From 235a402c8cd13f6c3f80e147384d10308ea2c1c9 Mon Sep 17 00:00:00 2001 From: dylancaowugang Date: Mon, 15 Aug 2022 17:20:27 +0800 Subject: [PATCH] add first commit --- .gitignore | 99 + Makefile | 1043 + apps/Makefile | 52 + apps/anc/Makefile | 105 + apps/anc/inc/anc_assist.h | 70 + apps/anc/inc/anc_wnr.h | 56 + apps/anc/inc/app_anc.h | 72 + apps/anc/inc/peak_detector.h | 41 + apps/anc/src/anc_assist.c | 445 + apps/anc/src/anc_wnr.c | 1371 + apps/anc/src/app_anc.c | 1956 + apps/anc/src/peak_detector.c | 196 + apps/apptester/Makefile | 176 + apps/apptester/app_audtest.cpp | 307 + apps/apptester/app_audtest.h | 23 + apps/apptester/app_audtest_pattern.h | 185231 +++++++++++++++ apps/apptester/audiobuffer.c | 146 + apps/apptester/audiobuffer.h | 47 + apps/audioplayers/Makefile | 180 + apps/audioplayers/a2dp_decoder/Makefile | 120 + .../a2dp_decoder/a2dp_decoder.cpp | 2036 + apps/audioplayers/a2dp_decoder/a2dp_decoder.h | 155 + .../a2dp_decoder/a2dp_decoder_aac_lc.cpp | 1012 + .../a2dp_decoder/a2dp_decoder_cp.c | 618 + .../a2dp_decoder/a2dp_decoder_cp.h | 82 + .../a2dp_decoder/a2dp_decoder_example.cpp | 137 + .../a2dp_decoder/a2dp_decoder_internal.h | 201 + .../a2dp_decoder/a2dp_decoder_ldac.cpp | 1117 + .../a2dp_decoder/a2dp_decoder_lhdc.cpp | 1249 + .../a2dp_decoder/a2dp_decoder_sbc.cpp | 969 + .../a2dp_decoder/a2dp_decoder_scalable.cpp | 739 + .../a2dp_decoder/a2dp_decoder_trace.h | 37 + apps/audioplayers/a2dpplay.cpp | 3475 + apps/audioplayers/app_audio.cpp | 791 + apps/audioplayers/app_audio.h | 224 + apps/audioplayers/bt_sco_chain.c | 1483 + apps/audioplayers/bt_sco_chain.h | 76 + apps/audioplayers/bt_sco_chain_cfg.h | 146 + apps/audioplayers/bt_sco_chain_cfg_default.c | 796 + apps/audioplayers/bt_sco_chain_cp.c | 228 + apps/audioplayers/bt_sco_chain_cp.h | 49 + apps/audioplayers/bt_sco_chain_thirdparty.c | 155 + .../bt_sco_chain_thirdparty_alango.c | 192 + apps/audioplayers/bt_sco_chain_tuning.c | 224 + apps/audioplayers/bt_sco_chain_tuning.h | 40 + apps/audioplayers/cvsdplay.cpp | 264 + apps/audioplayers/digmici2splay.cpp | 47 + apps/audioplayers/flacplay.cpp | 138 + apps/audioplayers/fmradio.cpp | 529 + apps/audioplayers/fmradio.h | 32 + apps/audioplayers/msbcplay.cpp | 152 + apps/audioplayers/plc_utils.c | 328 + apps/audioplayers/plc_utils.h | 54 + apps/audioplayers/rbplay/rb_ctl.cpp | 887 + apps/audioplayers/rbplay/rb_ctl.h | 75 + apps/audioplayers/rbplay/rbpcmbuf.cpp | 140 + apps/audioplayers/rbplay/rbpcmbuf.h | 39 + apps/audioplayers/rbplay/rbplay.cpp | 615 + apps/audioplayers/rbplay/rbplay.h | 41 + apps/audioplayers/rbplay/rbplaysd.cpp | 225 + apps/audioplayers/rbplay/rbplaysd.h | 63 + apps/audioplayers/rbplay/utils.h | 26 + apps/audioplayers/voice_test.c | 185 + apps/audioplayers/voicebtpcmplay.cpp | 2275 + .../voicebtpcmplay_sco_dma_snapshot.cpp | 948 + apps/audioplayers/wavplay.cpp | 253 + apps/battery/Makefile | 18 + apps/battery/app_battery.cpp | 903 + apps/battery/app_battery.h | 121 + apps/btusbaudio/Makefile | 41 + apps/btusbaudio/btusb_audio.c | 307 + apps/btusbaudio/btusb_audio.h | 40 + apps/btusbaudio/usbaudio_thread.c | 139 + apps/btusbaudio/usbaudio_thread.h | 49 + apps/cmd/Makefile | 10 + apps/cmd/app_cmd.cpp | 71 + apps/cmd/app_cmd.h | 29 + apps/common/Makefile | 17 + apps/common/app_spec_ostimer.cpp | 97 + apps/common/app_spec_ostimer.h | 45 + apps/common/app_thread.c | 164 + apps/common/app_thread.h | 92 + apps/common/app_utils.c | 281 + apps/common/app_utils.h | 108 + apps/common/randfrommic.c | 267 + apps/common/randfrommic.h | 33 + apps/factory/1k_2ch_44k_16bit.txt | 882 + apps/factory/1k_2ch_48k_16bit.txt | 96 + apps/factory/Makefile | 43 + apps/factory/app_factory.cpp | 689 + apps/factory/app_factory.h | 53 + apps/factory/app_factory_audio.cpp | 293 + apps/factory/app_factory_audio.h | 35 + apps/factory/app_factory_bt.cpp | 331 + apps/factory/app_factory_bt.h | 36 + apps/factory/app_factory_cdc_comm.c | 314 + apps/factory/app_factory_cdc_comm.h | 17 + apps/factory/sys_api_cdc_comm.c | 229 + apps/factory/sys_api_cdc_comm.h | 41 + apps/key/Makefile | 8 + apps/key/app_key.cpp | 167 + apps/key/app_key.h | 109 + apps/main/Makefile | 142 + apps/main/app_status_ind.h | 82 + apps/main/apps.cpp | 2847 + apps/main/apps.h | 93 + apps/main/apps_tester.cpp | 312 + apps/mic/Makefile | 59 + apps/mic/app_mic.cpp | 254 + apps/mic/app_mic.h | 65 + apps/pwl/Makefile | 8 + apps/pwl/app_pwl.cpp | 185 + apps/pwl/app_pwl.h | 63 + apps/sdmmc/Makefile | 14 + apps/sdmmc/app_sdmmc.cpp | 200 + apps/sdmmc/app_sdmmc.h | 39 + apps/usbaudio/Makefile | 193 + apps/usbaudio/usbaudio_entry.c | 347 + apps/usbhost/Makefile | 7 + apps/usbhost/app_usbhost.c | 21 + apps/usbhost/app_usbhost.h | 27 + apps/voice_detector/Makefile | 24 + apps/voice_detector/app_voice_detector.cpp | 267 + apps/voice_detector/app_voice_detector.h | 107 + apps/voice_detector/vad_sensor.h | 32 + apps/voice_detector/voice_detector.c | 904 + apps/voice_detector/voice_detector.h | 198 + config/Makefile | 54 + config/_default_cfg_src_/app_status_ind.c | 294 + config/_default_cfg_src_/res/SOUND_MUTE.txt | 132 + .../_default_cfg_src_/res/cn/SOUND_ANSWER.txt | 190 + .../res/cn/SOUND_CHARGE_FINISH.txt | 310 + .../res/cn/SOUND_CHARGE_PLEASE.txt | 275 + .../res/cn/SOUND_CONNECTED.txt | 240 + .../res/cn/SOUND_DIS_CONNECT.txt | 245 + .../_default_cfg_src_/res/cn/SOUND_EIGHT.txt | 110 + .../_default_cfg_src_/res/cn/SOUND_FINDME.txt | 645 + .../_default_cfg_src_/res/cn/SOUND_FIVE.txt | 120 + .../_default_cfg_src_/res/cn/SOUND_FOUR.txt | 130 + .../res/cn/SOUND_HUNG_UP.txt | 155 + .../res/cn/SOUND_INCOMING_CALL.txt | 250 + .../res/cn/SOUND_LANGUAGE_SWITCH.txt | 155 + .../_default_cfg_src_/res/cn/SOUND_NINE.txt | 130 + config/_default_cfg_src_/res/cn/SOUND_ONE.txt | 90 + .../_default_cfg_src_/res/cn/SOUND_OVER.txt | 195 + .../res/cn/SOUND_PAIRING.txt | 180 + .../res/cn/SOUND_PAIRING_FAIL.txt | 310 + .../res/cn/SOUND_PAIRING_SUCCESS.txt | 285 + .../res/cn/SOUND_PAIR_ENABLE.txt | 255 + .../res/cn/SOUND_POWER_OFF.txt | 190 + .../res/cn/SOUND_POWER_ON.txt | 190 + .../_default_cfg_src_/res/cn/SOUND_REFUSE.txt | 605 + .../_default_cfg_src_/res/cn/SOUND_SEVEN.txt | 125 + config/_default_cfg_src_/res/cn/SOUND_SIX.txt | 130 + .../_default_cfg_src_/res/cn/SOUND_THREE.txt | 120 + config/_default_cfg_src_/res/cn/SOUND_TWO.txt | 120 + .../res/cn/SOUND_WARNING.txt | 155 + .../_default_cfg_src_/res/cn/SOUND_ZERO.txt | 100 + .../res/en/SOUND_ALEXA_START.txt | 363 + .../res/en/SOUND_ALEXA_STOP.txt | 693 + .../_default_cfg_src_/res/en/SOUND_ANSWER.txt | 195 + .../res/en/SOUND_CHARGE_FINISH.txt | 280 + .../res/en/SOUND_CHARGE_PLEASE.txt | 315 + .../res/en/SOUND_CONNECTED.txt | 330 + .../res/en/SOUND_DIS_CONNECT.txt | 390 + .../_default_cfg_src_/res/en/SOUND_EIGHT.txt | 145 + .../_default_cfg_src_/res/en/SOUND_FINDME.txt | 645 + .../_default_cfg_src_/res/en/SOUND_FIVE.txt | 165 + .../_default_cfg_src_/res/en/SOUND_FOUR.txt | 155 + .../res/en/SOUND_GSOUND_MIC_CLOSE.txt | 234 + .../res/en/SOUND_GSOUND_MIC_OPEN.txt | 96 + .../res/en/SOUND_GSOUND_NC.txt | 648 + .../res/en/SOUND_HUNG_UP.txt | 155 + .../res/en/SOUND_INCOMING_CALL.txt | 445 + .../res/en/SOUND_LANGUAGE_SWITCH.txt | 155 + .../_default_cfg_src_/res/en/SOUND_NINE.txt | 175 + config/_default_cfg_src_/res/en/SOUND_ONE.txt | 145 + .../_default_cfg_src_/res/en/SOUND_OVER.txt | 175 + .../res/en/SOUND_PAIRING.txt | 195 + .../res/en/SOUND_PAIRING_FAIL.txt | 285 + .../res/en/SOUND_PAIRING_SUCCESS.txt | 345 + .../res/en/SOUND_PAIR_ENABLE.txt | 195 + .../res/en/SOUND_POWER_OFF.txt | 230 + .../res/en/SOUND_POWER_ON.txt | 245 + .../_default_cfg_src_/res/en/SOUND_REFUSE.txt | 605 + .../_default_cfg_src_/res/en/SOUND_SEVEN.txt | 185 + config/_default_cfg_src_/res/en/SOUND_SIX.txt | 175 + .../_default_cfg_src_/res/en/SOUND_THREE.txt | 145 + config/_default_cfg_src_/res/en/SOUND_TWO.txt | 165 + .../res/en/SOUND_WARNING.txt | 155 + .../_default_cfg_src_/res/en/SOUND_ZERO.txt | 215 + config/_default_cfg_src_/res/en/dudu.txt | 48 + config/_default_cfg_src_/res/eq/EQ_COEF.txt | 384 + config/_default_cfg_src_/res/gs_hw/en_all.txt | 1 + .../res/ring/SOUND_RING_16000.txt | 17825 ++ .../res/ring/SOUND_RING_44100.txt | 4224 + .../res/ring/SOUND_RING_48000.txt | 4224 + .../res/ring/SOUND_RING_8000.txt | 4224 + config/_default_cfg_src_/slave_code.S | 27 + config/_default_cfg_src_/tgt_hardware.c | 99 + config/_default_cfg_src_/tgt_hardware.h | 84 + config/best2300p_ibrt/target.mk | 410 + config/best2300p_ibrt/tgt_hardware.c | 339 + config/best2300p_ibrt/tgt_hardware.h | 152 + config/best2300p_ibrt_anc/target.mk | 423 + config/best2300p_ibrt_anc/tgt_hardware.c | 1089 + config/best2300p_ibrt_anc/tgt_hardware.h | 120 + config/common.mk | 2646 + include/rtos/freertos/FreeRTOS.h | 1186 + include/rtos/freertos/FreeRTOSConfig.h | 238 + include/rtos/freertos/StackMacros.h | 133 + include/rtos/freertos/cmsis_os.h | 879 + include/rtos/freertos/cmsis_os2.h | 758 + include/rtos/freertos/croutine.h | 719 + .../rtos/freertos/deprecated_definitions.h | 279 + include/rtos/freertos/event_groups.h | 757 + include/rtos/freertos/freertos_evr.h | 966 + include/rtos/freertos/freertos_list.h | 412 + include/rtos/freertos/message_buffer.h | 798 + include/rtos/freertos/mpu_prototypes.h | 156 + include/rtos/freertos/mpu_wrappers.h | 182 + include/rtos/freertos/portable.h | 165 + include/rtos/freertos/portmacro.h | 256 + include/rtos/freertos/projdefs.h | 124 + include/rtos/freertos/queue.h | 1655 + include/rtos/freertos/semphr.h | 1140 + include/rtos/freertos/stack_macros.h | 129 + include/rtos/freertos/stdint.readme | 27 + include/rtos/freertos/stream_buffer.h | 855 + include/rtos/freertos/task.h | 2340 + include/rtos/freertos/timers.h | 1278 + include/rtos/rtx/cmsis_os.h | 813 + include/rtos/rtx/os_tcb.h | 76 + include/rtos/rtx5/cmsis_os.h | 928 + include/rtos/rtx5/cmsis_os2.h | 760 + include/rtos/rtx5/os_tick.h | 71 + include/rtos/rtx5/rtx_evr.h | 1974 + include/rtos/rtx5/rtx_os.h | 482 + platform/Makefile | 7 + .../BasicMathFunctions/BasicMathFunctions.c | 63 + .../cmsis/DSP_Lib/BasicMathFunctions/Makefile | 6 + .../DSP_Lib/BasicMathFunctions/arm_abs_f32.c | 117 + .../DSP_Lib/BasicMathFunctions/arm_abs_q15.c | 132 + .../DSP_Lib/BasicMathFunctions/arm_abs_q31.c | 132 + .../DSP_Lib/BasicMathFunctions/arm_abs_q7.c | 134 + .../DSP_Lib/BasicMathFunctions/arm_add_f32.c | 113 + .../DSP_Lib/BasicMathFunctions/arm_add_q15.c | 126 + .../DSP_Lib/BasicMathFunctions/arm_add_q31.c | 108 + .../DSP_Lib/BasicMathFunctions/arm_add_q7.c | 109 + .../BasicMathFunctions/arm_dot_prod_f32.c | 120 + .../BasicMathFunctions/arm_dot_prod_q15.c | 120 + .../BasicMathFunctions/arm_dot_prod_q31.c | 115 + .../BasicMathFunctions/arm_dot_prod_q7.c | 139 + .../DSP_Lib/BasicMathFunctions/arm_mult_f32.c | 116 + .../DSP_Lib/BasicMathFunctions/arm_mult_q15.c | 143 + .../DSP_Lib/BasicMathFunctions/arm_mult_q31.c | 119 + .../DSP_Lib/BasicMathFunctions/arm_mult_q7.c | 119 + .../BasicMathFunctions/arm_negate_f32.c | 116 + .../BasicMathFunctions/arm_negate_q15.c | 126 + .../BasicMathFunctions/arm_negate_q31.c | 132 + .../BasicMathFunctions/arm_negate_q7.c | 126 + .../BasicMathFunctions/arm_offset_f32.c | 118 + .../BasicMathFunctions/arm_offset_q15.c | 121 + .../BasicMathFunctions/arm_offset_q31.c | 128 + .../BasicMathFunctions/arm_offset_q7.c | 116 + .../BasicMathFunctions/arm_scale_f32.c | 131 + .../BasicMathFunctions/arm_scale_q15.c | 144 + .../BasicMathFunctions/arm_scale_q31.c | 191 + .../DSP_Lib/BasicMathFunctions/arm_scale_q7.c | 129 + .../BasicMathFunctions/arm_shift_q15.c | 201 + .../BasicMathFunctions/arm_shift_q31.c | 181 + .../DSP_Lib/BasicMathFunctions/arm_shift_q7.c | 175 + .../DSP_Lib/BasicMathFunctions/arm_sub_f32.c | 116 + .../DSP_Lib/BasicMathFunctions/arm_sub_q15.c | 126 + .../DSP_Lib/BasicMathFunctions/arm_sub_q31.c | 108 + .../DSP_Lib/BasicMathFunctions/arm_sub_q7.c | 109 + .../cmsis/DSP_Lib/CommonTables/CommonTables.c | 31 + platform/cmsis/DSP_Lib/CommonTables/Makefile | 6 + .../DSP_Lib/CommonTables/arm_common_tables.c | 22151 ++ .../DSP_Lib/CommonTables/arm_const_structs.c | 379 + .../ComplexMathFunctions.c | 46 + .../DSP_Lib/ComplexMathFunctions/Makefile | 6 + .../ComplexMathFunctions/arm_cmplx_conj_f32.c | 130 + .../ComplexMathFunctions/arm_cmplx_conj_q15.c | 157 + .../ComplexMathFunctions/arm_cmplx_conj_q31.c | 137 + .../arm_cmplx_dot_prod_f32.c | 172 + .../arm_cmplx_dot_prod_q15.c | 154 + .../arm_cmplx_dot_prod_q31.c | 153 + .../ComplexMathFunctions/arm_cmplx_mag_f32.c | 139 + .../ComplexMathFunctions/arm_cmplx_mag_q15.c | 162 + .../ComplexMathFunctions/arm_cmplx_mag_q31.c | 130 + .../arm_cmplx_mag_squared_f32.c | 137 + .../arm_cmplx_mag_squared_q15.c | 161 + .../arm_cmplx_mag_squared_q31.c | 129 + .../arm_cmplx_mult_cmplx_f32.c | 155 + .../arm_cmplx_mult_cmplx_q15.c | 136 + .../arm_cmplx_mult_cmplx_q31.c | 137 + .../arm_cmplx_mult_real_f32.c | 140 + .../arm_cmplx_mult_real_q15.c | 182 + .../arm_cmplx_mult_real_q31.c | 148 + .../ControllerFunctions/ControllerFunctions.c | 37 + .../DSP_Lib/ControllerFunctions/Makefile | 6 + .../ControllerFunctions/arm_pid_init_f32.c | 75 + .../ControllerFunctions/arm_pid_init_q15.c | 95 + .../ControllerFunctions/arm_pid_init_q31.c | 92 + .../ControllerFunctions/arm_pid_reset_f32.c | 54 + .../ControllerFunctions/arm_pid_reset_q15.c | 54 + .../ControllerFunctions/arm_pid_reset_q31.c | 54 + .../ControllerFunctions/arm_sin_cos_f32.c | 146 + .../ControllerFunctions/arm_sin_cos_q31.c | 110 + .../FastMathFunctions/FastMathFunctions.c | 37 + .../cmsis/DSP_Lib/FastMathFunctions/Makefile | 6 + .../DSP_Lib/FastMathFunctions/arm_cos_f32.c | 122 + .../DSP_Lib/FastMathFunctions/arm_cos_q15.c | 84 + .../DSP_Lib/FastMathFunctions/arm_cos_q31.c | 84 + .../DSP_Lib/FastMathFunctions/arm_sin_f32.c | 122 + .../DSP_Lib/FastMathFunctions/arm_sin_q15.c | 77 + .../DSP_Lib/FastMathFunctions/arm_sin_q31.c | 77 + .../DSP_Lib/FastMathFunctions/arm_sqrt_q15.c | 144 + .../DSP_Lib/FastMathFunctions/arm_sqrt_q31.c | 144 + .../FilteringFunctions/FilteringFunctions.c | 127 + .../cmsis/DSP_Lib/FilteringFunctions/Makefile | 6 + .../arm_biquad_cascade_df1_32x64_init_q31.c | 94 + .../arm_biquad_cascade_df1_32x64_q31.c | 458 + .../arm_biquad_cascade_df1_f32.c | 340 + .../arm_biquad_cascade_df1_fast_q15.c | 250 + .../arm_biquad_cascade_df1_fast_q31.c | 296 + .../arm_biquad_cascade_df1_init_f32.c | 91 + .../arm_biquad_cascade_df1_init_q15.c | 96 + .../arm_biquad_cascade_df1_init_q31.c | 95 + .../arm_biquad_cascade_df1_q15.c | 363 + .../arm_biquad_cascade_df1_q31.c | 247 + .../arm_biquad_cascade_df2T_f32.c | 354 + .../arm_biquad_cascade_df2T_f64.c | 443 + .../arm_biquad_cascade_df2T_init_f32.c | 86 + .../arm_biquad_cascade_df2T_init_f64.c | 86 + .../arm_biquad_cascade_stereo_df2T_f32.c | 286 + .../arm_biquad_cascade_stereo_df2T_init_f32.c | 86 + .../DSP_Lib/FilteringFunctions/arm_conv_f32.c | 640 + .../arm_conv_fast_opt_q15.c | 366 + .../FilteringFunctions/arm_conv_fast_q15.c | 663 + .../FilteringFunctions/arm_conv_fast_q31.c | 558 + .../FilteringFunctions/arm_conv_opt_q15.c | 362 + .../FilteringFunctions/arm_conv_opt_q7.c | 360 + .../FilteringFunctions/arm_conv_partial_f32.c | 676 + .../arm_conv_partial_fast_opt_q15.c | 387 + .../arm_conv_partial_fast_q15.c | 700 + .../arm_conv_partial_fast_q31.c | 618 + .../arm_conv_partial_opt_q15.c | 386 + .../arm_conv_partial_opt_q7.c | 390 + .../FilteringFunctions/arm_conv_partial_q15.c | 752 + .../FilteringFunctions/arm_conv_partial_q31.c | 634 + .../FilteringFunctions/arm_conv_partial_q7.c | 753 + .../DSP_Lib/FilteringFunctions/arm_conv_q15.c | 696 + .../DSP_Lib/FilteringFunctions/arm_conv_q31.c | 581 + .../DSP_Lib/FilteringFunctions/arm_conv_q7.c | 700 + .../FilteringFunctions/arm_correlate_f32.c | 750 + .../arm_correlate_fast_opt_q15.c | 345 + .../arm_correlate_fast_q15.c | 614 + .../arm_correlate_fast_q31.c | 601 + .../arm_correlate_opt_q15.c | 341 + .../FilteringFunctions/arm_correlate_opt_q7.c | 388 + .../FilteringFunctions/arm_correlate_q15.c | 696 + .../FilteringFunctions/arm_correlate_q31.c | 682 + .../FilteringFunctions/arm_correlate_q7.c | 800 + .../FilteringFunctions/arm_fir_decimate_f32.c | 456 + .../arm_fir_decimate_fast_q15.c | 595 + .../arm_fir_decimate_fast_q31.c | 390 + .../arm_fir_decimate_init_f32.c | 105 + .../arm_fir_decimate_init_q15.c | 106 + .../arm_fir_decimate_init_q31.c | 105 + .../FilteringFunctions/arm_fir_decimate_q15.c | 595 + .../FilteringFunctions/arm_fir_decimate_q31.c | 387 + .../DSP_Lib/FilteringFunctions/arm_fir_f32.c | 493 + .../FilteringFunctions/arm_fir_fast_q15.c | 332 + .../FilteringFunctions/arm_fir_fast_q31.c | 324 + .../FilteringFunctions/arm_fir_init_f32.c | 81 + .../FilteringFunctions/arm_fir_init_q15.c | 137 + .../FilteringFunctions/arm_fir_init_q31.c | 80 + .../FilteringFunctions/arm_fir_init_q7.c | 81 + .../arm_fir_interpolate_f32.c | 556 + .../arm_fir_interpolate_init_f32.c | 106 + .../arm_fir_interpolate_init_q15.c | 106 + .../arm_fir_interpolate_init_q31.c | 105 + .../arm_fir_interpolate_q15.c | 479 + .../arm_fir_interpolate_q31.c | 481 + .../FilteringFunctions/arm_fir_lattice_f32.c | 453 + .../arm_fir_lattice_init_f32.c | 70 + .../arm_fir_lattice_init_q15.c | 70 + .../arm_fir_lattice_init_q31.c | 70 + .../FilteringFunctions/arm_fir_lattice_q15.c | 506 + .../FilteringFunctions/arm_fir_lattice_q31.c | 505 + .../DSP_Lib/FilteringFunctions/arm_fir_q15.c | 332 + .../DSP_Lib/FilteringFunctions/arm_fir_q31.c | 288 + .../DSP_Lib/FilteringFunctions/arm_fir_q7.c | 323 + .../FilteringFunctions/arm_fir_sparse_f32.c | 341 + .../arm_fir_sparse_init_f32.c | 93 + .../arm_fir_sparse_init_q15.c | 93 + .../arm_fir_sparse_init_q31.c | 92 + .../arm_fir_sparse_init_q7.c | 93 + .../FilteringFunctions/arm_fir_sparse_q15.c | 341 + .../FilteringFunctions/arm_fir_sparse_q31.c | 357 + .../FilteringFunctions/arm_fir_sparse_q7.c | 341 + .../FilteringFunctions/arm_iir_lattice_f32.c | 354 + .../arm_iir_lattice_init_f32.c | 77 + .../arm_iir_lattice_init_q15.c | 77 + .../arm_iir_lattice_init_q31.c | 77 + .../FilteringFunctions/arm_iir_lattice_q15.c | 396 + .../FilteringFunctions/arm_iir_lattice_q31.c | 356 + .../DSP_Lib/FilteringFunctions/arm_lms_f32.c | 360 + .../FilteringFunctions/arm_lms_init_f32.c | 81 + .../FilteringFunctions/arm_lms_init_q15.c | 92 + .../FilteringFunctions/arm_lms_init_q31.c | 92 + .../FilteringFunctions/arm_lms_norm_f32.c | 374 + .../arm_lms_norm_init_f32.c | 92 + .../arm_lms_norm_init_q15.c | 98 + .../arm_lms_norm_init_q31.c | 97 + .../FilteringFunctions/arm_lms_norm_q15.c | 297 + .../FilteringFunctions/arm_lms_norm_q31.c | 311 + .../DSP_Lib/FilteringFunctions/arm_lms_q15.c | 262 + .../DSP_Lib/FilteringFunctions/arm_lms_q31.c | 283 + platform/cmsis/DSP_Lib/Makefile | 51 + .../cmsis/DSP_Lib/MatrixFunctions/Makefile | 6 + .../DSP_Lib/MatrixFunctions/MatrixFunctions.c | 53 + .../DSP_Lib/MatrixFunctions/arm_mat_add_f32.c | 146 + .../DSP_Lib/MatrixFunctions/arm_mat_add_q15.c | 149 + .../DSP_Lib/MatrixFunctions/arm_mat_add_q31.c | 139 + .../MatrixFunctions/arm_mat_cmplx_mult_f32.c | 286 + .../MatrixFunctions/arm_mat_cmplx_mult_q15.c | 340 + .../MatrixFunctions/arm_mat_cmplx_mult_q31.c | 283 + .../MatrixFunctions/arm_mat_init_f32.c | 76 + .../MatrixFunctions/arm_mat_init_q15.c | 67 + .../MatrixFunctions/arm_mat_init_q31.c | 72 + .../MatrixFunctions/arm_mat_inverse_f32.c | 693 + .../MatrixFunctions/arm_mat_inverse_f64.c | 673 + .../MatrixFunctions/arm_mat_mult_f32.c | 200 + .../MatrixFunctions/arm_mat_mult_fast_q15.c | 483 + .../MatrixFunctions/arm_mat_mult_fast_q31.c | 374 + .../MatrixFunctions/arm_mat_mult_q15.c | 357 + .../MatrixFunctions/arm_mat_mult_q31.c | 196 + .../MatrixFunctions/arm_mat_scale_f32.c | 146 + .../MatrixFunctions/arm_mat_scale_q15.c | 170 + .../MatrixFunctions/arm_mat_scale_q31.c | 164 + .../DSP_Lib/MatrixFunctions/arm_mat_sub_f32.c | 143 + .../DSP_Lib/MatrixFunctions/arm_mat_sub_q15.c | 144 + .../DSP_Lib/MatrixFunctions/arm_mat_sub_q31.c | 139 + .../MatrixFunctions/arm_mat_trans_f32.c | 155 + .../MatrixFunctions/arm_mat_trans_q15.c | 182 + .../MatrixFunctions/arm_mat_trans_q31.c | 146 + .../DSP_Lib/StatisticsFunctions/Makefile | 6 + .../StatisticsFunctions/StatisticsFunctions.c | 53 + .../DSP_Lib/StatisticsFunctions/arm_max_f32.c | 156 + .../DSP_Lib/StatisticsFunctions/arm_max_q15.c | 148 + .../DSP_Lib/StatisticsFunctions/arm_max_q31.c | 148 + .../DSP_Lib/StatisticsFunctions/arm_max_q7.c | 148 + .../StatisticsFunctions/arm_mean_f32.c | 115 + .../StatisticsFunctions/arm_mean_q15.c | 114 + .../StatisticsFunctions/arm_mean_q31.c | 110 + .../DSP_Lib/StatisticsFunctions/arm_mean_q7.c | 112 + .../DSP_Lib/StatisticsFunctions/arm_min_f32.c | 156 + .../DSP_Lib/StatisticsFunctions/arm_min_q15.c | 149 + .../DSP_Lib/StatisticsFunctions/arm_min_q31.c | 149 + .../DSP_Lib/StatisticsFunctions/arm_min_q7.c | 149 + .../StatisticsFunctions/arm_power_f32.c | 124 + .../StatisticsFunctions/arm_power_q15.c | 132 + .../StatisticsFunctions/arm_power_q31.c | 121 + .../StatisticsFunctions/arm_power_q7.c | 136 + .../DSP_Lib/StatisticsFunctions/arm_rms_f32.c | 124 + .../DSP_Lib/StatisticsFunctions/arm_rms_q15.c | 134 + .../DSP_Lib/StatisticsFunctions/arm_rms_q31.c | 124 + .../DSP_Lib/StatisticsFunctions/arm_std_f32.c | 176 + .../DSP_Lib/StatisticsFunctions/arm_std_q15.c | 161 + .../DSP_Lib/StatisticsFunctions/arm_std_q31.c | 147 + .../DSP_Lib/StatisticsFunctions/arm_var_f32.c | 172 + .../DSP_Lib/StatisticsFunctions/arm_var_q15.c | 164 + .../DSP_Lib/StatisticsFunctions/arm_var_q31.c | 147 + .../cmsis/DSP_Lib/SupportFunctions/Makefile | 6 + .../SupportFunctions/SupportFunctions.c | 48 + .../DSP_Lib/SupportFunctions/arm_copy_f32.c | 110 + .../DSP_Lib/SupportFunctions/arm_copy_q15.c | 96 + .../DSP_Lib/SupportFunctions/arm_copy_q31.c | 98 + .../DSP_Lib/SupportFunctions/arm_copy_q7.c | 95 + .../DSP_Lib/SupportFunctions/arm_fill_f32.c | 110 + .../DSP_Lib/SupportFunctions/arm_fill_q15.c | 100 + .../DSP_Lib/SupportFunctions/arm_fill_q31.c | 98 + .../DSP_Lib/SupportFunctions/arm_fill_q7.c | 99 + .../SupportFunctions/arm_float_to_q15.c | 150 + .../SupportFunctions/arm_float_to_q31.c | 154 + .../SupportFunctions/arm_float_to_q7.c | 149 + .../SupportFunctions/arm_q15_to_float.c | 110 + .../DSP_Lib/SupportFunctions/arm_q15_to_q31.c | 138 + .../DSP_Lib/SupportFunctions/arm_q15_to_q7.c | 146 + .../SupportFunctions/arm_q31_to_float.c | 110 + .../DSP_Lib/SupportFunctions/arm_q31_to_q15.c | 134 + .../DSP_Lib/SupportFunctions/arm_q31_to_q7.c | 110 + .../SupportFunctions/arm_q7_to_float.c | 110 + .../DSP_Lib/SupportFunctions/arm_q7_to_q15.c | 143 + .../DSP_Lib/SupportFunctions/arm_q7_to_q31.c | 121 + .../cmsis/DSP_Lib/TransformFunctions/Makefile | 6 + .../TransformFunctions/TransformFunctions.c | 60 + .../TransformFunctions/arm_bitreversal.c | 229 + .../TransformFunctions/arm_bitreversal2.S | 216 + .../TransformFunctions/arm_bitreversal2.c | 99 + .../DSP_Lib/TransformFunctions/arm_cfft_f32.c | 629 + .../DSP_Lib/TransformFunctions/arm_cfft_q15.c | 332 + .../DSP_Lib/TransformFunctions/arm_cfft_q31.c | 254 + .../TransformFunctions/arm_cfft_radix2_f32.c | 470 + .../arm_cfft_radix2_init_f32.c | 197 + .../arm_cfft_radix2_init_q15.c | 182 + .../arm_cfft_radix2_init_q31.c | 179 + .../TransformFunctions/arm_cfft_radix2_q15.c | 689 + .../TransformFunctions/arm_cfft_radix2_q31.c | 337 + .../TransformFunctions/arm_cfft_radix4_f32.c | 1200 + .../arm_cfft_radix4_init_f32.c | 156 + .../arm_cfft_radix4_init_q15.c | 145 + .../arm_cfft_radix4_init_q31.c | 141 + .../TransformFunctions/arm_cfft_radix4_q15.c | 1809 + .../TransformFunctions/arm_cfft_radix4_q31.c | 827 + .../TransformFunctions/arm_cfft_radix8_f32.c | 285 + .../DSP_Lib/TransformFunctions/arm_dct4_f32.c | 448 + .../TransformFunctions/arm_dct4_init_f32.c | 16027 ++ .../TransformFunctions/arm_dct4_init_q15.c | 4283 + .../TransformFunctions/arm_dct4_init_q31.c | 4619 + .../DSP_Lib/TransformFunctions/arm_dct4_q15.c | 381 + .../DSP_Lib/TransformFunctions/arm_dct4_q31.c | 383 + .../DSP_Lib/TransformFunctions/arm_rfft_f32.c | 309 + .../TransformFunctions/arm_rfft_fast_f32.c | 320 + .../arm_rfft_fast_init_f32.c | 312 + .../TransformFunctions/arm_rfft_init_f32.c | 4279 + .../TransformFunctions/arm_rfft_init_q15.c | 2235 + .../TransformFunctions/arm_rfft_init_q31.c | 4285 + .../DSP_Lib/TransformFunctions/arm_rfft_q15.c | 380 + .../DSP_Lib/TransformFunctions/arm_rfft_q31.c | 292 + platform/cmsis/LICENSE.txt | 201 + platform/cmsis/Makefile | 67 + platform/cmsis/ca/Makefile | 23 + platform/cmsis/ca/cmsis_gic.c | 192 + platform/cmsis/ca/default_irq_ca.S | 290 + platform/cmsis/ca/irq_ctrl_gic.c | 405 + platform/cmsis/ca/mmu_ARMCA.c | 323 + platform/cmsis/ca/startup_ARMCA.c | 151 + platform/cmsis/ca/system_ARMCA.c | 136 + platform/cmsis/cmsis_nvic.c | 221 + platform/cmsis/inc/arm_common_tables.h | 121 + platform/cmsis/inc/arm_const_structs.h | 66 + platform/cmsis/inc/arm_math.h | 7210 + platform/cmsis/inc/best1000.h | 175 + platform/cmsis/inc/best1400.h | 191 + platform/cmsis/inc/best2000.h | 192 + platform/cmsis/inc/best2001.h | 236 + platform/cmsis/inc/best2300.h | 202 + platform/cmsis/inc/best2300a.h | 211 + platform/cmsis/inc/best2300p.h | 205 + platform/cmsis/inc/best3001.h | 181 + platform/cmsis/inc/best3003.h | 169 + platform/cmsis/inc/ca/best2001_dsp.h | 209 + platform/cmsis/inc/ca/cmsis_armcc_ca.h | 547 + platform/cmsis/inc/ca/cmsis_armclang_ca.h | 585 + platform/cmsis/inc/ca/cmsis_compiler_ca.h | 213 + platform/cmsis/inc/ca/cmsis_cp15_ca.h | 514 + platform/cmsis/inc/ca/cmsis_gcc_ca.h | 814 + platform/cmsis/inc/ca/cmsis_iccarm_ca.h | 571 + platform/cmsis/inc/ca/core_ca.h | 2726 + platform/cmsis/inc/ca/irq_ctrl.h | 186 + platform/cmsis/inc/ca/mem_ARMCA.h | 103 + platform/cmsis/inc/ca/system_ARMCA.h | 31 + platform/cmsis/inc/cmsis.h | 150 + platform/cmsis/inc/cmsis_armcc.h | 869 + platform/cmsis/inc/cmsis_armclang.h | 1420 + platform/cmsis/inc/cmsis_armclang_ltm.h | 1866 + platform/cmsis/inc/cmsis_compiler.h | 271 + platform/cmsis/inc/cmsis_gcc.h | 2101 + platform/cmsis/inc/cmsis_iccarm.h | 940 + platform/cmsis/inc/cmsis_nvic.h | 112 + platform/cmsis/inc/cmsis_version.h | 39 + platform/cmsis/inc/core_armv81mml.h | 2967 + platform/cmsis/inc/core_armv8mbl.h | 1918 + platform/cmsis/inc/core_armv8mml.h | 2832 + platform/cmsis/inc/core_cm0.h | 949 + platform/cmsis/inc/core_cm0plus.h | 1082 + platform/cmsis/inc/core_cm1.h | 976 + platform/cmsis/inc/core_cm23.h | 1993 + platform/cmsis/inc/core_cm3.h | 1934 + platform/cmsis/inc/core_cm33.h | 2914 + platform/cmsis/inc/core_cm35p.h | 2907 + platform/cmsis/inc/core_cm4.h | 2125 + platform/cmsis/inc/core_cm7.h | 2691 + platform/cmsis/inc/core_sc000.h | 1022 + platform/cmsis/inc/core_sc300.h | 1915 + platform/cmsis/inc/fpga1000.h | 175 + platform/cmsis/inc/link_sym_armclang.h | 235 + platform/cmsis/inc/main_entry.h | 33 + platform/cmsis/inc/mpu.h | 111 + platform/cmsis/inc/mpu_armv7.h | 289 + platform/cmsis/inc/mpu_armv8.h | 346 + platform/cmsis/inc/patch.h | 47 + platform/cmsis/inc/system_ARMCM.h | 48 + platform/cmsis/inc/system_cp.h | 35 + platform/cmsis/inc/tz_context.h | 70 + platform/cmsis/mpu_armv7m.c | 369 + platform/cmsis/mpu_armv8m.c | 281 + platform/cmsis/patch.c | 216 + platform/cmsis/patch_armv7m.c | 270 + platform/cmsis/reg_patch.h | 44 + platform/cmsis/reg_patch_armv7m.h | 63 + platform/cmsis/retarget_armclang.cpp | 101 + platform/cmsis/retarget_armclang_asm.S | 43 + platform/cmsis/retarget_gcc.cpp | 142 + platform/cmsis/stack_protector.c | 22 + platform/cmsis/system_ARMCM.c | 105 + platform/cmsis/system_cp.c | 239 + platform/cmsis/system_utils.c | 274 + platform/drivers/Makefile | 13 + platform/drivers/ana/Makefile | 200 + platform/drivers/ana/analog.h | 117 + platform/drivers/ana/best2300p/Makefile | 99 + .../drivers/ana/best2300p/analog_best2300p.c | 2297 + .../drivers/ana/best2300p/analog_best2300p.h | 42 + .../drivers/ana/best2300p/pmu_best2300p.c | 4287 + .../drivers/ana/best2300p/pmu_best2300p.h | 100 + .../ana/best2300p/reg_usbphy_best2300p.h | 573 + .../drivers/ana/best2300p/usbphy_best2300p.c | 410 + .../drivers/ana/best2300p/usbphy_best2300p.h | 34 + platform/drivers/ana/pmu.h | 259 + platform/drivers/ana/psramuhsphy.h | 60 + platform/drivers/ana/usbphy.h | 58 + platform/drivers/bt/Makefile | 152 + platform/drivers/bt/besbt_string.h | 21 + platform/drivers/bt/best2300p/Makefile | 23 + platform/drivers/bt/best2300p/bt_drv.cpp | 1391 + .../bt/best2300p/bt_drv_2300p_internal.h | 79 + .../bt/best2300p/bt_drv_calibration.cpp | 549 + platform/drivers/bt/best2300p/bt_drv_config.c | 1691 + platform/drivers/bt/best2300p/bt_drv_patch.c | 7314 + .../drivers/bt/best2300p/bt_drv_reg_op.cpp | 3278 + .../drivers/bt/best2300p/bt_drv_rfconfig.c | 796 + .../bt/best2300p/bt_drv_uart_bridge_intsys.c | 220 + platform/drivers/bt/best2300p/iqcorrect.c | 985 + platform/drivers/bt/best2300p/iqcorrect.h | 19 + platform/drivers/bt/bt_drv.h | 482 + platform/drivers/bt/bt_drv_common.c | 633 + platform/drivers/bt/bt_drv_interface.h | 393 + platform/drivers/bt/bt_drv_internal.h | 104 + platform/drivers/bt/bt_drv_reg_op.h | 336 + platform/drivers/btpcm/Makefile | 5 + platform/drivers/btpcm/btpcm.c | 119 + platform/drivers/btpcm/btpcm.h | 27 + platform/drivers/codec/Makefile | 34 + platform/drivers/codec/best2300p/Makefile | 8 + .../drivers/codec/best2300p/codec_best2300p.c | 688 + .../drivers/codec/best2300p/codec_best2300p.h | 31 + platform/drivers/codec/codec_int.h | 61 + platform/drivers/codec/codec_tlv32aic32.c | 239 + platform/drivers/codec/codec_tlv32aic32.h | 287 + platform/drivers/norflash/Makefile | 44 + platform/drivers/norflash/norflash_drv.c | 1620 + platform/drivers/norflash/norflash_drv.h | 189 + platform/drivers/norflash/norflash_en25s80b.c | 143 + platform/drivers/norflash/norflash_en25s80b.h | 73 + .../drivers/norflash/norflash_gd25lq32c.c | 583 + .../drivers/norflash/norflash_gd25lq32c.h | 85 + platform/drivers/norflash/norflash_gd25q32c.c | 365 + platform/drivers/norflash/norflash_gd25q32c.h | 88 + platform/drivers/sbcacc/Makefile | 18 + platform/drivers/usb/Makefile | 1 + platform/drivers/usb/usb_dev/Makefile | 130 + .../drivers/usb/usb_dev/cfg/usb_dev_desc.c | 384 + platform/drivers/usb/usb_dev/inc/usb_audio.h | 157 + .../drivers/usb/usb_dev/inc/usb_audio_sync.h | 72 + platform/drivers/usb/usb_dev/inc/usb_cdc.h | 126 + .../drivers/usb/usb_dev/inc/usb_descriptor.h | 144 + .../drivers/usb/usb_dev/inc/usb_dev_desc.h | 65 + .../drivers/usb/usb_dev/uaud_cfg_flags.mk | 110 + platform/drivers/usb/usb_host/Makefile | 20 + platform/drivers/usb/usb_host/inc/USBHost.h | 193 + .../drivers/usb/usb_host/inc/usb_tester.h | 49 + platform/hal/Makefile | 685 + platform/hal/best2300p/Makefile | 78 + .../hal/best2300p/hal_analogif_best2300p.c | 211 + platform/hal/best2300p/hal_cmu_best2300p.c | 2784 + platform/hal/best2300p/hal_cmu_best2300p.h | 265 + platform/hal/best2300p/hal_codec_best2300p.c | 4197 + platform/hal/best2300p/hal_dmacfg_best2300p.h | 115 + platform/hal/best2300p/hal_iomux_best2300p.c | 1104 + platform/hal/best2300p/hal_iomux_best2300p.h | 234 + platform/hal/best2300p/hal_psc_best2300p.c | 123 + .../hal/best2300p/hal_sensor_eng_best2300p.c | 345 + .../hal/best2300p/plat_addr_map_best2300p.h | 175 + platform/hal/best2300p/reg_aoncmu_best2300p.h | 532 + platform/hal/best2300p/reg_btcmu_best2300p.h | 57 + platform/hal/best2300p/reg_cmu_best2300p.h | 852 + platform/hal/best2300p/reg_codec_best2300p.h | 1785 + platform/hal/best2300p/reg_iomux_best2300p.h | 406 + platform/hal/best2300p/reg_psc_best2300p.h | 450 + .../hal/best2300p/reg_sensor_eng_best2300p.h | 119 + platform/hal/hal_analogif.h | 34 + platform/hal/hal_aud.h | 354 + platform/hal/hal_bootmode.c | 99 + platform/hal/hal_bootmode.h | 102 + platform/hal/hal_btdump.c | 83 + platform/hal/hal_btdump.h | 33 + platform/hal/hal_btpcm.c | 211 + platform/hal/hal_btpcm.h | 51 + platform/hal/hal_btpcmip.h | 279 + platform/hal/hal_cache.c | 601 + platform/hal/hal_cache.h | 57 + platform/hal/hal_chipid.c | 50 + platform/hal/hal_chipid.h | 68 + platform/hal/hal_cmd.c | 545 + platform/hal/hal_cmd.h | 105 + platform/hal/hal_cmu.h | 462 + platform/hal/hal_cmu_common.c | 447 + platform/hal/hal_codec.h | 213 + platform/hal/hal_codec_common.c | 129 + platform/hal/hal_dma.c | 1057 + platform/hal/hal_dma.h | 293 + platform/hal/hal_gpadc.c | 791 + platform/hal/hal_gpadc.h | 91 + platform/hal/hal_gpio.c | 508 + platform/hal/hal_gpio.h | 62 + platform/hal/hal_hwfft.h | 93 + platform/hal/hal_i2c.c | 2374 + platform/hal/hal_i2c.h | 221 + platform/hal/hal_i2cip.h | 374 + platform/hal/hal_i2s.c | 801 + platform/hal/hal_i2s.h | 82 + platform/hal/hal_i2s_tdm.c | 315 + platform/hal/hal_i2s_tdm.h | 74 + platform/hal/hal_i2sip.h | 236 + platform/hal/hal_intersys.c | 555 + platform/hal/hal_intersys.h | 77 + platform/hal/hal_iomux.h | 113 + platform/hal/hal_key.c | 1183 + platform/hal/hal_key.h | 103 + platform/hal/hal_location.h | 164 + platform/hal/hal_mcu2cp.c | 554 + platform/hal/hal_mcu2cp.h | 75 + platform/hal/hal_memsc.c | 46 + platform/hal/hal_memsc.h | 46 + platform/hal/hal_norflash.c | 1609 + platform/hal/hal_norflash.h | 185 + platform/hal/hal_norflaship.h | 179 + platform/hal/hal_norflaship_v1.c | 431 + platform/hal/hal_norflaship_v2.c | 563 + platform/hal/hal_overlay.c | 359 + platform/hal/hal_overlay.h | 148 + platform/hal/hal_phyif.c | 159 + platform/hal/hal_phyif.h | 38 + platform/hal/hal_psc.h | 44 + platform/hal/hal_psram.h | 39 + platform/hal/hal_psram_v1.c | 533 + platform/hal/hal_psram_v2.c | 815 + platform/hal/hal_psramip_v1.h | 217 + platform/hal/hal_psramuhs.c | 632 + platform/hal/hal_psramuhs.h | 34 + platform/hal/hal_pwm.c | 203 + platform/hal/hal_pwm.h | 43 + platform/hal/hal_rtc.c | 246 + platform/hal/hal_rtc.h | 50 + platform/hal/hal_sdmmc.c | 2827 + platform/hal/hal_sdmmc.h | 46 + platform/hal/hal_sec_eng.c | 1037 + platform/hal/hal_sec_eng.h | 149 + platform/hal/hal_sensor_eng.h | 63 + platform/hal/hal_slave_i2c.c | 73 + platform/hal/hal_slave_i2c.h | 45 + platform/hal/hal_sleep.c | 587 + platform/hal/hal_sleep.h | 201 + platform/hal/hal_sleep_core_pd.S | 100 + platform/hal/hal_sleep_core_pd.h | 34 + platform/hal/hal_sleep_mcu_pd.S | 84 + platform/hal/hal_sleep_mcu_pd.h | 34 + platform/hal/hal_spdif.c | 412 + platform/hal/hal_spdif.h | 54 + platform/hal/hal_spdifip.h | 261 + platform/hal/hal_spi.c | 1732 + platform/hal/hal_spi.h | 209 + platform/hal/hal_sysfreq.c | 160 + platform/hal/hal_sysfreq.h | 69 + platform/hal/hal_tdm.c | 589 + platform/hal/hal_tdm.h | 98 + platform/hal/hal_timer.c | 684 + platform/hal/hal_timer.h | 166 + platform/hal/hal_timer_raw.h | 69 + platform/hal/hal_trace.c | 2801 + platform/hal/hal_trace.h | 406 + platform/hal/hal_trace_mod.c | 32 + platform/hal/hal_trace_mod.h | 71 + platform/hal/hal_transq.c | 618 + platform/hal/hal_transq.h | 92 + platform/hal/hal_uart.c | 1355 + platform/hal/hal_uart.h | 253 + platform/hal/hal_usb.c | 2735 + platform/hal/hal_usb.h | 232 + platform/hal/hal_usbhost.c | 1079 + platform/hal/hal_usbhost.h | 173 + platform/hal/hal_wdt.c | 242 + platform/hal/hal_wdt.h | 54 + platform/hal/plat_addr_map.h | 82 + platform/hal/plat_types.h | 219 + platform/hal/reg_btpcmip.h | 141 + platform/hal/reg_dma.h | 149 + platform/hal/reg_gpio.h | 21 + platform/hal/reg_i2cip.h | 368 + platform/hal/reg_i2sip.h | 248 + platform/hal/reg_norflaship_v1.h | 130 + platform/hal/reg_norflaship_v2.h | 432 + platform/hal/reg_psram_mc_v2.h | 604 + platform/hal/reg_psram_phy_v2.h | 153 + platform/hal/reg_psramip_v1.h | 127 + platform/hal/reg_psramuhs_mc.h | 646 + platform/hal/reg_pwm.h | 94 + platform/hal/reg_rtc.h | 38 + platform/hal/reg_sdmmcip.h | 149 + platform/hal/reg_sec_eng.h | 336 + platform/hal/reg_slave_i2c.h | 48 + platform/hal/reg_spdifip.h | 288 + platform/hal/reg_spi.h | 112 + platform/hal/reg_tdm.h | 44 + platform/hal/reg_timer.h | 60 + platform/hal/reg_transq.h | 66 + platform/hal/reg_uart.h | 116 + platform/hal/reg_usb.h | 1744 + platform/main/Makefile | 252 + platform/main/main.cpp | 414 + platform/main/noapp_main.cpp | 213 + platform/main/nostd_main.c | 18 + platform/main/startup_main.S | 196 + rtos/Makefile | 16 + .../TARGET_ARM7/ARM7/TOOLCHAIN_GCC/HAL_CM0.S | 329 + .../ARM7/TOOLCHAIN_GCC/SVC_Table.S | 56 + rtos/rtx/TARGET_ARM7/HAL_CM.c | 161 + rtos/rtx/TARGET_ARM7/RTX_CM_lib.h | 384 + rtos/rtx/TARGET_ARM7/RTX_Conf.h | 72 + rtos/rtx/TARGET_ARM7/RTX_Conf_CM.c | 246 + rtos/rtx/TARGET_ARM7/cmsis_os.h | 774 + rtos/rtx/TARGET_ARM7/os_tcb.h | 70 + rtos/rtx/TARGET_ARM7/rt_CMSIS.c | 1853 + rtos/rtx/TARGET_ARM7/rt_Event.c | 190 + rtos/rtx/TARGET_ARM7/rt_Event.h | 46 + rtos/rtx/TARGET_ARM7/rt_HAL_CM.h | 216 + rtos/rtx/TARGET_ARM7/rt_List.c | 320 + rtos/rtx/TARGET_ARM7/rt_List.h | 67 + rtos/rtx/TARGET_ARM7/rt_Mailbox.c | 292 + rtos/rtx/TARGET_ARM7/rt_Mailbox.h | 48 + rtos/rtx/TARGET_ARM7/rt_MemBox.c | 166 + rtos/rtx/TARGET_ARM7/rt_MemBox.h | 46 + rtos/rtx/TARGET_ARM7/rt_Mutex.c | 197 + rtos/rtx/TARGET_ARM7/rt_Mutex.h | 44 + rtos/rtx/TARGET_ARM7/rt_Robin.c | 84 + rtos/rtx/TARGET_ARM7/rt_Robin.h | 45 + rtos/rtx/TARGET_ARM7/rt_Semaphore.c | 183 + rtos/rtx/TARGET_ARM7/rt_Semaphore.h | 46 + rtos/rtx/TARGET_ARM7/rt_System.c | 293 + rtos/rtx/TARGET_ARM7/rt_System.h | 52 + rtos/rtx/TARGET_ARM7/rt_Task.c | 341 + rtos/rtx/TARGET_ARM7/rt_Task.h | 73 + rtos/rtx/TARGET_ARM7/rt_Time.c | 94 + rtos/rtx/TARGET_ARM7/rt_Time.h | 47 + rtos/rtx/TARGET_ARM7/rt_TypeDef.h | 128 + rtos/rtx/TARGET_CORTEX_A/HAL_CA.c | 126 + rtos/rtx/TARGET_CORTEX_A/RTX_CM_lib.h | 407 + rtos/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c | 329 + rtos/rtx/TARGET_CORTEX_A/RTX_Config.h | 76 + .../TARGET_CORTEX_A/TOOLCHAIN_ARM/HAL_CA9.c | 416 + .../TARGET_CORTEX_A/TOOLCHAIN_ARM/SVC_Table.S | 57 + .../TARGET_CORTEX_A/TOOLCHAIN_GCC/HAL_CA9.S | 474 + .../TARGET_CORTEX_A/TOOLCHAIN_GCC/SVC_Table.S | 60 + rtos/rtx/TARGET_CORTEX_A/cmsis_os.h | 807 + rtos/rtx/TARGET_CORTEX_A/rt_CMSIS.c | 2103 + rtos/rtx/TARGET_CORTEX_A/rt_Event.c | 194 + rtos/rtx/TARGET_CORTEX_A/rt_Event.h | 46 + rtos/rtx/TARGET_CORTEX_A/rt_HAL_CA.h | 207 + rtos/rtx/TARGET_CORTEX_A/rt_HAL_CM.h | 276 + rtos/rtx/TARGET_CORTEX_A/rt_List.c | 324 + rtos/rtx/TARGET_CORTEX_A/rt_List.h | 67 + rtos/rtx/TARGET_CORTEX_A/rt_Mailbox.c | 296 + rtos/rtx/TARGET_CORTEX_A/rt_Mailbox.h | 48 + rtos/rtx/TARGET_CORTEX_A/rt_MemBox.c | 170 + rtos/rtx/TARGET_CORTEX_A/rt_MemBox.h | 46 + rtos/rtx/TARGET_CORTEX_A/rt_Memory.c | 140 + rtos/rtx/TARGET_CORTEX_A/rt_Memory.h | 44 + rtos/rtx/TARGET_CORTEX_A/rt_Mutex.c | 204 + rtos/rtx/TARGET_CORTEX_A/rt_Mutex.h | 44 + rtos/rtx/TARGET_CORTEX_A/rt_Robin.c | 88 + rtos/rtx/TARGET_CORTEX_A/rt_Robin.h | 45 + rtos/rtx/TARGET_CORTEX_A/rt_Semaphore.c | 191 + rtos/rtx/TARGET_CORTEX_A/rt_Semaphore.h | 46 + rtos/rtx/TARGET_CORTEX_A/rt_System.c | 304 + rtos/rtx/TARGET_CORTEX_A/rt_System.h | 52 + rtos/rtx/TARGET_CORTEX_A/rt_Task.c | 372 + rtos/rtx/TARGET_CORTEX_A/rt_Task.h | 87 + rtos/rtx/TARGET_CORTEX_A/rt_Time.c | 94 + rtos/rtx/TARGET_CORTEX_A/rt_Time.h | 47 + rtos/rtx/TARGET_CORTEX_A/rt_Timer.h | 46 + rtos/rtx/TARGET_CORTEX_A/rt_TypeDef.h | 167 + rtos/rtx/TARGET_CORTEX_M/HAL_CM.c | 176 + rtos/rtx/TARGET_CORTEX_M/Makefile | 36 + rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h | 394 + rtos/rtx/TARGET_CORTEX_M/RTX_Conf.h | 73 + rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c | 303 + .../TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c | 301 + .../TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S | 57 + .../TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S | 370 + .../TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S | 56 + .../TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S | 312 + .../TARGET_M0/TOOLCHAIN_IAR/SVC_Table.S | 58 + .../TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c | 301 + .../TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S | 57 + .../TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S | 370 + .../TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S | 56 + .../TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S | 312 + .../TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.S | 58 + .../TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c | 249 + .../TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S | 57 + .../TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S | 323 + .../TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S | 56 + .../TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S | 265 + .../TARGET_M3/TOOLCHAIN_IAR/SVC_Table.S | 58 + .../TARGET_M4/TOOLCHAIN_ARM/HAL_CM4.c | 309 + .../TARGET_M4/TOOLCHAIN_ARM/SVC_Table.S | 57 + .../TARGET_M4/TOOLCHAIN_GCC/HAL_CM4.S | 419 + .../TARGET_M4/TOOLCHAIN_GCC/SVC_Table.S | 56 + .../TARGET_M4/TOOLCHAIN_IAR/HAL_CM4.S | 333 + .../TARGET_M4/TOOLCHAIN_IAR/SVC_Table.S | 58 + rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c | 1985 + rtos/rtx/TARGET_CORTEX_M/rt_Event.c | 190 + rtos/rtx/TARGET_CORTEX_M/rt_Event.h | 46 + rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h | 287 + rtos/rtx/TARGET_CORTEX_M/rt_List.c | 343 + rtos/rtx/TARGET_CORTEX_M/rt_List.h | 68 + rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c | 292 + rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h | 48 + rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c | 166 + rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h | 46 + rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c | 197 + rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h | 44 + rtos/rtx/TARGET_CORTEX_M/rt_Robin.c | 84 + rtos/rtx/TARGET_CORTEX_M/rt_Robin.h | 45 + rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c | 183 + rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h | 46 + rtos/rtx/TARGET_CORTEX_M/rt_System.c | 445 + rtos/rtx/TARGET_CORTEX_M/rt_System.h | 52 + rtos/rtx/TARGET_CORTEX_M/rt_Task.c | 735 + rtos/rtx/TARGET_CORTEX_M/rt_Task.h | 74 + rtos/rtx/TARGET_CORTEX_M/rt_Time.c | 94 + rtos/rtx/TARGET_CORTEX_M/rt_Time.h | 60 + rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h | 128 + rtos/rtx5/ARM/irq_armv8mbl.s | 333 + rtos/rtx5/ARM/irq_armv8mbl_ns.s | 3 + rtos/rtx5/ARM/irq_armv8mml.s | 306 + rtos/rtx5/ARM/irq_armv8mml_ns.s | 3 + rtos/rtx5/ARM/irq_ca.s | 458 + rtos/rtx5/ARM/irq_cm0.s | 174 + rtos/rtx5/ARM/irq_cm3.s | 146 + rtos/rtx5/ARM/irq_cm4f.s | 162 + rtos/rtx5/GCC/Makefile | 15 + rtos/rtx5/GCC/irq_armv8mbl.S | 317 + rtos/rtx5/GCC/irq_armv8mbl_ns.S | 3 + rtos/rtx5/GCC/irq_armv8mml.S | 288 + rtos/rtx5/GCC/irq_armv8mml_fp.S | 3 + rtos/rtx5/GCC/irq_armv8mml_fp_ns.S | 4 + rtos/rtx5/GCC/irq_armv8mml_ns.S | 3 + rtos/rtx5/GCC/irq_ca.S | 465 + rtos/rtx5/GCC/irq_cm0.S | 173 + rtos/rtx5/GCC/irq_cm3.S | 144 + rtos/rtx5/GCC/irq_cm4f.S | 161 + rtos/rtx5/IAR/irq_armv8mbl.s | 4 + rtos/rtx5/IAR/irq_armv8mbl_common.s | 299 + rtos/rtx5/IAR/irq_armv8mbl_ns.s | 4 + rtos/rtx5/IAR/irq_armv8mml.s | 4 + rtos/rtx5/IAR/irq_armv8mml_common.s | 272 + rtos/rtx5/IAR/irq_armv8mml_ns.s | 4 + rtos/rtx5/IAR/irq_ca.s | 441 + rtos/rtx5/IAR/irq_cm0.s | 158 + rtos/rtx5/IAR/irq_cm3.s | 130 + rtos/rtx5/IAR/irq_cm4f.s | 146 + rtos/rtx5/Makefile | 34 + rtos/rtx5/RTE_Components.h | 7 + rtos/rtx5/cmsis_os1.c | 366 + rtos/rtx5/os_systick.c | 151 + rtos/rtx5/rtx_config/Makefile | 11 + rtos/rtx5/rtx_config/rtx_config.c | 127 + rtos/rtx5/rtx_config/rtx_config.h | 578 + rtos/rtx5/rtx_core_c.h | 48 + rtos/rtx5/rtx_core_ca.h | 1121 + rtos/rtx5/rtx_core_cm.h | 1201 + rtos/rtx5/rtx_delay.c | 101 + rtos/rtx5/rtx_evflags.c | 582 + rtos/rtx5/rtx_evr.c | 2116 + rtos/rtx5/rtx_kernel.c | 733 + rtos/rtx5/rtx_lib.c | 824 + rtos/rtx5/rtx_lib.h | 219 + rtos/rtx5/rtx_memory.c | 218 + rtos/rtx5/rtx_mempool.c | 705 + rtos/rtx5/rtx_msgqueue.c | 948 + rtos/rtx5/rtx_mutex.c | 536 + rtos/rtx5/rtx_semaphore.c | 507 + rtos/rtx5/rtx_system.c | 217 + rtos/rtx5/rtx_thread.c | 1952 + rtos/rtx5/rtx_thread_dump.c | 399 + rtos/rtx5/rtx_timer.c | 459 + scripts/build.mk | 519 + scripts/clean.mk | 179 + scripts/extrawarn.mk | 76 + scripts/include.mk | 268 + scripts/lib.mk | 217 + scripts/link/armca.lds.S | 355 + scripts/link/best1000.lds.S | 2016 + scripts/link/best1000_fpga_rom.lds.S | 320 + scripts/link/best1000_intsram.lds.S | 632 + scripts/link/best1000_intsram.lds_scat.S | 409 + scripts/link/best1000_msbc_aac.lds.S | 921 + scripts/link/best1000savepower.lds.S | 2175 + scripts/link/best2000_bisto.lds.S | 1096 + scripts/link/best2000_dma.lds.S | 1268 + scripts/link/programmer.lds.S | 283 + scripts/link/programmer.lds_scat.S | 160 + scripts/link/programmer_inflash.lds.S | 300 + scripts/link/rom.lds.S | 304 + scripts/link/rom.lds_scat.S | 180 + scripts/submods.mk | 13 + scripts/submods_init.mk | 24 + services/Makefile | 133 + services/anc_spp_tool/Makefile | 46 + services/anc_spp_tool/anc_parse_data.h | 93 + services/app_ai/Makefile | 58 + services/app_ai/inc/app_ai_algorithm.h | 61 + services/app_ai/inc/app_ai_if.h | 197 + services/app_ai/inc/app_ai_if_config.h | 43 + services/app_ai/inc/app_ai_if_custom_ui.h | 51 + services/app_ai/inc/app_ai_if_gsound.h | 35 + services/app_ai/inc/app_ai_if_thirdparty.h | 150 + services/app_ai/inc/app_ai_manager_api.h | 251 + services/app_ai/inc/app_ai_tws.h | 422 + services/app_ai/src/app_ai_algorithm.cpp | 411 + services/app_ai/src/app_ai_if.cpp | 302 + services/app_ai/src/app_ai_if_custom_ui.cpp | 118 + services/app_ai/src/app_ai_if_gsound.cpp | 16 + services/app_ai/src/app_ai_if_thirdparty.cpp | 108 + services/app_ai/src/app_ai_manager_api.cpp | 131 + services/app_ai/src/app_ai_tws.cpp | 656 + services/app_ai/voice_sbc/voice_sbc.cpp | 196 + services/app_ai/voice_sbc/voice_sbc.h | 72 + services/app_ibrt/Makefile | 102 + services/app_ibrt/inc/app_ibrt_a2dp.h | 30 + services/app_ibrt/inc/app_ibrt_auto_test.h | 88 + .../inc/app_ibrt_auto_test_cmd_handle.h | 117 + services/app_ibrt/inc/app_ibrt_ble_adv.h | 73 + services/app_ibrt/inc/app_ibrt_custom_cmd.h | 29 + services/app_ibrt/inc/app_ibrt_customif_cmd.h | 50 + services/app_ibrt/inc/app_ibrt_customif_ui.h | 94 + services/app_ibrt/inc/app_ibrt_hf.h | 43 + services/app_ibrt/inc/app_ibrt_if.h | 190 + services/app_ibrt/inc/app_ibrt_if_internal.h | 33 + services/app_ibrt/inc/app_ibrt_keyboard.h | 62 + services/app_ibrt/inc/app_ibrt_nvrecord.h | 41 + services/app_ibrt/inc/app_ibrt_ota_cmd.h | 52 + services/app_ibrt/inc/app_ibrt_ota_update.h | 79 + .../inc/app_ibrt_peripheral_manager.h | 60 + services/app_ibrt/inc/app_ibrt_rssi.h | 44 + services/app_ibrt/inc/app_ibrt_ui_test.h | 46 + .../app_ibrt/inc/app_ibrt_ui_test_cmd_if.h | 82 + services/app_ibrt/inc/app_ibrt_voice_report.h | 52 + services/app_ibrt/src/app_ibrt_auto_test.cpp | 150 + .../src/app_ibrt_auto_test_cmd_handle.cpp | 651 + services/app_ibrt/src/app_ibrt_ble_adv.cpp | 311 + .../app_ibrt/src/app_ibrt_customif_cmd.cpp | 258 + .../app_ibrt/src/app_ibrt_customif_ui.cpp | 889 + services/app_ibrt/src/app_ibrt_if.cpp | 1203 + services/app_ibrt/src/app_ibrt_keyboard.cpp | 400 + services/app_ibrt/src/app_ibrt_nvrecord.cpp | 323 + services/app_ibrt/src/app_ibrt_ota_cmd.cpp | 661 + services/app_ibrt/src/app_ibrt_ota_update.cpp | 428 + .../src/app_ibrt_peripheral_manager.cpp | 335 + services/app_ibrt/src/app_ibrt_rssi.cpp | 586 + .../app_ibrt/src/app_ibrt_search_pair_ui.cpp | 770 + services/app_ibrt/src/app_ibrt_ui_test.cpp | 868 + .../app_ibrt/src/app_ibrt_ui_test_cmd_if.cpp | 586 + .../app_ibrt/src/app_ibrt_voice_report.cpp | 511 + services/app_tws/Makefile | 42 + services/app_tws/inc/app_tws_if.h | 460 + services/app_tws/src/app_tws_if.cpp | 710 + services/audio_dump/Makefile | 15 + services/audio_dump/include/audio_dump.h | 42 + services/audio_dump/src/audio_dump.c | 278 + services/audio_process/Makefile | 75 + services/audio_process/audio_cfg.c | 110 + services/audio_process/audio_cfg.h | 43 + services/audio_process/audio_process.c | 1244 + services/audio_process/audio_process.h | 49 + services/audio_process/audio_spectrum.cpp | 118 + services/audio_process/audio_spectrum.h | 25 + services/audioflinger/Makefile | 123 + services/audioflinger/audioflinger.c | 3258 + services/audioflinger/audioflinger.h | 154 + services/auto_test/Makefile | 57 + services/auto_test/at_thread.cpp | 137 + services/auto_test/at_thread.h | 45 + services/auto_test/at_thread_user.cpp | 275 + services/auto_test/at_thread_user.h | 101 + services/auto_test/auto_test.cpp | 2436 + services/ble_app/Makefile | 156 + services/ble_app/app_amsc/app_amsc.c | 96 + services/ble_app/app_amsc/app_amsc.h | 86 + services/ble_app/app_amsc/app_amsc_task.c | 82 + services/ble_app/app_amsc/app_amsc_task.h | 50 + services/ble_app/app_ancc/app_ancc.c | 103 + services/ble_app/app_ancc/app_ancc.h | 86 + services/ble_app/app_ancc/app_ancc_task.c | 82 + services/ble_app/app_ancc/app_ancc_task.h | 50 + services/ble_app/app_batt/app_batt.c | 205 + services/ble_app/app_batt/app_batt.h | 112 + services/ble_app/app_ble_key.cpp | 91 + services/ble_app/app_ble_uart.cpp | 144 + services/ble_app/app_ble_uart.h | 22 + .../app_datapath/app_ble_cmd_handler.c | 583 + .../app_datapath/app_ble_cmd_handler.h | 161 + .../ble_app/app_datapath/app_ble_custom_cmd.c | 139 + .../ble_app/app_datapath/app_ble_custom_cmd.h | 65 + .../app_datapath/app_datapath_server.c | 293 + .../app_datapath/app_datapath_server.h | 134 + services/ble_app/app_dis/app_dis.c | 198 + services/ble_app/app_dis/app_dis.h | 135 + services/ble_app/app_gfps/app_gfps.c | 1308 + services/ble_app/app_gfps/app_gfps.h | 264 + services/ble_app/app_hid/app_hid.c | 944 + services/ble_app/app_hid/app_hid.h | 138 + services/ble_app/app_hrps/app_hrps.c | 156 + services/ble_app/app_hrps/app_hrps.h | 71 + services/ble_app/app_htp/app_ht.c | 467 + services/ble_app/app_htp/app_ht.h | 152 + services/ble_app/app_main/app.c | 1458 + services/ble_app/app_main/app.h | 395 + services/ble_app/app_main/app_ble_core.c | 335 + services/ble_app/app_main/app_ble_core.h | 250 + services/ble_app/app_main/app_ble_customif.c | 133 + services/ble_app/app_main/app_ble_customif.h | 52 + services/ble_app/app_main/app_ble_include.h | 36 + .../ble_app/app_main/app_ble_mode_switch.c | 1210 + .../ble_app/app_main/app_ble_mode_switch.h | 456 + .../ble_app/app_main/app_ble_rx_handler.c | 174 + .../ble_app/app_main/app_ble_rx_handler.h | 52 + services/ble_app/app_main/app_task.c | 1235 + services/ble_app/app_main/app_task.h | 107 + services/ble_app/app_ota/app_ota.c | 286 + services/ble_app/app_ota/app_ota.h | 120 + services/ble_app/app_sec/app_sec.c | 448 + services/ble_app/app_sec/app_sec.h | 111 + services/ble_app/app_tota/app_tota_ble.c | 254 + services/ble_app/app_tota/app_tota_ble.h | 118 + services/ble_app/app_vob/voice_over_ble.c | 1230 + .../ble_app/app_voice/app_voicepath_ble.c | 151 + .../ble_app/app_voice/app_voicepath_ble.h | 43 + services/ble_app/ble_app_dbg.h | 45 + services/ble_profiles/Makefile | 126 + services/ble_profiles/ams/ams_common.h | 79 + services/ble_profiles/ams/amsc/amsc.c | 188 + services/ble_profiles/ams/amsc/amsc.h | 181 + services/ble_profiles/ams/amsc/amsc_task.c | 521 + services/ble_profiles/ams/amsc/amsc_task.h | 109 + services/ble_profiles/anc/anc_common.h | 225 + services/ble_profiles/anc/ancc/ancc.c | 188 + services/ble_profiles/anc/ancc/ancc.h | 175 + services/ble_profiles/anc/ancc/ancc_task.c | 491 + services/ble_profiles/anc/ancc/ancc_task.h | 121 + services/ble_profiles/anp/anp_common.h | 181 + .../ble_profiles/anp/anpc/api/anpc_task.h | 223 + services/ble_profiles/anp/anpc/src/anpc.c | 258 + services/ble_profiles/anp/anpc/src/anpc.h | 182 + .../ble_profiles/anp/anpc/src/anpc_task.c | 872 + .../ble_profiles/anp/anps/api/anps_task.h | 134 + services/ble_profiles/anp/anps/src/anps.c | 332 + services/ble_profiles/anp/anps/src/anps.h | 249 + .../ble_profiles/anp/anps/src/anps_task.c | 655 + .../ble_profiles/bas/basc/api/basc_task.h | 202 + services/ble_profiles/bas/basc/src/basc.c | 207 + services/ble_profiles/bas/basc/src/basc.h | 130 + .../ble_profiles/bas/basc/src/basc_task.c | 623 + .../ble_profiles/bas/bass/api/bass_task.h | 130 + services/ble_profiles/bas/bass/src/bass.c | 461 + services/ble_profiles/bas/bass/src/bass.h | 172 + .../ble_profiles/bas/bass/src/bass_task.c | 390 + services/ble_profiles/blp/blp_common.h | 162 + .../ble_profiles/blp/blpc/api/blpc_task.h | 157 + services/ble_profiles/blp/blpc/src/blpc.c | 235 + services/ble_profiles/blp/blpc/src/blpc.h | 155 + .../ble_profiles/blp/blpc/src/blpc_task.c | 543 + .../ble_profiles/blp/blps/api/blps_task.h | 127 + services/ble_profiles/blp/blps/src/blps.c | 278 + services/ble_profiles/blp/blps/src/blps.h | 215 + .../ble_profiles/blp/blps/src/blps_task.c | 412 + services/ble_profiles/cpp/cpp_common.h | 441 + .../ble_profiles/cpp/cppc/api/cppc_task.h | 237 + services/ble_profiles/cpp/cppc/src/cppc.c | 751 + services/ble_profiles/cpp/cppc/src/cppc.h | 255 + .../ble_profiles/cpp/cppc/src/cppc_task.c | 790 + .../ble_profiles/cpp/cpps/api/cpps_task.h | 344 + services/ble_profiles/cpp/cpps/src/cpps.c | 1452 + services/ble_profiles/cpp/cpps/src/cpps.h | 366 + .../ble_profiles/cpp/cpps/src/cpps_task.c | 779 + services/ble_profiles/cscp/cscp_common.h | 208 + .../ble_profiles/cscp/cscpc/api/cscpc_task.h | 199 + services/ble_profiles/cscp/cscpc/src/cscpc.c | 237 + services/ble_profiles/cscp/cscpc/src/cscpc.h | 173 + .../ble_profiles/cscp/cscpc/src/cscpc_task.c | 945 + .../ble_profiles/cscp/cscps/api/cscps_task.h | 209 + services/ble_profiles/cscp/cscps/src/cscps.c | 357 + services/ble_profiles/cscp/cscps/src/cscps.h | 237 + .../ble_profiles/cscp/cscps/src/cscps_task.c | 831 + .../datapath/datapathps/api/datapathps_task.h | 88 + .../datapath/datapathps/src/datapathps.c | 240 + .../datapath/datapathps/src/datapathps.h | 163 + .../datapath/datapathps/src/datapathps_task.c | 466 + .../ble_profiles/dis/disc/api/disc_task.h | 105 + services/ble_profiles/dis/disc/src/disc.c | 198 + services/ble_profiles/dis/disc/src/disc.h | 131 + .../ble_profiles/dis/disc/src/disc_task.c | 345 + .../ble_profiles/dis/diss/api/diss_task.h | 144 + services/ble_profiles/dis/diss/src/diss.c | 347 + services/ble_profiles/dis/diss/src/diss.h | 197 + .../ble_profiles/dis/diss/src/diss_task.c | 277 + services/ble_profiles/find/find_common.h | 102 + .../ble_profiles/find/findl/api/findl_task.h | 103 + services/ble_profiles/find/findl/src/findl.c | 196 + services/ble_profiles/find/findl/src/findl.h | 172 + .../ble_profiles/find/findl/src/findl_task.c | 305 + .../ble_profiles/find/findt/api/findt_task.h | 62 + services/ble_profiles/find/findt/src/findt.c | 171 + services/ble_profiles/find/findt/src/findt.h | 154 + .../ble_profiles/find/findt/src/findt_task.c | 109 + services/ble_profiles/gfps/Makefile | 16 + services/ble_profiles/gfps/api/gfps_crypto.h | 21 + .../gfps/gfps_provider/api/gfps_provider.h | 278 + .../gfps_provider/api/gfps_provider_errors.h | 13 + .../gfps_provider/api/gfps_provider_task.h | 190 + .../gfps/gfps_provider/src/gfps_provider.c | 413 + .../gfps_provider/src/gfps_provider_task.c | 338 + services/ble_profiles/glp/glp_common.h | 623 + .../ble_profiles/glp/glpc/api/glpc_task.h | 196 + services/ble_profiles/glp/glpc/src/glpc.c | 442 + services/ble_profiles/glp/glpc/src/glpc.h | 209 + .../ble_profiles/glp/glpc/src/glpc_task.c | 773 + services/ble_profiles/glp/glps/api/glps.h | 324 + .../ble_profiles/glp/glps/api/glps_task.h | 147 + services/ble_profiles/glp/glps/src/glps.c | 551 + .../ble_profiles/glp/glps/src/glps_task.c | 724 + services/ble_profiles/hogp/hogp_common.h | 92 + .../hogp/hogpbh/api/hogpbh_task.h | 252 + .../ble_profiles/hogp/hogpbh/src/hogpbh.c | 207 + .../ble_profiles/hogp/hogpbh/src/hogpbh.h | 136 + .../hogp/hogpbh/src/hogpbh_task.c | 699 + .../ble_profiles/hogp/hogpd/api/hogpd_task.h | 305 + services/ble_profiles/hogp/hogpd/src/hogpd.c | 903 + services/ble_profiles/hogp/hogpd/src/hogpd.h | 271 + .../ble_profiles/hogp/hogpd/src/hogpd_task.c | 784 + .../hogp/hogprh/api/hogprh_task.h | 331 + .../ble_profiles/hogp/hogprh/src/hogprh.c | 203 + .../ble_profiles/hogp/hogprh/src/hogprh.h | 130 + .../hogp/hogprh/src/hogprh_task.c | 825 + services/ble_profiles/hrp/hrp_common.h | 134 + .../ble_profiles/hrp/hrpc/api/hrpc_task.h | 171 + services/ble_profiles/hrp/hrpc/src/hrpc.c | 238 + services/ble_profiles/hrp/hrpc/src/hrpc.h | 162 + .../ble_profiles/hrp/hrpc/src/hrpc_task.c | 633 + .../ble_profiles/hrp/hrps/api/hrps_task.h | 117 + services/ble_profiles/hrp/hrps/src/hrps.c | 324 + services/ble_profiles/hrp/hrps/src/hrps.h | 228 + .../ble_profiles/hrp/hrps/src/hrps_task.c | 353 + services/ble_profiles/htp/htp_common.h | 92 + .../ble_profiles/htp/htpc/api/htpc_task.h | 216 + services/ble_profiles/htp/htpc/src/htpc.c | 287 + services/ble_profiles/htp/htpc/src/htpc.h | 178 + .../ble_profiles/htp/htpc/src/htpc_task.c | 651 + .../ble_profiles/htp/htpt/api/htpt_task.h | 187 + services/ble_profiles/htp/htpt/src/htpt.c | 586 + services/ble_profiles/htp/htpt/src/htpt.h | 290 + .../ble_profiles/htp/htpt/src/htpt_task.c | 589 + services/ble_profiles/lan/lan_common.h | 399 + .../ble_profiles/lan/lanc/api/lanc_task.h | 211 + services/ble_profiles/lan/lanc/src/lanc.c | 686 + services/ble_profiles/lan/lanc/src/lanc.h | 267 + .../ble_profiles/lan/lanc/src/lanc_task.c | 784 + .../ble_profiles/lan/lans/api/lans_task.h | 270 + services/ble_profiles/lan/lans/src/lans.c | 1362 + services/ble_profiles/lan/lans/src/lans.h | 372 + .../ble_profiles/lan/lans/src/lans_task.c | 670 + services/ble_profiles/ota/ota.c | 207 + services/ble_profiles/ota/ota.h | 151 + services/ble_profiles/ota/ota_task.c | 429 + services/ble_profiles/ota/ota_task.h | 96 + services/ble_profiles/pasp/pasp_common.h | 41 + .../ble_profiles/pasp/paspc/api/paspc_task.h | 188 + services/ble_profiles/pasp/paspc/src/paspc.c | 204 + services/ble_profiles/pasp/paspc/src/paspc.h | 155 + .../ble_profiles/pasp/paspc/src/paspc_task.c | 696 + .../ble_profiles/pasp/pasps/api/pasps_task.h | 124 + services/ble_profiles/pasp/pasps/src/pasps.c | 253 + services/ble_profiles/pasp/pasps/src/pasps.h | 199 + .../ble_profiles/pasp/pasps/src/pasps_task.c | 566 + services/ble_profiles/prf/prf.c | 894 + services/ble_profiles/prf/prf_utils.c | 384 + services/ble_profiles/prf/prf_utils_128.c | 164 + .../ble_profiles/prox/proxm/api/proxm_task.h | 151 + services/ble_profiles/prox/proxm/src/proxm.c | 215 + services/ble_profiles/prox/proxm/src/proxm.h | 228 + .../ble_profiles/prox/proxm/src/proxm_task.c | 510 + .../ble_profiles/prox/proxr/api/proxr_task.h | 86 + services/ble_profiles/prox/proxr/src/proxr.c | 220 + services/ble_profiles/prox/proxr/src/proxr.h | 210 + .../ble_profiles/prox/proxr/src/proxr_task.c | 282 + services/ble_profiles/rscp/rscp_common.h | 204 + .../ble_profiles/rscp/rscpc/api/rscpc_task.h | 198 + services/ble_profiles/rscp/rscpc/src/rscpc.c | 235 + services/ble_profiles/rscp/rscpc/src/rscpc.h | 174 + .../ble_profiles/rscp/rscpc/src/rscpc_task.c | 943 + .../ble_profiles/rscp/rscps/api/rscps_task.h | 205 + services/ble_profiles/rscp/rscps/src/rscps.c | 356 + services/ble_profiles/rscp/rscps/src/rscps.h | 247 + .../ble_profiles/rscp/rscps/src/rscps_task.c | 825 + services/ble_profiles/tip/tip_common.h | 231 + .../ble_profiles/tip/tipc/api/tipc_task.h | 257 + services/ble_profiles/tip/tipc/src/tipc.c | 210 + services/ble_profiles/tip/tipc/src/tipc.h | 157 + .../ble_profiles/tip/tipc/src/tipc_task.c | 799 + .../ble_profiles/tip/tips/api/tips_task.h | 149 + services/ble_profiles/tip/tips/src/tips.c | 333 + services/ble_profiles/tip/tips/src/tips.h | 257 + .../ble_profiles/tip/tips/src/tips_task.c | 556 + services/ble_profiles/tota/tota_ble.c | 199 + services/ble_profiles/tota/tota_ble.h | 150 + services/ble_profiles/tota/tota_task.c | 428 + services/ble_profiles/tota/tota_task.h | 97 + services/ble_stack/Makefile | 61 + services/ble_stack/ble_ip/arch.h | 217 + services/ble_stack/ble_ip/besble.h | 8 + services/ble_stack/ble_ip/compiler.h | 43 + services/ble_stack/ble_ip/rwapp_config.h | 207 + services/ble_stack/ble_ip/rwble_hl.h | 47 + services/ble_stack/ble_ip/rwble_hl_config.h | 253 + services/ble_stack/ble_ip/rwip.h | 523 + services/ble_stack/ble_ip/rwip_config.h | 1035 + services/ble_stack/ble_ip/rwip_task.h | 173 + services/ble_stack/ble_ip/rwprf_config.h | 572 + services/ble_stack/common/api/co_bt.h | 48 + services/ble_stack/common/api/co_bt_defines.h | 2614 + services/ble_stack/common/api/co_endian.h | 235 + services/ble_stack/common/api/co_error.h | 101 + services/ble_stack/common/api/co_hci.h | 4986 + services/ble_stack/common/api/co_list.h | 288 + services/ble_stack/common/api/co_llcp.h | 483 + services/ble_stack/common/api/co_lmp.h | 1225 + services/ble_stack/common/api/co_math.h | 193 + services/ble_stack/common/api/co_utils.h | 501 + services/ble_stack/common/api/co_version.h | 33 + .../common/api/lePhone_rw_ble_error.txt | 370 + services/ble_stack/dbg/api/dbg.h | 53 + services/ble_stack/dbg/api/dbg_mwsgen.h | 199 + services/ble_stack/dbg/api/dbg_swdiag.h | 960 + services/ble_stack/dbg/api/dbg_trc.h | 886 + services/ble_stack/dbg/api/dbg_trc_config.h | 198 + services/ble_stack/dbg/src/dbg_trc_int.h | 146 + services/ble_stack/hci/api/hci_ble.h | 525 + services/ble_stack/hci/src/hci_int.h | 454 + services/ble_stack/hl/api/att.h | 1109 + services/ble_stack/hl/api/gap.h | 1047 + services/ble_stack/hl/api/gapc_task.h | 959 + services/ble_stack/hl/api/gapm_task.h | 1441 + services/ble_stack/hl/api/gattc_task.h | 711 + services/ble_stack/hl/api/gattm_task.h | 375 + services/ble_stack/hl/api/l2cc_task.h | 298 + services/ble_stack/hl/api/prf_types.h | 232 + services/ble_stack/hl/api/rwble_hl_error.h | 415 + services/ble_stack/hl/inc/attm.h | 401 + services/ble_stack/hl/inc/gapc.h | 236 + services/ble_stack/hl/inc/gapm.h | 346 + services/ble_stack/hl/inc/gattc.h | 163 + services/ble_stack/hl/inc/gattm.h | 108 + services/ble_stack/hl/inc/l2cc.h | 244 + services/ble_stack/hl/inc/l2cc_pdu.h | 1092 + services/ble_stack/hl/inc/l2cm.h | 114 + services/ble_stack/hl/inc/prf.h | 293 + services/ble_stack/hl/inc/prf_utils.h | 278 + services/ble_stack/hl/inc/prf_utils_128.h | 115 + services/ble_stack/hl/inc/smpc.h | 314 + services/ble_stack/hl/src/gap/gapc/gapc_int.h | 378 + services/ble_stack/hl/src/gap/gapc/gapc_sig.h | 52 + services/ble_stack/hl/src/gap/gapm/gapm_int.h | 762 + services/ble_stack/hl/src/gap/smp_common.h | 146 + services/ble_stack/hl/src/gap/smpc/smpc_api.h | 547 + .../ble_stack/hl/src/gap/smpc/smpc_crypto.h | 164 + services/ble_stack/hl/src/gap/smpc/smpc_int.h | 498 + .../ble_stack/hl/src/gap/smpc/smpc_util.h | 69 + services/ble_stack/hl/src/gatt/attc/attc.h | 114 + services/ble_stack/hl/src/gatt/attm/attm_db.h | 355 + services/ble_stack/hl/src/gatt/atts/atts.h | 138 + services/ble_stack/hl/src/gatt/gatt.h | 70 + .../ble_stack/hl/src/gatt/gattc/gattc_int.h | 245 + .../ble_stack/hl/src/gatt/gattm/gattm_int.h | 83 + services/ble_stack/hl/src/l2c/l2cc/l2cc_int.h | 196 + .../ble_stack/hl/src/l2c/l2cc/l2cc_lecb.h | 249 + .../ble_stack/hl/src/l2c/l2cc/l2cc_pdu_int.h | 176 + services/ble_stack/hl/src/l2c/l2cc/l2cc_sig.h | 84 + services/ble_stack/hl/src/l2c/l2cm/l2cm_int.h | 153 + services/ble_stack/ke/api/ke.h | 90 + services/ble_stack/ke/api/ke_event.h | 139 + services/ble_stack/ke/api/ke_mem.h | 140 + services/ble_stack/ke/api/ke_msg.h | 305 + services/ble_stack/ke/api/ke_task.h | 219 + services/ble_stack/ke/api/ke_timer.h | 140 + services/ble_stack/ke/src/ke_env.h | 53 + services/ble_stack/ke/src/ke_queue.h | 106 + services/bridge/Makefile | 54 + services/bridge/bridge.h | 58 + services/bt_app/Makefile | 277 + services/bt_app/a2dp_codecs/Makefile | 84 + .../bt_app/a2dp_codecs/aac/a2dp_codec_aac.cpp | 108 + .../bt_app/a2dp_codecs/app_a2dp_codecs.cpp | 241 + .../a2dp_codecs/include/a2dp_codec_aac.h | 53 + .../a2dp_codecs/include/a2dp_codec_ldac.h | 49 + .../a2dp_codecs/include/a2dp_codec_lhdc.h | 35 + .../a2dp_codecs/include/a2dp_codec_opus.h | 34 + .../a2dp_codecs/include/a2dp_codec_sbc.h | 33 + .../a2dp_codecs/include/a2dp_codec_scalable.h | 56 + .../a2dp_codecs/include/app_a2dp_codecs.h | 37 + .../bt_app/a2dp_codecs/include/codec_lhdc.h | 84 + .../a2dp_codecs/ldac/a2dp_codec_ldac.cpp | 89 + .../a2dp_codecs/lhdc/a2dp_codec_lhdc.cpp | 118 + .../bt_app/a2dp_codecs/lhdc/codec_lhdc.cpp | 144 + .../a2dp_codecs/opus/a2dp_codec_opus.cpp | 72 + .../bt_app/a2dp_codecs/sbc/a2dp_codec_sbc.cpp | 95 + .../scalable/a2dp_codec_scalable.cpp | 96 + services/bt_app/app_a2dp.cpp | 4126 + services/bt_app/app_a2dp.h | 40 + services/bt_app/app_a2dp_source.cpp | 872 + services/bt_app/app_a2dp_source.h | 124 + services/bt_app/app_bqb.cpp | 152 + services/bt_app/app_bqb_new_profile.cpp | 277 + services/bt_app/app_bt.cpp | 5277 + services/bt_app/app_bt.h | 254 + services/bt_app/app_bt_func.cpp | 913 + services/bt_app/app_bt_func.h | 351 + services/bt_app/app_bt_hid.cpp | 246 + services/bt_app/app_bt_hid.h | 79 + services/bt_app/app_bt_media_manager.cpp | 2434 + services/bt_app/app_bt_media_manager.h | 144 + services/bt_app/app_bt_stream.cpp | 8185 + services/bt_app/app_bt_stream.h | 242 + services/bt_app/app_bt_trace.h | 77 + services/bt_app/app_btgatt.cpp | 35 + services/bt_app/app_btgatt.h | 31 + services/bt_app/app_btmap_sms.cpp | 242 + services/bt_app/app_btmap_sms.h | 48 + services/bt_app/app_dip.cpp | 142 + services/bt_app/app_dip.h | 38 + services/bt_app/app_fp_rfcomm.cpp | 859 + services/bt_app/app_fp_rfcomm.h | 68 + services/bt_app/app_hfp.cpp | 2154 + services/bt_app/app_hfp.h | 81 + services/bt_app/app_hsp.cpp | 362 + services/bt_app/app_keyhandle.cpp | 1534 + services/bt_app/app_media_player.cpp | 1504 + services/bt_app/app_media_player.h | 180 + services/bt_app/app_rfcomm_mgr.cpp | 382 + services/bt_app/app_rfcomm_mgr.h | 62 + services/bt_app/app_ring_merge.cpp | 403 + services/bt_app/app_ring_merge.h | 47 + services/bt_app/app_sec.cpp | 67 + services/bt_app/app_spp.cpp | 257 + services/bt_app/app_spp.h | 82 + services/bt_app/audio_prompt_sbc.cpp | 1074 + services/bt_app/audio_prompt_sbc.h | 118 + services/bt_app/besbt.h | 52 + services/bt_app/besbt_cfg.h | 41 + services/bt_app/besmain.cpp | 524 + services/bt_app/btapp.h | 423 + services/bt_app/res_audio_data.h | 154 + services/bt_app/res_audio_data_cn.h | 153 + services/bt_app/res_audio_ring.h | 32 + services/bt_if_enhanced/Makefile | 130 + services/bt_if_enhanced/inc/a2dp_api.h | 634 + services/bt_if_enhanced/inc/avctp_api.h | 91 + services/bt_if_enhanced/inc/avdtp_api.h | 223 + services/bt_if_enhanced/inc/avrcp_api.h | 1703 + services/bt_if_enhanced/inc/avtp_api.h | 25 + services/bt_if_enhanced/inc/besaud_api.h | 44 + services/bt_if_enhanced/inc/besble_debug.h | 188 + services/bt_if_enhanced/inc/bluetooth.h | 443 + services/bt_if_enhanced/inc/bt_if.h | 169 + services/bt_if_enhanced/inc/bt_status_conv.h | 45 + services/bt_if_enhanced/inc/bt_xtal_sync.h | 48 + services/bt_if_enhanced/inc/btgatt_api.h | 56 + services/bt_if_enhanced/inc/btif_sys_config.h | 131 + services/bt_if_enhanced/inc/color_log.h | 81 + services/bt_if_enhanced/inc/conmgr_api.h | 203 + services/bt_if_enhanced/inc/dip_api.h | 37 + services/bt_if_enhanced/inc/hci_api.h | 345 + services/bt_if_enhanced/inc/hfp_api.h | 338 + services/bt_if_enhanced/inc/hid_api.h | 73 + services/bt_if_enhanced/inc/hshf_api.h | 408 + services/bt_if_enhanced/inc/l2cap_api.h | 118 + services/bt_if_enhanced/inc/map_api.h | 123 + services/bt_if_enhanced/inc/map_internal.h | 52 + services/bt_if_enhanced/inc/me_api.h | 1374 + services/bt_if_enhanced/inc/mei_api.h | 53 + services/bt_if_enhanced/inc/obex_api.h | 36 + services/bt_if_enhanced/inc/os_api.h | 44 + services/bt_if_enhanced/inc/rfcomm_api.h | 309 + services/bt_if_enhanced/inc/sco_api.h | 43 + services/bt_if_enhanced/inc/sdp_api.h | 521 + services/bt_if_enhanced/inc/spp_api.h | 178 + services/bt_if_enhanced/inc/spp_task.h | 39 + services/bt_if_enhanced/inc/tws_role_switch.h | 101 + services/bt_profiles_enhanced/Makefile | 101 + services/bt_profiles_enhanced/inc/a2dp.h | 187 + services/bt_profiles_enhanced/inc/a2dp_i.h | 179 + services/bt_profiles_enhanced/inc/avctp.h | 43 + services/bt_profiles_enhanced/inc/avctp_i.h | 173 + services/bt_profiles_enhanced/inc/avdtp.h | 333 + services/bt_profiles_enhanced/inc/avdtp_i.h | 302 + services/bt_profiles_enhanced/inc/avrcp.h | 59 + services/bt_profiles_enhanced/inc/avrcp_i.h | 237 + services/bt_profiles_enhanced/inc/bes_os.h | 52 + services/bt_profiles_enhanced/inc/besaud.h | 198 + .../bt_profiles_enhanced/inc/besaudalloc.h | 30 + .../bt_profiles_enhanced/inc/bt_co_list.h | 104 + services/bt_profiles_enhanced/inc/bt_common.h | 34 + .../bt_profiles_enhanced/inc/bt_schedule.h | 32 + .../bt_profiles_enhanced/inc/bt_sys_cfg.h | 413 + services/bt_profiles_enhanced/inc/btgatt.h | 138 + services/bt_profiles_enhanced/inc/btlib.h | 152 + .../bt_profiles_enhanced/inc/btlib_more.h | 25 + .../bt_profiles_enhanced/inc/btlib_type.h | 321 + services/bt_profiles_enhanced/inc/btm.h | 410 + .../bt_profiles_enhanced/inc/btm_devicedb.h | 34 + .../bt_profiles_enhanced/inc/btm_fast_init.h | 15 + .../inc/btm_handle_hcievent.h | 59 + services/bt_profiles_enhanced/inc/btm_hci.h | 551 + services/bt_profiles_enhanced/inc/btm_i.h | 648 + .../bt_profiles_enhanced/inc/btm_security.h | 44 + services/bt_profiles_enhanced/inc/co_lib.h | 27 + services/bt_profiles_enhanced/inc/co_ppbuff.h | 93 + services/bt_profiles_enhanced/inc/co_printf.h | 25 + services/bt_profiles_enhanced/inc/co_queue.h | 53 + services/bt_profiles_enhanced/inc/co_timer.h | 43 + services/bt_profiles_enhanced/inc/cobt.h | 349 + services/bt_profiles_enhanced/inc/cobuf.h | 89 + services/bt_profiles_enhanced/inc/data_link.h | 76 + services/bt_profiles_enhanced/inc/debug_cfg.h | 65 + .../bt_profiles_enhanced/inc/debug_print.h | 131 + services/bt_profiles_enhanced/inc/dip.h | 109 + services/bt_profiles_enhanced/inc/hci.h | 1263 + services/bt_profiles_enhanced/inc/hci_buff.h | 177 + services/bt_profiles_enhanced/inc/hfp.h | 148 + services/bt_profiles_enhanced/inc/hid_i.h | 176 + services/bt_profiles_enhanced/inc/hshf.h | 39 + services/bt_profiles_enhanced/inc/hshf_i.h | 408 + services/bt_profiles_enhanced/inc/l2cap.h | 358 + services/bt_profiles_enhanced/inc/l2cap_er.h | 168 + services/bt_profiles_enhanced/inc/l2cap_i.h | 125 + .../inc/map_bmessage_builder.h | 91 + .../bt_profiles_enhanced/inc/map_protocol.h | 59 + services/bt_profiles_enhanced/inc/map_sdp.h | 63 + .../bt_profiles_enhanced/inc/map_session.h | 212 + services/bt_profiles_enhanced/inc/md5.h | 38 + services/bt_profiles_enhanced/inc/obex.h | 122 + .../inc/obex_ascii_unicode.h | 38 + services/bt_profiles_enhanced/inc/obex_i.h | 84 + services/bt_profiles_enhanced/inc/obex_if.h | 27 + .../bt_profiles_enhanced/inc/obex_protocol.h | 137 + .../bt_profiles_enhanced/inc/obex_session.h | 121 + services/bt_profiles_enhanced/inc/obex_tlv.h | 43 + .../inc/obex_transmission.h | 161 + .../inc/obex_transportlayer.h | 122 + services/bt_profiles_enhanced/inc/overide.h | 1013 + services/bt_profiles_enhanced/inc/packer.h | 35 + services/bt_profiles_enhanced/inc/pbap.h | 20 + services/bt_profiles_enhanced/inc/pbap_i.h | 203 + .../bt_profiles_enhanced/inc/platform_deps.h | 67 + services/bt_profiles_enhanced/inc/rfcomm.h | 236 + services/bt_profiles_enhanced/inc/rfcomm_i.h | 127 + services/bt_profiles_enhanced/inc/sco.h | 32 + services/bt_profiles_enhanced/inc/sco_i.h | 56 + services/bt_profiles_enhanced/inc/sdp.h | 751 + services/bt_profiles_enhanced/inc/sppnew.h | 152 + services/bt_profiles_enhanced/inc/win32_os.h | 127 + services/communication/Makefile | 21 + .../comminication_knowles/Makefile | 24 + .../communication_cmd_handle.cpp | 78 + .../communication_cmd_handle.h | 36 + .../communication_cmd_msg.h | 20 + .../communication_sysapi.cpp | 646 + .../communication_sysapi.h | 92 + .../comminication_knowles/tool_msg.h | 185 + services/communication/communication_svr.cpp | 600 + services/communication/communication_svr.h | 27 + services/cp_accel/Makefile | 15 + services/cp_accel/cp_accel.c | 418 + services/cp_accel/cp_accel.h | 131 + services/cp_accel/cp_queue.c | 137 + services/cp_accel/cp_queue.h | 51 + services/hw_dsp/Makefile | 25 + services/hw_dsp/inc/hw_filter_codec_iir.h | 49 + services/hw_dsp/src/hw_filter_codec_iir.c | 145 + services/ibrt_core/Makefile | 94 + .../ibrt_core/inc/app_ibrt_bt_profile_sync.h | 43 + services/ibrt_core/inc/app_tws_besaud.h | 42 + services/ibrt_core/inc/app_tws_ctrl_thread.h | 76 + services/ibrt_core/inc/app_tws_ibrt.h | 367 + .../inc/app_tws_ibrt_audio_analysis.h | 87 + .../ibrt_core/inc/app_tws_ibrt_audio_sync.h | 146 + .../inc/app_tws_ibrt_cmd_audio_analysis.h | 35 + .../ibrt_core/inc/app_tws_ibrt_cmd_handler.h | 265 + .../inc/app_tws_ibrt_cmd_sync_a2dp_status.h | 38 + .../inc/app_tws_ibrt_cmd_sync_hfp_status.h | 38 + services/ibrt_core/inc/app_tws_ibrt_mock.h | 34 + services/ibrt_core/inc/app_tws_ibrt_queue.h | 33 + services/ibrt_core/inc/app_tws_ibrt_trace.h | 55 + services/ibrt_core/inc/app_tws_profile_sync.h | 84 + services/ibrt_core/inc/app_vendor_cmd_evt.h | 51 + services/ibrt_ota/Makefile | 118 + services/ibrt_ota/inc/ota_bes.h | 44 + services/ibrt_ota/inc/ota_control.h | 426 + services/ibrt_ota/inc/ota_spp.h | 60 + services/ibrt_ui/Makefile | 87 + services/ibrt_ui/inc/app_ibrt_ui.h | 779 + services/interconnection/Makefile | 114 + services/interconnection/umm_malloc/dbglog.h | 104 + .../interconnection/umm_malloc/umm_malloc.c | 619 + .../interconnection/umm_malloc/umm_malloc.h | 57 + services/lhdc_license/Makefile | 24 + services/multimedia/Makefile | 104 + .../algorithm/fft/include/fft128dot.h | 56 + .../algorithm/fft/include/fftr4_fxp.h | 56 + .../audio/codec/fdkaac_codec/ChangeLog | 42 + .../audio/codec/fdkaac_codec/NOTICE | 80 + .../audio/codec/fdkaac_codec/README | 3 + .../libAACdec/include/aacdecoder_lib.h | 770 + .../libAACenc/include/aacenc_lib.h | 1239 + .../fdkaac_codec/libFDK/include/FDK_archdef.h | 266 + .../libFDK/include/FDK_bitbuffer.h | 166 + .../libFDK/include/FDK_bitstream.h | 661 + .../fdkaac_codec/libFDK/include/FDK_core.h | 109 + .../fdkaac_codec/libFDK/include/FDK_crc.h | 231 + .../fdkaac_codec/libFDK/include/FDK_hybrid.h | 273 + .../libFDK/include/FDK_tools_rom.h | 270 + .../libFDK/include/FDK_trigFcts.h | 229 + .../libFDK/include/aarch64/clz_aarch64.h | 122 + .../libFDK/include/aarch64/fixmul_aarch64.h | 113 + .../codec/fdkaac_codec/libFDK/include/abs.h | 121 + .../fdkaac_codec/libFDK/include/arm/clz_arm.h | 122 + .../libFDK/include/arm/cplx_mul.h | 214 + .../libFDK/include/arm/fixmadd_arm.h | 160 + .../libFDK/include/arm/fixmul_arm.h | 142 + .../fdkaac_codec/libFDK/include/arm/scale.h | 152 + .../libFDK/include/arm/scramble.h | 158 + .../fdkaac_codec/libFDK/include/autocorr2nd.h | 128 + .../codec/fdkaac_codec/libFDK/include/clz.h | 198 + .../fdkaac_codec/libFDK/include/common_fix.h | 378 + .../fdkaac_codec/libFDK/include/cplx_mul.h | 269 + .../codec/fdkaac_codec/libFDK/include/dct.h | 147 + .../codec/fdkaac_codec/libFDK/include/fft.h | 253 + .../fdkaac_codec/libFDK/include/fft_rad2.h | 134 + .../fdkaac_codec/libFDK/include/fixmadd.h | 306 + .../fdkaac_codec/libFDK/include/fixminmax.h | 120 + .../fdkaac_codec/libFDK/include/fixmul.h | 292 + .../libFDK/include/fixpoint_math.h | 497 + .../codec/fdkaac_codec/libFDK/include/mdct.h | 243 + .../libFDK/include/mips/abs_mips.h | 107 + .../libFDK/include/mips/clz_mips.h | 118 + .../libFDK/include/mips/cplx_mul.h | 129 + .../libFDK/include/mips/fixmadd_mips.h | 95 + .../libFDK/include/mips/fixmul_mips.h | 113 + .../fdkaac_codec/libFDK/include/mips/scale.h | 110 + .../libFDK/include/mips/scramble.h | 121 + .../fdkaac_codec/libFDK/include/ppc/clz_ppc.h | 102 + .../libFDK/include/ppc/fixmul_ppc.h | 115 + .../codec/fdkaac_codec/libFDK/include/qmf.h | 248 + .../codec/fdkaac_codec/libFDK/include/scale.h | 250 + .../fdkaac_codec/libFDK/include/scramble.h | 165 + .../fdkaac_codec/libFDK/include/x86/abs_x86.h | 106 + .../fdkaac_codec/libFDK/include/x86/clz_x86.h | 154 + .../libFDK/include/x86/fixmul_x86.h | 178 + .../libMpegTPDec/include/mpegFileRead.h | 194 + .../libMpegTPDec/include/tp_data.h | 350 + .../libMpegTPDec/include/tpdec_lib.h | 521 + .../libMpegTPEnc/include/mpegFileWrite.h | 140 + .../libMpegTPEnc/include/tp_data.h | 350 + .../libMpegTPEnc/include/tpenc_lib.h | 296 + .../libPCMutils/include/limiter.h | 233 + .../libPCMutils/include/pcmutils_lib.h | 334 + .../libSBRdec/include/sbrdecoder.h | 347 + .../libSBRenc/include/sbr_encoder.h | 430 + .../fdkaac_codec/libSYS/include/FDK_audio.h | 633 + .../codec/fdkaac_codec/libSYS/include/audio.h | 106 + .../fdkaac_codec/libSYS/include/cmdl_parser.h | 221 + .../fdkaac_codec/libSYS/include/conv_string.h | 136 + .../fdkaac_codec/libSYS/include/genericStds.h | 478 + .../libSYS/include/machine_type.h | 357 + .../fdkaac_codec/libSYS/include/wav_file.h | 233 + .../audio/codec/sbc/inc/codec_sbc.h | 192 + .../audio/process/adp/include/adp_arch.h | 232 + .../audio/process/adp/include/adp_config.h | 50 + .../audio/process/adp/include/adp_fftwrap.h | 58 + .../audio/process/adp/include/adp_filter.h | 47 + .../audio/process/adp/include/adp_smallft.h | 46 + .../multimedia/audio/process/anc/cfg/Makefile | 31 + .../audio/process/anc/cfg/anc_cfg.c | 2295 + .../audio/process/anc/include/anc_process.h | 107 + .../audio/process/anc/include/fftfilt2.h | 37 + .../process/common/include/audio_memory.h | 69 + .../audio/process/drc/include/drc.h | 81 + .../audio/process/filters/cfg/Makefile | 13 + .../audio/process/filters/cfg/eq_cfg.c | 421 + .../audio/process/filters/cfg/eq_cfg.h | 41 + .../process/filters/include/dsd_process.h | 43 + .../filters/include/filter_debug_trace.h | 30 + .../process/filters/include/fir_process.h | 45 + .../filters/include/hw_codec_iir_process.h | 97 + .../process/filters/include/hw_iir_process.h | 67 + .../process/filters/include/iir_process.h | 86 + .../audio/process/fir2iir/include/fir2iir.h | 32 + .../include/integer_resampling.h | 39 + .../audio/process/limiter/include/limiter.h | 29 + .../audio/process/resample/coef/Makefile | 14 + .../coef/resample_16k_to_48k_filter.txt | 16 + .../coef/resample_32k_to_50p7k_filter.txt | 297 + .../coef/resample_44p1k_to_48k_filter.txt | 161 + .../coef/resample_44p1k_to_50p7k_filter.txt | 157 + .../coef/resample_48k_to_44p1k_filter.txt | 148 + .../coef/resample_48k_to_50p7k_filter.txt | 297 + .../coef/resample_50p7k_to_44p1k_filter.txt | 34 + .../coef/resample_50p7k_to_48k_filter.txt | 70 + .../coef/resample_8k_to_8p4k_filter.txt | 224 + .../coef/resample_8p4k_to_8k_filter.txt | 189 + .../coef/resample_any_up256_filter.txt | 257 + .../coef/resample_any_up512_32_filter.txt | 513 + .../coef/resample_any_up512_36_filter.txt | 513 + .../coef/resample_any_up64_filter.txt | 65 + .../process/resample/coef/resample_coef.c | 177 + .../process/resample/include/audio_resample.h | 54 + .../resample/include/audio_resample_ex.h | 85 + .../include/audio_resample_ex_32bit.h | 85 + .../process/resample/include/resample_coef.h | 47 + services/multimedia/speech/inc/Pcm8k_Cvsd.h | 49 + .../multimedia/speech/inc/SubBandBasedAEC.h | 46 + .../speech/inc/VoiceActivityDetection.h | 44 + services/multimedia/speech/inc/ae_macros.h | 7 + services/multimedia/speech/inc/ae_math.h | 93 + services/multimedia/speech/inc/agc.h | 48 + .../multimedia/speech/inc/anc_assist_algo.h | 88 + services/multimedia/speech/inc/audio_drc2.h | 47 + .../multimedia/speech/inc/buffer_manager.h | 52 + services/multimedia/speech/inc/compexp.h | 54 + services/multimedia/speech/inc/crossfade.h | 58 + services/multimedia/speech/inc/cvsd_codec.h | 80 + .../multimedia/speech/inc/dual_mic_denoise.h | 85 + .../multimedia/speech/inc/echo_canceller.h | 76 + services/multimedia/speech/inc/ext_fft_f32.h | 137 + services/multimedia/speech/inc/ext_heap.h | 101 + .../speech/inc/far_field_speech_enhancement.h | 32 + services/multimedia/speech/inc/fftfilt.h | 37 + services/multimedia/speech/inc/frame_resize.h | 52 + services/multimedia/speech/inc/g726.h | 31 + services/multimedia/speech/inc/g72x.h | 112 + services/multimedia/speech/inc/iir_resample.h | 55 + services/multimedia/speech/inc/iirfilt.h | 81 + services/multimedia/speech/inc/lc_mmse_ns.h | 52 + .../multimedia/speech/inc/lc_mmse_ns_float.h | 55 + .../multimedia/speech/inc/leftright_denoise.h | 62 + services/multimedia/speech/inc/lpc_plc_api.h | 41 + .../multimedia/speech/inc/main_classify.h | 34 + .../multimedia/speech/inc/med_aec3_comm.h | 122 + .../multimedia/speech/inc/med_aec3_main.h | 78 + .../speech/inc/med_aec3_main_internal.h | 93 + services/multimedia/speech/inc/ns3.h | 70 + services/multimedia/speech/inc/plc_16000.h | 45 + services/multimedia/speech/inc/plc_8000.h | 40 + services/multimedia/speech/inc/recognition.h | 41 + .../multimedia/speech/inc/sensormic_denoise.h | 65 + .../speech/inc/single_mic_NNDenoise.h | 65 + services/multimedia/speech/inc/spectrum.h | 51 + services/multimedia/speech/inc/spectrum_fix.h | 51 + .../speech/inc/speech_2mic_ns2_denoise.h | 66 + .../multimedia/speech/inc/speech_3mic_ns.h | 57 + services/multimedia/speech/inc/speech_aec.h | 66 + services/multimedia/speech/inc/speech_aec2.h | 58 + services/multimedia/speech/inc/speech_cfg.h | 57 + .../multimedia/speech/inc/speech_config.h | 16 + .../multimedia/speech/inc/speech_dc_filter.h | 66 + services/multimedia/speech/inc/speech_eq.h | 84 + .../speech/inc/speech_ff_2mic_ns2.h | 19 + .../speech/inc/speech_ff_3mic_ns1.h | 18 + .../speech/inc/speech_fir_calibration.h | 54 + services/multimedia/speech/inc/speech_gain.h | 62 + services/multimedia/speech/inc/speech_iir.h | 69 + .../speech/inc/speech_iir_calibration.h | 24 + .../multimedia/speech/inc/speech_memory.h | 55 + .../speech/inc/speech_mics_calibration.h | 89 + .../multimedia/speech/inc/speech_noise_gate.h | 47 + services/multimedia/speech/inc/speech_ns.h | 60 + .../speech/inc/speech_peak_detector.h | 60 + services/multimedia/speech/inc/speech_ssat.h | 90 + services/multimedia/speech/inc/speech_utils.h | 87 + .../multimedia/speech/inc/speex_resampler.h | 238 + .../speech/inc/triple_mic_denoise3.h | 34 + .../speech/inc/wind_detection_2mic.h | 51 + services/multimedia/speech/inc/wnr.h | 33 + services/norflash_api/Makefile | 47 + services/norflash_api/norflash_api.cpp | 1665 + services/norflash_api/norflash_api.h | 225 + services/nv_section/Makefile | 10 + services/nv_section/aud_section/Makefile | 12 + services/nv_section/aud_section/aud_section.c | 215 + services/nv_section/aud_section/aud_section.h | 204 + .../nv_section/aud_section/aud_section_inc.h | 30 + .../nv_section/customparam_section/Makefile | 13 + .../customparam_section/customparam_section.c | 114 + .../customparam_section/customparam_section.h | 69 + services/nv_section/factory_section/Makefile | 16 + .../factory_section/factory_section.c | 273 + .../factory_section/factory_section.h | 74 + services/nv_section/fpga_section/Makefile | 39 + .../nv_section/fpga_section/nvrecord_ble.c | 440 + .../nv_section/fpga_section/nvrecord_ble.h | 49 + .../nv_section/fpga_section/nvrecord_bt.c | 455 + .../nv_section/fpga_section/nvrecord_bt.h | 58 + .../nv_section/fpga_section/nvrecord_env.c | 111 + .../nv_section/fpga_section/nvrecord_env.h | 45 + .../fpga_section/nvrecord_externsion.c | 547 + .../fpga_section/nvrecord_externsion.h | 316 + services/nv_section/include/section_def.h | 37 + services/nv_section/log_section/Makefile | 22 + .../nv_section/log_section/coredump_section.c | 198 + .../nv_section/log_section/coredump_section.h | 36 + .../log_section/crash_dump_section.c | 664 + .../log_section/crash_dump_section.h | 152 + services/nv_section/log_section/log_section.c | 628 + services/nv_section/log_section/log_section.h | 87 + services/nv_section/nv_section_dbg.h | 46 + services/nv_section/userdata_section/Makefile | 63 + .../userdata_section/nvrecord_ble.c | 468 + .../userdata_section/nvrecord_ble.h | 51 + .../nv_section/userdata_section/nvrecord_bt.c | 506 + .../nv_section/userdata_section/nvrecord_bt.h | 54 + .../userdata_section/nvrecord_dma_config.c | 151 + .../userdata_section/nvrecord_dma_config.h | 44 + .../userdata_section/nvrecord_env.c | 116 + .../userdata_section/nvrecord_env.h | 44 + .../userdata_section/nvrecord_extension.c | 1091 + .../userdata_section/nvrecord_extension.h | 362 + .../nvrecord_fp_account_key.c | 168 + .../nvrecord_fp_account_key.h | 49 + .../userdata_section/nvrecord_gsound.c | 426 + .../userdata_section/nvrecord_gsound.h | 129 + .../userdata_section/nvrecord_ota.c | 177 + .../userdata_section/nvrecord_ota.h | 86 + services/nvrecord/Makefile | 28 + services/nvrecord/list_ext.c | 255 + services/nvrecord/list_ext.h | 83 + services/nvrecord/nvrec_config.c | 326 + services/nvrecord/nvrec_config.h | 108 + services/nvrecord/nvrecord.c | 2013 + services/nvrecord/nvrecord.h | 250 + services/nvrecord/nvrecord_ble.c | 331 + services/nvrecord/nvrecord_ble.h | 69 + services/nvrecord/nvrecord_dev.h | 41 + services/nvrecord/nvrecord_env.c | 139 + services/nvrecord/nvrecord_env.h | 94 + services/nvrecord/nvrecord_fp_account_key.c | 156 + services/nvrecord/nvrecord_fp_account_key.h | 61 + services/osif/Makefile | 13 + services/osif/ddbif.h | 44 + services/osif/ddbif_bes.c | 406 + services/osif/osif.h | 67 + services/osif/osif_rtx.c | 195 + services/ota/Makefile | 87 + services/ota/ota_common.cpp | 1649 + services/ota/ota_common.h | 670 + services/ota/ota_dbg.h | 45 + services/overlay/Makefile | 7 + services/overlay/app_overlay.cpp | 76 + services/overlay/app_overlay.h | 73 + services/resources/Makefile | 14 + services/resources/resources.cpp | 388 + services/resources/resources.h | 95 + services/through_put/Makefile | 43 + services/through_put/app_through_put.cpp | 300 + services/through_put/app_through_put.h | 177 + services/tota/Makefile | 94 + services/tota/app_spp_tota.cpp | 373 + services/tota/app_spp_tota.h | 77 + .../tota/app_spp_tota_general_service.cpp | 417 + services/tota/app_spp_tota_general_service.h | 27 + services/tota/app_tota.cpp | 249 + services/tota/app_tota.h | 244 + services/tota/app_tota_anc.cpp | 104 + services/tota/app_tota_anc.h | 38 + services/tota/app_tota_audio_dump.cpp | 181 + services/tota/app_tota_audio_dump.h | 37 + services/tota/app_tota_cmd_code.h | 204 + services/tota/app_tota_cmd_handler.cpp | 515 + services/tota/app_tota_cmd_handler.h | 81 + services/tota/app_tota_conn.cpp | 184 + services/tota/app_tota_conn.h | 31 + services/tota/app_tota_custom.cpp | 109 + services/tota/app_tota_custom.h | 22 + services/tota/app_tota_data_handler.cpp | 176 + services/tota/app_tota_data_handler.h | 96 + services/tota/app_tota_flash_program.cpp | 354 + services/tota/app_tota_flash_program.h | 47 + services/tota/app_tota_general.cpp | 239 + services/tota/app_tota_general.h | 86 + services/tota/app_tota_mic.cpp | 109 + services/tota/app_tota_mic.h | 26 + services/tota/tota_buffer_manager.cpp | 141 + services/tota/tota_buffer_manager.h | 44 + services/tota/tota_stream_data_transfer.cpp | 230 + services/tota/tota_stream_data_transfer.h | 43 + services/tota/tota_test.cpp | 52 + tests/anc_usb/Makefile | 292 + tests/anc_usb/adda_loop_app.c | 211 + tests/anc_usb/adda_loop_app.h | 33 + tests/anc_usb/anc_usb_app.c | 1057 + tests/anc_usb/anc_usb_app.h | 45 + tests/anc_usb/dualadc_audio_app.c | 405 + tests/anc_usb/dualadc_audio_app.h | 38 + tests/anc_usb/main.c | 503 + tests/anc_usb/memutils.c | 94 + tests/anc_usb/memutils.h | 32 + tests/anc_usb/mic_key.c | 154 + tests/anc_usb/safe_queue.c | 161 + tests/anc_usb/safe_queue.h | 44 + tests/anc_usb/speech_process.c | 261 + tests/anc_usb/speech_process.h | 40 + tests/anc_usb/usb_audio_app.c | 6266 + tests/anc_usb/usb_audio_app.h | 66 + tests/anc_usb/usb_audio_frm_defs.h | 232 + tests/anc_usb/usb_vendor_msg.c | 266 + tests/anc_usb/usb_vendor_msg.h | 17 + thirdparty/Makefile | 15 + thirdparty/audio_codec_lib/Makefile | 7 + thirdparty/audio_codec_lib/ldac/Makefile | 14 + thirdparty/audio_codec_lib/ldac/inc/ldacBT.h | 667 + .../audio_codec_lib/liblhdc-dec/Makefile | 56 + .../liblhdc-dec/inc/lhdcUtil.h | 56 + thirdparty/demo_lib/Makefile | 11 + thirdparty/demo_lib/demo_lib.c | 11 + thirdparty/demo_lib/demo_lib.h | 16 + thirdparty/noise_tracker_lib/Makefile | 9 + thirdparty/noise_tracker_lib/noise_tracker.c | 59 + thirdparty/noise_tracker_lib/noise_tracker.h | 20 + thirdparty/userapi/Makefile | 13 + thirdparty/userapi/app_thirdparty.cpp | 131 + thirdparty/userapi/app_thirdparty.h | 157 + thirdparty/userapi/demo_app/LibDemo.cpp | 41 + thirdparty/userapi/demo_app/LibDemo.h | 23 + thirdparty/userapi/demo_app/Makefile | 16 + thirdparty/userapi/noise_tracker_app/Makefile | 28 + .../noise_tracker_app/NoiseTrackerDemo.cpp | 209 + .../noise_tracker_callback.c | 14 + .../noise_tracker_callback.h | 14 + utils/boot_struct/Makefile | 11 + utils/boot_struct/boot_struct.c | 213 + utils/boot_struct/norflash_cfg.h | 90 + utils/boot_struct/reboot_param.h | 34 + utils/boot_struct/tool_msg.h | 265 + utils/build_info/build_info.c | 67 + utils/cqueue/Makefile | 17 + utils/cqueue/cqueue.c | 420 + utils/cqueue/cqueue.h | 73 + utils/crash_catcher/CrashCatcher.c | 405 + utils/crash_catcher/CrashCatcherPriv.h | 77 + utils/crash_catcher/CrashCatcher_armv7m.S | 112 + utils/crash_catcher/HexDump.c | 244 + utils/crash_catcher/Makefile | 16 + utils/crash_catcher/include/CrashCatcher.h | 158 + utils/crash_catcher/include/CrashCatcherApi.h | 28 + utils/crash_catcher/include/FloatMocks.h | 29 + utils/crc16/Makefile | 4 + utils/crc16/crc16.c | 74 + utils/crc16/crc16.h | 35 + utils/crc32/Makefile | 18 + utils/crc32/crc32.c | 134 + utils/crc32/crc32.h | 30 + utils/crc32/crc32_rom.c | 24 + utils/encrypt/Makefile | 17 + utils/encrypt/_sha256.h | 86 + utils/encrypt/aes.h | 47 + utils/encrypt/types.h | 108 + utils/encrypt/uECC.h | 365 + utils/encrypt/uECC_vli.h | 172 + utils/heap/Makefile | 11 + utils/heap/heap_api.c | 236 + utils/heap/heap_api.h | 83 + utils/heap/med_memory.h | 1 + utils/heap/multi_heap.c | 754 + utils/heap/multi_heap.h | 172 + utils/heap/multi_heap_internal.h | 70 + utils/heap/multi_heap_platform.h | 93 + utils/heap/pool_api.c | 97 + utils/hexdump/Makefile | 7 + utils/hexdump/hexdump.c | 82 + utils/hexdump/hexdump.h | 32 + utils/hwtimer_list/Makefile | 11 + utils/hwtimer_list/hwtimer_list.c | 587 + utils/hwtimer_list/hwtimer_list.h | 55 + utils/intersyshci/Makefile | 50 + utils/intersyshci/intersyshci.h | 45 + utils/intersyshci/trans_adapt.h | 34 + utils/intersyshci/trans_adapt_v1.h | 32 + utils/intersyshci/trans_adapt_v2.h | 32 + utils/kfifo/Makefile | 22 + utils/kfifo/kfifo.c | 148 + utils/kfifo/kfifo.h | 28 + utils/libc/Makefile | 36 + utils/libc/inc/assert.h | 27 + utils/libc/inc/ctype.h | 55 + utils/libc/inc/errno.h | 131 + utils/libc/inc/stdarg.h | 133 + utils/libc/inc/stdbool.h | 12 + utils/libc/inc/stddef.h | 12 + utils/libc/inc/stdint.h | 224 + utils/libc/inc/stdio.h | 30 + utils/libc/inc/stdlib.h | 33 + utils/libc/inc/string.h | 70 + utils/libc/libc_rom.c | 165 + utils/list/Makefile | 7 + utils/list/list.c | 321 + utils/list/list.h | 89 + utils/lockcqueue/Makefile | 10 + utils/lockcqueue/lockcqueue.c | 50 + utils/lockcqueue/lockcqueue.h | 45 + utils/retention_ram/Makefile | 10 + utils/retention_ram/retention_ram.c | 81 + utils/retention_ram/retention_ram.h | 35 + utils/rom_utils/Makefile | 25 + utils/rom_utils/export_fn_rom.h | 109 + utils/sha256/Makefile | 14 + utils/sha256/hash-internal.h | 66 + utils/sha256/sha256.c | 281 + utils/sha256/sha256.h | 56 + utils/sha256/sha256_rom.c | 39 + utils/xyzmodem/Makefile | 10 + utils/xyzmodem/xyzmodem.c | 385 + utils/xyzmodem/xyzmodem.h | 15 + 2046 files changed, 901681 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 apps/Makefile create mode 100644 apps/anc/Makefile create mode 100644 apps/anc/inc/anc_assist.h create mode 100644 apps/anc/inc/anc_wnr.h create mode 100644 apps/anc/inc/app_anc.h create mode 100644 apps/anc/inc/peak_detector.h create mode 100644 apps/anc/src/anc_assist.c create mode 100644 apps/anc/src/anc_wnr.c create mode 100644 apps/anc/src/app_anc.c create mode 100644 apps/anc/src/peak_detector.c create mode 100644 apps/apptester/Makefile create mode 100644 apps/apptester/app_audtest.cpp create mode 100644 apps/apptester/app_audtest.h create mode 100644 apps/apptester/app_audtest_pattern.h create mode 100644 apps/apptester/audiobuffer.c create mode 100644 apps/apptester/audiobuffer.h create mode 100644 apps/audioplayers/Makefile create mode 100644 apps/audioplayers/a2dp_decoder/Makefile create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder.cpp create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder.h create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder_aac_lc.cpp create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder_cp.c create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder_cp.h create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder_example.cpp create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder_internal.h create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder_ldac.cpp create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder_lhdc.cpp create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder_sbc.cpp create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder_scalable.cpp create mode 100644 apps/audioplayers/a2dp_decoder/a2dp_decoder_trace.h create mode 100644 apps/audioplayers/a2dpplay.cpp create mode 100644 apps/audioplayers/app_audio.cpp create mode 100644 apps/audioplayers/app_audio.h create mode 100644 apps/audioplayers/bt_sco_chain.c create mode 100644 apps/audioplayers/bt_sco_chain.h create mode 100644 apps/audioplayers/bt_sco_chain_cfg.h create mode 100644 apps/audioplayers/bt_sco_chain_cfg_default.c create mode 100644 apps/audioplayers/bt_sco_chain_cp.c create mode 100644 apps/audioplayers/bt_sco_chain_cp.h create mode 100644 apps/audioplayers/bt_sco_chain_thirdparty.c create mode 100644 apps/audioplayers/bt_sco_chain_thirdparty_alango.c create mode 100644 apps/audioplayers/bt_sco_chain_tuning.c create mode 100644 apps/audioplayers/bt_sco_chain_tuning.h create mode 100644 apps/audioplayers/cvsdplay.cpp create mode 100644 apps/audioplayers/digmici2splay.cpp create mode 100644 apps/audioplayers/flacplay.cpp create mode 100644 apps/audioplayers/fmradio.cpp create mode 100644 apps/audioplayers/fmradio.h create mode 100644 apps/audioplayers/msbcplay.cpp create mode 100644 apps/audioplayers/plc_utils.c create mode 100644 apps/audioplayers/plc_utils.h create mode 100644 apps/audioplayers/rbplay/rb_ctl.cpp create mode 100644 apps/audioplayers/rbplay/rb_ctl.h create mode 100644 apps/audioplayers/rbplay/rbpcmbuf.cpp create mode 100644 apps/audioplayers/rbplay/rbpcmbuf.h create mode 100644 apps/audioplayers/rbplay/rbplay.cpp create mode 100644 apps/audioplayers/rbplay/rbplay.h create mode 100644 apps/audioplayers/rbplay/rbplaysd.cpp create mode 100644 apps/audioplayers/rbplay/rbplaysd.h create mode 100644 apps/audioplayers/rbplay/utils.h create mode 100644 apps/audioplayers/voice_test.c create mode 100644 apps/audioplayers/voicebtpcmplay.cpp create mode 100644 apps/audioplayers/voicebtpcmplay_sco_dma_snapshot.cpp create mode 100644 apps/audioplayers/wavplay.cpp create mode 100644 apps/battery/Makefile create mode 100644 apps/battery/app_battery.cpp create mode 100644 apps/battery/app_battery.h create mode 100644 apps/btusbaudio/Makefile create mode 100644 apps/btusbaudio/btusb_audio.c create mode 100644 apps/btusbaudio/btusb_audio.h create mode 100644 apps/btusbaudio/usbaudio_thread.c create mode 100644 apps/btusbaudio/usbaudio_thread.h create mode 100644 apps/cmd/Makefile create mode 100644 apps/cmd/app_cmd.cpp create mode 100644 apps/cmd/app_cmd.h create mode 100644 apps/common/Makefile create mode 100644 apps/common/app_spec_ostimer.cpp create mode 100644 apps/common/app_spec_ostimer.h create mode 100644 apps/common/app_thread.c create mode 100644 apps/common/app_thread.h create mode 100644 apps/common/app_utils.c create mode 100644 apps/common/app_utils.h create mode 100644 apps/common/randfrommic.c create mode 100644 apps/common/randfrommic.h create mode 100644 apps/factory/1k_2ch_44k_16bit.txt create mode 100644 apps/factory/1k_2ch_48k_16bit.txt create mode 100644 apps/factory/Makefile create mode 100644 apps/factory/app_factory.cpp create mode 100644 apps/factory/app_factory.h create mode 100644 apps/factory/app_factory_audio.cpp create mode 100644 apps/factory/app_factory_audio.h create mode 100644 apps/factory/app_factory_bt.cpp create mode 100644 apps/factory/app_factory_bt.h create mode 100644 apps/factory/app_factory_cdc_comm.c create mode 100644 apps/factory/app_factory_cdc_comm.h create mode 100644 apps/factory/sys_api_cdc_comm.c create mode 100644 apps/factory/sys_api_cdc_comm.h create mode 100644 apps/key/Makefile create mode 100644 apps/key/app_key.cpp create mode 100644 apps/key/app_key.h create mode 100644 apps/main/Makefile create mode 100644 apps/main/app_status_ind.h create mode 100644 apps/main/apps.cpp create mode 100644 apps/main/apps.h create mode 100644 apps/main/apps_tester.cpp create mode 100644 apps/mic/Makefile create mode 100644 apps/mic/app_mic.cpp create mode 100644 apps/mic/app_mic.h create mode 100644 apps/pwl/Makefile create mode 100644 apps/pwl/app_pwl.cpp create mode 100644 apps/pwl/app_pwl.h create mode 100644 apps/sdmmc/Makefile create mode 100644 apps/sdmmc/app_sdmmc.cpp create mode 100644 apps/sdmmc/app_sdmmc.h create mode 100644 apps/usbaudio/Makefile create mode 100644 apps/usbaudio/usbaudio_entry.c create mode 100644 apps/usbhost/Makefile create mode 100644 apps/usbhost/app_usbhost.c create mode 100644 apps/usbhost/app_usbhost.h create mode 100644 apps/voice_detector/Makefile create mode 100644 apps/voice_detector/app_voice_detector.cpp create mode 100644 apps/voice_detector/app_voice_detector.h create mode 100644 apps/voice_detector/vad_sensor.h create mode 100644 apps/voice_detector/voice_detector.c create mode 100644 apps/voice_detector/voice_detector.h create mode 100644 config/Makefile create mode 100644 config/_default_cfg_src_/app_status_ind.c create mode 100644 config/_default_cfg_src_/res/SOUND_MUTE.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_ANSWER.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_CHARGE_FINISH.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_CHARGE_PLEASE.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_CONNECTED.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_DIS_CONNECT.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_EIGHT.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_FINDME.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_FIVE.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_FOUR.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_HUNG_UP.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_INCOMING_CALL.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_LANGUAGE_SWITCH.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_NINE.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_ONE.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_OVER.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_PAIRING.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_PAIRING_FAIL.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_PAIRING_SUCCESS.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_PAIR_ENABLE.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_POWER_OFF.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_POWER_ON.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_REFUSE.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_SEVEN.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_SIX.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_THREE.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_TWO.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_WARNING.txt create mode 100644 config/_default_cfg_src_/res/cn/SOUND_ZERO.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_ALEXA_START.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_ALEXA_STOP.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_ANSWER.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_CHARGE_FINISH.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_CHARGE_PLEASE.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_CONNECTED.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_DIS_CONNECT.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_EIGHT.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_FINDME.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_FIVE.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_FOUR.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_GSOUND_MIC_CLOSE.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_GSOUND_MIC_OPEN.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_GSOUND_NC.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_HUNG_UP.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_INCOMING_CALL.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_LANGUAGE_SWITCH.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_NINE.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_ONE.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_OVER.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_PAIRING.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_PAIRING_FAIL.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_PAIRING_SUCCESS.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_PAIR_ENABLE.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_POWER_OFF.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_POWER_ON.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_REFUSE.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_SEVEN.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_SIX.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_THREE.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_TWO.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_WARNING.txt create mode 100644 config/_default_cfg_src_/res/en/SOUND_ZERO.txt create mode 100644 config/_default_cfg_src_/res/en/dudu.txt create mode 100644 config/_default_cfg_src_/res/eq/EQ_COEF.txt create mode 100644 config/_default_cfg_src_/res/gs_hw/en_all.txt create mode 100644 config/_default_cfg_src_/res/ring/SOUND_RING_16000.txt create mode 100644 config/_default_cfg_src_/res/ring/SOUND_RING_44100.txt create mode 100644 config/_default_cfg_src_/res/ring/SOUND_RING_48000.txt create mode 100644 config/_default_cfg_src_/res/ring/SOUND_RING_8000.txt create mode 100644 config/_default_cfg_src_/slave_code.S create mode 100644 config/_default_cfg_src_/tgt_hardware.c create mode 100644 config/_default_cfg_src_/tgt_hardware.h create mode 100644 config/best2300p_ibrt/target.mk create mode 100644 config/best2300p_ibrt/tgt_hardware.c create mode 100644 config/best2300p_ibrt/tgt_hardware.h create mode 100644 config/best2300p_ibrt_anc/target.mk create mode 100644 config/best2300p_ibrt_anc/tgt_hardware.c create mode 100644 config/best2300p_ibrt_anc/tgt_hardware.h create mode 100644 config/common.mk create mode 100644 include/rtos/freertos/FreeRTOS.h create mode 100644 include/rtos/freertos/FreeRTOSConfig.h create mode 100644 include/rtos/freertos/StackMacros.h create mode 100644 include/rtos/freertos/cmsis_os.h create mode 100644 include/rtos/freertos/cmsis_os2.h create mode 100644 include/rtos/freertos/croutine.h create mode 100644 include/rtos/freertos/deprecated_definitions.h create mode 100644 include/rtos/freertos/event_groups.h create mode 100644 include/rtos/freertos/freertos_evr.h create mode 100644 include/rtos/freertos/freertos_list.h create mode 100644 include/rtos/freertos/message_buffer.h create mode 100644 include/rtos/freertos/mpu_prototypes.h create mode 100644 include/rtos/freertos/mpu_wrappers.h create mode 100644 include/rtos/freertos/portable.h create mode 100644 include/rtos/freertos/portmacro.h create mode 100644 include/rtos/freertos/projdefs.h create mode 100644 include/rtos/freertos/queue.h create mode 100644 include/rtos/freertos/semphr.h create mode 100644 include/rtos/freertos/stack_macros.h create mode 100644 include/rtos/freertos/stdint.readme create mode 100644 include/rtos/freertos/stream_buffer.h create mode 100644 include/rtos/freertos/task.h create mode 100644 include/rtos/freertos/timers.h create mode 100644 include/rtos/rtx/cmsis_os.h create mode 100644 include/rtos/rtx/os_tcb.h create mode 100644 include/rtos/rtx5/cmsis_os.h create mode 100644 include/rtos/rtx5/cmsis_os2.h create mode 100644 include/rtos/rtx5/os_tick.h create mode 100644 include/rtos/rtx5/rtx_evr.h create mode 100644 include/rtos/rtx5/rtx_os.h create mode 100644 platform/Makefile create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/BasicMathFunctions.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/Makefile create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_f32.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q15.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q31.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q7.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_f32.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q15.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q31.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q7.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_f32.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q15.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q31.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q7.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_f32.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q15.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q31.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q7.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_f32.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q15.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q31.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q7.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_f32.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q15.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q31.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q7.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_f32.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q15.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q31.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q7.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q15.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q31.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q7.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_f32.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q15.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q31.c create mode 100644 platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q7.c create mode 100644 platform/cmsis/DSP_Lib/CommonTables/CommonTables.c create mode 100644 platform/cmsis/DSP_Lib/CommonTables/Makefile create mode 100644 platform/cmsis/DSP_Lib/CommonTables/arm_common_tables.c create mode 100644 platform/cmsis/DSP_Lib/CommonTables/arm_const_structs.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/ComplexMathFunctions.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/Makefile create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_f32.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_q15.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_q31.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_f32.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_q15.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_q31.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_f32.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_q15.c create mode 100644 platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_q31.c create mode 100644 platform/cmsis/DSP_Lib/ControllerFunctions/ControllerFunctions.c create mode 100644 platform/cmsis/DSP_Lib/ControllerFunctions/Makefile create mode 100644 platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_f32.c create mode 100644 platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_q15.c create mode 100644 platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_q31.c create mode 100644 platform/cmsis/DSP_Lib/ControllerFunctions/arm_sin_cos_f32.c create mode 100644 platform/cmsis/DSP_Lib/ControllerFunctions/arm_sin_cos_q31.c create mode 100644 platform/cmsis/DSP_Lib/FastMathFunctions/FastMathFunctions.c create mode 100644 platform/cmsis/DSP_Lib/FastMathFunctions/Makefile create mode 100644 platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_f32.c create mode 100644 platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_q15.c create mode 100644 platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_q31.c create mode 100644 platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_f32.c create mode 100644 platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_q15.c create mode 100644 platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_q31.c create mode 100644 platform/cmsis/DSP_Lib/FastMathFunctions/arm_sqrt_q15.c create mode 100644 platform/cmsis/DSP_Lib/FastMathFunctions/arm_sqrt_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/FilteringFunctions.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/Makefile create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_f64.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_opt_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_opt_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_opt_q7.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_opt_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_opt_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_opt_q7.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q7.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q7.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_opt_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_opt_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_opt_q7.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q7.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_fast_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_fast_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_fast_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_fast_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q7.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q7.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q7.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q7.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_q31.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_q15.c create mode 100644 platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_q31.c create mode 100644 platform/cmsis/DSP_Lib/Makefile create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/Makefile create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/MatrixFunctions.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_f32.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_q15.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_q31.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_f32.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_q15.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_q31.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_inverse_f32.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_inverse_f64.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_f32.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_fast_q15.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_fast_q31.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_q15.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_q31.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_f32.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_q15.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_q31.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_f32.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_q15.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_q31.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_f32.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_q15.c create mode 100644 platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_q31.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/Makefile create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/StatisticsFunctions.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_f32.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q15.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q31.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q7.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_f32.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q15.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q31.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q7.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_f32.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q15.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q31.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q7.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_f32.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q15.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q31.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q7.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_f32.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_q15.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_q31.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_f32.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_q15.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_q31.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_f32.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_q15.c create mode 100644 platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_q31.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/Makefile create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/SupportFunctions.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_f32.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q15.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q31.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q7.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_f32.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q15.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q31.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q7.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q15.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q31.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q7.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_float.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_q31.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_q7.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_float.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_q15.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_q7.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_float.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_q15.c create mode 100644 platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_q31.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/Makefile create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/TransformFunctions.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal2.S create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal2.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_q15.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_q31.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_q15.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_q31.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_q15.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_q31.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix8_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_q15.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_q31.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_fast_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_fast_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_f32.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_q15.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_q31.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_q15.c create mode 100644 platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_q31.c create mode 100644 platform/cmsis/LICENSE.txt create mode 100644 platform/cmsis/Makefile create mode 100644 platform/cmsis/ca/Makefile create mode 100644 platform/cmsis/ca/cmsis_gic.c create mode 100644 platform/cmsis/ca/default_irq_ca.S create mode 100644 platform/cmsis/ca/irq_ctrl_gic.c create mode 100644 platform/cmsis/ca/mmu_ARMCA.c create mode 100644 platform/cmsis/ca/startup_ARMCA.c create mode 100644 platform/cmsis/ca/system_ARMCA.c create mode 100644 platform/cmsis/cmsis_nvic.c create mode 100644 platform/cmsis/inc/arm_common_tables.h create mode 100644 platform/cmsis/inc/arm_const_structs.h create mode 100644 platform/cmsis/inc/arm_math.h create mode 100644 platform/cmsis/inc/best1000.h create mode 100644 platform/cmsis/inc/best1400.h create mode 100644 platform/cmsis/inc/best2000.h create mode 100644 platform/cmsis/inc/best2001.h create mode 100644 platform/cmsis/inc/best2300.h create mode 100644 platform/cmsis/inc/best2300a.h create mode 100644 platform/cmsis/inc/best2300p.h create mode 100644 platform/cmsis/inc/best3001.h create mode 100644 platform/cmsis/inc/best3003.h create mode 100644 platform/cmsis/inc/ca/best2001_dsp.h create mode 100644 platform/cmsis/inc/ca/cmsis_armcc_ca.h create mode 100644 platform/cmsis/inc/ca/cmsis_armclang_ca.h create mode 100644 platform/cmsis/inc/ca/cmsis_compiler_ca.h create mode 100644 platform/cmsis/inc/ca/cmsis_cp15_ca.h create mode 100644 platform/cmsis/inc/ca/cmsis_gcc_ca.h create mode 100644 platform/cmsis/inc/ca/cmsis_iccarm_ca.h create mode 100644 platform/cmsis/inc/ca/core_ca.h create mode 100644 platform/cmsis/inc/ca/irq_ctrl.h create mode 100644 platform/cmsis/inc/ca/mem_ARMCA.h create mode 100644 platform/cmsis/inc/ca/system_ARMCA.h create mode 100644 platform/cmsis/inc/cmsis.h create mode 100644 platform/cmsis/inc/cmsis_armcc.h create mode 100644 platform/cmsis/inc/cmsis_armclang.h create mode 100644 platform/cmsis/inc/cmsis_armclang_ltm.h create mode 100644 platform/cmsis/inc/cmsis_compiler.h create mode 100644 platform/cmsis/inc/cmsis_gcc.h create mode 100644 platform/cmsis/inc/cmsis_iccarm.h create mode 100644 platform/cmsis/inc/cmsis_nvic.h create mode 100644 platform/cmsis/inc/cmsis_version.h create mode 100644 platform/cmsis/inc/core_armv81mml.h create mode 100644 platform/cmsis/inc/core_armv8mbl.h create mode 100644 platform/cmsis/inc/core_armv8mml.h create mode 100644 platform/cmsis/inc/core_cm0.h create mode 100644 platform/cmsis/inc/core_cm0plus.h create mode 100644 platform/cmsis/inc/core_cm1.h create mode 100644 platform/cmsis/inc/core_cm23.h create mode 100644 platform/cmsis/inc/core_cm3.h create mode 100644 platform/cmsis/inc/core_cm33.h create mode 100644 platform/cmsis/inc/core_cm35p.h create mode 100644 platform/cmsis/inc/core_cm4.h create mode 100644 platform/cmsis/inc/core_cm7.h create mode 100644 platform/cmsis/inc/core_sc000.h create mode 100644 platform/cmsis/inc/core_sc300.h create mode 100644 platform/cmsis/inc/fpga1000.h create mode 100644 platform/cmsis/inc/link_sym_armclang.h create mode 100644 platform/cmsis/inc/main_entry.h create mode 100644 platform/cmsis/inc/mpu.h create mode 100644 platform/cmsis/inc/mpu_armv7.h create mode 100644 platform/cmsis/inc/mpu_armv8.h create mode 100644 platform/cmsis/inc/patch.h create mode 100644 platform/cmsis/inc/system_ARMCM.h create mode 100644 platform/cmsis/inc/system_cp.h create mode 100644 platform/cmsis/inc/tz_context.h create mode 100644 platform/cmsis/mpu_armv7m.c create mode 100644 platform/cmsis/mpu_armv8m.c create mode 100644 platform/cmsis/patch.c create mode 100644 platform/cmsis/patch_armv7m.c create mode 100644 platform/cmsis/reg_patch.h create mode 100644 platform/cmsis/reg_patch_armv7m.h create mode 100644 platform/cmsis/retarget_armclang.cpp create mode 100644 platform/cmsis/retarget_armclang_asm.S create mode 100644 platform/cmsis/retarget_gcc.cpp create mode 100644 platform/cmsis/stack_protector.c create mode 100644 platform/cmsis/system_ARMCM.c create mode 100644 platform/cmsis/system_cp.c create mode 100644 platform/cmsis/system_utils.c create mode 100644 platform/drivers/Makefile create mode 100644 platform/drivers/ana/Makefile create mode 100644 platform/drivers/ana/analog.h create mode 100644 platform/drivers/ana/best2300p/Makefile create mode 100644 platform/drivers/ana/best2300p/analog_best2300p.c create mode 100644 platform/drivers/ana/best2300p/analog_best2300p.h create mode 100644 platform/drivers/ana/best2300p/pmu_best2300p.c create mode 100644 platform/drivers/ana/best2300p/pmu_best2300p.h create mode 100644 platform/drivers/ana/best2300p/reg_usbphy_best2300p.h create mode 100644 platform/drivers/ana/best2300p/usbphy_best2300p.c create mode 100644 platform/drivers/ana/best2300p/usbphy_best2300p.h create mode 100644 platform/drivers/ana/pmu.h create mode 100644 platform/drivers/ana/psramuhsphy.h create mode 100644 platform/drivers/ana/usbphy.h create mode 100644 platform/drivers/bt/Makefile create mode 100644 platform/drivers/bt/besbt_string.h create mode 100644 platform/drivers/bt/best2300p/Makefile create mode 100644 platform/drivers/bt/best2300p/bt_drv.cpp create mode 100644 platform/drivers/bt/best2300p/bt_drv_2300p_internal.h create mode 100644 platform/drivers/bt/best2300p/bt_drv_calibration.cpp create mode 100644 platform/drivers/bt/best2300p/bt_drv_config.c create mode 100644 platform/drivers/bt/best2300p/bt_drv_patch.c create mode 100644 platform/drivers/bt/best2300p/bt_drv_reg_op.cpp create mode 100644 platform/drivers/bt/best2300p/bt_drv_rfconfig.c create mode 100644 platform/drivers/bt/best2300p/bt_drv_uart_bridge_intsys.c create mode 100644 platform/drivers/bt/best2300p/iqcorrect.c create mode 100644 platform/drivers/bt/best2300p/iqcorrect.h create mode 100644 platform/drivers/bt/bt_drv.h create mode 100644 platform/drivers/bt/bt_drv_common.c create mode 100644 platform/drivers/bt/bt_drv_interface.h create mode 100644 platform/drivers/bt/bt_drv_internal.h create mode 100644 platform/drivers/bt/bt_drv_reg_op.h create mode 100644 platform/drivers/btpcm/Makefile create mode 100644 platform/drivers/btpcm/btpcm.c create mode 100644 platform/drivers/btpcm/btpcm.h create mode 100644 platform/drivers/codec/Makefile create mode 100644 platform/drivers/codec/best2300p/Makefile create mode 100644 platform/drivers/codec/best2300p/codec_best2300p.c create mode 100644 platform/drivers/codec/best2300p/codec_best2300p.h create mode 100644 platform/drivers/codec/codec_int.h create mode 100644 platform/drivers/codec/codec_tlv32aic32.c create mode 100644 platform/drivers/codec/codec_tlv32aic32.h create mode 100644 platform/drivers/norflash/Makefile create mode 100644 platform/drivers/norflash/norflash_drv.c create mode 100644 platform/drivers/norflash/norflash_drv.h create mode 100644 platform/drivers/norflash/norflash_en25s80b.c create mode 100644 platform/drivers/norflash/norflash_en25s80b.h create mode 100644 platform/drivers/norflash/norflash_gd25lq32c.c create mode 100644 platform/drivers/norflash/norflash_gd25lq32c.h create mode 100644 platform/drivers/norflash/norflash_gd25q32c.c create mode 100644 platform/drivers/norflash/norflash_gd25q32c.h create mode 100644 platform/drivers/sbcacc/Makefile create mode 100644 platform/drivers/usb/Makefile create mode 100644 platform/drivers/usb/usb_dev/Makefile create mode 100644 platform/drivers/usb/usb_dev/cfg/usb_dev_desc.c create mode 100644 platform/drivers/usb/usb_dev/inc/usb_audio.h create mode 100644 platform/drivers/usb/usb_dev/inc/usb_audio_sync.h create mode 100644 platform/drivers/usb/usb_dev/inc/usb_cdc.h create mode 100644 platform/drivers/usb/usb_dev/inc/usb_descriptor.h create mode 100644 platform/drivers/usb/usb_dev/inc/usb_dev_desc.h create mode 100644 platform/drivers/usb/usb_dev/uaud_cfg_flags.mk create mode 100644 platform/drivers/usb/usb_host/Makefile create mode 100644 platform/drivers/usb/usb_host/inc/USBHost.h create mode 100644 platform/drivers/usb/usb_host/inc/usb_tester.h create mode 100644 platform/hal/Makefile create mode 100644 platform/hal/best2300p/Makefile create mode 100644 platform/hal/best2300p/hal_analogif_best2300p.c create mode 100644 platform/hal/best2300p/hal_cmu_best2300p.c create mode 100644 platform/hal/best2300p/hal_cmu_best2300p.h create mode 100644 platform/hal/best2300p/hal_codec_best2300p.c create mode 100644 platform/hal/best2300p/hal_dmacfg_best2300p.h create mode 100644 platform/hal/best2300p/hal_iomux_best2300p.c create mode 100644 platform/hal/best2300p/hal_iomux_best2300p.h create mode 100644 platform/hal/best2300p/hal_psc_best2300p.c create mode 100644 platform/hal/best2300p/hal_sensor_eng_best2300p.c create mode 100644 platform/hal/best2300p/plat_addr_map_best2300p.h create mode 100644 platform/hal/best2300p/reg_aoncmu_best2300p.h create mode 100644 platform/hal/best2300p/reg_btcmu_best2300p.h create mode 100644 platform/hal/best2300p/reg_cmu_best2300p.h create mode 100644 platform/hal/best2300p/reg_codec_best2300p.h create mode 100644 platform/hal/best2300p/reg_iomux_best2300p.h create mode 100644 platform/hal/best2300p/reg_psc_best2300p.h create mode 100644 platform/hal/best2300p/reg_sensor_eng_best2300p.h create mode 100644 platform/hal/hal_analogif.h create mode 100644 platform/hal/hal_aud.h create mode 100644 platform/hal/hal_bootmode.c create mode 100644 platform/hal/hal_bootmode.h create mode 100644 platform/hal/hal_btdump.c create mode 100644 platform/hal/hal_btdump.h create mode 100644 platform/hal/hal_btpcm.c create mode 100644 platform/hal/hal_btpcm.h create mode 100644 platform/hal/hal_btpcmip.h create mode 100644 platform/hal/hal_cache.c create mode 100644 platform/hal/hal_cache.h create mode 100644 platform/hal/hal_chipid.c create mode 100644 platform/hal/hal_chipid.h create mode 100644 platform/hal/hal_cmd.c create mode 100644 platform/hal/hal_cmd.h create mode 100644 platform/hal/hal_cmu.h create mode 100644 platform/hal/hal_cmu_common.c create mode 100644 platform/hal/hal_codec.h create mode 100644 platform/hal/hal_codec_common.c create mode 100644 platform/hal/hal_dma.c create mode 100644 platform/hal/hal_dma.h create mode 100644 platform/hal/hal_gpadc.c create mode 100644 platform/hal/hal_gpadc.h create mode 100644 platform/hal/hal_gpio.c create mode 100644 platform/hal/hal_gpio.h create mode 100644 platform/hal/hal_hwfft.h create mode 100644 platform/hal/hal_i2c.c create mode 100644 platform/hal/hal_i2c.h create mode 100644 platform/hal/hal_i2cip.h create mode 100644 platform/hal/hal_i2s.c create mode 100644 platform/hal/hal_i2s.h create mode 100644 platform/hal/hal_i2s_tdm.c create mode 100644 platform/hal/hal_i2s_tdm.h create mode 100644 platform/hal/hal_i2sip.h create mode 100644 platform/hal/hal_intersys.c create mode 100644 platform/hal/hal_intersys.h create mode 100644 platform/hal/hal_iomux.h create mode 100644 platform/hal/hal_key.c create mode 100644 platform/hal/hal_key.h create mode 100644 platform/hal/hal_location.h create mode 100644 platform/hal/hal_mcu2cp.c create mode 100644 platform/hal/hal_mcu2cp.h create mode 100644 platform/hal/hal_memsc.c create mode 100644 platform/hal/hal_memsc.h create mode 100644 platform/hal/hal_norflash.c create mode 100644 platform/hal/hal_norflash.h create mode 100644 platform/hal/hal_norflaship.h create mode 100644 platform/hal/hal_norflaship_v1.c create mode 100644 platform/hal/hal_norflaship_v2.c create mode 100644 platform/hal/hal_overlay.c create mode 100644 platform/hal/hal_overlay.h create mode 100644 platform/hal/hal_phyif.c create mode 100644 platform/hal/hal_phyif.h create mode 100644 platform/hal/hal_psc.h create mode 100644 platform/hal/hal_psram.h create mode 100644 platform/hal/hal_psram_v1.c create mode 100644 platform/hal/hal_psram_v2.c create mode 100644 platform/hal/hal_psramip_v1.h create mode 100644 platform/hal/hal_psramuhs.c create mode 100644 platform/hal/hal_psramuhs.h create mode 100644 platform/hal/hal_pwm.c create mode 100644 platform/hal/hal_pwm.h create mode 100644 platform/hal/hal_rtc.c create mode 100644 platform/hal/hal_rtc.h create mode 100644 platform/hal/hal_sdmmc.c create mode 100644 platform/hal/hal_sdmmc.h create mode 100644 platform/hal/hal_sec_eng.c create mode 100644 platform/hal/hal_sec_eng.h create mode 100644 platform/hal/hal_sensor_eng.h create mode 100644 platform/hal/hal_slave_i2c.c create mode 100644 platform/hal/hal_slave_i2c.h create mode 100644 platform/hal/hal_sleep.c create mode 100644 platform/hal/hal_sleep.h create mode 100644 platform/hal/hal_sleep_core_pd.S create mode 100644 platform/hal/hal_sleep_core_pd.h create mode 100644 platform/hal/hal_sleep_mcu_pd.S create mode 100644 platform/hal/hal_sleep_mcu_pd.h create mode 100644 platform/hal/hal_spdif.c create mode 100644 platform/hal/hal_spdif.h create mode 100644 platform/hal/hal_spdifip.h create mode 100644 platform/hal/hal_spi.c create mode 100644 platform/hal/hal_spi.h create mode 100644 platform/hal/hal_sysfreq.c create mode 100644 platform/hal/hal_sysfreq.h create mode 100644 platform/hal/hal_tdm.c create mode 100644 platform/hal/hal_tdm.h create mode 100644 platform/hal/hal_timer.c create mode 100644 platform/hal/hal_timer.h create mode 100644 platform/hal/hal_timer_raw.h create mode 100644 platform/hal/hal_trace.c create mode 100644 platform/hal/hal_trace.h create mode 100644 platform/hal/hal_trace_mod.c create mode 100644 platform/hal/hal_trace_mod.h create mode 100644 platform/hal/hal_transq.c create mode 100644 platform/hal/hal_transq.h create mode 100644 platform/hal/hal_uart.c create mode 100644 platform/hal/hal_uart.h create mode 100644 platform/hal/hal_usb.c create mode 100644 platform/hal/hal_usb.h create mode 100644 platform/hal/hal_usbhost.c create mode 100644 platform/hal/hal_usbhost.h create mode 100644 platform/hal/hal_wdt.c create mode 100644 platform/hal/hal_wdt.h create mode 100644 platform/hal/plat_addr_map.h create mode 100644 platform/hal/plat_types.h create mode 100644 platform/hal/reg_btpcmip.h create mode 100644 platform/hal/reg_dma.h create mode 100644 platform/hal/reg_gpio.h create mode 100644 platform/hal/reg_i2cip.h create mode 100644 platform/hal/reg_i2sip.h create mode 100644 platform/hal/reg_norflaship_v1.h create mode 100644 platform/hal/reg_norflaship_v2.h create mode 100644 platform/hal/reg_psram_mc_v2.h create mode 100644 platform/hal/reg_psram_phy_v2.h create mode 100644 platform/hal/reg_psramip_v1.h create mode 100644 platform/hal/reg_psramuhs_mc.h create mode 100644 platform/hal/reg_pwm.h create mode 100644 platform/hal/reg_rtc.h create mode 100644 platform/hal/reg_sdmmcip.h create mode 100644 platform/hal/reg_sec_eng.h create mode 100644 platform/hal/reg_slave_i2c.h create mode 100644 platform/hal/reg_spdifip.h create mode 100644 platform/hal/reg_spi.h create mode 100644 platform/hal/reg_tdm.h create mode 100644 platform/hal/reg_timer.h create mode 100644 platform/hal/reg_transq.h create mode 100644 platform/hal/reg_uart.h create mode 100644 platform/hal/reg_usb.h create mode 100644 platform/main/Makefile create mode 100644 platform/main/main.cpp create mode 100644 platform/main/noapp_main.cpp create mode 100644 platform/main/nostd_main.c create mode 100644 platform/main/startup_main.S create mode 100644 rtos/Makefile create mode 100644 rtos/rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/HAL_CM0.S create mode 100644 rtos/rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/SVC_Table.S create mode 100644 rtos/rtx/TARGET_ARM7/HAL_CM.c create mode 100644 rtos/rtx/TARGET_ARM7/RTX_CM_lib.h create mode 100644 rtos/rtx/TARGET_ARM7/RTX_Conf.h create mode 100644 rtos/rtx/TARGET_ARM7/RTX_Conf_CM.c create mode 100644 rtos/rtx/TARGET_ARM7/cmsis_os.h create mode 100644 rtos/rtx/TARGET_ARM7/os_tcb.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_CMSIS.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_Event.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_Event.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_HAL_CM.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_List.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_List.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_Mailbox.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_Mailbox.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_MemBox.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_MemBox.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_Mutex.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_Mutex.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_Robin.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_Robin.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_Semaphore.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_Semaphore.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_System.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_System.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_Task.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_Task.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_Time.c create mode 100644 rtos/rtx/TARGET_ARM7/rt_Time.h create mode 100644 rtos/rtx/TARGET_ARM7/rt_TypeDef.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/HAL_CA.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/RTX_CM_lib.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/RTX_Config.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/HAL_CA9.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/HAL_CA9.S create mode 100644 rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_A/cmsis_os.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_CMSIS.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Event.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Event.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_HAL_CA.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_HAL_CM.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_List.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_List.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Mailbox.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Mailbox.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_MemBox.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_MemBox.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Memory.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Memory.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Mutex.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Mutex.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Robin.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Robin.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Semaphore.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Semaphore.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_System.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_System.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Task.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Task.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Time.c create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Time.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_Timer.h create mode 100644 rtos/rtx/TARGET_CORTEX_A/rt_TypeDef.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/HAL_CM.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/Makefile create mode 100644 rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/RTX_Conf.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/HAL_CM4.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/HAL_CM4.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_IAR/HAL_CM4.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_IAR/SVC_Table.S create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Event.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Event.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_List.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_List.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Robin.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Robin.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_System.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_System.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Task.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Task.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Time.c create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Time.h create mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h create mode 100644 rtos/rtx5/ARM/irq_armv8mbl.s create mode 100644 rtos/rtx5/ARM/irq_armv8mbl_ns.s create mode 100644 rtos/rtx5/ARM/irq_armv8mml.s create mode 100644 rtos/rtx5/ARM/irq_armv8mml_ns.s create mode 100644 rtos/rtx5/ARM/irq_ca.s create mode 100644 rtos/rtx5/ARM/irq_cm0.s create mode 100644 rtos/rtx5/ARM/irq_cm3.s create mode 100644 rtos/rtx5/ARM/irq_cm4f.s create mode 100644 rtos/rtx5/GCC/Makefile create mode 100644 rtos/rtx5/GCC/irq_armv8mbl.S create mode 100644 rtos/rtx5/GCC/irq_armv8mbl_ns.S create mode 100644 rtos/rtx5/GCC/irq_armv8mml.S create mode 100644 rtos/rtx5/GCC/irq_armv8mml_fp.S create mode 100644 rtos/rtx5/GCC/irq_armv8mml_fp_ns.S create mode 100644 rtos/rtx5/GCC/irq_armv8mml_ns.S create mode 100644 rtos/rtx5/GCC/irq_ca.S create mode 100644 rtos/rtx5/GCC/irq_cm0.S create mode 100644 rtos/rtx5/GCC/irq_cm3.S create mode 100644 rtos/rtx5/GCC/irq_cm4f.S create mode 100644 rtos/rtx5/IAR/irq_armv8mbl.s create mode 100644 rtos/rtx5/IAR/irq_armv8mbl_common.s create mode 100644 rtos/rtx5/IAR/irq_armv8mbl_ns.s create mode 100644 rtos/rtx5/IAR/irq_armv8mml.s create mode 100644 rtos/rtx5/IAR/irq_armv8mml_common.s create mode 100644 rtos/rtx5/IAR/irq_armv8mml_ns.s create mode 100644 rtos/rtx5/IAR/irq_ca.s create mode 100644 rtos/rtx5/IAR/irq_cm0.s create mode 100644 rtos/rtx5/IAR/irq_cm3.s create mode 100644 rtos/rtx5/IAR/irq_cm4f.s create mode 100644 rtos/rtx5/Makefile create mode 100644 rtos/rtx5/RTE_Components.h create mode 100644 rtos/rtx5/cmsis_os1.c create mode 100644 rtos/rtx5/os_systick.c create mode 100644 rtos/rtx5/rtx_config/Makefile create mode 100644 rtos/rtx5/rtx_config/rtx_config.c create mode 100644 rtos/rtx5/rtx_config/rtx_config.h create mode 100644 rtos/rtx5/rtx_core_c.h create mode 100644 rtos/rtx5/rtx_core_ca.h create mode 100644 rtos/rtx5/rtx_core_cm.h create mode 100644 rtos/rtx5/rtx_delay.c create mode 100644 rtos/rtx5/rtx_evflags.c create mode 100644 rtos/rtx5/rtx_evr.c create mode 100644 rtos/rtx5/rtx_kernel.c create mode 100644 rtos/rtx5/rtx_lib.c create mode 100644 rtos/rtx5/rtx_lib.h create mode 100644 rtos/rtx5/rtx_memory.c create mode 100644 rtos/rtx5/rtx_mempool.c create mode 100644 rtos/rtx5/rtx_msgqueue.c create mode 100644 rtos/rtx5/rtx_mutex.c create mode 100644 rtos/rtx5/rtx_semaphore.c create mode 100644 rtos/rtx5/rtx_system.c create mode 100644 rtos/rtx5/rtx_thread.c create mode 100644 rtos/rtx5/rtx_thread_dump.c create mode 100644 rtos/rtx5/rtx_timer.c create mode 100644 scripts/build.mk create mode 100644 scripts/clean.mk create mode 100644 scripts/extrawarn.mk create mode 100644 scripts/include.mk create mode 100644 scripts/lib.mk create mode 100644 scripts/link/armca.lds.S create mode 100644 scripts/link/best1000.lds.S create mode 100644 scripts/link/best1000_fpga_rom.lds.S create mode 100644 scripts/link/best1000_intsram.lds.S create mode 100644 scripts/link/best1000_intsram.lds_scat.S create mode 100644 scripts/link/best1000_msbc_aac.lds.S create mode 100644 scripts/link/best1000savepower.lds.S create mode 100644 scripts/link/best2000_bisto.lds.S create mode 100644 scripts/link/best2000_dma.lds.S create mode 100644 scripts/link/programmer.lds.S create mode 100644 scripts/link/programmer.lds_scat.S create mode 100644 scripts/link/programmer_inflash.lds.S create mode 100644 scripts/link/rom.lds.S create mode 100644 scripts/link/rom.lds_scat.S create mode 100644 scripts/submods.mk create mode 100644 scripts/submods_init.mk create mode 100644 services/Makefile create mode 100644 services/anc_spp_tool/Makefile create mode 100644 services/anc_spp_tool/anc_parse_data.h create mode 100644 services/app_ai/Makefile create mode 100644 services/app_ai/inc/app_ai_algorithm.h create mode 100644 services/app_ai/inc/app_ai_if.h create mode 100644 services/app_ai/inc/app_ai_if_config.h create mode 100644 services/app_ai/inc/app_ai_if_custom_ui.h create mode 100644 services/app_ai/inc/app_ai_if_gsound.h create mode 100644 services/app_ai/inc/app_ai_if_thirdparty.h create mode 100644 services/app_ai/inc/app_ai_manager_api.h create mode 100644 services/app_ai/inc/app_ai_tws.h create mode 100644 services/app_ai/src/app_ai_algorithm.cpp create mode 100644 services/app_ai/src/app_ai_if.cpp create mode 100644 services/app_ai/src/app_ai_if_custom_ui.cpp create mode 100644 services/app_ai/src/app_ai_if_gsound.cpp create mode 100644 services/app_ai/src/app_ai_if_thirdparty.cpp create mode 100644 services/app_ai/src/app_ai_manager_api.cpp create mode 100644 services/app_ai/src/app_ai_tws.cpp create mode 100644 services/app_ai/voice_sbc/voice_sbc.cpp create mode 100644 services/app_ai/voice_sbc/voice_sbc.h create mode 100644 services/app_ibrt/Makefile create mode 100644 services/app_ibrt/inc/app_ibrt_a2dp.h create mode 100644 services/app_ibrt/inc/app_ibrt_auto_test.h create mode 100644 services/app_ibrt/inc/app_ibrt_auto_test_cmd_handle.h create mode 100644 services/app_ibrt/inc/app_ibrt_ble_adv.h create mode 100644 services/app_ibrt/inc/app_ibrt_custom_cmd.h create mode 100644 services/app_ibrt/inc/app_ibrt_customif_cmd.h create mode 100644 services/app_ibrt/inc/app_ibrt_customif_ui.h create mode 100644 services/app_ibrt/inc/app_ibrt_hf.h create mode 100644 services/app_ibrt/inc/app_ibrt_if.h create mode 100644 services/app_ibrt/inc/app_ibrt_if_internal.h create mode 100644 services/app_ibrt/inc/app_ibrt_keyboard.h create mode 100644 services/app_ibrt/inc/app_ibrt_nvrecord.h create mode 100644 services/app_ibrt/inc/app_ibrt_ota_cmd.h create mode 100644 services/app_ibrt/inc/app_ibrt_ota_update.h create mode 100644 services/app_ibrt/inc/app_ibrt_peripheral_manager.h create mode 100644 services/app_ibrt/inc/app_ibrt_rssi.h create mode 100644 services/app_ibrt/inc/app_ibrt_ui_test.h create mode 100644 services/app_ibrt/inc/app_ibrt_ui_test_cmd_if.h create mode 100644 services/app_ibrt/inc/app_ibrt_voice_report.h create mode 100644 services/app_ibrt/src/app_ibrt_auto_test.cpp create mode 100644 services/app_ibrt/src/app_ibrt_auto_test_cmd_handle.cpp create mode 100644 services/app_ibrt/src/app_ibrt_ble_adv.cpp create mode 100644 services/app_ibrt/src/app_ibrt_customif_cmd.cpp create mode 100644 services/app_ibrt/src/app_ibrt_customif_ui.cpp create mode 100644 services/app_ibrt/src/app_ibrt_if.cpp create mode 100644 services/app_ibrt/src/app_ibrt_keyboard.cpp create mode 100644 services/app_ibrt/src/app_ibrt_nvrecord.cpp create mode 100644 services/app_ibrt/src/app_ibrt_ota_cmd.cpp create mode 100644 services/app_ibrt/src/app_ibrt_ota_update.cpp create mode 100644 services/app_ibrt/src/app_ibrt_peripheral_manager.cpp create mode 100644 services/app_ibrt/src/app_ibrt_rssi.cpp create mode 100644 services/app_ibrt/src/app_ibrt_search_pair_ui.cpp create mode 100644 services/app_ibrt/src/app_ibrt_ui_test.cpp create mode 100644 services/app_ibrt/src/app_ibrt_ui_test_cmd_if.cpp create mode 100644 services/app_ibrt/src/app_ibrt_voice_report.cpp create mode 100644 services/app_tws/Makefile create mode 100644 services/app_tws/inc/app_tws_if.h create mode 100644 services/app_tws/src/app_tws_if.cpp create mode 100644 services/audio_dump/Makefile create mode 100644 services/audio_dump/include/audio_dump.h create mode 100644 services/audio_dump/src/audio_dump.c create mode 100644 services/audio_process/Makefile create mode 100644 services/audio_process/audio_cfg.c create mode 100644 services/audio_process/audio_cfg.h create mode 100644 services/audio_process/audio_process.c create mode 100644 services/audio_process/audio_process.h create mode 100644 services/audio_process/audio_spectrum.cpp create mode 100644 services/audio_process/audio_spectrum.h create mode 100644 services/audioflinger/Makefile create mode 100644 services/audioflinger/audioflinger.c create mode 100644 services/audioflinger/audioflinger.h create mode 100644 services/auto_test/Makefile create mode 100644 services/auto_test/at_thread.cpp create mode 100644 services/auto_test/at_thread.h create mode 100644 services/auto_test/at_thread_user.cpp create mode 100644 services/auto_test/at_thread_user.h create mode 100644 services/auto_test/auto_test.cpp create mode 100644 services/ble_app/Makefile create mode 100644 services/ble_app/app_amsc/app_amsc.c create mode 100644 services/ble_app/app_amsc/app_amsc.h create mode 100644 services/ble_app/app_amsc/app_amsc_task.c create mode 100644 services/ble_app/app_amsc/app_amsc_task.h create mode 100644 services/ble_app/app_ancc/app_ancc.c create mode 100644 services/ble_app/app_ancc/app_ancc.h create mode 100644 services/ble_app/app_ancc/app_ancc_task.c create mode 100644 services/ble_app/app_ancc/app_ancc_task.h create mode 100644 services/ble_app/app_batt/app_batt.c create mode 100644 services/ble_app/app_batt/app_batt.h create mode 100644 services/ble_app/app_ble_key.cpp create mode 100644 services/ble_app/app_ble_uart.cpp create mode 100644 services/ble_app/app_ble_uart.h create mode 100644 services/ble_app/app_datapath/app_ble_cmd_handler.c create mode 100644 services/ble_app/app_datapath/app_ble_cmd_handler.h create mode 100644 services/ble_app/app_datapath/app_ble_custom_cmd.c create mode 100644 services/ble_app/app_datapath/app_ble_custom_cmd.h create mode 100644 services/ble_app/app_datapath/app_datapath_server.c create mode 100644 services/ble_app/app_datapath/app_datapath_server.h create mode 100644 services/ble_app/app_dis/app_dis.c create mode 100644 services/ble_app/app_dis/app_dis.h create mode 100644 services/ble_app/app_gfps/app_gfps.c create mode 100644 services/ble_app/app_gfps/app_gfps.h create mode 100644 services/ble_app/app_hid/app_hid.c create mode 100644 services/ble_app/app_hid/app_hid.h create mode 100644 services/ble_app/app_hrps/app_hrps.c create mode 100644 services/ble_app/app_hrps/app_hrps.h create mode 100644 services/ble_app/app_htp/app_ht.c create mode 100644 services/ble_app/app_htp/app_ht.h create mode 100644 services/ble_app/app_main/app.c create mode 100644 services/ble_app/app_main/app.h create mode 100644 services/ble_app/app_main/app_ble_core.c create mode 100644 services/ble_app/app_main/app_ble_core.h create mode 100644 services/ble_app/app_main/app_ble_customif.c create mode 100644 services/ble_app/app_main/app_ble_customif.h create mode 100644 services/ble_app/app_main/app_ble_include.h create mode 100644 services/ble_app/app_main/app_ble_mode_switch.c create mode 100644 services/ble_app/app_main/app_ble_mode_switch.h create mode 100644 services/ble_app/app_main/app_ble_rx_handler.c create mode 100644 services/ble_app/app_main/app_ble_rx_handler.h create mode 100644 services/ble_app/app_main/app_task.c create mode 100644 services/ble_app/app_main/app_task.h create mode 100644 services/ble_app/app_ota/app_ota.c create mode 100644 services/ble_app/app_ota/app_ota.h create mode 100644 services/ble_app/app_sec/app_sec.c create mode 100644 services/ble_app/app_sec/app_sec.h create mode 100644 services/ble_app/app_tota/app_tota_ble.c create mode 100644 services/ble_app/app_tota/app_tota_ble.h create mode 100644 services/ble_app/app_vob/voice_over_ble.c create mode 100644 services/ble_app/app_voice/app_voicepath_ble.c create mode 100644 services/ble_app/app_voice/app_voicepath_ble.h create mode 100644 services/ble_app/ble_app_dbg.h create mode 100644 services/ble_profiles/Makefile create mode 100644 services/ble_profiles/ams/ams_common.h create mode 100644 services/ble_profiles/ams/amsc/amsc.c create mode 100644 services/ble_profiles/ams/amsc/amsc.h create mode 100644 services/ble_profiles/ams/amsc/amsc_task.c create mode 100644 services/ble_profiles/ams/amsc/amsc_task.h create mode 100644 services/ble_profiles/anc/anc_common.h create mode 100644 services/ble_profiles/anc/ancc/ancc.c create mode 100644 services/ble_profiles/anc/ancc/ancc.h create mode 100644 services/ble_profiles/anc/ancc/ancc_task.c create mode 100644 services/ble_profiles/anc/ancc/ancc_task.h create mode 100644 services/ble_profiles/anp/anp_common.h create mode 100644 services/ble_profiles/anp/anpc/api/anpc_task.h create mode 100644 services/ble_profiles/anp/anpc/src/anpc.c create mode 100644 services/ble_profiles/anp/anpc/src/anpc.h create mode 100644 services/ble_profiles/anp/anpc/src/anpc_task.c create mode 100644 services/ble_profiles/anp/anps/api/anps_task.h create mode 100644 services/ble_profiles/anp/anps/src/anps.c create mode 100644 services/ble_profiles/anp/anps/src/anps.h create mode 100644 services/ble_profiles/anp/anps/src/anps_task.c create mode 100644 services/ble_profiles/bas/basc/api/basc_task.h create mode 100644 services/ble_profiles/bas/basc/src/basc.c create mode 100644 services/ble_profiles/bas/basc/src/basc.h create mode 100644 services/ble_profiles/bas/basc/src/basc_task.c create mode 100644 services/ble_profiles/bas/bass/api/bass_task.h create mode 100644 services/ble_profiles/bas/bass/src/bass.c create mode 100644 services/ble_profiles/bas/bass/src/bass.h create mode 100644 services/ble_profiles/bas/bass/src/bass_task.c create mode 100644 services/ble_profiles/blp/blp_common.h create mode 100644 services/ble_profiles/blp/blpc/api/blpc_task.h create mode 100644 services/ble_profiles/blp/blpc/src/blpc.c create mode 100644 services/ble_profiles/blp/blpc/src/blpc.h create mode 100644 services/ble_profiles/blp/blpc/src/blpc_task.c create mode 100644 services/ble_profiles/blp/blps/api/blps_task.h create mode 100644 services/ble_profiles/blp/blps/src/blps.c create mode 100644 services/ble_profiles/blp/blps/src/blps.h create mode 100644 services/ble_profiles/blp/blps/src/blps_task.c create mode 100644 services/ble_profiles/cpp/cpp_common.h create mode 100644 services/ble_profiles/cpp/cppc/api/cppc_task.h create mode 100644 services/ble_profiles/cpp/cppc/src/cppc.c create mode 100644 services/ble_profiles/cpp/cppc/src/cppc.h create mode 100644 services/ble_profiles/cpp/cppc/src/cppc_task.c create mode 100644 services/ble_profiles/cpp/cpps/api/cpps_task.h create mode 100644 services/ble_profiles/cpp/cpps/src/cpps.c create mode 100644 services/ble_profiles/cpp/cpps/src/cpps.h create mode 100644 services/ble_profiles/cpp/cpps/src/cpps_task.c create mode 100644 services/ble_profiles/cscp/cscp_common.h create mode 100644 services/ble_profiles/cscp/cscpc/api/cscpc_task.h create mode 100644 services/ble_profiles/cscp/cscpc/src/cscpc.c create mode 100644 services/ble_profiles/cscp/cscpc/src/cscpc.h create mode 100644 services/ble_profiles/cscp/cscpc/src/cscpc_task.c create mode 100644 services/ble_profiles/cscp/cscps/api/cscps_task.h create mode 100644 services/ble_profiles/cscp/cscps/src/cscps.c create mode 100644 services/ble_profiles/cscp/cscps/src/cscps.h create mode 100644 services/ble_profiles/cscp/cscps/src/cscps_task.c create mode 100644 services/ble_profiles/datapath/datapathps/api/datapathps_task.h create mode 100644 services/ble_profiles/datapath/datapathps/src/datapathps.c create mode 100644 services/ble_profiles/datapath/datapathps/src/datapathps.h create mode 100644 services/ble_profiles/datapath/datapathps/src/datapathps_task.c create mode 100644 services/ble_profiles/dis/disc/api/disc_task.h create mode 100644 services/ble_profiles/dis/disc/src/disc.c create mode 100644 services/ble_profiles/dis/disc/src/disc.h create mode 100644 services/ble_profiles/dis/disc/src/disc_task.c create mode 100644 services/ble_profiles/dis/diss/api/diss_task.h create mode 100644 services/ble_profiles/dis/diss/src/diss.c create mode 100644 services/ble_profiles/dis/diss/src/diss.h create mode 100644 services/ble_profiles/dis/diss/src/diss_task.c create mode 100644 services/ble_profiles/find/find_common.h create mode 100644 services/ble_profiles/find/findl/api/findl_task.h create mode 100644 services/ble_profiles/find/findl/src/findl.c create mode 100644 services/ble_profiles/find/findl/src/findl.h create mode 100644 services/ble_profiles/find/findl/src/findl_task.c create mode 100644 services/ble_profiles/find/findt/api/findt_task.h create mode 100644 services/ble_profiles/find/findt/src/findt.c create mode 100644 services/ble_profiles/find/findt/src/findt.h create mode 100644 services/ble_profiles/find/findt/src/findt_task.c create mode 100644 services/ble_profiles/gfps/Makefile create mode 100644 services/ble_profiles/gfps/api/gfps_crypto.h create mode 100644 services/ble_profiles/gfps/gfps_provider/api/gfps_provider.h create mode 100644 services/ble_profiles/gfps/gfps_provider/api/gfps_provider_errors.h create mode 100644 services/ble_profiles/gfps/gfps_provider/api/gfps_provider_task.h create mode 100644 services/ble_profiles/gfps/gfps_provider/src/gfps_provider.c create mode 100644 services/ble_profiles/gfps/gfps_provider/src/gfps_provider_task.c create mode 100644 services/ble_profiles/glp/glp_common.h create mode 100644 services/ble_profiles/glp/glpc/api/glpc_task.h create mode 100644 services/ble_profiles/glp/glpc/src/glpc.c create mode 100644 services/ble_profiles/glp/glpc/src/glpc.h create mode 100644 services/ble_profiles/glp/glpc/src/glpc_task.c create mode 100644 services/ble_profiles/glp/glps/api/glps.h create mode 100644 services/ble_profiles/glp/glps/api/glps_task.h create mode 100644 services/ble_profiles/glp/glps/src/glps.c create mode 100644 services/ble_profiles/glp/glps/src/glps_task.c create mode 100644 services/ble_profiles/hogp/hogp_common.h create mode 100644 services/ble_profiles/hogp/hogpbh/api/hogpbh_task.h create mode 100644 services/ble_profiles/hogp/hogpbh/src/hogpbh.c create mode 100644 services/ble_profiles/hogp/hogpbh/src/hogpbh.h create mode 100644 services/ble_profiles/hogp/hogpbh/src/hogpbh_task.c create mode 100644 services/ble_profiles/hogp/hogpd/api/hogpd_task.h create mode 100644 services/ble_profiles/hogp/hogpd/src/hogpd.c create mode 100644 services/ble_profiles/hogp/hogpd/src/hogpd.h create mode 100644 services/ble_profiles/hogp/hogpd/src/hogpd_task.c create mode 100644 services/ble_profiles/hogp/hogprh/api/hogprh_task.h create mode 100644 services/ble_profiles/hogp/hogprh/src/hogprh.c create mode 100644 services/ble_profiles/hogp/hogprh/src/hogprh.h create mode 100644 services/ble_profiles/hogp/hogprh/src/hogprh_task.c create mode 100644 services/ble_profiles/hrp/hrp_common.h create mode 100644 services/ble_profiles/hrp/hrpc/api/hrpc_task.h create mode 100644 services/ble_profiles/hrp/hrpc/src/hrpc.c create mode 100644 services/ble_profiles/hrp/hrpc/src/hrpc.h create mode 100644 services/ble_profiles/hrp/hrpc/src/hrpc_task.c create mode 100644 services/ble_profiles/hrp/hrps/api/hrps_task.h create mode 100644 services/ble_profiles/hrp/hrps/src/hrps.c create mode 100644 services/ble_profiles/hrp/hrps/src/hrps.h create mode 100644 services/ble_profiles/hrp/hrps/src/hrps_task.c create mode 100644 services/ble_profiles/htp/htp_common.h create mode 100644 services/ble_profiles/htp/htpc/api/htpc_task.h create mode 100644 services/ble_profiles/htp/htpc/src/htpc.c create mode 100644 services/ble_profiles/htp/htpc/src/htpc.h create mode 100644 services/ble_profiles/htp/htpc/src/htpc_task.c create mode 100644 services/ble_profiles/htp/htpt/api/htpt_task.h create mode 100644 services/ble_profiles/htp/htpt/src/htpt.c create mode 100644 services/ble_profiles/htp/htpt/src/htpt.h create mode 100644 services/ble_profiles/htp/htpt/src/htpt_task.c create mode 100644 services/ble_profiles/lan/lan_common.h create mode 100644 services/ble_profiles/lan/lanc/api/lanc_task.h create mode 100644 services/ble_profiles/lan/lanc/src/lanc.c create mode 100644 services/ble_profiles/lan/lanc/src/lanc.h create mode 100644 services/ble_profiles/lan/lanc/src/lanc_task.c create mode 100644 services/ble_profiles/lan/lans/api/lans_task.h create mode 100644 services/ble_profiles/lan/lans/src/lans.c create mode 100644 services/ble_profiles/lan/lans/src/lans.h create mode 100644 services/ble_profiles/lan/lans/src/lans_task.c create mode 100644 services/ble_profiles/ota/ota.c create mode 100644 services/ble_profiles/ota/ota.h create mode 100644 services/ble_profiles/ota/ota_task.c create mode 100644 services/ble_profiles/ota/ota_task.h create mode 100644 services/ble_profiles/pasp/pasp_common.h create mode 100644 services/ble_profiles/pasp/paspc/api/paspc_task.h create mode 100644 services/ble_profiles/pasp/paspc/src/paspc.c create mode 100644 services/ble_profiles/pasp/paspc/src/paspc.h create mode 100644 services/ble_profiles/pasp/paspc/src/paspc_task.c create mode 100644 services/ble_profiles/pasp/pasps/api/pasps_task.h create mode 100644 services/ble_profiles/pasp/pasps/src/pasps.c create mode 100644 services/ble_profiles/pasp/pasps/src/pasps.h create mode 100644 services/ble_profiles/pasp/pasps/src/pasps_task.c create mode 100644 services/ble_profiles/prf/prf.c create mode 100644 services/ble_profiles/prf/prf_utils.c create mode 100644 services/ble_profiles/prf/prf_utils_128.c create mode 100644 services/ble_profiles/prox/proxm/api/proxm_task.h create mode 100644 services/ble_profiles/prox/proxm/src/proxm.c create mode 100644 services/ble_profiles/prox/proxm/src/proxm.h create mode 100644 services/ble_profiles/prox/proxm/src/proxm_task.c create mode 100644 services/ble_profiles/prox/proxr/api/proxr_task.h create mode 100644 services/ble_profiles/prox/proxr/src/proxr.c create mode 100644 services/ble_profiles/prox/proxr/src/proxr.h create mode 100644 services/ble_profiles/prox/proxr/src/proxr_task.c create mode 100644 services/ble_profiles/rscp/rscp_common.h create mode 100644 services/ble_profiles/rscp/rscpc/api/rscpc_task.h create mode 100644 services/ble_profiles/rscp/rscpc/src/rscpc.c create mode 100644 services/ble_profiles/rscp/rscpc/src/rscpc.h create mode 100644 services/ble_profiles/rscp/rscpc/src/rscpc_task.c create mode 100644 services/ble_profiles/rscp/rscps/api/rscps_task.h create mode 100644 services/ble_profiles/rscp/rscps/src/rscps.c create mode 100644 services/ble_profiles/rscp/rscps/src/rscps.h create mode 100644 services/ble_profiles/rscp/rscps/src/rscps_task.c create mode 100644 services/ble_profiles/tip/tip_common.h create mode 100644 services/ble_profiles/tip/tipc/api/tipc_task.h create mode 100644 services/ble_profiles/tip/tipc/src/tipc.c create mode 100644 services/ble_profiles/tip/tipc/src/tipc.h create mode 100644 services/ble_profiles/tip/tipc/src/tipc_task.c create mode 100644 services/ble_profiles/tip/tips/api/tips_task.h create mode 100644 services/ble_profiles/tip/tips/src/tips.c create mode 100644 services/ble_profiles/tip/tips/src/tips.h create mode 100644 services/ble_profiles/tip/tips/src/tips_task.c create mode 100644 services/ble_profiles/tota/tota_ble.c create mode 100644 services/ble_profiles/tota/tota_ble.h create mode 100644 services/ble_profiles/tota/tota_task.c create mode 100644 services/ble_profiles/tota/tota_task.h create mode 100644 services/ble_stack/Makefile create mode 100644 services/ble_stack/ble_ip/arch.h create mode 100644 services/ble_stack/ble_ip/besble.h create mode 100644 services/ble_stack/ble_ip/compiler.h create mode 100644 services/ble_stack/ble_ip/rwapp_config.h create mode 100644 services/ble_stack/ble_ip/rwble_hl.h create mode 100644 services/ble_stack/ble_ip/rwble_hl_config.h create mode 100644 services/ble_stack/ble_ip/rwip.h create mode 100644 services/ble_stack/ble_ip/rwip_config.h create mode 100644 services/ble_stack/ble_ip/rwip_task.h create mode 100644 services/ble_stack/ble_ip/rwprf_config.h create mode 100644 services/ble_stack/common/api/co_bt.h create mode 100644 services/ble_stack/common/api/co_bt_defines.h create mode 100644 services/ble_stack/common/api/co_endian.h create mode 100644 services/ble_stack/common/api/co_error.h create mode 100644 services/ble_stack/common/api/co_hci.h create mode 100644 services/ble_stack/common/api/co_list.h create mode 100644 services/ble_stack/common/api/co_llcp.h create mode 100644 services/ble_stack/common/api/co_lmp.h create mode 100644 services/ble_stack/common/api/co_math.h create mode 100644 services/ble_stack/common/api/co_utils.h create mode 100644 services/ble_stack/common/api/co_version.h create mode 100644 services/ble_stack/common/api/lePhone_rw_ble_error.txt create mode 100644 services/ble_stack/dbg/api/dbg.h create mode 100644 services/ble_stack/dbg/api/dbg_mwsgen.h create mode 100644 services/ble_stack/dbg/api/dbg_swdiag.h create mode 100644 services/ble_stack/dbg/api/dbg_trc.h create mode 100644 services/ble_stack/dbg/api/dbg_trc_config.h create mode 100644 services/ble_stack/dbg/src/dbg_trc_int.h create mode 100644 services/ble_stack/hci/api/hci_ble.h create mode 100644 services/ble_stack/hci/src/hci_int.h create mode 100644 services/ble_stack/hl/api/att.h create mode 100644 services/ble_stack/hl/api/gap.h create mode 100644 services/ble_stack/hl/api/gapc_task.h create mode 100644 services/ble_stack/hl/api/gapm_task.h create mode 100644 services/ble_stack/hl/api/gattc_task.h create mode 100644 services/ble_stack/hl/api/gattm_task.h create mode 100644 services/ble_stack/hl/api/l2cc_task.h create mode 100644 services/ble_stack/hl/api/prf_types.h create mode 100644 services/ble_stack/hl/api/rwble_hl_error.h create mode 100644 services/ble_stack/hl/inc/attm.h create mode 100644 services/ble_stack/hl/inc/gapc.h create mode 100644 services/ble_stack/hl/inc/gapm.h create mode 100644 services/ble_stack/hl/inc/gattc.h create mode 100644 services/ble_stack/hl/inc/gattm.h create mode 100644 services/ble_stack/hl/inc/l2cc.h create mode 100644 services/ble_stack/hl/inc/l2cc_pdu.h create mode 100644 services/ble_stack/hl/inc/l2cm.h create mode 100644 services/ble_stack/hl/inc/prf.h create mode 100644 services/ble_stack/hl/inc/prf_utils.h create mode 100644 services/ble_stack/hl/inc/prf_utils_128.h create mode 100644 services/ble_stack/hl/inc/smpc.h create mode 100644 services/ble_stack/hl/src/gap/gapc/gapc_int.h create mode 100644 services/ble_stack/hl/src/gap/gapc/gapc_sig.h create mode 100644 services/ble_stack/hl/src/gap/gapm/gapm_int.h create mode 100644 services/ble_stack/hl/src/gap/smp_common.h create mode 100644 services/ble_stack/hl/src/gap/smpc/smpc_api.h create mode 100644 services/ble_stack/hl/src/gap/smpc/smpc_crypto.h create mode 100644 services/ble_stack/hl/src/gap/smpc/smpc_int.h create mode 100644 services/ble_stack/hl/src/gap/smpc/smpc_util.h create mode 100644 services/ble_stack/hl/src/gatt/attc/attc.h create mode 100644 services/ble_stack/hl/src/gatt/attm/attm_db.h create mode 100644 services/ble_stack/hl/src/gatt/atts/atts.h create mode 100644 services/ble_stack/hl/src/gatt/gatt.h create mode 100644 services/ble_stack/hl/src/gatt/gattc/gattc_int.h create mode 100644 services/ble_stack/hl/src/gatt/gattm/gattm_int.h create mode 100644 services/ble_stack/hl/src/l2c/l2cc/l2cc_int.h create mode 100644 services/ble_stack/hl/src/l2c/l2cc/l2cc_lecb.h create mode 100644 services/ble_stack/hl/src/l2c/l2cc/l2cc_pdu_int.h create mode 100644 services/ble_stack/hl/src/l2c/l2cc/l2cc_sig.h create mode 100644 services/ble_stack/hl/src/l2c/l2cm/l2cm_int.h create mode 100644 services/ble_stack/ke/api/ke.h create mode 100644 services/ble_stack/ke/api/ke_event.h create mode 100644 services/ble_stack/ke/api/ke_mem.h create mode 100644 services/ble_stack/ke/api/ke_msg.h create mode 100644 services/ble_stack/ke/api/ke_task.h create mode 100644 services/ble_stack/ke/api/ke_timer.h create mode 100644 services/ble_stack/ke/src/ke_env.h create mode 100644 services/ble_stack/ke/src/ke_queue.h create mode 100644 services/bridge/Makefile create mode 100644 services/bridge/bridge.h create mode 100644 services/bt_app/Makefile create mode 100644 services/bt_app/a2dp_codecs/Makefile create mode 100644 services/bt_app/a2dp_codecs/aac/a2dp_codec_aac.cpp create mode 100644 services/bt_app/a2dp_codecs/app_a2dp_codecs.cpp create mode 100644 services/bt_app/a2dp_codecs/include/a2dp_codec_aac.h create mode 100644 services/bt_app/a2dp_codecs/include/a2dp_codec_ldac.h create mode 100644 services/bt_app/a2dp_codecs/include/a2dp_codec_lhdc.h create mode 100644 services/bt_app/a2dp_codecs/include/a2dp_codec_opus.h create mode 100644 services/bt_app/a2dp_codecs/include/a2dp_codec_sbc.h create mode 100644 services/bt_app/a2dp_codecs/include/a2dp_codec_scalable.h create mode 100644 services/bt_app/a2dp_codecs/include/app_a2dp_codecs.h create mode 100644 services/bt_app/a2dp_codecs/include/codec_lhdc.h create mode 100644 services/bt_app/a2dp_codecs/ldac/a2dp_codec_ldac.cpp create mode 100644 services/bt_app/a2dp_codecs/lhdc/a2dp_codec_lhdc.cpp create mode 100644 services/bt_app/a2dp_codecs/lhdc/codec_lhdc.cpp create mode 100644 services/bt_app/a2dp_codecs/opus/a2dp_codec_opus.cpp create mode 100644 services/bt_app/a2dp_codecs/sbc/a2dp_codec_sbc.cpp create mode 100644 services/bt_app/a2dp_codecs/scalable/a2dp_codec_scalable.cpp create mode 100644 services/bt_app/app_a2dp.cpp create mode 100644 services/bt_app/app_a2dp.h create mode 100644 services/bt_app/app_a2dp_source.cpp create mode 100644 services/bt_app/app_a2dp_source.h create mode 100644 services/bt_app/app_bqb.cpp create mode 100644 services/bt_app/app_bqb_new_profile.cpp create mode 100644 services/bt_app/app_bt.cpp create mode 100644 services/bt_app/app_bt.h create mode 100644 services/bt_app/app_bt_func.cpp create mode 100644 services/bt_app/app_bt_func.h create mode 100644 services/bt_app/app_bt_hid.cpp create mode 100644 services/bt_app/app_bt_hid.h create mode 100644 services/bt_app/app_bt_media_manager.cpp create mode 100644 services/bt_app/app_bt_media_manager.h create mode 100644 services/bt_app/app_bt_stream.cpp create mode 100644 services/bt_app/app_bt_stream.h create mode 100644 services/bt_app/app_bt_trace.h create mode 100644 services/bt_app/app_btgatt.cpp create mode 100644 services/bt_app/app_btgatt.h create mode 100644 services/bt_app/app_btmap_sms.cpp create mode 100644 services/bt_app/app_btmap_sms.h create mode 100644 services/bt_app/app_dip.cpp create mode 100644 services/bt_app/app_dip.h create mode 100644 services/bt_app/app_fp_rfcomm.cpp create mode 100644 services/bt_app/app_fp_rfcomm.h create mode 100644 services/bt_app/app_hfp.cpp create mode 100644 services/bt_app/app_hfp.h create mode 100644 services/bt_app/app_hsp.cpp create mode 100644 services/bt_app/app_keyhandle.cpp create mode 100644 services/bt_app/app_media_player.cpp create mode 100644 services/bt_app/app_media_player.h create mode 100644 services/bt_app/app_rfcomm_mgr.cpp create mode 100644 services/bt_app/app_rfcomm_mgr.h create mode 100644 services/bt_app/app_ring_merge.cpp create mode 100644 services/bt_app/app_ring_merge.h create mode 100644 services/bt_app/app_sec.cpp create mode 100644 services/bt_app/app_spp.cpp create mode 100644 services/bt_app/app_spp.h create mode 100644 services/bt_app/audio_prompt_sbc.cpp create mode 100644 services/bt_app/audio_prompt_sbc.h create mode 100644 services/bt_app/besbt.h create mode 100644 services/bt_app/besbt_cfg.h create mode 100644 services/bt_app/besmain.cpp create mode 100644 services/bt_app/btapp.h create mode 100644 services/bt_app/res_audio_data.h create mode 100644 services/bt_app/res_audio_data_cn.h create mode 100644 services/bt_app/res_audio_ring.h create mode 100644 services/bt_if_enhanced/Makefile create mode 100644 services/bt_if_enhanced/inc/a2dp_api.h create mode 100644 services/bt_if_enhanced/inc/avctp_api.h create mode 100644 services/bt_if_enhanced/inc/avdtp_api.h create mode 100644 services/bt_if_enhanced/inc/avrcp_api.h create mode 100644 services/bt_if_enhanced/inc/avtp_api.h create mode 100644 services/bt_if_enhanced/inc/besaud_api.h create mode 100644 services/bt_if_enhanced/inc/besble_debug.h create mode 100644 services/bt_if_enhanced/inc/bluetooth.h create mode 100644 services/bt_if_enhanced/inc/bt_if.h create mode 100644 services/bt_if_enhanced/inc/bt_status_conv.h create mode 100644 services/bt_if_enhanced/inc/bt_xtal_sync.h create mode 100644 services/bt_if_enhanced/inc/btgatt_api.h create mode 100644 services/bt_if_enhanced/inc/btif_sys_config.h create mode 100644 services/bt_if_enhanced/inc/color_log.h create mode 100644 services/bt_if_enhanced/inc/conmgr_api.h create mode 100644 services/bt_if_enhanced/inc/dip_api.h create mode 100644 services/bt_if_enhanced/inc/hci_api.h create mode 100644 services/bt_if_enhanced/inc/hfp_api.h create mode 100644 services/bt_if_enhanced/inc/hid_api.h create mode 100644 services/bt_if_enhanced/inc/hshf_api.h create mode 100644 services/bt_if_enhanced/inc/l2cap_api.h create mode 100644 services/bt_if_enhanced/inc/map_api.h create mode 100644 services/bt_if_enhanced/inc/map_internal.h create mode 100644 services/bt_if_enhanced/inc/me_api.h create mode 100644 services/bt_if_enhanced/inc/mei_api.h create mode 100644 services/bt_if_enhanced/inc/obex_api.h create mode 100644 services/bt_if_enhanced/inc/os_api.h create mode 100644 services/bt_if_enhanced/inc/rfcomm_api.h create mode 100644 services/bt_if_enhanced/inc/sco_api.h create mode 100644 services/bt_if_enhanced/inc/sdp_api.h create mode 100644 services/bt_if_enhanced/inc/spp_api.h create mode 100644 services/bt_if_enhanced/inc/spp_task.h create mode 100644 services/bt_if_enhanced/inc/tws_role_switch.h create mode 100644 services/bt_profiles_enhanced/Makefile create mode 100644 services/bt_profiles_enhanced/inc/a2dp.h create mode 100644 services/bt_profiles_enhanced/inc/a2dp_i.h create mode 100644 services/bt_profiles_enhanced/inc/avctp.h create mode 100644 services/bt_profiles_enhanced/inc/avctp_i.h create mode 100644 services/bt_profiles_enhanced/inc/avdtp.h create mode 100644 services/bt_profiles_enhanced/inc/avdtp_i.h create mode 100644 services/bt_profiles_enhanced/inc/avrcp.h create mode 100644 services/bt_profiles_enhanced/inc/avrcp_i.h create mode 100644 services/bt_profiles_enhanced/inc/bes_os.h create mode 100644 services/bt_profiles_enhanced/inc/besaud.h create mode 100644 services/bt_profiles_enhanced/inc/besaudalloc.h create mode 100644 services/bt_profiles_enhanced/inc/bt_co_list.h create mode 100644 services/bt_profiles_enhanced/inc/bt_common.h create mode 100644 services/bt_profiles_enhanced/inc/bt_schedule.h create mode 100644 services/bt_profiles_enhanced/inc/bt_sys_cfg.h create mode 100644 services/bt_profiles_enhanced/inc/btgatt.h create mode 100644 services/bt_profiles_enhanced/inc/btlib.h create mode 100644 services/bt_profiles_enhanced/inc/btlib_more.h create mode 100644 services/bt_profiles_enhanced/inc/btlib_type.h create mode 100644 services/bt_profiles_enhanced/inc/btm.h create mode 100644 services/bt_profiles_enhanced/inc/btm_devicedb.h create mode 100644 services/bt_profiles_enhanced/inc/btm_fast_init.h create mode 100644 services/bt_profiles_enhanced/inc/btm_handle_hcievent.h create mode 100644 services/bt_profiles_enhanced/inc/btm_hci.h create mode 100644 services/bt_profiles_enhanced/inc/btm_i.h create mode 100644 services/bt_profiles_enhanced/inc/btm_security.h create mode 100644 services/bt_profiles_enhanced/inc/co_lib.h create mode 100644 services/bt_profiles_enhanced/inc/co_ppbuff.h create mode 100644 services/bt_profiles_enhanced/inc/co_printf.h create mode 100644 services/bt_profiles_enhanced/inc/co_queue.h create mode 100644 services/bt_profiles_enhanced/inc/co_timer.h create mode 100644 services/bt_profiles_enhanced/inc/cobt.h create mode 100644 services/bt_profiles_enhanced/inc/cobuf.h create mode 100644 services/bt_profiles_enhanced/inc/data_link.h create mode 100644 services/bt_profiles_enhanced/inc/debug_cfg.h create mode 100644 services/bt_profiles_enhanced/inc/debug_print.h create mode 100644 services/bt_profiles_enhanced/inc/dip.h create mode 100644 services/bt_profiles_enhanced/inc/hci.h create mode 100644 services/bt_profiles_enhanced/inc/hci_buff.h create mode 100644 services/bt_profiles_enhanced/inc/hfp.h create mode 100644 services/bt_profiles_enhanced/inc/hid_i.h create mode 100644 services/bt_profiles_enhanced/inc/hshf.h create mode 100644 services/bt_profiles_enhanced/inc/hshf_i.h create mode 100644 services/bt_profiles_enhanced/inc/l2cap.h create mode 100644 services/bt_profiles_enhanced/inc/l2cap_er.h create mode 100644 services/bt_profiles_enhanced/inc/l2cap_i.h create mode 100644 services/bt_profiles_enhanced/inc/map_bmessage_builder.h create mode 100644 services/bt_profiles_enhanced/inc/map_protocol.h create mode 100644 services/bt_profiles_enhanced/inc/map_sdp.h create mode 100644 services/bt_profiles_enhanced/inc/map_session.h create mode 100644 services/bt_profiles_enhanced/inc/md5.h create mode 100644 services/bt_profiles_enhanced/inc/obex.h create mode 100644 services/bt_profiles_enhanced/inc/obex_ascii_unicode.h create mode 100644 services/bt_profiles_enhanced/inc/obex_i.h create mode 100644 services/bt_profiles_enhanced/inc/obex_if.h create mode 100644 services/bt_profiles_enhanced/inc/obex_protocol.h create mode 100644 services/bt_profiles_enhanced/inc/obex_session.h create mode 100644 services/bt_profiles_enhanced/inc/obex_tlv.h create mode 100644 services/bt_profiles_enhanced/inc/obex_transmission.h create mode 100644 services/bt_profiles_enhanced/inc/obex_transportlayer.h create mode 100644 services/bt_profiles_enhanced/inc/overide.h create mode 100644 services/bt_profiles_enhanced/inc/packer.h create mode 100644 services/bt_profiles_enhanced/inc/pbap.h create mode 100644 services/bt_profiles_enhanced/inc/pbap_i.h create mode 100644 services/bt_profiles_enhanced/inc/platform_deps.h create mode 100644 services/bt_profiles_enhanced/inc/rfcomm.h create mode 100644 services/bt_profiles_enhanced/inc/rfcomm_i.h create mode 100644 services/bt_profiles_enhanced/inc/sco.h create mode 100644 services/bt_profiles_enhanced/inc/sco_i.h create mode 100644 services/bt_profiles_enhanced/inc/sdp.h create mode 100644 services/bt_profiles_enhanced/inc/sppnew.h create mode 100644 services/bt_profiles_enhanced/inc/win32_os.h create mode 100644 services/communication/Makefile create mode 100644 services/communication/comminication_knowles/Makefile create mode 100644 services/communication/comminication_knowles/communication_cmd_handle.cpp create mode 100644 services/communication/comminication_knowles/communication_cmd_handle.h create mode 100644 services/communication/comminication_knowles/communication_cmd_msg.h create mode 100644 services/communication/comminication_knowles/communication_sysapi.cpp create mode 100644 services/communication/comminication_knowles/communication_sysapi.h create mode 100644 services/communication/comminication_knowles/tool_msg.h create mode 100644 services/communication/communication_svr.cpp create mode 100644 services/communication/communication_svr.h create mode 100644 services/cp_accel/Makefile create mode 100644 services/cp_accel/cp_accel.c create mode 100644 services/cp_accel/cp_accel.h create mode 100644 services/cp_accel/cp_queue.c create mode 100644 services/cp_accel/cp_queue.h create mode 100644 services/hw_dsp/Makefile create mode 100644 services/hw_dsp/inc/hw_filter_codec_iir.h create mode 100644 services/hw_dsp/src/hw_filter_codec_iir.c create mode 100644 services/ibrt_core/Makefile create mode 100644 services/ibrt_core/inc/app_ibrt_bt_profile_sync.h create mode 100644 services/ibrt_core/inc/app_tws_besaud.h create mode 100644 services/ibrt_core/inc/app_tws_ctrl_thread.h create mode 100644 services/ibrt_core/inc/app_tws_ibrt.h create mode 100644 services/ibrt_core/inc/app_tws_ibrt_audio_analysis.h create mode 100644 services/ibrt_core/inc/app_tws_ibrt_audio_sync.h create mode 100644 services/ibrt_core/inc/app_tws_ibrt_cmd_audio_analysis.h create mode 100644 services/ibrt_core/inc/app_tws_ibrt_cmd_handler.h create mode 100644 services/ibrt_core/inc/app_tws_ibrt_cmd_sync_a2dp_status.h create mode 100644 services/ibrt_core/inc/app_tws_ibrt_cmd_sync_hfp_status.h create mode 100644 services/ibrt_core/inc/app_tws_ibrt_mock.h create mode 100644 services/ibrt_core/inc/app_tws_ibrt_queue.h create mode 100644 services/ibrt_core/inc/app_tws_ibrt_trace.h create mode 100644 services/ibrt_core/inc/app_tws_profile_sync.h create mode 100644 services/ibrt_core/inc/app_vendor_cmd_evt.h create mode 100644 services/ibrt_ota/Makefile create mode 100644 services/ibrt_ota/inc/ota_bes.h create mode 100644 services/ibrt_ota/inc/ota_control.h create mode 100644 services/ibrt_ota/inc/ota_spp.h create mode 100644 services/ibrt_ui/Makefile create mode 100644 services/ibrt_ui/inc/app_ibrt_ui.h create mode 100644 services/interconnection/Makefile create mode 100644 services/interconnection/umm_malloc/dbglog.h create mode 100644 services/interconnection/umm_malloc/umm_malloc.c create mode 100644 services/interconnection/umm_malloc/umm_malloc.h create mode 100644 services/lhdc_license/Makefile create mode 100644 services/multimedia/Makefile create mode 100644 services/multimedia/algorithm/fft/include/fft128dot.h create mode 100644 services/multimedia/algorithm/fft/include/fftr4_fxp.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/ChangeLog create mode 100644 services/multimedia/audio/codec/fdkaac_codec/NOTICE create mode 100644 services/multimedia/audio/codec/fdkaac_codec/README create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libAACdec/include/aacdecoder_lib.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libAACenc/include/aacenc_lib.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_archdef.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_bitbuffer.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_bitstream.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_core.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_crc.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_hybrid.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_tools_rom.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_trigFcts.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/aarch64/clz_aarch64.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/aarch64/fixmul_aarch64.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/abs.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/clz_arm.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/cplx_mul.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/fixmadd_arm.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/fixmul_arm.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/scale.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/scramble.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/autocorr2nd.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/clz.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/common_fix.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/cplx_mul.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/dct.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fft.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fft_rad2.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixmadd.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixminmax.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixmul.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixpoint_math.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mdct.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/abs_mips.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/clz_mips.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/cplx_mul.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/fixmadd_mips.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/fixmul_mips.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/scale.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/scramble.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/ppc/clz_ppc.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/ppc/fixmul_ppc.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/qmf.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/scale.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/scramble.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/abs_x86.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/clz_x86.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/fixmul_x86.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/mpegFileRead.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/tp_data.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/tpdec_lib.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/mpegFileWrite.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/tp_data.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/tpenc_lib.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libPCMutils/include/limiter.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libPCMutils/include/pcmutils_lib.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libSBRdec/include/sbrdecoder.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libSBRenc/include/sbr_encoder.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libSYS/include/FDK_audio.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libSYS/include/audio.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libSYS/include/cmdl_parser.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libSYS/include/conv_string.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libSYS/include/genericStds.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libSYS/include/machine_type.h create mode 100644 services/multimedia/audio/codec/fdkaac_codec/libSYS/include/wav_file.h create mode 100644 services/multimedia/audio/codec/sbc/inc/codec_sbc.h create mode 100644 services/multimedia/audio/process/adp/include/adp_arch.h create mode 100644 services/multimedia/audio/process/adp/include/adp_config.h create mode 100644 services/multimedia/audio/process/adp/include/adp_fftwrap.h create mode 100644 services/multimedia/audio/process/adp/include/adp_filter.h create mode 100644 services/multimedia/audio/process/adp/include/adp_smallft.h create mode 100644 services/multimedia/audio/process/anc/cfg/Makefile create mode 100644 services/multimedia/audio/process/anc/cfg/anc_cfg.c create mode 100644 services/multimedia/audio/process/anc/include/anc_process.h create mode 100644 services/multimedia/audio/process/anc/include/fftfilt2.h create mode 100644 services/multimedia/audio/process/common/include/audio_memory.h create mode 100644 services/multimedia/audio/process/drc/include/drc.h create mode 100644 services/multimedia/audio/process/filters/cfg/Makefile create mode 100644 services/multimedia/audio/process/filters/cfg/eq_cfg.c create mode 100644 services/multimedia/audio/process/filters/cfg/eq_cfg.h create mode 100644 services/multimedia/audio/process/filters/include/dsd_process.h create mode 100644 services/multimedia/audio/process/filters/include/filter_debug_trace.h create mode 100644 services/multimedia/audio/process/filters/include/fir_process.h create mode 100644 services/multimedia/audio/process/filters/include/hw_codec_iir_process.h create mode 100644 services/multimedia/audio/process/filters/include/hw_iir_process.h create mode 100644 services/multimedia/audio/process/filters/include/iir_process.h create mode 100644 services/multimedia/audio/process/fir2iir/include/fir2iir.h create mode 100644 services/multimedia/audio/process/integer_resampling/include/integer_resampling.h create mode 100644 services/multimedia/audio/process/limiter/include/limiter.h create mode 100644 services/multimedia/audio/process/resample/coef/Makefile create mode 100644 services/multimedia/audio/process/resample/coef/resample_16k_to_48k_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_32k_to_50p7k_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_44p1k_to_48k_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_44p1k_to_50p7k_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_48k_to_44p1k_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_48k_to_50p7k_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_50p7k_to_44p1k_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_50p7k_to_48k_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_8k_to_8p4k_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_8p4k_to_8k_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_any_up256_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_any_up512_32_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_any_up512_36_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_any_up64_filter.txt create mode 100644 services/multimedia/audio/process/resample/coef/resample_coef.c create mode 100644 services/multimedia/audio/process/resample/include/audio_resample.h create mode 100644 services/multimedia/audio/process/resample/include/audio_resample_ex.h create mode 100644 services/multimedia/audio/process/resample/include/audio_resample_ex_32bit.h create mode 100644 services/multimedia/audio/process/resample/include/resample_coef.h create mode 100644 services/multimedia/speech/inc/Pcm8k_Cvsd.h create mode 100644 services/multimedia/speech/inc/SubBandBasedAEC.h create mode 100644 services/multimedia/speech/inc/VoiceActivityDetection.h create mode 100644 services/multimedia/speech/inc/ae_macros.h create mode 100644 services/multimedia/speech/inc/ae_math.h create mode 100644 services/multimedia/speech/inc/agc.h create mode 100644 services/multimedia/speech/inc/anc_assist_algo.h create mode 100644 services/multimedia/speech/inc/audio_drc2.h create mode 100644 services/multimedia/speech/inc/buffer_manager.h create mode 100644 services/multimedia/speech/inc/compexp.h create mode 100644 services/multimedia/speech/inc/crossfade.h create mode 100644 services/multimedia/speech/inc/cvsd_codec.h create mode 100644 services/multimedia/speech/inc/dual_mic_denoise.h create mode 100644 services/multimedia/speech/inc/echo_canceller.h create mode 100644 services/multimedia/speech/inc/ext_fft_f32.h create mode 100644 services/multimedia/speech/inc/ext_heap.h create mode 100644 services/multimedia/speech/inc/far_field_speech_enhancement.h create mode 100644 services/multimedia/speech/inc/fftfilt.h create mode 100644 services/multimedia/speech/inc/frame_resize.h create mode 100644 services/multimedia/speech/inc/g726.h create mode 100644 services/multimedia/speech/inc/g72x.h create mode 100644 services/multimedia/speech/inc/iir_resample.h create mode 100644 services/multimedia/speech/inc/iirfilt.h create mode 100644 services/multimedia/speech/inc/lc_mmse_ns.h create mode 100644 services/multimedia/speech/inc/lc_mmse_ns_float.h create mode 100644 services/multimedia/speech/inc/leftright_denoise.h create mode 100644 services/multimedia/speech/inc/lpc_plc_api.h create mode 100644 services/multimedia/speech/inc/main_classify.h create mode 100644 services/multimedia/speech/inc/med_aec3_comm.h create mode 100644 services/multimedia/speech/inc/med_aec3_main.h create mode 100644 services/multimedia/speech/inc/med_aec3_main_internal.h create mode 100644 services/multimedia/speech/inc/ns3.h create mode 100644 services/multimedia/speech/inc/plc_16000.h create mode 100644 services/multimedia/speech/inc/plc_8000.h create mode 100644 services/multimedia/speech/inc/recognition.h create mode 100644 services/multimedia/speech/inc/sensormic_denoise.h create mode 100644 services/multimedia/speech/inc/single_mic_NNDenoise.h create mode 100644 services/multimedia/speech/inc/spectrum.h create mode 100644 services/multimedia/speech/inc/spectrum_fix.h create mode 100644 services/multimedia/speech/inc/speech_2mic_ns2_denoise.h create mode 100644 services/multimedia/speech/inc/speech_3mic_ns.h create mode 100644 services/multimedia/speech/inc/speech_aec.h create mode 100644 services/multimedia/speech/inc/speech_aec2.h create mode 100644 services/multimedia/speech/inc/speech_cfg.h create mode 100644 services/multimedia/speech/inc/speech_config.h create mode 100644 services/multimedia/speech/inc/speech_dc_filter.h create mode 100644 services/multimedia/speech/inc/speech_eq.h create mode 100644 services/multimedia/speech/inc/speech_ff_2mic_ns2.h create mode 100644 services/multimedia/speech/inc/speech_ff_3mic_ns1.h create mode 100644 services/multimedia/speech/inc/speech_fir_calibration.h create mode 100644 services/multimedia/speech/inc/speech_gain.h create mode 100644 services/multimedia/speech/inc/speech_iir.h create mode 100644 services/multimedia/speech/inc/speech_iir_calibration.h create mode 100644 services/multimedia/speech/inc/speech_memory.h create mode 100644 services/multimedia/speech/inc/speech_mics_calibration.h create mode 100644 services/multimedia/speech/inc/speech_noise_gate.h create mode 100644 services/multimedia/speech/inc/speech_ns.h create mode 100644 services/multimedia/speech/inc/speech_peak_detector.h create mode 100644 services/multimedia/speech/inc/speech_ssat.h create mode 100644 services/multimedia/speech/inc/speech_utils.h create mode 100644 services/multimedia/speech/inc/speex_resampler.h create mode 100644 services/multimedia/speech/inc/triple_mic_denoise3.h create mode 100644 services/multimedia/speech/inc/wind_detection_2mic.h create mode 100644 services/multimedia/speech/inc/wnr.h create mode 100644 services/norflash_api/Makefile create mode 100644 services/norflash_api/norflash_api.cpp create mode 100644 services/norflash_api/norflash_api.h create mode 100644 services/nv_section/Makefile create mode 100644 services/nv_section/aud_section/Makefile create mode 100644 services/nv_section/aud_section/aud_section.c create mode 100644 services/nv_section/aud_section/aud_section.h create mode 100644 services/nv_section/aud_section/aud_section_inc.h create mode 100644 services/nv_section/customparam_section/Makefile create mode 100644 services/nv_section/customparam_section/customparam_section.c create mode 100644 services/nv_section/customparam_section/customparam_section.h create mode 100644 services/nv_section/factory_section/Makefile create mode 100644 services/nv_section/factory_section/factory_section.c create mode 100644 services/nv_section/factory_section/factory_section.h create mode 100644 services/nv_section/fpga_section/Makefile create mode 100644 services/nv_section/fpga_section/nvrecord_ble.c create mode 100644 services/nv_section/fpga_section/nvrecord_ble.h create mode 100644 services/nv_section/fpga_section/nvrecord_bt.c create mode 100644 services/nv_section/fpga_section/nvrecord_bt.h create mode 100644 services/nv_section/fpga_section/nvrecord_env.c create mode 100644 services/nv_section/fpga_section/nvrecord_env.h create mode 100644 services/nv_section/fpga_section/nvrecord_externsion.c create mode 100644 services/nv_section/fpga_section/nvrecord_externsion.h create mode 100644 services/nv_section/include/section_def.h create mode 100644 services/nv_section/log_section/Makefile create mode 100644 services/nv_section/log_section/coredump_section.c create mode 100644 services/nv_section/log_section/coredump_section.h create mode 100644 services/nv_section/log_section/crash_dump_section.c create mode 100644 services/nv_section/log_section/crash_dump_section.h create mode 100644 services/nv_section/log_section/log_section.c create mode 100644 services/nv_section/log_section/log_section.h create mode 100644 services/nv_section/nv_section_dbg.h create mode 100644 services/nv_section/userdata_section/Makefile create mode 100644 services/nv_section/userdata_section/nvrecord_ble.c create mode 100644 services/nv_section/userdata_section/nvrecord_ble.h create mode 100644 services/nv_section/userdata_section/nvrecord_bt.c create mode 100644 services/nv_section/userdata_section/nvrecord_bt.h create mode 100644 services/nv_section/userdata_section/nvrecord_dma_config.c create mode 100644 services/nv_section/userdata_section/nvrecord_dma_config.h create mode 100644 services/nv_section/userdata_section/nvrecord_env.c create mode 100644 services/nv_section/userdata_section/nvrecord_env.h create mode 100644 services/nv_section/userdata_section/nvrecord_extension.c create mode 100644 services/nv_section/userdata_section/nvrecord_extension.h create mode 100644 services/nv_section/userdata_section/nvrecord_fp_account_key.c create mode 100644 services/nv_section/userdata_section/nvrecord_fp_account_key.h create mode 100644 services/nv_section/userdata_section/nvrecord_gsound.c create mode 100644 services/nv_section/userdata_section/nvrecord_gsound.h create mode 100644 services/nv_section/userdata_section/nvrecord_ota.c create mode 100644 services/nv_section/userdata_section/nvrecord_ota.h create mode 100644 services/nvrecord/Makefile create mode 100644 services/nvrecord/list_ext.c create mode 100644 services/nvrecord/list_ext.h create mode 100644 services/nvrecord/nvrec_config.c create mode 100644 services/nvrecord/nvrec_config.h create mode 100644 services/nvrecord/nvrecord.c create mode 100644 services/nvrecord/nvrecord.h create mode 100644 services/nvrecord/nvrecord_ble.c create mode 100644 services/nvrecord/nvrecord_ble.h create mode 100644 services/nvrecord/nvrecord_dev.h create mode 100644 services/nvrecord/nvrecord_env.c create mode 100644 services/nvrecord/nvrecord_env.h create mode 100644 services/nvrecord/nvrecord_fp_account_key.c create mode 100644 services/nvrecord/nvrecord_fp_account_key.h create mode 100644 services/osif/Makefile create mode 100644 services/osif/ddbif.h create mode 100644 services/osif/ddbif_bes.c create mode 100644 services/osif/osif.h create mode 100644 services/osif/osif_rtx.c create mode 100644 services/ota/Makefile create mode 100644 services/ota/ota_common.cpp create mode 100644 services/ota/ota_common.h create mode 100644 services/ota/ota_dbg.h create mode 100644 services/overlay/Makefile create mode 100644 services/overlay/app_overlay.cpp create mode 100644 services/overlay/app_overlay.h create mode 100644 services/resources/Makefile create mode 100644 services/resources/resources.cpp create mode 100644 services/resources/resources.h create mode 100644 services/through_put/Makefile create mode 100644 services/through_put/app_through_put.cpp create mode 100644 services/through_put/app_through_put.h create mode 100644 services/tota/Makefile create mode 100644 services/tota/app_spp_tota.cpp create mode 100644 services/tota/app_spp_tota.h create mode 100644 services/tota/app_spp_tota_general_service.cpp create mode 100644 services/tota/app_spp_tota_general_service.h create mode 100644 services/tota/app_tota.cpp create mode 100644 services/tota/app_tota.h create mode 100644 services/tota/app_tota_anc.cpp create mode 100644 services/tota/app_tota_anc.h create mode 100644 services/tota/app_tota_audio_dump.cpp create mode 100644 services/tota/app_tota_audio_dump.h create mode 100644 services/tota/app_tota_cmd_code.h create mode 100644 services/tota/app_tota_cmd_handler.cpp create mode 100644 services/tota/app_tota_cmd_handler.h create mode 100644 services/tota/app_tota_conn.cpp create mode 100644 services/tota/app_tota_conn.h create mode 100644 services/tota/app_tota_custom.cpp create mode 100644 services/tota/app_tota_custom.h create mode 100644 services/tota/app_tota_data_handler.cpp create mode 100644 services/tota/app_tota_data_handler.h create mode 100644 services/tota/app_tota_flash_program.cpp create mode 100644 services/tota/app_tota_flash_program.h create mode 100644 services/tota/app_tota_general.cpp create mode 100644 services/tota/app_tota_general.h create mode 100644 services/tota/app_tota_mic.cpp create mode 100644 services/tota/app_tota_mic.h create mode 100644 services/tota/tota_buffer_manager.cpp create mode 100644 services/tota/tota_buffer_manager.h create mode 100644 services/tota/tota_stream_data_transfer.cpp create mode 100644 services/tota/tota_stream_data_transfer.h create mode 100644 services/tota/tota_test.cpp create mode 100644 tests/anc_usb/Makefile create mode 100644 tests/anc_usb/adda_loop_app.c create mode 100644 tests/anc_usb/adda_loop_app.h create mode 100644 tests/anc_usb/anc_usb_app.c create mode 100644 tests/anc_usb/anc_usb_app.h create mode 100644 tests/anc_usb/dualadc_audio_app.c create mode 100644 tests/anc_usb/dualadc_audio_app.h create mode 100644 tests/anc_usb/main.c create mode 100644 tests/anc_usb/memutils.c create mode 100644 tests/anc_usb/memutils.h create mode 100644 tests/anc_usb/mic_key.c create mode 100644 tests/anc_usb/safe_queue.c create mode 100644 tests/anc_usb/safe_queue.h create mode 100644 tests/anc_usb/speech_process.c create mode 100644 tests/anc_usb/speech_process.h create mode 100644 tests/anc_usb/usb_audio_app.c create mode 100644 tests/anc_usb/usb_audio_app.h create mode 100644 tests/anc_usb/usb_audio_frm_defs.h create mode 100644 tests/anc_usb/usb_vendor_msg.c create mode 100644 tests/anc_usb/usb_vendor_msg.h create mode 100644 thirdparty/Makefile create mode 100644 thirdparty/audio_codec_lib/Makefile create mode 100644 thirdparty/audio_codec_lib/ldac/Makefile create mode 100644 thirdparty/audio_codec_lib/ldac/inc/ldacBT.h create mode 100644 thirdparty/audio_codec_lib/liblhdc-dec/Makefile create mode 100644 thirdparty/audio_codec_lib/liblhdc-dec/inc/lhdcUtil.h create mode 100644 thirdparty/demo_lib/Makefile create mode 100644 thirdparty/demo_lib/demo_lib.c create mode 100644 thirdparty/demo_lib/demo_lib.h create mode 100644 thirdparty/noise_tracker_lib/Makefile create mode 100644 thirdparty/noise_tracker_lib/noise_tracker.c create mode 100644 thirdparty/noise_tracker_lib/noise_tracker.h create mode 100644 thirdparty/userapi/Makefile create mode 100644 thirdparty/userapi/app_thirdparty.cpp create mode 100644 thirdparty/userapi/app_thirdparty.h create mode 100644 thirdparty/userapi/demo_app/LibDemo.cpp create mode 100644 thirdparty/userapi/demo_app/LibDemo.h create mode 100644 thirdparty/userapi/demo_app/Makefile create mode 100644 thirdparty/userapi/noise_tracker_app/Makefile create mode 100644 thirdparty/userapi/noise_tracker_app/NoiseTrackerDemo.cpp create mode 100644 thirdparty/userapi/noise_tracker_app/noise_tracker_callback.c create mode 100644 thirdparty/userapi/noise_tracker_app/noise_tracker_callback.h create mode 100644 utils/boot_struct/Makefile create mode 100644 utils/boot_struct/boot_struct.c create mode 100644 utils/boot_struct/norflash_cfg.h create mode 100644 utils/boot_struct/reboot_param.h create mode 100644 utils/boot_struct/tool_msg.h create mode 100644 utils/build_info/build_info.c create mode 100644 utils/cqueue/Makefile create mode 100644 utils/cqueue/cqueue.c create mode 100644 utils/cqueue/cqueue.h create mode 100644 utils/crash_catcher/CrashCatcher.c create mode 100644 utils/crash_catcher/CrashCatcherPriv.h create mode 100644 utils/crash_catcher/CrashCatcher_armv7m.S create mode 100644 utils/crash_catcher/HexDump.c create mode 100644 utils/crash_catcher/Makefile create mode 100644 utils/crash_catcher/include/CrashCatcher.h create mode 100644 utils/crash_catcher/include/CrashCatcherApi.h create mode 100644 utils/crash_catcher/include/FloatMocks.h create mode 100644 utils/crc16/Makefile create mode 100644 utils/crc16/crc16.c create mode 100644 utils/crc16/crc16.h create mode 100644 utils/crc32/Makefile create mode 100644 utils/crc32/crc32.c create mode 100644 utils/crc32/crc32.h create mode 100644 utils/crc32/crc32_rom.c create mode 100644 utils/encrypt/Makefile create mode 100644 utils/encrypt/_sha256.h create mode 100644 utils/encrypt/aes.h create mode 100644 utils/encrypt/types.h create mode 100644 utils/encrypt/uECC.h create mode 100644 utils/encrypt/uECC_vli.h create mode 100644 utils/heap/Makefile create mode 100644 utils/heap/heap_api.c create mode 100644 utils/heap/heap_api.h create mode 100644 utils/heap/med_memory.h create mode 100644 utils/heap/multi_heap.c create mode 100644 utils/heap/multi_heap.h create mode 100644 utils/heap/multi_heap_internal.h create mode 100644 utils/heap/multi_heap_platform.h create mode 100644 utils/heap/pool_api.c create mode 100644 utils/hexdump/Makefile create mode 100644 utils/hexdump/hexdump.c create mode 100644 utils/hexdump/hexdump.h create mode 100644 utils/hwtimer_list/Makefile create mode 100644 utils/hwtimer_list/hwtimer_list.c create mode 100644 utils/hwtimer_list/hwtimer_list.h create mode 100644 utils/intersyshci/Makefile create mode 100644 utils/intersyshci/intersyshci.h create mode 100644 utils/intersyshci/trans_adapt.h create mode 100644 utils/intersyshci/trans_adapt_v1.h create mode 100644 utils/intersyshci/trans_adapt_v2.h create mode 100644 utils/kfifo/Makefile create mode 100644 utils/kfifo/kfifo.c create mode 100644 utils/kfifo/kfifo.h create mode 100644 utils/libc/Makefile create mode 100644 utils/libc/inc/assert.h create mode 100644 utils/libc/inc/ctype.h create mode 100644 utils/libc/inc/errno.h create mode 100644 utils/libc/inc/stdarg.h create mode 100644 utils/libc/inc/stdbool.h create mode 100644 utils/libc/inc/stddef.h create mode 100644 utils/libc/inc/stdint.h create mode 100644 utils/libc/inc/stdio.h create mode 100644 utils/libc/inc/stdlib.h create mode 100644 utils/libc/inc/string.h create mode 100644 utils/libc/libc_rom.c create mode 100644 utils/list/Makefile create mode 100644 utils/list/list.c create mode 100644 utils/list/list.h create mode 100644 utils/lockcqueue/Makefile create mode 100644 utils/lockcqueue/lockcqueue.c create mode 100644 utils/lockcqueue/lockcqueue.h create mode 100644 utils/retention_ram/Makefile create mode 100644 utils/retention_ram/retention_ram.c create mode 100644 utils/retention_ram/retention_ram.h create mode 100644 utils/rom_utils/Makefile create mode 100644 utils/rom_utils/export_fn_rom.h create mode 100644 utils/sha256/Makefile create mode 100644 utils/sha256/hash-internal.h create mode 100644 utils/sha256/sha256.c create mode 100644 utils/sha256/sha256.h create mode 100644 utils/sha256/sha256_rom.c create mode 100644 utils/xyzmodem/Makefile create mode 100644 utils/xyzmodem/xyzmodem.c create mode 100644 utils/xyzmodem/xyzmodem.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1c99b0a --- /dev/null +++ b/.gitignore @@ -0,0 +1,99 @@ +# +# NOTE! Don't add files that are generated in specific +# subdirectories here. Add them in the ".gitignore" file +# in that subdirectory instead. +# +# NOTE! Please use 'git ls-files -i --exclude-standard' +# command after changing this file, to see if there are +# any tracked files which get ignored after the change. +# +# ('git ls-files -i --exclude-standard -ocs --directory' +# command can show all the tracked and untracked files +# which get ignored after the change.) +# + +# Hidden files +.* +# Except for these hidden files +!.gitignore +!.gitattributes +!.mailmap + +# Backup files +*~ +*.bak +*.BAK +*.orig +\#*# + +# Tag files +/tags +/TAGS +/cscope.* +/ncscope.* +/compile_commands.json + +# Object files +*.o +*.o.* +*.ko +*.obj +*.lo +*.slo +*.py[co] + +# List files +*.i +*.lst + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lai +*.pyd + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.elf +*.i*86 +*.x86_64 +*.hex + +# Source insight project files +/[sS][iI]/ + +# Generated project files +*.ncb +*.idb +*.pdb +*.sdf +*.suo +*.opensdf +#/Debug/ +#/Release/ +Debug/ +Release/ +/ipch/ + +# Library dir +#lib/ + +# Build dir +/out/ +*.pre + +# configuration file +# *.ini diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fbaf37f --- /dev/null +++ b/Makefile @@ -0,0 +1,1043 @@ + +CONFIG_CROSS_COMPILE := arm-none-eabi- +CONFIG_STRICT_CFLAGS ?= y +CONFIG_SAVE_TARGET ?= n +CONFIG_FORCE_WIN_SHELL ?= y + +export CONFIG_STRICT_CFLAGS CONFIG_SAVE_TARGET CONFIG_FORCE_WIN_SHELL + +# --------------------------------------------------------------------------- +# Platform and shell detection + +export WIN_PLAT := n +ifeq ($(OS),Windows_NT) +# Detect Cygwin +ifneq ($(findstring /,$(PWD)),/) +# also $(findstring /,$(HOME)) ? +WIN_PLAT := y +endif +endif + +export WIN_SHELL := n +ifeq ($(WIN_PLAT),y) +ifeq ($(CONFIG_FORCE_WIN_SHELL),y) +WIN_SHELL := y +else +# Detect Unix-style shell +ifeq ($(shell echo $$0),$$0) +WIN_SHELL := y +endif +endif +endif + +BACKSLASH := \ # backslash +BACKSLASH := $(strip $(BACKSLASH)) + +TO_UNIX_PATH = $(subst $(BACKSLASH),/,$(1)) +TO_WIN_PATH = $(subst /,$(BACKSLASH),$(1)) +ESC_WIN_PATH = $(subst $(BACKSLASH),$(BACKSLASH)$(BACKSLASH),$(1)) + +ifeq ($(WIN_PLAT),y) +ifeq ($(WIN_SHELL),y) +# make will choose sh.exe as SHELL if it finds sh.exe in the directories of PATH, regardless of +# the setting in environment or parent (e.g., when git.exe is in the PATH) +SHELL := cmd.exe +SHELL_CMD = $(call TO_WIN_PATH,$(1)) +else +SHELL_CMD = $(call ESC_WIN_PATH,$(call TO_WIN_PATH,$(1))) +endif +else +SHELL_CMD = $(1) +endif + +# The Unix-style path is recognized by compiler toolchain, GNU utilities and windows redirection +# operators, but not by windows native commands (e.g., mkdir) and applications. + +# End of platform and shell detection +# --------------------------------------------------------------------------- + +# Do not use make's built-in rules and variables +# (this increases performance and avoids hard-to-debug behaviour); +MAKEFLAGS += -rR + +# Avoid funny character set dependencies +unexport LC_ALL +LC_COLLATE=C +LC_NUMERIC=C +export LC_COLLATE LC_NUMERIC + +# Avoid interference with shell env settings +unexport GREP_OPTIONS + +# Check if just to show the help content +ifeq ($(MAKECMDGOALS),help) +ifeq ($(T),) +HELP_TARGET := 1 +endif +endif + +ifneq ($(HELP_TARGET),1) +# We are using a recursive build, so we need to do a little thinking +# to get the ordering right. +# +# Most importantly: sub-Makefiles should only ever modify files in +# their own directory. If in some directory we have a dependency on +# a file in another dir (which doesn't happen often, but it's often +# unavoidable when linking the built-in.o targets which finally +# turn into elf file), we will call a sub make in that other dir, and +# after that we are sure that everything which is in that other dir +# is now up to date. +# +# The only cases where we need to modify files which have global +# effects are thus separated out and done before the recursive +# descending is started. They are now explicitly listed as the +# prepare rule. + +# Beautify output +# --------------------------------------------------------------------------- +# +# Normally, we echo the whole command before executing it. By making +# that echo $($(quiet)$(cmd)), we now have the possibility to set +# $(quiet) to choose other forms of output instead, e.g. +# +# quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@ +# cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< +# +# If $(quiet) is empty, the whole command will be printed. +# If it is set to "quiet_", only the short version will be printed. +# If it is set to "silent_", nothing will be printed at all, since +# the variable $(silent_cmd_cc_o_c) doesn't exist. +# +# A simple variant is to prefix commands with $(Q) - that's useful +# for commands that shall be hidden in non-verbose mode. +# +# $(Q)ln $@ :< +# +# If KBUILD_VERBOSE equals 0 then the above command will be hidden. +# If KBUILD_VERBOSE equals 1 then the above command is displayed. +# +# To put more focus on warnings, be less verbose as default +# Use 'make V=1' to see the full commands + +ifeq ("$(origin V)","command line") + KBUILD_VERBOSE = $(V) +endif +ifndef KBUILD_VERBOSE + KBUILD_VERBOSE = 0 +endif + +ifeq ($(KBUILD_VERBOSE),1) + quiet := + Q := +else + quiet := quiet_ + Q := @ +endif + +# If the user is running make -s (silent mode), suppress echoing of +# commands + +ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4 +ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),) + quiet=silent_ +endif +else # make-3.8x +ifneq ($(filter s% -s%,$(MAKEFLAGS)),) + quiet=silent_ +endif +endif + +export quiet Q KBUILD_VERBOSE + +TARGET_CFG_FILE = config/$(T)/target.mk +TARGET_COMMON_FILE = config/common.mk + +# To locate output files in a separate directory two syntaxes are supported. +# In both cases the working directory must be the root of the kernel src. +# 1) O= +# Use "make O=dir/to/store/output/files/" +# +# 2) Set KBUILD_OUTPUT +# Set the environment variable KBUILD_OUTPUT to point to the directory +# where the output files shall be placed. +# export KBUILD_OUTPUT=dir/to/store/output/files/ +# make +# +# The O= assignment takes precedence over the KBUILD_OUTPUT environment +# variable. + +# KBUILD_SRC is set on invocation of make in OBJ directory +# KBUILD_SRC is not intended to be used by the regular user (for now) +ifeq ($(KBUILD_SRC),) + +export KBUILD_ROOT := $(CURDIR) + +# OK, Make called in directory where kernel src resides +# Do we want to locate output files in a separate directory? + +export KBUILD_OUTPUT := $(CURDIR)/out +ifeq ("$(origin O)","command line") + KBUILD_OUTPUT := $(O) +endif + +# Select target +ifeq ($(CONFIG_SAVE_TARGET),y) +ifeq ($(T),) +-include $(KBUILD_OUTPUT)/.config +T := $(strip $(T)) +endif +endif +ifeq ($(T),) +$(error Please specify the target in the command line: T=) +endif +ifeq ($(wildcard $(TARGET_CFG_FILE)),) +$(error Invalid target: T=$(T)) +endif +export T + +KBUILD_OUTPUT := $(KBUILD_OUTPUT)/$(T) + +# That's our default target when none is given on the command line +PHONY := _all +_all: + +# Cancel implicit rules on the config file +$(KBUILD_OUTPUT)/.config: ; + +ifneq ($(KBUILD_OUTPUT),) +# Invoke a second make in the output directory, passing relevant variables +# check that the output directory actually exists +saved-output := $(KBUILD_OUTPUT) +ifeq ($(WIN_PLAT),y) +KBUILD_OUTPUT := $(subst /,\,$(KBUILD_OUTPUT)) +KBUILD_OUTPUT := $(shell ( if not exist $(KBUILD_OUTPUT)\ mkdir $(KBUILD_OUTPUT) ) \ + && cd $(KBUILD_OUTPUT) && cd) +KBUILD_OUTPUT := $(subst \,/,$(KBUILD_OUTPUT)) +else +KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \ + && /bin/pwd) +endif + +$(if $(KBUILD_OUTPUT),, \ + $(error failed to create output directory "$(saved-output)")) + +ifeq ($(CONFIG_SAVE_TARGET),y) +ifeq ($(WIN_PLAT),y) +_dummy := $(shell echo T := $(T)> $(KBUILD_OUTPUT)/../.config) +else +_dummy := $(shell echo "T := $(T)" > $(KBUILD_OUTPUT)/../.config) +endif +endif + +PHONY += $(MAKECMDGOALS) sub-make + +$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make + @: + +include $(CURDIR)/scripts/submods_init.mk + +ifneq ($(filter allclean,$(MAKECMDGOALS)),) +ALLCLEAN := 1 +export ALLCLEAN +endif + +# Look for make include files relative to root of kernel src +MAKEFLAGS += --include-dir=$(CURDIR) + +ifeq ($(WIN_PLAT),y) +START_TIME := $(shell echo %time%) +START_DATE_TIME := $(shell echo %date% %time%) +else +START_TIME := $(shell date +"%s.%N") +START_DATE_TIME := $(shell date +"%Y-%m-%d %T.%N") +endif + +sub-make: FORCE + @echo MAKE START: $(START_DATE_TIME) + $(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \ + -f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS)) +ifeq ($(WIN_PLAT),y) + @echo MAKE END: %date% %time% +ifneq ($(wildcard tools/timediff.bat),) + @tools/timediff.bat "%time%" "$(START_TIME)" +endif +else + @echo MAKE END: $$(date +"%Y-%m-%d %T.%N") + @printf "MAKE TIME: %.2f seconds\n" $$(echo "$$(date +%s.%N) - $(START_TIME)" | bc) +endif + +# Leave processing to above invocation of make +skip-makefile := 1 +endif # ifneq ($(KBUILD_OUTPUT),) +endif # ifeq ($(KBUILD_SRC),) + +# We process the rest of the Makefile if this is the final invocation of make +ifeq ($(skip-makefile),) + +# Do not print "Entering directory ...", +# but we want to display it when entering to the output directory +# so that IDEs/editors are able to understand relative filenames. +MAKEFLAGS += --no-print-directory + +# If building an external module we do not care about the all: rule +# but instead _all depend on modules +PHONY += all +_all: all + +ifeq ($(KBUILD_SRC),) + # building in the source tree + srctree := . +else + ifeq ($(KBUILD_SRC)/,$(dir $(CURDIR))) + # building in a subdirectory of the source tree + srctree := .. + else + ifeq ($(KBUILD_SRC)/,$(dir $(patsubst %/,%,$(dir $(CURDIR))))) + srctree := ../.. + else + srctree := $(KBUILD_SRC) + endif + endif +endif +objtree := . +src := $(srctree) +obj := $(objtree) + +VPATH := $(srctree) + +export srctree objtree VPATH + +# Git revision +ifeq ($(WIN_PLAT),y) +GIT_REVISION := $(shell (where git >nul 2>&1) && (git rev-parse --short HEAD 2>nul)) +else +GIT_REVISION := $(shell (which git >/dev/null 2>&1) && (git rev-parse --short HEAD 2>/dev/null)) +endif + +ifneq ($(GIT_REVISION),) +ifeq ($(WIN_PLAT),y) +GIT_REVISION := $(GIT_REVISION)$(shell (git diff --quiet && git diff --cached --quiet) >nul 2>&1 || echo -dirty) +else +GIT_REVISION := $(GIT_REVISION)$(shell (git diff --quiet && git diff --cached --quiet) >/dev/null 2>&1 || echo -dirty) +endif +endif + + +# Cross compiling and selecting different set of gcc/bin-utils +# --------------------------------------------------------------------------- +# +# When performing cross compilation for other architectures ARCH shall be set +# to the target architecture. (See arch/* for the possibilities). +# ARCH can be set during invocation of make: +# make ARCH=ia64 +# Another way is to have ARCH set in the environment. +# The default ARCH is the host where make is executed. + +# CROSS_COMPILE specify the prefix used for all executables used +# during compilation. Only gcc and related bin-utils executables +# are prefixed with $(CROSS_COMPILE). +# CROSS_COMPILE can be set on the command line +# make CROSS_COMPILE=ia64-linux- +# Alternatively CROSS_COMPILE can be set in the environment. +# A third alternative is to store a setting in .config so that plain +# "make" in the configured kernel build directory always uses that. +# Default value for CROSS_COMPILE is not to prefix executables +# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile +ARCH ?= arm +CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%) + +# SHELL used by kbuild +ifneq ($(WIN_PLAT),y) +CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ + else if [ -x /bin/bash ]; then echo /bin/bash; \ + else echo sh; fi ; fi) +endif + +# Make variables (CC, etc...) +ifeq ($(TOOLCHAIN),armclang) +CC = armclang --target=arm-arm-none-eabi +CPP = $(CC) -E +AS = $(CC) +C++ = $(CC) +LD = $(CC) +AR = armar +NM = fromelf +STRIP = fromelf +OBJCOPY = fromelf +OBJDUMP = fromelf +else +AS = $(CROSS_COMPILE)as +CC = $(CROSS_COMPILE)gcc +CPP = $(CC) -E +C++ = $(CROSS_COMPILE)g++ +LD = $(CC) +#LD = $(CROSS_COMPILE)ld +AR = $(CROSS_COMPILE)ar +NM = $(CROSS_COMPILE)nm +STRIP = $(CROSS_COMPILE)strip +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump +endif + +AWK = awk +PERL = perl +PYTHON = python + +KBUILD_CPPFLAGS := + +KBUILD_CFLAGS := -fno-common -fmessage-length=0 -Wall \ + -fno-exceptions -ffunction-sections \ + -fdata-sections -fomit-frame-pointer + +# By default char on ARM platform is unsigned char, but char on x86 platform +# is signed char. To avoid porting issues, force char to be signed char +# on ARM platform. +KBUILD_CFLAGS += -fsigned-char + +ifneq ($(TOOLCHAIN),armclang) +# 1) Avoid checking out-of-bound array accesses in a loop +# (and unrolling/peeling/exiting the loop based on the check) +# 2) Avoid detecting paths dereferencing a NULL pointer +# (and turning the problematic statement into a trap) +KBUILD_CFLAGS += -fno-aggressive-loop-optimizations \ + -fno-isolate-erroneous-paths-dereference +endif + +# Treat floating-point constants as float instead of double +ifeq ($(TOOLCHAIN),armclang) +KBUILD_CFLAGS += -cl-single-precision-constant -fshort-enums +else +KBUILD_CFLAGS += -fsingle-precision-constant +endif +KBUILD_CFLAGS += -Wdouble-promotion -Wfloat-conversion + +KBUILD_CFLAGS += -g + +#C_ONLY_FLAGS := -std=gnu89 +C_ONLY_FLAGS := -std=gnu99 + +C++_ONLY_FLAGS := -std=gnu++98 -fno-rtti + +KBUILD_AFLAGS := -D__ASSEMBLY__ + +export ARCH CROSS_COMPILE AS LD CC +export CPP C++ AR NM STRIP OBJCOPY OBJDUMP +export MAKE AWK PERL PYTHON + +export KBUILD_CPPFLAGS NOSTDINC_FLAGS OBJCOPYFLAGS LDFLAGS +export KBUILD_CFLAGS +export KBUILD_AFLAGS +export KBUILD_ARFLAGS +export C_ONLY_FLAGS C++_ONLY_FLAGS + +# Files to ignore in find ... statements + +export RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o \ + -name CVS -o -name .pc -o -name .hg -o -name .git \) \ + -prune -o +export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \ + --exclude CVS --exclude .pc --exclude .hg --exclude .git + +# =========================================================================== +# Build targets only. + +# Objects we will link into $(IMAGE_FILE) / subdirs we need to visit +init-y := init/ +core-y := main/ + +LDS_FILE := best1000.lds + +# Link flags for all LD processes +LINK_CFLAGS := +export LINK_CFLAGS + +# Link flags for image only +LIB_LDFLAGS := +CFLAGS_IMAGE := -static +ifeq ($(TOOLCHAIN),armclang) +LDFLAGS_IMAGE := --no_locals +else +LDFLAGS_IMAGE := -X --no-wchar-size-warning +endif + +# Include target definitions +include $(srctree)/$(TARGET_CFG_FILE) +include $(srctree)/$(TARGET_COMMON_FILE) + +$(srctree)/$(TARGET_CFG_FILE): ; +$(srctree)/$(TARGET_COMMON_FILE): ; + +ifneq ($(filter-out %/,$(init-y) $(core-y)),) +$(error The object files cannot be linked at top level: $(filter-out %/,$(init-y) $(core-y))) +endif + +ifeq ($(TOOLCHAIN),armclang) +# Entry objects +ifeq ($(entry-y),) +entry-y += utils/boot_struct/boot_struct.o +ifeq ($(ROM_BUILD),1) +entry-y += tests/rom/startup_ARMCM.o +ifneq ($(filter tests/rom/,$(core-y)),) +entry-y += tests/rom/export_fn_rom.o +endif +else # !ROM_BUILD +entry-y += platform/cmsis/retarget_armclang_asm.o +ifeq ($(PROGRAMMER),1) +entry-y += tests/programmer/sys_api_programmer.o +else +entry-y += platform/main/startup_main.o +endif +endif # !ROM_BUILD +endif +ifeq ($(filter %.o,$(entry-y)),) +$(error Entry objects must be defined in entry-y in target.mk) +endif +BAD_ENTRY_OBJS := $(filter-out %.o,$(entry-y)) +ifneq ($(BAD_ENTRY_OBJS),) +$(error Only objects can be defined in entry-y in target.mk: $(BAD_ENTRY_OBJS)) +endif +IMAGE_ENTRY := $(entry-y) +ifeq ($(ROM_BUILD),1) +CFLAGS_IMAGE += -e Reset_Handler +else ifeq ($(PROGRAMMER),1) +CFLAGS_IMAGE += -e programmer_start +else +CFLAGS_IMAGE += -e __main +endif +endif + +ifneq ($(NO_BUILDID),1) +ifneq ($(TOOLCHAIN),armclang) +LDFLAGS_IMAGE += --build-id +endif +endif +ifeq ($(CROSS_REF),1) +ifeq ($(TOOLCHAIN),armclang) +LDFLAGS_IMAGE += --xref +else +LDFLAGS_IMAGE += --cref +endif +endif + +REAL_LDS_FILE := $(LDS_FILE) +ifeq ($(TOOLCHAIN),armclang) +SCATTER_LDS_SUFFIX := _scat +ifeq ($(filter %$(SCATTER_LDS_SUFFIX),$(LDS_FILE)),) +REAL_LDS_FILE := $(LDS_FILE)$(SCATTER_LDS_SUFFIX) +endif +endif + +# Generate REVISION_INFO (might be defined in target) +ifeq ($(REVISION_INFO),) +ifeq ($(CUST_TGT_INFO),) +REVISION_INFO := $(GIT_REVISION):$(T) +else +REVISION_INFO := $(GIT_REVISION):$(CUST_TGT_INFO) +endif +endif + +include $(srctree)/scripts/include.mk + +REVISION_INFO := $(subst $(space),-,$(strip $(REVISION_INFO))) +SOFTWARE_VERSION := $(subst $(space),-,$(strip $(SOFTWARE_VERSION))) + +$(info -------------------------------) +$(info REVISION_INFO: $(REVISION_INFO)) +$(info -------------------------------) + +# Build host and user info +ifeq ($(WIN_PLAT),y) +export BUILD_HOSTNAME := $(COMPUTERNAME) +export BUILD_USERNAME := $(USERNAME) +else +export BUILD_HOSTNAME := $(shell hostname -s) +export BUILD_USERNAME := $(shell id -un) +endif + +BUILD_HOSTNAME := $(subst $(space),-,$(strip $(BUILD_HOSTNAME))) +BUILD_USERNAME := $(subst $(space),-,$(strip $(BUILD_USERNAME))) + +# Default kernel image to build when no specific target is given. +# IMAGE_FILE may be overruled on the command line or +# set in the environment +IMAGE_FILE ?= $(notdir $(T)).elf + +ifneq ($(filter .map .bin .hex .lst,$(suffix $(IMAGE_FILE))),) +$(error Invalid IMAGE_FILE (conflicted suffix): $(IMAGE_FILE)) +endif + +LST_SECTION_OPTS := +LST_SECTION_NAME := +ifneq ($(LST_ONLY_SECTION),) +ifeq ($(TOOLCHAIN),armclang) +LST_SECTION_OPTS += $(foreach m,$(subst $(comma),$(space),$(LST_ONLY_SECTION)),--only=$m ) +else +LST_SECTION_OPTS += $(foreach m,$(subst $(comma),$(space),$(LST_ONLY_SECTION)),-j $m ) +endif +LST_SECTION_NAME := _$(subst *,+,$(subst !,-,$(LST_ONLY_SECTION))) +endif +ifneq ($(LST_RM_SECTION),) +ifeq ($(TOOLCHAIN),armclang) +LST_SECTION_OPTS += $(foreach m,$(subst $(comma),$(space),$(LST_RM_SECTION)),--ignore_section=$m ) +else +LST_SECTION_OPTS += $(foreach m,$(subst $(comma),$(space),$(LST_RM_SECTION)),-R $m ) +endif +LST_SECTION_NAME := $(LST_SECTION_NAME)_no_$(subst *,+,$(subst !,-,$(LST_RM_SECTION))) +endif + +IMAGE_MAP := $(addsuffix .map,$(basename $(IMAGE_FILE))) +IMAGE_BIN := $(addsuffix .bin,$(basename $(IMAGE_FILE))) +STR_BIN := $(addsuffix .str,$(basename $(IMAGE_FILE))) +IMAGE_HEX := $(addsuffix .hex,$(basename $(IMAGE_FILE))) +ifeq ($(LST_SECTION_OPTS),) +IMAGE_LST := $(addsuffix .lst,$(basename $(IMAGE_FILE))) +else +IMAGE_LST := $(addsuffix $(LST_SECTION_NAME).lst,$(basename $(IMAGE_FILE))) +IMAGE_SEC := $(addsuffix $(LST_SECTION_NAME)$(suffix $(IMAGE_FILE)),$(basename $(IMAGE_FILE))) +endif + +LDS_TARGET := _$(notdir $(REAL_LDS_FILE)) + +IMAGE_VER := build_info.o + +targets := $(LDS_TARGET) $(IMAGE_FILE) $(IMAGE_BIN) $(STR_BIN) $(IMAGE_LST) $(IMAGE_VER) +cmd_files := $(wildcard $(foreach f,$(targets),$(call get_depfile_name,$(f)))) + +ifneq ($(cmd_files),) +include $(cmd_files) +$(cmd_files): ; +endif + +# The all: target is the default when no target is given on the +# command line. +# This allow a user to issue only 'make' to build a kernel including modules +# Defaults to $(IMAGE_BIN) +ifeq ($(TRACE_STR_SECTION),1) +all: $(IMAGE_BIN) $(STR_BIN) ; +else +all: $(IMAGE_BIN) ; +endif + +ifeq ($(TOOLCHAIN),armclang) + cmd_gen-IMAGE_BIN = $(OBJCOPY) --bincombined -o $@ $< +else + cmd_gen-IMAGE_BIN = $(OBJCOPY) -R .trc_str -O binary $< $@ +endif +quiet_cmd_gen-IMAGE_BIN = GENBIN $@ + +$(IMAGE_BIN): $(IMAGE_FILE) +ifneq ($(filter 1,$(COMPILE_ONLY) $(NO_BIN)),) + @: +else + +$(call if_changed,gen-IMAGE_BIN) +endif + +ifeq ($(TOOLCHAIN),armclang) + cmd_gen-STR_BIN = $(OBJCOPY) --bincombined -o $@ $< +else + cmd_gen-STR_BIN = $(OBJCOPY) -j .code_start_addr -j .rodata_str -j .trc_str \ + --change-section-lma .code_start_addr=0x00000000 \ + --change-section-lma .rodata_str=0x00000010 \ + --change-section-lma .trc_str=0x00008000 \ + -O binary $< $@ +endif +quiet_cmd_gen-STR_BIN = GENBIN $@ + +$(STR_BIN): $(IMAGE_FILE) +ifneq ($(filter 1,$(COMPILE_ONLY) $(NO_BIN)),) + @: +else + +$(call if_changed,gen-STR_BIN) +endif + +ifneq ($(TOOLCHAIN),armclang) + cmd_gen-IMAGE_HEX = $(OBJCOPY) -O ihex $< $@ +quiet_cmd_gen-IMAGE_HEX = GENHEX $@ + +$(IMAGE_HEX): $(IMAGE_FILE) +ifeq ($(COMPILE_ONLY),1) + @: +else + +$(call if_changed,gen-IMAGE_HEX) +endif +endif + +PHONY += lst lst_only +lst lst_only: $(IMAGE_LST) ; + +ifneq ($(filter lst_only,$(MAKECMDGOALS)),) +NO_COMPILE := 1 +endif + +ifeq ($(TOOLCHAIN),armclang) + cmd_gen-IMAGE_LST = $(OBJDUMP) $(LST_SECTION_OPTS) --datasymbols --text -c -d --output=$@ $< +else +ifeq ($(LST_SECTION_OPTS),) + cmd_gen-IMAGE_LST = $(OBJDUMP) -Sldx $< > $@ +else + cmd_gen-IMAGE_LST = $(OBJCOPY) $(LST_SECTION_OPTS) $< $(IMAGE_SEC) && $(OBJDUMP) -Sldx $(IMAGE_SEC) > $@ +endif +endif +quiet_cmd_gen-IMAGE_LST = GENLST $@ + +$(IMAGE_LST): $(IMAGE_FILE) + +$(call if_changed,gen-IMAGE_LST) + + +# Flags + +# arch Makefile may override CC so keep this after arch Makefile is included +#ifeq ($(CONFIG_STRICT_CFLAGS),y) +#NOSTDINC_FLAGS += -nostdinc +#endif +#NOSTDINC_FLAGS += -isystem "$(subst \,/,$(shell $(CC) -print-file-name=include))" + +ifeq ($(CONFIG_STRICT_CFLAGS),y) +# warn about C99 declaration after statement +#C_ONLY_FLAGS += -Wdeclaration-after-statement + +# disallow errors like 'EXPORT_GPL(foo);' with missing header +C_ONLY_FLAGS += -Werror=implicit-int + +# require functions to have arguments in prototypes, not empty 'int foo()' +#C_ONLY_FLAGS += -Werror=strict-prototypes + +C_ONLY_FLAGS += -Werror-implicit-function-declaration + +# Prohibit date/time macros, which would make the build non-deterministic +KBUILD_CFLAGS += $(call cc-option,-Werror=date-time) + +KBUILD_CFLAGS += $(call cc-option,-Wlogical-op) + +#KBUILD_CFLAGS += -Wno-address-of-packed-member + +KBUILD_CFLAGS += -Wno-trigraphs \ + -fno-strict-aliasing \ + -Wno-format-security + +#KBUILD_CFLAGS += Wundef + +# use the deterministic mode of AR if available +KBUILD_ARFLAGS := D + +include $(srctree)/scripts/extrawarn.mk +endif # CONFIG_STRICT_CFLAGS + +ifeq ($(TOOLCHAIN),armclang) +KBUILD_CFLAGS += -Wno-typedef-redefinition +endif + +# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments +KBUILD_CPPFLAGS += $(KCPPFLAGS) +KBUILD_AFLAGS += $(KAFLAGS) +KBUILD_CFLAGS += $(KCFLAGS) + +IMAGE-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(core-y))) + +submodgoals = +ifneq ($(SUBMODS),) +include $(srctree)/scripts/submods.mk + +IMAGE-builddirs := $(call get_subdirs,$(IMAGE-dirs),$(SUBMODS)) +ifeq ($(COMPILE_ONLY),1) +submodgoals = $(call get_submodgoals,$@,$(SUBMODS)) +endif +else +IMAGE-builddirs := $(IMAGE-dirs) +endif + +IMAGE-alldirs := $(sort $(IMAGE-dirs) $(patsubst %/,%,$(filter %/, \ + $(init-) $(core-) $(extra-)))) + +init-y := $(patsubst %/, %/built-in$(built_in_suffix), $(init-y)) +core-y := $(patsubst %/, %/built-in$(built_in_suffix), $(core-y)) + +IMAGE_INIT := $(init-y) +IMAGE_MAIN := $(core-y) + +ifeq ($(NO_COMPILE),1) +IMAGE-deps := +else +IMAGE-deps := $(LDS_TARGET) $(IMAGE_INIT) $(IMAGE_MAIN) $(IMAGE_VER) +endif + +BUILD_INFO_FLAGS := \ + -DREVISION_INFO=$(REVISION_INFO) \ + -DFLASH_SIZE=$(FLASH_SIZE) \ + -DOTA_UPGRADE_CRC_LOG_SIZE=$(OTA_UPGRADE_CRC_LOG_SIZE) \ + -DNV_REC_DEV_VER=$(NV_REC_DEV_VER) \ + -I$(srctree)/platform/hal + +BUILD_INFO_FLAGS += $(LDS_SECTION_FLAGS) +BUILD_INFO_FLAGS += -DCHIP=$(CHIP) + +ifneq ($(CHIP_SUBTYPE),) +BUILD_INFO_FLAGS += -DCHIP_SUBTYPE=$(CHIP_SUBTYPE) +endif +ifneq ($(SOFTWARE_VERSION),) +BUILD_INFO_FLAGS += -DSOFTWARE_VERSION=$(SOFTWARE_VERSION) +endif +ifneq ($(OTA_BOOT_SIZE),0) +BUILD_INFO_FLAGS += -DOTA_BOOT_SIZE=$(OTA_BOOT_SIZE) +endif +ifneq ($(OTA_CODE_OFFSET),) +BUILD_INFO_FLAGS += -DOTA_CODE_OFFSET=$(OTA_CODE_OFFSET) +endif +ifneq ($(OTA_REMAP_OFFSET),) +BUILD_INFO_FLAGS += -DOTA_REMAP_OFFSET=$(OTA_REMAP_OFFSET) +endif +ifeq ($(CRC32_OF_IMAGE),1) +BUILD_INFO_FLAGS += -DCRC32_OF_IMAGE +endif +ifeq ($(TRACE_CRLF),1) +BUILD_INFO_FLAGS += -DTRACE_CRLF +endif + +BUILD_INFO_FLAGS += -DKERNEL=$(KERNEL) + +quiet_cmd_image_ver = CC $(IMAGE_VER) + cmd_image_ver = $(CC) $(filter-out -Werror=date-time, \ + $(call flags,KBUILD_CPPFLAGS) \ + $(call flags,KBUILD_CFLAGS) \ + $(call flags,C_ONLY_FLAGS) \ + $(NOSTDINC_FLAGS)) \ + $(BUILD_INFO_FLAGS) \ + -MD -MP -MF $(depfile) -MT $@ \ + -c -o $@ $< + +IMAGE_VER_SRC := $(src)/utils/build_info/build_info.c + +$(IMAGE_VER): $(IMAGE_VER_SRC) $(filter-out $(IMAGE_VER),$(IMAGE-deps)) FORCE + $(call if_changed_dep,image_ver) + +# Linker scripts preprocessor (.lds.S -> .lds) +# --------------------------------------------------------------------------- +quiet_cmd_cpp_lds_S = LDS $@ + cmd_cpp_lds_S = $(CPP) $(call flags,KBUILD_CPPFLAGS) \ + $(call flags,CPPFLAGS_$(LDS_FILE)) \ + -MD -MP -MF $(depfile) -MT $@ \ + $(NOSTDINC_FLAGS) \ + -P -C -E -x c -o $@ $< + +LDS_SRC_STEM := $(src)/scripts/link/$(REAL_LDS_FILE) +LDS_SRC := $(firstword $(wildcard $(LDS_SRC_STEM).S $(LDS_SRC_STEM).sx) $(LDS_SRC_STEM).S) + +$(LDS_TARGET): $(LDS_SRC) FORCE + $(call if_changed_dep,cpp_lds_S) + +PHONY += lds +lds: $(LDS_TARGET) ; + + +# Final link of $(IMAGE_FILE) +# --------------------------------------------------------------------------- +# +# 1) Link the archives twice to solve circular references between two or +# more archives. Otherwise we should use --start-group and --end-group +# options. Normally, an archive is searched only once in the order that +# it is specified on the command line. +# 2) Use --whole-archive option to solve weak symbol overriding issue. +# It tells LD to include every object file in the archive in the link, +# rather than searching the archive for the required object files. +# By default the strong symbols defined in the archive will not override +# any weak symbol, for LD only searches the archive if there is a undefined +# symbol (and a weak symbol is considered as a defined symbol). +# +ifeq ($(TOOLCHAIN),armclang) +#LDFLAGS_IMAGE += --symbols --list_mapping_symbols +ifeq ($(KBUILD_VERBOSE),1) +LDFLAGS_IMAGE += --verbose +endif + + cmd_link-IMAGE_FILE = $(LD) -o $@ \ + $(CFLAGS_IMAGE) \ + -Wl,$(subst $(space),$(comma),$(strip \ + $(LDFLAGS) $(LDFLAGS_IMAGE) \ + --scatter=$(LDS_TARGET) \ + --list=$(IMAGE_MAP) \ + --info=summarysizes --info=summarystack --info=totals --info=unused \ + --map --load_addr_map_info \ + --remove --no_autoat \ + --emit_debug_overlay_relocs --emit_debug_overlay_section \ + --diag_style=gnu --diag_suppress=L6314 --diag_suppress=L6329)) \ + $(IMAGE_ENTRY) $(IMAGE_INIT) $(IMAGE_MAIN) $(IMAGE_VER) \ + $(LIB_LDFLAGS) $(LIB_LDFLAGS) +else + cmd_link-IMAGE_FILE = $(LD) -o $@ \ + $(LD_USE_PATCH_SYMBOL) \ + -T $(LDS_TARGET) \ + $(CFLAGS_IMAGE) \ + -Wl,$(subst $(space),$(comma),$(strip \ + $(LDFLAGS) $(LDFLAGS_IMAGE) \ + -Map=$(IMAGE_MAP) \ + --gc-sections \ + --whole-archive)) \ + $(IMAGE_INIT) $(IMAGE_MAIN) $(IMAGE_VER) \ + -Wl,--no-whole-archive $(LIB_LDFLAGS) $(LIB_LDFLAGS) + +endif +quiet_cmd_link-IMAGE_FILE = LINK $@ + + +# Include targets which we want to +# execute if the rest of the kernel build went well. +$(IMAGE_FILE): $(IMAGE-deps) FORCE +ifneq ($(filter 1,$(COMPILE_ONLY) $(NO_COMPILE)),) + @: +else + +$(call if_changed,link-IMAGE_FILE) +endif + +ifneq ($(IMAGE-deps),) +# The actual objects are generated when descending, +# make sure no implicit rule kicks in +$(sort $(filter %/built-in$(built_in_suffix),$(IMAGE-deps))): $(IMAGE-builddirs) ; +endif + +# Handle descending into subdirectories listed in $(IMAGE-dirs) +# Preset locale variables to speed up the build process. Limit locale +# tweaks to this spot to avoid wrong language settings when running +# make menuconfig etc. +# Error messages still appears in the original language + +PHONY += $(IMAGE-dirs) +$(IMAGE-dirs): scripts + $(Q)$(MAKE) $(build)=$@ $(submodgoals) + +# clean - Delete most, but leave enough to build external modules +# +clean: rm-dirs := $(CLEAN_DIRS) +clean: rm-files := $(CLEAN_FILES) +ifneq ($(SUBMODS),) +clean-dirs := $(addprefix _clean_, $(IMAGE-builddirs)) +else +clean-dirs := $(addprefix _clean_, $(IMAGE-alldirs)) +endif + +PHONY += $(clean-dirs) clean IMAGE-clean +$(clean-dirs): + $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) + +IMAGE-clean: + $(Q)$(call CMDRMFILE,$(IMAGE_FILE) $(IMAGE_MAP) \ + $(IMAGE_BIN) $(STR_BIN) $(IMAGE_HEX) $(IMAGE_LST) \ + $(IMAGE_VER) $(LDS_TARGET)) + +clean: IMAGE-clean + +clean: $(clean-dirs) + $(call cmd,rmdirs) + $(call cmd,rmfiles) +ifeq ($(SUBMODS),) + $(Q)$(call CMDRMFILER,.,*.o *.a *.s *.d) +endif + +PHONY += allclean +ifeq ($(KBUILD_OUTPUT),) +allclean: clean ; +else +ifeq ($(SUBMODS),) +quiet_cmd_clean = RMDIR $(KBUILD_OUTPUT) + cmd_clean = $(call CMDRMDIR,$(KBUILD_OUTPUT)) + +allclean: + +$(call cmd,clean) +else +allclean: clean ; +endif +endif + +quiet_cmd_predefined-macros = GEN $@ + cmd_predefined-macros = $(CPP) $(filter-out -I% -D% -include%,$(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(C_ONLY_FLAGS)) \ + -x c -E -dM -o $@ $(devnull) + +PREDEF_MACRO_FILE := predefined-macros.txt + +$(PREDEF_MACRO_FILE): FORCE + $(call cmd,predefined-macros) + +PHONY += predefined-macros +predefined-macros: $(PREDEF_MACRO_FILE) ; + +# FIXME Should go into a make.lib or something +# =========================================================================== + +quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN $(wildcard $(rm-dirs))) + cmd_rmdirs = $(if $(wildcard $(rm-dirs)),$(call CMDRMDIR,$(rm-dirs))) + +quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files))) + cmd_rmfiles = $(if $(wildcard $(rm-files)),$(call CMDRMFILE,$(rm-files))) + +# Shorthand for $(Q)$(MAKE) -f scripts/clean.mk obj=dir +# Usage: +# $(Q)$(MAKE) $(clean)=dir +clean := -f $(srctree)/scripts/clean.mk obj + +ifneq ($(WIN_PLAT),y) +# Generate tags for editors +# --------------------------------------------------------------------------- +quiet_cmd_tags = GEN $@ + cmd_tags = $(CONFIG_SHELL) $(srctree)/tools/tags.sh $@ + +tags TAGS cscope gtags: FORCE + $(call cmd,tags) +endif + +HELP_TARGET := 2 + +endif # ifeq ($(skip-makefile),) +endif # ifneq ($(HELP_TARGET),1) + +# Help target +ifneq ($(HELP_TARGET),) +ifeq ($(HELP_TARGET),1) +include scripts/include.mk +endif + +help: FORCE + $(call echo-help,Mandatory options:) + $(call echo-help, T= - Select a target board configuration in config/) + $(call echo-help,) + $(call echo-help,Cleaning targets:) + $(call echo-help, clean - Remove most generated files) + $(call echo-help, allclean - Remove all generated files and the output directory if possible) + $(call echo-help,) + $(call echo-help,Generic targets:) + $(call echo-help, all - Build all targets marked with [*]) + $(call echo-help, lst - Build the mixed source/assembly file of the final image) + $(call echo-help, lds - Build the linker script file) +ifeq ($(HELP_TARGET),2) + $(call echo-help,* $(IMAGE_FILE)) + $(call echo-help, - Build the final image) +endif + $(call echo-help, dir/ - Build all files in dir and below) + $(call echo-help, dir/file.[oisS] - Build specified target only) + $(call echo-help, dir/file.lst - Build specified mixed source/assembly target only) + $(call echo-help, (requires a recent binutils and recent build (System.map))) + $(call echo-help,) + $(call echo-help, make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build) + $(call echo-help, make V=2 [targets] 2 => give reason for rebuild of target) + $(call echo-help, make O=dir [targets] Locate all output files in "dir", including .config) + $(call echo-help, make W=n [targets] Enable extra gcc checks, n=1,2,3 where) + $(call echo-help, 1: warnings which may be relevant and do not occur too often) + $(call echo-help, 2: warnings which occur quite often but may still be relevant) + $(call echo-help, 3: more obscure warnings, can most likely be ignored) + $(call echo-help, Multiple levels can be combined with W=12 or W=123) + $(call echo-help,) + $(call echo-help,Execute "make" or "make all" to build all targets marked with [*]) + +endif # ifneq ($(HELP_TARGET),) + +# Cancel implicit rules on top Makefile +ifeq ($(KBUILD_SRC),) +$(CURDIR)/Makefile Makefile: ; +else +$(KBUILD_SRC)/Makefile Makefile: ; +endif + +PHONY += FORCE +FORCE: ; + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable so we can use it in if_changed and friends. +.PHONY: $(PHONY) diff --git a/apps/Makefile b/apps/Makefile new file mode 100644 index 0000000..c383200 --- /dev/null +++ b/apps/Makefile @@ -0,0 +1,52 @@ +obj-y := audioplayers/ common/ main/ key/ pwl/ battery/ factory/ + +ifeq ($(APP_TEST_AUDIO),1) +obj-y += apptester/ +endif + +ifeq ($(BTUSB_AUDIO_MODE),1) +obj-y += usbaudio/ +endif +ifeq ($(BT_USB_AUDIO_DUAL_MODE),1) +obj-y += btusbaudio/ +obj-y += usbaudio/ +endif + +ifeq ($(APP_TEST_SDMMC),1) +obj-y += sdmmc/ +endif + +ifeq ($(ANC_APP),1) +obj-y += anc/ +endif + +ifeq ($(VOICE_DETECTOR_EN),1) +obj-y += voice_detector/ +endif + +ifeq ($(PC_CMD_UART),1) +obj-y += cmd/ +endif + +subdir-ccflags-y += -Iapps/apptester \ + -Iapps/audioplayers \ + -Iapps/common \ + -Iapps/sdmmc \ + -Iapps/main \ + -Iapps/cmd \ + -Iapps/key \ + -Iapps/pwl \ + -Iapps/battery \ + -Iservices/voicepath \ + -Iservices/ble_app/app_datapath \ + -Iutils/list \ + -Iutils/heap \ + -Iservices/multimedia/audio/process/filters/include +ifeq ($(BT_USB_AUDIO_DUAL_MODE),1) +subdir-ccflags-y += -Iapps/btusbaudio +endif + +ifeq ($(A2DP_LDAC_ON),1) +subdir-ccflags-y += -Ithirdparty/audio_codec_lib/ldac/inc +endif + diff --git a/apps/anc/Makefile b/apps/anc/Makefile new file mode 100644 index 0000000..39072db --- /dev/null +++ b/apps/anc/Makefile @@ -0,0 +1,105 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.cpp)) + +ifeq ($(ANC_APP),1) +CFLAGS_app_anc.o += -DANC_APP +endif + +ifeq ($(ANC_FF_ENABLED),1) +CFLAGS_app_anc.o += -DANC_FF_ENABLED +endif + +ifeq ($(ANC_FB_ENABLED),1) +CFLAGS_app_anc.o += -DANC_FB_ENABLED +endif + +ifeq ($(ANC_WNR_ENABLED),1) +CFLAGS_app_anc.o += -DANC_WNR_ENABLED +endif + + + +ifeq ($(ANC_ASSIST_ENABLED),1) +CFLAGS_app_anc.o += -DANC_ASSIST_ENABLED + +ifeq ($(ANC_ASSIST_WNR_ENABLED),1) +CFLAGS_anc_assist.o += -DANC_ASSIST_WNR_ENABLED +endif +ifeq ($(ANC_ASSIST_PILOT_ENABLED),1) +CFLAGS_anc_assist.o += -DANC_ASSIST_PILOT_ENABLED +endif +ifeq ($(ANC_ASSIST_NOISE_ADAPTIVE_ENABLED),1) +CFLAGS_anc_assist.o += -DANC_ASSIST_NOISE_ADAPTIVE_ENABLED +endif +ifeq ($(ANC_ASSIST_HESS_ENABLED),1) +CFLAGS_anc_assist.o += -DANC_ASSIST_HESS_ENABLED +endif +ifeq ($(ANC_ASSIST_PNC_ENABLED),1) +CFLAGS_anc_assist.o += -DANC_ASSIST_PNC_ENABLED +endif +ifeq ($(ANC_ASSIST_DEHOWLING_ENABLED),1) +CFLAGS_anc_assist.o += -DANC_ASSIST_DEHOWLING_ENABLED +endif + +else +obj_c := $(filter-out src/anc_assist.c ,$(obj_c)) +endif + + +ifeq ($(AUDIO_RESAMPLE),1) +CFLAGS_app_anc.o += -D__AUDIO_RESAMPLE__ +endif +ifeq ($(SW_PLAYBACK_RESAMPLE),1) +CFLAGS_app_anc.o += -DSW_PLAYBACK_RESAMPLE +endif +ifeq ($(SW_CAPTURE_RESAMPLE),1) +CFLAGS_app_anc.o += -DSW_CAPTURE_RESAMPLE +endif +ifeq ($(AUDIO_SECTION_SUPPT),1) +CFLAGS_app_anc.o += -D__AUDIO_SECTION_SUPPT__ +endif + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +subdir-ccflags-y += \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iservices/multimedia/audio/process/resample/include \ + -Iservices/multimedia/audio/process/anc/include \ + -Iservices/multimedia/speech/inc \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iapps/anc/inc \ + -Iapps/key \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/factory \ + -Iservices/ble_app \ + -Iservices/bt_app \ + -Iservices/anc/inc \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/include \ + -Iutils/hwtimer_list \ + -Iservices/ibrt_core/inc \ + -Iservices/tota \ + $(BT_IF_INCLUDES) \ + -Iservices/app_ibrt/inc \ + -Iservices/ble_stack/common/api \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ibrt_ui/inc \ + -Iservices/audio_dump/include diff --git a/apps/anc/inc/anc_assist.h b/apps/anc/inc/anc_assist.h new file mode 100644 index 0000000..474903e --- /dev/null +++ b/apps/anc/inc/anc_assist.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +#ifndef __ANC_ASSIT_H__ +#define __ANC_ASSIT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +//#define AF_ANC_DUMP_DATA + + +#if defined(_24BITS_ENABLE) +#define _SAMPLE_BITS (24) +typedef int ASSIST_PCM_T; +#else +#define _SAMPLE_BITS (16) +typedef short ASSIST_PCM_T; +#endif + + +#define ANC_ASSIST_FF1_MIC (1<<2) +#define ANC_ASSIST_FF2_MIC (1<<1) +#define ANC_ASSIST_FB_MIC (1<<0) + + + + + +typedef enum{ + ANC_ASSIST_STANDALONE = 0, + ANC_ASSIST_MUSIC, + ANC_ASSIST_PHONE_8K, + ANC_ASSIST_PHONE_16K, + + ANC_ASSIST_MODE_QTY + +}ANC_ASSIST_MODE_T; + + +void anc_assist_open(ANC_ASSIST_MODE_T mode); + +void anc_assist_process(uint8_t * buf, int len); +void anc_assist_close(); + + + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/apps/anc/inc/anc_wnr.h b/apps/anc/inc/anc_wnr.h new file mode 100644 index 0000000..15d6d57 --- /dev/null +++ b/apps/anc/inc/anc_wnr.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ANC_WNR_H__ +#define __ANC_WNR_H__ + +// #include "plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + ANC_WNR_OPEN_MODE_STANDALONE = 0, + ANC_WNR_OPEN_MODE_CONFIGURE, + + ANC_WNR_OPEN_MODE_QTY +} anc_wnr_open_mode_t; + +void anc_release_gain(void); + +typedef enum +{ + APP_WNR_NOTIFY_DETECT_RESULT, + APP_WNR_REQUEST_DETECT_RESULT, + APP_WNR_RESPONSE_DETECT_RESULT, + APP_WNR_PROCESS_DETECT_RESULT, + APP_WNR_SET_TRIGGER, + APP_WNR_EXCUTE_TRIGGER, + APP_WNR_SHARE_MODULE_INFO, +} anc_wnr_sync_ctrl_internal_event_e; + +int32_t anc_wnr_ctrl(int32_t sample_rate, int32_t frame_len); +int32_t anc_wnr_open(anc_wnr_open_mode_t mode); +int32_t anc_wnr_close(void); +int32_t anc_wnr_process(void *pcm_buf, uint32_t pcm_len); +void app_wnr_sync_state(void); +void app_wnr_cmd_receive_process(uint8_t *p_buff, uint16_t length); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/apps/anc/inc/app_anc.h b/apps/anc/inc/app_anc.h new file mode 100644 index 0000000..19f10a8 --- /dev/null +++ b/apps/anc/inc/app_anc.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_ANC_H__ +#define __APP_ANC_H__ + +#include "hal_aud.h" +#include "app_key.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void app_anc_set_playback_samplerate(enum AUD_SAMPRATE_T sample_rate); +void app_anc_init(enum AUD_IO_PATH_T input_path, enum AUD_SAMPRATE_T playback_rate, enum AUD_SAMPRATE_T capture_rate); +void app_anc_close(void); +void app_anc_enable(void); +void app_anc_disable(void); +bool anc_enabled(void); +void test_anc(void); +void app_anc_resample(uint32_t res_ratio, uint32_t *in, uint32_t *out, uint32_t samples); +#ifdef __BT_ANC_KEY__ +void app_anc_key(APP_KEY_STATUS *status, void *param); +#endif +int app_anc_open_module(void); +int app_anc_close_module(void); +enum AUD_SAMPRATE_T app_anc_get_play_rate(void); +bool app_anc_work_status(void); +void app_anc_send_howl_evt(uint32_t howl); +uint32_t app_anc_get_anc_status(void); +bool app_pwr_key_monitor_get_val(void); +bool app_anc_switch_get_val(void); +void app_anc_ios_init(void); +void app_anc_set_init_done(void); +bool app_anc_set_reboot(void); +void app_anc_status_post(uint8_t status); +bool app_anc_is_on(void); +uint32_t app_anc_get_sample_rate(void); +void app_anc_set_coef_idx(uint8_t idx); +uint8_t app_anc_get_coef_idx(void); + +#if defined(IBRT) +void app_anc_cmd_receive_process(uint8_t *buf, uint16_t len); +void app_anc_set_peer_coef_idx(uint8_t idx); +uint8_t app_anc_get_peer_coef_idx(void); +void app_anc_set_status_sync_flag(bool status); +bool app_anc_get_status_sync_flag(void); +#endif + +#ifndef __BT_ANC_KEY__ +int app_anc_start(void); +int app_anc_switch_coef(uint8_t index); +int app_anc_stop(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/apps/anc/inc/peak_detector.h b/apps/anc/inc/peak_detector.h new file mode 100644 index 0000000..0241ca3 --- /dev/null +++ b/apps/anc/inc/peak_detector.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __PEAK_DETECTOR_H__ +#define __PEAK_DETECTOR_H__ + +#include "plat_types.h" +#include "hal_aud.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + enum AUD_SAMPRATE_T fs; + enum AUD_BITS_T bits; + float factor_up; + float factor_down; + float reduce_dB; +} PEAK_DETECTOR_CFG_T; + +void peak_detector_init(void); +void peak_detector_setup(PEAK_DETECTOR_CFG_T *cfg); +void peak_detector_run(uint8_t *buf, uint32_t len, float vol_multiple); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/apps/anc/src/anc_assist.c b/apps/anc/src/anc_assist.c new file mode 100644 index 0000000..5e63926 --- /dev/null +++ b/apps/anc/src/anc_assist.c @@ -0,0 +1,445 @@ + + + +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "anc_assist.h" +#include "hal_trace.h" +#include "arm_math.h" +#include "audio_dump.h" +#include "speech_cfg.h" +#include "anc_process.h" +#include "audioflinger.h" +#include "anc_assist_algo.h" +#include "hal_codec.h" +#include "audioflinger.h" +#include "hal_timer.h" +#include "hal_aud.h" +#include +#include +#include +#include "hal_aud.h" +#include "anc_process.h" +#include "anc_assist_algo.h" +#include "speech_memory.h" +#include "speech_ssat.h" + + +#if defined(ANC_ASSIST_NOISE_ADAPTIVE_ENABLED) +#include "main_classify.h" +#endif + + +static void _close_mic_anc_assist(); +static void _open_mic_anc_assist(); +#define _SAMPLE_RATE (16000) + +#if defined(ANC_ASSIST_NOISE_ADAPTIVE_ENABLED) +#define _FRAME_LEN (128) +#else +#define _FRAME_LEN (160) +#endif + +#define _CHANNEL_NUM_MAX (3) +#define SAMPLE_BYTES (sizeof(ASSIST_PCM_T)) +#define AF_STREAM_BUFF_SIZE (_FRAME_LEN * SAMPLE_BYTES * _CHANNEL_NUM_MAX * 2) +#define ANC_ADPT_STREAM_ID AUD_STREAM_ID_3 + +#define _FRAME_LEN_MAX (160) +#define _SAMPLE_BITS_MAX (32) + +static uint8_t __attribute__((aligned(4))) af_stream_buff[AF_STREAM_BUFF_SIZE]; +static ASSIST_PCM_T af_stream_mic1[_FRAME_LEN_MAX * (_SAMPLE_BITS_MAX / 8)]; +static ASSIST_PCM_T af_stream_mic2[_FRAME_LEN_MAX * (_SAMPLE_BITS_MAX / 8)]; +static ASSIST_PCM_T af_stream_mic3[_FRAME_LEN_MAX * (_SAMPLE_BITS_MAX / 8)]; +int MIC_NUM = 0; +int MIC_MAP = 0; + +#if defined(ANC_ASSIST_PILOT_ENABLED) +#define _PLAY_SAMPLE_RATE (8000) +#define _PLAY_FRAME_LEN (80) +#define AF_PLAY_STREAM_BUFF_SIZE (_PLAY_FRAME_LEN * SAMPLE_BYTES * 1 * 2) +static uint8_t __attribute__((aligned(4))) af_play_stream_buff[AF_PLAY_STREAM_BUFF_SIZE]; +#endif + +#if defined(ANC_ASSIST_NOISE_ADAPTIVE_ENABLED) +ClassifyState * NoiseClassify_st = NULL; +#endif + +#if defined(ANC_ASSIST_PILOT_ENABLED) || defined(ANC_ASSIST_HESS_ENABLED) || defined(ANC_ASSIST_PNC_ENABLED) || defined(ANC_ASSIST_DEHOWLING_ENABLED) || defined(ANC_ASSIST_WNR_ENABLED) || defined(ANC_ASSIST_NOISE_ADAPTIVE_ENABLED) + +extern const struct_anc_cfg * anc_coef_list_48k[1]; +void anc_assist_change_curve(int curve_id){ + TRACE(2,"[%s] change anc curve %d",__func__,curve_id); + anc_set_cfg(anc_coef_list_48k[0],ANC_FEEDFORWARD,ANC_GAIN_NO_DELAY); + anc_set_cfg(anc_coef_list_48k[0],ANC_FEEDBACK,ANC_GAIN_NO_DELAY); +} +bool audio_engine_tt_is_on(){ + return 1; +} + + + +#define _tgt_ff_gain (512) +void anc_assist_set_anc_gain(float gain_ch_l, float gain_ch_r,enum ANC_TYPE_T anc_type){ + + TRACE(2,"[%s] set anc gain %d",__func__,(int)(100*gain_ch_l)); + uint32_t tgt_ff_gain_l,tgt_ff_gain_r; + tgt_ff_gain_l = (uint32_t)(_tgt_ff_gain*gain_ch_l); + tgt_ff_gain_r = (uint32_t)(_tgt_ff_gain*gain_ch_r); + anc_set_gain(tgt_ff_gain_l,tgt_ff_gain_r,anc_type); +} +#endif + +#if defined(ANC_ASSIST_PILOT_ENABLED) +static LeakageDetectionState * pilot_st = NULL; + +#endif + + +#if defined(ANC_ASSIST_HESS_ENABLED) || defined(ANC_ASSIST_PNC_ENABLED) || defined(ANC_ASSIST_DEHOWLING_ENABLED) || defined(ANC_ASSIST_WNR_ENABLED) +static ANCAssistMultiState * anc_assist_multi_st = NULL; +#endif + + + +ANC_ASSIST_MODE_T g_anc_assist_mode = ANC_ASSIST_MODE_QTY; +void anc_assist_open(ANC_ASSIST_MODE_T mode){ + g_anc_assist_mode = mode; + + + //normal init +#if defined(ANC_ASSIST_PILOT_ENABLED) + pilot_st = LeakageDetection_create(160,0); +#endif + +#if defined(ANC_ASSIST_HESS_ENABLED) || defined(ANC_ASSIST_PNC_ENABLED) || defined(ANC_ASSIST_DEHOWLING_ENABLED) || defined(ANC_ASSIST_WNR_ENABLED) + anc_assist_multi_st = ANCAssistMulti_create(_SAMPLE_RATE,_FRAME_LEN,128); +#endif + +#if defined(ANC_ASSIST_NOISE_ADAPTIVE_ENABLED) + NoiseClassify_st = classify_create(_SAMPLE_RATE, _FRAME_LEN); +#endif + + // audio_dump_init(160,sizeof(short),3); + + + if( mode == ANC_ASSIST_MODE_QTY){ + return; + } + else{ + if(mode == ANC_ASSIST_STANDALONE || mode == ANC_ASSIST_MUSIC ){ + _open_mic_anc_assist(); + } + if(mode == ANC_ASSIST_PHONE_8K){ + // normal init 8k + } + else if(mode == ANC_ASSIST_PHONE_16K){ + // normal init 16k + } + + } + + + +} + + + + +void anc_assist_close(){ + +#if defined(ANC_ASSIST_PILOT_ENABLED) + LeakageDetection_destroy(pilot_st); +#endif +#if defined(ANC_ASSIST_HESS_ENABLED) || defined(ANC_ASSIST_PNC_ENABLED) || defined(ANC_ASSIST_DEHOWLING_ENABLED) || defined(ANC_ASSIST_WNR_ENABLED) + ANCAssistMulti_destroy(anc_assist_multi_st); +#endif + +#if defined(ANC_ASSIST_NOISE_ADAPTIVE_ENABLED) + classify_destroy(NoiseClassify_st); +#endif + + // ext_heap_deinit(); + + if( g_anc_assist_mode == ANC_ASSIST_MODE_QTY){ + return; + } + else{ + if(g_anc_assist_mode == ANC_ASSIST_STANDALONE || g_anc_assist_mode == ANC_ASSIST_MUSIC ){ + _close_mic_anc_assist(); + } + if(g_anc_assist_mode == ANC_ASSIST_PHONE_8K){ + // normal init 8k + } + else if(g_anc_assist_mode == ANC_ASSIST_PHONE_16K){ + // normal init 16k + } + + } + +} + + +extern ASSIST_PCM_T ref_buf_data[80]; +void anc_assist_process(uint8_t * buf, int len){ + + + int32_t frame_len = len / SAMPLE_BYTES / MIC_NUM; + ASSERT(frame_len == _FRAME_LEN, "[%s] frame len(%d) is invalid.", __func__, frame_len); + ASSIST_PCM_T *pcm_buf = (ASSIST_PCM_T *)buf; + + ASSIST_PCM_T *mic1 = (ASSIST_PCM_T *)af_stream_mic1; + ASSIST_PCM_T *mic2 = (ASSIST_PCM_T *)af_stream_mic2; + ASSIST_PCM_T *mic3 = (ASSIST_PCM_T *)af_stream_mic3; + + for (int32_t i=0; itgt_ff_gain_l){ + pre_ff_gain_l = pre_ff_gain_l - 1; + ff_gain_l = pre_ff_gain_l; + } + + + if(pre_ff_gain_rtgt_ff_gain_r){ + pre_ff_gain_r = pre_ff_gain_r - 1; + ff_gain_r = pre_ff_gain_r; + } + + anc_set_gain(ff_gain_l, ff_gain_r, ANC_FEEDFORWARD); + TRACE(3,"[%s] ff_gain_l = %d, ff_gain_r = %d", __func__, ff_gain_l, ff_gain_r); + + struct anc_tuning_ctrl *c = (struct anc_tuning_ctrl *)param; + hwtimer_start(c->timer_ff_gain_id, US_TO_TICKS(ANC_TIMER_PERIOD_GAIN)); + ff_smoothing_flag = 1; + } else { + anc_set_gain(tgt_ff_gain_l, tgt_ff_gain_r, ANC_FEEDFORWARD); + ff_smoothing_flag = 0; + } + +} +#endif + +static void _set_anc_ff_gain(bool update_anc_gain, float gain_coef, enum ANC_TYPE_T type) +{ + +#ifdef HW_SUPPORT_SMOOOTHING_GAIN + if(update_anc_gain){ + anc_get_gain(&pre_ff_gain_l, &pre_ff_gain_r, ANC_FEEDFORWARD); + anc_ff_gain_l = pre_ff_gain_l; + anc_ff_gain_r = pre_ff_gain_r; + TRACE(3, "[%s] Update anc_gain_l = %d, anc_gain_r = %d.", __func__, anc_ff_gain_l, anc_ff_gain_r); + } + tgt_ff_gain_l = (int32_t)(anc_ff_gain_l * gain_coef); + tgt_ff_gain_r = (int32_t)(anc_ff_gain_r * gain_coef); + TRACE(3, "[%s] tgt_ff_gain_l = %d, tgt_ff_gain_r = %d.", __func__, tgt_ff_gain_l, tgt_ff_gain_r); + anc_set_gain(tgt_ff_gain_l, tgt_ff_gain_r, ANC_FEEDFORWARD); +#else + struct anc_tuning_ctrl *c = &anc_tctrl; + //uint32_t cur_time = TICKS_TO_MS(hal_sys_timer_get()); + + //reset timer + if (c->timer_ff_gain_run) { + hwtimer_stop(c->timer_ff_gain_id); + } + anc_get_gain(&pre_ff_gain_l, &pre_ff_gain_r, ANC_FEEDFORWARD); + TRACE(3,"[%s] pre_ff_gain_l = %d, pre_ff_gain_r = %d.", __func__, pre_ff_gain_l, pre_ff_gain_r); + if(update_anc_gain && !ff_smoothing_flag){ + anc_ff_gain_l = pre_ff_gain_l; + anc_ff_gain_r = pre_ff_gain_r; + TRACE(3,"[%s] Update anc_gain_l = %d, anc_gain_r = %d.", __func__, anc_ff_gain_l, anc_ff_gain_r); + } + tgt_ff_gain_l = (int32_t)(anc_ff_gain_l * gain_coef); + tgt_ff_gain_r = (int32_t)(anc_ff_gain_r * gain_coef); + delta_ff_gain_l = abs(tgt_ff_gain_l-pre_ff_gain_l); + delta_ff_gain_r = abs(tgt_ff_gain_r-pre_ff_gain_r); + TRACE(3,"[%s] tgt_ff_gain_l = %d, tgt_ff_gain_r = %d.", __func__, tgt_ff_gain_l, tgt_ff_gain_r); + + timer_cnt=0; + + //timer restart + hwtimer_start(c->timer_ff_gain_id, MS_TO_TICKS(ANC_TIMER_PERIOD_GAIN)); + c->timer_ff_gain_run = 1; + //set gain directly + //anc_set_gain(gain_ch_l, gain_ch_r, type); + + //AUD_TRACE(TRACE_MASK_INFO, "set anc gain :[%d], gain_ch_l=%d, gian_ch_r=%d, type=%d", + //cur_time, gain_ch_l, gain_ch_r, (int)type); +#endif +} + +void anc_release_gain(void) +{ + TRACE(1,"[%s] ...Release FF gain", __func__); + + _set_anc_ff_gain(false, 1, ANC_FEEDFORWARD); +} + +int32_t anc_wnr_ctrl(int32_t sample_rate, int32_t frame_len) +{ + TRACE(3,"[%s] sample_rate = %d, frame_len = %d", __func__, sample_rate, frame_len); + + g_sample_rate = sample_rate; + g_frame_len = frame_len; + + if (g_sample_rate == 16000) { + g_frame_len >>= 1; + } + + return 0; +} + +static void app_wnr_reset_state_queue(void) +{ + g_anc_wnr_state_queue.index_for_normal = 0; + g_anc_wnr_state_queue.index_for_sco = 0; + g_anc_wnr_state_queue.number_for_normal = 0; + g_anc_wnr_state_queue.number_for_sco = 0; + memset(g_anc_wnr_state_queue.buf_for_normal, 0, WNR_SYNC_COUNTER_THRESHOLD_FOR_NORMAL); + memset(g_anc_wnr_state_queue.buf_for_sco, 0, WNR_SYNC_COUNTER_THRESHOLD_FOR_SCO); +} +static void app_wnr_push_state_to_queue(uint8_t open_mode, uint8_t arg0) +{ + if(open_mode == ANC_WNR_OPEN_MODE_STANDALONE)//normal mode... + { + g_anc_wnr_state_queue.buf_for_normal[g_anc_wnr_state_queue.index_for_normal] = arg0; + + if(++g_anc_wnr_state_queue.index_for_normal >= WNR_SYNC_COUNTER_THRESHOLD_FOR_NORMAL) + { + g_anc_wnr_state_queue.index_for_normal = 0; + } + + if(g_anc_wnr_state_queue.number_for_normal < WNR_SYNC_COUNTER_THRESHOLD_FOR_NORMAL) + { + g_anc_wnr_state_queue.number_for_normal++; + } + } + else//sco mode... + { + g_anc_wnr_state_queue.buf_for_sco[g_anc_wnr_state_queue.index_for_sco] = arg0; + + if(++g_anc_wnr_state_queue.index_for_sco >= WNR_SYNC_COUNTER_THRESHOLD_FOR_SCO) + { + g_anc_wnr_state_queue.index_for_sco = 0; + } + + if(g_anc_wnr_state_queue.number_for_sco < WNR_SYNC_COUNTER_THRESHOLD_FOR_SCO) + { + g_anc_wnr_state_queue.number_for_sco++; + } + } +} +static uint8_t app_wnr_get_state_from_queue(uint8_t open_mode) +{ + uint8_t counter0 = 0; + uint8_t counter1 = 0; + uint8_t counter2 = 0; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(2,"[%s] open_mode:%d", __func__, open_mode); + TRACE(2,"[%s] index_for_normal:%d", __func__, g_anc_wnr_state_queue.index_for_normal); + TRACE(2,"[%s] index_for_sco:%d", __func__, g_anc_wnr_state_queue.index_for_sco); + TRACE(2,"[%s] number_for_normal:%d", __func__, g_anc_wnr_state_queue.number_for_normal); + TRACE(2,"[%s] number_for_sco:%d", __func__, g_anc_wnr_state_queue.number_for_sco); + TRACE(1,"[%s] buf_for_normal:", __func__); + DUMP8("%d ", g_anc_wnr_state_queue.buf_for_normal, g_anc_wnr_state_queue.number_for_normal); + TRACE(1,"[%s] buf_for_sco:", __func__); + DUMP8("%d ", g_anc_wnr_state_queue.buf_for_sco, g_anc_wnr_state_queue.number_for_sco); +#endif + + if(open_mode == ANC_WNR_OPEN_MODE_STANDALONE)//normal mode... + { + for(uint8_t i = 0; i= counter1) + { + if(counter0 >= counter2) + { + return 0; + } + else + { + return 2; + } + } + else + { + if(counter1 >= counter2) + { + return 1; + } + else + { + return 2; + } + } +} +static void app_wnr_trigger_internal_event(uint32_t evt, uint32_t arg0, uint32_t arg1, uint32_t arg2) +{ + APP_MESSAGE_BLOCK msg; +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(5,"[%s] evt:%d arg0:%d arg1:%d arg2:%d", __func__, evt, arg0, arg1, arg2); +#endif + msg.mod_id = APP_MODUAL_WNR; + msg.msg_body.message_id = evt; + msg.msg_body.message_Param0 = arg0; + msg.msg_body.message_Param1 = arg1; + msg.msg_body.message_Param2 = arg2; + app_mailbox_put(&msg); +} +static void app_wnr_share_module_info(void) +{ + uint8_t buf[3] = {0}; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(2,"[%s] local_module_onoff:%d", __func__, g_local_Wind_module_onoff); +#endif + + buf[0] = IBRT_ACTION_SYNC_WNR; + buf[1] = (uint8_t)APP_WNR_SHARE_MODULE_INFO; + buf[2] = (uint8_t)g_local_Wind_module_onoff; + + app_ibrt_ui_send_user_action(buf, 3); +} +void app_wnr_sync_state(void) +{ +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] enter...", __func__); +#endif + + wnr_sync_counter_for_sco = 0; + wnr_sync_counter_for_normal = 0; + g_wnr_notify_flag = false; + g_wnr_request_flag = false; + g_peer_Wind_module_onoff = false; + g_peer_Windstate = 0; + + if(g_local_Wind_module_onoff == true) + { + g_wnr_sync_flag = true; + } +} + +#if (WNR_SYNC_SET_ANC_FF_GAIN_TWOSTAGE == 1) +static void app_wnr_twostage_handler(void const *param) +{ + float gain_coef = 0.0; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] enter...", __func__); +#endif + + if((Twostage==1)&&(FFstate==7)) + { + FFstate = 1;//25%->50% + Twostage = 0; + gain_coef = _SMALL_WIND_FF_GAIN_COEF; + _set_anc_ff_gain(false, gain_coef, ANC_FEEDFORWARD); + + TRACE(1,"[%s] Enable 0.5 FF ANC.", __func__); + } + else if((Twostage==1)&&(FFstate==6)) + { + FFstate = 0;//75%->100% + Twostage = 0; + gain_coef = _NO_WIND_FF_GAIN_COEF; + _set_anc_ff_gain(false, gain_coef, ANC_FEEDFORWARD); + TRACE(1,"[%s] Enable FF ANC.", __func__); + } +} +#endif + +static void app_wnr_sync_timer_handler(void const *param) +{ + uint8_t temp = *((uint8_t *)param); +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(2,"[%s] arg0:%d", __func__, temp); +#endif + + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_EXCUTE_TRIGGER, (uint32_t)temp, 0, 0); +} +static void app_wnr_notify_detect_result(void) +{ + uint8_t buf[3] = {0}; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(2,"[%s] local_Windstate:%d", __func__, g_local_Windstate); +#endif + g_wnr_sync_flag = false; + g_wnr_notify_flag = true; + + buf[0] = IBRT_ACTION_SYNC_WNR; + buf[1] = (uint8_t)APP_WNR_NOTIFY_DETECT_RESULT; + buf[2] = g_local_Windstate; + + app_ibrt_ui_send_user_action(buf, 3); +} +static void app_wnr_request_detect_result(void) +{ + uint8_t buf[3] = {0}; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(2,"[%s] local_Windstate:%d", __func__, g_local_Windstate); +#endif + g_wnr_sync_flag = false; + g_wnr_request_flag = true; + + buf[0] = IBRT_ACTION_SYNC_WNR; + buf[1] = (uint8_t)APP_WNR_REQUEST_DETECT_RESULT; + buf[2] = g_local_Windstate; + + app_ibrt_ui_send_user_action(buf, 3); +} +static void app_wnr_response_detect_result(uint32_t arg0) +{ + uint8_t buf[3] = {0}; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] enter...", __func__); +#endif + + if(g_wnr_notify_flag == true) + { + g_wnr_notify_flag = false; + return; + } + + g_wnr_sync_flag = false; + g_local_Windstate = app_wnr_get_state_from_queue(g_wnr_open_mode); + g_peer_Windstate = (uint8_t)arg0; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(3,"[%s] local_Windstate:%d peer_Windstate:%d", __func__, g_local_Windstate, g_peer_Windstate); +#endif + + buf[0] = IBRT_ACTION_SYNC_WNR; + buf[1] = (uint8_t)APP_WNR_RESPONSE_DETECT_RESULT; + buf[2] = g_local_Windstate; + + app_ibrt_ui_send_user_action(buf, 3); +} +static void app_wnr_process_detect_result(uint32_t arg0) +{ + if(g_wnr_request_flag == false) + { + g_local_Windstate = app_wnr_get_state_from_queue(g_wnr_open_mode); + } + + g_wnr_sync_flag = false; + g_wnr_request_flag = false; + g_peer_Windstate = (uint8_t)arg0; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(3,"[%s] local_Windstate:%d peer_wnr_state:%d", __func__, g_local_Windstate, arg0); +#endif + + if(g_local_Windstate >= g_peer_Windstate) + { + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_SET_TRIGGER, (uint32_t)g_local_Windstate, 0, 0); + } + else + { + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_SET_TRIGGER, (uint32_t)g_peer_Windstate, 0, 0); + } +} +static void app_wnr_set_trigger(uint32_t arg0, uint32_t arg1) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + uint32_t current_ticks = 0; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(2,"[%s] set_Windstate:%d", __func__, arg0); +#endif + + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_MASTER) && (g_peer_Wind_module_onoff == true)) + { + uint8_t buf[7] = {0}; + current_ticks = bt_syn_get_curr_ticks(p_ibrt_ctrl->tws_conhandle); + uint32_t tg_ticks = current_ticks + MS_TO_TICKS(WNR_SYNC_TRIGGER_DELAY); + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(3,"[%s] current_ticks:%d tg_ticks:%d", __func__, current_ticks, tg_ticks); +#endif + + buf[0] = IBRT_ACTION_SYNC_WNR; + buf[1] = (uint8_t)APP_WNR_SET_TRIGGER; + buf[2] = (uint8_t)arg0; + buf[3] = (uint8_t)((tg_ticks&0xff000000)>>24); + buf[4] = (uint8_t)((tg_ticks&0x00ff0000)>>16); + buf[5] = (uint8_t)((tg_ticks&0x0000ff00)>>8); + buf[6] = (uint8_t)(tg_ticks&0x000000ff); + + app_ibrt_ui_send_user_action(buf, 7); + + if((app_wnr_sync_timer != NULL) && (tg_ticks != current_ticks)) + { + g_set_Windstate = (uint8_t)arg0; + osTimerStop(app_wnr_sync_timer); + osTimerStart(app_wnr_sync_timer, WNR_SYNC_TRIGGER_DELAY); + } + else + { + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_EXCUTE_TRIGGER, arg0, 0, 0); + } + return; + } + + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_SLAVE) && (g_peer_Wind_module_onoff == true)) + { + g_wnr_notify_flag = false; + current_ticks = bt_syn_get_curr_ticks(p_ibrt_ctrl->tws_conhandle); + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(3,"[%s] current_ticks:%d tg_ticks:%d", __func__, current_ticks, arg1); +#endif + + if(arg1 > current_ticks) + { + uint32_t diff_ticks = arg1 - current_ticks; + + g_set_Windstate = (uint8_t)arg0; + if(app_wnr_sync_timer != NULL) + { + osTimerStop(app_wnr_sync_timer); + osTimerStart(app_wnr_sync_timer, TICKS_TO_MS(diff_ticks)); + } + } + else + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] tg_ticks < current_ticks...", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_EXCUTE_TRIGGER, arg0, 0, 0); + } + return; + } + + if((app_tws_ibrt_tws_link_connected() == false) || (g_peer_Wind_module_onoff == false)) + { + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_EXCUTE_TRIGGER, arg0, 0, 0); + return; + } +} + +static void app_wnr_excute_trigger(uint32_t arg0) +{ + uint8_t t_Windstate = (uint8_t)arg0; + float gain_coef = 0.0; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(3,"[%s] last_Windstate:%d set_Windstate:%d", __func__, g_wind_st, t_Windstate); +#endif + + if((t_Windstate != g_wind_st)&&(app_anc_work_status())) + { + if(g_wind_st > t_Windstate) + { +#if (WNR_SYNC_SET_ANC_FF_GAIN_TWOSTAGE == 1) + Twostage = 1; +#endif + if(t_Windstate==1){ +#if (WNR_SYNC_SET_ANC_FF_GAIN_TWOSTAGE == 1) + FFstate = 7;//25% + gain_coef = _STRONG2SMALL_WIND_FF_MID_GAIN_COEF; + _set_anc_ff_gain(false, gain_coef, ANC_FEEDFORWARD); + TRACE(1,"[%s] Enable 0.25 FF ANC.", __func__); +#else + gain_coef = _SMALL_WIND_FF_GAIN_COEF; + _set_anc_ff_gain(false, gain_coef, ANC_FEEDFORWARD); + TRACE(1,"[%s] Enable 0.5 FF ANC.", __func__); +#endif + }//2->1 0%->25%->50% + else if(t_Windstate==0){ +#if (WNR_SYNC_SET_ANC_FF_GAIN_TWOSTAGE == 1) + FFstate = 6;//75% + gain_coef = _SMALL2NO_WIND_FF_MID_GAIN_COEF; + _set_anc_ff_gain(false, gain_coef, ANC_FEEDFORWARD); + TRACE(1,"[%s] Enable 0.75 FF ANC.", __func__); +#else + gain_coef = _NO_WIND_FF_GAIN_COEF; + _set_anc_ff_gain(false, gain_coef, ANC_FEEDFORWARD); + TRACE(1,"[%s] Enable FF ANC.", __func__); +#endif + }//1->0 50%->75%->100% + } + else + { + if(t_Windstate==2)//0% + { +#if (WNR_SYNC_SET_ANC_FF_GAIN_TWOSTAGE == 1) + FFstate = 2; +#endif + gain_coef = _STRONG_WIND_FF_GAIN_COEF; + _set_anc_ff_gain(false, gain_coef, ANC_FEEDFORWARD); + TRACE(1,"[%s] Disable FF ANC.", __func__); + } + else if(t_Windstate==1)//50% + { +#if (WNR_SYNC_SET_ANC_FF_GAIN_TWOSTAGE == 1) + FFstate = 1; +#endif + gain_coef = _SMALL_WIND_FF_GAIN_COEF; + _set_anc_ff_gain(false, gain_coef, ANC_FEEDFORWARD); + TRACE(1,"[%s] Enable 0.5 FF ANC.", __func__); + } + else + { +#if (WNR_SYNC_SET_ANC_FF_GAIN_TWOSTAGE == 1) + FFstate = 0; +#endif + gain_coef = _NO_WIND_FF_GAIN_COEF; + _set_anc_ff_gain(false, gain_coef, ANC_FEEDFORWARD); + TRACE(1,"[%s] Enable FF ANC.", __func__); + } + } + + g_wind_st = t_Windstate; + } + +#if (WNR_SYNC_SET_ANC_FF_GAIN_TWOSTAGE == 1) + if(((Twostage==1)&&(FFstate==7))||((Twostage==1)&&(FFstate==6))) + { + if(app_wnr_twostage_timer != NULL) + { + osTimerStop(app_wnr_twostage_timer); + osTimerStart(app_wnr_twostage_timer, WNR_SYNC_TWOSTAGE_DELAY); + } + } +#endif +} + +static int app_wnr_internal_event_process(APP_MESSAGE_BODY *msg_body) +{ + uint32_t evt = msg_body->message_id; + uint32_t arg0 = msg_body->message_Param0; + uint32_t arg1 = msg_body->message_Param1; + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(4,"[%s] evt:%d arg0:%d arg1:%d", __func__, evt, arg0, arg1); +#endif + + wnr_sync_counter_for_sco = 0; + wnr_sync_counter_for_normal = 0; + + switch (evt) + { + case APP_WNR_NOTIFY_DETECT_RESULT:app_wnr_notify_detect_result();break; + case APP_WNR_REQUEST_DETECT_RESULT:app_wnr_request_detect_result();break; + case APP_WNR_RESPONSE_DETECT_RESULT:app_wnr_response_detect_result(arg0);break; + case APP_WNR_PROCESS_DETECT_RESULT:app_wnr_process_detect_result(arg0);break; + case APP_WNR_SET_TRIGGER:app_wnr_set_trigger(arg0, arg1);break; + case APP_WNR_EXCUTE_TRIGGER:app_wnr_excute_trigger(arg0);break; + default:TRACE(2,"[%s] invalid evt:%d", __func__, evt);break; + } + + return 0; +} + +void app_wnr_cmd_receive_process(uint8_t *p_buff, uint16_t length) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] enter...", __func__); +#endif + + if((p_buff[0] == IBRT_ACTION_SYNC_WNR) && (p_buff[1] == APP_WNR_NOTIFY_DETECT_RESULT) && (app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_MASTER)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"NOTIFY_DETECT_RESULT peer_wnr_state:%d", p_buff[2]); +#endif + g_peer_Wind_module_onoff = true; + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_PROCESS_DETECT_RESULT, (uint32_t)p_buff[2], 0, 0); + return; + } + + if((p_buff[0] == IBRT_ACTION_SYNC_WNR) && (p_buff[1] == APP_WNR_REQUEST_DETECT_RESULT) && (app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_SLAVE)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"REQUEST_DETECT_RESULT peer_wnr_state:%d", p_buff[2]); +#endif + g_peer_Wind_module_onoff = true; + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_RESPONSE_DETECT_RESULT, (uint32_t)p_buff[2], 0, 0); + return; + } + + if((p_buff[0] == IBRT_ACTION_SYNC_WNR) && (p_buff[1] == APP_WNR_RESPONSE_DETECT_RESULT) && (app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_MASTER)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"RESPONSE_DETECT_RESULT peer_wnr_state:%d", p_buff[2]); +#endif + g_peer_Wind_module_onoff = true; + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_PROCESS_DETECT_RESULT, (uint32_t)p_buff[2], 0, 0); + return; + } + + if((p_buff[0] == IBRT_ACTION_SYNC_WNR) && (p_buff[1] == APP_WNR_SET_TRIGGER) && (app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_SLAVE)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"SET_TRIGGER set_Windstate:%d", p_buff[2]); +#endif + uint32_t tg_ticks = 0; + tg_ticks += p_buff[3]; + tg_ticks = tg_ticks << 8; + tg_ticks += p_buff[4]; + tg_ticks = tg_ticks << 8; + tg_ticks += p_buff[5]; + tg_ticks = tg_ticks << 8; + tg_ticks += p_buff[6]; + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_SET_TRIGGER, (uint32_t)p_buff[2], tg_ticks, 0); + return; + } + + if((p_buff[0] == IBRT_ACTION_SYNC_WNR) && (p_buff[1] == APP_WNR_SHARE_MODULE_INFO)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"APP_WNR_SHARE_MODULE_INFO peer_module_onoff:%d", p_buff[2]); +#endif + g_peer_Wind_module_onoff = (bool)p_buff[2]; + + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_MASTER) && (g_local_Wind_module_onoff == true) && (g_peer_Wind_module_onoff == true)) + { + wnr_sync_counter_for_normal = 0; + wnr_sync_counter_for_sco = 0; + if(g_local_Wind_module_onoff == true) + { + g_wnr_sync_flag = true; + } + return; + } + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_SLAVE) && (g_local_Wind_module_onoff == true) && (g_peer_Wind_module_onoff == true)) + { + wnr_sync_counter_for_normal = 0; + wnr_sync_counter_for_sco = 0; + if(g_local_Wind_module_onoff == true) + { + g_wnr_sync_flag = true; + } + return; + } + return; + } +} + +static bool wnr_open_flg = 0; +int32_t anc_wnr_open(anc_wnr_open_mode_t mode) +{ + if(wnr_open_flg == 1){ + return 0; + } + TRACE(4,"[%s] mode = %d, g_sample_rate = %d, g_frame_len = %d", __func__, mode, g_sample_rate, g_frame_len); + + hal_sysfreq_req(APP_SYSFREQ_USER_ANC_WNR, HAL_CMU_FREQ_26M); + TRACE(2,"[%s] Sys freq: %d", __func__, hal_sys_timer_calc_cpu_freq(5, 0)); + + app_wnr_reset_state_queue(); + app_set_threadhandle(APP_MODUAL_WNR, app_wnr_internal_event_process); + g_local_Wind_module_onoff = true; + if (app_wnr_sync_timer == NULL) + { + app_wnr_sync_timer = osTimerCreate (osTimer(APP_WNR_SYNC_TIMER), osTimerOnce, &g_set_Windstate); + } +#if (WNR_SYNC_SET_ANC_FF_GAIN_TWOSTAGE == 1) + if (app_wnr_twostage_timer == NULL) + { + app_wnr_twostage_timer = osTimerCreate(osTimer(APP_WNR_TWOSTAGE_TIMER), osTimerOnce, NULL); + } +#endif + g_set_Windstate = 0; + g_local_Windstate = 0; + g_peer_Windstate = 0; + g_wnr_notify_flag = false; + g_wnr_request_flag = false; + g_wnr_sync_flag = false; + g_wind_st = 0; + anc_ff_gain_l = 512; + anc_ff_gain_r = 512; + app_wnr_share_module_info(); + if (mode == ANC_WNR_OPEN_MODE_STANDALONE) { + g_wnr_open_mode = ANC_WNR_OPEN_MODE_STANDALONE;//normal mode... + wnr_sync_counter_for_normal = 0; + wnr_sync_counter_for_sco = 0; + g_sample_rate = _SAMPLE_RATE; + g_frame_len = _FRAME_LEN; + wind_st = WindDetection2Mic_create(_SAMPLE_RATE,_SAMPLE_BITS, _FRAME_LEN, &wind_cfg); + + _open_mic(); + + //audio_dump_init(_FRAME_LEN, sizeof(short), 2); + + } else if (mode == ANC_WNR_OPEN_MODE_CONFIGURE) { + g_wnr_open_mode = ANC_WNR_OPEN_MODE_CONFIGURE;//sco mode... + wnr_sync_counter_for_sco = 0; + wnr_sync_counter_for_normal = 0; + ASSERT(g_sample_rate == 8000 || g_sample_rate == 16000, "[%s] g_sample_rate(%d) is invalid.", __func__, g_sample_rate); + ASSERT(g_frame_len == 60 || g_frame_len == 120, "[%s] g_frame_len(%d) is invalid.", __func__, g_frame_len); + + wind_st = WindDetection2Mic_create(_SAMPLE_RATE,_SAMPLE_BITS, g_frame_len, &wind_cfg); + + //audio_dump_init(g_frame_len, sizeof(int), 2); + + } else { + ASSERT(0, "[%s] mode(%d) is invalid.", __func__, mode); + } + +#ifndef HW_SUPPORT_SMOOOTHING_GAIN + anc_gain_tuning_init(); + + struct anc_tuning_ctrl *c = &anc_tctrl; + + if (!c->timer_init) { + c->timer_ff_gain_id = hwtimer_alloc(anc_tuning_ff_gain_timer_timeout, (void *)c); + c->timer_ff_gain_run = 0; + c->timer_init = 1; + } +#endif + + g_open_mode = mode; + + + TRACE(1,"[%s] End...", __func__); + wnr_open_flg = 1; + return 0; +} + +int32_t anc_wnr_close(void) +{ + TRACE(1,"[%s] ...", __func__); + +#ifndef HW_SUPPORT_SMOOOTHING_GAIN + struct anc_tuning_ctrl *c = &anc_tctrl; + if (c->timer_ff_gain_run) { + hwtimer_stop(c->timer_ff_gain_id); + } + hwtimer_free(c->timer_ff_gain_id); + c->timer_init = 0; +#endif + + if (g_open_mode == ANC_WNR_OPEN_MODE_STANDALONE) { + _close_mic(); + g_open_mode = ANC_WNR_OPEN_MODE_QTY; + } + + WindDetection2Mic_destroy(wind_st); + + // size_t total = 0, used = 0, max_used = 0; + // speech_memory_info(&total, &used, &max_used); + // TRACE(3,"ANC WNR MALLOC MEM: total - %d, used - %d, max_used - %d.", total, used, max_used); + // ASSERT(used == 0, "[%s] used != 0", __func__); + app_wnr_reset_state_queue(); + app_set_threadhandle(APP_MODUAL_WNR, NULL); + g_local_Wind_module_onoff = false; + if (app_wnr_sync_timer != NULL) + { + osTimerStop(app_wnr_sync_timer); + } +#if (WNR_SYNC_SET_ANC_FF_GAIN_TWOSTAGE == 1) + if (app_wnr_twostage_timer != NULL) + { + osTimerStop(app_wnr_twostage_timer); + } +#endif + g_wnr_open_mode = ANC_WNR_OPEN_MODE_QTY; + wnr_sync_counter_for_normal = 0; + wnr_sync_counter_for_sco = 0; + g_set_Windstate = 0; + g_local_Windstate = 0; + g_peer_Windstate = 0; + g_wnr_notify_flag = false; + g_wnr_request_flag = false; + g_wnr_sync_flag = false; + g_wind_st = 0; + anc_ff_gain_l = 512; + anc_ff_gain_r = 512; + app_wnr_share_module_info(); + + hal_sysfreq_req(APP_SYSFREQ_USER_ANC_WNR, HAL_CMU_FREQ_32K); + wnr_open_flg = 0; + return 0; +} + +// TODO: Provide API to configure performance +static int32_t anc_wnr_process_frame(WNR_PCM_T *inF, WNR_PCM_T *inR, uint32_t frame_len) +{ + //static short mutetimer = 0; + //short targettimer = _TARGET_TIME; + float windictor = 0.0; + float wind_power; + + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if(cnt<=_PERIOD) + { +#if _SAMPLE_BITS==16 + windictor = WindDetection2Mic_process_16bit(wind_st, inF, inR, frame_len, &wind_power); +#else + windictor = WindDetection2Mic_process_24bit(wind_st, inF, inR, frame_len, &wind_power); +#endif + + //TRACE(2,"[%s] wind_power = %d.", __func__, (int)(wind_power*10000)); + windsum = windsum + windictor; + cnt = cnt + 1; + //TRACE(2,"[%s] cnt = %d, windsum = %d.", __func__, cnt, (int)windsum); + } + if(cnt==period) + { + cnt = 0; + wind_indictor = 0.8 * wind_indictor + 0.2 * windsum/period; + windsum = 0.0; + + //TRACE(2,"[%s] wind_indictor = %d.", __func__, (int)(wind_indictor*1000)); + + //float gain_coef; + + static uint8_t Windstate = 0; + //Windstate = wind_state_detect(g_wind_st, wind_indictor); + //TRACE(2,"[%s] windstate = %d.", __func__, Windstate); + //mutetimer = mutetimer + 1; + wind_state_detect(g_wind_st, wind_indictor, windindicator, windthd, &Windstate); + + for(int i = WINDINDICATOR_SIZE-1;i>0;i--) + { + windindicator[i] = windindicator[i-1]; + } + windindicator[0] = wind_indictor; + + + //TRACE(2,"[%s] windstate = %d.", __func__, Windstate); + + app_wnr_push_state_to_queue(g_wnr_open_mode, Windstate); + + if(g_wnr_open_mode == ANC_WNR_OPEN_MODE_STANDALONE) + { + if(++wnr_sync_counter_for_normal >= WNR_SYNC_COUNTER_THRESHOLD_FOR_NORMAL) + { + wnr_sync_counter_for_normal = 0; + wnr_sync_counter_for_sco = 0; + g_local_Windstate = app_wnr_get_state_from_queue(g_wnr_open_mode); +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] OPEN_MODE_STANDALONE", __func__); + TRACE(2,"[%s] local_Windstate:%d", __func__, g_local_Windstate); + TRACE(2,"[%s] last_Windstate:%d", __func__, g_wind_st); +#endif + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_MASTER) && (g_wnr_sync_flag == true)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] REQUEST_DETECT_RESULT", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_REQUEST_DETECT_RESULT, 0, 0, 0); + return 0; + } + + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_SLAVE) && (g_wnr_sync_flag == true)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] NOTIFY_DETECT_RESULT", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_NOTIFY_DETECT_RESULT, 0, 0, 0); + return 0; + } + + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_MASTER) && (g_local_Windstate != g_wind_st) && (g_peer_Wind_module_onoff == true)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] REQUEST_DETECT_RESULT", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_REQUEST_DETECT_RESULT, 0, 0, 0); + return 0; + } + + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_SLAVE) && (g_local_Windstate != g_wind_st) && (g_peer_Wind_module_onoff == true)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] NOTIFY_DETECT_RESULT", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_NOTIFY_DETECT_RESULT, 0, 0, 0); + return 0; + } + + if(((app_tws_ibrt_tws_link_connected() == false) || (g_peer_Wind_module_onoff == false)) && (g_local_Windstate != g_wind_st)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] SET_TRIGGER", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_SET_TRIGGER, (uint32_t)g_local_Windstate, 0, 0); + return 0; + } + } + } + else + { + if(++wnr_sync_counter_for_sco >= WNR_SYNC_COUNTER_THRESHOLD_FOR_SCO) + { + wnr_sync_counter_for_sco = 0; + wnr_sync_counter_for_normal = 0; + g_local_Windstate = app_wnr_get_state_from_queue(g_wnr_open_mode); +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] OPEN_MODE_CONFIGURE", __func__); + TRACE(2,"[%s] local_Windstate:%d", __func__, g_local_Windstate); + TRACE(2,"[%s] last_Windstate:%d", __func__, g_wind_st); +#endif + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_MASTER) && (g_wnr_sync_flag == true)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] REQUEST_DETECT_RESULT", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_REQUEST_DETECT_RESULT, 0, 0, 0); + return 0; + } + + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_SLAVE) && (g_wnr_sync_flag == true)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] NOTIFY_DETECT_RESULT", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_NOTIFY_DETECT_RESULT, 0, 0, 0); + return 0; + } + + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_MASTER) && (g_local_Windstate != g_wind_st) && (g_peer_Wind_module_onoff == true)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] REQUEST_DETECT_RESULT", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_REQUEST_DETECT_RESULT, 0, 0, 0); + return 0; + } + + if((app_tws_ibrt_tws_link_connected() == true) && (p_ibrt_ctrl->nv_role == IBRT_SLAVE) && (g_local_Windstate != g_wind_st) && (g_peer_Wind_module_onoff == true)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] NOTIFY_DETECT_RESULT", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_NOTIFY_DETECT_RESULT, 0, 0, 0); + return 0; + } + + if(((app_tws_ibrt_tws_link_connected() == false) || (g_peer_Wind_module_onoff == false)) && (g_local_Windstate != g_wind_st)) + { +#if(WNR_SYNC_DEBUG_LOG == 1) + TRACE(1,"[%s] SET_TRIGGER", __func__); +#endif + if(g_local_Wind_module_onoff == true) + app_wnr_trigger_internal_event(APP_WNR_SET_TRIGGER, (uint32_t)g_local_Windstate, 0, 0); + return 0; + } + } + } + } + return 0; + } + +static void inline stereo_resample_16k(WNR_PCM_T *pcm_buf, uint32_t pcm_len, WNR_PCM_T *mic1, WNR_PCM_T *mic2) +{ + uint32_t frame_len = pcm_len / _CHANNEL_NUM; + + const float num[3] = {0.020083, 0.040166, 0.020083}; + const float den[3] = {1.000000, -1.561018, 0.641351}; + + static float y0 = 0, y1 = 0, y2 = 0, x0 = 0, x1 = 0, x2 = 0; + static float Y0 = 0, Y1 = 0, Y2 = 0, X0 = 0, X1 = 0, X2 = 0; + + for (uint32_t i=0; i8k + if (g_sample_rate == 16000) { + stereo_resample_16k(tmp_buf, pcm_len, (WNR_PCM_T *)af_stream_mic1, (WNR_PCM_T *)af_stream_mic2); + // 2ch --> 1ch, 16k --> 8k + pcm_len = pcm_len / _CHANNEL_NUM / 2; + } + else{ + + WNR_PCM_T *mic1 = (WNR_PCM_T *)af_stream_mic1; + WNR_PCM_T *mic2 = (WNR_PCM_T *)af_stream_mic2; + pcm_len = pcm_len / _CHANNEL_NUM; + for (uint32_t i=0; i 0) + { + if (gain0_curr < gain0_tg) + { + gain0_curr++; + } + } + else + { + if (gain0_curr > gain0_tg) + { + gain0_curr--; + } + } + + if (gain1_tg > 0) + { + if (gain1_curr < gain1_tg) + { + gain1_curr++; + } + } + else + { + if (gain1_curr > gain1_tg) + { + gain1_curr--; + } + } + hal_sys_timer_delay_us(25); + + anc_set_gain(gain0_curr, gain1_curr, type); + + if ((gain0_curr == gain0_tg) && (gain1_curr == gain1_tg)) + { + TRACE(3,"[%s] cur gain: %d %d", __func__, gain0_curr, gain1_curr); + return 0; + } + + return 1; +} + +int __anc_usb_app_fadeout(enum ANC_TYPE_T type) +{ + int32_t gain0_curr, gain1_curr; + + anc_get_gain(&gain0_curr, &gain1_curr, type); + + if (gain0_curr > 0) + { + gain0_curr--; + } + else if (gain0_curr < 0) + { + gain0_curr++; + } + + if (gain1_curr > 0) + { + gain1_curr--; + } + else if (gain1_curr < 0) + { + gain1_curr++; + } + + // gain0_curr = gain1_curr = 0 ; + hal_sys_timer_delay_us(25); + + anc_set_gain(gain0_curr, gain1_curr, type); + + if ((gain0_curr == 0) && (gain1_curr == 0)) + { + TRACE(3,"[%s] gain: %d, %d", __func__, gain0_curr, gain1_curr); + return 0; + } + + return 1; +} + +#if defined(ANC_FF_ENABLED) && defined(ANC_FB_ENABLED) +int __anc_usb_app_fadein_ff_fb(void) +{ + int32_t gain0_curr, gain1_curr; + int32_t gain2_curr, gain3_curr; + + int32_t gain0_tg, gain1_tg; + int32_t gain2_tg, gain3_tg; + + + anc_get_gain(&gain0_curr, &gain1_curr, ANC_FEEDFORWARD); + anc_get_gain(&gain2_curr, &gain3_curr, ANC_FEEDBACK); + anc_get_cfg_gain(&gain0_tg, &gain1_tg, ANC_FEEDFORWARD); + anc_get_cfg_gain(&gain2_tg, &gain3_tg, ANC_FEEDBACK); + + uint32_t random_factor = rand(); + random_factor %= 5; + if(random_factor==0) random_factor++; + + + uint32_t random_factor_inverse = 5-random_factor; + if(random_factor_inverse==0) random_factor_inverse++; + + random_factor_inverse =1; + + if(is_sbc_mode() || is_sco_mode()){ + if (gain0_tg > 0) + { + if (gain0_curr < gain0_tg) + { + gain0_curr = MIN(gain0_curr+random_factor_inverse, gain0_tg); + } + } + else + { + if (gain0_curr > gain0_tg) + { + gain0_curr = MAX(gain0_curr-random_factor_inverse, gain0_tg); + } + } + + if (gain1_tg > 0) + { + if (gain1_curr < gain1_tg) + { + gain1_curr = MIN(gain1_curr+random_factor_inverse, gain1_tg); + } + } + else + { + if (gain1_curr > gain1_tg) + { + gain1_curr = MAX(gain1_curr-random_factor_inverse, gain1_tg); + } + } + + if (gain2_tg > 0) + { + if (gain2_curr < gain2_tg) + { + gain2_curr = MIN(gain2_curr+random_factor_inverse, gain2_tg); + } + } + else + { + if (gain2_curr > gain2_tg) + { + gain2_curr = MAX(gain2_curr-random_factor_inverse, gain2_tg); + } + } + + if (gain3_tg > 0) + { + if (gain3_curr < gain3_tg) + { + gain3_curr = MIN(gain3_curr+random_factor_inverse, gain3_tg); + } + } + else + { + if (gain3_curr > gain3_tg) + { + gain3_curr = MAX(gain3_curr-random_factor_inverse, gain3_tg); + } + } + }else{ + if (gain0_tg > 0) + { + if (gain0_curr < gain0_tg) + { + gain0_curr = MIN(gain0_curr+random_factor_inverse, gain0_tg); + } + } + else + { + if (gain0_curr > gain0_tg) + { + gain0_curr = MAX(gain0_curr-random_factor_inverse, gain0_tg); + } + } + + if (gain1_tg > 0) + { + if (gain1_curr < gain1_tg) + { + gain1_curr = MIN(gain1_curr+random_factor_inverse, gain1_tg); + } + } + else + { + if (gain1_curr > gain1_tg) + { + gain1_curr = MAX(gain1_curr-random_factor_inverse, gain1_tg); + } + } + + if (gain2_tg > 0) + { + if (gain2_curr < gain2_tg) + { + gain2_curr = MIN(gain2_curr+random_factor_inverse, gain2_tg); + } + } + else + { + if (gain2_curr > gain2_tg) + { + gain2_curr = MAX(gain2_curr-random_factor_inverse, gain2_tg); + } + } + + if (gain3_tg > 0) + { + if (gain3_curr < gain3_tg) + { + gain3_curr = MIN(gain3_curr+random_factor_inverse, gain3_tg); + } + } + else + { + if (gain3_curr > gain3_tg) + { + gain3_curr = MAX(gain3_curr-random_factor_inverse, gain3_tg); + } + } + } + + + anc_set_gain(gain0_curr, gain1_curr, ANC_FEEDFORWARD); + anc_set_gain(gain2_curr, gain3_curr, ANC_FEEDBACK); + + + //TRACE(5,"[%s] cur gain: %d %d %d %d", __func__, gain0_curr, gain1_curr, gain2_curr, gain3_curr); + + //osDelay(random_factor); + + hal_sys_timer_delay_us(40); + if(gain0_curr%40==0) + { + //osDelay(random_factor); + } + + if ((gain0_curr == gain0_tg) && (gain1_curr == gain1_tg) && (gain2_curr == gain2_tg) && (gain3_curr == gain3_tg)) + { + anc_disable_gain_updated_when_pass0(1); + + anc_set_gain(gain0_curr, gain1_curr, ANC_FEEDFORWARD); + anc_set_gain(gain2_curr, gain3_curr, ANC_FEEDBACK); + TRACE(5,"[%s] end cur gain: %d, %d, %d, %d", __func__, gain0_curr, gain1_curr,gain2_curr,gain3_curr); + return 0; + } + return 1; +} + +int __anc_usb_app_fadeout_ff_fb(void) +{ + int32_t gain0_curr, gain1_curr; + int32_t gain2_curr, gain3_curr; + anc_get_gain(&gain0_curr, &gain1_curr, ANC_FEEDFORWARD); + anc_get_gain(&gain2_curr, &gain3_curr, ANC_FEEDBACK); + + uint32_t random_factor = rand(); + random_factor = random_factor%5; + if(random_factor==0) random_factor++; + + uint32_t random_factor_inverse = 5-random_factor; + if(random_factor_inverse==0) random_factor_inverse++; + + random_factor_inverse =1; + + + if(is_sbc_mode() || is_sco_mode()){ + if (gain0_curr > 0) + { + gain0_curr = MAX(gain0_curr-random_factor_inverse,0); + } + else if (gain0_curr < 0) + { + gain0_curr = MIN(gain0_curr+random_factor_inverse,0); + } + + if (gain1_curr > 0) + { + gain1_curr = MAX(gain1_curr-random_factor_inverse,0); + } + else if (gain1_curr < 0) + { + gain1_curr = MIN(gain1_curr+random_factor_inverse,0); + } + + if (gain2_curr > 0) + { + gain2_curr = MAX(gain2_curr-random_factor_inverse,0); + } + else if (gain2_curr < 0) + { + gain2_curr = MIN(gain2_curr+random_factor_inverse,0); + } + + if (gain3_curr > 0) + { + gain3_curr = MAX(gain3_curr-random_factor_inverse,0); + } + else if (gain3_curr < 0) + { + gain3_curr = MIN(gain3_curr+random_factor_inverse,0); + } + }else{ + if (gain0_curr > 0) + { + gain0_curr = MAX(gain0_curr-random_factor_inverse,0); + } + else if (gain0_curr < 0) + { + gain0_curr = MIN(gain0_curr+random_factor_inverse,0); + } + + if (gain1_curr > 0) + { + gain1_curr = MAX(gain1_curr-random_factor_inverse,0); + } + else if (gain1_curr < 0) + { + gain1_curr = MIN(gain1_curr+random_factor_inverse,0); + } + + if (gain2_curr > 0) + { + gain2_curr = MAX(gain2_curr-random_factor_inverse,0); + } + else if (gain2_curr < 0) + { + gain2_curr = MIN(gain2_curr+random_factor_inverse,0); + } + + if (gain3_curr > 0) + { + gain3_curr = MAX(gain3_curr-random_factor_inverse,0); + } + else if (gain3_curr < 0) + { + gain3_curr = MIN(gain3_curr+random_factor_inverse,0); + } + + } + + + anc_set_gain(gain0_curr, gain1_curr, ANC_FEEDFORWARD); + anc_set_gain(gain2_curr, gain3_curr, ANC_FEEDBACK); + //TRACE(5,"[%s] cur gain: %d %d %d %d", __func__, gain0_curr, gain1_curr, gain2_curr, gain3_curr); + + + //osDelay(random_factor); + + hal_sys_timer_delay_us(40); + if(gain0_curr%40==0) + { + //osDelay(random_factor); + } + + if ((gain0_curr == 0) && (gain1_curr == 0) && (gain2_curr == 0) && (gain3_curr == 0)) + { + anc_disable_gain_updated_when_pass0(1); + + anc_set_gain(gain0_curr, gain1_curr, ANC_FEEDFORWARD); + anc_set_gain(gain2_curr, gain3_curr, ANC_FEEDBACK); + TRACE(5,"[%s] end cur gain: %d, %d, %d, %d", __func__, gain0_curr, gain1_curr,gain2_curr,gain3_curr); + return 0; + } + + return 1; +} +#endif + +void anc_gain_fade_handle(void) +{ + TRACE(2," %s %d ", __func__, app_anc_fade_status); + if (app_anc_fade_status == APP_ANC_FADE_OUT) + { + osSignalSet(anc_fade_thread_tid,FADE_OUT); + } + + if (app_anc_fade_status == APP_ANC_FADE_IN) + { +#ifdef ANC_LED_PIN + app_anc_switch_turnled(true); +#endif + + osSignalSet(anc_fade_thread_tid,FADE_IN); + + if (anc_set_dac_pa_delay) + { + anc_set_dac_pa_delay = false; +// osDelay(600); +// analog_aud_enable_dac_pa(48); + } + } +} + +void anc_fade_thread(void const *argument) +{ + + osEvent evt; + evt.status = 0; + uint32_t singles = 0; + + while(1) + { + evt = osSignalWait(0,osWaitForever); + + singles = evt.value.signals; + TRACE(2,"anc_fade_thread. %d",singles); + + if(evt.status == osEventSignal) + { + + switch (singles) + { + + case FADE_IN: +#if defined(ANC_FF_ENABLED) && defined(ANC_FB_ENABLED) + anc_disable_gain_updated_when_pass0(0); + while(__anc_usb_app_fadein_ff_fb()); +#else +#ifdef ANC_FF_ENABLED + while (__anc_usb_app_fadein(ANC_FEEDFORWARD)) + ; +#endif +#ifdef ANC_FB_ENABLED + while (__anc_usb_app_fadein(ANC_FEEDBACK)) + ; +#endif +#endif + app_anc_fade_status = APP_ANC_IDLE; + + break; + case FADE_OUT: + +#if defined(ANC_FF_ENABLED) && defined(ANC_FB_ENABLED) + anc_disable_gain_updated_when_pass0(0); + while(__anc_usb_app_fadeout_ff_fb()); +#else +#ifdef ANC_FF_ENABLED + while (__anc_usb_app_fadeout(ANC_FEEDFORWARD)) + ; +#endif +#ifdef ANC_FB_ENABLED + while (__anc_usb_app_fadeout(ANC_FEEDBACK)) + ; +#endif +#endif + + app_anc_fade_status = APP_ANC_IDLE; + +#ifdef ANC_FB_CHECK + hal_codec_anc_fb_check_set_irq_handler(anc_fb_check_irq_handler); + + anc_fb_check_param(); +#endif + break; + case CHANGE_FROM_ANC_TO_TT_DIRECTLY: +#if defined(ANC_FF_ENABLED) && defined(ANC_FB_ENABLED) + anc_disable_gain_updated_when_pass0(0); + while(__anc_usb_app_fadeout_ff_fb()); +#else +#ifdef ANC_FF_ENABLED + while (__anc_usb_app_fadeout(ANC_FEEDFORWARD)); +#endif + +#ifdef ANC_FB_ENABLED + while (__anc_usb_app_fadeout(ANC_FEEDBACK)); +#endif +#endif + +#if defined(ANC_FF_ENABLED) && defined(ANC_FB_ENABLED) + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx,ANC_FEEDFORWARD,ANC_GAIN_DELAY); + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx,ANC_FEEDBACK,ANC_GAIN_DELAY); +#ifdef AUDIO_ANC_FB_MC_HW + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx,ANC_MUSICCANCLE,ANC_GAIN_DELAY); +#endif +#else +#ifdef ANC_FF_ENABLED + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx,ANC_FEEDFORWARD,ANC_GAIN_DELAY); +#endif + +#ifdef ANC_FB_ENABLED + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx,ANC_FEEDBACK,ANC_GAIN_DELAY); +#endif +#endif + +#if defined(ANC_FF_ENABLED) && defined(ANC_FB_ENABLED) + anc_disable_gain_updated_when_pass0(0); + while(__anc_usb_app_fadein_ff_fb()); +#else +#ifdef ANC_FF_ENABLED + while (__anc_usb_app_fadein(ANC_FEEDFORWARD)); +#endif + +#ifdef ANC_FB_ENABLED + while (__anc_usb_app_fadein(ANC_FEEDBACK)); +#endif +#endif + + app_anc_fade_status = APP_ANC_IDLE; + + //recommand to play "ANC SWITCH" prompt here... + + break; + default: + break; + + } + + } + else + { + TRACE(2,"anc fade thread evt error"); + continue; + } + } +} + +void app_anc_gain_fadein(void) +{ + APP_MESSAGE_BLOCK msg; + TRACE(1," %s ", __func__); + if (app_poweroff_flag) + return; + + app_anc_fade_status = APP_ANC_FADE_IN; + + msg.mod_id = APP_MODUAL_ANC; + msg.msg_body.message_id = ANC_EVENT_FADE_IN; + app_mailbox_put(&msg); +} + +void app_anc_post_anc_codec_close(void) +{ + APP_MESSAGE_BLOCK msg; + TRACE(1," %s ", __func__); + if (app_poweroff_flag) + return; + + msg.mod_id = APP_MODUAL_ANC; + msg.msg_body.message_id = SIMPLE_PLAYER_CLOSE_CODEC_EVT; + app_mailbox_put(&msg); +} + +void app_anc_gain_fadeout(void) +{ + APP_MESSAGE_BLOCK msg; + TRACE(1," %s ", __func__); + if (app_poweroff_flag) + return; + + app_anc_fade_status = APP_ANC_FADE_OUT; + + msg.mod_id = APP_MODUAL_ANC; + msg.msg_body.message_id = ANC_EVENT_FADE_OUT; + app_mailbox_put(&msg); +} + +void app_anc_status_post(uint8_t status) +{ + APP_MESSAGE_BLOCK msg; + TRACE(2," %s status %d", __func__, status); + if (app_poweroff_flag) + return; + + msg.mod_id = APP_MODUAL_ANC; + msg.msg_body.message_id = ANC_EVENT_CHANGE_STATUS; + msg.msg_body.message_Param0 = status; + app_mailbox_put(&msg); +} + +void app_anc_status_sync(uint8_t status) +{ + APP_MESSAGE_BLOCK msg; + TRACE(2," %s status %d", __func__, status); + if (app_poweroff_flag) + return; + + msg.mod_id = APP_MODUAL_ANC; + msg.msg_body.message_id = ANC_EVENT_SYNC_STATUS; + msg.msg_body.message_Param0 = status; + app_mailbox_put(&msg); +} + +void app_anc_status_sync_init(void) +{ + APP_MESSAGE_BLOCK msg; + TRACE(1," %s ", __func__); + if (app_poweroff_flag) + return; + + msg.mod_id = APP_MODUAL_ANC; + msg.msg_body.message_id = ANC_EVENT_SYNC_INIT; + app_mailbox_put(&msg); +} + +void app_anc_do_init(void) +{ + APP_MESSAGE_BLOCK msg; + TRACE(1," %s DO INIT", __func__); + if (app_poweroff_flag) + return; + + msg.mod_id = APP_MODUAL_ANC; + msg.msg_body.message_id = ANC_EVENT_INIT; + app_mailbox_put(&msg); +} + +void app_anc_send_howl_evt(uint32_t howl) +{ + APP_MESSAGE_BLOCK msg; + TRACE(2," %s %d", __func__, howl); + if (app_poweroff_flag) + return; + + msg.mod_id = APP_MODUAL_ANC; + msg.msg_body.message_id = ANC_EVENT_HOWL_PROCESS; + msg.msg_body.message_Param0 = howl; + app_mailbox_put(&msg); +} + +void app_anc_send_pwr_key_monitor_evt(uint8_t level) +{ + APP_MESSAGE_BLOCK msg; + TRACE(2," %s %d", __func__, level); + if (app_poweroff_flag) + return; + + msg.mod_id = APP_MODUAL_ANC; + msg.msg_body.message_id = ANC_EVENT_PWR_KEY_MONITOR; + msg.msg_body.message_Param0 = level; + app_mailbox_put(&msg); +} + +extern void simple_player_delay_stop(void); + +void app_anc_post_simplayer_stop_evt(void) +{ + APP_MESSAGE_BLOCK msg; + TRACE(1," %s d", __func__); + + msg.mod_id = APP_MODUAL_ANC; + msg.msg_body.message_id = SIMPLE_PLAYER_DELAY_STOP_EVT; + msg.msg_body.message_Param0 = 0; + app_mailbox_put(&msg); +} + +bool anc_enabled(void) +{ + return (anc_work_status == ANC_STATUS_ON); +} + +void app_anc_resample(uint32_t res_ratio, uint32_t *in, uint32_t *out, uint32_t samples) +{ + uint32_t flag = int_lock(); + for (int i = samples; i > 0; i--) + { + for (int j = 0; j < res_ratio; j++) + { + *(out + (i - 1) * res_ratio + j) = *(in + i - 1); + } + } + int_unlock(flag); +} + +void app_anc_select_coef(void) +{ + TRACE(2,"enter %s %d\n", __FUNCTION__, __LINE__); + +#ifdef ANC_FF_ENABLED + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx, ANC_FEEDFORWARD, ANC_GAIN_DELAY); +#endif + +#ifdef ANC_FB_ENABLED + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx, ANC_FEEDBACK, ANC_GAIN_DELAY); +#endif + +#ifdef AUDIO_ANC_FB_MC_HW + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx, ANC_MUSICCANCLE, ANC_GAIN_NO_DELAY); +#endif + + TRACE(2,"exit %s %d\n", __FUNCTION__, __LINE__); +} + +void app_anc_enable(void) +{ + TRACE(2,"enter %s %d\n", __FUNCTION__, __LINE__); +//anc_active_codec(); +#ifndef __SIMPLE_INTERNAL_PLAYER_SUPPORT__ + analog_aud_codec_speaker_enable(true); +#endif +#ifdef ANC_FF_ENABLED + anc_open(ANC_FEEDFORWARD); + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx, ANC_FEEDFORWARD, ANC_GAIN_DELAY); +#endif + +#ifdef ANC_FB_ENABLED + anc_open(ANC_FEEDBACK); + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx, ANC_FEEDBACK, ANC_GAIN_DELAY); +#endif + +#ifdef AUDIO_ANC_FB_MC_HW + anc_open(ANC_MUSICCANCLE); + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx, ANC_MUSICCANCLE, ANC_GAIN_NO_DELAY); +#endif + +#ifdef AUDIO_ANC_FB_MC_HW + int32_t gain_ch_l = 0; + int32_t gain_ch_r = 0; + + anc_get_cfg_gain(&gain_ch_l, &gain_ch_r, ANC_MUSICCANCLE); + anc_set_gain(gain_ch_l, gain_ch_r, ANC_MUSICCANCLE); +#endif + +#if defined(ANC_WNR_ENABLED) + if (is_sco_mode()) { + anc_wnr_open(ANC_WNR_OPEN_MODE_CONFIGURE); + } else { + anc_wnr_open(ANC_WNR_OPEN_MODE_STANDALONE); + } +#endif + +#if defined(ANC_ASSIST_ENABLED) + anc_assist_open(ANC_ASSIST_STANDALONE); +#endif + + TRACE(2,"exit %s %d\n", __FUNCTION__, __LINE__); +} + +void app_anc_disable(void) +{ + TRACE(2,"enter %s %d\n", __FUNCTION__, __LINE__); + +#if defined(ANC_WNR_ENABLED) + anc_wnr_close(); +#endif + +#if defined(ANC_ASSIST_ENABLED) + anc_assist_close(); +#endif + +#ifdef AUDIO_ANC_FB_MC_HW + anc_close(ANC_MUSICCANCLE); +#endif + +#ifdef ANC_FF_ENABLED + anc_close(ANC_FEEDFORWARD); +#endif + +#ifdef ANC_FB_ENABLED + anc_close(ANC_FEEDBACK); +#endif + + TRACE(2,"exit %s %d\n", __FUNCTION__, __LINE__); +} + +static void anc_sample_rate_change(enum AUD_STREAM_T stream, enum AUD_SAMPRATE_T rate, enum AUD_SAMPRATE_T *new_play, enum AUD_SAMPRATE_T *new_cap) +{ + enum AUD_SAMPRATE_T play_rate, cap_rate; + + if (anc_sample_rate[stream] != rate) { +#ifdef CHIP_BEST1000 + if (stream == AUD_STREAM_PLAYBACK) { + play_rate = rate; + cap_rate = rate * (anc_sample_rate[AUD_STREAM_CAPTURE] / anc_sample_rate[AUD_STREAM_PLAYBACK]); + } else { + play_rate = rate / (anc_sample_rate[AUD_STREAM_CAPTURE] / anc_sample_rate[AUD_STREAM_PLAYBACK]); + cap_rate = rate; + } +#else + play_rate = rate; + cap_rate = rate; +#ifdef ANC_FF_ENABLED + anc_select_coef(play_rate,anc_coef_idx, ANC_FEEDFORWARD, ANC_GAIN_NO_DELAY); +#endif + +#ifdef ANC_FB_ENABLED + anc_select_coef(play_rate,anc_coef_idx, ANC_FEEDBACK, ANC_GAIN_NO_DELAY); +#endif + +#ifdef AUDIO_ANC_FB_MC_HW + anc_select_coef(play_rate,anc_coef_idx, ANC_MUSICCANCLE, ANC_GAIN_NO_DELAY); +#endif + + +#endif //CHIP_BEST1000 + + TRACE(5,"%s: Update anc sample rate from %u/%u to %u/%u", __func__, + anc_sample_rate[AUD_STREAM_PLAYBACK], anc_sample_rate[AUD_STREAM_CAPTURE], play_rate, cap_rate); + + if (new_play) { + *new_play= play_rate; + } + if (new_cap) { + *new_cap = cap_rate; + } + + anc_sample_rate[AUD_STREAM_PLAYBACK] = play_rate; + anc_sample_rate[AUD_STREAM_CAPTURE] = cap_rate; + } +} + +void app_anc_open_anc(void) +{ + enum AUD_SAMPRATE_T playback_rate; + enum AUD_SAMPRATE_T capture_rate; + AF_ANC_HANDLER handler; + + TRACE(2,"enter %s %d\n", __FUNCTION__, __LINE__); + + handler = anc_sample_rate_change; + +#ifdef __SIMPLE_INTERNAL_PLAYER_SUPPORT__ + app_start_player_by_anc(); +#endif + + if (anc_sample_rate[AUD_STREAM_PLAYBACK] == AUD_SAMPRATE_NULL) { +#ifdef CHIP_BEST1000 + anc_sample_rate[AUD_STREAM_PLAYBACK] = AUD_SAMPRATE_96000; + anc_sample_rate[AUD_STREAM_CAPTURE] = AUD_SAMPRATE_384000; +#else // !CHIP_BEST1000 + anc_sample_rate[AUD_STREAM_PLAYBACK] = AUD_SAMPRATE_48000; + anc_sample_rate[AUD_STREAM_CAPTURE] = AUD_SAMPRATE_48000; +#endif + anc_sample_rate[AUD_STREAM_PLAYBACK] = hal_codec_anc_convert_rate(anc_sample_rate[AUD_STREAM_PLAYBACK]); + anc_sample_rate[AUD_STREAM_CAPTURE] = hal_codec_anc_convert_rate(anc_sample_rate[AUD_STREAM_CAPTURE]); + } + + playback_rate = anc_sample_rate[AUD_STREAM_PLAYBACK]; + capture_rate = anc_sample_rate[AUD_STREAM_CAPTURE]; + + pmu_anc_config(1); + +#ifdef ANC_FF_ENABLED + af_anc_open(ANC_FEEDFORWARD, playback_rate, capture_rate, handler); + anc_open(ANC_FEEDFORWARD); + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx, ANC_FEEDFORWARD, ANC_GAIN_DELAY); +#endif + +#ifdef ANC_FB_ENABLED + af_anc_open(ANC_FEEDBACK, playback_rate, capture_rate, handler); + anc_open(ANC_FEEDBACK); + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx, ANC_FEEDBACK, ANC_GAIN_DELAY); +#endif + +#ifdef AUDIO_ANC_FB_MC_HW + anc_open(ANC_MUSICCANCLE); + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx, ANC_MUSICCANCLE, ANC_GAIN_NO_DELAY); +#endif + +#if defined(AUDIO_ANC_TT_HW) + anc_open(ANC_TALKTHRU); + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx, ANC_TALKTHRU, ANC_GAIN_NO_DELAY); +#endif + +#ifdef AUDIO_ANC_FB_MC_HW + int32_t gain_ch_l = 0; + int32_t gain_ch_r = 0; + + anc_get_cfg_gain(&gain_ch_l, &gain_ch_r, ANC_MUSICCANCLE); + anc_set_gain(gain_ch_l, gain_ch_r, ANC_MUSICCANCLE); +#endif + +#if defined(ANC_WNR_ENABLED) + if (is_sco_mode()) { + anc_wnr_open(ANC_WNR_OPEN_MODE_CONFIGURE); + } else { + anc_wnr_open(ANC_WNR_OPEN_MODE_STANDALONE); + } + #endif + + #if defined(ANC_ASSIST_ENABLED) + anc_assist_open(ANC_ASSIST_STANDALONE); +#endif + + + TRACE(2,"exit %s %d\n", __FUNCTION__, __LINE__); +} + +void app_anc_close_anc(void) +{ + TRACE(2,"enter %s %d\n", __FUNCTION__, __LINE__); + anc_set_dac_pa_delay = false; +#ifdef __SUPPORT_ANC_SINGLE_MODE_WITHOUT_BT__ + if (anc_single_mode_is_on()) + { + analog_aud_codec_speaker_enable(false); + } +#endif + +#ifdef ANC_WNR_ENABLED + anc_wnr_close(); +#endif + +#if defined(ANC_ASSIST_ENABLED) + anc_assist_close(); +#endif + +#if defined(AUDIO_ANC_TT_HW) + anc_close(ANC_TALKTHRU); +#endif + +#ifdef ANC_FF_ENABLED + anc_close(ANC_FEEDFORWARD); + af_anc_close(ANC_FEEDFORWARD); +#endif + +#ifdef ANC_FB_ENABLED +#if defined(AUDIO_ANC_FB_MC_HW) + anc_close(ANC_MUSICCANCLE); +#endif + anc_close(ANC_FEEDBACK); + af_anc_close(ANC_FEEDBACK); +#endif + + pmu_anc_config(0); +#ifdef __SIMPLE_INTERNAL_PLAYER_SUPPORT__ + app_stop_player_by_anc(); +#endif + TRACE(2,"exit %s %d\n", __FUNCTION__, __LINE__); +} + +void app_anc_bitrate_reopen(void) +{ + TRACE(2," %s status %d", __func__, anc_work_status); + if (anc_work_status == ANC_STATUS_INIT_ON) + { +// hal_codec_reconfig_pll_freq(playback_rate, capture_rate); + } + else if (anc_work_status == ANC_STATUS_ON) + { + // hal_codec_reconfig_pll_freq(playback_rate, capture_rate); + } + else if (anc_work_status == ANC_STATUS_WAITING_ON) + { + } + else + { + TRACE(0,"no deal situation."); + } +} + +void app_anc_status_change(void) +{ +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + anc_coef_idx = anc_peer_coef_idx; + } +#endif + + TRACE(3,"%s anc_work_status: %d anc_coef_idx: %d", __func__, anc_work_status, anc_coef_idx); + + switch (anc_work_status) + { + case ANC_STATUS_OFF: + anc_work_status = ANC_STATUS_WAITING_ON; + app_anc_timer_set(ANC_EVENT_OPEN, anc_switch_on_time); + app_anc_open_anc(); + break; + case ANC_STATUS_ON: + +#if (ANC_COEF_LIST_NUM > 1) + +#ifdef __BT_ANC_KEY__ + if(anc_status_sync_flag == false) + { + anc_coef_idx++; + } +#endif + + if (anc_coef_idx < ANC_COEF_LIST_NUM) + { + TRACE(2," %s set coef idx: %d ", __func__, anc_coef_idx); + +#ifdef ANC_MODE_SWITCH_WITHOUT_FADE + +#ifdef ANC_FF_ENABLED + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx,ANC_FEEDFORWARD,ANC_GAIN_NO_DELAY); +#endif +#ifdef ANC_FB_ENABLED + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx,ANC_FEEDBACK,ANC_GAIN_NO_DELAY); +#endif +#ifdef AUDIO_ANC_FB_MC_HW + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx,ANC_MUSICCANCLE,ANC_GAIN_NO_DELAY); +#endif + + //recommand to play "ANC SWITCH" prompt here... + +#else + osSignalSet(anc_fade_thread_tid,CHANGE_FROM_ANC_TO_TT_DIRECTLY); +#endif + } + else + { + anc_coef_idx = 0; + app_anc_timer_set(ANC_EVENT_CLOSE, anc_close_delay_time); + app_anc_gain_fadeout(); + anc_work_status = ANC_STATUS_WAITING_OFF; + } +#else + anc_coef_idx = 0; + app_anc_timer_set(ANC_EVENT_CLOSE, anc_close_delay_time); + app_anc_gain_fadeout(); + anc_work_status = ANC_STATUS_WAITING_OFF; +#endif + break; + case ANC_STATUS_INIT_ON: + app_anc_select_coef(); + app_anc_gain_fadein(); + anc_work_status = ANC_STATUS_WAITING_ON; + app_anc_timer_close(); + break; + default: + break; + } + if(anc_status_sync_flag == true) + anc_status_sync_flag = false; +} + +static int app_anc_handle_process(APP_MESSAGE_BODY *msg_body) +{ + uint32_t evt = msg_body->message_id; + uint32_t arg0 = msg_body->message_Param0; + + TRACE(4," %s evt: %d, arg0: %d , anc status :%d", __func__, evt, arg0, anc_work_status); + + switch (evt) + { + case ANC_EVENT_INIT: + //init anc_timer + app_anc_init_timer(); + //init anc&open codec +#ifdef __AUDIO_SECTION_SUPPT__ + anc_load_cfg(); +#endif + +#ifdef __ANC_INIT_ON__ + app_anc_open_anc(); + anc_work_status = ANC_STATUS_INIT_ON; + app_anc_timer_set(ANC_EVENT_CLOSE, anc_init_switch_off_time); +#else + anc_work_status = ANC_STATUS_OFF; +#endif +#ifdef __ANC_STICK_SWITCH_USE_GPIO__ + if (app_anc_switch_get_val() == ANC_SWITCH_ON_LEVEL) + { + app_anc_switch_set_edge(ANC_SWITCH_ON_LEVEL); + app_anc_status_post(ANC_SWITCH_ON_LEVEL); + } + else + { + app_anc_switch_set_edge(!(bool)ANC_SWITCH_ON_LEVEL); + } +#endif + //anc_coef_idx = 0; + anc_fade_thread_tid = osThreadCreate(osThread(anc_fade_thread),NULL); + break; + case ANC_EVENT_FADE_IN: + case ANC_EVENT_FADE_OUT: + anc_gain_fade_handle(); + if (evt == ANC_EVENT_FADE_IN) + { + anc_work_status = ANC_STATUS_ON; + //recommand to play "ANC ON" prompt here... + } + if (evt == ANC_EVENT_FADE_OUT) + { + anc_work_status = ANC_STATUS_INIT_ON; + //recommand to play "ANC OFF" prompt here... + } + break; + case ANC_EVENT_CHANGE_SAMPLERATE: + app_anc_bitrate_reopen(); + break; + case ANC_EVENT_CHANGE_STATUS: + +#ifdef __ANC_STICK_SWITCH_USE_GPIO__ + osDelay(10); + if (app_anc_switch_get_val() != (bool)arg0) + { //debonce + TRACE(0,"io level not equeue exit"); + break; + } + +#ifdef __SUPPORT_ANC_SINGLE_MODE_WITHOUT_BT__ + if (anc_single_mode_is_on()) + { + if (arg0 != ANC_SWITCH_ON_LEVEL) + { + TRACE(1," Anc ON but exit %d ", app_init_done); + if (app_init_done) + { + app_anc_shutdown = true; + app_shutdown(); + } + else + { + app_anc_timer_set(ANC_EVENT_SWITCH_KEY_DEBONCE, anc_switch_key_debonce_time); + } + return 0; + } + } +#endif + if (arg0 != ANC_SWITCH_ON_LEVEL) + app_anc_switch_set_edge((!(bool)ANC_SWITCH_ON_LEVEL)); + else + app_anc_switch_set_edge(ANC_SWITCH_ON_LEVEL); + + if (((arg0 == ANC_SWITCH_ON_LEVEL) && (anc_work_status == ANC_STATUS_ON)) || + ((arg0 != ANC_SWITCH_ON_LEVEL) && (anc_work_status == ANC_STATUS_OFF))) + { + //status same, no handle + TRACE(0," Anc NOT ON, exit"); + return 0; + } +#endif + +#if defined(IBRT) + if(((BOOL)arg0 == false) && (app_anc_work_status() == false)) + { + anc_coef_idx = 0; + anc_peer_coef_idx = 0; + anc_status_sync_flag = 0; + return 0; + } + + if(((BOOL)arg0 == true) && (app_anc_work_status() == true) && (anc_coef_idx == anc_peer_coef_idx)) + { + anc_status_sync_flag = 0; + return 0; + } +#endif + app_anc_status_change(); + + break; + case ANC_EVENT_SYNC_STATUS: +#if defined(IBRT) + TRACE(4,"%s anc_work_status %d--->%d anc_coef_idx:%d ", __func__, anc_work_status, arg0, anc_coef_idx); + + if(ANC_STATUS_ON == arg0) + { + arg0 = 1; + } + else + { + arg0 = 0; + } + + uint8_t buf[3] = {0}; + buf[0] = (uint8_t)arg0; + buf[1] = (uint8_t)anc_coef_idx; + buf[2] = false;//set peer anc_status_sync_flag = false + tws_ctrl_send_cmd(APP_TWS_CMD_SYNC_ANC_STATUS, buf, 3); +#endif + break; + case ANC_EVENT_SYNC_INIT:break; + case ANC_EVENT_HOWL_PROCESS: + //disable anc,set max gain,enable anc + { + //uint32_t howl = arg0; + if (anc_work_status == ANC_STATUS_ON) + { + //__anc_usb_app_howl_set_gain(howl); + } + } + break; +#ifdef __SUPPORT_ANC_SINGLE_MODE_WITHOUT_BT__ + case ANC_EVENT_PWR_KEY_MONITOR: + osDelay(10); + + if (app_pwr_key_monitor_get_val() != (bool)arg0) //debonce + return 0; + + if ((bool)arg0) + { + app_anc_timer_set(ANC_EVENT_PWR_KEY_MONITOR_REBOOT, anc_pwr_key_monitor_time); + app_pwr_key_monitor_set_int_edge(1); + } + else + { + hwtimer_stop(anc_timerid); + app_pwr_key_monitor_set_int_edge(0); + } + + break; +#endif + case SIMPLE_PLAYER_DELAY_STOP_EVT: +#ifdef __SIMPLE_INTERNAL_PLAYER_SUPPORT__ + simple_player_delay_stop(); +#endif + break; + case SIMPLE_PLAYER_CLOSE_CODEC_EVT: + app_anc_close_anc(); + anc_work_status = ANC_STATUS_OFF; + break; + default:break; + } + + return 0; +} + +static void anc_gain_fade_timer_handler(void *p) +{ + TRACE(2," %s , request %d ", __func__, anc_timer_request); + switch (anc_timer_request) + { + case ANC_EVENT_OPEN: + app_anc_gain_fadein(); + break; + case ANC_EVENT_CLOSE: + //real close + //app_anc_close_anc(); + //anc_work_status = ANC_STATUS_OFF; + app_anc_post_anc_codec_close(); + + break; + case ANC_EVENT_PWR_KEY_MONITOR_REBOOT: + TRACE(0," reboot !"); + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_REBOOT); + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_REBOOT_ANC_ON); + hal_sw_bootmode_set(HAL_SW_BOOTMODE_REBOOT_BT_ON); + app_reset(); + break; + case ANC_EVENT_SWITCH_KEY_DEBONCE: + TRACE(0," ANC SWITCH KEY "); +#ifdef __ANC_STICK_SWITCH_USE_GPIO__ + if (app_switch_callback) + app_switch_callback(hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)ANC_SWITCH_PIN)); +#endif + break; + default: + break; + } + anc_timer_request = ANC_EVENT_NONE; + hwtimer_stop(anc_timerid); +} + +void app_anc_init_timer(void) +{ + if (anc_timerid == NULL) + anc_timerid = hwtimer_alloc((HWTIMER_CALLBACK_T)anc_gain_fade_timer_handler, &anc_timer_request); +} + +void app_anc_timer_set(uint32_t request, uint32_t delay) +{ + TRACE(3," %s request %d , delay %ds ", __func__, request, (TICKS_TO_MS(delay) / 1000)); + if (anc_timerid == NULL) + return; + anc_timer_request = request; + hwtimer_stop(anc_timerid); + hwtimer_start(anc_timerid, delay); +} + +void app_anc_timer_close(void) +{ + TRACE(3," %s enter...", __func__); + if (anc_timerid == NULL) + { + return; + } + + anc_timer_request = ANC_EVENT_NONE; + hwtimer_stop(anc_timerid); +} + +#if defined(IBRT) +void app_anc_cmd_receive_process(uint8_t *buf, uint16_t len) +{ + TRACE(1, "[%s] enter...", __func__); + + if(buf[0] == IBRT_ACTION_ANC_NOTIRY_MASTER_EXCHANGE_COEF) + { + switch(buf[1]) + { +#ifdef __BT_ANC_KEY__ + case 0:app_anc_key(NULL, NULL);break;//slave invoke app_anc_key(); +#endif +#ifndef __BT_ANC_KEY__ + case 1:app_anc_start();break;//slave invoke app_anc_start(); + case 2:app_anc_switch_coef(buf[2]);break;//slave invoke app_anc_switch_coef(); + case 3:app_anc_stop();break;//slave invoke app_anc_stop(); +#endif + default:TRACE(1, "[%s] cmd invalid...", __func__);break; + } + } +} + +static void app_anc_notify_master_to_exchange_coef(uint8_t arg0, uint8_t arg1) +{ + uint8_t buf[3] = {0}; + + TRACE(3,"[%s] arg0:%d arg1:%d", __func__, arg0, arg1); + + buf[0] = IBRT_ACTION_ANC_NOTIRY_MASTER_EXCHANGE_COEF; + buf[1] = arg0; + buf[2] = arg1; + + app_ibrt_ui_send_user_action(buf, 3); +} +#endif + +#ifdef __BT_ANC_KEY__ +void app_anc_key(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s anc_work_st:%d , timer:%d", __func__, anc_work_status, anc_timer_request); + bool flag = app_anc_work_status(); + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + TRACE(2,"[%s] current_role: %d", __func__, p_ibrt_ctrl->current_role); + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + app_anc_notify_master_to_exchange_coef(0,0); + return; + } + app_anc_status_sync(!flag); +#endif + app_anc_status_post(!flag); +} +#endif + +#ifndef __BT_ANC_KEY__ +int app_anc_start(void) +{ + TRACE(1,"[%s] enter...", __func__); + bool flag = app_anc_work_status(); + + if(flag == true) + { + TRACE(1,"[%s] anc has been on...", __func__); + return -1; + } + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + TRACE(2,"[%s] current_role: %d", __func__, p_ibrt_ctrl->current_role); + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + app_anc_notify_master_to_exchange_coef(1,0); + return -1; + } + anc_coef_idx = 0; + app_anc_status_sync(!flag); +#endif + anc_coef_idx = 0; + app_anc_status_post(!flag); + + return 0; +} + +int app_anc_switch_coef(uint8_t index) +{ + TRACE(1,"[%s] enter...", __func__); + bool flag = app_anc_work_status(); + + if(flag == false) + { + TRACE(1,"[%s] anc has been off...", __func__); + return -1; + } + + if(index == anc_coef_idx) + { + TRACE(1,"[%s] anc coef has been load...", __func__); + return -1; + } + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + TRACE(2,"[%s] current_role: %d", __func__, p_ibrt_ctrl->current_role); + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + app_anc_notify_master_to_exchange_coef(2,index); + return -1; + } + anc_coef_idx = index; + app_anc_status_sync(!flag); +#endif + anc_coef_idx = index; + app_anc_status_post(!flag); + + return 0; +} + +int app_anc_stop(void) +{ + TRACE(1,"[%s] enter...", __func__); + bool flag = app_anc_work_status(); + + if(flag == false) + { + TRACE(1,"[%s] anc has been off...", __func__); + return -1; + } + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + TRACE(2,"[%s] current_role: %d", __func__, p_ibrt_ctrl->current_role); + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + app_anc_notify_master_to_exchange_coef(3,0); + return -1; + } + anc_coef_idx = ANC_COEF_NUM; + app_anc_status_sync(!flag); +#endif + anc_coef_idx = ANC_COEF_NUM; + app_anc_status_post(!flag); + + return 0; +} +#endif + +void app_anc_ios_init(void) +{ +#ifdef __ANC_STICK_SWITCH_USE_GPIO__ + if (cfg_anc_switch.pin != HAL_IOMUX_PIN_NUM) + { + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&cfg_anc_switch, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)cfg_anc_switch.pin, HAL_GPIO_DIR_IN, 0); + } +#endif +#ifdef __SUPPORT_ANC_SINGLE_MODE_WITHOUT_BT__ + if (cfg_pwr_key_monitor.pin != HAL_IOMUX_PIN_NUM) + { + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&cfg_pwr_key_monitor, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)cfg_pwr_key_monitor.pin, HAL_GPIO_DIR_IN, 0); + } + if (cfg_anc_led.pin != HAL_IOMUX_PIN_NUM) + { + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&cfg_anc_led, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)cfg_anc_led.pin, HAL_GPIO_DIR_OUT, 0); + } + +#endif +#ifdef ANC_SWITCH_PIN + uint8_t gpio_val = hal_gpio_pin_get_val(ANC_SWITCH_PIN); + if (gpio_val) + { + app_anc_switch_turnled(true); + TRACE(1," %s turn on led", __func__); + } + else + { + app_anc_switch_turnled(false); + TRACE(1," %s turn off led", __func__); + } +#endif +} + +int app_anc_open_module(void) +{ + TRACE(1,"%s ", __func__); + //set app module + app_set_threadhandle(APP_MODUAL_ANC, app_anc_handle_process); + app_anc_do_init(); +#ifdef __ANC_STICK_SWITCH_USE_GPIO__ + app_anc_switch_init(app_anc_status_post); + app_anc_switch_set_edge(app_anc_switch_get_val()); +#endif +#ifdef __SUPPORT_ANC_SINGLE_MODE_WITHOUT_BT__ + if (anc_single_mode_is_on()) + { + // app_pwr_key_monitor_init(app_anc_send_pwr_key_monitor_evt); + // app_pwr_key_monitor_set_int_edge(app_pwr_key_monitor_get_val()); + } +#endif + + return 0; +} + +int app_anc_close_module(void) +{ + TRACE(1," %s ", __func__); + + anc_timer_request = ANC_EVENT_NONE; + if (anc_timerid) + { + hwtimer_stop(anc_timerid); + hwtimer_free(anc_timerid); + anc_timerid = NULL; + } + if (app_anc_get_anc_status() != ANC_STATUS_OFF) + { + anc_work_status = ANC_STATUS_OFF; + app_anc_disable(); + app_anc_close_anc(); + } + app_set_threadhandle(APP_MODUAL_ANC, NULL); + return 0; +} + +enum AUD_SAMPRATE_T app_anc_get_play_rate(void) +{ + return anc_sample_rate[AUD_STREAM_PLAYBACK]; +} + +bool app_anc_work_status(void) +{ + // TRACE(2," %s st %d", __func__, anc_work_status); + return (anc_work_status == ANC_STATUS_ON || anc_work_status == ANC_STATUS_WAITING_ON); +} + +uint32_t app_anc_get_anc_status(void) +{ + return anc_work_status; +} + +void test_anc(void) +{ + app_anc_open_anc(); + app_anc_enable(); +} + +void test_anc_switch_coef(void) +{ + anc_coef_idx++; + + TRACE(2," %s set coef idx: %d ", __func__, anc_coef_idx); + + if (ANC_STATUS_OFF == anc_work_status || ANC_STATUS_INIT_ON == anc_work_status) + { + app_anc_status_change(); + anc_coef_idx = 0; + return; + } + if (anc_coef_idx < (ANC_COEF_LIST_NUM)) + { +#ifdef ANC_FF_ENABLED + while (__anc_usb_app_fadeout(ANC_FEEDFORWARD)) + ; +#endif +#ifdef ANC_FB_ENABLED + while (__anc_usb_app_fadeout(ANC_FEEDBACK)) + ; +#endif + + app_anc_disable(); + anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],anc_coef_idx,ANC_FEEDFORWARD,ANC_GAIN_DELAY); + app_anc_enable(); + +#ifdef ANC_FF_ENABLED + while (__anc_usb_app_fadein(ANC_FEEDFORWARD)) + ; +#endif +#ifdef ANC_FB_ENABLED + while (__anc_usb_app_fadein(ANC_FEEDBACK)) + ; +#endif + } + else + { + anc_coef_idx = 0; + app_anc_timer_set(ANC_EVENT_CLOSE, anc_close_delay_time); + app_anc_gain_fadeout(); + anc_work_status = ANC_STATUS_WAITING_OFF; + } +} + +#if defined(IBRT) +void app_anc_sync_status(void) +{ + uint8_t buf[3] = {0}; + + bool flag = app_anc_work_status(); + + buf[0] = (uint8_t)flag; + + if(flag == true) + { + buf[1] = (uint8_t)anc_coef_idx; + } + else + { + buf[1] = (uint8_t)ANC_COEF_NUM; + } + + buf[2] = true;//set peer anc_status_sync_flag = true + + anc_peer_coef_idx = 0; + + TRACE(4,"%s anc_work_status:%d, anc_coef_idx:%d, anc_sync_status_flag:%d", __func__, buf[0], buf[1], buf[2]); + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (p_ibrt_ctrl->current_role == IBRT_MASTER) + { + tws_ctrl_send_cmd(APP_TWS_CMD_SYNC_ANC_STATUS, buf, 3); + } +} +#endif + diff --git a/apps/anc/src/peak_detector.c b/apps/anc/src/peak_detector.c new file mode 100644 index 0000000..f40766a --- /dev/null +++ b/apps/anc/src/peak_detector.c @@ -0,0 +1,196 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "math.h" +#include "peak_detector.h" + +// #define PKD_FACTOR_UP (0.6) +// #define PKD_FACTOR_DOWN (2.0) +// #define PKD_REDUCE_RATE (0.0335) // -30dB + +static enum AUD_BITS_T pkd_samp_bits; +static float pkd_alphaR = 0.0f; +static float pkd_alphaA = 0.0f; +static float pkd_factor1 = 0.0f; +static float pkd_factor2 = 0.0f; +static float pkd_reduce_rate = 1.0f; + +#define FABS(x) ( (x) >= 0.f ? (x) : -(x) ) +#define Max(a,b) ((a)>(b) ? (a):(b)) + +// Depend on codec_dac_vol +// const float pkd_vol_multiple[18] = {0.089125, 0.0, 0.005623, 0.007943, 0.011220, 0.015849, 0.022387, 0.031623, 0.044668, 0.063096, 0.089125, 0.125893, 0.177828, 0.251189, 0.354813, 0.501187, 0.707946, 1.000000}; + +// static uint32_t test_num = 0; + +// int app_bt_stream_local_volume_get(void); + +// y = 20log(x) +static inline float convert_multiple_to_db(float multiple) +{ + return 20*(float)log10(multiple); +} + +// x = 10^(y/20) +static inline float convert_db_to_multiple(float db) +{ + return (float)pow(10, db/20); +} + +void peak_detector_init(void) +{ + pkd_alphaR = 0.0f; + pkd_alphaA = 0.0f; + pkd_factor1 = 0.0f; + pkd_factor2 = 0.0f; + pkd_reduce_rate = 1.0f; + // TRACE(3,"[%s] pkd_alphaR = %f, pkd_alphaA = %f", __func__, (double)pkd_alphaR, (double)pkd_alphaA); +} + +void peak_detector_setup(PEAK_DETECTOR_CFG_T *cfg) +{ + pkd_samp_bits = cfg->bits; + pkd_alphaR = (float)exp(-1/(cfg->factor_down * cfg->fs)); + pkd_alphaA = (float)exp(-1/(cfg->factor_up * cfg->fs)); + pkd_reduce_rate = convert_db_to_multiple(cfg->reduce_dB); +} + +static void peak_detector_run_16bits(int16_t *buf, uint32_t len, float vol_multiple) +{ + float normal_rate = 1.0; + float tgt_rate = 1.0; + + for(uint32_t i = 0; i < len; i++) + { + pkd_factor1 = Max(buf[i], pkd_alphaR * pkd_factor1); + pkd_factor2 = pkd_alphaA * pkd_factor2 + (1 - pkd_alphaA) * pkd_factor1; + + normal_rate = pkd_factor2/32768; + + tgt_rate = pkd_reduce_rate / normal_rate / vol_multiple; + + if(tgt_rate > 1.0) + { + tgt_rate = 1.0; + } + + // rate += (tgt_rate - rate) / 10000.0; + + // if(pkd_factor2>) + // { + // normal_rate = 0.25; + // } + // else + // { + // normal_rate = 0.25; + // } + // normal_rate *= 1.0 - pkd_factor2/32768; + + buf[i] = (int16_t)(buf[i] * tgt_rate); + // buf[i] = 0; + // + // TRACE(2,"%d, %d", buf[i], pkd_factor2); + } + + // if(test_num == 500) + // { + // test_num = 0; + // TRACE(0,"START>>>"); + // TRACE(2,"vol_level = %d, pkd_vol_multiple = %f", vol_level, pkd_vol_multiple[vol_level]); + // TRACE(3,"buf = %d, pkd_alphaR = %f, pkd_alphaA = %f", buf[len-1], pkd_alphaR, pkd_alphaA); + // TRACE(4,"pkd_factor1 = %f, pkd_factor2 = %f, normal_rate = %f, tgt_rate = %f", pkd_factor1, pkd_factor2, normal_rate, tgt_rate); + // TRACE(0,"END<<<"); + // // TRACE(7,"[%s] buf = %d, pkd_alphaR = %f, pkd_alphaA = %f, pkd_factor1 = %f, pkd_factor2 = %f, normal_rate = %f", __func__, buf[len-1], pkd_alphaR, pkd_alphaA, pkd_factor1, pkd_factor2, (1.0 - pkd_factor2/32768)); + // } + +#if 0 + short sample; + short sample_max = 0; + short sample_min = 0; + + for (uint32_t i = 0; i < len; i++) + { + sample = buf[i]; + if(sample > sample_max) + { + sample_max = sample; + } + + if(sample < sample_min) + { + sample_min = sample; + } + } + + + TRACE(2,"Max = %10d, Min = %10d",sample_max, sample_min); +#endif +} + +static void peak_detector_run_24bits(int32_t *buf, uint32_t len, float vol_multiple) +{ + float normal_rate = 1.0; + float tgt_rate = 1.0; + + for(uint32_t i = 0; i < len; i++) + { + pkd_factor1 = Max(buf[i], pkd_alphaR * pkd_factor1); + pkd_factor2 = pkd_alphaA * pkd_factor2 + (1 - pkd_alphaA) * pkd_factor1; + + normal_rate = pkd_factor2/32768; + + tgt_rate = pkd_reduce_rate / normal_rate / vol_multiple; + + if(tgt_rate > 1.0) + { + tgt_rate = 1.0; + } + + // rate += (tgt_rate - rate) / 10000.0; + + // if(pkd_factor2>) + // { + // normal_rate = 0.25; + // } + // else + // { + // normal_rate = 0.25; + // } + // normal_rate *= 1.0 - pkd_factor2/32768; + + buf[i] = (int32_t)(buf[i] * tgt_rate); + // buf[i] = 0; + // + // TRACE(2,"%d, %d", buf[i], pkd_factor2); + } +} + +void peak_detector_run(uint8_t *buf, uint32_t len, float vol_multiple) +{ + // int vol_level = 0; + + if (pkd_samp_bits <= AUD_BITS_16) { + len = len / sizeof(int16_t); + peak_detector_run_16bits((int16_t *)buf, len, vol_multiple); + } else { + len = len / sizeof(int32_t); + peak_detector_run_24bits((int32_t *)buf, len, vol_multiple); + } + + // test_num++; + + // vol_level = app_bt_stream_local_volume_get(); +} + diff --git a/apps/apptester/Makefile b/apps/apptester/Makefile new file mode 100644 index 0000000..0453beb --- /dev/null +++ b/apps/apptester/Makefile @@ -0,0 +1,176 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +ifeq ($(ANC_APP),1) +obj-y += ../../tests/anc_usb/anc_usb_app.c +endif +obj-y += ../../tests/anc_usb/usb_audio_app.c +obj-y += ../../tests/anc_usb/safe_queue.c +obj-y += ../../tests/anc_usb/memutils.c +obj-y += ../../tests/anc_usb/speech_process.c +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +subdir-ccflags-y += \ + -Iutils/cqueue \ + -Iplatform/drivers/ana \ + -Iservices/audio_process \ + -Iservices/multimedia/rbcodec/inc \ + -Iservices/multimedia/audio/process/anc/include \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/audio/process/resample/include \ + -Iservices/multimedia/speech/inc \ + -Iservices/nv_section/include \ + -Iservices/nv_section/aud_section \ + -Iplatform/drivers/usb/usb_dev/inc \ + -Itests/anc_usb \ + -Iutils/hwtimer_list + +CFLAGS_usb_audio_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) +CFLAGS_adda_loop_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) + +ifeq ($(APP_TEST_AUDIO),1) +ccflags-y += -DAPP_TEST_AUDIO +endif + +ANC_USB_CFG_FLAGS := + +# ANC option +ifeq ($(ANC_APP),1) +ANC_USB_CFG_FLAGS += -DANC_APP +endif + +# USB audio option +ifeq ($(USB_AUDIO_APP),1) +ANC_USB_CFG_FLAGS += -DUSB_AUDIO_APP +endif + +ifeq ($(USB_HIGH_SPEED),1) +ANC_USB_CFG_FLAGS += -DUSB_HIGH_SPEED +endif + +ifeq ($(AUDIO_RESAMPLE),1) +ANC_USB_CFG_FLAGS += -D__AUDIO_RESAMPLE__ +endif + +ifeq ($(ADC_CH_SEP_BUFF),1) +ANC_USB_CFG_FLAGS += -DADC_CH_SEP_BUFF +endif + +include platform/drivers/usb/usb_dev/uaud_cfg_flags.mk + +platform/drivers/usb/usb_dev/uaud_cfg_flags.mk: ; + +ANC_USB_CFG_FLAGS += $(UAUD_CFG_FLAGS) + +# USB audio configuration +ifeq ($(USB_AUDIO_DYN_CFG),1) +ifneq ($(AUDIO_RESAMPLE),1) +SW_CAPTURE_RESAMPLE ?= 1 +endif +endif + +ifeq ($(AUDIO_PLAYBACK_24BIT),1) +ANC_USB_CFG_FLAGS += -DAUDIO_PLAYBACK_24BIT +endif + +# DSD configuration +ifeq ($(HW_FIR_DSD_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__HW_FIR_DSD_PROCESS__ +endif + +# EQ configuration +ifeq ($(HW_FIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__HW_FIR_EQ_PROCESS__ +endif + +ifeq ($(HW_IIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__HW_IIR_EQ_PROCESS__ +endif + +ifeq ($(SW_IIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__SW_IIR_EQ_PROCESS__ +endif + +ifeq ($(SW_CAPTURE_RESAMPLE),1) +ANC_USB_CFG_FLAGS += -DSW_CAPTURE_RESAMPLE +endif + +CFLAGS_app_audtest.o += $(ANC_USB_CFG_FLAGS) +CFLAGS_usb_audio_app.o += $(ANC_USB_CFG_FLAGS) +CFLAGS_anc_usb_app.o += $(ANC_USB_CFG_FLAGS) + +ifeq ($(ANC_KEY_DOUBLE_CLICK_ON_OFF),1) +CFLAGS_anc_usb_app.o += -DANC_KEY_DOUBLE_CLICK_ON_OFF +endif + +ifeq ($(ANC_FF_ENABLED),1) +CFLAGS_anc_usb_app.o += -DANC_FF_ENABLED +endif + +ifeq ($(ANC_FB_ENABLED),1) +CFLAGS_anc_usb_app.o += -DANC_FB_ENABLED +endif + +ifeq ($(AUDIO_SECTION_SUPPT),1) +CFLAGS_anc_usb_app.o += -D__AUDIO_SECTION_SUPPT__ +endif + +ifeq ($(ANC_INIT_OFF),1) +CFLAGS_anc_usb_app.o += -DANC_INIT_OFF +endif + +ifeq ($(PC_CMD_UART),1) +CFLAGS_app_audtest.o += -D__PC_CMD_UART__ +endif + +ifeq ($(DELAY_STREAM_OPEN),1) +CFLAGS_usb_audio_app.o += -DDELAY_STREAM_OPEN +endif + +ifeq ($(NOISE_GATING),1) +CFLAGS_usb_audio_app.o += -DNOISE_GATING +endif + +ifeq ($(NOISE_REDUCTION),1) +CFLAGS_usb_audio_app.o += -DNOISE_REDUCTION +endif + +ifeq ($(ANC_L_R_MISALIGN_WORKAROUND),1) +CFLAGS_usb_audio_app.o += -DANC_L_R_MISALIGN_WORKAROUND +endif + +ifeq ($(ANDROID_ACCESSORY_SPEC),1) +CFLAGS_usb_audio_app.o += -DANDROID_ACCESSORY_SPEC +ifeq ($(ANDROID_VOICE_CMD_KEY),1) +CFLAGS_usb_audio_app.o += -DANDROID_VOICE_CMD_KEY +endif +endif + +ifeq ($(DUAL_AUX_MIC_MORE_FILTER),1) +CFLAGS_usb_audio_app.o += -DDUAL_AUX_MIC_MORE_FILTER +endif + +ifeq ($(FREQ_RESP_EQ),1) +CFLAGS_usb_audio_app.o += -DFREQ_RESP_EQ +endif + +ifeq ($(KEEP_SAME_LATENCY),1) +CFLAGS_usb_audio_app.o += -DKEEP_SAME_LATENCY +endif + +ifeq ($(USB_AUDIO_PWRKEY_TEST),1) +CFLAGS_usb_audio_app.o += -DUSB_AUDIO_PWRKEY_TEST +endif + +ifeq ($(AUDIO_RESAMPLE),1) +# If neither best1000 nor best2000 +ifeq ($(filter best1000 best2000,$(CHIP)),) +PLL_TUNE_SAMPLE_RATE ?= 1 +endif +ifeq ($(PLL_TUNE_SAMPLE_RATE),1) +CFLAGS_usb_audio_app.o += -DPLL_TUNE_SAMPLE_RATE +endif +endif + diff --git a/apps/apptester/app_audtest.cpp b/apps/apptester/app_audtest.cpp new file mode 100644 index 0000000..b48b306 --- /dev/null +++ b/apps/apptester/app_audtest.cpp @@ -0,0 +1,307 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "app_thread.h" + +#include "hal_timer.h" +#include "app_audtest_pattern.h" + +#include "hal_aud.h" +#include "audioflinger.h" +#include "audiobuffer.h" +#include "stdbool.h" +#include +#include "eq_export.h" +#include "app_utils.h" + +#if defined(APP_TEST_AUDIO) && defined(ANC_APP) +#include "anc_usb_app.h" +#include "usb_audio_app.h" +#include "usb_audio_frm_defs.h" +//#include "dualadc_audio_app.h" +#endif + +#define USB_AUDIO_PLAYBACK_BUFF_SIZE (FRAME_SIZE_PLAYBACK * 4) +#define USB_AUDIO_CAPTURE_BUFF_SIZE (FRAME_SIZE_CAPTURE * 4) + +#define USB_AUDIO_RECV_BUFF_SIZE (FRAME_SIZE_RECV * 8) +#define USB_AUDIO_SEND_BUFF_SIZE (FRAME_SIZE_SEND * 8) + +#define APP_TEST_PLAYBACK_BUFF_SIZE (128 * 20) +#define APP_TEST_CAPTURE_BUFF_SIZE (128 * 20) + +#if (USB_AUDIO_PLAYBACK_BUFF_SIZE > APP_TEST_PLAYBACK_BUFF_SIZE) +#define REAL_PLAYBACK_BUFF_SIZE USB_AUDIO_PLAYBACK_BUFF_SIZE +#else +#define REAL_PLAYBACK_BUFF_SIZE APP_TEST_PLAYBACK_BUFF_SIZE +#endif + +#if (USB_AUDIO_CAPTURE_BUFF_SIZE > APP_TEST_CAPTURE_BUFF_SIZE) +#define REAL_CAPTURE_BUFF_SIZE USB_AUDIO_CAPTURE_BUFF_SIZE +#else +#define REAL_CAPTURE_BUFF_SIZE APP_TEST_CAPTURE_BUFF_SIZE +#endif + +#define ALIGNED4 ALIGNED(4) + +static uint8_t ALIGNED4 app_test_playback_buff[REAL_PLAYBACK_BUFF_SIZE]; +static uint8_t ALIGNED4 app_test_capture_buff[REAL_CAPTURE_BUFF_SIZE]; + +#if defined(APP_TEST_AUDIO) && defined(ANC_APP) +static uint8_t ALIGNED4 app_test_recv_buff[USB_AUDIO_RECV_BUFF_SIZE]; +static uint8_t ALIGNED4 app_test_send_buff[USB_AUDIO_SEND_BUFF_SIZE]; +#endif + +uint32_t pcm_1ksin_more_data(uint8_t *buf, uint32_t len) +{ + static uint32_t nextPbufIdx = 0; + uint32_t remain_size = len; + uint32_t curr_size = 0; + static uint32_t pcm_preIrqTime = 0;; + uint32_t stime = 0; + + + stime = hal_sys_timer_get(); + TRACE(3,"pcm_1ksin_more_data irqDur:%d readbuff:0x%08x %d\n ", TICKS_TO_MS(stime - pcm_preIrqTime), buf, len); + pcm_preIrqTime = stime; + + // TRACE(2,"[pcm_1ksin_more_data] len=%d nextBuf:%d\n", len, nextPbufIdx); + if (remain_size > sizeof(sinwave)) + { + do{ + if (nextPbufIdx) + { + curr_size = sizeof(sinwave)-nextPbufIdx; + memcpy(buf,&sinwave[nextPbufIdx/2], curr_size); + remain_size -= curr_size; + nextPbufIdx = 0; + } + else if (remain_size>sizeof(sinwave)) + { + memcpy(buf+curr_size,sinwave,sizeof(sinwave)); + curr_size += sizeof(sinwave); + remain_size -= sizeof(sinwave); + } + else + { + memcpy(buf+curr_size,sinwave,remain_size); + nextPbufIdx = remain_size; + remain_size = 0; + } + }while(remain_size); + } + else + { + if ((sizeof(sinwave) - nextPbufIdx) >= len) + { + memcpy(buf, &sinwave[nextPbufIdx/2],len); + nextPbufIdx += len; + } + else + { + curr_size = sizeof(sinwave)-nextPbufIdx; + memcpy(buf, &sinwave[nextPbufIdx/2],curr_size); + nextPbufIdx = len - curr_size; + memcpy(buf+curr_size,sinwave, nextPbufIdx); + } + } + + return 0; +} + +uint32_t pcm_mute_more_data(uint8_t *buf, uint32_t len) +{ + memset(buf, 0 , len); + return 0; +} + +void da_output_sin1k(bool on) +{ + static bool isRun = false; + struct AF_STREAM_CONFIG_T stream_cfg; + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + if (isRun==on) + return; + else + isRun=on; + TRACE(2,"%s %d\n", __func__, on); + + if (on){ + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; + stream_cfg.sample_rate = AUD_SAMPRATE_44100; + + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.vol = 16; + + stream_cfg.handler = pcm_1ksin_more_data; + stream_cfg.data_ptr = app_test_playback_buff; + stream_cfg.data_size = APP_TEST_PLAYBACK_BUFF_SIZE; + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + }else{ + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + } + +} + +void da_tester(uint8_t on) +{ + da_output_sin1k(on); +} + +extern int voicecvsd_audio_init(void); +extern uint32_t voicecvsd_audio_more_data(uint8_t *buf, uint32_t len); +extern int get_voicecvsd_buffer_size(void); +extern int store_voice_pcm2cvsd(unsigned char *buf, unsigned int len); + +static uint32_t pcm_data_capture(uint8_t *buf, uint32_t len) +{ + uint32_t stime, etime; + static uint32_t preIrqTime = 0; + + stime = hal_sys_timer_get(); +// audio_buffer_set_stereo2mono_16bits(buf, len, 1); + audio_buffer_set(buf, len); + etime = hal_sys_timer_get(); + TRACE(4,"%s irqDur:%d fsSpend:%d, Len:%d", __func__, TICKS_TO_MS(stime - preIrqTime), TICKS_TO_MS(etime - stime), len); + preIrqTime = stime; + return 0; +} + +static uint32_t pcm_data_playback(uint8_t *buf, uint32_t len) +{ + uint32_t stime, etime; + static uint32_t preIrqTime = 0; + stime = hal_sys_timer_get(); +// audio_buffer_get_mono2stereo_16bits(buf, len); + audio_buffer_get(buf, len); + etime = hal_sys_timer_get(); + TRACE(4,"%s irqDur:%d fsSpend:%d, Len:%d", __func__, TICKS_TO_MS(stime - preIrqTime), TICKS_TO_MS(etime - stime), len); + preIrqTime = stime; + return 0; +} + +uint32_t pcm_cvsd_data_capture(uint8_t *buf, uint32_t len) +{ + uint32_t stime, etime; + static uint32_t preIrqTime = 0; + + //TRACE(1,"%s enter", __func__); + stime = hal_sys_timer_get(); + len >>= 1; + audio_stereo2mono_16bits(0, (uint16_t *)buf, (uint16_t *)buf, len); + store_voice_pcm2cvsd(buf, len); + etime = hal_sys_timer_get(); + TRACE(4,"%s exit irqDur:%d fsSpend:%d, add:%d", __func__, TICKS_TO_MS(stime - preIrqTime), TICKS_TO_MS(etime - stime), len); + preIrqTime = stime; + return 0; +} + +uint32_t pcm_cvsd_data_playback(uint8_t *buf, uint32_t len) +{ + int n; + uint32_t stime, etime; + static uint32_t preIrqTime = 0; + + //TRACE(1,"%s enter", __func__); + stime = hal_sys_timer_get(); + pcm_1ksin_more_data(buf, len); + voicecvsd_audio_more_data(buf, len); + n = get_voicecvsd_buffer_size(); + etime = hal_sys_timer_get(); + TRACE(5,"%s exit irqDur:%d fsSpend:%d, get:%d remain:%d", __func__, TICKS_TO_MS(stime - preIrqTime), TICKS_TO_MS(etime - stime), len, n); + preIrqTime = stime; + return 0; +} + +void adc_looptester(bool on, enum AUD_IO_PATH_T input_path, enum AUD_SAMPRATE_T sample_rate) +{ + struct AF_STREAM_CONFIG_T stream_cfg; + + static bool isRun = false; + + if (isRun==on) + return; + else + isRun=on; + + if (on){ + audio_buffer_init(); + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; + stream_cfg.sample_rate = sample_rate; + + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.io_path = input_path; + stream_cfg.vol = 0x03; + + stream_cfg.handler = pcm_data_capture; + + stream_cfg.data_ptr = app_test_capture_buff; + stream_cfg.data_size = APP_TEST_CAPTURE_BUFF_SIZE; + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + + stream_cfg.handler = pcm_data_playback; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + + stream_cfg.data_ptr = app_test_playback_buff; + stream_cfg.data_size = APP_TEST_PLAYBACK_BUFF_SIZE; + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + }else{ + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + } +} + +#if defined(APP_TEST_AUDIO) && defined(ANC_APP) +void app_anc_usb_init(void) +{ + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_52M); + + anc_usb_app_init(AUD_INPUT_PATH_MAINMIC, AUD_SAMPRATE_96000, AUD_SAMPRATE_192000); + + struct USB_AUDIO_BUF_CFG cfg; + + memset(&cfg, 0, sizeof(cfg)); + cfg.play_buf = app_test_playback_buff; + cfg.play_size = USB_AUDIO_PLAYBACK_BUFF_SIZE; + cfg.cap_buf = app_test_capture_buff; + cfg.cap_size = USB_AUDIO_CAPTURE_BUFF_SIZE; + cfg.recv_buf = app_test_recv_buff; + cfg.recv_size = USB_AUDIO_RECV_BUFF_SIZE; + cfg.send_buf = app_test_send_buff; + cfg.send_size = USB_AUDIO_SEND_BUFF_SIZE; + + usb_audio_app_init(&cfg); + + //dualadc_audio_app_init(app_test_playback_buff, USB_AUDIO_PLAYBACK_BUFF_SIZE, + //app_test_capture_buff, USB_AUDIO_CAPTURE_BUFF_SIZE); +} +#endif + diff --git a/apps/apptester/app_audtest.h b/apps/apptester/app_audtest.h new file mode 100644 index 0000000..191267d --- /dev/null +++ b/apps/apptester/app_audtest.h @@ -0,0 +1,23 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_AUDTEST_H__ +#define __APP_AUDTEST_H__ + +#include "audioflinger.h" +void da_output_sin1k(bool on); +void adc_looptester(bool on, uint8_t mode, enum AUD_SAMPRATE_T sample_rate); + +#endif diff --git a/apps/apptester/app_audtest_pattern.h b/apps/apptester/app_audtest_pattern.h new file mode 100644 index 0000000..0d986a4 --- /dev/null +++ b/apps/apptester/app_audtest_pattern.h @@ -0,0 +1,185231 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_AUDTEST_PATTERN_H__ +#define __APP_AUDTEST_PATTERN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define CODEC_TESTMODE (1) +#define CODEC_1KSIN (1) +#define CODEC_WHITENOISE (2) + +#define CODEC_SAMPLERATE (44100) + +#if (CODEC_SAMPLERATE == 48000) + +#if (CODEC_TESTMODE == CODEC_1KSIN) +const int16_t sinwave[] = { + 0 , + 0 , + 4234 , + 4234 , + 8396 , + 8396 , + 12414 , + 12414 , + 16220 , + 16220 , + 19748 , + 19748 , + 22938 , + 22938 , + 25736 , + 25736 , + 28094 , + 28094 , + 29970 , + 29970 , + 31334 , + 31334 , + 32162 , + 32162 , + 32440 , + 32440 , + 32162 , + 32162 , + 31334 , + 31334 , + 29970 , + 29970 , + 28094 , + 28094 , + 25736 , + 25736 , + 22938 , + 22938 , + 19748 , + 19748 , + 16220 , + 16220 , + 12414 , + 12414 , + 8396 , + 8396 , + 4234 , + 4234 , + 0 , + 0 , + -4234 , + -4234 , + -8396 , + -8396 , + -12414 , + -12414 , + -16220 , + -16220 , + -19748 , + -19748 , + -22938 , + -22938 , + -25736 , + -25736 , + -28094 , + -28094 , + -29970 , + -29970 , + -31334 , + -31334 , + -32162 , + -32162 , + -32440 , + -32440 , + -32162 , + -32162 , + -31334 , + -31334 , + -29970 , + -29970 , + -28094 , + -28094 , + -25736 , + -25736 , + -22938 , + -22938 , + -19748 , + -19748 , + -16220 , + -16220 , + -12414 , + -12414 , + -8396 , + -8396 , + -4234 , + -4234 +}; +#elif (CODEC_TESTMODE == CODEC_WHITENOISE) +const int16_t sinwave[] = { +-15137 , +5197 , +29897 , +7339 , +26187 , +-16625 , +1465 , +20867 , +5873 , +11597 , +-4271 , +11251 , +-2911 , +-4837 , +22165 , +-10965 , +23733 , +-31833 , +25389 , +23105 , +-8851 , +13419 , +-29179 , +16799 , +-18493 , +-19735 , +31841 , +14091 , +2509 , +-18723 , +-16523 , +1551 , +14723 , +-5375 , +20603 , +-25865 , +-18393 , +11831 , +8529 , +16975 , +-18917 , +-24759 , +-26227 , +-8495 , +-8403 , +27429 , +22549 , +19941 , +-18561 , +-10873 , +4407 , +-19825 , +-20269 , +29757 , +-7871 , +-8461 , +-28565 , +5343 , +-5221 , +-27577 , +15707 , +17663 , +-24995 , +-11955 , +-28831 , +-2841 , +29287 , +-6333 , +13895 , +11471 , +32764 , +-29337 , +20909 , +19607 , +-16431 , +-21783 , +-11927 , +-12805 , +20659 , +3939 , +13919 , +335 , +-26221 , +-11823 , +-13355 , +-17223 , +-24539 , +-29173 , +-3757 , +30173 , +27637 , +14519 , +-29459 , +-16859 , +-12805 , +-15927 , +15917 , +-26257 , +25791 , +15739 , +26967 , +-22713 , +13543 , +-13381 , +-19627 , +-26975 , +-20917 , +-2517 , +1537 , +-9203 , +30109 , +-17253 , +-19199 , +8819 , +-13709 , +2043 , +-9439 , +28235 , +-7709 , +-17451 , +-30677 , +27473 , +3485 , +7751 , +-10441 , +-9023 , +1919 , +-12681 , +-31341 , +-22517 , +14771 , +401 , +8715 , +29201 , +23363 , +15929 , +27847 , +18139 , +14637 , +20103 , +-87 , +17357 , +1029 , +-24453 , +-10471 , +-17309 , +-1529 , +-13063 , +-11417 , +-11929 , +-14935 , +32067 , +-13661 , +-3411 , +26819 , +26345 , +17127 , +17217 , +3095 , +-27069 , +27975 , +22569 , +-29839 , +-16523 , +30991 , +18843 , +5695 , +-12845 , +-10319 , +-29005 , +-17241 , +27115 , +-30451 , +-25687 , +16667 , +-21007 , +2131 , +-17779 , +1661 , +-16193 , +-3753 , +5757 , +29353 , +-28859 , +-2455 , +29021 , +-25189 , +23691 , +16047 , +31765 , +-23307 , +24609 , +-15115 , +18745 , +31787 , +11029 , +-12521 , +-11689 , +-28401 , +2937 , +5571 , +1947 , +7399 , +9801 , +-19231 , +25105 , +31245 , +32752 , +31843 , +28769 , +22021 , +-21703 , +-18013 , +22009 , +6163 , +22219 , +4401 , +-19243 , +21583 , +28961 , +-32453 , +-1619 , +-23735 , +6909 , +9297 , +-32083 , +-18927 , +8293 , +-13103 , +-26445 , +-291 , +12315 , +4269 , +-19713 , +-14819 , +-30319 , +-8749 , +-649 , +1037 , +22885 , +12023 , +-26289 , +-10541 , +31833 , +-1801 , +-28593 , +-4843 , +-7995 , +-5975 , +-3451 , +-17131 , +16023 , +2365 , +5755 , +-8127 , +24009 , +-5367 , +29683 , +27473 , +-23727 , +25323 , +4383 , +-25889 , +7335 , +31263 , +-1453 , +-21381 , +-15949 , +-22895 , +-17335 , +15433 , +9539 , +-7233 , +22729 , +-239 , +19469 , +-15355 , +-21011 , +12513 , +-7647 , +4739 , +-14373 , +-28647 , +-31009 , +7525 , +5357 , +15629 , +26483 , +16589 , +-2949 , +22043 , +-8245 , +-13799 , +-26613 , +-22463 , +23057 , +-13367 , +-20729 , +19505 , +9373 , +-1585 , +-11017 , +-30733 , +30329 , +9835 , +14907 , +-13067 , +23113 , +30589 , +32581 , +10917 , +-18477 , +-5013 , +14919 , +3467 , +13289 , +19557 , +8051 , +-23841 , +7919 , +5453 , +17335 , +-18271 , +10691 , +-31991 , +29161 , +29235 , +6469 , +18267 , +2695 , +-22163 , +12355 , +2619 , +26097 , +21561 , +-30731 , +19115 , +12571 , +-14677 , +3833 , +-18415 , +-17211 , +10643 , +26311 , +-25581 , +-18631 , +-611 , +22437 , +27881 , +18559 , +743 , +4905 , +8249 , +2325 , +23827 , +-727 , +22123 , +-13529 , +19431 , +13109 , +-2425 , +-20921 , +20577 , +-30063 , +21125 , +30121 , +5709 , +15529 , +27695 , +-26413 , +-1437 , +-1521 , +29293 , +1757 , +-31527 , +-25617 , +3883 , +5155 , +-20353 , +11267 , +-25179 , +-30081 , +22099 , +31507 , +-7871 , +21509 , +-27233 , +-533 , +21743 , +-18379 , +-28531 , +10449 , +-21767 , +-23625 , +21819 , +377 , +-27299 , +-3443 , +19295 , +8069 , +28327 , +13527 , +-433 , +-11397 , +-9403 , +-6659 , +-25687 , +-21447 , +-1179 , +-29069 , +-417 , +4849 , +17733 , +-14365 , +-25003 , +13725 , +-24555 , +-25607 , +15479 , +-2051 , +-10427 , +13701 , +-23725 , +8967 , +-413 , +23619 , +21549 , +-29973 , +-8845 , +-19697 , +30877 , +25465 , +-573 , +12437 , +-3937 , +31533 , +28485 , +-13673 , +-10959 , +-27495 , +-8595 , +-13415 , +18287 , +-27039 , +4733 , +-13539 , +-7141 , +-13897 , +27749 , +-16291 , +-19511 , +-8373 , +32285 , +10117 , +-4245 , +-3381 , +21111 , +-20129 , +29031 , +17621 , +32119 , +30109 , +11063 , +-7307 , +-29389 , +8063 , +30593 , +-1771 , +-3295 , +3353 , +-24413 , +-1541 , +-523 , +-9979 , +29661 , +26691 , +-1031 , +18075 , +14551 , +26191 , +7649 , +2215 , +-6713 , +-12345 , +12839 , +23205 , +-6141 , +4361 , +-12063 , +-7047 , +22807 , +29995 , +4121 , +-8025 , +-1951 , +8807 , +22695 , +-765 , +-16091 , +32033 , +29575 , +-4619 , +29999 , +10577 , +26543 , +11305 , +-3109 , +25223 , +16493 , +-11059 , +-19015 , +-7591 , +21563 , +9281 , +17569 , +3425 , +9237 , +-31913 , +2125 , +-24909 , +27477 , +-24829 , +16237 , +-30247 , +30731 , +-32099 , +32069 , +19265 , +25553 , +11409 , +-31809 , +24387 , +17703 , +-27241 , +-11773 , +6027 , +-3767 , +-23947 , +-16489 , +-30947 , +26247 , +-2011 , +31727 , +-17215 , +30495 , +10911 , +-13691 , +1031 , +-13165 , +15879 , +-11401 , +25785 , +-9345 , +-3477 , +-8035 , +6353 , +-8199 , +-11791 , +24345 , +12533 , +31325 , +31129 , +-645 , +8043 , +1199 , +5237 , +15953 , +24985 , +14449 , +-32427 , +22339 , +-13 , +15607 , +6929 , +-19287 , +7289 , +-18879 , +-25809 , +-1627 , +18349 , +-5037 , +3883 , +-11085 , +-11253 , +-23789 , +22561 , +-32559 , +-8189 , +-17771 , +11537 , +19207 , +20077 , +12287 , +6029 , +-2935 , +25993 , +-26925 , +25337 , +18759 , +19563 , +-23845 , +30269 , +-15601 , +7933 , +-9619 , +-28671 , +-28391 , +-12175 , +2381 , +23905 , +-9169 , +-27585 , +-29689 , +25389 , +-24783 , +1431 , +3007 , +-20073 , +-5057 , +-15011 , +-15727 , +-9619 , +-2491 , +-14689 , +-8093 , +-24101 , +-18661 , +397 , +10305 , +24983 , +-30185 , +-15121 , +24117 , +-26981 , +-27863 , +24103 , +-25191 , +-28315 , +19055 , +20377 , +12279 , +-16217 , +1107 , +-12881 , +-933 , +-29055 , +-12769 , +-17839 , +10035 , +18489 , +30483 , +-10541 , +-1383 , +2167 , +7679 , +25721 , +-20675 , +7155 , +7007 , +-5275 , +11689 , +-10051 , +-24593 , +24601 , +24623 , +24543 , +-8255 , +24419 , +11563 , +16815 , +8665 , +-18209 , +-19989 , +31855 , +-29627 , +-19 , +-10749 , +-12907 , +1199 , +23333 , +-12513 , +-12933 , +-643 , +19025 , +-21151 , +-12899 , +-30875 , +-25879 , +-30663 , +-3769 , +32647 , +17155 , +25531 , +30939 , +12801 , +23253 , +26233 , +-18565 , +18699 , +-4961 , +30675 , +-21683 , +24713 , +-11467 , +-8483 , +-20437 , +5681 , +24297 , +-1621 , +17627 , +-4593 , +-1787 , +-23245 , +23245 , +-7249 , +32201 , +28055 , +10319 , +-85 , +-31519 , +7947 , +-2747 , +-13885 , +20567 , +-12503 , +-9631 , +-4227 , +-26093 , +-2365 , +-5411 , +-2255 , +-2097 , +-19391 , +-16207 , +22447 , +3467 , +-12677 , +-7353 , +-13241 , +18065 , +-28665 , +191 , +15729 , +19681 , +4895 , +29085 , +5593 , +-2261 , +5609 , +-257 , +23547 , +-6831 , +-4255 , +25439 , +26689 , +-31919 , +-17249 , +32193 , +-28783 , +-21817 , +24253 , +-20617 , +-26007 , +-25889 , +24869 , +23623 , +24697 , +32465 , +24691 , +1335 , +24761 , +15063 , +2501 , +-2635 , +-20989 , +-18521 , +19091 , +-1189 , +2089 , +25703 , +-14069 , +8219 , +31115 , +10025 , +15595 , +-8447 , +20787 , +29665 , +-16177 , +-13461 , +-11923 , +-15905 , +-19433 , +8885 , +27359 , +6081 , +17713 , +16515 , +-9193 , +-6665 , +15481 , +28009 , +3511 , +-6229 , +8085 , +45 , +759 , +16971 , +17727 , +18807 , +-18737 , +-25747 , +-3669 , +16915 , +15749 , +23897 , +4953 , +29599 , +711 , +-7689 , +-18327 , +5067 , +31813 , +-17335 , +-11135 , +-13813 , +10435 , +-10139 , +28433 , +6101 , +13243 , +-22037 , +-11717 , +-9393 , +-27281 , +8445 , +-11737 , +-7019 , +1917 , +-25159 , +-15149 , +5475 , +-23041 , +-26069 , +17017 , +855 , +-27361 , +17103 , +18009 , +-27481 , +-31953 , +-19071 , +-14305 , +-28843 , +24387 , +7927 , +26027 , +-27927 , +7239 , +28347 , +13687 , +29865 , +-10091 , +-9823 , +22889 , +30295 , +16913 , +-7491 , +27179 , +20317 , +-28989 , +8931 , +21247 , +-32627 , +-7709 , +-31085 , +-18907 , +-5543 , +30085 , +14973 , +29087 , +7563 , +24731 , +-399 , +23709 , +24183 , +20893 , +5849 , +-10939 , +-11589 , +5531 , +-27469 , +14101 , +-11917 , +17363 , +11269 , +-11853 , +-12815 , +-6703 , +20699 , +30801 , +-11019 , +29689 , +-11591 , +16757 , +5221 , +-335 , +-20843 , +-28833 , +25991 , +-9241 , +20307 , +-1829 , +20921 , +-20167 , +-2889 , +10903 , +-30301 , +12927 , +30943 , +22785 , +18165 , +27885 , +11323 , +23191 , +-28509 , +-2393 , +9 , +713 , +-9841 , +-9511 , +-18619 , +-10935 , +-3633 , +-26031 , +22057 , +-22047 , +-15779 , +6293 , +-30687 , +22743 , +-13485 , +-12937 , +13377 , +1977 , +-9055 , +4921 , +-1981 , +11963 , +325 , +-5863 , +-15881 , +-4469 , +5383 , +621 , +16197 , +-12623 , +-859 , +31295 , +23707 , +31837 , +-1889 , +863 , +-30227 , +-24125 , +2647 , +-4869 , +-473 , +28149 , +-7197 , +-11329 , +-20185 , +-6851 , +23083 , +22373 , +17463 , +-28181 , +-11851 , +-21299 , +-28413 , +-21065 , +-25133 , +25757 , +5909 , +23447 , +-13731 , +15951 , +-63 , +2577 , +18413 , +24525 , +-3921 , +-27109 , +-3439 , +-13937 , +25795 , +18031 , +27395 , +24357 , +-15457 , +14179 , +14951 , +23649 , +-4203 , +20289 , +14463 , +-28961 , +-32221 , +21281 , +-21407 , +11301 , +28395 , +13375 , +8119 , +-25541 , +17701 , +11729 , +23659 , +4287 , +-14433 , +-13467 , +-29461 , +16513 , +4913 , +28597 , +-2347 , +8089 , +2999 , +29693 , +18493 , +-5119 , +18307 , +30679 , +-4263 , +26283 , +12637 , +-1645 , +29887 , +-28393 , +-26375 , +-12531 , +20505 , +-14481 , +27111 , +-26879 , +12133 , +-28895 , +-16103 , +-17683 , +10399 , +-3603 , +6351 , +6497 , +-12789 , +-17015 , +-15595 , +-3875 , +-25379 , +32687 , +27321 , +8989 , +-16775 , +-26945 , +-11581 , +26885 , +-27605 , +11979 , +-29585 , +-28955 , +1373 , +-31941 , +-9307 , +20827 , +2125 , +15581 , +-32279 , +-3411 , +23883 , +17537 , +-22559 , +8343 , +-2965 , +-7669 , +-25281 , +17075 , +-2623 , +-32748 , +-22713 , +-14017 , +-7145 , +-5119 , +-27209 , +-27519 , +-11739 , +27277 , +22095 , +3227 , +8779 , +30963 , +16059 , +483 , +-14137 , +-28035 , +17689 , +-4675 , +-30613 , +-11617 , +-8479 , +-21519 , +8665 , +-13431 , +-16789 , +17539 , +-4803 , +26953 , +9953 , +-8693 , +-10629 , +14679 , +3767 , +28813 , +13301 , +-4419 , +-14173 , +20693 , +28595 , +31387 , +27413 , +11337 , +-1237 , +-28335 , +-20943 , +-29375 , +-31379 , +-3059 , +30787 , +32742 , +-5149 , +22243 , +-12099 , +28545 , +-8831 , +15211 , +29099 , +-11169 , +-22395 , +-26667 , +-20569 , +-13799 , +10923 , +-23937 , +-4007 , +9849 , +23523 , +-26091 , +26477 , +10445 , +27537 , +-7653 , +21001 , +22973 , +-6087 , +19479 , +26815 , +-19541 , +-5695 , +-6887 , +-16361 , +-21631 , +-18907 , +8153 , +-12431 , +12811 , +-10063 , +-19627 , +-10611 , +17883 , +9139 , +1503 , +22907 , +11661 , +-27457 , +31931 , +-5349 , +-3407 , +-27819 , +-30665 , +-507 , +13589 , +-32209 , +-15299 , +-3049 , +-4437 , +6885 , +1395 , +9305 , +16341 , +-29647 , +-21807 , +3969 , +-9153 , +-11613 , +2995 , +31465 , +12353 , +17369 , +23161 , +-22013 , +-10585 , +-15303 , +-11367 , +28243 , +30487 , +-24793 , +-28355 , +17899 , +-23325 , +31163 , +-9387 , +16475 , +-10655 , +22525 , +19503 , +-7631 , +3265 , +11423 , +-24169 , +-16661 , +17515 , +-5331 , +-28057 , +371 , +17875 , +-27445 , +-32607 , +-25833 , +-4401 , +14187 , +24583 , +20733 , +-29581 , +22405 , +-22221 , +24605 , +23911 , +-17325 , +-20171 , +-4165 , +-11069 , +5761 , +15773 , +2653 , +-19105 , +31085 , +-21213 , +21829 , +-25169 , +7897 , +-29517 , +15975 , +7201 , +27943 , +-3829 , +-10019 , +-7189 , +-18419 , +27857 , +8171 , +14951 , +-19499 , +-1235 , +-10135 , +13551 , +4873 , +-18723 , +-14137 , +-8401 , +18101 , +-18991 , +32635 , +-7681 , +-9957 , +-7871 , +24575 , +-15683 , +23277 , +8775 , +11847 , +21285 , +23297 , +-17675 , +-12099 , +27045 , +24717 , +9195 , +-32593 , +31287 , +24539 , +18037 , +8533 , +10169 , +-24185 , +27419 , +-2757 , +26059 , +-27599 , +-19259 , +27203 , +17179 , +-32581 , +-32703 , +13337 , +-3001 , +-26375 , +-32655 , +27949 , +14127 , +22767 , +-4403 , +-2525 , +-22829 , +-19833 , +-22385 , +-13349 , +6055 , +-1073 , +-28615 , +-29735 , +-27547 , +6051 , +3003 , +-8381 , +4983 , +-12047 , +-2299 , +1119 , +31927 , +-8079 , +-7397 , +11905 , +6109 , +-27435 , +-1609 , +-2935 , +-1205 , +-27257 , +23899 , +-31271 , +-27805 , +-18465 , +24037 , +-8755 , +-9621 , +24285 , +22959 , +-21069 , +22743 , +23901 , +-23773 , +13641 , +-31191 , +-11563 , +17109 , +-15959 , +-23987 , +-1403 , +-4587 , +2759 , +-24733 , +25913 , +2577 , +10097 , +13351 , +-27275 , +4963 , +20407 , +-20805 , +30265 , +16943 , +9713 , +-24567 , +-23503 , +-15683 , +-16847 , +-2151 , +369 , +23175 , +7223 , +-22557 , +-29783 , +-11813 , +24561 , +27441 , +-4893 , +-1551 , +22643 , +-16147 , +-16719 , +-22655 , +-19101 , +-17535 , +-2059 , +31191 , +-28925 , +-18779 , +32009 , +-14733 , +31893 , +-29113 , +19069 , +-32479 , +-3735 , +28113 , +12885 , +30855 , +6207 , +-12273 , +-23629 , +-16571 , +-6829 , +-14463 , +29985 , +-26223 , +-26943 , +10029 , +10553 , +-14527 , +23443 , +-23543 , +-23065 , +-32139 , +22819 , +-31043 , +-10727 , +2715 , +-14555 , +1547 , +11777 , +5145 , +23059 , +-7777 , +-30267 , +-2979 , +-19411 , +21867 , +24247 , +-7567 , +5355 , +-641 , +-18667 , +9243 , +-265 , +-15781 , +-4041 , +32627 , +3241 , +26063 , +-19635 , +-14091 , +-21769 , +-14257 , +8341 , +-6623 , +-3337 , +32457 , +-23275 , +7309 , +22985 , +-12027 , +29391 , +1411 , +28449 , +-18317 , +4991 , +-493 , +25135 , +-2169 , +3531 , +27563 , +-31453 , +-7787 , +5381 , +-21191 , +-30953 , +-5341 , +-17575 , +4275 , +-25447 , +-25917 , +7817 , +-23237 , +20115 , +-3475 , +-30933 , +16823 , +10189 , +-5801 , +29269 , +-26655 , +-1825 , +3655 , +-543 , +-21533 , +-5457 , +-5517 , +12059 , +-30603 , +5983 , +15573 , +3071 , +-30871 , +-7723 , +-23035 , +-269 , +1741 , +-15457 , +-9079 , +31991 , +-7553 , +-13953 , +443 , +26209 , +-30139 , +30291 , +12055 , +6681 , +3175 , +17559 , +-11245 , +-19635 , +-4925 , +32343 , +-897 , +27047 , +8297 , +-23637 , +5969 , +-29687 , +1457 , +6061 , +22023 , +3525 , +-20265 , +19443 , +15483 , +7761 , +25863 , +8835 , +31037 , +-15487 , +-28153 , +-16817 , +-24985 , +-4541 , +11841 , +31275 , +-11525 , +465 , +-15009 , +15941 , +5297 , +17771 , +4963 , +-5087 , +8795 , +14483 , +-31677 , +6407 , +-22855 , +16827 , +28665 , +-12535 , +-17463 , +-20597 , +27429 , +-29587 , +24235 , +-31603 , +-31717 , +14767 , +-5135 , +1385 , +-15233 , +19957 , +15481 , +-32351 , +-12447 , +-9721 , +31433 , +20161 , +-3121 , +-20025 , +18655 , +28193 , +-29709 , +27691 , +20111 , +-10989 , +161 , +29107 , +-14243 , +-12385 , +18813 , +-11935 , +11981 , +30145 , +16773 , +5169 , +-29119 , +-21737 , +-22477 , +-14571 , +-22703 , +-24291 , +10003 , +-3229 , +28573 , +21479 , +13267 , +15831 , +2863 , +-1703 , +9963 , +-7157 , +-10677 , +-9507 , +24225 , +20583 , +-26679 , +-28265 , +-14665 , +31903 , +29679 , +7463 , +-25493 , +-9561 , +-18491 , +-13095 , +-14553 , +-973 , +5361 , +29535 , +-25211 , +-20317 , +26127 , +-8947 , +28403 , +-11897 , +-27769 , +137 , +-22071 , +30095 , +-20255 , +-7669 , +-2593 , +-15867 , +-5463 , +-24305 , +7073 , +4805 , +23737 , +-22385 , +4015 , +-20293 , +26907 , +31167 , +-1291 , +-12597 , +-22691 , +2367 , +-26823 , +1375 , +1129 , +9943 , +-18373 , +1101 , +10973 , +-6229 , +22865 , +-19627 , +-13341 , +-29961 , +1907 , +31005 , +-8051 , +-11963 , +-37 , +-8031 , +31655 , +15911 , +-9443 , +21813 , +17423 , +15469 , +7359 , +11509 , +12181 , +-25381 , +32585 , +-17987 , +-27063 , +26473 , +21739 , +-26457 , +13913 , +30445 , +-11125 , +-2049 , +16487 , +-10395 , +-21667 , +3001 , +1125 , +24221 , +-21761 , +26735 , +22245 , +30583 , +-5103 , +31953 , +18165 , +-26729 , +15689 , +-7769 , +15483 , +22431 , +14097 , +-18369 , +5899 , +-23061 , +-13415 , +-12435 , +25909 , +3009 , +-21647 , +-14597 , +19569 , +32019 , +22177 , +-5717 , +14689 , +-21845 , +12869 , +-2651 , +-3909 , +20207 , +31391 , +-29833 , +6293 , +27923 , +27055 , +31621 , +-11709 , +-1331 , +27221 , +-22005 , +31919 , +-4969 , +-20517 , +-15991 , +14123 , +7259 , +2579 , +27593 , +15573 , +699 , +19957 , +18763 , +-20383 , +-17739 , +10925 , +24385 , +-3975 , +18415 , +-15559 , +13321 , +3221 , +-26787 , +-7039 , +21029 , +29263 , +12935 , +12265 , +27053 , +27457 , +7481 , +4721 , +-14257 , +-31913 , +-10815 , +-8119 , +24515 , +28585 , +-4193 , +-4887 , +4805 , +-29225 , +16581 , +-2131 , +-32633 , +-27687 , +6471 , +-15133 , +1713 , +-30625 , +32159 , +15213 , +12757 , +-25695 , +-9389 , +-8491 , +21607 , +-1853 , +12355 , +-535 , +31799 , +10143 , +7245 , +28105 , +32357 , +5925 , +-10863 , +10635 , +20957 , +26675 , +30503 , +-20917 , +28749 , +4331 , +-23985 , +27589 , +30109 , +-3959 , +-5575 , +8557 , +-18967 , +27585 , +555 , +-32756 , +505 , +-22125 , +9797 , +-6193 , +21041 , +-30557 , +-18759 , +-25885 , +-28649 , +-6899 , +32119 , +15507 , +13885 , +18121 , +-27017 , +-2861 , +-315 , +-28551 , +29279 , +4199 , +22611 , +-14655 , +-5173 , +30061 , +-9857 , +-30687 , +-6409 , +-15233 , +27357 , +19795 , +29699 , +32329 , +24419 , +2585 , +-5213 , +1435 , +13167 , +18075 , +-427 , +-10745 , +10809 , +18747 , +11817 , +-14597 , +-32313 , +26869 , +-21793 , +-19631 , +30063 , +8235 , +2235 , +23919 , +-14651 , +-2039 , +-13913 , +-6185 , +1309 , +-7085 , +12533 , +-17847 , +19321 , +10179 , +22937 , +11091 , +-21243 , +22755 , +1753 , +-14743 , +2067 , +-24739 , +10125 , +-31101 , +30607 , +-15909 , +-31793 , +-8909 , +6897 , +7253 , +-29379 , +-8653 , +27847 , +5881 , +-13911 , +26513 , +-8297 , +13683 , +-12205 , +-25037 , +-1689 , +22219 , +20899 , +-26885 , +-23121 , +15809 , +8539 , +-31655 , +-2609 , +-1631 , +-17573 , +16491 , +2061 , +18331 , +15051 , +-29815 , +19719 , +-31591 , +15325 , +-10391 , +-7249 , +18333 , +-24575 , +-2389 , +17343 , +15507 , +-21349 , +-30465 , +-4427 , +22447 , +31809 , +31663 , +24397 , +-1733 , +14957 , +30403 , +-4241 , +6653 , +8635 , +-29043 , +-4943 , +6149 , +-19305 , +4561 , +-27827 , +15363 , +10371 , +-13239 , +10133 , +-28889 , +31681 , +-27187 , +-6675 , +6523 , +11671 , +-31257 , +327 , +8361 , +4351 , +-23577 , +26643 , +32621 , +12767 , +27517 , +-30787 , +-21163 , +17607 , +-559 , +-14681 , +-28887 , +-26329 , +22303 , +-4965 , +-22597 , +1535 , +24777 , +12739 , +-16061 , +-14045 , +14321 , +11301 , +-22729 , +-12051 , +-32621 , +21405 , +2205 , +26739 , +7449 , +21581 , +6893 , +-16827 , +8827 , +-6243 , +5469 , +15773 , +24779 , +27563 , +7365 , +12833 , +22615 , +-3765 , +-18447 , +-20977 , +-3267 , +-1925 , +25717 , +11009 , +-9339 , +-27811 , +25615 , +-8933 , +-14927 , +10153 , +23157 , +12495 , +-30745 , +-31057 , +-11337 , +27397 , +21873 , +-27707 , +19211 , +-7203 , +-2327 , +12611 , +-13777 , +-11283 , +22219 , +-21501 , +-18113 , +11239 , +14981 , +23879 , +-2297 , +28387 , +-32744 , +-17595 , +-11805 , +1805 , +-18381 , +-28659 , +-1771 , +3293 , +29885 , +-28911 , +-363 , +-1833 , +9209 , +275 , +-32393 , +14265 , +-12259 , +-16741 , +-26443 , +6457 , +-25755 , +12537 , +-26989 , +4413 , +20651 , +-28233 , +-17297 , +-15475 , +-8055 , +8333 , +-2277 , +-11755 , +8929 , +-30747 , +15287 , +-6765 , +-19195 , +10179 , +-25339 , +-5929 , +19519 , +32589 , +-20155 , +-4489 , +21755 , +27831 , +24717 , +-18173 , +13901 , +31681 , +-19555 , +24007 , +4633 , +-1365 , +-17605 , +-1539 , +22941 , +3509 , +10249 , +-3455 , +3733 , +30989 , +-21793 , +-18925 , +2247 , +22861 , +-19043 , +31237 , +6185 , +-32145 , +-19315 , +-5765 , +23405 , +-17075 , +22579 , +16155 , +-23781 , +-25715 , +1961 , +-16047 , +14645 , +6695 , +4975 , +6393 , +-6855 , +-13747 , +-16173 , +31389 , +-31535 , +-18191 , +-14917 , +6709 , +4311 , +-13129 , +19711 , +-7859 , +26363 , +-11669 , +6985 , +-8239 , +-20527 , +-4095 , +-5023 , +28469 , +-18063 , +-18945 , +-24301 , +-32711 , +7821 , +-30843 , +21883 , +2837 , +-28161 , +-28485 , +-2081 , +6715 , +9973 , +971 , +30735 , +26511 , +-4747 , +-11177 , +10037 , +1045 , +-17535 , +-22151 , +24623 , +565 , +31403 , +15923 , +4199 , +-26009 , +-11733 , +-6041 , +14639 , +-15751 , +-31359 , +32341 , +403 , +-20677 , +24443 , +21135 , +28851 , +14525 , +481 , +32369 , +26777 , +-26365 , +29051 , +13077 , +-1637 , +32065 , +-18757 , +18649 , +-23001 , +-7785 , +27329 , +-15033 , +-20709 , +-20679 , +-30457 , +-28783 , +171 , +-27335 , +23915 , +2963 , +-10327 , +5047 , +-6455 , +-11455 , +-18589 , +12693 , +-31207 , +18075 , +-14335 , +-11079 , +20997 , +10805 , +13649 , +13499 , +-6403 , +3103 , +-22997 , +24613 , +3025 , +-22681 , +25665 , +19493 , +713 , +-499 , +19575 , +26313 , +-8383 , +24951 , +8131 , +9141 , +-18501 , +8567 , +19579 , +31579 , +3193 , +6573 , +-14285 , +-11083 , +14999 , +-10855 , +4629 , +20857 , +21409 , +-32007 , +-2635 , +-2857 , +12715 , +27351 , +9837 , +-25431 , +8169 , +10481 , +19251 , +17715 , +-4151 , +22973 , +-27919 , +-28841 , +-11639 , +-2347 , +26973 , +331 , +-12465 , +6653 , +25687 , +-1575 , +11715 , +24207 , +435 , +-12789 , +-21211 , +-26249 , +19871 , +2415 , +-8223 , +8109 , +2421 , +18629 , +-31821 , +21291 , +27407 , +-22723 , +11825 , +-20889 , +3245 , +13871 , +9711 , +1605 , +9527 , +30545 , +-16371 , +15003 , +-24275 , +20845 , +6743 , +3355 , +13293 , +30623 , +-30249 , +22229 , +-1645 , +-17655 , +-27153 , +21543 , +-16049 , +16137 , +-10251 , +16193 , +-26559 , +2037 , +-26811 , +-3827 , +-21307 , +-9135 , +31195 , +-16201 , +8799 , +-3959 , +8557 , +22937 , +-4611 , +21799 , +3327 , +-16455 , +21217 , +-24695 , +-26877 , +15039 , +6127 , +-15073 , +26595 , +24429 , +3459 , +-24291 , +13611 , +-4199 , +-1065 , +7351 , +9489 , +-14173 , +-28217 , +29143 , +-20845 , +-26515 , +27709 , +-32681 , +19991 , +-28461 , +-12807 , +-21069 , +-6543 , +-11867 , +8177 , +18249 , +9871 , +-16099 , +-11735 , +-8433 , +-13441 , +2775 , +-19191 , +-25913 , +5913 , +32073 , +25397 , +-4681 , +21253 , +32189 , +-11293 , +-19221 , +-18337 , +19141 , +-21061 , +11741 , +-27699 , +-15045 , +29223 , +-16451 , +-493 , +-2133 , +6443 , +3867 , +301 , +5211 , +13763 , +21545 , +-32279 , +8633 , +15029 , +27505 , +-14847 , +3413 , +-2067 , +-26361 , +-4441 , +23897 , +-6059 , +30281 , +16303 , +14465 , +26663 , +531 , +-29933 , +-873 , +27595 , +19319 , +-26335 , +7013 , +-12493 , +-20749 , +-6913 , +30255 , +-10841 , +7729 , +-31281 , +-4181 , +-3549 , +27189 , +-25533 , +27773 , +28725 , +2077 , +7349 , +-1495 , +5453 , +18511 , +19903 , +21645 , +21141 , +30785 , +-11433 , +-32295 , +8015 , +-6497 , +-24995 , +-17143 , +5033 , +16913 , +-26431 , +26335 , +-9199 , +19051 , +26125 , +13647 , +-25319 , +19559 , +4233 , +22917 , +24513 , +24543 , +-1335 , +-11175 , +7769 , +-8061 , +-4661 , +-20157 , +-30249 , +6417 , +-25711 , +24531 , +8103 , +-26353 , +28205 , +-7247 , +-22513 , +11521 , +-1171 , +4875 , +-19199 , +-3809 , +-2853 , +-25707 , +14705 , +30355 , +-5011 , +1529 , +-11981 , +29483 , +-14965 , +28633 , +-11955 , +-3179 , +10925 , +13373 , +-18221 , +-30701 , +-8329 , +14993 , +6713 , +25531 , +18251 , +9247 , +-27337 , +-6619 , +-1947 , +4091 , +-1773 , +-30809 , +-19601 , +11661 , +10117 , +-24561 , +-26719 , +-10887 , +-12285 , +-37 , +-5299 , +24863 , +-25689 , +-11283 , +20739 , +30869 , +-7817 , +-13369 , +-16099 , +3863 , +31567 , +-1473 , +8163 , +-14841 , +-11481 , +26815 , +-14307 , +-4515 , +-16135 , +-11023 , +-7637 , +-8025 , +20751 , +-28415 , +-8295 , +-7299 , +2789 , +-429 , +-3261 , +22651 , +-12167 , +-25931 , +-8737 , +26545 , +-4575 , +6173 , +-6367 , +-7763 , +29425 , +30437 , +23371 , +-28709 , +27007 , +-25995 , +25925 , +-21615 , +2383 , +20617 , +-25287 , +-19585 , +30873 , +17123 , +9135 , +22437 , +14001 , +-13439 , +-24297 , +-19507 , +-14637 , +9047 , +495 , +-28535 , +-19585 , +-7283 , +18259 , +-7521 , +-32171 , +20781 , +17431 , +16653 , +-20377 , +27489 , +-24987 , +-30347 , +20245 , +13351 , +-4665 , +27425 , +22881 , +11151 , +19919 , +4211 , +22987 , +30061 , +15651 , +-24861 , +30889 , +-24173 , +8475 , +-14995 , +-29957 , +-29041 , +17877 , +4503 , +14791 , +24281 , +-19753 , +17113 , +-9743 , +-1907 , +-21483 , +21671 , +3211 , +1961 , +14237 , +30423 , +-16451 , +-1341 , +32671 , +-21337 , +-22517 , +-3525 , +26893 , +18989 , +-13763 , +6651 , +14005 , +2131 , +11687 , +26029 , +-28461 , +-6323 , +20241 , +10091 , +-14039 , +-26735 , +27651 , +30979 , +-19557 , +-24241 , +16037 , +-4183 , +-5301 , +617 , +16911 , +-28115 , +-9183 , +31471 , +5931 , +-30279 , +26873 , +16401 , +8705 , +-31487 , +-31195 , +19867 , +-2147 , +17921 , +-24425 , +3557 , +-19365 , +21049 , +10607 , +-28579 , +-11583 , +15705 , +7701 , +1641 , +-25889 , +-31105 , +-6959 , +-16657 , +-15841 , +32758 , +21989 , +22599 , +21407 , +14687 , +18723 , +24753 , +30987 , +-7047 , +-32764 , +7507 , +15345 , +-21425 , +17479 , +-20565 , +-10337 , +30447 , +-27911 , +20873 , +-19595 , +-30293 , +11299 , +-8309 , +-25153 , +-30775 , +24271 , +27151 , +24335 , +-15429 , +-5719 , +1195 , +15891 , +23263 , +-14311 , +-29651 , +-29713 , +5037 , +17363 , +-25847 , +-12015 , +30325 , +8949 , +25689 , +-19827 , +6293 , +19105 , +-21169 , +10225 , +-28109 , +-20983 , +-25297 , +6565 , +5745 , +-7653 , +-25655 , +-73 , +9771 , +11649 , +-2447 , +-26303 , +21801 , +27985 , +-31885 , +21551 , +-26153 , +-23021 , +-1011 , +32173 , +8071 , +-26273 , +17641 , +-11541 , +4891 , +14329 , +23829 , +-30079 , +25155 , +18531 , +11127 , +28227 , +-6851 , +6649 , +-7483 , +7579 , +-5379 , +-25465 , +13319 , +4189 , +-24591 , +-19359 , +1923 , +29219 , +18229 , +8955 , +-3017 , +28195 , +-16817 , +-9213 , +11735 , +903 , +17247 , +7929 , +8513 , +-1465 , +-2597 , +11583 , +30583 , +4223 , +2507 , +-2881 , +-18671 , +-1979 , +9597 , +-30985 , +15423 , +15879 , +-7749 , +-19303 , +-16587 , +-20641 , +-7031 , +-23141 , +8497 , +23145 , +-29101 , +-14891 , +-18459 , +-16993 , +-20043 , +-8677 , +-12421 , +16433 , +19875 , +-20017 , +-25855 , +-29991 , +-15833 , +-1799 , +19311 , +-9929 , +30621 , +3813 , +-31471 , +-9305 , +28773 , +11573 , +-5239 , +16795 , +-17121 , +-29823 , +-957 , +-31635 , +19299 , +15199 , +-4243 , +2753 , +1779 , +6417 , +-10383 , +15443 , +-14981 , +-22389 , +-18713 , +-24999 , +-2877 , +14099 , +-15079 , +-28593 , +-31891 , +6485 , +-26389 , +-16037 , +-987 , +24067 , +29283 , +-2535 , +19299 , +-13085 , +23189 , +14083 , +10137 , +-30099 , +21025 , +-201 , +-27663 , +14303 , +17959 , +-31781 , +30083 , +-6177 , +967 , +-21519 , +-19699 , +-16511 , +-7665 , +-12113 , +-10449 , +-25613 , +23159 , +-8615 , +-21219 , +-27515 , +18399 , +-4713 , +-12329 , +-20149 , +1017 , +-4787 , +-23577 , +-20945 , +6995 , +29937 , +-19563 , +8845 , +-12355 , +22381 , +-6753 , +-6837 , +8527 , +3687 , +-31117 , +1389 , +-27175 , +-27099 , +-25633 , +12079 , +30431 , +-11805 , +31577 , +-10847 , +-16883 , +4263 , +6823 , +-1863 , +26679 , +-13667 , +4897 , +-8213 , +26307 , +12015 , +-12445 , +-24247 , +-6223 , +-26089 , +-9337 , +-13037 , +11273 , +-29505 , +-12317 , +5585 , +-23341 , +15125 , +-12749 , +19693 , +-29033 , +19617 , +2399 , +-29755 , +-15543 , +-7003 , +20399 , +-7859 , +-1333 , +-29975 , +3965 , +23583 , +12773 , +3359 , +-12683 , +-14059 , +28593 , +-3919 , +-29883 , +-411 , +-24157 , +-29407 , +479 , +2863 , +-14859 , +26333 , +18983 , +9123 , +7335 , +-7531 , +-14029 , +-24179 , +-26897 , +-5865 , +-4865 , +-3727 , +15677 , +-27739 , +-21853 , +-15323 , +-15455 , +30927 , +14093 , +23783 , +1239 , +-20021 , +-3521 , +21495 , +-25679 , +12357 , +-771 , +-23123 , +21269 , +31939 , +28937 , +26129 , +-23439 , +30071 , +-19489 , +-3855 , +-841 , +9623 , +-9243 , +-4483 , +-43 , +19763 , +-24531 , +1123 , +-32087 , +-20077 , +-13661 , +-29863 , +29567 , +-12789 , +-23351 , +8515 , +26881 , +-689 , +22261 , +28613 , +4023 , +-19625 , +-19971 , +-169 , +11769 , +-8277 , +23417 , +28391 , +30315 , +4157 , +-11143 , +-6169 , +-7947 , +27851 , +21177 , +9969 , +-15819 , +8871 , +-7079 , +-3891 , +22913 , +22815 , +-10721 , +19483 , +3411 , +17993 , +-11233 , +22371 , +3663 , +31839 , +-17151 , +5033 , +-26449 , +1947 , +-24653 , +-1139 , +-29633 , +29833 , +-9313 , +-16671 , +-27945 , +22241 , +-9369 , +-1349 , +-29359 , +26849 , +25115 , +17941 , +32513 , +-9435 , +-7435 , +27359 , +-20559 , +-4869 , +-9337 , +9115 , +15377 , +25915 , +-22401 , +13685 , +-13131 , +937 , +-13097 , +16087 , +-21621 , +-32067 , +9103 , +4741 , +-4139 , +16907 , +-3097 , +-2255 , +-1887 , +12559 , +24597 , +-23655 , +-4679 , +4747 , +9855 , +20249 , +32553 , +-20389 , +11631 , +-20793 , +-25813 , +6099 , +-11955 , +14089 , +21157 , +30355 , +27993 , +31147 , +-23521 , +-20515 , +5861 , +-1921 , +25915 , +17009 , +769 , +17515 , +687 , +-26907 , +-28987 , +-16121 , +20155 , +20091 , +25081 , +-6989 , +5665 , +-21899 , +-23469 , +19759 , +-19555 , +-23561 , +-17097 , +-32585 , +23007 , +-13223 , +-27169 , +-19567 , +19457 , +-29187 , +-10721 , +27187 , +-17283 , +-6741 , +5019 , +20431 , +-30035 , +11365 , +27515 , +6511 , +-26951 , +2501 , +32423 , +-12911 , +-7147 , +9937 , +18557 , +18487 , +17013 , +-18095 , +-14327 , +21383 , +-19125 , +32685 , +-3139 , +11485 , +20925 , +17727 , +-4179 , +-12695 , +-13549 , +-30931 , +-449 , +-10945 , +26051 , +20929 , +9067 , +23545 , +-30507 , +-4535 , +-3477 , +-24125 , +-23067 , +31067 , +32255 , +-10751 , +-20579 , +-1595 , +-7403 , +-8107 , +-10585 , +4049 , +26127 , +32079 , +-15065 , +-10965 , +-25997 , +-30869 , +4275 , +1329 , +-29399 , +-15171 , +6863 , +1487 , +26923 , +4351 , +6111 , +-5931 , +-28989 , +15403 , +29855 , +-565 , +-27325 , +30103 , +21027 , +3159 , +12089 , +-25723 , +20551 , +-12541 , +26927 , +18241 , +24231 , +-14687 , +15061 , +-4681 , +-13283 , +-479 , +-7481 , +-4977 , +19635 , +-10525 , +1217 , +-9283 , +11809 , +30103 , +591 , +-1119 , +29375 , +-6255 , +-31213 , +6039 , +2813 , +-26465 , +-18063 , +-19175 , +-6813 , +12649 , +7371 , +-6321 , +3327 , +30271 , +31291 , +-24793 , +-29083 , +15989 , +-5429 , +-12301 , +23327 , +7231 , +26155 , +16507 , +-7249 , +-13055 , +-11035 , +24733 , +-24579 , +2609 , +7455 , +-1193 , +15957 , +-11609 , +8653 , +7533 , +-20257 , +-15245 , +11365 , +2171 , +-11885 , +-24767 , +-18145 , +-30067 , +-11081 , +-30937 , +7595 , +-28105 , +16847 , +8187 , +611 , +22317 , +-21731 , +6453 , +9739 , +-4257 , +-9327 , +16959 , +25607 , +-22393 , +-19633 , +-16559 , +29963 , +-433 , +27281 , +30407 , +25183 , +-31525 , +29493 , +20215 , +9103 , +-24597 , +-20313 , +21649 , +24233 , +24177 , +15967 , +24937 , +-15635 , +21155 , +31959 , +23521 , +-2549 , +-16741 , +-25339 , +-22861 , +-29731 , +-4759 , +25167 , +-9909 , +149 , +4273 , +21255 , +22693 , +11647 , +31419 , +3937 , +-5983 , +12345 , +-29421 , +1773 , +-12837 , +15457 , +13211 , +17547 , +-26619 , +20439 , +17451 , +-30489 , +11449 , +16753 , +-25957 , +27501 , +10971 , +8757 , +18793 , +-17973 , +15977 , +26891 , +-18741 , +-12841 , +31957 , +-7937 , +-443 , +4633 , +25053 , +-11793 , +28361 , +27833 , +-31513 , +23499 , +32067 , +-14087 , +-24879 , +31817 , +955 , +30513 , +-1969 , +-18663 , +9449 , +-25795 , +-10043 , +-10071 , +-21427 , +24961 , +3479 , +-13491 , +17095 , +12891 , +8711 , +-2295 , +20403 , +-25577 , +24461 , +9141 , +-8583 , +11121 , +11945 , +21961 , +24747 , +-5499 , +-4027 , +-25209 , +-23395 , +-16821 , +-6267 , +20663 , +-10119 , +23177 , +19489 , +-22815 , +-3621 , +1107 , +7485 , +12291 , +20969 , +-9469 , +-13115 , +7623 , +-537 , +-8281 , +23357 , +-10427 , +17491 , +29441 , +-989 , +-12503 , +9849 , +-32253 , +-9543 , +5247 , +24207 , +6327 , +5997 , +-27173 , +23119 , +-27699 , +-27223 , +-28899 , +517 , +10369 , +-19929 , +6557 , +-23499 , +-1253 , +31185 , +22255 , +-8797 , +31715 , +30997 , +11795 , +-10759 , +17055 , +-17475 , +4911 , +-22311 , +8325 , +5447 , +-11831 , +21365 , +-24389 , +18877 , +-11905 , +-345 , +-20673 , +12049 , +-12999 , +-629 , +-24971 , +24301 , +29929 , +22675 , +17165 , +-28395 , +-3651 , +15649 , +24191 , +13873 , +-15139 , +10661 , +4111 , +27447 , +-1891 , +11819 , +-31695 , +-8909 , +7223 , +6519 , +-25965 , +-19031 , +519 , +-5473 , +-17783 , +10085 , +-18375 , +24355 , +-29171 , +-19489 , +-19441 , +-2689 , +-9423 , +-16125 , +-22645 , +15437 , +13337 , +-26729 , +-1613 , +-14891 , +-19083 , +25103 , +22847 , +-26587 , +-29831 , +17371 , +25049 , +29103 , +30033 , +8531 , +-13361 , +-17829 , +-229 , +12281 , +7761 , +31015 , +-21919 , +-6303 , +23583 , +9777 , +-17135 , +27269 , +-23859 , +-20131 , +-4369 , +407 , +13429 , +-27287 , +-21097 , +-17311 , +-7187 , +20349 , +12011 , +-10985 , +23427 , +4943 , +2577 , +-5197 , +13877 , +5043 , +-28949 , +-20023 , +25447 , +14265 , +-27637 , +7911 , +-13033 , +-27589 , +-3279 , +-15005 , +-18275 , +-32253 , +27705 , +24503 , +-9757 , +-22443 , +9889 , +11869 , +-28395 , +-11247 , +-30345 , +15905 , +19163 , +-3255 , +-24113 , +12027 , +31515 , +3411 , +-12345 , +-27797 , +10787 , +-28823 , +-3599 , +-32695 , +-29589 , +-14917 , +-14507 , +25891 , +-25399 , +-9971 , +-16409 , +-15081 , +12585 , +10439 , +-3209 , +-6109 , +-32317 , +22933 , +30519 , +7427 , +-25893 , +-3973 , +-13913 , +-23673 , +-20241 , +-11669 , +-29421 , +-10389 , +-12427 , +-32669 , +18569 , +-19531 , +-9711 , +26623 , +26451 , +18047 , +22607 , +8341 , +12009 , +11615 , +985 , +-4917 , +-7307 , +-19921 , +-28371 , +22703 , +-11589 , +-24455 , +-21797 , +19535 , +32161 , +27447 , +-26825 , +27347 , +-26597 , +-17599 , +-32619 , +5651 , +6055 , +-487 , +-10239 , +-4433 , +2123 , +3393 , +-13713 , +10407 , +24577 , +-31201 , +16513 , +-29577 , +-30537 , +-5561 , +24757 , +31911 , +-10037 , +8285 , +3101 , +-10263 , +-19979 , +28009 , +19867 , +4017 , +32463 , +32429 , +13211 , +19273 , +18111 , +-25597 , +3139 , +-4241 , +4219 , +-25935 , +31791 , +25189 , +-13575 , +-22335 , +26543 , +25745 , +-2839 , +-30505 , +9843 , +-10865 , +-17745 , +22157 , +-1587 , +15823 , +-15655 , +27469 , +15719 , +-2905 , +24853 , +31651 , +19061 , +15085 , +26543 , +-31469 , +-31371 , +8719 , +20357 , +-23429 , +-29085 , +-26703 , +-4481 , +27879 , +2929 , +28087 , +29829 , +-10527 , +1597 , +-18709 , +-6401 , +24663 , +21395 , +20495 , +-11583 , +29923 , +-621 , +-4747 , +27789 , +-18765 , +10363 , +-31463 , +-10231 , +16343 , +27095 , +27953 , +-13005 , +29721 , +2615 , +1877 , +21597 , +31577 , +10601 , +20487 , +-12127 , +-919 , +15669 , +10963 , +4319 , +12373 , +-7537 , +-15641 , +-24785 , +-6577 , +31057 , +-10201 , +1755 , +-28681 , +-32139 , +20681 , +18649 , +-4547 , +14539 , +-6291 , +14019 , +30389 , +23601 , +19887 , +-5045 , +2413 , +-22707 , +-25783 , +7991 , +3919 , +-6205 , +24995 , +32213 , +-26395 , +12523 , +15339 , +-11273 , +-27189 , +8463 , +13235 , +11883 , +-17299 , +-20195 , +-11771 , +-19217 , +14967 , +-31005 , +13561 , +29359 , +-14951 , +16837 , +467 , +-15051 , +9453 , +-17931 , +-29801 , +-22041 , +-13629 , +-21971 , +1565 , +-24063 , +-26871 , +-17437 , +7603 , +25863 , +23055 , +28165 , +-13523 , +6587 , +12273 , +-12751 , +-17279 , +19873 , +19557 , +31849 , +10713 , +25325 , +20247 , +-3761 , +28471 , +-21253 , +-18309 , +32473 , +17023 , +-3255 , +-26833 , +913 , +-8681 , +-27913 , +1481 , +-14271 , +-2049 , +-2385 , +-28359 , +-32715 , +-8855 , +-25305 , +8085 , +-7183 , +-30005 , +26141 , +28539 , +-8605 , +6271 , +24005 , +-14361 , +-15197 , +21461 , +-16699 , +-3963 , +-28633 , +-9039 , +25261 , +2705 , +-27783 , +-24677 , +22773 , +25131 , +-24203 , +1119 , +-9111 , +-12239 , +7933 , +-22239 , +24365 , +-15217 , +-2259 , +501 , +-6871 , +-28377 , +-5601 , +-19211 , +25871 , +3351 , +11797 , +2783 , +26563 , +10399 , +-9413 , +19497 , +-24987 , +-30351 , +6619 , +25241 , +-22855 , +-14453 , +-29933 , +-26787 , +-18905 , +25235 , +-7149 , +-14941 , +25393 , +1959 , +13263 , +-9805 , +17773 , +16317 , +-13509 , +-2939 , +-23557 , +7797 , +16385 , +3033 , +-5509 , +2421 , +-32327 , +24273 , +7311 , +12351 , +31139 , +-26877 , +-63 , +-13175 , +11483 , +-4579 , +13323 , +-15591 , +-9961 , +12273 , +-3379 , +-17133 , +983 , +-3827 , +-21445 , +20957 , +-3033 , +-11805 , +15199 , +22895 , +-28981 , +9801 , +-6005 , +-209 , +3333 , +-9815 , +-3497 , +-21179 , +-31299 , +-6269 , +-10987 , +26743 , +-16055 , +16533 , +2245 , +-19327 , +20377 , +29807 , +28055 , +-26389 , +22775 , +-2169 , +7897 , +-8609 , +8503 , +24019 , +-7047 , +7299 , +-19081 , +25057 , +-1295 , +-20393 , +-17327 , +4213 , +27083 , +13061 , +-8037 , +-3949 , +-24431 , +-30409 , +-12655 , +-32731 , +-28091 , +8951 , +15261 , +-8945 , +1891 , +-31737 , +-3965 , +-3393 , +24137 , +-21327 , +20001 , +1105 , +29243 , +31523 , +17565 , +-5343 , +-7973 , +-25269 , +13613 , +-7711 , +26135 , +11047 , +-18883 , +13363 , +-31061 , +-32345 , +-19917 , +-21815 , +16663 , +30203 , +-10073 , +3049 , +-749 , +31089 , +-9711 , +-30563 , +29067 , +-14901 , +26123 , +28219 , +-18159 , +10779 , +25605 , +-2945 , +19683 , +-28653 , +24189 , +-32729 , +7759 , +-11807 , +-26439 , +12813 , +-31043 , +-1907 , +-14597 , +6841 , +17947 , +31429 , +-7873 , +-5511 , +18395 , +-27583 , +2157 , +30207 , +26221 , +19857 , +-2541 , +-6283 , +-6869 , +19583 , +-4449 , +-3053 , +-10013 , +1241 , +-20973 , +-4545 , +14015 , +25051 , +18245 , +3095 , +-15929 , +32762 , +28043 , +-17765 , +-28971 , +-28873 , +8447 , +21811 , +22281 , +30223 , +13613 , +6613 , +20685 , +19641 , +-21933 , +-20075 , +-14527 , +18699 , +20755 , +9667 , +10295 , +13007 , +-20305 , +-26245 , +-16211 , +-1891 , +-22595 , +-24639 , +-8253 , +32047 , +-16539 , +-31199 , +-26571 , +13631 , +-22251 , +27573 , +-10161 , +-21031 , +-8519 , +31953 , +4201 , +-27849 , +-8849 , +11019 , +8157 , +20499 , +-3381 , +-17955 , +-16255 , +-8821 , +5251 , +-2119 , +10395 , +-9363 , +-17749 , +31645 , +7005 , +-30445 , +13425 , +16185 , +8155 , +-18755 , +28495 , +-4749 , +5765 , +18279 , +-22329 , +-17007 , +-6887 , +23329 , +661 , +12997 , +28967 , +-17943 , +29043 , +-26547 , +-24325 , +-26879 , +-445 , +-28153 , +-25827 , +17605 , +-11825 , +-26235 , +-951 , +-3831 , +773 , +-16465 , +15333 , +493 , +-24671 , +-29999 , +-2311 , +11061 , +-6287 , +18751 , +22951 , +-11235 , +12813 , +-20389 , +24359 , +-6721 , +30471 , +8255 , +8245 , +-26153 , +-3927 , +25547 , +-6123 , +25135 , +-11989 , +17729 , +18435 , +-32665 , +-32147 , +-12455 , +-7887 , +26197 , +26667 , +-27939 , +7477 , +30429 , +-25415 , +-14145 , +-29427 , +16199 , +-24515 , +-22349 , +9871 , +-16107 , +29275 , +-13245 , +6245 , +-7069 , +3709 , +-2451 , +27779 , +-21837 , +-15743 , +6067 , +12573 , +14927 , +22515 , +-6469 , +24615 , +23071 , +-30777 , +-6813 , +15681 , +30205 , +-20339 , +10839 , +25149 , +-15473 , +18221 , +-14545 , +12805 , +-24669 , +-1505 , +8961 , +-5591 , +-17411 , +-225 , +8571 , +2757 , +13757 , +-31895 , +28289 , +19711 , +11305 , +-18835 , +-14793 , +-8189 , +-4077 , +26381 , +-28249 , +9333 , +25505 , +-21679 , +-20523 , +-24979 , +-23883 , +-30051 , +-15537 , +21995 , +-29769 , +8813 , +-9135 , +24021 , +16633 , +15755 , +-10409 , +-18071 , +14981 , +-10805 , +18483 , +22583 , +125 , +30775 , +18857 , +24733 , +9709 , +987 , +2437 , +-32585 , +-25561 , +-17689 , +26933 , +32223 , +-2405 , +7801 , +-29987 , +-17759 , +-18647 , +-29495 , +-23819 , +-5327 , +15107 , +6631 , +-6569 , +-20375 , +24569 , +-25871 , +-4889 , +20795 , +31325 , +23499 , +24729 , +19115 , +-19629 , +30557 , +20759 , +-4535 , +26541 , +19003 , +975 , +-14551 , +-24769 , +-2061 , +-26477 , +-683 , +13501 , +31407 , +23213 , +28623 , +-14835 , +13697 , +5751 , +-17151 , +1313 , +-32501 , +19313 , +-3661 , +-32429 , +10941 , +-27935 , +5777 , +-32459 , +24211 , +4831 , +21519 , +1263 , +-3259 , +22009 , +-6923 , +-30441 , +-28417 , +24387 , +-28857 , +-24055 , +-21857 , +21235 , +-9273 , +1975 , +-16027 , +-29835 , +-15385 , +10767 , +-5321 , +29445 , +3655 , +-6715 , +4937 , +-1587 , +4515 , +29111 , +-4765 , +115 , +5721 , +7357 , +5011 , +-28877 , +3671 , +-3071 , +18019 , +12673 , +-9327 , +-5665 , +18325 , +19987 , +-8955 , +-27339 , +18267 , +-11389 , +-1499 , +8505 , +23561 , +4451 , +-6951 , +-31267 , +-935 , +5587 , +-13837 , +-24419 , +-3055 , +26525 , +10281 , +17877 , +-13487 , +29901 , +1415 , +-7515 , +6201 , +-29241 , +15215 , +-14535 , +-19675 , +-15137 , +4365 , +-20045 , +17773 , +-30097 , +-9137 , +-20111 , +10903 , +23925 , +-7843 , +-1293 , +7181 , +26793 , +10389 , +-15317 , +-24745 , +25611 , +-32007 , +-16039 , +-20779 , +-27889 , +30003 , +23135 , +-27399 , +14115 , +16647 , +12445 , +29173 , +20171 , +-15031 , +3401 , +25595 , +-1727 , +27735 , +-12221 , +-13831 , +22149 , +-7913 , +30577 , +-26427 , +15353 , +-15775 , +-10601 , +15069 , +-27275 , +3337 , +6055 , +-3423 , +-13597 , +29765 , +-25687 , +14085 , +597 , +24757 , +21505 , +713 , +-26977 , +-12853 , +11349 , +-29129 , +-26003 , +-16939 , +-25379 , +27479 , +-16423 , +31843 , +-705 , +31911 , +31879 , +26443 , +-20509 , +-16813 , +-15811 , +30241 , +-16943 , +23021 , +9209 , +14375 , +-1279 , +-855 , +-16505 , +-32565 , +19261 , +-6131 , +-15457 , +31387 , +8047 , +-19151 , +-5513 , +22723 , +-15491 , +17009 , +-16163 , +24321 , +-27479 , +-15449 , +4565 , +30749 , +-18345 , +27879 , +20131 , +4831 , +27511 , +-20559 , +19315 , +32141 , +-32173 , +-32083 , +10339 , +30687 , +12521 , +-21539 , +-16601 , +13175 , +-19515 , +-31391 , +27931 , +31447 , +-3755 , +13473 , +-28201 , +14047 , +-21561 , +-13297 , +-26033 , +2751 , +23385 , +20315 , +-3993 , +15991 , +18747 , +4651 , +-22773 , +-20545 , +733 , +26961 , +15049 , +405 , +-16947 , +9865 , +16101 , +-15839 , +-15345 , +-10577 , +20213 , +-16581 , +-32527 , +14959 , +7417 , +16729 , +18023 , +-3701 , +-3089 , +25869 , +25311 , +-12153 , +-30995 , +19201 , +-24671 , +-10011 , +25789 , +22111 , +-16485 , +19423 , +-6163 , +12765 , +5829 , +-12383 , +-1169 , +-11481 , +-11791 , +7925 , +-29779 , +13533 , +1827 , +15245 , +-991 , +-251 , +9841 , +-25943 , +31083 , +-10737 , +-7343 , +17501 , +32754 , +-30655 , +11897 , +23875 , +28397 , +-11853 , +22575 , +4787 , +-32760 , +-4407 , +-3287 , +24953 , +-1157 , +-19159 , +-28703 , +-20719 , +153 , +27447 , +-6037 , +-21153 , +-17683 , +5633 , +-27433 , +-32537 , +23513 , +30153 , +-8201 , +-24195 , +-20319 , +26859 , +-11065 , +28041 , +-21235 , +-4761 , +7233 , +-6217 , +-15751 , +30919 , +-15439 , +-26827 , +23417 , +-8543 , +-31855 , +611 , +21477 , +32147 , +-24867 , +-17389 , +-14989 , +-5455 , +-3345 , +31545 , +213 , +-11393 , +20439 , +13613 , +2895 , +20083 , +-20177 , +-19877 , +30921 , +20959 , +28535 , +-27269 , +-1423 , +-30351 , +491 , +19793 , +31175 , +16939 , +26843 , +-5923 , +6207 , +-23335 , +-10107 , +17937 , +-5287 , +-2293 , +-17301 , +-27885 , +-13011 , +6791 , +-21717 , +-26127 , +6547 , +839 , +25301 , +-12591 , +-20559 , +23541 , +26059 , +-26445 , +4117 , +4311 , +20497 , +-13145 , +-4275 , +-1713 , +32035 , +-11389 , +5379 , +22483 , +5723 , +29207 , +-8309 , +26721 , +8631 , +-21519 , +17415 , +-19073 , +-22213 , +-18297 , +-23815 , +27559 , +-27955 , +-32009 , +18777 , +25417 , +16515 , +-21439 , +-2511 , +6463 , +-28291 , +-30729 , +15541 , +19909 , +23365 , +2941 , +6869 , +-32273 , +-3171 , +10171 , +-25507 , +2987 , +-7455 , +-31399 , +-7541 , +-2007 , +22227 , +7027 , +26657 , +29921 , +28159 , +-26407 , +-9721 , +-2299 , +-3191 , +6075 , +23637 , +-9867 , +-23667 , +5101 , +-27649 , +-22207 , +-28687 , +7061 , +19671 , +-10089 , +-16957 , +12905 , +5173 , +4165 , +-27897 , +24425 , +-24569 , +-10331 , +11549 , +23821 , +23153 , +-13535 , +14221 , +-7159 , +-5673 , +6435 , +23395 , +-30595 , +3461 , +32141 , +-8435 , +-24145 , +-22855 , +29625 , +-29017 , +13383 , +17993 , +-10519 , +-31525 , +22269 , +5803 , +-22207 , +-5061 , +2527 , +31389 , +14653 , +20753 , +-2051 , +14385 , +23985 , +-25665 , +7079 , +-30613 , +55 , +19345 , +-17119 , +-7337 , +-20945 , +2587 , +-15391 , +-8029 , +26673 , +12041 , +-11711 , +1205 , +26633 , +19581 , +9149 , +-11713 , +5419 , +23527 , +-23135 , +-1949 , +-8273 , +-23715 , +16975 , +-2753 , +14793 , +-5269 , +-10519 , +1289 , +26559 , +7543 , +-13419 , +-19029 , +24159 , +-7533 , +-14805 , +-2349 , +26619 , +23253 , +28535 , +-363 , +-14367 , +-31443 , +-15645 , +-9609 , +5201 , +28611 , +-8001 , +1299 , +32499 , +-14135 , +-9489 , +-10193 , +-15405 , +-6183 , +29733 , +13129 , +-2343 , +-6203 , +18843 , +11969 , +-6211 , +-5899 , +24393 , +13151 , +21637 , +5185 , +-31079 , +20091 , +-23947 , +30271 , +-26709 , +6789 , +21901 , +19241 , +-2813 , +5167 , +-381 , +-11483 , +20927 , +-19467 , +-10445 , +18223 , +12887 , +9277 , +-14947 , +1631 , +8149 , +-5137 , +-675 , +-27697 , +1413 , +25991 , +-2145 , +31977 , +-20177 , +23225 , +-1637 , +-16309 , +-4647 , +-25475 , +-7797 , +-13043 , +12529 , +-4183 , +29221 , +-19795 , +21009 , +9743 , +-11121 , +-26281 , +17707 , +-17389 , +-30503 , +6857 , +20299 , +-11585 , +31997 , +-27745 , +-21041 , +-8613 , +-32189 , +1337 , +10259 , +-7795 , +-9903 , +-24571 , +-31813 , +-29463 , +3215 , +-29089 , +21339 , +6921 , +-11985 , +6125 , +6073 , +16685 , +9879 , +-19095 , +11133 , +3143 , +27747 , +11527 , +29043 , +671 , +-22823 , +20295 , +15673 , +25059 , +-22047 , +27723 , +28287 , +-11839 , +25213 , +6579 , +14009 , +25347 , +-2363 , +24821 , +-32419 , +13085 , +-2987 , +-4559 , +30353 , +-29615 , +17745 , +22415 , +4207 , +-9663 , +9173 , +5389 , +15033 , +19205 , +-15375 , +16613 , +29959 , +29895 , +-5089 , +-18343 , +28561 , +-10277 , +13371 , +-19185 , +-26023 , +-27311 , +8955 , +30445 , +7911 , +12823 , +-7703 , +5741 , +15489 , +-16761 , +-16423 , +5999 , +32489 , +14981 , +14817 , +-11101 , +-14457 , +-29161 , +-15665 , +23369 , +-24269 , +-4485 , +299 , +-12383 , +-10663 , +1981 , +-17505 , +-3665 , +-15931 , +-15659 , +11259 , +-9569 , +20939 , +57 , +-3923 , +-30055 , +13833 , +7929 , +21681 , +24345 , +12187 , +-22443 , +9741 , +2505 , +-1069 , +-2093 , +-11571 , +8153 , +-11919 , +14303 , +1141 , +-9777 , +-6053 , +-29993 , +29181 , +7147 , +983 , +-18255 , +8261 , +24313 , +30531 , +14595 , +-14063 , +-28249 , +-25273 , +-3669 , +-24445 , +-30109 , +14739 , +-32293 , +12553 , +8621 , +-17125 , +29113 , +-31263 , +-29455 , +-6975 , +7789 , +23559 , +4577 , +-21863 , +-17721 , +-28233 , +-21941 , +419 , +15435 , +-29609 , +-20365 , +21491 , +-29487 , +-13053 , +11239 , +15227 , +-10091 , +27501 , +-10533 , +27961 , +20695 , +-20627 , +29693 , +20213 , +15085 , +-32539 , +-29483 , +12141 , +-23583 , +-6587 , +12435 , +-26335 , +-28543 , +18817 , +-13461 , +-18573 , +513 , +-17533 , +-20879 , +18041 , +-22777 , +-4563 , +24553 , +1307 , +-28337 , +7367 , +19497 , +8669 , +-14407 , +-25857 , +-4377 , +-26089 , +3307 , +16985 , +3353 , +923 , +-19875 , +30257 , +5957 , +-18171 , +-12289 , +-2521 , +19553 , +-8093 , +-18367 , +14119 , +-19161 , +17519 , +187 , +31435 , +-28691 , +30797 , +-2247 , +23915 , +17661 , +15807 , +-9383 , +4741 , +31599 , +-23077 , +-19295 , +1973 , +26239 , +-7093 , +7447 , +9785 , +-7325 , +19705 , +-10147 , +27359 , +32683 , +29779 , +-28863 , +3195 , +11 , +-5641 , +-30755 , +-5911 , +32709 , +-31239 , +-19929 , +28799 , +-16269 , +-16241 , +-7917 , +-14331 , +-15775 , +3151 , +-30687 , +22825 , +15723 , +-21789 , +-10885 , +-30335 , +4689 , +-2999 , +-32625 , +-12291 , +19599 , +-30595 , +9501 , +-7971 , +-13131 , +25539 , +-32039 , +10285 , +13123 , +19791 , +31107 , +19131 , +9207 , +-26491 , +6515 , +-6769 , +31151 , +-20303 , +-24381 , +17383 , +-32063 , +26429 , +-17195 , +17317 , +-8759 , +31847 , +-6023 , +8275 , +3853 , +23167 , +15997 , +23701 , +26187 , +31641 , +-26421 , +-32225 , +19735 , +29129 , +21495 , +-4049 , +-27211 , +2521 , +-28829 , +28809 , +-7575 , +-32639 , +16849 , +-13589 , +-17067 , +16929 , +-1415 , +3843 , +30927 , +11511 , +-22873 , +-13079 , +28733 , +-12843 , +13257 , +-3045 , +-16029 , +-28835 , +26135 , +-28431 , +5701 , +21435 , +-17513 , +8337 , +-26753 , +28883 , +-19511 , +-19599 , +-24811 , +-30971 , +21425 , +-27065 , +17357 , +10847 , +15985 , +-18045 , +21779 , +-10671 , +14953 , +-28857 , +-8387 , +9197 , +31429 , +-26651 , +-12173 , +-17763 , +-31331 , +21705 , +-10749 , +-3243 , +3719 , +-9729 , +2609 , +-22957 , +-25165 , +-18907 , +-30051 , +6995 , +23425 , +26849 , +-28913 , +-27579 , +-10089 , +8161 , +6357 , +27277 , +10881 , +-3515 , +-11623 , +13999 , +13503 , +21159 , +14519 , +-1391 , +30305 , +-4217 , +-24033 , +-14801 , +13349 , +-17845 , +16797 , +-12587 , +22275 , +19633 , +-18499 , +28881 , +-10417 , +25803 , +19745 , +5045 , +3149 , +-20621 , +27991 , +26887 , +-18357 , +-26295 , +31279 , +-645 , +10547 , +24099 , +-28779 , +-27477 , +17835 , +3855 , +20465 , +18257 , +-8533 , +-14653 , +20717 , +-9219 , +7567 , +-15211 , +16609 , +21069 , +26295 , +-23049 , +23705 , +6311 , +-30567 , +30323 , +19899 , +-7057 , +-28833 , +-12781 , +2457 , +-23363 , +5367 , +-18835 , +-14199 , +-30823 , +26037 , +-29171 , +-21061 , +-30283 , +20831 , +-23951 , +14233 , +-30563 , +209 , +-18299 , +4241 , +20341 , +-22517 , +15251 , +22655 , +-27089 , +27859 , +19137 , +-395 , +27459 , +22979 , +23819 , +17181 , +-21 , +-18971 , +-19533 , +-1143 , +20179 , +-26415 , +21313 , +-21353 , +-27303 , +4921 , +-17677 , +5817 , +5951 , +-15349 , +4797 , +19037 , +9447 , +12805 , +1983 , +-9031 , +-9209 , +-15923 , +3893 , +21799 , +-25879 , +-24439 , +18431 , +27393 , +-25065 , +31483 , +-19835 , +11251 , +-16227 , +22801 , +-2237 , +-23851 , +-10563 , +30213 , +29617 , +5895 , +-25815 , +27885 , +-14909 , +31807 , +-22857 , +-28195 , +-29213 , +10993 , +27293 , +-12427 , +-24735 , +30997 , +-23259 , +-7937 , +22383 , +19337 , +18667 , +16649 , +21151 , +14317 , +20111 , +-23437 , +14547 , +20207 , +26867 , +23059 , +-10317 , +10029 , +5099 , +26307 , +17327 , +16519 , +-2693 , +-18941 , +14193 , +22527 , +2445 , +14085 , +27089 , +-15357 , +-28625 , +15955 , +4697 , +29013 , +13885 , +983 , +21551 , +-26537 , +28837 , +-27263 , +-14443 , +-15639 , +-32225 , +5723 , +-9759 , +15041 , +9053 , +-24039 , +15345 , +30785 , +17865 , +-21185 , +5931 , +-22069 , +-5957 , +14763 , +16617 , +-5211 , +31027 , +-18505 , +9339 , +18499 , +-19443 , +-5171 , +-25701 , +6441 , +-32065 , +-20351 , +28003 , +-8131 , +-13687 , +-4829 , +-21555 , +12709 , +-22985 , +-26399 , +-22625 , +-14821 , +589 , +8789 , +-19727 , +19905 , +5067 , +5027 , +27157 , +7041 , +-24227 , +19219 , +-17635 , +16611 , +-26857 , +-24545 , +25549 , +12897 , +-9047 , +19733 , +7699 , +-29631 , +-6629 , +-2771 , +13053 , +4079 , +-2299 , +-24803 , +-21447 , +29139 , +-28605 , +31797 , +-9215 , +4009 , +49 , +-11275 , +29599 , +10077 , +-29345 , +-5085 , +-8101 , +-22951 , +13265 , +17771 , +9981 , +10601 , +27817 , +1133 , +-2631 , +17677 , +-1935 , +-8359 , +9395 , +-20915 , +9155 , +26637 , +23789 , +23577 , +32395 , +2721 , +7623 , +14623 , +32183 , +-26487 , +-9997 , +32287 , +-135 , +-18389 , +23789 , +19653 , +10743 , +4335 , +17905 , +-23805 , +-25469 , +-29723 , +-21129 , +16105 , +27483 , +-32557 , +-12241 , +-29961 , +-8745 , +10189 , +-7573 , +11005 , +26407 , +10065 , +-13533 , +16751 , +-11895 , +-26913 , +-661 , +1339 , +5121 , +19981 , +10345 , +-16343 , +-13673 , +-10203 , +-2615 , +-12887 , +-14079 , +-7113 , +-28989 , +-19921 , +-16409 , +-30287 , +8063 , +-7409 , +27803 , +14719 , +4381 , +22223 , +19273 , +-19557 , +12841 , +30209 , +17331 , +-9945 , +-31347 , +-31587 , +18543 , +-19707 , +-4079 , +7129 , +24723 , +-31505 , +31823 , +-13189 , +5113 , +17685 , +27943 , +-32327 , +-19987 , +20519 , +-10557 , +-17265 , +27243 , +-19971 , +-2559 , +16271 , +-20007 , +-9565 , +-393 , +17221 , +-6345 , +6135 , +-26911 , +-13559 , +-19237 , +-21567 , +-17377 , +12887 , +9133 , +-10685 , +17069 , +-30041 , +-10021 , +-21151 , +-20843 , +-7741 , +30223 , +6185 , +-26125 , +2215 , +-27605 , +-14603 , +25057 , +-3377 , +20609 , +32764 , +20975 , +17941 , +-7033 , +-26513 , +1577 , +13065 , +16401 , +-3567 , +15231 , +11719 , +7693 , +21837 , +-14651 , +-24757 , +-29771 , +32715 , +-5589 , +10067 , +23113 , +-16493 , +-16081 , +-31055 , +29515 , +29331 , +-1247 , +-13793 , +-30931 , +17101 , +-25589 , +-12895 , +3735 , +30427 , +-967 , +-20395 , +5651 , +12049 , +-16859 , +20685 , +-13239 , +-6377 , +-3339 , +27111 , +19129 , +5117 , +9585 , +26665 , +-28427 , +14029 , +-31877 , +-28783 , +10831 , +15283 , +-8693 , +-30219 , +30233 , +32131 , +-18531 , +-2603 , +2657 , +17889 , +6453 , +3511 , +10525 , +8651 , +26063 , +-3 , +-16403 , +-7493 , +-7077 , +3901 , +-5555 , +-23493 , +14387 , +4893 , +28241 , +-20993 , +-32750 , +29089 , +11229 , +-30089 , +21393 , +10511 , +-2469 , +10737 , +22295 , +573 , +-12049 , +27175 , +-25001 , +-31883 , +1337 , +-9633 , +-27317 , +-17475 , +3205 , +5115 , +-22625 , +32443 , +-15483 , +32667 , +24251 , +10509 , +-8051 , +-8531 , +11817 , +-31467 , +9283 , +29061 , +-22885 , +-6045 , +15583 , +4603 , +18265 , +8571 , +-11299 , +6783 , +-22971 , +20029 , +-16841 , +29105 , +9795 , +12979 , +-14559 , +-28039 , +-3009 , +10341 , +3387 , +-5987 , +-32099 , +15939 , +27213 , +23011 , +15155 , +-24343 , +-8837 , +21403 , +-24635 , +-7293 , +28673 , +13501 , +-28425 , +16671 , +-29591 , +27785 , +-3129 , +28297 , +16453 , +9613 , +28037 , +5283 , +24677 , +-10929 , +28237 , +-29893 , +1933 , +-30627 , +16897 , +-5023 , +26549 , +17121 , +24501 , +6211 , +26035 , +19907 , +-20553 , +-15995 , +-2171 , +-14283 , +-5 , +6675 , +-17161 , +21979 , +24345 , +14469 , +-13589 , +16719 , +-27193 , +-12825 , +8453 , +-5303 , +30407 , +17441 , +-15897 , +-8653 , +15721 , +-9023 , +-6675 , +24125 , +-19841 , +-6049 , +16477 , +-12811 , +20441 , +-20885 , +-12503 , +-16535 , +6707 , +7565 , +11547 , +2477 , +27063 , +-9095 , +-8551 , +-17655 , +22769 , +-11451 , +-28457 , +16253 , +4683 , +-15035 , +-15477 , +-27675 , +-19463 , +4963 , +-10961 , +-8819 , +643 , +16115 , +-5715 , +15943 , +-24147 , +17677 , +-23641 , +15627 , +3065 , +27243 , +10267 , +-25851 , +153 , +-28747 , +25775 , +-4813 , +-24597 , +-22941 , +4183 , +-11653 , +-4497 , +24079 , +24219 , +7749 , +-2495 , +-23981 , +-8889 , +-12401 , +16141 , +283 , +29865 , +11401 , +-11123 , +-28289 , +577 , +-9555 , +-27785 , +29471 , +-31231 , +19281 , +-2813 , +32243 , +23037 , +21705 , +4311 , +15019 , +27823 , +20469 , +3463 , +-17535 , +-2659 , +-28063 , +-18557 , +28051 , +-25433 , +-25385 , +30365 , +31425 , +-29781 , +-10631 , +23029 , +-11271 , +25289 , +11357 , +29301 , +31769 , +-30951 , +28063 , +13263 , +11075 , +-15397 , +-17415 , +5099 , +-7501 , +-18881 , +-5915 , +8417 , +-30433 , +-1141 , +5925 , +-14983 , +10113 , +-26145 , +30953 , +29723 , +-8573 , +-25747 , +-32159 , +28747 , +11327 , +21541 , +26835 , +28317 , +-25937 , +18943 , +17973 , +17199 , +28271 , +14241 , +-18101 , +22181 , +28201 , +8615 , +23091 , +6557 , +23131 , +-2483 , +-9337 , +11939 , +11711 , +-20557 , +12275 , +-32075 , +-16873 , +28813 , +-29627 , +3115 , +-10869 , +-27815 , +-25067 , +26685 , +23679 , +9253 , +-12597 , +3829 , +-21527 , +-17225 , +-5309 , +21927 , +-24527 , +15181 , +2017 , +-2071 , +-31615 , +19411 , +-1747 , +24331 , +28317 , +15259 , +14561 , +24591 , +9023 , +3993 , +-28787 , +-22489 , +6897 , +21779 , +23205 , +-28769 , +-16545 , +-23327 , +-14559 , +-29853 , +31021 , +20765 , +-10095 , +-2831 , +-22949 , +13669 , +-27467 , +24783 , +4367 , +8587 , +11157 , +15241 , +-261 , +-10545 , +29721 , +-6875 , +28965 , +3993 , +-27359 , +789 , +-21427 , +-30293 , +13091 , +16577 , +-24127 , +-29979 , +-1481 , +13929 , +20651 , +-10129 , +-9033 , +-20819 , +-18437 , +-26501 , +-8617 , +637 , +28849 , +5753 , +-15427 , +-15465 , +-30535 , +-7731 , +32401 , +28025 , +-18873 , +16141 , +-20955 , +21721 , +31653 , +25523 , +3193 , +-29275 , +21403 , +29787 , +8167 , +-141 , +32307 , +-17039 , +2347 , +24697 , +-31197 , +7799 , +-14841 , +20233 , +5787 , +8111 , +-16307 , +16779 , +14751 , +-21921 , +393 , +-31505 , +-26911 , +-9343 , +-7413 , +421 , +-13547 , +-5893 , +-28031 , +-229 , +28623 , +-28323 , +17177 , +-25169 , +-5163 , +3605 , +25353 , +16171 , +-23559 , +41 , +-21067 , +-27203 , +-23437 , +20327 , +29247 , +-28309 , +23225 , +29739 , +-6495 , +-7155 , +30673 , +9099 , +-8373 , +21447 , +-27853 , +-10729 , +-15569 , +-27649 , +-23019 , +8457 , +5217 , +-9001 , +-2225 , +23045 , +25903 , +-1759 , +-28755 , +32079 , +4535 , +733 , +-12605 , +-12679 , +-27137 , +-31191 , +14415 , +11183 , +-10097 , +17087 , +4617 , +-29859 , +16773 , +17389 , +-5637 , +-25491 , +-2509 , +-30963 , +-25247 , +255 , +4397 , +-6025 , +-2057 , +7081 , +12017 , +-28929 , +-31783 , +-6371 , +9963 , +-29201 , +-24109 , +-12173 , +18723 , +-2699 , +-32189 , +3031 , +-1985 , +2473 , +5733 , +23489 , +-2007 , +-10249 , +-28105 , +-15691 , +18729 , +-7391 , +-26933 , +6001 , +-6289 , +7603 , +-25317 , +-3157 , +18231 , +-5381 , +-18067 , +-2743 , +-6815 , +24195 , +20251 , +-13805 , +-15231 , +29189 , +-13065 , +-523 , +11899 , +27109 , +2597 , +941 , +-28001 , +8239 , +23397 , +28683 , +-10179 , +28163 , +-1801 , +-8283 , +-581 , +27541 , +-13071 , +32523 , +23599 , +-16727 , +16915 , +-21111 , +26493 , +-20609 , +11043 , +-19879 , +17123 , +15443 , +23235 , +-937 , +539 , +-7339 , +971 , +-7101 , +-4367 , +23325 , +31259 , +26991 , +-21675 , +-3669 , +27647 , +-7937 , +-30727 , +-13871 , +11255 , +3993 , +-6293 , +-20675 , +8989 , +-23127 , +1445 , +-18209 , +1013 , +-27125 , +-979 , +29167 , +-10803 , +16201 , +23207 , +-16035 , +28805 , +-8357 , +11247 , +18381 , +-32517 , +18893 , +-16461 , +27661 , +-21033 , +22667 , +4237 , +-12789 , +-2845 , +3849 , +7823 , +22613 , +-10011 , +-6137 , +5739 , +-22523 , +30719 , +17853 , +-25343 , +837 , +8821 , +31901 , +6009 , +-27075 , +-30185 , +28811 , +18395 , +11925 , +8719 , +15499 , +5673 , +11617 , +-14533 , +-8955 , +-8717 , +-6237 , +18695 , +21617 , +6263 , +11587 , +-5439 , +17053 , +-17619 , +11899 , +30069 , +26201 , +8939 , +30687 , +-3513 , +435 , +-7311 , +15561 , +-23231 , +-26445 , +21391 , +-22439 , +24757 , +653 , +11695 , +27879 , +-14063 , +17755 , +7417 , +18941 , +-24265 , +13401 , +-28959 , +-16173 , +-18599 , +18579 , +-24251 , +-20673 , +-30135 , +-21461 , +-31483 , +2357 , +16213 , +-4093 , +11545 , +26809 , +165 , +25601 , +-24025 , +-21411 , +23559 , +-30275 , +-11615 , +23603 , +-17837 , +-26175 , +14167 , +3397 , +-30917 , +-27845 , +9361 , +31635 , +8611 , +-12743 , +8107 , +-28023 , +11393 , +-30625 , +4391 , +7153 , +22571 , +25631 , +-21689 , +19827 , +15413 , +21107 , +-8921 , +-4985 , +22985 , +-8431 , +-21933 , +16625 , +-8581 , +22311 , +16093 , +-29255 , +16293 , +-15723 , +-26627 , +18589 , +17981 , +10137 , +-26335 , +-14317 , +-23763 , +4375 , +-6781 , +-24649 , +-23507 , +-12475 , +22091 , +25417 , +8471 , +27373 , +25889 , +2083 , +14789 , +-15591 , +25411 , +-25291 , +-925 , +-12969 , +-10973 , +-28299 , +-29621 , +28773 , +-13707 , +16605 , +-7847 , +-3719 , +-29993 , +-29 , +-18489 , +27621 , +28375 , +23917 , +-14203 , +19295 , +15767 , +-11443 , +-7669 , +16567 , +-6429 , +-25289 , +-1603 , +-22269 , +-3643 , +-4551 , +-12875 , +-8345 , +30623 , +15541 , +12069 , +28993 , +967 , +-8999 , +-29401 , +-21273 , +12185 , +-24177 , +-10211 , +-32035 , +21265 , +-17405 , +21897 , +12687 , +8675 , +-28273 , +31833 , +-19577 , +-29415 , +-16327 , +29135 , +26659 , +-16099 , +2473 , +16079 , +-4397 , +-26527 , +23713 , +21943 , +-21301 , +23147 , +-19209 , +-32581 , +-2753 , +8049 , +2571 , +-12097 , +19481 , +-20361 , +959 , +-23387 , +-17613 , +15323 , +-21007 , +24883 , +-19959 , +-18823 , +-7571 , +-3747 , +26617 , +16695 , +-24209 , +-22745 , +14585 , +27435 , +4241 , +-27399 , +-2869 , +-22489 , +22605 , +-2185 , +-26443 , +-11307 , +6123 , +-14377 , +27587 , +6481 , +-22529 , +3779 , +-2705 , +5953 , +-7331 , +3999 , +-14615 , +-26521 , +-20839 , +-7051 , +-28991 , +-18237 , +-2573 , +-24001 , +28457 , +-12509 , +23003 , +-25149 , +3755 , +-3267 , +16865 , +-5905 , +23387 , +30789 , +-29139 , +-24409 , +30871 , +13325 , +-24703 , +9003 , +-12485 , +-5483 , +-4703 , +-14621 , +-18345 , +-18907 , +-7079 , +10683 , +-17809 , +-15387 , +16107 , +-20223 , +-11993 , +15607 , +-26093 , +20911 , +-18555 , +-19443 , +29807 , +14675 , +-21337 , +-4223 , +21891 , +28509 , +-21773 , +26605 , +21297 , +1783 , +-30241 , +21317 , +-21081 , +-1693 , +535 , +-27537 , +-17949 , +16591 , +3139 , +26453 , +-11615 , +19369 , +-28105 , +8579 , +-30757 , +24707 , +-5459 , +-8383 , +-15171 , +2653 , +6015 , +29987 , +9243 , +9609 , +15965 , +32295 , +11117 , +-23305 , +21509 , +-8627 , +-23479 , +-22503 , +29181 , +-28243 , +-13233 , +-1741 , +-12599 , +8205 , +-27723 , +-29641 , +-12127 , +-29441 , +-24025 , +5657 , +12975 , +7283 , +23127 , +21679 , +-19263 , +-15407 , +-27681 , +7929 , +19843 , +-24683 , +17357 , +-10735 , +22333 , +17761 , +-13427 , +20073 , +-20737 , +19095 , +9827 , +-13895 , +15971 , +-10381 , +-21143 , +6473 , +-6209 , +-24927 , +-22011 , +-32565 , +19681 , +4437 , +28379 , +29117 , +26695 , +10211 , +12109 , +-18639 , +28883 , +-26919 , +19821 , +10805 , +7 , +-14185 , +22137 , +-31075 , +-3399 , +29535 , +26065 , +30823 , +-941 , +9211 , +9841 , +31115 , +25727 , +-27447 , +10981 , +-26541 , +-6295 , +10587 , +-11321 , +-16835 , +12405 , +26245 , +31917 , +-28863 , +-6289 , +-16635 , +10159 , +31165 , +-14253 , +-29559 , +24403 , +3773 , +-17035 , +-29357 , +-30965 , +15069 , +29759 , +-16817 , +21035 , +30623 , +25709 , +-5721 , +-26269 , +-29381 , +-15935 , +-15905 , +18099 , +-763 , +20537 , +-7831 , +-28697 , +-21447 , +-27959 , +-31039 , +14221 , +-6313 , +19609 , +25863 , +3181 , +22015 , +-13133 , +24847 , +24451 , +-2237 , +-959 , +-27905 , +-22411 , +-16765 , +-22719 , +25699 , +4235 , +-5951 , +-2111 , +8909 , +7209 , +-23939 , +-25703 , +-8477 , +10945 , +5645 , +-29541 , +-4101 , +1367 , +31345 , +-3247 , +-3015 , +13161 , +15025 , +7221 , +-23269 , +20087 , +-12885 , +-2207 , +22685 , +3053 , +22137 , +6873 , +-31033 , +13735 , +-23237 , +-16597 , +11209 , +18657 , +-20355 , +-20801 , +24219 , +-3149 , +7935 , +-24711 , +-3067 , +10499 , +-1509 , +-4347 , +-31165 , +775 , +8343 , +14717 , +-18149 , +11315 , +-28165 , +-15697 , +4721 , +1723 , +10863 , +10703 , +16225 , +19073 , +-6389 , +24493 , +7643 , +20881 , +19129 , +22387 , +25267 , +-13539 , +-1149 , +27091 , +13379 , +3311 , +12401 , +-7473 , +-28297 , +-17563 , +2015 , +-19999 , +-8847 , +-27 , +24151 , +-19269 , +26521 , +1499 , +15849 , +-27525 , +18487 , +-2517 , +32251 , +-21141 , +27021 , +10541 , +-21587 , +-1745 , +5485 , +-14559 , +-11607 , +29571 , +-8367 , +-28883 , +16003 , +-3727 , +17139 , +-817 , +-13183 , +-7411 , +-12439 , +-31783 , +-6647 , +-2141 , +14003 , +6885 , +-17563 , +7291 , +6625 , +-13231 , +-10457 , +-12793 , +-5729 , +-31305 , +-24067 , +13221 , +-19633 , +-8733 , +-4341 , +-563 , +12973 , +2379 , +10431 , +32463 , +-47 , +-19195 , +13869 , +-2551 , +12765 , +67 , +-20253 , +-31327 , +19977 , +19533 , +-31927 , +-13639 , +-9413 , +6899 , +-30865 , +-28627 , +29221 , +-19579 , +15977 , +-27707 , +-24105 , +-14769 , +14377 , +-10771 , +-32551 , +-14699 , +17369 , +27639 , +17097 , +13051 , +169 , +19653 , +-21915 , +-31599 , +-6351 , +4103 , +-20431 , +-965 , +25413 , +6139 , +13705 , +1717 , +5711 , +7571 , +7225 , +28417 , +-9693 , +-26813 , +-25963 , +5989 , +-25509 , +-3551 , +9233 , +28899 , +-21971 , +5557 , +-16805 , +26925 , +-31547 , +10783 , +6897 , +1827 , +-10729 , +6357 , +19771 , +28099 , +-25025 , +-16417 , +29981 , +32167 , +12631 , +20363 , +13847 , +-13059 , +7629 , +-13661 , +21211 , +11775 , +-27851 , +8491 , +17757 , +31717 , +25009 , +-8817 , +11131 , +-6557 , +10681 , +-9109 , +-8189 , +29601 , +-11139 , +1713 , +-26535 , +-3917 , +-4937 , +-31119 , +-8571 , +2185 , +-4089 , +28161 , +16339 , +-18059 , +12489 , +18883 , +-30747 , +-7913 , +24687 , +-27561 , +-8111 , +5851 , +23123 , +-31403 , +-21325 , +-29455 , +18201 , +12927 , +31559 , +12221 , +-20353 , +31615 , +-7677 , +-17441 , +-25163 , +-18397 , +-24533 , +665 , +20541 , +-24315 , +-9103 , +5335 , +-18117 , +27353 , +-10367 , +-29543 , +16205 , +-29679 , +-5341 , +-21261 , +-4889 , +9505 , +11725 , +-28535 , +-24787 , +-31951 , +-27965 , +7803 , +19779 , +-19107 , +-8539 , +-541 , +43 , +-21405 , +18569 , +16341 , +-27877 , +-8993 , +8093 , +-2103 , +-11177 , +-9209 , +19761 , +31385 , +7815 , +-4389 , +2903 , +31743 , +655 , +997 , +-22529 , +-15743 , +6631 , +3949 , +-21377 , +-22027 , +-26253 , +16945 , +16831 , +11377 , +-17185 , +4765 , +10435 , +-22075 , +-23953 , +-28539 , +8135 , +9589 , +-20641 , +-1191 , +3035 , +13103 , +5301 , +4833 , +-16653 , +18881 , +-29537 , +6773 , +-19831 , +-19303 , +-6079 , +1713 , +-29015 , +-9295 , +-31205 , +-12881 , +-10859 , +6673 , +18645 , +20933 , +-29739 , +-9529 , +9885 , +-8529 , +13521 , +13395 , +-5893 , +-20139 , +-1045 , +-17745 , +13617 , +-32257 , +25109 , +-16451 , +29959 , +-30457 , +18409 , +-17857 , +-18385 , +-2535 , +-21437 , +2901 , +9749 , +20963 , +-2221 , +-9615 , +6199 , +-15785 , +10817 , +16333 , +29955 , +-22183 , +-13513 , +30057 , +25389 , +-27137 , +-6655 , +18045 , +-4735 , +69 , +-1753 , +30067 , +-20671 , +-14525 , +10109 , +20579 , +8447 , +-5657 , +-31165 , +11267 , +-25109 , +29235 , +-8267 , +-729 , +-17993 , +2795 , +-15827 , +-14157 , +-281 , +14289 , +13233 , +8729 , +-21075 , +-22431 , +-7661 , +28745 , +-27841 , +-25343 , +10115 , +12593 , +-28243 , +-10557 , +-17493 , +-3151 , +-4033 , +2449 , +26947 , +16399 , +3145 , +18675 , +-24529 , +9979 , +-32129 , +26423 , +15377 , +-20741 , +26841 , +-16581 , +22373 , +-10137 , +-20257 , +24721 , +-31977 , +28645 , +19077 , +5707 , +15003 , +26455 , +8067 , +16421 , +-4987 , +-4765 , +32563 , +-2497 , +28581 , +-1193 , +4827 , +28511 , +15509 , +-28235 , +-3433 , +8601 , +17375 , +23323 , +-3425 , +-27243 , +-18297 , +-4669 , +-16083 , +25665 , +-22739 , +25469 , +-4915 , +22277 , +-20061 , +-32738 , +27447 , +8841 , +-14593 , +7811 , +-18263 , +-19497 , +12345 , +7167 , +10175 , +-30677 , +-14011 , +31319 , +31175 , +1815 , +-16731 , +-4031 , +22425 , +22345 , +-22655 , +-24497 , +-15623 , +-23109 , +21573 , +11887 , +6241 , +22381 , +10677 , +-5147 , +-18081 , +7583 , +24707 , +20921 , +-2187 , +25735 , +365 , +-32323 , +22371 , +5259 , +-2609 , +1527 , +-15099 , +7669 , +1215 , +-31069 , +-12369 , +-14547 , +5281 , +-20827 , +-30975 , +13683 , +-30393 , +-2423 , +4157 , +10265 , +5757 , +-29201 , +-29661 , +24111 , +-8405 , +7053 , +25929 , +-24883 , +14567 , +-29789 , +-24847 , +-9285 , +-5099 , +-23309 , +15453 , +26287 , +18549 , +-25543 , +22707 , +-20211 , +-6595 , +24101 , +1861 , +-29169 , +27579 , +-14383 , +-27525 , +28553 , +12127 , +-31303 , +16155 , +-27361 , +3677 , +-11981 , +551 , +-23047 , +20415 , +-15255 , +-30919 , +-21249 , +-5119 , +31949 , +-9897 , +-4209 , +4393 , +-15337 , +-4021 , +-26955 , +15195 , +30649 , +-21385 , +-23837 , +-17931 , +26323 , +23355 , +8749 , +-1757 , +-8523 , +23483 , +8441 , +26619 , +-25137 , +-957 , +19775 , +21271 , +25897 , +10267 , +-15303 , +-29789 , +-8091 , +-545 , +679 , +13057 , +7207 , +-6565 , +28535 , +-32039 , +17177 , +17369 , +30987 , +-5709 , +-9885 , +20997 , +-17175 , +21523 , +11931 , +20029 , +12793 , +-1529 , +15935 , +-32659 , +-13003 , +-30389 , +-18759 , +15461 , +-26393 , +985 , +24261 , +29615 , +-18847 , +11015 , +-28301 , +-4117 , +16945 , +-12521 , +2207 , +-12887 , +-27935 , +-9389 , +-21015 , +20411 , +-13791 , +30381 , +-21975 , +-23797 , +12429 , +4295 , +27499 , +-21761 , +21473 , +-19561 , +-9885 , +28229 , +24489 , +29053 , +28777 , +15409 , +-22393 , +18389 , +31475 , +8851 , +-7713 , +19993 , +8577 , +-13299 , +-2541 , +-30353 , +-30425 , +24309 , +-1731 , +15561 , +-18313 , +29853 , +11879 , +3447 , +31483 , +-16071 , +-26815 , +-11197 , +-1227 , +-31697 , +1621 , +29445 , +19213 , +22769 , +11209 , +-31039 , +-27953 , +-32681 , +-27503 , +20027 , +7843 , +14965 , +5155 , +-25333 , +643 , +18679 , +-28489 , +13119 , +-29521 , +12781 , +-22019 , +20843 , +16049 , +23347 , +12879 , +-7869 , +-31543 , +-27073 , +-3471 , +2743 , +-7191 , +13435 , +-20537 , +-29311 , +-10705 , +15391 , +-4859 , +-18613 , +3547 , +-10873 , +23923 , +20025 , +22217 , +-30453 , +-32099 , +18443 , +-12699 , +25941 , +27793 , +-23117 , +-21977 , +-22975 , +5263 , +19303 , +17547 , +-3029 , +19015 , +11583 , +-22397 , +-11315 , +-21615 , +-22447 , +21367 , +24215 , +-24925 , +24633 , +26041 , +-9341 , +-14647 , +31045 , +-1667 , +20593 , +-5219 , +-30977 , +-10157 , +-23553 , +-13633 , +1867 , +18201 , +26585 , +-13297 , +-15877 , +8319 , +-7265 , +4195 , +-6931 , +-2575 , +30771 , +-11585 , +13469 , +28439 , +-3181 , +-27631 , +10561 , +-24627 , +-4815 , +2399 , +20575 , +-29543 , +-15669 , +17545 , +-13595 , +-27229 , +19911 , +3967 , +16321 , +47 , +-5885 , +-3593 , +6907 , +22159 , +-8397 , +-9823 , +29001 , +-10585 , +-9797 , +-8981 , +24623 , +-22827 , +26623 , +4137 , +17037 , +2423 , +14145 , +-6819 , +-28229 , +18143 , +4857 , +3685 , +-13535 , +-31293 , +17831 , +22963 , +12887 , +19009 , +29237 , +-32373 , +-14423 , +-11441 , +32199 , +26037 , +19273 , +3767 , +-24043 , +-22599 , +-23347 , +23437 , +16451 , +8595 , +-30883 , +-11483 , +-29635 , +12019 , +-21955 , +20627 , +-22391 , +16617 , +28137 , +-4455 , +19103 , +-19415 , +17841 , +13347 , +32711 , +25017 , +-16949 , +-22717 , +-21905 , +-7633 , +30189 , +-349 , +20475 , +-1173 , +-6043 , +-22143 , +-12501 , +12485 , +21941 , +-6621 , +-26905 , +-4655 , +-21339 , +7893 , +-2659 , +17295 , +-14625 , +-15013 , +6423 , +-20443 , +-11775 , +25837 , +22227 , +-5863 , +15679 , +8875 , +21723 , +8201 , +883 , +25755 , +11041 , +-17955 , +-22087 , +-10469 , +5457 , +-3961 , +-13695 , +-30501 , +-13015 , +22325 , +-31437 , +21849 , +9561 , +-18161 , +-21959 , +21969 , +-817 , +19049 , +-1119 , +-28481 , +8861 , +-23427 , +23087 , +-24629 , +16965 , +-31833 , +14073 , +-31669 , +28819 , +-16365 , +8575 , +25145 , +28927 , +30979 , +-13763 , +22949 , +19317 , +-5511 , +20941 , +14007 , +19133 , +-6789 , +15477 , +12319 , +-1211 , +25281 , +-7609 , +27661 , +17029 , +10229 , +-19533 , +-31827 , +9933 , +-2203 , +10915 , +-17119 , +24485 , +16959 , +-16367 , +13297 , +18081 , +-10935 , +-16867 , +-22517 , +16565 , +30737 , +18091 , +11061 , +14363 , +-2381 , +26231 , +25861 , +16021 , +-29179 , +-29523 , +-23197 , +-4003 , +12885 , +16129 , +32117 , +-20629 , +-22367 , +25161 , +5911 , +20307 , +-5555 , +-4209 , +739 , +18851 , +-13481 , +28085 , +-19311 , +4785 , +23319 , +1917 , +26117 , +-22793 , +-2185 , +-27085 , +-26441 , +-5905 , +-30047 , +30897 , +-4683 , +-6299 , +-5309 , +-28917 , +-29671 , +-23471 , +-10435 , +12951 , +-12807 , +29747 , +-32545 , +-32113 , +27631 , +-29213 , +9889 , +-8925 , +-8451 , +-7441 , +-21159 , +-8939 , +12567 , +-10123 , +-19215 , +-19501 , +-3053 , +-1933 , +8103 , +14339 , +-26851 , +13221 , +-31815 , +-32597 , +-11593 , +-13349 , +32679 , +25789 , +25389 , +32467 , +26855 , +-18633 , +-13939 , +2445 , +19741 , +-26699 , +19231 , +-25557 , +-16939 , +-20595 , +-6303 , +22075 , +24249 , +-19611 , +31861 , +25503 , +-20921 , +329 , +-11737 , +-11815 , +271 , +-19637 , +-15529 , +-18967 , +10085 , +-367 , +15865 , +-17753 , +-19043 , +14067 , +20881 , +-20593 , +26307 , +20241 , +1053 , +12331 , +-28213 , +11501 , +9629 , +-1063 , +10583 , +-21761 , +-9729 , +5683 , +15845 , +-25135 , +4507 , +18395 , +31367 , +-18923 , +-22479 , +6105 , +-27617 , +-26817 , +25171 , +-10897 , +8985 , +-1383 , +-32401 , +-13703 , +-8293 , +14049 , +9781 , +11833 , +-18367 , +1113 , +14749 , +-3911 , +-17573 , +-10905 , +5207 , +-2399 , +19097 , +-25689 , +-25403 , +-8821 , +-28339 , +20873 , +4985 , +-7971 , +-19167 , +8291 , +17951 , +-2269 , +-18103 , +31499 , +24837 , +-16411 , +-29629 , +1263 , +5893 , +23041 , +14347 , +-25167 , +22535 , +-17795 , +-21293 , +26937 , +19961 , +-25621 , +7737 , +11345 , +-10181 , +-25039 , +27399 , +-10825 , +15783 , +-20753 , +-30877 , +-29761 , +19711 , +21073 , +24965 , +5731 , +-23579 , +-7065 , +14587 , +-545 , +21593 , +27387 , +-8107 , +13765 , +-24403 , +4079 , +-7839 , +-21351 , +1531 , +-9201 , +-1049 , +-26649 , +19745 , +-13715 , +-2341 , +-11045 , +-9669 , +-13255 , +15383 , +13661 , +-3439 , +-10989 , +13973 , +4515 , +12571 , +-30741 , +-5339 , +-2489 , +-7825 , +-25515 , +-15451 , +-14611 , +31041 , +-27551 , +1211 , +11593 , +-6059 , +-9485 , +-6645 , +-21309 , +-2307 , +-7525 , +-15123 , +12943 , +27401 , +23795 , +27051 , +31289 , +11079 , +8809 , +-10445 , +7883 , +6517 , +-7517 , +-25261 , +-20381 , +-9537 , +13657 , +9583 , +-22977 , +18095 , +9117 , +-3655 , +-31389 , +-19283 , +-15929 , +18153 , +5037 , +-8207 , +-3651 , +14457 , +-4251 , +-26113 , +-6699 , +-28841 , +25441 , +927 , +31785 , +-31971 , +-12395 , +-31665 , +2673 , +-16945 , +32305 , +14403 , +-19885 , +-24049 , +15665 , +3291 , +-10679 , +19411 , +-27527 , +17301 , +-14609 , +17317 , +-3979 , +-27765 , +16605 , +23631 , +-26337 , +-24211 , +-11523 , +-19683 , +-12885 , +1521 , +-14997 , +19091 , +-9073 , +-25903 , +-26429 , +14239 , +-28635 , +17985 , +-18943 , +-9895 , +-14403 , +-789 , +26321 , +4917 , +-27333 , +12895 , +-20881 , +451 , +-18649 , +28689 , +6907 , +8665 , +-14515 , +19151 , +10067 , +25179 , +-2607 , +28347 , +17763 , +6245 , +-22331 , +-1597 , +10509 , +19985 , +-10169 , +-9071 , +27503 , +25505 , +32533 , +31249 , +7881 , +31553 , +-2143 , +15709 , +27341 , +-22725 , +-25165 , +24121 , +-13959 , +21165 , +-29577 , +-29679 , +-909 , +-9017 , +-12001 , +-18587 , +21209 , +-8579 , +-5647 , +-20021 , +22433 , +4803 , +-5659 , +-9117 , +-32661 , +22851 , +6333 , +-25393 , +-2851 , +-13419 , +26517 , +-12117 , +1657 , +23801 , +-28149 , +-2169 , +28919 , +-885 , +17351 , +19293 , +-1257 , +-19967 , +6811 , +32647 , +-28669 , +-21285 , +-8933 , +24127 , +26911 , +-16859 , +-16975 , +-883 , +24675 , +13475 , +571 , +-17213 , +821 , +-27753 , +-6117 , +-10373 , +32189 , +7145 , +7383 , +-23807 , +-2367 , +-24593 , +-23763 , +20827 , +29695 , +-26215 , +31913 , +23735 , +-8455 , +-1231 , +-4157 , +23141 , +16991 , +-19829 , +-15761 , +27725 , +-10283 , +22213 , +16705 , +2289 , +-419 , +-1927 , +27381 , +20949 , +-20197 , +-29571 , +6293 , +-20349 , +-26945 , +-5875 , +31243 , +-3581 , +16723 , +-12909 , +-16587 , +-26423 , +-18795 , +-4909 , +17799 , +-25287 , +-10033 , +29097 , +8733 , +21655 , +-14285 , +-2495 , +24653 , +-18817 , +-11091 , +26059 , +-13105 , +-18203 , +6203 , +-16203 , +-23227 , +-1405 , +20941 , +15205 , +1115 , +29659 , +6291 , +-20621 , +25183 , +26273 , +-37 , +-10409 , +597 , +17345 , +-15511 , +19627 , +-23661 , +-16429 , +5193 , +-16161 , +20441 , +-12787 , +7731 , +26737 , +-25115 , +-17979 , +23891 , +4263 , +16525 , +5723 , +-9039 , +-10301 , +14937 , +-16957 , +29947 , +-63 , +-29283 , +-27281 , +9193 , +-11383 , +-16123 , +20937 , +5131 , +5801 , +4285 , +-4045 , +27947 , +-2163 , +-23555 , +8053 , +-31463 , +-963 , +-24791 , +20155 , +-30453 , +-7799 , +27237 , +-25843 , +14203 , +-6967 , +1193 , +21315 , +-15763 , +28695 , +-17565 , +19075 , +29269 , +-24321 , +7817 , +-20175 , +8561 , +-24129 , +-30421 , +-21395 , +10133 , +19705 , +5787 , +25613 , +-12661 , +5103 , +23539 , +-16627 , +-6421 , +-24777 , +-16835 , +-31091 , +-27281 , +8697 , +-17155 , +10057 , +-3887 , +-10333 , +2389 , +-13939 , +-30691 , +-23521 , +-15981 , +-2127 , +27021 , +20113 , +-22193 , +-29937 , +-15909 , +20103 , +-18941 , +6013 , +-21465 , +-23623 , +-14305 , +-29375 , +19001 , +-20421 , +-5977 , +18829 , +-17039 , +-29381 , +-7357 , +19829 , +6157 , +-11725 , +-27423 , +-11415 , +-8439 , +18085 , +-14657 , +-1239 , +13429 , +30285 , +-4585 , +-15297 , +16975 , +-24603 , +-22495 , +3837 , +-551 , +-2481 , +19131 , +-9239 , +-9361 , +-21419 , +24957 , +-32321 , +-29977 , +-15643 , +28487 , +4581 , +21597 , +4539 , +-13203 , +-23709 , +11669 , +-32091 , +-1733 , +-17315 , +8145 , +-2245 , +15641 , +-28155 , +5667 , +-12017 , +-5599 , +22301 , +-21425 , +-27541 , +7471 , +20713 , +5655 , +-25209 , +21125 , +-5471 , +-18655 , +24643 , +-22817 , +32631 , +-31935 , +10843 , +7429 , +4869 , +-16549 , +-8157 , +-16405 , +-20409 , +15031 , +-21567 , +-1727 , +-22765 , +-26409 , +5849 , +-2925 , +24595 , +-15401 , +-31019 , +26335 , +-197 , +7993 , +-27757 , +-27993 , +-29503 , +-27831 , +12447 , +-8047 , +-9069 , +2283 , +8429 , +-7045 , +-5031 , +28153 , +-21235 , +10001 , +-4131 , +-9697 , +5095 , +-29717 , +-15343 , +-5085 , +-21005 , +-21475 , +127 , +-2097 , +15085 , +-677 , +24389 , +7233 , +21009 , +7553 , +-19575 , +-9535 , +27855 , +6843 , +9847 , +17947 , +-31735 , +4109 , +-3405 , +25211 , +-18489 , +-4485 , +22099 , +-12863 , +-1683 , +-13671 , +-3235 , +18517 , +12407 , +-31075 , +22191 , +13961 , +-11857 , +12549 , +-8819 , +-19865 , +24807 , +-4189 , +-20091 , +17937 , +-10961 , +-12485 , +4853 , +-6509 , +22413 , +20377 , +-22021 , +18241 , +21555 , +1067 , +5613 , +7557 , +22079 , +8469 , +29529 , +27975 , +-23063 , +19661 , +4211 , +30129 , +8511 , +-29133 , +2069 , +22169 , +18275 , +-20699 , +-1233 , +1615 , +-4551 , +-5223 , +-24375 , +-20489 , +-25947 , +17721 , +25715 , +4707 , +-3267 , +21363 , +-13509 , +-2201 , +17807 , +-6119 , +-10445 , +23479 , +-27195 , +24693 , +8535 , +24377 , +12529 , +-1313 , +-7663 , +-27169 , +14771 , +2269 , +-24529 , +-12029 , +10113 , +21933 , +-16811 , +-1737 , +-20399 , +-26257 , +-24833 , +4259 , +5341 , +20651 , +-26897 , +-2593 , +18257 , +-12169 , +26155 , +-191 , +-7029 , +-4343 , +28533 , +1729 , +30667 , +6347 , +26175 , +-437 , +247 , +10751 , +-21721 , +-23405 , +13635 , +-6967 , +3823 , +29303 , +29303 , +23503 , +13295 , +22735 , +-9055 , +10579 , +17941 , +26309 , +-25013 , +-13629 , +16729 , +-3915 , +-15561 , +-1833 , +32439 , +20349 , +-23145 , +21545 , +-16479 , +-12205 , +26047 , +15947 , +28673 , +-4821 , +25703 , +14171 , +22181 , +25979 , +14171 , +-26583 , +27715 , +20391 , +4277 , +187 , +4331 , +-17721 , +4245 , +21367 , +22525 , +-1777 , +31069 , +-27473 , +-23899 , +10905 , +15967 , +-31037 , +16593 , +8395 , +-6877 , +23211 , +20651 , +12831 , +12563 , +19743 , +-27509 , +5767 , +-28233 , +-30683 , +30585 , +25671 , +-13457 , +8491 , +-2017 , +-15041 , +-11603 , +-29793 , +-19909 , +31951 , +20897 , +22537 , +-16729 , +22061 , +-12157 , +-26717 , +-24127 , +-27847 , +-1989 , +-17303 , +105 , +-3111 , +-6239 , +19903 , +21375 , +28113 , +4915 , +18811 , +20943 , +-21229 , +-22703 , +-30323 , +18583 , +-2905 , +-6929 , +1537 , +6767 , +30705 , +28877 , +19373 , +7377 , +-15209 , +3381 , +-197 , +-29693 , +21713 , +-18897 , +-15159 , +-12901 , +-7611 , +-26567 , +25593 , +14703 , +-28325 , +-9857 , +-32621 , +-24305 , +-29413 , +-21101 , +-16497 , +19903 , +11133 , +-21591 , +-20287 , +-21269 , +12875 , +-8377 , +21721 , +25381 , +21615 , +-29819 , +-26605 , +-615 , +32721 , +6333 , +-26307 , +-1535 , +5037 , +9423 , +5461 , +23845 , +-26771 , +11721 , +-12377 , +-28719 , +2559 , +-12499 , +20055 , +-17845 , +25005 , +2467 , +-15477 , +22087 , +21621 , +-29395 , +31473 , +12135 , +227 , +32235 , +-23579 , +-30159 , +-28827 , +-21691 , +-12285 , +-22141 , +25641 , +-20051 , +-451 , +27279 , +-1683 , +-301 , +-30089 , +12111 , +-1439 , +12379 , +-9827 , +-12413 , +-18827 , +-15075 , +6717 , +-14303 , +-31431 , +-26417 , +-3683 , +24919 , +12971 , +8783 , +27983 , +763 , +3103 , +-5047 , +4437 , +28547 , +-23161 , +16511 , +23213 , +7555 , +-4271 , +32117 , +-29075 , +26527 , +-19259 , +3757 , +11615 , +-13559 , +6867 , +32609 , +-7151 , +-5007 , +14191 , +-24643 , +20341 , +-25723 , +22891 , +13451 , +28149 , +-29469 , +6353 , +10619 , +5387 , +663 , +-14417 , +-16941 , +17239 , +6923 , +23427 , +-23647 , +-22721 , +-379 , +26363 , +-30335 , +12795 , +-23775 , +15459 , +1739 , +3897 , +24385 , +-12177 , +25163 , +-9937 , +653 , +30105 , +11133 , +24877 , +-21149 , +2039 , +7749 , +-6971 , +7895 , +-24173 , +18727 , +1875 , +-20183 , +28485 , +-4617 , +26653 , +-17225 , +-16889 , +5405 , +11497 , +-26245 , +-10029 , +19269 , +22809 , +-2299 , +-12553 , +-32355 , +18747 , +-15637 , +-17689 , +-30587 , +11047 , +21959 , +-24155 , +7373 , +-13673 , +7853 , +-32119 , +-145 , +-30147 , +-31449 , +-20573 , +4029 , +-7847 , +14755 , +1677 , +-8155 , +13781 , +-21383 , +8647 , +-17057 , +27357 , +-7339 , +6797 , +-24529 , +-1035 , +25915 , +-3281 , +405 , +-879 , +29939 , +16875 , +2435 , +-11221 , +21005 , +13379 , +4127 , +3811 , +-18349 , +-32043 , +-5769 , +6795 , +21951 , +28081 , +-3151 , +18507 , +28405 , +22841 , +24525 , +-5455 , +27201 , +9073 , +-21285 , +-6069 , +30979 , +-13865 , +-12879 , +-25919 , +6065 , +30655 , +-3809 , +21101 , +-25525 , +-27347 , +25779 , +22123 , +-29869 , +-4571 , +-30237 , +-18113 , +-5307 , +-30071 , +21965 , +-9759 , +20113 , +20079 , +21361 , +-5797 , +-13297 , +-1285 , +-24479 , +19679 , +-25089 , +-22603 , +-9215 , +13409 , +-24715 , +19551 , +-32455 , +15789 , +24665 , +29525 , +-23887 , +31741 , +2019 , +-21415 , +-32379 , +-17387 , +-17019 , +-10249 , +-2427 , +23771 , +-12175 , +-7341 , +9697 , +-27539 , +21899 , +3209 , +30061 , +31159 , +29665 , +18303 , +15695 , +-21871 , +6051 , +-9405 , +11069 , +-6575 , +17305 , +-12327 , +-12233 , +29927 , +-18141 , +17569 , +20661 , +-19855 , +11945 , +18211 , +-20629 , +-26789 , +-13163 , +17005 , +-21895 , +-27415 , +10443 , +-24857 , +-23771 , +-24991 , +30881 , +-21837 , +-30697 , +-18799 , +12635 , +25209 , +14855 , +-9737 , +-12517 , +13003 , +25347 , +-25269 , +-1439 , +18931 , +14363 , +22689 , +-15361 , +-28077 , +7583 , +14077 , +12177 , +-4807 , +-23085 , +619 , +-15245 , +-14797 , +-7635 , +1177 , +23871 , +-26893 , +32519 , +-11285 , +-4673 , +29593 , +-24099 , +25881 , +30571 , +14231 , +507 , +14655 , +-7079 , +27389 , +13251 , +125 , +189 , +30813 , +-25001 , +-30455 , +19165 , +19227 , +5085 , +21197 , +-11897 , +-4535 , +-31699 , +-24713 , +-9971 , +17405 , +-15855 , +22297 , +32447 , +27943 , +-11527 , +-26307 , +4823 , +-1553 , +-16081 , +21117 , +24835 , +31367 , +26777 , +-20839 , +-24755 , +-30583 , +13801 , +-16617 , +15261 , +-7993 , +20569 , +11857 , +16301 , +-23127 , +9695 , +22289 , +-31875 , +25095 , +-11797 , +-26451 , +26199 , +-7047 , +22167 , +16283 , +17977 , +-29901 , +8295 , +-9593 , +28121 , +6243 , +-13185 , +21487 , +-20205 , +-22787 , +-22191 , +-22471 , +28647 , +-10209 , +-5655 , +-28597 , +14321 , +-12063 , +915 , +-1881 , +-17315 , +8367 , +11799 , +-25349 , +23651 , +10273 , +32379 , +-24513 , +-4035 , +6229 , +-27603 , +31053 , +5281 , +8903 , +20679 , +3063 , +-21323 , +-3677 , +-28103 , +18077 , +-11637 , +167 , +26517 , +7241 , +-4585 , +-4495 , +-18383 , +13129 , +10919 , +24155 , +-10895 , +8253 , +735 , +-32039 , +-4365 , +-31301 , +6953 , +-6073 , +-7859 , +-4003 , +8881 , +-26555 , +22341 , +-14495 , +-3357 , +11667 , +-19069 , +10687 , +-23205 , +-3997 , +-14125 , +4025 , +-10151 , +-27851 , +-20781 , +-30465 , +-9781 , +-22485 , +-3789 , +28479 , +-3917 , +26341 , +19303 , +25921 , +32035 , +-9511 , +4837 , +31359 , +9917 , +4649 , +-17965 , +19253 , +-11869 , +25847 , +25675 , +-2809 , +-28173 , +27975 , +2063 , +-18419 , +21945 , +-14511 , +3767 , +-25487 , +32113 , +12887 , +-3461 , +-2937 , +6903 , +10751 , +-12963 , +4959 , +3841 , +-28625 , +21221 , +4069 , +-17127 , +32609 , +11353 , +-5001 , +-29165 , +-8841 , +12155 , +-1287 , +-1789 , +-14565 , +26547 , +-10899 , +19133 , +27541 , +27097 , +-15597 , +-7231 , +28957 , +-5543 , +-7689 , +9407 , +31165 , +3583 , +-4847 , +-15993 , +-8033 , +27935 , +-2345 , +-19837 , +18411 , +16727 , +-4007 , +31919 , +3869 , +-19005 , +21719 , +2071 , +18913 , +-11851 , +-11817 , +-17215 , +20321 , +-2579 , +17349 , +7729 , +31273 , +25681 , +-8449 , +-25245 , +12407 , +-13785 , +-8837 , +-9931 , +-13033 , +17613 , +-30513 , +1389 , +-32585 , +-10005 , +-1831 , +-20439 , +-15419 , +-11215 , +24267 , +-25127 , +28865 , +4499 , +13513 , +-3141 , +7959 , +-26637 , +10753 , +26827 , +-10631 , +-29851 , +9021 , +-19133 , +-19787 , +-5911 , +10243 , +-1905 , +-28657 , +1171 , +-27605 , +19907 , +22549 , +16981 , +26097 , +18073 , +1787 , +301 , +149 , +-31519 , +369 , +12515 , +15213 , +10883 , +-11527 , +-30155 , +5507 , +22509 , +-4919 , +-7775 , +-6747 , +28947 , +32019 , +-29553 , +24325 , +24801 , +-2325 , +20749 , +16975 , +-27853 , +25237 , +-10231 , +4919 , +-8871 , +3687 , +6663 , +-21851 , +3321 , +-18407 , +-16807 , +-711 , +21917 , +-14693 , +-6951 , +-4499 , +21663 , +-21383 , +21021 , +-30671 , +-7263 , +2727 , +30261 , +28405 , +29065 , +-21537 , +17883 , +-5551 , +6649 , +-3977 , +24115 , +23057 , +13123 , +-15685 , +27391 , +28625 , +-29979 , +-21569 , +18261 , +1309 , +2177 , +8383 , +-12065 , +-6667 , +-4273 , +-24329 , +-6777 , +26621 , +30237 , +-17425 , +-31815 , +9731 , +-4669 , +-26525 , +-31463 , +-18401 , +11805 , +5007 , +-5195 , +-16307 , +-32387 , +4365 , +14789 , +9081 , +-14677 , +4909 , +-13345 , +-14551 , +345 , +-19511 , +-21075 , +-21625 , +4381 , +5537 , +-7891 , +-17925 , +-14621 , +-6607 , +-28581 , +8267 , +4333 , +2059 , +8571 , +-28629 , +30021 , +32169 , +-23103 , +15189 , +-27971 , +-21297 , +-25967 , +-7127 , +-8099 , +-28071 , +30007 , +-9543 , +25437 , +-355 , +-3811 , +15983 , +-27737 , +29239 , +-26495 , +23573 , +9919 , +-19603 , +32691 , +-32645 , +-1719 , +-19459 , +-21817 , +6025 , +-12547 , +-8325 , +5585 , +28633 , +8471 , +27179 , +-10341 , +-1337 , +-19619 , +-18351 , +22237 , +24855 , +10121 , +30223 , +2551 , +17409 , +18249 , +30653 , +-18137 , +719 , +15545 , +-1349 , +-17601 , +23797 , +29015 , +24275 , +9441 , +18595 , +19317 , +-4087 , +25145 , +-10777 , +-32193 , +-9997 , +13099 , +30267 , +16425 , +-10853 , +-32233 , +-32605 , +-13335 , +-16697 , +3339 , +19015 , +-4113 , +-31267 , +22903 , +-21633 , +-10145 , +-18119 , +-5523 , +18815 , +-24699 , +10497 , +12631 , +31833 , +16595 , +-15229 , +12585 , +10661 , +10835 , +18435 , +19489 , +27539 , +9379 , +-11487 , +13307 , +23683 , +-13973 , +-91 , +29863 , +-8421 , +16467 , +-28451 , +-28279 , +-17689 , +31361 , +21363 , +11557 , +-6811 , +-23411 , +17859 , +13153 , +20395 , +1785 , +-24387 , +32313 , +4207 , +3367 , +-9939 , +-4871 , +17071 , +-21801 , +12703 , +26095 , +28863 , +-10215 , +-2891 , +-17747 , +-7201 , +23499 , +-4099 , +-6471 , +-20387 , +-25461 , +18247 , +-24377 , +-10713 , +-20431 , +14465 , +-18831 , +19939 , +25031 , +-6131 , +10865 , +23171 , +26115 , +-12899 , +-29353 , +-2197 , +30271 , +-9855 , +-30527 , +-17677 , +-30227 , +-5493 , +5397 , +1433 , +-6511 , +-21407 , +20919 , +-10879 , +15933 , +30289 , +30655 , +5787 , +-27519 , +17073 , +-8395 , +-14533 , +8681 , +22199 , +-28981 , +-14041 , +-4615 , +-19771 , +19981 , +-18629 , +22421 , +-7345 , +-19937 , +-26761 , +17421 , +18991 , +7411 , +-15967 , +11399 , +30839 , +9985 , +-11693 , +-15877 , +-20271 , +27523 , +663 , +24493 , +10831 , +12069 , +-17403 , +1059 , +11215 , +-9915 , +-16051 , +2207 , +-26683 , +-18523 , +-15519 , +20245 , +153 , +1191 , +-17667 , +7839 , +-8825 , +-22527 , +-8505 , +26241 , +-2073 , +-22021 , +-29209 , +-24685 , +-22253 , +-11997 , +1819 , +1093 , +183 , +25221 , +17491 , +22285 , +27563 , +31839 , +-11575 , +-4253 , +-3249 , +869 , +-109 , +17729 , +-21157 , +-26003 , +12483 , +-19703 , +29757 , +-25429 , +-15617 , +-23023 , +32756 , +-28049 , +17291 , +-2677 , +-2213 , +6223 , +24311 , +-26619 , +4623 , +-20243 , +23587 , +28513 , +-7485 , +31019 , +31717 , +25419 , +25107 , +14043 , +5399 , +-32205 , +-11807 , +-17915 , +-15047 , +24765 , +4393 , +2195 , +-29315 , +28617 , +-1953 , +19599 , +13419 , +-32549 , +22083 , +-809 , +-15375 , +12569 , +-23241 , +14425 , +31743 , +29385 , +4379 , +-13363 , +4505 , +-4801 , +-6745 , +-9755 , +-28037 , +27483 , +-713 , +-25077 , +-15071 , +4221 , +18483 , +16791 , +23919 , +-29691 , +1247 , +15241 , +-8771 , +833 , +-16465 , +12989 , +31863 , +-5653 , +-19417 , +-9559 , +-6613 , +-32483 , +-22995 , +-15731 , +13361 , +13521 , +-13335 , +-28875 , +-4177 , +-28721 , +-8177 , +-26843 , +31045 , +-471 , +-2873 , +22877 , +-21225 , +5687 , +7929 , +-14711 , +7015 , +-24567 , +-28115 , +-11075 , +-21067 , +4963 , +17629 , +21929 , +4175 , +-15309 , +-19121 , +-30891 , +-18327 , +30089 , +-6417 , +22361 , +-8517 , +-29939 , +12325 , +-12143 , +18069 , +-28417 , +-3923 , +-21671 , +10615 , +21159 , +-14221 , +30785 , +7975 , +14159 , +26337 , +23885 , +23121 , +7609 , +-30011 , +-8801 , +4501 , +28191 , +19097 , +-23615 , +27939 , +-25949 , +15723 , +-14771 , +-12071 , +-14775 , +-25559 , +32559 , +-9521 , +-13715 , +-3199 , +-12971 , +-4487 , +21187 , +32307 , +-1807 , +-23493 , +18373 , +-16405 , +29225 , +-2685 , +16307 , +30875 , +591 , +32091 , +11781 , +-30637 , +-14431 , +-23157 , +2405 , +-9325 , +-3209 , +6181 , +-24533 , +-2005 , +-15617 , +19883 , +21325 , +17039 , +-21891 , +-28773 , +-4129 , +-27729 , +10991 , +18317 , +24327 , +14159 , +19039 , +-3385 , +25715 , +-5409 , +9859 , +-28071 , +9045 , +-2855 , +-26109 , +-4169 , +-24101 , +-4983 , +27697 , +-29241 , +805 , +19067 , +823 , +-24955 , +-20549 , +22847 , +4317 , +-10989 , +9353 , +-24881 , +12723 , +27729 , +-24489 , +22107 , +-2351 , +14847 , +26557 , +4783 , +21009 , +9799 , +-10337 , +8449 , +-9025 , +-8229 , +-475 , +-15289 , +-3881 , +9363 , +-3537 , +-7911 , +3263 , +30331 , +-24243 , +12801 , +31095 , +-27279 , +19521 , +-25513 , +-21675 , +-27333 , +27113 , +-17001 , +21825 , +-6111 , +10433 , +18745 , +-22935 , +13825 , +18133 , +20231 , +-21897 , +22507 , +30781 , +509 , +17485 , +20537 , +5139 , +6039 , +-17603 , +-26847 , +16365 , +22447 , +21181 , +-27689 , +20945 , +29911 , +-7007 , +-26085 , +-24401 , +-15067 , +-2601 , +17495 , +31583 , +-3173 , +15769 , +-32199 , +32271 , +16885 , +5927 , +13249 , +-449 , +29445 , +-10749 , +-22299 , +-15047 , +-2683 , +29855 , +-8799 , +-12017 , +26489 , +-27229 , +-13681 , +21511 , +2559 , +20375 , +-24055 , +-21859 , +15785 , +-17623 , +20913 , +32760 , +-24747 , +-17453 , +8343 , +-10021 , +-8823 , +-1239 , +-15925 , +15665 , +-8637 , +-29059 , +-19599 , +-18455 , +19801 , +16161 , +16997 , +-6779 , +11083 , +-4829 , +2627 , +-14073 , +29855 , +1145 , +18959 , +-24725 , +31159 , +31939 , +-6845 , +27043 , +-215 , +23421 , +26981 , +25859 , +-16741 , +12475 , +-4053 , +10829 , +24593 , +-31135 , +13829 , +-21739 , +-31791 , +-17961 , +-17087 , +-14907 , +-2893 , +14407 , +21913 , +-22511 , +-25861 , +-27317 , +-8111 , +-18451 , +18357 , +29745 , +-22319 , +15117 , +-3961 , +-17493 , +10675 , +29905 , +29705 , +3085 , +-27035 , +29385 , +32419 , +-4099 , +321 , +16293 , +-22557 , +-16461 , +30233 , +-19281 , +24653 , +-20821 , +-7841 , +-24125 , +-14397 , +-1057 , +7091 , +-31797 , +1097 , +-17277 , +-3589 , +-32335 , +12655 , +14647 , +-32253 , +-6183 , +-32740 , +21955 , +-15477 , +-9701 , +-24843 , +-1205 , +-27165 , +29751 , +801 , +-757 , +10761 , +4305 , +10671 , +28557 , +8501 , +-4373 , +26987 , +-5533 , +14333 , +-4653 , +27961 , +-21411 , +-10783 , +-26713 , +-4383 , +6719 , +22897 , +12867 , +-13703 , +-28671 , +30935 , +3777 , +557 , +-903 , +-28935 , +-12435 , +-13663 , +16293 , +11535 , +-9157 , +14273 , +-15535 , +-14155 , +-16955 , +-24027 , +18015 , +-8565 , +-26949 , +23769 , +21107 , +24905 , +29669 , +-11323 , +21551 , +-12971 , +-21871 , +-21897 , +-12817 , +-18209 , +-621 , +-3193 , +-25351 , +14459 , +-16203 , +6245 , +-14019 , +-4049 , +-19783 , +-30279 , +-10357 , +10519 , +-14905 , +-12233 , +5699 , +-15499 , +-29075 , +5621 , +-9061 , +23883 , +-28401 , +-16313 , +13385 , +-31371 , +9703 , +12823 , +-6715 , +21309 , +11131 , +20153 , +24319 , +14971 , +16271 , +-10937 , +27795 , +29729 , +-18779 , +11381 , +15745 , +-11427 , +2543 , +-18703 , +-22161 , +24365 , +-3125 , +18481 , +12625 , +-30601 , +-3397 , +-11825 , +-19793 , +21667 , +27351 , +-7835 , +17749 , +21679 , +7629 , +1759 , +15249 , +-16181 , +12629 , +-17577 , +-17181 , +-28559 , +31787 , +-8089 , +-3267 , +-6409 , +20865 , +28685 , +17075 , +-21327 , +-32001 , +29943 , +-31811 , +-21377 , +-11977 , +-7329 , +-18457 , +3565 , +-32099 , +27237 , +12555 , +-31803 , +22785 , +-10781 , +-23799 , +1833 , +-25213 , +6349 , +6145 , +30511 , +31503 , +-26625 , +16139 , +-2831 , +24403 , +-12901 , +3431 , +21551 , +-26057 , +-8995 , +10821 , +30813 , +-3113 , +11899 , +7403 , +-2497 , +28923 , +-21135 , +-19079 , +-11771 , +-505 , +-17309 , +-22495 , +-20001 , +14463 , +31603 , +-11565 , +23825 , +3835 , +30355 , +9607 , +-8297 , +28567 , +21605 , +-23325 , +10797 , +-17159 , +-25199 , +32643 , +-30983 , +16825 , +13463 , +-21085 , +-17777 , +23147 , +-27091 , +4963 , +10651 , +-29179 , +31255 , +-25227 , +-9487 , +19685 , +-4997 , +20573 , +-20957 , +-29117 , +30657 , +-15837 , +-24935 , +1061 , +30429 , +-2417 , +27443 , +7649 , +10295 , +5599 , +31317 , +-28405 , +-26375 , +-2561 , +21123 , +-24329 , +231 , +-4543 , +32633 , +-9049 , +-22851 , +-4711 , +15301 , +-29881 , +-6911 , +19277 , +-18719 , +32553 , +26463 , +18997 , +20415 , +-30921 , +14463 , +-14741 , +-25615 , +14063 , +-18337 , +1421 , +-27849 , +15577 , +4901 , +8557 , +-18537 , +-131 , +20611 , +1355 , +-28163 , +-18207 , +-27777 , +30095 , +23369 , +-14211 , +-23845 , +6651 , +10733 , +29617 , +20959 , +623 , +31747 , +-13117 , +-7749 , +-25069 , +30181 , +-1967 , +-3235 , +-25319 , +-21177 , +-30387 , +8645 , +-19215 , +-10035 , +11121 , +-8991 , +-16641 , +15397 , +21563 , +-25377 , +10713 , +10393 , +12903 , +1553 , +13561 , +27185 , +-27683 , +5431 , +-4357 , +-1727 , +-1485 , +-5023 , +28235 , +-14201 , +-27229 , +22595 , +15467 , +1987 , +24191 , +-23027 , +27549 , +-19763 , +1323 , +-7741 , +20263 , +-15061 , +-3945 , +5399 , +19971 , +-5587 , +823 , +-24899 , +-14313 , +391 , +24183 , +14921 , +-31245 , +20575 , +-9035 , +-12159 , +-21755 , +-18703 , +31165 , +-22473 , +-23981 , +-15713 , +25017 , +4005 , +-597 , +-2933 , +-8529 , +5691 , +-16535 , +5297 , +-9093 , +28423 , +1699 , +-5763 , +15167 , +4985 , +-27159 , +11233 , +-22431 , +-16691 , +11381 , +4085 , +13827 , +-9765 , +10731 , +14855 , +26873 , +-4247 , +29839 , +30769 , +-2755 , +16657 , +6643 , +6267 , +-7949 , +-27505 , +-23997 , +13165 , +17875 , +-11877 , +-29205 , +-15579 , +26925 , +-30657 , +-2605 , +-8461 , +25173 , +-2121 , +-14815 , +-3215 , +1961 , +-21055 , +-29851 , +20245 , +23037 , +22131 , +19027 , +-9389 , +9877 , +-11105 , +23043 , +23083 , +6055 , +15009 , +-18271 , +73 , +-5309 , +-17483 , +-11611 , +-15465 , +2267 , +11737 , +13459 , +13911 , +11567 , +13343 , +7977 , +18111 , +25805 , +-22141 , +30237 , +-17653 , +3327 , +25669 , +341 , +-15849 , +4943 , +-5691 , +30873 , +28791 , +11131 , +10965 , +20949 , +-32235 , +13287 , +-8045 , +-13881 , +14395 , +-32615 , +-24123 , +7999 , +-21445 , +17591 , +18601 , +30931 , +28281 , +-11659 , +-16043 , +27923 , +-13807 , +-5741 , +-10103 , +-23221 , +-31519 , +-13231 , +8971 , +-27979 , +29737 , +21231 , +-27267 , +-20947 , +-16989 , +-19045 , +-6985 , +14963 , +7451 , +17647 , +18075 , +217 , +1663 , +-14107 , +-21649 , +129 , +-889 , +-16809 , +1977 , +-30697 , +-3141 , +10987 , +-14703 , +-19967 , +6679 , +16279 , +-899 , +-17635 , +-9439 , +-32367 , +29381 , +11253 , +30843 , +-20021 , +9039 , +19585 , +3845 , +10981 , +15609 , +-9651 , +24685 , +-4691 , +18533 , +31045 , +14663 , +5143 , +-31389 , +-10531 , +-13395 , +-7511 , +6329 , +-2093 , +-10677 , +12419 , +8835 , +-22427 , +-4093 , +24013 , +21771 , +-30977 , +-12293 , +-28497 , +9247 , +-24185 , +-5569 , +28881 , +9449 , +7425 , +14543 , +6471 , +-18873 , +-8235 , +-30403 , +30997 , +-30299 , +-18821 , +9923 , +-9699 , +9297 , +-5439 , +14555 , +-14689 , +-3753 , +-14985 , +-20901 , +1325 , +-1061 , +-3413 , +3331 , +-7391 , +-5657 , +16485 , +-605 , +-31333 , +20429 , +-20519 , +-4955 , +30963 , +-3077 , +20769 , +-26831 , +14003 , +6997 , +-7815 , +-9029 , +-9709 , +30215 , +-23571 , +-21215 , +-17687 , +-15127 , +27805 , +27459 , +10025 , +-12473 , +22129 , +-25575 , +-3367 , +-16055 , +6985 , +14921 , +5767 , +-30019 , +-31041 , +-31163 , +5189 , +22139 , +-1187 , +-21797 , +23329 , +-19915 , +-32175 , +3673 , +24859 , +32463 , +23977 , +-22507 , +-21607 , +16703 , +-27383 , +12947 , +32363 , +-5157 , +29923 , +-28139 , +26935 , +-18377 , +30769 , +18359 , +27509 , +10621 , +-27479 , +18691 , +-6421 , +-12479 , +24953 , +5137 , +6299 , +-7971 , +4223 , +22547 , +20555 , +18759 , +-19969 , +2679 , +-24983 , +15209 , +-17705 , +16507 , +12439 , +-6405 , +17727 , +-23225 , +5267 , +26071 , +1025 , +-7041 , +-26183 , +31191 , +24615 , +-7837 , +2293 , +13095 , +-18113 , +4707 , +-5313 , +5921 , +16391 , +-9927 , +-26991 , +-8287 , +25525 , +12155 , +14687 , +27361 , +18843 , +32701 , +7315 , +-3119 , +18287 , +801 , +21501 , +10987 , +-10239 , +31599 , +-27311 , +18319 , +615 , +-24143 , +28061 , +-22055 , +-21563 , +8527 , +-29371 , +9465 , +-13447 , +30617 , +25201 , +-30195 , +-1575 , +-28691 , +-17901 , +-29833 , +20841 , +29765 , +-24751 , +-28493 , +6805 , +-5541 , +12679 , +-27977 , +14823 , +21811 , +-22341 , +-26433 , +-10051 , +-19655 , +16533 , +-4689 , +16519 , +4319 , +16855 , +-23063 , +24697 , +18345 , +-7593 , +-29281 , +-2617 , +25043 , +13173 , +6069 , +-12709 , +31323 , +-10477 , +25871 , +7695 , +29089 , +-19699 , +-915 , +24159 , +20095 , +23347 , +19145 , +-20311 , +-23583 , +27071 , +-31705 , +15075 , +-11561 , +32333 , +-791 , +30415 , +-32461 , +6995 , +-27719 , +-5197 , +7331 , +6683 , +17357 , +19099 , +-15805 , +-4809 , +30665 , +25857 , +25267 , +27009 , +13591 , +-2539 , +31421 , +19845 , +-18495 , +-18841 , +14427 , +16265 , +-26949 , +-19927 , +25693 , +31227 , +2259 , +23013 , +-6025 , +-8597 , +25071 , +17839 , +18915 , +-22781 , +24825 , +8933 , +-3987 , +28287 , +26159 , +-15261 , +-28137 , +-14679 , +10745 , +-12999 , +-25815 , +5451 , +3139 , +-4629 , +-5429 , +-4183 , +-27557 , +11293 , +-17377 , +-21383 , +14651 , +11477 , +5077 , +25695 , +2675 , +-1743 , +-30133 , +6367 , +20845 , +13719 , +-13797 , +14805 , +-15525 , +17277 , +-25803 , +16759 , +23417 , +17807 , +-11647 , +-24901 , +30197 , +32373 , +-537 , +-22941 , +17219 , +515 , +9465 , +-15767 , +11245 , +12531 , +30199 , +-26637 , +15611 , +-2273 , +14203 , +23515 , +13495 , +17463 , +-10621 , +3481 , +18455 , +-18695 , +26891 , +-12099 , +14475 , +-3349 , +32045 , +7407 , +-11689 , +-26479 , +-29521 , +-931 , +27501 , +22563 , +-4829 , +4283 , +31427 , +5835 , +-27529 , +-26957 , +-8151 , +-25001 , +-30183 , +8167 , +-2905 , +-12429 , +23679 , +15199 , +-1201 , +-12697 , +29517 , +-15225 , +2715 , +8771 , +-27163 , +4263 , +1595 , +16033 , +32387 , +-19751 , +-16003 , +28631 , +-11821 , +3711 , +-7663 , +-24141 , +21257 , +28735 , +-25739 , +-1869 , +-21383 , +-6791 , +-9541 , +-19015 , +-23375 , +-30141 , +-1295 , +23623 , +6159 , +-31271 , +-26133 , +-27853 , +-28965 , +28061 , +-23129 , +-18457 , +-14375 , +18055 , +14877 , +-25587 , +3945 , +-8923 , +26521 , +26065 , +-17637 , +-21489 , +31123 , +2709 , +-24119 , +2271 , +-10743 , +23595 , +-6101 , +-12373 , +3415 , +8329 , +-1551 , +17657 , +12937 , +11269 , +1885 , +26173 , +5181 , +-2551 , +-8357 , +24775 , +28143 , +-24495 , +32277 , +26441 , +-22049 , +-5985 , +10253 , +-25151 , +19289 , +-785 , +27065 , +21503 , +-26209 , +-21957 , +-11371 , +18063 , +-23761 , +-8795 , +-13635 , +7737 , +12713 , +-4039 , +17927 , +-6661 , +-14817 , +-19167 , +-12393 , +-20617 , +13809 , +-15781 , +-23809 , +7671 , +33 , +-5131 , +16329 , +4061 , +-3281 , +27079 , +18593 , +7841 , +15217 , +-24669 , +1757 , +11583 , +29161 , +19 , +27293 , +-17093 , +-15463 , +401 , +-8351 , +16915 , +-13979 , +-25033 , +-13019 , +11059 , +10341 , +22025 , +7663 , +-9095 , +-27975 , +11157 , +-24587 , +19741 , +16621 , +-27837 , +-25559 , +-31433 , +31681 , +-13065 , +31061 , +-20047 , +20111 , +-24483 , +-15435 , +1727 , +-1507 , +-3185 , +28943 , +10455 , +16371 , +13403 , +-18105 , +21543 , +7737 , +3061 , +23417 , +-1385 , +5127 , +21805 , +-22635 , +4145 , +-31161 , +-13013 , +9327 , +-16857 , +23811 , +30375 , +10849 , +-19389 , +28995 , +10141 , +19031 , +-12061 , +-7325 , +14729 , +-9869 , +22383 , +-3601 , +-11237 , +31005 , +27983 , +26865 , +-13705 , +-3171 , +5481 , +16853 , +-32031 , +17717 , +25109 , +-29767 , +-7937 , +10679 , +5523 , +13385 , +-21875 , +1693 , +26889 , +-14061 , +24213 , +-30303 , +12789 , +-13979 , +-2261 , +-11303 , +7719 , +-24419 , +-29285 , +-30395 , +15933 , +-7925 , +22829 , +-25355 , +-26987 , +-10433 , +83 , +12691 , +-4411 , +3561 , +-19349 , +26247 , +-26725 , +-9689 , +4077 , +27013 , +24459 , +-30611 , +12073 , +-23379 , +28079 , +16845 , +-1155 , +24859 , +15161 , +16855 , +8463 , +-18935 , +25453 , +29933 , +-22783 , +7261 , +-32229 , +5925 , +-24017 , +32457 , +-10089 , +27537 , +-1441 , +7773 , +-3795 , +9253 , +-17917 , +9121 , +-1765 , +-28155 , +-8089 , +13361 , +2315 , +13927 , +11887 , +-6961 , +5131 , +-13343 , +-6709 , +24573 , +-19199 , +24649 , +-3399 , +6425 , +-27997 , +-26875 , +30763 , +-7191 , +-28167 , +-21525 , +13973 , +18631 , +-28855 , +20117 , +-15091 , +27941 , +-10863 , +-4551 , +5403 , +26803 , +3205 , +-29183 , +14559 , +24299 , +-11005 , +-17947 , +-7217 , +13623 , +-13299 , +-19457 , +-25101 , +15739 , +11323 , +29291 , +8601 , +-21193 , +-14915 , +-31343 , +-9333 , +14619 , +-31545 , +32523 , +1485 , +-21215 , +16023 , +-3847 , +21707 , +-9951 , +-801 , +-25131 , +-20703 , +-22037 , +32713 , +-3893 , +-6207 , +-14623 , +11875 , +22167 , +-3399 , +-29681 , +11685 , +-28967 , +-29597 , +-18241 , +-10789 , +-29203 , +-13535 , +-21867 , +16039 , +1859 , +-27761 , +32035 , +6517 , +14393 , +26439 , +-6649 , +-28045 , +2929 , +-31221 , +9597 , +28683 , +11433 , +-9851 , +-7301 , +10453 , +9489 , +-23677 , +20805 , +10267 , +6187 , +26271 , +26509 , +-1855 , +14619 , +397 , +-26371 , +-28979 , +-28545 , +29887 , +-11935 , +26451 , +10955 , +19113 , +6447 , +-18703 , +18211 , +6771 , +-19033 , +24269 , +-24917 , +7481 , +7529 , +-8191 , +23653 , +19897 , +-26223 , +1437 , +-8825 , +2703 , +-5307 , +32025 , +-11691 , +-19727 , +-12837 , +5461 , +-10377 , +13791 , +-21147 , +-9213 , +8145 , +3043 , +27085 , +-11855 , +18139 , +-27835 , +32369 , +27695 , +-7303 , +18115 , +26163 , +-24683 , +-3241 , +-14647 , +-27625 , +-23117 , +-18759 , +11563 , +-10145 , +15373 , +5339 , +-23719 , +-30189 , +-28593 , +8387 , +-19685 , +19759 , +-27827 , +-10593 , +18889 , +-13017 , +-5523 , +-22125 , +-6657 , +17417 , +14255 , +-1505 , +-6185 , +9751 , +-4069 , +3307 , +31655 , +-13863 , +30905 , +-26075 , +5931 , +25783 , +-15855 , +-29353 , +331 , +13331 , +6679 , +3517 , +-9137 , +10975 , +27821 , +26407 , +-21871 , +-1099 , +-21861 , +-5313 , +17853 , +-10385 , +-28933 , +25463 , +-16255 , +-18365 , +31553 , +11083 , +-21809 , +-28333 , +-24153 , +-29911 , +-20341 , +15051 , +13869 , +27589 , +-30005 , +29303 , +-8695 , +-1557 , +-17525 , +-14113 , +5547 , +21213 , +3043 , +-11561 , +-15069 , +-11987 , +17601 , +30623 , +-17619 , +4619 , +6695 , +-19597 , +18075 , +19241 , +-16167 , +-22867 , +-22957 , +2315 , +9881 , +18771 , +-30781 , +-4635 , +17635 , +-25801 , +19421 , +-30489 , +-31203 , +-22391 , +19087 , +-8665 , +-19111 , +15089 , +-13129 , +-18709 , +28801 , +-28883 , +-2911 , +21127 , +-27363 , +-6373 , +19703 , +-28751 , +-24709 , +20575 , +13889 , +9821 , +29817 , +30581 , +-5417 , +2579 , +-29271 , +-8375 , +20829 , +-29493 , +29 , +21839 , +21947 , +23099 , +21905 , +-1509 , +143 , +-7235 , +-20443 , +-18821 , +1327 , +21657 , +12447 , +29967 , +-491 , +-22811 , +5907 , +-1959 , +4069 , +-3873 , +-27095 , +-23197 , +10969 , +-32065 , +-12081 , +6861 , +-23875 , +-4847 , +-1427 , +-5021 , +21865 , +-30835 , +4523 , +23361 , +6071 , +-28557 , +11667 , +25183 , +-24325 , +31833 , +-10911 , +-4179 , +-21249 , +-29037 , +23207 , +-24145 , +-29581 , +20985 , +-20973 , +-7795 , +-9237 , +2633 , +-22881 , +-20045 , +-26283 , +-18941 , +13131 , +2275 , +20467 , +-18251 , +28503 , +4563 , +-27949 , +-14885 , +4345 , +10047 , +32191 , +9275 , +10903 , +-7037 , +29891 , +-7761 , +-18821 , +8885 , +-9703 , +3979 , +-6899 , +14907 , +-3417 , +-24721 , +-23155 , +24801 , +-20235 , +-1891 , +24909 , +31865 , +-24923 , +-8747 , +24925 , +16873 , +-25491 , +-17489 , +-10539 , +-1847 , +-20339 , +-2201 , +-645 , +-17543 , +-25657 , +22085 , +20747 , +-29767 , +27863 , +5485 , +19683 , +5061 , +-13715 , +-13773 , +-20929 , +27621 , +11171 , +-23815 , +-20237 , +-17269 , +-18701 , +8331 , +16035 , +5355 , +-73 , +-8215 , +-30601 , +19983 , +23063 , +-29523 , +855 , +21107 , +-633 , +-27683 , +16033 , +-24035 , +-21061 , +-20669 , +-29343 , +27441 , +8741 , +-7869 , +-1527 , +3851 , +-7191 , +-1737 , +31917 , +27611 , +-9643 , +14409 , +-5197 , +-15689 , +15833 , +11971 , +-24813 , +-28109 , +10623 , +27117 , +15879 , +15747 , +-32029 , +2659 , +-20657 , +-10237 , +28847 , +-9487 , +-23591 , +-4771 , +6029 , +-31 , +-19449 , +-25063 , +-10847 , +-10529 , +-30881 , +-5959 , +-19327 , +8011 , +-311 , +30543 , +18865 , +781 , +-9923 , +-13931 , +-17005 , +6133 , +-13557 , +4999 , +12521 , +-3695 , +32639 , +-22411 , +14529 , +23423 , +32041 , +19111 , +-22279 , +-11183 , +25747 , +14183 , +25901 , +24787 , +-32403 , +18339 , +28727 , +20469 , +9811 , +-769 , +-3551 , +1819 , +-13567 , +-11407 , +27811 , +28403 , +25859 , +-20649 , +-10731 , +6353 , +-3333 , +-16365 , +-11545 , +-19323 , +-19893 , +-20711 , +-14943 , +-4429 , +-2215 , +29585 , +-4783 , +20395 , +8255 , +-23955 , +19081 , +12997 , +-26109 , +-27907 , +-32039 , +28211 , +28759 , +12299 , +31419 , +-15525 , +24517 , +-12945 , +-8675 , +-20561 , +-7565 , +-9683 , +20299 , +-18937 , +12117 , +-14585 , +29801 , +-18311 , +-23583 , +-1639 , +-25743 , +31403 , +-28593 , +9199 , +11433 , +-6989 , +-8625 , +-10083 , +-23659 , +7787 , +-30149 , +-19623 , +18037 , +6985 , +26327 , +-4595 , +21567 , +-20807 , +9095 , +-17797 , +-7921 , +-16145 , +3325 , +14405 , +6439 , +-17337 , +-32635 , +24469 , +8799 , +-13539 , +-30293 , +-18389 , +21541 , +-487 , +-23943 , +13555 , +-527 , +-3305 , +3633 , +3113 , +29757 , +5235 , +-14717 , +-7195 , +-25601 , +2279 , +29511 , +11063 , +-21347 , +27619 , +25779 , +-2109 , +24681 , +26209 , +2067 , +16337 , +19351 , +16451 , +-12543 , +-14099 , +-28233 , +-32223 , +285 , +-23813 , +-20055 , +-16467 , +28743 , +-30771 , +-24553 , +-23929 , +-30891 , +-2239 , +-6029 , +19853 , +-21685 , +26579 , +3171 , +-20291 , +26391 , +25529 , +-9787 , +-6771 , +22975 , +-5511 , +-4325 , +11193 , +24355 , +-4353 , +9871 , +-24921 , +-5325 , +19005 , +8035 , +15157 , +4005 , +-1479 , +-25105 , +19993 , +9257 , +1451 , +-1521 , +-7501 , +-30419 , +-9197 , +21543 , +19049 , +32005 , +-30125 , +-14187 , +21629 , +31667 , +-25663 , +22949 , +20069 , +8469 , +-53 , +-14317 , +25765 , +1437 , +-13311 , +4603 , +31781 , +-29297 , +12983 , +-12205 , +7177 , +8883 , +-31209 , +10983 , +-32760 , +-12143 , +-24641 , +-25915 , +27467 , +-17627 , +-31535 , +13129 , +-11339 , +26655 , +-24941 , +-22143 , +-557 , +21135 , +24449 , +-11729 , +8475 , +-16087 , +-21269 , +-12733 , +11477 , +22259 , +-6905 , +-25139 , +-14993 , +22147 , +-9847 , +20855 , +4687 , +4025 , +-26939 , +-28033 , +29745 , +28653 , +20279 , +-18133 , +-17409 , +11443 , +17321 , +10695 , +-1497 , +-32503 , +-61 , +12311 , +32369 , +-2789 , +-15577 , +4435 , +8287 , +10345 , +28425 , +-29541 , +26617 , +5779 , +-12225 , +-32267 , +-20687 , +-12671 , +-25115 , +-2113 , +-11341 , +5157 , +1137 , +13995 , +-28355 , +-6995 , +5445 , +13361 , +7295 , +21825 , +-3379 , +917 , +5737 , +-15307 , +4373 , +-31413 , +28681 , +-11069 , +25317 , +3329 , +22241 , +11591 , +-13485 , +13835 , +-15933 , +28653 , +-21543 , +-24989 , +-18913 , +26103 , +-6405 , +-16357 , +-8729 , +-10905 , +12109 , +-24233 , +-31263 , +-1725 , +-1257 , +-27961 , +-25477 , +5187 , +-2965 , +-19297 , +-14035 , +5649 , +15801 , +31243 , +13383 , +-13573 , +25323 , +-7383 , +5969 , +-29137 , +20217 , +-23165 , +-21025 , +-2447 , +7687 , +-1273 , +-24857 , +30037 , +9209 , +20345 , +30365 , +24815 , +-121 , +-31627 , +18633 , +24605 , +4575 , +989 , +5027 , +-20185 , +12981 , +22743 , +-1245 , +17165 , +-1827 , +-30907 , +-2849 , +6451 , +28519 , +-9799 , +-929 , +-3689 , +-28883 , +24049 , +26623 , +-23151 , +21753 , +-14385 , +30263 , +15627 , +-13297 , +-3381 , +-21631 , +11311 , +-6831 , +-17931 , +6313 , +-19541 , +29387 , +24161 , +8617 , +-9377 , +8155 , +13357 , +-8965 , +-101 , +-16973 , +-12821 , +-23683 , +26839 , +-17269 , +24227 , +-5955 , +-6679 , +10527 , +-30135 , +-3117 , +-8005 , +1757 , +23725 , +-28477 , +-6773 , +24175 , +-24831 , +21063 , +5271 , +-10023 , +17349 , +31791 , +30301 , +16143 , +8517 , +11833 , +-21929 , +-18933 , +-19825 , +-6299 , +-6103 , +3947 , +5869 , +-1579 , +-13477 , +1669 , +2007 , +1815 , +-7783 , +-15875 , +-649 , +7437 , +29537 , +29157 , +14737 , +-29895 , +32579 , +25161 , +-3829 , +2205 , +24467 , +23121 , +19417 , +16907 , +4773 , +-24619 , +29561 , +26885 , +-25211 , +30581 , +26609 , +-9453 , +-32473 , +31027 , +-11461 , +31123 , +-17875 , +-28283 , +-27835 , +-13793 , +17173 , +1785 , +12909 , +30553 , +-28431 , +23617 , +1643 , +19017 , +675 , +26315 , +11737 , +13361 , +-17769 , +29161 , +9245 , +-32531 , +-9485 , +-14767 , +9197 , +-13889 , +-25517 , +28235 , +4159 , +-16207 , +14087 , +-29125 , +7107 , +27755 , +5823 , +10687 , +-6435 , +-4985 , +20685 , +-21181 , +19481 , +24171 , +-11045 , +5149 , +-27861 , +-1373 , +20509 , +807 , +16985 , +695 , +15121 , +-20529 , +18051 , +-26747 , +2483 , +-5197 , +-22127 , +4115 , +-2507 , +11453 , +-28821 , +-5901 , +24117 , +-5707 , +-20105 , +-7157 , +10877 , +9055 , +4237 , +28923 , +14643 , +29193 , +5487 , +-2577 , +17039 , +28591 , +-10305 , +4343 , +12319 , +-10611 , +-15491 , +27101 , +24179 , +11315 , +21755 , +11395 , +-16039 , +20777 , +9043 , +-15435 , +25241 , +-13063 , +-3739 , +-4987 , +13093 , +11985 , +-695 , +-17885 , +-22819 , +23189 , +17993 , +-24017 , +4789 , +6779 , +347 , +10649 , +17791 , +-13021 , +-3047 , +18933 , +21273 , +-30677 , +-4555 , +10067 , +2601 , +-30903 , +6517 , +11927 , +3155 , +16357 , +22565 , +13395 , +239 , +-3791 , +27165 , +-21477 , +-9657 , +2237 , +4133 , +-28573 , +-23223 , +13203 , +-6659 , +4817 , +-9277 , +29645 , +10959 , +-21225 , +-20199 , +4779 , +12329 , +-21939 , +20861 , +-14543 , +-22671 , +-16183 , +-29785 , +-5829 , +-31265 , +-11151 , +-8943 , +2327 , +-18697 , +31131 , +22697 , +-15467 , +21889 , +20579 , +24585 , +10923 , +-23813 , +-12165 , +-22731 , +-25975 , +30107 , +-25201 , +31439 , +21289 , +21691 , +-999 , +-16179 , +-20875 , +-1057 , +32431 , +-21575 , +19153 , +31777 , +-31761 , +-26531 , +575 , +-19411 , +-25407 , +3589 , +1517 , +22201 , +29505 , +22837 , +-2477 , +14211 , +18955 , +-18213 , +20425 , +5823 , +-21477 , +-27121 , +933 , +-23789 , +25885 , +-16827 , +-27197 , +-5617 , +23117 , +6157 , +-26957 , +-4309 , +23501 , +-13763 , +-11717 , +-24269 , +-31115 , +19897 , +2689 , +-6581 , +20025 , +24989 , +-26729 , +-2469 , +-14093 , +23043 , +-15461 , +-17389 , +20935 , +-16083 , +15177 , +29789 , +7411 , +-15545 , +27415 , +17491 , +-11223 , +23707 , +8395 , +-581 , +-11417 , +-15801 , +18835 , +-13827 , +7763 , +-647 , +9373 , +-3173 , +-23029 , +12587 , +-15823 , +-31189 , +-2171 , +-32181 , +10055 , +-819 , +-5535 , +6789 , +-4705 , +-18655 , +26693 , +15729 , +-18341 , +27847 , +-6989 , +-6065 , +21779 , +22349 , +-25245 , +-3013 , +-7823 , +19117 , +15125 , +13035 , +-12985 , +29763 , +-5389 , +32223 , +4393 , +-1979 , +-30623 , +12323 , +29057 , +9659 , +-4265 , +635 , +9773 , +30973 , +3899 , +-15831 , +-16753 , +9373 , +-10699 , +-9707 , +-26067 , +22765 , +-29427 , +9877 , +-12859 , +499 , +-17541 , +2969 , +-13085 , +13271 , +11527 , +17769 , +-20483 , +-529 , +11871 , +27615 , +28429 , +-9181 , +-25815 , +-24557 , +-5983 , +32495 , +-11167 , +23713 , +3447 , +8669 , +14129 , +-8097 , +2201 , +10359 , +11335 , +11145 , +-17423 , +14783 , +26541 , +1929 , +26973 , +-28111 , +28961 , +4387 , +-8111 , +-15319 , +3309 , +15667 , +2023 , +-24847 , +-25277 , +-12315 , +7547 , +29731 , +5135 , +15975 , +32703 , +29619 , +-29361 , +-3283 , +24151 , +22109 , +10739 , +27799 , +9711 , +3741 , +17195 , +-20929 , +213 , +-18387 , +-29115 , +31901 , +17421 , +32247 , +18693 , +23371 , +8429 , +-20845 , +1657 , +-14919 , +29493 , +-18631 , +13395 , +-26011 , +931 , +15673 , +-3899 , +12437 , +5901 , +3579 , +18645 , +4235 , +-24069 , +7533 , +30513 , +-14781 , +-1857 , +19201 , +15249 , +-14683 , +21513 , +9509 , +-7545 , +-8385 , +515 , +25401 , +5591 , +10365 , +-25625 , +19973 , +3415 , +-3481 , +6165 , +-12619 , +14397 , +-23603 , +4275 , +23633 , +-2307 , +1031 , +5817 , +32691 , +32161 , +-6353 , +27029 , +9723 , +30365 , +-19247 , +-5317 , +31123 , +32297 , +-16085 , +-22335 , +31131 , +3615 , +-3873 , +-12431 , +2019 , +-3513 , +-24787 , +26221 , +-23187 , +-8903 , +16049 , +-23367 , +-27303 , +13743 , +-21363 , +15323 , +-24995 , +-19357 , +-20943 , +28405 , +8909 , +-5535 , +-28281 , +20053 , +-14597 , +18403 , +26547 , +-4205 , +24131 , +-17499 , +-11709 , +-1495 , +22139 , +-32063 , +-9491 , +24711 , +23017 , +16645 , +-12853 , +-25167 , +24511 , +-1585 , +-29179 , +20303 , +-7407 , +349 , +23831 , +-31667 , +30797 , +32427 , +-29567 , +-26641 , +31031 , +-27191 , +4613 , +-3735 , +-167 , +-11595 , +30295 , +32758 , +-6911 , +-4943 , +5723 , +19313 , +1207 , +31257 , +11995 , +-3725 , +28471 , +-21309 , +-21819 , +26337 , +-12313 , +-20789 , +11219 , +-10743 , +-18481 , +-18443 , +17881 , +-3783 , +1809 , +29571 , +25705 , +-28199 , +11493 , +-12665 , +21271 , +-1023 , +30215 , +-14651 , +-8147 , +-24943 , +8635 , +20991 , +-28189 , +-22581 , +30013 , +-2597 , +-6633 , +18023 , +-31297 , +10285 , +5259 , +-4305 , +-3881 , +4057 , +-13427 , +32533 , +15235 , +-16857 , +-8381 , +-28211 , +3993 , +30873 , +25431 , +-6941 , +4035 , +11083 , +10029 , +8015 , +31221 , +-25665 , +3237 , +-10853 , +20579 , +29761 , +12619 , +8807 , +16641 , +-16459 , +25107 , +-21615 , +879 , +-4617 , +-11891 , +27593 , +25981 , +-1875 , +-30559 , +6309 , +-16869 , +-16221 , +-30265 , +32059 , +-301 , +15265 , +7867 , +-24261 , +7107 , +-30011 , +18617 , +5251 , +529 , +-28329 , +-13519 , +14141 , +-11031 , +9251 , +-14075 , +-10637 , +-22289 , +26967 , +27709 , +-2781 , +30267 , +-32563 , +-28611 , +6625 , +30925 , +3315 , +-6527 , +-1815 , +-18549 , +-19431 , +-29229 , +-11599 , +-5709 , +12873 , +-27643 , +24337 , +29397 , +5029 , +23079 , +-25397 , +-21169 , +-20679 , +21311 , +23981 , +15165 , +31321 , +5503 , +-6369 , +-27143 , +19569 , +13829 , +32589 , +-27633 , +-21661 , +-6391 , +16039 , +7603 , +-18337 , +-12135 , +-497 , +-14401 , +-10951 , +7127 , +-18079 , +-29403 , +-26047 , +10407 , +16025 , +24297 , +13467 , +-6677 , +-32423 , +-15717 , +-15079 , +17471 , +27413 , +14159 , +-10353 , +-17621 , +32671 , +-26353 , +-30031 , +22747 , +11837 , +15069 , +-32667 , +21601 , +10057 , +-4317 , +11935 , +-26019 , +-29113 , +-18775 , +-22349 , +19525 , +24699 , +19993 , +31033 , +-22001 , +-6147 , +20973 , +-23465 , +24181 , +-27811 , +12519 , +27301 , +-23133 , +2475 , +-23283 , +-7047 , +18037 , +-11491 , +-5343 , +3531 , +-10703 , +28195 , +28821 , +23175 , +16053 , +10489 , +12295 , +27489 , +-195 , +-26683 , +29753 , +-1225 , +8075 , +-211 , +14723 , +-25375 , +19887 , +-29837 , +-6701 , +24971 , +7731 , +-21499 , +-28893 , +-115 , +-6439 , +27547 , +-30613 , +-28219 , +11219 , +7375 , +27935 , +-30865 , +6005 , +13105 , +25383 , +-9097 , +-2953 , +-24347 , +-13483 , +12889 , +8869 , +-28493 , +6239 , +-7817 , +32281 , +-11095 , +1105 , +-25879 , +-20237 , +-7897 , +-9075 , +-19741 , +26517 , +-21375 , +7231 , +-21633 , +-8367 , +19221 , +3413 , +6179 , +-14417 , +-24607 , +-22537 , +29001 , +-4585 , +-1641 , +26755 , +-3867 , +-21481 , +-3009 , +21499 , +3893 , +-28663 , +30535 , +-7415 , +-18401 , +14433 , +10269 , +2929 , +-12031 , +-9905 , +10569 , +8199 , +10001 , +25867 , +32259 , +-16599 , +24111 , +-12675 , +-5557 , +-30787 , +-1981 , +24189 , +-22653 , +-13157 , +3339 , +-27767 , +-14973 , +-361 , +-13695 , +-31743 , +-28619 , +1255 , +21925 , +15065 , +-11859 , +15403 , +9185 , +1745 , +18619 , +21461 , +25819 , +13363 , +11275 , +-15823 , +-27449 , +10503 , +4539 , +1747 , +-12469 , +23499 , +4973 , +29585 , +-1323 , +7339 , +-31001 , +-19461 , +25701 , +-22215 , +8999 , +-13483 , +-7173 , +-32087 , +-5639 , +-16115 , +8537 , +32385 , +-20971 , +-19535 , +4463 , +-30247 , +-29263 , +-30099 , +17443 , +-26869 , +14749 , +-769 , +6833 , +-21001 , +24791 , +10799 , +32387 , +-26965 , +6313 , +29893 , +12425 , +5801 , +-26307 , +-8441 , +18695 , +14487 , +9905 , +-25427 , +3 , +-27011 , +32443 , +4953 , +22017 , +7797 , +-23887 , +397 , +-19083 , +18921 , +22065 , +1065 , +9355 , +16203 , +10797 , +12893 , +8067 , +-10677 , +27785 , +2087 , +-19575 , +-2419 , +-11215 , +22341 , +-3569 , +18665 , +16819 , +30383 , +21667 , +-19691 , +27731 , +26767 , +10569 , +-27153 , +-11351 , +11963 , +-24755 , +17955 , +-12879 , +1453 , +-29529 , +-18573 , +2409 , +-16905 , +-31803 , +-11677 , +24045 , +-5057 , +20969 , +27765 , +15871 , +10161 , +32265 , +23267 , +-22475 , +3843 , +-8169 , +-26663 , +-5253 , +19425 , +-5915 , +-3551 , +6205 , +19689 , +-19843 , +16235 , +30195 , +-4569 , +28911 , +-30467 , +-10941 , +-14331 , +23475 , +10981 , +5771 , +23755 , +-22659 , +23999 , +-17141 , +-9071 , +-22377 , +8931 , +-6549 , +-18501 , +-19019 , +2843 , +32481 , +-18449 , +-7343 , +-12311 , +2499 , +-10353 , +12161 , +14123 , +-10595 , +-28753 , +13903 , +14693 , +-1331 , +-11125 , +1683 , +-7567 , +-6249 , +30849 , +12103 , +-6991 , +-2873 , +11665 , +-25241 , +22227 , +-18503 , +-8893 , +25147 , +-27643 , +32509 , +-28877 , +-1475 , +-18777 , +-13717 , +-27143 , +11373 , +-23159 , +6077 , +15019 , +6691 , +11173 , +-9309 , +-24883 , +-26769 , +4685 , +-159 , +3285 , +25579 , +-18961 , +-17695 , +28437 , +23575 , +3395 , +9035 , +9531 , +15151 , +-25843 , +17957 , +-4023 , +1413 , +16971 , +10467 , +11531 , +-19629 , +29941 , +-31489 , +5393 , +13339 , +-19157 , +-26473 , +15903 , +25215 , +-7939 , +-7293 , +4149 , +143 , +16529 , +10469 , +27127 , +21673 , +-12569 , +-29363 , +11181 , +32465 , +-19185 , +10569 , +-8007 , +7817 , +28639 , +-6015 , +16273 , +24867 , +-26585 , +3405 , +-18381 , +4259 , +-14987 , +12495 , +-14043 , +-17651 , +-31939 , +6019 , +21217 , +-30141 , +-12125 , +12903 , +-24105 , +-7077 , +8865 , +9349 , +26337 , +27769 , +24779 , +9483 , +22073 , +31781 , +-11131 , +-27153 , +-23303 , +-21213 , +-32073 , +-22787 , +7433 , +-29751 , +-6135 , +23917 , +-101 , +2529 , +-28777 , +-10231 , +28199 , +-13841 , +31793 , +10161 , +-28193 , +-9443 , +-9209 , +-27515 , +14755 , +-635 , +-275 , +-22671 , +9859 , +1807 , +1801 , +-12211 , +-16723 , +-32573 , +19473 , +111 , +24303 , +5291 , +-5883 , +4551 , +675 , +-7131 , +27741 , +21107 , +31283 , +24249 , +8909 , +3293 , +-6137 , +-20107 , +-2955 , +25679 , +-17401 , +26305 , +19611 , +24073 , +-6777 , +20159 , +999 , +28379 , +29643 , +18455 , +-15087 , +25921 , +23797 , +347 , +-7129 , +2039 , +-23673 , +19157 , +8249 , +16655 , +-28081 , +4327 , +18327 , +11661 , +18153 , +-26913 , +13957 , +-5761 , +17077 , +2635 , +10361 , +28815 , +14923 , +1757 , +-11315 , +27427 , +-9353 , +8885 , +18429 , +16371 , +-15957 , +6981 , +1621 , +16923 , +20741 , +-17763 , +19767 , +21433 , +-20557 , +3407 , +3525 , +-10999 , +-27139 , +191 , +-31707 , +14317 , +11441 , +511 , +-5585 , +4123 , +-19935 , +-19163 , +15533 , +-2145 , +7579 , +23841 , +-29937 , +8197 , +31071 , +3099 , +-13921 , +-6169 , +11029 , +13383 , +-25021 , +19717 , +-7479 , +-20167 , +8109 , +-27931 , +26723 , +-7735 , +-233 , +-2593 , +-101 , +-5537 , +5239 , +-15677 , +-25993 , +-18483 , +-15043 , +-21791 , +-28103 , +-9551 , +15747 , +-21327 , +7911 , +-11459 , +-3123 , +26847 , +17713 , +-6753 , +28477 , +15335 , +29429 , +3787 , +-14261 , +-3021 , +-32205 , +12767 , +-9219 , +31913 , +23173 , +5619 , +-22111 , +21447 , +-5861 , +19571 , +-11521 , +10045 , +-22741 , +-26633 , +-18659 , +27651 , +26353 , +-5219 , +8041 , +19187 , +-24803 , +-25887 , +-2181 , +-17953 , +-4901 , +-11791 , +1865 , +6439 , +1083 , +-4475 , +10207 , +11733 , +-14543 , +-11967 , +-5483 , +-12233 , +-17651 , +-16515 , +10959 , +9965 , +-27537 , +-4691 , +-32213 , +-14709 , +4545 , +18989 , +5951 , +-29263 , +-9163 , +-24419 , +-16687 , +-27241 , +-22735 , +-21059 , +-6263 , +3893 , +18001 , +15295 , +18483 , +25809 , +-3621 , +-8413 , +-14227 , +30745 , +29111 , +27659 , +-25625 , +21693 , +26343 , +-17385 , +2069 , +12161 , +27523 , +-9027 , +-13203 , +2527 , +16679 , +15903 , +-23275 , +-11751 , +-14857 , +-1441 , +-8153 , +22477 , +-6129 , +-12925 , +32101 , +-4843 , +20351 , +-10819 , +-12185 , +3099 , +-2367 , +-19371 , +7525 , +-9935 , +27057 , +9967 , +10337 , +-9875 , +-7419 , +-20109 , +12003 , +-19019 , +71 , +28757 , +17457 , +25193 , +17483 , +-21635 , +-30707 , +-31893 , +8229 , +16787 , +12255 , +25795 , +-17751 , +-31777 , +-9601 , +24489 , +11863 , +-25959 , +9817 , +1073 , +30177 , +2507 , +569 , +-8371 , +-16623 , +28319 , +-20365 , +13685 , +23639 , +3389 , +-2907 , +-30279 , +3247 , +18209 , +25579 , +18775 , +-11745 , +-28169 , +20375 , +29659 , +3763 , +1769 , +17001 , +-26711 , +8175 , +8835 , +-30649 , +-1241 , +12489 , +-13053 , +-18313 , +19011 , +31271 , +17205 , +-17833 , +-24421 , +-22073 , +-2105 , +15501 , +18439 , +-22579 , +1319 , +5839 , +955 , +29351 , +18389 , +-29173 , +16347 , +18835 , +-18115 , +-3291 , +-621 , +-8819 , +8977 , +-27599 , +-11343 , +-16175 , +-15583 , +30765 , +-9285 , +-13115 , +-2133 , +-8909 , +-7293 , +-18813 , +-29629 , +-3793 , +-17589 , +-30269 , +-16613 , +-17119 , +-1967 , +16983 , +-26909 , +-17713 , +1005 , +15395 , +-24289 , +3325 , +-12509 , +-20073 , +-20225 , +-11741 , +713 , +167 , +-18757 , +-30293 , +1035 , +-4547 , +18277 , +931 , +-23147 , +-24517 , +-4797 , +-11527 , +-8927 , +-31255 , +-10073 , +-17871 , +21903 , +-6411 , +2377 , +2717 , +13701 , +20707 , +-30691 , +28183 , +-3459 , +-25841 , +-13907 , +4917 , +-30623 , +-18151 , +-12051 , +-19449 , +-4695 , +5099 , +10903 , +28487 , +7141 , +-24283 , +22785 , +-5095 , +-31513 , +28953 , +-14217 , +-16323 , +19531 , +-5305 , +-7155 , +-28465 , +7575 , +29003 , +25343 , +-6797 , +-2349 , +-24477 , +26249 , +9749 , +-16483 , +-5797 , +-32717 , +-17631 , +1221 , +-18675 , +14521 , +-14277 , +-20381 , +-9393 , +12119 , +31089 , +5745 , +31353 , +27047 , +23291 , +11745 , +11603 , +-5127 , +-19601 , +20019 , +-28277 , +12839 , +22647 , +18833 , +183 , +-24335 , +-2543 , +15209 , +-23097 , +-30765 , +16441 , +-7301 , +-22277 , +-13473 , +1843 , +-6787 , +-21921 , +-12273 , +-22989 , +-15063 , +17089 , +-16985 , +-15203 , +-2337 , +-15575 , +-19707 , +-7747 , +-9039 , +-5419 , +633 , +-23811 , +2055 , +-13401 , +3751 , +23707 , +-26705 , +-27351 , +-8243 , +-13081 , +2681 , +32255 , +2479 , +-32267 , +24137 , +-31781 , +-1567 , +-7719 , +-11335 , +14849 , +18081 , +19805 , +11819 , +24111 , +5689 , +21817 , +-14243 , +27685 , +14025 , +31181 , +21897 , +-6255 , +-343 , +27991 , +-22791 , +-27509 , +-29383 , +20647 , +20001 , +22161 , +-31677 , +-7579 , +29489 , +-4615 , +-11829 , +6327 , +-18377 , +19439 , +-23959 , +7555 , +-32595 , +-19229 , +5153 , +9513 , +30103 , +27021 , +-15937 , +6071 , +-25061 , +3675 , +-16729 , +-31587 , +-7017 , +-30347 , +6965 , +-10003 , +24633 , +-28889 , +-30319 , +20497 , +15125 , +-27425 , +15107 , +-26883 , +-29501 , +25257 , +-29225 , +-26129 , +371 , +-1245 , +-23641 , +29859 , +-23165 , +4595 , +30781 , +-759 , +-21089 , +-14137 , +-28443 , +-8059 , +-27829 , +-5441 , +-9139 , +-13413 , +24077 , +24181 , +-9519 , +-27599 , +28917 , +1641 , +-22693 , +-8637 , +-19269 , +-14335 , +-1859 , +13085 , +30301 , +-3845 , +-19583 , +781 , +-11731 , +-19607 , +9291 , +-30299 , +881 , +-4059 , +31395 , +3179 , +28785 , +1997 , +-25505 , +27667 , +-13539 , +-5571 , +-5781 , +-32713 , +7705 , +7293 , +2089 , +13713 , +7773 , +-4797 , +21067 , +-6479 , +-26299 , +-28695 , +-1503 , +-6347 , +22321 , +21985 , +-32643 , +-18045 , +19097 , +-16721 , +-27899 , +-6403 , +25505 , +-27035 , +-5369 , +-3393 , +-8129 , +-9581 , +17627 , +24273 , +28863 , +-25145 , +1969 , +15329 , +2285 , +-24193 , +-18959 , +15229 , +-19037 , +-8537 , +-16883 , +-17207 , +20195 , +-19321 , +-15393 , +-13385 , +24175 , +-2485 , +-1415 , +-30017 , +4833 , +-28951 , +-22907 , +-229 , +-26807 , +-3163 , +24855 , +-18569 , +-22729 , +7431 , +13063 , +17713 , +-18589 , +15949 , +8399 , +11 , +-30023 , +-3221 , +16087 , +3173 , +-29705 , +7553 , +-6571 , +7163 , +-15421 , +9675 , +8871 , +-7921 , +-15547 , +-8407 , +-4315 , +-21455 , +23355 , +-16893 , +23931 , +11373 , +30613 , +-24875 , +15489 , +-13823 , +-2165 , +-11497 , +22423 , +-27743 , +-9673 , +-21315 , +-6539 , +13859 , +-26709 , +16433 , +17801 , +-2373 , +-377 , +-27455 , +-28975 , +10169 , +28183 , +-1115 , +11051 , +4019 , +-15133 , +-14999 , +-3023 , +-17589 , +-9261 , +3567 , +-361 , +-20125 , +-6731 , +-10523 , +-23303 , +461 , +-29845 , +10421 , +-5319 , +-22895 , +7277 , +29195 , +-11693 , +-20583 , +-21515 , +-8769 , +-19269 , +12527 , +29317 , +-10405 , +17201 , +27505 , +19469 , +30213 , +14871 , +10253 , +-21891 , +1535 , +26447 , +-17029 , +-11047 , +26781 , +6283 , +-18323 , +-13605 , +-32061 , +-30163 , +-25011 , +-23291 , +29137 , +28317 , +-15757 , +-14027 , +-16605 , +9753 , +-23073 , +-13371 , +18953 , +-16613 , +-9875 , +21791 , +8251 , +22309 , +-9581 , +-7209 , +-807 , +-3043 , +-7535 , +-15555 , +-23081 , +28203 , +8241 , +3711 , +-8195 , +-32253 , +21501 , +6199 , +12643 , +-23603 , +18159 , +3723 , +10843 , +-21901 , +5045 , +13245 , +27895 , +-5257 , +-17821 , +-31923 , +11003 , +-8359 , +-2391 , +7047 , +21077 , +-6563 , +-12145 , +17315 , +8211 , +17903 , +-8275 , +26201 , +20963 , +-2441 , +-18209 , +-9995 , +-20993 , +22963 , +32385 , +-14601 , +6577 , +29065 , +2851 , +6699 , +-2495 , +-20629 , +-20793 , +-18633 , +-905 , +-3041 , +-2411 , +-6469 , +20103 , +-10203 , +30481 , +17133 , +-1899 , +-11127 , +4311 , +419 , +-26717 , +25657 , +-22573 , +-3331 , +24337 , +-18973 , +-15117 , +3177 , +13457 , +1607 , +6761 , +-10163 , +6815 , +15121 , +25179 , +-24041 , +-24201 , +-10699 , +-28645 , +-18735 , +-26991 , +-9795 , +-13337 , +-28095 , +-21859 , +-19409 , +12567 , +20607 , +17899 , +-12967 , +-14631 , +15367 , +17273 , +-13393 , +-21647 , +-12199 , +-13739 , +10785 , +-5667 , +2317 , +-603 , +13939 , +-3545 , +21863 , +-17637 , +4119 , +11269 , +2173 , +8169 , +-16511 , +-25569 , +-25157 , +3129 , +-507 , +5063 , +-22001 , +23851 , +-14809 , +-7385 , +-11921 , +5451 , +17533 , +-31225 , +-26371 , +11139 , +16639 , +17143 , +28063 , +14491 , +-26403 , +13583 , +-18673 , +-17621 , +-7963 , +-18391 , +20343 , +10777 , +-14265 , +-20591 , +14223 , +-29303 , +21503 , +-24765 , +-8407 , +-10661 , +-30045 , +4005 , +-9645 , +-21467 , +-22339 , +13237 , +23275 , +-5725 , +30119 , +18895 , +18103 , +32693 , +-12073 , +-20779 , +16895 , +-2347 , +4043 , +7159 , +-31071 , +18195 , +17483 , +1759 , +-8275 , +16005 , +851 , +-25489 , +-24197 , +11845 , +-15265 , +19961 , +-2489 , +5609 , +29003 , +26867 , +22333 , +1399 , +16035 , +-20175 , +-30171 , +-4639 , +25731 , +30113 , +-1181 , +-26629 , +-12309 , +6013 , +-13145 , +-1549 , +25751 , +31749 , +28657 , +-23731 , +-6311 , +24761 , +10039 , +30545 , +10475 , +2577 , +16499 , +28177 , +-30381 , +17583 , +26181 , +-27693 , +27561 , +12573 , +-8959 , +-237 , +-19835 , +-11767 , +1099 , +-2825 , +-9021 , +-11027 , +-2765 , +-3001 , +-9495 , +-29347 , +-27447 , +-8475 , +13557 , +-25941 , +-3279 , +-1593 , +-26435 , +12329 , +20293 , +-1171 , +26817 , +30693 , +-26969 , +-7975 , +25479 , +2005 , +-17835 , +-16119 , +-1167 , +-7783 , +-20535 , +22249 , +30485 , +-2899 , +30351 , +31189 , +29209 , +-25819 , +-1451 , +15497 , +-10623 , +2277 , +10643 , +-5477 , +-6509 , +9557 , +6289 , +-25483 , +28455 , +-14433 , +-30453 , +-26167 , +-17791 , +-12965 , +-20923 , +17041 , +23469 , +987 , +-31321 , +-18823 , +27217 , +23505 , +-25653 , +-3351 , +18181 , +24461 , +-27105 , +-24725 , +-32719 , +25527 , +22779 , +16559 , +-4253 , +27271 , +8759 , +2563 , +-22751 , +12665 , +28735 , +1347 , +-14009 , +24967 , +3507 , +-13995 , +-8737 , +23013 , +6527 , +30501 , +-15753 , +-29389 , +25449 , +13591 , +-13831 , +-5831 , +-2765 , +-7935 , +9473 , +16667 , +8237 , +12455 , +10943 , +12821 , +-6315 , +-1875 , +-26049 , +31409 , +7651 , +-11761 , +27727 , +15489 , +4715 , +-10717 , +19917 , +8277 , +7795 , +-22273 , +23177 , +-11023 , +-3453 , +-30073 , +12433 , +-8117 , +-2357 , +-23089 , +-3049 , +15167 , +-26575 , +22307 , +23485 , +-20539 , +-9751 , +-24451 , +23921 , +29099 , +913 , +-31633 , +-27707 , +-5677 , +-15415 , +32689 , +-3125 , +11233 , +-24759 , +-9981 , +-5271 , +3703 , +1141 , +-69 , +-32723 , +24049 , +-9341 , +-20315 , +-31057 , +8597 , +-5375 , +6547 , +-30113 , +27475 , +-5897 , +-19647 , +32231 , +-22021 , +-28543 , +2521 , +-13323 , +-2579 , +-27679 , +11239 , +-8027 , +20575 , +-15593 , +-2093 , +-15543 , +19719 , +16131 , +-41 , +-10037 , +7773 , +4335 , +15477 , +26239 , +31825 , +-339 , +17779 , +-4737 , +23935 , +-3275 , +18769 , +-2433 , +-1305 , +-11339 , +31559 , +26157 , +5677 , +6439 , +12205 , +-3585 , +-1461 , +1651 , +24325 , +-12913 , +11971 , +-11519 , +-14485 , +10359 , +21859 , +-24113 , +25739 , +-27485 , +10873 , +-25331 , +30239 , +-4819 , +8069 , +3635 , +-13091 , +-10833 , +-30599 , +-13667 , +-27139 , +27177 , +-11415 , +-13159 , +23845 , +14147 , +-15667 , +20745 , +31975 , +4925 , +8753 , +20857 , +-19015 , +-4299 , +-4753 , +-19791 , +9063 , +14599 , +25191 , +-39 , +18705 , +-6749 , +-2759 , +2559 , +27559 , +-17433 , +-24835 , +17477 , +-3371 , +-2061 , +32499 , +13413 , +2179 , +-8439 , +17995 , +-12333 , +11983 , +23511 , +26187 , +7513 , +1147 , +15199 , +30995 , +-3295 , +-4111 , +8771 , +-9005 , +10587 , +-5963 , +-11611 , +-1663 , +6481 , +5977 , +-9609 , +10511 , +-16137 , +-31743 , +16989 , +-17883 , +25361 , +-29877 , +21753 , +1375 , +-1091 , +20951 , +5841 , +3321 , +24983 , +-4559 , +-31079 , +-24813 , +27461 , +-32427 , +15893 , +29279 , +-3683 , +-2655 , +-29843 , +13665 , +1583 , +-25529 , +-25853 , +2081 , +13929 , +24915 , +-13871 , +22631 , +13093 , +-12775 , +-18369 , +-26511 , +-19255 , +-28113 , +13681 , +-14293 , +-3113 , +-13595 , +-25807 , +18663 , +-29169 , +-16067 , +-19911 , +-3175 , +12287 , +22121 , +-18673 , +-5753 , +-9445 , +-10571 , +-26785 , +6023 , +8285 , +27405 , +-47 , +-7239 , +10065 , +-7953 , +21091 , +-587 , +-9801 , +225 , +7485 , +-14001 , +2971 , +11119 , +10763 , +23495 , +-2077 , +29855 , +-16935 , +-31867 , +-5775 , +-2589 , +8551 , +-11701 , +26805 , +-29021 , +2557 , +8697 , +-14899 , +-13537 , +-1331 , +-29769 , +22289 , +10743 , +14017 , +18871 , +17463 , +30747 , +23259 , +31593 , +13791 , +31561 , +14599 , +17457 , +-15943 , +-23809 , +2935 , +15525 , +-5361 , +-2061 , +-26501 , +-20929 , +-28695 , +531 , +24275 , +-28261 , +6811 , +-8971 , +25231 , +-14555 , +20451 , +13005 , +-19869 , +-32161 , +-28287 , +22003 , +15743 , +24459 , +27979 , +12489 , +4583 , +7151 , +-12083 , +17473 , +-25779 , +26757 , +-18095 , +27851 , +-1435 , +-12493 , +-18291 , +-23083 , +3267 , +8841 , +9639 , +-31811 , +15661 , +28661 , +21211 , +-25523 , +-19339 , +-4995 , +-24693 , +-27213 , +725 , +-11281 , +-16679 , +5109 , +-9795 , +-19801 , +2753 , +15593 , +-4549 , +4539 , +15277 , +2743 , +-25665 , +-581 , +23701 , +9413 , +24453 , +24545 , +21387 , +30513 , +-15259 , +-24111 , +-10531 , +16591 , +-10459 , +-27699 , +9897 , +-12385 , +-17567 , +3437 , +25335 , +-23619 , +30927 , +16599 , +-10679 , +12521 , +-26323 , +14457 , +3269 , +-2453 , +-20859 , +30523 , +4021 , +9631 , +23053 , +13123 , +-25163 , +-28963 , +-5239 , +8993 , +-18629 , +3321 , +12557 , +21897 , +22459 , +10043 , +-28819 , +2963 , +-19659 , +8663 , +-1281 , +3435 , +-12203 , +13535 , +-5883 , +29065 , +-10491 , +8641 , +-11907 , +20081 , +-5241 , +-8385 , +22899 , +20193 , +-4591 , +-27675 , +-16919 , +-24433 , +-2337 , +-26879 , +-26851 , +13665 , +-6453 , +-20451 , +-29585 , +-12513 , +-7057 , +19699 , +4273 , +-12875 , +7597 , +-6681 , +-16639 , +14305 , +-23081 , +18693 , +28709 , +-2445 , +-14281 , +875 , +-24485 , +-17921 , +-22727 , +-24237 , +15801 , +-31973 , +32756 , +-901 , +30463 , +17677 , +27203 , +20773 , +-23821 , +-25839 , +-4755 , +20877 , +-10183 , +2051 , +16683 , +-4127 , +19875 , +-18269 , +-27837 , +5823 , +6937 , +16451 , +10667 , +2079 , +29407 , +18437 , +-18155 , +-25893 , +-5253 , +-22379 , +-14325 , +3739 , +-3579 , +-6567 , +30345 , +-20911 , +-765 , +-30673 , +-32237 , +-1739 , +-26691 , +16545 , +-8623 , +-30153 , +-8679 , +24997 , +-17891 , +30203 , +-32523 , +-27955 , +18727 , +22351 , +-5389 , +16895 , +10755 , +-15839 , +-25117 , +-14671 , +-16183 , +21759 , +24715 , +-20575 , +24107 , +8451 , +21767 , +13069 , +-29949 , +-24491 , +-28767 , +14689 , +20607 , +-3293 , +17959 , +-1405 , +-11099 , +-25843 , +12227 , +-23177 , +9079 , +27951 , +11603 , +2725 , +31879 , +-3451 , +-11709 , +-16251 , +-753 , +-4359 , +-6687 , +-17691 , +-375 , +18117 , +30011 , +-13163 , +457 , +-1411 , +-29329 , +2979 , +32405 , +29051 , +13965 , +-28649 , +28597 , +-13601 , +-14619 , +-31451 , +-3173 , +27905 , +9957 , +1255 , +-9881 , +-29845 , +7537 , +-18791 , +29331 , +-9387 , +15543 , +-22713 , +-32515 , +11925 , +-30839 , +21777 , +-26239 , +11551 , +26427 , +25823 , +-11497 , +-6921 , +2541 , +-1393 , +6763 , +26799 , +-16011 , +11201 , +487 , +13399 , +31397 , +-31495 , +26209 , +-28417 , +-6865 , +6503 , +-16353 , +-20831 , +25595 , +5401 , +30845 , +-21333 , +24061 , +18867 , +7165 , +18663 , +1931 , +-21081 , +-16159 , +27901 , +15419 , +17903 , +31301 , +21093 , +-32463 , +29249 , +12213 , +29923 , +-14329 , +5067 , +-20155 , +2943 , +2581 , +-31125 , +24617 , +16375 , +21585 , +-7067 , +17359 , +-9023 , +23461 , +-29547 , +-7307 , +-22151 , +12745 , +25401 , +-17343 , +11743 , +12953 , +-15083 , +-21541 , +4941 , +-15893 , +-23243 , +10115 , +-9037 , +-3603 , +-13017 , +-26715 , +11527 , +-22025 , +-18519 , +-20483 , +21571 , +26089 , +-529 , +7201 , +23261 , +9723 , +-12463 , +22693 , +17339 , +-22755 , +27519 , +4265 , +-17235 , +31689 , +5963 , +-10247 , +-2709 , +7519 , +-31797 , +-26209 , +-11005 , +-29189 , +8227 , +-27907 , +17875 , +-23859 , +19889 , +13161 , +-12277 , +-28941 , +-4405 , +-18369 , +14997 , +-14641 , +18421 , +-8837 , +27293 , +-11299 , +-21605 , +31443 , +14717 , +12563 , +-6073 , +25931 , +31035 , +-14419 , +-3753 , +27989 , +-8321 , +9359 , +-17861 , +-11941 , +3851 , +-485 , +-17369 , +-791 , +30645 , +8835 , +7759 , +-5067 , +17629 , +26283 , +-1891 , +3133 , +4709 , +-21129 , +-22293 , +-4249 , +-24535 , +-24665 , +-19787 , +-20857 , +15355 , +11319 , +8537 , +20107 , +6671 , +26917 , +-6963 , +641 , +21511 , +-4901 , +8403 , +-23999 , +-14761 , +14331 , +-6479 , +11635 , +-31671 , +18369 , +20851 , +-19661 , +6769 , +-5937 , +31891 , +30247 , +22435 , +-7535 , +19777 , +-23277 , +-11151 , +-27893 , +-31219 , +32756 , +-3807 , +4921 , +7465 , +16791 , +-32227 , +31713 , +19743 , +-23117 , +-7435 , +25327 , +22531 , +25471 , +-22569 , +10571 , +30003 , +29901 , +-23169 , +12595 , +-7797 , +-32361 , +-30797 , +-27377 , +-30181 , +18475 , +-20929 , +30413 , +18791 , +22959 , +-30619 , +32693 , +12051 , +837 , +9953 , +-22327 , +-13787 , +-17505 , +15441 , +-7279 , +-4679 , +-4841 , +17465 , +-17537 , +-6085 , +29767 , +2171 , +-30787 , +-23269 , +-21723 , +15685 , +17805 , +-20217 , +22673 , +27541 , +-19685 , +-26457 , +23675 , +-7641 , +-15653 , +-26161 , +28781 , +-6923 , +-169 , +7993 , +-11089 , +-11477 , +-2153 , +-321 , +16853 , +31645 , +19429 , +-3567 , +-2339 , +22467 , +29495 , +16877 , +15305 , +-6863 , +-12035 , +7129 , +12459 , +-10867 , +13179 , +-30119 , +16721 , +19717 , +21155 , +-30811 , +5445 , +-6323 , +26475 , +8935 , +21629 , +-17649 , +29603 , +12267 , +6241 , +5101 , +21075 , +31075 , +24937 , +6895 , +10381 , +-4719 , +26937 , +9603 , +20171 , +-17017 , +10547 , +-7443 , +19135 , +-6433 , +-4717 , +8263 , +-3663 , +8175 , +19717 , +23287 , +19289 , +-24955 , +23739 , +-9823 , +19757 , +-20193 , +30989 , +-31833 , +1605 , +-23905 , +31369 , +12059 , +21421 , +-8059 , +-20599 , +-25285 , +-19143 , +-9299 , +29269 , +-8857 , +23273 , +-25733 , +-19531 , +20123 , +687 , +31643 , +21001 , +-2205 , +-16675 , +3129 , +-27427 , +27735 , +15593 , +-29513 , +-23283 , +-749 , +-23343 , +-1817 , +22863 , +24489 , +-22287 , +8383 , +12119 , +-27999 , +-8619 , +-15723 , +-13977 , +11629 , +-2661 , +8147 , +-14233 , +-10399 , +-5057 , +1077 , +23169 , +7469 , +-12671 , +-18563 , +22077 , +23761 , +8623 , +-11865 , +14859 , +25 , +-28923 , +27053 , +-6039 , +-17007 , +-6391 , +-26959 , +30835 , +6151 , +5461 , +-17473 , +-3329 , +-11151 , +7421 , +-27135 , +21553 , +-24969 , +-19105 , +-31371 , +-22119 , +-27807 , +-24703 , +2089 , +-23353 , +-5229 , +19425 , +-8203 , +31329 , +31359 , +-5931 , +-9557 , +26047 , +15657 , +29023 , +-19243 , +-22273 , +-20721 , +-11135 , +3819 , +24999 , +7599 , +-13025 , +-4851 , +2475 , +-19845 , +-32175 , +-18119 , +-743 , +27465 , +-30663 , +16383 , +-9183 , +-18089 , +22877 , +-24633 , +8629 , +-325 , +-8061 , +-23947 , +-14685 , +-23967 , +11011 , +31155 , +18727 , +-3465 , +-9309 , +21921 , +-3837 , +-29319 , +30187 , +-12793 , +-22501 , +-30315 , +6659 , +-27109 , +16273 , +4783 , +-14077 , +29357 , +31053 , +-18733 , +-13867 , +-5403 , +-20949 , +6451 , +18051 , +-21637 , +26749 , +17305 , +-17899 , +5227 , +-13513 , +20067 , +18151 , +-5839 , +7541 , +-26889 , +-29307 , +-25731 , +21151 , +15553 , +7161 , +10355 , +-6399 , +7333 , +3503 , +87 , +-5925 , +763 , +-3131 , +-3889 , +-31233 , +19459 , +-25113 , +-30313 , +-2585 , +-21789 , +-9309 , +-3143 , +6223 , +20249 , +-12729 , +-19639 , +-24505 , +8311 , +-7375 , +19347 , +9175 , +18837 , +3761 , +15837 , +-6135 , +-14121 , +24407 , +23199 , +-15991 , +16337 , +-32301 , +-8911 , +-7745 , +-18095 , +19781 , +18957 , +-6049 , +-25139 , +-4069 , +-30847 , +4487 , +-29095 , +-10899 , +10481 , +-10151 , +24109 , +-9527 , +25725 , +-6649 , +-7541 , +-4461 , +-21687 , +-23169 , +-11963 , +-20773 , +23601 , +21355 , +26027 , +8377 , +-30469 , +-7455 , +1033 , +6175 , +17945 , +-29079 , +-27743 , +26673 , +31959 , +28059 , +-14563 , +29733 , +-18409 , +-6341 , +2951 , +14481 , +-7281 , +22475 , +21957 , +25931 , +30071 , +-15193 , +-31085 , +-24647 , +-1341 , +-3173 , +-25357 , +-31311 , +32229 , +-16645 , +28459 , +-30515 , +-16391 , +-453 , +8765 , +14915 , +-17279 , +-9463 , +6107 , +7997 , +28573 , +-5403 , +-29979 , +-23117 , +22217 , +-6863 , +-28073 , +20929 , +-23545 , +19927 , +-15663 , +-17539 , +-25689 , +-5033 , +9851 , +30037 , +5235 , +26461 , +-15471 , +29411 , +-28051 , +-8987 , +26953 , +2115 , +-3065 , +-12603 , +-1187 , +6639 , +10711 , +15315 , +-3089 , +-27369 , +-3887 , +15723 , +21525 , +-14219 , +1795 , +411 , +-17729 , +-19031 , +-11577 , +31149 , +-9665 , +-3313 , +-2945 , +-27325 , +1077 , +13847 , +-17721 , +25077 , +1037 , +7711 , +-3783 , +-6311 , +-9 , +22473 , +407 , +6065 , +-26537 , +-20269 , +-8309 , +-21263 , +-563 , +13423 , +-18717 , +19039 , +13723 , +-6117 , +-11207 , +-17753 , +17581 , +16635 , +-16319 , +-23941 , +30977 , +-5711 , +1389 , +32673 , +-30287 , +-3919 , +-26575 , +19601 , +-15013 , +-2279 , +22965 , +-24437 , +1823 , +30739 , +-21227 , +-23505 , +-21987 , +-16225 , +-26865 , +-19817 , +13155 , +-20493 , +24639 , +-273 , +-5525 , +-10155 , +12763 , +5767 , +6159 , +6249 , +-23325 , +-26765 , +9225 , +17683 , +-17439 , +-3171 , +18655 , +-1073 , +16157 , +-26527 , +5735 , +13695 , +-3243 , +21157 , +31415 , +-20017 , +-23819 , +18285 , +-30305 , +-11517 , +29137 , +22773 , +-17757 , +599 , +29529 , +20557 , +-10895 , +13523 , +-1195 , +-23701 , +17623 , +-22369 , +-24291 , +12227 , +2113 , +29415 , +27981 , +-16023 , +-1105 , +-2523 , +10751 , +-16743 , +-20957 , +-9983 , +19847 , +-12325 , +32429 , +-27219 , +30631 , +-9059 , +14285 , +14769 , +-1727 , +13371 , +-7811 , +28233 , +24223 , +15273 , +415 , +24901 , +29723 , +30593 , +757 , +-22959 , +-17057 , +19101 , +-1377 , +-22311 , +-10465 , +16691 , +-31729 , +-14753 , +-17593 , +16483 , +-5249 , +-22191 , +24509 , +29277 , +24303 , +-931 , +-22633 , +18157 , +23959 , +3669 , +7889 , +24727 , +7649 , +32377 , +30851 , +-14799 , +8677 , +-30373 , +18331 , +12537 , +-19879 , +3627 , +-5605 , +-12495 , +30737 , +-7013 , +7879 , +21291 , +-5135 , +-25807 , +15713 , +-22795 , +-10901 , +13851 , +-30363 , +7259 , +-28817 , +1679 , +-26823 , +29069 , +19435 , +12963 , +15343 , +-32199 , +3519 , +1433 , +-143 , +-747 , +-28367 , +-24379 , +-30393 , +-2555 , +-9487 , +9441 , +-65 , +-21331 , +-23163 , +-5153 , +-11849 , +24453 , +25925 , +-5305 , +-7487 , +-31877 , +6871 , +-10479 , +-28177 , +14337 , +-21475 , +7413 , +-27907 , +20401 , +-1093 , +20551 , +4619 , +-15021 , +30469 , +7765 , +6621 , +-2679 , +21111 , +25395 , +-19315 , +29909 , +11441 , +30497 , +-16707 , +-9663 , +20461 , +19537 , +-6821 , +22125 , +18939 , +30037 , +-14891 , +28453 , +4785 , +-21533 , +-22323 , +-18555 , +30953 , +-4037 , +-12465 , +-9083 , +3577 , +-9995 , +-13673 , +-8683 , +18341 , +11103 , +-10697 , +-13129 , +4259 , +21591 , +-21283 , +-7273 , +32645 , +-9831 , +-12413 , +22303 , +-5063 , +23461 , +-18647 , +-20461 , +7171 , +16393 , +-5873 , +2853 , +-17429 , +-25533 , +25963 , +5395 , +-7741 , +30995 , +26787 , +6969 , +-13425 , +1625 , +-2303 , +2221 , +-27249 , +-10393 , +10989 , +-22571 , +7847 , +-16419 , +-16985 , +125 , +-11425 , +26877 , +-15743 , +10871 , +-26791 , +14217 , +3211 , +27817 , +-31413 , +-26093 , +14045 , +171 , +-17035 , +22493 , +-14531 , +21213 , +-1383 , +-2003 , +25447 , +5887 , +9587 , +-9689 , +-28487 , +2381 , +-24909 , +5407 , +-2449 , +-19443 , +30579 , +-18055 , +-26019 , +4535 , +20527 , +-30213 , +4135 , +25463 , +5693 , +-14933 , +4853 , +5213 , +22469 , +6691 , +-32337 , +229 , +26175 , +22117 , +13747 , +-1263 , +-163 , +-2501 , +-21491 , +-7417 , +-19309 , +7693 , +-1745 , +11299 , +-14079 , +7987 , +-211 , +9877 , +-16905 , +7383 , +24173 , +-6799 , +17891 , +-5821 , +6375 , +6481 , +-10797 , +-19521 , +24533 , +-18589 , +-29341 , +-24855 , +-31755 , +-15099 , +-21191 , +-10361 , +-32709 , +8161 , +21503 , +17385 , +5891 , +-25985 , +-17955 , +25531 , +-1579 , +17761 , +-23961 , +30807 , +-3175 , +15513 , +15649 , +-29269 , +-29369 , +-11807 , +11375 , +31621 , +9519 , +27445 , +-5363 , +30579 , +-3939 , +-4635 , +18447 , +20245 , +-8159 , +3641 , +12625 , +-7433 , +-8635 , +23419 , +-31633 , +-1557 , +24761 , +24727 , +7747 , +1247 , +-15335 , +-20171 , +-7975 , +-5321 , +27169 , +15177 , +-6171 , +30625 , +4701 , +-19149 , +-23617 , +32113 , +25967 , +-32689 , +4827 , +20087 , +10937 , +-10217 , +-11841 , +-26281 , +8353 , +-23117 , +14713 , +18529 , +-4287 , +-12271 , +17565 , +30959 , +11679 , +24707 , +29365 , +9005 , +-3731 , +21457 , +25155 , +-30073 , +-7883 , +28633 , +22831 , +3693 , +16669 , +-2663 , +29637 , +29623 , +-3561 , +-30763 , +-19923 , +15995 , +-9315 , +7721 , +-25503 , +13407 , +-18457 , +23713 , +-19295 , +-24711 , +-17759 , +10193 , +28791 , +27043 , +2599 , +-12947 , +-4061 , +-22445 , +-31939 , +-26267 , +11415 , +-20235 , +-16571 , +12147 , +-11279 , +19901 , +-11017 , +-32447 , +-29583 , +11017 , +-13415 , +-18189 , +-10765 , +5423 , +14521 , +-4021 , +16867 , +7901 , +97 , +3125 , +14777 , +18413 , +-20525 , +-27411 , +3057 , +-17221 , +27327 , +-7541 , +30587 , +17921 , +-7427 , +30239 , +28101 , +303 , +21187 , +-10419 , +17179 , +-1727 , +-3747 , +-12707 , +1459 , +-18413 , +-9627 , +21211 , +13083 , +26691 , +-8325 , +1705 , +-31689 , +-24701 , +15487 , +-27233 , +1969 , +26989 , +-22969 , +-11883 , +17143 , +-21787 , +-21545 , +-7415 , +-28239 , +30185 , +-7651 , +26161 , +31675 , +26089 , +-11745 , +-13167 , +14747 , +-25431 , +8637 , +-9445 , +8057 , +30599 , +-4377 , +-25413 , +9881 , +-27289 , +-10925 , +-24199 , +19789 , +17661 , +-26959 , +-7667 , +1399 , +-3159 , +-8851 , +8183 , +27003 , +-19247 , +4577 , +6679 , +28593 , +31159 , +-17911 , +28105 , +-11157 , +4561 , +23493 , +31861 , +-3483 , +-29787 , +22919 , +11693 , +16823 , +3607 , +-15981 , +-6715 , +-19111 , +-15797 , +-30799 , +-30489 , +-20715 , +-6659 , +8553 , +-7505 , +-15873 , +-25007 , +-841 , +19011 , +-1173 , +-23761 , +-14005 , +-9497 , +-5523 , +23325 , +3125 , +6425 , +7623 , +32663 , +-2519 , +23589 , +20581 , +-7707 , +-3027 , +-11199 , +-935 , +26735 , +-3369 , +-31449 , +-29619 , +-9055 , +-13305 , +3363 , +-7297 , +-24267 , +-10475 , +-28487 , +29749 , +-5867 , +5013 , +-23891 , +-25413 , +-31057 , +-6523 , +-32599 , +-32043 , +-5173 , +-7663 , +31823 , +9659 , +29163 , +-28743 , +-5935 , +-8563 , +-31975 , +-19171 , +25865 , +1873 , +-17597 , +2853 , +-9709 , +101 , +-26091 , +-8253 , +1633 , +19577 , +-8879 , +-26075 , +-4779 , +-1269 , +7077 , +-26253 , +863 , +6487 , +-18431 , +26113 , +28299 , +25049 , +-14989 , +-21239 , +13213 , +-7625 , +-3203 , +-281 , +-22613 , +-12339 , +6897 , +-14393 , +-459 , +17037 , +-31937 , +31465 , +19383 , +3727 , +30809 , +26709 , +-11061 , +29685 , +18693 , +13579 , +441 , +-8847 , +17841 , +28101 , +-12657 , +25905 , +-10283 , +11309 , +4031 , +22631 , +18881 , +18065 , +25395 , +28975 , +22269 , +543 , +9699 , +-237 , +7453 , +-16485 , +17907 , +-18943 , +-31465 , +-25959 , +18757 , +23485 , +-17121 , +29485 , +24727 , +3043 , +-9473 , +23093 , +-8431 , +19029 , +16105 , +-10247 , +-4503 , +-25543 , +-12581 , +1401 , +-10381 , +-8335 , +-23959 , +-4073 , +-18625 , +6289 , +14109 , +16341 , +-1881 , +-4269 , +-15027 , +-26613 , +27253 , +-28263 , +-12935 , +-21857 , +18925 , +13537 , +30227 , +30141 , +6639 , +-4557 , +-11795 , +-23533 , +-24947 , +6315 , +-22785 , +-30847 , +-10979 , +607 , +-12861 , +-22953 , +16601 , +6119 , +-16105 , +21261 , +25585 , +17995 , +30345 , +18041 , +-17111 , +-13447 , +5939 , +-19323 , +8681 , +11593 , +-20205 , +-11409 , +-13091 , +-28953 , +30953 , +19829 , +-1783 , +7381 , +-19325 , +-27371 , +24927 , +-14497 , +-6753 , +-27703 , +31965 , +915 , +19775 , +-21707 , +-12513 , +-13639 , +24447 , +-32543 , +9595 , +-28593 , +16371 , +-29575 , +6295 , +26231 , +-8581 , +-8069 , +-21887 , +2301 , +-13159 , +9591 , +22855 , +1727 , +25423 , +16321 , +32273 , +-15945 , +20847 , +-26707 , +20663 , +32099 , +10875 , +31815 , +26585 , +13251 , +3579 , +-26493 , +3447 , +26839 , +-177 , +-3325 , +16397 , +-19315 , +1549 , +28741 , +-18397 , +15165 , +-20777 , +20315 , +-13717 , +-13147 , +1209 , +-26329 , +32345 , +-7843 , +-25869 , +-1515 , +-20169 , +11979 , +-16543 , +-439 , +-25149 , +2471 , +27973 , +10341 , +-24513 , +20193 , +6313 , +-9551 , +-28911 , +2865 , +-5579 , +-29979 , +32725 , +-26381 , +-31869 , +14413 , +20733 , +27835 , +-7175 , +-25451 , +-12327 , +18485 , +-31197 , +3825 , +-11451 , +2989 , +19849 , +-28193 , +8877 , +-8701 , +23817 , +859 , +-32331 , +-7399 , +28075 , +-6249 , +-18367 , +14557 , +-16901 , +-14799 , +-4325 , +29365 , +12773 , +-28173 , +14597 , +19317 , +-17655 , +4867 , +-24493 , +-14881 , +-24177 , +-13415 , +-28421 , +29595 , +-14969 , +20291 , +-2247 , +6819 , +28863 , +-31601 , +-5469 , +29001 , +-12009 , +-13999 , +15803 , +10413 , +-19621 , +29003 , +-13811 , +-601 , +-26977 , +-26767 , +-12089 , +2133 , +-20467 , +-18015 , +18381 , +511 , +-2229 , +5845 , +27477 , +-18019 , +-11449 , +18393 , +27647 , +28357 , +32661 , +2701 , +-28313 , +19243 , +-15803 , +-18537 , +-22201 , +-19821 , +2619 , +23195 , +6919 , +-24241 , +-29175 , +-6927 , +30677 , +-11985 , +-31933 , +29411 , +-8381 , +-8959 , +1629 , +7007 , +4187 , +6787 , +-13571 , +16947 , +32565 , +25313 , +11477 , +-6973 , +18197 , +-32347 , +-18179 , +-9919 , +20735 , +-32201 , +-14389 , +30821 , +-31029 , +-27697 , +16165 , +-22103 , +27335 , +-17423 , +5475 , +-13829 , +-5177 , +3939 , +-21349 , +25845 , +-12863 , +-22103 , +-24955 , +14491 , +32479 , +6897 , +4299 , +31629 , +-20189 , +-31587 , +10727 , +-8761 , +-28559 , +7211 , +-16783 , +15309 , +-4817 , +19637 , +-12543 , +31851 , +13149 , +12011 , +-4475 , +-28435 , +-31187 , +-28797 , +10519 , +4055 , +-10219 , +15415 , +-31915 , +25111 , +22383 , +-12485 , +-21963 , +-1339 , +1931 , +-20167 , +-5271 , +-28331 , +-8627 , +-30271 , +3629 , +-10665 , +15933 , +-10683 , +9373 , +-25951 , +9513 , +-8295 , +-4713 , +-7915 , +-6353 , +-14887 , +-8435 , +-11563 , +-12695 , +-9485 , +28889 , +3573 , +30447 , +919 , +-16353 , +18105 , +16255 , +22187 , +8989 , +-19635 , +-22897 , +-19637 , +-14971 , +14843 , +-5147 , +-31429 , +-6827 , +-9759 , +-12625 , +28647 , +-14285 , +17965 , +-16357 , +6095 , +317 , +11223 , +25201 , +-15735 , +8041 , +6611 , +-21335 , +1333 , +23639 , +-31801 , +-30077 , +14709 , +25517 , +-10419 , +20769 , +-3867 , +-13587 , +7077 , +-8167 , +7957 , +20943 , +5099 , +-14567 , +12799 , +-31981 , +23509 , +18419 , +-12035 , +-12827 , +30435 , +-29385 , +31305 , +-20571 , +18977 , +-4783 , +-18709 , +1613 , +-1965 , +-28129 , +7477 , +9025 , +-26439 , +23811 , +-9791 , +-18771 , +-16319 , +24451 , +-2341 , +11095 , +21819 , +-16293 , +6793 , +-29961 , +-23143 , +25883 , +-3335 , +-31979 , +14243 , +14393 , +2425 , +-23969 , +19761 , +25515 , +13303 , +26235 , +-28321 , +22527 , +23789 , +12901 , +-5943 , +-2055 , +-9755 , +-15033 , +-9151 , +-16227 , +2153 , +18895 , +-27131 , +17877 , +27005 , +-27129 , +-5761 , +-9339 , +-3177 , +-19539 , +23923 , +-15589 , +-11493 , +18701 , +-20291 , +-19021 , +20811 , +-1451 , +-11895 , +8873 , +6601 , +23409 , +-16635 , +-1361 , +-27005 , +-30107 , +19877 , +24425 , +-26059 , +2585 , +17865 , +3971 , +4447 , +-2621 , +-10997 , +-6327 , +-3655 , +9391 , +-13853 , +19909 , +8239 , +22177 , +-28181 , +-6585 , +-31403 , +167 , +29331 , +24209 , +2147 , +-11661 , +-2983 , +-20129 , +-22355 , +-29639 , +-1917 , +-19061 , +28057 , +15609 , +29011 , +20893 , +25877 , +-32407 , +13509 , +11235 , +26773 , +-9415 , +-7743 , +12047 , +-8061 , +-18175 , +20437 , +-17589 , +15937 , +18051 , +-32403 , +-9265 , +25749 , +-25195 , +-28527 , +22785 , +-18767 , +28525 , +-29167 , +-257 , +1431 , +-16769 , +-13499 , +-3895 , +5153 , +-16171 , +-31161 , +24519 , +-5771 , +-32029 , +28835 , +32752 , +-22025 , +25315 , +2199 , +4181 , +11975 , +-855 , +15557 , +20553 , +5051 , +-25085 , +21101 , +-18201 , +29647 , +-9337 , +-31189 , +21299 , +3107 , +24049 , +24353 , +697 , +-653 , +32760 , +11455 , +-25453 , +-7157 , +-11097 , +-22801 , +8981 , +32323 , +11833 , +10453 , +-555 , +-26251 , +15725 , +32255 , +-31155 , +32119 , +24923 , +-17885 , +-16145 , +-29041 , +-16429 , +4955 , +-25927 , +24047 , +15919 , +14031 , +-31909 , +-8021 , +29357 , +4091 , +-17477 , +1331 , +9805 , +31327 , +12575 , +24391 , +32541 , +-10819 , +15545 , +8817 , +27419 , +-2871 , +8135 , +8963 , +25481 , +24165 , +-27609 , +5507 , +8389 , +22881 , +18795 , +-15187 , +22175 , +-17755 , +-22917 , +30183 , +4409 , +-4627 , +-22619 , +13369 , +-13739 , +12557 , +12599 , +14791 , +-12491 , +31127 , +-20839 , +12227 , +3819 , +-737 , +21987 , +31983 , +-5829 , +-11281 , +-6155 , +23181 , +5609 , +-20929 , +17681 , +-6181 , +15509 , +5101 , +-21009 , +-3067 , +21785 , +9915 , +2393 , +-18777 , +26711 , +24311 , +1601 , +11965 , +-13929 , +15047 , +29275 , +24605 , +24669 , +22485 , +-25295 , +10097 , +6847 , +-4219 , +8129 , +-9043 , +8261 , +11703 , +-8051 , +31751 , +-8903 , +23031 , +-21445 , +-29331 , +32383 , +19257 , +15017 , +-32121 , +-2573 , +7693 , +-1917 , +-15585 , +7995 , +-23205 , +28001 , +8231 , +7459 , +-29285 , +-27047 , +-6871 , +-30861 , +-21879 , +3353 , +16449 , +-32439 , +26463 , +21381 , +14491 , +20461 , +-11885 , +7105 , +-5283 , +-30165 , +13825 , +-6953 , +18221 , +30769 , +-14157 , +-15413 , +-479 , +-17447 , +20237 , +-20181 , +-6595 , +-9839 , +17547 , +13107 , +-32667 , +-18007 , +29175 , +-17313 , +-8745 , +-17877 , +28451 , +-27007 , +-25565 , +26937 , +1823 , +-19875 , +12199 , +32738 , +-2319 , +13247 , +13441 , +13681 , +-309 , +4629 , +-505 , +-31909 , +-16949 , +-23165 , +7367 , +29055 , +20521 , +30849 , +4853 , +781 , +10227 , +13801 , +-4247 , +-9255 , +6219 , +2975 , +1817 , +13875 , +2837 , +22935 , +-31481 , +16703 , +22835 , +1403 , +2243 , +32719 , +15681 , +19129 , +2913 , +16313 , +22727 , +24355 , +17133 , +-15955 , +-15375 , +-15357 , +-17307 , +10643 , +-24623 , +-25677 , +-7117 , +-12451 , +-23801 , +-9293 , +13605 , +2147 , +-26359 , +-19639 , +-14881 , +315 , +19405 , +-371 , +27869 , +-16371 , +-12275 , +7693 , +-19745 , +-6293 , +-21515 , +2783 , +19441 , +20913 , +-12191 , +-205 , +20175 , +7383 , +-9065 , +-29829 , +-7443 , +16067 , +-23435 , +28657 , +-25367 , +14897 , +28983 , +4799 , +16771 , +3065 , +-2913 , +-5493 , +10009 , +-5901 , +26301 , +-19055 , +-4717 , +-7089 , +-14821 , +-10939 , +-15125 , +5731 , +-19845 , +-22945 , +-1507 , +23565 , +-9715 , +11635 , +667 , +18057 , +28971 , +-4071 , +-16819 , +21443 , +-21369 , +21103 , +10247 , +1847 , +-18961 , +20799 , +11385 , +-1209 , +4989 , +-3947 , +-8267 , +-31989 , +-1711 , +14037 , +-14053 , +-2889 , +32205 , +3155 , +32215 , +13415 , +10307 , +-10391 , +16855 , +-26757 , +-11717 , +11541 , +-6333 , +-18317 , +21277 , +28175 , +-23431 , +21313 , +-4489 , +-22439 , +6267 , +-15837 , +-861 , +-27295 , +13813 , +13055 , +-14827 , +3227 , +19621 , +11571 , +2301 , +-15735 , +-5787 , +32758 , +8595 , +-21403 , +-15213 , +12583 , +19647 , +-8145 , +30479 , +-31573 , +-679 , +18761 , +11705 , +-19387 , +-17441 , +2443 , +4957 , +28653 , +-30543 , +-8481 , +-22215 , +-16733 , +14529 , +25943 , +-14875 , +22483 , +-15147 , +-29241 , +29401 , +3357 , +817 , +8411 , +24673 , +23739 , +-15393 , +-22867 , +10253 , +-15277 , +-14499 , +-29983 , +5557 , +-5043 , +-30761 , +-10947 , +-20759 , +17327 , +19679 , +20159 , +-20243 , +9335 , +-32343 , +27443 , +-17107 , +6247 , +-14917 , +-12463 , +27707 , +22127 , +-20435 , +-13489 , +-191 , +4213 , +-17063 , +-24069 , +26621 , +-22091 , +24351 , +-2983 , +-8393 , +28059 , +-22643 , +10669 , +-15945 , +-8431 , +-31195 , +11299 , +-5179 , +14435 , +3981 , +20953 , +19221 , +13199 , +-14387 , +-13693 , +-8375 , +-19681 , +26367 , +27005 , +-7961 , +25479 , +4237 , +9311 , +18125 , +-4883 , +29929 , +7709 , +25133 , +-12905 , +-10813 , +-26981 , +-14079 , +29871 , +25791 , +-26939 , +18185 , +-19033 , +-2891 , +-20183 , +3387 , +11277 , +30043 , +-20725 , +-10299 , +-22555 , +12687 , +-32255 , +17021 , +14973 , +18429 , +21003 , +985 , +-1081 , +22119 , +39 , +18029 , +8247 , +-12463 , +-2709 , +-10019 , +30477 , +-3523 , +-26975 , +27739 , +-5825 , +-8603 , +13399 , +-26217 , +4287 , +-18445 , +-12417 , +-7105 , +-32673 , +22455 , +-30077 , +29937 , +-11223 , +32091 , +7901 , +-15945 , +8749 , +-985 , +12077 , +-8961 , +-7197 , +-9687 , +-12839 , +-23793 , +-4097 , +-9731 , +4123 , +32255 , +-25397 , +26363 , +1437 , +-1997 , +-23813 , +23533 , +-4971 , +-10925 , +-9975 , +-25515 , +-1447 , +-5699 , +24331 , +-2031 , +-28555 , +26757 , +21259 , +20901 , +13893 , +-8213 , +-23071 , +32489 , +12051 , +-25523 , +10377 , +-9147 , +1189 , +-22107 , +27129 , +2657 , +-8617 , +11139 , +32127 , +-12691 , +-835 , +17277 , +16787 , +-29495 , +12719 , +15917 , +16181 , +22085 , +-21277 , +16039 , +-17985 , +-37 , +-2805 , +8309 , +1851 , +15581 , +25963 , +-14331 , +-14007 , +13241 , +2027 , +-26193 , +7783 , +-31449 , +9145 , +20255 , +25553 , +15851 , +22613 , +-7335 , +-24615 , +-21757 , +-25293 , +-13019 , +11449 , +-30617 , +-557 , +16403 , +-17419 , +-32201 , +27213 , +-21523 , +18985 , +-32637 , +29817 , +12973 , +7019 , +-19087 , +20861 , +19703 , +22551 , +-6655 , +-2073 , +21783 , +25137 , +-6845 , +-19897 , +12397 , +31547 , +-17907 , +-447 , +-12433 , +-11639 , +26415 , +4143 , +-17379 , +-27623 , +-12745 , +-11471 , +28409 , +4085 , +-23399 , +-16951 , +-23937 , +-28163 , +-3207 , +21231 , +23839 , +583 , +6609 , +-22611 , +-5711 , +-6665 , +-14027 , +-15049 , +30325 , +-10091 , +-2807 , +16253 , +-28033 , +5605 , +11317 , +-10165 , +16823 , +11325 , +21855 , +-31009 , +-8363 , +28519 , +17833 , +-17413 , +-31029 , +17383 , +10717 , +14983 , +15179 , +-9495 , +14893 , +23707 , +-31303 , +30339 , +-20371 , +7467 , +-16093 , +-12643 , +30915 , +-16887 , +-12873 , +-20925 , +-27419 , +25229 , +25155 , +24959 , +-22061 , +30373 , +-19423 , +2985 , +-20475 , +14965 , +-21061 , +32335 , +15919 , +19041 , +27515 , +-22403 , +26225 , +31669 , +14147 , +13979 , +-25071 , +-6737 , +-17809 , +31435 , +-22601 , +28453 , +-25027 , +13749 , +-2021 , +-18291 , +21201 , +22507 , +-29365 , +-17755 , +13483 , +21431 , +-20393 , +-3713 , +-14179 , +6013 , +-26225 , +27679 , +17987 , +18565 , +28471 , +-26479 , +10489 , +-10651 , +-26939 , +9347 , +-167 , +32455 , +-12141 , +-13733 , +12589 , +22995 , +5661 , +25291 , +-3091 , +1779 , +-19793 , +4853 , +9647 , +-28099 , +-29013 , +-4361 , +18087 , +-21951 , +9523 , +-5881 , +18715 , +15973 , +7277 , +25871 , +28633 , +7607 , +-1999 , +18621 , +-3277 , +-20915 , +-8375 , +-8155 , +-23431 , +21787 , +-5339 , +28365 , +18405 , +-22969 , +-1521 , +-15025 , +-8923 , +-2555 , +31725 , +-19599 , +-29117 , +25065 , +12657 , +-20815 , +32039 , +-5429 , +21973 , +-31377 , +10123 , +-18669 , +11023 , +30323 , +-26257 , +5523 , +24719 , +-31467 , +9757 , +22761 , +19567 , +25029 , +-8301 , +9031 , +28467 , +-16587 , +-31609 , +15067 , +14845 , +27617 , +7381 , +32411 , +-28859 , +2095 , +-899 , +5025 , +-2543 , +-20217 , +25883 , +25349 , +-2131 , +30437 , +32219 , +55 , +-24601 , +-1667 , +-9739 , +4045 , +-26689 , +-57 , +17827 , +18151 , +-11611 , +25753 , +4507 , +6907 , +17969 , +12229 , +-27389 , +14909 , +-23463 , +13231 , +7661 , +-7069 , +-28631 , +1889 , +2125 , +15377 , +17657 , +-19165 , +13169 , +10399 , +10285 , +-2661 , +-29187 , +-8063 , +15715 , +20317 , +-4005 , +-19437 , +-2767 , +-3325 , +-585 , +12533 , +20061 , +-21555 , +17277 , +13801 , +-15985 , +-17235 , +20295 , +3869 , +-4205 , +491 , +-3237 , +13073 , +-30201 , +12085 , +29089 , +-18453 , +28315 , +-32199 , +-15075 , +6475 , +27843 , +-15935 , +-15903 , +26275 , +-21003 , +-7871 , +17295 , +29205 , +14423 , +8443 , +8777 , +6087 , +-31741 , +657 , +9771 , +13757 , +-25927 , +-5605 , +-20153 , +27691 , +-17897 , +-15419 , +22547 , +15955 , +-4017 , +-31267 , +8301 , +-21535 , +-21659 , +-6279 , +-24821 , +-9547 , +-19743 , +9093 , +-21641 , +-5815 , +-31735 , +8283 , +-7549 , +-32381 , +-30561 , +-11297 , +-20663 , +17419 , +8203 , +15383 , +4759 , +-23511 , +-3293 , +-15295 , +-7953 , +19477 , +-30119 , +28265 , +-20735 , +-24103 , +-24973 , +-26233 , +9373 , +-31585 , +7111 , +-17389 , +-4563 , +-9585 , +20467 , +-5353 , +1197 , +1831 , +14867 , +-31271 , +-31703 , +-7667 , +30073 , +-8739 , +-14171 , +18033 , +-18715 , +13199 , +2475 , +-11555 , +21565 , +-8369 , +11313 , +-3697 , +-12601 , +-243 , +791 , +-16045 , +-10271 , +-32667 , +-18909 , +-2343 , +-14287 , +-8397 , +-30863 , +20105 , +365 , +28843 , +-20617 , +-22807 , +12931 , +-27923 , +-30869 , +23395 , +-2475 , +-26329 , +-17839 , +-2135 , +-15107 , +-13273 , +-19363 , +-9333 , +-20621 , +22385 , +2301 , +-6327 , +-8749 , +31453 , +1861 , +-14223 , +18441 , +-10073 , +13551 , +-197 , +-24299 , +14351 , +-6197 , +13397 , +-4931 , +-27541 , +-19007 , +-2237 , +-18491 , +-12091 , +-3265 , +32053 , +27301 , +-6165 , +-1991 , +30819 , +-20793 , +-3823 , +25497 , +-24609 , +24121 , +-12067 , +5441 , +-17 , +-2583 , +-4341 , +5755 , +-21787 , +603 , +-14213 , +10479 , +-7559 , +32481 , +-18989 , +13351 , +20895 , +-24747 , +-16755 , +18813 , +28385 , +-947 , +-12141 , +30355 , +-24779 , +-26153 , +13403 , +7759 , +12625 , +-16207 , +-27269 , +4179 , +-13939 , +8703 , +30655 , +5873 , +22067 , +15741 , +28869 , +13223 , +9307 , +-32183 , +-493 , +16917 , +11585 , +8711 , +20399 , +14713 , +13339 , +3747 , +-8389 , +-15205 , +-13193 , +6793 , +11141 , +26709 , +-7921 , +-19619 , +28839 , +-3965 , +-11489 , +12077 , +-19305 , +23415 , +-13759 , +9265 , +73 , +-1031 , +19653 , +-15617 , +7485 , +2491 , +-18299 , +-21695 , +-20579 , +22611 , +-19391 , +13043 , +1239 , +27821 , +12663 , +-26601 , +28331 , +-22263 , +5811 , +5355 , +-32051 , +-14473 , +10869 , +20133 , +5885 , +23235 , +22143 , +5801 , +20883 , +-29193 , +-9297 , +-2493 , +-22871 , +-9653 , +-29097 , +31965 , +6561 , +-5209 , +-19691 , +-14155 , +-25781 , +27541 , +-27603 , +16923 , +-9099 , +-5453 , +26465 , +291 , +27913 , +-24389 , +-25531 , +-10783 , +32667 , +15081 , +11033 , +27423 , +10637 , +28931 , +-989 , +31637 , +30625 , +-26431 , +-123 , +-28253 , +12049 , +-4137 , +3477 , +18823 , +-27869 , +-11173 , +10167 , +-29167 , +1867 , +-23603 , +12723 , +-14359 , +-6721 , +30847 , +-17523 , +30515 , +25221 , +32157 , +-3107 , +12251 , +-11491 , +4507 , +23207 , +28731 , +12939 , +28463 , +19639 , +19043 , +14833 , +5321 , +-143 , +22467 , +-6737 , +-23923 , +1329 , +-4243 , +-16655 , +26311 , +-3553 , +5833 , +-15921 , +20713 , +14723 , +9425 , +14303 , +-32003 , +-9303 , +-28739 , +24401 , +14753 , +-981 , +-8887 , +13957 , +17021 , +-1837 , +11627 , +17441 , +-18119 , +6383 , +22401 , +-19535 , +17147 , +27943 , +4623 , +-24907 , +-32677 , +-2083 , +7425 , +-9667 , +-4645 , +-18951 , +-6579 , +8455 , +-5411 , +-24499 , +-24255 , +-3573 , +7969 , +15717 , +18475 , +-1123 , +-2377 , +-9249 , +-32611 , +27393 , +27773 , +3401 , +-9699 , +-1915 , +-9455 , +31095 , +24415 , +2067 , +3145 , +-23979 , +-3587 , +-18863 , +16179 , +-20411 , +26801 , +10807 , +23685 , +-8455 , +-6133 , +801 , +4501 , +-23871 , +28073 , +15215 , +2519 , +7791 , +1521 , +22423 , +-305 , +425 , +-23483 , +14787 , +-10609 , +26557 , +5569 , +29155 , +-30553 , +-12541 , +1645 , +25157 , +419 , +-16213 , +-28425 , +4277 , +-17145 , +16669 , +20717 , +-1011 , +19895 , +-24371 , +28531 , +-12721 , +-29437 , +-14961 , +-23943 , +17211 , +-22511 , +-31621 , +-27011 , +7025 , +-15401 , +9273 , +-17741 , +29689 , +28575 , +-24611 , +-6199 , +23147 , +-25111 , +-15809 , +-9955 , +-2695 , +23545 , +-20007 , +-3983 , +6673 , +-61 , +1299 , +15397 , +-23311 , +1121 , +-2269 , +14325 , +28863 , +19735 , +-10903 , +16419 , +16545 , +1725 , +15673 , +12095 , +30553 , +-8253 , +16959 , +7765 , +-3371 , +-12643 , +5465 , +-16477 , +-7089 , +7881 , +17375 , +19421 , +-803 , +-965 , +10127 , +31193 , +-14701 , +13655 , +-24873 , +30923 , +-32239 , +27507 , +-23121 , +25859 , +24739 , +27073 , +-6405 , +12055 , +29393 , +-9521 , +-8619 , +28073 , +9089 , +5247 , +-23955 , +4507 , +-26745 , +12925 , +-4129 , +29887 , +-13891 , +14135 , +-29551 , +-17635 , +-17501 , +27479 , +-25731 , +-353 , +-28051 , +-19529 , +-1769 , +15695 , +-1889 , +5595 , +14367 , +-32247 , +-25559 , +8943 , +22263 , +16321 , +8441 , +-32461 , +-14975 , +22313 , +24601 , +19453 , +-11409 , +-16651 , +19261 , +-32211 , +7971 , +18063 , +19689 , +15139 , +7429 , +27471 , +31995 , +-9665 , +20307 , +-18379 , +-32307 , +-1841 , +18055 , +-22499 , +30153 , +16013 , +547 , +-32131 , +-22141 , +-8045 , +-13809 , +10901 , +-26037 , +-293 , +6253 , +22831 , +-2737 , +-26579 , +-21513 , +14549 , +-215 , +19611 , +23251 , +-9087 , +14333 , +-22915 , +-16917 , +-30495 , +-27629 , +8675 , +19651 , +18441 , +8421 , +-21871 , +469 , +-16471 , +28353 , +-14219 , +8043 , +-15927 , +-26913 , +12957 , +11503 , +-28671 , +13813 , +183 , +-15159 , +18733 , +13139 , +13053 , +19127 , +31145 , +-21383 , +-14151 , +8863 , +17925 , +-8915 , +7477 , +32756 , +10307 , +23579 , +-15565 , +25977 , +-18549 , +-31773 , +-26899 , +-4687 , +29281 , +24759 , +16005 , +29607 , +865 , +-1425 , +-12035 , +-19381 , +-1929 , +21289 , +-9289 , +-32697 , +25745 , +-3497 , +32353 , +5723 , +25569 , +21599 , +-10889 , +-16839 , +-1395 , +5801 , +27449 , +-17459 , +17895 , +14405 , +-6369 , +13095 , +30765 , +18169 , +-19501 , +5323 , +-26953 , +-12071 , +-11347 , +-21881 , +29363 , +-3485 , +-25693 , +-9009 , +-11165 , +22807 , +-29495 , +-14189 , +20683 , +-28021 , +1093 , +-17001 , +-15889 , +9 , +-1595 , +15693 , +-9851 , +18081 , +-31621 , +4649 , +-14789 , +-27711 , +24213 , +6015 , +25437 , +-29099 , +7987 , +-13869 , +-5353 , +19543 , +25309 , +14269 , +-23759 , +9449 , +-25985 , +27439 , +31803 , +-18707 , +-18207 , +-7327 , +6989 , +-995 , +30363 , +14105 , +17985 , +-16215 , +25745 , +30605 , +10851 , +22339 , +-31509 , +27575 , +30127 , +-7747 , +-23927 , +15405 , +-17781 , +1577 , +7931 , +-22661 , +5621 , +26723 , +28419 , +22261 , +-28599 , +-16333 , +-641 , +27673 , +12393 , +-7205 , +-21269 , +-8611 , +14725 , +-24769 , +-20653 , +-15985 , +-29881 , +-20625 , +-4913 , +3241 , +-25455 , +-17729 , +-20359 , +-1753 , +2229 , +-25237 , +-11289 , +-27931 , +10023 , +-7515 , +8477 , +-28561 , +-23103 , +-15827 , +8977 , +3041 , +-25237 , +31343 , +7317 , +13371 , +6497 , +24339 , +24025 , +-28869 , +-30493 , +29729 , +-20389 , +-7251 , +4977 , +-4727 , +4459 , +25683 , +18307 , +27463 , +29459 , +13099 , +7099 , +18939 , +-17505 , +-10923 , +-17757 , +-8201 , +-17525 , +-20639 , +4329 , +-283 , +20983 , +8755 , +-27129 , +-28209 , +30641 , +24649 , +18321 , +-20539 , +26779 , +-27737 , +20185 , +-1295 , +-23641 , +27681 , +18737 , +-23513 , +-1705 , +-20937 , +-21849 , +-5365 , +24749 , +-9617 , +13105 , +29339 , +-13659 , +-31445 , +-4497 , +16977 , +-21457 , +30467 , +-18979 , +-13385 , +30373 , +11671 , +-21105 , +-13183 , +-18749 , +-11023 , +-19607 , +25887 , +4639 , +20821 , +14547 , +15327 , +-9437 , +29083 , +32501 , +1147 , +29571 , +-7671 , +-21139 , +17465 , +13619 , +-2137 , +-17529 , +-21893 , +6631 , +-5093 , +-23561 , +-10783 , +-9985 , +-24063 , +-9459 , +-8743 , +-19445 , +-30271 , +32625 , +30903 , +-22085 , +-16669 , +15707 , +5715 , +18265 , +-2573 , +23623 , +-14563 , +-12095 , +21195 , +-4305 , +18357 , +-2339 , +-16523 , +-24761 , +2307 , +-11113 , +-9345 , +2351 , +-29491 , +27219 , +7123 , +9391 , +-4391 , +20457 , +13071 , +-20757 , +-3465 , +-10983 , +23133 , +3869 , +27809 , +18567 , +-27953 , +-21035 , +25233 , +-25291 , +30513 , +13983 , +-19237 , +9841 , +-18847 , +-17331 , +-20733 , +-23975 , +-12753 , +14243 , +21399 , +19145 , +7851 , +22679 , +-17215 , +9435 , +-4605 , +8709 , +26985 , +18139 , +29913 , +18405 , +-12607 , +19645 , +-29921 , +-14331 , +1645 , +-19685 , +3429 , +-19129 , +-3833 , +20645 , +-27969 , +-21169 , +-23225 , +-23005 , +-29939 , +-3905 , +-31849 , +15587 , +24035 , +-27149 , +-14809 , +-13383 , +-24105 , +-12751 , +-6779 , +23151 , +1115 , +-19095 , +-22081 , +7111 , +-1517 , +-23445 , +16363 , +13801 , +-12363 , +32151 , +11339 , +12643 , +13141 , +-5085 , +28901 , +18073 , +-12723 , +3525 , +-16237 , +16837 , +1919 , +32501 , +5793 , +13677 , +-31163 , +16803 , +-29983 , +-19627 , +-29257 , +30315 , +-17845 , +-15361 , +-14197 , +24653 , +-25589 , +21661 , +-25237 , +-21779 , +6943 , +21389 , +-23603 , +27459 , +19565 , +13135 , +20817 , +-11561 , +-26275 , +3071 , +30603 , +3441 , +-18707 , +4939 , +-21911 , +16737 , +-16049 , +-23833 , +9987 , +10791 , +21495 , +-31345 , +21241 , +17845 , +-2493 , +-15749 , +27715 , +3103 , +-19329 , +-24755 , +-32369 , +10717 , +15761 , +4249 , +19227 , +13435 , +23811 , +20691 , +-1019 , +-11821 , +10655 , +-10805 , +-23511 , +-13883 , +-16249 , +23713 , +14967 , +-1423 , +-6959 , +17473 , +-6195 , +-22803 , +23449 , +-4519 , +-21941 , +6271 , +23705 , +24273 , +-5837 , +2641 , +-4277 , +-11835 , +4403 , +-10325 , +-29583 , +32764 , +-11955 , +-6995 , +-9155 , +18909 , +4131 , +14727 , +-5927 , +-32535 , +12759 , +-14289 , +-25199 , +-30791 , +-14757 , +21655 , +-5543 , +-32663 , +14419 , +30567 , +25589 , +-15969 , +-27551 , +-19653 , +-18301 , +18931 , +267 , +5199 , +-12131 , +-5639 , +-251 , +21187 , +-2833 , +23719 , +2579 , +-4279 , +-12217 , +1627 , +-19875 , +16997 , +-22979 , +-28085 , +-14779 , +-2529 , +-27079 , +9859 , +-23353 , +-7617 , +17175 , +26195 , +20549 , +-15613 , +-18629 , +-1199 , +23017 , +-15785 , +-8915 , +-9007 , +15739 , +19341 , +25767 , +3541 , +17845 , +8601 , +27705 , +2441 , +-28387 , +12225 , +-14505 , +-27073 , +20319 , +3291 , +14585 , +14049 , +-12509 , +-22265 , +31407 , +-3347 , +29799 , +7645 , +26681 , +-21269 , +12115 , +6449 , +10143 , +-16541 , +-29805 , +-9661 , +-23095 , +6235 , +-4043 , +14715 , +16279 , +-29877 , +10227 , +-19813 , +-4225 , +-28269 , +-13797 , +-5757 , +-10343 , +12665 , +-25635 , +-24229 , +-32705 , +17307 , +-32221 , +-25003 , +-23771 , +-12565 , +7151 , +27105 , +-9487 , +-19677 , +-25299 , +29027 , +3915 , +22977 , +527 , +30577 , +-2683 , +-23167 , +13029 , +-12411 , +32159 , +-10165 , +12399 , +23611 , +-31757 , +-22603 , +-8003 , +-14337 , +-24771 , +14329 , +-27517 , +-4013 , +25407 , +13673 , +-8975 , +-1159 , +-4149 , +-15255 , +-13813 , +4279 , +9325 , +32746 , +10627 , +11015 , +20597 , +15965 , +-8691 , +-433 , +-18541 , +-10959 , +-6339 , +26399 , +-15633 , +-27965 , +12761 , +23781 , +14021 , +-22817 , +-14157 , +-8539 , +17527 , +12717 , +32261 , +-11725 , +-11993 , +12601 , +-23231 , +19941 , +-14129 , +1369 , +-2705 , +17619 , +-10785 , +-15823 , +11269 , +3469 , +21833 , +2343 , +-30657 , +-17587 , +-8415 , +-24483 , +-18705 , +-15945 , +15285 , +-32601 , +18145 , +-9459 , +7459 , +-28161 , +15791 , +-22297 , +30065 , +-12663 , +-6895 , +1899 , +-16089 , +1021 , +26815 , +-29945 , +7779 , +-5205 , +23753 , +8355 , +-30601 , +-12057 , +-15259 , +18533 , +4087 , +32271 , +-20143 , +-7459 , +26465 , +-22539 , +5033 , +2239 , +-25565 , +-28701 , +-11719 , +-6877 , +21567 , +5127 , +-15523 , +2611 , +26721 , +-6535 , +-25003 , +14445 , +12913 , +8869 , +32031 , +4175 , +26807 , +-1715 , +1737 , +-22887 , +-8861 , +-21763 , +-9649 , +29441 , +-1359 , +-30459 , +20981 , +-28309 , +21377 , +13545 , +14105 , +-12891 , +8295 , +-10647 , +32397 , +29077 , +327 , +32744 , +-23183 , +19963 , +-9359 , +31087 , +-14715 , +-2649 , +11317 , +-21983 , +13 , +-23763 , +-22535 , +-10189 , +16925 , +-16093 , +32211 , +-2205 , +7541 , +-29489 , +6055 , +15863 , +-21795 , +-13459 , +-20813 , +14377 , +8947 , +2521 , +-29519 , +-28119 , +16015 , +24275 , +20845 , +-12145 , +-2153 , +10157 , +5335 , +-20645 , +-15793 , +-18551 , +-16991 , +24417 , +-10435 , +28947 , +25689 , +23113 , +-23175 , +17073 , +6905 , +1289 , +1417 , +-703 , +-3833 , +-10025 , +17589 , +32077 , +-29657 , +19109 , +-24347 , +7883 , +11573 , +10515 , +19697 , +29517 , +31199 , +-22289 , +-27263 , +-19783 , +-7489 , +-10197 , +15971 , +-8571 , +-537 , +-20653 , +-20387 , +3951 , +-20983 , +31105 , +3979 , +-6733 , +28165 , +-13601 , +-11719 , +-27709 , +-26365 , +-17003 , +-4047 , +31615 , +1803 , +-21173 , +17053 , +-10771 , +-10721 , +10517 , +11359 , +23925 , +-18481 , +21495 , +8929 , +29327 , +-25767 , +27603 , +12145 , +-19703 , +3127 , +-20759 , +285 , +31667 , +7481 , +22475 , +-22781 , +19611 , +14373 , +-6189 , +-29901 , +-30775 , +-22071 , +30753 , +-14851 , +-32143 , +17039 , +18701 , +25039 , +24749 , +-7265 , +18465 , +-22643 , +-19527 , +20589 , +-15211 , +2917 , +21153 , +7383 , +2623 , +-11735 , +25989 , +4029 , +6931 , +1837 , +6989 , +-11753 , +16151 , +-9583 , +471 , +17035 , +-23847 , +43 , +30915 , +17803 , +-17301 , +9933 , +13973 , +27111 , +-20773 , +8233 , +22653 , +14823 , +25639 , +-11991 , +-2935 , +-28441 , +-27205 , +-32069 , +-22947 , +-12951 , +31585 , +-21701 , +3691 , +14255 , +22721 , +-14275 , +-17491 , +29909 , +-24237 , +24807 , +30681 , +24167 , +-5411 , +-14129 , +28189 , +5751 , +26209 , +-17587 , +9303 , +-20419 , +6053 , +26459 , +-16695 , +17703 , +-31977 , +993 , +-31147 , +-12689 , +2649 , +-31593 , +10547 , +-25795 , +-20695 , +-30887 , +-20951 , +-17607 , +29923 , +4605 , +-28093 , +13729 , +6259 , +14513 , +2319 , +25831 , +22225 , +17613 , +-10421 , +20159 , +31223 , +29745 , +-16341 , +20679 , +25689 , +-5867 , +-761 , +-1651 , +-11551 , +-7575 , +-18545 , +26163 , +3423 , +-11097 , +-363 , +-891 , +-17017 , +31535 , +11567 , +-9843 , +9319 , +31261 , +15489 , +-13139 , +26211 , +-22367 , +-2071 , +14139 , +9635 , +-25639 , +-29763 , +-22381 , +8985 , +-30169 , +26241 , +-29007 , +7659 , +7943 , +-7007 , +-11447 , +-22155 , +22383 , +-16729 , +-17051 , +12733 , +-357 , +-19983 , +-4241 , +-6551 , +-7313 , +23535 , +-9767 , +-15295 , +24141 , +-16427 , +31273 , +29973 , +16233 , +28375 , +-16747 , +15943 , +-16991 , +-13601 , +26145 , +-19015 , +32223 , +23495 , +-19157 , +30023 , +19171 , +-20725 , +-10609 , +-31551 , +-27229 , +-17911 , +16691 , +-19871 , +22051 , +14007 , +-1491 , +-28221 , +25803 , +-3371 , +2895 , +22877 , +-7107 , +-30289 , +1603 , +22137 , +-11339 , +-32693 , +-5083 , +12201 , +25045 , +15397 , +20891 , +-21051 , +6153 , +-13203 , +5991 , +17247 , +30293 , +-589 , +-28789 , +2743 , +6069 , +-20439 , +26319 , +29245 , +-2321 , +-6055 , +10991 , +20353 , +-5137 , +-28073 , +-15075 , +-28499 , +-1633 , +28545 , +-16085 , +17533 , +-31689 , +9907 , +-18151 , +12475 , +2085 , +-4355 , +-17105 , +-20687 , +26965 , +-13085 , +4245 , +2339 , +29455 , +-9719 , +4717 , +2375 , +-24491 , +-28811 , +-21655 , +-959 , +-15185 , +-30141 , +6115 , +-10347 , +-21105 , +-15649 , +26229 , +-16609 , +21535 , +-20807 , +-31981 , +-24299 , +-18527 , +17535 , +9891 , +8301 , +-1983 , +23257 , +-31985 , +-31255 , +-13709 , +22939 , +995 , +-4223 , +-9533 , +-19075 , +-1177 , +30305 , +14899 , +11871 , +-27601 , +-31907 , +27411 , +18411 , +-8391 , +2543 , +9815 , +-2847 , +22149 , +-7769 , +29039 , +-4921 , +-21461 , +-2515 , +7329 , +-23519 , +15857 , +-31313 , +16859 , +24359 , +1385 , +9695 , +-9197 , +22273 , +23683 , +-14483 , +3869 , +27009 , +28327 , +28661 , +14335 , +19283 , +-20911 , +-7551 , +24011 , +-19269 , +10019 , +-4483 , +6907 , +-32565 , +1151 , +-25295 , +-26815 , +14109 , +9377 , +-2633 , +-22043 , +-2041 , +4149 , +-28817 , +-17249 , +17239 , +11887 , +-21757 , +-31003 , +-28277 , +-29277 , +2515 , +14801 , +14213 , +6239 , +15345 , +13417 , +-29499 , +-28925 , +-25445 , +-10103 , +-13273 , +7633 , +-19149 , +-26583 , +-22771 , +-6253 , +16047 , +-11455 , +809 , +23719 , +31139 , +-25055 , +-9567 , +-18785 , +5281 , +2111 , +-18727 , +28751 , +22853 , +-1127 , +-16989 , +4725 , +-10331 , +19595 , +-14091 , +11455 , +18503 , +4643 , +-32475 , +-11409 , +-9059 , +-8455 , +-3683 , +31089 , +-18947 , +-3441 , +-28647 , +32495 , +-17647 , +-1245 , +11867 , +19565 , +-31777 , +-32766 , +-12705 , +21085 , +-27599 , +-29589 , +-12001 , +-15043 , +-25451 , +-19743 , +30653 , +28199 , +-1581 , +255 , +12101 , +26613 , +10983 , +-1063 , +-24863 , +8395 , +30073 , +15565 , +-3953 , +30773 , +28877 , +-14623 , +19549 , +20933 , +-20665 , +-21355 , +-477 , +29729 , +15967 , +7739 , +15795 , +3231 , +13585 , +30933 , +4503 , +-20637 , +2273 , +28009 , +17479 , +11243 , +-7859 , +-10023 , +-7197 , +3635 , +-24127 , +25661 , +17513 , +9283 , +-7655 , +-31305 , +-919 , +-8117 , +-29293 , +-1587 , +-11189 , +-4285 , +24641 , +19781 , +8179 , +-9229 , +-1265 , +-28807 , +31499 , +5783 , +-14799 , +-15063 , +24499 , +14581 , +23069 , +13285 , +-28749 , +-8463 , +-22783 , +7629 , +-14271 , +-5209 , +-27963 , +1537 , +-18387 , +-27897 , +17779 , +5475 , +-20321 , +-27 , +-9155 , +-18429 , +2127 , +-4453 , +-17683 , +2791 , +-22215 , +5141 , +13281 , +12909 , +-16167 , +-22155 , +-16769 , +12571 , +2783 , +-3037 , +29749 , +22273 , +-20881 , +8807 , +3043 , +-7799 , +9677 , +21635 , +3041 , +-7215 , +10399 , +10825 , +27253 , +3973 , +4257 , +-21197 , +21695 , +30259 , +-20259 , +-4357 , +21567 , +-9431 , +5991 , +13495 , +-30011 , +-21049 , +12683 , +1639 , +15599 , +17497 , +-13681 , +-1253 , +25369 , +28529 , +-8981 , +-26241 , +30943 , +-579 , +-21001 , +9463 , +17161 , +18529 , +-21459 , +-20679 , +-15347 , +24523 , +-30757 , +18019 , +5893 , +-3827 , +32357 , +-26731 , +26915 , +31675 , +20457 , +-8697 , +-13909 , +-4041 , +-10351 , +30367 , +2157 , +20113 , +-16845 , +-4081 , +23229 , +24033 , +16279 , +-4249 , +-281 , +5145 , +31279 , +-16079 , +-27095 , +-14755 , +16711 , +-4347 , +27949 , +-17949 , +-5695 , +-20057 , +27393 , +11585 , +2387 , +-26727 , +-8567 , +29261 , +-24523 , +14391 , +-7551 , +12397 , +-23205 , +19277 , +-28693 , +26487 , +27959 , +-721 , +-18673 , +19205 , +-7451 , +-10415 , +22251 , +-29107 , +3047 , +5473 , +-29901 , +14457 , +-12707 , +-16675 , +10437 , +-26239 , +29123 , +23853 , +-16221 , +30593 , +-11749 , +-22987 , +16741 , +3215 , +-16971 , +-3211 , +-4293 , +-4839 , +30043 , +-8801 , +-5543 , +28345 , +-14577 , +-11095 , +-1027 , +-22645 , +-17597 , +3179 , +-7719 , +-25079 , +19597 , +-27207 , +-12265 , +-16029 , +8673 , +-1035 , +25029 , +16979 , +-15539 , +16167 , +-20517 , +25721 , +16683 , +-32101 , +-14683 , +24625 , +-14883 , +18419 , +12741 , +-4885 , +2559 , +-28987 , +-10585 , +3079 , +9003 , +-20307 , +-10887 , +11299 , +-23261 , +20967 , +-22363 , +15613 , +-29295 , +15977 , +15043 , +-13365 , +-3517 , +-29833 , +11037 , +-16375 , +-5677 , +-10813 , +-1897 , +-12069 , +-22795 , +-3079 , +19255 , +19171 , +15899 , +-2591 , +5137 , +16021 , +3511 , +-14351 , +-17469 , +-20719 , +16631 , +21357 , +6003 , +-9861 , +25841 , +29429 , +23611 , +11481 , +-30619 , +-27745 , +-14039 , +2657 , +-8721 , +23193 , +16315 , +-6573 , +22725 , +10035 , +-32055 , +-7847 , +15335 , +-13951 , +21517 , +29269 , +5087 , +17773 , +10253 , +14531 , +4853 , +-1453 , +-22367 , +-28793 , +18407 , +1817 , +-16933 , +-1977 , +-22751 , +17091 , +21901 , +-2225 , +24183 , +-24179 , +-24261 , +30677 , +27481 , +24199 , +657 , +20705 , +-5233 , +-15963 , +24163 , +671 , +8305 , +-9631 , +3607 , +17465 , +-25445 , +1735 , +10157 , +31273 , +-27609 , +-24807 , +21549 , +-21223 , +-14487 , +-25121 , +-4961 , +6453 , +35 , +-25471 , +-27253 , +-4597 , +-26313 , +-927 , +4325 , +22231 , +2287 , +-27535 , +32399 , +25443 , +-6747 , +-17589 , +-15537 , +-5791 , +23811 , +1483 , +20037 , +-2501 , +-27203 , +-28127 , +-2851 , +-5773 , +-3139 , +14197 , +7513 , +-12425 , +-18705 , +29169 , +-4175 , +5365 , +-5021 , +25441 , +-15069 , +10943 , +10775 , +-16307 , +-29161 , +12823 , +3363 , +393 , +26277 , +18825 , +-3467 , +-19883 , +4483 , +-28085 , +-7665 , +13037 , +-28283 , +-31217 , +9397 , +-14421 , +-26223 , +-19115 , +31785 , +19605 , +2835 , +-31151 , +30183 , +25981 , +15107 , +3129 , +-12203 , +-32109 , +13641 , +-28899 , +27269 , +-28287 , +-18747 , +-9147 , +-18847 , +-19713 , +5571 , +-2301 , +9585 , +-13071 , +-12051 , +16913 , +-30717 , +20729 , +-821 , +-18079 , +-10509 , +3987 , +18357 , +21629 , +24537 , +28587 , +-13233 , +10583 , +-13375 , +-7499 , +27265 , +26541 , +-1945 , +-4795 , +-8471 , +-15151 , +7153 , +-25557 , +20701 , +28689 , +11037 , +-16895 , +-28969 , +10115 , +-1529 , +-18095 , +-20101 , +-31391 , +3921 , +22303 , +23811 , +7653 , +-24087 , +23051 , +22843 , +-31335 , +-18115 , +14823 , +-18439 , +-10183 , +-6163 , +-9271 , +16923 , +-10237 , +-26357 , +-24919 , +25333 , +15759 , +26573 , +-27525 , +19021 , +20523 , +31175 , +16321 , +31957 , +24245 , +21415 , +-21085 , +-29921 , +12523 , +8293 , +17549 , +10015 , +2375 , +-7417 , +8003 , +20497 , +20317 , +-30009 , +19575 , +-13051 , +31401 , +25053 , +-13593 , +-21051 , +21995 , +-12625 , +-26129 , +2653 , +13059 , +-8315 , +-18779 , +-18169 , +10053 , +-26419 , +23917 , +12969 , +-6069 , +32193 , +26649 , +24009 , +24925 , +19379 , +8309 , +30735 , +-26309 , +24505 , +24425 , +-10709 , +119 , +-16667 , +20619 , +-19873 , +-16301 , +14591 , +-19905 , +-16021 , +8727 , +-25149 , +-5563 , +-14831 , +-22815 , +31887 , +-14637 , +-9477 , +-6133 , +26271 , +17463 , +-21691 , +-10249 , +11207 , +12001 , +20841 , +31595 , +2475 , +-1531 , +5313 , +-19601 , +17779 , +-23891 , +-17035 , +12183 , +10247 , +-2217 , +-18697 , +8427 , +-11067 , +7171 , +-18175 , +-15053 , +-3399 , +-23845 , +12031 , +25303 , +-24491 , +4411 , +5655 , +-13009 , +-22099 , +10575 , +-30313 , +2405 , +31015 , +-12243 , +-18961 , +11203 , +-17733 , +-6033 , +27177 , +1425 , +10659 , +-1727 , +-31 , +-17555 , +-32611 , +-1531 , +-11839 , +-9187 , +1179 , +6755 , +-1933 , +4083 , +-24067 , +-8477 , +-31207 , +-1899 , +5195 , +27145 , +-1969 , +22883 , +4201 , +18915 , +6291 , +8265 , +-5807 , +-24019 , +841 , +26389 , +-22701 , +2785 , +-29389 , +1365 , +2491 , +-1195 , +-16545 , +-13655 , +27417 , +6603 , +-24151 , +-1635 , +-9 , +18319 , +2995 , +6915 , +26629 , +-15987 , +-19375 , +-15925 , +2527 , +11629 , +14223 , +22357 , +12609 , +-5341 , +19237 , +-30639 , +26551 , +-31985 , +-9877 , +27153 , +-29 , +-30579 , +15057 , +-3991 , +19239 , +-14057 , +17887 , +-13317 , +29161 , +8147 , +28067 , +18713 , +26179 , +-14925 , +-22865 , +18199 , +-5829 , +30215 , +19091 , +-8151 , +6785 , +16281 , +-20023 , +-9805 , +-30043 , +23105 , +-17345 , +29995 , +18375 , +-9981 , +65 , +-18071 , +-8997 , +-28509 , +-10253 , +-13187 , +-17573 , +2745 , +1359 , +30227 , +1919 , +-8877 , +9371 , +25151 , +16115 , +16133 , +-23205 , +15579 , +-19949 , +12163 , +-32305 , +15711 , +18339 , +3261 , +27885 , +15153 , +-31995 , +-5011 , +-20783 , +-7541 , +17649 , +-28099 , +26557 , +8649 , +16045 , +23121 , +29063 , +26433 , +-28729 , +-3991 , +-26719 , +-14431 , +-31159 , +11127 , +23939 , +-23357 , +-1675 , +-6735 , +2979 , +-4861 , +14075 , +10545 , +15097 , +-29923 , +-1357 , +-30457 , +-26901 , +7805 , +26835 , +-299 , +3531 , +-27617 , +-32089 , +9447 , +10189 , +-18461 , +3529 , +9415 , +-17279 , +22117 , +26073 , +12889 , +-16697 , +1879 , +12471 , +-5265 , +22345 , +14419 , +27961 , +29671 , +1401 , +-28611 , +-11165 , +-22979 , +-259 , +17171 , +1315 , +12455 , +-31309 , +28229 , +29311 , +-2389 , +27677 , +5527 , +-29609 , +-28873 , +-32667 , +-10137 , +6811 , +14137 , +5581 , +-2151 , +17153 , +4281 , +25773 , +-15391 , +12601 , +1645 , +-1823 , +3231 , +-9809 , +11225 , +-6451 , +-22727 , +-12611 , +-3619 , +-305 , +-22799 , +-24481 , +2001 , +-18637 , +23869 , +-16779 , +16669 , +1205 , +-17757 , +21873 , +22361 , +-9871 , +10247 , +7575 , +-7983 , +-32163 , +28815 , +-27473 , +21431 , +-25789 , +-11279 , +-26047 , +28065 , +-11977 , +-9897 , +-6583 , +-10313 , +11151 , +-1369 , +21111 , +24381 , +4955 , +-16281 , +28123 , +-25937 , +-11939 , +26131 , +21289 , +21341 , +-17787 , +-24845 , +14695 , +-29827 , +-15645 , +-27793 , +-18645 , +30917 , +-20703 , +-20749 , +12373 , +19331 , +-25475 , +22073 , +26173 , +6713 , +5949 , +7723 , +-23945 , +-13905 , +30637 , +-25801 , +29697 , +18831 , +-17007 , +24871 , +30471 , +-649 , +-24031 , +19319 , +7945 , +-21861 , +6269 , +-22985 , +-1113 , +-15915 , +-2901 , +20307 , +28617 , +24129 , +-3831 , +26743 , +21343 , +-12209 , +-13753 , +-20121 , +30621 , +3431 , +-22045 , +8907 , +-31323 , +-9229 , +-26853 , +-7783 , +12237 , +5121 , +9829 , +8925 , +11599 , +-13227 , +8047 , +6169 , +-1913 , +-13307 , +20877 , +31775 , +-14431 , +6289 , +20153 , +-10145 , +-18467 , +-1931 , +17669 , +6861 , +-23741 , +16971 , +-20843 , +-27607 , +-26413 , +20569 , +4121 , +-2329 , +28487 , +28849 , +32197 , +28285 , +27209 , +10693 , +7875 , +26427 , +27175 , +11129 , +26423 , +7851 , +-25073 , +17613 , +16549 , +-27557 , +12485 , +13791 , +-9989 , +-3257 , +-6179 , +-18797 , +20483 , +2977 , +11627 , +-30299 , +-1197 , +-2765 , +31821 , +-3007 , +30927 , +29233 , +-22837 , +29211 , +18333 , +10899 , +-4123 , +-503 , +8095 , +22515 , +28413 , +-14571 , +-16537 , +-1575 , +-18923 , +-21983 , +26803 , +10907 , +12933 , +18415 , +-15515 , +-21319 , +16435 , +4043 , +24309 , +18599 , +26443 , +5775 , +-30095 , +4915 , +-17285 , +4687 , +-17677 , +13397 , +-9309 , +21089 , +14483 , +18061 , +29971 , +3071 , +18917 , +-6479 , +-6845 , +-11431 , +-27151 , +-29611 , +-12535 , +-26317 , +-2901 , +17041 , +12367 , +1269 , +26083 , +22885 , +-5805 , +-31925 , +26315 , +-22645 , +11857 , +-7879 , +24035 , +29911 , +-9267 , +-13391 , +21879 , +-23291 , +9531 , +2993 , +-17259 , +15127 , +-27071 , +-10539 , +26247 , +-13015 , +-8601 , +3187 , +-32571 , +207 , +24409 , +-18639 , +-18567 , +-22551 , +-2667 , +-21731 , +16487 , +-27143 , +-3157 , +-26555 , +1141 , +-14847 , +-14353 , +27089 , +-24681 , +-5933 , +17589 , +18839 , +28491 , +-3085 , +775 , +8253 , +26519 , +-14109 , +-10273 , +-5699 , +-6541 , +-29431 , +-11303 , +-18795 , +15827 , +-13831 , +-14987 , +-20147 , +11279 , +-4521 , +-19005 , +151 , +-1311 , +18217 , +22443 , +-8729 , +31969 , +2487 , +-7789 , +-18297 , +-24197 , +-31275 , +18849 , +-17099 , +-10401 , +6347 , +23671 , +-26061 , +-2683 , +-1885 , +-22947 , +-10265 , +-7523 , +28673 , +-22775 , +-25107 , +-19701 , +-23937 , +18381 , +15541 , +30043 , +29063 , +3151 , +21397 , +25921 , +-26205 , +-2619 , +-5277 , +-17149 , +-24485 , +-28499 , +23949 , +-8831 , +-21875 , +9475 , +24501 , +1187 , +-11455 , +-32519 , +3011 , +19025 , +6915 , +22061 , +15489 , +7153 , +-30785 , +-24215 , +5805 , +-4517 , +-29419 , +5331 , +5787 , +24145 , +21805 , +-861 , +31301 , +30581 , +535 , +-27033 , +24551 , +22983 , +32673 , +21165 , +28947 , +-2663 , +-597 , +-1719 , +29261 , +5637 , +-21759 , +10237 , +-28895 , +29163 , +-14153 , +9149 , +-17733 , +-1183 , +-21001 , +29799 , +-765 , +9655 , +-11161 , +17141 , +1071 , +23005 , +-31499 , +-3533 , +-11559 , +20847 , +15669 , +-5631 , +-7515 , +-28641 , +25911 , +3333 , +-27833 , +-19533 , +28127 , +-12061 , +15913 , +-11657 , +-4161 , +28915 , +-14727 , +-24511 , +-7573 , +13183 , +-567 , +-28195 , +-31657 , +14709 , +-19167 , +-18677 , +2857 , +-12125 , +-11617 , +-32015 , +-19309 , +-16275 , +17281 , +15135 , +20399 , +-30459 , +8909 , +17659 , +-10547 , +3363 , +-5029 , +2493 , +12761 , +-25023 , +5241 , +-22295 , +-18135 , +-7347 , +-9221 , +12615 , +-28461 , +-28191 , +-18219 , +-26539 , +29839 , +29185 , +11063 , +10313 , +3081 , +-23475 , +22301 , +-25475 , +24501 , +-23871 , +14955 , +-23435 , +-31183 , +-3103 , +-10355 , +1355 , +8723 , +2169 , +11389 , +4521 , +-14261 , +15317 , +20079 , +-20405 , +-6417 , +28281 , +-32295 , +-22295 , +17565 , +13139 , +-22763 , +28601 , +-20401 , +1915 , +-11405 , +10079 , +-1611 , +-29595 , +28375 , +4465 , +-13813 , +15521 , +-21047 , +9569 , +30061 , +-27899 , +-16363 , +1533 , +23737 , +7283 , +-29729 , +3433 , +-2079 , +27661 , +19769 , +-22643 , +8383 , +27111 , +-3517 , +-19687 , +-18823 , +-3003 , +-29771 , +8439 , +12615 , +19283 , +-22009 , +-30143 , +16097 , +16219 , +-257 , +-2883 , +-187 , +-26245 , +7113 , +32209 , +-1517 , +-18719 , +-23657 , +9219 , +25713 , +-12667 , +-13647 , +26345 , +-12467 , +-9895 , +31243 , +-2659 , +-10675 , +-27383 , +-4249 , +9159 , +-6379 , +-26327 , +12773 , +23809 , +-18135 , +-2309 , +13089 , +20187 , +-29125 , +23451 , +-2877 , +335 , +-11501 , +11455 , +-30051 , +-27207 , +14549 , +-26649 , +20803 , +-7089 , +-8473 , +3103 , +12577 , +-20455 , +-23231 , +5675 , +17935 , +-22161 , +16199 , +5963 , +-15499 , +-2333 , +7973 , +-12691 , +27863 , +31943 , +-11871 , +11233 , +31475 , +-25823 , +-7565 , +26521 , +17749 , +-26087 , +-7899 , +-11811 , +-30603 , +32005 , +-24993 , +22149 , +-24503 , +29645 , +14797 , +10925 , +-28833 , +-23827 , +6249 , +-25359 , +10873 , +31215 , +23389 , +-32733 , +16545 , +20571 , +-4265 , +10369 , +6075 , +-32455 , +-13215 , +29557 , +5547 , +-17153 , +32313 , +-11837 , +-4637 , +-13813 , +-29397 , +-13241 , +11135 , +27559 , +-8347 , +-1235 , +28629 , +-22675 , +-21805 , +-6237 , +15773 , +8529 , +3961 , +-12261 , +-22407 , +-14833 , +-3519 , +-14597 , +-16107 , +31779 , +12379 , +9175 , +5567 , +4935 , +-15589 , +-16599 , +8059 , +10853 , +-5059 , +-3957 , +-3167 , +17429 , +725 , +-14485 , +4587 , +-15985 , +-1901 , +30285 , +-22755 , +-989 , +12203 , +26737 , +7179 , +13625 , +-18147 , +-1509 , +18751 , +-27457 , +-27745 , +19271 , +9991 , +-4569 , +739 , +9437 , +21013 , +-31777 , +-26757 , +26731 , +15507 , +-32441 , +-209 , +605 , +25529 , +25383 , +13779 , +-10565 , +25067 , +1707 , +11933 , +-24491 , +13645 , +-26917 , +-29183 , +14979 , +-27945 , +4241 , +-29687 , +19807 , +-25097 , +-27411 , +-26839 , +-11147 , +-9053 , +16985 , +-12389 , +30723 , +-16405 , +-13323 , +-3275 , +12459 , +-26335 , +-30831 , +-11839 , +11693 , +21343 , +10799 , +-7723 , +30117 , +-13905 , +-5393 , +3633 , +14773 , +4503 , +17543 , +21385 , +21325 , +-28109 , +3401 , +18155 , +-7081 , +16343 , +7565 , +7311 , +-28169 , +-11239 , +15529 , +18229 , +20923 , +23155 , +-29579 , +18421 , +16729 , +-5803 , +11063 , +-14689 , +-32533 , +-8253 , +17441 , +-30067 , +-30823 , +32613 , +17991 , +27647 , +-5409 , +15145 , +31255 , +-10769 , +4157 , +-28081 , +-21163 , +-3981 , +-16011 , +-12277 , +11659 , +2947 , +6969 , +-30821 , +-14075 , +25185 , +-12687 , +9435 , +3665 , +-12433 , +11239 , +26979 , +-32219 , +-30597 , +-3453 , +11795 , +1001 , +31655 , +22535 , +16703 , +6309 , +25781 , +17473 , +-18125 , +21627 , +13031 , +14021 , +-27815 , +-25949 , +-10417 , +-12505 , +-2107 , +27609 , +5041 , +28593 , +-1703 , +-1183 , +25041 , +-3429 , +10837 , +17015 , +-29873 , +-5693 , +-8843 , +-13747 , +2567 , +24811 , +27521 , +25721 , +-14121 , +-26015 , +21869 , +-30215 , +23815 , +-16821 , +-25879 , +-26461 , +20511 , +-2989 , +7553 , +-22751 , +-28109 , +-8227 , +26675 , +10087 , +-21299 , +-2359 , +-19583 , +4009 , +-12751 , +-21853 , +32273 , +-15909 , +17737 , +-9121 , +-28223 , +27037 , +-31249 , +-28019 , +-12995 , +2239 , +19913 , +27157 , +-30179 , +-5583 , +419 , +-18065 , +-2187 , +-19587 , +-9401 , +-8617 , +16633 , +-13119 , +-51 , +-20985 , +-9595 , +22307 , +5763 , +32758 , +-14267 , +27087 , +30773 , +-13571 , +15165 , +-12951 , +-28917 , +-13015 , +23155 , +-4599 , +32487 , +13789 , +-28555 , +15279 , +-20943 , +19093 , +13695 , +-20159 , +18233 , +32283 , +-4595 , +-17925 , +18957 , +-3519 , +-27151 , +11635 , +18125 , +-9193 , +4079 , +-26111 , +22663 , +17059 , +-11821 , +-27197 , +30857 , +4119 , +-31477 , +19987 , +-15803 , +-4719 , +-27717 , +3453 , +-16485 , +-7865 , +-1447 , +-4043 , +21947 , +10061 , +13765 , +32533 , +27257 , +15551 , +-23075 , +26893 , +-9691 , +-27261 , +15511 , +4901 , +-10779 , +-2949 , +-11875 , +14061 , +17029 , +-8637 , +-3491 , +18293 , +12257 , +7779 , +-31063 , +-11063 , +167 , +-10489 , +8651 , +-23061 , +23231 , +4929 , +22555 , +-16061 , +30747 , +21425 , +-3809 , +7071 , +-4075 , +3533 , +19989 , +9635 , +-28355 , +-27253 , +-8931 , +-4149 , +25537 , +27045 , +-3905 , +7385 , +27697 , +23111 , +-11247 , +23251 , +18155 , +-32179 , +29513 , +-25989 , +13281 , +-29955 , +28881 , +-17085 , +-21761 , +12853 , +-277 , +-3639 , +4351 , +-29903 , +21947 , +30415 , +-23367 , +-3661 , +7655 , +-851 , +15621 , +10187 , +-22607 , +23889 , +-4333 , +-27133 , +18055 , +-7499 , +13625 , +9757 , +-22239 , +-11313 , +-20907 , +-20407 , +-31207 , +-32744 , +3491 , +29409 , +29953 , +-32395 , +21263 , +-29545 , +19447 , +27831 , +-7145 , +-3783 , +-9781 , +-22379 , +-25321 , +-12063 , +21635 , +-23781 , +29485 , +-5713 , +21637 , +7595 , +-16757 , +-17403 , +-19419 , +-14481 , +-15027 , +6453 , +11197 , +-8615 , +-24877 , +1223 , +587 , +3729 , +1949 , +24611 , +-21883 , +18543 , +15773 , +22741 , +-23439 , +-15107 , +32019 , +4413 , +31613 , +-3873 , +13791 , +31689 , +14615 , +30171 , +-28313 , +-8021 , +9159 , +6851 , +24795 , +1563 , +8903 , +-19973 , +3101 , +29441 , +-25069 , +-12703 , +-26349 , +-15309 , +13071 , +30421 , +25471 , +-29643 , +5523 , +-28635 , +-25255 , +-19103 , +30089 , +13705 , +12195 , +-8533 , +-16125 , +-18529 , +5059 , +-21801 , +6869 , +31199 , +-17057 , +31279 , +-8789 , +26255 , +-21329 , +-31049 , +-31843 , +12613 , +-16039 , +-9489 , +-13739 , +8151 , +26053 , +6915 , +27539 , +-28203 , +11003 , +-26491 , +16981 , +-381 , +-4877 , +-22359 , +13421 , +-24243 , +6007 , +-19211 , +-18293 , +-29497 , +9071 , +-383 , +20715 , +23575 , +-6969 , +-29785 , +-11685 , +15101 , +-16197 , +14407 , +-12325 , +31807 , +25777 , +24687 , +689 , +30379 , +5529 , +7585 , +1799 , +-8063 , +12221 , +-29053 , +17665 , +24955 , +-4325 , +8477 , +24141 , +-27847 , +6207 , +22409 , +-1977 , +10307 , +-26217 , +-207 , +14987 , +29043 , +-17071 , +21127 , +-9717 , +-1541 , +939 , +-709 , +2219 , +29145 , +15829 , +31473 , +8537 , +-24885 , +319 , +-14209 , +26781 , +-29751 , +2935 , +-8287 , +-17981 , +-20739 , +-20863 , +-2771 , +30811 , +15933 , +-8789 , +-3625 , +-24985 , +27139 , +-3353 , +7515 , +16101 , +-18719 , +-15191 , +29759 , +21739 , +11643 , +9267 , +-24571 , +14147 , +-26365 , +23669 , +2535 , +-30597 , +-29655 , +-13977 , +15 , +-1147 , +25755 , +8155 , +25933 , +-15157 , +1271 , +32213 , +-7349 , +4039 , +32073 , +-9365 , +5969 , +20761 , +23035 , +-3053 , +-20115 , +-13017 , +-11949 , +16513 , +-453 , +11049 , +-30867 , +6399 , +-11501 , +27855 , +8365 , +-26559 , +21695 , +8777 , +23221 , +22209 , +-28479 , +13037 , +-7191 , +-26987 , +24823 , +4683 , +-22179 , +-2105 , +-28187 , +-17985 , +-11445 , +19759 , +-15517 , +16015 , +10263 , +-22071 , +-1065 , +23681 , +3515 , +16011 , +26095 , +-13065 , +-7743 , +8387 , +12501 , +-15745 , +-8251 , +-28437 , +2795 , +24817 , +20063 , +-9729 , +12033 , +-30201 , +10915 , +24921 , +31761 , +-10637 , +2587 , +-247 , +-28819 , +4981 , +27447 , +13993 , +22915 , +7415 , +11337 , +26809 , +9483 , +27685 , +24837 , +-27531 , +-30519 , +12931 , +15975 , +-15827 , +15291 , +22917 , +21821 , +-20961 , +17369 , +16037 , +-11497 , +-13363 , +30531 , +-31741 , +441 , +14803 , +-14327 , +-12943 , +-17117 , +-16825 , +21071 , +-15849 , +6137 , +25477 , +-23269 , +10883 , +-6527 , +-12911 , +15735 , +-31933 , +26657 , +-8211 , +-21445 , +-9217 , +-14515 , +-13331 , +24119 , +23313 , +-22523 , +8079 , +32505 , +15765 , +31947 , +-4899 , +-4619 , +-21489 , +-9701 , +-24137 , +-16817 , +15223 , +-32667 , +-22477 , +14593 , +29399 , +21635 , +26485 , +-9825 , +11617 , +-337 , +-17147 , +15757 , +12553 , +26627 , +-31065 , +32179 , +-11877 , +-12697 , +21683 , +-5449 , +-1967 , +-22771 , +-8979 , +-23621 , +26607 , +1901 , +17889 , +-119 , +-27301 , +-13127 , +-7501 , +16467 , +-4941 , +14801 , +30591 , +-30227 , +-9501 , +17347 , +-25045 , +-28035 , +29635 , +17603 , +25539 , +1465 , +3241 , +19863 , +-18863 , +4769 , +-23675 , +-12895 , +-17617 , +7085 , +27255 , +-14011 , +-23065 , +401 , +20453 , +22253 , +10117 , +109 , +-9447 , +-25983 , +3703 , +-26745 , +13655 , +-2219 , +11991 , +29575 , +-18579 , +-20307 , +11093 , +-11483 , +-11303 , +-20309 , +13947 , +24175 , +-19117 , +-21039 , +25755 , +-6027 , +27119 , +26349 , +-23023 , +4999 , +-3407 , +11675 , +555 , +20457 , +4005 , +30523 , +10877 , +11537 , +8313 , +-21403 , +-333 , +30041 , +-3695 , +-4381 , +6383 , +3131 , +-12891 , +3629 , +-1375 , +1801 , +-21551 , +25179 , +-3619 , +-2017 , +-11723 , +-14947 , +20277 , +-7007 , +-15097 , +25657 , +1033 , +-9035 , +-9679 , +-25855 , +16749 , +-20941 , +18785 , +-25529 , +12149 , +-22043 , +4265 , +4949 , +21783 , +-3269 , +-31341 , +32365 , +-14219 , +21119 , +-5447 , +30517 , +-16445 , +407 , +-7715 , +-24129 , +-25957 , +27445 , +4735 , +31213 , +-1073 , +21651 , +-8961 , +-18567 , +3015 , +27047 , +29221 , +-32665 , +31579 , +-23583 , +10055 , +8703 , +24353 , +-31909 , +24283 , +-30655 , +31571 , +-28007 , +-8819 , +11231 , +6167 , +11453 , +-7205 , +-20811 , +-2455 , +-449 , +-7125 , +-8503 , +32097 , +14373 , +11619 , +22447 , +-18407 , +-4677 , +25093 , +31385 , +15355 , +-27441 , +5055 , +-2883 , +-28765 , +8289 , +23433 , +-29609 , +10799 , +-21023 , +-14785 , +27671 , +-23785 , +15591 , +28077 , +-23255 , +10889 , +26985 , +-27079 , +8093 , +-7613 , +-24461 , +-22293 , +-20121 , +12001 , +-14499 , +-7663 , +-27689 , +-26173 , +-12917 , +-29621 , +-4213 , +23383 , +8347 , +8239 , +-18701 , +9721 , +31523 , +8279 , +-30917 , +18767 , +1513 , +2561 , +-14389 , +-14829 , +17301 , +12837 , +-16321 , +27257 , +-16655 , +-6395 , +-8995 , +-28929 , +-3167 , +-20911 , +-9843 , +-29749 , +26959 , +-2121 , +2897 , +32381 , +31089 , +7167 , +-32705 , +30855 , +-18565 , +163 , +11769 , +-20981 , +29593 , +14303 , +-6499 , +-17103 , +20447 , +-2729 , +19529 , +-23049 , +24591 , +-20701 , +31501 , +-30057 , +-13369 , +-15507 , +-24221 , +-12207 , +27449 , +-1399 , +16167 , +-18223 , +22121 , +15751 , +17167 , +3063 , +-8483 , +22867 , +-16731 , +-5571 , +-5151 , +9803 , +26813 , +24457 , +12593 , +-5037 , +-22933 , +-12669 , +14391 , +23405 , +21123 , +-13197 , +-19511 , +-3879 , +-1147 , +-31341 , +5721 , +8355 , +-12255 , +16871 , +-7507 , +7107 , +-3545 , +8863 , +-20709 , +-30033 , +26625 , +-20511 , +21313 , +5239 , +25773 , +20267 , +14395 , +2651 , +7729 , +14883 , +17243 , +4065 , +-5479 , +3577 , +21345 , +6005 , +-9367 , +-29897 , +-14285 , +-29835 , +-28777 , +-25059 , +3351 , +-1065 , +29703 , +18291 , +-25239 , +10289 , +10877 , +32233 , +31701 , +-16799 , +20247 , +-24595 , +-27637 , +-23143 , +21573 , +-29187 , +-263 , +11773 , +-21179 , +1417 , +-24185 , +-837 , +-237 , +21571 , +7625 , +3229 , +-28695 , +-1035 , +-28999 , +-25815 , +-21197 , +24293 , +1649 , +23095 , +16389 , +3233 , +18147 , +-16893 , +18457 , +-14501 , +-21239 , +-16435 , +30015 , +-9785 , +-14677 , +-4885 , +-26785 , +-10905 , +-30067 , +6759 , +7401 , +20845 , +-21721 , +-27377 , +22475 , +-15859 , +-1053 , +9751 , +-16137 , +89 , +24783 , +-15323 , +-3511 , +-25957 , +16601 , +18675 , +-28917 , +-31453 , +-3451 , +871 , +-11541 , +17321 , +6949 , +32289 , +-147 , +8995 , +30867 , +21147 , +24555 , +-25577 , +3429 , +24773 , +7179 , +30075 , +10153 , +17167 , +-28495 , +-16375 , +14877 , +22289 , +26495 , +16919 , +-29 , +12951 , +9415 , +27631 , +-7491 , +-8897 , +25607 , +27817 , +7107 , +-22897 , +31457 , +32641 , +-31077 , +-3955 , +-17779 , +2477 , +-24783 , +-14629 , +2009 , +-24389 , +-24079 , +-26041 , +415 , +-28315 , +18047 , +-1813 , +28085 , +-281 , +3305 , +-25923 , +9331 , +13019 , +-27289 , +-25937 , +12959 , +13713 , +-1393 , +13381 , +27117 , +18147 , +-23029 , +-8791 , +6125 , +20371 , +-26665 , +5699 , +7057 , +-7399 , +-26635 , +-15911 , +4377 , +-5625 , +19107 , +26655 , +-13167 , +-29477 , +-24809 , +12497 , +-9529 , +30551 , +-28491 , +-2999 , +16579 , +3161 , +-19767 , +14495 , +12739 , +-24013 , +32443 , +29499 , +-3159 , +24451 , +-9009 , +26343 , +-22017 , +-12147 , +-8371 , +-2445 , +16233 , +-13037 , +10321 , +17351 , +9625 , +-14679 , +-3607 , +29565 , +9171 , +6031 , +12513 , +-4879 , +-5163 , +27147 , +-13839 , +28391 , +-21153 , +-12225 , +20857 , +-12137 , +24605 , +-23423 , +19895 , +-14515 , +-979 , +-13771 , +29563 , +-30601 , +22791 , +26403 , +-10899 , +-24501 , +-5373 , +-21169 , +32177 , +-11051 , +5965 , +-12975 , +27187 , +28047 , +22101 , +-22227 , +25421 , +-18563 , +-9007 , +24495 , +-23281 , +7623 , +821 , +18491 , +-11543 , +-20793 , +9123 , +30511 , +11757 , +26027 , +9831 , +25261 , +-31357 , +4235 , +29941 , +-16381 , +-9565 , +11005 , +-29869 , +12667 , +11659 , +-31439 , +-8159 , +-9041 , +28145 , +3975 , +23301 , +-32407 , +1485 , +-23899 , +4523 , +10487 , +-2437 , +7191 , +-31943 , +1537 , +133 , +-22693 , +2627 , +-25367 , +-12847 , +-29817 , +-17077 , +-13161 , +-27049 , +21843 , +30135 , +-12323 , +14179 , +-19015 , +13637 , +-12473 , +13641 , +-4851 , +-24057 , +7027 , +-24683 , +6803 , +-12073 , +-22543 , +20431 , +18583 , +5715 , +-8561 , +31403 , +-29433 , +5719 , +25407 , +3011 , +5769 , +-13845 , +-8093 , +-15409 , +32273 , +-19515 , +29607 , +-28317 , +13565 , +-1217 , +-11423 , +7197 , +26539 , +-23093 , +-15261 , +-1441 , +11415 , +-22803 , +-1971 , +-30323 , +22501 , +-329 , +-5005 , +-7997 , +-13435 , +-24903 , +-7893 , +-10743 , +-25653 , +19841 , +-32347 , +-29171 , +-8067 , +16525 , +21577 , +-29091 , +-30089 , +-23353 , +-29813 , +-13797 , +5561 , +-12931 , +20289 , +-24259 , +28681 , +16853 , +5759 , +19003 , +-5119 , +24775 , +10733 , +-25013 , +-26453 , +-11369 , +-6493 , +-16357 , +-10849 , +-31029 , +-9863 , +-27383 , +31629 , +24999 , +19171 , +-30505 , +29031 , +29721 , +21327 , +-27675 , +1513 , +-11455 , +4083 , +-1041 , +-6727 , +-9119 , +4137 , +-14537 , +1535 , +5715 , +-27829 , +23117 , +23417 , +27009 , +-20733 , +14397 , +-18921 , +-6553 , +-2513 , +23877 , +-26349 , +-11651 , +-18393 , +11289 , +26499 , +13239 , +28841 , +25999 , +-17029 , +-28033 , +-32733 , +8923 , +19867 , +10787 , +-15219 , +19019 , +6957 , +16347 , +10955 , +30331 , +26815 , +-10189 , +-12169 , +-14329 , +13105 , +-31987 , +-12735 , +-26157 , +-28327 , +30231 , +17095 , +-28751 , +-12271 , +-21061 , +-18967 , +-2135 , +-23847 , +19621 , +27815 , +-2651 , +16611 , +-3667 , +-14987 , +29101 , +-14665 , +15453 , +13581 , +16547 , +-19387 , +14297 , +-1065 , +32629 , +-8329 , +-7065 , +11187 , +-26409 , +-19625 , +-26789 , +5715 , +-4739 , +5023 , +27029 , +-17381 , +-26927 , +-17205 , +27767 , +21357 , +15403 , +30911 , +-8867 , +-32625 , +29323 , +-45 , +3991 , +22003 , +-24883 , +-8589 , +17629 , +-19167 , +-11673 , +14125 , +11343 , +10239 , +-25959 , +-18087 , +16353 , +-13649 , +14893 , +-23523 , +-18341 , +24045 , +17837 , +11801 , +20435 , +6619 , +6675 , +10609 , +-30049 , +22883 , +9741 , +15463 , +-16687 , +-18931 , +32175 , +-31109 , +-28119 , +-21423 , +-20311 , +2555 , +9877 , +24697 , +23299 , +-19941 , +-21207 , +-25617 , +26709 , +19859 , +-26741 , +-25829 , +-32389 , +21939 , +8189 , +-15429 , +-25391 , +-9733 , +24515 , +-9289 , +10471 , +26673 , +-21465 , +-10117 , +-13889 , +18689 , +29169 , +-8493 , +8321 , +-5877 , +18261 , +-29891 , +-27215 , +-14721 , +27767 , +6853 , +-25109 , +-17605 , +29273 , +-29605 , +28955 , +-1193 , +16475 , +21161 , +-21457 , +-24505 , +12335 , +-20879 , +-10919 , +6255 , +30799 , +18783 , +15039 , +21309 , +-25349 , +10597 , +9139 , +443 , +8107 , +-27501 , +-13197 , +-15439 , +9483 , +-663 , +9301 , +-26319 , +18797 , +-28745 , +-14707 , +28861 , +23503 , +30191 , +9559 , +10707 , +14143 , +28421 , +24505 , +-7157 , +29411 , +-13125 , +-17993 , +-3413 , +8301 , +29315 , +12039 , +19651 , +20751 , +-4911 , +6231 , +-11833 , +-26381 , +14585 , +23283 , +15005 , +18745 , +21889 , +6919 , +3905 , +-26515 , +13051 , +26715 , +30933 , +29049 , +7519 , +-8833 , +18489 , +8485 , +13795 , +-22133 , +2349 , +-26103 , +5453 , +-935 , +31195 , +-30965 , +11987 , +19765 , +16117 , +-7089 , +2927 , +29723 , +11347 , +22197 , +-2633 , +3441 , +-1535 , +-1581 , +11831 , +8245 , +-16931 , +-9117 , +16451 , +32451 , +429 , +-7349 , +-28839 , +-9731 , +-12871 , +19199 , +-19217 , +-237 , +32735 , +32657 , +-14635 , +14255 , +-14545 , +-31977 , +7679 , +17587 , +-25597 , +-25941 , +-18959 , +-5263 , +-29551 , +31203 , +-17281 , +-29347 , +13837 , +-23355 , +27195 , +-15791 , +16951 , +16451 , +-17601 , +27957 , +-16005 , +2353 , +8333 , +17221 , +14721 , +-22083 , +-15907 , +15809 , +16463 , +9579 , +26625 , +-4567 , +-1063 , +-27773 , +-22599 , +11509 , +24091 , +-8169 , +25859 , +6855 , +30127 , +-13459 , +18175 , +-5079 , +-21777 , +-8191 , +13373 , +30663 , +16765 , +-26887 , +28577 , +-223 , +-2455 , +25373 , +28073 , +10693 , +4803 , +-9649 , +-1445 , +-21755 , +-13649 , +-19067 , +-14459 , +-30151 , +16649 , +-8385 , +-1107 , +-31383 , +1901 , +18559 , +-9897 , +-31091 , +29407 , +-17341 , +5861 , +-23741 , +-25383 , +26999 , +-273 , +-24819 , +26849 , +23415 , +-3819 , +26617 , +26285 , +-26369 , +23393 , +-31251 , +-5971 , +8613 , +-15337 , +-2991 , +10031 , +-32301 , +-1009 , +24141 , +-14355 , +13627 , +4495 , +13695 , +-24019 , +-28713 , +7071 , +-25805 , +5969 , +25939 , +30181 , +-27619 , +-10247 , +10007 , +-31491 , +32397 , +28051 , +-20307 , +-25777 , +17195 , +24691 , +31429 , +5731 , +14383 , +21105 , +27821 , +19653 , +12051 , +-6659 , +1089 , +25679 , +-23337 , +-13897 , +3175 , +-22261 , +-29527 , +-16251 , +-26101 , +31879 , +-21205 , +-461 , +-30833 , +30125 , +2085 , +-20351 , +9935 , +-14053 , +17595 , +3265 , +24969 , +-28165 , +-27609 , +-17941 , +99 , +4959 , +2297 , +-4291 , +20569 , +-30189 , +-10051 , +8011 , +-8511 , +-22795 , +-32699 , +-30827 , +-31823 , +18901 , +16981 , +31915 , +29451 , +-27453 , +-1821 , +-13641 , +-29719 , +-4115 , +-20277 , +671 , +-24943 , +5621 , +2051 , +2971 , +-7939 , +-16179 , +-14753 , +-11961 , +18885 , +3845 , +-22341 , +26179 , +2457 , +14769 , +-10563 , +29511 , +-9407 , +-19791 , +-1273 , +19129 , +25099 , +17307 , +30195 , +30921 , +20171 , +17663 , +-23859 , +10251 , +-31923 , +-31147 , +-22657 , +12933 , +-5043 , +-449 , +-14629 , +14163 , +18939 , +-9357 , +-21183 , +-29513 , +-24867 , +3591 , +-20505 , +26291 , +32093 , +-7857 , +30339 , +2595 , +-5195 , +-16843 , +1933 , +25681 , +5735 , +-20981 , +-20747 , +-8427 , +-30407 , +-18961 , +-18601 , +-13983 , +9899 , +-23915 , +28083 , +11363 , +-27149 , +23719 , +26541 , +25881 , +24431 , +23965 , +-31683 , +23145 , +28571 , +23825 , +-24853 , +-22597 , +14485 , +-12643 , +28031 , +-27635 , +10761 , +18477 , +-32695 , +11663 , +-18513 , +26841 , +-9015 , +25019 , +-22973 , +22593 , +10993 , +27111 , +-10505 , +30301 , +-4907 , +25703 , +18803 , +21469 , +-18195 , +29211 , +-29623 , +-29959 , +-4411 , +12431 , +21487 , +-28459 , +-8649 , +-6003 , +28719 , +5963 , +-9949 , +18743 , +-10193 , +5963 , +10153 , +1955 , +1241 , +7091 , +22239 , +15083 , +20955 , +-7003 , +-9717 , +-13105 , +-25315 , +-1187 , +30293 , +-10557 , +-9027 , +20111 , +28937 , +17291 , +-7299 , +28475 , +-1977 , +-29353 , +3015 , +-31229 , +-16837 , +-4009 , +287 , +-26359 , +16093 , +-5681 , +24599 , +14911 , +-22499 , +23483 , +25811 , +13897 , +-9047 , +11479 , +24561 , +23499 , +-30441 , +-17079 , +10769 , +-3259 , +-15451 , +1957 , +19903 , +-143 , +11891 , +-14697 , +8183 , +-8687 , +5171 , +30451 , +32533 , +24909 , +30569 , +-29109 , +28753 , +-1657 , +-29667 , +-16889 , +21425 , +1979 , +-27625 , +-25847 , +-6517 , +-4021 , +-27243 , +-32337 , +-13195 , +1633 , +-7037 , +3715 , +-10561 , +-6203 , +-2509 , +831 , +-15765 , +24881 , +30617 , +-3983 , +-23381 , +29483 , +7675 , +31635 , +-16949 , +-28833 , +10799 , +-26217 , +-5449 , +-22921 , +5717 , +-27121 , +27885 , +7787 , +26117 , +16059 , +16627 , +18793 , +4371 , +2977 , +-17579 , +29979 , +-32577 , +-25683 , +-23529 , +10895 , +-26769 , +23999 , +-30543 , +-18817 , +-17685 , +-16823 , +31877 , +-28103 , +22797 , +-20123 , +-43 , +-15123 , +-8449 , +-3731 , +17727 , +-10875 , +-25869 , +-13803 , +-29255 , +25859 , +-32681 , +-14333 , +-11525 , +2387 , +18069 , +9439 , +30853 , +-32599 , +-9667 , +18425 , +15117 , +-10929 , +-26421 , +13143 , +5761 , +-30197 , +20185 , +13645 , +23157 , +26347 , +28889 , +-18791 , +-23261 , +-349 , +-31161 , +31995 , +-803 , +-31645 , +16231 , +14923 , +-16377 , +2607 , +11647 , +-16369 , +-23661 , +-16455 , +-27255 , +-20583 , +30705 , +18871 , +21867 , +-361 , +-4979 , +-13895 , +21429 , +10295 , +2507 , +-20859 , +29141 , +25263 , +-26257 , +-6925 , +30927 , +-20127 , +13737 , +-32459 , +-1929 , +11123 , +13949 , +30915 , +-28381 , +20191 , +13767 , +-31581 , +-24597 , +-18415 , +25001 , +-15283 , +-15009 , +5627 , +21899 , +14583 , +16057 , +-19787 , +-20085 , +-20103 , +-30307 , +26765 , +10365 , +16031 , +19021 , +23453 , +15457 , +-14339 , +-5023 , +20461 , +24915 , +-9903 , +-2561 , +-3067 , +-16621 , +16465 , +-31339 , +-2045 , +18665 , +-27891 , +-3573 , +18743 , +25649 , +14011 , +1415 , +19003 , +-10941 , +-231 , +-13673 , +24453 , +10995 , +-445 , +25589 , +-22391 , +24713 , +-25339 , +-6477 , +15687 , +-4551 , +-27717 , +-20739 , +-14229 , +19 , +-9305 , +10065 , +-10785 , +2955 , +12481 , +31277 , +-21019 , +31581 , +15389 , +9809 , +5299 , +-21993 , +-331 , +-4749 , +-14715 , +-7417 , +-27443 , +5495 , +2103 , +-24137 , +-5693 , +29739 , +9309 , +-14369 , +29801 , +15731 , +11489 , +489 , +-27681 , +3093 , +-9971 , +4569 , +-23323 , +7387 , +-10189 , +14549 , +26561 , +13403 , +28855 , +30481 , +-12669 , +10027 , +-15435 , +-9651 , +-13331 , +31889 , +-29429 , +-27957 , +15045 , +9161 , +-18439 , +1733 , +30125 , +-19537 , +-24519 , +-25489 , +-18563 , +11521 , +22423 , +29281 , +-9195 , +-18665 , +-14335 , +-16747 , +-26177 , +20237 , +2607 , +3045 , +-13569 , +-7791 , +-14167 , +3577 , +-7955 , +-14583 , +1899 , +17347 , +5647 , +6737 , +10235 , +8315 , +31149 , +-7687 , +-32261 , +-3311 , +27567 , +-31759 , +26699 , +17449 , +-24339 , +31693 , +-3431 , +-7535 , +18449 , +-13453 , +25465 , +22071 , +26339 , +7769 , +-31995 , +-3673 , +2095 , +5949 , +-14871 , +14849 , +21007 , +-16293 , +-26361 , +-8857 , +7375 , +-27099 , +-22139 , +-4087 , +8761 , +9339 , +-32401 , +-22649 , +23929 , +-20893 , +20677 , +19707 , +-19603 , +-10173 , +15129 , +-25241 , +31615 , +-13159 , +421 , +20653 , +257 , +-11475 , +25059 , +-241 , +-27393 , +-11567 , +169 , +7449 , +18585 , +-19053 , +14775 , +17965 , +-6183 , +10107 , +-21539 , +-29339 , +19733 , +-22595 , +-9851 , +3353 , +-23365 , +25715 , +-18985 , +27865 , +-18007 , +-10025 , +30279 , +-27179 , +-7661 , +-23045 , +-32589 , +19947 , +-23351 , +-25095 , +-12805 , +-3831 , +-20705 , +31163 , +-26345 , +309 , +13111 , +12575 , +-19795 , +-15103 , +18145 , +28101 , +20783 , +-21379 , +23285 , +4145 , +-19093 , +-19273 , +25379 , +16275 , +31663 , +-32337 , +-14763 , +-1031 , +-3759 , +26317 , +-20613 , +-21753 , +18133 , +5597 , +-10515 , +-26833 , +-2435 , +11399 , +23615 , +-9877 , +14181 , +22595 , +-14181 , +-23183 , +-10985 , +18645 , +-11883 , +28783 , +17323 , +10565 , +-2937 , +-5565 , +18515 , +-10415 , +-32155 , +16687 , +3709 , +-28305 , +13343 , +-22507 , +361 , +21307 , +-8347 , +-26835 , +16953 , +-26507 , +25625 , +-16579 , +4759 , +-16777 , +27151 , +10065 , +3009 , +-17359 , +1909 , +27895 , +31271 , +26777 , +-6235 , +-24851 , +-19069 , +1961 , +2681 , +-21913 , +-12947 , +21975 , +-19407 , +-11589 , +25203 , +-13815 , +-23115 , +11167 , +957 , +17935 , +13701 , +-29217 , +-5871 , +-4703 , +24831 , +-365 , +24953 , +23501 , +28223 , +223 , +-12707 , +-4367 , +13941 , +-13791 , +-31987 , +25405 , +-20289 , +-12115 , +24807 , +29595 , +-10881 , +-21235 , +-30747 , +-18121 , +29235 , +-14937 , +-3135 , +-32405 , +1483 , +-17147 , +23935 , +-11715 , +15753 , +6795 , +14731 , +21845 , +10833 , +9635 , +10839 , +24949 , +-14721 , +27523 , +-16537 , +-9613 , +-7091 , +-6305 , +-9993 , +8111 , +7319 , +17697 , +-30715 , +-16117 , +-10681 , +13985 , +-15631 , +12899 , +-483 , +21345 , +-14699 , +13703 , +-30961 , +31417 , +31709 , +12977 , +19233 , +12449 , +-17959 , +14205 , +25787 , +-4903 , +-17317 , +-11167 , +-26497 , +-11091 , +-22767 , +-28505 , +-6231 , +-10461 , +27927 , +11491 , +-7461 , +-23625 , +-2803 , +27625 , +-10879 , +29591 , +-11843 , +-26037 , +24991 , +7513 , +26401 , +-29617 , +-23503 , +27433 , +-11255 , +19039 , +31229 , +11153 , +30761 , +9227 , +-785 , +-2901 , +28347 , +24961 , +-11791 , +4559 , +-10869 , +19325 , +24381 , +-27685 , +14491 , +-15931 , +-31941 , +-1057 , +-1485 , +6179 , +-7203 , +30815 , +3963 , +29151 , +28265 , +11519 , +-5739 , +21423 , +8161 , +31941 , +-7375 , +-23501 , +-21043 , +-12595 , +2733 , +-11537 , +10143 , +-14973 , +-24413 , +24005 , +10369 , +24663 , +8963 , +27875 , +-20043 , +-9 , +15541 , +-17081 , +17769 , +-15093 , +29089 , +-28243 , +23051 , +16741 , +-8359 , +-7665 , +-16851 , +-3133 , +-5601 , +-32361 , +1231 , +-31235 , +11911 , +29469 , +-28095 , +17861 , +-28779 , +9241 , +24953 , +-12331 , +-18109 , +-14821 , +6627 , +26037 , +-4181 , +32459 , +-29243 , +-6679 , +-32109 , +-22953 , +14609 , +-8535 , +-17011 , +-13197 , +-10053 , +-19683 , +-21367 , +-17463 , +-19817 , +19223 , +-29457 , +13307 , +-23125 , +17731 , +17211 , +-28143 , +-25845 , +9189 , +-21233 , +8057 , +28459 , +27663 , +10189 , +16247 , +-5181 , +12123 , +9137 , +13093 , +-5607 , +-2019 , +7015 , +-21527 , +13797 , +-28631 , +-14301 , +-7065 , +18589 , +-26121 , +-5575 , +30721 , +30043 , +29803 , +32311 , +-20279 , +-25307 , +24837 , +-18821 , +-31747 , +983 , +25761 , +-28339 , +-2819 , +23913 , +-9567 , +25457 , +5829 , +-21547 , +12981 , +12103 , +25569 , +1381 , +-12023 , +8287 , +-23319 , +-9323 , +-30469 , +915 , +7545 , +-9629 , +-21921 , +5019 , +14243 , +-2011 , +6443 , +-3545 , +26095 , +-12817 , +26549 , +9593 , +29647 , +-12201 , +27495 , +-3459 , +-873 , +-32543 , +17405 , +-5283 , +16631 , +12229 , +19769 , +2715 , +4847 , +26199 , +-3305 , +-19795 , +4169 , +-28205 , +-8047 , +27151 , +-7273 , +1721 , +-32567 , +-21539 , +-15455 , +-2903 , +19147 , +-23315 , +-5793 , +25269 , +-12353 , +13667 , +13433 , +-13251 , +935 , +3793 , +-18889 , +30275 , +-18287 , +18115 , +23293 , +5447 , +-15279 , +13791 , +27197 , +-9313 , +-14149 , +-1151 , +5369 , +-30645 , +5721 , +32199 , +-13643 , +-29103 , +-24157 , +15921 , +-29463 , +-4971 , +-32071 , +-9541 , +-1783 , +-12759 , +-2153 , +-27797 , +16619 , +-29899 , +24787 , +-21385 , +-13875 , +8765 , +12495 , +1233 , +-22075 , +-15863 , +17777 , +-18109 , +-17475 , +31725 , +-23453 , +11273 , +-32279 , +-18767 , +4549 , +18665 , +-28993 , +31197 , +31071 , +24007 , +-21393 , +10647 , +-23961 , +24511 , +31451 , +-13571 , +9645 , +-2879 , +-17387 , +26867 , +7769 , +6561 , +1865 , +-20093 , +-29405 , +-17223 , +6723 , +25529 , +-6649 , +9461 , +-32415 , +-23055 , +-16255 , +32119 , +-12791 , +-9039 , +8769 , +23975 , +5031 , +6665 , +23659 , +-23091 , +-7393 , +-17053 , +-3263 , +-30677 , +31945 , +23517 , +-30611 , +5779 , +28901 , +-30429 , +16299 , +11391 , +26265 , +-26429 , +-27135 , +3497 , +16739 , +-4085 , +9093 , +-28377 , +23827 , +91 , +16259 , +12537 , +6215 , +-32257 , +-191 , +-10705 , +25949 , +1929 , +-30921 , +-18061 , +-26133 , +-32345 , +9917 , +12333 , +13503 , +-13443 , +13899 , +-16879 , +-11697 , +-10375 , +12341 , +17215 , +1967 , +-27473 , +-1065 , +-24877 , +23575 , +9389 , +-7337 , +-25081 , +6345 , +31195 , +11225 , +-28735 , +10135 , +-2489 , +-14283 , +21683 , +-18479 , +8969 , +7731 , +17389 , +-7741 , +6163 , +22085 , +-17417 , +175 , +-21365 , +11703 , +-18323 , +-1217 , +1955 , +-15509 , +17425 , +12923 , +-22029 , +22295 , +8039 , +20303 , +-30897 , +29425 , +29639 , +-22927 , +18721 , +30707 , +-5379 , +27365 , +20797 , +1161 , +865 , +26353 , +-27331 , +11729 , +-1947 , +29591 , +-5545 , +845 , +6073 , +26249 , +-9803 , +21789 , +-9513 , +-20825 , +-27313 , +13501 , +-25303 , +22253 , +9537 , +10287 , +18067 , +-22533 , +26017 , +-30781 , +-15723 , +8185 , +-4899 , +-445 , +-25633 , +-1757 , +29327 , +-23631 , +-27541 , +-2385 , +-12589 , +-21889 , +-28143 , +-20393 , +10787 , +5955 , +-18527 , +5181 , +30127 , +31473 , +637 , +22389 , +-15311 , +10135 , +17585 , +3317 , +-25783 , +-10353 , +-11385 , +-25847 , +-10925 , +16187 , +-15709 , +-14509 , +11201 , +-32457 , +919 , +-28353 , +493 , +-739 , +16897 , +4859 , +-30597 , +28845 , +-11235 , +-24335 , +-11993 , +-7273 , +-26655 , +-8261 , +-5337 , +21921 , +5265 , +2205 , +-24585 , +-22675 , +-18209 , +5249 , +-5955 , +-19031 , +-29323 , +1387 , +-19435 , +7881 , +13343 , +1647 , +5241 , +-21697 , +-29869 , +-26067 , +28423 , +-12231 , +-12719 , +-28731 , +-15643 , +17613 , +-30279 , +-2473 , +-24299 , +8635 , +15527 , +-14607 , +-4915 , +-31841 , +-445 , +32011 , +-943 , +10159 , +-33 , +21893 , +12873 , +-1301 , +17293 , +27665 , +-22631 , +5085 , +24379 , +28477 , +-585 , +3789 , +-23483 , +8921 , +-3699 , +17529 , +-31859 , +26877 , +-14655 , +-11443 , +-31209 , +2425 , +9113 , +-3299 , +-19931 , +-4143 , +30033 , +-29863 , +-19265 , +6067 , +29935 , +-31799 , +-22559 , +-8211 , +-7009 , +-14395 , +-13057 , +-1045 , +7563 , +29673 , +5159 , +-17493 , +-31187 , +9807 , +-14437 , +-7627 , +-30417 , +-5813 , +13283 , +-15725 , +9407 , +-20321 , +-23449 , +-9401 , +-21915 , +-7891 , +-29559 , +-22453 , +-14493 , +-9409 , +13627 , +-7295 , +28033 , +-209 , +-14569 , +-5205 , +-19343 , +9383 , +2295 , +-30231 , +19357 , +-933 , +-21743 , +-12883 , +-27513 , +21557 , +30343 , +14129 , +-611 , +-18911 , +14725 , +-6027 , +-19057 , +22831 , +-14377 , +5297 , +20265 , +-8867 , +-6139 , +26191 , +28083 , +-13887 , +-31517 , +-27801 , +4535 , +17743 , +-1103 , +-10065 , +-24979 , +515 , +-8533 , +-27909 , +12161 , +-11613 , +1067 , +-20689 , +22393 , +-7439 , +14903 , +10429 , +-8569 , +2665 , +30369 , +20117 , +-26143 , +12657 , +-9319 , +1701 , +-3177 , +16667 , +26823 , +-14387 , +15089 , +-27311 , +-20247 , +-32173 , +21825 , +27035 , +27613 , +12007 , +-6335 , +14407 , +15687 , +15375 , +-28957 , +-31695 , +-30813 , +-28125 , +17841 , +1265 , +-23587 , +26055 , +-31843 , +-21101 , +21865 , +-28445 , +14949 , +-31277 , +-11557 , +-21995 , +16731 , +-12841 , +15107 , +-27981 , +18893 , +25693 , +-12677 , +-19655 , +-3119 , +-6273 , +-14901 , +-25017 , +7073 , +-30747 , +7165 , +21015 , +-2185 , +1655 , +9643 , +-12167 , +7645 , +-11099 , +19623 , +17731 , +3217 , +-12529 , +-14325 , +29519 , +18379 , +-30009 , +-22321 , +-24591 , +-21975 , +-21245 , +4835 , +-19213 , +-777 , +17751 , +-1333 , +-12027 , +28947 , +-23951 , +16303 , +-325 , +4155 , +-26295 , +31227 , +18947 , +-16663 , +-18715 , +22129 , +-5087 , +-6479 , +21631 , +-10809 , +-14819 , +24847 , +1615 , +18617 , +-7737 , +-17725 , +23739 , +24739 , +12585 , +26543 , +28683 , +11419 , +17533 , +-223 , +11947 , +23303 , +11945 , +6329 , +-6693 , +-26699 , +20533 , +-7745 , +-793 , +24177 , +16579 , +749 , +23271 , +6695 , +-28919 , +-4389 , +28397 , +-6035 , +-28857 , +12489 , +21185 , +-9821 , +-4033 , +-11265 , +31 , +1417 , +20141 , +31643 , +4197 , +19547 , +32577 , +17143 , +-307 , +7265 , +-14571 , +-395 , +25905 , +5133 , +-17755 , +-2853 , +11055 , +-10093 , +-1209 , +-22223 , +8177 , +-1795 , +-29917 , +-13045 , +-2465 , +13767 , +-4175 , +-3215 , +7127 , +1271 , +-9565 , +7211 , +24933 , +-21839 , +-28307 , +-20575 , +-4229 , +-16815 , +-13521 , +813 , +31789 , +29703 , +15673 , +-525 , +15329 , +-32023 , +-29191 , +-2493 , +-31603 , +-117 , +-6531 , +24419 , +-25743 , +801 , +-9633 , +24561 , +-23227 , +30471 , +-8631 , +-5963 , +12541 , +-8985 , +1253 , +25595 , +21753 , +27465 , +14935 , +-27281 , +-10559 , +22191 , +-18891 , +-15761 , +21815 , +-24789 , +-9213 , +-17689 , +-4773 , +14967 , +16933 , +-9563 , +20853 , +-3441 , +5975 , +-25801 , +-13607 , +-12091 , +-24915 , +-12739 , +7697 , +27995 , +-1533 , +6211 , +-13913 , +-1119 , +-1291 , +-15333 , +-26799 , +27267 , +12893 , +-31051 , +-2139 , +29093 , +-2489 , +19313 , +8287 , +-7427 , +-27033 , +-24321 , +25873 , +6377 , +30485 , +-8525 , +-15785 , +-10037 , +19141 , +-26021 , +5013 , +-32233 , +8701 , +-31073 , +-5327 , +-7691 , +-30261 , +20943 , +-31419 , +-31913 , +28867 , +-25281 , +-13097 , +-11379 , +2671 , +-23261 , +-5225 , +-3231 , +26961 , +-20257 , +23573 , +-29525 , +1873 , +-7191 , +-2447 , +-31633 , +-2885 , +-30951 , +-4193 , +-7825 , +-6729 , +25215 , +17177 , +-16567 , +-10689 , +16327 , +32535 , +-23035 , +31891 , +11527 , +27459 , +7735 , +16957 , +-26603 , +-32257 , +-9831 , +-1155 , +-9623 , +-19447 , +18451 , +5445 , +19821 , +28357 , +-3737 , +29107 , +32601 , +23787 , +27447 , +-21753 , +-24439 , +-9791 , +17325 , +-2787 , +-16045 , +-28971 , +-18295 , +21857 , +-1945 , +13359 , +-27977 , +26955 , +2457 , +-5355 , +-397 , +29525 , +-23221 , +11063 , +-18475 , +-6539 , +-10185 , +-17815 , +25581 , +10257 , +-15415 , +-22813 , +28255 , +-16261 , +14077 , +-17423 , +17267 , +-19991 , +16307 , +26925 , +16053 , +11749 , +19591 , +-27595 , +9737 , +24917 , +-2261 , +19695 , +-30399 , +-28957 , +3897 , +-9173 , +-8645 , +12285 , +-619 , +9455 , +-20109 , +21579 , +6205 , +-12247 , +-15585 , +-2135 , +-349 , +15069 , +26821 , +-31075 , +-27003 , +-24847 , +2897 , +18767 , +-16055 , +28239 , +6581 , +-4861 , +25037 , +22701 , +18423 , +-7157 , +-13627 , +-3135 , +29391 , +-11191 , +11669 , +32241 , +-67 , +-13281 , +8609 , +-19559 , +4515 , +30187 , +-9173 , +11957 , +27095 , +505 , +12459 , +18725 , +19911 , +-251 , +-3679 , +-1701 , +18691 , +-9941 , +-13833 , +-24165 , +9183 , +14179 , +9937 , +18861 , +-6523 , +-4237 , +18919 , +15129 , +16531 , +-14223 , +7261 , +30683 , +11563 , +-15439 , +-9697 , +931 , +11155 , +9287 , +11697 , +30593 , +-7097 , +-4875 , +-11119 , +-10199 , +-28009 , +3239 , +25601 , +9889 , +2745 , +-3729 , +18031 , +-23681 , +-19359 , +-17929 , +-30395 , +15521 , +20963 , +-17029 , +-27843 , +7525 , +-5189 , +-23993 , +23361 , +-9897 , +-18253 , +-17759 , +14271 , +10621 , +23155 , +-8113 , +-8575 , +-19459 , +18079 , +-31095 , +-21243 , +-10663 , +-19355 , +14959 , +-11947 , +-5583 , +-6495 , +18951 , +27491 , +-915 , +10861 , +-13907 , +16089 , +28413 , +25151 , +-20457 , +3451 , +32021 , +30073 , +16573 , +12785 , +6615 , +31879 , +31965 , +-27855 , +8601 , +373 , +-11535 , +-30649 , +21909 , +11531 , +-15195 , +-15177 , +6693 , +14431 , +-17585 , +-6835 , +28539 , +-1301 , +-15645 , +-19071 , +7377 , +-4813 , +25465 , +-15041 , +-31183 , +30667 , +20787 , +26445 , +9371 , +-6405 , +10945 , +-20449 , +6345 , +-9515 , +-425 , +-29403 , +-12187 , +-29751 , +-13023 , +-29513 , +13757 , +-17471 , +-15043 , +28247 , +25087 , +-21579 , +27189 , +5017 , +18927 , +-4663 , +25591 , +-5769 , +23839 , +27617 , +11335 , +25123 , +-28759 , +31413 , +21185 , +-26777 , +-14749 , +20851 , +-28857 , +-21129 , +7581 , +-16945 , +23295 , +3659 , +593 , +27807 , +18379 , +5501 , +-27165 , +-24851 , +-12739 , +17557 , +21589 , +-23655 , +-13803 , +-26645 , +29951 , +-4757 , +23855 , +5113 , +-569 , +7591 , +28937 , +9017 , +217 , +-9425 , +-29007 , +-9097 , +-797 , +-12783 , +17723 , +-13909 , +-10301 , +-26715 , +-10555 , +18261 , +27599 , +7971 , +25569 , +5197 , +8057 , +2753 , +19865 , +10785 , +32665 , +-17093 , +1499 , +30191 , +21529 , +-20481 , +1663 , +-30283 , +10039 , +-32327 , +9903 , +-8659 , +-18641 , +-28313 , +1779 , +-17107 , +19077 , +32259 , +-13423 , +27755 , +24237 , +25221 , +-8807 , +-20241 , +-22195 , +9867 , +-5549 , +17107 , +-7187 , +-17557 , +-9923 , +18861 , +23095 , +-25141 , +-3975 , +31063 , +-19793 , +29623 , +-8237 , +-6309 , +-5665 , +8001 , +-5591 , +12467 , +-2019 , +7567 , +-6795 , +2103 , +6589 , +-30087 , +18741 , +-14999 , +12745 , +-24417 , +873 , +3019 , +16187 , +3587 , +19473 , +8899 , +23727 , +-2787 , +12059 , +5605 , +17059 , +-3467 , +1247 , +13781 , +-15315 , +-317 , +-28389 , +4505 , +15919 , +-31373 , +103 , +-32647 , +28945 , +-30761 , +31785 , +-11191 , +-17159 , +9381 , +-29417 , +-13231 , +14473 , +23589 , +1063 , +24731 , +-26103 , +26811 , +-24055 , +-565 , +27439 , +-31739 , +13601 , +18811 , +32589 , +28783 , +26109 , +1813 , +9223 , +-24751 , +-5557 , +13603 , +1177 , +19327 , +22103 , +-1233 , +14203 , +24685 , +17663 , +-32752 , +28331 , +-31305 , +3627 , +16599 , +-15781 , +10055 , +-15421 , +11 , +3625 , +-11803 , +-21201 , +-6757 , +22751 , +-17323 , +-1725 , +-6367 , +16033 , +-11035 , +-8511 , +4299 , +-10835 , +11153 , +-7345 , +-14681 , +1419 , +4245 , +-32531 , +-27005 , +-14133 , +-16509 , +-7705 , +-19905 , +20801 , +-4387 , +-5283 , +-21847 , +-31057 , +7219 , +20013 , +-32049 , +-10231 , +-4943 , +-10641 , +-19487 , +-10451 , +31291 , +-20115 , +14725 , +-26861 , +-6905 , +-7649 , +16037 , +17549 , +437 , +-25573 , +-32041 , +-3723 , +31715 , +-17131 , +4137 , +2675 , +17735 , +7377 , +22915 , +28459 , +-22199 , +-5215 , +22901 , +-23307 , +-8933 , +-10411 , +-13931 , +7195 , +25677 , +11963 , +2641 , +-117 , +8681 , +-17519 , +-11435 , +-30957 , +28169 , +-29949 , +17489 , +17431 , +2029 , +23707 , +28255 , +24777 , +15513 , +-4161 , +-4657 , +18913 , +6635 , +-6227 , +-21361 , +-17703 , +1579 , +32227 , +25839 , +-23393 , +-27601 , +-17623 , +-757 , +-6451 , +-5141 , +28419 , +21145 , +21351 , +-24689 , +-25185 , +-28859 , +-2803 , +17685 , +-25505 , +-25213 , +4027 , +-21401 , +-27455 , +-10767 , +-11275 , +2537 , +-23073 , +32037 , +15495 , +-4707 , +23657 , +10767 , +3773 , +24241 , +-18155 , +-21307 , +29979 , +-3171 , +32157 , +-29211 , +11407 , +16059 , +-1995 , +-16791 , +-17359 , +26459 , +1415 , +-28669 , +-20619 , +18273 , +-32477 , +-29207 , +19179 , +-6827 , +-9093 , +20029 , +-19607 , +-23805 , +5219 , +-11299 , +-47 , +-1905 , +-17161 , +-26443 , +11589 , +5131 , +23589 , +-10073 , +28121 , +13717 , +-13667 , +13521 , +-13871 , +8169 , +-11451 , +18291 , +-29863 , +30079 , +-14025 , +16445 , +27833 , +23063 , +19517 , +8499 , +275 , +12517 , +-3139 , +-19467 , +20373 , +-12523 , +6201 , +-12381 , +6451 , +-1297 , +29511 , +1843 , +-16159 , +-28821 , +-12793 , +22597 , +20041 , +7241 , +30235 , +-3457 , +-31995 , +23211 , +-20193 , +-20637 , +31313 , +20009 , +-6493 , +21159 , +-13493 , +27245 , +-18271 , +11025 , +-23127 , +-27319 , +-15757 , +11205 , +-7957 , +23889 , +13907 , +5673 , +30237 , +15599 , +4425 , +-13259 , +23555 , +16897 , +7591 , +25423 , +15837 , +-3607 , +31749 , +3999 , +1177 , +-15827 , +-5451 , +32748 , +-21881 , +-629 , +-31817 , +-15889 , +20889 , +28047 , +10555 , +18227 , +5143 , +-24401 , +22671 , +8799 , +-30759 , +9445 , +-25695 , +5407 , +27643 , +-28993 , +20715 , +-31123 , +31001 , +-23301 , +503 , +-1675 , +-13307 , +-30557 , +79 , +7393 , +-7427 , +12705 , +-32521 , +2747 , +-23189 , +6099 , +-4507 , +-12091 , +28179 , +24749 , +-22275 , +-9911 , +-28719 , +26953 , +-4607 , +19573 , +19665 , +1283 , +7443 , +567 , +-18367 , +18573 , +5153 , +7309 , +31379 , +14731 , +-9753 , +-7577 , +-4051 , +15017 , +20197 , +-3339 , +-25949 , +-29643 , +7379 , +27013 , +23663 , +-18125 , +-25443 , +2521 , +30505 , +18681 , +-5417 , +3331 , +-15291 , +-29369 , +-7495 , +-22859 , +8257 , +-6949 , +14231 , +-9443 , +-32673 , +19083 , +25815 , +-17085 , +-21789 , +-30497 , +-21401 , +-21035 , +2505 , +-5591 , +-9287 , +-19829 , +-28679 , +-17125 , +3901 , +32245 , +10495 , +-31271 , +11341 , +16349 , +-21683 , +13219 , +18871 , +-10735 , +-15131 , +13015 , +-16729 , +30157 , +-9575 , +-19557 , +4129 , +25987 , +20929 , +-793 , +29951 , +-8387 , +15479 , +9257 , +10343 , +-19601 , +-8121 , +341 , +17083 , +-15277 , +3951 , +-18559 , +20769 , +-3649 , +-13167 , +-22025 , +25449 , +-29315 , +12525 , +13785 , +-14191 , +-4059 , +3359 , +2091 , +12729 , +18033 , +15433 , +26739 , +29597 , +12059 , +8667 , +20435 , +-24951 , +16687 , +18879 , +-23399 , +-23339 , +4837 , +-23783 , +29277 , +18395 , +-9987 , +19829 , +30361 , +-31887 , +13967 , +28815 , +-9795 , +12253 , +21867 , +5755 , +27853 , +4689 , +-8469 , +-32669 , +17265 , +5089 , +-4785 , +-4669 , +661 , +-10499 , +-29293 , +19995 , +-17539 , +25443 , +-5689 , +-10963 , +-21667 , +8355 , +-19479 , +-5717 , +-18577 , +-10487 , +-5829 , +26237 , +-623 , +-4323 , +-31207 , +-22931 , +20825 , +-22629 , +16983 , +21091 , +-595 , +31209 , +-4587 , +27169 , +-23845 , +25871 , +-30953 , +32629 , +-30415 , +22321 , +-24935 , +-25613 , +16407 , +28033 , +10165 , +-14033 , +-7771 , +17089 , +17959 , +-19597 , +-11589 , +1075 , +13753 , +24311 , +22427 , +-31467 , +-7669 , +26521 , +-11011 , +2195 , +18163 , +-15591 , +5547 , +-1463 , +12629 , +32203 , +27799 , +19763 , +30839 , +27087 , +2933 , +-18137 , +18401 , +14545 , +26065 , +-28977 , +-28247 , +-1995 , +-1885 , +23071 , +16723 , +26587 , +20085 , +2891 , +18217 , +9039 , +-26649 , +-8633 , +5139 , +5509 , +-20265 , +-18251 , +-25109 , +12045 , +-5643 , +13921 , +-31657 , +-10545 , +28375 , +7229 , +28195 , +3395 , +-24429 , +27091 , +14105 , +-17883 , +15577 , +-16065 , +1619 , +7343 , +-22137 , +23981 , +-6887 , +-10665 , +15559 , +20547 , +-4547 , +-30727 , +-9821 , +15271 , +-21019 , +31135 , +-18151 , +17903 , +-13837 , +17579 , +-18499 , +31007 , +-30001 , +-1891 , +-53 , +18971 , +23753 , +-19905 , +26555 , +32289 , +-7695 , +7519 , +23903 , +9921 , +-21405 , +-9969 , +-19073 , +-5031 , +14637 , +13909 , +14311 , +24325 , +17313 , +18787 , +16383 , +-31199 , +2351 , +-15017 , +18931 , +26163 , +-27209 , +-26009 , +-15309 , +-19081 , +-20373 , +-12633 , +-607 , +30399 , +-32485 , +-30413 , +-30693 , +-19709 , +-31207 , +-14351 , +-6249 , +2373 , +-3447 , +-18493 , +-6723 , +19733 , +3389 , +10053 , +25087 , +-5241 , +-22519 , +3069 , +-2513 , +20135 , +18337 , +-28131 , +18323 , +-2189 , +5099 , +-20815 , +23685 , +-31147 , +10457 , +-21413 , +-12663 , +27161 , +24517 , +-21871 , +12515 , +28009 , +10561 , +-30903 , +-31829 , +-9543 , +-28811 , +11069 , +2929 , +28369 , +-1801 , +-20327 , +25925 , +-11849 , +-15325 , +23609 , +12127 , +-12761 , +21227 , +-7837 , +7721 , +-101 , +-24771 , +-6155 , +-10779 , +11947 , +-4147 , +19755 , +24759 , +5145 , +-14983 , +5831 , +-26299 , +-17855 , +-26343 , +-28457 , +25041 , +13585 , +-32297 , +-29207 , +-55 , +-6019 , +23567 , +16831 , +29669 , +5507 , +-30563 , +-20859 , +9919 , +-6763 , +-9027 , +7319 , +-15897 , +-21349 , +-9637 , +-27481 , +-29311 , +-26263 , +-14091 , +-11133 , +10837 , +-29521 , +-14617 , +-18875 , +113 , +20095 , +27473 , +-32243 , +14901 , +-9671 , +4191 , +8765 , +-23563 , +-1783 , +24115 , +-19929 , +18447 , +-7459 , +11819 , +24403 , +8065 , +7645 , +24263 , +5417 , +-20739 , +21607 , +-20487 , +-5323 , +-6005 , +22909 , +16385 , +-12841 , +10649 , +5067 , +-16191 , +22909 , +-21099 , +-30961 , +-615 , +24665 , +19719 , +-19421 , +-13889 , +4771 , +-7897 , +-30877 , +-4333 , +16707 , +9207 , +-29259 , +13691 , +-19697 , +25811 , +-22541 , +6841 , +1163 , +-5735 , +29931 , +21189 , +2577 , +21553 , +-22053 , +-22367 , +11413 , +-6993 , +4443 , +22451 , +-18213 , +-4125 , +26851 , +30113 , +-26323 , +25209 , +-11073 , +-31581 , +29071 , +-22385 , +8831 , +-14753 , +-27009 , +-11833 , +-28165 , +26429 , +-10707 , +18919 , +23747 , +6725 , +-29653 , +-531 , +-19431 , +15727 , +-2135 , +17829 , +28015 , +7813 , +19503 , +27079 , +5457 , +30831 , +29909 , +7817 , +-24341 , +-16103 , +501 , +-13637 , +30203 , +24511 , +14703 , +-3237 , +329 , +25543 , +-16047 , +-23629 , +-27747 , +-11231 , +-8931 , +10733 , +-17091 , +12055 , +-19079 , +39 , +-8223 , +12967 , +-23955 , +14871 , +12075 , +-31395 , +-4077 , +20243 , +-10339 , +22439 , +5589 , +-26439 , +-31721 , +-27213 , +-10203 , +24059 , +-1589 , +-15937 , +19635 , +-15683 , +691 , +3835 , +14627 , +29675 , +24205 , +-11049 , +-15285 , +26643 , +-3499 , +-3359 , +-3609 , +-29575 , +-4557 , +15645 , +-7987 , +-18763 , +8703 , +-30503 , +17329 , +-19773 , +14383 , +29193 , +3151 , +-14943 , +3927 , +28955 , +-16085 , +31851 , +-5605 , +22871 , +30157 , +8163 , +-21075 , +-10325 , +-8855 , +-23393 , +-6467 , +2575 , +28715 , +28555 , +-13063 , +-14507 , +6883 , +-14573 , +-769 , +-20607 , +28987 , +18607 , +8409 , +-25431 , +-9605 , +15109 , +16117 , +-29629 , +-20303 , +5235 , +-6247 , +-26363 , +-13703 , +3641 , +-1827 , +7477 , +26409 , +7167 , +12581 , +-27255 , +-2671 , +8189 , +18457 , +23673 , +-21203 , +-19581 , +-14825 , +-10721 , +29149 , +23587 , +21043 , +9349 , +-1499 , +-31431 , +-20819 , +-899 , +-20515 , +5643 , +7139 , +-19703 , +17259 , +-929 , +22991 , +6941 , +27005 , +-31849 , +1 , +19463 , +-17603 , +-12223 , +25613 , +-6079 , +12557 , +22581 , +-14703 , +-825 , +12221 , +-20691 , +-351 , +4339 , +-24505 , +32731 , +23489 , +32469 , +2557 , +2429 , +-2457 , +-21497 , +10059 , +-1533 , +9957 , +15113 , +-4881 , +-877 , +23273 , +-13033 , +31655 , +-11085 , +373 , +27777 , +-2957 , +24023 , +-15017 , +14213 , +-22709 , +18297 , +-12775 , +25509 , +-27569 , +-6729 , +16263 , +12671 , +-18547 , +-4503 , +-20581 , +-5853 , +5935 , +31409 , +-13575 , +30451 , +3125 , +9503 , +-8211 , +-16141 , +-16981 , +-25535 , +-30761 , +19615 , +18025 , +-32321 , +10029 , +19793 , +32063 , +-4623 , +31727 , +-19705 , +-10309 , +28665 , +-3427 , +20933 , +24401 , +-7597 , +-1609 , +-18063 , +12581 , +-5123 , +2987 , +-10719 , +-32721 , +-31231 , +-22701 , +-3851 , +-28151 , +23949 , +-4373 , +10615 , +-20975 , +27287 , +9609 , +-151 , +30511 , +-27925 , +-15595 , +1319 , +-22513 , +-20029 , +22215 , +21107 , +-22067 , +-9245 , +-4079 , +-12327 , +-715 , +14385 , +17957 , +-3459 , +-4487 , +17611 , +21991 , +123 , +-29843 , +-8035 , +-20891 , +30137 , +21559 , +-3713 , +9165 , +-24253 , +-24947 , +-313 , +8429 , +4899 , +9071 , +-26523 , +20255 , +-3405 , +-20651 , +-7561 , +-13107 , +-10883 , +27891 , +7529 , +-21919 , +11917 , +-15767 , +-32129 , +-6723 , +-4527 , +14589 , +19711 , +-25539 , +27363 , +26453 , +18359 , +-21731 , +10483 , +22063 , +-18653 , +30343 , +-25331 , +22419 , +-2049 , +3829 , +32125 , +-14189 , +-21923 , +27963 , +-17243 , +-19073 , +-16061 , +-779 , +-15407 , +-10085 , +20153 , +11647 , +1685 , +-5283 , +25711 , +16753 , +-31075 , +-15841 , +-7991 , +5275 , +24587 , +10843 , +-32641 , +4207 , +-2481 , +867 , +3245 , +1797 , +-9857 , +-30319 , +-655 , +11409 , +-985 , +19471 , +26887 , +-6311 , +20909 , +-15107 , +-26799 , +-20949 , +27939 , +3125 , +4613 , +-21159 , +14495 , +-25471 , +-30417 , +27185 , +23825 , +-23727 , +25691 , +7411 , +29345 , +-11537 , +22563 , +-1721 , +-28287 , +12097 , +-10169 , +7481 , +23371 , +-13063 , +-16819 , +24241 , +5329 , +-1199 , +-883 , +-20633 , +-6021 , +-12225 , +-18985 , +20321 , +-5855 , +-28877 , +-28293 , +-31261 , +-4775 , +-7609 , +-23567 , +6381 , +-9379 , +24063 , +-15387 , +15157 , +32083 , +18301 , +-23597 , +10391 , +30263 , +5433 , +-30683 , +10515 , +28449 , +-24007 , +-3647 , +12869 , +5419 , +-29751 , +5413 , +-8359 , +-65 , +-20041 , +30209 , +-2169 , +6011 , +20739 , +32589 , +15113 , +-27273 , +-20195 , +28643 , +-20843 , +13105 , +-9315 , +29589 , +7505 , +-23851 , +22137 , +16579 , +2383 , +-6111 , +22717 , +4727 , +-15741 , +-22095 , +29121 , +22271 , +-9157 , +4837 , +6889 , +-5381 , +-18149 , +24107 , +11219 , +14591 , +25995 , +-24609 , +-22251 , +5547 , +30909 , +-5721 , +-6797 , +-20425 , +13335 , +24125 , +28059 , +28571 , +-26315 , +19925 , +-18863 , +5151 , +-20899 , +-3345 , +1339 , +-2709 , +-22153 , +-6227 , +-29693 , +-19147 , +14727 , +-5201 , +11807 , +15935 , +-22881 , +4715 , +-5885 , +26627 , +97 , +-3583 , +22235 , +5827 , +4847 , +-5479 , +17339 , +12317 , +23141 , +7729 , +-12955 , +15403 , +-21291 , +12547 , +1399 , +2839 , +-11595 , +27217 , +-29149 , +14131 , +-14877 , +19905 , +10605 , +-9323 , +-12523 , +17721 , +-19749 , +22307 , +14805 , +29489 , +31673 , +29757 , +-10507 , +17807 , +-32317 , +-13115 , +1423 , +-7939 , +30819 , +-15677 , +31343 , +-835 , +7279 , +-6799 , +32285 , +18191 , +-13735 , +6877 , +-9917 , +-5641 , +-12569 , +26111 , +10163 , +18591 , +27247 , +-24243 , +-13865 , +-29387 , +-369 , +1495 , +11435 , +7983 , +24163 , +-10533 , +-24519 , +-26055 , +-18115 , +2533 , +29835 , +23939 , +6109 , +17241 , +-27355 , +19347 , +-7127 , +-99 , +23295 , +-11607 , +29543 , +16543 , +-13063 , +-10863 , +2803 , +-26627 , +1753 , +-29447 , +22393 , +-6769 , +-325 , +-1713 , +-12631 , +-23927 , +24853 , +-749 , +-3215 , +4367 , +-17635 , +-18511 , +-2887 , +10317 , +-21545 , +14555 , +-24939 , +-27375 , +21367 , +9311 , +5631 , +-22815 , +-18069 , +24193 , +22289 , +-32369 , +24775 , +22735 , +-4675 , +27485 , +-15549 , +6013 , +-7939 , +-28791 , +-5451 , +-30919 , +18585 , +3435 , +-7937 , +15243 , +-31403 , +-21497 , +11921 , +11683 , +-27735 , +2611 , +8031 , +-27723 , +28927 , +-23781 , +1619 , +26837 , +2917 , +32619 , +14159 , +-17081 , +-19511 , +-5411 , +-4197 , +26465 , +-30033 , +1619 , +-6939 , +11481 , +-8343 , +-29075 , +-19791 , +-859 , +-1583 , +-20821 , +-8613 , +20811 , +18045 , +14581 , +-22139 , +21441 , +23931 , +6595 , +27413 , +-10559 , +-9335 , +24743 , +-22867 , +-15711 , +-31287 , +-19091 , +-25953 , +2475 , +-20483 , +-28233 , +31849 , +-17161 , +23869 , +5897 , +7083 , +22977 , +4911 , +-9877 , +9121 , +-6337 , +-10305 , +30331 , +-19687 , +-767 , +20825 , +20745 , +-32025 , +18875 , +-32351 , +18733 , +21225 , +-19793 , +4773 , +-14111 , +-10895 , +-23689 , +-20835 , +-745 , +-11961 , +-22945 , +23071 , +-27825 , +-19939 , +-8893 , +18645 , +-11339 , +16265 , +29411 , +9403 , +28593 , +-19851 , +-25413 , +16339 , +-8951 , +-7897 , +17755 , +-22437 , +-27279 , +-18007 , +-2237 , +-26743 , +4771 , +-15671 , +8241 , +12993 , +-8449 , +-9327 , +17667 , +5967 , +-28009 , +-3783 , +15887 , +-22373 , +5331 , +-7255 , +5105 , +-26391 , +-1407 , +20587 , +-27409 , +-23423 , +22641 , +31773 , +15047 , +-2177 , +-7545 , +4729 , +30989 , +13809 , +-20643 , +-2885 , +3077 , +-24925 , +30805 , +-12631 , +24563 , +16461 , +-20947 , +-22021 , +-22279 , +-18097 , +14879 , +14437 , +-15507 , +31205 , +17269 , +3069 , +29877 , +229 , +-11869 , +30273 , +9365 , +2801 , +-23847 , +17801 , +-22767 , +11311 , +3877 , +6395 , +11973 , +-13173 , +20481 , +-31987 , +-75 , +-417 , +1137 , +-19851 , +-1369 , +10171 , +18843 , +-9821 , +-26361 , +-2545 , +16349 , +3259 , +28971 , +-27539 , +21605 , +-12791 , +-9413 , +-25539 , +10055 , +255 , +-12667 , +-18313 , +26139 , +31655 , +-28851 , +29529 , +29457 , +-4449 , +17715 , +9881 , +12423 , +23439 , +4607 , +-31185 , +-14039 , +-11745 , +-16129 , +-17033 , +-13189 , +-21643 , +-22819 , +-26885 , +30723 , +-983 , +-13835 , +-22881 , +-31535 , +29883 , +-5321 , +-4511 , +20893 , +26769 , +-30865 , +-2681 , +-16027 , +13161 , +26921 , +-13721 , +-22917 , +-19115 , +-7417 , +-6515 , +4645 , +7471 , +19095 , +28033 , +24747 , +-18025 , +-13401 , +-16905 , +23037 , +2147 , +11305 , +-12921 , +16065 , +-17247 , +-26497 , +18159 , +6633 , +-3321 , +4181 , +-7491 , +11991 , +19691 , +-29693 , +-3439 , +-9239 , +10689 , +29269 , +-26931 , +-13929 , +-18675 , +30449 , +-26923 , +-16891 , +3807 , +31017 , +21445 , +-4823 , +7371 , +31571 , +-12891 , +7503 , +-32419 , +19103 , +13091 , +30789 , +11283 , +-4235 , +-3123 , +24799 , +-7207 , +32329 , +-13115 , +9509 , +30201 , +24817 , +-14335 , +-6953 , +-15463 , +-20351 , +-23047 , +-31601 , +26037 , +-18527 , +-22045 , +1373 , +8079 , +13673 , +16493 , +6353 , +-10321 , +30897 , +30965 , +18851 , +20307 , +-5139 , +-14019 , +-28481 , +20591 , +10635 , +5029 , +-20765 , +-30173 , +12481 , +26601 , +8885 , +-11347 , +-11543 , +30283 , +4957 , +3559 , +-3747 , +11611 , +1945 , +23361 , +-23607 , +31267 , +-16039 , +-6609 , +-8443 , +-23833 , +5589 , +-4561 , +-19343 , +13397 , +6697 , +21301 , +-15933 , +-1723 , +31841 , +22437 , +-5777 , +-2837 , +24867 , +-12075 , +-5267 , +-10347 , +-25159 , +32245 , +-2405 , +-6691 , +-22869 , +-16999 , +-13671 , +-13723 , +2785 , +22941 , +-32235 , +18955 , +-11479 , +-24145 , +-25171 , +21155 , +-24987 , +-29635 , +26433 , +23605 , +-11763 , +5617 , +17875 , +-27477 , +-18597 , +-26715 , +6609 , +-12787 , +-9007 , +19165 , +14845 , +-22723 , +-27553 , +-19259 , +10425 , +-6359 , +-6667 , +12189 , +-26139 , +-32123 , +-12649 , +19131 , +-7881 , +17413 , +9215 , +14591 , +24849 , +-28909 , +-2897 , +1481 , +4565 , +13575 , +-17275 , +-14215 , +-17975 , +-11039 , +17883 , +-29091 , +-4767 , +-17027 , +-28901 , +13103 , +28703 , +-13743 , +-29479 , +-8183 , +3567 , +12957 , +8293 , +26853 , +-31503 , +-15573 , +6893 , +16523 , +-26655 , +31365 , +-23285 , +15117 , +-7967 , +-91 , +-7451 , +-10557 , +31963 , +-5319 , +11453 , +17341 , +10071 , +23381 , +-19437 , +-7745 , +-8497 , +-13911 , +-4813 , +27831 , +-22135 , +-25539 , +-27305 , +-28749 , +-27919 , +26793 , +-21199 , +5729 , +31087 , +25033 , +16403 , +29947 , +-15169 , +-6151 , +20347 , +-8501 , +-25395 , +-19511 , +-17611 , +-23783 , +-18173 , +-27845 , +32231 , +2221 , +24621 , +12663 , +5681 , +24507 , +-20277 , +-7935 , +29769 , +-32153 , +-13851 , +-8075 , +17415 , +31667 , +-5013 , +4543 , +-5243 , +-29439 , +11531 , +-25651 , +5687 , +18943 , +-12667 , +28369 , +9345 , +809 , +-9083 , +8943 , +22481 , +14015 , +7933 , +10623 , +4913 , +16441 , +-515 , +-14151 , +2151 , +-447 , +28165 , +-9739 , +-22133 , +-22737 , +31973 , +-15769 , +-18663 , +-31751 , +-26863 , +-25013 , +17041 , +-13901 , +7543 , +5799 , +-629 , +18819 , +25567 , +-9857 , +11595 , +12055 , +-20551 , +11401 , +6887 , +-31327 , +20345 , +-28045 , +22477 , +-17585 , +25203 , +-1399 , +-20763 , +-9407 , +26925 , +29431 , +6699 , +-18947 , +13881 , +-10875 , +-27457 , +-20363 , +22415 , +26305 , +8583 , +29035 , +-28571 , +-8247 , +-8643 , +9593 , +31617 , +-9617 , +31499 , +-28285 , +-4583 , +6149 , +-4439 , +-21583 , +13097 , +-25977 , +-16663 , +-3359 , +-18621 , +2135 , +-18983 , +15529 , +15603 , +21109 , +23383 , +12741 , +12689 , +5437 , +2857 , +12565 , +15001 , +-21615 , +-105 , +-12011 , +-27775 , +27809 , +10367 , +-18479 , +21529 , +3095 , +9969 , +353 , +14167 , +-27435 , +17733 , +-4897 , +-1351 , +-2515 , +-15433 , +2015 , +-4583 , +-25709 , +20851 , +-28565 , +-13305 , +1761 , +2625 , +17779 , +29343 , +-6913 , +-12155 , +24011 , +-27427 , +-27351 , +23535 , +-8797 , +-897 , +-25953 , +-11137 , +633 , +29783 , +-3871 , +21035 , +-611 , +-3297 , +-17817 , +6381 , +-19175 , +7899 , +16851 , +-5787 , +-15559 , +-16215 , +-14929 , +15847 , +27767 , +16667 , +1703 , +-13289 , +-15367 , +-15089 , +4155 , +8965 , +-18809 , +779 , +13305 , +-16959 , +13317 , +26893 , +-20685 , +25199 , +12133 , +-21783 , +-3263 , +9707 , +-21207 , +20771 , +2091 , +-5167 , +-26541 , +24639 , +489 , +-17627 , +-27169 , +-20319 , +25 , +-16545 , +-28995 , +3803 , +-20421 , +19979 , +10311 , +-17261 , +-13725 , +-14121 , +-7367 , +27091 , +-32655 , +-19397 , +6441 , +16089 , +22479 , +-9601 , +-28543 , +3715 , +26021 , +-11425 , +-8459 , +18709 , +26001 , +-14305 , +21113 , +-14441 , +-23841 , +-13273 , +-26431 , +1967 , +11331 , +-24047 , +-8915 , +-4101 , +18957 , +17739 , +-27315 , +-19235 , +-20763 , +4141 , +-19503 , +-2587 , +23299 , +-10609 , +31235 , +-21609 , +-22047 , +-13091 , +-24641 , +-557 , +-32129 , +-27721 , +2543 , +-25949 , +8715 , +16393 , +-14467 , +-23153 , +31015 , +-18535 , +-29491 , +-10361 , +-27749 , +14889 , +26037 , +-6361 , +649 , +28425 , +-10759 , +-11877 , +-16079 , +-12489 , +8253 , +7153 , +-29667 , +-15381 , +-5249 , +-23307 , +8923 , +20921 , +-241 , +8073 , +27709 , +-22489 , +19723 , +-12933 , +-2809 , +28093 , +847 , +-27941 , +-16081 , +8363 , +-9483 , +-1577 , +-6255 , +25559 , +24137 , +16147 , +-4061 , +-28555 , +23871 , +-389 , +27833 , +25635 , +18543 , +-26457 , +-15313 , +9089 , +-21873 , +-5981 , +-22485 , +2375 , +30817 , +25175 , +11599 , +23003 , +28469 , +12625 , +-523 , +-3219 , +14815 , +28713 , +-24727 , +-19823 , +-27607 , +4175 , +16789 , +-31923 , +9429 , +-30101 , +4427 , +30397 , +17931 , +-4303 , +-31509 , +-19165 , +29783 , +28855 , +-25685 , +-23423 , +-25565 , +-943 , +-30911 , +7089 , +-605 , +-791 , +-18395 , +-1533 , +-8353 , +-8749 , +-15289 , +-1207 , +-14565 , +26151 , +8257 , +8311 , +29017 , +-31585 , +8985 , +-31557 , +16203 , +-23581 , +19565 , +-2285 , +21327 , +8043 , +17719 , +12389 , +5093 , +-3887 , +-27907 , +-487 , +19753 , +11695 , +30093 , +14637 , +-22327 , +28145 , +-6351 , +-7727 , +-19335 , +-19793 , +14187 , +14207 , +12021 , +-6775 , +14381 , +9613 , +-11405 , +-30601 , +30091 , +-9137 , +23451 , +-20951 , +28669 , +-4443 , +-4101 , +-11559 , +20751 , +-13285 , +-16631 , +-21083 , +4763 , +-4231 , +-3435 , +-28051 , +-28543 , +-26137 , +-17473 , +31775 , +31969 , +29299 , +-21133 , +22425 , +-20783 , +-7617 , +7517 , +-22787 , +-15465 , +-31483 , +-15509 , +5511 , +-30117 , +-31175 , +20403 , +5101 , +12905 , +17061 , +12029 , +5417 , +-19487 , +1651 , +13747 , +-31771 , +27375 , +16339 , +26963 , +2107 , +23947 , +-497 , +-24457 , +13861 , +9125 , +5405 , +12603 , +15423 , +-5653 , +-16965 , +26179 , +-21709 , +-30989 , +2573 , +-3539 , +-4737 , +6907 , +1709 , +6533 , +-30755 , +12835 , +-8127 , +-13495 , +-17905 , +-7907 , +-6753 , +24529 , +-26563 , +-11155 , +-16809 , +13909 , +13515 , +-13797 , +-21033 , +-5921 , +-3409 , +28143 , +15097 , +20163 , +-26543 , +4135 , +5155 , +1431 , +15067 , +11951 , +-30761 , +-18261 , +-26095 , +18649 , +27093 , +-8445 , +1197 , +-2663 , +-17237 , +10187 , +23865 , +-19403 , +-2099 , +19797 , +22369 , +28547 , +16949 , +-31093 , +-31287 , +11171 , +31087 , +20203 , +20593 , +-10707 , +23867 , +-17155 , +27519 , +-20235 , +-18523 , +8009 , +-6491 , +20283 , +-9837 , +6101 , +27881 , +-25243 , +17383 , +-4583 , +-13045 , +-5317 , +-10989 , +20341 , +25177 , +28823 , +21295 , +13871 , +30205 , +17571 , +-21863 , +12005 , +12519 , +16273 , +-18171 , +-19321 , +13847 , +-16689 , +-749 , +-9517 , +32121 , +-15417 , +627 , +-185 , +-30911 , +25865 , +-7569 , +-18279 , +32697 , +2577 , +-20209 , +-17225 , +27559 , +27001 , +11943 , +-2761 , +-2789 , +-15949 , +-27147 , +31311 , +-3899 , +17467 , +-8519 , +-21423 , +13271 , +11093 , +19659 , +9127 , +-11691 , +29255 , +-23631 , +-20677 , +24049 , +-22519 , +-10565 , +6531 , +15711 , +-11129 , +-29283 , +-5141 , +-19405 , +-6069 , +21885 , +-5935 , +-19661 , +-20795 , +-10601 , +29697 , +2353 , +-17671 , +-6579 , +-24157 , +3173 , +18107 , +-12863 , +9155 , +21573 , +31841 , +-25361 , +-12745 , +-25641 , +8963 , +-7615 , +-5853 , +25747 , +9521 , +-24913 , +2541 , +29103 , +-5595 , +-12725 , +-21833 , +-19453 , +-1661 , +23907 , +14421 , +-16805 , +-7795 , +-7659 , +-12607 , +23115 , +-10277 , +-3479 , +23583 , +21905 , +3219 , +28387 , +25127 , +8165 , +10275 , +-26205 , +3625 , +20817 , +-5261 , +20985 , +-8327 , +-20207 , +27305 , +19583 , +-27531 , +-11039 , +-9645 , +-24661 , +-27153 , +-3875 , +26411 , +31985 , +-26319 , +-4143 , +4163 , +28241 , +-20375 , +27673 , +-1081 , +-3977 , +-32337 , +-24329 , +15925 , +-16051 , +-9105 , +-5021 , +-29685 , +-17643 , +25963 , +-1679 , +-12791 , +-27643 , +-28369 , +11035 , +4069 , +23129 , +-23285 , +24487 , +-15997 , +1259 , +-2429 , +-23441 , +-15695 , +-4011 , +8535 , +-3515 , +12627 , +-24455 , +27625 , +-30131 , +29231 , +-24919 , +4677 , +2887 , +27663 , +-13265 , +-20597 , +-10381 , +28041 , +375 , +32241 , +-7449 , +-19149 , +20887 , +-23243 , +-32157 , +5203 , +-13715 , +20381 , +21165 , +-23515 , +2365 , +-17053 , +-12185 , +1413 , +31681 , +3767 , +-18327 , +9009 , +-23105 , +-975 , +-14189 , +-4479 , +17197 , +13777 , +-1743 , +3729 , +-24899 , +-24471 , +-14653 , +-1521 , +-2823 , +10663 , +-23453 , +29537 , +15325 , +27259 , +11925 , +-8349 , +9965 , +-12259 , +13989 , +28325 , +-16431 , +-31875 , +15993 , +-28393 , +27491 , +-14529 , +31977 , +-21427 , +-19629 , +1073 , +671 , +-29651 , +-21451 , +15425 , +5989 , +-31187 , +20515 , +7165 , +26625 , +-14581 , +-23095 , +25215 , +7317 , +-15613 , +3079 , +-10255 , +28517 , +16519 , +-32247 , +-30085 , +-9151 , +-2697 , +17365 , +-30267 , +-32685 , +11993 , +-27795 , +-10013 , +-15751 , +31507 , +1635 , +-12583 , +-9187 , +-12637 , +12273 , +-25207 , +23187 , +6993 , +-111 , +14131 , +12513 , +-11793 , +-21481 , +19049 , +29229 , +18059 , +-31927 , +-29563 , +19585 , +28461 , +30191 , +2727 , +23599 , +-2807 , +-18309 , +-18137 , +-4187 , +4153 , +20493 , +-1649 , +21445 , +9719 , +-7137 , +20247 , +-16191 , +-24235 , +-21361 , +-1643 , +-149 , +-403 , +-11207 , +-20739 , +24337 , +-32729 , +10263 , +11093 , +5083 , +-30617 , +27343 , +-12503 , +-27241 , +2759 , +9425 , +1169 , +5917 , +4555 , +18673 , +-23915 , +-20961 , +-12631 , +-31371 , +1845 , +17281 , +11113 , +-26181 , +8157 , +-7111 , +22449 , +-30657 , +6231 , +-30051 , +18419 , +-695 , +-6069 , +-1983 , +-24791 , +-15885 , +30513 , +-18353 , +-1271 , +-27703 , +-28977 , +-7589 , +6849 , +14559 , +21543 , +-19009 , +-10193 , +10345 , +32511 , +-23183 , +27541 , +-24619 , +1989 , +-5029 , +-3627 , +31841 , +-31717 , +16949 , +-21209 , +-20171 , +-5697 , +-14119 , +-1967 , +-19981 , +-4083 , +-13791 , +25695 , +-22047 , +-14351 , +24121 , +-1827 , +-10391 , +25185 , +-28037 , +3727 , +-7097 , +-675 , +10435 , +-17245 , +-28143 , +12115 , +-30901 , +20593 , +-27813 , +10543 , +-3839 , +-14417 , +-5819 , +26305 , +-24989 , +-15063 , +-25189 , +-31299 , +-12593 , +-2057 , +12647 , +31537 , +27233 , +27965 , +-26611 , +-8319 , +19531 , +-15271 , +5855 , +-30507 , +-12889 , +-16993 , +-7879 , +11295 , +-22313 , +7065 , +-14053 , +15493 , +-12963 , +20141 , +-9159 , +-16029 , +15399 , +-7323 , +17815 , +23229 , +-31625 , +11045 , +19367 , +11327 , +-1743 , +5975 , +-15661 , +-6487 , +14001 , +-16591 , +-13145 , +-22573 , +4401 , +-30745 , +15193 , +-5863 , +-31857 , +26467 , +29159 , +13407 , +-18769 , +14717 , +6327 , +-10367 , +-18089 , +-24651 , +32413 , +20047 , +123 , +25449 , +-377 , +-25853 , +18463 , +-11637 , +16773 , +17721 , +-4949 , +3805 , +-19095 , +14183 , +21699 , +-14421 , +4065 , +13013 , +-31843 , +22011 , +13831 , +4635 , +27619 , +-19639 , +24705 , +-28149 , +6905 , +17091 , +-11245 , +-9927 , +21737 , +-6915 , +1721 , +30181 , +-18259 , +20009 , +-30397 , +2687 , +1291 , +5835 , +-29339 , +24727 , +-27151 , +32511 , +24663 , +6741 , +-19901 , +23581 , +-19989 , +-17797 , +-15807 , +10499 , +29 , +15053 , +1619 , +-20287 , +-203 , +-5865 , +-6555 , +19419 , +22111 , +-15715 , +29125 , +10229 , +-30533 , +1557 , +10093 , +-28139 , +25339 , +13347 , +-24853 , +-17577 , +-14983 , +13899 , +10671 , +-4057 , +8911 , +-7063 , +1251 , +-17931 , +-29965 , +-24399 , +13257 , +-7313 , +-25915 , +16927 , +-25969 , +-10435 , +10293 , +1391 , +29091 , +20785 , +717 , +-17253 , +-22121 , +-9719 , +-24363 , +-2865 , +22379 , +1437 , +4321 , +19167 , +-16015 , +-5219 , +2033 , +-22973 , +9369 , +-11575 , +25601 , +-28015 , +-13739 , +-31069 , +-1237 , +28523 , +-30999 , +20399 , +3893 , +-20735 , +14407 , +1579 , +15791 , +-9467 , +23907 , +14137 , +17549 , +-26585 , +24081 , +-11091 , +29495 , +24579 , +-25769 , +26419 , +8229 , +10659 , +-8119 , +15119 , +-1285 , +-18317 , +19291 , +32595 , +-27877 , +-13893 , +18501 , +-12393 , +-5439 , +-10091 , +-19889 , +8245 , +28313 , +-20383 , +-18645 , +-31493 , +10709 , +-31287 , +-28073 , +-13725 , +-28977 , +-12755 , +-18203 , +22865 , +-21489 , +-29281 , +-29213 , +23877 , +9717 , +21341 , +14117 , +-23269 , +-13113 , +-25401 , +-21847 , +13877 , +10061 , +-10535 , +-29593 , +2627 , +-13849 , +-18913 , +-2903 , +-4239 , +-11743 , +7475 , +-18709 , +797 , +24279 , +18859 , +16683 , +-16613 , +23743 , +32671 , +-21567 , +4449 , +32653 , +-5227 , +4539 , +30277 , +-16509 , +-3329 , +-13899 , +-29391 , +13193 , +-21709 , +-26831 , +8161 , +-24629 , +-20773 , +27751 , +5143 , +-28469 , +2557 , +-11093 , +16335 , +23295 , +29795 , +-24775 , +-26621 , +-10525 , +-28005 , +-7535 , +-20011 , +12691 , +30061 , +-4013 , +3665 , +-22043 , +4053 , +20881 , +10399 , +-28163 , +-9351 , +25515 , +-16703 , +28011 , +25507 , +-21085 , +19653 , +-31809 , +-4431 , +-31239 , +12927 , +-16481 , +-483 , +8451 , +31683 , +12899 , +-8989 , +-24639 , +-15589 , +5161 , +-2937 , +14139 , +9983 , +-26505 , +8327 , +2127 , +-13937 , +28481 , +-18353 , +-16361 , +-11577 , +19093 , +-30789 , +-26445 , +27965 , +16547 , +28167 , +-11601 , +-19119 , +25183 , +-9397 , +16075 , +4847 , +24211 , +-7059 , +-3999 , +-2629 , +-30341 , +9635 , +-20425 , +27607 , +8413 , +11105 , +18389 , +-29941 , +9371 , +-26149 , +15715 , +9357 , +-25641 , +-13581 , +6137 , +-17619 , +-24967 , +6837 , +-15231 , +13331 , +-1187 , +-26029 , +13061 , +14839 , +-11563 , +24983 , +-15219 , +-13611 , +-555 , +14047 , +-24203 , +-6103 , +-26247 , +-14959 , +-28601 , +-7773 , +-28887 , +6937 , +25873 , +12903 , +28977 , +-23971 , +-24259 , +26807 , +-31791 , +21935 , +23531 , +4157 , +19163 , +24407 , +2753 , +5813 , +29641 , +-8077 , +17237 , +-23771 , +29783 , +5767 , +3309 , +-10333 , +-19051 , +-26781 , +-9489 , +30075 , +-23669 , +-9311 , +-14427 , +-9229 , +31043 , +-12385 , +10145 , +22915 , +8553 , +-23815 , +3473 , +18307 , +869 , +-29065 , +-10599 , +-6037 , +5355 , +-14193 , +22311 , +-32625 , +2073 , +24667 , +-16305 , +-24245 , +-4591 , +14091 , +-10849 , +7877 , +9733 , +-12311 , +-29825 , +-22495 , +-3869 , +11967 , +-23041 , +31287 , +-32425 , +31971 , +28723 , +9423 , +-8079 , +-21343 , +9229 , +-9637 , +32447 , +-11465 , +6839 , +16935 , +-13865 , +29007 , +23905 , +17685 , +-24963 , +25079 , +-20829 , +-13093 , +-4301 , +-22509 , +-23471 , +-4689 , +30549 , +-11681 , +-5675 , +29323 , +-11601 , +11741 , +17155 , +17371 , +-11883 , +32467 , +26485 , +-24387 , +24955 , +30787 , +20065 , +-23885 , +-7665 , +-22047 , +753 , +989 , +16081 , +7303 , +-26339 , +-24649 , +-23261 , +21817 , +23297 , +-22973 , +12015 , +-2417 , +-14669 , +-1583 , +22965 , +-18249 , +29857 , +-20693 , +-24031 , +-4117 , +32357 , +10323 , +7215 , +22883 , +32283 , +-15941 , +24503 , +26323 , +-16835 , +-30215 , +-24183 , +-16285 , +-19973 , +-1023 , +20743 , +13607 , +19983 , +13281 , +4669 , +-11761 , +23065 , +-27149 , +27765 , +22381 , +21109 , +24729 , +1363 , +-15133 , +-3435 , +8303 , +-16279 , +13273 , +-45 , +32527 , +-25773 , +-18305 , +27859 , +25657 , +-25007 , +-32451 , +27987 , +-7779 , +-18089 , +-4943 , +-28029 , +-7935 , +-6741 , +-12771 , +-30747 , +3335 , +25593 , +-26515 , +-30563 , +-5027 , +28403 , +-22623 , +9545 , +-22665 , +14943 , +24783 , +29277 , +28871 , +-26955 , +24725 , +14077 , +1915 , +4405 , +28697 , +13389 , +19625 , +-6017 , +30837 , +7503 , +25361 , +-21073 , +11447 , +22329 , +20815 , +-5653 , +-23971 , +6735 , +-24937 , +-24439 , +-28609 , +2873 , +-7697 , +1435 , +27671 , +-6949 , +-17445 , +16651 , +7787 , +19117 , +12965 , +-27083 , +-31471 , +23443 , +-5877 , +-14337 , +31775 , +7481 , +10105 , +4461 , +-23193 , +22499 , +12227 , +-30021 , +-22935 , +-1331 , +-11431 , +21241 , +5331 , +-24323 , +-15357 , +22045 , +-13961 , +20129 , +-26855 , +1947 , +-11839 , +-291 , +-3273 , +-5753 , +-18517 , +6705 , +-8073 , +14365 , +22591 , +27973 , +-19667 , +-28187 , +133 , +-18361 , +-30439 , +-2995 , +2307 , +28351 , +-11997 , +-6991 , +-22605 , +-16401 , +-10865 , +7685 , +12401 , +32671 , +-16199 , +-25885 , +31749 , +1921 , +5195 , +21541 , +-21105 , +-22273 , +2809 , +-29695 , +3707 , +-14435 , +-9043 , +-617 , +14603 , +13251 , +23891 , +-14057 , +18743 , +-8665 , +-4613 , +29773 , +19517 , +31637 , +14499 , +-10307 , +-22907 , +12623 , +-20895 , +20541 , +-22489 , +-7707 , +16425 , +3339 , +2009 , +12941 , +18935 , +-11671 , +31855 , +-7949 , +10385 , +2217 , +11471 , +-32355 , +29113 , +28633 , +11877 , +16061 , +18155 , +20421 , +-13783 , +-20599 , +-17779 , +31903 , +-16381 , +24593 , +-16463 , +2063 , +16595 , +8605 , +-25535 , +-2351 , +-10523 , +-17535 , +21957 , +-11577 , +-2845 , +5233 , +4235 , +29077 , +25427 , +27749 , +-9873 , +-14413 , +17555 , +-16667 , +-11767 , +8207 , +-6335 , +-6683 , +14181 , +-28643 , +8007 , +-27363 , +15167 , +113 , +23875 , +-14873 , +10173 , +-24103 , +15497 , +-21623 , +-14947 , +9973 , +-16487 , +-14305 , +31993 , +-26041 , +-3311 , +14817 , +10361 , +10457 , +12077 , +-9975 , +4869 , +-18101 , +-20553 , +15907 , +6157 , +-22679 , +-17781 , +18663 , +24113 , +31823 , +3201 , +16275 , +-23421 , +-1291 , +-15121 , +7875 , +-26057 , +22859 , +-30821 , +12741 , +14567 , +-557 , +3381 , +-29839 , +-26309 , +-26183 , +-9643 , +30603 , +14893 , +-2201 , +21737 , +31883 , +12993 , +21921 , +-4049 , +1541 , +17975 , +-22759 , +-22731 , +20341 , +21185 , +-29043 , +32203 , +-22627 , +4807 , +28505 , +16375 , +-23463 , +-22383 , +27283 , +14325 , +24317 , +-4981 , +-24415 , +4777 , +20777 , +-2571 , +-28849 , +-21857 , +-5601 , +-10725 , +-7057 , +-3721 , +29855 , +-491 , +-25369 , +-20503 , +25919 , +18165 , +-14257 , +21551 , +-22207 , +5251 , +-14073 , +-30959 , +3559 , +-30085 , +26831 , +-16567 , +22615 , +19515 , +-26141 , +-29815 , +9699 , +-16643 , +15499 , +-13595 , +11507 , +18075 , +-16071 , +-29729 , +-2483 , +29875 , +-225 , +-13877 , +-22797 , +-23953 , +5963 , +-16173 , +-3457 , +-4937 , +-17351 , +4201 , +-12809 , +2793 , +-18965 , +25671 , +-1245 , +-2031 , +-1401 , +-9255 , +1131 , +-6495 , +13161 , +-6075 , +-16087 , +30381 , +1729 , +-10023 , +-1405 , +-22885 , +-603 , +-12795 , +18629 , +30305 , +24233 , +19153 , +-16073 , +-19137 , +-11007 , +7391 , +-29579 , +-3603 , +15369 , +-11565 , +-693 , +1375 , +26475 , +31065 , +16387 , +12277 , +16303 , +-10605 , +14921 , +16695 , +2903 , +-9187 , +-19589 , +-15865 , +15477 , +-30859 , +23941 , +-26267 , +-25917 , +-5889 , +-10697 , +9113 , +8765 , +-30339 , +14619 , +13301 , +28211 , +-6659 , +22993 , +-1783 , +2285 , +14939 , +16105 , +15193 , +30645 , +21047 , +-2763 , +-4453 , +23415 , +-26519 , +21407 , +-29333 , +32219 , +7421 , +-14451 , +14207 , +8919 , +-13913 , +-15955 , +2667 , +30405 , +31935 , +-9389 , +-21301 , +28937 , +17083 , +19533 , +-31741 , +789 , +26141 , +-14013 , +-29575 , +-5097 , +-29195 , +25221 , +19527 , +2299 , +-23851 , +31591 , +-10125 , +30995 , +-19893 , +29213 , +25773 , +28455 , +-30505 , +4109 , +21893 , +1813 , +14945 , +23209 , +19739 , +-2085 , +20791 , +-9015 , +10851 , +31293 , +-9347 , +129 , +29399 , +15319 , +3885 , +-28291 , +7855 , +-18763 , +-17267 , +-51 , +16277 , +-14997 , +18209 , +31565 , +31211 , +-13393 , +23849 , +32627 , +-14225 , +19307 , +9627 , +-6231 , +-32123 , +15967 , +7315 , +9255 , +7397 , +3123 , +22097 , +-22711 , +-25387 , +29963 , +24753 , +9061 , +13795 , +18601 , +31519 , +-20181 , +2583 , +16889 , +23829 , +30321 , +-31561 , +-8393 , +17161 , +-6763 , +18291 , +-29061 , +31219 , +11601 , +8735 , +1749 , +8505 , +-3819 , +3315 , +9705 , +23341 , +-7717 , +-25285 , +10751 , +-23549 , +20355 , +-4977 , +-24413 , +-30901 , +19115 , +27283 , +-7753 , +27621 , +28415 , +-28379 , +28435 , +-20869 , +-4577 , +-3299 , +4239 , +-15745 , +-3347 , +-25221 , +1193 , +-28265 , +-2713 , +17199 , +7575 , +-11873 , +5887 , +11069 , +8925 , +-30433 , +8051 , +22923 , +20333 , +31291 , +12841 , +-5629 , +17459 , +-21449 , +-11265 , +5723 , +18231 , +-13463 , +22953 , +-8631 , +10033 , +-26701 , +22155 , +-13773 , +-25695 , +6515 , +9225 , +-16267 , +31079 , +-11001 , +6501 , +25867 , +-27681 , +-19263 , +-29673 , +-1067 , +-23951 , +-7849 , +12447 , +17733 , +687 , +16615 , +-3097 , +19871 , +-20755 , +-11161 , +-6893 , +-22869 , +16725 , +-21599 , +18395 , +1009 , +23427 , +-22615 , +26467 , +-20115 , +19101 , +-15403 , +16791 , +-9009 , +16359 , +7475 , +-23811 , +10535 , +-2593 , +28811 , +-13555 , +-31447 , +6609 , +18119 , +12559 , +-17445 , +20979 , +-30727 , +-32399 , +-18477 , +14335 , +-21301 , +27543 , +-3857 , +8259 , +18043 , +22593 , +-883 , +1341 , +5455 , +-24489 , +-18375 , +28599 , +26003 , +23623 , +1785 , +-19623 , +-5365 , +25563 , +-26383 , +22469 , +-11537 , +-26991 , +-19031 , +1581 , +17503 , +1139 , +-32581 , +-11413 , +1889 , +3955 , +-20207 , +16027 , +-30125 , +7485 , +12955 , +-17361 , +-539 , +-3697 , +-21875 , +9609 , +-16491 , +18713 , +22025 , +-6887 , +-13663 , +-13111 , +15205 , +14059 , +26495 , +-2639 , +9691 , +21955 , +-11811 , +-1709 , +25541 , +-4937 , +3343 , +22139 , +-16555 , +-23225 , +-24817 , +6817 , +-22075 , +10735 , +27117 , +30641 , +4383 , +30025 , +23505 , +-15759 , +-10143 , +-14947 , +11627 , +29013 , +27211 , +3321 , +-6421 , +13261 , +24193 , +13775 , +25469 , +-17871 , +-22189 , +5129 , +-29885 , +17923 , +19951 , +23199 , +31687 , +-25895 , +2841 , +28085 , +22257 , +26535 , +-1437 , +26925 , +-3955 , +-16217 , +-26137 , +13253 , +4655 , +-15973 , +14459 , +-2395 , +-29249 , +-3907 , +15471 , +-11901 , +-10653 , +31237 , +15549 , +9011 , +22521 , +-9465 , +25801 , +16069 , +17685 , +5969 , +6805 , +-6893 , +4981 , +3385 , +24441 , +23271 , +24315 , +825 , +-7333 , +29573 , +27423 , +1483 , +16999 , +26575 , +-1297 , +11707 , +25931 , +-11823 , +-18555 , +26369 , +31717 , +-23321 , +-8969 , +-12259 , +-30069 , +31305 , +26079 , +18919 , +431 , +2599 , +27967 , +20461 , +22569 , +10565 , +-245 , +-20147 , +8163 , +8971 , +3865 , +16901 , +-29413 , +-14299 , +-12651 , +7377 , +-6131 , +2455 , +6145 , +-29311 , +-7875 , +30803 , +10665 , +15315 , +16415 , +-32425 , +26267 , +-20793 , +-7079 , +-16833 , +22049 , +-16259 , +-28301 , +12897 , +-26189 , +6793 , +32023 , +-13213 , +4475 , +21191 , +6089 , +1107 , +-6339 , +-16197 , +2067 , +-4545 , +-18465 , +-23707 , +-12213 , +-26289 , +-27821 , +-20579 , +5829 , +4955 , +2845 , +-24865 , +2187 , +-5885 , +1853 , +-10571 , +-12649 , +31303 , +-26195 , +-16259 , +-29307 , +-1117 , +-30623 , +-5679 , +-6189 , +31647 , +-14929 , +-31405 , +31383 , +-15123 , +-28841 , +25611 , +19635 , +29953 , +27627 , +-197 , +-22385 , +7973 , +-16679 , +-21827 , +22609 , +-11241 , +10961 , +-30759 , +-17253 , +-6631 , +31435 , +20627 , +-19019 , +16785 , +18807 , +-27755 , +-10411 , +12829 , +7993 , +30841 , +-8499 , +-5079 , +16029 , +-23387 , +-7231 , +-19701 , +-10411 , +22693 , +15213 , +-3171 , +-10323 , +24065 , +-31159 , +11085 , +5247 , +-8811 , +-8109 , +-3143 , +-77 , +-18835 , +-21573 , +2763 , +-23241 , +27925 , +-4571 , +-20661 , +9835 , +19317 , +-18347 , +10747 , +27689 , +-14035 , +-28559 , +-9425 , +18227 , +-11159 , +22199 , +-23331 , +-18645 , +4921 , +-25425 , +2369 , +-28655 , +-19097 , +-6423 , +-10767 , +13879 , +-4395 , +-11975 , +-19601 , +-22345 , +-19889 , +-29343 , +28999 , +-28047 , +-15129 , +-19371 , +26279 , +-26245 , +-15923 , +-7693 , +-16525 , +-23261 , +9889 , +4915 , +3553 , +21087 , +83 , +16103 , +-1903 , +20165 , +20599 , +8425 , +23839 , +-11767 , +-15587 , +-20511 , +-16571 , +-4625 , +-13015 , +13683 , +23659 , +-4919 , +-13525 , +-32521 , +-17473 , +30311 , +14525 , +11447 , +4819 , +-19561 , +-26547 , +28065 , +22193 , +10265 , +9089 , +25987 , +20849 , +31507 , +-9199 , +28609 , +-27561 , +-6635 , +5391 , +24717 , +-24985 , +-32123 , +3283 , +11935 , +3961 , +11675 , +-20669 , +-143 , +16347 , +15067 , +6325 , +3569 , +5217 , +-21235 , +-3773 , +25527 , +26369 , +11695 , +14501 , +-9013 , +-9243 , +31479 , +-25983 , +28109 , +31503 , +-31681 , +-7343 , +9397 , +-6557 , +-4853 , +-21071 , +-9209 , +-31673 , +11893 , +-8135 , +6293 , +30397 , +3879 , +5075 , +2469 , +-18703 , +-22051 , +31387 , +9147 , +11615 , +-17841 , +24365 , +19915 , +7775 , +26803 , +-11131 , +6375 , +-15549 , +19373 , +-20913 , +-1403 , +26601 , +-10029 , +22983 , +307 , +-6945 , +-1129 , +-20723 , +-1075 , +-12815 , +2759 , +21247 , +-29905 , +11581 , +-11131 , +-15991 , +5757 , +8925 , +-1857 , +-26483 , +6603 , +16617 , +18975 , +15145 , +-14499 , +-993 , +28049 , +26013 , +29535 , +2293 , +28719 , +-13925 , +-15847 , +-719 , +-29761 , +19233 , +4269 , +3585 , +-11865 , +-2603 , +4169 , +17043 , +-2963 , +17109 , +3041 , +-3281 , +-6235 , +-14569 , +-12183 , +-4915 , +-29073 , +-7621 , +-20597 , +4397 , +12397 , +-31257 , +-27423 , +-13455 , +-4805 , +-21091 , +-23129 , +12591 , +-6551 , +-24811 , +25339 , +10261 , +22513 , +-29937 , +-14701 , +26613 , +22319 , +-22859 , +20975 , +-20129 , +28759 , +21867 , +-30693 , +4287 , +-9609 , +31529 , +-13861 , +-31245 , +31201 , +-28843 , +3183 , +-6051 , +26921 , +-30697 , +25285 , +24451 , +16545 , +13877 , +-11987 , +18465 , +-11187 , +10603 , +25497 , +-8761 , +-24485 , +-19135 , +-431 , +-32533 , +-25573 , +11873 , +-7891 , +-3709 , +-21643 , +-1935 , +21833 , +22047 , +26347 , +31859 , +32065 , +26493 , +29185 , +-24693 , +-16409 , +-26457 , +6209 , +-11671 , +-14983 , +-27771 , +26803 , +20759 , +32609 , +-7685 , +-30773 , +-21677 , +12899 , +7031 , +28653 , +11623 , +-1189 , +28437 , +-10147 , +16773 , +-14731 , +-7631 , +31415 , +24985 , +12511 , +7037 , +28399 , +-20063 , +19723 , +4765 , +-10815 , +-9587 , +-16033 , +31805 , +-30295 , +15757 , +14703 , +19113 , +3681 , +6127 , +-24141 , +6891 , +30419 , +-20617 , +9673 , +-6573 , +31127 , +7985 , +26911 , +-12125 , +27619 , +-9003 , +-3531 , +27287 , +23309 , +-29041 , +16461 , +16649 , +-907 , +18791 , +-31829 , +4225 , +-21489 , +-12277 , +28747 , +30029 , +12621 , +-5581 , +8981 , +28703 , +-32103 , +27759 , +-28267 , +-26847 , +16213 , +2185 , +31805 , +19341 , +6217 , +32335 , +23311 , +-13373 , +-8543 , +17661 , +15581 , +31207 , +29029 , +17671 , +4351 , +12023 , +16749 , +-17807 , +21391 , +-3493 , +-23585 , +-10315 , +-27623 , +-4599 , +-21729 , +16651 , +-12581 , +-2281 , +-16819 , +-1975 , +4215 , +-32049 , +-22721 , +-11975 , +23597 , +24659 , +20209 , +1651 , +19609 , +3751 , +-8061 , +1713 , +26333 , +1873 , +-30031 , +4781 , +-26519 , +-10893 , +-26681 , +-15501 , +-10457 , +20825 , +5149 , +4413 , +23611 , +-10081 , +-17649 , +-3387 , +28977 , +-9539 , +25199 , +11561 , +18373 , +-28123 , +-25469 , +27703 , +-11253 , +16855 , +-14207 , +15177 , +8493 , +-12419 , +18813 , +-2401 , +6311 , +4611 , +7137 , +19765 , +13305 , +-21331 , +-32397 , +27419 , +4325 , +-12627 , +-1091 , +25679 , +24605 , +-20669 , +19723 , +-2029 , +9865 , +7751 , +-18455 , +17603 , +-14093 , +337 , +13587 , +-31691 , +-9661 , +5447 , +-10261 , +26755 , +9275 , +-13193 , +6523 , +12663 , +-7511 , +-24273 , +16869 , +4683 , +-22239 , +-19241 , +-22433 , +25 , +-5321 , +4999 , +427 , +-32611 , +-24781 , +29727 , +29959 , +-28255 , +-3247 , +-13087 , +-20559 , +16581 , +-29329 , +-27515 , +-20775 , +3039 , +19785 , +2005 , +30747 , +-24109 , +2357 , +19395 , +30829 , +7145 , +15699 , +-15357 , +-15955 , +18339 , +9551 , +30239 , +-8577 , +6429 , +14477 , +-12011 , +29911 , +-8743 , +-32531 , +-20121 , +28399 , +18467 , +-15365 , +-1605 , +-7499 , +-5409 , +-2389 , +-26641 , +28619 , +15847 , +-3187 , +20143 , +19457 , +-15643 , +-5239 , +7059 , +-18873 , +25253 , +-30441 , +-28239 , +2087 , +-25877 , +15859 , +183 , +7615 , +-27433 , +-19625 , +-16247 , +19509 , +-17487 , +-11079 , +31051 , +-24907 , +-5051 , +27893 , +-16377 , +-28189 , +-11073 , +-12779 , +-8255 , +1495 , +-25345 , +31611 , +9991 , +-24943 , +28525 , +20135 , +-28139 , +19191 , +-1445 , +3683 , +10599 , +10821 , +-32301 , +-3971 , +-4913 , +-30703 , +-26121 , +-505 , +-23791 , +9905 , +8659 , +-11769 , +26105 , +-28599 , +-26949 , +-21841 , +17141 , +-22995 , +22553 , +17693 , +-14295 , +9963 , +-3117 , +31623 , +-10739 , +25271 , +4889 , +7681 , +-29315 , +-10645 , +8123 , +-601 , +-19881 , +-6921 , +14859 , +-23969 , +23189 , +26467 , +-26835 , +-23797 , +16863 , +19263 , +-8205 , +6215 , +-26205 , +-2151 , +-22479 , +8601 , +-21069 , +-20349 , +-26981 , +-2765 , +13657 , +-20231 , +21783 , +29217 , +-22289 , +13157 , +-7785 , +-21243 , +29685 , +8341 , +22389 , +28501 , +23473 , +-25299 , +-14013 , +8455 , +-3525 , +11689 , +17193 , +5333 , +28193 , +-22325 , +-29249 , +-20757 , +-16775 , +-20327 , +-13989 , +24101 , +13171 , +-5675 , +31221 , +-8247 , +-27775 , +-22031 , +7033 , +-14923 , +-2849 , +21387 , +-10597 , +-18653 , +13233 , +6501 , +28217 , +25563 , +23715 , +24535 , +-725 , +-24091 , +-7185 , +29903 , +-25445 , +-21039 , +265 , +-10681 , +-29979 , +1377 , +1705 , +-16587 , +-5401 , +-11071 , +3941 , +13073 , +-19497 , +28237 , +-10545 , +16323 , +-5719 , +-15177 , +5899 , +-20967 , +-18989 , +24525 , +17121 , +-10039 , +30903 , +-15447 , +-2979 , +-7709 , +27507 , +-15765 , +-6173 , +-313 , +-5579 , +-20365 , +-9273 , +4769 , +-231 , +-3303 , +11363 , +20319 , +17795 , +-7713 , +-31563 , +5419 , +-16911 , +29231 , +31605 , +-14243 , +-21931 , +-23147 , +29861 , +-10753 , +2799 , +12913 , +-24653 , +-24907 , +-11359 , +24367 , +27155 , +-32699 , +29131 , +-30713 , +15943 , +-19071 , +-17757 , +18219 , +-6263 , +17613 , +-9719 , +-18555 , +29145 , +-19193 , +23011 , +-13845 , +-8551 , +-16113 , +-9739 , +9441 , +-31327 , +-15949 , +-28623 , +-31039 , +31451 , +1579 , +10655 , +8831 , +-12199 , +-11499 , +9123 , +-4385 , +3311 , +16361 , +13795 , +24617 , +-20663 , +-21779 , +-7017 , +-31641 , +5505 , +-1097 , +-11419 , +-1519 , +-24261 , +27677 , +-3915 , +-18087 , +28733 , +4015 , +4495 , +10193 , +-32379 , +-11855 , +5611 , +28329 , +-24865 , +8591 , +11667 , +-29847 , +-7421 , +1499 , +21873 , +4905 , +13351 , +-12863 , +-23187 , +8259 , +-29927 , +6395 , +-31037 , +25239 , +24285 , +28241 , +27357 , +-13773 , +3255 , +6289 , +6825 , +-15207 , +-27437 , +-32261 , +13937 , +-31633 , +-31921 , +-14775 , +-461 , +19389 , +24031 , +-19685 , +-1413 , +12445 , +28127 , +-4361 , +-25161 , +21625 , +16103 , +32443 , +30229 , +1475 , +-22037 , +24985 , +2003 , +-15317 , +-15153 , +31627 , +-6111 , +-24747 , +-29057 , +-31151 , +12399 , +-6121 , +-20599 , +16611 , +-7603 , +-21459 , +10033 , +-27285 , +21433 , +-2963 , +15631 , +-4673 , +15367 , +15755 , +-28899 , +28249 , +31017 , +9027 , +-27553 , +20427 , +9613 , +-18919 , +27625 , +3769 , +5755 , +29587 , +20613 , +-21931 , +23265 , +22763 , +-30527 , +-22193 , +-11593 , +2119 , +11153 , +7509 , +30415 , +30841 , +-28325 , +23813 , +26925 , +10027 , +-13927 , +-21397 , +26087 , +17827 , +-4879 , +-29711 , +-21389 , +-10251 , +-23615 , +-6691 , +-1657 , +16055 , +-18103 , +-11701 , +-22167 , +9025 , +4913 , +10655 , +-25905 , +15971 , +-6737 , +-25221 , +-5581 , +-3687 , +31769 , +-28605 , +7595 , +10947 , +28155 , +25355 , +-9919 , +-30107 , +-26447 , +29197 , +-19507 , +17495 , +-19067 , +30637 , +17481 , +-19713 , +-7107 , +-29211 , +-81 , +5387 , +565 , +-31169 , +-181 , +28069 , +9729 , +-12201 , +18327 , +-209 , +6009 , +-22843 , +-22641 , +22649 , +7251 , +-17763 , +-14195 , +27773 , +-3775 , +5481 , +-31071 , +-21363 , +18311 , +27033 , +10597 , +-25323 , +-24817 , +-30337 , +-27303 , +-9005 , +-11007 , +15567 , +3513 , +5765 , +16099 , +11397 , +-24875 , +-10965 , +-21977 , +7535 , +-14101 , +-19781 , +6221 , +12571 , +-31875 , +-9893 , +-28819 , +25939 , +12585 , +20243 , +-10401 , +2577 , +-25601 , +1039 , +31561 , +26107 , +-28063 , +6991 , +-6215 , +16727 , +15443 , +26079 , +-705 , +-28789 , +-16045 , +-30569 , +-4225 , +-4341 , +22197 , +-15289 , +-14125 , +14295 , +20093 , +-10115 , +27227 , +-12175 , +16047 , +-1875 , +24729 , +341 , +-9941 , +19451 , +25733 , +-269 , +-29683 , +-4257 , +-7895 , +-7643 , +-32141 , +-3469 , +21945 , +18213 , +7655 , +18067 , +-5083 , +-13555 , +-32725 , +6317 , +7225 , +8133 , +15771 , +-29337 , +-19661 , +-4481 , +-12295 , +22495 , +6101 , +16563 , +-7727 , +8929 , +8967 , +-22639 , +2631 , +17567 , +25825 , +-9729 , +4471 , +-19219 , +11863 , +261 , +21831 , +-16911 , +14139 , +27353 , +26309 , +24417 , +14565 , +-9151 , +30709 , +-9155 , +21827 , +14495 , +-19913 , +27389 , +-23943 , +-18345 , +3347 , +-32683 , +-19733 , +26067 , +-17001 , +-21403 , +29157 , +6395 , +-10709 , +-32141 , +11429 , +-22237 , +12017 , +-31963 , +8193 , +-29297 , +11921 , +-32455 , +25199 , +-23455 , +-29795 , +30903 , +-32083 , +22555 , +-24993 , +20657 , +-19763 , +-9333 , +23353 , +32631 , +-10285 , +-19379 , +-29319 , +2381 , +21965 , +19393 , +27309 , +-11863 , +-3997 , +-16769 , +5767 , +-18715 , +-26623 , +-23983 , +12071 , +28795 , +31575 , +-1361 , +-1537 , +-22595 , +13703 , +5039 , +18719 , +17157 , +28847 , +31623 , +-20199 , +23421 , +-11003 , +-11657 , +10065 , +-10939 , +-25485 , +-22189 , +-24359 , +4663 , +-23897 , +9837 , +-13881 , +-18659 , +18869 , +-22257 , +27915 , +-1179 , +2851 , +9081 , +-23347 , +31583 , +3467 , +25431 , +27455 , +1259 , +-26957 , +181 , +-23557 , +22205 , +-19941 , +11127 , +13779 , +18959 , +-7139 , +3927 , +19759 , +24279 , +16775 , +1625 , +24295 , +8837 , +-15441 , +20933 , +913 , +26931 , +12551 , +-28261 , +17255 , +-11931 , +29243 , +-19829 , +27281 , +-30147 , +-21555 , +-30089 , +-507 , +-11213 , +-3039 , +-9379 , +-5919 , +13389 , +-481 , +-2855 , +31293 , +-11817 , +-28605 , +-21481 , +19333 , +-2401 , +8257 , +-7601 , +-22703 , +10661 , +27409 , +20923 , +-30529 , +-9127 , +24969 , +-9967 , +-13493 , +8787 , +16763 , +-649 , +-23775 , +27529 , +13131 , +-9473 , +-2561 , +-18169 , +17411 , +15261 , +-21375 , +17445 , +5099 , +3233 , +-27641 , +4167 , +4521 , +-5463 , +-5889 , +24331 , +-26159 , +-987 , +8647 , +32519 , +-11523 , +-11711 , +4607 , +-4865 , +-24979 , +-30619 , +-409 , +16289 , +29971 , +-9683 , +-18127 , +-10831 , +-30409 , +26591 , +24285 , +-16683 , +1159 , +-7837 , +-13427 , +-10569 , +-17743 , +20411 , +24801 , +-30003 , +10367 , +13565 , +13391 , +17035 , +5989 , +-17719 , +15865 , +-7651 , +-16987 , +-22719 , +-24575 , +24471 , +-19743 , +20611 , +-24981 , +-7493 , +-28367 , +18075 , +24431 , +26407 , +-25919 , +-5115 , +3151 , +22797 , +15327 , +-19299 , +27313 , +9329 , +-15967 , +17177 , +-31109 , +11993 , +7411 , +7427 , +-31705 , +13201 , +2607 , +11567 , +13207 , +31317 , +30009 , +-13135 , +31605 , +-8049 , +29207 , +-30115 , +13577 , +11541 , +-24057 , +26803 , +-28533 , +-22951 , +23831 , +-13725 , +-26107 , +25375 , +30779 , +-15043 , +-2399 , +19907 , +-21 , +5035 , +29319 , +20957 , +-16587 , +23723 , +30515 , +-21365 , +-5283 , +2627 , +593 , +-10465 , +-13337 , +26239 , +13579 , +1111 , +-18625 , +14051 , +5101 , +-22497 , +15301 , +-29083 , +-28875 , +439 , +-12951 , +3561 , +27567 , +8317 , +-12343 , +19251 , +9225 , +23325 , +21691 , +-27039 , +23217 , +-20153 , +26489 , +-10781 , +-3033 , +4073 , +15393 , +-20233 , +29143 , +-4117 , +7137 , +-16231 , +-23181 , +18273 , +25991 , +-253 , +21705 , +17733 , +31385 , +11681 , +-6627 , +-12367 , +-3863 , +27015 , +-21251 , +15511 , +-8007 , +-22929 , +-4195 , +15601 , +-22713 , +18473 , +15531 , +29319 , +-2583 , +-28003 , +10671 , +-22499 , +-31319 , +10299 , +4569 , +9259 , +18261 , +20209 , +-4771 , +3611 , +26657 , +13233 , +-9905 , +24059 , +691 , +-7081 , +26611 , +20153 , +-11065 , +14381 , +20895 , +-13607 , +-11971 , +24287 , +-25079 , +-13395 , +-6469 , +19959 , +-8665 , +8975 , +-11589 , +-15159 , +-29057 , +-22635 , +22823 , +7933 , +14855 , +15181 , +-18315 , +-21129 , +30073 , +-23307 , +-19909 , +-12839 , +19243 , +-19537 , +69 , +30837 , +12135 , +-23235 , +-29135 , +31945 , +5447 , +18103 , +20357 , +9335 , +-17407 , +-14397 , +2633 , +29879 , +-13103 , +-18355 , +-4583 , +-14761 , +-7867 , +10433 , +20425 , +-5073 , +2577 , +25795 , +24945 , +-24549 , +-4489 , +16481 , +16135 , +28269 , +7185 , +28627 , +10111 , +-10259 , +-24789 , +-7761 , +14937 , +-7601 , +31649 , +-27745 , +-28225 , +-12509 , +7731 , +-9825 , +4383 , +12635 , +24157 , +-28751 , +-16327 , +6455 , +10417 , +11795 , +2755 , +-28989 , +27049 , +14331 , +-17289 , +4813 , +20745 , +-819 , +4531 , +24157 , +-31315 , +9173 , +-19313 , +6319 , +25067 , +-1413 , +-403 , +-17493 , +-12193 , +-767 , +22045 , +24277 , +-7857 , +-28235 , +621 , +-24365 , +-20359 , +28331 , +18759 , +26455 , +-19599 , +-24071 , +13119 , +-21083 , +2171 , +-19355 , +-13383 , +6523 , +-8741 , +-8535 , +13681 , +-29031 , +-30285 , +-14043 , +27559 , +30891 , +27225 , +-12779 , +1951 , +975 , +10035 , +13903 , +-7475 , +-1155 , +27141 , +26741 , +-4761 , +-30707 , +-22317 , +-32083 , +4467 , +-32085 , +6201 , +22243 , +31345 , +-26683 , +24123 , +16753 , +6501 , +-4073 , +7585 , +-11675 , +-17039 , +-26609 , +-3631 , +-16077 , +-26379 , +24017 , +-3289 , +8941 , +-29923 , +23977 , +23497 , +23287 , +1537 , +-2807 , +25861 , +-16821 , +-5831 , +21501 , +-2785 , +24869 , +10479 , +25887 , +13751 , +1857 , +-26231 , +17431 , +-21867 , +-20847 , +-18517 , +-1391 , +-7929 , +-21389 , +-15135 , +-17485 , +20407 , +-10895 , +4267 , +22031 , +32513 , +-22673 , +-14823 , +5165 , +4565 , +-4501 , +5609 , +-15507 , +-14593 , +-9301 , +5395 , +6543 , +2827 , +1925 , +10219 , +12453 , +12955 , +21893 , +20917 , +20873 , +-2755 , +13107 , +16575 , +-15143 , +16577 , +10561 , +28403 , +-7567 , +-747 , +14157 , +12023 , +5977 , +-10085 , +-3569 , +-573 , +6727 , +-19197 , +-9193 , +-3917 , +1685 , +-13149 , +-3835 , +-26585 , +-27211 , +10311 , +-9413 , +11925 , +12075 , +32149 , +-13283 , +27687 , +1801 , +3553 , +28359 , +-10547 , +735 , +-25221 , +-4799 , +-6443 , +-25285 , +7067 , +-32711 , +-10229 , +32667 , +4771 , +-32451 , +32585 , +2793 , +30983 , +30575 , +-879 , +-31117 , +-1375 , +5829 , +-24157 , +11615 , +21123 , +-22089 , +-6881 , +-11611 , +-12969 , +-8837 , +-17905 , +21385 , +-29649 , +26815 , +9221 , +-28527 , +-24599 , +-31519 , +24505 , +9471 , +-27399 , +-20061 , +30743 , +-27449 , +-30777 , +-17563 , +-24611 , +10499 , +22927 , +31715 , +10161 , +13047 , +7593 , +19807 , +26809 , +-4741 , +22383 , +-22423 , +31671 , +-19201 , +8333 , +-7157 , +5275 , +-12807 , +-12325 , +-28535 , +23193 , +29155 , +14521 , +25745 , +5325 , +23217 , +6879 , +13563 , +841 , +-31539 , +-9541 , +-4357 , +-17235 , +24453 , +6731 , +3295 , +-6075 , +9233 , +19051 , +32065 , +11417 , +-29955 , +-13125 , +29891 , +-21873 , +-26581 , +-16919 , +8769 , +23803 , +-19129 , +147 , +-17003 , +13497 , +-11583 , +-24421 , +-5951 , +18755 , +-14531 , +9981 , +-9295 , +-2605 , +-23141 , +-2515 , +21101 , +15083 , +16735 , +18155 , +-18985 , +15483 , +-26193 , +-8807 , +30429 , +13425 , +25297 , +4119 , +5171 , +-20009 , +26137 , +13341 , +-15731 , +31841 , +-3993 , +3591 , +12117 , +-2925 , +1821 , +22589 , +21987 , +18507 , +-25705 , +-1277 , +-8393 , +21475 , +29987 , +3277 , +1069 , +-30779 , +2431 , +13087 , +27195 , +-21883 , +-1083 , +31711 , +-3423 , +-12429 , +31209 , +18229 , +-3031 , +22973 , +12473 , +22997 , +-10403 , +25597 , +3653 , +-20505 , +-29385 , +25687 , +-29979 , +10323 , +-10139 , +25875 , +-20309 , +-24415 , +-7941 , +-22101 , +-26281 , +-26293 , +2729 , +6253 , +-25897 , +-1385 , +-31369 , +16529 , +-9665 , +4593 , +-28419 , +21709 , +32053 , +24513 , +-5609 , +-3471 , +12795 , +19907 , +23329 , +3325 , +17875 , +26083 , +-6485 , +-10695 , +525 , +8587 , +-31561 , +-1333 , +-30871 , +-5751 , +-5523 , +2905 , +-8157 , +24151 , +21585 , +27155 , +-32681 , +-32509 , +-13569 , +-27439 , +-4849 , +-11141 , +-9631 , +9137 , +-15963 , +3949 , +13163 , +21543 , +-13363 , +30361 , +12361 , +30867 , +30209 , +30635 , +-19679 , +9315 , +14465 , +-25451 , +22347 , +27813 , +18629 , +28519 , +27903 , +5407 , +16247 , +26273 , +-18539 , +485 , +-4881 , +29203 , +26177 , +-14987 , +5155 , +16433 , +16191 , +-23729 , +17449 , +-11285 , +30101 , +-8439 , +-30687 , +-31995 , +8517 , +-20499 , +9663 , +-2833 , +-11765 , +-20213 , +8755 , +14883 , +13455 , +9681 , +-14931 , +-27667 , +16925 , +-5333 , +-10937 , +1241 , +-3353 , +27923 , +-17521 , +16759 , +-5457 , +30891 , +22383 , +6591 , +6149 , +17109 , +-22097 , +-3353 , +-16889 , +31565 , +6375 , +27061 , +-8057 , +-15299 , +-31747 , +-19103 , +-29993 , +26205 , +-9453 , +-7455 , +-5901 , +-26241 , +30479 , +-32563 , +-21699 , +14769 , +-6271 , +-11345 , +-21323 , +16593 , +28453 , +10975 , +21431 , +-9051 , +-6433 , +28121 , +-23259 , +31091 , +16169 , +31253 , +-32209 , +-26339 , +22543 , +26973 , +2175 , +-12621 , +26537 , +22701 , +-29449 , +-18807 , +-22767 , +-14463 , +10473 , +17115 , +32221 , +10163 , +20937 , +13531 , +-7149 , +-18987 , +29553 , +6729 , +12965 , +12797 , +1225 , +-22639 , +6759 , +-28371 , +3853 , +-14755 , +-1657 , +16161 , +-24707 , +12463 , +18313 , +2219 , +7065 , +-3971 , +20405 , +18053 , +-4135 , +-25663 , +-3555 , +24755 , +-28449 , +-23269 , +-23801 , +16979 , +18229 , +-26403 , +24815 , +-10761 , +-17017 , +-24911 , +-9989 , +8829 , +-13995 , +6049 , +29171 , +8299 , +26157 , +-20291 , +30137 , +-8257 , +23393 , +-15825 , +4419 , +5711 , +-31671 , +21195 , +25361 , +-20837 , +13037 , +-26571 , +20517 , +28457 , +-23227 , +19307 , +22397 , +21083 , +1263 , +-22041 , +7173 , +-22841 , +-5781 , +31539 , +-8935 , +-28653 , +-11059 , +-3325 , +-27277 , +67 , +-23819 , +-14391 , +-1873 , +-15971 , +25421 , +21965 , +1839 , +-22279 , +-27395 , +9935 , +28845 , +-30565 , +15779 , +-18925 , +32027 , +-1137 , +-11637 , +-14085 , +-19411 , +-24197 , +27753 , +13351 , +-1213 , +-7433 , +15757 , +25861 , +25069 , +-10645 , +-15713 , +-30743 , +21723 , +23909 , +-23081 , +-23893 , +28503 , +4713 , +-13137 , +31675 , +-23745 , +8025 , +-30681 , +-23111 , +-4231 , +-27591 , +24429 , +-30835 , +23793 , +22169 , +27939 , +-18179 , +31241 , +16737 , +-14575 , +-29745 , +3229 , +-29389 , +-6055 , +6483 , +12907 , +6457 , +-27077 , +-21373 , +-22503 , +-21375 , +14145 , +-8039 , +28323 , +-14377 , +5369 , +19497 , +-30883 , +8223 , +-32715 , +4279 , +-413 , +22817 , +20409 , +9937 , +-1135 , +6387 , +-20101 , +-16735 , +4611 , +3009 , +-14761 , +-29425 , +-31233 , +-4049 , +67 , +23885 , +-16001 , +17449 , +-17645 , +-16641 , +-20709 , +-21945 , +1955 , +10431 , +13187 , +-24683 , +8601 , +26437 , +32127 , +-26117 , +-30825 , +-20229 , +25693 , +9991 , +11767 , +13841 , +-29455 , +9041 , +-15355 , +-31467 , +-29435 , +-23991 , +-31829 , +-25579 , +-15013 , +-24937 , +-31813 , +-473 , +10779 , +2799 , +1173 , +-23155 , +-20013 , +23399 , +-20627 , +10829 , +-23833 , +8019 , +16383 , +-2751 , +30611 , +-15459 , +-28483 , +-10315 , +-28585 , +5529 , +-32359 , +-8325 , +27903 , +-24993 , +-20179 , +-16501 , +-23547 , +28329 , +-32641 , +-23279 , +20641 , +29471 , +22829 , +-12021 , +12079 , +-5831 , +-20943 , +-12703 , +8241 , +3217 , +-20719 , +-25483 , +18879 , +-27455 , +9627 , +-22965 , +-28793 , +7093 , +30233 , +-8685 , +-26303 , +1159 , +14861 , +-10943 , +8105 , +-1327 , +28007 , +10547 , +-18447 , +-23919 , +-22975 , +7221 , +-10815 , +-28555 , +20237 , +-19665 , +15275 , +8887 , +23385 , +12197 , +-28125 , +21111 , +28415 , +15975 , +23801 , +5519 , +-4129 , +-19819 , +1869 , +26867 , +-1511 , +9541 , +15883 , +-25729 , +-20797 , +20883 , +20705 , +-3755 , +-10973 , +-31431 , +-11849 , +14257 , +18017 , +-591 , +10923 , +24905 , +7113 , +-30275 , +25215 , +-15591 , +6011 , +18319 , +-14435 , +2501 , +16291 , +-10415 , +-18039 , +32621 , +9273 , +-9649 , +18645 , +-17911 , +-14547 , +5757 , +-6747 , +18997 , +-24787 , +5791 , +-11113 , +-32101 , +-21297 , +-24877 , +-23991 , +-4165 , +6737 , +-12877 , +19789 , +-26549 , +24019 , +16875 , +24217 , +-25073 , +22023 , +7241 , +-22389 , +22317 , +22897 , +13925 , +-7077 , +30733 , +-20455 , +26023 , +-6641 , +26019 , +28615 , +8939 , +-24835 , +18519 , +12985 , +28311 , +-22853 , +-2221 , +-24357 , +18733 , +-32105 , +21595 , +17279 , +-26515 , +25497 , +12331 , +-25703 , +-12059 , +-27925 , +20297 , +-3473 , +15369 , +17631 , +-22687 , +-9001 , +13009 , +2657 , +27931 , +-5903 , +9421 , +-26389 , +2677 , +28245 , +-15427 , +8453 , +-27243 , +-1833 , +11177 , +-5317 , +-8147 , +17847 , +24441 , +29585 , +-18621 , +19291 , +-3571 , +-17537 , +27545 , +17291 , +13275 , +2661 , +14967 , +12321 , +-17157 , +-11127 , +-20723 , +-11705 , +-21561 , +137 , +-27575 , +-29649 , +28661 , +17239 , +-28885 , +9543 , +31269 , +-13651 , +-1631 , +-5895 , +-22521 , +-4599 , +5593 , +6101 , +-15131 , +7719 , +12837 , +9047 , +-2363 , +-13585 , +-10939 , +-21479 , +28671 , +30711 , +-29879 , +-17779 , +15697 , +-18567 , +27365 , +10799 , +-30601 , +17351 , +-5303 , +-16573 , +10057 , +-4283 , +8825 , +-8433 , +-12463 , +-23835 , +1063 , +25227 , +-14881 , +8983 , +-18169 , +31651 , +25763 , +-11449 , +-22867 , +9441 , +19141 , +12249 , +16351 , +5045 , +-28031 , +13969 , +13679 , +-23261 , +-7367 , +30111 , +8087 , +-17153 , +-18417 , +-1785 , +14279 , +3999 , +-19713 , +-12635 , +15117 , +-12773 , +21619 , +22683 , +3289 , +11523 , +-4253 , +9809 , +12903 , +-17007 , +12769 , +-29723 , +-16753 , +4457 , +6715 , +-20437 , +-14825 , +-24371 , +-20337 , +18721 , +-2919 , +27477 , +23779 , +-16663 , +22993 , +19239 , +12735 , +-4805 , +1911 , +29359 , +833 , +15207 , +-26731 , +3291 , +-23877 , +17091 , +13159 , +30667 , +5825 , +-17497 , +12969 , +4623 , +10193 , +-5907 , +-5257 , +4705 , +6489 , +14807 , +-13667 , +25043 , +-6309 , +23195 , +19577 , +-3951 , +-8061 , +27465 , +-4537 , +32025 , +-2887 , +-27309 , +-20475 , +17897 , +-28603 , +-18565 , +16069 , +-25151 , +23383 , +24649 , +24451 , +-9641 , +-18901 , +-12531 , +-19841 , +-27249 , +18849 , +13137 , +26393 , +-18121 , +-31667 , +-7475 , +-2013 , +19763 , +23571 , +-16917 , +-30533 , +-32695 , +11331 , +31407 , +-1625 , +-7357 , +2093 , +3647 , +20261 , +20151 , +23095 , +-4913 , +32587 , +27451 , +10103 , +22559 , +16601 , +21525 , +-12335 , +29807 , +-3435 , +19583 , +-23933 , +23551 , +13089 , +-165 , +8009 , +-5891 , +16725 , +16737 , +15337 , +28163 , +-17133 , +-12823 , +-31143 , +5387 , +-8031 , +-2539 , +31561 , +7407 , +-13691 , +-17779 , +-5817 , +-21163 , +-4137 , +18361 , +-18355 , +31029 , +20253 , +19573 , +-4639 , +-6207 , +31647 , +9041 , +17831 , +-1045 , +6467 , +17981 , +13947 , +-19881 , +-7963 , +1229 , +-17397 , +3537 , +-15059 , +-2841 , +-17167 , +-30131 , +20453 , +5633 , +25919 , +11857 , +-12331 , +7897 , +19879 , +-3331 , +28441 , +-4693 , +-14583 , +-17799 , +-13829 , +-27927 , +8845 , +-29457 , +7753 , +-4493 , +20027 , +21505 , +-21715 , +22351 , +-25067 , +-13111 , +22917 , +17891 , +6571 , +-6071 , +17597 , +30893 , +9787 , +21091 , +15395 , +-29835 , +-6849 , +22361 , +-11069 , +30989 , +8071 , +-8265 , +9153 , +-125 , +5337 , +-17697 , +-18137 , +24287 , +2051 , +-4117 , +-3257 , +27221 , +-8337 , +19763 , +17039 , +25599 , +-19899 , +-4537 , +30179 , +-25833 , +-26119 , +-4009 , +-22673 , +17583 , +-24471 , +3393 , +-7669 , +-31007 , +8823 , +21747 , +5891 , +11925 , +32533 , +-17037 , +31871 , +1967 , +27375 , +-16045 , +-5043 , +20423 , +-16267 , +-15197 , +23365 , +15207 , +9335 , +30833 , +281 , +1471 , +22333 , +-2883 , +18605 , +-32039 , +-30173 , +-16147 , +8439 , +-21413 , +-28245 , +-32045 , +-14771 , +8375 , +19479 , +-29681 , +-25533 , +3303 , +5251 , +-479 , +12291 , +30881 , +-25989 , +-17209 , +-1247 , +27923 , +-2543 , +-6389 , +-265 , +-4581 , +20607 , +3755 , +-12165 , +15867 , +-1747 , +-6627 , +11415 , +25493 , +16219 , +-25349 , +-21245 , +27425 , +-6097 , +-23799 , +-19047 , +22885 , +-26287 , +2465 , +12851 , +18797 , +4095 , +15279 , +15613 , +-21307 , +31915 , +17451 , +17745 , +9777 , +-9463 , +23311 , +-12533 , +-2337 , +-24905 , +-3887 , +25189 , +30247 , +-29629 , +-4011 , +-15281 , +-29761 , +5839 , +28529 , +3907 , +-23437 , +6695 , +-31273 , +-15199 , +6491 , +18773 , +-32105 , +28291 , +-32357 , +10683 , +14351 , +-5601 , +-6513 , +-3409 , +-27025 , +-3443 , +21137 , +10637 , +19617 , +1073 , +-19931 , +21073 , +-22575 , +12423 , +32691 , +-29519 , +26969 , +-1403 , +12741 , +30129 , +-13505 , +-11417 , +-7233 , +9665 , +27435 , +20497 , +12553 , +-23727 , +21471 , +-20763 , +-17697 , +-24089 , +-8911 , +-14827 , +20591 , +-6727 , +-25983 , +-3451 , +12709 , +9163 , +4017 , +7959 , +25689 , +-18821 , +25757 , +31889 , +-27637 , +-347 , +-12523 , +487 , +29721 , +-14033 , +-5293 , +19741 , +7285 , +-28369 , +-17677 , +-869 , +22753 , +-2441 , +-32149 , +6405 , +25257 , +16561 , +15621 , +-22639 , +-813 , +18169 , +-8365 , +-791 , +27355 , +-27659 , +8239 , +-6031 , +14831 , +7783 , +37 , +20531 , +21667 , +28241 , +-14467 , +21801 , +22825 , +-31109 , +-19809 , +-26597 , +-22011 , +27297 , +1313 , +-18703 , +12625 , +-26123 , +-17621 , +-25963 , +20075 , +22089 , +-28295 , +-21179 , +-6613 , +3997 , +-25641 , +-28311 , +3491 , +-13255 , +8713 , +28909 , +18263 , +-6843 , +-1191 , +32031 , +-13589 , +-4125 , +8317 , +-18695 , +-12443 , +10949 , +-21483 , +-26613 , +20449 , +18501 , +421 , +-19521 , +17099 , +-4867 , +21263 , +-5817 , +-17517 , +-17695 , +15489 , +15839 , +-4377 , +16599 , +-20745 , +-2123 , +-28305 , +-22839 , +-7885 , +4411 , +-30467 , +28227 , +32553 , +-25343 , +26703 , +8077 , +-12283 , +12807 , +-21187 , +15163 , +2719 , +-1889 , +14711 , +18507 , +-28561 , +28601 , +-579 , +22205 , +18181 , +-32057 , +20369 , +-12631 , +-14327 , +2061 , +-7817 , +-7211 , +-24663 , +16253 , +-10837 , +-31277 , +20889 , +27149 , +-7339 , +9363 , +23683 , +4493 , +1603 , +8573 , +-3063 , +6405 , +-20189 , +17677 , +-22221 , +11655 , +-1479 , +4325 , +-18067 , +-20595 , +-17769 , +18023 , +15361 , +-21305 , +6101 , +31183 , +-6653 , +643 , +28749 , +2505 , +-25381 , +16497 , +8653 , +21385 , +-28883 , +25615 , +8911 , +31587 , +3161 , +1135 , +-6603 , +-24091 , +-11659 , +1695 , +-32379 , +-8849 , +2749 , +29299 , +-29291 , +-12221 , +-21357 , +32746 , +-17975 , +13099 , +32495 , +29945 , +-30255 , +11397 , +28767 , +27631 , +13785 , +-13341 , +32123 , +-26045 , +9535 , +-32229 , +-8737 , +12275 , +-1065 , +-4635 , +-20579 , +26459 , +-20073 , +-11019 , +-9923 , +-8825 , +-21291 , +-24181 , +23089 , +-13547 , +22267 , +15507 , +-15923 , +13697 , +9157 , +-25545 , +1217 , +-20213 , +-32011 , +-8453 , +26893 , +-13569 , +-19321 , +19281 , +-16261 , +-19297 , +-2187 , +2999 , +-22115 , +18025 , +2785 , +-185 , +3897 , +-3075 , +31191 , +30427 , +-25011 , +-14227 , +-22145 , +13975 , +27259 , +793 , +8667 , +-27641 , +30989 , +27907 , +2297 , +2237 , +27239 , +-341 , +18605 , +4447 , +-1541 , +-4505 , +22219 , +-20157 , +-29493 , +-16585 , +6109 , +29325 , +-31141 , +26659 , +-11173 , +15035 , +-25565 , +11273 , +-18331 , +-13367 , +-8297 , +14851 , +-10761 , +18879 , +-18803 , +-20943 , +8615 , +-25393 , +31299 , +2847 , +25045 , +2027 , +-2865 , +-15475 , +-30611 , +-13343 , +29979 , +-4907 , +28435 , +12013 , +-20133 , +-20035 , +28135 , +-16177 , +12293 , +-25139 , +-15177 , +13169 , +28489 , +22829 , +20147 , +-24595 , +-31991 , +-4875 , +30893 , +-28621 , +24917 , +10255 , +-3635 , +-23271 , +-27299 , +15493 , +3787 , +12531 , +-28435 , +11615 , +22435 , +-24909 , +21597 , +9465 , +14289 , +-647 , +-23269 , +19421 , +18693 , +-30547 , +-30067 , +14363 , +12387 , +-31593 , +18841 , +-29415 , +-31187 , +18297 , +-26985 , +-7177 , +-16371 , +-14555 , +13767 , +-27551 , +-27201 , +-31979 , +-15793 , +30181 , +-10167 , +8963 , +-11347 , +12753 , +13249 , +-24059 , +14769 , +15747 , +-11405 , +24093 , +-30983 , +5451 , +24741 , +-7083 , +-24093 , +-12359 , +21455 , +-11937 , +-27643 , +-24195 , +4167 , +-24931 , +20525 , +27061 , +-15733 , +-19515 , +-22833 , +-8491 , +30953 , +-27403 , +8453 , +29679 , +28351 , +-31411 , +-1535 , +-29039 , +563 , +30213 , +-4345 , +9507 , +19561 , +-26109 , +7655 , +23989 , +-11207 , +30201 , +-22027 , +17755 , +21355 , +-15113 , +24445 , +14343 , +1649 , +2439 , +3517 , +4323 , +32407 , +9025 , +-12447 , +-17633 , +28351 , +-16151 , +-1679 , +15187 , +27295 , +1793 , +-5927 , +-13997 , +4205 , +17125 , +26191 , +4745 , +-27357 , +609 , +-10025 , +15563 , +11053 , +26569 , +-329 , +-15953 , +15273 , +4753 , +25841 , +-17813 , +-5607 , +29799 , +21815 , +-19409 , +-9571 , +-5431 , +29289 , +-23315 , +-19791 , +29983 , +-17533 , +6337 , +19543 , +24397 , +11555 , +12231 , +5087 , +-18221 , +-18057 , +-31641 , +-30701 , +-3997 , +-12621 , +-28101 , +21749 , +27635 , +9237 , +-19101 , +247 , +30043 , +1359 , +23129 , +-23377 , +21359 , +-11125 , +30279 , +-23279 , +-6255 , +-1321 , +-8209 , +-6101 , +-22583 , +-213 , +-24341 , +31831 , +19811 , +-1069 , +-10343 , +10741 , +4097 , +10865 , +16745 , +-6233 , +-15047 , +-16783 , +1465 , +-22273 , +-17241 , +-14847 , +-9941 , +32709 , +-20345 , +18827 , +4477 , +-30813 , +-23857 , +24999 , +-15905 , +-27551 , +-315 , +31647 , +30675 , +6817 , +-10475 , +-31657 , +-20355 , +19217 , +-26511 , +12757 , +-24965 , +-10203 , +2207 , +9005 , +22593 , +24143 , +-5611 , +3839 , +1779 , +-6467 , +7191 , +-18325 , +11701 , +31877 , +-28859 , +-7535 , +-24183 , +19559 , +-6475 , +-1409 , +18853 , +18175 , +7573 , +-20563 , +16461 , +-17023 , +2357 , +13051 , +27689 , +-3853 , +4009 , +21531 , +10781 , +3033 , +-5413 , +13723 , +8097 , +32381 , +-12249 , +-12469 , +-12903 , +13725 , +-11149 , +-2237 , +-1103 , +-23643 , +-6973 , +10579 , +-27603 , +5225 , +11091 , +-15105 , +2121 , +17241 , +14643 , +-1547 , +-10997 , +-21443 , +-13225 , +6915 , +16545 , +-29075 , +-30151 , +-28779 , +-6097 , +6787 , +-31003 , +7081 , +13877 , +-15713 , +-3939 , +-18873 , +22875 , +9487 , +-18455 , +-22921 , +-11313 , +-30315 , +-29647 , +7873 , +15129 , +26905 , +1239 , +3865 , +16507 , +-2081 , +20173 , +25955 , +-26179 , +10819 , +13997 , +29793 , +-7535 , +11247 , +-6317 , +-18125 , +3683 , +-15979 , +13551 , +-18613 , +-32079 , +-29403 , +-13143 , +8931 , +29161 , +-21371 , +8363 , +4603 , +-28993 , +-21817 , +26819 , +27595 , +-20481 , +15337 , +-28813 , +20157 , +31979 , +-17663 , +25493 , +-23321 , +-17899 , +-7421 , +-6553 , +-24827 , +20141 , +-17941 , +3621 , +19941 , +-26011 , +9855 , +-10967 , +4717 , +13249 , +10369 , +-4743 , +7183 , +-22797 , +11117 , +-3865 , +-21061 , +19761 , +27561 , +26019 , +24927 , +-11125 , +-6585 , +28503 , +8665 , +-28599 , +-13519 , +-31557 , +4981 , +10687 , +-5649 , +435 , +8925 , +-13917 , +4303 , +-4639 , +29337 , +20969 , +-10579 , +-12351 , +24321 , +-16359 , +-14559 , +-7105 , +20665 , +20523 , +26935 , +-27953 , +5545 , +30677 , +6315 , +30215 , +-1937 , +21105 , +10659 , +-12111 , +20065 , +-27321 , +20189 , +-14483 , +-19461 , +-23443 , +-17805 , +14019 , +-20517 , +-8159 , +-3827 , +32183 , +-3007 , +-15717 , +-14445 , +5353 , +-2313 , +-6553 , +-31883 , +18987 , +6101 , +-29379 , +-27309 , +-1901 , +3509 , +-16547 , +-6593 , +-27367 , +-11797 , +-25763 , +12141 , +26547 , +-15807 , +-4463 , +21623 , +18653 , +12647 , +-21041 , +14339 , +-17467 , +7665 , +26331 , +785 , +-17195 , +18381 , +16943 , +22175 , +7377 , +23613 , +-21157 , +24559 , +-16277 , +28751 , +17883 , +18227 , +-25503 , +-32307 , +7285 , +-3885 , +-14833 , +14019 , +-5885 , +-30441 , +28811 , +-27797 , +18137 , +-11669 , +11833 , +-8533 , +-28265 , +-20977 , +20203 , +27915 , +31359 , +-10417 , +-19859 , +-30163 , +-4527 , +18755 , +-6233 , +14535 , +25507 , +18173 , +-4049 , +281 , +10679 , +32325 , +-32663 , +-31259 , +-12337 , +15575 , +5141 , +6119 , +15633 , +12303 , +-20631 , +-49 , +-28463 , +-22739 , +-23373 , +-18761 , +25457 , +-12283 , +13923 , +-15077 , +32701 , +-6601 , +28077 , +-32689 , +-21323 , +-13075 , +-613 , +24193 , +-24589 , +2831 , +-30037 , +6435 , +-20355 , +-24069 , +11999 , +21993 , +25117 , +-18757 , +-28069 , +3653 , +24885 , +-31289 , +28801 , +27997 , +1829 , +-26323 , +-7813 , +23675 , +-239 , +-18091 , +16479 , +30223 , +9029 , +-28619 , +1479 , +-26841 , +11017 , +30477 , +28383 , +-14499 , +16633 , +26261 , +18697 , +-20645 , +6625 , +-32319 , +-17939 , +21963 , +-23541 , +13041 , +23571 , +23249 , +-6365 , +21421 , +-30721 , +27139 , +11401 , +22231 , +8639 , +6885 , +2083 , +-4753 , +-15601 , +-2085 , +22983 , +7613 , +-26135 , +-7263 , +-8451 , +17683 , +-11357 , +-27317 , +28005 , +-1023 , +-4993 , +25269 , +28049 , +21771 , +-17463 , +4475 , +-20915 , +28135 , +-27539 , +-6537 , +10377 , +-13519 , +21011 , +-21581 , +-13399 , +30367 , +-21841 , +-6937 , +-5541 , +22469 , +-25439 , +-5525 , +24563 , +-16577 , +20805 , +8879 , +1601 , +-25487 , +19477 , +4667 , +-27671 , +21953 , +15927 , +31261 , +31547 , +-17591 , +22173 , +15593 , +-7793 , +3087 , +26263 , +16937 , +18199 , +-31293 , +-19729 , +4191 , +-2247 , +30453 , +-13955 , +21875 , +-9881 , +19397 , +13125 , +5553 , +-17799 , +-29401 , +23307 , +-18111 , +-22907 , +19093 , +-32665 , +-20453 , +27441 , +-6585 , +3943 , +-7035 , +-9581 , +-17433 , +13471 , +-19453 , +-6523 , +-26153 , +1475 , +-22825 , +11389 , +-31531 , +5827 , +-25101 , +2533 , +-16827 , +-11431 , +-20619 , +-12041 , +-31521 , +29999 , +27037 , +13833 , +-30743 , +-4503 , +-19385 , +-29319 , +-31503 , +-24377 , +2271 , +-3601 , +2047 , +14651 , +14557 , +-5305 , +-14759 , +-30725 , +31419 , +-21027 , +-29777 , +-21215 , +-2705 , +-30101 , +12757 , +29117 , +-32161 , +-22943 , +-25853 , +9585 , +-8739 , +-27463 , +9861 , +-10103 , +-481 , +-6315 , +-26637 , +19087 , +-14161 , +20685 , +-5903 , +25959 , +-8589 , +28371 , +-675 , +-25373 , +-18923 , +-11001 , +-19953 , +2785 , +-17151 , +28743 , +15879 , +-24609 , +-18715 , +-9583 , +24115 , +16397 , +5015 , +-18597 , +17309 , +9463 , +29599 , +-20383 , +-17371 , +23433 , +4901 , +11017 , +-29257 , +-18767 , +21357 , +20017 , +31753 , +3703 , +6857 , +28815 , +-3887 , +9107 , +17179 , +-30845 , +-16779 , +-125 , +-12603 , +-20879 , +-2735 , +10541 , +7205 , +24225 , +17249 , +-31257 , +-12409 , +28547 , +-10619 , +16155 , +-21593 , +30621 , +14639 , +-31653 , +4257 , +-23081 , +8611 , +-32263 , +22893 , +-21675 , +-21591 , +25637 , +-12335 , +-12849 , +-2873 , +-16779 , +28385 , +-17813 , +-27905 , +12305 , +11255 , +12559 , +-8709 , +-25539 , +-479 , +8263 , +-32051 , +-12425 , +23585 , +18825 , +23081 , +-5879 , +26857 , +1565 , +-1771 , +24879 , +-31099 , +17521 , +-3033 , +925 , +-30815 , +21993 , +19773 , +-18783 , +14201 , +-23225 , +947 , +26301 , +28761 , +-4753 , +16155 , +-4423 , +30855 , +2255 , +3189 , +21567 , +-8759 , +-3787 , +9703 , +12525 , +-30891 , +2077 , +-17159 , +-24585 , +13905 , +16273 , +-16573 , +-30665 , +11451 , +15235 , +-29261 , +-25911 , +13047 , +927 , +-25031 , +-8675 , +-19531 , +23971 , +5 , +7579 , +9839 , +26687 , +14907 , +5549 , +-32669 , +-29085 , +32049 , +-19359 , +-7157 , +27419 , +-25055 , +18043 , +18195 , +-18961 , +-10907 , +-5871 , +18127 , +-12373 , +-18641 , +6051 , +-7367 , +1985 , +24249 , +-20819 , +22627 , +12835 , +17421 , +15049 , +-12687 , +-23145 , +-19415 , +-5057 , +6163 , +14987 , +25549 , +1821 , +14205 , +25207 , +5277 , +10197 , +-7717 , +-4181 , +-15127 , +13391 , +-18101 , +-23121 , +25055 , +20873 , +30039 , +10775 , +29763 , +-19039 , +-19987 , +28121 , +-16473 , +-20869 , +-25391 , +10025 , +19493 , +-19245 , +14751 , +29647 , +-11629 , +-7211 , +29753 , +15363 , +833 , +-21195 , +-17979 , +28093 , +-24791 , +8649 , +20517 , +-22383 , +-9297 , +-22885 , +9195 , +29197 , +2261 , +28301 , +17623 , +-30073 , +-3597 , +-28573 , +-14139 , +31353 , +-3857 , +4451 , +19763 , +-4003 , +11253 , +-17299 , +-12497 , +1791 , +-2637 , +7571 , +4557 , +3159 , +-14329 , +31275 , +19243 , +-7963 , +-11961 , +7535 , +20443 , +-30847 , +-29723 , +-11889 , +-2841 , +-581 , +22713 , +-8881 , +-8131 , +-2901 , +-27731 , +24087 , +32691 , +-32171 , +6911 , +22163 , +24185 , +25459 , +-16149 , +18887 , +-28401 , +-6699 , +-24587 , +-17755 , +28609 , +4921 , +-13935 , +26667 , +22431 , +13471 , +18275 , +-25099 , +-22035 , +17961 , +-6407 , +29017 , +-15829 , +29541 , +-14345 , +17149 , +6779 , +13365 , +9443 , +23791 , +22183 , +8731 , +20039 , +1341 , +28051 , +7705 , +20601 , +-8945 , +-22221 , +-8447 , +15309 , +-7107 , +-19195 , +-32683 , +-30899 , +-1689 , +29455 , +10653 , +-31245 , +11917 , +-12469 , +26167 , +26203 , +-13781 , +18855 , +17853 , +-19197 , +19657 , +28289 , +-9007 , +-9983 , +21273 , +-2671 , +15995 , +-31945 , +-21361 , +-16527 , +-31235 , +-30707 , +32373 , +27015 , +2355 , +7081 , +-13431 , +-20343 , +19295 , +-5971 , +14349 , +22893 , +-14197 , +-1695 , +25191 , +-10013 , +12639 , +-5253 , +-22477 , +29007 , +12149 , +26189 , +-20511 , +-193 , +18995 , +19323 , +-28985 , +11361 , +1061 , +-26047 , +-7237 , +16641 , +-14125 , +32023 , +-16853 , +19453 , +-15589 , +31227 , +-22087 , +-9923 , +13315 , +15645 , +-18867 , +-4439 , +25117 , +-2527 , +-11087 , +-30807 , +-18097 , +-16437 , +24483 , +18193 , +13113 , +2625 , +10615 , +-26717 , +-24569 , +32705 , +-6617 , +-3323 , +-6199 , +23507 , +18927 , +-30923 , +-9143 , +-21241 , +-19359 , +-3451 , +-19607 , +31025 , +-16383 , +19983 , +-15883 , +15377 , +-29093 , +16051 , +-28929 , +-18271 , +10397 , +17545 , +-10313 , +-27463 , +-13141 , +219 , +-25667 , +-18605 , +32443 , +-21857 , +-13823 , +-7873 , +-18579 , +26993 , +-23017 , +30813 , +-31139 , +-12547 , +32271 , +-689 , +325 , +9999 , +-14131 , +9147 , +22413 , +-10765 , +17635 , +1273 , +25187 , +32123 , +12261 , +25939 , +2393 , +8309 , +11847 , +-31817 , +21369 , +-865 , +-1105 , +27635 , +31963 , +21285 , +31695 , +17257 , +-5949 , +-10351 , +17343 , +-30641 , +18485 , +-695 , +13269 , +-17571 , +-13047 , +-9335 , +14839 , +27657 , +-15987 , +-8235 , +-11141 , +8001 , +23701 , +1775 , +28029 , +2211 , +10775 , +-11173 , +9903 , +3633 , +-8131 , +-16307 , +11709 , +3725 , +-1783 , +21537 , +12575 , +-7761 , +-6051 , +-21161 , +3441 , +3099 , +18085 , +-24823 , +19275 , +-25437 , +-14373 , +10727 , +-31337 , +11405 , +22323 , +-32089 , +20593 , +31325 , +12067 , +24323 , +-18315 , +-26875 , +17925 , +-16081 , +-3425 , +7579 , +-6359 , +-1579 , +21659 , +28053 , +-12173 , +6275 , +11685 , +24445 , +-21397 , +-32079 , +-26657 , +27697 , +16605 , +-5843 , +-9695 , +-16755 , +10733 , +21525 , +29279 , +10165 , +31149 , +32087 , +24691 , +28093 , +5181 , +12707 , +-13951 , +-4887 , +8277 , +-4131 , +-29753 , +869 , +25709 , +32549 , +-9481 , +16249 , +-6069 , +-19649 , +32015 , +-14265 , +-19685 , +6035 , +-16459 , +-1795 , +-495 , +-18269 , +-16889 , +-22897 , +-19601 , +-15355 , +3835 , +2033 , +-28113 , +14041 , +29745 , +-18227 , +-12783 , +21185 , +-24241 , +-12611 , +-31691 , +4441 , +-19497 , +30971 , +-9161 , +20017 , +29569 , +8875 , +11711 , +-8383 , +-3315 , +-28803 , +671 , +21481 , +-22107 , +-5389 , +19819 , +-28067 , +-25427 , +16921 , +-21361 , +2983 , +-19939 , +24499 , +4579 , +-16871 , +-15525 , +-31999 , +-22833 , +-16821 , +-30577 , +-5903 , +17623 , +32399 , +-2945 , +-24623 , +23225 , +-29467 , +6377 , +-25191 , +-27135 , +-131 , +11087 , +-28533 , +10535 , +18341 , +-15775 , +25217 , +1569 , +-23733 , +-7227 , +-6505 , +-6787 , +-6935 , +-1417 , +-22167 , +29181 , +-13815 , +19873 , +23495 , +28843 , +-26571 , +4081 , +-12299 , +15723 , +14447 , +-24719 , +343 , +29729 , +-30413 , +3551 , +7859 , +7745 , +7903 , +-30331 , +3813 , +15585 , +10935 , +-16747 , +26649 , +1887 , +-16291 , +-14085 , +20861 , +-18837 , +12735 , +-12619 , +18307 , +13229 , +-18023 , +-9549 , +14993 , +-31281 , +11371 , +4133 , +59 , +20767 , +-6163 , +-12711 , +-28935 , +17569 , +-18165 , +-8941 , +-919 , +-13395 , +-4007 , +14687 , +-18951 , +-9219 , +23823 , +-25867 , +-5081 , +14421 , +26241 , +18945 , +-22471 , +-119 , +-1003 , +23947 , +-31629 , +-8157 , +-27719 , +-1471 , +32461 , +-14223 , +-4385 , +-22053 , +-8657 , +27429 , +-8713 , +25323 , +-24021 , +28777 , +-17829 , +22837 , +29997 , +-21643 , +-12583 , +11919 , +-26311 , +11439 , +26267 , +-25553 , +-14559 , +-30667 , +-17751 , +11401 , +30781 , +10501 , +30173 , +7591 , +-27993 , +2189 , +1879 , +1021 , +-4117 , +-23875 , +31617 , +17859 , +-18873 , +32427 , +4987 , +1747 , +-931 , +9127 , +21271 , +-25355 , +-20627 , +-11573 , +-17069 , +9409 , +13331 , +-8927 , +-2225 , +20209 , +-18063 , +-4561 , +-30265 , +-449 , +-18697 , +8977 , +-1785 , +-12873 , +-29553 , +17947 , +27495 , +6035 , +-17061 , +1763 , +-27071 , +-27505 , +-17171 , +-31005 , +10603 , +11205 , +-14597 , +4747 , +28971 , +2819 , +-18021 , +24287 , +26291 , +-24665 , +27127 , +9095 , +-6377 , +-30737 , +27531 , +26993 , +18631 , +5335 , +-15913 , +26077 , +1921 , +29807 , +29853 , +14847 , +-16683 , +7349 , +32399 , +28437 , +11023 , +-28949 , +3733 , +-30979 , +26807 , +2925 , +-27783 , +31049 , +10889 , +19985 , +-30173 , +29921 , +7659 , +-5389 , +-31147 , +-16879 , +13797 , +25559 , +28125 , +299 , +5273 , +-29185 , +24143 , +-3689 , +19263 , +24701 , +13631 , +-29335 , +-22381 , +-15595 , +13045 , +-8829 , +19929 , +30089 , +-20563 , +-30171 , +-15793 , +-22657 , +23365 , +7179 , +-17119 , +22731 , +-135 , +16893 , +-8725 , +6737 , +15519 , +-3345 , +2985 , +18265 , +14551 , +-15215 , +-19919 , +20325 , +-17971 , +20079 , +-27091 , +10385 , +-24347 , +-3705 , +30609 , +-32161 , +16895 , +-9125 , +14993 , +-12005 , +-29529 , +-23663 , +-12511 , +-13911 , +32721 , +18183 , +-28957 , +26085 , +-8179 , +-1175 , +18851 , +2421 , +-22461 , +-28593 , +-18349 , +-8411 , +11499 , +-13617 , +-29061 , +1725 , +27073 , +-29545 , +-7619 , +-21669 , +29183 , +8075 , +8893 , +-26041 , +31515 , +32207 , +21799 , +29261 , +31217 , +-4499 , +-12257 , +923 , +-13687 , +-12695 , +11709 , +-2037 , +-9653 , +-8623 , +-21503 , +23563 , +19633 , +-5023 , +-19503 , +8171 , +-28025 , +13077 , +-16789 , +10677 , +27547 , +17471 , +20831 , +3979 , +19199 , +-10077 , +18699 , +4729 , +5561 , +23565 , +10635 , +29139 , +13307 , +-29205 , +-20933 , +-20733 , +27875 , +3681 , +20385 , +-9743 , +-31577 , +12261 , +-2055 , +32199 , +5467 , +-6825 , +-25067 , +18011 , +-26085 , +9365 , +-275 , +-2563 , +9421 , +-27243 , +11651 , +-15407 , +-18861 , +-6655 , +12647 , +-17751 , +-20151 , +-26297 , +27565 , +12377 , +24373 , +-21191 , +-1441 , +-4715 , +73 , +-5343 , +-11649 , +7747 , +23953 , +15705 , +-14217 , +-23977 , +21935 , +-7839 , +16143 , +-10459 , +23577 , +-12675 , +-19213 , +28997 , +25285 , +10443 , +-5993 , +32477 , +9837 , +6355 , +-13629 , +10885 , +21821 , +-8277 , +-2181 , +22163 , +-30703 , +32649 , +-4735 , +-22273 , +-31185 , +-12071 , +-17337 , +8117 , +-13451 , +23511 , +24685 , +-14999 , +-14051 , +-12627 , +-31057 , +-24839 , +-10001 , +26623 , +-4757 , +26941 , +23283 , +11791 , +7311 , +16225 , +-2631 , +19019 , +-21489 , +-15939 , +28931 , +24939 , +-12055 , +-10961 , +8957 , +16393 , +26767 , +-27919 , +26627 , +-19529 , +15081 , +-32523 , +7367 , +-5997 , +-21815 , +-21839 , +-27881 , +9069 , +-29467 , +-19831 , +-1779 , +12363 , +23881 , +29589 , +-21815 , +23955 , +-29865 , +19465 , +26283 , +23449 , +5179 , +-22529 , +-9205 , +-10057 , +9187 , +-6947 , +-29589 , +12779 , +-2953 , +9501 , +30517 , +4075 , +-23467 , +11443 , +-30731 , +18621 , +14975 , +-8739 , +16139 , +-8753 , +-28257 , +28289 , +-29469 , +28303 , +24953 , +-4611 , +22453 , +-2169 , +7905 , +13191 , +-23629 , +13803 , +-5579 , +-13057 , +-10811 , +-30787 , +17499 , +1613 , +2247 , +-24481 , +-15829 , +-24273 , +-4809 , +-5719 , +30329 , +21917 , +11121 , +-5755 , +19067 , +-19811 , +-16279 , +-31739 , +-815 , +30611 , +19683 , +29181 , +-275 , +-475 , +-12505 , +-15335 , +-5859 , +-13171 , +-16579 , +-13711 , +-17167 , +-6037 , +1443 , +14511 , +-20929 , +557 , +-15227 , +-8557 , +-21861 , +4313 , +27511 , +-13029 , +22343 , +30311 , +3497 , +16409 , +-16975 , +17569 , +29347 , +9277 , +24167 , +-17807 , +-9861 , +-28221 , +-7531 , +-28225 , +-6511 , +4985 , +9209 , +13767 , +-19523 , +4703 , +-15525 , +31219 , +31509 , +15803 , +1411 , +-5839 , +-11243 , +18359 , +11959 , +17867 , +-1179 , +-12681 , +5295 , +20927 , +7437 , +-13911 , +7949 , +30617 , +6439 , +21675 , +28243 , +27591 , +-17635 , +11539 , +24929 , +24183 , +-9375 , +-16935 , +12649 , +-10775 , +25507 , +3807 , +-9115 , +-14007 , +-21113 , +28947 , +5651 , +5129 , +13283 , +16127 , +30575 , +-9801 , +3699 , +-30231 , +-23391 , +-3497 , +12301 , +2919 , +-24191 , +-2251 , +-8347 , +13177 , +3205 , +2121 , +25143 , +-21731 , +30783 , +-7679 , +21255 , +9065 , +-25767 , +23455 , +-26277 , +-14041 , +-28931 , +-6631 , +31853 , +13541 , +-11293 , +9057 , +-14237 , +12181 , +21937 , +11849 , +32271 , +9121 , +9485 , +-21797 , +1307 , +-28029 , +8187 , +14119 , +22733 , +26331 , +16619 , +21669 , +10041 , +31503 , +-13277 , +25097 , +23285 , +11351 , +5051 , +-16995 , +1881 , +21091 , +2583 , +-22507 , +12085 , +29539 , +23261 , +-21 , +24069 , +-29521 , +17009 , +27957 , +-29783 , +18385 , +-9247 , +5629 , +17061 , +-3029 , +7535 , +29467 , +-32559 , +7425 , +15225 , +23945 , +19091 , +5145 , +-22023 , +-5053 , +26777 , +18645 , +29823 , +14993 , +18445 , +-15421 , +9375 , +-20755 , +30033 , +-24901 , +-4361 , +-9641 , +-22219 , +-11913 , +24219 , +-30681 , +-8015 , +10921 , +14095 , +5741 , +30493 , +-12911 , +-15159 , +-20797 , +-17697 , +3097 , +21531 , +30633 , +-2889 , +-2705 , +1715 , +22107 , +22883 , +28947 , +-16493 , +22825 , +-8733 , +15993 , +23945 , +25171 , +26157 , +-20193 , +-993 , +11093 , +18023 , +-32477 , +29473 , +14547 , +-29031 , +-30633 , +-13177 , +-10533 , +6383 , +-15389 , +-5893 , +-18991 , +-11671 , +29269 , +2755 , +16307 , +13843 , +-22981 , +32577 , +15877 , +29381 , +9535 , +7915 , +-6119 , +13135 , +-5195 , +-9279 , +-3597 , +-32451 , +11455 , +5699 , +-19561 , +-17911 , +9951 , +-3855 , +231 , +3793 , +-23283 , +23097 , +-13831 , +-31089 , +-31661 , +1269 , +7153 , +-1315 , +5603 , +1889 , +-26025 , +1815 , +-19021 , +22673 , +2287 , +25131 , +28041 , +-7053 , +-497 , +-25921 , +-859 , +28215 , +21889 , +-21007 , +7113 , +-1705 , +31689 , +28813 , +21979 , +-3841 , +10769 , +17093 , +19705 , +-14827 , +-21901 , +1645 , +-15345 , +15271 , +15575 , +-12373 , +17653 , +6627 , +-19387 , +18485 , +-17663 , +32663 , +-6969 , +15627 , +-9693 , +-30179 , +-1605 , +20133 , +-21893 , +-29729 , +19625 , +15287 , +4207 , +-30393 , +-11105 , +-16799 , +-22199 , +13367 , +-14843 , +29673 , +-11187 , +7689 , +31485 , +-14603 , +16457 , +22527 , +15407 , +21571 , +-10821 , +14909 , +557 , +-15909 , +21851 , +-30401 , +-14527 , +-32561 , +-31939 , +-20007 , +-32307 , +29039 , +13925 , +21413 , +24351 , +-7681 , +9439 , +-11773 , +22213 , +-8203 , +-15271 , +9099 , +-20879 , +21419 , +5943 , +-26615 , +-31165 , +-8549 , +-16847 , +-13071 , +1453 , +-3049 , +9827 , +-30629 , +16575 , +9337 , +11245 , +-19845 , +28171 , +4843 , +2309 , +9623 , +-31499 , +3469 , +-5739 , +-29571 , +-9073 , +-16327 , +-1205 , +1919 , +-7441 , +-1607 , +21049 , +-12309 , +-31483 , +-1157 , +31209 , +-28159 , +24313 , +19407 , +2805 , +-19095 , +19711 , +-32107 , +7455 , +19503 , +29867 , +2177 , +-4633 , +-8133 , +24277 , +16589 , +-27731 , +-10427 , +14821 , +5487 , +5433 , +-23213 , +-9043 , +24023 , +-16927 , +-31319 , +-24117 , +6175 , +1563 , +-3513 , +-19599 , +-4917 , +-5997 , +-28189 , +-8243 , +-2819 , +-1081 , +-11175 , +-29229 , +15149 , +10269 , +-2647 , +-5471 , +-4511 , +21115 , +-24721 , +-6321 , +-16411 , +-11421 , +-7977 , +8009 , +25479 , +4739 , +-19175 , +16167 , +-21945 , +7891 , +-12177 , +1031 , +12181 , +-25809 , +-5233 , +27493 , +4361 , +-10397 , +17823 , +11119 , +-22375 , +28117 , +-27471 , +3037 , +-16047 , +15759 , +7353 , +14163 , +16009 , +6361 , +9477 , +7465 , +-21083 , +89 , +-31687 , +-1069 , +-17853 , +17059 , +31421 , +-21587 , +-775 , +22609 , +-27709 , +-15785 , +7307 , +-11101 , +-15183 , +-22895 , +-18009 , +17035 , +-31965 , +-21363 , +7441 , +18001 , +2399 , +-11573 , +8303 , +-9309 , +-32435 , +14189 , +18795 , +2095 , +19951 , +-8685 , +-28805 , +-9537 , +11101 , +-8653 , +-15341 , +3783 , +23859 , +-28177 , +5471 , +11401 , +-23659 , +-8855 , +-23693 , +32167 , +11935 , +9893 , +-24559 , +-20935 , +18531 , +5595 , +-3881 , +29289 , +-4777 , +-18867 , +-13321 , +2187 , +2903 , +4001 , +18293 , +-4177 , +-24801 , +-12353 , +21207 , +-21821 , +26673 , +7451 , +4969 , +-6113 , +27495 , +10653 , +6885 , +-6739 , +-1067 , +-25107 , +28859 , +26989 , +-32183 , +30035 , +-6725 , +9887 , +-17589 , +25095 , +-21927 , +-6321 , +-23675 , +21011 , +-24743 , +21109 , +-13623 , +11425 , +22807 , +-22905 , +17791 , +24537 , +19755 , +16533 , +-2903 , +22327 , +8883 , +18399 , +23627 , +29287 , +-25343 , +21995 , +-16271 , +-27501 , +6355 , +29477 , +-16225 , +-7097 , +5141 , +16363 , +10701 , +-11327 , +-18425 , +-24013 , +14043 , +2509 , +-8697 , +-12397 , +-2163 , +17177 , +-31039 , +3049 , +5637 , +-15341 , +15333 , +-2969 , +-19791 , +29499 , +21601 , +-20687 , +-28977 , +13309 , +-27875 , +-10379 , +15709 , +-26101 , +6189 , +32253 , +-28015 , +-29389 , +7307 , +5711 , +2519 , +-2631 , +28753 , +-22461 , +23113 , +2347 , +13167 , +7701 , +-3687 , +20413 , +-16155 , +1797 , +-29281 , +-1505 , +17525 , +-22935 , +-21443 , +-24619 , +-3355 , +-22709 , +2531 , +-497 , +23725 , +19577 , +-6523 , +-12539 , +-11465 , +29991 , +18701 , +20937 , +22673 , +19963 , +-1699 , +-25953 , +4521 , +1711 , +26813 , +17373 , +-19709 , +25641 , +16603 , +-26821 , +-8207 , +-30967 , +-11973 , +-14423 , +-2995 , +-16695 , +4921 , +21427 , +12461 , +-16039 , +31863 , +10317 , +-16097 , +7977 , +22491 , +-25551 , +-27039 , +19409 , +-8955 , +-9291 , +-30315 , +4893 , +-16819 , +-8923 , +-15747 , +-11605 , +25899 , +30101 , +-10191 , +20481 , +-27327 , +-22975 , +-23467 , +-31963 , +-21045 , +-17819 , +16603 , +11705 , +16791 , +19849 , +10281 , +-26997 , +15737 , +-11671 , +-4123 , +16821 , +21837 , +-19903 , +-27107 , +-723 , +-4245 , +-25429 , +-9975 , +6629 , +18069 , +8183 , +-28353 , +10593 , +-1409 , +8703 , +-31127 , +6091 , +-14659 , +20867 , +-18813 , +-1397 , +-26561 , +10239 , +-30833 , +27497 , +-18107 , +-27643 , +-9269 , +-14317 , +19419 , +-7153 , +-32659 , +11851 , +-13617 , +2529 , +-4391 , +-29591 , +-14039 , +-12711 , +-10149 , +-24953 , +-22489 , +3527 , +29787 , +12295 , +31659 , +-27443 , +2331 , +31161 , +-10945 , +-19025 , +-22807 , +-2965 , +-21113 , +11819 , +-29223 , +30725 , +9271 , +30167 , +13825 , +-223 , +20109 , +3313 , +29223 , +-6373 , +-13235 , +-7229 , +-23291 , +1207 , +23349 , +29293 , +-32517 , +25901 , +8435 , +-26297 , +19013 , +5065 , +-7265 , +-7759 , +5049 , +-17415 , +-5961 , +14197 , +-4615 , +32756 , +-19821 , +-19817 , +-32469 , +-9277 , +21593 , +-30291 , +2363 , +-4893 , +-27521 , +-15167 , +11395 , +-2473 , +-27205 , +-14183 , +-23279 , +31047 , +15997 , +21147 , +13401 , +-17907 , +5863 , +-733 , +-9875 , +2519 , +-10933 , +-7081 , +-15951 , +-21315 , +20757 , +-31867 , +-5089 , +-19371 , +5201 , +25329 , +-2317 , +-22833 , +17309 , +-20933 , +4073 , +19083 , +5281 , +19243 , +32499 , +28207 , +-29947 , +-30449 , +-15505 , +1351 , +-19473 , +145 , +-17433 , +29009 , +6135 , +-17393 , +-12225 , +20323 , +-25699 , +16499 , +-27019 , +-24011 , +-31161 , +-29041 , +-5681 , +-20287 , +-6221 , +-19219 , +-4957 , +29019 , +5107 , +2609 , +-4995 , +-9913 , +28129 , +-22557 , +-24347 , +-5935 , +14365 , +15833 , +-17267 , +-13335 , +-23427 , +-10753 , +18707 , +-6353 , +-9713 , +-24393 , +-15057 , +10653 , +10633 , +25011 , +32113 , +31375 , +10305 , +-27325 , +6009 , +-25499 , +-5719 , +-6599 , +-14423 , +23445 , +3915 , +3131 , +10597 , +25161 , +-6351 , +-21865 , +12745 , +-30609 , +20721 , +18339 , +13533 , +-1957 , +-24297 , +-2923 , +30031 , +-45 , +15137 , +-16945 , +13997 , +-6733 , +6651 , +31685 , +-13799 , +-25605 , +-273 , +7249 , +-29303 , +-22927 , +32547 , +-891 , +21877 , +3503 , +-22637 , +27403 , +14611 , +-18753 , +28545 , +-5385 , +14609 , +-2247 , +-20107 , +20257 , +-18227 , +-16945 , +-7507 , +17923 , +16903 , +10093 , +16669 , +28165 , +-29915 , +-10027 , +-20507 , +-30115 , +14301 , +-2901 , +-1469 , +-3991 , +19571 , +1559 , +-19183 , +-14975 , +-13449 , +-18473 , +30399 , +9553 , +30195 , +-20517 , +-25151 , +-14159 , +9771 , +26461 , +23957 , +17665 , +-17203 , +22387 , +18989 , +31737 , +6321 , +21041 , +6643 , +21511 , +4363 , +24631 , +-10697 , +20777 , +-5591 , +-1329 , +12843 , +9789 , +15525 , +-1401 , +16481 , +-10531 , +-14559 , +4671 , +16059 , +-32323 , +8825 , +11981 , +-20255 , +27513 , +-12153 , +-27893 , +-32445 , +25075 , +-25267 , +2169 , +24715 , +4135 , +-13641 , +-951 , +7059 , +23177 , +-307 , +-7933 , +8159 , +23513 , +27761 , +-21353 , +-6501 , +6777 , +11921 , +-13585 , +32263 , +-29109 , +19937 , +23829 , +-5767 , +3841 , +26901 , +7363 , +-28721 , +-15619 , +30615 , +-17291 , +28783 , +9895 , +-24897 , +7183 , +22195 , +17469 , +-28275 , +10731 , +-15381 , +-19399 , +29405 , +-14225 , +-14383 , +-483 , +-19933 , +-28625 , +32639 , +29135 , +-9563 , +-14719 , +29423 , +4471 , +-13017 , +24715 , +-30489 , +-23607 , +23603 , +27375 , +-13953 , +-30995 , +-15671 , +-21045 , +-22775 , +23501 , +-4719 , +-6809 , +1431 , +8683 , +3745 , +26433 , +-18195 , +-9273 , +29609 , +-29785 , +-20231 , +21413 , +5809 , +-19507 , +-29495 , +6385 , +-7855 , +17515 , +-13301 , +19987 , +6757 , +27857 , +22265 , +24265 , +-2489 , +4735 , +-27427 , +14073 , +-15987 , +-18117 , +-14081 , +4629 , +-25037 , +-16463 , +-4569 , +31459 , +19299 , +-14207 , +-14199 , +-27677 , +-4191 , +-22565 , +26185 , +16417 , +23945 , +-21091 , +-14743 , +17547 , +-13563 , +-23585 , +-8631 , +-1585 , +29449 , +23061 , +-19045 , +-22867 , +6593 , +5285 , +-12069 , +6865 , +-5293 , +-18185 , +-23995 , +-24017 , +-21225 , +3611 , +14675 , +-5935 , +-18107 , +-5673 , +-5969 , +-6339 , +-17099 , +-24003 , +6833 , +28481 , +-19941 , +-25647 , +3151 , +29009 , +2099 , +19467 , +-22883 , +-28067 , +31875 , +-30583 , +11969 , +10793 , +-28403 , +31375 , +1129 , +16933 , +8077 , +3885 , +9927 , +-21301 , +-341 , +15319 , +-18423 , +-12951 , +12723 , +-4237 , +14159 , +10373 , +-25897 , +2045 , +-22241 , +21685 , +-22567 , +9367 , +26219 , +25585 , +-3767 , +-21469 , +-13837 , +23913 , +17477 , +-8101 , +29783 , +-8215 , +3743 , +21871 , +24181 , +-31577 , +-23127 , +-23025 , +29303 , +6809 , +24415 , +-17389 , +-7365 , +21079 , +-2525 , +-31353 , +-1449 , +-3477 , +12021 , +28233 , +-27513 , +11311 , +14895 , +30239 , +1195 , +10521 , +-14663 , +15185 , +-27329 , +26791 , +16317 , +-11843 , +24653 , +1697 , +11495 , +-16781 , +-18959 , +-32253 , +11545 , +-4147 , +-14011 , +7241 , +-31835 , +2561 , +-9255 , +26959 , +-20481 , +-8125 , +-24647 , +10145 , +2049 , +29267 , +2005 , +-1701 , +-13165 , +18077 , +16129 , +5501 , +-20241 , +30921 , +-659 , +-30269 , +19547 , +21725 , +-2921 , +9471 , +28241 , +-10547 , +-30257 , +-24085 , +-12981 , +-6507 , +-26849 , +10891 , +2025 , +-22319 , +27347 , +-13315 , +28859 , +-17451 , +-17051 , +-3373 , +-25497 , +-18103 , +-10757 , +-30741 , +10863 , +-11205 , +-27299 , +-14901 , +-16287 , +-5189 , +-24723 , +24177 , +-20593 , +-5651 , +23331 , +2483 , +15697 , +-14419 , +251 , +5137 , +1455 , +3223 , +28665 , +1553 , +28833 , +9137 , +281 , +-1003 , +-20027 , +23663 , +4427 , +-14669 , +19099 , +-4003 , +31209 , +27537 , +-30921 , +-6865 , +-20561 , +7859 , +-4743 , +9045 , +-16333 , +19551 , +5835 , +-26339 , +-6689 , +-13459 , +-5035 , +-15807 , +-5531 , +-12255 , +-16971 , +27655 , +4031 , +-18553 , +10807 , +3537 , +-18535 , +17221 , +21647 , +-29121 , +-32421 , +24051 , +22797 , +-13121 , +5775 , +-7 , +32345 , +-14427 , +24039 , +19685 , +6315 , +-18743 , +19627 , +-32451 , +-26755 , +-3429 , +3773 , +-14115 , +-18993 , +-69 , +-17151 , +-27185 , +17615 , +-26865 , +23139 , +-28767 , +-30433 , +611 , +20295 , +-19651 , +-23929 , +-23177 , +7043 , +-17601 , +-2519 , +2973 , +30427 , +26839 , +4933 , +20941 , +-26637 , +-15087 , +2661 , +17733 , +-9783 , +-3399 , +-20713 , +3737 , +30637 , +-22349 , +-17363 , +-16055 , +-26691 , +-4919 , +21099 , +-22555 , +23509 , +9995 , +-13881 , +-23401 , +12559 , +9643 , +19741 , +32325 , +5559 , +10571 , +14435 , +29223 , +3521 , +-28199 , +-20115 , +-7719 , +32197 , +17383 , +29463 , +30203 , +-23431 , +24199 , +17157 , +-29371 , +-5473 , +22943 , +2527 , +20509 , +16775 , +9405 , +1529 , +16563 , +18435 , +24185 , +4257 , +-24677 , +28131 , +15427 , +28097 , +31963 , +-12829 , +15045 , +7723 , +-12913 , +-2515 , +11949 , +11327 , +24057 , +22349 , +-12777 , +-5327 , +-2021 , +-28243 , +19029 , +-24387 , +-26927 , +22913 , +4689 , +-28331 , +-667 , +10577 , +21855 , +-6421 , +-29777 , +31457 , +24217 , +27161 , +-22879 , +-16717 , +24755 , +-31259 , +-29335 , +-13831 , +-13733 , +-29203 , +-3323 , +-3311 , +-17657 , +-16597 , +13403 , +-27525 , +-20399 , +-3291 , +-32045 , +11859 , +979 , +32169 , +-9365 , +-8635 , +20857 , +11521 , +8787 , +26123 , +24157 , +-6993 , +15109 , +30811 , +-26599 , +-13661 , +29911 , +-31635 , +-15189 , +32503 , +9245 , +-18457 , +-1343 , +22045 , +-16457 , +28509 , +31381 , +3491 , +23345 , +-12993 , +32583 , +-3229 , +-10923 , +-20641 , +-24397 , +-2243 , +-27835 , +-17699 , +-8759 , +-24751 , +8215 , +-18781 , +-6297 , +22197 , +-30491 , +-5021 , +-15443 , +3759 , +-12945 , +-14331 , +25053 , +-21913 , +15657 , +28065 , +13989 , +11561 , +6359 , +32255 , +30983 , +8981 , +20649 , +-15993 , +6053 , +15447 , +-18737 , +-3651 , +-351 , +-27929 , +32397 , +22837 , +-14867 , +-27979 , +24543 , +-32243 , +24621 , +-913 , +14211 , +-21783 , +-7677 , +-1365 , +31641 , +14951 , +-1547 , +-15961 , +23739 , +-5869 , +12471 , +-20093 , +-5229 , +-9749 , +-30195 , +29425 , +6901 , +22855 , +-25059 , +1653 , +-2445 , +31327 , +-15537 , +15895 , +-6795 , +19261 , +24727 , +-26209 , +21213 , +-10443 , +95 , +-693 , +-28407 , +-20515 , +15307 , +15111 , +21123 , +13445 , +5797 , +-6619 , +-28923 , +20529 , +-7257 , +27033 , +11549 , +-6643 , +18775 , +-10071 , +18501 , +-23445 , +32609 , +29227 , +27503 , +30261 , +23661 , +20031 , +-26579 , +19177 , +19577 , +11901 , +29247 , +27917 , +-14419 , +-5959 , +26539 , +7983 , +25013 , +25651 , +11613 , +-18609 , +2461 , +-24239 , +26677 , +-3865 , +-28123 , +-15397 , +-9563 , +-21161 , +6805 , +-26709 , +-4409 , +-9499 , +28701 , +-30741 , +-2827 , +-17873 , +-83 , +-32563 , +-4381 , +14885 , +28735 , +-19521 , +16183 , +-23931 , +32199 , +-18903 , +5529 , +17613 , +11377 , +-3423 , +-4261 , +27571 , +-4977 , +-7011 , +1149 , +16677 , +-14623 , +5817 , +-1703 , +-7495 , +10615 , +23399 , +-21333 , +23717 , +27909 , +14369 , +31283 , +-15557 , +-21829 , +-1231 , +-13879 , +8933 , +-1379 , +29655 , +17139 , +32397 , +-19875 , +-15091 , +32003 , +-27479 , +-17233 , +19133 , +-31833 , +-23899 , +-24281 , +2423 , +2061 , +-8481 , +21643 , +-24411 , +-27029 , +-7903 , +27053 , +14157 , +-22493 , +-20071 , +-17721 , +23363 , +-5541 , +-18867 , +9033 , +19165 , +-28403 , +14101 , +25153 , +-24269 , +3749 , +-20459 , +-17121 , +-9005 , +2071 , +-21837 , +31519 , +-18179 , +-8841 , +21777 , +-12007 , +-11953 , +-24813 , +-28671 , +21971 , +-30707 , +-14583 , +-21629 , +-26903 , +-22833 , +-28833 , +-30283 , +-6639 , +-20037 , +15517 , +24657 , +-2295 , +25917 , +13537 , +-12123 , +26073 , +22083 , +15227 , +-29173 , +-16963 , +11501 , +-22267 , +19163 , +6259 , +29131 , +-2059 , +9193 , +-4591 , +26007 , +32191 , +17023 , +11625 , +-9373 , +-22427 , +-4917 , +13527 , +-29349 , +-26483 , +-17179 , +-15465 , +-7171 , +28711 , +13881 , +31657 , +-22585 , +11635 , +29065 , +3097 , +-27271 , +27303 , +5985 , +-25623 , +19657 , +-9729 , +24847 , +-29353 , +-28261 , +-10665 , +22557 , +12739 , +22459 , +-8125 , +3141 , +-31233 , +-28397 , +24493 , +-2069 , +-28887 , +13923 , +-32289 , +19227 , +28679 , +-32137 , +-29653 , +21749 , +-12585 , +-10267 , +31477 , +-15441 , +-23633 , +18755 , +17753 , +-3321 , +1871 , +15319 , +-25291 , +323 , +6781 , +7387 , +-31799 , +-7523 , +-25123 , +-24271 , +-30001 , +11077 , +21057 , +-30831 , +6675 , +-14381 , +-18031 , +21843 , +-28283 , +23623 , +20497 , +1433 , +-24617 , +-32397 , +-10681 , +8971 , +-23145 , +-26363 , +-15541 , +17425 , +31935 , +28653 , +30627 , +24967 , +31957 , +26467 , +18583 , +-3 , +4987 , +23639 , +-1011 , +-23709 , +-13933 , +1389 , +-13085 , +-31411 , +3269 , +-141 , +-28741 , +1439 , +-27221 , +16471 , +4197 , +-12843 , +-15779 , +10407 , +16295 , +7847 , +-17017 , +-5251 , +18845 , +16467 , +-13813 , +-31485 , +11409 , +-29365 , +-29935 , +-2207 , +-6063 , +3951 , +-24415 , +1599 , +-8697 , +10181 , +28859 , +10417 , +30865 , +14515 , +29941 , +-5703 , +-19109 , +-13641 , +-7033 , +28479 , +-23117 , +9113 , +4843 , +24445 , +-32601 , +-14293 , +23287 , +-8953 , +23893 , +-8069 , +-4501 , +-11977 , +11725 , +-2415 , +25111 , +15661 , +4703 , +1953 , +20069 , +-14015 , +-25223 , +24517 , +-9091 , +19197 , +8191 , +14391 , +-26669 , +31129 , +-27107 , +-28663 , +23621 , +-30485 , +19627 , +14165 , +-18253 , +-7449 , +-10505 , +-31485 , +-25067 , +-18541 , +27939 , +-20745 , +-19695 , +-25733 , +19205 , +15561 , +9241 , +-4937 , +10095 , +-29437 , +18427 , +13903 , +23571 , +-6957 , +-3835 , +19011 , +-10791 , +585 , +-15731 , +18943 , +26037 , +-22267 , +25367 , +21837 , +-30211 , +8571 , +-7451 , +6101 , +18503 , +8867 , +12051 , +-4849 , +12215 , +7737 , +-5845 , +-11585 , +7143 , +26469 , +31557 , +-7699 , +-12241 , +11271 , +-16237 , +-31145 , +901 , +-18335 , +6787 , +11379 , +-2861 , +-683 , +19029 , +-25123 , +8145 , +-12005 , +-6357 , +-15275 , +10841 , +-7559 , +-14161 , +2871 , +-23993 , +-10629 , +15903 , +5997 , +-23613 , +-30547 , +27115 , +3571 , +39 , +-6701 , +-26163 , +8385 , +-685 , +22811 , +-3235 , +-26035 , +17791 , +17373 , +19755 , +8061 , +8091 , +30671 , +-29607 , +24611 , +-30687 , +11195 , +24243 , +-4621 , +17009 , +25279 , +-22207 , +29179 , +31399 , +15865 , +-31893 , +-1889 , +4083 , +12487 , +5761 , +-29689 , +8051 , +-28797 , +14817 , +-10971 , +-6263 , +28849 , +9095 , +-1251 , +-25679 , +22713 , +1319 , +31055 , +16609 , +-22491 , +-4661 , +9151 , +10837 , +17495 , +-14371 , +4629 , +12017 , +29373 , +-13361 , +-22253 , +12055 , +24205 , +16165 , +31377 , +761 , +16631 , +-10213 , +13291 , +27003 , +-23577 , +-25169 , +21251 , +3969 , +-18635 , +-25535 , +-9797 , +18379 , +12385 , +18091 , +-18467 , +-29867 , +-21303 , +-9255 , +9125 , +23069 , +3679 , +-22309 , +-26451 , +-27509 , +-13595 , +32643 , +-19089 , +-6841 , +-23129 , +14719 , +-20685 , +21383 , +-13399 , +-24597 , +-27507 , +-27153 , +-13715 , +-28825 , +5713 , +15851 , +22811 , +-20291 , +3859 , +21375 , +27721 , +-25113 , +-32493 , +31143 , +-29655 , +-13387 , +17089 , +13097 , +-6849 , +4059 , +4525 , +24561 , +2981 , +7059 , +17407 , +-29977 , +-5959 , +-15703 , +-12167 , +8265 , +-13487 , +26399 , +-6945 , +9343 , +4741 , +24893 , +-15619 , +-31881 , +27347 , +-17365 , +7191 , +-28551 , +5601 , +7947 , +-23837 , +-12665 , +13493 , +14989 , +3077 , +-26327 , +-29589 , +-27889 , +13569 , +-14897 , +-17041 , +-213 , +-22093 , +-10839 , +25905 , +-19759 , +16463 , +-12301 , +8799 , +12009 , +977 , +23771 , +-3167 , +-4773 , +9461 , +14549 , +-5943 , +8633 , +10677 , +-26517 , +-24939 , +26181 , +4925 , +-27483 , +31965 , +-21099 , +-19871 , +14285 , +12113 , +20647 , +-7527 , +17113 , +20657 , +-28293 , +-7301 , +17209 , +-16257 , +27177 , +-30553 , +4401 , +-25793 , +119 , +30803 , +20147 , +19757 , +-27145 , +12331 , +-331 , +-18575 , +19609 , +2273 , +-13049 , +-8231 , +-26683 , +-4081 , +7857 , +8979 , +-19977 , +4291 , +-32059 , +24931 , +-4399 , +8809 , +-25667 , +7643 , +16821 , +-27067 , +6475 , +2067 , +-12065 , +23411 , +-9545 , +-6043 , +-4869 , +29011 , +-11847 , +26271 , +17725 , +143 , +-16953 , +-23751 , +-20487 , +12935 , +22521 , +6939 , +24509 , +32589 , +1883 , +-12859 , +-8985 , +-21985 , +-19007 , +7695 , +-25665 , +9309 , +-8919 , +25949 , +-30967 , +3843 , +25995 , +-20129 , +22309 , +-28003 , +27443 , +-23487 , +3491 , +-14907 , +-31335 , +-4255 , +27997 , +-9711 , +-22853 , +24723 , +-14581 , +-14439 , +10997 , +-1587 , +-3491 , +12003 , +12627 , +2917 , +-13419 , +-22175 , +-11149 , +-14139 , +3487 , +16487 , +23505 , +20393 , +-8027 , +17061 , +-595 , +-26159 , +-2775 , +12315 , +18773 , +20799 , +-31839 , +-2923 , +-11771 , +-281 , +2185 , +10401 , +12867 , +-29715 , +5373 , +-28409 , +-87 , +-29347 , +3027 , +-27453 , +-14517 , +21087 , +9007 , +-7813 , +-21881 , +11509 , +-32093 , +-2441 , +-19357 , +-4819 , +-10821 , +-12773 , +32605 , +1755 , +11037 , +24025 , +17355 , +22995 , +30757 , +9397 , +-6481 , +5279 , +-26383 , +-32723 , +8459 , +-22089 , +9473 , +-63 , +22467 , +20283 , +-4015 , +28381 , +15343 , +295 , +-28441 , +-12963 , +-13391 , +32273 , +-16135 , +-4483 , +-13425 , +13913 , +-2695 , +-2475 , +20559 , +-23061 , +305 , +28107 , +29001 , +4203 , +7261 , +9493 , +-17597 , +6137 , +10435 , +-25433 , +31685 , +9827 , +-30137 , +11445 , +31991 , +8407 , +27653 , +-23775 , +18929 , +24109 , +-13843 , +-28681 , +-27747 , +22407 , +5843 , +-1943 , +-12795 , +2975 , +-10479 , +-22463 , +-25039 , +-29583 , +1939 , +-9763 , +12413 , +-20615 , +-22149 , +27811 , +3957 , +22631 , +18993 , +25087 , +-27869 , +22109 , +-8195 , +-10027 , +-32525 , +19363 , +-11487 , +16253 , +-3069 , +-26659 , +-29841 , +-3017 , +9727 , +-17209 , +23137 , +3113 , +12405 , +13677 , +6577 , +30929 , +24243 , +14301 , +22133 , +17409 , +10263 , +22889 , +24749 , +6739 , +27377 , +-29353 , +5993 , +-9179 , +-47 , +30235 , +-13995 , +27923 , +15719 , +-32499 , +467 , +31203 , +-31533 , +-15189 , +-25955 , +27921 , +28291 , +6467 , +-5679 , +18865 , +-20593 , +25651 , +25739 , +-23307 , +20357 , +-29279 , +-29179 , +30245 , +18119 , +6321 , +-29915 , +-2799 , +7531 , +-10695 , +12957 , +16137 , +-23933 , +-22009 , +-3715 , +-1445 , +21507 , +-9593 , +23629 , +-20411 , +-28913 , +-7417 , +-15191 , +5489 , +8413 , +16489 , +-21677 , +-1811 , +20483 , +12387 , +26319 , +4509 , +-2473 , +-9429 , +-10635 , +25149 , +-15553 , +-8261 , +31249 , +27599 , +16017 , +-17793 , +-14853 , +-6503 , +-23577 , +-363 , +2983 , +14749 , +11895 , +-9857 , +-12609 , +26767 , +-4757 , +-9891 , +-8509 , +-20407 , +-18245 , +28073 , +3355 , +-30257 , +24193 , +6763 , +-10325 , +19385 , +-24359 , +-10771 , +-8205 , +8757 , +7211 , +-30469 , +-31069 , +-27267 , +-20973 , +10647 , +-31819 , +22217 , +29867 , +26675 , +-11519 , +-29747 , +-397 , +26469 , +-12969 , +20657 , +-15723 , +30241 , +-14823 , +-22391 , +31181 , +17525 , +1363 , +-27579 , +28603 , +-30021 , +30287 , +-30665 , +25787 , +-25773 , +-7503 , +-2049 , +6205 , +-10529 , +4619 , +12555 , +5023 , +31473 , +-23045 , +15237 , +-12925 , +-15535 , +2749 , +-1577 , +-16985 , +-10839 , +21575 , +16031 , +31035 , +28609 , +24541 , +4383 , +28611 , +-12229 , +4657 , +-10173 , +24669 , +-11835 , +2543 , +-23541 , +8109 , +-20271 , +-24867 , +19851 , +-14809 , +29655 , +-31369 , +-23193 , +-8471 , +28159 , +-4357 , +26815 , +-20707 , +-11167 , +32265 , +13485 , +11715 , +-8771 , +-6211 , +12357 , +-15343 , +25775 , +-26305 , +-23297 , +28237 , +-31637 , +14817 , +15797 , +21785 , +10229 , +25013 , +9249 , +30559 , +983 , +23721 , +-19255 , +31893 , +-3499 , +21017 , +387 , +18335 , +10799 , +-22297 , +-9627 , +25129 , +18385 , +23 , +-27329 , +-10121 , +-24305 , +-27669 , +19349 , +-25147 , +-9383 , +26477 , +-14571 , +4379 , +15479 , +2707 , +-11123 , +-17759 , +-21055 , +21719 , +13675 , +-9855 , +-5679 , +-5051 , +-6231 , +-9671 , +-13113 , +-3809 , +-943 , +19825 , +16113 , +-23059 , +-19349 , +30551 , +-19951 , +27671 , +7293 , +3957 , +-22257 , +-4865 , +-8577 , +18695 , +16943 , +-14441 , +-32173 , +-17443 , +15309 , +-25991 , +-11077 , +17827 , +27539 , +-15743 , +-21289 , +31685 , +8243 , +-23073 , +-14311 , +-14907 , +26013 , +-7237 , +-2885 , +-18417 , +-23625 , +16447 , +17085 , +-14505 , +-28781 , +-23241 , +29527 , +-5015 , +-6353 , +3883 , +24307 , +20615 , +-4191 , +-16657 , +-30295 , +-26045 , +11741 , +-30781 , +-25041 , +-3379 , +20959 , +-28189 , +1881 , +23511 , +-13203 , +27049 , +24587 , +28135 , +1865 , +-19685 , +-3657 , +5931 , +-18449 , +23051 , +-1715 , +29401 , +17605 , +-26967 , +-5445 , +20741 , +-19235 , +-24929 , +27361 , +-30985 , +8737 , +23205 , +14343 , +-24579 , +9751 , +-1889 , +-18215 , +1747 , +14611 , +-19921 , +27101 , +16235 , +31723 , +-24623 , +-7825 , +18765 , +-7111 , +-3983 , +-24013 , +-15759 , +17161 , +23939 , +29707 , +-7539 , +7703 , +13211 , +31645 , +-6405 , +-11383 , +-14455 , +-14281 , +1795 , +29 , +-20505 , +-28581 , +-30533 , +-24595 , +-25795 , +-11097 , +3681 , +-7777 , +6805 , +-24233 , +-19411 , +9249 , +14473 , +-22987 , +5803 , +5853 , +13549 , +23837 , +-9837 , +29813 , +15573 , +30439 , +-14555 , +20475 , +30527 , +-14615 , +8185 , +27811 , +15897 , +25833 , +13149 , +-26617 , +-9241 , +15767 , +-10193 , +32461 , +-23087 , +-13941 , +-8661 , +-3083 , +-13757 , +8881 , +4049 , +8829 , +-21505 , +12365 , +-9041 , +-24153 , +8637 , +8551 , +17475 , +-7259 , +29235 , +-4655 , +6477 , +-2337 , +25797 , +5521 , +13741 , +4509 , +16001 , +22243 , +-18763 , +-8117 , +979 , +-27989 , +-9723 , +3625 , +-10617 , +-26763 , +-27937 , +131 , +-14231 , +2785 , +28677 , +15473 , +-1435 , +10661 , +-5623 , +28419 , +24593 , +-27135 , +-19923 , +-28665 , +-51 , +-4937 , +6583 , +5939 , +1883 , +22659 , +10699 , +-17435 , +-29455 , +-9195 , +-31811 , +-18595 , +21725 , +-30073 , +-24079 , +367 , +29583 , +26197 , +-28371 , +32699 , +9275 , +7893 , +-17801 , +-24725 , +-21525 , +25649 , +-10903 , +20839 , +-24293 , +2523 , +-25851 , +-7925 , +28625 , +-20597 , +20757 , +-25241 , +29233 , +10419 , +-14847 , +-13075 , +30103 , +23155 , +-10975 , +-7251 , +1075 , +-14309 , +2975 , +29711 , +19227 , +-31205 , +-31291 , +-11767 , +-2843 , +-13445 , +-25381 , +-7973 , +-12097 , +-9763 , +32127 , +829 , +-25077 , +29669 , +15991 , +-23005 , +-11151 , +-26051 , +-28653 , +24045 , +-16263 , +-14579 , +-25603 , +3619 , +-13147 , +24555 , +11669 , +5031 , +20231 , +-27049 , +-17725 , +-5767 , +-19623 , +28341 , +25943 , +16353 , +22935 , +9671 , +-29473 , +-463 , +275 , +-21349 , +2299 , +9977 , +6159 , +29453 , +-23497 , +5821 , +-14373 , +14525 , +-4251 , +5427 , +5475 , +7299 , +1395 , +-20233 , +-4533 , +-23957 , +22469 , +-8769 , +31369 , +-6103 , +6921 , +19743 , +-30085 , +-16363 , +27795 , +-1613 , +31107 , +-5467 , +-14285 , +23775 , +23829 , +9817 , +-6515 , +18185 , +-10151 , +20037 , +-25615 , +-11701 , +27713 , +16123 , +-12359 , +26539 , +-25571 , +-17915 , +9233 , +20185 , +-16713 , +-27 , +26213 , +-16283 , +-11289 , +22659 , +24613 , +-3473 , +14001 , +16939 , +8233 , +6123 , +-31785 , +32517 , +21639 , +-13741 , +-29449 , +-18165 , +-13083 , +-10785 , +-20455 , +-2945 , +-17063 , +-8135 , +27603 , +-30491 , +-9795 , +-7741 , +-30759 , +-10109 , +-7801 , +-5829 , +-21991 , +32329 , +-19421 , +8709 , +-20397 , +10837 , +-31291 , +-27431 , +-22999 , +-6937 , +19657 , +-25859 , +-20537 , +-4133 , +-117 , +31743 , +-16153 , +-355 , +-17741 , +11751 , +30845 , +-859 , +26653 , +-20485 , +-1857 , +6767 , +-475 , +-2069 , +5061 , +22765 , +-4219 , +-5749 , +-23389 , +19335 , +-7251 , +20755 , +27899 , +18575 , +20377 , +22479 , +20245 , +-16327 , +1829 , +27479 , +15485 , +-3563 , +24303 , +3919 , +-20201 , +-18175 , +-2393 , +-28267 , +4789 , +-23123 , +-15379 , +6401 , +-13003 , +8069 , +30111 , +1683 , +-31981 , +-15311 , +-14403 , +8505 , +10885 , +-17011 , +-8265 , +-31747 , +28433 , +17951 , +18769 , +-14657 , +12195 , +5135 , +-21527 , +22891 , +28973 , +-7519 , +-12189 , +-30281 , +-25163 , +-11737 , +3955 , +11097 , +26611 , +-10619 , +-16263 , +23223 , +11111 , +-5095 , +-16165 , +21037 , +8435 , +19265 , +-21541 , +-13897 , +16365 , +21071 , +-9489 , +-9931 , +9155 , +24057 , +-14693 , +-10983 , +-12795 , +18525 , +-8247 , +7591 , +-25337 , +-14735 , +31127 , +22695 , +20211 , +23551 , +-9277 , +3487 , +26983 , +7707 , +5489 , +7313 , +-8827 , +-997 , +-22391 , +1831 , +16531 , +-14579 , +-23151 , +-31629 , +28941 , +-20551 , +20485 , +22313 , +67 , +29449 , +-7381 , +-8625 , +14443 , +-4849 , +-28815 , +22651 , +5945 , +19061 , +18493 , +20875 , +5377 , +-28551 , +31307 , +13019 , +4159 , +-19615 , +17029 , +28157 , +13757 , +-3207 , +15705 , +14833 , +15651 , +-18299 , +-31089 , +23261 , +-11755 , +-23619 , +425 , +-5047 , +-32319 , +4161 , +-32079 , +-23091 , +1283 , +-17897 , +-4203 , +-28073 , +16117 , +-15459 , +-3583 , +-20009 , +-14323 , +-11901 , +20919 , +32125 , +23981 , +30023 , +-28827 , +-14739 , +3649 , +-25051 , +-10245 , +-6403 , +31191 , +18585 , +-6009 , +-16793 , +-205 , +9291 , +-1397 , +28421 , +11627 , +26769 , +20697 , +22281 , +20989 , +-28827 , +31969 , +15277 , +31595 , +11991 , +-2923 , +7931 , +-14263 , +-22257 , +4283 , +-18447 , +23263 , +-5443 , +3009 , +1359 , +-14017 , +-4079 , +6431 , +-3399 , +25049 , +18487 , +11557 , +-30593 , +7319 , +20305 , +-29349 , +-25137 , +-28559 , +22249 , +-16043 , +-31379 , +-14965 , +29927 , +-1015 , +-21269 , +15305 , +12567 , +-27221 , +-22941 , +-541 , +-14067 , +-20987 , +-27477 , +6407 , +17073 , +-28855 , +29203 , +20713 , +1321 , +-5771 , +10645 , +26719 , +12369 , +32285 , +-1387 , +-10637 , +27331 , +21707 , +7957 , +16391 , +24119 , +4053 , +11373 , +-29219 , +-25967 , +31161 , +9859 , +-2241 , +5961 , +-7441 , +-17021 , +-9971 , +2925 , +26691 , +-20965 , +-20139 , +21527 , +-18001 , +-17367 , +5999 , +8541 , +31149 , +16387 , +2195 , +8665 , +-13029 , +-16869 , +24823 , +-7027 , +13191 , +-32439 , +-9897 , +-22163 , +16395 , +-20617 , +24865 , +22607 , +19109 , +-12063 , +11521 , +-10657 , +-19947 , +16841 , +20981 , +29215 , +-14807 , +-31059 , +17655 , +-25125 , +-3425 , +-1277 , +5887 , +-20319 , +17017 , +-11665 , +-14933 , +-6727 , +-11309 , +-7041 , +30801 , +21153 , +21569 , +15063 , +407 , +2939 , +7587 , +-9733 , +32137 , +11795 , +2939 , +-17287 , +25657 , +2889 , +-24373 , +30887 , +-5939 , +10001 , +-27035 , +-30507 , +-739 , +18159 , +27083 , +-20977 , +-11831 , +18145 , +1157 , +25935 , +10963 , +-4889 , +5107 , +-6351 , +24755 , +29423 , +10667 , +-21965 , +26097 , +-175 , +15439 , +-8341 , +-22203 , +-15411 , +-24341 , +-7749 , +11293 , +-1291 , +5311 , +3979 , +-23099 , +31799 , +-4185 , +1793 , +2809 , +7747 , +5861 , +-17217 , +20991 , +-24559 , +-14205 , +25869 , +-13509 , +20561 , +-10455 , +-22623 , +-6581 , +11111 , +28273 , +5581 , +-17509 , +-22561 , +-2111 , +23349 , +12931 , +-5781 , +14245 , +8469 , +7127 , +-28073 , +15269 , +7141 , +6411 , +-5251 , +12447 , +15267 , +-22597 , +-25915 , +-18023 , +30335 , +10705 , +-24547 , +-8411 , +9757 , +16919 , +-12059 , +12073 , +28481 , +23883 , +-30217 , +9541 , +-21487 , +-16447 , +-12267 , +29607 , +20683 , +-4237 , +-26911 , +17497 , +17141 , +-11619 , +26203 , +2859 , +6949 , +23249 , +5845 , +-3 , +18727 , +5265 , +-9367 , +-9829 , +-27965 , +29549 , +21239 , +-7913 , +-6931 , +12945 , +-10347 , +-2655 , +-4225 , +-24095 , +-15215 , +-26407 , +-31885 , +14229 , +-5407 , +-25681 , +11161 , +15943 , +-5093 , +-31817 , +-2095 , +-2149 , +-19469 , +16641 , +-3395 , +2885 , +-14291 , +19569 , +14851 , +-25939 , +-22757 , +-14695 , +12539 , +-12027 , +-4979 , +-20723 , +-14865 , +18397 , +30033 , +-13247 , +16845 , +6207 , +14629 , +23515 , +-26013 , +-4027 , +4917 , +9101 , +-16621 , +1327 , +12555 , +-1425 , +-10221 , +14849 , +24591 , +25303 , +-4069 , +21145 , +-3719 , +19627 , +161 , +-29889 , +27853 , +-26557 , +-10093 , +27849 , +-14125 , +29109 , +-10865 , +13611 , +25353 , +7353 , +-6249 , +-21355 , +28067 , +18681 , +-10419 , +-16639 , +3073 , +-30993 , +18089 , +-19879 , +-10847 , +-2765 , +25647 , +20737 , +-2147 , +-16803 , +-14161 , +-7941 , +-21339 , +32603 , +30581 , +16245 , +17263 , +11847 , +30975 , +-1817 , +27573 , +-26177 , +2113 , +-19029 , +427 , +6329 , +-13743 , +-11503 , +4091 , +-32025 , +2213 , +-32515 , +16437 , +2437 , +26055 , +15351 , +29133 , +2223 , +1173 , +-1077 , +-20591 , +26947 , +-26133 , +-4451 , +15267 , +-21709 , +24813 , +6271 , +-5647 , +12377 , +27055 , +-20593 , +-32475 , +-8231 , +14965 , +-29557 , +23083 , +-17935 , +15211 , +-30747 , +-2531 , +29779 , +-6951 , +7011 , +-15681 , +-18691 , +10209 , +8247 , +-14979 , +4501 , +2481 , +397 , +25815 , +16697 , +-5827 , +15277 , +2147 , +-8481 , +26489 , +32655 , +-14527 , +3623 , +27151 , +21235 , +-8941 , +17591 , +12439 , +-31493 , +7541 , +-15855 , +-2991 , +20287 , +7671 , +-12307 , +2651 , +31593 , +20115 , +25355 , +103 , +25931 , +-18269 , +13463 , +-21513 , +12665 , +-25503 , +-5137 , +-23529 , +4189 , +-23339 , +28947 , +7563 , +-6699 , +-5551 , +-159 , +-24173 , +11587 , +31599 , +4359 , +-26851 , +29229 , +-23429 , +-17717 , +5751 , +13649 , +-21125 , +-28571 , +-103 , +-27077 , +18077 , +-22179 , +-13627 , +-26271 , +23345 , +-8607 , +3029 , +25277 , +-31969 , +-10473 , +8165 , +15581 , +-13591 , +123 , +-623 , +-15233 , +2579 , +951 , +-24663 , +4269 , +-32729 , +-10887 , +625 , +12113 , +-4051 , +-2613 , +11085 , +-12727 , +-3431 , +-1941 , +13059 , +26889 , +-18993 , +-4701 , +-13713 , +-11605 , +-6893 , +-15449 , +12733 , +29835 , +-4607 , +14429 , +6683 , +6491 , +23693 , +29643 , +27131 , +-25409 , +-31373 , +-7463 , +23491 , +22371 , +14127 , +27325 , +-4347 , +-24683 , +-22149 , +-29501 , +9279 , +13913 , +25409 , +-27985 , +-1271 , +-1787 , +20249 , +23439 , +-21805 , +-20647 , +-18887 , +-7915 , +3611 , +19987 , +23031 , +3445 , +-18393 , +-31223 , +25523 , +-1617 , +-21189 , +-2109 , +25441 , +11383 , +13647 , +-7277 , +5235 , +-3709 , +-16053 , +-20949 , +8531 , +24933 , +23233 , +4527 , +-25245 , +12769 , +-27107 , +21343 , +28011 , +-6451 , +32611 , +21913 , +22167 , +31583 , +31077 , +-8573 , +-5137 , +7179 , +-30853 , +-5355 , +4683 , +2267 , +-1601 , +26301 , +21201 , +14403 , +-3139 , +8047 , +-19483 , +-11651 , +-14925 , +20033 , +20647 , +7517 , +-28605 , +-29569 , +26349 , +-3919 , +10925 , +-29371 , +5043 , +19215 , +-15475 , +29597 , +30233 , +7987 , +13317 , +7435 , +28891 , +-3629 , +32133 , +14513 , +-15803 , +24573 , +27127 , +-32035 , +-21841 , +9705 , +-14723 , +-729 , +-9867 , +-16809 , +12457 , +31497 , +-10137 , +12895 , +-4559 , +23283 , +-21039 , +12753 , +-14549 , +-15383 , +-4893 , +3077 , +23233 , +16275 , +-4943 , +-24257 , +-6545 , +2269 , +23979 , +-7047 , +-2123 , +-6389 , +-2671 , +1475 , +85 , +-4783 , +27117 , +-8933 , +17665 , +-2327 , +28945 , +-21053 , +7841 , +14257 , +387 , +-9705 , +1535 , +-18113 , +-30721 , +-24595 , +25091 , +7289 , +19435 , +30049 , +-28561 , +30637 , +-17839 , +7735 , +8465 , +-22231 , +-12465 , +4529 , +-17539 , +-2475 , +22045 , +18657 , +-22715 , +20297 , +14203 , +3467 , +28343 , +3813 , +-29011 , +-7823 , +-27639 , +-28821 , +-17173 , +5689 , +-12005 , +27539 , +13159 , +11703 , +-9815 , +-15321 , +11195 , +-25905 , +6153 , +25113 , +1763 , +-1335 , +23643 , +3357 , +-30025 , +24361 , +-2487 , +-4417 , +-18979 , +-16379 , +12605 , +23031 , +25161 , +12005 , +-21743 , +-12465 , +28213 , +-7661 , +32083 , +-27289 , +-23667 , +-20365 , +-20233 , +-16867 , +5625 , +5601 , +-2931 , +-4061 , +12099 , +22531 , +3325 , +-13047 , +8797 , +-7259 , +-1857 , +19435 , +-815 , +31375 , +15759 , +-8073 , +3773 , +18911 , +22695 , +-14709 , +-7865 , +-32547 , +-13957 , +19025 , +29595 , +-32683 , +-20755 , +25811 , +-2467 , +14965 , +28415 , +-31473 , +-16989 , +-9449 , +24859 , +-8805 , +-24205 , +20649 , +-3397 , +3757 , +-31573 , +-12933 , +16043 , +-31549 , +14991 , +-9833 , +-28999 , +25519 , +-32081 , +3359 , +-16393 , +22067 , +21347 , +2847 , +361 , +6689 , +10959 , +-11029 , +-6841 , +8417 , +-25017 , +3567 , +15529 , +7321 , +-8103 , +18445 , +-19001 , +-11841 , +30009 , +-3979 , +-19275 , +1331 , +-12863 , +-2821 , +24207 , +-8493 , +225 , +-17937 , +20283 , +-26475 , +23457 , +30837 , +-3685 , +-11743 , +-111 , +-25249 , +-3509 , +24811 , +18367 , +16515 , +-15151 , +-2881 , +11325 , +19601 , +-19617 , +26857 , +23559 , +28527 , +28929 , +6593 , +17799 , +27413 , +-22951 , +5837 , +-14965 , +-8491 , +28893 , +-30389 , +-19273 , +8519 , +19587 , +10075 , +2951 , +17041 , +24581 , +2949 , +-11075 , +-12469 , +-23665 , +-14113 , +-22945 , +27595 , +-9731 , +5023 , +-9937 , +-8181 , +-11115 , +-10705 , +13983 , +-21519 , +-1739 , +2769 , +21837 , +-17351 , +-31977 , +12713 , +23547 , +22459 , +30211 , +-17571 , +25345 , +-8881 , +-17407 , +16431 , +11341 , +27173 , +26017 , +-9331 , +27097 , +147 , +-31581 , +-31697 , +19099 , +18295 , +-26311 , +-18257 , +-31221 , +31245 , +2489 , +22685 , +-25071 , +-24511 , +-25385 , +541 , +-28805 , +-22641 , +28257 , +-13319 , +-22273 , +29785 , +22129 , +-19399 , +-16211 , +-31817 , +15143 , +-25789 , +32742 , +13789 , +17635 , +9065 , +-557 , +22759 , +27901 , +19721 , +24677 , +3125 , +24311 , +10017 , +-17467 , +-27577 , +9275 , +27747 , +-6069 , +14095 , +-28075 , +25815 , +-30977 , +-18229 , +-3163 , +-7189 , +-4981 , +-28319 , +-7529 , +-17651 , +10927 , +29231 , +-12445 , +30917 , +-4033 , +13419 , +10299 , +-13237 , +30623 , +-14345 , +-25593 , +26017 , +15277 , +15029 , +28579 , +-21981 , +-21687 , +28777 , +23949 , +5551 , +-27839 , +-23797 , +-2015 , +-24531 , +30413 , +17307 , +1619 , +-79 , +-29045 , +21381 , +-11545 , +7947 , +-23053 , +-12695 , +-6619 , +-24345 , +-28853 , +15489 , +8725 , +-14493 , +26153 , +1395 , +-18123 , +-26591 , +22627 , +-25689 , +-2127 , +-27417 , +11657 , +6179 , +22301 , +-8013 , +17631 , +24293 , +-11095 , +10577 , +16849 , +25519 , +477 , +11641 , +7921 , +-22671 , +-14385 , +14177 , +-8341 , +-31215 , +21727 , +25561 , +-26887 , +27851 , +11493 , +3551 , +99 , +-28405 , +-11273 , +14013 , +23157 , +16315 , +2961 , +17053 , +-15499 , +23847 , +6747 , +-7779 , +-13545 , +11597 , +5725 , +32115 , +29437 , +-841 , +-22095 , +885 , +21933 , +-15911 , +18881 , +25409 , +11269 , +20185 , +22783 , +-26167 , +26935 , +11261 , +11035 , +-24335 , +9533 , +-19857 , +25529 , +7077 , +3543 , +32673 , +-22609 , +5747 , +-27141 , +-9951 , +6329 , +-19297 , +7127 , +6387 , +-27731 , +8641 , +15681 , +-17819 , +10559 , +-24619 , +4783 , +8041 , +-14037 , +2521 , +-30539 , +-22925 , +-26635 , +-23831 , +-28681 , +10435 , +-6365 , +-30265 , +23463 , +31055 , +18415 , +-22263 , +26229 , +-1015 , +-20353 , +31643 , +30223 , +-4669 , +11173 , +32233 , +21779 , +29831 , +2827 , +-23699 , +31629 , +4197 , +5111 , +-22329 , +24039 , +-31531 , +-24963 , +-26019 , +-26009 , +-11637 , +7987 , +26471 , +-17111 , +22993 , +4977 , +-9837 , +-11633 , +-17061 , +-14329 , +-14057 , +-32703 , +-25181 , +-3473 , +-6845 , +-9059 , +-15169 , +-27505 , +-5719 , +-17223 , +-9543 , +8933 , +-26715 , +-20273 , +14953 , +25931 , +19581 , +26435 , +-309 , +2599 , +-29705 , +-20979 , +-7979 , +25639 , +22389 , +-13635 , +-555 , +19061 , +-22139 , +24809 , +7747 , +-27789 , +-4609 , +-24789 , +-27361 , +8689 , +-12643 , +-5481 , +20419 , +-793 , +11281 , +-16201 , +11833 , +27053 , +-25703 , +2041 , +15393 , +-32599 , +16677 , +-31051 , +-7687 , +13467 , +24027 , +-18281 , +-22787 , +17473 , +27457 , +-17757 , +-25729 , +3739 , +6859 , +-31327 , +953 , +-15969 , +4595 , +12065 , +23343 , +-9357 , +-17703 , +26861 , +18557 , +30239 , +335 , +-2305 , +-26183 , +21967 , +21629 , +21501 , +-7873 , +12675 , +-15119 , +15405 , +-13549 , +11847 , +-26823 , +22261 , +-15689 , +1265 , +8957 , +-18743 , +381 , +-13737 , +22165 , +26537 , +-25239 , +-11777 , +-18653 , +-15337 , +-20353 , +-23707 , +13605 , +-14193 , +12449 , +31141 , +-21099 , +7553 , +-28699 , +17855 , +28541 , +4037 , +-17041 , +-21691 , +-25073 , +12187 , +-24889 , +-4197 , +-14529 , +-12777 , +-26191 , +21417 , +-31015 , +4385 , +18051 , +-12265 , +-29161 , +-10767 , +-7417 , +-21501 , +-6211 , +6649 , +-25151 , +-6599 , +-12111 , +8811 , +20957 , +-5909 , +-751 , +6699 , +-13455 , +32750 , +-24119 , +24135 , +11365 , +-30363 , +6833 , +12527 , +-30267 , +22793 , +-31457 , +2795 , +22939 , +17879 , +9987 , +17309 , +-14017 , +23117 , +-1413 , +18279 , +-27585 , +-24807 , +13811 , +5305 , +29607 , +-1957 , +10415 , +14197 , +-16929 , +3423 , +17397 , +-1295 , +20233 , +12997 , +-22381 , +2673 , +20941 , +-12467 , +4359 , +14359 , +189 , +13055 , +28679 , +-23965 , +-2013 , +22765 , +7083 , +-4057 , +12385 , +-29851 , +-8969 , +-9473 , +14533 , +25265 , +-17421 , +-16313 , +-13603 , +5697 , +-8113 , +28825 , +20059 , +-26511 , +24175 , +-2625 , +25953 , +29883 , +18699 , +-30927 , +6491 , +-6031 , +-8385 , +25861 , +-16289 , +11757 , +12073 , +-11919 , +13053 , +29273 , +1285 , +-8011 , +27291 , +28117 , +32437 , +22437 , +8263 , +5691 , +7151 , +20627 , +-31721 , +25685 , +-23873 , +-8503 , +-23297 , +-23663 , +-20303 , +26759 , +-24283 , +17471 , +20575 , +-4231 , +14013 , +-22465 , +27529 , +-87 , +-12965 , +-7611 , +29109 , +31999 , +-28713 , +-8309 , +2875 , +1845 , +-20839 , +-3065 , +12523 , +11339 , +25203 , +16681 , +-32748 , +8587 , +-14333 , +-4341 , +9009 , +15093 , +11131 , +-20431 , +9963 , +-9927 , +-8951 , +-30787 , +-27711 , +1593 , +9633 , +18983 , +9239 , +30707 , +29795 , +-12171 , +-4391 , +12803 , +23649 , +22003 , +-8573 , +32149 , +31501 , +-1937 , +19653 , +28641 , +-8451 , +-11543 , +-25961 , +-18655 , +1873 , +-21807 , +7379 , +-6645 , +4991 , +-22593 , +13643 , +-2619 , +15291 , +3497 , +-4001 , +13921 , +10683 , +29083 , +-231 , +26067 , +18979 , +24813 , +26055 , +9579 , +-20917 , +-3325 , +-18679 , +-31289 , +-26969 , +15739 , +13171 , +-7849 , +15763 , +8939 , +-23131 , +-17083 , +-1361 , +29719 , +21207 , +-5891 , +22203 , +-9301 , +-10237 , +-27621 , +10219 , +-29583 , +19307 , +-27935 , +20153 , +10761 , +31423 , +-30407 , +11085 , +-7137 , +-25171 , +13349 , +25415 , +15401 , +21757 , +-30277 , +4121 , +28059 , +20007 , +-6245 , +-4635 , +-3937 , +25453 , +2023 , +-23855 , +3919 , +-28563 , +-2883 , +-18719 , +1383 , +-27839 , +-19927 , +21575 , +-23929 , +-28141 , +-10585 , +26699 , +-6431 , +-25291 , +-13805 , +15507 , +-28041 , +26045 , +-7389 , +8449 , +7893 , +145 , +7009 , +15887 , +6977 , +3601 , +-28255 , +10147 , +25463 , +7711 , +-27913 , +18533 , +10471 , +-22333 , +25143 , +-16995 , +18017 , +29495 , +30177 , +-17533 , +-10663 , +-18039 , +25765 , +4641 , +-31853 , +-2895 , +14419 , +-5471 , +-29589 , +-27355 , +24405 , +21803 , +-3975 , +-30219 , +-2903 , +-16579 , +-16165 , +-5025 , +-27051 , +-5507 , +2787 , +-22545 , +-32155 , +31771 , +21839 , +30473 , +12893 , +-17247 , +10249 , +3091 , +11571 , +-24499 , +-27049 , +-16645 , +18379 , +-20501 , +17297 , +-26785 , +3049 , +-5589 , +-9627 , +2839 , +32171 , +13685 , +28291 , +18775 , +-2175 , +31311 , +-16167 , +27203 , +21673 , +-477 , +-8625 , +23305 , +8735 , +5795 , +4345 , +-8589 , +3613 , +-12897 , +-25647 , +31239 , +19983 , +-29353 , +14577 , +-22629 , +13065 , +27993 , +-11703 , +9071 , +-23355 , +14301 , +27865 , +-20799 , +-17645 , +-16495 , +-16797 , +7913 , +11739 , +-25095 , +26029 , +4331 , +-11381 , +-3515 , +15663 , +6557 , +-6633 , +14509 , +-16301 , +-13781 , +18027 , +-11709 , +-1241 , +24897 , +30309 , +21837 , +-871 , +-32615 , +-32433 , +15901 , +17197 , +-16619 , +-29995 , +6251 , +7221 , +28501 , +15489 , +-18133 , +28043 , +29401 , +-13913 , +-24345 , +-7739 , +29065 , +-15889 , +7829 , +-4367 , +19933 , +27197 , +19179 , +-20531 , +11623 , +-11213 , +29761 , +1915 , +-4621 , +27683 , +4833 , +1981 , +24355 , +13707 , +-8733 , +4523 , +6267 , +28173 , +6275 , +-22295 , +17411 , +-12575 , +-20489 , +29033 , +13657 , +9429 , +16845 , +20369 , +9549 , +30401 , +-23873 , +8967 , +-5641 , +29313 , +-503 , +5081 , +849 , +22631 , +9541 , +-5569 , +-11187 , +7483 , +10435 , +26831 , +24683 , +-1361 , +-12195 , +8499 , +26071 , +9817 , +3283 , +-17561 , +11257 , +-6363 , +-1631 , +10093 , +-8553 , +-16043 , +-30887 , +-20093 , +-12955 , +-3851 , +26229 , +28893 , +26653 , +-5421 , +19129 , +2277 , +20255 , +7159 , +7939 , +13537 , +20605 , +-24675 , +16803 , +5691 , +-22113 , +9133 , +24893 , +-17099 , +25939 , +-19541 , +4623 , +-7139 , +11881 , +-24003 , +-19491 , +21767 , +28357 , +18709 , +-16325 , +-3577 , +4865 , +-10377 , +6505 , +-10263 , +-13697 , +-6367 , +29101 , +-27807 , +7165 , +4051 , +25383 , +-7983 , +9909 , +12601 , +20531 , +-4491 , +26609 , +-21649 , +-23505 , +-26333 , +23845 , +15859 , +-29467 , +-25731 , +23169 , +-15081 , +-15271 , +10153 , +28179 , +-29177 , +-31965 , +-7277 , +-22699 , +31031 , +13127 , +-16491 , +-25781 , +-23715 , +-1135 , +-24643 , +32027 , +-13079 , +-17563 , +20351 , +-23773 , +14335 , +-28897 , +-18451 , +-12143 , +13547 , +29927 , +-12181 , +7033 , +5407 , +10757 , +16883 , +-14477 , +-17241 , +-10043 , +13505 , +-4945 , +-30181 , +-20799 , +16529 , +17291 , +-13015 , +-3133 , +-2219 , +-4941 , +-31881 , +-18153 , +619 , +-29267 , +-27605 , +-18069 , +19037 , +-26119 , +16861 , +-32485 , +8463 , +8365 , +2831 , +30481 , +-6529 , +-2433 , +-20189 , +-8673 , +8179 , +-27539 , +-25127 , +26321 , +31169 , +-32055 , +24385 , +27077 , +-21643 , +-22311 , +29241 , +25225 , +-18793 , +22757 , +4959 , +-15631 , +30681 , +28893 , +20107 , +-18711 , +729 , +26471 , +1223 , +-3885 , +-16305 , +-25227 , +8393 , +5729 , +-14645 , +-13207 , +-19989 , +-6685 , +26093 , +-5983 , +9631 , +-21461 , +23575 , +20629 , +22377 , +8927 , +-20819 , +-24469 , +-20645 , +20301 , +-25397 , +531 , +1797 , +31181 , +-23431 , +20959 , +-29451 , +-10865 , +4709 , +-4197 , +24233 , +-3845 , +5149 , +-27621 , +4363 , +-31099 , +-15165 , +871 , +-8343 , +-14847 , +11341 , +-3265 , +-18199 , +-20857 , +-22221 , +-451 , +-7037 , +-28481 , +-17237 , +-1167 , +29563 , +20925 , +-20125 , +-28053 , +14935 , +-31143 , +5305 , +25571 , +-30631 , +-243 , +31341 , +-24891 , +21877 , +-9151 , +-32027 , +22991 , +7877 , +-15573 , +-25641 , +-30297 , +10637 , +19243 , +29575 , +-5259 , +25765 , +15251 , +-27003 , +-17417 , +-24451 , +-19947 , +12251 , +-27875 , +21899 , +-13943 , +25549 , +15391 , +-20153 , +-9911 , +15625 , +-7655 , +8619 , +-6893 , +-23451 , +26903 , +5913 , +21845 , +23323 , +19391 , +13543 , +-28665 , +28531 , +-10917 , +-22457 , +-30195 , +9225 , +4213 , +-8761 , +-5887 , +-16001 , +16879 , +19785 , +-12909 , +19121 , +18589 , +-27527 , +-8609 , +-29831 , +-18081 , +-26681 , +-21685 , +31193 , +4015 , +-7721 , +337 , +25021 , +-13631 , +-1655 , +18149 , +-11475 , +-12515 , +-6559 , +30919 , +-13557 , +-6991 , +-25723 , +-8359 , +3653 , +-22163 , +-32453 , +5245 , +12175 , +-12203 , +-11049 , +29157 , +14237 , +1317 , +5945 , +32756 , +26585 , +19545 , +16835 , +32015 , +3995 , +14293 , +-1585 , +-27273 , +-5149 , +-14351 , +31409 , +-7259 , +2445 , +20761 , +28193 , +-12005 , +-24051 , +15835 , +27451 , +-4159 , +-5463 , +1421 , +21491 , +-7239 , +20005 , +12123 , +18711 , +30141 , +2315 , +-17953 , +27831 , +26099 , +-24485 , +-16577 , +11051 , +5957 , +10941 , +-21059 , +17029 , +-21705 , +-7097 , +-4903 , +16517 , +-22973 , +1193 , +18143 , +-20711 , +-19277 , +20459 , +-4343 , +-22699 , +-22543 , +22949 , +31753 , +735 , +17509 , +-3405 , +-20687 , +-7177 , +-2099 , +-18065 , +24575 , +-13339 , +4111 , +17519 , +25663 , +-2061 , +-30051 , +-8273 , +-13161 , +15587 , +5181 , +21593 , +19879 , +6385 , +20847 , +-19727 , +11685 , +13369 , +1855 , +-26605 , +-29079 , +1989 , +15517 , +-7255 , +27661 , +-7441 , +-5069 , +23207 , +10245 , +1899 , +24257 , +11065 , +-1867 , +5043 , +-14857 , +-13435 , +5515 , +29703 , +12231 , +10979 , +-2159 , +4575 , +27195 , +-21111 , +-31091 , +-1563 , +-4135 , +-5419 , +-30057 , +12401 , +29807 , +-23051 , +14891 , +27769 , +10865 , +-1753 , +15561 , +-3823 , +22735 , +11121 , +-1527 , +15711 , +22861 , +10453 , +-29391 , +-13551 , +-26787 , +5391 , +13649 , +-27815 , +-22669 , +-3897 , +-26147 , +-28059 , +3811 , +-14007 , +-17477 , +341 , +-11215 , +27335 , +-5401 , +32433 , +28661 , +3331 , +-26495 , +-8859 , +13857 , +-3443 , +23919 , +-11719 , +-12309 , +29315 , +3435 , +14277 , +-8673 , +25783 , +11935 , +8431 , +23533 , +26747 , +-21053 , +29145 , +-9647 , +-565 , +9897 , +14185 , +11233 , +-5879 , +-26273 , +29997 , +-26327 , +-9931 , +-7229 , +-24089 , +13693 , +-14167 , +-10341 , +-30091 , +27739 , +4173 , +17711 , +-11437 , +24377 , +-23223 , +-11683 , +-12147 , +11237 , +31055 , +-2507 , +-5061 , +-19623 , +30011 , +-3825 , +21367 , +-1775 , +1633 , +6439 , +8663 , +-19735 , +-18891 , +21419 , +-15519 , +8557 , +-15215 , +4701 , +-15097 , +-14151 , +15453 , +-21081 , +-13411 , +8653 , +31443 , +29495 , +-5807 , +-9113 , +-24263 , +16653 , +2471 , +-13997 , +-5879 , +1311 , +-21529 , +1363 , +21181 , +-1687 , +-23517 , +31845 , +-22795 , +-2939 , +6817 , +23975 , +16961 , +-22835 , +-32291 , +-26705 , +-23737 , +7139 , +-17667 , +-2725 , +13193 , +22743 , +8393 , +-3285 , +17043 , +28345 , +-20189 , +-6877 , +-21571 , +-9811 , +3329 , +-31465 , +7769 , +-31601 , +-31005 , +-32377 , +-32655 , +18683 , +-2101 , +9465 , +25597 , +17397 , +-27979 , +-21041 , +1691 , +-10507 , +28307 , +28321 , +-11317 , +-21113 , +-325 , +20239 , +-7775 , +-24741 , +12777 , +-15069 , +24573 , +-14621 , +28599 , +-8415 , +29257 , +-23443 , +11405 , +30177 , +27565 , +-23117 , +19487 , +8105 , +-6713 , +-5639 , +2657 , +-1153 , +-22045 , +-25945 , +-23801 , +-4849 , +-6987 , +-20393 , +28529 , +24815 , +-25459 , +31863 , +-19665 , +12681 , +-7661 , +-12449 , +-12559 , +-15259 , +-19587 , +4839 , +4609 , +-2033 , +2635 , +12667 , +-7621 , +-1439 , +2935 , +-24133 , +29323 , +-24731 , +-11727 , +28307 , +-16427 , +20649 , +-13029 , +-27703 , +3203 , +11543 , +9725 , +-30945 , +-28053 , +29005 , +11257 , +17893 , +-23731 , +-16267 , +14415 , +-16615 , +-4147 , +26017 , +1415 , +-3597 , +11501 , +9629 , +-3787 , +-26361 , +-12293 , +-18105 , +8227 , +-17957 , +6421 , +-30609 , +-739 , +-3849 , +9239 , +-17115 , +2579 , +-11635 , +14363 , +18327 , +31715 , +14205 , +3437 , +-5529 , +-26493 , +-12543 , +16897 , +-6265 , +20423 , +-13131 , +-19343 , +25991 , +1675 , +2873 , +-659 , +9595 , +3187 , +31557 , +-16451 , +-24253 , +-19417 , +14143 , +1711 , +10867 , +-31237 , +4951 , +27415 , +8609 , +-31427 , +545 , +14015 , +-8641 , +-41 , +9635 , +15977 , +24305 , +-8037 , +-6919 , +-21955 , +23147 , +-1047 , +-8603 , +25801 , +-14137 , +20213 , +3561 , +26737 , +32089 , +-22149 , +95 , +-23695 , +-5883 , +-17939 , +27415 , +-21943 , +-25307 , +-3011 , +-29 , +-3901 , +-22831 , +19205 , +-10825 , +-16033 , +23231 , +13131 , +15809 , +-21681 , +-22119 , +-5459 , +23807 , +-24847 , +-27435 , +30757 , +25175 , +28871 , +-9197 , +24377 , +-20175 , +-1303 , +31463 , +32183 , +-10101 , +-27387 , +3903 , +3049 , +-20843 , +6867 , +-16333 , +14161 , +26825 , +14607 , +-17053 , +20447 , +2173 , +14571 , +-4409 , +-83 , +-3067 , +527 , +-4851 , +-31443 , +5185 , +-29939 , +-9613 , +26605 , +20157 , +28761 , +13335 , +-24633 , +-19391 , +-5693 , +13269 , +-22885 , +15349 , +-10645 , +-9571 , +27785 , +25321 , +5949 , +15181 , +-22873 , +-30663 , +-4121 , +7685 , +28731 , +23973 , +-22959 , +-27641 , +-18835 , +17567 , +6295 , +-27647 , +26249 , +-4111 , +-32383 , +14069 , +-10577 , +8645 , +9075 , +-21115 , +24843 , +-8627 , +4593 , +-31277 , +-22123 , +-5427 , +-11885 , +22993 , +-31171 , +-3775 , +1653 , +32291 , +433 , +8293 , +-5827 , +-13973 , +28805 , +-24483 , +-17789 , +3119 , +4349 , +-19517 , +-4901 , +20771 , +11571 , +-8899 , +15675 , +32267 , +14299 , +-7775 , +29185 , +27919 , +-9351 , +-385 , +-1947 , +5777 , +29717 , +11589 , +6253 , +-7283 , +-5257 , +-13619 , +-2193 , +-16283 , +28637 , +31613 , +8447 , +2115 , +-719 , +-23593 , +-12687 , +-7953 , +12491 , +19867 , +-23353 , +7971 , +24473 , +-11945 , +8493 , +19301 , +26339 , +7295 , +27637 , +-8351 , +12159 , +-5107 , +-13813 , +21439 , +23437 , +-11379 , +25831 , +5757 , +5797 , +26817 , +-24297 , +451 , +-32613 , +27567 , +-17631 , +27453 , +-21841 , +17219 , +-7413 , +25593 , +-24761 , +-22947 , +-29107 , +16561 , +27691 , +-13969 , +14407 , +691 , +-22733 , +-5999 , +18751 , +-18129 , +25999 , +-31197 , +23507 , +29455 , +7531 , +13779 , +-26379 , +-9899 , +27191 , +19527 , +25183 , +2541 , +11099 , +19245 , +911 , +-13559 , +-2709 , +25039 , +-24255 , +-20743 , +19939 , +-9675 , +8029 , +16509 , +-22183 , +-13645 , +13689 , +-12379 , +-23487 , +-7161 , +27087 , +-2267 , +28181 , +-19471 , +10929 , +29229 , +-8417 , +13385 , +-16765 , +23233 , +12447 , +-363 , +16951 , +26771 , +-12401 , +-987 , +28219 , +18519 , +16857 , +-5459 , +23041 , +-23647 , +-27123 , +-29357 , +-2587 , +-3785 , +21909 , +-7597 , +29619 , +-23061 , +29047 , +13583 , +21909 , +-8713 , +8581 , +25769 , +23441 , +5837 , +11801 , +14109 , +1923 , +4469 , +-25525 , +4311 , +-4211 , +30053 , +13477 , +-5943 , +-26859 , +19417 , +-9111 , +-12021 , +1599 , +-5213 , +14645 , +-5143 , +-10279 , +28047 , +-26803 , +9601 , +-2589 , +16695 , +-30135 , +-30245 , +-17281 , +-1453 , +16463 , +-28805 , +-17563 , +-4453 , +-53 , +11905 , +-12827 , +-17377 , +-14421 , +7229 , +-16045 , +20501 , +-30193 , +841 , +16909 , +-31173 , +-1657 , +4123 , +18151 , +-1877 , +24781 , +-21977 , +-19675 , +6199 , +31985 , +-20115 , +26365 , +9525 , +-11739 , +6297 , +30335 , +8423 , +29409 , +13205 , +-16611 , +20299 , +-20059 , +-27997 , +-27751 , +24941 , +-19151 , +-15879 , +-18821 , +-8113 , +26427 , +-14893 , +23315 , +-4049 , +-19033 , +-21747 , +25833 , +1133 , +-25023 , +1083 , +-25157 , +-25637 , +-781 , +-21689 , +6637 , +-25193 , +-27523 , +-24709 , +-31867 , +28263 , +18859 , +22567 , +-31831 , +22153 , +2323 , +25525 , +653 , +20499 , +20297 , +-21701 , +30193 , +-10811 , +-13415 , +12951 , +-2539 , +-13721 , +5431 , +-21233 , +20793 , +4247 , +-5369 , +-16809 , +-10869 , +-5331 , +-2623 , +16443 , +2469 , +-16881 , +-31555 , +25775 , +2945 , +18305 , +15645 , +3173 , +-12807 , +-5623 , +13193 , +10727 , +-4941 , +7871 , +26729 , +-30415 , +20133 , +-22487 , +7833 , +-11319 , +20231 , +-25201 , +1193 , +10577 , +-23355 , +-6439 , +-22391 , +9385 , +-16251 , +16607 , +11725 , +-23169 , +-9965 , +25161 , +-16807 , +13927 , +24163 , +22757 , +-21079 , +26491 , +2811 , +-18567 , +-14731 , +-2713 , +19451 , +-21471 , +-17669 , +5389 , +14219 , +-26841 , +12205 , +-17517 , +-13867 , +14939 , +22635 , +15109 , +-24453 , +6369 , +-24517 , +2915 , +-4969 , +8093 , +21379 , +6207 , +-11477 , +11769 , +-15167 , +27347 , +-3047 , +-26813 , +-7235 , +-30567 , +20385 , +13449 , +-16567 , +24165 , +16981 , +7913 , +-5773 , +4093 , +-12399 , +-21901 , +13891 , +-31701 , +-3473 , +-18057 , +-13075 , +1371 , +11597 , +99 , +907 , +-12619 , +4021 , +21019 , +-681 , +-8789 , +-5415 , +-29491 , +-31903 , +-8159 , +27797 , +16203 , +4041 , +-26895 , +22747 , +-24855 , +-31887 , +-31467 , +6577 , +-6713 , +32319 , +17203 , +23973 , +-20037 , +-11829 , +20411 , +31945 , +31639 , +1695 , +-19583 , +-9173 , +-16627 , +27625 , +21197 , +1995 , +-5369 , +-22089 , +17143 , +-17649 , +-19853 , +19885 , +-895 , +-28729 , +-10835 , +19007 , +-15951 , +-29799 , +-951 , +-8095 , +4513 , +17405 , +-18579 , +-5167 , +32733 , +-12103 , +17583 , +2487 , +-14215 , +17617 , +10599 , +-28173 , +30889 , +-6651 , +16015 , +-9529 , +987 , +-9525 , +17679 , +-16619 , +-25267 , +-31043 , +-25953 , +-8427 , +-20953 , +19871 , +10011 , +-27763 , +16397 , +-2869 , +6745 , +2953 , +13375 , +23341 , +-28025 , +-29547 , +-24787 , +-16451 , +-15619 , +19829 , +8337 , +20085 , +-19557 , +-7337 , +-28671 , +11209 , +12441 , +-18029 , +-10735 , +-18781 , +743 , +-29729 , +18915 , +14547 , +2303 , +23301 , +27453 , +-16883 , +18497 , +-11229 , +20783 , +18783 , +-28983 , +-23979 , +-23269 , +8493 , +-16953 , +-23809 , +-32173 , +27039 , +21593 , +29813 , +4659 , +-14937 , +21217 , +22333 , +15547 , +13931 , +3803 , +-9793 , +17823 , +-3769 , +3901 , +18053 , +-21021 , +25665 , +-30397 , +19697 , +12793 , +8449 , +-27183 , +-9103 , +15435 , +-6583 , +-18615 , +-21957 , +-23451 , +32752 , +-14371 , +22911 , +4733 , +-19117 , +-6031 , +-16855 , +-8303 , +-425 , +-30743 , +12817 , +-13817 , +14039 , +6919 , +29879 , +22195 , +2211 , +-25407 , +3449 , +13955 , +17397 , +28443 , +-22455 , +-30585 , +-8599 , +-19331 , +25833 , +20625 , +-12171 , +-18039 , +-28507 , +-1457 , +-30365 , +-30853 , +-15743 , +16603 , +12741 , +14069 , +-11777 , +21211 , +29813 , +7011 , +-24505 , +-29933 , +1535 , +24265 , +11247 , +-27265 , +-23895 , +9763 , +-6359 , +22767 , +-17695 , +-10697 , +-14215 , +32023 , +-31177 , +-28431 , +3577 , +-6865 , +-19243 , +-31941 , +11013 , +-2295 , +30583 , +6989 , +-10119 , +1697 , +5607 , +-16491 , +-16537 , +-16833 , +-13329 , +7679 , +-18865 , +-9457 , +9427 , +-21549 , +2263 , +5681 , +-29367 , +28179 , +-15867 , +-28073 , +21493 , +-23993 , +28917 , +-23077 , +-12197 , +24545 , +24595 , +22871 , +-6055 , +-13813 , +-18739 , +29377 , +-21473 , +-5625 , +32215 , +25849 , +16553 , +-13823 , +-557 , +-1041 , +-12103 , +-6035 , +28821 , +7471 , +-17341 , +-25641 , +31963 , +29947 , +-16781 , +32577 , +29821 , +26605 , +16929 , +32507 , +-13013 , +8451 , +-25403 , +-25095 , +-13403 , +5177 , +26607 , +2987 , +-9875 , +-12887 , +-20153 , +-23977 , +32007 , +25881 , +14587 , +26089 , +27823 , +28185 , +30399 , +7005 , +-19571 , +-17251 , +-25283 , +-28543 , +24943 , +-10739 , +21527 , +-21411 , +-17149 , +26337 , +24661 , +-8189 , +28813 , +-27459 , +-3229 , +4077 , +-22241 , +-31485 , +-10103 , +-29235 , +-24495 , +-4113 , +14561 , +15083 , +-30595 , +6189 , +11725 , +27391 , +21361 , +-273 , +-9741 , +-24705 , +19365 , +11407 , +16563 , +-19579 , +-2047 , +-6763 , +-27613 , +-28649 , +16901 , +9313 , +12671 , +273 , +22153 , +12089 , +1065 , +-15765 , +14577 , +8933 , +-30951 , +24093 , +-32531 , +18885 , +7389 , +-3465 , +15015 , +-26779 , +-2547 , +30959 , +24963 , +8353 , +15939 , +-23165 , +-4785 , +-6097 , +-14443 , +-2417 , +-5629 , +-10301 , +-4981 , +3359 , +-28173 , +15775 , +-8045 , +-6703 , +-7537 , +-22869 , +9987 , +2593 , +-23667 , +27923 , +26763 , +21071 , +22703 , +-11431 , +24361 , +20393 , +5623 , +1011 , +4269 , +-2197 , +-20903 , +-12963 , +4003 , +-23013 , +13561 , +29363 , +-1325 , +4947 , +18659 , +26827 , +-3269 , +20007 , +9023 , +22473 , +16509 , +23029 , +-8177 , +14655 , +-9245 , +-31805 , +-1695 , +-5449 , +6607 , +2065 , +27913 , +3293 , +10681 , +8497 , +-31525 , +-30969 , +-23395 , +5669 , +-18079 , +-30891 , +-7681 , +25075 , +-22765 , +22343 , +19293 , +-29827 , +-29167 , +-9001 , +26147 , +-14885 , +21591 , +8209 , +-13265 , +-3793 , +-32133 , +-21211 , +-13639 , +5119 , +13021 , +11015 , +-8231 , +-6895 , +27497 , +-383 , +-12679 , +32191 , +-9789 , +20943 , +-32563 , +-13111 , +27147 , +22711 , +29003 , +-7745 , +-20465 , +10523 , +-11741 , +-22335 , +-25859 , +29 , +11063 , +12015 , +27565 , +19365 , +-22889 , +1835 , +25921 , +20623 , +-15501 , +-6267 , +12403 , +-15059 , +-22635 , +5891 , +26943 , +14451 , +-14501 , +-15359 , +20257 , +-25219 , +7213 , +-9461 , +4041 , +-11341 , +-24205 , +30251 , +-23463 , +-31901 , +20499 , +31949 , +-18151 , +9929 , +20581 , +-29681 , +-26707 , +-26697 , +-25943 , +-16483 , +-29743 , +-1621 , +-16891 , +29445 , +-17775 , +22623 , +1527 , +-27755 , +-7173 , +-11549 , +-18865 , +-25939 , +1889 , +-21697 , +-27221 , +-14185 , +25097 , +4733 , +32361 , +-18453 , +-16281 , +2377 , +11807 , +-7855 , +-26157 , +11531 , +2971 , +10223 , +-4405 , +-13961 , +6993 , +1587 , +24989 , +1707 , +-9637 , +29487 , +-32345 , +-29751 , +14315 , +6263 , +-16113 , +28165 , +25925 , +-3987 , +3321 , +-15289 , +-19399 , +-6879 , +-32709 , +-18623 , +15387 , +-30805 , +10403 , +26113 , +32055 , +30717 , +22173 , +30485 , +-17717 , +-27333 , +28533 , +-20973 , +17281 , +-29029 , +-17901 , +23999 , +24679 , +-4941 , +7719 , +3739 , +8803 , +11097 , +19945 , +12803 , +-14805 , +-1037 , +21075 , +14787 , +-6457 , +18519 , +-3631 , +-5073 , +13949 , +3615 , +-5759 , +19643 , +-2485 , +-21887 , +28901 , +-3817 , +-7195 , +-20825 , +29 , +6845 , +-10711 , +-11127 , +-12125 , +27925 , +-16359 , +11331 , +4223 , +-26617 , +21069 , +6635 , +16379 , +-12525 , +-3339 , +15343 , +-19997 , +25829 , +17477 , +-11799 , +-22983 , +25465 , +-3717 , +-17419 , +-2193 , +30887 , +-1463 , +-21875 , +-11749 , +3903 , +13529 , +-26911 , +28465 , +-4957 , +15929 , +7083 , +18623 , +10975 , +-28319 , +-14709 , +-16097 , +-6339 , +-867 , +-1571 , +-19279 , +32097 , +11663 , +30481 , +-4585 , +-22819 , +-29789 , +10631 , +-2845 , +22351 , +6407 , +18907 , +11997 , +-21261 , +-28123 , +29137 , +-13393 , +-12867 , +-31851 , +-18279 , +29473 , +2295 , +-29023 , +28593 , +11733 , +5451 , +-27603 , +-26563 , +-32647 , +-15509 , +-449 , +-22305 , +12671 , +-739 , +-8213 , +-17397 , +-20129 , +26841 , +9167 , +-16671 , +-25279 , +-30241 , +-32495 , +-18299 , +21565 , +-19249 , +28363 , +-15875 , +5907 , +-20283 , +-12787 , +-14721 , +-21921 , +23783 , +-32177 , +-23477 , +-3243 , +12939 , +-20367 , +-14837 , +-30983 , +-1085 , +-9179 , +-13151 , +-23595 , +-27015 , +-25607 , +24969 , +-29139 , +7177 , +7101 , +-13913 , +-14655 , +17753 , +9609 , +20641 , +5117 , +25453 , +-5843 , +9411 , +-10827 , +-15231 , +14893 , +-17597 , +-25767 , +-8795 , +31797 , +21801 , +29873 , +4303 , +-2535 , +-17247 , +-2795 , +26483 , +-15553 , +-11563 , +24863 , +6565 , +7079 , +1599 , +-273 , +14753 , +10841 , +18825 , +211 , +23537 , +10845 , +-23841 , +653 , +-27651 , +571 , +-5169 , +-28411 , +-25305 , +5607 , +-9835 , +-19329 , +-30623 , +-30909 , +-6661 , +-2729 , +-14779 , +-25321 , +12467 , +-11465 , +-6739 , +-30595 , +-3801 , +9937 , +-8497 , +16617 , +-28455 , +26133 , +17099 , +-20843 , +1591 , +17129 , +10193 , +-9343 , +-30737 , +-25505 , +10669 , +25315 , +12499 , +14965 , +22243 , +-10453 , +-21467 , +19521 , +25161 , +22121 , +-32143 , +8375 , +-3811 , +1369 , +7917 , +4563 , +23969 , +-22323 , +9545 , +6747 , +-14807 , +5547 , +12299 , +3601 , +-16195 , +-20639 , +-28831 , +-5009 , +-29905 , +-21279 , +8321 , +17889 , +4015 , +23577 , +-10879 , +11121 , +-27163 , +7143 , +1443 , +-24303 , +30861 , +17559 , +7739 , +2625 , +-18551 , +-18733 , +-13309 , +-30377 , +-16771 , +18723 , +13549 , +-14039 , +14305 , +-13345 , +23169 , +10577 , +17571 , +-9301 , +15543 , +-15141 , +-4041 , +14959 , +-10937 , +19331 , +14641 , +-6455 , +-31867 , +9583 , +-31137 , +-22001 , +191 , +-9891 , +-8095 , +21691 , +29963 , +11623 , +-14407 , +24945 , +-15197 , +-1485 , +-143 , +13931 , +-21057 , +10415 , +9257 , +-17035 , +-12561 , +-11707 , +26541 , +-30105 , +11753 , +-1129 , +18713 , +18459 , +22253 , +-7753 , +-24219 , +-23579 , +-21357 , +20953 , +-9087 , +28559 , +41 , +917 , +-18705 , +12745 , +2701 , +28055 , +22491 , +-8921 , +-8837 , +3289 , +8111 , +-6761 , +-6797 , +-27045 , +815 , +27739 , +-27645 , +2911 , +-13555 , +-17791 , +19113 , +10263 , +4103 , +-15917 , +-25051 , +9451 , +19321 , +-9123 , +-30121 , +16931 , +-11143 , +-32167 , +-20845 , +5675 , +8557 , +11949 , +10867 , +5699 , +9761 , +10721 , +13119 , +20919 , +9831 , +29591 , +-1609 , +-10337 , +-10971 , +-32123 , +-1939 , +-16629 , +6131 , +4843 , +17059 , +18889 , +18225 , +-17525 , +-5215 , +6543 , +17055 , +-32479 , +7813 , +-4165 , +12921 , +8285 , +-343 , +-4211 , +19719 , +18009 , +-6033 , +-9511 , +30907 , +28559 , +10909 , +16703 , +8903 , +-23207 , +-12231 , +6633 , +8763 , +-11809 , +-27939 , +-16449 , +-115 , +-7531 , +-29301 , +-14307 , +30917 , +28975 , +-14323 , +-21485 , +-26105 , +11039 , +13003 , +-17389 , +17071 , +-20597 , +11037 , +22061 , +28397 , +7099 , +8237 , +-10551 , +7639 , +-475 , +28741 , +15325 , +11265 , +-6191 , +5805 , +-3415 , +-1377 , +21595 , +16899 , +-14363 , +15117 , +8301 , +27405 , +29317 , +-18699 , +18097 , +1053 , +-20247 , +27871 , +6987 , +22745 , +28825 , +-9907 , +-16943 , +-18783 , +-1929 , +-15279 , +-1593 , +30049 , +-29309 , +27557 , +19855 , +-1817 , +-30203 , +24901 , +20459 , +17089 , +24399 , +-2431 , +11241 , +11407 , +31217 , +-29791 , +27495 , +-7459 , +-32657 , +-25617 , +-14335 , +-18307 , +-7041 , +-8615 , +14993 , +-5537 , +16061 , +21121 , +289 , +27617 , +27871 , +-28061 , +-11415 , +21431 , +-5511 , +16471 , +-575 , +307 , +23589 , +-5695 , +-25959 , +-28123 , +-15027 , +13845 , +-23943 , +-16079 , +24657 , +-17797 , +2671 , +-15191 , +-28339 , +18917 , +-22259 , +17889 , +-5305 , +6563 , +6627 , +2315 , +-16401 , +-28035 , +22379 , +23953 , +12755 , +9809 , +17299 , +-4381 , +16665 , +541 , +-10585 , +3545 , +-13649 , +-2907 , +11467 , +2697 , +-3567 , +24965 , +10745 , +-18791 , +-4747 , +-26423 , +-5001 , +-22497 , +-21365 , +27397 , +-14903 , +21749 , +20911 , +20975 , +-3535 , +-24941 , +-2655 , +1393 , +-14689 , +-6561 , +-21051 , +-10933 , +-29387 , +17043 , +19667 , +-24795 , +-14285 , +-5237 , +-10735 , +-18141 , +4977 , +31133 , +6925 , +-22265 , +23645 , +2935 , +31695 , +-67 , +-22417 , +-4877 , +16797 , +12673 , +8737 , +-10643 , +-29657 , +-15765 , +-23447 , +23713 , +18753 , +-24693 , +31917 , +-22277 , +12067 , +-891 , +-25793 , +4727 , +12569 , +-29279 , +-5549 , +-20747 , +26299 , +30315 , +889 , +29969 , +-8787 , +-15161 , +-1135 , +1661 , +19917 , +-12153 , +32071 , +-17709 , +10225 , +22409 , +-5625 , +759 , +-2273 , +-20919 , +-18049 , +-17177 , +-29633 , +-8963 , +-12411 , +-28653 , +-5027 , +299 , +161 , +-5569 , +31065 , +-13377 , +31995 , +-19255 , +19743 , +29611 , +22997 , +23189 , +16229 , +-2827 , +-3705 , +13911 , +-29215 , +-2987 , +20973 , +367 , +-24839 , +8011 , +29035 , +23363 , +-10487 , +24759 , +25183 , +277 , +-2035 , +-15883 , +15637 , +-12709 , +997 , +20589 , +-1975 , +7579 , +6403 , +-8271 , +-6121 , +-24135 , +16811 , +21 , +7029 , +20443 , +-21083 , +451 , +20527 , +29111 , +20087 , +23641 , +-19117 , +30839 , +20003 , +21241 , +13373 , +-22527 , +22611 , +11495 , +30715 , +13019 , +11801 , +-9563 , +27471 , +-8575 , +31785 , +24445 , +25897 , +-14277 , +27527 , +-10331 , +-17511 , +25201 , +-6961 , +29399 , +-2743 , +17039 , +-551 , +15201 , +20855 , +-10417 , +-30205 , +449 , +-8599 , +-24677 , +17631 , +17601 , +-10643 , +-1567 , +-28819 , +28169 , +31555 , +9193 , +14291 , +15163 , +10275 , +-31947 , +17305 , +-21623 , +-11727 , +-12849 , +13399 , +18893 , +-20623 , +11173 , +-16645 , +11043 , +15425 , +-6045 , +28021 , +31229 , +22355 , +-12853 , +8949 , +-6721 , +-21473 , +-16757 , +-1377 , +-12587 , +9193 , +-22125 , +30921 , +-30901 , +-27355 , +28145 , +-31059 , +32746 , +27009 , +-14553 , +12453 , +-17981 , +29265 , +-9721 , +-24861 , +21593 , +-23665 , +31233 , +16545 , +-28631 , +-4787 , +-16631 , +-24089 , +7623 , +-5201 , +991 , +-7239 , +4481 , +-23195 , +-6921 , +20177 , +21347 , +4259 , +22471 , +-1835 , +-7201 , +-26987 , +29343 , +-3051 , +-13089 , +19801 , +-759 , +447 , +5979 , +8313 , +24723 , +16023 , +-25225 , +-24605 , +4665 , +-15825 , +4375 , +-21157 , +3117 , +-22367 , +3827 , +-16259 , +28729 , +32451 , +-27079 , +-1749 , +-5487 , +-30491 , +-17251 , +-18293 , +-4819 , +-9215 , +-2317 , +-1921 , +23463 , +-16005 , +-12725 , +6553 , +-16505 , +23893 , +22911 , +24471 , +-25309 , +3815 , +21337 , +-11173 , +251 , +-31721 , +9501 , +-13987 , +-8829 , +-2287 , +-16979 , +-20563 , +20871 , +-29055 , +-29419 , +32351 , +28421 , +22603 , +31921 , +24465 , +-25995 , +-10563 , +15289 , +-9259 , +6837 , +-26543 , +-18339 , +15411 , +-3757 , +-11817 , +7521 , +23199 , +-27799 , +29505 , +11309 , +-26391 , +-25867 , +-20795 , +19309 , +13891 , +2231 , +27303 , +8741 , +-17619 , +11901 , +-27291 , +5959 , +-19469 , +-9723 , +-11147 , +-29231 , +29091 , +-10159 , +-31365 , +13665 , +2439 , +27005 , +-30203 , +18249 , +19223 , +-17123 , +-10825 , +2095 , +-7043 , +3857 , +14101 , +26149 , +28029 , +31963 , +21165 , +2871 , +-28419 , +11133 , +18645 , +-17267 , +3313 , +-10807 , +-547 , +24063 , +-16169 , +23363 , +31953 , +29229 , +-32075 , +26477 , +27819 , +28441 , +-3451 , +-13907 , +4103 , +-16583 , +1077 , +-27241 , +-14493 , +-14565 , +30755 , +-23601 , +-29227 , +-14481 , +-1529 , +-29861 , +26687 , +-3159 , +7803 , +-21629 , +16137 , +-27371 , +-2331 , +24091 , +6745 , +-28053 , +29691 , +-5525 , +14545 , +13299 , +20147 , +20605 , +-1863 , +31761 , +-20547 , +-31501 , +3015 , +-5021 , +19837 , +13677 , +-4787 , +3925 , +14463 , +-21169 , +4847 , +-25027 , +3703 , +-3291 , +-12313 , +-25611 , +-13397 , +-18825 , +25267 , +15339 , +-3333 , +9763 , +9547 , +-4675 , +17487 , +18225 , +22497 , +25941 , +-18033 , +-7123 , +32281 , +-2181 , +545 , +-21245 , +-14665 , +8945 , +13533 , +-24749 , +30177 , +-25077 , +-3963 , +20293 , +-13867 , +-16193 , +-23877 , +10473 , +21017 , +-23735 , +11647 , +16909 , +12611 , +-14017 , +-23773 , +-11119 , +16671 , +-20189 , +20673 , +-1727 , +-28299 , +8321 , +-12487 , +-17615 , +14649 , +-31609 , +21155 , +7051 , +-3515 , +16153 , +-4023 , +7669 , +30611 , +14445 , +4897 , +30045 , +7667 , +-29405 , +-10555 , +-5801 , +-24763 , +-20265 , +-32537 , +3059 , +-28629 , +-8893 , +-11955 , +22549 , +30795 , +9679 , +24643 , +20559 , +1277 , +1961 , +-15455 , +-18891 , +20105 , +-12701 , +-19921 , +29243 , +-22557 , +-23289 , +-8787 , +17415 , +-3887 , +-21587 , +-17593 , +-11445 , +-7491 , +-5733 , +-3449 , +14623 , +20439 , +29647 , +-21805 , +-26151 , +-13095 , +-24537 , +28519 , +-6305 , +-17095 , +-25361 , +-7737 , +25609 , +14821 , +17659 , +-3403 , +-531 , +-13701 , +-30655 , +-9803 , +6851 , +26877 , +16619 , +-32005 , +-5065 , +-14323 , +-13061 , +-21535 , +-6979 , +21411 , +17493 , +26091 , +25843 , +-7101 , +-23713 , +14387 , +14703 , +-25411 , +-15845 , +-26779 , +289 , +-5539 , +28597 , +-5065 , +5151 , +8097 , +-30039 , +-8089 , +775 , +-24195 , +27983 , +10793 , +18131 , +7943 , +-30983 , +-29149 , +14643 , +-13387 , +31109 , +20453 , +-4765 , +5137 , +-27775 , +-14105 , +383 , +-15113 , +-327 , +24053 , +101 , +7497 , +31563 , +-29901 , +27655 , +-15835 , +-175 , +16009 , +2111 , +3489 , +4835 , +14503 , +32307 , +-20479 , +16575 , +-21385 , +-4069 , +7025 , +29531 , +-10989 , +-27217 , +-19911 , +-27011 , +-17855 , +-1811 , +12155 , +21843 , +-9367 , +-5259 , +16997 , +19723 , +-1779 , +-13205 , +-11285 , +-29715 , +-19261 , +14019 , +-4351 , +-19215 , +16299 , +-20451 , +-15535 , +-24617 , +-12443 , +28703 , +-17805 , +-12863 , +4499 , +-10163 , +6055 , +-30137 , +21951 , +-19367 , +6667 , +4369 , +-23069 , +-9461 , +6479 , +-28681 , +-31393 , +18311 , +-27397 , +23943 , +-29081 , +17203 , +-20973 , +15405 , +-23035 , +-18425 , +867 , +455 , +-373 , +17255 , +26661 , +31671 , +-24431 , +8575 , +27975 , +-6269 , +-19863 , +-30443 , +13597 , +-10265 , +13843 , +-28703 , +-30311 , +-8589 , +30143 , +12141 , +-21249 , +-11875 , +-10565 , +-32159 , +-8919 , +1883 , +19189 , +-11671 , +307 , +23613 , +6375 , +-29057 , +31161 , +24321 , +12827 , +-15923 , +-29813 , +30897 , +-12261 , +8961 , +23789 , +26933 , +-28695 , +21541 , +-701 , +-3983 , +-15359 , +27383 , +28499 , +-1069 , +13505 , +22979 , +11769 , +12407 , +1901 , +20663 , +9057 , +10681 , +933 , +-20545 , +-30023 , +17483 , +-4259 , +-24353 , +-19341 , +19921 , +14667 , +-3329 , +9461 , +-3849 , +-22031 , +19797 , +1489 , +13835 , +21255 , +21295 , +24965 , +-4079 , +30073 , +-12213 , +8617 , +28255 , +-27175 , +-31299 , +18349 , +19125 , +30565 , +-20683 , +22543 , +-21553 , +13675 , +-10009 , +28693 , +-11129 , +13139 , +7635 , +-509 , +22373 , +6923 , +26287 , +-27695 , +-14665 , +-24059 , +-16083 , +-13209 , +14639 , +19631 , +26591 , +-17577 , +31479 , +-6039 , +-28019 , +-8435 , +17225 , +-3077 , +-22773 , +3469 , +18053 , +-20847 , +-7537 , +21415 , +31951 , +1331 , +5005 , +16057 , +29989 , +5819 , +31759 , +-30505 , +3311 , +-31159 , +29833 , +-24689 , +25635 , +21575 , +-6347 , +-737 , +26071 , +30165 , +15335 , +-13273 , +-17067 , +-7483 , +-13203 , +-12819 , +-28737 , +21013 , +31069 , +-1275 , +-11751 , +23781 , +30579 , +-10599 , +-27671 , +16369 , +-4763 , +-5101 , +5713 , +-3195 , +31297 , +28511 , +1949 , +-11783 , +15423 , +30623 , +-17557 , +-31577 , +28703 , +-13211 , +-18643 , +28517 , +16633 , +-17049 , +27483 , +21113 , +-8035 , +-839 , +28915 , +23317 , +-32667 , +-3189 , +9119 , +23117 , +17039 , +-30381 , +-4021 , +23185 , +-17381 , +-10861 , +12347 , +19359 , +7961 , +-19443 , +-5983 , +-761 , +-23165 , +-19597 , +18109 , +7957 , +21659 , +22189 , +12391 , +-32175 , +-20285 , +8325 , +-16073 , +19831 , +31177 , +25059 , +3091 , +25069 , +1999 , +17033 , +-1719 , +-22853 , +24727 , +-955 , +-26329 , +29187 , +-25245 , +-16213 , +-15595 , +-14083 , +-18107 , +16717 , +22827 , +-20891 , +24577 , +21113 , +2121 , +14207 , +-10917 , +-24475 , +-9039 , +-24697 , +-29453 , +-4367 , +-31973 , +4527 , +-30045 , +-9255 , +-29103 , +24973 , +9039 , +-25741 , +-26299 , +27167 , +13881 , +-22561 , +-25173 , +19259 , +30443 , +-9529 , +22285 , +15755 , +-8327 , +-5739 , +2665 , +13571 , +-7315 , +-17373 , +-30143 , +2519 , +31499 , +-27137 , +-12485 , +24571 , +-24771 , +-30179 , +-715 , +1295 , +19933 , +12557 , +11483 , +-795 , +-20847 , +6583 , +-11835 , +-2969 , +28709 , +-4973 , +5385 , +21285 , +-2461 , +-18083 , +-937 , +-23749 , +28771 , +26447 , +-19059 , +-30769 , +28531 , +-16419 , +-8491 , +-1523 , +5727 , +3049 , +9017 , +1177 , +31055 , +-17547 , +951 , +-19061 , +17955 , +4075 , +9443 , +32483 , +19785 , +16581 , +-1799 , +-17017 , +779 , +4815 , +7791 , +-24907 , +-28295 , +22999 , +19229 , +7165 , +-27981 , +23791 , +7109 , +17853 , +3015 , +-27365 , +-24525 , +-27631 , +-16381 , +-16749 , +-1067 , +30291 , +29913 , +-19347 , +-3377 , +-9969 , +15913 , +3815 , +-17511 , +-9607 , +27427 , +-1009 , +-4849 , +25963 , +11163 , +19203 , +-7921 , +-5417 , +-31263 , +8617 , +25491 , +-3647 , +-19175 , +21731 , +1603 , +-19015 , +-30699 , +-9395 , +-3955 , +-29741 , +-10069 , +21101 , +-31677 , +17945 , +-19573 , +3701 , +-20817 , +19853 , +18589 , +-21393 , +15915 , +-21863 , +15315 , +-24829 , +5175 , +-19451 , +28293 , +-21087 , +-29671 , +-25475 , +-9911 , +-8639 , +-4631 , +-27019 , +-29113 , +-15973 , +17973 , +-14667 , +31761 , +-26145 , +31251 , +-17087 , +2307 , +21481 , +-4173 , +-21285 , +7957 , +-13573 , +-23673 , +6389 , +-16339 , +20213 , +459 , +12847 , +-17657 , +-6895 , +23715 , +-26299 , +-26501 , +15127 , +22203 , +-16235 , +22881 , +-15089 , +6735 , +-23539 , +7401 , +-631 , +-19251 , +4001 , +18281 , +16453 , +28403 , +11343 , +16831 , +14197 , +31061 , +-29815 , +26919 , +21359 , +-14971 , +26935 , +18317 , +17639 , +25511 , +23595 , +-21393 , +-3669 , +15491 , +11547 , +-16855 , +-9259 , +-32729 , +3091 , +-25639 , +29573 , +-24335 , +-9099 , +-22607 , +19227 , +13115 , +-12435 , +4557 , +-23057 , +-30371 , +1257 , +-17523 , +22913 , +25687 , +27409 , +2929 , +31041 , +-28453 , +-27581 , +-13973 , +-15179 , +-14095 , +-17535 , +-25671 , +20543 , +-19961 , +-20619 , +15425 , +24651 , +20363 , +-9245 , +-413 , +-4335 , +-15867 , +10655 , +-17071 , +-11069 , +-21843 , +-4857 , +-13587 , +2633 , +2947 , +-25855 , +-2275 , +-385 , +-1047 , +31845 , +18339 , +30179 , +2487 , +6151 , +30839 , +-4911 , +-24873 , +-29923 , +-9063 , +-3011 , +17243 , +-30649 , +-18571 , +-32533 , +5143 , +13559 , +-22869 , +-23261 , +17847 , +-25223 , +13429 , +-21267 , +3157 , +-2207 , +10873 , +5319 , +-16491 , +27269 , +-17121 , +21213 , +-27843 , +-26507 , +10093 , +-5437 , +-17333 , +-25995 , +-12447 , +-15447 , +23179 , +-21005 , +-30019 , +14615 , +-331 , +18301 , +7281 , +-8669 , +9471 , +-15297 , +-32157 , +27437 , +31801 , +29175 , +11215 , +-12787 , +20833 , +9581 , +-20447 , +-11049 , +-2111 , +5993 , +7747 , +27405 , +-31357 , +16433 , +31873 , +-7855 , +-17211 , +-5763 , +-28455 , +14253 , +31037 , +-20753 , +-30249 , +-7621 , +31297 , +-23287 , +-24599 , +101 , +-7825 , +-8533 , +18235 , +32413 , +15801 , +2309 , +2577 , +6803 , +31491 , +22039 , +-23659 , +-15893 , +-29127 , +28057 , +29497 , +17275 , +13801 , +-25463 , +-8053 , +-13569 , +-22697 , +-1265 , +-14449 , +8013 , +-32742 , +-16127 , +-31341 , +6937 , +-11217 , +-32551 , +-16759 , +22559 , +-20329 , +-32471 , +29413 , +-31517 , +-5529 , +-4969 , +32233 , +23787 , +-28055 , +4175 , +5253 , +-17551 , +-6869 , +24839 , +23729 , +-16229 , +4001 , +32363 , +-19137 , +-32453 , +-24527 , +-4837 , +-14797 , +14587 , +-939 , +-16611 , +-3677 , +30497 , +-19789 , +-7455 , +15621 , +15809 , +425 , +20653 , +19213 , +-29839 , +27255 , +-12647 , +32261 , +18313 , +-22331 , +-31991 , +-9567 , +2265 , +-6455 , +3491 , +-15525 , +-20773 , +-31271 , +24267 , +9289 , +17781 , +21377 , +1423 , +10101 , +11045 , +-31971 , +11313 , +2487 , +-3643 , +17399 , +-1267 , +10251 , +-3653 , +19413 , +-26077 , +-8857 , +1973 , +11797 , +-30467 , +18713 , +29915 , +-10427 , +-31439 , +-27237 , +22931 , +1347 , +-18595 , +-10265 , +-15699 , +5059 , +24213 , +8029 , +-16099 , +-2697 , +-19875 , +-12793 , +-31685 , +-20061 , +13099 , +-11903 , +-4493 , +15921 , +8529 , +-11189 , +-25473 , +3657 , +21117 , +-95 , +-10465 , +11633 , +7601 , +26067 , +26451 , +16155 , +-27207 , +-21217 , +-15087 , +15047 , +-13787 , +4871 , +-26497 , +15501 , +18107 , +24615 , +1445 , +16965 , +-30347 , +-7019 , +-17745 , +11541 , +-22787 , +5293 , +14493 , +-8309 , +-10855 , +-8589 , +20091 , +-12233 , +5803 , +20329 , +16159 , +-5955 , +-18775 , +-23837 , +-30369 , +2423 , +-9327 , +20703 , +-13631 , +2437 , +-9751 , +13671 , +-19263 , +-29847 , +-30677 , +26715 , +-29573 , +32283 , +18631 , +-8751 , +11503 , +-23899 , +663 , +26349 , +943 , +-4549 , +-16427 , +11063 , +31 , +8397 , +11163 , +12915 , +-4825 , +26663 , +-23087 , +5881 , +11631 , +26503 , +9641 , +30861 , +21013 , +31665 , +-23909 , +18363 , +-31771 , +-27769 , +15321 , +-32345 , +14097 , +29993 , +-10685 , +29805 , +8557 , +-14461 , +26857 , +9203 , +-5347 , +-18323 , +-20487 , +-6331 , +-28195 , +-26819 , +32321 , +-10643 , +-2395 , +15331 , +25883 , +8389 , +-29195 , +-28035 , +-5391 , +-7211 , +-21893 , +9077 , +2091 , +-25937 , +23127 , +-4075 , +8881 , +-16965 , +20181 , +31643 , +16343 , +-21739 , +-14699 , +22749 , +-23327 , +28525 , +-3497 , +5201 , +-25101 , +-30899 , +-13277 , +-11595 , +-23671 , +12551 , +-9973 , +31771 , +-27017 , +26359 , +-12963 , +-13433 , +19031 , +6763 , +-29853 , +6919 , +5769 , +-14601 , +29837 , +17477 , +-23131 , +-2491 , +-31433 , +28071 , +-17545 , +-13187 , +13019 , +7139 , +10609 , +13577 , +-31541 , +24601 , +-22095 , +-14337 , +24417 , +31335 , +-10139 , +-17 , +31175 , +-14077 , +981 , +-10177 , +-2531 , +23511 , +2767 , +27645 , +5181 , +1169 , +421 , +-21185 , +-2319 , +15173 , +-10843 , +-13063 , +-3161 , +-20615 , +-22769 , +27473 , +25773 , +-8759 , +4491 , +10363 , +30185 , +-32267 , +6949 , +-20979 , +-7159 , +15747 , +453 , +-14119 , +9801 , +19147 , +-24797 , +-21683 , +-1377 , +-27491 , +-25787 , +-4037 , +-13189 , +2633 , +9581 , +30267 , +-4617 , +-30649 , +27553 , +-21627 , +7063 , +11585 , +-30575 , +25157 , +17021 , +29625 , +8219 , +-14991 , +289 , +-6125 , +25151 , +-31197 , +-9591 , +-11465 , +-21351 , +-9869 , +-27647 , +-20061 , +-32173 , +24273 , +-19113 , +-12537 , +4779 , +-31021 , +-23669 , +-8613 , +1493 , +-28007 , +19981 , +-6535 , +-14199 , +-15461 , +-6539 , +23347 , +3563 , +-11257 , +-25927 , +-17689 , +-16367 , +20377 , +-13851 , +-30555 , +5869 , +-6925 , +-21679 , +-1357 , +3535 , +18287 , +-8095 , +13751 , +-4265 , +-18053 , +-5965 , +27717 , +12271 , +-10375 , +-3875 , +-17673 , +20169 , +-17655 , +-3165 , +6413 , +-2741 , +3815 , +-23119 , +13689 , +3345 , +11079 , +9169 , +-26493 , +1121 , +-11609 , +-9311 , +-7719 , +-1757 , +-22739 , +-22829 , +31531 , +601 , +-3975 , +-28457 , +-26819 , +20507 , +-13827 , +16163 , +-10871 , +23045 , +20955 , +29665 , +25167 , +-11205 , +-4039 , +-23765 , +-5327 , +-23847 , +20251 , +4797 , +16455 , +-31761 , +6837 , +31799 , +-1603 , +-22537 , +8777 , +-22069 , +-1567 , +-3891 , +-3709 , +1403 , +9161 , +3879 , +31299 , +-27949 , +7777 , +13967 , +-6397 , +19225 , +31747 , +-24615 , +11689 , +21513 , +7827 , +-28133 , +31453 , +2323 , +12311 , +10787 , +3559 , +20231 , +-30771 , +-26503 , +-25343 , +10841 , +-11325 , +3527 , +-9681 , +4045 , +24301 , +3549 , +12449 , +-6209 , +-13373 , +24873 , +21117 , +15303 , +-25771 , +23719 , +-20671 , +-30973 , +-10015 , +-18339 , +27283 , +8389 , +-15887 , +-21417 , +-5213 , +-17973 , +-15633 , +-29671 , +-25349 , +-7169 , +-24517 , +-26469 , +-2853 , +-25433 , +9157 , +16573 , +24073 , +20763 , +10027 , +-30653 , +6459 , +22025 , +21061 , +-12977 , +-20775 , +18721 , +26183 , +-23473 , +2403 , +21841 , +27989 , +641 , +-12215 , +-11903 , +-22885 , +28385 , +6971 , +12741 , +-31001 , +29099 , +5641 , +-15593 , +-23105 , +-1467 , +-21261 , +10641 , +-4363 , +-3127 , +-9847 , +6435 , +-3893 , +-16401 , +-22531 , +16589 , +-24961 , +-12151 , +-29437 , +-8111 , +24423 , +6011 , +9245 , +117 , +-15731 , +-31435 , +-4485 , +-14927 , +-20799 , +19883 , +10839 , +-10897 , +26417 , +11207 , +23229 , +17853 , +15497 , +23403 , +-26631 , +3977 , +17027 , +-32289 , +16475 , +31575 , +-7681 , +15569 , +8603 , +-32647 , +-24669 , +-28731 , +-19793 , +-28983 , +-4375 , +-6121 , +30237 , +-17699 , +27067 , +-4249 , +7387 , +-15165 , +17551 , +-7007 , +-32349 , +-3783 , +22267 , +-19617 , +5323 , +11617 , +-28469 , +-32263 , +-12131 , +29949 , +13213 , +-4627 , +20017 , +-3291 , +-22281 , +-20777 , +4803 , +-10883 , +19681 , +-10251 , +-21111 , +18935 , +1271 , +28691 , +-16879 , +-24839 , +-1009 , +-26613 , +31509 , +-471 , +23099 , +-2125 , +-11823 , +-18027 , +20855 , +-22173 , +-18977 , +-23691 , +22197 , +23523 , +-18033 , +26717 , +-8331 , +-7455 , +-31045 , +25597 , +31713 , +-4621 , +20517 , +-6069 , +-23193 , +7689 , +-11451 , +28491 , +6599 , +12643 , +685 , +-20677 , +6839 , +32269 , +-3877 , +2383 , +27121 , +29397 , +5009 , +19185 , +22997 , +22211 , +30637 , +14695 , +-13707 , +-235 , +-639 , +-8165 , +27449 , +-19539 , +13739 , +6479 , +6383 , +-1515 , +-2449 , +18769 , +-20379 , +32497 , +16783 , +-15307 , +11653 , +-10763 , +-28001 , +-10737 , +28387 , +18527 , +11743 , +-6743 , +30179 , +27123 , +-30827 , +-22083 , +31555 , +-21393 , +23523 , +-5977 , +-20419 , +-22143 , +-28897 , +-17755 , +1051 , +23361 , +28333 , +-14707 , +-14769 , +-1235 , +27221 , +28929 , +32015 , +-16483 , +-8677 , +30247 , +-14239 , +12215 , +1175 , +-6677 , +-22075 , +17905 , +-22067 , +-1369 , +2111 , +6401 , +-18807 , +-15767 , +-14095 , +17239 , +11311 , +4773 , +21563 , +-16107 , +-22245 , +-16787 , +-8375 , +31885 , +3445 , +-30939 , +21043 , +16683 , +22661 , +-16441 , +8849 , +19707 , +22167 , +6799 , +-1395 , +14491 , +14149 , +-26311 , +-31603 , +28081 , +-23463 , +6071 , +13111 , +-7189 , +28961 , +26983 , +24081 , +23657 , +31301 , +-32557 , +-30047 , +-11323 , +-12761 , +-26145 , +14837 , +25215 , +-19025 , +-8569 , +4811 , +17405 , +-19025 , +32279 , +-16357 , +15357 , +8371 , +-20769 , +23609 , +4753 , +20825 , +-28051 , +-16279 , +24211 , +9519 , +29769 , +-28423 , +22177 , +-12279 , +23333 , +24019 , +-8041 , +-24621 , +25759 , +-20579 , +-26755 , +-14095 , +-7313 , +22863 , +11 , +-11505 , +-18395 , +-6587 , +-23659 , +-16765 , +-9121 , +31967 , +18835 , +31263 , +-26493 , +3475 , +1929 , +-15997 , +23541 , +9867 , +24451 , +-1021 , +-20531 , +17335 , +9495 , +13301 , +15381 , +-3227 , +24785 , +-16759 , +22395 , +-22687 , +-5585 , +-21465 , +6539 , +-30075 , +-4067 , +-26301 , +26477 , +13011 , +10213 , +-2125 , +-3311 , +-30709 , +-9555 , +26763 , +-23311 , +-18739 , +-30351 , +15987 , +26689 , +-30685 , +24435 , +-16253 , +-11851 , +-2657 , +11067 , +17811 , +-26461 , +20985 , +5639 , +-16361 , +23251 , +-8675 , +-11829 , +-11651 , +-23899 , +8905 , +30119 , +1019 , +-22575 , +-6493 , +-16169 , +11755 , +-15717 , +6355 , +-965 , +-18009 , +2451 , +-30699 , +12859 , +-14631 , +4547 , +-16801 , +-2733 , +-11681 , +18799 , +-10013 , +27899 , +-2671 , +-6843 , +-19267 , +-7897 , +22061 , +-10213 , +18431 , +31809 , +-8543 , +-13013 , +32585 , +31639 , +-10523 , +-25411 , +30695 , +-31135 , +30173 , +13165 , +28257 , +25387 , +803 , +25565 , +14749 , +-15399 , +-24217 , +-25879 , +-21905 , +24595 , +22855 , +-4501 , +-22605 , +5705 , +31907 , +32357 , +24291 , +19237 , +-1413 , +-24381 , +24889 , +16255 , +-17597 , +-12403 , +1335 , +-27423 , +-25163 , +-11867 , +-6963 , +-18319 , +11321 , +5625 , +-12311 , +27761 , +-23889 , +-18115 , +2965 , +10295 , +23753 , +11813 , +13701 , +-31071 , +17643 , +27 , +-23491 , +31509 , +23415 , +-22409 , +-25701 , +-31507 , +-4429 , +-4553 , +11769 , +-26247 , +-25839 , +-14275 , +8641 , +-911 , +-21479 , +14839 , +-19577 , +-16651 , +-2639 , +8877 , +-29541 , +7417 , +-16901 , +30499 , +-14805 , +28997 , +-12365 , +-8733 , +20689 , +-2063 , +19707 , +9707 , +-26447 , +5967 , +23229 , +-28695 , +-16877 , +26481 , +15489 , +25067 , +14961 , +12315 , +-1857 , +-16983 , +18969 , +-27333 , +7617 , +12581 , +-3517 , +10719 , +-16655 , +-1543 , +-1113 , +8629 , +17079 , +29441 , +-18033 , +-9993 , +6353 , +-23401 , +-2687 , +-5393 , +-3801 , +28497 , +-10429 , +-28955 , +-29915 , +18731 , +8571 , +29601 , +-19049 , +1359 , +-25905 , +-11945 , +-26885 , +-25023 , +-1169 , +-5589 , +-10659 , +31389 , +14131 , +-20193 , +-17235 , +9293 , +31801 , +-12397 , +-6507 , +-5563 , +-16907 , +-16071 , +-24873 , +25777 , +9415 , +16013 , +31007 , +21431 , +14877 , +-21045 , +17759 , +-12113 , +10503 , +-11669 , +-3163 , +18895 , +-5307 , +29469 , +-32651 , +16501 , +-17679 , +11827 , +-32353 , +16847 , +-24441 , +13477 , +27537 , +4635 , +30087 , +9095 , +10049 , +-32161 , +13191 , +-19457 , +4209 , +-5987 , +-6191 , +31161 , +-2925 , +-19823 , +9077 , +26605 , +10779 , +2787 , +16353 , +21699 , +22621 , +2271 , +20483 , +13147 , +2015 , +25271 , +5583 , +15425 , +-27853 , +6699 , +-11155 , +-17313 , +-28591 , +7121 , +22205 , +-15747 , +19055 , +18625 , +635 , +25397 , +25683 , +-7473 , +20433 , +-13465 , +15155 , +-11443 , +32119 , +-9923 , +8713 , +-15305 , +-9921 , +29589 , +3435 , +-31761 , +30007 , +22533 , +-14363 , +-21643 , +-24259 , +-26807 , +18123 , +-221 , +279 , +30785 , +14235 , +-32287 , +-26869 , +-1689 , +24011 , +-19753 , +-25861 , +-22325 , +-9941 , +-4683 , +30199 , +2691 , +-4945 , +25949 , +-17837 , +17835 , +24027 , +-20197 , +28747 , +20435 , +1155 , +25707 , +-28911 , +20231 , +-23751 , +-22241 , +-1435 , +27191 , +-24553 , +21541 , +-9037 , +-16329 , +-18913 , +27831 , +-19035 , +-17099 , +14089 , +-25065 , +-2755 , +-31051 , +-2649 , +-29759 , +31601 , +-18943 , +28857 , +-32721 , +-11205 , +6437 , +22077 , +28161 , +-30661 , +-19859 , +-2221 , +-17465 , +22979 , +-20909 , +-15221 , +-11737 , +-14723 , +-30723 , +27337 , +-7005 , +-23181 , +5171 , +-22389 , +-4921 , +14773 , +-21801 , +29653 , +20459 , +-28307 , +9951 , +-30597 , +10081 , +-30353 , +-2867 , +-2307 , +-23757 , +19807 , +-6241 , +-13343 , +32601 , +-21445 , +3155 , +26505 , +881 , +6525 , +13273 , +-24947 , +-31493 , +-19791 , +27531 , +14989 , +-7157 , +8581 , +7205 , +-3181 , +-1407 , +-19855 , +1853 , +31203 , +30151 , +30651 , +-9411 , +-22443 , +4869 , +-11997 , +-27177 , +30511 , +-18983 , +12269 , +27909 , +-14471 , +20879 , +28539 , +30323 , +-24871 , +7387 , +-26003 , +-14967 , +-5141 , +2061 , +29745 , +14289 , +27415 , +-4659 , +-24805 , +-22533 , +-15387 , +30289 , +-18685 , +-16555 , +30433 , +9497 , +14425 , +7611 , +-19483 , +-30433 , +-29763 , +4115 , +-20229 , +1939 , +3607 , +-29367 , +-26191 , +14615 , +27951 , +-20031 , +-20751 , +20849 , +12485 , +29009 , +-20647 , +-30263 , +-14289 , +-18499 , +8211 , +1369 , +-2971 , +-20567 , +-29135 , +10411 , +-6495 , +26643 , +24703 , +-9389 , +-5257 , +-28597 , +20955 , +-21477 , +-1429 , +-32147 , +11285 , +20431 , +523 , +21595 , +-9411 , +29279 , +18561 , +10025 , +29057 , +21161 , +-18251 , +27941 , +13187 , +8355 , +29659 , +24131 , +17717 , +-27103 , +32657 , +21275 , +3879 , +-15873 , +-6025 , +15971 , +-2963 , +32225 , +12611 , +-805 , +28903 , +-31121 , +26207 , +-19495 , +14379 , +-20995 , +-20997 , +-2519 , +27849 , +8663 , +-21339 , +-6243 , +-30663 , +14829 , +-27029 , +5873 , +2845 , +-13559 , +17507 , +17999 , +-29141 , +29587 , +9935 , +-9661 , +19321 , +-9543 , +27573 , +10037 , +-18341 , +23095 , +12783 , +21855 , +18361 , +2693 , +8393 , +4931 , +-4885 , +-22129 , +15381 , +-12633 , +30473 , +21489 , +19659 , +-21491 , +23753 , +-30543 , +-18921 , +-2905 , +4309 , +28525 , +3831 , +13011 , +30371 , +-9953 , +22611 , +-19183 , +-28717 , +-3251 , +10125 , +-20611 , +-1543 , +9669 , +-25175 , +-19517 , +21763 , +4817 , +-32041 , +-18531 , +10761 , +12787 , +24203 , +25025 , +27307 , +-741 , +-7133 , +-10905 , +8417 , +10339 , +-29717 , +-19403 , +26457 , +-9155 , +-20277 , +-28995 , +16977 , +27191 , +2631 , +31605 , +28903 , +29737 , +-9425 , +3113 , +-12553 , +-519 , +-21341 , +23033 , +24433 , +25025 , +-4679 , +24533 , +-26829 , +-24935 , +20365 , +23401 , +95 , +-1593 , +13787 , +27807 , +-12751 , +27251 , +5143 , +11151 , +31069 , +-14359 , +3849 , +27905 , +-797 , +12873 , +-17695 , +-4771 , +-13467 , +-21057 , +19913 , +6695 , +5381 , +26691 , +7949 , +-19983 , +30133 , +-24123 , +-13663 , +29407 , +-23527 , +-20749 , +-11959 , +-28785 , +14547 , +3681 , +3363 , +8865 , +9833 , +2131 , +-11575 , +22689 , +-1649 , +-12061 , +5863 , +-30579 , +31241 , +-23355 , +28749 , +-3395 , +-15361 , +-10115 , +20109 , +24169 , +29139 , +21011 , +15637 , +19867 , +-4479 , +25935 , +-30017 , +-89 , +-30613 , +-30097 , +11761 , +-1501 , +23739 , +-6307 , +15661 , +20575 , +-19655 , +9073 , +-11213 , +24925 , +-7521 , +32153 , +-17007 , +17487 , +21875 , +-25315 , +-18245 , +-25727 , +-14495 , +5331 , +-19287 , +1503 , +21267 , +4315 , +-10517 , +-6425 , +26753 , +9933 , +-22719 , +-17121 , +17369 , +-16259 , +14259 , +-16621 , +-827 , +6443 , +-24279 , +-2359 , +-14765 , +17725 , +-21371 , +-27725 , +30525 , +15483 , +55 , +-21703 , +-3375 , +24253 , +-21923 , +8091 , +-30145 , +27443 , +24399 , +-6791 , +-4495 , +25097 , +17603 , +24515 , +-13719 , +18607 , +-24231 , +2615 , +-25069 , +18573 , +18625 , +10835 , +-3679 , +8247 , +7237 , +-16691 , +31075 , +24361 , +30699 , +26003 , +16921 , +25593 , +-7157 , +28731 , +32211 , +-27365 , +-7325 , +-8455 , +2373 , +-13303 , +13743 , +31269 , +16799 , +27405 , +26311 , +-15839 , +17125 , +5479 , +565 , +-4641 , +9929 , +-32239 , +17225 , +-20529 , +23553 , +24821 , +-26189 , +-1697 , +-20963 , +-13661 , +-9573 , +29933 , +5603 , +12933 , +30269 , +-4541 , +-5589 , +21409 , +-30213 , +24975 , +-30425 , +4041 , +9975 , +-5929 , +4687 , +-18089 , +-23251 , +16369 , +18601 , +-16541 , +23303 , +5895 , +13741 , +13431 , +-28291 , +-5255 , +-23407 , +10197 , +3233 , +-24725 , +3629 , +18715 , +193 , +-30801 , +3405 , +-12659 , +-13317 , +10309 , +-3195 , +5571 , +19541 , +22345 , +-26989 , +-2333 , +10839 , +-389 , +-4563 , +16985 , +-4065 , +13091 , +-26013 , +24851 , +17663 , +-9059 , +-5525 , +-28879 , +9611 , +-24255 , +31747 , +-22205 , +28737 , +20963 , +2887 , +1025 , +-24945 , +-29747 , +-29949 , +18049 , +631 , +-14035 , +7571 , +-16657 , +24741 , +-26597 , +1593 , +10693 , +16129 , +12291 , +10989 , +25473 , +-16429 , +7591 , +16067 , +-791 , +24907 , +15763 , +11445 , +10669 , +31141 , +-17131 , +-9465 , +435 , +-14399 , +22967 , +-8425 , +-29497 , +-4045 , +-26829 , +14775 , +-28461 , +16095 , +9197 , +-19449 , +-25961 , +-31465 , +9201 , +-2873 , +14559 , +27685 , +-26017 , +-6595 , +-7615 , +5237 , +-22165 , +-31625 , +32081 , +22811 , +-7975 , +-21443 , +859 , +-28677 , +21225 , +591 , +13715 , +7763 , +-22569 , +-29871 , +-8995 , +-17953 , +-6191 , +3099 , +-29711 , +-20891 , +13173 , +-13683 , +23591 , +-37 , +8891 , +-14607 , +-25439 , +-16143 , +637 , +1483 , +-5113 , +30261 , +-22429 , +563 , +-19263 , +-8797 , +5471 , +-8017 , +-31829 , +-3397 , +-24919 , +31367 , +12629 , +-30937 , +-10959 , +-9821 , +21935 , +18369 , +-7269 , +15579 , +-435 , +-31175 , +-25931 , +15577 , +7955 , +-24797 , +-7059 , +10597 , +-19075 , +21655 , +-10927 , +14155 , +5699 , +-2747 , +5243 , +-26971 , +23971 , +-22515 , +-11755 , +2495 , +31247 , +-19433 , +1095 , +5219 , +-13977 , +7531 , +8887 , +23485 , +-16207 , +28171 , +6271 , +20139 , +-27053 , +905 , +-23397 , +-20841 , +26315 , +-18147 , +-7947 , +4307 , +-13343 , +17991 , +10183 , +-3989 , +24165 , +10709 , +4005 , +26749 , +6763 , +31119 , +-18967 , +12057 , +7669 , +28221 , +4019 , +-6001 , +-17863 , +1105 , +31067 , +27469 , +20305 , +-30485 , +15467 , +3127 , +-5513 , +27525 , +17435 , +-29829 , +7867 , +11259 , +-18367 , +-17941 , +4157 , +-17105 , +-18735 , +28379 , +10719 , +13331 , +-7217 , +-6547 , +30087 , +6995 , +1997 , +8305 , +3789 , +17247 , +29917 , +22463 , +-22469 , +26375 , +27145 , +10759 , +-25857 , +31891 , +11601 , +-30669 , +31015 , +2911 , +5153 , +1843 , +-26025 , +24045 , +12867 , +-22177 , +-25853 , +-6017 , +-6305 , +-18357 , +17951 , +-17359 , +749 , +-14559 , +-7833 , +24207 , +-18767 , +30069 , +21513 , +-8789 , +4019 , +2721 , +8159 , +30911 , +11697 , +-32359 , +-23251 , +-19149 , +-3807 , +7499 , +-22315 , +14407 , +22431 , +7533 , +-27377 , +15649 , +16107 , +-21541 , +27807 , +-151 , +-14753 , +-26005 , +-5993 , +-3491 , +1771 , +2379 , +-18307 , +7279 , +22917 , +-29227 , +23831 , +28499 , +-7129 , +-3613 , +-27245 , +29863 , +-23225 , +9139 , +-10423 , +9977 , +-18997 , +28211 , +-14353 , +20331 , +-1659 , +-28195 , +12879 , +16329 , +-2521 , +-10735 , +28039 , +16669 , +2245 , +-21781 , +-20813 , +-28983 , +-20037 , +-3173 , +15671 , +13859 , +12089 , +-28353 , +359 , +-19833 , +7721 , +17977 , +26055 , +-25103 , +22967 , +-30201 , +709 , +19991 , +-11971 , +26009 , +3301 , +-18947 , +-29503 , +-4047 , +-629 , +25619 , +-26645 , +-31567 , +28197 , +-2871 , +2941 , +18299 , +-25113 , +-11867 , +-4787 , +5315 , +-26105 , +-27427 , +7867 , +28519 , +-32661 , +-5771 , +4521 , +-30639 , +-11027 , +16331 , +31733 , +-2495 , +24845 , +11963 , +-16021 , +13869 , +-27095 , +-9941 , +19527 , +-29671 , +-5581 , +12337 , +-29661 , +23661 , +9965 , +27039 , +-11399 , +-27189 , +9123 , +-31969 , +-13423 , +17263 , +-7847 , +10701 , +-18689 , +-8197 , +-32367 , +-8625 , +14999 , +-32549 , +3955 , +-21145 , +-6931 , +29203 , +-27755 , +21783 , +11329 , +23199 , +27177 , +11815 , +6915 , +-32443 , +21427 , +-19885 , +25281 , +18929 , +14413 , +-2355 , +3497 , +-31859 , +5459 , +-3225 , +-31113 , +-25005 , +3489 , +-4575 , +12017 , +25259 , +5193 , +-7357 , +15587 , +16519 , +10697 , +16885 , +5519 , +-12499 , +-23605 , +-10919 , +-8271 , +-27233 , +30549 , +12833 , +-31769 , +-19611 , +-641 , +-32601 , +-11339 , +-32271 , +10935 , +-1147 , +3837 , +-14739 , +-20373 , +-1359 , +32750 , +-29669 , +335 , +-7413 , +25987 , +16167 , +-20477 , +-11645 , +-7045 , +8197 , +8289 , +24739 , +14031 , +-22719 , +801 , +19379 , +-11861 , +-3619 , +-27619 , +27207 , +-17949 , +-12759 , +4869 , +-18083 , +-16657 , +-32487 , +28313 , +-8457 , +-11163 , +-9187 , +-26021 , +-1753 , +16869 , +-17541 , +-31025 , +4537 , +-7771 , +-31455 , +13361 , +3645 , +9553 , +-16379 , +-10327 , +29859 , +6553 , +23547 , +-29947 , +-9133 , +8221 , +-15863 , +32499 , +25547 , +-26651 , +17731 , +10167 , +679 , +11359 , +3101 , +23651 , +4177 , +719 , +2639 , +-8049 , +-10497 , +32335 , +8991 , +20629 , +-29859 , +-11707 , +3141 , +-6079 , +-32605 , +6997 , +2359 , +7185 , +-3805 , +14049 , +5903 , +31975 , +13165 , +4347 , +-24365 , +-8635 , +-19493 , +-24351 , +21599 , +14083 , +-30027 , +19443 , +12203 , +13445 , +1731 , +-6355 , +24239 , +-1925 , +1123 , +3867 , +443 , +-1777 , +26919 , +3669 , +29765 , +31653 , +-25627 , +2679 , +11341 , +-24053 , +20821 , +-20589 , +-13783 , +-32199 , +-31445 , +4657 , +28909 , +16515 , +-2135 , +-61 , +-209 , +-23463 , +1973 , +30109 , +16499 , +8049 , +16767 , +30319 , +-20751 , +-16499 , +31113 , +-2503 , +-8707 , +687 , +-13243 , +5319 , +9427 , +1483 , +23089 , +24229 , +-24077 , +1541 , +6249 , +19617 , +12029 , +-21399 , +-29247 , +-17999 , +23811 , +7199 , +-11165 , +-30851 , +4453 , +15145 , +-18471 , +10573 , +-9437 , +11669 , +18357 , +19845 , +-26429 , +31543 , +-18787 , +23959 , +-31083 , +-10269 , +-8729 , +3207 , +19867 , +1571 , +15799 , +-21549 , +10971 , +-13201 , +-11891 , +32505 , +-14535 , +29927 , +-28321 , +-14997 , +-10297 , +-12409 , +-2245 , +-19713 , +7853 , +12005 , +24913 , +3827 , +-7057 , +22369 , +-22381 , +-20131 , +-32301 , +-10009 , +-15409 , +-26839 , +4659 , +-13541 , +-12479 , +-15227 , +-6577 , +25629 , +20649 , +-21011 , +-12361 , +25019 , +4081 , +24463 , +-9077 , +-17117 , +23603 , +6991 , +-25621 , +-24275 , +5471 , +-23239 , +-32069 , +6907 , +21067 , +-2433 , +-30459 , +32071 , +-1205 , +-28949 , +-26667 , +-4595 , +12625 , +7387 , +-8313 , +5833 , +-9859 , +-19531 , +-20831 , +28459 , +9527 , +18661 , +-7885 , +6741 , +28359 , +-20657 , +-32601 , +-12657 , +17007 , +-14005 , +-21477 , +-16515 , +-5119 , +10521 , +24891 , +731 , +24823 , +-10273 , +15765 , +26549 , +-8437 , +31515 , +-12169 , +14361 , +5971 , +-28513 , +-27327 , +-8871 , +15825 , +-1787 , +11839 , +-8517 , +-10865 , +-30549 , +-2045 , +12977 , +-28353 , +-10453 , +-29381 , +23193 , +8259 , +1361 , +21259 , +16619 , +16465 , +-20077 , +-23071 , +20983 , +-5241 , +-11513 , +-16689 , +-14565 , +-1275 , +-19745 , +-5783 , +-25475 , +5635 , +-17309 , +8721 , +10559 , +17767 , +23395 , +-19241 , +-11715 , +995 , +-24273 , +-2861 , +-12481 , +8839 , +-6125 , +-23561 , +31411 , +23005 , +11601 , +9065 , +9189 , +-8323 , +22931 , +1113 , +-9283 , +-10197 , +12259 , +4453 , +13291 , +-407 , +6951 , +26715 , +26791 , +21907 , +-28133 , +-17241 , +-4885 , +16757 , +18881 , +23069 , +-11997 , +-9629 , +-4513 , +87 , +-915 , +-10799 , +-25865 , +11915 , +-20407 , +-9363 , +-14533 , +-2077 , +20189 , +-24905 , +-7157 , +-1961 , +-9315 , +-27375 , +24163 , +-32253 , +11923 , +-24475 , +16611 , +-25859 , +21001 , +-31183 , +11187 , +-7245 , +715 , +-29913 , +-9457 , +-577 , +-13605 , +2877 , +-3027 , +-29891 , +-20821 , +26187 , +20679 , +24231 , +-6959 , +6437 , +-32513 , +-3283 , +-28607 , +23341 , +-17429 , +-14967 , +-2807 , +6251 , +-2437 , +-23205 , +8067 , +-24533 , +22785 , +-26881 , +30223 , +-8177 , +-13539 , +24039 , +11599 , +-31827 , +-12741 , +18285 , +5845 , +-12127 , +24203 , +20021 , +-15767 , +-26841 , +4721 , +11771 , +27061 , +3893 , +12429 , +32758 , +-24959 , +-1519 , +-3039 , +30623 , +13167 , +-8089 , +-18407 , +22557 , +22315 , +-15127 , +16501 , +14865 , +23085 , +9053 , +-9655 , +14831 , +5863 , +-27591 , +-30151 , +-22825 , +29827 , +-4927 , +355 , +18927 , +-999 , +13205 , +-28441 , +24119 , +-1943 , +16843 , +-11309 , +20715 , +6159 , +26769 , +18337 , +-7607 , +2623 , +-3273 , +-29909 , +-16645 , +3581 , +-8751 , +31787 , +10725 , +-5165 , +-26551 , +-5337 , +-12675 , +20997 , +11771 , +7669 , +21421 , +2899 , +-22067 , +-10069 , +-14567 , +2089 , +3779 , +9497 , +30989 , +-19877 , +-17127 , +-28477 , +24767 , +-31911 , +-25633 , +6487 , +-24265 , +21739 , +-8439 , +32675 , +18081 , +25705 , +-15855 , +14613 , +-11225 , +-32659 , +3843 , +-18521 , +-17853 , +22807 , +-13791 , +16481 , +19871 , +27317 , +-9741 , +2129 , +22119 , +31497 , +993 , +-12297 , +-12247 , +8443 , +5453 , +-19123 , +-3551 , +20175 , +-28375 , +29749 , +6169 , +22241 , +-17905 , +-12943 , +-23613 , +25307 , +20699 , +19489 , +28297 , +-10897 , +-8257 , +8631 , +-7187 , +-29043 , +-5667 , +20589 , +23645 , +-30181 , +-10395 , +-9149 , +-12151 , +-11989 , +-2525 , +14961 , +32061 , +13753 , +26265 , +-18591 , +-28735 , +-12063 , +19875 , +2859 , +29343 , +-17519 , +8825 , +-11131 , +-11507 , +-1593 , +29021 , +12867 , +-2371 , +4169 , +-5465 , +13129 , +31279 , +15577 , +5727 , +21769 , +3991 , +-14095 , +-31663 , +-14221 , +22059 , +28413 , +-12109 , +-19083 , +25083 , +18951 , +21805 , +13551 , +3151 , +18433 , +-8585 , +14631 , +-23431 , +-27029 , +15989 , +7373 , +6451 , +411 , +4809 , +4199 , +12911 , +-16793 , +-26641 , +7757 , +-3145 , +-27031 , +-7981 , +-731 , +-16643 , +-4435 , +19177 , +26833 , +20479 , +-24337 , +-31033 , +14839 , +10255 , +8021 , +3383 , +-3099 , +-32133 , +-9571 , +22745 , +285 , +26969 , +25313 , +-17355 , +22077 , +739 , +15047 , +11343 , +-19585 , +-20653 , +-10947 , +-10297 , +15539 , +3891 , +-19027 , +-7569 , +-24657 , +-30143 , +10937 , +7517 , +-32435 , +28341 , +-25741 , +5001 , +26851 , +16685 , +-8433 , +17129 , +-7627 , +21749 , +-26843 , +-9735 , +3577 , +17643 , +1121 , +-11801 , +22721 , +25805 , +19901 , +-17123 , +-28549 , +-15595 , +-19911 , +8799 , +4203 , +-11433 , +-25323 , +-17313 , +15257 , +22799 , +5257 , +30171 , +-553 , +-21763 , +31479 , +31279 , +-29909 , +-6397 , +6825 , +12913 , +5583 , +11887 , +29707 , +-30971 , +-19795 , +-32031 , +-14755 , +15805 , +9291 , +23455 , +-13589 , +-13211 , +-15285 , +-29847 , +6861 , +30693 , +17251 , +-28975 , +14099 , +6101 , +30675 , +-9447 , +-21621 , +22163 , +-3491 , +17801 , +17387 , +-14875 , +-28227 , +6975 , +-13423 , +-24575 , +-13149 , +405 , +20413 , +-29393 , +-5591 , +14061 , +23619 , +17893 , +-7989 , +19469 , +10945 , +26965 , +5087 , +-4611 , +15463 , +24713 , +-22641 , +-10159 , +22039 , +-23041 , +-23731 , +-30703 , +22319 , +18873 , +-25903 , +-14587 , +-7489 , +2523 , +5517 , +-22635 , +21305 , +-10297 , +27809 , +2331 , +-3923 , +8615 , +22365 , +15547 , +-7805 , +-18287 , +-8657 , +-7483 , +-12879 , +-21729 , +-5083 , +-26497 , +-21385 , +-4995 , +14043 , +-29049 , +-19315 , +8205 , +-19209 , +-24669 , +-6425 , +24951 , +23331 , +37 , +11237 , +24901 , +22407 , +7603 , +31503 , +-21003 , +-31817 , +-14419 , +1351 , +-32357 , +17719 , +14335 , +-9843 , +-5135 , +-27541 , +5239 , +-983 , +-20239 , +25103 , +163 , +26733 , +-19471 , +4921 , +-10205 , +-2839 , +18227 , +19391 , +10627 , +-28127 , +14339 , +-16573 , +2453 , +-9269 , +-4275 , +16541 , +-10423 , +29827 , +32441 , +-14375 , +2047 , +9215 , +-3525 , +-22869 , +-27545 , +12243 , +-16845 , +-23701 , +7635 , +-6503 , +-24067 , +12941 , +25623 , +-10821 , +-10477 , +-31081 , +9173 , +-24167 , +-7011 , +-20841 , +-2721 , +-1971 , +-4217 , +31521 , +17417 , +-26909 , +-8409 , +25023 , +-2553 , +-9979 , +11845 , +5875 , +-9027 , +-13501 , +-16199 , +5797 , +-31327 , +14275 , +-27255 , +-11487 , +-31861 , +-23181 , +-21133 , +-15729 , +-14197 , +-15921 , +-491 , +745 , +10317 , +11533 , +-13957 , +-13201 , +-25883 , +8413 , +12857 , +27307 , +22575 , +-5735 , +25603 , +-3107 , +25501 , +-22009 , +10441 , +30455 , +-24421 , +24965 , +16965 , +-10217 , +1889 , +-21299 , +24609 , +4989 , +4683 , +14629 , +2689 , +7941 , +-1105 , +25113 , +22821 , +8731 , +-7107 , +-3657 , +-12545 , +15415 , +31177 , +31551 , +12869 , +-28203 , +14005 , +18531 , +-18159 , +-10265 , +-11845 , +20727 , +25203 , +5589 , +-2489 , +13619 , +-11251 , +-10767 , +-8875 , +-19869 , +-27605 , +31855 , +-8507 , +-30177 , +-1959 , +-801 , +-27853 , +21515 , +-24459 , +-23009 , +-25007 , +12805 , +-10665 , +15583 , +-17991 , +-8477 , +-22053 , +7307 , +6223 , +4011 , +8575 , +-26933 , +-17903 , +-24763 , +22389 , +18811 , +-14223 , +31933 , +-9405 , +-23775 , +-27859 , +-11277 , +12251 , +19941 , +17833 , +26835 , +-16855 , +-18165 , +-4921 , +-25325 , +5173 , +30949 , +-6853 , +6249 , +-14153 , +-19115 , +19045 , +-29893 , +-9425 , +24255 , +32171 , +-31771 , +-6019 , +24955 , +24143 , +-12701 , +3069 , +-28707 , +18889 , +22165 , +-15081 , +31387 , +31897 , +1261 , +-18083 , +-4141 , +-5207 , +-29265 , +-21725 , +22651 , +11805 , +-21853 , +31891 , +-21411 , +-28755 , +-18609 , +-26807 , +13453 , +-7299 , +10165 , +-28565 , +-11169 , +12153 , +-11905 , +24893 , +4327 , +-14299 , +32703 , +3133 , +-28953 , +-2819 , +-14039 , +1719 , +16203 , +-19127 , +-24383 , +16097 , +-3547 , +-17039 , +-26333 , +5749 , +-30689 , +17633 , +21031 , +10687 , +31351 , +-17325 , +2347 , +15169 , +-3725 , +1201 , +-15423 , +7107 , +8543 , +15977 , +3305 , +-6417 , +9727 , +-14011 , +-17207 , +27747 , +5259 , +-29503 , +-15639 , +7507 , +31779 , +8429 , +27361 , +22169 , +3277 , +-4171 , +5023 , +24401 , +-25369 , +-6459 , +-12013 , +-3093 , +17697 , +-11807 , +-3987 , +-18993 , +-13575 , +-2639 , +-10543 , +22375 , +4523 , +811 , +12949 , +-9023 , +-13901 , +-1189 , +-2317 , +-14175 , +5817 , +7109 , +6725 , +-29155 , +25619 , +27445 , +-28997 , +7861 , +8123 , +-223 , +28053 , +-4891 , +-27711 , +-28293 , +-13099 , +15175 , +-27059 , +32515 , +14209 , +4131 , +18447 , +-14803 , +16467 , +-23161 , +-26315 , +7791 , +9969 , +-21019 , +-13071 , +-16357 , +1963 , +17701 , +-19617 , +-2891 , +-29265 , +-6587 , +-11767 , +2001 , +-24639 , +15715 , +13021 , +-20375 , +-141 , +11875 , +4513 , +-30033 , +21215 , +-6143 , +8171 , +-17811 , +-28453 , +23403 , +-26717 , +19927 , +18359 , +-4015 , +-11283 , +30949 , +-18835 , +-12919 , +-22357 , +16689 , +12385 , +-29151 , +12401 , +-19901 , +-15467 , +-17671 , +18681 , +12915 , +-26271 , +-7979 , +30245 , +4155 , +2475 , +-25861 , +25459 , +-8171 , +-10081 , +27211 , +-17429 , +-15667 , +-26903 , +-20265 , +-28503 , +11355 , +-25491 , +-22027 , +1475 , +17215 , +-27271 , +-18721 , +32209 , +28753 , +6791 , +-10299 , +-1061 , +14111 , +19047 , +-22165 , +-3121 , +-4409 , +-8437 , +-16583 , +16773 , +29511 , +-19287 , +-20005 , +32297 , +26457 , +15237 , +-17835 , +27709 , +7889 , +-13283 , +12697 , +-19955 , +-13973 , +21991 , +-13147 , +-25945 , +-2519 , +24711 , +-4843 , +5459 , +1831 , +-10359 , +-8641 , +-21617 , +-20997 , +-26473 , +22217 , +-23171 , +2175 , +15407 , +5825 , +5353 , +30269 , +4321 , +-1483 , +-335 , +-16849 , +-16125 , +22605 , +23247 , +-25299 , +-25883 , +1761 , +8897 , +21689 , +-3181 , +-9583 , +9863 , +21077 , +-25595 , +-1187 , +-8159 , +-30873 , +-7971 , +-6719 , +-643 , +-30333 , +3219 , +28741 , +-9997 , +4941 , +-7105 , +-21093 , +-26557 , +-565 , +5827 , +823 , +10751 , +19013 , +5765 , +19555 , +-9837 , +21647 , +21937 , +25053 , +-20043 , +-14863 , +23777 , +-8729 , +25941 , +24693 , +-19355 , +29927 , +-2261 , +15039 , +6125 , +-17799 , +-10349 , +-31639 , +-4915 , +-21747 , +-20191 , +27357 , +29353 , +-11783 , +-25727 , +13989 , +-22853 , +25619 , +-4863 , +14667 , +20865 , +9929 , +25211 , +-23641 , +14067 , +31677 , +-10793 , +-9017 , +-7869 , +26841 , +15107 , +28981 , +-491 , +-2847 , +7007 , +13023 , +-14803 , +-20327 , +18373 , +-24225 , +26545 , +-15277 , +-1803 , +13027 , +-5409 , +23051 , +5783 , +-27271 , +-30403 , +-17417 , +-9051 , +-32529 , +-4255 , +-81 , +-26767 , +12581 , +24855 , +-27211 , +-20965 , +8423 , +14375 , +-27243 , +-19589 , +7497 , +-19067 , +7805 , +-19025 , +18805 , +-25333 , +-23471 , +-31745 , +11025 , +-27725 , +-32441 , +9059 , +22285 , +-18355 , +-23553 , +10609 , +-10503 , +28345 , +-19947 , +13789 , +-8475 , +-10855 , +30531 , +17003 , +-5191 , +-8559 , +-1807 , +365 , +-7675 , +-32513 , +1613 , +691 , +17757 , +-219 , +-25367 , +-10485 , +8245 , +-18953 , +-1585 , +-5581 , +-19405 , +28481 , +-20713 , +19287 , +-29943 , +-20889 , +-27131 , +7169 , +-47 , +-4197 , +-2659 , +-8807 , +-10021 , +20887 , +-19017 , +21847 , +2581 , +-24111 , +-2399 , +16063 , +14287 , +17207 , +-6865 , +-31591 , +4645 , +-6297 , +9047 , +14435 , +8397 , +-28061 , +-25277 , +81 , +6003 , +-7987 , +8949 , +13251 , +19083 , +2205 , +-25009 , +24119 , +23731 , +-29609 , +15805 , +24775 , +-17279 , +6347 , +27449 , +-5597 , +2789 , +-31419 , +-6153 , +32001 , +501 , +28227 , +-7059 , +-17125 , +-2993 , +25273 , +27893 , +15013 , +31981 , +7101 , +735 , +29769 , +30593 , +-18747 , +-17905 , +18327 , +-9919 , +27227 , +-19699 , +-30717 , +-32177 , +-21157 , +18853 , +-2981 , +-24697 , +18599 , +-12293 , +17089 , +-19237 , +19293 , +11811 , +31523 , +-6105 , +22931 , +15927 , +22571 , +-23413 , +19853 , +15605 , +-6459 , +11847 , +-23689 , +9939 , +7179 , +16139 , +-22631 , +22935 , +-26175 , +17115 , +-8427 , +21103 , +22867 , +19799 , +-23783 , +-8055 , +30017 , +24479 , +26265 , +-23507 , +-14047 , +5799 , +-24951 , +12883 , +-24557 , +23061 , +-15213 , +-19269 , +10681 , +9097 , +27727 , +24197 , +-4689 , +-2425 , +-7427 , +-29363 , +-2683 , +8389 , +20923 , +-4421 , +-6859 , +23305 , +-9671 , +-32095 , +-17895 , +-7561 , +-23041 , +-11885 , +26731 , +-23947 , +24593 , +12285 , +3891 , +-30981 , +4411 , +26039 , +-1341 , +-28819 , +-10569 , +-28119 , +11701 , +-17927 , +27507 , +-23337 , +-22443 , +24415 , +-1085 , +17023 , +9897 , +5981 , +15257 , +28333 , +-29473 , +-17029 , +14137 , +-11815 , +-17851 , +-20895 , +-10627 , +-3079 , +-1335 , +-10821 , +-30079 , +17307 , +-12569 , +-23421 , +7649 , +16771 , +16931 , +-30747 , +8045 , +-22347 , +-30707 , +-1909 , +-8343 , +-5349 , +6055 , +-17793 , +30521 , +-9577 , +-665 , +25987 , +-11357 , +-10595 , +-25679 , +-12831 , +14723 , +22083 , +-28217 , +26055 , +15619 , +9959 , +331 , +12067 , +-23721 , +14137 , +-5589 , +22003 , +9963 , +18145 , +-10973 , +2855 , +-27097 , +21129 , +-31565 , +-18449 , +17565 , +5247 , +-7021 , +8601 , +18123 , +29127 , +-4177 , +-27161 , +28745 , +11193 , +-15205 , +-18453 , +-29561 , +-20977 , +-24433 , +1367 , +-13821 , +20877 , +-1825 , +-21415 , +-12285 , +-5369 , +27377 , +-13831 , +30411 , +-249 , +-17741 , +-22299 , +-26029 , +29147 , +-26727 , +6357 , +-125 , +3125 , +24589 , +30297 , +-15379 , +-21441 , +-25743 , +31545 , +20477 , +31537 , +25227 , +28489 , +17335 , +-143 , +28301 , +-11841 , +21995 , +25373 , +1657 , +4879 , +-25097 , +-14541 , +-31959 , +30531 , +16367 , +-1247 , +-24125 , +-18225 , +-3231 , +28887 , +23723 , +-31763 , +23691 , +-14997 , +-31999 , +25203 , +-20467 , +-18899 , +-14693 , +12331 , +-26323 , +-9671 , +30837 , +-20565 , +-9601 , +-1901 , +-21585 , +22451 , +-24275 , +21191 , +-2299 , +-3849 , +673 , +-17425 , +-29501 , +7301 , +-25401 , +-11169 , +-7871 , +23189 , +-12095 , +16813 , +-26663 , +-22041 , +-28639 , +15187 , +-4511 , +22419 , +13469 , +17347 , +24351 , +5993 , +23113 , +26107 , +-20155 , +-829 , +13397 , +-12373 , +12263 , +27617 , +21559 , +8121 , +16245 , +-25665 , +23409 , +16747 , +2479 , +-16275 , +-28733 , +11251 , +30751 , +30185 , +-13851 , +24207 , +13591 , +-31885 , +-18759 , +28957 , +-5347 , +-28819 , +-7413 , +-28369 , +31469 , +-9307 , +-30269 , +17325 , +24557 , +-24003 , +-25437 , +17123 , +-1243 , +11001 , +-135 , +-11997 , +-839 , +12565 , +28119 , +22485 , +-23589 , +-20053 , +853 , +-21747 , +3405 , +-17801 , +-8645 , +-13907 , +18513 , +20803 , +-11071 , +29175 , +27173 , +2991 , +-19257 , +25249 , +22517 , +28561 , +1545 , +-24455 , +32605 , +-19507 , +-14627 , +-26511 , +13657 , +-1623 , +7011 , +30265 , +-3137 , +-26963 , +26437 , +-30883 , +11577 , +-30993 , +-13843 , +731 , +-4165 , +-24589 , +30005 , +3381 , +3451 , +-25597 , +-10581 , +20753 , +1127 , +-27129 , +2881 , +1101 , +23591 , +3545 , +-27253 , +-20075 , +-19835 , +3359 , +-12687 , +-24959 , +11891 , +-31579 , +2151 , +9767 , +-28293 , +31285 , +-8919 , +-8139 , +-24645 , +7911 , +-25097 , +-4977 , +5721 , +26121 , +24127 , +15193 , +-6015 , +13415 , +-28443 , +10653 , +-1321 , +-16343 , +-20501 , +19039 , +5489 , +14641 , +-6469 , +-19411 , +17493 , +20967 , +14031 , +-21693 , +24161 , +-16229 , +3827 , +29 , +-5415 , +20829 , +-13067 , +-1395 , +7499 , +-24503 , +8679 , +10583 , +8213 , +5229 , +-12083 , +-4537 , +25941 , +13083 , +-16417 , +7883 , +13921 , +-7229 , +-11213 , +-28409 , +14791 , +-17339 , +-28665 , +-4751 , +10171 , +-4655 , +-5271 , +-25367 , +25879 , +-5571 , +24439 , +11085 , +-17205 , +22995 , +-25577 , +-2413 , +-4129 , +31167 , +-8149 , +-32155 , +21473 , +31437 , +27727 , +18481 , +14309 , +-1837 , +2057 , +23497 , +18423 , +8837 , +4491 , +-17289 , +-22763 , +-22071 , +4063 , +-21867 , +-2135 , +5265 , +16301 , +-9821 , +2689 , +-31177 , +4709 , +-10523 , +27713 , +-26293 , +6143 , +31865 , +-30363 , +25083 , +19251 , +-14105 , +-24401 , +12503 , +14385 , +-3259 , +15397 , +11837 , +-2603 , +5065 , +26761 , +26143 , +26977 , +14559 , +25421 , +23659 , +-13131 , +16579 , +-2289 , +-15915 , +-4341 , +20383 , +16017 , +24891 , +10281 , +14873 , +1579 , +-8843 , +30237 , +-17299 , +-31797 , +22445 , +-17039 , +-10737 , +-25239 , +-27073 , +-23577 , +8629 , +30209 , +-15353 , +-591 , +-32263 , +30981 , +24641 , +17701 , +-1427 , +-25507 , +30425 , +5367 , +3377 , +4317 , +-18099 , +7413 , +29967 , +6453 , +-28679 , +-30407 , +-27629 , +16247 , +-17411 , +21475 , +28321 , +-24317 , +-24187 , +31059 , +-29939 , +-30459 , +-11597 , +-31007 , +-29263 , +4459 , +-3355 , +31757 , +-5749 , +607 , +-30053 , +30279 , +32081 , +-22471 , +-7225 , +7957 , +29961 , +-10239 , +-31063 , +21721 , +18465 , +-9631 , +28451 , +1535 , +11271 , +29975 , +-28011 , +-18753 , +-11451 , +-13571 , +-12747 , +-22197 , +-12017 , +19057 , +-10781 , +8331 , +31079 , +25171 , +15237 , +-19109 , +-27217 , +13699 , +9949 , +13881 , +-14913 , +1229 , +-10781 , +2433 , +-6783 , +-30865 , +32153 , +-30169 , +20231 , +-5631 , +-23707 , +22255 , +20773 , +-21507 , +-30995 , +3105 , +-19833 , +5033 , +-19351 , +24517 , +-26299 , +28827 , +22399 , +6233 , +-20727 , +-6999 , +26263 , +-10743 , +-9837 , +-5277 , +16057 , +9833 , +24545 , +22541 , +-14371 , +-9561 , +-11323 , +531 , +-17971 , +6225 , +-26639 , +-10233 , +6513 , +7287 , +23197 , +-28397 , +-31051 , +10619 , +23703 , +-19211 , +29397 , +-26827 , +-8989 , +12917 , +-10441 , +32185 , +-32571 , +15451 , +-31541 , +-3449 , +4199 , +-23313 , +-23589 , +20551 , +24557 , +28645 , +31845 , +-32515 , +-17147 , +-11553 , +7925 , +-15677 , +-18163 , +23651 , +1529 , +-8439 , +-22629 , +31055 , +18335 , +19515 , +-22105 , +4309 , +28709 , +12811 , +-25325 , +28399 , +-25413 , +-14307 , +-14131 , +13661 , +-4399 , +1863 , +-25249 , +-29931 , +-4107 , +9541 , +25103 , +16965 , +-469 , +-11539 , +9843 , +11459 , +22721 , +-19213 , +-12149 , +22277 , +-6741 , +3859 , +-24747 , +24991 , +18263 , +6609 , +-1561 , +-20171 , +23309 , +-1357 , +-7413 , +-21255 , +-18501 , +-10509 , +-5809 , +-15461 , +17753 , +-1865 , +-5211 , +28361 , +-31559 , +32465 , +-30089 , +-4831 , +-24609 , +-28949 , +-25281 , +-5457 , +-9503 , +-32181 , +-31587 , +-12325 , +32053 , +1285 , +-20233 , +-4367 , +-13423 , +-24657 , +13701 , +18439 , +10809 , +-23647 , +-16393 , +7041 , +-25 , +-3669 , +-13187 , +775 , +28947 , +-27833 , +28271 , +-14089 , +-29741 , +-24997 , +-31401 , +-18843 , +-975 , +23397 , +-18793 , +-28783 , +-7931 , +9791 , +883 , +-2343 , +-9909 , +335 , +21425 , +28215 , +-7687 , +21315 , +-13133 , +-20677 , +7261 , +-14525 , +19719 , +-28293 , +5361 , +-14411 , +-7035 , +14225 , +-23887 , +-29847 , +-24345 , +-17775 , +-2313 , +11603 , +-31009 , +3077 , +-2605 , +-14645 , +4013 , +18011 , +28383 , +1085 , +827 , +9195 , +20123 , +11363 , +1719 , +-11167 , +24643 , +4605 , +-18527 , +-5951 , +-18393 , +-6133 , +-21651 , +-29229 , +24197 , +28803 , +11161 , +-13017 , +21215 , +32139 , +1603 , +3207 , +32723 , +15659 , +19261 , +-31763 , +-18575 , +18319 , +19887 , +-7683 , +20507 , +-6217 , +-15833 , +-10493 , +31189 , +-26961 , +20787 , +-16801 , +-7141 , +8525 , +30333 , +7815 , +-13241 , +28775 , +1113 , +14203 , +3159 , +27523 , +9193 , +22461 , +16975 , +-4579 , +10671 , +12233 , +-22507 , +18257 , +5795 , +-9201 , +-19523 , +15391 , +7631 , +-8857 , +6253 , +1049 , +1637 , +-18415 , +16295 , +14499 , +-15781 , +28961 , +-11467 , +11941 , +4471 , +-23937 , +28525 , +-19769 , +-30471 , +23907 , +5651 , +-24537 , +-10333 , +-27841 , +31155 , +18831 , +-24997 , +15685 , +-18063 , +11575 , +-19137 , +-1447 , +-23191 , +-5397 , +13627 , +23433 , +9089 , +-2857 , +7719 , +-26875 , +-13115 , +-3407 , +-3751 , +-9835 , +23359 , +20339 , +6337 , +-4455 , +73 , +-5731 , +29311 , +30329 , +15213 , +24027 , +-9991 , +25503 , +18871 , +-7085 , +-133 , +-2577 , +-14955 , +14411 , +31555 , +-4929 , +-28895 , +-32155 , +20773 , +10067 , +-27381 , +-17055 , +-8291 , +27597 , +-27171 , +-29369 , +32099 , +-29523 , +29161 , +297 , +-23413 , +-23355 , +9611 , +14165 , +537 , +-24143 , +1041 , +23571 , +16921 , +-11059 , +19215 , +-1321 , +-4039 , +-15693 , +-22991 , +6653 , +17631 , +-5843 , +-17511 , +6395 , +14013 , +-19533 , +22711 , +-14045 , +-22283 , +22107 , +22433 , +-18219 , +3493 , +-14503 , +-11037 , +10549 , +21763 , +-28941 , +-12829 , +-22941 , +-32519 , +-23049 , +-16461 , +-17857 , +-19147 , +6839 , +24167 , +-20083 , +7113 , +-19325 , +-779 , +-5187 , +30273 , +19861 , +-17025 , +-21219 , +-19663 , +7067 , +8761 , +-5229 , +24673 , +-24929 , +5821 , +3533 , +20815 , +28297 , +2525 , +5383 , +21083 , +-24813 , +12289 , +10551 , +16461 , +-3523 , +-31231 , +-51 , +23677 , +-28335 , +-21389 , +5347 , +13659 , +-31667 , +13201 , +12029 , +-1127 , +-24601 , +28545 , +9533 , +-25677 , +8699 , +27967 , +24603 , +29711 , +-19319 , +8163 , +3229 , +-109 , +3885 , +24199 , +31247 , +19649 , +-4333 , +-13675 , +-26049 , +-26297 , +-25229 , +13993 , +7211 , +-5601 , +-17273 , +-23071 , +6473 , +-2017 , +-27899 , +31669 , +-13013 , +18713 , +-29165 , +-2989 , +20425 , +-12943 , +12739 , +32121 , +-13779 , +-9679 , +12297 , +1987 , +7605 , +-10335 , +-8653 , +-5999 , +30143 , +31847 , +-16155 , +25681 , +-17429 , +-4841 , +26249 , +31071 , +26319 , +-26549 , +18507 , +865 , +-25809 , +10051 , +-5737 , +-12527 , +6071 , +23281 , +-4601 , +-18781 , +-7375 , +11677 , +24033 , +24215 , +13627 , +4341 , +-12019 , +-21745 , +-28283 , +-24409 , +-18289 , +-31317 , +-29307 , +-24195 , +32377 , +3041 , +14507 , +-23317 , +-19347 , +-16943 , +-24797 , +10547 , +2189 , +-14941 , +24327 , +-29193 , +14583 , +-4267 , +-14317 , +-19121 , +-16969 , +26913 , +32231 , +-22171 , +24905 , +-7095 , +5301 , +7821 , +32649 , +11891 , +-24449 , +10711 , +9005 , +-9339 , +-20783 , +1073 , +-17985 , +6135 , +-23823 , +12787 , +-27119 , +15279 , +-4965 , +-6393 , +-1731 , +13655 , +4415 , +-147 , +-9711 , +26161 , +-83 , +25701 , +8975 , +1661 , +-22953 , +13819 , +-24857 , +-21953 , +17415 , +-28377 , +19305 , +-351 , +27409 , +19039 , +19199 , +22479 , +12053 , +29875 , +11429 , +10053 , +29995 , +3427 , +-15769 , +-3415 , +-8537 , +-23563 , +15945 , +-7379 , +17991 , +22229 , +-12843 , +-31401 , +18421 , +-927 , +27649 , +-11929 , +-13577 , +-12145 , +8621 , +5161 , +1701 , +32501 , +27807 , +-12213 , +-1619 , +-7823 , +1269 , +12347 , +-13377 , +19253 , +-18145 , +8311 , +4553 , +-18331 , +-26533 , +-21905 , +27827 , +-17873 , +9125 , +-22571 , +31377 , +30557 , +-17097 , +26227 , +-28067 , +-26251 , +3709 , +21647 , +16945 , +32335 , +-25461 , +19895 , +2045 , +-31193 , +17179 , +-24545 , +15553 , +-10691 , +-12803 , +25205 , +-21953 , +26599 , +26905 , +12865 , +-15555 , +-17361 , +7901 , +-3405 , +-2509 , +3043 , +7485 , +-23553 , +4747 , +19511 , +-1755 , +-5321 , +14419 , +-8239 , +-22415 , +25253 , +19065 , +19563 , +27249 , +19097 , +23425 , +-13077 , +22219 , +-19765 , +3261 , +6129 , +-13559 , +-19407 , +22535 , +13047 , +28293 , +-11439 , +-17419 , +-22035 , +1249 , +8993 , +17045 , +835 , +-14589 , +16475 , +23205 , +-14191 , +31373 , +-17067 , +-1209 , +-1117 , +-47 , +5721 , +2621 , +20503 , +-29107 , +-14721 , +31903 , +371 , +22435 , +-27389 , +10769 , +-25155 , +-14069 , +-19685 , +-13693 , +-25449 , +9043 , +-15787 , +5729 , +6863 , +-24237 , +23403 , +-32437 , +-28033 , +-6937 , +11673 , +-30895 , +-6243 , +-7583 , +20091 , +1195 , +-24293 , +649 , +-11685 , +-28691 , +-22915 , +-19695 , +17691 , +20167 , +23021 , +7567 , +7029 , +15663 , +26323 , +15599 , +-19225 , +24361 , +7415 , +2419 , +1537 , +-11023 , +-20473 , +-3291 , +-31933 , +18881 , +13253 , +25303 , +25707 , +-19203 , +-21367 , +31121 , +-10153 , +-6675 , +3181 , +-14709 , +16733 , +-11781 , +29907 , +11181 , +4633 , +7529 , +-27509 , +-22399 , +25297 , +-10619 , +31331 , +17317 , +-10429 , +-9373 , +-19387 , +-13613 , +-4861 , +-7657 , +4805 , +-24249 , +19029 , +-25749 , +-5819 , +21703 , +9597 , +-6119 , +8839 , +12555 , +23709 , +-26499 , +451 , +-30265 , +22027 , +-20779 , +-6075 , +-3311 , +16683 , +-25609 , +-2181 , +8297 , +-12347 , +28291 , +-6245 , +-24031 , +-35 , +27813 , +-5455 , +14693 , +3595 , +4163 , +-3017 , +-1367 , +10323 , +-8775 , +15665 , +-2397 , +-1663 , +3349 , +23751 , +-24125 , +-23301 , +32203 , +-12973 , +-19923 , +19225 , +-4885 , +13827 , +-21459 , +-20989 , +-6689 , +20719 , +-10955 , +3845 , +26011 , +-14931 , +-15025 , +-9111 , +-22435 , +-12179 , +20249 , +18377 , +6625 , +3471 , +-2501 , +23791 , +-8167 , +16825 , +-21411 , +-20183 , +-1949 , +30327 , +3237 , +17183 , +24393 , +17225 , +-12885 , +-23757 , +15023 , +-25793 , +-24079 , +-945 , +32401 , +-2281 , +16089 , +5439 , +1083 , +13257 , +-15837 , +-7531 , +-29699 , +-599 , +11743 , +-16147 , +-24219 , +8187 , +13035 , +-4137 , +-9733 , +-28405 , +485 , +25889 , +26225 , +-27959 , +23203 , +-28483 , +28261 , +-16427 , +-28107 , +10509 , +11919 , +23849 , +-14517 , +-26691 , +20863 , +-14303 , +-703 , +7973 , +31443 , +22813 , +21897 , +20497 , +31985 , +-28013 , +8103 , +-6105 , +12605 , +-2899 , +-2131 , +-20295 , +27343 , +19801 , +-21717 , +30237 , +-1103 , +-8981 , +7341 , +-20605 , +17553 , +10025 , +-8777 , +-4269 , +18171 , +-14097 , +-18643 , +-19455 , +-19945 , +10813 , +-10145 , +-20125 , +-7723 , +25817 , +-7053 , +10893 , +18607 , +14173 , +-27039 , +29735 , +15321 , +23763 , +13165 , +14153 , +-26105 , +8403 , +-31715 , +-29493 , +17551 , +-30705 , +-29773 , +-30431 , +-7367 , +-6795 , +-18909 , +20665 , +-5531 , +13249 , +-19321 , +19657 , +23497 , +2975 , +-16349 , +-26453 , +14767 , +-29137 , +31695 , +16313 , +9377 , +7221 , +11259 , +25503 , +7083 , +12703 , +32029 , +-7371 , +-10479 , +15783 , +-28499 , +-26151 , +-19071 , +-12445 , +-30555 , +-12473 , +-19503 , +-4377 , +18791 , +-4115 , +26427 , +-1325 , +-21943 , +9669 , +29191 , +-7567 , +-13187 , +-5715 , +27345 , +5199 , +-12143 , +9541 , +-20933 , +-1715 , +-23961 , +-709 , +4897 , +21569 , +5035 , +-9171 , +-1699 , +24069 , +-821 , +-10757 , +-21775 , +-2535 , +-25487 , +-1115 , +-30775 , +-16465 , +-4745 , +-18529 , +-3091 , +-31919 , +11105 , +-13661 , +-32705 , +-21271 , +15707 , +283 , +17837 , +15975 , +16293 , +14561 , +-5397 , +3797 , +-7275 , +-12371 , +19629 , +-21017 , +-8693 , +4577 , +16475 , +-15329 , +7271 , +-15905 , +26963 , +18271 , +-2039 , +20461 , +-26483 , +23553 , +8255 , +-9601 , +-20755 , +14955 , +29379 , +-28905 , +31201 , +-3789 , +31407 , +-31839 , +-32079 , +23465 , +-12803 , +-24515 , +18465 , +9467 , +373 , +-20057 , +-9541 , +12227 , +27433 , +15361 , +21373 , +14885 , +27505 , +9781 , +7445 , +5735 , +29789 , +-10805 , +-30831 , +20487 , +-30799 , +-11459 , +-24921 , +-27309 , +25435 , +-28977 , +-17825 , +-17025 , +5227 , +24049 , +-15795 , +-15549 , +10377 , +18699 , +-25777 , +-29713 , +13813 , +-15915 , +-18497 , +-11517 , +-3593 , +-9667 , +16947 , +4677 , +-29223 , +5037 , +-9561 , +-16799 , +-28067 , +24305 , +24133 , +-20489 , +-3651 , +25737 , +-20079 , +4407 , +-30693 , +-21123 , +1319 , +-22529 , +-15751 , +-15171 , +-29455 , +-11161 , +-23495 , +-5897 , +8675 , +7139 , +-7415 , +26347 , +-14807 , +-26407 , +20837 , +13381 , +-31767 , +9905 , +20365 , +-7433 , +-24965 , +-23941 , +31481 , +-31471 , +-29163 , +6141 , +21587 , +-26349 , +-16875 , +13129 , +5107 , +-26931 , +-31319 , +-12573 , +25807 , +13491 , +21263 , +-2491 , +15867 , +-589 , +-32435 , +13575 , +-28003 , +20373 , +-12187 , +-30093 , +4195 , +22985 , +-2029 , +-9833 , +-23425 , +13507 , +19711 , +11751 , +-225 , +-22057 , +-3979 , +-21431 , +-12957 , +-15477 , +-32089 , +-30535 , +-7725 , +-16783 , +-12459 , +-10151 , +859 , +29313 , +27925 , +-26613 , +-25917 , +-13071 , +-14595 , +-16503 , +-2397 , +29319 , +-30489 , +-18173 , +24031 , +8825 , +-6625 , +5417 , +-22369 , +-3647 , +-19805 , +-11309 , +-26685 , +-2313 , +-14637 , +6413 , +-23845 , +32417 , +-23115 , +-22859 , +29865 , +24601 , +-8803 , +-3439 , +-12789 , +-29989 , +7029 , +12521 , +1917 , +25693 , +26725 , +11163 , +-5877 , +3695 , +-30179 , +15799 , +4301 , +11783 , +-641 , +19351 , +-24611 , +19107 , +-31785 , +3953 , +26065 , +24093 , +-17759 , +-28039 , +17071 , +-21243 , +-19025 , +10863 , +-2201 , +32631 , +5103 , +-11329 , +7377 , +-11665 , +-31077 , +16401 , +31003 , +-26197 , +17141 , +29037 , +27587 , +-22019 , +22137 , +14785 , +-22503 , +-7137 , +21919 , +30479 , +-2519 , +-18411 , +23821 , +25585 , +12859 , +-26371 , +-8883 , +-11077 , +17099 , +31081 , +10503 , +-18155 , +15615 , +-6089 , +15805 , +-17907 , +28573 , +-6675 , +-16645 , +19635 , +-29555 , +2697 , +-25575 , +4397 , +-22337 , +5087 , +22633 , +-10671 , +19125 , +29811 , +28149 , +6593 , +16241 , +-1335 , +-15693 , +23681 , +28143 , +10565 , +-22457 , +9221 , +24863 , +22137 , +24107 , +-39 , +-16293 , +11787 , +-29067 , +27569 , +28255 , +-22011 , +-17147 , +-6659 , +-31039 , +7333 , +8517 , +4875 , +-3605 , +25289 , +-7587 , +17557 , +-14447 , +-10571 , +11755 , +15841 , +14247 , +7025 , +8507 , +-29615 , +12769 , +22691 , +-767 , +19589 , +-31841 , +-281 , +-25717 , +-19477 , +-23439 , +-21339 , +-24185 , +14039 , +-5881 , +19301 , +24869 , +-23775 , +21675 , +-589 , +-6169 , +1849 , +-16071 , +-2711 , +11975 , +-16961 , +-27237 , +-13679 , +-6923 , +30105 , +-15685 , +27321 , +-13037 , +-29037 , +16125 , +14539 , +9447 , +-23955 , +-18375 , +30053 , +3993 , +-28039 , +-19409 , +-30799 , +31331 , +-3665 , +-10365 , +16067 , +29647 , +9039 , +-29897 , +-23711 , +28017 , +1511 , +-18279 , +29295 , +24595 , +-32003 , +-11321 , +-10309 , +19073 , +-9441 , +-4963 , +-32427 , +683 , +1655 , +-459 , +-23701 , +-11923 , +491 , +13531 , +1185 , +-12093 , +24755 , +25219 , +-21789 , +-31621 , +-1429 , +22983 , +16585 , +-23181 , +3507 , +26455 , +-13473 , +-26801 , +-20669 , +-24069 , +-14197 , +-32587 , +-8831 , +18689 , +19937 , +32255 , +4255 , +-5827 , +16371 , +-6541 , +-24789 , +-32647 , +14899 , +7171 , +-12495 , +22391 , +16201 , +-8839 , +-5173 , +-13729 , +-13847 , +-27843 , +14139 , +-18497 , +22057 , +-29059 , +4483 , +-12805 , +-1187 , +-19723 , +11135 , +28493 , +11887 , +-31971 , +7801 , +25659 , +17585 , +1761 , +16457 , +5257 , +-12479 , +-31523 , +3041 , +32441 , +26323 , +-31209 , +-2449 , +-23043 , +17 , +7213 , +2289 , +-20813 , +24691 , +-7655 , +5709 , +24925 , +-13421 , +-20639 , +-6677 , +19475 , +-32501 , +30163 , +10953 , +14979 , +8903 , +16825 , +-24809 , +15461 , +-25633 , +-11115 , +7247 , +-3467 , +-24589 , +-11689 , +1991 , +23013 , +23291 , +-1767 , +-5165 , +-12707 , +27047 , +23373 , +-27309 , +31343 , +-19921 , +5249 , +-29229 , +-4465 , +13751 , +28813 , +18973 , +5773 , +29209 , +-683 , +-6829 , +17801 , +27717 , +32505 , +-16245 , +-28561 , +-1255 , +16011 , +-8481 , +12013 , +27319 , +-21677 , +22031 , +6891 , +4187 , +-14727 , +-21617 , +-22907 , +-6471 , +20809 , +30243 , +16515 , +-13615 , +13795 , +7163 , +8009 , +28999 , +8819 , +1351 , +2651 , +-21449 , +-12559 , +6987 , +-1455 , +6555 , +-6835 , +-5117 , +-14521 , +-11761 , +1077 , +18989 , +-25117 , +12349 , +-11203 , +-15895 , +29373 , +18595 , +-22615 , +-17967 , +11369 , +10747 , +-25453 , +-26479 , +-17443 , +32263 , +-18001 , +-14601 , +-9353 , +-23825 , +-639 , +-6501 , +-21395 , +-10987 , +-10223 , +5349 , +-5429 , +-32395 , +1831 , +-27983 , +-4127 , +22641 , +19713 , +-22429 , +15173 , +14645 , +-1655 , +7811 , +-17845 , +-29307 , +-16873 , +8907 , +-31243 , +11803 , +-15465 , +-3639 , +20335 , +26497 , +31573 , +7415 , +13067 , +14177 , +8743 , +-15033 , +10675 , +23141 , +28199 , +-23989 , +-12059 , +17029 , +24309 , +11715 , +-16087 , +-29201 , +-22433 , +-13385 , +11015 , +5711 , +-20569 , +18189 , +-3451 , +12461 , +-27853 , +31403 , +283 , +13769 , +13515 , +32513 , +1577 , +-5393 , +-16825 , +13353 , +24053 , +-7345 , +-26411 , +-32643 , +22301 , +29139 , +20133 , +7089 , +-29037 , +17277 , +20263 , +15979 , +-26095 , +14905 , +3519 , +3667 , +-18155 , +-24517 , +29443 , +7867 , +-15269 , +19405 , +6255 , +-8797 , +5067 , +-13387 , +18073 , +17765 , +-27909 , +13315 , +11765 , +-21827 , +-17371 , +-23705 , +20989 , +-149 , +-20069 , +6419 , +-24837 , +24903 , +11713 , +-19701 , +8751 , +19927 , +-32377 , +-4865 , +-9069 , +21101 , +22881 , +-2135 , +-22511 , +-28489 , +-32581 , +-16233 , +-22727 , +-4125 , +23539 , +-15727 , +14197 , +21031 , +20693 , +13929 , +-8757 , +-22811 , +-10869 , +-17321 , +9741 , +12611 , +24091 , +5585 , +-4971 , +-9413 , +-8095 , +2013 , +2683 , +-4807 , +9855 , +-525 , +-9143 , +561 , +-22565 , +-31415 , +-25791 , +-28617 , +8343 , +14519 , +257 , +-8807 , +-24697 , +13577 , +11725 , +-17803 , +17061 , +-21037 , +18749 , +-10543 , +23061 , +-17709 , +-10889 , +3381 , +10639 , +-2623 , +11495 , +31167 , +99 , +167 , +8827 , +-19009 , +-8219 , +-29503 , +15443 , +4047 , +26739 , +-1589 , +-32513 , +6245 , +17631 , +9697 , +20279 , +23285 , +-13197 , +-31281 , +14353 , +-25727 , +4957 , +7665 , +21433 , +28847 , +8629 , +29577 , +2217 , +-28049 , +-30489 , +3727 , +-17057 , +-19197 , +4021 , +-23529 , +27807 , +18587 , +-21331 , +-32485 , +-27617 , +-2695 , +-30951 , +19937 , +30143 , +11383 , +13955 , +-15935 , +9037 , +-23509 , +-1879 , +24467 , +19635 , +6777 , +5615 , +-11659 , +18607 , +12977 , +11355 , +809 , +20499 , +-14301 , +-26349 , +32239 , +25455 , +-29389 , +-18357 , +16605 , +-11431 , +20221 , +13251 , +-30029 , +-7395 , +-19105 , +6075 , +-15817 , +32239 , +-10343 , +-6541 , +3595 , +30385 , +32101 , +25113 , +-19193 , +18977 , +25743 , +17733 , +-8437 , +-9327 , +25351 , +-24073 , +-12701 , +9253 , +-17025 , +7939 , +10639 , +19589 , +-30075 , +-13295 , +28073 , +10521 , +31251 , +-15337 , +8501 , +-28483 , +-9809 , +22091 , +-8321 , +-31231 , +11515 , +-4705 , +-11155 , +-21803 , +13017 , +28339 , +-16169 , +-2357 , +-20751 , +17493 , +8039 , +10189 , +-12321 , +-11655 , +-32283 , +-6831 , +-30283 , +-30811 , +-16611 , +3601 , +-17115 , +17657 , +2347 , +10315 , +-31985 , +21661 , +-31659 , +27761 , +29851 , +-22855 , +30315 , +25187 , +18385 , +-29451 , +-22889 , +-30425 , +-26447 , +-21403 , +1463 , +291 , +14033 , +24077 , +14133 , +-20267 , +-12439 , +13775 , +4709 , +-9211 , +19443 , +-6165 , +-19379 , +-23165 , +-17083 , +17651 , +14867 , +29539 , +11039 , +-31679 , +-17473 , +-21081 , +8273 , +-27403 , +-24665 , +-12411 , +19269 , +-21145 , +-8647 , +17175 , +2851 , +-11999 , +20051 , +-105 , +16735 , +-31397 , +-28119 , +25109 , +16343 , +27627 , +-17267 , +14513 , +11115 , +-827 , +18125 , +30797 , +-21741 , +5615 , +28433 , +-27441 , +15221 , +-26121 , +-26841 , +-3121 , +-253 , +-11025 , +-17433 , +29143 , +25227 , +-8219 , +-25341 , +29205 , +28251 , +-17705 , +-21153 , +28823 , +7113 , +21809 , +25585 , +-28927 , +-30887 , +15549 , +1295 , +5061 , +22349 , +11043 , +31821 , +21469 , +11969 , +10715 , +24277 , +-257 , +-31425 , +-31573 , +-20933 , +18011 , +-17697 , +17045 , +29657 , +-10805 , +-16173 , +23903 , +-13147 , +6035 , +11913 , +28535 , +32137 , +-17771 , +6977 , +4223 , +-22467 , +-3319 , +-27619 , +-26571 , +-18277 , +28083 , +1735 , +32758 , +8829 , +28069 , +30845 , +6827 , +2063 , +3173 , +-7761 , +-9393 , +24747 , +5305 , +-31209 , +-7717 , +-18387 , +28623 , +-24243 , +1731 , +7887 , +-25345 , +16353 , +7409 , +24959 , +11263 , +-25355 , +-24011 , +8891 , +-20071 , +-9131 , +-27069 , +-5151 , +12011 , +30987 , +-20439 , +-12531 , +25361 , +16505 , +-21941 , +-20113 , +-145 , +12789 , +-9007 , +-10713 , +13913 , +6875 , +-8531 , +-15983 , +-25517 , +18215 , +25861 , +3377 , +-11319 , +7821 , +6453 , +17397 , +-1211 , +1559 , +-25277 , +24351 , +22053 , +24111 , +30421 , +-1133 , +10201 , +-2745 , +6323 , +-8275 , +14741 , +-14621 , +-15699 , +-5721 , +655 , +24383 , +28709 , +-419 , +-5459 , +-17575 , +-29443 , +4281 , +-24631 , +-623 , +-22255 , +-9861 , +-2717 , +-12605 , +-7631 , +22425 , +18137 , +-15403 , +15511 , +-20201 , +-11235 , +-24611 , +-24097 , +-29603 , +4337 , +-13651 , +-16769 , +31247 , +24225 , +-11283 , +30145 , +-30877 , +10289 , +23231 , +9271 , +-28415 , +-9949 , +12737 , +26809 , +28243 , +-22881 , +6077 , +-21543 , +-29347 , +-23749 , +-9043 , +7639 , +5915 , +5415 , +19297 , +25379 , +13395 , +-30995 , +-20595 , +-22707 , +-29965 , +-30047 , +20587 , +20095 , +-29729 , +-22623 , +-18489 , +-651 , +-22185 , +27337 , +7587 , +12281 , +3523 , +4395 , +-12217 , +5589 , +-5361 , +-15035 , +-3877 , +-4531 , +-1399 , +-6463 , +23681 , +-26089 , +17707 , +21669 , +6635 , +-25641 , +-13181 , +12809 , +9073 , +16145 , +11265 , +7515 , +-6733 , +7585 , +-13617 , +21001 , +19103 , +-17475 , +-18897 , +-21305 , +-22243 , +29275 , +-17329 , +2613 , +28951 , +24637 , +-8291 , +-2003 , +-5095 , +-26277 , +-17749 , +12647 , +-5525 , +19681 , +-4999 , +-9283 , +-19295 , +6563 , +9559 , +223 , +6585 , +18715 , +-5061 , +14733 , +-3661 , +10457 , +-19311 , +841 , +-4953 , +14981 , +23711 , +-18281 , +1627 , +29261 , +-21417 , +-23629 , +30305 , +15333 , +-4947 , +9157 , +29865 , +32247 , +12149 , +23707 , +-21861 , +21541 , +24501 , +26851 , +-22349 , +-18569 , +-19839 , +-31007 , +14483 , +-12967 , +-28595 , +14247 , +-7267 , +5395 , +-28975 , +-14131 , +-31219 , +11199 , +-27819 , +16557 , +18063 , +24255 , +-19061 , +9491 , +-13737 , +-15175 , +-1295 , +5245 , +-583 , +5389 , +-32103 , +-22067 , +18755 , +-2607 , +14737 , +-23931 , +-29869 , +-1983 , +-20563 , +-16517 , +-20943 , +-1089 , +9451 , +22553 , +12961 , +12099 , +26435 , +6153 , +-30973 , +26971 , +-26369 , +-8329 , +-32025 , +3743 , +30619 , +15815 , +-8409 , +16041 , +15125 , +32455 , +635 , +32655 , +-23101 , +-15761 , +-1389 , +-24617 , +23737 , +5907 , +-1615 , +1781 , +8333 , +3619 , +12481 , +11321 , +-317 , +-15531 , +24045 , +27731 , +5011 , +-12693 , +-6217 , +-2745 , +-2991 , +5991 , +-9065 , +223 , +23097 , +1341 , +-20733 , +5545 , +9675 , +-239 , +1565 , +-31123 , +21159 , +-18449 , +31417 , +-6105 , +-3105 , +15615 , +-26371 , +-18817 , +-12077 , +15939 , +-395 , +-8519 , +-17787 , +-30263 , +-4941 , +26937 , +12661 , +12645 , +10331 , +-1673 , +29689 , +21227 , +31945 , +23663 , +-29423 , +-1307 , +-17381 , +-8795 , +31683 , +6603 , +-27695 , +-25961 , +2803 , +957 , +3559 , +-29519 , +29109 , +29367 , +5731 , +-32303 , +21547 , +-31921 , +-8837 , +-17617 , +15585 , +-23579 , +28193 , +27363 , +9879 , +-4507 , +20767 , +-14377 , +11943 , +-7053 , +-27471 , +-4033 , +2007 , +1583 , +4253 , +21137 , +17839 , +15205 , +16071 , +-11013 , +6231 , +-30903 , +-32693 , +29541 , +-28441 , +-341 , +10009 , +-29735 , +1609 , +30901 , +7173 , +-28279 , +-19833 , +-3557 , +31081 , +24127 , +8359 , +6875 , +-3535 , +-9639 , +-31989 , +1647 , +23935 , +13119 , +-30153 , +30349 , +16059 , +22617 , +-11205 , +-18351 , +-24019 , +-2419 , +-29567 , +-29691 , +9751 , +-21967 , +21545 , +3917 , +-30645 , +-24693 , +2777 , +8677 , +-28605 , +22971 , +-28633 , +15577 , +-21063 , +-10175 , +5465 , +13367 , +9155 , +-11539 , +6101 , +-9391 , +6241 , +17501 , +-25627 , +877 , +24739 , +-1299 , +-16357 , +-13059 , +24885 , +26681 , +16677 , +-15521 , +-9351 , +26377 , +1575 , +-17653 , +-215 , +12243 , +19855 , +-5551 , +-26525 , +13233 , +-28047 , +13455 , +-19901 , +5589 , +-15781 , +8171 , +-31229 , +31619 , +-9291 , +28039 , +3721 , +-5493 , +-29553 , +-13249 , +6279 , +28225 , +-5635 , +-25125 , +9997 , +15089 , +-10255 , +18121 , +1187 , +2009 , +14741 , +85 , +22759 , +22435 , +-32231 , +-23193 , +6805 , +26461 , +-16875 , +29103 , +13879 , +-1045 , +-21155 , +11109 , +16675 , +-14839 , +1371 , +-20605 , +-28377 , +-27463 , +29667 , +22645 , +-28523 , +3651 , +31375 , +14169 , +-22809 , +10149 , +-17771 , +-26705 , +-29243 , +4755 , +-14049 , +-14947 , +27311 , +-9749 , +9253 , +-29033 , +-31475 , +25775 , +24515 , +29863 , +-3901 , +6007 , +9231 , +3095 , +1361 , +-13197 , +4983 , +31667 , +-1687 , +22999 , +12693 , +-26755 , +31487 , +24289 , +-7547 , +-29209 , +-25615 , +-28861 , +6849 , +-24699 , +-5363 , +13607 , +-10375 , +-9903 , +4533 , +8603 , +30567 , +18771 , +-12811 , +-15465 , +3115 , +-23065 , +-24297 , +-25241 , +15393 , +-8339 , +2751 , +-12115 , +-13125 , +-27513 , +-22401 , +-1835 , +27987 , +-7993 , +4597 , +3085 , +-9587 , +32245 , +-13987 , +31423 , +-3547 , +-20549 , +6317 , +17795 , +-12463 , +-3615 , +13097 , +16803 , +-30835 , +-7927 , +29571 , +17411 , +-24577 , +21983 , +3687 , +27305 , +-11451 , +10971 , +4507 , +15529 , +16339 , +-23441 , +1947 , +-10079 , +-26931 , +-3131 , +6053 , +-5705 , +25431 , +-13323 , +-1447 , +-25851 , +627 , +-32321 , +-25901 , +16795 , +25431 , +-21057 , +-17349 , +-2831 , +10311 , +-14039 , +31715 , +-12827 , +16363 , +-17151 , +2013 , +1071 , +-28889 , +-9263 , +25111 , +-23977 , +-15501 , +15837 , +-30739 , +2095 , +-6733 , +-2075 , +-10687 , +-3121 , +-14957 , +9301 , +535 , +18695 , +-10921 , +14079 , +32177 , +20315 , +-29125 , +-27817 , +-24039 , +-24969 , +-2747 , +-8923 , +30021 , +28975 , +22691 , +-1093 , +25775 , +-26903 , +-8839 , +18363 , +-13213 , +-17499 , +-2489 , +-9409 , +-23901 , +15979 , +22965 , +31895 , +8183 , +20035 , +-28175 , +7045 , +-17465 , +-31307 , +-17277 , +22769 , +21877 , +-17227 , +-27987 , +4383 , +-7693 , +18725 , +21047 , +24683 , +30171 , +26061 , +-24877 , +6783 , +1033 , +-2105 , +-3093 , +11277 , +-22355 , +27271 , +-16637 , +-8443 , +-10001 , +-9657 , +-17789 , +31053 , +20217 , +17671 , +-24287 , +11767 , +2711 , +-1539 , +-11863 , +-9985 , +15953 , +-103 , +-1187 , +32129 , +-32517 , +-22549 , +27341 , +-405 , +7125 , +2991 , +3887 , +2491 , +-13029 , +-23625 , +-12241 , +-20939 , +-10457 , +-18199 , +19539 , +-27743 , +-19457 , +-7501 , +-26675 , +19827 , +17781 , +19463 , +5075 , +-16359 , +-9799 , +-2349 , +-2443 , +4253 , +-9099 , +-18955 , +-25861 , +5873 , +-29599 , +5561 , +12985 , +-13675 , +-29343 , +-5431 , +-4509 , +-24097 , +-20713 , +-16467 , +14321 , +23461 , +-16385 , +-10051 , +5355 , +11137 , +-15099 , +1693 , +18755 , +-16257 , +28061 , +-203 , +21175 , +7771 , +7259 , +29987 , +-11109 , +-16069 , +23567 , +-23107 , +-29641 , +989 , +6483 , +-27267 , +26023 , +16475 , +30897 , +-19705 , +-14045 , +-23717 , +-24275 , +6293 , +-18203 , +10699 , +21351 , +9203 , +-10375 , +-16107 , +-23247 , +-25353 , +-4457 , +475 , +-18017 , +8831 , +3709 , +32047 , +-12881 , +5599 , +-8761 , +5189 , +29007 , +-17187 , +12739 , +21173 , +17667 , +-11733 , +-30903 , +17195 , +5107 , +15451 , +29725 , +-18783 , +-23925 , +9057 , +-22345 , +30231 , +2445 , +7289 , +-25941 , +22221 , +-2639 , +-23373 , +28533 , +-22277 , +-23633 , +-24103 , +16343 , +-1791 , +-3867 , +8695 , +19373 , +-25809 , +22631 , +4423 , +13899 , +-1557 , +13471 , +7855 , +-7343 , +7799 , +7513 , +-31051 , +3073 , +27679 , +-17821 , +-767 , +9499 , +1531 , +-7517 , +27715 , +-21195 , +-10469 , +24501 , +-15171 , +31633 , +-19123 , +11767 , +-28367 , +10097 , +-27065 , +-28373 , +-30117 , +8185 , +20327 , +-10873 , +-7957 , +-29567 , +-10259 , +5465 , +30203 , +-29333 , +-31317 , +-9455 , +-17915 , +-2689 , +15429 , +-2077 , +27235 , +5055 , +1765 , +26329 , +-6851 , +-23099 , +5229 , +-27537 , +19461 , +-30057 , +-29119 , +-7509 , +11381 , +19965 , +16747 , +-15951 , +-6151 , +9311 , +-28065 , +13535 , +-28233 , +28439 , +-19669 , +7263 , +31485 , +24907 , +-27587 , +6989 , +9787 , +-8889 , +-30843 , +29245 , +-10117 , +8787 , +3653 , +-22947 , +-32423 , +25355 , +-14027 , +19727 , +12671 , +-9157 , +841 , +-11269 , +-10345 , +-31699 , +-12575 , +-25175 , +31685 , +-5491 , +11651 , +19099 , +-20065 , +24761 , +14871 , +-31005 , +30889 , +669 , +-12905 , +13371 , +17221 , +-18423 , +-27059 , +18591 , +23605 , +-14715 , +6539 , +14689 , +25223 , +2999 , +-26655 , +19139 , +5145 , +30761 , +19411 , +-25579 , +7815 , +-7507 , +-1257 , +18499 , +11947 , +-13261 , +21065 , +29425 , +-2417 , +11291 , +799 , +-26091 , +25067 , +-8939 , +7469 , +1039 , +-20201 , +-15755 , +-26355 , +-24005 , +-19837 , +15881 , +-29143 , +16403 , +-11593 , +3705 , +2785 , +22205 , +15041 , +11797 , +1871 , +23851 , +-19149 , +-13775 , +27263 , +-4947 , +-28259 , +-5375 , +-26085 , +-28147 , +15993 , +-7189 , +-29517 , +-23773 , +-11851 , +9313 , +-10643 , +-3853 , +14237 , +-32453 , +-22473 , +-20929 , +16469 , +-29043 , +14733 , +25253 , +17367 , +8705 , +-27483 , +16941 , +-27543 , +-27219 , +15663 , +-16019 , +30607 , +-7321 , +-22139 , +-16871 , +-8823 , +12455 , +1645 , +5151 , +-28851 , +-7465 , +15685 , +-2241 , +2807 , +-11217 , +-19257 , +-5861 , +-14647 , +-16117 , +-15303 , +-23585 , +4761 , +-31295 , +20775 , +-11963 , +20443 , +17665 , +-28769 , +-6591 , +-18431 , +3743 , +23777 , +-1271 , +27015 , +7935 , +11421 , +-2123 , +-3229 , +20181 , +173 , +-4773 , +5883 , +-13421 , +25411 , +-3177 , +-1887 , +-20429 , +-9299 , +25271 , +30345 , +-26987 , +-10877 , +-15803 , +-8637 , +-18089 , +29289 , +17445 , +-18257 , +-16859 , +15933 , +9257 , +-7049 , +-16225 , +15829 , +-15313 , +-18675 , +-19033 , +20535 , +-9037 , +23575 , +-16581 , +23115 , +-26133 , +11123 , +-30515 , +13597 , +-675 , +11683 , +17435 , +-10613 , +23541 , +-31023 , +24203 , +-21369 , +20645 , +63 , +-30981 , +-23871 , +-1165 , +26693 , +7199 , +-13583 , +-6889 , +191 , +-25765 , +8061 , +24337 , +-19439 , +10259 , +22721 , +-18365 , +18585 , +-15479 , +19641 , +7683 , +19107 , +19765 , +-11963 , +-32321 , +-6933 , +-7273 , +-26409 , +23303 , +24461 , +-16999 , +435 , +-25041 , +32127 , +5215 , +20383 , +-16543 , +28811 , +13729 , +18471 , +6715 , +-25659 , +22147 , +-22201 , +-27169 , +-9085 , +16113 , +29355 , +-8813 , +-28203 , +25969 , +31077 , +1491 , +6781 , +-27781 , +15911 , +-2577 , +363 , +-21929 , +32251 , +28189 , +-28497 , +-24461 , +30071 , +531 , +755 , +20275 , +20085 , +-8161 , +2933 , +10583 , +-20397 , +-17213 , +-4997 , +29127 , +-5469 , +-17721 , +-11183 , +2801 , +-19867 , +-22573 , +-18245 , +30367 , +-5697 , +25995 , +26865 , +7759 , +27193 , +-10467 , +3603 , +31755 , +18795 , +11109 , +-11737 , +15301 , +-28605 , +-9347 , +-6773 , +-4823 , +-9039 , +13787 , +-25873 , +24053 , +-6683 , +-12831 , +-11823 , +13527 , +23299 , +-22533 , +26479 , +-6973 , +5217 , +31287 , +-6593 , +-28475 , +3897 , +-9895 , +11247 , +-1951 , +11237 , +-21897 , +15827 , +1123 , +9877 , +-20209 , +997 , +3139 , +-15735 , +-28253 , +8759 , +27629 , +-24637 , +8391 , +-22291 , +-32217 , +-19639 , +22211 , +-11593 , +-20635 , +-9773 , +-16471 , +-30263 , +27927 , +32013 , +-16407 , +-5297 , +5525 , +-15551 , +-31379 , +-32409 , +29793 , +16799 , +-723 , +27547 , +-18671 , +-22293 , +-23217 , +11737 , +-10599 , +25783 , +-27727 , +24037 , +4401 , +-23267 , +-30447 , +-6309 , +-29535 , +-13581 , +26779 , +7709 , +-18147 , +-20855 , +-5117 , +22353 , +-29537 , +-18215 , +-5089 , +16601 , +11963 , +18247 , +5625 , +-20665 , +11519 , +20949 , +25715 , +6745 , +-12351 , +-13349 , +13903 , +32754 , +-22661 , +-18625 , +22743 , +-6777 , +-5465 , +25133 , +-8469 , +12331 , +-17391 , +-14511 , +7321 , +-29967 , +-3663 , +-30577 , +-24775 , +5111 , +29703 , +31797 , +31235 , +1999 , +-12821 , +17597 , +-16595 , +9089 , +1259 , +-5385 , +32115 , +29953 , +21029 , +-3371 , +6725 , +21023 , +-11369 , +-7539 , +24649 , +-20979 , +-12803 , +-19357 , +6787 , +-31413 , +-26841 , +10965 , +-27669 , +-26587 , +-16173 , +32601 , +-11399 , +11177 , +-25599 , +25491 , +-4917 , +2337 , +-21295 , +-13041 , +15671 , +29701 , +9943 , +-31881 , +-4765 , +20095 , +2543 , +-5815 , +-28837 , +9299 , +-2147 , +-2283 , +12593 , +21607 , +22753 , +-7887 , +-17397 , +4271 , +-4973 , +24557 , +-2111 , +27817 , +22063 , +4693 , +2803 , +12891 , +-15041 , +-3231 , +-12381 , +-19011 , +19745 , +22963 , +-11191 , +24259 , +1391 , +31171 , +24943 , +8645 , +-30005 , +-7511 , +23495 , +-24963 , +-1987 , +-4793 , +23237 , +7557 , +-3833 , +-27133 , +-13389 , +9283 , +-11517 , +-18167 , +31053 , +-10387 , +-22153 , +10483 , +20443 , +-7175 , +-1939 , +-26607 , +-19013 , +9879 , +-1911 , +-13293 , +20625 , +-13909 , +23399 , +5195 , +-28985 , +4545 , +12397 , +31331 , +-12875 , +-28531 , +551 , +-23153 , +29743 , +-2475 , +-15331 , +-6065 , +-9815 , +14841 , +-22229 , +28825 , +20927 , +20321 , +31325 , +4773 , +13403 , +9333 , +-31171 , +-23023 , +14919 , +7323 , +-16199 , +28067 , +1601 , +-15701 , +11115 , +-32383 , +12957 , +-5785 , +7809 , +-19479 , +-17579 , +-3471 , +-30197 , +-6047 , +7333 , +29641 , +-14381 , +21887 , +-481 , +-3135 , +5561 , +-22257 , +-15803 , +-3213 , +20623 , +-31015 , +-11607 , +-65 , +1889 , +22993 , +113 , +187 , +32609 , +-4143 , +-11897 , +32695 , +-16337 , +-10285 , +4641 , +7075 , +16571 , +-1369 , +-32039 , +-7141 , +19609 , +26157 , +-1197 , +-11567 , +-17959 , +-15609 , +-9917 , +7051 , +1887 , +27865 , +5137 , +-30059 , +31675 , +-23295 , +-13073 , +-22075 , +23687 , +-10303 , +-19603 , +-7193 , +-10703 , +27661 , +5781 , +24251 , +-21409 , +5553 , +-1407 , +-15513 , +19143 , +8721 , +2673 , +-21125 , +20097 , +-18593 , +-16535 , +-1955 , +8159 , +32341 , +-27833 , +-23739 , +-19255 , +-20887 , +-26541 , +-31817 , +5013 , +-2935 , +19811 , +32379 , +-20899 , +11347 , +1643 , +32527 , +11993 , +25545 , +-15973 , +-6743 , +-13649 , +8589 , +-16147 , +-23645 , +-18343 , +26007 , +-16309 , +-16767 , +-9101 , +23659 , +8217 , +29021 , +18325 , +15577 , +-9127 , +-23327 , +-25431 , +18477 , +-22471 , +-2615 , +-2101 , +25829 , +1585 , +461 , +28055 , +19445 , +-19301 , +13091 , +-17655 , +-16269 , +18119 , +-15761 , +15821 , +-13867 , +17049 , +10055 , +-13025 , +26789 , +-25959 , +-20707 , +-29921 , +-16961 , +-9069 , +29375 , +18091 , +7173 , +-4949 , +25169 , +-31313 , +-875 , +-23309 , +-24645 , +-12275 , +19843 , +12681 , +-8275 , +21219 , +4889 , +-32469 , +2321 , +29809 , +-11395 , +-23989 , +-13567 , +28777 , +-15111 , +25775 , +24899 , +-27447 , +13999 , +6025 , +16189 , +14135 , +11213 , +-17403 , +-9865 , +-1327 , +-24249 , +-31637 , +17793 , +32397 , +30225 , +-2125 , +-6021 , +3083 , +28117 , +-28259 , +-5109 , +24305 , +17963 , +14155 , +-20021 , +7361 , +22099 , +22613 , +-693 , +5425 , +-20117 , +5221 , +3205 , +-7417 , +17187 , +15693 , +22229 , +1383 , +-8445 , +-29279 , +10865 , +2487 , +-17905 , +-5173 , +-8095 , +-8721 , +18195 , +4521 , +-8451 , +-7307 , +-4791 , +28829 , +8919 , +-9615 , +-28257 , +-21971 , +-31167 , +15785 , +27241 , +29975 , +32577 , +9945 , +5527 , +18151 , +-29697 , +21385 , +26995 , +-26091 , +1489 , +25187 , +-2095 , +10389 , +-28001 , +-7923 , +-17457 , +-3333 , +-4891 , +17033 , +-5623 , +27651 , +14893 , +22011 , +23375 , +-24393 , +-22527 , +22035 , +-30235 , +-19199 , +-30877 , +10459 , +-26321 , +-29505 , +-24881 , +-6129 , +24563 , +-1691 , +-5471 , +18943 , +-4851 , +17423 , +-31709 , +727 , +32423 , +27667 , +-6417 , +-18811 , +25589 , +-3543 , +19705 , +-27897 , +-16029 , +-30733 , +22781 , +11085 , +-20647 , +31773 , +-14473 , +-21881 , +-21655 , +15093 , +24097 , +-2045 , +-11247 , +-17537 , +-11803 , +-7291 , +-6423 , +12561 , +-9381 , +-3559 , +31073 , +-9877 , +12731 , +-7305 , +25591 , +16203 , +-23467 , +-30773 , +-10255 , +-13945 , +2705 , +-483 , +6035 , +-4441 , +16989 , +-3301 , +18645 , +-6913 , +-2773 , +-1923 , +23199 , +10043 , +23401 , +-29485 , +29827 , +-23161 , +-18825 , +-5145 , +-5907 , +-1253 , +-18147 , +16263 , +8673 , +-32677 , +-27001 , +18671 , +-32721 , +-28309 , +-4163 , +6803 , +-23243 , +-7869 , +22425 , +-1417 , +7943 , +12625 , +-23237 , +1301 , +-4301 , +17801 , +-13043 , +-22363 , +-7177 , +27905 , +30767 , +-28419 , +15347 , +30469 , +4721 , +7143 , +-29587 , +27825 , +-31019 , +-4613 , +25081 , +-6385 , +25211 , +-16397 , +-27711 , +22947 , +-27111 , +-887 , +-16081 , +10639 , +-29183 , +18121 , +-3537 , +-5855 , +-10101 , +-32531 , +-11805 , +-28687 , +4877 , +27567 , +31709 , +1913 , +21855 , +30253 , +21459 , +-7127 , +-11321 , +-10699 , +-8231 , +-23803 , +-4233 , +-32479 , +7453 , +17333 , +28035 , +7473 , +18201 , +-26843 , +3161 , +-31903 , +-30385 , +6809 , +12221 , +-5695 , +-27781 , +-18619 , +-9415 , +20047 , +-30633 , +15971 , +-19687 , +14925 , +16069 , +-1583 , +15339 , +30231 , +19857 , +10533 , +4197 , +-14975 , +-9821 , +-15547 , +17903 , +17579 , +-24899 , +21631 , +-18543 , +32089 , +10925 , +20769 , +28525 , +-13113 , +-15611 , +-19309 , +-6469 , +12815 , +-4771 , +17645 , +21559 , +7405 , +4605 , +21265 , +-16091 , +21803 , +12573 , +20283 , +7361 , +-28055 , +8861 , +2601 , +1597 , +-9091 , +22585 , +-1373 , +-31441 , +19531 , +-26041 , +24475 , +26773 , +17691 , +-18713 , +-26939 , +-31675 , +-16785 , +-25661 , +32685 , +-31511 , +-18845 , +-11709 , +17229 , +-28043 , +25721 , +-10681 , +22569 , +31005 , +17659 , +16215 , +6887 , +-28459 , +-27437 , +13415 , +-11421 , +6973 , +21973 , +8715 , +32335 , +20517 , +29613 , +11051 , +13115 , +-12163 , +8487 , +19515 , +32579 , +-18481 , +1543 , +-22281 , +-29675 , +1081 , +21869 , +-865 , +27535 , +-29471 , +25759 , +-23391 , +24539 , +16115 , +-9617 , +15841 , +30723 , +-9965 , +3843 , +19553 , +22789 , +-8871 , +-19395 , +-6773 , +-29833 , +-3643 , +24197 , +-11047 , +9615 , +26429 , +1581 , +13079 , +10699 , +7933 , +6463 , +-6125 , +29181 , +-31077 , +13789 , +3807 , +32489 , +-7569 , +9491 , +-19329 , +1115 , +-24937 , +11829 , +-5845 , +-30271 , +-8595 , +23213 , +-25607 , +-2241 , +637 , +-15775 , +14631 , +26443 , +23803 , +30849 , +-32061 , +5317 , +-13119 , +12509 , +-25621 , +-17013 , +30401 , +13767 , +-16763 , +20883 , +22015 , +-14749 , +-27789 , +18053 , +-9717 , +30083 , +-23215 , +26581 , +19449 , +-24325 , +-6747 , +31567 , +12755 , +-26241 , +-17247 , +-28097 , +26779 , +-27915 , +-25777 , +24317 , +11449 , +-2737 , +-30633 , +26383 , +-14085 , +9703 , +-24793 , +27059 , +9221 , +24911 , +-1603 , +-11511 , +-7085 , +-16977 , +-821 , +-27751 , +25255 , +-4707 , +32387 , +13433 , +8967 , +-9355 , +-16447 , +32735 , +3125 , +-19159 , +-20537 , +-27083 , +5539 , +-32601 , +29301 , +-14403 , +-23569 , +-12125 , +-24315 , +2715 , +19419 , +-19973 , +15677 , +25973 , +13247 , +27015 , +-12501 , +9869 , +-13431 , +6769 , +-23207 , +16209 , +4915 , +-4843 , +-20599 , +-25479 , +10163 , +-12719 , +-5139 , +-11617 , +20099 , +24411 , +-8485 , +-2221 , +14213 , +11815 , +3335 , +-327 , +-21107 , +-12757 , +-4033 , +30107 , +27985 , +-5687 , +24221 , +-4095 , +23261 , +-7137 , +-9151 , +1105 , +-12909 , +9051 , +-12405 , +10973 , +10911 , +-25703 , +4051 , +23045 , +-31249 , +-19907 , +-14695 , +-18751 , +-32341 , +4549 , +6989 , +12745 , +9263 , +-31197 , +-24203 , +26915 , +-9085 , +31127 , +371 , +-22979 , +27979 , +10755 , +-11341 , +20613 , +-2483 , +11975 , +9837 , +-21373 , +-11171 , +26393 , +-23085 , +16239 , +-28711 , +-5927 , +-8499 , +-20661 , +-28251 , +2029 , +-27593 , +30579 , +-10593 , +3609 , +-24945 , +18885 , +22933 , +-17585 , +20017 , +29737 , +27583 , +9879 , +-14319 , +8883 , +-19525 , +5973 , +21747 , +-10701 , +2817 , +28463 , +6943 , +-6315 , +-3625 , +-17315 , +15005 , +28215 , +-11821 , +-29563 , +-15381 , +26235 , +-14645 , +-26609 , +-32459 , +26599 , +9807 , +24067 , +2575 , +-13447 , +32163 , +18521 , +6567 , +-27395 , +15923 , +-3877 , +-24693 , +-1749 , +-12141 , +-24973 , +-32053 , +-10183 , +17897 , +-27897 , +-28727 , +1271 , +24565 , +16857 , +-30627 , +-20381 , +10109 , +1613 , +-12645 , +-11831 , +-14001 , +29523 , +-24061 , +-7347 , +-3669 , +-11467 , +26429 , +-13547 , +24139 , +-4111 , +-3507 , +18639 , +-8497 , +-17389 , +19277 , +-16425 , +31679 , +-3063 , +-6739 , +-18999 , +-1035 , +20481 , +-15911 , +-8809 , +-32605 , +24121 , +29059 , +1829 , +28615 , +-25119 , +30287 , +-13473 , +25887 , +-3479 , +-3309 , +19667 , +24995 , +1889 , +10123 , +-6971 , +-3715 , +-17209 , +-20851 , +5325 , +-32637 , +13295 , +-2355 , +-27417 , +-27345 , +-27445 , +-4603 , +-10733 , +10771 , +9161 , +22207 , +-11929 , +-8747 , +-16335 , +-16261 , +31659 , +12705 , +25329 , +-25995 , +-19085 , +-29139 , +-18943 , +22739 , +4011 , +18213 , +23603 , +9317 , +15551 , +21799 , +395 , +3291 , +-31191 , +-449 , +-13281 , +13685 , +7817 , +9431 , +17765 , +-2999 , +-22459 , +30007 , +21523 , +23533 , +-14187 , +10615 , +24175 , +10169 , +7975 , +-25605 , +11567 , +-32131 , +31281 , +24681 , +-22835 , +-24653 , +-24829 , +6947 , +-1185 , +-24767 , +32559 , +-12483 , +22767 , +-19547 , +12817 , +-9487 , +-16299 , +697 , +-29969 , +23203 , +4747 , +14563 , +-23665 , +10829 , +-4469 , +18129 , +13139 , +15737 , +30625 , +16811 , +2761 , +-31293 , +-25529 , +-8745 , +-29751 , +8131 , +-2695 , +31781 , +30221 , +-371 , +-10607 , +16777 , +-8121 , +-12885 , +-23137 , +12635 , +-19017 , +16781 , +5181 , +-15865 , +-28601 , +-29051 , +20715 , +-7097 , +18211 , +15943 , +-14107 , +-2853 , +2511 , +7119 , +-28037 , +-28477 , +24511 , +28139 , +6123 , +-15371 , +-7059 , +14379 , +6839 , +-30057 , +6137 , +-17837 , +-22659 , +7345 , +7221 , +-6557 , +4685 , +-913 , +-18871 , +1279 , +-27767 , +16081 , +27843 , +16493 , +-25291 , +1763 , +6705 , +19989 , +-32561 , +-21637 , +-13253 , +-4505 , +32171 , +32623 , +18233 , +31587 , +-12339 , +-19387 , +1613 , +15759 , +-10439 , +20345 , +4085 , +-16539 , +-4145 , +-21977 , +30507 , +-10411 , +4523 , +29519 , +-7943 , +-24519 , +-11797 , +-21373 , +-6511 , +6219 , +-9191 , +-26329 , +-21529 , +-24923 , +31735 , +6179 , +-32057 , +1839 , +20449 , +24607 , +-3477 , +32027 , +-17511 , +-27079 , +-1129 , +-5151 , +13227 , +14139 , +-3791 , +9907 , +-1733 , +-13475 , +-17065 , +-31119 , +24165 , +-9109 , +-5387 , +13865 , +11023 , +-22895 , +19427 , +-6641 , +14919 , +31621 , +-27785 , +7403 , +-6127 , +20545 , +-16991 , +-8167 , +26573 , +27971 , +-25985 , +-5629 , +-25853 , +-18115 , +22141 , +10001 , +-32577 , +-27057 , +22239 , +-20181 , +-10897 , +-13887 , +17131 , +421 , +-1233 , +26165 , +-28305 , +-28221 , +-15703 , +12395 , +29417 , +-24153 , +11375 , +30315 , +28689 , +24019 , +-17717 , +-11961 , +-27397 , +6933 , +27679 , +-14003 , +-32597 , +-7927 , +-2633 , +-11067 , +12589 , +-1265 , +22311 , +-22237 , +-7121 , +-14401 , +24091 , +22211 , +-7147 , +32485 , +12981 , +10011 , +-26217 , +9715 , +-31641 , +-19075 , +-17967 , +27399 , +28481 , +14921 , +-5919 , +-25009 , +-20011 , +-32605 , +-22269 , +-32239 , +19335 , +32427 , +-4583 , +10527 , +7017 , +2113 , +11737 , +-25653 , +-26735 , +-27607 , +17487 , +31583 , +13551 , +-29741 , +1287 , +23581 , +-26709 , +7565 , +-12133 , +3501 , +9207 , +2363 , +1739 , +-30181 , +1901 , +24465 , +-21219 , +-15537 , +21215 , +-21563 , +8683 , +1793 , +15541 , +32719 , +13311 , +12599 , +9159 , +-9443 , +30383 , +25907 , +27307 , +25551 , +10865 , +-31493 , +-15461 , +-5533 , +-28175 , +7999 , +1215 , +12285 , +2989 , +3035 , +7437 , +26389 , +-14325 , +28373 , +16803 , +26289 , +29681 , +22977 , +-5223 , +2077 , +-20511 , +-15407 , +-16805 , +-22745 , +-21623 , +4155 , +-4479 , +15565 , +-16927 , +-9413 , +16681 , +3205 , +20931 , +17793 , +15311 , +23521 , +-255 , +30265 , +-25441 , +11481 , +10235 , +-29837 , +-19625 , +29303 , +-3141 , +-20189 , +-19821 , +-18407 , +-881 , +-26983 , +-28237 , +-19683 , +-29929 , +-1419 , +-26843 , +-18653 , +-18969 , +-31455 , +9031 , +-31551 , +15775 , +-22065 , +-11335 , +27323 , +32119 , +-14875 , +-26821 , +12733 , +18537 , +14079 , +-13825 , +-13679 , +2743 , +-24733 , +-3451 , +14037 , +2065 , +4345 , +14063 , +-23495 , +3621 , +22211 , +8925 , +12851 , +29627 , +5335 , +-10811 , +23091 , +-17331 , +-2345 , +12743 , +29285 , +-18409 , +-23327 , +8971 , +17123 , +30909 , +-18669 , +-26737 , +9577 , +-3497 , +24445 , +16269 , +-22633 , +-24305 , +665 , +-20921 , +10143 , +2873 , +30275 , +-3229 , +25475 , +30693 , +7985 , +17607 , +29391 , +-19969 , +-23315 , +-12051 , +8905 , +12261 , +29771 , +20917 , +11565 , +30587 , +-14241 , +30671 , +16747 , +5827 , +29181 , +-14725 , +22611 , +2301 , +5541 , +-2055 , +19031 , +-8139 , +6151 , +-32179 , +8257 , +-29853 , +-3853 , +21667 , +5733 , +4349 , +7379 , +25891 , +-13725 , +5651 , +25765 , +10057 , +-29869 , +-30237 , +-19345 , +-32063 , +17543 , +19961 , +14397 , +25269 , +-1341 , +12985 , +-2157 , +30129 , +21483 , +8329 , +-22681 , +13811 , +8519 , +-15017 , +-5473 , +-11705 , +25647 , +-24895 , +-18183 , +3931 , +-15023 , +-18273 , +9369 , +-18019 , +-2467 , +-2011 , +13805 , +-16499 , +-2495 , +19319 , +5683 , +-29545 , +-20507 , +-27197 , +16487 , +-17299 , +-5283 , +-20525 , +-3901 , +-16675 , +2467 , +21805 , +-30029 , +-31701 , +-32047 , +21929 , +11595 , +-13851 , +-24873 , +-7293 , +11845 , +8255 , +24757 , +22009 , +-19599 , +16359 , +7213 , +14439 , +8887 , +-14235 , +-20987 , +-559 , +-24441 , +-279 , +-12619 , +12551 , +21711 , +-23129 , +30631 , +31035 , +-20863 , +-31821 , +-11543 , +19223 , +23929 , +-19119 , +-21143 , +-25003 , +15105 , +23767 , +-7253 , +32727 , +-10041 , +-13317 , +-16127 , +-10179 , +-4529 , +-16973 , +-14011 , +16135 , +23795 , +-18299 , +-6899 , +12829 , +601 , +12647 , +26727 , +-30217 , +4453 , +-30957 , +-5103 , +-32217 , +10681 , +28127 , +28973 , +11899 , +-6745 , +-7147 , +-14467 , +-19313 , +5807 , +18125 , +-20967 , +8685 , +26733 , +-24765 , +-22875 , +13979 , +-24033 , +-16211 , +-3311 , +-969 , +16017 , +20123 , +-18999 , +-32367 , +-28003 , +17345 , +-21397 , +-27967 , +14873 , +4449 , +32013 , +-14909 , +861 , +-4331 , +3553 , +-19581 , +4401 , +29481 , +-8323 , +-19065 , +27459 , +2937 , +-7791 , +-7 , +-19159 , +28357 , +-17901 , +28737 , +17363 , +-24951 , +-2297 , +-6107 , +18817 , +-28331 , +8873 , +-29351 , +20543 , +7593 , +12851 , +-14953 , +-17701 , +15683 , +18183 , +18239 , +-31651 , +16641 , +14961 , +5731 , +-2557 , +3385 , +-5157 , +-14741 , +-29777 , +-2425 , +-13949 , +-10203 , +-16661 , +22321 , +-29767 , +-29599 , +-4005 , +29941 , +-25967 , +771 , +10161 , +-12441 , +5663 , +-345 , +-7631 , +28363 , +-1747 , +9385 , +-22631 , +19301 , +20085 , +4557 , +-25175 , +25943 , +-4013 , +6987 , +-11763 , +-23305 , +-13563 , +5229 , +29411 , +7083 , +6497 , +-3929 , +-21085 , +-17097 , +-27641 , +-26071 , +27813 , +10655 , +2851 , +-11007 , +-21739 , +-24705 , +25241 , +-31063 , +-26781 , +-20773 , +26827 , +14885 , +15429 , +-15237 , +32705 , +14491 , +-6097 , +9669 , +-28431 , +3689 , +2883 , +29973 , +17259 , +-11075 , +-15409 , +22161 , +-4967 , +6059 , +-11967 , +19847 , +13167 , +-20277 , +9637 , +27195 , +-8661 , +28237 , +-12903 , +-8115 , +-15735 , +-8561 , +26307 , +7557 , +20603 , +6205 , +-9007 , +31025 , +-20641 , +-10531 , +-23325 , +5115 , +-6721 , +-15377 , +12179 , +63 , +895 , +17545 , +-13983 , +19181 , +-14693 , +-23711 , +-24141 , +-815 , +-19873 , +-4235 , +12359 , +-21385 , +4379 , +26393 , +-20177 , +-18303 , +-10147 , +-14451 , +-4283 , +-15747 , +-6227 , +22815 , +5415 , +-32197 , +-26179 , +4029 , +-17231 , +-30295 , +8235 , +-26611 , +-2837 , +4393 , +-24145 , +-22271 , +30347 , +25707 , +-27943 , +29179 , +-16661 , +1989 , +16711 , +32089 , +18813 , +11779 , +2399 , +-8301 , +-24635 , +-26933 , +11909 , +2767 , +30677 , +28017 , +-12847 , +7933 , +-26307 , +16453 , +-7347 , +3697 , +-16245 , +-22403 , +-9819 , +28401 , +14653 , +-17791 , +-25493 , +20311 , +26175 , +-10561 , +-23359 , +-5719 , +-3879 , +-3309 , +-1895 , +-30297 , +-10697 , +-2929 , +-27541 , +32750 , +2895 , +12765 , +14193 , +31109 , +-4251 , +-18929 , +2649 , +5125 , +17665 , +23555 , +6267 , +1571 , +-5791 , +23083 , +5023 , +-19253 , +633 , +22261 , +23077 , +-29509 , +-9367 , +-25193 , +-18493 , +-1895 , +10093 , +-29845 , +-10045 , +19341 , +-7323 , +-12853 , +-6225 , +30805 , +-29255 , +-30621 , +19859 , +-4895 , +-4891 , +-1013 , +3251 , +27241 , +7265 , +-14813 , +-21061 , +12809 , +6177 , +20579 , +14215 , +24013 , +32399 , +-30407 , +10571 , +-16805 , +-16135 , +31907 , +-4271 , +5373 , +31383 , +-6787 , +-13771 , +573 , +9717 , +20327 , +-24423 , +-32515 , +-5899 , +-7921 , +-19623 , +17937 , +-20667 , +26387 , +-21425 , +-9127 , +19279 , +-18605 , +-131 , +-10929 , +-10817 , +1233 , +5839 , +-6617 , +877 , +15355 , +16461 , +18793 , +-22045 , +-109 , +-10535 , +15619 , +10823 , +24059 , +-25247 , +-2843 , +-1319 , +-10477 , +-15207 , +-9709 , +1779 , +-13679 , +-27851 , +28233 , +7539 , +-6441 , +10397 , +-21501 , +9659 , +-20409 , +21039 , +15141 , +21287 , +-18137 , +-5405 , +20999 , +3847 , +-24085 , +-16995 , +-25835 , +-12013 , +31255 , +25035 , +-2339 , +-24981 , +-26223 , +2741 , +29367 , +26371 , +-30081 , +-16097 , +19401 , +-1629 , +7067 , +-109 , +22195 , +-14751 , +13063 , +10511 , +-23655 , +10133 , +31149 , +-11711 , +-18755 , +26955 , +30485 , +21815 , +11679 , +18249 , +13753 , +-22617 , +10381 , +6525 , +2015 , +-5223 , +20667 , +26357 , +-31501 , +-19807 , +-11551 , +5983 , +22365 , +27549 , +9807 , +-1291 , +-3367 , +-3353 , +-1917 , +-7935 , +-13485 , +-17131 , +5449 , +-2869 , +9269 , +-27613 , +-23737 , +-26341 , +4171 , +24379 , +-29411 , +31269 , +-17899 , +-4895 , +28417 , +3597 , +-29541 , +14257 , +-7989 , +15317 , +21709 , +7573 , +29845 , +24797 , +-3239 , +385 , +16851 , +27863 , +-18689 , +20385 , +21737 , +19519 , +-2197 , +23579 , +-9403 , +22863 , +2191 , +-27577 , +25585 , +2949 , +7803 , +31323 , +3251 , +-25205 , +14767 , +25525 , +-3165 , +-7757 , +-19461 , +29059 , +-15043 , +-773 , +-31277 , +-17405 , +-16639 , +16497 , +-9177 , +10299 , +-377 , +-9925 , +5819 , +-8147 , +29973 , +-28917 , +-14593 , +-6763 , +22459 , +18707 , +-14485 , +-18663 , +25581 , +-28291 , +849 , +-32758 , +-12143 , +-12439 , +1847 , +-13673 , +17315 , +28515 , +-3665 , +11391 , +-23485 , +-19883 , +-9039 , +-6567 , +8535 , +23303 , +22387 , +-4805 , +17561 , +-3567 , +2235 , +22271 , +27189 , +-10151 , +4543 , +-24335 , +29917 , +-8189 , +18811 , +-14065 , +5737 , +-23569 , +-6015 , +-20039 , +-31515 , +21939 , +-17059 , +-14347 , +-3025 , +14859 , +-32409 , +25623 , +-21491 , +-29737 , +26139 , +-8953 , +4807 , +-623 , +29425 , +-14861 , +-31685 , +-28343 , +-13389 , +20101 , +19833 , +-235 , +30557 , +15777 , +-23333 , +25103 , +-16533 , +32403 , +-2409 , +25549 , +-16457 , +-18217 , +24033 , +-25003 , +16081 , +-5569 , +-23943 , +27801 , +26325 , +31673 , +-27959 , +-7827 , +30399 , +-14209 , +4735 , +7423 , +1101 , +-28719 , +-19045 , +-18221 , +-6575 , +18737 , +16403 , +-32207 , +24453 , +-11503 , +-7709 , +15147 , +-24083 , +29721 , +-30811 , +-26105 , +17063 , +-22829 , +6067 , +16193 , +-18875 , +-22553 , +-3153 , +-9729 , +28069 , +16087 , +-26967 , +13065 , +-21683 , +-18129 , +-22607 , +22081 , +-22213 , +-28601 , +22763 , +-28003 , +10053 , +-20111 , +27443 , +-30563 , +-1557 , +-8011 , +-20955 , +-189 , +-20045 , +11791 , +21701 , +-18547 , +-3329 , +-2787 , +-2419 , +-2457 , +-27035 , +24411 , +-27389 , +-723 , +10635 , +-7969 , +32221 , +10395 , +-6027 , +-22647 , +24971 , +-4537 , +-14487 , +29891 , +30299 , +28827 , +-23233 , +-9803 , +7 , +-7863 , +15931 , +19965 , +5075 , +27211 , +-2199 , +6375 , +-3801 , +-10931 , +6765 , +-31449 , +-14691 , +-22089 , +-26139 , +22283 , +15267 , +-1773 , +-2509 , +-703 , +-26989 , +-28143 , +23271 , +29689 , +-10433 , +-11777 , +-29563 , +21173 , +-25063 , +-13127 , +-16657 , +-915 , +14273 , +805 , +-5079 , +27223 , +-23267 , +24623 , +-15421 , +-30449 , +-2055 , +-19397 , +-13659 , +-24483 , +-9195 , +26399 , +-15503 , +-17047 , +-23359 , +-26465 , +-2223 , +-26771 , +-18693 , +26463 , +30547 , +-6413 , +-22533 , +-27045 , +-4541 , +-22643 , +-6059 , +18665 , +6917 , +15371 , +21391 , +3359 , +-29855 , +-4813 , +31793 , +-4895 , +-20627 , +-17673 , +3181 , +-17085 , +-8875 , +-1997 , +4899 , +25745 , +23997 , +-22301 , +-27251 , +20163 , +6289 , +6869 , +15687 , +-14223 , +-1431 , +-20249 , +31473 , +30795 , +-21935 , +22717 , +-2749 , +-20711 , +-22479 , +-23811 , +-25437 , +-14805 , +27543 , +-2559 , +15169 , +17487 , +-25829 , +-11505 , +-9807 , +343 , +-3027 , +-23015 , +-12295 , +-1 , +-1163 , +6121 , +-9419 , +13937 , +3495 , +23271 , +4007 , +-711 , +-5927 , +27201 , +-175 , +23743 , +18015 , +-19533 , +-4851 , +-3779 , +-25309 , +9141 , +25643 , +-25291 , +-23431 , +3123 , +3197 , +-15763 , +-20615 , +-8759 , +4855 , +14693 , +30941 , +11133 , +-313 , +-16557 , +30541 , +-3859 , +19179 , +4757 , +21057 , +-27885 , +-25527 , +30119 , +-28845 , +-27787 , +-5047 , +-12121 , +4125 , +28129 , +32746 , +10561 , +30859 , +-26463 , +857 , +-22225 , +5557 , +7991 , +-24045 , +-5337 , +23867 , +-12397 , +29549 , +-14751 , +-25323 , +29135 , +5051 , +20611 , +-3085 , +605 , +-15907 , +19999 , +10767 , +26315 , +-9889 , +-13909 , +-32121 , +-27407 , +265 , +2289 , +7483 , +-23373 , +-6653 , +-26345 , +281 , +-15311 , +-9379 , +-22265 , +26367 , +-31107 , +13875 , +27247 , +23823 , +-31521 , +-16827 , +-20169 , +23173 , +-13697 , +2823 , +-30339 , +-9193 , +681 , +9533 , +-1021 , +-24383 , +-7811 , +17687 , +-18125 , +-24793 , +-16601 , +1221 , +-7535 , +19305 , +-8803 , +-8309 , +-21841 , +17791 , +20693 , +21861 , +945 , +2053 , +375 , +-29937 , +5173 , +-20571 , +-15847 , +-16723 , +-21797 , +29407 , +-4353 , +26841 , +26671 , +-7575 , +-28605 , +25145 , +-10451 , +-30201 , +30361 , +-6749 , +11315 , +2527 , +19077 , +-14681 , +-7565 , +16473 , +1551 , +-19277 , +-4103 , +-25495 , +-12033 , +-7519 , +-14311 , +12407 , +-18543 , +-5417 , +-7063 , +-25171 , +13237 , +18391 , +3129 , +28623 , +189 , +14691 , +4747 , +409 , +12695 , +28163 , +17041 , +-32367 , +399 , +18737 , +12951 , +12131 , +22395 , +7653 , +13705 , +27063 , +29557 , +13739 , +8933 , +-23413 , +-16611 , +-955 , +-21199 , +-8187 , +14401 , +10169 , +-263 , +-18473 , +28195 , +13555 , +-10687 , +-23801 , +-30423 , +4307 , +-10623 , +31831 , +21787 , +17867 , +18715 , +-5361 , +-14895 , +-31245 , +1105 , +-15265 , +-4487 , +-5717 , +-20285 , +-715 , +-7357 , +-17759 , +9569 , +17553 , +32159 , +9083 , +4585 , +-8609 , +31473 , +-25625 , +-20519 , +-10541 , +-4657 , +26927 , +-19993 , +9783 , +31157 , +2907 , +10753 , +-8877 , +20793 , +-4417 , +-25157 , +-3535 , +28365 , +14873 , +335 , +-14969 , +-15 , +4393 , +-12017 , +-1915 , +31465 , +9159 , +351 , +-21713 , +22263 , +-7815 , +-719 , +-17609 , +-8427 , +10639 , +27381 , +6993 , +5933 , +-12355 , +-4071 , +-9455 , +11215 , +-13015 , +-21765 , +-2243 , +25701 , +30223 , +-25755 , +-30041 , +4085 , +-29743 , +-20091 , +30599 , +25681 , +-31855 , +-17569 , +8531 , +-14381 , +-9909 , +-5937 , +20241 , +32147 , +-14485 , +7671 , +-12743 , +11291 , +15075 , +-13249 , +-4607 , +13995 , +23499 , +-30267 , +27457 , +24807 , +-32145 , +8029 , +-6971 , +-19187 , +-3857 , +17671 , +28705 , +9399 , +10573 , +-15137 , +26387 , +-9205 , +14355 , +15525 , +1363 , +-16523 , +-13473 , +13729 , +-4373 , +3043 , +28289 , +-13521 , +14103 , +-28299 , +-15853 , +-26713 , +-109 , +-32581 , +2187 , +8157 , +18555 , +17005 , +-8355 , +29977 , +2203 , +20897 , +31881 , +17807 , +9809 , +-28541 , +18619 , +4945 , +26841 , +3979 , +11741 , +-13875 , +-1487 , +-16579 , +29233 , +27077 , +-28309 , +1111 , +30701 , +965 , +-8829 , +-22897 , +14669 , +-18149 , +18617 , +4555 , +-9939 , +-1199 , +-21395 , +25043 , +8225 , +-15841 , +3441 , +12435 , +15891 , +-4113 , +-1821 , +-24887 , +-22451 , +-25401 , +-26231 , +-28857 , +27681 , +32711 , +7585 , +-29539 , +-12813 , +12073 , +-31423 , +20833 , +-29473 , +28331 , +28969 , +27359 , +-23871 , +17551 , +2591 , +-4533 , +-10017 , +3345 , +-26427 , +-18297 , +2285 , +17503 , +-6669 , +12369 , +25271 , +16151 , +-1143 , +763 , +-29135 , +-30415 , +24019 , +-11351 , +525 , +9095 , +21841 , +21763 , +26325 , +22465 , +24861 , +-14993 , +24197 , +23249 , +27067 , +17871 , +-30557 , +30191 , +-13191 , +685 , +6865 , +-4597 , +-10441 , +-22533 , +-6673 , +25033 , +-13101 , +5963 , +8107 , +-10761 , +2549 , +-10105 , +-14183 , +10371 , +25191 , +15653 , +1747 , +8697 , +20209 , +-21025 , +19717 , +-8839 , +943 , +6899 , +-23023 , +-16603 , +1771 , +1747 , +-739 , +-20179 , +24691 , +9053 , +-17867 , +-8399 , +-1679 , +-1635 , +-29863 , +-22451 , +17603 , +-27661 , +-19941 , +-131 , +-14379 , +-23841 , +-21067 , +-3415 , +-25611 , +5161 , +-26207 , +-28655 , +-32721 , +-27487 , +6323 , +-7613 , +-27737 , +-2981 , +9393 , +15003 , +20583 , +-6823 , +-26011 , +-32199 , +-8511 , +3281 , +-9669 , +-13963 , +22819 , +-8483 , +21851 , +-12839 , +6257 , +15543 , +24377 , +-20835 , +-24361 , +19823 , +7091 , +-30825 , +18221 , +-30427 , +-7767 , +10939 , +9919 , +28347 , +-5613 , +-20467 , +32693 , +-9193 , +-23657 , +5151 , +5597 , +-32559 , +-32091 , +-25343 , +-22513 , +25459 , +-23023 , +15809 , +6141 , +-3797 , +10275 , +-20385 , +23179 , +-28665 , +29747 , +32323 , +-14161 , +11179 , +30915 , +-20679 , +-5953 , +-19319 , +3611 , +22249 , +18511 , +2459 , +26959 , +-18229 , +32393 , +17559 , +-3087 , +15011 , +-4351 , +-8019 , +24595 , +-8839 , +25873 , +-19529 , +20713 , +29963 , +8111 , +12793 , +28641 , +21967 , +26053 , +-2987 , +17977 , +-20127 , +15115 , +-1789 , +-19687 , +22913 , +19803 , +-26937 , +22053 , +8585 , +-19825 , +-25933 , +-14691 , +-27031 , +-28973 , +-30643 , +-4367 , +17687 , +15233 , +29787 , +25819 , +18317 , +1653 , +29195 , +5617 , +20545 , +8681 , +2741 , +8391 , +-5095 , +-9011 , +-18417 , +12927 , +13029 , +-17509 , +-10013 , +16607 , +-24995 , +-30287 , +6223 , +-1801 , +16271 , +-1233 , +-16529 , +-17879 , +2777 , +-2235 , +-5721 , +30151 , +29291 , +8973 , +4939 , +19245 , +1839 , +-15125 , +-1313 , +14427 , +22609 , +-26533 , +19663 , +-18683 , +-14037 , +-21935 , +4517 , +-25041 , +-27197 , +-10739 , +22207 , +8267 , +-16959 , +-1421 , +2445 , +15811 , +3559 , +32738 , +32067 , +-31709 , +11 , +18059 , +-27881 , +29089 , +-22131 , +-27307 , +-785 , +21821 , +28751 , +8481 , +-27995 , +855 , +-16851 , +-15179 , +12729 , +14025 , +27385 , +261 , +8073 , +-2433 , +5351 , +-8683 , +26117 , +-10359 , +8089 , +17485 , +8949 , +29625 , +-28285 , +26193 , +16799 , +-4931 , +-30737 , +21335 , +-26871 , +-11345 , +31089 , +18953 , +-10059 , +19765 , +-291 , +-7221 , +26059 , +-13805 , +23237 , +-20313 , +23265 , +11333 , +30575 , +23447 , +-6105 , +-20325 , +-27835 , +-4255 , +25127 , +29897 , +21463 , +21491 , +1269 , +-3575 , +30547 , +-25551 , +-7697 , +17447 , +-9099 , +15451 , +-4111 , +-27355 , +6403 , +-16167 , +-18931 , +-31415 , +22215 , +7575 , +-30527 , +-6209 , +-20727 , +11747 , +-11849 , +-21593 , +-17281 , +31927 , +23029 , +18867 , +-25655 , +-4701 , +3731 , +-29123 , +4715 , +24081 , +14335 , +6111 , +5191 , +-10447 , +-25689 , +25231 , +24459 , +26691 , +-32705 , +-18643 , +26421 , +16757 , +3175 , +-10327 , +17409 , +10037 , +-2055 , +-16497 , +-7191 , +-10731 , +1965 , +20769 , +12313 , +28437 , +19293 , +18169 , +24933 , +-31609 , +-26951 , +16917 , +15173 , +-8357 , +11391 , +19569 , +25933 , +-27389 , +5175 , +-22489 , +-25821 , +-31293 , +4703 , +17149 , +-5387 , +-9331 , +-17611 , +-22907 , +-17801 , +-24233 , +-26655 , +-17235 , +-13741 , +2801 , +-10703 , +16611 , +-4053 , +-31389 , +31443 , +13725 , +-16633 , +10175 , +-29173 , +13951 , +-10667 , +-25475 , +15083 , +-277 , +3929 , +6995 , +22795 , +-739 , +16685 , +-29815 , +22725 , +18881 , +-11465 , +26321 , +2533 , +-9207 , +-10725 , +29865 , +13545 , +21071 , +-9413 , +-2525 , +32435 , +10011 , +17065 , +23117 , +-28987 , +-21811 , +14243 , +4859 , +-4107 , +-26195 , +5001 , +-24021 , +-23635 , +-22913 , +24407 , +30677 , +-8297 , +-11869 , +11161 , +-18365 , +-4641 , +-6999 , +-2329 , +-32013 , +-22551 , +-5525 , +-9507 , +-11811 , +-31869 , +-1119 , +14221 , +-30369 , +-21851 , +14331 , +-27265 , +-12155 , +5539 , +17339 , +-2523 , +18925 , +8173 , +8653 , +19155 , +17683 , +-28871 , +-15781 , +19001 , +-32715 , +-31415 , +7655 , +23639 , +-27995 , +21535 , +13543 , +-11015 , +-26721 , +-21329 , +-13353 , +13483 , +12707 , +8221 , +15315 , +-22469 , +32337 , +27509 , +12209 , +32415 , +4795 , +-31265 , +-23147 , +-12929 , +-26559 , +-5795 , +3345 , +-989 , +8677 , +3581 , +-9809 , +27887 , +-11737 , +-28781 , +25115 , +-683 , +-5795 , +-2573 , +25515 , +-27559 , +-11129 , +-26713 , +639 , +30585 , +21677 , +-28889 , +-25065 , +-25037 , +22189 , +14995 , +21101 , +-17415 , +-27743 , +15847 , +32141 , +14497 , +-28247 , +32697 , +8615 , +-12439 , +7505 , +6249 , +31663 , +3175 , +-11431 , +-21533 , +-22929 , +24709 , +-11493 , +9675 , +-24029 , +1015 , +12637 , +20545 , +-26479 , +24371 , +17319 , +15633 , +-19045 , +12905 , +23585 , +-1681 , +27747 , +13179 , +3555 , +-31701 , +-32557 , +23163 , +-28201 , +32367 , +-21055 , +-27499 , +25607 , +-28945 , +16261 , +5525 , +-20101 , +-4183 , +31505 , +-39 , +-20849 , +7703 , +10625 , +-25913 , +28109 , +9711 , +8255 , +-12341 , +20293 , +32333 , +7571 , +9673 , +-24483 , +-3717 , +-11841 , +-3303 , +-31691 , +-30947 , +27797 , +-517 , +-17289 , +-5905 , +-30835 , +17301 , +27319 , +14845 , +-15257 , +7525 , +25149 , +-10155 , +-1999 , +32059 , +8809 , +329 , +15091 , +30645 , +4491 , +-12257 , +-19529 , +-10959 , +4147 , +-28855 , +31017 , +-7867 , +-753 , +-11227 , +24241 , +12479 , +16707 , +23851 , +1539 , +-27115 , +-707 , +10923 , +3391 , +-933 , +-4591 , +-13821 , +-20095 , +24777 , +-23731 , +19289 , +-16893 , +-23903 , +7513 , +-9777 , +8107 , +25013 , +27717 , +28225 , +-2773 , +-23723 , +26405 , +-27529 , +29587 , +30157 , +5099 , +-17697 , +30571 , +19039 , +-10303 , +1221 , +6735 , +15797 , +2007 , +5905 , +9473 , +1751 , +-3387 , +-10381 , +-18941 , +-15183 , +-1441 , +-27101 , +-2895 , +25081 , +-10737 , +-26085 , +10455 , +-14413 , +-27223 , +-30777 , +3785 , +-27099 , +31943 , +-26043 , +-16389 , +-25519 , +20127 , +10005 , +2077 , +-14871 , +8797 , +25693 , +32425 , +-18483 , +22517 , +-5743 , +15623 , +-11527 , +-14973 , +-7493 , +-30433 , +-10739 , +-19167 , +28195 , +19569 , +-10959 , +-13507 , +7323 , +-20567 , +-16223 , +28011 , +3103 , +-19773 , +12691 , +-15923 , +-27357 , +6551 , +-19007 , +-8485 , +571 , +-31499 , +20813 , +17349 , +19041 , +4159 , +28491 , +12613 , +17821 , +19329 , +-1871 , +-1285 , +21579 , +-5627 , +-13877 , +-5819 , +-3893 , +-657 , +15931 , +-15473 , +9151 , +5457 , +2925 , +-25799 , +21177 , +6985 , +8591 , +-4379 , +24961 , +17299 , +-13557 , +-16815 , +-25151 , +-5597 , +-15749 , +-22867 , +27969 , +-19389 , +30499 , +-24709 , +13987 , +-12643 , +14319 , +28639 , +31891 , +-24605 , +31965 , +29815 , +-23671 , +-14373 , +1799 , +-12873 , +23031 , +-15619 , +3851 , +-28989 , +6919 , +2697 , +14857 , +1215 , +-15407 , +2335 , +-29407 , +-20819 , +-19693 , +-17445 , +5985 , +-573 , +27503 , +22499 , +-30143 , +30277 , +12307 , +-13171 , +30881 , +18651 , +-27643 , +31211 , +29749 , +-919 , +29647 , +-3097 , +-15995 , +16487 , +20917 , +10719 , +-9625 , +32697 , +-29577 , +-13645 , +30449 , +19467 , +26753 , +15725 , +21747 , +14753 , +25509 , +1607 , +30193 , +17335 , +-13481 , +-4015 , +2969 , +20819 , +3423 , +-11391 , +-13639 , +-3421 , +-17649 , +20299 , +-9027 , +-4405 , +-18679 , +20931 , +10149 , +-17845 , +-31385 , +-15579 , +9331 , +28107 , +13945 , +11771 , +-969 , +21881 , +-7167 , +-17491 , +9073 , +-20259 , +14567 , +23965 , +11291 , +-17607 , +-1169 , +31421 , +1559 , +-27563 , +4597 , +-1625 , +26151 , +8675 , +-1501 , +-203 , +-29845 , +-32433 , +10923 , +14749 , +6997 , +8727 , +22397 , +4097 , +19487 , +8361 , +4221 , +-29045 , +5577 , +-1607 , +-19773 , +26381 , +-24181 , +11795 , +9285 , +-8695 , +-20529 , +-4359 , +21025 , +-939 , +11437 , +27389 , +-5819 , +-8913 , +-21797 , +-11441 , +16815 , +28889 , +-723 , +-20063 , +-3037 , +-29785 , +-22905 , +-22921 , +4713 , +-26207 , +22619 , +10243 , +31221 , +-12647 , +14233 , +22907 , +14645 , +10943 , +8239 , +-27921 , +32563 , +11195 , +-24835 , +-20057 , +3553 , +-32181 , +-9655 , +-14089 , +-22849 , +-23475 , +8387 , +19349 , +27171 , +-27803 , +22257 , +17779 , +-24349 , +-20465 , +-1237 , +-16865 , +-5991 , +-3785 , +-2025 , +-9333 , +14927 , +22609 , +-617 , +-8849 , +-15417 , +-1551 , +-26545 , +-30427 , +2849 , +29413 , +-16493 , +7669 , +21789 , +8653 , +4575 , +27125 , +-14891 , +-725 , +30675 , +5987 , +13295 , +24073 , +26025 , +-13705 , +9817 , +-26873 , +29489 , +10173 , +-2947 , +-20495 , +-32191 , +23277 , +-32515 , +7651 , +11187 , +13893 , +-30997 , +-12331 , +-21795 , +-32159 , +-3717 , +26551 , +-125 , +-26993 , +13893 , +-2037 , +32347 , +-11865 , +10741 , +7677 , +-30729 , +2925 , +18309 , +-12297 , +-25019 , +-27045 , +-7691 , +-18243 , +-28535 , +-5631 , +14469 , +30465 , +-2613 , +-29221 , +-6803 , +-26239 , +-21027 , +23727 , +-24819 , +-20583 , +-24381 , +-18345 , +-15435 , +18015 , +29885 , +-14809 , +-22581 , +10809 , +29359 , +19391 , +7825 , +-15117 , +20769 , +17505 , +13651 , +-4001 , +7605 , +-14643 , +-26327 , +5475 , +-735 , +21401 , +-24797 , +-4201 , +-1627 , +9223 , +26383 , +-12965 , +-26621 , +-28327 , +4259 , +-23441 , +27383 , +11445 , +31549 , +-11505 , +23857 , +-24723 , +-30691 , +-6781 , +-5685 , +-5143 , +22293 , +14397 , +-1215 , +9967 , +30153 , +-12689 , +-22295 , +16769 , +31073 , +13609 , +-29973 , +-1223 , +-1339 , +-13599 , +-9025 , +-27363 , +27987 , +17311 , +9751 , +23799 , +-14313 , +-15993 , +-23961 , +-22231 , +31109 , +23029 , +7887 , +23827 , +-25173 , +24345 , +-31073 , +-29223 , +-4363 , +17929 , +-10683 , +24519 , +26969 , +-32423 , +-21297 , +-19419 , +6163 , +10301 , +13273 , +-16497 , +1501 , +-15855 , +-27127 , +8401 , +-14421 , +3711 , +-17399 , +-28619 , +-26147 , +8719 , +-30719 , +-16537 , +-30727 , +-20669 , +18309 , +-32315 , +-26905 , +-11219 , +-27623 , +-10949 , +27041 , +17543 , +23073 , +-7271 , +22641 , +10317 , +15961 , +-27543 , +29353 , +-31025 , +6613 , +-14517 , +25305 , +-27051 , +-15247 , +-12593 , +-21115 , +-14295 , +-6711 , +17351 , +16995 , +-5831 , +1207 , +-14051 , +-10225 , +12073 , +-29369 , +-10185 , +2623 , +-30225 , +1325 , +11715 , +-19833 , +4585 , +9921 , +-4331 , +29569 , +-5511 , +6775 , +8189 , +-4457 , +28947 , +-31019 , +-32483 , +-25559 , +4319 , +-20759 , +28363 , +-16815 , +-27953 , +22343 , +-10151 , +26139 , +16947 , +-22151 , +-6149 , +817 , +-16939 , +-12799 , +29463 , +30243 , +-12915 , +29895 , +-13537 , +7447 , +5215 , +1047 , +1771 , +-11525 , +-2291 , +-23015 , +23697 , +22859 , +-28877 , +-4921 , +-23625 , +9277 , +733 , +17505 , +-26509 , +385 , +6303 , +-5007 , +-2401 , +-28303 , +24623 , +-20681 , +1457 , +2771 , +-14473 , +4005 , +-21229 , +16645 , +-3017 , +9689 , +-22273 , +25793 , +14871 , +-7661 , +-2101 , +30541 , +-31429 , +-4561 , +6101 , +-6091 , +4453 , +-6759 , +11717 , +21895 , +17793 , +7113 , +-21641 , +-6525 , +-29749 , +-22213 , +-28857 , +14553 , +32347 , +-2337 , +-11281 , +22627 , +16449 , +-32735 , +10463 , +-18093 , +23329 , +851 , +-29935 , +-21259 , +-1725 , +-10075 , +-10649 , +18663 , +-11213 , +-22617 , +-6279 , +14535 , +-20523 , +13117 , +26105 , +29301 , +-17925 , +29713 , +-12409 , +17607 , +-22909 , +-18031 , +-9471 , +-18237 , +-8215 , +2405 , +-13211 , +-17071 , +-23453 , +30057 , +-11991 , +5501 , +26487 , +-24541 , +-759 , +-32475 , +20497 , +10171 , +-149 , +6203 , +11043 , +12149 , +10541 , +20591 , +-21837 , +-16477 , +-9467 , +-23177 , +18809 , +13351 , +-2991 , +23487 , +-21771 , +29029 , +23163 , +21917 , +-12281 , +6069 , +12483 , +29455 , +-2037 , +28009 , +-10079 , +29685 , +-31127 , +14141 , +21141 , +-11071 , +-15181 , +14153 , +6025 , +-25163 , +-9923 , +-30075 , +673 , +-25443 , +-13775 , +-25413 , +25493 , +255 , +-6867 , +-5377 , +-11895 , +-11559 , +25427 , +19621 , +-10647 , +15319 , +-24089 , +-1343 , +2747 , +6923 , +-14485 , +3605 , +-17929 , +-9433 , +11561 , +-21619 , +-22683 , +821 , +25945 , +-26821 , +2931 , +31179 , +13743 , +26057 , +24965 , +-3389 , +24191 , +1139 , +7771 , +32635 , +-31163 , +-12411 , +-6433 , +-18043 , +8651 , +-4283 , +24441 , +32738 , +-20295 , +13177 , +11257 , +-16715 , +9905 , +9561 , +14299 , +14729 , +-10011 , +-30715 , +-8407 , +-12299 , +-14287 , +-125 , +4053 , +13543 , +-24661 , +5679 , +-1141 , +-28593 , +16331 , +22719 , +29193 , +859 , +11763 , +-16213 , +31743 , +-30923 , +-16241 , +9521 , +20059 , +7723 , +24491 , +-5427 , +11823 , +-12417 , +-19953 , +-22235 , +23805 , +25989 , +3791 , +-107 , +-23151 , +26223 , +2923 , +20495 , +-24221 , +16253 , +32353 , +-26453 , +20063 , +6833 , +-12729 , +9099 , +3405 , +22289 , +-6811 , +17761 , +-24421 , +6997 , +-24115 , +-7589 , +17345 , +-1241 , +6639 , +-3669 , +29455 , +9943 , +-29259 , +-18579 , +31757 , +7567 , +23575 , +-4821 , +28239 , +23061 , +-10951 , +-28461 , +-31541 , +-3589 , +16639 , +-28119 , +-24651 , +-24741 , +-3551 , +5833 , +-6443 , +11531 , +-16947 , +-29547 , +11363 , +-17061 , +-20553 , +17075 , +10327 , +-7355 , +21171 , +-16123 , +9285 , +1581 , +26065 , +-27107 , +12219 , +2069 , +21995 , +-11333 , +29967 , +-22955 , +21451 , +-3653 , +-14661 , +-29487 , +24245 , +20381 , +-711 , +-27717 , +7051 , +3177 , +15701 , +8121 , +-12199 , +27961 , +-16633 , +7345 , +23675 , +-30167 , +11471 , +-29967 , +-31447 , +31179 , +13189 , +5873 , +28307 , +-19671 , +23225 , +-19577 , +-26243 , +-8655 , +-17021 , +-20833 , +15695 , +-13637 , +-17433 , +14449 , +22197 , +-14861 , +15519 , +-10943 , +17075 , +1627 , +-26757 , +-20083 , +15931 , +26175 , +-16327 , +20683 , +-23989 , +9389 , +-13863 , +-29025 , +13441 , +-6931 , +23165 , +27285 , +25647 , +-23427 , +10163 , +-27049 , +-13317 , +-8321 , +4957 , +15971 , +-12297 , +-25665 , +253 , +1353 , +-20433 , +-28133 , +-1133 , +-22179 , +-6197 , +11917 , +-15369 , +19701 , +12451 , +-24941 , +24485 , +-9961 , +855 , +-22995 , +-16345 , +29373 , +-5143 , +29531 , +6875 , +31367 , +-30001 , +10251 , +2395 , +3827 , +-25961 , +21141 , +2633 , +-30445 , +-11791 , +3255 , +31405 , +-5173 , +-1455 , +-1783 , +-24631 , +-17023 , +4867 , +-10511 , +-9863 , +17505 , +-10049 , +-6875 , +-27393 , +-25339 , +-30259 , +-13669 , +6245 , +-23619 , +16017 , +15875 , +-16813 , +10297 , +-20823 , +9153 , +-17821 , +25547 , +-17791 , +23139 , +-517 , +10781 , +-28305 , +-4713 , +21927 , +-13213 , +-13235 , +-6231 , +22255 , +10011 , +21641 , +31095 , +14001 , +-11711 , +28609 , +-20247 , +8179 , +-5113 , +-14369 , +30183 , +9031 , +30221 , +-14421 , +1497 , +22163 , +-17127 , +9193 , +-23149 , +15735 , +-15535 , +-5913 , +-15913 , +4639 , +9457 , +-7007 , +13899 , +1691 , +28549 , +-15021 , +-3345 , +5813 , +25501 , +-15219 , +-18417 , +-32177 , +6407 , +14039 , +8397 , +-30667 , +32139 , +-10309 , +-19455 , +31097 , +9757 , +10855 , +13257 , +-17077 , +-5481 , +-14657 , +-7315 , +-8885 , +17395 , +-5383 , +-1051 , +12905 , +-6911 , +10677 , +1735 , +19001 , +-31327 , +-29553 , +22471 , +-25397 , +22645 , +835 , +23721 , +-21757 , +8993 , +30515 , +-1089 , +7539 , +28929 , +23443 , +-18215 , +-1105 , +-10147 , +4595 , +-10043 , +-27605 , +-13789 , +-1187 , +15169 , +11403 , +-7135 , +-29207 , +9081 , +4743 , +15803 , +18141 , +-22793 , +9521 , +-22749 , +-11977 , +-1245 , +28385 , +21267 , +14549 , +22837 , +-6275 , +-7423 , +-32253 , +-20303 , +-2213 , +19931 , +32151 , +-8099 , +-11625 , +-26305 , +12673 , +-21059 , +17635 , +-8913 , +-21005 , +13055 , +1515 , +-30131 , +-22809 , +-1147 , +11815 , +27279 , +-21945 , +-31027 , +-7117 , +21631 , +19063 , +27121 , +-9561 , +2279 , +5497 , +-14431 , +-18835 , +13077 , +-20359 , +22163 , +-2655 , +903 , +-4109 , +-20863 , +28383 , +23857 , +17471 , +5023 , +291 , +3369 , +21167 , +30871 , +-29671 , +1253 , +4897 , +-4359 , +-14083 , +3823 , +18981 , +15927 , +7153 , +-2525 , +-18559 , +-9947 , +-2611 , +-26781 , +-11941 , +-5665 , +-8573 , +-10803 , +25541 , +-21421 , +-16397 , +-5771 , +-4899 , +-12495 , +-30405 , +165 , +3423 , +4959 , +-15717 , +-21631 , +-6719 , +-7689 , +10693 , +2649 , +-18487 , +4291 , +-4425 , +13897 , +-23387 , +-29399 , +-22249 , +-9087 , +-8317 , +9643 , +-25085 , +-31755 , +11435 , +10719 , +28273 , +30105 , +1301 , +6373 , +-14847 , +-16617 , +13953 , +5727 , +8793 , +18439 , +22545 , +24041 , +19195 , +29097 , +-5283 , +27923 , +-28257 , +14619 , +-32241 , +7127 , +29445 , +21517 , +-16391 , +23439 , +-20393 , +16391 , +-28241 , +-11147 , +30969 , +-17395 , +28571 , +6545 , +-17181 , +-23317 , +1435 , +-21707 , +16251 , +-21541 , +5905 , +32762 , +-32023 , +-8245 , +-2173 , +19503 , +9203 , +-32497 , +28589 , +16343 , +-16809 , +6039 , +26399 , +29473 , +-3689 , +17325 , +10831 , +-18085 , +-24989 , +16677 , +-23245 , +4723 , +-2975 , +-27363 , +27227 , +29411 , +26765 , +-8655 , +-8571 , +6709 , +11281 , +16177 , +24763 , +12275 , +15259 , +23649 , +-14619 , +-8415 , +-24779 , +25379 , +1767 , +-22475 , +-3427 , +5187 , +25647 , +8595 , +-12771 , +18583 , +-1575 , +-8579 , +10215 , +-6069 , +-1727 , +-19307 , +17895 , +-13165 , +29977 , +6089 , +22555 , +-31781 , +4357 , +-15147 , +21363 , +28811 , +28081 , +29241 , +9503 , +14901 , +-22165 , +-16467 , +-10643 , +2391 , +-13001 , +7197 , +-18143 , +-31351 , +32363 , +-9699 , +13383 , +3643 , +-13113 , +10981 , +18839 , +9707 , +29959 , +14281 , +27453 , +-30753 , +28679 , +4655 , +-17855 , +-8101 , +9801 , +-19963 , +17745 , +-24745 , +8225 , +-17729 , +24613 , +-8773 , +-30145 , +16071 , +-21681 , +-13031 , +26317 , +14717 , +-7021 , +-22051 , +-15611 , +-2131 , +6087 , +-22519 , +-14009 , +9859 , +18465 , +-11661 , +1975 , +-16125 , +10773 , +21619 , +-15533 , +-27641 , +1453 , +9759 , +-20605 , +-28491 , +22875 , +-27899 , +-7619 , +-23185 , +21853 , +-27807 , +23703 , +21851 , +-14457 , +28633 , +-37 , +-14775 , +-28765 , +-22611 , +18219 , +32055 , +13385 , +-28301 , +-25205 , +-32443 , +-20429 , +-20907 , +-22399 , +7471 , +4123 , +10173 , +24367 , +-2239 , +-1779 , +28567 , +17889 , +-18477 , +-20669 , +31493 , +-22987 , +-2497 , +-19079 , +-28775 , +7071 , +-23461 , +-25399 , +6921 , +19601 , +-20371 , +7425 , +-29335 , +10255 , +5543 , +3455 , +-21017 , +32705 , +4893 , +22145 , +25085 , +22163 , +-16065 , +29443 , +24365 , +-17463 , +-16947 , +-25835 , +-16589 , +-30059 , +9809 , +11957 , +-4407 , +-6601 , +-26339 , +31013 , +-4399 , +-13689 , +29879 , +25793 , +24599 , +-30435 , +3547 , +14175 , +20867 , +-29985 , +5103 , +-4325 , +18647 , +11803 , +-9221 , +22457 , +32223 , +6431 , +-13789 , +28795 , +-16333 , +-9901 , +-28263 , +14963 , +-155 , +9935 , +-31969 , +-30875 , +-4673 , +-23437 , +-24073 , +-7917 , +-19079 , +29825 , +-18593 , +8483 , +14451 , +31153 , +7299 , +-11927 , +-11671 , +-25395 , +29439 , +-4919 , +5553 , +-4409 , +975 , +6283 , +31339 , +-173 , +-823 , +-4559 , +30785 , +16381 , +17559 , +28119 , +667 , +-13379 , +7469 , +12543 , +-8361 , +27419 , +19649 , +30197 , +-12285 , +11451 , +1345 , +-25699 , +1421 , +27259 , +16981 , +9681 , +-10613 , +-27897 , +-10809 , +-7619 , +12261 , +-28681 , +-9591 , +17831 , +-18417 , +8289 , +-14811 , +-26151 , +7365 , +-11 , +-12105 , +5105 , +-31929 , +12945 , +-5269 , +27447 , +-27901 , +19551 , +-665 , +2167 , +4827 , +3689 , +-24751 , +26079 , +-28457 , +12205 , +3391 , +-18615 , +3163 , +-21825 , +-30923 , +29475 , +6883 , +26587 , +-10217 , +-11331 , +32569 , +-25737 , +15139 , +-5855 , +-21711 , +-20117 , +22505 , +21361 , +9175 , +7289 , +-29497 , +15801 , +16433 , +-7571 , +16345 , +-20147 , +14967 , +15541 , +28283 , +-9833 , +3007 , +9589 , +13109 , +20607 , +2631 , +10533 , +31293 , +2863 , +-15843 , +21665 , +-25493 , +-131 , +95 , +-26681 , +6325 , +6585 , +-30477 , +29841 , +9245 , +-25849 , +28347 , +21159 , +18483 , +30777 , +-31149 , +20343 , +-14325 , +-11997 , +-5311 , +-7467 , +945 , +6265 , +4023 , +12293 , +-28125 , +1057 , +20159 , +23399 , +18891 , +-8689 , +30977 , +-17287 , +-4235 , +19863 , +21483 , +17537 , +-15413 , +12625 , +-31877 , +-3689 , +-22717 , +-24221 , +-10653 , +-22965 , +3231 , +-19867 , +27861 , +15789 , +29163 , +4269 , +-20051 , +13299 , +-26655 , +3123 , +-25045 , +-17523 , +12283 , +11491 , +16437 , +-26953 , +14545 , +-6287 , +-1281 , +-29289 , +-16091 , +-30021 , +31313 , +-10029 , +18773 , +-615 , +-12231 , +22701 , +31561 , +25909 , +-19135 , +-3951 , +28923 , +19435 , +25387 , +-8387 , +16743 , +24729 , +553 , +27461 , +3071 , +26229 , +8335 , +-17349 , +15019 , +28019 , +11543 , +14403 , +12863 , +-5367 , +27529 , +15909 , +10603 , +-13413 , +23553 , +-27665 , +24129 , +5185 , +3231 , +25089 , +25121 , +11567 , +19907 , +4783 , +-19401 , +27775 , +16581 , +-4521 , +25201 , +-1641 , +14629 , +-13321 , +-5897 , +-24335 , +26707 , +-20927 , +2087 , +-20351 , +19413 , +-23235 , +-14077 , +29829 , +22029 , +-13223 , +26679 , +27875 , +-13977 , +-17149 , +24449 , +-11527 , +15899 , +19907 , +17851 , +-30723 , +-13735 , +-2607 , +-17087 , +975 , +17679 , +-21203 , +10489 , +23637 , +-25837 , +-24263 , +24509 , +-685 , +-20763 , +-27187 , +5723 , +10427 , +-17695 , +19155 , +14353 , +-10347 , +-20997 , +-16803 , +-6793 , +4933 , +31479 , +-23743 , +20997 , +24433 , +-11747 , +-7131 , +14343 , +19539 , +15733 , +-29911 , +6925 , +-13941 , +6013 , +-6673 , +4335 , +20871 , +21601 , +15933 , +18749 , +-31411 , +-27211 , +-239 , +2873 , +20693 , +-32601 , +-25033 , +25173 , +12265 , +-12605 , +8807 , +12573 , +-21645 , +4383 , +-25129 , +-7491 , +-22693 , +-25065 , +30039 , +29427 , +-26403 , +-24187 , +-13339 , +1159 , +15715 , +-14467 , +-5429 , +-16831 , +-5669 , +31103 , +-461 , +9831 , +2703 , +9779 , +-453 , +-19279 , +-5251 , +-29795 , +7321 , +-11583 , +24881 , +31703 , +-29021 , +793 , +27161 , +5201 , +3063 , +26265 , +24675 , +-8329 , +-9849 , +22643 , +-11185 , +-9991 , +-18121 , +22689 , +-22777 , +-13183 , +-27149 , +-797 , +32257 , +1759 , +17481 , +8239 , +9931 , +-11825 , +12157 , +2227 , +867 , +-19923 , +19239 , +-17339 , +5917 , +-8025 , +8515 , +15195 , +-13333 , +-2823 , +21711 , +-9591 , +2107 , +15277 , +28901 , +29299 , +-21163 , +-20925 , +23629 , +-25013 , +5673 , +1527 , +18837 , +-16191 , +-20821 , +-7953 , +31665 , +1923 , +15277 , +29179 , +-18681 , +9519 , +-5319 , +-19765 , +-18671 , +-1585 , +-15011 , +-28513 , +-32651 , +-7727 , +-27241 , +2957 , +-6255 , +-7301 , +-7019 , +-16341 , +9125 , +29413 , +6819 , +-11311 , +-14759 , +1139 , +25205 , +-17585 , +-4125 , +9677 , +25733 , +-11233 , +6041 , +21841 , +29417 , +18471 , +16647 , +20499 , +15787 , +13285 , +-2679 , +3667 , +-22621 , +-30925 , +-9623 , +9839 , +-11317 , +-26505 , +15213 , +-12703 , +797 , +-7587 , +25075 , +13241 , +23271 , +-7149 , +4235 , +25101 , +11165 , +-25607 , +-1267 , +28661 , +-12223 , +-27423 , +-27853 , +10891 , +-16853 , +-577 , +429 , +-2221 , +-8853 , +-15381 , +-23617 , +9405 , +-15973 , +10193 , +-6829 , +24865 , +-9413 , +-15317 , +-12399 , +-28629 , +14727 , +32697 , +9215 , +-18723 , +-2865 , +24955 , +23569 , +13829 , +-9901 , +-16537 , +25921 , +2861 , +27279 , +-16477 , +29101 , +20513 , +-10457 , +-23497 , +-19155 , +-20261 , +-2775 , +-9905 , +26339 , +4095 , +-8455 , +15849 , +-8355 , +4569 , +18581 , +-24809 , +11055 , +-14903 , +9601 , +-8791 , +-5637 , +9797 , +-18673 , +-18825 , +-11749 , +-22707 , +-25789 , +-23289 , +-20305 , +-29855 , +-3039 , +-10027 , +15929 , +14083 , +16267 , +-19203 , +-24655 , +15003 , +-2153 , +-11649 , +-5087 , +19209 , +-27799 , +-787 , +-28995 , +-8057 , +137 , +8619 , +-8843 , +-19413 , +11449 , +-22111 , +-17387 , +-11299 , +-18347 , +13687 , +-23589 , +-31531 , +26911 , +13387 , +-6261 , +-21371 , +30115 , +19687 , +-29689 , +-2017 , +16645 , +4483 , +-29329 , +31367 , +-24735 , +-2581 , +-5969 , +-1845 , +15005 , +75 , +16799 , +-25319 , +12231 , +11353 , +32149 , +18495 , +31971 , +-1777 , +10881 , +14743 , +22353 , +6379 , +2689 , +17803 , +665 , +-17249 , +-25601 , +21125 , +16329 , +28747 , +-2491 , +21607 , +-4791 , +823 , +-11631 , +32397 , +-4293 , +29189 , +6585 , +-7117 , +-1977 , +19317 , +-12749 , +16259 , +19199 , +-30833 , +-21827 , +5879 , +2989 , +18789 , +19817 , +-1693 , +15027 , +-31931 , +18235 , +2147 , +-4257 , +-2697 , +-6079 , +-30381 , +-5313 , +32623 , +8229 , +-19251 , +7685 , +15241 , +19277 , +31899 , +12753 , +23867 , +17519 , +-32715 , +-18411 , +18903 , +-27989 , +-6223 , +3809 , +-7235 , +3103 , +23875 , +-26937 , +-32754 , +-15103 , +-8911 , +20779 , +32499 , +-23749 , +-27575 , +32543 , +-445 , +28285 , +-31523 , +22713 , +-24891 , +-19243 , +10811 , +29929 , +-11287 , +23503 , +-11613 , +-1577 , +-18947 , +13829 , +-6211 , +11701 , +-12571 , +30007 , +-8811 , +-32740 , +-9899 , +20715 , +19 , +-23583 , +-5501 , +-18055 , +-10513 , +-11927 , +-409 , +28593 , +22575 , +-13939 , +24175 , +22755 , +-24297 , +-20251 , +-9541 , +26503 , +28071 , +23461 , +19913 , +-4025 , +1685 , +8699 , +25277 , +-15451 , +-8771 , +-11045 , +5647 , +-7163 , +-28385 , +-5277 , +-5947 , +12367 , +-29609 , +-32597 , +15915 , +-9471 , +145 , +14879 , +-9201 , +1483 , +27397 , +-20905 , +1391 , +22949 , +25069 , +25713 , +10177 , +-3223 , +-8193 , +1001 , +-28009 , +31977 , +-14751 , +-13077 , +12777 , +-13691 , +-13019 , +-3787 , +-15679 , +-10937 , +-26049 , +-6811 , +31357 , +27003 , +14077 , +17109 , +-26501 , +25029 , +-25597 , +20985 , +-9637 , +-14663 , +-29765 , +-10963 , +19123 , +-21775 , +29521 , +11281 , +25159 , +7085 , +-30159 , +26469 , +-3133 , +-545 , +-6155 , +25947 , +-9743 , +12239 , +-14109 , +-29069 , +-8081 , +-14549 , +-18205 , +19151 , +-8467 , +-15453 , +-8967 , +-14321 , +32481 , +3579 , +4919 , +10153 , +-23621 , +7085 , +8511 , +-21057 , +-4697 , +3835 , +-22221 , +2163 , +20159 , +-21631 , +7471 , +18377 , +10943 , +-2209 , +26949 , +-25095 , +-1721 , +-8007 , +-29717 , +-32699 , +-7543 , +-16413 , +-11009 , +16467 , +20103 , +3569 , +823 , +-18933 , +-8499 , +10191 , +-2019 , +4577 , +-13663 , +30167 , +14979 , +28605 , +5567 , +-12307 , +-125 , +16967 , +-26217 , +30231 , +-3607 , +11975 , +22777 , +30099 , +28733 , +29045 , +5719 , +-11665 , +31017 , +25179 , +-23429 , +19871 , +-385 , +12963 , +-5703 , +8091 , +-10583 , +31349 , +3505 , +32627 , +1187 , +-20659 , +-13957 , +20069 , +-29065 , +6871 , +21097 , +-16389 , +-26065 , +27197 , +-10433 , +22175 , +2383 , +28171 , +2017 , +3249 , +19151 , +8831 , +-24681 , +545 , +-25713 , +-26523 , +27065 , +-31091 , +27989 , +-10645 , +-18187 , +-10291 , +11325 , +19199 , +-14085 , +27925 , +6845 , +-6495 , +697 , +9865 , +31755 , +30397 , +-25833 , +14677 , +-15061 , +22789 , +-31703 , +12359 , +3153 , +8007 , +10473 , +-10011 , +28395 , +15303 , +-5263 , +29953 , +-23027 , +19987 , +-8783 , +2269 , +-32401 , +10335 , +-21335 , +7607 , +-32537 , +9563 , +13851 , +-12059 , +17495 , +-6519 , +-16179 , +-30863 , +2607 , +4895 , +20279 , +7723 , +-2973 , +12111 , +1219 , +-4543 , +19421 , +9261 , +5503 , +32351 , +31359 , +-28675 , +14425 , +14399 , +-3183 , +30485 , +5077 , +-1343 , +-15679 , +27949 , +-25275 , +-8053 , +-1645 , +-12491 , +-7551 , +4887 , +-19613 , +9657 , +13861 , +591 , +-6189 , +18349 , +13881 , +-10069 , +-15415 , +21963 , +-23171 , +-31813 , +-16153 , +9833 , +-28909 , +10577 , +13183 , +14803 , +-21315 , +24841 , +-30961 , +-12515 , +-30829 , +2665 , +-7881 , +12675 , +19257 , +6009 , +25395 , +-10687 , +-15457 , +9175 , +-15919 , +25311 , +32049 , +12371 , +27621 , +13337 , +32653 , +23301 , +-2227 , +32043 , +-25911 , +-5145 , +3163 , +-26705 , +-16617 , +-29205 , +-30761 , +-25611 , +22285 , +3217 , +2931 , +-9769 , +7259 , +28163 , +-19259 , +18965 , +24311 , +-15953 , +12983 , +-28629 , +14053 , +31573 , +-3697 , +-23381 , +-26527 , +-19797 , +-27305 , +-16369 , +-15707 , +8043 , +31453 , +-25061 , +275 , +10741 , +30507 , +-20051 , +14071 , +-6053 , +-29319 , +24853 , +11707 , +24581 , +-11345 , +-7435 , +7581 , +-7231 , +15703 , +-11375 , +26861 , +-6561 , +-31473 , +6823 , +447 , +6595 , +-4975 , +14797 , +29223 , +12935 , +2841 , +-25791 , +-273 , +10253 , +25197 , +-1715 , +-9007 , +18707 , +-3515 , +30225 , +-4055 , +-813 , +-32171 , +31717 , +3893 , +-30569 , +-9549 , +-471 , +16075 , +-20013 , +-23843 , +12967 , +-7797 , +-27465 , +7979 , +23395 , +20897 , +-30897 , +-31549 , +-18189 , +-8975 , +24857 , +7195 , +15713 , +-25635 , +-231 , +-5655 , +6003 , +6765 , +23665 , +5789 , +-20849 , +19479 , +6017 , +-13221 , +10001 , +-15893 , +-17547 , +-15505 , +1823 , +-25773 , +-22937 , +13643 , +5127 , +10563 , +-7191 , +28153 , +13 , +-17415 , +-11219 , +-19433 , +209 , +-27855 , +-2159 , +-16563 , +-6629 , +26843 , +-18751 , +30019 , +-14023 , +-29093 , +32577 , +9503 , +-4907 , +5173 , +3223 , +-1671 , +-6835 , +-2993 , +13777 , +-10031 , +-24181 , +-18779 , +6061 , +27791 , +27745 , +-30589 , +-3293 , +-31123 , +32345 , +15929 , +-26489 , +-25475 , +14357 , +14165 , +-18659 , +-27747 , +-25309 , +-25251 , +-5837 , +-28565 , +10067 , +-2807 , +-11085 , +1725 , +-30061 , +31217 , +14403 , +-16479 , +-32443 , +15567 , +15579 , +3533 , +14619 , +31795 , +-7209 , +-5993 , +30821 , +12219 , +-5737 , +9587 , +5109 , +15821 , +-2927 , +-30747 , +-12943 , +21453 , +26863 , +-8195 , +12839 , +-10029 , +-18271 , +-4273 , +-28051 , +-3351 , +-30731 , +19559 , +-22151 , +5819 , +32439 , +-827 , +3501 , +6619 , +7617 , +-689 , +381 , +16235 , +28949 , +29013 , +-17213 , +14173 , +-2443 , +-20485 , +-14703 , +-30679 , +-28549 , +-6083 , +30609 , +23305 , +-8649 , +-27809 , +15573 , +8873 , +-12487 , +28131 , +-19653 , +5223 , +-13255 , +12045 , +13111 , +-5115 , +19491 , +-18737 , +-6863 , +-3611 , +11701 , +-5559 , +-2459 , +-17475 , +-21099 , +-2375 , +1579 , +-24617 , +20715 , +13049 , +25565 , +21181 , +-25483 , +22393 , +13607 , +-22661 , +-4061 , +17581 , +7393 , +-5549 , +24365 , +4115 , +31339 , +-12809 , +-9043 , +-28769 , +-9859 , +25405 , +-27467 , +7093 , +-21883 , +4955 , +-13851 , +-16469 , +-9343 , +5275 , +3977 , +-28495 , +26959 , +20889 , +14377 , +25435 , +-32375 , +15095 , +-12117 , +-26747 , +19683 , +31633 , +32740 , +13021 , +-1543 , +1857 , +8877 , +465 , +8365 , +31753 , +-893 , +-2293 , +5627 , +19925 , +-11105 , +-32411 , +18519 , +-19283 , +22403 , +4195 , +15489 , +-10893 , +-27361 , +32561 , +17115 , +7445 , +-3231 , +-25073 , +32069 , +17991 , +27987 , +-28077 , +19831 , +443 , +30377 , +17629 , +-15411 , +-18209 , +23527 , +-26867 , +9905 , +25353 , +30443 , +-27069 , +10849 , +-6855 , +4111 , +26061 , +-3753 , +-2995 , +17341 , +5989 , +27925 , +-3659 , +-15223 , +10789 , +14209 , +-17737 , +-11837 , +-6137 , +31939 , +-7651 , +15001 , +22995 , +3471 , +19563 , +-14939 , +2459 , +12813 , +-22879 , +-10997 , +19383 , +21797 , +-20629 , +-24813 , +17975 , +8287 , +-13603 , +-11465 , +28383 , +8245 , +-10073 , +965 , +-18531 , +-30483 , +-15149 , +-21515 , +8575 , +13299 , +-13579 , +10879 , +-4557 , +28079 , +-7189 , +-30545 , +10227 , +-21537 , +22031 , +26117 , +-18423 , +-15255 , +-8203 , +-8115 , +-15425 , +-17219 , +30111 , +-12245 , +-30761 , +-13913 , +2097 , +12869 , +27275 , +-26719 , +20529 , +5323 , +31741 , +29625 , +4667 , +-7787 , +7471 , +27869 , +-10695 , +23745 , +1411 , +1467 , +-30435 , +12227 , +24231 , +-28909 , +279 , +22779 , +12055 , +-15727 , +-9139 , +22487 , +-13549 , +-18903 , +-19951 , +28007 , +-31725 , +-16411 , +3745 , +-13973 , +20161 , +25163 , +12629 , +-1027 , +-26763 , +-9943 , +1373 , +-31847 , +-731 , +24307 , +19703 , +-12353 , +10981 , +-15719 , +30505 , +-28667 , +-30757 , +26079 , +6133 , +-22603 , +-2635 , +15413 , +31511 , +-25121 , +21925 , +-7659 , +18741 , +-7695 , +3033 , +25803 , +-18527 , +-17191 , +14705 , +-11549 , +14983 , +18059 , +-6923 , +11501 , +12713 , +14383 , +-13999 , +-12573 , +-30819 , +-3419 , +845 , +-5643 , +-17543 , +-28247 , +21889 , +9967 , +19735 , +25445 , +15057 , +2311 , +963 , +-25455 , +32613 , +10547 , +1915 , +-24321 , +-26597 , +-7669 , +17567 , +-18243 , +28809 , +-31719 , +4661 , +-30295 , +-6293 , +-21833 , +-28015 , +11657 , +-20063 , +-13989 , +-14693 , +15525 , +-9305 , +-30333 , +-13439 , +-23333 , +-24183 , +4343 , +15085 , +-23237 , +-10913 , +-14157 , +9667 , +-14819 , +-29629 , +-17357 , +-24241 , +9661 , +18891 , +10579 , +24333 , +-3769 , +25083 , +22687 , +18127 , +25217 , +-13879 , +22067 , +-29821 , +6613 , +3591 , +-23793 , +12899 , +11501 , +-22299 , +30447 , +-31569 , +-15925 , +28129 , +-21851 , +25577 , +-29083 , +17483 , +-7445 , +-1917 , +5301 , +-6099 , +5061 , +-19675 , +-3237 , +-5677 , +-2991 , +6233 , +8873 , +-23625 , +31521 , +20167 , +30281 , +24319 , +-1261 , +-6159 , +15173 , +24179 , +-1875 , +-9373 , +19117 , +2039 , +20461 , +11381 , +26795 , +-7043 , +-15703 , +12921 , +18451 , +-20857 , +-30879 , +-1161 , +2697 , +10007 , +-3941 , +-16021 , +-27381 , +-5847 , +-15175 , +-5645 , +-28397 , +-3155 , +24145 , +-30581 , +29229 , +8701 , +11529 , +-9401 , +22535 , +19157 , +-20763 , +-17907 , +9497 , +15819 , +31275 , +28737 , +-24151 , +22345 , +28595 , +-1779 , +887 , +-7421 , +-21055 , +5647 , +-20025 , +1261 , +23393 , +14483 , +-25093 , +24763 , +-7111 , +-19125 , +2229 , +14285 , +-17183 , +14987 , +2909 , +13747 , +18369 , +251 , +-16819 , +-23779 , +-3481 , +-20787 , +21339 , +14165 , +9049 , +25987 , +-775 , +16439 , +4211 , +-3563 , +-1599 , +22701 , +5567 , +-26695 , +-25439 , +26017 , +-23349 , +27915 , +-22177 , +4471 , +25727 , +-15405 , +-8773 , +32263 , +-26243 , +-27847 , +-245 , +25873 , +28399 , +23671 , +17479 , +24377 , +14307 , +-32233 , +29865 , +-30335 , +16677 , +-30293 , +-27963 , +16695 , +19353 , +16387 , +27681 , +11897 , +18183 , +14309 , +-6843 , +21795 , +25989 , +-25789 , +23137 , +25679 , +7999 , +-14599 , +-5029 , +-951 , +16089 , +-22269 , +4711 , +8965 , +-29119 , +22831 , +18467 , +-24805 , +15369 , +-7077 , +12335 , +28993 , +-28349 , +-15829 , +833 , +9273 , +4053 , +-4795 , +-23613 , +11091 , +-28339 , +5635 , +11749 , +1891 , +32323 , +-6229 , +23607 , +27187 , +-18905 , +-10193 , +-26431 , +4229 , +16291 , +31321 , +4767 , +-30079 , +22885 , +-13679 , +-20463 , +-21835 , +905 , +28165 , +13597 , +-11387 , +-26271 , +23665 , +30365 , +-9429 , +-27689 , +-5043 , +-3619 , +-16851 , +3135 , +-18043 , +-24401 , +-10161 , +6067 , +24245 , +25099 , +-9197 , +-27929 , +30947 , +-12515 , +16555 , +30345 , +-4691 , +-11037 , +24181 , +19471 , +-5107 , +-5563 , +-3599 , +-9453 , +-24695 , +15013 , +15675 , +-22737 , +3567 , +-25337 , +-32768 , +22095 , +6025 , +-20581 , +-521 , +-26739 , +4569 , +-4139 , +19417 , +-23933 , +-2865 , +10003 , +6877 , +-6353 , +-28027 , +931 , +15019 , +1599 , +-11923 , +13927 , +2513 , +-22035 , +24853 , +-4887 , +3269 , +22361 , +-7851 , +-9 , +-7337 , +-12195 , +-3055 , +-20815 , +21671 , +7663 , +12649 , +15917 , +-22111 , +-9497 , +30319 , +21895 , +3571 , +-10393 , +-31125 , +28283 , +12165 , +-21327 , +30341 , +12925 , +-11149 , +22899 , +-9207 , +7255 , +-24701 , +32431 , +13591 , +13875 , +-17633 , +21767 , +-31781 , +19521 , +-23867 , +-3427 , +-27573 , +27595 , +-15601 , +-1693 , +-7075 , +1733 , +10265 , +17915 , +-22857 , +-27661 , +-3449 , +-18675 , +-10251 , +883 , +-13577 , +-23271 , +-8619 , +-8225 , +3063 , +8917 , +-21517 , +29667 , +-9601 , +-25083 , +-9341 , +-13233 , +-6931 , +-1841 , +-16503 , +-4427 , +119 , +-19557 , +-9203 , +7299 , +23849 , +16221 , +-15657 , +31379 , +-30639 , +4221 , +-13789 , +-2741 , +-2677 , +-30171 , +-27167 , +-18131 , +17957 , +23065 , +-5277 , +6137 , +1827 , +23829 , +-14441 , +12861 , +7601 , +-23649 , +12233 , +15725 , +-26079 , +-20637 , +-19249 , +-16767 , +10589 , +-32503 , +8387 , +-28407 , +-8989 , +-29041 , +18245 , +4805 , +-32453 , +14877 , +28707 , +19389 , +15085 , +-7841 , +21663 , +27353 , +-24065 , +7521 , +10015 , +28411 , +5097 , +19171 , +-25237 , +21651 , +29707 , +-3283 , +30043 , +-24641 , +4779 , +11631 , +27677 , +-25897 , +-3481 , +-28521 , +8161 , +8593 , +9265 , +-12891 , +-11241 , +20621 , +29123 , +-30073 , +-28637 , +-3717 , +3739 , +-27285 , +-28517 , +-1115 , +-30859 , +2211 , +-32005 , +275 , +-22471 , +30447 , +-31783 , +-8169 , +-28547 , +-18337 , +22439 , +-28299 , +-20869 , +28583 , +-10779 , +27367 , +-10107 , +-8201 , +-297 , +-20923 , +15615 , +11091 , +-19521 , +-17127 , +24793 , +-28307 , +-30313 , +-14157 , +-7033 , +-14599 , +-20919 , +22211 , +18293 , +-629 , +22627 , +29297 , +25089 , +-19479 , +-18091 , +-7687 , +-12809 , +-6427 , +-5601 , +14525 , +-2689 , +-17735 , +-13675 , +7647 , +165 , +13525 , +19217 , +-24741 , +22847 , +7751 , +6315 , +-5733 , +-655 , +-22913 , +9197 , +15255 , +22689 , +-8519 , +-1513 , +28513 , +-9487 , +-23091 , +26829 , +-4281 , +1845 , +7297 , +25677 , +28519 , +12135 , +14959 , +-22479 , +17351 , +-26709 , +-25773 , +2719 , +-21777 , +14265 , +7397 , +-1533 , +-6915 , +-11551 , +25903 , +7499 , +28483 , +-24969 , +-5779 , +-29033 , +15445 , +11993 , +-29347 , +-22409 , +16561 , +-7463 , +29461 , +-8797 , +11205 , +-31295 , +4967 , +-27855 , +-23149 , +24511 , +13999 , +30029 , +-5945 , +27883 , +-6615 , +15983 , +4427 , +-3407 , +-4651 , +26907 , +-2207 , +11219 , +1727 , +-15345 , +-4289 , +17117 , +16873 , +24833 , +17695 , +21279 , +-13423 , +-10793 , +-12831 , +-22499 , +-24809 , +18521 , +25625 , +-3177 , +17229 , +15475 , +-22101 , +-19985 , +10065 , +-25373 , +-6679 , +30001 , +-18455 , +-2439 , +22557 , +20093 , +-15021 , +24011 , +-10573 , +3593 , +20901 , +-2199 , +4799 , +-28269 , +24479 , +-25951 , +22565 , +-9887 , +-9721 , +-31065 , +8739 , +7085 , +11137 , +-23971 , +23669 , +-29017 , +-24865 , +16001 , +-22303 , +8423 , +8201 , +-11675 , +-32419 , +-10131 , +30019 , +-21715 , +-29031 , +4107 , +-30445 , +1409 , +2851 , +19311 , +-9071 , +-30265 , +-29961 , +-9847 , +-17853 , +-23839 , +-107 , +-623 , +16753 , +-22695 , +20647 , +-10633 , +-7679 , +19745 , +24839 , +-17185 , +24785 , +24523 , +-10139 , +20375 , +-893 , +12609 , +-30379 , +-6515 , +-13593 , +-17161 , +-13329 , +-23473 , +-6461 , +-2643 , +-23325 , +-8713 , +-31181 , +13723 , +4369 , +4527 , +-28287 , +18741 , +19873 , +9119 , +-11653 , +3161 , +29851 , +6511 , +21579 , +4627 , +17921 , +3123 , +3023 , +20163 , +30053 , +-30481 , +24691 , +15593 , +21503 , +6021 , +-21115 , +29771 , +12111 , +8245 , +21523 , +11199 , +15395 , +-6255 , +30011 , +-25261 , +26179 , +-9997 , +-4851 , +-15093 , +-9097 , +-10373 , +-23079 , +29213 , +-20175 , +-12927 , +-9203 , +8867 , +26513 , +12943 , +27277 , +-24105 , +-15087 , +-16419 , +-18555 , +-7991 , +-16497 , +2881 , +22989 , +409 , +-8217 , +16559 , +3761 , +3369 , +-3823 , +-19923 , +6233 , +19295 , +21431 , +30281 , +-25451 , +-18989 , +-12727 , +-13035 , +7223 , +32015 , +12695 , +-31841 , +-25865 , +6209 , +-22039 , +3557 , +-28745 , +-10377 , +5275 , +-28845 , +13677 , +28757 , +12847 , +-30285 , +21615 , +32077 , +3303 , +27309 , +7249 , +26457 , +27615 , +-20551 , +9789 , +-19921 , +-21853 , +-10083 , +14279 , +8959 , +-12985 , +-8101 , +-8631 , +-18013 , +10495 , +29881 , +31417 , +-2977 , +31033 , +-23515 , +-10751 , +22037 , +-18125 , +14913 , +-10791 , +-22787 , +-26093 , +-32053 , +27163 , +-6181 , +-4735 , +-21729 , +19105 , +28609 , +-9029 , +31273 , +-25191 , +11317 , +17459 , +-26913 , +7767 , +31741 , +2975 , +5441 , +-9027 , +-25529 , +-11625 , +-32323 , +11523 , +8299 , +-13905 , +9023 , +-8167 , +27679 , +4103 , +-21609 , +23673 , +-22483 , +28011 , +3705 , +-20605 , +10675 , +-16155 , +-18701 , +12115 , +-15411 , +-1065 , +-11415 , +-15079 , +-1057 , +407 , +-4093 , +30707 , +-26563 , +17281 , +-26701 , +20547 , +-32405 , +29073 , +13215 , +11141 , +28117 , +6013 , +-7901 , +-26449 , +20485 , +32329 , +30275 , +21757 , +-167 , +-21915 , +27819 , +-32429 , +4929 , +-12735 , +-5347 , +10259 , +26865 , +2403 , +-23189 , +11119 , +19357 , +-13311 , +-13577 , +13387 , +-18639 , +-18657 , +-17501 , +-18037 , +-21119 , +20763 , +-17589 , +-18449 , +5647 , +26321 , +23487 , +12915 , +8247 , +28967 , +-10951 , +4885 , +-24593 , +-10445 , +1365 , +-31683 , +23801 , +25799 , +19593 , +23187 , +-13155 , +-12915 , +541 , +-22707 , +11745 , +-27487 , +-18775 , +2831 , +-32697 , +12457 , +-769 , +-7867 , +19703 , +-15257 , +-3661 , +-9229 , +-17785 , +17373 , +14597 , +10259 , +-7385 , +24019 , +-21659 , +-19855 , +-6815 , +517 , +26723 , +-23309 , +-22711 , +-9307 , +-30679 , +-19325 , +-15299 , +-26491 , +9075 , +22367 , +-25319 , +21669 , +-5621 , +31727 , +751 , +589 , +-69 , +-10207 , +29757 , +9893 , +22471 , +26941 , +25773 , +-15665 , +18149 , +15427 , +-30909 , +-16003 , +-31815 , +5825 , +-27875 , +-16119 , +19911 , +6177 , +31395 , +-28147 , +-3349 , +-5227 , +-29371 , +17023 , +27481 , +-23975 , +31669 , +3391 , +17421 , +-12645 , +-18791 , +1597 , +-28733 , +-2353 , +8133 , +-9469 , +5749 , +-1665 , +-31245 , +32729 , +31567 , +31155 , +-7427 , +8531 , +-28379 , +-5195 , +-11117 , +12911 , +-27281 , +23163 , +18291 , +-4305 , +-30269 , +32117 , +-13021 , +11173 , +25539 , +14055 , +-27609 , +-14435 , +19359 , +4803 , +31415 , +-24921 , +-24311 , +-8705 , +13309 , +19635 , +-335 , +-4501 , +-2105 , +-24789 , +-3021 , +13071 , +-19261 , +2695 , +-20839 , +-23299 , +15669 , +-917 , +18255 , +12463 , +26157 , +25145 , +-3683 , +-20521 , +-28343 , +15405 , +-16739 , +3005 , +-26403 , +-27407 , +12207 , +8215 , +-26953 , +-19011 , +20349 , +30305 , +32085 , +-4381 , +-30361 , +29101 , +-1127 , +-13069 , +-2177 , +777 , +-23803 , +4679 , +24323 , +32329 , +-14225 , +19751 , +-27821 , +-22677 , +5953 , +25179 , +30571 , +-28569 , +20261 , +-7103 , +21977 , +24457 , +9287 , +-29077 , +-14543 , +-27063 , +-17909 , +-16977 , +-8433 , +-3931 , +-20417 , +15557 , +-10359 , +29945 , +15067 , +15713 , +-3291 , +-13231 , +15411 , +-10811 , +-12971 , +31563 , +-9803 , +-9513 , +-11921 , +4963 , +-31971 , +28359 , +4125 , +-2855 , +-7129 , +7191 , +11109 , +-18183 , +-18217 , +-10951 , +-28399 , +-8955 , +-991 , +-20309 , +-17489 , +-14981 , +26921 , +-18039 , +-19961 , +-19973 , +-14597 , +-21337 , +32021 , +-18023 , +-2369 , +-1489 , +-13185 , +26543 , +15479 , +-7253 , +-32369 , +4421 , +-17871 , +3757 , +22691 , +31449 , +-27199 , +25563 , +26933 , +-6463 , +-16133 , +-28019 , +-19391 , +9215 , +-9111 , +4321 , +31051 , +-19051 , +11395 , +-4003 , +-30255 , +-21913 , +6505 , +24309 , +21311 , +15757 , +12567 , +11447 , +-10383 , +-10455 , +9251 , +11731 , +19363 , +-31295 , +-19219 , +-11973 , +-27155 , +-30693 , +4449 , +-15427 , +24885 , +-113 , +-28893 , +-2155 , +-79 , +25315 , +16979 , +-6013 , +-11307 , +-13921 , +26301 , +29809 , +30677 , +-22549 , +5013 , +8313 , +23443 , +4831 , +12715 , +8843 , +4379 , +9573 , +11305 , +1917 , +-97 , +-25209 , +21443 , +19875 , +-19223 , +19021 , +27767 , +-13329 , +-29353 , +25107 , +23999 , +15745 , +-5553 , +22885 , +32081 , +-13887 , +-20675 , +21069 , +27721 , +-7945 , +15623 , +-17353 , +-271 , +17765 , +-23553 , +15425 , +9965 , +-26403 , +17517 , +30231 , +22521 , +18137 , +-27279 , +-12985 , +24353 , +8981 , +19081 , +-18657 , +9331 , +-27487 , +-28789 , +-19203 , +20289 , +-23163 , +-27889 , +-28879 , +17617 , +-12599 , +6003 , +-6069 , +31125 , +-9953 , +16979 , +-16133 , +-29461 , +-22039 , +25207 , +1119 , +10059 , +21725 , +-7083 , +-19221 , +4869 , +18969 , +11527 , +-11855 , +-30857 , +-1857 , +-27715 , +-29631 , +7879 , +-16895 , +12737 , +-6403 , +28183 , +30925 , +-16163 , +21499 , +-18365 , +-26163 , +16487 , +27725 , +-19693 , +2071 , +-26453 , +22503 , +-10507 , +-19917 , +-2841 , +-531 , +12597 , +9145 , +3013 , +-27243 , +12475 , +-2195 , +3667 , +-20619 , +25911 , +32209 , +30069 , +20323 , +-22303 , +28737 , +26087 , +11973 , +-21325 , +2185 , +-7509 , +-16527 , +24345 , +21757 , +-31225 , +1793 , +9521 , +8465 , +-1795 , +-5461 , +24187 , +19059 , +-7871 , +921 , +11037 , +-9565 , +32173 , +-27709 , +-4981 , +-17149 , +-22203 , +-19645 , +30927 , +27005 , +31905 , +20021 , +30769 , +23439 , +17905 , +2817 , +-6783 , +-21013 , +3945 , +-20159 , +10433 , +-19833 , +27719 , +10517 , +-15265 , +-8389 , +-15299 , +-21769 , +3313 , +-6437 , +-10893 , +14355 , +-7311 , +22217 , +-23299 , +-3291 , +-5657 , +-28403 , +-27189 , +29133 , +10927 , +31475 , +-8655 , +-24985 , +-21975 , +-18403 , +5067 , +16995 , +-9481 , +-13791 , +1543 , +-12001 , +27819 , +-4965 , +-24813 , +-29891 , +27917 , +1479 , +855 , +-28037 , +13255 , +-31845 , +-22671 , +1545 , +4257 , +32093 , +-27483 , +-16533 , +13373 , +-3655 , +-27687 , +-14401 , +-13497 , +31073 , +30483 , +7593 , +-15305 , +17947 , +14695 , +-7269 , +14207 , +-14753 , +11635 , +-28999 , +-5559 , +-14997 , +-3491 , +11815 , +-7251 , +24549 , +26431 , +25319 , +-29591 , +-23327 , +21799 , +8239 , +20765 , +15245 , +1939 , +-13243 , +16125 , +-6855 , +-29861 , +-9781 , +-27895 , +13305 , +-13255 , +29099 , +-19509 , +19895 , +18611 , +17755 , +-29299 , +5071 , +-27487 , +8639 , +-14071 , +-30937 , +25109 , +23171 , +-11091 , +-16189 , +18657 , +-23061 , +14411 , +22239 , +1161 , +-32461 , +11095 , +-31093 , +24761 , +-19101 , +-6759 , +-1605 , +-29629 , +5283 , +-23965 , +-32279 , +2707 , +2077 , +-12713 , +-24799 , +-1117 , +1615 , +22415 , +11173 , +-3459 , +-30239 , +-26533 , +1021 , +4649 , +-24319 , +-11139 , +913 , +-22225 , +-21191 , +-16163 , +11717 , +899 , +27589 , +3517 , +23431 , +-21753 , +-8587 , +27517 , +17779 , +-12671 , +11507 , +455 , +16995 , +1809 , +5809 , +-11959 , +-28019 , +13347 , +3371 , +-2059 , +-28911 , +-23047 , +-28977 , +20399 , +-27105 , +20107 , +-9647 , +24463 , +2947 , +12567 , +-28035 , +6027 , +17855 , +-14331 , +27285 , +20161 , +-16465 , +-26259 , +29483 , +31775 , +26251 , +-19963 , +8047 , +-24157 , +23701 , +16033 , +-25837 , +-7663 , +2085 , +-985 , +-30563 , +-18127 , +-14525 , +-18941 , +-16325 , +20087 , +8123 , +-29907 , +10019 , +-9647 , +-15421 , +12685 , +14185 , +-27191 , +17155 , +-4093 , +20563 , +11473 , +-16333 , +-31013 , +26421 , +10985 , +-31945 , +-16705 , +12485 , +23143 , +-16463 , +-10697 , +23287 , +-29151 , +26655 , +-31333 , +-4269 , +-12881 , +25959 , +-11889 , +30161 , +23585 , +2819 , +25595 , +-4057 , +-28365 , +8071 , +-23683 , +17839 , +-763 , +20925 , +16745 , +14257 , +-12707 , +29253 , +30271 , +30275 , +-3249 , +18855 , +-23395 , +-4701 , +-4989 , +25319 , +-25921 , +-7159 , +-13593 , +-23899 , +10863 , +1 , +20453 , +691 , +20361 , +-12477 , +-22497 , +18983 , +-25371 , +-6641 , +-18267 , +6651 , +10201 , +12029 , +30385 , +9759 , +-21973 , +-31909 , +16853 , +-3307 , +4747 , +9223 , +-18241 , +-4087 , +15249 , +10941 , +105 , +17765 , +299 , +-29699 , +-2605 , +12269 , +27799 , +-16043 , +16957 , +16467 , +12005 , +-19389 , +-13857 , +22357 , +8671 , +391 , +27929 , +-18865 , +1937 , +11521 , +-27589 , +-937 , +16437 , +-8701 , +32171 , +26577 , +-20815 , +-17363 , +-14677 , +13455 , +-31861 , +1217 , +9863 , +28253 , +9833 , +28799 , +-11177 , +4131 , +-2559 , +-32257 , +-28885 , +-14471 , +5775 , +-11139 , +-16175 , +13503 , +1749 , +-31935 , +-19713 , +-75 , +13205 , +16751 , +20243 , +-26473 , +16761 , +14939 , +24653 , +-597 , +17819 , +21095 , +-12161 , +23911 , +-23429 , +-8097 , +-10419 , +-4867 , +-12435 , +30531 , +-27681 , +-13449 , +-26469 , +-10065 , +2333 , +18771 , +21879 , +-22621 , +-2971 , +27795 , +-30789 , +-3089 , +30403 , +2397 , +17619 , +13813 , +2219 , +18189 , +5093 , +-11505 , +-20437 , +-5677 , +31295 , +-15769 , +-3665 , +14531 , +-4527 , +27207 , +29485 , +-10121 , +26917 , +19959 , +-13855 , +29211 , +20055 , +-23531 , +27269 , +32529 , +-7535 , +28007 , +13325 , +4353 , +2173 , +9277 , +-29479 , +-4491 , +31805 , +-25535 , +-30097 , +-9237 , +17773 , +10963 , +7095 , +26999 , +-26741 , +-20517 , +-21077 , +7379 , +-9989 , +-26839 , +17045 , +20473 , +2175 , +27211 , +29639 , +-25537 , +14629 , +2785 , +21969 , +10727 , +23753 , +11639 , +-18633 , +-17347 , +5389 , +11487 , +-20049 , +-11731 , +-15675 , +-12793 , +1491 , +-19617 , +-29699 , +3155 , +14687 , +-15929 , +-28563 , +-31119 , +-4129 , +-6203 , +1133 , +-23627 , +30197 , +31413 , +27245 , +2543 , +-2299 , +27153 , +-23819 , +31683 , +21873 , +4865 , +2835 , +-18559 , +7507 , +-28557 , +24921 , +28289 , +-30281 , +-8263 , +-22185 , +-4875 , +5191 , +-20069 , +-14969 , +-30141 , +-30829 , +16373 , +-41 , +31197 , +3007 , +-53 , +14483 , +5275 , +9663 , +-30757 , +-3105 , +12947 , +8457 , +-31805 , +-587 , +-21141 , +-9259 , +2959 , +-9125 , +-23751 , +28115 , +14291 , +-13995 , +-28201 , +-24227 , +19011 , +26851 , +-7493 , +-18631 , +17103 , +-2053 , +-175 , +27845 , +14641 , +10425 , +-31283 , +-17221 , +21267 , +25949 , +-18805 , +21089 , +-20839 , +-20029 , +-19993 , +10051 , +6531 , +-7337 , +-24951 , +17263 , +-4925 , +26515 , +20557 , +6181 , +-7025 , +20717 , +-30833 , +27925 , +19713 , +-7587 , +24841 , +22553 , +23337 , +20809 , +3627 , +14179 , +2729 , +-2557 , +28145 , +9791 , +22479 , +-23873 , +-25033 , +-7093 , +11809 , +22797 , +7579 , +-22747 , +-7293 , +5581 , +-27187 , +-12627 , +-26675 , +-5207 , +-6547 , +-3143 , +20695 , +9235 , +-30631 , +18767 , +11039 , +-24911 , +-7793 , +-14249 , +30427 , +10079 , +-24187 , +7645 , +6543 , +-1371 , +-16905 , +-11329 , +3117 , +12455 , +10315 , +-21521 , +19873 , +18089 , +-11425 , +-23011 , +8691 , +32515 , +8681 , +-22529 , +-2597 , +20369 , +21833 , +16385 , +-16679 , +-26953 , +5349 , +31351 , +12237 , +-12591 , +-23041 , +16741 , +-26093 , +-1999 , +-5107 , +16035 , +-11501 , +29069 , +-13933 , +-18261 , +-2465 , +30467 , +-1671 , +25017 , +23627 , +32649 , +-1821 , +-28261 , +-25343 , +12521 , +6537 , +-7721 , +-2019 , +8759 , +21649 , +-23445 , +-1851 , +9417 , +-2589 , +11521 , +-20931 , +19373 , +-18427 , +25777 , +20739 , +27051 , +26739 , +-24537 , +-21405 , +15789 , +-21389 , +12399 , +9363 , +1477 , +-397 , +-23009 , +-20147 , +-20323 , +31705 , +16145 , +-23331 , +25971 , +-25759 , +30371 , +-26681 , +-25971 , +25589 , +12391 , +20687 , +29239 , +15363 , +30045 , +415 , +-27083 , +-5805 , +15275 , +-20519 , +18879 , +-9881 , +12503 , +8879 , +-5643 , +19017 , +-385 , +11515 , +-27427 , +27621 , +395 , +-21543 , +11989 , +4589 , +-5139 , +4539 , +32397 , +3613 , +18643 , +-10749 , +-26749 , +-13531 , +23399 , +-24287 , +19189 , +16373 , +20471 , +-29407 , +-10407 , +-11365 , +14277 , +21191 , +-29091 , +18841 , +-14555 , +-17623 , +-22187 , +20161 , +20041 , +11719 , +1083 , +-16765 , +-7055 , +-19683 , +-2273 , +14545 , +15775 , +17349 , +1579 , +8305 , +8921 , +-17401 , +-24567 , +-26159 , +1239 , +19441 , +-23825 , +-23959 , +-24253 , +-17419 , +-8185 , +-10103 , +12909 , +24059 , +21875 , +3001 , +8575 , +769 , +22205 , +11661 , +-19649 , +-13019 , +23501 , +-17669 , +-22721 , +13899 , +-20881 , +13879 , +16793 , +9009 , +-20935 , +-14071 , +-18653 , +23295 , +-7409 , +-22615 , +29741 , +15211 , +-27113 , +19471 , +13745 , +329 , +10547 , +8657 , +27923 , +32167 , +-6923 , +-17801 , +-6571 , +-28827 , +29979 , +8797 , +10447 , +14663 , +-13433 , +28155 , +-30107 , +-21357 , +-24143 , +6091 , +27977 , +8233 , +20647 , +18073 , +-24543 , +-13285 , +14211 , +-27553 , +22739 , +-7745 , +26717 , +28055 , +-15955 , +-10161 , +-11319 , +-24289 , +-28377 , +-6661 , +-21809 , +14469 , +-23529 , +-633 , +12131 , +12513 , +4713 , +10331 , +-21675 , +11319 , +-18859 , +-27357 , +-14889 , +-19647 , +-25057 , +13027 , +-4247 , +8143 , +24645 , +12429 , +7255 , +-14433 , +-13763 , +14623 , +-31313 , +32691 , +-7765 , +-15307 , +-22341 , +4135 , +-20453 , +21285 , +15603 , +-20337 , +-11977 , +-3435 , +22657 , +9419 , +15229 , +-10093 , +31529 , +-28067 , +15229 , +30509 , +-18479 , +-22969 , +6539 , +-9333 , +-19347 , +9051 , +25085 , +-20091 , +-18309 , +28955 , +18393 , +-15429 , +-32255 , +17167 , +6681 , +20525 , +6391 , +-3947 , +17245 , +2391 , +22865 , +-27321 , +-13277 , +7105 , +27495 , +-28217 , +-10371 , +4125 , +-7437 , +-31459 , +4687 , +-7713 , +-17267 , +22155 , +-29441 , +8785 , +-3679 , +26605 , +-2119 , +-32719 , +-9505 , +-30587 , +-18153 , +-29759 , +6463 , +-16291 , +-10391 , +3943 , +15729 , +-29667 , +11359 , +-11073 , +-6695 , +-24225 , +-9397 , +11833 , +-29949 , +-11383 , +-32297 , +7467 , +-19807 , +12583 , +6967 , +27755 , +-16129 , +-3647 , +3561 , +-26777 , +8439 , +19509 , +23529 , +-10813 , +-1421 , +-12919 , +28009 , +9059 , +12123 , +18511 , +28169 , +-25327 , +-10475 , +-2963 , +-19313 , +2447 , +-3975 , +-10365 , +11553 , +-6353 , +-32183 , +3517 , +15867 , +-10771 , +-7641 , +2859 , +7849 , +-18945 , +23059 , +28055 , +6587 , +21245 , +-7073 , +30435 , +-20225 , +-3223 , +13861 , +-14373 , +7229 , +-23345 , +-12219 , +29585 , +6761 , +-25507 , +20181 , +821 , +-29347 , +-31753 , +-20699 , +-32153 , +-10221 , +3027 , +-15323 , +11287 , +30555 , +-26479 , +-28303 , +-12327 , +-13037 , +26061 , +-15173 , +-30787 , +-27165 , +-2751 , +1479 , +-10585 , +361 , +8789 , +21735 , +-14551 , +-6909 , +-19913 , +12267 , +8919 , +249 , +-18311 , +-19039 , +23077 , +-12231 , +-22491 , +32713 , +13497 , +-9583 , +26963 , +27529 , +-7611 , +357 , +19271 , +2161 , +-31775 , +-16665 , +11013 , +-6681 , +-14877 , +-12335 , +-22939 , +30499 , +-24015 , +16281 , +-19531 , +-14935 , +-7391 , +20269 , +30153 , +-21951 , +32463 , +11819 , +-23401 , +-15255 , +25325 , +-363 , +25161 , +-6057 , +-14041 , +6925 , +-11039 , +15205 , +-21513 , +6025 , +23617 , +-18665 , +29683 , +29843 , +-17195 , +19079 , +30137 , +31989 , +5783 , +21087 , +22577 , +17915 , +187 , +-24741 , +-1161 , +18985 , +-24137 , +-15565 , +-2009 , +-27027 , +7141 , +-9187 , +20285 , +479 , +9877 , +-26947 , +25189 , +26613 , +11179 , +-24919 , +-13093 , +23865 , +-15953 , +13651 , +13505 , +22151 , +-9619 , +10121 , +-21265 , +-17727 , +32265 , +-9873 , +-16551 , +-10491 , +27287 , +-24339 , +-18471 , +11623 , +28721 , +9907 , +18323 , +5679 , +-7787 , +1451 , +6341 , +11143 , +-3783 , +24815 , +27425 , +30649 , +21219 , +-22459 , +20645 , +-8733 , +-1599 , +17171 , +-23817 , +-19147 , +19201 , +23007 , +18741 , +3747 , +-25365 , +30269 , +-6571 , +-25311 , +23159 , +12621 , +-30729 , +-18343 , +-23707 , +-22351 , +28097 , +29155 , +-16171 , +-3579 , +-32459 , +13567 , +18019 , +17625 , +-27125 , +-5943 , +14263 , +4903 , +2819 , +3319 , +2723 , +-14261 , +-7353 , +-14069 , +-8773 , +26235 , +-4037 , +26123 , +-17557 , +-17729 , +9175 , +10947 , +16779 , +24431 , +-23679 , +4717 , +-31357 , +17693 , +-19615 , +22007 , +-29479 , +-1509 , +4671 , +16309 , +12869 , +26733 , +-8749 , +16791 , +-12455 , +16961 , +-26715 , +-14873 , +-32117 , +-11033 , +25187 , +-19847 , +27089 , +31303 , +4019 , +5739 , +-22087 , +24803 , +5777 , +-1447 , +-26361 , +-7617 , +2599 , +-13549 , +-5953 , +8165 , +-22237 , +22237 , +8395 , +7901 , +7567 , +-10983 , +18701 , +6555 , +-31447 , +-3951 , +5881 , +16515 , +23099 , +19489 , +30629 , +-24359 , +-11017 , +31215 , +-12689 , +27193 , +-8887 , +-8911 , +-16377 , +19095 , +-23249 , +28243 , +-7659 , +6319 , +-31847 , +-9795 , +10053 , +-31491 , +10167 , +-3839 , +24543 , +2363 , +-17193 , +-6499 , +-22803 , +-12717 , +5821 , +19497 , +5061 , +-16163 , +32375 , +19221 , +-30685 , +-29679 , +14263 , +4063 , +-3387 , +-19649 , +22191 , +-8243 , +-8571 , +-32307 , +-411 , +-11997 , +-23061 , +2477 , +-24697 , +-25129 , +9029 , +-6063 , +20429 , +-30505 , +13637 , +2595 , +-11831 , +-12881 , +-4075 , +9349 , +25919 , +-27955 , +-11539 , +7743 , +-2043 , +-10701 , +-9677 , +7805 , +-12463 , +19639 , +-14843 , +31303 , +16791 , +-21583 , +28001 , +14453 , +-26399 , +21813 , +30133 , +25645 , +-19037 , +-8489 , +18161 , +-6701 , +-30187 , +27341 , +-27605 , +6791 , +1553 , +19391 , +20659 , +-7649 , +-29857 , +-5395 , +27045 , +23447 , +-32105 , +26861 , +7173 , +2063 , +10355 , +-3863 , +16223 , +-29629 , +11183 , +13899 , +23757 , +-14209 , +13137 , +5375 , +-5469 , +32539 , +-6759 , +-13273 , +-31625 , +16755 , +-30911 , +-13483 , +30659 , +-9383 , +-13469 , +-30145 , +31993 , +-2795 , +-5169 , +25337 , +-2793 , +9177 , +-24099 , +-6479 , +-31795 , +8377 , +6097 , +-23327 , +24065 , +24099 , +27301 , +-8949 , +9465 , +-19493 , +-11159 , +4843 , +-23065 , +22891 , +5915 , +-709 , +22025 , +-6369 , +16381 , +-14627 , +-7363 , +-27261 , +23403 , +6813 , +-20203 , +29523 , +12603 , +-3741 , +-25991 , +-13839 , +-24183 , +-25871 , +-12363 , +26727 , +-17895 , +-1773 , +10525 , +3287 , +7213 , +25953 , +-14829 , +-23433 , +-13609 , +14701 , +20657 , +-26103 , +-1573 , +29057 , +-16937 , +-5429 , +-2821 , +25045 , +-7737 , +14843 , +-18467 , +-2487 , +-20167 , +-25911 , +20053 , +29849 , +-30985 , +18641 , +-27321 , +14619 , +17907 , +1803 , +29691 , +26095 , +-20511 , +23887 , +9717 , +-833 , +-14261 , +27719 , +-21173 , +23283 , +-25553 , +-28699 , +1413 , +-28567 , +17935 , +-30621 , +12013 , +-30545 , +-31087 , +25007 , +-21913 , +32435 , +-13933 , +-11925 , +32207 , +-19701 , +-4159 , +17255 , +22731 , +-9057 , +-19277 , +19603 , +-3545 , +19425 , +2431 , +-17287 , +13739 , +14483 , +15315 , +1335 , +23157 , +12783 , +16787 , +12787 , +31181 , +10597 , +227 , +9177 , +-16769 , +4055 , +-4915 , +19853 , +-15175 , +32077 , +-12715 , +-23257 , +16981 , +23339 , +4617 , +1191 , +-28735 , +2285 , +29221 , +-20237 , +10573 , +-3235 , +21797 , +16199 , +-16125 , +5711 , +-18213 , +-28359 , +-1787 , +24783 , +523 , +7969 , +24159 , +29667 , +-30591 , +18717 , +-17307 , +-19517 , +14251 , +-6521 , +24707 , +9093 , +7085 , +-13333 , +26267 , +871 , +13055 , +32637 , +-23075 , +-22153 , +23675 , +-11241 , +22045 , +-29485 , +-17915 , +-23895 , +1451 , +-1183 , +24465 , +23099 , +-2133 , +29187 , +-22839 , +-24995 , +-32017 , +3925 , +-229 , +-21473 , +-30387 , +6365 , +-28071 , +-17011 , +-24715 , +2765 , +-27187 , +9129 , +-691 , +10799 , +-24623 , +20187 , +-12595 , +4523 , +-9755 , +32241 , +-697 , +12463 , +26447 , +19343 , +2387 , +-19143 , +-10201 , +-11727 , +3351 , +-10245 , +251 , +-24935 , +32555 , +807 , +3807 , +10445 , +-12827 , +-13415 , +12297 , +2959 , +27455 , +13457 , +-22299 , +-19887 , +24863 , +13813 , +-21073 , +-19023 , +1601 , +-775 , +-10095 , +-24975 , +-5253 , +-8347 , +-27599 , +18153 , +-26197 , +31047 , +21195 , +-27897 , +14331 , +-4823 , +-5677 , +-18747 , +-19773 , +-16691 , +-5633 , +-15591 , +31457 , +16485 , +19433 , +-20101 , +30097 , +2629 , +18723 , +-23085 , +13503 , +29991 , +-17971 , +-24849 , +4071 , +-28973 , +-12623 , +19847 , +13675 , +-32413 , +32731 , +18853 , +19555 , +-6915 , +-30801 , +24239 , +-16637 , +-3077 , +17025 , +9679 , +17767 , +6581 , +19115 , +-22797 , +-14097 , +-11343 , +10539 , +14405 , +14363 , +23897 , +-3401 , +21533 , +25309 , +7733 , +10581 , +-25211 , +30579 , +21159 , +-17805 , +-13535 , +14275 , +-6373 , +29055 , +-20297 , +32555 , +-567 , +-18685 , +7961 , +12513 , +5857 , +-3021 , +-11605 , +9925 , +21329 , +29457 , +10315 , +14527 , +-13841 , +4863 , +-12071 , +-2931 , +26425 , +-22059 , +15139 , +7721 , +20367 , +27005 , +-5023 , +-28525 , +15333 , +8713 , +32561 , +-26825 , +-14085 , +-18355 , +-32501 , +22453 , +12571 , +-22283 , +-6603 , +25671 , +26701 , +-4071 , +19525 , +3729 , +4879 , +11619 , +-15599 , +-27903 , +20365 , +23699 , +21545 , +-19305 , +-13991 , +-1367 , +209 , +-7853 , +4007 , +-4239 , +28277 , +30455 , +-23043 , +5027 , +-1625 , +16499 , +-14477 , +-21643 , +26515 , +-15443 , +21605 , +-21067 , +-4621 , +30689 , +-7507 , +12135 , +-13937 , +31867 , +26719 , +-13361 , +6965 , +-6043 , +30971 , +24855 , +17189 , +18923 , +-29399 , +-1693 , +29465 , +28427 , +19691 , +14433 , +-20815 , +3663 , +21601 , +9583 , +-3469 , +26667 , +27381 , +-21981 , +-18113 , +30917 , +-23275 , +-25227 , +-26559 , +-11677 , +26737 , +-19641 , +10617 , +-18385 , +-13645 , +10375 , +-859 , +-28261 , +17067 , +-31809 , +-14659 , +20021 , +9237 , +16949 , +-30741 , +-11775 , +-8755 , +-13953 , +-8187 , +587 , +29313 , +30109 , +18821 , +-29941 , +9197 , +7053 , +29437 , +-2897 , +-14181 , +-10139 , +28433 , +8825 , +-15349 , +-31505 , +-3341 , +-11937 , +6521 , +-23111 , +23379 , +12115 , +-28405 , +12213 , +-20513 , +8999 , +26513 , +-1715 , +23861 , +23781 , +-32581 , +12283 , +-8863 , +-14691 , +-27703 , +-21921 , +1741 , +28103 , +19151 , +28383 , +14783 , +32023 , +-13207 , +18099 , +9299 , +24279 , +-22551 , +-19061 , +21741 , +-24645 , +-25567 , +11671 , +21295 , +-21955 , +12427 , +-10193 , +30589 , +-3469 , +-26355 , +-13603 , +14571 , +-21913 , +-9179 , +259 , +10675 , +-26895 , +-19539 , +-3611 , +23097 , +7435 , +8203 , +6987 , +23159 , +8113 , +9707 , +22673 , +-28169 , +-14805 , +-20869 , +24139 , +9813 , +-15629 , +539 , +12879 , +10281 , +13065 , +-10851 , +-1959 , +16007 , +-21051 , +25077 , +-5355 , +-30471 , +-25289 , +32379 , +-9783 , +-4113 , +30457 , +13723 , +605 , +-25669 , +-4725 , +-13297 , +-24577 , +-13807 , +-19927 , +-19817 , +1583 , +-17939 , +-8411 , +23091 , +-24479 , +-6627 , +-23879 , +25305 , +-20971 , +17969 , +17001 , +7343 , +4963 , +-12819 , +3793 , +-11331 , +5667 , +-7343 , +24583 , +-8657 , +24443 , +769 , +12903 , +-6909 , +6649 , +19267 , +31733 , +24395 , +-31701 , +9597 , +-11725 , +-18473 , +-12357 , +-14813 , +30835 , +5503 , +-23299 , +-17611 , +28345 , +15817 , +8979 , +16693 , +-26359 , +-30159 , +-19329 , +-26977 , +-26811 , +26579 , +-28615 , +1507 , +25987 , +22959 , +16203 , +-8741 , +23783 , +-2729 , +-279 , +4289 , +-21255 , +-11729 , +22275 , +-20049 , +-6787 , +-7393 , +-17051 , +2189 , +-22327 , +13007 , +-25267 , +29837 , +7847 , +31325 , +-25731 , +-10969 , +16283 , +-30061 , +28381 , +-20085 , +-28463 , +-87 , +9605 , +-10593 , +26717 , +14187 , +11881 , +-23701 , +21037 , +517 , +-167 , +-17371 , +-21177 , +1325 , +-20559 , +23443 , +6581 , +18909 , +24415 , +-1257 , +-12587 , +-4973 , +-15741 , +-30443 , +29231 , +26625 , +-22141 , +-6665 , +-31023 , +29255 , +-8789 , +-8283 , +3363 , +-6997 , +10809 , +25459 , +27463 , +-23083 , +-5629 , +7845 , +13797 , +3711 , +-3713 , +17757 , +-3697 , +-16205 , +11627 , +-18403 , +25743 , +27011 , +-12839 , +16307 , +-28345 , +25917 , +21965 , +6075 , +-3835 , +-16855 , +26451 , +32661 , +1879 , +32187 , +-23527 , +-30247 , +-6673 , +-14257 , +31365 , +-7599 , +-18193 , +-17573 , +14153 , +-15755 , +-3133 , +-31183 , +13191 , +-13219 , +13953 , +-19151 , +30557 , +1081 , +-31815 , +10109 , +-22271 , +-24497 , +-8497 , +-22725 , +-24483 , +-6287 , +-5417 , +-25531 , +30495 , +-10767 , +-24095 , +-11935 , +27995 , +-16103 , +-17181 , +-15361 , +31383 , +-20181 , +-7165 , +30317 , +-7315 , +-22067 , +16245 , +15503 , +-21597 , +-26351 , +-32563 , +31513 , +15543 , +9433 , +-797 , +-11969 , +6409 , +3807 , +-4577 , +-23297 , +-3231 , +26407 , +30547 , +-30271 , +791 , +17657 , +32541 , +31141 , +-4965 , +15957 , +-1105 , +22831 , +5791 , +21995 , +-14537 , +-17027 , +-15457 , +-26723 , +-27479 , +27913 , +-14335 , +7019 , +7459 , +-27945 , +13483 , +-22805 , +7613 , +7225 , +-12769 , +-23217 , +15843 , +14581 , +-22517 , +-21043 , +30253 , +30225 , +-17047 , +20639 , +4027 , +27389 , +-8945 , +25211 , +-11261 , +29005 , +-15665 , +32391 , +-31431 , +24313 , +-19187 , +-2347 , +14099 , +-17653 , +32467 , +-5287 , +-24523 , +25825 , +7785 , +-16541 , +-1033 , +9689 , +117 , +-23151 , +-27443 , +9619 , +8075 , +31315 , +-28909 , +-18267 , +-8123 , +-23339 , +3177 , +-32301 , +483 , +13951 , +16271 , +24009 , +31575 , +237 , +-30537 , +4433 , +-25367 , +-9627 , +12897 , +12809 , +20039 , +-14129 , +-6481 , +16801 , +-16097 , +19245 , +30017 , +29583 , +28731 , +31125 , +399 , +5443 , +-15601 , +13223 , +12725 , +4329 , +11741 , +5511 , +30171 , +-32101 , +9799 , +27469 , +5 , +-10219 , +-15259 , +-9461 , +-31643 , +29429 , +26721 , +-709 , +23107 , +17777 , +15503 , +-25671 , +5445 , +24971 , +-5121 , +-12485 , +12109 , +-3381 , +26015 , +-19637 , +-9515 , +-25991 , +969 , +-5955 , +-27197 , +-22959 , +-3999 , +-24923 , +-27457 , +6595 , +7533 , +22999 , +-24815 , +415 , +-21973 , +13011 , +29425 , +2647 , +3239 , +-15799 , +19049 , +-12107 , +-10279 , +29705 , +-26461 , +-6899 , +30263 , +30845 , +-26681 , +-1793 , +-20271 , +3235 , +-16559 , +12195 , +23271 , +20609 , +-17683 , +2123 , +-1537 , +25635 , +-1595 , +-9285 , +-15739 , +781 , +28261 , +25559 , +-16169 , +22069 , +-26869 , +17893 , +-30997 , +13439 , +26243 , +5955 , +13911 , +-30289 , +9597 , +-11111 , +16121 , +7139 , +-7071 , +17305 , +-22013 , +26507 , +-27211 , +14129 , +18843 , +-13851 , +26851 , +11849 , +-23319 , +-19987 , +32157 , +17653 , +-1859 , +4061 , +-30797 , +-4049 , +9371 , +-17631 , +31587 , +31761 , +-9125 , +1741 , +-9663 , +-15221 , +-2503 , +15515 , +-18305 , +8349 , +11637 , +13915 , +4813 , +-2039 , +12645 , +-12811 , +-29521 , +-1131 , +22803 , +23513 , +12117 , +30649 , +-11443 , +-1035 , +16631 , +-17953 , +-21689 , +-11973 , +-13145 , +21 , +31143 , +-121 , +-3413 , +-5303 , +6697 , +-27613 , +-26283 , +-5121 , +15789 , +5307 , +-27043 , +-24183 , +12505 , +-4903 , +-5961 , +-23617 , +-20699 , +29137 , +6893 , +-20677 , +6785 , +-19125 , +26099 , +-21493 , +-4259 , +-8661 , +-21371 , +-30999 , +-12975 , +16403 , +-6411 , +21753 , +-5079 , +-5803 , +6031 , +-17923 , +21891 , +-8337 , +24427 , +2315 , +-17691 , +-15869 , +19397 , +6093 , +16469 , +3145 , +-3117 , +15405 , +4981 , +-21233 , +-221 , +27801 , +10003 , +11567 , +11375 , +-1361 , +-5303 , +7295 , +28915 , +-8061 , +23053 , +-681 , +18505 , +6219 , +12371 , +26237 , +19649 , +-2403 , +-21607 , +-27739 , +-20427 , +-219 , +-23537 , +7263 , +-21147 , +11227 , +23325 , +2461 , +-30259 , +7875 , +-10619 , +415 , +16383 , +13849 , +8187 , +-15759 , +27253 , +-1257 , +16703 , +-23839 , +-30989 , +-7393 , +21673 , +20983 , +10839 , +-9347 , +-32173 , +-29457 , +15601 , +-26725 , +16799 , +945 , +-10395 , +6583 , +-18595 , +9153 , +-10255 , +28193 , +-30629 , +453 , +-14247 , +4333 , +-1917 , +6511 , +11313 , +-2513 , +-20887 , +7171 , +-12359 , +-21327 , +-3217 , +-31425 , +12085 , +-27859 , +-14249 , +12003 , +-28981 , +-26625 , +-22951 , +-25957 , +-9519 , +31589 , +17601 , +10885 , +-5977 , +3125 , +15101 , +25 , +12311 , +22287 , +-10429 , +-18001 , +-27355 , +16415 , +415 , +-14733 , +23145 , +32585 , +-31861 , +-30507 , +-11289 , +30447 , +-29683 , +-117 , +-3477 , +-8935 , +-14265 , +11529 , +16217 , +-20675 , +-5991 , +-2703 , +24845 , +26731 , +-5585 , +-21745 , +-16465 , +-3571 , +-735 , +343 , +25223 , +18199 , +24325 , +-25009 , +-25119 , +16839 , +523 , +663 , +-22185 , +-29735 , +22675 , +-43 , +-18765 , +10557 , +7491 , +30133 , +-24255 , +-27305 , +28583 , +-29347 , +-12881 , +-5461 , +7487 , +11105 , +21081 , +3359 , +28443 , +-12221 , +41 , +20143 , +21497 , +-24727 , +25585 , +-31065 , +16081 , +-15215 , +22587 , +4949 , +-28169 , +-4147 , +16299 , +-16819 , +-4433 , +8183 , +32713 , +-1265 , +16711 , +29613 , +21611 , +30805 , +-7767 , +14539 , +-27779 , +31671 , +-24453 , +-3495 , +31073 , +-17 , +6325 , +-29427 , +5577 , +3469 , +7603 , +31297 , +28933 , +17967 , +-25131 , +-5785 , +487 , +6715 , +-11887 , +-10237 , +-29675 , +-24299 , +3857 , +12327 , +-291 , +-29739 , +6723 , +-21149 , +27799 , +10883 , +18811 , +-16315 , +-19853 , +-1071 , +22143 , +10315 , +-5927 , +-16565 , +13355 , +31839 , +13373 , +-32235 , +-16257 , +22991 , +3699 , +-25055 , +-21695 , +29121 , +-24429 , +9191 , +26891 , +11565 , +17733 , +-22879 , +-29977 , +8023 , +-13411 , +-7429 , +21101 , +-315 , +-28045 , +14419 , +-9649 , +23737 , +5185 , +27755 , +-21637 , +-11481 , +-1169 , +-20059 , +5807 , +-7895 , +22323 , +26551 , +10897 , +11779 , +2285 , +-28949 , +-25017 , +27279 , +495 , +26059 , +-30573 , +-30409 , +27115 , +10595 , +15203 , +-31625 , +17847 , +28661 , +7153 , +27591 , +-18765 , +5683 , +-12461 , +-4325 , +27287 , +14067 , +-27747 , +8413 , +21457 , +9579 , +7535 , +-22949 , +16991 , +-7707 , +-11757 , +3789 , +29983 , +253 , +-18921 , +-30529 , +-17493 , +32083 , +-6053 , +-20973 , +16567 , +27593 , +437 , +-24969 , +-27425 , +2611 , +12543 , +8277 , +4613 , +8341 , +27577 , +87 , +12069 , +11483 , +-29931 , +26459 , +-9037 , +20749 , +-21091 , +24293 , +-32401 , +31757 , +-19141 , +15387 , +-20549 , +-15159 , +14815 , +10563 , +11129 , +28659 , +-14189 , +-31311 , +22619 , +-26557 , +-14581 , +21573 , +-22333 , +-3807 , +-11319 , +28769 , +9497 , +-25627 , +-1361 , +-16031 , +-23653 , +-30833 , +-27113 , +9365 , +-14141 , +21243 , +13415 , +17845 , +26643 , +10655 , +23093 , +7649 , +23923 , +-27973 , +30929 , +20747 , +30469 , +-21733 , +-3735 , +8705 , +-30845 , +-16061 , +31895 , +13523 , +14611 , +-13261 , +-12673 , +-10279 , +-18273 , +-19305 , +-12439 , +2853 , +-11861 , +-6013 , +16589 , +-393 , +-27983 , +12711 , +9983 , +15805 , +4603 , +17933 , +-12495 , +17419 , +27379 , +2889 , +-13797 , +-21241 , +-29695 , +1079 , +-19699 , +-17165 , +-4893 , +-7881 , +7047 , +30481 , +-14977 , +-21801 , +29519 , +-1359 , +-8889 , +32539 , +17681 , +24213 , +-29951 , +22823 , +-24723 , +-15629 , +-723 , +-9345 , +659 , +-11795 , +25303 , +-27451 , +-21919 , +26251 , +3311 , +-18723 , +-29457 , +-28121 , +8223 , +-18245 , +-6735 , +-18315 , +-4313 , +-9585 , +-23283 , +-1553 , +-27209 , +1151 , +-25493 , +-23339 , +-5183 , +-2083 , +-16677 , +-7009 , +26959 , +19175 , +20003 , +26617 , +4839 , +9973 , +19543 , +13621 , +1623 , +16695 , +2549 , +25937 , +-16365 , +1515 , +10365 , +-677 , +-20213 , +28183 , +-5755 , +-24967 , +15619 , +30653 , +8791 , +17501 , +-18067 , +-18279 , +-21501 , +-13769 , +-31555 , +849 , +-22537 , +28215 , +-12729 , +-26825 , +28959 , +2935 , +9871 , +-11657 , +-28299 , +17029 , +28715 , +-8493 , +-27621 , +18507 , +18707 , +20705 , +3059 , +-27759 , +-31625 , +12727 , +-22857 , +8431 , +-13019 , +27439 , +-23401 , +-31413 , +2125 , +3733 , +-29629 , +-31033 , +-28437 , +28135 , +29587 , +29769 , +-7275 , +32645 , +-19309 , +-3231 , +-11561 , +-31627 , +26401 , +31947 , +-9211 , +26891 , +30467 , +16237 , +-19299 , +-10193 , +-20863 , +-24133 , +-22507 , +30991 , +-29319 , +6599 , +-8645 , +20309 , +17659 , +-27737 , +8713 , +-18973 , +-20639 , +7797 , +16635 , +-5109 , +-25375 , +6087 , +-25875 , +-21181 , +19631 , +-29277 , +-1429 , +-13473 , +27275 , +3835 , +19857 , +17229 , +26849 , +-23901 , +22367 , +-15289 , +-28839 , +7369 , +-3693 , +8589 , +-27141 , +-29967 , +-2311 , +-22879 , +9397 , +-4509 , +28243 , +-14859 , +3977 , +-719 , +3487 , +6705 , +-22767 , +8609 , +-20997 , +12767 , +-2655 , +28719 , +-14339 , +7591 , +16609 , +-13311 , +-28543 , +14603 , +-22559 , +-3617 , +-12787 , +9623 , +13739 , +-24149 , +-353 , +28835 , +16491 , +-24997 , +-6643 , +-9343 , +27893 , +-17297 , +7383 , +-16839 , +12013 , +-18711 , +-18557 , +31943 , +7505 , +711 , +-24973 , +-31031 , +-3173 , +22773 , +-20929 , +-9797 , +-26795 , +11983 , +14471 , +32177 , +-1485 , +-10991 , +-683 , +-2929 , +12453 , +30033 , +13549 , +5055 , +-27399 , +-23047 , +-15833 , +16485 , +20201 , +-13125 , +9543 , +-31199 , +6075 , +1937 , +18265 , +-32705 , +-27951 , +-11225 , +-18941 , +-29327 , +4811 , +11747 , +26589 , +17931 , +8983 , +23123 , +-24241 , +-21325 , +-20983 , +7207 , +4583 , +4513 , +6009 , +-31575 , +-15829 , +8273 , +9175 , +7095 , +-5641 , +4029 , +963 , +-27081 , +18261 , +27929 , +23587 , +-11499 , +3539 , +30983 , +-23869 , +22195 , +1627 , +-28855 , +-22685 , +-787 , +-2165 , +-28407 , +-24235 , +6529 , +-4467 , +-13951 , +-26223 , +-16619 , +-32653 , +17723 , +-30377 , +25765 , +-25591 , +5065 , +1333 , +-24185 , +1069 , +27643 , +-13135 , +14289 , +2735 , +10903 , +5721 , +9573 , +-23651 , +-23665 , +-4009 , +-3235 , +26923 , +15807 , +-29293 , +-1025 , +-22539 , +-11997 , +-10433 , +-8379 , +3055 , +16265 , +6909 , +-8761 , +1449 , +16333 , +11629 , +21045 , +-32713 , +-11367 , +-9919 , +343 , +-135 , +24461 , +-3355 , +30843 , +-16637 , +-8699 , +-6007 , +12917 , +-5781 , +9287 , +9915 , +-17647 , +-32735 , +-19899 , +10633 , +-30453 , +3023 , +1225 , +-28153 , +-14703 , +-21213 , +-7621 , +6269 , +-16337 , +-22983 , +-26167 , +-19733 , +12873 , +-2973 , +-21201 , +-14291 , +11547 , +4747 , +-8987 , +-14451 , +-14553 , +31749 , +3799 , +-797 , +22067 , +2027 , +1953 , +-1759 , +26303 , +-19215 , +28231 , +26485 , +10753 , +-571 , +4717 , +-22819 , +-28075 , +19933 , +-4857 , +63 , +-10691 , +-20779 , +-11363 , +-12029 , +-28207 , +17987 , +22013 , +-32217 , +16063 , +-17389 , +-16785 , +-23589 , +15039 , +8547 , +-21381 , +1433 , +5261 , +28621 , +16907 , +8887 , +22363 , +14667 , +23355 , +-17527 , +-29487 , +-24437 , +-14211 , +-3345 , +-21119 , +12747 , +863 , +-14219 , +-18463 , +-19415 , +21945 , +18149 , +-23109 , +-29823 , +-5265 , +16225 , +30773 , +-15677 , +-14687 , +-5889 , +-28103 , +22221 , +3681 , +15579 , +6517 , +-9793 , +-20491 , +26287 , +-27183 , +1755 , +-13685 , +8693 , +-30869 , +24271 , +-8855 , +23407 , +11013 , +25757 , +12463 , +-4275 , +9481 , +-27929 , +28815 , +-9281 , +19195 , +-24113 , +-3335 , +-16373 , +17261 , +13639 , +-24603 , +39 , +13443 , +-29709 , +-3079 , +25815 , +14555 , +18037 , +5585 , +-28615 , +-11501 , +-8365 , +30123 , +7911 , +6077 , +-5311 , +-4191 , +-12915 , +-14897 , +-17917 , +-6035 , +31481 , +1447 , +28609 , +23693 , +24259 , +1661 , +11997 , +23051 , +19539 , +12887 , +27219 , +-9041 , +23173 , +12427 , +-1915 , +-31563 , +-14403 , +28335 , +-355 , +8205 , +29315 , +26643 , +19555 , +32265 , +-16751 , +25529 , +16529 , +-31337 , +15991 , +-7983 , +-12883 , +1539 , +-1623 , +27053 , +-18589 , +14883 , +-22753 , +1331 , +-24485 , +30225 , +-19351 , +-285 , +147 , +-2195 , +28999 , +15683 , +-25549 , +20485 , +14273 , +-8481 , +-27929 , +25369 , +-5955 , +21947 , +-24645 , +27925 , +-27359 , +-18097 , +-24209 , +3513 , +-21667 , +-30979 , +843 , +-13083 , +-32373 , +-30459 , +7809 , +4545 , +-27643 , +7179 , +11259 , +1151 , +20607 , +-29953 , +-8517 , +21135 , +-14945 , +-18021 , +16045 , +19797 , +3853 , +-10913 , +-9213 , +23399 , +-10725 , +17665 , +-3315 , +13375 , +-16695 , +-29073 , +-26485 , +-8583 , +6513 , +27453 , +-31091 , +-6015 , +-20273 , +-15451 , +-24121 , +-11303 , +3235 , +-14343 , +-12439 , +10949 , +197 , +-8035 , +13175 , +14471 , +-8005 , +-21373 , +28579 , +-9191 , +12247 , +-14821 , +-1375 , +28005 , +9671 , +-31023 , +10245 , +11513 , +-8263 , +-32503 , +-1899 , +13893 , +-27165 , +-6009 , +19235 , +27721 , +-21081 , +-24197 , +-31255 , +22745 , +43 , +11753 , +20569 , +30287 , +11625 , +12717 , +30075 , +-9279 , +21453 , +-15127 , +-31035 , +-15425 , +1099 , +19717 , +22387 , +-6781 , +-13577 , +5151 , +-6057 , +6323 , +9247 , +22283 , +-9155 , +15245 , +13793 , +455 , +3263 , +-11349 , +9795 , +-11659 , +22421 , +24883 , +26061 , +6863 , +15479 , +-9071 , +-14691 , +-10209 , +25461 , +22195 , +-18429 , +22977 , +-23611 , +13241 , +32409 , +11787 , +-23771 , +-1997 , +-16169 , +-29225 , +-23121 , +8409 , +16427 , +-409 , +-22987 , +-831 , +5789 , +25073 , +20237 , +535 , +20689 , +11909 , +-5255 , +-27309 , +15543 , +919 , +-5769 , +-17671 , +17553 , +21987 , +1043 , +-21561 , +-20847 , +27127 , +-20913 , +-15501 , +6387 , +21793 , +-10647 , +-15901 , +2711 , +15595 , +-26175 , +-10529 , +28689 , +-29427 , +297 , +28755 , +23877 , +23537 , +23999 , +17149 , +-5245 , +-19045 , +24137 , +-31315 , +-29669 , +1329 , +29957 , +-10503 , +-22669 , +21735 , +-23031 , +-14991 , +-8031 , +-25475 , +22037 , +29281 , +-10871 , +-10701 , +12785 , +18179 , +-19607 , +4681 , +-14789 , +13363 , +30715 , +16621 , +-8245 , +29873 , +14091 , +-5447 , +19591 , +18895 , +15497 , +-28761 , +5299 , +-21839 , +25383 , +-7023 , +-15147 , +24063 , +30579 , +-22755 , +-8187 , +30239 , +-153 , +16451 , +4809 , +-22541 , +16009 , +-4811 , +15977 , +29701 , +-12675 , +-22811 , +-2869 , +-26041 , +-23521 , +32760 , +31949 , +-12213 , +-9955 , +-20167 , +-2287 , +12795 , +4625 , +3225 , +-17561 , +25803 , +-9971 , +3747 , +-31083 , +-6789 , +-15165 , +18039 , +-28489 , +30787 , +-15341 , +19511 , +9239 , +13207 , +26149 , +-493 , +-13181 , +7509 , +30465 , +15275 , +-18651 , +-11639 , +-14167 , +-10215 , +23259 , +12691 , +-32595 , +-1441 , +273 , +32497 , +-15797 , +-23457 , +18197 , +-913 , +3323 , +-26533 , +12277 , +27357 , +10131 , +21727 , +-8497 , +28235 , +-4141 , +24397 , +-28237 , +19645 , +-6517 , +-27457 , +-2831 , +-151 , +-12251 , +-18035 , +26359 , +3689 , +16841 , +-185 , +17577 , +12023 , +29419 , +-18147 , +-10699 , +7203 , +11113 , +-2323 , +-2963 , +-24051 , +9763 , +16037 , +-347 , +21399 , +-16367 , +7243 , +14589 , +-7513 , +19417 , +-16271 , +11083 , +-27947 , +-7699 , +25895 , +6241 , +-16725 , +1309 , +-20101 , +9713 , +-6313 , +-3151 , +-11411 , +19685 , +18151 , +-763 , +-30619 , +-21973 , +23807 , +-19557 , +-13265 , +18463 , +28177 , +21429 , +26225 , +-1963 , +27927 , +13935 , +3753 , +22001 , +18375 , +-22187 , +24213 , +-30579 , +3409 , +633 , +19263 , +-8319 , +-6257 , +18707 , +23653 , +-8765 , +24261 , +19089 , +23165 , +-12739 , +-8235 , +29741 , +-21725 , +30887 , +-779 , +18703 , +5143 , +3805 , +24815 , +-13089 , +7347 , +-5451 , +-4915 , +-17701 , +-14873 , +13405 , +-2019 , +-7819 , +-12119 , +2349 , +11167 , +31329 , +19187 , +15109 , +-4477 , +-10435 , +-25797 , +16413 , +-8671 , +14999 , +-15771 , +27493 , +18479 , +13713 , +3143 , +1367 , +8055 , +25079 , +-6509 , +23891 , +25365 , +-12077 , +5721 , +27509 , +28715 , +1415 , +1015 , +6893 , +13847 , +-10903 , +21917 , +-11047 , +-15057 , +981 , +-28619 , +25499 , +12279 , +-3385 , +-2325 , +-14673 , +14043 , +16371 , +24857 , +3851 , +-18843 , +-22941 , +16069 , +-9237 , +20467 , +-895 , +-31849 , +-28621 , +17653 , +-22849 , +-20399 , +-10171 , +-865 , +22179 , +-19767 , +-26541 , +11301 , +28259 , +-11169 , +-9407 , +6515 , +-7933 , +28405 , +-9741 , +-4003 , +-6431 , +-24473 , +-19669 , +-23963 , +24281 , +-19323 , +-5153 , +18663 , +13265 , +32137 , +20499 , +-32295 , +-24865 , +21263 , +19503 , +-16643 , +-25131 , +-4211 , +22229 , +-101 , +30301 , +-7091 , +-31935 , +-4935 , +-25197 , +-9247 , +-11243 , +-12329 , +-9187 , +25379 , +26301 , +23587 , +1725 , +28831 , +3901 , +-15827 , +9075 , +25245 , +31889 , +1575 , +21261 , +-21625 , +32127 , +4251 , +22335 , +-6931 , +32243 , +29085 , +3395 , +-32515 , +-11051 , +20107 , +-19227 , +-11663 , +-1437 , +29249 , +23591 , +-23787 , +16133 , +-2095 , +18257 , +4269 , +6825 , +-30791 , +-21109 , +-6013 , +-21353 , +-24669 , +-24073 , +14669 , +-31791 , +-9069 , +-32441 , +21419 , +18399 , +-16473 , +-17453 , +-3807 , +23091 , +-6841 , +21563 , +-18031 , +2039 , +9955 , +-5523 , +-8407 , +25709 , +-24787 , +-21679 , +2279 , +25537 , +2251 , +-815 , +17287 , +20071 , +28561 , +15993 , +12547 , +9451 , +-21447 , +30353 , +11909 , +3151 , +-23907 , +17325 , +-22299 , +23267 , +-17811 , +-5429 , +22427 , +23963 , +-30105 , +-9749 , +-27081 , +28135 , +11793 , +30501 , +-27551 , +28683 , +15855 , +-27585 , +-27577 , +20985 , +-7623 , +24267 , +-4195 , +-23897 , +-2023 , +9401 , +6925 , +-9755 , +-16035 , +-14991 , +24633 , +26811 , +5811 , +10095 , +-31191 , +10811 , +-27555 , +-30123 , +8265 , +19679 , +-18063 , +3461 , +-17437 , +19545 , +29063 , +17211 , +-23541 , +5105 , +245 , +10275 , +29737 , +-7841 , +-13431 , +22385 , +12513 , +25 , +-4671 , +-11399 , +8085 , +-2761 , +8319 , +15049 , +5205 , +13253 , +-8379 , +-15937 , +28261 , +-3687 , +18665 , +-14173 , +31519 , +13485 , +-19755 , +26169 , +30593 , +-20231 , +26291 , +-16671 , +-6121 , +-28979 , +-32081 , +-32723 , +32633 , +-20065 , +29741 , +22769 , +19267 , +-26771 , +1275 , +-14869 , +24455 , +26771 , +29457 , +2761 , +-18227 , +20509 , +-30013 , +-20531 , +-29561 , +-19287 , +15231 , +23523 , +-16375 , +27059 , +-24831 , +25397 , +-16893 , +29051 , +-5371 , +-7609 , +25205 , +26447 , +17807 , +-17013 , +13609 , +10859 , +-3183 , +23933 , +-21839 , +-7851 , +-9675 , +32573 , +-23597 , +-4697 , +-13697 , +-3681 , +-7283 , +-6027 , +-28769 , +-26935 , +-19583 , +16157 , +14225 , +-32185 , +28409 , +-30555 , +-29083 , +-29781 , +11353 , +11149 , +17391 , +11673 , +15635 , +27687 , +-19453 , +2413 , +-17367 , +31605 , +-14037 , +-6331 , +-7393 , +-24963 , +-3617 , +-30047 , +23917 , +1569 , +-24513 , +13181 , +21127 , +28537 , +19527 , +9183 , +24131 , +9383 , +28813 , +509 , +12255 , +30257 , +31089 , +28361 , +1905 , +17629 , +7901 , +-22259 , +-13853 , +-19453 , +8315 , +-27387 , +-7319 , +-25495 , +-9115 , +119 , +-20359 , +-10345 , +-18327 , +31559 , +-23229 , +-1099 , +-10821 , +-25455 , +-5207 , +-24611 , +1835 , +3141 , +-20547 , +-16141 , +-32285 , +10551 , +-11605 , +24327 , +16535 , +-23615 , +15423 , +-5345 , +-28347 , +-6961 , +-32043 , +-25193 , +-15001 , +-26237 , +8665 , +19707 , +31923 , +15173 , +-2383 , +-8875 , +-32187 , +-5027 , +15427 , +-8175 , +-19353 , +-32499 , +-17177 , +31821 , +-4419 , +3367 , +29405 , +14261 , +28419 , +-12763 , +20299 , +-18473 , +-21435 , +-13887 , +24495 , +5121 , +6289 , +-1775 , +2521 , +-12399 , +-15047 , +22549 , +-27033 , +5335 , +24963 , +-20003 , +-15945 , +18533 , +-29727 , +-32491 , +-29857 , +-29467 , +-4687 , +-17121 , +-979 , +20349 , +6507 , +-5195 , +6805 , +29851 , +-23713 , +20213 , +-14927 , +15697 , +27883 , +-30725 , +-20813 , +32051 , +-26059 , +-31231 , +10463 , +14499 , +10847 , +6637 , +2055 , +17329 , +-21947 , +1649 , +17785 , +-1675 , +-1617 , +-7011 , +-23673 , +-23583 , +-25847 , +-19207 , +1901 , +-21479 , +-31323 , +29987 , +-15913 , +11091 , +-3483 , +-28199 , +32205 , +-3035 , +6907 , +-29281 , +3643 , +-21403 , +25503 , +-19503 , +-11817 , +3961 , +-6325 , +12347 , +-6747 , +-3785 , +-8597 , +25391 , +-8725 , +6457 , +-10213 , +-13785 , +15787 , +-29003 , +15841 , +21707 , +25751 , +27861 , +6621 , +32411 , +11151 , +-10351 , +-26747 , +1279 , +-6257 , +10501 , +14049 , +-28197 , +2869 , +-4281 , +10815 , +12975 , +7855 , +-11579 , +-10647 , +-3027 , +17969 , +-743 , +-4765 , +31305 , +3833 , +6239 , +7067 , +-4895 , +-17735 , +32529 , +-16473 , +4291 , +-15973 , +-19361 , +-23423 , +-6829 , +-15699 , +-17149 , +13873 , +-24935 , +-25881 , +28829 , +10515 , +21471 , +-9579 , +23433 , +2951 , +15053 , +20825 , +18743 , +-17875 , +-14605 , +-5985 , +3847 , +11933 , +-31249 , +-31595 , +-20587 , +-24423 , +4093 , +9125 , +28325 , +29133 , +-6893 , +-2969 , +-4761 , +-9215 , +-29067 , +-26075 , +-6311 , +-9769 , +-9003 , +22467 , +-22625 , +16891 , +-25889 , +22855 , +-12581 , +-29467 , +-29607 , +-11323 , +-32383 , +15623 , +4543 , +13277 , +-26961 , +24971 , +18511 , +4783 , +-8305 , +11145 , +-343 , +10587 , +7969 , +3519 , +21993 , +-1297 , +-13669 , +24269 , +26423 , +27875 , +10819 , +-2585 , +-14875 , +1559 , +-3395 , +-17907 , +13829 , +3133 , +-4371 , +-25655 , +28551 , +14307 , +-11697 , +-3739 , +17857 , +14041 , +-13371 , +-21093 , +2971 , +-19145 , +-3845 , +26841 , +-29671 , +9421 , +6709 , +-19215 , +28535 , +-1249 , +18095 , +-19625 , +25797 , +-25125 , +8561 , +26067 , +-6153 , +-18993 , +-16733 , +-20041 , +-889 , +8295 , +10609 , +-29275 , +-19327 , +14241 , +-9643 , +20919 , +-9177 , +-22395 , +-20999 , +-24003 , +-24063 , +-28643 , +29833 , +-4871 , +-27785 , +5867 , +-20077 , +-3885 , +-14869 , +17129 , +-23471 , +18445 , +-31665 , +14329 , +12435 , +27911 , +22845 , +-24867 , +-16379 , +12651 , +-12911 , +27317 , +-19437 , +8167 , +-19589 , +-19213 , +-32705 , +-16275 , +22051 , +-6191 , +1271 , +14049 , +26035 , +-4273 , +17129 , +13403 , +-2057 , +-22363 , +-281 , +-19759 , +30071 , +18493 , +28211 , +29537 , +-13561 , +-4563 , +-31911 , +-18695 , +-18457 , +8497 , +-3185 , +10647 , +-28589 , +26647 , +-29563 , +30719 , +19621 , +-17979 , +-3391 , +-30729 , +15587 , +-1107 , +24689 , +-13575 , +14559 , +18111 , +31947 , +-23699 , +-23351 , +10985 , +-7195 , +21599 , +8779 , +-22263 , +30465 , +29633 , +17949 , +7019 , +3443 , +22291 , +10787 , +-15175 , +-25099 , +29355 , +13311 , +15739 , +30841 , +9055 , +-6099 , +30729 , +-22393 , +-9529 , +8601 , +-27897 , +6167 , +9715 , +-31305 , +12893 , +-29983 , +-31073 , +-29413 , +-26967 , +2617 , +-26901 , +-1899 , +11073 , +-9875 , +28573 , +2751 , +-15711 , +-30063 , +-14135 , +24099 , +14697 , +19429 , +-13033 , +-20539 , +-18477 , +1435 , +6005 , +30277 , +18863 , +24645 , +-11443 , +-25227 , +1235 , +19353 , +30529 , +15979 , +30233 , +7639 , +4705 , +-21473 , +-29483 , +-7273 , +-23577 , +-21371 , +-17199 , +-2009 , +30053 , +13855 , +-28995 , +32357 , +-4215 , +-30187 , +22317 , +-11763 , +-7859 , +723 , +19471 , +-30305 , +-20047 , +28443 , +-20313 , +8361 , +29685 , +20901 , +20477 , +-7511 , +22097 , +-8919 , +-543 , +11871 , +25381 , +1285 , +22109 , +-22101 , +3265 , +31311 , +29611 , +32223 , +31627 , +-4757 , +-11599 , +13467 , +5827 , +27691 , +7671 , +19745 , +16315 , +13403 , +5919 , +8755 , +-18557 , +-11551 , +22239 , +14435 , +-22733 , +-6311 , +7031 , +-29453 , +-15725 , +25633 , +-8791 , +-725 , +32091 , +-23813 , +-7119 , +24105 , +-13591 , +9757 , +-29249 , +23879 , +24701 , +24021 , +-30355 , +-16153 , +-3607 , +19091 , +-19017 , +8655 , +24785 , +21387 , +-8717 , +-19195 , +22109 , +10695 , +3657 , +15907 , +16245 , +4035 , +-18895 , +-15829 , +9079 , +23941 , +20829 , +4839 , +19823 , +-26319 , +-12479 , +-13633 , +16335 , +-987 , +28925 , +-12021 , +-5461 , +-17269 , +21985 , +-267 , +-25495 , +-3201 , +28251 , +-825 , +-23295 , +30613 , +3449 , +-4151 , +9133 , +-31749 , +-12075 , +4249 , +-2259 , +-31725 , +5913 , +-15875 , +18543 , +-9339 , +-17169 , +16453 , +-22571 , +729 , +22651 , +-32483 , +13541 , +-12143 , +-21677 , +23519 , +-14201 , +18111 , +-32005 , +-28039 , +-26187 , +-17121 , +-16425 , +-11591 , +21689 , +-16473 , +-17757 , +18477 , +7397 , +31151 , +-16269 , +-10635 , +28873 , +1399 , +-8925 , +-27619 , +26857 , +30799 , +-21425 , +-25097 , +18683 , +803 , +26833 , +-9487 , +-9319 , +-105 , +-3403 , +-14225 , +-28545 , +16801 , +941 , +-6369 , +-10951 , +-31327 , +18967 , +-8107 , +-24471 , +21235 , +-23967 , +-1055 , +-22669 , +11025 , +10003 , +-409 , +14009 , +23841 , +20283 , +2105 , +9301 , +22037 , +-11411 , +-29525 , +-10927 , +-15043 , +-28365 , +-1553 , +-12963 , +28003 , +9487 , +10607 , +-16125 , +-1441 , +29417 , +12443 , +-23959 , +-19659 , +-10995 , +-21941 , +-24445 , +24745 , +10659 , +4245 , +-28473 , +16467 , +30373 , +16159 , +-17555 , +23617 , +23635 , +-18945 , +-32219 , +7943 , +3639 , +-19185 , +-9911 , +31833 , +2705 , +-14395 , +2975 , +-31195 , +18515 , +-9843 , +-16251 , +-14805 , +5019 , +27291 , +-17227 , +13325 , +20649 , +-691 , +21877 , +8183 , +23897 , +21497 , +3665 , +-5725 , +18711 , +-26803 , +22871 , +-9211 , +-25765 , +-733 , +-3641 , +1363 , +24735 , +2007 , +-13999 , +25509 , +-18983 , +-2523 , +-49 , +15889 , +-30097 , +31609 , +-8845 , +563 , +-12109 , +22735 , +18313 , +32345 , +-11045 , +-4601 , +-22609 , +-12275 , +-3471 , +23485 , +-17021 , +-8397 , +24667 , +19875 , +21221 , +-16995 , +19267 , +1363 , +19115 , +-15575 , +-2409 , +-16975 , +475 , +-16813 , +7167 , +-325 , +31581 , +4433 , +16727 , +-1567 , +20029 , +5033 , +15653 , +-31001 , +-12711 , +-28599 , +-24175 , +-9941 , +26529 , +-18403 , +17887 , +-31343 , +-23605 , +24881 , +-22943 , +-3891 , +-11641 , +-5573 , +21241 , +-16833 , +-13245 , +-25925 , +9225 , +22349 , +-14509 , +-10349 , +28143 , +9017 , +-18501 , +1051 , +-5385 , +-30855 , +12627 , +26555 , +-27683 , +18579 , +17557 , +-4087 , +7869 , +25451 , +19901 , +10071 , +23695 , +-2267 , +11929 , +14287 , +11545 , +22397 , +-5457 , +21263 , +16753 , +-8297 , +7677 , +22073 , +25835 , +-25253 , +17965 , +659 , +-31589 , +27983 , +22103 , +-23911 , +11585 , +-24849 , +-29401 , +29595 , +-18481 , +-18045 , +1449 , +-21553 , +-9135 , +31091 , +-1421 , +29931 , +-7309 , +-25045 , +13151 , +-19651 , +11889 , +-24475 , +-27189 , +-3769 , +19863 , +-5877 , +20297 , +18385 , +23851 , +-24437 , +-27943 , +-25981 , +-7949 , +-20819 , +24737 , +257 , +-10715 , +755 , +20519 , +-19335 , +13287 , +-17049 , +-10999 , +22983 , +-28103 , +20471 , +-2513 , +5 , +12153 , +12367 , +-4213 , +-21591 , +3165 , +12849 , +-18869 , +-14827 , +22109 , +8779 , +-10345 , +18869 , +-10057 , +-18035 , +-22077 , +663 , +-21531 , +-32507 , +18443 , +-17537 , +-9325 , +-16843 , +20677 , +-20605 , +15127 , +-17 , +-8669 , +6177 , +8293 , +25507 , +-20123 , +12251 , +15765 , +11077 , +2189 , +-32443 , +20681 , +-17515 , +5793 , +-9561 , +-7503 , +-25849 , +-27047 , +-16877 , +-13439 , +-30447 , +28511 , +-23047 , +-18843 , +17923 , +-6653 , +-2493 , +23419 , +9061 , +19823 , +-3607 , +-22451 , +-2869 , +-19351 , +-29423 , +-28983 , +31019 , +-31613 , +29593 , +-19789 , +-11079 , +-29737 , +7231 , +-21081 , +13119 , +26939 , +16431 , +8583 , +10991 , +-11523 , +-28899 , +20857 , +-2105 , +-20451 , +-2081 , +31071 , +10075 , +31737 , +23935 , +-25653 , +-13003 , +-4971 , +4319 , +-387 , +-10325 , +21321 , +-6463 , +3409 , +-25283 , +-20487 , +17009 , +-9275 , +14943 , +-4393 , +-4919 , +-793 , +-10275 , +18569 , +4061 , +-5685 , +29109 , +15605 , +12035 , +-20849 , +13919 , +8297 , +29557 , +5573 , +5817 , +-19619 , +9571 , +2679 , +-25007 , +-17241 , +-22129 , +26771 , +-21439 , +7731 , +-9369 , +-3089 , +9351 , +23609 , +7057 , +-21061 , +12771 , +3837 , +-5359 , +16503 , +12323 , +14077 , +27359 , +-17807 , +-10491 , +-5201 , +-26637 , +20147 , +-17013 , +23735 , +-25621 , +21639 , +-12847 , +-25183 , +2589 , +15723 , +-16021 , +13335 , +24879 , +-18047 , +15929 , +-8041 , +-22227 , +-15725 , +-21571 , +-26191 , +-31191 , +-14971 , +22777 , +12729 , +-26807 , +-23989 , +2751 , +-24827 , +31333 , +-17819 , +-30061 , +24219 , +19485 , +-14893 , +19959 , +-5771 , +-909 , +-22891 , +-12719 , +-19405 , +20447 , +-3433 , +-22219 , +-20141 , +-6933 , +27703 , +8519 , +-12825 , +5705 , +8493 , +6029 , +24785 , +4461 , +26643 , +5455 , +1149 , +-1631 , +29775 , +32353 , +-11503 , +28579 , +-18281 , +-31733 , +32041 , +21941 , +-12319 , +-4009 , +13077 , +10301 , +9437 , +25063 , +-10107 , +-15657 , +4079 , +4187 , +31435 , +-5645 , +-23643 , +-20201 , +-32367 , +28903 , +-8275 , +-27481 , +-28149 , +21641 , +-32173 , +-27501 , +-25417 , +-23993 , +12405 , +-5703 , +3473 , +-31805 , +11259 , +-31967 , +-26933 , +18149 , +20685 , +-2729 , +-29179 , +-17801 , +-28589 , +-26041 , +21509 , +-18633 , +-23711 , +-1647 , +-16655 , +11641 , +10937 , +4445 , +-251 , +-28873 , +-2559 , +-26693 , +-2611 , +-4435 , +-22217 , +-13191 , +30681 , +-22163 , +30893 , +-3209 , +28919 , +-2053 , +13181 , +3969 , +25327 , +14819 , +21639 , +-2645 , +14005 , +22097 , +20963 , +20767 , +-10205 , +2349 , +-7461 , +-20605 , +-27597 , +29869 , +29799 , +11717 , +-20043 , +-12437 , +-31715 , +-8839 , +15495 , +-30965 , +6577 , +31407 , +31569 , +-20671 , +5863 , +-30133 , +1969 , +5493 , +-27119 , +30943 , +261 , +-12071 , +3839 , +-11777 , +20885 , +-22785 , +31359 , +10271 , +32335 , +7403 , +11343 , +-15131 , +-1791 , +-29507 , +-25701 , +-17917 , +27919 , +6067 , +-11795 , +27281 , +-341 , +-13103 , +-18261 , +9445 , +-2929 , +-9227 , +-751 , +-6939 , +-15311 , +11623 , +-15709 , +-10519 , +-1921 , +13821 , +-9181 , +-19705 , +-5353 , +24491 , +-15593 , +-30473 , +-14341 , +-8543 , +1453 , +5221 , +-11315 , +19161 , +25415 , +12741 , +27779 , +-10691 , +20323 , +-29771 , +-17241 , +30513 , +4891 , +6347 , +-26365 , +-8265 , +17695 , +-32265 , +-32541 , +-26371 , +-12251 , +2381 , +14539 , +7035 , +16359 , +2417 , +-2135 , +15243 , +-29543 , +-23209 , +-24939 , +-15747 , +7397 , +-16207 , +-3323 , +-29643 , +13913 , +-10053 , +21379 , +315 , +-27539 , +-10863 , +-8469 , +17755 , +24047 , +27665 , +-31201 , +-3399 , +12541 , +10285 , +59 , +-18073 , +32133 , +-18497 , +6489 , +-17533 , +-6601 , +-29205 , +21435 , +-565 , +-8201 , +30447 , +21389 , +-15183 , +18405 , +13437 , +3353 , +13821 , +10181 , +-17771 , +11645 , +5851 , +24831 , +9431 , +-18967 , +-387 , +30229 , +-921 , +16721 , +-10967 , +10909 , +-6599 , +-4951 , +-2089 , +12727 , +20973 , +22939 , +-10167 , +-23803 , +16681 , +-15425 , +29083 , +28195 , +-16529 , +-24491 , +26987 , +-31583 , +8823 , +-16263 , +13665 , +-3465 , +-21759 , +28129 , +7503 , +-25339 , +-25031 , +31247 , +29129 , +-8065 , +28543 , +-18423 , +-12487 , +-15377 , +4813 , +-10085 , +-14979 , +-1113 , +3975 , +8447 , +-17417 , +29247 , +27609 , +-3037 , +27181 , +-28663 , +2185 , +-22949 , +-17187 , +-1787 , +-31409 , +-27753 , +32659 , +-1693 , +17845 , +-4063 , +-23865 , +22641 , +-20893 , +19405 , +30317 , +-13795 , +13061 , +16313 , +-20199 , +-18719 , +19605 , +16001 , +-25721 , +-28089 , +-4035 , +-267 , +14529 , +30681 , +-24917 , +31063 , +-15695 , +18075 , +-23575 , +-4337 , +21301 , +-3325 , +-24651 , +-2847 , +4545 , +18293 , +-4517 , +-2133 , +-17039 , +-13517 , +2569 , +13203 , +-5221 , +2015 , +31915 , +-27185 , +-11529 , +-6809 , +31301 , +-32565 , +-1241 , +21639 , +-17473 , +-5393 , +-22313 , +-65 , +-19889 , +-12339 , +24149 , +15047 , +-21695 , +27619 , +18597 , +-6005 , +-935 , +15049 , +-3811 , +-28769 , +-12123 , +12271 , +2941 , +21819 , +-21033 , +8659 , +-18301 , +5811 , +18979 , +-8261 , +5381 , +22893 , +-13687 , +-5655 , +28043 , +18775 , +447 , +17497 , +-4503 , +32227 , +-14475 , +23539 , +10315 , +-17023 , +67 , +30277 , +16733 , +30603 , +28139 , +-23619 , +10967 , +11471 , +-8125 , +-21411 , +-19683 , +32377 , +-8575 , +-4357 , +-13229 , +7053 , +24857 , +-21777 , +-8335 , +17637 , +-19435 , +-21427 , +-31771 , +8101 , +6633 , +-11607 , +29603 , +-29131 , +18127 , +27193 , +5057 , +-14411 , +19611 , +-12379 , +27019 , +26103 , +3867 , +22061 , +-11235 , +8697 , +-10011 , +-6041 , +25217 , +-2341 , +10421 , +23421 , +7739 , +-7335 , +20289 , +-4905 , +8813 , +447 , +-2665 , +-7577 , +-10395 , +11877 , +9199 , +-15031 , +10939 , +-2907 , +-7927 , +12049 , +7145 , +-1451 , +509 , +-24203 , +30047 , +-24133 , +17051 , +24713 , +2593 , +6665 , +15933 , +-14469 , +20439 , +-27053 , +24865 , +4037 , +-21137 , +-7415 , +27207 , +745 , +22055 , +4585 , +-27203 , +-29021 , +2361 , +29827 , +1923 , +-19539 , +-29219 , +-25309 , +-28971 , +-14615 , +17393 , +-25007 , +23063 , +32035 , +-24309 , +16585 , +-19689 , +-18109 , +-3567 , +26609 , +23543 , +-27381 , +14673 , +23761 , +-23431 , +-25529 , +-32487 , +14221 , +-12321 , +-19825 , +31441 , +8023 , +-7365 , +-25739 , +-15727 , +-26383 , +29777 , +-25277 , +-24773 , +-25699 , +-28443 , +13873 , +-26869 , +-23399 , +22167 , +23583 , +-20289 , +-32495 , +21313 , +16073 , +-18145 , +1697 , +17861 , +1155 , +25887 , +29253 , +22379 , +31091 , +-22417 , +-23085 , +26039 , +10557 , +6299 , +-1035 , +29887 , +-9397 , +-19295 , +-5473 , +-7669 , +-5765 , +-5885 , +11269 , +28645 , +26971 , +10343 , +-23013 , +-16079 , +-24615 , +-3925 , +-14205 , +24011 , +-18549 , +-27525 , +-26359 , +-10407 , +12633 , +-24211 , +9887 , +9895 , +1973 , +15003 , +-25905 , +-9859 , +-927 , +16307 , +-24139 , +10489 , +2199 , +-26477 , +24701 , +-28573 , +26567 , +32103 , +-19893 , +-887 , +13523 , +4915 , +-7223 , +11155 , +4547 , +13563 , +-23283 , +21857 , +-11781 , +-16045 , +27159 , +-19359 , +-24841 , +17521 , +-3635 , +1757 , +-28799 , +22227 , +11117 , +-24347 , +10605 , +-30645 , +12935 , +9881 , +-14905 , +12189 , +-26247 , +-30969 , +20373 , +-2411 , +-17825 , +20349 , +21773 , +31393 , +18069 , +-4243 , +-7349 , +-9755 , +-13151 , +1207 , +9351 , +-31529 , +27839 , +18571 , +14545 , +11351 , +29633 , +13501 , +16711 , +9283 , +5279 , +-1635 , +5581 , +4753 , +-1957 , +-9137 , +-25269 , +17129 , +-9083 , +-27227 , +16469 , +30399 , +-1999 , +-13963 , +28281 , +-30241 , +24427 , +11887 , +-21021 , +-15467 , +7473 , +32379 , +11679 , +11321 , +15341 , +-14453 , +21077 , +-16559 , +29803 , +13559 , +13683 , +-11749 , +-17579 , +-5803 , +-28937 , +-31049 , +25887 , +205 , +403 , +-23635 , +6289 , +21489 , +16761 , +-22509 , +18351 , +4893 , +3461 , +29727 , +26427 , +-11703 , +29431 , +24123 , +-25433 , +7515 , +21429 , +3241 , +6803 , +11535 , +-22797 , +-5235 , +-7237 , +-11203 , +27769 , +-26739 , +11389 , +15805 , +-13739 , +5355 , +4807 , +-27969 , +19729 , +11029 , +-7027 , +8601 , +-15761 , +-17213 , +-21299 , +7465 , +-22879 , +29839 , +16121 , +-29525 , +-25605 , +-25079 , +30969 , +-31733 , +-6857 , +-31915 , +-3167 , +15559 , +23069 , +10045 , +-9823 , +10043 , +-12601 , +-19511 , +7435 , +-29563 , +25947 , +30047 , +-15553 , +-10025 , +-15821 , +-17839 , +32617 , +9805 , +-25945 , +28415 , +21367 , +8263 , +-27075 , +-12703 , +28561 , +-10427 , +-1441 , +-209 , +2069 , +-25287 , +6293 , +-2705 , +23045 , +-32159 , +-2239 , +28815 , +-27125 , +-30045 , +11471 , +28157 , +-5653 , +13151 , +25975 , +-6079 , +24697 , +25029 , +-29847 , +14995 , +-12269 , +20925 , +2451 , +245 , +-28769 , +-25305 , +8395 , +-13117 , +10743 , +-3129 , +-14449 , +-31269 , +-14359 , +-25707 , +3135 , +-12251 , +-30541 , +20881 , +29135 , +19893 , +-32531 , +-23769 , +16127 , +5467 , +-26609 , +22519 , +14361 , +13763 , +-923 , +1083 , +-17627 , +-25333 , +25983 , +23449 , +-18783 , +15573 , +-8907 , +23673 , +29369 , +-15639 , +18199 , +-5151 , +-23297 , +-16833 , +24167 , +-1585 , +-14681 , +-30551 , +25239 , +-14843 , +9527 , +-13091 , +10803 , +23923 , +-23097 , +273 , +-11161 , +-6145 , +-19789 , +-20971 , +-12047 , +-8475 , +19413 , +-9497 , +30361 , +-15471 , +-20159 , +29907 , +-8153 , +28397 , +-24457 , +3069 , +18401 , +-28347 , +-25569 , +-17269 , +-26241 , +31383 , +13883 , +-25557 , +29347 , +-15505 , +-11029 , +-31687 , +18895 , +-4549 , +-5737 , +-28591 , +-3101 , +-26329 , +4787 , +10597 , +16401 , +22647 , +8169 , +-2727 , +-7597 , +-11947 , +28901 , +-31975 , +25703 , +11571 , +-22921 , +2867 , +21833 , +32159 , +7771 , +7405 , +28449 , +10397 , +12653 , +-28711 , +-5177 , +-2693 , +-21415 , +-28167 , +-16463 , +-11733 , +31457 , +10827 , +-3213 , +-5855 , +-631 , +2021 , +-11343 , +8095 , +467 , +-2671 , +12187 , +-27499 , +-11013 , +-13859 , +24039 , +14331 , +26919 , +11195 , +16443 , +4771 , +1319 , +917 , +-707 , +22161 , +30379 , +-3867 , +-22287 , +-12325 , +16115 , +-25525 , +-27705 , +-12809 , +-19949 , +15917 , +30725 , +7577 , +-32603 , +12739 , +15811 , +11019 , +-23551 , +-4933 , +-29339 , +-6911 , +9459 , +13131 , +-5997 , +30709 , +-19209 , +-7997 , +-32341 , +31229 , +-28173 , +7349 , +-30271 , +-24797 , +-21403 , +21629 , +11541 , +-29121 , +-30681 , +-11935 , +-2555 , +-4531 , +-12385 , +17191 , +-12661 , +17475 , +4473 , +5937 , +22583 , +-18065 , +-24349 , +-3059 , +-11619 , +25163 , +4157 , +12691 , +18523 , +7633 , +15961 , +-23171 , +14981 , +-23199 , +28203 , +-25475 , +-32097 , +-6909 , +24843 , +22483 , +-23777 , +13399 , +-5275 , +-6295 , +15959 , +-30757 , +-1037 , +-18325 , +-5131 , +13003 , +-29323 , +-20387 , +9467 , +20857 , +31467 , +11443 , +32311 , +29727 , +-20917 , +-16665 , +-5837 , +-23999 , +-24133 , +-743 , +13243 , +20091 , +-21693 , +16155 , +32199 , +21219 , +2831 , +-24555 , +-8703 , +-29227 , +13341 , +7317 , +-4945 , +14165 , +18303 , +9513 , +27955 , +-31003 , +14853 , +32121 , +-12797 , +-15911 , +-25465 , +-16417 , +-18657 , +18991 , +32395 , +23927 , +24327 , +-14863 , +25485 , +29381 , +-8645 , +-2305 , +-15703 , +18625 , +14633 , +23407 , +2271 , +-9611 , +22699 , +11877 , +-27199 , +14099 , +-22275 , +-7831 , +-21837 , +6287 , +-26829 , +-22977 , +-15203 , +-31051 , +-23237 , +8511 , +22567 , +-8513 , +19525 , +-9171 , +26733 , +6001 , +26059 , +-28267 , +-4033 , +-26191 , +21241 , +-5989 , +-27185 , +-31331 , +-25931 , +-18085 , +-24341 , +-17375 , +13837 , +29115 , +-21569 , +-31467 , +17199 , +-19769 , +1537 , +10703 , +22249 , +-16759 , +17067 , +23615 , +9365 , +-12709 , +-6085 , +-15741 , +-19299 , +-5691 , +-17565 , +32519 , +-7829 , +21977 , +-25533 , +3343 , +21217 , +13567 , +28193 , +18913 , +-20389 , +28499 , +421 , +587 , +16661 , +31619 , +31113 , +-9013 , +-19655 , +8223 , +8663 , +-2023 , +16705 , +-14991 , +12705 , +5705 , +-4607 , +28637 , +28469 , +-21409 , +3861 , +-1365 , +11995 , +-20889 , +-8745 , +-21647 , +-23545 , +28687 , +18149 , +-18983 , +-747 , +29115 , +-20471 , +-14325 , +16763 , +29219 , +-4937 , +14193 , +27275 , +-25501 , +6407 , +-6623 , +-20827 , +10907 , +-27859 , +30891 , +30443 , +21761 , +-13457 , +-2955 , +-2173 , +-6785 , +8859 , +24205 , +-7609 , +18371 , +-28925 , +29449 , +11261 , +28127 , +16373 , +3293 , +23573 , +24925 , +-2127 , +22063 , +24285 , +-10025 , +21471 , +22835 , +21049 , +-22003 , +-17269 , +2429 , +17629 , +28805 , +12701 , +24037 , +24573 , +16537 , +-20787 , +-27949 , +29591 , +-16621 , +24097 , +11545 , +23827 , +30025 , +20701 , +-10923 , +16529 , +-17999 , +-2303 , +-23623 , +3221 , +1271 , +3395 , +-2957 , +16445 , +2969 , +14719 , +23673 , +27651 , +29693 , +3509 , +-10523 , +25835 , +-32503 , +-22143 , +-15665 , +-23993 , +-30401 , +-19953 , +-13913 , +-16931 , +-28083 , +-10089 , +17923 , +-29005 , +-5845 , +-22701 , +17155 , +-10695 , +3763 , +-13063 , +-21475 , +-2045 , +-12105 , +-24913 , +-14971 , +-19447 , +-6249 , +2183 , +-31503 , +23381 , +-4003 , +-23435 , +-7419 , +30533 , +6999 , +12231 , +-17125 , +23351 , +26405 , +5921 , +24481 , +-26423 , +-16293 , +20715 , +20729 , +-12649 , +-8807 , +15959 , +29891 , +-13985 , +12311 , +-13621 , +8123 , +28623 , +-16177 , +-32285 , +13333 , +28849 , +20995 , +-11291 , +-8625 , +11171 , +-25245 , +16569 , +2703 , +-13227 , +1693 , +-24223 , +10869 , +4157 , +-25991 , +18421 , +25459 , +-20789 , +-19855 , +11793 , +-16981 , +-9173 , +5313 , +-5671 , +27459 , +-8585 , +-5875 , +-24215 , +-16321 , +11627 , +22893 , +-19245 , +-3373 , +5285 , +14347 , +22157 , +15425 , +20571 , +-32453 , +-13709 , +29237 , +-25457 , +4621 , +-31935 , +-20337 , +-20791 , +27501 , +-10629 , +11209 , +-28079 , +-9799 , +32501 , +-15415 , +-8477 , +-10027 , +-23095 , +28471 , +-15889 , +3267 , +-22077 , +5979 , +21061 , +-22845 , +23915 , +-913 , +9815 , +-28959 , +-3221 , +14967 , +-23313 , +10773 , +20885 , +-31069 , +2145 , +5333 , +595 , +-17127 , +-29619 , +-21967 , +31905 , +22359 , +-16949 , +-20633 , +-1399 , +25347 , +26157 , +-1021 , +-27115 , +4429 , +2103 , +30313 , +-6967 , +30399 , +26573 , +15615 , +-13923 , +-27751 , +5173 , +21429 , +-19087 , +15521 , +27853 , +-20957 , +3595 , +-883 , +6205 , +-4569 , +-3193 , +-31291 , +26165 , +-20749 , +7259 , +-13111 , +-27735 , +-19285 , +-67 , +25353 , +27003 , +-10115 , +1713 , +10805 , +11713 , +2355 , +-1173 , +-2019 , +24437 , +14419 , +28505 , +17153 , +13489 , +-29771 , +20367 , +28273 , +21349 , +-21611 , +24517 , +-12129 , +-17263 , +-31439 , +-11311 , +2111 , +25079 , +23013 , +-16491 , +-17709 , +24155 , +29365 , +-27263 , +21387 , +18491 , +20593 , +27529 , +-9567 , +-26885 , +-20405 , +16023 , +32033 , +-27989 , +15599 , +-4979 , +-8873 , +-14791 , +17425 , +7347 , +-15469 , +27689 , +18585 , +-12617 , +18317 , +-12851 , +-14043 , +-14307 , +2617 , +3325 , +4917 , +-26559 , +-26591 , +20563 , +31411 , +27333 , +-29637 , +-13859 , +-12783 , +24719 , +-29891 , +-28587 , +24295 , +-22719 , +-20609 , +-15649 , +30465 , +1837 , +32075 , +-4291 , +-28165 , +8145 , +-2119 , +12933 , +13151 , +2765 , +-4603 , +3169 , +-20173 , +-25251 , +6501 , +23739 , +-13547 , +79 , +9063 , +-31743 , +26069 , +-10633 , +11461 , +7633 , +17291 , +-22093 , +-4933 , +20031 , +4147 , +-10667 , +227 , +6529 , +-25927 , +-21211 , +-31347 , +-16851 , +-27997 , +981 , +-29037 , +-30225 , +-24037 , +-5127 , +-26443 , +8383 , +15497 , +-14207 , +-29839 , +-20833 , +-1613 , +31149 , +25427 , +-1071 , +-10931 , +-10359 , +7387 , +-9335 , +11025 , +13027 , +-2101 , +-4821 , +-14497 , +5317 , +-21759 , +10243 , +-7095 , +-2969 , +-24369 , +10619 , +27447 , +7089 , +-11309 , +-16943 , +21241 , +29227 , +25681 , +-25771 , +29273 , +26233 , +32267 , +-14309 , +-24767 , +-20913 , +-22891 , +-24009 , +29259 , +5355 , +3119 , +627 , +-31021 , +4115 , +-4833 , +29063 , +-28771 , +21375 , +-20601 , +-6189 , +6113 , +6883 , +-15939 , +3989 , +18665 , +25173 , +-9435 , +-32353 , +-29655 , +-15021 , +-19065 , +-2925 , +25041 , +15413 , +-10521 , +-10595 , +17391 , +28705 , +-31779 , +18849 , +-4611 , +-8819 , +29293 , +-1535 , +-7937 , +32047 , +21859 , +-14395 , +31773 , +11127 , +-10205 , +-17821 , +-32337 , +-31097 , +8969 , +14059 , +24809 , +31409 , +-32707 , +-3897 , +7133 , +13665 , +14599 , +-29461 , +8739 , +-18781 , +17331 , +28565 , +-2069 , +-18155 , +-9765 , +-21375 , +405 , +10335 , +-28855 , +-28257 , +19399 , +-8663 , +331 , +-15277 , +-22515 , +-8807 , +-18807 , +26913 , +-2587 , +-15033 , +18277 , +19951 , +-3995 , +-20557 , +26311 , +-28999 , +22595 , +14915 , +-7295 , +-21301 , +-11651 , +-5451 , +14879 , +-28557 , +21351 , +-21733 , +-12481 , +27973 , +28225 , +-27569 , +27247 , +193 , +24921 , +-16655 , +2435 , +9121 , +13981 , +21207 , +-23449 , +9597 , +-12109 , +-29425 , +-1665 , +-5361 , +15501 , +-2993 , +-1417 , +18151 , +8077 , +29677 , +-3675 , +-31581 , +-26095 , +-27301 , +-2085 , +-24919 , +30353 , +-28637 , +-11591 , +5725 , +-717 , +26703 , +-11373 , +-6441 , +17383 , +-11403 , +-12609 , +-30177 , +21249 , +7201 , +-15507 , +-30489 , +-2489 , +-17455 , +19461 , +-29509 , +-28011 , +-7311 , +28411 , +27839 , +-10261 , +-21941 , +-6109 , +11493 , +-22513 , +7045 , +-32105 , +26533 , +2459 , +-9701 , +-25863 , +6713 , +32665 , +-27825 , +25187 , +19277 , +-25183 , +-2135 , +-1621 , +-31681 , +12387 , +29287 , +-693 , +-27439 , +-11567 , +22397 , +-26197 , +-26267 , +18343 , +-16373 , +-16383 , +-17487 , +28555 , +-12977 , +-27731 , +-23041 , +13221 , +-30173 , +-22525 , +8409 , +15539 , +8951 , +9903 , +-11445 , +-12635 , +-21441 , +30351 , +-25193 , +-24397 , +12153 , +31483 , +-31121 , +2553 , +13977 , +945 , +-19799 , +23171 , +-29181 , +-31457 , +24443 , +-18185 , +29965 , +-20163 , +22319 , +23711 , +-2841 , +2287 , +-10143 , +31749 , +-27101 , +-561 , +26545 , +-14325 , +11427 , +-17267 , +-31743 , +-13433 , +-3569 , +14279 , +-19163 , +1875 , +-22825 , +-29859 , +-4831 , +8943 , +-3675 , +20559 , +-19489 , +2445 , +-19117 , +-1777 , +5485 , +19381 , +-27291 , +-12707 , +-13657 , +-25259 , +24839 , +-23397 , +-27525 , +-14243 , +-25479 , +-7765 , +16801 , +-5167 , +-7919 , +-5313 , +22219 , +24429 , +19373 , +-27207 , +-11933 , +5037 , +-20045 , +-21631 , +-831 , +-14731 , +-11139 , +9429 , +-11803 , +-7139 , +19291 , +10287 , +-9813 , +27921 , +23559 , +27409 , +2441 , +-18465 , +31131 , +2915 , +-27969 , +26591 , +-24047 , +31047 , +7193 , +28727 , +21039 , +-30345 , +24091 , +31623 , +18445 , +18457 , +-26171 , +-28685 , +-13315 , +-23529 , +-7741 , +18365 , +-18415 , +-29963 , +-20951 , +30309 , +-2547 , +-29395 , +-19801 , +-28103 , +-21537 , +-23799 , +28487 , +-17811 , +-12651 , +10739 , +29595 , +-20039 , +21469 , +-19885 , +-13179 , +-23187 , +-17935 , +-18969 , +-27553 , +6409 , +7707 , +-12651 , +7609 , +-12717 , +-26205 , +-31281 , +-20329 , +503 , +7505 , +21595 , +21019 , +-11115 , +-31911 , +-5447 , +-28977 , +14429 , +4063 , +23029 , +-16563 , +15149 , +6117 , +13567 , +-16511 , +1309 , +1741 , +17025 , +-28583 , +25505 , +31299 , +-10437 , +-9209 , +14621 , +-21303 , +28895 , +-11087 , +-22273 , +-6503 , +-22183 , +26025 , +22609 , +11565 , +6841 , +12077 , +-25895 , +-5841 , +19331 , +17557 , +-6993 , +-17673 , +15237 , +9489 , +22607 , +13691 , +-22221 , +-6433 , +-14023 , +-18481 , +-22659 , +3333 , +2821 , +7449 , +-25561 , +-123 , +-6919 , +31495 , +16035 , +-25061 , +-32219 , +-22837 , +-20635 , +-6803 , +-18947 , +-18285 , +16321 , +7885 , +-4761 , +17791 , +573 , +-28057 , +9311 , +-30699 , +-17557 , +13309 , +-18427 , +12103 , +19267 , +16933 , +27967 , +3029 , +9979 , +20469 , +-31801 , +21599 , +-1191 , +-20153 , +11721 , +-18493 , +3987 , +-16025 , +17399 , +-2517 , +-32605 , +-941 , +-29143 , +14453 , +-4833 , +25195 , +30827 , +-8649 , +-22125 , +7861 , +-29541 , +-1491 , +5459 , +-6267 , +-30593 , +13623 , +10205 , +4547 , +26719 , +20433 , +-12633 , +-12643 , +15897 , +-1529 , +13183 , +-29763 , +11453 , +14833 , +-31905 , +-4603 , +24741 , +6313 , +19907 , +24263 , +23559 , +-12861 , +5255 , +-23687 , +28695 , +8521 , +9271 , +30703 , +-17771 , +15403 , +19695 , +-23785 , +32748 , +-24771 , +-27729 , +32299 , +14791 , +30895 , +29749 , +26219 , +12841 , +4095 , +-13491 , +4441 , +775 , +-32643 , +441 , +15207 , +-11683 , +31283 , +-28809 , +-22211 , +-23867 , +16749 , +28583 , +-3227 , +-28519 , +-23387 , +-25383 , +5255 , +21371 , +8449 , +11761 , +12837 , +-9093 , +-4791 , +11117 , +-26677 , +26793 , +9055 , +-19119 , +23761 , +-8151 , +-16325 , +-28303 , +-21367 , +-9769 , +-19879 , +-17843 , +10491 , +6991 , +-20803 , +1643 , +24611 , +-4715 , +1123 , +-32723 , +-13409 , +7715 , +9787 , +-31189 , +21227 , +1151 , +9119 , +19461 , +-14309 , +25695 , +-14517 , +-11323 , +22291 , +-31693 , +-27435 , +-2129 , +24381 , +20553 , +23719 , +-25445 , +-20547 , +-7589 , +-24971 , +-23345 , +-25037 , +17837 , +29235 , +-17581 , +-4117 , +-12377 , +12181 , +-28723 , +3479 , +-6941 , +-29701 , +-25895 , +31115 , +-32049 , +26357 , +735 , +109 , +26053 , +-717 , +-18073 , +-25483 , +9111 , +-17923 , +26877 , +-31969 , +4791 , +24373 , +19323 , +21861 , +21957 , +-17473 , +-32533 , +-5509 , +-7257 , +-22393 , +-293 , +-21245 , +-7127 , +-31759 , +-20427 , +703 , +14603 , +-7213 , +-8809 , +-18727 , +-29795 , +-18959 , +30251 , +-8565 , +-18723 , +-30993 , +20739 , +12383 , +-6653 , +10187 , +-277 , +17895 , +16293 , +27093 , +17601 , +-16397 , +30019 , +10539 , +-10667 , +-15033 , +3947 , +23977 , +27063 , +-11301 , +-12723 , +27241 , +-17643 , +23685 , +-2359 , +25527 , +-26351 , +8515 , +-7143 , +-31865 , +-28259 , +-12831 , +-18983 , +-31631 , +22345 , +-15551 , +29353 , +6955 , +30505 , +-29433 , +30529 , +18039 , +30493 , +-1579 , +-30201 , +-21083 , +-2887 , +19975 , +27435 , +-14967 , +-9069 , +-30493 , +14657 , +-3091 , +21021 , +13403 , +-32177 , +27027 , +24571 , +-18631 , +22897 , +-5469 , +2275 , +-24093 , +18665 , +15785 , +-12053 , +-4723 , +30905 , +30991 , +22375 , +-23059 , +-7747 , +-6391 , +6463 , +-2691 , +-6849 , +-18401 , +-3125 , +3111 , +8471 , +15381 , +-32733 , +-10099 , +-10185 , +-9875 , +-8451 , +2989 , +-14387 , +31577 , +3331 , +24365 , +-16169 , +-20937 , +22443 , +-27135 , +-8645 , +8839 , +2709 , +12209 , +-20639 , +-12699 , +-4779 , +17931 , +12103 , +25983 , +-22055 , +-29353 , +-8163 , +24457 , +-19655 , +-4325 , +-7331 , +17727 , +-15083 , +-18617 , +26205 , +31703 , +-27803 , +-13329 , +15217 , +18167 , +-15657 , +-6259 , +-2183 , +14643 , +-15959 , +19879 , +27649 , +-13573 , +-26375 , +-3555 , +-10799 , +20513 , +20131 , +-30003 , +-26607 , +965 , +-4201 , +-31785 , +-9263 , +25299 , +-9549 , +20051 , +-5075 , +-29449 , +25625 , +385 , +-22811 , +-7137 , +26885 , +-14703 , +-9875 , +-23967 , +-5077 , +1737 , +-7543 , +-24955 , +21131 , +-11191 , +28777 , +-2315 , +22727 , +-31421 , +-19651 , +-9425 , +22785 , +-1625 , +-9143 , +11213 , +-1749 , +-31891 , +16777 , +10475 , +-9751 , +-5829 , +-583 , +-6355 , +24029 , +31661 , +25853 , +-15567 , +8589 , +-19199 , +9711 , +-29821 , +15277 , +23377 , +28469 , +-26335 , +-8703 , +-25257 , +-3675 , +-29085 , +28337 , +8593 , +5839 , +-2943 , +-19937 , +-32760 , +17441 , +28549 , +7495 , +7815 , +-32139 , +-16189 , +-6005 , +-6329 , +25137 , +20433 , +-1259 , +-11719 , +29657 , +29183 , +18093 , +-18257 , +11561 , +10321 , +-21491 , +27543 , +-27985 , +-29709 , +-69 , +-31683 , +32227 , +-24265 , +18275 , +-6281 , +-10307 , +-14073 , +-14417 , +29535 , +-24631 , +-30495 , +-1385 , +-12395 , +6089 , +-7861 , +1609 , +-10267 , +-5181 , +-5421 , +-13201 , +-26219 , +-20829 , +-3719 , +10775 , +23307 , +-31927 , +-14665 , +32764 , +-23031 , +18983 , +-32275 , +7017 , +-13201 , +11093 , +26465 , +-26735 , +-8347 , +-10957 , +11697 , +-12451 , +-28387 , +18287 , +22989 , +30671 , +-1785 , +-32081 , +-5773 , +-1325 , +-19833 , +-2911 , +1057 , +-21861 , +20019 , +-1905 , +-5491 , +-6793 , +-29307 , +17537 , +-9051 , +16935 , +24857 , +-25909 , +11775 , +23739 , +8539 , +-26581 , +16593 , +23527 , +-1587 , +-2463 , +-24723 , +-14629 , +-335 , +6981 , +-5059 , +-15461 , +-6835 , +19549 , +-8149 , +21977 , +-10597 , +24313 , +4013 , +-18869 , +21633 , +15565 , +-20945 , +23167 , +-22129 , +5375 , +2063 , +-15039 , +-9419 , +-28213 , +-5353 , +-18589 , +-27021 , +-5485 , +-19083 , +-9959 , +3869 , +10873 , +17199 , +29659 , +18829 , +-31879 , +29213 , +21679 , +-14631 , +1535 , +29795 , +28427 , +2961 , +-27395 , +-22169 , +22571 , +-1809 , +28299 , +13643 , +13025 , +28825 , +8437 , +3809 , +9211 , +15053 , +17499 , +-17367 , +-6387 , +-22747 , +-12097 , +30017 , +-25643 , +-8249 , +26795 , +-6685 , +25609 , +26399 , +28733 , +17757 , +-5703 , +-18405 , +18629 , +-759 , +26139 , +-32549 , +-30499 , +-27329 , +16621 , +28655 , +-30469 , +8403 , +-8117 , +3087 , +7315 , +-8433 , +-16127 , +-29103 , +-12379 , +19489 , +28523 , +14049 , +-32547 , +22561 , +30923 , +5175 , +-20443 , +-901 , +-4839 , +-19241 , +22975 , +-6159 , +-30359 , +-17537 , +-18975 , +30991 , +8885 , +-12827 , +-19257 , +-16605 , +26945 , +-10769 , +-28851 , +-17993 , +-25493 , +3429 , +17415 , +-29051 , +18181 , +-13261 , +22751 , +-4623 , +-25553 , +-28393 , +-18145 , +24071 , +-29527 , +15585 , +2073 , +-23577 , +11449 , +-2009 , +16433 , +967 , +-32147 , +-17543 , +-2429 , +-28827 , +21645 , +-3549 , +6891 , +15111 , +4569 , +12127 , +-29521 , +-3865 , +26869 , +28169 , +23427 , +23349 , +-22343 , +-11551 , +3381 , +-25463 , +-32507 , +26937 , +-16461 , +-20765 , +15395 , +-11723 , +32693 , +-24299 , +2199 , +24189 , +-21565 , +27341 , +27513 , +-30089 , +-17447 , +-28933 , +29519 , +21765 , +17789 , +17623 , +-15519 , +26799 , +-27567 , +24401 , +3991 , +-28819 , +-20683 , +-21747 , +8393 , +26827 , +8663 , +-1319 , +-1631 , +-9547 , +25291 , +-25949 , +13287 , +13471 , +11819 , +24825 , +11879 , +32073 , +-21341 , +5877 , +9019 , +-7445 , +-16619 , +28353 , +-16721 , +-14855 , +18087 , +16517 , +20109 , +22097 , +-16027 , +17897 , +8703 , +15101 , +4943 , +3073 , +12775 , +15459 , +-11273 , +21455 , +-22097 , +26875 , +-1897 , +-26309 , +26789 , +-21357 , +12969 , +-1921 , +5079 , +20987 , +-9471 , +10799 , +-12189 , +26435 , +-16027 , +-12891 , +15961 , +31855 , +-18273 , +-17919 , +-13303 , +-19277 , +14107 , +-29285 , +-1567 , +-24017 , +-7167 , +13309 , +-22843 , +-7145 , +26821 , +-26017 , +-797 , +-131 , +24389 , +19095 , +5901 , +27265 , +-19359 , +9369 , +-2409 , +16901 , +22289 , +-4501 , +-7773 , +-24081 , +-29701 , +-3431 , +-15871 , +6103 , +-17007 , +25915 , +-25463 , +10311 , +8353 , +-14503 , +-18197 , +24173 , +1401 , +243 , +-28143 , +-8617 , +11631 , +26997 , +9963 , +-3671 , +-761 , +30377 , +-15407 , +-31019 , +-7549 , +18999 , +-9129 , +6869 , +-14083 , +-10857 , +3495 , +1375 , +-4091 , +-13171 , +-7851 , +-24669 , +-83 , +7713 , +26811 , +15739 , +-20183 , +11283 , +18637 , +28971 , +-7193 , +30931 , +20089 , +-28267 , +30501 , +1027 , +9077 , +-1297 , +-16373 , +3425 , +15261 , +515 , +-3011 , +30281 , +-27961 , +4571 , +24827 , +31141 , +21281 , +-5115 , +-14667 , +-3471 , +-1021 , +-31935 , +-20187 , +-5979 , +8525 , +26815 , +9185 , +-25417 , +23351 , +17367 , +29565 , +-13939 , +32433 , +19519 , +-23781 , +21753 , +-18891 , +16065 , +7809 , +9903 , +-27869 , +-15239 , +10431 , +23997 , +-20585 , +-15223 , +-10441 , +-25465 , +-1855 , +-26545 , +-3781 , +-23755 , +14783 , +-26079 , +-29657 , +-3911 , +-269 , +1667 , +-17413 , +-24007 , +27099 , +-22559 , +12395 , +18703 , +3431 , +17605 , +5755 , +-4283 , +27353 , +18573 , +5789 , +641 , +10003 , +-24919 , +-14531 , +23941 , +-28553 , +14413 , +27617 , +10281 , +-29383 , +13485 , +22725 , +-14903 , +-30153 , +9139 , +-11545 , +-30137 , +-32165 , +23353 , +-15193 , +28037 , +-18843 , +-10565 , +7903 , +30029 , +11595 , +-26217 , +15995 , +3547 , +-27375 , +3011 , +11915 , +2251 , +-25569 , +18689 , +7905 , +31379 , +23319 , +-9577 , +-6357 , +11899 , +-6347 , +-11375 , +-4477 , +-5861 , +-23269 , +-14487 , +20367 , +12613 , +29749 , +-27825 , +-28397 , +-10355 , +19079 , +29139 , +-13557 , +-3021 , +22797 , +20775 , +-28601 , +-27737 , +20621 , +-7211 , +29819 , +-13959 , +-8461 , +25585 , +-31007 , +25041 , +-727 , +-32551 , +-26299 , +-5775 , +9575 , +28521 , +-21591 , +17437 , +2587 , +-27469 , +21587 , +-30303 , +-6863 , +-15563 , +31855 , +24897 , +-2063 , +-32103 , +18717 , +-27725 , +21341 , +23011 , +-30449 , +2971 , +-32515 , +-27599 , +32415 , +-899 , +9283 , +30697 , +24169 , +26677 , +11353 , +26753 , +23133 , +-17673 , +-20863 , +-5467 , +-28317 , +-19009 , +231 , +765 , +-17565 , +24393 , +11775 , +-6307 , +-5649 , +13199 , +22613 , +31359 , +13639 , +18877 , +9963 , +-30147 , +-20987 , +-22361 , +-11759 , +18503 , +27431 , +-32315 , +-5957 , +-2725 , +3241 , +-30035 , +26201 , +14079 , +-30043 , +11521 , +12593 , +4023 , +-22303 , +-15119 , +-26319 , +-3653 , +-6417 , +-22993 , +-4273 , +-7115 , +17597 , +8043 , +-12961 , +13043 , +-19527 , +13375 , +9831 , +-24413 , +-29607 , +17851 , +-18567 , +-27769 , +-8127 , +24901 , +-3825 , +13493 , +211 , +28199 , +-3877 , +-1595 , +4683 , +-3717 , +-23515 , +-28403 , +853 , +-24415 , +-21851 , +-22437 , +-16091 , +31299 , +4561 , +-31187 , +15 , +-25151 , +-32573 , +-4763 , +28833 , +-26323 , +-4991 , +17285 , +-18119 , +26053 , +27879 , +29027 , +3103 , +-13591 , +18925 , +30313 , +-19945 , +24469 , +-9845 , +9793 , +24961 , +-7595 , +17937 , +2327 , +-17939 , +8131 , +-11019 , +-10673 , +-17355 , +8053 , +-14793 , +-32329 , +-26863 , +-12413 , +25645 , +21319 , +-24527 , +-6541 , +23531 , +339 , +-11817 , +13239 , +-2553 , +17737 , +-23313 , +5797 , +18437 , +-7451 , +-24669 , +21479 , +-2531 , +-26141 , +28789 , +387 , +-25181 , +-1465 , +-4645 , +-16061 , +32723 , +-27901 , +-11695 , +437 , +-31443 , +29505 , +-29453 , +32161 , +12625 , +30213 , +-361 , +-19965 , +-24751 , +20607 , +31585 , +-32127 , +7819 , +-9557 , +-5917 , +-15259 , +-30715 , +-30055 , +20647 , +-6131 , +-7105 , +-26083 , +-16551 , +30963 , +31115 , +-12533 , +-14257 , +-21485 , +-9493 , +24045 , +-31319 , +-19215 , +3941 , +-8389 , +27879 , +6411 , +27101 , +-12523 , +-12283 , +-17971 , +10597 , +-28809 , +25353 , +-13037 , +31269 , +25847 , +-25047 , +31769 , +-4447 , +26101 , +21591 , +24823 , +2463 , +-11173 , +22109 , +-25965 , +-3975 , +-9773 , +31351 , +-20701 , +-8721 , +7799 , +-8085 , +-2789 , +28049 , +12821 , +-13795 , +-17745 , +22399 , +16353 , +-8023 , +-7231 , +-19239 , +1195 , +15871 , +13917 , +25729 , +32669 , +4851 , +3509 , +-22393 , +21867 , +16863 , +-21613 , +-27663 , +24083 , +-14929 , +-8107 , +24861 , +21775 , +15749 , +16737 , +18577 , +9237 , +29897 , +-23005 , +-4003 , +-16319 , +16323 , +9087 , +3051 , +4573 , +-31563 , +15821 , +17497 , +-8563 , +-13967 , +-30385 , +339 , +11789 , +7537 , +28965 , +10855 , +8553 , +-18321 , +23763 , +30947 , +-19281 , +9599 , +-5079 , +29223 , +25393 , +21159 , +-32319 , +-23937 , +9781 , +23793 , +-11271 , +12413 , +-14803 , +28937 , +-17299 , +24783 , +-2441 , +-26537 , +-539 , +8857 , +13195 , +-13681 , +14551 , +15433 , +-9287 , +7121 , +-14755 , +12529 , +31327 , +24377 , +-20057 , +30245 , +-16989 , +5633 , +-30721 , +4679 , +3751 , +783 , +14127 , +15207 , +17479 , +15125 , +-19827 , +3741 , +26699 , +2339 , +-27035 , +-2085 , +1823 , +32705 , +-32267 , +-7611 , +533 , +3723 , +24551 , +-14063 , +23567 , +-3005 , +21833 , +-16169 , +-1859 , +-6805 , +-28929 , +4455 , +-14755 , +-16545 , +-23099 , +30765 , +18915 , +-24597 , +-12131 , +11005 , +1469 , +14691 , +-25139 , +-19599 , +-19705 , +-17605 , +27223 , +15039 , +-15033 , +10019 , +20463 , +24081 , +12445 , +27285 , +-16017 , +9055 , +-5505 , +5369 , +-29221 , +9925 , +7413 , +567 , +-32309 , +-26535 , +-31667 , +-11825 , +24429 , +8841 , +-4271 , +-32147 , +25851 , +20719 , +23045 , +2573 , +6573 , +-28761 , +-25899 , +17031 , +-26313 , +23339 , +6749 , +683 , +5569 , +-18261 , +-29295 , +-17445 , +-14241 , +-28959 , +10875 , +29731 , +2049 , +-2195 , +20343 , +29901 , +-16647 , +8363 , +5349 , +-31363 , +-2327 , +-10229 , +-16027 , +3013 , +-19655 , +21741 , +-26481 , +-6333 , +-11751 , +23535 , +-987 , +25139 , +11249 , +21199 , +22483 , +3721 , +-22177 , +23747 , +-12447 , +-6257 , +-30811 , +5959 , +10097 , +-28687 , +-31825 , +3967 , +-8017 , +1115 , +9085 , +-30707 , +-621 , +-25959 , +-10717 , +-22683 , +27279 , +-23263 , +8773 , +-22873 , +-32563 , +-27853 , +-25853 , +6391 , +-25755 , +-6801 , +-11399 , +-7333 , +14101 , +-12559 , +2229 , +-759 , +-27523 , +-9505 , +-17867 , +-28607 , +21713 , +28303 , +-5935 , +-27731 , +2321 , +-32750 , +13379 , +29745 , +11207 , +22869 , +-28911 , +-6333 , +32059 , +-16461 , +-16111 , +32205 , +14891 , +22541 , +28761 , +3955 , +9477 , +-24723 , +-5957 , +-27007 , +-9833 , +20495 , +22965 , +-27603 , +25431 , +-29955 , +-15621 , +-27265 , +-29173 , +-25037 , +18265 , +-3933 , +-5877 , +-16605 , +7741 , +21187 , +-2829 , +-28191 , +-9311 , +13913 , +29661 , +-11095 , +18063 , +-9713 , +21535 , +2053 , +30223 , +-12271 , +11637 , +27485 , +27815 , +-16915 , +-14135 , +9747 , +-5553 , +25823 , +-21923 , +-2791 , +-21271 , +-30031 , +5777 , +13577 , +-10441 , +-9451 , +-30449 , +-24387 , +-18855 , +22901 , +5765 , +-25493 , +-25151 , +31571 , +-20251 , +25909 , +4523 , +-31971 , +-14829 , +-699 , +-2031 , +13185 , +12583 , +11373 , +2097 , +29521 , +-2537 , +27951 , +12403 , +-1585 , +-16383 , +7777 , +10991 , +-25721 , +-26157 , +-11967 , +-1957 , +20399 , +-9847 , +3089 , +31115 , +-31239 , +-18963 , +22821 , +-8349 , +-6939 , +32447 , +-1403 , +10581 , +2215 , +-4229 , +6659 , +27217 , +23157 , +-27511 , +-12849 , +3141 , +-26529 , +-17675 , +-13935 , +-13807 , +9645 , +-7503 , +5127 , +-26627 , +-17487 , +11069 , +-26353 , +12981 , +-27867 , +-19729 , +-4019 , +-29505 , +-25093 , +24733 , +12349 , +-11655 , +-5699 , +4063 , +9675 , +15489 , +-15779 , +-26683 , +-14229 , +26815 , +-21095 , +-23541 , +17073 , +29143 , +-10557 , +-10031 , +26475 , +32023 , +809 , +14557 , +-5319 , +-2303 , +-22815 , +17987 , +15005 , +13875 , +12837 , +-10837 , +17569 , +-17175 , +12079 , +3075 , +4581 , +-12051 , +18569 , +32437 , +-32715 , +-24037 , +-12303 , +-4509 , +-1363 , +-18613 , +-8801 , +-27619 , +-31163 , +-9773 , +-24527 , +31005 , +-1299 , +14201 , +-2829 , +-12043 , +-16087 , +-3347 , +-7997 , +-12717 , +-5087 , +-9529 , +351 , +-5583 , +2113 , +32501 , +-28863 , +5519 , +30283 , +23733 , +2045 , +-12883 , +-21771 , +22805 , +6415 , +-30013 , +11003 , +16869 , +-7369 , +-32463 , +-25671 , +-29397 , +11863 , +11591 , +-16315 , +3875 , +-23107 , +-24213 , +-17659 , +-8527 , +-19191 , +3805 , +27589 , +8289 , +7553 , +-32529 , +16983 , +-4141 , +-9243 , +17073 , +23969 , +8125 , +30407 , +-6341 , +20283 , +2143 , +19817 , +27733 , +23429 , +7291 , +-237 , +28597 , +-29121 , +31949 , +-32029 , +-4417 , +31653 , +16901 , +2099 , +-30547 , +1535 , +-19139 , +14181 , +-17581 , +-65 , +12017 , +-5313 , +4693 , +537 , +-11145 , +-1335 , +-16165 , +20503 , +-5127 , +11159 , +-25139 , +7733 , +-279 , +-6991 , +-1399 , +5753 , +-32001 , +-17953 , +19483 , +28935 , +16813 , +26505 , +7925 , +31035 , +13843 , +22281 , +19755 , +-10427 , +6529 , +17283 , +-4317 , +30267 , +22119 , +5959 , +-299 , +24241 , +-26163 , +-26213 , +9595 , +24027 , +-17579 , +1309 , +-21547 , +-12011 , +13219 , +7827 , +1233 , +28169 , +-9885 , +-7089 , +-5423 , +24383 , +7351 , +28151 , +-30885 , +-29383 , +31035 , +5355 , +-25257 , +27657 , +22125 , +32023 , +11711 , +9577 , +3761 , +-27063 , +-28963 , +30549 , +21705 , +11791 , +28163 , +7965 , +-20541 , +10761 , +-19519 , +10505 , +17787 , +707 , +-15717 , +-925 , +-21615 , +-26865 , +2119 , +31769 , +-2339 , +-4131 , +22879 , +5071 , +-16021 , +3213 , +3999 , +2427 , +24303 , +20431 , +25235 , +-5253 , +-2111 , +-23307 , +-3363 , +29489 , +-15785 , +-2605 , +-31 , +-19439 , +4913 , +2315 , +16385 , +-4285 , +31589 , +24815 , +-11433 , +-7239 , +-21121 , +13011 , +18669 , +-3389 , +24847 , +3819 , +11891 , +-3797 , +-4971 , +20635 , +8819 , +-823 , +-12807 , +-4263 , +-7917 , +11937 , +-9849 , +-14339 , +17223 , +-32395 , +18281 , +-2409 , +-22395 , +-15135 , +22419 , +22739 , +-15611 , +-2831 , +-15283 , +-12091 , +15991 , +-12743 , +-17637 , +24649 , +14645 , +-2449 , +-27587 , +-19247 , +2053 , +-28291 , +169 , +15305 , +15429 , +-25819 , +-6533 , +22377 , +25775 , +-8951 , +-23565 , +-13299 , +-32631 , +-9901 , +-3859 , +-501 , +-25249 , +-32317 , +5845 , +6161 , +-26817 , +4933 , +-18653 , +-19975 , +29545 , +-4587 , +-10157 , +4127 , +19853 , +-15797 , +29015 , +-27841 , +20357 , +-5897 , +11159 , +28869 , +-21629 , +16829 , +-27803 , +19373 , +4307 , +27877 , +28405 , +-14889 , +-27885 , +-17925 , +29655 , +-24097 , +31713 , +-23837 , +4841 , +-29321 , +-227 , +11119 , +-27941 , +11321 , +18845 , +-643 , +12569 , +31497 , +-7577 , +-26231 , +-32437 , +9189 , +-10653 , +29641 , +-15539 , +-9665 , +-22883 , +21955 , +26533 , +22485 , +28915 , +-9117 , +31357 , +4619 , +19285 , +27291 , +11539 , +16323 , +18809 , +26737 , +13759 , +18353 , +9487 , +9885 , +15971 , +12085 , +133 , +16031 , +6493 , +8629 , +15407 , +-14505 , +-2805 , +-22413 , +-10735 , +13857 , +17855 , +-21787 , +19459 , +17509 , +-25041 , +-12399 , +30845 , +-20043 , +11897 , +21851 , +25025 , +14949 , +8595 , +-663 , +29591 , +-25953 , +-28345 , +7539 , +7047 , +-2559 , +18601 , +29341 , +16271 , +31661 , +3343 , +-13101 , +-30887 , +-24855 , +-23161 , +10905 , +-4099 , +-17359 , +22745 , +23915 , +-24025 , +-32043 , +6639 , +-12655 , +-32029 , +-1269 , +6875 , +31859 , +30405 , +-32633 , +-441 , +-14211 , +-12371 , +-30307 , +24433 , +11625 , +-8973 , +-27959 , +-5985 , +30241 , +5675 , +1749 , +-20451 , +-29421 , +-10155 , +31593 , +5039 , +31753 , +11671 , +6695 , +-13683 , +-19329 , +-26761 , +-29119 , +26071 , +14469 , +21395 , +20115 , +-2157 , +-17401 , +4819 , +-25549 , +6175 , +22193 , +-25815 , +3481 , +555 , +-8633 , +19395 , +-473 , +-715 , +-32399 , +-1079 , +-17847 , +-12679 , +-17627 , +11151 , +-16373 , +26739 , +13935 , +81 , +-5067 , +-28469 , +-17711 , +613 , +-5155 , +-19241 , +-18147 , +5629 , +-13699 , +-23407 , +-28477 , +-22951 , +-2919 , +27657 , +9655 , +31611 , +-31035 , +871 , +-8519 , +12905 , +16713 , +3419 , +-23491 , +-12325 , +-1993 , +23573 , +-2119 , +25979 , +-10241 , +29889 , +-17539 , +16791 , +22155 , +-13951 , +-15597 , +-24225 , +10451 , +-7713 , +-15351 , +23955 , +5371 , +10691 , +-16549 , +-30265 , +-1817 , +-24839 , +31547 , +32277 , +-8881 , +5397 , +9587 , +17235 , +28001 , +18431 , +-18889 , +-9777 , +-21807 , +29917 , +11135 , +21129 , +13939 , +-20083 , +13541 , +13023 , +1367 , +-17757 , +26609 , +6869 , +-9641 , +28637 , +-27397 , +9665 , +23613 , +-18659 , +21629 , +-627 , +8269 , +-549 , +25841 , +6245 , +-32407 , +4389 , +-3805 , +6385 , +-25699 , +-31723 , +22283 , +-14057 , +17477 , +23745 , +-30935 , +-22747 , +22169 , +16323 , +-27563 , +32147 , +11465 , +-11747 , +-29667 , +-713 , +-25191 , +-30269 , +12191 , +-11779 , +22129 , +-23413 , +-23335 , +10781 , +-5635 , +32161 , +-18299 , +10203 , +27457 , +-1657 , +-14217 , +13749 , +-4817 , +16521 , +-4501 , +-19167 , +-16699 , +32693 , +-31901 , +-61 , +-17503 , +-6059 , +-27781 , +13095 , +-30443 , +-23071 , +23111 , +-16649 , +6087 , +641 , +24487 , +11697 , +16841 , +29183 , +19741 , +8165 , +-8921 , +-17605 , +5035 , +-3609 , +6921 , +-2007 , +31267 , +1037 , +-29881 , +-23475 , +-21495 , +7517 , +-25471 , +29093 , +-7969 , +-7983 , +-3911 , +7217 , +-19445 , +-13047 , +24165 , +-3105 , +17697 , +-16765 , +-2541 , +21767 , +-18235 , +27729 , +-7053 , +-14487 , +12797 , +-10411 , +-30471 , +-1129 , +-9199 , +9211 , +-26383 , +24319 , +7381 , +-10647 , +-22765 , +32337 , +-30831 , +-5829 , +-6233 , +-4475 , +-22449 , +-18751 , +-30447 , +-2997 , +16307 , +11435 , +30959 , +-24057 , +1879 , +16971 , +-4691 , +-23483 , +-26971 , +10571 , +-29535 , +29879 , +-32729 , +12511 , +-31579 , +11177 , +16231 , +-11387 , +29991 , +-22539 , +3901 , +-6343 , +31173 , +17795 , +16567 , +26669 , +12905 , +-9663 , +10847 , +-10751 , +8155 , +12687 , +18465 , +-25733 , +11487 , +-16825 , +-23651 , +30913 , +-17469 , +-17621 , +7419 , +26639 , +4227 , +29149 , +-21429 , +-2831 , +28507 , +-8099 , +13147 , +32247 , +-14373 , +29949 , +-2037 , +22767 , +17547 , +6359 , +24359 , +20897 , +-26891 , +16587 , +-61 , +31489 , +22599 , +15599 , +-22775 , +-13591 , +22117 , +32401 , +25759 , +30803 , +9605 , +3239 , +14195 , +-27633 , +-12729 , +-8505 , +29465 , +-11269 , +-4023 , +22181 , +30113 , +2239 , +12609 , +-28667 , +-14865 , +13817 , +20631 , +-16583 , +12949 , +-15097 , +-18563 , +22033 , +2343 , +-13775 , +-8829 , +10075 , +-487 , +-11163 , +22963 , +16599 , +-8943 , +16241 , +-2011 , +-19541 , +-26175 , +-32583 , +-21473 , +871 , +-9917 , +26223 , +-18785 , +29553 , +-29721 , +-16051 , +-9853 , +-5375 , +-20583 , +28873 , +-4329 , +-22629 , +-11601 , +18897 , +-16847 , +30215 , +28479 , +-12285 , +25281 , +-22077 , +-18687 , +14689 , +8953 , +-29949 , +-6239 , +-19315 , +2259 , +29479 , +-16493 , +27005 , +6201 , +20397 , +11125 , +11451 , +31119 , +-15439 , +-15395 , +23825 , +28887 , +-24611 , +13243 , +-7221 , +31037 , +-5907 , +7973 , +-12435 , +23871 , +9369 , +-23879 , +-32539 , +-23761 , +9495 , +881 , +-7349 , +9829 , +2827 , +-22787 , +-23019 , +13501 , +-18933 , +-4967 , +-3635 , +2247 , +23433 , +-415 , +-28849 , +-1975 , +31827 , +13107 , +-1667 , +12137 , +-3957 , +6401 , +20851 , +20537 , +16927 , +-16473 , +-21173 , +-12585 , +3513 , +23621 , +-18105 , +25087 , +-23995 , +-8935 , +9107 , +24615 , +-26915 , +-31271 , +-13703 , +24853 , +-28857 , +11395 , +9495 , +-1033 , +-6423 , +11959 , +-8547 , +-1541 , +31305 , +-18533 , +7167 , +-10903 , +18171 , +28189 , +25649 , +-8903 , +6687 , +9187 , +-23843 , +-10965 , +1367 , +-25453 , +15771 , +27233 , +-11713 , +1451 , +-19541 , +21619 , +11367 , +14051 , +-16343 , +31499 , +-17975 , +21249 , +30411 , +-2053 , +-9791 , +-7895 , +21267 , +19927 , +17027 , +-2367 , +-19961 , +-21751 , +13597 , +-30271 , +-20879 , +-28305 , +32738 , +-31859 , +-10351 , +-17813 , +1891 , +-21423 , +-17841 , +-28797 , +3573 , +1747 , +-19199 , +3955 , +-3685 , +-19253 , +3479 , +30669 , +-26493 , +-1085 , +-15781 , +-29951 , +17405 , +-32157 , +3361 , +-13557 , +497 , +24151 , +4359 , +-32647 , +29921 , +2713 , +-21849 , +-6647 , +10833 , +-8621 , +-9513 , +20677 , +14283 , +7219 , +-15405 , +-21355 , +22103 , +12867 , +-20219 , +9565 , +13417 , +16961 , +8497 , +21643 , +13925 , +-30087 , +19253 , +-13509 , +23951 , +-14567 , +5431 , +20681 , +-29309 , +9229 , +-2451 , +-21017 , +-6091 , +-10407 , +-17597 , +23609 , +30817 , +-1049 , +-23521 , +-3477 , +-7549 , +-15127 , +-10599 , +-23349 , +21589 , +-24147 , +-26327 , +-19875 , +27329 , +27125 , +20841 , +5751 , +18015 , +10963 , +-17207 , +22233 , +-31131 , +-21513 , +23495 , +-14785 , +25129 , +17813 , +-30807 , +4997 , +-26357 , +7853 , +10929 , +32045 , +28927 , +27637 , +-27941 , +-32373 , +31607 , +-14561 , +22287 , +25423 , +22749 , +14013 , +-14629 , +23203 , +12947 , +-361 , +-9043 , +-13631 , +9057 , +-12159 , +10887 , +21513 , +18035 , +30129 , +-18113 , +6815 , +-23343 , +-30565 , +21037 , +6529 , +-18093 , +22345 , +11109 , +-9705 , +-15585 , +-31185 , +28283 , +26711 , +-24935 , +-29817 , +-28251 , +-9385 , +23777 , +-25817 , +-1141 , +19041 , +20941 , +6873 , +-5779 , +-31081 , +-12199 , +14131 , +4065 , +28925 , +19877 , +-20235 , +-4591 , +17689 , +8813 , +31443 , +19301 , +-20467 , +-23811 , +16347 , +-10289 , +3109 , +-14931 , +27205 , +26219 , +-26369 , +4057 , +-15663 , +-17715 , +2063 , +337 , +16535 , +24747 , +13767 , +-18847 , +8551 , +-31207 , +26411 , +-1991 , +-7525 , +20549 , +-7197 , +29679 , +12915 , +-23895 , +17627 , +20461 , +29161 , +-12089 , +20311 , +-10247 , +-8429 , +12891 , +-19317 , +30621 , +-23 , +4639 , +-29263 , +-17627 , +26029 , +-4363 , +-4953 , +-28899 , +24769 , +-30809 , +22787 , +30271 , +-17165 , +-22237 , +-28245 , +-4621 , +7781 , +14117 , +27373 , +-18115 , +5849 , +26491 , +8471 , +19009 , +-29807 , +-22595 , +-2159 , +565 , +-31839 , +9597 , +31859 , +32731 , +-2361 , +28933 , +18589 , +-19343 , +-19251 , +12941 , +-27567 , +-2251 , +-685 , +27125 , +30791 , +-12457 , +-8145 , +12537 , +13129 , +-21391 , +-443 , +30701 , +19529 , +17791 , +-15653 , +-19209 , +-5893 , +-10663 , +-21127 , +-581 , +12523 , +-3163 , +-15309 , +-31837 , +5393 , +11607 , +-14701 , +-5491 , +21493 , +14249 , +14557 , +29189 , +4669 , +-11639 , +-8197 , +26879 , +-8255 , +10137 , +-14905 , +-7157 , +-32461 , +-10583 , +24039 , +11793 , +22057 , +26793 , +-7385 , +-5239 , +-19527 , +24867 , +-31407 , +26671 , +2963 , +-22987 , +32637 , +1855 , +14229 , +30469 , +-20743 , +20009 , +-15895 , +-22337 , +-15727 , +-32305 , +-32359 , +25095 , +-26003 , +20025 , +25507 , +3317 , +-3985 , +28875 , +-18277 , +-18551 , +-7937 , +-8959 , +-8515 , +-25945 , +27757 , +21413 , +-24449 , +-111 , +-30519 , +-7029 , +8121 , +15319 , +-9171 , +21183 , +-23251 , +-1071 , +-18515 , +-11449 , +11431 , +-27741 , +27285 , +7769 , +1429 , +-29023 , +-31145 , +19217 , +24605 , +13657 , +10963 , +28071 , +7857 , +16895 , +-3271 , +28715 , +-15309 , +31597 , +-25763 , +7611 , +-10625 , +28307 , +-2673 , +-10181 , +-29295 , +-391 , +18677 , +-3949 , +9995 , +687 , +-20389 , +6487 , +-18847 , +-21437 , +-28259 , +-5099 , +-13979 , +-5817 , +-14999 , +-1799 , +-18083 , +32439 , +-30809 , +22799 , +163 , +4349 , +-14263 , +15103 , +27835 , +-11545 , +-2903 , +25143 , +-31511 , +4889 , +-11945 , +4275 , +-699 , +24591 , +31873 , +21291 , +-29089 , +31371 , +12471 , +10187 , +2375 , +-12653 , +-8105 , +30577 , +51 , +-21783 , +16723 , +22877 , +-9325 , +-4353 , +24985 , +-26251 , +-19549 , +26483 , +23517 , +-1811 , +-14711 , +-28409 , +17661 , +8589 , +-7445 , +-1517 , +-5681 , +-15517 , +-24821 , +-1403 , +30083 , +-11015 , +-19369 , +-1449 , +-26513 , +28177 , +22407 , +-385 , +18289 , +13533 , +-6859 , +-19339 , +-21563 , +-10831 , +-17679 , +-19423 , +23383 , +32071 , +-27425 , +12369 , +29093 , +-12953 , +18375 , +-12869 , +-24309 , +17451 , +12215 , +-10129 , +-11095 , +-29255 , +11023 , +-28723 , +31403 , +-18325 , +31267 , +-16127 , +3891 , +-15463 , +23377 , +26617 , +-97 , +-32567 , +-17513 , +-28961 , +32367 , +16229 , +-11353 , +9227 , +24469 , +15093 , +2441 , +-377 , +-27311 , +17369 , +-4437 , +-14089 , +25987 , +-25981 , +-19845 , +2849 , +-4207 , +29989 , +-7807 , +2519 , +6827 , +10225 , +-14091 , +-19075 , +-31565 , +26581 , +22231 , +24305 , +-30321 , +-24665 , +-12663 , +27411 , +-1279 , +-12315 , +10723 , +-17231 , +-24319 , +-3857 , +32463 , +3331 , +6801 , +20409 , +16737 , +-5465 , +14103 , +-8957 , +-17815 , +-26859 , +24633 , +-6377 , +-30061 , +31379 , +11311 , +13821 , +-28163 , +26295 , +-20321 , +563 , +5193 , +24407 , +-21007 , +-16923 , +28989 , +8707 , +11053 , +10405 , +18903 , +9215 , +-26037 , +-23129 , +27107 , +16055 , +7445 , +19569 , +19993 , +-15683 , +627 , +-21477 , +-24913 , +10557 , +5201 , +-18175 , +30325 , +7153 , +-12821 , +-8963 , +-12695 , +2977 , +4775 , +-24029 , +-6699 , +3353 , +32117 , +-4109 , +-285 , +13471 , +-8033 , +21269 , +18353 , +10215 , +3619 , +18315 , +18421 , +7827 , +-32627 , +-651 , +-21755 , +2345 , +-949 , +-28613 , +-16769 , +5767 , +-15989 , +10321 , +32085 , +20447 , +26251 , +-159 , +32619 , +-31957 , +-3461 , +-16617 , +-23123 , +13355 , +20683 , +12867 , +-9559 , +-13355 , +-19191 , +-16223 , +-16477 , +-16807 , +1849 , +-21235 , +-25037 , +-8313 , +-3927 , +-29133 , +30293 , +-25125 , +-24245 , +-1579 , +-32505 , +23527 , +-6765 , +-9609 , +-155 , +-24497 , +-23357 , +26523 , +-20943 , +21573 , +24523 , +14459 , +-18945 , +-14215 , +-14173 , +26947 , +28609 , +-18279 , +2589 , +19133 , +-10787 , +1347 , +-10179 , +-27493 , +-1587 , +23683 , +-7911 , +-28131 , +22071 , +-30525 , +-18905 , +16727 , +21881 , +-25015 , +-14821 , +-8989 , +-6957 , +-16591 , +32575 , +-14311 , +27629 , +-21027 , +12871 , +21957 , +253 , +-6667 , +-12883 , +24931 , +12633 , +29655 , +2439 , +13015 , +13965 , +17049 , +7135 , +-23387 , +-4105 , +6261 , +-29299 , +1185 , +30939 , +-1585 , +18317 , +-22733 , +-19707 , +10911 , +28885 , +-23289 , +-25135 , +-31115 , +13491 , +-17589 , +-11825 , +26343 , +2465 , +-14753 , +-1833 , +-12145 , +-28517 , +-12523 , +-25949 , +7809 , +-23301 , +8801 , +5603 , +-7097 , +-19247 , +27547 , +7643 , +15951 , +-1609 , +18735 , +-27531 , +18673 , +-21971 , +21461 , +6361 , +-2599 , +-17553 , +4179 , +8845 , +-2037 , +19405 , +-15453 , +261 , +-433 , +19845 , +-24131 , +-26693 , +-3019 , +-30183 , +20165 , +11981 , +-32377 , +-27099 , +10953 , +12307 , +-32705 , +-12865 , +24559 , +10415 , +-24317 , +-3773 , +11063 , +-6351 , +-2535 , +31413 , +22451 , +3623 , +-25369 , +17303 , +25651 , +-3271 , +15841 , +-27843 , +19343 , +8895 , +-25849 , +11687 , +26445 , +24539 , +-6949 , +31449 , +25833 , +30985 , +3545 , +24249 , +-14977 , +-14009 , +-11151 , +-9893 , +-8177 , +-16995 , +-17541 , +2021 , +-8661 , +14143 , +-22217 , +-25127 , +-21705 , +8733 , +25785 , +28417 , +19995 , +6149 , +-22037 , +8627 , +-23169 , +26671 , +3071 , +-24141 , +-385 , +23397 , +24173 , +27533 , +32235 , +3207 , +-9115 , +18533 , +-11275 , +-21067 , +-14645 , +-28073 , +12907 , +-28197 , +-20307 , +-26295 , +-647 , +-11567 , +12859 , +16455 , +11989 , +-5139 , +14909 , +27483 , +-7303 , +8479 , +-18923 , +21983 , +3043 , +2693 , +-14297 , +26973 , +-18747 , +7305 , +17629 , +-21279 , +-4545 , +-31627 , +-20961 , +25817 , +-24681 , +12681 , +25921 , +-1185 , +-31371 , +25237 , +19335 , +-14045 , +-29551 , +-28651 , +-30445 , +-10577 , +-21765 , +2757 , +-19865 , +11861 , +-24131 , +9911 , +1105 , +-10639 , +-24275 , +19183 , +-4499 , +3153 , +18317 , +-17029 , +-23525 , +-10359 , +-3501 , +-31739 , +-5133 , +-29243 , +-9767 , +12531 , +-6721 , +24359 , +-4197 , +-2821 , +-265 , +-31969 , +-2331 , +-12995 , +-12879 , +7617 , +-12263 , +9687 , +2595 , +30111 , +28249 , +-14079 , +24205 , +-28135 , +28619 , +29343 , +17859 , +-9661 , +-12215 , +-8089 , +-20457 , +-13263 , +-20839 , +-18843 , +-22829 , +25817 , +-25557 , +4133 , +-22985 , +20573 , +28493 , +5697 , +-6673 , +31473 , +4067 , +28793 , +18437 , +6703 , +13983 , +-5037 , +9825 , +-14615 , +-26949 , +12327 , +-18755 , +-16505 , +27183 , +-11579 , +15641 , +-5407 , +-10139 , +-20611 , +-15169 , +-19571 , +12157 , +-12601 , +-26705 , +21445 , +26619 , +-17585 , +11417 , +-22097 , +-5379 , +-25711 , +-15521 , +11335 , +4861 , +-6153 , +26623 , +6309 , +24319 , +5479 , +-27627 , +28643 , +-12203 , +3167 , +9933 , +-8853 , +27333 , +-15217 , +-5281 , +7641 , +20309 , +-8977 , +26117 , +-437 , +26995 , +-30631 , +8053 , +-29639 , +9913 , +-22881 , +9941 , +-29231 , +12569 , +25121 , +567 , +-9519 , +-23649 , +10729 , +-14961 , +-21035 , +-20055 , +24643 , +-30675 , +-31171 , +14483 , +-27179 , +-3921 , +-19849 , +13313 , +-22227 , +3973 , +6879 , +-29561 , +-23827 , +16345 , +25883 , +14571 , +-22963 , +18201 , +2021 , +10709 , +-12731 , +27355 , +26481 , +-2031 , +20251 , +-19097 , +-28097 , +-12995 , +-19331 , +8357 , +-18833 , +32521 , +-27621 , +-8297 , +-6233 , +21737 , +-29511 , +32339 , +19799 , +28755 , +-5679 , +4217 , +20897 , +20333 , +-15451 , +9771 , +-5971 , +25171 , +-3117 , +-16505 , +-30599 , +10945 , +-18827 , +-2407 , +-5825 , +-8619 , +20405 , +-26659 , +9791 , +837 , +-29211 , +24879 , +22309 , +-109 , +-32744 , +8005 , +14801 , +4807 , +14653 , +25001 , +1213 , +-19929 , +-2133 , +-721 , +-1585 , +-16523 , +-30393 , +5355 , +-11855 , +-28133 , +17433 , +-7759 , +-26715 , +19179 , +27481 , +-4095 , +3563 , +27223 , +22811 , +3211 , +12933 , +8489 , +17489 , +-26849 , +-861 , +21429 , +-1165 , +29735 , +-5525 , +-14439 , +27537 , +21665 , +30555 , +29681 , +19433 , +-29549 , +4889 , +27663 , +-14841 , +12297 , +-20265 , +23731 , +29263 , +-20857 , +-30949 , +5059 , +-32473 , +-23293 , +6181 , +2693 , +26749 , +7777 , +6849 , +27223 , +-4625 , +-1435 , +23453 , +-31775 , +-6827 , +-19667 , +12071 , +12499 , +31715 , +14633 , +-29731 , +6177 , +26557 , +7575 , +25903 , +19629 , +-11249 , +-15501 , +24271 , +16013 , +24999 , +-12553 , +28807 , +30395 , +5131 , +-29809 , +-28003 , +5457 , +-31987 , +-32689 , +2719 , +-30145 , +10479 , +-5391 , +28865 , +-32637 , +9455 , +22853 , +1457 , +29669 , +19043 , +6451 , +28919 , +-5853 , +-11179 , +-18647 , +32707 , +-16195 , +-27243 , +17179 , +-951 , +-25579 , +-687 , +-27659 , +13723 , +-12991 , +-14283 , +16789 , +20483 , +-14039 , +-18949 , +-29371 , +-2607 , +-27565 , +7043 , +-3919 , +-32579 , +8721 , +-22157 , +-29853 , +13245 , +7739 , +16197 , +9903 , +-25257 , +6507 , +8931 , +2109 , +-17791 , +-28753 , +29893 , +19185 , +-3595 , +-15935 , +14459 , +-2451 , +-32760 , +-10043 , +-13865 , +-29437 , +27399 , +19581 , +5749 , +18481 , +-26617 , +1023 , +29659 , +-17511 , +6213 , +10485 , +27153 , +5747 , +18167 , +9545 , +19125 , +-17523 , +-12373 , +-15511 , +-4969 , +26559 , +13595 , +-5901 , +25551 , +-24859 , +-3965 , +-7173 , +3671 , +-26799 , +-16003 , +-15689 , +-13023 , +23499 , +18009 , +-21059 , +-15955 , +23559 , +29939 , +-17225 , +26661 , +9109 , +3079 , +15779 , +26103 , +28519 , +-27373 , +-6531 , +-6941 , +22973 , +3751 , +-5751 , +-11617 , +-11101 , +-10429 , +25595 , +-8987 , +10983 , +-3933 , +7991 , +-32235 , +-16495 , +13227 , +7305 , +3649 , +-15395 , +-29525 , +-7333 , +-9007 , +7091 , +-10175 , +2539 , +-18797 , +10391 , +30899 , +-3959 , +-23465 , +-19665 , +15293 , +10057 , +3585 , +-21715 , +-22279 , +30271 , +32299 , +-2603 , +20645 , +53 , +-7625 , +741 , +13063 , +30691 , +-24861 , +24605 , +-10175 , +-8279 , +20841 , +809 , +12457 , +-13371 , +-27373 , +-32217 , +-10845 , +-24823 , +-23211 , +-3441 , +-15625 , +-17897 , +13407 , +-22855 , +8361 , +5403 , +20031 , +-32305 , +13649 , +15353 , +-24467 , +6725 , +6387 , +9491 , +-525 , +25297 , +16475 , +-9615 , +30705 , +4579 , +30959 , +28041 , +-7481 , +32671 , +27911 , +11627 , +8099 , +12881 , +18635 , +-26751 , +665 , +-11925 , +-26745 , +-1345 , +11585 , +-18695 , +-3707 , +17763 , +-18997 , +-10347 , +-28065 , +-2775 , +-3435 , +14567 , +28639 , +-24063 , +16971 , +-20837 , +-5805 , +6991 , +10353 , +5591 , +-22685 , +-28777 , +-26995 , +-14547 , +-15247 , +-18753 , +-18001 , +30501 , +-10905 , +30403 , +9359 , +15647 , +-5359 , +-1297 , +-20949 , +-1829 , +9217 , +-19055 , +-9003 , +-12695 , +-6445 , +17469 , +13777 , +-3927 , +23831 , +-20877 , +18797 , +29235 , +18075 , +-2323 , +-11373 , +21733 , +-17071 , +30531 , +-14103 , +-28729 , +411 , +-465 , +-22425 , +17295 , +-6363 , +10305 , +-5783 , +-10857 , +-1465 , +-5353 , +-8625 , +10577 , +-2611 , +-13545 , +-7281 , +-20415 , +-24227 , +-19547 , +13139 , +-30599 , +-20407 , +-5671 , +13707 , +24969 , +-18201 , +4539 , +-23419 , +24575 , +-9113 , +-16899 , +24077 , +-18599 , +14129 , +-32213 , +14589 , +12929 , +-20039 , +-151 , +-18601 , +25285 , +18901 , +-7255 , +-4899 , +-21173 , +27801 , +21347 , +29225 , +-4341 , +30893 , +-18991 , +-17333 , +-4279 , +297 , +23455 , +-20269 , +22667 , +-5915 , +-2005 , +-12679 , +28691 , +-4523 , +25911 , +-15831 , +17365 , +-16409 , +-22235 , +-16223 , +-30997 , +12497 , +-18517 , +31879 , +-11111 , +-22931 , +-6893 , +4355 , +-28233 , +22037 , +-31769 , +-18221 , +9397 , +27509 , +-23245 , +-22041 , +-17399 , +-20635 , +29497 , +-4745 , +23341 , +-14525 , +7851 , +-29539 , +26133 , +-23349 , +-10657 , +-5781 , +25387 , +15979 , +-15989 , +-25471 , +11197 , +10269 , +29817 , +-20693 , +17155 , +9407 , +-10299 , +-30223 , +-29815 , +18417 , +-1521 , +28603 , +4913 , +-16287 , +-15303 , +-8873 , +11687 , +-7507 , +2071 , +-23129 , +-27301 , +-29515 , +-7763 , +8739 , +-13583 , +31097 , +-7451 , +20485 , +27465 , +-25235 , +461 , +12751 , +-19481 , +9035 , +-16063 , +19825 , +-4623 , +8573 , +-29649 , +-24869 , +-2131 , +-24611 , +-17585 , +-10479 , +-23441 , +1571 , +15699 , +16333 , +11031 , +-30031 , +22949 , +7057 , +23303 , +-17943 , +-31331 , +-9669 , +-12389 , +-20975 , +-15301 , +-1499 , +-9695 , +3997 , +-30629 , +-4679 , +23127 , +30223 , +-28301 , +-8821 , +15703 , +16723 , +-17725 , +-24853 , +-9451 , +-31863 , +13591 , +-18681 , +-5537 , +4973 , +8947 , +-15751 , +17221 , +24353 , +3927 , +6501 , +10271 , +6031 , +14063 , +2067 , +19711 , +19519 , +7119 , +29693 , +21925 , +4009 , +23463 , +17777 , +511 , +15383 , +16513 , +28071 , +-16095 , +28915 , +1007 , +-7849 , +-7503 , +-8025 , +15571 , +24525 , +7921 , +1771 , +28551 , +24201 , +-21213 , +-8275 , +14491 , +-3753 , +-24425 , +-18857 , +2579 , +1757 , +-15347 , +9653 , +-3311 , +-11845 , +-21567 , +24647 , +27167 , +-18905 , +13775 , +22803 , +-28201 , +-27657 , +12609 , +-6897 , +-4059 , +-15029 , +25457 , +27875 , +4087 , +-22127 , +-23533 , +18257 , +1407 , +5423 , +18337 , +21509 , +19683 , +32147 , +-28581 , +-4367 , +-1163 , +14791 , +23993 , +-11227 , +-17549 , +-20591 , +-11675 , +3105 , +-30155 , +-15095 , +10423 , +30901 , +-20245 , +28331 , +28069 , +6741 , +-4141 , +-19977 , +23109 , +-23057 , +21491 , +-2941 , +951 , +-31925 , +-20659 , +-4199 , +-26193 , +-13351 , +11165 , +8265 , +-5283 , +25101 , +-4215 , +3073 , +-5391 , +-18117 , +20067 , +12719 , +-6267 , +26089 , +31319 , +-183 , +-19033 , +3753 , +12583 , +-23567 , +32321 , +-10893 , +23401 , +5773 , +27675 , +-11907 , +5683 , +10455 , +-4147 , +-20083 , +8031 , +-263 , +-11715 , +7897 , +7225 , +-15445 , +-12915 , +-1957 , +-19779 , +-3905 , +-7005 , +-341 , +-4783 , +1091 , +12557 , +2127 , +-7947 , +-1515 , +24461 , +22177 , +3583 , +25083 , +-27903 , +8989 , +29527 , +27197 , +-6683 , +-711 , +-13269 , +-18759 , +16965 , +4293 , +-4059 , +23679 , +-14279 , +-4937 , +-12761 , +-9753 , +31451 , +-7539 , +-1661 , +25389 , +27585 , +-27103 , +16815 , +23421 , +7409 , +-10749 , +19583 , +21149 , +20829 , +21581 , +-21791 , +24311 , +985 , +22529 , +24591 , +11317 , +-17261 , +-297 , +21321 , +-27047 , +-753 , +10145 , +-23535 , +10585 , +-1387 , +-25313 , +22745 , +23855 , +24375 , +-26289 , +24649 , +-6533 , +18747 , +14673 , +23787 , +-3183 , +16669 , +-1609 , +13159 , +-20971 , +24067 , +-11425 , +-11457 , +-9961 , +20661 , +4303 , +12799 , +-7259 , +-29419 , +29701 , +-3841 , +18409 , +18969 , +-15147 , +-23151 , +-29001 , +-28607 , +24515 , +15293 , +-12365 , +3727 , +-8877 , +27519 , +1499 , +-4609 , +27111 , +-18315 , +4265 , +23427 , +-6633 , +-3045 , +-18007 , +113 , +26499 , +-17787 , +-26999 , +8581 , +12853 , +-7785 , +8129 , +-25511 , +-15759 , +21179 , +-11369 , +31573 , +-241 , +18197 , +-16947 , +22573 , +11349 , +24133 , +15265 , +17621 , +-18613 , +-30825 , +21629 , +29441 , +29079 , +13757 , +32507 , +21009 , +21973 , +-10997 , +10889 , +23445 , +27757 , +-985 , +-6785 , +17981 , +-5913 , +20297 , +30645 , +-10413 , +6095 , +-29203 , +-13929 , +2739 , +13567 , +-15603 , +-4155 , +-14007 , +-15743 , +4061 , +13099 , +-6663 , +30691 , +2301 , +28047 , +-26323 , +25103 , +7733 , +-27983 , +12987 , +19363 , +1193 , +-16921 , +14947 , +1481 , +-25707 , +-25559 , +-18741 , +-22125 , +17283 , +-30031 , +-11537 , +27085 , +8197 , +16915 , +-26077 , +3413 , +15339 , +26069 , +643 , +-22021 , +2041 , +-12161 , +-533 , +-18481 , +11303 , +-3007 , +-13963 , +5375 , +9035 , +10241 , +13165 , +4653 , +-26269 , +14579 , +4039 , +8011 , +1083 , +6325 , +-27875 , +12523 , +28341 , +-25 , +-13281 , +30235 , +-4491 , +-8897 , +-3179 , +30401 , +-17379 , +26919 , +-13619 , +12913 , +26121 , +-18993 , +-16229 , +22459 , +5503 , +-27705 , +5321 , +11287 , +24177 , +-23785 , +-19943 , +15399 , +-28247 , +26843 , +-2381 , +27809 , +2445 , +16725 , +8997 , +-31845 , +26961 , +-31099 , +-22573 , +-15767 , +18091 , +-15541 , +2297 , +-22539 , +13845 , +19185 , +-28393 , +29585 , +-20103 , +3401 , +-30217 , +-32677 , +-11911 , +-181 , +13337 , +4359 , +20755 , +-4061 , +13487 , +-23489 , +-11283 , +8911 , +-19945 , +27003 , +-6405 , +-31689 , +-10541 , +-4523 , +-19515 , +-10817 , +-3333 , +-25497 , +-8681 , +-23449 , +-3011 , +8093 , +-31681 , +25695 , +27729 , +19727 , +-9795 , +-30433 , +-8717 , +-23971 , +21635 , +-3581 , +-30635 , +-2689 , +-7003 , +-31911 , +26911 , +27941 , +11933 , +17411 , +-21277 , +22919 , +16369 , +-10357 , +17941 , +1481 , +-18815 , +-21313 , +-7547 , +6597 , +-11733 , +-18241 , +-2221 , +-23445 , +26895 , +5793 , +7019 , +26265 , +13893 , +25473 , +26747 , +30321 , +31501 , +12059 , +6763 , +-11473 , +27287 , +22755 , +9559 , +391 , +22569 , +-20061 , +-1529 , +18553 , +8163 , +-18043 , +12511 , +-22871 , +-15881 , +-11591 , +21349 , +6195 , +-22443 , +-16247 , +31787 , +17679 , +-28939 , +-13591 , +1363 , +12255 , +-31107 , +24221 , +-639 , +-697 , +2441 , +-32317 , +-25779 , +27591 , +-25515 , +-2827 , +26443 , +5145 , +-4351 , +22751 , +21617 , +2559 , +-1471 , +12369 , +32541 , +-2655 , +3731 , +5853 , +-13689 , +15713 , +19975 , +1009 , +5301 , +22587 , +-30627 , +-3481 , +14589 , +-8047 , +-3623 , +-15195 , +-26381 , +32655 , +-21403 , +-17107 , +25579 , +18681 , +-25773 , +25535 , +21735 , +-24695 , +31127 , +12009 , +7955 , +14793 , +-21897 , +-13793 , +16577 , +24419 , +-17205 , +20569 , +29917 , +-2303 , +6317 , +21289 , +31455 , +31899 , +-12357 , +1609 , +27989 , +30815 , +1991 , +26567 , +24261 , +-29191 , +-2031 , +-17271 , +30005 , +-17295 , +-3839 , +14705 , +15389 , +-6521 , +26201 , +12527 , +25821 , +15239 , +29689 , +-25311 , +-21061 , +-26463 , +-10999 , +24159 , +10069 , +31423 , +-14917 , +1631 , +-28515 , +-26397 , +-14465 , +-30783 , +333 , +-16647 , +-16455 , +-24011 , +-25885 , +309 , +26879 , +25349 , +30747 , +-8223 , +-28981 , +-28103 , +-27939 , +29635 , +3001 , +25635 , +-10049 , +15083 , +565 , +18311 , +9723 , +-25079 , +18369 , +10271 , +24291 , +-14771 , +31391 , +-573 , +24539 , +-9279 , +-17899 , +-3 , +-1067 , +17423 , +31005 , +22045 , +-16063 , +-1549 , +25501 , +-25645 , +-17013 , +-27397 , +-12763 , +4679 , +-2283 , +6639 , +-22491 , +-10827 , +-10839 , +11169 , +26781 , +-4225 , +12657 , +-19383 , +-4767 , +-25401 , +16499 , +-24739 , +-15157 , +-24183 , +6795 , +-17437 , +-9743 , +47 , +3035 , +24403 , +-1181 , +-4687 , +28107 , +-7965 , +13403 , +23073 , +15993 , +-31381 , +28799 , +-6707 , +11961 , +-3145 , +25101 , +-25901 , +24201 , +-13989 , +8863 , +17211 , +-32758 , +26645 , +-31143 , +-19577 , +-26377 , +-27749 , +-26195 , +-7715 , +6813 , +-2051 , +16771 , +8583 , +-30637 , +12401 , +30203 , +23327 , +25713 , +26293 , +4011 , +-26335 , +-25647 , +8933 , +-24763 , +-16133 , +10165 , +25549 , +18401 , +-12113 , +7763 , +-26679 , +5035 , +30953 , +-5701 , +-29157 , +-17637 , +27539 , +-8865 , +-1861 , +22197 , +14063 , +-7679 , +-26947 , +-3273 , +1331 , +28713 , +-24805 , +-32681 , +6299 , +-28377 , +-31719 , +4603 , +23553 , +7813 , +-22763 , +-5141 , +-8193 , +-2053 , +5345 , +20499 , +-25481 , +26611 , +-7523 , +-30927 , +20155 , +28273 , +17163 , +7189 , +-13291 , +10907 , +-5013 , +-16043 , +-24335 , +6821 , +-6445 , +-9855 , +21603 , +27215 , +23299 , +6629 , +10319 , +2009 , +31169 , +16315 , +-21005 , +-18557 , +5039 , +20447 , +1803 , +-8837 , +-1627 , +22801 , +11101 , +13915 , +-17021 , +12451 , +2783 , +13853 , +-5229 , +8633 , +-7101 , +17819 , +21593 , +1785 , +-22511 , +-27013 , +32495 , +-14641 , +-16309 , +-14923 , +-9259 , +-21993 , +5231 , +1147 , +-12199 , +-31397 , +-24025 , +-65 , +12897 , +11411 , +-32179 , +15909 , +19653 , +10571 , +-19823 , +11385 , +1071 , +11119 , +31623 , +-28497 , +13415 , +11379 , +-13497 , +-25779 , +-8647 , +-17129 , +23683 , +20339 , +15809 , +30099 , +533 , +31049 , +24901 , +89 , +-4309 , +-5383 , +22677 , +-18611 , +21451 , +14373 , +-27429 , +19315 , +9719 , +-22553 , +-28427 , +28467 , +28481 , +-27327 , +23117 , +-1275 , +-2335 , +-2539 , +4661 , +-31561 , +-24489 , +16547 , +-71 , +-7911 , +22129 , +26493 , +18937 , +-30661 , +-9481 , +9215 , +-3329 , +21537 , +21169 , +18243 , +11041 , +-28161 , +-6639 , +18855 , +-27443 , +-8715 , +20023 , +-12107 , +-28447 , +-16073 , +-22883 , +25503 , +11153 , +-29993 , +23329 , +1601 , +-15953 , +23285 , +-30049 , +-3441 , +-2423 , +-10125 , +-18929 , +10377 , +4679 , +-30409 , +5147 , +3267 , +24759 , +17625 , +24883 , +-12979 , +-22351 , +-17949 , +-31705 , +-15051 , +21479 , +32131 , +-8385 , +-27013 , +24381 , +-25145 , +-23081 , +12933 , +-21591 , +11859 , +3697 , +-30427 , +-14463 , +-14439 , +-18097 , +5627 , +-14247 , +28819 , +9101 , +1159 , +19803 , +-5385 , +32439 , +8839 , +16923 , +-9739 , +-15135 , +22789 , +31219 , +-17561 , +24895 , +-7233 , +-17447 , +11153 , +17727 , +-213 , +22199 , +27477 , +-15841 , +17635 , +-10685 , +-24343 , +-251 , +28331 , +-4003 , +-13545 , +25497 , +-18467 , +17113 , +-8471 , +-12517 , +-27291 , +-1563 , +2029 , +-3081 , +-965 , +-2341 , +-32029 , +-20503 , +-4519 , +-28779 , +2811 , +-18297 , +-31179 , +32339 , +20877 , +29797 , +14515 , +6653 , +30799 , +22691 , +-31319 , +28435 , +1547 , +-23795 , +-12599 , +20723 , +19933 , +-14163 , +-29405 , +-1095 , +-16153 , +28901 , +-25323 , +24213 , +8839 , +21771 , +-10033 , +-22873 , +5907 , +-9093 , +-18117 , +8779 , +1295 , +-13007 , +13701 , +5381 , +-16153 , +-5917 , +-26361 , +-27709 , +-1243 , +-12651 , +-30777 , +455 , +-5849 , +-1863 , +-5779 , +17909 , +8285 , +12217 , +-3397 , +20649 , +7163 , +18721 , +1415 , +2589 , +25909 , +-29913 , +-24783 , +16685 , +-10763 , +-29495 , +3483 , +-19773 , +-4587 , +-5523 , +8865 , +-15969 , +-19695 , +-22809 , +-25069 , +-2377 , +4679 , +-28379 , +-31189 , +-7665 , +15789 , +-31179 , +9861 , +29711 , +-1275 , +-6161 , +-4713 , +26459 , +23957 , +8187 , +-8021 , +-11479 , +-7575 , +-30859 , +-8621 , +32289 , +26363 , +-29949 , +26473 , +2477 , +-3461 , +25449 , +9849 , +-29231 , +-13959 , +15011 , +-4663 , +-17015 , +-15321 , +5503 , +25543 , +11163 , +24335 , +22967 , +5635 , +-14349 , +32325 , +18557 , +10919 , +11643 , +23335 , +17829 , +26735 , +-10131 , +-27503 , +17193 , +-13019 , +-8911 , +-9835 , +10583 , +27283 , +14265 , +9905 , +-27819 , +-15875 , +19277 , +3471 , +-18363 , +22041 , +-21783 , +-205 , +-10023 , +-21621 , +-15845 , +4283 , +2411 , +28631 , +30291 , +12941 , +-20331 , +-293 , +22715 , +21023 , +-28083 , +-313 , +-32619 , +24093 , +-16525 , +19095 , +-23025 , +-23249 , +16887 , +-7411 , +-27241 , +-30935 , +-8861 , +7709 , +-27713 , +-3899 , +-17409 , +-13069 , +-13945 , +-26147 , +24671 , +-28569 , +20799 , +32289 , +-19583 , +5105 , +-1059 , +-30641 , +-30873 , +26401 , +26317 , +-6163 , +26147 , +11679 , +31317 , +2431 , +1411 , +-8807 , +-6041 , +-22211 , +14097 , +-15165 , +-15369 , +-1967 , +-21309 , +3015 , +-14119 , +19593 , +27137 , +28743 , +27667 , +21139 , +14659 , +-4789 , +19641 , +15025 , +-467 , +2623 , +7487 , +-10247 , +15393 , +2157 , +-25251 , +10755 , +-22181 , +-22807 , +-17319 , +18725 , +9861 , +-19173 , +31723 , +11565 , +-3369 , +11175 , +-21623 , +18073 , +29859 , +1005 , +5197 , +25163 , +28281 , +-31229 , +11581 , +-12347 , +-1869 , +17701 , +-4043 , +16861 , +6041 , +-32075 , +-6355 , +25085 , +17907 , +12203 , +2591 , +-29233 , +-13279 , +17557 , +-31403 , +-18561 , +15279 , +-22517 , +75 , +-8079 , +-6279 , +23465 , +31999 , +9843 , +-20427 , +10111 , +26567 , +-9349 , +-617 , +31771 , +-4169 , +-24605 , +15329 , +-15639 , +16229 , +-2285 , +-18949 , +-10945 , +-20907 , +20167 , +9231 , +-11827 , +-32065 , +-3903 , +-14683 , +2195 , +23543 , +-10497 , +26157 , +13659 , +-8903 , +-9611 , +3877 , +-16201 , +-20219 , +13387 , +-7511 , +16237 , +31995 , +-13941 , +-11379 , +-6021 , +-8659 , +14687 , +-22533 , +14723 , +1531 , +9669 , +6013 , +-32305 , +3943 , +-20787 , +23973 , +-29759 , +-23311 , +-26549 , +6425 , +7377 , +3823 , +4625 , +-12495 , +-31749 , +16993 , +-25939 , +-5109 , +-4411 , +2125 , +-2921 , +-26835 , +-17241 , +-10857 , +-23061 , +13451 , +-30443 , +27473 , +-1369 , +-5581 , +9189 , +-10333 , +353 , +597 , +12373 , +-4335 , +31353 , +-32285 , +-23941 , +-10653 , +12761 , +-13397 , +-11455 , +-19219 , +-17621 , +-22551 , +25307 , +10103 , +2185 , +-30625 , +-24129 , +-29815 , +-11327 , +24817 , +-18403 , +-17589 , +20999 , +-4927 , +17367 , +20949 , +10795 , +-18505 , +-23299 , +4113 , +9559 , +-15185 , +-20289 , +31239 , +-28097 , +10235 , +745 , +17603 , +-11553 , +28301 , +-23085 , +-21343 , +3255 , +10629 , +18667 , +19495 , +29559 , +30283 , +-17001 , +-29851 , +9789 , +-9433 , +-3395 , +16325 , +5971 , +20571 , +9909 , +-27547 , +-2467 , +-12871 , +-30785 , +-11535 , +-27369 , +13499 , +-1279 , +9463 , +-16755 , +-4323 , +16889 , +-6715 , +-1843 , +6639 , +13943 , +-25413 , +10537 , +-27335 , +21785 , +14373 , +-27929 , +-12283 , +20029 , +-24427 , +10361 , +-22273 , +-10887 , +15545 , +-22723 , +15247 , +26523 , +32181 , +30123 , +-3735 , +16151 , +3063 , +-17389 , +-20309 , +12039 , +-21357 , +-20525 , +32375 , +-25443 , +30487 , +-30447 , +28159 , +20253 , +29675 , +6895 , +13361 , +20055 , +15133 , +-31159 , +14263 , +-30817 , +-21561 , +-281 , +30119 , +28993 , +21461 , +6965 , +4745 , +25723 , +-24461 , +-22907 , +-4107 , +-6665 , +28369 , +28089 , +7855 , +-27453 , +5511 , +-383 , +-31431 , +-2107 , +32361 , +-12005 , +-27921 , +-7757 , +26849 , +-11141 , +22429 , +-23659 , +27843 , +-10993 , +-10345 , +-14927 , +-10839 , +-18957 , +-2991 , +32517 , +-4407 , +-2899 , +-16007 , +-23739 , +-10419 , +28509 , +-24945 , +16207 , +30509 , +-6791 , +-4875 , +-25563 , +-21371 , +11017 , +-17771 , +-8097 , +18795 , +-31141 , +14573 , +2093 , +-1459 , +12345 , +22703 , +27587 , +-21307 , +28327 , +25041 , +-29601 , +-28945 , +16913 , +-8149 , +24499 , +16197 , +7443 , +-17263 , +-11799 , +17655 , +-24927 , +-9627 , +-18929 , +26815 , +-14651 , +4527 , +-8931 , +1597 , +-25125 , +-8773 , +-29857 , +-4659 , +-14781 , +-26581 , +1143 , +-4383 , +-3939 , +-26473 , +26065 , +-23853 , +-21887 , +4245 , +-30821 , +-28601 , +32689 , +-921 , +7231 , +16121 , +-6695 , +1 , +-14763 , +21535 , +-5439 , +-30551 , +23847 , +20277 , +7435 , +2827 , +6041 , +-159 , +-22685 , +-18983 , +-10831 , +18751 , +5697 , +28889 , +16515 , +21833 , +-16361 , +-32637 , +-1873 , +-16739 , +18447 , +-23019 , +-29867 , +-9631 , +13121 , +5173 , +26005 , +-20585 , +2155 , +4087 , +32381 , +-18571 , +-3539 , +-26999 , +-4219 , +-449 , +23483 , +-8389 , +13197 , +-17251 , +-32748 , +4641 , +17479 , +371 , +25541 , +2853 , +20033 , +-31689 , +12563 , +-32349 , +13131 , +14291 , +28349 , +27777 , +-27779 , +-18963 , +2353 , +-1341 , +-27481 , +6859 , +-22979 , +-1883 , +8269 , +27049 , +15191 , +-1737 , +-12261 , +4493 , +24133 , +7279 , +16613 , +-21853 , +18527 , +-13887 , +1041 , +-31723 , +1089 , +14143 , +-6241 , +6749 , +-16891 , +5417 , +-13161 , +3621 , +-20991 , +13831 , +-15359 , +-19557 , +-27151 , +-29885 , +-21915 , +-11705 , +18621 , +20027 , +-1609 , +-21141 , +13485 , +-21021 , +2521 , +-4913 , +26651 , +-10027 , +30611 , +32293 , +2227 , +-17429 , +-5633 , +1751 , +-19165 , +19803 , +-4463 , +-409 , +-13987 , +-17339 , +9091 , +2371 , +-699 , +23769 , +26837 , +-21477 , +22001 , +-22301 , +20413 , +-4163 , +-7843 , +11495 , +-32597 , +3435 , +13473 , +-17989 , +20399 , +-17483 , +9387 , +-19811 , +14213 , +13265 , +-20099 , +-12339 , +29439 , +-30869 , +-25637 , +11683 , +27907 , +24329 , +-25209 , +39 , +16127 , +-18211 , +-17411 , +-15577 , +-2587 , +-16355 , +-21085 , +16083 , +-10845 , +21721 , +-13941 , +14553 , +21271 , +23641 , +31137 , +10735 , +-883 , +29169 , +-22681 , +-12295 , +2223 , +4181 , +6963 , +-2917 , +-15355 , +-13443 , +17883 , +16461 , +-27417 , +-19727 , +27895 , +29181 , +-12807 , +29859 , +-20073 , +-11491 , +1827 , +22609 , +-5769 , +16455 , +13571 , +-21683 , +-15689 , +-25021 , +14063 , +-19227 , +10781 , +5041 , +4961 , +-13521 , +27581 , +-8423 , +-25859 , +-24475 , +1599 , +8575 , +-22019 , +24769 , +-22383 , +30083 , +-16339 , +-18225 , +21021 , +-21769 , +10085 , +23623 , +3461 , +32497 , +24703 , +9575 , +15833 , +-22421 , +3791 , +25803 , +-2477 , +4437 , +6687 , +31169 , +21637 , +-27599 , +16159 , +19233 , +21789 , +5675 , +-14749 , +-18257 , +6933 , +21933 , +-26151 , +-25373 , +8557 , +17787 , +28867 , +30545 , +20325 , +19527 , +18991 , +22389 , +26419 , +16591 , +-4633 , +8209 , +-14531 , +31343 , +-21513 , +-17663 , +-2611 , +-12739 , +4761 , +21913 , +-4277 , +-12129 , +-11597 , +15737 , +-20745 , +13153 , +-30003 , +30179 , +-5597 , +-26539 , +-20343 , +-25193 , +30175 , +-20383 , +20637 , +15659 , +20291 , +-227 , +-8887 , +5601 , +-16873 , +6889 , +-15537 , +-30469 , +-30191 , +-15995 , +-661 , +-20579 , +-17771 , +-26323 , +24141 , +15135 , +-10019 , +-2521 , +-14065 , +-18973 , +11453 , +31977 , +4139 , +15537 , +-5159 , +-1883 , +-19717 , +18571 , +-11431 , +15973 , +12711 , +-24309 , +9253 , +29863 , +12195 , +3895 , +31131 , +-26771 , +7331 , +-5929 , +29383 , +-28451 , +-25575 , +3155 , +-23013 , +-16813 , +25387 , +25861 , +-10325 , +14847 , +-15071 , +-28653 , +-5667 , +-16139 , +-22927 , +-17977 , +-32599 , +-29233 , +3619 , +19311 , +-12471 , +-71 , +3539 , +-32351 , +-30595 , +26135 , +14379 , +-31957 , +26931 , +-14197 , +24021 , +4183 , +21965 , +933 , +-14091 , +25297 , +-32303 , +4577 , +-20703 , +22007 , +-26073 , +-9901 , +4573 , +28597 , +27081 , +21941 , +-14963 , +-7717 , +-3839 , +30465 , +-10515 , +7153 , +26401 , +-29555 , +1809 , +1437 , +7863 , +-27493 , +-27179 , +31081 , +-15283 , +18551 , +4821 , +6183 , +-4205 , +15629 , +27883 , +3271 , +32549 , +-4091 , +-2015 , +-10071 , +-18753 , +6483 , +-24017 , +-16259 , +-26643 , +6487 , +3437 , +-3689 , +27985 , +-9363 , +-13749 , +-2107 , +79 , +1295 , +26449 , +-25681 , +29001 , +-13979 , +-28787 , +-15963 , +10841 , +14685 , +-4205 , +24827 , +-7031 , +26697 , +6381 , +11237 , +14217 , +15601 , +7197 , +-57 , +-21533 , +18227 , +4363 , +-18921 , +-14403 , +29197 , +17923 , +28077 , +3595 , +-5565 , +19757 , +-7015 , +26691 , +4465 , +-24447 , +-1401 , +-3427 , +-10845 , +5189 , +-3187 , +-23863 , +17773 , +-12291 , +-27775 , +-16095 , +-18301 , +1515 , +-22053 , +-21399 , +25813 , +8447 , +9733 , +-8187 , +-18403 , +-24227 , +19511 , +-19287 , +19973 , +24383 , +8909 , +-11363 , +-9551 , +27779 , +-20451 , +-11155 , +-7711 , +19605 , +8407 , +-729 , +-28025 , +-17683 , +28367 , +-25333 , +-24871 , +-18427 , +-24473 , +-1591 , +26865 , +5331 , +14425 , +18235 , +23519 , +13501 , +-4591 , +-24173 , +-14009 , +15893 , +18059 , +-32227 , +9073 , +28943 , +9639 , +-22921 , +-5143 , +-8901 , +-4095 , +-7617 , +11921 , +11641 , +21835 , +-11435 , +-7871 , +-15755 , +23327 , +-3953 , +-47 , +-11365 , +-16287 , +-5389 , +-17217 , +-12647 , +20751 , +-9879 , +-25023 , +-21179 , +17051 , +9981 , +-8229 , +31271 , +12483 , +-17523 , +-3969 , +-17561 , +-11539 , +22281 , +25881 , +-953 , +503 , +-26841 , +14257 , +11551 , +9877 , +-24681 , +-21761 , +4555 , +-22485 , +-9017 , +-21885 , +30383 , +29725 , +-9973 , +-227 , +25641 , +13741 , +-25497 , +12329 , +2181 , +22099 , +-29005 , +26895 , +-28545 , +24207 , +21607 , +15201 , +-22989 , +-12469 , +-25147 , +-27277 , +-12647 , +2987 , +24725 , +-14993 , +23927 , +27495 , +29791 , +-7951 , +14305 , +3491 , +2337 , +26911 , +7473 , +-31669 , +-3963 , +-31939 , +-20875 , +-4125 , +12707 , +-25143 , +-5009 , +-23575 , +-8409 , +-9713 , +25617 , +-5217 , +-22499 , +4677 , +-16027 , +1907 , +6937 , +-11227 , +283 , +-1329 , +5115 , +10235 , +-1937 , +17005 , +19483 , +31819 , +27561 , +2871 , +-31475 , +-29223 , +27409 , +411 , +17873 , +-23473 , +11885 , +20835 , +-23923 , +-1201 , +9971 , +-4595 , +1735 , +-20469 , +32713 , +-17501 , +31261 , +2909 , +-15123 , +-20457 , +22391 , +-32671 , +-5949 , +-31469 , +-4409 , +14217 , +24571 , +4699 , +2363 , +32311 , +-29683 , +-5993 , +-14341 , +-3365 , +11325 , +17597 , +-10917 , +-14975 , +3327 , +-3111 , +24725 , +-6931 , +-20991 , +16239 , +-9211 , +28725 , +5783 , +31307 , +-2601 , +17625 , +-28485 , +17893 , +-15539 , +341 , +-32129 , +10281 , +-27031 , +21571 , +7687 , +-30243 , +30257 , +-4117 , +8195 , +-19083 , +-20131 , +-1445 , +21671 , +-4511 , +-31849 , +20997 , +6943 , +14585 , +17709 , +32465 , +-24695 , +-5441 , +7503 , +-22595 , +879 , +-25785 , +-20803 , +25831 , +11455 , +-29301 , +-18677 , +-14797 , +29501 , +10685 , +6227 , +26207 , +-7035 , +-24665 , +17771 , +-7533 , +22137 , +18813 , +-30559 , +-29051 , +63 , +-6343 , +7411 , +-17143 , +-11847 , +19055 , +-28219 , +29999 , +16761 , +-30035 , +28949 , +-5167 , +-14017 , +23113 , +-24517 , +-26183 , +-14105 , +-27715 , +29473 , +17963 , +2031 , +-26749 , +-5645 , +-8697 , +-29339 , +-28057 , +4441 , +28511 , +1629 , +17505 , +-711 , +8585 , +29429 , +24561 , +21985 , +-32321 , +20927 , +6639 , +-4151 , +-975 , +451 , +489 , +26055 , +-9821 , +-27915 , +-17667 , +11719 , +-26243 , +-17115 , +-21207 , +8193 , +107 , +13701 , +18217 , +-5959 , +-19599 , +6805 , +-5939 , +23661 , +-18559 , +-20831 , +3537 , +9875 , +-21095 , +6327 , +-11973 , +-13617 , +9045 , +25633 , +24869 , +28845 , +-12277 , +30295 , +31525 , +29143 , +5729 , +13187 , +-30443 , +8907 , +-23963 , +-30359 , +30335 , +-12775 , +31781 , +-26385 , +-10659 , +23061 , +26313 , +-18935 , +29063 , +-28397 , +-7127 , +30261 , +-10881 , +-31713 , +-19227 , +-31367 , +-1081 , +45 , +11517 , +31183 , +-24123 , +-29217 , +13549 , +23845 , +26893 , +-3149 , +20285 , +9689 , +22595 , +-19781 , +31391 , +-10845 , +-11153 , +30169 , +18567 , +30493 , +-21805 , +-5255 , +63 , +-20051 , +17225 , +449 , +9861 , +11273 , +-27881 , +-691 , +16795 , +29991 , +-6073 , +25197 , +12775 , +-21577 , +9597 , +10449 , +-2299 , +-25571 , +-31149 , +12747 , +14693 , +-29465 , +-31693 , +30981 , +28765 , +29123 , +-3159 , +-2125 , +-829 , +-17155 , +-3527 , +-19885 , +4101 , +-30861 , +-17215 , +-5919 , +-18489 , +18189 , +1613 , +-7793 , +-6675 , +-13389 , +-6297 , +17915 , +-12991 , +-17715 , +-515 , +-29967 , +27269 , +16687 , +-10839 , +23185 , +-28149 , +13211 , +12441 , +31001 , +22991 , +21943 , +18653 , +7189 , +14343 , +-127 , +-24001 , +11285 , +-20917 , +-9909 , +-31585 , +26855 , +-9955 , +-6609 , +-18737 , +-6061 , +-17399 , +-27379 , +-28197 , +-6323 , +-24003 , +4093 , +1269 , +26031 , +27549 , +-32183 , +-24131 , +-31629 , +7775 , +-29465 , +18723 , +7785 , +-27357 , +-24207 , +-28485 , +-27793 , +-24187 , +31641 , +30867 , +15915 , +31551 , +28965 , +-30315 , +-29631 , +-11335 , +-12189 , +-2997 , +12553 , +26145 , +1317 , +-14255 , +27341 , +23561 , +-17351 , +-9197 , +-11653 , +24187 , +-17059 , +32061 , +-21023 , +-21617 , +-19523 , +-32385 , +15459 , +2185 , +-25373 , +-12301 , +-2509 , +-6035 , +5685 , +-1303 , +13835 , +-24813 , +16623 , +591 , +17761 , +-1847 , +29845 , +-10635 , +17187 , +3683 , +30697 , +-19593 , +-8977 , +-21033 , +30831 , +-4853 , +21191 , +12111 , +30811 , +17117 , +-17075 , +3789 , +27401 , +21857 , +3703 , +8757 , +-18441 , +21301 , +-15153 , +-15379 , +23621 , +30447 , +-14049 , +-13835 , +25245 , +28031 , +28339 , +-24193 , +-5707 , +15611 , +3599 , +26369 , +29003 , +-15359 , +12833 , +21205 , +-23149 , +27021 , +-12287 , +21067 , +24883 , +5451 , +-32475 , +9543 , +7611 , +2167 , +14359 , +-10159 , +-30045 , +-20687 , +26547 , +-3275 , +-32073 , +599 , +5339 , +13335 , +6171 , +-28203 , +-13653 , +12043 , +-4425 , +-12403 , +-5827 , +-21973 , +-25283 , +-19811 , +18131 , +3637 , +19601 , +19269 , +-25703 , +-15457 , +19923 , +24375 , +-20519 , +-11217 , +-8505 , +-22927 , +-15183 , +-22253 , +-11051 , +-16231 , +12113 , +15737 , +26239 , +31437 , +-24915 , +-25175 , +-13477 , +32259 , +953 , +2715 , +-5495 , +-549 , +-27617 , +-26097 , +-12375 , +32764 , +-8329 , +-21721 , +7773 , +21477 , +28417 , +1913 , +15407 , +-11441 , +-6183 , +2227 , +26905 , +767 , +10165 , +-25945 , +32379 , +-21479 , +21525 , +29155 , +-29559 , +-31229 , +21509 , +20185 , +3661 , +-30539 , +-21431 , +-23201 , +-5095 , +-107 , +13859 , +-32545 , +1157 , +29899 , +-22405 , +-807 , +29667 , +3357 , +27559 , +10763 , +21043 , +27719 , +-20585 , +-18427 , +8101 , +-17967 , +15509 , +15165 , +-26745 , +-8603 , +-2443 , +26537 , +8647 , +-28247 , +-30123 , +6103 , +-25889 , +20637 , +16079 , +30859 , +-21927 , +-11157 , +24249 , +12489 , +24511 , +8637 , +13903 , +-8581 , +19987 , +-14179 , +6907 , +-16507 , +-8751 , +27853 , +30081 , +-8363 , +3415 , +11927 , +18111 , +-24313 , +22505 , +3113 , +7899 , +-521 , +-1239 , +-11407 , +-245 , +20695 , +21253 , +-17299 , +7611 , +1353 , +-31687 , +17421 , +1361 , +1023 , +11589 , +24449 , +1381 , +13119 , +21985 , +-24553 , +28271 , +-7149 , +21753 , +24465 , +-28663 , +-31791 , +-6881 , +-29439 , +-3677 , +27189 , +8081 , +12825 , +-16965 , +7165 , +-27235 , +18695 , +-10345 , +-9725 , +16555 , +-1325 , +-27783 , +-11057 , +-32599 , +-8661 , +-30371 , +-9041 , +-7927 , +20167 , +31275 , +-6571 , +-9157 , +30007 , +-16527 , +15339 , +21913 , +5957 , +15773 , +-19799 , +497 , +-14145 , +20657 , +-17163 , +30317 , +-27423 , +-21629 , +-20243 , +5653 , +-18401 , +-24215 , +7057 , +-27197 , +-32131 , +-11651 , +30793 , +20119 , +-1419 , +-19893 , +9483 , +5883 , +22591 , +-7919 , +-5397 , +-9713 , +-3663 , +-12431 , +-3271 , +-23131 , +-20843 , +-23379 , +-32495 , +26299 , +-25213 , +-8357 , +18295 , +3185 , +-16075 , +-22365 , +-19465 , +18819 , +-20891 , +20979 , +1451 , +-21443 , +4639 , +-2761 , +-30489 , +17655 , +-18275 , +-20595 , +-12479 , +-27893 , +11417 , +28297 , +15411 , +-4017 , +-30927 , +-14367 , +-16849 , +13065 , +-30669 , +-11351 , +3123 , +-16789 , +-28935 , +-32497 , +16367 , +-18039 , +-29757 , +23949 , +9289 , +-23341 , +-32371 , +18085 , +4231 , +1543 , +-20377 , +-493 , +-22565 , +25269 , +79 , +6289 , +21891 , +16681 , +-15225 , +16129 , +-8867 , +26603 , +28523 , +14893 , +-9989 , +5047 , +20175 , +-16125 , +31045 , +23539 , +-5933 , +-32449 , +25735 , +32167 , +4411 , +23215 , +2325 , +17653 , +20291 , +17643 , +15441 , +19733 , +-21499 , +-10363 , +32341 , +20163 , +-32451 , +-4921 , +-17919 , +13635 , +24757 , +22249 , +-9833 , +12753 , +-21491 , +8139 , +1999 , +-31329 , +-2789 , +19241 , +-2701 , +14915 , +-16701 , +-27817 , +-1163 , +-32581 , +-18867 , +6267 , +29065 , +-4387 , +-709 , +31289 , +4409 , +21331 , +-25687 , +21499 , +-17021 , +22545 , +-19687 , +-27745 , +-30999 , +-21685 , +-30251 , +-23887 , +17425 , +-6411 , +1733 , +-9691 , +-26919 , +-4433 , +-19005 , +14475 , +-18963 , +-949 , +-5003 , +-11573 , +-11547 , +4787 , +10153 , +-2211 , +29911 , +3959 , +14627 , +31741 , +-24719 , +4787 , +24067 , +11751 , +7831 , +30093 , +-10865 , +-9077 , +-12691 , +1841 , +4249 , +-2357 , +14333 , +-14269 , +4423 , +12975 , +23115 , +-8997 , +4987 , +14235 , +-2075 , +-4871 , +5533 , +-15605 , +16647 , +-21629 , +23039 , +16329 , +12845 , +-17481 , +30891 , +18345 , +32553 , +-21211 , +6595 , +1973 , +25279 , +17963 , +-4013 , +-263 , +10939 , +-11035 , +3501 , +4005 , +-10101 , +-16723 , +9537 , +23255 , +-20909 , +1551 , +-10001 , +-8505 , +139 , +-193 , +-23063 , +20357 , +9229 , +-5353 , +-30209 , +8751 , +-12099 , +-20343 , +-1661 , +17065 , +-12145 , +27801 , +15769 , +27611 , +21293 , +4311 , +-11501 , +-26023 , +-16891 , +-14249 , +-7739 , +-28239 , +20713 , +23331 , +25699 , +-5107 , +30499 , +18493 , +6355 , +-21377 , +7437 , +-12785 , +-12025 , +-13399 , +-7641 , +-26271 , +15449 , +-18693 , +32695 , +21215 , +-16037 , +14961 , +15317 , +-15619 , +-32715 , +-13117 , +-16113 , +-15229 , +5501 , +-18915 , +12921 , +-17035 , +13711 , +2397 , +-11191 , +-10603 , +-18339 , +-6205 , +8427 , +-22187 , +11733 , +1845 , +-23909 , +-25515 , +-27989 , +-3353 , +27011 , +-22959 , +15805 , +-351 , +30281 , +-20569 , +-25117 , +25713 , +-3799 , +19013 , +-8121 , +-31519 , +-31337 , +-2017 , +5957 , +-15949 , +-17847 , +-18381 , +-1605 , +-5351 , +-25127 , +4595 , +-11553 , +-18585 , +-24615 , +22343 , +-17757 , +15703 , +-4503 , +21761 , +-20861 , +-5969 , +12371 , +10711 , +-23845 , +-7793 , +-3165 , +31701 , +9419 , +24087 , +-22339 , +-15267 , +-23425 , +-10589 , +-32267 , +-5477 , +25 , +-27509 , +4005 , +-7043 , +26359 , +-27819 , +-3893 , +-27093 , +11673 , +11371 , +28703 , +-22525 , +-22031 , +-31403 , +26017 , +-29945 , +-20417 , +14451 , +13509 , +25569 , +-14235 , +12343 , +16121 , +5205 , +-19517 , +11475 , +-23871 , +6967 , +23439 , +-4999 , +-24745 , +-32027 , +-16471 , +28183 , +29883 , +-27067 , +-521 , +18051 , +6223 , +-27601 , +2621 , +-32709 , +-27157 , +6519 , +11885 , +-609 , +30073 , +31059 , +-5233 , +-10845 , +-757 , +-17309 , +21255 , +-23801 , +-22667 , +32281 , +28795 , +15893 , +-22685 , +24771 , +-9181 , +-10027 , +-12561 , +20465 , +3493 , +-2619 , +-19523 , +18809 , +-30871 , +12561 , +26515 , +-6929 , +29303 , +21579 , +-25233 , +20885 , +-15673 , +-21337 , +-27875 , +729 , +31779 , +7083 , +-26795 , +-15543 , +12149 , +-9617 , +-31667 , +26129 , +18595 , +26447 , +1747 , +-12561 , +17647 , +-27099 , +2539 , +-30549 , +27069 , +15109 , +7897 , +-24051 , +5117 , +26479 , +14793 , +2395 , +14329 , +-19957 , +-25895 , +7757 , +10671 , +-32549 , +15293 , +-19835 , +17835 , +-12801 , +-26159 , +12421 , +-28069 , +24287 , +13485 , +8493 , +-3603 , +-6675 , +-26299 , +-14419 , +-865 , +1753 , +20861 , +3077 , +7073 , +-19127 , +-28607 , +27629 , +-925 , +-6641 , +-3553 , +10851 , +-2957 , +2791 , +10843 , +30095 , +28117 , +20653 , +-2933 , +-17591 , +-3113 , +6157 , +8879 , +-7161 , +-1939 , +-24375 , +8133 , +-21413 , +-5627 , +24421 , +-16669 , +-11025 , +-19993 , +-2717 , +-20781 , +24813 , +13057 , +17405 , +27171 , +-25845 , +-7861 , +-28321 , +-1083 , +6389 , +2455 , +14419 , +28707 , +30027 , +-7703 , +-9589 , +19127 , +-2029 , +-1449 , +-29369 , +-10207 , +-6723 , +9815 , +-1893 , +-19257 , +-21361 , +30367 , +-7903 , +24547 , +-22367 , +23413 , +5169 , +13087 , +-18857 , +-30833 , +11927 , +-26959 , +19287 , +-21657 , +13775 , +-13841 , +19973 , +-24303 , +31677 , +6243 , +25455 , +8349 , +-15131 , +-11409 , +-5161 , +-27427 , +10523 , +-6057 , +26009 , +10445 , +-22841 , +27363 , +28341 , +-23193 , +-8043 , +-5009 , +7349 , +14327 , +-589 , +-2161 , +-7377 , +-18185 , +9345 , +-30693 , +-16191 , +-29853 , +-30767 , +-10295 , +-5505 , +-21355 , +32407 , +22347 , +-21011 , +3229 , +-25045 , +11237 , +-15999 , +-14571 , +20217 , +2431 , +-17523 , +21629 , +-11335 , +-16057 , +-6209 , +19473 , +15151 , +23741 , +13081 , +-12767 , +13403 , +7509 , +26215 , +12011 , +15663 , +14479 , +26425 , +-1551 , +9169 , +-22397 , +-18603 , +-6703 , +21071 , +-5879 , +-5451 , +-12133 , +-9009 , +-1721 , +19459 , +23729 , +-13743 , +31179 , +26501 , +17943 , +-28699 , +16163 , +-19299 , +2121 , +13921 , +12537 , +5569 , +-4959 , +8853 , +-12895 , +26351 , +6429 , +-2033 , +10813 , +-11603 , +-18495 , +-29115 , +-14513 , +9589 , +-12685 , +28757 , +4559 , +-10313 , +-8375 , +-8385 , +-5945 , +1613 , +-5789 , +-12651 , +-149 , +4467 , +-7605 , +-11333 , +29611 , +6717 , +16323 , +32665 , +29011 , +5785 , +-21977 , +6871 , +14753 , +-19529 , +28473 , +15505 , +26455 , +-16625 , +-12923 , +13207 , +-14499 , +19923 , +-20433 , +-17895 , +-25141 , +23267 , +-3245 , +-5141 , +-20587 , +4943 , +-14121 , +-2253 , +-6003 , +-30395 , +21961 , +32679 , +-2549 , +1427 , +8237 , +11335 , +-20995 , +-20589 , +25955 , +22411 , +-25977 , +-15441 , +-3853 , +23079 , +-32243 , +4177 , +-29719 , +26683 , +17371 , +-3749 , +-25421 , +30989 , +-7889 , +-32217 , +3949 , +12613 , +2783 , +15863 , +7873 , +18331 , +2913 , +-14609 , +5441 , +23581 , +25971 , +2955 , +-24777 , +-17957 , +-217 , +-32097 , +-15099 , +-1243 , +12673 , +-19003 , +9719 , +2111 , +-27507 , +-11683 , +-29791 , +26783 , +-8199 , +30975 , +28079 , +24223 , +-18389 , +-31881 , +32323 , +-14917 , +-16427 , +-1735 , +-10547 , +11071 , +-14823 , +-5539 , +-8861 , +6541 , +26901 , +26903 , +31377 , +3527 , +1279 , +22957 , +-18499 , +4115 , +18369 , +20717 , +24057 , +26185 , +16649 , +14633 , +-21157 , +22837 , +18155 , +-2641 , +-15149 , +-31679 , +-30995 , +-17217 , +-11639 , +-22595 , +-25687 , +24577 , +-23377 , +30093 , +-283 , +15233 , +-19745 , +20579 , +-20449 , +807 , +14315 , +30073 , +-6217 , +9899 , +29755 , +-30521 , +11893 , +1043 , +-20313 , +-1097 , +-20047 , +-24413 , +6597 , +18025 , +11227 , +8283 , +3023 , +27489 , +14757 , +-19471 , +-6421 , +-16963 , +29579 , +13633 , +1045 , +25077 , +9203 , +10827 , +-7579 , +-32493 , +-3643 , +26283 , +9461 , +-22941 , +22397 , +909 , +31023 , +16301 , +16079 , +-6615 , +-591 , +-18441 , +-26445 , +-29511 , +16787 , +9391 , +18943 , +23027 , +29779 , +-657 , +17541 , +5885 , +-8675 , +-10711 , +9385 , +-7193 , +14511 , +-27671 , +11125 , +20139 , +165 , +5133 , +-4815 , +-14191 , +22367 , +-16911 , +-29565 , +12863 , +-29365 , +-2247 , +-9729 , +-18915 , +-4923 , +-3463 , +12351 , +-22179 , +-8845 , +-12169 , +25731 , +-21659 , +-2033 , +-29733 , +-23619 , +-17455 , +8909 , +-22671 , +-27595 , +32487 , +20013 , +5847 , +-27751 , +26767 , +-5551 , +22973 , +27031 , +1483 , +-21287 , +16791 , +18169 , +7347 , +-16581 , +23003 , +26931 , +-9501 , +-4713 , +27311 , +14983 , +-13697 , +-4587 , +3629 , +18071 , +-14941 , +22707 , +-12265 , +-9349 , +-24481 , +26539 , +-12283 , +-20643 , +-16083 , +6207 , +24111 , +25233 , +24553 , +-15339 , +-30057 , +13863 , +-23735 , +-13549 , +7877 , +-12531 , +21719 , +26035 , +-1537 , +23965 , +25447 , +14293 , +18439 , +443 , +-5105 , +-17367 , +-30139 , +-15507 , +413 , +8175 , +-5231 , +-2063 , +-5479 , +-22681 , +-10665 , +27475 , +3501 , +12949 , +17763 , +9867 , +17577 , +-1371 , +-14583 , +10767 , +-12805 , +8127 , +-21785 , +-2833 , +-27489 , +8031 , +21017 , +12395 , +1691 , +-13521 , +6641 , +22537 , +12795 , +-10145 , +-9937 , +-18891 , +24643 , +-24715 , +26553 , +-29363 , +-6037 , +9393 , +10453 , +-15033 , +28499 , +223 , +4065 , +-2631 , +20159 , +17069 , +6021 , +9345 , +23249 , +-8055 , +-23695 , +4305 , +-16905 , +-11533 , +-15207 , +25295 , +9071 , +28503 , +-10273 , +-26717 , +-6091 , +7015 , +30551 , +541 , +-30075 , +-3855 , +13825 , +-18495 , +4037 , +27193 , +7665 , +-15769 , +-26351 , +-20787 , +26905 , +28235 , +-8677 , +-26399 , +27767 , +3245 , +-14661 , +2851 , +11731 , +739 , +-9517 , +-20709 , +-25621 , +32247 , +-16173 , +-19463 , +-7873 , +-23881 , +-32081 , +-23055 , +-14031 , +-28073 , +-11951 , +-2537 , +-20521 , +7037 , +-357 , +19119 , +-3047 , +28645 , +-6699 , +12303 , +25723 , +-18833 , +31405 , +16877 , +-25003 , +-11839 , +13991 , +25919 , +-10375 , +13139 , +7455 , +10891 , +2691 , +4885 , +-29259 , +-3897 , +-639 , +-7305 , +-25259 , +-8019 , +6957 , +23057 , +11673 , +22675 , +-26965 , +-6993 , +31449 , +-7997 , +-11843 , +-7441 , +22675 , +16469 , +32121 , +31831 , +-11165 , +-13691 , +28041 , +27373 , +30599 , +31881 , +-27177 , +-28077 , +-8499 , +1009 , +10961 , +-17577 , +-7927 , +17777 , +23573 , +19475 , +-1001 , +31819 , +-24137 , +21629 , +16461 , +-30183 , +5101 , +-14455 , +29299 , +-28889 , +-15027 , +14519 , +-25545 , +25425 , +-26751 , +-2511 , +-15569 , +1879 , +-32121 , +-10395 , +-437 , +-22859 , +-14757 , +-26605 , +-24117 , +16891 , +-191 , +6127 , +-17989 , +-26199 , +-27539 , +22201 , +-29975 , +29053 , +31043 , +-31543 , +21085 , +-15275 , +-18161 , +57 , +-1195 , +135 , +-15045 , +-27029 , +947 , +-6993 , +-507 , +-7633 , +18177 , +5395 , +28093 , +7763 , +-6173 , +369 , +11895 , +17601 , +4109 , +13149 , +29255 , +-11763 , +-16707 , +-25317 , +-23049 , +1433 , +23991 , +239 , +-22977 , +-2521 , +21689 , +2299 , +32639 , +21231 , +21361 , +10133 , +-20491 , +10557 , +-30217 , +-10205 , +25715 , +-31105 , +-30775 , +22633 , +-22629 , +20205 , +-1729 , +29291 , +-1127 , +8333 , +-1153 , +28357 , +22097 , +-25889 , +16127 , +-14469 , +-2013 , +-7449 , +-20363 , +-19629 , +5405 , +-17465 , +-8111 , +8633 , +-14161 , +3039 , +-8011 , +16131 , +19435 , +9819 , +-11789 , +6489 , +-6597 , +-20141 , +-10889 , +32265 , +-28525 , +-32675 , +-24755 , +-22697 , +-15567 , +15273 , +24083 , +-11549 , +26065 , +11159 , +12655 , +22645 , +23139 , +205 , +-6385 , +22875 , +-26037 , +-3881 , +13843 , +-24513 , +24077 , +-203 , +12565 , +-13955 , +18319 , +-13577 , +9877 , +19461 , +1741 , +-18213 , +-22535 , +31395 , +28947 , +-11815 , +-4353 , +5603 , +-32081 , +11845 , +22969 , +-31129 , +17203 , +17763 , +13569 , +22461 , +1061 , +-1663 , +-29321 , +2997 , +-3527 , +-18295 , +16113 , +-8645 , +28937 , +-30431 , +-1411 , +-28233 , +14671 , +23617 , +31441 , +-9261 , +-20069 , +31557 , +-24765 , +-29977 , +31115 , +27277 , +-23227 , +-1089 , +-24699 , +6287 , +14433 , +-2047 , +30957 , +-20107 , +-28511 , +-27393 , +-27429 , +-4307 , +22427 , +11023 , +-16041 , +15883 , +-29733 , +-671 , +-25837 , +-29227 , +6879 , +-21921 , +-24677 , +10087 , +27027 , +-905 , +14867 , +24257 , +-31935 , +13189 , +-15763 , +31145 , +9999 , +24219 , +-6367 , +-23879 , +27641 , +-8605 , +31081 , +16635 , +13121 , +-22545 , +5105 , +-29689 , +8559 , +24605 , +-27625 , +-19313 , +21953 , +-6305 , +-8803 , +31105 , +-26581 , +28195 , +-7963 , +-32357 , +13773 , +-22113 , +23461 , +20867 , +17379 , +16685 , +19495 , +13919 , +-32435 , +3111 , +-28939 , +-783 , +-29069 , +14393 , +-24805 , +-13017 , +-19503 , +-4037 , +-3877 , +571 , +-4385 , +-25715 , +-8473 , +22339 , +32145 , +19941 , +-24043 , +16467 , +-24495 , +32695 , +19355 , +-14325 , +-13713 , +-22789 , +14787 , +-13899 , +-1763 , +-14193 , +-215 , +-8225 , +26861 , +-26093 , +13421 , +-8343 , +25025 , +19509 , +11377 , +14121 , +20801 , +-27245 , +777 , +3065 , +-5155 , +5645 , +-455 , +26969 , +-29633 , +-21851 , +-17941 , +24187 , +-30401 , +-13879 , +5677 , +24553 , +-17817 , +-32709 , +24539 , +-14963 , +-7459 , +9821 , +-21533 , +-17065 , +15075 , +26127 , +-8963 , +-30127 , +-12337 , +-22265 , +19419 , +26671 , +-3457 , +-30809 , +-30233 , +-5259 , +27737 , +20561 , +13945 , +13825 , +-19785 , +16203 , +24209 , +-10195 , +-12055 , +32521 , +24331 , +-18845 , +16553 , +-30449 , +-16035 , +-13513 , +26897 , +-189 , +2759 , +7673 , +-997 , +-27189 , +-2539 , +-14889 , +-5491 , +9569 , +4043 , +20843 , +9855 , +32295 , +11497 , +27353 , +-5053 , +4871 , +-19429 , +4201 , +-13845 , +5513 , +12661 , +14741 , +7483 , +6695 , +11431 , +16555 , +16417 , +-8921 , +-17991 , +-5917 , +7083 , +16373 , +-17341 , +22771 , +22919 , +5881 , +21793 , +-7637 , +-5137 , +-8209 , +29359 , +-5109 , +9261 , +-1853 , +-1155 , +-9127 , +3977 , +28383 , +-29809 , +21441 , +21195 , +-241 , +15367 , +-26909 , +15399 , +24019 , +28015 , +31727 , +17345 , +24627 , +3169 , +-19261 , +-19813 , +7455 , +18633 , +-12937 , +-22507 , +-24763 , +14229 , +-18561 , +13793 , +16229 , +22263 , +14657 , +-13701 , +16171 , +27925 , +6693 , +-24033 , +-17271 , +-18111 , +25403 , +30277 , +-27249 , +-4167 , +-29623 , +9117 , +21693 , +-2091 , +-4765 , +32377 , +-16925 , +-6971 , +19719 , +3537 , +4981 , +8391 , +-7499 , +-6983 , +-21407 , +17119 , +-23037 , +21079 , +-3473 , +-30955 , +16955 , +-24489 , +24847 , +24863 , +-31123 , +-26639 , +-25419 , +8613 , +-22009 , +1357 , +15029 , +9721 , +15861 , +-3701 , +20885 , +-30137 , +8753 , +-13513 , +27111 , +-10671 , +22493 , +13627 , +-6237 , +-25427 , +2011 , +-19361 , +-31745 , +-31631 , +-27163 , +-3267 , +-4159 , +-19081 , +6187 , +-11083 , +13855 , +7947 , +2909 , +3313 , +-2027 , +-28375 , +-25773 , +30927 , +6197 , +8247 , +22553 , +-5147 , +-4341 , +-13515 , +-20595 , +-21265 , +-24593 , +-9095 , +887 , +22733 , +-22947 , +-789 , +-19431 , +25595 , +13261 , +29113 , +-2217 , +-3453 , +30217 , +31885 , +-11201 , +16001 , +24077 , +22089 , +6955 , +17679 , +-171 , +-17345 , +-19887 , +-3651 , +8123 , +-30747 , +3813 , +-32617 , +4047 , +18703 , +12967 , +20109 , +25517 , +23211 , +1539 , +-12173 , +-23471 , +27123 , +26273 , +-6023 , +-28295 , +-6105 , +-15735 , +21021 , +3063 , +24265 , +-26711 , +23727 , +16517 , +7755 , +-20477 , +-21447 , +11047 , +16213 , +29233 , +14599 , +2811 , +28273 , +7815 , +17811 , +-8557 , +31303 , +20653 , +-31997 , +-32563 , +7255 , +-25165 , +7199 , +32303 , +-3021 , +-22877 , +-8503 , +15031 , +11565 , +30633 , +15353 , +-32709 , +-14697 , +-29799 , +22059 , +3387 , +-2433 , +19479 , +-10653 , +15421 , +-24869 , +26145 , +-16483 , +23459 , +19787 , +-13519 , +-1847 , +-12797 , +-17077 , +-18735 , +-15039 , +-29949 , +21743 , +-28491 , +-7231 , +6311 , +-27621 , +845 , +-29729 , +-27339 , +-4551 , +7911 , +517 , +-5757 , +1645 , +-7875 , +-1563 , +-17445 , +-14761 , +-1643 , +32633 , +15171 , +18243 , +8529 , +-24979 , +23393 , +1507 , +-7919 , +-32727 , +-26413 , +22667 , +6723 , +14391 , +-8709 , +-24607 , +11579 , +-2231 , +-24471 , +10781 , +5073 , +-9049 , +-12639 , +16571 , +18549 , +7731 , +-22909 , +22709 , +-11833 , +-16687 , +3097 , +-8897 , +19119 , +-29843 , +30955 , +-29447 , +16115 , +-27029 , +7145 , +-7765 , +-19367 , +-5727 , +16815 , +31353 , +14385 , +-22829 , +-25239 , +159 , +18803 , +20133 , +-30171 , +32423 , +30559 , +26133 , +-9041 , +-24029 , +3203 , +12915 , +24041 , +-8221 , +-24987 , +-15397 , +-31327 , +-3413 , +22931 , +1583 , +-29209 , +-21389 , +25143 , +4227 , +30441 , +-28143 , +8505 , +27429 , +4939 , +14723 , +-10805 , +-31735 , +-19207 , +-7531 , +17297 , +2503 , +-28021 , +16937 , +-10971 , +25877 , +32013 , +-2077 , +2879 , +2229 , +-409 , +-22939 , +-28599 , +-12297 , +30759 , +9739 , +-14221 , +9133 , +23269 , +-13797 , +13899 , +7591 , +3601 , +12423 , +-29729 , +25249 , +-24493 , +-27623 , +-16317 , +-5435 , +-10145 , +6455 , +447 , +28831 , +-16821 , +3349 , +-9133 , +-16743 , +13675 , +-28823 , +27867 , +-27929 , +-16727 , +-24915 , +-1885 , +21009 , +-1191 , +-309 , +-16003 , +16347 , +2195 , +-3483 , +28257 , +30407 , +19217 , +15993 , +-8069 , +22023 , +-15493 , +28845 , +-13111 , +-25095 , +-31927 , +-8203 , +-3535 , +-3299 , +23061 , +24537 , +17435 , +-113 , +21369 , +7717 , +-7803 , +-5381 , +7521 , +-23769 , +12447 , +24859 , +-4379 , +27743 , +-2333 , +-8539 , +1957 , +6591 , +-14937 , +31953 , +24473 , +-23205 , +-27841 , +-3259 , +-24719 , +-25171 , +-10101 , +2197 , +-1689 , +-9669 , +2839 , +10545 , +-1383 , +-23835 , +-13395 , +23787 , +-4889 , +-15991 , +-24209 , +21219 , +-7873 , +30279 , +-26253 , +-17405 , +-1409 , +-14793 , +-23851 , +-21507 , +4297 , +7321 , +-177 , +14521 , +17753 , +-18787 , +-24485 , +4175 , +-24859 , +-11895 , +-14149 , +15751 , +18023 , +4989 , +-13665 , +-11575 , +31881 , +9899 , +14903 , +-19559 , +-8347 , +-253 , +27849 , +13451 , +6389 , +-15747 , +-25525 , +-13891 , +-29227 , +-13377 , +-30847 , +31699 , +9391 , +-16539 , +-6519 , +23403 , +-16895 , +11179 , +-29699 , +-21743 , +29829 , +-21839 , +-30071 , +-2109 , +15869 , +-213 , +14075 , +-10279 , +1169 , +9111 , +24299 , +-30581 , +-12123 , +-15357 , +-29759 , +8675 , +6959 , +6709 , +-21927 , +-26315 , +-8041 , +-23445 , +-4329 , +18967 , +-29689 , +-20847 , +20099 , +15833 , +21315 , +9721 , +25175 , +-5763 , +6917 , +-20585 , +4899 , +-26059 , +31703 , +30897 , +-8613 , +18509 , +-155 , +-17889 , +4343 , +2225 , +11859 , +26107 , +-12665 , +-11041 , +-31071 , +-2077 , +15563 , +-7843 , +-3467 , +-8279 , +-21557 , +15031 , +-10367 , +32397 , +4719 , +-7949 , +22219 , +12023 , +-18537 , +6531 , +-10989 , +20137 , +24505 , +12239 , +25511 , +-15485 , +-10515 , +23575 , +8625 , +-3411 , +12173 , +2299 , +11809 , +-23975 , +-29363 , +12139 , +16887 , +-16905 , +-11053 , +293 , +-29921 , +29931 , +6087 , +-26201 , +-8243 , +-21557 , +5499 , +-4697 , +-7605 , +14353 , +-22545 , +-20205 , +11617 , +-8615 , +30077 , +27521 , +8473 , +-29937 , +-16671 , +29479 , +26665 , +-16971 , +-24099 , +1623 , +-12863 , +-24947 , +-22461 , +15225 , +31717 , +-18723 , +-1121 , +-131 , +14919 , +-15457 , +5441 , +-9517 , +-14949 , +-25927 , +17111 , +-19223 , +-10379 , +-25925 , +-10353 , +19997 , +-2405 , +-25325 , +24991 , +-22471 , +-22561 , +-7481 , +-17301 , +5483 , +6009 , +-3163 , +22293 , +9657 , +-11553 , +-6135 , +-30825 , +11003 , +-21737 , +5385 , +16993 , +-29867 , +22425 , +-27851 , +3685 , +-26067 , +-3685 , +-26681 , +-29257 , +12197 , +-8203 , +6243 , +29349 , +-18801 , +19315 , +-20147 , +14669 , +-5909 , +-19543 , +17943 , +32181 , +-3369 , +-17323 , +21741 , +18021 , +13325 , +-13521 , +29755 , +7035 , +22491 , +-29119 , +-3349 , +16969 , +-1125 , +711 , +4893 , +-2717 , +-25691 , +5245 , +-10393 , +-3769 , +-307 , +28031 , +-9605 , +11617 , +-10147 , +-29031 , +10609 , +6585 , +-10109 , +-14295 , +-26507 , +14581 , +-7337 , +11115 , +-30209 , +28415 , +-22971 , +3165 , +-24429 , +-9185 , +17423 , +11281 , +21231 , +-25467 , +20289 , +9089 , +-9527 , +17517 , +-13527 , +9971 , +30215 , +28855 , +27473 , +-17983 , +29297 , +17399 , +-13965 , +27325 , +-1037 , +10257 , +-13837 , +12555 , +9547 , +-21419 , +-6435 , +-32405 , +9033 , +-10221 , +-26287 , +-19427 , +12931 , +-13903 , +-26237 , +-11465 , +8073 , +-1467 , +11575 , +27001 , +-5721 , +-589 , +15533 , +27049 , +30743 , +5945 , +26145 , +-14743 , +-9803 , +31377 , +-14397 , +-11631 , +1857 , +-28281 , +-18389 , +513 , +-24563 , +7691 , +9561 , +8965 , +-26307 , +-28465 , +-11745 , +-22499 , +22391 , +27745 , +10795 , +6755 , +11047 , +3259 , +-7059 , +19547 , +-22743 , +-21661 , +11293 , +25939 , +-13817 , +-2051 , +-30677 , +23851 , +29113 , +7525 , +14651 , +193 , +4555 , +-29879 , +17947 , +5821 , +9257 , +23619 , +-4423 , +-17175 , +19527 , +-20379 , +-16989 , +-27125 , +-23323 , +-11167 , +-4109 , +-8123 , +12347 , +-29417 , +27603 , +3035 , +-7493 , +24495 , +-661 , +-5475 , +16457 , +11825 , +4707 , +4021 , +1001 , +159 , +-21553 , +30721 , +-13821 , +21129 , +-16719 , +4845 , +13583 , +-17107 , +-17679 , +17351 , +-31525 , +22019 , +28873 , +-3173 , +6199 , +-26143 , +3277 , +19341 , +-11983 , +15495 , +25175 , +-20569 , +-11311 , +-19259 , +15495 , +4667 , +-26805 , +-8955 , +-4683 , +14263 , +-15943 , +-32657 , +-10901 , +765 , +-14761 , +11383 , +5345 , +25151 , +-16847 , +7931 , +10733 , +-2993 , +29545 , +-22309 , +-22397 , +-389 , +5857 , +-8945 , +-13657 , +-13589 , +-26497 , +-7107 , +3819 , +1901 , +6619 , +-13097 , +-25247 , +15577 , +29567 , +12205 , +-21741 , +-2335 , +17561 , +-32505 , +-27647 , +-19351 , +-31433 , +26177 , +-7273 , +14439 , +4861 , +-6179 , +927 , +21297 , +12381 , +-10211 , +-13887 , +-17317 , +28241 , +17949 , +-25739 , +5391 , +-1905 , +21865 , +24703 , +-21791 , +-17339 , +21011 , +-1049 , +4907 , +24915 , +22867 , +-31893 , +14051 , +-29193 , +28311 , +-4735 , +-6413 , +27925 , +21785 , +28101 , +-28397 , +-4381 , +1537 , +14327 , +11549 , +-17365 , +6903 , +-7823 , +-1301 , +21495 , +1337 , +6435 , +10409 , +19413 , +26937 , +-4605 , +-1615 , +10883 , +30379 , +23563 , +-31265 , +-10953 , +-27347 , +22449 , +-22163 , +1859 , +15693 , +4059 , +15691 , +-13219 , +22061 , +-24997 , +12273 , +30037 , +-4199 , +-8475 , +-26941 , +-191 , +-20325 , +-23417 , +20443 , +25925 , +-11627 , +1443 , +19563 , +-11073 , +221 , +-2457 , +7053 , +15365 , +-2865 , +-5699 , +-12893 , +11163 , +9831 , +-20271 , +-14289 , +-32275 , +26969 , +20733 , +-24033 , +-9851 , +-12625 , +2119 , +-24395 , +12737 , +-23853 , +14423 , +-4907 , +-13807 , +-8137 , +28655 , +6365 , +-22615 , +-4511 , +19173 , +3841 , +-16963 , +1415 , +24729 , +37 , +12343 , +3757 , +-1811 , +27435 , +-22287 , +22577 , +-16449 , +-11047 , +14183 , +-2321 , +11995 , +18467 , +-19721 , +11213 , +-6531 , +14093 , +6039 , +-23071 , +-21441 , +-11265 , +-10999 , +-1795 , +18587 , +31645 , +-30573 , +8395 , +-1319 , +18205 , +6465 , +26727 , +-17523 , +24361 , +-20851 , +-29065 , +1419 , +10021 , +31143 , +32189 , +23911 , +-9957 , +-14049 , +29241 , +20321 , +-22011 , +24359 , +-7495 , +7145 , +3753 , +-32183 , +1779 , +-13681 , +14581 , +-16231 , +21019 , +-9349 , +26061 , +-8843 , +-17917 , +20335 , +4977 , +-7751 , +8875 , +15919 , +-18359 , +-14731 , +-14757 , +-19577 , +4673 , +-19923 , +-3525 , +2745 , +-22873 , +16517 , +-4243 , +-32639 , +-30091 , +-13181 , +28835 , +13181 , +2873 , +13637 , +23607 , +19249 , +20579 , +5425 , +19139 , +32127 , +-29411 , +-7235 , +-28101 , +-21867 , +-9559 , +-1643 , +13701 , +-14479 , +21301 , +-4255 , +-28533 , +-12593 , +-31441 , +20213 , +6361 , +-3927 , +-10455 , +3851 , +2743 , +-18389 , +-3037 , +-11907 , +23225 , +24617 , +-10129 , +23547 , +-15395 , +3611 , +-26883 , +17219 , +18979 , +11159 , +28479 , +16603 , +2467 , +-27075 , +19321 , +11079 , +-21981 , +-8637 , +16285 , +2239 , +20277 , +19285 , +8351 , +13421 , +23753 , +-8155 , +-13227 , +3615 , +-6073 , +5197 , +14783 , +11393 , +11819 , +31963 , +-5641 , +-30245 , +-7145 , +6971 , +-11921 , +-23747 , +-16531 , +-30031 , +20959 , +577 , +2153 , +-15273 , +23695 , +10557 , +-28233 , +-20077 , +21809 , +23039 , +-4981 , +17673 , +-12989 , +12037 , +12601 , +21019 , +-20521 , +32561 , +13391 , +-9509 , +-2565 , +-31739 , +-32723 , +3207 , +31619 , +-17833 , +-5355 , +-23937 , +3181 , +30097 , +8657 , +-6209 , +17073 , +-25251 , +-321 , +3795 , +19609 , +-29209 , +1393 , +6229 , +13219 , +-28013 , +-9541 , +-37 , +-17465 , +-3283 , +4443 , +26493 , +29539 , +2993 , +8959 , +31169 , +2947 , +26227 , +-4631 , +14873 , +-28477 , +20701 , +-28923 , +-1063 , +-25435 , +-7509 , +-3971 , +14257 , +5985 , +-4193 , +-6955 , +30625 , +-23989 , +-9289 , +9855 , +-28299 , +17055 , +-13849 , +5111 , +-6213 , +25821 , +7511 , +-32675 , +-5829 , +-12123 , +-15087 , +28805 , +-30991 , +-23287 , +19007 , +7317 , +-10109 , +-2711 , +6367 , +3609 , +-22727 , +7879 , +-1281 , +-19805 , +6007 , +28067 , +15991 , +15065 , +10415 , +11347 , +32025 , +7697 , +17381 , +-20009 , +32623 , +6767 , +-28521 , +-30409 , +12787 , +2417 , +18501 , +18769 , +9407 , +24851 , +-16293 , +13631 , +-29225 , +-18083 , +25269 , +15649 , +17865 , +11903 , +19599 , +30595 , +-18691 , +-2191 , +-13311 , +-21723 , +14167 , +2299 , +29681 , +353 , +-15229 , +7513 , +-363 , +30973 , +-25957 , +-1967 , +-18847 , +12673 , +-25235 , +16327 , +-25207 , +10005 , +3117 , +-16169 , +3055 , +30417 , +30635 , +31089 , +-1121 , +-15457 , +29457 , +15977 , +-17461 , +-11383 , +-2287 , +22041 , +16957 , +-617 , +-4179 , +-8339 , +-11437 , +-32731 , +-5025 , +23943 , +14451 , +22461 , +27353 , +16335 , +15625 , +-20881 , +-19399 , +-16755 , +-22023 , +31649 , +-15159 , +-7165 , +30619 , +27763 , +13869 , +6659 , +28207 , +-21361 , +-23519 , +5127 , +-4901 , +-22647 , +-31825 , +28105 , +3869 , +23207 , +-6933 , +-10657 , +-5945 , +20303 , +5921 , +8137 , +4211 , +-10805 , +-22631 , +2839 , +12415 , +-26451 , +-19771 , +10485 , +-10619 , +8355 , +3 , +-22843 , +14673 , +24785 , +-8245 , +24643 , +11609 , +-7259 , +17517 , +3463 , +-77 , +-20429 , +3399 , +-6733 , +28561 , +-32760 , +-897 , +-29185 , +32315 , +23951 , +20279 , +-21167 , +19841 , +17109 , +28747 , +-933 , +-15181 , +-12049 , +-17021 , +10797 , +13341 , +-18481 , +-10421 , +27983 , +-20733 , +-6497 , +29429 , +6495 , +21513 , +7311 , +10083 , +4379 , +15423 , +-3529 , +11333 , +27911 , +18569 , +-3221 , +-31783 , +11903 , +-31325 , +-7787 , +-30959 , +22351 , +24207 , +-18807 , +19553 , +15819 , +21907 , +32738 , +-7969 , +30055 , +31665 , +-21805 , +-13293 , +9169 , +24219 , +-10101 , +-10723 , +6791 , +-23247 , +-11523 , +-30605 , +-29455 , +4721 , +-17851 , +24861 , +-17677 , +9973 , +637 , +12393 , +26637 , +6379 , +23059 , +-26335 , +30449 , +23181 , +4251 , +11081 , +-32365 , +26387 , +5687 , +4429 , +-14895 , +3633 , +11103 , +-14391 , +15993 , +-2545 , +22851 , +-10321 , +16623 , +-29759 , +19101 , +2831 , +30523 , +6711 , +-25331 , +5183 , +-29015 , +16323 , +-15633 , +8097 , +29403 , +31237 , +-29259 , +18389 , +28007 , +105 , +-1863 , +25715 , +489 , +-23265 , +19615 , +11069 , +-8547 , +-2933 , +13093 , +7133 , +-18055 , +19277 , +-11397 , +11809 , +29121 , +6823 , +-28893 , +-17757 , +20007 , +4997 , +30529 , +-27113 , +-20649 , +28647 , +4723 , +-10513 , +3865 , +4833 , +-29907 , +15775 , +-23581 , +-18665 , +-8557 , +-18609 , +-32519 , +-7255 , +9161 , +-3301 , +-29957 , +-8271 , +-31791 , +-32319 , +6399 , +23619 , +-1567 , +30685 , +-26061 , +3287 , +29757 , +2725 , +6119 , +-6585 , +28045 , +7961 , +-5075 , +15437 , +-26955 , +17347 , +-31499 , +30063 , +-22227 , +3307 , +-29803 , +-29309 , +-1575 , +19279 , +18677 , +7839 , +-7067 , +5467 , +-25063 , +10387 , +-22763 , +6883 , +26941 , +20195 , +-14555 , +15191 , +-20623 , +-15043 , +-27237 , +-10625 , +25257 , +-23953 , +-4955 , +-12365 , +7263 , +-11801 , +-17049 , +-17521 , +-23393 , +23455 , +-31135 , +12333 , +-25173 , +15007 , +19003 , +-20509 , +11275 , +31221 , +7971 , +9837 , +-3289 , +-12255 , +-4447 , +28851 , +15969 , +28957 , +32247 , +-6403 , +-20821 , +20171 , +22253 , +24997 , +17567 , +32750 , +-22219 , +-20393 , +7961 , +1443 , +-17349 , +-1087 , +-14775 , +-22689 , +2429 , +2517 , +23383 , +7515 , +-26775 , +-9097 , +-31635 , +16791 , +-21325 , +-23875 , +27991 , +32587 , +29735 , +29859 , +-19299 , +14561 , +-22265 , +-11967 , +-25325 , +23665 , +-7195 , +22405 , +23545 , +-8527 , +-24591 , +-20111 , +-9333 , +21621 , +-28451 , +10697 , +-13789 , +25249 , +24877 , +-7089 , +19911 , +15527 , +28947 , +12415 , +13385 , +-5769 , +-21051 , +-4417 , +-2087 , +-30977 , +6483 , +-32735 , +28705 , +17439 , +6917 , +14479 , +-30759 , +18717 , +12335 , +-13423 , +-12571 , +18089 , +5509 , +-21643 , +16615 , +-7351 , +255 , +-11495 , +6235 , +-16555 , +1061 , +-3569 , +1581 , +18291 , +12011 , +29545 , +-23087 , +3461 , +-29943 , +22243 , +-31269 , +-8143 , +-30759 , +21661 , +-25317 , +22725 , +-4447 , +17245 , +-31701 , +6083 , +-2179 , +14647 , +19349 , +26569 , +-26971 , +24275 , +18013 , +32529 , +-26029 , +-4833 , +-24285 , +5995 , +-20205 , +19843 , +7609 , +-27475 , +-3939 , +-11097 , +-13515 , +29105 , +-2769 , +3989 , +4751 , +11213 , +12645 , +7049 , +-4165 , +25797 , +-31091 , +21 , +-20677 , +29519 , +-17025 , +-31769 , +2103 , +6653 , +-2049 , +29689 , +-5349 , +-25411 , +-19833 , +-10933 , +-9045 , +-4909 , +28325 , +-1763 , +13721 , +9031 , +-25125 , +-5211 , +7843 , +491 , +-6935 , +13641 , +-24283 , +-19771 , +20395 , +26195 , +-23499 , +32273 , +-29323 , +25899 , +11831 , +-20813 , +-12825 , +-2287 , +-15619 , +23863 , +22083 , +31575 , +13907 , +22845 , +26441 , +20749 , +-13535 , +-5765 , +-29809 , +-8373 , +-2307 , +-26063 , +-6569 , +-18471 , +-23989 , +-11743 , +-25885 , +-13203 , +15563 , +26119 , +-7079 , +11883 , +32435 , +-7533 , +-2549 , +20749 , +11857 , +-15137 , +15457 , +17959 , +-15851 , +22887 , +5665 , +-4771 , +14131 , +31105 , +-25011 , +-29225 , +-2891 , +-8361 , +-24961 , +-11651 , +4887 , +18523 , +16829 , +-24403 , +-8097 , +7749 , +-24623 , +-16013 , +-1871 , +-8569 , +-18147 , +-10943 , +-13461 , +-1983 , +-1279 , +-30165 , +-6983 , +22723 , +-7007 , +-29545 , +-11343 , +24189 , +-7095 , +10877 , +1261 , +27255 , +1345 , +8471 , +27033 , +-14253 , +-31195 , +-29403 , +17175 , +9397 , +-4159 , +30101 , +-5361 , +19015 , +-15265 , +-5943 , +-4087 , +23857 , +24491 , +9287 , +24201 , +19721 , +7939 , +-16649 , +-29027 , +-19123 , +27219 , +19923 , +19969 , +-7065 , +-19093 , +31525 , +-16721 , +16659 , +4565 , +2111 , +-15875 , +-14751 , +26929 , +-20049 , +18477 , +-12755 , +-2033 , +28159 , +23689 , +-7657 , +8513 , +-289 , +17923 , +-13577 , +12721 , +19691 , +-27587 , +-26919 , +11461 , +-31265 , +28973 , +-12943 , +14635 , +30023 , +3891 , +-29929 , +-14793 , +4037 , +-29781 , +-17855 , +441 , +-22339 , +7695 , +9071 , +-18861 , +-13679 , +-5243 , +-29771 , +10843 , +10587 , +22271 , +-26203 , +5923 , +-22491 , +9677 , +-18231 , +20703 , +-5985 , +20665 , +-19549 , +14069 , +23891 , +-9829 , +15387 , +-31529 , +22119 , +32119 , +6781 , +-25763 , +207 , +-25839 , +15089 , +-9573 , +-12287 , +9729 , +20849 , +9277 , +18997 , +-427 , +19517 , +7763 , +-20709 , +-31583 , +19679 , +20153 , +28941 , +-15719 , +24471 , +-22811 , +-1841 , +45 , +-22185 , +-26559 , +-21563 , +7447 , +17469 , +18693 , +-21341 , +-30975 , +-32119 , +397 , +20145 , +9231 , +-12265 , +27185 , +-19589 , +2561 , +-5549 , +-20069 , +-29937 , +22985 , +-22859 , +13223 , +28333 , +6045 , +-71 , +-18255 , +-12795 , +22421 , +-24495 , +-6797 , +-6417 , +-26937 , +-23067 , +-3235 , +-16479 , +-26417 , +-12089 , +18793 , +-25753 , +-24069 , +-9429 , +3447 , +-7717 , +26069 , +11937 , +17957 , +-3939 , +-32191 , +-20473 , +-23265 , +-12403 , +-8431 , +-9715 , +-28155 , +16257 , +-13789 , +-8673 , +-29255 , +7037 , +10227 , +997 , +-31175 , +-31633 , +-28489 , +-197 , +13047 , +-12451 , +-19979 , +29863 , +4529 , +-20953 , +-13157 , +25681 , +7117 , +-30019 , +-22633 , +-19587 , +-13271 , +-29483 , +-12559 , +-29571 , +-29319 , +16927 , +30559 , +-13003 , +10529 , +24841 , +-8603 , +15363 , +20101 , +-25113 , +32483 , +-17595 , +-13593 , +2747 , +-3535 , +13133 , +-30273 , +-1693 , +-10825 , +27345 , +-2675 , +-10159 , +-29427 , +-31249 , +-11973 , +457 , +14463 , +25501 , +8685 , +-2669 , +-18369 , +-28251 , +16731 , +-2761 , +5091 , +3867 , +-20311 , +31409 , +7827 , +-27309 , +-15421 , +-32335 , +-20589 , +-24735 , +-17105 , +6983 , +18271 , +-6137 , +29285 , +17447 , +31047 , +-27087 , +4269 , +30039 , +-3711 , +-12303 , +6773 , +-6291 , +28611 , +-5135 , +13601 , +73 , +-29093 , +-1681 , +-8335 , +-7357 , +-21045 , +-10575 , +-22451 , +-25617 , +-8997 , +-29181 , +-477 , +-9395 , +5429 , +12585 , +11965 , +-16509 , +-23433 , +-5285 , +-20583 , +-25065 , +6613 , +-32327 , +18113 , +18599 , +-28631 , +-1463 , +11303 , +-15333 , +-21361 , +-24215 , +-17545 , +-5531 , +10615 , +9673 , +-12689 , +-4429 , +17993 , +743 , +22463 , +15405 , +-3217 , +-3585 , +22101 , +-22745 , +4855 , +-26227 , +-18109 , +26843 , +-23131 , +13113 , +19467 , +-8795 , +15503 , +24665 , +17273 , +32177 , +-30923 , +-6937 , +-31995 , +2113 , +22035 , +-32525 , +12955 , +22871 , +-5693 , +-24411 , +-17149 , +-7687 , +-6517 , +6829 , +-12629 , +15071 , +-15235 , +-19141 , +27915 , +-13901 , +5129 , +-22149 , +-16781 , +-3901 , +28441 , +-8817 , +-26005 , +-16067 , +28327 , +3327 , +31367 , +-22553 , +31955 , +-26695 , +-7237 , +3151 , +-9343 , +12163 , +-8127 , +23185 , +-18579 , +7155 , +-24101 , +28547 , +-24637 , +19697 , +-6973 , +-8333 , +14903 , +-3165 , +10993 , +3935 , +-29793 , +-9755 , +26617 , +-26453 , +-21243 , +12369 , +13673 , +-4267 , +17739 , +2719 , +10135 , +-15691 , +-24781 , +17075 , +23293 , +4277 , +-19447 , +-1531 , +-11755 , +25471 , +679 , +29091 , +-17493 , +12737 , +-29919 , +28839 , +14775 , +-9893 , +-14643 , +-3801 , +-16199 , +11421 , +-2843 , +19389 , +-22647 , +2559 , +-27751 , +-26261 , +-75 , +-2473 , +23979 , +-31707 , +20059 , +12687 , +-23415 , +15809 , +15737 , +15845 , +24281 , +-10901 , +-8757 , +20887 , +-15455 , +-23643 , +-28383 , +-21723 , +-13869 , +1211 , +13625 , +16389 , +25709 , +6587 , +-22765 , +-16933 , +-11509 , +-14355 , +14033 , +22067 , +-8445 , +-20785 , +9217 , +19639 , +23803 , +19587 , +-17787 , +-16411 , +-13569 , +2261 , +10207 , +-23475 , +25377 , +24229 , +-24305 , +27203 , +31367 , +-9241 , +-3859 , +17947 , +-31479 , +12319 , +1781 , +-27935 , +-27321 , +331 , +-24911 , +18313 , +-20157 , +-16533 , +-26753 , +-2379 , +-11403 , +11885 , +5369 , +20707 , +-3993 , +-8535 , +-63 , +-24283 , +-10037 , +19423 , +-289 , +15453 , +20501 , +-9567 , +-32363 , +23287 , +12175 , +27741 , +-3649 , +21785 , +-4617 , +-15933 , +-22881 , +-18081 , +25487 , +25547 , +-20417 , +13849 , +8893 , +19237 , +4935 , +-13065 , +15645 , +-461 , +-29359 , +18763 , +-13025 , +23943 , +31171 , +28863 , +7193 , +-10547 , +-4311 , +-6521 , +-17183 , +13907 , +-21237 , +14625 , +29413 , +-12557 , +-3513 , +4745 , +15815 , +12437 , +-11293 , +753 , +24943 , +9511 , +11377 , +-8713 , +-15705 , +11273 , +-17449 , +8805 , +28717 , +11285 , +-28747 , +25697 , +-20395 , +-27635 , +19511 , +12835 , +27417 , +-24173 , +28013 , +27449 , +18613 , +1703 , +6433 , +-32205 , +23739 , +-23141 , +-26315 , +-24353 , +-19025 , +-25719 , +5749 , +9989 , +-22243 , +20815 , +-21517 , +31641 , +13361 , +-13559 , +27359 , +-22411 , +18643 , +-4609 , +26329 , +-18285 , +24377 , +-2775 , +25297 , +20675 , +9213 , +-13283 , +13915 , +31459 , +-25917 , +-30577 , +-31865 , +7065 , +-29377 , +-17853 , +-10951 , +2697 , +-24871 , +-13941 , +-16895 , +17675 , +-9019 , +7223 , +3961 , +13161 , +8847 , +14613 , +-15857 , +30865 , +11073 , +-24093 , +-23191 , +17489 , +-22791 , +-25651 , +28991 , +-24563 , +11509 , +-24995 , +20131 , +-21001 , +25145 , +-24325 , +29165 , +21191 , +11427 , +-289 , +-8957 , +16887 , +19067 , +10637 , +-7621 , +-7051 , +9879 , +-7731 , +32687 , +4571 , +16619 , +12061 , +11031 , +5165 , +935 , +-12879 , +9753 , +-4595 , +23751 , +19177 , +-3281 , +23409 , +-3025 , +-30653 , +757 , +-31517 , +22091 , +-8999 , +12803 , +-8915 , +-5355 , +-29349 , +12099 , +8603 , +4545 , +-11649 , +25297 , +-2895 , +14533 , +9727 , +27977 , +2909 , +19067 , +3599 , +-10329 , +25783 , +17971 , +8025 , +2967 , +-31693 , +24017 , +28013 , +11349 , +9825 , +28637 , +8639 , +-6143 , +26647 , +13859 , +28957 , +-9863 , +-10183 , +199 , +-22615 , +-27991 , +27619 , +21979 , +-31919 , +-6285 , +-13009 , +19837 , +-27457 , +-28427 , +-929 , +619 , +-8481 , +-16017 , +-17505 , +-4329 , +27851 , +-16237 , +-17095 , +-28855 , +5703 , +10335 , +3147 , +7725 , +10943 , +-9607 , +-22523 , +-14091 , +15027 , +17919 , +-13989 , +11751 , +-18503 , +5607 , +-13503 , +32764 , +-23823 , +-8239 , +11617 , +9971 , +509 , +-5277 , +-22189 , +13291 , +21113 , +-21985 , +-11689 , +-32127 , +-19467 , +-2115 , +14217 , +-8611 , +107 , +-17667 , +-32609 , +1361 , +-29899 , +-247 , +32025 , +-8719 , +-16755 , +7493 , +-25085 , +-17753 , +20347 , +4009 , +-11743 , +337 , +16465 , +-31845 , +15541 , +3921 , +27049 , +-15037 , +-16729 , +-19923 , +-15921 , +7015 , +-13747 , +3235 , +6857 , +-21563 , +31127 , +16447 , +-28987 , +32735 , +24271 , +-19591 , +21267 , +-15771 , +1993 , +19525 , +10651 , +-13061 , +-21597 , +30519 , +10463 , +7843 , +-1289 , +21259 , +4707 , +-11647 , +-30053 , +-10037 , +-4175 , +-20667 , +-12085 , +22625 , +11729 , +26361 , +11505 , +8619 , +-4297 , +8027 , +-3631 , +-19939 , +-13241 , +-9547 , +-5561 , +16083 , +-17851 , +-9927 , +20607 , +-3293 , +20685 , +-29997 , +-20567 , +-17467 , +9683 , +10625 , +-22477 , +-2469 , +30737 , +-27597 , +3715 , +-8815 , +-8183 , +-32231 , +23601 , +2485 , +16239 , +-22911 , +-5195 , +-8757 , +-22737 , +-8913 , +-2391 , +14633 , +27617 , +-2257 , +-12675 , +17807 , +8379 , +16441 , +18351 , +-17989 , +-20205 , +21625 , +-12411 , +26755 , +20553 , +24311 , +9281 , +29807 , +30801 , +22625 , +10207 , +-45 , +-20835 , +24175 , +-15033 , +-20133 , +18327 , +-17487 , +24583 , +-6861 , +-8031 , +-18447 , +-14709 , +-7533 , +-14205 , +-14081 , +7899 , +-4641 , +3689 , +15377 , +-14905 , +-28869 , +28507 , +-4191 , +-26457 , +-6753 , +-9679 , +13747 , +-24171 , +24185 , +-15855 , +30395 , +-25059 , +-22081 , +-2209 , +-21257 , +22653 , +17025 , +16187 , +20539 , +19287 , +25617 , +24955 , +-13743 , +-30739 , +-15479 , +-6885 , +3025 , +22229 , +-6669 , +13115 , +22901 , +-29897 , +27347 , +22679 , +-5641 , +129 , +9035 , +7547 , +27747 , +15005 , +19881 , +-21441 , +3827 , +-24401 , +-12923 , +32317 , +7777 , +19013 , +-18343 , +-14517 , +-10803 , +-10473 , +3733 , +6063 , +30463 , +18745 , +-1731 , +27803 , +17239 , +23001 , +25593 , +26403 , +27923 , +16497 , +19383 , +-7753 , +-26321 , +25731 , +-26187 , +-25577 , +2491 , +-3637 , +-7379 , +13773 , +2229 , +-14589 , +-6825 , +12075 , +-21665 , +-18675 , +5649 , +10423 , +-31211 , +-27469 , +8435 , +6445 , +26797 , +227 , +-22307 , +-19981 , +-17597 , +29529 , +9763 , +-21999 , +-27749 , +30179 , +14609 , +10155 , +6903 , +-30183 , +18703 , +-13 , +23657 , +-20083 , +-14281 , +1451 , +5045 , +4233 , +-3227 , +7703 , +-27491 , +-23739 , +26331 , +21615 , +25287 , +32161 , +24405 , +-23579 , +-28153 , +-29351 , +-101 , +-20461 , +-30911 , +22209 , +29345 , +9205 , +12733 , +-23553 , +16919 , +-4255 , +21757 , +-24905 , +-18039 , +6913 , +-1251 , +19539 , +-21003 , +27337 , +-22625 , +-6991 , +-32291 , +-30993 , +25295 , +-1187 , +-16921 , +-7327 , +13713 , +-3253 , +5617 , +7623 , +11711 , +-19189 , +12967 , +2539 , +-31995 , +8069 , +6049 , +9407 , +-3031 , +11057 , +32243 , +-23091 , +-2827 , +14283 , +-1199 , +-6349 , +-15225 , +31887 , +19863 , +23575 , +1063 , +4845 , +-23823 , +-12891 , +-6495 , +-27705 , +13923 , +5761 , +-28639 , +-16603 , +6385 , +5313 , +-16761 , +9835 , +32559 , +2667 , +21051 , +20757 , +27475 , +9309 , +-12401 , +21485 , +3035 , +24539 , +28813 , +21189 , +-22887 , +-31117 , +-8361 , +-6995 , +26705 , +30851 , +12537 , +-11605 , +-3889 , +32297 , +14535 , +10481 , +-3199 , +-10565 , +-13269 , +4765 , +-15221 , +16071 , +3853 , +30695 , +10851 , +-23423 , +24727 , +-10531 , +19433 , +-15677 , +159 , +20129 , +4859 , +-9603 , +1397 , +21783 , +-9329 , +17079 , +-17859 , +3875 , +-14513 , +1793 , +-567 , +-15525 , +-29271 , +19561 , +-17939 , +24397 , +8303 , +-19199 , +2909 , +-30941 , +-789 , +31173 , +12799 , +10223 , +-32395 , +29471 , +-7739 , +1105 , +8083 , +-14371 , +3081 , +13247 , +-15741 , +31395 , +-18083 , +3119 , +16997 , +-29203 , +3049 , +28251 , +15297 , +-2435 , +581 , +-5009 , +9133 , +5209 , +4807 , +-15543 , +-4001 , +-5565 , +14183 , +7721 , +11841 , +-13395 , +-32239 , +-25355 , +-9835 , +-18123 , +-11911 , +-27423 , +-11137 , +9117 , +-16771 , +949 , +20901 , +19773 , +23029 , +-21121 , +2889 , +515 , +-11509 , +23753 , +-24871 , +-8729 , +-25061 , +-17067 , +-6899 , +-9755 , +13315 , +-13995 , +-24961 , +22383 , +505 , +16669 , +19649 , +25199 , +-24079 , +9573 , +-28687 , +25011 , +-3231 , +-21511 , +-7969 , +-4623 , +11437 , +-22797 , +-111 , +1849 , +31981 , +-10637 , +-4499 , +24811 , +22101 , +7387 , +-11835 , +-973 , +-1793 , +3453 , +-29703 , +-14081 , +22097 , +-12831 , +28161 , +-31367 , +-6971 , +-16015 , +-11115 , +-27655 , +31821 , +-2123 , +2491 , +-121 , +-11475 , +-10995 , +17121 , +26317 , +-19643 , +-4629 , +4981 , +1417 , +32758 , +-29569 , +11263 , +-27499 , +9331 , +-9983 , +-16967 , +14415 , +671 , +7257 , +23199 , +13719 , +-1441 , +5471 , +-21995 , +-23219 , +8567 , +-10095 , +-13839 , +-8643 , +17369 , +12879 , +-19421 , +-12891 , +-15219 , +909 , +-32585 , +-2531 , +-2313 , +-28405 , +-9085 , +19743 , +-30531 , +15635 , +-29647 , +-20751 , +5143 , +-23635 , +21471 , +8489 , +29355 , +-28329 , +6959 , +-25699 , +-5919 , +-13251 , +-23063 , +-28707 , +-15935 , +10225 , +-18171 , +-6355 , +29507 , +-9305 , +1111 , +-20743 , +-7375 , +-27931 , +-22385 , +11219 , +-7051 , +12483 , +-19991 , +-29977 , +-31497 , +-16997 , +24371 , +-5649 , +17395 , +30541 , +-29333 , +-4685 , +-14125 , +31719 , +8157 , +-24833 , +12933 , +1771 , +-17235 , +-14823 , +-26797 , +-18175 , +-18943 , +31925 , +-12997 , +-7637 , +30599 , +11893 , +4809 , +18057 , +20635 , +-16417 , +-20373 , +21891 , +-3367 , +5073 , +10831 , +19339 , +32051 , +-22659 , +6835 , +13905 , +27533 , +31965 , +19655 , +21369 , +17107 , +2993 , +12283 , +-15909 , +20883 , +28911 , +15327 , +-723 , +23827 , +-27451 , +23665 , +7245 , +-27931 , +32521 , +-251 , +18919 , +-26869 , +-28111 , +-10355 , +28605 , +1667 , +-6959 , +-2441 , +-29613 , +18019 , +29069 , +18187 , +-21717 , +-2187 , +21911 , +3641 , +-2177 , +-6585 , +-10849 , +-32267 , +-7813 , +-12341 , +24915 , +4369 , +-12823 , +-11669 , +19793 , +29591 , +18553 , +-7263 , +31653 , +7061 , +12401 , +8717 , +-21831 , +7817 , +-10273 , +23573 , +-23853 , +12065 , +-29345 , +-23823 , +-1521 , +-16471 , +-30647 , +16975 , +-22833 , +-6955 , +-20631 , +-2971 , +6331 , +4383 , +12859 , +-21885 , +4145 , +16541 , +27811 , +-15813 , +-5051 , +-21159 , +3365 , +-279 , +-22729 , +-23509 , +-2667 , +8147 , +14693 , +-28147 , +-12709 , +27327 , +-25911 , +-7687 , +-15325 , +783 , +6899 , +-15555 , +26651 , +25937 , +18297 , +28749 , +10915 , +-8355 , +6389 , +3627 , +26763 , +23789 , +-24965 , +-17361 , +-32051 , +24755 , +-8299 , +-5015 , +-1861 , +-32273 , +11441 , +-25485 , +-829 , +18059 , +-27097 , +-31027 , +31645 , +-20045 , +-15965 , +-6989 , +3597 , +24299 , +-10711 , +-10123 , +-13037 , +-32345 , +-18815 , +6225 , +-32607 , +-24223 , +16955 , +-3639 , +8413 , +27193 , +-10975 , +15739 , +8661 , +27137 , +-17107 , +23415 , +-32337 , +4577 , +-8445 , +-12257 , +4459 , +-11161 , +16623 , +-26249 , +-4071 , +-18399 , +-19375 , +-11011 , +-20337 , +14007 , +21919 , +-12795 , +8605 , +-16253 , +6873 , +3219 , +12497 , +-17247 , +10369 , +31915 , +-8287 , +23957 , +9491 , +17967 , +-15573 , +8791 , +17151 , +27957 , +1647 , +23537 , +14621 , +-11551 , +26367 , +-28779 , +-7763 , +-20805 , +9279 , +3383 , +-18493 , +6277 , +22807 , +-27997 , +-5305 , +-17765 , +-18385 , +21267 , +17265 , +17599 , +8867 , +15179 , +-30797 , +-18563 , +4419 , +-13775 , +-22721 , +8185 , +18495 , +21987 , +22265 , +-9137 , +-12949 , +5453 , +24047 , +101 , +-26387 , +-14777 , +18513 , +-3255 , +-1925 , +18471 , +-18201 , +-8961 , +7445 , +733 , +4369 , +-793 , +-13517 , +29319 , +-22729 , +-32631 , +-23159 , +-20591 , +17347 , +-3341 , +2615 , +19263 , +7321 , +-9075 , +-1405 , +22743 , +1807 , +-21639 , +1301 , +-1241 , +6249 , +31839 , +-21851 , +20141 , +27849 , +-9263 , +13633 , +2081 , +19631 , +6169 , +31225 , +-24681 , +26861 , +15257 , +32029 , +24595 , +25887 , +18335 , +28913 , +13217 , +26785 , +-14407 , +1771 , +-31761 , +-4595 , +21913 , +-29851 , +1889 , +-30419 , +9567 , +-15397 , +-11601 , +-9351 , +12925 , +1945 , +-30987 , +28423 , +9475 , +-29951 , +-2989 , +-20469 , +-30845 , +21813 , +2303 , +-17205 , +25953 , +-10149 , +25827 , +17429 , +-5713 , +-23477 , +27053 , +10811 , +5763 , +11215 , +8047 , +11405 , +11469 , +5207 , +-14925 , +15173 , +-9035 , +2093 , +26899 , +-15855 , +-10643 , +-31945 , +21839 , +-26885 , +-11377 , +-28121 , +-17427 , +-14357 , +-20243 , +-969 , +26439 , +-357 , +-20241 , +-12451 , +-11737 , +-19701 , +32365 , +-14583 , +31715 , +-7035 , +2047 , +-31403 , +-12047 , +-28409 , +-13351 , +5829 , +32766 , +-23737 , +-21463 , +-18307 , +-27771 , +-28895 , +-7197 , +22767 , +10223 , +21653 , +13349 , +-13529 , +5665 , +8511 , +-7673 , +9329 , +27293 , +18507 , +-25355 , +15509 , +273 , +-14095 , +-6777 , +-14183 , +7285 , +7019 , +3291 , +2027 , +21411 , +31855 , +25709 , +31781 , +-21907 , +28451 , +-18839 , +-23753 , +12083 , +-21095 , +-24947 , +11315 , +-2817 , +16325 , +-9353 , +-24977 , +-15841 , +-3851 , +12417 , +-5297 , +19251 , +-9267 , +-4065 , +-7567 , +21201 , +17591 , +-14675 , +107 , +-31341 , +31455 , +-8757 , +-28669 , +27319 , +-2127 , +-4039 , +-27167 , +16693 , +29897 , +26153 , +32465 , +8527 , +12391 , +4635 , +2161 , +15029 , +6265 , +-22991 , +23665 , +-30955 , +5121 , +31243 , +-10683 , +-14025 , +8977 , +-18145 , +27491 , +12437 , +-29365 , +-28273 , +11761 , +31083 , +-10543 , +31613 , +-7671 , +-7843 , +-19519 , +12525 , +7533 , +-14205 , +-19929 , +28183 , +-5707 , +22279 , +-11649 , +4669 , +24857 , +-195 , +-14683 , +-18171 , +15771 , +13365 , +3919 , +25685 , +-11581 , +11483 , +-20473 , +20135 , +27095 , +2957 , +-20063 , +32221 , +30873 , +16943 , +11057 , +11937 , +-21903 , +-30013 , +2443 , +-20421 , +13367 , +19593 , +19759 , +-14109 , +27223 , +-14963 , +-2355 , +15011 , +4509 , +-12089 , +23093 , +-32603 , +25181 , +-24403 , +4049 , +23825 , +13877 , +17999 , +15517 , +20323 , +22593 , +23789 , +26789 , +-29881 , +28627 , +-19955 , +-25617 , +-30745 , +32171 , +16923 , +-1537 , +-16433 , +25519 , +24949 , +-27695 , +-18115 , +28453 , +27153 , +-22461 , +-4355 , +23915 , +-14971 , +2843 , +-20035 , +-11479 , +-21585 , +-5513 , +-26133 , +-16881 , +28097 , +-21817 , +-24057 , +-26351 , +-23073 , +4425 , +-32387 , +2833 , +9015 , +29945 , +24575 , +-10205 , +-5485 , +11793 , +31067 , +-25273 , +9081 , +-1027 , +-13867 , +20113 , +18881 , +-26159 , +23291 , +-4109 , +31655 , +14663 , +18689 , +-32661 , +15467 , +7215 , +6295 , +-28735 , +-31901 , +1137 , +30015 , +30387 , +28569 , +-19845 , +-4049 , +-22081 , +30683 , +10817 , +-10343 , +7757 , +28507 , +-2385 , +-16751 , +14955 , +14021 , +9121 , +-12965 , +18183 , +29133 , +9831 , +29261 , +-9051 , +6491 , +27815 , +-29921 , +17047 , +16911 , +-13845 , +-24895 , +14519 , +-4253 , +31629 , +16319 , +9115 , +19271 , +-1233 , +12045 , +4947 , +6699 , +22455 , +22373 , +-25447 , +-15449 , +19655 , +14621 , +-879 , +-14457 , +-12111 , +-8575 , +32509 , +-2201 , +20723 , +-3931 , +-24845 , +19667 , +21807 , +1221 , +-9699 , +-19509 , +-16227 , +-17891 , +-20891 , +-24077 , +27147 , +-16331 , +-17865 , +-11751 , +16977 , +24009 , +30519 , +-939 , +-16053 , +-28651 , +-30861 , +-7517 , +-11957 , +23219 , +3363 , +-30225 , +-3815 , +24563 , +1245 , +-2113 , +-15257 , +22959 , +6731 , +19517 , +-13621 , +-30041 , +-4245 , +-28463 , +30001 , +-16297 , +20025 , +4929 , +20955 , +-687 , +15609 , +-23231 , +-31021 , +25615 , +27871 , +-26485 , +21227 , +31317 , +-1201 , +-12417 , +-13013 , +23807 , +-619 , +-17873 , +-25909 , +-925 , +-12517 , +-26619 , +-11339 , +-1763 , +-26081 , +-10805 , +-12947 , +14707 , +4849 , +-8111 , +1175 , +-12509 , +-8795 , +17279 , +-8981 , +17857 , +-27057 , +28143 , +28581 , +-3695 , +-3143 , +-3843 , +8331 , +22231 , +-869 , +-27283 , +12631 , +16821 , +-14507 , +7287 , +2999 , +-22909 , +-17371 , +1381 , +31175 , +-7519 , +-11811 , +12203 , +-31483 , +30169 , +-17121 , +-20103 , +13251 , +-13265 , +-30185 , +-17699 , +-8915 , +12345 , +-26455 , +-8879 , +19383 , +32257 , +29493 , +-28711 , +26135 , +-20915 , +30665 , +18333 , +-26947 , +-11645 , +-13355 , +-779 , +-22067 , +-26369 , +-28053 , +29973 , +22931 , +-3609 , +-8971 , +10255 , +16769 , +-4983 , +20071 , +7035 , +28577 , +25897 , +-5889 , +-30327 , +19601 , +-25753 , +-391 , +-21351 , +4601 , +18699 , +-17723 , +-30895 , +-30847 , +20835 , +16711 , +317 , +15951 , +-24295 , +-11133 , +12251 , +763 , +22153 , +95 , +9281 , +-16889 , +-13661 , +16087 , +5413 , +31445 , +-28109 , +3895 , +15749 , +-13019 , +4037 , +-2099 , +18357 , +19719 , +-20997 , +27179 , +-25355 , +24921 , +23139 , +471 , +29075 , +4281 , +22733 , +5509 , +-6787 , +4351 , +1831 , +4815 , +4441 , +-13003 , +-22061 , +-25489 , +22553 , +-26095 , +-10109 , +-7435 , +-10975 , +-12051 , +-23673 , +12287 , +16073 , +2363 , +2481 , +7155 , +5519 , +10367 , +-10585 , +26165 , +30615 , +-32565 , +-32329 , +-6179 , +28881 , +-19025 , +9527 , +-26381 , +8081 , +-24649 , +9821 , +8233 , +-31331 , +-6553 , +-23157 , +-6901 , +24017 , +-30557 , +20277 , +7357 , +-12755 , +3003 , +-23243 , +-14031 , +20087 , +-30507 , +22685 , +8927 , +-25783 , +20713 , +-13289 , +25857 , +3501 , +24379 , +22197 , +29763 , +12091 , +21073 , +24405 , +22531 , +-7517 , +9069 , +-6037 , +-509 , +-1833 , +21635 , +-23457 , +16549 , +-30061 , +-13139 , +10861 , +-22625 , +-4483 , +6959 , +25581 , +-9415 , +-23619 , +22753 , +-13767 , +16897 , +2321 , +24627 , +-29443 , +-16125 , +14441 , +-27749 , +14609 , +5757 , +-8449 , +-5487 , +-2091 , +-14557 , +27113 , +32015 , +-255 , +5579 , +24377 , +17783 , +18691 , +-599 , +15253 , +20767 , +11737 , +-22771 , +-21439 , +5945 , +-2975 , +20109 , +32205 , +11859 , +-3019 , +5835 , +5913 , +6223 , +24585 , +-17239 , +-9989 , +23769 , +20601 , +-23047 , +14925 , +-21919 , +10087 , +17091 , +-1905 , +13707 , +-7217 , +14577 , +13555 , +3895 , +32293 , +21133 , +-10751 , +-22295 , +-6871 , +-22923 , +1447 , +16327 , +-19651 , +-3177 , +9173 , +26135 , +13377 , +-22869 , +1423 , +25389 , +-11283 , +-32157 , +-10095 , +-24087 , +-29539 , +25129 , +-31913 , +-6741 , +28345 , +3925 , +-9787 , +32211 , +-10107 , +-24345 , +32307 , +12207 , +30325 , +23995 , +-14579 , +3833 , +-23539 , +-26297 , +-32543 , +-821 , +17715 , +-32053 , +-6905 , +1311 , +-20465 , +24339 , +-25435 , +21181 , +-16555 , +9379 , +10331 , +-3657 , +-23251 , +-3461 , +-31667 , +6245 , +-27009 , +22855 , +24765 , +11991 , +-6445 , +-4325 , +-14549 , +19665 , +-21341 , +9639 , +-31771 , +26177 , +-31179 , +-9485 , +11295 , +-8649 , +-26891 , +-25449 , +6289 , +-18341 , +21835 , +5487 , +11403 , +8429 , +16627 , +-25129 , +-15987 , +-31947 , +6617 , +26207 , +-28835 , +-6531 , +-20633 , +13579 , +-5977 , +-13945 , +-8085 , +11517 , +9227 , +13453 , +-7329 , +-26433 , +-30279 , +14769 , +28497 , +12011 , +-25201 , +-25609 , +-8913 , +-13971 , +7589 , +-11077 , +-9817 , +1843 , +-29329 , +12209 , +-16519 , +-12177 , +-23215 , +13651 , +12881 , +13639 , +32441 , +7137 , +4641 , +-24819 , +-11087 , +30419 , +24313 , +-13313 , +12545 , +-9005 , +9561 , +-29323 , +23995 , +-17351 , +2833 , +-16227 , +-3231 , +5627 , +-27499 , +31163 , +23409 , +22317 , +-17707 , +-9779 , +8067 , +2293 , +-5739 , +-31011 , +-8995 , +-28927 , +-443 , +16033 , +-19313 , +-21373 , +24415 , +31681 , +-28659 , +1961 , +-15313 , +-23153 , +4669 , +25491 , +-15039 , +-15819 , +-29413 , +-14135 , +-13019 , +9083 , +-11319 , +21559 , +-32299 , +1521 , +16679 , +-7003 , +16001 , +-25937 , +-13579 , +24235 , +-18955 , +29583 , +31069 , +-16595 , +21863 , +-13859 , +6929 , +-19373 , +32717 , +-26731 , +-29207 , +-2819 , +14783 , +-1251 , +29681 , +3771 , +24007 , +-8843 , +-21241 , +-7601 , +-3779 , +21235 , +27889 , +-31081 , +-20067 , +-20865 , +17911 , +-13809 , +29279 , +-16569 , +-9 , +2755 , +25421 , +12533 , +-27647 , +-25397 , +-10397 , +-31125 , +9327 , +30529 , +-23523 , +-22789 , +18807 , +24507 , +-20139 , +30235 , +-30131 , +19519 , +-11875 , +28063 , +23217 , +13245 , +31499 , +-19851 , +29965 , +1293 , +30881 , +-25641 , +-5873 , +-931 , +11291 , +9477 , +-18761 , +3885 , +30795 , +16769 , +19963 , +-22841 , +-5141 , +-29763 , +-13609 , +24893 , +17663 , +18017 , +17893 , +4309 , +-7003 , +10229 , +4479 , +-19957 , +19311 , +-5849 , +15175 , +-28667 , +13883 , +3441 , +10829 , +20361 , +29583 , +-8601 , +-20063 , +6271 , +2409 , +4443 , +28519 , +-27177 , +-15457 , +3999 , +-12165 , +1043 , +-15695 , +22849 , +-28551 , +1589 , +8997 , +-1481 , +3685 , +31033 , +21853 , +-30175 , +19897 , +-495 , +15855 , +-20869 , +-1029 , +29201 , +-18815 , +-26791 , +21217 , +3579 , +-30953 , +28319 , +11995 , +25443 , +28663 , +12725 , +12855 , +-3917 , +23545 , +-4667 , +19631 , +-31841 , +21345 , +-10647 , +32647 , +8731 , +18235 , +12015 , +13863 , +-20005 , +19757 , +32265 , +2857 , +5695 , +25551 , +1035 , +20987 , +-809 , +22409 , +-5221 , +15607 , +4179 , +-8215 , +11505 , +-2065 , +-13827 , +-29325 , +-25719 , +-28843 , +-26191 , +-24567 , +5725 , +-1079 , +-25511 , +23983 , +21153 , +10801 , +-26401 , +501 , +14581 , +22617 , +31655 , +-8765 , +19745 , +-25087 , +2185 , +-16453 , +6217 , +-1415 , +-1211 , +15623 , +3497 , +-16705 , +20095 , +-3403 , +-7733 , +-21493 , +-7879 , +22417 , +-13247 , +-24845 , +12993 , +13951 , +-21541 , +7927 , +27957 , +26951 , +-31395 , +-21849 , +30321 , +-5121 , +21695 , +6189 , +16271 , +-7981 , +-22313 , +-7569 , +2779 , +-25497 , +419 , +-17755 , +-8119 , +21159 , +26863 , +13931 , +-6029 , +31787 , +15773 , +-3487 , +-6647 , +-29697 , +-22191 , +319 , +-31277 , +3595 , +-18259 , +-149 , +-17121 , +-14883 , +-29171 , +-23787 , +-4415 , +-6643 , +-22857 , +8401 , +3715 , +-2037 , +-21861 , +15525 , +31527 , +-29569 , +-16759 , +24493 , +-14635 , +19485 , +-12063 , +-30165 , +9755 , +-32517 , +-10023 , +31265 , +-17059 , +-20371 , +-32729 , +-8597 , +-31531 , +23901 , +12099 , +-4525 , +-1271 , +-29921 , +-3043 , +15793 , +23997 , +6349 , +15185 , +9591 , +-24205 , +-29413 , +-11297 , +-26413 , +-8355 , +27319 , +13677 , +-16701 , +29145 , +-23273 , +-32529 , +10285 , +30569 , +19925 , +13293 , +-1415 , +-3035 , +4747 , +1587 , +-6491 , +18875 , +-23771 , +-5617 , +17633 , +15843 , +-26435 , +-22783 , +11431 , +18265 , +-2835 , +1787 , +-7859 , +22863 , +-11853 , +3601 , +27431 , +-6803 , +22973 , +13499 , +-19179 , +19525 , +-24251 , +7301 , +1699 , +29771 , +30571 , +-18615 , +12955 , +-16561 , +-14327 , +22759 , +21023 , +5745 , +-23021 , +-21633 , +25669 , +17565 , +-27035 , +-471 , +-21977 , +22401 , +13089 , +-6619 , +6021 , +16133 , +-16509 , +-21853 , +-20525 , +25413 , +-15295 , +29417 , +10197 , +26889 , +19543 , +-20713 , +-23621 , +-9035 , +-9623 , +-19617 , +-5707 , +-1075 , +-20839 , +-591 , +-7929 , +21737 , +29913 , +7685 , +-19027 , +30245 , +-3125 , +-18175 , +30819 , +25127 , +-11241 , +-25279 , +-27825 , +903 , +6205 , +25345 , +-5371 , +22233 , +23795 , +-29087 , +1073 , +-31981 , +31229 , +-21485 , +1447 , +-26477 , +-25727 , +24731 , +-4359 , +11921 , +27623 , +-7679 , +-9329 , +-26861 , +26147 , +-11251 , +-21943 , +-7825 , +-5987 , +-259 , +-7797 , +25401 , +8319 , +-10051 , +10201 , +-59 , +25997 , +22687 , +10479 , +-6635 , +7811 , +3479 , +16219 , +-683 , +-14873 , +-4373 , +-17769 , +-18473 , +10085 , +-8333 , +6549 , +-31611 , +28069 , +23369 , +4583 , +-26915 , +6309 , +18443 , +-17587 , +15719 , +29835 , +24459 , +-18483 , +32427 , +-22263 , +11529 , +-20397 , +13487 , +-1755 , +5357 , +-577 , +24299 , +19361 , +24313 , +-10621 , +-7489 , +-27707 , +-17651 , +-10055 , +29297 , +12993 , +14417 , +18619 , +-11617 , +-5757 , +9975 , +-9155 , +13883 , +29451 , +-9105 , +27107 , +-5889 , +24391 , +-11747 , +21851 , +105 , +18021 , +5783 , +4079 , +19253 , +-4937 , +-30377 , +-31321 , +14155 , +28413 , +-9991 , +-12585 , +-6591 , +3911 , +-17431 , +-451 , +10321 , +-17847 , +23465 , +25497 , +-27187 , +-8909 , +27259 , +6851 , +32537 , +-23543 , +-9307 , +16193 , +-5339 , +14461 , +-18911 , +-25501 , +23653 , +6467 , +-1579 , +12765 , +-27579 , +8687 , +3921 , +25813 , +3363 , +23367 , +-17917 , +13703 , +25291 , +11293 , +1265 , +20821 , +24935 , +683 , +8681 , +22881 , +-3331 , +3681 , +-19641 , +13735 , +-23703 , +8781 , +30753 , +-13165 , +-3379 , +22495 , +-11513 , +-2281 , +11919 , +-30125 , +9011 , +2379 , +2257 , +17025 , +26697 , +-14467 , +-22937 , +11055 , +10381 , +8135 , +23371 , +-23049 , +4497 , +-32719 , +-12895 , +-26475 , +19329 , +8515 , +-18655 , +2753 , +-2359 , +7451 , +-741 , +-21371 , +-13231 , +-21751 , +22243 , +-8931 , +22591 , +22439 , +15063 , +19015 , +-14557 , +-28309 , +18891 , +-16359 , +-16975 , +25033 , +-3837 , +16741 , +13057 , +-21823 , +31413 , +135 , +-15041 , +-16129 , +17649 , +20667 , +-32541 , +-17811 , +22313 , +10239 , +-28047 , +18765 , +3613 , +18789 , +-9561 , +31701 , +5723 , +-20503 , +-8901 , +14401 , +27949 , +20939 , +531 , +-12947 , +-24547 , +-11157 , +-24329 , +28653 , +745 , +18587 , +-12333 , +-1109 , +5109 , +-30855 , +27493 , +-11791 , +-14521 , +18379 , +21117 , +11281 , +-4091 , +-31793 , +19377 , +-17809 , +-32669 , +18331 , +-29295 , +-6105 , +-10207 , +32752 , +24937 , +-25833 , +-9857 , +-7791 , +-10125 , +-14209 , +-835 , +-32477 , +2955 , +-18919 , +6665 , +13181 , +-8847 , +16305 , +8701 , +20097 , +-18569 , +-1739 , +31891 , +-7563 , +14527 , +-31395 , +18085 , +991 , +20469 , +-1871 , +9689 , +15831 , +-18561 , +-24275 , +-5339 , +-15133 , +19515 , +2647 , +-17473 , +-32181 , +14003 , +-27183 , +-1895 , +-28683 , +24287 , +-32645 , +-25517 , +15551 , +8779 , +-21501 , +18363 , +12619 , +-15133 , +1277 , +-19259 , +-12951 , +-27621 , +-8829 , +-14345 , +21983 , +13489 , +5185 , +-1935 , +2761 , +4835 , +24601 , +18011 , +-16783 , +27933 , +-26575 , +30685 , +1189 , +-3771 , +20629 , +-11105 , +-28017 , +25695 , +-23739 , +6069 , +-6387 , +19667 , +32211 , +-12253 , +-11381 , +5913 , +19321 , +-6197 , +-681 , +-21249 , +21425 , +-30483 , +-4227 , +-2219 , +-23215 , +6683 , +-10975 , +16937 , +-6631 , +-30545 , +29773 , +-1149 , +-8487 , +-26167 , +-32429 , +-15209 , +7163 , +31169 , +-7519 , +19839 , +31399 , +16929 , +-741 , +-3209 , +-1455 , +-20959 , +-24339 , +-26229 , +-21801 , +-19049 , +-20753 , +-19493 , +3865 , +18039 , +3693 , +-689 , +-13297 , +-11065 , +2959 , +-12345 , +-929 , +-1771 , +-18909 , +-26915 , +123 , +-10893 , +22785 , +21787 , +9009 , +30959 , +-24101 , +-19537 , +-5425 , +-1655 , +-28267 , +-27481 , +28331 , +31911 , +-13019 , +-24665 , +-30391 , +-6631 , +26337 , +-16095 , +16107 , +25989 , +-18339 , +5135 , +12461 , +-26013 , +25795 , +11815 , +29721 , +-31111 , +7079 , +18071 , +-22713 , +1737 , +13411 , +12093 , +-26263 , +2841 , +-17939 , +-26531 , +24557 , +17367 , +-209 , +-26923 , +12305 , +32421 , +21473 , +-6947 , +-11011 , +26945 , +-3619 , +-10945 , +6741 , +-3321 , +-17667 , +28933 , +857 , +1251 , +-8339 , +-18499 , +9849 , +-14387 , +1159 , +31269 , +1391 , +12735 , +1063 , +-14477 , +-17967 , +4397 , +-9081 , +25849 , +-12749 , +20225 , +-5993 , +18541 , +-25673 , +-24821 , +-1839 , +-29537 , +1061 , +22271 , +25749 , +-10075 , +-8057 , +-23573 , +-21505 , +-20061 , +-955 , +-10701 , +-15809 , +-20745 , +-2897 , +-1025 , +-26509 , +2295 , +-10973 , +-32191 , +253 , +31271 , +-14437 , +5151 , +-31911 , +-5389 , +-20015 , +28917 , +14461 , +-8219 , +5833 , +28873 , +18341 , +8795 , +5359 , +-4285 , +7093 , +-25659 , +-10059 , +-10971 , +-5873 , +-9385 , +23455 , +-1979 , +-25627 , +15941 , +-14359 , +2563 , +-14565 , +12921 , +22673 , +19521 , +-21611 , +-29747 , +3575 , +17627 , +-4077 , +25533 , +3829 , +10145 , +8591 , +31655 , +3703 , +11981 , +-27635 , +-26239 , +-29299 , +-26117 , +-17425 , +-10483 , +21001 , +-29791 , +-26657 , +23441 , +-5735 , +32009 , +17171 , +30745 , +-28327 , +-32571 , +18479 , +-25057 , +23017 , +2991 , +-13155 , +10451 , +-8173 , +31827 , +11367 , +28869 , +29137 , +6391 , +7809 , +8743 , +-2061 , +-17399 , +-1607 , +19843 , +31789 , +-6375 , +12789 , +10989 , +-23623 , +29777 , +-23009 , +1987 , +-2461 , +-24979 , +-10635 , +22241 , +18989 , +-26825 , +-25761 , +23383 , +11103 , +25721 , +29897 , +26025 , +-26335 , +15223 , +2561 , +7035 , +-4459 , +4839 , +-3583 , +-15917 , +20587 , +-23699 , +23641 , +463 , +30465 , +-29043 , +-19853 , +8149 , +11505 , +-7133 , +-13951 , +7515 , +23083 , +-16795 , +-17217 , +-17139 , +-3177 , +11337 , +2139 , +-7789 , +-22755 , +8849 , +-823 , +16065 , +-25521 , +-21705 , +8851 , +-10927 , +8557 , +2913 , +-22847 , +12573 , +-25327 , +6121 , +26525 , +-7723 , +-25543 , +28743 , +-17891 , +9783 , +21729 , +-10229 , +32689 , +16841 , +29987 , +26333 , +-23395 , +29967 , +-26939 , +-14613 , +-24877 , +4161 , +12121 , +14825 , +1353 , +-26487 , +21709 , +-25471 , +-10289 , +30645 , +11919 , +8277 , +-28819 , +11889 , +27413 , +-2963 , +-28875 , +-32507 , +-28157 , +-27595 , +3489 , +-27007 , +-30021 , +-2827 , +3681 , +-32129 , +12153 , +18887 , +-31549 , +12629 , +17641 , +-27123 , +13943 , +11985 , +-20929 , +-14739 , +30459 , +16241 , +13775 , +-30649 , +21345 , +17431 , +-15833 , +-26703 , +18103 , +24645 , +20389 , +-17433 , +3793 , +-9519 , +-31087 , +10827 , +-18003 , +-20187 , +17839 , +-30763 , +-31933 , +21739 , +-1697 , +16659 , +-25633 , +-29617 , +5937 , +28829 , +28409 , +-4941 , +-27137 , +3085 , +-32113 , +-6167 , +-17791 , +-28807 , +-30979 , +-7193 , +4199 , +-8345 , +-20657 , +21763 , +-6157 , +-26293 , +-5597 , +21159 , +12305 , +-30091 , +4853 , +-24945 , +1259 , +-31337 , +-19451 , +-27011 , +-13565 , +20143 , +28831 , +2157 , +11983 , +-10867 , +-20475 , +24921 , +-7989 , +30397 , +-24395 , +11875 , +26131 , +31495 , +11343 , +26775 , +-10883 , +-29335 , +-3099 , +-31969 , +-9939 , +24453 , +-4905 , +-19463 , +-13131 , +13477 , +-18905 , +28467 , +20383 , +-29909 , +15957 , +-29531 , +9367 , +-25457 , +-11849 , +4129 , +-19213 , +-5171 , +10575 , +3121 , +4307 , +-26007 , +-28129 , +-26801 , +-15433 , +-17439 , +-15093 , +19349 , +21915 , +24481 , +-30933 , +18695 , +-12155 , +-30329 , +-21857 , +12851 , +8875 , +-12085 , +-30733 , +7041 , +-19201 , +-8827 , +-30745 , +-6955 , +3659 , +31903 , +-10795 , +-2597 , +-9525 , +-32179 , +-11645 , +-11091 , +12357 , +13061 , +24441 , +-28903 , +26269 , +27381 , +-25889 , +28243 , +23791 , +15365 , +9165 , +-4821 , +-31957 , +14911 , +32557 , +26825 , +-32731 , +11989 , +-19191 , +-31771 , +-13257 , +27025 , +-16791 , +-19333 , +6221 , +26833 , +-9303 , +-3065 , +-9847 , +4093 , +27477 , +2617 , +-11949 , +9341 , +22903 , +27189 , +-5645 , +18743 , +-16517 , +6719 , +16299 , +12419 , +-13185 , +-25091 , +-20915 , +15521 , +-29137 , +23339 , +-17581 , +18103 , +-19943 , +28883 , +13431 , +-15293 , +-10357 , +30985 , +23247 , +789 , +-30237 , +11545 , +-3493 , +-19509 , +31601 , +25675 , +3627 , +31427 , +6341 , +25873 , +-3863 , +-16493 , +3215 , +201 , +-9731 , +29449 , +-13331 , +29163 , +5915 , +921 , +-15533 , +29895 , +12899 , +14429 , +15315 , +-27973 , +-27407 , +10887 , +-28419 , +6125 , +30207 , +5467 , +-12493 , +-21633 , +28275 , +13481 , +21131 , +589 , +-30465 , +27077 , +32279 , +-23523 , +9907 , +-8453 , +9163 , +15201 , +-28649 , +24969 , +-19253 , +26469 , +-30009 , +-21991 , +-11699 , +-30451 , +-13435 , +19385 , +22247 , +-32247 , +-25389 , +-32433 , +28783 , +-8553 , +-28145 , +-28271 , +-7605 , +25001 , +-24833 , +391 , +2129 , +27571 , +27645 , +19831 , +-19941 , +13259 , +15995 , +24671 , +28383 , +19321 , +20009 , +-32269 , +25031 , +25821 , +-8575 , +-3311 , +14027 , +-11411 , +-2835 , +-3909 , +20485 , +-16591 , +849 , +21897 , +-15471 , +-32137 , +24365 , +-28245 , +16855 , +10761 , +-8911 , +12629 , +31857 , +-28693 , +26967 , +-22075 , +9599 , +2185 , +-3209 , +-23379 , +8059 , +6783 , +-30623 , +-32201 , +-2671 , +14527 , +-4233 , +18801 , +13437 , +-2217 , +-23355 , +-16557 , +-17441 , +-19807 , +-30827 , +-9175 , +-24557 , +8447 , +5515 , +22421 , +-19319 , +-14579 , +-30151 , +-31997 , +22175 , +-14747 , +-17603 , +10913 , +-28425 , +-311 , +2259 , +-19239 , +12111 , +-1565 , +15089 , +14403 , +-9513 , +-26239 , +-23845 , +-16343 , +-10479 , +61 , +22851 , +30575 , +30497 , +-21301 , +-3885 , +-3557 , +-7259 , +16285 , +30039 , +19777 , +18705 , +-7385 , +3909 , +23935 , +1673 , +-12655 , +9181 , +-23557 , +-2767 , +-9481 , +18879 , +16847 , +24587 , +-23785 , +-5625 , +-24053 , +-15283 , +9613 , +-6693 , +4647 , +-3525 , +24975 , +6289 , +259 , +-22915 , +-6627 , +3643 , +7249 , +13303 , +-13375 , +-14653 , +1183 , +22049 , +4291 , +-8825 , +-12355 , +-15393 , +-12319 , +-4759 , +4547 , +-25891 , +18823 , +-30355 , +-23423 , +15199 , +14217 , +-24107 , +-6789 , +-21343 , +25431 , +-21079 , +-23971 , +8617 , +-2375 , +28901 , +27643 , +-18779 , +32519 , +-18691 , +-30789 , +-327 , +6877 , +-9729 , +14237 , +31333 , +-13739 , +28205 , +-28503 , +-29103 , +22981 , +-5617 , +-26649 , +4779 , +-8471 , +-23795 , +-8737 , +4861 , +16553 , +-2423 , +20613 , +-10621 , +-16051 , +-2187 , +31675 , +-14067 , +815 , +30827 , +-4023 , +23621 , +32764 , +-13755 , +2377 , +31133 , +-5537 , +1849 , +-14289 , +-25455 , +29261 , +17001 , +-203 , +11663 , +25513 , +29697 , +-32165 , +13643 , +6025 , +31181 , +-26921 , +145 , +-20503 , +1109 , +22809 , +-13149 , +-27167 , +-14227 , +20785 , +5139 , +12895 , +-12971 , +-4645 , +-27631 , +-9883 , +12105 , +7657 , +-23985 , +24503 , +11939 , +-16319 , +-5295 , +21271 , +-7319 , +8785 , +12619 , +19713 , +28013 , +17675 , +9069 , +22491 , +-1825 , +8285 , +-6707 , +-8521 , +28519 , +-25307 , +25009 , +8063 , +11715 , +32175 , +-2451 , +-26693 , +-27183 , +-4955 , +-23881 , +25529 , +-10955 , +-5489 , +16003 , +2135 , +-18325 , +20933 , +-8871 , +-24793 , +-7585 , +-22293 , +-3791 , +-8901 , +16517 , +31721 , +17857 , +-5041 , +4977 , +29533 , +27747 , +-29053 , +25585 , +-7523 , +-20385 , +-31587 , +15525 , +1059 , +11211 , +-20815 , +-32754 , +-25453 , +5349 , +-8345 , +-19655 , +15399 , +-9243 , +-9811 , +-27453 , +-10581 , +12631 , +28907 , +-10119 , +-5641 , +-29453 , +17353 , +-8329 , +-5403 , +19705 , +2385 , +-15179 , +12489 , +1535 , +-5953 , +-27101 , +5997 , +7001 , +-11355 , +4677 , +-28799 , +14303 , +23217 , +-15805 , +-10855 , +-16561 , +-2851 , +-14199 , +-30813 , +-12247 , +12585 , +15321 , +-12063 , +-4613 , +-13611 , +26345 , +-7071 , +-5055 , +6167 , +-15243 , +32237 , +12737 , +-13483 , +4057 , +-24175 , +-5035 , +32473 , +16939 , +20871 , +19793 , +779 , +-11311 , +29365 , +26197 , +-6357 , +6807 , +-26717 , +-16733 , +13451 , +7247 , +-5645 , +14587 , +-11205 , +-21025 , +-5541 , +25077 , +-26797 , +14047 , +16155 , +-16691 , +22937 , +-3665 , +18677 , +13515 , +14025 , +15 , +-18779 , +8467 , +19009 , +11323 , +-12581 , +14585 , +-3779 , +-20869 , +-22351 , +-13601 , +1937 , +-12479 , +2721 , +30609 , +5857 , +-16959 , +10245 , +-1009 , +-4011 , +29445 , +-2811 , +9203 , +-22315 , +-1655 , +18709 , +31811 , +28607 , +-3757 , +-30743 , +-8503 , +14367 , +-22393 , +2291 , +28137 , +-21401 , +-24447 , +-2729 , +6397 , +25771 , +-10383 , +-11165 , +16687 , +-10415 , +-20883 , +32391 , +-26935 , +-943 , +-15351 , +-20787 , +-14573 , +6885 , +-25735 , +-5423 , +4777 , +-17971 , +26649 , +-1731 , +25687 , +10743 , +-10861 , +-24901 , +103 , +-23611 , +9327 , +-9873 , +25733 , +28349 , +29487 , +21231 , +28689 , +3015 , +-29723 , +16575 , +27891 , +-9765 , +3659 , +27457 , +4347 , +11593 , +20061 , +-27849 , +4023 , +20829 , +-16533 , +-4689 , +21701 , +27815 , +17341 , +-4473 , +32439 , +-16463 , +14493 , +6491 , +-19879 , +13867 , +-26887 , +4357 , +24219 , +-15695 , +117 , +-25201 , +2273 , +31999 , +4359 , +-8015 , +-17959 , +-1375 , +-13043 , +28867 , +8919 , +-9671 , +-31767 , +-28107 , +5035 , +-1751 , +-241 , +18319 , +22777 , +19415 , +21927 , +28639 , +-25839 , +-12195 , +15523 , +-21577 , +21835 , +-27711 , +11091 , +16551 , +32217 , +16821 , +11393 , +-19671 , +-2527 , +14019 , +-19451 , +20267 , +23445 , +-29423 , +20707 , +22265 , +20749 , +7059 , +-27683 , +4279 , +-10081 , +-8257 , +655 , +27231 , +-10767 , +-13875 , +28421 , +27703 , +20761 , +25453 , +-29741 , +12739 , +-28175 , +18681 , +5295 , +-24253 , +-21521 , +-4811 , +25475 , +-26195 , +-28033 , +-24699 , +-13807 , +-12515 , +19925 , +19611 , +-30725 , +3541 , +26701 , +-3645 , +-19093 , +7085 , +11331 , +14985 , +-1503 , +-4077 , +-13729 , +16631 , +26889 , +31359 , +125 , +-6065 , +22623 , +-20629 , +22777 , +-13759 , +-29125 , +5069 , +-25971 , +11941 , +-26195 , +32523 , +-32599 , +1457 , +-20391 , +19319 , +21575 , +23729 , +-6009 , +-21179 , +32073 , +17727 , +10179 , +26629 , +-23481 , +-22789 , +-25103 , +-25961 , +31987 , +-3131 , +9443 , +-9819 , +-12051 , +13939 , +23671 , +20641 , +-7405 , +29705 , +-9431 , +8497 , +-15517 , +-10379 , +19247 , +-18125 , +-21677 , +-24643 , +-13297 , +22313 , +-1377 , +18625 , +28853 , +30013 , +-4947 , +-6543 , +12819 , +21169 , +-24997 , +10883 , +11823 , +21469 , +31839 , +3239 , +-29759 , +28829 , +-19943 , +-29365 , +-9655 , +26965 , +-20241 , +-30013 , +18089 , +-1437 , +26659 , +8465 , +31799 , +-14829 , +17707 , +-29677 , +-30111 , +11553 , +-27509 , +1083 , +-22857 , +-12887 , +23339 , +-29235 , +9101 , +-8031 , +16431 , +12945 , +29453 , +11733 , +-24753 , +-25073 , +-28971 , +-12717 , +23473 , +-27581 , +-25593 , +30071 , +-29893 , +15069 , +9193 , +30799 , +-28039 , +-21267 , +-18185 , +19357 , +-14111 , +-11993 , +24705 , +-20399 , +15803 , +-5487 , +-26435 , +18043 , +-19083 , +-9279 , +21343 , +-16699 , +30581 , +-27497 , +-17221 , +25197 , +1143 , +-23957 , +10061 , +10681 , +19813 , +23249 , +-3105 , +6389 , +-32083 , +-26425 , +-12775 , +7141 , +5143 , +-31623 , +5533 , +6081 , +-1755 , +23911 , +-13409 , +27561 , +-9761 , +-16591 , +-8971 , +-26717 , +12343 , +22719 , +8379 , +16909 , +-1575 , +-29181 , +-7321 , +21401 , +4739 , +-981 , +22107 , +25023 , +-12571 , +22623 , +-17405 , +8131 , +-4113 , +-24333 , +-22421 , +3609 , +-31057 , +6433 , +11867 , +8303 , +-8025 , +1861 , +20713 , +-28135 , +5289 , +-21109 , +-28273 , +-24303 , +18469 , +30005 , +-3375 , +26473 , +17677 , +-15291 , +18243 , +-29883 , +30759 , +30145 , +9517 , +-683 , +-4127 , +27745 , +22177 , +32205 , +29619 , +14287 , +7695 , +8153 , +19437 , +17497 , +10081 , +-31849 , +-11753 , +-29395 , +32143 , +-367 , +25029 , +18703 , +23741 , +27317 , +-15891 , +-30317 , +14543 , +-11321 , +-24893 , +17613 , +-12163 , +-17565 , +11279 , +-15973 , +-23307 , +11115 , +-30711 , +-8635 , +-21013 , +20229 , +-2391 , +10699 , +-24013 , +-13805 , +-29307 , +18321 , +-21283 , +-30937 , +26661 , +-27243 , +-6461 , +13311 , +-795 , +-29393 , +27823 , +9341 , +-21955 , +-10679 , +27109 , +-11239 , +5287 , +-31475 , +-4281 , +-16925 , +27887 , +31273 , +-4383 , +-15633 , +14095 , +23933 , +13329 , +-10405 , +-22143 , +11097 , +-20471 , +11705 , +15651 , +-13259 , +-3327 , +-26351 , +-31357 , +-20761 , +10677 , +23895 , +-5703 , +-8871 , +30611 , +9819 , +21961 , +-31799 , +1349 , +23887 , +31853 , +25205 , +-25649 , +-27469 , +-16011 , +8667 , +9253 , +17107 , +25759 , +373 , +-7359 , +-32067 , +1259 , +-10009 , +-13631 , +5051 , +5243 , +-7239 , +-18949 , +20293 , +21725 , +20375 , +-5229 , +19845 , +-3085 , +1279 , +-17509 , +-4033 , +24895 , +-23935 , +-28129 , +3161 , +29635 , +8817 , +22087 , +27079 , +-1967 , +8995 , +28139 , +-11769 , +16491 , +18851 , +15787 , +-6881 , +-13927 , +-18715 , +32137 , +-4855 , +-27335 , +1931 , +14843 , +26547 , +18661 , +-10733 , +-9841 , +32635 , +-20673 , +14223 , +-265 , +10777 , +-20145 , +10977 , +-24671 , +9767 , +24663 , +29301 , +9951 , +-28917 , +10291 , +-12175 , +-665 , +16251 , +-15835 , +7537 , +19841 , +-17811 , +55 , +12741 , +23441 , +-11631 , +2321 , +6429 , +19253 , +-14261 , +7245 , +-30517 , +-22311 , +5671 , +30545 , +4217 , +-28717 , +-23591 , +29353 , +-677 , +-15107 , +-26713 , +28637 , +26607 , +-25147 , +32369 , +-20533 , +25649 , +3017 , +543 , +-22151 , +-13229 , +-23309 , +-6503 , +-1671 , +-25101 , +11 , +-31419 , +-32335 , +25051 , +15829 , +32507 , +-11839 , +-27087 , +5791 , +-9091 , +28629 , +-27859 , +17509 , +21869 , +6653 , +-7587 , +-24221 , +-2613 , +-26621 , +-32687 , +-11479 , +-9751 , +13769 , +215 , +-9665 , +14561 , +32283 , +3511 , +24111 , +30099 , +19979 , +14307 , +3623 , +28183 , +-10039 , +-27845 , +-4597 , +-15945 , +-19467 , +5299 , +-6127 , +17769 , +-31617 , +11037 , +31449 , +24263 , +25595 , +-30121 , +-9215 , +32131 , +-27015 , +-24313 , +26431 , +27491 , +-22307 , +-20271 , +-19973 , +-21837 , +-28743 , +269 , +7015 , +-25781 , +-8543 , +9221 , +12563 , +-25101 , +-20471 , +-14681 , +-16375 , +-4501 , +21911 , +705 , +-5533 , +27613 , +26877 , +-21577 , +6497 , +2007 , +21843 , +-29253 , +9223 , +5055 , +-3857 , +6021 , +-32207 , +9421 , +16311 , +26255 , +-7123 , +-14715 , +-2559 , +11719 , +1739 , +-19537 , +-11287 , +28359 , +7169 , +-12855 , +28961 , +32147 , +-24577 , +-29943 , +-28331 , +18125 , +-3393 , +4809 , +-26369 , +20587 , +-29141 , +-16243 , +15029 , +27895 , +12455 , +17775 , +-2795 , +-26309 , +-11211 , +8219 , +30983 , +-893 , +-13821 , +-23737 , +-28505 , +-31917 , +-11639 , +17073 , +-24943 , +3225 , +-30177 , +24205 , +19905 , +-24211 , +539 , +17793 , +-30237 , +-20669 , +-8615 , +-23267 , +22579 , +-17237 , +-12439 , +8409 , +-22317 , +-28549 , +-16111 , +18305 , +-18277 , +17303 , +-27273 , +-24775 , +7039 , +13595 , +-15187 , +-23 , +1881 , +22817 , +-18223 , +-3007 , +-2227 , +-9749 , +16031 , +22827 , +16281 , +-31835 , +-7539 , +-3135 , +-22033 , +-3431 , +-28063 , +13769 , +-19891 , +-1051 , +23369 , +-5973 , +31833 , +18615 , +-25485 , +-2327 , +6449 , +-25591 , +-31193 , +3097 , +13771 , +-17719 , +15709 , +17243 , +-13881 , +28323 , +31701 , +-25521 , +-8501 , +-25809 , +1201 , +28309 , +2137 , +-8787 , +-14967 , +-27717 , +-23511 , +-20679 , +-1017 , +32699 , +31483 , +-32375 , +14333 , +-15 , +-9735 , +-12771 , +-28161 , +-10093 , +-17273 , +-28671 , +-4489 , +-1879 , +7837 , +8185 , +-23229 , +31883 , +4001 , +-5305 , +26053 , +14027 , +-25157 , +-813 , +-20605 , +-2117 , +12723 , +-12045 , +-18629 , +19297 , +29505 , +27543 , +4217 , +-6683 , +19949 , +10503 , +-3149 , +30365 , +11877 , +16669 , +30947 , +6513 , +4175 , +29937 , +-24937 , +7901 , +29863 , +-8417 , +30093 , +25195 , +-10089 , +24189 , +18639 , +-6235 , +-15155 , +-27833 , +6727 , +-2675 , +3411 , +-6425 , +19411 , +26783 , +23015 , +-27103 , +-13081 , +29495 , +-28973 , +13777 , +-23395 , +-31585 , +11849 , +-21981 , +12369 , +-29071 , +18997 , +2117 , +-4427 , +24737 , +7829 , +23211 , +12141 , +21483 , +-5031 , +-16459 , +32549 , +-1333 , +11441 , +-9475 , +10283 , +4347 , +-19221 , +4347 , +-24701 , +24933 , +-7477 , +-31415 , +13955 , +-9567 , +26975 , +21335 , +-5909 , +-30233 , +-10663 , +-1629 , +-24711 , +-19321 , +26603 , +28531 , +-16637 , +-14359 , +19227 , +-8951 , +23569 , +22523 , +-9577 , +28257 , +-5387 , +-7121 , +-2537 , +14435 , +-15265 , +-25869 , +2605 , +-22371 , +22137 , +-11353 , +-8035 , +30587 , +23165 , +30483 , +-11971 , +-27387 , +-6453 , +3683 , +27459 , +2059 , +-19063 , +-20321 , +12067 , +14309 , +30639 , +-31071 , +28903 , +-26451 , +-29525 , +7561 , +-1277 , +12783 , +-2447 , +16321 , +-30289 , +-2071 , +-7657 , +-29591 , +-18747 , +28477 , +-25369 , +-31407 , +28173 , +-27861 , +19971 , +19323 , +-32225 , +30287 , +19567 , +-15865 , +31157 , +-27189 , +27057 , +20395 , +11657 , +22287 , +2283 , +-2373 , +20135 , +-22523 , +23147 , +-1143 , +27977 , +14801 , +-27703 , +-11919 , +-26581 , +19969 , +31871 , +-31159 , +11367 , +-29109 , +9981 , +25687 , +-4661 , +-6455 , +11847 , +717 , +-75 , +-9565 , +20485 , +31935 , +-10653 , +19285 , +-17629 , +1691 , +-18223 , +10847 , +-5403 , +-26075 , +-5361 , +3459 , +26239 , +-3865 , +6427 , +7541 , +15659 , +-31441 , +6711 , +22297 , +-26937 , +-11899 , +-23361 , +-26823 , +12521 , +-31067 , +2697 , +26819 , +8311 , +-4107 , +-27215 , +3441 , +-20545 , +15997 , +-25093 , +-18153 , +-20209 , +-3489 , +-4439 , +30535 , +7631 , +6867 , +-27443 , +-19563 , +23063 , +-23403 , +-20949 , +-9141 , +-2873 , +28393 , +20613 , +6049 , +15393 , +24331 , +8577 , +-31883 , +32477 , +10797 , +-18701 , +-2167 , +20933 , +3557 , +22463 , +-15829 , +-20021 , +12081 , +13613 , +22401 , +23203 , +-10265 , +-19265 , +27445 , +10713 , +19121 , +-7535 , +27819 , +-6555 , +25987 , +-23515 , +-8765 , +17617 , +-13679 , +-15417 , +31753 , +32701 , +-14385 , +27739 , +-19343 , +23815 , +-19235 , +11709 , +22923 , +-2209 , +-117 , +8595 , +5183 , +9307 , +-24887 , +18601 , +-30971 , +-12527 , +9249 , +-18233 , +-25703 , +7985 , +9137 , +-19701 , +-3273 , +-15207 , +10911 , +15037 , +-3761 , +16243 , +-1001 , +17577 , +22723 , +31945 , +19645 , +5885 , +-3173 , +-24679 , +-19287 , +-3693 , +15675 , +20087 , +4059 , +-26919 , +-30945 , +23967 , +1337 , +-13025 , +-28655 , +11655 , +-5119 , +28783 , +1507 , +-27129 , +-14397 , +11499 , +-5723 , +-18975 , +-27939 , +31135 , +20061 , +32483 , +-28821 , +-5153 , +27197 , +22133 , +-10553 , +31511 , +29283 , +-23869 , +-8323 , +-13015 , +14599 , +-25539 , +12737 , +9029 , +1591 , +15301 , +621 , +-193 , +-23787 , +-25289 , +-5005 , +6503 , +3973 , +-20849 , +-32553 , +-16671 , +-9623 , +-31889 , +-6871 , +12415 , +-27555 , +9547 , +14461 , +6677 , +21737 , +14325 , +-2339 , +-17833 , +-13767 , +19123 , +4939 , +-11477 , +-13473 , +11743 , +49 , +-1403 , +-6917 , +9469 , +24151 , +25529 , +-10109 , +19793 , +-30105 , +-18081 , +-31251 , +4339 , +-16165 , +8093 , +14323 , +-397 , +4213 , +-2293 , +-13631 , +-8991 , +-11461 , +30719 , +-23245 , +21619 , +-6673 , +-16783 , +-881 , +921 , +22019 , +24141 , +23219 , +22671 , +-16875 , +6215 , +-8485 , +1915 , +2279 , +-14531 , +12489 , +29955 , +-11567 , +7687 , +-24947 , +-4759 , +8641 , +19921 , +23729 , +27 , +-21583 , +11507 , +24823 , +-10287 , +25497 , +-2485 , +-12399 , +-6363 , +-31507 , +14613 , +29395 , +-15961 , +-10859 , +4413 , +13685 , +31099 , +22115 , +16447 , +5955 , +22889 , +6669 , +15997 , +-27561 , +21375 , +31391 , +-8945 , +-2351 , +-995 , +25979 , +-28631 , +-29933 , +27031 , +-2611 , +-1563 , +11887 , +-12213 , +5507 , +-12887 , +12397 , +13111 , +23749 , +-23569 , +-395 , +269 , +-6159 , +-10581 , +-28139 , +-2603 , +23561 , +-485 , +6567 , +6397 , +-11849 , +9765 , +-11361 , +12275 , +-8513 , +21543 , +-27603 , +32063 , +30197 , +30039 , +-4727 , +9241 , +-10825 , +19861 , +29339 , +2177 , +15595 , +32457 , +3131 , +-31783 , +-24983 , +16561 , +-10009 , +-14855 , +2821 , +-7865 , +-28929 , +15051 , +2549 , +-23157 , +-9865 , +-13213 , +-26663 , +8935 , +-22769 , +22929 , +1059 , +-22271 , +-7151 , +14593 , +25887 , +-11251 , +-27003 , +8401 , +-9631 , +-8271 , +-11031 , +19107 , +21951 , +-11685 , +-28823 , +11325 , +8905 , +6411 , +-23657 , +-25443 , +-6973 , +-21567 , +12967 , +-17009 , +17179 , +21055 , +-19937 , +-32309 , +-929 , +8565 , +-20713 , +10119 , +-26693 , +-14007 , +-17431 , +32659 , +27885 , +-13577 , +-32651 , +22765 , +15037 , +12265 , +25801 , +-5921 , +1011 , +-9969 , +-12697 , +-30829 , +27349 , +-339 , +26613 , +-26329 , +17179 , +-1847 , +27515 , +-1199 , +-28057 , +-6169 , +26387 , +-12441 , +-18629 , +22139 , +29735 , +-1785 , +-4489 , +27313 , +22825 , +10531 , +-4277 , +-16183 , +-29239 , +-12897 , +-10827 , +-31249 , +-26197 , +-17049 , +4979 , +-5227 , +-14937 , +-1783 , +-24707 , +-29879 , +-26765 , +22473 , +7165 , +-11505 , +4077 , +31039 , +10953 , +4659 , +9153 , +-11417 , +-22437 , +16045 , +26289 , +13631 , +1349 , +2795 , +24897 , +-27165 , +30253 , +25647 , +-30477 , +-30699 , +12863 , +-3729 , +21249 , +10859 , +30769 , +-21859 , +22935 , +-5167 , +-28241 , +8331 , +2943 , +-845 , +-29353 , +-29373 , +-8599 , +-15223 , +-6347 , +17621 , +31643 , +13305 , +-10317 , +-24903 , +-8413 , +19297 , +-32487 , +-4189 , +-7779 , +-20991 , +-19585 , +-21539 , +9313 , +-26239 , +32585 , +18971 , +-10183 , +6679 , +19997 , +-297 , +22183 , +-11495 , +-17827 , +-6105 , +1417 , +13331 , +-8931 , +-15851 , +32099 , +29283 , +19097 , +-17543 , +27151 , +8013 , +29999 , +-31923 , +7663 , +-19811 , +-20769 , +9869 , +20401 , +-7761 , +-32463 , +-10623 , +-1405 , +6931 , +-27711 , +12195 , +-10043 , +-351 , +-9945 , +6387 , +28999 , +10771 , +14969 , +-11319 , +12035 , +12825 , +31035 , +21557 , +31563 , +8183 , +32740 , +31185 , +21133 , +19351 , +-10045 , +16669 , +19329 , +-5599 , +-31863 , +-31403 , +-30485 , +10523 , +-7881 , +27339 , +-29239 , +11769 , +-4455 , +2489 , +27667 , +-11723 , +-31425 , +29089 , +17897 , +29677 , +-9491 , +-25307 , +-26277 , +-19719 , +-2141 , +28245 , +20111 , +29307 , +23045 , +19343 , +133 , +-2301 , +-32165 , +29911 , +30797 , +31007 , +-25593 , +-22097 , +-11587 , +1143 , +-641 , +14185 , +18597 , +-1181 , +-18751 , +2057 , +4499 , +5893 , +-6573 , +-13933 , +22779 , +15321 , +3247 , +-14871 , +-16895 , +-1315 , +5701 , +-31967 , +21919 , +5915 , +21487 , +-15265 , +-22679 , +-6207 , +6631 , +811 , +-25405 , +-4411 , +15687 , +-1719 , +-9579 , +31731 , +10231 , +21263 , +32135 , +-19325 , +-17623 , +8775 , +-20299 , +-10433 , +-18347 , +10613 , +5871 , +5383 , +-5971 , +-26685 , +32357 , +-10757 , +-17647 , +19787 , +-10517 , +-15609 , +-28527 , +16373 , +-7513 , +27651 , +28507 , +6345 , +-26289 , +-7611 , +21565 , +-24111 , +-18973 , +8125 , +-9583 , +7275 , +26331 , +-28023 , +29377 , +6175 , +-26389 , +-23277 , +-8395 , +-7685 , +-11213 , +-25947 , +12245 , +9319 , +9209 , +-26497 , +-3083 , +-12411 , +229 , +13169 , +-9511 , +-7683 , +-19025 , +23031 , +31395 , +10849 , +13925 , +-3379 , +30165 , +-26373 , +-7657 , +2053 , +-18627 , +14893 , +10005 , +-10589 , +-905 , +28997 , +-32349 , +-25931 , +26339 , +-29743 , +-13001 , +28645 , +19225 , +17795 , +24619 , +7833 , +-2331 , +21627 , +-5637 , +11657 , +-23111 , +-27093 , +-29709 , +4049 , +23475 , +-2909 , +9333 , +-14449 , +-8447 , +-25483 , +17571 , +-11009 , +-30741 , +-25851 , +-14173 , +-13821 , +7999 , +32101 , +-30131 , +23121 , +-31921 , +1963 , +9835 , +16373 , +19305 , +-25401 , +19565 , +-13189 , +8653 , +28385 , +-28515 , +32381 , +3107 , +4141 , +14561 , +29627 , +23159 , +31807 , +-1045 , +4027 , +29873 , +12783 , +10997 , +-20779 , +16009 , +30117 , +15861 , +-16935 , +18949 , +21555 , +14939 , +3607 , +-28569 , +32311 , +-5055 , +-16889 , +-5707 , +-27677 , +27179 , +-29099 , +-1377 , +-1691 , +-9413 , +-1155 , +-12029 , +-13391 , +-2071 , +-3095 , +-6431 , +3557 , +15675 , +-32129 , +-15405 , +-22759 , +19071 , +17853 , +-2807 , +18617 , +24957 , +2899 , +-27719 , +-10915 , +-32453 , +26681 , +4639 , +24611 , +4903 , +-23223 , +-30997 , +23687 , +-23847 , +-10155 , +12105 , +5815 , +-26553 , +-32323 , +24393 , +3179 , +27773 , +-31093 , +-26401 , +15943 , +20691 , +-8435 , +347 , +4515 , +-16211 , +-11805 , +-4771 , +-9485 , +-2647 , +5025 , +-17585 , +-22381 , +-18851 , +-23833 , +-19357 , +26147 , +30607 , +-18195 , +11263 , +-3997 , +18407 , +-22869 , +-27201 , +12677 , +32305 , +-2457 , +-13847 , +-8695 , +-24053 , +-22065 , +12389 , +-5615 , +-30939 , +-4973 , +2613 , +20285 , +4851 , +4983 , +-28303 , +15107 , +-23317 , +16373 , +10165 , +15749 , +-26317 , +-32689 , +19237 , +-28443 , +-8731 , +-15325 , +-30243 , +4393 , +4803 , +32139 , +11245 , +-893 , +11109 , +18097 , +-13361 , +5179 , +3075 , +25575 , +-27297 , +13813 , +6303 , +31299 , +25427 , +1433 , +11969 , +21163 , +29493 , +-16485 , +431 , +383 , +-6183 , +-13341 , +20779 , +19105 , +-11693 , +10521 , +-3427 , +-26087 , +-1673 , +18565 , +9437 , +26911 , +6085 , +29279 , +9815 , +26567 , +-14353 , +19121 , +-31273 , +17155 , +-10305 , +-29019 , +9649 , +24395 , +14757 , +-23965 , +27011 , +24495 , +19613 , +1895 , +-31127 , +-11923 , +-19795 , +21341 , +28085 , +-11247 , +28129 , +-16529 , +18983 , +5631 , +31677 , +-6103 , +1957 , +-611 , +-22729 , +-10807 , +-8843 , +22233 , +-14027 , +-6885 , +21237 , +23889 , +12149 , +-22323 , +-18741 , +31453 , +25115 , +23373 , +-32595 , +-27983 , +-107 , +-1765 , +-27255 , +12529 , +-6367 , +-25693 , +-6589 , +30409 , +27067 , +11415 , +24815 , +6919 , +-18017 , +2503 , +-21365 , +22321 , +20531 , +-20111 , +-22735 , +6425 , +-32111 , +3881 , +7885 , +20737 , +-911 , +-32479 , +-17313 , +-19417 , +22949 , +11785 , +-26195 , +-13341 , +-27119 , +-15515 , +31099 , +-22215 , +-29659 , +13413 , +6721 , +5375 , +14805 , +-28351 , +-25751 , +-27551 , +1035 , +-28917 , +27905 , +6667 , +-20311 , +-10231 , +-15881 , +-17481 , +20215 , +-17267 , +-817 , +17477 , +-14685 , +23631 , +3803 , +-1445 , +17713 , +-8125 , +16885 , +29555 , +16893 , +-8973 , +25779 , +-13449 , +20647 , +30035 , +-11995 , +6367 , +31257 , +22045 , +17925 , +30011 , +21491 , +8615 , +2679 , +29277 , +-29049 , +25661 , +21563 , +21473 , +12629 , +-22285 , +26733 , +-6835 , +15865 , +-14587 , +28337 , +17577 , +-3663 , +-81 , +28403 , +31123 , +23881 , +1145 , +29087 , +12507 , +-29797 , +32287 , +14937 , +29849 , +-4483 , +11229 , +-27345 , +-18233 , +19015 , +13133 , +-20903 , +5207 , +-10303 , +-18241 , +27757 , +-311 , +-11111 , +22541 , +17685 , +27207 , +14949 , +-27145 , +-31665 , +-28097 , +-11243 , +-7687 , +32279 , +22129 , +27113 , +16549 , +-23887 , +31379 , +15341 , +13941 , +-4783 , +-23969 , +-32017 , +2861 , +-23205 , +25141 , +12279 , +-597 , +-5605 , +15399 , +-23997 , +-32705 , +251 , +-7779 , +-29771 , +5517 , +-8647 , +-28315 , +-17449 , +-6701 , +-8155 , +-5553 , +2381 , +-23339 , +13523 , +2623 , +4553 , +-8153 , +-7593 , +20943 , +2191 , +19975 , +-5765 , +-23455 , +19293 , +13503 , +31479 , +31923 , +-2573 , +-32145 , +-18645 , +-20993 , +11263 , +-21137 , +-4011 , +10639 , +20889 , +-2785 , +-6331 , +-24361 , +-5569 , +6985 , +-1373 , +23559 , +22087 , +11761 , +-16235 , +7469 , +9949 , +31151 , +769 , +26563 , +16497 , +15495 , +-27065 , +1229 , +-31813 , +12613 , +629 , +7025 , +13609 , +-29875 , +30459 , +-18931 , +-9501 , +31483 , +235 , +3023 , +-14027 , +-11657 , +31663 , +26315 , +5517 , +-7415 , +13371 , +-359 , +10231 , +11005 , +-18739 , +-24727 , +-23791 , +-5139 , +-16607 , +30105 , +-9599 , +16803 , +-15577 , +-10795 , +-28683 , +-11925 , +4163 , +22945 , +11917 , +-22029 , +-3335 , +10371 , +15587 , +27543 , +-7889 , +-14965 , +15735 , +20801 , +7905 , +14705 , +-19025 , +12739 , +-10917 , +-3789 , +-27831 , +4519 , +5355 , +10531 , +-22441 , +23953 , +-18141 , +15495 , +30131 , +25865 , +-22647 , +-20057 , +-1029 , +11749 , +24785 , +23155 , +-13557 , +14353 , +23701 , +24975 , +2027 , +18927 , +10127 , +-25613 , +-24239 , +-8911 , +-17329 , +-2309 , +27287 , +17447 , +3699 , +23303 , +21807 , +8099 , +16481 , +-9585 , +-32611 , +15691 , +31611 , +-31305 , +22771 , +30317 , +-7459 , +-17803 , +31681 , +-22687 , +-26481 , +18709 , +-25707 , +22359 , +19775 , +17763 , +6637 , +10423 , +21115 , +-9159 , +-28747 , +-22029 , +-22681 , +1433 , +-971 , +-24859 , +-2059 , +27461 , +-11623 , +23199 , +1693 , +23511 , +-25129 , +16843 , +30873 , +8799 , +29491 , +3453 , +31893 , +-26003 , +-5323 , +-6515 , +17391 , +22713 , +-9957 , +-3723 , +-14743 , +16431 , +30937 , +25245 , +-14237 , +-9331 , +19343 , +-19653 , +-25703 , +21369 , +23161 , +3757 , +-28083 , +22811 , +6263 , +-28597 , +-25329 , +-8911 , +-26127 , +27073 , +2795 , +-5205 , +23395 , +-30233 , +-7137 , +-31807 , +20037 , +-9187 , +-10401 , +-15219 , +25739 , +-18405 , +12673 , +17953 , +21151 , +-26033 , +-10311 , +-2275 , +-16433 , +-17225 , +-17321 , +22221 , +-25261 , +-22479 , +-14863 , +25529 , +-9289 , +22103 , +-24279 , +5833 , +14045 , +-1059 , +29921 , +-15669 , +20595 , +4959 , +-3861 , +12449 , +-12061 , +-16193 , +-20657 , +-12349 , +-14631 , +9465 , +24567 , +-11413 , +-723 , +-17791 , +-18707 , +-27621 , +32617 , +21015 , +-27377 , +3523 , +1203 , +-14307 , +25419 , +-11693 , +31053 , +2677 , +6233 , +18639 , +24203 , +-31023 , +-7957 , +-28431 , +14673 , +-26221 , +-7573 , +-7365 , +-14593 , +5411 , +4145 , +-14965 , +12529 , +31167 , +-29891 , +-5061 , +-2441 , +-2591 , +-31637 , +8117 , +-15031 , +-14581 , +6449 , +-371 , +-1913 , +4899 , +8911 , +-3053 , +-2523 , +-11695 , +28687 , +15221 , +8939 , +-7863 , +24955 , +18253 , +-23311 , +-11213 , +24589 , +26049 , +-21367 , +-24071 , +9843 , +-1773 , +31685 , +-16355 , +21697 , +7363 , +-7063 , +-14561 , +18087 , +3869 , +29795 , +14147 , +-23507 , +14169 , +2241 , +30197 , +-23317 , +8239 , +-207 , +-25699 , +32189 , +16107 , +-16915 , +10745 , +-3841 , +-8435 , +-13761 , +17135 , +31041 , +2657 , +9583 , +30705 , +1669 , +-14963 , +10309 , +-13883 , +-14861 , +31025 , +-27403 , +-3861 , +-5105 , +-8317 , +6051 , +-31121 , +-1675 , +20057 , +-4783 , +9535 , +29201 , +-18989 , +-5793 , +7177 , +32465 , +11103 , +-28289 , +-14451 , +29159 , +22883 , +-30675 , +11639 , +-23175 , +-21683 , +-603 , +-4165 , +-21287 , +-29145 , +24415 , +12387 , +20549 , +-25161 , +-501 , +32245 , +19221 , +5653 , +-7687 , +24639 , +17527 , +25021 , +-31193 , +-25163 , +-1361 , +7215 , +-20061 , +-11961 , +6331 , +24835 , +10131 , +26809 , +-20827 , +-16515 , +26025 , +-23683 , +-15325 , +-21837 , +10519 , +-22009 , +-547 , +-16879 , +-3577 , +21931 , +-13019 , +-20859 , +15769 , +-16147 , +8741 , +16389 , +-20903 , +14435 , +6309 , +6067 , +-9423 , +-23547 , +-26827 , +-15755 , +-791 , +259 , +22765 , +-14331 , +12825 , +1067 , +22951 , +8845 , +-28249 , +31917 , +7343 , +-3387 , +-15433 , +-28795 , +-14847 , +-14209 , +22825 , +25417 , +32259 , +22473 , +-26221 , +21635 , +6067 , +-3455 , +-79 , +19085 , +29037 , +-24979 , +7267 , +17629 , +-30701 , +8149 , +6179 , +-18191 , +-19243 , +-12137 , +-29951 , +-10095 , +3421 , +-25661 , +-7405 , +22713 , +24205 , +-2639 , +4467 , +-12059 , +-17993 , +10397 , +-19017 , +19185 , +3153 , +-12877 , +32742 , +7017 , +-17873 , +-13637 , +239 , +-26007 , +-19905 , +-21479 , +-24151 , +-11023 , +-2629 , +-19587 , +-1983 , +-12611 , +2531 , +29415 , +13371 , +27807 , +19511 , +19533 , +-10017 , +-24751 , +-24273 , +-21079 , +32319 , +-6439 , +30061 , +24987 , +-12127 , +-14769 , +-30341 , +-13193 , +-31103 , +16459 , +-32762 , +28129 , +-31483 , +-3159 , +-22901 , +32489 , +-5387 , +-3857 , +-3941 , +1183 , +14899 , +-8165 , +-25207 , +12071 , +22453 , +-28925 , +-32601 , +23899 , +-26117 , +-32729 , +25603 , +-25379 , +-25081 , +-28147 , +32147 , +-341 , +6871 , +22295 , +28407 , +-26561 , +27479 , +13787 , +-14421 , +-30427 , +1763 , +-5633 , +-32317 , +-8949 , +-24521 , +32135 , +28963 , +-23959 , +8937 , +21177 , +7475 , +3463 , +18275 , +22125 , +-739 , +33 , +-2729 , +-3353 , +-29063 , +-12933 , +11455 , +-9421 , +16025 , +-27907 , +-21177 , +18167 , +-25041 , +-703 , +5207 , +-18741 , +-10357 , +-11851 , +-22151 , +-9961 , +-8363 , +5297 , +-28323 , +-22679 , +22469 , +9229 , +-24751 , +21575 , +-25001 , +-25035 , +32049 , +8589 , +-1019 , +28105 , +25059 , +-18619 , +28675 , +-11851 , +3667 , +4861 , +3313 , +-17985 , +18661 , +-22625 , +24727 , +20393 , +-28817 , +-14905 , +-8679 , +1219 , +14261 , +-7003 , +-15693 , +-1013 , +-18853 , +-7355 , +27887 , +10425 , +17501 , +-9611 , +-24993 , +-1695 , +-25839 , +-26861 , +-24621 , +-6263 , +-371 , +21743 , +-16369 , +-15431 , +20149 , +-11753 , +9481 , +5665 , +22173 , +21181 , +26525 , +27559 , +4753 , +-21117 , +-3645 , +-6273 , +9355 , +-1961 , +-26807 , +-3769 , +12061 , +-4661 , +24849 , +22431 , +20223 , +-23823 , +703 , +-16577 , +27377 , +-23121 , +-3339 , +-18805 , +-28087 , +7059 , +-25073 , +17849 , +8659 , +-1739 , +-21677 , +21335 , +-6303 , +-5627 , +-13135 , +-19091 , +-1105 , +173 , +4345 , +18199 , +-29977 , +-14373 , +12427 , +-9577 , +17301 , +-13397 , +-13155 , +24557 , +-23519 , +13167 , +6373 , +6137 , +-8507 , +-31727 , +-6181 , +11269 , +-29693 , +8933 , +-28305 , +-32285 , +-7263 , +-20219 , +-21443 , +9355 , +-19425 , +-10459 , +4421 , +6443 , +-12107 , +-26125 , +8747 , +-1859 , +11707 , +-12571 , +-13847 , +9769 , +25523 , +-13931 , +12289 , +-1833 , +-12103 , +-9827 , +-27071 , +-19515 , +4217 , +-20247 , +22775 , +-24285 , +685 , +19091 , +-30301 , +10857 , +6155 , +27189 , +7223 , +17651 , +7627 , +19407 , +7879 , +2831 , +16275 , +-25591 , +-3125 , +-9825 , +30709 , +20771 , +1743 , +-13777 , +10087 , +31803 , +-3155 , +-7801 , +2485 , +-21715 , +-26555 , +-13617 , +16895 , +-3351 , +2231 , +30485 , +-19147 , +14925 , +-8677 , +31099 , +27395 , +-8839 , +-10319 , +30651 , +11601 , +16815 , +18089 , +-30903 , +7741 , +29085 , +15433 , +-12561 , +31881 , +23109 , +-3407 , +17623 , +20127 , +-16311 , +26641 , +-7887 , +11267 , +-31285 , +-23457 , +7495 , +-8889 , +22717 , +-24179 , +5901 , +2703 , +25027 , +20035 , +12615 , +-20359 , +2943 , +-23779 , +-30701 , +-27739 , +31351 , +16983 , +4621 , +27295 , +-12961 , +-26095 , +-14885 , +-2461 , +-16901 , +253 , +-25517 , +-16049 , +-17805 , +-14945 , +-14587 , +-17259 , +3881 , +-22529 , +-3233 , +29761 , +14615 , +-18971 , +-3525 , +4519 , +-1883 , +399 , +-25601 , +-7075 , +15607 , +10985 , +18733 , +-22093 , +32727 , +13125 , +-18555 , +19115 , +-22017 , +-27753 , +-19563 , +18551 , +6133 , +3365 , +24273 , +-28829 , +-10395 , +11461 , +27187 , +-6053 , +-19209 , +-1897 , +7495 , +-16163 , +12969 , +-16333 , +-32307 , +-32401 , +-349 , +-30867 , +-29743 , +10909 , +657 , +901 , +-27079 , +28781 , +-23681 , +-23837 , +3047 , +3153 , +18989 , +-26807 , +-27317 , +32177 , +-13341 , +23191 , +-23933 , +-3891 , +-13357 , +-23051 , +-22041 , +-31675 , +-21273 , +21397 , +-3283 , +-23287 , +11297 , +8935 , +18165 , +-18217 , +15213 , +-10417 , +23279 , +-12499 , +13565 , +-22173 , +21093 , +-28479 , +-223 , +-32099 , +11103 , +9601 , +14489 , +-1127 , +28721 , +18691 , +1397 , +-27453 , +1433 , +17787 , +-27543 , +8605 , +27991 , +3393 , +-2907 , +-8599 , +21825 , +10935 , +21549 , +10349 , +-13597 , +-16689 , +16051 , +20643 , +-5241 , +17913 , +-2837 , +-32527 , +26851 , +23459 , +29801 , +11239 , +-17891 , +13355 , +18419 , +-269 , +20849 , +1371 , +-18341 , +-12517 , +-20927 , +5473 , +30171 , +30765 , +-23633 , +-22461 , +20963 , +9861 , +-21577 , +-31785 , +8577 , +825 , +-24893 , +16965 , +24613 , +-17703 , +-22581 , +10995 , +-21749 , +-10593 , +-13087 , +-13825 , +-21237 , +24623 , +-7085 , +-451 , +-27925 , +-14389 , +20031 , +-19027 , +-24505 , +-31477 , +19117 , +4203 , +-811 , +27157 , +17439 , +8759 , +21075 , +8535 , +-6469 , +2649 , +21195 , +-12871 , +23499 , +-26067 , +-16525 , +17761 , +-32277 , +16907 , +2063 , +-8481 , +31121 , +31943 , +6835 , +18663 , +24113 , +29097 , +31795 , +25745 , +-31797 , +1253 , +16613 , +-26103 , +4363 , +3725 , +-501 , +-24633 , +19931 , +-4081 , +19363 , +11343 , +32381 , +16429 , +-4423 , +-30113 , +-23769 , +-14989 , +17487 , +-30803 , +-3051 , +30511 , +1187 , +-18913 , +29217 , +-17173 , +-2283 , +30589 , +25573 , +-23455 , +-20873 , +-13389 , +5955 , +17909 , +-6681 , +22911 , +-16499 , +4019 , +-27093 , +-22095 , +-14323 , +11961 , +23425 , +3293 , +29487 , +-12479 , +17407 , +9113 , +7689 , +27401 , +-24987 , +-32469 , +121 , +-8621 , +-7815 , +24783 , +-15933 , +31579 , +17375 , +-6815 , +-18015 , +-11185 , +7273 , +-9311 , +13785 , +29645 , +-23809 , +30433 , +-25503 , +15309 , +10725 , +67 , +-15893 , +-23767 , +26529 , +-3981 , +19713 , +-30327 , +-5813 , +27607 , +32159 , +-9761 , +17769 , +-26291 , +12617 , +-19613 , +10051 , +-13473 , +31655 , +20741 , +-13633 , +-3069 , +-21613 , +26473 , +187 , +23243 , +5309 , +12637 , +21465 , +3485 , +30137 , +-7473 , +26089 , +1007 , +21151 , +-17843 , +7601 , +27775 , +7201 , +26865 , +-17075 , +7563 , +31513 , +2275 , +30983 , +-24705 , +-26443 , +23121 , +-22867 , +-13759 , +-17669 , +32475 , +7529 , +27861 , +3565 , +-5219 , +-8679 , +-2141 , +-3811 , +-13933 , +-25559 , +-24285 , +-24123 , +31911 , +16103 , +-733 , +-26273 , +-30445 , +-3231 , +32371 , +30911 , +-28821 , +-6475 , +-9439 , +-10325 , +-26871 , +16627 , +-13515 , +-12053 , +24333 , +30827 , +6627 , +-23823 , +-4657 , +-27253 , +-32443 , +15581 , +5849 , +32567 , +18583 , +4137 , +12131 , +-6243 , +7397 , +-333 , +-22205 , +-3697 , +7247 , +-17065 , +-13203 , +9825 , +-29763 , +-31987 , +18149 , +-11213 , +12045 , +23681 , +-13507 , +27867 , +-17441 , +-995 , +30085 , +-725 , +24247 , +24247 , +11981 , +21717 , +-13627 , +7317 , +-14577 , +-2367 , +-13289 , +-16621 , +-583 , +27107 , +-11183 , +-3405 , +12437 , +657 , +31205 , +-4681 , +-5813 , +-17311 , +25037 , +-7365 , +339 , +15479 , +-29761 , +-9525 , +-27535 , +-27539 , +30953 , +-15237 , +31149 , +-8805 , +9513 , +8575 , +31429 , +17655 , +19139 , +6469 , +559 , +-24725 , +-5997 , +21259 , +30599 , +7855 , +-32041 , +27639 , +653 , +16031 , +5715 , +25009 , +-4965 , +-31983 , +13843 , +-13959 , +22689 , +7731 , +19365 , +11195 , +-30315 , +5981 , +29127 , +23603 , +28529 , +2671 , +-7763 , +9847 , +-19797 , +6049 , +27311 , +10011 , +-2519 , +7139 , +-4995 , +10559 , +-30789 , +-13905 , +19433 , +-8017 , +14105 , +-17819 , +-9719 , +22645 , +-29871 , +4129 , +-23039 , +-4621 , +3777 , +-16365 , +-20177 , +12415 , +-5735 , +7513 , +32233 , +32117 , +-32061 , +-17323 , +-3917 , +-20271 , +24427 , +18051 , +-1031 , +-15799 , +-1813 , +22233 , +3653 , +-22815 , +-16055 , +-2413 , +-17675 , +20235 , +3629 , +-11627 , +-27271 , +6449 , +8793 , +-16063 , +-18683 , +-28449 , +3491 , +-20279 , +-6451 , +-11701 , +-25749 , +-27119 , +-9029 , +27251 , +1939 , +29693 , +-26967 , +3005 , +-19977 , +4941 , +14355 , +-4355 , +-30615 , +-32003 , +27735 , +14625 , +24349 , +-1781 , +-15509 , +15671 , +-4171 , +11233 , +273 , +-3305 , +-18779 , +-17375 , +-10609 , +31337 , +26423 , +-14585 , +-271 , +585 , +11775 , +14645 , +13745 , +-4771 , +31185 , +-1513 , +-1 , +-30103 , +-31937 , +-30799 , +-16277 , +14697 , +19087 , +6911 , +3367 , +21805 , +17451 , +-4921 , +-16195 , +-18071 , +27555 , +-19723 , +-17087 , +15701 , +-2779 , +-4495 , +-9711 , +-1341 , +21869 , +8569 , +-3063 , +-18003 , +-10175 , +-31115 , +-26567 , +22625 , +32109 , +24403 , +16677 , +-30715 , +21555 , +30043 , +-24975 , +-19013 , +3407 , +-7793 , +-8413 , +30773 , +-1185 , +-19081 , +30295 , +22989 , +14823 , +-25467 , +21113 , +22301 , +13001 , +3555 , +-263 , +-5605 , +14899 , +9939 , +-22395 , +-1625 , +31011 , +-14975 , +31685 , +-31311 , +-8619 , +-927 , +22157 , +26563 , +19907 , +30205 , +17303 , +37 , +-14695 , +-7843 , +-18243 , +10091 , +-18517 , +-309 , +4015 , +15507 , +14961 , +25917 , +12587 , +-22625 , +27775 , +-26589 , +-5449 , +-22367 , +-24709 , +-31295 , +-6441 , +-13465 , +-26733 , +1545 , +-16445 , +-10373 , +-28549 , +29169 , +9381 , +-27437 , +16605 , +-5303 , +-30391 , +15575 , +-27557 , +27929 , +22625 , +-4097 , +21501 , +15475 , +8239 , +2031 , +30001 , +-11823 , +-20027 , +-25079 , +18235 , +-11547 , +-21827 , +7817 , +14133 , +13559 , +24941 , +16411 , +25221 , +8127 , +-21597 , +14321 , +-20529 , +-22349 , +30685 , +-32157 , +-22923 , +-277 , +-20227 , +6143 , +-17271 , +8051 , +25731 , +26399 , +21321 , +-21985 , +-23733 , +-5621 , +6677 , +-4369 , +5305 , +-20085 , +4073 , +-13355 , +-19335 , +-17409 , +-9391 , +29475 , +-19785 , +28915 , +-20251 , +-19889 , +-4395 , +6467 , +-32703 , +-11945 , +1189 , +-21595 , +-24713 , +-23913 , +25629 , +-14899 , +-21233 , +-9445 , +27539 , +10749 , +-8069 , +19329 , +-911 , +-26339 , +-32497 , +4421 , +-32141 , +24919 , +-17541 , +22695 , +-6821 , +31027 , +-29249 , +-14603 , +23845 , +32545 , +423 , +9579 , +-24373 , +30111 , +28095 , +25743 , +26479 , +-27703 , +-2859 , +-28677 , +-19427 , +629 , +-1057 , +-13629 , +-7169 , +-8761 , +-12667 , +-5051 , +-2285 , +21327 , +10767 , +-10873 , +2919 , +13469 , +-6431 , +5895 , +-32045 , +-10665 , +30829 , +-229 , +-13527 , +-27691 , +31671 , +-22331 , +16627 , +-12491 , +3133 , +8967 , +9385 , +-14851 , +6013 , +18629 , +6763 , +4641 , +26345 , +24855 , +11319 , +12207 , +-26537 , +8223 , +-14691 , +-8489 , +-17147 , +8291 , +-22523 , +-17781 , +-10487 , +27817 , +14931 , +-9319 , +-4785 , +12873 , +20273 , +-8131 , +-4603 , +13321 , +-18753 , +12345 , +6055 , +5489 , +-22331 , +-10895 , +8291 , +5801 , +30841 , +-16121 , +-11235 , +22729 , +-30037 , +-11037 , +24801 , +17083 , +1667 , +-30239 , +2529 , +7817 , +14521 , +-30125 , +30951 , +-30917 , +8521 , +6445 , +26193 , +-16595 , +9135 , +-25205 , +-12411 , +-30997 , +20891 , +10965 , +29679 , +-29569 , +18481 , +23895 , +-12173 , +2901 , +6069 , +25425 , +20841 , +-19317 , +11725 , +-30059 , +-3311 , +30669 , +-17867 , +10909 , +2193 , +17577 , +-31241 , +17189 , +24935 , +23661 , +-19161 , +-22723 , +-31387 , +19575 , +27409 , +3309 , +16163 , +10519 , +-14085 , +-9921 , +11525 , +8413 , +16221 , +223 , +-28513 , +121 , +-22129 , +-10955 , +5311 , +-16629 , +11275 , +5621 , +-15909 , +-21759 , +19743 , +7997 , +-9977 , +20339 , +16431 , +-29649 , +-12933 , +-22033 , +-9381 , +9725 , +5241 , +-14119 , +12231 , +30613 , +979 , +27201 , +15439 , +-8799 , +30425 , +-19649 , +-19783 , +27447 , +29143 , +-26683 , +18295 , +31455 , +31759 , +2807 , +-31787 , +17457 , +-6101 , +-28661 , +-27979 , +19953 , +-15563 , +17303 , +-51 , +5281 , +-24045 , +-2703 , +-7851 , +-16995 , +1409 , +27391 , +25665 , +11953 , +-29567 , +25111 , +13059 , +25137 , +-21159 , +27731 , +-20809 , +20369 , +11531 , +15081 , +29407 , +16511 , +3401 , +29443 , +7067 , +-5509 , +10483 , +-23911 , +-14745 , +9447 , +14085 , +28103 , +17733 , +-27731 , +27679 , +-29533 , +31877 , +7757 , +29289 , +-20069 , +-7439 , +-29837 , +-4065 , +-4023 , +-25461 , +6427 , +21623 , +-17207 , +10181 , +26907 , +9003 , +7061 , +5429 , +-26039 , +30301 , +6621 , +-15921 , +-6655 , +-4317 , +9819 , +-29791 , +-26031 , +-13203 , +25263 , +30981 , +-14205 , +24717 , +-31435 , +-13731 , +-32711 , +-25309 , +25437 , +28229 , +-4341 , +-4709 , +-17275 , +-12201 , +15503 , +6181 , +23887 , +-1451 , +31495 , +23845 , +13177 , +32746 , +-31641 , +-29381 , +27189 , +11489 , +7157 , +19881 , +9985 , +-4649 , +11357 , +17243 , +-255 , +-5249 , +31313 , +23631 , +-17193 , +20555 , +-23657 , +-4193 , +-28937 , +-20305 , +-15705 , +-5143 , +13951 , +-29229 , +-28991 , +-13235 , +20121 , +-5421 , +20613 , +-29717 , +17477 , +27757 , +-31987 , +20433 , +5817 , +-1219 , +31109 , +-135 , +30779 , +24697 , +-7875 , +-31811 , +26479 , +-10975 , +30793 , +-7081 , +-9927 , +-1089 , +-12141 , +-1075 , +-29931 , +15515 , +30583 , +-1547 , +-27163 , +-909 , +23003 , +27877 , +-9899 , +-23117 , +-17213 , +2157 , +-10327 , +-977 , +-23957 , +-7151 , +6685 , +-19625 , +-3101 , +26495 , +-19015 , +-16653 , +18209 , +-25211 , +2213 , +22107 , +-26215 , +9615 , +18445 , +8747 , +-10401 , +31645 , +-2453 , +-29571 , +-31057 , +-12623 , +-9625 , +-21595 , +28689 , +7643 , +-29133 , +-16539 , +-25869 , +-11365 , +16215 , +-18273 , +30385 , +-26645 , +-18673 , +-15459 , +-30657 , +-28499 , +17195 , +19641 , +29751 , +-14173 , +-26793 , +30621 , +-17037 , +-2835 , +16127 , +-32515 , +4137 , +20733 , +-18523 , +709 , +29049 , +-14067 , +-13385 , +-27941 , +11155 , +11037 , +17891 , +-19371 , +-12733 , +-27035 , +-27397 , +-27857 , +7181 , +-7857 , +30783 , +-32127 , +15303 , +11763 , +19521 , +-19143 , +1711 , +25863 , +4145 , +10585 , +-13561 , +-12449 , +-17471 , +15781 , +23329 , +-31265 , +-649 , +-5665 , +-16117 , +-4103 , +-1663 , +4483 , +28305 , +2205 , +8469 , +-5897 , +16867 , +-24135 , +-17847 , +-6835 , +13999 , +24109 , +12383 , +11887 , +7083 , +-26049 , +-15189 , +3045 , +9403 , +-1377 , +-18457 , +17405 , +-20093 , +-9773 , +-31739 , +-6763 , +8315 , +19507 , +16013 , +29759 , +1681 , +-3483 , +-17545 , +-4339 , +-23753 , +21067 , +-30597 , +-22085 , +-5881 , +-4471 , +22765 , +28777 , +-3383 , +-11149 , +-1509 , +-4645 , +15647 , +-10107 , +26649 , +-13269 , +31883 , +14687 , +6951 , +-30725 , +26647 , +-7877 , +9591 , +28217 , +20579 , +-535 , +14747 , +-17325 , +-9413 , +10047 , +12617 , +23275 , +-17477 , +-13289 , +11457 , +11021 , +-16677 , +7623 , +-7525 , +24053 , +1163 , +12819 , +14373 , +-12491 , +-17075 , +-27727 , +-17859 , +-9861 , +17485 , +-1741 , +3743 , +-25151 , +-4619 , +23175 , +-2613 , +13575 , +25353 , +7409 , +-2737 , +-15219 , +-8133 , +-29319 , +17065 , +-4983 , +12873 , +25073 , +1689 , +-30367 , +-14705 , +30813 , +-28417 , +16223 , +-22493 , +-29443 , +-27347 , +-14101 , +-16021 , +7861 , +1731 , +32581 , +14899 , +14861 , +-20733 , +5567 , +19021 , +25255 , +4783 , +-151 , +22687 , +21305 , +-16295 , +30555 , +-16703 , +-13309 , +-24765 , +-23717 , +2323 , +10183 , +22195 , +-14043 , +2901 , +-4287 , +26061 , +3607 , +-24125 , +8993 , +997 , +-18067 , +30371 , +29825 , +24927 , +28923 , +-23443 , +9181 , +24833 , +26725 , +-29619 , +-16757 , +25041 , +-1325 , +-18093 , +29363 , +12649 , +-22739 , +10235 , +12749 , +-16693 , +-6447 , +-13753 , +22923 , +-23103 , +-10549 , +-24483 , +7009 , +10931 , +11149 , +15769 , +23151 , +-16647 , +26411 , +4651 , +14341 , +-23107 , +-13813 , +20775 , +1681 , +-11959 , +-2523 , +-13529 , +-9439 , +-28443 , +-17229 , +-27303 , +30033 , +10031 , +3699 , +-10981 , +-19001 , +-7955 , +-31143 , +-30697 , +23341 , +-15249 , +-31039 , +-24363 , +15787 , +29025 , +24883 , +20439 , +-16171 , +18717 , +-32617 , +-11985 , +-19409 , +30609 , +3557 , +-26985 , +23069 , +-2933 , +1901 , +9739 , +-12965 , +5529 , +17019 , +-31525 , +31997 , +-14245 , +20383 , +-30897 , +-2337 , +3421 , +-18077 , +-9039 , +-18275 , +-13455 , +-27273 , +12269 , +16145 , +-27771 , +-8073 , +13483 , +3143 , +27901 , +-25569 , +-1825 , +-9229 , +17031 , +10235 , +21225 , +-16787 , +1911 , +-13139 , +-15323 , +21033 , +11677 , +-3689 , +-22515 , +-11347 , +-31843 , +-2785 , +1993 , +15367 , +5063 , +8031 , +-5561 , +9675 , +7029 , +-22691 , +30937 , +-20349 , +-19757 , +17099 , +-12217 , +6833 , +15693 , +14387 , +-10641 , +19005 , +14931 , +27579 , +-5041 , +-1165 , +-28995 , +24149 , +-11093 , +-12677 , +-8543 , +-26757 , +-22753 , +-5297 , +4005 , +29029 , +10167 , +29743 , +-29729 , +-16449 , +23303 , +32421 , +23849 , +18661 , +-20797 , +-13583 , +-18183 , +-30309 , +-28965 , +-3579 , +5307 , +-17597 , +-16631 , +16895 , +23203 , +-27499 , +20727 , +287 , +22287 , +-17193 , +-28983 , +20289 , +-2475 , +27031 , +-19903 , +24017 , +27427 , +7903 , +-16309 , +13895 , +-10925 , +2545 , +24867 , +-14561 , +-32447 , +-4483 , +3297 , +28489 , +22439 , +7771 , +25749 , +-16333 , +-27147 , +29633 , +4067 , +-20951 , +26407 , +-14853 , +-2285 , +-6303 , +29977 , +-12125 , +12721 , +-30359 , +2665 , +1369 , +-32353 , +-4827 , +-9015 , +16381 , +-19787 , +-16065 , +6099 , +-10907 , +-18741 , +11045 , +-16277 , +-2923 , +-10657 , +9855 , +2191 , +-11653 , +-12889 , +-9431 , +-21585 , +-26595 , +11815 , +8617 , +-5233 , +-29861 , +-9007 , +-4569 , +17805 , +27173 , +1169 , +-9753 , +30861 , +28721 , +21871 , +-31941 , +-3261 , +-209 , +-6109 , +-1019 , +17167 , +24971 , +-25043 , +-343 , +-25769 , +-24673 , +22125 , +8575 , +3421 , +-8345 , +-12737 , +-16167 , +-30569 , +18115 , +-30965 , +-10381 , +15243 , +-10203 , +-30621 , +32101 , +27933 , +16849 , +22171 , +17831 , +26225 , +6031 , +-2595 , +12803 , +-31421 , +28391 , +20933 , +30093 , +3767 , +21973 , +-7815 , +-16999 , +-9547 , +7177 , +-8131 , +14651 , +28611 , +-6509 , +-3441 , +5941 , +-22691 , +-31193 , +-28741 , +-19853 , +29387 , +1995 , +2039 , +9479 , +-10123 , +-2027 , +32509 , +31131 , +-15929 , +-12059 , +-19687 , +13165 , +-20101 , +-30317 , +-5937 , +25795 , +-1413 , +-15949 , +-11549 , +3049 , +-28875 , +32323 , +-12545 , +-4445 , +369 , +-3729 , +20165 , +-21463 , +-13647 , +17591 , +-15001 , +15771 , +29951 , +-8773 , +-3649 , +-25345 , +-17335 , +5475 , +-8983 , +-13645 , +16443 , +-9823 , +25943 , +-5785 , +-8553 , +12707 , +-20885 , +-22375 , +19979 , +7313 , +19605 , +-19067 , +4487 , +-15681 , +-31263 , +27303 , +23577 , +29031 , +32531 , +30117 , +-701 , +22757 , +-21183 , +-21541 , +-4649 , +-31387 , +25579 , +-15045 , +-27323 , +2599 , +-10355 , +13789 , +24447 , +-10445 , +27841 , +-8733 , +-17589 , +12681 , +-21553 , +-14337 , +6423 , +17891 , +-20283 , +-20897 , +603 , +-12821 , +28693 , +32309 , +-7833 , +16367 , +-22615 , +-28259 , +-28221 , +-32483 , +-11143 , +-10207 , +20739 , +-28103 , +1193 , +-23121 , +10269 , +11991 , +-8677 , +24587 , +25925 , +-10485 , +-20083 , +-15663 , +15941 , +15283 , +-3545 , +-3613 , +13135 , +-31465 , +-5729 , +4711 , +19041 , +27703 , +201 , +-24001 , +-17649 , +-24971 , +29877 , +17919 , +8931 , +25555 , +-12227 , +17761 , +-9677 , +-87 , +555 , +28231 , +-32385 , +-15395 , +26563 , +-27089 , +24377 , +20123 , +-23579 , +29217 , +-22989 , +-5487 , +-25949 , +-711 , +15461 , +-30305 , +26963 , +9613 , +6729 , +21013 , +-19665 , +-2123 , +-9539 , +13931 , +6759 , +185 , +-27825 , +-28809 , +15807 , +7815 , +-29415 , +12579 , +4767 , +30455 , +-2535 , +-3667 , +-3149 , +-13003 , +8975 , +6995 , +15359 , +-4669 , +31177 , +-16237 , +-14731 , +26861 , +-25595 , +27367 , +10771 , +21441 , +-5435 , +7155 , +2677 , +18311 , +-1499 , +6463 , +21745 , +22461 , +3513 , +31351 , +-15827 , +13957 , +13665 , +-3559 , +29751 , +16299 , +8863 , +-14155 , +2333 , +-24051 , +20085 , +-32097 , +-1529 , +24485 , +-30795 , +10283 , +-24883 , +23537 , +-32287 , +-22427 , +-20977 , +12529 , +31873 , +20033 , +-28211 , +677 , +-25867 , +-16287 , +26755 , +2299 , +1235 , +-31933 , +2745 , +2123 , +26301 , +30201 , +-4831 , +28755 , +-5185 , +16741 , +14127 , +22955 , +18201 , +12787 , +-6611 , +6585 , +-6489 , +29639 , +21721 , +-23243 , +-6741 , +10627 , +-139 , +30991 , +-10193 , +21871 , +-9113 , +16895 , +1755 , +3395 , +8523 , +-1439 , +13129 , +-4021 , +-13165 , +-18743 , +31967 , +22579 , +-13425 , +-10013 , +32297 , +15407 , +5403 , +-7941 , +15023 , +16061 , +-28509 , +-27151 , +-2737 , +-8743 , +8651 , +-17497 , +-30959 , +15797 , +-20361 , +4107 , +20097 , +-31249 , +-31375 , +-14717 , +20363 , +18769 , +-11397 , +14819 , +-25649 , +-4095 , +-15127 , +3309 , +-25739 , +-25545 , +-6735 , +29001 , +20109 , +-32383 , +16911 , +-13071 , +7909 , +9837 , +4505 , +30263 , +23133 , +-30513 , +18129 , +-16837 , +-4671 , +-25495 , +-9405 , +469 , +30757 , +7215 , +12317 , +-1757 , +20147 , +9727 , +23363 , +-659 , +-30447 , +-26413 , +-18197 , +32171 , +-20947 , +-21129 , +-26187 , +22899 , +6555 , +-15925 , +25917 , +23161 , +-20117 , +-12683 , +2365 , +-31615 , +1153 , +32537 , +3357 , +29661 , +26991 , +25871 , +8715 , +-32163 , +13769 , +15521 , +-30823 , +-5425 , +-23037 , +-17219 , +7377 , +-23823 , +-29245 , +-5839 , +30155 , +9199 , +26811 , +24417 , +-12853 , +-9901 , +-7165 , +-27265 , +11733 , +28293 , +30705 , +-31677 , +-24639 , +-19779 , +10859 , +-19673 , +-14883 , +19327 , +4553 , +7961 , +-20739 , +-4719 , +-20447 , +-3149 , +16151 , +21623 , +-16597 , +-28935 , +1109 , +-20385 , +-31599 , +-14453 , +-12103 , +-15701 , +18125 , +-4763 , +-4057 , +24793 , +-1417 , +32011 , +21253 , +-27133 , +-16345 , +-695 , +-31405 , +6873 , +19147 , +-149 , +-13757 , +23569 , +-14723 , +-17931 , +13387 , +-14491 , +22491 , +13781 , +4549 , +-26871 , +-13349 , +-31197 , +-31231 , +-11353 , +-28625 , +595 , +-22813 , +-15153 , +-29677 , +-1291 , +-2317 , +-30733 , +-3677 , +-7969 , +-27649 , +1511 , +-24643 , +22259 , +-3547 , +-313 , +11347 , +9811 , +31615 , +25729 , +12095 , +-29421 , +-5083 , +-17467 , +-6747 , +-8329 , +-15659 , +-17543 , +-14909 , +-3157 , +-25083 , +-7495 , +6987 , +20473 , +-8837 , +15689 , +17467 , +-27777 , +24677 , +3733 , +-22983 , +4459 , +-18447 , +-25827 , +-2973 , +5813 , +-22937 , +-14217 , +-8785 , +-11695 , +17087 , +-13373 , +-17475 , +22501 , +-26439 , +-24925 , +23091 , +-19189 , +7543 , +29363 , +28307 , +-28413 , +-12145 , +-9341 , +-10091 , +20201 , +25007 , +-6387 , +17145 , +10867 , +12969 , +-9045 , +15595 , +18209 , +-29171 , +-9577 , +25547 , +10751 , +-5561 , +2521 , +-19053 , +-27183 , +-28363 , +-24381 , +-23641 , +16855 , +-31687 , +27631 , +-461 , +25343 , +-2855 , +5545 , +20477 , +32665 , +10705 , +-7177 , +-15683 , +-31337 , +10417 , +9479 , +9211 , +-25791 , +-1041 , +551 , +8805 , +-23953 , +-4735 , +-3771 , +23457 , +-6595 , +-29195 , +31963 , +21163 , +-5305 , +-8177 , +-25997 , +-6483 , +-9633 , +-32557 , +18327 , +25173 , +32195 , +9259 , +-23221 , +-17491 , +18653 , +15867 , +18949 , +7283 , +25201 , +12209 , +553 , +19187 , +10587 , +-11671 , +-18695 , +2907 , +11207 , +-19073 , +-19433 , +4503 , +2275 , +-5723 , +881 , +-25685 , +13603 , +-20353 , +6083 , +19583 , +6375 , +-5959 , +32141 , +24393 , +-32311 , +-29025 , +-13689 , +-13483 , +-8639 , +10555 , +-31843 , +28775 , +15337 , +31709 , +12643 , +-7283 , +-32719 , +21575 , +23313 , +-2951 , +-11369 , +-13003 , +-24581 , +-31905 , +-18591 , +-8831 , +-22649 , +-16577 , +-16943 , +-29773 , +8099 , +25807 , +23779 , +-25063 , +-32317 , +5567 , +-11393 , +8037 , +-10671 , +24743 , +-26317 , +-28735 , +11951 , +-28343 , +20587 , +6757 , +3491 , +-7813 , +-19665 , +-22601 , +30303 , +8819 , +29263 , +9173 , +-9755 , +30373 , +32547 , +-11841 , +-25841 , +13339 , +-18491 , +733 , +24835 , +-30903 , +28097 , +2853 , +-4059 , +-4503 , +-16555 , +-13909 , +-15979 , +9551 , +15139 , +-25153 , +4393 , +-26167 , +-14741 , +8317 , +-26147 , +109 , +15817 , +31465 , +-18223 , +8695 , +-14241 , +-20337 , +11969 , +31005 , +21917 , +-18807 , +14329 , +-18195 , +15725 , +-20693 , +13009 , +-11361 , +31475 , +8715 , +-29533 , +-26125 , +31165 , +-30557 , +11589 , +-29951 , +-4735 , +1893 , +6397 , +-4967 , +-21415 , +-21681 , +-32515 , +-15339 , +877 , +1041 , +-1447 , +-14413 , +32313 , +29329 , +4993 , +-8077 , +-26563 , +1045 , +53 , +21603 , +20795 , +12751 , +-27649 , +12673 , +7143 , +23805 , +17201 , +4367 , +7971 , +24445 , +25169 , +-13461 , +16831 , +2273 , +23579 , +13413 , +-1885 , +-8175 , +5621 , +30751 , +20363 , +347 , +15079 , +12379 , +9291 , +28941 , +-23275 , +-13733 , +3189 , +-17777 , +-25167 , +21809 , +-8803 , +13305 , +11133 , +20641 , +20493 , +-16853 , +10171 , +-27537 , +-19459 , +22887 , +20905 , +-6085 , +12619 , +26213 , +6259 , +25567 , +-30279 , +-5137 , +21429 , +12349 , +-10859 , +-18185 , +-23957 , +-16227 , +13061 , +-17615 , +-22421 , +7299 , +-8269 , +25127 , +-7585 , +20997 , +-19197 , +26327 , +18491 , +-22357 , +32469 , +-12349 , +30261 , +-21313 , +9397 , +-30319 , +-27589 , +-21723 , +7575 , +27679 , +-19467 , +-19015 , +9739 , +1049 , +-8915 , +-14303 , +-20231 , +-1769 , +-32555 , +9513 , +2777 , +26671 , +-30089 , +-31591 , +-22681 , +2831 , +-14289 , +10639 , +-28195 , +-31845 , +-7895 , +31059 , +30641 , +-23561 , +-28021 , +10929 , +17855 , +2861 , +27387 , +-23081 , +-12271 , +-4543 , +-17265 , +-21345 , +31755 , +26049 , +-693 , +-7305 , +25897 , +6121 , +19987 , +21167 , +-3019 , +-26827 , +24613 , +30801 , +24833 , +19831 , +28945 , +639 , +5789 , +19315 , +-27339 , +-13753 , +29199 , +-11019 , +2223 , +9975 , +-11383 , +363 , +-16683 , +12801 , +31273 , +18681 , +-6091 , +4933 , +8743 , +22039 , +-22781 , +-4621 , +-8815 , +-3169 , +-21993 , +-31265 , +8073 , +28533 , +-6553 , +13657 , +29171 , +18829 , +9973 , +19333 , +-12879 , +-30831 , +-21679 , +27445 , +3423 , +-31505 , +-29553 , +575 , +29317 , +-26759 , +8379 , +29011 , +-19121 , +24697 , +5331 , +-935 , +-26929 , +8777 , +30017 , +6979 , +28069 , +-3479 , +23763 , +17257 , +-23225 , +8223 , +-32211 , +-16031 , +-22613 , +-22653 , +23499 , +-17581 , +10635 , +2339 , +4717 , +-3119 , +20755 , +24085 , +-1505 , +25911 , +-20705 , +137 , +-13923 , +19837 , +-32011 , +-24335 , +18523 , +-15735 , +16499 , +8071 , +-21769 , +26391 , +-12075 , +629 , +22065 , +22527 , +-31267 , +-8095 , +16487 , +-5607 , +14235 , +-26745 , +-22143 , +20629 , +-31591 , +-22181 , +24953 , +-15415 , +-21351 , +-28011 , +21835 , +16531 , +-565 , +30665 , +-26007 , +30767 , +19593 , +-369 , +-20293 , +2185 , +28037 , +-21755 , +13077 , +-27363 , +10893 , +-26123 , +-20953 , +-10163 , +-22085 , +-4245 , +-10749 , +17713 , +-16593 , +-11829 , +-11767 , +20989 , +8523 , +18793 , +-10395 , +717 , +-2207 , +-9057 , +-13819 , +-13055 , +-17671 , +16491 , +7185 , +27417 , +-7301 , +-2683 , +-23577 , +-18169 , +21621 , +10735 , +-24439 , +12553 , +1601 , +-18665 , +-23389 , +8453 , +-7853 , +-27535 , +-24589 , +12377 , +17371 , +-27009 , +-16557 , +20027 , +10769 , +-11653 , +23329 , +-24435 , +28893 , +32357 , +-21443 , +-29903 , +11031 , +-23137 , +32647 , +26603 , +-32451 , +-30207 , +-24629 , +1715 , +5039 , +2421 , +11847 , +-29047 , +22367 , +-8179 , +-24173 , +-10535 , +-6893 , +7837 , +-23769 , +-11965 , +13071 , +-21039 , +-31921 , +7169 , +-20131 , +13763 , +31643 , +21689 , +-16261 , +16919 , +30691 , +17363 , +31381 , +-1389 , +-25161 , +30805 , +-14531 , +18485 , +19035 , +27709 , +-20057 , +-16695 , +-16581 , +-14003 , +31065 , +8967 , +13545 , +-6539 , +21867 , +-6875 , +-29553 , +5531 , +25143 , +26609 , +22507 , +-9733 , +-20067 , +27759 , +28613 , +-24831 , +-2645 , +31203 , +-12059 , +1943 , +-16925 , +-25991 , +-2157 , +28169 , +-16661 , +17487 , +29059 , +-21419 , +7371 , +-14567 , +-8617 , +-15099 , +12189 , +5683 , +5781 , +-31603 , +-17717 , +18229 , +-20197 , +-19693 , +3783 , +-25325 , +-24805 , +-4387 , +3393 , +30641 , +5775 , +-14571 , +-30755 , +-5 , +-31945 , +12077 , +-3725 , +-6017 , +-18935 , +-7501 , +-9799 , +6785 , +2867 , +-11861 , +11149 , +-22633 , +-16757 , +11619 , +-23141 , +-10303 , +9863 , +11725 , +-31323 , +-21507 , +3515 , +10077 , +-8657 , +-21151 , +-7477 , +2387 , +-28997 , +24759 , +-2327 , +-9051 , +22147 , +13965 , +-32059 , +23365 , +-1615 , +20437 , +-22003 , +14341 , +-3819 , +-4359 , +13663 , +12015 , +-25511 , +-4749 , +15045 , +30227 , +28357 , +3555 , +27821 , +-22807 , +3687 , +-32081 , +18269 , +-18395 , +-8741 , +-32495 , +-11027 , +8209 , +-6023 , +14515 , +16321 , +-18591 , +-22261 , +1995 , +-5247 , +29839 , +-23789 , +17327 , +19595 , +-26703 , +18031 , +28139 , +13811 , +24273 , +5539 , +11739 , +-10759 , +-9529 , +-31097 , +-6455 , +6395 , +-881 , +-27261 , +17019 , +-21773 , +29471 , +-31937 , +-30643 , +20337 , +29125 , +-19221 , +6355 , +-14325 , +-2311 , +12007 , +-6683 , +347 , +-21573 , +-24061 , +16185 , +-16779 , +-3227 , +-31943 , +-13439 , +31459 , +17409 , +9691 , +1537 , +-17645 , +24367 , +20567 , +6305 , +-31907 , +-31891 , +17253 , +27279 , +11629 , +11767 , +-21559 , +-17589 , +21575 , +-31457 , +30337 , +8777 , +3763 , +799 , +-123 , +-13559 , +12353 , +31099 , +-27915 , +-14941 , +-14149 , +1231 , +-18207 , +-15377 , +-26085 , +2353 , +17263 , +6931 , +-17147 , +-12547 , +-26721 , +-7779 , +11205 , +-10185 , +10369 , +-32227 , +27579 , +-31135 , +-25365 , +-26057 , +3421 , +10447 , +-26707 , +32325 , +15019 , +2943 , +-26027 , +14695 , +3111 , +-24965 , +-1449 , +25119 , +-9139 , +19875 , +24791 , +-25755 , +20877 , +8461 , +-13105 , +6723 , +22207 , +-16931 , +-28717 , +2029 , +-17885 , +-8293 , +15687 , +6227 , +-21811 , +-7669 , +1043 , +11585 , +-13147 , +29571 , +27357 , +24053 , +6883 , +1997 , +-6457 , +15153 , +20729 , +9069 , +17563 , +-22563 , +4633 , +6031 , +23691 , +7697 , +-30937 , +17993 , +2155 , +-18239 , +-21711 , +-30845 , +-11167 , +-9793 , +-411 , +-14775 , +25123 , +-15261 , +-10351 , +28325 , +-2383 , +1179 , +3087 , +-15377 , +10883 , +-1397 , +9801 , +-18507 , +13389 , +25239 , +-7511 , +22787 , +-14801 , +12811 , +11025 , +29761 , +-2705 , +-24539 , +18653 , +31633 , +9397 , +-19525 , +-31413 , +20379 , +26809 , +11587 , +-3969 , +241 , +24457 , +9595 , +-30983 , +8669 , +-3531 , +14453 , +28043 , +-16189 , +-1779 , +-27339 , +31697 , +-23829 , +14933 , +-13881 , +-13017 , +-10261 , +-17533 , +-23591 , +-28633 , +15725 , +-8975 , +-559 , +-13157 , +2969 , +14363 , +-12191 , +22523 , +473 , +-18355 , +24747 , +-20387 , +19523 , +-6679 , +-7475 , +-2571 , +-18073 , +-9199 , +26877 , +-17655 , +22699 , +-7957 , +30501 , +-7577 , +6429 , +6223 , +4851 , +17505 , +-32557 , +18695 , +-22405 , +21063 , +5313 , +11395 , +-25789 , +28755 , +-30451 , +16653 , +-9243 , +15923 , +20971 , +-26997 , +23079 , +-31247 , +-21265 , +-29265 , +-21625 , +2421 , +-17679 , +435 , +-16795 , +-6535 , +-15783 , +-11123 , +-3703 , +-14083 , +12793 , +21933 , +26699 , +-23477 , +31855 , +31533 , +-3301 , +10849 , +25581 , +26001 , +25771 , +-17931 , +-12639 , +9723 , +-21641 , +-1309 , +-17535 , +16099 , +-30747 , +-7893 , +28583 , +-10417 , +14045 , +20073 , +29739 , +6283 , +-5925 , +2505 , +31869 , +-20891 , +23955 , +18051 , +-13005 , +-7715 , +31741 , +28881 , +15213 , +18019 , +16111 , +31081 , +23713 , +29071 , +-12741 , +22385 , +-253 , +-19113 , +7237 , +-1797 , +-32183 , +21703 , +-8169 , +23035 , +10519 , +11063 , +17401 , +-1601 , +-1339 , +15883 , +8337 , +26347 , +19911 , +12513 , +7283 , +6633 , +-28039 , +5199 , +-30663 , +21989 , +30331 , +-30949 , +20259 , +18507 , +-1905 , +-24083 , +-11229 , +7861 , +-31517 , +-23151 , +4993 , +19305 , +-19977 , +-7259 , +-7957 , +-20401 , +-18959 , +-9767 , +-26097 , +-6037 , +11377 , +-2143 , +9655 , +26575 , +17641 , +1651 , +-26793 , +-21987 , +-3717 , +-21387 , +20273 , +10103 , +11853 , +449 , +-4377 , +18425 , +-1693 , +-20457 , +-1391 , +3509 , +4849 , +-27371 , +32347 , +-21215 , +7737 , +24301 , +-28525 , +-13285 , +15079 , +7075 , +2127 , +-24743 , +-20773 , +12991 , +16507 , +-24987 , +-18289 , +-15993 , +16241 , +1553 , +8681 , +-11843 , +6933 , +-7817 , +-21615 , +25289 , +-3731 , +-11931 , +-5937 , +-17023 , +19895 , +19037 , +-23589 , +2647 , +20991 , +-32497 , +25279 , +-24047 , +32061 , +-17077 , +9381 , +4357 , +26089 , +19323 , +-4171 , +17617 , +16653 , +-15205 , +18285 , +-9071 , +-29201 , +-6985 , +9075 , +5015 , +-16877 , +-22573 , +32503 , +16035 , +12773 , +-6791 , +6275 , +21403 , +25029 , +8863 , +31317 , +29637 , +-29789 , +-11739 , +-7367 , +-3969 , +-17125 , +-17455 , +10207 , +-15761 , +-28151 , +-15937 , +9391 , +-5301 , +32673 , +-17307 , +-10193 , +-17919 , +1027 , +-23303 , +-16951 , +26995 , +-28067 , +-14721 , +-32465 , +4539 , +-27779 , +11563 , +-24015 , +25553 , +21223 , +3179 , +8463 , +10193 , +12403 , +21331 , +-13481 , +-2649 , +-4515 , +10141 , +16705 , +8275 , +29669 , +32537 , +19323 , +19355 , +-9119 , +-28753 , +-26231 , +-23485 , +10971 , +19917 , +-32613 , +12995 , +31265 , +-20121 , +-11543 , +16517 , +359 , +-1689 , +26501 , +18327 , +-15021 , +-23121 , +27317 , +25831 , +19873 , +24457 , +3787 , +-15111 , +14129 , +-30563 , +-19073 , +799 , +-1367 , +-22411 , +10693 , +-3277 , +-16509 , +28779 , +551 , +-12853 , +-27735 , +-29151 , +-15461 , +14069 , +-8303 , +1149 , +-9001 , +5999 , +28369 , +17185 , +4659 , +-16291 , +-6859 , +-19361 , +29177 , +20859 , +-1957 , +-1611 , +26945 , +-9753 , +17865 , +-28989 , +4423 , +11077 , +7557 , +2759 , +19777 , +-10367 , +6449 , +-18295 , +-12099 , +20743 , +-10341 , +-17181 , +-22923 , +-23173 , +-19235 , +-31823 , +20389 , +-13589 , +-10515 , +-21691 , +5095 , +-2161 , +26303 , +9831 , +-26229 , +-1027 , +19923 , +-13111 , +24171 , +6111 , +20563 , +4609 , +10567 , +16689 , +-9299 , +6907 , +2973 , +22005 , +24993 , +-5641 , +3065 , +12393 , +-26653 , +-9979 , +4315 , +5571 , +29747 , +6897 , +9221 , +30567 , +15593 , +31429 , +-22955 , +32417 , +-31201 , +4537 , +-29667 , +23259 , +29495 , +11189 , +14843 , +-13741 , +5377 , +4675 , +6707 , +-10919 , +15435 , +-2559 , +-32121 , +13313 , +-26369 , +-20823 , +651 , +22111 , +32177 , +-30345 , +-19841 , +-30915 , +8131 , +-8655 , +-25943 , +8531 , +-21513 , +-23921 , +-13525 , +20225 , +1927 , +-19387 , +15451 , +19589 , +-27207 , +4457 , +3997 , +-23377 , +-9727 , +-18565 , +18617 , +24615 , +20117 , +24781 , +-26701 , +-24815 , +18299 , +-10101 , +19235 , +-27303 , +14899 , +7465 , +781 , +24921 , +16833 , +2397 , +15421 , +-19167 , +14151 , +-17513 , +19479 , +-13791 , +14117 , +29691 , +-6921 , +-26773 , +-5497 , +8405 , +-17659 , +-15769 , +28037 , +20887 , +24969 , +16911 , +10677 , +-14261 , +-1841 , +11419 , +32071 , +24975 , +-15247 , +-22585 , +-31077 , +-29941 , +16953 , +29577 , +-5033 , +103 , +-9867 , +1855 , +-1529 , +1737 , +-17715 , +-18067 , +-5845 , +-8503 , +2211 , +-5633 , +-20781 , +-23319 , +-8225 , +-22805 , +9661 , +22667 , +22867 , +-15489 , +-4895 , +16751 , +7051 , +-9719 , +-11629 , +27557 , +-27355 , +12315 , +9239 , +29195 , +30639 , +-2757 , +-17989 , +20287 , +-29955 , +-11235 , +5993 , +27927 , +28923 , +20059 , +31175 , +-21855 , +29195 , +-9553 , +10189 , +-28525 , +-5665 , +15785 , +-7977 , +27715 , +27847 , +5351 , +-16571 , +-30427 , +15765 , +3279 , +26509 , +16573 , +11247 , +-18237 , +-9255 , +6429 , +29475 , +-31265 , +-13287 , +-22059 , +-20087 , +-16341 , +-17765 , +32625 , +-28591 , +8789 , +-13013 , +-19083 , +13283 , +-6165 , +-23901 , +32453 , +3251 , +-9711 , +1285 , +21681 , +8341 , +20151 , +-12271 , +1119 , +25761 , +-28069 , +-7065 , +21189 , +16255 , +-19407 , +32527 , +28461 , +-13245 , +11495 , +-12895 , +-5097 , +-2619 , +22491 , +5839 , +30407 , +639 , +14031 , +20359 , +1329 , +-22311 , +30755 , +29831 , +-19857 , +17417 , +14227 , +-32651 , +453 , +16751 , +29025 , +22135 , +-16373 , +24159 , +-24547 , +31055 , +15281 , +-12667 , +31955 , +-6421 , +2859 , +-7489 , +22977 , +-3963 , +6647 , +18533 , +3995 , +26419 , +13321 , +31029 , +-2761 , +-2807 , +-14395 , +29597 , +-9783 , +-1369 , +5761 , +21397 , +31137 , +-13991 , +-29841 , +-7167 , +25941 , +-28249 , +28957 , +-16261 , +-11385 , +-8585 , +-17043 , +8115 , +21785 , +-2915 , +11275 , +-8635 , +-7203 , +-4365 , +24421 , +-7657 , +17371 , +-4359 , +16421 , +28195 , +12029 , +14819 , +21285 , +32477 , +17229 , +-26059 , +15849 , +-14587 , +11175 , +-8737 , +12701 , +25853 , +-1281 , +-14129 , +29825 , +-5977 , +12807 , +21519 , +-15893 , +-15947 , +26483 , +-28333 , +-18245 , +-20855 , +2733 , +2847 , +4177 , +17291 , +14605 , +-1711 , +-13299 , +8953 , +7571 , +8771 , +9533 , +-691 , +-11493 , +-16289 , +25499 , +-3575 , +16667 , +17465 , +23617 , +26901 , +-5421 , +19233 , +-12503 , +-877 , +10509 , +-23995 , +23323 , +-29891 , +-14765 , +-20929 , +16425 , +2873 , +30111 , +3891 , +-22357 , +13681 , +7071 , +-9879 , +-20303 , +-24215 , +25191 , +14939 , +-7169 , +27035 , +-28761 , +-7593 , +27267 , +-4015 , +5479 , +2709 , +-25781 , +-8971 , +-10945 , +28619 , +11781 , +-5649 , +-29173 , +6473 , +-15637 , +-25859 , +27687 , +17551 , +-1721 , +29701 , +13347 , +19811 , +-13213 , +-14215 , +1 , +-5519 , +28417 , +-17633 , +1769 , +-27047 , +23899 , +-31113 , +26463 , +32077 , +-8813 , +-23155 , +27647 , +-14555 , +-22869 , +-2735 , +17077 , +-27137 , +-6651 , +26221 , +-24977 , +-28339 , +23375 , +22433 , +15199 , +21877 , +-15611 , +12447 , +-16981 , +-24609 , +18279 , +21843 , +-7515 , +-28773 , +12269 , +2509 , +31883 , +-11665 , +-30911 , +24209 , +12469 , +5743 , +-4165 , +-17043 , +28753 , +-26599 , +24145 , +11989 , +-23647 , +9453 , +-3049 , +-4167 , +-87 , +27265 , +-20941 , +28637 , +-403 , +-5601 , +9299 , +20659 , +-3677 , +26839 , +3497 , +31919 , +-22535 , +13335 , +-15261 , +-4315 , +-25413 , +4811 , +32673 , +17561 , +-21995 , +15085 , +31723 , +-21597 , +-18993 , +9119 , +-13779 , +20021 , +20601 , +-29757 , +-721 , +-13433 , +-16597 , +-29421 , +28041 , +-9633 , +26559 , +5055 , +19487 , +-21517 , +6017 , +-28039 , +15129 , +10045 , +7277 , +19219 , +-23209 , +-27437 , +-22295 , +927 , +-29591 , +-11455 , +31219 , +32762 , +1297 , +-21541 , +14311 , +-26647 , +6701 , +24607 , +-30297 , +16817 , +20025 , +1923 , +21091 , +26933 , +29505 , +-10795 , +4549 , +-5243 , +4445 , +-7665 , +-8529 , +-28939 , +5031 , +-31315 , +-2957 , +20417 , +-3147 , +-4981 , +19077 , +-9957 , +7051 , +-4811 , +11967 , +-32061 , +-18913 , +-15929 , +23049 , +-21723 , +-22973 , +-18111 , +30623 , +-14871 , +-9177 , +31073 , +-26943 , +-2281 , +-16055 , +-5901 , +32495 , +-28001 , +-3335 , +23225 , +24225 , +22653 , +833 , +4273 , +-13191 , +-15023 , +30829 , +-20485 , +-27903 , +20333 , +-15623 , +-17113 , +16103 , +-6021 , +25093 , +-18151 , +-6235 , +-25723 , +-4513 , +-2481 , +10959 , +-24677 , +17385 , +-16691 , +-11849 , +-18713 , +-32363 , +-7577 , +6575 , +12861 , +6117 , +17821 , +5829 , +28993 , +-25125 , +-30475 , +10479 , +14065 , +-23437 , +24785 , +-1075 , +-21817 , +16541 , +-18999 , +2267 , +24141 , +-31821 , +9597 , +5165 , +12087 , +-25999 , +-1033 , +-25689 , +24053 , +-13715 , +15739 , +-20303 , +-20267 , +1553 , +-10015 , +13427 , +-1135 , +20241 , +-26001 , +-4469 , +-7313 , +-24735 , +-2259 , +30277 , +14289 , +-28491 , +18625 , +26197 , +-18601 , +31341 , +-28217 , +-11509 , +-26257 , +15897 , +25255 , +31503 , +-19347 , +31337 , +-2327 , +-21863 , +-26583 , +23719 , +8985 , +18725 , +29971 , +-14161 , +11025 , +2477 , +10187 , +3947 , +6363 , +13669 , +16697 , +-5179 , +-21499 , +2285 , +25379 , +-479 , +31097 , +7181 , +-14001 , +32343 , +21461 , +-13335 , +22285 , +23591 , +-27581 , +8123 , +343 , +-31179 , +23509 , +8211 , +-4761 , +-28797 , +25943 , +6269 , +7121 , +27487 , +32679 , +-17461 , +-2023 , +30695 , +18581 , +-23871 , +-23347 , +-28937 , +16433 , +7509 , +23575 , +21929 , +-13143 , +-12701 , +-17185 , +-32183 , +18079 , +2531 , +23639 , +20683 , +-23035 , +28067 , +29731 , +-8759 , +-6293 , +-21371 , +1245 , +-24589 , +-15899 , +1069 , +17725 , +-18415 , +-15021 , +21821 , +-19027 , +20337 , +31049 , +22033 , +-20387 , +-17177 , +-27555 , +-10257 , +-12837 , +-22467 , +-7167 , +-26937 , +-2507 , +-7115 , +-807 , +-29847 , +30337 , +14071 , +19355 , +14389 , +-3327 , +-14063 , +-24997 , +-6047 , +-29253 , +29415 , +-16781 , +22947 , +6537 , +-24397 , +12997 , +-14221 , +-20041 , +1275 , +-15701 , +-10559 , +-29161 , +-11901 , +-11971 , +17705 , +27553 , +-20787 , +10545 , +-2389 , +24961 , +10763 , +20785 , +14059 , +31413 , +-11877 , +179 , +-17695 , +-5085 , +-18435 , +-12969 , +21525 , +16179 , +-27315 , +-22351 , +-12721 , +18659 , +16185 , +18095 , +-4129 , +17765 , +-20619 , +1129 , +5189 , +-4051 , +20669 , +26495 , +22899 , +-3943 , +-13751 , +-12823 , +-10371 , +29429 , +443 , +26197 , +-9509 , +17959 , +-29785 , +2305 , +-26343 , +21945 , +17025 , +2315 , +22545 , +-10123 , +15385 , +-27057 , +32675 , +2941 , +-10865 , +-14403 , +-29201 , +-11801 , +3535 , +-6605 , +26123 , +4303 , +-6521 , +4049 , +-3779 , +8175 , +927 , +-13351 , +-30033 , +9921 , +16691 , +-22791 , +11689 , +-16889 , +30729 , +28723 , +-8629 , +-21005 , +10379 , +11817 , +17605 , +8367 , +17463 , +25853 , +-3315 , +8583 , +-12889 , +-15199 , +19733 , +-16273 , +-30985 , +-10311 , +-29819 , +-19925 , +26317 , +-13593 , +-12039 , +-15143 , +3009 , +-6991 , +-13907 , +275 , +-6553 , +-14901 , +-12863 , +-12411 , +20917 , +2553 , +-537 , +-1283 , +21001 , +24931 , +21155 , +-6381 , +12953 , +-17813 , +5629 , +-11473 , +-18063 , +-27635 , +-16451 , +-32211 , +10721 , +4267 , +-21471 , +7793 , +-12929 , +-7825 , +-23275 , +-19837 , +15263 , +-24031 , +-18965 , +3613 , +5955 , +-17029 , +16791 , +28623 , +31639 , +29187 , +-11425 , +-13555 , +-12563 , +3941 , +-24039 , +719 , +13359 , +1097 , +15845 , +-3931 , +21211 , +-11091 , +24667 , +-28593 , +-21127 , +-28487 , +22351 , +10197 , +16017 , +-7143 , +513 , +-15329 , +-27607 , +21979 , +-10023 , +-7667 , +8633 , +-12103 , +-2151 , +-25579 , +161 , +3073 , +-24031 , +13391 , +-10457 , +-4893 , +15257 , +21269 , +7657 , +30793 , +10291 , +-11749 , +31705 , +27957 , +-28321 , +27655 , +28849 , +8083 , +-31615 , +10369 , +1519 , +-21611 , +25647 , +-8997 , +-16817 , +6539 , +9187 , +-26347 , +31673 , +-30155 , +17977 , +22921 , +-27709 , +931 , +5533 , +-11021 , +-13657 , +-2423 , +3985 , +-16619 , +27831 , +5143 , +-1449 , +22465 , +15959 , +-29615 , +-25291 , +-24957 , +31351 , +19689 , +-27867 , +683 , +-26741 , +22675 , +12301 , +-6167 , +2815 , +-12573 , +-3971 , +-10395 , +-15567 , +-17249 , +27619 , +-19109 , +-28691 , +19609 , +16707 , +-11475 , +12635 , +28939 , +-2447 , +13821 , +17799 , +-25241 , +16835 , +-5691 , +-13241 , +-22347 , +-18863 , +-18187 , +31167 , +28779 , +19115 , +8319 , +-28843 , +21445 , +-19957 , +-10121 , +29483 , +8085 , +21 , +-14037 , +-16875 , +-32089 , +-28917 , +-15175 , +-2035 , +-23915 , +-24443 , +-8921 , +-17609 , +-5865 , +-20311 , +-20739 , +30027 , +-24091 , +-3099 , +30809 , +32665 , +-32497 , +-2271 , +21645 , +-14987 , +-22069 , +-9597 , +29741 , +-20163 , +19927 , +7835 , +-22089 , +-26685 , +32079 , +31773 , +8857 , +23121 , +16127 , +-16863 , +-23339 , +30485 , +-30397 , +5841 , +10519 , +16423 , +13147 , +-6485 , +10567 , +28915 , +30533 , +28205 , +31661 , +-9669 , +7183 , +25111 , +4729 , +23691 , +-8011 , +-9697 , +30695 , +-5837 , +16251 , +-28119 , +24279 , +-15945 , +8639 , +-2557 , +8157 , +-21033 , +-25517 , +-4205 , +31453 , +24565 , +19543 , +-4199 , +29991 , +-16355 , +27787 , +10469 , +-21493 , +21871 , +15155 , +30219 , +-3089 , +-31199 , +-14237 , +-7775 , +-25623 , +-6671 , +-15141 , +18669 , +11741 , +19237 , +26979 , +4395 , +777 , +-7689 , +3737 , +26423 , +-31449 , +-2409 , +-29355 , +465 , +29699 , +-21091 , +-131 , +-8629 , +1933 , +25353 , +-1707 , +-4153 , +18039 , +-6225 , +-11421 , +14577 , +26959 , +21815 , +7359 , +18479 , +-24049 , +-20329 , +-12817 , +-29089 , +8253 , +4869 , +21563 , +-30709 , +-22147 , +-28301 , +3467 , +12585 , +-24917 , +-25983 , +19639 , +-17589 , +-14987 , +765 , +32359 , +-425 , +-20875 , +30937 , +-31127 , +-25661 , +4029 , +-27487 , +-4733 , +19533 , +-5121 , +16751 , +-2095 , +20529 , +-8677 , +-19603 , +15263 , +31201 , +24889 , +-23357 , +-12105 , +-13507 , +28001 , +4377 , +-20413 , +7499 , +16533 , +10115 , +23845 , +-13709 , +-21403 , +-21755 , +27847 , +-11475 , +-16369 , +31105 , +2167 , +30023 , +9997 , +28983 , +-189 , +-21103 , +5167 , +27833 , +-32695 , +-25575 , +4411 , +-29343 , +5529 , +17127 , +-29953 , +-29617 , +-2173 , +-26833 , +29157 , +18907 , +20597 , +23819 , +-14571 , +21391 , +-30381 , +-14921 , +28163 , +-26461 , +13899 , +18495 , +6797 , +1261 , +-17361 , +-21309 , +-19565 , +14945 , +18003 , +-15829 , +525 , +8453 , +9431 , +-18859 , +1185 , +-31385 , +11153 , +-30495 , +-16447 , +32153 , +10579 , +-28589 , +-7619 , +-13143 , +4047 , +-30245 , +5725 , +-875 , +-7185 , +11143 , +22397 , +26313 , +3745 , +-20229 , +9247 , +-7409 , +9793 , +23209 , +-7035 , +21775 , +-14237 , +22411 , +24011 , +-12223 , +-25555 , +4439 , +-30339 , +-30101 , +5429 , +21307 , +-22099 , +21647 , +3795 , +17173 , +-3693 , +-11661 , +-10239 , +-23257 , +-25955 , +10373 , +-14425 , +25171 , +-16891 , +22631 , +-3715 , +-14127 , +-13581 , +983 , +4959 , +32615 , +-3825 , +-12751 , +21283 , +-23775 , +22423 , +5217 , +-6921 , +1933 , +30973 , +13151 , +12851 , +4457 , +31477 , +5413 , +-26441 , +9193 , +-9443 , +15399 , +23227 , +6245 , +18435 , +1359 , +-10449 , +-18291 , +-311 , +22637 , +-23923 , +-19661 , +-31429 , +32565 , +-26571 , +877 , +6243 , +23221 , +31811 , +16991 , +-22621 , +-20655 , +17895 , +-9369 , +-19375 , +-16591 , +-21953 , +-25893 , +-4663 , +-5305 , +-83 , +-28865 , +-7673 , +-27975 , +4525 , +-19201 , +-25921 , +-5917 , +-715 , +25765 , +32507 , +-1589 , +-21119 , +-1137 , +20773 , +-27369 , +4469 , +-18643 , +-24145 , +22415 , +-24205 , +15027 , +-29153 , +-29949 , +19887 , +-18603 , +9387 , +5333 , +27911 , +12029 , +17495 , +10983 , +-15259 , +-13947 , +20865 , +1813 , +16009 , +-19351 , +-26875 , +20783 , +27753 , +-31481 , +-21559 , +30575 , +26121 , +-27307 , +-19229 , +-21135 , +9169 , +21267 , +-9179 , +-13909 , +-6045 , +-1651 , +-11463 , +-18073 , +-11525 , +-21047 , +-17605 , +-15561 , +12859 , +30019 , +18641 , +20467 , +-20593 , +-213 , +31933 , +29229 , +-5381 , +-18415 , +-14079 , +-7131 , +-24709 , +8231 , +-1435 , +-19381 , +-6187 , +-9225 , +-16731 , +22575 , +-17419 , +30613 , +7923 , +24059 , +16069 , +21599 , +-14559 , +29803 , +-2947 , +-18127 , +28975 , +329 , +31115 , +32027 , +19813 , +-417 , +-11813 , +17569 , +-16661 , +21745 , +-5963 , +-13977 , +17635 , +28597 , +22811 , +9331 , +-6145 , +15183 , +5781 , +-27935 , +1177 , +19779 , +3733 , +-21219 , +-14005 , +26989 , +23109 , +-30569 , +16905 , +7683 , +6375 , +-17411 , +18361 , +-20997 , +-30041 , +-16905 , +11333 , +535 , +-31751 , +-27047 , +31545 , +-10161 , +-11927 , +23003 , +-22819 , +-5681 , +-23559 , +26717 , +-1595 , +16235 , +-25095 , +-6775 , +-23313 , +27805 , +-26531 , +25631 , +16987 , +-5899 , +-18283 , +15269 , +-23519 , +16411 , +-4377 , +-32609 , +18439 , +20541 , +30017 , +5957 , +18335 , +20237 , +26265 , +-10049 , +7385 , +-12997 , +1731 , +17119 , +4893 , +28771 , +-11579 , +-21935 , +-17177 , +-25713 , +-3663 , +26457 , +17881 , +-16853 , +7681 , +-2807 , +-1707 , +-32385 , +-24729 , +31483 , +-10857 , +-29531 , +27947 , +-18043 , +-31925 , +5885 , +4357 , +-12171 , +-30299 , +305 , +25195 , +-10167 , +5881 , +-21343 , +-19849 , +-14877 , +13781 , +18783 , +-32721 , +-28477 , +-14695 , +-11607 , +19823 , +5061 , +5511 , +29153 , +-21457 , +-24501 , +25961 , +32766 , +7271 , +-17401 , +18077 , +-8815 , +-11673 , +287 , +4789 , +-9937 , +-603 , +-26377 , +25733 , +23667 , +-22497 , +18785 , +-6965 , +-26765 , +-14799 , +-29613 , +17205 , +-7499 , +-28951 , +-21981 , +-19451 , +4011 , +-19233 , +20027 , +-13785 , +-8277 , +-26731 , +-29097 , +1477 , +-9889 , +1353 , +-9159 , +-4253 , +13517 , +-23223 , +-9763 , +6003 , +5567 , +-23855 , +-30659 , +-11661 , +-13117 , +-20377 , +-14213 , +2429 , +22177 , +-1115 , +-22621 , +-2197 , +-11691 , +10655 , +27871 , +10849 , +9607 , +-3149 , +-7635 , +-24085 , +-30853 , +31975 , +-12389 , +24987 , +10901 , +-2117 , +8449 , +20503 , +-17331 , +-19327 , +-20943 , +-17739 , +-3169 , +12347 , +7605 , +21913 , +-6641 , +15343 , +-9723 , +4161 , +23323 , +-11137 , +-28351 , +-26967 , +-10705 , +-15613 , +14183 , +-10535 , +-28889 , +-25187 , +775 , +25345 , +4417 , +16595 , +23689 , +2073 , +-18289 , +22891 , +14289 , +28905 , +-14851 , +5823 , +-12151 , +11693 , +16831 , +-25201 , +16593 , +-2005 , +25675 , +21355 , +-5519 , +-29625 , +-16945 , +-25997 , +10911 , +-4835 , +-11213 , +5575 , +20523 , +28317 , +28545 , +3657 , +19517 , +23451 , +19691 , +4105 , +5517 , +-28559 , +28731 , +22541 , +13847 , +-7669 , +-13361 , +10931 , +31575 , +-22133 , +30477 , +-21887 , +16637 , +19545 , +11107 , +18311 , +20013 , +6333 , +16305 , +24367 , +-17109 , +20217 , +-9649 , +9367 , +-6755 , +-20769 , +-28285 , +26987 , +-16065 , +25065 , +12909 , +24377 , +-15589 , +-26159 , +-6515 , +-5809 , +-26299 , +-17491 , +28595 , +-26867 , +-12023 , +28541 , +-19843 , +-8513 , +-10835 , +27729 , +18247 , +-20233 , +16809 , +22741 , +18861 , +-925 , +-1451 , +-26515 , +7799 , +14887 , +3627 , +23759 , +26651 , +-25935 , +-12935 , +-11239 , +-7757 , +-5357 , +5539 , +-13461 , +22641 , +-13599 , +18119 , +-25091 , +31641 , +19069 , +-9201 , +-14155 , +-17669 , +-30217 , +7761 , +-1467 , +-5141 , +28775 , +-5803 , +-2115 , +-4939 , +5055 , +-1139 , +11687 , +-361 , +-5853 , +-14267 , +17819 , +3643 , +21961 , +17503 , +-26531 , +-23889 , +-18361 , +-23151 , +-11153 , +-21801 , +-32141 , +-29677 , +-20179 , +-7825 , +31667 , +-28967 , +1635 , +-135 , +-15395 , +-23979 , +8293 , +30013 , +-20853 , +20899 , +-22361 , +-7751 , +3827 , +16965 , +-1321 , +161 , +3135 , +-1445 , +15987 , +18131 , +5735 , +24929 , +7395 , +-6831 , +4999 , +-3239 , +27659 , +27315 , +23989 , +7827 , +-23189 , +-17623 , +-22177 , +-15399 , +-32331 , +-26905 , +27679 , +20781 , +-28449 , +26411 , +-9199 , +28417 , +9921 , +-30297 , +8111 , +-18453 , +29743 , +-11643 , +-14807 , +29407 , +9355 , +31955 , +8249 , +-14357 , +22493 , +16777 , +-28289 , +26473 , +20849 , +-13069 , +29271 , +7099 , +-19735 , +19123 , +-26063 , +15741 , +-25637 , +16437 , +10861 , +-32183 , +-31261 , +28071 , +-20055 , +7649 , +13629 , +-4749 , +16291 , +-21009 , +-27169 , +18993 , +-32367 , +-6079 , +-8947 , +-15573 , +32495 , +-31887 , +-14471 , +30533 , +3809 , +21043 , +19407 , +-20859 , +-25079 , +2297 , +-26153 , +-1537 , +23771 , +-22987 , +-16889 , +25169 , +28279 , +-2795 , +-15965 , +23713 , +12289 , +8879 , +-24757 , +-16887 , +12415 , +-8765 , +-7147 , +26007 , +-3801 , +-1811 , +21807 , +-11063 , +1593 , +1891 , +29161 , +28279 , +-20385 , +-5083 , +10839 , +-27557 , +-31109 , +-11331 , +-23965 , +23291 , +18441 , +-28557 , +22889 , +3119 , +28653 , +-12027 , +-29105 , +12297 , +-24627 , +10719 , +14361 , +21595 , +31733 , +26837 , +27395 , +19113 , +3995 , +11095 , +-32227 , +5279 , +20935 , +12077 , +-6821 , +14097 , +-7515 , +21935 , +-15305 , +-21659 , +-26273 , +-11911 , +-25411 , +10139 , +-1425 , +30373 , +-6353 , +-2885 , +11903 , +-23161 , +-16875 , +3021 , +-28229 , +-14367 , +-9513 , +-20135 , +29617 , +-10091 , +-16681 , +18259 , +8093 , +-4627 , +24839 , +-29283 , +-15031 , +15939 , +14337 , +2301 , +23143 , +-26815 , +-1887 , +-14189 , +3169 , +-16485 , +-7913 , +16843 , +23225 , +-17605 , +-6005 , +31463 , +29149 , +27149 , +-21721 , +15327 , +-8581 , +31009 , +27319 , +32241 , +12645 , +7797 , +-1085 , +-11899 , +-21539 , +-26847 , +-2273 , +-3405 , +-29585 , +-8173 , +2059 , +17457 , +5201 , +-24243 , +-20797 , +26835 , +-8907 , +-15469 , +20385 , +-19585 , +-26725 , +-22361 , +-6485 , +-23135 , +-13897 , +32261 , +14259 , +13361 , +-22849 , +-24045 , +-11543 , +2839 , +-26941 , +-27677 , +-14857 , +-30925 , +-30965 , +25951 , +20885 , +-24879 , +-25879 , +10255 , +31655 , +28827 , +21783 , +19521 , +-10801 , +-20199 , +-11897 , +27345 , +20617 , +-20829 , +10179 , +29015 , +29377 , +9181 , +-29251 , +-22305 , +-12821 , +-28497 , +21299 , +-28891 , +1691 , +20919 , +19831 , +-1457 , +18849 , +11851 , +-13353 , +32539 , +-31337 , +-27419 , +-21399 , +-28251 , +16647 , +15913 , +-22169 , +22671 , +25845 , +28241 , +30475 , +-21817 , +-11263 , +-29399 , +-13857 , +12219 , +9725 , +19591 , +-8801 , +6667 , +24575 , +5449 , +-27511 , +29897 , +255 , +-3389 , +-14539 , +31531 , +15089 , +-19269 , +-8975 , +-3387 , +-20393 , +32740 , +17563 , +69 , +-29095 , +-31539 , +-6671 , +28323 , +23395 , +5485 , +9069 , +-7963 , +21049 , +-12033 , +-31581 , +-6587 , +-24179 , +7827 , +-24305 , +26875 , +26653 , +-21005 , +25457 , +28525 , +-15035 , +14123 , +15785 , +-22557 , +-10725 , +12405 , +25867 , +-18741 , +-2301 , +-19785 , +-20687 , +-16545 , +8655 , +17527 , +10083 , +7921 , +-16309 , +-15523 , +-2975 , +-11625 , +-13473 , +9241 , +-22851 , +32611 , +-29023 , +16621 , +-30791 , +-27363 , +-6027 , +28313 , +157 , +-31871 , +24219 , +4063 , +-19833 , +31213 , +-8375 , +-8343 , +22225 , +-22115 , +-31027 , +10323 , +-35 , +-32155 , +16791 , +-23273 , +-11663 , +-7703 , +-23845 , +15631 , +-12395 , +-21167 , +-14429 , +22627 , +-14627 , +-12923 , +-24979 , +645 , +2385 , +1507 , +27449 , +-27857 , +-2887 , +-25225 , +-8143 , +5581 , +-4227 , +21171 , +-23887 , +10117 , +-4875 , +-28245 , +-27419 , +-31835 , +4683 , +25797 , +-17437 , +-2403 , +-27703 , +6137 , +6725 , +-4233 , +25271 , +1665 , +22327 , +26575 , +-15437 , +-29925 , +-30181 , +23119 , +25987 , +-30023 , +665 , +32673 , +4217 , +-28229 , +25913 , +-30233 , +-31173 , +-1111 , +-2945 , +-26947 , +-21975 , +7527 , +24185 , +4001 , +-30161 , +-5649 , +-6429 , +-20233 , +24603 , +2449 , +17847 , +-4223 , +9083 , +-9319 , +4683 , +29773 , +-15377 , +23191 , +4833 , +-6345 , +-23549 , +23317 , +18629 , +-16415 , +27785 , +7363 , +4323 , +21791 , +-12175 , +-22979 , +12515 , +-7427 , +22811 , +-7361 , +10425 , +-16589 , +-11465 , +-683 , +-24379 , +29721 , +29719 , +-6367 , +19555 , +-1505 , +20367 , +-28155 , +6413 , +-14387 , +13889 , +-14745 , +489 , +-4047 , +-27521 , +5729 , +24553 , +2013 , +27037 , +-7431 , +3677 , +2145 , +-4145 , +-5153 , +15375 , +-5577 , +3193 , +24995 , +16599 , +11597 , +8465 , +-3483 , +20409 , +2031 , +21615 , +-14055 , +23929 , +29761 , +-4957 , +-2247 , +5039 , +-11203 , +-11943 , +16637 , +10345 , +25641 , +-12635 , +-15343 , +-3525 , +13193 , +-20383 , +28881 , +-28455 , +-9059 , +-12795 , +-12799 , +-32205 , +-19877 , +7927 , +-253 , +-1021 , +-25377 , +28529 , +-31601 , +-7693 , +23659 , +-12849 , +-20501 , +-20441 , +27349 , +-14233 , +16549 , +12895 , +13199 , +-27673 , +9415 , +24461 , +-9711 , +-19927 , +-11373 , +12775 , +18129 , +12681 , +15033 , +-11385 , +-19769 , +7363 , +-18927 , +-2179 , +26969 , +13123 , +2513 , +-18581 , +-1831 , +-32251 , +-10427 , +-12899 , +-30341 , +-2839 , +-31737 , +-31843 , +-27953 , +30859 , +2999 , +11599 , +-22603 , +-15203 , +-19403 , +-30587 , +-28457 , +26297 , +7255 , +-9955 , +28071 , +9667 , +-25311 , +6547 , +5067 , +21945 , +30081 , +6173 , +25889 , +13323 , +-18307 , +-10175 , +-11221 , +-7043 , +30197 , +4333 , +-12525 , +9837 , +5593 , +7951 , +18715 , +23231 , +24031 , +17583 , +6811 , +-3545 , +6583 , +-29565 , +28527 , +-9211 , +-8755 , +10767 , +-1029 , +3519 , +-9093 , +-20941 , +12445 , +-17769 , +17853 , +-6073 , +9121 , +21507 , +10611 , +-13389 , +27075 , +-5495 , +21519 , +12815 , +-27361 , +1805 , +7637 , +-11865 , +-27989 , +-27467 , +-23411 , +16557 , +-25039 , +-3273 , +26559 , +23735 , +1221 , +-13891 , +-16537 , +-4371 , +28093 , +-19923 , +9525 , +-7021 , +-7639 , +21773 , +-14279 , +-3035 , +19147 , +3545 , +25383 , +1779 , +-25453 , +-20519 , +-13051 , +16179 , +27537 , +-31883 , +15465 , +-3429 , +7279 , +5145 , +-19149 , +29049 , +27755 , +-6529 , +-26437 , +-3505 , +-30773 , +-20591 , +-12139 , +31205 , +26331 , +9149 , +-29761 , +6117 , +-22177 , +-2355 , +1637 , +20461 , +-22385 , +9277 , +21511 , +1841 , +-2165 , +6173 , +-23483 , +-12661 , +2649 , +-12199 , +-1529 , +-7913 , +15191 , +-29027 , +-12995 , +-20667 , +-6347 , +12973 , +-28901 , +20093 , +-10383 , +-10959 , +-30525 , +-23255 , +-19639 , +-17633 , +3211 , +-21673 , +-20685 , +14723 , +29101 , +-26677 , +13021 , +-24097 , +-11643 , +20891 , +-21093 , +-12539 , +1343 , +-441 , +20839 , +27237 , +-14565 , +1099 , +-5037 , +-32269 , +-28127 , +23105 , +-26493 , +-31121 , +5457 , +31343 , +31399 , +19021 , +-14491 , +-11545 , +18163 , +6403 , +-29689 , +2587 , +-15215 , +32481 , +-7291 , +-4113 , +1957 , +-9871 , +-25331 , +29539 , +-26189 , +18497 , +-31901 , +29845 , +18601 , +5709 , +-997 , +-13463 , +-11183 , +13255 , +4425 , +23195 , +12865 , +-10119 , +-8757 , +-30889 , +-24483 , +-6505 , +-11287 , +-4783 , +15819 , +9753 , +-10589 , +-22689 , +25197 , +-3943 , +-25253 , +1163 , +27861 , +26015 , +23059 , +439 , +16065 , +-16511 , +6691 , +24485 , +8211 , +-8001 , +-9871 , +-21087 , +16451 , +-20019 , +-16343 , +8325 , +-29089 , +26489 , +-32007 , +-29083 , +8065 , +18875 , +24001 , +26263 , +-9279 , +4883 , +-24367 , +-427 , +-22093 , +-32681 , +18593 , +2511 , +-12193 , +10523 , +-26617 , +-26167 , +-14407 , +14455 , +11501 , +30123 , +12177 , +7787 , +-30831 , +10785 , +9497 , +-11855 , +31791 , +-23505 , +-20783 , +-17891 , +-30901 , +-20281 , +30469 , +-9365 , +31833 , +14567 , +-29501 , +22685 , +-30977 , +-28117 , +25429 , +-6193 , +-2363 , +-17431 , +-14285 , +20117 , +-12969 , +-7993 , +1927 , +32463 , +-30925 , +-2861 , +-2283 , +27647 , +5865 , +-14309 , +8131 , +12583 , +-30003 , +26055 , +-17019 , +-24807 , +21811 , +6061 , +-12839 , +-13479 , +-20699 , +-6541 , +-6971 , +-18583 , +3485 , +-4589 , +65 , +-22353 , +8503 , +24331 , +4673 , +18623 , +22643 , +-31773 , +31005 , +9789 , +23649 , +-23731 , +7823 , +-20945 , +32746 , +5821 , +29999 , +13789 , +-26255 , +28029 , +3177 , +11547 , +16159 , +-2997 , +-3347 , +4401 , +-8811 , +31081 , +-24653 , +14377 , +-24293 , +-23235 , +-26261 , +3239 , +-22169 , +-16541 , +-27527 , +-11707 , +32715 , +14411 , +16233 , +-30099 , +18413 , +-12469 , +30191 , +4521 , +-23805 , +-21191 , +4689 , +3457 , +-17013 , +19331 , +5487 , +-15661 , +32641 , +32715 , +23857 , +27815 , +22295 , +-31751 , +-24193 , +11145 , +-27157 , +21207 , +-4161 , +9573 , +-10041 , +12579 , +23753 , +-4645 , +29137 , +-17615 , +9567 , +-12525 , +19777 , +20219 , +-2781 , +2845 , +18597 , +10941 , +-29675 , +-21049 , +29835 , +6153 , +31367 , +1777 , +14535 , +-1181 , +11155 , +25959 , +-11493 , +8279 , +-2535 , +10813 , +10363 , +-26095 , +27695 , +-13155 , +24773 , +-28551 , +-24283 , +-6611 , +17651 , +-11835 , +-25109 , +-8229 , +-10287 , +-32625 , +-17379 , +22331 , +8511 , +13947 , +8045 , +-11171 , +-23581 , +29501 , +1441 , +-6107 , +30049 , +-20417 , +9477 , +19237 , +28945 , +-3921 , +-11921 , +5361 , +32061 , +9759 , +8107 , +-23555 , +23251 , +16791 , +-16519 , +19951 , +-2143 , +18741 , +-15361 , +28793 , +-17653 , +18999 , +4813 , +-1355 , +-15037 , +32675 , +-20151 , +1779 , +-26367 , +-31407 , +-22357 , +-25313 , +10175 , +-4209 , +-18313 , +13711 , +-18325 , +7985 , +-28811 , +5209 , +-24417 , +-21973 , +-15581 , +5429 , +18527 , +12461 , +15799 , +-49 , +28747 , +-2381 , +23179 , +-869 , +12895 , +6689 , +26915 , +16951 , +-19169 , +-17053 , +-12647 , +-27847 , +2391 , +-397 , +32151 , +-23407 , +10835 , +4741 , +-807 , +1109 , +-26473 , +24079 , +-19433 , +-26333 , +-30959 , +-7829 , +-18553 , +20981 , +4825 , +-11799 , +-13875 , +7803 , +32099 , +-18579 , +-13185 , +-14351 , +-7873 , +-6529 , +22287 , +-15757 , +22851 , +-20757 , +-21429 , +-28961 , +4689 , +5845 , +-14761 , +-15065 , +16267 , +31311 , +-20197 , +24357 , +26885 , +-6279 , +-5305 , +23551 , +3331 , +-28917 , +1477 , +21485 , +2993 , +8573 , +14767 , +5287 , +-10919 , +28821 , +11467 , +-8661 , +-11495 , +11647 , +-25473 , +22553 , +543 , +7021 , +10065 , +-10345 , +14691 , +-29017 , +-4905 , +3475 , +4567 , +-28639 , +15403 , +-19021 , +-5849 , +32157 , +2293 , +23963 , +-2329 , +32315 , +24271 , +-9009 , +-5031 , +-23657 , +-29879 , +-27391 , +5785 , +3929 , +13917 , +4857 , +31581 , +-2733 , +8551 , +10203 , +-6107 , +-11751 , +-15203 , +4877 , +27645 , +-20969 , +-31993 , +-11129 , +13225 , +-15067 , +-21251 , +16301 , +16489 , +27307 , +2321 , +-6485 , +-3797 , +-32211 , +7061 , +30279 , +-10689 , +25705 , +-7025 , +-26055 , +-14441 , +-30485 , +19495 , +523 , +-19077 , +-13269 , +-2637 , +-24987 , +11203 , +-21985 , +-20197 , +-20749 , +-117 , +17749 , +17115 , +-18257 , +8047 , +-28017 , +-17795 , +-829 , +-447 , +-32553 , +3977 , +-30755 , +-28609 , +30225 , +15623 , +29191 , +21203 , +-2015 , +-27795 , +26367 , +22209 , +-9607 , +31001 , +3857 , +-15131 , +-14283 , +20821 , +28779 , +-10901 , +-32085 , +-15941 , +-7943 , +-20095 , +-21357 , +3647 , +-24385 , +14233 , +31119 , +-15459 , +-19289 , +6681 , +6731 , +26705 , +6625 , +20629 , +15637 , +27669 , +-5695 , +21383 , +31473 , +3539 , +-31229 , +6793 , +2359 , +28707 , +26043 , +21769 , +-30815 , +-27587 , +-25959 , +-10869 , +17139 , +29553 , +-22831 , +-22705 , +-15359 , +-4313 , +-17565 , +-14695 , +853 , +-12467 , +-2299 , +-3227 , +6461 , +-30891 , +-17047 , +-26981 , +-15765 , +-1619 , +-16607 , +12745 , +-28407 , +-3659 , +-13835 , +20827 , +8783 , +-29643 , +-1607 , +31065 , +12449 , +18009 , +24995 , +1171 , +-9693 , +-5335 , +-14809 , +28257 , +-3123 , +6015 , +32591 , +-291 , +-16115 , +-29573 , +7055 , +20883 , +-6183 , +2183 , +-9439 , +-20799 , +-1727 , +-8509 , +-25637 , +-20727 , +26263 , +1279 , +19847 , +8619 , +15093 , +-12227 , +-31045 , +-21181 , +29029 , +6045 , +21047 , +8947 , +16237 , +-2603 , +-13137 , +-981 , +11305 , +-7881 , +-21711 , +-1323 , +19437 , +21019 , +16885 , +25621 , +30799 , +-20521 , +9147 , +-12935 , +-9015 , +-17341 , +-3685 , +-2889 , +-20533 , +13733 , +29541 , +-26135 , +28761 , +-6353 , +-28557 , +-11209 , +-32742 , +-8203 , +16645 , +-9955 , +29183 , +2149 , +4117 , +-20965 , +-6843 , +-12733 , +17849 , +-17165 , +17697 , +7961 , +20969 , +-15785 , +17617 , +26931 , +-28697 , +3887 , +28721 , +-9441 , +-1515 , +-27579 , +-22311 , +-26221 , +-6591 , +-20351 , +-6231 , +9207 , +25229 , +14757 , +6901 , +-24749 , +19131 , +-18561 , +30985 , +16329 , +-20979 , +18851 , +8015 , +-30575 , +-25195 , +12197 , +21979 , +-26009 , +-1257 , +27599 , +20367 , +18575 , +24663 , +30809 , +-16725 , +11333 , +-18699 , +-30943 , +5611 , +28347 , +-26419 , +17385 , +-12777 , +-32377 , +4285 , +-28417 , +-30685 , +32167 , +-11251 , +13961 , +25535 , +24817 , +-29627 , +-975 , +25207 , +-7665 , +18809 , +9563 , +12105 , +4853 , +-19149 , +-14361 , +8887 , +-30249 , +7607 , +-2719 , +-9369 , +18601 , +-3601 , +11965 , +17207 , +6923 , +-14923 , +6795 , +22739 , +-23859 , +30383 , +-2637 , +-27181 , +-13601 , +-30295 , +-18771 , +18763 , +-10037 , +22637 , +23349 , +-16657 , +-11089 , +10259 , +22661 , +-30053 , +32689 , +-16407 , +-23021 , +-12165 , +-28419 , +-26437 , +23227 , +-7789 , +28983 , +15537 , +21639 , +1257 , +11383 , +-4179 , +-7461 , +-15093 , +-11587 , +14359 , +-5325 , +-26059 , +-273 , +24639 , +-32679 , +18659 , +-17335 , +-30669 , +25631 , +-13081 , +-32159 , +24595 , +27541 , +10501 , +32655 , +8941 , +15809 , +-3319 , +-5647 , +-5617 , +25813 , +-2975 , +-28959 , +-3861 , +10735 , +-18639 , +22763 , +-7839 , +13125 , +22511 , +1091 , +-16223 , +23787 , +29563 , +-17981 , +-27521 , +-15363 , +-30285 , +-14245 , +22859 , +31841 , +-21363 , +13587 , +24619 , +-5895 , +-11341 , +22907 , +-21013 , +11873 , +-21357 , +18595 , +29287 , +-18399 , +16127 , +12951 , +12365 , +18533 , +15937 , +32345 , +-21115 , +-30145 , +24241 , +-11695 , +17409 , +-25009 , +-30763 , +-15539 , +-21733 , +-26101 , +15083 , +25073 , +-11933 , +29033 , +1555 , +24249 , +-8441 , +17187 , +23509 , +-921 , +-1897 , +32613 , +-22713 , +-30463 , +-9615 , +-7925 , +-2913 , +-27319 , +-7033 , +-20133 , +1607 , +-23887 , +-20795 , +20019 , +11905 , +32727 , +-16923 , +27343 , +-14991 , +2941 , +28863 , +753 , +-27715 , +-27141 , +-16853 , +30889 , +2471 , +-26305 , +-9383 , +-11135 , +-25955 , +-189 , +25247 , +-24517 , +5463 , +-20739 , +4827 , +21511 , +20591 , +-26649 , +-16567 , +-12737 , +887 , +-3101 , +-30763 , +-12907 , +9357 , +-2107 , +-3587 , +-6697 , +-23935 , +-21949 , +-1507 , +-6369 , +-11431 , +6505 , +-19117 , +12173 , +28539 , +-22887 , +-25647 , +-8317 , +28987 , +-24323 , +5043 , +26707 , +-20237 , +-6521 , +21593 , +28037 , +-27231 , +-15521 , +14915 , +28801 , +-19973 , +-14371 , +9059 , +16083 , +-23033 , +-13045 , +27641 , +-25893 , +7475 , +-8307 , +-23579 , +5895 , +16621 , +18729 , +5261 , +-25719 , +30653 , +28849 , +-20703 , +-29031 , +-14115 , +-14199 , +-1149 , +5919 , +-17335 , +-31857 , +8089 , +29169 , +3941 , +18595 , +-26843 , +-11885 , +5641 , +-25453 , +-19425 , +-16289 , +8223 , +14999 , +32649 , +32073 , +-17479 , +4941 , +4809 , +19221 , +11179 , +10797 , +389 , +10765 , +-5471 , +2429 , +-5131 , +-3019 , +-27981 , +1235 , +-11841 , +21517 , +395 , +517 , +15691 , +-29247 , +4329 , +163 , +-8287 , +-27933 , +-17461 , +6129 , +-19271 , +22695 , +2051 , +9051 , +18525 , +-5997 , +-29631 , +-10891 , +13173 , +9151 , +-5439 , +26981 , +27117 , +-20347 , +6225 , +-21781 , +28929 , +2757 , +-14351 , +-29491 , +5655 , +11917 , +-11545 , +1497 , +-16865 , +-10913 , +-2723 , +27727 , +-6813 , +-16927 , +-18569 , +2025 , +-6175 , +-2533 , +-9501 , +4679 , +-21979 , +-24537 , +9469 , +-8719 , +15005 , +10607 , +-8863 , +23489 , +887 , +27749 , +-9983 , +-18711 , +-23311 , +-19271 , +27073 , +16231 , +4155 , +7695 , +2703 , +23289 , +-1339 , +17725 , +8179 , +-19305 , +16925 , +-15361 , +-23239 , +25195 , +22599 , +28459 , +7665 , +14923 , +20625 , +-12427 , +-23523 , +3249 , +-23315 , +-13159 , +27323 , +-465 , +19407 , +797 , +-29471 , +-18583 , +13945 , +-17277 , +-32423 , +-23663 , +-12325 , +517 , +2737 , +-2729 , +-27667 , +-15923 , +-1061 , +-21911 , +22401 , +32427 , +-22207 , +17765 , +22683 , +-32183 , +24157 , +30295 , +-20655 , +2543 , +-20529 , +27049 , +14105 , +26027 , +509 , +-2655 , +-30553 , +-32231 , +7199 , +24155 , +7237 , +-11119 , +8165 , +-6085 , +11431 , +8669 , +-17025 , +-3869 , +29255 , +6015 , +-957 , +-14665 , +20283 , +12117 , +28609 , +-2357 , +-31859 , +-10781 , +12629 , +18777 , +533 , +19201 , +30277 , +9413 , +-561 , +13589 , +6743 , +-28919 , +-14415 , +24269 , +-2323 , +-31313 , +-27383 , +-26797 , +24213 , +-7085 , +-14767 , +11529 , +-27353 , +-28275 , +-14715 , +-1345 , +-25507 , +10865 , +6911 , +32623 , +11497 , +-7031 , +-17457 , +-1941 , +13323 , +-8635 , +19599 , +-2527 , +-21075 , +-27145 , +19903 , +25417 , +13051 , +-16557 , +-8549 , +30375 , +5497 , +12117 , +10099 , +-30919 , +24219 , +5835 , +1157 , +15095 , +-29733 , +17221 , +2387 , +2049 , +24409 , +-24953 , +29817 , +-32665 , +-25369 , +-23407 , +11277 , +24653 , +2989 , +2055 , +23147 , +-10567 , +-27591 , +15663 , +-15465 , +181 , +-11495 , +9071 , +27411 , +3865 , +-2059 , +-31429 , +-24013 , +3765 , +18727 , +-22893 , +5877 , +-13545 , +9163 , +-26119 , +-1181 , +-15437 , +-12187 , +-27671 , +-8867 , +-21587 , +1005 , +-2861 , +18169 , +27647 , +25965 , +16785 , +-16549 , +8253 , +-4073 , +-15779 , +17419 , +1483 , +-30241 , +81 , +-11571 , +-10863 , +-22895 , +-9899 , +7161 , +-32715 , +20327 , +25243 , +-2733 , +-15143 , +26405 , +20891 , +-23193 , +-26041 , +-32079 , +9095 , +-24743 , +-7503 , +11817 , +-17601 , +-14523 , +25067 , +-2439 , +-21039 , +-10479 , +28187 , +3961 , +-2703 , +-1079 , +21239 , +-4481 , +17125 , +17271 , +-8321 , +-20101 , +-23153 , +-3211 , +5675 , +-21875 , +-15917 , +24397 , +30639 , +-6117 , +19995 , +22539 , +-8149 , +4463 , +3663 , +-13283 , +28389 , +28621 , +1475 , +-20579 , +28805 , +31747 , +6075 , +-15045 , +-15421 , +-14193 , +-12711 , +24449 , +-20307 , +-24535 , +-32738 , +-19775 , +-21933 , +12517 , +-29733 , +-12457 , +-3323 , +-25657 , +-7383 , +-9071 , +-25849 , +-16165 , +-25751 , +-21501 , +-11825 , +8143 , +-17101 , +15705 , +439 , +-23289 , +2641 , +19125 , +-20935 , +-17605 , +-3525 , +30087 , +-29529 , +31111 , +27913 , +11235 , +-12451 , +17931 , +-2837 , +-8613 , +7039 , +-15107 , +22055 , +-25009 , +8499 , +27719 , +-29297 , +-17197 , +20049 , +-27753 , +28021 , +-32261 , +-27741 , +22783 , +16675 , +-27459 , +-19303 , +12809 , +9947 , +11067 , +6525 , +-32433 , +22595 , +-25687 , +-25547 , +2195 , +6509 , +26017 , +18291 , +-28843 , +-31173 , +19445 , +-32655 , +-27147 , +-2457 , +-26867 , +-27867 , +27963 , +12277 , +6081 , +6399 , +-30083 , +8237 , +679 , +12825 , +28721 , +21263 , +15353 , +2295 , +771 , +-7859 , +11229 , +-26437 , +-23695 , +3267 , +-19633 , +11741 , +-7199 , +17271 , +22887 , +-26269 , +13113 , +-16131 , +18751 , +-29031 , +21499 , +-31097 , +14401 , +9037 , +-2091 , +-7861 , +-13047 , +-5505 , +22463 , +14213 , +-24907 , +-24161 , +8341 , +21477 , +25789 , +-6075 , +-29661 , +-6249 , +28495 , +-1433 , +-305 , +31403 , +41 , +-6895 , +417 , +-31979 , +-25625 , +11675 , +-3865 , +-9691 , +-5143 , +25449 , +14145 , +18553 , +18589 , +-27623 , +27973 , +24705 , +-31649 , +6721 , +13709 , +24425 , +3797 , +-16729 , +11607 , +19609 , +2233 , +-23565 , +-13925 , +4013 , +24639 , +-2833 , +30875 , +-19221 , +-29211 , +-12993 , +-8185 , +-26565 , +2513 , +21645 , +-28787 , +-20833 , +4515 , +-31665 , +-11 , +-22995 , +-10547 , +-28679 , +14009 , +5255 , +-21135 , +26551 , +-6635 , +27595 , +21431 , +19869 , +25005 , +-4585 , +-5731 , +-2707 , +16281 , +22395 , +-20131 , +9925 , +-509 , +30321 , +12343 , +22999 , +-31425 , +27349 , +-14377 , +18087 , +-8611 , +-15523 , +24605 , +-8517 , +-2487 , +12691 , +14723 , +-22177 , +-15007 , +3147 , +32752 , +-1457 , +-19575 , +22681 , +-18935 , +-1291 , +-28477 , +-28335 , +-28391 , +-473 , +-1457 , +-6925 , +23897 , +5719 , +-31687 , +8751 , +-32051 , +26187 , +32633 , +2773 , +17061 , +9305 , +-19323 , +17743 , +17671 , +-14305 , +-5523 , +-23397 , +3953 , +23225 , +-28047 , +-321 , +-1143 , +24953 , +28695 , +18887 , +-14721 , +23327 , +-27189 , +14135 , +20701 , +18321 , +-29205 , +1541 , +-22813 , +12821 , +2157 , +-15595 , +-5799 , +13831 , +-6937 , +-20437 , +12015 , +-2541 , +-3785 , +2405 , +-2541 , +-535 , +13455 , +-7885 , +16195 , +1655 , +7955 , +19155 , +-6161 , +-27483 , +30193 , +-29887 , +24009 , +-5497 , +21491 , +-30537 , +17051 , +-15593 , +5791 , +12449 , +6315 , +-12177 , +-28723 , +3091 , +-28793 , +29825 , +21433 , +-17721 , +-30367 , +-21433 , +31651 , +-29555 , +28909 , +-23159 , +-19231 , +-3763 , +-2131 , +-2293 , +-2947 , +-2185 , +-11053 , +-3259 , +-22715 , +-28423 , +-25453 , +3489 , +-18835 , +-10555 , +18431 , +-13779 , +14491 , +695 , +-31391 , +12247 , +10121 , +22553 , +26889 , +13603 , +-3555 , +-19815 , +-26961 , +8035 , +17143 , +-3141 , +31561 , +19569 , +-11375 , +1753 , +-20643 , +24291 , +-23589 , +-19559 , +6625 , +17607 , +28229 , +-2337 , +-5233 , +4315 , +-20377 , +6733 , +2749 , +7745 , +8205 , +16949 , +1973 , +30395 , +-6955 , +-21995 , +12687 , +-3231 , +28229 , +18319 , +-7289 , +4057 , +15971 , +3035 , +-23853 , +-6129 , +-32559 , +31687 , +9473 , +22639 , +-14755 , +-10707 , +-10549 , +-18275 , +-17119 , +-32541 , +-1171 , +10407 , +15635 , +-3007 , +-895 , +-5947 , +-32475 , +-8947 , +599 , +-19571 , +-6949 , +-21253 , +27849 , +-27991 , +-417 , +20891 , +17561 , +9749 , +27929 , +18911 , +15679 , +-10797 , +13519 , +-11769 , +24397 , +-6623 , +-715 , +24095 , +-3263 , +-6603 , +3591 , +6901 , +-15139 , +29043 , +24479 , +-21103 , +22271 , +-17625 , +-26603 , +-5839 , +8185 , +-9031 , +19665 , +-19529 , +26217 , +24173 , +24733 , +-12115 , +-10605 , +-3445 , +-10679 , +-13641 , +26681 , +-9425 , +-4163 , +-19577 , +-21265 , +-3481 , +-3693 , +-3487 , +7925 , +-13057 , +25383 , +-9981 , +-30575 , +-4177 , +9021 , +14125 , +7141 , +-28969 , +10509 , +-23413 , +21319 , +-12107 , +18915 , +-18117 , +12827 , +2585 , +-9427 , +-4939 , +-471 , +-4693 , +-30431 , +21329 , +2421 , +9615 , +14795 , +-3525 , +-23401 , +20401 , +21669 , +-7709 , +-11885 , +-11157 , +18099 , +-2305 , +-12491 , +-28723 , +-25827 , +10755 , +5345 , +-15033 , +-32707 , +29969 , +-10507 , +21995 , +4417 , +24693 , +-21613 , +-20191 , +15425 , +-2653 , +26633 , +30689 , +-25389 , +20641 , +-12639 , +19049 , +8999 , +-30705 , +9461 , +-18321 , +-8291 , +9107 , +19151 , +-13333 , +-13605 , +-10023 , +27005 , +9785 , +-7571 , +-14585 , +-11353 , +10211 , +29137 , +-5967 , +11695 , +6863 , +-8163 , +-2983 , +30333 , +-10507 , +-9719 , +25445 , +2275 , +-9823 , +12431 , +-10349 , +11629 , +18215 , +17411 , +-26891 , +21689 , +-12525 , +21417 , +22117 , +-28073 , +-5395 , +-30259 , +2689 , +28693 , +28521 , +7261 , +-2267 , +-19995 , +-6111 , +23039 , +-19111 , +8745 , +-18995 , +-1113 , +26579 , +-371 , +26369 , +-27981 , +-10771 , +7527 , +17243 , +27521 , +-23271 , +25481 , +-32451 , +-17267 , +26843 , +-23917 , +7691 , +31227 , +-16059 , +30681 , +-12063 , +-23109 , +16359 , +17329 , +4039 , +29729 , +19279 , +-11957 , +-24725 , +7411 , +-18181 , +-14577 , +-23205 , +-20211 , +21973 , +30577 , +-19271 , +-13201 , +5419 , +10823 , +-12933 , +31967 , +7715 , +30373 , +-14823 , +13559 , +28597 , +-15053 , +6089 , +9153 , +21285 , +-27895 , +-31431 , +-14123 , +21753 , +-29441 , +-27705 , +7395 , +-907 , +7049 , +20277 , +9949 , +-1657 , +30485 , +20451 , +21887 , +335 , +-8999 , +31629 , +30063 , +4367 , +-977 , +30837 , +-25643 , +20385 , +13425 , +19243 , +-8849 , +17775 , +-17591 , +5819 , +10797 , +-23819 , +17301 , +30563 , +9545 , +19883 , +15533 , +28631 , +20953 , +-5243 , +16975 , +24813 , +27633 , +-23315 , +-11031 , +985 , +17969 , +21809 , +-3469 , +-8471 , +995 , +-7799 , +-22575 , +11449 , +1941 , +-4479 , +12957 , +-21019 , +28199 , +-21509 , +-13433 , +23889 , +28271 , +-4187 , +-20179 , +32463 , +30023 , +21993 , +-29841 , +103 , +22063 , +-24205 , +-16563 , +-23037 , +26713 , +4379 , +-13509 , +-2133 , +-6067 , +-7061 , +17395 , +27201 , +30203 , +-14713 , +-30243 , +-17741 , +1869 , +22453 , +-12583 , +-3147 , +10061 , +-29367 , +-31591 , +5627 , +-9803 , +8227 , +-13439 , +-9489 , +-1279 , +-15963 , +-1549 , +-30231 , +29973 , +20267 , +-11211 , +22505 , +8265 , +-17403 , +-29511 , +18891 , +-22263 , +-5653 , +9479 , +4357 , +20963 , +10237 , +18181 , +-9513 , +-5585 , +-28625 , +11989 , +-30197 , +-12013 , +-1207 , +-17101 , +21291 , +23855 , +-15519 , +19009 , +13105 , +-32601 , +3277 , +20713 , +14539 , +445 , +-12897 , +-30029 , +6157 , +8177 , +19351 , +-27625 , +167 , +-623 , +18595 , +-20129 , +11937 , +-23087 , +-27177 , +-13323 , +11667 , +1897 , +17625 , +16449 , +18009 , +-17495 , +12267 , +-27647 , +3919 , +-3567 , +4177 , +-21219 , +-26875 , +22631 , +-9387 , +-24319 , +8573 , +22359 , +-25153 , +-19335 , +-4129 , +31617 , +-29245 , +-23549 , +2735 , +25365 , +-29819 , +-13141 , +-31095 , +2033 , +-14329 , +19809 , +15193 , +-16851 , +-13655 , +-18225 , +26125 , +-16579 , +-29411 , +28599 , +11479 , +-26235 , +-6691 , +15301 , +32221 , +23667 , +-1751 , +17131 , +16497 , +-9967 , +-6023 , +-5319 , +20689 , +-12505 , +30841 , +-14545 , +15955 , +24263 , +-6789 , +8861 , +17451 , +-27021 , +-24963 , +18421 , +29845 , +30121 , +7821 , +5675 , +-29033 , +15361 , +-25391 , +-255 , +30261 , +23745 , +-13573 , +1513 , +-14555 , +-4359 , +23101 , +-10409 , +31253 , +-3555 , +32449 , +-28513 , +5201 , +16147 , +10663 , +20551 , +23045 , +32215 , +12667 , +9953 , +-1287 , +-2165 , +8487 , +-32667 , +12733 , +-25329 , +-6797 , +-25079 , +-12951 , +6691 , +4343 , +14483 , +-25129 , +19697 , +-4455 , +-7367 , +-17837 , +-1493 , +6781 , +18165 , +-25895 , +5545 , +-9853 , +-12707 , +31695 , +30583 , +-6335 , +-9731 , +1075 , +21875 , +-3471 , +5417 , +-22943 , +22883 , +32762 , +863 , +-19653 , +-21617 , +27725 , +24085 , +-26639 , +-13867 , +-15489 , +23323 , +15917 , +-31931 , +10149 , +29541 , +1745 , +-4039 , +32217 , +-15753 , +22319 , +-16665 , +6577 , +-27099 , +12475 , +-21373 , +7987 , +18177 , +-13489 , +-32051 , +21329 , +-3803 , +-22061 , +29233 , +4831 , +9619 , +8579 , +8279 , +-22517 , +11267 , +-13409 , +17221 , +-18855 , +-4793 , +-9817 , +8431 , +-2799 , +7711 , +-15341 , +-13487 , +-4027 , +-15735 , +19333 , +28933 , +2107 , +-24155 , +17543 , +-26011 , +26479 , +-15869 , +9669 , +-21741 , +9991 , +-31097 , +-12097 , +-32738 , +22987 , +-31825 , +-29437 , +-32103 , +13725 , +-23167 , +-21021 , +1701 , +4979 , +-16949 , +-9545 , +20255 , +32205 , +4883 , +29063 , +3491 , +1453 , +2013 , +-949 , +-18635 , +5649 , +29323 , +12449 , +-31409 , +32229 , +-16971 , +29195 , +31607 , +-6011 , +26875 , +20119 , +18787 , +-851 , +615 , +-4565 , +24963 , +23027 , +12349 , +-5073 , +7205 , +11457 , +-7339 , +-27701 , +16131 , +-28471 , +18933 , +-2403 , +-16029 , +31237 , +-25819 , +-10767 , +9383 , +23585 , +21131 , +-10629 , +14703 , +18565 , +-2877 , +-2421 , +-22231 , +-17733 , +-3019 , +-16695 , +7209 , +-13453 , +-12695 , +9581 , +21575 , +507 , +-1557 , +-25615 , +5107 , +31791 , +-17259 , +16213 , +10701 , +-23307 , +-32143 , +-23865 , +30907 , +12601 , +-13043 , +11497 , +21641 , +-25763 , +21331 , +32643 , +2807 , +-10947 , +27105 , +-7751 , +-3753 , +26775 , +19425 , +9413 , +-12639 , +-16879 , +23653 , +-1225 , +-1517 , +-15705 , +-1991 , +15003 , +1601 , +-23633 , +-4037 , +-61 , +20651 , +-9921 , +17467 , +11635 , +19937 , +14137 , +13897 , +15777 , +-5619 , +15543 , +20115 , +-8919 , +-10731 , +23039 , +26555 , +18945 , +6449 , +25867 , +23475 , +-5123 , +-16643 , +-2957 , +26891 , +8185 , +-1511 , +-10009 , +-5929 , +-21093 , +-27843 , +27951 , +27895 , +-8315 , +-817 , +-2919 , +-8447 , +-18927 , +-7425 , +-16391 , +-18555 , +11403 , +-28575 , +20763 , +-6661 , +2269 , +-261 , +13499 , +-32507 , +11737 , +-4631 , +-13559 , +-10407 , +-6177 , +-11411 , +-18805 , +-1779 , +11301 , +905 , +10667 , +20853 , +16993 , +-7399 , +-13661 , +27003 , +-12021 , +32615 , +26101 , +27249 , +-15341 , +25163 , +10087 , +31093 , +1557 , +-1353 , +-28295 , +-31941 , +-31727 , +29145 , +-5279 , +-28563 , +29611 , +17583 , +23933 , +14979 , +21467 , +31263 , +29769 , +22807 , +-24535 , +-12911 , +16867 , +32707 , +-20899 , +-23037 , +-10761 , +25715 , +-20793 , +12709 , +17469 , +-14785 , +18151 , +32241 , +-3727 , +-4921 , +-16721 , +-7107 , +24261 , +22531 , +14387 , +-23843 , +11233 , +-18269 , +-5653 , +-1359 , +-30889 , +-14113 , +-11421 , +-22203 , +-14947 , +7643 , +-7051 , +5987 , +22141 , +-30351 , +3841 , +5165 , +-12003 , +9361 , +15143 , +29881 , +20071 , +-26087 , +-27139 , +28705 , +-13815 , +-13781 , +13001 , +4133 , +-15893 , +24067 , +30387 , +-29127 , +-13269 , +25685 , +18183 , +-2783 , +23435 , +-29151 , +29157 , +-8435 , +27253 , +9225 , +18809 , +-22483 , +17517 , +19503 , +-5701 , +-4667 , +9733 , +-18299 , +8347 , +-20015 , +-5279 , +21935 , +28871 , +-1267 , +-31457 , +4689 , +9941 , +18847 , +27615 , +22251 , +-1789 , +-18405 , +-13779 , +17975 , +10609 , +8493 , +-27387 , +24055 , +-23855 , +8617 , +19139 , +-28589 , +1959 , +20257 , +-28513 , +28077 , +11259 , +31485 , +26271 , +30465 , +-3691 , +23071 , +10777 , +12465 , +-333 , +26853 , +7843 , +3559 , +18241 , +25561 , +-19059 , +-13205 , +-8047 , +11445 , +19417 , +22775 , +6039 , +29703 , +-26951 , +-11247 , +16793 , +-183 , +30329 , +-12443 , +16237 , +-7315 , +26629 , +23453 , +11059 , +-29691 , +19675 , +-335 , +10371 , +-6447 , +-15999 , +10959 , +-12495 , +-29737 , +-17789 , +19873 , +10365 , +14851 , +-24603 , +4149 , +-18739 , +-32715 , +-24801 , +-8379 , +32746 , +-5409 , +27539 , +21535 , +-28245 , +-29157 , +9603 , +-27149 , +-1731 , +17475 , +-24691 , +19371 , +-23343 , +30987 , +-17753 , +13897 , +10197 , +-9959 , +4233 , +3001 , +-9805 , +-16875 , +-23373 , +-21969 , +18171 , +-20657 , +-11301 , +15349 , +27945 , +-12595 , +14831 , +25553 , +-18217 , +-29981 , +-14717 , +2513 , +15991 , +27727 , +-18479 , +-8023 , +9605 , +22737 , +-19413 , +15241 , +-16827 , +8769 , +-17931 , +19573 , +14845 , +-17883 , +7713 , +25375 , +32167 , +-7729 , +20767 , +17469 , +1833 , +-20755 , +-23973 , +12639 , +23827 , +-17235 , +-17863 , +-18101 , +211 , +24901 , +637 , +-5927 , +23405 , +-16361 , +-19113 , +-3013 , +-25419 , +4169 , +-13621 , +-3863 , +1281 , +-4139 , +31925 , +-18455 , +-28311 , +6951 , +-26313 , +-30541 , +-32131 , +24881 , +23481 , +-31619 , +-19081 , +11275 , +1113 , +-26081 , +18427 , +30211 , +-6677 , +-1435 , +32331 , +-31949 , +8815 , +-21277 , +25599 , +14243 , +-12799 , +23895 , +7997 , +25051 , +-20383 , +-1673 , +28275 , +-11783 , +23767 , +14163 , +18569 , +-27315 , +-10049 , +-25567 , +6053 , +11889 , +-30607 , +7071 , +-31147 , +8667 , +-25919 , +-6167 , +22355 , +-20737 , +-21769 , +-30261 , +16305 , +3549 , +-11961 , +-9823 , +15259 , +2337 , +-9791 , +-3923 , +21903 , +19637 , +-9767 , +-21785 , +22539 , +16603 , +-9141 , +-11933 , +25039 , +-13879 , +-9307 , +-31461 , +-11119 , +-15429 , +-15563 , +595 , +-27083 , +-27763 , +-20859 , +21609 , +7305 , +-23597 , +8013 , +4655 , +15217 , +9847 , +25079 , +-17723 , +11699 , +-3389 , +-10105 , +-13589 , +-12263 , +-10231 , +25635 , +8935 , +-30919 , +15533 , +-23297 , +-11063 , +-14423 , +25035 , +18651 , +-3245 , +-18257 , +9025 , +8185 , +31051 , +-5753 , +-29617 , +12435 , +-7853 , +-28403 , +6319 , +-32547 , +-31165 , +20479 , +-1491 , +-12433 , +25595 , +-4683 , +15031 , +-3517 , +20677 , +1867 , +4869 , +5171 , +18213 , +10607 , +19871 , +-30489 , +-10189 , +19591 , +3713 , +28497 , +24181 , +11119 , +-10447 , +-9559 , +2355 , +27831 , +8017 , +-17953 , +22613 , +5711 , +22977 , +13719 , +8371 , +17355 , +-16849 , +-17249 , +-20233 , +-26863 , +-20689 , +30437 , +12009 , +23447 , +5339 , +22261 , +-15019 , +-11237 , +-31777 , +-32273 , +-17835 , +-21799 , +-30435 , +17909 , +1589 , +-957 , +-3653 , +22327 , +-32065 , +-3015 , +26565 , +-29867 , +19231 , +30145 , +15163 , +-13463 , +25651 , +-15039 , +-20561 , +29813 , +17765 , +-21193 , +-22949 , +-8613 , +23047 , +5483 , +-839 , +16733 , +4901 , +-31569 , +30623 , +-19961 , +-24097 , +-31471 , +-27955 , +27579 , +-3521 , +25241 , +3347 , +8595 , +-357 , +15483 , +-30501 , +-29209 , +4961 , +-7983 , +6477 , +-1977 , +7023 , +27349 , +5085 , +-5661 , +-29447 , +7065 , +-407 , +-14183 , +3791 , +25911 , +-3631 , +-28585 , +28229 , +-24423 , +18701 , +25379 , +-643 , +26013 , +-2877 , +10127 , +-3513 , +-541 , +19301 , +-4693 , +-8837 , +-5649 , +-21055 , +21125 , +-11575 , +-3855 , +-10203 , +-26083 , +22811 , +-19721 , +14311 , +-18469 , +-17567 , +13733 , +7563 , +-629 , +-11789 , +25453 , +9043 , +-22315 , +-9115 , +-2743 , +-24485 , +1841 , +-31775 , +-16657 , +-32723 , +26723 , +-25093 , +-10867 , +22241 , +-26765 , +-14323 , +-30463 , +2473 , +4639 , +29451 , +-22643 , +-7181 , +-18723 , +30693 , +1043 , +28927 , +8521 , +-13237 , +-18741 , +-3601 , +27939 , +28703 , +4219 , +-14227 , +-26683 , +11061 , +-18385 , +-21065 , +14367 , +13243 , +-5259 , +3645 , +-15065 , +21771 , +22795 , +25017 , +8919 , +-20737 , +-29147 , +-10301 , +-21083 , +-23081 , +28185 , +12521 , +31863 , +6779 , +-21347 , +7251 , +4381 , +-31893 , +-15747 , +-3641 , +12111 , +-507 , +21713 , +8271 , +4635 , +-3995 , +-31043 , +10579 , +-18465 , +21435 , +11679 , +-32733 , +31947 , +16165 , +24523 , +9757 , +-17463 , +-13563 , +21963 , +23355 , +-20987 , +-6951 , +5637 , +15159 , +16601 , +11153 , +-7421 , +-24811 , +6731 , +27759 , +-7127 , +6977 , +-31741 , +-10153 , +225 , +29229 , +29891 , +-30299 , +26209 , +21341 , +28769 , +29331 , +-20515 , +-16627 , +30269 , +19453 , +10559 , +-6597 , +-18887 , +-25395 , +9311 , +-8377 , +17457 , +29123 , +-10049 , +1803 , +-32267 , +-8747 , +-14921 , +26227 , +30655 , +-9465 , +3903 , +-2929 , +-11477 , +-23615 , +-13033 , +3377 , +-15185 , +7333 , +-15221 , +-3065 , +29589 , +26351 , +-31583 , +-17363 , +16497 , +13121 , +23765 , +27715 , +-29161 , +-4857 , +9813 , +-18669 , +18713 , +22085 , +22455 , +8343 , +-6723 , +-21513 , +23335 , +-6241 , +3181 , +-5405 , +-24785 , +-29729 , +-21319 , +19701 , +23017 , +18577 , +-20785 , +-26857 , +30381 , +23425 , +-1173 , +20355 , +-22951 , +28849 , +4691 , +29857 , +2557 , +2665 , +-6319 , +-13213 , +28701 , +15825 , +15789 , +25615 , +-25507 , +-25589 , +14877 , +22695 , +-28221 , +-24633 , +25409 , +32691 , +22379 , +30563 , +-14179 , +2213 , +12225 , +-31879 , +-30701 , +-20825 , +-17867 , +25081 , +27089 , +-27909 , +-2187 , +-8757 , +-13611 , +22479 , +-22487 , +-25897 , +-29221 , +-27759 , +-477 , +-10577 , +19165 , +13523 , +6177 , +5525 , +29957 , +-4459 , +16379 , +5149 , +-20693 , +17703 , +25443 , +-10933 , +1735 , +21375 , +-16621 , +9497 , +19817 , +-7927 , +13459 , +26529 , +18617 , +-8181 , +16999 , +3241 , +-3867 , +-5001 , +5831 , +32707 , +30113 , +-7359 , +-19237 , +-4897 , +16791 , +10813 , +-23435 , +-20123 , +-19351 , +-16271 , +9281 , +-11823 , +-13537 , +-20751 , +22147 , +19397 , +28455 , +-3535 , +24653 , +-25437 , +-23611 , +29673 , +-3271 , +21671 , +18963 , +11615 , +14747 , +3709 , +-19593 , +2635 , +-25273 , +-23719 , +-17771 , +-23517 , +24757 , +-3185 , +-25905 , +28161 , +-32055 , +7085 , +15927 , +26859 , +-6909 , +28177 , +14859 , +-1859 , +11327 , +2307 , +12715 , +-3729 , +21471 , +24903 , +-10221 , +29947 , +27539 , +-26307 , +18383 , +-18005 , +30599 , +-907 , +-5769 , +20731 , +-5351 , +30665 , +-24409 , +1769 , +-18915 , +26097 , +30577 , +-3637 , +23689 , +-30563 , +-32675 , +-13643 , +4275 , +-31217 , +9949 , +9789 , +18437 , +-15565 , +-22971 , +-23065 , +-15813 , +-3533 , +-8379 , +-17941 , +31511 , +11665 , +17373 , +2973 , +32405 , +-2109 , +4567 , +10297 , +6063 , +-2235 , +-27707 , +-31681 , +20871 , +-14541 , +-24465 , +28495 , +17193 , +-19357 , +4301 , +4219 , +7613 , +-16647 , +25735 , +803 , +30021 , +-18297 , +19685 , +-21431 , +-17457 , +-10599 , +22091 , +-8083 , +26415 , +-28203 , +26667 , +-3611 , +-18119 , +10647 , +21383 , +-16463 , +-23945 , +-23555 , +10211 , +-9001 , +-18591 , +-23929 , +-31049 , +26683 , +-20457 , +-7375 , +-21129 , +-21265 , +27285 , +-14847 , +28153 , +8987 , +-6287 , +-20691 , +-12933 , +-5821 , +14605 , +-25177 , +-32237 , +20015 , +-8881 , +-12743 , +1707 , +-31949 , +31201 , +-15585 , +32119 , +3863 , +29411 , +-30689 , +6381 , +6499 , +21533 , +-29923 , +17213 , +9789 , +-31547 , +-7883 , +15433 , +23235 , +15787 , +20567 , +26147 , +-7719 , +14839 , +-2729 , +-2057 , +-30327 , +6753 , +-8561 , +20369 , +12511 , +-3355 , +29419 , +-26289 , +7735 , +-1281 , +-627 , +1687 , +-10729 , +-10145 , +13789 , +19157 , +-30065 , +31785 , +7203 , +-26899 , +-17655 , +2719 , +673 , +-13513 , +7331 , +-14997 , +6953 , +6131 , +25353 , +28745 , +24885 , +-15289 , +457 , +10303 , +14463 , +21425 , +32305 , +9571 , +-26595 , +-15871 , +27041 , +24321 , +6671 , +3541 , +-25499 , +-30113 , +-14491 , +-13941 , +-14065 , +27637 , +-1847 , +-5447 , +77 , +-3301 , +9123 , +-28627 , +15683 , +6217 , +-5209 , +-2467 , +-28065 , +-2605 , +20725 , +21085 , +3765 , +4885 , +21161 , +-13467 , +-3117 , +23093 , +-8707 , +19127 , +21537 , +-20393 , +25047 , +23077 , +-20051 , +-22445 , +-8471 , +-14081 , +-19057 , +18417 , +-13245 , +20369 , +-26695 , +22435 , +-22419 , +-5859 , +20305 , +13493 , +-28925 , +7245 , +9097 , +-25079 , +-21817 , +-5591 , +-19207 , +29525 , +-9155 , +-25699 , +6005 , +-8497 , +27837 , +9567 , +5223 , +-7823 , +9747 , +23155 , +11683 , +-18009 , +-22889 , +-23265 , +30915 , +7311 , +18875 , +32357 , +-5379 , +-18005 , +32047 , +23543 , +11643 , +283 , +-9619 , +19637 , +-28107 , +-23461 , +-8993 , +-1125 , +16711 , +-13971 , +-29591 , +20809 , +14023 , +26785 , +-2933 , +27623 , +10531 , +-13119 , +-16395 , +9649 , +-4107 , +-21041 , +-12127 , +-7715 , +-31911 , +-8643 , +11367 , +-10203 , +11209 , +673 , +5655 , +-26965 , +-1419 , +19439 , +-21741 , +-3453 , +8727 , +-21451 , +-8857 , +7843 , +18511 , +32205 , +8797 , +8535 , +26489 , +5401 , +-21095 , +24641 , +22791 , +13493 , +-28499 , +31437 , +-24493 , +-9157 , +-26825 , +11049 , +-29183 , +26987 , +14195 , +26047 , +21453 , +-31755 , +28503 , +28457 , +8429 , +-13409 , +-6617 , +8363 , +-8483 , +-16117 , +10901 , +4911 , +-22845 , +-7961 , +25931 , +-5959 , +-30917 , +27047 , +22549 , +27741 , +-19777 , +-15427 , +361 , +-16197 , +-20883 , +1111 , +-17273 , +21747 , +-26261 , +-32117 , +13839 , +-10203 , +9403 , +-2279 , +3357 , +-7329 , +21395 , +7837 , +30937 , +-28135 , +-25545 , +22093 , +-13675 , +-16077 , +-32433 , +11049 , +9315 , +11359 , +15295 , +21435 , +15409 , +8747 , +-29443 , +3147 , +-31909 , +1639 , +20979 , +19863 , +-30013 , +23339 , +-4537 , +-10741 , +-1171 , +-30649 , +10303 , +32123 , +-1125 , +6463 , +-29417 , +-13481 , +22613 , +-22079 , +-2603 , +18279 , +19351 , +14491 , +17573 , +32003 , +14037 , +6457 , +-3407 , +10439 , +10781 , +15257 , +-31117 , +-30515 , +-28751 , +707 , +-30059 , +18281 , +-11239 , +25025 , +7493 , +-1955 , +25277 , +30485 , +-20469 , +-24437 , +-12545 , +24249 , +4137 , +16445 , +-32303 , +29327 , +20327 , +-10291 , +-15411 , +-20135 , +-23177 , +-8475 , +31693 , +-31689 , +-7741 , +-22983 , +31239 , +-25957 , +-31283 , +-25677 , +-22627 , +5311 , +8195 , +-5825 , +-3397 , +-19293 , +-235 , +26093 , +20269 , +19839 , +-10801 , +20923 , +-23685 , +10685 , +26489 , +-11329 , +-1415 , +-24715 , +-11107 , +-19731 , +-11929 , +-29859 , +-24461 , +16705 , +-9599 , +-5559 , +1703 , +-3711 , +3105 , +18717 , +-17985 , +-28817 , +21581 , +17227 , +-24083 , +-28025 , +-14121 , +-14397 , +-19353 , +-31953 , +-21521 , +23667 , +31549 , +-5511 , +7485 , +6203 , +26039 , +-15281 , +-12417 , +-29855 , +31015 , +-5063 , +-25965 , +20117 , +31303 , +31877 , +16925 , +28765 , +9993 , +-26609 , +18585 , +30993 , +-26377 , +-27025 , +9971 , +15701 , +26627 , +2737 , +-16225 , +14097 , +-23061 , +-25455 , +27697 , +-25373 , +18945 , +11317 , +26745 , +-4063 , +9619 , +14427 , +5649 , +14663 , +-1865 , +-227 , +-12927 , +-21771 , +-16473 , +20771 , +-22061 , +-7323 , +-12131 , +-28843 , +8097 , +-31641 , +-7645 , +-13533 , +-18243 , +22993 , +-28169 , +-32467 , +-13247 , +-14723 , +-31663 , +-6523 , +-29915 , +-20545 , +-19505 , +16481 , +14681 , +-24735 , +2493 , +15957 , +-5279 , +21523 , +-10503 , +-12529 , +-24475 , +30825 , +17729 , +26503 , +4305 , +-18351 , +22799 , +13507 , +2407 , +-4849 , +-25609 , +12285 , +-21795 , +-26709 , +1909 , +-29331 , +26095 , +25077 , +18505 , +32121 , +3065 , +-8713 , +-3499 , +-18327 , +-13295 , +15339 , +-17177 , +-13143 , +29853 , +11959 , +24479 , +-22663 , +-11925 , +-18717 , +10181 , +20517 , +32327 , +3089 , +-8685 , +19909 , +1565 , +23799 , +5409 , +-20629 , +-22909 , +-25131 , +30767 , +11999 , +-28711 , +7533 , +12933 , +26077 , +-1569 , +6267 , +1857 , +-29245 , +-6959 , +943 , +12733 , +-15925 , +-8457 , +-15325 , +-22949 , +15311 , +-22845 , +-29101 , +-13343 , +-31891 , +361 , +-23659 , +17751 , +1999 , +-25101 , +-23023 , +-7087 , +7133 , +23773 , +-17601 , +23511 , +-13067 , +-11219 , +13521 , +-13391 , +-29661 , +26631 , +-1989 , +-17337 , +8665 , +-12345 , +23709 , +-23821 , +-7125 , +24477 , +-18617 , +-31015 , +-22657 , +-4449 , +20135 , +-8631 , +25035 , +-20127 , +-5173 , +15497 , +-1969 , +-7913 , +-15795 , +-6089 , +12227 , +-30947 , +-6441 , +-3557 , +14107 , +17693 , +3091 , +-7039 , +-15177 , +29087 , +-16859 , +-23787 , +15903 , +24869 , +-11101 , +-27851 , +-7627 , +13249 , +21265 , +-23347 , +28153 , +-211 , +28627 , +21419 , +13235 , +-21147 , +-1627 , +14685 , +7351 , +26555 , +-11365 , +18307 , +-29297 , +-6543 , +-16495 , +17065 , +-23355 , +31959 , +12067 , +-27231 , +-13297 , +14809 , +21291 , +5467 , +5123 , +-2789 , +8629 , +-13001 , +21085 , +-24429 , +-30091 , +27621 , +31407 , +-18785 , +-28221 , +26809 , +10645 , +7329 , +-30189 , +31105 , +-9613 , +21005 , +9195 , +28901 , +-16465 , +17419 , +-29607 , +7477 , +-19101 , +-25203 , +20977 , +16325 , +18069 , +-5149 , +18493 , +13513 , +15605 , +28631 , +8639 , +25509 , +-19693 , +-3263 , +-1953 , +4047 , +8463 , +31525 , +31849 , +-24033 , +23517 , +11845 , +517 , +677 , +-265 , +18495 , +9517 , +6925 , +14485 , +28955 , +15393 , +6509 , +28769 , +20845 , +20587 , +-29797 , +-16195 , +-17681 , +-10677 , +-5361 , +-17817 , +15753 , +-9549 , +-20173 , +27331 , +-32515 , +-8255 , +-29633 , +7305 , +15085 , +8117 , +-13169 , +-13569 , +6531 , +28267 , +-23943 , +-16461 , +31359 , +29007 , +17581 , +21165 , +18125 , +26073 , +-26881 , +17715 , +-13655 , +11907 , +27089 , +-20747 , +-7637 , +-8637 , +-5667 , +-2617 , +21091 , +31359 , +22671 , +-14367 , +-22795 , +11145 , +-23325 , +-28529 , +27689 , +-27753 , +-839 , +24427 , +7563 , +-31693 , +-4435 , +-17901 , +-24321 , +-13757 , +13425 , +20589 , +-22953 , +18545 , +-16993 , +2889 , +-15503 , +6187 , +4891 , +28077 , +-23351 , +-5863 , +-21789 , +-16249 , +10901 , +22295 , +17513 , +219 , +-13733 , +28331 , +-6805 , +2191 , +3335 , +6141 , +-28849 , +-5747 , +-32373 , +-24495 , +17651 , +-3189 , +-1043 , +6649 , +30987 , +23615 , +30949 , +-13609 , +31995 , +527 , +32243 , +24909 , +2087 , +16727 , +19961 , +10169 , +28625 , +21523 , +-13747 , +-4505 , +-22671 , +13347 , +22621 , +-7149 , +-24185 , +30713 , +-23623 , +5337 , +10493 , +8665 , +-27467 , +-14415 , +-13577 , +-9845 , +21371 , +29281 , +-5843 , +-30569 , +-20567 , +31743 , +-29501 , +-12039 , +-15263 , +-31265 , +4517 , +22113 , +12521 , +29461 , +16983 , +20959 , +-16963 , +-6557 , +-937 , +26663 , +-14803 , +28341 , +-2841 , +14911 , +15983 , +6685 , +-18827 , +-22339 , +-20937 , +-22715 , +28267 , +16767 , +-2087 , +3433 , +-23677 , +-12317 , +17361 , +-27947 , +27815 , +-30859 , +-5911 , +10703 , +16453 , +-16069 , +-22327 , +19485 , +-3033 , +-15525 , +6421 , +3319 , +1483 , +-29865 , +-28421 , +-26243 , +-15557 , +4815 , +29527 , +-8267 , +27753 , +1707 , +11587 , +-27653 , +-6913 , +26843 , +-16075 , +19717 , +3777 , +5267 , +13967 , +-4533 , +25687 , +-25355 , +-14915 , +6411 , +-4937 , +32343 , +6347 , +-9281 , +7917 , +6643 , +30849 , +22547 , +-12675 , +29731 , +15861 , +-26787 , +-18381 , +11545 , +24737 , +17809 , +-14457 , +-21489 , +30985 , +-30009 , +-21403 , +-2801 , +4033 , +-17631 , +-9837 , +8473 , +-28399 , +5455 , +-31867 , +-3865 , +-17141 , +18309 , +-18517 , +29219 , +-5089 , +-3345 , +9309 , +12059 , +55 , +-6741 , +-22243 , +-7939 , +23115 , +17219 , +18303 , +7309 , +-21377 , +21413 , +-29571 , +-3747 , +183 , +12437 , +2633 , +-3193 , +-13397 , +2479 , +-1363 , +-22559 , +25737 , +14037 , +-24099 , +-13637 , +-18171 , +-11987 , +-30255 , +26895 , +-27147 , +2713 , +11811 , +17473 , +23651 , +-1109 , +12379 , +30803 , +31535 , +8227 , +-21295 , +-9059 , +-31455 , +14813 , +-14337 , +5893 , +15229 , +-11689 , +3167 , +-9801 , +25893 , +4767 , +-20291 , +17249 , +-13785 , +10697 , +24337 , +-9759 , +11227 , +-1549 , +-27685 , +6029 , +-28295 , +17327 , +11763 , +727 , +-16073 , +2055 , +18151 , +-14185 , +15825 , +22761 , +-5163 , +-12105 , +-24395 , +20525 , +-12613 , +17781 , +-22385 , +25853 , +-30637 , +-31475 , +-11171 , +-10271 , +-32141 , +30211 , +-7399 , +27935 , +8913 , +13771 , +4027 , +11719 , +20085 , +6667 , +25057 , +26401 , +-8839 , +31819 , +-5407 , +-24405 , +6003 , +18485 , +18273 , +-16249 , +-12227 , +-15283 , +15725 , +5761 , +15713 , +-29411 , +-12521 , +-31369 , +7129 , +15099 , +-26235 , +-31901 , +15997 , +-21957 , +-10097 , +10179 , +7375 , +24039 , +-6443 , +151 , +31313 , +-2823 , +-28071 , +-6689 , +-16791 , +10765 , +7571 , +-31863 , +5291 , +21921 , +17675 , +-11795 , +-4677 , +-5429 , +8569 , +13513 , +-1889 , +-6547 , +15945 , +30901 , +11423 , +-22289 , +-17203 , +26391 , +-1137 , +12919 , +-9285 , +10405 , +17591 , +14759 , +-17573 , +11861 , +8225 , +5319 , +-18927 , +-10025 , +6769 , +-4723 , +9595 , +-26993 , +-1727 , +14155 , +-5115 , +-20469 , +-24581 , +-8283 , +-25849 , +31481 , +11561 , +12759 , +-29355 , +11173 , +-6059 , +-7079 , +-12701 , +-787 , +6231 , +18729 , +9677 , +-6471 , +23101 , +6265 , +8061 , +-25871 , +-28527 , +-12825 , +26683 , +253 , +833 , +4157 , +22219 , +-6223 , +-14361 , +7071 , +-1669 , +9679 , +2737 , +-22965 , +-32697 , +-7939 , +20397 , +14281 , +23403 , +13115 , +17577 , +27305 , +-6535 , +-6443 , +15237 , +4287 , +-2061 , +-32533 , +-6897 , +-20019 , +11625 , +21083 , +25685 , +23751 , +19463 , +-14531 , +21127 , +17291 , +-29263 , +-21285 , +-13493 , +6417 , +12957 , +-22995 , +6539 , +-21973 , +12139 , +-31031 , +7389 , +-22349 , +20409 , +-13213 , +-177 , +8529 , +-23235 , +-4417 , +21449 , +-27735 , +-25761 , +-16849 , +13531 , +9491 , +-30895 , +-30589 , +31771 , +-6695 , +3235 , +15497 , +-22025 , +-24343 , +11871 , +17407 , +-27109 , +11793 , +25759 , +19473 , +-32713 , +-16715 , +-29021 , +-19383 , +-26267 , +7431 , +6511 , +-9203 , +-25099 , +21951 , +13025 , +1691 , +-26667 , +-15273 , +24897 , +3441 , +24917 , +-1603 , +22373 , +-26281 , +145 , +30091 , +23873 , +6609 , +29503 , +-22075 , +9477 , +13069 , +779 , +16651 , +25771 , +-9619 , +-17815 , +8025 , +3101 , +-9873 , +4599 , +5427 , +28607 , +-4307 , +28235 , +-17051 , +16275 , +18519 , +-31147 , +32059 , +-23865 , +-31325 , +18987 , +7993 , +20435 , +2251 , +25195 , +77 , +-1775 , +-16381 , +-8177 , +18319 , +-6703 , +10229 , +13513 , +8307 , +4087 , +-17359 , +3023 , +28553 , +-25077 , +-29143 , +6979 , +-1625 , +4569 , +15025 , +-31229 , +30127 , +901 , +-2587 , +-6661 , +-32573 , +-16095 , +-6733 , +-26867 , +-4873 , +-21813 , +-32053 , +23127 , +25231 , +-23745 , +14355 , +-5607 , +-13385 , +27893 , +-1883 , +-27133 , +-32073 , +19373 , +1099 , +-32744 , +-17743 , +-15717 , +-28053 , +-28165 , +6867 , +-14613 , +-25721 , +-15671 , +1041 , +16101 , +31029 , +-14983 , +31071 , +9601 , +-27499 , +-18517 , +8807 , +10879 , +-9399 , +-5883 , +24771 , +9985 , +13037 , +21257 , +-4177 , +16031 , +-23791 , +-9875 , +1609 , +1283 , +28079 , +-5385 , +29767 , +32768 , +-12767 , +-25909 , +-20183 , +24103 , +-26975 , +-13745 , +22011 , +14821 , +25655 , +31611 , +-1663 , +16663 , +-24267 , +-7243 , +-6405 , +6431 , +3635 , +22309 , +-22697 , +22403 , +2435 , +-23407 , +-11035 , +26369 , +19749 , +-1611 , +12695 , +12581 , +23369 , +-6119 , +30645 , +25701 , +20797 , +-23963 , +-8937 , +-20805 , +22767 , +2629 , +-16167 , +-15179 , +28889 , +-22861 , +31639 , +-29423 , +-15739 , +6875 , +-13789 , +18649 , +16253 , +13671 , +-13637 , +4087 , +-17211 , +12385 , +1225 , +31305 , +17619 , +14731 , +29457 , +-12989 , +-10229 , +-9425 , +2159 , +-31233 , +21423 , +23931 , +-22769 , +-26663 , +-18591 , +-18339 , +543 , +14211 , +-32497 , +11731 , +25105 , +-30047 , +22389 , +9421 , +-15541 , +5087 , +-17645 , +23675 , +18273 , +13195 , +-2655 , +4139 , +28877 , +-27479 , +11 , +9119 , +8487 , +-8561 , +-26907 , +-4119 , +-11805 , +-32003 , +13671 , +-14149 , +-129 , +177 , +12005 , +-11709 , +16189 , +29313 , +-24891 , +16265 , +-2207 , +-15627 , +26357 , +-28357 , +12775 , +23647 , +-2841 , +-4847 , +-32329 , +-21135 , +1291 , +9627 , +29277 , +23119 , +7355 , +-30045 , +31307 , +29241 , +-3387 , +6647 , +-6269 , +-32371 , +32341 , +10451 , +-16681 , +-10127 , +-7057 , +7593 , +1439 , +-8739 , +-1043 , +21123 , +28149 , +-14529 , +-24587 , +-18475 , +-8859 , +-29557 , +-30487 , +20441 , +-14803 , +28887 , +-7185 , +6757 , +-13585 , +-2195 , +24791 , +-30397 , +-23317 , +-25233 , +-4449 , +5387 , +-15171 , +12257 , +-8601 , +2679 , +-23161 , +5705 , +-23317 , +10305 , +19129 , +27081 , +-3465 , +9589 , +-8131 , +12463 , +22883 , +-18357 , +-2761 , +-26989 , +15113 , +13699 , +18739 , +30959 , +13119 , +24629 , +-23571 , +8243 , +-17845 , +-32207 , +-20615 , +32099 , +13663 , +25809 , +19713 , +-15321 , +11663 , +16981 , +23553 , +-18069 , +-6837 , +18361 , +27641 , +-29069 , +1105 , +-16627 , +20651 , +-24461 , +-28111 , +31311 , +4297 , +-2907 , +-2249 , +-26943 , +10043 , +-14105 , +15339 , +12479 , +-28981 , +4303 , +16137 , +8221 , +-28575 , +14147 , +6647 , +21755 , +-13377 , +-879 , +27581 , +-4835 , +29363 , +-14073 , +-15745 , +-26177 , +11985 , +19469 , +-9361 , +28155 , +-22099 , +-16453 , +-3761 , +-21107 , +12177 , +-22287 , +-11935 , +-19393 , +25781 , +27633 , +-4381 , +-29263 , +-31497 , +-29325 , +11521 , +21945 , +9751 , +-1983 , +-26793 , +-1733 , +-2967 , +8013 , +-16159 , +28541 , +25101 , +21579 , +373 , +1031 , +-16209 , +10951 , +18877 , +-14097 , +-16973 , +16313 , +-14931 , +-13895 , +-18183 , +15787 , +1401 , +5807 , +-4595 , +30013 , +-6891 , +16569 , +-6173 , +-7603 , +-5597 , +23985 , +14091 , +-2677 , +20591 , +11581 , +-7571 , +-1395 , +31979 , +30249 , +-30079 , +29289 , +3873 , +13375 , +-18685 , +15055 , +18733 , +-20839 , +18221 , +-9827 , +1595 , +3711 , +31861 , +-15107 , +-2191 , +-28989 , +-26697 , +-7 , +24437 , +-9333 , +-32515 , +-7281 , +1117 , +-17735 , +29097 , +27731 , +-28627 , +-27467 , +6459 , +-7039 , +6089 , +-2609 , +13437 , +17041 , +111 , +-24553 , +3901 , +5205 , +-1105 , +17833 , +-6003 , +20117 , +20967 , +-31853 , +-20109 , +-9955 , +13107 , +13607 , +7713 , +12117 , +18159 , +-18475 , +-32331 , +-4759 , +12705 , +14205 , +27749 , +-24119 , +18821 , +-25775 , +-31675 , +-17577 , +12653 , +11041 , +-28559 , +-5135 , +-28079 , +-31425 , +11983 , +-10355 , +-21709 , +-817 , +11329 , +26579 , +-4189 , +-1885 , +-2205 , +-25547 , +27829 , +27279 , +9659 , +11909 , +11381 , +-2233 , +-31877 , +-7159 , +20449 , +-6479 , +-23121 , +-7397 , +5987 , +29887 , +30457 , +-6849 , +-28217 , +-25909 , +-18737 , +-25159 , +10679 , +-5785 , +-7385 , +11425 , +-13913 , +-30021 , +-31557 , +-2425 , +-12705 , +1373 , +21943 , +-18309 , +32742 , +-10327 , +15095 , +12469 , +18677 , +-31855 , +-30783 , +13215 , +25865 , +8963 , +-31757 , +-31365 , +15545 , +7347 , +-21303 , +20589 , +10439 , +4479 , +-22523 , +-28901 , +-11377 , +-26049 , +25013 , +17351 , +-3841 , +-4579 , +19559 , +-11297 , +-31477 , +2421 , +15325 , +24603 , +28849 , +27939 , +-11709 , +28949 , +32099 , +3683 , +-2059 , +-12195 , +-24823 , +-28895 , +21925 , +-6633 , +-23433 , +22235 , +18721 , +29451 , +3677 , +-23571 , +19587 , +-185 , +17613 , +11639 , +18411 , +-10965 , +-7385 , +28069 , +-14917 , +-7925 , +21143 , +11417 , +-32443 , +19781 , +27403 , +25521 , +18449 , +13015 , +21163 , +4461 , +-23161 , +13939 , +21461 , +5567 , +20787 , +27169 , +-7797 , +-20761 , +-10379 , +19279 , +-32135 , +-20793 , +29883 , +13675 , +-9635 , +191 , +-25801 , +8445 , +-30191 , +-26619 , +6945 , +1853 , +7665 , +24185 , +25953 , +-15827 , +-15645 , +15361 , +-7987 , +-16087 , +-1599 , +-12705 , +-13847 , +27151 , +345 , +-5749 , +-27377 , +32455 , +12009 , +30855 , +19251 , +24421 , +-4855 , +-10567 , +-9959 , +-32583 , +-26319 , +14791 , +-14069 , +-4241 , +-2131 , +17385 , +24333 , +14245 , +30221 , +22213 , +-28771 , +-30467 , +-3031 , +-16701 , +-14101 , +28477 , +19345 , +20203 , +1673 , +-2205 , +19847 , +-31435 , +10151 , +-26309 , +28541 , +-12437 , +-51 , +-17027 , +-8705 , +2165 , +6675 , +14431 , +11833 , +-14785 , +-22829 , +-28495 , +26089 , +-28667 , +-29715 , +27505 , +-28201 , +-27347 , +3951 , +-3095 , +-23861 , +-857 , +5339 , +-26557 , +-14069 , +25789 , +25815 , +-3427 , +1615 , +-21651 , +-2197 , +13997 , +11833 , +-26813 , +-18255 , +-1079 , +3403 , +30893 , +-16365 , +-17521 , +-4507 , +23513 , +29187 , +-8975 , +14009 , +-7419 , +-31695 , +-23597 , +20545 , +24929 , +23617 , +-8927 , +-25925 , +20061 , +-16119 , +-24727 , +-25821 , +-22137 , +22085 , +-2065 , +8609 , +26339 , +-9525 , +-9141 , +-25075 , +31679 , +-24241 , +14457 , +23261 , +-23537 , +15245 , +29047 , +-10587 , +30785 , +-12279 , +13409 , +-3063 , +-5219 , +4683 , +-5639 , +14395 , +-13551 , +21895 , +-22827 , +-12309 , +21653 , +-19991 , +-4127 , +-27961 , +32507 , +-19391 , +11145 , +-17043 , +2631 , +-28615 , +5957 , +-26137 , +-3953 , +19737 , +6587 , +-12637 , +20297 , +-6929 , +-14007 , +-29721 , +24875 , +-12713 , +32559 , +20427 , +-24453 , +-5977 , +20245 , +30899 , +-22033 , +17071 , +15155 , +24135 , +-2049 , +-19477 , +-807 , +10469 , +3781 , +-16325 , +14745 , +8097 , +12363 , +-16861 , +31951 , +-23365 , +12643 , +-18565 , +-12863 , +-26479 , +-30961 , +-855 , +14901 , +23325 , +9283 , +-7589 , +11661 , +9199 , +16461 , +-24133 , +-5033 , +-5989 , +-25177 , +-11477 , +3179 , +-30273 , +26957 , +31611 , +16771 , +32367 , +19097 , +9125 , +22097 , +-18897 , +-17509 , +-3333 , +-21997 , +-5771 , +16877 , +17385 , +2745 , +4243 , +-24561 , +-21715 , +17257 , +14647 , +-26819 , +-5755 , +14249 , +29283 , +20935 , +-16399 , +-7443 , +1765 , +3563 , +7785 , +5295 , +-16825 , +8491 , +-23283 , +16653 , +23637 , +-5083 , +-4117 , +15839 , +5897 , +-10519 , +-23251 , +17479 , +15111 , +-4647 , +-16941 , +3797 , +-18789 , +14073 , +233 , +27671 , +-15579 , +22469 , +10567 , +7605 , +25883 , +-23657 , +-21059 , +23559 , +-1411 , +10861 , +-23591 , +-10705 , +-28725 , +-8117 , +-19185 , +-31063 , +13189 , +29975 , +-24957 , +13427 , +25 , +-2841 , +13101 , +-1897 , +5217 , +-14117 , +22695 , +-24509 , +12953 , +12413 , +-2481 , +17261 , +15831 , +-13425 , +20237 , +-6175 , +19971 , +19565 , +-17011 , +-30503 , +-28075 , +-5415 , +19179 , +23321 , +-17857 , +-20641 , +6131 , +-23161 , +7411 , +12067 , +4311 , +1601 , +22357 , +-12223 , +-7317 , +31795 , +-26509 , +11935 , +-20523 , +3381 , +21627 , +-18103 , +27595 , +24733 , +-27077 , +8265 , +28749 , +9819 , +-22771 , +-21767 , +10707 , +-23923 , +17755 , +3811 , +25361 , +13727 , +8591 , +-8429 , +8743 , +14549 , +-9845 , +11255 , +-28581 , +1909 , +10923 , +27561 , +-7085 , +-29619 , +-28117 , +17113 , +-14643 , +11225 , +5173 , +17939 , +10705 , +25301 , +24899 , +19363 , +2673 , +-3757 , +4649 , +26091 , +5373 , +-5543 , +12931 , +7735 , +-23623 , +32752 , +-11859 , +2075 , +4123 , +-7227 , +-11713 , +17731 , +-12675 , +5183 , +-20471 , +4561 , +19545 , +-4587 , +29821 , +-3787 , +2305 , +23139 , +-28237 , +-27771 , +-7985 , +-3769 , +-9249 , +2893 , +749 , +-5891 , +22855 , +27635 , +-30341 , +-22169 , +8377 , +26761 , +11347 , +-9157 , +-377 , +2853 , +1599 , +20869 , +6143 , +7351 , +-6993 , +-28463 , +17761 , +21863 , +6637 , +28345 , +23125 , +-4761 , +18911 , +32509 , +5351 , +-22959 , +10551 , +-17629 , +-5377 , +-6921 , +-22737 , +13699 , +28245 , +-3135 , +31165 , +12525 , +32495 , +1415 , +-31663 , +29873 , +1041 , +4319 , +4357 , +13639 , +25531 , +7171 , +21597 , +26971 , +28835 , +4377 , +13179 , +-7319 , +1701 , +-19683 , +-15145 , +2011 , +3521 , +-13529 , +-31881 , +30615 , +7059 , +9809 , +-21337 , +-30949 , +27463 , +31749 , +-16331 , +-9705 , +25621 , +-11039 , +-25823 , +-1149 , +26167 , +-30211 , +9435 , +19001 , +5731 , +29911 , +1787 , +4619 , +-8257 , +26523 , +26487 , +10585 , +-7075 , +-31225 , +7515 , +-5331 , +5169 , +-26953 , +22527 , +-6699 , +-23927 , +-6901 , +12487 , +5617 , +-28151 , +-13455 , +8017 , +1557 , +-28903 , +32325 , +-14285 , +-21791 , +-12053 , +12077 , +7729 , +21389 , +14565 , +8419 , +19961 , +-30959 , +26787 , +-15461 , +27727 , +9653 , +1643 , +29141 , +24281 , +-22751 , +-6107 , +-6733 , +-2239 , +-13045 , +23765 , +-299 , +-18179 , +-24011 , +19597 , +-3919 , +16769 , +7705 , +26351 , +29031 , +-13575 , +17657 , +6173 , +287 , +-16007 , +7283 , +31795 , +-7721 , +-7485 , +19617 , +2371 , +-10295 , +-8075 , +-14931 , +10179 , +18999 , +-831 , +16873 , +29073 , +-9017 , +-26197 , +-917 , +-12445 , +6495 , +12985 , +29721 , +11459 , +17015 , +-18121 , +-27821 , +-1405 , +-6667 , +-13599 , +5115 , +14269 , +18563 , +-17631 , +30745 , +14653 , +16739 , +-6451 , +28391 , +-6261 , +-24875 , +19031 , +-397 , +-21679 , +-21795 , +-11643 , +18869 , +-16287 , +-5979 , +24493 , +19235 , +10021 , +-23973 , +-3219 , +23501 , +-4967 , +24437 , +225 , +-8463 , +199 , +-9313 , +22363 , +-5605 , +21433 , +-27127 , +-24677 , +16815 , +28915 , +-28359 , +-7289 , +-32237 , +20845 , +23407 , +6245 , +-13003 , +-25593 , +-2185 , +9105 , +-11085 , +3207 , +-16897 , +20919 , +-26523 , +14601 , +-12427 , +-18297 , +-20097 , +28163 , +11865 , +31471 , +-32219 , +-10069 , +6679 , +26583 , +8579 , +-18427 , +-15775 , +-5293 , +23655 , +-13243 , +-5371 , +-13731 , +-23977 , +-17191 , +-26553 , +-24305 , +14117 , +-21291 , +23477 , +-25765 , +-32493 , +-18959 , +22915 , +24635 , +-13473 , +-32253 , +-24993 , +-22665 , +21857 , +-17683 , +-8751 , +29139 , +1565 , +-30433 , +12553 , +23495 , +-25495 , +-10099 , +-4549 , +701 , +-19599 , +-25567 , +12411 , +-2877 , +29665 , +-14403 , +10253 , +8903 , +18803 , +14505 , +-13497 , +19789 , +29961 , +17555 , +-33 , +25511 , +-11453 , +9983 , +-11061 , +19887 , +-20575 , +1353 , +-7023 , +6139 , +-1013 , +-16109 , +30759 , +-1383 , +-15111 , +20803 , +-32185 , +12871 , +14845 , +-9861 , +2887 , +9255 , +8931 , +14349 , +9585 , +-15365 , +6477 , +17015 , +477 , +-19237 , +24255 , +26713 , +15815 , +7277 , +-22719 , +-2833 , +101 , +-24419 , +-20367 , +-22777 , +327 , +-30761 , +-737 , +-10379 , +3873 , +29631 , +-29341 , +-6633 , +12085 , +-20893 , +-5321 , +9535 , +-4835 , +-32261 , +25485 , +-1099 , +-3291 , +-27875 , +-15387 , +29995 , +-31959 , +-19085 , +29803 , +-1737 , +-6167 , +13049 , +18055 , +24771 , +30433 , +-591 , +-12289 , +8725 , +15009 , +-15399 , +-21881 , +-13513 , +-8791 , +24231 , +28633 , +-32009 , +-4681 , +-27777 , +-13739 , +-14241 , +4009 , +-24659 , +29197 , +10407 , +15317 , +-31079 , +28265 , +9143 , +-25897 , +-25977 , +29751 , +-2279 , +6901 , +14271 , +-18361 , +-30869 , +21997 , +10845 , +3709 , +8295 , +-8365 , +-18833 , +-21133 , +17225 , +-27797 , +-17727 , +28299 , +15319 , +-391 , +-6645 , +-7549 , +-19511 , +29855 , +30381 , +4757 , +-813 , +-3533 , +31971 , +17931 , +18699 , +23707 , +6019 , +-23463 , +-30225 , +15259 , +-23761 , +2991 , +11735 , +-31945 , +21517 , +-3045 , +29673 , +-31221 , +12809 , +-18665 , +-29029 , +-22501 , +-4227 , +5031 , +19619 , +-5587 , +-28039 , +18161 , +-32655 , +-6739 , +26733 , +-28333 , +-8663 , +20721 , +15467 , +32764 , +-30697 , +-23519 , +18395 , +-11523 , +429 , +-2421 , +-10827 , +22513 , +-16139 , +-21389 , +4151 , +-28409 , +5773 , +3449 , +-3817 , +-32611 , +-23523 , +23397 , +-13235 , +29023 , +6477 , +-32379 , +27957 , +4817 , +28483 , +-2941 , +15961 , +-15751 , +23191 , +-9541 , +29597 , +22887 , +11209 , +5405 , +-20737 , +22099 , +-10689 , +16501 , +6085 , +-17349 , +21943 , +18255 , +23621 , +32113 , +10819 , +-25523 , +-27125 , +-13509 , +8893 , +-19203 , +-30561 , +8673 , +11717 , +-8915 , +12981 , +26963 , +26929 , +-1329 , +10725 , +567 , +10255 , +23109 , +-18195 , +6015 , +10005 , +6971 , +14427 , +3213 , +-22631 , +22025 , +-26161 , +24511 , +-22257 , +-28293 , +-25173 , +-9843 , +-1797 , +-24265 , +-21677 , +24603 , +20845 , +-31601 , +-15389 , +18271 , +15865 , +24025 , +-30877 , +30117 , +-213 , +6725 , +-15231 , +13499 , +9345 , +-7621 , +-30005 , +1909 , +5351 , +-5585 , +14179 , +23515 , +15783 , +-17417 , +29759 , +29101 , +8167 , +-28505 , +-24105 , +19845 , +-2909 , +-11545 , +-23711 , +4211 , +7965 , +25039 , +-31349 , +-29689 , +9693 , +-21449 , +-2125 , +27385 , +27169 , +15507 , +3995 , +-14795 , +21981 , +-12975 , +20387 , +32377 , +14385 , +32167 , +26503 , +12907 , +-30629 , +16111 , +-22647 , +10547 , +-14539 , +4739 , +-25031 , +2447 , +-18641 , +12303 , +-10079 , +-19089 , +8893 , +-21397 , +15621 , +8715 , +-5795 , +-18185 , +-2029 , +-31617 , +-29949 , +4969 , +29859 , +-21801 , +-5613 , +-16843 , +21993 , +-9799 , +31715 , +-26285 , +-5069 , +1647 , +-24669 , +-3167 , +7195 , +-14975 , +21479 , +-21313 , +12355 , +-14889 , +651 , +-165 , +-29303 , +12351 , +-25795 , +-29677 , +-15935 , +-15461 , +-19349 , +-17209 , +-6925 , +1379 , +-5441 , +6265 , +-15095 , +24273 , +14099 , +-24681 , +-11253 , +32359 , +29419 , +-14109 , +20699 , +-10731 , +-15501 , +14015 , +-23961 , +-29237 , +8939 , +-17141 , +23907 , +-15731 , +-16215 , +-12419 , +-4989 , +27157 , +28557 , +-3977 , +21297 , +-19739 , +-9481 , +14427 , +709 , +14555 , +-17849 , +-29329 , +14911 , +-6575 , +-17717 , +-23513 , +-6021 , +-9807 , +22589 , +24581 , +-30481 , +10127 , +23479 , +-21259 , +-3365 , +-11973 , +14643 , +26903 , +-27895 , +-14365 , +889 , +30503 , +2051 , +21537 , +11931 , +-28345 , +-26429 , +-17893 , +-9999 , +-2975 , +32247 , +29203 , +-11637 , +31741 , +30131 , +-12919 , +6957 , +18069 , +-26201 , +24777 , +3781 , +31343 , +-4133 , +2317 , +-1951 , +17143 , +-21017 , +-6393 , +17327 , +-24939 , +-22873 , +9737 , +1257 , +5381 , +-9609 , +-6255 , +3929 , +-4557 , +-24089 , +11115 , +21063 , +393 , +27385 , +3133 , +-19333 , +-18989 , +-32555 , +10407 , +9769 , +18833 , +-10753 , +-28449 , +8565 , +-1077 , +18707 , +4285 , +20833 , +11633 , +23549 , +11867 , +-26801 , +4913 , +-10837 , +-19155 , +9965 , +4043 , +17999 , +9623 , +-3913 , +20203 , +-6643 , +-7929 , +4845 , +-18301 , +-14787 , +27271 , +-30457 , +-11101 , +-13033 , +-27683 , +-11857 , +-18485 , +29683 , +-4319 , +-15555 , +-28725 , +-16379 , +23759 , +18087 , +-5865 , +28041 , +3687 , +12545 , +17565 , +-14971 , +-10879 , +-3215 , +5669 , +5629 , +5985 , +22949 , +-15585 , +17575 , +15645 , +3791 , +-17921 , +29745 , +-2013 , +8477 , +14873 , +13287 , +13147 , +15279 , +-7181 , +12789 , +2241 , +-12533 , +-21985 , +-6109 , +-27787 , +-8157 , +14997 , +15103 , +-2467 , +-19015 , +30859 , +-31833 , +28467 , +7271 , +7879 , +-1043 , +-12767 , +30993 , +8831 , +1315 , +10719 , +25055 , +-4433 , +16709 , +10303 , +-2641 , +4073 , +-2379 , +-19633 , +-21993 , +26809 , +-18829 , +29421 , +-14381 , +-31113 , +-17189 , +-7457 , +19907 , +11935 , +1231 , +23917 , +29283 , +-17241 , +-31361 , +-3467 , +31679 , +26719 , +-28011 , +25351 , +9711 , +3261 , +-10509 , +6523 , +20493 , +-30913 , +-7701 , +30221 , +10157 , +18367 , +-16655 , +18409 , +-29991 , +10445 , +-28705 , +-13609 , +-10111 , +10373 , +-24163 , +315 , +-6279 , +6627 , +-3225 , +-15675 , +23537 , +-6491 , +-22403 , +22389 , +4967 , +31133 , +23647 , +-2239 , +-8405 , +-5755 , +-11899 , +1571 , +17735 , +-927 , +-3439 , +25787 , +-32762 , +-25777 , +-25075 , +-21155 , +29669 , +20193 , +13477 , +-19027 , +-11257 , +23541 , +25049 , +11451 , +11573 , +-26351 , +5943 , +-21097 , +3923 , +-27597 , +12817 , +7781 , +3411 , +8495 , +-15425 , +-19455 , +-13385 , +-6007 , +29769 , +29191 , +-10879 , +3781 , +-2137 , +32635 , +28589 , +-29625 , +3447 , +10197 , +9003 , +19873 , +825 , +-8031 , +13653 , +-19335 , +12545 , +11149 , +-14617 , +-28455 , +26799 , +-21231 , +-11913 , +11007 , +-12371 , +20341 , +-17553 , +30153 , +6947 , +-13707 , +-17789 , +379 , +-22865 , +26453 , +-17241 , +-14563 , +23965 , +22909 , +3983 , +25685 , +-4447 , +-31865 , +32411 , +-8255 , +16907 , +225 , +8027 , +-29245 , +-21885 , +19427 , +-31617 , +11755 , +-14271 , +22629 , +-28847 , +-10051 , +-26945 , +31443 , +-26707 , +-10727 , +-25347 , +29645 , +8829 , +-3063 , +-18391 , +30783 , +-8533 , +30229 , +30949 , +-29201 , +8347 , +13613 , +-29959 , +5279 , +-27613 , +2029 , +8071 , +-11361 , +23815 , +2945 , +-11825 , +25581 , +24043 , +-6921 , +-421 , +20161 , +-8755 , +-27877 , +1209 , +-18257 , +17405 , +-5937 , +27579 , +-3779 , +8857 , +18401 , +24613 , +-16653 , +18301 , +-19359 , +-31251 , +-16383 , +3011 , +-10115 , +-27665 , +-18611 , +-26185 , +4313 , +-19935 , +7691 , +24909 , +6497 , +4695 , +-11815 , +29469 , +29357 , +-17555 , +14167 , +-1571 , +6089 , +-247 , +-22211 , +-30129 , +-25443 , +-28211 , +-29711 , +-32317 , +19639 , +-16877 , +-8797 , +11021 , +25263 , +-22233 , +-25881 , +-7689 , +-4107 , +8947 , +-12349 , +-4797 , +-29391 , +-1975 , +-21165 , +18201 , +27415 , +16265 , +31705 , +3077 , +-9283 , +-26647 , +-16041 , +-14223 , +-5001 , +-11489 , +29863 , +23697 , +10287 , +419 , +-27367 , +-20755 , +6713 , +22885 , +-385 , +-6839 , +-22099 , +-4353 , +-11827 , +23591 , +-6843 , +-18057 , +18993 , +5305 , +22441 , +-10133 , +22185 , +-11939 , +31825 , +-27435 , +-12261 , +-26477 , +27863 , +5179 , +-23569 , +-10633 , +24277 , +13931 , +-13533 , +-11081 , +2615 , +-27217 , +26087 , +-16121 , +-28651 , +8585 , +-11339 , +-1501 , +-1521 , +19435 , +8163 , +-9407 , +-5603 , +16617 , +-25915 , +-16887 , +-27921 , +8443 , +-2245 , +27401 , +-28481 , +-19027 , +-15151 , +-20297 , +-17749 , +-26407 , +-25009 , +22755 , +-31597 , +18015 , +-6947 , +13485 , +2405 , +4191 , +24457 , +30465 , +22015 , +28143 , +-26763 , +5515 , +3203 , +-25515 , +18523 , +26681 , +-2003 , +2745 , +-16977 , +-16607 , +-22093 , +-30617 , +29755 , +9995 , +-19441 , +-21121 , +-10199 , +5217 , +-24085 , +30253 , +30633 , +11425 , +15201 , +-30615 , +-32251 , +-6555 , +13419 , +7203 , +-5325 , +14281 , +-9307 , +-503 , +3057 , +2929 , +-7751 , +-23375 , +5731 , +-19461 , +-11995 , +-12199 , +14115 , +5619 , +20131 , +-21215 , +-17705 , +-16297 , +-17931 , +-4165 , +4181 , +-21633 , +18243 , +-6997 , +-211 , +-10589 , +10481 , +-5639 , +-5427 , +31693 , +-7691 , +19309 , +31247 , +4689 , +22711 , +-1723 , +31577 , +-10299 , +-15775 , +4461 , +23853 , +6009 , +-329 , +-19657 , +4939 , +-6031 , +31859 , +5527 , +-16319 , +-26151 , +15903 , +22483 , +-1149 , +-31229 , +5991 , +1217 , +3083 , +-31783 , +-17681 , +-16255 , +-4251 , +-20775 , +-20297 , +6315 , +-31407 , +-17013 , +-13083 , +-4333 , +-18469 , +-24969 , +16171 , +30457 , +-2071 , +-27741 , +-11633 , +15555 , +-6563 , +-31609 , +30161 , +12345 , +-32343 , +-16765 , +-23489 , +10549 , +-20507 , +-9251 , +-14589 , +-8479 , +32111 , +2355 , +9997 , +-13969 , +-6149 , +24949 , +-30883 , +-6579 , +-29143 , +-26527 , +-33 , +-10523 , +7081 , +-21643 , +12487 , +20935 , +-13883 , +-11929 , +26207 , +24175 , +-13179 , +24613 , +-14995 , +21367 , +1085 , +-7867 , +6145 , +3921 , +-13397 , +3325 , +21195 , +25465 , +14991 , +-7265 , +27389 , +10803 , +-19263 , +-25195 , +-27493 , +-315 , +7623 , +-22071 , +-32425 , +4135 , +-30479 , +29361 , +-18459 , +1605 , +-16909 , +8633 , +-25639 , +29097 , +27123 , +6463 , +15865 , +-16957 , +21805 , +23823 , +-29417 , +7575 , +29955 , +-24239 , +-149 , +27385 , +12951 , +14353 , +19563 , +28735 , +-16923 , +-27355 , +20253 , +-27519 , +-15017 , +-24399 , +-22279 , +25167 , +27109 , +-28645 , +15669 , +-7965 , +-14431 , +32133 , +7337 , +14305 , +-5415 , +30147 , +-1503 , +-27253 , +-30293 , +13519 , +-16591 , +-12423 , +23071 , +18637 , +22935 , +-18991 , +23737 , +-11403 , +22795 , +-28415 , +-3175 , +-24041 , +30103 , +-15887 , +7695 , +-11257 , +-27017 , +-825 , +-20299 , +-14429 , +29031 , +5649 , +-7679 , +-31299 , +23171 , +-9591 , +871 , +25503 , +23703 , +-5823 , +-16665 , +4983 , +12799 , +2149 , +-20179 , +-9379 , +13821 , +-5005 , +-18397 , +10941 , +-6519 , +-5655 , +-12789 , +18009 , +3767 , +-30329 , +-14053 , +17085 , +12673 , +30467 , +-10353 , +1337 , +19757 , +-15807 , +4161 , +-31919 , +-28907 , +-5361 , +-4149 , +-1851 , +4107 , +-20655 , +6671 , +19447 , +12595 , +5069 , +14431 , +22771 , +-20147 , +-24755 , +19461 , +23257 , +4761 , +16487 , +19821 , +11231 , +26925 , +-10831 , +28589 , +-27709 , +10697 , +-12175 , +-8029 , +23755 , +4403 , +-5661 , +23955 , +26417 , +-17395 , +25315 , +29751 , +29477 , +1839 , +-14801 , +-14251 , +-9921 , +-12167 , +-23265 , +13795 , +-5761 , +12343 , +18127 , +10131 , +10423 , +-15639 , +-15891 , +-1553 , +9365 , +7081 , +30943 , +-15629 , +5641 , +-2309 , +28801 , +22051 , +2635 , +17963 , +31075 , +-8921 , +-13749 , +-21729 , +-23691 , +-8999 , +14509 , +31919 , +-2997 , +-279 , +24127 , +-5243 , +-10293 , +30699 , +-8977 , +24427 , +17259 , +25081 , +331 , +-23257 , +1001 , +-7233 , +10861 , +1243 , +11649 , +31773 , +-16257 , +-10037 , +9893 , +19007 , +29097 , +-17209 , +17717 , +-21973 , +-4717 , +-4615 , +30263 , +-541 , +-10415 , +-3265 , +-6127 , +-1287 , +9703 , +9731 , +12097 , +21671 , +-21705 , +13209 , +-8817 , +6759 , +-1663 , +12039 , +973 , +-23795 , +24407 , +19315 , +-27127 , +23647 , +12819 , +-10521 , +10827 , +22309 , +7893 , +-29259 , +2503 , +-6191 , +-17931 , +-8629 , +3223 , +13187 , +1277 , +13707 , +14325 , +437 , +8997 , +-5209 , +-26893 , +-21947 , +-3005 , +-5775 , +17835 , +30735 , +-12725 , +-25033 , +9989 , +22541 , +3395 , +24097 , +15589 , +11493 , +-20041 , +-16131 , +6885 , +-24825 , +-14913 , +6563 , +27529 , +-16057 , +-16285 , +-25147 , +7 , +25067 , +-24669 , +22087 , +25191 , +24657 , +-3861 , +28703 , +25167 , +-8459 , +-32764 , +1443 , +-27599 , +-21985 , +-7015 , +-1945 , +15111 , +-21783 , +-23009 , +-3179 , +-27513 , +-16673 , +11869 , +11969 , +-33 , +-13291 , +16981 , +2373 , +-2323 , +27071 , +14797 , +5655 , +20979 , +-2741 , +-21197 , +-20447 , +-12845 , +27639 , +-11735 , +-20709 , +19653 , +-7957 , +15981 , +21727 , +-13937 , +-6199 , +18779 , +2887 , +30013 , +-13353 , +-15393 , +2687 , +-2213 , +-5249 , +16111 , +32738 , +18605 , +4221 , +-26485 , +19785 , +8289 , +7271 , +1825 , +-1807 , +27599 , +-7727 , +23453 , +-6713 , +-14163 , +-32293 , +-20017 , +27721 , +31175 , +9809 , +18283 , +-5163 , +-12747 , +28733 , +-20097 , +27783 , +29467 , +29443 , +10351 , +-5743 , +-22569 , +-27659 , +8803 , +-9203 , +-13123 , +9839 , +-2995 , +7773 , +17495 , +7281 , +-20141 , +-16381 , +7947 , +-23633 , +209 , +-7699 , +-30365 , +1837 , +8907 , +13149 , +29891 , +-21155 , +-9491 , +10039 , +29333 , +-30039 , +31223 , +31191 , +14863 , +-8035 , +-16959 , +8055 , +-12187 , +-24209 , +-16473 , +13045 , +-13439 , +20509 , +-22131 , +-715 , +-22725 , +-19187 , +26959 , +-21251 , +-23277 , +16147 , +6845 , +-10431 , +11879 , +26909 , +24593 , +22533 , +12585 , +-965 , +24807 , +-21583 , +28443 , +-31169 , +-22603 , +22761 , +14217 , +-9001 , +-27197 , +-32029 , +-31879 , +1309 , +-23127 , +15433 , +-5017 , +22455 , +13369 , +-19841 , +30081 , +14697 , +2055 , +-13937 , +-24741 , +16431 , +20307 , +16499 , +-16857 , +7385 , +19597 , +-2575 , +2665 , +8475 , +26949 , +26103 , +25661 , +-17875 , +-6237 , +-2199 , +16635 , +-18463 , +-5527 , +12935 , +-17535 , +-18381 , +2907 , +30649 , +16095 , +-28821 , +14405 , +20203 , +-15463 , +1205 , +3691 , +-6293 , +5971 , +-17615 , +27779 , +-8141 , +10003 , +-24687 , +29489 , +-3887 , +-15371 , +-19921 , +-21511 , +-30027 , +-9627 , +-31323 , +-29001 , +2825 , +-27693 , +18921 , +7583 , +-27377 , +23277 , +-17445 , +-12371 , +11509 , +14939 , +-11925 , +-32355 , +11049 , +-29201 , +31267 , +-23191 , +-24515 , +32359 , +19531 , +26685 , +-16079 , +16283 , +30327 , +1773 , +-2985 , +-30405 , +-12889 , +2289 , +-26977 , +16903 , +20439 , +-26145 , +4475 , +-10879 , +-3295 , +-18087 , +22831 , +11309 , +6475 , +31119 , +27565 , +-16823 , +32742 , +1075 , +-6167 , +-18185 , +1251 , +-25099 , +21943 , +-20981 , +6061 , +24689 , +13853 , +-14799 , +11963 , +-7503 , +29743 , +-4691 , +6577 , +-30687 , +20065 , +-3183 , +-30735 , +-20983 , +20587 , +4981 , +-25673 , +28547 , +30101 , +-7757 , +-7761 , +14319 , +2961 , +4633 , +-31477 , +-9225 , +28125 , +4385 , +6181 , +28923 , +12683 , +-6225 , +-13947 , +-25843 , +-9815 , +24899 , +23947 , +-30357 , +-21493 , +-4935 , +-15235 , +22901 , +-16721 , +12147 , +-23261 , +6183 , +-10867 , +-15583 , +-19491 , +6669 , +10479 , +5615 , +11831 , +-7743 , +-21423 , +-6853 , +21261 , +19673 , +-4687 , +19161 , +12053 , +16237 , +9575 , +-11073 , +-27133 , +-31229 , +-29055 , +-24765 , +-24551 , +9741 , +-24677 , +-5681 , +-31681 , +-11039 , +15415 , +7711 , +9889 , +-13015 , +30349 , +-15883 , +13249 , +-17685 , +-1551 , +19277 , +8213 , +-2575 , +-19041 , +20257 , +-7143 , +-15671 , +-8169 , +659 , +-13079 , +-11717 , +-5383 , +-31057 , +14683 , +-18621 , +32599 , +-2403 , +-25709 , +-29817 , +6801 , +-20385 , +-26847 , +31313 , +25513 , +-12285 , +-27755 , +27135 , +-12001 , +21853 , +-25707 , +31755 , +-18615 , +-5055 , +-8071 , +-25743 , +22311 , +-12487 , +-17825 , +-11851 , +1473 , +-17219 , +31949 , +-26027 , +1013 , +30445 , +-2121 , +-4931 , +7901 , +-14907 , +-725 , +13513 , +-20327 , +29659 , +-15527 , +-3659 , +6581 , +15759 , +31541 , +13209 , +19185 , +10957 , +-3191 , +-20645 , +30631 , +19257 , +-24431 , +-24271 , +-30563 , +19701 , +-8173 , +13711 , +26459 , +-6711 , +-11791 , +-20311 , +-17911 , +-30997 , +-25267 , +3169 , +10175 , +21291 , +31247 , +17603 , +-17049 , +-12367 , +22291 , +2817 , +-29941 , +18229 , +29867 , +5861 , +4531 , +22451 , +-13365 , +-12595 , +-26181 , +-23897 , +-26225 , +32287 , +2477 , +6081 , +-6305 , +-11705 , +21911 , +-11739 , +26503 , +-10709 , +7907 , +21 , +32327 , +9245 , +-25423 , +-12997 , +-12431 , +-31131 , +25767 , +-14509 , +10367 , +-16863 , +11355 , +-19101 , +7981 , +-22315 , +6931 , +22913 , +15499 , +31825 , +-15307 , +5369 , +3233 , +20783 , +25099 , +-6383 , +-5511 , +-19507 , +26919 , +-16831 , +-8001 , +29639 , +3127 , +-27679 , +30427 , +27109 , +-14241 , +19049 , +-15743 , +27805 , +-28147 , +-14803 , +-27185 , +11017 , +-17835 , +14473 , +8679 , +9817 , +9413 , +5539 , +-6661 , +-32297 , +-6715 , +-21345 , +17145 , +-7859 , +-7835 , +-9643 , +-29811 , +3601 , +-32071 , +-12659 , +-5945 , +-26001 , +9139 , +23481 , +-5323 , +15269 , +15741 , +-14043 , +8301 , +4701 , +-1721 , +-24653 , +-31437 , +-26203 , +14761 , +26905 , +11273 , +29793 , +-19337 , +-9843 , +-4021 , +-11955 , +13595 , +23561 , +-29243 , +-25237 , +-24727 , +30969 , +-2869 , +15617 , +-13573 , +3963 , +13009 , +785 , +-12537 , +-9967 , +-14459 , +8015 , +-10569 , +12251 , +-16793 , +14997 , +5635 , +-28843 , +25817 , +31207 , +-2297 , +-14463 , +-2875 , +8157 , +6105 , +23215 , +2987 , +-31579 , +12519 , +-599 , +17975 , +-25479 , +31691 , +-19855 , +-10139 , +-15215 , +-19807 , +30073 , +31245 , +3745 , +16355 , +-2729 , +32768 , +-15663 , +-18751 , +19711 , +31133 , +20533 , +11253 , +14463 , +10995 , +25533 , +-30945 , +-17359 , +15179 , +23995 , +25755 , +-18825 , +28745 , +-8751 , +-24613 , +21485 , +-12929 , +-25241 , +7737 , +-8659 , +28809 , +20653 , +-3495 , +-8969 , +-32345 , +-14837 , +28665 , +507 , +4301 , +-993 , +18505 , +-10497 , +14145 , +26155 , +18123 , +-22875 , +21935 , +5915 , +-14685 , +-26725 , +-14647 , +2799 , +30831 , +29269 , +-8619 , +18109 , +-28509 , +2373 , +-29493 , +1827 , +-2461 , +-17511 , +32619 , +-19129 , +-29997 , +2663 , +5333 , +-9661 , +8437 , +-18321 , +-475 , +-14043 , +15871 , +27725 , +-7039 , +14187 , +14901 , +19765 , +-5313 , +31725 , +-9665 , +-28115 , +26225 , +-21403 , +-1791 , +31673 , +-25087 , +20825 , +23027 , +-20445 , +-2741 , +-5985 , +15353 , +29225 , +20277 , +-4531 , +-15169 , +-21961 , +1731 , +-23499 , +-9079 , +14881 , +21553 , +20439 , +-28013 , +-27817 , +30351 , +9953 , +-24093 , +1953 , +31187 , +-24027 , +11943 , +-13225 , +-3727 , +28431 , +21507 , +10261 , +32637 , +-18535 , +-25993 , +-15627 , +-32717 , +-1843 , +-4437 , +-28341 , +-19941 , +8115 , +12493 , +20695 , +12963 , +9425 , +-2971 , +4225 , +-22745 , +-8671 , +-30539 , +-17779 , +-5477 , +16255 , +-7803 , +6487 , +6041 , +-15949 , +30855 , +20105 , +18171 , +10205 , +-16603 , +13527 , +-9481 , +23401 , +14563 , +-23509 , +-20819 , +-26983 , +-10711 , +4209 , +589 , +-27291 , +-22611 , +31417 , +31651 , +1291 , +-32197 , +11521 , +4915 , +-5645 , +-21739 , +14431 , +17875 , +13365 , +9419 , +11719 , +25281 , +14983 , +-19309 , +2357 , +20031 , +21437 , +14361 , +-14481 , +-28513 , +18109 , +25571 , +-25033 , +2543 , +-14093 , +-32221 , +20233 , +8699 , +-15529 , +18959 , +-29621 , +-13067 , +-27183 , +26551 , +-5873 , +15493 , +4417 , +-13213 , +19263 , +-27289 , +24563 , +24423 , +22627 , +-32387 , +-27503 , +10103 , +-11063 , +-2453 , +6049 , +-31605 , +27981 , +2217 , +-21631 , +-28117 , +-7289 , +8997 , +16079 , +19019 , +5251 , +31571 , +17781 , +-32605 , +-11779 , +6599 , +-12271 , +20109 , +1563 , +20303 , +6647 , +1871 , +6555 , +-4469 , +-14937 , +19717 , +5271 , +8701 , +32703 , +24039 , +29111 , +13999 , +16507 , +12847 , +7139 , +13121 , +-7259 , +-32151 , +-29045 , +-27777 , +20249 , +20045 , +-28593 , +133 , +-8273 , +-999 , +-32703 , +23883 , +21693 , +-22423 , +-21099 , +-63 , +-3575 , +-16757 , +-19995 , +28265 , +4163 , +29015 , +17881 , +31343 , +-11261 , +11409 , +-30613 , +3645 , +17207 , +-26959 , +12447 , +-30569 , +28957 , +15179 , +-24139 , +-977 , +-1853 , +30171 , +23007 , +11203 , +32249 , +-19165 , +-19579 , +-25937 , +27845 , +-20737 , +28911 , +-30199 , +-20637 , +-25405 , +2697 , +14903 , +-27977 , +6159 , +14227 , +18693 , +-28339 , +-20443 , +-22183 , +-31675 , +15557 , +-12347 , +28915 , +2269 , +-553 , +2949 , +1907 , +1637 , +-7491 , +28839 , +28833 , +-195 , +13375 , +-5011 , +28729 , +-8923 , +2327 , +25597 , +18841 , +-19879 , +-28681 , +-27479 , +507 , +32545 , +18419 , +21721 , +-25287 , +-11281 , +-8307 , +19795 , +19697 , +-22539 , +-3559 , +-15591 , +2637 , +15425 , +23489 , +-30267 , +-28107 , +25423 , +23543 , +-18851 , +15367 , +1313 , +15989 , +10921 , +-23857 , +14301 , +-15705 , +-28399 , +-26369 , +-15137 , +-1613 , +-7953 , +24235 , +29271 , +-11545 , +873 , +-28103 , +-5797 , +3763 , +-20277 , +-11361 , +-28545 , +-12257 , +7773 , +-28131 , +13047 , +-31539 , +-27461 , +-917 , +-13281 , +23393 , +-31055 , +-29827 , +20385 , +135 , +16521 , +8115 , +-14843 , +-9631 , +-14353 , +10389 , +-27187 , +31371 , +1089 , +-12539 , +20747 , +32387 , +-14485 , +-26109 , +-8327 , +-26963 , +-12483 , +-31273 , +23827 , +-5173 , +22337 , +1491 , +-31447 , +-25877 , +21271 , +-6009 , +515 , +32746 , +-5809 , +-27017 , +30955 , +1637 , +18107 , +-23719 , +-21811 , +14647 , +25157 , +10697 , +-32431 , +-14229 , +-13997 , +-5763 , +24685 , +15797 , +3219 , +-24567 , +-27525 , +5997 , +-6823 , +-27639 , +13535 , +521 , +-21645 , +-13599 , +21259 , +-6133 , +13193 , +-7945 , +-12755 , +4227 , +-21013 , +-923 , +-23759 , +1027 , +-25107 , +-11727 , +4457 , +28697 , +-32317 , +13835 , +27549 , +-16059 , +17107 , +11395 , +-4693 , +-21649 , +1679 , +-2119 , +28305 , +22757 , +30671 , +5793 , +18195 , +30667 , +8359 , +-20811 , +17613 , +-8677 , +-4925 , +22573 , +459 , +-997 , +27699 , +-15181 , +30881 , +-10929 , +-4397 , +14505 , +11525 , +-18441 , +4121 , +20173 , +-16159 , +27401 , +-13457 , +-381 , +19957 , +2721 , +-20211 , +23683 , +23529 , +19199 , +21327 , +3603 , +-13599 , +23039 , +-31605 , +-6463 , +-30049 , +5901 , +32113 , +-22379 , +30223 , +-9821 , +-31785 , +24277 , +11117 , +32311 , +10779 , +19249 , +14545 , +-3647 , +-16649 , +-8835 , +30027 , +-3161 , +1499 , +-21007 , +-8577 , +17979 , +-12351 , +-3623 , +-11595 , +1457 , +-29559 , +25293 , +-135 , +23961 , +27857 , +4209 , +-9043 , +21715 , +11333 , +5283 , +3113 , +-6135 , +7301 , +-24005 , +30149 , +10925 , +-30605 , +26169 , +30719 , +-22939 , +2061 , +-19571 , +1293 , +-20211 , +-9019 , +28987 , +1139 , +-3795 , +-4519 , +17193 , +-11997 , +-14103 , +-32721 , +-6847 , +11273 , +-8315 , +14117 , +12601 , +31533 , +-32425 , +-30737 , +-14649 , +-21177 , +3649 , +9713 , +-12719 , +-26153 , +11937 , +-30065 , +-12749 , +13757 , +1749 , +11531 , +2665 , +29781 , +8495 , +-32035 , +26323 , +11527 , +18021 , +24709 , +17379 , +-8859 , +-875 , +-11539 , +19933 , +-24637 , +-6987 , +2361 , +-18807 , +11851 , +-20849 , +26401 , +-11921 , +19097 , +-9417 , +22473 , +-30069 , +25043 , +1539 , +-1763 , +-20595 , +-15043 , +-5119 , +14243 , +-31867 , +20309 , +-5639 , +29395 , +-27353 , +-12953 , +10453 , +16885 , +20345 , +1449 , +12455 , +29047 , +15633 , +-20011 , +6681 , +-12099 , +30157 , +17977 , +5737 , +-6009 , +12043 , +-8877 , +-31267 , +12733 , +-6569 , +8173 , +21697 , +-6963 , +7863 , +-32337 , +-10535 , +-1663 , +10319 , +-21957 , +-9891 , +28503 , +-5465 , +25283 , +9069 , +30297 , +10585 , +-8159 , +7439 , +-28551 , +15183 , +-16015 , +-11103 , +17251 , +-21383 , +-25819 , +6867 , +29397 , +-15861 , +26271 , +-4829 , +-1153 , +22823 , +-20913 , +-6449 , +-22961 , +6179 , +-12735 , +-4019 , +3159 , +27193 , +8505 , +-6837 , +-31975 , +15811 , +29261 , +26909 , +-22175 , +-781 , +-29955 , +-24131 , +-21337 , +-18173 , +13765 , +4411 , +-8489 , +-3 , +-29377 , +17855 , +-19273 , +21727 , +-4173 , +-26631 , +-15173 , +-15767 , +28463 , +-20455 , +-8621 , +-32705 , +5669 , +2379 , +-11817 , +8881 , +-10113 , +11185 , +201 , +19693 , +-30411 , +-11051 , +20159 , +23991 , +-21397 , +-14689 , +-30035 , +3745 , +32259 , +29915 , +-5939 , +32197 , +1211 , +18717 , +-23327 , +-26119 , +-30277 , +-19123 , +25891 , +27021 , +19641 , +-13167 , +30091 , +9083 , +-13175 , +-25913 , +29613 , +-27865 , +31803 , +-3453 , +-31977 , +-16749 , +15529 , +-5757 , +-24033 , +18199 , +29341 , +-17495 , +14143 , +31897 , +4443 , +19565 , +28401 , +-25787 , +29125 , +-291 , +-32255 , +11209 , +19943 , +7187 , +31847 , +-509 , +-18147 , +-32731 , +-25437 , +-18871 , +27807 , +-14931 , +-7283 , +25869 , +16541 , +-22611 , +-4941 , +8487 , +10715 , +-11751 , +-22733 , +7297 , +-27711 , +-10041 , +1803 , +11097 , +28411 , +-29469 , +18167 , +13803 , +-13171 , +26863 , +-11577 , +-29509 , +23913 , +19255 , +29241 , +-26819 , +-20851 , +14025 , +-13235 , +-10985 , +31125 , +21231 , +-9437 , +-22063 , +-7721 , +-7903 , +26703 , +-5355 , +-2567 , +24969 , +10669 , +-22169 , +19977 , +-25109 , +-26943 , +11089 , +7701 , +-11475 , +3723 , +-27863 , +-27323 , +-20159 , +26083 , +10051 , +-7823 , +27051 , +30277 , +-19287 , +-20679 , +-31637 , +-15045 , +1109 , +32413 , +-19589 , +-9181 , +-9501 , +-23527 , +23759 , +26775 , +31441 , +20021 , +4797 , +-17095 , +8501 , +26531 , +-19707 , +-13551 , +29937 , +-21033 , +25657 , +11105 , +24685 , +-11237 , +10695 , +20995 , +19919 , +2861 , +18015 , +-32705 , +15801 , +-15025 , +9465 , +-28647 , +-20365 , +3815 , +69 , +12347 , +-9805 , +21395 , +167 , +-22465 , +5835 , +-6209 , +2219 , +-17013 , +8031 , +11969 , +-6141 , +-12117 , +-5973 , +-19085 , +11515 , +-13529 , +-19673 , +6467 , +19565 , +-2597 , +15057 , +5071 , +22593 , +20435 , +-32295 , +-31999 , +-923 , +32155 , +11747 , +-14943 , +-1479 , +-5861 , +-4173 , +17521 , +-9577 , +10739 , +-4753 , +32709 , +3649 , +20047 , +-22699 , +31123 , +13529 , +7231 , +20205 , +-11241 , +-15777 , +-7283 , +2247 , +31975 , +-17627 , +-2021 , +4279 , +15493 , +-16827 , +27829 , +14463 , +637 , +5791 , +9837 , +-18157 , +17917 , +2633 , +-8077 , +-12719 , +21225 , +8337 , +14439 , +5425 , +-9353 , +-27027 , +23353 , +9349 , +-22969 , +-18061 , +27261 , +22567 , +-20235 , +24919 , +12867 , +18111 , +-24773 , +16349 , +18287 , +-9743 , +-12671 , +16215 , +9873 , +-32491 , +-6667 , +-22635 , +27459 , +30325 , +15145 , +16741 , +-18445 , +-28929 , +-7385 , +12423 , +26183 , +-29567 , +-14329 , +-17375 , +-26633 , +27231 , +-25843 , +-16957 , +-16363 , +-25397 , +-1219 , +-4397 , +15609 , +-17795 , +-22417 , +-13175 , +6793 , +-30481 , +6897 , +19049 , +-27365 , +-7409 , +22423 , +2875 , +29897 , +29301 , +22615 , +22653 , +-9909 , +-19671 , +-7845 , +-28571 , +-29113 , +14795 , +6821 , +16973 , +-32713 , +-19373 , +-14823 , +-20039 , +27063 , +-25275 , +27165 , +-2109 , +20831 , +6515 , +18611 , +31509 , +-4071 , +-2013 , +31495 , +-2453 , +-26623 , +19929 , +2453 , +-14979 , +-19533 , +-24183 , +22709 , +-20351 , +30251 , +9285 , +-15943 , +-4581 , +-11499 , +-5245 , +-20353 , +-27679 , +22445 , +-23087 , +7573 , +11589 , +-1005 , +-15861 , +-17209 , +-20203 , +-31451 , +-32499 , +-18381 , +-29325 , +-28977 , +-5637 , +20467 , +589 , +-10509 , +6377 , +13855 , +-32179 , +-8017 , +-8165 , +-139 , +21087 , +-30653 , +13245 , +-32661 , +8093 , +-24735 , +22551 , +28359 , +-15411 , +10759 , +19019 , +8119 , +-4011 , +21467 , +23431 , +-17815 , +-2117 , +-18949 , +30399 , +-18651 , +28051 , +1373 , +2279 , +739 , +-11011 , +-15967 , +937 , +-24733 , +5531 , +-915 , +-3425 , +6087 , +-4343 , +-11965 , +-25851 , +-24155 , +8919 , +-23077 , +7673 , +17067 , +-29441 , +-13579 , +5425 , +-11605 , +-7459 , +-27205 , +-24019 , +12853 , +20645 , +-30319 , +-6151 , +-29259 , +-21147 , +-21905 , +-6311 , +1289 , +32111 , +-28741 , +13709 , +-28781 , +31575 , +20381 , +-31357 , +29913 , +-8337 , +-9509 , +31627 , +12695 , +7611 , +-7887 , +-15465 , +8541 , +21097 , +-10713 , +-7697 , +-15199 , +5321 , +11879 , +-18837 , +-1191 , +-5949 , +28055 , +10791 , +3093 , +1753 , +7353 , +-65 , +-12397 , +-19825 , +16625 , +15877 , +-10019 , +-10385 , +27375 , +11575 , +-3621 , +9345 , +-2371 , +24255 , +-15247 , +24121 , +-27623 , +-18591 , +2061 , +7931 , +-20659 , +-3079 , +3019 , +-16885 , +-11637 , +-24397 , +-2809 , +-27387 , +-26689 , +-1347 , +-30093 , +23517 , +17127 , +-19319 , +-7245 , +-11441 , +-25357 , +5245 , +-10893 , +30167 , +10003 , +26157 , +29183 , +26415 , +16021 , +13841 , +30305 , +23105 , +18749 , +20423 , +-1047 , +-23131 , +-32233 , +-2371 , +18009 , +16017 , +32475 , +20851 , +1645 , +-11685 , +1461 , +32555 , +-5889 , +-18845 , +19373 , +20521 , +-13673 , +-6499 , +13169 , +6249 , +26499 , +-13701 , +-23367 , +-27437 , +-8075 , +-1945 , +-27627 , +23283 , +-5225 , +-20541 , +-11441 , +-13509 , +2595 , +16727 , +16949 , +-595 , +-25991 , +7759 , +30723 , +-24293 , +7869 , +-14925 , +32045 , +17629 , +-28691 , +18523 , +-21065 , +1293 , +5489 , +-25747 , +23579 , +4407 , +-1729 , +29005 , +19601 , +1433 , +12397 , +-12005 , +-24337 , +-28971 , +20549 , +9389 , +19711 , +20523 , +18409 , +-2817 , +-21671 , +-31689 , +-18851 , +3377 , +19127 , +20507 , +13607 , +15359 , +-29741 , +16711 , +28521 , +27573 , +10169 , +-4699 , +23919 , +18603 , +13987 , +11865 , +31957 , +11837 , +-12469 , +-4881 , +23827 , +-28099 , +-10545 , +-1245 , +22683 , +-22799 , +6397 , +-4855 , +-11667 , +27535 , +16687 , +28107 , +-12237 , +-7381 , +-13403 , +1765 , +18649 , +-21969 , +-30885 , +-11817 , +-93 , +-23967 , +-16287 , +3171 , +17347 , +-4789 , +-21835 , +1851 , +27769 , +-4807 , +9625 , +26439 , +27037 , +-31561 , +28521 , +12625 , +16583 , +19585 , +-7685 , +-26559 , +-12579 , +-2055 , +20329 , +1497 , +-22995 , +-24535 , +6013 , +21991 , +24837 , +11571 , +-29327 , +-17409 , +16589 , +-27059 , +-14753 , +19381 , +29085 , +12345 , +26627 , +-25775 , +-13739 , +-15819 , +-28633 , +30991 , +24887 , +-26241 , +27755 , +10957 , +-13061 , +21319 , +-25947 , +12359 , +27243 , +-27351 , +-5703 , +-45 , +32377 , +27675 , +-27921 , +-19055 , +-29479 , +-30213 , +-31799 , +11565 , +-17643 , +6509 , +-12189 , +32267 , +-26581 , +24677 , +-6593 , +21003 , +8349 , +-5859 , +-26711 , +3769 , +22289 , +27011 , +-26747 , +18697 , +18789 , +8505 , +32173 , +31627 , +-9659 , +-6641 , +-5173 , +30503 , +10057 , +-26891 , +-5461 , +-31147 , +-7289 , +11637 , +6161 , +-17711 , +32429 , +9645 , +-17123 , +24021 , +28831 , +29891 , +25879 , +-1321 , +-32383 , +-14877 , +3275 , +-845 , +26205 , +13745 , +-32155 , +21875 , +-30153 , +17477 , +3525 , +10361 , +23453 , +13727 , +-1709 , +-4283 , +-2357 , +-26459 , +4961 , +4257 , +-31683 , +11411 , +-16391 , +25179 , +9157 , +-8961 , +-19651 , +-29307 , +-17369 , +3135 , +-5063 , +-13019 , +-30929 , +-7049 , +2113 , +-147 , +-19893 , +-6405 , +-31041 , +-32389 , +-5217 , +29273 , +5529 , +-12923 , +13219 , +30405 , +32255 , +21407 , +-13517 , +4377 , +18881 , +-31515 , +-27091 , +17477 , +-18127 , +-30403 , +-13685 , +-30383 , +8563 , +-26743 , +17397 , +28109 , +19289 , +26725 , +21465 , +-1849 , +-5449 , +-17577 , +26121 , +3665 , +-14783 , +26257 , +20943 , +-30361 , +-22563 , +-5857 , +-20603 , +17523 , +-21123 , +-2141 , +2731 , +-14269 , +4731 , +-1133 , +18567 , +-9861 , +2409 , +-795 , +6961 , +-25449 , +-16785 , +-4525 , +-9929 , +-30631 , +6693 , +-11255 , +-28241 , +-8505 , +23777 , +-17181 , +-19255 , +-7005 , +10907 , +1575 , +10487 , +-28833 , +7999 , +-7757 , +9333 , +-7783 , +-31871 , +-26943 , +-23705 , +-20973 , +14911 , +29977 , +-11655 , +-1755 , +32337 , +-3389 , +17893 , +-20291 , +-30495 , +-5041 , +21791 , +-3371 , +-18357 , +32639 , +29407 , +-26013 , +20333 , +30847 , +-9797 , +19167 , +25981 , +-13909 , +25925 , +-19919 , +7791 , +1461 , +-4191 , +14631 , +-15431 , +21611 , +2967 , +-9609 , +-10819 , +-9753 , +29491 , +22577 , +-21095 , +2121 , +729 , +-30795 , +-14469 , +-11279 , +-26403 , +-5073 , +19839 , +16951 , +-20071 , +22413 , +-1271 , +19101 , +6155 , +-13831 , +-3945 , +-32115 , +-32021 , +18379 , +-28645 , +-29805 , +30267 , +-8691 , +-1579 , +-17393 , +16745 , +-29341 , +16807 , +-1427 , +29161 , +21395 , +-2831 , +17125 , +-28099 , +2927 , +2281 , +-12375 , +-29281 , +23387 , +-13969 , +23459 , +-28657 , +27189 , +-8087 , +30633 , +-17681 , +-27939 , +3483 , +27199 , +-31209 , +-12767 , +-22793 , +-28225 , +9585 , +2873 , +31109 , +-16099 , +-13553 , +11971 , +8873 , +-28899 , +7621 , +-4041 , +31241 , +4103 , +-17345 , +19931 , +9181 , +-3611 , +9367 , +-12475 , +-7221 , +29487 , +-10127 , +20043 , +-14277 , +11287 , +5523 , +32381 , +-14795 , +8751 , +-1285 , +-5345 , +-8783 , +7847 , +29301 , +-23651 , +24185 , +-16633 , +-18759 , +20105 , +25975 , +14439 , +-12803 , +-9457 , +10899 , +17697 , +-12017 , +-30487 , +14089 , +13589 , +22259 , +32479 , +7235 , +-26543 , +-8979 , +-22593 , +-15569 , +31831 , +-31959 , +3529 , +-5097 , +-19507 , +-2619 , +27831 , +-2311 , +8379 , +-9611 , +12841 , +-29599 , +31035 , +-25963 , +-23387 , +16061 , +32439 , +-7747 , +26889 , +-17349 , +8097 , +-22303 , +7815 , +-22247 , +31657 , +9701 , +18713 , +-17785 , +17011 , +30645 , +17023 , +10741 , +25813 , +26335 , +27057 , +6387 , +-28533 , +4775 , +18649 , +-641 , +28267 , +-7515 , +-5683 , +-20755 , +6953 , +-27437 , +4359 , +11055 , +-11647 , +-16331 , +-26855 , +-21325 , +17655 , +-23585 , +-26457 , +10433 , +-28655 , +-25957 , +-19229 , +-12729 , +20745 , +2807 , +4733 , +-25283 , +-13819 , +11239 , +25379 , +-20875 , +-28201 , +30161 , +-25229 , +17395 , +-14807 , +6191 , +-23175 , +14797 , +14401 , +19367 , +-25697 , +-4231 , +-29645 , +-10089 , +2603 , +16813 , +-15723 , +-21953 , +-22215 , +-21329 , +9407 , +-14777 , +-3795 , +12085 , +2945 , +-32539 , +13225 , +1465 , +30807 , +17775 , +29457 , +-10671 , +-1759 , +-13455 , +-20359 , +25863 , +-12701 , +4167 , +-6117 , +26803 , +-13323 , +-4805 , +29787 , +-26545 , +-5059 , +-24045 , +3891 , +-30507 , +3561 , +11307 , +10797 , +29585 , +-11229 , +-15849 , +-11035 , +31997 , +8525 , +19375 , +-5645 , +-27627 , +9271 , +11945 , +-17813 , +-32205 , +28635 , +18359 , +-4137 , +17255 , +5515 , +26653 , +-9049 , +16203 , +14771 , +12229 , +-3283 , +31327 , +6929 , +-25641 , +-25827 , +22495 , +1123 , +8665 , +7539 , +1051 , +8361 , +-20675 , +-8451 , +8017 , +-22055 , +25987 , +-24247 , +-16125 , +27161 , +27331 , +545 , +27599 , +1905 , +-22827 , +-3713 , +2501 , +4621 , +-15137 , +22025 , +-30393 , +19693 , +20847 , +-26619 , +12889 , +10525 , +19733 , +19161 , +19577 , +-5259 , +2933 , +-21255 , +11515 , +29893 , +-18711 , +13925 , +17891 , +9371 , +20625 , +-4705 , +19765 , +-12693 , +-31505 , +-17629 , +5329 , +14681 , +11515 , +29537 , +10963 , +8797 , +-11329 , +-12493 , +-9639 , +14609 , +6255 , +2771 , +-23315 , +3793 , +17659 , +25435 , +-13231 , +28811 , +-3793 , +10931 , +1249 , +8933 , +2633 , +-22003 , +-6049 , +30973 , +5899 , +-29983 , +16727 , +-16993 , +4189 , +-417 , +-14611 , +-6403 , +-22953 , +23405 , +24893 , +-29461 , +18925 , +27411 , +-29139 , +-26225 , +-11535 , +7047 , +-309 , +-21345 , +6843 , +-11889 , +1307 , +-22245 , +25401 , +4237 , +-5507 , +25979 , +-7537 , +-20251 , +-14727 , +-2445 , +19233 , +23809 , +-4579 , +-29661 , +-22469 , +-29495 , +-27695 , +22993 , +26395 , +-18543 , +-20553 , +-32733 , +-7017 , +-2915 , +-14217 , +29143 , +22309 , +-15857 , +-19293 , +-13579 , +28035 , +10857 , +-4987 , +4751 , +31171 , +121 , +-31617 , +24309 , +-32535 , +27099 , +26591 , +21611 , +1795 , +28655 , +-5069 , +30311 , +-4167 , +-12467 , +21805 , +17219 , +19319 , +-16961 , +24813 , +4729 , +26861 , +-8515 , +29925 , +11611 , +829 , +7773 , +-31963 , +6723 , +-7035 , +-21803 , +16447 , +-28069 , +-11013 , +-15259 , +-15977 , +6595 , +11913 , +-25631 , +7231 , +-19883 , +-4899 , +-2149 , +7245 , +-24357 , +-28149 , +-10531 , +-21327 , +-17213 , +-18535 , +-13337 , +1939 , +16989 , +-23519 , +17509 , +18213 , +-24695 , +-17047 , +30819 , +28417 , +13051 , +12017 , +14277 , +-31239 , +30189 , +-25325 , +20037 , +-10123 , +-30635 , +15517 , +-18969 , +-1203 , +-26717 , +9957 , +20467 , +-22761 , +6129 , +16989 , +23657 , +1037 , +18371 , +-26703 , +26617 , +32343 , +-2501 , +27491 , +-6011 , +-17685 , +977 , +-3113 , +16395 , +-15129 , +-27253 , +1013 , +24103 , +2915 , +29365 , +-32199 , +-18427 , +18379 , +-31459 , +1111 , +-12579 , +-6985 , +-3133 , +26439 , +-791 , +-699 , +-12265 , +-17441 , +-16161 , +-29455 , +-12879 , +24561 , +16357 , +-6169 , +-889 , +-25631 , +13837 , +5093 , +-603 , +-25415 , +3403 , +6535 , +-21917 , +8897 , +21231 , +-6611 , +-23003 , +-17249 , +17303 , +-10683 , +-11639 , +-6425 , +-23117 , +-32723 , +7717 , +-6093 , +-21905 , +-10363 , +-23107 , +-15933 , +3379 , +16653 , +-24577 , +3209 , +10651 , +-20745 , +2991 , +6861 , +16365 , +24003 , +-26509 , +13885 , +-24559 , +18835 , +-15883 , +21127 , +-3319 , +-3065 , +-27221 , +3189 , +23275 , +-28011 , +6921 , +19835 , +-24233 , +15711 , +-10693 , +27611 , +11375 , +13959 , +23893 , +7991 , +-3503 , +-7663 , +30745 , +8615 , +8969 , +-31179 , +-15835 , +-10921 , +-16109 , +27701 , +18347 , +-14699 , +-8117 , +31159 , +5295 , +25207 , +-15513 , +-9567 , +11959 , +-17943 , +-28687 , +-11411 , +-3825 , +-22203 , +-12099 , +21501 , +17267 , +15471 , +32479 , +25339 , +-23731 , +-22675 , +-14037 , +-1617 , +30579 , +-21635 , +21025 , +26705 , +-22953 , +-16211 , +7281 , +-9493 , +-6467 , +-9231 , +-8725 , +5799 , +-15615 , +10689 , +-3847 , +1965 , +-14661 , +-27349 , +-25447 , +14201 , +-12535 , +29555 , +-5423 , +-15433 , +-2755 , +11293 , +-14931 , +-4719 , +3093 , +13717 , +-27983 , +-9837 , +10109 , +15931 , +1235 , +-26629 , +9909 , +-9729 , +23799 , +3477 , +-18149 , +-29569 , +-12063 , +-10993 , +-10917 , +-30831 , +20655 , +-20265 , +6949 , +-2449 , +25297 , +-23187 , +5991 , +11575 , +20101 , +21565 , +-7415 , +-27369 , +19655 , +-20743 , +5151 , +-21283 , +-2095 , +-25745 , +31139 , +-2545 , +-20209 , +-24605 , +-26193 , +9855 , +13717 , +12259 , +27189 , +30319 , +6429 , +-20061 , +15407 , +25373 , +24439 , +-11311 , +20837 , +-16929 , +-4981 , +19445 , +5275 , +24511 , +713 , +-27329 , +27721 , +22923 , +-30689 , +-14365 , +8153 , +-1929 , +18815 , +8437 , +-14503 , +30505 , +-2875 , +21177 , +15799 , +-19619 , +315 , +13701 , +3447 , +-16397 , +16013 , +-3825 , +-12309 , +-21615 , +16965 , +13901 , +-2323 , +21425 , +27575 , +-24123 , +-1773 , +-25539 , +-18805 , +-8595 , +22635 , +-7253 , +5029 , +-24321 , +31667 , +2961 , +-32601 , +5073 , +-11763 , +-4677 , +-27165 , +-13523 , +14651 , +-27193 , +-15657 , +-9683 , +7765 , +5947 , +-3803 , +8199 , +20737 , +22559 , +-14843 , +26103 , +299 , +-22513 , +14917 , +25995 , +-8385 , +31711 , +-16195 , +20343 , +-10527 , +9639 , +-19639 , +-5379 , +23583 , +-7843 , +15931 , +-6729 , +-15567 , +3573 , +-32165 , +27633 , +-25939 , +-5393 , +9565 , +-24185 , +-32707 , +-19851 , +2257 , +4921 , +26589 , +26613 , +24489 , +-18301 , +-12913 , +13103 , +-9691 , +-25097 , +-13935 , +-24615 , +8273 , +-12273 , +32537 , +-26195 , +21243 , +-24945 , +-8821 , +32009 , +-13525 , +-12205 , +11315 , +5125 , +-12259 , +-8271 , +22649 , +-10237 , +31673 , +-10427 , +32415 , +20435 , +-31357 , +-6315 , +-23309 , +-7613 , +11297 , +19359 , +8585 , +-2755 , +-2747 , +-26185 , +-23945 , +-20139 , +31795 , +4065 , +20611 , +16879 , +1705 , +-927 , +1127 , +-5689 , +6247 , +-10919 , +1667 , +-15331 , +-17127 , +6431 , +20755 , +-30155 , +-16163 , +-28903 , +-13075 , +13699 , +-28885 , +267 , +-32589 , +-10691 , +-4005 , +1273 , +10891 , +30313 , +23961 , +-4225 , +15457 , +24967 , +9043 , +-31071 , +-19825 , +-22373 , +2629 , +-29401 , +-17117 , +15047 , +-16675 , +-16777 , +-19567 , +27243 , +-20673 , +21229 , +19179 , +14003 , +-26697 , +-23377 , +-31083 , +12727 , +30135 , +3339 , +23433 , +23311 , +6475 , +-28091 , +32259 , +-14619 , +3341 , +32253 , +20927 , +27039 , +3237 , +29691 , +29871 , +-8223 , +-15937 , +8589 , +-9167 , +-29897 , +-127 , +7517 , +-817 , +-9439 , +13437 , +4039 , +-2963 , +6831 , +19259 , +-17477 , +12041 , +-25953 , +-20197 , +5 , +32233 , +-28695 , +-17443 , +26929 , +6499 , +32481 , +9619 , +27617 , +-31485 , +-30005 , +-10473 , +-8285 , +-12719 , +-32267 , +-18169 , +-11705 , +7679 , +-439 , +-15553 , +19387 , +5035 , +29293 , +711 , +6753 , +-7155 , +31577 , +-12715 , +16361 , +-20043 , +20073 , +-7869 , +5801 , +6211 , +-25603 , +-27389 , +-14483 , +25113 , +-16757 , +-3815 , +10203 , +24731 , +-29123 , +-13929 , +-26297 , +24293 , +-20221 , +-23539 , +1 , +9983 , +-16597 , +-25847 , +27457 , +-28265 , +5249 , +-2039 , +-31383 , +-26565 , +-23073 , +-17417 , +25837 , +25101 , +-19641 , +-12767 , +-10841 , +17155 , +-20871 , +2477 , +-19799 , +9621 , +11797 , +-7789 , +26781 , +22265 , +17701 , +-11497 , +14485 , +11741 , +5947 , +24255 , +21359 , +-31841 , +271 , +-16435 , +26015 , +30721 , +11661 , +6709 , +-21619 , +30563 , +-4237 , +22289 , +9845 , +-1151 , +-18585 , +26533 , +2479 , +-355 , +-369 , +9929 , +-1899 , +-26297 , +-595 , +-28435 , +11475 , +-15735 , +-30543 , +-30073 , +7489 , +-21849 , +-6449 , +-4847 , +-17089 , +-22449 , +-221 , +4735 , +-4987 , +12377 , +-20033 , +-26821 , +12161 , +-12295 , +-19133 , +-30061 , +18481 , +-24195 , +-12037 , +-14913 , +-14479 , +13183 , +-13457 , +-24245 , +12001 , +23201 , +-6779 , +-16103 , +-17617 , +-6721 , +14865 , +11989 , +28409 , +-21325 , +-9745 , +31471 , +30241 , +-3713 , +-871 , +7179 , +31139 , +-29681 , +7497 , +-15095 , +-1037 , +-10133 , +23681 , +-5779 , +21969 , +-8331 , +-463 , +10333 , +27551 , +-19941 , +23623 , +-10721 , +-19651 , +28433 , +9677 , +23559 , +-23965 , +-5365 , +17015 , +-22795 , +7533 , +29555 , +13001 , +23627 , +-317 , +-23647 , +17569 , +3429 , +20137 , +-15211 , +29785 , +8593 , +17299 , +-20693 , +21083 , +-20851 , +-23803 , +-22311 , +-15045 , +-2189 , +-25883 , +13023 , +73 , +-13769 , +-21669 , +17415 , +-31053 , +29607 , +-18149 , +-6949 , +-27885 , +-32301 , +-8115 , +-22955 , +-17523 , +3347 , +8153 , +-5341 , +10857 , +-16519 , +30023 , +31577 , +17185 , +21189 , +-32495 , +23207 , +3075 , +-17179 , +19325 , +22805 , +13383 , +-15635 , +16887 , +22075 , +3747 , +10883 , +1255 , +-20747 , +22631 , +16873 , +7689 , +-12897 , +9491 , +-2463 , +14153 , +21705 , +-14737 , +12603 , +-5615 , +-9099 , +2337 , +-19657 , +-16593 , +-17973 , +-25137 , +9873 , +30493 , +-14001 , +1705 , +-24731 , +13033 , +-19555 , +-7801 , +17085 , +-27263 , +-23393 , +-6521 , +19443 , +30099 , +-4791 , +29469 , +10427 , +14303 , +-30777 , +-1623 , +-7281 , +27153 , +-2497 , +11673 , +-27473 , +-18917 , +29705 , +17403 , +4499 , +-14835 , +-3747 , +8341 , +-27931 , +12391 , +-11885 , +-14469 , +-30467 , +1273 , +-7201 , +-5333 , +22225 , +4663 , +-29059 , +-4315 , +11127 , +31505 , +-23437 , +14079 , +-19953 , +-19125 , +-8765 , +6659 , +-12211 , +-30635 , +27177 , +21313 , +11105 , +9385 , +-27059 , +17959 , +-21637 , +-5229 , +-1157 , +-4191 , +-19019 , +-97 , +12773 , +-9303 , +21661 , +13661 , +32077 , +-2207 , +1821 , +31941 , +27715 , +-26709 , +28157 , +23309 , +-7707 , +-29629 , +-28715 , +-29445 , +-32251 , +-26797 , +-5237 , +27079 , +-2059 , +8595 , +4417 , +7783 , +4017 , +-32043 , +-1571 , +22899 , +6555 , +-18649 , +-11025 , +32629 , +-28493 , +-10137 , +-31437 , +-59 , +31573 , +13403 , +-31859 , +-7713 , +32355 , +22345 , +24695 , +9019 , +6925 , +-7405 , +-25603 , +-605 , +3837 , +-30007 , +3127 , +-20973 , +20245 , +2751 , +-30145 , +-11257 , +-27481 , +30001 , +7595 , +345 , +-2777 , +-21679 , +24193 , +-28005 , +31855 , +23263 , +17843 , +26595 , +16743 , +22599 , +9237 , +-27085 , +-4789 , +-21197 , +-2091 , +-22201 , +11611 , +13221 , +-10121 , +-29199 , +1815 , +5523 , +-20157 , +-17173 , +-30985 , +2295 , +587 , +-16839 , +-15971 , +-24463 , +-8235 , +-25351 , +-24685 , +-30637 , +-6051 , +25533 , +27525 , +2119 , +26889 , +14691 , +-25869 , +-24233 , +26785 , +13937 , +-13973 , +8339 , +-12025 , +-29979 , +24127 , +-475 , +28465 , +3221 , +-11065 , +24801 , +415 , +-14847 , +7947 , +-24981 , +3411 , +-25169 , +6915 , +-28735 , +-20149 , +-20991 , +-28083 , +-28067 , +12403 , +25997 , +-17303 , +-29239 , +27175 , +2041 , +-17557 , +-10823 , +-1759 , +-22711 , +2867 , +16543 , +12541 , +11715 , +23339 , +19139 , +-19939 , +-28609 , +-13701 , +-25115 , +-13253 , +-16127 , +-319 , +-10935 , +26441 , +31509 , +3401 , +-10671 , +-21765 , +32289 , +-20793 , +-27235 , +7345 , +21181 , +-19061 , +-24421 , +27643 , +12113 , +15933 , +17311 , +-23159 , +5483 , +-27883 , +-23423 , +1189 , +-16497 , +14733 , +-22095 , +6957 , +30623 , +8869 , +1487 , +-30713 , +28063 , +30091 , +16323 , +-3041 , +-22753 , +-4895 , +3923 , +-29225 , +7943 , +15983 , +-6587 , +-17653 , +11769 , +-31401 , +-535 , +14713 , +-11489 , +9945 , +-16071 , +26055 , +-2681 , +10623 , +-5265 , +-7951 , +13821 , +30423 , +13087 , +19531 , +26981 , +-77 , +-9779 , +21489 , +21383 , +15063 , +-2041 , +-16449 , +-17799 , +-2503 , +-8713 , +-15663 , +27239 , +-3403 , +24709 , +16749 , +16885 , +16961 , +27363 , +17805 , +-8433 , +-8015 , +-21323 , +22985 , +1101 , +32481 , +-17259 , +721 , +20155 , +-1929 , +-30917 , +3949 , +21569 , +27669 , +25361 , +-2325 , +-15763 , +28181 , +-24505 , +-481 , +-27177 , +19907 , +-4757 , +23251 , +495 , +-6903 , +26763 , +3529 , +8541 , +-5447 , +-19267 , +-21719 , +1749 , +16179 , +-5053 , +-13951 , +18029 , +11179 , +-14557 , +20277 , +-28807 , +3037 , +-12745 , +22145 , +28387 , +23099 , +-3381 , +-8219 , +-11777 , +-26953 , +25265 , +2861 , +25061 , +-21 , +-3871 , +3795 , +20303 , +-26915 , +-5497 , +-23025 , +-22811 , +25899 , +-20319 , +11581 , +-14817 , +32207 , +-4585 , +9439 , +2199 , +-20401 , +-15797 , +21261 , +17895 , +26233 , +-18367 , +15221 , +14331 , +-23401 , +-7639 , +9679 +}; +#endif +#elif (CODEC_SAMPLERATE == 44100) +#if (CODEC_TESTMODE == CODEC_1KSIN) +const int16_t sinwave[] = { + 0 , + 0 , + 4652 , + 4652 , + 9211 , + 9211 , + 13583 , + 13583 , + 17679 , + 17679 , + 21418 , + 21418 , + 24722 , + 24722 , + 27525 , + 27525 , + 29771 , + 29771 , + 31413 , + 31413 , + 32419 , + 32419 , + 32767 , + 32767 , + 32452 , + 32452 , + 31479 , + 31479 , + 29868 , + 29868 , + 27651 , + 27651 , + 24875 , + 24875 , + 21594 , + 21594 , + 17876 , + 17876 , + 13795 , + 13795 , + 9435 , + 9435 , + 4883 , + 4883 , + 233 , + 233 , + -4421 , + -4421 , + -8987 , + -8987 , + -13370, + -13370, + -17483, + -17483, + -21241, + -21241, + -24568, + -24568, + -27398, + -27398, + -29673, + -29673, + -31346, + -31346, + -32384, + -32384, + -32766, + -32766, + -32483, + -32483, + -31543, + -31543, + -29963, + -29963, + -27776, + -27776, + -25026, + -25026, + -21769, + -21769, + -18071, + -18071, + -14006, + -14006, + -9658 , + -9658 , + -5114 , + -5114 , + -466 , + -466 , + 4190 , + 4190 , + 8762 , + 8762 , + 13157 , + 13157 , + 17285 , + 17285 , + 21062 , + 21062 , + 24413 , + 24413 , + 27269 , + 27269 , + 29573 , + 29573 , + 31277 , + 31277 , + 32347 , + 32347 , + 32762 , + 32762 , + 32513 , + 32513 , + 31605 , + 31605 , + 30057 , + 30057 , + 27899 , + 27899 , + 25176 , + 25176 , + 21943 , + 21943 , + 18265 , + 18265 , + 14217 , + 14217 , + 9881 , + 9881 , + 5344 , + 5344 , + 700 , + 700 , + -3958 , + -3958 , + -8537 , + -8537 , + -12943, + -12943, + -17086, + -17086, + -20883, + -20883, + -24257, + -24257, + -27139, + -27139, + -29472, + -29472, + -31207, + -31207, + -32309, + -32309, + -32757, + -32757, + -32541, + -32541, + -31666, + -31666, + -30149, + -30149, + -28021, + -28021, + -25325, + -25325, + -22116, + -22116, + -18458, + -18458, + -14427, + -14427, + -10103, + -10103, + -5575 , + -5575 , + -933 , + -933 , + 3726 , + 3726 , + 8311 , + 8311 , + 12728 , + 12728 , + 16886 , + 16886 , + 20703 , + 20703 , + 24099 , + 24099 , + 27008 , + 27008 , + 29369 , + 29369 , + 31135 , + 31135 , + 32270 , + 32270 , + 32751 , + 32751 , + 32568 , + 32568 , + 31725 , + 31725 , + 30240 , + 30240 , + 28141 , + 28141 , + 25472 , + 25472 , + 22287 , + 22287 , + 18651 , + 18651 , + 14636 , + 14636 , + 10325 , + 10325 , + 5805 , + 5805 , + 1166 , + 1166 , + -3494 , + -3494 , + -8085 , + -8085 , + -12512, + -12512, + -16686, + -16686, + -20521, + -20521, + -23941, + -23941, + -26875, + -26875, + -29265, + -29265, + -31061, + -31061, + -32228, + -32228, + -32742, + -32742, + -32593, + -32593, + -31783, + -31783, + -30329, + -30329, + -28260, + -28260, + -25619, + -25619, + -22458, + -22458, + -18842, + -18842, + -14845, + -14845, + -10546, + -10546, + -6034 , + -6034 , + -1400 , + -1400 , + 3262 , + 3262 , + 7859 , + 7859 , + 12296 , + 12296 , + 16484 , + 16484 , + 20339 , + 20339 , + 23781 , + 23781 , + 26741 , + 26741 , + 29159 , + 29159 , + 30986 , + 30986 , + 32185 , + 32185 , + 32732 , + 32732 , + 32616 , + 32616 , + 31839 , + 31839 , + 30416 , + 30416 , + 28377 , + 28377 , + 25763 , + 25763 , + 22627 , + 22627 , + 19033 , + 19033 , + 15052 , + 15052 , + 10767 , + 10767 , + 6263 , + 6263 , + 1633 , + 1633 , + -3030 , + -3030 , + -7632 , + -7632 , + -12080, + -12080, + -16282, + -16282, + -20155, + -20155, + -23619, + -23619, + -26605, + -26605, + -29052, + -29052, + -30909, + -30909, + -32141, + -32141, + -32721, + -32721, + -32638, + -32638, + -31893, + -31893, + -30502, + -30502, + -28493, + -28493, + -25907, + -25907, + -22796, + -22796, + -19222, + -19222, + -15259, + -15259, + -10987, + -10987, + -6492 , + -6492 , + -1866 , + -1866 , + 2797 , + 2797 , + 7405 , + 7405 , + 11862 , + 11862 , + 16079 , + 16079 , + 19971 , + 19971 , + 23457 , + 23457 , + 26468 , + 26468 , + 28943 , + 28943 , + 30831 , + 30831 , + 32094 , + 32094 , + 32707 , + 32707 , + 32658 , + 32658 , + 31946 , + 31946 , + 30587 , + 30587 , + 28608 , + 28608 , + 26049 , + 26049 , + 22963 , + 22963 , + 19411 , + 19411 , + 15466 , + 15466 , + 11207 , + 11207 , + 6721 , + 6721 , + 2099 , + 2099 , + -2565 , + -2565 , + -7177 , + -7177 , + -11644, + -11644, + -15876, + -15876, + -19785, + -19785, + -23293, + -23293, + -26330, + -26330, + -28833, + -28833, + -30751, + -30751, + -32047, + -32047, + -32692, + -32692, + -32676, + -32676, + -31997, + -31997, + -30670, + -30670, + -28721, + -28721, + -26190, + -26190, + -23129, + -23129, + -19598, + -19598, + -15671, + -15671, + -11426, + -11426, + -6949 , + -6949 , + -2332 , + -2332 , + 2332 , + 2332 , + 6949 , + 6949 , + 11426 , + 11426 , + 15671 , + 15671 , + 19598 , + 19598 , + 23129 , + 23129 , + 26190 , + 26190 , + 28721 , + 28721 , + 30670 , + 30670 , + 31997 , + 31997 , + 32676 , + 32676 , + 32692 , + 32692 , + 32047 , + 32047 , + 30751 , + 30751 , + 28833 , + 28833 , + 26330 , + 26330 , + 23293 , + 23293 , + 19785 , + 19785 , + 15876 , + 15876 , + 11644 , + 11644 , + 7177 , + 7177 , + 2565 , + 2565 , + -2099 , + -2099 , + -6721 , + -6721 , + -11207, + -11207, + -15466, + -15466, + -19411, + -19411, + -22963, + -22963, + -26049, + -26049, + -28608, + -28608, + -30587, + -30587, + -31946, + -31946, + -32658, + -32658, + -32707, + -32707, + -32094, + -32094, + -30831, + -30831, + -28943, + -28943, + -26468, + -26468, + -23457, + -23457, + -19971, + -19971, + -16079, + -16079, + -11862, + -11862, + -7405 , + -7405 , + -2797 , + -2797 , + 1866 , + 1866 , + 6492 , + 6492 , + 10987 , + 10987 , + 15259 , + 15259 , + 19222 , + 19222 , + 22796 , + 22796 , + 25907 , + 25907 , + 28493 , + 28493 , + 30502 , + 30502 , + 31893 , + 31893 , + 32638 , + 32638 , + 32721 , + 32721 , + 32141 , + 32141 , + 30909 , + 30909 , + 29052 , + 29052 , + 26605 , + 26605 , + 23619 , + 23619 , + 20155 , + 20155 , + 16282 , + 16282 , + 12080 , + 12080 , + 7632 , + 7632 , + 3030 , + 3030 , + -1633 , + -1633 , + -6263 , + -6263 , + -10767, + -10767, + -15052, + -15052, + -19033, + -19033, + -22627, + -22627, + -25763, + -25763, + -28377, + -28377, + -30416, + -30416, + -31839, + -31839, + -32616, + -32616, + -32732, + -32732, + -32185, + -32185, + -30986, + -30986, + -29159, + -29159, + -26741, + -26741, + -23781, + -23781, + -20339, + -20339, + -16484, + -16484, + -12296, + -12296, + -7859 , + -7859 , + -3262 , + -3262 , + 1400 , + 1400 , + 6034 , + 6034 , + 10546 , + 10546 , + 14845 , + 14845 , + 18842 , + 18842 , + 22458 , + 22458 , + 25619 , + 25619 , + 28260 , + 28260 , + 30329 , + 30329 , + 31783 , + 31783 , + 32593 , + 32593 , + 32742 , + 32742 , + 32228 , + 32228 , + 31061 , + 31061 , + 29265 , + 29265 , + 26875 , + 26875 , + 23941 , + 23941 , + 20521 , + 20521 , + 16686 , + 16686 , + 12512 , + 12512 , + 8085 , + 8085 , + 3494 , + 3494 , + -1166 , + -1166 , + -5805 , + -5805 , + -10325, + -10325, + -14636, + -14636, + -18651, + -18651, + -22287, + -22287, + -25472, + -25472, + -28141, + -28141, + -30240, + -30240, + -31725, + -31725, + -32568, + -32568, + -32751, + -32751, + -32270, + -32270, + -31135, + -31135, + -29369, + -29369, + -27008, + -27008, + -24099, + -24099, + -20703, + -20703, + -16886, + -16886, + -12728, + -12728, + -8311 , + -8311 , + -3726 , + -3726 , + 933 , + 933 , + 5575 , + 5575 , + 10103 , + 10103 , + 14427 , + 14427 , + 18458 , + 18458 , + 22116 , + 22116 , + 25325 , + 25325 , + 28021 , + 28021 , + 30149 , + 30149 , + 31666 , + 31666 , + 32541 , + 32541 , + 32757 , + 32757 , + 32309 , + 32309 , + 31207 , + 31207 , + 29472 , + 29472 , + 27139 , + 27139 , + 24257 , + 24257 , + 20883 , + 20883 , + 17086 , + 17086 , + 12943 , + 12943 , + 8537 , + 8537 , + 3958 , + 3958 , + -700 , + -700 , + -5344 , + -5344 , + -9881 , + -9881 , + -14217, + -14217, + -18265, + -18265, + -21943, + -21943, + -25176, + -25176, + -27899, + -27899, + -30057, + -30057, + -31605, + -31605, + -32513, + -32513, + -32762, + -32762, + -32347, + -32347, + -31277, + -31277, + -29573, + -29573, + -27269, + -27269, + -24413, + -24413, + -21062, + -21062, + -17285, + -17285, + -13157, + -13157, + -8762 , + -8762 , + -4190 , + -4190 , + 466 , + 466 , + 5114 , + 5114 , + 9658 , + 9658 , + 14006 , + 14006 , + 18071 , + 18071 , + 21769 , + 21769 , + 25026 , + 25026 , + 27776 , + 27776 , + 29963 , + 29963 , + 31543 , + 31543 , + 32483 , + 32483 , + 32766 , + 32766 , + 32384 , + 32384 , + 31346 , + 31346 , + 29673 , + 29673 , + 27398 , + 27398 , + 24568 , + 24568 , + 21241 , + 21241 , + 17483 , + 17483 , + 13370 , + 13370 , + 8987 , + 8987 , + 4421 , + 4421 , + -233 , + -233 , + -4883 , + -4883 , + -9435 , + -9435 , + -13795, + -13795, + -17876, + -17876, + -21594, + -21594, + -24875, + -24875, + -27651, + -27651, + -29868, + -29868, + -31479, + -31479, + -32452, + -32452, + -32767, + -32767, + -32419, + -32419, + -31413, + -31413, + -29771, + -29771, + -27525, + -27525, + -24722, + -24722, + -21418, + -21418, + -17679, + -17679, + -13583, + -13583, + -9211 , + -9211 , + -4652 , + -4652 , +}; +#elif (CODEC_TESTMODE == CODEC_WHITENOISE) +const int16_t sinwave[] = { +-13279 , +23249 , +-2387 , +-24403 , +30985 , +-403 , +-14925 , +-18617 , +21463 , +25395 , +4097 , +-21503 , +-16815 , +20875 , +-14167 , +31523 , +-4541 , +14695 , +-4055 , +-27691 , +18671 , +-19955 , +-9173 , +-16071 , +-2799 , +17023 , +-32331 , +-26623 , +-9401 , +2629 , +14815 , +16519 , +-13035 , +25297 , +-1769 , +-2715 , +2653 , +4429 , +28875 , +3729 , +-8883 , +8443 , +5039 , +-3861 , +-31517 , +-505 , +29795 , +-17821 , +9691 , +-5915 , +-2367 , +643 , +-1489 , +23073 , +19329 , +-30829 , +30475 , +28349 , +-20867 , +8231 , +-24253 , +-2807 , +24421 , +-14019 , +18511 , +12793 , +19705 , +10455 , +24517 , +-2307 , +27323 , +23815 , +12101 , +8283 , +-22225 , +28569 , +-28411 , +5121 , +2193 , +17949 , +-2383 , +22757 , +-16887 , +26243 , +27897 , +-8485 , +-7323 , +26675 , +21885 , +3817 , +-22189 , +27051 , +3909 , +15395 , +-31721 , +25223 , +17855 , +-29443 , +19139 , +-21967 , +7727 , +-2769 , +-16145 , +-29985 , +-1105 , +22527 , +-32011 , +14653 , +4517 , +27429 , +-13151 , +2179 , +31925 , +29207 , +4721 , +13059 , +6721 , +27119 , +-6841 , +3917 , +-10661 , +-16973 , +6309 , +2491 , +-22463 , +6975 , +-23709 , +14997 , +-2733 , +-32629 , +13029 , +-3933 , +-28019 , +6543 , +-5925 , +2115 , +7291 , +1691 , +15215 , +26375 , +-8779 , +-23771 , +28677 , +29637 , +-1065 , +25901 , +-22421 , +-7371 , +8947 , +-4855 , +-1383 , +-20213 , +26513 , +24013 , +-29981 , +-25207 , +-26845 , +-27121 , +8377 , +1941 , +-20739 , +24915 , +11729 , +31583 , +-20017 , +14801 , +-16403 , +-12951 , +-27751 , +-19747 , +21775 , +6693 , +29735 , +9139 , +2603 , +-32239 , +-8187 , +-21805 , +7269 , +-1463 , +20481 , +8669 , +13513 , +2465 , +-24815 , +6627 , +30335 , +-13757 , +-20771 , +30789 , +-14455 , +1977 , +-3411 , +-13309 , +19445 , +-11883 , +6373 , +-3165 , +-29801 , +23165 , +-29961 , +11125 , +14915 , +31687 , +-1049 , +7291 , +6787 , +-19049 , +-17101 , +955 , +-3377 , +877 , +4697 , +-30183 , +3399 , +23871 , +15051 , +25767 , +14823 , +15643 , +27231 , +21901 , +-13499 , +305 , +26707 , +-23217 , +-31295 , +-32141 , +3261 , +-21325 , +-1721 , +-18513 , +21641 , +-30957 , +15739 , +-17119 , +17381 , +-31441 , +-30595 , +6281 , +20301 , +30871 , +-26597 , +-28207 , +-32017 , +28523 , +25987 , +30739 , +8367 , +-1845 , +7053 , +-21697 , +-4967 , +-30309 , +-14501 , +16939 , +-8225 , +6629 , +-17497 , +9515 , +31307 , +-27979 , +7789 , +30001 , +27195 , +9319 , +-26327 , +5981 , +-15595 , +7553 , +-23669 , +15639 , +31301 , +23059 , +24757 , +16551 , +25263 , +-7289 , +-30993 , +-20913 , +24235 , +-9989 , +18909 , +-11807 , +121 , +14363 , +-16581 , +-24361 , +20799 , +-24971 , +-18923 , +22763 , +-2437 , +-25769 , +30841 , +-21709 , +28159 , +-21983 , +28601 , +-13391 , +-26523 , +27935 , +8987 , +15727 , +18955 , +16611 , +-30447 , +-19681 , +6795 , +-16357 , +8953 , +-9181 , +10929 , +20459 , +-9397 , +30257 , +6387 , +19649 , +7767 , +31591 , +-9113 , +-4177 , +9595 , +-15131 , +-16833 , +-31671 , +-4899 , +-1565 , +10691 , +1777 , +-13409 , +9031 , +-30013 , +-15433 , +9885 , +-17469 , +-3441 , +3507 , +13727 , +-27545 , +-17549 , +-22825 , +21267 , +26045 , +-7503 , +-4023 , +-12731 , +25949 , +20723 , +31545 , +-18403 , +-18421 , +-14013 , +4677 , +-23989 , +6217 , +-18809 , +-11461 , +-14073 , +-30349 , +-28805 , +29063 , +-24757 , +28501 , +2337 , +14589 , +13699 , +-7613 , +-12353 , +-5833 , +29389 , +-26703 , +-425 , +363 , +-26455 , +14157 , +3227 , +-27453 , +2365 , +29847 , +27499 , +16183 , +-14339 , +-15119 , +-30781 , +21219 , +-21261 , +2629 , +27715 , +-10787 , +-15767 , +2577 , +-18157 , +26771 , +-15061 , +2311 , +10863 , +-21345 , +16187 , +25373 , +25997 , +17437 , +13579 , +30763 , +17447 , +391 , +-8911 , +-15099 , +22111 , +24589 , +23201 , +-32499 , +-11445 , +-9111 , +-3735 , +-26549 , +-20517 , +17979 , +-21021 , +23051 , +5217 , +-24097 , +-2449 , +-19473 , +-6019 , +-19769 , +-81 , +20877 , +-21093 , +-14771 , +-25803 , +30849 , +24555 , +-10475 , +22729 , +-1785 , +-27183 , +-24357 , +29205 , +2837 , +-27155 , +-17195 , +30945 , +28657 , +-25727 , +24191 , +16335 , +-20409 , +377 , +-14083 , +-2677 , +-12599 , +-29739 , +5361 , +-5491 , +18237 , +-30807 , +24271 , +-1721 , +-19943 , +-1639 , +-2633 , +2275 , +-7007 , +-27965 , +-23857 , +-23943 , +-6795 , +-23481 , +-24297 , +4297 , +-29269 , +-14029 , +24011 , +623 , +11889 , +32513 , +-26327 , +9887 , +4887 , +25739 , +-37 , +-17315 , +14257 , +22411 , +-11067 , +-29645 , +3113 , +10375 , +-15523 , +17509 , +-25637 , +7509 , +29325 , +-20557 , +-3667 , +-1525 , +-4103 , +-16759 , +4259 , +-14215 , +-29715 , +-9541 , +22777 , +5667 , +15775 , +32185 , +-20033 , +-8009 , +10263 , +-32437 , +20201 , +-5885 , +22401 , +8905 , +27633 , +-23435 , +20231 , +12493 , +-11549 , +-31481 , +32547 , +23415 , +-30719 , +-12351 , +15487 , +7957 , +29139 , +-17999 , +20295 , +16745 , +21953 , +855 , +-19703 , +22875 , +301 , +-13651 , +-24831 , +22831 , +-2295 , +-13419 , +28409 , +-27839 , +31215 , +-14639 , +-31581 , +12603 , +19131 , +18305 , +-18071 , +-27185 , +-3169 , +32535 , +30925 , +-24339 , +-2115 , +28621 , +6973 , +20091 , +-16571 , +7587 , +-26263 , +-22645 , +-26621 , +-559 , +12317 , +32281 , +-23943 , +23745 , +3233 , +-5311 , +899 , +-3445 , +-26241 , +2033 , +12889 , +24037 , +-31763 , +-10201 , +-17603 , +-16989 , +4509 , +-8023 , +20103 , +8361 , +-8433 , +24377 , +29759 , +1129 , +-24969 , +-25263 , +-17359 , +-26157 , +-4341 , +21853 , +-15725 , +2261 , +-6949 , +-23961 , +-7923 , +27215 , +22831 , +29281 , +-7081 , +-20345 , +-25767 , +-3381 , +-25003 , +13869 , +-26093 , +-4101 , +-21335 , +11207 , +7503 , +-24889 , +19407 , +-25683 , +10391 , +-14135 , +-29005 , +15493 , +7645 , +-11507 , +-11575 , +-13775 , +-18209 , +-26801 , +-14169 , +7511 , +31471 , +-30795 , +-5865 , +-18107 , +-24741 , +5373 , +-20807 , +2173 , +12345 , +-12479 , +27669 , +-99 , +21443 , +14631 , +5679 , +24287 , +27187 , +-14947 , +-9305 , +18963 , +5139 , +-2035 , +-8113 , +28431 , +-18143 , +7961 , +-2755 , +29357 , +-22635 , +-24109 , +-23191 , +-9149 , +25613 , +22383 , +28361 , +14229 , +16853 , +-7803 , +32729 , +-23207 , +-9269 , +-32575 , +-11833 , +-28127 , +-31315 , +23581 , +-2307 , +-13349 , +19957 , +-19815 , +30271 , +-21045 , +-22473 , +-4235 , +2623 , +-25863 , +22511 , +6377 , +-25157 , +32567 , +-19491 , +-28329 , +23567 , +-29045 , +-9757 , +-23799 , +-20911 , +-1233 , +-5297 , +-12693 , +31973 , +-9715 , +-5695 , +21181 , +-29283 , +-4693 , +19583 , +-5813 , +22085 , +-28757 , +-6583 , +11053 , +7109 , +28867 , +13233 , +-26253 , +-19019 , +26419 , +-22023 , +-16405 , +-12685 , +957 , +7785 , +27211 , +-2107 , +9501 , +-8673 , +25585 , +27617 , +16899 , +-29067 , +-17891 , +-11505 , +-24183 , +28109 , +-1885 , +-6715 , +14891 , +3309 , +22817 , +17205 , +28479 , +6365 , +23751 , +21609 , +25839 , +19761 , +-14217 , +-27681 , +8877 , +9969 , +31631 , +4505 , +15409 , +28645 , +6431 , +-29765 , +14573 , +14965 , +-1127 , +-3161 , +29185 , +26107 , +27405 , +-18553 , +-24899 , +17307 , +-29213 , +-22415 , +-14449 , +29605 , +3089 , +-11009 , +-10363 , +-27809 , +-9001 , +12381 , +-31685 , +-11417 , +14061 , +24045 , +-15273 , +3715 , +6983 , +31063 , +-29565 , +30981 , +29253 , +13093 , +2791 , +-32621 , +13167 , +6613 , +6423 , +-2931 , +-28761 , +26491 , +7319 , +3807 , +-27155 , +11217 , +3531 , +30039 , +19081 , +10961 , +-8849 , +-13437 , +-22323 , +18385 , +-3943 , +-4861 , +-30903 , +-10989 , +-5345 , +26723 , +-10623 , +-24605 , +-32605 , +21109 , +12843 , +4397 , +-31747 , +2601 , +15587 , +15001 , +-4807 , +1247 , +-16801 , +10267 , +3595 , +15175 , +-973 , +19987 , +-21301 , +20147 , +17657 , +27613 , +15853 , +-265 , +9755 , +-17677 , +-3081 , +2229 , +17401 , +-15747 , +-8713 , +1087 , +19629 , +-22681 , +-13183 , +23785 , +-701 , +20743 , +13599 , +-1817 , +-20123 , +14885 , +-13229 , +-22115 , +30115 , +18073 , +3589 , +-895 , +5155 , +30057 , +27777 , +-31637 , +5075 , +-14509 , +24047 , +13163 , +8751 , +12789 , +73 , +-8915 , +-8339 , +-2213 , +-29745 , +31173 , +-31427 , +14873 , +19467 , +16655 , +24569 , +9699 , +22333 , +13949 , +-28057 , +-31575 , +-17321 , +15739 , +7141 , +6181 , +24439 , +20033 , +-26323 , +-28671 , +15581 , +-7381 , +-18555 , +29793 , +19045 , +13967 , +-11655 , +-8955 , +-20613 , +26909 , +-19433 , +19679 , +-29801 , +10409 , +-4193 , +-30171 , +821 , +-4203 , +-12605 , +-13583 , +-13497 , +29851 , +18775 , +3667 , +-5323 , +25383 , +-109 , +-1555 , +-4783 , +-3019 , +-20797 , +5131 , +13775 , +32677 , +6271 , +-19911 , +-18369 , +-25069 , +-11157 , +29781 , +-15489 , +-3279 , +1125 , +-23497 , +7231 , +14489 , +25411 , +20923 , +7659 , +-24273 , +-23029 , +-31905 , +6699 , +11505 , +-22619 , +21333 , +-20773 , +1361 , +22301 , +20771 , +19073 , +31245 , +-8109 , +-69 , +-26811 , +-18807 , +1843 , +-14327 , +1131 , +-14425 , +11635 , +14357 , +9797 , +2587 , +-1335 , +-6505 , +9397 , +-26299 , +8091 , +-11505 , +-4065 , +-10613 , +10821 , +-26019 , +29915 , +-24273 , +-6461 , +22493 , +-31427 , +22185 , +16629 , +-29961 , +-19973 , +13177 , +8525 , +-9923 , +-14029 , +11401 , +15375 , +1283 , +13275 , +-9987 , +19203 , +-3981 , +-5699 , +-31603 , +-22097 , +1321 , +13293 , +605 , +-13291 , +-10165 , +-2625 , +22617 , +-30753 , +25373 , +-19385 , +-9467 , +-22497 , +-22499 , +5191 , +-11811 , +-15479 , +7319 , +1707 , +15401 , +-13023 , +-20799 , +23429 , +-12719 , +22403 , +-16299 , +-3201 , +-16447 , +647 , +-4705 , +18391 , +-32461 , +2955 , +-1759 , +-32557 , +-3183 , +30753 , +-19549 , +-11585 , +14153 , +-11447 , +14543 , +22879 , +-21467 , +-2775 , +22595 , +10731 , +14753 , +-12983 , +-31949 , +-11389 , +30669 , +-22719 , +5753 , +1581 , +-12139 , +-7681 , +22833 , +-26553 , +12709 , +-28301 , +1995 , +-23935 , +26305 , +717 , +-15441 , +-5543 , +-19311 , +-25807 , +16199 , +21259 , +-13301 , +2293 , +32417 , +-29421 , +-20933 , +16211 , +1153 , +-17383 , +-26459 , +13477 , +17405 , +19315 , +-28139 , +-9445 , +11925 , +-22245 , +-20479 , +19445 , +14021 , +7969 , +-21413 , +-25291 , +-24793 , +-31827 , +-7197 , +23009 , +28163 , +-2193 , +21773 , +5299 , +-8857 , +27285 , +-18609 , +3409 , +-24635 , +8273 , +17147 , +24587 , +-12027 , +-5953 , +16789 , +-18417 , +-5083 , +18793 , +-335 , +-991 , +-25277 , +19517 , +12617 , +-4653 , +-14269 , +11521 , +30095 , +13119 , +-25631 , +-25269 , +-4275 , +-15557 , +2379 , +-10493 , +-21321 , +11287 , +30769 , +13645 , +-7739 , +-21299 , +3945 , +-29685 , +-27631 , +-26431 , +27137 , +-2607 , +-12509 , +-523 , +4313 , +20569 , +-1709 , +1473 , +-28491 , +8069 , +24859 , +2059 , +-31525 , +3795 , +-25867 , +-14081 , +28203 , +-14005 , +-14419 , +-9911 , +-20809 , +24585 , +23355 , +-28467 , +-32299 , +-2269 , +31775 , +-25639 , +18623 , +-3791 , +-27855 , +-27929 , +933 , +20795 , +9215 , +-27449 , +20299 , +-29905 , +-31321 , +23403 , +-16615 , +31461 , +-27609 , +-15607 , +-5189 , +-18039 , +-3527 , +15333 , +3637 , +2461 , +-3151 , +7805 , +32633 , +4461 , +-14261 , +23111 , +-2939 , +7175 , +-247 , +30439 , +-12555 , +6323 , +-1529 , +24553 , +23071 , +-28433 , +27355 , +-3337 , +19625 , +-13091 , +28511 , +-14193 , +26273 , +-8631 , +26397 , +12097 , +-31723 , +-13807 , +6415 , +-11933 , +-979 , +-30673 , +16909 , +-699 , +-23359 , +4641 , +9113 , +2035 , +21105 , +14311 , +11061 , +-15771 , +11581 , +29569 , +19015 , +31037 , +-20063 , +29405 , +5731 , +30451 , +-18907 , +-28589 , +18989 , +-32609 , +19835 , +-3677 , +-16725 , +17699 , +-8937 , +-31393 , +29989 , +14053 , +16451 , +-26893 , +-13969 , +-14319 , +20413 , +12565 , +25809 , +-32447 , +-23097 , +1717 , +2389 , +-5435 , +-2361 , +6795 , +-12897 , +-16307 , +-10663 , +-8973 , +-7863 , +26413 , +16621 , +-1919 , +29117 , +7945 , +-15911 , +-31519 , +-14459 , +-6885 , +-29197 , +-10143 , +13355 , +-32287 , +27305 , +-20517 , +-6009 , +-18093 , +-18019 , +-6857 , +19367 , +5539 , +-32583 , +27747 , +-5611 , +17525 , +-14655 , +-12609 , +-27201 , +32397 , +7289 , +-8923 , +-12737 , +-3567 , +-21965 , +-12203 , +2499 , +-22721 , +-26133 , +-28681 , +-2471 , +-10339 , +13783 , +22533 , +19407 , +12225 , +-27761 , +29905 , +17925 , +-3209 , +9109 , +19835 , +24519 , +31879 , +-651 , +29915 , +26153 , +3045 , +16477 , +-1777 , +31829 , +25963 , +24625 , +-22177 , +10225 , +11795 , +-18649 , +-30013 , +-531 , +-31571 , +13279 , +13009 , +2009 , +-13031 , +31733 , +16701 , +31173 , +9721 , +23331 , +-20533 , +-12135 , +-32527 , +-10543 , +12493 , +-3867 , +-10913 , +-16851 , +21523 , +24125 , +25989 , +3785 , +-21909 , +8981 , +-29097 , +1455 , +-24685 , +-32493 , +6561 , +13559 , +17079 , +489 , +-30009 , +30181 , +-19103 , +177 , +24059 , +3965 , +30969 , +17339 , +-19977 , +-5737 , +21175 , +-16651 , +21553 , +9345 , +-481 , +5807 , +-22633 , +-4849 , +26105 , +-1275 , +24007 , +-6857 , +-25661 , +-3155 , +31427 , +-1757 , +17841 , +-19373 , +-25811 , +-1835 , +-17629 , +-28309 , +-2819 , +-12753 , +-30825 , +11667 , +2743 , +-22627 , +-29657 , +-2207 , +-30421 , +-4327 , +30595 , +-28731 , +18341 , +26071 , +-13215 , +-20267 , +-7517 , +15437 , +11899 , +-21201 , +-5863 , +32469 , +11781 , +8141 , +5149 , +-20801 , +18857 , +-7071 , +-32475 , +-8209 , +24311 , +-4063 , +26299 , +13037 , +16739 , +9007 , +15291 , +901 , +-20549 , +-21913 , +-14073 , +-23589 , +24609 , +2491 , +7613 , +-1021 , +23171 , +26375 , +-8717 , +-6633 , +22923 , +11627 , +-7187 , +-24875 , +27173 , +-24281 , +-21545 , +8883 , +-32405 , +31723 , +-32263 , +-12425 , +16673 , +10683 , +-5259 , +8783 , +-23885 , +-16841 , +16761 , +-5527 , +-16223 , +14975 , +-2311 , +-14323 , +30337 , +15239 , +-32535 , +20531 , +3955 , +-22283 , +22771 , +-21349 , +-17639 , +31849 , +4783 , +4197 , +271 , +14695 , +-1187 , +-9939 , +-5403 , +11685 , +15387 , +-19301 , +7317 , +4585 , +-2407 , +-23935 , +-27783 , +9047 , +21599 , +11123 , +17355 , +19797 , +113 , +-23587 , +19603 , +31707 , +923 , +-11369 , +-1501 , +-20915 , +31511 , +-9719 , +20245 , +-7463 , +8659 , +-22857 , +19381 , +29247 , +9251 , +-8609 , +-21495 , +-3011 , +13817 , +-31603 , +21567 , +17499 , +25497 , +16825 , +9125 , +-16575 , +-27427 , +-25127 , +26153 , +20635 , +15073 , +1915 , +-25529 , +26979 , +8257 , +-157 , +-11901 , +30405 , +-11315 , +16533 , +14701 , +-3733 , +-23095 , +15611 , +19207 , +-25249 , +-20583 , +-14729 , +4807 , +4707 , +-8701 , +15485 , +-3311 , +9409 , +30179 , +5667 , +-29913 , +18087 , +2915 , +8391 , +-853 , +31235 , +25527 , +19225 , +18315 , +-5421 , +14667 , +21697 , +-2941 , +-13817 , +23175 , +14953 , +-14829 , +-32561 , +6909 , +-18849 , +-22541 , +-11143 , +-28885 , +-21081 , +-27377 , +4807 , +-30039 , +-7783 , +-21509 , +-8501 , +-10009 , +-16913 , +10735 , +-18889 , +-22429 , +-25747 , +-31681 , +-14535 , +-24477 , +20199 , +22609 , +11993 , +-26325 , +23783 , +27155 , +14277 , +28339 , +-22085 , +26873 , +-20043 , +-6685 , +-491 , +-19603 , +-1735 , +7245 , +14367 , +-12079 , +-14311 , +31325 , +-32495 , +-9749 , +26153 , +-24553 , +24401 , +-30739 , +21151 , +17483 , +-771 , +8665 , +-529 , +32343 , +31507 , +137 , +-21469 , +29263 , +-22271 , +-7901 , +6063 , +-10303 , +-1865 , +-16885 , +-4915 , +21227 , +1867 , +26209 , +-19117 , +6253 , +-28147 , +-29701 , +19723 , +-11379 , +12313 , +32725 , +30347 , +18143 , +-22413 , +21775 , +-22381 , +-24691 , +15527 , +-23963 , +-21545 , +-3327 , +-16433 , +-26077 , +8549 , +-8409 , +-11713 , +-20319 , +-30347 , +-15071 , +6541 , +-30407 , +-7481 , +-27007 , +-13005 , +25025 , +31347 , +-21251 , +28579 , +-19329 , +1097 , +-23383 , +3035 , +18597 , +-27741 , +-20299 , +-12405 , +26951 , +-29503 , +25239 , +22937 , +31445 , +9887 , +23505 , +-27317 , +-22769 , +-27315 , +-7645 , +31187 , +-10369 , +29897 , +-12731 , +-31121 , +-18825 , +-29613 , +-13031 , +21245 , +-4483 , +-32179 , +27499 , +3343 , +24653 , +-26491 , +-7133 , +14733 , +-30899 , +2333 , +10499 , +-27965 , +-15227 , +7129 , +7641 , +23299 , +-14311 , +-29707 , +32311 , +-1099 , +-11973 , +22155 , +26037 , +18669 , +-851 , +-30377 , +-3429 , +16781 , +22961 , +10787 , +-1247 , +-23593 , +-635 , +-12657 , +19751 , +11905 , +-12971 , +-911 , +28777 , +-6567 , +14013 , +-5459 , +25405 , +14417 , +-28999 , +-17783 , +18883 , +20505 , +20255 , +-15987 , +-30811 , +31549 , +-5479 , +-1073 , +15437 , +-3909 , +28443 , +16083 , +-26219 , +-10987 , +-20773 , +17635 , +3339 , +-11535 , +10183 , +10471 , +-19551 , +8237 , +24967 , +27321 , +4075 , +18293 , +-1563 , +5119 , +31441 , +-29087 , +6099 , +5509 , +18119 , +20487 , +31963 , +29973 , +3465 , +9237 , +-4837 , +25543 , +8279 , +10863 , +9657 , +-11031 , +-28001 , +21305 , +6625 , +-21177 , +-10427 , +-1155 , +-20937 , +8969 , +26699 , +-18881 , +-21807 , +26129 , +28955 , +-26099 , +7093 , +10439 , +-3281 , +-5341 , +-10303 , +8571 , +23891 , +31229 , +26169 , +7229 , +3413 , +-29075 , +-1365 , +-19159 , +-19385 , +-18633 , +-16523 , +21325 , +5421 , +22055 , +9909 , +31739 , +5695 , +16555 , +31169 , +5795 , +-25453 , +19687 , +24359 , +-18139 , +10855 , +9041 , +-28901 , +-27471 , +-18487 , +11465 , +28279 , +6941 , +-16937 , +-2771 , +-14293 , +-2893 , +-5001 , +-9613 , +23871 , +24223 , +-32117 , +24645 , +-31935 , +-30291 , +-16209 , +17 , +-30395 , +4531 , +28265 , +-12887 , +6999 , +9573 , +-5653 , +-14249 , +23669 , +30377 , +-17857 , +12405 , +-4343 , +-29839 , +7181 , +-18045 , +-23583 , +-30953 , +-32571 , +-3899 , +1953 , +1067 , +30815 , +-20391 , +-31035 , +5851 , +-621 , +-2361 , +24591 , +4023 , +-25455 , +-1243 , +7557 , +5917 , +27701 , +-10839 , +-13335 , +14591 , +20929 , +-27457 , +-22355 , +-1717 , +-30955 , +5795 , +32367 , +2229 , +-9365 , +32639 , +26609 , +12827 , +-22903 , +-23559 , +12683 , +6229 , +-6531 , +16461 , +4395 , +-9075 , +32721 , +21487 , +-4919 , +17695 , +6215 , +31125 , +-6303 , +31975 , +-31727 , +-27687 , +27749 , +801 , +15749 , +-22963 , +29117 , +-7239 , +-8361 , +13073 , +10301 , +-12243 , +6485 , +-2833 , +-11627 , +12505 , +6041 , +19955 , +-1321 , +-14627 , +-11197 , +17025 , +-16797 , +-2459 , +19379 , +22765 , +26725 , +20883 , +2881 , +13713 , +4811 , +31685 , +4717 , +19307 , +-31297 , +-645 , +32423 , +31025 , +3481 , +8359 , +-1675 , +-5399 , +32609 , +28041 , +24889 , +6145 , +9153 , +-8189 , +-23457 , +13799 , +-16265 , +28021 , +18207 , +-2267 , +30813 , +-3307 , +-29781 , +-4369 , +-17967 , +9411 , +-19221 , +28999 , +-3149 , +-27547 , +23483 , +18319 , +18659 , +27069 , +20121 , +4511 , +-1491 , +-7485 , +-3103 , +-21663 , +-16689 , +13433 , +-22905 , +28391 , +-15519 , +-7099 , +1359 , +-21755 , +-30883 , +12749 , +-21375 , +9831 , +20745 , +-22199 , +21029 , +1829 , +28667 , +30303 , +-17223 , +-2327 , +1545 , +-28809 , +-29591 , +-9357 , +-28989 , +20889 , +20169 , +-1087 , +-8851 , +-23363 , +-11001 , +-5723 , +-13965 , +16557 , +17585 , +2001 , +16743 , +10833 , +-9513 , +1149 , +-909 , +405 , +-9765 , +8311 , +-32171 , +14261 , +-26219 , +-25917 , +-15915 , +-14825 , +12825 , +6309 , +-4677 , +32171 , +-18201 , +25159 , +-10161 , +-31045 , +-30553 , +19405 , +-31419 , +10565 , +-29859 , +8933 , +10815 , +30165 , +-221 , +30957 , +21955 , +-6439 , +-21143 , +-24197 , +29871 , +-28033 , +3227 , +-17017 , +28213 , +1285 , +17515 , +-21773 , +-29105 , +23451 , +-29571 , +-20307 , +30397 , +-18511 , +-8793 , +16191 , +20085 , +-23851 , +28069 , +-25105 , +-6235 , +31499 , +-4787 , +-9133 , +5155 , +32673 , +339 , +-8085 , +-8091 , +-26997 , +-4749 , +-5835 , +-4865 , +25143 , +-5583 , +24007 , +-24939 , +-16403 , +7443 , +16619 , +23641 , +18075 , +-21677 , +8495 , +-27397 , +-8647 , +-8425 , +-8827 , +-15831 , +1945 , +-10447 , +5719 , +8833 , +-4929 , +-18101 , +-23777 , +25103 , +-11839 , +-8533 , +-7043 , +-5829 , +-491 , +-3227 , +19159 , +2641 , +-18831 , +-32754 , +-5787 , +-15001 , +24345 , +-10751 , +28119 , +23265 , +24263 , +-10741 , +21597 , +25703 , +-9741 , +-30297 , +-20401 , +-21417 , +-8525 , +1723 , +24887 , +31685 , +6417 , +-27195 , +3191 , +-26895 , +-22555 , +-28001 , +-19629 , +-24519 , +10795 , +-81 , +15761 , +6551 , +-25383 , +17315 , +-12141 , +-17253 , +8509 , +2467 , +19175 , +24795 , +17361 , +-17387 , +-17307 , +10481 , +-9327 , +-28215 , +12999 , +11761 , +6615 , +-23117 , +-19777 , +24933 , +-7501 , +4395 , +-19059 , +-8773 , +1471 , +-32611 , +795 , +23883 , +28539 , +15043 , +16535 , +4033 , +-5341 , +4701 , +2945 , +-31199 , +-29433 , +14955 , +-1715 , +-4813 , +23909 , +29923 , +21369 , +20103 , +23487 , +-27669 , +-6109 , +4071 , +29363 , +-14965 , +-14563 , +26957 , +29777 , +-24081 , +17295 , +2397 , +-18693 , +29719 , +4615 , +-24477 , +27317 , +-19185 , +-9453 , +-30273 , +16123 , +12717 , +6749 , +19431 , +28967 , +-11577 , +-24007 , +9947 , +-9417 , +32740 , +-25655 , +26909 , +6959 , +5245 , +23439 , +-15575 , +27381 , +-8271 , +-7549 , +20847 , +16541 , +-22913 , +25519 , +-27449 , +20301 , +-24455 , +-22971 , +4465 , +135 , +26371 , +-25541 , +-13183 , +-491 , +20229 , +1367 , +24543 , +-7091 , +9511 , +30425 , +-9021 , +-19213 , +-15225 , +-24701 , +13471 , +8851 , +32752 , +8251 , +24741 , +19537 , +-10857 , +-12001 , +-71 , +585 , +25931 , +-13541 , +-23831 , +10849 , +-24265 , +3591 , +-32667 , +23973 , +12561 , +6969 , +-15115 , +22047 , +32723 , +23713 , +15353 , +17705 , +27645 , +-20385 , +-31271 , +-21939 , +-28101 , +-3879 , +-27393 , +-15721 , +10931 , +-11941 , +-22193 , +10357 , +-3925 , +-6365 , +-32225 , +-17407 , +3269 , +14085 , +-333 , +27627 , +31169 , +8061 , +-6867 , +-2371 , +-9305 , +-2237 , +2061 , +15561 , +16777 , +14443 , +-32219 , +14955 , +-13899 , +-28679 , +16657 , +17137 , +-24461 , +-22023 , +-27091 , +-27665 , +20791 , +4633 , +1555 , +-9967 , +-7587 , +191 , +3725 , +-18311 , +-19621 , +27805 , +6931 , +-105 , +-27261 , +14549 , +24507 , +-30591 , +5941 , +-10363 , +-11591 , +28611 , +31125 , +14563 , +-941 , +-19773 , +18627 , +24281 , +-10921 , +-12653 , +3743 , +27925 , +27671 , +30535 , +6125 , +-29271 , +-30749 , +-43 , +-15331 , +-32223 , +757 , +-30113 , +22397 , +14609 , +4859 , +-26343 , +-14349 , +16449 , +14335 , +6045 , +31789 , +27439 , +2537 , +29885 , +30055 , +-31173 , +-25485 , +-6943 , +-9321 , +28205 , +-20067 , +25825 , +25645 , +25693 , +29361 , +-27309 , +-29885 , +-2245 , +-6227 , +1649 , +5981 , +22393 , +-6841 , +3169 , +-8291 , +29075 , +-22181 , +-19425 , +19579 , +-23569 , +-8727 , +-3901 , +-29955 , +26995 , +14989 , +-26265 , +-5521 , +-12127 , +31859 , +20341 , +23711 , +5927 , +-4909 , +-6775 , +-28533 , +16895 , +11751 , +24257 , +-24663 , +2559 , +-31131 , +7829 , +-14965 , +-2823 , +25459 , +24883 , +6697 , +-3247 , +18723 , +-27559 , +-14707 , +23057 , +-5783 , +-22365 , +-21483 , +-28287 , +-26221 , +-3215 , +-2529 , +20551 , +-8635 , +-18127 , +-29109 , +-17673 , +17897 , +-1985 , +-5329 , +16427 , +18859 , +-29631 , +12687 , +-30429 , +27895 , +16881 , +8215 , +22225 , +21351 , +-3197 , +-17007 , +-23683 , +1345 , +17783 , +16795 , +-7979 , +6765 , +7151 , +12261 , +-21881 , +1007 , +24715 , +7653 , +-15011 , +11225 , +12481 , +6923 , +-15669 , +9165 , +3249 , +13187 , +8467 , +-26131 , +7811 , +1383 , +16343 , +19543 , +12853 , +-8077 , +303 , +-19689 , +30209 , +26695 , +28485 , +-26455 , +-25815 , +12565 , +15981 , +22761 , +28499 , +20191 , +-31817 , +-371 , +-31131 , +20273 , +30737 , +-2273 , +3287 , +-27311 , +-24621 , +-27279 , +23183 , +-28421 , +12007 , +6813 , +24119 , +-14433 , +333 , +32113 , +30993 , +10253 , +69 , +-22417 , +-7331 , +-24393 , +19419 , +26183 , +12575 , +28775 , +263 , +-19255 , +3969 , +10609 , +-3009 , +-18849 , +-11601 , +-8331 , +14483 , +-1531 , +-5083 , +30603 , +-13501 , +20935 , +-7799 , +-27897 , +15317 , +-4183 , +-9203 , +3239 , +-22347 , +309 , +26679 , +-32683 , +-6079 , +-32415 , +32327 , +-10921 , +13935 , +30989 , +27401 , +17157 , +16085 , +26111 , +-20181 , +-14323 , +-9391 , +85 , +31515 , +-29665 , +24341 , +5759 , +-19113 , +9257 , +-14779 , +-18501 , +26959 , +12563 , +-24049 , +25861 , +28853 , +20721 , +6461 , +-32617 , +6483 , +-9539 , +-10923 , +-19491 , +-11921 , +23697 , +13359 , +-31765 , +29847 , +21597 , +-27129 , +-13189 , +20735 , +6945 , +8221 , +22877 , +32085 , +31391 , +-13369 , +22137 , +-26847 , +-6755 , +6671 , +-12739 , +-32365 , +-13677 , +17347 , +-4451 , +15583 , +-1813 , +15895 , +19589 , +28183 , +-28493 , +27569 , +-8751 , +-20603 , +29913 , +21067 , +-7727 , +16761 , +-18463 , +11467 , +28715 , +13227 , +-1251 , +-20015 , +-6551 , +-24815 , +14439 , +-6441 , +-5147 , +2097 , +-4523 , +22477 , +17473 , +-32255 , +9973 , +-29917 , +10339 , +-22213 , +20741 , +2673 , +24045 , +4149 , +25511 , +-10365 , +-15055 , +13113 , +17565 , +-23049 , +-27219 , +-29345 , +-5889 , +-20141 , +259 , +-6685 , +10353 , +-30819 , +29803 , +28155 , +-17693 , +-24457 , +12467 , +-14539 , +22721 , +6319 , +28851 , +-30133 , +30123 , +27231 , +-10681 , +26233 , +-29263 , +31101 , +21953 , +29019 , +32011 , +-13061 , +22505 , +-16581 , +-9651 , +19549 , +19057 , +-9221 , +-13529 , +22989 , +22255 , +15445 , +19343 , +-24397 , +30799 , +16327 , +24457 , +28887 , +-22829 , +-9503 , +10065 , +-537 , +21125 , +-32221 , +20001 , +23461 , +-7113 , +27979 , +-13475 , +-29079 , +31985 , +-13513 , +28237 , +-30643 , +-21525 , +-451 , +11355 , +27315 , +21261 , +30969 , +-22071 , +-7061 , +29153 , +21425 , +-2843 , +1091 , +3845 , +12835 , +-5181 , +22565 , +-1997 , +-28189 , +17527 , +-20315 , +-28505 , +6453 , +-20533 , +24869 , +26151 , +-419 , +3705 , +21607 , +-15253 , +8061 , +12509 , +-12893 , +-217 , +-7445 , +6453 , +11813 , +-21903 , +30731 , +14423 , +-26789 , +31177 , +-28507 , +-25373 , +-16005 , +-639 , +10941 , +-29435 , +-8559 , +-2363 , +-32021 , +-32093 , +-7657 , +31241 , +-14541 , +537 , +1297 , +-26621 , +-23967 , +17269 , +-8537 , +-15069 , +14299 , +9771 , +-5837 , +-18547 , +-22535 , +26443 , +-13341 , +-3187 , +-19229 , +-28097 , +16591 , +-16747 , +-24603 , +-23557 , +-4211 , +-20305 , +-10423 , +-10051 , +5197 , +-25479 , +-29527 , +-25535 , +19311 , +1435 , +-13361 , +5241 , +22937 , +-8771 , +10761 , +16067 , +18519 , +-16379 , +-23041 , +6057 , +-20695 , +25355 , +-12269 , +-15089 , +-32481 , +31057 , +-11473 , +15089 , +14071 , +-18375 , +30239 , +21147 , +-21079 , +15747 , +-21131 , +-13219 , +-28279 , +2879 , +-10803 , +13253 , +-21029 , +-11701 , +11959 , +7771 , +-1813 , +-15547 , +-20991 , +-17199 , +-19287 , +-25085 , +-15459 , +14021 , +31669 , +-18539 , +9709 , +-14097 , +-27895 , +11947 , +16029 , +7647 , +22529 , +1697 , +20485 , +-9933 , +8957 , +24809 , +-5391 , +-12975 , +30323 , +-29433 , +-13049 , +-11363 , +-11635 , +9997 , +-16487 , +-16593 , +1337 , +-885 , +-28931 , +25105 , +20171 , +-4083 , +-19869 , +7409 , +13065 , +-27881 , +-17357 , +-3749 , +20175 , +-20851 , +10977 , +-29065 , +2589 , +29119 , +-19901 , +20533 , +32441 , +32723 , +-27283 , +-22257 , +27453 , +-27711 , +10503 , +-4551 , +-30029 , +-3379 , +5673 , +-409 , +10419 , +25981 , +30123 , +-17681 , +18927 , +-4333 , +23553 , +-13415 , +16725 , +-1149 , +-4711 , +-23355 , +2465 , +15335 , +-27735 , +18473 , +15231 , +-5757 , +27019 , +-18417 , +-2033 , +-22737 , +31385 , +-27391 , +-24555 , +-18085 , +-6017 , +-8693 , +-20609 , +-13187 , +-28139 , +19313 , +-27257 , +525 , +21177 , +15329 , +-7869 , +31749 , +29223 , +-21455 , +-25913 , +7879 , +23757 , +12699 , +8371 , +-15959 , +15525 , +28263 , +25169 , +-31267 , +-30067 , +-1743 , +-12753 , +-29711 , +12325 , +11931 , +-13011 , +-16441 , +21019 , +-6783 , +8737 , +-3317 , +23309 , +32189 , +1509 , +-469 , +24283 , +16721 , +22521 , +8145 , +28293 , +-28631 , +-17521 , +21207 , +-2945 , +-12723 , +-1743 , +-11583 , +-20093 , +-29537 , +31945 , +-31045 , +29179 , +-7155 , +18503 , +-29947 , +5057 , +31563 , +12981 , +-28427 , +-2931 , +12045 , +-13369 , +19819 , +24769 , +-11077 , +-17409 , +-21049 , +6847 , +4019 , +-1729 , +2921 , +-27955 , +-20243 , +-22559 , +5535 , +-6305 , +-26291 , +75 , +-21981 , +17911 , +-27071 , +4371 , +21519 , +-15231 , +12561 , +-19063 , +-22179 , +19229 , +-6015 , +-26405 , +16085 , +-22905 , +-13029 , +-25181 , +27273 , +23265 , +-2083 , +-32251 , +-29487 , +20245 , +-11403 , +6215 , +6077 , +-5973 , +-20495 , +-5145 , +3345 , +-20451 , +-26361 , +-21709 , +10939 , +5551 , +-6465 , +11615 , +32203 , +28369 , +-32595 , +27939 , +-27671 , +-15381 , +19375 , +20431 , +853 , +-31051 , +-17889 , +-28445 , +-32425 , +-14051 , +-2413 , +-21979 , +16185 , +3213 , +-24313 , +4161 , +-14915 , +16849 , +-26971 , +-25641 , +1821 , +4457 , +-17423 , +30487 , +-8325 , +1117 , +16775 , +26591 , +-17447 , +-23139 , +23377 , +-12729 , +-24679 , +13271 , +-7613 , +12227 , +16489 , +-1077 , +-10103 , +-22855 , +28869 , +-3291 , +18505 , +3729 , +-28435 , +-21545 , +29915 , +17499 , +15961 , +14321 , +-10635 , +21469 , +-1613 , +5619 , +-10123 , +-5847 , +-1197 , +-16979 , +-11767 , +-8509 , +-4561 , +-6765 , +12655 , +16421 , +-13989 , +6291 , +20909 , +-26393 , +32766 , +-19339 , +-3387 , +-6061 , +-16445 , +-5975 , +-13197 , +4471 , +30175 , +-12893 , +13151 , +8135 , +21119 , +11447 , +18645 , +14377 , +707 , +4203 , +-21241 , +-29031 , +22835 , +-19119 , +11189 , +14393 , +7355 , +-3231 , +23413 , +12779 , +-18909 , +-18479 , +-22691 , +29545 , +29699 , +-22681 , +-17593 , +26339 , +-25281 , +-32423 , +-13697 , +-25335 , +2559 , +23201 , +-22269 , +5555 , +31523 , +18903 , +12083 , +-2835 , +26683 , +-25727 , +-8171 , +-875 , +31753 , +9977 , +18941 , +-23951 , +30571 , +-9285 , +6613 , +6857 , +-19747 , +7997 , +22725 , +12155 , +-2453 , +4943 , +-13187 , +15255 , +-8147 , +23783 , +-3617 , +9079 , +-28355 , +-31869 , +-30153 , +-24239 , +-9935 , +-32515 , +13057 , +-16807 , +-26609 , +-26139 , +15 , +-12209 , +-28985 , +5719 , +-28593 , +-11361 , +22065 , +-3249 , +-27397 , +31217 , +-19333 , +9355 , +17237 , +-15027 , +2339 , +32477 , +-22311 , +-30815 , +1913 , +-7425 , +23039 , +-24849 , +30601 , +-16139 , +29549 , +17873 , +13723 , +-29731 , +26029 , +20635 , +10283 , +13897 , +-31897 , +-20747 , +25695 , +20247 , +-13795 , +2541 , +14589 , +-10547 , +-8869 , +-10605 , +22509 , +25961 , +-21383 , +-19187 , +-10721 , +-18241 , +-17719 , +29745 , +14869 , +17235 , +-32171 , +-28255 , +20689 , +-11351 , +-5869 , +-29087 , +335 , +-5083 , +16551 , +-4123 , +-10625 , +-7335 , +-14197 , +17849 , +30651 , +25835 , +10965 , +2961 , +-14401 , +27365 , +-5275 , +-16419 , +-7647 , +18309 , +16805 , +1771 , +-20661 , +-10327 , +21693 , +12917 , +18161 , +30101 , +21067 , +1473 , +-9977 , +-15279 , +22427 , +3633 , +21825 , +-5245 , +-23199 , +26725 , +-30465 , +23495 , +5611 , +18891 , +-5167 , +-19579 , +19943 , +9911 , +-11673 , +-9147 , +-24699 , +-13055 , +16395 , +-1901 , +6215 , +19225 , +3737 , +14921 , +-20185 , +-1121 , +-23301 , +14705 , +6485 , +-29319 , +-3045 , +-7271 , +4979 , +24691 , +-3491 , +-25685 , +-8889 , +3661 , +19865 , +-23995 , +-26119 , +30809 , +-29809 , +24209 , +14019 , +12687 , +20707 , +-24669 , +-15825 , +-25297 , +1687 , +28225 , +-21039 , +-26169 , +-27143 , +-30897 , +-3469 , +4317 , +29479 , +5787 , +-28959 , +17151 , +-20995 , +-13771 , +22795 , +10327 , +16789 , +-10677 , +-26163 , +-16949 , +23099 , +385 , +27427 , +-26989 , +-13853 , +20931 , +20699 , +-30133 , +25383 , +29097 , +979 , +-10349 , +29367 , +26175 , +-6225 , +-27869 , +3931 , +-21141 , +8981 , +-17567 , +30817 , +23745 , +-11681 , +-14209 , +15005 , +22739 , +19667 , +4363 , +21465 , +15635 , +-2973 , +-9455 , +3287 , +3113 , +-30759 , +29099 , +-15937 , +16585 , +28573 , +5915 , +20767 , +22281 , +-803 , +11107 , +26971 , +26173 , +4949 , +24415 , +27821 , +-7345 , +13693 , +19545 , +9115 , +9105 , +27457 , +18473 , +-2583 , +-18399 , +-1219 , +-12863 , +-7655 , +14771 , +28279 , +21071 , +-5283 , +-25359 , +-10611 , +-8495 , +13843 , +-22701 , +-12679 , +17965 , +-30019 , +-25485 , +11713 , +20427 , +30579 , +-17429 , +-6605 , +-20823 , +-14365 , +-22617 , +1049 , +7415 , +-29755 , +19135 , +18677 , +29743 , +25557 , +22739 , +22711 , +6567 , +19781 , +-549 , +-3719 , +-26701 , +-23619 , +-10617 , +9645 , +-17613 , +-28209 , +-14065 , +4321 , +3507 , +-22545 , +-10601 , +-275 , +1021 , +-11795 , +31993 , +32181 , +-18125 , +25321 , +-16091 , +20825 , +-29077 , +28623 , +31225 , +-15637 , +-31041 , +12365 , +-3177 , +16819 , +-18449 , +-25013 , +-31941 , +-12583 , +-22673 , +3045 , +9113 , +11177 , +-5117 , +-6173 , +-20047 , +16963 , +-5157 , +26793 , +-7641 , +-16173 , +3879 , +21947 , +-30953 , +24401 , +16171 , +-22607 , +15995 , +-14419 , +2531 , +13991 , +8431 , +-26475 , +16909 , +12099 , +-30435 , +31389 , +29641 , +-31203 , +-29821 , +-16375 , +1457 , +8649 , +14043 , +-30989 , +24177 , +-3267 , +13543 , +-10737 , +-6441 , +-19241 , +-7217 , +-21535 , +16507 , +-30771 , +32758 , +30833 , +-30523 , +10283 , +30293 , +-1657 , +145 , +-4287 , +30545 , +-3743 , +-4029 , +23717 , +25109 , +-20503 , +8291 , +23979 , +-24475 , +-6537 , +-16725 , +2901 , +2811 , +-16905 , +1961 , +5839 , +-4511 , +-22603 , +-29481 , +-25493 , +18497 , +-8057 , +28455 , +-27373 , +-10939 , +7815 , +26155 , +-25019 , +1893 , +24917 , +-5213 , +20617 , +31951 , +23743 , +25495 , +-9113 , +3887 , +30215 , +-26387 , +9701 , +5005 , +-13421 , +26251 , +5755 , +-7511 , +16171 , +-6943 , +23945 , +16847 , +-1369 , +-3063 , +22357 , +-15313 , +26421 , +31325 , +21117 , +-17229 , +3845 , +12177 , +-5133 , +-10147 , +24967 , +19531 , +-18063 , +-1767 , +-11745 , +-2509 , +-1419 , +26907 , +18787 , +-16229 , +-30789 , +-339 , +24783 , +6531 , +-18133 , +18581 , +24825 , +-1211 , +31323 , +23267 , +31317 , +-17763 , +17797 , +21575 , +12381 , +18763 , +15611 , +13299 , +28507 , +-15065 , +6945 , +6123 , +17551 , +-21577 , +12519 , +31711 , +-20237 , +-30131 , +10945 , +-28535 , +-29071 , +-32105 , +-11237 , +17271 , +-103 , +31683 , +-28333 , +3953 , +25045 , +22535 , +-14283 , +11593 , +14891 , +1733 , +-4373 , +15671 , +5229 , +-13533 , +31099 , +177 , +-13067 , +-28901 , +24001 , +15549 , +15579 , +-25831 , +26079 , +23763 , +-16215 , +-30191 , +2363 , +-4567 , +-28255 , +-11753 , +1015 , +-29801 , +26977 , +-18055 , +25831 , +20969 , +26669 , +4181 , +18949 , +29875 , +-19043 , +-31055 , +885 , +2995 , +-11305 , +-2283 , +-11025 , +-20319 , +7495 , +32159 , +3523 , +1415 , +25819 , +-19553 , +-20667 , +-17503 , +12467 , +-6225 , +22995 , +12971 , +-30881 , +-21947 , +-18369 , +18625 , +-14441 , +-31019 , +8659 , +29359 , +-32143 , +16737 , +-21827 , +-19247 , +-12263 , +28815 , +23317 , +-27543 , +5897 , +-13233 , +-15289 , +-26257 , +-16961 , +2275 , +-21227 , +30967 , +-16641 , +-27013 , +3085 , +32764 , +-26497 , +7513 , +2169 , +22209 , +-29665 , +3671 , +14819 , +-19295 , +-21587 , +8203 , +-8695 , +7283 , +-22765 , +4185 , +15695 , +14677 , +-10993 , +-32111 , +-2629 , +-3063 , +28275 , +20995 , +25715 , +-10033 , +29647 , +12563 , +-6741 , +-6723 , +13753 , +-4899 , +8995 , +22931 , +-2179 , +11583 , +10523 , +-25833 , +-23473 , +2425 , +31187 , +-12053 , +3857 , +18757 , +-10375 , +16871 , +-19327 , +-21905 , +-859 , +5611 , +30705 , +743 , +-1193 , +-28861 , +21125 , +-26785 , +31331 , +21615 , +27877 , +32357 , +-30351 , +-7543 , +-25735 , +26611 , +17271 , +-16363 , +-19171 , +-24177 , +-2133 , +-30625 , +-17311 , +-20773 , +4351 , +26445 , +21301 , +20153 , +29715 , +7607 , +28971 , +17617 , +-29771 , +9799 , +-11219 , +-16449 , +-17447 , +4805 , +9137 , +-19563 , +29445 , +-17923 , +15985 , +261 , +-28071 , +19979 , +-21845 , +-16145 , +25597 , +-3275 , +-24367 , +-29573 , +-10215 , +-4277 , +-22333 , +6577 , +16469 , +2423 , +16775 , +1169 , +16837 , +12951 , +-29821 , +7345 , +13677 , +3605 , +27957 , +3913 , +-20689 , +29509 , +10853 , +-14893 , +25419 , +32557 , +-6685 , +20773 , +8787 , +20211 , +1475 , +-18177 , +9121 , +-1377 , +-3577 , +-30671 , +22101 , +-6009 , +9701 , +27941 , +-3897 , +4377 , +2935 , +-14589 , +-2431 , +19251 , +-26121 , +30527 , +-4933 , +14601 , +11893 , +-12361 , +30027 , +-4755 , +-26863 , +-2741 , +2085 , +-7763 , +-14163 , +-28941 , +-31921 , +21489 , +14127 , +6485 , +-13993 , +-23033 , +18479 , +-18717 , +9807 , +-11065 , +-10185 , +-11157 , +-19643 , +-24605 , +19061 , +31291 , +28727 , +31295 , +6903 , +-24151 , +19601 , +-9519 , +27489 , +26425 , +-10723 , +1519 , +-32219 , +28973 , +-14717 , +-6355 , +-19395 , +25249 , +10043 , +5045 , +-20129 , +-19681 , +17419 , +-29413 , +-21829 , +-15681 , +9205 , +23737 , +19499 , +-32077 , +-16193 , +-24699 , +-13 , +-30103 , +-19241 , +6761 , +29941 , +-3807 , +-26657 , +-4323 , +-8343 , +-15363 , +-15979 , +-30341 , +-5101 , +28839 , +-21675 , +23901 , +-8699 , +-931 , +-22517 , +-29457 , +-12603 , +24463 , +10927 , +3979 , +-30439 , +-8713 , +21307 , +28941 , +-2513 , +-19667 , +-1501 , +-15953 , +-27297 , +-5183 , +-3503 , +-12705 , +-2465 , +-15659 , +-18027 , +14747 , +-20999 , +23605 , +20387 , +-29503 , +-17077 , +13035 , +27529 , +-9747 , +-7311 , +5209 , +-14421 , +1615 , +-11825 , +-43 , +-17359 , +21767 , +-17735 , +-15685 , +-8179 , +19057 , +12979 , +-22265 , +-6043 , +-32752 , +-9175 , +6765 , +32405 , +-32555 , +-10843 , +31735 , +17571 , +17919 , +25221 , +11791 , +-16331 , +27763 , +-14791 , +-217 , +25619 , +-17779 , +-13835 , +-5437 , +28685 , +3719 , +-6929 , +32031 , +-8315 , +19773 , +32525 , +-19655 , +7773 , +27033 , +17961 , +-20623 , +-17295 , +7259 , +3523 , +6819 , +-10351 , +25721 , +12601 , +-30283 , +29687 , +26615 , +-3971 , +-16451 , +31551 , +-12995 , +-16559 , +9357 , +-26145 , +9455 , +-255 , +18381 , +-19679 , +31811 , +6801 , +-14177 , +9111 , +-20511 , +32131 , +31137 , +-30183 , +-26829 , +23807 , +6557 , +20281 , +-24515 , +-13413 , +30861 , +-23753 , +-3077 , +3975 , +24897 , +10883 , +-17613 , +-19635 , +8045 , +4269 , +-25645 , +18689 , +-1461 , +-17953 , +1727 , +22529 , +31655 , +-13611 , +28215 , +27945 , +-9341 , +-16551 , +-861 , +-14965 , +26663 , +-14539 , +-7185 , +-29787 , +17083 , +8621 , +-8855 , +7969 , +18529 , +-20617 , +-3573 , +24325 , +32715 , +-3273 , +9059 , +28265 , +-7343 , +14449 , +3297 , +-5189 , +-8301 , +6401 , +5551 , +4713 , +24191 , +6429 , +19215 , +-16601 , +-18691 , +-28229 , +31535 , +-12651 , +22775 , +-24163 , +-22403 , +-12659 , +-29191 , +23739 , +28043 , +31175 , +9803 , +-3519 , +26969 , +-2531 , +27265 , +259 , +19511 , +19775 , +10649 , +-11653 , +-25317 , +6125 , +15251 , +-19399 , +-12431 , +-11351 , +20615 , +10213 , +-16001 , +-9481 , +25659 , +8621 , +15159 , +30739 , +-20927 , +3397 , +-31347 , +2597 , +26249 , +-11945 , +-19883 , +-19205 , +13947 , +-30331 , +-21355 , +-27837 , +-20845 , +11991 , +-22175 , +-7359 , +-26509 , +-6471 , +4397 , +9735 , +32125 , +12403 , +31153 , +-22227 , +14829 , +-22241 , +-14283 , +29453 , +-2961 , +-25057 , +5227 , +2419 , +21047 , +9753 , +25553 , +2781 , +16281 , +-1939 , +-10887 , +4653 , +9507 , +-17615 , +22129 , +-8987 , +-7885 , +-95 , +30349 , +11227 , +24081 , +-23265 , +30155 , +22137 , +7297 , +-9565 , +8739 , +2153 , +-29981 , +30395 , +-25121 , +8663 , +-32569 , +-8705 , +-22917 , +12839 , +-18681 , +12297 , +29685 , +-31449 , +-27557 , +-3345 , +-14173 , +15055 , +9843 , +-2761 , +18841 , +24947 , +-24687 , +-25003 , +-18579 , +-30077 , +12449 , +26009 , +8099 , +-11851 , +-26675 , +-22605 , +-24973 , +-12597 , +15255 , +-27993 , +-14031 , +27079 , +10871 , +24639 , +22809 , +2461 , +-10525 , +-26871 , +11947 , +5489 , +-6147 , +-30259 , +17799 , +16463 , +-2407 , +-12921 , +-20289 , +-26785 , +-28963 , +-8737 , +14259 , +-13661 , +20053 , +-22503 , +-21659 , +-22487 , +30355 , +13465 , +-29611 , +16837 , +-13253 , +9943 , +6361 , +-19125 , +6825 , +19407 , +23537 , +3909 , +13307 , +-4347 , +21667 , +16427 , +-14927 , +11767 , +-12845 , +-25571 , +-9785 , +529 , +-363 , +-8937 , +23619 , +14641 , +-29941 , +8111 , +32091 , +5263 , +-575 , +-11707 , +18433 , +-14781 , +20855 , +3781 , +17663 , +-31433 , +-23673 , +22227 , +-32111 , +28575 , +-22857 , +10895 , +-10115 , +-3087 , +-4465 , +29125 , +-16217 , +-1957 , +-21705 , +12201 , +-25557 , +30917 , +-4665 , +30987 , +-17159 , +-11463 , +3369 , +9493 , +3045 , +31465 , +17255 , +12411 , +-23735 , +18847 , +7047 , +19259 , +13841 , +10169 , +-14357 , +-30513 , +-25761 , +17055 , +-1769 , +-21779 , +22171 , +-30279 , +19739 , +-335 , +29709 , +-22035 , +-4255 , +17509 , +-28169 , +16273 , +-32503 , +-26195 , +28203 , +30443 , +-7751 , +-8635 , +-12253 , +-11493 , +-3833 , +-29895 , +10137 , +21409 , +-8135 , +29847 , +-18525 , +-20403 , +11445 , +28081 , +-22975 , +-7235 , +-9531 , +18381 , +-14205 , +-17331 , +2299 , +9053 , +-31979 , +-21607 , +29701 , +-29761 , +-26791 , +-29591 , +775 , +21867 , +13577 , +-26829 , +-2961 , +-18767 , +10307 , +15633 , +-15535 , +-27921 , +31779 , +8501 , +23867 , +28747 , +27107 , +-5917 , +-16235 , +4071 , +-5015 , +6635 , +-25745 , +8351 , +-12185 , +-16479 , +733 , +1083 , +-26387 , +3665 , +-9519 , +7977 , +4227 , +-17095 , +1653 , +-21835 , +-8505 , +20227 , +-1799 , +-32313 , +-1419 , +189 , +-16651 , +-8177 , +20503 , +-26805 , +6205 , +-29755 , +29955 , +-15511 , +-17861 , +25059 , +-16633 , +21529 , +21187 , +-17195 , +-26507 , +-4189 , +25455 , +-21063 , +26823 , +-29947 , +-29323 , +-32754 , +-5723 , +22515 , +26111 , +32766 , +16527 , +24907 , +27397 , +31479 , +-19219 , +-29169 , +12451 , +-3321 , +23203 , +17111 , +24303 , +31863 , +-30415 , +22995 , +-26537 , +15891 , +30537 , +-22217 , +-8075 , +3037 , +-11553 , +-12223 , +-25755 , +5191 , +-21039 , +-32093 , +-16991 , +-26651 , +-26899 , +2695 , +17497 , +-23631 , +14229 , +14587 , +-29113 , +17843 , +19925 , +31991 , +-21237 , +13383 , +23287 , +22727 , +18177 , +24525 , +-8545 , +-4595 , +8603 , +26343 , +30303 , +-10187 , +-5069 , +25895 , +-17963 , +3437 , +25453 , +5205 , +11069 , +-481 , +25861 , +-18405 , +5261 , +-21789 , +3121 , +-13247 , +-22263 , +-5885 , +28269 , +-4759 , +17251 , +-29341 , +4319 , +-3009 , +6215 , +-18935 , +-20955 , +-17605 , +13691 , +-5623 , +25779 , +-31025 , +9595 , +18433 , +-6739 , +-30683 , +3973 , +31511 , +-17353 , +29269 , +-21447 , +-20891 , +17747 , +-26081 , +-6477 , +14075 , +28727 , +-26593 , +-32229 , +11345 , +-8409 , +-6775 , +-25661 , +-22715 , +-32565 , +27489 , +25021 , +-8305 , +14855 , +31793 , +-10761 , +-8265 , +-18349 , +12349 , +-2611 , +1935 , +1171 , +-25531 , +7713 , +5423 , +-4493 , +-9547 , +1015 , +-5017 , +-6089 , +24415 , +6545 , +-11077 , +27419 , +-29257 , +-18439 , +26071 , +31781 , +2437 , +-6875 , +-9585 , +27011 , +-17893 , +3727 , +585 , +22617 , +-2021 , +-28605 , +-30459 , +-17625 , +-8801 , +24707 , +-12853 , +18581 , +12535 , +-18473 , +-93 , +-29999 , +-7707 , +3495 , +-18155 , +-24733 , +-28335 , +16725 , +-11755 , +16269 , +7039 , +18387 , +-24443 , +-22249 , +-25397 , +13755 , +24365 , +32691 , +-5921 , +-535 , +-3289 , +16075 , +-5011 , +-17267 , +-14361 , +21475 , +-3739 , +-6449 , +-1625 , +31075 , +15789 , +14041 , +-31129 , +27137 , +1111 , +-21385 , +-17059 , +-31607 , +8543 , +31281 , +-23303 , +30781 , +-26655 , +14043 , +-28853 , +-28243 , +19147 , +11189 , +-27377 , +-16369 , +-6117 , +5883 , +12055 , +-5361 , +32405 , +15111 , +-22967 , +-20173 , +-18943 , +4575 , +-28141 , +9901 , +8659 , +32085 , +7527 , +-21325 , +-22919 , +-13415 , +18995 , +31061 , +26877 , +26709 , +-5291 , +-6181 , +16721 , +-28095 , +-29415 , +10649 , +9973 , +-4799 , +1065 , +28483 , +-28609 , +18679 , +-9459 , +8913 , +15365 , +29663 , +22045 , +18891 , +24033 , +29413 , +17917 , +-22493 , +-23329 , +-2691 , +24725 , +-17513 , +5307 , +24123 , +22659 , +10107 , +10651 , +14319 , +27421 , +-22249 , +15933 , +28467 , +-25379 , +11399 , +-21317 , +10385 , +23655 , +6659 , +-24133 , +-29939 , +-15371 , +29637 , +6699 , +22343 , +12627 , +-9127 , +885 , +-23791 , +27735 , +7543 , +-2501 , +-28289 , +5087 , +18269 , +-31857 , +24463 , +-30401 , +167 , +-29531 , +-25297 , +4669 , +7843 , +-25323 , +-5405 , +27019 , +7721 , +-16501 , +5075 , +30139 , +-27395 , +-15103 , +-9109 , +24257 , +13207 , +30327 , +23917 , +-17959 , +28555 , +-22227 , +17297 , +1043 , +28245 , +-21157 , +-13425 , +9017 , +18615 , +3937 , +-11579 , +9559 , +16013 , +9103 , +-11193 , +-2393 , +-3285 , +21579 , +10879 , +17935 , +18993 , +-21801 , +27961 , +20501 , +-799 , +-30081 , +17475 , +-14239 , +32764 , +5723 , +-31101 , +-26205 , +21013 , +14715 , +-619 , +-19427 , +19057 , +-13907 , +-23081 , +-23919 , +81 , +-17241 , +-15605 , +7611 , +-7463 , +-6201 , +-24217 , +22091 , +6497 , +16973 , +23353 , +11611 , +-15285 , +8715 , +31473 , +4965 , +-18849 , +27301 , +-11837 , +-14909 , +16031 , +10053 , +23225 , +-23907 , +6821 , +-31027 , +-32177 , +-13467 , +10615 , +-19807 , +-21877 , +-12843 , +-2339 , +30667 , +17297 , +2905 , +-18625 , +15039 , +20671 , +-26857 , +-13321 , +11659 , +-19905 , +-15779 , +26667 , +16541 , +2861 , +3995 , +28199 , +-14875 , +-25571 , +-15397 , +7475 , +16037 , +-5571 , +-12615 , +-22549 , +19349 , +-29969 , +16607 , +19227 , +14249 , +-5157 , +2295 , +-755 , +5441 , +28553 , +12069 , +19821 , +-6685 , +-18821 , +18175 , +-29287 , +-15241 , +27843 , +20489 , +-9859 , +-30217 , +29723 , +-17243 , +6377 , +-6995 , +-15745 , +-10347 , +-28315 , +23019 , +-12991 , +16359 , +8343 , +10817 , +-10077 , +-19591 , +-18679 , +-28621 , +1013 , +-8217 , +11149 , +20855 , +27171 , +29195 , +-237 , +6825 , +11985 , +7151 , +10491 , +-25217 , +-12299 , +-14005 , +-31755 , +-5747 , +-27665 , +-17801 , +-3243 , +-2195 , +27675 , +-16925 , +-10007 , +-8567 , +9203 , +16407 , +-3239 , +-21183 , +13469 , +27169 , +15605 , +23471 , +5387 , +1683 , +-7407 , +-12065 , +24205 , +25853 , +-4639 , +29307 , +-25107 , +-3111 , +-20277 , +14099 , +10499 , +-14059 , +-25791 , +-19763 , +-12077 , +-12035 , +-32229 , +5783 , +-14305 , +-9291 , +-1683 , +-26131 , +-27003 , +16695 , +-10527 , +18181 , +28685 , +21449 , +29837 , +-24177 , +-14003 , +22767 , +-13241 , +8165 , +32762 , +16617 , +903 , +-4403 , +28671 , +-11091 , +32695 , +-2139 , +-13025 , +-28073 , +6927 , +-24281 , +6395 , +-4055 , +-28181 , +17049 , +3519 , +15865 , +-16223 , +-15993 , +21797 , +-8901 , +-13855 , +20991 , +25633 , +1889 , +-17025 , +-11967 , +21225 , +-9497 , +-10273 , +-19715 , +2453 , +-6461 , +-3659 , +-1779 , +-26309 , +-5029 , +14451 , +11683 , +6519 , +4097 , +-14573 , +-10227 , +-7529 , +12265 , +14197 , +25571 , +31781 , +-26205 , +-15305 , +-3383 , +6149 , +-10737 , +4869 , +4253 , +-3575 , +-15401 , +16255 , +-15819 , +27663 , +-18323 , +16007 , +-6505 , +16019 , +-8329 , +12827 , +25259 , +-27189 , +-28461 , +-14931 , +3965 , +29501 , +-11005 , +11003 , +-7445 , +11221 , +-12239 , +-12437 , +19175 , +23173 , +19359 , +25051 , +13089 , +8019 , +5541 , +16639 , +-21167 , +759 , +28703 , +-5573 , +-19491 , +22257 , +17777 , +-32525 , +-223 , +27171 , +23545 , +1641 , +25881 , +27107 , +16387 , +23061 , +-17499 , +18335 , +7243 , +-25993 , +-19145 , +31463 , +14573 , +-391 , +-20461 , +-2033 , +22751 , +-16577 , +-4097 , +13121 , +-21013 , +10881 , +14983 , +-30693 , +-25819 , +30051 , +19879 , +-8769 , +-541 , +26577 , +10507 , +-8333 , +13621 , +30801 , +-24123 , +-24141 , +-24611 , +28763 , +14471 , +3023 , +-14133 , +12599 , +-21925 , +-8707 , +-1521 , +-20141 , +13271 , +-21517 , +28243 , +-13805 , +-299 , +-23553 , +-10027 , +-4553 , +-19789 , +31395 , +31707 , +24743 , +-24829 , +21159 , +-31311 , +977 , +30917 , +-1613 , +-5093 , +22911 , +8735 , +20843 , +32337 , +-13521 , +29849 , +15613 , +25971 , +-11541 , +-31285 , +-5307 , +-13433 , +7333 , +24227 , +-10915 , +-7957 , +14345 , +-25327 , +18875 , +-1969 , +-3371 , +-1979 , +-9279 , +-3791 , +-3145 , +8035 , +-28709 , +-22321 , +-21085 , +-5439 , +7191 , +-22113 , +17317 , +22425 , +5433 , +-11953 , +30017 , +17989 , +24663 , +9523 , +11075 , +29429 , +-16145 , +-29371 , +-17117 , +-24343 , +-9341 , +-21097 , +-31027 , +28707 , +-31577 , +-27059 , +-6393 , +-10839 , +-19293 , +-32233 , +15941 , +-20941 , +-2167 , +23337 , +1527 , +25453 , +-20023 , +16047 , +-26507 , +7073 , +4429 , +-18745 , +-16063 , +27647 , +781 , +-7429 , +-21007 , +1355 , +1327 , +18233 , +22393 , +21271 , +11665 , +31045 , +-1007 , +-31363 , +15601 , +25787 , +-15999 , +-685 , +5755 , +23933 , +6141 , +-27927 , +29667 , +-18255 , +-2689 , +-20679 , +11775 , +9273 , +-32357 , +-20569 , +-3623 , +29863 , +18911 , +-29643 , +-17837 , +8633 , +-26975 , +14395 , +-6609 , +10577 , +-1957 , +-19041 , +17079 , +-28441 , +-23161 , +21133 , +-7477 , +15755 , +-16143 , +2481 , +6777 , +23121 , +8337 , +31983 , +30489 , +1367 , +-21273 , +-32107 , +3043 , +31535 , +-3893 , +-17123 , +-5363 , +30945 , +-3637 , +13655 , +9043 , +3169 , +-5883 , +28469 , +6693 , +-29825 , +-2953 , +-3859 , +-26071 , +-5779 , +22749 , +-19261 , +28259 , +8875 , +27655 , +32053 , +-7733 , +-2171 , +-16461 , +-31815 , +-1191 , +-21239 , +-23327 , +31219 , +-12629 , +3201 , +-24655 , +21871 , +-18153 , +22885 , +-7241 , +-8745 , +-7357 , +30175 , +28879 , +30121 , +-8389 , +-4685 , +-6019 , +5493 , +-17647 , +8135 , +-19519 , +-3695 , +24555 , +15887 , +-28301 , +-15795 , +-27231 , +23561 , +9487 , +9909 , +-32045 , +17339 , +-25057 , +6593 , +387 , +18717 , +4097 , +-3565 , +-24535 , +-11229 , +-28081 , +-7133 , +-22705 , +-9947 , +-15957 , +32521 , +-1113 , +-2083 , +-18147 , +7079 , +13477 , +30949 , +7143 , +-18845 , +-16493 , +-7773 , +18403 , +11113 , +26413 , +22221 , +18519 , +19795 , +6075 , +-31399 , +-24243 , +-12687 , +14235 , +18935 , +-29847 , +29811 , +27761 , +-12533 , +-18361 , +-29013 , +9383 , +22817 , +14157 , +9923 , +-17003 , +31213 , +-27897 , +-7185 , +-25073 , +-7755 , +-16643 , +6319 , +7561 , +-30887 , +-4597 , +-3335 , +-28769 , +24257 , +-5827 , +18181 , +19515 , +21973 , +-227 , +-5007 , +3111 , +-12293 , +9113 , +9731 , +29217 , +22539 , +22603 , +3041 , +6269 , +-16185 , +-2719 , +28745 , +-1227 , +27601 , +-5397 , +14017 , +-27003 , +-4311 , +-27981 , +-27169 , +-28161 , +-11999 , +10905 , +15215 , +20517 , +-27949 , +-28817 , +-13511 , +14985 , +-16097 , +20545 , +-20431 , +8785 , +17435 , +-19903 , +-18383 , +-29337 , +-23273 , +-17137 , +29235 , +18433 , +-31997 , +-6245 , +-14585 , +4793 , +-4741 , +32121 , +-15219 , +-15053 , +-8655 , +21689 , +4967 , +-17117 , +-30485 , +-5057 , +3897 , +-3599 , +-17931 , +-30053 , +-1695 , +-31537 , +-1243 , +30055 , +15905 , +9549 , +-18617 , +-9967 , +17517 , +8821 , +5147 , +31039 , +-16367 , +-32671 , +-17721 , +-15961 , +-399 , +-5551 , +18139 , +20321 , +9663 , +-9911 , +-27715 , +-30017 , +-8523 , +-14553 , +-24411 , +27049 , +24777 , +-14797 , +17175 , +-3467 , +22761 , +21827 , +24539 , +-26819 , +-23885 , +-14261 , +-7569 , +441 , +19497 , +7547 , +11017 , +26511 , +-9235 , +-26931 , +11011 , +-199 , +20983 , +-4053 , +-6175 , +-21165 , +-9525 , +-30215 , +-25411 , +-32139 , +-21191 , +24633 , +12865 , +8585 , +2701 , +9753 , +17705 , +-22869 , +-9915 , +24081 , +29485 , +9847 , +-11691 , +-14725 , +9859 , +24041 , +-18221 , +-3417 , +-26673 , +-21843 , +-27595 , +26745 , +16039 , +-7169 , +25861 , +6777 , +26749 , +11263 , +19487 , +-27021 , +11807 , +20875 , +-25499 , +-16245 , +32689 , +-9585 , +-12555 , +29395 , +32539 , +20205 , +-11805 , +-9879 , +-7923 , +-9277 , +-22151 , +-7413 , +-29583 , +-6319 , +-9251 , +-25045 , +12385 , +-21175 , +-24743 , +-9585 , +2211 , +31657 , +17167 , +-6295 , +-30563 , +-22505 , +-13779 , +-14875 , +9431 , +-10831 , +12711 , +-22453 , +-3359 , +-23699 , +22641 , +5523 , +22491 , +23275 , +565 , +-30339 , +32107 , +-18479 , +-4981 , +-5845 , +-15061 , +24481 , +28339 , +-23499 , +-3413 , +8721 , +-25653 , +-9659 , +17381 , +-26137 , +24451 , +23853 , +12341 , +17991 , +-29341 , +-6271 , +1489 , +-19305 , +23151 , +24491 , +7617 , +-11569 , +14707 , +32649 , +-8611 , +597 , +-28247 , +-18307 , +17463 , +849 , +18431 , +-21491 , +10657 , +20617 , +-27959 , +4343 , +1185 , +953 , +4087 , +23751 , +21343 , +-9623 , +-27181 , +2549 , +28465 , +29507 , +-18895 , +-11659 , +-513 , +23533 , +27695 , +-18725 , +-17851 , +1897 , +-5015 , +10723 , +-13939 , +17627 , +4015 , +14487 , +22881 , +20211 , +20549 , +1761 , +-17725 , +3003 , +-11889 , +30879 , +-19409 , +-27409 , +27219 , +24389 , +16897 , +-24353 , +10605 , +1007 , +32131 , +-7241 , +19719 , +26099 , +-7601 , +357 , +9301 , +1545 , +-21927 , +10215 , +-11325 , +-27181 , +30813 , +-5587 , +29625 , +25597 , +2263 , +29543 , +-32311 , +-9003 , +8577 , +-21789 , +7281 , +-2209 , +30533 , +24677 , +329 , +-6415 , +-15685 , +6393 , +-14911 , +-5813 , +-17637 , +-27561 , +16983 , +-30421 , +12213 , +-23893 , +-22447 , +11623 , +-2063 , +25341 , +14835 , +19591 , +-3651 , +-32261 , +7477 , +7391 , +-14709 , +-28323 , +16639 , +6427 , +-20791 , +4019 , +-13085 , +12647 , +-5161 , +14535 , +4941 , +251 , +12413 , +13927 , +32321 , +-8133 , +-20505 , +-13873 , +28303 , +11083 , +2845 , +1395 , +-31339 , +-27357 , +-11015 , +12119 , +20839 , +-8399 , +-7013 , +25589 , +-11373 , +-12951 , +11885 , +4485 , +-9641 , +-20767 , +23439 , +-7203 , +-23469 , +21221 , +-10287 , +14535 , +-14643 , +-15727 , +-29131 , +-19237 , +-12711 , +-26897 , +3035 , +4307 , +-28127 , +17283 , +16761 , +-18583 , +-20081 , +11631 , +-25759 , +19369 , +13455 , +-6399 , +-22549 , +-20531 , +-14781 , +26577 , +1133 , +-23409 , +-32195 , +-26279 , +-14145 , +-26355 , +-13261 , +4105 , +10535 , +-15595 , +10809 , +18661 , +-31017 , +6145 , +-26243 , +17301 , +-22813 , +15889 , +21881 , +-12027 , +18361 , +3649 , +-30289 , +28281 , +-13027 , +-16735 , +-6693 , +1317 , +15001 , +19759 , +-29513 , +26179 , +13433 , +17197 , +21797 , +-9295 , +16203 , +26871 , +-10767 , +-23291 , +-2619 , +-32159 , +13315 , +-18139 , +27983 , +-21621 , +11037 , +-23457 , +-32527 , +28217 , +18701 , +-9471 , +15053 , +10151 , +-11419 , +22643 , +5147 , +-10513 , +20413 , +-7475 , +17303 , +-5171 , +9821 , +-13583 , +-11643 , +11787 , +22397 , +-32485 , +-20447 , +21833 , +-17667 , +-10743 , +31645 , +26973 , +-15719 , +16515 , +15503 , +-31957 , +13991 , +-133 , +-15883 , +1531 , +-6841 , +28837 , +-8283 , +-5809 , +-17373 , +29581 , +16969 , +11075 , +17571 , +12589 , +4565 , +857 , +-1369 , +8201 , +6781 , +-4645 , +30135 , +-25401 , +-19403 , +10163 , +-9017 , +-4285 , +8349 , +-19787 , +-25493 , +5167 , +-26747 , +31373 , +-10357 , +8987 , +-17955 , +-19961 , +-30053 , +-22237 , +-23761 , +231 , +-9897 , +-12299 , +20889 , +-26035 , +32511 , +-22161 , +-25535 , +-11393 , +-9983 , +30651 , +28755 , +21327 , +-31679 , +18915 , +-29581 , +29155 , +1217 , +-15131 , +29369 , +-7907 , +28651 , +29015 , +-14043 , +13669 , +-28359 , +25967 , +-8035 , +26381 , +-32393 , +-23637 , +-26019 , +-7137 , +10355 , +1501 , +25595 , +19133 , +-24257 , +3273 , +-32305 , +25587 , +-1825 , +27707 , +24567 , +30485 , +16267 , +-21599 , +8653 , +-29299 , +25689 , +-19681 , +10205 , +-16575 , +-11385 , +-25301 , +-15269 , +8033 , +20259 , +-23387 , +-10719 , +25021 , +-1461 , +-30869 , +-32223 , +-12121 , +3813 , +13683 , +-15521 , +-21693 , +13779 , +9317 , +2411 , +-31645 , +-1615 , +8117 , +-25255 , +-17957 , +19461 , +-4817 , +1331 , +-25505 , +-27391 , +-25057 , +7675 , +24533 , +17839 , +-6947 , +9241 , +27695 , +25783 , +18159 , +25179 , +9927 , +3463 , +-31853 , +-16539 , +-13265 , +23069 , +1769 , +-7757 , +29327 , +-20693 , +-16007 , +8711 , +-13187 , +-7453 , +15449 , +1127 , +-15275 , +13857 , +16831 , +28565 , +-30711 , +-26585 , +-3563 , +23299 , +7559 , +11477 , +-25187 , +11087 , +6019 , +-29339 , +14971 , +30011 , +-32037 , +-17507 , +-12459 , +24351 , +-23449 , +16267 , +-21907 , +22761 , +-24751 , +26553 , +-17103 , +25235 , +-25611 , +9193 , +-2983 , +-26349 , +-30927 , +29261 , +-7041 , +16867 , +571 , +-10437 , +-23757 , +3301 , +-25849 , +-10393 , +9369 , +-15123 , +-6901 , +-4961 , +-2693 , +9905 , +-30039 , +-4867 , +-22047 , +5693 , +-4353 , +23713 , +-10191 , +-5389 , +30779 , +-24085 , +-1859 , +2559 , +6777 , +-27597 , +485 , +-30897 , +15133 , +23801 , +6305 , +1291 , +-31579 , +9133 , +11689 , +-30321 , +-15613 , +31701 , +-8445 , +-31773 , +24695 , +3539 , +30237 , +-18773 , +-25885 , +29203 , +23141 , +16813 , +2471 , +-18739 , +-12189 , +-32323 , +-29703 , +-30669 , +23887 , +-199 , +14265 , +29485 , +-22741 , +8965 , +24781 , +14999 , +10579 , +-5633 , +20729 , +-18705 , +-27227 , +20213 , +-14289 , +14481 , +14857 , +-23777 , +-8841 , +-7055 , +17043 , +-29413 , +22581 , +851 , +12307 , +-6559 , +6671 , +-17537 , +23349 , +12087 , +-20163 , +11517 , +-9193 , +-11981 , +-21659 , +26699 , +-20901 , +-6101 , +-16145 , +14229 , +27079 , +-13905 , +28899 , +12911 , +26457 , +771 , +9529 , +5127 , +-21795 , +1427 , +30651 , +-13333 , +26891 , +14835 , +-20653 , +16683 , +-32231 , +-20151 , +3559 , +16425 , +-14121 , +11605 , +1721 , +-30019 , +28227 , +-18723 , +-2771 , +-32005 , +27049 , +31407 , +27699 , +26723 , +13613 , +9483 , +-18923 , +-24675 , +-18699 , +29611 , +-25391 , +-851 , +-20817 , +13871 , +4851 , +-30803 , +32695 , +29983 , +-11031 , +-19443 , +-20567 , +-2219 , +-25887 , +-32199 , +-3721 , +-8701 , +-3303 , +-31773 , +5381 , +-28889 , +23745 , +15023 , +-19649 , +-22913 , +-17591 , +-13965 , +-4429 , +9475 , +-17855 , +28651 , +8357 , +-26915 , +14759 , +-14099 , +-13651 , +26595 , +23247 , +17197 , +-23353 , +7823 , +17835 , +-13211 , +8179 , +-19085 , +16041 , +10015 , +13639 , +-13515 , +9489 , +-7461 , +-9845 , +-7935 , +-3631 , +28373 , +-4781 , +24461 , +20193 , +16179 , +395 , +-25979 , +-8429 , +31941 , +-14177 , +-30073 , +20075 , +14139 , +-29687 , +30111 , +-15617 , +-28203 , +32361 , +15927 , +-14779 , +-7511 , +16933 , +-28521 , +16115 , +15437 , +31861 , +-22825 , +-27825 , +23065 , +-13049 , +-9381 , +-29681 , +26333 , +529 , +-15927 , +4013 , +-27117 , +-7965 , +-381 , +20031 , +1953 , +23311 , +-27491 , +30159 , +-4603 , +-30735 , +-7599 , +-30923 , +28441 , +15055 , +1027 , +25451 , +14147 , +-29329 , +-10835 , +-22165 , +14129 , +14131 , +19161 , +31873 , +-31733 , +2217 , +21795 , +-13529 , +-11721 , +25513 , +4387 , +11865 , +-32123 , +2029 , +29165 , +-1679 , +-17943 , +3111 , +8971 , +-28033 , +31675 , +23447 , +-10003 , +-21731 , +15975 , +-28633 , +-14363 , +29131 , +-3417 , +-32509 , +31143 , +21445 , +-2757 , +23983 , +-18129 , +26459 , +-7389 , +-21089 , +-12981 , +5835 , +-14251 , +3149 , +-18037 , +9111 , +-24329 , +-1575 , +-16973 , +-26019 , +-23279 , +-26603 , +-13373 , +-12499 , +22223 , +-21463 , +11359 , +-1431 , +-13519 , +-17245 , +2509 , +-29163 , +9539 , +-23535 , +6517 , +-9297 , +-17445 , +28699 , +7111 , +8843 , +-7729 , +-6887 , +27331 , +-24915 , +-14171 , +32301 , +20207 , +-20455 , +30169 , +16853 , +21189 , +-19793 , +17031 , +17163 , +19637 , +-24949 , +-8785 , +9945 , +22425 , +2251 , +18659 , +-31119 , +29099 , +-25351 , +-14457 , +-31289 , +-1531 , +-22825 , +14467 , +30375 , +-15217 , +-15167 , +-11649 , +-8117 , +-901 , +23161 , +-17767 , +-15497 , +-29375 , +-9077 , +28059 , +29457 , +18963 , +-29669 , +29629 , +-9929 , +-29743 , +-17595 , +22219 , +-32555 , +32137 , +12783 , +21233 , +15299 , +-12433 , +-13529 , +-17947 , +-17065 , +2123 , +-7439 , +-32607 , +385 , +11641 , +-21331 , +-4189 , +-10145 , +-1693 , +2531 , +-4707 , +28253 , +22641 , +-1633 , +-9041 , +10431 , +25739 , +14415 , +-32223 , +-20789 , +-26875 , +10255 , +-3947 , +30543 , +26915 , +-26231 , +-4917 , +-19767 , +6919 , +-29361 , +-15157 , +-5647 , +-9933 , +-31317 , +4519 , +10459 , +-1931 , +-32513 , +23469 , +3723 , +-32663 , +13463 , +6437 , +-26355 , +-17297 , +-24569 , +-125 , +1551 , +2847 , +-28421 , +7971 , +-24587 , +-23483 , +12181 , +-16005 , +-12425 , +-29357 , +11079 , +-32291 , +18865 , +29799 , +-24543 , +-26455 , +-19775 , +-22097 , +19637 , +-12029 , +-29469 , +-4239 , +12391 , +8459 , +-13319 , +22655 , +10825 , +23713 , +-6727 , +-4821 , +-20367 , +-1399 , +-18897 , +20159 , +14287 , +25651 , +4327 , +4477 , +25739 , +-14355 , +22139 , +1293 , +-25897 , +-6757 , +-6485 , +9083 , +2125 , +-12815 , +-14595 , +24239 , +-16961 , +3109 , +21963 , +1121 , +-3691 , +12847 , +25055 , +-3945 , +679 , +16253 , +32399 , +18067 , +21387 , +-9681 , +-5039 , +-6053 , +-27013 , +-11581 , +-4655 , +25759 , +-24161 , +-5539 , +-7795 , +-27845 , +25581 , +21365 , +-2069 , +-26571 , +4739 , +-6895 , +-8751 , +-31455 , +9849 , +30845 , +13249 , +20785 , +17211 , +27015 , +10601 , +24475 , +-25247 , +-20179 , +5569 , +19611 , +-1527 , +-27931 , +25507 , +14561 , +-8529 , +21569 , +-21791 , +19353 , +2431 , +-2247 , +19931 , +-23853 , +-13769 , +28375 , +29595 , +27267 , +21363 , +18041 , +-18833 , +20985 , +-25453 , +13181 , +24311 , +6101 , +-5115 , +-30333 , +-31801 , +25729 , +-24025 , +2337 , +-6785 , +-21713 , +23705 , +283 , +-8361 , +18757 , +2587 , +14877 , +17481 , +-25505 , +1759 , +-23311 , +-32617 , +18115 , +-9883 , +17205 , +-10255 , +23129 , +-22577 , +17049 , +6149 , +-24029 , +-579 , +-15725 , +-26725 , +-15817 , +-1371 , +15507 , +-9683 , +26167 , +-32601 , +1733 , +-20489 , +13889 , +31723 , +-5821 , +10909 , +-13709 , +-9617 , +15817 , +15927 , +21725 , +19565 , +-28169 , +26351 , +14841 , +25895 , +17407 , +11033 , +20387 , +13379 , +4579 , +-11835 , +-1391 , +-4185 , +4911 , +9695 , +-7603 , +-14899 , +5417 , +-25147 , +29611 , +28821 , +-11891 , +-16549 , +-5697 , +-24401 , +-2101 , +6307 , +5469 , +-9893 , +-32589 , +-23331 , +-25851 , +-11047 , +17591 , +-2539 , +-8345 , +2349 , +19617 , +-1213 , +23123 , +25987 , +-11067 , +-17699 , +-30669 , +-8189 , +31427 , +-9741 , +12805 , +-5079 , +-29261 , +18371 , +17359 , +29089 , +-1817 , +-6695 , +-5731 , +23445 , +-16093 , +-31591 , +10995 , +22673 , +-29621 , +3177 , +-17209 , +-7469 , +11175 , +11063 , +16895 , +10535 , +-24433 , +24225 , +-19879 , +-4037 , +-27727 , +-19841 , +8185 , +1149 , +-18755 , +3077 , +-27827 , +21613 , +2209 , +22871 , +13715 , +19319 , +29765 , +32163 , +-32313 , +-31411 , +-15939 , +20915 , +-19421 , +29117 , +20995 , +-28403 , +12307 , +267 , +-25295 , +2953 , +5291 , +-3899 , +-5321 , +-3229 , +-18523 , +-12001 , +16149 , +-24615 , +16081 , +23239 , +-4979 , +-25529 , +4119 , +11589 , +-12187 , +23473 , +20455 , +-29239 , +-23787 , +26855 , +9775 , +16007 , +24071 , +27419 , +481 , +1683 , +11081 , +-10505 , +-27943 , +561 , +-10295 , +-23499 , +-19871 , +21431 , +16395 , +-8265 , +-3545 , +19675 , +-20639 , +29213 , +2479 , +-22381 , +-22107 , +-3353 , +-9645 , +-4763 , +5997 , +-8195 , +16825 , +-28601 , +19655 , +4567 , +29381 , +-4109 , +-7567 , +-15353 , +3353 , +-16193 , +-9843 , +2651 , +-21753 , +245 , +477 , +2671 , +7695 , +3501 , +6777 , +-11827 , +4557 , +-4061 , +-23291 , +8315 , +19839 , +31629 , +-7311 , +23 , +19441 , +21371 , +-2007 , +32625 , +25085 , +29345 , +-24373 , +27297 , +11129 , +19009 , +-31891 , +22435 , +30397 , +4597 , +-31167 , +-8349 , +26257 , +24585 , +10717 , +23399 , +675 , +-23975 , +24049 , +-39 , +-4471 , +-28763 , +-14221 , +-21983 , +32563 , +10601 , +-2201 , +15365 , +-6431 , +26165 , +29961 , +-9415 , +-20577 , +7305 , +13971 , +-4745 , +15419 , +17955 , +23911 , +10527 , +-30787 , +13281 , +-15663 , +-28093 , +-9373 , +-13799 , +17979 , +-17333 , +-19697 , +23911 , +21987 , +10245 , +-30645 , +18449 , +-21991 , +5697 , +-17477 , +-12331 , +-21775 , +-22813 , +21777 , +29767 , +30847 , +-25465 , +-11887 , +15787 , +3469 , +-25463 , +-18183 , +9285 , +29909 , +17325 , +12553 , +10295 , +-30541 , +-6357 , +18285 , +12759 , +13669 , +23117 , +10819 , +21131 , +-19007 , +-28537 , +1795 , +32279 , +-15769 , +29705 , +-14331 , +21631 , +11139 , +-14111 , +26741 , +5215 , +-11015 , +29833 , +5827 , +19899 , +-29397 , +517 , +-8795 , +27995 , +-18911 , +-17797 , +2959 , +-18267 , +14673 , +10825 , +4259 , +-11787 , +-16949 , +27293 , +2863 , +23921 , +-26375 , +1931 , +-17759 , +-8601 , +29135 , +-9557 , +4357 , +25883 , +3723 , +-19923 , +6905 , +9517 , +17641 , +7279 , +30243 , +-29595 , +-31525 , +12317 , +3633 , +-3567 , +-2625 , +-22339 , +22595 , +30427 , +-25057 , +12239 , +-15117 , +11551 , +-29217 , +10857 , +-24383 , +8653 , +-32005 , +-7359 , +6931 , +23985 , +191 , +26965 , +-21593 , +30551 , +20859 , +-1287 , +-29041 , +-12959 , +27325 , +21869 , +-29019 , +349 , +11277 , +-16129 , +-10617 , +-13541 , +-4067 , +12701 , +17 , +-17271 , +-6005 , +21485 , +6731 , +3593 , +15375 , +-8479 , +-8725 , +2891 , +24377 , +475 , +-14261 , +14501 , +-24665 , +18233 , +21725 , +-14109 , +22975 , +-15501 , +3365 , +31659 , +-12059 , +-5969 , +-22731 , +31825 , +8753 , +-10531 , +-5475 , +22821 , +18861 , +-32687 , +-27669 , +-21667 , +-19963 , +31441 , +-4451 , +-30879 , +18123 , +-10953 , +23967 , +19871 , +-32479 , +-13943 , +-30151 , +-3085 , +26361 , +-23673 , +29079 , +24431 , +-2869 , +-19507 , +2223 , +-6467 , +-5679 , +-22683 , +-20795 , +-27409 , +28345 , +7141 , +9825 , +17635 , +-28965 , +-14333 , +19649 , +11531 , +-1025 , +4267 , +18393 , +-3115 , +5253 , +25243 , +25289 , +-7049 , +-23517 , +10361 , +20685 , +23627 , +22307 , +-19091 , +3781 , +2219 , +22543 , +-971 , +6937 , +3395 , +4083 , +27329 , +15429 , +-21781 , +-32493 , +-15799 , +-29247 , +32515 , +13339 , +17385 , +2945 , +-3261 , +12263 , +2477 , +21487 , +-2535 , +-3157 , +-7109 , +-10151 , +-27773 , +-5199 , +-27427 , +13303 , +-31139 , +22677 , +-17379 , +-7851 , +23111 , +8441 , +21725 , +1621 , +13807 , +-31303 , +5105 , +-29019 , +-6669 , +12463 , +-31687 , +19631 , +16435 , +-27171 , +14127 , +22815 , +30641 , +7983 , +-7673 , +26829 , +30939 , +6829 , +-16567 , +20803 , +-6541 , +-7367 , +3299 , +29607 , +-12581 , +15297 , +-315 , +17977 , +-19981 , +21753 , +-525 , +-19373 , +-4239 , +30101 , +-29655 , +-29485 , +13751 , +-17155 , +-23581 , +-18661 , +2343 , +-1905 , +-4859 , +26247 , +-1017 , +835 , +-25113 , +1127 , +-20789 , +-22531 , +24821 , +2163 , +12535 , +32299 , +5821 , +30667 , +-9615 , +-18155 , +-13161 , +16995 , +13663 , +24959 , +-16471 , +14083 , +4219 , +-3597 , +-15213 , +-14911 , +20967 , +-12945 , +-5255 , +18677 , +-23923 , +-30559 , +-18275 , +3243 , +-30219 , +32151 , +-13953 , +-13143 , +4761 , +-24057 , +15981 , +-7971 , +-28993 , +6137 , +-16229 , +-12203 , +-27181 , +28929 , +31937 , +-32065 , +-11715 , +7165 , +-5585 , +-14251 , +-18503 , +-2745 , +-18845 , +28769 , +-17869 , +29045 , +-21207 , +-22997 , +7445 , +23171 , +-2777 , +-13189 , +-3285 , +-26725 , +30973 , +-28795 , +26357 , +-2239 , +-11039 , +25965 , +-7301 , +29713 , +-24405 , +13621 , +13741 , +-5131 , +28277 , +23613 , +15929 , +-15903 , +21939 , +-13769 , +19423 , +25089 , +25289 , +27551 , +-18869 , +8315 , +-15579 , +-25937 , +-11921 , +27303 , +1489 , +-12571 , +-11941 , +-15685 , +18579 , +17131 , +-18801 , +32277 , +-22141 , +-14061 , +-9509 , +-16925 , +-10979 , +-31141 , +14003 , +-26013 , +2273 , +-13359 , +-2297 , +-1893 , +25191 , +-14693 , +31643 , +653 , +-11531 , +15979 , +21983 , +-17931 , +-28773 , +6771 , +24651 , +-25223 , +21965 , +-6947 , +-31183 , +-10133 , +23665 , +1225 , +21527 , +-2825 , +18819 , +-6461 , +-6001 , +-30497 , +1059 , +-13387 , +23953 , +-11079 , +-17609 , +30311 , +16979 , +-12901 , +-1927 , +28529 , +15771 , +-30369 , +6165 , +6073 , +28831 , +-31407 , +-835 , +16739 , +-19877 , +-16529 , +22601 , +-30897 , +15201 , +6681 , +24773 , +6931 , +-9667 , +597 , +18959 , +16747 , +18503 , +-12169 , +23533 , +13623 , +-18693 , +-9369 , +-857 , +-22287 , +11729 , +-18861 , +-30693 , +-24919 , +-12141 , +-28443 , +19289 , +-12683 , +-22979 , +12801 , +31931 , +21359 , +-1973 , +-31501 , +-30601 , +-10451 , +-7529 , +12599 , +-30271 , +-3147 , +11185 , +13471 , +18521 , +1017 , +-587 , +-2023 , +-27991 , +6861 , +-26721 , +-10529 , +19551 , +22623 , +-28883 , +-28623 , +2427 , +22067 , +-17615 , +-25711 , +-29197 , +-7791 , +24165 , +-10383 , +2499 , +-17269 , +-21811 , +-30087 , +27013 , +-25241 , +13703 , +12083 , +-27757 , +9377 , +29477 , +583 , +-5745 , +351 , +-11131 , +-13513 , +-6519 , +-919 , +-25555 , +-10353 , +12689 , +8609 , +1051 , +-24409 , +-821 , +-16387 , +-13275 , +5073 , +2323 , +30717 , +-14133 , +-2795 , +9733 , +4259 , +-30061 , +21615 , +-31067 , +19181 , +-18977 , +-29315 , +-15763 , +27591 , +9029 , +-13893 , +-9501 , +-19315 , +24683 , +32063 , +7613 , +-32261 , +-22187 , +-10775 , +15211 , +18855 , +-3511 , +-27357 , +27195 , +11771 , +6687 , +19477 , +-4633 , +24745 , +-8933 , +29277 , +-9293 , +2987 , +-24503 , +20295 , +29447 , +-1875 , +-21171 , +11655 , +-7555 , +-20713 , +-2363 , +-11925 , +-11901 , +16499 , +-749 , +-22111 , +-31117 , +31601 , +-5177 , +-19879 , +287 , +-17057 , +-30875 , +-31979 , +-7687 , +6681 , +975 , +32461 , +30113 , +4741 , +23305 , +-24905 , +-17155 , +-28273 , +15523 , +-12433 , +-13863 , +26523 , +11653 , +22717 , +18421 , +-897 , +-4015 , +18377 , +-30047 , +28671 , +-12751 , +21453 , +-2341 , +-8001 , +-10189 , +13651 , +8667 , +4539 , +-18141 , +-6163 , +31797 , +9801 , +12261 , +-12693 , +-7825 , +-21377 , +-13759 , +12691 , +-7151 , +-20927 , +-1971 , +4439 , +11853 , +163 , +4149 , +-16237 , +-12541 , +-30223 , +23197 , +17219 , +-13459 , +-18909 , +-16527 , +-6347 , +-13017 , +-11823 , +11081 , +3911 , +17617 , +-31829 , +17713 , +-22243 , +-9949 , +7289 , +-29423 , +17757 , +31363 , +-2677 , +31351 , +19041 , +-3295 , +-27217 , +-19461 , +14703 , +19345 , +-11081 , +-2291 , +32377 , +-9255 , +-19105 , +-14251 , +-15799 , +24853 , +11729 , +-31609 , +14151 , +-4217 , +-26983 , +-5703 , +-10079 , +6449 , +-2017 , +-20161 , +5139 , +8429 , +-4451 , +20995 , +-10731 , +-28149 , +23701 , +-31911 , +28819 , +5213 , +-23603 , +-26535 , +21545 , +-11049 , +-25403 , +19389 , +5085 , +23207 , +1203 , +5165 , +-21683 , +8395 , +-26123 , +-26335 , +32627 , +-13271 , +-24825 , +24627 , +4565 , +22057 , +-1017 , +19197 , +-8639 , +969 , +-18783 , +-661 , +23297 , +-32455 , +-1905 , +-15211 , +-27753 , +-1549 , +23687 , +5659 , +22003 , +-31411 , +-17983 , +16373 , +27183 , +-16485 , +9699 , +24787 , +-13123 , +-6211 , +25983 , +16623 , +25387 , +22847 , +-31989 , +9063 , +9041 , +-17687 , +-15279 , +10267 , +9491 , +-17949 , +-18825 , +22009 , +-26991 , +-22211 , +-30617 , +-6689 , +2781 , +-8685 , +27599 , +-6673 , +6975 , +8229 , +13463 , +-12955 , +-11553 , +1767 , +-4387 , +6391 , +-8951 , +-25827 , +-23709 , +-30815 , +-4643 , +5367 , +659 , +4103 , +23943 , +3749 , +11761 , +9801 , +28157 , +875 , +22543 , +27231 , +13109 , +29509 , +29457 , +22245 , +-27177 , +-32017 , +-23147 , +2181 , +26745 , +28813 , +-16837 , +-19009 , +1887 , +-19271 , +23951 , +-4279 , +31395 , +10265 , +3725 , +16615 , +-27911 , +1411 , +1427 , +19135 , +-1819 , +8327 , +-16941 , +-5319 , +-22929 , +10387 , +11609 , +-28343 , +-15521 , +20609 , +-14471 , +20311 , +23537 , +12983 , +1481 , +-14707 , +-5611 , +18871 , +-20583 , +-32081 , +10525 , +-10941 , +-26645 , +-8583 , +11255 , +-31773 , +2545 , +2161 , +11759 , +-18159 , +-25609 , +16451 , +5595 , +-14395 , +-24343 , +-7017 , +9173 , +-1653 , +-4027 , +26987 , +-16003 , +-17883 , +15505 , +-12571 , +-4959 , +-16487 , +-20391 , +-20297 , +13443 , +-31021 , +2465 , +-31257 , +-15991 , +-845 , +-5151 , +10551 , +24443 , +-21589 , +-24453 , +16879 , +561 , +17875 , +-591 , +-23233 , +-17191 , +-7285 , +-21469 , +18453 , +-23645 , +-12671 , +-32063 , +-9871 , +-28673 , +12635 , +12617 , +-25281 , +16209 , +-31801 , +-3783 , +-24653 , +-15313 , +2831 , +30023 , +-9961 , +-15851 , +18235 , +-12447 , +23091 , +27545 , +-23393 , +-31461 , +6417 , +-17619 , +18937 , +-30033 , +30311 , +-8623 , +23305 , +23663 , +4965 , +19273 , +-30809 , +-4417 , +4111 , +31063 , +16217 , +-21359 , +18967 , +-19595 , +24943 , +15445 , +-19407 , +-627 , +-15971 , +17273 , +24049 , +-31697 , +22793 , +-8101 , +17437 , +-28987 , +31727 , +4805 , +-32377 , +27733 , +-5199 , +-13595 , +-1945 , +21169 , +7537 , +-10561 , +3123 , +-22477 , +-29397 , +26159 , +-31759 , +-20493 , +30027 , +23895 , +11545 , +4219 , +-15677 , +11679 , +22241 , +11531 , +-25173 , +27941 , +-16863 , +-14009 , +24143 , +-6979 , +421 , +-4243 , +18127 , +19559 , +14081 , +-28393 , +-9939 , +28223 , +-18445 , +-9621 , +8691 , +-6139 , +-16333 , +-20523 , +-12481 , +17153 , +-3125 , +20035 , +27745 , +-25969 , +26103 , +-31275 , +-26125 , +-30457 , +14451 , +-30949 , +-26005 , +-27843 , +27483 , +-17715 , +2877 , +-13703 , +-2693 , +-25599 , +8809 , +-8977 , +-17103 , +3299 , +18587 , +19633 , +-30279 , +7659 , +26557 , +1325 , +-31471 , +-16483 , +-14831 , +1829 , +26187 , +22199 , +-14899 , +25381 , +-9117 , +-21777 , +24877 , +14971 , +20889 , +10283 , +-17651 , +-335 , +-24755 , +-5581 , +-25599 , +-22657 , +-13743 , +-29965 , +13299 , +5967 , +24515 , +11049 , +-2003 , +26151 , +-30103 , +-21081 , +-2559 , +19239 , +30849 , +-25347 , +29139 , +23689 , +10785 , +-19519 , +10943 , +24075 , +16393 , +32575 , +6817 , +21999 , +-7425 , +5291 , +2751 , +-24463 , +23461 , +20711 , +-11059 , +-17985 , +29395 , +-25935 , +-22377 , +-2441 , +12905 , +-24741 , +11793 , +-7535 , +7859 , +521 , +-9235 , +32487 , +-32719 , +30051 , +23221 , +5409 , +-10755 , +14287 , +19557 , +-9679 , +2203 , +27183 , +20611 , +5967 , +30041 , +14605 , +-25423 , +4459 , +27159 , +20571 , +463 , +26409 , +10675 , +-28245 , +-19061 , +7511 , +4309 , +-31513 , +-18311 , +4579 , +-3257 , +31621 , +12467 , +3417 , +18897 , +-8641 , +-28443 , +10969 , +18575 , +-25261 , +-7183 , +-12667 , +30155 , +15155 , +5373 , +-7539 , +-9901 , +27069 , +-29675 , +-28015 , +23633 , +-19971 , +-2247 , +15789 , +29091 , +7763 , +-26629 , +-10531 , +-24907 , +24383 , +-4715 , +27657 , +-811 , +25225 , +4993 , +2929 , +19215 , +-11007 , +-21357 , +-16477 , +-22393 , +-31045 , +-19823 , +-9733 , +-28857 , +10681 , +581 , +17305 , +10145 , +25393 , +-997 , +3285 , +-29693 , +-22723 , +4411 , +-3271 , +5457 , +-10473 , +-27367 , +5629 , +18359 , +6607 , +-21613 , +-28425 , +30733 , +-6267 , +-21623 , +13851 , +-15969 , +-16613 , +-12813 , +7533 , +25749 , +32375 , +-32393 , +17279 , +9405 , +-10959 , +14981 , +-4511 , +-16145 , +-13869 , +6129 , +4385 , +6877 , +-13941 , +13315 , +26047 , +10091 , +14951 , +-1517 , +30115 , +16271 , +2059 , +22691 , +18585 , +-5729 , +8937 , +10235 , +-3511 , +-19665 , +27131 , +-25297 , +-18901 , +13161 , +-2313 , +8657 , +-1533 , +-12831 , +17677 , +26611 , +-16679 , +19953 , +10775 , +4809 , +-10133 , +-3441 , +6745 , +-13375 , +-25809 , +677 , +-20811 , +7193 , +14529 , +-32277 , +-6813 , +-7431 , +-32031 , +7739 , +5415 , +-16379 , +19689 , +-4753 , +2835 , +19069 , +9161 , +5043 , +19117 , +27857 , +-27529 , +-5535 , +-5957 , +-17221 , +-18195 , +-16555 , +-1941 , +10193 , +17313 , +-15159 , +789 , +-13145 , +-16007 , +18861 , +-32145 , +22623 , +19013 , +-11653 , +-10941 , +-16193 , +22461 , +10897 , +-22865 , +-19753 , +-1297 , +1551 , +16335 , +-29175 , +10297 , +19493 , +-17401 , +17319 , +20939 , +-24083 , +-26709 , +-3315 , +2191 , +19915 , +-28353 , +-26053 , +-9295 , +2875 , +21807 , +-19739 , +11915 , +-6351 , +-5115 , +5135 , +15651 , +-17171 , +25375 , +-4053 , +1825 , +27475 , +-22547 , +18339 , +22855 , +23233 , +3491 , +-22525 , +-21141 , +27499 , +30071 , +-28799 , +6381 , +-7115 , +-28337 , +19741 , +431 , +31233 , +14597 , +-19145 , +-11891 , +1941 , +18969 , +-32087 , +24665 , +3557 , +2537 , +-17313 , +19527 , +-27403 , +-32155 , +-2199 , +-1799 , +-31443 , +-11947 , +-12903 , +27875 , +4401 , +-7681 , +24733 , +-15025 , +18487 , +-30359 , +16783 , +30929 , +26857 , +32021 , +-27371 , +8253 , +3243 , +7211 , +-13325 , +-475 , +-15481 , +-31935 , +-14299 , +-817 , +14455 , +-7545 , +-14725 , +23205 , +30273 , +-29049 , +-6999 , +-17097 , +25811 , +-15531 , +-25623 , +-7501 , +5905 , +-28081 , +2055 , +-22059 , +315 , +-3503 , +21253 , +-22429 , +-20551 , +27245 , +7465 , +2087 , +5751 , +20257 , +14751 , +-7575 , +4291 , +2583 , +-26745 , +-11809 , +10647 , +25685 , +-20589 , +-3287 , +17539 , +19187 , +19997 , +3019 , +16113 , +1631 , +4543 , +4007 , +8721 , +23559 , +30319 , +-17173 , +-733 , +-28001 , +-15091 , +-31083 , +85 , +-12089 , +-16503 , +-31391 , +-4075 , +-12711 , +24943 , +-22711 , +-30475 , +20493 , +-29439 , +-10887 , +-5131 , +26045 , +-807 , +18629 , +-21657 , +-7399 , +20981 , +-15195 , +-28613 , +2783 , +-27055 , +-3923 , +-20509 , +-7017 , +3079 , +-30589 , +-5469 , +13503 , +-24355 , +-26027 , +27245 , +-28779 , +-8603 , +-29737 , +14903 , +32321 , +-20851 , +7603 , +-29231 , +11921 , +-13117 , +9611 , +-11709 , +-23245 , +15229 , +13927 , +7839 , +-5525 , +-27041 , +-4171 , +7517 , +10571 , +-26421 , +10937 , +1587 , +14699 , +-20227 , +-16755 , +-16279 , +-29915 , +-2143 , +4759 , +-14927 , +-4539 , +25577 , +14203 , +-8823 , +11081 , +-27601 , +-16741 , +18691 , +-6381 , +763 , +2057 , +30509 , +-14043 , +173 , +16131 , +-9765 , +23637 , +18829 , +-17175 , +-3317 , +-24051 , +-28577 , +2743 , +12981 , +-12297 , +-10877 , +14585 , +-17117 , +12351 , +-7543 , +-14777 , +-20013 , +-25527 , +-15797 , +-13251 , +2749 , +-30237 , +-29311 , +-21779 , +-21441 , +8965 , +25563 , +-5409 , +-17051 , +24579 , +-5733 , +-29307 , +-7987 , +-25523 , +8621 , +-31693 , +26099 , +-25191 , +-965 , +-31335 , +2837 , +-31319 , +29127 , +-1609 , +26501 , +-22913 , +-32057 , +13401 , +-27009 , +-20209 , +-3145 , +-18933 , +14979 , +13949 , +7603 , +-21605 , +28977 , +-3115 , +-21615 , +25599 , +-12389 , +-8129 , +-25739 , +-2849 , +-223 , +30141 , +23793 , +-14973 , +4805 , +11357 , +25487 , +14415 , +11527 , +-24589 , +1531 , +10933 , +-29123 , +22611 , +395 , +-31815 , +-23705 , +-21497 , +31327 , +-30503 , +11661 , +-19065 , +-12297 , +12691 , +6541 , +-11533 , +7757 , +12633 , +8321 , +-22457 , +-15507 , +-4095 , +-14199 , +7193 , +-15993 , +10441 , +-8655 , +18121 , +21903 , +26567 , +-455 , +-13245 , +-26033 , +7653 , +18427 , +-26581 , +-28669 , +-31913 , +-12227 , +29857 , +24689 , +147 , +-4985 , +29553 , +14203 , +21961 , +-4351 , +-24113 , +-30653 , +14555 , +27331 , +-373 , +5811 , +-24101 , +-26441 , +10959 , +-25183 , +32245 , +-2841 , +-12977 , +26981 , +245 , +-21413 , +8201 , +-16655 , +19769 , +-3217 , +-24457 , +26465 , +-21977 , +-9043 , +23119 , +14367 , +299 , +-14299 , +-15187 , +-4237 , +-9943 , +829 , +-22053 , +15775 , +-30599 , +-20203 , +4477 , +21109 , +-10917 , +-27817 , +-23217 , +-14483 , +-17163 , +-13417 , +-30627 , +15943 , +-26427 , +11549 , +6325 , +-29679 , +23195 , +14153 , +-27735 , +-14125 , +5909 , +20587 , +5247 , +7063 , +-26991 , +22803 , +-6743 , +-25847 , +9381 , +12271 , +-25467 , +6801 , +22047 , +15907 , +-2165 , +15331 , +-651 , +-23523 , +-2293 , +-25313 , +1467 , +7921 , +10339 , +31585 , +27689 , +15917 , +-25671 , +-24093 , +4097 , +569 , +31791 , +-629 , +-28395 , +31525 , +-15711 , +-21237 , +-2891 , +-32764 , +-1321 , +-6797 , +18733 , +5835 , +-27841 , +-31925 , +-65 , +-23391 , +-20699 , +-24529 , +13589 , +32439 , +-3215 , +1249 , +-24521 , +-3163 , +17875 , +-12317 , +24593 , +25919 , +-2429 , +10385 , +24409 , +-29969 , +19579 , +22199 , +-30957 , +29833 , +-5081 , +5801 , +30597 , +26023 , +4261 , +-32293 , +-79 , +8575 , +3957 , +25597 , +2889 , +-16579 , +7869 , +21641 , +16173 , +-24875 , +-10767 , +27879 , +-935 , +-27037 , +24859 , +-3329 , +365 , +-4095 , +-8573 , +-12207 , +25233 , +20509 , +-8453 , +11657 , +4097 , +7243 , +-32641 , +2723 , +-23821 , +31405 , +7043 , +11127 , +-22239 , +-32325 , +-1381 , +12501 , +9901 , +-20315 , +5313 , +13855 , +-31061 , +18469 , +16893 , +-13471 , +-19951 , +-25637 , +-7509 , +-23579 , +-31445 , +-3035 , +28971 , +-11953 , +23451 , +6255 , +-2529 , +-7375 , +-5427 , +6681 , +-10471 , +-15575 , +8943 , +30661 , +-2079 , +-23181 , +20075 , +12593 , +-23007 , +-6653 , +10203 , +-7283 , +18337 , +10787 , +7811 , +-31141 , +17155 , +-24963 , +-32433 , +-8001 , +6899 , +-22077 , +-14275 , +20311 , +13289 , +-5189 , +-19353 , +-3433 , +15447 , +-7971 , +32363 , +-8797 , +-20633 , +617 , +-13463 , +23967 , +27185 , +-17665 , +-24447 , +-3699 , +-13453 , +1979 , +3265 , +2723 , +21967 , +7619 , +-15967 , +11557 , +19571 , +-5011 , +20993 , +-30277 , +16997 , +-11317 , +20373 , +-22711 , +5167 , +26567 , +-283 , +13639 , +17429 , +-26689 , +-9785 , +-24935 , +12503 , +4755 , +-26543 , +29931 , +7905 , +16205 , +-1965 , +19585 , +-29691 , +-24025 , +-1199 , +8343 , +-14921 , +1585 , +-11527 , +-10189 , +14783 , +17249 , +13337 , +899 , +31087 , +-1749 , +18461 , +27051 , +26473 , +5539 , +-2811 , +32555 , +-30777 , +-32507 , +-19501 , +23723 , +-5415 , +-14885 , +-21097 , +20057 , +-21919 , +3469 , +22225 , +-27715 , +28999 , +18813 , +16763 , +26649 , +1487 , +-8035 , +23927 , +-5323 , +20053 , +-18041 , +24455 , +707 , +-14205 , +-1771 , +-31029 , +-13265 , +-5365 , +19837 , +30901 , +-18697 , +27101 , +7649 , +27519 , +-8311 , +-11043 , +30315 , +22313 , +-15719 , +-30429 , +2285 , +25835 , +-7949 , +27813 , +6633 , +21807 , +27609 , +27777 , +-19915 , +5133 , +-28195 , +13733 , +-4849 , +13371 , +-31697 , +8207 , +-17735 , +-30579 , +-13183 , +-15229 , +-4217 , +-27673 , +2903 , +13513 , +-2175 , +1979 , +-18717 , +20053 , +1657 , +2297 , +-3493 , +8085 , +7327 , +29583 , +5583 , +-10349 , +-18533 , +-11171 , +-377 , +14401 , +-30677 , +20905 , +-16425 , +799 , +1069 , +14883 , +-13195 , +22659 , +11589 , +29265 , +12371 , +-32445 , +25583 , +30859 , +-3329 , +6905 , +-24809 , +14199 , +14955 , +7855 , +-8143 , +24311 , +17999 , +-17881 , +15313 , +31663 , +-9211 , +29569 , +20165 , +-31501 , +15061 , +-28803 , +30637 , +6463 , +12501 , +12853 , +-21237 , +8499 , +26691 , +12879 , +18409 , +4361 , +-31401 , +5817 , +-25881 , +-32623 , +11421 , +14045 , +-21039 , +20897 , +-30259 , +30045 , +-2621 , +7443 , +28453 , +-29365 , +25013 , +7741 , +-23231 , +27099 , +-27753 , +21731 , +-31889 , +-32603 , +-25109 , +5563 , +26759 , +-22955 , +7645 , +-16041 , +11341 , +21989 , +2519 , +-9819 , +8507 , +-7595 , +3229 , +11753 , +-16671 , +-29979 , +-15135 , +21803 , +-29509 , +-5683 , +-16031 , +12093 , +25999 , +-19091 , +-28295 , +-23517 , +-21705 , +19477 , +-15809 , +23069 , +-31993 , +555 , +8217 , +-26097 , +-19809 , +-21775 , +5331 , +6785 , +13633 , +21427 , +31295 , +-5867 , +8621 , +-22135 , +-18109 , +10881 , +-1927 , +387 , +-29321 , +-5883 , +-3353 , +31599 , +17723 , +-22173 , +27193 , +14083 , +-10673 , +-425 , +-4203 , +5021 , +-24849 , +-11631 , +11341 , +-3459 , +11107 , +-24277 , +8905 , +-3211 , +-10211 , +21665 , +-6193 , +-23511 , +-22449 , +1097 , +27745 , +-26175 , +10505 , +18507 , +28697 , +27941 , +-18239 , +23583 , +13309 , +-28237 , +2943 , +-14473 , +1495 , +-393 , +17255 , +-14905 , +15369 , +8677 , +30165 , +9263 , +-17933 , +6155 , +-2823 , +-12801 , +-27463 , +-25771 , +13801 , +-16475 , +-3929 , +-22599 , +-21703 , +-26577 , +-20731 , +18547 , +27677 , +-32455 , +1135 , +-30659 , +-15 , +-23191 , +-28751 , +-1013 , +9823 , +-4759 , +2325 , +-8131 , +-3089 , +15201 , +8775 , +16473 , +6947 , +-8987 , +-20827 , +8519 , +-17907 , +27513 , +-21477 , +9729 , +-31641 , +-11391 , +17529 , +-22831 , +-24019 , +-17991 , +24393 , +-19703 , +6831 , +-2251 , +-9173 , +-2759 , +9269 , +25553 , +3503 , +-3611 , +12297 , +-22743 , +-29529 , +-26429 , +2841 , +18455 , +-1027 , +-24465 , +-5367 , +-19801 , +-10985 , +-23393 , +-16433 , +27789 , +-11101 , +32487 , +-24119 , +12321 , +8181 , +-11807 , +-19367 , +9687 , +-17699 , +16119 , +21747 , +-3019 , +26109 , +16009 , +-4417 , +-8631 , +32171 , +4785 , +19119 , +-22361 , +-3783 , +-13189 , +-19437 , +31961 , +-5413 , +-9327 , +-13899 , +-31903 , +16375 , +8323 , +21357 , +27687 , +16895 , +-1673 , +-3009 , +-25225 , +1995 , +16731 , +4333 , +16761 , +-14479 , +-18005 , +-15597 , +-5593 , +22679 , +-10595 , +12477 , +961 , +30547 , +26081 , +8319 , +-12847 , +-8321 , +2001 , +8719 , +4759 , +-10095 , +-3277 , +9047 , +21765 , +18931 , +-1179 , +-13801 , +-21191 , +-4129 , +20769 , +27127 , +2931 , +-14165 , +-2643 , +-4325 , +6543 , +21173 , +22677 , +-27323 , +29433 , +-19803 , +6119 , +-15519 , +27433 , +23127 , +23267 , +-7253 , +6811 , +18471 , +-16583 , +-28613 , +-5569 , +30415 , +20675 , +-5087 , +21889 , +-27201 , +-31821 , +-32511 , +6835 , +-24079 , +-22187 , +31011 , +-28155 , +30535 , +-10425 , +-29165 , +25351 , +-3495 , +-18137 , +-31819 , +20637 , +-17703 , +17621 , +-30757 , +21361 , +20071 , +-14041 , +20067 , +-17679 , +25569 , +20259 , +16841 , +-29499 , +16197 , +-14927 , +-24509 , +-9527 , +3593 , +-4131 , +-8873 , +18307 , +-7191 , +-29307 , +8177 , +28955 , +28747 , +-18789 , +13571 , +31445 , +1037 , +-7985 , +-12653 , +27907 , +-27 , +-30761 , +26457 , +-23673 , +17201 , +-4065 , +-23851 , +709 , +-19621 , +-1027 , +-32281 , +11029 , +29603 , +-29841 , +17387 , +25289 , +-6783 , +24149 , +19529 , +28317 , +2421 , +-3807 , +-7021 , +4265 , +22633 , +19477 , +13085 , +26085 , +-21119 , +15613 , +15889 , +-9701 , +22645 , +-3233 , +21261 , +-5537 , +-3991 , +30521 , +-21709 , +28165 , +-183 , +-3529 , +-23609 , +-25055 , +7579 , +17259 , +25419 , +-27787 , +-26921 , +-10873 , +17161 , +29421 , +11845 , +12181 , +-10951 , +155 , +7251 , +14379 , +-8305 , +-11991 , +-9115 , +-23773 , +8799 , +-11821 , +-7365 , +-32293 , +17445 , +24293 , +-10817 , +28133 , +-18005 , +-24411 , +22617 , +17985 , +665 , +26329 , +3801 , +-2283 , +4753 , +15033 , +-6981 , +17385 , +16069 , +-8347 , +13833 , +3157 , +-30703 , +-1821 , +-3915 , +839 , +-26229 , +4495 , +18027 , +20655 , +21419 , +-18913 , +1769 , +5563 , +15315 , +-8181 , +15071 , +19349 , +-22417 , +26257 , +5947 , +-2933 , +395 , +-20947 , +-7921 , +6111 , +-4625 , +20101 , +-9763 , +32742 , +-15185 , +-6411 , +-13199 , +-19761 , +6987 , +-9873 , +21059 , +7645 , +-14271 , +9227 , +26943 , +-5359 , +12839 , +4331 , +29229 , +31089 , +17221 , +-2879 , +12155 , +-4171 , +-9811 , +-19525 , +-9055 , +-7801 , +3023 , +17675 , +-2577 , +32567 , +6549 , +-4915 , +-14099 , +18415 , +25079 , +25739 , +25903 , +-18827 , +13593 , +-21965 , +1451 , +-8101 , +-9505 , +-21111 , +-30059 , +32699 , +-23039 , +-27607 , +7093 , +24427 , +27565 , +-13323 , +-29885 , +-24133 , +14231 , +-23533 , +-28361 , +-9819 , +-27501 , +-23451 , +30501 , +28301 , +16817 , +23421 , +19611 , +17013 , +-21557 , +-9445 , +15343 , +4789 , +939 , +-25829 , +6043 , +-29903 , +18581 , +-1283 , +-18407 , +-31717 , +8043 , +6601 , +16949 , +25113 , +-12743 , +15513 , +-4633 , +4369 , +13403 , +31625 , +26031 , +-28335 , +5897 , +-4821 , +22117 , +-28847 , +-25997 , +2185 , +18329 , +-537 , +16221 , +30097 , +21603 , +11007 , +15663 , +1051 , +-9017 , +18129 , +-28523 , +339 , +-14465 , +-10847 , +-26989 , +-23621 , +27739 , +1005 , +-29669 , +-14945 , +-16615 , +21803 , +-13781 , +-23027 , +-11591 , +-23297 , +5729 , +-6067 , +19805 , +-3339 , +-8177 , +-30243 , +-7021 , +-3913 , +-15909 , +1759 , +31293 , +-13629 , +8151 , +25887 , +-3619 , +9129 , +14863 , +23931 , +22131 , +-17987 , +-29781 , +23533 , +26839 , +-20651 , +-12669 , +-29197 , +11909 , +-4745 , +31543 , +-18547 , +-26361 , +-26339 , +7625 , +1723 , +-8773 , +4839 , +22191 , +-25237 , +-27077 , +31059 , +-8073 , +2549 , +16681 , +9587 , +29137 , +26135 , +15245 , +6699 , +-11215 , +21609 , +-13655 , +-8735 , +1763 , +-27567 , +20057 , +-18751 , +-14689 , +25733 , +13279 , +-16027 , +20909 , +27643 , +-16059 , +-9699 , +-16271 , +24931 , +20787 , +-12135 , +-13687 , +10529 , +5955 , +-8661 , +20577 , +-24125 , +1243 , +-10627 , +-32433 , +-10505 , +-6521 , +2755 , +-2515 , +-11511 , +20943 , +22395 , +-26519 , +-14633 , +31633 , +21665 , +-21087 , +-16311 , +-28973 , +8295 , +-8257 , +-22713 , +-25561 , +-17299 , +-26229 , +-18119 , +-18061 , +30073 , +-28727 , +15091 , +27223 , +19889 , +-12601 , +-26313 , +-5889 , +-7855 , +9345 , +-20565 , +26491 , +-16923 , +16179 , +28239 , +-7787 , +-23555 , +22637 , +-27281 , +-26833 , +-21657 , +-15177 , +-16339 , +-14571 , +-15893 , +16283 , +30049 , +-15783 , +31869 , +19527 , +30505 , +-4053 , +-19721 , +-32097 , +2253 , +-9685 , +-8621 , +8409 , +25413 , +-9911 , +-20127 , +-18027 , +4135 , +31513 , +-7167 , +22127 , +25383 , +14251 , +-22315 , +-6365 , +-13815 , +-28701 , +-14975 , +21779 , +11039 , +11347 , +-15007 , +4979 , +2617 , +5263 , +16061 , +-31789 , +-21467 , +-26869 , +-23933 , +1853 , +-3935 , +-1685 , +-29055 , +5065 , +6873 , +-30361 , +6683 , +9917 , +16471 , +9745 , +5507 , +-5353 , +-27005 , +-9791 , +-19597 , +27829 , +22165 , +-25507 , +-27295 , +-20509 , +28689 , +-10693 , +-19909 , +-31369 , +-15939 , +-17545 , +3999 , +-3231 , +4381 , +6083 , +-14961 , +2515 , +30815 , +-23861 , +17581 , +31943 , +-32027 , +29959 , +22255 , +-9689 , +-20435 , +-19181 , +-11553 , +-19369 , +-27311 , +5511 , +31047 , +-26279 , +21761 , +15181 , +-2699 , +11865 , +-23053 , +-23423 , +30695 , +18387 , +8161 , +10175 , +-7279 , +22047 , +1791 , +-23549 , +1417 , +-369 , +19959 , +-1799 , +-12475 , +14593 , +1625 , +-8227 , +2895 , +-13819 , +-2153 , +-17199 , +-31613 , +29025 , +-27515 , +173 , +6083 , +-23237 , +1855 , +13155 , +-22483 , +12709 , +-29773 , +16083 , +28117 , +-27459 , +-12143 , +4635 , +-26875 , +28479 , +-26945 , +13691 , +-19487 , +-7775 , +18263 , +26277 , +-6983 , +11689 , +-18397 , +-10857 , +17065 , +29829 , +-10615 , +6647 , +31457 , +-5789 , +28939 , +30947 , +5205 , +20619 , +-10433 , +-27823 , +22521 , +8949 , +-30651 , +5345 , +21367 , +11873 , +-22593 , +31545 , +-4505 , +2545 , +29001 , +-29221 , +-30199 , +14141 , +25203 , +-24961 , +9083 , +18415 , +21303 , +10725 , +28781 , +-8231 , +13551 , +-3785 , +-4505 , +-5233 , +-20523 , +9177 , +23661 , +-7301 , +22257 , +-20029 , +-26805 , +29563 , +-21867 , +24155 , +20539 , +24305 , +-24231 , +-21559 , +-27093 , +-1693 , +-4209 , +14035 , +-22161 , +2957 , +-15049 , +-25801 , +4599 , +31999 , +14977 , +30839 , +28685 , +-26065 , +8891 , +-20669 , +-123 , +20243 , +32211 , +28481 , +17789 , +11835 , +16451 , +11629 , +-8047 , +-25499 , +-22123 , +6897 , +-3183 , +-1893 , +-7853 , +13435 , +8897 , +6341 , +4737 , +-32235 , +-25725 , +-3385 , +-17003 , +-24707 , +7843 , +-13809 , +30963 , +9469 , +-31497 , +-17991 , +-10275 , +2247 , +-18773 , +-3295 , +-20491 , +-28473 , +-29453 , +-30471 , +29993 , +-4869 , +-27077 , +7909 , +-7115 , +4691 , +13547 , +21905 , +-19559 , +-4609 , +4245 , +19275 , +-31987 , +-30387 , +20919 , +2327 , +-16003 , +13825 , +-24599 , +13387 , +-16003 , +23335 , +23195 , +-9049 , +-19387 , +-1417 , +1099 , +-16665 , +-15575 , +-31203 , +22591 , +-11289 , +-113 , +7969 , +699 , +-31703 , +24933 , +-11215 , +29623 , +22529 , +-29665 , +-1787 , +-15333 , +31775 , +-28121 , +11823 , +9593 , +-3411 , +28381 , +12659 , +-11203 , +-14107 , +28429 , +3751 , +1129 , +10535 , +16355 , +-14079 , +-16173 , +-24169 , +-9117 , +5365 , +13523 , +30515 , +4455 , +14989 , +22655 , +23907 , +-12267 , +-18373 , +30565 , +27165 , +1743 , +-16835 , +-30271 , +-24969 , +14523 , +6759 , +-10183 , +-9285 , +-29783 , +-21373 , +-7667 , +-25333 , +-31593 , +-1239 , +-557 , +19819 , +10917 , +275 , +-21323 , +-28063 , +-14193 , +-13573 , +6173 , +25359 , +1185 , +-531 , +-19977 , +17345 , +-30925 , +-8669 , +28517 , +32277 , +-6241 , +-4519 , +-27143 , +-21121 , +6075 , +-16471 , +-27799 , +30833 , +1485 , +2529 , +-10295 , +-12817 , +-21241 , +-23457 , +10823 , +32673 , +19581 , +30561 , +28765 , +-28557 , +-865 , +-541 , +24461 , +4009 , +23341 , +28661 , +4499 , +-10123 , +-31311 , +11669 , +-3287 , +3607 , +6781 , +-32251 , +1329 , +-21401 , +30743 , +22433 , +-6025 , +1277 , +-3269 , +-3009 , +-21533 , +-32577 , +15183 , +22011 , +-10953 , +32251 , +-23205 , +18585 , +-25537 , +-23809 , +-27261 , +-13477 , +-12141 , +32051 , +-16647 , +-8365 , +25029 , +-15185 , +29311 , +22085 , +543 , +7251 , +-19625 , +-17933 , +-9255 , +-22943 , +19135 , +-7165 , +-12077 , +17809 , +-28189 , +24137 , +15561 , +-7507 , +10847 , +9129 , +-19951 , +-29017 , +23855 , +-9877 , +-22325 , +-9933 , +22569 , +6417 , +-26463 , +13277 , +503 , +-7497 , +29947 , +-18019 , +-25459 , +-12321 , +951 , +13051 , +-4575 , +7893 , +1635 , +-20837 , +10401 , +11901 , +-21011 , +-31141 , +18357 , +-32079 , +20715 , +10471 , +7463 , +-5859 , +-9147 , +32727 , +-15383 , +-10617 , +-2449 , +19009 , +-20091 , +-27463 , +19749 , +17365 , +7703 , +22737 , +1447 , +28785 , +-1333 , +-9705 , +-14493 , +25663 , +11975 , +-32425 , +22843 , +-8119 , +21169 , +-14145 , +18743 , +-25715 , +-23905 , +-7127 , +-26949 , +-28513 , +24213 , +18947 , +-10429 , +-22597 , +20855 , +13469 , +-12903 , +5463 , +-18813 , +-19455 , +-5231 , +17739 , +13641 , +26705 , +-18889 , +-21927 , +11303 , +31897 , +-31599 , +19021 , +313 , +-1491 , +-28457 , +24213 , +-20005 , +3191 , +-11233 , +-7851 , +22677 , +19807 , +-23385 , +24325 , +-7779 , +-19953 , +-29059 , +-7039 , +-23093 , +12381 , +24255 , +24999 , +9237 , +-19303 , +-9901 , +22641 , +-28291 , +32744 , +4379 , +12423 , +30611 , +-30951 , +-9549 , +1879 , +6507 , +-5629 , +20897 , +21685 , +-10479 , +7001 , +-6121 , +15333 , +18307 , +-12031 , +-1761 , +-7865 , +16683 , +21743 , +21857 , +-25511 , +-30507 , +20087 , +-15797 , +24161 , +24363 , +-25551 , +-7205 , +9591 , +-23389 , +22083 , +-30525 , +-11221 , +-13313 , +-28347 , +-11979 , +17805 , +21323 , +-1651 , +10253 , +-2605 , +-1215 , +-8429 , +-31093 , +5997 , +30043 , +-13885 , +-1387 , +27799 , +-16335 , +11857 , +-6305 , +-17033 , +-5499 , +23451 , +-1871 , +17075 , +29877 , +14457 , +16537 , +-9075 , +2217 , +-5611 , +30625 , +28273 , +-16293 , +-1333 , +-10357 , +14109 , +-19769 , +6521 , +-30583 , +32037 , +-161 , +2389 , +6383 , +26651 , +4107 , +-9645 , +-2185 , +24099 , +18847 , +489 , +26601 , +-16891 , +-7477 , +27771 , +-5535 , +19919 , +6561 , +7969 , +-29441 , +13793 , +32641 , +-32241 , +8227 , +-8049 , +-27753 , +-5281 , +-15067 , +-27081 , +25553 , +-32137 , +-12411 , +11735 , +27735 , +5073 , +28851 , +-21983 , +28039 , +-4767 , +9781 , +6941 , +28771 , +23397 , +25197 , +-25543 , +-20073 , +-8765 , +26567 , +-14621 , +-21791 , +-21031 , +-12677 , +29091 , +-3301 , +-21283 , +-21319 , +5041 , +11425 , +21167 , +-9873 , +-23283 , +-17831 , +-19147 , +16755 , +21273 , +29469 , +16435 , +-14523 , +-7763 , +3003 , +13723 , +-23231 , +4275 , +28529 , +-29067 , +-13733 , +-8643 , +-16681 , +21541 , +10583 , +-735 , +11621 , +2641 , +29309 , +22533 , +30055 , +16691 , +12245 , +-1783 , +6765 , +-6037 , +-17443 , +11727 , +12879 , +31335 , +2753 , +16413 , +-4963 , +-26579 , +-16875 , +-25871 , +-28519 , +11701 , +31495 , +-19433 , +10677 , +-18743 , +-1245 , +-28089 , +-25987 , +-17325 , +-12417 , +18359 , +19997 , +8763 , +20087 , +14647 , +16467 , +23997 , +-23579 , +-30267 , +-27673 , +11331 , +31709 , +-32085 , +28577 , +-7493 , +16351 , +20499 , +22983 , +-4753 , +24211 , +-5605 , +-13807 , +-26531 , +-27139 , +-32135 , +10785 , +-18415 , +-18377 , +20099 , +-903 , +19193 , +-7503 , +1495 , +25081 , +-21693 , +-24617 , +-4761 , +-18989 , +26927 , +-5287 , +-14569 , +30721 , +26087 , +-28447 , +32211 , +15939 , +18145 , +-8897 , +-6615 , +-7281 , +-9813 , +6703 , +27485 , +-20973 , +-32701 , +-13171 , +263 , +-23643 , +15869 , +11527 , +12579 , +-15173 , +31947 , +-11431 , +-24913 , +26089 , +8987 , +3085 , +-11067 , +24531 , +4661 , +-12125 , +-17875 , +19883 , +-23287 , +-9641 , +-32395 , +-28127 , +18315 , +-14513 , +28049 , +23267 , +-16755 , +-13733 , +17127 , +23183 , +14361 , +-8917 , +-17167 , +28975 , +-17347 , +-4865 , +-8107 , +-1231 , +5751 , +-1555 , +-32399 , +-293 , +-12427 , +-24437 , +-10363 , +-4027 , +20355 , +1585 , +29753 , +17363 , +-16043 , +-24657 , +30659 , +-30931 , +-12955 , +-13697 , +22905 , +14513 , +-14903 , +-20345 , +7399 , +5491 , +23179 , +28229 , +19305 , +5555 , +28291 , +-3181 , +-30135 , +-12337 , +9387 , +-26921 , +9549 , +31169 , +-16899 , +-11587 , +26067 , +16665 , +24519 , +9843 , +3691 , +12653 , +23165 , +-28583 , +-11539 , +24917 , +2337 , +-25791 , +9491 , +-25109 , +-7925 , +30239 , +11661 , +19635 , +-13749 , +3659 , +18847 , +-17379 , +22651 , +-23503 , +-6861 , +-25983 , +-997 , +-11637 , +2417 , +-13429 , +-15257 , +-32744 , +30687 , +21565 , +-13905 , +-19493 , +-22031 , +-27291 , +-10189 , +-15417 , +-29407 , +-29555 , +29551 , +-10749 , +21389 , +21377 , +-13817 , +11415 , +12557 , +-27077 , +-19959 , +13231 , +23747 , +14175 , +17881 , +-13751 , +12093 , +-9415 , +14709 , +-17033 , +-19185 , +-28375 , +-32671 , +-4599 , +-29221 , +21413 , +23535 , +6359 , +28667 , +-26963 , +27171 , +-18073 , +10383 , +-25407 , +-13055 , +-203 , +28697 , +-13725 , +619 , +19805 , +27537 , +-20485 , +-31625 , +15583 , +12801 , +617 , +-13751 , +-26291 , +11933 , +14823 , +-16023 , +20491 , +-18603 , +3979 , +22425 , +-13823 , +-20491 , +-28355 , +11573 , +-22569 , +-28229 , +1077 , +2047 , +22699 , +-20629 , +19941 , +7811 , +-31929 , +3559 , +7039 , +-11291 , +-17949 , +-22193 , +32744 , +-959 , +28747 , +32399 , +16427 , +16765 , +-21333 , +12671 , +-31111 , +-16217 , +27321 , +-22667 , +13215 , +30659 , +10607 , +28257 , +-30985 , +-25551 , +-25781 , +18529 , +21739 , +29049 , +-3841 , +-19489 , +-31771 , +-18263 , +-18773 , +-14299 , +1991 , +20521 , +-17513 , +15985 , +5101 , +7195 , +-923 , +-103 , +-17517 , +-12505 , +2005 , +3603 , +-18205 , +-21537 , +-10769 , +9373 , +-28073 , +-10611 , +-30267 , +-7863 , +-10557 , +20371 , +5541 , +-10981 , +-22589 , +11839 , +14807 , +20513 , +19123 , +13343 , +-10801 , +16901 , +-2003 , +20709 , +1001 , +1837 , +-24069 , +11953 , +-2149 , +31311 , +-6251 , +24309 , +5687 , +8843 , +-3823 , +16321 , +16925 , +-10753 , +26787 , +12711 , +-12177 , +-22303 , +19089 , +13835 , +8531 , +-32485 , +-15447 , +-29185 , +21155 , +9821 , +-10691 , +29081 , +1317 , +9909 , +-613 , +30665 , +-21431 , +26543 , +-30717 , +-14665 , +24669 , +-17435 , +-8419 , +-23403 , +-21691 , +21783 , +30453 , +-32515 , +18357 , +27339 , +-25741 , +3777 , +19171 , +-4775 , +-11185 , +-31159 , +-20281 , +-25199 , +6031 , +-22419 , +-15665 , +24771 , +-32137 , +-26171 , +20763 , +10599 , +-12025 , +11909 , +13865 , +19495 , +19445 , +-16677 , +7453 , +-26235 , +25885 , +7099 , +623 , +5093 , +-17793 , +-17341 , +26405 , +-26065 , +-18505 , +-17525 , +-20853 , +24289 , +-29199 , +-16641 , +-24977 , +-31829 , +-17819 , +23863 , +31183 , +-20091 , +-11443 , +7505 , +-20959 , +1353 , +-11425 , +-22839 , +-29961 , +10441 , +-25663 , +14795 , +-951 , +-3995 , +-7035 , +2069 , +-16607 , +21799 , +21407 , +-31163 , +2269 , +9051 , +-3491 , +19893 , +6363 , +13733 , +-18077 , +-22823 , +-21317 , +-27495 , +27419 , +21517 , +-12525 , +21201 , +29873 , +-19215 , +-1881 , +32141 , +3473 , +-9659 , +-989 , +-1601 , +19797 , +-24005 , +-19375 , +-23121 , +28739 , +30035 , +-4913 , +-26869 , +579 , +-17489 , +32077 , +-12925 , +10329 , +-23825 , +3905 , +12763 , +-16233 , +19593 , +-31205 , +14733 , +-28513 , +-865 , +-32249 , +1755 , +14995 , +24915 , +-2785 , +23905 , +12431 , +-30039 , +17183 , +17215 , +24229 , +-21799 , +-7257 , +-22887 , +-15541 , +14117 , +-279 , +-8253 , +-20897 , +-32461 , +-793 , +26577 , +-8553 , +24811 , +32557 , +-25681 , +13693 , +1729 , +-17151 , +-7241 , +14819 , +-29027 , +-17889 , +6093 , +8419 , +27431 , +20471 , +30711 , +-27319 , +16807 , +-32423 , +4467 , +-2659 , +20053 , +4279 , +-6065 , +16521 , +-5829 , +-12069 , +-17025 , +26591 , +17283 , +-22503 , +-13957 , +16905 , +-2731 , +-16879 , +17235 , +-11773 , +29741 , +-13349 , +3141 , +7639 , +2487 , +1737 , +22491 , +19343 , +25373 , +-25185 , +-22401 , +15535 , +20715 , +16449 , +-1903 , +24623 , +-12449 , +-22025 , +26625 , +-3345 , +-4283 , +-23015 , +18029 , +26293 , +-18613 , +-30891 , +-11859 , +10141 , +-27169 , +-30373 , +-32523 , +30749 , +31617 , +5401 , +13417 , +-25749 , +13725 , +24439 , +8501 , +1675 , +8677 , +23177 , +-11737 , +-12367 , +-11737 , +29001 , +5317 , +5195 , +-18265 , +1489 , +10977 , +-29331 , +29939 , +10769 , +6333 , +2767 , +-9921 , +-29943 , +26519 , +3143 , +16443 , +1659 , +13509 , +12727 , +19305 , +-7379 , +-6831 , +-18033 , +-24065 , +9111 , +22027 , +-14909 , +-14289 , +-5341 , +-8159 , +-24771 , +-22771 , +28127 , +2623 , +-20513 , +-8995 , +25273 , +15903 , +27377 , +28149 , +28725 , +23201 , +-9183 , +-4595 , +-29787 , +31339 , +5363 , +-17899 , +-15647 , +-14601 , +12483 , +23193 , +26757 , +-20433 , +10035 , +-22899 , +6809 , +24715 , +9513 , +-16725 , +-25635 , +-14949 , +-23481 , +31049 , +-2189 , +1329 , +-1825 , +22195 , +-6371 , +-18711 , +-29073 , +-27139 , +-3085 , +-17847 , +-30057 , +-32157 , +18841 , +345 , +3731 , +-28383 , +-19457 , +10167 , +-12495 , +26559 , +-16495 , +11827 , +15173 , +25337 , +29677 , +13029 , +-5971 , +-18933 , +-24279 , +32199 , +32699 , +-17777 , +14199 , +-17973 , +-8905 , +-30507 , +-24211 , +-19855 , +-23853 , +28855 , +-26437 , +28131 , +-4571 , +27381 , +27991 , +-1137 , +28183 , +6923 , +14149 , +-12491 , +-28945 , +31115 , +-5439 , +139 , +-2889 , +-16657 , +-14587 , +18251 , +-963 , +-22789 , +6003 , +3029 , +31371 , +-23411 , +-16553 , +25659 , +29401 , +7669 , +-30693 , +21989 , +-1265 , +18901 , +-22019 , +13217 , +1719 , +-15247 , +-30899 , +28735 , +20591 , +30087 , +4639 , +-16989 , +6641 , +-8531 , +-11129 , +-12185 , +-1415 , +27169 , +4943 , +-24595 , +29645 , +-11731 , +817 , +31475 , +-31323 , +14577 , +-30583 , +-14157 , +-2123 , +2245 , +31125 , +-12681 , +-28141 , +13577 , +-9429 , +20915 , +-963 , +-3193 , +4075 , +28311 , +31371 , +-31165 , +29185 , +31535 , +16931 , +11731 , +20305 , +20217 , +-25733 , +-9151 , +-16323 , +-14599 , +-29879 , +-16301 , +20685 , +-8623 , +14845 , +16751 , +-2953 , +13153 , +-11845 , +-31759 , +15435 , +20821 , +2767 , +3583 , +18355 , +-27065 , +7851 , +-23321 , +26531 , +3529 , +22873 , +-1299 , +-5031 , +6157 , +375 , +17841 , +5521 , +13681 , +-12627 , +21755 , +-25285 , +-12639 , +-22877 , +16921 , +-11077 , +20769 , +-10113 , +20405 , +-13163 , +30839 , +-28967 , +4653 , +32431 , +7089 , +-20431 , +30827 , +29445 , +22413 , +-6673 , +-12991 , +-10525 , +27907 , +461 , +18745 , +32409 , +11367 , +31197 , +19701 , +-13899 , +17661 , +13053 , +-9213 , +-7747 , +20755 , +20939 , +28723 , +19305 , +-2413 , +18973 , +-17037 , +16977 , +-3037 , +-6911 , +32293 , +-10449 , +29371 , +29997 , +-8197 , +18579 , +29623 , +-3593 , +-22203 , +-29157 , +-19593 , +12499 , +-20779 , +-29139 , +-10127 , +-2747 , +-19887 , +-2515 , +18127 , +3933 , +16647 , +11571 , +28801 , +16559 , +-21683 , +22857 , +-1579 , +8135 , +-21415 , +-4325 , +-30057 , +-19931 , +-9587 , +-15301 , +-23647 , +-2897 , +30813 , +7115 , +20725 , +2741 , +-16989 , +-23107 , +4181 , +19291 , +12657 , +-6007 , +-15269 , +-6755 , +11377 , +3433 , +3095 , +21183 , +7093 , +-30967 , +-10471 , +20291 , +-25573 , +-30009 , +-29159 , +-28051 , +1559 , +-11163 , +-22525 , +-977 , +-32239 , +-21435 , +917 , +29097 , +15685 , +-22499 , +-8843 , +8217 , +-10485 , +7735 , +-17717 , +24153 , +-24899 , +-15587 , +8277 , +-6951 , +-17913 , +27099 , +28163 , +-27635 , +-13375 , +24243 , +-18675 , +-32397 , +13131 , +21591 , +-4467 , +-32001 , +31837 , +23453 , +16533 , +-3819 , +5989 , +-8773 , +-4155 , +-10485 , +-3487 , +4347 , +-28823 , +18961 , +2607 , +-8199 , +-3575 , +7867 , +-29591 , +-17577 , +-23413 , +-19227 , +-24125 , +19953 , +19907 , +4669 , +30937 , +-29791 , +-13683 , +817 , +-22131 , +4713 , +24163 , +31339 , +-30501 , +22069 , +-12161 , +-6459 , +-31433 , +-28915 , +-12957 , +-18493 , +9057 , +-7725 , +25855 , +-14191 , +-19525 , +-17547 , +-703 , +-5777 , +22565 , +-10585 , +-28365 , +16307 , +29271 , +-7141 , +-27511 , +-19395 , +4781 , +19775 , +21447 , +10349 , +32657 , +2409 , +10443 , +-22109 , +27969 , +-615 , +23535 , +23341 , +-457 , +-8531 , +2461 , +20165 , +9205 , +3605 , +-7063 , +901 , +30817 , +26903 , +11171 , +-15513 , +10147 , +-32131 , +-20871 , +-26829 , +623 , +16075 , +13189 , +2299 , +20717 , +19201 , +7403 , +27927 , +32261 , +26059 , +-24333 , +-5737 , +13119 , +-3267 , +28439 , +-3009 , +-747 , +-11513 , +6565 , +32509 , +4045 , +-3789 , +7125 , +-29985 , +17619 , +-30379 , +-11169 , +22931 , +-6001 , +-27573 , +19599 , +-2733 , +28863 , +22639 , +9189 , +18281 , +-19639 , +-27563 , +30765 , +29983 , +-19043 , +15359 , +8715 , +-17609 , +-21369 , +16529 , +7717 , +32748 , +17537 , +23185 , +31403 , +-11427 , +-13671 , +20123 , +-24203 , +5775 , +19901 , +-23399 , +22177 , +227 , +20635 , +18813 , +17315 , +-17401 , +9203 , +4983 , +26331 , +20087 , +-32399 , +-24403 , +16311 , +3187 , +32521 , +-30607 , +3911 , +18291 , +29381 , +22273 , +1355 , +-3039 , +-8405 , +19381 , +-20003 , +32469 , +9 , +20925 , +-27783 , +-31099 , +4051 , +11095 , +6559 , +-18875 , +-8839 , +18313 , +-3099 , +30011 , +-13633 , +14933 , +1429 , +-23275 , +-13547 , +20343 , +-10817 , +9989 , +31477 , +12181 , +-11311 , +24377 , +-6229 , +4097 , +18617 , +28369 , +8131 , +25831 , +19563 , +23637 , +9165 , +-29175 , +-26609 , +-7503 , +20419 , +30205 , +-29563 , +7853 , +-11051 , +-25639 , +17801 , +-11551 , +23503 , +32631 , +4421 , +31281 , +26599 , +-6109 , +9329 , +-7995 , +-28141 , +-549 , +-7457 , +31611 , +13547 , +-21249 , +-27491 , +13801 , +-24327 , +19605 , +-8311 , +-4405 , +29079 , +-271 , +-8855 , +23297 , +6715 , +-15109 , +9861 , +-30969 , +17507 , +-17439 , +-22341 , +-20759 , +5591 , +32077 , +-23781 , +-23361 , +-2157 , +6691 , +-25091 , +32163 , +-2797 , +-22609 , +-18531 , +-17109 , +19507 , +-10387 , +7463 , +-18597 , +17791 , +-28369 , +2145 , +24873 , +-4845 , +2019 , +6581 , +18279 , +-15377 , +16579 , +26317 , +-7099 , +463 , +-31473 , +5547 , +2881 , +32645 , +-18871 , +-9147 , +-23637 , +-7733 , +-797 , +15509 , +27021 , +7333 , +-13947 , +-10949 , +-4813 , +-6351 , +-24391 , +-24951 , +-30441 , +14337 , +-22233 , +27689 , +-31137 , +25075 , +29777 , +-29915 , +10195 , +-5747 , +-1597 , +-11123 , +-11433 , +-21811 , +15573 , +3211 , +4573 , +26505 , +-27431 , +-6669 , +-25113 , +22081 , +4055 , +-32151 , +14455 , +-13957 , +-6197 , +-14613 , +31881 , +-30823 , +-32173 , +23795 , +26893 , +-5327 , +-3349 , +-18419 , +-9891 , +25577 , +30631 , +-2073 , +-23499 , +28613 , +-6035 , +-263 , +-26325 , +-23285 , +-28511 , +-27255 , +5289 , +-7021 , +27501 , +-3753 , +25187 , +19617 , +14959 , +31143 , +-22963 , +1089 , +28403 , +8155 , +-31717 , +30489 , +23979 , +9365 , +15661 , +6593 , +-19221 , +-24259 , +32019 , +20129 , +-21157 , +-20947 , +-29571 , +-31929 , +-4819 , +32059 , +8885 , +7737 , +-27165 , +16601 , +-29289 , +21843 , +29813 , +14241 , +26637 , +-31585 , +-13287 , +-19327 , +-26879 , +7595 , +-19605 , +31551 , +-15145 , +-14497 , +31795 , +18843 , +4967 , +-14755 , +7577 , +-6933 , +15473 , +17871 , +6359 , +-31705 , +-10087 , +-26429 , +-12169 , +-4471 , +1249 , +3077 , +-13813 , +9893 , +7831 , +24697 , +-11677 , +-1535 , +-12839 , +-31257 , +31813 , +19749 , +5763 , +-20891 , +-3677 , +31809 , +-22609 , +21023 , +-28839 , +-22469 , +8617 , +15289 , +17251 , +18503 , +-30107 , +13601 , +9615 , +-10237 , +-22405 , +27881 , +17083 , +-1521 , +31905 , +11299 , +4747 , +-6367 , +-28263 , +-2891 , +-28763 , +-32349 , +23219 , +-24531 , +27235 , +-6715 , +22723 , +-26845 , +19979 , +-12777 , +15763 , +-18169 , +-20337 , +-23391 , +-14875 , +3203 , +9401 , +-26497 , +-32287 , +-12219 , +-22799 , +-28687 , +17429 , +1129 , +-9115 , +20221 , +28389 , +1089 , +-17199 , +-21891 , +-10101 , +18615 , +-24915 , +8125 , +32141 , +-5345 , +7653 , +-22385 , +-18001 , +147 , +-10987 , +9195 , +16243 , +26055 , +24899 , +11005 , +-31221 , +4969 , +-22515 , +-21821 , +-6699 , +-27921 , +-10131 , +6693 , +6993 , +-21517 , +7657 , +-23419 , +26779 , +-7665 , +32335 , +8423 , +3425 , +-9425 , +-9751 , +11643 , +19799 , +18029 , +-31175 , +18357 , +-17095 , +23395 , +31535 , +14579 , +3645 , +-30193 , +-29979 , +-20605 , +4107 , +29471 , +-25651 , +23623 , +8497 , +-16179 , +23925 , +27849 , +-14811 , +-1991 , +28597 , +-17961 , +-24905 , +-9411 , +29809 , +-32111 , +29191 , +29391 , +969 , +3085 , +-30463 , +22983 , +-1329 , +-665 , +3923 , +24647 , +7371 , +-12197 , +-19739 , +8081 , +32485 , +11869 , +14803 , +-27053 , +-18839 , +-28105 , +18147 , +25999 , +16759 , +1555 , +1151 , +-14873 , +8763 , +22049 , +-4571 , +-12931 , +9387 , +-28757 , +28783 , +7747 , +-14659 , +9381 , +-26759 , +-27429 , +15127 , +-29741 , +-31769 , +4077 , +32341 , +-19117 , +-8617 , +-6151 , +-2379 , +11199 , +343 , +12213 , +-27053 , +14787 , +4575 , +21733 , +-2077 , +-5073 , +-16819 , +14767 , +28137 , +18581 , +-9257 , +24187 , +31853 , +-28573 , +-25975 , +13373 , +-19145 , +-6029 , +-30799 , +12125 , +28291 , +15659 , +5867 , +-19707 , +19521 , +-17651 , +-5755 , +27897 , +5059 , +-19495 , +-29565 , +14837 , +-15881 , +18461 , +-6895 , +10879 , +23593 , +-21171 , +897 , +-16317 , +29487 , +26721 , +-27459 , +-1047 , +-11997 , +21737 , +-21949 , +21359 , +18853 , +-12123 , +4251 , +10493 , +9347 , +-7267 , +-5043 , +-9665 , +6911 , +-17223 , +-10913 , +65 , +24447 , +23259 , +10569 , +-2109 , +-22581 , +-17805 , +-13461 , +18957 , +-20037 , +24479 , +3083 , +3663 , +14973 , +-27465 , +-4665 , +-9353 , +-8127 , +13681 , +-32367 , +25221 , +-6537 , +24173 , +-28381 , +18791 , +21635 , +-9893 , +20475 , +24139 , +26363 , +-25211 , +19157 , +-17533 , +-13477 , +15603 , +19865 , +-3121 , +-25031 , +-27145 , +30685 , +-8385 , +-23545 , +-24235 , +14299 , +8327 , +-19387 , +-19257 , +25573 , +-1321 , +-12489 , +4645 , +10847 , +-28621 , +-10721 , +6905 , +4153 , +8269 , +24055 , +147 , +-18969 , +24537 , +-27479 , +18595 , +-25899 , +-32661 , +-20285 , +-431 , +-26783 , +201 , +-7243 , +-6183 , +17751 , +-8763 , +18047 , +-26467 , +3807 , +15257 , +-18187 , +-18497 , +7173 , +8117 , +11121 , +21307 , +-10593 , +21287 , +19211 , +-26757 , +15569 , +1375 , +2125 , +-15497 , +-17919 , +18329 , +-3977 , +-20159 , +-16815 , +-1875 , +-11987 , +-13529 , +-13163 , +14689 , +-24915 , +-15033 , +14023 , +335 , +5265 , +-3161 , +16651 , +-5069 , +2303 , +-27441 , +-7399 , +-10299 , +-5533 , +-5923 , +-8127 , +27151 , +24491 , +27939 , +28119 , +6221 , +-32009 , +5173 , +8249 , +-14787 , +-20777 , +-11631 , +22073 , +-27147 , +22019 , +22437 , +-9439 , +71 , +-8815 , +19315 , +-2273 , +-12913 , +-3667 , +-5977 , +-22965 , +1801 , +19663 , +19243 , +11793 , +30901 , +27003 , +19265 , +-14029 , +-9313 , +5743 , +15647 , +-24003 , +16585 , +25953 , +27903 , +-11137 , +-11151 , +-5065 , +-20543 , +-21635 , +-28169 , +-12103 , +-8199 , +-9993 , +45 , +-26925 , +-24693 , +-9905 , +-29135 , +10563 , +13769 , +16017 , +-22327 , +5337 , +-7683 , +6621 , +8243 , +28203 , +31379 , +15209 , +-2427 , +22985 , +-20321 , +-32525 , +11903 , +-20735 , +-12283 , +-5439 , +-19737 , +-21241 , +21507 , +-20723 , +-4511 , +15037 , +10325 , +1031 , +11199 , +-22303 , +-4415 , +-10169 , +22249 , +28357 , +8509 , +12749 , +13859 , +-9843 , +26745 , +27499 , +-19469 , +9697 , +-253 , +2255 , +20849 , +-985 , +30935 , +22761 , +22819 , +-14527 , +-14475 , +-24847 , +-5551 , +-8775 , +-11641 , +-1577 , +29921 , +-2687 , +31975 , +-15809 , +-16975 , +-9685 , +28229 , +-26889 , +867 , +-8799 , +31029 , +-12307 , +23495 , +-1193 , +-2609 , +-28753 , +-7773 , +9741 , +-5949 , +11095 , +-13549 , +-18437 , +20209 , +8463 , +97 , +32149 , +25985 , +21759 , +19291 , +21177 , +18043 , +-13105 , +-18645 , +-13709 , +-19999 , +-24173 , +14511 , +-9949 , +23365 , +24655 , +14163 , +-1719 , +-27681 , +-28443 , +3685 , +-15701 , +-22225 , +-25707 , +7923 , +27679 , +-12285 , +-15119 , +-30181 , +12211 , +-3037 , +30803 , +11245 , +2411 , +17495 , +-26405 , +-4423 , +-14211 , +-11503 , +4321 , +3821 , +-5373 , +9073 , +22511 , +26477 , +15415 , +-1295 , +10045 , +24165 , +-21207 , +20335 , +5281 , +-30035 , +24569 , +-22073 , +19471 , +-22127 , +23945 , +-11023 , +8077 , +-711 , +-4673 , +12695 , +-23127 , +-21643 , +2611 , +-31191 , +7797 , +13591 , +-7313 , +-23689 , +22271 , +-25129 , +-3935 , +-18999 , +-15547 , +23703 , +-32297 , +-25989 , +-31053 , +-21427 , +19637 , +4623 , +8979 , +21839 , +-5203 , +9927 , +1549 , +-30927 , +-14407 , +-24641 , +-21223 , +-9443 , +25743 , +-10109 , +-26627 , +5799 , +-30881 , +-10969 , +-15941 , +-14551 , +12291 , +-5409 , +-10215 , +19865 , +-9025 , +-10983 , +-5755 , +29409 , +4213 , +-28909 , +-15967 , +7353 , +-27811 , +-13837 , +-21461 , +15099 , +26171 , +22369 , +-10625 , +-31359 , +-8159 , +24731 , +1929 , +8825 , +-4459 , +-15853 , +-6593 , +-13001 , +-4003 , +25471 , +-31071 , +-27235 , +8871 , +-7049 , +29981 , +-12317 , +6347 , +30095 , +-1889 , +19705 , +13951 , +13799 , +-15625 , +29529 , +-23411 , +-4789 , +-14375 , +20579 , +-18413 , +31429 , +29267 , +14899 , +17453 , +-12361 , +-3895 , +6649 , +-12737 , +-12425 , +-12445 , +-2349 , +7325 , +-5279 , +-26349 , +-9949 , +6091 , +-11407 , +-18689 , +-24987 , +30261 , +4957 , +18051 , +-10865 , +10853 , +-3031 , +7587 , +15325 , +3001 , +31301 , +-18933 , +-3533 , +-20063 , +-10207 , +13949 , +755 , +-1711 , +11587 , +21195 , +20559 , +11773 , +-5663 , +14935 , +-31957 , +19345 , +-20737 , +19715 , +4715 , +21473 , +763 , +-12629 , +-1329 , +11887 , +-19791 , +20767 , +16211 , +2711 , +14087 , +3225 , +-13835 , +-17329 , +-2285 , +-8523 , +-15075 , +2905 , +-16729 , +10217 , +1395 , +27901 , +16749 , +16253 , +-25555 , +8257 , +641 , +-18935 , +10735 , +9383 , +30857 , +7775 , +2597 , +855 , +-14777 , +-27373 , +-4397 , +-7449 , +-8259 , +-16795 , +1267 , +-8825 , +29619 , +29381 , +14673 , +4545 , +29157 , +-11837 , +-18989 , +26025 , +-31355 , +-3191 , +12131 , +29853 , +23653 , +-3885 , +7231 , +-24711 , +4741 , +31083 , +27343 , +-18609 , +-26067 , +-20197 , +-12031 , +15005 , +30853 , +-29913 , +19485 , +-25331 , +-20817 , +23621 , +-5853 , +-28253 , +10077 , +-9447 , +28065 , +-12419 , +-32535 , +18215 , +-1791 , +18691 , +-29715 , +-4533 , +13941 , +19877 , +22111 , +-14151 , +14137 , +-29163 , +6943 , +25453 , +-29317 , +31481 , +-4579 , +-11997 , +-16465 , +-2523 , +31971 , +-9771 , +-21409 , +-12717 , +-17479 , +8367 , +-2413 , +-675 , +-10445 , +30853 , +4757 , +8435 , +16975 , +7887 , +2907 , +9683 , +14607 , +5411 , +-26539 , +-25213 , +-28795 , +20771 , +-25657 , +-18809 , +9597 , +-1281 , +-24157 , +20247 , +-10617 , +29289 , +30431 , +6749 , +16019 , +21009 , +29003 , +20519 , +11019 , +10643 , +32752 , +-8413 , +4199 , +9721 , +-25635 , +-26219 , +23627 , +24751 , +-20081 , +21645 , +-999 , +3325 , +-25929 , +29097 , +-4083 , +15357 , +16541 , +-13507 , +17105 , +28431 , +32503 , +31511 , +15773 , +-20259 , +-8383 , +29621 , +12483 , +27847 , +-15219 , +25593 , +-22317 , +-17185 , +8169 , +-8859 , +26663 , +26211 , +17705 , +13519 , +-761 , +15539 , +-1973 , +5537 , +19515 , +8907 , +19271 , +16261 , +-6111 , +25401 , +25705 , +26279 , +-29621 , +-26991 , +-15063 , +-20885 , +-27249 , +-12177 , +10629 , +-18785 , +-12635 , +19177 , +-26663 , +-19653 , +26945 , +18565 , +-18127 , +-31085 , +31653 , +25781 , +4651 , +22037 , +-9545 , +2767 , +13379 , +-28291 , +-22361 , +19325 , +32697 , +-7033 , +28663 , +-14139 , +-29223 , +2871 , +8985 , +-3983 , +-9243 , +129 , +-10101 , +15631 , +-12709 , +32649 , +-25751 , +-19097 , +-23333 , +20315 , +10375 , +25205 , +30329 , +20767 , +-4081 , +-3105 , +-12657 , +-14121 , +13195 , +19183 , +549 , +-10095 , +-26483 , +9219 , +-10823 , +-23007 , +1979 , +-26987 , +-29791 , +9051 , +12397 , +-23647 , +-3361 , +-3895 , +-30527 , +-30037 , +-29067 , +21219 , +8765 , +7473 , +27975 , +-20023 , +10965 , +-14177 , +-13715 , +-25737 , +29335 , +-28975 , +3593 , +-16253 , +-12877 , +-23293 , +18081 , +-7347 , +-21733 , +-3763 , +-19717 , +12737 , +-18531 , +7829 , +29807 , +387 , +-6795 , +32529 , +451 , +26291 , +-20381 , +30005 , +29311 , +-25315 , +-2479 , +-25803 , +15051 , +-17419 , +15449 , +24819 , +28607 , +-21493 , +-18325 , +22651 , +11333 , +-10103 , +-2211 , +-5889 , +11879 , +-28125 , +30595 , +-24503 , +17709 , +-25385 , +4047 , +-9545 , +-22797 , +-8161 , +31585 , +-1617 , +-14267 , +-20047 , +-7775 , +-8035 , +-13523 , +-19799 , +-19753 , +-3993 , +7959 , +-18607 , +-20155 , +14687 , +26913 , +-20147 , +32445 , +7117 , +19703 , +5209 , +-31047 , +3793 , +11815 , +-21119 , +-25355 , +-14871 , +-32257 , +25811 , +10369 , +27883 , +-13859 , +-7775 , +13157 , +12911 , +-12783 , +-30415 , +13993 , +-10029 , +12587 , +-12299 , +-1281 , +-31309 , +-3109 , +21835 , +26057 , +-30761 , +319 , +-15957 , +-30019 , +19381 , +23499 , +-8347 , +-9735 , +13927 , +657 , +-6697 , +-15713 , +-24803 , +10017 , +28455 , +-24095 , +-24799 , +-13347 , +4215 , +22189 , +-4035 , +25307 , +3235 , +20909 , +-28217 , +-31443 , +6515 , +31223 , +27659 , +23239 , +-20651 , +-16877 , +-21945 , +-13619 , +-9323 , +-22119 , +805 , +3189 , +3355 , +-10419 , +-22605 , +-20395 , +-11369 , +-26703 , +4309 , +-17853 , +2369 , +-23519 , +25415 , +-7259 , +24339 , +13929 , +-24053 , +-25007 , +-15495 , +23773 , +26471 , +-4127 , +-25711 , +-7439 , +23645 , +-17013 , +18139 , +-22957 , +9889 , +-24455 , +-6787 , +-20349 , +1293 , +-9565 , +-10005 , +-4893 , +-11611 , +-31709 , +-2257 , +-11427 , +-22527 , +-30443 , +-5999 , +-8337 , +-11439 , +-28703 , +-22559 , +11211 , +24265 , +24609 , +-25311 , +2663 , +-8793 , +-7691 , +19135 , +-3813 , +-18531 , +19927 , +1361 , +-27973 , +-21805 , +-23309 , +-21039 , +31913 , +-17315 , +2565 , +-6585 , +4333 , +20267 , +4781 , +-18161 , +13523 , +-26223 , +-22201 , +10889 , +-29699 , +12587 , +-26813 , +-21161 , +-26623 , +-6809 , +20479 , +-3829 , +-27525 , +-24461 , +5149 , +877 , +26535 , +-31049 , +1371 , +15399 , +32635 , +3281 , +17129 , +-5375 , +-3267 , +15365 , +-22965 , +16541 , +-15975 , +-8903 , +14495 , +27047 , +-31935 , +-15757 , +-1911 , +21655 , +27131 , +-6457 , +2171 , +6623 , +-7105 , +-25389 , +-8807 , +32425 , +-17077 , +-31811 , +-30969 , +-30195 , +4549 , +31391 , +-23097 , +-23351 , +-3903 , +19079 , +11535 , +15229 , +365 , +16115 , +-31963 , +23389 , +1305 , +25787 , +6827 , +16745 , +-29223 , +-22631 , +7307 , +21547 , +-15977 , +-31213 , +14907 , +32750 , +-32337 , +-27647 , +16543 , +28009 , +-12537 , +-31883 , +-31901 , +-29939 , +-15709 , +-5055 , +-18229 , +24747 , +-3393 , +-30231 , +24083 , +9655 , +-25493 , +10265 , +15427 , +4601 , +27035 , +-2653 , +9603 , +24771 , +11209 , +30195 , +-32003 , +32439 , +25345 , +-14077 , +-13521 , +23023 , +-5755 , +-32291 , +30913 , +19643 , +-25635 , +-15479 , +-26143 , +-25891 , +21873 , +-9073 , +-28647 , +-1731 , +6565 , +6371 , +6309 , +6173 , +-16025 , +615 , +13653 , +-22563 , +1363 , +-14367 , +3539 , +-12249 , +15427 , +625 , +24977 , +-28247 , +-22931 , +-28285 , +-24053 , +2645 , +-25359 , +-15015 , +19887 , +5135 , +32255 , +-28693 , +-23759 , +13807 , +-21149 , +-2953 , +17757 , +24555 , +-32353 , +28005 , +-6283 , +26913 , +30095 , +-32563 , +-26101 , +-14209 , +30315 , +15205 , +-12209 , +-32766 , +-22923 , +-13823 , +-18957 , +-19855 , +27653 , +-5753 , +-4739 , +-9327 , +9507 , +25955 , +20251 , +8919 , +22427 , +23693 , +-16381 , +-16207 , +-19037 , +-31507 , +-17847 , +-4567 , +-12573 , +9571 , +-25293 , +22321 , +-14829 , +-453 , +24085 , +-30903 , +-7401 , +-10209 , +-20059 , +18631 , +22929 , +-3689 , +17879 , +28289 , +7167 , +763 , +9267 , +15 , +4935 , +4335 , +-11087 , +16513 , +-27933 , +-15013 , +22791 , +-30829 , +24935 , +-31011 , +-26481 , +25957 , +11677 , +1737 , +21649 , +2237 , +-14299 , +32159 , +15651 , +24495 , +-1657 , +19965 , +16003 , +-5405 , +19655 , +17951 , +-24855 , +-17593 , +-22907 , +14287 , +1249 , +-28091 , +147 , +7913 , +-477 , +-25473 , +8711 , +-29115 , +7919 , +-16635 , +-21541 , +-25799 , +20957 , +-4335 , +20991 , +-117 , +28731 , +-29643 , +-26379 , +-22037 , +-17689 , +13599 , +-4119 , +29937 , +19357 , +3785 , +32581 , +15499 , +5853 , +-2509 , +-31795 , +2551 , +-27083 , +-27491 , +-29133 , +-29115 , +-19677 , +-12737 , +32565 , +-23745 , +2663 , +-31879 , +-26577 , +2801 , +8161 , +7323 , +30775 , +9621 , +-25885 , +-10229 , +23985 , +-10735 , +8973 , +21259 , +-31633 , +19691 , +-2655 , +17639 , +-1987 , +-3639 , +-13473 , +-6985 , +-19453 , +9057 , +9951 , +-3701 , +25945 , +1519 , +-23715 , +-10959 , +-21345 , +6197 , +23585 , +-9889 , +12693 , +-14603 , +1103 , +-6285 , +25719 , +-18727 , +-14533 , +-13651 , +17291 , +-773 , +-30393 , +27871 , +-697 , +-549 , +-24257 , +1453 , +-14627 , +10957 , +-24029 , +-19393 , +-16553 , +22011 , +19855 , +31613 , +14131 , +-11049 , +18051 , +6341 , +13427 , +10523 , +-25393 , +-21213 , +-29891 , +26675 , +-14123 , +-20213 , +25325 , +6469 , +12271 , +10891 , +32691 , +-15969 , +-14009 , +-25073 , +10403 , +-10319 , +-1241 , +-20083 , +599 , +21637 , +18647 , +-1471 , +-18949 , +-25673 , +-5899 , +-4891 , +-17167 , +-3599 , +-9145 , +26733 , +10465 , +14813 , +-25315 , +-11463 , +-16299 , +12189 , +-223 , +17103 , +18379 , +-9523 , +22451 , +-23017 , +20311 , +28395 , +-31045 , +27147 , +23731 , +21083 , +-2039 , +-28427 , +-13863 , +-31777 , +13611 , +-19417 , +12319 , +5765 , +8129 , +-6095 , +-18489 , +-983 , +27735 , +-1129 , +9245 , +-10643 , +30143 , +2063 , +-3059 , +1573 , +231 , +-12749 , +28479 , +-20131 , +2355 , +-11329 , +-2137 , +-2099 , +11601 , +-17345 , +30629 , +3533 , +-11115 , +-11179 , +17557 , +30157 , +-23345 , +18277 , +19953 , +4181 , +24739 , +-2095 , +-3871 , +14963 , +-14751 , +29107 , +18515 , +-19783 , +-30879 , +-4073 , +20889 , +31927 , +-4139 , +-4953 , +-17029 , +31463 , +22307 , +12787 , +-14891 , +-2249 , +-3907 , +-6113 , +-8277 , +-11789 , +5499 , +-27617 , +-24133 , +-28865 , +-25229 , +-32407 , +-18525 , +-1259 , +25163 , +-29131 , +14703 , +-25669 , +-32231 , +-11725 , +16307 , +-21835 , +31415 , +6077 , +3107 , +-13245 , +-19045 , +-24679 , +-24913 , +15707 , +-25551 , +10021 , +3857 , +-20455 , +-13139 , +-22245 , +-32013 , +-28995 , +-30869 , +-12095 , +6265 , +-8925 , +-4921 , +-26717 , +-25245 , +28855 , +9065 , +1487 , +27299 , +-18701 , +-211 , +-29563 , +15471 , +-15795 , +16495 , +-3211 , +24289 , +-10819 , +1001 , +20601 , +1801 , +9897 , +31499 , +451 , +12425 , +3427 , +-31535 , +8863 , +-10321 , +23583 , +16151 , +29355 , +-6143 , +5229 , +10363 , +10117 , +-18589 , +13101 , +-5459 , +-24307 , +26029 , +-13559 , +25933 , +30745 , +-1865 , +9587 , +4409 , +-8273 , +-29441 , +8721 , +21615 , +-12105 , +29371 , +-29505 , +-8603 , +-1987 , +-28817 , +-24059 , +-23337 , +-8161 , +-9203 , +31239 , +-26325 , +19023 , +22401 , +-28151 , +-20929 , +13949 , +17875 , +11363 , +18121 , +-30113 , +5051 , +-16655 , +-23511 , +-11167 , +-18759 , +10263 , +28101 , +8407 , +-7763 , +-7631 , +-5921 , +22981 , +-6669 , +-4719 , +-1811 , +10499 , +-26381 , +-22291 , +-32653 , +-10997 , +5695 , +20579 , +14937 , +4121 , +-18901 , +23273 , +-23613 , +12795 , +4321 , +28233 , +3689 , +-11209 , +26109 , +8599 , +29553 , +18635 , +16549 , +17961 , +7875 , +-7327 , +-20451 , +-4339 , +-13595 , +-29423 , +-4893 , +-4341 , +17747 , +-25977 , +-15805 , +1293 , +13139 , +23759 , +-27533 , +28453 , +3923 , +25727 , +23341 , +7165 , +-2375 , +-4239 , +26813 , +13011 , +24641 , +30979 , +21927 , +10733 , +21205 , +-6969 , +-5969 , +9111 , +13539 , +15293 , +21375 , +-13931 , +-13261 , +29707 , +-25671 , +24351 , +-31161 , +15159 , +-30577 , +16725 , +-24279 , +15071 , +-4901 , +-29123 , +19653 , +-12309 , +-23111 , +10805 , +23757 , +-21427 , +9627 , +-9235 , +-23811 , +23347 , +-7197 , +-18717 , +-30203 , +8135 , +-30463 , +-29611 , +2261 , +9815 , +12033 , +-25927 , +-31109 , +-32731 , +-29017 , +13245 , +-14727 , +-7803 , +28937 , +-28491 , +30113 , +-25943 , +15783 , +-29285 , +28515 , +-15663 , +-771 , +-32129 , +21425 , +3583 , +-22619 , +-3189 , +-31407 , +17721 , +6631 , +20329 , +10417 , +-9929 , +-31791 , +29775 , +15177 , +-30813 , +-21035 , +13159 , +23401 , +-30003 , +-5669 , +-29997 , +22681 , +19423 , +2273 , +-12771 , +9325 , +3999 , +11525 , +29997 , +15323 , +-27233 , +-12245 , +-13873 , +8471 , +8697 , +-10479 , +11161 , +-535 , +-5757 , +2271 , +8815 , +1673 , +22669 , +-15541 , +-2185 , +-19217 , +11281 , +17193 , +3219 , +29873 , +-10893 , +22919 , +-21931 , +-10409 , +8373 , +-6843 , +31867 , +-5827 , +-27345 , +-5849 , +29927 , +-16677 , +-30523 , +-27021 , +19729 , +-11605 , +23977 , +9225 , +24071 , +19321 , +-7551 , +-13829 , +1763 , +-15553 , +19763 , +-18017 , +22973 , +-22921 , +-14323 , +27183 , +18217 , +-15361 , +2439 , +4571 , +47 , +9573 , +-4489 , +-23705 , +-14653 , +-14399 , +-28983 , +10299 , +-6987 , +19735 , +-15179 , +-12541 , +311 , +15905 , +-24961 , +-31037 , +-29495 , +-2897 , +-19803 , +32365 , +31671 , +-14721 , +-12643 , +24831 , +1807 , +-30573 , +-2037 , +-23019 , +-21477 , +775 , +14459 , +-12539 , +8787 , +28015 , +11159 , +-6027 , +32738 , +-29781 , +-14371 , +10355 , +17545 , +-31939 , +23005 , +269 , +-31951 , +295 , +10731 , +32619 , +-7731 , +-14277 , +-15267 , +20325 , +-22565 , +16379 , +23609 , +15259 , +-27807 , +7151 , +16505 , +-32243 , +-21417 , +-19595 , +-9283 , +-10953 , +-12623 , +8743 , +13955 , +24993 , +8903 , +-14169 , +29661 , +-20483 , +15443 , +17917 , +16559 , +-17473 , +6125 , +-32405 , +-21153 , +5681 , +-20735 , +-9011 , +27161 , +28177 , +23103 , +10085 , +-8841 , +21409 , +-17761 , +26941 , +3529 , +-28345 , +24785 , +7933 , +-11073 , +-3937 , +-5319 , +-449 , +21931 , +-15335 , +-11677 , +-9623 , +11831 , +3339 , +-25599 , +-15865 , +22935 , +-27061 , +-21409 , +-4959 , +15945 , +-9401 , +28247 , +-28395 , +-8631 , +5027 , +2515 , +15465 , +-24119 , +15171 , +24763 , +-16081 , +-19351 , +28401 , +-30091 , +22349 , +27887 , +30063 , +-31271 , +1123 , +-18559 , +-13041 , +22953 , +-7011 , +-1445 , +5581 , +23431 , +27659 , +27913 , +12255 , +-10893 , +14455 , +23067 , +-6435 , +-15937 , +-29757 , +17247 , +-32439 , +-10875 , +1723 , +24733 , +3247 , +-28251 , +-17295 , +28873 , +-16835 , +-28107 , +13845 , +21949 , +16343 , +-11131 , +32583 , +29299 , +16819 , +11141 , +-11529 , +17339 , +10353 , +-25903 , +185 , +11123 , +12205 , +-12261 , +8861 , +-6589 , +-9951 , +29479 , +-17529 , +-23607 , +53 , +-31673 , +-10743 , +14691 , +27159 , +-32437 , +15287 , +26457 , +10841 , +-30463 , +23813 , +-22375 , +-19451 , +13609 , +409 , +-31503 , +-4301 , +25321 , +22821 , +-8763 , +11047 , +-24111 , +-31551 , +11591 , +17637 , +-32441 , +12483 , +12337 , +-9659 , +29827 , +22289 , +-3591 , +-7787 , +-31479 , +-15871 , +-19571 , +32169 , +-29791 , +26543 , +-23413 , +26231 , +10185 , +13773 , +-6411 , +-16855 , +11703 , +26119 , +-10899 , +-21823 , +-15675 , +-3369 , +1001 , +-29663 , +-8073 , +17619 , +-3341 , +9909 , +30183 , +-20327 , +-4779 , +-25993 , +-8257 , +-8943 , +2139 , +32411 , +-4421 , +-21929 , +-16759 , +-1641 , +13459 , +-20217 , +7373 , +11717 , +-12419 , +-3555 , +-1473 , +-11659 , +27677 , +-12475 , +12885 , +20875 , +-18935 , +-7237 , +22937 , +16783 , +-4429 , +-10847 , +-6937 , +-27571 , +-7447 , +-18481 , +15137 , +20969 , +-2353 , +5177 , +-22171 , +14455 , +-32691 , +14009 , +-20025 , +6161 , +10259 , +-12173 , +-21361 , +17269 , +-30453 , +-29787 , +13287 , +-4839 , +-14769 , +-22527 , +21017 , +-14141 , +20389 , +14213 , +-5565 , +-13919 , +-29581 , +5079 , +21397 , +21729 , +-23233 , +9237 , +-24829 , +-16181 , +9117 , +2869 , +32641 , +30807 , +-24403 , +-10537 , +19641 , +-25787 , +14865 , +-14687 , +6211 , +29365 , +1381 , +-15339 , +19807 , +-28093 , +14905 , +-23829 , +-11479 , +-617 , +19079 , +-15901 , +10583 , +10883 , +-24149 , +9255 , +30571 , +14235 , +16859 , +-25829 , +1643 , +12107 , +-2017 , +6327 , +7459 , +-20629 , +24271 , +-15775 , +-18739 , +-12957 , +26237 , +-9151 , +3159 , +-28999 , +-25221 , +9503 , +26645 , +-12763 , +-4659 , +-17741 , +15351 , +-6855 , +2465 , +7813 , +-3513 , +-3477 , +15943 , +29507 , +28889 , +5041 , +-6745 , +-30061 , +-14645 , +28057 , +11843 , +-9359 , +-839 , +22247 , +29087 , +-1785 , +32627 , +-32609 , +-11963 , +-24061 , +7485 , +29355 , +21053 , +111 , +3449 , +13549 , +12027 , +12809 , +-1295 , +31961 , +-26653 , +-20197 , +-30591 , +14213 , +-26055 , +-18985 , +18511 , +-14257 , +26009 , +10281 , +-25199 , +-11289 , +-22537 , +14863 , +-32589 , +-4107 , +14351 , +17017 , +-25059 , +3877 , +-14755 , +-3945 , +-14495 , +447 , +-13157 , +28599 , +12029 , +-7475 , +29619 , +-27747 , +26249 , +-13915 , +-22467 , +-23209 , +-26763 , +-26621 , +5489 , +-5993 , +-4545 , +15525 , +16031 , +29071 , +-20435 , +16997 , +28461 , +25413 , +-3197 , +971 , +-18163 , +11879 , +29239 , +23333 , +-17999 , +-5971 , +28471 , +10021 , +23939 , +21673 , +9743 , +31733 , +23013 , +-19937 , +-17107 , +-10035 , +-27233 , +-4379 , +12947 , +14867 , +14301 , +20529 , +15127 , +24549 , +-27225 , +11383 , +-29679 , +8513 , +-18987 , +-12863 , +-30827 , +9109 , +-23667 , +5251 , +-15561 , +-12591 , +18227 , +-3339 , +24877 , +-10741 , +-537 , +22769 , +-19425 , +11411 , +-22657 , +-22465 , +9549 , +-16507 , +25335 , +18807 , +-10931 , +-13339 , +-20113 , +31059 , +-4279 , +10559 , +14243 , +-6513 , +9899 , +24749 , +-10785 , +14385 , +22367 , +-6013 , +20091 , +5241 , +-16249 , +23639 , +13011 , +-16351 , +-11851 , +2467 , +20153 , +-4541 , +671 , +-22311 , +19061 , +-10065 , +-21159 , +-25865 , +-17607 , +14525 , +25361 , +-31827 , +23065 , +14513 , +-19647 , +-26655 , +-26237 , +-2683 , +-8853 , +30937 , +20795 , +-22199 , +25931 , +-3129 , +-18229 , +5627 , +411 , +32233 , +26751 , +18653 , +-8899 , +-15075 , +-26397 , +20043 , +-23811 , +11509 , +22707 , +-4581 , +19395 , +-28583 , +-3759 , +2153 , +10065 , +8085 , +12743 , +-21767 , +6003 , +-19715 , +-10185 , +30477 , +30145 , +27123 , +-11817 , +28599 , +-25651 , +-4463 , +-30359 , +-14149 , +-31263 , +13751 , +-981 , +-12837 , +-30667 , +5031 , +-12965 , +31421 , +-29015 , +32025 , +4137 , +-9419 , +-8455 , +-13097 , +49 , +-13273 , +-10885 , +-6701 , +24683 , +13531 , +-27569 , +-30271 , +-18257 , +20693 , +7455 , +-17365 , +10663 , +8747 , +-12973 , +-30193 , +3909 , +-23451 , +-19255 , +3567 , +10691 , +-10291 , +-16625 , +2161 , +-31473 , +15687 , +10003 , +-6797 , +-10549 , +-9553 , +11627 , +-31327 , +-30009 , +24491 , +-30465 , +-23405 , +13811 , +-31993 , +-30143 , +13151 , +-22567 , +12427 , +26867 , +32691 , +21143 , +-24747 , +-19377 , +32627 , +16723 , +-5971 , +24005 , +6339 , +21817 , +14175 , +22071 , +-16723 , +237 , +10137 , +13741 , +14901 , +14983 , +28469 , +-6773 , +-2071 , +-9209 , +26273 , +-15027 , +-19963 , +10835 , +-30163 , +16829 , +-12539 , +-17753 , +-29725 , +22191 , +19643 , +28313 , +3557 , +-3281 , +-28693 , +-16767 , +-25281 , +-18365 , +-3999 , +2685 , +1349 , +2595 , +22923 , +10727 , +-27805 , +-5147 , +-10355 , +-3765 , +25467 , +-25145 , +26847 , +-6435 , +19645 , +30167 , +-5029 , +-8841 , +-30979 , +-5325 , +-31771 , +-20983 , +-24437 , +19393 , +17265 , +-14437 , +-9077 , +5219 , +-31575 , +-12867 , +-28209 , +25525 , +-18693 , +-641 , +-24019 , +32573 , +1081 , +-28435 , +-23979 , +-7379 , +-24147 , +-9975 , +-13779 , +-11121 , +9649 , +17979 , +17837 , +-4597 , +-17979 , +5969 , +-473 , +-24817 , +-32465 , +-6417 , +29747 , +5529 , +3079 , +-12399 , +-15881 , +-30117 , +11995 , +24057 , +24075 , +26503 , +5823 , +2605 , +-18747 , +16889 , +-3607 , +28399 , +15903 , +7409 , +1221 , +-2127 , +-513 , +-4011 , +-31857 , +15633 , +19745 , +-5799 , +2161 , +-14383 , +-17317 , +24005 , +-495 , +29257 , +-11125 , +-5721 , +-10581 , +8295 , +-17189 , +-20599 , +26547 , +1573 , +24995 , +13101 , +16863 , +13433 , +13249 , +-14651 , +24009 , +-23333 , +6257 , +677 , +-2813 , +31539 , +-24161 , +16263 , +-8275 , +-18865 , +9927 , +-29901 , +20113 , +1767 , +-10677 , +4035 , +14779 , +1285 , +22339 , +25949 , +23439 , +31759 , +5091 , +-14757 , +4193 , +1327 , +-15289 , +-25067 , +-3445 , +-22445 , +20943 , +27153 , +-29941 , +-17499 , +-21765 , +26041 , +-4457 , +-18051 , +-24643 , +-1899 , +-24779 , +17637 , +24147 , +24327 , +-30125 , +5249 , +-22365 , +-31365 , +31583 , +-1001 , +23051 , +-29143 , +-9501 , +-13191 , +21953 , +-1727 , +4627 , +16907 , +30117 , +-6223 , +27377 , +-18005 , +-28257 , +28751 , +-15137 , +-7111 , +14189 , +32665 , +-2635 , +12419 , +11017 , +14831 , +12125 , +9153 , +18291 , +22597 , +16873 , +22673 , +-10217 , +30555 , +4653 , +23659 , +661 , +-11909 , +7381 , +9109 , +22823 , +23213 , +24057 , +19365 , +11633 , +-18577 , +30019 , +-7055 , +-17439 , +1517 , +24179 , +-2167 , +-14473 , +-3655 , +-26999 , +-31183 , +-16845 , +2567 , +1361 , +13781 , +-553 , +-11683 , +-31869 , +25351 , +20819 , +-31277 , +21845 , +-11533 , +16013 , +1221 , +29077 , +-17581 , +15553 , +-6899 , +-4793 , +22767 , +27483 , +7359 , +25519 , +-13163 , +-7867 , +16219 , +-19721 , +30341 , +11467 , +-14967 , +-6845 , +-30599 , +7147 , +22347 , +-25023 , +1553 , +25903 , +-28479 , +-6833 , +-5165 , +18699 , +14677 , +-23549 , +-19297 , +-15451 , +25973 , +-20139 , +-2655 , +26435 , +31441 , +-16089 , +18649 , +30479 , +-28909 , +4199 , +15877 , +23163 , +6411 , +9631 , +-30179 , +277 , +27765 , +32277 , +11595 , +20193 , +-2003 , +32607 , +-14491 , +10539 , +-16671 , +-31363 , +-11547 , +15339 , +589 , +25965 , +-419 , +3983 , +-26373 , +15429 , +23665 , +-30887 , +-6549 , +-7473 , +-23981 , +24639 , +-4647 , +-8807 , +11443 , +-14285 , +30571 , +8597 , +831 , +-23033 , +-16399 , +-31443 , +-28011 , +-22075 , +-21733 , +13787 , +21697 , +-17027 , +-4055 , +2623 , +8237 , +-4441 , +14639 , +2239 , +21791 , +26615 , +-21303 , +-1389 , +-24141 , +-27721 , +-9655 , +25451 , +-27571 , +-357 , +-32639 , +-19081 , +-19313 , +4893 , +9963 , +6671 , +23261 , +17747 , +365 , +-22851 , +-437 , +-14521 , +5765 , +22243 , +12563 , +24017 , +8205 , +-24123 , +921 , +28139 , +7787 , +1323 , +1495 , +-9583 , +5707 , +23665 , +-24745 , +-13557 , +-3877 , +23595 , +-2635 , +-3629 , +-2437 , +2607 , +6537 , +27625 , +-9219 , +-30151 , +-19993 , +-12123 , +-9643 , +5877 , +-8615 , +-30185 , +-14117 , +32681 , +-30897 , +3545 , +-19973 , +573 , +-10981 , +3691 , +-9617 , +-9761 , +1393 , +15625 , +-19721 , +23055 , +22349 , +-19451 , +-21357 , +-4543 , +17789 , +-24167 , +26425 , +-10763 , +-14447 , +19273 , +13071 , +-2749 , +-11955 , +433 , +23581 , +-28157 , +-14159 , +7399 , +14479 , +21851 , +10849 , +-26297 , +29027 , +27097 , +5283 , +27861 , +32171 , +3595 , +-3875 , +11539 , +-14281 , +29595 , +-3197 , +7507 , +30687 , +17117 , +-21867 , +15769 , +21033 , +-25869 , +21141 , +29161 , +-20335 , +-6561 , +10751 , +23077 , +51 , +23577 , +31555 , +-3485 , +-15345 , +-31445 , +-27333 , +-27705 , +-28233 , +-24887 , +27169 , +28121 , +143 , +12515 , +3343 , +4189 , +895 , +-20155 , +-14867 , +7593 , +-23249 , +-29907 , +-3091 , +-17017 , +-24899 , +25437 , +30343 , +-6021 , +-16141 , +-3907 , +-11029 , +9137 , +-22519 , +16741 , +-9217 , +-15043 , +-20021 , +-15287 , +-5429 , +22797 , +-20891 , +-4295 , +-23163 , +15911 , +17293 , +-9839 , +18163 , +5269 , +31293 , +-23745 , +18551 , +5045 , +28403 , +99 , +-26507 , +-7921 , +-25503 , +-16029 , +5975 , +-79 , +-18265 , +-20597 , +-27899 , +28675 , +-25333 , +-27111 , +-1837 , +-26585 , +12341 , +-12317 , +-2555 , +3269 , +-13601 , +12639 , +-16707 , +21103 , +3859 , +-22709 , +13181 , +12143 , +-22045 , +25017 , +7443 , +-23001 , +-2147 , +-7251 , +-18661 , +12261 , +649 , +-12493 , +16629 , +20535 , +-11237 , +-14855 , +-12999 , +6351 , +-28497 , +13925 , +1969 , +-18993 , +21947 , +27945 , +10709 , +-25949 , +21137 , +-15513 , +-10819 , +26465 , +5009 , +16701 , +3993 , +7833 , +30685 , +-29471 , +3503 , +-15441 , +18843 , +32317 , +5841 , +-1609 , +-3931 , +12031 , +10065 , +-17727 , +14273 , +-8389 , +-27527 , +-16445 , +-25505 , +-31113 , +26251 , +-20253 , +8397 , +26957 , +-24275 , +-18859 , +6383 , +-29821 , +12913 , +-32339 , +-5767 , +22167 , +-16327 , +26563 , +12703 , +19689 , +3135 , +-23809 , +22367 , +8513 , +9863 , +22067 , +-4575 , +2807 , +9817 , +26621 , +-4091 , +-20869 , +-24139 , +-12657 , +16783 , +29311 , +-25781 , +25623 , +30685 , +-26241 , +7933 , +-9335 , +22889 , +-2079 , +17611 , +-4605 , +4407 , +-24949 , +-11701 , +22685 , +-29543 , +20991 , +12975 , +-15677 , +-1195 , +9707 , +-723 , +9485 , +-5519 , +5449 , +-15873 , +-14181 , +-3747 , +-4369 , +21979 , +30435 , +27053 , +28335 , +21479 , +-3559 , +10585 , +-9491 , +3637 , +19955 , +-18581 , +-333 , +-23367 , +16661 , +-3263 , +-10167 , +31427 , +1751 , +-22983 , +-11179 , +-15631 , +-5715 , +-2061 , +-4757 , +22963 , +3571 , +15621 , +-30683 , +-22987 , +-27319 , +6195 , +25539 , +-17953 , +-19857 , +26153 , +30519 , +26189 , +-14953 , +-5199 , +4809 , +-32315 , +6465 , +15977 , +7719 , +4655 , +22415 , +-8191 , +-13569 , +-26995 , +20513 , +1007 , +-27621 , +9973 , +9839 , +-2141 , +-7953 , +-23801 , +-32619 , +-23223 , +9661 , +-22809 , +-12613 , +10491 , +-10201 , +32429 , +17125 , +-3979 , +4165 , +-12181 , +-28347 , +23893 , +11841 , +13467 , +4387 , +25041 , +23663 , +29977 , +22053 , +4075 , +17887 , +-21861 , +-9683 , +-27861 , +-9857 , +-3925 , +-12363 , +-29479 , +29097 , +-6115 , +-19293 , +19121 , +14401 , +-16379 , +-16993 , +-12253 , +8013 , +-713 , +-19983 , +10751 , +17931 , +-18381 , +20433 , +1207 , +8839 , +-30295 , +-11959 , +-747 , +18361 , +-8855 , +-22141 , +-23699 , +8215 , +-7203 , +4775 , +-22177 , +29873 , +-9725 , +-31695 , +12803 , +6343 , +-8223 , +-22067 , +-17237 , +-28193 , +5507 , +-3419 , +-24037 , +5221 , +13933 , +20805 , +-25545 , +-21321 , +27541 , +17387 , +20549 , +-4917 , +-29729 , +-17053 , +21411 , +-2505 , +-31985 , +1629 , +-23815 , +14553 , +5955 , +12097 , +1017 , +-16925 , +-15125 , +10901 , +18833 , +22395 , +-5819 , +10179 , +-3415 , +-29495 , +-3251 , +18045 , +6997 , +-25955 , +-11459 , +14995 , +14479 , +24699 , +24705 , +-1981 , +-27023 , +-28101 , +-4563 , +289 , +4331 , +1561 , +-14853 , +26975 , +-259 , +30549 , +-15941 , +11693 , +-14231 , +-27323 , +-17579 , +-3697 , +7669 , +-18701 , +2873 , +-16843 , +19481 , +2861 , +-12971 , +-9769 , +-24513 , +-25305 , +9371 , +20359 , +22645 , +1415 , +13543 , +16267 , +5545 , +8201 , +2947 , +-28619 , +18527 , +-25203 , +11803 , +5949 , +-28695 , +-13639 , +2105 , +-11369 , +-31713 , +25349 , +-4303 , +20429 , +-7781 , +-14239 , +-2901 , +-15149 , +-28565 , +30525 , +16267 , +5477 , +32073 , +3889 , +9075 , +14805 , +-17063 , +-14327 , +-20811 , +13423 , +-2979 , +-21661 , +-6449 , +9803 , +30059 , +27333 , +27491 , +-25435 , +5677 , +10805 , +-18519 , +-20813 , +11405 , +5973 , +-17809 , +1027 , +-20743 , +9459 , +-881 , +23375 , +-4337 , +-15575 , +3551 , +-22061 , +-6429 , +-5139 , +28855 , +27433 , +-28501 , +23603 , +-17443 , +14753 , +16637 , +20857 , +11013 , +18197 , +31621 , +-23569 , +21951 , +-12731 , +14907 , +-27395 , +17661 , +5293 , +7971 , +10853 , +-24833 , +5343 , +-30599 , +28123 , +8657 , +26965 , +-137 , +26911 , +9281 , +-28717 , +-1665 , +13961 , +21847 , +7479 , +25565 , +-461 , +29263 , +-1583 , +-3589 , +14207 , +11025 , +15941 , +-23017 , +1853 , +-4831 , +-14127 , +-29567 , +4667 , +-13019 , +9017 , +8525 , +-25501 , +18127 , +-12015 , +22671 , +19529 , +2915 , +-24935 , +-16111 , +27471 , +-26977 , +2069 , +-18035 , +-1481 , +-15805 , +20907 , +12383 , +29241 , +4091 , +26545 , +-6715 , +-30047 , +-7707 , +8071 , +-22379 , +-9507 , +22905 , +-3849 , +-31377 , +-20189 , +5391 , +-16379 , +24703 , +-2689 , +-31789 , +-12471 , +-3671 , +29035 , +2101 , +29383 , +-25777 , +21485 , +-24341 , +-25781 , +4985 , +18983 , +20585 , +-11719 , +22429 , +1145 , +-1327 , +-16915 , +-7477 , +-32754 , +-3473 , +-14705 , +-24979 , +-4863 , +-5449 , +-3225 , +-31369 , +-30491 , +-30289 , +-26431 , +29223 , +17899 , +20471 , +-4553 , +3641 , +-27021 , +3893 , +9619 , +23965 , +13603 , +-22763 , +6689 , +-9289 , +16775 , +16573 , +12431 , +-23797 , +-30433 , +-16191 , +32569 , +-26753 , +21755 , +-22621 , +-10487 , +2831 , +-27687 , +6345 , +-15151 , +-11001 , +-18255 , +16369 , +8987 , +21429 , +9687 , +-13011 , +21643 , +20653 , +31887 , +-16553 , +-16727 , +16239 , +-22233 , +13581 , +-25269 , +-12619 , +905 , +31787 , +-14755 , +17431 , +23643 , +6073 , +30273 , +-26033 , +20117 , +-2963 , +-17239 , +-9747 , +-21101 , +-31839 , +-24091 , +-23409 , +26549 , +-2873 , +-25401 , +27291 , +-19087 , +17763 , +28917 , +17269 , +-4879 , +24455 , +3517 , +-8139 , +-11741 , +-317 , +-31369 , +-28445 , +-17573 , +-27739 , +-19117 , +-11215 , +25183 , +-8789 , +-19015 , +27051 , +-17909 , +29631 , +-21731 , +24181 , +-24481 , +-3281 , +3923 , +3201 , +-15071 , +3361 , +2931 , +-31673 , +-25365 , +10893 , +-1499 , +22785 , +-18233 , +-8521 , +-21891 , +18267 , +23117 , +-8155 , +31571 , +-20813 , +-25553 , +-16359 , +-6367 , +21707 , +1883 , +6279 , +-26545 , +27653 , +-4977 , +26761 , +-25069 , +21527 , +23153 , +22371 , +-9779 , +3403 , +2087 , +-27153 , +15567 , +-10709 , +3187 , +5783 , +-4405 , +-5181 , +-18109 , +-11305 , +-2921 , +-7083 , +29649 , +-8921 , +28563 , +-25453 , +-7885 , +-7557 , +3447 , +12115 , +16253 , +-2499 , +-16207 , +-4149 , +17231 , +-16965 , +22847 , +-8635 , +20979 , +-14291 , +5631 , +-28835 , +28663 , +17439 , +-14709 , +-589 , +-17349 , +-13453 , +-27241 , +15913 , +-12395 , +32215 , +5055 , +-29037 , +-10017 , +8629 , +-25883 , +-18699 , +-12903 , +-31817 , +-24059 , +13627 , +-30987 , +-13125 , +6547 , +11117 , +9085 , +1605 , +26703 , +-30611 , +-31461 , +-31365 , +8347 , +25385 , +17343 , +29859 , +1625 , +83 , +-5005 , +13073 , +32059 , +31395 , +-6933 , +-15451 , +-2141 , +-31359 , +-13399 , +449 , +32249 , +16965 , +-21361 , +-11071 , +-6533 , +-24593 , +-7689 , +6645 , +-10845 , +15707 , +-1465 , +32021 , +7923 , +17919 , +31253 , +-2239 , +-25005 , +16667 , +-11599 , +11371 , +8677 , +19323 , +25929 , +24417 , +31843 , +-19549 , +-5513 , +13363 , +22515 , +28819 , +5727 , +-1735 , +-7809 , +27383 , +-11959 , +-20859 , +-7029 , +4323 , +-9043 , +-31785 , +28561 , +11271 , +15583 , +1309 , +-26405 , +29293 , +16145 , +-21141 , +31699 , +-13911 , +29691 , +6247 , +1761 , +-19305 , +30445 , +-30125 , +-20029 , +-7273 , +-9881 , +1649 , +-19361 , +24375 , +2863 , +-21487 , +-10713 , +17787 , +-26895 , +-28171 , +28129 , +-28281 , +-29875 , +-10157 , +-22003 , +-6689 , +26739 , +10573 , +-17993 , +-11995 , +27201 , +24555 , +-4657 , +-31427 , +-31025 , +-29305 , +27391 , +31003 , +-1647 , +5589 , +-31737 , +-4881 , +-19731 , +6479 , +21655 , +-14113 , +-31669 , +-6603 , +-19295 , +-12739 , +24763 , +-22529 , +7215 , +-27833 , +-30205 , +3417 , +-28729 , +16725 , +567 , +7317 , +11575 , +-29289 , +6613 , +-4431 , +28915 , +-7093 , +29277 , +-30533 , +-13333 , +15991 , +19813 , +-29735 , +-24093 , +-26083 , +-32713 , +-3139 , +18509 , +-29447 , +-7197 , +-25705 , +7581 , +-5711 , +-26153 , +-15977 , +20775 , +-4201 , +-769 , +16599 , +29551 , +-809 , +-26795 , +-17947 , +26379 , +15155 , +-3077 , +25003 , +-13837 , +16193 , +-23085 , +-20751 , +28503 , +4631 , +23191 , +-25009 , +517 , +-25201 , +21111 , +-15189 , +26413 , +-3339 , +5155 , +-6105 , +-1589 , +25671 , +-19085 , +22441 , +13941 , +-6171 , +-28557 , +-18239 , +-4169 , +-16683 , +-17151 , +-31701 , +-23835 , +-10901 , +9955 , +-5939 , +1405 , +-10609 , +-26527 , +19739 , +25333 , +26991 , +-28327 , +10023 , +-7397 , +-28235 , +17115 , +25351 , +20713 , +-21949 , +-30911 , +4053 , +31195 , +-3477 , +11969 , +-29913 , +-16947 , +9635 , +30863 , +-7421 , +-6325 , +5567 , +4203 , +-22949 , +-7055 , +-16467 , +26817 , +-9213 , +30783 , +-11609 , +-14023 , +22569 , +31859 , +8685 , +-5669 , +10321 , +-13351 , +-1791 , +29333 , +19907 , +27955 , +-13739 , +14185 , +32401 , +5759 , +12433 , +-30479 , +9473 , +-24357 , +-17857 , +29057 , +21903 , +-31523 , +30727 , +14017 , +-3231 , +-2207 , +-14997 , +-2111 , +-17601 , +-16659 , +17399 , +-16501 , +27915 , +22911 , +-32509 , +-7093 , +-13381 , +-29971 , +15841 , +2773 , +-21553 , +-5193 , +-11623 , +-22835 , +-14263 , +-28573 , +-23769 , +20273 , +-27097 , +24915 , +7977 , +-16517 , +-12715 , +15135 , +17435 , +-8907 , +-6609 , +28519 , +6673 , +-26093 , +11889 , +-16843 , +8943 , +2693 , +-12111 , +24525 , +13343 , +-30503 , +25433 , +14087 , +-19771 , +15561 , +19483 , +-15321 , +-21887 , +-8293 , +-22287 , +-4039 , +-18785 , +5297 , +-2169 , +18659 , +13777 , +11947 , +13123 , +-15171 , +-16277 , +-18185 , +-24141 , +-22481 , +22803 , +-25111 , +1415 , +-23865 , +20481 , +16729 , +28681 , +-17141 , +20657 , +26551 , +26903 , +11991 , +-28131 , +16803 , +-23145 , +-18891 , +-24199 , +29699 , +1141 , +-31053 , +-16537 , +29859 , +2579 , +26939 , +18345 , +4931 , +-28083 , +9323 , +7017 , +-30923 , +-3871 , +-14995 , +-31263 , +-9871 , +14453 , +-7853 , +-27749 , +823 , +-8187 , +26345 , +21545 , +-26347 , +32487 , +6413 , +-421 , +23185 , +-10447 , +18831 , +28407 , +32313 , +-6459 , +-4995 , +-1553 , +4663 , +14013 , +-25589 , +1567 , +18803 , +8543 , +-23339 , +27523 , +3359 , +18085 , +-19761 , +3049 , +-21795 , +-6361 , +13961 , +-25043 , +-2227 , +23957 , +6935 , +9209 , +-17119 , +28343 , +-7079 , +493 , +-12091 , +-22565 , +-12829 , +12901 , +-24471 , +-31787 , +587 , +-30041 , +-26469 , +-29071 , +-31999 , +-30043 , +13673 , +15979 , +-10065 , +-20695 , +6119 , +-16911 , +9219 , +-16741 , +-1955 , +22927 , +-22759 , +2089 , +-13109 , +-12887 , +24387 , +3471 , +-1011 , +10875 , +-14485 , +-28859 , +-2707 , +-31097 , +23269 , +29495 , +1219 , +14227 , +-3893 , +32257 , +-17663 , +-13793 , +-30767 , +22183 , +-15531 , +28513 , +-25947 , +-13107 , +31933 , +6581 , +-27459 , +-9881 , +12319 , +-99 , +32693 , +20989 , +15075 , +-17103 , +-32477 , +-14755 , +1543 , +-13281 , +16627 , +-32561 , +8635 , +-30177 , +-12221 , +8411 , +23929 , +-31251 , +10413 , +-14229 , +13463 , +19131 , +-9173 , +21403 , +26473 , +25137 , +3435 , +-27939 , +6351 , +-15135 , +18603 , +-65 , +18517 , +28993 , +21769 , +-7143 , +197 , +24859 , +-27039 , +27599 , +4929 , +-27243 , +6051 , +-26367 , +-18721 , +29081 , +-10835 , +-27967 , +-6981 , +6869 , +25247 , +18005 , +-14193 , +6449 , +31163 , +-11541 , +7637 , +-4917 , +-25681 , +-18487 , +-11953 , +-11675 , +19325 , +15631 , +-16595 , +28265 , +967 , +3823 , +-6753 , +-27045 , +31919 , +-31911 , +-7189 , +-3891 , +23079 , +-32187 , +7687 , +-23581 , +-9517 , +-30631 , +23735 , +-13765 , +-24747 , +-17359 , +16921 , +-6541 , +8755 , +-29173 , +27335 , +3357 , +-2015 , +-9727 , +-27795 , +-721 , +28899 , +1229 , +-25895 , +-8441 , +-20319 , +2797 , +-18269 , +-7715 , +-9795 , +-1429 , +-16333 , +28599 , +24371 , +-12529 , +-14235 , +12267 , +5989 , +10517 , +3997 , +-28657 , +10109 , +-10643 , +29795 , +2931 , +24387 , +-22935 , +23153 , +-5863 , +7537 , +32760 , +21591 , +-22479 , +21645 , +12899 , +27017 , +-11507 , +-14269 , +-1917 , +20735 , +28819 , +6971 , +9841 , +30793 , +-13245 , +-14989 , +-1587 , +12071 , +-13149 , +-29933 , +1125 , +-12383 , +-28609 , +-29753 , +10617 , +15005 , +-30437 , +-32101 , +-23179 , +-32511 , +-12625 , +20047 , +6169 , +4413 , +-8611 , +23083 , +2373 , +16747 , +-32155 , +-159 , +-8159 , +-29211 , +5995 , +30427 , +-15137 , +25695 , +-6049 , +29595 , +25839 , +-11393 , +-9989 , +-627 , +4533 , +-2323 , +5823 , +-23325 , +12743 , +30715 , +2145 , +-23059 , +31903 , +-1367 , +13263 , +5483 , +-1831 , +-12463 , +21149 , +-21139 , +13537 , +-16209 , +19717 , +21159 , +-19911 , +22147 , +21337 , +-5559 , +-1243 , +25765 , +-12803 , +-26537 , +23271 , +16027 , +23523 , +-381 , +-20359 , +26551 , +-26757 , +-27775 , +21445 , +6055 , +-9679 , +-21787 , +-31399 , +27545 , +-18839 , +17781 , +24741 , +-25661 , +24551 , +16899 , +-14167 , +3463 , +-17701 , +1737 , +18233 , +-26101 , +18761 , +15161 , +22191 , +-7863 , +-20723 , +-21925 , +3617 , +429 , +1097 , +-6747 , +-22497 , +-29653 , +-20891 , +-16301 , +-9245 , +3287 , +-2177 , +15159 , +-32493 , +-1 , +7275 , +-1763 , +30189 , +-29759 , +2343 , +-11361 , +16395 , +-10717 , +31701 , +-22411 , +24467 , +20397 , +-14801 , +-2217 , +-13071 , +-13699 , +-6785 , +26709 , +-26349 , +-18973 , +10529 , +-11611 , +10265 , +22137 , +8043 , +-9211 , +-365 , +21175 , +311 , +-14193 , +-26311 , +27659 , +21447 , +-27883 , +18209 , +-17283 , +-1711 , +-6675 , +32375 , +20657 , +26597 , +3161 , +-23629 , +30359 , +16119 , +29783 , +-17575 , +-26511 , +-3261 , +-9997 , +-473 , +-911 , +-13993 , +-21201 , +-14381 , +16595 , +-10623 , +-8375 , +-10173 , +-5001 , +16459 , +-29535 , +24383 , +-5135 , +29293 , +-16887 , +-13645 , +21285 , +-31919 , +-15201 , +-12451 , +15203 , +32507 , +20265 , +-23539 , +5627 , +-12143 , +-12315 , +-6311 , +19283 , +-32185 , +19177 , +10193 , +32385 , +-29731 , +9461 , +-31039 , +19817 , +-6253 , +2769 , +28003 , +-6839 , +-23127 , +-30437 , +-13165 , +17371 , +-18867 , +27819 , +-8431 , +31979 , +-24039 , +-31897 , +-6609 , +-9111 , +-5881 , +-10861 , +-9967 , +15623 , +16369 , +-4171 , +32351 , +27475 , +25725 , +21733 , +-6017 , +-4793 , +-16477 , +-20055 , +-13229 , +1641 , +-29035 , +-6327 , +-21915 , +20573 , +-13755 , +-30805 , +17063 , +-16385 , +-31401 , +-9811 , +19115 , +28413 , +-1895 , +-527 , +-8613 , +497 , +-2567 , +19527 , +-23765 , +749 , +-1533 , +-32395 , +5595 , +2211 , +-27689 , +-10857 , +-1373 , +499 , +23447 , +-27913 , +26615 , +32261 , +12147 , +17763 , +25525 , +18657 , +-4341 , +6661 , +-29975 , +13449 , +28025 , +-30789 , +-17421 , +26253 , +-11841 , +-10255 , +15185 , +555 , +7615 , +-22539 , +19151 , +-31013 , +5051 , +-1323 , +-21699 , +-17549 , +12863 , +-3153 , +171 , +32179 , +-339 , +-12141 , +-28387 , +20075 , +22047 , +15825 , +21961 , +-3579 , +-787 , +-26153 , +-10551 , +-599 , +9383 , +16777 , +-13993 , +-22325 , +8317 , +32021 , +-6013 , +-17591 , +77 , +9549 , +109 , +-4093 , +18949 , +-26235 , +-23561 , +-23567 , +-30293 , +7645 , +-31481 , +10681 , +-4143 , +14891 , +-6347 , +-26163 , +-18809 , +12609 , +9483 , +30461 , +-31525 , +10449 , +-16457 , +-111 , +-30515 , +6597 , +-3769 , +-32027 , +32709 , +8459 , +14687 , +-27781 , +25999 , +18687 , +-9103 , +28053 , +465 , +25397 , +-12937 , +27215 , +3081 , +2769 , +-1497 , +-10443 , +7669 , +26477 , +29105 , +2649 , +11423 , +-14239 , +24047 , +2803 , +-16443 , +-20317 , +18213 , +-22927 , +-24611 , +27421 , +-26059 , +18957 , +12931 , +-16505 , +-5803 , +30959 , +15735 , +-8259 , +-8369 , +14015 , +18451 , +9621 , +23853 , +16059 , +21319 , +-18115 , +-17795 , +24405 , +8201 , +-18419 , +-24577 , +-11711 , +-17325 , +-3099 , +29923 , +-5859 , +-29029 , +-7427 , +-10623 , +-6537 , +-26683 , +-10171 , +4751 , +23409 , +9127 , +7223 , +7127 , +-7721 , +-24589 , +-461 , +-3723 , +-30029 , +-11847 , +30293 , +-3957 , +-9881 , +8535 , +28621 , +2167 , +-23735 , +13565 , +21433 , +18831 , +-21579 , +-28267 , +-4997 , +-14761 , +21671 , +31307 , +14735 , +16187 , +15315 , +-14727 , +19435 , +-28475 , +7235 , +-6619 , +-15669 , +23635 , +-13215 , +-13065 , +275 , +-7339 , +-20321 , +-1103 , +-19675 , +-29441 , +31363 , +24617 , +-17101 , +3717 , +-29629 , +17343 , +10785 , +-21037 , +-10013 , +85 , +13011 , +-26947 , +-26431 , +-19513 , +-2549 , +-17723 , +-21831 , +-22043 , +-1857 , +13127 , +-1615 , +-19223 , +1779 , +-25031 , +-16705 , +11375 , +-29425 , +27997 , +-2123 , +-13587 , +437 , +-24581 , +-5571 , +8621 , +30753 , +-8423 , +2931 , +-9407 , +-3339 , +29751 , +9213 , +-31613 , +-28771 , +4739 , +2205 , +5119 , +8733 , +-5491 , +-16557 , +-6147 , +22897 , +135 , +26861 , +29415 , +1119 , +15611 , +-14561 , +20045 , +-28973 , +12285 , +-18653 , +-5027 , +20405 , +-277 , +30917 , +-24623 , +-16573 , +29857 , +6663 , +12917 , +11749 , +-21455 , +-8399 , +-15859 , +5001 , +19993 , +-149 , +7139 , +-28809 , +-10237 , +-29225 , +20141 , +12465 , +-6413 , +-6361 , +-21749 , +-24897 , +-1017 , +31667 , +-5503 , +15123 , +-19545 , +19995 , +-19215 , +21207 , +-6333 , +-435 , +15497 , +-1715 , +-20083 , +-18127 , +10311 , +8865 , +-13013 , +-6991 , +-31513 , +5959 , +17905 , +-8103 , +-2973 , +-10293 , +-2919 , +-19855 , +-11291 , +-30417 , +-17155 , +-1651 , +-28603 , +-32317 , +1741 , +-1365 , +-7941 , +3707 , +26823 , +9163 , +8599 , +-30521 , +-399 , +-9467 , +-32319 , +-11029 , +24655 , +-3553 , +17319 , +-7975 , +-18791 , +-26965 , +-16131 , +15239 , +-8583 , +5785 , +28269 , +23749 , +6589 , +20817 , +-27239 , +-19045 , +16659 , +11599 , +-631 , +8475 , +-3907 , +-5579 , +14761 , +-12865 , +-22575 , +-22683 , +-10429 , +14137 , +20967 , +-2277 , +8555 , +18641 , +13141 , +-10749 , +-19575 , +16447 , +-20503 , +-8367 , +-28095 , +26873 , +-7135 , +5465 , +757 , +18455 , +-30497 , +5801 , +-9803 , +20645 , +6565 , +6047 , +30149 , +-18311 , +-19127 , +30851 , +9343 , +-31347 , +-20171 , +20505 , +8929 , +27609 , +22291 , +-15679 , +-2697 , +-27731 , +-15089 , +32269 , +20185 , +-8065 , +26765 , +12497 , +15523 , +-12211 , +2907 , +22475 , +-11545 , +-29837 , +-5263 , +13993 , +3629 , +15613 , +-10973 , +21933 , +9191 , +19337 , +-18465 , +23491 , +-1687 , +-30061 , +-21151 , +-25323 , +-1693 , +-933 , +-5275 , +13863 , +-43 , +15407 , +-26641 , +2923 , +-27511 , +10571 , +-2063 , +-31395 , +11281 , +-5579 , +-3947 , +24861 , +-22733 , +-8057 , +21215 , +28031 , +-14099 , +-23211 , +-5633 , +-29527 , +-9503 , +-23043 , +-15375 , +-11737 , +14425 , +31109 , +-21307 , +5515 , +-2119 , +-31123 , +21583 , +-11911 , +27251 , +4359 , +5731 , +-22707 , +-21623 , +19029 , +-8821 , +24357 , +-2945 , +30557 , +6207 , +-17279 , +-3891 , +-14079 , +14495 , +-163 , +-14361 , +-935 , +-18777 , +27071 , +5539 , +23431 , +3309 , +-24099 , +-30401 , +14097 , +-22575 , +18601 , +25297 , +28605 , +16189 , +-25363 , +-30909 , +10467 , +-27941 , +-32027 , +25289 , +15177 , +197 , +-14249 , +20953 , +-32649 , +-4407 , +-729 , +-14173 , +-29035 , +32283 , +-18319 , +-3831 , +-835 , +-32373 , +-24027 , +-2275 , +-14381 , +11843 , +6423 , +-17397 , +-4121 , +32503 , +-12895 , +10143 , +-6657 , +-15963 , +10415 , +-12235 , +-7561 , +18375 , +-10397 , +12601 , +-17445 , +-20205 , +21285 , +10257 , +22069 , +-14171 , +-16835 , +-4189 , +17137 , +27847 , +-4883 , +21063 , +-22227 , +31005 , +-3321 , +19005 , +3733 , +11107 , +3589 , +-14165 , +6327 , +-1371 , +17313 , +-9457 , +-8479 , +22769 , +-29455 , +-6343 , +-7055 , +22425 , +-6667 , +13767 , +21431 , +-23069 , +6589 , +-31977 , +-28347 , +-7615 , +-23819 , +-12609 , +-16443 , +-18927 , +30975 , +8589 , +19549 , +-19509 , +8597 , +-32267 , +7035 , +28607 , +-8491 , +-12527 , +28209 , +-13493 , +20955 , +-17901 , +6163 , +-5483 , +27105 , +-27073 , +7555 , +-13121 , +-2099 , +14183 , +21137 , +-347 , +-16815 , +-26919 , +4693 , +24591 , +22141 , +30439 , +-22847 , +29545 , +-16167 , +-17203 , +30969 , +12293 , +-1277 , +-18121 , +-24013 , +-12603 , +29113 , +5933 , +-2811 , +-30373 , +-22657 , +-22117 , +5957 , +-15361 , +-6223 , +-12489 , +-15271 , +-26197 , +24091 , +-23291 , +-12265 , +17099 , +27407 , +-16565 , +537 , +20091 , +-29689 , +-24309 , +24981 , +9793 , +-20309 , +-22025 , +2485 , +-11203 , +21627 , +-19729 , +7793 , +-31771 , +13535 , +4335 , +-1563 , +-19135 , +-1093 , +13973 , +10791 , +-25953 , +-18801 , +-21489 , +22437 , +-26423 , +29197 , +-27247 , +-21511 , +25027 , +-11735 , +-32679 , +-11969 , +-24069 , +-319 , +-20967 , +8689 , +-18425 , +-17245 , +-26885 , +8511 , +28385 , +2867 , +-9715 , +-11293 , +12945 , +7801 , +21575 , +4477 , +-18573 , +3519 , +-27147 , +26217 , +-29721 , +3757 , +28345 , +-25065 , +-29555 , +-27437 , +-14337 , +-29209 , +-19715 , +11727 , +-31243 , +14453 , +14073 , +29149 , +-22779 , +-7803 , +31277 , +-7949 , +22983 , +10823 , +-18847 , +1109 , +16773 , +-12743 , +-6601 , +-21323 , +-24285 , +6271 , +-8101 , +-23361 , +-23385 , +-22085 , +7493 , +-20423 , +-32475 , +-22943 , +8039 , +12191 , +-23747 , +-6769 , +-2581 , +16431 , +-23537 , +14447 , +-11799 , +-20343 , +15547 , +25089 , +9759 , +-24119 , +-4017 , +-10373 , +18733 , +11543 , +-23485 , +-7901 , +4679 , +-6715 , +-8329 , +13213 , +26733 , +-28699 , +-6243 , +-26163 , +15401 , +-7321 , +30019 , +-14545 , +-7227 , +-19551 , +13881 , +-5467 , +20987 , +21371 , +-10601 , +6619 , +7993 , +-29191 , +-14291 , +11541 , +-8879 , +2903 , +-32641 , +9103 , +-21065 , +31397 , +25915 , +-22447 , +-28109 , +22487 , +7983 , +-12413 , +28695 , +-22937 , +-29753 , +-23471 , +15877 , +30817 , +1281 , +-24779 , +21527 , +-26105 , +14309 , +-25383 , +22173 , +14817 , +16765 , +28009 , +-19623 , +-6825 , +19019 , +-27533 , +10547 , +-20021 , +22601 , +20785 , +21101 , +-5585 , +-28839 , +-30861 , +-22169 , +6429 , +-26563 , +-24347 , +-53 , +-14479 , +26133 , +-269 , +-8121 , +-14501 , +4691 , +5407 , +-11571 , +25603 , +1841 , +-15401 , +-1215 , +19859 , +12463 , +3017 , +2747 , +-26153 , +27653 , +-20025 , +-1231 , +-20137 , +-4707 , +-5357 , +-29247 , +-32537 , +-10867 , +-21959 , +857 , +-14393 , +-21871 , +-23441 , +2039 , +-9677 , +-3209 , +-22683 , +18527 , +-20347 , +-22747 , +22433 , +-21929 , +-25917 , +-21747 , +-4271 , +-24743 , +28863 , +6175 , +5547 , +-30259 , +-26967 , +32329 , +26309 , +-21313 , +-20949 , +-8599 , +-15391 , +-25055 , +19453 , +-27957 , +1107 , +-19597 , +-30205 , +-8679 , +7893 , +24843 , +-12833 , +22747 , +25433 , +959 , +-25587 , +-2711 , +-8857 , +3367 , +-12423 , +-11673 , +30455 , +2643 , +3479 , +-27715 , +-3135 , +31999 , +-12549 , +31241 , +23833 , +-181 , +-11147 , +-3935 , +-2483 , +-22019 , +24735 , +-13823 , +20849 , +13609 , +3587 , +-7479 , +-25403 , +-13449 , +-26203 , +25395 , +-16261 , +2005 , +31269 , +22287 , +25893 , +5549 , +-25771 , +-11213 , +31353 , +27553 , +5707 , +26489 , +22199 , +6337 , +15871 , +53 , +1655 , +7239 , +-10139 , +4657 , +-6905 , +-16443 , +-9217 , +9757 , +5445 , +27625 , +-30219 , +-28531 , +-3347 , +-4179 , +15539 , +-30865 , +5247 , +-19951 , +-15621 , +19975 , +-2679 , +-14763 , +-24699 , +-20643 , +-7799 , +23217 , +1289 , +32577 , +14143 , +31109 , +-6427 , +22973 , +-25461 , +-27359 , +-2513 , +22795 , +15039 , +-10773 , +-7349 , +-1519 , +-25733 , +-23773 , +-17397 , +-6313 , +15873 , +24091 , +-16837 , +-7553 , +32019 , +-14365 , +30401 , +-31681 , +-8893 , +2451 , +-31431 , +2775 , +23507 , +-10509 , +-9215 , +-4343 , +-10741 , +-23621 , +-11045 , +30609 , +8457 , +25417 , +-3587 , +799 , +-5593 , +-13603 , +-23627 , +16589 , +-2105 , +-29111 , +-5517 , +3863 , +-7505 , +-28879 , +11627 , +14675 , +-8219 , +30397 , +7591 , +-13399 , +-19709 , +-20011 , +-605 , +13713 , +24843 , +18391 , +9573 , +-3395 , +-17465 , +-31793 , +6929 , +-3423 , +23967 , +-6097 , +6149 , +30301 , +11755 , +25867 , +21099 , +-25279 , +1493 , +18633 , +-7329 , +22459 , +-29273 , +-7327 , +-24203 , +-1831 , +-5463 , +21517 , +-14373 , +7733 , +21881 , +31117 , +-15885 , +9849 , +12509 , +31951 , +-3227 , +-4529 , +-18139 , +-4555 , +-11079 , +3035 , +-7171 , +-4795 , +15473 , +16563 , +-30529 , +21223 , +11423 , +23131 , +26969 , +22037 , +-769 , +14647 , +13209 , +-23783 , +14727 , +13827 , +4877 , +23877 , +3471 , +-25133 , +-5291 , +809 , +-27817 , +31875 , +-11523 , +-21175 , +-8145 , +28079 , +-6441 , +-24741 , +9475 , +-21455 , +3537 , +-23559 , +-17545 , +6165 , +-15025 , +10975 , +30593 , +27405 , +-29185 , +-24167 , +5505 , +21367 , +4405 , +-311 , +7379 , +-21055 , +-26943 , +-2093 , +3825 , +-27533 , +-7353 , +-9959 , +15105 , +32411 , +5913 , +30901 , +3573 , +9421 , +-23157 , +15281 , +14109 , +25747 , +-817 , +-23107 , +31043 , +-9617 , +-2481 , +27491 , +-32705 , +27209 , +-22661 , +32457 , +-27883 , +28269 , +-21717 , +3811 , +31369 , +-15101 , +31605 , +-3801 , +29747 , +29701 , +-3073 , +28109 , +-30175 , +7091 , +-27425 , +-6523 , +9959 , +-4201 , +-25105 , +20393 , +15929 , +28145 , +-25947 , +-3073 , +-7675 , +-29261 , +30317 , +31461 , +-25589 , +-25861 , +-20101 , +-22251 , +25581 , +31241 , +-12755 , +-11307 , +-30249 , +-30535 , +-28967 , +32433 , +28035 , +-10633 , +7213 , +7095 , +23013 , +-5445 , +-21501 , +26151 , +23859 , +-11777 , +-16201 , +20401 , +30085 , +-22215 , +-26363 , +-2001 , +-5647 , +24527 , +-6055 , +-22573 , +10259 , +-6125 , +28591 , +17385 , +-455 , +-29125 , +-28953 , +13839 , +-30227 , +-21039 , +26269 , +15843 , +-19693 , +32187 , +-23933 , +9541 , +-29827 , +10915 , +-31693 , +-12533 , +27401 , +-2057 , +18065 , +-26565 , +8243 , +-24737 , +29083 , +-31811 , +3377 , +-22857 , +14017 , +10397 , +-30327 , +-7035 , +28103 , +-9543 , +24617 , +-5391 , +18955 , +1537 , +-15875 , +-28353 , +24689 , +13355 , +-31471 , +21441 , +5549 , +-19225 , +2075 , +-15783 , +3359 , +24739 , +-28005 , +-19095 , +-20435 , +28083 , +-30349 , +-32433 , +26137 , +-12261 , +20475 , +-8105 , +-27559 , +7091 , +11675 , +-13507 , +-141 , +24821 , +4073 , +-2019 , +-23477 , +-995 , +-32457 , +14319 , +-24059 , +-12551 , +-21585 , +27257 , +19549 , +-8945 , +-16145 , +16593 , +-393 , +-15779 , +-25063 , +-31157 , +-14789 , +-883 , +1139 , +10235 , +-32721 , +32439 , +15993 , +-19807 , +31695 , +-30841 , +-30341 , +32559 , +16483 , +12809 , +7087 , +17841 , +-30125 , +-18221 , +7883 , +20179 , +6411 , +-7233 , +30493 , +-1071 , +25925 , +-26581 , +-20697 , +-8969 , +-10261 , +937 , +-8271 , +3723 , +-26261 , +22841 , +-5021 , +5203 , +-28275 , +-26367 , +-4895 , +-5243 , +-20525 , +23175 , +6745 , +-29881 , +5191 , +4457 , +6567 , +-29799 , +12503 , +-15217 , +-1563 , +10969 , +31535 , +-20501 , +-16503 , +27069 , +-14575 , +-14165 , +-11275 , +30141 , +-7893 , +-25609 , +12693 , +6679 , +-32147 , +-32733 , +-23433 , +28485 , +13285 , +-28565 , +-2209 , +-32525 , +15125 , +27429 , +25955 , +8823 , +9935 , +10883 , +10241 , +-22075 , +5251 , +-28731 , +31163 , +-14091 , +17957 , +-10003 , +-6875 , +15913 , +8309 , +14593 , +14471 , +-28143 , +10727 , +27321 , +-2573 , +-25375 , +8689 , +21951 , +-26663 , +2501 , +-14109 , +15971 , +-32221 , +-28453 , +28741 , +30671 , +-2103 , +8109 , +-5205 , +4297 , +-4879 , +-22487 , +-1525 , +29411 , +3449 , +-12781 , +-16487 , +27703 , +-12257 , +11015 , +26655 , +-25701 , +-4593 , +24807 , +-30257 , +-18595 , +5885 , +-19751 , +24743 , +-22915 , +14783 , +23743 , +31291 , +-7079 , +14687 , +24875 , +-5611 , +9973 , +26303 , +1501 , +-24949 , +-16471 , +-26975 , +-18767 , +-4579 , +-20903 , +11345 , +-30939 , +-2753 , +-8393 , +-3927 , +2631 , +-9027 , +-29975 , +3517 , +-18133 , +-24427 , +12629 , +1763 , +-24593 , +28479 , +9929 , +1365 , +-30427 , +14745 , +11197 , +20803 , +24535 , +-29903 , +1799 , +20335 , +-13 , +17185 , +-25965 , +-9401 , +11599 , +17767 , +27289 , +21873 , +-5861 , +-17213 , +3933 , +16113 , +-8745 , +1283 , +-30371 , +-18241 , +6609 , +-10779 , +-4081 , +-16429 , +-12269 , +-14741 , +29463 , +32203 , +22503 , +-16207 , +9729 , +-31235 , +8907 , +32331 , +-29065 , +22287 , +-7967 , +-23271 , +27895 , +-1779 , +-29709 , +-25443 , +-18415 , +4105 , +-28443 , +-19495 , +16921 , +15145 , +-12373 , +-20577 , +357 , +6213 , +-22075 , +22899 , +29435 , +-15363 , +-10445 , +9943 , +4053 , +11859 , +14837 , +-28367 , +19603 , +7103 , +26615 , +13845 , +7091 , +10955 , +9111 , +22567 , +27207 , +-18903 , +31373 , +-10131 , +-28879 , +-5299 , +-15501 , +16431 , +9437 , +-4735 , +12719 , +-3263 , +17777 , +23939 , +14327 , +8939 , +-24183 , +7573 , +28993 , +-26313 , +26997 , +-21987 , +18493 , +-2873 , +-32539 , +-8521 , +5455 , +27963 , +-2773 , +32723 , +-5371 , +-18441 , +11761 , +24775 , +-14067 , +9607 , +-12181 , +32361 , +28083 , +-28813 , +-13033 , +-6617 , +32213 , +11929 , +-28687 , +-15965 , +15195 , +-3583 , +-13525 , +24261 , +-32211 , +28215 , +-11163 , +-29609 , +17331 , +-729 , +3173 , +8983 , +14529 , +9841 , +18769 , +4953 , +537 , +-6083 , +-17563 , +-12521 , +28513 , +-1893 , +17453 , +26765 , +9367 , +-26791 , +-18375 , +15693 , +22029 , +2135 , +855 , +-31269 , +-11555 , +20065 , +-22705 , +-24125 , +5607 , +16011 , +-29419 , +30769 , +-27325 , +-31745 , +-24445 , +-15091 , +2107 , +-21405 , +11923 , +-21875 , +-9273 , +-11099 , +32277 , +24395 , +-29315 , +3673 , +-25881 , +20715 , +9489 , +5519 , +-13391 , +-27871 , +-31673 , +28459 , +-21999 , +-3243 , +-14991 , +-30785 , +21861 , +-30535 , +24671 , +-5409 , +-18443 , +6367 , +19935 , +11007 , +22191 , +10443 , +-7761 , +-28219 , +-23711 , +4765 , +-27909 , +12515 , +18799 , +-2157 , +27469 , +27505 , +27915 , +-6479 , +21515 , +-28731 , +21743 , +4053 , +-1423 , +-26171 , +30353 , +23367 , +-32253 , +-18999 , +23775 , +15837 , +-17021 , +-25625 , +24951 , +8587 , +9847 , +23511 , +-20389 , +14977 , +19213 , +-20155 , +-29139 , +8377 , +-5465 , +30885 , +22755 , +1565 , +30915 , +23701 , +15111 , +-7919 , +15995 , +21419 , +2403 , +25495 , +-11649 , +1751 , +17219 , +5853 , +8069 , +-18387 , +-21205 , +29531 , +-20153 , +-15791 , +32265 , +19819 , +32762 , +18487 , +-26891 , +28253 , +-3515 , +11665 , +-17051 , +-19947 , +19897 , +-4197 , +20451 , +-32485 , +19917 , +30321 , +27979 , +-197 , +6479 , +30449 , +1663 , +-14695 , +20061 , +32013 , +-11621 , +-30905 , +23781 , +13983 , +-25159 , +25443 , +-6249 , +5835 , +-5605 , +24491 , +25431 , +-5681 , +23533 , +-16239 , +-21179 , +29021 , +-6279 , +-21539 , +-12507 , +-24203 , +14813 , +-6469 , +-21921 , +-27209 , +21577 , +2141 , +-16011 , +-10425 , +-11855 , +-1783 , +-10243 , +2841 , +-12535 , +5559 , +-24297 , +-24371 , +-4613 , +-12247 , +13413 , +-26103 , +27167 , +9083 , +-32381 , +591 , +-18251 , +-19125 , +31233 , +12119 , +-21799 , +-1215 , +10711 , +25057 , +-30143 , +15663 , +30309 , +-8423 , +10351 , +-13399 , +-17441 , +6751 , +22633 , +17177 , +335 , +1965 , +-13573 , +13149 , +-1273 , +11879 , +-15009 , +983 , +-27745 , +-27463 , +-21885 , +27661 , +13161 , +7017 , +-12613 , +22717 , +32357 , +25135 , +-29193 , +-27277 , +-16189 , +-13163 , +7297 , +4775 , +-15919 , +-16573 , +2605 , +8269 , +13693 , +-21019 , +-4071 , +29945 , +-31679 , +4469 , +16609 , +22887 , +8615 , +-8419 , +-19627 , +-12127 , +10553 , +-26741 , +16311 , +5265 , +31227 , +-31031 , +10095 , +16149 , +2147 , +19605 , +-191 , +30625 , +-24875 , +17723 , +13323 , +32081 , +-15213 , +-5399 , +499 , +-6789 , +831 , +-14453 , +22063 , +-6441 , +17095 , +3877 , +-27861 , +2311 , +29671 , +31391 , +-20657 , +-28489 , +16671 , +31535 , +-22995 , +53 , +-473 , +24097 , +-19389 , +-31611 , +-29205 , +31033 , +21801 , +-22787 , +30463 , +-2171 , +31823 , +7005 , +-8549 , +24247 , +51 , +611 , +-24045 , +25859 , +-20453 , +30949 , +18125 , +12137 , +3145 , +-13461 , +-1865 , +-28513 , +6329 , +9801 , +20291 , +24661 , +16979 , +6699 , +4321 , +-31965 , +-12635 , +-12995 , +-21269 , +-17717 , +-12771 , +12471 , +-23505 , +-10461 , +2237 , +4861 , +-26663 , +24417 , +-8869 , +26163 , +14061 , +19449 , +-29873 , +-27823 , +-15803 , +-5899 , +-8531 , +12741 , +24325 , +30921 , +-18679 , +-1149 , +-4203 , +-20561 , +24729 , +21921 , +-21739 , +-24709 , +14341 , +17771 , +11095 , +11259 , +-28531 , +10749 , +10585 , +-24635 , +21703 , +4705 , +-24517 , +31125 , +23005 , +2075 , +-28999 , +2593 , +-8905 , +9805 , +3871 , +-1417 , +9415 , +-10939 , +-571 , +21199 , +-18007 , +667 , +-6651 , +6633 , +13681 , +-21047 , +28085 , +9437 , +6613 , +-24257 , +-2277 , +12155 , +-21783 , +-20479 , +-20119 , +-10979 , +17371 , +20407 , +-12365 , +-32255 , +7717 , +-6321 , +7785 , +-2777 , +841 , +-22009 , +-20663 , +27293 , +-7933 , +22297 , +-11293 , +1635 , +-18419 , +-19011 , +7811 , +-26699 , +-8887 , +9681 , +-24143 , +19703 , +1411 , +7403 , +9769 , +28663 , +5027 , +-6159 , +-28847 , +-15657 , +8555 , +-30415 , +9777 , +-27303 , +-17753 , +2809 , +749 , +10943 , +-15633 , +7857 , +19639 , +-30693 , +-555 , +24689 , +-30639 , +17201 , +-20061 , +5915 , +-21251 , +27077 , +23697 , +-14101 , +14329 , +6519 , +-2945 , +31903 , +-2447 , +-8159 , +-22231 , +-257 , +-16895 , +31909 , +-24349 , +1279 , +-13403 , +6219 , +-22573 , +-32177 , +307 , +-28521 , +18845 , +3195 , +-18091 , +-5729 , +19883 , +-23935 , +27135 , +-32533 , +3547 , +-20253 , +-12955 , +6341 , +-24645 , +-21945 , +-13957 , +21521 , +18489 , +3211 , +-12829 , +-17749 , +12779 , +10843 , +-8087 , +-8647 , +-8775 , +-28339 , +4095 , +-18553 , +17941 , +25723 , +-31185 , +-11171 , +11457 , +-31853 , +-4331 , +28121 , +-29961 , +-10637 , +28637 , +-189 , +-25561 , +-27321 , +-7253 , +30057 , +31539 , +-6893 , +-26839 , +-29069 , +-13789 , +-24357 , +14957 , +-32191 , +23643 , +-22733 , +16759 , +-29887 , +23383 , +-31663 , +27437 , +26557 , +-8735 , +-12109 , +-22835 , +27589 , +27085 , +7211 , +4071 , +15225 , +22567 , +-17027 , +14553 , +-14873 , +-27659 , +24181 , +31679 , +-26531 , +-21651 , +-25471 , +-30219 , +8781 , +-21589 , +-27195 , +-3583 , +407 , +-16665 , +-17737 , +-11233 , +-4245 , +1329 , +-17353 , +32033 , +26013 , +-24665 , +-4573 , +8191 , +-27523 , +26157 , +-2447 , +26043 , +-16081 , +16299 , +8393 , +3045 , +-23419 , +-27467 , +11935 , +18833 , +-7595 , +-11047 , +-1089 , +13003 , +12623 , +-31165 , +-12427 , +-11631 , +19291 , +-10241 , +-19943 , +13133 , +15979 , +11957 , +-24783 , +3531 , +13783 , +-23597 , +-5125 , +22197 , +21557 , +-4265 , +-17769 , +25215 , +-19027 , +-19469 , +-11891 , +-10255 , +13009 , +-23079 , +-20493 , +10511 , +-1027 , +-31771 , +13823 , +-13669 , +-23255 , +23383 , +-17893 , +-7673 , +-17861 , +3605 , +-7543 , +-24077 , +29679 , +-27821 , +7021 , +3355 , +-23267 , +-5415 , +365 , +22493 , +30877 , +15029 , +-26421 , +-24537 , +6047 , +3953 , +-22283 , +13293 , +-12167 , +14031 , +5283 , +7725 , +-10743 , +11521 , +-31121 , +12889 , +12171 , +-27557 , +18921 , +20057 , +-3861 , +-20585 , +-22219 , +2817 , +21415 , +22141 , +-22755 , +-27903 , +-14309 , +23847 , +28073 , +-10133 , +-26779 , +-6725 , +18751 , +-8033 , +11703 , +-27501 , +-30671 , +24265 , +-23251 , +7943 , +5855 , +21719 , +-22233 , +11421 , +12353 , +-3343 , +18981 , +703 , +-1265 , +28021 , +-9703 , +-3339 , +27471 , +357 , +26945 , +929 , +16495 , +-8341 , +-1149 , +-13521 , +30685 , +13643 , +3647 , +-2601 , +3105 , +3545 , +-31067 , +28105 , +22643 , +16243 , +-24419 , +-25101 , +-1835 , +8447 , +-2553 , +-14549 , +32419 , +15703 , +13991 , +-8209 , +-11845 , +-17079 , +-22411 , +-2401 , +-27131 , +-16365 , +2161 , +-29137 , +28053 , +23117 , +-7161 , +-4769 , +28475 , +29551 , +727 , +-10119 , +-22109 , +14789 , +-1765 , +-21115 , +2795 , +25823 , +31353 , +23297 , +-31563 , +-363 , +-31399 , +10521 , +-15159 , +-5513 , +-319 , +-12961 , +23071 , +-7225 , +-10577 , +-16121 , +-24951 , +10743 , +19685 , +20887 , +15549 , +-27757 , +28243 , +25639 , +-21775 , +16327 , +25311 , +25363 , +29173 , +-25007 , +-23611 , +20021 , +-26425 , +1529 , +-19855 , +26017 , +3251 , +-28281 , +26573 , +26327 , +24029 , +31553 , +29733 , +-11137 , +-22421 , +-20769 , +10103 , +16539 , +523 , +-13821 , +6735 , +4427 , +17433 , +17199 , +-12517 , +-18441 , +-30159 , +-4285 , +-7161 , +-11501 , +15685 , +-25231 , +-4777 , +12873 , +825 , +435 , +-28619 , +13637 , +27385 , +-23097 , +-2541 , +31959 , +-21229 , +6313 , +12415 , +26299 , +22733 , +5249 , +-23171 , +19405 , +17849 , +-11481 , +7259 , +-1863 , +-24103 , +18705 , +-31989 , +22849 , +29739 , +32467 , +1025 , +-12823 , +27589 , +-16111 , +-31617 , +9267 , +21361 , +-8453 , +9077 , +-22181 , +445 , +12103 , +-12069 , +20359 , +7579 , +-27749 , +-27261 , +23943 , +-28811 , +12957 , +-23695 , +-24309 , +-2363 , +8273 , +-14661 , +-25773 , +-981 , +-21209 , +20183 , +-24461 , +-10227 , +-27803 , +2169 , +24837 , +-6749 , +-17629 , +24555 , +-10655 , +-25957 , +-13115 , +17377 , +2387 , +-17621 , +18931 , +-7979 , +-21673 , +8867 , +25867 , +-13091 , +-1453 , +-1899 , +20257 , +-17405 , +-6459 , +-21923 , +13429 , +21791 , +-2937 , +-32447 , +-24731 , +16173 , +-12801 , +11527 , +31211 , +-221 , +473 , +6929 , +26007 , +-16817 , +-7357 , +-3603 , +-24067 , +-28373 , +1181 , +2419 , +14779 , +22193 , +17593 , +14173 , +-21019 , +-14271 , +-6517 , +-14243 , +-10241 , +-11805 , +-21653 , +-589 , +14975 , +-13513 , +26565 , +-6327 , +30647 , +-22341 , +2643 , +-3509 , +10069 , +-16981 , +-29227 , +1085 , +-15781 , +9817 , +-12981 , +31379 , +-8809 , +29439 , +-19797 , +-6457 , +27283 , +-21727 , +-18405 , +-8455 , +14107 , +16731 , +13219 , +-17669 , +25383 , +4035 , +25967 , +-27147 , +1377 , +-2891 , +-16259 , +27765 , +-18929 , +10293 , +26079 , +-20727 , +14483 , +-7739 , +19045 , +8537 , +-1181 , +26297 , +-281 , +23999 , +-22913 , +6415 , +-27925 , +-10921 , +28775 , +-24879 , +-30227 , +-23387 , +29083 , +-17953 , +23305 , +5281 , +-20855 , +-6065 , +29503 , +8277 , +4107 , +25925 , +12833 , +-10509 , +605 , +-23991 , +-9965 , +-3473 , +-3437 , +-12001 , +-6915 , +31381 , +25243 , +-27105 , +-13689 , +-13153 , +-13403 , +31501 , +-29491 , +-8367 , +1835 , +14965 , +9887 , +7057 , +30297 , +31611 , +15919 , +-24195 , +-24555 , +5691 , +6987 , +20993 , +32109 , +30875 , +22559 , +29941 , +11407 , +17319 , +17505 , +21423 , +16969 , +-18071 , +29451 , +-24545 , +29173 , +4923 , +27291 , +99 , +-15363 , +22693 , +-4157 , +-26905 , +4811 , +-12615 , +-7517 , +-8465 , +1601 , +-26657 , +9857 , +-19007 , +17851 , +-25549 , +-29691 , +-6101 , +6261 , +21091 , +13801 , +7339 , +11417 , +-32513 , +28727 , +29177 , +-17247 , +-28591 , +29185 , +-21975 , +-13471 , +-31555 , +405 , +14911 , +-20875 , +14731 , +29499 , +5703 , +-24777 , +-2991 , +-1433 , +-28177 , +-30139 , +-5959 , +-14987 , +11675 , +-10903 , +-15125 , +-9253 , +-22525 , +21527 , +-8623 , +14059 , +11331 , +8807 , +5889 , +3333 , +-2949 , +-24947 , +5003 , +-14517 , +14561 , +14543 , +-9899 , +-26141 , +-15521 , +20987 , +28013 , +13991 , +-93 , +-8093 , +-29719 , +-28067 , +-8257 , +4949 , +4029 , +13429 , +27965 , +-21231 , +8975 , +2365 , +24247 , +19263 , +-12269 , +11929 , +-30227 , +21995 , +2653 , +-19651 , +-30107 , +-13059 , +-14139 , +-16291 , +29817 , +-21459 , +18355 , +9719 , +-4877 , +7553 , +3065 , +-16013 , +32041 , +12861 , +-16843 , +-18703 , +31633 , +23137 , +30361 , +-2827 , +24791 , +21155 , +-28333 , +-1379 , +-7815 , +-16161 , +-23719 , +22627 , +-23587 , +14101 , +-22587 , +-7349 , +-5399 , +-11039 , +-593 , +4775 , +3359 , +16239 , +20103 , +-32707 , +4141 , +10231 , +-2845 , +787 , +16651 , +6323 , +-1053 , +23705 , +8339 , +-16295 , +20221 , +-3997 , +31895 , +29711 , +12901 , +32361 , +3447 , +8167 , +-25647 , +22453 , +28733 , +24021 , +-31771 , +1445 , +-10953 , +-5337 , +-14341 , +-9321 , +15109 , +13441 , +-19327 , +27433 , +-29125 , +12363 , +-12327 , +21239 , +-31367 , +16311 , +-605 , +24511 , +-28169 , +20011 , +-28005 , +30767 , +-17233 , +-6333 , +28917 , +19217 , +-14365 , +31557 , +-15057 , +14339 , +27971 , +-30183 , +31599 , +27317 , +4221 , +-4927 , +1365 , +-24419 , +-16807 , +-2731 , +-30637 , +-28373 , +-12207 , +-25231 , +3211 , +28811 , +3233 , +31545 , +-15325 , +-31529 , +-25875 , +-19255 , +799 , +17867 , +-23219 , +-21965 , +-77 , +-251 , +-533 , +-29203 , +-3295 , +27835 , +-24293 , +-23597 , +-19691 , +19183 , +27629 , +24225 , +23407 , +20265 , +-8371 , +5083 , +8361 , +-31567 , +18329 , +32341 , +-7511 , +-31933 , +8373 , +-14551 , +-26601 , +30799 , +3747 , +19747 , +10811 , +31397 , +17059 , +-7477 , +-9905 , +8375 , +-23359 , +-17717 , +-16041 , +-11953 , +-26123 , +-17675 , +-26749 , +-14655 , +-16715 , +28083 , +14329 , +15533 , +28177 , +18945 , +7223 , +-16341 , +27975 , +-30231 , +20963 , +6797 , +-27677 , +18293 , +2605 , +-12649 , +-14263 , +6185 , +22943 , +-24531 , +10463 , +-8451 , +16505 , +7829 , +-18027 , +3281 , +-27775 , +-22227 , +28163 , +1899 , +-8851 , +-6499 , +-6137 , +-4377 , +-12123 , +9877 , +-15661 , +31163 , +25001 , +-23031 , +-15733 , +7965 , +8681 , +11739 , +-16291 , +18449 , +-3307 , +1057 , +-21741 , +-16693 , +-21763 , +-22571 , +29747 , +5305 , +-16415 , +20241 , +16789 , +14063 , +-27311 , +-24635 , +-17547 , +-5851 , +-32385 , +-25871 , +-12527 , +24369 , +8991 , +12887 , +-16955 , +-21259 , +8115 , +-32581 , +-12139 , +17633 , +-7573 , +7323 , +-30639 , +15593 , +29569 , +32091 , +-24021 , +-28169 , +1 , +-5365 , +-14129 , +8685 , +10807 , +-3943 , +18929 , +-27629 , +-17805 , +-14199 , +-22407 , +-6121 , +-14227 , +-17363 , +25349 , +-7299 , +-2791 , +-4771 , +-14571 , +5537 , +-13055 , +-32077 , +10387 , +-21979 , +-5349 , +-20931 , +22001 , +-15889 , +-3043 , +-31051 , +-24377 , +-30047 , +607 , +11071 , +21217 , +-13171 , +-26069 , +10653 , +-6181 , +10033 , +-16743 , +-24859 , +-7361 , +-19411 , +16101 , +2753 , +-25837 , +18621 , +-11195 , +19739 , +-12555 , +3503 , +10311 , +-14751 , +25525 , +-23081 , +23461 , +4657 , +7019 , +-25837 , +9627 , +21663 , +-24045 , +18869 , +9155 , +-28191 , +-14695 , +645 , +29293 , +2189 , +14467 , +-25803 , +9587 , +1615 , +-24069 , +9561 , +-18027 , +12063 , +30313 , +993 , +5713 , +-20737 , +19859 , +5901 , +14387 , +20017 , +9005 , +14057 , +7099 , +-8215 , +21233 , +-19389 , +171 , +907 , +-22209 , +6181 , +-25119 , +-20381 , +24617 , +-9785 , +23983 , +-31781 , +24855 , +17169 , +15027 , +18993 , +-23847 , +15243 , +21809 , +-17995 , +-967 , +12761 , +-10005 , +-10117 , +17185 , +-9297 , +19317 , +1175 , +4139 , +1099 , +-9457 , +5843 , +-333 , +8563 , +-14849 , +-26649 , +-16003 , +-6433 , +29287 , +-32717 , +-7231 , +-28605 , +20125 , +31221 , +-28983 , +6581 , +4613 , +7679 , +11273 , +7859 , +30311 , +8947 , +15281 , +-26731 , +455 , +-2307 , +14287 , +11649 , +-1859 , +-17407 , +-9251 , +23789 , +4429 , +7777 , +-22305 , +7823 , +-445 , +-475 , +-515 , +20183 , +27395 , +25283 , +-25201 , +-29721 , +32746 , +-20149 , +-2359 , +-15855 , +-30947 , +-25305 , +3005 , +7873 , +-13849 , +-13493 , +19459 , +-24061 , +16019 , +-24587 , +15307 , +1653 , +7867 , +12001 , +16245 , +14271 , +-471 , +-14849 , +25511 , +3977 , +31275 , +2739 , +31213 , +-28423 , +6505 , +8577 , +25029 , +23207 , +29765 , +-10161 , +-10683 , +-30957 , +15783 , +19225 , +-26589 , +-19549 , +17505 , +-1237 , +19549 , +26133 , +1279 , +-12077 , +-6329 , +-30597 , +-7137 , +-91 , +-991 , +13231 , +-22193 , +17697 , +-14023 , +-32687 , +21091 , +31233 , +22653 , +-27081 , +-10425 , +-4643 , +-29549 , +-19857 , +-2465 , +-31377 , +29293 , +23471 , +-24233 , +4935 , +-20627 , +32077 , +8837 , +-7421 , +25585 , +-24389 , +-27973 , +-4343 , +23153 , +-637 , +-18535 , +-18243 , +-9453 , +-26705 , +-7565 , +15159 , +-1081 , +9429 , +-6241 , +-3969 , +-15135 , +-4223 , +-14771 , +24903 , +551 , +28977 , +6373 , +14107 , +6261 , +-9519 , +-6693 , +18719 , +-18485 , +17323 , +-5885 , +-25787 , +-15889 , +-18715 , +-4745 , +-14331 , +15739 , +-10373 , +20441 , +-13159 , +-21127 , +21167 , +16707 , +-20563 , +-23167 , +-9975 , +-7541 , +-1377 , +-3517 , +-10809 , +-12245 , +32049 , +11953 , +-25379 , +13963 , +21445 , +7559 , +18283 , +1761 , +-22511 , +-24725 , +-2385 , +25741 , +9311 , +-25211 , +-19069 , +-7453 , +-28359 , +-16237 , +-20393 , +-21617 , +-27221 , +19589 , +-1121 , +9583 , +4599 , +-1901 , +-24359 , +13275 , +3279 , +7129 , +10745 , +-22895 , +-21751 , +1635 , +25443 , +-3585 , +10715 , +-8489 , +-29587 , +-14307 , +21391 , +-9089 , +-20921 , +-22065 , +26305 , +13797 , +20867 , +2223 , +-6127 , +-25621 , +18947 , +4461 , +22113 , +-26265 , +-11921 , +-18777 , +14725 , +-20685 , +-22473 , +5181 , +-31871 , +-31537 , +29957 , +-15569 , +-17345 , +1389 , +6835 , +13807 , +-4147 , +-15979 , +15557 , +-19139 , +-10489 , +27957 , +-21913 , +5499 , +13019 , +-11715 , +-6183 , +-17269 , +-11775 , +4017 , +-29071 , +4127 , +14635 , +32077 , +-17651 , +-7015 , +26051 , +2957 , +17171 , +1121 , +-23775 , +30805 , +-6179 , +26549 , +-5563 , +12285 , +16571 , +13583 , +-15349 , +13041 , +-27801 , +8689 , +9705 , +-10305 , +21243 , +19523 , +16671 , +-15937 , +32113 , +9255 , +-17287 , +-7145 , +-28785 , +32343 , +20603 , +-5785 , +18285 , +26361 , +15909 , +-10285 , +-4771 , +-13065 , +-26589 , +18845 , +23409 , +-25131 , +-10615 , +4677 , +31597 , +27149 , +-21241 , +-22503 , +29503 , +10729 , +-25689 , +10829 , +14325 , +15059 , +12795 , +23449 , +-16579 , +11571 , +31973 , +26957 , +-30895 , +31431 , +-26945 , +-10519 , +-21125 , +-17035 , +-11751 , +26163 , +19203 , +32431 , +30455 , +21463 , +20657 , +14139 , +-30085 , +-16267 , +-26439 , +-26727 , +-26321 , +-25027 , +26431 , +-20267 , +-1107 , +-1267 , +4421 , +5599 , +-29215 , +-259 , +557 , +-29343 , +20665 , +30593 , +-10333 , +27675 , +-4505 , +18173 , +-13271 , +12223 , +-26351 , +-28449 , +10233 , +29241 , +15369 , +-1487 , +-3955 , +-12903 , +30605 , +-10567 , +-29041 , +-14237 , +24309 , +-25969 , +-23977 , +25189 , +29041 , +26671 , +-16677 , +23059 , +-15041 , +4889 , +17199 , +-15779 , +-8859 , +28389 , +2681 , +263 , +8677 , +17113 , +10855 , +-12925 , +29307 , +-17915 , +30763 , +18501 , +-13363 , +-22563 , +3059 , +-15711 , +30509 , +31047 , +31455 , +20253 , +-17209 , +10815 , +-139 , +-19893 , +-28579 , +6117 , +18599 , +-13277 , +12421 , +1823 , +10037 , +4571 , +12373 , +14247 , +-11841 , +12345 , +-7257 , +-9303 , +-2269 , +28275 , +-23097 , +-13353 , +22411 , +-5757 , +-3405 , +-12279 , +7125 , +16383 , +-13621 , +21579 , +-23657 , +-14733 , +22805 , +-7557 , +397 , +-9165 , +21477 , +14431 , +-8553 , +30909 , +4131 , +21055 , +-1231 , +-30329 , +-16643 , +16889 , +1895 , +14431 , +-12771 , +10909 , +2385 , +-19905 , +-7579 , +14469 , +2569 , +-31069 , +25895 , +-4633 , +16675 , +14183 , +7129 , +-25609 , +30377 , +4375 , +-15793 , +24693 , +-11381 , +-7217 , +8055 , +32715 , +-10083 , +-19313 , +-29557 , +29607 , +-19441 , +-235 , +26315 , +-31223 , +-21153 , +-24531 , +25529 , +20711 , +-8227 , +153 , +16327 , +-1475 , +-1133 , +-26537 , +-16483 , +-31579 , +17613 , +25223 , +31685 , +3193 , +-30203 , +22969 , +28391 , +18779 , +18529 , +-27439 , +-16763 , +11355 , +-18775 , +7245 , +-18901 , +-3447 , +-4417 , +4145 , +27953 , +-31735 , +-4709 , +13905 , +3817 , +30647 , +-24135 , +-30419 , +15707 , +-27857 , +-16355 , +-8373 , +-31101 , +8053 , +-26685 , +17165 , +25599 , +-5629 , +-25701 , +4875 , +-17077 , +19039 , +-9473 , +-32027 , +25723 , +1087 , +8363 , +-27483 , +-31373 , +24083 , +-4043 , +8847 , +32669 , +17449 , +6663 , +4475 , +8733 , +-12229 , +7637 , +17327 , +-15725 , +3469 , +5011 , +25651 , +9803 , +20871 , +21237 , +8877 , +-18953 , +195 , +-28325 , +-2119 , +-3093 , +6319 , +-20907 , +2495 , +-21299 , +21925 , +-6509 , +19015 , +-9515 , +19831 , +-23203 , +25565 , +-19585 , +22167 , +-21355 , +-28581 , +-10299 , +-27739 , +-13537 , +-4149 , +7899 , +-1145 , +-9753 , +30651 , +-3229 , +-18935 , +14161 , +4885 , +-17633 , +-23317 , +31027 , +2679 , +16697 , +29053 , +-29359 , +19723 , +-25877 , +-2371 , +79 , +-19997 , +32447 , +24547 , +-23765 , +-13877 , +-31161 , +-11387 , +18229 , +22945 , +21075 , +803 , +-14197 , +5429 , +2471 , +30539 , +7945 , +-19817 , +10811 , +-4051 , +-21047 , +-4619 , +9445 , +-19799 , +-30441 , +-27151 , +-17501 , +6649 , +-5401 , +14461 , +-26047 , +17849 , +-29231 , +-30679 , +8609 , +15497 , +9867 , +4617 , +-8857 , +23329 , +-19497 , +23549 , +-25547 , +26599 , +-8955 , +921 , +-23961 , +8971 , +5865 , +-2701 , +-4285 , +-21727 , +-14515 , +21757 , +3259 , +-29137 , +7923 , +11483 , +24985 , +-8367 , +-7677 , +32707 , +32323 , +10441 , +-10487 , +-11829 , +23533 , +-28007 , +5231 , +-15801 , +1613 , +5533 , +-7063 , +-12769 , +-22563 , +4895 , +30591 , +-11605 , +28807 , +10487 , +7541 , +26883 , +20205 , +-26089 , +15565 , +-20003 , +-3059 , +9133 , +-16199 , +-22045 , +6541 , +-26953 , +13719 , +-24949 , +-32159 , +3611 , +19431 , +-9355 , +-20975 , +6465 , +-1595 , +10293 , +-18837 , +-19673 , +-3361 , +11961 , +20407 , +24061 , +-20759 , +25113 , +25467 , +15165 , +-18785 , +32245 , +15783 , +30781 , +28471 , +13893 , +-15281 , +-6319 , +7255 , +12215 , +-19987 , +7513 , +20627 , +-10103 , +18951 , +-5151 , +-31653 , +14809 , +-32643 , +-28751 , +2945 , +22915 , +2861 , +27633 , +8485 , +17527 , +22071 , +-22095 , +16947 , +22931 , +-11597 , +-27635 , +-29097 , +-4871 , +-26655 , +2245 , +26495 , +-9243 , +-12559 , +-10931 , +1985 , +10507 , +-7895 , +22633 , +17893 , +14699 , +-8023 , +16457 , +16469 , +-13913 , +9123 , +-17123 , +9871 , +13281 , +-30201 , +41 , +-9939 , +7691 , +26061 , +24425 , +-26549 , +10441 , +32155 , +-2663 , +30861 , +-18755 , +8717 , +5853 , +-10607 , +25709 , +-12959 , +29135 , +-32541 , +18573 , +17841 , +13589 , +-12159 , +-27423 , +-17993 , +4485 , +26563 , +-20591 , +-12303 , +28847 , +-12319 , +23807 , +8297 , +-18431 , +-21275 , +4647 , +4327 , +-4011 , +-16349 , +1899 , +-29785 , +-21999 , +28977 , +9205 , +-30567 , +30137 , +5471 , +22925 , +-7921 , +-14071 , +-21071 , +-30483 , +26103 , +-22385 , +21331 , +-31077 , +-20323 , +-4669 , +2711 , +22595 , +-23081 , +-32355 , +13415 , +17039 , +9151 , +25513 , +22081 , +-16521 , +-11787 , +-10839 , +28843 , +-2775 , +-29627 , +-31837 , +-25549 , +-15025 , +24565 , +131 , +9433 , +3319 , +-27797 , +28457 , +-9193 , +11483 , +-20375 , +-20473 , +-9907 , +29257 , +2255 , +-5323 , +24769 , +30833 , +-21051 , +-12525 , +10513 , +6717 , +20861 , +23375 , +-18643 , +3247 , +2919 , +-28529 , +2259 , +-17997 , +30439 , +-9087 , +17793 , +29563 , +9363 , +-26001 , +-21011 , +-26537 , +-10779 , +-32671 , +-32251 , +-16633 , +31609 , +20651 , +5471 , +-31845 , +28091 , +-22517 , +-13775 , +3271 , +-10195 , +16449 , +10957 , +-7749 , +-12527 , +32549 , +-9827 , +10363 , +1965 , +-21955 , +-28789 , +-6983 , +-21765 , +-26919 , +-7923 , +20267 , +15073 , +11949 , +399 , +-8865 , +495 , +-24353 , +15727 , +4641 , +1429 , +-26709 , +25207 , +-20925 , +-3373 , +19059 , +-12587 , +23033 , +-643 , +-15271 , +24207 , +24251 , +10733 , +14169 , +-4227 , +-30321 , +-1735 , +-19489 , +-19517 , +-12821 , +-4111 , +7389 , +2759 , +-16117 , +-4273 , +-20373 , +6315 , +-31295 , +-9991 , +-811 , +-11199 , +16603 , +29997 , +-26053 , +-15479 , +-21011 , +4997 , +-32609 , +7841 , +-4939 , +-8665 , +21131 , +-28349 , +7913 , +22399 , +29725 , +21181 , +-4455 , +-1413 , +18085 , +-13207 , +-27397 , +30011 , +24765 , +-31073 , +31181 , +30287 , +6875 , +-27597 , +811 , +-31633 , +18547 , +13423 , +-21023 , +-10063 , +30085 , +-7295 , +1611 , +-19647 , +-32579 , +-28287 , +-26197 , +8855 , +-5627 , +14299 , +30713 , +-19145 , +-21089 , +-31407 , +24137 , +3551 , +961 , +-10129 , +8597 , +-11707 , +-9049 , +16515 , +29217 , +-5041 , +28973 , +-17129 , +-28853 , +-27195 , +-16409 , +29669 , +997 , +9875 , +20159 , +5457 , +783 , +7543 , +2303 , +10087 , +32137 , +23361 , +-28167 , +28487 , +-30823 , +2183 , +-7151 , +12583 , +10061 , +7641 , +-27549 , +32453 , +9069 , +1667 , +-27957 , +19559 , +-5447 , +21951 , +-16753 , +-31673 , +11221 , +1641 , +10083 , +-12139 , +13721 , +15681 , +21269 , +21481 , +-18459 , +1433 , +24467 , +2115 , +-765 , +149 , +22933 , +-907 , +13175 , +32477 , +-24669 , +10285 , +-8103 , +-809 , +-22087 , +3675 , +4655 , +31077 , +3421 , +-6601 , +27713 , +-24817 , +5681 , +-32079 , +-23945 , +14285 , +-13547 , +-20371 , +32169 , +-7381 , +-18505 , +16953 , +129 , +-30955 , +21163 , +-31741 , +-15161 , +29439 , +22539 , +19545 , +10567 , +-21079 , +-3965 , +25685 , +26651 , +25931 , +-779 , +32289 , +11663 , +-1447 , +24199 , +29157 , +-14483 , +-25423 , +-27835 , +-1719 , +-31521 , +-3235 , +32559 , +-24223 , +24263 , +-14653 , +-17961 , +11055 , +-32625 , +9563 , +14455 , +4763 , +-13947 , +-1293 , +-21367 , +29663 , +-8521 , +-28069 , +28385 , +1935 , +-6845 , +-1629 , +20293 , +27909 , +32057 , +-16177 , +8319 , +31585 , +5353 , +2835 , +22779 , +-12037 , +11457 , +27279 , +-24607 , +22877 , +-23643 , +32375 , +-24923 , +447 , +-23613 , +-13347 , +-4315 , +21495 , +18413 , +-14111 , +32321 , +12281 , +-28297 , +-28059 , +15089 , +23499 , +-14717 , +17487 , +27099 , +8697 , +-12063 , +27703 , +30065 , +-18789 , +-19095 , +-29017 , +-28031 , +-25927 , +-17461 , +14029 , +4441 , +-18861 , +24305 , +-30537 , +-19633 , +24789 , +-25141 , +-12791 , +-8985 , +4105 , +-15183 , +-2763 , +-925 , +-6761 , +18231 , +31541 , +-803 , +-11529 , +-15737 , +-18497 , +7653 , +-29715 , +-16331 , +1027 , +1933 , +-127 , +20891 , +-19493 , +29449 , +-28813 , +7085 , +22923 , +16327 , +-16845 , +-5287 , +19445 , +19717 , +-29853 , +27221 , +-6321 , +-4117 , +14017 , +3197 , +-32669 , +24093 , +-24151 , +-12889 , +-32197 , +-6949 , +1797 , +-10239 , +-20891 , +17557 , +16849 , +-21789 , +-2143 , +2309 , +23045 , +-9683 , +-4321 , +13761 , +-28649 , +-489 , +15415 , +8029 , +-24851 , +-5231 , +5791 , +-14085 , +27737 , +-13035 , +15137 , +-24991 , +-8177 , +13315 , +21209 , +-7521 , +6429 , +-17801 , +17641 , +-21737 , +-17945 , +19873 , +27311 , +-16613 , +-32107 , +-18273 , +7809 , +13319 , +-3559 , +-30765 , +-25373 , +7643 , +9625 , +-9029 , +-20415 , +11339 , +-20881 , +19015 , +7973 , +-29605 , +-26971 , +20921 , +21741 , +-6531 , +19425 , +-26637 , +15625 , +-12003 , +-22299 , +27479 , +-14163 , +-28735 , +-10871 , +-19943 , +5901 , +30373 , +13609 , +-9961 , +-18413 , +-13625 , +7079 , +-9413 , +409 , +30343 , +-32539 , +-1723 , +-4325 , +27327 , +27309 , +14891 , +-31753 , +1115 , +17723 , +19441 , +10275 , +20075 , +-7637 , +-8961 , +-2207 , +30913 , +22003 , +1527 , +31479 , +23307 , +27611 , +-9195 , +-14863 , +23651 , +-6021 , +-15365 , +27593 , +-26769 , +21157 , +-25323 , +18863 , +-27917 , +31469 , +23911 , +-26061 , +26347 , +31123 , +13805 , +19335 , +-23001 , +23303 , +-10387 , +4149 , +-7077 , +13017 , +-4141 , +8785 , +12481 , +-13007 , +30729 , +12601 , +23845 , +-18735 , +-5561 , +29129 , +27017 , +-11395 , +-1797 , +18707 , +-5069 , +15105 , +-8687 , +-30315 , +-12721 , +-27487 , +-9519 , +-17671 , +13565 , +-22253 , +61 , +25667 , +-4369 , +25339 , +-10275 , +-12143 , +15999 , +-2595 , +1315 , +17993 , +22601 , +25493 , +30521 , +10465 , +28221 , +6231 , +17249 , +-763 , +-24765 , +-10977 , +-16441 , +-14499 , +-23741 , +-24407 , +-2337 , +-16963 , +-29745 , +-2321 , +2869 , +-15649 , +28967 , +-4323 , +-23605 , +-23395 , +25573 , +-28665 , +-1807 , +-27481 , +31495 , +2853 , +-26213 , +-11333 , +22153 , +5645 , +-32455 , +1887 , +-4475 , +6753 , +-27119 , +12823 , +1729 , +29777 , +10257 , +-14821 , +7887 , +30607 , +-30673 , +-13675 , +13981 , +29387 , +20543 , +-29869 , +16281 , +27039 , +29511 , +-13565 , +-28103 , +-17125 , +-20903 , +-4121 , +16417 , +31397 , +29167 , +8981 , +-25933 , +-30329 , +-9285 , +-9691 , +-14805 , +28379 , +-9979 , +-15507 , +-20171 , +-8191 , +2437 , +-29509 , +18693 , +-9309 , +31409 , +31885 , +16879 , +-32479 , +-11357 , +21957 , +19585 , +24205 , +2401 , +32229 , +3865 , +27941 , +13255 , +-8765 , +-17409 , +29769 , +-25907 , +29897 , +-25609 , +2805 , +-27541 , +5793 , +25953 , +-4171 , +19185 , +19319 , +-18483 , +-4317 , +981 , +-13649 , +-27627 , +4309 , +-233 , +-30697 , +10481 , +17123 , +-30963 , +-13401 , +-13295 , +15315 , +18635 , +19379 , +30647 , +-13545 , +-29465 , +-15959 , +-23345 , +20485 , +26853 , +-3771 , +-9853 , +-28857 , +-32515 , +-26045 , +-15275 , +-24861 , +29315 , +19623 , +15291 , +8355 , +32435 , +-26781 , +-1487 , +-31979 , +-29171 , +-30303 , +28371 , +-32511 , +9265 , +-411 , +31351 , +-26781 , +23601 , +-21793 , +28993 , +-22047 , +-31381 , +26379 , +14531 , +-29243 , +30949 , +-22279 , +-9593 , +-19603 , +16159 , +-21891 , +25401 , +-22957 , +7787 , +12651 , +26159 , +-25741 , +-22069 , +29261 , +-631 , +-14767 , +-6075 , +1435 , +-24889 , +-21397 , +11453 , +26485 , +-25627 , +12077 , +-18875 , +-1577 , +-22295 , +-31629 , +-20219 , +343 , +15881 , +-10887 , +-20607 , +-27563 , +11831 , +-17321 , +13439 , +-2885 , +19005 , +22515 , +25945 , +19507 , +26711 , +11907 , +31951 , +17111 , +-22453 , +-27013 , +5745 , +26741 , +19453 , +-8689 , +-5537 , +-6079 , +-887 , +-5855 , +4537 , +32523 , +-11297 , +32189 , +27489 , +11261 , +723 , +-2283 , +14695 , +-27701 , +27583 , +-26893 , +-28975 , +-29069 , +2447 , +11701 , +-23043 , +-10385 , +31589 , +20673 , +-18575 , +22645 , +-29527 , +-10365 , +26941 , +1697 , +4515 , +-10529 , +28363 , +-13763 , +-3947 , +-11475 , +28985 , +26861 , +-20655 , +24751 , +-10189 , +-5523 , +23889 , +-5499 , +-29881 , +28617 , +12879 , +-10189 , +17347 , +-2801 , +-18081 , +-13943 , +-30969 , +-2671 , +-8057 , +8481 , +-7841 , +27285 , +-15151 , +-27303 , +31069 , +7309 , +-27927 , +-51 , +-27729 , +-16681 , +21559 , +9029 , +8057 , +-12821 , +111 , +-24521 , +-7383 , +-22503 , +-21583 , +-12355 , +25041 , +-10049 , +10521 , +-17145 , +4357 , +3587 , +-1567 , +-2721 , +-2265 , +-20217 , +-7953 , +26255 , +19015 , +-26457 , +-3339 , +1005 , +10109 , +-12629 , +31491 , +27077 , +-1349 , +-8321 , +-29791 , +14165 , +-20699 , +-21387 , +-27541 , +22343 , +16369 , +14447 , +-11229 , +-4439 , +-15945 , +26397 , +-181 , +10847 , +31815 , +9917 , +-3265 , +-23771 , +11533 , +-957 , +-12853 , +-28675 , +2525 , +27165 , +16707 , +32557 , +-25519 , +10599 , +32027 , +-12873 , +3487 , +-21081 , +-31997 , +-27313 , +-1295 , +-5379 , +16501 , +18639 , +27199 , +-10529 , +17625 , +-18629 , +-2139 , +-25771 , +27671 , +-21205 , +-11463 , +-2899 , +21935 , +-4915 , +-22679 , +-20047 , +77 , +-19365 , +-49 , +-12699 , +25069 , +-29939 , +18567 , +8501 , +21607 , +-29545 , +-501 , +4797 , +-20853 , +-5343 , +9611 , +22513 , +-7749 , +-8257 , +-23103 , +9947 , +-3069 , +-16031 , +-26547 , +-8745 , +11949 , +31321 , +11147 , +-27323 , +22877 , +5193 , +11499 , +-27707 , +-9819 , +-28007 , +-11315 , +7407 , +-28893 , +-11399 , +-6961 , +-28027 , +-15341 , +-20655 , +-14929 , +24627 , +2665 , +3775 , +-26205 , +-22079 , +23919 , +12037 , +-473 , +13265 , +24529 , +-13041 , +-32673 , +32527 , +3643 , +28381 , +25325 , +-29197 , +-16775 , +-31869 , +-13243 , +19695 , +-15615 , +-28251 , +-2681 , +5421 , +-29933 , +11363 , +29143 , +16837 , +-26801 , +-6439 , +9787 , +20341 , +6865 , +-491 , +2537 , +32477 , +-24385 , +-3691 , +18209 , +28977 , +-29073 , +-15823 , +-11123 , +-18575 , +-9741 , +4003 , +7953 , +-13273 , +-13003 , +-13199 , +-9181 , +28571 , +11667 , +-16271 , +-25427 , +-8565 , +-24595 , +-28231 , +14419 , +-9371 , +-24243 , +-29669 , +-22175 , +503 , +-5137 , +-8427 , +28941 , +23991 , +-24355 , +-30117 , +7263 , +-17813 , +3603 , +-20295 , +387 , +-22677 , +26883 , +-30307 , +-12893 , +-23213 , +21953 , +-22271 , +-1223 , +30269 , +-28023 , +-10769 , +-14097 , +2175 , +-24603 , +10095 , +-14095 , +-3115 , +-17091 , +-24569 , +-24371 , +297 , +4595 , +-81 , +4543 , +-19267 , +23289 , +1097 , +-7791 , +21233 , +-2839 , +-12137 , +-17419 , +22383 , +-25955 , +-20039 , +-23467 , +-10523 , +-20405 , +-1247 , +4147 , +-15547 , +29461 , +12555 , +16893 , +-30093 , +-6875 , +14705 , +-927 , +1927 , +-12723 , +-13423 , +9777 , +15991 , +-22257 , +-10797 , +30383 , +-9631 , +-11199 , +4687 , +-15769 , +-6605 , +-7903 , +-32325 , +143 , +-18455 , +22001 , +1259 , +-24359 , +-31155 , +-17147 , +-13117 , +18885 , +-24289 , +22629 , +-10059 , +-26745 , +-15397 , +20963 , +15281 , +-3243 , +31465 , +-16465 , +24485 , +6975 , +4949 , +21873 , +-143 , +29325 , +3345 , +6631 , +3933 , +-19823 , +-30819 , +-1809 , +19477 , +5125 , +-24241 , +-30163 , +-22497 , +-30501 , +16637 , +-7139 , +20441 , +7837 , +16959 , +-11349 , +31713 , +8509 , +31781 , +20555 , +-13793 , +5753 , +-26005 , +-31599 , +21815 , +10659 , +16689 , +17227 , +17015 , +8201 , +29501 , +16665 , +-415 , +28097 , +-19805 , +-5507 , +-8301 , +-31995 , +-11253 , +11905 , +26697 , +-5617 , +-925 , +5573 , +-8627 , +19817 , +-16107 , +32277 , +29051 , +-303 , +-7485 , +-11635 , +-22357 , +5759 , +-25987 , +6181 , +19763 , +-15599 , +-3715 , +9933 , +-29479 , +-7725 , +6997 , +26377 , +-30131 , +30627 , +19123 , +-5119 , +5159 , +8767 , +-1903 , +16929 , +-17835 , +6689 , +5615 , +-13781 , +-1515 , +-8995 , +8205 , +-1835 , +-18315 , +6127 , +-28893 , +21211 , +-15547 , +-5097 , +-26735 , +32153 , +-28533 , +8503 , +-19033 , +15397 , +-2941 , +25245 , +-1077 , +-20251 , +1553 , +7145 , +-25795 , +-17499 , +-5695 , +3681 , +-24753 , +-13257 , +-17613 , +14021 , +21265 , +385 , +19741 , +7079 , +18843 , +-4837 , +-2113 , +7241 , +-32587 , +-11419 , +11739 , +-10253 , +-27115 , +-16353 , +4141 , +17859 , +-30945 , +18309 , +-18587 , +-27373 , +-3315 , +19423 , +27805 , +28229 , +22451 , +-24673 , +-30639 , +-21473 , +16565 , +-9223 , +12247 , +9641 , +-7877 , +17399 , +-22183 , +-24457 , +4141 , +3093 , +32329 , +-31855 , +7913 , +-8615 , +9311 , +25279 , +-32133 , +-3353 , +25869 , +-1431 , +-14507 , +-27365 , +15219 , +-19479 , +-14453 , +27941 , +24801 , +19043 , +-25725 , +26139 , +16327 , +-22489 , +15669 , +-30575 , +-31443 , +-27525 , +21979 , +-24133 , +2229 , +18941 , +11829 , +3829 , +17155 , +-29325 , +14641 , +-31255 , +2755 , +23855 , +12593 , +12575 , +-12265 , +-12073 , +16315 , +-1767 , +3739 , +16843 , +10167 , +20969 , +11725 , +21495 , +-5601 , +25929 , +-30703 , +-2263 , +-8899 , +-3787 , +-12247 , +-1809 , +-20893 , +-19715 , +-29405 , +16105 , +17953 , +-18711 , +-6949 , +16803 , +1787 , +25667 , +27889 , +-8209 , +24231 , +-25095 , +14909 , +8893 , +8639 , +-12369 , +-6453 , +2413 , +-22017 , +16219 , +-14769 , +-2385 , +12019 , +31579 , +289 , +-10795 , +20797 , +15633 , +-12873 , +-28493 , +20545 , +-26639 , +-32623 , +-4629 , +-7583 , +-13021 , +-21819 , +28623 , +10167 , +-25703 , +-289 , +19379 , +-20659 , +25763 , +13423 , +4555 , +1747 , +-757 , +-24075 , +7547 , +-13101 , +-32087 , +-15015 , +26169 , +-17037 , +3713 , +29415 , +-14115 , +-20057 , +-25771 , +-7479 , +24951 , +2277 , +-1855 , +21747 , +3507 , +30053 , +8913 , +-31827 , +-20571 , +-23849 , +-10727 , +-25477 , +18729 , +-20587 , +-18353 , +-2147 , +-30799 , +-3995 , +-4771 , +17929 , +-10071 , +-2395 , +28933 , +28123 , +-25015 , +20751 , +3305 , +-12973 , +-25363 , +-279 , +17203 , +7245 , +14571 , +3519 , +1443 , +-23499 , +-25359 , +22943 , +-28379 , +1667 , +24793 , +-6199 , +17909 , +18867 , +-14081 , +-11283 , +-11221 , +25783 , +13855 , +18405 , +-27433 , +247 , +-8795 , +30179 , +26525 , +-21819 , +25229 , +3379 , +-4923 , +10325 , +26295 , +8563 , +29659 , +12087 , +-21313 , +-959 , +30403 , +12361 , +-7593 , +-11907 , +-1713 , +29243 , +-21735 , +-12803 , +-23203 , +12921 , +1001 , +30919 , +-1175 , +1195 , +-26939 , +-8509 , +28585 , +10413 , +5919 , +-32515 , +-13405 , +3845 , +16053 , +32083 , +-21437 , +-15395 , +-32021 , +-5707 , +29819 , +30835 , +6819 , +-9767 , +-29615 , +-7393 , +27793 , +1903 , +17533 , +-21053 , +32277 , +-27419 , +13951 , +-21827 , +31381 , +-7537 , +31031 , +2155 , +-5293 , +-4495 , +-32255 , +15135 , +-18491 , +13923 , +2629 , +-10865 , +-31119 , +-27427 , +-11883 , +2009 , +-27077 , +4129 , +-27579 , +-781 , +-22455 , +5111 , +3711 , +-12633 , +4691 , +3559 , +25569 , +18441 , +-28291 , +-7185 , +-15475 , +11887 , +-2637 , +15801 , +-24375 , +18663 , +15737 , +6237 , +22545 , +-8647 , +14923 , +-25465 , +-26443 , +-7857 , +21873 , +-20669 , +27371 , +-31685 , +-29357 , +13605 , +10855 , +27047 , +17245 , +-32756 , +19837 , +11473 , +-3511 , +-8365 , +20649 , +30719 , +25857 , +-13685 , +-24907 , +24957 , +-31245 , +-24907 , +-12983 , +18191 , +24297 , +26103 , +1543 , +-8211 , +24927 , +-24105 , +-3039 , +-17097 , +-28827 , +-28685 , +3699 , +-3853 , +-25369 , +-7885 , +-27117 , +4991 , +-24175 , +23433 , +8569 , +24459 , +29479 , +24099 , +3079 , +7317 , +16465 , +-16343 , +-24023 , +4057 , +-31739 , +495 , +25067 , +11219 , +-5809 , +18609 , +10261 , +13867 , +14257 , +7365 , +-24131 , +-25545 , +-8195 , +25181 , +-9635 , +11761 , +16803 , +-31559 , +15993 , +-2199 , +16535 , +19419 , +-5467 , +-3897 , +17305 , +21705 , +-24791 , +-17221 , +13085 , +-23493 , +12311 , +11637 , +-28519 , +19419 , +-13857 , +-14303 , +15965 , +-26121 , +-7573 , +-287 , +4083 , +-13377 , +11955 , +22847 , +-17687 , +-17933 , +29915 , +17187 , +16443 , +30759 , +-27961 , +-17831 , +26139 , +24181 , +-28369 , +-28043 , +23123 , +30131 , +6977 , +-30881 , +5399 , +-16849 , +12977 , +-10691 , +-27553 , +18665 , +30803 , +-27411 , +-30779 , +-25793 , +-7881 , +-32766 , +-31535 , +21813 , +12343 , +30525 , +23515 , +-28127 , +3101 , +24701 , +-23203 , +-1043 , +2605 , +-22213 , +8145 , +2245 , +-31415 , +7813 , +-2557 , +23377 , +-26243 , +21365 , +-31253 , +-17033 , +7205 , +20001 , +-16375 , +-21115 , +-6023 , +-19677 , +-18635 , +-2573 , +22697 , +10109 , +30973 , +18327 , +17273 , +8483 , +-14721 , +20061 , +22097 , +-8725 , +-14919 , +14461 , +9181 , +-18175 , +17253 , +10299 , +-16607 , +-26905 , +-25257 , +-30699 , +15119 , +-24599 , +-4789 , +-18047 , +-6491 , +277 , +-29629 , +5667 , +-25215 , +-5195 , +-31141 , +-17529 , +1269 , +-29887 , +5927 , +6487 , +3495 , +10721 , +-14713 , +-17903 , +-28247 , +15199 , +15869 , +15941 , +26375 , +-31077 , +28299 , +583 , +-16663 , +9609 , +7939 , +26221 , +10535 , +-27731 , +31465 , +12733 , +5217 , +-31995 , +-17985 , +1841 , +8857 , +-20591 , +30443 , +25961 , +10821 , +26943 , +-11775 , +10467 , +15347 , +3175 , +-4187 , +2225 , +-31661 , +8393 , +-3363 , +1461 , +25305 , +22263 , +1777 , +17499 , +-29487 , +7263 , +-28235 , +18633 , +-27405 , +-591 , +9841 , +3483 , +-20601 , +-28699 , +20783 , +-4831 , +2801 , +6059 , +-11629 , +-10997 , +-27441 , +-22681 , +25655 , +-17237 , +-31859 , +-5211 , +-25211 , +-10837 , +31873 , +24087 , +4359 , +28479 , +-20859 , +5897 , +14919 , +997 , +-18169 , +-2731 , +21533 , +27033 , +-18523 , +21731 , +-20585 , +-25459 , +19017 , +2977 , +-23745 , +7265 , +-3653 , +-6929 , +-21759 , +21467 , +-26433 , +21415 , +-12163 , +801 , +-24157 , +-28021 , +-3109 , +9327 , +20579 , +-5315 , +3371 , +17233 , +-5829 , +23485 , +-453 , +-16809 , +23483 , +21085 , +3307 , +-5297 , +-11669 , +-18377 , +-25081 , +-27135 , +-299 , +555 , +18595 , +-11935 , +31271 , +-32689 , +-9751 , +-27831 , +4677 , +-23567 , +24959 , +4787 , +23397 , +29703 , +-8621 , +24687 , +24103 , +-6105 , +-23559 , +12891 , +-17879 , +25093 , +4225 , +22815 , +5409 , +-667 , +-21809 , +-10151 , +11895 , +-4455 , +16757 , +6503 , +28509 , +-22671 , +8711 , +12433 , +20323 , +-1349 , +249 , +-21307 , +26003 , +-2505 , +-22031 , +-5679 , +32261 , +-21749 , +4257 , +23833 , +-29697 , +-25401 , +-9693 , +-11057 , +-12161 , +3793 , +-2361 , +8621 , +3427 , +-6047 , +25721 , +9001 , +7415 , +26363 , +-20081 , +-20943 , +-14831 , +22375 , +22559 , +18019 , +9377 , +3363 , +-30239 , +8641 , +32473 , +-12189 , +-31615 , +28397 , +-8525 , +-1401 , +1651 , +21981 , +18457 , +30989 , +-939 , +-21733 , +-7313 , +-4335 , +-323 , +-12943 , +-2889 , +11581 , +-18277 , +-22997 , +-2275 , +14413 , +-12795 , +17357 , +-19169 , +-27143 , +23449 , +1861 , +-19185 , +6263 , +-22959 , +-9301 , +-11707 , +-8085 , +5085 , +28789 , +23197 , +-12949 , +889 , +-4563 , +-30553 , +5353 , +-24767 , +7599 , +-19927 , +14259 , +15891 , +31197 , +841 , +3563 , +28129 , +9171 , +7705 , +8575 , +16007 , +12715 , +30391 , +3865 , +-6875 , +20391 , +-15393 , +9637 , +20473 , +11251 , +23559 , +-963 , +-15687 , +-23335 , +-10507 , +13991 , +4963 , +12663 , +-13353 , +12361 , +-24681 , +31997 , +987 , +-14935 , +-28037 , +-21409 , +-1719 , +-2981 , +-27907 , +18065 , +-1255 , +-30337 , +29379 , +14141 , +-13045 , +-26953 , +-2701 , +-7173 , +7233 , +-6753 , +18571 , +-13301 , +-24493 , +8647 , +17347 , +-21879 , +16619 , +-3799 , +2529 , +-27861 , +6107 , +-19679 , +8713 , +371 , +-22601 , +7651 , +-24159 , +21095 , +7913 , +29309 , +32417 , +-24367 , +-177 , +32577 , +-23955 , +31729 , +587 , +10435 , +-10959 , +28847 , +-28317 , +-20139 , +6579 , +-8863 , +-21677 , +30459 , +-28245 , +2039 , +-29267 , +24547 , +-32093 , +-4421 , +-1311 , +-21155 , +-27837 , +-13439 , +29931 , +27985 , +-9929 , +-16025 , +17497 , +16961 , +-12423 , +-21241 , +-23575 , +-17999 , +-13005 , +-28873 , +-5979 , +-5845 , +5395 , +-30157 , +-395 , +-30281 , +5411 , +-5787 , +4413 , +18889 , +-4319 , +11153 , +-17813 , +-29243 , +-7847 , +-30827 , +-29925 , +22255 , +-22535 , +-7273 , +19113 , +-30493 , +28397 , +-18739 , +-15929 , +17813 , +27705 , +-12893 , +27161 , +-26687 , +-17721 , +26751 , +-9653 , +9187 , +-29239 , +-21255 , +18091 , +6069 , +21645 , +-7799 , +-4547 , +4129 , +-6443 , +27593 , +-13225 , +11711 , +20915 , +2345 , +26297 , +4037 , +23767 , +14887 , +4127 , +-4727 , +24693 , +22537 , +30565 , +-31125 , +-31859 , +19729 , +-9459 , +8287 , +-1323 , +26427 , +-18069 , +19671 , +24575 , +15727 , +21807 , +-21443 , +-18019 , +7995 , +-6525 , +26611 , +19319 , +1805 , +-12127 , +-25919 , +-14495 , +-31001 , +-19479 , +24531 , +-2415 , +-22625 , +-19329 , +-16335 , +29563 , +12941 , +-12959 , +14003 , +-29655 , +24005 , +-30729 , +639 , +-6897 , +21211 , +-4041 , +-7 , +-2969 , +-30715 , +7479 , +16449 , +-4601 , +25579 , +9793 , +5933 , +14265 , +9165 , +-9097 , +-10311 , +-493 , +31809 , +8413 , +-2299 , +469 , +-5007 , +12025 , +-12851 , +13747 , +15301 , +-19475 , +-20387 , +17595 , +6703 , +2565 , +-27379 , +-26331 , +23243 , +28895 , +313 , +-1103 , +-16083 , +-26129 , +29873 , +25463 , +-9973 , +24999 , +3009 , +3655 , +-12167 , +3339 , +-28775 , +31099 , +-13147 , +-7229 , +-21169 , +21331 , +-20215 , +32443 , +-29875 , +-823 , +-11993 , +-23753 , +30041 , +-19469 , +-31557 , +619 , +-10499 , +-311 , +5759 , +-19055 , +15493 , +28301 , +1365 , +-12665 , +-28035 , +21409 , +4103 , +-11037 , +23455 , +31187 , +899 , +-30837 , +5459 , +-31419 , +-15483 , +-17715 , +-32099 , +1977 , +-31269 , +-21769 , +5537 , +-6543 , +-18403 , +-25743 , +12181 , +10369 , +-30755 , +6739 , +28475 , +-14937 , +-31387 , +-16259 , +-14895 , +-29267 , +22765 , +-14799 , +-30059 , +-16333 , +597 , +17447 , +17591 , +27919 , +-25767 , +31017 , +25553 , +13605 , +5197 , +-5079 , +-24865 , +-31813 , +-7337 , +-15653 , +12729 , +-10151 , +7707 , +9419 , +-20219 , +14611 , +-2557 , +753 , +-21321 , +25971 , +3821 , +7125 , +-9975 , +-7747 , +-22427 , +-27619 , +-2583 , +29403 , +4447 , +-1119 , +11513 , +8871 , +24171 , +5907 , +7689 , +25799 , +-9615 , +17929 , +21001 , +29703 , +10729 , +-8807 , +19587 , +-32719 , +-26481 , +20339 , +-3179 , +-15267 , +-30305 , +30069 , +-31131 , +7641 , +-32119 , +-9783 , +-9697 , +15217 , +-14289 , +21369 , +5479 , +-691 , +1689 , +-12413 , +-23979 , +7503 , +-1237 , +-24965 , +-28951 , +-18465 , +-26271 , +7837 , +5127 , +-12979 , +-24059 , +6751 , +31473 , +21417 , +9451 , +-19559 , +6455 , +-3827 , +-6881 , +13069 , +-25807 , +-2419 , +6055 , +-27513 , +21763 , +-19595 , +29881 , +10101 , +-11775 , +-18121 , +4977 , +7165 , +23225 , +10163 , +2055 , +21649 , +-22177 , +-26087 , +15499 , +21523 , +-31539 , +-13251 , +31771 , +-24481 , +31219 , +-28561 , +10395 , +29041 , +27609 , +11733 , +-27917 , +1259 , +12815 , +-16581 , +28087 , +28225 , +-605 , +-21891 , +21109 , +15173 , +-17241 , +-14263 , +-11943 , +-15043 , +13335 , +21639 , +879 , +-31101 , +2141 , +16169 , +5983 , +19611 , +27719 , +-2679 , +-12137 , +-24887 , +-20871 , +15415 , +28947 , +12581 , +23919 , +12641 , +1419 , +-17345 , +14827 , +3991 , +-29653 , +4391 , +-20493 , +-14025 , +-4655 , +-15853 , +3657 , +5171 , +16829 , +14195 , +13407 , +-391 , +21461 , +-30333 , +-4397 , +-23875 , +-6835 , +-2455 , +-17817 , +5597 , +-24595 , +19659 , +9587 , +9391 , +13251 , +8939 , +-30747 , +-1437 , +-26791 , +12855 , +18871 , +18255 , +-7567 , +-20633 , +28639 , +81 , +-17603 , +-2283 , +-22571 , +20133 , +-12783 , +26321 , +-30335 , +-14281 , +18343 , +-17729 , +18353 , +-30587 , +-13881 , +-14425 , +-30949 , +16875 , +-11637 , +-5737 , +-27697 , +-8311 , +3609 , +-273 , +-21203 , +-12405 , +-30005 , +18435 , +-24479 , +-29165 , +18425 , +817 , +26969 , +-30593 , +5929 , +7543 , +4671 , +-3761 , +18373 , +-12409 , +-30357 , +-25483 , +5461 , +32617 , +-23065 , +31793 , +20537 , +-16757 , +4695 , +-10653 , +14563 , +-17317 , +22145 , +-13711 , +1413 , +1377 , +-18633 , +16267 , +2641 , +-6443 , +9437 , +-11373 , +-971 , +20151 , +-4015 , +-7569 , +17927 , +-32663 , +32371 , +15841 , +-6075 , +30147 , +-19951 , +-21023 , +-9393 , +17583 , +17507 , +-11919 , +27673 , +24897 , +-15353 , +30711 , +-29853 , +5193 , +29301 , +2841 , +-30857 , +-397 , +-18445 , +8463 , +10333 , +-35 , +26135 , +-12417 , +-22893 , +23593 , +-32585 , +-10543 , +29765 , +29469 , +-15005 , +15885 , +20741 , +-6729 , +-22177 , +30507 , +-24569 , +32707 , +1559 , +-23563 , +30929 , +-16903 , +11293 , +4947 , +27259 , +18575 , +-27491 , +-28879 , +26977 , +14933 , +-5807 , +-27957 , +-8355 , +-29623 , +-25855 , +391 , +22147 , +32181 , +-16775 , +30293 , +-18861 , +20675 , +26623 , +-15489 , +-29835 , +13201 , +15687 , +-17661 , +20971 , +-21035 , +30195 , +-10387 , +14805 , +27365 , +649 , +-8917 , +24219 , +-18337 , +4583 , +3179 , +-5967 , +-28363 , +-21185 , +-1173 , +4545 , +-29365 , +-23925 , +-20133 , +-31881 , +-29299 , +30091 , +6571 , +2211 , +31881 , +-28875 , +26601 , +2305 , +-1149 , +25529 , +-31719 , +-14483 , +21523 , +-14617 , +6025 , +-9581 , +-31179 , +10043 , +21035 , +-10187 , +-13593 , +-6329 , +115 , +-21801 , +25413 , +-29265 , +2467 , +-30213 , +3089 , +933 , +-4437 , +3291 , +-4641 , +-26151 , +24963 , +20387 , +24993 , +3065 , +-29443 , +-23779 , +25021 , +15011 , +9501 , +-16645 , +-83 , +-11293 , +-10247 , +-4483 , +-18921 , +-24029 , +14087 , +12215 , +-4263 , +-18007 , +-20229 , +-17085 , +-26445 , +15505 , +-19425 , +-1415 , +6605 , +-4803 , +-28377 , +14885 , +-30499 , +18261 , +13965 , +22467 , +29497 , +22327 , +23655 , +-25801 , +4717 , +2041 , +14527 , +-8443 , +17879 , +8149 , +21613 , +28929 , +10427 , +-23761 , +-26515 , +-23149 , +-25371 , +-10753 , +11189 , +-27289 , +-24143 , +-27691 , +14739 , +-597 , +-12369 , +13895 , +14465 , +-17729 , +-12105 , +-15889 , +-13957 , +-10891 , +11395 , +-28191 , +-14373 , +-25919 , +16835 , +14759 , +-24143 , +-18949 , +-15429 , +-10833 , +-28521 , +-14961 , +-27563 , +-32175 , +-13555 , +25141 , +21177 , +12601 , +17999 , +4275 , +30317 , +-27285 , +8365 , +5635 , +20197 , +23983 , +19557 , +-23011 , +-16485 , +30101 , +-27911 , +25893 , +4269 , +-31513 , +-30459 , +-19671 , +-21517 , +26015 , +-30049 , +-17841 , +7823 , +-14237 , +22563 , +-18537 , +14097 , +-16519 , +27541 , +30227 , +-26617 , +26695 , +-24969 , +29843 , +-26855 , +27457 , +14365 , +-21009 , +-16225 , +-30105 , +-889 , +31661 , +-10309 , +-2501 , +21433 , +-29879 , +-21783 , +-24263 , +8601 , +24031 , +-27353 , +18897 , +26171 , +19055 , +893 , +29403 , +16069 , +31371 , +-10465 , +663 , +24249 , +-9833 , +-1027 , +-16359 , +-26143 , +28283 , +3045 , +26443 , +-26989 , +6111 , +22031 , +-29857 , +16531 , +8927 , +9029 , +-51 , +5229 , +-19381 , +-29081 , +-59 , +-9403 , +31829 , +-13931 , +-13269 , +-4297 , +-21301 , +10171 , +-2035 , +-24535 , +-22055 , +-15695 , +7067 , +-11993 , +27957 , +5581 , +9629 , +26171 , +5081 , +25855 , +885 , +-25921 , +-29117 , +18533 , +-10361 , +-10179 , +-5339 , +13417 , +30269 , +9665 , +13471 , +22101 , +24959 , +-14407 , +22519 , +-25239 , +-1375 , +10303 , +4053 , +18549 , +8935 , +-24573 , +18673 , +-12299 , +627 , +14223 , +-1701 , +-31579 , +11719 , +-1739 , +-7651 , +-17769 , +-7759 , +-5295 , +13197 , +-10033 , +-29235 , +19249 , +-29715 , +9563 , +25979 , +8297 , +18611 , +-23067 , +12115 , +-16219 , +-24007 , +-4909 , +2847 , +23559 , +-30213 , +10971 , +26199 , +10751 , +-15547 , +23837 , +-10479 , +20129 , +11897 , +-4169 , +5507 , +4223 , +-16711 , +-21279 , +-13331 , +30457 , +4651 , +20607 , +29987 , +-5853 , +9385 , +-26553 , +375 , +-6895 , +5369 , +10309 , +31283 , +26553 , +29835 , +7173 , +23447 , +7485 , +6573 , +-25567 , +-8881 , +-3631 , +-5053 , +20569 , +-7835 , +6927 , +-23297 , +1587 , +-15935 , +12745 , +-2277 , +25607 , +-19427 , +29799 , +7311 , +165 , +-903 , +-13887 , +15557 , +-18595 , +-23009 , +-25491 , +-23075 , +-28505 , +-1265 , +9893 , +20571 , +5935 , +29177 , +18063 , +-23203 , +29041 , +19135 , +29479 , +-163 , +6103 , +-28321 , +-5755 , +-8865 , +32583 , +-16523 , +-21821 , +16565 , +-28609 , +-19411 , +25163 , +11557 , +17007 , +15039 , +-13127 , +-15435 , +13519 , +-10395 , +-18645 , +-4141 , +-26055 , +4821 , +12057 , +7961 , +21119 , +-971 , +-1359 , +-1159 , +-30719 , +6551 , +-3663 , +-24577 , +-22071 , +32495 , +20149 , +16393 , +6691 , +17293 , +-28387 , +-18189 , +27061 , +3599 , +1879 , +1633 , +30477 , +-4379 , +-26177 , +4327 , +19149 , +16697 , +-4613 , +-12469 , +2093 , +-13703 , +31429 , +12853 , +-13787 , +-12229 , +-23471 , +-11663 , +-15109 , +23751 , +31007 , +-9827 , +-31651 , +27141 , +10063 , +7529 , +-25093 , +10999 , +-15737 , +-6839 , +-20327 , +11187 , +29239 , +21171 , +1969 , +32729 , +-24447 , +-7219 , +-17531 , +-18549 , +16781 , +2227 , +-23117 , +-11545 , +-13479 , +17185 , +597 , +-5127 , +-2529 , +-14155 , +5525 , +-12483 , +-8929 , +8101 , +-21051 , +14991 , +-26619 , +-21005 , +-9735 , +-1371 , +-6991 , +-19673 , +-21219 , +-24823 , +-1635 , +-23417 , +25995 , +-881 , +6319 , +25557 , +-11993 , +13899 , +-1391 , +18555 , +17913 , +-31471 , +-21883 , +29515 , +1849 , +30049 , +-5429 , +25783 , +28411 , +-11285 , +-18075 , +19849 , +-19407 , +127 , +3459 , +4629 , +-23213 , +-8313 , +25931 , +30713 , +12145 , +8705 , +15419 , +30289 , +2505 , +7155 , +505 , +8303 , +24039 , +-7831 , +-22089 , +8979 , +-15313 , +-7705 , +27131 , +19491 , +27911 , +-17821 , +-15099 , +5349 , +-12707 , +30145 , +29089 , +-22857 , +-21041 , +-3131 , +15485 , +21057 , +-8395 , +-20851 , +31239 , +-3789 , +-28733 , +-26999 , +8381 , +10881 , +30109 , +15607 , +9231 , +4365 , +-17425 , +1235 , +10159 , +5357 , +903 , +-28073 , +9063 , +-16613 , +20459 , +12527 , +3965 , +12209 , +14573 , +26543 , +12671 , +-10593 , +14543 , +29777 , +8609 , +24291 , +28367 , +-7003 , +8337 , +17477 , +-20925 , +1683 , +-10793 , +2947 , +12853 , +26249 , +3747 , +-27363 , +-12939 , +5243 , +-27351 , +-32139 , +-4303 , +-6315 , +-18309 , +9633 , +21525 , +30453 , +-25373 , +-3191 , +-17445 , +1189 , +-4943 , +-3917 , +31587 , +2577 , +413 , +4209 , +17235 , +-22845 , +7837 , +-357 , +-3291 , +-23537 , +-11721 , +19403 , +-12093 , +18333 , +6497 , +29711 , +-859 , +-21423 , +23253 , +-18399 , +31323 , +-9779 , +-11543 , +16677 , +-23113 , +21091 , +-30745 , +-31011 , +27733 , +20369 , +24295 , +28767 , +9147 , +25849 , +26917 , +10069 , +21489 , +-15917 , +471 , +5545 , +20117 , +-14099 , +-11125 , +1481 , +-5513 , +14111 , +25595 , +-8877 , +15279 , +-28603 , +10595 , +-5541 , +-24521 , +2737 , +-7075 , +15127 , +-1791 , +-20181 , +13113 , +-2019 , +26509 , +-3225 , +3027 , +14615 , +26629 , +23797 , +11495 , +19459 , +-24617 , +-21817 , +8179 , +-6435 , +14531 , +-2275 , +-7289 , +15337 , +8319 , +13315 , +-10717 , +26715 , +1221 , +-21433 , +-1661 , +13719 , +25589 , +-15631 , +9867 , +-23319 , +-30175 , +-22211 , +18827 , +15803 , +-11599 , +17171 , +16161 , +-27061 , +1651 , +-3593 , +27027 , +3817 , +11831 , +32399 , +-26979 , +14249 , +-19999 , +-10099 , +19929 , +-10081 , +7179 , +-6859 , +8069 , +5269 , +23063 , +5189 , +3047 , +-25021 , +-12093 , +-3203 , +-25823 , +30729 , +7497 , +30857 , +-17015 , +13861 , +-9485 , +14727 , +3203 , +15209 , +17717 , +19439 , +-31785 , +-6025 , +3647 , +537 , +19337 , +13691 , +16927 , +16175 , +-21967 , +-20903 , +-29107 , +-26203 , +-18477 , +18803 , +-14893 , +1073 , +-5829 , +4305 , +-1583 , +13635 , +3023 , +5609 , +-345 , +-31489 , +-13849 , +-22581 , +-19069 , +31153 , +20395 , +17377 , +-3463 , +-17717 , +10343 , +14623 , +22305 , +-23975 , +-5019 , +30147 , +-1621 , +9461 , +-10433 , +30601 , +12405 , +18503 , +-8513 , +-10655 , +23083 , +-8197 , +25139 , +25007 , +-1455 , +-14025 , +2627 , +18423 , +621 , +23693 , +-3759 , +16671 , +-24689 , +20101 , +-21433 , +13091 , +25711 , +-18817 , +19441 , +18767 , +10251 , +29755 , +-4383 , +-2575 , +28853 , +-21559 , +-1101 , +-10595 , +-15439 , +-28663 , +-25609 , +-3373 , +-20147 , +13203 , +-28805 , +19789 , +-2701 , +-26555 , +-4047 , +16291 , +-31543 , +-19161 , +-389 , +-26481 , +-8633 , +-21777 , +-29179 , +-2911 , +31049 , +-8457 , +11047 , +18807 , +-22481 , +13489 , +-28499 , +7031 , +-14481 , +7585 , +-31171 , +22021 , +4403 , +-18471 , +-16599 , +15929 , +-4757 , +-19735 , +-11833 , +30747 , +5733 , +13151 , +-8377 , +-27043 , +27117 , +27833 , +1041 , +11403 , +-16675 , +10721 , +10393 , +-9271 , +-26825 , +-987 , +19125 , +21001 , +1725 , +18603 , +-10375 , +-19517 , +-23031 , +-5013 , +11661 , +26673 , +-5589 , +-20823 , +-8183 , +-16385 , +-18253 , +14827 , +-11835 , +28299 , +-28583 , +-11405 , +-16075 , +19863 , +7689 , +-30411 , +23751 , +25477 , +-27007 , +3659 , +30641 , +-23541 , +-21401 , +-519 , +30541 , +25459 , +31459 , +-17129 , +-28427 , +-3001 , +15539 , +-19947 , +-4011 , +26515 , +10183 , +2921 , +24133 , +-6247 , +17751 , +-13171 , +-32733 , +-23285 , +-24963 , +22901 , +18347 , +-12609 , +-27317 , +14475 , +-21685 , +-29717 , +-15775 , +17181 , +16125 , +28889 , +12043 , +-925 , +-14945 , +26149 , +17361 , +18153 , +21201 , +31343 , +17307 , +12433 , +5441 , +-26983 , +-21705 , +3335 , +24973 , +-29577 , +19847 , +-26949 , +5525 , +30733 , +-31741 , +20049 , +-5031 , +-5307 , +19429 , +-12119 , +-9651 , +-9171 , +-22609 , +23367 , +2603 , +-12895 , +7505 , +14161 , +-28067 , +10895 , +-22341 , +17165 , +31421 , +19375 , +-1295 , +20943 , +11011 , +8115 , +23981 , +-25993 , +-9839 , +-4603 , +4977 , +-5017 , +4809 , +11261 , +-29669 , +-7429 , +-3855 , +-9061 , +17925 , +-12415 , +7293 , +29371 , +-19559 , +-28233 , +11503 , +-21037 , +-661 , +5815 , +-32205 , +26915 , +-1845 , +-18827 , +11881 , +-10889 , +10983 , +10175 , +2125 , +5459 , +12377 , +17061 , +32257 , +-19529 , +24901 , +18815 , +16495 , +-4785 , +2547 , +-4001 , +24351 , +17455 , +4061 , +-9467 , +-4983 , +22023 , +23377 , +-13985 , +-15625 , +27873 , +-8825 , +10881 , +-32301 , +-15793 , +-29897 , +19985 , +23431 , +-4813 , +9133 , +-5039 , +-13365 , +29159 , +7273 , +15491 , +-12659 , +-4869 , +-30409 , +20983 , +-20681 , +-12173 , +22717 , +-2195 , +2197 , +11121 , +-16997 , +-16095 , +3367 , +29823 , +7175 , +-29393 , +-20493 , +-12745 , +21463 , +10913 , +-14865 , +-16763 , +-16597 , +24273 , +-18493 , +-12201 , +-17039 , +371 , +-9167 , +6111 , +8975 , +26369 , +4837 , +4419 , +25971 , +-11845 , +-18479 , +-11819 , +-9305 , +8473 , +-30971 , +979 , +-5263 , +30661 , +-30463 , +-23403 , +31465 , +4119 , +-24683 , +-693 , +32395 , +-2299 , +-13515 , +-12749 , +-1065 , +-6747 , +-16177 , +9299 , +22627 , +-3817 , +-6101 , +-11859 , +19833 , +18703 , +23225 , +-3 , +22569 , +-17219 , +-1299 , +-10775 , +-543 , +15953 , +15387 , +-22845 , +-17009 , +7397 , +-19767 , +-23369 , +1321 , +11527 , +1417 , +-29305 , +977 , +-26719 , +22099 , +18889 , +-20371 , +-30853 , +-17315 , +-2413 , +-9033 , +27949 , +-6547 , +20927 , +-21287 , +4509 , +32185 , +153 , +19339 , +12013 , +24891 , +-22243 , +12959 , +-14333 , +20875 , +21937 , +-8157 , +-2451 , +9519 , +6997 , +20469 , +26349 , +7553 , +31327 , +4571 , +15457 , +29693 , +29111 , +21533 , +-28347 , +-18407 , +-17269 , +-17767 , +20389 , +5541 , +12933 , +23135 , +-26727 , +7063 , +-15737 , +-20025 , +27707 , +7021 , +-29 , +-2803 , +-8415 , +-18175 , +-17905 , +-30883 , +29265 , +-15645 , +-26913 , +-1923 , +-5955 , +-5331 , +10049 , +24279 , +15673 , +30945 , +28271 , +26133 , +-2061 , +-30281 , +21417 , +-5575 , +-26001 , +-895 , +-2447 , +30521 , +23029 , +-25601 , +23865 , +-31473 , +-8041 , +-24017 , +30377 , +-14245 , +19611 , +11313 , +-6837 , +28529 , +9853 , +-18793 , +-29241 , +-23563 , +-31389 , +14911 , +24479 , +10487 , +6677 , +431 , +20575 , +28037 , +22645 , +-12571 , +351 , +-5175 , +30585 , +27061 , +2033 , +11415 , +32673 , +11939 , +20509 , +18323 , +8175 , +-18893 , +-28193 , +14267 , +-32417 , +11463 , +20693 , +-9079 , +-12061 , +29431 , +24187 , +-119 , +-18479 , +-24989 , +22245 , +13929 , +31461 , +-3307 , +4087 , +-1631 , +-2119 , +-4783 , +29467 , +-14473 , +14517 , +29679 , +-18059 , +-21587 , +-10355 , +-13515 , +-32091 , +897 , +-6603 , +24619 , +-16905 , +-10659 , +-27039 , +1143 , +-8675 , +-25893 , +22385 , +-19787 , +20331 , +-16279 , +-23819 , +29517 , +-22393 , +-10913 , +12189 , +31175 , +-29271 , +-24171 , +-15693 , +4783 , +-16819 , +3447 , +22547 , +31199 , +17773 , +11685 , +-10071 , +12641 , +17469 , +19211 , +5977 , +-3901 , +20317 , +16239 , +19597 , +-15121 , +-10603 , +-367 , +-14309 , +30851 , +-28919 , +-23609 , +4547 , +-9047 , +22517 , +-9207 , +12331 , +2675 , +-28189 , +1169 , +20047 , +13485 , +24677 , +-10765 , +30595 , +8757 , +-12725 , +-3147 , +-24093 , +-5925 , +19545 , +14431 , +-16565 , +175 , +-32121 , +5665 , +3285 , +18399 , +-5205 , +-7199 , +22733 , +3853 , +13251 , +28371 , +30503 , +-14805 , +-12133 , +-22379 , +-25475 , +25035 , +-13035 , +-13881 , +-10369 , +4347 , +16085 , +-16097 , +24821 , +23457 , +24189 , +18183 , +-1491 , +16721 , +-17815 , +28079 , +4603 , +28827 , +31711 , +1447 , +-6103 , +12023 , +14033 , +-20745 , +26489 , +2311 , +15369 , +-4421 , +-4589 , +-7295 , +-6675 , +8501 , +-17275 , +-31621 , +-10319 , +-24475 , +17203 , +11593 , +-22773 , +-2261 , +1625 , +23765 , +-6027 , +30929 , +20599 , +21105 , +5593 , +5417 , +27479 , +26939 , +18393 , +-16085 , +-26759 , +-7193 , +14707 , +19459 , +31247 , +16671 , +-29107 , +-1873 , +14711 , +-20389 , +-11429 , +-19433 , +51 , +-16587 , +12837 , +16287 , +7771 , +-10425 , +20087 , +10311 , +-32355 , +-23427 , +18079 , +-7617 , +-17487 , +-1041 , +19997 , +-7937 , +20307 , +23357 , +-9501 , +995 , +31669 , +-26529 , +-8955 , +12089 , +15999 , +-9723 , +-1795 , +27107 , +-15293 , +28775 , +15441 , +22379 , +-139 , +-22871 , +17633 , +26271 , +-25115 , +9381 , +21131 , +-29537 , +5299 , +-1717 , +15215 , +-7039 , +-1333 , +-6791 , +-17755 , +2913 , +27099 , +-175 , +4461 , +-28421 , +-25141 , +17935 , +29431 , +21699 , +-30025 , +15975 , +12937 , +10115 , +-24217 , +12121 , +11331 , +-30363 , +31295 , +6025 , +24663 , +-9063 , +-24891 , +-3309 , +14517 , +-7063 , +10635 , +27119 , +29013 , +-5943 , +29875 , +32447 , +6877 , +22141 , +-28959 , +22055 , +-20503 , +13219 , +-20819 , +-20825 , +-19275 , +16597 , +23723 , +8441 , +-9887 , +7871 , +-29743 , +-16161 , +5793 , +20529 , +22653 , +13953 , +-17165 , +28861 , +-23065 , +-6079 , +-4505 , +30673 , +21013 , +19739 , +31421 , +24647 , +14429 , +-143 , +-27079 , +3205 , +-17837 , +-22417 , +25285 , +-16627 , +1867 , +23513 , +-15437 , +-97 , +-9657 , +31849 , +29687 , +17609 , +-6541 , +-16215 , +-10537 , +14847 , +-21983 , +28739 , +31531 , +-1479 , +-8131 , +29153 , +-14067 , +5897 , +18495 , +16763 , +-11749 , +-15319 , +-843 , +26431 , +-17369 , +-89 , +4133 , +-31015 , +-16783 , +3689 , +-22379 , +-24751 , +10593 , +9553 , +20861 , +-27801 , +28857 , +-26929 , +-17347 , +-28057 , +-20391 , +23809 , +-22757 , +31105 , +-23703 , +22591 , +8885 , +-14945 , +-31205 , +6719 , +-4611 , +11715 , +-9761 , +-27231 , +8365 , +32217 , +-31719 , +-30187 , +-9149 , +-13803 , +16223 , +1253 , +15227 , +-27967 , +-10453 , +-12775 , +14397 , +-3933 , +9753 , +6659 , +-16353 , +25035 , +20117 , +22375 , +-20645 , +20201 , +9761 , +29183 , +-5565 , +-7891 , +19199 , +24995 , +19771 , +16545 , +-9099 , +24029 , +-21707 , +-11537 , +19837 , +-29187 , +-27999 , +-27949 , +18941 , +-29261 , +4331 , +6107 , +9861 , +-25049 , +11381 , +26319 , +-11643 , +-9323 , +19721 , +8833 , +-15107 , +20319 , +19153 , +13609 , +-9279 , +13991 , +23507 , +-30147 , +-23253 , +21865 , +-26645 , +-3901 , +3153 , +-20977 , +19259 , +-16845 , +-8253 , +30097 , +-12501 , +18883 , +10939 , +-25599 , +8665 , +-10165 , +-10017 , +-15955 , +-3047 , +4247 , +-25491 , +-3917 , +26089 , +-28613 , +-28929 , +-3301 , +10603 , +-18187 , +-31559 , +-25241 , +17495 , +20091 , +-30195 , +-6723 , +10237 , +-803 , +-31773 , +8039 , +22451 , +24401 , +27227 , +13055 , +21969 , +-24683 , +5643 , +11009 , +3889 , +17861 , +6053 , +-4901 , +32021 , +20653 , +-28095 , +30351 , +-19021 , +11945 , +-28661 , +30921 , +8987 , +-20741 , +-13957 , +-23181 , +6335 , +-31845 , +22293 , +-30001 , +32609 , +27549 , +17815 , +21267 , +-12407 , +-25093 , +-31561 , +16507 , +4743 , +-29447 , +10331 , +15841 , +8677 , +-26123 , +29771 , +23519 , +-8869 , +-11839 , +-21901 , +-28073 , +-28845 , +18813 , +5009 , +-24933 , +14289 , +13291 , +14965 , +22005 , +-2565 , +18251 , +-11851 , +17617 , +18437 , +-29773 , +15329 , +-3517 , +22959 , +10723 , +11845 , +-24529 , +6457 , +21153 , +26139 , +-8237 , +19171 , +-10609 , +-6081 , +-11541 , +21211 , +-31099 , +-15503 , +28989 , +-4677 , +-2973 , +-13053 , +-21825 , +-28803 , +-21389 , +20505 , +-16861 , +-24325 , +32569 , +10073 , +-25615 , +21467 , +-3121 , +14639 , +-20949 , +17685 , +31413 , +-12681 , +-9137 , +-23077 , +31033 , +-17477 , +9223 , +8991 , +-15039 , +-11021 , +-25043 , +17285 , +-22107 , +-23637 , +18545 , +29657 , +2831 , +-10289 , +27495 , +31247 , +-15033 , +27347 , +-2777 , +-31059 , +-9959 , +-4745 , +-24477 , +-25389 , +-32095 , +-2061 , +16373 , +-30551 , +-12251 , +13497 , +1803 , +7257 , +-11915 , +-595 , +9643 , +-5243 , +-2117 , +979 , +-28201 , +15687 , +-16939 , +-1645 , +21793 , +27809 , +12589 , +-18587 , +14017 , +28533 , +29461 , +-11497 , +6711 , +-17405 , +-13671 , +8569 , +-5551 , +17629 , +24281 , +6811 , +26839 , +-15521 , +12767 , +-26495 , +-17775 , +2211 , +29697 , +-6049 , +2033 , +-29433 , +-14419 , +-22955 , +2583 , +-2539 , +-29247 , +23447 , +-9091 , +-13569 , +-11663 , +22327 , +-5375 , +4001 , +-3441 , +-18091 , +21631 , +-529 , +-28311 , +10451 , +-26129 , +-27159 , +-2265 , +11159 , +-3589 , +15395 , +28567 , +-26311 , +6419 , +7853 , +-15983 , +8259 , +-2553 , +-26475 , +22215 , +21987 , +-5345 , +19419 , +11293 , +18471 , +11191 , +10725 , +8841 , +2739 , +-4527 , +8837 , +-14239 , +13817 , +-11473 , +-20133 , +13113 , +-12045 , +22381 , +487 , +571 , +-25257 , +-21353 , +-7705 , +8443 , +15957 , +-13119 , +14949 , +25299 , +12743 , +8991 , +18207 , +-28999 , +5105 , +-24289 , +17547 , +-3177 , +9653 , +-26625 , +-13245 , +7459 , +-29367 , +12005 , +-26613 , +-16067 , +18807 , +-12935 , +-7363 , +32185 , +20297 , +21243 , +8901 , +32453 , +-13747 , +29143 , +19355 , +-23109 , +-2237 , +1993 , +24505 , +18549 , +-28325 , +-13721 , +31125 , +8499 , +18925 , +8261 , +3603 , +-31011 , +17071 , +32387 , +-25335 , +-31245 , +619 , +8941 , +-30679 , +-3629 , +-9155 , +-32115 , +18563 , +1689 , +16711 , +17605 , +-17803 , +-19595 , +-2841 , +8939 , +-18385 , +9607 , +-25741 , +-31653 , +-17765 , +-21717 , +-25745 , +12049 , +-18203 , +-30747 , +-14009 , +-6973 , +-409 , +-12125 , +-10875 , +17525 , +12071 , +-5977 , +-2681 , +-14183 , +13005 , +-18731 , +-16707 , +14745 , +15899 , +11145 , +-21413 , +27905 , +-19737 , +12029 , +18325 , +-22265 , +3729 , +-28659 , +27221 , +-31575 , +-24837 , +2979 , +-27531 , +-25523 , +13825 , +1151 , +-13455 , +-3385 , +-27789 , +919 , +-857 , +22277 , +-17013 , +-26385 , +23053 , +-23019 , +-27 , +-19217 , +-22171 , +16847 , +-14089 , +4667 , +-523 , +-27685 , +7691 , +-14327 , +-11063 , +-2731 , +-8781 , +-25343 , +2907 , +-11549 , +-30519 , +12941 , +-22309 , +25929 , +-13863 , +-24399 , +-3623 , +-10621 , +29481 , +-26007 , +-16761 , +11103 , +11047 , +-19845 , +-29841 , +-13929 , +32611 , +-10029 , +15525 , +-3491 , +-27129 , +-22437 , +2951 , +2437 , +13775 , +-25267 , +-26895 , +265 , +23685 , +-13295 , +-29195 , +-16073 , +7155 , +12441 , +-4847 , +-6859 , +-2723 , +11821 , +17903 , +-23515 , +27513 , +22473 , +2451 , +16057 , +747 , +6395 , +19739 , +-14005 , +26935 , +22323 , +237 , +-21899 , +-1477 , +-23653 , +4735 , +-22995 , +23591 , +5493 , +28797 , +-12973 , +27127 , +25839 , +27023 , +10711 , +9325 , +24183 , +23945 , +32579 , +-7811 , +18079 , +14629 , +-2081 , +29267 , +18023 , +-19395 , +5695 , +30663 , +30751 , +-13695 , +-15519 , +-25263 , +-21315 , +26287 , +-11961 , +-3455 , +-32339 , +-18355 , +-13821 , +6911 , +-8395 , +11231 , +25443 , +-29447 , +30535 , +32157 , +28401 , +-27101 , +23767 , +-8527 , +-24925 , +24359 , +19385 , +-23319 , +-2591 , +-23129 , +-18189 , +31987 , +16163 , +25771 , +17305 , +-26863 , +24077 , +9119 , +-25057 , +-14759 , +-10751 , +9165 , +-30659 , +2659 , +23867 , +9289 , +-3783 , +31621 , +-11163 , +-2949 , +-9525 , +4493 , +31415 , +-29433 , +5225 , +15609 , +-18813 , +-6323 , +26413 , +-13653 , +19033 , +19299 , +18973 , +2597 , +20115 , +19589 , +-18667 , +-20931 , +-14471 , +11285 , +14349 , +24669 , +12243 , +-9461 , +-15105 , +32303 , +-12287 , +20981 , +-30155 , +-1569 , +14735 , +30571 , +12075 , +-11055 , +-16551 , +19721 , +-18977 , +11475 , +16917 , +-25889 , +-30041 , +21467 , +10615 , +-11909 , +-9065 , +-5565 , +-7743 , +23113 , +-10683 , +29555 , +-18981 , +3743 , +-12491 , +23847 , +24047 , +3373 , +3487 , +-3807 , +6789 , +-23053 , +12503 , +10591 , +-19443 , +-27461 , +-9191 , +-8491 , +14085 , +16919 , +-17947 , +19115 , +-15223 , +17101 , +28635 , +20971 , +20333 , +-12837 , +-25843 , +-27713 , +-25125 , +24803 , +27867 , +-19931 , +26461 , +19247 , +71 , +-13011 , +-6267 , +22305 , +-47 , +-22357 , +-17159 , +18993 , +-19505 , +29809 , +27921 , +29531 , +4417 , +-20723 , +25579 , +37 , +-7891 , +6903 , +-14067 , +20487 , +-26505 , +15947 , +107 , +-395 , +-1999 , +25863 , +12307 , +-9403 , +3715 , +-25151 , +-24011 , +-30283 , +-20495 , +-22311 , +23491 , +-549 , +323 , +21049 , +-16501 , +-28511 , +10701 , +11659 , +-27191 , +-7621 , +-14761 , +11497 , +20543 , +17183 , +13417 , +2593 , +-7471 , +-9347 , +20011 , +-1433 , +2209 , +18743 , +-20811 , +-23413 , +19863 , +-5027 , +5873 , +-11849 , +-19313 , +-26081 , +2791 , +-12129 , +20955 , +-4535 , +16291 , +831 , +-19859 , +-3277 , +-3711 , +-28905 , +26469 , +22603 , +-17657 , +-22569 , +-29141 , +-4361 , +1093 , +27805 , +-21241 , +-23011 , +-23899 , +-12365 , +-17349 , +-17387 , +-16059 , +-32579 , +-19559 , +24351 , +-22063 , +20855 , +29851 , +29793 , +-31273 , +3309 , +26877 , +-17063 , +-20315 , +14637 , +-21041 , +5079 , +-20069 , +-17527 , +8985 , +-2951 , +30469 , +-10425 , +14309 , +3997 , +-5771 , +32473 , +-13601 , +6361 , +28569 , +28573 , +-2193 , +-29445 , +31381 , +4107 , +10057 , +-22921 , +-19753 , +-30605 , +16523 , +14439 , +-8845 , +3635 , +18519 , +-22531 , +4599 , +-9871 , +20959 , +-17283 , +22731 , +-17073 , +4625 , +32183 , +18941 , +-9559 , +-4201 , +-9985 , +-15193 , +25927 , +-6265 , +17569 , +22197 , +-3179 , +7785 , +6619 , +27987 , +20709 , +30165 , +-8873 , +-6735 , +18969 , +-369 , +11811 , +5735 , +27873 , +-24807 , +-27867 , +-5815 , +12667 , +-14641 , +-8429 , +7617 , +-31013 , +-31363 , +25333 , +19363 , +14703 , +-8329 , +-22767 , +-16759 , +11347 , +-18895 , +-7579 , +-15959 , +-8947 , +7513 , +-5979 , +29741 , +10685 , +29807 , +-14673 , +-16883 , +-11815 , +7381 , +-14971 , +32101 , +-22167 , +9333 , +3007 , +-31669 , +-2373 , +-17203 , +-27251 , +32557 , +-3431 , +-10609 , +-17629 , +23461 , +-7417 , +-17999 , +-577 , +18383 , +-14223 , +-3573 , +21267 , +-7643 , +5491 , +26737 , +-22711 , +-20009 , +26881 , +69 , +-12945 , +32671 , +-15579 , +-28273 , +-27011 , +-22755 , +11323 , +-26725 , +18111 , +-1875 , +18083 , +27659 , +8663 , +17345 , +-15619 , +26231 , +17713 , +8627 , +12001 , +-18315 , +-30469 , +6439 , +5649 , +24135 , +-24673 , +-20007 , +-4551 , +-1055 , +11189 , +-28417 , +-15071 , +-375 , +1159 , +13845 , +10603 , +-9493 , +24825 , +28737 , +17859 , +-16455 , +8465 , +9247 , +-22879 , +-27463 , +-4637 , +31273 , +-23945 , +-24989 , +26639 , +3453 , +-9105 , +-25099 , +7349 , +13121 , +-9823 , +-14827 , +30965 , +-3465 , +8395 , +23511 , +29661 , +-15275 , +-9075 , +23657 , +9957 , +-19169 , +30747 , +-229 , +3309 , +-643 , +11893 , +27649 , +8103 , +-21421 , +1061 , +32517 , +-29791 , +30999 , +9075 , +-4221 , +12971 , +22195 , +4893 , +-19359 , +-19235 , +-8499 , +-16495 , +-861 , +14343 , +11691 , +-12643 , +-27515 , +-23123 , +18057 , +13751 , +3863 , +-26757 , +-26515 , +-30043 , +-29617 , +-21947 , +-17533 , +1727 , +29601 , +28529 , +-267 , +-19295 , +-1249 , +-19201 , +-8387 , +-16283 , +-11511 , +23543 , +-763 , +25185 , +-12825 , +30049 , +-21381 , +23633 , +-8925 , +-8763 , +-19161 , +-32483 , +14875 , +3863 , +23115 , +16141 , +5059 , +24889 , +17327 , +-23429 , +-26443 , +28915 , +24325 , +-10477 , +-18997 , +-6817 , +20919 , +30083 , +24891 , +19441 , +-27833 , +-9283 , +-13787 , +17123 , +-14301 , +-15963 , +17593 , +-21963 , +29947 , +11345 , +19139 , +4893 , +-23907 , +10685 , +26823 , +9739 , +-30133 , +20225 , +28571 , +14095 , +-7531 , +28939 , +-15747 , +-16155 , +-6991 , +-28707 , +6573 , +-417 , +-23989 , +27707 , +-28285 , +23139 , +-15383 , +-16409 , +24071 , +-4513 , +18365 , +-28579 , +-1273 , +-14523 , +22781 , +-27645 , +12467 , +10499 , +-10311 , +8683 , +-15175 , +-30601 , +-22215 , +-23551 , +12239 , +29677 , +26833 , +967 , +12249 , +8719 , +-28363 , +2451 , +-29061 , +-8347 , +-18851 , +9787 , +-3027 , +4679 , +-6191 , +-24745 , +8157 , +3417 , +-11389 , +-27145 , +23293 , +26755 , +-16079 , +-8233 , +-32217 , +6243 , +-467 , +11031 , +31267 , +-945 , +-11835 , +25725 , +27025 , +6849 , +-28145 , +-10211 , +-28935 , +17501 , +-3771 , +1183 , +2911 , +21853 , +7073 , +-26383 , +31075 , +-12915 , +-16977 , +-27523 , +-22313 , +-2363 , +-29913 , +485 , +22225 , +20959 , +24135 , +17465 , +14923 , +-32209 , +-30805 , +28339 , +15669 , +28543 , +26273 , +-24859 , +14865 , +-10625 , +-7679 , +-11907 , +5643 , +-61 , +-9841 , +10613 , +-28787 , +-10951 , +10179 , +8653 , +-26277 , +3619 , +19505 , +-24123 , +-26073 , +-22129 , +22101 , +27539 , +26799 , +28487 , +10481 , +-8803 , +23631 , +-20649 , +-21023 , +32301 , +18973 , +-2055 , +4729 , +18859 , +-14721 , +-1517 , +-23463 , +15191 , +-31935 , +21549 , +26307 , +2179 , +8757 , +31721 , +-1929 , +-31169 , +21569 , +32253 , +-7669 , +-20061 , +-25347 , +-13143 , +-6975 , +-11657 , +-27959 , +-11089 , +25051 , +-20367 , +-3227 , +-28469 , +29309 , +21237 , +25869 , +-11347 , +-14337 , +17213 , +15367 , +-32657 , +-4925 , +-14051 , +7369 , +27019 , +-623 , +6713 , +-11643 , +3675 , +29547 , +-3143 , +12869 , +-4345 , +5611 , +-27003 , +25223 , +-20733 , +-20969 , +-25093 , +24397 , +-16893 , +-28233 , +-22233 , +4797 , +-16519 , +-24781 , +20091 , +-9677 , +26763 , +-15899 , +21003 , +-12321 , +3201 , +-26893 , +-27075 , +-20267 , +-28719 , +19111 , +-16631 , +-18513 , +-1661 , +17999 , +-87 , +17305 , +23347 , +-14719 , +2781 , +-23561 , +18315 , +-3573 , +-25197 , +-8085 , +-28875 , +-30409 , +-25555 , +-10875 , +31829 , +-14927 , +14897 , +32193 , +17537 , +-32041 , +9351 , +-16589 , +-5827 , +18069 , +9769 , +-27243 , +16109 , +17083 , +16225 , +-3871 , +21069 , +-6447 , +-22655 , +8301 , +-7055 , +6781 , +-20201 , +8827 , +13621 , +-18359 , +2221 , +-20393 , +-11211 , +24839 , +17907 , +24301 , +-20405 , +16295 , +18309 , +-21531 , +7553 , +-10871 , +20767 , +20275 , +2447 , +26461 , +25677 , +-22217 , +5837 , +8823 , +-13391 , +-23219 , +-10837 , +-27995 , +20655 , +-5905 , +-11087 , +-32625 , +5033 , +-22715 , +-16659 , +-12155 , +32441 , +-3779 , +16627 , +31195 , +19177 , +-9687 , +-5043 , +11973 , +4073 , +18641 , +-11907 , +-13145 , +22083 , +-13037 , +2155 , +11511 , +-23523 , +20973 , +-8349 , +28301 , +31851 , +1059 , +-6003 , +20345 , +-14173 , +17745 , +-25119 , +-20633 , +-23299 , +899 , +-11355 , +-11667 , +1833 , +19789 , +-20131 , +31841 , +14209 , +31331 , +26955 , +31931 , +-27447 , +-16203 , +26207 , +-15643 , +-26011 , +-29187 , +10429 , +-27881 , +-24311 , +32229 , +-30561 , +-3155 , +20989 , +17553 , +-26653 , +-5379 , +17613 , +26049 , +-9739 , +-23113 , +-16505 , +4199 , +2637 , +7599 , +4459 , +-2375 , +10597 , +22855 , +-32727 , +31441 , +2099 , +-9415 , +16283 , +1983 , +2589 , +23281 , +27635 , +-4313 , +21877 , +23915 , +32381 , +-23727 , +10863 , +-14713 , +13527 , +-23095 , +-26469 , +-1311 , +25247 , +625 , +19161 , +-21973 , +-23115 , +-20703 , +-24107 , +-9729 , +29935 , +-22607 , +-11013 , +18753 , +-32429 , +7839 , +20985 , +-15377 , +-7735 , +-26079 , +4773 , +32635 , +349 , +21947 , +8583 , +6051 , +-14355 , +-16289 , +1223 , +17357 , +-2711 , +28409 , +18343 , +-9001 , +10119 , +23441 , +-9601 , +19317 , +-32265 , +-14113 , +-32469 , +-2293 , +28967 , +-23965 , +2063 , +-13059 , +32619 , +-20227 , +30601 , +30861 , +-19257 , +31753 , +-539 , +25395 , +30995 , +12015 , +-14369 , +5487 , +28871 , +23361 , +32659 , +4139 , +19493 , +-4269 , +-22023 , +-18805 , +245 , +14671 , +-25897 , +24647 , +26303 , +20177 , +14145 , +11395 , +-21119 , +-20225 , +16017 , +-21205 , +-22811 , +-31459 , +20949 , +707 , +23043 , +14761 , +29135 , +-32567 , +-9849 , +-4113 , +11121 , +29311 , +-11139 , +-32219 , +10949 , +6227 , +-9863 , +32261 , +27771 , +30127 , +-15269 , +-5157 , +-14897 , +1869 , +20091 , +14891 , +-1271 , +-1513 , +14701 , +9657 , +7281 , +-1413 , +3121 , +-2513 , +25037 , +13379 , +-9491 , +-6353 , +15443 , +-25875 , +4391 , +5611 , +-10455 , +4739 , +-18819 , +-13507 , +-16819 , +-28425 , +9687 , +31297 , +-7133 , +-12301 , +-20697 , +19305 , +-17061 , +-22725 , +7067 , +-29673 , +-21651 , +-22665 , +-29605 , +-9541 , +28061 , +3485 , +-21573 , +26465 , +-12193 , +-22855 , +-22283 , +8397 , +21345 , +-17329 , +-2459 , +9749 , +-521 , +-24277 , +16951 , +21689 , +6683 , +-2363 , +-24147 , +19253 , +3551 , +17161 , +26313 , +-18397 , +2919 , +-4419 , +-26479 , +19915 , +-12445 , +17493 , +-31299 , +12859 , +9735 , +-30911 , +27127 , +17381 , +28287 , +-17447 , +-25203 , +2737 , +-11031 , +14239 , +18351 , +-21091 , +31439 , +-28121 , +2845 , +-15161 , +17951 , +3691 , +-23189 , +24595 , +-29027 , +5277 , +-1869 , +6719 , +25061 , +-11129 , +30667 , +-28557 , +-27175 , +-22435 , +27905 , +5733 , +24991 , +20505 , +4947 , +-279 , +-19175 , +-25265 , +-1499 , +20751 , +1753 , +-22643 , +-21643 , +16817 , +-12129 , +8489 , +3227 , +18841 , +29255 , +-7011 , +29057 , +12299 , +-19633 , +21091 , +-9645 , +-7705 , +-25915 , +-26809 , +21433 , +27967 , +-10819 , +29505 , +-3687 , +-1687 , +25685 , +-26415 , +23617 , +5023 , +-15073 , +15567 , +26665 , +10257 , +22307 , +-4407 , +-20441 , +32643 , +10837 , +20957 , +-21977 , +-26275 , +-2427 , +-12791 , +11873 , +14923 , +28901 , +-11767 , +-5863 , +1873 , +-18443 , +-16979 , +-20787 , +1377 , +3585 , +3249 , +10995 , +-10887 , +-26089 , +-9701 , +-7889 , +1333 , +26497 , +21509 , +-1779 , +19435 , +23479 , +14341 , +-13257 , +3137 , +23267 , +-4107 , +-20693 , +-3515 , +21193 , +26463 , +-4999 , +1541 , +25679 , +12605 , +27253 , +2729 , +-7319 , +5735 , +-3213 , +-32247 , +26005 , +-23457 , +-26497 , +11461 , +-26919 , +-11097 , +9869 , +24285 , +3375 , +25765 , +9791 , +205 , +-11643 , +-2579 , +24083 , +-27363 , +-8903 , +-28893 , +20251 , +6783 , +12035 , +-27313 , +-23495 , +8807 , +-11651 , +-10829 , +3033 , +-3041 , +28429 , +-18391 , +29729 , +5221 , +-21655 , +12791 , +8621 , +2427 , +5767 , +-28377 , +-26419 , +-19513 , +-12521 , +-18339 , +-11983 , +4837 , +-24195 , +-7373 , +-21461 , +-12475 , +-11193 , +-29933 , +9573 , +24637 , +23331 , +-31607 , +13843 , +9891 , +-22435 , +-4839 , +-7501 , +21477 , +-11053 , +417 , +27457 , +-2649 , +22125 , +29997 , +5615 , +-563 , +-749 , +24647 , +-29605 , +-24799 , +28205 , +24797 , +17233 , +-10651 , +-10609 , +649 , +-6927 , +30699 , +2811 , +1913 , +13689 , +-26193 , +-12521 , +-22083 , +27253 , +-19993 , +31457 , +27935 , +27765 , +16939 , +-18773 , +-26241 , +-1209 , +26365 , +-31345 , +-2641 , +11443 , +9193 , +22125 , +-9541 , +15789 , +-15331 , +21341 , +14293 , +11791 , +10109 , +-22615 , +-24931 , +7891 , +21567 , +-3001 , +-4093 , +-5431 , +9475 , +-21807 , +-15973 , +-3633 , +27493 , +-30983 , +4979 , +-29045 , +24351 , +-8571 , +28277 , +11937 , +-20071 , +-61 , +811 , +-31383 , +7681 , +22149 , +-7887 , +-11987 , +-12823 , +-28775 , +-8461 , +-21797 , +27227 , +29373 , +18973 , +22593 , +12655 , +-21731 , +-1953 , +6339 , +-6039 , +13891 , +-12077 , +25747 , +589 , +-20075 , +26057 , +-27029 , +-11533 , +15951 , +-18641 , +-2111 , +9897 , +13301 , +-19115 , +-22653 , +5699 , +22857 , +-25513 , +21327 , +28599 , +-9265 , +-16405 , +15143 , +-29905 , +-16965 , +-8259 , +30637 , +-6995 , +-3479 , +-25535 , +-1321 , +21013 , +-7849 , +9237 , +17199 , +11725 , +-30811 , +-20017 , +14719 , +19925 , +-4099 , +-3489 , +12563 , +8031 , +14613 , +-5157 , +-32145 , +-16671 , +-7509 , +31969 , +-18303 , +25781 , +-26381 , +3181 , +-14239 , +-469 , +13971 , +-32213 , +19333 , +19239 , +13595 , +8023 , +13431 , +22577 , +17411 , +20497 , +-2541 , +-21227 , +15895 , +3383 , +-27333 , +2039 , +13691 , +-6475 , +-25333 , +-789 , +-12777 , +20077 , +28061 , +21003 , +-24931 , +15229 , +-8909 , +28693 , +-12303 , +-16859 , +-23559 , +-16513 , +-19661 , +-25577 , +-30151 , +18959 , +-31193 , +-29359 , +-12015 , +30963 , +7733 , +12665 , +-12879 , +18265 , +-20001 , +21933 , +12045 , +-15991 , +30907 , +-23837 , +-6631 , +10363 , +23017 , +19643 , +10367 , +-28177 , +24841 , +-10021 , +-31273 , +23815 , +12733 , +-26939 , +-30879 , +21337 , +12687 , +-8145 , +-11719 , +-12653 , +-24455 , +-17953 , +17429 , +-17785 , +22491 , +-4871 , +629 , +-13373 , +26601 , +12515 , +-2971 , +-15687 , +19373 , +32149 , +-24919 , +4927 , +-5255 , +7797 , +-9597 , +-14145 , +9701 , +-25173 , +24283 , +-327 , +5955 , +8189 , +-27641 , +-14869 , +-10349 , +18727 , +-22025 , +-12827 , +-6395 , +16561 , +26869 , +-21731 , +231 , +-4283 , +-19243 , +4489 , +-29401 , +3209 , +15029 , +-9289 , +26687 , +5501 , +16687 , +13931 , +14777 , +-15541 , +4889 , +-14167 , +4383 , +6813 , +-849 , +12379 , +-32397 , +-21635 , +21339 , +-21659 , +-3279 , +6573 , +32738 , +17717 , +25783 , +-31369 , +-31969 , +24807 , +20809 , +-4855 , +-4805 , +-2089 , +-2423 , +7761 , +-16533 , +25783 , +-20379 , +20813 , +12315 , +4905 , +-23655 , +749 , +-13903 , +-5153 , +28325 , +10337 , +-9275 , +-10977 , +6465 , +21239 , +-18737 , +8179 , +-1447 , +-9103 , +-21911 , +14769 , +-13185 , +-19487 , +15875 , +31253 , +-22287 , +-7431 , +-25573 , +26077 , +8445 , +25575 , +-22537 , +15843 , +11787 , +24499 , +-18983 , +12975 , +12297 , +27915 , +23997 , +5263 , +-19863 , +-6233 , +24715 , +-10187 , +12187 , +-2025 , +6097 , +-14389 , +-29959 , +25637 , +26621 , +-18295 , +31057 , +-16481 , +-21231 , +7381 , +-28723 , +5569 , +-26141 , +19149 , +12661 , +-23809 , +-32311 , +-12431 , +4899 , +-18595 , +1245 , +9769 , +-29193 , +22869 , +-26965 , +-21269 , +30811 , +-16097 , +-10383 , +11467 , +-17041 , +17553 , +14289 , +-12519 , +27397 , +-13451 , +-8435 , +-10511 , +28187 , +25699 , +19387 , +-2217 , +-18991 , +4629 , +-22781 , +-25129 , +-2845 , +26949 , +16979 , +2443 , +-18019 , +5887 , +14231 , +-31033 , +5207 , +-6275 , +-23571 , +-22751 , +-31637 , +25977 , +29929 , +-12781 , +25519 , +-21999 , +16449 , +-5617 , +-30615 , +29971 , +7689 , +-19949 , +21963 , +9689 , +-657 , +16335 , +-3351 , +-21341 , +27629 , +24105 , +-8141 , +3181 , +18181 , +25703 , +-23705 , +-31417 , +20595 , +-2629 , +-15851 , +-209 , +7409 , +32099 , +-15735 , +-12953 , +21857 , +-16579 , +27467 , +25163 , +-15731 , +21723 , +-1769 , +2991 , +7011 , +28453 , +-31917 , +20403 , +3487 , +-19353 , +18183 , +539 , +30991 , +-27915 , +4181 , +-21981 , +21835 , +-8143 , +31349 , +20709 , +14821 , +7221 , +15907 , +20509 , +295 , +12769 , +18083 , +14741 , +32073 , +2935 , +-15055 , +28397 , +-18389 , +-11345 , +-1281 , +-32261 , +-19063 , +15187 , +-3677 , +-2653 , +12215 , +-25771 , +-9701 , +30509 , +18139 , +19305 , +19005 , +10267 , +-25959 , +1305 , +4275 , +4233 , +-14757 , +-21661 , +-10383 , +20985 , +-18433 , +20169 , +19627 , +12981 , +-9967 , +-14863 , +2645 , +-26203 , +-32123 , +-19783 , +-3057 , +4771 , +-19733 , +19405 , +17323 , +-3243 , +32555 , +-15675 , +-1005 , +-18295 , +13757 , +-24905 , +-1321 , +13315 , +-21411 , +-7343 , +24595 , +-23837 , +-20409 , +23671 , +-31507 , +17519 , +4331 , +-6579 , +14481 , +-30343 , +15659 , +2525 , +31651 , +29735 , +-5361 , +-14805 , +29243 , +16475 , +-15877 , +-8763 , +-15271 , +-4995 , +32619 , +-32537 , +9443 , +-17697 , +-29143 , +-21491 , +14103 , +17291 , +-30711 , +4873 , +-30075 , +11939 , +-26091 , +-3937 , +-6773 , +12083 , +17241 , +-28005 , +-27067 , +22157 , +26117 , +-1429 , +525 , +22561 , +9015 , +27187 , +11119 , +-10801 , +31015 , +13931 , +26271 , +19657 , +7141 , +-19475 , +-2953 , +-17697 , +-32625 , +-25955 , +-17431 , +-27549 , +-27895 , +-19345 , +-9735 , +8825 , +3643 , +12557 , +16439 , +-7693 , +-4423 , +30181 , +6583 , +-1371 , +-2031 , +-15671 , +11907 , +26435 , +-15251 , +-31997 , +-611 , +-6733 , +22239 , +-23827 , +-14993 , +18407 , +-22519 , +-15865 , +12993 , +15673 , +9563 , +-26217 , +-4545 , +11323 , +-25903 , +28597 , +-16291 , +13589 , +32547 , +-4369 , +-31773 , +-2979 , +6781 , +14937 , +-24875 , +7791 , +32701 , +-27095 , +14837 , +-29891 , +-12253 , +31947 , +-4427 , +-13643 , +-15979 , +30843 , +9141 , +-9845 , +-8377 , +-26269 , +-12367 , +3741 , +32001 , +-8151 , +-9465 , +-10045 , +-11055 , +29961 , +-10331 , +25895 , +18241 , +887 , +18303 , +-14811 , +13843 , +4649 , +10643 , +-19813 , +29049 , +-20551 , +1363 , +30143 , +-20537 , +19385 , +11431 , +10115 , +1975 , +5193 , +27745 , +-15005 , +-6897 , +-20429 , +-7369 , +17339 , +28655 , +-21117 , +14133 , +12203 , +-8585 , +31901 , +-7747 , +-1697 , +-22269 , +20437 , +-13829 , +32505 , +6379 , +-18555 , +-6691 , +-4137 , +10677 , +21163 , +6539 , +-24455 , +13515 , +27647 , +3427 , +-6447 , +24501 , +-9343 , +12903 , +-26849 , +17619 , +1189 , +-21183 , +14661 , +-12649 , +18649 , +24501 , +-29021 , +-17101 , +-14687 , +-14185 , +-32657 , +-12583 , +-17097 , +-3515 , +3721 , +631 , +27803 , +10149 , +22231 , +-4893 , +-13777 , +-22641 , +19741 , +-26469 , +-7733 , +3799 , +15181 , +-6145 , +15193 , +-20301 , +-23953 , +-3581 , +7403 , +-27197 , +-27673 , +20839 , +341 , +22905 , +7003 , +-8587 , +6979 , +-25053 , +-12029 , +-13515 , +15567 , +20305 , +11397 , +-26075 , +-1123 , +27353 , +-20407 , +-6287 , +26995 , +-30641 , +-31401 , +31915 , +14671 , +-10507 , +-24665 , +-22777 , +-22275 , +-13767 , +771 , +18443 , +1845 , +11433 , +16469 , +-26417 , +11821 , +-11919 , +-15485 , +6063 , +-13645 , +-25521 , +2511 , +-26491 , +-14389 , +6155 , +22685 , +-4251 , +-18759 , +21357 , +3293 , +11727 , +-29783 , +15547 , +6873 , +-5525 , +-31047 , +13229 , +-10609 , +-29893 , +-24163 , +2533 , +-25461 , +2655 , +22961 , +10725 , +29499 , +11583 , +11917 , +7309 , +15565 , +-22963 , +-21211 , +9485 , +-28289 , +6457 , +24413 , +11109 , +-9599 , +31145 , +30753 , +-21171 , +-15037 , +-17297 , +-27649 , +-4669 , +-22701 , +21319 , +26171 , +6895 , +-5451 , +27405 , +-21909 , +-23895 , +6839 , +25709 , +12943 , +28007 , +-22195 , +32553 , +27045 , +14267 , +1253 , +12229 , +8899 , +-15793 , +5831 , +6083 , +3251 , +4173 , +-15903 , +6237 , +-24061 , +27755 , +31275 , +30655 , +-4699 , +27733 , +-29577 , +-28493 , +-1021 , +-21845 , +11977 , +1259 , +20631 , +28531 , +-3785 , +-5721 , +14337 , +-227 , +-22729 , +-6405 , +20135 , +-14353 , +24959 , +-15999 , +5059 , +9729 , +-28587 , +18065 , +-7937 , +-2633 , +-6545 , +4855 , +7825 , +-21321 , +5191 , +11311 , +3023 , +12645 , +-3087 , +-7139 , +-3005 , +10447 , +15741 , +-187 , +10575 , +-3273 , +23485 , +-27269 , +-26569 , +3833 , +31149 , +-23257 , +21699 , +6677 , +24647 , +-12043 , +-4017 , +10773 , +15575 , +16403 , +-2705 , +-19825 , +-6185 , +6369 , +24571 , +-19935 , +-15293 , +-29135 , +27049 , +24031 , +-12427 , +-2313 , +-31957 , +845 , +-1667 , +-6005 , +-11835 , +22753 , +24053 , +-13479 , +2399 , +-2835 , +30045 , +-7655 , +-1241 , +8991 , +-10511 , +15247 , +-20323 , +-12167 , +-23807 , +-31045 , +27445 , +-14905 , +11723 , +16783 , +24687 , +-5991 , +721 , +14897 , +-30109 , +-17739 , +-10063 , +-9553 , +25833 , +-12267 , +-29317 , +14127 , +-4313 , +29539 , +-15471 , +22193 , +-13909 , +12517 , +14071 , +-20923 , +-14077 , +32766 , +25385 , +18113 , +-11047 , +17185 , +-28287 , +-31499 , +27521 , +22095 , +-6147 , +3183 , +-24035 , +-7155 , +-28511 , +-19291 , +-1745 , +-18219 , +-28333 , +2229 , +-8785 , +19735 , +27689 , +18847 , +11943 , +-16979 , +8259 , +27381 , +-24757 , +27347 , +-23765 , +539 , +19851 , +30109 , +27299 , +-24583 , +25907 , +-11271 , +7943 , +-29385 , +10113 , +13079 , +3609 , +24817 , +12087 , +24687 , +30309 , +27127 , +18749 , +28979 , +17167 , +25209 , +-18005 , +24643 , +20531 , +26187 , +17781 , +23215 , +-12361 , +-23661 , +-10131 , +29349 , +-6487 , +-16889 , +8171 , +-3853 , +6925 , +23719 , +-3619 , +-781 , +-21949 , +-9749 , +-10137 , +-11505 , +24531 , +-29049 , +-26131 , +16817 , +1225 , +-20837 , +5563 , +-23365 , +-109 , +12653 , +19727 , +6023 , +15437 , +-17499 , +-3905 , +5463 , +-2655 , +1019 , +19265 , +16463 , +30241 , +-21891 , +-8365 , +-30997 , +27159 , +-1477 , +-27897 , +24575 , +-9755 , +-29307 , +-16543 , +21797 , +25815 , +19615 , +-915 , +-27715 , +-11135 , +-16641 , +473 , +-17313 , +-24433 , +9983 , +29707 , +-22313 , +31523 , +24603 , +-2635 , +24729 , +32173 , +-2145 , +22009 , +-3139 , +3651 , +30701 , +13045 , +29815 , +5489 , +24103 , +-5921 , +-14579 , +-25443 , +-19853 , +9633 , +-32691 , +27865 , +-17751 , +-1815 , +-30071 , +-14789 , +-16491 , +-18229 , +-14065 , +-14413 , +23713 , +-27955 , +29215 , +-24727 , +21021 , +8585 , +22369 , +7055 , +20973 , +-8507 , +-11039 , +-19521 , +-16701 , +-13825 , +-24953 , +-23861 , +-10791 , +7063 , +9227 , +10523 , +15143 , +23637 , +-15501 , +-28793 , +24599 , +-18031 , +-32253 , +677 , +-17207 , +-4677 , +-31813 , +-8529 , +21441 , +-27259 , +-1711 , +-31797 , +30749 , +18795 , +-17247 , +19189 , +20053 , +21459 , +21419 , +-19643 , +-141 , +23461 , +-28149 , +24533 , +5827 , +-9379 , +-28435 , +-497 , +525 , +-17233 , +13705 , +-21359 , +11351 , +-3949 , +-487 , +-1421 , +-21745 , +23519 , +19795 , +5939 , +-2609 , +-3995 , +-5027 , +19197 , +-24439 , +19081 , +-1209 , +20367 , +-28599 , +-21675 , +2059 , +-24187 , +-23955 , +-22767 , +-31759 , +25151 , +15953 , +24675 , +20383 , +-7637 , +-13927 , +-22561 , +-27267 , +27557 , +30425 , +-10209 , +-21827 , +26195 , +26327 , +-14749 , +11973 , +27375 , +-27589 , +-24675 , +8497 , +24493 , +-32303 , +2581 , +9799 , +13581 , +9015 , +25465 , +-19985 , +23345 , +-2019 , +29559 , +20779 , +-30791 , +-11785 , +27353 , +-13805 , +-7141 , +15419 , +-30957 , +19011 , +15479 , +-241 , +12903 , +23519 , +18165 , +-19315 , +-1929 , +-9981 , +-25709 , +-6025 , +10075 , +-27201 , +29835 , +-17819 , +30013 , +-1907 , +-12513 , +31375 , +-32143 , +14665 , +1269 , +14583 , +-28665 , +32425 , +30195 , +-16603 , +17133 , +-28105 , +23187 , +-5025 , +-13443 , +25287 , +22197 , +-5017 , +18843 , +3439 , +-6903 , +16549 , +-15027 , +-23299 , +13007 , +5105 , +-27695 , +28665 , +-31673 , +-12105 , +-32461 , +-10995 , +-18059 , +29123 , +-27029 , +-20983 , +2949 , +-31383 , +-11281 , +14683 , +-25953 , +23367 , +-18225 , +25087 , +-7105 , +21625 , +-4533 , +-27141 , +-17905 , +-12719 , +-4119 , +-7333 , +-11969 , +-24689 , +2069 , +-27741 , +-32171 , +-24551 , +31021 , +-565 , +-11887 , +13109 , +11047 , +-14669 , +22463 , +19521 , +-19047 , +18463 , +9101 , +-6683 , +7777 , +22065 , +11113 , +25553 , +9393 , +6999 , +26579 , +-10503 , +28847 , +17103 , +11831 , +-25537 , +32643 , +10645 , +-7097 , +19895 , +-23555 , +19941 , +-23599 , +32353 , +-3167 , +-19163 , +-6375 , +14417 , +30791 , +-32655 , +-10835 , +-19079 , +32299 , +26491 , +18881 , +19159 , +22157 , +21019 , +9731 , +-461 , +26307 , +-14285 , +5115 , +-16821 , +-9257 , +28723 , +17113 , +-19041 , +-9577 , +21519 , +16081 , +-20591 , +-31689 , +9393 , +30967 , +2103 , +-22691 , +13307 , +-26737 , +7801 , +30149 , +23861 , +9967 , +-16165 , +5711 , +-27635 , +-15667 , +-29515 , +27553 , +20999 , +20511 , +-18471 , +-6349 , +-25985 , +24427 , +15587 , +-16139 , +-13035 , +20391 , +-7711 , +27479 , +-331 , +18829 , +4493 , +-25615 , +4345 , +-21645 , +-245 , +-16241 , +16441 , +-605 , +3101 , +14543 , +24563 , +1845 , +-5671 , +11319 , +32195 , +7013 , +27625 , +21709 , +8935 , +14185 , +-31177 , +-27085 , +-5075 , +2257 , +27953 , +-18121 , +-20375 , +29777 , +20597 , +9203 , +-4745 , +-19157 , +-22505 , +-6563 , +-19539 , +-21255 , +-29619 , +-3223 , +-14381 , +31751 , +4013 , +-8553 , +13207 , +-1487 , +5089 , +-2543 , +-881 , +10295 , +-28441 , +4421 , +14763 , +12693 , +-14661 , +-5133 , +16171 , +5851 , +20897 , +26063 , +6427 , +-26487 , +-26419 , +32409 , +3145 , +31325 , +-28765 , +26281 , +21949 , +-18635 , +16751 , +31769 , +-8011 , +-17049 , +8091 , +-29621 , +11027 , +19343 , +-30107 , +12815 , +4193 , +1523 , +-29667 , +-22477 , +-19645 , +23633 , +16087 , +-5983 , +15725 , +-10179 , +-11097 , +28653 , +-20963 , +27643 , +-17833 , +32121 , +28439 , +-9777 , +-13153 , +10247 , +-6119 , +-13349 , +6111 , +7887 , +-14127 , +-19339 , +6741 , +28445 , +16727 , +3843 , +211 , +9823 , +-7895 , +6473 , +-10757 , +10445 , +21663 , +-25269 , +7161 , +5229 , +-18209 , +-7259 , +-14159 , +-30529 , +-16801 , +26203 , +7299 , +-21817 , +20949 , +23603 , +19325 , +15783 , +945 , +-19303 , +28943 , +10175 , +-6635 , +-25629 , +-14773 , +-17349 , +6483 , +8249 , +-28005 , +-24269 , +-16681 , +3817 , +-12557 , +-21955 , +-30035 , +-24009 , +-3183 , +32649 , +-21645 , +6083 , +-6095 , +26999 , +16591 , +-14507 , +-28989 , +6317 , +6255 , +-11717 , +-8021 , +-15689 , +-5773 , +799 , +5741 , +27413 , +-14731 , +-2467 , +-11793 , +-20265 , +-523 , +8933 , +-15571 , +-1861 , +8537 , +-9341 , +-16525 , +19385 , +27231 , +-7997 , +-15601 , +-15835 , +14105 , +-25785 , +-10861 , +-11453 , +-11167 , +-26979 , +18565 , +24929 , +20183 , +21653 , +18585 , +-9623 , +-32175 , +4379 , +14697 , +17665 , +8157 , +-29033 , +-11345 , +-28127 , +-7631 , +-32077 , +32251 , +2853 , +-22365 , +-17465 , +-10261 , +13421 , +-20315 , +-26977 , +-4123 , +-913 , +-23103 , +-8991 , +6989 , +-28843 , +-16383 , +-23585 , +-5829 , +-22771 , +-22277 , +17391 , +10167 , +-20501 , +24379 , +65 , +29555 , +-26187 , +-12225 , +30527 , +18939 , +-21177 , +24819 , +29527 , +5747 , +16033 , +7329 , +13413 , +12493 , +-27767 , +-15761 , +-13957 , +18305 , +-10599 , +26969 , +-27837 , +11209 , +28379 , +-3423 , +-31025 , +30801 , +-27673 , +719 , +18685 , +2679 , +30319 , +-18143 , +-17857 , +-14851 , +-10911 , +-8821 , +2819 , +-25787 , +22395 , +-17107 , +-3969 , +18437 , +-32413 , +27971 , +4621 , +-13689 , +-24513 , +-21331 , +18183 , +-171 , +-32559 , +7123 , +-17127 , +24955 , +19207 , +817 , +-24805 , +25915 , +23067 , +24639 , +21613 , +25927 , +26915 , +28913 , +-3899 , +-25995 , +-5069 , +30129 , +-4969 , +5627 , +-4629 , +-7729 , +-16933 , +13859 , +18837 , +-19843 , +26991 , +-29303 , +-26177 , +9293 , +-23309 , +-19251 , +-19639 , +32545 , +-24299 , +-303 , +1289 , +12449 , +5235 , +-30871 , +-19495 , +-4803 , +-24851 , +-27495 , +-13511 , +3999 , +7557 , +-15797 , +23131 , +-4449 , +1705 , +-3955 , +-10807 , +25031 , +26395 , +27707 , +-27283 , +11325 , +-26819 , +19011 , +-14537 , +-31165 , +16623 , +27997 , +-20943 , +32047 , +-12825 , +11835 , +-31217 , +25055 , +-10617 , +7751 , +-7339 , +-583 , +-22223 , +-8999 , +-6175 , +-14825 , +-32213 , +30449 , +9229 , +-14775 , +-29719 , +18795 , +31811 , +30729 , +16367 , +-8771 , +-5353 , +17009 , +16419 , +-18137 , +30681 , +-10373 , +16555 , +-27019 , +14775 , +10221 , +6721 , +555 , +-16565 , +9695 , +-25337 , +-11959 , +-19783 , +3491 , +15335 , +27259 , +4681 , +27979 , +10345 , +22997 , +-10891 , +-23909 , +-2297 , +9991 , +22155 , +1921 , +25607 , +-6631 , +22723 , +-31477 , +20693 , +31395 , +723 , +-15129 , +-28199 , +1409 , +-23029 , +-18097 , +-23345 , +29967 , +-22037 , +-19571 , +-6237 , +-20515 , +29753 , +-16151 , +26559 , +20975 , +-23135 , +-31189 , +-7697 , +29799 , +-32061 , +20871 , +2739 , +30671 , +-7729 , +-25823 , +-18669 , +18625 , +29859 , +-21509 , +-513 , +5929 , +-14505 , +-23691 , +-5595 , +-2059 , +-13473 , +-27839 , +-11195 , +26967 , +18209 , +-5669 , +-501 , +12661 , +517 , +-7297 , +-31383 , +-28767 , +1307 , +14757 , +18543 , +14361 , +-14295 , +-14083 , +-11875 , +4661 , +-23741 , +26073 , +-6973 , +12581 , +23783 , +-26831 , +-15275 , +-217 , +11413 , +28697 , +-14527 , +4927 , +2531 , +16311 , +22351 , +-22155 , +-24549 , +20407 , +-4113 , +13695 , +-16819 , +26961 , +13717 , +2053 , +-25625 , +22701 , +-17003 , +32345 , +-13867 , +9963 , +-24971 , +-19289 , +10257 , +17047 , +24775 , +12977 , +-18499 , +20123 , +26755 , +-29939 , +-24133 , +-12353 , +28383 , +25809 , +18885 , +28829 , +9377 , +-6185 , +-14837 , +5141 , +-27393 , +875 , +-27843 , +28241 , +24821 , +-30839 , +-8909 , +23599 , +27413 , +-30569 , +13305 , +-20155 , +3051 , +1429 , +1389 , +-19377 , +26319 , +18649 , +-19625 , +557 , +-2243 , +-1205 , +-25095 , +3931 , +-4435 , +25113 , +-1225 , +-29 , +31465 , +-16659 , +-11745 , +3553 , +-29459 , +19113 , +-3317 , +13935 , +14389 , +-15713 , +17457 , +25885 , +17051 , +69 , +15045 , +-10761 , +-849 , +-27793 , +-10105 , +-6675 , +-1395 , +-10485 , +1507 , +2515 , +-15055 , +30803 , +-24447 , +9177 , +7257 , +-6009 , +5737 , +-4227 , +-7977 , +-20183 , +-6775 , +-17393 , +16229 , +8875 , +-10269 , +11673 , +13319 , +21941 , +21521 , +15463 , +-549 , +-2351 , +-26009 , +10995 , +-25741 , +-11097 , +18061 , +-21917 , +-6227 , +-22345 , +-4717 , +-6785 , +28431 , +4755 , +12419 , +-21975 , +-27241 , +15757 , +7049 , +26969 , +9499 , +10487 , +10617 , +17803 , +-9189 , +2783 , +-15369 , +-6205 , +5405 , +-15045 , +-26623 , +21245 , +7811 , +-6741 , +-26863 , +28201 , +23267 , +10155 , +-847 , +31905 , +-15901 , +-3761 , +12437 , +15649 , +-9849 , +-15749 , +-8915 , +-6337 , +-16363 , +3737 , +4807 , +-16539 , +24163 , +30925 , +-12515 , +31045 , +23227 , +-5449 , +-16011 , +8409 , +-7133 , +32163 , +-23759 , +-15923 , +-4543 , +-20925 , +-783 , +-31351 , +-2637 , +-11541 , +-20445 , +32663 , +-6949 , +19521 , +7451 , +-8023 , +12617 , +26749 , +15793 , +-14329 , +-13951 , +28955 , +-29611 , +27539 , +-5277 , +-9451 , +4007 , +-12751 , +31481 , +4511 , +25231 , +-17203 , +-3637 , +-11431 , +4307 , +18891 , +32457 , +-26101 , +8249 , +32513 , +28303 , +1241 , +7697 , +32307 , +29769 , +-17153 , +-30381 , +-14331 , +-5371 , +-13049 , +-3777 , +-7819 , +-22641 , +-7549 , +-24477 , +4051 , +29385 , +29251 , +11333 , +25403 , +-15231 , +14091 , +-16013 , +-14449 , +-10553 , +723 , +-31721 , +21475 , +-22071 , +23153 , +-8935 , +-28539 , +4139 , +-11293 , +2987 , +-5271 , +23513 , +-20747 , +-11407 , +4903 , +-15509 , +-24439 , +-24827 , +28789 , +6125 , +18499 , +-4321 , +30229 , +-7353 , +18629 , +28201 , +-169 , +-30969 , +31339 , +-32685 , +29965 , +29637 , +12411 , +-22485 , +-3833 , +4337 , +2279 , +-26689 , +6145 , +27955 , +15993 , +17955 , +-7643 , +20287 , +-2665 , +-7777 , +2559 , +-16597 , +31605 , +-2509 , +23033 , +-24501 , +-4151 , +-24389 , +-28601 , +29577 , +20749 , +9859 , +4465 , +-9671 , +25387 , +-13987 , +8507 , +-3725 , +26821 , +12353 , +-9689 , +7665 , +9945 , +15451 , +-25753 , +24667 , +11021 , +-23895 , +9561 , +-13783 , +-13227 , +8721 , +7293 , +10997 , +-8647 , +-20997 , +10991 , +-29095 , +-29051 , +25957 , +30811 , +-23999 , +25991 , +-20865 , +-20357 , +-25147 , +-8001 , +20163 , +20485 , +-16251 , +-24545 , +-10361 , +28721 , +633 , +-25157 , +16159 , +-14171 , +3153 , +26637 , +-405 , +8181 , +4167 , +-10597 , +-29961 , +-7535 , +-25735 , +12613 , +-31347 , +6219 , +-2105 , +16873 , +30031 , +28739 , +13855 , +18599 , +26451 , +-25757 , +31071 , +19095 , +19125 , +-21155 , +-26199 , +-19719 , +24879 , +-17383 , +-18375 , +-16643 , +-25541 , +30127 , +-9275 , +-21527 , +16027 , +-6937 , +11591 , +8157 , +-25985 , +7209 , +-4759 , +-15093 , +17431 , +-263 , +-17851 , +-28829 , +-28503 , +-7701 , +15829 , +-23331 , +-17877 , +14621 , +-9035 , +24607 , +32609 , +3379 , +32143 , +26053 , +-26519 , +28363 , +225 , +17419 , +-10275 , +-24463 , +-32411 , +-27375 , +20585 , +12067 , +-2851 , +7051 , +22235 , +-20167 , +17777 , +-11785 , +-18229 , +25579 , +31621 , +25699 , +-95 , +24387 , +4111 , +3221 , +6201 , +-26475 , +-137 , +18635 , +14071 , +27511 , +-19225 , +25841 , +20579 , +-7879 , +26147 , +20057 , +-457 , +28381 , +-2075 , +-22025 , +10499 , +24981 , +695 , +-23279 , +20027 , +-20051 , +4165 , +30847 , +-17705 , +29713 , +-22221 , +5723 , +-28057 , +-24001 , +19329 , +-1469 , +-1365 , +28861 , +-7851 , +-27639 , +17323 , +-5097 , +-12191 , +17645 , +25679 , +5203 , +14763 , +26455 , +-23689 , +12003 , +-32269 , +22793 , +-14951 , +-30929 , +-17785 , +-29 , +-26931 , +21879 , +657 , +-16115 , +10605 , +1115 , +30977 , +25273 , +-24275 , +-29493 , +-10537 , +-12201 , +-7501 , +8325 , +18943 , +14667 , +-89 , +-9465 , +-22355 , +-32213 , +-18597 , +-20217 , +-27349 , +-32655 , +-7217 , +22131 , +-21951 , +-1863 , +11101 , +21217 , +18425 , +-10385 , +-12607 , +-889 , +6409 , +-25579 , +-5187 , +-28233 , +-5983 , +28397 , +3107 , +10457 , +-7995 , +-9923 , +22911 , +-20771 , +-14041 , +-26625 , +19745 , +-21453 , +24187 , +-32487 , +13495 , +2121 , +23125 , +-3301 , +25455 , +-31875 , +17275 , +-14477 , +26495 , +8089 , +-24897 , +16167 , +7243 , +11979 , +-26535 , +-7675 , +-3851 , +16665 , +-16961 , +-14231 , +15223 , +-22437 , +-8201 , +18281 , +-4031 , +-13643 , +-18823 , +30613 , +-27067 , +-1139 , +23163 , +-29145 , +-12393 , +4869 , +13013 , +-32573 , +20101 , +31727 , +26707 , +-5203 , +-28883 , +-4021 , +31369 , +-19849 , +11669 , +-25545 , +3381 , +21325 , +12357 , +-8339 , +-31217 , +25755 , +8027 , +25915 , +-27871 , +13643 , +16425 , +-13573 , +12711 , +1917 , +-12989 , +-29435 , +19805 , +-8761 , +-31961 , +29229 , +-28577 , +21211 , +22849 , +11709 , +31609 , +29649 , +-16487 , +28643 , +24329 , +5333 , +14549 , +7351 , +19531 , +-26529 , +-22305 , +-7771 , +-26819 , +-24333 , +12287 , +-7825 , +241 , +-23217 , +-5531 , +-20831 , +8801 , +-8407 , +27725 , +19593 , +12243 , +-29593 , +21143 , +28337 , +-21343 , +-1327 , +-16425 , +-20781 , +10141 , +22099 , +7665 , +-3757 , +-26645 , +-20053 , +-971 , +-20419 , +29259 , +16809 , +25075 , +25777 , +3837 , +17123 , +28049 , +-14621 , +30743 , +-32279 , +-26587 , +7319 , +14425 , +-505 , +30099 , +19981 , +17033 , +-24969 , +18713 , +-1663 , +-30391 , +29205 , +18033 , +15651 , +24433 , +29089 , +-10393 , +28555 , +14561 , +15469 , +-16917 , +32441 , +-7195 , +-14435 , +27311 , +11647 , +-11523 , +30679 , +24641 , +-6261 , +-28861 , +-25209 , +-1381 , +25549 , +-5317 , +-13431 , +29507 , +-12931 , +3635 , +103 , +31197 , +-21621 , +-4085 , +6681 , +14661 , +16027 , +23969 , +-29653 , +8489 , +-29317 , +7581 , +-12151 , +19491 , +-10215 , +19913 , +-30041 , +-9659 , +-22269 , +-28437 , +-10939 , +6209 , +15699 , +9509 , +-19813 , +-13577 , +31539 , +31419 , +5915 , +30607 , +11979 , +25469 , +-31063 , +17 , +-14909 , +29333 , +-17335 , +27775 , +16687 , +-23327 , +21603 , +14441 , +-27119 , +-5683 , +-3729 , +-755 , +13393 , +-23385 , +-11461 , +-12317 , +-5079 , +-16773 , +22679 , +11713 , +-5587 , +24685 , +25489 , +-13721 , +439 , +-4473 , +6193 , +7333 , +-537 , +23323 , +-4693 , +-283 , +12565 , +27287 , +-30183 , +15439 , +-1333 , +-35 , +24759 , +25175 , +31809 , +2335 , +-30063 , +-20773 , +13133 , +9519 , +-11831 , +29371 , +-19485 , +-26277 , +26433 , +-16145 , +14343 , +-20533 , +15071 , +-15843 , +15947 , +5709 , +28219 , +-31561 , +-4415 , +21945 , +-9761 , +-24179 , +32371 , +-1599 , +7417 , +-29465 , +18785 , +-32439 , +12183 , +-5087 , +-9481 , +-20665 , +-4259 , +-14403 , +-25345 , +21521 , +-24899 , +-3587 , +25889 , +10043 , +-12623 , +31229 , +-26411 , +-13841 , +-21777 , +-31927 , +8159 , +-30271 , +8357 , +23027 , +-8889 , +-1013 , +-10317 , +6963 , +-6453 , +2499 , +30295 , +-13705 , +13025 , +-31789 , +10101 , +11001 , +-2779 , +-10253 , +-9405 , +13793 , +24919 , +-515 , +14987 , +-31529 , +3281 , +13771 , +-15273 , +-30439 , +-22909 , +-21111 , +3637 , +-6375 , +15715 , +-22383 , +-24861 , +-12661 , +-12949 , +16063 , +23447 , +-22771 , +19217 , +19533 , +-93 , +-5843 , +-6853 , +-21973 , +-26947 , +31757 , +-19013 , +18129 , +29109 , +28537 , +-26555 , +14243 , +-29279 , +27259 , +24551 , +23227 , +-6747 , +-22923 , +8963 , +-24245 , +-22753 , +-12611 , +-10809 , +-26003 , +-16283 , +-25425 , +-5347 , +22147 , +-15877 , +-30649 , +13361 , +15119 , +-30131 , +25913 , +-18851 , +-8449 , +-19483 , +17551 , +-20569 , +-30827 , +15905 , +29363 , +-32329 , +23989 , +26737 , +-5609 , +-17585 , +-3139 , +14345 , +4673 , +-1979 , +13281 , +-24547 , +9063 , +-12295 , +20229 , +-15209 , +1677 , +-30131 , +-15349 , +20305 , +2577 , +-11489 , +6073 , +20423 , +17103 , +9275 , +21763 , +-25257 , +-3667 , +7645 , +-4627 , +13303 , +-14911 , +-31329 , +5343 , +-31895 , +21213 , +9211 , +9853 , +10483 , +-27477 , +14393 , +15357 , +2977 , +-10681 , +-17683 , +32265 , +21229 , +-10665 , +9963 , +20485 , +12295 , +32669 , +199 , +-5125 , +-3713 , +3609 , +-11071 , +-31003 , +22919 , +-1895 , +-7351 , +-27255 , +-20823 , +30419 , +13295 , +18901 , +32505 , +-1029 , +18139 , +-8019 , +-29227 , +32227 , +7375 , +-10159 , +-7143 , +-8053 , +-12913 , +-22743 , +31445 , +24123 , +25831 , +2849 , +30861 , +17435 , +15897 , +-30329 , +30949 , +-9395 , +-27167 , +14165 , +-10525 , +-10621 , +-29987 , +25113 , +29093 , +7191 , +17553 , +12611 , +-7279 , +17571 , +30943 , +-10243 , +-23523 , +-23013 , +2037 , +28553 , +3061 , +17253 , +-6447 , +4629 , +-19519 , +30827 , +4143 , +19983 , +9557 , +-17735 , +-19447 , +-30199 , +22379 , +18071 , +23947 , +28931 , +-5155 , +4249 , +18313 , +-177 , +-22437 , +-11331 , +-26757 , +18397 , +8611 , +-27645 , +-18697 , +-30177 , +4411 , +28035 , +-31843 , +-20391 , +19879 , +2051 , +-29277 , +-12675 , +-8929 , +-30955 , +7349 , +-18049 , +6861 , +20137 , +13189 , +20277 , +26239 , +29735 , +18861 , +-31073 , +22241 , +13323 , +-3013 , +-7977 , +-6597 , +17399 , +13467 , +21071 , +-28259 , +22861 , +-23023 , +15551 , +-7519 , +-17335 , +16823 , +-28305 , +23453 , +16279 , +-3853 , +-19439 , +15967 , +29803 , +-22935 , +13859 , +9573 , +29465 , +13691 , +695 , +-6255 , +4143 , +-24517 , +4827 , +-16795 , +-10739 , +5095 , +16995 , +9911 , +-25867 , +19423 , +23885 , +29681 , +2993 , +-27873 , +-623 , +-29251 , +671 , +7219 , +20857 , +-12217 , +849 , +-6219 , +25219 , +-30989 , +-19813 , +-3781 , +-2905 , +-1651 , +-23749 , +-9507 , +-27069 , +-31727 , +20191 , +-12511 , +-1949 , +-20269 , +-27703 , +-11911 , +10147 , +-12995 , +-28955 , +13625 , +-17019 , +-3829 , +10845 , +29457 , +-23999 , +-4097 , +14517 , +5377 , +30507 , +11799 , +29791 , +-3883 , +16767 , +-12729 , +15319 , +26907 , +28093 , +13239 , +25149 , +-4965 , +-15483 , +19825 , +-5019 , +27729 , +25065 , +-23393 , +4725 , +-29 , +23625 , +-23233 , +24057 , +28825 , +4007 , +6495 , +15491 , +-7465 , +-14205 , +20183 , +-8519 , +22031 , +-11981 , +-8327 , +-17423 , +13125 , +-32585 , +-27697 , +-28081 , +-24073 , +25111 , +22611 , +15185 , +-9307 , +3121 , +-17121 , +11507 , +13755 , +-15841 , +-1993 , +-195 , +6677 , +29697 , +-7639 , +-12705 , +-23057 , +14435 , +-6819 , +-11951 , +10081 , +-10747 , +22455 , +-805 , +12625 , +30273 , +14051 , +2873 , +32245 , +6109 , +-16645 , +-16335 , +22465 , +-9631 , +-11315 , +-15961 , +-16151 , +-17931 , +-19315 , +-9033 , +4431 , +-11343 , +-3573 , +3921 , +17151 , +-13697 , +8049 , +11849 , +-23253 , +25705 , +13681 , +32762 , +11677 , +-1929 , +8205 , +9037 , +8371 , +-15099 , +28351 , +-25753 , +18387 , +-14691 , +-24775 , +22447 , +28265 , +10063 , +-1383 , +-28563 , +23897 , +-8575 , +32041 , +20451 , +3323 , +-26285 , +-16243 , +-29 , +17807 , +-31889 , +24705 , +21479 , +26171 , +2153 , +-11761 , +-6231 , +-30083 , +9607 , +9547 , +27199 , +-14809 , +25647 , +-22143 , +-21079 , +-20525 , +5291 , +-5127 , +29431 , +-3617 , +-7795 , +2341 , +19157 , +6629 , +21379 , +-14237 , +25253 , +24241 , +23985 , +31275 , +-27101 , +-27463 , +-30075 , +4301 , +-25241 , +2323 , +-7917 , +27559 , +-20589 , +31473 , +6889 , +19679 , +29151 , +-5221 , +17007 , +-3689 , +-29903 , +31969 , +20917 , +-15189 , +-19397 , +5651 , +-5681 , +9187 , +-25587 , +1917 , +-17745 , +-20565 , +31023 , +25699 , +-19585 , +7509 , +-24769 , +19305 , +-27793 , +963 , +-3845 , +-10849 , +-3305 , +-25947 , +-31001 , +-7191 , +24139 , +-7111 , +25183 , +-31997 , +-27019 , +14705 , +-31441 , +7663 , +-27287 , +-20287 , +17835 , +14067 , +26817 , +22335 , +14151 , +-8431 , +32179 , +-19341 , +32689 , +-23557 , +30059 , +-28547 , +-3993 , +11409 , +6621 , +29907 , +-17199 , +15313 , +-29915 , +-8323 , +9427 , +21077 , +15709 , +-24375 , +-5139 , +-22965 , +-8461 , +23425 , +-2863 , +-22035 , +-16517 , +-24663 , +-9869 , +-10125 , +-12521 , +-26707 , +-10319 , +401 , +-12737 , +-16343 , +-5543 , +-13457 , +-14813 , +-24049 , +26319 , +-23775 , +24957 , +1903 , +-2277 , +-11369 , +15853 , +-23905 , +18569 , +-1245 , +-12849 , +-24575 , +18107 , +-26779 , +-7531 , +6709 , +15175 , +-8247 , +30617 , +-5933 , +-22071 , +-22913 , +-10881 , +-15971 , +16509 , +30699 , +-23035 , +9277 , +-19111 , +-20307 , +4187 , +2177 , +-6239 , +-15865 , +30211 , +-14589 , +7687 , +23781 , +-6111 , +13431 , +-18121 , +-17593 , +-4781 , +26447 , +13049 , +-16319 , +-20467 , +8191 , +-15933 , +9847 , +11635 , +19375 , +30937 , +29961 , +31913 , +-26245 , +15579 , +-3311 , +-14671 , +-26079 , +25823 , +20899 , +1729 , +25149 , +24595 , +17463 , +11037 , +9989 , +14279 , +-16473 , +-20883 , +-12935 , +17933 , +6061 , +16789 , +-7133 , +-1835 , +-19761 , +-25075 , +-181 , +-1675 , +-29469 , +6329 , +-4177 , +-28459 , +16383 , +3397 , +-13381 , +-24583 , +-13325 , +-17931 , +17219 , +1309 , +-11197 , +-23547 , +13751 , +-15023 , +-29539 , +7291 , +735 , +-11639 , +3023 , +-635 , +-29165 , +-14785 , +15687 , +14407 , +27631 , +26751 , +10495 , +19265 , +12941 , +23435 , +-13825 , +14619 , +25667 , +-15381 , +11093 , +6147 , +-4915 , +17671 , +897 , +-11903 , +-22253 , +10817 , +-31107 , +10967 , +-3747 , +5259 , +-22997 , +-21043 , +-25083 , +1151 , +31053 , +-30187 , +32439 , +6393 , +259 , +1819 , +-17375 , +-9687 , +1215 , +-24995 , +7221 , +26935 , +15547 , +22089 , +-24361 , +27725 , +-32009 , +30099 , +31005 , +3895 , +17067 , +9991 , +-17149 , +-3971 , +-8639 , +9703 , +-5215 , +21235 , +17361 , +2757 , +-23579 , +27609 , +26641 , +20689 , +-28719 , +9579 , +-8235 , +-21571 , +-1495 , +11779 , +20481 , +-14835 , +1711 , +-21593 , +-5113 , +-13 , +1247 , +27689 , +-17705 , +18085 , +-10977 , +-5703 , +-9633 , +-25549 , +-10111 , +-1023 , +31103 , +26597 , +25327 , +-29255 , +-16259 , +9999 , +10225 , +11973 , +24585 , +-27035 , +-26155 , +-9529 , +-343 , +-5153 , +-19591 , +-13253 , +15541 , +14597 , +9327 , +-19443 , +-31021 , +-29237 , +22473 , +11697 , +28389 , +-3095 , +19779 , +-14405 , +-15471 , +-9543 , +-17155 , +30971 , +7717 , +2945 , +32189 , +-9717 , +7971 , +-16803 , +-23145 , +-1163 , +4393 , +-6267 , +23859 , +12349 , +10865 , +21811 , +-8833 , +-23293 , +9419 , +-18957 , +-28701 , +7065 , +25613 , +8061 , +-14073 , +-23787 , +25361 , +11791 , +5621 , +-23441 , +-24787 , +21573 , +-27671 , +7067 , +-17883 , +29549 , +19061 , +21787 , +2735 , +21599 , +71 , +2071 , +21341 , +6367 , +-32167 , +9467 , +-10211 , +15719 , +-10837 , +12427 , +-30157 , +17285 , +19325 , +-31879 , +-32089 , +-25413 , +-4091 , +18051 , +-31925 , +-4663 , +19369 , +-31995 , +-18907 , +17035 , +-4429 , +8213 , +25457 , +19029 , +-16501 , +9239 , +-10733 , +13511 , +-31887 , +4829 , +9879 , +18211 , +-26185 , +-16333 , +9373 , +-15831 , +24941 , +28417 , +5851 , +12399 , +16811 , +-27427 , +-30319 , +-19145 , +-13255 , +6699 , +-7295 , +29635 , +-3379 , +28331 , +-1689 , +-22727 , +-14645 , +19091 , +22515 , +-32021 , +-17555 , +29745 , +31807 , +29505 , +-7545 , +25077 , +-19769 , +-10495 , +7101 , +4371 , +-11039 , +-14035 , +-20937 , +-5995 , +-25417 , +4959 , +17629 , +247 , +-14405 , +-8035 , +-15091 , +-22465 , +-16475 , +18609 , +-2093 , +31377 , +487 , +19453 , +32161 , +-6325 , +-607 , +22497 , +1163 , +31385 , +-24541 , +-5247 , +14583 , +-15471 , +18397 , +29993 , +26845 , +11981 , +21975 , +33 , +20855 , +-21127 , +5555 , +-13563 , +3973 , +-32521 , +13333 , +24225 , +-22027 , +751 , +31655 , +15679 , +12073 , +-15895 , +4241 , +-15733 , +-9049 , +-13719 , +-7575 , +19427 , +18775 , +29821 , +-29523 , +16691 , +2611 , +-29215 , +24007 , +5707 , +-13947 , +14479 , +-17293 , +-9035 , +18591 , +21981 , +-23615 , +32273 , +17423 , +-10739 , +28045 , +14063 , +-19873 , +-15255 , +-23689 , +27169 , +21823 , +26595 , +3671 , +25745 , +5451 , +20509 , +-17351 , +10661 , +8255 , +-22771 , +13521 , +-8181 , +16807 , +-24813 , +-27529 , +-2281 , +28197 , +21899 , +-14943 , +-25447 , +-1763 , +495 , +-28465 , +-25805 , +27889 , +-13979 , +-17643 , +14651 , +32187 , +3807 , +-5371 , +12291 , +3717 , +-26707 , +-29655 , +21439 , +-16129 , +23705 , +26883 , +981 , +1971 , +24443 , +13179 , +-1097 , +12999 , +23895 , +-19491 , +-25539 , +28463 , +-19215 , +-10671 , +17787 , +12385 , +23009 , +20177 , +-9955 , +-875 , +11317 , +2973 , +-717 , +4987 , +-29567 , +11839 , +14233 , +-6291 , +-31623 , +-15625 , +31173 , +-7889 , +23565 , +-4425 , +13601 , +26149 , +-3337 , +-13411 , +-28699 , +-26365 , +-18719 , +-21527 , +-11667 , +-13039 , +-29201 , +-1161 , +-23279 , +9179 , +-29215 , +30643 , +13947 , +19823 , +-10327 , +-2539 , +-7545 , +-7411 , +28541 , +28953 , +29073 , +21605 , +26997 , +-27727 , +-30637 , +-8369 , +17063 , +31557 , +24637 , +-30207 , +-16721 , +-6105 , +24649 , +-26681 , +8667 , +-27509 , +-20905 , +28731 , +8117 , +-5631 , +20741 , +28925 , +22049 , +-12953 , +-1537 , +-24083 , +-21263 , +-18067 , +4325 , +-15391 , +29187 , +-8321 , +5785 , +-20003 , +-30253 , +-30907 , +-1767 , +-29489 , +-29545 , +25755 , +28631 , +-22083 , +10197 , +7175 , +-1903 , +-17785 , +-25477 , +-21071 , +-29523 , +10525 , +-20105 , +-291 , +-22775 , +7477 , +-3375 , +14813 , +-19879 , +9343 , +-27329 , +15509 , +30721 , +-2711 , +-10683 , +-12957 , +-22683 , +17479 , +12483 , +-12635 , +3527 , +8987 , +15889 , +10413 , +-26977 , +-7229 , +-25705 , +-24015 , +-21395 , +-2895 , +-21267 , +24399 , +4635 , +-20439 , +-28065 , +16125 , +-13107 , +-27149 , +11295 , +-12539 , +13883 , +-6249 , +-32317 , +3707 , +-12407 , +7953 , +26227 , +-18765 , +-4957 , +14353 , +-20109 , +17089 , +-12273 , +17319 , +-7361 , +28007 , +20293 , +16007 , +-28889 , +23953 , +-26739 , +-24137 , +24929 , +14673 , +11093 , +-23091 , +6563 , +22353 , +-20479 , +-20311 , +21051 , +-14641 , +-23471 , +-6749 , +27563 , +26129 , +-26835 , +20559 , +29883 , +16227 , +-2301 , +-24147 , +26389 , +25737 , +4509 , +-2077 , +-28585 , +187 , +23673 , +-22409 , +32693 , +-9959 , +-25183 , +-31481 , +20489 , +-3159 , +3335 , +-28037 , +-22929 , +-25399 , +1623 , +-21819 , +15703 , +-31959 , +25423 , +275 , +21545 , +8775 , +5791 , +141 , +-9393 , +13151 , +7989 , +32135 , +-19241 , +23789 , +27683 , +-20165 , +-7803 , +-10087 , +-14101 , +-2043 , +-3473 , +18361 , +27225 , +-13807 , +-26859 , +28231 , +13285 , +-6495 , +-24589 , +3155 , +19835 , +10679 , +19875 , +-29179 , +8675 , +1113 , +17515 , +-13811 , +23947 , +3903 , +-931 , +-31077 , +1515 , +-20461 , +1513 , +-805 , +16723 , +18723 , +-1287 , +4847 , +-6325 , +-5219 , +29831 , +-31649 , +29031 , +1095 , +-9037 , +-20199 , +25755 , +-1361 , +30049 , +19171 , +-13535 , +15089 , +27469 , +-26285 , +-10565 , +-24093 , +19875 , +-29615 , +17315 , +-15405 , +-15849 , +21763 , +-27695 , +1471 , +-12929 , +-17083 , +-17703 , +267 , +-30491 , +-2639 , +21065 , +10677 , +-25813 , +4607 , +-4489 , +12053 , +20243 , +-5101 , +-21539 , +3861 , +-25111 , +-23195 , +-29451 , +21471 , +1671 , +32515 , +-16245 , +29729 , +-30463 , +16391 , +26775 , +-12869 , +-24915 , +-7545 , +-1639 , +13053 , +-31035 , +-16611 , +-13719 , +-32161 , +-16519 , +-4405 , +-4971 , +16567 , +907 , +7045 , +-6853 , +-21009 , +-23447 , +30497 , +24153 , +19525 , +-26439 , +4299 , +26795 , +20983 , +6017 , +16645 , +26113 , +-635 , +6067 , +25627 , +13337 , +17509 , +-29619 , +-25829 , +-20493 , +-11205 , +-19221 , +-13491 , +10673 , +-8557 , +23267 , +-27601 , +-7967 , +-22761 , +21211 , +29667 , +8549 , +19525 , +6879 , +-11723 , +6335 , +-15699 , +-4863 , +10757 , +-1041 , +31395 , +7783 , +2375 , +-27187 , +-22405 , +8937 , +8063 , +-10795 , +-22719 , +3367 , +4779 , +30609 , +28137 , +-7389 , +21195 , +23135 , +-28907 , +-24747 , +-23603 , +-24103 , +-17597 , +13895 , +-27127 , +13985 , +15749 , +30891 , +-23233 , +-16449 , +27325 , +10741 , +13825 , +-21387 , +31575 , +9071 , +10685 , +26271 , +-14471 , +-9257 , +16675 , +17791 , +-8769 , +11119 , +1323 , +22815 , +27769 , +-23395 , +28293 , +-23001 , +30039 , +22781 , +915 , +-5583 , +-15445 , +25343 , +-23321 , +-32605 , +7455 , +3065 , +-16339 , +-32760 , +9447 , +-6463 , +8627 , +-22549 , +27009 , +-18747 , +7251 , +14119 , +-27415 , +31655 , +16373 , +17091 , +14161 , +31055 , +22151 , +-23215 , +9303 , +-27513 , +-8343 , +7863 , +-9531 , +-9203 , +-16011 , +-17259 , +-4415 , +-27083 , +27501 , +8983 , +-4477 , +-21767 , +6899 , +-12723 , +-18023 , +-15723 , +-32249 , +-7167 , +-15725 , +-3941 , +-32005 , +-20971 , +13119 , +17295 , +15081 , +21845 , +27493 , +4349 , +4783 , +-2861 , +-11783 , +22033 , +3689 , +-25153 , +28885 , +1203 , +4959 , +25529 , +21235 , +-27367 , +23689 , +2481 , +7459 , +-19491 , +-10883 , +26427 , +-9917 , +25763 , +-27665 , +7783 , +27641 , +28959 , +10147 , +-17895 , +-21271 , +31929 , +-1813 , +-13087 , +-26261 , +-27483 , +28055 , +10329 , +-26167 , +-27537 , +3189 , +-15121 , +20721 , +14113 , +22339 , +29257 , +-4431 , +11481 , +-27859 , +-6113 , +31853 , +3285 , +14269 , +20355 , +7255 , +31769 , +15451 , +-9011 , +-19673 , +24707 , +-961 , +-28189 , +-2985 , +30811 , +-5907 , +-16101 , +18645 , +11895 , +-15571 , +26767 , +-30661 , +715 , +-28035 , +-521 , +-883 , +24455 , +4881 , +-15623 , +-22419 , +12967 , +-11703 , +14863 , +18385 , +9231 , +-20061 , +-11307 , +835 , +-16341 , +2105 , +27875 , +19853 , +28405 , +6843 , +-19421 , +-7173 , +-28767 , +8671 , +4529 , +26897 , +-28507 , +-26785 , +9769 , +-28227 , +23643 , +367 , +31367 , +23831 , +-3565 , +-2887 , +30839 , +20115 , +-31823 , +-31539 , +17205 , +8897 , +-4163 , +-9441 , +-30495 , +-2441 , +-4093 , +11389 , +-7079 , +22681 , +-11097 , +-15095 , +-6263 , +15939 , +9147 , +25265 , +26195 , +20879 , +-2723 , +-27105 , +6613 , +-27969 , +25675 , +25151 , +13391 , +-15361 , +-5385 , +-11733 , +-653 , +-26727 , +1321 , +-16985 , +3903 , +6315 , +-4595 , +29727 , +19289 , +18021 , +-11563 , +-31213 , +8415 , +22971 , +20935 , +25881 , +15047 , +-21087 , +-25125 , +4689 , +11953 , +-15935 , +7891 , +-27811 , +17475 , +20403 , +-6709 , +26073 , +-4865 , +-5449 , +-12703 , +-22187 , +1181 , +8681 , +-23491 , +14283 , +29149 , +-25345 , +9521 , +25749 , +16361 , +11129 , +14289 , +-26131 , +-14299 , +15971 , +11911 , +-29477 , +1161 , +-15231 , +28465 , +16305 , +-23941 , +-7915 , +22321 , +-29943 , +-4573 , +29959 , +-19443 , +25903 , +11847 , +-3411 , +-22397 , +-24535 , +-30555 , +29687 , +22047 , +22053 , +1727 , +-29905 , +9049 , +-17293 , +-11451 , +-14807 , +-2523 , +-27397 , +18395 , +23555 , +15127 , +-2497 , +-7293 , +-681 , +4331 , +-24125 , +-16031 , +16123 , +28843 , +-24303 , +-22491 , +-26837 , +-21951 , +24881 , +18905 , +25937 , +3467 , +1175 , +-13253 , +-975 , +6141 , +9127 , +12693 , +9895 , +-333 , +-19547 , +-17895 , +7903 , +-4861 , +19501 , +-10829 , +28681 , +-12379 , +-31949 , +-16799 , +-17773 , +1083 , +-26767 , +21267 , +-11549 , +-14991 , +8553 , +19193 , +12945 , +-21611 , +719 , +22881 , +13333 , +6571 , +19599 , +23055 , +4361 , +-4343 , +21313 , +7695 , +6877 , +21871 , +-21989 , +-3815 , +9743 , +923 , +15475 , +28505 , +-24603 , +-13213 , +15785 , +-15401 , +18081 , +-11697 , +10161 , +-6335 , +-961 , +14259 , +32766 , +-2225 , +-21593 , +-23749 , +-25865 , +16017 , +-18329 , +28947 , +5633 , +1233 , +-3861 , +-6029 , +16355 , +-16417 , +31547 , +19903 , +10185 , +-17167 , +-19417 , +10523 , +-30021 , +-9599 , +30983 , +-26241 , +22417 , +27283 , +-11275 , +3161 , +369 , +-10853 , +-32131 , +12703 , +22719 , +5591 , +20189 , +-31647 , +8859 , +-23781 , +-19529 , +16369 , +9947 , +-6351 , +-15795 , +6505 , +-4997 , +-11599 , +-15563 , +-27181 , +-9061 , +-21931 , +-30313 , +21683 , +1015 , +-23337 , +-3871 , +10027 , +10971 , +28995 , +31997 , +19337 , +31647 , +15827 , +-27377 , +-23195 , +28573 , +22337 , +20645 , +19001 , +15019 , +-1875 , +20343 , +14965 , +27919 , +25567 , +-27751 , +-24803 , +1019 , +-9673 , +-10695 , +25561 , +-24445 , +-29197 , +20177 , +-31337 , +7447 , +9231 , +25827 , +-4715 , +14711 , +-8549 , +17451 , +12557 , +-27347 , +1941 , +-13469 , +3383 , +-20341 , +-19393 , +-12947 , +-2063 , +11287 , +30965 , +7443 , +-25389 , +-371 , +9613 , +23363 , +-24899 , +-9901 , +8739 , +-71 , +30211 , +29553 , +-31621 , +-27581 , +-15631 , +-3317 , +30167 , +-25991 , +-4881 , +11603 , +329 , +5101 , +26135 , +-2805 , +-7531 , +9449 , +27461 , +12151 , +28029 , +-13915 , +-26437 , +-6193 , +9639 , +5633 , +11061 , +6469 , +7911 , +-2119 , +17787 , +26483 , +-16863 , +-3295 , +4737 , +32085 , +-3427 , +-11681 , +7159 , +19137 , +32733 , +-16617 , +-21143 , +-10143 , +28669 , +-16717 , +-25643 , +-5591 , +18047 , +2321 , +18877 , +10319 , +2991 , +12733 , +16327 , +1729 , +-14223 , +-25685 , +12753 , +8999 , +-30049 , +12139 , +-14201 , +20811 , +-30235 , +-13339 , +1921 , +3615 , +-31479 , +27025 , +-22573 , +-28371 , +-4139 , +26667 , +16177 , +13459 , +2407 , +-273 , +-29833 , +27511 , +29447 , +18253 , +-17711 , +-251 , +24449 , +-9689 , +2115 , +-13855 , +-3327 , +30597 , +-31535 , +-21983 , +-5273 , +-20277 , +25871 , +-7733 , +10523 , +3445 , +-21709 , +-25155 , +12399 , +-23987 , +-31301 , +-9413 , +15213 , +-27867 , +14969 , +25555 , +-3017 , +30477 , +-2511 , +6115 , +28633 , +5899 , +22703 , +16265 , +-32345 , +32593 , +5473 , +6683 , +-245 , +-9475 , +-32661 , +25639 , +3053 , +4679 , +24643 , +3041 , +1911 , +-23747 , +-9271 , +-13277 , +12671 , +-21247 , +-8997 , +-6691 , +-24491 , +-23177 , +-16529 , +-20457 , +-24803 , +-20093 , +-23249 , +13921 , +3241 , +6075 , +17801 , +-25143 , +-11571 , +-14931 , +-28081 , +-30623 , +3645 , +24451 , +2251 , +12069 , +-289 , +-11697 , +1877 , +27263 , +22693 , +-8015 , +-141 , +24893 , +3305 , +-24033 , +-9117 , +5635 , +9277 , +27791 , +30277 , +-29875 , +-16183 , +8379 , +27041 , +-18979 , +-7899 , +20687 , +11149 , +-2631 , +-1113 , +14761 , +-19905 , +19875 , +2631 , +1673 , +-30175 , +4365 , +7921 , +22357 , +-20619 , +16533 , +6233 , +-32447 , +1119 , +19709 , +-28835 , +-32235 , +-17531 , +30877 , +-27435 , +7647 , +-28887 , +-28829 , +22507 , +7977 , +7353 , +11591 , +19707 , +12725 , +15597 , +19269 , +-4893 , +20405 , +-20385 , +19151 , +-23335 , +14717 , +-1887 , +14287 , +3793 , +-4155 , +-18991 , +30995 , +2625 , +-22439 , +24767 , +-22703 , +-12915 , +13651 , +-18063 , +-15719 , +-30771 , +22227 , +-15795 , +32331 , +-21707 , +-4293 , +-24667 , +-9325 , +30687 , +-28195 , +13273 , +-13729 , +-8399 , +25665 , +-12319 , +2265 , +22437 , +-13871 , +-12171 , +-1703 , +-18131 , +-11755 , +32667 , +-22809 , +-17907 , +-7827 , +4801 , +-20435 , +9253 , +-29621 , +7509 , +20713 , +23253 , +7391 , +20447 , +16885 , +18771 , +-17567 , +-9319 , +-22609 , +20863 , +-20295 , +21119 , +-14601 , +21311 , +-17473 , +23541 , +-18259 , +25687 , +-3855 , +5585 , +-11363 , +20665 , +7343 , +31235 , +1285 , +31597 , +8173 , +-24425 , +-12419 , +14295 , +16235 , +13923 , +10367 , +13213 , +-8845 , +17 , +-5039 , +2295 , +-27123 , +-15937 , +8329 , +-28277 , +13751 , +25359 , +-17155 , +4545 , +-32099 , +-22583 , +13117 , +-11103 , +20561 , +21733 , +27789 , +20515 , +-10745 , +6711 , +30297 , +27153 , +-16571 , +6255 , +-27341 , +-2731 , +-4317 , +23497 , +-2489 , +-41 , +28155 , +8979 , +-18609 , +2259 , +31149 , +19275 , +32019 , +-18509 , +12359 , +-18499 , +20575 , +11109 , +-12981 , +3725 , +-1671 , +31283 , +-3743 , +-24095 , +-28139 , +31259 , +-4981 , +-8857 , +-31275 , +27049 , +-32023 , +4219 , +-18113 , +-28341 , +9187 , +-4935 , +3889 , +29999 , +3051 , +-28397 , +1245 , +-20589 , +18609 , +31085 , +-25539 , +2983 , +6105 , +10931 , +19729 , +-1829 , +-26565 , +-3213 , +13391 , +-4417 , +17805 , +-26381 , +14885 , +-9903 , +13997 , +18629 , +26217 , +9701 , +-27065 , +-22805 , +7057 , +-30611 , +19997 , +20579 , +28721 , +4439 , +23731 , +-21949 , +24301 , +-21525 , +-12917 , +21845 , +1271 , +-25319 , +-13345 , +7719 , +-22785 , +6869 , +-14373 , +-15957 , +-19277 , +-27663 , +9801 , +24139 , +-32079 , +-16265 , +29401 , +-5759 , +-3323 , +4725 , +-29487 , +-32275 , +-15335 , +-24727 , +-14785 , +-2571 , +-16845 , +6657 , +28095 , +22225 , +30575 , +-2935 , +-17751 , +-4049 , +-6609 , +17333 , +-27703 , +31813 , +31259 , +31231 , +10395 , +-5021 , +-3183 , +-27779 , +-11005 , +-25061 , +-20059 , +-13767 , +18309 , +21705 , +-20841 , +27403 , +25077 , +-12365 , +-7483 , +-7443 , +-13125 , +21663 , +17961 , +-25383 , +-19325 , +1775 , +10323 , +-14307 , +-21893 , +25393 , +5849 , +-24787 , +7939 , +-18627 , +2645 , +18187 , +28395 , +-4403 , +4571 , +-8433 , +-1235 , +-29549 , +13557 , +-9911 , +17179 , +10191 , +-15343 , +13139 , +31011 , +18027 , +-12409 , +-22611 , +-30211 , +-5229 , +-765 , +28563 , +3693 , +-19765 , +29577 , +-21163 , +8051 , +-12409 , +5601 , +5937 , +-31487 , +-14015 , +-15461 , +-1367 , +14141 , +19481 , +-10111 , +12379 , +-21963 , +-6687 , +-23923 , +6231 , +-9201 , +1985 , +1635 , +14079 , +-25141 , +9287 , +2639 , +-30121 , +3705 , +16897 , +32689 , +12253 , +-16145 , +-9577 , +-32001 , +29413 , +-31747 , +24163 , +2617 , +-9357 , +17713 , +13441 , +14817 , +21899 , +1537 , +-28811 , +-18317 , +2319 , +23435 , +-4553 , +-18337 , +-1515 , +28879 , +-24111 , +-3971 , +2497 , +863 , +12149 , +15117 , +28571 , +21151 , +-6377 , +4899 , +17253 , +31095 , +-31101 , +-22361 , +12155 , +10895 , +16627 , +-15663 , +-7265 , +18179 , +811 , +10515 , +24669 , +18339 , +19473 , +-13665 , +-19751 , +-3937 , +29123 , +23641 , +14639 , +18379 , +-21715 , +-23217 , +1861 , +17741 , +-18905 , +12721 , +-31703 , +14043 , +29191 , +-23481 , +-10273 , +19829 , +18109 , +24177 , +16839 , +19859 , +-20377 , +-18793 , +-4247 , +-9751 , +-14479 , +29987 , +27603 , +20631 , +7455 , +-12295 , +16237 , +-19741 , +-15177 , +-25489 , +-10151 , +-28811 , +-7929 , +-4151 , +21311 , +26373 , +-29043 , +-6615 , +15537 , +-31839 , +-32255 , +-14321 , +-7431 , +-17831 , +13175 , +17997 , +20601 , +3965 , +-4621 , +1151 , +-31105 , +-19119 , +-25727 , +10753 , +4249 , +23883 , +-23089 , +12653 , +-30599 , +21445 , +-15551 , +-20851 , +8767 , +24123 , +2191 , +17113 , +-9891 , +-11271 , +5845 , +30823 , +21987 , +-5791 , +-16845 , +-17557 , +8803 , +-23147 , +-4897 , +10795 , +19009 , +31419 , +17091 , +29557 , +-1905 , +-1877 , +8589 , +31643 , +12131 , +-28113 , +-28337 , +-19 , +12205 , +-4937 , +-11885 , +-3931 , +-22123 , +-19827 , +-4365 , +-18063 , +19789 , +24471 , +13615 , +12379 , +-11153 , +135 , +-10803 , +25419 , +7117 , +23703 , +-25817 , +-1029 , +26063 , +-32323 , +7 , +29291 , +23885 , +11113 , +-31805 , +-14875 , +-3873 , +-1099 , +-27951 , +-2969 , +-24903 , +-219 , +-9251 , +-5977 , +18697 , +29405 , +26981 , +5761 , +10947 , +17743 , +22479 , +32245 , +1285 , +18823 , +-32768 , +19615 , +7399 , +-27439 , +-4483 , +-10837 , +8661 , +-267 , +32497 , +6225 , +-27545 , +15609 , +29781 , +-29493 , +-14917 , +-29109 , +25987 , +28623 , +1869 , +29829 , +22093 , +17539 , +9033 , +28055 , +21779 , +-15111 , +-19091 , +10387 , +29919 , +-1755 , +31831 , +11471 , +31743 , +-21419 , +15201 , +27567 , +7955 , +-1747 , +17663 , +-19247 , +8369 , +9239 , +17805 , +-31541 , +11635 , +31807 , +26283 , +9827 , +-13161 , +31505 , +25369 , +-25023 , +15637 , +-9687 , +-23799 , +22833 , +-26833 , +-10297 , +-1797 , +5329 , +2709 , +25049 , +5905 , +-1327 , +-28427 , +24417 , +21739 , +26277 , +-4841 , +-12175 , +-8705 , +19907 , +20085 , +-853 , +-8081 , +-15791 , +29003 , +26673 , +-11171 , +-30615 , +-27843 , +-14559 , +29645 , +13773 , +5219 , +-22649 , +31479 , +-11243 , +7399 , +2527 , +-14051 , +32121 , +7965 , +-24571 , +-1563 , +-5125 , +-29163 , +-5457 , +3893 , +29475 , +-24389 , +-4761 , +17287 , +23607 , +31085 , +-20223 , +-25411 , +7417 , +-30193 , +19601 , +22401 , +24785 , +-29533 , +-21269 , +-15589 , +23703 , +-6039 , +-11633 , +-23101 , +25783 , +-9363 , +-16851 , +-15997 , +15869 , +16551 , +-15467 , +-28283 , +8381 , +19085 , +31537 , +-10255 , +-6507 , +2607 , +2557 , +5187 , +23201 , +6861 , +-2043 , +31271 , +9267 , +18925 , +19791 , +-32569 , +17419 , +-27653 , +11615 , +-23889 , +-25585 , +19797 , +-22223 , +26141 , +31109 , +-12303 , +-93 , +17885 , +-26165 , +-31387 , +1147 , +-28003 , +-24183 , +-23153 , +-6697 , +-6965 , +32367 , +-32351 , +2087 , +14055 , +-21647 , +-19521 , +12457 , +16477 , +-12431 , +2839 , +-18855 , +10463 , +-20861 , +-29581 , +-3727 , +11323 , +-6745 , +24409 , +-24227 , +18101 , +26865 , +-95 , +-32463 , +-32293 , +15443 , +-29817 , +-15705 , +-1567 , +24267 , +-31157 , +-22641 , +13175 , +24609 , +-6333 , +-3631 , +-9697 , +-26349 , +-12935 , +25051 , +32527 , +32287 , +-20549 , +-1119 , +28793 , +1197 , +24891 , +18959 , +16753 , +-27957 , +-15707 , +22785 , +6715 , +29031 , +30637 , +-25145 , +26925 , +14597 , +31035 , +-31225 , +3071 , +12535 , +-9233 , +-6837 , +-30303 , +6423 , +-23741 , +-1811 , +29855 , +22011 , +-1753 , +14991 , +-29203 , +-2125 , +-24053 , +-18153 , +-16315 , +-27911 , +1415 , +12327 , +-29699 , +25841 , +-23705 , +-27119 , +-1183 , +-18083 , +19783 , +22611 , +-18555 , +2899 , +-845 , +-369 , +21925 , +-10115 , +-25173 , +27645 , +29949 , +-24891 , +-23085 , +30571 , +-15083 , +-873 , +-12295 , +4529 , +-29527 , +27543 , +-11211 , +-19797 , +-14091 , +-29229 , +29827 , +17579 , +32147 , +-31357 , +-18993 , +18041 , +19667 , +20285 , +-25185 , +23495 , +-3953 , +-26965 , +19485 , +1067 , +-21625 , +-565 , +-13647 , +-20335 , +19255 , +20121 , +26401 , +-4293 , +-11727 , +-28839 , +-3295 , +-6605 , +25327 , +28991 , +-16277 , +-11189 , +-31947 , +4527 , +-20129 , +-12149 , +20447 , +-31243 , +13839 , +-32725 , +-18109 , +10619 , +-29211 , +-1259 , +24573 , +9855 , +9643 , +-26931 , +10835 , +12625 , +27185 , +-12297 , +10755 , +-4603 , +-6305 , +2635 , +-5471 , +-1873 , +3023 , +24325 , +-16271 , +2073 , +26845 , +12779 , +12215 , +8955 , +-14515 , +-15177 , +1173 , +24501 , +-6057 , +-32489 , +13155 , +9861 , +19269 , +12583 , +6529 , +28221 , +-12405 , +-8603 , +14009 , +-5249 , +-29863 , +-28893 , +-2289 , +-21897 , +-20803 , +-25971 , +-23271 , +2825 , +-13519 , +-13545 , +7393 , +-26731 , +22457 , +1911 , +22317 , +-20951 , +-13955 , +-17891 , +25955 , +29749 , +6357 , +-20691 , +-2593 , +3275 , +2805 , +-24333 , +-1849 , +-30379 , +6127 , +10977 , +32105 , +-29497 , +17755 , +23297 , +24585 , +6495 , +-12951 , +-26127 , +-8121 , +-32551 , +-5511 , +8537 , +-18453 , +-4315 , +-24783 , +-18207 , +-13757 , +-30809 , +-11491 , +-3665 , +1017 , +-29469 , +-25669 , +-26533 , +-31895 , +-30017 , +2593 , +-27289 , +-24189 , +-1225 , +21765 , +-3019 , +-3309 , +23959 , +-18587 , +18565 , +-9563 , +14381 , +-9323 , +10855 , +-15653 , +-885 , +10965 , +185 , +-26301 , +17975 , +-9869 , +-11751 , +-24147 , +27621 , +1885 , +21599 , +14855 , +-9425 , +-12999 , +-3435 , +-22861 , +14031 , +-29191 , +369 , +32611 , +-20651 , +25857 , +-9651 , +-11161 , +-29089 , +2217 , +5275 , +-23407 , +27731 , +-1681 , +-27169 , +-17529 , +2197 , +21879 , +-20437 , +-28521 , +15421 , +10417 , +1807 , +15895 , +-173 , +-28303 , +29463 , +10557 , +-1911 , +-28291 , +-25657 , +29291 , +-28821 , +-7247 , +-32766 , +-14827 , +-1763 , +-20979 , +-23269 , +-23019 , +14225 , +26711 , +9269 , +-15491 , +-31937 , +-12503 , +20041 , +-32521 , +5985 , +15245 , +7835 , +13717 , +-10077 , +14107 , +13233 , +18485 , +-12701 , +-23421 , +-31027 , +-17589 , +-6557 , +21687 , +-26141 , +16703 , +-1275 , +24691 , +21517 , +29005 , +-27649 , +7773 , +17551 , +13517 , +22937 , +3485 , +-31679 , +1305 , +-19871 , +-29455 , +-4717 , +4573 , +-31901 , +-18871 , +-7429 , +-6159 , +-29987 , +14047 , +23537 , +-20299 , +19843 , +31689 , +28783 , +-24095 , +3627 , +2841 , +6871 , +-18973 , +-14327 , +24949 , +26751 , +17593 , +-23699 , +11297 , +-12135 , +-27327 , +-8979 , +14253 , +-5709 , +-235 , +-26837 , +-5383 , +13743 , +-19223 , +-28919 , +-22821 , +15417 , +-12455 , +10841 , +-7635 , +-21567 , +-20409 , +-9949 , +23151 , +-18197 , +22191 , +16721 , +12499 , +29847 , +-17659 , +11501 , +19425 , +20553 , +-13303 , +-19755 , +-10873 , +-30425 , +9245 , +-28169 , +11701 , +-20105 , +3873 , +14091 , +10607 , +4237 , +-1843 , +25795 , +-2447 , +4425 , +-9347 , +-2423 , +31543 , +30475 , +-14439 , +-19019 , +-29787 , +-28365 , +7013 , +-18105 , +-13805 , +9487 , +-31915 , +18459 , +-29459 , +18009 , +23277 , +-19033 , +-24383 , +-10709 , +-31213 , +12587 , +16103 , +-8065 , +23279 , +-141 , +4229 , +-28643 , +-19403 , +5891 , +-27077 , +-3817 , +-15347 , +-26917 , +-13267 , +14789 , +-16545 , +4007 , +25245 , +-11721 , +-1613 , +6011 , +25355 , +-11727 , +-30333 , +8199 , +-26171 , +11681 , +3349 , +1875 , +-25601 , +18327 , +-22571 , +23287 , +-15759 , +9147 , +-12245 , +-14897 , +-3989 , +-4531 , +1491 , +-24521 , +32621 , +4757 , +2233 , +6847 , +10045 , +-26659 , +-22457 , +-1173 , +14983 , +-793 , +-15541 , +25949 , +4075 , +18925 , +-28609 , +-23777 , +-4199 , +-28399 , +-14799 , +27467 , +23919 , +-27305 , +-16881 , +-26675 , +6021 , +-12261 , +9351 , +-14445 , +-24241 , +-29423 , +21593 , +-7473 , +-19663 , +21683 , +-3791 , +-1625 , +26265 , +23873 , +-9471 , +30061 , +30353 , +14899 , +4569 , +5215 , +27873 , +-32205 , +-24007 , +-22571 , +5019 , +-23655 , +12785 , +3325 , +833 , +-24741 , +17781 , +22555 , +-23215 , +-7539 , +-10827 , +-21971 , +-31901 , +-2475 , +20085 , +-22211 , +15037 , +15969 , +-29403 , +4865 , +-5009 , +32227 , +-1985 , +25121 , +-32275 , +23305 , +18191 , +-529 , +-25059 , +-26381 , +4641 , +-4971 , +-27909 , +16425 , +-15355 , +32731 , +13225 , +28055 , +693 , +-2991 , +-9465 , +5 , +10593 , +31503 , +32469 , +-9205 , +-5419 , +-23057 , +10045 , +-371 , +-19385 , +-20931 , +-23823 , +5555 , +-5971 , +-29195 , +-12343 , +-10147 , +-29537 , +25469 , +20433 , +-11237 , +31399 , +6101 , +743 , +-5713 , +-18403 , +-16557 , +7377 , +12279 , +637 , +-21281 , +12247 , +30063 , +11583 , +-20569 , +983 , +6179 , +26669 , +29525 , +-28191 , +27691 , +1603 , +31435 , +-945 , +26785 , +-8963 , +-21157 , +-9385 , +-11493 , +-11211 , +-4485 , +-18899 , +-24161 , +-16771 , +-18433 , +145 , +-13539 , +4587 , +11989 , +29933 , +15981 , +-26239 , +-21961 , +8943 , +14269 , +-18693 , +9573 , +2711 , +-21363 , +19755 , +-27679 , +-25637 , +1575 , +-5429 , +-28643 , +-3401 , +-7523 , +19935 , +23745 , +10181 , +5173 , +-10363 , +-20395 , +-29345 , +-26773 , +2127 , +17287 , +12583 , +-18587 , +-25317 , +-26159 , +31277 , +6377 , +25711 , +-825 , +15233 , +-7201 , +25673 , +8635 , +4935 , +-15561 , +26751 , +29183 , +28251 , +-3213 , +-28271 , +28065 , +2137 , +6037 , +-1019 , +8343 , +16453 , +3225 , +6205 , +8833 , +6553 , +29553 , +-13617 , +6363 , +16859 , +10609 , +-4767 , +13241 , +-3391 , +26459 , +18423 , +-25345 , +2235 , +-16701 , +-25897 , +21013 , +9751 , +-20973 , +-12071 , +24613 , +14991 , +767 , +-3519 , +-1335 , +18279 , +-15493 , +-4069 , +25935 , +-18425 , +-10949 , +-8179 , +9833 , +9993 , +7071 , +-16209 , +32363 , +-6181 , +17463 , +24169 , +-26629 , +11479 , +-1613 , +28873 , +27473 , +8655 , +-19107 , +-30637 , +-13335 , +-11467 , +-6383 , +-6935 , +-26435 , +14761 , +-21575 , +-13169 , +-30975 , +16913 , +-13761 , +31445 , +32597 , +10809 , +12039 , +16547 , +1409 , +2529 , +-25111 , +-4965 , +-23895 , +-8103 , +-11611 , +5095 , +-13815 , +-353 , +-14369 , +21397 , +12331 , +9707 , +23705 , +8817 , +3233 , +13011 , +4129 , +19295 , +15931 , +-21289 , +3221 , +-22489 , +-13891 , +4743 , +14289 , +13535 , +-21729 , +14861 , +-32017 , +5043 , +28983 , +-25009 , +12347 , +-26297 , +-25597 , +-3963 , +18345 , +-1657 , +13647 , +-14773 , +-3629 , +-21237 , +-25603 , +-17343 , +-3735 , +9951 , +-1615 , +-6881 , +-3277 , +-3349 , +23309 , +-8885 , +-4993 , +-11075 , +-7571 , +23285 , +16417 , +-275 , +3351 , +-27983 , +-7709 , +-1301 , +-32005 , +18565 , +12423 , +22879 , +26857 , +-6771 , +-16843 , +-15619 , +-21183 , +27147 , +-16517 , +-32293 , +18233 , +-27647 , +22717 , +6989 , +-8057 , +4683 , +-32203 , +4669 , +-7773 , +7219 , +-17815 , +27135 , +22653 , +17809 , +16157 , +429 , +-20047 , +-6313 , +1235 , +24571 , +-17345 , +-2893 , +9405 , +1943 , +-4147 , +-27485 , +-1735 , +-5129 , +27983 , +22541 , +-24375 , +7861 , +-19891 , +25689 , +8069 , +19819 , +30355 , +27269 , +-10469 , +10245 , +-21393 , +-15679 , +-29373 , +18333 , +7009 , +-31609 , +-18247 , +-21043 , +-29349 , +-3283 , +19631 , +29843 , +1649 , +5895 , +-17715 , +-14691 , +-229 , +-9483 , +25509 , +-18395 , +6373 , +-31101 , +11691 , +6219 , +17833 , +-4997 , +31407 , +-11543 , +-9913 , +9727 , +13265 , +-1293 , +32223 , +12837 , +9213 , +5445 , +-32119 , +20999 , +22753 , +-17407 , +31877 , +31077 , +-15771 , +12899 , +-19709 , +-21581 , +-14171 , +289 , +19785 , +-25163 , +4201 , +13111 , +-17545 , +29595 , +9749 , +19273 , +20927 , +-3179 , +18221 , +-30343 , +-29167 , +1255 , +585 , +-26183 , +101 , +-11379 , +-6779 , +17067 , +19809 , +28739 , +-3193 , +11511 , +17313 , +17711 , +5863 , +23325 , +31585 , +14053 , +19513 , +27091 , +30913 , +-13807 , +-17805 , +12509 , +-14221 , +9607 , +29171 , +-9119 , +3835 , +18649 , +2545 , +5831 , +-32159 , +20335 , +-11149 , +23299 , +-14739 , +6185 , +-7985 , +1917 , +-23715 , +10603 , +-31591 , +18783 , +-28899 , +10681 , +-23771 , +30829 , +-32513 , +-15153 , +27509 , +-1181 , +2039 , +21819 , +-15179 , +19655 , +6987 , +10871 , +8503 , +14405 , +-25133 , +-15499 , +-4123 , +-6011 , +2985 , +-10809 , +25661 , +-8827 , +19051 , +31021 , +-13113 , +25451 , +5099 , +20397 , +12299 , +-24087 , +-3223 , +563 , +26639 , +-9211 , +19789 , +-5729 , +29771 , +-1919 , +26969 , +15459 , +14879 , +-5467 , +-2195 , +-26471 , +27601 , +5025 , +1713 , +17051 , +-12801 , +13411 , +-6313 , +-4067 , +-27749 , +2027 , +-4401 , +30659 , +2143 , +7719 , +-27011 , +15675 , +16841 , +3909 , +-4873 , +-20017 , +3733 , +-24681 , +-11849 , +-15993 , +-9045 , +-5155 , +-3239 , +-31561 , +-12895 , +13863 , +2121 , +3613 , +-20047 , +27433 , +14857 , +-21127 , +8493 , +-2029 , +15067 , +32419 , +27769 , +2281 , +-507 , +-25311 , +-25979 , +-14499 , +-30079 , +-11197 , +11717 , +-19933 , +-8139 , +9149 , +-6235 , +-23345 , +26545 , +-3915 , +17027 , +-22489 , +-7069 , +15207 , +-9685 , +8957 , +24913 , +-20171 , +31431 , +-31861 , +4169 , +-3263 , +3677 , +-1727 , +-27737 , +-5753 , +8393 , +22317 , +-21887 , +31347 , +12845 , +-18753 , +-18585 , +32503 , +-28689 , +-3277 , +6547 , +19243 , +-5071 , +-27295 , +-12119 , +-23715 , +27591 , +18447 , +25325 , +30119 , +25259 , +27863 , +32241 , +12305 , +30465 , +-5771 , +18913 , +2851 , +25217 , +-14943 , +-6359 , +8443 , +2683 , +-20123 , +3761 , +-22295 , +9795 , +3069 , +19615 , +12167 , +11319 , +-31961 , +-12925 , +9035 , +-17109 , +-7431 , +13841 , +-29271 , +18019 , +11845 , +32097 , +20641 , +4629 , +-26777 , +16799 , +-16161 , +32337 , +29083 , +-28861 , +-2995 , +-28023 , +-19745 , +-27951 , +-25299 , +-21635 , +7749 , +11527 , +-13899 , +30139 , +-20791 , +-7781 , +24609 , +-4467 , +23211 , +6259 , +-20659 , +-23683 , +-14517 , +10583 , +-5171 , +-6071 , +1403 , +10803 , +-3701 , +15189 , +-4519 , +-2107 , +8657 , +-28505 , +14507 , +28893 , +-18959 , +-17563 , +-8529 , +23569 , +24143 , +-21053 , +-4997 , +-4111 , +-31225 , +-14463 , +20175 , +30153 , +4855 , +-5409 , +-17807 , +-301 , +-1441 , +-28643 , +17411 , +-23573 , +-32263 , +-28823 , +-16291 , +18385 , +-31343 , +-9891 , +-31391 , +21463 , +-26347 , +-10765 , +-23723 , +26399 , +24381 , +-24059 , +11967 , +28757 , +-4975 , +-7367 , +-19785 , +10719 , +-28915 , +27269 , +25539 , +28827 , +-11721 , +23839 , +11051 , +27923 , +6065 , +7161 , +8917 , +1855 , +-25509 , +-24141 , +-26209 , +-25429 , +16867 , +-28901 , +14379 , +28995 , +-2851 , +-25051 , +24137 , +-11653 , +1891 , +-19625 , +20671 , +25873 , +22561 , +17873 , +20393 , +-27325 , +-25095 , +21947 , +11601 , +-24195 , +-20463 , +-22211 , +32133 , +14245 , +8821 , +-30721 , +-2705 , +7359 , +3877 , +-21227 , +5101 , +-10445 , +25523 , +-22653 , +-21909 , +-11399 , +-29863 , +24875 , +24119 , +-1185 , +-12911 , +1101 , +-17827 , +14261 , +14641 , +-2181 , +-5631 , +-11127 , +29689 , +10255 , +-19667 , +16355 , +18105 , +23337 , +-13773 , +6903 , +15835 , +-17119 , +5505 , +5599 , +13959 , +26497 , +-1541 , +-29225 , +12337 , +5505 , +18381 , +26091 , +15031 , +-16649 , +-8241 , +4667 , +-9991 , +20951 , +-22195 , +19887 , +-20497 , +16935 , +-3985 , +29223 , +-9665 , +10357 , +-15101 , +-5315 , +-18341 , +9939 , +29153 , +-17541 , +-27375 , +19535 , +-23365 , +-29681 , +-2385 , +-20759 , +24181 , +16135 , +-2933 , +29703 , +17413 , +31751 , +26921 , +32633 , +26561 , +12161 , +22731 , +229 , +9021 , +29807 , +25741 , +-26685 , +6563 , +-8057 , +-24071 , +17881 , +-1401 , +-21769 , +-20697 , +-6103 , +7491 , +-23139 , +23369 , +28281 , +-29491 , +-32579 , +-17459 , +-30409 , +-25585 , +20789 , +1521 , +1541 , +-25919 , +-11971 , +1245 , +-27999 , +-15683 , +21407 , +-31691 , +7783 , +-2595 , +-7835 , +-30919 , +-28093 , +25677 , +31261 , +-23463 , +5933 , +-19609 , +-4475 , +23887 , +-23777 , +-17145 , +19923 , +-13391 , +1165 , +32615 , +23897 , +31251 , +9313 , +21879 , +4813 , +-15977 , +-18837 , +4017 , +-30465 , +-31739 , +4191 , +1397 , +26373 , +-26009 , +24395 , +-18721 , +12803 , +-12251 , +-3181 , +5919 , +-32425 , +-15729 , +-9377 , +5971 , +-29353 , +32003 , +-31839 , +-30243 , +4231 , +10619 , +-26753 , +-2503 , +-3245 , +-21071 , +-10667 , +30045 , +-17851 , +-29527 , +6185 , +11909 , +11963 , +-6961 , +14499 , +-29547 , +14885 , +-7531 , +8325 , +-15377 , +27575 , +32639 , +-23131 , +-16187 , +8357 , +-6711 , +31075 , +5627 , +-14631 , +20593 , +-8799 , +1141 , +12845 , +-16425 , +22587 , +13043 , +31773 , +23253 , +7425 , +11887 , +26119 , +-11177 , +26157 , +19181 , +-18975 , +-21139 , +29531 , +-817 , +-31379 , +-21527 , +26369 , +17087 , +-1039 , +23929 , +-17815 , +14323 , +27257 , +-199 , +-32731 , +26383 , +17023 , +-24119 , +11535 , +-2691 , +-8397 , +-7693 , +8115 , +16199 , +-26331 , +3505 , +-25001 , +-1183 , +7303 , +3539 , +-31895 , +-32615 , +31203 , +-5107 , +20601 , +17109 , +-5811 , +19865 , +-8271 , +8447 , +-18397 , +-17853 , +27597 , +-25771 , +22849 , +2061 , +9879 , +-30145 , +4023 , +-15553 , +5593 , +28073 , +11273 , +-5375 , +28375 , +-4895 , +21467 , +-9611 , +10311 , +-24863 , +-13261 , +-18869 , +-1331 , +-19655 , +15919 , +14049 , +-30739 , +-27821 , +-4555 , +9937 , +-8317 , +5217 , +-8773 , +28171 , +7109 , +20895 , +-12435 , +375 , +19369 , +-14533 , +-23053 , +-28931 , +25585 , +-14935 , +5409 , +15919 , +28311 , +-10893 , +7601 , +23885 , +-20287 , +9121 , +19325 , +21233 , +-183 , +-29059 , +11829 , +-21479 , +-1625 , +27389 , +1175 , +-24895 , +25451 , +-25967 , +4649 , +-9981 , +21565 , +2429 , +-26769 , +-2907 , +30283 , +11699 , +-7007 , +26425 , +2889 , +-25047 , +32489 , +18093 , +-4127 , +23215 , +-12267 , +-17809 , +21941 , +-9139 , +22737 , +28917 , +27597 , +-31211 , +-8859 , +-3613 , +-21099 , +-29055 , +-31519 , +9371 , +4181 , +-1727 , +25311 , +-7335 , +-14553 , +-18013 , +25525 , +-3383 , +-10899 , +-27305 , +4913 , +13855 , +10189 , +-8229 , +13777 , +30639 , +27559 , +-22975 , +-21385 , +-25081 , +23825 , +25495 , +-25947 , +-23163 , +-15545 , +-10831 , +18225 , +13937 , +-11349 , +2701 , +-20603 , +12175 , +13109 , +15907 , +17739 , +-705 , +20083 , +-24385 , +-12625 , +5393 , +16381 , +-25127 , +-7917 , +28127 , +-659 , +-17553 , +-4535 , +19553 , +729 , +-22051 , +23623 , +15431 , +13511 , +-25553 , +-24733 , +-29229 , +12459 , +-32509 , +-12537 , +12273 , +-15403 , +13269 , +-21265 , +16075 , +-16137 , +16101 , +-26915 , +7907 , +-5105 , +17791 , +23245 , +31919 , +13549 , +-20763 , +26041 , +2219 , +-2019 , +-22123 , +17603 , +18419 , +32359 , +7983 , +-3849 , +20829 , +29385 , +-20283 , +-8833 , +-12531 , +-31003 , +21431 , +16473 , +7317 , +-507 , +-22777 , +-29293 , +-9857 , +22155 , +-26315 , +-25339 , +-14217 , +-13841 , +30359 , +29313 , +21203 , +-9427 , +-2001 , +8337 , +-30541 , +-21559 , +27391 , +-16977 , +-2665 , +20289 , +-30741 , +-7179 , +8571 , +-11007 , +5131 , +-19609 , +5733 , +16615 , +-7809 , +-12653 , +-15733 , +10795 , +18643 , +18913 , +-28961 , +14565 , +-19769 , +1333 , +555 , +14847 , +19125 , +26683 , +-14165 , +429 , +29027 , +-1779 , +-2011 , +-11163 , +2137 , +-14983 , +-6019 , +-29099 , +11711 , +5811 , +30927 , +16741 , +-32595 , +26507 , +6411 , +-32353 , +-31219 , +5417 , +28677 , +6197 , +17897 , +-15803 , +-2537 , +21745 , +-18103 , +-6949 , +23597 , +-18895 , +8329 , +30311 , +5993 , +8029 , +-9675 , +16025 , +-5837 , +21981 , +-11689 , +-20331 , +-17453 , +-873 , +8795 , +-11617 , +-21621 , +-14877 , +-1697 , +10333 , +-27603 , +5121 , +25871 , +6027 , +-1229 , +-16361 , +4857 , +-16589 , +-20905 , +16291 , +-23957 , +-18071 , +-4433 , +-8075 , +-24893 , +-16519 , +-32709 , +21291 , +-17839 , +-22357 , +30219 , +15395 , +24997 , +-17551 , +4809 , +755 , +16239 , +-14039 , +-27171 , +-26519 , +-14131 , +3147 , +19707 , +27385 , +27187 , +16679 , +-15805 , +16829 , +27827 , +-3813 , +24273 , +13799 , +11229 , +26701 , +23007 , +-32069 , +-19437 , +19935 , +19539 , +25609 , +24939 , +22189 , +16607 , +-17627 , +-26889 , +2685 , +-26477 , +-19877 , +9899 , +5057 , +-25609 , +5865 , +-32341 , +4549 , +4263 , +-24199 , +18733 , +25965 , +-21659 , +-6887 , +22471 , +-3991 , +-18765 , +7343 , +-9393 , +16119 , +-14865 , +-28943 , +-26837 , +5129 , +-13089 , +-16153 , +-6351 , +-12269 , +29661 , +11991 , +-25861 , +-21973 , +91 , +-15425 , +16831 , +13273 , +-22007 , +-14509 , +-345 , +7997 , +-19359 , +31345 , +32171 , +-16435 , +9421 , +6683 , +8421 , +15761 , +27953 , +-32535 , +-399 , +-3369 , +-7411 , +7947 , +-14665 , +-5015 , +23313 , +-32587 , +11089 , +1099 , +-16073 , +6949 , +-8609 , +-28951 , +1367 , +-26611 , +-15781 , +4831 , +13377 , +22423 , +25201 , +799 , +5463 , +24785 , +19293 , +-3145 , +9381 , +30899 , +23743 , +16641 , +16757 , +-26743 , +-21773 , +-24225 , +-5781 , +29941 , +2409 , +-26259 , +22553 , +25187 , +-10881 , +19141 , +25373 , +11265 , +6615 , +-27351 , +27315 , +14393 , +-24017 , +579 , +14033 , +-25181 , +6071 , +29665 , +6331 , +26505 , +-16911 , +3229 , +10531 , +-16177 , +-6143 , +19243 , +-1357 , +15739 , +-16763 , +-12291 , +-26313 , +-1375 , +28145 , +-14969 , +11557 , +-13089 , +21865 , +25329 , +7101 , +13659 , +19985 , +-32425 , +-1121 , +21807 , +-23829 , +-17545 , +13799 , +-26773 , +-11987 , +4077 , +-21573 , +18823 , +-22245 , +32239 , +14449 , +-9629 , +-6307 , +-27523 , +26651 , +-2127 , +-8489 , +27681 , +15011 , +16895 , +19201 , +803 , +19303 , +-12515 , +-7489 , +29761 , +13641 , +13091 , +-15427 , +-25 , +-29875 , +18401 , +20031 , +24553 , +15797 , +27355 , +-30335 , +23991 , +-15479 , +27069 , +-22391 , +8985 , +-7995 , +-10917 , +-14459 , +15719 , +24797 , +-3301 , +31129 , +-13507 , +-25121 , +1277 , +16197 , +-13131 , +11277 , +8201 , +32049 , +3621 , +-32273 , +18759 , +2955 , +-23223 , +-2835 , +4415 , +-2595 , +30985 , +-7575 , +26085 , +-31901 , +-13395 , +23893 , +-11493 , +8173 , +16271 , +14411 , +-5719 , +15653 , +20059 , +-15323 , +1193 , +-15235 , +-21825 , +6937 , +9615 , +12657 , +-31571 , +20553 , +7829 , +-5009 , +10249 , +23521 , +-15429 , +-469 , +-4631 , +7085 , +23095 , +-19599 , +-1975 , +16437 , +-391 , +18819 , +-20415 , +32333 , +14481 , +15091 , +32447 , +-8907 , +30523 , +17649 , +-18491 , +31017 , +-22199 , +-17105 , +12311 , +-28029 , +-21087 , +20529 , +30071 , +16713 , +-11855 , +-16341 , +8545 , +-23219 , +5739 , +-17331 , +15931 , +-5441 , +29629 , +26797 , +14103 , +-1209 , +-11643 , +-20847 , +18911 , +13219 , +-2801 , +-4787 , +-3045 , +-2639 , +1541 , +9111 , +21017 , +28437 , +1519 , +10595 , +-5961 , +27723 , +-12507 , +4665 , +-11897 , +-28609 , +-6069 , +20497 , +-15973 , +-14235 , +-8887 , +-20831 , +-7505 , +21841 , +22205 , +-16573 , +-2333 , +16337 , +-22531 , +-12993 , +-16643 , +-28027 , +2947 , +-3413 , +6929 , +12271 , +17907 , +26053 , +-8761 , +-25319 , +-6265 , +-26939 , +-13811 , +-26461 , +-7157 , +13879 , +-19637 , +-10663 , +-18089 , +-17453 , +14377 , +-18601 , +-9147 , +-31271 , +4017 , +22165 , +-23511 , +10463 , +24863 , +-15869 , +27853 , +2105 , +7685 , +-18395 , +9953 , +-12609 , +-10479 , +-15837 , +3833 , +-8145 , +829 , +617 , +-15613 , +23305 , +12681 , +-28743 , +28225 , +-15653 , +7477 , +-19255 , +17345 , +-5343 , +7287 , +-5035 , +-179 , +15009 , +-7755 , +-3655 , +-23311 , +-8395 , +1849 , +-16885 , +14055 , +2609 , +23915 , +-13903 , +-26091 , +-13003 , +29579 , +27255 , +24835 , +-20605 , +21227 , +-22993 , +-19117 , +-27685 , +-7013 , +20927 , +6075 , +1749 , +-1613 , +-11073 , +11899 , +-29267 , +28153 , +27023 , +23125 , +3499 , +23849 , +12783 , +18949 , +-7181 , +-7519 , +-2021 , +17467 , +-14887 , +23453 , +-2981 , +24593 , +447 , +-23567 , +28449 , +25601 , +14449 , +17729 , +-26719 , +-31899 , +9967 , +4277 , +26341 , +-19867 , +-26413 , +6965 , +-6295 , +-14219 , +6947 , +-27617 , +-18125 , +10569 , +-30807 , +28287 , +10855 , +11347 , +201 , +21703 , +-17311 , +-1353 , +30173 , +-8437 , +27985 , +7107 , +18447 , +-31823 , +-25011 , +26599 , +10153 , +15025 , +-4631 , +-26067 , +-15885 , +19269 , +-8359 , +14385 , +22409 , +15405 , +-23047 , +2205 , +-11465 , +24151 , +-4749 , +-12261 , +31047 , +-5595 , +-2481 , +-29489 , +-14491 , +10013 , +-8433 , +-6065 , +-25359 , +-27097 , +29125 , +6175 , +17363 , +-27077 , +20011 , +-7007 , +29147 , +31657 , +-14275 , +3735 , +-9577 , +-28227 , +21323 , +-13553 , +27045 , +-249 , +-11875 , +-29209 , +-17001 , +1041 , +-24451 , +-9541 , +-1223 , +-29557 , +-18215 , +21605 , +-28293 , +-29935 , +-17323 , +-15633 , +1473 , +5983 , +18151 , +18449 , +24761 , +-14591 , +23789 , +31267 , +21431 , +14489 , +19913 , +-25195 , +-20853 , +18825 , +-7441 , +-19217 , +15833 , +-4553 , +13191 , +-24769 , +-22031 , +9405 , +-2941 , +-745 , +28203 , +-1503 , +-25293 , +5127 , +-32583 , +6677 , +14433 , +26761 , +-15615 , +-7901 , +14821 , +18059 , +-11659 , +26993 , +12483 , +-4007 , +20973 , +-30221 , +-21059 , +-21481 , +17279 , +16415 , +13935 , +26559 , +-29999 , +31789 , +-25371 , +11159 , +12281 , +-14387 , +-27725 , +4899 , +31441 , +-16551 , +-10609 , +1187 , +32463 , +-10859 , +-16541 , +-8435 , +12127 , +23013 , +-24591 , +22141 , +-27467 , +14587 , +-18469 , +14133 , +14637 , +28707 , +8011 , +18189 , +26403 , +-21783 , +32257 , +32115 , +20287 , +855 , +-6423 , +-13857 , +-20643 , +23727 , +-20417 , +8395 , +4569 , +20641 , +-24549 , +1837 , +15725 , +9989 , +17805 , +21611 , +-4727 , +-12271 , +-10695 , +25303 , +27431 , +22801 , +26727 , +26277 , +7721 , +-11361 , +-7773 , +9061 , +-20697 , +10075 , +29137 , +-18441 , +-11821 , +-14811 , +-3389 , +-18171 , +20429 , +-17709 , +1111 , +20993 , +27635 , +2665 , +15625 , +-23407 , +13891 , +-8235 , +18191 , +7827 , +-6093 , +31261 , +16879 , +-375 , +-7809 , +21793 , +16533 , +-16739 , +23949 , +-31535 , +15347 , +-25071 , +31035 , +-17693 , +21007 , +317 , +-24257 , +-4345 , +-22111 , +-8195 , +249 , +8619 , +-11735 , +-1355 , +2511 , +12579 , +-1911 , +3523 , +-21757 , +14705 , +-14313 , +-17549 , +21003 , +30323 , +20545 , +25729 , +19307 , +8347 , +-14697 , +-22775 , +-25589 , +15405 , +32109 , +-17407 , +-5361 , +-11535 , +-6419 , +27445 , +-27601 , +-28561 , +-843 , +-12877 , +31377 , +14499 , +-7193 , +-26921 , +-19429 , +-3779 , +9673 , +7087 , +-23207 , +-10931 , +21719 , +-12035 , +-23103 , +-13433 , +30305 , +30641 , +-15205 , +5873 , +2205 , +-20517 , +-14763 , +-26079 , +-705 , +10789 , +-3499 , +17655 , +-32613 , +12237 , +-13993 , +-23349 , +-6867 , +-18151 , +15429 , +3889 , +-29761 , +-13739 , +31629 , +24359 , +8185 , +20293 , +-2313 , +-17191 , +381 , +11553 , +-23035 , +26567 , +12671 , +-15607 , +12479 , +-1135 , +-25387 , +-28413 , +4375 , +10015 , +6811 , +15725 , +17593 , +20067 , +-2233 , +-20231 , +-22685 , +3723 , +25659 , +-32481 , +-29243 , +7359 , +-23581 , +24867 , +-18225 , +30547 , +19019 , +-11911 , +14735 , +24961 , +27195 , +-14897 , +23943 , +8613 , +1737 , +31097 , +15241 , +-1557 , +-24209 , +10865 , +-1787 , +21397 , +15537 , +-3383 , +24557 , +-27483 , +-21725 , +30885 , +-8953 , +-26591 , +-31987 , +-21323 , +32449 , +16577 , +-29055 , +20269 , +3219 , +7727 , +4079 , +29497 , +-12595 , +-25415 , +-19647 , +-18185 , +7927 , +-18547 , +-31889 , +30193 , +22693 , +-23185 , +-17251 , +-31723 , +17101 , +30707 , +-11601 , +-4313 , +-30301 , +9517 , +-31651 , +14531 , +24815 , +-3077 , +21205 , +27339 , +-6423 , +-15707 , +13771 , +-20379 , +24457 , +8235 , +-7149 , +-21133 , +-8091 , +-20495 , +-30531 , +19591 , +-31483 , +-12299 , +15523 , +15199 , +-15419 , +-1649 , +7311 , +-12835 , +-1251 , +-11095 , +21445 , +32633 , +-12409 , +30061 , +-3289 , +-13501 , +29135 , +-17271 , +-4927 , +-28081 , +26095 , +20957 , +3057 , +-14149 , +-7583 , +12729 , +16873 , +-24295 , +24579 , +17557 , +7905 , +-4495 , +29283 , +-1721 , +-12395 , +-2889 , +-32615 , +22969 , +30579 , +24507 , +30377 , +-28119 , +16165 , +-26449 , +1869 , +25301 , +-4177 , +12819 , +-27051 , +29755 , +29189 , +-24013 , +25471 , +1493 , +2849 , +1053 , +3531 , +-4281 , +-21343 , +5915 , +1883 , +27673 , +12763 , +13477 , +4541 , +-22025 , +-7821 , +29925 , +23251 , +-28321 , +2939 , +-18017 , +21023 , +-16159 , +7167 , +-10311 , +-12637 , +13009 , +-1497 , +-26841 , +-25295 , +-31357 , +3019 , +-16025 , +3915 , +24067 , +-19061 , +-2433 , +-23943 , +-8891 , +-20631 , +-32663 , +22553 , +-24597 , +1499 , +-8941 , +-10811 , +16499 , +8047 , +14043 , +-6625 , +-11281 , +-24873 , +-31879 , +29231 , +22849 , +31105 , +-32377 , +-29897 , +-27947 , +6847 , +19563 , +-25325 , +17105 , +-5305 , +-16677 , +24837 , +16849 , +5473 , +23501 , +-22249 , +26661 , +-8847 , +-2575 , +-25615 , +-16003 , +26389 , +-12885 , +31021 , +811 , +16057 , +23943 , +32305 , +-17191 , +32691 , +-29383 , +905 , +15291 , +-4387 , +-31993 , +27325 , +-26545 , +-7771 , +-13359 , +-2901 , +-6511 , +18857 , +4479 , +6233 , +179 , +-17197 , +6137 , +29273 , +-7085 , +-11797 , +14501 , +-7023 , +6715 , +-22091 , +5211 , +-351 , +8337 , +-897 , +-19491 , +18101 , +20365 , +-31675 , +-12595 , +31453 , +12477 , +6979 , +28971 , +25315 , +-16207 , +26377 , +-18615 , +19113 , +-27849 , +26655 , +-10175 , +-17157 , +21015 , +-14833 , +14067 , +-26901 , +-29117 , +12295 , +-20105 , +2985 , +23451 , +-22037 , +-6377 , +-20267 , +-20717 , +7665 , +-21303 , +11103 , +-2179 , +2745 , +26663 , +-27429 , +-5961 , +-23071 , +-30493 , +12633 , +-3737 , +19231 , +-10045 , +-29251 , +21297 , +-28709 , +-9709 , +-24935 , +21869 , +-11449 , +-4949 , +-2175 , +-30107 , +-23821 , +29011 , +-19735 , +-24825 , +-13335 , +-23605 , +8823 , +-21215 , +28739 , +25405 , +-8227 , +-30697 , +-1727 , +-24265 , +22067 , +-997 , +15847 , +-20705 , +23503 , +30693 , +-18927 , +8749 , +-2921 , +6383 , +4621 , +-31259 , +-11039 , +-28121 , +3755 , +-27377 , +-17207 , +-6873 , +-8735 , +12585 , +17409 , +26099 , +-1057 , +-12183 , +11829 , +301 , +-14177 , +-26071 , +-8225 , +15563 , +-16885 , +-5651 , +2965 , +-5289 , +-25977 , +28879 , +12277 , +2459 , +22549 , +-21125 , +-537 , +-16669 , +18403 , +-3417 , +16263 , +-2125 , +10857 , +-19439 , +22385 , +-27911 , +-25601 , +20973 , +-3935 , +-26163 , +-20997 , +6881 , +-2365 , +31139 , +1081 , +-17283 , +28435 , +-18165 , +20297 , +-9671 , +18867 , +7899 , +31473 , +737 , +-15493 , +-15369 , +26967 , +-17255 , +28767 , +1915 , +-28019 , +-8375 , +-31175 , +-8831 , +24753 , +-2655 , +-32723 , +28747 , +-24449 , +-9077 , +-19847 , +-29691 , +-8595 , +22817 , +-6449 , +-13063 , +2113 , +-8919 , +-26323 , +2117 , +11049 , +12811 , +-4807 , +-6377 , +-22957 , +16969 , +-3055 , +11369 , +-22009 , +-18055 , +23211 , +-25303 , +23357 , +-19781 , +6311 , +771 , +29621 , +11695 , +14251 , +16783 , +-18799 , +-32267 , +19257 , +-2547 , +4457 , +-30437 , +-20215 , +-26215 , +-15897 , +-18661 , +12763 , +-25111 , +22493 , +-9903 , +6873 , +31869 , +-5153 , +-19469 , +26471 , +12385 , +25175 , +13833 , +4989 , +4697 , +4899 , +31723 , +11905 , +-28761 , +-21083 , +22571 , +-14693 , +-19661 , +-20125 , +-25829 , +17555 , +-1709 , +21275 , +-12095 , +20513 , +26103 , +9817 , +-21179 , +-11059 , +21863 , +25491 , +-8195 , +16197 , +-131 , +8899 , +-31535 , +-29905 , +9553 , +25207 , +-5059 , +14727 , +-7809 , +13165 , +-3637 , +-14473 , +4829 , +-8017 , +-26363 , +-16979 , +22951 , +27687 , +10477 , +-4045 , +8007 , +14259 , +32255 , +1735 , +-24447 , +12999 , +-13673 , +-6733 , +29233 , +25725 , +32255 , +3881 , +30851 , +10801 , +-30255 , +-27371 , +-14171 , +661 , +-16895 , +-19595 , +27915 , +15693 , +29515 , +-21703 , +-31723 , +26373 , +15403 , +-2671 , +-20131 , +-13813 , +-11173 , +26571 , +22875 , +-9373 , +1733 , +24491 , +-24663 , +-5021 , +-15871 , +-28609 , +-24649 , +-1845 , +4935 , +-30919 , +-10237 , +-5799 , +16359 , +-32053 , +16339 , +8931 , +-19127 , +-20485 , +-151 , +-17935 , +1883 , +26999 , +17089 , +8917 , +-19057 , +-28937 , +7875 , +-18881 , +-4525 , +-29427 , +253 , +-7591 , +2311 , +11645 , +-24101 , +24669 , +-4493 , +-14307 , +-3739 , +18091 , +10179 , +-5085 , +-2453 , +20329 , +-13313 , +6659 , +6213 , +11151 , +1025 , +-23097 , +-13555 , +14987 , +23785 , +23011 , +5711 , +32337 , +-24287 , +-3441 , +-4535 , +9207 , +28617 , +2469 , +-10339 , +30919 , +19121 , +-29971 , +-12917 , +-23581 , +21211 , +18687 , +-7505 , +-945 , +27495 , +-13675 , +-27605 , +21393 , +-1269 , +-6039 , +18287 , +3275 , +1051 , +21383 , +-5531 , +22603 , +-13591 , +-25559 , +11825 , +27561 , +-15663 , +-12021 , +21601 , +3679 , +-1623 , +20295 , +1707 , +21213 , +-17993 , +-9557 , +12585 , +-11225 , +-26067 , +-26987 , +22275 , +20453 , +-18913 , +-2237 , +22965 , +-2813 , +16891 , +17329 , +10943 , +16069 , +14213 , +-16401 , +24547 , +-19361 , +20551 , +6139 , +8661 , +25867 , +1679 , +8983 , +28025 , +30887 , +-11035 , +-26721 , +8089 , +-21303 , +27653 , +-14487 , +-15581 , +5719 , +5973 , +-879 , +-26159 , +-97 , +2013 , +-28965 , +-10377 , +15087 , +-16961 , +18825 , +-30809 , +-15953 , +18483 , +14765 , +5621 , +-2057 , +-27659 , +32011 , +-3925 , +27815 , +-32695 , +10597 , +15873 , +28161 , +-3477 , +-7071 , +7125 , +19133 , +-24691 , +17363 , +25065 , +-26715 , +-15035 , +-29025 , +24203 , +20907 , +-30575 , +-2547 , +-31263 , +13443 , +13127 , +-8289 , +-29803 , +7609 , +2065 , +22385 , +-8437 , +-11195 , +-6941 , +17157 , +547 , +3249 , +27633 , +27815 , +-19863 , +413 , +-5329 , +-197 , +23761 , +30951 , +-17859 , +-30051 , +-11285 , +-29377 , +18155 , +10355 , +-16225 , +5179 , +-30679 , +-9847 , +-15003 , +-1807 , +3969 , +-19545 , +-13319 , +25361 , +28945 , +-2069 , +30103 , +633 , +14847 , +-22115 , +9647 , +22355 , +11639 , +-17015 , +-24797 , +20137 , +29 , +31197 , +-21509 , +2937 , +18953 , +7795 , +-14437 , +13399 , +-6341 , +28089 , +17279 , +-25217 , +32409 , +11775 , +-8591 , +-22681 , +26465 , +15183 , +17987 , +10727 , +-23261 , +16843 , +31749 , +17345 , +12861 , +-18305 , +-27971 , +-6461 , +20683 , +13503 , +-16227 , +30805 , +6695 , +-21001 , +15043 , +24227 , +1245 , +-13815 , +-11417 , +-11747 , +-26335 , +-13787 , +-11625 , +-13403 , +3021 , +12319 , +373 , +26391 , +-2093 , +-19385 , +24549 , +-28049 , +-4553 , +-23615 , +31945 , +24911 , +5257 , +16223 , +-5955 , +-8917 , +-30243 , +13045 , +-17591 , +-22059 , +-13763 , +-17097 , +-23911 , +22163 , +-14165 , +-24565 , +30143 , +-19521 , +-2159 , +29029 , +-16037 , +1245 , +-2121 , +25753 , +18147 , +26417 , +9671 , +9279 , +-6579 , +17619 , +-16837 , +-11139 , +-5549 , +11347 , +-12331 , +-10773 , +12065 , +-6975 , +-19301 , +24799 , +7059 , +5715 , +18767 , +-28335 , +-6929 , +24441 , +-25757 , +-1235 , +5395 , +11887 , +17781 , +24359 , +-13509 , +14171 , +12871 , +-26595 , +-20695 , +-8477 , +-463 , +22759 , +3821 , +29001 , +-20703 , +-11599 , +7953 , +32251 , +-1263 , +-9261 , +-10921 , +12209 , +-11015 , +-20693 , +22001 , +-1787 , +30797 , +-9227 , +27443 , +28039 , +-21771 , +32285 , +-43 , +-24741 , +28099 , +22303 , +5027 , +-9911 , +-11411 , +-8355 , +8887 , +3423 , +13823 , +-6161 , +30513 , +-12291 , +-32037 , +-6903 , +23923 , +14199 , +-10963 , +30917 , +-19761 , +30763 , +5859 , +22153 , +-14643 , +-27369 , +-8155 , +5839 , +1749 , +-787 , +19793 , +5003 , +27765 , +27573 , +873 , +-6917 , +9735 , +-5923 , +6935 , +-26875 , +29183 , +14803 , +10783 , +12039 , +9357 , +-24289 , +9045 , +-26057 , +-12311 , +16889 , +17687 , +-25483 , +1787 , +97 , +-12725 , +-10327 , +-19813 , +13753 , +-20023 , +-31855 , +-3769 , +4569 , +101 , +-4569 , +31071 , +171 , +16725 , +23659 , +-2601 , +-5053 , +28985 , +25543 , +21871 , +-19599 , +-8317 , +21473 , +-31631 , +-21279 , +-23937 , +-14099 , +-30491 , +-29007 , +-9791 , +-367 , +31049 , +-28029 , +30495 , +-1221 , +17865 , +11805 , +-14807 , +11243 , +-13321 , +14461 , +27171 , +-30559 , +11527 , +-11409 , +2683 , +-9953 , +-8577 , +-3669 , +26047 , +12885 , +28023 , +-11929 , +795 , +17449 , +27721 , +17267 , +14925 , +-28713 , +-32043 , +5837 , +-13795 , +7881 , +6441 , +-32577 , +-19117 , +-11793 , +-27449 , +-9869 , +-25035 , +-7795 , +-24491 , +-31481 , +22651 , +-23127 , +30171 , +24881 , +-5689 , +16071 , +-23693 , +-28857 , +-20325 , +14171 , +17031 , +-3353 , +-5673 , +-19055 , +6537 , +15619 , +19627 , +21929 , +-24535 , +-9345 , +-2795 , +17615 , +24075 , +-23225 , +21715 , +-19339 , +-25593 , +-25879 , +25309 , +15913 , +-8237 , +-27735 , +-16035 , +20463 , +10829 , +12063 , +4649 , +14611 , +28705 , +-7353 , +12731 , +-4211 , +17681 , +32543 , +-28507 , +9675 , +12705 , +-1597 , +25485 , +-14065 , +-21677 , +-6667 , +-7777 , +-32689 , +10081 , +25163 , +18833 , +17277 , +16375 , +-8783 , +-6897 , +-23701 , +25567 , +-30573 , +-15689 , +-9693 , +2249 , +-13719 , +24213 , +15285 , +-10245 , +-27687 , +-3821 , +8089 , +-12925 , +-6847 , +-25479 , +-9597 , +-15875 , +25057 , +12511 , +-8003 , +22209 , +18273 , +-16727 , +-22277 , +-17255 , +-24073 , +-20611 , +26551 , +19719 , +5369 , +-25155 , +15111 , +28137 , +4083 , +-23939 , +-8459 , +-18493 , +-14269 , +20985 , +-32167 , +-10641 , +-12499 , +7823 , +-11219 , +7247 , +-25475 , +23103 , +-7827 , +16401 , +-6769 , +-29039 , +-9375 , +15587 , +6387 , +25377 , +24195 , +-13019 , +-10623 , +-13689 , +20947 , +30631 , +-17421 , +-21031 , +-2391 , +-22685 , +24057 , +-12645 , +16661 , +-14933 , +-14889 , +5955 , +4273 , +-12563 , +19319 , +4643 , +25085 , +23009 , +9217 , +-16663 , +4149 , +-30389 , +31995 , +32407 , +16299 , +-8151 , +31705 , +19961 , +2201 , +28787 , +-1515 , +1695 , +31361 , +23625 , +21965 , +-8627 , +-28667 , +8635 , +11993 , +-8957 , +11061 , +-22289 , +26715 , +-32411 , +-19857 , +-29467 , +18147 , +19387 , +26039 , +-26963 , +767 , +26471 , +1167 , +-7395 , +-22441 , +10975 , +-9143 , +-21755 , +-26301 , +-23007 , +-10519 , +9715 , +-28955 , +-2125 , +-23949 , +32603 , +28089 , +-24561 , +-30519 , +22113 , +-14659 , +-29787 , +4097 , +-16385 , +23803 , +2895 , +-1217 , +17353 , +-30815 , +29511 , +-15349 , +-13533 , +-14171 , +-26457 , +9257 , +-1291 , +28627 , +-6825 , +-14353 , +-4121 , +-23965 , +14985 , +-16089 , +-10987 , +-24801 , +22965 , +-11691 , +19791 , +-26905 , +3085 , +10915 , +9925 , +-3621 , +-16271 , +-21973 , +20811 , +22759 , +-10255 , +18133 , +-28921 , +23523 , +22715 , +-22103 , +-10321 , +3109 , +16285 , +-25423 , +-6589 , +25501 , +10225 , +24907 , +-5829 , +-12183 , +-32223 , +-30977 , +-12981 , +-17165 , +4245 , +23259 , +6803 , +27781 , +-7371 , +-30905 , +-9127 , +1119 , +-30379 , +-923 , +-29883 , +6481 , +-19911 , +-18211 , +29199 , +-26153 , +-3069 , +-29887 , +-31547 , +27821 , +-3787 , +25563 , +8823 , +-25627 , +-27491 , +20237 , +-18059 , +25731 , +-25641 , +-20443 , +-14845 , +661 , +10307 , +-11087 , +9111 , +-28219 , +-29063 , +30819 , +10379 , +-9607 , +7237 , +20827 , +-31653 , +25449 , +3353 , +15627 , +22611 , +-24655 , +25875 , +9603 , +-32043 , +-28305 , +-5535 , +14165 , +-27389 , +-18209 , +-2741 , +32742 , +27395 , +-22557 , +20127 , +-29627 , +-8531 , +4657 , +-11089 , +8331 , +-29493 , +-20011 , +7881 , +-24665 , +9421 , +-10149 , +-10451 , +15297 , +15101 , +1117 , +899 , +-30963 , +5441 , +21403 , +-3113 , +32031 , +27211 , +10651 , +4113 , +-25393 , +-29867 , +-7499 , +15337 , +10885 , +-4011 , +-5191 , +2405 , +13075 , +-24901 , +5623 , +29127 , +26391 , +25249 , +32744 , +19733 , +26307 , +21131 , +-5579 , +16383 , +-27067 , +-27237 , +-11939 , +22627 , +4753 , +-7095 , +9161 , +4161 , +-8507 , +-17509 , +-5025 , +-4301 , +-7687 , +-17697 , +-13923 , +-32151 , +-12903 , +9181 , +-30413 , +-7399 , +-31683 , +-2661 , +-16359 , +-31873 , +6403 , +-26233 , +-18647 , +31307 , +-153 , +-25799 , +-31691 , +1193 , +-31849 , +25255 , +-22627 , +30377 , +9035 , +26845 , +1643 , +21055 , +-8409 , +-8397 , +-26387 , +-17221 , +7299 , +16653 , +-23101 , +2749 , +12243 , +-14327 , +-7807 , +-25937 , +10099 , +15037 , +19143 , +-19005 , +-4349 , +3567 , +6861 , +-20641 , +25411 , +20551 , +-23925 , +-1249 , +28261 , +22673 , +27719 , +29001 , +-15127 , +-20885 , +31151 , +31173 , +23281 , +9605 , +-2445 , +21909 , +10781 , +-23725 , +14167 , +16081 , +24547 , +-30901 , +24021 , +-26859 , +-29595 , +11667 , +30767 , +-9083 , +-5691 , +-31675 , +30211 , +-25283 , +21513 , +11043 , +-13973 , +8525 , +2403 , +5573 , +3217 , +815 , +-13541 , +10339 , +-31801 , +28351 , +30421 , +-14593 , +-11229 , +16051 , +-20359 , +-12511 , +-14709 , +-20331 , +-19333 , +-3057 , +28511 , +-6343 , +-5437 , +-2677 , +-28031 , +-3149 , +20985 , +-22275 , +-25607 , +-25385 , +23397 , +19773 , +1279 , +-25307 , +20287 , +8375 , +32167 , +-28849 , +-11887 , +-19913 , +-19741 , +16671 , +-24699 , +-7151 , +2347 , +-23291 , +7491 , +6627 , +9103 , +6653 , +-13241 , +-30519 , +-28851 , +16909 , +16957 , +8725 , +27633 , +8001 , +-18353 , +4231 , +26591 , +-20707 , +-13559 , +16389 , +-5763 , +-17257 , +-32087 , +-6187 , +-17223 , +8341 , +15355 , +-28843 , +7473 , +10453 , +-30291 , +-31445 , +29885 , +23931 , +-22995 , +16653 , +-22895 , +23797 , +-29189 , +-22551 , +16081 , +1665 , +23171 , +-21853 , +24233 , +-21733 , +-2697 , +14159 , +-17177 , +31999 , +-17241 , +-2837 , +-27887 , +-2669 , +11857 , +-15983 , +-12551 , +27121 , +13833 , +27437 , +24801 , +-31279 , +12801 , +-25921 , +-505 , +-6907 , +18665 , +27149 , +12227 , +-31887 , +10309 , +-25637 , +1817 , +15237 , +-15547 , +-4447 , +19679 , +2869 , +10785 , +-32311 , +-31167 , +22379 , +4587 , +-15007 , +-23061 , +-6647 , +9449 , +-5033 , +-15977 , +-14761 , +-19603 , +22831 , +-23515 , +-8189 , +-8913 , +-709 , +-27589 , +24721 , +-13533 , +8789 , +10067 , +-16547 , +4563 , +-26861 , +31063 , +-28665 , +-11213 , +-19067 , +-24385 , +-9351 , +-16643 , +15461 , +-18661 , +14163 , +29831 , +29399 , +20029 , +21479 , +-32483 , +-29029 , +-22079 , +14517 , +28627 , +-11059 , +-27347 , +-6311 , +6117 , +27921 , +11913 , +-25327 , +-17777 , +24403 , +32115 , +27305 , +2393 , +-19457 , +11963 , +23291 , +-21249 , +11961 , +19577 , +-8227 , +25789 , +-25713 , +19111 , +-16985 , +22061 , +9913 , +16439 , +11553 , +-23137 , +-18739 , +-23383 , +27641 , +-4371 , +-16011 , +27175 , +29637 , +-18729 , +-27985 , +-13281 , +3957 , +27865 , +32375 , +-21935 , +1865 , +5509 , +-2799 , +-14221 , +-25779 , +13653 , +-3663 , +-13761 , +1103 , +5133 , +-17477 , +17429 , +13143 , +-3957 , +29307 , +-18425 , +-30813 , +15647 , +23387 , +-10371 , +-19691 , +31853 , +27289 , +-7867 , +-31433 , +-10573 , +-379 , +29743 , +-11091 , +-75 , +17715 , +-20961 , +16169 , +-31481 , +17591 , +-4177 , +-2065 , +7399 , +-549 , +7233 , +23741 , +3487 , +-24233 , +-20845 , +-30381 , +17743 , +20363 , +31199 , +-24225 , +14927 , +23221 , +28527 , +2297 , +11263 , +-31835 , +16567 , +17311 , +-9175 , +10499 , +13799 , +-20057 , +22737 , +-7947 , +4365 , +-7107 , +-4465 , +30049 , +21923 , +-16431 , +-9369 , +-17753 , +-13139 , +9499 , +-9691 , +14549 , +-25263 , +22665 , +7725 , +8027 , +-11795 , +-8125 , +-10277 , +31563 , +-24145 , +4245 , +-9897 , +10255 , +22187 , +-275 , +29673 , +29339 , +10361 , +4951 , +9693 , +-6355 , +-7351 , +-3983 , +12493 , +16769 , +-19591 , +-5663 , +-20349 , +-2169 , +-4683 , +-16043 , +19019 , +22179 , +11137 , +-7699 , +3283 , +-21671 , +-27549 , +-11709 , +-26505 , +27535 , +-21653 , +5335 , +10273 , +-9407 , +31057 , +12047 , +-27997 , +9147 , +27411 , +3753 , +-9081 , +21835 , +-17149 , +-31305 , +29297 , +19331 , +-13721 , +5395 , +-23575 , +-5143 , +6535 , +-17061 , +30405 , +-18639 , +31827 , +3691 , +27377 , +9461 , +7535 , +11595 , +18127 , +-15889 , +-11821 , +2225 , +-31727 , +-30545 , +-31013 , +29687 , +29959 , +27859 , +9447 , +24719 , +-17789 , +-28479 , +-16785 , +-4611 , +8747 , +7643 , +25495 , +-30637 , +-31411 , +14141 , +29269 , +-13023 , +-16319 , +-273 , +-17675 , +28405 , +23095 , +9631 , +20803 , +-12467 , +-2665 , +-805 , +25113 , +-30955 , +8403 , +-31801 , +-6791 , +-27243 , +-24635 , +26197 , +-31451 , +28153 , +-14977 , +26365 , +-28745 , +-25801 , +-2389 , +11001 , +20543 , +12947 , +-5027 , +-7947 , +-23987 , +-13163 , +-12435 , +-17841 , +6809 , +15483 , +-15275 , +-20791 , +-25585 , +-16839 , +-131 , +-32061 , +-20115 , +-11537 , +-1509 , +-30727 , +-31911 , +-31783 , +-8307 , +4269 , +-15621 , +17367 , +-13525 , +3439 , +24849 , +10065 , +-4447 , +-12981 , +27019 , +-21821 , +14535 , +22655 , +-9311 , +-16475 , +-27395 , +23999 , +-10643 , +22507 , +23291 , +10721 , +-3583 , +10239 , +1839 , +-24039 , +7421 , +-10449 , +-11369 , +-18249 , +-10579 , +22195 , +18705 , +21585 , +7577 , +-26857 , +24887 , +8585 , +-5463 , +21565 , +20669 , +18241 , +-28501 , +12243 , +-28097 , +30027 , +-10111 , +-11709 , +18847 , +17839 , +12707 , +19001 , +-26663 , +26711 , +-12469 , +25229 , +-2207 , +-28339 , +2555 , +9929 , +14583 , +-24209 , +-8797 , +19987 , +14589 , +427 , +-9165 , +-15187 , +-6827 , +-22343 , +27823 , +3051 , +-21583 , +-15541 , +-20783 , +-22351 , +-6029 , +30411 , +-9445 , +22623 , +28163 , +-18799 , +30571 , +17489 , +-17249 , +-23651 , +14363 , +-5161 , +705 , +28363 , +-6763 , +-855 , +32235 , +13713 , +7789 , +-11801 , +21507 , +-11985 , +19955 , +-11899 , +32049 , +4207 , +-20651 , +24651 , +-10711 , +21467 , +-19155 , +-23471 , +-3309 , +1133 , +-21087 , +-12823 , +-13607 , +-9005 , +-1293 , +7973 , +-11523 , +32033 , +-18269 , +27081 , +-23553 , +16647 , +9469 , +15299 , +-16861 , +-12147 , +-22727 , +29217 , +-31019 , +25419 , +-13809 , +27281 , +5757 , +11805 , +715 , +-29875 , +-4391 , +-3233 , +-25363 , +22943 , +12751 , +11681 , +-23999 , +-10545 , +28881 , +-13083 , +5997 , +23461 , +-21339 , +-429 , +25873 , +-21931 , +-25141 , +-2449 , +17763 , +28419 , +-8881 , +13781 , +3641 , +-6479 , +1567 , +16497 , +-20557 , +-6977 , +26345 , +16177 , +16191 , +-4385 , +23661 , +-31673 , +26435 , +-22643 , +-5033 , +27097 , +-27859 , +16133 , +-18277 , +-31943 , +12295 , +8895 , +-7357 , +-26459 , +-9833 , +-23701 , +-1323 , +25973 , +-13323 , +-13991 , +-30945 , +-28457 , +29085 , +3975 , +20117 , +-9969 , +26127 , +15619 , +-5081 , +-5861 , +-15133 , +5363 , +-12903 , +-12027 , +7517 , +5385 , +12893 , +-26493 , +-7533 , +-1417 , +17127 , +-7107 , +-20495 , +17767 , +-10101 , +9605 , +14949 , +29433 , +3533 , +19589 , +17893 , +9657 , +12099 , +29957 , +30611 , +-2927 , +9445 , +-31339 , +23637 , +6217 , +-5149 , +14669 , +31717 , +-20615 , +14603 , +-29689 , +-12179 , +-12025 , +-9331 , +271 , +31397 , +9495 , +-1947 , +-17311 , +2655 , +15497 , +-18903 , +-6557 , +13225 , +24307 , +29027 , +21011 , +18529 , +1809 , +4461 , +-8755 , +20045 , +-14909 , +-27203 , +-31117 , +2485 , +-15485 , +29649 , +-23243 , +-11145 , +-26527 , +-8847 , +20413 , +-26205 , +-19853 , +-30823 , +21229 , +-12911 , +723 , +2501 , +-16361 , +-17795 , +10519 , +28113 , +-31567 , +-1645 , +-10939 , +2121 , +1167 , +28827 , +-26545 , +12617 , +11935 , +-21511 , +-9463 , +-2607 , +1051 , +-4771 , +13217 , +22941 , +2627 , +-14649 , +-11877 , +16767 , +-24937 , +-26067 , +14399 , +-25039 , +-23153 , +-10871 , +-97 , +-4167 , +-29747 , +17275 , +-11263 , +-18129 , +4571 , +18519 , +27617 , +-725 , +-9625 , +25537 , +-21403 , +23177 , +13035 , +-12599 , +-19371 , +-7729 , +3835 , +-29057 , +1427 , +15099 , +-21015 , +-11513 , +-31467 , +13283 , +-7417 , +-1221 , +-30373 , +20231 , +30819 , +5309 , +-20633 , +27373 , +-23565 , +12427 , +-20937 , +6647 , +1879 , +25631 , +-8009 , +-15685 , +12811 , +-12539 , +-16829 , +8415 , +7715 , +31979 , +-1641 , +15975 , +-24701 , +31817 , +32329 , +32153 , +15763 , +359 , +1219 , +-13491 , +28541 , +-4607 , +29879 , +-28217 , +-19751 , +-27301 , +-12769 , +-31725 , +29945 , +5341 , +-12121 , +-9769 , +18063 , +6433 , +6583 , +5035 , +20971 , +26517 , +-3879 , +-8201 , +-29771 , +1169 , +31421 , +14409 , +-27099 , +19949 , +-30031 , +20263 , +-12617 , +-7659 , +-13679 , +26221 , +32357 , +-21591 , +28995 , +9765 , +-23453 , +-5739 , +16307 , +-29731 , +21329 , +-29793 , +-955 , +2687 , +6391 , +-17527 , +9423 , +-3417 , +26745 , +-5469 , +3861 , +-17531 , +32531 , +15339 , +12219 , +17445 , +-17585 , +-23911 , +-16451 , +-23211 , +-8513 , +-29375 , +30833 , +-21517 , +12851 , +30057 , +-25107 , +-27697 , +1135 , +11161 , +4117 , +6903 , +31593 , +14337 , +-26115 , +-31331 , +12285 , +10119 , +14321 , +-21917 , +-29661 , +7519 , +-29717 , +-24777 , +25513 , +-32473 , +14461 , +7851 , +-16527 , +8575 , +23135 , +15825 , +21279 , +-23777 , +-10159 , +-30065 , +-27307 , +-27541 , +-15959 , +10867 , +-3473 , +-615 , +29491 , +4629 , +4531 , +-15049 , +-17727 , +-4891 , +-23279 , +-16051 , +-20209 , +-12915 , +-17575 , +-13065 , +-32185 , +16059 , +3307 , +-17801 , +-8971 , +-13173 , +15101 , +31181 , +16257 , +-25009 , +31045 , +19417 , +-9179 , +14577 , +-26053 , +23013 , +19299 , +453 , +-2609 , +-30269 , +-15103 , +-26139 , +8861 , +-6549 , +6015 , +-22011 , +-1627 , +29963 , +5653 , +14035 , +-9077 , +-12643 , +-19173 , +5573 , +-18871 , +22025 , +-29421 , +-25995 , +-20895 , +25271 , +-999 , +5245 , +1697 , +14245 , +-25127 , +13769 , +6999 , +7939 , +21005 , +-1677 , +-509 , +-32183 , +-30357 , +8981 , +-23913 , +22227 , +4395 , +-4433 , +5927 , +-18705 , +5363 , +2281 , +-16853 , +-129 , +-28843 , +26627 , +815 , +18959 , +-7993 , +7451 , +-32243 , +-25753 , +-15083 , +-18931 , +6309 , +-24913 , +24415 , +18377 , +-9449 , +17653 , +-27499 , +-18131 , +25211 , +8539 , +27747 , +26201 , +28177 , +-9829 , +-20303 , +-19313 , +20233 , +-31959 , +-31843 , +-20867 , +5801 , +17615 , +9193 , +16677 , +-239 , +5303 , +-26625 , +12585 , +1649 , +-5359 , +30563 , +24747 , +13503 , +16679 , +-30041 , +32157 , +-31763 , +13549 , +31215 , +-20317 , +-7517 , +10535 , +16857 , +25695 , +18813 , +14835 , +-22779 , +-17065 , +23223 , +24045 , +24575 , +-9665 , +-31631 , +-29765 , +11715 , +29915 , +7517 , +-17357 , +-25937 , +-1197 , +29695 , +8421 , +-26635 , +-17911 , +18527 , +26431 , +-20063 , +11767 , +-22459 , +24603 , +4359 , +6021 , +-23057 , +-7201 , +1469 , +26071 , +-7863 , +19213 , +19731 , +-27977 , +23461 , +21349 , +-12277 , +-31009 , +-29193 , +-13963 , +4055 , +-24875 , +14725 , +-12623 , +-1853 , +-6075 , +-5339 , +5139 , +21435 , +12247 , +-22281 , +-7897 , +-29123 , +-2167 , +-15725 , +16301 , +4303 , +-4733 , +15309 , +9137 , +-9219 , +-1167 , +-13851 , +-6119 , +-23603 , +-31137 , +-9405 , +-2105 , +8625 , +-2291 , +-24151 , +-1237 , +-10991 , +8899 , +-26889 , +25187 , +-5587 , +-21325 , +29781 , +-23609 , +32677 , +-2105 , +5109 , +1805 , +617 , +-16127 , +13639 , +21717 , +-10185 , +-1459 , +-25681 , +17103 , +4237 , +-547 , +32707 , +-3003 , +21537 , +-19967 , +-13571 , +26431 , +-13599 , +-19079 , +5625 , +9745 , +12387 , +11349 , +-7901 , +5497 , +-12581 , +17737 , +-3 , +-18633 , +-26463 , +3973 , +-20791 , +-18143 , +6167 , +-18163 , +19149 , +10435 , +28207 , +-12909 , +9475 , +9063 , +5977 , +-29237 , +26449 , +23235 , +-20733 , +-2231 , +-31673 , +17917 , +27019 , +-27437 , +10579 , +22353 , +31931 , +-20677 , +11131 , +3617 , +11969 , +-2373 , +26253 , +15759 , +-15453 , +15555 , +1765 , +24471 , +311 , +22113 , +13721 , +19619 , +-32347 , +-16635 , +-24775 , +12203 , +-29613 , +5099 , +-13057 , +3777 , +-21153 , +-21 , +-14193 , +-16333 , +-15459 , +-20533 , +555 , +-23521 , +-17139 , +26407 , +-3733 , +-1395 , +-17973 , +19893 , +26741 , +11775 , +-12905 , +3379 , +4535 , +-5477 , +6073 , +22443 , +4121 , +22955 , +27021 , +-4525 , +14785 , +22987 , +13163 , +16623 , +-6849 , +2929 , +-4057 , +15763 , +-16057 , +-30191 , +-14583 , +26899 , +-20751 , +10667 , +-25531 , +-10299 , +5737 , +4331 , +18413 , +7915 , +-20953 , +-30789 , +11119 , +-10621 , +11439 , +-11683 , +-8819 , +-15463 , +-9025 , +-3833 , +9427 , +17199 , +-29683 , +7157 , +-1905 , +3459 , +-13185 , +21505 , +-16309 , +-5643 , +-35 , +-8251 , +-30271 , +27479 , +9747 , +3363 , +27989 , +19655 , +-6689 , +3949 , +-9965 , +-30965 , +-14319 , +20973 , +-1511 , +-18847 , +7485 , +5903 , +-863 , +-5921 , +-31239 , +-17431 , +23145 , +27973 , +-27253 , +30809 , +-4173 , +-17831 , +-30929 , +-3165 , +3771 , +1727 , +32193 , +-31359 , +18863 , +-22199 , +17921 , +31673 , +11053 , +-9761 , +4929 , +15425 , +-27347 , +-5435 , +11939 , +-25653 , +-375 , +-28031 , +4307 , +16609 , +18153 , +24107 , +-8649 , +27519 , +22847 , +-7095 , +-16979 , +-1751 , +21699 , +-12253 , +447 , +-633 , +29797 , +23967 , +-25501 , +-14477 , +27849 , +23963 , +-10965 , +-21859 , +30909 , +23225 , +-17923 , +26009 , +-13265 , +-2359 , +16975 , +31871 , +-23123 , +6289 , +-25377 , +24577 , +-18863 , +557 , +-24597 , +-18183 , +6211 , +-6169 , +-11297 , +-20331 , +-29775 , +8077 , +4257 , +-29477 , +12859 , +-32695 , +9525 , +31181 , +-32515 , +2809 , +-32253 , +-10499 , +-24333 , +29449 , +23939 , +-7771 , +-2553 , +-24633 , +19331 , +4927 , +1139 , +-16831 , +-16685 , +3231 , +27851 , +-1131 , +28033 , +25995 , +13929 , +32723 , +3989 , +14539 , +8301 , +-16053 , +28739 , +-15151 , +12591 , +-14229 , +18853 , +-1859 , +15417 , +31767 , +-7433 , +17929 , +-26941 , +-29059 , +-5819 , +-29037 , +-19805 , +8815 , +31407 , +-30921 , +-10291 , +-16063 , +-9187 , +26349 , +-19387 , +-18157 , +-11923 , +14945 , +-1379 , +31675 , +4159 , +-19459 , +-14619 , +5643 , +-15081 , +-12137 , +557 , +22453 , +-23771 , +10357 , +31855 , +-15455 , +30327 , +17651 , +-2791 , +-7997 , +-20303 , +-11629 , +-13835 , +881 , +-6075 , +1943 , +-31573 , +10049 , +-15827 , +5915 , +-333 , +-3753 , +15903 , +2219 , +21457 , +29517 , +-8887 , +-13221 , +23309 , +-14725 , +-25719 , +-7329 , +-8667 , +6103 , +13091 , +29989 , +18319 , +15435 , +-23821 , +10475 , +-281 , +25999 , +28471 , +-25641 , +11245 , +3967 , +-27469 , +-13423 , +6139 , +-16911 , +-22925 , +19801 , +-6655 , +-23789 , +3589 , +-22117 , +-9995 , +-14787 , +-6617 , +-19437 , +-7983 , +-15537 , +26637 , +14423 , +-23029 , +-17791 , +25359 , +-11525 , +-13431 , +-30525 , +-18723 , +20255 , +-24805 , +-8049 , +18505 , +24719 , +-3975 , +23365 , +26729 , +4693 , +18097 , +6913 , +9825 , +-15917 , +11297 , +5363 , +-31857 , +-417 , +-14087 , +-25543 , +585 , +9557 , +-31709 , +17717 , +-30957 , +4785 , +-7477 , +-18077 , +1113 , +-16855 , +24139 , +-27719 , +-5979 , +7361 , +26793 , +-8845 , +-14507 , +7915 , +22413 , +17269 , +13273 , +8977 , +28089 , +-25567 , +18277 , +-19265 , +-17661 , +-10839 , +-14035 , +-4053 , +2763 , +-6927 , +28955 , +25171 , +-26381 , +-13091 , +15625 , +-16995 , +-15017 , +22061 , +20595 , +15069 , +32201 , +-28707 , +22199 , +-255 , +-27011 , +-20501 , +-8245 , +23831 , +-14059 , +27841 , +-20623 , +19703 , +-28155 , +26369 , +30447 , +-4535 , +-23401 , +-17433 , +-3759 , +28713 , +11615 , +22549 , +-9711 , +13629 , +-25807 , +8951 , +-18849 , +-29623 , +9887 , +-25967 , +-5941 , +-10935 , +-12305 , +-2081 , +1927 , +27405 , +2955 , +29607 , +-4835 , +10569 , +-11005 , +-15403 , +31649 , +-6347 , +24709 , +26961 , +-30095 , +-16733 , +8909 , +-6567 , +-2455 , +30605 , +26529 , +30037 , +19609 , +-4031 , +11981 , +22579 , +1925 , +-9755 , +-30829 , +22587 , +-10543 , +-24165 , +8879 , +-29073 , +-5757 , +-8683 , +21183 , +3159 , +-19785 , +6573 , +13127 , +32101 , +8409 , +20733 , +11817 , +22723 , +-16551 , +-517 , +-26733 , +-17485 , +-17691 , +1927 , +-26493 , +-31647 , +16421 , +28049 , +8117 , +-15039 , +11501 , +2467 , +4387 , +10461 , +-29705 , +15365 , +27641 , +24125 , +-11491 , +-8885 , +-24821 , +9643 , +23567 , +19571 , +-15407 , +5661 , +3979 , +-3713 , +-2081 , +-19709 , +-17641 , +3201 , +-29477 , +-5471 , +2359 , +10567 , +18163 , +-27415 , +-27613 , +3931 , +25051 , +2769 , +2821 , +-31053 , +-27587 , +28201 , +-7767 , +-14153 , +-13893 , +-17927 , +-32063 , +-2593 , +-13475 , +13139 , +31887 , +26575 , +-29039 , +21169 , +-24539 , +14313 , +25243 , +-16955 , +-29923 , +-11671 , +-19307 , +27095 , +-27699 , +-4613 , +-24091 , +32415 , +-28669 , +-16431 , +4399 , +4499 , +28221 , +-15293 , +-30251 , +20939 , +6493 , +-3105 , +-32279 , +15443 , +-24861 , +-17153 , +23209 , +28927 , +4011 , +-26133 , +-15499 , +16335 , +4889 , +-25749 , +-17591 , +-31051 , +-23335 , +-16417 , +-5967 , +30723 , +-2793 , +28371 , +-32699 , +-7889 , +-7371 , +-3805 , +29089 , +2615 , +2821 , +15749 , +4823 , +-14985 , +-9091 , +-3667 , +623 , +-14341 , +-18957 , +-12323 , +30683 , +-7583 , +30929 , +-26371 , +-17809 , +12837 , +-28461 , +-25801 , +-2341 , +-7289 , +-6725 , +-13037 , +11039 , +-25643 , +-20603 , +-13055 , +24839 , +9291 , +-23253 , +-25217 , +-4321 , +28015 , +32207 , +30121 , +-1995 , +-32037 , +15485 , +32341 , +-7873 , +-30813 , +15967 , +-11353 , +-2587 , +21285 , +-31885 , +-23761 , +-3217 , +-14745 , +10695 , +-16771 , +-19903 , +29159 , +-27853 , +31287 , +-23091 , +-23557 , +11657 , +12725 , +27415 , +30629 , +21843 , +18197 , +7581 , +-1049 , +19209 , +-2083 , +-21795 , +2981 , +-19765 , +-8703 , +-9143 , +-4617 , +-26985 , +30095 , +20407 , +22271 , +25341 , +32439 , +5733 , +-7869 , +-10651 , +-27541 , +12905 , +-26743 , +23219 , +-12423 , +-21841 , +-22743 , +-15983 , +-12771 , +28005 , +-11543 , +-9441 , +-2023 , +-18169 , +-16815 , +-8411 , +22353 , +17347 , +-22135 , +8409 , +-8985 , +-9859 , +-19031 , +1291 , +27331 , +-22463 , +18843 , +-19741 , +31169 , +-3263 , +-20631 , +30489 , +-19405 , +25671 , +-32229 , +20905 , +23821 , +-19535 , +1037 , +-23025 , +-9365 , +-8475 , +-2613 , +-31237 , +17077 , +-23217 , +1375 , +-29039 , +12087 , +-31789 , +28213 , +-12267 , +-12495 , +-6455 , +-7829 , +-18387 , +28789 , +-13711 , +20141 , +30357 , +27261 , +-32271 , +-23159 , +-11177 , +-17147 , +-9017 , +10061 , +-2681 , +15133 , +25285 , +24919 , +-655 , +-25907 , +-8573 , +26615 , +3419 , +16671 , +-4507 , +27069 , +-27203 , +8895 , +-11265 , +13145 , +29167 , +-28395 , +14879 , +-17429 , +-14741 , +19413 , +10555 , +20961 , +6527 , +-20707 , +-7577 , +-32685 , +-24945 , +22031 , +-10021 , +17615 , +11195 , +2525 , +-32295 , +-21063 , +-11737 , +21877 , +13107 , +31009 , +-28497 , +-27263 , +-14279 , +-13281 , +6425 , +-8937 , +17719 , +-25947 , +8151 , +-31041 , +12655 , +-10281 , +11829 , +-13807 , +-8309 , +1771 , +28437 , +11729 , +23701 , +17527 , +28205 , +11905 , +15731 , +24657 , +16821 , +-3715 , +737 , +8159 , +5793 , +23697 , +19425 , +16631 , +-26781 , +27153 , +-28999 , +21811 , +9495 , +4465 , +-28565 , +3529 , +23359 , +-25505 , +21161 , +4067 , +-10757 , +-16293 , +-20397 , +-5767 , +-19769 , +21703 , +24677 , +16039 , +-15451 , +-627 , +-26753 , +-14461 , +-4891 , +-24019 , +-55 , +13947 , +-23215 , +2387 , +16255 , +-24791 , +4331 , +28923 , +-14889 , +30121 , +-20955 , +31483 , +5771 , +-16779 , +3477 , +17961 , +19389 , +-31043 , +-29649 , +3041 , +1667 , +15675 , +-30719 , +6705 , +-31283 , +911 , +1893 , +-32157 , +7149 , +-28651 , +19133 , +21529 , +-17789 , +-18371 , +16549 , +-17173 , +-13061 , +15205 , +21687 , +-7057 , +6533 , +-6609 , +-28491 , +-8985 , +-8059 , +-22951 , +-30647 , +-32697 , +-3429 , +-22763 , +1857 , +-28203 , +-2807 , +3553 , +-1481 , +-963 , +-29509 , +28641 , +-30241 , +-31695 , +-22609 , +-26697 , +-8021 , +-14473 , +-25345 , +-19497 , +-27889 , +-8057 , +23369 , +-31393 , +8755 , +-31071 , +23981 , +-22663 , +-28365 , +613 , +-24757 , +-30939 , +-31539 , +-12563 , +17713 , +9113 , +-6755 , +16229 , +14041 , +12059 , +31961 , +285 , +23837 , +-22449 , +-31871 , +-11735 , +-16457 , +-31719 , +-25569 , +17523 , +14637 , +32758 , +12027 , +-6825 , +-1707 , +-19259 , +-24365 , +-24133 , +-29115 , +565 , +23571 , +-16733 , +-21555 , +-5495 , +9359 , +15947 , +26993 , +-2307 , +-21065 , +2499 , +11999 , +15513 , +-5293 , +-18687 , +1765 , +6533 , +5307 , +17273 , +-28433 , +-15635 , +-11637 , +-25793 , +18685 , +-17589 , +-28963 , +17551 , +24081 , +-14009 , +24581 , +2033 , +-12485 , +-30957 , +-31291 , +-4909 , +1787 , +8759 , +-3841 , +25233 , +-21173 , +25583 , +-12803 , +-4577 , +-6131 , +-26101 , +-30439 , +13335 , +-15869 , +30775 , +17917 , +-18605 , +-4019 , +-30241 , +16733 , +9225 , +-20899 , +19589 , +5413 , +32601 , +-6035 , +-30057 , +22331 , +4979 , +27773 , +3779 , +-30027 , +28707 , +22981 , +18395 , +-9329 , +22509 , +-31057 , +-2785 , +-25375 , +-3673 , +5459 , +29473 , +409 , +5775 , +-4505 , +-16111 , +1977 , +5351 , +23231 , +-10591 , +3589 , +-16639 , +29503 , +25175 , +3135 , +7915 , +-24743 , +-30623 , +-6685 , +-22927 , +-9731 , +-17931 , +-12457 , +13251 , +-2791 , +15657 , +15789 , +-15729 , +-27763 , +32063 , +22735 , +8587 , +4511 , +-17525 , +26693 , +-31589 , +5119 , +14535 , +12893 , +19299 , +-2765 , +28389 , +-14859 , +-11173 , +-13933 , +29549 , +-22881 , +-19343 , +12741 , +6743 , +-11411 , +11031 , +-19541 , +-3749 , +-24549 , +10983 , +-11799 , +-21555 , +-10039 , +-12631 , +-26157 , +5883 , +10299 , +-27905 , +-8219 , +12025 , +14475 , +11371 , +-7489 , +27655 , +-31141 , +20983 , +-29541 , +-8105 , +24217 , +21571 , +2889 , +15995 , +-333 , +-9957 , +-2401 , +24617 , +20299 , +-27749 , +-17033 , +26017 , +12653 , +20667 , +-28377 , +1403 , +-10667 , +12395 , +-30861 , +9477 , +6549 , +25389 , +11025 , +20765 , +21979 , +17453 , +12947 , +12159 , +-21471 , +10197 , +-27161 , +-32597 , +13671 , +-18711 , +-17839 , +-13777 , +5869 , +11803 , +-4903 , +16777 , +-3863 , +23081 , +-7343 , +3961 , +-24639 , +-22417 , +31677 , +-31777 , +-14401 , +9219 , +29277 , +21005 , +9035 , +-18613 , +17941 , +28067 , +2981 , +-30189 , +877 , +-24605 , +13343 , +-11219 , +11783 , +28047 , +4041 , +-897 , +-32615 , +25913 , +-9797 , +23713 , +-17565 , +28195 , +-18501 , +-32525 , +14631 , +12179 , +-4219 , +15669 , +-32095 , +10413 , +-22921 , +28067 , +-26495 , +-28475 , +9165 , +-17277 , +11233 , +-26561 , +3419 , +17485 , +32061 , +8673 , +-26939 , +26157 , +6635 , +-29519 , +6963 , +-21197 , +12307 , +-22967 , +6541 , +5595 , +-20179 , +23979 , +2865 , +-28121 , +-1301 , +20129 , +3371 , +8765 , +16065 , +-17005 , +-11283 , +22905 , +24527 , +7129 , +-7797 , +-22517 , +32613 , +-21347 , +30315 , +16647 , +-4111 , +25129 , +13445 , +-2809 , +-14719 , +-29755 , +-4845 , +-9927 , +-15695 , +27663 , +-28461 , +4859 , +-15065 , +20429 , +-17735 , +-24585 , +-29555 , +15695 , +-13023 , +29365 , +-3829 , +-11199 , +6547 , +-17481 , +22069 , +30205 , +2807 , +-18673 , +-29809 , +20081 , +-13755 , +-10633 , +-11395 , +21867 , +21965 , +-24597 , +18619 , +-8071 , +-32037 , +6331 , +23133 , +-8901 , +-7681 , +5423 , +-27073 , +19517 , +-573 , +17553 , +31229 , +5201 , +-5161 , +20941 , +-32143 , +-14747 , +-22313 , +-3957 , +12711 , +27101 , +13951 , +11967 , +17235 , +-5785 , +-2981 , +-7479 , +-14387 , +14423 , +11021 , +-29179 , +23945 , +-14211 , +16887 , +-29715 , +16653 , +26749 , +-26753 , +-6743 , +27495 , +8871 , +29631 , +-24025 , +30507 , +13397 , +3517 , +-5447 , +-31773 , +-19021 , +6955 , +-9177 , +-12271 , +2605 , +-7533 , +23631 , +16797 , +-20173 , +18459 , +-13265 , +-27437 , +-28771 , +-13131 , +-4469 , +27099 , +18817 , +-2085 , +-9473 , +-5969 , +-15227 , +9157 , +21911 , +13199 , +27327 , +9247 , +25319 , +24581 , +17929 , +-16571 , +28835 , +11857 , +-29735 , +29179 , +-5445 , +14181 , +-20069 , +30115 , +-27415 , +-13985 , +-24189 , +-32523 , +-32553 , +10879 , +10223 , +15159 , +-1879 , +31393 , +12597 , +-9737 , +13857 , +-5327 , +-4093 , +-7873 , +15915 , +-31321 , +-31693 , +32337 , +-18173 , +14463 , +14881 , +29917 , +7873 , +25257 , +-1401 , +5819 , +4213 , +-27245 , +725 , +15905 , +13763 , +-14967 , +32263 , +-15781 , +30451 , +-24383 , +5625 , +24323 , +-5231 , +17609 , +5449 , +-31303 , +21887 , +2693 , +12713 , +4701 , +-32619 , +-24417 , +-26957 , +22981 , +24235 , +11397 , +18763 , +-29963 , +14399 , +-22049 , +31599 , +-9509 , +-13945 , +16521 , +-6001 , +29309 , +-23545 , +-14071 , +-11665 , +-26693 , +-21327 , +14215 , +-18835 , +2181 , +3697 , +9543 , +21357 , +145 , +31055 , +12443 , +6179 , +-7793 , +1539 , +27493 , +-28177 , +-2581 , +-27123 , +-28663 , +-3017 , +17919 , +2125 , +13535 , +20541 , +-2105 , +6687 , +-18887 , +-27273 , +12579 , +19691 , +3795 , +-3477 , +-2939 , +-22461 , +22213 , +-20995 , +-4047 , +-20357 , +8455 , +4433 , +-18449 , +27069 , +28515 , +31267 , +24903 , +-16475 , +29933 , +11671 , +-1483 , +10585 , +-8455 , +917 , +-11671 , +-7651 , +-9061 , +-32093 , +3827 , +-29073 , +-25451 , +-31683 , +-32633 , +-23141 , +31187 , +-1621 , +13355 , +30679 , +-29081 , +-5803 , +-18827 , +10461 , +-6917 , +15527 , +-32443 , +30457 , +205 , +30299 , +-29709 , +-22865 , +-3037 , +-5797 , +30227 , +27331 , +-17079 , +-30699 , +17571 , +8415 , +8707 , +-7087 , +10703 , +15013 , +-15991 , +30609 , +20247 , +11079 , +-27397 , +-13345 , +6683 , +-20065 , +-27041 , +-25303 , +-7229 , +-10551 , +-14829 , +-29925 , +-26111 , +31031 , +18119 , +29559 , +17411 , +-17333 , +-14343 , +3307 , +-7951 , +13429 , +-2331 , +-9625 , +-26337 , +10177 , +11783 , +3833 , +-17977 , +-17677 , +6917 , +31267 , +29509 , +25377 , +-27845 , +5303 , +-11835 , +29643 , +20123 , +17957 , +-6009 , +8557 , +-16067 , +31327 , +-22637 , +-12127 , +-13501 , +8235 , +21481 , +2479 , +30559 , +-22537 , +6723 , +-5979 , +32703 , +-25797 , +-19381 , +25077 , +-11883 , +25671 , +-26545 , +13193 , +-14595 , +-8541 , +-21635 , +-9639 , +20353 , +18403 , +-4455 , +25737 , +-16625 , +-22275 , +7479 , +30715 , +31595 , +20517 , +-18581 , +25965 , +16433 , +29477 , +28179 , +-24569 , +12611 , +-28113 , +26999 , +29055 , +29639 , +-19647 , +25239 , +17065 , +-31329 , +3567 , +1749 , +20629 , +2911 , +16323 , +-25037 , +9757 , +19649 , +-24301 , +27657 , +-19957 , +6055 , +-11681 , +-15811 , +20899 , +16783 , +6681 , +16123 , +-22587 , +32641 , +-21741 , +11505 , +-26493 , +-13159 , +27461 , +32255 , +16691 , +5869 , +21289 , +22645 , +17679 , +27413 , +-611 , +-20789 , +17991 , +22041 , +-32721 , +-9769 , +-7265 , +-18969 , +9209 , +-21117 , +4735 , +-20393 , +5881 , +13 , +11667 , +2197 , +-21009 , +7091 , +-28705 , +-29917 , +20137 , +4851 , +5205 , +-14259 , +-25883 , +28487 , +20979 , +-10975 , +-3163 , +12883 , +-5035 , +19175 , +-4859 , +-24161 , +-12079 , +15645 , +-13671 , +-11049 , +-18419 , +24037 , +-25535 , +32377 , +-15337 , +2315 , +4991 , +-6379 , +-27907 , +28013 , +-22187 , +-27905 , +-25113 , +-29435 , +11413 , +-30069 , +15533 , +19281 , +20673 , +-17211 , +9711 , +16977 , +21857 , +29857 , +-15443 , +-27131 , +24021 , +22721 , +13411 , +32347 , +-28237 , +-4701 , +20633 , +-16469 , +-25187 , +4697 , +-29439 , +-13901 , +-21345 , +28613 , +4367 , +-19189 , +29177 , +21075 , +-9715 , +-10471 , +23431 , +-6617 , +17081 , +9365 , +-31605 , +19939 , +-14507 , +6767 , +-32497 , +-29745 , +24135 , +25951 , +-26181 , +-19037 , +15659 , +-63 , +-28631 , +27307 , +25203 , +-471 , +-31809 , +1171 , +-17553 , +-15805 , +3849 , +31375 , +16123 , +-13221 , +13711 , +28445 , +-11133 , +-7343 , +14895 , +24633 , +24491 , +-13561 , +-2575 , +29205 , +-14249 , +16747 , +-14495 , +-13233 , +22353 , +31203 , +-19861 , +433 , +16219 , +-12477 , +-14161 , +31329 , +-21815 , +-7091 , +29269 , +22679 , +9617 , +-5463 , +-20627 , +-12319 , +-17425 , +18513 , +-5691 , +26317 , +-23175 , +21399 , +28477 , +6959 , +-11087 , +23963 , +11425 , +-7991 , +17187 , +-15563 , +-16123 , +29327 , +20989 , +15491 , +-32365 , +-4513 , +5923 , +8909 , +-31247 , +13107 , +-4405 , +-6901 , +21773 , +31191 , +10645 , +25299 , +19067 , +8235 , +12061 , +26073 , +19531 , +7893 , +-4835 , +-3615 , +-5791 , +8569 , +-5379 , +-23747 , +30799 , +-18065 , +-9749 , +-11331 , +20137 , +-23807 , +-1671 , +-16849 , +-22301 , +-27363 , +10417 , +22609 , +23203 , +-27759 , +-1109 , +6991 , +-8293 , +15297 , +-21077 , +29363 , +-6941 , +991 , +18357 , +2533 , +-7471 , +-7005 , +-11359 , +-20451 , +-8373 , +25991 , +-3139 , +2783 , +-3927 , +-31879 , +-18723 , +-12559 , +-26367 , +27155 , +247 , +-18473 , +-28149 , +30553 , +24629 , +-2625 , +8561 , +-32277 , +-22887 , +18955 , +-29267 , +-9787 , +8199 , +-30151 , +-13481 , +-1173 , +-17179 , +-16029 , +-1273 , +28073 , +2355 , +-22471 , +-12373 , +-15925 , +18467 , +-21647 , +30045 , +11861 , +-29653 , +14533 , +4283 , +-17355 , +9125 , +-30103 , +28347 , +32387 , +12769 , +-22265 , +-753 , +-13133 , +-13117 , +-9169 , +-23821 , +-2219 , +30419 , +16723 , +-28029 , +28479 , +19935 , +-16057 , +-21859 , +-10413 , +-14843 , +7207 , +-32461 , +-1869 , +18783 , +17377 , +-20961 , +4467 , +-27643 , +-17115 , +28293 , +30167 , +9397 , +16089 , +14499 , +-1013 , +-26139 , +18457 , +22571 , +10841 , +21339 , +-6999 , +11035 , +-24609 , +12357 , +22517 , +5913 , +-20533 , +-15919 , +-6531 , +-12477 , +-22763 , +-13753 , +30167 , +655 , +-19279 , +24735 , +15139 , +2717 , +-5051 , +-28519 , +12291 , +-19693 , +23403 , +-12457 , +-31213 , +-20109 , +-22173 , +7279 , +-12061 , +-6795 , +14665 , +10127 , +7789 , +-1575 , +18131 , +21129 , +-18933 , +32203 , +-2687 , +-6163 , +-18953 , +3755 , +-13729 , +24103 , +18233 , +-21901 , +-30671 , +-235 , +-24541 , +-15737 , +-6601 , +-13287 , +-29361 , +10003 , +6495 , +-2375 , +-18167 , +25309 , +-22535 , +-14927 , +26967 , +-24675 , +32760 , +16017 , +-5017 , +-21797 , +-14431 , +27599 , +27527 , +13125 , +24783 , +-26783 , +23717 , +-10623 , +-26979 , +20949 , +19003 , +6027 , +-4697 , +-25105 , +10707 , +-10867 , +-28993 , +6323 , +-1801 , +23349 , +17443 , +30219 , +-10069 , +-24947 , +-32451 , +10715 , +24421 , +-13997 , +27857 , +-27247 , +22921 , +-24109 , +26043 , +-28087 , +-20391 , +-5061 , +-1497 , +-20641 , +-20617 , +23671 , +-14013 , +-635 , +24785 , +12427 , +18307 , +-16801 , +14115 , +2911 , +-8889 , +-12135 , +-16659 , +10281 , +22569 , +12415 , +-29209 , +32309 , +9889 , +25883 , +10493 , +-4793 , +22089 , +12733 , +6339 , +2669 , +-13167 , +25639 , +-7055 , +-23207 , +-19977 , +5909 , +11099 , +-25025 , +-30783 , +16737 , +-27417 , +9247 , +-8143 , +-5741 , +-12541 , +-3153 , +12611 , +-10759 , +21283 , +-20833 , +-17953 , +4421 , +10673 , +-7289 , +-3693 , +7073 , +25615 , +-8663 , +31435 , +8261 , +-31485 , +-10149 , +3983 , +1943 , +-28737 , +-23725 , +24751 , +-16971 , +-2747 , +24965 , +24451 , +-31329 , +6255 , +26875 , +-5595 , +-20291 , +-24477 , +-6615 , +21025 , +-27899 , +20869 , +22345 , +-19019 , +2955 , +-23307 , +30767 , +-23677 , +31135 , +-10615 , +-18775 , +203 , +30301 , +-24259 , +-14515 , +-21975 , +10953 , +25137 , +29399 , +-14657 , +-26001 , +-9695 , +13309 , +17917 , +-17815 , +17753 , +-16947 , +32717 , +-21237 , +561 , +639 , +28499 , +-1557 , +32259 , +-11565 , +-32740 , +6787 , +-24411 , +-21023 , +26081 , +13125 , +28253 , +-9863 , +-2375 , +20783 , +6237 , +23285 , +32717 , +1009 , +13241 , +-5997 , +-29543 , +-21391 , +20193 , +27475 , +-26467 , +22517 , +-25195 , +10563 , +-23653 , +32687 , +-3233 , +12385 , +8263 , +-31523 , +-15215 , +6639 , +13699 , +16733 , +26033 , +-16821 , +-13793 , +-31551 , +16763 , +-3771 , +21251 , +-10767 , +15701 , +-8449 , +-9237 , +20795 , +1095 , +8507 , +17067 , +-1299 , +28789 , +9531 , +7381 , +24175 , +-13551 , +-1519 , +16381 , +-11815 , +6877 , +8065 , +25709 , +13835 , +14619 , +27983 , +-9635 , +-29881 , +-6903 , +-21733 , +-13909 , +12869 , +-29229 , +-3905 , +-3047 , +12751 , +2837 , +26397 , +29173 , +22743 , +-1077 , +-32387 , +24933 , +-27375 , +971 , +18275 , +19 , +22023 , +-24641 , +-14619 , +10083 , +21687 , +-14437 , +18315 , +-23755 , +-26717 , +6037 , +21919 , +23317 , +2929 , +-18533 , +15877 , +-14857 , +-30721 , +-18091 , +4761 , +-24469 , +-26119 , +9357 , +-12543 , +23897 , +-5897 , +27189 , +-18935 , +18745 , +-28145 , +30167 , +32633 , +-10297 , +20207 , +5519 , +28271 , +5181 , +-16005 , +-3959 , +-6093 , +-21487 , +-17449 , +-15381 , +-23663 , +-29665 , +-8947 , +7771 , +2231 , +-30607 , +23073 , +20975 , +-9857 , +1643 , +19361 , +-11093 , +-17833 , +8585 , +22473 , +-14477 , +-19569 , +17045 , +4373 , +-9339 , +17201 , +-24223 , +-7849 , +20081 , +5983 , +-22275 , +-9901 , +13461 , +2343 , +-18833 , +15573 , +-13809 , +28631 , +10729 , +9035 , +565 , +25825 , +17033 , +1241 , +3477 , +4133 , +-17273 , +-29705 , +3683 , +-27437 , +-22031 , +-31873 , +-19593 , +-18753 , +32233 , +14677 , +-3641 , +-12231 , +-15789 , +11629 , +-27563 , +12389 , +28689 , +25969 , +-9551 , +31253 , +25023 , +15567 , +-8721 , +6943 , +-10011 , +2393 , +-3045 , +29747 , +-29265 , +27737 , +-13773 , +-14023 , +16687 , +-22487 , +27809 , +-28125 , +18949 , +-11703 , +-2509 , +17481 , +5031 , +14847 , +7565 , +11329 , +2059 , +-9373 , +22827 , +28723 , +-9237 , +14083 , +-11827 , +-11599 , +-19085 , +26101 , +-9345 , +19991 , +9599 , +-15767 , +11517 , +8285 , +27477 , +-815 , +-29253 , +24425 , +-1325 , +-2713 , +12887 , +-21001 , +-17099 , +12885 , +32657 , +10463 , +1085 , +19009 , +27591 , +9465 , +-22533 , +7015 , +14049 , +-10891 , +18169 , +10043 , +-20263 , +29353 , +8441 , +-5515 , +-14677 , +-1677 , +-31701 , +-30295 , +-29239 , +6927 , +17641 , +-21905 , +-31205 , +30057 , +14309 , +-12059 , +19061 , +-21507 , +9965 , +6613 , +26503 , +31021 , +14363 , +-22197 , +-28317 , +20497 , +16271 , +-23125 , +-4247 , +-22819 , +-3157 , +5961 , +-18747 , +-32339 , +31681 , +-31617 , +-13467 , +21985 , +20825 , +-23989 , +-24719 , +-8711 , +-5157 , +-3739 , +2375 , +-2585 , +11989 , +-24625 , +18409 , +6121 , +4769 , +-30985 , +-4605 , +-28187 , +32691 , +-25007 , +-5293 , +2873 , +-11205 , +-17825 , +27827 , +29467 , +3185 , +-4005 , +-13695 , +-4243 , +1341 , +30277 , +15773 , +-7151 , +-11913 , +22399 , +-27929 , +-21813 , +-26211 , +-10783 , +-27349 , +5011 , +-497 , +-12459 , +26023 , +17769 , +29631 , +-19 , +31475 , +6073 , +-27789 , +30845 , +32391 , +31779 , +-11409 , +8625 , +-16209 , +4321 , +-23619 , +-23645 , +31483 , +29593 , +25819 , +-30217 , +-26301 , +27827 , +12533 , +-909 , +16663 , +-29899 , +-4195 , +-7147 , +-12357 , +18717 , +-21497 , +-11095 , +-31077 , +20525 , +-23111 , +-27929 , +-25015 , +-2219 , +5067 , +-28923 , +-2065 , +-28549 , +4759 , +11217 , +9547 , +-24869 , +-19459 , +10831 , +-219 , +-29215 , +-22005 , +4547 , +-32187 , +119 , +-31677 , +-5031 , +10995 , +20713 , +-2229 , +12335 , +-31005 , +22837 , +10027 , +11513 , +13751 , +7141 , +27645 , +-10733 , +4085 , +25965 , +-30421 , +16661 , +-21381 , +-525 , +-12505 , +-20237 , +-901 , +-31811 , +8097 , +-31343 , +13807 , +-31243 , +19517 , +-6181 , +-15209 , +-2035 , +-14381 , +-30113 , +31081 , +-27245 , +8729 , +22113 , +-20333 , +20107 , +17901 , +23927 , +-23061 , +21571 , +-3589 , +-6239 , +-20505 , +-8531 , +25605 , +-2595 , +-26341 , +16957 , +-20849 , +4417 , +-12245 , +28211 , +-20197 , +-16745 , +-22967 , +27525 , +10979 , +28269 , +21541 , +-3035 , +-8175 , +16821 , +-659 , +-17691 , +18805 , +31449 , +27327 , +31695 , +-14663 , +-3245 , +-19931 , +27891 , +-13531 , +28099 , +-31219 , +10185 , +-825 , +7311 , +25277 , +-23803 , +-16837 , +13553 , +21069 , +21745 , +6873 , +-6509 , +32545 , +5697 , +-29333 , +-28757 , +19681 , +-8849 , +-26253 , +-31345 , +12267 , +-5487 , +-20785 , +18891 , +-1197 , +31665 , +20483 , +-31813 , +-8871 , +-24153 , +-3353 , +-26967 , +-15781 , +19823 , +-27677 , +11355 , +22099 , +11775 , +29599 , +-29651 , +23761 , +30373 , +-2229 , +5811 , +-26773 , +9689 , +9031 , +-16955 , +-3397 , +-7013 , +-22429 , +-12007 , +12757 , +5701 , +-1127 , +-2207 , +-12221 , +12513 , +28731 , +-21535 , +21107 , +-2545 , +-13129 , +6273 , +-17219 , +-23475 , +20933 , +-23441 , +26829 , +-18217 , +-21463 , +3883 , +-3673 , +23039 , +-14111 , +28713 , +28179 , +511 , +997 , +-3351 , +-20063 , +-32165 , +-22187 , +-22653 , +-13285 , +-2129 , +16705 , +16335 , +32635 , +-14831 , +-25137 , +4339 , +-7067 , +13789 , +9215 , +12669 , +-2779 , +-14057 , +18145 , +3069 , +14107 , +-7871 , +-21173 , +15895 , +15037 , +-12881 , +-1523 , +7205 , +10763 , +-9633 , +-20811 , +-20153 , +7559 , +30555 , +8375 , +-27649 , +28589 , +4227 , +-1737 , +26437 , +-14611 , +-21011 , +14127 , +24611 , +3615 , +-2883 , +11315 , +-22579 , +4995 , +-24453 , +27559 , +-3533 , +1581 , +3307 , +9331 , +8481 , +-30203 , +-6045 , +-8899 , +19413 , +-26045 , +-22867 , +2855 , +785 , +-3495 , +-13235 , +31483 , +10685 , +13689 , +-21905 , +1259 , +14833 , +-29561 , +-23767 , +-32053 , +20129 , +-3439 , +-29085 , +-32575 , +-13921 , +-6203 , +22313 , +-24445 , +-4541 , +-15631 , +27013 , +10001 , +18555 , +22895 , +2255 , +-21277 , +14443 , +13737 , +9877 , +26797 , +31351 , +5129 , +-11805 , +3215 , +1003 , +-8591 , +-10463 , +-21041 , +3077 , +-8643 , +-22415 , +-20715 , +-26213 , +23723 , +9851 , +9497 , +27939 , +27103 , +25041 , +-21015 , +-24741 , +601 , +-4931 , +12949 , +-13227 , +19179 , +-10845 , +-29843 , +8981 , +6961 , +-7733 , +32437 , +12711 , +-29049 , +8395 , +4579 , +-14919 , +-11385 , +28749 , +-23215 , +-17999 , +-3589 , +2169 , +-11653 , +1601 , +-16549 , +-22343 , +-31571 , +-3957 , +-17987 , +32035 , +17481 , +-21331 , +341 , +21575 , +11377 , +19677 , +10345 , +15755 , +-31925 , +21765 , +4551 , +10237 , +27823 , +-13613 , +-27199 , +-26189 , +-20633 , +6747 , +9639 , +6049 , +1251 , +-22749 , +9651 , +21997 , +-5267 , +25029 , +13715 , +-14133 , +29419 , +14855 , +8017 , +-21041 , +-1009 , +-15001 , +-23339 , +9681 , +25107 , +-3515 , +-7207 , +30521 , +-30995 , +8041 , +-30627 , +4313 , +-17907 , +28715 , +-31317 , +25935 , +-3699 , +-19205 , +-29247 , +14029 , +19953 , +-16245 , +-171 , +27521 , +-8101 , +-32425 , +-32189 , +609 , +11075 , +-18491 , +2699 , +16519 , +21935 , +-24387 , +31177 , +-20725 , +-30485 , +27835 , +-26839 , +349 , +28869 , +-9357 , +-27165 , +31763 , +22077 , +-11299 , +-7631 , +-2995 , +-13117 , +20687 , +27849 , +-127 , +27119 , +31259 , +11473 , +27619 , +32695 , +16933 , +4187 , +-26327 , +20775 , +24567 , +4955 , +-13833 , +-18025 , +-551 , +-19169 , +1445 , +-16789 , +-2959 , +-31669 , +-23897 , +833 , +-5549 , +-1719 , +4441 , +-26449 , +12313 , +22341 , +-165 , +7547 , +-20221 , +-13397 , +27503 , +-21939 , +-12285 , +-31723 , +-15933 , +32754 , +-30367 , +-3383 , +-26409 , +-4091 , +-20277 , +-1617 , +9937 , +30777 , +-23569 , +13259 , +1873 , +-30719 , +18839 , +5423 , +27081 , +-5933 , +-19145 , +6525 , +16475 , +16597 , +18193 , +-18217 , +-30931 , +-22495 , +-24377 , +23385 , +15427 , +-14217 , +18033 , +789 , +8145 , +32629 , +17467 , +-7039 , +-10983 , +31565 , +-20365 , +-23173 , +31687 , +-13821 , +25135 , +31417 , +22971 , +-11489 , +-19365 , +-9275 , +-21137 , +-19481 , +-21167 , +1393 , +16585 , +30237 , +25333 , +727 , +-11151 , +6441 , +-3251 , +29893 , +-1105 , +-6687 , +-5737 , +-12355 , +-32581 , +1207 , +26591 , +18543 , +-5729 , +-12687 , +-4835 , +9899 , +13701 , +-12443 , +4041 , +-18725 , +27285 , +-2767 , +1261 , +-28165 , +3149 , +-8463 , +19407 , +29719 , +4691 , +-14345 , +22003 , +22835 , +30679 , +1283 , +-31803 , +6361 , +-1181 , +-29701 , +19877 , +14335 , +10037 , +32293 , +-3709 , +10629 , +14873 , +11487 , +31995 , +-19151 , +2239 , +-28465 , +-29719 , +-17121 , +28559 , +-21589 , +-27775 , +6597 , +27919 , +-13215 , +4579 , +-15271 , +31913 , +11731 , +31293 , +2015 , +18959 , +-6117 , +13661 , +-3957 , +21777 , +-21455 , +-28985 , +-20021 , +-25105 , +16945 , +-6573 , +15027 , +-3529 , +16903 , +-451 , +-20227 , +-3551 , +-333 , +-16955 , +2681 , +26203 , +7163 , +16449 , +32015 , +-407 , +-14685 , +-30533 , +-723 , +3963 , +1827 , +-19967 , +-32057 , +27593 , +9957 , +-3257 , +19655 , +-5531 , +-24585 , +20787 , +-9457 , +-18539 , +-28857 , +21377 , +-10519 , +1451 , +8537 , +-26863 , +-24067 , +13919 , +-3713 , +-27511 , +-15403 , +5285 , +-11373 , +29539 , +-4661 , +14087 , +43 , +16777 , +-12927 , +8827 , +6997 , +26481 , +26077 , +17847 , +3535 , +-20303 , +9857 , +25875 , +10429 , +-16107 , +31167 , +-28967 , +-29733 , +20027 , +277 , +12321 , +17991 , +-2647 , +14371 , +25127 , +10661 , +1893 , +-18905 , +2081 , +-14367 , +7441 , +-14871 , +-10851 , +-27801 , +-10885 , +-29629 , +-10923 , +-26149 , +-29507 , +29969 , +-30587 , +-11957 , +26829 , +7845 , +14023 , +28655 , +-28001 , +31687 , +-31125 , +18013 , +-3149 , +25641 , +-2741 , +-27585 , +20531 , +19297 , +18983 , +20369 , +5517 , +22107 , +-27011 , +22101 , +-19071 , +-30889 , +-7975 , +-32055 , +-6717 , +14437 , +4027 , +6691 , +-25581 , +-25519 , +11493 , +-29241 , +7881 , +32293 , +-26315 , +1793 , +511 , +-2279 , +18685 , +-19141 , +26903 , +21269 , +-24357 , +22195 , +25825 , +-9309 , +2835 , +-3143 , +-14805 , +-16031 , +-8857 , +17505 , +15583 , +-9207 , +-22677 , +-18241 , +7057 , +30935 , +-32417 , +-25699 , +-26717 , +-4207 , +29577 , +18355 , +-8745 , +13807 , +-29173 , +-6303 , +-11417 , +10661 , +-14021 , +-18715 , +-9319 , +-14135 , +18045 , +16655 , +31201 , +4315 , +2457 , +-29049 , +10357 , +-17363 , +-15725 , +-16527 , +15195 , +-27157 , +-16381 , +1977 , +10259 , +-25463 , +-24083 , +-31303 , +2465 , +-21827 , +-6883 , +-5247 , +-18137 , +-8457 , +-8457 , +29313 , +21253 , +31067 , +16855 , +4555 , +-32665 , +26677 , +-15899 , +28359 , +23909 , +15095 , +-3479 , +-32657 , +21397 , +-19541 , +-3153 , +23803 , +-16089 , +-20753 , +2385 , +10791 , +-15237 , +-26005 , +-20199 , +-22551 , +1079 , +12743 , +21077 , +19871 , +-13337 , +-17879 , +7597 , +29133 , +21771 , +29737 , +13699 , +29791 , +-27469 , +31817 , +-18753 , +25419 , +26013 , +-11797 , +-17869 , +4575 , +26305 , +-17201 , +-6549 , +6761 , +26227 , +18693 , +-22011 , +-15749 , +-19977 , +4459 , +-18801 , +14747 , +8603 , +4255 , +-11299 , +10877 , +14665 , +-20361 , +-23589 , +5819 , +13735 , +-12287 , +28395 , +29967 , +23981 , +-2061 , +-28481 , +2569 , +28855 , +30115 , +-25177 , +29511 , +-30427 , +-27515 , +-10123 , +23855 , +19309 , +-20963 , +4303 , +23331 , +-17991 , +18557 , +-32253 , +-9665 , +-31751 , +-1227 , +-13719 , +9867 , +11387 , +21201 , +-27855 , +-1355 , +-9973 , +27349 , +195 , +-28085 , +10371 , +30245 , +-31853 , +-18831 , +-6939 , +-4591 , +8565 , +-17129 , +-5647 , +-24641 , +-12415 , +-3397 , +6215 , +20517 , +-2977 , +26257 , +-21265 , +11917 , +-21725 , +-28345 , +-10879 , +-12937 , +-8539 , +-12741 , +-10065 , +-9689 , +-10913 , +7983 , +-21657 , +19089 , +17849 , +12931 , +19047 , +14799 , +-29975 , +9203 , +-20395 , +11045 , +4687 , +-4159 , +-16297 , +-5269 , +-26305 , +4221 , +-721 , +-14063 , +21349 , +16179 , +25803 , +23179 , +-28257 , +-12767 , +18533 , +-29865 , +325 , +-27141 , +30995 , +10089 , +7189 , +-4713 , +-24343 , +-25307 , +-8067 , +-23511 , +8327 , +11745 , +27253 , +30209 , +18745 , +17615 , +-31519 , +-3147 , +19335 , +11389 , +-13477 , +21479 , +-19881 , +-9523 , +29843 , +10105 , +-15747 , +2923 , +23845 , +26685 , +-26925 , +24773 , +27383 , +-9669 , +20697 , +-15483 , +-7933 , +14173 , +13763 , +-18299 , +-17475 , +7597 , +4117 , +-6839 , +-21019 , +14343 , +-21057 , +31485 , +-10787 , +-26273 , +-11601 , +-16415 , +-15481 , +-15769 , +30703 , +28491 , +-6507 , +18899 , +-20685 , +10267 , +-663 , +-24819 , +767 , +-24143 , +-25493 , +-8339 , +-21711 , +-8339 , +26073 , +13811 , +28195 , +6813 , +2605 , +-17029 , +-31169 , +-25861 , +-22295 , +23931 , +25625 , +13729 , +-22027 , +-26317 , +-23295 , +-21879 , +-22669 , +-13971 , +5669 , +-26501 , +-32740 , +-18253 , +7199 , +16265 , +10777 , +6655 , +22291 , +-13813 , +24145 , +-11777 , +-9399 , +21521 , +-19383 , +-30009 , +-10693 , +26975 , +18043 , +-30201 , +-1993 , +12771 , +30513 , +16839 , +31349 , +1195 , +-4651 , +-27745 , +6571 , +-26267 , +25807 , +15979 , +-8919 , +-28597 , +24541 , +28295 , +623 , +-30553 , +25317 , +-6013 , +-6845 , +32195 , +-16039 , +-14751 , +15441 , +-23967 , +-25089 , +16201 , +-32199 , +29371 , +13143 , +29119 , +-7379 , +13555 , +-915 , +-22433 , +-30971 , +-24565 , +-10703 , +4373 , +-28705 , +-7835 , +-20147 , +24271 , +-23251 , +-18257 , +-4991 , +19903 , +25429 , +-7579 , +-4225 , +-32245 , +-30785 , +-30521 , +7731 , +-18171 , +12667 , +-3251 , +-17235 , +-15125 , +3663 , +11425 , +-9359 , +19221 , +-13233 , +-10469 , +-7091 , +-17231 , +-22535 , +-6223 , +-8267 , +-32255 , +28365 , +32631 , +2713 , +-12279 , +-12703 , +-25709 , +-11075 , +8397 , +18431 , +-11341 , +-8301 , +-14845 , +-24393 , +-8439 , +5519 , +-29095 , +9719 , +6083 , +29189 , +-2789 , +-24917 , +-19199 , +-28295 , +-11147 , +16589 , +-3253 , +-23933 , +4655 , +-31873 , +-7283 , +-12523 , +16089 , +9635 , +6287 , +-18841 , +-24693 , +16627 , +-5399 , +3903 , +-26081 , +-15969 , +-29825 , +2771 , +-1055 , +6745 , +-25479 , +-28643 , +4813 , +-29453 , +-30537 , +-6221 , +4425 , +-8321 , +20937 , +-4063 , +-19373 , +-10791 , +3185 , +29371 , +-23481 , +18377 , +-15475 , +-20225 , +-30713 , +11153 , +-1639 , +-15773 , +17091 , +27925 , +-32607 , +-9547 , +21541 , +-5787 , +-8003 , +4335 , +-11505 , +26325 , +1287 , +-16755 , +-1325 , +-7775 , +26389 , +3947 , +-15643 , +1275 , +28907 , +-9707 , +31007 , +10403 , +19839 , +22695 , +-10647 , +-21755 , +-8285 , +-9695 , +-31233 , +-55 , +6023 , +1089 , +-26847 , +19191 , +24233 , +-16941 , +-11953 , +-8065 , +21081 , +22937 , +25345 , +-32675 , +-31583 , +6545 , +-7463 , +-22735 , +31693 , +-23845 , +7009 , +-13491 , +-22439 , +31239 , +-26297 , +-8613 , +-30363 , +8185 , +29701 , +-5275 , +-18497 , +-6353 , +18735 , +10619 , +3913 , +6573 , +-7657 , +23239 , +-20747 , +-30905 , +31759 , +-12259 , +1861 , +5245 , +11045 , +-5855 , +-20677 , +25045 , +20303 , +26833 , +14291 , +9137 , +-27603 , +30375 , +-18947 , +17065 , +29499 , +-23507 , +15123 , +23645 , +-20339 , +-12521 , +-3119 , +-17193 , +-13817 , +14293 , +9677 , +26715 , +-12015 , +-23371 , +-15503 , +19905 , +-22829 , +-5775 , +-12687 , +14671 , +4843 , +-21681 , +16577 , +-24563 , +-21339 , +-17999 , +-19435 , +-9311 , +3765 , +-11465 , +32717 , +-4441 , +19819 , +12111 , +-31367 , +27015 , +10095 , +-23475 , +25545 , +-30775 , +-5895 , +-15863 , +18439 , +7673 , +31109 , +-18189 , +5647 , +28657 , +-29683 , +26027 , +7883 , +-30789 , +27077 , +22809 , +7461 , +9445 , +20301 , +13571 , +-20095 , +-9127 , +-11155 , +13615 , +5047 , +-32587 , +22089 , +15597 , +13191 , +27427 , +-9189 , +16695 , +-107 , +-17227 , +28275 , +26439 , +2787 , +12343 , +22749 , +-20559 , +18623 , +-27513 , +20011 , +-31239 , +5959 , +-30859 , +-6367 , +3245 , +20567 , +-30447 , +29621 , +32247 , +-26359 , +-119 , +-26941 , +30911 , +-22615 , +17279 , +-23485 , +-28105 , +-18389 , +19685 , +14851 , +1027 , +-6359 , +6219 , +2789 , +-12611 , +-21677 , +23749 , +21645 , +10525 , +9585 , +-21965 , +-2147 , +-27763 , +32465 , +-30679 , +-21903 , +26685 , +3655 , +-21187 , +15951 , +16315 , +31645 , +-6431 , +28455 , +533 , +-26219 , +-13895 , +13769 , +-927 , +11863 , +-15749 , +5269 , +-11551 , +25201 , +-24773 , +22209 , +-22629 , +3655 , +10579 , +-17917 , +19817 , +-25069 , +-6235 , +31443 , +-8297 , +-15269 , +-24181 , +15137 , +-27145 , +-19741 , +-17891 , +-17527 , +11649 , +4653 , +-1007 , +-8437 , +-17055 , +28523 , +-4591 , +-3765 , +20629 , +22779 , +18323 , +-22719 , +7171 , +-7843 , +-25033 , +-11659 , +-22253 , +-16211 , +-7279 , +16047 , +-13117 , +-13159 , +-13425 , +-19905 , +-15547 , +-299 , +-19639 , +-30555 , +18445 , +-15843 , +8287 , +-8237 , +633 , +-16983 , +28873 , +-12323 , +7893 , +-10469 , +-11467 , +-23237 , +27655 , +-23801 , +8161 , +-27271 , +-10855 , +-1055 , +-22037 , +-6543 , +-28075 , +-2183 , +-24273 , +3 , +-8355 , +-3345 , +7325 , +24655 , +-24633 , +-4817 , +25875 , +-5525 , +-18257 , +-6169 , +-26447 , +-30819 , +-32305 , +-30977 , +16057 , +-27889 , +8865 , +-22893 , +-7207 , +2057 , +13287 , +8041 , +22291 , +-5461 , +32211 , +29163 , +-24823 , +-7387 , +10895 , +-28777 , +16349 , +-31891 , +17767 , +31495 , +-5759 , +12149 , +-8625 , +-2473 , +9881 , +8165 , +-22005 , +-2003 , +9159 , +30553 , +30393 , +7969 , +10129 , +-7667 , +19699 , +-9273 , +-11605 , +-18399 , +-27291 , +-30443 , +-16167 , +6727 , +6877 , +11113 , +-23997 , +259 , +16627 , +3577 , +25931 , +-18851 , +18191 , +-2351 , +-30483 , +-19939 , +-4083 , +10561 , +12171 , +20609 , +26193 , +-4385 , +2639 , +23413 , +-19357 , +-8449 , +-19199 , +-8629 , +-22019 , +-25437 , +-26021 , +15351 , +-31313 , +17143 , +-1821 , +-65 , +15085 , +14413 , +8261 , +24697 , +-21329 , +-24689 , +32553 , +-4539 , +-19323 , +8251 , +-26227 , +25275 , +20015 , +15577 , +32665 , +2991 , +-16459 , +-4111 , +-8967 , +-14239 , +5631 , +-14455 , +14523 , +4409 , +-12819 , +14105 , +32153 , +505 , +501 , +22529 , +25313 , +-8575 , +-3025 , +-12153 , +-12861 , +2553 , +19701 , +6473 , +-15575 , +-5997 , +-6661 , +-9927 , +533 , +-23617 , +31207 , +-28655 , +-8589 , +18657 , +4193 , +18255 , +29813 , +14991 , +32443 , +-32337 , +-13205 , +27715 , +-11019 , +8473 , +1813 , +24729 , +3945 , +31523 , +10883 , +25085 , +-6957 , +21511 , +-22679 , +-4623 , +2293 , +-2025 , +12023 , +-13641 , +-17503 , +11191 , +-3791 , +-16491 , +-925 , +10711 , +-9271 , +26501 , +14987 , +26859 , +-3725 , +5741 , +-9783 , +24159 , +20931 , +18653 , +25413 , +-1903 , +2431 , +-27069 , +-17605 , +1869 , +17273 , +-25181 , +13069 , +19131 , +-3605 , +-6959 , +-12323 , +24807 , +-30649 , +8739 , +-25179 , +18855 , +-8811 , +-5967 , +26325 , +-18145 , +-12469 , +12043 , +-22433 , +-3915 , +-17243 , +-22421 , +6743 , +22155 , +29301 , +26741 , +-23285 , +-31883 , +-24697 , +-13973 , +6809 , +-147 , +26997 , +3301 , +-29433 , +25751 , +14839 , +-20727 , +-26403 , +8363 , +23749 , +-7099 , +31801 , +-29447 , +-31249 , +14721 , +21101 , +-27435 , +-10069 , +-12573 , +19469 , +-23907 , +-31049 , +9467 , +15255 , +2851 , +-24529 , +-2947 , +20089 , +-20559 , +11231 , +2177 , +19125 , +3701 , +8227 , +-27855 , +10487 , +31111 , +21563 , +-2805 , +25383 , +-21421 , +549 , +28301 , +-12403 , +30619 , +-3857 , +-19337 , +24665 , +-17429 , +-8299 , +-8577 , +-24633 , +27283 , +18523 , +-22391 , +16567 , +-15081 , +5279 , +32355 , +-25667 , +-27849 , +22835 , +18931 , +28861 , +-30891 , +-19657 , +31737 , +-15097 , +-30339 , +23915 , +18245 , +13803 , +8399 , +-27117 , +-31125 , +-26673 , +-19583 , +27971 , +17409 , +14793 , +-10927 , +-27717 , +23885 , +-23107 , +23685 , +16963 , +14219 , +13545 , +30039 , +-11911 , +-105 , +20743 , +27639 , +6709 , +27697 , +-17949 , +25853 , +13917 , +31403 , +-22675 , +-17303 , +-17867 , +7719 , +8279 , +17167 , +-445 , +22865 , +23855 , +4759 , +-28257 , +-17777 , +-28689 , +12279 , +27855 , +-19777 , +-6115 , +-19355 , +-741 , +-16789 , +11101 , +-19245 , +-24469 , +-9847 , +-17781 , +-24607 , +-22121 , +13739 , +23381 , +19037 , +-31417 , +-21833 , +-25003 , +25145 , +5961 , +-9693 , +14749 , +-32768 , +-6045 , +31917 , +12255 , +-28977 , +15537 , +-11631 , +7163 , +-15667 , +-21889 , +-20927 , +31001 , +-10717 , +18839 , +4509 , +16193 , +-15239 , +4899 , +-10837 , +-21387 , +-17181 , +-30203 , +21715 , +-28091 , +-32155 , +17319 , +-28787 , +-17 , +-3359 , +26967 , +-15449 , +-24339 , +-4969 , +-13789 , +-4623 , +-22513 , +18969 , +-27351 , +11897 , +-24805 , +11457 , +21625 , +-30905 , +-3361 , +19887 , +16483 , +-4721 , +-27707 , +-29381 , +-31915 , +9579 , +-32011 , +30959 , +-31181 , +24599 , +-23581 , +3 , +-8917 , +5279 , +-21907 , +3661 , +-4849 , +2851 , +32115 , +17857 , +-7885 , +4747 , +-6675 , +-29083 , +2487 , +22709 , +-7551 , +-19257 , +14961 , +-8895 , +30625 , +-12551 , +16947 , +-2381 , +21533 , +-24567 , +4783 , +25147 , +8765 , +-19979 , +-20273 , +-10777 , +-8867 , +24105 , +-31359 , +-29349 , +1023 , +31855 , +10017 , +-14071 , +-411 , +-3985 , +13123 , +-18453 , +-28245 , +-12895 , +20749 , +-15433 , +-18595 , +18891 , +-3051 , +-18533 , +-20083 , +13807 , +-2125 , +-18059 , +-19597 , +13779 , +-21791 , +-29305 , +-2435 , +28133 , +25735 , +7347 , +-27675 , +-8249 , +14429 , +-19151 , +-1325 , +11575 , +-7105 , +-569 , +23279 , +-1647 , +-29181 , +4993 , +-9353 , +-24127 , +27095 , +-13843 , +-2339 , +-32065 , +-7917 , +-31287 , +-11563 , +-31099 , +20887 , +-21943 , +-4867 , +12167 , +-613 , +4293 , +-3101 , +-9553 , +17423 , +-32019 , +9385 , +28621 , +-18067 , +-20589 , +1307 , +14485 , +14613 , +-28211 , +-11709 , +5653 , +-30941 , +-15681 , +31619 , +-13135 , +-25913 , +-21049 , +-32207 , +-24943 , +10527 , +7995 , +-27223 , +-4953 , +-30579 , +9631 , +17383 , +5657 , +-31603 , +-17057 , +-26977 , +20035 , +14869 , +16133 , +-2853 , +-24277 , +-27551 , +2031 , +8453 , +-8585 , +-32171 , +21901 , +-21617 , +-23825 , +31827 , +-13549 , +-19969 , +14435 , +29327 , +-26187 , +17035 , +-31691 , +-17433 , +-15523 , +15415 , +-17337 , +7493 , +28645 , +865 , +6773 , +-32407 , +-13111 , +-7451 , +18063 , +31049 , +28519 , +29097 , +-20785 , +7401 , +-20043 , +-11069 , +-31023 , +25777 , +371 , +13829 , +-23285 , +-27837 , +-26131 , +18201 , +-2361 , +-14373 , +-24535 , +10523 , +-15721 , +20763 , +6563 , +-28495 , +29011 , +-10129 , +-19061 , +32413 , +5517 , +-549 , +-8079 , +25825 , +27013 , +31835 , +6791 , +4165 , +31659 , +28341 , +2135 , +11909 , +-15985 , +-13099 , +13813 , +-14125 , +-13989 , +-18011 , +1215 , +-29951 , +16843 , +-18083 , +-17519 , +12047 , +-28503 , +26731 , +12667 , +-6843 , +-20545 , +-13637 , +2817 , +4299 , +-30639 , +-13419 , +455 , +12483 , +-31467 , +1531 , +11987 , +19935 , +-27985 , +28021 , +-12479 , +-15239 , +18083 , +-4235 , +31613 , +-15573 , +25805 , +-23259 , +18679 , +21993 , +31587 , +-21049 , +-12707 , +21913 , +-12965 , +18823 , +-32169 , +5157 , +17271 , +19673 , +27833 , +7449 , +-25681 , +-31671 , +-24005 , +-7491 , +-28881 , +8409 , +-32067 , +-20571 , +9931 , +-15143 , +12777 , +-19249 , +-2563 , +18749 , +17023 , +-29637 , +29781 , +-11403 , +3077 , +2049 , +11643 , +21447 , +-23809 , +-23065 , +-99 , +1057 , +-5211 , +32639 , +8301 , +-135 , +-16609 , +3769 , +8347 , +-30301 , +-25793 , +-24835 , +-23101 , +8101 , +-11087 , +-15673 , +4847 , +-5999 , +-15431 , +-23111 , +-10357 , +-24863 , +-7319 , +-27851 , +-25377 , +-30137 , +23387 , +-30345 , +2565 , +-24053 , +-5147 , +12587 , +22109 , +28645 , +-19243 , +4485 , +25233 , +-13493 , +-12631 , +22745 , +-28671 , +1367 , +11843 , +4533 , +3775 , +-25329 , +-13533 , +7289 , +-9719 , +5199 , +-32731 , +-15001 , +6977 , +-753 , +-24917 , +20297 , +11101 , +-10425 , +-21401 , +19069 , +-5391 , +-10425 , +17279 , +4245 , +-22385 , +11397 , +-29353 , +15461 , +19923 , +-7937 , +20417 , +30379 , +2771 , +-5871 , +1203 , +28437 , +14357 , +31689 , +-2941 , +23013 , +-22773 , +19391 , +-13669 , +-13817 , +6411 , +-18315 , +-25417 , +16293 , +5311 , +-28631 , +-9063 , +17219 , +-11731 , +31273 , +11325 , +25939 , +29983 , +-24143 , +-29539 , +-1453 , +20003 , +-18105 , +-8485 , +-5283 , +23041 , +-4475 , +12291 , +29515 , +-18507 , +-6529 , +-14529 , +8257 , +19687 , +23187 , +28301 , +-3637 , +20699 , +28103 , +-4613 , +-5253 , +-2571 , +21147 , +12641 , +-3081 , +-5715 , +22881 , +4241 , +22677 , +-7425 , +-229 , +12821 , +-12935 , +-2193 , +5327 , +101 , +16929 , +-4485 , +-26785 , +10657 , +25225 , +19343 , +20451 , +-24121 , +7353 , +18055 , +-11139 , +-24729 , +737 , +27297 , +435 , +-29975 , +-7687 , +5103 , +-31669 , +22577 , +25801 , +-31907 , +-29793 , +17129 , +7053 , +-16097 , +15471 , +25905 , +-16373 , +1451 , +-949 , +8401 , +3623 , +-7889 , +11603 , +-11521 , +2301 , +-9837 , +29351 , +-13685 , +1149 , +-18719 , +5417 , +-1891 , +19323 , +13899 , +-24343 , +21485 , +-17839 , +23451 , +21229 , +26231 , +9707 , +6447 , +28563 , +-585 , +-6293 , +-31123 , +6497 , +30045 , +25657 , +23747 , +-16281 , +-27507 , +-5475 , +-3311 , +-15857 , +30091 , +-17703 , +28591 , +20855 , +28669 , +-27457 , +26851 , +16459 , +32159 , +-24119 , +-21555 , +-16359 , +4475 , +5041 , +25069 , +-19409 , +-9819 , +20365 , +19731 , +-21523 , +25449 , +-675 , +20957 , +7583 , +6669 , +-11215 , +2215 , +-1577 , +-26615 , +31413 , +-29427 , +12099 , +-15691 , +21581 , +17367 , +14087 , +-22389 , +-27985 , +-12421 , +16785 , +-26151 , +25593 , +-5357 , +7155 , +29699 , +-27317 , +25553 , +26049 , +-26841 , +-32291 , +-5895 , +12125 , +32367 , +-22891 , +-5541 , +-26409 , +29361 , +-19931 , +15691 , +-30393 , +20405 , +27037 , +-16363 , +5791 , +-11283 , +14727 , +-19465 , +-18941 , +29349 , +-13445 , +1435 , +-13143 , +8383 , +30781 , +15375 , +-18137 , +5105 , +-4529 , +17975 , +-4781 , +-5005 , +-6899 , +-8497 , +12435 , +16697 , +13379 , +-16679 , +-23875 , +1717 , +10309 , +22173 , +-26773 , +-14333 , +27271 , +17689 , +-7725 , +10917 , +22199 , +17921 , +-22241 , +-19269 , +5203 , +-12749 , +23879 , +19905 , +19651 , +3761 , +-7065 , +29113 , +-10773 , +-27117 , +-26475 , +-28941 , +10571 , +18569 , +11839 , +-31175 , +-107 , +-6585 , +6911 , +-14963 , +-5953 , +-10101 , +-27407 , +-2719 , +14497 , +32007 , +-15729 , +-20405 , +8207 , +-22555 , +13065 , +15679 , +19051 , +-27597 , +14105 , +-15285 , +-10307 , +-1303 , +12895 , +-2615 , +2897 , +-30637 , +32055 , +-25573 , +-31031 , +26643 , +-4335 , +4061 , +27067 , +8085 , +-22195 , +1705 , +11715 , +28423 , +14985 , +-19391 , +-26851 , +28883 , +-19837 , +-18865 , +-28225 , +-20591 , +-16783 , +-15711 , +21229 , +27275 , +26063 , +-28719 , +-26791 , +-16219 , +32705 , +-3949 , +21935 , +-1563 , +30953 , +-26279 , +-16969 , +-22689 , +-32325 , +-30571 , +-9241 , +-11855 , +-17065 , +-30347 , +-18045 , +-4607 , +-30495 , +-14065 , +20779 , +-11927 , +29535 , +-2525 , +12277 , +23287 , +-505 , +-7347 , +6927 , +3113 , +-17127 , +9155 , +-28215 , +18391 , +-3777 , +-25979 , +-31689 , +28603 , +12635 , +29725 , +5699 , +-26533 , +15593 , +-32045 , +-14519 , +2959 , +-28979 , +30053 , +-10705 , +20841 , +-14163 , +-8129 , +14841 , +-2117 , +-28971 , +-28363 , +1763 , +-12279 , +-4997 , +9655 , +-26627 , +-9217 , +-10073 , +23437 , +21819 , +-24463 , +-3195 , +5135 , +28183 , +5829 , +5183 , +-32295 , +24733 , +-2821 , +-16561 , +30981 , +-23281 , +-31717 , +7519 , +23015 , +22005 , +-17107 , +-30053 , +-29119 , +11447 , +-6983 , +22161 , +4341 , +-21833 , +23731 , +-13187 , +-1971 , +-14617 , +-6915 , +7209 , +31395 , +-2079 , +605 , +15175 , +26017 , +-3455 , +-15373 , +22337 , +32764 , +-2825 , +-24789 , +-4199 , +-12901 , +-2453 , +-26041 , +12477 , +11885 , +-27897 , +32063 , +-22693 , +20353 , +3223 , +16721 , +-7099 , +26325 , +14243 , +30437 , +10429 , +-20095 , +-21249 , +-9709 , +-19633 , +11379 , +6123 , +-12911 , +-15055 , +32685 , +-1885 , +-3021 , +-2027 , +-27661 , +-19583 , +-24353 , +-901 , +-13561 , +17547 , +21761 , +22679 , +21093 , +28563 , +1425 , +16287 , +-30605 , +-15159 , +24183 , +6563 , +-5053 , +20951 , +-17261 , +-11285 , +-28737 , +22389 , +5681 , +-28215 , +-31633 , +-9337 , +-30213 , +-10761 , +15009 , +28591 , +-13191 , +-17305 , +19249 , +1129 , +11267 , +23715 , +-23625 , +8353 , +25405 , +-4963 , +-29377 , +21963 , +-3569 , +-17389 , +-31355 , +18555 , +13591 , +-24489 , +25263 , +9601 , +-3157 , +-5961 , +-18053 , +-9353 , +-25531 , +29513 , +-507 , +-3865 , +-6263 , +-1465 , +22255 , +20181 , +6577 , +12779 , +-25817 , +-10271 , +-25975 , +-12609 , +29211 , +9181 , +7143 , +3199 , +3691 , +14303 , +1705 , +-12951 , +31529 , +-27937 , +26147 , +-5611 , +-3189 , +26321 , +2587 , +-13871 , +15653 , +22071 , +5955 , +-9349 , +31909 , +-29127 , +-16851 , +1745 , +32003 , +-27325 , +20685 , +-20915 , +-7867 , +-23015 , +28255 , +22915 , +14501 , +-4243 , +32243 , +-24593 , +27995 , +-28675 , +12115 , +27729 , +-31283 , +-22747 , +14987 , +12425 , +12355 , +20987 , +5589 , +8683 , +4395 , +-4893 , +-9705 , +5649 , +19391 , +29103 , +3543 , +6211 , +15697 , +18987 , +-28995 , +20289 , +-7433 , +28479 , +20857 , +19357 , +-7741 , +11393 , +12365 , +22169 , +-22147 , +24661 , +32762 , +-9859 , +-22047 , +-28549 , +-23745 , +30055 , +4685 , +-21719 , +21705 , +-7247 , +5117 , +-13139 , +-8269 , +14013 , +7877 , +-7817 , +-393 , +-27823 , +4169 , +31931 , +-26513 , +-1419 , +-12879 , +-17533 , +5571 , +15293 , +16357 , +-29619 , +-32283 , +-22479 , +10819 , +13081 , +13455 , +-25191 , +-11305 , +25105 , +14637 , +-32163 , +-1261 , +-16751 , +11493 , +18901 , +3083 , +10949 , +-13563 , +6443 , +4389 , +-21565 , +-8195 , +9385 , +22105 , +17445 , +-9513 , +23959 , +14049 , +-25833 , +-19153 , +2195 , +3451 , +-14341 , +27055 , +-11165 , +-16615 , +6777 , +-20223 , +-30375 , +-10213 , +14105 , +15687 , +-5861 , +-19447 , +24671 , +11293 , +-10487 , +-22585 , +17497 , +-6399 , +24847 , +-22961 , +9923 , +10839 , +-16133 , +22513 , +-16489 , +27361 , +-4517 , +7161 , +-22997 , +20909 , +-10033 , +-4873 , +-24383 , +-31081 , +-7453 , +-24715 , +-20315 , +-32447 , +-19095 , +29475 , +12995 , +-26497 , +849 , +28317 , +-4925 , +2141 , +22011 , +32159 , +24217 , +9875 , +31255 , +-13899 , +12453 , +32121 , +-23305 , +17793 , +5699 , +1407 , +-5521 , +-7579 , +-787 , +13613 , +6945 , +26823 , +-8247 , +8081 , +-23713 , +27329 , +6089 , +22845 , +-32131 , +18777 , +-32707 , +-9279 , +-3409 , +-15297 , +18415 , +-24681 , +-9895 , +3075 , +-14665 , +9389 , +-26639 , +-12603 , +12185 , +-24241 , +21839 , +14201 , +30553 , +4001 , +22403 , +22425 , +18319 , +-11875 , +-31175 , +-3235 , +22089 , +9097 , +-21115 , +10353 , +-1509 , +5353 , +-26303 , +-6351 , +21177 , +16381 , +-24347 , +-18847 , +-8685 , +-2117 , +-17449 , +-18077 , +-11805 , +9279 , +-18863 , +28911 , +4563 , +-31285 , +-24913 , +11851 , +6663 , +-27083 , +839 , +-20219 , +-18881 , +-16145 , +6343 , +-6361 , +-8851 , +10609 , +24841 , +18419 , +-30265 , +-18383 , +-5527 , +-16103 , +-6809 , +-23001 , +-16477 , +-20879 , +-23715 , +16057 , +-24541 , +-11215 , +-8885 , +4153 , +-26395 , +-11355 , +19837 , +17115 , +-27191 , +4711 , +15741 , +20015 , +-31893 , +-29673 , +303 , +-15083 , +6525 , +-31083 , +22117 , +28727 , +-6759 , +-24393 , +-32515 , +28423 , +-20829 , +13185 , +31603 , +-26837 , +-14183 , +32225 , +5117 , +-13695 , +28907 , +-27939 , +20001 , +31627 , +-13475 , +-32171 , +-7987 , +6259 , +-26803 , +-19399 , +10479 , +-27525 , +13727 , +-4545 , +26767 , +-14341 , +5895 , +-1001 , +-21917 , +-8497 , +10981 , +29229 , +8687 , +-29349 , +26271 , +-32037 , +24595 , +17405 , +-649 , +24093 , +13351 , +6401 , +24803 , +5075 , +-28269 , +-24285 , +-24215 , +28783 , +20975 , +28287 , +18413 , +-13259 , +11143 , +28171 , +16277 , +17645 , +-19315 , +-9327 , +-6121 , +23071 , +-13673 , +1061 , +-5987 , +25543 , +14029 , +-28899 , +-9459 , +-9323 , +-6541 , +-31351 , +26605 , +-3943 , +-28667 , +-12245 , +-5447 , +23943 , +7379 , +25587 , +14009 , +-1691 , +-20717 , +-11023 , +-27563 , +-1335 , +-25477 , +-30769 , +-28935 , +26003 , +13657 , +14795 , +-21665 , +-25829 , +-20433 , +5931 , +-24975 , +-31499 , +4549 , +6203 , +7325 , +21023 , +27077 , +-9025 , +-9811 , +16069 , +15309 , +-16913 , +-12003 , +24167 , +27921 , +20203 , +28413 , +-8027 , +-29077 , +953 , +-20167 , +-14233 , +-9481 , +14007 , +-9859 , +-29283 , +-15579 , +17557 , +-14451 , +-24197 , +23645 , +-2351 , +-27631 , +19747 , +-29431 , +-2903 , +-31745 , +-7445 , +19767 , +29331 , +-5021 , +-17907 , +-11349 , +-10179 , +7871 , +-4891 , +1915 , +-27397 , +-2587 , +20895 , +3623 , +-9529 , +6981 , +-23173 , +20011 , +30643 , +-25389 , +25217 , +-16863 , +-31261 , +-5297 , +14257 , +-10161 , +10759 , +-9939 , +-25659 , +2759 , +6227 , +-19997 , +29287 , +-1029 , +6129 , +449 , +15333 , +31695 , +15621 , +9809 , +-14483 , +31043 , +4371 , +16161 , +-8253 , +-11147 , +25097 , +-26835 , +-5509 , +25929 , +-4175 , +7847 , +-3671 , +3707 , +-20575 , +3417 , +4139 , +13623 , +-8259 , +17783 , +-18359 , +30001 , +-24789 , +-28935 , +-13053 , +-5825 , +17869 , +17273 , +1467 , +-8085 , +12853 , +-32129 , +-27533 , +22423 , +17953 , +-31135 , +-31101 , +3973 , +-13965 , +12703 , +-10287 , +-26751 , +-5213 , +27821 , +-20343 , +9317 , +-25665 , +27737 , +-15015 , +-29627 , +-4383 , +30875 , +21025 , +15991 , +-13023 , +19443 , +-22735 , +-28619 , +7443 , +-23753 , +-16127 , +13743 , +9663 , +5627 , +-7577 , +16297 , +24345 , +-12457 , +-22195 , +30091 , +26865 , +16203 , +-27151 , +25601 , +24697 , +23697 , +31887 , +-2033 , +19505 , +-28931 , +-9813 , +-345 , +-10651 , +-9653 , +-32583 , +24775 , +3619 , +24957 , +-25249 , +29707 , +26293 , +-9553 , +32549 , +14281 , +-21101 , +2933 , +10167 , +-10585 , +12007 , +-6737 , +5011 , +17587 , +-16267 , +23775 , +13641 , +20987 , +-5341 , +-29689 , +-25811 , +2471 , +-5403 , +17401 , +-18541 , +-19059 , +-17095 , +-26055 , +-15483 , +24147 , +-2523 , +-28599 , +13309 , +8179 , +-27743 , +27535 , +-18025 , +10987 , +-30815 , +-10849 , +-15661 , +-13885 , +12413 , +23837 , +-1855 , +17197 , +30703 , +28431 , +-20919 , +-3939 , +-12145 , +24765 , +-17967 , +24925 , +-13879 , +-24069 , +-20097 , +-7637 , +29261 , +-20463 , +501 , +16713 , +16659 , +-7927 , +-10373 , +10013 , +-17205 , +-24697 , +20935 , +-9405 , +-26151 , +12069 , +-1493 , +-12757 , +-31031 , +-28339 , +-2995 , +-16597 , +24399 , +-23927 , +-7837 , +-10471 , +-591 , +2145 , +-4629 , +-28829 , +25295 , +1971 , +481 , +-16981 , +27793 , +-9337 , +-29833 , +-25639 , +-11553 , +-23447 , +-9141 , +9399 , +-23777 , +-30651 , +-28377 , +-25341 , +-3543 , +6843 , +-975 , +-24303 , +-833 , +-23053 , +2465 , +-28965 , +28291 , +27645 , +-26875 , +-23395 , +1909 , +30887 , +-19221 , +-21527 , +22503 , +7121 , +-13529 , +-30397 , +-13581 , +-23481 , +6011 , +-30665 , +-18567 , +29469 , +32475 , +-17423 , +-20593 , +-131 , +10533 , +19545 , +-14715 , +-7411 , +-8365 , +1957 , +1355 , +-31045 , +-23503 , +4207 , +-14979 , +-30693 , +32671 , +91 , +10957 , +28477 , +-3005 , +22301 , +29441 , +-13051 , +6081 , +-29153 , +21605 , +23045 , +-14991 , +-22385 , +8911 , +11729 , +-7267 , +-26625 , +-3317 , +-22819 , +13107 , +19831 , +29913 , +6863 , +-24063 , +-12523 , +-17569 , +-6311 , +-26773 , +10775 , +-21459 , +-1131 , +13219 , +-26237 , +19625 , +29139 , +-1695 , +-18127 , +-23029 , +20991 , +-9697 , +7535 , +30679 , +5231 , +7371 , +10001 , +28885 , +-711 , +5887 , +27659 , +9859 , +-6123 , +12479 , +-29555 , +-31977 , +-25425 , +10923 , +-13165 , +-7701 , +17275 , +7871 , +18945 , +-28029 , +4887 , +13183 , +10051 , +-1543 , +-12775 , +31159 , +-32173 , +2807 , +10609 , +-4941 , +-28571 , +19513 , +-19659 , +3319 , +-18961 , +9591 , +20995 , +3441 , +-3253 , +-21785 , +-2859 , +2873 , +32201 , +-24787 , +-29861 , +18371 , +-8883 , +-7201 , +-8495 , +-8801 , +26207 , +4207 , +25427 , +-6237 , +26827 , +26539 , +-26177 , +-27983 , +-5451 , +-7241 , +6663 , +4587 , +18479 , +-28549 , +-8699 , +-4763 , +-28839 , +-4953 , +-6945 , +-23709 , +-3861 , +-30427 , +-14643 , +5137 , +7517 , +-24817 , +20871 , +-20551 , +-6539 , +-11221 , +-15093 , +-8327 , +-673 , +-6689 , +-14087 , +-24449 , +9549 , +29361 , +-19849 , +-13885 , +-19833 , +-26057 , +12915 , +-3017 , +-20991 , +-21621 , +1171 , +32135 , +30077 , +-26027 , +-18821 , +-25273 , +12315 , +29231 , +8111 , +1209 , +-4233 , +-32599 , +-24095 , +249 , +-10951 , +28093 , +-13863 , +-26691 , +5427 , +-1337 , +26811 , +-27003 , +11257 , +-24579 , +-16915 , +3165 , +8695 , +-16281 , +-13977 , +9737 , +13061 , +-21411 , +24205 , +-6967 , +-19829 , +10865 , +3979 , +-22645 , +-31731 , +-16651 , +-30425 , +-353 , +73 , +27119 , +30489 , +-15881 , +-24885 , +4999 , +-30485 , +-7717 , +15371 , +24339 , +-20667 , +-5597 , +21503 , +7291 , +10707 , +-20501 , +2357 , +4155 , +32143 , +8655 , +20591 , +18909 , +-5213 , +-19807 , +6327 , +-16151 , +-32579 , +22175 , +-14351 , +28775 , +21735 , +-29901 , +-7167 , +-22323 , +5087 , +24865 , +16473 , +-12167 , +26097 , +325 , +-30699 , +19125 , +20811 , +-23605 , +31883 , +-17125 , +11225 , +29153 , +-16269 , +27551 , +13727 , +18937 , +-30865 , +-7427 , +29575 , +-8583 , +555 , +-22095 , +-7487 , +9973 , +-8459 , +12149 , +-25439 , +-25625 , +-18735 , +-19661 , +739 , +13545 , +-16617 , +22403 , +-29541 , +-24215 , +-26751 , +7581 , +19321 , +-19477 , +-29485 , +-303 , +-15951 , +30639 , +10209 , +-9081 , +8259 , +-5895 , +24885 , +32429 , +-31259 , +-14395 , +20765 , +22709 , +22089 , +31995 , +-19381 , +19725 , +16897 , +-30167 , +7401 , +10005 , +5845 , +31675 , +10287 , +917 , +-3943 , +-10823 , +-28543 , +24505 , +-7549 , +-3341 , +29699 , +1673 , +-20217 , +20161 , +-22611 , +-27425 , +-19409 , +12605 , +28397 , +-13349 , +31343 , +13811 , +28601 , +27111 , +17409 , +-23263 , +15137 , +-15837 , +-4421 , +5993 , +17015 , +-13729 , +27239 , +23563 , +-28459 , +-10339 , +19867 , +6563 , +8517 , +-16131 , +-23785 , +8531 , +10573 , +-24267 , +-30833 , +-4981 , +12297 , +-4457 , +-20463 , +15669 , +18893 , +8571 , +28885 , +22645 , +20527 , +-24265 , +23707 , +-11303 , +28329 , +12195 , +5243 , +27927 , +-9301 , +-29947 , +24645 , +-7095 , +5689 , +32399 , +10067 , +20631 , +32764 , +6485 , +25061 , +-6275 , +-21537 , +17349 , +-25867 , +-20869 , +14629 , +27555 , +6809 , +3923 , +-27903 , +32377 , +20681 , +-14665 , +27825 , +-5485 , +-26425 , +9615 , +21009 , +-8577 , +-4875 , +7333 , +9401 , +32499 , +-23775 , +2785 , +-8823 , +19287 , +-13971 , +-14843 , +27349 , +26803 , +15259 , +-10785 , +745 , +2857 , +2285 , +23043 , +-15569 , +-18959 , +17013 , +-28155 , +-3141 , +-30265 , +-13833 , +-32721 , +-14481 , +23023 , +14647 , +-24903 , +-3957 , +-16475 , +31189 , +8065 , +-7733 , +-7141 , +9645 , +-20919 , +5111 , +14567 , +18333 , +11615 , +10243 , +-10489 , +-27411 , +25833 , +15775 , +-17327 , +-18651 , +7313 , +22103 , +-24721 , +-16807 , +-26693 , +7465 , +-28075 , +21523 , +-5049 , +-5481 , +11063 , +-14697 , +11201 , +23879 , +27657 , +-31537 , +-10467 , +24343 , +8299 , +8853 , +-27413 , +-4429 , +-5587 , +32143 , +-24045 , +-31309 , +-19393 , +6793 , +-2803 , +29483 , +-15317 , +21325 , +-29803 , +719 , +8719 , +27891 , +-9499 , +-14213 , +-28911 , +11977 , +-9613 , +-6053 , +-15779 , +4507 , +-24293 , +-19597 , +9367 , +-24687 , +3303 , +28873 , +-15913 , +7309 , +27963 , +-21781 , +-21987 , +3831 , +-22637 , +-9707 , +30799 , +-16097 , +-12615 , +-15677 , +14249 , +21267 , +-23425 , +24775 , +24513 , +29939 , +-523 , +-18715 , +7919 , +25037 , +-32223 , +23273 , +-21679 , +13039 , +-17611 , +5697 , +-11711 , +9163 , +-3505 , +29457 , +32331 , +-8639 , +-12891 , +-29233 , +27555 , +26497 , +10571 , +859 , +-15581 , +-15009 , +8797 , +21395 , +-11333 , +-3029 , +-13119 , +-28563 , +-23949 , +17675 , +-29863 , +-20077 , +-30501 , +-17205 , +-32063 , +25715 , +-26109 , +-29881 , +7809 , +-20257 , +1527 , +13101 , +8389 , +18977 , +13241 , +31333 , +13471 , +-7023 , +-13903 , +-17695 , +31407 , +26549 , +23725 , +-21509 , +2155 , +21707 , +-687 , +15427 , +-11831 , +14835 , +23577 , +-27673 , +-2685 , +-30283 , +-17465 , +-10377 , +-7227 , +-20697 , +27233 , +-15535 , +22379 , +-18817 , +-1879 , +-18585 , +-26181 , +25127 , +-6127 , +19365 , +2195 , +1121 , +1847 , +1221 , +22319 , +-2735 , +13533 , +16799 , +-32431 , +-611 , +-16037 , +-1781 , +-5879 , +-29305 , +9887 , +24633 , +-26911 , +6269 , +20131 , +4479 , +5275 , +27959 , +8285 , +-13381 , +-9625 , +25167 , +-29881 , +25129 , +-14689 , +-20649 , +-14013 , +-2891 , +-26635 , +19053 , +3877 , +2269 , +-7625 , +8801 , +25507 , +-25859 , +30079 , +-29383 , +-11063 , +-16333 , +-20499 , +17243 , +-15367 , +-3919 , +-19997 , +16155 , +-32675 , +-28013 , +-4941 , +22739 , +-6169 , +-8903 , +997 , +-2175 , +18111 , +-21213 , +30945 , +-21029 , +11581 , +24643 , +6451 , +7143 , +29803 , +21209 , +-22725 , +-4845 , +10477 , +5317 , +-19097 , +19149 , +-27511 , +-4243 , +11241 , +-25699 , +7697 , +-11263 , +28921 , +-6467 , +14313 , +19043 , +-21633 , +-19415 , +5359 , +30841 , +6225 , +-16059 , +23555 , +-9723 , +-5645 , +25065 , +-28173 , +-16129 , +-21825 , +-6657 , +29175 , +13929 , +-26199 , +-9319 , +-4947 , +21417 , +-1675 , +-31349 , +1421 , +-21403 , +-13715 , +24193 , +18141 , +-7979 , +-6507 , +147 , +1075 , +-3937 , +-1939 , +18795 , +9061 , +26155 , +17441 , +4809 , +-23549 , +-3455 , +-17597 , +22443 , +-25263 , +-28263 , +21255 , +7651 , +-5445 , +-12483 , +5363 , +-991 , +16085 , +17493 , +-7649 , +-27487 , +-11067 , +-6963 , +24805 , +-9167 , +30795 , +13793 , +3365 , +-31279 , +7213 , +1271 , +-7443 , +27335 , +-18631 , +-18689 , +-25665 , +18237 , +-24657 , +-14269 , +-2495 , +-23721 , +7497 , +-27455 , +123 , +16579 , +27047 , +261 , +-9081 , +-6947 , +-10415 , +7037 , +-2097 , +-10431 , +22305 , +20055 , +11461 , +-4895 , +5193 , +14801 , +-14567 , +30625 , +24263 , +-12517 , +-7569 , +-3473 , +-25511 , +-15451 , +7069 , +-15917 , +30711 , +-2819 , +3167 , +-7911 , +1995 , +-10969 , +-30325 , +-11311 , +8619 , +30577 , +7125 , +-19459 , +-27119 , +21965 , +-21767 , +-19301 , +-30321 , +26287 , +-11395 , +-3903 , +-23351 , +-25767 , +-8477 , +-8391 , +21233 , +24251 , +-10651 , +17041 , +-14665 , +11469 , +-22483 , +-4677 , +-567 , +-9631 , +-10485 , +13601 , +31429 , +-23173 , +-21335 , +25661 , +-4681 , +-22991 , +26191 , +4015 , +-31991 , +-18439 , +21515 , +-25635 , +4353 , +29575 , +25209 , +-12289 , +-9285 , +20773 , +1777 , +-12859 , +10139 , +-29817 , +1597 , +17759 , +21059 , +-9433 , +3551 , +15907 , +-21993 , +-24037 , +-26699 , +19361 , +-17365 , +-24467 , +4163 , +-30923 , +20665 , +-14091 , +-18591 , +9765 , +-12763 , +20143 , +13173 , +1079 , +14953 , +-32111 , +20269 , +-1331 , +-27889 , +-26135 , +-9805 , +23669 , +-19533 , +-2767 , +8553 , +27911 , +-32019 , +-155 , +287 , +11837 , +-25135 , +15839 , +-2097 , +22729 , +14825 , +-22353 , +17099 , +-9749 , +30117 , +-7313 , +29313 , +-21107 , +-12457 , +28319 , +29097 , +27867 , +-1357 , +27003 , +30471 , +26969 , +-13131 , +-941 , +-9831 , +-21381 , +30251 , +869 , +16215 , +-19525 , +-15195 , +4659 , +7777 , +16697 , +-24089 , +26457 , +2247 , +6343 , +-30223 , +-5907 , +-17747 , +397 , +12135 , +-16053 , +25369 , +-7143 , +1679 , +-19337 , +7957 , +23801 , +-4401 , +-14861 , +8057 , +-25643 , +-19813 , +18195 , +28949 , +-6393 , +-27149 , +-6699 , +-8329 , +-25685 , +-21671 , +-11197 , +-5613 , +581 , +10057 , +-24515 , +17421 , +-12339 , +27187 , +-11303 , +-10657 , +-21683 , +-1807 , +-2501 , +-17251 , +-28681 , +7101 , +1259 , +13355 , +25535 , +23473 , +-595 , +-2575 , +-25999 , +-26955 , +-28455 , +-3435 , +15687 , +-7685 , +-27597 , +-5831 , +12037 , +-3333 , +20039 , +-12121 , +1169 , +18151 , +12857 , +-29935 , +18953 , +-16225 , +9253 , +-9141 , +-29607 , +-2767 , +-8719 , +6779 , +-167 , +-8495 , +-29527 , +-28329 , +6239 , +11845 , +15959 , +4063 , +-2725 , +-3345 , +14421 , +-26485 , +-6035 , +-11981 , +-12755 , +-21489 , +-5 , +32635 , +-12053 , +9867 , +-7345 , +-15953 , +12029 , +10053 , +-9299 , +-25821 , +-9091 , +-1307 , +25059 , +-4325 , +-25573 , +-32733 , +2159 , +18361 , +-16287 , +-243 , +6665 , +-1153 , +32161 , +-5453 , +-15163 , +26939 , +-7113 , +-31387 , +10663 , +-32119 , +7025 , +-8345 , +10427 , +23753 , +-2845 , +10287 , +16815 , +147 , +28729 , +-13801 , +24807 , +12209 , +18325 , +18585 , +-3813 , +22939 , +7271 , +22791 , +2407 , +30313 , +23747 , +11709 , +4075 , +75 , +31035 , +27615 , +-22307 , +-15481 , +-31953 , +-15469 , +18983 , +-17169 , +-13389 , +-23887 , +19319 , +-16683 , +-25893 , +-1533 , +-13601 , +5251 , +-26723 , +-29447 , +15849 , +-9157 , +-2021 , +-15395 , +1839 , +20387 , +4745 , +30869 , +-6029 , +-19763 , +26241 , +-18989 , +-22219 , +8603 , +-18731 , +-7983 , +-13867 , +-3129 , +19437 , +17797 , +-25829 , +-4267 , +-2399 , +32095 , +-28067 , +397 , +-5241 , +-22407 , +12817 , +-18833 , +3801 , +-3753 , +24291 , +9901 , +-14147 , +21275 , +31057 , +-27613 , +-1489 , +6717 , +5057 , +27863 , +10823 , +6083 , +-25319 , +-5027 , +-31713 , +-263 , +-10277 , +5095 , +-17119 , +-6739 , +30133 , +12459 , +31721 , +24287 , +-20577 , +-22299 , +22421 , +10239 , +12917 , +18245 , +1949 , +-8027 , +14339 , +-17161 , +-9169 , +-15161 , +9391 , +-28149 , +5897 , +-7823 , +-32383 , +15477 , +15559 , +-17413 , +-21817 , +-27259 , +-2359 , +-7223 , +2849 , +26073 , +-25219 , +26233 , +15141 , +16353 , +831 , +-24927 , +-8851 , +24777 , +-26699 , +21767 , +-28873 , +-12295 , +31641 , +-21421 , +-14981 , +29965 , +-25313 , +-12465 , +-4485 , +23627 , +29893 , +-9825 , +-20505 , +-7781 , +31409 , +-3347 , +-26259 , +-1537 , +-4989 , +5295 , +9173 , +21389 , +-1107 , +29273 , +21657 , +-31769 , +-943 , +-1001 , +-8715 , +-725 , +-21353 , +-3075 , +5005 , +375 , +11389 , +3533 , +-29831 , +19675 , +-16835 , +4389 , +-15389 , +-21039 , +-6377 , +30263 , +-23265 , +17461 , +2231 , +-2809 , +14397 , +-24899 , +2813 , +32539 , +27177 , +28403 , +11875 , +-25665 , +13121 , +2987 , +-24881 , +-24913 , +-1175 , +31225 , +-8471 , +-20139 , +-27997 , +13489 , +-23559 , +9863 , +-27089 , +27219 , +14905 , +4279 , +-26087 , +-5745 , +2477 , +-27989 , +-4263 , +29749 , +21381 , +-7495 , +24165 , +-20305 , +-16409 , +30847 , +-20915 , +29179 , +-11183 , +23833 , +20561 , +-29153 , +-5527 , +5593 , +2039 , +-1241 , +-16545 , +8575 , +-6229 , +27287 , +13245 , +32754 , +31179 , +7013 , +21443 , +15477 , +28237 , +6773 , +16441 , +29287 , +-23353 , +-22133 , +4047 , +-15245 , +-5353 , +1221 , +16627 , +-16823 , +18543 , +16019 , +-11229 , +6359 , +11507 , +27187 , +-22833 , +22789 , +24017 , +-13151 , +9897 , +-16153 , +-2605 , +19479 , +-2693 , +2935 , +21119 , +-10751 , +-27253 , +-5425 , +17837 , +-3213 , +-18841 , +-16159 , +25497 , +17447 , +14913 , +-30041 , +-14973 , +6125 , +-29747 , +30185 , +6337 , +-8531 , +23693 , +6507 , +21085 , +-22825 , +25523 , +-14427 , +-8411 , +25177 , +13683 , +-3071 , +-22451 , +10789 , +-13601 , +8845 , +-15237 , +14359 , +-11711 , +23095 , +11625 , +-12423 , +24553 , +-28285 , +20989 , +-13319 , +6031 , +3523 , +-9001 , +3867 , +26153 , +11473 , +-30863 , +-31687 , +-7107 , +-28349 , +20923 , +-3335 , +30913 , +10535 , +-2523 , +22591 , +21615 , +1851 , +-3513 , +-595 , +23965 , +-31071 , +-1043 , +1941 , +9365 , +-20197 , +15029 , +-20107 , +-1937 , +24513 , +7717 , +-3857 , +13415 , +3641 , +10307 , +-18629 , +23987 , +-10129 , +-31567 , +-30425 , +10721 , +-25905 , +-15299 , +-23155 , +1451 , +-21251 , +-27391 , +29251 , +13389 , +12039 , +-12557 , +26529 , +8033 , +24869 , +-21243 , +12909 , +-4297 , +-531 , +-30021 , +17499 , +937 , +3849 , +-449 , +-29957 , +25977 , +13429 , +-22791 , +-31425 , +-14305 , +-10701 , +-30545 , +28519 , +13357 , +14465 , +19221 , +-17025 , +-3551 , +-5483 , +13799 , +-25515 , +-12867 , +-30765 , +16767 , +-20239 , +18911 , +17287 , +5109 , +-12655 , +-8999 , +14105 , +17073 , +-9449 , +-12983 , +-5427 , +-20355 , +-26099 , +-14477 , +4331 , +24617 , +-27113 , +-15591 , +-5233 , +-27747 , +-7961 , +20943 , +21703 , +-28813 , +-7743 , +-4651 , +-7841 , +-9465 , +-5533 , +24945 , +5647 , +21789 , +-13683 , +-8507 , +10039 , +-2835 , +6635 , +-8153 , +15125 , +-28733 , +28827 , +26875 , +-22919 , +31501 , +17941 , +-16631 , +7179 , +25345 , +-20815 , +13397 , +17903 , +11691 , +-20581 , +6519 , +-15855 , +17029 , +24899 , +28787 , +-1845 , +3731 , +-26529 , +30741 , +-14803 , +7421 , +19811 , +-22591 , +28071 , +-25571 , +31345 , +13269 , +-12213 , +-22751 , +-22571 , +-19853 , +23937 , +11297 , +-8445 , +-1815 , +-18879 , +-14669 , +15361 , +-13951 , +31433 , +26375 , +-10897 , +27093 , +15055 , +7549 , +13043 , +-18001 , +75 , +-7493 , +2617 , +-7587 , +27801 , +-19379 , +31335 , +13959 , +-8125 , +-8783 , +32273 , +23183 , +-23249 , +-14851 , +-13383 , +19805 , +-27819 , +6633 , +-9019 , +27075 , +10241 , +-21905 , +21235 , +-1971 , +-30841 , +-10269 , +29781 , +27033 , +24947 , +-7799 , +-2619 , +-11977 , +12109 , +-3667 , +-13343 , +-18187 , +-14903 , +15933 , +14981 , +-6971 , +-20351 , +5599 , +-9543 , +7945 , +20525 , +12679 , +-12493 , +-23187 , +13153 , +8851 , +-8371 , +20039 , +-24133 , +13665 , +-20359 , +-407 , +-11875 , +-24467 , +-10693 , +-30861 , +-16277 , +22491 , +-3931 , +-31047 , +9537 , +23963 , +-28345 , +23697 , +30247 , +-6655 , +7855 , +-11221 , +30667 , +10451 , +28251 , +-27665 , +20411 , +14061 , +19765 , +-4527 , +-28391 , +-21425 , +-20853 , +11047 , +15323 , +-26945 , +-18045 , +-7803 , +9849 , +26839 , +27925 , +31251 , +-13783 , +20897 , +4741 , +29161 , +-5735 , +-12107 , +13913 , +30175 , +2599 , +-8509 , +24533 , +-4503 , +14229 , +-32067 , +16103 , +5109 , +2627 , +11103 , +-30545 , +9145 , +26605 , +-23217 , +14959 , +-13041 , +-2347 , +1461 , +31489 , +28497 , +-17525 , +24911 , +-11569 , +16425 , +-9957 , +-22515 , +-3499 , +-3467 , +-5181 , +32041 , +-16629 , +-2675 , +-2505 , +25529 , +-8475 , +-6865 , +22861 , +6097 , +31309 , +16841 , +-12743 , +27665 , +27793 , +2387 , +-9399 , +-31805 , +-25879 , +18609 , +-17639 , +-16011 , +-22047 , +15741 , +11845 , +16903 , +-13989 , +8295 , +12209 , +15439 , +-12539 , +12301 , +815 , +7463 , +22345 , +5199 , +-26937 , +-18417 , +9427 , +12845 , +-20893 , +25657 , +30331 , +2075 , +-11765 , +24109 , +-29749 , +10963 , +30369 , +17883 , +4071 , +-1347 , +22803 , +4397 , +-23787 , +-22087 , +-31723 , +19245 , +15017 , +-22151 , +-1957 , +-2155 , +-28797 , +6753 , +28495 , +-3359 , +21253 , +21203 , +12361 , +9973 , +25227 , +5909 , +28745 , +27689 , +-20123 , +-26215 , +13355 , +28393 , +8523 , +-9241 , +11621 , +29123 , +349 , +-30747 , +-30409 , +17423 , +27535 , +-9803 , +10859 , +17651 , +14505 , +-19949 , +17803 , +-13553 , +-15679 , +26913 , +-10351 , +-14201 , +11821 , +31177 , +-4309 , +925 , +28927 , +-25197 , +16493 , +-17455 , +-12041 , +28919 , +-1273 , +4977 , +4099 , +14399 , +23297 , +5553 , +-201 , +-9003 , +-5133 , +-20151 , +-20423 , +-17631 , +-2375 , +32649 , +-693 , +22753 , +4527 , +-20495 , +-24655 , +-25603 , +19301 , +-4025 , +-29515 , +-26143 , +-6179 , +-22217 , +-12001 , +-26791 , +10303 , +26465 , +-23773 , +20707 , +5391 , +-14091 , +-7451 , +9099 , +-15639 , +-14383 , +-16025 , +11841 , +2489 , +-18419 , +-14839 , +943 , +9837 , +-11491 , +-5507 , +1175 , +16183 , +-22683 , +1341 , +-1371 , +16957 , +17491 , +14985 , +3019 , +5841 , +31473 , +-21543 , +-25063 , +-26319 , +2823 , +7641 , +17423 , +22707 , +5287 , +-13093 , +18813 , +-28533 , +-22957 , +10205 , +-1835 , +21237 , +-16503 , +-22035 , +12555 , +24311 , +-24607 , +-30159 , +25569 , +-26475 , +-17759 , +31323 , +-27447 , +-25723 , +9945 , +11165 , +28727 , +24693 , +-7171 , +-11743 , +4991 , +27825 , +-13581 , +24327 , +-25305 , +-31643 , +-31817 , +-22309 , +7617 , +22361 , +22379 , +14983 , +325 , +8221 , +14063 , +211 , +-30487 , +-21047 , +-12797 , +-29097 , +28019 , +-12233 , +-1327 , +11769 , +16921 , +-24909 , +-32245 , +31709 , +-20523 , +-28359 , +22409 , +-17181 , +8509 , +-7121 , +21335 , +-21343 , +-2339 , +16019 , +-21677 , +-1583 , +-9207 , +4801 , +2371 , +10585 , +21567 , +-20069 , +-27281 , +6061 , +6389 , +-30639 , +-12875 , +-12065 , +24571 , +-32627 , +-32475 , +-2299 , +-23995 , +-1231 , +-14311 , +28473 , +-1193 , +23951 , +20679 , +-29423 , +-18171 , +-22245 , +-10141 , +29843 , +13281 , +5551 , +10413 , +-5455 , +-30715 , +9779 , +29201 , +19519 , +18035 , +12259 , +23095 , +-7317 , +-18717 , +-13313 , +-26843 , +21433 , +-15833 , +11271 , +28367 , +21617 , +7423 , +-14221 , +-3279 , +29093 , +-13463 , +25061 , +21221 , +2971 , +-27515 , +-13081 , +5701 , +19663 , +32483 , +-32731 , +-24333 , +20071 , +-4761 , +23839 , +-12289 , +9003 , +29839 , +-21661 , +3193 , +253 , +97 , +-16829 , +-21883 , +16595 , +25259 , +15639 , +-4865 , +27949 , +-7693 , +-31257 , +-31357 , +5901 , +-8003 , +8875 , +-5867 , +-22159 , +13675 , +-14079 , +20783 , +-3259 , +19093 , +-9109 , +-16041 , +-24603 , +-24613 , +-5385 , +-5821 , +22029 , +-15545 , +7307 , +15203 , +-19117 , +23325 , +3215 , +4101 , +-5599 , +22581 , +1579 , +11491 , +4137 , +-5931 , +6909 , +-30397 , +7013 , +17413 , +3153 , +-22905 , +32641 , +-6805 , +32475 , +21839 , +19941 , +20899 , +28907 , +16137 , +539 , +-1259 , +27433 , +3081 , +-19245 , +24393 , +25549 , +32295 , +-4773 , +-2869 , +-13231 , +22483 , +-13937 , +373 , +-15947 , +26541 , +-19371 , +-3759 , +-10457 , +-28517 , +25241 , +17901 , +29513 , +9833 , +20157 , +-18893 , +14307 , +30423 , +27293 , +-26943 , +27673 , +-10441 , +16375 , +8897 , +-7899 , +3713 , +14193 , +-17083 , +18839 , +29683 , +15879 , +-15591 , +31483 , +-26079 , +-32497 , +1307 , +-28125 , +-8565 , +30879 , +-31973 , +29139 , +-19007 , +-1895 , +32553 , +-27647 , +3053 , +-32746 , +-32397 , +-23159 , +-28171 , +32607 , +25755 , +-7071 , +20241 , +-13205 , +659 , +-18339 , +20189 , +-557 , +-26133 , +32345 , +-15367 , +-7097 , +-31817 , +-517 , +30493 , +-9585 , +20951 , +-32283 , +-9553 , +9209 , +-4639 , +2673 , +-25889 , +4441 , +-12187 , +-27925 , +577 , +9339 , +-5925 , +-7875 , +2779 , +-5605 , +19941 , +-10183 , +29641 , +-15767 , +20025 , +-15297 , +-19635 , +20459 , +-1555 , +-25979 , +7529 , +-15093 , +-17323 , +-23871 , +5881 , +-14333 , +7771 , +-31893 , +-21177 , +9557 , +18769 , +10355 , +27179 , +2247 , +25173 , +31861 , +-17257 , +-2855 , +22043 , +27761 , +-12871 , +12481 , +11597 , +11787 , +6799 , +-6947 , +-32413 , +16443 , +-22017 , +-25175 , +10743 , +7817 , +14193 , +27971 , +-17757 , +7869 , +10723 , +25431 , +-5805 , +28967 , +-20603 , +-27747 , +29983 , +-17593 , +-10799 , +25297 , +-23129 , +17679 , +-2531 , +21029 , +-1309 , +12435 , +20157 , +321 , +9603 , +-19381 , +8337 , +-24905 , +-8257 , +-12349 , +10533 , +32509 , +-16709 , +29397 , +-11965 , +4573 , +-27567 , +-28831 , +-6131 , +-4483 , +31089 , +3463 , +17049 , +11719 , +6393 , +6749 , +6145 , +-13463 , +21259 , +-14039 , +29189 , +17739 , +-12061 , +32531 , +-30183 , +12683 , +-24267 , +8551 , +27393 , +747 , +29953 , +32325 , +-20755 , +-19499 , +-27415 , +-6183 , +-19955 , +-28723 , +9999 , +31259 , +4517 , +-11419 , +-8859 , +763 , +-12367 , +23233 , +-23409 , +1319 , +-3347 , +5759 , +27441 , +-13003 , +-1153 , +32575 , +-26165 , +4451 , +1019 , +-16499 , +21271 , +5073 , +-6387 , +-13211 , +5335 , +-16591 , +16777 , +9251 , +-11981 , +-18937 , +-22271 , +27647 , +6285 , +-13221 , +-4387 , +-23553 , +27617 , +-7179 , +-14337 , +10617 , +20369 , +-23789 , +-20283 , +16387 , +14023 , +-607 , +26041 , +22765 , +-8373 , +2289 , +-14187 , +-11975 , +13783 , +4599 , +-30233 , +24089 , +23281 , +28153 , +28457 , +-8231 , +-8123 , +-563 , +-29363 , +-11419 , +-10627 , +-9325 , +20453 , +6715 , +-15471 , +10979 , +-23375 , +20705 , +6575 , +-31855 , +9143 , +27619 , +18049 , +-4387 , +-29725 , +-11451 , +-3307 , +-4307 , +27669 , +-19329 , +-29659 , +-30135 , +20671 , +-15629 , +-21761 , +-12789 , +19963 , +7907 , +30419 , +-14435 , +15907 , +-25875 , +-26997 , +25905 , +-29461 , +6151 , +-13527 , +14901 , +-6407 , +12265 , +-13671 , +-25069 , +-23051 , +-6637 , +29455 , +7515 , +20783 , +-26821 , +-4395 , +-19063 , +2733 , +-8369 , +-8015 , +-11465 , +16579 , +-21021 , +12465 , +-29993 , +31791 , +16689 , +-28279 , +997 , +-23887 , +16267 , +22121 , +-29019 , +-31199 , +-22699 , +-20139 , +23645 , +6149 , +-12927 , +-3585 , +20999 , +6575 , +8831 , +-8931 , +-4727 , +-24371 , +-2629 , +-19393 , +-19085 , +18573 , +-4199 , +1579 , +11059 , +26405 , +31197 , +-8263 , +-18483 , +8183 , +-12617 , +29979 , +-29931 , +-21975 , +-6613 , +-9271 , +-6815 , +-23627 , +-1515 , +-4919 , +-15415 , +-14073 , +-10089 , +-6253 , +26333 , +-5871 , +-17127 , +-4771 , +-21545 , +28139 , +-6215 , +-4865 , +-20389 , +20963 , +-21685 , +5957 , +-18261 , +-9965 , +10703 , +29635 , +-12193 , +-6269 , +30561 , +-20937 , +7581 , +19387 , +23489 , +-19369 , +24275 , +-10791 , +27191 , +15411 , +-29975 , +-27859 , +-22497 , +-13567 , +3077 , +1617 , +31185 , +21631 , +-29515 , +-19525 , +3617 , +2761 , +-12365 , +-9505 , +87 , +30379 , +-30191 , +-19523 , +26791 , +28801 , +-18437 , +2305 , +4897 , +4493 , +25583 , +-31083 , +5433 , +13767 , +22635 , +-27461 , +31147 , +-22973 , +-19409 , +6057 , +15109 , +-31749 , +-9999 , +-5221 , +17557 , +2867 , +-21355 , +30061 , +-19995 , +18249 , +-23319 , +8115 , +1197 , +-12529 , +-27183 , +7255 , +-30377 , +8613 , +-17901 , +17059 , +-24089 , +-17461 , +-4487 , +25065 , +12163 , +32199 , +-26727 , +-8051 , +-11681 , +31145 , +10761 , +-85 , +14395 , +-15821 , +-13041 , +-25823 , +12633 , +21035 , +4071 , +-16849 , +-15373 , +-23501 , +10605 , +-7025 , +-2499 , +4899 , +-17825 , +16397 , +-31025 , +-25893 , +-30187 , +-9577 , +19363 , +4517 , +13739 , +-4891 , +28563 , +29189 , +18895 , +16767 , +17991 , +19731 , +-16665 , +-927 , +-4431 , +-683 , +20431 , +-24815 , +31753 , +-19949 , +-23785 , +-24271 , +-8897 , +-5323 , +-16721 , +30113 , +15095 , +32147 , +-16853 , +21519 , +1023 , +-18473 , +17265 , +-24817 , +24645 , +-16439 , +-26121 , +16059 , +16981 , +-16331 , +1147 , +-14401 , +-12465 , +-203 , +11577 , +-14595 , +21845 , +29973 , +12451 , +2459 , +-30569 , +-1121 , +15001 , +14757 , +16053 , +-20993 , +11809 , +-22757 , +24777 , +-28397 , +20385 , +-27249 , +19413 , +7237 , +27031 , +-6597 , +22459 , +-17689 , +25547 , +30361 , +-17219 , +-8699 , +-15089 , +2943 , +-28825 , +-18753 , +6001 , +8365 , +2843 , +12575 , +-22791 , +29939 , +-7437 , +18299 , +-27941 , +-21829 , +-11961 , +17985 , +-22223 , +-10963 , +7591 , +6223 , +1333 , +18877 , +20803 , +13273 , +-6151 , +-29111 , +-11783 , +16303 , +-15465 , +-17487 , +-25673 , +2341 , +-3847 , +11501 , +-12157 , +-7587 , +2045 , +-11613 , +22255 , +295 , +21059 , +837 , +16139 , +-2469 , +20559 , +8097 , +9701 , +-10839 , +-13999 , +-7163 , +20349 , +9723 , +23895 , +-16953 , +-20677 , +12865 , +4613 , +-661 , +-26901 , +-11565 , +-11827 , +15667 , +17461 , +18245 , +21929 , +-11205 , +1169 , +14529 , +29007 , +-20979 , +10179 , +31963 , +14829 , +24257 , +30931 , +-20243 , +-159 , +-13431 , +30079 , +17899 , +-28691 , +16339 , +-963 , +5317 , +-16781 , +18143 , +-22359 , +4907 , +-23765 , +8655 , +-27005 , +16639 , +-28965 , +12877 , +-15579 , +26133 , +10383 , +12695 , +-14977 , +-18277 , +-21035 , +-29667 , +5255 , +1003 , +-12949 , +-18023 , +-27593 , +26591 , +5253 , +-5725 , +-24315 , +18615 , +26233 , +-9015 , +20951 , +-30885 , +30461 , +16947 , +10365 , +-26037 , +-16675 , +29095 , +-5969 , +-24859 , +-7375 , +-9681 , +-12933 , +-1211 , +1821 , +-717 , +-10945 , +-22373 , +-1 , +19971 , +23595 , +-16891 , +-7125 , +-12803 , +-17111 , +21477 , +-5077 , +-17125 , +12645 , +22457 , +7781 , +14103 , +-22983 , +26737 , +-17053 , +5365 , +-15957 , +21327 , +-3959 , +-5343 , +-12957 , +18743 , +-24767 , +31757 , +-16349 , +25733 , +-2367 , +30525 , +7617 , +-26765 , +-28099 , +-8979 , +-6755 , +-25891 , +-16993 , +-8677 , +18329 , +-2643 , +-13633 , +-28377 , +22417 , +-19293 , +-3809 , +21227 , +30549 , +-5451 , +-20457 , +11347 , +-20705 , +-28185 , +11167 , +5231 , +-21365 , +-7007 , +31607 , +26385 , +-24561 , +-14459 , +25835 , +26599 , +-20235 , +23503 , +30465 , +10765 , +16337 , +21025 , +309 , +-19421 , +-20617 , +5607 , +-9035 , +-18189 , +-4999 , +26917 , +-32746 , +-17289 , +27421 , +-30505 , +21895 , +-641 , +-11315 , +29123 , +-13425 , +-1089 , +5657 , +24021 , +6217 , +-3471 , +6703 , +4599 , +9997 , +8033 , +-14133 , +5219 , +-22343 , +11921 , +-24141 , +25473 , +-16803 , +-23991 , +-26447 , +-15037 , +13949 , +-28751 , +28941 , +18159 , +-11075 , +-30741 , +20349 , +1415 , +-25565 , +1447 , +-17759 , +-10605 , +-27701 , +14147 , +-15875 , +-5755 , +-479 , +32089 , +-31885 , +-1657 , +31381 , +30169 , +-14543 , +10203 , +2517 , +-5205 , +-5579 , +5807 , +27785 , +-32073 , +-12485 , +23665 , +-11133 , +30863 , +3645 , +-6221 , +24705 , +20853 , +6757 , +27509 , +23131 , +-13827 , +-26997 , +27655 , +-20541 , +-6869 , +-28633 , +1119 , +-25229 , +28409 , +-10039 , +-1047 , +1267 , +-13439 , +13849 , +17643 , +25799 , +27273 , +-24507 , +31575 , +-5337 , +-18525 , +18177 , +31777 , +-25797 , +-8513 , +-27401 , +-21219 , +-811 , +15685 , +-5687 , +3409 , +20129 , +-10319 , +17023 , +-23087 , +-19741 , +-21595 , +-30585 , +29457 , +20141 , +13955 , +-16603 , +24265 , +-11367 , +2183 , +-14477 , +25151 , +27643 , +-17315 , +-3369 , +26923 , +-32345 , +11065 , +7157 , +3331 , +22293 , +13679 , +32303 , +-16159 , +-5335 , +-2163 , +919 , +-31285 , +8035 , +-15375 , +16747 , +-16483 , +-26465 , +-18205 , +-9461 , +16975 , +21055 , +19239 , +-31885 , +12251 , +23539 , +-25315 , +21807 , +-16757 , +-17945 , +-1451 , +-18217 , +32731 , +-8327 , +20393 , +-28153 , +16329 , +-17283 , +-2095 , +-5423 , +5291 , +-11031 , +-19331 , +-10819 , +-18539 , +23315 , +11247 , +-16835 , +-17123 , +-15259 , +-15597 , +-8283 , +-14649 , +-12133 , +11283 , +6821 , +17611 , +31607 , +-32399 , +-7875 , +-8067 , +-12043 , +17827 , +28983 , +10009 , +7183 , +7973 , +5413 , +-29409 , +26599 , +-22253 , +-23601 , +25135 , +-13431 , +12355 , +-2515 , +-12965 , +30749 , +-19239 , +-29721 , +27139 , +421 , +2151 , +5701 , +-25303 , +-9681 , +24697 , +8619 , +15181 , +30607 , +13749 , +-27253 , +-26939 , +7065 , +-14473 , +17127 , +-29039 , +-18729 , +7133 , +14659 , +-19017 , +-8767 , +-11161 , +6679 , +11035 , +18551 , +-20719 , +8919 , +14799 , +-11019 , +3041 , +9561 , +23035 , +-31791 , +20237 , +9947 , +-21981 , +26477 , +30599 , +-8845 , +30991 , +-593 , +-15847 , +-15349 , +-2029 , +-5055 , +-20225 , +-809 , +-21001 , +-26813 , +20479 , +-17843 , +-15805 , +-30083 , +3325 , +26269 , +-18147 , +11557 , +-747 , +16809 , +-18525 , +-18421 , +-6601 , +-21117 , +-5959 , +-6569 , +-6857 , +-7849 , +6761 , +22721 , +2159 , +15089 , +11199 , +9029 , +-18741 , +-6481 , +25367 , +32095 , +15213 , +5623 , +17655 , +3263 , +19901 , +31797 , +879 , +-15735 , +-4605 , +19021 , +7657 , +-15617 , +28289 , +24727 , +18819 , +20427 , +265 , +-4269 , +14825 , +11433 , +-24299 , +15783 , +25257 , +30367 , +-19873 , +-12527 , +18705 , +26051 , +11261 , +-24735 , +32385 , +-3743 , +-22545 , +-21195 , +-9403 , +-12609 , +12101 , +-29973 , +4591 , +-15787 , +6825 , +11801 , +13101 , +-17541 , +-8317 , +-19059 , +14883 , +-19799 , +8583 , +23997 , +14655 , +-15821 , +-7979 , +23485 , +16277 , +29045 , +7305 , +-10555 , +-29005 , +-21867 , +-15907 , +-18409 , +14593 , +21175 , +16311 , +-30331 , +-16243 , +-845 , +-26935 , +6751 , +-12689 , +-20911 , +15907 , +8945 , +-25959 , +12291 , +-19379 , +-24963 , +7217 , +-8427 , +5347 , +5037 , +-26007 , +31337 , +-30041 , +-31863 , +-18983 , +-7755 , +-2531 , +14077 , +-32171 , +16175 , +-24419 , +8895 , +-14009 , +-27695 , +21491 , +6611 , +3203 , +7687 , +-20873 , +-31105 , +24995 , +-27921 , +2971 , +-7739 , +-16931 , +-24053 , +-9969 , +-24233 , +-13733 , +-17541 , +-20403 , +-11243 , +-9963 , +-28485 , +3263 , +9467 , +4647 , +18381 , +-2487 , +31913 , +29095 , +-9983 , +30827 , +-1721 , +-20989 , +-28895 , +15829 , +29969 , +-24875 , +8751 , +10369 , +21309 , +15417 , +25757 , +15943 , +-13435 , +-12631 , +-1279 , +-15881 , +27659 , +26453 , +5711 , +-12045 , +2531 , +14583 , +-22379 , +23879 , +-10237 , +-5841 , +3117 , +-9155 , +-9033 , +29273 , +-27271 , +-32391 , +32161 , +-21017 , +1813 , +24205 , +23085 , +7987 , +24731 , +16151 , +11401 , +5857 , +-53 , +-26285 , +-5857 , +-14675 , +-29611 , +27447 , +-11127 , +24013 , +-23041 , +23559 , +-14325 , +-14915 , +-12949 , +-1419 , +23695 , +6051 , +32583 , +28459 , +13337 , +25115 , +-1529 , +31733 , +6589 , +-10337 , +-23011 , +8009 , +12315 , +-691 , +-26441 , +-19353 , +-6573 , +-3509 , +10475 , +-6161 , +-5243 , +26523 , +3961 , +22781 , +-10049 , +24691 , +2301 , +16057 , +-13959 , +21271 , +29357 , +-5515 , +-25965 , +-15825 , +-9847 , +32323 , +1983 , +-6497 , +-3045 , +-20463 , +24459 , +-32291 , +-341 , +-3781 , +1479 , +28883 , +-3593 , +-11613 , +31883 , +5927 , +-29589 , +-691 , +11175 , +15135 , +-23077 , +-26757 , +-24929 , +27127 , +-14921 , +28213 , +28961 , +31925 , +29639 , +-17545 , +-24069 , +21893 , +15203 , +-8011 , +-31591 , +28049 , +-9945 , +-4611 , +2297 , +19283 , +-29907 , +19857 , +-28125 , +31093 , +-1079 , +27641 , +4897 , +5669 , +-16707 , +-19299 , +-21899 , +-27925 , +-10005 , +-17697 , +29721 , +-17143 , +19101 , +-6223 , +-13841 , +-22969 , +5165 , +-31827 , +-21831 , +-31145 , +-21179 , +30125 , +32663 , +11427 , +26265 , +-29209 , +-2053 , +6829 , +-20973 , +-19075 , +13343 , +-8477 , +-21089 , +-9573 , +-2557 , +-14347 , +15437 , +-3827 , +4319 , +-30545 , +-26085 , +-8357 , +-12515 , +-7079 , +-4577 , +-20391 , +-31019 , +-1155 , +-179 , +-7865 , +5309 , +20819 , +8097 , +9313 , +30121 , +8583 , +-15903 , +28673 , +13949 , +7839 , +-20017 , +-19923 , +-3413 , +12493 , +26343 , +183 , +-26333 , +19783 , +27023 , +-25137 , +-20525 , +-483 , +17113 , +-22243 , +19867 , +-19817 , +-4433 , +-10913 , +705 , +28679 , +18585 , +-1421 , +26613 , +-1241 , +27365 , +-9219 , +-29763 , +4585 , +30831 , +-903 , +-2447 , +-12841 , +-14129 , +-11053 , +31925 , +-14621 , +-4335 , +18559 , +-26511 , +3787 , +-27919 , +-20975 , +-32701 , +-25375 , +-27499 , +17497 , +-19071 , +17011 , +29371 , +27633 , +16551 , +-16489 , +27517 , +32097 , +21589 , +4231 , +20355 , +-27725 , +-28987 , +-29827 , +32693 , +9089 , +-28217 , +-6397 , +3459 , +-18787 , +10545 , +-16169 , +30093 , +-23519 , +-18467 , +-17103 , +-4891 , +7429 , +8991 , +-10577 , +-18239 , +25913 , +-2879 , +-2403 , +-30539 , +-28351 , +-5261 , +28121 , +19311 , +-24507 , +-20023 , +26145 , +30183 , +19121 , +-3151 , +-7185 , +13603 , +23879 , +-30097 , +28887 , +-32163 , +-1859 , +-2293 , +1621 , +-28211 , +-29233 , +-7339 , +20777 , +-27687 , +-4647 , +-7849 , +-6859 , +16585 , +18417 , +8523 , +31175 , +9993 , +27261 , +22039 , +-14721 , +13273 , +8523 , +-32701 , +6309 , +28293 , +2087 , +-10383 , +14579 , +24101 , +-22019 , +-30121 , +-17919 , +4555 , +17507 , +-29387 , +18191 , +17215 , +1977 , +11981 , +2917 , +-29635 , +11199 , +-21541 , +-13791 , +9763 , +-20303 , +30991 , +-16739 , +11307 , +9431 , +31619 , +-8901 , +-10193 , +18083 , +-6221 , +-29503 , +-20019 , +-9399 , +-267 , +28727 , +10287 , +-28205 , +25457 , +22833 , +-29123 , +19133 , +15007 , +-1353 , +-3755 , +-25587 , +-10703 , +29841 , +-15741 , +-5657 , +7067 , +20263 , +-13767 , +-5209 , +25085 , +-45 , +24203 , +-2691 , +-345 , +-29255 , +21471 , +-8577 , +14343 , +28457 , +-24533 , +-9407 , +-10453 , +14185 , +10415 , +9463 , +4013 , +11543 , +-19933 , +-15107 , +-2505 , +24827 , +27515 , +23805 , +15731 , +23905 , +2839 , +17279 , +29061 , +1525 , +-2433 , +-13051 , +27139 , +-16363 , +27797 , +6561 , +10865 , +31661 , +10841 , +16141 , +-5837 , +-19317 , +-32237 , +10053 , +29957 , +1085 , +23831 , +-1125 , +-20229 , +23651 , +8175 , +29777 , +24305 , +-32375 , +-5851 , +-6985 , +-3965 , +-8575 , +8815 , +23481 , +-26997 , +18491 , +-9117 , +-20229 , +18197 , +-13801 , +-4931 , +-10637 , +-3627 , +4805 , +18191 , +18047 , +-25821 , +-26215 , +-30731 , +-6527 , +-27277 , +5217 , +10963 , +13805 , +-28341 , +21957 , +25103 , +8683 , +-17479 , +11285 , +2499 , +21869 , +-23727 , +22693 , +-21259 , +24003 , +7069 , +14249 , +5461 , +31671 , +-10465 , +12421 , +23923 , +31009 , +-4161 , +-31057 , +-657 , +23301 , +5577 , +-23809 , +-13763 , +18469 , +-25243 , +28037 , +24407 , +31775 , +8845 , +-12307 , +-5387 , +-24837 , +-1151 , +-1971 , +-11071 , +22861 , +12747 , +29819 , +14109 , +31951 , +14763 , +-16913 , +-23865 , +-26263 , +8211 , +19987 , +9507 , +22237 , +26401 , +-11489 , +2281 , +27341 , +18709 , +-25233 , +18783 , +-31901 , +-26165 , +-8871 , +12307 , +-417 , +-337 , +-13939 , +5389 , +-15187 , +-19143 , +17887 , +-18029 , +8841 , +-24605 , +8881 , +13653 , +-3061 , +-11869 , +-29507 , +-4569 , +-445 , +20447 , +-14993 , +-28095 , +-13099 , +17129 , +-17469 , +-29457 , +-5111 , +19703 , +-25191 , +-4661 , +-10389 , +16275 , +-1651 , +14963 , +29919 , +-6237 , +-30383 , +8909 , +29751 , +10193 , +15487 , +-28759 , +27473 , +6539 , +-25605 , +1037 , +1705 , +27769 , +7619 , +-14105 , +9845 , +-17289 , +-32439 , +-9413 , +16443 , +5643 , +-13237 , +5359 , +-8985 , +24925 , +47 , +-30739 , +-29845 , +-5199 , +8147 , +-31765 , +8141 , +-14503 , +-25109 , +16031 , +-26939 , +14903 , +-13349 , +-27025 , +30163 , +-3411 , +24839 , +-6217 , +-39 , +15129 , +-19791 , +27763 , +5677 , +-7225 , +-19375 , +7811 , +7741 , +7027 , +22631 , +-27559 , +-15463 , +-4551 , +27101 , +-12231 , +-4459 , +-23791 , +30167 , +31211 , +-14501 , +-20543 , +-8691 , +31479 , +7561 , +31583 , +-21597 , +30041 , +3137 , +-22721 , +14981 , +3265 , +13001 , +5749 , +21815 , +31295 , +22941 , +27587 , +-9929 , +25223 , +-9203 , +13845 , +31687 , +26271 , +-20913 , +-31875 , +-14507 , +26397 , +22551 , +4773 , +-5813 , +-3617 , +-17479 , +-9527 , +26723 , +-11709 , +433 , +8757 , +23431 , +15317 , +-32567 , +-9425 , +14629 , +-30821 , +-1367 , +32637 , +-10489 , +-1093 , +1269 , +8791 , +-19797 , +-27209 , +-2341 , +-3875 , +6683 , +20271 , +13111 , +-9963 , +19785 , +-10997 , +10019 , +-28837 , +12255 , +10555 , +-10987 , +-21915 , +-23647 , +9971 , +17519 , +3499 , +9015 , +24917 , +-21091 , +23147 , +-19049 , +21687 , +-17749 , +-24801 , +-11827 , +25171 , +-19359 , +-653 , +19293 , +-29053 , +-3115 , +32445 , +-8429 , +31097 , +28801 , +-12559 , +30823 , +-30097 , +-15639 , +5671 , +-14523 , +-14993 , +29601 , +-22399 , +15987 , +17273 , +-4367 , +-15185 , +4709 , +-15033 , +-2837 , +6373 , +20619 , +22659 , +-8705 , +17999 , +-22723 , +-30853 , +-29673 , +6923 , +-2563 , +2909 , +24619 , +-17757 , +15967 , +30957 , +3167 , +27909 , +3421 , +-8259 , +-25961 , +19445 , +-2775 , +-11289 , +32651 , +-30961 , +12173 , +-9663 , +4713 , +30261 , +189 , +-20709 , +16613 , +12941 , +-3407 , +24431 , +-10283 , +-4615 , +-32509 , +-21343 , +14403 , +-16117 , +19771 , +-19789 , +-12017 , +10115 , +29617 , +18685 , +13569 , +-7363 , +6367 , +5477 , +9565 , +32183 , +-14529 , +-13801 , +26885 , +8191 , +-19043 , +-31295 , +-14329 , +-1751 , +-29199 , +-12735 , +955 , +-5293 , +-13125 , +7661 , +9049 , +-18673 , +20691 , +31543 , +-4841 , +23911 , +13255 , +4855 , +-7247 , +-4023 , +-32075 , +19735 , +-24427 , +-30323 , +-4197 , +21461 , +-7569 , +-24483 , +4915 , +-31379 , +10301 , +30017 , +22355 , +-14237 , +12537 , +-13185 , +8625 , +14891 , +14235 , +-20697 , +22357 , +12395 , +17345 , +27265 , +-12199 , +1195 , +26305 , +-31221 , +-11181 , +-23915 , +15681 , +-6169 , +14109 , +20653 , +-29363 , +-8223 , +11841 , +-21635 , +22775 , +20695 , +30393 , +19291 , +15717 , +-20285 , +-7331 , +3227 , +30319 , +5923 , +-5201 , +29255 , +24245 , +4599 , +21297 , +7001 , +-15303 , +31039 , +-32439 , +-15763 , +-5773 , +-1815 , +-24181 , +-16383 , +-29973 , +-30387 , +9371 , +-30933 , +-16039 , +-29143 , +-18049 , +5325 , +6185 , +-11243 , +22399 , +-14001 , +-20307 , +9335 , +28783 , +-23337 , +-13925 , +-22523 , +-7273 , +24071 , +-31941 , +-12363 , +-14079 , +19239 , +14321 , +-969 , +-21167 , +-27155 , +16731 , +-25617 , +22049 , +-20053 , +-32283 , +-2197 , +-22821 , +-29691 , +-29977 , +25689 , +-16887 , +28727 , +-18635 , +5893 , +-7371 , +5305 , +4675 , +19021 , +23863 , +-13431 , +25517 , +-2535 , +-14051 , +19673 , +14173 , +-13231 , +2417 , +5191 , +14875 , +-19363 , +26145 , +-14179 , +-15701 , +32017 , +-2873 , +-23041 , +-8357 , +-721 , +-7791 , +25259 , +-16345 , +23133 , +-20339 , +-31191 , +-10933 , +-20837 , +3977 , +-21751 , +31321 , +-15307 , +20581 , +-23777 , +-31277 , +8267 , +9199 , +-2515 , +-27319 , +5051 , +-21195 , +-19673 , +28135 , +2717 , +-31385 , +3051 , +18833 , +-11717 , +-14293 , +-19599 , +26749 , +3469 , +-16277 , +30347 , +-16565 , +-28631 , +19901 , +1811 , +6553 , +-10301 , +-26065 , +29105 , +-30435 , +23583 , +14505 , +13833 , +31039 , +-4721 , +17339 , +31091 , +16177 , +-9757 , +-27397 , +19513 , +32387 , +4073 , +-21289 , +31049 , +14911 , +-1697 , +25339 , +-10127 , +-5505 , +17265 , +-2281 , +-25835 , +28291 , +19881 , +-26043 , +-29849 , +13135 , +30573 , +2261 , +-18913 , +26305 , +1019 , +19637 , +30391 , +-28895 , +-13103 , +16437 , +24093 , +24389 , +31415 , +-5775 , +-5141 , +7969 , +32049 , +17951 , +-28123 , +-32539 , +30829 , +-24597 , +-1173 , +14987 , +25037 , +329 , +3001 , +15357 , +719 , +-7465 , +-27757 , +-9825 , +6797 , +-22229 , +11717 , +-15501 , +-10825 , +2869 , +16283 , +8359 , +-11005 , +-1781 , +-27751 , +-22605 , +31275 , +6987 , +-31059 , +2801 , +-19613 , +-32017 , +16367 , +-28239 , +-683 , +-24151 , +-5421 , +13783 , +-11375 , +8879 , +27625 , +7659 , +18313 , +-17373 , +-30713 , +-13383 , +-2543 , +-28445 , +-2545 , +-10395 , +4933 , +15067 , +21283 , +-28927 , +-15085 , +5613 , +29015 , +21163 , +-31701 , +-7369 , +-1809 , +1311 , +-17549 , +23801 , +-11241 , +26837 , +24069 , +-11549 , +23831 , +-15987 , +-21589 , +26361 , +-14575 , +-28037 , +-9269 , +731 , +-18125 , +-12085 , +-6425 , +-25175 , +-27535 , +25285 , +9877 , +-5543 , +23487 , +17249 , +1013 , +1675 , +-18745 , +8799 , +27817 , +16869 , +1827 , +-10015 , +17997 , +-27159 , +2063 , +-30081 , +-26511 , +-6579 , +-3927 , +-13597 , +-23281 , +-24105 , +-28505 , +-24609 , +-22655 , +-9301 , +24457 , +-18425 , +29185 , +29999 , +-2469 , +-21051 , +-24169 , +28763 , +-5151 , +-20745 , +-24427 , +661 , +-29861 , +24831 , +12179 , +-32764 , +23991 , +22883 , +-21277 , +-18575 , +-699 , +737 , +-11643 , +-10603 , +11255 , +18181 , +8873 , +28409 , +-23531 , +-11195 , +-17763 , +-19643 , +-25737 , +22683 , +-15281 , +-31451 , +28985 , +-30571 , +15929 , +27539 , +32247 , +19185 , +20965 , +2491 , +32387 , +-8007 , +-3875 , +11847 , +-28389 , +25047 , +-4059 , +4929 , +15657 , +26153 , +23091 , +-6549 , +32113 , +13091 , +12139 , +12815 , +17615 , +17887 , +19727 , +15963 , +30063 , +-28231 , +-19775 , +829 , +-15745 , +19299 , +-8593 , +-15693 , +29809 , +-26495 , +30421 , +-7251 , +-30805 , +-1089 , +-909 , +9563 , +7617 , +-10901 , +-18175 , +-15605 , +-18131 , +-12151 , +-23189 , +-24449 , +15239 , +-27537 , +32325 , +5833 , +7747 , +-27939 , +-16697 , +31131 , +-8737 , +19089 , +-17851 , +-4829 , +3997 , +-10655 , +-29659 , +-23447 , +6593 , +8405 , +5717 , +8219 , +1607 , +-27585 , +-14777 , +-31247 , +26647 , +-24751 , +22635 , +-22405 , +-13635 , +-6609 , +21019 , +-10365 , +-23381 , +30745 , +27173 , +4311 , +17379 , +-7827 , +-26699 , +-22093 , +-21193 , +29265 , +-49 , +2185 , +-6657 , +-28227 , +31053 , +-30877 , +-24491 , +29983 , +-8363 , +5813 , +-15931 , +5227 , +-5559 , +-18247 , +-17267 , +-19785 , +-14513 , +27973 , +13135 , +-11443 , +9783 , +-23005 , +-8373 , +-3249 , +-2561 , +-9237 , +12573 , +-8255 , +-30777 , +23383 , +-23577 , +41 , +20555 , +-7391 , +15129 , +28073 , +-41 , +10837 , +8861 , +11919 , +10435 , +-6357 , +-5737 , +28275 , +11369 , +28259 , +20371 , +2767 , +-22881 , +-31979 , +7245 , +19475 , +4011 , +28433 , +-1575 , +9027 , +-13121 , +-1103 , +-13983 , +-15353 , +26351 , +25397 , +27233 , +-3253 , +8363 , +-11623 , +27737 , +-7597 , +-24143 , +-27667 , +-23797 , +-4525 , +-3695 , +31023 , +5417 , +7301 , +30871 , +-24671 , +15771 , +-21817 , +16203 , +9119 , +5931 , +-29521 , +9321 , +-8963 , +-5439 , +11555 , +16727 , +-17445 , +22559 , +19569 , +13597 , +-8707 , +-28397 , +21223 , +-29217 , +-2913 , +16177 , +-4115 , +2255 , +4827 , +3085 , +23963 , +-8017 , +31853 , +17393 , +8401 , +-7487 , +-29409 , +-29931 , +-25135 , +-32189 , +20625 , +7511 , +22867 , +-23967 , +-7527 , +-28553 , +15905 , +20151 , +12315 , +-28471 , +-16595 , +6721 , +12381 , +-28563 , +11819 , +23765 , +12007 , +-7921 , +7847 , +1821 , +15823 , +12307 , +11673 , +17677 , +26777 , +-8871 , +1419 , +-22823 , +-16497 , +9325 , +-2275 , +2165 , +-11367 , +-28605 , +-467 , +-4221 , +-17775 , +-20117 , +-29845 , +-26673 , +13341 , +-28979 , +-5523 , +26187 , +1801 , +-14111 , +-25527 , +-1407 , +12063 , +-6301 , +32431 , +-26995 , +-3207 , +-13939 , +6013 , +5531 , +32095 , +-20267 , +-8995 , +10449 , +1955 , +-8681 , +-11815 , +4821 , +15979 , +14685 , +20335 , +-26179 , +-6247 , +-1015 , +21043 , +26509 , +27541 , +-10853 , +9313 , +-28375 , +22191 , +-32035 , +-17295 , +31695 , +27383 , +20381 , +-22475 , +-9969 , +23177 , +31469 , +-9099 , +-3769 , +-15757 , +-2605 , +16637 , +-2925 , +32263 , +29825 , +20789 , +-30129 , +-5451 , +18965 , +-22199 , +22273 , +13405 , +1733 , +-10327 , +-20251 , +16945 , +20645 , +19255 , +15053 , +23553 , +-4399 , +-18991 , +-25167 , +8223 , +32559 , +-17555 , +6291 , +-7761 , +-12639 , +17843 , +7939 , +1923 , +19395 , +21525 , +-16875 , +-31889 , +-29669 , +-24475 , +-43 , +-1497 , +23515 , +-4119 , +1345 , +-19567 , +20495 , +26875 , +3779 , +-5217 , +21337 , +-15073 , +11047 , +-25685 , +9519 , +-18535 , +-15081 , +21575 , +17287 , +24705 , +-14585 , +16283 , +14107 , +9319 , +-29249 , +-7107 , +-17897 , +-16293 , +24901 , +-16247 , +-20137 , +-3435 , +-21419 , +22129 , +28705 , +-28801 , +-21911 , +-16413 , +15955 , +23387 , +-15335 , +25491 , +-26327 , +-32691 , +21031 , +-7585 , +9829 , +-1797 , +-273 , +-10977 , +-11755 , +-14425 , +32351 , +29437 , +3783 , +20927 , +-11157 , +-18347 , +-20419 , +-18437 , +-7663 , +9731 , +22691 , +-32011 , +28867 , +-20157 , +-4011 , +31805 , +29801 , +-1023 , +8197 , +3063 , +-17449 , +28091 , +17793 , +-3349 , +-14403 , +17613 , +-9501 , +-18137 , +45 , +14423 , +-14261 , +-22261 , +135 , +-15739 , +-26597 , +-20757 , +12791 , +-21639 , +1445 , +-2779 , +27755 , +-4975 , +-8591 , +-27465 , +-10741 , +-31667 , +-21017 , +12883 , +-18123 , +21151 , +11155 , +-8191 , +-30485 , +-27193 , +-7211 , +6959 , +-13351 , +8103 , +4891 , +16203 , +9661 , +-9313 , +11159 , +17629 , +14193 , +-17179 , +-639 , +9501 , +-29359 , +-21159 , +-1599 , +-17907 , +21571 , +-27423 , +-30931 , +29449 , +3361 , +4415 , +-7607 , +-18961 , +-2375 , +-2453 , +32623 , +17575 , +26185 , +12135 , +26515 , +32581 , +-14743 , +6041 , +-30855 , +-9575 , +29841 , +-7001 , +26987 , +25423 , +13581 , +14537 , +20845 , +-23163 , +30061 , +30117 , +13309 , +-12067 , +5513 , +-6237 , +32587 , +28957 , +-4367 , +25035 , +12009 , +-27837 , +-11545 , +25109 , +8711 , +-20709 , +14045 , +22091 , +11309 , +11613 , +18271 , +6485 , +-10125 , +-7617 , +-26215 , +16671 , +22323 , +21649 , +13129 , +21733 , +-29107 , +10577 , +8503 , +-31731 , +-15409 , +-29751 , +21547 , +-2681 , +-9413 , +-5597 , +-917 , +18333 , +-25289 , +-8579 , +7087 , +22605 , +459 , +-25459 , +-31335 , +-4573 , +-2799 , +-17495 , +1707 , +22925 , +-29069 , +-19089 , +-5691 , +-22855 , +12899 , +-3887 , +-27623 , +30693 , +-26991 , +-20045 , +28577 , +8257 , +8353 , +-15103 , +-9189 , +5949 , +-26775 , +16713 , +24195 , +23655 , +-24923 , +13263 , +-14591 , +-7229 , +-2773 , +-28117 , +-31379 , +-23905 , +-4689 , +18521 , +-7107 , +21743 , +6637 , +-17577 , +25093 , +-27871 , +-24471 , +-26559 , +-7831 , +20605 , +13483 , +18393 , +-6245 , +23025 , +10727 , +-8523 , +-24245 , +-4747 , +-26551 , +-7743 , +-6617 , +475 , +3233 , +-18583 , +-3379 , +22311 , +-17767 , +7461 , +4423 , +-6289 , +-22151 , +31131 , +-6141 , +-12247 , +-11441 , +25385 , +-22713 , +19467 , +-20809 , +13071 , +-13013 , +-10917 , +6919 , +-779 , +-18413 , +2255 , +9999 , +-15597 , +-16473 , +24799 , +-21941 , +16057 , +3141 , +24997 , +10395 , +5497 , +-6911 , +19755 , +-1917 , +-11601 , +-21477 , +-1981 , +9179 , +32161 , +16881 , +-10257 , +-1271 , +9237 , +1661 , +-8413 , +-11589 , +12653 , +12623 , +17709 , +-7141 , +-5577 , +-18437 , +-13177 , +-14453 , +-7093 , +31519 , +-24019 , +-32293 , +-11421 , +-3633 , +28025 , +-25595 , +-32207 , +2959 , +-22405 , +15707 , +20467 , +-32555 , +-10035 , +-16311 , +2713 , +18931 , +-16145 , +-18035 , +32073 , +29847 , +8733 , +-5659 , +-29815 , +4035 , +9895 , +4689 , +12493 , +26181 , +3275 , +8905 , +15503 , +16295 , +10763 , +-17555 , +8941 , +24501 , +-8443 , +30795 , +-17985 , +-919 , +-27703 , +-115 , +14887 , +25191 , +21689 , +18995 , +24245 , +32764 , +10201 , +8009 , +-2569 , +-29051 , +-19803 , +14759 , +-15979 , +-28037 , +18551 , +4125 , +-1561 , +-5667 , +-1715 , +-18375 , +19983 , +-24277 , +-18133 , +-9361 , +-18295 , +-14619 , +14327 , +14051 , +83 , +30073 , +-32313 , +-25203 , +15991 , +-13375 , +-69 , +-2809 , +16419 , +-29703 , +-3747 , +9391 , +7501 , +-26313 , +-2449 , +28525 , +-9279 , +2915 , +-16051 , +12269 , +30393 , +4533 , +-30279 , +28491 , +8953 , +23455 , +22591 , +20051 , +10087 , +16467 , +-15869 , +-18121 , +8737 , +23733 , +11553 , +24011 , +4627 , +-8237 , +13695 , +23605 , +-747 , +15835 , +18985 , +-21973 , +-30083 , +-32357 , +6953 , +-24403 , +27195 , +-2963 , +-4135 , +-21453 , +-8083 , +21691 , +32195 , +-26767 , +19839 , +21231 , +22515 , +26759 , +2741 , +-29461 , +-28969 , +18619 , +29525 , +-16373 , +-26487 , +28339 , +29229 , +27019 , +6585 , +-31955 , +27577 , +-29291 , +-22797 , +30769 , +-9035 , +-9053 , +5763 , +19153 , +-31437 , +-4215 , +31435 , +-22691 , +30777 , +-11805 , +23831 , +-6119 , +-6193 , +-27891 , +20731 , +26235 , +1445 , +5535 , +30755 , +-26915 , +-12257 , +-10903 , +3761 , +-6471 , +9205 , +-9251 , +-26603 , +-10911 , +-5565 , +-25837 , +-15259 , +16175 , +-17625 , +-6337 , +-22995 , +21325 , +-13091 , +-14681 , +20691 , +11227 , +-30905 , +20505 , +30569 , +-32589 , +-27621 , +20455 , +9221 , +27807 , +-15515 , +-5281 , +8087 , +-17137 , +-25423 , +-1343 , +8775 , +-15283 , +-2919 , +20917 , +25671 , +9791 , +24285 , +-20921 , +-22735 , +-26729 , +-11005 , +-31137 , +20439 , +1935 , +26979 , +27573 , +-22367 , +11293 , +24269 , +15951 , +-7065 , +-5967 , +31889 , +-6799 , +-1601 , +-30875 , +-2265 , +-14565 , +-4381 , +15549 , +-15045 , +-18941 , +-20999 , +-4645 , +-18103 , +-29179 , +-1539 , +-20169 , +14267 , +14113 , +-25593 , +471 , +-7817 , +18163 , +24881 , +7431 , +2811 , +-1881 , +229 , +-32107 , +22519 , +-19595 , +-31807 , +3969 , +21347 , +-10345 , +17117 , +-21701 , +23577 , +2499 , +6071 , +-165 , +-16917 , +-19169 , +-11141 , +12759 , +20281 , +-1091 , +-25369 , +6587 , +27405 , +-12911 , +14231 , +-6561 , +-24651 , +24041 , +-4117 , +-20185 , +-5679 , +-20631 , +8273 , +-3663 , +-11275 , +28281 , +-731 , +19603 , +21185 , +-11701 , +-18419 , +-19311 , +-19091 , +-17339 , +-27709 , +22105 , +-32015 , +-12797 , +123 , +18095 , +-25707 , +-21045 , +22709 , +27449 , +30465 , +12677 , +22163 , +-27231 , +-10517 , +-22475 , +-9803 , +18781 , +-14827 , +-1555 , +5521 , +9185 , +15353 , +-10673 , +-16313 , +24409 , +15577 , +-22147 , +23039 , +26585 , +-12717 , +-28781 , +9399 , +-1245 , +-26495 , +-349 , +-6999 , +-13611 , +-29811 , +24355 , +279 , +6433 , +25033 , +19185 , +7591 , +18443 , +22091 , +-21821 , +-15297 , +-11495 , +-6151 , +27171 , +14167 , +-21609 , +307 , +-1565 , +1237 , +28481 , +23515 , +22813 , +29027 , +29057 , +31225 , +-9059 , +21571 , +3885 , +2759 , +27883 , +31669 , +17591 , +5203 , +29361 , +12733 , +-283 , +-18027 , +10689 , +-1659 , +7693 , +-2813 , +-28027 , +7483 , +-23603 , +8109 , +-17927 , +9301 , +833 , +-25391 , +-28633 , +-13697 , +3003 , +-32261 , +1305 , +-28951 , +26107 , +-27761 , +-23469 , +29721 , +7143 , +28147 , +26317 , +2127 , +8901 , +13077 , +-3225 , +20055 , +24561 , +-27501 , +1511 , +-24865 , +8215 , +-28091 , +13417 , +6741 , +30951 , +-15009 , +-13469 , +-15559 , +-29361 , +-28667 , +-2037 , +-9993 , +11319 , +2403 , +-1691 , +-29887 , +-15949 , +-441 , +-28763 , +-25115 , +4797 , +-8649 , +25145 , +5415 , +-17553 , +-4859 , +-27595 , +-32107 , +-6213 , +-28429 , +16209 , +2659 , +16027 , +5439 , +3427 , +-18113 , +30679 , +-18111 , +-22451 , +17073 , +-27597 , +25597 , +14463 , +-16407 , +12327 , +-11191 , +-22035 , +-30949 , +-5859 , +-23215 , +-4223 , +-19621 , +19747 , +-63 , +-739 , +29933 , +19751 , +20307 , +-20471 , +-15833 , +-22099 , +-11031 , +24051 , +-32577 , +20999 , +27939 , +16991 , +-16469 , +11791 , +25473 , +-32087 , +6513 , +19035 , +-22037 , +115 , +-10489 , +-8455 , +19673 , +-19805 , +-5337 , +10407 , +31709 , +-17189 , +24103 , +-29561 , +-317 , +-659 , +16977 , +-421 , +28461 , +18903 , +-14147 , +8507 , +3743 , +4537 , +-29017 , +6861 , +-28383 , +-24497 , +-17595 , +-28419 , +-19375 , +-19353 , +1575 , +-13769 , +-1281 , +-22827 , +15873 , +26655 , +25923 , +-10377 , +26645 , +-19261 , +32023 , +-26465 , +4093 , +-1445 , +-28819 , +20757 , +-8187 , +-8835 , +27077 , +3211 , +6665 , +12755 , +29771 , +12951 , +2249 , +16729 , +-32665 , +-25565 , +449 , +-495 , +9183 , +-16523 , +3969 , +5689 , +-1945 , +10903 , +-9079 , +25351 , +-26695 , +1111 , +-2409 , +-22049 , +-21451 , +-13377 , +649 , +10253 , +-4627 , +3591 , +-1867 , +-7943 , +25673 , +19223 , +439 , +9959 , +-15337 , +-16263 , +3029 , +22047 , +16935 , +21195 , +-20275 , +15037 , +-19875 , +19911 , +-31693 , +6351 , +19283 , +12969 , +25163 , +-12511 , +-6549 , +19767 , +-10407 , +3179 , +5219 , +18217 , +14207 , +3853 , +-8587 , +29235 , +32531 , +-6333 , +-29717 , +107 , +-27781 , +-19485 , +17465 , +-7345 , +-901 , +-11889 , +-6769 , +-30409 , +-20969 , +29805 , +-6149 , +12617 , +-1301 , +-23447 , +-23305 , +3579 , +18171 , +5085 , +-9337 , +-4605 , +-27891 , +-14119 , +-14127 , +-23599 , +30861 , +4301 , +-21197 , +-7287 , +-21039 , +-18741 , +5595 , +-12425 , +-21759 , +-3013 , +-15651 , +-5363 , +-30869 , +5141 , +-32303 , +-21419 , +-22701 , +16535 , +-11033 , +25581 , +21081 , +29559 , +-16771 , +-19587 , +-13755 , +173 , +-30401 , +19117 , +-1435 , +-19563 , +-6991 , +8867 , +22371 , +-2375 , +11865 , +-4105 , +1947 , +-515 , +16199 , +809 , +-5123 , +27487 , +-27085 , +20383 , +-24235 , +26149 , +13851 , +-12009 , +4655 , +-25435 , +4433 , +1955 , +-20179 , +10347 , +22811 , +-15843 , +-3107 , +-13057 , +-30271 , +-4315 , +9741 , +-30443 , +-29901 , +-21359 , +11695 , +-3515 , +-16873 , +19823 , +22309 , +21325 , +19807 , +-29067 , +-15845 , +1211 , +-25491 , +-20231 , +-30999 , +-2001 , +10655 , +-19345 , +11355 , +-4597 , +-17043 , +26203 , +-31209 , +19891 , +15867 , +-32563 , +-27793 , +6211 , +-193 , +-28839 , +30393 , +-4669 , +-6267 , +-11637 , +7461 , +-25375 , +16539 , +-9759 , +-20709 , +13611 , +-29355 , +3143 , +24847 , +5059 , +15291 , +-10489 , +-17193 , +-7521 , +-29811 , +-17593 , +-1145 , +567 , +-32411 , +-3581 , +-30777 , +21953 , +15955 , +-8579 , +16559 , +-5653 , +-27673 , +1853 , +-27369 , +28179 , +11481 , +-12927 , +3955 , +-2053 , +8725 , +-25795 , +27185 , +2563 , +21593 , +-16495 , +-15225 , +21479 , +25163 , +-20037 , +4047 , +9705 , +-27885 , +-3435 , +19811 , +3737 , +-29329 , +17551 , +-19217 , +-25855 , +13135 , +29213 , +23371 , +-20123 , +31211 , +23229 , +29143 , +32371 , +-27041 , +32355 , +-18871 , +27907 , +22199 , +-16525 , +11029 , +8265 , +-103 , +-27837 , +-20429 , +-5997 , +-31153 , +22787 , +-27519 , +-21893 , +32609 , +3911 , +-18529 , +-20317 , +-26185 , +8171 , +21563 , +24553 , +-481 , +31389 , +2803 , +17953 , +27515 , +-18997 , +17831 , +31571 , +26435 , +28191 , +-29863 , +-12951 , +23217 , +-25485 , +-9097 , +-20885 , +-3001 , +6731 , +-20541 , +23867 , +-23051 , +3283 , +-22625 , +16583 , +-26709 , +28235 , +-26645 , +-4669 , +-6547 , +28169 , +-2979 , +-12573 , +-30731 , +-8467 , +16215 , +-6255 , +-21819 , +27735 , +-28357 , +-22235 , +-5445 , +-12889 , +-12209 , +21151 , +12849 , +-20437 , +-20217 , +-11557 , +-24687 , +-28771 , +5861 , +-23217 , +18287 , +13591 , +-4651 , +-24261 , +11035 , +5267 , +5111 , +13161 , +15299 , +16601 , +27655 , +-1437 , +-15871 , +11771 , +-20441 , +15651 , +507 , +-1455 , +7489 , +13399 , +29683 , +30187 , +-28963 , +-25069 , +26985 , +-24435 , +9077 , +-27641 , +30377 , +-10715 , +335 , +7227 , +30957 , +25025 , +21463 , +27719 , +-28441 , +-20721 , +6517 , +22279 , +-5655 , +-11703 , +-9755 , +-9001 , +-23183 , +-24903 , +-8941 , +22087 , +-15541 , +935 , +-1431 , +12633 , +24093 , +-6181 , +-26445 , +-18123 , +5255 , +15241 , +-2447 , +-8097 , +-2369 , +30933 , +21163 , +-31373 , +-12131 , +19137 , +3665 , +10845 , +10299 , +-27985 , +24081 , +-27125 , +-14067 , +-31667 , +-23381 , +22703 , +13175 , +4119 , +3531 , +-21907 , +-14105 , +21581 , +-32413 , +-25443 , +3175 , +19559 , +-30845 , +5495 , +-12355 , +30479 , +13483 , +-29101 , +-23295 , +-21859 , +-18773 , +3173 , +27823 , +-12281 , +-26121 , +19433 , +22599 , +-17311 , +24445 , +-27163 , +14689 , +-7983 , +31493 , +14429 , +30017 , +2309 , +20991 , +6407 , +29949 , +-8145 , +21215 , +23185 , +-5629 , +29821 , +-17159 , +-29625 , +-16581 , +28943 , +12499 , +23637 , +3745 , +18027 , +-24321 , +17539 , +-3243 , +-1661 , +-17547 , +10591 , +-28611 , +-12007 , +25451 , +25607 , +8979 , +-26169 , +21415 , +11853 , +31745 , +-18319 , +-32417 , +-5757 , +-20033 , +-15553 , +22415 , +14245 , +27167 , +-9969 , +25289 , +24341 , +-28881 , +28535 , +-31335 , +-3885 , +-14131 , +-12493 , +19799 , +10555 , +-27969 , +-2269 , +32639 , +815 , +18253 , +7619 , +30599 , +30175 , +-2475 , +-30433 , +27967 , +-11019 , +24807 , +-2737 , +15261 , +-13485 , +-3749 , +16749 , +-16353 , +-6069 , +2029 , +-25843 , +27295 , +14161 , +29641 , +-8135 , +5549 , +-9665 , +28855 , +28641 , +-16539 , +7677 , +283 , +8409 , +15043 , +455 , +-859 , +-26799 , +29061 , +-22307 , +-21675 , +-20281 , +20093 , +-20801 , +17697 , +16011 , +-6043 , +-10779 , +11779 , +-14681 , +1345 , +2289 , +18075 , +-31897 , +-29137 , +9837 , +10557 , +22853 , +3009 , +-28923 , +-21619 , +-1177 , +-15659 , +-4551 , +31899 , +-2411 , +-30223 , +13719 , +14199 , +-9549 , +-4333 , +17009 , +-15803 , +15027 , +-14833 , +9759 , +20961 , +-17641 , +-18583 , +-30551 , +-5657 , +-6431 , +-6235 , +7687 , +-20133 , +781 , +20263 , +-23081 , +-3147 , +-26485 , +-9599 , +28057 , +9857 , +-4939 , +-5287 , +-12959 , +-13459 , +8263 , +20921 , +-26865 , +-30991 , +11479 , +21983 , +-4083 , +17237 , +30927 , +-5463 , +-29309 , +-18347 , +14819 , +-24485 , +-13553 , +12085 , +24071 , +28669 , +-27651 , +-9379 , +13039 , +-2251 , +-26879 , +-24729 , +-31749 , +15521 , +-17301 , +-26943 , +26299 , +-27485 , +22243 , +15299 , +28127 , +-16693 , +1697 , +-32187 , +31409 , +-11363 , +-14561 , +-16717 , +-6899 , +6905 , +8029 , +-20051 , +12765 , +25321 , +-4983 , +-28641 , +4107 , +-4363 , +-16571 , +24527 , +-11269 , +-26611 , +17241 , +-32641 , +10627 , +13517 , +-22041 , +-18049 , +13415 , +-7583 , +-29137 , +-23603 , +-10421 , +17879 , +19643 , +-14175 , +22829 , +24059 , +17689 , +19599 , +8541 , +-593 , +-485 , +32541 , +-15879 , +-31039 , +-23419 , +9939 , +2269 , +-703 , +-9139 , +-7711 , +20259 , +2909 , +23631 , +29485 , +-16617 , +3513 , +19585 , +21483 , +-14163 , +-16319 , +-8521 , +25017 , +31869 , +-23667 , +6605 , +311 , +1341 , +-19799 , +20329 , +-29411 , +-2129 , +-32387 , +13357 , +27089 , +-20189 , +23447 , +4723 , +-27261 , +31853 , +31631 , +3975 , +3271 , +-19113 , +-3371 , +-1197 , +-9309 , +-23901 , +23057 , +-23895 , +13107 , +15993 , +-7689 , +7145 , +23481 , +-23195 , +-9059 , +1609 , +-9417 , +25553 , +22359 , +13183 , +-22393 , +23025 , +-8945 , +-19453 , +-15623 , +28237 , +-1767 , +-16955 , +1631 , +-14679 , +-28019 , +25951 , +-27731 , +-16505 , +-18395 , +-24105 , +-23023 , +23065 , +-2935 , +-27957 , +11401 , +22717 , +-15567 , +-32459 , +-5 , +-15885 , +15799 , +-28005 , +3535 , +471 , +-26187 , +-22837 , +20227 , +25111 , +-28905 , +22543 , +-7225 , +4199 , +16117 , +-27159 , +11157 , +27523 , +-19729 , +-11701 , +12739 , +-12639 , +-29443 , +14665 , +18085 , +-27799 , +-49 , +-5285 , +7451 , +-32151 , +-22625 , +-19955 , +17585 , +27159 , +23435 , +10041 , +22575 , +5187 , +-28813 , +-14657 , +-18243 , +21005 , +24133 , +-7489 , +11625 , +22113 , +-11041 , +-3505 , +16213 , +5867 , +-27293 , +12981 , +-21957 , +-5223 , +27405 , +4889 , +-18033 , +9345 , +-6509 , +25287 , +-5605 , +-12693 , +-25873 , +-17953 , +-22519 , +24001 , +4811 , +5261 , +-32375 , +30721 , +5697 , +6345 , +-23067 , +-27707 , +22859 , +-381 , +2323 , +-22743 , +10885 , +-28055 , +977 , +-25391 , +15001 , +19217 , +-14269 , +-14501 , +5125 , +-5959 , +-31997 , +2899 , +23427 , +-26751 , +-32585 , +-2121 , +28885 , +3099 , +12341 , +-31521 , +-30685 , +-27893 , +22797 , +-19965 , +-11311 , +-30119 , +24237 , +-18131 , +-10539 , +15821 , +-6161 , +4529 , +30615 , +-25179 , +-15559 , +-1755 , +-5311 , +-14387 , +24333 , +-17703 , +4503 , +-9321 , +-20693 , +28113 , +22867 , +4087 , +-10719 , +24889 , +-15105 , +-31693 , +27491 , +-4253 , +10311 , +-15583 , +-18965 , +-4295 , +13775 , +28897 , +-19643 , +31801 , +30103 , +6923 , +17201 , +19691 , +-17467 , +-23693 , +20411 , +20439 , +14347 , +15705 , +18889 , +-14589 , +-19089 , +29987 , +-11715 , +-26137 , +8881 , +15001 , +-6263 , +5603 , +-1249 , +26005 , +28613 , +-10947 , +-22557 , +-21183 , +30543 , +1171 , +29165 , +-30257 , +-1061 , +-16683 , +7229 , +-1875 , +-25591 , +-18495 , +-16705 , +-25787 , +905 , +-4907 , +-1625 , +10279 , +27557 , +-27449 , +6463 , +-22833 , +2149 , +1413 , +16973 , +28119 , +-17891 , +-14171 , +16097 , +23473 , +-9333 , +-27043 , +939 , +16857 , +-31633 , +28415 , +-31267 , +-1389 , +6305 , +-29963 , +-1669 , +8485 , +31655 , +22825 , +4151 , +-7033 , +-16175 , +17425 , +20677 , +-4955 , +-20525 , +29977 , +7865 , +-13815 , +-2605 , +20127 , +-29991 , +-6109 , +23309 , +-11153 , +-31753 , +31223 , +-11037 , +-17743 , +-32693 , +22873 , +-13193 , +21361 , +14155 , +20639 , +29125 , +4741 , +-31747 , +-14623 , +29495 , +-8175 , +2009 , +18095 , +-3643 , +-3717 , +-23019 , +-10429 , +2433 , +24805 , +28553 , +-24511 , +-14663 , +15139 , +5889 , +-12309 , +-8309 , +15407 , +-31215 , +15321 , +2559 , +-3539 , +-21897 , +-19407 , +18073 , +32469 , +5099 , +-32415 , +-2183 , +-20617 , +31351 , +1105 , +7151 , +-23705 , +-15017 , +-3801 , +-30571 , +-18173 , +-21945 , +7281 , +29665 , +-1763 , +32099 , +21225 , +12103 , +-18177 , +18807 , +13217 , +25799 , +-21801 , +-14113 , +-31547 , +-20211 , +5309 , +22237 , +-1325 , +-3581 , +26141 , +29033 , +-5559 , +8683 , +-7239 , +-7273 , +-9241 , +5883 , +-24035 , +12385 , +31587 , +-145 , +-31079 , +22029 , +-10079 , +-3551 , +-31055 , +-32267 , +29551 , +27563 , +-8667 , +-13077 , +2481 , +4079 , +29527 , +-26605 , +-24531 , +-30657 , +8787 , +-24019 , +-16979 , +-10779 , +9785 , +28025 , +20679 , +-3763 , +22847 , +3597 , +14353 , +3469 , +-31965 , +-1879 , +-6959 , +22659 , +28203 , +-5613 , +4163 , +-28813 , +-1391 , +32493 , +-1213 , +16407 , +-6011 , +-27633 , +12431 , +3637 , +-28513 , +1881 , +16767 , +-10813 , +17119 , +-3817 , +29999 , +371 , +-31721 , +-4663 , +-7603 , +-4657 , +-7691 , +-28535 , +-5313 , +-20269 , +-27287 , +-27173 , +-27423 , +7683 , +-21589 , +-4341 , +-20541 , +24327 , +-4693 , +15871 , +19413 , +-1863 , +15885 , +-9841 , +28331 , +-27447 , +-23137 , +-3483 , +-31701 , +26571 , +-14769 , +-4021 , +-32309 , +-29735 , +-4949 , +-24569 , +13385 , +10143 , +30669 , +18875 , +-20511 , +-17923 , +-12321 , +18347 , +23301 , +25119 , +-23799 , +13735 , +-29803 , +31755 , +-24333 , +20697 , +11927 , +27075 , +27825 , +8223 , +29297 , +-7975 , +-697 , +-797 , +-5215 , +-27513 , +9367 , +-27527 , +11247 , +-27577 , +29921 , +-1561 , +17453 , +14061 , +15543 , +24659 , +10345 , +-5569 , +-11917 , +5575 , +28331 , +-16635 , +-8139 , +-10603 , +24615 , +2481 , +-683 , +4395 , +-11017 , +-4253 , +10845 , +12907 , +-11691 , +14229 , +-30075 , +-28025 , +25427 , +14885 , +-605 , +6737 , +-23541 , +16879 , +-9813 , +14615 , +30565 , +15341 , +31395 , +17153 , +-8379 , +2757 , +-7913 , +-12323 , +28485 , +22247 , +5919 , +12931 , +-11799 , +13095 , +-27709 , +-24411 , +-10137 , +28107 , +21763 , +8999 , +3271 , +-6607 , +-6069 , +-6401 , +16047 , +-16683 , +6501 , +1667 , +657 , +-15361 , +32762 , +25415 , +-25753 , +-8503 , +-23681 , +-22411 , +18151 , +-4929 , +-4675 , +3489 , +25663 , +-11275 , +9141 , +-3547 , +27981 , +11167 , +-25299 , +-5897 , +14931 , +20779 , +-3437 , +19713 , +-30669 , +16855 , +22921 , +-2565 , +14629 , +4299 , +26573 , +9663 , +18415 , +20905 , +29883 , +17959 , +-6755 , +20407 , +20799 , +-28833 , +-17989 , +26975 , +-29105 , +11969 , +-17139 , +26717 , +2539 , +1577 , +-22847 , +11847 , +-1407 , +-25647 , +25647 , +-29263 , +12541 , +21159 , +-27891 , +-22597 , +-14033 , +-31959 , +30247 , +-22991 , +203 , +-29515 , +23701 , +10781 , +27871 , +30567 , +-3205 , +18147 , +17871 , +15985 , +31287 , +25045 , +451 , +23277 , +20765 , +-12721 , +-2643 , +-22723 , +-9545 , +32337 , +13491 , +13027 , +10091 , +-24689 , +26161 , +7885 , +25539 , +32013 , +-13781 , +6717 , +-32477 , +32061 , +9293 , +-26601 , +4341 , +-27511 , +-15017 , +21687 , +-13713 , +1149 , +27425 , +17495 , +-19771 , +-16561 , +12039 , +-32299 , +24545 , +18429 , +15085 , +22037 , +19867 , +26349 , +31919 , +-4131 , +-17037 , +-29965 , +4125 , +-7135 , +6343 , +12029 , +-26767 , +3813 , +19849 , +7195 , +14919 , +-4975 , +7547 , +-8161 , +-31979 , +969 , +-10263 , +20663 , +-11485 , +30659 , +30169 , +29437 , +-23287 , +23337 , +-28473 , +-24681 , +21913 , +-9377 , +11233 , +15177 , +-21657 , +-9105 , +-14405 , +-9201 , +-11085 , +7507 , +-18297 , +12985 , +5101 , +31953 , +14025 , +-28421 , +-11611 , +30423 , +8861 , +25613 , +21251 , +29257 , +-3749 , +31681 , +-18487 , +-2201 , +-16927 , +30227 , +-25925 , +26265 , +-3265 , +10059 , +-5723 , +18379 , +-30215 , +22165 , +16843 , +-13749 , +20403 , +-22767 , +-32285 , +-29421 , +12659 , +1393 , +-13679 , +18353 , +85 , +29199 , +-23207 , +27541 , +-22331 , +32645 , +-30185 , +21993 , +21555 , +24009 , +31487 , +10735 , +27981 , +-13893 , +-4339 , +-5163 , +-325 , +-18101 , +-15619 , +-3063 , +25679 , +7171 , +26825 , +21277 , +-14649 , +-30677 , +3485 , +15889 , +23035 , +11351 , +-4531 , +6967 , +-10853 , +-8825 , +-28079 , +18303 , +8295 , +-26185 , +9535 , +11355 , +-23071 , +22273 , +-22855 , +-16881 , +20109 , +30507 , +10479 , +-1395 , +-27991 , +-18491 , +-10861 , +-32567 , +-24745 , +-2365 , +-3755 , +-10089 , +1643 , +-23667 , +-27183 , +-32003 , +-3951 , +13467 , +23057 , +27407 , +18957 , +31121 , +-24191 , +-12479 , +-7695 , +8657 , +-13975 , +15179 , +-3115 , +20375 , +-4893 , +-21899 , +5139 , +-28785 , +30543 , +27249 , +-2439 , +3307 , +15703 , +-10563 , +1921 , +23045 , +21595 , +-31637 , +20495 , +-23195 , +24685 , +-2423 , +-25693 , +-19605 , +-28469 , +29419 , +22809 , +29789 , +725 , +3983 , +11731 , +-28925 , +-15481 , +-28563 , +-19583 , +-18499 , +10093 , +11727 , +22607 , +11287 , +-20191 , +-9423 , +-9829 , +10989 , +15929 , +9873 , +20793 , +-16139 , +-19763 , +18503 , +19743 , +-15901 , +-9373 , +31585 , +-5725 , +17913 , +-17043 , +13947 , +26159 , +-31713 , +3649 , +23831 , +11391 , +24705 , +2185 , +365 , +-15787 , +-30815 , +22603 , +-12591 , +-25171 , +28149 , +21841 , +-19329 , +21377 , +3065 , +17449 , +-5897 , +6387 , +-20791 , +-10853 , +-8743 , +3855 , +-19141 , +-25437 , +15415 , +20733 , +-28301 , +-19737 , +-32399 , +15551 , +-6399 , +17329 , +21641 , +-4509 , +7541 , +13663 , +11263 , +26045 , +16245 , +-22165 , +23593 , +20129 , +32345 , +-29999 , +9735 , +-7271 , +12863 , +-7403 , +-8543 , +-7395 , +-20819 , +11701 , +-14635 , +3917 , +-15465 , +25117 , +-21571 , +12325 , +17163 , +-5079 , +-6279 , +4155 , +25401 , +19221 , +-9579 , +27631 , +21781 , +-28935 , +30161 , +19245 , +-6295 , +27835 , +-4985 , +-16999 , +-29071 , +8337 , +10109 , +29013 , +-22541 , +-10513 , +4155 , +7209 , +21457 , +-11255 , +19689 , +12107 , +-18131 , +4545 , +-31585 , +-12917 , +4079 , +-29661 , +-15289 , +31761 , +18163 , +-2975 , +7147 , +-31339 , +-24949 , +581 , +3219 , +-30701 , +4011 , +7213 , +-8549 , +9479 , +-10385 , +-29313 , +30861 , +19489 , +-193 , +935 , +-12681 , +6277 , +14695 , +-30325 , +-32317 , +-18315 , +-5593 , +-18051 , +-13935 , +22427 , +-19119 , +24005 , +15239 , +-31821 , +26719 , +14209 , +-29381 , +963 , +-26355 , +9269 , +-6669 , +-26143 , +-12181 , +22961 , +-9963 , +-22695 , +-25983 , +-3953 , +-24341 , +11121 , +21081 , +29997 , +-19961 , +5281 , +671 , +-18649 , +16151 , +23617 , +12987 , +-28859 , +-15041 , +-6967 , +-1951 , +-11267 , +14573 , +-28019 , +9647 , +13417 , +-5323 , +-26903 , +-5177 , +12729 , +-16475 , +26115 , +-13861 , +-4297 , +-13659 , +20223 , +8409 , +4269 , +-4027 , +11957 , +17261 , +24433 , +-25703 , +13549 , +23207 , +28111 , +9875 , +13337 , +-2283 , +-3835 , +2653 , +29573 , +-22963 , +2493 , +28711 , +31763 , +25875 , +13061 , +14985 , +-10375 , +17897 , +4033 , +8023 , +14829 , +9259 , +-12627 , +-5637 , +3689 , +-17499 , +23755 , +32329 , +-8871 , +-853 , +7777 , +-19493 , +-31269 , +-2895 , +26225 , +-24089 , +-16015 , +9061 , +25775 , +29591 , +-5573 , +-27577 , +-15883 , +23779 , +31669 , +-27463 , +-23737 , +-14361 , +17889 , +24229 , +19261 , +21177 , +-13553 , +-28789 , +4613 , +-19001 , +-16375 , +-15337 , +-5159 , +10923 , +9937 , +12357 , +13809 , +27521 , +-1063 , +-29715 , +513 , +-7485 , +-4681 , +11231 , +-26575 , +9121 , +5983 , +-24707 , +26517 , +17109 , +13535 , +-21805 , +7453 , +10239 , +19089 , +-2773 , +6427 , +28539 , +14039 , +17449 , +-1231 , +-2885 , +9805 , +-25761 , +31943 , +-25319 , +25229 , +6249 , +21005 , +31545 , +29527 , +-7289 , +18795 , +-7463 , +2651 , +3245 , +24959 , +-31447 , +-20129 , +-21215 , +3467 , +11691 , +-19707 , +9615 , +24699 , +14211 , +13819 , +-12119 , +22095 , +21327 , +693 , +565 , +-3043 , +-19069 , +-5211 , +-21845 , +30339 , +17731 , +20473 , +30539 , +18087 , +-7245 , +-20281 , +-14667 , +-4701 , +25557 , +-12081 , +18949 , +-16763 , +19167 , +22189 , +-21919 , +28363 , +-3819 , +27029 , +2847 , +21837 , +6943 , +16525 , +-16303 , +-30779 , +-23583 , +7193 , +4577 , +-28999 , +20179 , +-23933 , +25387 , +-6145 , +23257 , +5769 , +-26859 , +4013 , +-4705 , +24727 , +2211 , +18325 , +-4247 , +25217 , +-4079 , +-10953 , +28531 , +-29257 , +-29585 , +-4543 , +10435 , +13313 , +-5709 , +2949 , +16263 , +-30025 , +-25775 , +-9617 , +-12573 , +-10123 , +17245 , +-31495 , +24407 , +-15019 , +15891 , +-30675 , +-8821 , +17835 , +18939 , +-12013 , +10669 , +5943 , +-31613 , +22577 , +-10427 , +18657 , +-27897 , +-3199 , +13717 , +-15123 , +20603 , +-26913 , +14437 , +21943 , +-10375 , +-17645 , +22887 , +7401 , +16603 , +9021 , +2565 , +-2761 , +-4393 , +-18231 , +-12861 , +-18805 , +-17267 , +-18951 , +-27383 , +-11055 , +-5587 , +-10555 , +28813 , +20761 , +7555 , +-14229 , +13595 , +30049 , +20243 , +-28845 , +10229 , +21183 , +-1101 , +7061 , +19371 , +31271 , +29345 , +-15385 , +25971 , +-6251 , +-26593 , +-8419 , +21241 , +-26673 , +-2945 , +13341 , +-14141 , +-16233 , +26575 , +30803 , +4355 , +9065 , +23003 , +-27465 , +-7441 , +29355 , +-16683 , +-5839 , +-5481 , +16751 , +-14235 , +18081 , +6467 , +30111 , +-25785 , +-10413 , +22087 , +-19261 , +-7843 , +-21007 , +-22441 , +-15575 , +-28597 , +13057 , +28523 , +19885 , +-17271 , +10465 , +-14581 , +5607 , +-12027 , +32303 , +-22229 , +-1821 , +819 , +-22827 , +-5757 , +-14243 , +23463 , +-19599 , +-24211 , +28283 , +11055 , +-8361 , +9263 , +21499 , +17515 , +-13049 , +5093 , +-32521 , +-11811 , +10527 , +-20793 , +28695 , +8335 , +-5157 , +-4849 , +3139 , +14113 , +-3835 , +-30903 , +-12053 , +-28321 , +7801 , +32045 , +-31569 , +-10139 , +-12017 , +13561 , +-31071 , +-4309 , +-14307 , +-13495 , +9717 , +11169 , +18281 , +-21653 , +-955 , +5193 , +-22621 , +2103 , +-15815 , +31311 , +3427 , +19825 , +-26933 , +18461 , +32407 , +8593 , +12543 , +-9097 , +3709 , +4139 , +-3051 , +18959 , +22563 , +29883 , +24127 , +21411 , +-167 , +-16893 , +-13851 , +31887 , +28709 , +-24097 , +-1713 , +1513 , +-27453 , +22947 , +25833 , +12311 , +-17897 , +32495 , +-15373 , +-26395 , +23213 , +-24315 , +-14407 , +3621 , +2085 , +10917 , +-32429 , +-21315 , +11063 , +-20379 , +27091 , +-23483 , +-11747 , +16263 , +-31487 , +30493 , +17823 , +-15027 , +-26983 , +3845 , +-25481 , +9949 , +-7687 , +32313 , +1367 , +8585 , +27739 , +-15103 , +-173 , +-29767 , +14745 , +29647 , +14573 , +3635 , +31569 , +-32299 , +19833 , +-4615 , +10925 , +12321 , +6433 , +-347 , +1173 , +20783 , +-9385 , +21821 , +24679 , +-13055 , +-8235 , +-11383 , +-9937 , +-17987 , +-6649 , +9201 , +16735 , +-8001 , +-237 , +15823 , +-9973 , +2103 , +6727 , +2633 , +16025 , +-9925 , +-2029 , +16811 , +4607 , +-17825 , +-17537 , +6461 , +-15747 , +30423 , +-11731 , +-9829 , +32459 , +2559 , +27329 , +-2671 , +-16419 , +26497 , +12775 , +-18071 , +26131 , +-26651 , +-29247 , +10959 , +-7947 , +429 , +4075 , +12577 , +22885 , +14059 , +21987 , +-25013 , +22115 , +8025 , +4109 , +12317 , +-11209 , +-10509 , +26411 , +8737 , +17971 , +6409 , +30795 , +26615 , +31463 , +-28701 , +8009 , +10287 , +-9513 , +-7989 , +-14395 , +-28773 , +-1607 , +-13139 , +31895 , +-27355 , +-3543 , +15665 , +-4661 , +-14797 , +-31779 , +-27059 , +-23275 , +-19597 , +27753 , +9307 , +8397 , +5689 , +-3479 , +-321 , +3433 , +18003 , +6977 , +14059 , +21867 , +6249 , +-31913 , +-21491 , +16355 , +-17205 , +20677 , +23313 , +21859 , +-18739 , +14481 , +-31927 , +17273 , +-31581 , +3691 , +30589 , +30373 , +4019 , +-10525 , +29579 , +-23857 , +32111 , +-11239 , +20081 , +-3515 , +30895 , +-31487 , +24819 , +4907 , +-29817 , +3861 , +30893 , +-9349 , +-24157 , +2701 , +12203 , +-17541 , +19219 , +10515 , +-32639 , +-18769 , +-10317 , +-20727 , +-4379 , +6999 , +-7431 , +14125 , +7361 , +-20375 , +26703 , +-18205 , +9173 , +-28159 , +-2067 , +18659 , +-29751 , +29791 , +9263 , +-29581 , +13505 , +-31393 , +-16533 , +22305 , +3711 , +-23443 , +593 , +27381 , +-3089 , +10499 , +12983 , +-11467 , +-31923 , +-4201 , +-7429 , +-11887 , +19121 , +-6879 , +25047 , +-10787 , +8491 , +-14073 , +29371 , +30801 , +1119 , +23963 , +-6495 , +-4551 , +21141 , +-16623 , +11625 , +-3795 , +-18087 , +6393 , +30641 , +-28463 , +-20339 , +29235 , +-32475 , +-6397 , +-9719 , +-14487 , +-25755 , +9883 , +7589 , +11277 , +4435 , +-871 , +-9761 , +10693 , +31469 , +-17427 , +237 , +5741 , +6565 , +19355 , +31315 , +-26483 , +-10951 , +20361 , +-24317 , +4681 , +-3825 , +-31839 , +13801 , +10981 , +4613 , +-15975 , +-24819 , +11959 , +-21297 , +-22233 , +-13529 , +32161 , +29905 , +25265 , +-28233 , +-16383 , +-7313 , +29843 , +-6243 , +6709 , +28651 , +8905 , +-16331 , +5775 , +-28739 , +20787 , +-3353 , +32197 , +5989 , +24643 , +-699 , +-10763 , +5069 , +-963 , +-1629 , +-16363 , +-19431 , +22249 , +-24021 , +-5137 , +23553 , +-15409 , +-18311 , +-9577 , +30377 , +12011 , +-22093 , +10083 , +8701 , +26093 , +-14563 , +-28831 , +19075 , +-21531 , +-5323 , +28505 , +20403 , +-28793 , +-7353 , +-4043 , +-14123 , +31705 , +30089 , +-26105 , +-32169 , +-1167 , +23477 , +-31367 , +19357 , +9773 , +2585 , +-7223 , +-21145 , +12651 , +-25805 , +5437 , +8349 , +-25929 , +-18483 , +1569 , +-8787 , +-6889 , +-11377 , +2617 , +-9119 , +24751 , +-27109 , +-4419 , +7223 , +-2809 , +-14173 , +31437 , +-12999 , +26041 , +-24575 , +5743 , +29017 , +2479 , +-17583 , +-12287 , +-29117 , +27865 , +-20731 , +30771 , +1973 , +-11157 , +29823 , +3203 , +-17825 , +7559 , +-27089 , +10287 , +28463 , +-4477 , +28705 , +-19539 , +-16585 , +-19815 , +23833 , +-30037 , +-7 , +22563 , +10285 , +20605 , +-12223 , +18771 , +-25891 , +11037 , +23943 , +-26781 , +32677 , +-25445 , +-1609 , +-12195 , +-3809 , +13087 , +6551 , +30527 , +19859 , +18265 , +21403 , +-26935 , +-22769 , +-32391 , +30515 , +26271 , +2053 , +23723 , +21687 , +31505 , +25695 , +24849 , +19881 , +30541 , +-28907 , +19509 , +17823 , +-17897 , +3147 , +-8193 , +2957 , +-767 , +6115 , +-28613 , +-11347 , +24101 , +-18277 , +-14723 , +-9791 , +-13223 , +14235 , +-2899 , +-15357 , +19949 , +-11111 , +11761 , +-8597 , +6619 , +3689 , +32295 , +-14707 , +-1145 , +22555 , +-18461 , +-24585 , +-1805 , +-28023 , +-3869 , +26879 , +-19593 , +8829 , +25865 , +-30689 , +31481 , +-1221 , +-2099 , +10705 , +-29787 , +30117 , +3133 , +-31007 , +28201 , +19399 , +-5261 , +-21689 , +-3485 , +-28419 , +29061 , +-10877 , +-17239 , +-385 , +14605 , +1645 , +-8851 , +27773 , +-755 , +-9837 , +27527 , +-12357 , +27001 , +15891 , +-26399 , +-27743 , +4647 , +10219 , +14777 , +-22309 , +-14269 , +-11817 , +13899 , +8301 , +1615 , +-22617 , +-8421 , +-21687 , +-21865 , +28953 , +-25699 , +-10643 , +-18391 , +-10963 , +-5257 , +23413 , +22095 , +-12797 , +12849 , +23991 , +-14719 , +9519 , +17781 , +-5159 , +-30487 , +-28531 , +13767 , +-25111 , +26443 , +-30815 , +18865 , +-22539 , +-24947 , +26987 , +-23671 , +14629 , +-8543 , +2755 , +-30301 , +32593 , +22795 , +17701 , +-14071 , +10009 , +-27189 , +-25061 , +10933 , +-20355 , +18139 , +-24829 , +29507 , +28665 , +-11729 , +-2697 , +-6863 , +-27627 , +-13795 , +-3047 , +-17003 , +1923 , +3173 , +-29711 , +-23727 , +-30793 , +-16487 , +22081 , +-32563 , +-14341 , +-6361 , +-14621 , +-16337 , +-1779 , +-14913 , +7967 , +25113 , +-29393 , +-14759 , +14585 , +-6445 , +-28473 , +9125 , +-15589 , +-32237 , +28531 , +1543 , +1311 , +-28373 , +32159 , +20491 , +-15253 , +-13377 , +7841 , +-11933 , +24971 , +9995 , +-8365 , +6235 , +-14841 , +-7289 , +23843 , +-26163 , +15035 , +-17103 , +20911 , +26529 , +-16717 , +-18887 , +-25887 , +11717 , +-2437 , +29763 , +-26751 , +-21095 , +19451 , +-22509 , +-20399 , +28663 , +22227 , +30671 , +26021 , +-6751 , +9519 , +25525 , +-18061 , +-20935 , +32031 , +-25267 , +19959 , +15807 , +-20883 , +18727 , +4295 , +-26491 , +3323 , +-23785 , +-13723 , +23973 , +-21611 , +31967 , +27229 , +-10241 , +28493 , +3955 , +26589 , +19881 , +4947 , +-26959 , +3785 , +17905 , +13639 , +-20591 , +4439 , +-563 , +537 , +-3867 , +13863 , +-15661 , +-25763 , +-18809 , +31445 , +27831 , +-13021 , +-26849 , +-31973 , +-21187 , +11343 , +31825 , +-21407 , +28343 , +13681 , +-10891 , +-25131 , +-1803 , +-31709 , +-9003 , +-21239 , +5317 , +-17709 , +26463 , +-4345 , +-6681 , +13095 , +14049 , +19943 , +-19583 , +3799 , +18111 , +31469 , +22307 , +-16139 , +2859 , +5405 , +-30157 , +-22567 , +6877 , +-9137 , +-13847 , +-12439 , +15183 , +18641 , +2505 , +29691 , +18287 , +24439 , +-4965 , +23977 , +-5931 , +6711 , +-17443 , +-21461 , +-25719 , +15675 , +-10811 , +11047 , +-3029 , +-3963 , +-13907 , +-14569 , +-24397 , +-2567 , +-9447 , +14999 , +7077 , +-11267 , +8995 , +-29633 , +-30253 , +-13165 , +2165 , +29945 , +-17789 , +-1817 , +17867 , +18145 , +-15815 , +24949 , +14045 , +27795 , +10217 , +27285 , +-23583 , +6411 , +7333 , +28057 , +-15493 , +16373 , +-18973 , +-10657 , +-21695 , +28301 , +-24015 , +-25227 , +-6491 , +-25357 , +20587 , +30375 , +27765 , +-28667 , +365 , +-29677 , +-21805 , +-7249 , +-17317 , +7635 , +-7763 , +21971 , +-25271 , +-8705 , +-31827 , +27023 , +30331 , +24917 , +-10817 , +-1245 , +15389 , +31819 , +-31491 , +-9151 , +12919 , +-7001 , +27437 , +4327 , +22187 , +-4201 , +14773 , +-15173 , +-1561 , +-15287 , +17179 , +-28453 , +1823 , +-9467 , +6899 , +10813 , +-5305 , +8387 , +17501 , +4225 , +-26615 , +-26813 , +-22789 , +21837 , +-26369 , +-13913 , +617 , +5155 , +-19611 , +-4731 , +6199 , +-19781 , +2137 , +2187 , +-15265 , +-32299 , +12689 , +-3445 , +-17347 , +-10597 , +20621 , +-29675 , +11269 , +13425 , +-30631 , +405 , +-5435 , +-24753 , +-9799 , +29417 , +31951 , +-20837 , +-9747 , +-10381 , +-25417 , +30845 , +15331 , +30393 , +-32049 , +-4677 , +-23573 , +-12937 , +-23781 , +-16879 , +-16905 , +14141 , +6601 , +23815 , +3663 , +13441 , +32297 , +16199 , +29899 , +-23239 , +21539 , +-6025 , +-9593 , +-12299 , +-11207 , +-7783 , +543 , +-29325 , +16879 , +12241 , +-3483 , +28861 , +-30513 , +25551 , +-3177 , +17339 , +22497 , +-9827 , +-26849 , +-20399 , +29593 , +16633 , +-15935 , +28141 , +30299 , +1581 , +12377 , +-13397 , +-18581 , +-19605 , +28435 , +-4377 , +-28571 , +-7521 , +-17635 , +-25005 , +-18115 , +-10297 , +-14615 , +-3693 , +-3409 , +23507 , +-10019 , +-17069 , +-18633 , +-4109 , +15501 , +5087 , +10895 , +-3723 , +32369 , +-19903 , +-95 , +-14819 , +27175 , +-20023 , +-29435 , +-22281 , +17181 , +22073 , +-14351 , +12219 , +12243 , +20557 , +23995 , +8341 , +20363 , +19679 , +-23613 , +-20339 , +29321 , +10359 , +-27139 , +-15791 , +-4919 , +-24733 , +-25637 , +15769 , +31539 , +-11691 , +19399 , +5877 , +-19629 , +30583 , +-6877 , +8239 , +-2661 , +4099 , +-18249 , +14613 , +23053 , +-1447 , +14255 , +-1821 , +-28805 , +-18275 , +-7917 , +26637 , +9533 , +17357 , +-14917 , +-7529 , +14189 , +-15535 , +-9523 , +-17669 , +-2665 , +-32481 , +-11603 , +-19087 , +-1031 , +29261 , +-19333 , +-3121 , +-2251 , +11301 , +-5619 , +27103 , +-30069 , +-25143 , +-929 , +29241 , +-3945 , +26173 , +-18799 , +-25705 , +20091 , +7943 , +-6305 , +18099 , +12711 , +29513 , +30997 , +11417 , +12293 , +23375 , +6155 , +25987 , +8889 , +21685 , +8093 , +2091 , +-3249 , +-4365 , +1437 , +-1617 , +29571 , +-31621 , +-943 , +1501 , +14185 , +30797 , +751 , +-10225 , +-5589 , +-12269 , +7307 , +-4987 , +5445 , +-32071 , +-6769 , +4667 , +-11721 , +21379 , +16321 , +-27327 , +24259 , +-28253 , +19627 , +-22123 , +2971 , +-27559 , +28313 , +11897 , +32167 , +19325 , +-30697 , +25161 , +-17999 , +-17241 , +12769 , +-24869 , +-3423 , +-15171 , +8025 , +-18871 , +-28103 , +-2547 , +27017 , +2141 , +29767 , +-5403 , +-1901 , +-6063 , +-13217 , +-6995 , +-15443 , +27455 , +-20971 , +3965 , +8089 , +14051 , +-20559 , +16949 , +-11371 , +26887 , +-24721 , +-27881 , +11487 , +12107 , +-15571 , +-26405 , +-14169 , +10117 , +-25945 , +-20405 , +19593 , +8345 , +-25549 , +7769 , +-14981 , +21455 , +-7183 , +26297 , +-6821 , +-20823 , +19853 , +-20747 , +-10547 , +17731 , +-3989 , +-31221 , +-8251 , +-31457 , +30315 , +-6019 , +-30083 , +16521 , +17689 , +-9999 , +-29469 , +10853 , +-3735 , +25925 , +9881 , +-9587 , +-2581 , +28709 , +11631 , +-3413 , +9095 , +5929 , +-32683 , +31627 , +-15179 , +3431 , +6357 , +4849 , +-5327 , +-15731 , +29453 , +509 , +-8139 , +-20865 , +-31709 , +-11273 , +12087 , +-26271 , +-2237 , +-31317 , +17171 , +14397 , +-5871 , +-6843 , +3539 , +-2537 , +-9819 , +15013 , +-19751 , +16765 , +3327 , +-12237 , +-21595 , +13995 , +4613 , +29761 , +24321 , +-483 , +-22541 , +-29991 , +-23877 , +-18523 , +-17825 , +-14307 , +8165 , +18951 , +-21601 , +11033 , +4485 , +-4337 , +-23081 , +20769 , +21965 , +-11221 , +10843 , +-18017 , +18907 , +-22657 , +-26695 , +4729 , +26597 , +27011 , +-8667 , +9439 , +8191 , +23315 , +6777 , +31393 , +-7355 , +24589 , +20389 , +21521 , +-9827 , +-20885 , +-2383 , +1619 , +14825 , +8661 , +-25299 , +23097 , +-17211 , +3001 , +18983 , +919 , +8631 , +-10263 , +-7759 , +-14047 , +16113 , +23983 , +16071 , +29885 , +-27777 , +13669 , +15315 , +9309 , +-11261 , +-5493 , +24995 , +4955 , +27123 , +25191 , +29915 , +29769 , +23877 , +20241 , +-26121 , +29519 , +-24397 , +1815 , +18361 , +-1787 , +14441 , +-26225 , +-16345 , +17857 , +13123 , +30377 , +18435 , +-645 , +-4473 , +-31529 , +-11073 , +-17377 , +-25581 , +-1451 , +26873 , +-13727 , +-31967 , +-11449 , +-10381 , +2847 , +-3207 , +15449 , +9349 , +-18127 , +25379 , +-13883 , +15901 , +3521 , +-20817 , +-11521 , +16949 , +26411 , +-3105 , +-13633 , +3011 , +2125 , +-289 , +-5221 , +15935 , +2141 , +-15861 , +4389 , +-30831 , +-29873 , +-12267 , +5505 , +20615 , +-9575 , +20683 , +-29833 , +-27689 , +30365 , +26695 , +11539 , +5009 , +-18311 , +-30551 , +-10567 , +-23275 , +7259 , +-22959 , +26301 , +-13425 , +-13217 , +-14697 , +22905 , +22765 , +-31767 , +-7939 , +31211 , +19801 , +25463 , +-29971 , +32459 , +-21205 , +-13061 , +26099 , +-5093 , +-31379 , +-8011 , +-14225 , +4425 , +-10557 , +-19833 , +-26419 , +31689 , +-24845 , +-12335 , +-11451 , +-18915 , +-18225 , +11721 , +-19959 , +-21633 , +-13637 , +6223 , +-4093 , +-30737 , +-1131 , +14665 , +7689 , +27855 , +-22979 , +20603 , +-32097 , +-11785 , +-15487 , +-19497 , +31775 , +-5295 , +17049 , +12389 , +-8835 , +-5393 , +2083 , +25481 , +15741 , +30629 , +-13417 , +9449 , +-20377 , +12319 , +-29893 , +6333 , +-7099 , +-28041 , +-12635 , +683 , +6031 , +8273 , +28587 , +-3813 , +-7561 , +6003 , +8669 , +-9963 , +19087 , +-26917 , +28799 , +-17775 , +6407 , +-30635 , +27389 , +-6823 , +-5273 , +9881 , +-18455 , +30295 , +-2361 , +30685 , +18031 , +-23181 , +-2687 , +-27409 , +22089 , +-1047 , +14197 , +5331 , +3647 , +2851 , +19633 , +29901 , +22815 , +-17393 , +17079 , +-10999 , +16681 , +-12553 , +-5075 , +-7771 , +-32233 , +-23591 , +11035 , +16469 , +-30327 , +-7359 , +-19045 , +23157 , +-25083 , +8093 , +19735 , +-9315 , +25705 , +1819 , +-8191 , +-17215 , +31719 , +15865 , +-29175 , +13253 , +26745 , +31079 , +1747 , +24469 , +-31777 , +-3371 , +15157 , +2239 , +11537 , +-13357 , +-10005 , +20103 , +-4551 , +31327 , +-30517 , +-26491 , +-11987 , +-10803 , +26505 , +-23373 , +-26009 , +-9201 , +-20255 , +2581 , +8825 , +-14445 , +5463 , +1983 , +-31225 , +-29279 , +-19855 , +-1925 , +25667 , +23847 , +9577 , +17111 , +-7203 , +13853 , +-20379 , +7623 , +-18813 , +12629 , +-5577 , +433 , +-11565 , +-28461 , +-3959 , +7695 , +7385 , +12461 , +-27487 , +-21625 , +-19201 , +28761 , +31379 , +29303 , +9611 , +11405 , +-23819 , +24095 , +9881 , +-7793 , +22303 , +29735 , +12429 , +-29163 , +-4127 , +2245 , +-27383 , +28313 , +28343 , +-30897 , +22129 , +10545 , +24961 , +-22703 , +30169 , +-32281 , +2243 , +26151 , +-4229 , +12179 , +14421 , +-25317 , +7611 , +-5841 , +-5475 , +-29709 , +-17773 , +17333 , +-439 , +12299 , +14221 , +30833 , +5763 , +-16393 , +-23483 , +-21539 , +5549 , +9103 , +-9389 , +-13067 , +10903 , +-16247 , +11723 , +-23277 , +-6085 , +29591 , +17719 , +12359 , +24555 , +3581 , +29703 , +-10709 , +-18925 , +12197 , +11405 , +-25793 , +10609 , +-10825 , +-10627 , +-7489 , +1219 , +30137 , +-17709 , +-9989 , +29449 , +-739 , +15965 , +7729 , +-20935 , +-29341 , +8873 , +-13853 , +-32647 , +19619 , +1409 , +24239 , +-28719 , +8885 , +-10529 , +-14683 , +27757 , +-17729 , +32105 , +-4057 , +-9907 , +-24241 , +24933 , +9017 , +18301 , +-10507 , +5689 , +-22695 , +-1067 , +-20651 , +-9639 , +-11813 , +-10459 , +21705 , +9669 , +5315 , +14587 , +-14223 , +-257 , +9749 , +-2869 , +-18737 , +20099 , +-10319 , +-11847 , +-1829 , +-5951 , +-18509 , +-29507 , +6559 , +-31085 , +4409 , +-10895 , +-18353 , +25651 , +26061 , +15665 , +7899 , +-16709 , +-2255 , +-28437 , +-6897 , +-6125 , +31169 , +-27323 , +-2007 , +10605 , +-30913 , +-25251 , +-8469 , +11329 , +-5577 , +-3073 , +-28099 , +8639 , +22989 , +-28835 , +-15817 , +24781 , +-16867 , +1867 , +-8243 , +-19853 , +-27379 , +17903 , +-15663 , +1255 , +-28757 , +-5377 , +17563 , +-17169 , +-5 , +-9861 , +-22759 , +24045 , +12125 , +-6181 , +8303 , +-16315 , +13657 , +10963 , +25345 , +-29087 , +26365 , +-11645 , +31259 , +16425 , +-2383 , +4657 , +-11525 , +19697 , +-9065 , +2691 , +-13705 , +-13315 , +-24745 , +11831 , +-26875 , +15215 , +5507 , +6485 , +-6301 , +-23095 , +-18587 , +21231 , +3491 , +-8743 , +-26273 , +-3755 , +3785 , +2363 , +-22849 , +-26421 , +28387 , +12623 , +13587 , +-13113 , +4505 , +4781 , +-30707 , +2979 , +1879 , +-7393 , +24013 , +-21287 , +-24883 , +17949 , +7109 , +-1605 , +-27875 , +10173 , +-19451 , +30883 , +-20891 , +-18891 , +-9441 , +-7493 , +-18213 , +12741 , +-22921 , +-17373 , +3177 , +-13503 , +11039 , +1717 , +-23363 , +18683 , +13613 , +1851 , +1003 , +-21955 , +-20591 , +-27357 , +-15495 , +-32441 , +-11149 , +-4931 , +10753 , +15301 , +-16891 , +31721 , +-25271 , +4547 , +28641 , +-24229 , +18641 , +-11483 , +-3879 , +-10675 , +-12045 , +19365 , +-29355 , +15029 , +27261 , +30023 , +-9683 , +-1021 , +11973 , +12627 , +-28681 , +-29103 , +1085 , +-16439 , +-10515 , +12323 , +-3183 , +-21159 , +6967 , +-20325 , +16707 , +28645 , +459 , +-4047 , +9143 , +26987 , +-27193 , +5099 , +28117 , +-30329 , +17987 , +-7403 , +1561 , +17765 , +-13141 , +18301 , +-32201 , +7741 , +-27753 , +26659 , +-16601 , +28233 , +-18907 , +22135 , +-12865 , +-19393 , +12241 , +-14831 , +3025 , +5445 , +21703 , +-14617 , +-15935 , +19821 , +10949 , +-1531 , +7321 , +-14677 , +-17817 , +14531 , +-9055 , +3663 , +-3827 , +9861 , +-28545 , +24823 , +11045 , +-23319 , +-19257 , +-31469 , +-243 , +-23931 , +-28653 , +-21553 , +24677 , +15389 , +9123 , +-28525 , +-19475 , +-22433 , +2153 , +-28933 , +-5161 , +-6641 , +-28499 , +-6323 , +17571 , +-23341 , +1565 , +-5775 , +-17805 , +24661 , +23655 , +15977 , +-12569 , +9739 , +12373 , +2123 , +-18571 , +-663 , +27483 , +4279 , +-29633 , +27291 , +25531 , +-16945 , +-28825 , +949 , +-12009 , +1457 , +9457 , +-28551 , +28039 , +6249 , +-27883 , +-21371 , +-25801 , +-1933 , +8981 , +25611 , +-6539 , +-18005 , +-17769 , +-15601 , +-17321 , +-24889 , +-31359 , +-12521 , +11721 , +-12975 , +-14259 , +-7313 , +5925 , +-12259 , +29405 , +-6189 , +-31665 , +-24513 , +-29733 , +22957 , +-22195 , +27787 , +3215 , +-24621 , +18269 , +-10367 , +17713 , +-24393 , +-10611 , +-7215 , +25035 , +4893 , +19409 , +18251 , +10119 , +-32415 , +-11359 , +23641 , +-32115 , +30491 , +22795 , +27129 , +-935 , +-11927 , +12627 , +31281 , +-19817 , +-22115 , +-15363 , +30477 , +-6543 , +-11659 , +-30859 , +-14831 , +-17293 , +24541 , +10779 , +6707 , +17627 , +12565 , +16351 , +-19369 , +25717 , +-2693 , +19551 , +-13759 , +-18961 , +-23621 , +-32399 , +19471 , +-1097 , +-9339 , +2639 , +-16335 , +14925 , +10695 , +15127 , +28133 , +4893 , +-22679 , +31991 , +-29145 , +30681 , +-5505 , +20157 , +-17615 , +20047 , +-15869 , +12783 , +22127 , +7363 , +-19441 , +-9121 , +7413 , +22211 , +-18795 , +-31153 , +-23939 , +25219 , +6799 , +-21251 , +-5417 , +-4431 , +8645 , +8639 , +-9749 , +-20267 , +14075 , +-16993 , +-19927 , +9247 , +16553 , +-28309 , +22911 , +24771 , +1593 , +-5545 , +-25377 , +-23595 , +8121 , +777 , +10789 , +-24679 , +26647 , +-18115 , +30875 , +11365 , +27095 , +8147 , +22509 , +29167 , +-16821 , +17777 , +23973 , +8493 , +-10419 , +1937 , +-5865 , +-10587 , +11123 , +18973 , +-2581 , +15693 , +15563 , +27531 , +29957 , +2527 , +29203 , +19825 , +25607 , +26289 , +14957 , +-13925 , +23363 , +-6131 , +29595 , +-5209 , +-13769 , +-24307 , +-30027 , +-14565 , +-25979 , +28903 , +20321 , +16895 , +29029 , +8407 , +-3701 , +-21521 , +18341 , +27243 , +8607 , +31167 , +-28643 , +32343 , +-13503 , +-633 , +-23383 , +9181 , +25215 , +29501 , +-20069 , +2199 , +15249 , +14805 , +-10309 , +22737 , +-6899 , +-28465 , +-17219 , +14439 , +-867 , +-19883 , +16945 , +13337 , +30269 , +-24107 , +-25847 , +17251 , +-12817 , +-30961 , +30597 , +29399 , +7153 , +-4679 , +32689 , +-12561 , +-31879 , +-15987 , +-11173 , +-22673 , +-3093 , +24297 , +-12661 , +-15565 , +-19309 , +-28699 , +-19075 , +-25455 , +-19751 , +-12829 , +-23783 , +15909 , +2815 , +-24653 , +20195 , +-10187 , +-15533 , +27683 , +-2175 , +-22913 , +12777 , +-26339 , +8869 , +16023 , +1239 , +20277 , +27539 , +-8511 , +25827 , +-17969 , +6153 , +-10943 , +10951 , +7079 , +-21561 , +-26567 , +-24861 , +-28675 , +12921 , +-23041 , +-17549 , +-12267 , +30781 , +-14855 , +26957 , +-10909 , +-6005 , +-15893 , +-20717 , +-20451 , +19387 , +12249 , +19179 , +27209 , +6905 , +25695 , +-20799 , +20327 , +-23885 , +9601 , +-10513 , +28795 , +-21595 , +13831 , +-3197 , +-17241 , +-7619 , +20823 , +23537 , +-31157 , +-19297 , +-20531 , +-15029 , +-13165 , +-8425 , +-21617 , +13045 , +8599 , +24343 , +-25109 , +-26135 , +-31505 , +1195 , +-29403 , +-20893 , +2757 , +23149 , +-15651 , +-11233 , +-22657 , +7173 , +-7461 , +-22257 , +-2111 , +-3297 , +-26003 , +8849 , +23831 , +-19743 , +-32707 , +-19153 , +18177 , +-13859 , +15527 , +32461 , +143 , +8859 , +-28005 , +-5271 , +-9601 , +10875 , +24805 , +-13239 , +2505 , +14141 , +13329 , +22979 , +4801 , +755 , +-32575 , +5987 , +6315 , +30327 , +7811 , +4785 , +-5675 , +31335 , +6951 , +29791 , +8233 , +1695 , +32411 , +-9205 , +11853 , +10279 , +5953 , +32365 , +-20167 , +13749 , +-6455 , +32277 , +-8631 , +-5469 , +18313 , +30371 , +26077 , +-24477 , +25165 , +-19847 , +-23957 , +24185 , +3259 , +763 , +27677 , +-1801 , +-22489 , +-19643 , +26851 , +-2707 , +6369 , +-29345 , +12555 , +28265 , +28193 , +27127 , +8289 , +-21143 , +21065 , +17051 , +11199 , +-19625 , +-9267 , +15981 , +-27865 , +26497 , +-10617 , +-20125 , +-14247 , +-23283 , +7561 , +-31243 , +25077 , +-8461 , +7549 , +2393 , +29445 , +-28041 , +6005 , +-28099 , +7963 , +16415 , +15439 , +-1537 , +-15633 , +9005 , +14463 , +24673 , +-30355 , +24469 , +18541 , +12739 , +-15021 , +-8591 , +27989 , +-6175 , +-6329 , +-28411 , +-9585 , +31997 , +26735 , +21033 , +13173 , +2471 , +-32371 , +7757 , +-20045 , +-31511 , +1681 , +-9753 , +-13279 , +7943 , +16047 , +24177 , +30239 , +11951 , +4355 , +1503 , +-28827 , +10425 , +23967 , +27803 , +-25503 , +-26023 , +-9437 , +-24077 , +24337 , +-25123 , +20699 , +32543 , +26705 , +-15905 , +-31409 , +23723 , +14785 , +-9471 , +-18075 , +-8583 , +4111 , +-18401 , +2033 , +3637 , +-4647 , +12563 , +-32305 , +31823 , +-255 , +-30753 , +24185 , +-24725 , +-4989 , +-27537 , +6441 , +10857 , +14547 , +-19765 , +-11679 , +-28467 , +15537 , +-5163 , +-12783 , +29117 , +-9089 , +20603 , +26151 , +8575 , +-29155 , +-143 , +18861 , +2407 , +-14525 , +-12949 , +24663 , +5717 , +27725 , +2003 , +10921 , +-4693 , +22435 , +18945 , +-2431 , +8389 , +-28279 , +-8971 , +-16327 , +5873 , +20595 , +-26229 , +6203 , +-6675 , +23013 , +-15047 , +-6885 , +-12077 , +-9275 , +-7873 , +23081 , +-23145 , +22075 , +-7065 , +-1389 , +-20217 , +-20997 , +-10437 , +243 , +-32461 , +-211 , +19125 , +877 , +11891 , +18617 , +-24189 , +11337 , +25305 , +-30681 , +-23623 , +-8447 , +-10203 , +24049 , +21767 , +8675 , +-31675 , +-11683 , +-31371 , +-23513 , +11341 , +21207 , +5275 , +-18301 , +-27165 , +32711 , +24405 , +7239 , +3913 , +-7447 , +-12289 , +-7437 , +-31295 , +9769 , +2345 , +24143 , +-7525 , +-7439 , +-23851 , +23297 , +-6505 , +-24049 , +-3541 , +-30289 , +15345 , +9213 , +-11345 , +27785 , +-2363 , +-30263 , +-4099 , +-24217 , +15389 , +30305 , +29439 , +-8089 , +18259 , +-16269 , +-21079 , +-30979 , +-31205 , +-13121 , +-26073 , +1929 , +751 , +10481 , +-17761 , +5497 , +-10737 , +32507 , +19049 , +-6693 , +-11021 , +30957 , +14781 , +23669 , +14405 , +-21177 , +-5133 , +32091 , +28765 , +11225 , +12351 , +-1269 , +-8143 , +-15593 , +27869 , +14597 , +-18729 , +-27151 , +29907 , +-25889 , +-24721 , +6699 , +35 , +30691 , +32685 , +5941 , +16009 , +-29919 , +-831 , +-17015 , +31917 , +14343 , +-293 , +28275 , +21467 , +31617 , +-5355 , +19583 , +23621 , +-7799 , +-13315 , +11325 , +-9811 , +22337 , +8317 , +-603 , +23203 , +12683 , +-30371 , +17901 , +-15803 , +16419 , +3381 , +-15909 , +-19355 , +17715 , +10987 , +-14169 , +-9131 , +-22157 , +29345 , +-30905 , +1553 , +-15179 , +-8899 , +-21421 , +-32261 , +-27897 , +-26033 , +-25515 , +-13549 , +11847 , +-29549 , +-14683 , +-6219 , +-7109 , +11501 , +12991 , +31939 , +16681 , +3031 , +-8677 , +2925 , +-6413 , +-22179 , +643 , +20829 , +-30551 , +-9321 , +-8973 , +17269 , +-7521 , +31647 , +3303 , +-25849 , +1809 , +-28405 , +9273 , +28039 , +-10447 , +-19487 , +32635 , +-14641 , +191 , +-8941 , +-317 , +-16953 , +22567 , +23925 , +-18669 , +-1109 , +-6381 , +13109 , +13351 , +11707 , +-30843 , +30167 , +25297 , +22903 , +25459 , +4259 , +-17461 , +-29865 , +12503 , +-31829 , +-14567 , +-10243 , +-32175 , +-7371 , +-28711 , +10227 , +1075 , +-12867 , +8349 , +-14875 , +-473 , +-28567 , +-24509 , +10067 , +-3785 , +12801 , +10065 , +-6197 , +-21901 , +-25497 , +-6715 , +28319 , +-24059 , +-25455 , +-20107 , +14119 , +-319 , +-3841 , +-27423 , +13163 , +5707 , +7859 , +30351 , +16739 , +-15967 , +17579 , +28897 , +10925 , +24125 , +-23085 , +-3475 , +9929 , +-11351 , +8583 , +16089 , +22475 , +30105 , +21121 , +26665 , +14739 , +6783 , +-29603 , +22691 , +31627 , +16035 , +28541 , +1311 , +15579 , +-29755 , +19355 , +24545 , +8993 , +-25303 , +2217 , +9205 , +17321 , +22577 , +-12709 , +4353 , +22311 , +-20099 , +8721 , +-20579 , +12267 , +13947 , +-19621 , +13873 , +-5475 , +13183 , +-28951 , +-22965 , +-11915 , +-12703 , +-4091 , +-17809 , +27117 , +-4719 , +26765 , +-17281 , +-23291 , +17327 , +-26777 , +-9089 , +-22037 , +22435 , +9599 , +8191 , +13121 , +-7885 , +16695 , +-32281 , +-2353 , +21029 , +20587 , +23257 , +4023 , +-7223 , +4313 , +-22017 , +-7367 , +281 , +-8409 , +22119 , +30687 , +25935 , +23633 , +221 , +-18633 , +-14593 , +10667 , +32325 , +-28141 , +26541 , +-3247 , +-28057 , +32567 , +24551 , +-32481 , +857 , +19609 , +-41 , +1585 , +-25273 , +-17643 , +7269 , +26317 , +16085 , +-9055 , +-24381 , +-21267 , +-31249 , +-21231 , +15509 , +25385 , +13613 , +-8895 , +-31115 , +3633 , +-5733 , +18647 , +27419 , +31949 , +14625 , +3701 , +16625 , +9803 , +-11955 , +-15755 , +22567 , +20351 , +-20809 , +-19421 , +24395 , +11827 , +1231 , +-17047 , +29803 , +-15575 , +-4547 , +-27367 , +15005 , +-23927 , +32181 , +7059 , +-13277 , +25313 , +18253 , +-26101 , +-7933 , +-5483 , +-1447 , +27709 , +535 , +21473 , +9155 , +3227 , +8363 , +-24763 , +-20257 , +-1257 , +27281 , +-4979 , +19141 , +30283 , +-19775 , +29235 , +8751 , +32573 , +18023 , +-5265 , +17349 , +8075 , +-31103 , +-19299 , +3327 , +27183 , +7671 , +20031 , +-9865 , +11951 , +11307 , +32365 , +-32569 , +-10535 , +15393 , +-14123 , +-17189 , +26359 , +24585 , +29999 , +4301 , +6283 , +18775 , +-9161 , +18487 , +-30843 , +-19095 , +13087 , +10007 , +-5633 , +1675 , +-29297 , +25115 , +19051 , +24997 , +19993 , +30589 , +15447 , +10299 , +-17103 , +-32675 , +925 , +10013 , +-345 , +-28011 , +-23011 , +20843 , +7579 , +-13543 , +-8201 , +24635 , +26361 , +-26427 , +29249 , +11945 , +-13713 , +24507 , +-15295 , +10863 , +31205 , +3383 , +20255 , +-20217 , +32633 , +-19473 , +-13273 , +-20173 , +-32275 , +-14113 , +-25223 , +26917 , +28587 , +6315 , +26945 , +-26361 , +18487 , +3443 , +24439 , +549 , +-17373 , +23855 , +8715 , +-30093 , +-9325 , +-18309 , +-14421 , +-9035 , +-29915 , +-28159 , +-3859 , +-8951 , +-2185 , +-27071 , +26639 , +-13815 , +-16613 , +-5135 , +17201 , +25185 , +2823 , +-11051 , +261 , +-6433 , +19865 , +-14573 , +-26609 , +20763 , +-8183 , +-26861 , +-4009 , +-27011 , +13917 , +-13879 , +-16475 , +20449 , +-7701 , +-22627 , +16439 , +-25171 , +6729 , +10169 , +-17927 , +-24477 , +1221 , +19425 , +22077 , +24003 , +29287 , +1233 , +13815 , +27227 , +19545 , +14095 , +17005 , +12191 , +26349 , +-1977 , +-20363 , +9863 , +-3313 , +-25311 , +-20945 , +-8541 , +17977 , +-20581 , +13107 , +10675 , +12531 , +26075 , +27477 , +17343 , +-25655 , +-20077 , +-19499 , +20399 , +-23873 , +32713 , +-23783 , +99 , +-6323 , +16703 , +4841 , +-14767 , +20691 , +21309 , +-23265 , +22929 , +-3177 , +24819 , +-17691 , +-1923 , +22071 , +21839 , +22125 , +13003 , +-12891 , +-2735 , +-8411 , +-26341 , +10139 , +-17689 , +16503 , +10525 , +23447 , +2111 , +23283 , +-12773 , +31317 , +19371 , +16405 , +-12773 , +-27715 , +11243 , +12407 , +31605 , +-13467 , +21775 , +-11125 , +743 , +21383 , +-565 , +-22579 , +-20947 , +-31115 , +-17073 , +3713 , +29471 , +-10605 , +-13921 , +3565 , +10055 , +-13101 , +13933 , +7945 , +12277 , +-12891 , +19565 , +5057 , +1753 , +-9099 , +-28365 , +-31073 , +27419 , +5543 , +-26747 , +-13037 , +-26889 , +5887 , +12341 , +-7135 , +20943 , +3757 , +4989 , +20381 , +14021 , +-22347 , +-25907 , +25565 , +2005 , +-27917 , +-23757 , +-3591 , +25961 , +-12407 , +12319 , +-12671 , +-15751 , +-29217 , +-6451 , +10927 , +-4841 , +-15853 , +-1515 , +14375 , +913 , +13049 , +-24899 , +3883 , +11781 , +13967 , +-24481 , +20307 , +-2951 , +-11017 , +11959 , +29381 , +-30347 , +-30231 , +31613 , +19437 , +-7913 , +23733 , +16571 , +-23111 , +-4943 , +-31055 , +-14419 , +32329 , +-11561 , +24629 , +-30705 , +-11219 , +31751 , +-13285 , +-2051 , +32287 , +19375 , +-9819 , +-23485 , +1329 , +24017 , +-10999 , +10559 , +-1649 , +8473 , +32343 , +9261 , +-17993 , +-23185 , +-24831 , +-19189 , +9255 , +30491 , +-18999 , +-22293 , +11167 , +24141 , +-3785 , +-6967 , +-14891 , +-9407 , +12443 , +10469 , +11437 , +-18729 , +17279 , +-15201 , +-5643 , +32675 , +8091 , +21193 , +-23151 , +19337 , +17753 , +5761 , +11847 , +-27175 , +2749 , +4237 , +-19231 , +-28189 , +1261 , +25899 , +-19979 , +-13811 , +18461 , +10865 , +28185 , +25453 , +-18931 , +14111 , +-23405 , +-8729 , +4861 , +2555 , +14493 , +-22343 , +6445 , +24999 , +29977 , +25503 , +17099 , +-25349 , +-12609 , +9311 , +-32143 , +31705 , +-24345 , +-26385 , +-24039 , +22663 , +-9037 , +24063 , +-32611 , +29067 , +8907 , +25117 , +-6749 , +23549 , +16279 , +-21181 , +9251 , +13923 , +-32269 , +25847 , +17231 , +-19451 , +-7057 , +25821 , +-6631 , +-26423 , +-32517 , +17361 , +-22235 , +-17013 , +18219 , +7553 , +12095 , +13555 , +27877 , +-1913 , +-27557 , +-22325 , +-28257 , +8437 , +32511 , +-30757 , +3095 , +20349 , +-30645 , +7231 , +23177 , +-2817 , +12903 , +8769 , +11623 , +-32093 , +9597 , +-2129 , +1169 , +1649 , +-5329 , +-1101 , +-10483 , +-2965 , +-8041 , +14123 , +-17087 , +29729 , +-26953 , +-6781 , +5547 , +2769 , +22897 , +-2551 , +7187 , +-1547 , +5383 , +7625 , +27467 , +10845 , +20997 , +-28185 , +24929 , +-1073 , +32717 , +621 , +-8611 , +-12007 , +17785 , +-4691 , +21875 , +-20315 , +4449 , +-7147 , +-22339 , +-11877 , +-24811 , +-11127 , +-14475 , +28015 , +-21563 , +-1739 , +-31059 , +-20993 , +-28337 , +31985 , +-21377 , +4141 , +-95 , +28937 , +-23085 , +4843 , +-29503 , +11173 , +-8563 , +-29979 , +21313 , +-22893 , +13381 , +29323 , +22321 , +-2389 , +31621 , +-29011 , +-5729 , +29599 , +-28803 , +-16493 , +-15733 , +-22445 , +-7113 , +22169 , +2395 , +-23619 , +4953 , +18497 , +993 , +-15821 , +23381 , +-27955 , +-23619 , +-30903 , +-30427 , +-20135 , +-21905 , +-24535 , +17535 , +29553 , +-25675 , +-22937 , +13969 , +4391 , +13977 , +-17571 , +825 , +-11339 , +-21287 , +-27647 , +-29511 , +10883 , +20715 , +3389 , +31219 , +-31535 , +-3479 , +-7991 , +30495 , +-14395 , +-24297 , +-28033 , +10499 , +-18169 , +3663 , +11833 , +19115 , +13781 , +17661 , +-4573 , +-4701 , +-29023 , +-4071 , +24983 , +21679 , +-8417 , +-6243 , +11377 , +24829 , +-17683 , +15359 , +-2325 , +2533 , +1689 , +30755 , +-23051 , +-10467 , +21829 , +20959 , +29705 , +-10895 , +-23875 , +-32539 , +647 , +-519 , +-15861 , +-3003 , +-1143 , +-30759 , +22673 , +7773 , +23621 , +7277 , +-16987 , +-28835 , +-45 , +26127 , +-26973 , +-27089 , +-32105 , +-3773 , +-30841 , +8191 , +5645 , +-10127 , +-12281 , +-29145 , +23851 , +12835 , +11559 , +-17747 , +-5843 , +-17987 , +-10409 , +-7367 , +28407 , +-21849 , +-2809 , +-19827 , +19691 , +17949 , +22973 , +8319 , +31035 , +-1203 , +-5713 , +24687 , +28875 , +-21981 , +31201 , +-27073 , +15997 , +-1929 , +-31567 , +-30261 , +13079 , +12745 , +-29957 , +4323 , +25997 , +-22153 , +31141 , +26561 , +-27677 , +6003 , +-5179 , +12289 , +31873 , +-6273 , +-24275 , +19993 , +18443 , +-3353 , +391 , +23891 , +7095 , +-25423 , +1007 , +-3519 , +27695 , +-14247 , +21259 , +25533 , +10455 , +-23795 , +1437 , +21075 , +22457 , +-18591 , +-15449 , +-22965 , +14799 , +17287 , +-20495 , +15373 , +-28703 , +18947 , +-4553 , +-2257 , +6103 , +21743 , +7595 , +29657 , +-9573 , +25513 , +-24545 , +3783 , +25195 , +-1271 , +1427 , +31685 , +29103 , +-12255 , +29775 , +-23913 , +21075 , +1397 , +25979 , +-1401 , +21925 , +29353 , +-29127 , +7243 , +-25441 , +-4413 , +19771 , +-15741 , +-16175 , +5343 , +29915 , +-3917 , +30117 , +31593 , +-13901 , +30909 , +-17843 , +-10799 , +3511 , +-26929 , +-19451 , +-1851 , +-4147 , +-9243 , +-14085 , +14573 , +-18465 , +7873 , +5025 , +7195 , +1913 , +-21673 , +-14713 , +-10995 , +-31005 , +26835 , +-26451 , +-32357 , +-10575 , +11789 , +-11675 , +-23691 , +-25119 , +-899 , +4767 , +-13477 , +3187 , +22963 , +25805 , +-4401 , +-21889 , +32599 , +-16589 , +24661 , +-13365 , +-26217 , +-32317 , +-7639 , +32746 , +-13273 , +3443 , +-13453 , +22217 , +13745 , +3091 , +-18431 , +-11821 , +-22057 , +-32597 , +-17791 , +-9853 , +22945 , +14413 , +-30409 , +3963 , +8827 , +-19597 , +-25291 , +21789 , +-17489 , +8141 , +-17389 , +24229 , +31313 , +31401 , +-7125 , +-21825 , +-7223 , +29623 , +4939 , +-18785 , +-14661 , +10357 , +-8211 , +-14695 , +4743 , +20469 , +23795 , +6971 , +9539 , +-4283 , +16355 , +-5403 , +-14293 , +11833 , +-15981 , +-2087 , +-27999 , +25807 , +12647 , +6881 , +-5219 , +-1793 , +-19697 , +-26021 , +25005 , +9493 , +7863 , +-23079 , +-28311 , +16009 , +31677 , +-12751 , +21101 , +-27303 , +3573 , +-11749 , +25291 , +-31775 , +27989 , +-26805 , +18699 , +-14547 , +-24525 , +-22527 , +-23393 , +-18469 , +-20487 , +3369 , +-23333 , +31591 , +-20381 , +-8979 , +-8593 , +-14831 , +-20173 , +21969 , +14171 , +17701 , +-28059 , +-8633 , +8553 , +18917 , +13043 , +-16179 , +-9429 , +-13105 , +-3585 , +-899 , +-4249 , +24963 , +-1387 , +561 , +-21733 , +13075 , +20957 , +-18931 , +-15895 , +-24353 , +8153 , +-29283 , +-9957 , +-27671 , +10903 , +8819 , +12565 , +9393 , +-1045 , +4405 , +9545 , +-22131 , +-22103 , +32057 , +-17735 , +-14979 , +-18341 , +4259 , +-2839 , +-28791 , +4217 , +-12047 , +10577 , +27279 , +32291 , +-24545 , +2405 , +-23127 , +-19627 , +-15819 , +-25861 , +31991 , +17573 , +16229 , +-10415 , +-27899 , +-26509 , +31393 , +10365 , +31379 , +16555 , +-11081 , +32105 , +26875 , +-18703 , +-19485 , +11337 , +-22269 , +-3227 , +-14363 , +23443 , +-6605 , +-10795 , +-7513 , +10615 , +-5965 , +-9871 , +15683 , +18903 , +-9829 , +2827 , +-32343 , +21187 , +-22571 , +-17973 , +28847 , +28523 , +-23189 , +-9623 , +31913 , +-20069 , +-2715 , +-27423 , +12425 , +-18005 , +-7649 , +-2897 , +-17553 , +-4855 , +-19421 , +13187 , +30915 , +-3301 , +8577 , +-27007 , +-13107 , +-20281 , +-4705 , +21995 , +11727 , +31333 , +-11875 , +-30869 , +-20069 , +-19403 , +17703 , +-32067 , +-2133 , +-26275 , +16331 , +-18201 , +-14407 , +24923 , +-29993 , +30207 , +15579 , +31743 , +-17495 , +-31407 , +-10989 , +7143 , +28305 , +12323 , +15723 , +-14479 , +-9697 , +-28947 , +12949 , +10291 , +21251 , +-23291 , +19955 , +-12037 , +-10149 , +16105 , +5947 , +12861 , +16539 , +2791 , +12939 , +29971 , +7893 , +-7075 , +771 , +29871 , +-1897 , +-13967 , +-26149 , +-29099 , +-7095 , +29511 , +18937 , +32725 , +10235 , +2231 , +-18417 , +3203 , +-3903 , +-7287 , +-16595 , +-24405 , +-17779 , +-8145 , +477 , +-21621 , +-32631 , +12277 , +32695 , +-6193 , +19941 , +9661 , +1919 , +19071 , +18233 , +-2755 , +-8777 , +-12153 , +-15271 , +-9045 , +28603 , +-7523 , +-27985 , +-20223 , +27479 , +-30779 , +-2031 , +17579 , +4831 , +7749 , +-29163 , +-24377 , +9671 , +-11489 , +-29199 , +-30505 , +13757 , +-28667 , +-23339 , +16635 , +-16321 , +-26665 , +-5965 , +3759 , +-6987 , +-30319 , +1447 , +27637 , +3843 , +465 , +15309 , +25885 , +28329 , +-27963 , +17805 , +6385 , +-28071 , +19105 , +-16767 , +-11405 , +9 , +-32605 , +8905 , +-17643 , +8593 , +8317 , +-289 , +-30611 , +24005 , +11353 , +26605 , +16495 , +-18937 , +-21179 , +21685 , +26921 , +-16289 , +-13767 , +-4399 , +-20235 , +22041 , +15745 , +29855 , +-32717 , +-12585 , +-8001 , +-15473 , +28037 , +8239 , +-30881 , +8959 , +3197 , +-17987 , +-8305 , +26513 , +3811 , +30141 , +-28231 , +1795 , +12385 , +30245 , +22133 , +13445 , +-6977 , +17979 , +15117 , +-25191 , +16543 , +6315 , +-13211 , +-8349 , +5295 , +31271 , +24707 , +19585 , +-19613 , +20597 , +13947 , +7015 , +22829 , +32267 , +-23315 , +-27335 , +-20677 , +557 , +3833 , +23835 , +24739 , +-4741 , +-10305 , +26639 , +14885 , +779 , +3149 , +-17077 , +-13219 , +24075 , +-997 , +-26861 , +2175 , +-3125 , +30729 , +-1009 , +-12399 , +19039 , +-4151 , +26915 , +-5097 , +15281 , +9705 , +-23609 , +28251 , +7453 , +-19911 , +19679 , +-7397 , +9097 , +2769 , +19479 , +23747 , +23545 , +19329 , +-21581 , +-14553 , +4265 , +29645 , +-785 , +32183 , +-3415 , +21347 , +-9007 , +-25541 , +-8211 , +-8943 , +-20089 , +523 , +-25105 , +6211 , +14389 , +32705 , +24763 , +26871 , +-1189 , +10109 , +30355 , +26165 , +18849 , +14221 , +-4097 , +-2299 , +-15051 , +-26701 , +-25497 , +-4625 , +9119 , +24791 , +13101 , +-9497 , +13857 , +26429 , +323 , +19409 , +-11645 , +16193 , +-3261 , +13167 , +-19337 , +-19315 , +21513 , +-20767 , +-4247 , +11219 , +6085 , +-7783 , +2263 , +-6397 , +2975 , +8145 , +21295 , +-23549 , +-15935 , +8073 , +-24283 , +-29211 , +-28167 , +26617 , +-5755 , +-1881 , +-31031 , +-18549 , +-3183 , +-8353 , +-28917 , +-26539 , +-23589 , +-25343 , +-13315 , +-9453 , +403 , +-10359 , +21467 , +12435 , +-29589 , +5565 , +16639 , +-26181 , +-1305 , +-2209 , +25967 , +-6659 , +-1735 , +-30741 , +31485 , +-1975 , +151 , +-23609 , +10201 , +2701 , +-8431 , +-6139 , +-20563 , +-22617 , +2031 , +9359 , +-22223 , +-27677 , +17541 , +-14099 , +-28599 , +23531 , +-8823 , +17261 , +-29545 , +-15801 , +-11025 , +-13589 , +17559 , +-15537 , +18495 , +-29953 , +5429 , +26535 , +-27791 , +-21835 , +-31259 , +7479 , +19515 , +9673 , +20797 , +-12643 , +-21001 , +-3999 , +-9721 , +28975 , +-29203 , +23867 , +25827 , +16745 , +28723 , +15985 , +-4519 , +26089 , +-11001 , +-18261 , +-2707 , +12527 , +22177 , +16593 , +4799 , +-18363 , +-20595 , +-17325 , +-19423 , +-1085 , +16771 , +15313 , +-11095 , +21059 , +13507 , +18525 , +2383 , +21785 , +-14365 , +15147 , +-17911 , +527 , +-6089 , +-26667 , +-8365 , +19413 , +-21867 , +-7935 , +7259 , +-12033 , +-17215 , +-8273 , +-29301 , +-3717 , +26421 , +-11043 , +9127 , +-1397 , +14209 , +-29235 , +-7327 , +-24259 , +-5343 , +-11599 , +-7817 , +-31909 , +-19749 , +10225 , +21317 , +-6415 , +26249 , +22997 , +-29727 , +28729 , +-16001 , +-13623 , +15791 , +1561 , +16221 , +-1011 , +-10111 , +-25319 , +-20123 , +18669 , +23587 , +8411 , +9303 , +19585 , +30589 , +13333 , +11977 , +-5669 , +19493 , +-249 , +16381 , +28355 , +-20865 , +-15245 , +1845 , +-14091 , +14923 , +29973 , +-29801 , +17869 , +5055 , +-1635 , +3191 , +-11125 , +-21207 , +27429 , +16951 , +17155 , +26873 , +-3543 , +6051 , +27861 , +28771 , +-31747 , +29627 , +-10965 , +-27023 , +14031 , +11289 , +-23827 , +-24671 , +25617 , +-18493 , +30585 , +-14859 , +20855 , +-17789 , +6105 , +-11887 , +-26509 , +187 , +24709 , +-25129 , +1067 , +971 , +31627 , +25329 , +7657 , +-28969 , +-11949 , +-25611 , +8221 , +-25557 , +-21549 , +-7811 , +-30763 , +783 , +1099 , +-28491 , +-853 , +3615 , +29555 , +-26881 , +-14519 , +-28121 , +-17345 , +14851 , +-29095 , +-25231 , +-5873 , +13385 , +-28161 , +22441 , +29547 , +-427 , +7633 , +10799 , +28213 , +-25547 , +26963 , +-14103 , +10861 , +-14427 , +-24855 , +13229 , +20059 , +-12641 , +16719 , +18435 , +-10415 , +-391 , +-22631 , +-1141 , +-545 , +-3211 , +-14429 , +-10537 , +29833 , +-23329 , +1801 , +-14157 , +-1787 , +-31325 , +19109 , +-5617 , +-20497 , +-28311 , +-895 , +19023 , +17149 , +-25051 , +16469 , +23585 , +14787 , +-13769 , +3705 , +6873 , +-31523 , +24315 , +27997 , +-32697 , +-19537 , +-21 , +-32375 , +25359 , +-13153 , +32301 , +-21493 , +21889 , +16327 , +10419 , +28535 , +-25355 , +-5075 , +-3891 , +21335 , +-9827 , +-20607 , +15173 , +32301 , +30431 , +30803 , +-18957 , +15841 , +31789 , +21187 , +2523 , +14015 , +-10657 , +26565 , +-15935 , +28911 , +-20085 , +26323 , +15677 , +-919 , +-1193 , +21029 , +2141 , +25459 , +-23079 , +9573 , +28597 , +-23663 , +-15637 , +20213 , +-22279 , +-6907 , +4099 , +29587 , +26649 , +-22335 , +2699 , +29859 , +14543 , +-23325 , +9405 , +12509 , +29893 , +1963 , +13039 , +-2169 , +11807 , +22773 , +-22145 , +9775 , +-6499 , +-19923 , +-15595 , +-5923 , +27441 , +-31541 , +10125 , +-27433 , +-21487 , +-22711 , +11075 , +-27187 , +-5801 , +-8035 , +16113 , +26003 , +3091 , +-21971 , +-22521 , +-31135 , +-31769 , +24651 , +6527 , +-2173 , +-32481 , +-26323 , +17723 , +7313 , +-7355 , +-9635 , +-557 , +-28881 , +-19395 , +25793 , +249 , +-11461 , +-30759 , +20227 , +589 , +25997 , +-26633 , +-22897 , +3757 , +7461 , +-2795 , +-12525 , +-8169 , +22257 , +-23709 , +-10139 , +14849 , +-7173 , +-915 , +781 , +-6617 , +12835 , +11551 , +11059 , +27119 , +-22699 , +10343 , +21019 , +3127 , +-22713 , +-6579 , +-489 , +17333 , +15279 , +18313 , +-22263 , +9673 , +-10509 , +30105 , +-2733 , +-4649 , +10607 , +5987 , +-7853 , +13607 , +-32481 , +12861 , +-20139 , +-3287 , +-21533 , +3985 , +-14315 , +-8605 , +-11219 , +-271 , +9647 , +17853 , +20545 , +19631 , +-15077 , +-1445 , +-9241 , +17659 , +-28641 , +25077 , +13477 , +-25749 , +8655 , +18865 , +-28547 , +3879 , +3973 , +-28299 , +-6375 , +-23693 , +-4017 , +18381 , +-31349 , +17613 , +-9489 , +20015 , +-7033 , +12927 , +-28073 , +7651 , +14611 , +1221 , +6291 , +-15017 , +-18491 , +-22701 , +-8113 , +-18961 , +635 , +8311 , +21703 , +31341 , +-18287 , +31923 , +-4025 , +-4683 , +-24167 , +-18737 , +-26347 , +2613 , +27283 , +-2955 , +31991 , +-5701 , +28069 , +-4285 , +8995 , +3523 , +31831 , +-7571 , +-4929 , +-30633 , +9281 , +-11059 , +-17463 , +7529 , +26193 , +-26753 , +-1883 , +-2907 , +22647 , +20723 , +-20989 , +-3127 , +-22045 , +-4975 , +-3235 , +22917 , +-32327 , +18115 , +24049 , +-20279 , +-20401 , +28055 , +-20423 , +-19295 , +-21793 , +-12847 , +32738 , +15509 , +18883 , +-23417 , +2621 , +-13967 , +-16083 , +-29383 , +-4281 , +-13657 , +-13225 , +-31645 , +2833 , +13353 , +-31925 , +13983 , +9663 , +31933 , +-11513 , +-3019 , +-19967 , +-25391 , +4171 , +8499 , +21003 , +9693 , +-25413 , +31243 , +23305 , +2609 , +5799 , +1189 , +3865 , +11605 , +2877 , +1535 , +-14907 , +21725 , +-23743 , +-11209 , +-17669 , +-28225 , +16965 , +-8911 , +-17281 , +-17873 , +-28573 , +-18007 , +28141 , +3061 , +-6543 , +-23349 , +23335 , +-28855 , +-27457 , +12363 , +-28333 , +21027 , +-953 , +-29441 , +-2477 , +5143 , +-3475 , +16369 , +5817 , +31411 , +26419 , +-25597 , +-23995 , +26189 , +-14863 , +-10247 , +20179 , +32607 , +2189 , +6425 , +23009 , +-27549 , +-2765 , +19011 , +24701 , +-8155 , +32401 , +6025 , +-14917 , +-12131 , +-16763 , +-6591 , +24505 , +26187 , +-31899 , +8613 , +-23799 , +-15353 , +-6237 , +-19483 , +1205 , +1889 , +-5097 , +965 , +-13653 , +369 , +-29525 , +20141 , +705 , +-6085 , +18333 , +-18615 , +-10201 , +-26503 , +-28887 , +-8035 , +-163 , +32764 , +7635 , +28059 , +28847 , +-14209 , +-23281 , +15681 , +10541 , +-9467 , +-12671 , +-17621 , +10779 , +-11345 , +1975 , +7343 , +28409 , +-501 , +4181 , +-7565 , +4585 , +-3589 , +-15647 , +30341 , +22197 , +26881 , +4069 , +16115 , +-11199 , +25631 , +-23625 , +-795 , +29825 , +-17881 , +11947 , +-12237 , +-32013 , +-22885 , +-14389 , +-18563 , +-32355 , +28931 , +25105 , +-6973 , +-903 , +-15171 , +-13287 , +-16767 , +4981 , +-11933 , +12897 , +-6849 , +-3345 , +-13417 , +-25601 , +5551 , +-3425 , +-6559 , +22997 , +16197 , +-27873 , +23811 , +-8117 , +-22709 , +4565 , +-23207 , +903 , +28799 , +-13449 , +25253 , +3627 , +24355 , +9467 , +12529 , +-21889 , +12701 , +13073 , +-7963 , +5689 , +25993 , +-10211 , +15387 , +-26453 , +-16041 , +-28499 , +-5639 , +-19591 , +31325 , +-22929 , +-29429 , +1503 , +20337 , +431 , +-20263 , +23125 , +28673 , +20811 , +-24511 , +-10535 , +-30801 , +-16085 , +-17335 , +-14437 , +-14749 , +-2249 , +27523 , +-961 , +15591 , +-28969 , +14805 , +12169 , +26105 , +-13601 , +16607 , +29087 , +13293 , +-18927 , +28877 , +3263 , +31421 , +27155 , +-11857 , +-9103 , +3749 , +-19229 , +21839 , +-28859 , +28471 , +-11053 , +20879 , +-13553 , +22263 , +-32003 , +15163 , +-21617 , +1905 , +1089 , +-18075 , +-27713 , +-22061 , +30903 , +-22211 , +-13961 , +-25599 , +8617 , +10851 , +-11343 , +561 , +-10739 , +19399 , +4925 , +29955 , +23935 , +28925 , +-29189 , +9235 , +-5717 , +2069 , +25741 , +17691 , +26205 , +-22541 , +-5479 , +10115 , +-10271 , +12073 , +-9865 , +-15239 , +-32760 , +-1205 , +-27279 , +9103 , +419 , +-12083 , +-651 , +27599 , +14957 , +-29867 , +-17071 , +-1711 , +2963 , +11925 , +-26009 , +20313 , +-14177 , +28581 , +-19731 , +16107 , +-31497 , +20187 , +10139 , +6623 , +-2089 , +-9699 , +10215 , +19075 , +11971 , +-20543 , +-10049 , +10155 , +-14723 , +23011 , +3521 , +23885 , +-7543 , +6709 , +19695 , +-15981 , +-25829 , +15971 , +5355 , +-4481 , +6543 , +-27419 , +-8787 , +30707 , +7013 , +6743 , +-13383 , +5723 , +5047 , +30545 , +-29215 , +-25167 , +-23755 , +26301 , +23915 , +6441 , +-24939 , +-25417 , +-26405 , +-7367 , +23441 , +17883 , +-3805 , +4667 , +31837 , +-18651 , +-24231 , +4479 , +-3677 , +26177 , +-22285 , +-16663 , +27377 , +-15765 , +-32645 , +-6911 , +-4673 , +1477 , +16591 , +27027 , +-13605 , +-26841 , +-19253 , +2243 , +-21917 , +5253 , +19859 , +-2909 , +-6587 , +-25159 , +28987 , +12627 , +-5327 , +30695 , +7175 , +1419 , +-10229 , +-24243 , +19491 , +22467 , +5107 , +28061 , +12247 , +20417 , +4781 , +-15659 , +-29115 , +5297 , +-95 , +3739 , +25243 , +-57 , +-30895 , +-29683 , +8653 , +6981 , +30547 , +-3551 , +-23857 , +17957 , +27847 , +8823 , +8523 , +-11225 , +18767 , +-3915 , +21211 , +619 , +-22905 , +-26019 , +1721 , +6285 , +-1 , +1831 , +18441 , +-29131 , +-13393 , +27091 , +31355 , +3381 , +14583 , +22923 , +27025 , +-22495 , +-12789 , +-1101 , +-15785 , +7525 , +-25611 , +22083 , +-4207 , +32473 , +16647 , +25249 , +-12161 , +5605 , +29145 , +-1803 , +16911 , +-9203 , +16573 , +11269 , +-3441 , +24591 , +-9293 , +11663 , +30711 , +28535 , +-1813 , +21269 , +8329 , +23741 , +-22093 , +21319 , +30239 , +14807 , +-13319 , +21451 , +-5163 , +-8365 , +-11721 , +-8291 , +-20921 , +6131 , +6647 , +24039 , +3653 , +-14143 , +-30525 , +8535 , +32275 , +28065 , +-22627 , +-22537 , +-26347 , +-15753 , +-2815 , +9093 , +11793 , +-3913 , +-23219 , +-7605 , +-15389 , +6519 , +-30267 , +-20357 , +-28489 , +-27627 , +22027 , +-13823 , +23483 , +-18111 , +-1011 , +29915 , +16737 , +-27997 , +22151 , +-9223 , +-11761 , +18149 , +-9735 , +17035 , +-31911 , +-26027 , +-31717 , +10207 , +-5193 , +23543 , +-15911 , +29625 , +-16185 , +5923 , +-31801 , +17189 , +4087 , +-7789 , +14621 , +28123 , +-22075 , +-25077 , +-5841 , +23559 , +14199 , +-29857 , +9059 , +17585 , +-3247 , +30745 , +-601 , +27783 , +31563 , +29319 , +-9875 , +32065 , +-18867 , +19803 , +10021 , +-29327 , +17385 , +-12097 , +-8151 , +-3877 , +28299 , +-4117 , +-4281 , +26965 , +6199 , +-9403 , +16297 , +-12267 , +-26177 , +18155 , +-21929 , +-12401 , +3195 , +-16933 , +31275 , +-14899 , +-2427 , +22915 , +-16827 , +26435 , +-11927 , +-18989 , +8975 , +14889 , +25445 , +31201 , +-30295 , +-32167 , +25371 , +19709 , +5605 , +-19045 , +24011 , +-28607 , +-5439 , +4231 , +22545 , +-19273 , +19805 , +25559 , +8463 , +-31259 , +26229 , +-19899 , +-12235 , +16615 , +23125 , +-18723 , +25965 , +-12271 , +-4267 , +-5159 , +985 , +761 , +31439 , +10741 , +-16629 , +6937 , +19609 , +30795 , +29369 , +-31519 , +20729 , +9385 , +-25351 , +5461 , +8481 , +-17299 , +-19723 , +-23523 , +14885 , +-555 , +-6103 , +23079 , +-28043 , +23005 , +-8171 , +-29517 , +17871 , +7829 , +17019 , +31989 , +-28733 , +-7685 , +-22003 , +-11221 , +-13155 , +17745 , +-6733 , +13363 , +-18203 , +-22285 , +1079 , +-19297 , +-22697 , +-5961 , +8833 , +-23465 , +-6823 , +-18247 , +29779 , +26535 , +1523 , +-17731 , +32635 , +-13599 , +19271 , +-7163 , +397 , +-24211 , +-6515 , +19363 , +30749 , +2399 , +18049 , +-1701 , +-15501 , +11161 , +11367 , +-13073 , +-9269 , +-12197 , +-16515 , +5637 , +4355 , +-24479 , +22255 , +-2959 , +-13097 , +27251 , +12889 , +6423 , +20381 , +17797 , +-10057 , +-193 , +24437 , +-6329 , +21983 , +13931 , +25099 , +1861 , +3707 , +-11081 , +-10045 , +9853 , +25215 , +-22107 , +-18563 , +-27791 , +-10721 , +18817 , +-29243 , +711 , +-1713 , +-30417 , +-1393 , +-27555 , +-14927 , +-32117 , +25195 , +-25377 , +-21743 , +-18117 , +24641 , +3045 , +609 , +30731 , +-6007 , +-14715 , +7977 , +-317 , +-26881 , +-12691 , +-18549 , +-26495 , +7901 , +-29311 , +-9557 , +12941 , +21913 , +7653 , +11701 , +-29773 , +-12273 , +-6493 , +-22707 , +-27615 , +-30137 , +25791 , +-32373 , +5553 , +-28247 , +30919 , +-26001 , +15569 , +10671 , +4343 , +-1313 , +6609 , +25381 , +-30773 , +-17383 , +-19781 , +-25127 , +-28907 , +941 , +-16975 , +-4899 , +-103 , +19961 , +-25665 , +-10953 , +25891 , +-16615 , +-21447 , +24345 , +-24799 , +-19863 , +-28535 , +-3679 , +28087 , +16495 , +30871 , +-3835 , +17243 , +-3225 , +3981 , +-26791 , +13037 , +25123 , +8513 , +-71 , +21067 , +-5733 , +-28669 , +-9205 , +26987 , +15569 , +-19721 , +-13007 , +17911 , +853 , +-19217 , +-10809 , +-29859 , +15931 , +3007 , +-8365 , +22383 , +-21619 , +-24549 , +-13817 , +-27785 , +-8115 , +-16919 , +-273 , +18895 , +20709 , +25885 , +-851 , +-10249 , +29 , +4875 , +-10569 , +21811 , +3233 , +-25525 , +7939 , +1441 , +-11035 , +12035 , +12875 , +12745 , +-5711 , +5579 , +24251 , +15041 , +-30967 , +21241 , +-8913 , +17087 , +-13393 , +-21371 , +5357 , +16943 , +26389 , +16475 , +8659 , +-7859 , +-2597 , +14639 , +5403 , +-4541 , +-15171 , +-17441 , +-6003 , +-14411 , +12825 , +-23229 , +-25551 , +-27675 , +26077 , +12423 , +30359 , +-25535 , +-26627 , +7683 , +-8319 , +-23167 , +-25225 , +29333 , +-13029 , +-25537 , +-3139 , +26487 , +15297 , +28173 , +695 , +-23909 , +-22491 , +26377 , +-13001 , +20343 , +1045 , +-5117 , +-14349 , +12399 , +7595 , +-5887 , +3831 , +16539 , +-3833 , +-13207 , +-20059 , +-465 , +-9079 , +26255 , +19753 , +-2747 , +12169 , +-31283 , +-21135 , +-23741 , +2953 , +-22751 , +-21339 , +19107 , +4083 , +-27839 , +2339 , +-12455 , +-14253 , +16435 , +27117 , +13219 , +21769 , +-12443 , +18861 , +-12953 , +18049 , +69 , +39 , +-13309 , +8947 , +-4259 , +-24017 , +9901 , +-29039 , +31201 , +-4061 , +-29883 , +-29117 , +7635 , +2793 , +26035 , +-8987 , +-20843 , +10073 , +-26699 , +-13579 , +-18945 , +-1977 , +-1725 , +-24369 , +-9733 , +1769 , +14691 , +-1177 , +7835 , +-20001 , +14201 , +7041 , +23731 , +2715 , +27947 , +-24731 , +-15121 , +18795 , +-32589 , +-24805 , +-14489 , +4063 , +-26703 , +-23775 , +14277 , +12749 , +-32109 , +28067 , +1481 , +15561 , +22623 , +3637 , +25201 , +30229 , +-25843 , +14343 , +-22129 , +-30945 , +31847 , +21153 , +-6189 , +-28555 , +23383 , +15641 , +21881 , +-9405 , +4549 , +15311 , +-25265 , +-7865 , +10989 , +2203 , +18517 , +-7351 , +-26055 , +32147 , +9681 , +-14831 , +2711 , +-11725 , +2029 , +28133 , +24145 , +-7389 , +-21299 , +20605 , +30565 , +31851 , +11295 , +30075 , +-8097 , +7717 , +-16063 , +-25247 , +28077 , +13243 , +18889 , +-14577 , +28541 , +13727 , +20655 , +-13385 , +-29681 , +-21119 , +-555 , +18771 , +-9585 , +-27387 , +-15831 , +-27743 , +22127 , +1793 , +6197 , +-7267 , +17213 , +-17615 , +12607 , +32111 , +-26371 , +17515 , +-6435 , +1263 , +4347 , +-30365 , +-14065 , +-18285 , +-5329 , +28629 , +-24365 , +-13587 , +1031 , +12869 , +16191 , +-27993 , +21189 , +22585 , +-3811 , +-14101 , +26719 , +-14101 , +28411 , +-29071 , +1735 , +-3967 , +-24117 , +28383 , +26831 , +28621 , +5111 , +6875 , +21121 , +20089 , +26361 , +4201 , +-32275 , +10187 , +-23183 , +-5639 , +-26485 , +18903 , +-13883 , +-29743 , +5391 , +16179 , +20781 , +-6135 , +30147 , +-17609 , +13145 , +-28411 , +7003 , +24755 , +5753 , +-11669 , +1105 , +23331 , +6117 , +-30561 , +-1861 , +16999 , +295 , +28335 , +16035 , +16643 , +16801 , +6877 , +28385 , +-2865 , +-31593 , +24967 , +-32145 , +561 , +15311 , +22183 , +-20407 , +-11817 , +-2389 , +-23091 , +13239 , +28907 , +-8775 , +30861 , +-27853 , +3023 , +10961 , +-23675 , +32701 , +-1197 , +-2643 , +20937 , +-6995 , +-9105 , +11519 , +-6435 , +16403 , +-21893 , +5127 , +20279 , +-9335 , +21469 , +7343 , +30505 , +-625 , +-16043 , +30245 , +8289 , +-21663 , +-14431 , +10217 , +-12831 , +4943 , +-1087 , +4463 , +-393 , +14233 , +-7765 , +-22987 , +28077 , +-3653 , +28037 , +-16807 , +-27825 , +-6567 , +20311 , +21421 , +6485 , +-32383 , +333 , +-31911 , +-32663 , +-27753 , +4199 , +-21525 , +-21807 , +-22887 , +-26703 , +-15 , +-31249 , +-23541 , +26115 , +25877 , +-30151 , +-7361 , +-14803 , +-2133 , +18863 , +14393 , +25019 , +2773 , +-15151 , +6909 , +13863 , +-747 , +-16865 , +32621 , +5263 , +-18077 , +-15353 , +30111 , +-23571 , +15561 , +10595 , +10935 , +24027 , +-1927 , +-23441 , +25149 , +32181 , +26729 , +-13249 , +-11 , +23145 , +-18849 , +11457 , +-17867 , +8861 , +-15973 , +10533 , +-29497 , +29551 , +25311 , +25829 , +1071 , +-15957 , +17681 , +-5331 , +-1641 , +3459 , +10831 , +-13085 , +-10471 , +-10037 , +-2683 , +27925 , +-867 , +-10327 , +20619 , +13297 , +23851 , +21459 , +18103 , +-8123 , +-4915 , +-17847 , +-21511 , +12139 , +-2335 , +19331 , +-22415 , +5069 , +-2833 , +26165 , +16517 , +12757 , +-507 , +25727 , +12671 , +-9371 , +26251 , +-31833 , +-1373 , +16855 , +-22365 , +-12717 , +27327 , +5741 , +11509 , +-32447 , +-30127 , +20811 , +3091 , +-7559 , +14865 , +22253 , +24647 , +781 , +24083 , +13351 , +16371 , +25421 , +-4773 , +10387 , +-1947 , +-3715 , +-16907 , +14225 , +-24277 , +23315 , +25999 , +-2119 , +-24585 , +10345 , +1677 , +22743 , +13545 , +-25863 , +24999 , +-26529 , +-22669 , +-14827 , +1017 , +7273 , +11173 , +-9705 , +-5725 , +27945 , +6161 , +6697 , +27867 , +1253 , +-31717 , +29803 , +-9845 , +11883 , +-6443 , +13495 , +32097 , +-22003 , +-12715 , +-13865 , +-29585 , +20761 , +18315 , +5433 , +-19905 , +28623 , +3743 , +15661 , +-22677 , +3543 , +8133 , +31123 , +-23627 , +-8899 , +-16239 , +-11489 , +1181 , +2025 , +-26149 , +19723 , +131 , +-27757 , +-1525 , +29005 , +-16849 , +-27583 , +-10253 , +-18603 , +-22281 , +-6857 , +-20943 , +-17091 , +22865 , +-24459 , +-14601 , +-13431 , +-5655 , +3249 , +4211 , +-25765 , +4413 , +14791 , +4505 , +-10453 , +-10317 , +951 , +6023 , +19967 , +16945 , +-19427 , +13141 , +20771 , +-14023 , +-1499 , +8303 , +13413 , +-2951 , +28935 , +-21651 , +26821 , +-3351 , +27901 , +-20115 , +10675 , +-30875 , +18109 , +20459 , +13511 , +8633 , +-8851 , +23829 , +-31753 , +31819 , +-30945 , +-16221 , +-32177 , +-27099 , +10183 , +-15047 , +-19673 , +24975 , +-22861 , +-1489 , +17379 , +-209 , +31367 , +-16903 , +-32735 , +-8807 , +-31829 , +2291 , +-24457 , +-27289 , +-4783 , +-28483 , +-5207 , +-9767 , +19679 , +-9193 , +-23963 , +21985 , +-18447 , +24371 , +-21137 , +-12857 , +2253 , +14481 , +-31123 , +23865 , +2395 , +-22957 , +21257 , +10725 , +-17251 , +-13287 , +-21831 , +25237 , +32427 , +-7847 , +-271 , +-7491 , +13089 , +24629 , +7645 , +21151 , +14883 , +19663 , +-14447 , +7133 , +25549 , +11563 , +-12849 , +2703 , +-26063 , +-13951 , +-18891 , +-3361 , +31173 , +19731 , +22261 , +13089 , +-28571 , +-8313 , +26131 , +27237 , +31437 , +20165 , +29461 , +15257 , +-26497 , +-7871 , +17223 , +29973 , +-29099 , +-5917 , +2147 , +29891 , +20323 , +11859 , +27097 , +8355 , +-7049 , +-13095 , +-10119 , +19445 , +-21991 , +-26963 , +9399 , +-7995 , +15603 , +-26151 , +-12457 , +-23029 , +-13097 , +-8825 , +3253 , +-1475 , +3629 , +-4129 , +-3479 , +23147 , +-32265 , +23645 , +-14447 , +3541 , +19513 , +-23891 , +-4225 , +-12799 , +20735 , +-14855 , +26353 , +-15525 , +-12339 , +3277 , +19411 , +-20927 , +13723 , +2407 , +26469 , +-27479 , +23881 , +-32109 , +13061 , +-13271 , +-2405 , +21759 , +20319 , +-18273 , +19379 , +-6887 , +-6621 , +5949 , +7423 , +14689 , +-4545 , +11815 , +-13379 , +21827 , +-13669 , +-18293 , +-29973 , +-5007 , +15179 , +-6349 , +-12609 , +1721 , +6473 , +19877 , +-19803 , +-21409 , +-11089 , +5049 , +-29257 , +13041 , +11629 , +17323 , +28071 , +17059 , +7811 , +-29509 , +-20403 , +11301 , +29619 , +21055 , +29579 , +-22789 , +451 , +24385 , +5073 , +-28587 , +-1749 , +5775 , +28947 , +-15765 , +19285 , +30557 , +12859 , +-25521 , +-26033 , +-12719 , +-16597 , +21061 , +-21753 , +27429 , +10539 , +-24925 , +-11775 , +12991 , +-17943 , +-5343 , +21135 , +26047 , +24809 , +-30033 , +10379 , +29599 , +-18553 , +7129 , +13451 , +12879 , +-11419 , +-21613 , +17053 , +21055 , +-24727 , +-20329 , +-7297 , +26375 , +-3277 , +30523 , +-28589 , +23667 , +8475 , +5579 , +4315 , +-20447 , +12953 , +-32421 , +-25553 , +18327 , +-29873 , +-9433 , +-21517 , +15067 , +10873 , +-29077 , +-1511 , +27535 , +17125 , +22191 , +-24313 , +16513 , +24935 , +-14673 , +-10653 , +24011 , +-9765 , +26535 , +14395 , +-20125 , +-19815 , +2353 , +9415 , +-21445 , +-14749 , +22941 , +5277 , +-41 , +21741 , +24261 , +28519 , +-18335 , +-17973 , +-6295 , +-11487 , +2881 , +-32275 , +-29435 , +17869 , +-19905 , +-26733 , +24107 , +18857 , +11017 , +-17207 , +-13995 , +19435 , +-19615 , +3165 , +-8121 , +26103 , +22943 , +-18089 , +-29729 , +-5863 , +-1571 , +-15115 , +-14227 , +-21319 , +32637 , +-7399 , +-32109 , +-26855 , +17231 , +17741 , +11413 , +22663 , +-8671 , +-31691 , +-23503 , +-12009 , +18395 , +24453 , +-32515 , +6367 , +-25833 , +-29573 , +25399 , +-23899 , +21809 , +19163 , +23337 , +28963 , +27373 , +-1949 , +243 , +-10567 , +2435 , +23233 , +21741 , +-18525 , +23615 , +-10227 , +119 , +-14665 , +11919 , +21957 , +3931 , +-19305 , +-15703 , +-2495 , +-18019 , +-13975 , +-19303 , +27815 , +21971 , +-7911 , +16857 , +8045 , +3079 , +16897 , +-12947 , +-11959 , +24831 , +17967 , +-1923 , +2219 , +12833 , +20247 , +10083 , +-4683 , +14793 , +-1077 , +-13491 , +-10567 , +-19427 , +6575 , +18515 , +15139 , +15467 , +18365 , +-12277 , +17663 , +31479 , +-15311 , +2213 , +-18197 , +-17567 , +23751 , +-10111 , +27791 , +881 , +-1679 , +11845 , +915 , +-15755 , +-18035 , +7549 , +11037 , +-20201 , +7077 , +10151 , +3013 , +-1611 , +10141 , +2521 , +10763 , +16697 , +4979 , +-6453 , +27989 , +-22411 , +23149 , +9591 , +-31391 , +24051 , +-16671 , +-9167 , +26177 , +-10153 , +11867 , +8253 , +4815 , +20777 , +99 , +4583 , +28075 , +-26561 , +-30805 , +-737 , +18603 , +-10363 , +28113 , +26245 , +27357 , +24413 , +-11891 , +23827 , +-15113 , +4985 , +-24721 , +-6107 , +-29617 , +-28631 , +7447 , +-5605 , +29783 , +-24513 , +7911 , +20331 , +-16743 , +7009 , +-8125 , +-7617 , +22815 , +-15139 , +-2489 , +-25979 , +-15489 , +17161 , +21755 , +-15727 , +-3515 , +-14565 , +-8435 , +-14295 , +-5905 , +32117 , +30731 , +4649 , +17001 , +24203 , +4375 , +-19823 , +24573 , +30775 , +-22489 , +19751 , +30417 , +18315 , +-20045 , +2693 , +13281 , +15153 , +-6927 , +-4171 , +11887 , +-2499 , +-7537 , +29263 , +-7933 , +27527 , +-21013 , +-24315 , +24795 , +27017 , +28869 , +-18237 , +-29717 , +-20821 , +-32381 , +32331 , +-6829 , +7715 , +9179 , +13377 , +-10159 , +11599 , +-1007 , +-31283 , +-26177 , +8583 , +-21323 , +15789 , +24589 , +13943 , +-26927 , +8657 , +10671 , +17655 , +13481 , +-13453 , +-13789 , +615 , +1771 , +-11351 , +30043 , +28799 , +-29585 , +11399 , +-32319 , +-27219 , +15465 , +-339 , +-26459 , +5615 , +-1241 , +-7323 , +3385 , +-15325 , +323 , +-11459 , +-28145 , +-15389 , +-21153 , +-24299 , +1289 , +21475 , +14423 , +22979 , +-30257 , +-10049 , +-15355 , +24609 , +-21807 , +16473 , +-17301 , +-25169 , +-18247 , +21933 , +885 , +-24673 , +8289 , +7471 , +-8405 , +-1927 , +-4275 , +-11873 , +8815 , +-16851 , +16041 , +-26273 , +-30673 , +31909 , +-17227 , +-29615 , +-18145 , +29931 , +3271 , +8743 , +-3085 , +-32583 , +13757 , +-24253 , +-12267 , +29323 , +-10499 , +-23027 , +4829 , +19013 , +23521 , +23235 , +3915 , +5697 , +-6727 , +30687 , +-30661 , +-10011 , +9279 , +-23325 , +-29407 , +19141 , +-11123 , +20917 , +18755 , +-11977 , +7837 , +-24451 , +15717 , +-32415 , +-30411 , +30703 , +-9199 , +-30747 , +-17299 , +22067 , +71 , +-13087 , +-13673 , +-973 , +13999 , +11421 , +14277 , +-30351 , +20831 , +7319 , +30651 , +8301 , +15879 , +5405 , +6759 , +-21653 , +-26961 , +-26781 , +24279 , +-9769 , +-6929 , +10273 , +25785 , +-4583 , +4003 , +5799 , +-19385 , +29679 , +-5339 , +26741 , +21707 , +30527 , +25611 , +-16047 , +10637 , +21371 , +15441 , +-24601 , +-12971 , +-19607 , +-11487 , +-14633 , +-23465 , +-9847 , +-4353 , +10833 , +23735 , +-14105 , +647 , +14899 , +-27273 , +26225 , +-7261 , +-8043 , +-7177 , +10965 , +27975 , +3307 , +-4119 , +31955 , +927 , +9115 , +-8759 , +19479 , +29393 , +10765 , +-16429 , +1173 , +8245 , +1873 , +17793 , +29271 , +1539 , +-20179 , +24957 , +-21021 , +29075 , +-25165 , +7711 , +-22265 , +-999 , +20839 , +22621 , +29751 , +-18991 , +25025 , +-26293 , +-11165 , +-1087 , +-15265 , +-14833 , +16719 , +-4117 , +-15739 , +-8617 , +-7061 , +3083 , +26947 , +-32427 , +-20431 , +-14647 , +-12787 , +28983 , +10223 , +-15503 , +-55 , +-13027 , +-4053 , +-31691 , +-909 , +14733 , +-16517 , +5847 , +-31955 , +-20615 , +-14377 , +-19481 , +6873 , +10657 , +12399 , +-14205 , +9521 , +-5979 , +-18417 , +25213 , +22117 , +-31389 , +6125 , +30503 , +26917 , +-30203 , +16127 , +-899 , +26441 , +-13975 , +-547 , +19681 , +24285 , +11557 , +15121 , +-12973 , +-9281 , +12789 , +18421 , +20013 , +-587 , +-13639 , +28159 , +7767 , +-31993 , +-7699 , +19629 , +18683 , +-24685 , +12699 , +8135 , +-2619 , +-1943 , +-22049 , +-31159 , +25495 , +-25629 , +7635 , +-7761 , +30147 , +20023 , +28423 , +-6699 , +19389 , +665 , +-4217 , +28999 , +-9377 , +-10039 , +12867 , +17953 , +1425 , +30515 , +527 , +-17565 , +7565 , +6527 , +-18661 , +-311 , +23193 , +11187 , +-23835 , +-219 , +11311 , +-13885 , +-13635 , +-26831 , +-5943 , +-1109 , +-22355 , +4337 , +-12537 , +1543 , +11009 , +-26237 , +-11911 , +-22741 , +-21965 , +-17031 , +9413 , +-26433 , +3433 , +-31311 , +2157 , +11729 , +-10901 , +19633 , +-15873 , +25969 , +17947 , +-7049 , +17101 , +18883 , +26225 , +9433 , +28719 , +-3165 , +3817 , +31319 , +-31187 , +2733 , +-16761 , +-29321 , +-29505 , +6631 , +28231 , +-25957 , +22403 , +-28475 , +6937 , +-28071 , +2041 , +-14125 , +15959 , +-26025 , +-30155 , +-6203 , +-4931 , +1689 , +1047 , +-2549 , +-11295 , +25445 , +-20727 , +499 , +-12755 , +-22637 , +5171 , +-22729 , +17747 , +10087 , +9011 , +-11491 , +6989 , +24557 , +6997 , +7431 , +20935 , +13003 , +-16563 , +-29803 , +10281 , +-21863 , +-13461 , +7733 , +-6147 , +-8257 , +9815 , +-3269 , +6133 , +5579 , +-15287 , +25215 , +19801 , +-22205 , +-19269 , +-7055 , +21515 , +-6653 , +21165 , +7601 , +-6929 , +24085 , +3917 , +-6363 , +-23823 , +-9977 , +-12483 , +-21863 , +-27019 , +29635 , +21061 , +-5171 , +-8367 , +2277 , +-25209 , +22035 , +-10935 , +31133 , +-8125 , +9827 , +20225 , +-4361 , +-13565 , +18939 , +18295 , +-21569 , +-11947 , +2415 , +-26117 , +-31015 , +19979 , +-26561 , +3243 , +-23025 , +489 , +24827 , +24931 , +-28303 , +-6939 , +26061 , +-23235 , +14129 , +-15909 , +-29285 , +30341 , +-2063 , +-27455 , +13725 , +31023 , +21407 , +9067 , +-8337 , +-20013 , +20173 , +-14155 , +21425 , +-217 , +10381 , +-5565 , +4379 , +27117 , +30917 , +4285 , +24595 , +-31883 , +20227 , +6775 , +-7479 , +-30063 , +27103 , +-32577 , +-1583 , +-28911 , +7881 , +10111 , +-10959 , +19377 , +2667 , +-20599 , +-30203 , +-4453 , +8563 , +-15555 , +1167 , +-30629 , +14845 , +21967 , +11985 , +22875 , +-23205 , +19707 , +9127 , +-18993 , +-3465 , +-29389 , +-14757 , +-18369 , +28837 , +-8087 , +-26939 , +31343 , +-29953 , +-20681 , +6615 , +3297 , +-27591 , +1187 , +-20801 , +-6969 , +6913 , +-11189 , +10363 , +-1921 , +24269 , +-1239 , +1009 , +17033 , +-713 , +-3389 , +-28023 , +-7423 , +28633 , +-20761 , +-3775 , +-26733 , +29343 , +-25121 , +9289 , +-15879 , +-5469 , +17197 , +12059 , +-19223 , +25983 , +25793 , +-32499 , +32667 , +-14031 , +17077 , +-29069 , +-4171 , +19559 , +-11909 , +-4563 , +459 , +20315 , +28321 , +-11321 , +30797 , +11565 , +2049 , +15883 , +-12019 , +-25159 , +11643 , +-19941 , +20779 , +-16401 , +1327 , +-9459 , +24465 , +25773 , +-26061 , +-6661 , +-6671 , +-19949 , +32205 , +-3419 , +-4045 , +-18589 , +13093 , +28799 , +17007 , +2379 , +23943 , +-16307 , +7533 , +-307 , +10515 , +-3521 , +-5739 , +-22901 , +-6667 , +-1915 , +107 , +3239 , +20005 , +9827 , +19587 , +-5869 , +28051 , +21461 , +-2053 , +20083 , +-23315 , +32153 , +-7817 , +29033 , +-16695 , +14799 , +3989 , +8315 , +-28827 , +-9967 , +-9503 , +1117 , +5857 , +-29687 , +1625 , +16595 , +-25105 , +25995 , +32341 , +-29181 , +-15085 , +-28375 , +-2547 , +25173 , +-427 , +-27061 , +7051 , +17597 , +27005 , +-45 , +-26077 , +-8283 , +-30007 , +16415 , +-23701 , +-5071 , +-11227 , +10681 , +14003 , +-29141 , +30947 , +-11173 , +-8449 , +14413 , +-31753 , +18067 , +8059 , +-20195 , +-22361 , +-17445 , +18041 , +20551 , +-14903 , +-8411 , +-8477 , +3187 , +-27779 , +-11773 , +30775 , +29087 , +29531 , +22581 , +-773 , +6131 , +-9417 , +-63 , +20413 , +-19685 , +21073 , +-25197 , +26237 , +21027 , +30991 , +-2421 , +-25419 , +-6197 , +4921 , +-4837 , +29637 , +-19621 , +-29527 , +2909 , +31219 , +-24061 , +-3959 , +-15957 , +-28707 , +16563 , +-13557 , +12729 , +17523 , +22117 , +-4707 , +-8659 , +32627 , +-16627 , +-29273 , +5807 , +12891 , +-24873 , +-19009 , +30865 , +18401 , +-31211 , +-32421 , +23507 , +-30221 , +-25209 , +6935 , +-31537 , +-18905 , +29501 , +-2715 , +-3519 , +30899 , +32748 , +13759 , +8169 , +-31255 , +-831 , +-13713 , +-27233 , +-30157 , +8643 , +8885 , +6889 , +10363 , +25763 , +395 , +26393 , +-16585 , +-12267 , +25307 , +-23075 , +11219 , +2989 , +-5323 , +-22429 , +17581 , +11313 , +-9725 , +6881 , +16783 , +-7053 , +-2485 , +-26951 , +-13657 , +11949 , +28129 , +-5871 , +-6661 , +1615 , +7963 , +26083 , +31587 , +19047 , +17681 , +-24677 , +-22781 , +24677 , +-431 , +23341 , +-28095 , +-20603 , +-23013 , +6317 , +2879 , +-29537 , +30733 , +2153 , +-27953 , +-20871 , +30315 , +-15233 , +6385 , +-15697 , +2765 , +-22795 , +8131 , +15095 , +22873 , +5203 , +31999 , +-5361 , +-16773 , +-27977 , +29171 , +-28929 , +28449 , +1393 , +20985 , +-11773 , +-19605 , +-6885 , +28521 , +-4647 , +-19479 , +-13269 , +-30953 , +31383 , +20821 , +12309 , +25165 , +-30961 , +-319 , +-24869 , +-6343 , +-28259 , +5721 , +22819 , +20467 , +31101 , +-24421 , +-24355 , +-16409 , +175 , +1541 , +-27575 , +-4137 , +-2497 , +-23721 , +-4707 , +10319 , +-24273 , +-18361 , +32533 , +17053 , +-31811 , +-22343 , +-15475 , +-6069 , +3913 , +2169 , +23449 , +-14061 , +24741 , +26993 , +-12509 , +-167 , +-25361 , +25697 , +27509 , +23337 , +1773 , +-11243 , +-27167 , +-13405 , +25821 , +-17629 , +27339 , +-24835 , +-12587 , +-13279 , +335 , +-12043 , +32149 , +3157 , +11083 , +8145 , +-19997 , +-30471 , +2559 , +8139 , +19555 , +-26897 , +20261 , +1299 , +11751 , +-27409 , +-32119 , +23617 , +-1961 , +-22447 , +9243 , +26965 , +18423 , +27703 , +653 , +25889 , +-691 , +2889 , +-24979 , +20819 , +-20623 , +-17425 , +-3659 , +-25893 , +-8471 , +5893 , +29675 , +17137 , +253 , +16667 , +-19791 , +-14715 , +-1133 , +24097 , +22249 , +31803 , +10633 , +18347 , +-4549 , +-24351 , +32641 , +-611 , +20801 , +-13723 , +-5813 , +-13965 , +-493 , +-1707 , +30637 , +-29723 , +16221 , +203 , +30403 , +11569 , +30721 , +31985 , +1239 , +-22583 , +27431 , +4079 , +16823 , +-23155 , +-10025 , +7533 , +-20851 , +10115 , +18193 , +-17281 , +-10697 , +12305 , +20331 , +6183 , +-10719 , +-6219 , +18717 , +-2483 , +-8295 , +13367 , +-22623 , +-25301 , +18861 , +14953 , +-6707 , +-12459 , +19323 , +-15783 , +21857 , +5669 , +-2285 , +-2545 , +-21715 , +4795 , +-29499 , +29375 , +-24677 , +3439 , +-16641 , +9347 , +31699 , +31691 , +-347 , +-7019 , +-5303 , +-19193 , +26595 , +20999 , +-5669 , +-29447 , +26513 , +-8973 , +9833 , +3477 , +-20227 , +31809 , +-19989 , +1761 , +-25527 , +1493 , +21255 , +-21143 , +-31413 , +-24249 , +22063 , +-187 , +17109 , +19745 , +12849 , +10109 , +20121 , +-4463 , +-9893 , +-26607 , +-19073 , +-7257 , +3843 , +4717 , +26747 , +-28669 , +-26195 , +22107 , +1507 , +-9191 , +-22117 , +-20605 , +-19635 , +7905 , +19433 , +6493 , +8157 , +27159 , +16929 , +12717 , +18221 , +-20253 , +5723 , +-20101 , +3221 , +-16091 , +-15415 , +-23419 , +18187 , +-30945 , +-13351 , +5953 , +21881 , +-27725 , +4043 , +29515 , +-11369 , +23833 , +18113 , +16995 , +-30913 , +12823 , +26725 , +-28699 , +7757 , +22457 , +-7179 , +-24389 , +-11031 , +18827 , +-1055 , +14817 , +-25491 , +-27567 , +7651 , +11599 , +-9543 , +17209 , +-28781 , +25979 , +23045 , +22427 , +18305 , +10059 , +-32447 , +17197 , +19151 , +-15727 , +27879 , +-9031 , +26441 , +26881 , +87 , +-14499 , +-24073 , +25513 , +-30803 , +-15305 , +12865 , +24301 , +537 , +-6491 , +24951 , +1269 , +-21319 , +8961 , +9975 , +-24909 , +-6673 , +12239 , +-10051 , +-3253 , +311 , +12663 , +-14211 , +7709 , +9095 , +10371 , +9537 , +-27859 , +-16357 , +-26027 , +-1677 , +2595 , +-12841 , +27739 , +-25211 , +-30783 , +19741 , +27083 , +30459 , +15839 , +13855 , +27605 , +23569 , +31193 , +26561 , +-25499 , +29637 , +22929 , +-20761 , +-13485 , +-5513 , +32489 , +32337 , +19999 , +21249 , +31147 , +28411 , +25127 , +3151 , +8211 , +8419 , +-30371 , +-31887 , +-29253 , +-27535 , +-9853 , +-21959 , +285 , +-27571 , +-18971 , +31317 , +20353 , +18349 , +-5241 , +-8991 , +10107 , +-31435 , +-22549 , +-12675 , +-9761 , +-431 , +16953 , +6131 , +-7871 , +-9467 , +20231 , +29501 , +-8223 , +-8627 , +-2425 , +29995 , +19503 , +-21777 , +1341 , +4977 , +-31813 , +16599 , +-20669 , +8009 , +31917 , +19181 , +32247 , +-29569 , +-12857 , +21871 , +24623 , +-8939 , +17613 , +-31547 , +21763 , +-30381 , +-15477 , +-6947 , +-22287 , +-17311 , +-25787 , +-5889 , +15775 , +15713 , +7857 , +13357 , +-11245 , +-8957 , +-23949 , +16879 , +-11927 , +16293 , +-23537 , +1973 , +30221 , +23521 , +20321 , +9903 , +-145 , +-31321 , +6813 , +-14823 , +-21443 , +24031 , +-20289 , +-20959 , +6943 , +32369 , +-7549 , +-17605 , +-1049 , +15087 , +-10781 , +16881 , +-29869 , +19867 , +11275 , +31563 , +-11973 , +-14069 , +21967 , +-28269 , +6479 , +9789 , +-12633 , +26047 , +-25009 , +-14543 , +30249 , +-23233 , +-8259 , +-14849 , +-16395 , +18519 , +-26083 , +26733 , +-3519 , +4345 , +-9813 , +4109 , +10937 , +8731 , +8079 , +-305 , +25103 , +18317 , +4503 , +-14309 , +9693 , +1623 , +-21391 , +-14739 , +16689 , +3467 , +28769 , +28007 , +2935 , +8099 , +-32647 , +-12181 , +-27149 , +3153 , +11345 , +13749 , +28609 , +-11555 , +-9149 , +3569 , +14401 , +-31489 , +-10211 , +10323 , +-18403 , +557 , +-8105 , +31535 , +-18251 , +9087 , +4569 , +22803 , +21019 , +28673 , +3107 , +27229 , +-6259 , +-3705 , +-11763 , +17237 , +-30101 , +16911 , +23803 , +-4417 , +-1103 , +27025 , +23197 , +17659 , +1003 , +-23463 , +3359 , +26521 , +22963 , +-22049 , +-14881 , +14707 , +-12641 , +-29663 , +-3407 , +11073 , +-1337 , +-14469 , +13707 , +13491 , +7857 , +-25863 , +32451 , +21003 , +29647 , +16697 , +-24125 , +24117 , +-23691 , +8631 , +23623 , +-24229 , +-25517 , +-27981 , +18447 , +-5121 , +32361 , +17275 , +-20707 , +-26985 , +-10877 , +-6325 , +-17819 , +15775 , +-9681 , +14505 , +-3317 , +-28109 , +-3787 , +-4817 , +-29157 , +5929 , +8593 , +-19983 , +31421 , +8869 , +-18199 , +-14259 , +-21773 , +-967 , +-10619 , +23369 , +-28981 , +28529 , +5321 , +9571 , +14873 , +-21773 , +2343 , +32497 , +11441 , +-15333 , +-11613 , +27893 , +13597 , +-18681 , +28347 , +-14223 , +26069 , +15159 , +3311 , +5705 , +-27399 , +17575 , +6315 , +10133 , +24197 , +-30371 , +12747 , +6775 , +8463 , +-7281 , +-13429 , +-11403 , +-4873 , +-6097 , +-22013 , +-30891 , +-8663 , +-30201 , +-2535 , +28015 , +-10167 , +8531 , +8195 , +12937 , +7543 , +-20519 , +18485 , +17451 , +-18559 , +-18051 , +26339 , +-29571 , +11157 , +-30373 , +-5649 , +-18793 , +28811 , +15203 , +357 , +-27805 , +-24699 , +25193 , +21111 , +-18709 , +22333 , +-23865 , +18671 , +-6601 , +18863 , +6505 , +-16597 , +28067 , +-5033 , +-6287 , +13457 , +-2117 , +-15643 , +-17849 , +19085 , +-887 , +15483 , +-22477 , +-16381 , +24953 , +-25759 , +14711 , +-23733 , +25001 , +-8389 , +-2587 , +-3419 , +22213 , +10693 , +20215 , +25399 , +31323 , +-27125 , +15975 , +-31105 , +14265 , +-1509 , +29003 , +1615 , +9789 , +-29881 , +22435 , +12097 , +17463 , +-9003 , +-3969 , +-32333 , +-30153 , +12601 , +-21877 , +-32447 , +28397 , +-27189 , +12585 , +31409 , +29561 , +-16119 , +32275 , +30847 , +20553 , +11073 , +1895 , +7615 , +-9611 , +22993 , +25153 , +-24669 , +14731 , +-11041 , +12763 , +-27277 , +-31251 , +-16497 , +-17637 , +-10497 , +26545 , +-30025 , +-2893 , +8599 , +-12823 , +-17883 , +27571 , +-17527 , +22153 , +13381 , +-11101 , +-12781 , +32437 , +5221 , +-24289 , +-21025 , +13219 , +30567 , +29161 , +-13829 , +-9239 , +15105 , +-17019 , +31051 , +29021 , +10089 , +-31925 , +24203 , +-15515 , +31641 , +25351 , +-25923 , +31191 , +21501 , +-3823 , +-31193 , +-4019 , +-7245 , +-24867 , +10187 , +-32259 , +-1987 , +4117 , +9053 , +24081 , +-16453 , +13369 , +21943 , +31873 , +18855 , +-847 , +-10275 , +-13465 , +-17911 , +1889 , +-24473 , +11487 , +-22741 , +5577 , +31619 , +23889 , +-26151 , +-22375 , +-28309 , +23129 , +10261 , +-26677 , +13143 , +25105 , +-23983 , +-201 , +9979 , +8953 , +-13533 , +22445 , +10367 , +13371 , +-28289 , +5263 , +-9481 , +28307 , +17779 , +-25111 , +-8365 , +15777 , +16217 , +-251 , +18917 , +-32319 , +29073 , +8583 , +11853 , +6755 , +-9027 , +-4863 , +31225 , +-20251 , +24175 , +8977 , +-10989 , +-9239 , +-11665 , +20467 , +-15867 , +13101 , +-409 , +-22627 , +-19603 , +27617 , +16415 , +10067 , +20621 , +5513 , +30265 , +-11321 , +-24495 , +3907 , +7011 , +27557 , +21177 , +19891 , +3087 , +26291 , +-7975 , +2381 , +-4427 , +-26259 , +-17579 , +-4817 , +-18819 , +21777 , +16205 , +24195 , +14463 , +23615 , +-22053 , +29769 , +19323 , +-31725 , +-15853 , +-18505 , +27149 , +22965 , +29037 , +17683 , +20329 , +-23433 , +707 , +25855 , +-31085 , +7275 , +16335 , +13925 , +25621 , +11647 , +9495 , +-32581 , +25139 , +7951 , +25713 , +18149 , +22445 , +30717 , +28147 , +12943 , +-32529 , +-2227 , +14189 , +28669 , +-11315 , +-1727 , +31331 , +4715 , +-27209 , +-24349 , +-24445 , +-26399 , +-21387 , +-25047 , +5787 , +-21625 , +-24225 , +-6003 , +15897 , +-22137 , +-12529 , +17947 , +-19209 , +8031 , +-20059 , +-2283 , +11327 , +-16969 , +-11921 , +24067 , +-31495 , +-5955 , +16431 , +-947 , +27563 , +30715 , +8397 , +-25771 , +10829 , +-16723 , +12685 , +-1523 , +-5951 , +29859 , +-12085 , +-10481 , +5065 , +-26743 , +29745 , +-20681 , +8837 , +-9013 , +2673 , +2229 , +29287 , +-13333 , +16251 , +-23887 , +29097 , +6485 , +6965 , +24917 , +-12213 , +22973 , +-3407 , +20077 , +-4219 , +-23057 , +9197 , +-31103 , +18369 , +18221 , +-27649 , +27237 , +-745 , +1033 , +26587 , +-4775 , +23101 , +9651 , +-4227 , +22425 , +27143 , +-12835 , +15275 , +21887 , +26457 , +-19187 , +22055 , +-21743 , +15269 , +-5775 , +-27539 , +25633 , +-15397 , +-22977 , +-797 , +-10017 , +5097 , +-9333 , +13979 , +24309 , +28847 , +32413 , +-1153 , +-229 , +14453 , +15043 , +-31467 , +1845 , +29159 , +-25927 , +-5199 , +-12059 , +14731 , +17009 , +-4055 , +-27481 , +-14915 , +20851 , +10263 , +-24217 , +14625 , +-31305 , +1159 , +-12135 , +-1127 , +14067 , +-21707 , +-28975 , +-11829 , +-15743 , +6727 , +20703 , +27397 , +32681 , +-29061 , +-12963 , +-25143 , +-11135 , +-23573 , +-11565 , +2741 , +-31929 , +10557 , +4683 , +24069 , +-14285 , +7519 , +-18849 , +-6269 , +24529 , +-12357 , +7907 , +-16117 , +3545 , +-25869 , +-26389 , +15221 , +-17269 , +12825 , +27509 , +-13801 , +-13185 , +-1951 , +4207 , +9399 , +-21245 , +23397 , +-3491 , +-10235 , +21749 , +-22581 , +-31129 , +-871 , +-19439 , +20627 , +6905 , +19551 , +-19241 , +8379 , +13013 , +20123 , +-6443 , +20357 , +-15181 , +-11691 , +27017 , +-4317 , +14153 , +28511 , +12211 , +-20995 , +29179 , +17855 , +13107 , +25179 , +-9769 , +-19535 , +-20133 , +22697 , +-27831 , +14873 , +1995 , +-9177 , +-8163 , +18307 , +18885 , +-3551 , +-3553 , +8591 , +9739 , +-16465 , +2619 , +-23309 , +13615 , +-28191 , +15367 , +5103 , +18547 , +133 , +-21021 , +-21691 , +-12003 , +9041 , +-21103 , +13745 , +-1967 , +20899 , +28999 , +21987 , +32611 , +25787 , +-8877 , +-16651 , +183 , +-2963 , +9765 , +4963 , +-22253 , +-31143 , +-22799 , +-23933 , +381 , +10153 , +-15167 , +-17281 , +-7793 , +26949 , +13841 , +-11063 , +8779 , +13961 , +-31001 , +11033 , +10619 , +32389 , +12647 , +13025 , +-6777 , +10155 , +8941 , +28993 , +20935 , +17931 , +1449 , +2441 , +7013 , +3085 , +9905 , +-20439 , +32427 , +28071 , +20635 , +15401 , +-2847 , +-4583 , +29333 , +-28885 , +-13659 , +-28645 , +27649 , +3027 , +14013 , +24737 , +-11129 , +21195 , +2425 , +-27637 , +6319 , +32315 , +-29565 , +-21023 , +-15621 , +-27719 , +-21701 , +-21755 , +18813 , +25797 , +-1143 , +-22921 , +14319 , +-27197 , +-16579 , +-3969 , +3661 , +885 , +30181 , +4207 , +-21527 , +16105 , +5921 , +-22313 , +-24827 , +22523 , +-29315 , +-18885 , +12529 , +-20917 , +-30261 , +8273 , +-31079 , +177 , +18169 , +5557 , +-21087 , +29497 , +22123 , +10781 , +-4609 , +-15465 , +3279 , +-20707 , +14353 , +25635 , +-22663 , +16209 , +1849 , +-19117 , +-15815 , +-3043 , +-28437 , +5543 , +13747 , +15847 , +-26545 , +51 , +-2505 , +-10551 , +-16809 , +-3703 , +2847 , +-14391 , +-22957 , +19251 , +13975 , +-1897 , +-14579 , +-4685 , +26123 , +16835 , +16477 , +-16143 , +-32021 , +31085 , +-29369 , +-7367 , +-17393 , +29321 , +27277 , +-18765 , +-8307 , +26257 , +-13875 , +-31399 , +-8949 , +-15939 , +10511 , +-3219 , +2207 , +-13897 , +9961 , +-1933 , +13859 , +5857 , +-21745 , +-26959 , +17677 , +22521 , +31599 , +2327 , +13513 , +22627 , +-27191 , +-24637 , +22923 , +-16169 , +9663 , +757 , +-13905 , +-30053 , +28541 , +5257 , +-25711 , +-25283 , +-31043 , +10219 , +3033 , +-28987 , +10867 , +-14189 , +9315 , +-391 , +-25387 , +-14595 , +-1141 , +-32247 , +-12293 , +-15333 , +9227 , +-25271 , +-16647 , +-3243 , +25939 , +-17295 , +19313 , +19197 , +21599 , +-22323 , +30635 , +-9401 , +-6901 , +28661 , +21811 , +-31805 , +-29707 , +13709 , +32750 , +-16561 , +2253 , +-6285 , +32171 , +-16741 , +28979 , +19583 , +-9653 , +-30445 , +-27643 , +26033 , +22601 , +23647 , +19779 , +-26121 , +3547 , +603 , +-7587 , +-23461 , +-14713 , +21901 , +-233 , +-17219 , +-32455 , +-21475 , +27343 , +-3319 , +25315 , +24911 , +3689 , +13557 , +-2677 , +13685 , +25241 , +-2505 , +3049 , +-17293 , +-8513 , +-3275 , +8573 , +-27993 , +-32703 , +1611 , +-28887 , +-28561 , +609 , +-30859 , +27715 , +-19427 , +-8555 , +11923 , +29753 , +-1433 , +-21151 , +-4073 , +-14181 , +-8853 , +-81 , +-13243 , +-6211 , +-19937 , +18589 , +2277 , +-20535 , +-25523 , +-4119 , +-12931 , +-14755 , +20745 , +9399 , +-26097 , +15515 , +24489 , +-30481 , +-28603 , +-14391 , +14651 , +19735 , +1841 , +26211 , +-20857 , +-11093 , +24967 , +-13895 , +7287 , +31473 , +-25011 , +23553 , +-227 , +-28585 , +-25575 , +15087 , +8995 , +10307 , +-31031 , +-297 , +11719 , +-12431 , +26553 , +-22987 , +-19633 , +-15669 , +20603 , +32211 , +-27641 , +-16705 , +6159 , +23897 , +-10317 , +-235 , +8859 , +4203 , +-16501 , +-30897 , +11175 , +17463 , +18095 , +19319 , +-30005 , +-11879 , +-14043 , +20859 , +-5387 , +-17493 , +2379 , +25351 , +-5099 , +-17693 , +19409 , +26589 , +-22693 , +-21341 , +-15819 , +171 , +-29205 , +-16553 , +-1101 , +31329 , +-26085 , +-19699 , +-27449 , +-19955 , +19237 , +1673 , +-8935 , +305 , +25443 , +26849 , +-21505 , +-13665 , +-7929 , +18323 , +7027 , +-16441 , +10571 , +-11999 , +24965 , +30363 , +-8647 , +17439 , +-32675 , +26593 , +22223 , +-7467 , +1195 , +-4601 , +12749 , +25429 , +-30049 , +23685 , +-1321 , +13327 , +16741 , +-14421 , +23101 , +27885 , +9503 , +-27391 , +-14547 , +-15129 , +10071 , +27675 , +13419 , +25633 , +-523 , +-24593 , +-20599 , +-5505 , +-12091 , +-22351 , +27297 , +-32071 , +32091 , +-14805 , +10377 , +23037 , +-22113 , +25231 , +-31855 , +21503 , +23735 , +19931 , +1715 , +21397 , +22143 , +27043 , +-28333 , +-4151 , +-8815 , +-8847 , +-653 , +-4739 , +15269 , +27547 , +-32661 , +21875 , +-24417 , +-353 , +-16863 , +32501 , +-23561 , +1781 , +1729 , +-6429 , +7355 , +-16023 , +-18695 , +11083 , +-30715 , +-523 , +12967 , +901 , +-18965 , +32531 , +29217 , +-29495 , +-2809 , +-30303 , +-26151 , +-15539 , +29787 , +-17107 , +-27481 , +32717 , +5083 , +-13103 , +10357 , +-11849 , +23389 , +12427 , +32127 , +3511 , +-12275 , +26395 , +-28665 , +26827 , +24685 , +-8113 , +-31605 , +30701 , +7881 , +10213 , +22145 , +27669 , +559 , +26847 , +-9843 , +25313 , +-6681 , +-7847 , +-31427 , +-23641 , +32623 , +24295 , +821 , +8461 , +-32023 , +23401 , +-2055 , +5919 , +-20959 , +-11679 , +-489 , +7663 , +-3593 , +26321 , +19429 , +-30557 , +29279 , +-3701 , +-1101 , +26899 , +-27427 , +4113 , +28301 , +4063 , +-10897 , +-13333 , +-16019 , +24841 , +-26091 , +-3463 , +-13073 , +-10999 , +-17219 , +13649 , +-22639 , +32359 , +959 , +-21739 , +8809 , +-5157 , +16603 , +-14127 , +14425 , +16083 , +20131 , +27589 , +-6199 , +20123 , +-23419 , +3021 , +28383 , +12271 , +-18127 , +-20949 , +25149 , +-1771 , +-5217 , +-20247 , +-27093 , +6769 , +10879 , +1711 , +21087 , +9121 , +4661 , +-1257 , +-14293 , +19729 , +-18099 , +6023 , +17203 , +-25063 , +-7303 , +16523 , +3251 , +1933 , +-11515 , +-23637 , +31011 , +19169 , +28875 , +-29243 , +6273 , +1457 , +691 , +-15905 , +-32515 , +-17945 , +10411 , +26763 , +-21445 , +10829 , +22547 , +12207 , +24319 , +-7263 , +-29243 , +-19733 , +-27793 , +18999 , +28291 , +-15251 , +24009 , +1033 , +-29201 , +-20929 , +17299 , +5971 , +5129 , +1073 , +32099 , +-27225 , +31011 , +7715 , +6917 , +11143 , +-28585 , +-11551 , +-32191 , +27779 , +-26491 , +-29827 , +16395 , +13255 , +-29757 , +18215 , +-23491 , +-3785 , +25951 , +-22657 , +8145 , +15115 , +-27057 , +-25227 , +-8809 , +31709 , +24617 , +-12643 , +-29329 , +5457 , +20129 , +19207 , +-9733 , +-12517 , +-30853 , +-21609 , +-32543 , +-5469 , +10505 , +12511 , +-31367 , +-19685 , +28443 , +-1421 , +30221 , +-7661 , +-10625 , +-4409 , +15243 , +-20331 , +-2317 , +27521 , +27585 , +-4933 , +19363 , +22099 , +-27119 , +-5179 , +-24039 , +-22955 , +-32079 , +-20297 , +26557 , +-547 , +-9127 , +8047 , +-29241 , +27857 , +15487 , +-27595 , +15291 , +-3191 , +4625 , +-18465 , +2145 , +-8677 , +23213 , +-6047 , +-3785 , +-28609 , +-22955 , +3563 , +-14223 , +-9825 , +23979 , +13431 , +20847 , +27317 , +-15705 , +-15889 , +-15441 , +-32231 , +-23603 , +-24393 , +-5045 , +27235 , +14829 , +14033 , +-23053 , +-8063 , +10323 , +-32405 , +-8355 , +-1395 , +6013 , +11517 , +-6077 , +-22747 , +-7585 , +481 , +15577 , +23871 , +-12785 , +32103 , +-30775 , +5261 , +-15357 , +-4237 , +4771 , +7755 , +1733 , +-2931 , +23771 , +-2411 , +22835 , +-23423 , +4415 , +-22967 , +4137 , +19827 , +4593 , +-12967 , +1739 , +4981 , +-11553 , +-4705 , +-4819 , +19621 , +-17741 , +3647 , +-5741 , +-3647 , +-15783 , +20343 , +1065 , +-1221 , +2795 , +-30983 , +21815 , +729 , +-24019 , +31939 , +28127 , +461 , +11659 , +-8069 , +-3249 , +-31933 , +-19579 , +-28865 , +-7045 , +9091 , +15281 , +16901 , +-32169 , +-19579 , +32047 , +15469 , +21133 , +-9975 , +21409 , +5149 , +13493 , +-31951 , +12963 , +10391 , +527 , +2965 , +20421 , +-7277 , +-20551 , +23519 , +-17663 , +22993 , +27493 , +-4127 , +7601 , +25725 , +-21867 , +3119 , +22543 , +-13579 , +-23467 , +307 , +-19165 , +-27335 , +11625 , +-11573 , +-4801 , +7847 , +28433 , +7257 , +-20739 , +365 , +28731 , +-30365 , +-6487 , +29265 , +-5835 , +-17753 , +31817 , +9483 , +23031 , +-4175 , +-16373 , +20771 , +-9533 , +19703 , +15679 , +-4281 , +-24717 , +5747 , +11213 , +-14563 , +-23261 , +-18765 , +14391 , +26017 , +-32145 , +-5515 , +-9727 , +-27651 , +-11737 , +-5949 , +-3915 , +26335 , +12431 , +-8313 , +-8357 , +32337 , +17163 , +-25441 , +-8601 , +-29167 , +-15775 , +-17537 , +-17347 , +-14743 , +-147 , +12097 , +-15327 , +13709 , +-9637 , +-32447 , +943 , +-18077 , +-23463 , +-25551 , +-22821 , +-26127 , +-7207 , +31669 , +-23967 , +25631 , +29505 , +-26503 , +25789 , +7459 , +-3549 , +26827 , +-14935 , +26185 , +253 , +-12881 , +-5105 , +-22187 , +16231 , +-15237 , +25223 , +-6827 , +-31535 , +13551 , +4679 , +13307 , +19385 , +13257 , +23717 , +-24709 , +-14491 , +-28193 , +2817 , +24789 , +-25575 , +4025 , +19791 , +7869 , +-20019 , +3497 , +32513 , +17641 , +6505 , +4193 , +-5503 , +3051 , +31871 , +-3579 , +17201 , +18823 , +3963 , +6101 , +3545 , +-24173 , +32353 , +-31697 , +-20571 , +12101 , +-13309 , +7481 , +23453 , +16145 , +-25671 , +-21 , +-26983 , +12545 , +-8803 , +14259 , +-30273 , +7049 , +21819 , +-19835 , +-9357 , +18147 , +-3375 , +-13961 , +18133 , +6371 , +30465 , +13781 , +-22085 , +-30377 , +22795 , +-13637 , +-16095 , +-18731 , +26507 , +-13517 , +19495 , +-19431 , +7075 , +13505 , +-12919 , +9689 , +5827 , +-10617 , +-23661 , +-14045 , +-15659 , +-29485 , +-20835 , +31279 , +-29445 , +31037 , +15875 , +-11331 , +-19769 , +-28865 , +31637 , +-283 , +6639 , +19785 , +3487 , +-13449 , +10889 , +-1441 , +10065 , +-22325 , +9151 , +16425 , +-16449 , +-26843 , +-7411 , +31123 , +10073 , +-22145 , +-27149 , +-29215 , +-19489 , +12265 , +20019 , +-20409 , +-17701 , +8801 , +-3969 , +-9217 , +-28001 , +-7127 , +30143 , +25831 , +-11855 , +-2147 , +-2371 , +29845 , +-31539 , +-17773 , +31329 , +-13329 , +-27815 , +-15577 , +-403 , +-24253 , +2655 , +-2787 , +-19793 , +-3361 , +-31235 , +-6217 , +-8517 , +9771 , +29035 , +-19449 , +27171 , +19263 , +21865 , +-15407 , +32565 , +-8965 , +-4805 , +-18217 , +16423 , +21921 , +14873 , +1215 , +1753 , +28649 , +19765 , +18781 , +9991 , +27805 , +41 , +6549 , +-21753 , +13487 , +21489 , +12975 , +761 , +-20525 , +-20891 , +-14801 , +7815 , +10133 , +-20949 , +-5077 , +-5861 , +3821 , +-13001 , +-10709 , +-24433 , +1637 , +-30269 , +-9607 , +-399 , +29853 , +19899 , +-4103 , +-21579 , +-29837 , +-13113 , +-19833 , +-2325 , +4505 , +4273 , +-30775 , +17659 , +-14177 , +-5013 , +-885 , +13405 , +-14431 , +3455 , +-3435 , +-5427 , +-23987 , +25611 , +-18683 , +-31355 , +-19327 , +6453 , +-26333 , +9209 , +27239 , +-13271 , +6587 , +-31477 , +-8951 , +19851 , +19195 , +-20803 , +-25755 , +-28303 , +30909 , +-26503 , +-2031 , +4065 , +-20113 , +20409 , +-19645 , +19385 , +18273 , +-28855 , +22905 , +-18371 , +-7523 , +16631 , +11909 , +-19203 , +15173 , +-7723 , +-727 , +-10159 , +5221 , +16615 , +-23753 , +16477 , +-28847 , +-28571 , +-19945 , +8821 , +28533 , +16743 , +-1041 , +20775 , +26291 , +-24027 , +25909 , +-3929 , +571 , +-18765 , +-11575 , +4559 , +20449 , +17453 , +-29559 , +27535 , +-11275 , +-31111 , +-5013 , +-5393 , +-6245 , +-30599 , +-19945 , +20863 , +6053 , +-26935 , +-11519 , +-26035 , +-25623 , +-15121 , +7925 , +23915 , +32535 , +-739 , +-28353 , +-5675 , +-28907 , +-28065 , +-22985 , +19957 , +-21029 , +-12969 , +-29341 , +1689 , +-25925 , +27515 , +-28671 , +-29595 , +-13235 , +-30527 , +-31695 , +30677 , +29367 , +-5149 , +-23429 , +29611 , +14993 , +11533 , +-23563 , +-18963 , +-6095 , +-20709 , +22229 , +14173 , +25489 , +-7341 , +-14459 , +24941 , +19607 , +-12397 , +4167 , +27323 , +-20481 , +20245 , +-11969 , +6665 , +-2911 , +1441 , +-25837 , +10159 , +-26283 , +32063 , +9733 , +-2661 , +-9397 , +26239 , +-21117 , +-10809 , +-8999 , +29473 , +18501 , +-26839 , +25821 , +-15529 , +-27419 , +-28359 , +-12653 , +23927 , +-27917 , +-6689 , +16871 , +-22475 , +147 , +12777 , +-13227 , +24415 , +5263 , +25613 , +29247 , +-1265 , +-4881 , +-3493 , +-12099 , +357 , +-30183 , +9779 , +26627 , +15041 , +-20897 , +-18751 , +9773 , +16507 , +31263 , +27123 , +19099 , +24085 , +7255 , +-3085 , +14797 , +15609 , +28601 , +-13031 , +22965 , +21171 , +-9139 , +13933 , +-29039 , +-30301 , +21889 , +9369 , +28743 , +7221 , +-13117 , +18781 , +-12235 , +6817 , +-3941 , +-3187 , +-22639 , +-27879 , +-28607 , +-627 , +1597 , +-11131 , +31671 , +-32197 , +6683 , +-15423 , +14425 , +-28553 , +-6417 , +-17589 , +25093 , +-27377 , +-14671 , +-4737 , +4259 , +-19653 , +19041 , +-16047 , +6727 , +-15463 , +-27797 , +8581 , +-30271 , +12705 , +-17041 , +13923 , +8637 , +28569 , +28839 , +-32269 , +17497 , +14615 , +13497 , +-10573 , +5943 , +23537 , +-25587 , +8399 , +15389 , +16311 , +-8279 , +31195 , +-2551 , +-7251 , +907 , +32519 , +4807 , +-29889 , +7029 , +25051 , +28943 , +-12033 , +-14249 , +-21651 , +31511 , +22553 , +-31209 , +10781 , +28079 , +-11193 , +-7695 , +451 , +-15403 , +-24495 , +12625 , +22133 , +-24877 , +-25853 , +-7903 , +-30289 , +-32045 , +-32093 , +-2643 , +-32231 , +16371 , +-31003 , +-11533 , +-2629 , +24553 , +18795 , +-6787 , +11951 , +-4085 , +1211 , +17343 , +16991 , +-9 , +4531 , +-8225 , +13117 , +-21345 , +-31867 , +25123 , +-2823 , +4071 , +4651 , +17333 , +-13513 , +-4933 , +2917 , +16903 , +-1331 , +28585 , +-32215 , +-15705 , +17783 , +-9227 , +29861 , +16281 , +10251 , +32055 , +8367 , +21547 , +21309 , +-19093 , +16061 , +-32177 , +22217 , +32655 , +23395 , +18553 , +-2253 , +16063 , +1861 , +-24599 , +9729 , +12733 , +5525 , +31637 , +5229 , +25375 , +-24317 , +24431 , +22685 , +28113 , +3901 , +-22455 , +-25245 , +-4545 , +-13599 , +-25555 , +-11159 , +-2077 , +-5125 , +-9429 , +25333 , +26461 , +-30987 , +18619 , +16667 , +26899 , +-9707 , +1425 , +-31887 , +3133 , +4471 , +-28169 , +18255 , +14985 , +-9859 , +-20319 , +31109 , +-5075 , +30671 , +8713 , +28557 , +-3975 , +-23861 , +-12219 , +-13491 , +8959 , +-12409 , +-31905 , +-24253 , +25883 , +11837 , +-18897 , +22857 , +13331 , +3409 , +-23631 , +16837 , +13229 , +-9541 , +9435 , +19813 , +-31413 , +31755 , +30459 , +-3245 , +17275 , +13527 , +-32119 , +-22031 , +-1515 , +-11335 , +-17787 , +-3057 , +29395 , +24005 , +11337 , +30885 , +-20889 , +-3963 , +-10273 , +7435 , +25103 , +4711 , +-5913 , +-26201 , +-11845 , +10691 , +-6177 , +-32455 , +24209 , +21061 , +31747 , +12927 , +-24041 , +18673 , +-10843 , +-21383 , +28097 , +-22897 , +22783 , +-17123 , +-30967 , +8367 , +-24171 , +-32111 , +30735 , +2331 , +30211 , +-18723 , +19621 , +-15411 , +-15265 , +-16851 , +-27661 , +27499 , +16133 , +-4223 , +32391 , +23611 , +-19975 , +4069 , +28911 , +-8797 , +-22339 , +30767 , +-7469 , +-24041 , +31907 , +-8907 , +-7541 , +21911 , +25519 , +12925 , +5433 , +-3419 , +-26651 , +-24701 , +-29861 , +5565 , +12071 , +-157 , +16875 , +1871 , +-17525 , +-7395 , +-22541 , +-19405 , +19509 , +-29117 , +165 , +19625 , +-6483 , +-6599 , +-1547 , +-15931 , +4279 , +-13337 , +20399 , +-9873 , +-32087 , +-10251 , +-11507 , +4319 , +-26035 , +-3711 , +-20781 , +1415 , +-23001 , +-18601 , +16359 , +-25447 , +-24221 , +13225 , +23143 , +-24327 , +30743 , +-11701 , +21311 , +4021 , +27691 , +4451 , +-22969 , +-13571 , +-19797 , +-7001 , +-28459 , +-5223 , +-7775 , +17173 , +30937 , +26859 , +18021 , +-10453 , +30833 , +20309 , +-17275 , +18839 , +-6647 , +15687 , +7437 , +7801 , +12517 , +24227 , +-8603 , +-25315 , +-5557 , +-24897 , +-849 , +-17885 , +21257 , +18655 , +-15725 , +31819 , +17821 , +-12507 , +-30045 , +-11363 , +-11075 , +-4079 , +4393 , +23339 , +30337 , +-3467 , +28295 , +-701 , +5101 , +12269 , +21003 , +-3537 , +-10999 , +-23083 , +-27325 , +4447 , +389 , +-15161 , +-16415 , +-4817 , +-12859 , +13965 , +-27641 , +-20199 , +27777 , +-11617 , +15137 , +14959 , +15573 , +30995 , +11077 , +25483 , +27871 , +3103 , +23811 , +-1641 , +-5925 , +16387 , +-5695 , +21683 , +-4437 , +31123 , +-21875 , +2745 , +7685 , +29473 , +-4227 , +-19341 , +23797 , +-8201 , +-6267 , +15695 , +26887 , +-14763 , +-12085 , +-19043 , +27861 , +-14361 , +-30333 , +7997 , +29215 , +4279 , +-26303 , +11491 , +2155 , +9389 , +19165 , +27593 , +-2031 , +17283 , +-4417 , +-12315 , +23009 , +-25799 , +-8775 , +6823 , +-5333 , +281 , +21609 , +5161 , +-2457 , +26915 , +-16639 , +3823 , +-22463 , +-11257 , +-29265 , +-20965 , +10551 , +-5209 , +10599 , +26149 , +21421 , +1537 , +8521 , +-20461 , +24207 , +-14671 , +10343 , +26417 , +21593 , +5859 , +-973 , +18765 , +-20805 , +-21553 , +-13501 , +4455 , +-4435 , +-11345 , +13495 , +9455 , +-30455 , +-16071 , +30725 , +19325 , +-95 , +3475 , +-4767 , +26887 , +32469 , +-22321 , +24193 , +-19815 , +-10321 , +-3871 , +22537 , +21899 , +11901 , +10009 , +2897 , +2369 , +13791 , +-1003 , +-10035 , +-31911 , +20073 , +27205 , +6873 , +18025 , +25275 , +-26925 , +18709 , +-15563 , +-10227 , +-3797 , +3137 , +17513 , +27481 , +18665 , +23185 , +-25393 , +21217 , +4687 , +13439 , +4103 , +31829 , +-28345 , +6707 , +28093 , +16227 , +8915 , +-11955 , +-10393 , +23763 , +23817 , +-27841 , +10361 , +-24035 , +15753 , +15403 , +31005 , +2435 , +7797 , +-28105 , +-19603 , +-20829 , +-22037 , +15719 , +-19675 , +28567 , +-31753 , +-30739 , +-6171 , +-28023 , +-7403 , +32529 , +-3617 , +18379 , +-12511 , +-29575 , +12565 , +24691 , +16081 , +8199 , +-16621 , +4455 , +-13393 , +-32203 , +-13537 , +6919 , +13455 , +26345 , +-12043 , +11573 , +26245 , +22731 , +-24059 , +-8199 , +17509 , +-27357 , +-18145 , +6285 , +-6993 , +28713 , +-12105 , +13055 , +32275 , +-9753 , +13201 , +-14265 , +-17823 , +7047 , +-16375 , +26843 , +-22525 , +25905 , +5559 , +9163 , +503 , +17507 , +-6727 , +12885 , +1603 , +-25917 , +-8863 , +-24571 , +-27917 , +11649 , +9069 , +18239 , +-15989 , +25895 , +-8249 , +-1431 , +-18175 , +22003 , +-14923 , +12657 , +-4551 , +-22351 , +6287 , +5109 , +-29961 , +31761 , +8963 , +14285 , +13145 , +-10629 , +-26431 , +-5075 , +-7729 , +-16267 , +-9545 , +26937 , +4503 , +-24727 , +-27187 , +-17377 , +-4179 , +-5879 , +-19433 , +-14423 , +-13749 , +-14555 , +6287 , +12637 , +30429 , +-15363 , +7503 , +-27887 , +-6537 , +5919 , +19527 , +-14075 , +-24365 , +-21821 , +19063 , +-19337 , +24001 , +29079 , +28065 , +19135 , +29993 , +9503 , +-2933 , +18657 , +23929 , +1163 , +22957 , +25523 , +-3931 , +-21485 , +-18319 , +19553 , +-20583 , +-25399 , +-17179 , +24983 , +-17357 , +-29453 , +5623 , +25871 , +-15939 , +6371 , +-7637 , +3499 , +-31773 , +-5039 , +3795 , +-12789 , +19503 , +-975 , +8649 , +-22609 , +-4619 , +-5875 , +26019 , +25215 , +-26403 , +8667 , +-3985 , +243 , +12747 , +-8367 , +31979 , +-14179 , +27233 , +-28729 , +-29127 , +-18615 , +20209 , +-13433 , +-10725 , +-17255 , +-32007 , +27049 , +21929 , +-28655 , +-7141 , +-12951 , +12423 , +31673 , +-13425 , +1021 , +-21849 , +-3281 , +-23005 , +-13581 , +18543 , +20291 , +6831 , +5893 , +-30331 , +-31219 , +30479 , +13167 , +13815 , +14215 , +-25707 , +4555 , +-18947 , +-6493 , +7433 , +-7575 , +27693 , +-18719 , +-10979 , +-29405 , +-30159 , +-31123 , +-26265 , +8889 , +22533 , +-17233 , +20691 , +-8537 , +26027 , +-23187 , +8099 , +-11905 , +-24735 , +-20389 , +-7709 , +-13381 , +-17317 , +27955 , +-21407 , +-24289 , +3 , +-25515 , +-29659 , +23689 , +-14945 , +11219 , +15467 , +31817 , +-12647 , +30997 , +2843 , +-12541 , +-13517 , +-20759 , +-23623 , +2293 , +5563 , +-26593 , +-1813 , +-22045 , +6213 , +-16741 , +1123 , +19297 , +21733 , +12023 , +-27291 , +-4177 , +-30617 , +-18283 , +-6737 , +26899 , +-8321 , +563 , +11521 , +29101 , +-18801 , +19211 , +-5369 , +-29735 , +-9261 , +12391 , +8157 , +17141 , +-13279 , +20411 , +11009 , +-6965 , +-7653 , +7479 , +-30523 , +19295 , +-4121 , +-14615 , +9813 , +-12471 , +15217 , +31819 , +-31707 , +-1395 , +21779 , +-3487 , +24299 , +5111 , +-16165 , +31825 , +5911 , +6891 , +-5571 , +-28551 , +-28979 , +19397 , +23115 , +4615 , +-18855 , +-15187 , +-22423 , +14095 , +32557 , +25323 , +7569 , +25385 , +27989 , +28875 , +-32257 , +-12667 , +32617 , +15335 , +3439 , +20865 , +-23273 , +11273 , +-3629 , +11465 , +31749 , +29309 , +30857 , +9699 , +-29863 , +-5647 , +10779 , +-12209 , +-19029 , +16065 , +-1939 , +23331 , +6525 , +-2089 , +-7299 , +-17643 , +6193 , +30725 , +4241 , +-30429 , +-17529 , +-28713 , +-13313 , +28063 , +12687 , +-18453 , +27987 , +28623 , +-26841 , +-29745 , +-27115 , +507 , +-14099 , +-25257 , +-15625 , +8723 , +29369 , +14447 , +-22633 , +26301 , +5525 , +12153 , +19629 , +20715 , +15415 , +18471 , +26825 , +-17921 , +-27143 , +24777 , +-5237 , +-18857 , +12365 , +-6607 , +13141 , +-15253 , +-31049 , +-19963 , +-6773 , +-24479 , +-24247 , +-5741 , +-7863 , +-27607 , +-1645 , +-2765 , +17559 , +-25579 , +24099 , +10261 , +-989 , +14321 , +-29577 , +12449 , +-10885 , +16529 , +-18055 , +-5813 , +-29759 , +-26115 , +-16265 , +-24089 , +-14613 , +6645 , +12439 , +31117 , +-31375 , +31507 , +-3887 , +-7963 , +-6007 , +-19353 , +-19863 , +-8957 , +-9503 , +-29311 , +-5659 , +8895 , +-30249 , +-14567 , +-31097 , +-23917 , +10539 , +-20453 , +8259 , +-25369 , +-1725 , +32581 , +-11213 , +-10511 , +2005 , +18749 , +-30821 , +2065 , +-23771 , +-5333 , +-13997 , +6041 , +-2109 , +-15923 , +2507 , +17211 , +-12103 , +-31469 , +24953 , +-14897 , +-3509 , +8245 , +-25131 , +5807 , +1831 , +-8625 , +-13095 , +22937 , +-26589 , +-15507 , +-281 , +5883 , +1657 , +27189 , +30549 , +-11059 , +113 , +15857 , +853 , +-22541 , +26791 , +26923 , +-20619 , +22023 , +10173 , +20677 , +-27753 , +8121 , +-8049 , +-3181 , +-4761 , +-13403 , +-265 , +1653 , +16725 , +2481 , +6391 , +9445 , +-17915 , +-14633 , +6779 , +-4585 , +32343 , +-30325 , +13195 , +26259 , +13775 , +28301 , +265 , +30279 , +29587 , +-8641 , +-6173 , +-9437 , +16361 , +-28029 , +6861 , +26667 , +30757 , +1291 , +17019 , +-5861 , +15655 , +-8647 , +16471 , +-32145 , +10321 , +31861 , +953 , +-6645 , +32509 , +11261 , +-5727 , +13383 , +7295 , +10059 , +-24853 , +-7793 , +19087 , +-2079 , +-757 , +30833 , +16457 , +20391 , +-9913 , +-28605 , +32673 , +-3393 , +15971 , +-12239 , +-13979 , +-13853 , +2281 , +22229 , +-8283 , +-19143 , +24025 , +24149 , +-12615 , +14251 , +-3109 , +29939 , +-2893 , +-27971 , +-22779 , +8751 , +32595 , +27369 , +20231 , +20565 , +-26489 , +-29575 , +20457 , +21151 , +-1693 , +-5929 , +-8893 , +-8257 , +7053 , +25707 , +26609 , +-9977 , +-16059 , +-29453 , +11853 , +13813 , +3027 , +-12203 , +26349 , +-5035 , +-10111 , +19459 , +-563 , +11469 , +-25583 , +-13117 , +23575 , +-13315 , +29887 , +5909 , +12879 , +12315 , +-21849 , +4101 , +-17135 , +-25857 , +22227 , +-8573 , +31815 , +10435 , +26781 , +-25287 , +-11035 , +23259 , +-15943 , +-19225 , +-27369 , +-30805 , +-24415 , +30525 , +-11517 , +1697 , +4501 , +4653 , +7681 , +28871 , +-25075 , +29633 , +31303 , +-12829 , +-3405 , +13951 , +7987 , +1549 , +-19489 , +11829 , +28659 , +28609 , +14471 , +-21161 , +9925 , +-11649 , +25535 , +6869 , +10927 , +-18977 , +21677 , +-3981 , +1971 , +21799 , +9471 , +-18013 , +-32371 , +3943 , +28135 , +10969 , +14565 , +-21485 , +-13421 , +-5783 , +-9465 , +19473 , +5923 , +7127 , +-11227 , +24413 , +-28897 , +23227 , +-1023 , +30487 , +-22925 , +6663 , +13611 , +19493 , +-19993 , +8945 , +30401 , +-11711 , +11283 , +13893 , +14485 , +-20587 , +-14371 , +28467 , +-17927 , +-3879 , +2407 , +32439 , +6889 , +20959 , +-25193 , +22375 , +-16441 , +-3403 , +10235 , +25039 , +-2157 , +-11975 , +-16555 , +-11965 , +23719 , +-8399 , +-12157 , +12609 , +-6165 , +3301 , +-24575 , +-15553 , +11911 , +8243 , +8667 , +-15093 , +-15827 , +-20437 , +24617 , +14239 , +11193 , +7461 , +10245 , +15991 , +30847 , +-8867 , +13573 , +-20625 , +-11789 , +-2559 , +-27857 , +-5357 , +6127 , +-1837 , +28533 , +-27265 , +-2725 , +24125 , +3755 , +18355 , +26481 , +-27667 , +8959 , +-11923 , +12151 , +-26653 , +14325 , +9081 , +9959 , +30741 , +27861 , +31385 , +-4549 , +-29057 , +13745 , +-7477 , +-4589 , +-11845 , +23247 , +-21715 , +8959 , +4643 , +-4437 , +-7595 , +-21595 , +31577 , +29291 , +29473 , +-28281 , +12909 , +-7977 , +-1519 , +-15311 , +26735 , +-10287 , +-5335 , +-16645 , +-18045 , +-26545 , +8253 , +-11977 , +12421 , +5329 , +26573 , +-32529 , +-14575 , +-14759 , +11359 , +27 , +-17877 , +32740 , +-13227 , +11353 , +-29877 , +-1951 , +-17849 , +4393 , +1533 , +17193 , +-555 , +25759 , +8689 , +-4361 , +11529 , +-2405 , +6553 , +869 , +30247 , +-30073 , +-29373 , +-27429 , +-11769 , +5003 , +2729 , +9997 , +-2321 , +-13499 , +-12017 , +-27153 , +9189 , +6913 , +10717 , +-17099 , +23701 , +-12429 , +11693 , +-27073 , +11669 , +-28949 , +19949 , +1181 , +-28337 , +2577 , +31477 , +2303 , +3403 , +-8421 , +16029 , +-27985 , +-24555 , +-22647 , +-23727 , +-22647 , +-26745 , +10325 , +16305 , +6777 , +-6229 , +7343 , +16041 , +-30621 , +6671 , +-27847 , +-17409 , +-11343 , +28061 , +21947 , +19829 , +-10695 , +16115 , +21335 , +4187 , +-32325 , +20795 , +-31411 , +5039 , +9947 , +3975 , +17957 , +30377 , +6811 , +24227 , +-27789 , +5085 , +29257 , +5997 , +12801 , +4305 , +3587 , +-15947 , +11419 , +10765 , +-22107 , +-22645 , +-23247 , +5059 , +11337 , +-9955 , +28833 , +-14637 , +-4549 , +14605 , +29921 , +4727 , +11631 , +10573 , +16837 , +19019 , +26751 , +-3987 , +-9175 , +26863 , +-10213 , +28545 , +13233 , +32539 , +-16629 , +16489 , +15109 , +-14539 , +-14179 , +-11079 , +6777 , +13677 , +11685 , +-21241 , +30043 , +-9129 , +-10259 , +16581 , +14741 , +-519 , +15415 , +-20841 , +-3591 , +8559 , +8875 , +-13007 , +4839 , +1275 , +5591 , +-19283 , +14739 , +-15201 , +-20449 , +22623 , +-10823 , +3381 , +32703 , +18731 , +13771 , +-19443 , +-18121 , +14443 , +28091 , +-29959 , +28753 , +21303 , +4131 , +-14099 , +-28787 , +3653 , +12809 , +-8425 , +17949 , +31295 , +-20213 , +4725 , +9311 , +-18277 , +13347 , +-19987 , +-24875 , +-22279 , +-8489 , +16615 , +12183 , +26349 , +12021 , +28257 , +-12717 , +-20379 , +-825 , +12427 , +-2367 , +-13191 , +5583 , +-8993 , +-2659 , +2761 , +27133 , +-27469 , +-19431 , +29517 , +17259 , +-8613 , +-17955 , +-16717 , +-32629 , +-15689 , +-25221 , +12089 , +18667 , +18259 , +-25753 , +25085 , +13413 , +-25353 , +-29839 , +-20261 , +23769 , +-9525 , +-4935 , +15555 , +21095 , +-25121 , +16427 , +14483 , +27173 , +25935 , +26997 , +-29589 , +24409 , +731 , +20095 , +27021 , +-16597 , +-2059 , +28005 , +-6489 , +5863 , +5991 , +-24337 , +15547 , +23725 , +17243 , +-13439 , +-17301 , +-30039 , +-24573 , +-24417 , +5081 , +-6957 , +4771 , +17633 , +-777 , +-7909 , +25911 , +-925 , +-5015 , +10799 , +-6533 , +-24629 , +-10031 , +-19293 , +-8557 , +4017 , +-19787 , +24251 , +-20455 , +24233 , +-23351 , +4753 , +-589 , +-5719 , +-19247 , +-7463 , +-21449 , +5903 , +-8971 , +6679 , +6453 , +-3053 , +13719 , +-19373 , +24091 , +26811 , +18355 , +15189 , +-2109 , +14941 , +8107 , +32091 , +-21869 , +-27507 , +14505 , +5711 , +-1267 , +20639 , +-10123 , +17289 , +4849 , +-19563 , +-3127 , +-1545 , +27341 , +-9573 , +13099 , +-18719 , +4117 , +-29181 , +12359 , +797 , +-8253 , +-19783 , +-31803 , +8395 , +-29341 , +4661 , +-17501 , +-9341 , +-12617 , +-20219 , +-11767 , +-3303 , +-31803 , +27567 , +15523 , +6349 , +13177 , +4665 , +11391 , +-2299 , +-19277 , +-17893 , +5719 , +15241 , +23525 , +32437 , +7033 , +7217 , +-31449 , +26701 , +27413 , +20013 , +-11559 , +-20095 , +13333 , +-6231 , +-1879 , +9027 , +16251 , +9237 , +27453 , +-16563 , +-13517 , +-32039 , +-13245 , +28957 , +-17041 , +14473 , +27397 , +-657 , +-14209 , +27297 , +-20085 , +-6101 , +-26845 , +11703 , +-10711 , +-30489 , +-26261 , +-16833 , +-22115 , +1501 , +-30197 , +-5197 , +-9817 , +27999 , +17459 , +11869 , +-32738 , +-23087 , +487 , +24445 , +22155 , +27685 , +-25895 , +-29683 , +26171 , +6345 , +-9283 , +-9737 , +-29469 , +25391 , +-29145 , +-2101 , +-21079 , +-9293 , +18653 , +3827 , +-6455 , +21537 , +-24399 , +-20363 , +-23643 , +-4445 , +-11811 , +-19421 , +-7329 , +2879 , +31187 , +-32169 , +-29709 , +-13359 , +31131 , +-16343 , +8653 , +26235 , +-26453 , +-10717 , +-17441 , +-349 , +63 , +18823 , +-29631 , +15469 , +10025 , +24563 , +-10945 , +23207 , +17973 , +1451 , +-23817 , +-7343 , +-4867 , +28231 , +8561 , +-11635 , +-12487 , +26605 , +-6351 , +22547 , +25249 , +-9975 , +3159 , +-4301 , +25925 , +24713 , +26163 , +1345 , +-7077 , +-28531 , +-16545 , +-6501 , +-9311 , +-17499 , +25681 , +10773 , +1329 , +-13173 , +-9091 , +21235 , +-3619 , +8271 , +10211 , +-7829 , +507 , +-9437 , +22831 , +-30323 , +22221 , +-20609 , +-7093 , +-14133 , +21585 , +-28701 , +31097 , +-28185 , +-13421 , +17167 , +-15121 , +18281 , +26005 , +21177 , +-5399 , +-17247 , +26261 , +19653 , +6211 , +29975 , +25075 , +-12545 , +-111 , +-9591 , +-2431 , +21841 , +-25923 , +-24229 , +11101 , +17019 , +2321 , +5011 , +-31411 , +6985 , +-7715 , +31319 , +27791 , +27729 , +-11381 , +24027 , +-1223 , +21031 , +-6351 , +-11297 , +-13301 , +7191 , +16557 , +-27485 , +-7731 , +341 , +-19643 , +3687 , +16157 , +24773 , +685 , +12121 , +18131 , +-31969 , +10417 , +7699 , +31957 , +22459 , +30533 , +-26481 , +-16537 , +9147 , +-4325 , +12711 , +-28401 , +-25657 , +-23875 , +9473 , +-29979 , +24647 , +32295 , +-1645 , +-28817 , +21527 , +19167 , +-21867 , +-10763 , +-14905 , +18567 , +-28941 , +26207 , +-7353 , +12799 , +-18605 , +7557 , +28715 , +1781 , +-1407 , +-11761 , +13911 , +29181 , +26737 , +-20021 , +10567 , +9009 , +23465 , +28543 , +-19533 , +-2243 , +-7863 , +22855 , +10201 , +17155 , +-20615 , +-4243 , +-13781 , +7081 , +25187 , +5057 , +28297 , +-3269 , +14249 , +26983 , +8185 , +25017 , +101 , +-701 , +-13599 , +29365 , +-32359 , +-12609 , +25023 , +20329 , +-1241 , +20777 , +29787 , +-25265 , +3407 , +32143 , +-20089 , +26939 , +-19293 , +-29425 , +19281 , +-2317 , +-27521 , +-3143 , +-19007 , +19777 , +18429 , +-19491 , +-18421 , +-10607 , +-3717 , +-24087 , +18505 , +-4597 , +-16253 , +-20287 , +10677 , +-20191 , +-22969 , +-8557 , +-15009 , +-4681 , +-3933 , +-9679 , +13671 , +-31577 , +905 , +-1809 , +-1361 , +6379 , +-5889 , +-27411 , +21789 , +25385 , +-4205 , +27649 , +-18871 , +465 , +3927 , +5885 , +18109 , +7607 , +19801 , +12691 , +-2649 , +-17629 , +-10855 , +19117 , +2837 , +3949 , +893 , +13625 , +-19285 , +-19689 , +4309 , +-11885 , +-31523 , +2151 , +-23737 , +-6321 , +23711 , +-20873 , +-4021 , +10131 , +-18513 , +22739 , +-20569 , +-4107 , +-11467 , +-7281 , +-27553 , +-6707 , +-22767 , +-1057 , +-31693 , +533 , +10629 , +13617 , +17817 , +9653 , +-10893 , +-7485 , +-9173 , +-12699 , +-5357 , +-29251 , +19373 , +1025 , +25387 , +24515 , +-1671 , +5727 , +3271 , +23061 , +25723 , +17325 , +-12941 , +-20189 , +27563 , +-8381 , +31731 , +9383 , +-9469 , +4353 , +19829 , +-21449 , +30455 , +-15073 , +19793 , +20583 , +15985 , +-7027 , +-10435 , +-30631 , +6977 , +28101 , +-29693 , +-3117 , +-18149 , +-31193 , +-18239 , +-13851 , +-17651 , +7119 , +-22381 , +-11279 , +1915 , +12269 , +-10019 , +19785 , +25229 , +24991 , +-30733 , +32585 , +3893 , +-11961 , +-27045 , +29169 , +-20839 , +-2975 , +12925 , +-30475 , +5653 , +29155 , +18147 , +25945 , +21423 , +-24823 , +8943 , +-7281 , +-26353 , +-19273 , +22031 , +-29183 , +17655 , +21839 , +13689 , +23611 , +-15555 , +31491 , +1117 , +5747 , +31553 , +26295 , +13991 , +13735 , +-31515 , +-22705 , +-14801 , +-26563 , +23557 , +-11891 , +4725 , +-7415 , +19057 , +103 , +17111 , +-6407 , +-16285 , +-18975 , +-23737 , +-7395 , +21367 , +13411 , +-3193 , +-1209 , +-25565 , +-6001 , +8419 , +-17627 , +-22095 , +-1119 , +25183 , +-559 , +17587 , +-22981 , +12157 , +4593 , +-18429 , +23497 , +2405 , +29257 , +22573 , +26191 , +-29011 , +-5419 , +-32393 , +2761 , +-11897 , +-32155 , +17487 , +-12803 , +26743 , +173 , +30789 , +-3625 , +12695 , +26853 , +28035 , +-15551 , +16451 , +16607 , +-2875 , +-12173 , +-4777 , +-873 , +-2603 , +-24613 , +-32283 , +26197 , +19581 , +-155 , +29805 , +23365 , +9217 , +-31655 , +-20331 , +-19321 , +-30441 , +21433 , +-7837 , +-19251 , +27235 , +-13555 , +13811 , +-11663 , +-16535 , +8647 , +-26447 , +13837 , +3591 , +-25839 , +-12021 , +-14953 , +1645 , +24621 , +-30795 , +5103 , +28055 , +-25785 , +-23215 , +3333 , +3655 , +-5421 , +947 , +-18843 , +-6031 , +-15011 , +-5735 , +-9135 , +22337 , +-6681 , +18651 , +867 , +25999 , +22721 , +14121 , +30361 , +2259 , +16607 , +-26301 , +-13841 , +31389 , +-4687 , +30891 , +-22145 , +26773 , +22909 , +-1051 , +19727 , +13033 , +-22481 , +31021 , +26671 , +-3763 , +-16701 , +-25685 , +-4397 , +30315 , +-29945 , +4909 , +-31133 , +2533 , +5123 , +-14751 , +-1193 , +4291 , +-5431 , +-117 , +-27821 , +23665 , +5075 , +-29763 , +-27719 , +22583 , +211 , +17551 , +-11067 , +-13009 , +-19695 , +-933 , +-18141 , +29883 , +-25019 , +17647 , +25093 , +4481 , +25573 , +2243 , +30661 , +18145 , +-245 , +28351 , +24299 , +-6415 , +30909 , +99 , +12759 , +-4371 , +-17193 , +-30073 , +22223 , +-5577 , +-22703 , +-20337 , +2715 , +-3129 , +-7645 , +-21973 , +-18533 , +3627 , +-21603 , +9093 , +29019 , +2555 , +7477 , +-18431 , +27831 , +-19759 , +2793 , +-147 , +-13211 , +31427 , +4885 , +-23103 , +-26087 , +23641 , +-2363 , +-31407 , +17429 , +11009 , +-11625 , +15245 , +30529 , +2577 , +20487 , +12331 , +-21047 , +16953 , +26453 , +-30995 , +18991 , +11639 , +-13873 , +-3115 , +-26903 , +29083 , +-29519 , +-5673 , +-32141 , +16689 , +11393 , +7191 , +28649 , +-9471 , +-32551 , +-13919 , +-3039 , +9 , +-18227 , +-13411 , +-10433 , +-26645 , +-2117 , +-8691 , +13013 , +15345 , +-21847 , +6911 , +1133 , +-8067 , +11799 , +8263 , +3251 , +21767 , +-9129 , +-10311 , +21245 , +-11637 , +7275 , +23007 , +9579 , +20621 , +-30375 , +-7375 , +-4739 , +-10101 , +-13821 , +21455 , +-20179 , +-28687 , +12673 , +12725 , +-26489 , +-20323 , +-16395 , +-23175 , +20411 , +10183 , +-25627 , +27003 , +-25155 , +4999 , +-25577 , +9127 , +1879 , +-10553 , +-1563 , +8609 , +-10555 , +-1093 , +-15345 , +-4215 , +24525 , +-25383 , +10789 , +-16083 , +-10159 , +-29615 , +14407 , +9659 , +-25229 , +-3579 , +7061 , +-501 , +15643 , +-26619 , +-30991 , +11583 , +7205 , +-25215 , +20587 , +-1007 , +4323 , +-14269 , +-8439 , +-22915 , +-13751 , +11433 , +-32473 , +3071 , +23411 , +25627 , +17233 , +-1465 , +-15415 , +2561 , +24465 , +2679 , +-13415 , +-18623 , +-8877 , +-30505 , +3359 , +13363 , +31157 , +24331 , +-32211 , +6423 , +28771 , +30927 , +28225 , +-27373 , +15595 , +-25809 , +-747 , +-27739 , +-4965 , +9785 , +28089 , +-1891 , +6355 , +-18113 , +8757 , +10905 , +8669 , +12679 , +27539 , +-23561 , +-15791 , +-1147 , +27263 , +-15795 , +-27945 , +11921 , +-9119 , +-29591 , +-26987 , +27433 , +11501 , +-22849 , +26617 , +-3173 , +-23487 , +11881 , +7701 , +-2235 , +2431 , +-19815 , +-32131 , +-30643 , +-28197 , +1171 , +-20589 , +13271 , +29757 , +5671 , +-20633 , +-19271 , +-1705 , +-24919 , +13073 , +-18239 , +24631 , +-16795 , +-1405 , +12379 , +28523 , +22681 , +1249 , +8403 , +2697 , +23535 , +8545 , +28945 , +-23467 , +-20107 , +-1895 , +-22331 , +-6831 , +2577 , +9823 , +6695 , +24281 , +17017 , +31769 , +28209 , +-23879 , +-27211 , +925 , +2895 , +-26811 , +22027 , +-9595 , +20127 , +24561 , +25721 , +32263 , +4003 , +-19859 , +7859 , +-24755 , +26235 , +-4045 , +-1129 , +6223 , +11425 , +-9045 , +-29145 , +6441 , +12317 , +18365 , +9979 , +9713 , +-28359 , +-31511 , +-13245 , +-747 , +17089 , +1755 , +-16333 , +-465 , +9399 , +-2161 , +19977 , +10587 , +-20083 , +9437 , +5495 , +20243 , +-18983 , +6549 , +-29529 , +-30585 , +2703 , +-17639 , +-3929 , +-28559 , +-13891 , +17269 , +23663 , +5233 , +-2627 , +-4109 , +15947 , +-26909 , +2799 , +15415 , +-7203 , +-1737 , +29685 , +467 , +21649 , +18125 , +22625 , +21605 , +12949 , +-10175 , +-16901 , +29225 , +-9645 , +26455 , +29805 , +-24301 , +30819 , +11071 , +-15489 , +20589 , +19983 , +-27273 , +21459 , +22241 , +-9157 , +-14557 , +18967 , +-23263 , +11501 , +22245 , +3261 , +17651 , +-3271 , +32561 , +-21443 , +-817 , +-17987 , +19751 , +26047 , +28661 , +-10337 , +-6165 , +14427 , +4869 , +25593 , +-30589 , +1233 , +-13029 , +-8229 , +14885 , +12221 , +-25251 , +-12611 , +-1263 , +15955 , +7457 , +-2689 , +22001 , +26007 , +13945 , +30675 , +2983 , +-31725 , +-6321 , +-29625 , +-6737 , +32267 , +26879 , +-341 , +18669 , +29759 , +-27537 , +14615 , +-24313 , +-13029 , +-9565 , +2907 , +15433 , +-30605 , +-22057 , +-5893 , +-20503 , +-10825 , +-26853 , +-10845 , +23791 , +25775 , +9317 , +-18393 , +11655 , +26803 , +31529 , +19437 , +8923 , +-14755 , +-3205 , +26869 , +-13467 , +25549 , +-16489 , +-9657 , +14799 , +4945 , +-27641 , +31467 , +-27579 , +4267 , +-23501 , +-11927 , +-11179 , +-30525 , +-13443 , +-7755 , +-12485 , +9181 , +15063 , +28081 , +7873 , +2645 , +-32037 , +23589 , +665 , +23509 , +21091 , +32299 , +-11731 , +-28401 , +-15963 , +27447 , +5887 , +-16397 , +-32319 , +-21629 , +-6275 , +14951 , +-14105 , +-5873 , +-26027 , +32637 , +21219 , +24337 , +27225 , +-2253 , +20025 , +16377 , +8907 , +28831 , +-29249 , +18903 , +27703 , +-9547 , +-10573 , +16743 , +-11821 , +12145 , +-23721 , +-29829 , +5967 , +2457 , +12799 , +-25351 , +-2255 , +-8977 , +14515 , +31055 , +-7769 , +18669 , +5445 , +-2193 , +-11289 , +32255 , +-11803 , +1351 , +-8185 , +11567 , +-10693 , +-24139 , +32073 , +-1425 , +-25341 , +-15099 , +14593 , +-5825 , +17951 , +-4127 , +-8215 , +-17419 , +23859 , +-26415 , +-18445 , +-17049 , +-21321 , +12333 , +-7513 , +-4817 , +30105 , +-3431 , +32766 , +1625 , +-7347 , +16893 , +-22099 , +22689 , +5223 , +-17161 , +-8437 , +-5075 , +-28747 , +-13091 , +-1691 , +-6213 , +32215 , +-7639 , +16593 , +-20123 , +32591 , +6015 , +-18039 , +-15919 , +30503 , +29465 , +16837 , +-24083 , +8703 , +32451 , +-26603 , +2851 , +-11869 , +28245 , +-7633 , +-24043 , +9519 , +-29527 , +-13229 , +17365 , +5531 , +10003 , +-9959 , +23959 , +11991 , +-20643 , +-1585 , +18163 , +19813 , +19511 , +1875 , +5781 , +-18319 , +-28619 , +13153 , +-5769 , +-3995 , +-28859 , +2681 , +5273 , +2565 , +2729 , +7721 , +14653 , +-4605 , +-5265 , +-4113 , +-19563 , +21789 , +-15519 , +13451 , +23561 , +-10065 , +-29557 , +2013 , +4833 , +-4145 , +24359 , +10553 , +3721 , +12515 , +22043 , +-10183 , +25665 , +-20553 , +23023 , +27173 , +-15531 , +-12259 , +2629 , +12221 , +-9507 , +25851 , +32211 , +-15469 , +25065 , +29673 , +4313 , +22761 , +14919 , +30023 , +-1511 , +8967 , +-23123 , +26837 , +-8625 , +27915 , +1401 , +-26929 , +6699 , +31311 , +7403 , +21885 , +-1337 , +-14539 , +19927 , +-21679 , +-25443 , +-15741 , +-14371 , +9597 , +-22265 , +-26817 , +8743 , +-17647 , +-21971 , +7939 , +22429 , +5251 , +11651 , +-27439 , +-25189 , +4059 , +27837 , +8307 , +3377 , +-9923 , +-19123 , +-11695 , +-26927 , +28677 , +18009 , +10179 , +14475 , +-3997 , +-8919 , +-20493 , +-4409 , +31085 , +-22477 , +-5845 , +22395 , +1975 , +-10113 , +-4429 , +32744 , +7285 , +-30295 , +3881 , +-11069 , +-30461 , +14427 , +-7341 , +-21245 , +14091 , +32575 , +-637 , +26375 , +17685 , +21113 , +-13985 , +-28585 , +20387 , +29087 , +-19385 , +4053 , +16071 , +18485 , +13863 , +-13695 , +28731 , +-2915 , +-11571 , +-17757 , +-27141 , +-21095 , +-21561 , +-3699 , +8535 , +15927 , +-17739 , +31695 , +-28009 , +-12203 , +19491 , +-24595 , +-31483 , +-17009 , +-11549 , +28573 , +-12401 , +-24897 , +-21531 , +9083 , +-28201 , +20975 , +-5497 , +14653 , +-31271 , +11991 , +-14979 , +-13193 , +28141 , +8655 , +-17383 , +8643 , +-2185 , +-6841 , +3115 , +-9077 , +-5653 , +4551 , +-28585 , +-10449 , +-1423 , +15453 , +-24849 , +5579 , +7163 , +-9317 , +327 , +-13467 , +-23591 , +11025 , +-25711 , +-5715 , +6867 , +-15047 , +-8905 , +13105 , +4807 , +11265 , +-28247 , +18455 , +-10061 , +-2123 , +10687 , +-23219 , +23387 , +-7047 , +5519 , +3663 , +7771 , +30279 , +18111 , +22867 , +-28225 , +27493 , +29541 , +5641 , +-23013 , +-19113 , +12635 , +1741 , +-2779 , +12383 , +-32231 , +-7073 , +22215 , +-11923 , +-6395 , +25635 , +15041 , +-32093 , +-27047 , +-1839 , +-24901 , +26177 , +-6031 , +17839 , +-1831 , +-18401 , +-27229 , +-17333 , +-4387 , +1451 , +-9059 , +23725 , +12723 , +-2979 , +10553 , +4123 , +21911 , +20143 , +21459 , +-27067 , +-351 , +-28777 , +4391 , +31999 , +14817 , +-23429 , +-21855 , +6785 , +23291 , +7597 , +-26819 , +535 , +13879 , +-31391 , +3291 , +-5287 , +3873 , +5415 , +8727 , +-31765 , +5021 , +-32289 , +-26461 , +9131 , +-17539 , +5685 , +-6119 , +-9361 , +-7009 , +-11371 , +-24227 , +-10691 , +895 , +-11859 , +-15763 , +-31491 , +16467 , +-27565 , +4793 , +-29509 , +-10079 , +-28657 , +8197 , +-4265 , +-25259 , +-27383 , +-3153 , +26301 , +-6815 , +22659 , +6299 , +27299 , +-13109 , +-11051 , +2429 , +-10049 , +6219 , +-18469 , +-24651 , +-18569 , +-27295 , +-26631 , +-25943 , +2855 , +20205 , +10125 , +-10341 , +13771 , +28235 , +7907 , +20993 , +-9917 , +8419 , +5303 , +-31647 , +-19455 , +23111 , +-731 , +16799 , +28745 , +-13621 , +-30941 , +-24863 , +-8733 , +-7527 , +4221 , +1501 , +-29099 , +14671 , +26689 , +1981 , +19361 , +12815 , +6091 , +2151 , +24945 , +13341 , +27177 , +23137 , +12503 , +20475 , +-5603 , +-7385 , +1671 , +-22285 , +-29033 , +-8191 , +-21627 , +31547 , +19879 , +-7337 , +-22419 , +5773 , +19959 , +-23915 , +-19689 , +-23241 , +28357 , +-21387 , +16097 , +6071 , +24151 , +-24607 , +-22691 , +3287 , +-2309 , +-1209 , +-4725 , +3647 , +6769 , +7279 , +32657 , +-1647 , +-15375 , +-30501 , +759 , +-4609 , +-30561 , +5781 , +-26283 , +-27037 , +15999 , +3467 , +-26727 , +10201 , +495 , +-9879 , +10163 , +-4909 , +20897 , +25585 , +-13101 , +-19275 , +30989 , +-20527 , +16925 , +-21 , +375 , +-13319 , +-21529 , +16513 , +24915 , +-18569 , +-27797 , +1855 , +-23985 , +19917 , +-23293 , +30009 , +13759 , +-11315 , +-22303 , +-13841 , +-20579 , +15591 , +-20929 , +26079 , +-24581 , +-16113 , +-7899 , +6557 , +17149 , +-9467 , +663 , +6519 , +16211 , +18237 , +-1201 , +28025 , +11057 , +6957 , +-32525 , +13845 , +4035 , +-29403 , +17875 , +-25291 , +-23769 , +-31569 , +-21731 , +-13359 , +28903 , +-29863 , +28053 , +-17395 , +-22287 , +13855 , +17613 , +16333 , +-13047 , +-24781 , +-4897 , +5065 , +-2869 , +2143 , +-27999 , +22319 , +-8167 , +15831 , +6755 , +16307 , +-28647 , +-11885 , +14623 , +25129 , +-24915 , +-14547 , +-10183 , +26529 , +3175 , +-14291 , +-17485 , +-30987 , +-17147 , +30953 , +-7451 , +-25873 , +23145 , +1505 , +-25675 , +11475 , +-10741 , +-32375 , +-16305 , +19331 , +16635 , +10925 , +5983 , +-30965 , +12877 , +13131 , +20169 , +-5945 , +29727 , +8155 , +-30501 , +16367 , +12035 , +22331 , +-3057 , +-25933 , +19457 , +-1287 , +25909 , +17367 , +17677 , +-24529 , +27711 , +7363 , +7159 , +219 , +-9373 , +-21469 , +-20495 , +15805 , +14565 , +-18181 , +10619 , +-14173 , +4931 , +-13763 , +-19231 , +-28853 , +-20493 , +25319 , +17201 , +32439 , +3225 , +21143 , +-30283 , +-2301 , +-21821 , +-3425 , +-2075 , +18371 , +7701 , +-22619 , +-9237 , +-13097 , +-10989 , +32699 , +28043 , +-15423 , +5195 , +17645 , +-2133 , +29059 , +-25581 , +-9117 , +-10177 , +-20241 , +-3909 , +18933 , +-28987 , +-32375 , +-17073 , +12355 , +-28349 , +-20781 , +18633 , +9551 , +8115 , +10291 , +30149 , +-19569 , +-12797 , +8509 , +17601 , +24465 , +-879 , +-28011 , +20691 , +-30203 , +-2283 , +13121 , +16093 , +-31137 , +-3543 , +-32119 , +-26809 , +-16917 , +-24781 , +-1471 , +567 , +14177 , +-28951 , +433 , +24143 , +23305 , +6721 , +-18205 , +-22057 , +19271 , +2539 , +13433 , +13957 , +-22087 , +-19381 , +16915 , +8107 , +8395 , +-13843 , +19733 , +31469 , +-30253 , +-30587 , +31755 , +15237 , +1963 , +-29607 , +-24963 , +16369 , +-4671 , +-1975 , +841 , +-32215 , +-13389 , +11325 , +-12425 , +-7585 , +30059 , +-15843 , +-4717 , +-31689 , +24497 , +2383 , +11657 , +13941 , +10567 , +-18261 , +-21255 , +-8897 , +-22399 , +3827 , +8203 , +22227 , +21845 , +6601 , +4815 , +-11593 , +26623 , +23341 , +-17645 , +4993 , +-31723 , +-31375 , +29367 , +-27907 , +18457 , +-31313 , +29319 , +243 , +-26217 , +-27449 , +-6761 , +5207 , +1469 , +-31023 , +-4847 , +9987 , +3695 , +4375 , +-21349 , +-27663 , +-17437 , +16015 , +-2269 , +20465 , +19129 , +-13613 , +-19395 , +-19229 , +20109 , +-25707 , +-27143 , +-2199 , +8473 , +4251 , +14139 , +16169 , +-2619 , +25137 , +14997 , +-9861 , +27071 , +-14801 , +-32357 , +32423 , +-5991 , +-27811 , +5313 , +8609 , +-17059 , +7035 , +-11347 , +16943 , +10275 , +29621 , +-31215 , +14779 , +20529 , +-7275 , +25861 , +31349 , +27269 , +12929 , +-19233 , +14615 , +-4867 , +-29771 , +-30843 , +30999 , +9701 , +12469 , +16207 , +-3229 , +4113 , +-19901 , +-5549 , +-12391 , +-17545 , +-6173 , +3657 , +-22597 , +8769 , +24009 , +-803 , +-12693 , +-15759 , +29007 , +18563 , +20385 , +-11285 , +-11271 , +29145 , +-23583 , +29461 , +-21279 , +25973 , +-29189 , +-26639 , +4275 , +-7609 , +6971 , +12715 , +2085 , +24677 , +15903 , +16063 , +-8971 , +-28563 , +-1125 , +14725 , +-6825 , +2905 , +-23867 , +-20145 , +-31247 , +19161 , +1811 , +26619 , +-23981 , +-32215 , +13583 , +-13289 , +13301 , +28517 , +-26219 , +10095 , +16291 , +-17045 , +4999 , +23073 , +-7807 , +3629 , +-6141 , +31303 , +-22665 , +17797 , +4383 , +12281 , +-3531 , +11417 , +-8417 , +9717 , +-27483 , +1441 , +25647 , +26289 , +27105 , +10325 , +-23913 , +-525 , +6575 , +16051 , +-2695 , +-18711 , +-15497 , +14939 , +-21501 , +20161 , +-14405 , +-25999 , +20265 , +-3133 , +26641 , +6633 , +-30241 , +26855 , +30105 , +24163 , +11215 , +-23059 , +-14861 , +-16507 , +16017 , +19447 , +-22847 , +-16685 , +-23195 , +-14691 , +1933 , +18431 , +16233 , +29063 , +-28079 , +20945 , +1101 , +-25971 , +27245 , +-2195 , +5017 , +-18371 , +-13803 , +-24007 , +11857 , +-21245 , +13907 , +23597 , +-27839 , +28349 , +-32391 , +-7507 , +-19037 , +-5427 , +21535 , +-28187 , +-14747 , +32441 , +29847 , +-16229 , +-30757 , +-8899 , +-31519 , +-23417 , +25591 , +-18455 , +28461 , +22323 , +15613 , +1331 , +14537 , +4935 , +-3897 , +15121 , +29603 , +17007 , +1649 , +22035 , +1589 , +29605 , +32407 , +1271 , +-32247 , +-11757 , +15881 , +-12089 , +-16215 , +13415 , +2827 , +-26261 , +-233 , +23723 , +-27391 , +16071 , +12239 , +-32611 , +32433 , +-12727 , +-17617 , +-19831 , +-7433 , +3341 , +26235 , +17053 , +19455 , +-18833 , +-26285 , +-20283 , +-27401 , +18209 , +-18005 , +18181 , +-20911 , +-21305 , +-10695 , +-3003 , +-17293 , +-19955 , +22399 , +32699 , +-30481 , +32577 , +-4299 , +-21323 , +-16829 , +1895 , +32327 , +26353 , +-6649 , +-17963 , +10567 , +-28797 , +-24149 , +20555 , +21363 , +-32229 , +5549 , +4485 , +-18407 , +-5395 , +-173 , +24669 , +23201 , +1273 , +27873 , +-4261 , +-31495 , +-9995 , +-28593 , +28877 , +-29549 , +-27501 , +-23419 , +7013 , +-27171 , +-28059 , +23829 , +-9395 , +3639 , +10803 , +-10133 , +-30785 , +5225 , +-7727 , +-29557 , +-2789 , +-30817 , +5749 , +9797 , +15237 , +-2847 , +-18797 , +-11529 , +2555 , +6921 , +9269 , +-4939 , +24037 , +15671 , +-10289 , +-32499 , +30521 , +-1067 , +-9317 , +-21955 , +24845 , +-5117 , +-18579 , +13029 , +-6485 , +-23149 , +-6893 , +31819 , +19765 , +32643 , +25891 , +7939 , +-22097 , +-19725 , +-29607 , +15927 , +11167 , +7327 , +-24213 , +1361 , +13351 , +21715 , +25447 , +18493 , +-28269 , +21991 , +4229 , +-16867 , +-18559 , +26933 , +1413 , +-12669 , +19299 , +-28013 , +-29313 , +26917 , +-8783 , +12871 , +-1469 , +-8169 , +10089 , +5507 , +-25301 , +15497 , +-23499 , +-21157 , +-18315 , +1521 , +-7935 , +-23489 , +289 , +-3119 , +22289 , +-30227 , +-14017 , +-32277 , +11159 , +-12811 , +27337 , +-8463 , +-21549 , +-16221 , +2817 , +11723 , +-8803 , +-11649 , +20041 , +-28349 , +-883 , +-13755 , +5231 , +-1471 , +15241 , +10587 , +-10859 , +12423 , +-23841 , +30409 , +-18563 , +3555 , +25309 , +-22351 , +-3223 , +25577 , +29419 , +25675 , +-23445 , +-31701 , +-10975 , +19539 , +-27065 , +-7433 , +22111 , +5645 , +11457 , +-13181 , +8935 , +-25419 , +-1159 , +-23377 , +1905 , +-21635 , +9801 , +-22217 , +-18745 , +-18949 , +8725 , +-20879 , +-5157 , +14125 , +-4577 , +-12675 , +-16287 , +-4375 , +24049 , +-31995 , +4067 , +-18983 , +-29793 , +8563 , +16223 , +8177 , +2739 , +12705 , +16727 , +-23195 , +-3215 , +-26851 , +11889 , +-30167 , +24259 , +1243 , +19083 , +15325 , +27267 , +-19605 , +-12719 , +24147 , +24151 , +-11851 , +19803 , +15989 , +2315 , +-22479 , +4287 , +-7213 , +-4503 , +-6501 , +15917 , +30857 , +23945 , +5165 , +9091 , +16317 , +1977 , +-26021 , +32491 , +-11621 , +12229 , +25095 , +7023 , +-9273 , +2517 , +31539 , +-26099 , +2393 , +25545 , +-14519 , +-16551 , +27985 , +11791 , +7619 , +7567 , +1173 , +-783 , +-7315 , +29477 , +-25501 , +6783 , +-29675 , +-27149 , +-12725 , +16601 , +-307 , +17083 , +19115 , +-27379 , +21657 , +-22199 , +10655 , +-1431 , +-5711 , +3339 , +31361 , +22111 , +14635 , +21029 , +-13859 , +-9009 , +31557 , +-12529 , +-10777 , +-791 , +32269 , +15013 , +10617 , +1665 , +-20319 , +3781 , +-10875 , +8167 , +-10009 , +14185 , +271 , +-23489 , +27585 , +26169 , +-30809 , +-32165 , +-53 , +-7517 , +24161 , +-19439 , +-11637 , +11897 , +-2233 , +26129 , +-10189 , +22277 , +23387 , +-6077 , +19917 , +19105 , +13063 , +-359 , +17921 , +2765 , +29971 , +-21909 , +10303 , +4815 , +-3029 , +1103 , +-25985 , +-13633 , +-32061 , +15981 , +-12935 , +24363 , +-6749 , +26455 , +-23715 , +-10967 , +19663 , +1385 , +-22265 , +-19735 , +-29943 , +8859 , +22969 , +5341 , +-15421 , +-7981 , +-23213 , +-30911 , +-14435 , +11981 , +12559 , +31801 , +-10413 , +-19103 , +19125 , +-18831 , +1347 , +-27289 , +1613 , +-32731 , +-4773 , +3599 , +32359 , +1731 , +-1137 , +-23633 , +-20797 , +-19703 , +-1827 , +-8411 , +-7789 , +-10869 , +5815 , +15789 , +10029 , +32731 , +12549 , +26931 , +-12219 , +-7651 , +32409 , +20789 , +25257 , +1305 , +26665 , +15375 , +115 , +14557 , +-16959 , +26847 , +-17981 , +4039 , +707 , +22999 , +-16135 , +15921 , +2139 , +24339 , +-1683 , +13939 , +-29065 , +31219 , +-10081 , +-9843 , +9023 , +12535 , +4607 , +5169 , +-1775 , +27665 , +1299 , +-16281 , +-5393 , +-3713 , +26173 , +-23651 , +26499 , +-25817 , +6633 , +-7871 , +31377 , +-9111 , +-17841 , +-17957 , +-21267 , +-20361 , +-16479 , +-4445 , +-3339 , +-30413 , +-15673 , +-24167 , +24975 , +22147 , +-11619 , +2591 , +-7789 , +15913 , +21409 , +-10739 , +-26155 , +7197 , +25135 , +-28851 , +18315 , +25439 , +12091 , +-8719 , +15701 , +30555 , +20361 , +-307 , +16549 , +5553 , +30049 , +18061 , +-569 , +-5989 , +-29493 , +2379 , +19023 , +-9793 , +-19899 , +-16725 , +-4589 , +15749 , +-1029 , +-17805 , +10915 , +28403 , +-29311 , +20897 , +-18109 , +-3065 , +-4601 , +-15359 , +30561 , +-15741 , +6421 , +-15797 , +31115 , +-17065 , +16833 , +-5963 , +-17171 , +617 , +-16277 , +1551 , +12101 , +8437 , +8939 , +-30889 , +17755 , +-12185 , +-10411 , +-8233 , +-10249 , +16297 , +26923 , +17849 , +32607 , +-27385 , +-14065 , +-25829 , +9547 , +-18817 , +-26869 , +-9293 , +1373 , +-3427 , +-6343 , +-6441 , +-11241 , +-24113 , +30979 , +-475 , +17497 , +22593 , +-10021 , +-12145 , +-23725 , +-16329 , +25713 , +27129 , +-15611 , +-19237 , +-22167 , +-8369 , +-5337 , +-19041 , +5785 , +3871 , +2231 , +18961 , +30653 , +20141 , +-11299 , +28213 , +13227 , +23441 , +9327 , +-24743 , +-15081 , +27077 , +11495 , +-24209 , +26045 , +-22963 , +-11305 , +-27413 , +25633 , +1597 , +-7195 , +29967 , +7113 , +-17825 , +19005 , +-26933 , +2031 , +8001 , +7061 , +16407 , +-5959 , +-32297 , +-26727 , +-4155 , +29433 , +-28537 , +-7447 , +28121 , +-32167 , +-12085 , +-20597 , +15465 , +17951 , +-3767 , +-29713 , +-32533 , +24671 , +20575 , +4187 , +-493 , +28591 , +-28851 , +-23833 , +13867 , +-1177 , +-30277 , +2551 , +19943 , +14935 , +-30241 , +-31439 , +-14399 , +-21511 , +4367 , +-23303 , +-20529 , +-973 , +3287 , +-26531 , +20507 , +10627 , +-12141 , +10655 , +1405 , +26051 , +-21619 , +8475 , +19697 , +-22183 , +29579 , +18129 , +-24211 , +28915 , +-9237 , +-17845 , +16959 , +-25159 , +-3781 , +-9953 , +31201 , +-4079 , +-28327 , +27627 , +32077 , +5323 , +14329 , +20931 , +31715 , +-17189 , +-2099 , +25131 , +-2131 , +-18535 , +-2023 , +-16999 , +-441 , +-30863 , +20167 , +17503 , +23089 , +26909 , +-28929 , +27691 , +21671 , +17757 , +-7097 , +11263 , +8185 , +-31439 , +4625 , +13991 , +-32155 , +16527 , +12253 , +15283 , +-9875 , +-16483 , +31171 , +26345 , +3501 , +-14749 , +3483 , +-10685 , +-28869 , +-23795 , +-4981 , +15979 , +-3469 , +30363 , +6433 , +30119 , +17753 , +-20455 , +10733 , +7513 , +-19089 , +12893 , +10387 , +8695 , +-25079 , +7229 , +5485 , +18815 , +-26843 , +-21697 , +-6245 , +-30601 , +-25395 , +12511 , +24991 , +21849 , +-6431 , +-28103 , +-28047 , +-19819 , +-30345 , +19021 , +23323 , +9989 , +30131 , +26285 , +-12079 , +23779 , +-3299 , +30397 , +-11389 , +-24759 , +10617 , +-6811 , +-20227 , +-4577 , +-11489 , +-19123 , +11389 , +-8041 , +-20525 , +6035 , +-15673 , +3625 , +-12255 , +-11005 , +-32067 , +13831 , +20781 , +463 , +21119 , +-8943 , +-24301 , +-3125 , +-1799 , +-26025 , +-7239 , +-3301 , +-15357 , +-13817 , +-28629 , +-25221 , +8947 , +-8465 , +-8589 , +29667 , +3513 , +2665 , +7659 , +-29997 , +-28557 , +29407 , +-29669 , +-11015 , +21387 , +-20295 , +-15339 , +117 , +30795 , +-13857 , +24129 , +24211 , +-24079 , +25509 , +-10053 , +-12813 , +-31917 , +25423 , +24627 , +8021 , +-14105 , +-19199 , +-28365 , +-4927 , +-18581 , +28983 , +-13811 , +23369 , +22257 , +6341 , +9501 , +-16581 , +-32131 , +8005 , +-19535 , +-25887 , +-19427 , +31767 , +4445 , +-4181 , +-6789 , +31187 , +-6197 , +23029 , +23805 , +31813 , +31523 , +-4295 , +-16551 , +-2849 , +-10545 , +22217 , +15791 , +15807 , +-19739 , +5375 , +14365 , +-27885 , +-22027 , +-32507 , +11481 , +-7389 , +-10395 , +23803 , +19405 , +-21315 , +30275 , +-30533 , +-31065 , +-23501 , +-26459 , +-14577 , +30075 , +22227 , +-28801 , +3429 , +-6193 , +-31523 , +6903 , +22027 , +31295 , +27129 , +-1215 , +27879 , +2187 , +-21453 , +-1549 , +-20825 , +21561 , +10611 , +991 , +12935 , +-18527 , +23409 , +27507 , +22141 , +15763 , +-30157 , +-5247 , +9721 , +-2721 , +-31493 , +-32095 , +-27883 , +-9347 , +6607 , +-16629 , +-1451 , +11927 , +863 , +-27925 , +-5925 , +-30417 , +-31351 , +18743 , +-25313 , +-26711 , +28749 , +-19703 , +14887 , +-15635 , +-16057 , +9593 , +9535 , +-22663 , +-25695 , +24567 , +-31179 , +-20227 , +-12647 , +-3303 , +25097 , +-19855 , +-23965 , +16383 , +18475 , +-11601 , +9143 , +-22495 , +2611 , +-23159 , +-23111 , +1453 , +30231 , +-13987 , +-19841 , +1119 , +-29981 , +-7877 , +8699 , +29401 , +8175 , +17257 , +-28803 , +9333 , +30367 , +13453 , +-6747 , +31649 , +-20847 , +1851 , +14557 , +13503 , +-27557 , +-2035 , +-22441 , +-30353 , +-15679 , +7747 , +32121 , +17517 , +-29073 , +18639 , +16863 , +-8723 , +-19409 , +8185 , +975 , +14445 , +16799 , +25455 , +-32463 , +5651 , +-20367 , +-25375 , +28935 , +-8577 , +-21483 , +7955 , +-23703 , +-13021 , +31233 , +-22145 , +12275 , +8225 , +31839 , +-30619 , +27337 , +24479 , +-14519 , +-30361 , +-10233 , +21921 , +16507 , +-25443 , +-10819 , +-12709 , +16789 , +31283 , +13413 , +-18161 , +13513 , +9335 , +30171 , +-16023 , +9241 , +-24961 , +-5419 , +-1719 , +-19695 , +-20681 , +26333 , +-21719 , +31479 , +2297 , +-15673 , +-4881 , +16775 , +-21079 , +-6743 , +2883 , +561 , +-6323 , +-29615 , +25965 , +16837 , +-21213 , +-30905 , +-11865 , +-23369 , +-12999 , +-22731 , +8693 , +16331 , +-19837 , +4075 , +-7801 , +-25763 , +8057 , +10711 , +-7549 , +-7931 , +-19157 , +-5643 , +-19353 , +11233 , +-24873 , +-22453 , +-25895 , +29507 , +14855 , +15589 , +7433 , +2025 , +4901 , +-25785 , +-14975 , +7101 , +3729 , +-23447 , +10881 , +19461 , +5691 , +26411 , +-10545 , +-23015 , +9153 , +-30895 , +11041 , +7847 , +-261 , +765 , +-12321 , +-3233 , +-30435 , +3741 , +-12407 , +-4305 , +-5045 , +16239 , +-3697 , +2303 , +-30799 , +-17297 , +28065 , +21731 , +-4067 , +-21031 , +-28785 , +-16427 , +-8939 , +-23789 , +25497 , +-29201 , +23147 , +10039 , +847 , +4897 , +5729 , +15357 , +-25885 , +-24981 , +9269 , +-3273 , +-16631 , +3983 , +2877 , +-8503 , +11075 , +3923 , +31363 , +-28893 , +-32575 , +25135 , +30935 , +-10183 , +7613 , +19853 , +26983 , +5365 , +-23229 , +-30853 , +-17185 , +8505 , +20383 , +-22297 , +-22791 , +16973 , +-25823 , +-26027 , +-20331 , +-18977 , +30081 , +-3305 , +32345 , +8051 , +30133 , +-15609 , +-23617 , +-29595 , +15939 , +-16709 , +-9551 , +18005 , +-24543 , +17985 , +30629 , +11311 , +-27127 , +15959 , +29233 , +-13939 , +-20399 , +13343 , +-9695 , +-6969 , +2371 , +-15525 , +4371 , +-17573 , +23031 , +-18653 , +-24435 , +-23323 , +18345 , +-8933 , +1175 , +21667 , +-32369 , +821 , +17101 , +29025 , +-14537 , +6103 , +-23035 , +-17415 , +28507 , +-7001 , +30289 , +31809 , +-30921 , +23475 , +1453 , +27793 , +8805 , +-4301 , +-5877 , +-9295 , +-3275 , +-5189 , +-18965 , +15695 , +-15487 , +19707 , +7287 , +-7935 , +-6645 , +1257 , +-18915 , +1975 , +14411 , +11657 , +24733 , +4017 , +-13101 , +7449 , +32173 , +-4357 , +-10719 , +-11059 , +-4345 , +-19357 , +-5641 , +-15857 , +9995 , +18161 , +13619 , +18981 , +9675 , +7139 , +-18393 , +6265 , +-17745 , +6939 , +9073 , +-22707 , +-7547 , +27171 , +27989 , +-1297 , +-26085 , +21919 , +-18539 , +1907 , +-677 , +4419 , +-25147 , +-18195 , +2777 , +-31155 , +-31707 , +5671 , +-7175 , +-6015 , +-261 , +30171 , +-7815 , +18845 , +-5527 , +15973 , +21651 , +-7345 , +19141 , +10243 , +19601 , +20399 , +-29325 , +31115 , +14565 , +26683 , +16955 , +14239 , +-16443 , +843 , +-6879 , +-16795 , +-24265 , +18437 , +-12099 , +-16951 , +-325 , +-12065 , +-3821 , +4133 , +-8363 , +21647 , +20207 , +25479 , +18471 , +3461 , +2997 , +11619 , +-15983 , +-26653 , +-6719 , +-7989 , +-24385 , +32251 , +-8901 , +-8413 , +-4663 , +11065 , +4459 , +7013 , +15943 , +32169 , +28317 , +-6195 , +23651 , +-21015 , +17515 , +-6633 , +4739 , +-14945 , +23711 , +-28107 , +-3251 , +23673 , +-21881 , +24453 , +30279 , +-11369 , +10955 , +-8047 , +16631 , +-14445 , +3021 , +-3779 , +-2965 , +-3859 , +-18827 , +23429 , +22369 , +11019 , +-12395 , +-4427 , +13521 , +-9813 , +-13895 , +-32483 , +-14577 , +25823 , +8063 , +-11189 , +1887 , +897 , +-12683 , +-11321 , +-17905 , +-29649 , +10863 , +9795 , +-28919 , +-31547 , +-24231 , +-30371 , +12019 , +10315 , +-30825 , +-4147 , +-29499 , +-25735 , +-31531 , +-9693 , +21467 , +1955 , +-18071 , +-7683 , +-13675 , +-11199 , +13349 , +-4159 , +361 , +-18729 , +-12119 , +4819 , +-22911 , +-11919 , +5705 , +29771 , +21965 , +-26715 , +12123 , +23603 , +-16997 , +-19969 , +-28401 , +-16071 , +28599 , +-26627 , +27597 , +23273 , +-18693 , +6283 , +31753 , +-20885 , +18793 , +-30477 , +21401 , +3503 , +11969 , +-11685 , +-19567 , +303 , +-19549 , +5567 , +3737 , +5151 , +-16103 , +7777 , +-13367 , +31539 , +28853 , +23241 , +25081 , +-29247 , +13615 , +-27595 , +-7267 , +-30319 , +28531 , +7321 , +4899 , +-26365 , +-14273 , +-21739 , +-26687 , +-27697 , +9785 , +-24859 , +27345 , +29241 , +-26487 , +-7959 , +5549 , +-5423 , +3563 , +7049 , +-10241 , +12961 , +12373 , +-32447 , +20133 , +22509 , +15609 , +-9847 , +-19721 , +12131 , +12531 , +3157 , +19123 , +19417 , +8789 , +-7153 , +8263 , +-1911 , +7615 , +15877 , +-25685 , +-21061 , +24701 , +24943 , +5059 , +-2037 , +18199 , +-19239 , +-4055 , +18971 , +-14221 , +-30169 , +29581 , +-20281 , +-10907 , +14593 , +-14707 , +-7703 , +29897 , +16343 , +23305 , +-25213 , +-3047 , +-23725 , +16385 , +-9855 , +1167 , +17485 , +32233 , +-20501 , +7341 , +25679 , +4987 , +-30813 , +-2461 , +4223 , +-21729 , +28567 , +-32353 , +-21729 , +-24395 , +9339 , +9067 , +19333 , +28655 , +-18173 , +-26245 , +11407 , +9009 , +22681 , +23123 , +-7773 , +-9507 , +7317 , +-13871 , +-30181 , +1337 , +27637 , +6735 , +-17593 , +24247 , +-8805 , +12855 , +22751 , +21215 , +5365 , +28189 , +5123 , +-10857 , +-28341 , +-26799 , +-14169 , +19713 , +-6303 , +-6399 , +29075 , +-23591 , +24001 , +28103 , +-5409 , +7233 , +25449 , +-18489 , +15069 , +-1245 , +-9977 , +1353 , +-26209 , +-23545 , +-23383 , +-4153 , +-4375 , +15717 , +-30713 , +-11377 , +-343 , +30087 , +-20189 , +-10791 , +-1043 , +32727 , +-617 , +-8355 , +-17821 , +-7491 , +26687 , +25445 , +13893 , +11767 , +-26251 , +19319 , +-21795 , +12653 , +4559 , +-8359 , +-4237 , +-13173 , +-6327 , +433 , +21199 , +-4579 , +-29427 , +-26331 , +-21211 , +-9055 , +-25185 , +32229 , +-8039 , +24355 , +8091 , +-15415 , +-32723 , +-8557 , +15595 , +-18193 , +-10943 , +6043 , +-7037 , +28875 , +-1145 , +29949 , +20111 , +13245 , +19323 , +-21915 , +-9419 , +-21709 , +-13479 , +-22587 , +17357 , +8765 , +-8551 , +32043 , +-26995 , +-19813 , +-5141 , +18203 , +-2861 , +-18841 , +12705 , +-17563 , +-29747 , +22045 , +-32589 , +28279 , +-16455 , +-29891 , +5685 , +26951 , +413 , +28509 , +19277 , +10135 , +18299 , +12231 , +21415 , +-26919 , +-24817 , +32139 , +-15749 , +11649 , +-11519 , +-11753 , +3569 , +-19741 , +-25955 , +24665 , +-14039 , +-12411 , +19477 , +2629 , +-13137 , +-519 , +-30423 , +13059 , +1389 , +-3017 , +-8593 , +-14989 , +8747 , +7541 , +-13057 , +18257 , +-10365 , +15481 , +13997 , +20679 , +-3499 , +-12679 , +-23349 , +16525 , +-3893 , +18031 , +24917 , +-31627 , +22979 , +-18191 , +-9555 , +20109 , +-29997 , +4235 , +18899 , +3763 , +13495 , +25233 , +4897 , +-30547 , +15951 , +31873 , +-9857 , +-8511 , +17941 , +16849 , +-17387 , +26833 , +31257 , +-3503 , +-18797 , +-20499 , +-399 , +-3851 , +-25637 , +26217 , +-26055 , +9025 , +-23751 , +-19327 , +-7423 , +-32503 , +41 , +-20121 , +-24875 , +-4897 , +31869 , +24795 , +-27483 , +-4899 , +-29405 , +3401 , +-31931 , +23557 , +-9899 , +22107 , +30435 , +-21489 , +-21419 , +-13293 , +13571 , +-12339 , +18847 , +28263 , +-2321 , +26111 , +-25683 , +-5807 , +10931 , +15523 , +13599 , +-6799 , +29339 , +-15143 , +7301 , +17689 , +-25823 , +-28879 , +23173 , +-23053 , +-16533 , +26767 , +-15711 , +-247 , +21569 , +12145 , +-4507 , +-19605 , +20869 , +-1573 , +-7383 , +-3773 , +12845 , +-23647 , +23103 , +-19099 , +699 , +23875 , +9137 , +19317 , +13869 , +21319 , +-25737 , +-23951 , +31105 , +1551 , +-22225 , +19923 , +15783 , +27187 , +16985 , +-29913 , +12281 , +26963 , +-6391 , +9243 , +22835 , +-9351 , +4383 , +-31449 , +6891 , +-28439 , +3589 , +-8047 , +-15477 , +-31621 , +15075 , +-18919 , +-3899 , +-12683 , +6999 , +-26877 , +30867 , +28639 , +17069 , +32433 , +4257 , +-29089 , +-30823 , +-26685 , +27735 , +14481 , +31339 , +-14937 , +2367 , +19165 , +-27189 , +-13647 , +25097 , +-29493 , +8687 , +25273 , +-16381 , +-24857 , +16983 , +10799 , +25353 , +-12021 , +9725 , +-22093 , +14337 , +31041 , +-11759 , +24109 , +-10793 , +-7401 , +32565 , +5477 , +-1809 , +28535 , +303 , +30491 , +13599 , +-769 , +12583 , +4773 , +5675 , +12505 , +-11689 , +-14085 , +26295 , +-18409 , +-5815 , +-5289 , +-10815 , +6533 , +-623 , +-6579 , +-19815 , +12289 , +15865 , +-11935 , +-2213 , +-6821 , +-179 , +-17631 , +23017 , +17827 , +-29315 , +2487 , +-25769 , +-31993 , +-14489 , +-14325 , +-12813 , +553 , +32001 , +14161 , +-13903 , +1787 , +2079 , +32039 , +-30935 , +6669 , +6045 , +-14803 , +-26351 , +-16781 , +9503 , +-19175 , +31785 , +-28659 , +-29363 , +30293 , +-2617 , +25201 , +-15749 , +20497 , +14519 , +30767 , +-28171 , +1755 , +2251 , +27327 , +-3157 , +-4415 , +-27457 , +-9533 , +23655 , +217 , +16061 , +-32527 , +2705 , +-12955 , +2897 , +-18593 , +17751 , +-23957 , +-4381 , +4961 , +1653 , +-16699 , +-20051 , +10207 , +1635 , +-5697 , +-24015 , +2097 , +-23795 , +18219 , +-12747 , +-23697 , +-26353 , +-16383 , +-1477 , +-28593 , +1903 , +-10387 , +3957 , +24955 , +-18997 , +17517 , +14401 , +6761 , +5405 , +10217 , +25375 , +-9031 , +-3349 , +14147 , +25643 , +26111 , +22275 , +-19585 , +27921 , +30249 , +-31825 , +-31539 , +5003 , +-18865 , +-28559 , +21153 , +-25009 , +14353 , +-26823 , +-4007 , +-12139 , +9575 , +-5087 , +-2495 , +-5117 , +-18177 , +22427 , +-8383 , +8491 , +5911 , +-13515 , +-32035 , +9859 , +7885 , +-30521 , +17381 , +11735 , +-13315 , +13367 , +-13447 , +-4025 , +16791 , +-14433 , +-22353 , +2243 , +5241 , +-7657 , +-21341 , +21751 , +-4411 , +26853 , +23313 , +-27443 , +9143 , +-3279 , +18285 , +93 , +19459 , +-1977 , +-18817 , +3183 , +-32087 , +14407 , +23671 , +5483 , +23115 , +22365 , +-28801 , +10453 , +8971 , +9089 , +-14621 , +-23233 , +-26405 , +31907 , +-16745 , +-5939 , +-28065 , +22385 , +5983 , +-14819 , +-14279 , +-11649 , +-13479 , +-2097 , +19695 , +-10735 , +20255 , +19055 , +-13003 , +13889 , +-18595 , +-19205 , +12495 , +-12349 , +-17693 , +6091 , +-19483 , +-26853 , +-5821 , +-9705 , +4313 , +4689 , +-4629 , +7657 , +-11609 , +13613 , +14261 , +-15723 , +26545 , +6125 , +-8953 , +-4687 , +3361 , +-32645 , +5219 , +21133 , +10943 , +-18897 , +6537 , +-4053 , +14149 , +-26633 , +-10489 , +32189 , +-17095 , +27931 , +11345 , +15759 , +-26553 , +26737 , +10335 , +28301 , +793 , +22041 , +4289 , +5173 , +-29273 , +27563 , +-29385 , +19725 , +-27617 , +-19717 , +-12343 , +-4191 , +20011 , +1865 , +4447 , +-23049 , +3801 , +7419 , +15067 , +16257 , +-13085 , +-29735 , +4781 , +29095 , +-29801 , +21435 , +-14605 , +-16727 , +-17371 , +-11311 , +11269 , +-17625 , +12151 , +-21433 , +-30823 , +27153 , +-20337 , +-32115 , +16463 , +-6363 , +-8359 , +8203 , +18903 , +6113 , +25607 , +-7339 , +-23173 , +-25861 , +4841 , +-1049 , +-12479 , +-20895 , +6335 , +26711 , +28545 , +17321 , +-14439 , +12057 , +10489 , +-1273 , +7211 , +-13913 , +-9371 , +15571 , +-27739 , +14923 , +12957 , +10607 , +27147 , +-15291 , +-9685 , +-26675 , +-9969 , +-16753 , +11615 , +-9635 , +28519 , +30995 , +-17431 , +-32115 , +6307 , +-21407 , +31473 , +-9541 , +-4727 , +27619 , +-1357 , +20145 , +25841 , +4767 , +30865 , +31389 , +-755 , +8807 , +9645 , +6277 , +-2731 , +-29291 , +31235 , +-31681 , +12495 , +25409 , +-5123 , +3573 , +-9997 , +22005 , +-7021 , +-11513 , +-9993 , +5363 , +18391 , +21913 , +-13901 , +-4135 , +27159 , +-30083 , +26099 , +-17173 , +-13967 , +-27213 , +8011 , +31169 , +25579 , +-4777 , +-5255 , +-24959 , +525 , +6953 , +-7629 , +-25705 , +19957 , +-11151 , +-15479 , +31217 , +3829 , +-24437 , +-335 , +5551 , +24993 , +-14897 , +20841 , +-5279 , +17527 , +-19183 , +-26675 , +-4161 , +20709 , +-21605 , +-6999 , +27103 , +-1811 , +-15461 , +31321 , +18413 , +8507 , +11049 , +-17377 , +-6557 , +28599 , +-17999 , +-20493 , +-15937 , +9897 , +-25611 , +10473 , +2759 , +-7103 , +20097 , +12795 , +-27349 , +7867 , +-24925 , +-11923 , +6353 , +-19209 , +-5659 , +-17251 , +15749 , +27529 , +21505 , +5213 , +26929 , +-20907 , +11099 , +-15923 , +-14187 , +28333 , +13311 , +-29779 , +-30083 , +30171 , +4365 , +31811 , +-14977 , +1099 , +-31559 , +-20579 , +47 , +5393 , +-16697 , +8835 , +-11303 , +7697 , +29047 , +-26187 , +-24143 , +-23415 , +-6907 , +14807 , +-11621 , +32309 , +-15969 , +-6207 , +-26289 , +5851 , +-14365 , +2387 , +-20699 , +-28047 , +12233 , +-16681 , +831 , +9127 , +-6613 , +11473 , +-11195 , +28427 , +24753 , +-4519 , +11423 , +21145 , +16461 , +18421 , +14633 , +-5679 , +31287 , +13037 , +29299 , +9821 , +16223 , +-9943 , +4205 , +-10985 , +23145 , +-26239 , +-16213 , +26543 , +15395 , +11423 , +5905 , +23225 , +28283 , +587 , +-20197 , +-28595 , +-23041 , +28497 , +-31871 , +30491 , +10697 , +-15413 , +19073 , +22019 , +-13821 , +-7675 , +-27507 , +-27603 , +7381 , +28105 , +24453 , +21921 , +14821 , +11331 , +-16273 , +17505 , +-21427 , +-21423 , +-29263 , +-8705 , +-11511 , +-12451 , +-31799 , +7603 , +26627 , +19129 , +-9089 , +-9475 , +25973 , +-18063 , +-12125 , +-19285 , +499 , +22179 , +-951 , +-8059 , +-1321 , +-1953 , +7539 , +-18605 , +-6847 , +25333 , +9559 , +21895 , +-17015 , +-29485 , +5135 , +10305 , +27961 , +-5411 , +-26923 , +-16645 , +32649 , +23873 , +-8007 , +-18031 , +-17329 , +-11055 , +-18981 , +10981 , +-7809 , +18657 , +8477 , +18409 , +13085 , +5523 , +-13211 , +-17591 , +6587 , +23223 , +29515 , +30069 , +-30869 , +29477 , +26713 , +20797 , +23351 , +7309 , +-23363 , +25833 , +31519 , +26585 , +23173 , +22485 , +-9073 , +2553 , +-32427 , +-27517 , +13137 , +9541 , +21921 , +-20683 , +32525 , +9041 , +16989 , +-9977 , +12091 , +-18617 , +11589 , +-18555 , +5535 , +-24389 , +-25209 , +30913 , +-8383 , +18183 , +-19203 , +31733 , +19423 , +-15073 , +29675 , +26249 , +-9233 , +32241 , +16179 , +-579 , +11533 , +-11981 , +8461 , +-25417 , +-17159 , +2241 , +-17347 , +-24801 , +19213 , +5745 , +27093 , +-26573 , +-28615 , +14961 , +31067 , +-20891 , +-31373 , +10779 , +2965 , +-3223 , +-3915 , +-12471 , +32689 , +4317 , +28789 , +14393 , +-5369 , +8527 , +-16999 , +-12327 , +-27827 , +3553 , +23539 , +30371 , +-7347 , +18527 , +28981 , +-27657 , +-11739 , +14803 , +-1421 , +-18447 , +13553 , +15775 , +6153 , +-6719 , +-3307 , +-32487 , +-22489 , +7813 , +-27419 , +-24675 , +-6217 , +17567 , +9445 , +21287 , +20965 , +-4211 , +-9341 , +4461 , +30219 , +18495 , +-29373 , +-4749 , +-977 , +-31241 , +21385 , +-27223 , +-28679 , +9111 , +26563 , +-14721 , +-5589 , +25985 , +-22235 , +2427 , +-20325 , +18409 , +-15131 , +6355 , +25769 , +28077 , +30953 , +-16501 , +6199 , +10167 , +-5877 , +-29183 , +8483 , +11463 , +32459 , +15121 , +-31943 , +6611 , +19335 , +2465 , +18613 , +21215 , +25905 , +2759 , +-32463 , +23635 , +13707 , +-27563 , +7975 , +17617 , +13281 , +-15371 , +27615 , +14229 , +311 , +26307 , +18925 , +-12479 , +24335 , +7525 , +-475 , +16705 , +-1903 , +5277 , +-18661 , +-1639 , +30291 , +10861 , +-29937 , +-16571 , +-11129 , +-10339 , +9329 , +-1781 , +29617 , +-18967 , +-11057 , +10967 , +-9237 , +-1405 , +18007 , +17299 , +-21871 , +-17091 , +-31803 , +-11399 , +-23937 , +25623 , +-28961 , +-15631 , +22215 , +2905 , +15729 , +-24083 , +26599 , +16939 , +-27459 , +10163 , +-13431 , +-3153 , +23423 , +-1211 , +5811 , +-11113 , +6741 , +23595 , +17021 , +11581 , +17091 , +-15401 , +-7339 , +22587 , +-19285 , +6003 , +19113 , +-12921 , +23099 , +-32191 , +-29907 , +4609 , +4721 , +-28563 , +-10367 , +25497 , +-24055 , +-23957 , +13183 , +31193 , +-7427 , +20679 , +-4129 , +13065 , +-5511 , +-10109 , +-6021 , +-31299 , +23889 , +10223 , +-765 , +-28941 , +-21763 , +-23553 , +-17353 , +5293 , +26387 , +15907 , +-18023 , +21757 , +31027 , +-3423 , +-31315 , +31151 , +23443 , +18279 , +-16209 , +-30637 , +8159 , +-7317 , +16327 , +9945 , +29383 , +-10623 , +-17213 , +3241 , +21995 , +-22097 , +2129 , +30785 , +-14253 , +-12279 , +14005 , +-32451 , +5485 , +-28669 , +-16639 , +-24825 , +637 , +-683 , +1229 , +15317 , +-28003 , +6981 , +17523 , +-21421 , +-26317 , +-16501 , +22975 , +25529 , +-11549 , +19869 , +22831 , +-17319 , +-17137 , +-7531 , +29605 , +11459 , +-7223 , +2425 , +7331 , +16721 , +-8625 , +-28635 , +-5375 , +12875 , +-19967 , +-27503 , +11299 , +28281 , +-11301 , +25269 , +-24135 , +-3527 , +-32663 , +15073 , +25069 , +-15587 , +-23997 , +-26485 , +21027 , +26619 , +-251 , +4531 , +13353 , +-19061 , +-7487 , +26287 , +-16905 , +-14463 , +511 , +-9581 , +-19487 , +32287 , +-13775 , +27637 , +32087 , +22603 , +-10069 , +1625 , +11279 , +565 , +-12259 , +17399 , +28107 , +28767 , +17543 , +-10205 , +24717 , +-8389 , +-2635 , +14873 , +-16055 , +-28857 , +4147 , +-22439 , +27939 , +-27233 , +-21297 , +7299 , +-21209 , +-26345 , +18047 , +18345 , +17533 , +-11303 , +24299 , +12075 , +-18137 , +12655 , +2395 , +-32247 , +-12493 , +-7829 , +-27597 , +16073 , +-20875 , +13939 , +2277 , +-15941 , +-21823 , +10717 , +-17803 , +-11295 , +9889 , +23501 , +-26015 , +-11711 , +-30579 , +-6205 , +-29657 , +-31297 , +-17755 , +-6731 , +28473 , +-15507 , +11493 , +-4175 , +5997 , +28019 , +-11805 , +-31769 , +-5119 , +-5035 , +3583 , +-25783 , +25867 , +-18215 , +4389 , +19621 , +8055 , +3673 , +-27911 , +-11209 , +-16525 , +23957 , +27035 , +-10305 , +22907 , +-26595 , +-3367 , +16167 , +-26179 , +-5103 , +-14367 , +31113 , +25117 , +2193 , +-19573 , +-31019 , +5799 , +-32127 , +25337 , +-25119 , +20621 , +29163 , +-14107 , +-14591 , +12185 , +-8229 , +-21685 , +17191 , +553 , +7341 , +21415 , +6003 , +31651 , +-26905 , +-9815 , +-27315 , +12659 , +19097 , +115 , +14077 , +-27011 , +24877 , +7757 , +-22331 , +11545 , +6593 , +1755 , +22135 , +10119 , +-28159 , +28633 , +21901 , +12013 , +-30853 , +-14253 , +961 , +-30519 , +-22147 , +-1449 , +12841 , +21229 , +-27801 , +3895 , +13511 , +3571 , +1925 , +11833 , +-20827 , +11833 , +-32151 , +-4657 , +29301 , +-5287 , +-16703 , +28503 , +20377 , +1567 , +16817 , +15689 , +9159 , +-17151 , +-30809 , +25589 , +2333 , +-22763 , +-5707 , +-17223 , +-1861 , +-21107 , +-11409 , +-7237 , +-17959 , +-9295 , +24887 , +-12259 , +30045 , +15697 , +-227 , +-31045 , +-14855 , +-31811 , +8249 , +-8355 , +-25411 , +-22207 , +-22915 , +-11151 , +-11725 , +19231 , +4879 , +21827 , +-17421 , +-3583 , +5919 , +4795 , +-24895 , +241 , +-25269 , +16009 , +21791 , +-32043 , +-7327 , +-19227 , +617 , +-29079 , +-17203 , +-30519 , +10859 , +30895 , +-27293 , +27297 , +1401 , +-29203 , +19645 , +-7797 , +26887 , +-30427 , +-32239 , +-12537 , +7363 , +-32247 , +26761 , +13627 , +-3027 , +-30343 , +-17379 , +-18533 , +-31577 , +-21391 , +-4375 , +-12751 , +-12261 , +-27247 , +9987 , +9031 , +-17401 , +-31487 , +9433 , +5033 , +-21219 , +-10499 , +-22011 , +-13991 , +8019 , +-12101 , +30883 , +-5943 , +-28031 , +-5131 , +-31955 , +18575 , +-23685 , +22733 , +25811 , +-21601 , +-22109 , +-4519 , +-17841 , +-2553 , +-20223 , +16777 , +29505 , +-11231 , +10465 , +6831 , +-19451 , +19533 , +7909 , +363 , +24589 , +13101 , +24227 , +5929 , +-6989 , +-1453 , +19895 , +-2023 , +23707 , +-11897 , +-9123 , +-9569 , +-23679 , +-28045 , +25227 , +-23205 , +29339 , +28383 , +-15993 , +13199 , +7525 , +-9875 , +-24067 , +-32729 , +1795 , +-24375 , +9887 , +-4317 , +26647 , +-19093 , +-5325 , +28055 , +32021 , +-28219 , +-22481 , +-24537 , +-19171 , +-17151 , +21207 , +-10255 , +-1707 , +24631 , +4555 , +1557 , +-23363 , +26151 , +-8671 , +26017 , +17553 , +7533 , +10503 , +5135 , +-18161 , +-10947 , +24013 , +20537 , +-12575 , +27803 , +-26489 , +-26663 , +-5909 , +19473 , +26911 , +23413 , +-11613 , +-15901 , +-1295 , +-32541 , +21235 , +14545 , +30947 , +27705 , +-26753 , +16711 , +1529 , +-14521 , +4243 , +-6887 , +8815 , +-16495 , +-10907 , +15799 , +-10923 , +-3387 , +10493 , +-15127 , +29343 , +-15951 , +14215 , +22535 , +21959 , +16835 , +-23507 , +26027 , +26841 , +-31499 , +-151 , +15861 , +-12265 , +28751 , +-16923 , +-717 , +-28151 , +-10017 , +-14387 , +2343 , +-27625 , +7973 , +14511 , +-26439 , +-15453 , +283 , +26567 , +15917 , +-15457 , +-9565 , +-12065 , +-5153 , +-2395 , +3199 , +-2647 , +27513 , +15761 , +-15921 , +-12401 , +-16467 , +17045 , +-13307 , +-5613 , +26731 , +-22317 , +-12965 , +-16989 , +409 , +-1925 , +27089 , +25327 , +13385 , +-24743 , +-18785 , +14019 , +29303 , +-8721 , +-24529 , +-31129 , +30015 , +-1767 , +32409 , +-9115 , +-2673 , +-30705 , +-28525 , +1523 , +-26779 , +14099 , +-27407 , +26819 , +32647 , +-10627 , +14999 , +-16043 , +-29769 , +3669 , +-24841 , +-7715 , +-23185 , +-29081 , +-27903 , +-30319 , +10011 , +4841 , +-8541 , +-4991 , +-13371 , +5507 , +15037 , +1013 , +8543 , +-32019 , +14741 , +16191 , +-2711 , +19723 , +-10789 , +-21223 , +-19399 , +12671 , +-8171 , +13685 , +12965 , +-29499 , +667 , +-1059 , +-9657 , +-28215 , +-27629 , +-32189 , +-20437 , +-16897 , +-4001 , +-23451 , +11789 , +-7683 , +-28635 , +917 , +26131 , +-26995 , +-26957 , +-1247 , +26875 , +30287 , +3723 , +-19169 , +26335 , +-3125 , +-29621 , +30665 , +-32155 , +9221 , +28717 , +-15527 , +-12677 , +21917 , +32257 , +22617 , +28299 , +-13211 , +925 , +-16761 , +20791 , +31091 , +17883 , +25627 , +32145 , +1983 , +27665 , +-4685 , +27341 , +5439 , +-24061 , +-12645 , +23171 , +-3985 , +-22425 , +-15951 , +11615 , +-19843 , +-29745 , +15027 , +-21925 , +3539 , +-17879 , +26651 , +-20361 , +-22219 , +11961 , +-8835 , +19187 , +24405 , +-4985 , +32341 , +8199 , +15089 , +32613 , +-16029 , +12821 , +-30875 , +-17575 , +-7031 , +27495 , +-12857 , +29341 , +10517 , +-5015 , +5755 , +23067 , +-20313 , +-27557 , +18259 , +-11175 , +4741 , +-17271 , +-2533 , +-9479 , +16751 , +-25077 , +-30789 , +-16719 , +-9737 , +23025 , +-3125 , +-2623 , +29023 , +7177 , +1193 , +-20245 , +-785 , +20489 , +27675 , +28395 , +-5691 , +24911 , +-31657 , +18033 , +-709 , +-741 , +5541 , +7831 , +-27213 , +20289 , +-1925 , +-29223 , +25587 , +12639 , +-5109 , +-26739 , +13571 , +-15195 , +31071 , +-35 , +-7049 , +28149 , +15093 , +28219 , +3927 , +-21331 , +24783 , +5727 , +-24725 , +-15395 , +-14063 , +8123 , +-14565 , +-21001 , +-31459 , +-31889 , +-31295 , +21259 , +8989 , +-26421 , +19585 , +31105 , +-27609 , +2109 , +-9301 , +26959 , +1749 , +23763 , +-3963 , +-17995 , +-29101 , +-5079 , +-9299 , +16747 , +-4605 , +19685 , +-26647 , +-24219 , +24973 , +5041 , +31115 , +25091 , +-18053 , +3765 , +3641 , +6861 , +-23477 , +-18555 , +17747 , +-25435 , +31761 , +5029 , +30917 , +-26997 , +28807 , +-17543 , +28253 , +-21305 , +26023 , +16317 , +-5719 , +31403 , +24263 , +-23161 , +-6583 , +30407 , +-12759 , +12461 , +4809 , +12703 , +-24295 , +13521 , +-23557 , +-6423 , +24707 , +9419 , +6351 , +-9919 , +15887 , +-26457 , +1701 , +28765 , +26033 , +-32231 , +-31187 , +-28207 , +27593 , +18297 , +22713 , +11319 , +12211 , +-709 , +24093 , +27897 , +2793 , +30181 , +29435 , +-26505 , +-23405 , +24709 , +20389 , +-821 , +16797 , +11695 , +32623 , +-2303 , +-5795 , +-3347 , +2189 , +-32061 , +13979 , +1217 , +-9117 , +19617 , +11567 , +32531 , +-22425 , +-16703 , +-5089 , +29743 , +8049 , +17 , +-27607 , +-1475 , +21393 , +24077 , +15083 , +-12489 , +14451 , +6379 , +17009 , +-13475 , +-6613 , +2651 , +-4785 , +-9671 , +-19307 , +7863 , +-30919 , +-19957 , +-14557 , +6341 , +-1505 , +453 , +8513 , +-26653 , +10171 , +19845 , +-9433 , +-10037 , +-8265 , +12683 , +-28879 , +10435 , +-13769 , +17331 , +-26699 , +-31913 , +7931 , +19305 , +13667 , +21141 , +-32523 , +2085 , +13839 , +-13891 , +-10661 , +15971 , +13339 , +-11647 , +30023 , +17173 , +1601 , +1205 , +31945 , +-16989 , +30701 , +-24431 , +-19837 , +-10145 , +-7653 , +865 , +-17215 , +-26755 , +-17237 , +-28995 , +4367 , +-29043 , +-16327 , +31305 , +28491 , +-21395 , +-20361 , +-30749 , +16717 , +21965 , +26367 , +4705 , +-18703 , +-31207 , +14005 , +28361 , +-2379 , +12025 , +16279 , +6147 , +15051 , +-29111 , +-13545 , +-25317 , +12985 , +-19825 , +18675 , +-13839 , +-32399 , +-6669 , +1167 , +625 , +-20513 , +14265 , +10957 , +18513 , +27659 , +-9165 , +14433 , +-7353 , +27821 , +-25789 , +26795 , +9145 , +-11963 , +1357 , +15633 , +14339 , +22195 , +-22871 , +-19243 , +-29663 , +14419 , +-3669 , +19823 , +-21517 , +5517 , +5897 , +25439 , +8171 , +-19469 , +-31519 , +2959 , +15437 , +-2599 , +17449 , +-733 , +23265 , +-8855 , +-4949 , +-23597 , +30509 , +-3009 , +26491 , +-3389 , +-23245 , +-4223 , +14317 , +4063 , +23197 , +-6029 , +-31979 , +28587 , +637 , +403 , +-29259 , +31139 , +-11385 , +-12243 , +-5959 , +19727 , +24767 , +25207 , +1075 , +-16809 , +-9023 , +14891 , +24781 , +9447 , +-30875 , +5013 , +6085 , +4473 , +15881 , +-11977 , +-3743 , +-31497 , +-22977 , +25561 , +-15891 , +-16433 , +-5369 , +1829 , +17709 , +16843 , +-31609 , +-21831 , +12377 , +4711 , +583 , +-8247 , +-19823 , +-5709 , +20447 , +9007 , +7131 , +20891 , +27709 , +-9209 , +-7531 , +22475 , +2897 , +-6463 , +-16529 , +-6137 , +6731 , +1221 , +6119 , +26359 , +-25009 , +2173 , +28473 , +-23151 , +-6733 , +5623 , +5601 , +-15135 , +-31823 , +-12297 , +-12409 , +8811 , +3747 , +-13933 , +-22655 , +-6917 , +6329 , +5195 , +-21559 , +16903 , +23347 , +17051 , +-14737 , +4993 , +-29677 , +-18659 , +28059 , +-10711 , +-10657 , +-26599 , +25085 , +-22413 , +27857 , +16285 , +13251 , +25045 , +12047 , +-32742 , +-14817 , +23201 , +-9879 , +-27269 , +-30419 , +-933 , +-18675 , +6843 , +-23945 , +-19817 , +20159 , +-9223 , +-17429 , +21583 , +529 , +-8935 , +-20145 , +-25163 , +5917 , +27863 , +-11207 , +-11629 , +9401 , +-25503 , +-367 , +8477 , +22837 , +-3225 , +11131 , +-8885 , +-27765 , +-18241 , +-12583 , +11447 , +-14561 , +-22665 , +-23745 , +15081 , +-24077 , +26735 , +9831 , +-29127 , +-4769 , +-22421 , +31795 , +-27359 , +-24247 , +8881 , +-4063 , +1051 , +8669 , +30753 , +-12999 , +7155 , +-24633 , +10957 , +-15209 , +28833 , +4843 , +-27125 , +-26031 , +18597 , +-14441 , +15125 , +20735 , +11479 , +-2491 , +14875 , +-29783 , +-16187 , +24005 , +20449 , +24125 , +31629 , +22537 , +12239 , +17555 , +22829 , +24903 , +-28015 , +30679 , +7263 , +-30269 , +-11989 , +23179 , +14583 , +-13829 , +25743 , +13051 , +-335 , +-20123 , +8635 , +-5067 , +7311 , +26533 , +-30133 , +5505 , +5293 , +30791 , +2453 , +-10147 , +-18271 , +24821 , +30271 , +7403 , +17989 , +23085 , +-20393 , +-27401 , +15651 , +21119 , +-19477 , +-6817 , +-31691 , +-27583 , +-2013 , +-23011 , +-1965 , +3523 , +29399 , +28847 , +-1281 , +-19439 , +6311 , +-19179 , +6587 , +-2013 , +12691 , +-29361 , +26093 , +-14693 , +23063 , +18251 , +-27351 , +2545 , +-30533 , +-8863 , +-32237 , +10045 , +-4047 , +5457 , +9649 , +28001 , +5613 , +32173 , +-24245 , +-4413 , +-2759 , +481 , +28853 , +-17009 , +-31021 , +19619 , +23863 , +607 , +-31491 , +-20253 , +18651 , +-6781 , +-15331 , +-11943 , +27205 , +-15701 , +-2097 , +-16799 , +4367 , +-24789 , +15491 , +-15729 , +-30045 , +23207 , +15759 , +-27249 , +16267 , +-28071 , +20425 , +11695 , +-24239 , +-20801 , +22687 , +-6199 , +205 , +5073 , +-9805 , +15813 , +-6899 , +-5183 , +-1809 , +-15471 , +-1381 , +-31693 , +-8937 , +-23923 , +13157 , +-18965 , +14063 , +19347 , +12037 , +20239 , +20169 , +-26781 , +-31831 , +-2083 , +28321 , +3493 , +-161 , +-30245 , +173 , +-30125 , +31221 , +20895 , +14981 , +-1601 , +20299 , +13045 , +-21333 , +25353 , +6701 , +10149 , +-29013 , +-1783 , +-14417 , +4259 , +8115 , +27101 , +-25861 , +20937 , +-3161 , +9421 , +14775 , +12305 , +-31555 , +-12591 , +22739 , +27211 , +-7787 , +-25217 , +8671 , +1111 , +-12341 , +-12149 , +-5909 , +-17193 , +15129 , +441 , +19167 , +9583 , +18663 , +-31909 , +19531 , +-10883 , +-6045 , +-31423 , +-28477 , +-20669 , +14111 , +14393 , +17083 , +-20555 , +-28123 , +-22527 , +-15399 , +16543 , +-21619 , +-31803 , +-16945 , +-31387 , +31899 , +-29425 , +-21577 , +-26055 , +27731 , +-6841 , +29665 , +15829 , +-32115 , +-3675 , +10811 , +-8785 , +-105 , +3501 , +-27883 , +31925 , +12357 , +-15321 , +32395 , +27781 , +-10611 , +-14703 , +-27565 , +20769 , +-359 , +23327 , +-22503 , +26411 , +-26517 , +31025 , +11857 , +-31589 , +-21019 , +19525 , +-5735 , +-13323 , +-29325 , +21877 , +26759 , +-30199 , +-16113 , +-7311 , +27659 , +13859 , +10733 , +6383 , +-12741 , +3265 , +6275 , +14761 , +437 , +15575 , +-18133 , +30163 , +-16013 , +8059 , +-21195 , +-5097 , +2343 , +29219 , +10373 , +6661 , +-4601 , +2905 , +27555 , +29457 , +28725 , +505 , +-3493 , +22025 , +-9075 , +-16667 , +11985 , +6415 , +-10495 , +-3781 , +10521 , +25617 , +-23187 , +-8943 , +-9395 , +-28231 , +-11535 , +-853 , +-24021 , +20211 , +-15411 , +27701 , +-26071 , +12505 , +20913 , +6135 , +16653 , +31023 , +2209 , +9491 , +13317 , +-16031 , +7229 , +-29513 , +25151 , +-15377 , +-21083 , +25047 , +-29693 , +-913 , +31181 , +-18073 , +26185 , +22017 , +-30629 , +-21231 , +15057 , +-24505 , +-3345 , +28781 , +23739 , +733 , +23821 , +-3909 , +18851 , +10067 , +13419 , +-2279 , +-12495 , +20899 , +20943 , +17719 , +3383 , +7975 , +4701 , +-23395 , +-21431 , +9241 , +-32389 , +24655 , +8403 , +8065 , +-21727 , +8473 , +21165 , +-591 , +-20813 , +-23499 , +-32449 , +24899 , +-21921 , +17553 , +-17395 , +-5501 , +5861 , +-12671 , +-14379 , +-2697 , +-21501 , +-27145 , +-14301 , +1613 , +25921 , +18231 , +-31377 , +-25517 , +-16569 , +27163 , +-22609 , +-23689 , +-14911 , +4031 , +-17039 , +15413 , +2473 , +-23873 , +26489 , +4625 , +6187 , +20971 , +-32565 , +-1893 , +-30223 , +3463 , +-25775 , +1749 , +17157 , +-28937 , +-22291 , +-5835 , +-1239 , +25345 , +10515 , +-24033 , +-22873 , +28289 , +-19751 , +28885 , +-10323 , +-6751 , +13213 , +5881 , +-20439 , +11669 , +-17905 , +13433 , +31769 , +-24375 , +9687 , +-3567 , +-29587 , +-21083 , +-27745 , +-19903 , +27221 , +18363 , +-8779 , +193 , +-1249 , +9097 , +2333 , +30845 , +-21363 , +-19289 , +-2257 , +-10231 , +16817 , +26245 , +13221 , +-867 , +22589 , +1953 , +14147 , +-1139 , +15967 , +-8383 , +-2339 , +4671 , +12575 , +26025 , +5885 , +-23391 , +-25813 , +5841 , +-25615 , +551 , +27707 , +22433 , +28267 , +10555 , +8415 , +-6741 , +-29547 , +16703 , +-27937 , +-13989 , +16295 , +761 , +10767 , +17077 , +11783 , +-14437 , +-31323 , +-22391 , +-24109 , +30247 , +13845 , +-19915 , +-9207 , +1911 , +-24727 , +9165 , +-13289 , +-10063 , +-25579 , +21727 , +1005 , +-31687 , +-1965 , +-30295 , +16545 , +31023 , +24057 , +-26933 , +24451 , +2409 , +-14127 , +-14453 , +6063 , +9699 , +7025 , +32381 , +20521 , +-32323 , +-4967 , +-30517 , +27261 , +21427 , +9469 , +-25633 , +22981 , +28177 , +-31317 , +-2651 , +-8619 , +-6865 , +-20773 , +-26817 , +-16957 , +-921 , +-16563 , +4671 , +20361 , +-28273 , +9241 , +24667 , +13849 , +-16659 , +-20209 , +-16985 , +-25487 , +-5197 , +-26231 , +-685 , +-12223 , +757 , +25031 , +20693 , +-28561 , +2339 , +24773 , +-1617 , +-6079 , +-14339 , +-5485 , +-8799 , +-4375 , +-14067 , +-17617 , +30051 , +17317 , +22181 , +-17959 , +3543 , +-25005 , +-17589 , +-21261 , +-11319 , +19589 , +30651 , +-2485 , +-24031 , +-3293 , +-22693 , +-4093 , +2721 , +27769 , +19251 , +479 , +-28393 , +6873 , +-19609 , +1819 , +-28395 , +-30805 , +-16599 , +7377 , +-14797 , +-22781 , +11067 , +28861 , +-4423 , +-26685 , +-22817 , +10409 , +-32545 , +14381 , +-6317 , +-1483 , +-5499 , +26359 , +29123 , +-29897 , +21351 , +18671 , +21451 , +12947 , +23003 , +27399 , +-32153 , +12687 , +-15871 , +6383 , +5997 , +-589 , +-28797 , +-16333 , +9607 , +-19691 , +-32309 , +-18479 , +23209 , +18233 , +27315 , +17483 , +10505 , +-27543 , +22473 , +12359 , +-20843 , +-10867 , +1535 , +-11869 , +4853 , +-21889 , +-26647 , +-11509 , +-27661 , +15589 , +1647 , +-26089 , +-1919 , +-25205 , +17413 , +-24099 , +-24023 , +-3525 , +-30105 , +-24053 , +-2807 , +-29683 , +-13611 , +-9595 , +20039 , +32335 , +-18243 , +23407 , +16655 , +-12851 , +26371 , +-24109 , +20997 , +-12113 , +-4183 , +24757 , +-5825 , +-10537 , +7705 , +-12637 , +-19773 , +-19795 , +-27699 , +20441 , +9583 , +14977 , +24465 , +-11053 , +26759 , +23139 , +32563 , +-15005 , +20377 , +-12689 , +17349 , +-12211 , +-23293 , +7603 , +4171 , +30557 , +31459 , +-4735 , +27389 , +-20479 , +-17777 , +17737 , +-9999 , +28765 , +-21867 , +-9493 , +31845 , +-32537 , +-23767 , +-105 , +-4761 , +27263 , +-22235 , +17699 , +17685 , +-9981 , +10105 , +29657 , +-11435 , +19049 , +32557 , +-5915 , +30473 , +25179 , +-23089 , +-2797 , +4301 , +-17849 , +-30093 , +21561 , +2087 , +-31233 , +31013 , +21771 , +23369 , +-6963 , +13539 , +-13969 , +12605 , +14091 , +23 , +22359 , +26283 , +20537 , +19343 , +16925 , +3331 , +-8805 , +17391 , +17489 , +21565 , +-9905 , +-2637 , +-28127 , +-10479 , +25053 , +16285 , +-25571 , +-15953 , +-12709 , +19379 , +-21853 , +-13581 , +22271 , +-14665 , +-5723 , +30751 , +10805 , +-29157 , +-751 , +-23789 , +17977 , +3197 , +-19045 , +-17655 , +-4299 , +-865 , +-479 , +-18489 , +6607 , +-13607 , +-26245 , +14171 , +-23997 , +19737 , +-14125 , +-16817 , +-22523 , +2391 , +29317 , +-28059 , +-6709 , +-15729 , +-7827 , +10191 , +24111 , +-31693 , +-19257 , +-26397 , +13507 , +-7125 , +6271 , +8277 , +2983 , +-19637 , +-8685 , +3571 , +-16987 , +-11197 , +-29217 , +11735 , +-13111 , +28965 , +2307 , +6689 , +23927 , +18257 , +-11349 , +28465 , +5635 , +16883 , +-24583 , +23135 , +-17721 , +6905 , +12619 , +31531 , +-8511 , +14989 , +12321 , +-28923 , +-32601 , +-29433 , +1645 , +-8333 , +-4993 , +-30865 , +23663 , +-5417 , +-17993 , +4719 , +19977 , +16285 , +15805 , +-27707 , +-3941 , +509 , +19227 , +-12725 , +16731 , +5161 , +-27387 , +-12193 , +5161 , +22793 , +-28803 , +-22303 , +6891 , +2425 , +9189 , +6833 , +-25245 , +-27657 , +4629 , +1691 , +-1655 , +-289 , +22007 , +-15395 , +-31649 , +17701 , +27037 , +7951 , +-7349 , +-23155 , +-17445 , +14251 , +30195 , +23647 , +13149 , +-3081 , +-6001 , +-16477 , +5691 , +17289 , +-31035 , +13783 , +11807 , +-6089 , +26365 , +-217 , +-32567 , +-623 , +1599 , +18727 , +30007 , +-2341 , +27779 , +-31483 , +-17093 , +19329 , +29075 , +30799 , +-9337 , +-30187 , +14935 , +21 , +-25005 , +2497 , +-31045 , +-327 , +26221 , +-3517 , +-6149 , +27667 , +-27943 , +-11677 , +30589 , +55 , +-5925 , +31977 , +9777 , +28837 , +20637 , +25629 , +15457 , +-18427 , +-16829 , +11187 , +8715 , +24667 , +-24709 , +-22195 , +1979 , +18369 , +-23133 , +2929 , +-30753 , +-10329 , +17489 , +24317 , +-10075 , +9849 , +-17283 , +11043 , +-22965 , +-1047 , +3081 , +23517 , +11777 , +12187 , +-26141 , +13035 , +-20169 , +23141 , +-2411 , +30531 , +-9861 , +20995 , +-30363 , +-25837 , +9425 , +26443 , +-32279 , +4145 , +-3449 , +-8463 , +-6623 , +-31981 , +18577 , +-25423 , +5387 , +13389 , +-5795 , +30991 , +-27203 , +10371 , +-11725 , +14737 , +-29951 , +26343 , +-17919 , +-23695 , +-23707 , +-471 , +-22337 , +-24363 , +-8741 , +2039 , +16191 , +-3953 , +-1331 , +25327 , +-14459 , +22601 , +-3659 , +23325 , +-23129 , +-11959 , +17203 , +-1815 , +16667 , +-22621 , +32685 , +11935 , +-361 , +1005 , +-9637 , +-25515 , +25183 , +-10369 , +8429 , +8815 , +-3283 , +-23767 , +-4205 , +-1387 , +-2695 , +4197 , +31141 , +-28891 , +-26791 , +-10983 , +-16723 , +-14029 , +-23337 , +-9789 , +-31731 , +3327 , +23755 , +6717 , +-5367 , +-25369 , +32305 , +14573 , +-1177 , +-25883 , +9727 , +15489 , +-1399 , +24713 , +-27261 , +28705 , +-6403 , +25961 , +31031 , +-8653 , +-3941 , +27679 , +-14313 , +23943 , +17693 , +11711 , +-11395 , +-22255 , +2357 , +15315 , +-24711 , +31273 , +-10717 , +20681 , +7077 , +7483 , +-27695 , +-14599 , +21633 , +30977 , +1901 , +28175 , +13641 , +59 , +-4489 , +30479 , +-3507 , +-31255 , +-413 , +-20799 , +-19509 , +27649 , +-24401 , +-16715 , +-26299 , +9385 , +-15495 , +-21323 , +-21159 , +32233 , +-26989 , +20667 , +-7657 , +-20499 , +-29403 , +-1685 , +-21023 , +-23115 , +31677 , +-2287 , +24763 , +30797 , +10985 , +17677 , +-13791 , +-27509 , +13907 , +2517 , +18285 , +-31931 , +-28593 , +9577 , +-11619 , +-13311 , +-32257 , +-31157 , +10677 , +-5573 , +32742 , +31991 , +-22885 , +-13041 , +-21767 , +-14883 , +-8349 , +-9859 , +22085 , +-32299 , +-22733 , +-6377 , +26875 , +-10977 , +-30835 , +12097 , +-2799 , +25807 , +19003 , +-22813 , +-9651 , +27341 , +-21613 , +-17755 , +-12817 , +-26543 , +-12967 , +-6747 , +-24903 , +32461 , +-32231 , +6829 , +3473 , +-18573 , +2295 , +30709 , +4757 , +-32473 , +21007 , +15689 , +-6479 , +3319 , +25415 , +31957 , +-22083 , +12563 , +-2645 , +32335 , +-753 , +-17853 , +-7355 , +19633 , +27287 , +5095 , +32111 , +26235 , +-3979 , +32359 , +25523 , +2137 , +-30449 , +-29651 , +-3299 , +2673 , +1969 , +7453 , +-6629 , +-14327 , +8601 , +-28531 , +15559 , +2499 , +-1125 , +26049 , +1489 , +27231 , +5171 , +731 , +8131 , +11749 , +-7655 , +-9637 , +-29969 , +871 , +-159 , +-22765 , +25521 , +-22221 , +14607 , +-2401 , +7511 , +-5231 , +23343 , +-17829 , +5493 , +-2571 , +4463 , +5857 , +6071 , +28347 , +-19403 , +10747 , +-5569 , +21849 , +23091 , +-223 , +31357 , +6945 , +1675 , +27241 , +-15737 , +-4493 , +19291 , +519 , +-279 , +-20365 , +14553 , +-4543 , +19721 , +-29375 , +-3857 , +-14363 , +18937 , +-20803 , +-18613 , +15685 , +-13875 , +427 , +-10753 , +-19023 , +16251 , +-31365 , +11927 , +-21661 , +-4827 , +7803 , +-12377 , +-3063 , +29951 , +25233 , +26359 , +-20563 , +-7517 , +22635 , +-6139 , +5687 , +-15133 , +-24251 , +16177 , +-9375 , +28711 , +1301 , +26947 , +24875 , +327 , +-9909 , +-14445 , +28895 , +14553 , +14849 , +2193 , +-19845 , +-14569 , +-29253 , +31983 , +-25931 , +8231 , +19355 , +12585 , +1897 , +28933 , +31769 , +-23643 , +17047 , +-13111 , +-5061 , +28489 , +-23589 , +10893 , +-29875 , +-15721 , +-30623 , +19387 , +-5347 , +-1219 , +-9887 , +8943 , +23209 , +15925 , +-9963 , +-11449 , +-27801 , +25685 , +28211 , +-8133 , +28905 , +4975 , +-23071 , +-23047 , +-21721 , +23527 , +-23503 , +-19905 , +2859 , +-19769 , +-17641 , +5545 , +4691 , +-24489 , +-8223 , +17815 , +-29699 , +-1219 , +14131 , +-22921 , +457 , +2061 , +-4233 , +22181 , +-30131 , +21857 , +8665 , +20935 , +-5555 , +-21383 , +-3643 , +-31593 , +-32651 , +-4537 , +-23851 , +-5815 , +-3185 , +13587 , +-8881 , +17501 , +6969 , +4747 , +-9957 , +-26123 , +6947 , +16989 , +-22723 , +-3151 , +10435 , +-22189 , +20935 , +-28921 , +-3191 , +-1823 , +2651 , +3095 , +10145 , +-12471 , +7963 , +-19191 , +805 , +-21459 , +-4571 , +30171 , +30161 , +-28251 , +-28795 , +-25401 , +-15547 , +-22053 , +28087 , +-1265 , +8115 , +-14045 , +-31593 , +32345 , +16157 , +9357 , +32475 , +-9589 , +20239 , +5383 , +27149 , +23581 , +21199 , +16105 , +14591 , +31477 , +23065 , +-2531 , +-13109 , +17853 , +-30115 , +13987 , +-17345 , +15799 , +29291 , +2491 , +-28195 , +-17629 , +-24395 , +-20623 , +-18347 , +29189 , +-3067 , +25789 , +-12937 , +12167 , +-24913 , +7701 , +-27731 , +26581 , +21587 , +3721 , +14835 , +-21397 , +-26103 , +21337 , +12885 , +-23825 , +-20187 , +-25589 , +20183 , +-27501 , +5221 , +9995 , +23811 , +11741 , +-77 , +-5449 , +-2097 , +-30963 , +-1451 , +17157 , +-14309 , +3311 , +-9309 , +-1141 , +-5203 , +25137 , +16971 , +3623 , +-17757 , +-11967 , +-2563 , +-4597 , +-23699 , +26269 , +11175 , +-18597 , +21833 , +19381 , +9265 , +6981 , +-3789 , +31291 , +7599 , +24723 , +31077 , +24569 , +3867 , +20683 , +14155 , +-29899 , +9871 , +27077 , +20473 , +-2179 , +-32261 , +11197 , +16169 , +4869 , +6751 , +-9229 , +28843 , +5243 , +22909 , +-27715 , +-20377 , +-18073 , +21019 , +-3035 , +-22325 , +1273 , +4785 , +22009 , +10187 , +5989 , +2729 , +-12691 , +25171 , +-19011 , +-1519 , +-8153 , +-4545 , +-26037 , +25559 , +12513 , +-21793 , +9567 , +-1409 , +7041 , +20441 , +-31055 , +-165 , +30375 , +-9545 , +-2249 , +3141 , +26573 , +-27949 , +7031 , +16339 , +-25885 , +-9265 , +9831 , +17427 , +-18855 , +-29039 , +-11071 , +10179 , +25543 , +4283 , +-10021 , +-32251 , +-15111 , +-7521 , +-12545 , +-10085 , +-21107 , +-9285 , +21061 , +-16227 , +30985 , +-12879 , +18921 , +-20049 , +-10893 , +-14919 , +1825 , +961 , +23149 , +-23391 , +19323 , +3903 , +17605 , +17729 , +-12367 , +-6199 , +11925 , +-5771 , +25343 , +-22161 , +7123 , +9615 , +15105 , +-12183 , +-19599 , +599 , +-29695 , +-27829 , +-781 , +-29313 , +481 , +-18491 , +31363 , +-28515 , +12635 , +-9779 , +-2167 , +-22883 , +-26131 , +-25241 , +-7219 , +26561 , +20519 , +-15665 , +-27907 , +-7149 , +-6007 , +-27329 , +14555 , +9317 , +-17711 , +-21477 , +-1601 , +-5697 , +5597 , +30379 , +-6205 , +25433 , +31747 , +-30119 , +17481 , +4891 , +32735 , +11111 , +-8671 , +-26481 , +22967 , +2083 , +-7143 , +-26029 , +-12983 , +-24927 , +1051 , +-31199 , +30761 , +17653 , +11963 , +24373 , +8347 , +19433 , +-10405 , +21333 , +7395 , +13367 , +2237 , +20025 , +27427 , +28219 , +9753 , +17301 , +-28239 , +-25549 , +-20293 , +26495 , +-8207 , +-12555 , +-5615 , +3447 , +10155 , +-19167 , +-21935 , +26063 , +-31005 , +13539 , +17287 , +-11853 , +23089 , +26657 , +-14035 , +1431 , +-4199 , +29495 , +-27577 , +-19919 , +4583 , +11827 , +23549 , +-5135 , +1153 , +6281 , +-17751 , +2299 , +1983 , +-28855 , +30585 , +11675 , +-567 , +-16931 , +27781 , +16195 , +18411 , +16697 , +24931 , +30205 , +29807 , +-2661 , +-19901 , +17511 , +-11025 , +-6465 , +7045 , +-12759 , +-27339 , +-9577 , +-32305 , +-23317 , +27279 , +28289 , +3757 , +979 , +29605 , +16135 , +31135 , +16761 , +24793 , +4621 , +-10827 , +-20385 , +32021 , +31631 , +-17491 , +-23065 , +-20699 , +-2855 , +10367 , +-8239 , +2971 , +-8645 , +-6017 , +45 , +3859 , +25411 , +-6415 , +22489 , +6429 , +-18055 , +14881 , +-18573 , +16263 , +-20081 , +17407 , +32465 , +4675 , +4899 , +-16597 , +-23805 , +26547 , +-17683 , +4255 , +-7495 , +-13949 , +-3203 , +-19017 , +-7857 , +-26101 , +113 , +9939 , +24631 , +-30185 , +21551 , +1641 , +20213 , +30541 , +26651 , +-2909 , +-5733 , +19199 , +-20659 , +-8337 , +-25159 , +-3709 , +-25649 , +10017 , +-4645 , +521 , +11855 , +28543 , +2949 , +12025 , +2137 , +30053 , +24475 , +5831 , +30997 , +-16173 , +-18067 , +-29367 , +31859 , +-29809 , +23585 , +-2669 , +9453 , +-19405 , +-23889 , +-15283 , +26551 , +5577 , +29275 , +-15729 , +-15483 , +7145 , +13227 , +10545 , +-18003 , +-5307 , +-30239 , +11431 , +-28169 , +-2357 , +-32527 , +4447 , +24771 , +22839 , +27125 , +24719 , +-14393 , +-13515 , +7729 , +21905 , +26957 , +-29211 , +-8067 , +7103 , +-31265 , +8715 , +-27319 , +-2875 , +-17271 , +9109 , +-30453 , +-8325 , +25999 , +8637 , +32059 , +-10433 , +32671 , +-13415 , +13267 , +17357 , +-22641 , +18749 , +12597 , +-20077 , +4761 , +6473 , +-4937 , +27275 , +773 , +19207 , +10123 , +1939 , +-20625 , +27909 , +-24001 , +-28085 , +5241 , +2083 , +-5963 , +20321 , +-22273 , +-201 , +27801 , +-13965 , +27867 , +-21733 , +-22951 , +13409 , +18959 , +2895 , +29855 , +-16085 , +16519 , +-7419 , +29253 , +-1467 , +21579 , +6855 , +31439 , +-16279 , +-18883 , +15999 , +5481 , +1 , +8011 , +28701 , +-429 , +-18713 , +-10711 , +-22869 , +-31005 , +25299 , +22411 , +-28195 , +1017 , +28711 , +6361 , +-1483 , +757 , +-16059 , +23921 , +-2667 , +32055 , +-6541 , +-27061 , +-14249 , +-15859 , +7717 , +17483 , +-13599 , +20273 , +-18979 , +-11041 , +11209 , +20413 , +-7289 , +29007 , +-6561 , +-1621 , +-20669 , +14431 , +-14895 , +-32317 , +1485 , +-9575 , +-13127 , +-8681 , +-29881 , +4347 , +-9925 , +3839 , +18075 , +-6605 , +-8803 , +9867 , +-17071 , +19023 , +-31395 , +-14721 , +-26653 , +-5883 , +-24887 , +19657 , +26261 , +-17827 , +8469 , +26233 , +-24873 , +17899 , +9977 , +16695 , +26897 , +4237 , +-19003 , +4931 , +22267 , +11421 , +-22279 , +12773 , +-25981 , +25777 , +-26021 , +28263 , +-10989 , +-1851 , +7831 , +-3701 , +6007 , +26115 , +11853 , +19851 , +10799 , +12527 , +5037 , +-375 , +-18877 , +10789 , +-19307 , +4487 , +26275 , +9615 , +-28387 , +10727 , +-26115 , +-25567 , +20153 , +-25257 , +-17135 , +12295 , +10191 , +-8621 , +-6773 , +-29849 , +6087 , +-4837 , +-15011 , +-28263 , +7089 , +1831 , +-29033 , +23251 , +24403 , +19745 , +-8263 , +-3469 , +-20801 , +-26783 , +20627 , +20391 , +1145 , +12509 , +-18535 , +-32595 , +-29701 , +-20311 , +-16455 , +-32629 , +-3875 , +-22037 , +-6469 , +-20669 , +21097 , +27217 , +31759 , +25745 , +-19539 , +32525 , +-18391 , +-27363 , +16413 , +14413 , +-31651 , +563 , +15519 , +-7375 , +2865 , +-5115 , +-721 , +-3519 , +-22217 , +-16813 , +-18705 , +-13207 , +22119 , +-20557 , +-31039 , +31345 , +8183 , +-13509 , +-31649 , +-5391 , +-13651 , +23749 , +14841 , +1229 , +13759 , +14237 , +22591 , +16429 , +-27097 , +-12351 , +-247 , +-527 , +8829 , +-25199 , +29283 , +21929 , +18247 , +-15341 , +-27605 , +-28137 , +-1057 , +29083 , +-1497 , +5145 , +20417 , +-3309 , +-1889 , +-11221 , +-14237 , +-3677 , +31089 , +14937 , +-22635 , +-11525 , +-2131 , +-31557 , +-19891 , +-19459 , +30637 , +29803 , +-28663 , +-2571 , +-11353 , +30975 , +23203 , +-10657 , +13519 , +4733 , +30379 , +2317 , +4325 , +-24107 , +19517 , +-13075 , +-31659 , +24543 , +-1963 , +29497 , +24775 , +-19767 , +-29007 , +-11981 , +-14269 , +-26095 , +1059 , +-27561 , +-21321 , +26887 , +22885 , +-3811 , +3109 , +-30793 , +7803 , +-23509 , +16679 , +29289 , +-6525 , +-16885 , +16401 , +-20583 , +-15345 , +12645 , +6283 , +-2963 , +26109 , +-25669 , +-27741 , +12203 , +-4909 , +16537 , +18025 , +-19653 , +4239 , +-20649 , +-3837 , +13325 , +-20731 , +2887 , +-32185 , +-10077 , +23225 , +28275 , +-26665 , +3583 , +559 , +24273 , +-11593 , +23325 , +18379 , +-12795 , +-10149 , +-5395 , +-24033 , +-25719 , +22607 , +1225 , +-9007 , +4467 , +-4537 , +11117 , +4587 , +21411 , +14515 , +6767 , +-19541 , +14723 , +-1055 , +23097 , +-16657 , +-30149 , +-22133 , +-23937 , +-20997 , +4969 , +9463 , +-15563 , +17367 , +-28071 , +7047 , +19471 , +-14295 , +-6209 , +-13861 , +-21907 , +-13427 , +-29207 , +-31391 , +-2593 , +3179 , +-13947 , +-7571 , +8981 , +-27573 , +-29501 , +-12585 , +-10919 , +-23111 , +-31451 , +30991 , +-31097 , +-28017 , +19365 , +23477 , +15753 , +4823 , +12147 , +17839 , +-29879 , +13343 , +-27855 , +-18743 , +1579 , +31057 , +21669 , +26819 , +-1017 , +17163 , +14071 , +23791 , +-28003 , +6263 , +-14495 , +17989 , +3729 , +-5975 , +-19347 , +-22523 , +30949 , +-9113 , +4015 , +-32579 , +23271 , +-12139 , +29169 , +-9741 , +-14155 , +4353 , +31231 , +5173 , +29227 , +27579 , +-25143 , +18349 , +-3485 , +13553 , +-14805 , +-28351 , +5545 , +21319 , +-21215 , +-23511 , +19953 , +-4951 , +30329 , +30721 , +3541 , +-13393 , +31505 , +27497 , +16901 , +5477 , +-16755 , +-19687 , +-24247 , +26545 , +1939 , +28023 , +2799 , +-2009 , +4733 , +12981 , +-21557 , +-13479 , +-10607 , +31073 , +8615 , +-25415 , +21953 , +-22649 , +21829 , +-28945 , +-4393 , +10305 , +17101 , +15535 , +-21957 , +24017 , +26829 , +16911 , +31003 , +-14279 , +5545 , +-10653 , +-8397 , +14421 , +19355 , +-29035 , +-261 , +26479 , +29481 , +-8201 , +-32673 , +-13473 , +-27625 , +31655 , +18939 , +-233 , +19687 , +6745 , +-31531 , +-26683 , +16587 , +-12105 , +-7541 , +-16793 , +13345 , +-31687 , +-25065 , +26083 , +-28821 , +-26503 , +12031 , +30113 , +-32575 , +27921 , +10001 , +-16225 , +29649 , +-15379 , +12951 , +8461 , +6227 , +-22491 , +-19693 , +-28571 , +-20733 , +-4775 , +-5003 , +-27651 , +-10989 , +-8319 , +15575 , +-10711 , +-31189 , +15181 , +22187 , +17353 , +-29475 , +1781 , +-2689 , +-31127 , +6557 , +25501 , +1323 , +13011 , +-18373 , +-4321 , +-19565 , +-31703 , +23511 , +-12693 , +25815 , +-1151 , +-18083 , +-1953 , +521 , +-17419 , +-22405 , +-9955 , +-25999 , +-1211 , +-15591 , +-6687 , +-12489 , +24293 , +-1197 , +14687 , +423 , +-25191 , +24561 , +-12137 , +-17439 , +15761 , +-14505 , +-32723 , +19473 , +-14595 , +-26359 , +14909 , +2607 , +17185 , +28063 , +-17215 , +16427 , +24569 , +-17099 , +16469 , +11443 , +4163 , +21617 , +16291 , +6235 , +31 , +-14357 , +-4311 , +-2713 , +-18905 , +-25033 , +32161 , +-32271 , +-18169 , +26699 , +-19251 , +25773 , +-28275 , +-32635 , +4821 , +15391 , +337 , +-22501 , +-3045 , +6223 , +17851 , +15129 , +-6757 , +22277 , +-16473 , +13007 , +-18505 , +23167 , +-10375 , +-20781 , +27035 , +4775 , +30137 , +15481 , +-31477 , +-12075 , +-6111 , +-27453 , +705 , +24053 , +-29889 , +2269 , +20295 , +-13485 , +4237 , +21785 , +-30649 , +-2619 , +-18179 , +4705 , +-30101 , +13157 , +23585 , +32307 , +-6229 , +9171 , +-27719 , +-12009 , +24117 , +6877 , +-7219 , +-9323 , +-6219 , +7621 , +14147 , +8627 , +-1741 , +-5391 , +-30463 , +11497 , +2927 , +1065 , +4471 , +19607 , +949 , +13125 , +-12097 , +32003 , +-27339 , +-32397 , +-13005 , +-21301 , +13017 , +6371 , +-8569 , +6369 , +-22109 , +2309 , +23905 , +-2305 , +-1153 , +25917 , +-28823 , +9891 , +-27999 , +-18911 , +10225 , +8329 , +25939 , +13613 , +-19207 , +-9063 , +8795 , +-13577 , +20699 , +-6551 , +-567 , +18419 , +28755 , +22579 , +13901 , +-12389 , +9505 , +-2999 , +-5351 , +-4551 , +-21219 , +5391 , +23089 , +20749 , +-23091 , +-21643 , +8005 , +-26351 , +-17277 , +1007 , +-29937 , +16431 , +13037 , +-30231 , +-21731 , +2295 , +4153 , +16833 , +6711 , +-3885 , +22173 , +12611 , +12591 , +7369 , +5499 , +28313 , +-20419 , +-18261 , +-20487 , +3529 , +30935 , +16595 , +12305 , +-23377 , +28675 , +11865 , +-465 , +-25235 , +8505 , +32199 , +-10937 , +3945 , +14767 , +2143 , +19309 , +22213 , +29757 , +10175 , +-14609 , +8789 , +3503 , +-25557 , +14315 , +12307 , +22937 , +11579 , +28263 , +28707 , +-28743 , +-747 , +25835 , +-14787 , +27079 , +1573 , +22421 , +8625 , +-22067 , +-17575 , +-75 , +9171 , +8455 , +17105 , +-13339 , +3329 , +20273 , +17181 , +27803 , +10253 , +12903 , +-17675 , +-29365 , +27713 , +24437 , +-9361 , +4599 , +-29237 , +-1353 , +23735 , +-20155 , +13507 , +-22161 , +17735 , +17189 , +-28011 , +5013 , +-25699 , +-25639 , +3587 , +3645 , +-1411 , +19345 , +15771 , +1633 , +32669 , +6799 , +-5977 , +-15289 , +3293 , +-26195 , +18097 , +8007 , +21515 , +-24703 , +13687 , +-17863 , +-23279 , +2543 , +-25251 , +24635 , +-2387 , +-25529 , +-17303 , +6671 , +8625 , +20953 , +-28735 , +-27659 , +-14675 , +-759 , +5017 , +-5117 , +-10697 , +-29965 , +-28239 , +-32519 , +13211 , +-15499 , +-18871 , +-9827 , +27149 , +-8753 , +-23647 , +15505 , +-5009 , +-15941 , +-17433 , +4269 , +-10369 , +19717 , +22963 , +-25135 , +-20849 , +30109 , +12037 , +17993 , +2755 , +-24523 , +-32079 , +-12139 , +-19261 , +859 , +1119 , +-9777 , +8439 , +28425 , +28421 , +2171 , +-14789 , +20677 , +-20007 , +6117 , +18207 , +19505 , +-10291 , +21491 , +-6765 , +16431 , +25985 , +-25219 , +14633 , +4199 , +26051 , +-28883 , +-24629 , +2933 , +-9081 , +-9525 , +24815 , +17771 , +-10157 , +30499 , +-1201 , +-16645 , +-9657 , +-18863 , +-27351 , +-20219 , +-13173 , +-9061 , +1775 , +-11087 , +16199 , +20433 , +30849 , +7 , +9251 , +-2275 , +2277 , +-4345 , +-16333 , +-7331 , +30849 , +-28345 , +3195 , +-10245 , +19923 , +-19457 , +15581 , +-13237 , +27811 , +24745 , +-23143 , +-685 , +-26687 , +-14309 , +-18623 , +-22471 , +-10943 , +4629 , +18735 , +1285 , +11557 , +-5785 , +-5501 , +-26099 , +-17757 , +7291 , +29077 , +32703 , +-30763 , +10873 , +-32273 , +-21255 , +11253 , +5333 , +16585 , +-7185 , +-23533 , +19821 , +-4103 , +22387 , +24143 , +6433 , +-22669 , +-24365 , +-4213 , +16105 , +-6851 , +7735 , +27565 , +23403 , +11237 , +20845 , +-10163 , +-20199 , +26493 , +22349 , +-19979 , +-13119 , +20755 , +3977 , +-1069 , +-10575 , +-30555 , +3333 , +-11787 , +-6081 , +-25185 , +-6473 , +-2561 , +15855 , +-16949 , +245 , +20067 , +-25085 , +17105 , +26451 , +-12261 , +-13417 , +-10711 , +-12549 , +-13603 , +24117 , +25497 , +22913 , +4057 , +-10763 , +-28125 , +12351 , +-5399 , +17417 , +-1139 , +-28629 , +26193 , +24543 , +-9659 , +24111 , +-12045 , +24759 , +26093 , +-9213 , +-249 , +29619 , +-27069 , +-27263 , +15697 , +9853 , +-31581 , +7811 , +28387 , +-25005 , +9209 , +-18123 , +19779 , +-3163 , +-30915 , +31985 , +17207 , +-30163 , +28265 , +5523 , +-9747 , +-17021 , +20977 , +-19627 , +12477 , +-17865 , +-23361 , +17189 , +30557 , +-9365 , +-31581 , +-30847 , +-7529 , +25835 , +-28335 , +10695 , +5001 , +-3647 , +8663 , +23571 , +26959 , +28495 , +-28519 , +9109 , +13645 , +-789 , +-10817 , +-7315 , +18903 , +-30735 , +10299 , +16375 , +-9359 , +31837 , +-8909 , +-3401 , +11399 , +25059 , +15875 , +-22885 , +-1117 , +-17011 , +-29519 , +29925 , +11299 , +4037 , +-4381 , +6777 , +-24201 , +18173 , +30561 , +32179 , +-15149 , +32441 , +1531 , +-25395 , +-21139 , +25397 , +13843 , +31907 , +25387 , +4463 , +5003 , +12319 , +13287 , +-13369 , +-12737 , +-28671 , +-27871 , +23321 , +9215 , +-17601 , +31799 , +29771 , +-18171 , +-2083 , +-12517 , +-1421 , +5869 , +3139 , +-24689 , +30051 , +-30163 , +-22251 , +-4385 , +-27453 , +-27121 , +-1143 , +-14321 , +6069 , +14117 , +71 , +13985 , +-3881 , +-21433 , +-20807 , +4029 , +-269 , +-505 , +-27421 , +1529 , +12803 , +-859 , +-1087 , +-123 , +29911 , +-4975 , +11289 , +9963 , +13091 , +-26277 , +-5159 , +-20929 , +-11231 , +1837 , +-13339 , +-17185 , +413 , +31427 , +24189 , +32679 , +5017 , +4071 , +-4599 , +-11351 , +30813 , +-27037 , +-13195 , +-31901 , +28945 , +-4741 , +-11505 , +-29057 , +-1321 , +-27163 , +10961 , +29699 , +15457 , +-19899 , +-2743 , +-2297 , +20487 , +11807 , +-4633 , +22009 , +-15767 , +17231 , +-25643 , +27719 , +-25227 , +5643 , +11349 , +-18779 , +22547 , +-24759 , +-29291 , +-20045 , +-32211 , +-25141 , +-7677 , +-29877 , +-31409 , +-14967 , +-7119 , +-25051 , +20929 , +-6737 , +21279 , +-20453 , +20503 , +15633 , +-227 , +27357 , +28495 , +-19159 , +-28895 , +1835 , +-22679 , +15239 , +-26985 , +-23929 , +-14211 , +-3629 , +5061 , +14197 , +-4527 , +27707 , +-4451 , +-20431 , +28791 , +-18829 , +-28653 , +3043 , +-22817 , +22309 , +10747 , +3673 , +23281 , +2547 , +-14501 , +29249 , +15657 , +26597 , +-17081 , +5599 , +14121 , +13927 , +-27597 , +6725 , +-3501 , +-27455 , +471 , +27915 , +27363 , +-16371 , +2939 , +-19317 , +-6267 , +-23123 , +-5935 , +5777 , +11629 , +-953 , +-16553 , +-11877 , +18671 , +6971 , +-12769 , +8331 , +-15719 , +18591 , +8759 , +24803 , +-26423 , +-19025 , +27507 , +-3207 , +-10809 , +-7731 , +2513 , +-12361 , +6743 , +-25615 , +-5303 , +16711 , +-2855 , +23209 , +21029 , +-14251 , +23773 , +8845 , +7137 , +-27579 , +11069 , +-19657 , +-24453 , +-28443 , +-6479 , +12989 , +-15799 , +32301 , +-17175 , +4005 , +18015 , +2673 , +39 , +20835 , +3411 , +26401 , +343 , +3911 , +17577 , +20467 , +-24925 , +17921 , +10393 , +-855 , +24205 , +-15467 , +28279 , +-2747 , +28557 , +25037 , +-4225 , +16571 , +25625 , +18231 , +-21455 , +-6609 , +851 , +26267 , +-16339 , +14509 , +1551 , +-2827 , +24197 , +-6819 , +6259 , +3565 , +28313 , +15425 , +-2037 , +16071 , +-7829 , +-21657 , +1641 , +12263 , +22395 , +-7005 , +10289 , +9413 , +12063 , +-23095 , +18623 , +-30115 , +-27817 , +-25757 , +23089 , +19507 , +-23767 , +21993 , +10759 , +10181 , +18809 , +-13957 , +-7619 , +-18817 , +-8869 , +20501 , +-28967 , +26175 , +8945 , +-22963 , +-32752 , +6205 , +-15161 , +-9597 , +-7977 , +-24943 , +-8803 , +-22877 , +23029 , +-12251 , +-21811 , +11345 , +6567 , +27437 , +-227 , +-29779 , +6067 , +32287 , +-29163 , +19587 , +-4611 , +-28887 , +-22563 , +4615 , +7585 , +14899 , +32141 , +-28407 , +6287 , +32071 , +-31217 , +16563 , +-6245 , +27543 , +7021 , +-16967 , +-15073 , +32493 , +-5971 , +22553 , +-31737 , +16295 , +16433 , +-15539 , +7029 , +31533 , +-3459 , +24843 , +11985 , +-16153 , +-16991 , +7791 , +-5533 , +23995 , +-4857 , +23491 , +3181 , +-29185 , +16847 , +-10581 , +29377 , +7673 , +-17505 , +3811 , +1241 , +12489 , +23053 , +7543 , +21103 , +26095 , +28255 , +30325 , +-16743 , +5435 , +-27141 , +-29393 , +-28841 , +-9909 , +-2773 , +-11541 , +-17991 , +8315 , +-13695 , +2075 , +-15765 , +-921 , +-3413 , +22557 , +-30001 , +-6185 , +29901 , +14185 , +25247 , +-17599 , +-20651 , +31823 , +13817 , +-30785 , +15703 , +-21971 , +12281 , +-28541 , +11361 , +-6359 , +-22055 , +6865 , +-25893 , +-27547 , +-16769 , +19577 , +22229 , +189 , +23197 , +-12081 , +-27293 , +11769 , +8515 , +31775 , +23159 , +8327 , +-775 , +-23129 , +-22213 , +-20045 , +-19107 , +28689 , +5343 , +23653 , +24875 , +-18325 , +-13829 , +-947 , +3309 , +-7271 , +-22429 , +-2141 , +28153 , +16983 , +-31359 , +-13471 , +-1507 , +17319 , +12073 , +29171 , +15275 , +11729 , +18165 , +-25481 , +-17891 , +-27181 , +-29157 , +13933 , +20251 , +19809 , +-17979 , +11259 , +16421 , +-167 , +26603 , +-5483 , +-2909 , +12989 , +19625 , +-27579 , +-24455 , +-5083 , +12309 , +23893 , +-17625 , +-23103 , +-11107 , +3217 , +-25761 , +-10811 , +24027 , +5627 , +3861 , +-17553 , +20459 , +18437 , +18471 , +-21903 , +-16569 , +-31933 , +-2717 , +-29451 , +-14049 , +29871 , +-8149 , +-11255 , +-5075 , +-13743 , +-6517 , +-29019 , +23057 , +-9595 , +-22067 , +-8427 , +-9945 , +13739 , +-13931 , +-30981 , +20193 , +6757 , +885 , +-15933 , +-30055 , +17477 , +3851 , +9627 , +26867 , +3347 , +-29037 , +-15635 , +-6229 , +22649 , +-5117 , +14929 , +16887 , +16959 , +31391 , +273 , +-21165 , +1799 , +-19175 , +-29679 , +-12571 , +8061 , +-4067 , +-26281 , +-32437 , +1561 , +22897 , +20471 , +761 , +-24755 , +-25711 , +28303 , +9491 , +-17341 , +-581 , +16453 , +-27971 , +-20461 , +22671 , +-28621 , +-14087 , +28541 , +-18647 , +21353 , +-10499 , +13085 , +-847 , +16735 , +32525 , +5159 , +26233 , +4851 , +-12335 , +-25697 , +17043 , +-24611 , +-12755 , +-17393 , +-19731 , +-27995 , +18329 , +11707 , +-11037 , +-5347 , +25849 , +-23197 , +9559 , +1885 , +5625 , +-8845 , +31053 , +27445 , +-4899 , +-5699 , +25351 , +-471 , +-32031 , +-12875 , +23439 , +-2075 , +-757 , +-13021 , +-30501 , +13117 , +-13943 , +28505 , +30821 , +8087 , +11647 , +-21255 , +-22983 , +2291 , +-17555 , +16413 , +10393 , +-4519 , +18939 , +-28907 , +22541 , +-24879 , +-31913 , +10659 , +-13315 , +21731 , +-23287 , +20655 , +-31797 , +-30589 , +-30637 , +-32643 , +-27543 , +12179 , +-29955 , +30057 , +12913 , +9435 , +28857 , +-23779 , +28863 , +-4747 , +-11023 , +-27061 , +-29821 , +-27435 , +17705 , +14563 , +6117 , +-10443 , +-25655 , +28875 , +-4081 , +21141 , +-19577 , +4373 , +13261 , +-2517 , +2863 , +-27203 , +13735 , +26727 , +29187 , +-24097 , +-21391 , +-25767 , +21651 , +-18327 , +363 , +18365 , +-15851 , +10073 , +4817 , +-31131 , +-15819 , +-25229 , +17149 , +16439 , +4985 , +25215 , +11253 , +-21343 , +-5613 , +-22031 , +-12405 , +-26987 , +-14535 , +-1993 , +-25617 , +-24575 , +251 , +4699 , +7371 , +15299 , +4769 , +28751 , +-20265 , +-27097 , +19839 , +-22125 , +7159 , +9175 , +585 , +-11139 , +19917 , +3931 , +-17673 , +20451 , +13525 , +15627 , +-25327 , +-4257 , +-2565 , +7563 , +-29559 , +509 , +24755 , +1731 , +10013 , +11129 , +-2159 , +19281 , +12321 , +-30727 , +25957 , +-14197 , +-31523 , +4667 , +-18743 , +8939 , +12653 , +-15271 , +12359 , +26901 , +-16887 , +27385 , +6371 , +21827 , +19691 , +-23799 , +20797 , +-6847 , +-24417 , +-1549 , +3879 , +-32539 , +-23843 , +-22439 , +-27211 , +26381 , +-31773 , +-8371 , +16869 , +-26355 , +2637 , +8195 , +-15451 , +-853 , +11113 , +-27117 , +-9351 , +-4967 , +-31729 , +-5079 , +29833 , +-4247 , +-13821 , +-27841 , +29505 , +-13041 , +-12867 , +-2987 , +4195 , +-17721 , +9425 , +-31573 , +6311 , +-10847 , +5307 , +13433 , +-5947 , +-23705 , +-10691 , +12319 , +32283 , +-11739 , +-14029 , +27629 , +29629 , +-4587 , +-20239 , +-3511 , +17429 , +17949 , +-28393 , +27765 , +-22801 , +-18749 , +17127 , +-8771 , +25625 , +-27729 , +23329 , +2361 , +29305 , +26513 , +30811 , +31225 , +-17493 , +-15701 , +-28201 , +-23093 , +23565 , +-12353 , +24279 , +8805 , +-18591 , +-6263 , +28287 , +25893 , +14813 , +-9543 , +2087 , +1355 , +7631 , +10857 , +27697 , +-1879 , +3495 , +-6381 , +-29339 , +-15645 , +-1383 , +28177 , +-9531 , +3875 , +-81 , +-17013 , +12779 , +-21429 , +-22171 , +-26893 , +-28195 , +25535 , +31169 , +10243 , +-22941 , +-23927 , +231 , +29223 , +-15387 , +27933 , +25141 , +10373 , +27581 , +-27255 , +-25131 , +15467 , +-3823 , +-21445 , +30435 , +-12215 , +22061 , +-23773 , +19955 , +-14039 , +-1447 , +-25725 , +-14285 , +-18777 , +12337 , +-10733 , +-25851 , +18797 , +21633 , +15815 , +21521 , +4133 , +32147 , +-31489 , +30175 , +-19725 , +23315 , +19777 , +-16143 , +25965 , +24159 , +20853 , +345 , +-14569 , +-15517 , +2709 , +14545 , +-5549 , +-28177 , +-14613 , +32085 , +-17949 , +12171 , +-21559 , +25655 , +29909 , +-26147 , +-26177 , +20921 , +30983 , +-7825 , +27473 , +-31445 , +5141 , +-749 , +-31179 , +14713 , +-27943 , +-29255 , +14087 , +-19897 , +18269 , +-21823 , +-12419 , +-29301 , +-17063 , +20187 , +-213 , +12709 , +-10971 , +32091 , +24235 , +-20495 , +-719 , +-18417 , +-23193 , +-3095 , +16901 , +-8801 , +-32321 , +-26957 , +27823 , +2139 , +-29747 , +12097 , +-6207 , +-31337 , +19101 , +30435 , +-23861 , +32135 , +-15399 , +6755 , +-21433 , +25489 , +-29167 , +-28775 , +-17885 , +-14553 , +-8853 , +-14455 , +22699 , +-25311 , +-32043 , +5365 , +-2045 , +-26221 , +21963 , +8059 , +-28635 , +-19929 , +131 , +15139 , +4951 , +24819 , +-22867 , +-893 , +26397 , +-16435 , +24227 , +24911 , +7095 , +5165 , +-2773 , +25973 , +-26085 , +-7299 , +-3165 , +23733 , +101 , +10229 , +24773 , +-5967 , +25815 , +-16911 , +13271 , +-7275 , +-18617 , +-24121 , +-3483 , +5915 , +-1751 , +5671 , +28797 , +6199 , +1007 , +19173 , +11103 , +7967 , +-27115 , +-25499 , +14011 , +13291 , +-8559 , +859 , +13419 , +-30799 , +16073 , +-12999 , +20129 , +21005 , +31503 , +13561 , +-21333 , +2893 , +4503 , +-2949 , +23073 , +23291 , +-4111 , +26205 , +6311 , +-27909 , +16125 , +20555 , +5147 , +3871 , +32101 , +-4635 , +-3757 , +20805 , +-24421 , +21517 , +12117 , +12777 , +29765 , +-15167 , +21257 , +-703 , +-4031 , +2931 , +-10885 , +-11053 , +-17135 , +31201 , +19593 , +11659 , +-24865 , +-25231 , +-14811 , +-15781 , +-275 , +17665 , +-12801 , +-11447 , +19347 , +-4283 , +5583 , +2317 , +26285 , +14753 , +14331 , +-10969 , +-9569 , +26489 , +-29473 , +-22919 , +3527 , +-26097 , +-30089 , +-13735 , +11377 , +-12069 , +-22877 , +21045 , +345 , +19037 , +13269 , +-10851 , +29851 , +23935 , +12369 , +26853 , +-5843 , +25445 , +32733 , +-24521 , +12505 , +-13881 , +-30715 , +-2255 , +20147 , +-6711 , +-22843 , +29941 , +-16367 , +-24745 , +31689 , +-6967 , +-31741 , +-29449 , +31779 , +31529 , +-26293 , +-26591 , +-14203 , +16229 , +10969 , +-15843 , +-16903 , +4531 , +8893 , +8537 , +14613 , +-23095 , +23457 , +-20679 , +947 , +18933 , +10435 , +-387 , +25905 , +-11591 , +27753 , +29197 , +19745 , +-32035 , +-2849 , +3159 , +4227 , +18441 , +22505 , +28453 , +12669 , +9185 , +1215 , +9205 , +10647 , +6547 , +-15231 , +-15151 , +-20887 , +30715 , +24885 , +7595 , +26849 , +-10189 , +-21703 , +-8657 , +-26897 , +-22351 , +-27331 , +-3045 , +-28733 , +-25385 , +-24897 , +9757 , +-23935 , +-9967 , +17661 , +1833 , +18303 , +13165 , +-19859 , +-9653 , +7159 , +24751 , +25789 , +32519 , +-24509 , +26093 , +321 , +-471 , +12435 , +9893 , +4083 , +-12503 , +12327 , +26457 , +-11035 , +28147 , +-8447 , +7325 , +59 , +22861 , +-11737 , +24249 , +27813 , +4523 , +-31151 , +-9793 , +-23465 , +12413 , +1323 , +4639 , +25725 , +12315 , +5375 , +21955 , +-10443 , +-1017 , +-5379 , +-20061 , +-17399 , +-7721 , +-10263 , +-15387 , +14055 , +-1409 , +-6315 , +-15769 , +32147 , +-23497 , +-5797 , +-29209 , +7081 , +9415 , +-8495 , +10641 , +1291 , +3171 , +16391 , +28441 , +11999 , +28933 , +5623 , +22357 , +-6393 , +-26047 , +24069 , +-20657 , +-24043 , +13733 , +-20429 , +-28183 , +30663 , +-21625 , +-24615 , +32229 , +1535 , +-21407 , +-12579 , +24717 , +-3531 , +-29011 , +11115 , +27841 , +-16007 , +-27337 , +20527 , +5775 , +16095 , +-18953 , +32525 , +2895 , +10373 , +-1683 , +11859 , +32313 , +23293 , +2673 , +-24453 , +-24189 , +13135 , +3729 , +32341 , +-23575 , +24431 , +24299 , +-5165 , +2779 , +-10963 , +14717 , +3883 , +-16129 , +10171 , +771 , +-32095 , +-20135 , +-3175 , +12621 , +-22349 , +18145 , +-26349 , +30233 , +23255 , +-22385 , +-713 , +16999 , +-5455 , +2561 , +-30385 , +14935 , +-4659 , +-6003 , +8403 , +-20099 , +-13355 , +-29479 , +17901 , +-14411 , +-30905 , +-22287 , +9313 , +16003 , +-18253 , +27367 , +-17643 , +-24857 , +13423 , +-9247 , +-9219 , +-14407 , +21195 , +-7241 , +14999 , +31861 , +21203 , +-14071 , +16617 , +3237 , +-12417 , +-31271 , +-7445 , +-21593 , +-16527 , +-14177 , +10385 , +-28395 , +-2271 , +-1563 , +-22989 , +31121 , +-23129 , +7773 , +-25717 , +-24541 , +-15387 , +-4741 , +-3789 , +-14323 , +-4543 , +-2935 , +-13167 , +28457 , +-24345 , +7747 , +-3493 , +-16195 , +20081 , +30449 , +-20601 , +24787 , +18735 , +-31503 , +-32571 , +-22513 , +-2351 , +3559 , +12409 , +26637 , +18089 , +-24515 , +-23761 , +-12237 , +-7583 , +-18101 , +2715 , +-29939 , +4397 , +-8219 , +-18685 , +-21469 , +-14963 , +-29825 , +16199 , +-31151 , +-12937 , +12213 , +14159 , +675 , +-25309 , +17521 , +11523 , +-28765 , +-21457 , +-23939 , +9161 , +16703 , +-8863 , +3223 , +18041 , +14609 , +-5921 , +15635 , +2005 , +-4281 , +16615 , +20459 , +27007 , +29681 , +26879 , +-7845 , +-24201 , +16601 , +14269 , +-18187 , +-10737 , +-19489 , +-1299 , +22843 , +10337 , +-13867 , +-2473 , +19391 , +-15027 , +12743 , +13551 , +-32345 , +13545 , +20711 , +9359 , +-24355 , +-24443 , +20181 , +-3023 , +-27241 , +18193 , +-15743 , +11429 , +16495 , +-10199 , +6015 , +31691 , +-26359 , +-4737 , +17375 , +10821 , +7449 , +23257 , +-6523 , +13239 , +-7161 , +-29565 , +26113 , +31103 , +12037 , +-21421 , +10221 , +2015 , +-12893 , +-15083 , +30903 , +-6709 , +12011 , +-25463 , +15365 , +26383 , +30455 , +31701 , +-627 , +30991 , +28935 , +-24951 , +31335 , +-7683 , +-18913 , +-32758 , +15077 , +-5485 , +-8163 , +-16493 , +21743 , +27207 , +8521 , +-11611 , +-4389 , +-20985 , +6265 , +15881 , +-25917 , +12657 , +14753 , +-29379 , +8799 , +-23929 , +-23823 , +-16265 , +-9387 , +10219 , +-18845 , +26897 , +7199 , +24981 , +20449 , +11407 , +-5799 , +7177 , +-4145 , +-6645 , +29595 , +11799 , +-19921 , +7727 , +32207 , +30987 , +27183 , +4535 , +17425 , +-31901 , +-17849 , +-421 , +-1283 , +-23021 , +-32559 , +-4527 , +32655 , +17457 , +28957 , +-17859 , +20339 , +1331 , +12559 , +31157 , +25061 , +-30301 , +-11473 , +6699 , +-1787 , +-28067 , +1353 , +21613 , +945 , +4675 , +-13439 , +-18273 , +10197 , +8819 , +8169 , +2217 , +3411 , +20737 , +20127 , +-26309 , +329 , +16951 , +26209 , +-3777 , +-30217 , +7227 , +-27231 , +24527 , +783 , +-19113 , +-13275 , +-16207 , +-9585 , +-851 , +31007 , +10059 , +-31203 , +-27285 , +-16965 , +-22491 , +-14121 , +7301 , +-5055 , +-1841 , +25011 , +4335 , +-21591 , +7785 , +-17839 , +-10669 , +-26701 , +-7527 , +-20905 , +-13751 , +-19071 , +18169 , +839 , +-7151 , +-27477 , +-20711 , +-22313 , +-10551 , +29915 , +-1805 , +22989 , +11809 , +18403 , +15331 , +-19123 , +23969 , +-6057 , +26143 , +26813 , +14925 , +23713 , +28847 , +-32235 , +-10511 , +32415 , +25067 , +-32069 , +15047 , +-8269 , +-10651 , +19159 , +-5443 , +16739 , +18543 , +29999 , +-17113 , +31341 , +-12785 , +15231 , +-4107 , +8285 , +-31379 , +31567 , +-1679 , +-12885 , +26591 , +-3255 , +2927 , +23627 , +-17587 , +20755 , +-16115 , +-4911 , +-9677 , +10159 , +-4377 , +4601 , +-30181 , +26177 , +3533 , +-1843 , +-26481 , +26489 , +14339 , +-6857 , +-2415 , +12641 , +12525 , +-9451 , +2717 , +-587 , +28497 , +-13349 , +28943 , +-23867 , +-24053 , +8357 , +-7375 , +-2883 , +-22715 , +-1847 , +31901 , +-18549 , +28211 , +-2817 , +5959 , +14637 , +-17599 , +-6423 , +-2581 , +11411 , +18135 , +15667 , +29957 , +-8979 , +11911 , +-31701 , +-1457 , +20873 , +12495 , +-11563 , +-9549 , +31275 , +-21689 , +31879 , +28361 , +-1057 , +-11425 , +-8447 , +3529 , +-18851 , +8597 , +-23295 , +9987 , +-26159 , +26415 , +21853 , +12767 , +-6845 , +-31119 , +-31075 , +-21429 , +25953 , +17747 , +-28907 , +-8263 , +-13341 , +12989 , +2417 , +-23401 , +-18599 , +5697 , +1501 , +-9147 , +-31859 , +-7605 , +16273 , +-9845 , +31309 , +-24353 , +12017 , +28565 , +31957 , +21197 , +20513 , +-8341 , +-16999 , +14707 , +30233 , +23527 , +-23907 , +-32027 , +-32185 , +23593 , +26715 , +-12111 , +22687 , +29851 , +-25333 , +-28395 , +26679 , +-4515 , +3203 , +-23887 , +-24485 , +-10945 , +13453 , +15051 , +10791 , +-19389 , +-9791 , +-31241 , +-16731 , +-18295 , +-11047 , +-1185 , +-3751 , +29383 , +-20337 , +-9619 , +18277 , +-4273 , +12271 , +-13555 , +29463 , +23673 , +21811 , +6241 , +-29689 , +-2149 , +277 , +32251 , +-25681 , +30861 , +-15693 , +-111 , +22143 , +-19563 , +-4133 , +-15561 , +22907 , +-22043 , +-25113 , +26139 , +-15285 , +-16239 , +-27881 , +-15433 , +-30757 , +22023 , +-14233 , +-22643 , +16751 , +28171 , +-27673 , +24921 , +-1477 , +-21465 , +5013 , +-19499 , +-23687 , +21671 , +-3917 , +5603 , +-22777 , +-29671 , +5021 , +-16817 , +25723 , +-29389 , +24615 , +29185 , +-3397 , +3421 , +4721 , +-29509 , +-491 , +-30817 , +-11201 , +15435 , +6871 , +-23013 , +8909 , +26179 , +25705 , +-32247 , +7477 , +12347 , +-16157 , +-3547 , +21299 , +-23941 , +-24281 , +-24653 , +-21359 , +23867 , +-27279 , +6639 , +239 , +-10149 , +-29057 , +-24565 , +30755 , +9623 , +8985 , +-9827 , +19217 , +-21179 , +-19919 , +13731 , +-767 , +-8827 , +-18053 , +10227 , +-23179 , +17409 , +14467 , +-713 , +25225 , +2593 , +30787 , +32099 , +-29761 , +19397 , +3903 , +5291 , +-17055 , +16501 , +31261 , +-17661 , +21593 , +-20699 , +8377 , +21003 , +29307 , +-23447 , +8133 , +-20077 , +9075 , +-7383 , +-20783 , +6795 , +-17907 , +2009 , +31481 , +18557 , +-499 , +-10699 , +-12821 , +-9849 , +17043 , +-22147 , +-9851 , +17615 , +-795 , +32543 , +-15 , +6017 , +-3115 , +-27649 , +28729 , +-20415 , +-24695 , +3103 , +-4261 , +12583 , +-11805 , +-25367 , +9709 , +-8141 , +16203 , +-20009 , +18981 , +-20917 , +19 , +949 , +32385 , +7339 , +-23995 , +6737 , +-17197 , +14569 , +-7165 , +-20291 , +-23073 , +-6307 , +-20903 , +29693 , +3441 , +13349 , +26779 , +5193 , +-25865 , +-7525 , +15411 , +8375 , +22165 , +-3253 , +24839 , +-23163 , +31425 , +22633 , +2631 , +1217 , +25179 , +-28465 , +3011 , +393 , +-5311 , +24943 , +-12339 , +30147 , +9577 , +25933 , +-19063 , +-21935 , +-22917 , +-21511 , +28617 , +-13873 , +23019 , +7815 , +31841 , +26051 , +9605 , +-7423 , +19461 , +-31137 , +14997 , +30313 , +12955 , +15533 , +27507 , +-19161 , +-18411 , +12117 , +23973 , +-30199 , +25037 , +6597 , +-3991 , +31667 , +-29611 , +-18949 , +-20513 , +-12127 , +28117 , +2217 , +-21361 , +-32363 , +-10013 , +-30719 , +-28785 , +-19819 , +-10277 , +5343 , +17173 , +-5533 , +-18257 , +16005 , +1931 , +-16271 , +-24243 , +-14125 , +19763 , +14685 , +17513 , +-4861 , +10801 , +-30231 , +-12575 , +19675 , +-15061 , +30829 , +-23155 , +4201 , +-29597 , +5335 , +2967 , +9783 , +-28345 , +-223 , +18779 , +7687 , +-8049 , +-3007 , +27575 , +-27125 , +11989 , +-9807 , +13281 , +-19815 , +-20055 , +-173 , +20429 , +-26523 , +32047 , +-12293 , +29425 , +24893 , +15921 , +-22433 , +26543 , +-31941 , +-22345 , +3211 , +-20187 , +8831 , +29479 , +-3103 , +-10879 , +17769 , +13779 , +25485 , +-5921 , +25425 , +1819 , +3965 , +28835 , +17847 , +11255 , +14809 , +14155 , +-19445 , +-19169 , +-30467 , +10441 , +-7725 , +24729 , +3057 , +-12451 , +6001 , +-26669 , +9561 , +-30487 , +-29359 , +-7621 , +-27397 , +3277 , +-3669 , +-23463 , +22443 , +23103 , +-28495 , +-31899 , +-27193 , +-22753 , +-26805 , +17761 , +22579 , +26451 , +26709 , +-31319 , +15309 , +1183 , +31821 , +5659 , +-9373 , +24309 , +-15473 , +25759 , +10285 , +-21155 , +783 , +-17079 , +26825 , +-10437 , +9105 , +-16151 , +5807 , +-8651 , +-5283 , +-6101 , +21029 , +28803 , +6779 , +27437 , +9409 , +15307 , +24937 , +26001 , +19033 , +6261 , +10835 , +-28899 , +-18307 , +-23159 , +-21299 , +24783 , +-25487 , +27903 , +17413 , +-397 , +1953 , +10401 , +32649 , +-17215 , +673 , +16217 , +-6551 , +-25617 , +16023 , +4877 , +-6905 , +-28979 , +7491 , +14079 , +-8901 , +-6567 , +18283 , +9875 , +-12007 , +-17953 , +-30243 , +-27463 , +-24543 , +-23677 , +12505 , +-5189 , +20219 , +-22165 , +-26087 , +5527 , +20907 , +-21691 , +13629 , +9433 , +20555 , +11373 , +-21811 , +-2577 , +24139 , +-11649 , +24995 , +24839 , +7191 , +28781 , +6897 , +5215 , +-17567 , +-2533 , +-9035 , +-20697 , +24013 , +7285 , +-7507 , +13519 , +-14799 , +9737 , +-12847 , +28903 , +-11191 , +-29669 , +-13749 , +25453 , +-15637 , +-4029 , +-7183 , +19893 , +-24373 , +10877 , +16701 , +30641 , +-1117 , +-13367 , +31937 , +17871 , +13821 , +-4803 , +-10973 , +-18601 , +32601 , +-23647 , +27535 , +-6857 , +-6413 , +-4215 , +18619 , +-26265 , +-32527 , +-32287 , +24659 , +-26951 , +5667 , +11541 , +19189 , +-22223 , +22073 , +23199 , +-4435 , +5861 , +1139 , +23839 , +-12827 , +-30389 , +5863 , +-2309 , +13541 , +1817 , +16427 , +-4757 , +-571 , +5781 , +-9321 , +29 , +8937 , +-24459 , +-19461 , +7495 , +-10249 , +-21709 , +-25391 , +10809 , +24913 , +-31003 , +22015 , +14469 , +25099 , +-32363 , +-19965 , +32647 , +-10145 , +-17381 , +30391 , +-3451 , +-32591 , +14193 , +-3967 , +-13499 , +-10501 , +-19823 , +-20465 , +-7895 , +28359 , +28871 , +27273 , +9407 , +-9807 , +-32627 , +29781 , +6111 , +-11183 , +-25889 , +-12733 , +-26045 , +-3653 , +13079 , +15687 , +-7523 , +32121 , +-12475 , +25785 , +-979 , +-13317 , +16643 , +23301 , +-24355 , +-20077 , +-10543 , +-20251 , +-14375 , +22517 , +7659 , +25369 , +-16219 , +10781 , +19617 , +-20831 , +12981 , +3801 , +-4815 , +16243 , +-9853 , +-22087 , +-7907 , +-20043 , +21807 , +-9599 , +21763 , +-8849 , +-6261 , +13105 , +-17165 , +-6963 , +30143 , +-25491 , +29007 , +31951 , +-22951 , +-8069 , +1051 , +26753 , +29671 , +21699 , +-6443 , +-24903 , +3089 , +22965 , +30929 , +4685 , +21295 , +-5807 , +5651 , +-27453 , +-7069 , +-5091 , +16031 , +-13417 , +-6613 , +-29549 , +28245 , +-20507 , +-29823 , +16675 , +-17071 , +-28499 , +-26257 , +-15193 , +-8015 , +3969 , +-14041 , +-19111 , +-23553 , +4037 , +24221 , +4691 , +29437 , +4193 , +-13411 , +20349 , +3079 , +-6147 , +-18591 , +14345 , +-3361 , +23479 , +17069 , +22383 , +-17391 , +-30631 , +-8089 , +8417 , +-14143 , +-27109 , +-25939 , +-29377 , +-29941 , +-20791 , +7275 , +26519 , +-5419 , +-20849 , +22393 , +29 , +-7379 , +-30941 , +7981 , +32153 , +-4073 , +-12929 , +-28809 , +-31385 , +25843 , +27169 , +-26507 , +29169 , +17225 , +-7237 , +-31085 , +-12385 , +-21979 , +15469 , +-8427 , +22617 , +30197 , +-9857 , +26945 , +9587 , +10453 , +28051 , +-17435 , +20529 , +-19601 , +23913 , +10111 , +-18251 , +13909 , +-26871 , +21703 , +11137 , +21457 , +21381 , +28625 , +-25245 , +10821 , +-17621 , +14241 , +-18953 , +-28931 , +-7101 , +-13757 , +24733 , +-24179 , +9281 , +-31387 , +-25619 , +20385 , +11137 , +-11413 , +16307 , +-7845 , +-7303 , +15629 , +-3743 , +9773 , +-30853 , +-26777 , +-235 , +23079 , +-4121 , +-22889 , +22781 , +23515 , +-30751 , +3289 , +24927 , +19117 , +-6775 , +-8689 , +-13555 , +9647 , +31935 , +-20497 , +15961 , +-32009 , +25671 , +32389 , +-883 , +-2187 , +-23151 , +15709 , +14827 , +18257 , +3819 , +27921 , +26139 , +-2371 , +57 , +-29343 , +6953 , +21331 , +10799 , +-15405 , +-5379 , +-29211 , +-18429 , +-28991 , +-15537 , +-805 , +-9299 , +-8971 , +8229 , +7949 , +13467 , +25029 , +-15167 , +30481 , +2285 , +32167 , +13097 , +-10463 , +-14047 , +-27833 , +-26099 , +13669 , +-10661 , +8483 , +29001 , +-24365 , +787 , +30625 , +31971 , +28297 , +-14769 , +25511 , +28271 , +14239 , +-26277 , +-23113 , +-8929 , +-16511 , +30725 , +-29313 , +-13271 , +23239 , +-1205 , +-28169 , +30665 , +-4465 , +1699 , +15865 , +-24401 , +8277 , +32671 , +18775 , +3591 , +-12731 , +2103 , +13937 , +32225 , +26653 , +13173 , +19537 , +-17359 , +16505 , +11447 , +17733 , +6215 , +28345 , +18779 , +-30227 , +-3901 , +22859 , +32001 , +20701 , +-29169 , +-32627 , +10303 , +31413 , +861 , +-24033 , +14809 , +-32083 , +19987 , +-13119 , +6779 , +23487 , +27597 , +31909 , +23279 , +-28115 , +-24879 , +22603 , +-25389 , +-30297 , +-26361 , +-23083 , +-21033 , +12251 , +-14991 , +4323 , +19825 , +-1135 , +26661 , +-10005 , +-27375 , +-28605 , +-13115 , +13 , +31459 , +-8659 , +15215 , +-28047 , +26369 , +5875 , +-5055 , +-25067 , +21287 , +20141 , +-20149 , +-3277 , +27893 , +8581 , +-28921 , +17677 , +-19811 , +13775 , +-1199 , +-15543 , +-32223 , +-3429 , +-1313 , +-15411 , +-27891 , +17109 , +-10949 , +-27373 , +21159 , +-17189 , +-26823 , +4347 , +6827 , +1681 , +7149 , +2101 , +14985 , +-12807 , +-11221 , +7681 , +19217 , +11859 , +1139 , +11423 , +-15179 , +-9813 , +-20107 , +-13805 , +20543 , +-8455 , +-3327 , +1417 , +-13821 , +25779 , +-6783 , +-2775 , +28577 , +12265 , +-3597 , +11375 , +12337 , +20441 , +-23459 , +-19705 , +-26875 , +-14833 , +-14133 , +-27621 , +18657 , +-32017 , +1729 , +-25033 , +-29783 , +-28961 , +-19659 , +27545 , +-12123 , +-18483 , +4365 , +19213 , +-18131 , +-25769 , +-18425 , +8513 , +-29201 , +25941 , +23111 , +-9565 , +-24421 , +6907 , +-24517 , +-31309 , +-28641 , +-13715 , +21281 , +-21027 , +-6301 , +30425 , +-29195 , +3795 , +3707 , +6409 , +11505 , +14435 , +1633 , +-29565 , +13185 , +15057 , +-6353 , +-16097 , +24761 , +-3157 , +-26411 , +2329 , +-21933 , +4901 , +-16813 , +-9297 , +-10721 , +29165 , +19307 , +-7107 , +-5627 , +-12405 , +-17181 , +-19001 , +-21899 , +-28369 , +27443 , +-1251 , +-8355 , +-26355 , +-4155 , +31601 , +-26705 , +-12743 , +5287 , +-13459 , +9031 , +27895 , +18119 , +715 , +-1169 , +-18531 , +681 , +20077 , +20949 , +8161 , +13215 , +-18701 , +32253 , +-32583 , +-637 , +-3107 , +321 , +-32597 , +-5909 , +-23789 , +22855 , +-19283 , +-5659 , +-17139 , +22771 , +-25735 , +14639 , +-25251 , +16359 , +2405 , +30699 , +30673 , +18549 , +7355 , +5595 , +-28155 , +-7139 , +21139 , +29207 , +6531 , +24187 , +-11223 , +-20925 , +-4527 , +7885 , +-27469 , +-21425 , +14861 , +16351 , +22465 , +11943 , +11143 , +-18805 , +14343 , +-27927 , +-20777 , +-16729 , +-14649 , +7979 , +31225 , +-14709 , +23451 , +22943 , +17881 , +-28417 , +-21297 , +25307 , +-29699 , +-14927 , +18495 , +-13681 , +-24433 , +-22473 , +1195 , +-10575 , +-32521 , +11649 , +911 , +-19131 , +12027 , +10191 , +23419 , +-28537 , +-4017 , +-16083 , +751 , +-591 , +19117 , +-919 , +5033 , +-16859 , +5237 , +29835 , +-377 , +19247 , +29113 , +4817 , +-14369 , +9273 , +5601 , +-3299 , +-7091 , +22401 , +-24133 , +12025 , +-12777 , +15703 , +30231 , +-14583 , +-5381 , +-8753 , +-11559 , +25343 , +-9587 , +-1795 , +-25955 , +8223 , +-15087 , +10667 , +-27969 , +9767 , +-15669 , +6803 , +30723 , +15063 , +-3107 , +17937 , +-16479 , +3035 , +24733 , +14435 , +23779 , +26449 , +14961 , +-13217 , +25405 , +6833 , +-27363 , +23205 , +-8993 , +-20397 , +12453 , +21345 , +-21033 , +-15517 , +27557 , +14967 , +-9313 , +8785 , +-2527 , +32329 , +4411 , +30675 , +23777 , +8415 , +-18479 , +-19875 , +1355 , +-21585 , +31679 , +-7663 , +-20037 , +26057 , +-27085 , +-15043 , +9815 , +17559 , +-19647 , +-17585 , +1645 , +-28915 , +-13183 , +22099 , +-32191 , +-21655 , +-12253 , +17127 , +-4749 , +3943 , +27781 , +-16719 , +-10805 , +-13575 , +-10157 , +21855 , +-19817 , +-23171 , +-4333 , +7185 , +-15231 , +17789 , +31301 , +9057 , +15845 , +23261 , +-257 , +22479 , +19379 , +17305 , +-6153 , +-30527 , +5815 , +8957 , +25643 , +-12811 , +21885 , +-7335 , +-11793 , +893 , +-31065 , +6715 , +3715 , +-27597 , +27587 , +18219 , +-32203 , +19125 , +-9055 , +25819 , +16627 , +24799 , +-29905 , +17641 , +5987 , +-31303 , +-12337 , +-20979 , +-9097 , +4601 , +5681 , +-19241 , +-8303 , +8953 , +683 , +18149 , +-13553 , +-11221 , +-6135 , +24733 , +-11415 , +20243 , +-23055 , +-6813 , +-30011 , +-5693 , +-30793 , +-28081 , +12563 , +3019 , +15275 , +875 , +-10073 , +4537 , +31491 , +17251 , +14151 , +-6389 , +31271 , +-8759 , +31693 , +-29011 , +-18043 , +-5185 , +63 , +20967 , +20217 , +4919 , +12381 , +-12827 , +16277 , +-3927 , +31939 , +-26723 , +515 , +-7345 , +-19845 , +-20909 , +-16043 , +-19497 , +-28901 , +29839 , +30825 , +3481 , +-5799 , +26511 , +32177 , +16989 , +17953 , +19783 , +-26725 , +20611 , +12849 , +4311 , +12637 , +-23615 , +14383 , +1403 , +-14255 , +-30623 , +-13501 , +-14317 , +10705 , +-14099 , +-469 , +30471 , +-26231 , +28273 , +24279 , +30931 , +30801 , +6961 , +-12673 , +-30481 , +-31863 , +-2087 , +-20929 , +17231 , +17641 , +-21691 , +14371 , +-6563 , +-13601 , +21673 , +23761 , +-31897 , +16745 , +79 , +-621 , +21925 , +-31901 , +-28973 , +-9485 , +30627 , +15469 , +-31017 , +4051 , +-20669 , +-19659 , +-14025 , +28935 , +-30669 , +-11175 , +-24627 , +-22161 , +29917 , +-27207 , +7835 , +27269 , +11757 , +19031 , +20365 , +-30339 , +2107 , +-351 , +8363 , +24799 , +31057 , +30041 , +-29481 , +20121 , +-32171 , +-8991 , +-2305 , +-22885 , +14727 , +-10983 , +12247 , +-3607 , +10817 , +-8777 , +7699 , +-11713 , +-15519 , +-15075 , +-32485 , +25113 , +-29623 , +12205 , +-14771 , +26971 , +22613 , +-12371 , +26785 , +15965 , +12501 , +26001 , +-11525 , +-21621 , +11649 , +8413 , +15561 , +-20109 , +-3207 , +31095 , +31059 , +32109 , +4785 , +6533 , +12637 , +27807 , +-1551 , +-4159 , +32625 , +29609 , +-18097 , +589 , +26253 , +-15697 , +19235 , +6675 , +7007 , +-525 , +-25735 , +-8549 , +-26635 , +-7435 , +1559 , +31327 , +29189 , +-19965 , +-32021 , +24485 , +27543 , +13393 , +14595 , +17881 , +-18881 , +-18793 , +-20467 , +-2205 , +24795 , +-12251 , +22595 , +2047 , +-6203 , +20089 , +-24337 , +2969 , +24467 , +7519 , +21849 , +26011 , +12865 , +-31875 , +30793 , +18641 , +-6407 , +-29837 , +22003 , +-69 , +-5057 , +-3721 , +1147 , +5473 , +-9041 , +28001 , +2787 , +30387 , +13875 , +-20149 , +26251 , +9311 , +-1089 , +-2903 , +-22747 , +-29403 , +14719 , +25567 , +22829 , +10417 , +-7271 , +19547 , +30429 , +27381 , +1893 , +23847 , +6067 , +-22527 , +-14567 , +-11255 , +5721 , +85 , +6163 , +-4327 , +-6879 , +-4671 , +-17535 , +31443 , +18697 , +-30535 , +27041 , +-11081 , +13087 , +7725 , +-22663 , +14941 , +28809 , +11745 , +16139 , +-17141 , +26873 , +26949 , +-11757 , +-20015 , +-23647 , +-13615 , +32567 , +-2525 , +19115 , +24023 , +4553 , +-7961 , +25911 , +-12579 , +-19467 , +14361 , +-47 , +23669 , +-25731 , +729 , +-1181 , +16535 , +-22281 , +-28659 , +-17739 , +10873 , +29049 , +-30353 , +26207 , +-7967 , +-21795 , +27435 , +-185 , +-23291 , +29295 , +14323 , +-2159 , +28129 , +26157 , +-15969 , +-30179 , +-27641 , +2167 , +24123 , +-30591 , +1539 , +26195 , +24997 , +-10375 , +-25299 , +30741 , +13219 , +20965 , +-21759 , +13477 , +23165 , +19007 , +22263 , +-12495 , +21009 , +25239 , +-6951 , +5987 , +-30865 , +-3325 , +31651 , +29727 , +20721 , +-18787 , +-31535 , +28849 , +15053 , +-2309 , +15421 , +21653 , +-32713 , +-4573 , +-30601 , +-16995 , +2287 , +-26873 , +-19557 , +-19273 , +-15521 , +-23429 , +7333 , +13597 , +-19659 , +-10579 , +31059 , +-25073 , +-29583 , +26401 , +-16265 , +1807 , +13065 , +-15585 , +21707 , +-4465 , +-2311 , +19641 , +-30637 , +15159 , +-6949 , +23093 , +4141 , +1937 , +777 , +11279 , +-32533 , +12357 , +-11483 , +4461 , +27499 , +7381 , +-4033 , +29463 , +12851 , +-17715 , +8551 , +-785 , +12097 , +9093 , +-18239 , +-25109 , +17003 , +-7089 , +-26839 , +-26997 , +24625 , +24883 , +-21445 , +19921 , +14617 , +18989 , +19195 , +9403 , +-28283 , +-25893 , +10979 , +53 , +25099 , +7353 , +28025 , +-15973 , +22609 , +-7203 , +-32653 , +26025 , +-12197 , +-16857 , +13377 , +501 , +-8593 , +3329 , +-8399 , +22761 , +-32411 , +403 , +-6915 , +15415 , +-27263 , +-19589 , +31465 , +30169 , +-24625 , +2565 , +93 , +28539 , +2547 , +-4123 , +-15373 , +20613 , +-6517 , +-13975 , +-29415 , +-13695 , +-10759 , +-23233 , +-15831 , +19487 , +9165 , +8087 , +-32011 , +-11603 , +-19317 , +28659 , +-28689 , +4615 , +-9195 , +-26293 , +21943 , +11027 , +-19345 , +13525 , +-2765 , +-22339 , +3369 , +-12499 , +-24529 , +-1175 , +-29909 , +20507 , +8811 , +10989 , +4375 , +25799 , +-4297 , +-2291 , +2071 , +25707 , +-29807 , +7789 , +-24263 , +-22639 , +-21327 , +1033 , +-22711 , +-13877 , +-7381 , +27447 , +-1749 , +-12823 , +10885 , +-32243 , +17575 , +-25423 , +13639 , +-3473 , +6611 , +-10731 , +-12893 , +12657 , +-4389 , +27889 , +8825 , +-15009 , +11363 , +1345 , +22787 , +-17871 , +-9641 , +-29485 , +15069 , +-897 , +1359 , +1669 , +22695 , +-11527 , +29783 , +-5 , +31001 , +11879 , +-14505 , +-22053 , +-21351 , +2073 , +-27171 , +2687 , +-8873 , +-31011 , +-22911 , +17197 , +13287 , +8837 , +-10573 , +24535 , +10319 , +32205 , +-13541 , +-22201 , +-26709 , +11999 , +109 , +-3611 , +-18883 , +11847 , +21695 , +-11041 , +13831 , +9325 , +-24219 , +24561 , +31203 , +19851 , +32073 , +8083 , +11553 , +11299 , +-16449 , +1457 , +6035 , +-15877 , +-9249 , +8935 , +-31187 , +-30829 , +-21405 , +-21957 , +8221 , +-9695 , +-14349 , +14155 , +-32671 , +6147 , +-2553 , +-12527 , +27615 , +9141 , +-9159 , +-27885 , +-1025 , +-31403 , +31779 , +-24801 , +-27201 , +-7537 , +-26191 , +2431 , +1359 , +1309 , +-24069 , +32181 , +-27095 , +10165 , +10913 , +27057 , +32675 , +-15985 , +-24165 , +13709 , +32273 , +-30639 , +17817 , +32187 , +-4013 , +-8051 , +-299 , +-14391 , +20981 , +29881 , +12397 , +-22129 , +27071 , +10911 , +6721 , +-9487 , +1241 , +12133 , +-7361 , +10767 , +-27053 , +20981 , +-7099 , +-13829 , +-27831 , +25597 , +19317 , +-3075 , +-7301 , +-9883 , +-20469 , +21309 , +15965 , +24139 , +-20803 , +13063 , +-13133 , +-25743 , +9863 , +-6277 , +-6483 , +-7871 , +11789 , +26821 , +18043 , +-3777 , +22895 , +-26405 , +-30879 , +-25091 , +26789 , +11187 , +18779 , +31135 , +-2485 , +-22027 , +-11995 , +19139 , +16139 , +-31177 , +31971 , +-32760 , +-26267 , +-17219 , +-6865 , +23037 , +-18929 , +-2655 , +687 , +923 , +16589 , +-24169 , +12345 , +20801 , +-1595 , +2339 , +24925 , +24097 , +-8353 , +-14771 , +25993 , +-16313 , +-32625 , +-24355 , +-28777 , +-29945 , +4029 , +17679 , +-26131 , +-10249 , +19987 , +-13101 , +7949 , +3687 , +-6315 , +-27781 , +32441 , +-24231 , +22079 , +19445 , +-30855 , +31743 , +-5801 , +-11891 , +-17209 , +-11099 , +73 , +-21735 , +-28261 , +-25033 , +6589 , +-18253 , +28545 , +20531 , +-13903 , +1019 , +-7621 , +15647 , +12363 , +10943 , +-16433 , +12167 , +2365 , +23617 , +-23255 , +-31377 , +-5235 , +24807 , +-24791 , +-32177 , +-11779 , +-23431 , +22593 , +3977 , +-31787 , +-17713 , +-23927 , +-23713 , +-2491 , +22295 , +-18847 , +-31119 , +15931 , +11649 , +-649 , +12207 , +10935 , +-18563 , +-15759 , +-4393 , +8101 , +21103 , +-25347 , +-25241 , +18745 , +-20243 , +-3483 , +-29163 , +-16451 , +5747 , +25265 , +29391 , +-19463 , +21911 , +31285 , +28969 , +15351 , +2251 , +32687 , +7517 , +-10131 , +-625 , +-18721 , +-27715 , +19083 , +18983 , +-4195 , +26797 , +-11691 , +1493 , +-18065 , +-22753 , +28029 , +7059 , +5029 , +-27261 , +11959 , +12107 , +-3597 , +31047 , +17815 , +3469 , +28031 , +4297 , +-12573 , +-25149 , +-1403 , +-1069 , +1389 , +-12557 , +31335 , +-13677 , +-5267 , +30447 , +-32185 , +-5363 , +1113 , +-25583 , +-20959 , +11549 , +14135 , +8561 , +22625 , +5349 , +29055 , +19865 , +-29191 , +-19507 , +8807 , +9161 , +-26879 , +16371 , +9927 , +1957 , +-5179 , +8747 , +15723 , +-23701 , +-4507 , +-19851 , +-25625 , +-30539 , +16611 , +23277 , +-17415 , +-31831 , +4041 , +22867 , +-1703 , +6323 , +10549 , +-10513 , +6161 , +9409 , +14455 , +-28899 , +19293 , +6131 , +-471 , +-17355 , +-11015 , +-15655 , +-9023 , +-31989 , +-11007 , +11819 , +-28237 , +-27417 , +25153 , +29951 , +29439 , +16381 , +-31977 , +6529 , +2385 , +-22945 , +7871 , +-13271 , +24211 , +21371 , +32567 , +7547 , +-9977 , +-6125 , +31633 , +4661 , +-1309 , +5299 , +-7479 , +4621 , +-8605 , +-25943 , +16159 , +10473 , +-14749 , +-29825 , +-30221 , +4753 , +-25737 , +32493 , +-6121 , +2289 , +-21111 , +-2211 , +1705 , +-13113 , +-28189 , +-21291 , +12399 , +-7963 , +30167 , +-2443 , +-19545 , +28635 , +-16951 , +2679 , +-20377 , +-11201 , +18645 , +19609 , +-6289 , +15197 , +12503 , +25373 , +-24187 , +23145 , +24341 , +19007 , +18251 , +-20923 , +-12989 , +7725 , +-15975 , +15791 , +-13523 , +-11387 , +14927 , +22009 , +8391 , +-27073 , +21945 , +14919 , +25795 , +1845 , +31831 , +15681 , +24491 , +4111 , +19779 , +15693 , +-11397 , +-31297 , +-12031 , +-1203 , +32697 , +20861 , +-31521 , +17355 , +-17913 , +22585 , +-10563 , +25273 , +29509 , +-10089 , +10617 , +-9815 , +289 , +30565 , +-1605 , +-12155 , +-31697 , +-19823 , +15181 , +14531 , +17033 , +-3417 , +-30985 , +6941 , +-12581 , +-3385 , +12501 , +2001 , +21511 , +-18669 , +-8399 , +8529 , +-8909 , +-13893 , +-17959 , +-18053 , +-3477 , +-2465 , +-13833 , +-1701 , +25007 , +15387 , +-23959 , +-29871 , +-29551 , +11755 , +-5989 , +-16419 , +4683 , +31159 , +-10789 , +9415 , +11863 , +-12865 , +18741 , +1759 , +-23671 , +-11119 , +-32307 , +-10695 , +-29785 , +32649 , +6573 , +-6953 , +-7301 , +22471 , +22823 , +30703 , +11121 , +3491 , +31401 , +-23653 , +-2895 , +-345 , +-2281 , +-5867 , +-19793 , +-5621 , +29341 , +3949 , +-22199 , +-29787 , +25107 , +11971 , +20319 , +21865 , +197 , +26105 , +-535 , +-165 , +-20773 , +13045 , +17293 , +9741 , +20515 , +-6833 , +-19269 , +-20593 , +-15499 , +9105 , +-28601 , +12015 , +2691 , +-1303 , +4217 , +-467 , +14897 , +29029 , +-16215 , +18097 , +-13451 , +4777 , +-20647 , +-20409 , +25765 , +28455 , +-11055 , +-4457 , +-19627 , +1497 , +-31195 , +-6887 , +28335 , +-28555 , +19687 , +-26223 , +6727 , +10795 , +-1239 , +-21241 , +-24201 , +18645 , +21535 , +-27847 , +25397 , +183 , +8503 , +16541 , +-14741 , +-30029 , +2991 , +-31025 , +-4399 , +-31487 , +4783 , +-10353 , +-21951 , +-6555 , +-2597 , +-22985 , +11925 , +7153 , +27763 , +8119 , +-16391 , +18731 , +-32537 , +28933 , +-10297 , +8921 , +-5903 , +21531 , +-7205 , +23593 , +-19929 , +7023 , +13935 , +7795 , +6941 , +-3097 , +15987 , +-31891 , +-3851 , +-27309 , +-24479 , +-30239 , +18805 , +6507 , +18327 , +31981 , +-3667 , +12605 , +2101 , +17837 , +26879 , +28967 , +-5781 , +-24699 , +-16195 , +-5287 , +-20397 , +-22839 , +14403 , +-12099 , +-15535 , +-17923 , +-4719 , +20607 , +-543 , +9613 , +31323 , +28153 , +-29449 , +-28157 , +-10843 , +1329 , +27603 , +-21315 , +20961 , +-18993 , +-26279 , +811 , +3961 , +-4971 , +-25113 , +-30591 , +-17415 , +-15527 , +31153 , +-16907 , +-2665 , +-4229 , +-27749 , +-2707 , +11091 , +30429 , +-16249 , +-22845 , +20877 , +25435 , +-1221 , +20343 , +17183 , +11463 , +-6997 , +-11033 , +9973 , +4437 , +-23333 , +-7933 , +-19937 , +5287 , +17459 , +12691 , +-24977 , +-8911 , +5463 , +20957 , +11667 , +10301 , +18301 , +-18713 , +4261 , +3167 , +14671 , +-18893 , +-29621 , +-15765 , +-23503 , +20201 , +12617 , +11507 , +14381 , +15775 , +411 , +-10691 , +-16323 , +21125 , +23057 , +-25421 , +26407 , +-32219 , +30815 , +-14875 , +13529 , +-22381 , +-2625 , +-20479 , +23607 , +30509 , +3581 , +-9789 , +29057 , +-31537 , +2843 , +30961 , +8479 , +-1909 , +-21153 , +22357 , +32509 , +-14625 , +-6155 , +11831 , +-31127 , +-1675 , +-13827 , +14413 , +-7587 , +-1709 , +-5079 , +12855 , +-27031 , +21393 , +15059 , +-32391 , +-24585 , +-3939 , +29845 , +-17931 , +10295 , +13797 , +13669 , +14809 , +24169 , +2589 , +-6621 , +5155 , +-27973 , +13285 , +26815 , +399 , +-22117 , +2839 , +-10043 , +-28649 , +32667 , +-2965 , +14455 , +18663 , +21947 , +-24645 , +25199 , +1235 , +-8627 , +-32585 , +6059 , +10067 , +577 , +31261 , +-32217 , +-2053 , +-2295 , +13173 , +1021 , +-11663 , +-17175 , +4413 , +-21773 , +25827 , +-25133 , +18355 , +8347 , +-19195 , +-15171 , +-1 , +28387 , +9089 , +-31369 , +2031 , +28985 , +9721 , +27913 , +1073 , +18963 , +-4235 , +-19835 , +-25335 , +-19179 , +-16541 , +8291 , +-25207 , +-29279 , +3847 , +3673 , +32073 , +25075 , +21883 , +-31825 , +19619 , +27319 , +-26075 , +6679 , +31587 , +-16609 , +-29271 , +-18161 , +29191 , +7557 , +24937 , +-15959 , +30065 , +8305 , +5495 , +-15629 , +-13021 , +14403 , +29969 , +20161 , +-23565 , +16707 , +31127 , +1809 , +-25781 , +3637 , +19461 , +31707 , +-30507 , +-16519 , +-25369 , +-3735 , +22205 , +16031 , +-29995 , +-22727 , +32359 , +-18815 , +-12437 , +-18621 , +5537 , +24535 , +27323 , +9701 , +-6557 , +31313 , +-31411 , +14891 , +-30463 , +-13775 , +-16237 , +-18765 , +-1813 , +29283 , +-21023 , +2809 , +-25641 , +-31983 , +-23577 , +5435 , +13191 , +5309 , +-21851 , +-29493 , +-19971 , +18397 , +-18969 , +-21275 , +26669 , +237 , +-6599 , +14345 , +-30917 , +-18167 , +2153 , +27607 , +27699 , +15111 , +2925 , +-671 , +-20931 , +-23285 , +-23315 , +-18937 , +26459 , +-31065 , +-9167 , +-14133 , +-20581 , +29541 , +-19555 , +30765 , +-15663 , +-7695 , +-22365 , +9347 , +-14127 , +-20575 , +16967 , +23245 , +-18395 , +8341 , +26119 , +-1005 , +19269 , +-19379 , +-21663 , +5427 , +-32687 , +-22845 , +26055 , +32583 , +-25787 , +30211 , +-25329 , +-8081 , +8887 , +17469 , +-21385 , +9527 , +-12537 , +28261 , +-16363 , +2655 , +-7135 , +12101 , +-5933 , +-12479 , +-4695 , +-22759 , +-283 , +-22365 , +21951 , +8103 , +2753 , +3085 , +-12753 , +-6959 , +27799 , +27559 , +1069 , +-30279 , +31305 , +31369 , +-26999 , +-3511 , +-13335 , +-28259 , +-14739 , +-1705 , +-4445 , +19693 , +-9587 , +2875 , +-18877 , +-1663 , +-21273 , +-29465 , +-6873 , +-5195 , +23285 , +26487 , +25269 , +22035 , +-28563 , +-28587 , +-18343 , +-18261 , +25707 , +-6711 , +3319 , +-32541 , +16697 , +14357 , +22247 , +-3621 , +-12677 , +-10485 , +-919 , +-4803 , +21997 , +31779 , +-25949 , +-19299 , +-25957 , +-5859 , +11027 , +15171 , +-25965 , +4871 , +16265 , +8335 , +13095 , +12777 , +-29533 , +-5423 , +8093 , +-29491 , +31423 , +-25959 , +19047 , +23135 , +-2701 , +11925 , +-5917 , +-29177 , +12685 , +12265 , +22921 , +-5767 , +-24189 , +-8445 , +15529 , +10965 , +-12183 , +6391 , +-16479 , +-20681 , +23415 , +-29357 , +-28009 , +25049 , +-15889 , +23679 , +-32595 , +20385 , +17315 , +-18805 , +8895 , +-18623 , +-31261 , +-28021 , +-23403 , +-4663 , +14075 , +5745 , +5277 , +-4159 , +26669 , +-14489 , +13859 , +-2363 , +-10717 , +6813 , +19983 , +-5225 , +-10267 , +32427 , +-7663 , +3257 , +11359 , +30053 , +-7583 , +-24185 , +24135 , +-10699 , +13817 , +4557 , +-2399 , +-12049 , +8517 , +14815 , +13747 , +-14035 , +32611 , +21297 , +-30081 , +-24027 , +17875 , +18803 , +-32585 , +-27901 , +19131 , +-11233 , +23867 , +7099 , +-14961 , +11421 , +8455 , +12905 , +-32167 , +-18219 , +10939 , +16679 , +16225 , +-32185 , +11903 , +3171 , +11641 , +-11873 , +-17265 , +6577 , +2717 , +-14631 , +3617 , +-20685 , +-12479 , +17869 , +20719 , +865 , +26105 , +3915 , +10523 , +-19093 , +26047 , +24245 , +-24135 , +9739 , +18075 , +-7145 , +17343 , +-14111 , +2281 , +29371 , +-29831 , +1611 , +-14583 , +15429 , +29833 , +-14923 , +10653 , +-4025 , +21595 , +14463 , +13879 , +-26529 , +-17635 , +-693 , +28831 , +-30519 , +-27847 , +13271 , +-14721 , +15737 , +14153 , +-26285 , +15775 , +31673 , +-18799 , +17729 , +-9055 , +-28621 , +-3 , +7877 , +-14799 , +409 , +11147 , +-23939 , +-313 , +-28751 , +-26027 , +4317 , +-11051 , +-10509 , +9465 , +-25335 , +25477 , +28831 , +4247 , +-19419 , +10223 , +-6315 , +591 , +-2765 , +8401 , +22577 , +-22225 , +-3735 , +28877 , +6233 , +22191 , +19723 , +-1263 , +14115 , +15791 , +22721 , +-3421 , +13473 , +-28701 , +-17553 , +-11251 , +-15171 , +12755 , +17549 , +-15981 , +-2347 , +15701 , +32511 , +-17931 , +-26167 , +2687 , +7281 , +-24161 , +13475 , +-2271 , +-11993 , +-27037 , +27549 , +-23361 , +-18339 , +-31307 , +10695 , +-6905 , +-9959 , +32093 , +26391 , +3271 , +-7287 , +-20819 , +-7423 , +-6805 , +-16687 , +-25529 , +-21607 , +-2829 , +-143 , +27205 , +-14053 , +21601 , +-8687 , +-14089 , +-6639 , +-13115 , +-14625 , +29215 , +19427 , +29343 , +6499 , +-20315 , +3059 , +30697 , +12511 , +-5427 , +-21197 , +27781 , +19739 , +-22797 , +13885 , +-23243 , +29641 , +705 , +-5141 , +281 , +-7595 , +5353 , +-25485 , +-14941 , +10301 , +12635 , +-12553 , +-14067 , +-32273 , +-30725 , +-20575 , +-23721 , +-29665 , +5601 , +4163 , +7609 , +-6247 , +24835 , +21855 , +-26467 , +-6753 , +-2433 , +-22581 , +-24549 , +-11069 , +9027 , +17093 , +26345 , +1589 , +-8371 , +13967 , +24539 , +9127 , +25441 , +30589 , +-21035 , +-4707 , +24903 , +-28265 , +-23991 , +-1463 , +22131 , +-10065 , +551 , +-29471 , +-3757 , +27893 , +18781 , +7541 , +241 , +-5103 , +-23349 , +-22195 , +-6337 , +9921 , +-9545 , +25533 , +1469 , +-19741 , +-9775 , +-8325 , +7361 , +-19941 , +9887 , +18553 , +5409 , +-23323 , +-8327 , +-14779 , +11383 , +-24019 , +-28923 , +-24879 , +-1075 , +-13465 , +-31451 , +12757 , +20709 , +21799 , +-4483 , +25771 , +20959 , +-965 , +25185 , +-26981 , +-7301 , +16195 , +8013 , +-19013 , +-13869 , +13505 , +-21023 , +-29623 , +31629 , +21951 , +8791 , +-8579 , +8087 , +5341 , +-19329 , +28899 , +-21157 , +-26137 , +-6609 , +-28877 , +-22661 , +31225 , +-4031 , +11179 , +26889 , +-15349 , +-20981 , +12007 , +32057 , +14861 , +-16559 , +4149 , +-1629 , +3713 , +6345 , +20077 , +21235 , +-365 , +-17659 , +-7853 , +-23517 , +8365 , +-14349 , +15201 , +-8141 , +16275 , +-20777 , +-3033 , +-6557 , +6647 , +-22855 , +-19679 , +-3861 , +24215 , +12139 , +29461 , +22059 , +-17201 , +-12047 , +-18979 , +5235 , +-7755 , +-11893 , +-16179 , +8233 , +-18001 , +6685 , +31109 , +-4977 , +-12663 , +303 , +-1209 , +9969 , +6677 , +13411 , +31955 , +7271 , +9529 , +30831 , +-24897 , +-15871 , +-13427 , +30611 , +-17843 , +-10355 , +31601 , +22161 , +18623 , +7361 , +19109 , +18469 , +-1221 , +4347 , +-18587 , +-10497 , +-25837 , +13691 , +28153 , +7737 , +19119 , +18963 , +-5421 , +-22449 , +16085 , +31847 , +20773 , +11415 , +-30585 , +415 , +19967 , +-7367 , +1887 , +4771 , +24535 , +-22611 , +7267 , +-15663 , +23221 , +-24155 , +13661 , +-22219 , +-32579 , +-21355 , +-14161 , +-11197 , +1867 , +13725 , +-9799 , +9 , +24719 , +-14323 , +-25185 , +-30989 , +8607 , +83 , +22701 , +1271 , +-8945 , +7549 , +3115 , +9553 , +-13805 , +-5849 , +3253 , +-27973 , +-28665 , +11767 , +6423 , +-32215 , +3733 , +29847 , +2459 , +-12293 , +31301 , +16175 , +-20499 , +10167 , +-23143 , +31571 , +-149 , +11845 , +-12637 , +25223 , +5633 , +9887 , +-14051 , +-32465 , +15743 , +2319 , +-8957 , +7175 , +32111 , +-31513 , +12709 , +-21469 , +-10895 , +-6985 , +7499 , +-22177 , +-18411 , +19715 , +12607 , +23383 , +-8659 , +19841 , +23151 , +-5915 , +2723 , +15565 , +-4481 , +24085 , +-10531 , +22173 , +-667 , +-8037 , +8073 , +5253 , +-16513 , +-13617 , +10747 , +-18145 , +30767 , +-6875 , +6659 , +-31275 , +-23319 , +30243 , +-12221 , +-27897 , +-12075 , +24791 , +-14063 , +-15665 , +-6939 , +2517 , +5055 , +-14791 , +19561 , +15015 , +-1407 , +-21265 , +-14805 , +-17457 , +29373 , +-2175 , +14851 , +-8907 , +-4635 , +-23531 , +27381 , +-23259 , +-23855 , +11673 , +-8765 , +-8761 , +-6249 , +-2679 , +-13303 , +-18155 , +-19491 , +4123 , +31699 , +17231 , +-7239 , +-5377 , +-11339 , +23551 , +21253 , +-14705 , +-31899 , +28005 , +26935 , +31121 , +-26419 , +-25997 , +11705 , +30563 , +-9811 , +-25785 , +31941 , +-28481 , +-18003 , +33 , +29873 , +26347 , +17649 , +4829 , +-19493 , +2419 , +-10437 , +3815 , +32491 , +-18843 , +-2185 , +-6217 , +26557 , +13569 , +12257 , +21961 , +-29523 , +-15625 , +14993 , +25101 , +2165 , +3105 , +23191 , +10223 , +-21883 , +9393 , +14743 , +1473 , +-28713 , +-525 , +8665 , +-3149 , +-19379 , +19845 , +-4887 , +14677 , +5247 , +24325 , +32427 , +14731 , +30751 , +-14253 , +9457 , +-29441 , +31949 , +30789 , +-19559 , +8991 , +-1689 , +6113 , +-19169 , +-24173 , +20971 , +13839 , +-30791 , +-17865 , +-11313 , +13787 , +-16659 , +-20591 , +-19761 , +30499 , +-24153 , +-16439 , +-16815 , +-20007 , +7385 , +-20957 , +26419 , +-1107 , +649 , +8945 , +11819 , +28757 , +-4753 , +6677 , +4759 , +-3011 , +-24309 , +6131 , +6625 , +2491 , +15933 , +23779 , +-30903 , +12493 , +9313 , +-12489 , +-9145 , +-13997 , +-10529 , +-11349 , +14683 , +-4161 , +-16567 , +-13225 , +14191 , +19539 , +9203 , +30259 , +-11865 , +19675 , +11015 , +-8951 , +30651 , +-16163 , +16931 , +7661 , +-7985 , +20567 , +-15767 , +-20429 , +-18737 , +-15115 , +10525 , +27887 , +-19903 , +-25143 , +-17215 , +3299 , +16029 , +-6779 , +-2401 , +21755 , +16171 , +-15565 , +-30481 , +-22199 , +3161 , +-17047 , +22885 , +15991 , +16779 , +10241 , +18517 , +-24127 , +29569 , +-19367 , +7227 , +-12429 , +26405 , +-25597 , +27105 , +-28717 , +-7969 , +24063 , +-12049 , +21159 , +-23425 , +-31117 , +25863 , +16679 , +-17023 , +30951 , +-25765 , +-16781 , +-22545 , +-19213 , +-27449 , +3729 , +29115 , +-29307 , +7265 , +23517 , +27793 , +-13683 , +12961 , +-11507 , +-30673 , +11577 , +31977 , +3481 , +-4795 , +20147 , +29093 , +-32065 , +-3903 , +-11959 , +-26399 , +14075 , +-2123 , +23613 , +-18075 , +25075 , +25507 , +23011 , +19013 , +17155 , +8023 , +-3987 , +257 , +-9187 , +-7095 , +11547 , +-11241 , +-13479 , +-12187 , +-9745 , +18973 , +-1319 , +25715 , +-2577 , +27995 , +24399 , +-32031 , +18387 , +15331 , +31977 , +-30937 , +837 , +-5083 , +-5415 , +3477 , +-1899 , +-8693 , +-29381 , +-31821 , +18157 , +-28531 , +-16999 , +6421 , +2323 , +29647 , +6625 , +10417 , +-2919 , +-4171 , +12759 , +-19781 , +25497 , +30455 , +-13545 , +-261 , +-16151 , +-317 , +-3197 , +-87 , +-12583 , +-19763 , +-26047 , +-29507 , +-16285 , +15849 , +-6349 , +4043 , +-25365 , +32551 , +2283 , +-18335 , +-6541 , +865 , +-20183 , +-12075 , +-1453 , +7009 , +-2103 , +19361 , +9327 , +-6549 , +-9141 , +8511 , +-8967 , +10593 , +7607 , +-27013 , +10391 , +19023 , +-24281 , +845 , +-27857 , +18577 , +7863 , +12853 , +-17137 , +2399 , +19705 , +-4085 , +-3409 , +-12055 , +17143 , +-7073 , +-14619 , +16371 , +18591 , +19017 , +10141 , +-21019 , +-12855 , +-24115 , +-6897 , +14187 , +-16479 , +-3675 , +9087 , +22921 , +-2903 , +-20063 , +-20629 , +28977 , +-6355 , +-2689 , +-21431 , +-2207 , +30267 , +-4033 , +-27203 , +-11849 , +-6885 , +26627 , +2899 , +-28795 , +-11957 , +12889 , +24245 , +-5263 , +22253 , +20771 , +23649 , +27021 , +7117 , +-14365 , +18151 , +27109 , +30921 , +-15975 , +31899 , +-30815 , +31195 , +7965 , +-16429 , +-25447 , +-4991 , +1515 , +-26219 , +16749 , +13499 , +-30835 , +-12581 , +8735 , +8329 , +-1695 , +24645 , +-219 , +29145 , +5377 , +3153 , +-19699 , +22275 , +30991 , +-13295 , +5255 , +-30267 , +-23917 , +17001 , +3335 , +19639 , +-2353 , +-27201 , +-17447 , +-193 , +-2657 , +-21441 , +-587 , +-32750 , +11333 , +17027 , +12515 , +5673 , +203 , +-11045 , +-29241 , +6193 , +-4647 , +-11529 , +-5121 , +2703 , +18185 , +5673 , +19447 , +27601 , +7617 , +4635 , +-763 , +-6235 , +24205 , +-18431 , +-18429 , +10327 , +-16651 , +-31655 , +-31137 , +-315 , +-27689 , +-20705 , +-12873 , +6359 , +10297 , +-2427 , +22517 , +-395 , +-21331 , +-981 , +-20511 , +-29433 , +22297 , +-21289 , +-21953 , +-22175 , +-13539 , +-21841 , +29533 , +24645 , +25317 , +12783 , +-1737 , +11609 , +28801 , +28707 , +2569 , +-24419 , +4027 , +-14885 , +-157 , +6749 , +-24459 , +-5403 , +19917 , +-10821 , +-32389 , +27913 , +-12079 , +-1649 , +9183 , +-32453 , +11165 , +-6153 , +3793 , +-24747 , +5653 , +-31685 , +-5135 , +-8111 , +-4497 , +-22701 , +13359 , +-26881 , +26443 , +31445 , +-27361 , +6975 , +-21947 , +-3467 , +-22831 , +16307 , +-14567 , +7159 , +2601 , +27135 , +-14551 , +32173 , +-30791 , +-14977 , +15785 , +15207 , +18197 , +-30597 , +-21463 , +14835 , +-18767 , +-15391 , +-27725 , +-1777 , +15409 , +-19073 , +-30113 , +23527 , +17741 , +5305 , +11635 , +6149 , +-12009 , +20929 , +18413 , +721 , +2535 , +16209 , +1451 , +-2685 , +1955 , +7903 , +-29959 , +32671 , +21153 , +-30887 , +-14163 , +8171 , +16125 , +7773 , +-6985 , +15339 , +-18327 , +-25619 , +3913 , +-29235 , +-26991 , +4267 , +7261 , +16627 , +4589 , +-6515 , +-17955 , +29915 , +28953 , +-27619 , +-26067 , +24223 , +-31059 , +31269 , +27471 , +-16145 , +6035 , +-7181 , +-3473 , +-3455 , +-15897 , +-24059 , +9225 , +11023 , +31813 , +14159 , +-28555 , +20173 , +17833 , +4327 , +-763 , +-3995 , +7615 , +-16317 , +-32361 , +-16025 , +-8765 , +-20499 , +699 , +10565 , +2519 , +19137 , +24631 , +15059 , +13011 , +3489 , +12337 , +-16339 , +169 , +31659 , +24251 , +-27327 , +32057 , +27891 , +-30221 , +2239 , +-18527 , +-20541 , +29333 , +31629 , +22561 , +29759 , +22807 , +-2363 , +15467 , +31415 , +-24769 , +-4047 , +-19331 , +31815 , +-31173 , +-2761 , +30717 , +-14817 , +24889 , +29785 , +-5111 , +32563 , +5249 , +23853 , +-11881 , +-28553 , +14603 , +-12589 , +-3001 , +-22635 , +-17257 , +-29459 , +-3649 , +19493 , +22087 , +29463 , +-20095 , +32615 , +-22605 , +-24863 , +-23227 , +-8583 , +25221 , +-30651 , +27083 , +-16629 , +19087 , +-16227 , +-8131 , +16037 , +27749 , +-28637 , +22527 , +-17333 , +24689 , +10719 , +-7927 , +-19255 , +-3439 , +-20957 , +24257 , +31065 , +1575 , +-19577 , +29519 , +-18199 , +3769 , +-29091 , +-9351 , +21453 , +-2813 , +3749 , +21245 , +29173 , +-16235 , +-4977 , +-26275 , +21419 , +-8731 , +-25751 , +-20663 , +-11069 , +22761 , +-17631 , +-7065 , +6747 , +-7119 , +-8143 , +-12877 , +25359 , +1147 , +-5597 , +-17321 , +29103 , +14545 , +-24447 , +-13055 , +-30081 , +30491 , +-12721 , +10171 , +31457 , +-10947 , +-27645 , +-30653 , +-23647 , +-18779 , +10241 , +-22813 , +32149 , +22127 , +-17013 , +-26163 , +-28439 , +1527 , +-13757 , +-14611 , +22225 , +-2065 , +25111 , +32321 , +-583 , +-4101 , +-7741 , +-11079 , +-30711 , +-20793 , +-24633 , +-10363 , +15699 , +29345 , +-9253 , +-20493 , +-6635 , +25741 , +-23317 , +-12345 , +-13849 , +18913 , +-4725 , +-16883 , +-6087 , +21085 , +-30989 , +-25475 , +25481 , +23229 , +14967 , +-701 , +-26851 , +31709 , +-18051 , +8551 , +-12487 , +15935 , +-25613 , +14231 , +7125 , +18999 , +9549 , +-19573 , +13785 , +-5003 , +2037 , +21973 , +-4393 , +18211 , +-8373 , +-967 , +9019 , +-30853 , +-26597 , +-11635 , +-22777 , +-2083 , +32657 , +-1017 , +9489 , +18029 , +12465 , +19739 , +26801 , +-10199 , +6229 , +11731 , +2557 , +-32647 , +-14429 , +15521 , +-2941 , +30035 , +-13059 , +-13885 , +-16257 , +-10291 , +19337 , +-15603 , +22167 , +-22223 , +2327 , +10313 , +-10741 , +-31583 , +10917 , +-24561 , +13681 , +-2783 , +22355 , +17689 , +-27149 , +-16329 , +31197 , +17441 , +-16133 , +-763 , +-10097 , +25139 , +-14219 , +20439 , +-17471 , +905 , +16771 , +8779 , +23245 , +-13601 , +4535 , +12245 , +18313 , +26959 , +18119 , +16103 , +4155 , +-18777 , +-3897 , +24197 , +20501 , +-21947 , +30437 , +-32681 , +-6613 , +19559 , +24219 , +-14519 , +-29971 , +14345 , +-661 , +25247 , +31771 , +-15045 , +3345 , +19851 , +30527 , +29691 , +-26041 , +-13491 , +-17749 , +-20597 , +17903 , +-2115 , +17637 , +-32185 , +20693 , +17523 , +2729 , +20997 , +27105 , +14933 , +23389 , +15585 , +-18731 , +22449 , +11273 , +11935 , +3965 , +25301 , +-32559 , +18049 , +-7311 , +2345 , +-21273 , +-23143 , +-15805 , +8901 , +-24307 , +15787 , +-451 , +29321 , +133 , +-18311 , +24983 , +15031 , +13453 , +4009 , +28209 , +32263 , +13905 , +-4849 , +8135 , +17731 , +18285 , +27535 , +-22353 , +-16035 , +20701 , +20593 , +8457 , +-24055 , +8311 , +21815 , +-24449 , +30931 , +15589 , +-26115 , +-17799 , +-32589 , +-30693 , +-10171 , +-11051 , +-24015 , +26703 , +28251 , +20769 , +3057 , +-20625 , +-9437 , +75 , +14289 , +-1757 , +-15753 , +-10007 , +-19331 , +-18635 , +4611 , +26595 , +-29811 , +-23401 , +24205 , +-3155 , +-25577 , +-10541 , +4575 , +-13821 , +-15925 , +9733 , +-32489 , +-20443 , +8327 , +9049 , +-31875 , +-4735 , +27765 , +22005 , +-24099 , +-5895 , +-31073 , +-2433 , +30309 , +-12139 , +17923 , +-7923 , +21743 , +17337 , +-15051 , +-2653 , +-11287 , +30689 , +3185 , +-24795 , +19875 , +-12329 , +28717 , +-18223 , +-3545 , +23919 , +31809 , +-30153 , +-32361 , +17845 , +-15505 , +4533 , +18175 , +32687 , +27523 , +21863 , +27571 , +-6763 , +-12821 , +-3415 , +15133 , +4221 , +1227 , +-23549 , +28453 , +-2395 , +-17253 , +-2645 , +7413 , +-15333 , +8759 , +-8071 , +23139 , +-6659 , +17789 , +-31901 , +13247 , +-16335 , +-14233 , +-19605 , +2605 , +1433 , +12957 , +-26079 , +-3457 , +10961 , +-15987 , +6809 , +11401 , +-5281 , +3339 , +13535 , +19199 , +22901 , +22619 , +8177 , +9159 , +28701 , +-6179 , +21049 , +8405 , +-24577 , +13071 , +12419 , +2429 , +20105 , +19255 , +-25735 , +-9129 , +-16455 , +20077 , +5009 , +-11895 , +25153 , +16193 , +-21619 , +7595 , +-2477 , +6339 , +-32391 , +-29421 , +-31029 , +30505 , +-2545 , +-28743 , +-21271 , +-21277 , +23241 , +-12919 , +5779 , +-25555 , +20031 , +-9417 , +-14595 , +11565 , +32563 , +10145 , +2543 , +-18295 , +3587 , +-18017 , +-28297 , +16003 , +17559 , +-10661 , +-18913 , +-15737 , +-8983 , +10289 , +20905 , +-23725 , +-29195 , +32255 , +11335 , +18299 , +5933 , +-17669 , +29773 , +-2415 , +-32135 , +3865 , +14453 , +14009 , +-11091 , +4047 , +23687 , +-31045 , +-7047 , +-13951 , +159 , +-13147 , +-28689 , +24903 , +-11555 , +20695 , +2159 , +24405 , +17313 , +-25179 , +27941 , +14789 , +5187 , +7021 , +27647 , +14333 , +14403 , +-16083 , +8485 , +18039 , +-32495 , +-20073 , +-4875 , +-11481 , +3123 , +7347 , +30833 , +19019 , +-5109 , +15855 , +-24507 , +19401 , +773 , +-12615 , +32303 , +12543 , +-30375 , +-14951 , +18697 , +-1245 , +13623 , +-17977 , +17199 , +16917 , +32141 , +-15549 , +28551 , +15291 , +-4303 , +12143 , +17643 , +29657 , +3235 , +-7645 , +6185 , +19553 , +-20417 , +-17591 , +29823 , +-8613 , +26873 , +-9997 , +6789 , +21291 , +-13931 , +3575 , +-8781 , +20087 , +8795 , +25851 , +6229 , +-32647 , +-25261 , +2079 , +-4613 , +-1839 , +13563 , +25861 , +5245 , +20973 , +32127 , +-6797 , +23403 , +19667 , +-18317 , +5223 , +-22009 , +-2693 , +11013 , +-30803 , +-21565 , +-6225 , +11969 , +26109 , +-7381 , +-13223 , +-2883 , +-7795 , +23403 , +-22687 , +29525 , +32557 , +-20415 , +3587 , +30307 , +-32293 , +-23435 , +-8791 , +18939 , +21217 , +-305 , +-29887 , +-2147 , +15977 , +-6763 , +-23787 , +-29199 , +23697 , +28799 , +-28381 , +27387 , +-241 , +-22225 , +18935 , +213 , +31545 , +-19929 , +-5121 , +3311 , +-22355 , +19527 , +-3735 , +-17995 , +-5027 , +29377 , +2677 , +-23849 , +10285 , +17807 , +14413 , +13311 , +26377 , +-1423 , +16487 , +23037 , +-25217 , +3165 , +4177 , +-371 , +22227 , +24961 , +10761 , +18059 , +-22883 , +-24653 , +-20253 , +2725 , +14041 , +26473 , +11985 , +-32105 , +-13691 , +-21193 , +-21951 , +-25877 , +3259 , +-5695 , +9339 , +-4831 , +1091 , +22585 , +6255 , +-11659 , +939 , +-1201 , +4625 , +-30451 , +28135 , +-24399 , +-2509 , +-7239 , +10077 , +-25859 , +4831 , +31785 , +2951 , +27197 , +-28637 , +-8291 , +16139 , +2783 , +22909 , +-20949 , +-18873 , +9001 , +6043 , +9321 , +-14213 , +-14541 , +21193 , +1967 , +10063 , +2913 , +21947 , +27853 , +4857 , +7515 , +-5909 , +20797 , +8911 , +7039 , +32367 , +32485 , +31325 , +25313 , +-6575 , +-19901 , +-15617 , +-29759 , +9065 , +31537 , +-15873 , +-13187 , +30897 , +-12267 , +-7389 , +-1265 , +18211 , +-13413 , +-28727 , +-6905 , +-11251 , +-29455 , +-21887 , +13819 , +-28701 , +-19849 , +1827 , +-23421 , +-2649 , +26367 , +14185 , +-25159 , +-25935 , +31101 , +-31741 , +10017 , +-30959 , +30537 , +27189 , +12075 , +28257 , +16591 , +30185 , +1071 , +-7903 , +4297 , +-12217 , +10713 , +3725 , +28151 , +23253 , +17707 , +12021 , +-167 , +-20729 , +22259 , +11929 , +-17691 , +-9641 , +-837 , +-20235 , +26305 , +12003 , +-4017 , +1197 , +-6923 , +131 , +32169 , +8143 , +16813 , +-22951 , +10093 , +15551 , +-1049 , +-26381 , +12775 , +12155 , +-32587 , +1253 , +19575 , +2951 , +20711 , +-22063 , +4499 , +12853 , +-13995 , +24081 , +-27333 , +24969 , +1413 , +3781 , +-17937 , +-9337 , +-11021 , +-27537 , +-31695 , +15889 , +15035 , +13319 , +9321 , +9021 , +28637 , +9367 , +-4233 , +8751 , +-8213 , +-3757 , +-619 , +18543 , +6217 , +4139 , +-22567 , +-23617 , +8671 , +-31509 , +-25557 , +-2949 , +15701 , +-5935 , +-16445 , +8293 , +31177 , +-20831 , +-26605 , +32265 , +7685 , +-1219 , +29261 , +-28533 , +23617 , +-5435 , +341 , +19463 , +18505 , +-26075 , +-21959 , +31331 , +-30647 , +-13003 , +14119 , +22701 , +-18441 , +-30389 , +10477 , +1257 , +-2483 , +31831 , +24293 , +-11145 , +-27191 , +-30601 , +19833 , +10975 , +26397 , +19477 , +31507 , +-5841 , +-27031 , +-389 , +31637 , +3535 , +-27915 , +30951 , +8795 , +-25375 , +-1693 , +-15313 , +8865 , +26893 , +-1933 , +713 , +-10607 , +-11035 , +10285 , +3955 , +25765 , +9395 , +19363 , +-22465 , +-1103 , +30937 , +-2781 , +32305 , +23889 , +2213 , +-31499 , +343 , +28385 , +-19035 , +31373 , +16731 , +2299 , +-28789 , +-28601 , +-17757 , +-17047 , +24695 , +-26215 , +26597 , +-13405 , +-9765 , +-25643 , +-4031 , +-1089 , +31175 , +6491 , +18901 , +-26639 , +-16179 , +1869 , +-22313 , +15487 , +-12207 , +26065 , +4913 , +-18889 , +2405 , +-3391 , +28819 , +-22677 , +-15329 , +-4381 , +28427 , +11113 , +-18577 , +28071 , +5157 , +12401 , +10621 , +10075 , +21115 , +-16341 , +-32645 , +17891 , +31693 , +-4445 , +19459 , +9203 , +-6239 , +-22591 , +24295 , +30401 , +-22961 , +4925 , +4495 , +-9659 , +-26457 , +-14563 , +17619 , +14317 , +-15367 , +-32603 , +15691 , +-39 , +15037 , +-25643 , +-4309 , +-21369 , +29085 , +355 , +-11615 , +-30437 , +22811 , +-15573 , +-10079 , +12813 , +5019 , +7981 , +-26551 , +-14237 , +-24571 , +8453 , +19633 , +20329 , +20695 , +-26145 , +-17595 , +11501 , +26561 , +-22797 , +-25955 , +17389 , +-21061 , +32379 , +-28201 , +-24097 , +24479 , +-17619 , +26735 , +13909 , +18239 , +-8657 , +32401 , +-29369 , +22779 , +16275 , +9723 , +959 , +-21027 , +9549 , +-3253 , +28443 , +12849 , +14507 , +-24613 , +-20807 , +-8037 , +4689 , +-27617 , +8249 , +-7761 , +5289 , +-19853 , +28209 , +26631 , +19679 , +31351 , +-20123 , +-24349 , +-28065 , +7403 , +23681 , +-28363 , +-25405 , +-26623 , +-5553 , +14149 , +18513 , +29753 , +-14739 , +-14143 , +-16143 , +14773 , +26763 , +25945 , +-13401 , +13845 , +6687 , +5585 , +-6523 , +-21809 , +24217 , +28579 , +30509 , +-1019 , +30245 , +-19183 , +-16447 , +-2087 , +-3363 , +-13897 , +-11683 , +-12721 , +-10115 , +-11339 , +15123 , +-11873 , +16037 , +-7889 , +-26535 , +-26869 , +-4729 , +27257 , +-9715 , +-28615 , +-4827 , +2215 , +24293 , +-19183 , +32523 , +14501 , +-22421 , +22023 , +31359 , +-32051 , +-8847 , +-20733 , +-31939 , +-8445 , +-11503 , +21165 , +4789 , +-21171 , +-11241 , +1613 , +-13385 , +6889 , +-8437 , +9755 , +4277 , +19429 , +-28009 , +10785 , +21625 , +8501 , +-32627 , +25481 , +7511 , +-3247 , +8023 , +-30085 , +13039 , +6473 , +4593 , +13427 , +-4519 , +-27557 , +-411 , +-13539 , +9447 , +-18415 , +-21827 , +7075 , +-23203 , +9941 , +-26499 , +5777 , +-16481 , +-1273 , +-10595 , +-10203 , +-12555 , +29847 , +16893 , +-28373 , +16055 , +803 , +-5021 , +26705 , +403 , +1155 , +-7701 , +-5115 , +-3271 , +4075 , +1291 , +11463 , +7319 , +9599 , +14585 , +6147 , +21141 , +-26005 , +-27975 , +11115 , +10055 , +6525 , +-14209 , +6349 , +-23129 , +-28613 , +-26695 , +29293 , +-12337 , +24695 , +22907 , +-2087 , +22447 , +-20877 , +32125 , +-25787 , +-30137 , +9069 , +9109 , +-10399 , +-6823 , +-837 , +-29787 , +28079 , +20395 , +-16537 , +-27619 , +9573 , +27573 , +26689 , +-271 , +-23883 , +-799 , +28791 , +-19189 , +-4429 , +-10435 , +32437 , +-16307 , +-14429 , +20919 , +7349 , +13311 , +20955 , +-19757 , +18775 , +-17457 , +16659 , +-28701 , +16193 , +2369 , +4667 , +-26945 , +18413 , +-10319 , +28127 , +-17917 , +-3259 , +-16703 , +19187 , +14263 , +-29759 , +-29865 , +-5583 , +29339 , +7921 , +22293 , +16879 , +5585 , +-3417 , +5709 , +-3463 , +31515 , +-16769 , +-11139 , +23267 , +-13423 , +-32257 , +22341 , +-6551 , +-11561 , +20271 , +24545 , +10823 , +-803 , +-7763 , +17183 , +-5115 , +30223 , +23113 , +4051 , +-22433 , +-6645 , +-2277 , +-1061 , +-19823 , +-17177 , +8221 , +20361 , +-31691 , +-29995 , +-24511 , +-30811 , +21915 , +23147 , +25351 , +-6687 , +-26979 , +-31399 , +-29031 , +10195 , +24571 , +-1131 , +21093 , +-25499 , +30001 , +29987 , +16939 , +20445 , +-4399 , +-31169 , +-27231 , +-31163 , +9557 , +3619 , +9345 , +15467 , +-2943 , +-1999 , +30507 , +-6311 , +-4301 , +-14411 , +-15439 , +10823 , +-25669 , +-6631 , +12155 , +-17635 , +20667 , +11163 , +11607 , +11621 , +-13705 , +-25973 , +20501 , +-9283 , +4269 , +-15107 , +27033 , +-22561 , +-15117 , +-11003 , +20093 , +-14073 , +29063 , +-20627 , +5667 , +24827 , +-3917 , +10479 , +12105 , +3955 , +-31593 , +-14873 , +8489 , +15395 , +-18549 , +-877 , +20749 , +20257 , +-25361 , +29129 , +-23447 , +-28693 , +-30067 , +10281 , +22381 , +-7463 , +-7575 , +6623 , +-8155 , +7441 , +1305 , +13519 , +13839 , +9993 , +1191 , +12635 , +22063 , +-23177 , +12249 , +15243 , +23463 , +24779 , +3605 , +-6443 , +1239 , +9001 , +-7241 , +25673 , +-789 , +17629 , +22245 , +29521 , +-15875 , +-24743 , +19693 , +1249 , +32671 , +7847 , +-26605 , +2359 , +-18941 , +-22171 , +-29193 , +24591 , +1415 , +-26821 , +7777 , +25433 , +-2345 , +28113 , +-32097 , +1145 , +6007 , +7245 , +7515 , +-3085 , +17133 , +27975 , +-23821 , +-13395 , +28743 , +-6337 , +8785 , +-19549 , +-9149 , +-11363 , +1607 , +31009 , +-6183 , +-23525 , +-22689 , +-28553 , +-31907 , +28363 , +-31173 , +-1741 , +32275 , +-18293 , +-14743 , +31963 , +-28087 , +17913 , +441 , +16423 , +-31255 , +10987 , +3097 , +7855 , +14233 , +-12177 , +-16405 , +-14035 , +-4015 , +10555 , +27361 , +7729 , +-11923 , +-13147 , +-3253 , +-19111 , +-18611 , +12321 , +19963 , +5387 , +26727 , +-18637 , +23703 , +-30037 , +26853 , +-11797 , +-13203 , +7505 , +19127 , +-7715 , +3539 , +-27897 , +-11733 , +7573 , +-1025 , +121 , +-14579 , +10899 , +19795 , +-9415 , +-13769 , +-23107 , +25667 , +1641 , +1963 , +21091 , +-26455 , +-11781 , +7467 , +10153 , +-28265 , +25703 , +3409 , +-2933 , +-14409 , +-31001 , +-26835 , +-11699 , +-14309 , +19495 , +-13745 , +7537 , +20385 , +-30331 , +12143 , +11579 , +-10563 , +-25917 , +23929 , +-32355 , +-23081 , +26691 , +21291 , +-24649 , +2603 , +10171 , +27947 , +21703 , +-15599 , +-12427 , +20641 , +-26713 , +16355 , +-19461 , +-23989 , +-16185 , +-14771 , +18521 , +-7655 , +20635 , +6439 , +30929 , +17219 , +-863 , +-18479 , +-26603 , +-10013 , +15053 , +19971 , +22267 , +-4341 , +899 , +27691 , +-16711 , +-6053 , +537 , +8263 , +-23143 , +30751 , +-5185 , +-30923 , +-27081 , +-28449 , +13577 , +-4465 , +-24267 , +-8319 , +-8749 , +-24823 , +4463 , +10969 , +-29749 , +-6337 , +31423 , +28611 , +-21665 , +32531 , +6951 , +4537 , +-12487 , +-9343 , +1683 , +-2059 , +1587 , +-29955 , +5387 , +-4359 , +24529 , +12871 , +2929 , +9909 , +22335 , +16833 , +-2381 , +9495 , +23741 , +-1205 , +12677 , +1321 , +13729 , +-8035 , +3225 , +23199 , +27339 , +8723 , +-28323 , +-28163 , +32155 , +9751 , +22311 , +9505 , +7025 , +-16153 , +-7433 , +31845 , +1947 , +13565 , +-30293 , +-11213 , +-3117 , +-27685 , +19635 , +-225 , +-205 , +-26777 , +-22187 , +23673 , +5045 , +-29751 , +-11685 , +-9361 , +-9695 , +25013 , +19529 , +25243 , +31881 , +-32429 , +25631 , +29729 , +-4283 , +30091 , +30857 , +26185 , +-1947 , +2021 , +-29285 , +2189 , +-21075 , +-6949 , +8965 , +3387 , +-24309 , +24755 , +-15151 , +3979 , +29581 , +29913 , +20115 , +-29131 , +1761 , +-29259 , +22825 , +-19835 , +1345 , +16645 , +-13587 , +15355 , +-2057 , +-31569 , +627 , +26723 , +-23475 , +32291 , +-27715 , +12385 , +-6395 , +-32211 , +4079 , +-20325 , +-14759 , +23879 , +-12401 , +5953 , +-3477 , +31871 , +14137 , +-4565 , +27709 , +3779 , +28375 , +6519 , +-29903 , +-18751 , +859 , +25241 , +6389 , +-6855 , +27381 , +-6159 , +-17403 , +29655 , +-7221 , +18669 , +26785 , +-26481 , +-23249 , +-6499 , +4161 , +-13973 , +-9377 , +4289 , +18319 , +-22287 , +26035 , +30579 , +6883 , +-27921 , +-12453 , +-18129 , +-14029 , +-7719 , +31381 , +25973 , +-25197 , +-31585 , +30311 , +19419 , +-24791 , +-763 , +-2349 , +28587 , +20387 , +24187 , +-6251 , +30709 , +12339 , +25979 , +-28333 , +-3033 , +17671 , +16209 , +-13985 , +19759 , +20287 , +6793 , +-23579 , +-17663 , +-2717 , +6067 , +8359 , +5829 , +-28065 , +-19767 , +-13765 , +-7845 , +-7429 , +15611 , +-16457 , +22143 , +18895 , +32533 , +8437 , +-7077 , +-7745 , +7245 , +21825 , +-8281 , +5875 , +-12903 , +9369 , +-13259 , +-439 , +3473 , +7005 , +4627 , +9047 , +19647 , +12435 , +30495 , +1241 , +18045 , +9871 , +13599 , +-2129 , +-29119 , +-25031 , +1115 , +-22443 , +-4727 , +21695 , +-3407 , +-3369 , +-21987 , +-31797 , +24369 , +18765 , +19705 , +-9151 , +-3533 , +24785 , +409 , +4973 , +-5645 , +23801 , +9689 , +31435 , +-27747 , +12745 , +8773 , +-26067 , +18679 , +29751 , +8953 , +17537 , +-13717 , +20757 , +-14091 , +7937 , +19875 , +-7533 , +27637 , +4845 , +6305 , +-25553 , +1227 , +-24121 , +347 , +1337 , +22577 , +-27647 , +-22069 , +31163 , +31275 , +-1469 , +-12143 , +10753 , +16855 , +-1769 , +-29185 , +4229 , +-14905 , +22309 , +-10817 , +5741 , +30937 , +17903 , +5339 , +7809 , +-109 , +23809 , +17507 , +11941 , +22003 , +16307 , +18561 , +28619 , +24015 , +-6825 , +-3063 , +15477 , +28071 , +-1035 , +-30561 , +-2651 , +-2047 , +23945 , +2881 , +-10665 , +-7361 , +4017 , +17769 , +32123 , +-22025 , +-14871 , +-13661 , +26219 , +-9265 , +24133 , +-9571 , +2019 , +5835 , +20651 , +30671 , +-11911 , +4401 , +-30593 , +-30081 , +-16489 , +-13351 , +-24341 , +26733 , +-16911 , +-31481 , +-1139 , +-26403 , +-28549 , +-31801 , +-22095 , +11569 , +31465 , +21439 , +-24567 , +-31221 , +24219 , +-30329 , +11497 , +-9005 , +-30943 , +-22649 , +10489 , +27107 , +-8917 , +15181 , +-9621 , +32529 , +-18429 , +-13473 , +705 , +28367 , +1413 , +-21095 , +3827 , +-26697 , +155 , +24069 , +-7625 , +27831 , +11823 , +28209 , +13097 , +-11883 , +-10075 , +-23291 , +-3183 , +-23535 , +-15915 , +26403 , +-17769 , +-13951 , +17279 , +-75 , +-22155 , +-26403 , +-27065 , +-7735 , +-15691 , +-1697 , +30511 , +31275 , +11241 , +3483 , +-7291 , +-22081 , +20961 , +-15593 , +9063 , +-32691 , +26467 , +7771 , +-9551 , +20459 , +13921 , +-25705 , +22653 , +-20283 , +-17481 , +31665 , +-8937 , +-29313 , +-31391 , +21981 , +3699 , +-12281 , +19245 , +-14919 , +21289 , +-14609 , +-17927 , +-29211 , +19439 , +-9399 , +-5783 , +1815 , +9095 , +-20741 , +29731 , +13241 , +-4799 , +15251 , +-21887 , +20475 , +-13839 , +2473 , +-10295 , +13933 , +2913 , +6317 , +4589 , +28951 , +3667 , +-28855 , +-29769 , +20245 , +751 , +-13269 , +-7793 , +-10585 , +23491 , +-4241 , +22691 , +-5165 , +6963 , +29799 , +-30545 , +-31885 , +-18567 , +-3075 , +26667 , +15059 , +-13029 , +-22651 , +13059 , +11205 , +22493 , +-15335 , +9171 , +21825 , +-21951 , +18029 , +30625 , +28787 , +-9351 , +18223 , +-19445 , +-30119 , +-7197 , +28629 , +-22517 , +14811 , +8191 , +-22535 , +7975 , +-13733 , +29161 , +-27851 , +-16595 , +13021 , +-18097 , +-2187 , +2151 , +12689 , +-9755 , +-23597 , +-4009 , +25579 , +2151 , +-4119 , +3821 , +-19639 , +-27125 , +27573 , +-10685 , +-4615 , +-3463 , +-10267 , +-13109 , +-6947 , +7231 , +-333 , +16915 , +-6785 , +14291 , +-31425 , +30195 , +-5971 , +-31483 , +19811 , +-21937 , +19847 , +27381 , +-32748 , +5959 , +31011 , +-11633 , +-10195 , +14829 , +12957 , +-30847 , +17869 , +30089 , +5041 , +-10317 , +-32201 , +32579 , +-6701 , +10561 , +-21479 , +-29593 , +17357 , +-16655 , +-31627 , +-17643 , +22473 , +25389 , +25581 , +-21127 , +3575 , +12659 , +-32605 , +-12407 , +-27743 , +13917 , +-25463 , +16187 , +31419 , +7687 , +-19391 , +-12491 , +23049 , +-22251 , +-14733 , +7187 , +16809 , +8229 , +19359 , +11283 , +-9163 , +32197 , +30331 , +-28335 , +-27559 , +-30995 , +-11061 , +-31103 , +-26907 , +-30213 , +26805 , +-473 , +2411 , +-987 , +-11615 , +7243 , +19801 , +-21129 , +-23677 , +4789 , +-22647 , +-13505 , +28611 , +-10335 , +9313 , +26905 , +-17781 , +-20737 , +4195 , +-14253 , +20895 , +-479 , +-8881 , +5617 , +12731 , +25077 , +-13389 , +-10465 , +-29851 , +32711 , +12547 , +-17361 , +73 , +-30611 , +-19913 , +4619 , +-20209 , +-6655 , +19167 , +-30159 , +13237 , +3107 , +30907 , +-28375 , +2659 , +-7519 , +25555 , +-5253 , +-19771 , +-15683 , +23311 , +-11987 , +-6681 , +32477 , +32081 , +16311 , +8329 , +27849 , +-6391 , +-17799 , +3059 , +-5543 , +15445 , +12729 , +-8363 , +21691 , +-6259 , +18453 , +20893 , +-5601 , +-7065 , +-20865 , +13259 , +-29195 , +28547 , +-12623 , +19405 , +-6239 , +29329 , +31785 , +-30767 , +-11335 , +1243 , +-7261 , +8745 , +-24647 , +-10135 , +28935 , +-12907 , +2103 , +-5235 , +-7189 , +-32219 , +29093 , +22283 , +19081 , +653 , +21379 , +-28515 , +6963 , +-19971 , +19989 , +-1509 , +9293 , +-11655 , +-7523 , +5391 , +-30009 , +-15437 , +17941 , +13001 , +-28907 , +23135 , +18023 , +-1799 , +20643 , +-6127 , +-17887 , +-27961 , +18383 , +2959 , +29363 , +-6545 , +-20891 , +-7765 , +10525 , +-22701 , +-29043 , +-20833 , +23859 , +-25451 , +-20397 , +-26661 , +-24753 , +-3023 , +7565 , +-31123 , +15497 , +-1391 , +29791 , +-13883 , +-14997 , +3757 , +-16337 , +-27873 , +26421 , +10903 , +4383 , +-7853 , +-28789 , +-10083 , +-30205 , +-2777 , +-11605 , +-4899 , +7381 , +-6603 , +-29649 , +-9379 , +-21063 , +28729 , +12861 , +677 , +-11161 , +-28437 , +-11455 , +-15661 , +-3025 , +3669 , +-18903 , +-18119 , +-7579 , +32179 , +-27371 , +-1941 , +-11417 , +-7485 , +27285 , +-27417 , +-14841 , +32667 , +18785 , +24091 , +9615 , +-4851 , +13967 , +7177 , +-9683 , +4981 , +32331 , +10589 , +32762 , +7183 , +31501 , +-15871 , +-929 , +-3365 , +18265 , +-8649 , +10785 , +28901 , +20973 , +-3531 , +-11317 , +-14545 , +19583 , +27189 , +-19283 , +16887 , +27893 , +15127 , +-18357 , +-867 , +30999 , +24431 , +12389 , +-25101 , +-27439 , +-26335 , +14685 , +-19177 , +19169 , +20351 , +1343 , +-12593 , +-14313 , +-7725 , +17707 , +-9383 , +-16119 , +18057 , +26967 , +-821 , +-1465 , +20149 , +-4223 , +21989 , +-5345 , +26171 , +30703 , +-3731 , +29381 , +10329 , +-10021 , +23047 , +6171 , +-24373 , +-6027 , +-1403 , +-13345 , +-28329 , +13653 , +-8497 , +-23197 , +-27661 , +25979 , +-4823 , +-28213 , +29007 , +29625 , +12313 , +28095 , +-31751 , +-31811 , +18615 , +-32347 , +32750 , +-31625 , +-24183 , +-10145 , +30379 , +22815 , +31191 , +26743 , +28637 , +-16219 , +24967 , +-30753 , +28253 , +-19539 , +15735 , +-24023 , +14811 , +28933 , +27721 , +-22209 , +-15125 , +-3941 , +9165 , +14485 , +-30811 , +-2819 , +-24887 , +-7445 , +-22855 , +29509 , +13145 , +-23943 , +16135 , +-30307 , +-5689 , +-7245 , +-21065 , +-17363 , +-21535 , +8823 , +11473 , +-20323 , +-23343 , +-28207 , +-25513 , +8193 , +-5771 , +-14815 , +-12325 , +14173 , +313 , +-9753 , +14485 , +7827 , +26475 , +1257 , +17413 , +-8733 , +-25319 , +7677 , +18169 , +23007 , +-7327 , +-207 , +19769 , +-25119 , +13907 , +17545 , +-23155 , +11529 , +-24513 , +23867 , +-32153 , +-28241 , +32147 , +26465 , +-31001 , +-7331 , +-14029 , +-12747 , +-26489 , +31563 , +2379 , +8903 , +-13019 , +-28849 , +-2893 , +10039 , +-12899 , +-5283 , +26807 , +-31641 , +-31513 , +-32389 , +-14465 , +8765 , +29613 , +2103 , +22235 , +-26031 , +-32673 , +24483 , +-18531 , +-17107 , +-25651 , +-2867 , +3453 , +-24065 , +4671 , +-9293 , +-4259 , +14549 , +-7919 , +-10303 , +-18381 , +-10413 , +-5947 , +2753 , +20565 , +-18453 , +21405 , +-32165 , +1879 , +-7273 , +2229 , +23559 , +-27037 , +32269 , +-31847 , +-18549 , +-7411 , +-4995 , +-6051 , +12265 , +-25937 , +-12607 , +-21451 , +4839 , +15935 , +17181 , +-21873 , +3827 , +-18777 , +27763 , +-343 , +-28753 , +2463 , +-19717 , +31145 , +-32551 , +18177 , +-18567 , +3383 , +-20531 , +18087 , +28927 , +657 , +-31881 , +20159 , +27923 , +22057 , +17101 , +15005 , +-21893 , +4021 , +-24113 , +14883 , +1637 , +-4403 , +-13077 , +-15991 , +-19415 , +17413 , +-21747 , +-15937 , +-18563 , +20093 , +-29179 , +-16065 , +-9941 , +-2559 , +2439 , +-4759 , +3665 , +14747 , +10401 , +-17319 , +-13813 , +10925 , +-17993 , +14143 , +12733 , +-13171 , +-5903 , +-31431 , +-21573 , +-20329 , +-7871 , +-12631 , +-16247 , +-22841 , +-21555 , +4363 , +-14701 , +23251 , +1521 , +-1195 , +20579 , +13759 , +26033 , +27331 , +-10921 , +23547 , +-6983 , +-24519 , +-29473 , +8183 , +18891 , +-14823 , +-3025 , +-16071 , +-5959 , +-8555 , +-2437 , +-12297 , +-28443 , +-19823 , +12207 , +3381 , +16945 , +-9999 , +16799 , +8017 , +-8071 , +28277 , +-19507 , +-3289 , +-25203 , +-27111 , +21909 , +8605 , +20903 , +23003 , +-25875 , +12745 , +31331 , +1059 , +-5225 , +3965 , +6199 , +-30311 , +23771 , +-29085 , +8811 , +7027 , +-12865 , +20887 , +-13929 , +31317 , +-8763 , +-4161 , +16525 , +8619 , +-18923 , +-21603 , +17377 , +-7303 , +7493 , +-26317 , +6099 , +3257 , +-12923 , +-30903 , +13523 , +-21961 , +-31393 , +-31333 , +23153 , +1497 , +-13593 , +24411 , +16599 , +-2935 , +-9861 , +-7589 , +-24383 , +3205 , +-19977 , +19099 , +-13831 , +23605 , +-14995 , +-21917 , +-32695 , +-18041 , +12891 , +-22821 , +22261 , +16835 , +3179 , +24869 , +17075 , +8681 , +-22879 , +-7181 , +-26073 , +16263 , +22555 , +-4705 , +15573 , +-9721 , +-19647 , +28355 , +6297 , +-17253 , +-22653 , +-27307 , +-14937 , +6271 , +-31341 , +-17355 , +28923 , +-24607 , +24087 , +5971 , +-12975 , +-1739 , +-19741 , +29753 , +17059 , +8965 , +-3407 , +-6353 , +5149 , +-8103 , +-18597 , +-17207 , +-19309 , +-14981 , +16017 , +-30715 , +381 , +-671 , +5393 , +-23323 , +-25487 , +24443 , +27745 , +1915 , +6929 , +-4595 , +4869 , +-20589 , +17805 , +21769 , +-30923 , +-26435 , +7063 , +-32411 , +7195 , +32489 , +-10273 , +-5903 , +-22139 , +20353 , +-22015 , +-25931 , +-16863 , +-24835 , +24327 , +-20541 , +-13261 , +-1279 , +-20387 , +13461 , +18635 , +28911 , +29003 , +8925 , +13703 , +8451 , +21227 , +-31773 , +3259 , +13799 , +30365 , +21341 , +-30667 , +6355 , +-30965 , +15047 , +14963 , +14873 , +-28779 , +-17101 , +29271 , +17993 , +19021 , +-5201 , +24931 , +8125 , +7281 , +14863 , +-915 , +29885 , +31073 , +-29615 , +-28961 , +18961 , +-7143 , +5229 , +30819 , +21015 , +18215 , +6319 , +3365 , +26721 , +-9441 , +14991 , +4233 , +2501 , +21405 , +22027 , +-15779 , +8443 , +-30025 , +-28289 , +-2407 , +-73 , +25331 , +-18953 , +12177 , +-9157 , +6083 , +26641 , +12979 , +-21651 , +-19331 , +22857 , +4027 , +-20611 , +-5685 , +2527 , +4709 , +-27923 , +-1613 , +13087 , +-26955 , +26671 , +-3585 , +29259 , +14239 , +26049 , +-4803 , +19425 , +20551 , +-18753 , +-28107 , +8065 , +18361 , +14333 , +-30237 , +9279 , +-24803 , +31141 , +9197 , +1397 , +14965 , +-8895 , +-7779 , +14379 , +-9265 , +10339 , +8017 , +-24353 , +18687 , +25521 , +-27517 , +-24089 , +5081 , +24195 , +-7633 , +10821 , +31975 , +-20745 , +-6183 , +-8965 , +26785 , +-31085 , +5887 , +-5907 , +-8409 , +13131 , +32013 , +-22221 , +3701 , +-23251 , +-17441 , +-23057 , +18209 , +-12183 , +-22351 , +3495 , +-5237 , +17393 , +-13925 , +16161 , +-13921 , +-13165 , +27011 , +31669 , +-10495 , +31883 , +31391 , +23081 , +-14383 , +-4199 , +-157 , +4613 , +30683 , +9127 , +12803 , +14193 , +-25005 , +-16945 , +8801 , +-123 , +-15351 , +5121 , +649 , +-23253 , +-3033 , +-11501 , +-9811 , +1645 , +8033 , +-26279 , +-10857 , +4691 , +-22091 , +24005 , +-3419 , +7993 , +6813 , +-1161 , +12861 , +-15957 , +26575 , +-17961 , +6091 , +15283 , +-11673 , +10541 , +-23499 , +7357 , +-12625 , +11195 , +-30771 , +10727 , +-4533 , +-31917 , +-15653 , +9949 , +17655 , +-17553 , +27775 , +-26835 , +16319 , +-14389 , +-10185 , +4133 , +26289 , +12151 , +-11815 , +13091 , +287 , +7291 , +10237 , +-6025 , +5199 , +10207 , +15617 , +-3407 , +-19277 , +14933 , +-10623 , +29313 , +8617 , +22847 , +-7355 , +29445 , +-23639 , +-18349 , +28611 , +5809 , +-23293 , +-6225 , +-32491 , +31895 , +-747 , +30325 , +3691 , +-2489 , +-6651 , +-7721 , +-12017 , +-23005 , +-27403 , +10435 , +8907 , +7745 , +-4927 , +-9245 , +-23819 , +6067 , +17201 , +589 , +-9767 , +-9619 , +-20301 , +-21879 , +-27979 , +28051 , +-7533 , +-32721 , +9267 , +10331 , +-6215 , +15875 , +24417 , +-17573 , +-4139 , +21639 , +23843 , +19049 , +29983 , +-25321 , +-7627 , +-20757 , +-14191 , +29055 , +-28263 , +31415 , +30871 , +19 , +-23147 , +-11417 , +-30129 , +13383 , +26411 , +-16847 , +-711 , +3017 , +7183 , +-3009 , +-28293 , +-20455 , +-23781 , +-10359 , +18569 , +11417 , +30547 , +-24535 , +-26515 , +6451 , +20815 , +23099 , +-13969 , +4453 , +7999 , +-13273 , +30303 , +20449 , +-29865 , +-8825 , +-22721 , +18077 , +-14123 , +-27013 , +32381 , +-29839 , +-8341 , +20349 , +-3921 , +-3791 , +11585 , +10681 , +32463 , +9535 , +22379 , +26603 , +27365 , +-22109 , +24793 , +-16461 , +24397 , +-31831 , +8159 , +15213 , +103 , +30451 , +-13799 , +-15223 , +24789 , +9495 , +-12555 , +-4507 , +-12247 , +-5711 , +-18271 , +6563 , +-981 , +-13571 , +19333 , +-30719 , +-9083 , +22257 , +-25537 , +30895 , +24831 , +-15149 , +21523 , +-6863 , +23099 , +13135 , +-9241 , +-2395 , +-27419 , +23319 , +-23103 , +-13393 , +-24715 , +-29199 , +19637 , +-22847 , +12893 , +23125 , +-15519 , +7423 , +-19769 , +-21631 , +18667 , +23949 , +-14389 , +-16869 , +23661 , +10605 , +31271 , +-16073 , +26357 , +-27691 , +-10629 , +31747 , +21505 , +8971 , +-30213 , +-12337 , +-12183 , +27057 , +29095 , +28335 , +26599 , +-20303 , +-27639 , +-24947 , +14593 , +-13951 , +32107 , +24773 , +30607 , +-24315 , +30343 , +-10691 , +30115 , +-21783 , +-29237 , +14329 , +27407 , +-17039 , +-5367 , +15413 , +-19625 , +30169 , +26037 , +16385 , +-17881 , +-17111 , +-10857 , +3409 , +20049 , +-31351 , +5633 , +-27233 , +-27839 , +22563 , +13205 , +30967 , +18673 , +-13451 , +-17299 , +-20069 , +-23957 , +31271 , +-21799 , +15379 , +25271 , +-28057 , +-7525 , +5063 , +30813 , +-27201 , +-18277 , +23579 , +-12463 , +24939 , +32027 , +3581 , +-28299 , +5947 , +-32645 , +521 , +-29297 , +-295 , +-30107 , +-20711 , +-833 , +-2121 , +15239 , +30051 , +24177 , +-27823 , +20947 , +-12793 , +-23833 , +28693 , +18221 , +14133 , +23577 , +-4937 , +17069 , +13497 , +11589 , +-13309 , +-11191 , +15637 , +12499 , +-7877 , +29471 , +-5339 , +-29477 , +23793 , +13853 , +19489 , +-4589 , +-11691 , +-16575 , +-23989 , +8527 , +-29415 , +-11953 , +29691 , +-31883 , +20419 , +-30705 , +16185 , +32754 , +4737 , +-21771 , +-22063 , +-10821 , +-9591 , +4719 , +-31239 , +-9541 , +16879 , +-26745 , +-31911 , +30161 , +-14343 , +-31185 , +-6999 , +1865 , +-32261 , +2535 , +4557 , +-2099 , +17579 , +-29435 , +24167 , +9701 , +-8707 , +-32161 , +-8971 , +-5655 , +30585 , +-28275 , +-27043 , +-6019 , +-18153 , +-25185 , +-487 , +27529 , +-15219 , +-25007 , +-1347 , +31147 , +-24267 , +-15421 , +23315 , +25655 , +12375 , +-9029 , +4027 , +941 , +16905 , +30541 , +317 , +23211 , +-7543 , +-19423 , +-9571 , +-10387 , +30735 , +17445 , +-24453 , +-5187 , +-14041 , +-30525 , +27817 , +13175 , +-31863 , +20125 , +9789 , +-7821 , +23413 , +6851 , +-29135 , +-21753 , +23427 , +-32145 , +30837 , +-5639 , +32001 , +-31437 , +-30325 , +11513 , +8397 , +25021 , +20639 , +-4449 , +-32605 , +-8953 , +5659 , +-21799 , +-20221 , +29713 , +14019 , +2789 , +19323 , +28699 , +25417 , +24531 , +22921 , +21853 , +-25493 , +9069 , +-26643 , +-23497 , +17285 , +-18497 , +-21881 , +25849 , +6061 , +7427 , +22697 , +30217 , +30535 , +-10721 , +27123 , +5289 , +-16859 , +-19559 , +15271 , +-26587 , +6163 , +-17129 , +-22907 , +-10347 , +-24583 , +-3761 , +19749 , +12809 , +9071 , +5245 , +-5437 , +-20145 , +25301 , +17763 , +-17753 , +16157 , +9707 , +-28477 , +-28683 , +25809 , +-787 , +15175 , +-18943 , +-29269 , +1569 , +-1527 , +12589 , +17277 , +-28675 , +-11895 , +30789 , +24043 , +-4173 , +-11493 , +15945 , +-25571 , +25677 , +28905 , +25813 , +-24325 , +24137 , +-24475 , +-20759 , +-13853 , +937 , +-31927 , +19541 , +-10271 , +18579 , +-12543 , +-10885 , +-7319 , +29795 , +-21837 , +-12363 , +-28023 , +27465 , +15277 , +21037 , +2477 , +-27559 , +-26529 , +-7379 , +-28981 , +-19411 , +22995 , +9725 , +22303 , +-27663 , +-31835 , +28987 , +30563 , +-13049 , +-1409 , +-6739 , +28299 , +-28393 , +16651 , +7587 , +17143 , +-14677 , +-19605 , +3271 , +-21971 , +21057 , +-1733 , +10361 , +13077 , +-7187 , +-6663 , +28833 , +-5463 , +8553 , +-32760 , +28943 , +29491 , +-31569 , +26157 , +-11439 , +1541 , +-14571 , +19315 , +-26361 , +22447 , +12509 , +-15945 , +-26947 , +-10571 , +-23213 , +2715 , +18245 , +15565 , +-15517 , +9971 , +-28787 , +-5487 , +-3403 , +-9013 , +-29959 , +1469 , +-19139 , +-5157 , +-1993 , +-11811 , +5467 , +10363 , +24219 , +15251 , +-30613 , +-19173 , +-31755 , +3651 , +7655 , +4675 , +19177 , +-13233 , +21239 , +15617 , +-28217 , +-24111 , +25225 , +-27673 , +10727 , +27093 , +27119 , +-17787 , +32635 , +15877 , +14833 , +13141 , +2537 , +-30479 , +11371 , +-6075 , +7331 , +4797 , +-10655 , +22945 , +12417 , +93 , +-4463 , +-21619 , +15769 , +15687 , +16537 , +18947 , +15761 , +18355 , +1157 , +23369 , +28287 , +-10415 , +29417 , +-18205 , +28221 , +22139 , +-4743 , +-22767 , +-14783 , +-23049 , +-27611 , +713 , +-9 , +8995 , +-24921 , +7719 , +-9837 , +26809 , +21161 , +875 , +-19599 , +-15873 , +-4529 , +22129 , +-12819 , +-14207 , +24409 , +-29531 , +28591 , +9293 , +7865 , +-19583 , +-29549 , +-6493 , +2213 , +32123 , +1269 , +30515 , +-30409 , +-12917 , +5519 , +-29737 , +-2689 , +30999 , +4049 , +8897 , +26911 , +30833 , +-3401 , +-2243 , +101 , +15821 , +-995 , +26857 , +-14633 , +27323 , +-13663 , +19811 , +12889 , +-25573 , +10227 , +-23413 , +-32061 , +-31593 , +5043 , +-22729 , +-8723 , +3489 , +9919 , +10349 , +-32683 , +-18721 , +-6379 , +-16107 , +-9679 , +-5075 , +9259 , +-16837 , +-3835 , +-30189 , +-3139 , +18877 , +-8765 , +18613 , +26417 , +-14963 , +-16553 , +17751 , +-28315 , +-11941 , +-1591 , +25169 , +-2801 , +-3363 , +6609 , +-19073 , +-3185 , +22655 , +13551 , +-17083 , +21579 , +-20843 , +7683 , +-27649 , +31877 , +32547 , +18025 , +-9729 , +28595 , +5121 , +-23671 , +-29189 , +12377 , +21417 , +28917 , +-29679 , +-26273 , +-28585 , +9985 , +-5321 , +18409 , +-15911 , +32215 , +-3785 , +-21073 , +8629 , +-10989 , +-10971 , +-7209 , +-24087 , +-10277 , +2135 , +22089 , +13855 , +-19085 , +15835 , +-8309 , +26479 , +-14759 , +-6023 , +27929 , +10885 , +-2599 , +26395 , +-15303 , +28781 , +-14295 , +-26669 , +32601 , +27069 , +21763 , +2379 , +-9249 , +-2993 , +3763 , +-32063 , +28807 , +11137 , +-21059 , +6779 , +25659 , +-27931 , +6373 , +-27963 , +15721 , +-11397 , +-24107 , +13667 , +-7719 , +-31895 , +28207 , +-6771 , +-8435 , +-4043 , +25893 , +-24477 , +-27889 , +25469 , +31121 , +9195 , +19915 , +-9687 , +-22385 , +-2941 , +755 , +-22997 , +-31599 , +30939 , +-23485 , +-3407 , +-23303 , +25713 , +-17301 , +-23835 , +-11721 , +10371 , +25179 , +-31979 , +18007 , +-23673 , +7457 , +17539 , +-9699 , +-14549 , +-12225 , +15235 , +30367 , +27843 , +18567 , +22599 , +-23715 , +4169 , +-32407 , +21007 , +-30509 , +-22067 , +15063 , +31965 , +16283 , +23929 , +-2153 , +16823 , +-15363 , +14839 , +-1001 , +-20139 , +26119 , +-17027 , +26063 , +10593 , +3627 , +22837 , +-3313 , +-31701 , +11857 , +-21695 , +-27809 , +-13603 , +-18569 , +-22741 , +22611 , +-7619 , +-5189 , +25819 , +-8479 , +10717 , +25857 , +-12771 , +-14019 , +-31273 , +10247 , +-7545 , +24879 , +-13567 , +7157 , +-13827 , +-1297 , +1451 , +-16767 , +28069 , +12405 , +-27953 , +27775 , +-12447 , +-29353 , +-31791 , +5885 , +-10301 , +-15587 , +17587 , +-17189 , +-11639 , +-477 , +-819 , +-32547 , +20885 , +29409 , +-24061 , +-19383 , +-20897 , +-17455 , +13959 , +-20993 , +-7691 , +8127 , +10495 , +-14831 , +-5263 , +22693 , +20305 , +19925 , +31979 , +-3331 , +29643 , +-9083 , +9975 , +-8795 , +-4891 , +-14255 , +-17763 , +16939 , +14197 , +9213 , +6609 , +15783 , +2919 , +6385 , +11875 , +-28131 , +-7437 , +-2599 , +16261 , +-6073 , +27741 , +-13895 , +23991 , +-17931 , +-8669 , +-7293 , +7493 , +31973 , +-23109 , +3637 , +22333 , +9753 , +26825 , +-7829 , +10473 , +-25171 , +-12071 , +-389 , +-5695 , +15157 , +6549 , +-28149 , +20463 , +-7535 , +-9861 , +-3543 , +31543 , +-9917 , +-741 , +-20253 , +7807 , +-5043 , +27849 , +-1183 , +32699 , +-383 , +21723 , +-25221 , +-31127 , +-26783 , +-30633 , +-32303 , +-28529 , +-30091 , +-2505 , +1635 , +17957 , +20251 , +-22245 , +-595 , +8991 , +8429 , +18817 , +-19401 , +-4139 , +-32627 , +-25989 , +-11597 , +-8191 , +11523 , +-5907 , +29845 , +-28613 , +11665 , +-6851 , +19239 , +-26129 , +1043 , +-8297 , +9511 , +-2611 , +-24629 , +-8555 , +-19753 , +-6963 , +10435 , +-30585 , +-8547 , +-26721 , +15267 , +22301 , +-28139 , +19623 , +-20987 , +3497 , +16303 , +7281 , +29519 , +-5675 , +2241 , +11439 , +-17907 , +-31019 , +-10207 , +-32339 , +-9785 , +-5337 , +18749 , +9797 , +10587 , +-18233 , +-19527 , +-7583 , +21967 , +-2073 , +13177 , +14313 , +20917 , +29735 , +1351 , +-8637 , +29939 , +9293 , +4069 , +29767 , +-6871 , +-27521 , +-3675 , +-24393 , +-8573 , +-13575 , +27267 , +22837 , +-2799 , +-24761 , +31413 , +-30783 , +-6499 , +-1031 , +3539 , +-14675 , +5385 , +733 , +-30113 , +27411 , +16673 , +-29765 , +7653 , +-27181 , +-25097 , +-2681 , +7571 , +-31997 , +-11077 , +-15845 , +21325 , +-12301 , +4365 , +-2959 , +-28855 , +-4205 , +-21027 , +-22183 , +22055 , +-31361 , +-25921 , +-7503 , +899 , +-8343 , +4547 , +-735 , +14615 , +17685 , +-18995 , +-14265 , +-3509 , +22229 , +-20113 , +-18047 , +5197 , +12921 , +-4547 , +12567 , +-11601 , +-26929 , +-853 , +18935 , +-16261 , +-17001 , +-15265 , +11247 , +-6711 , +9207 , +-27381 , +22627 , +-20003 , +-1665 , +-20537 , +-5755 , +8635 , +28053 , +-7959 , +15375 , +-3269 , +-27791 , +16983 , +-1161 , +15531 , +5271 , +-16793 , +2219 , +16607 , +27087 , +27445 , +13129 , +-10291 , +-11625 , +22131 , +15699 , +17311 , +-15579 , +-9779 , +8555 , +-13737 , +211 , +4029 , +4999 , +-5161 , +9509 , +-32551 , +13361 , +-29557 , +-16587 , +-24129 , +28211 , +-5011 , +-13395 , +14679 , +30425 , +-15695 , +-17591 , +18365 , +26791 , +21965 , +-16447 , +-31347 , +-3957 , +-6117 , +-26805 , +5059 , +-31331 , +20715 , +-29045 , +29707 , +-23725 , +6689 , +-3817 , +24993 , +32311 , +-1467 , +-24479 , +-23897 , +11045 , +803 , +2359 , +27125 , +-20225 , +23775 , +12221 , +24959 , +-797 , +-6771 , +2523 , +-2785 , +12517 , +-29369 , +-8127 , +-2567 , +17741 , +-14645 , +-4647 , +11851 , +29765 , +-7025 , +-2627 , +-569 , +26647 , +-17831 , +1971 , +-27029 , +-23583 , +23383 , +11041 , +-3619 , +7891 , +19639 , +10381 , +5947 , +-30239 , +1217 , +10635 , +-13957 , +14335 , +3693 , +26427 , +13885 , +8407 , +-22149 , +-24769 , +-17113 , +-2559 , +16139 , +-30925 , +26555 , +-15683 , +-32071 , +-2393 , +10673 , +3623 , +-26579 , +-107 , +-32311 , +-2059 , +5433 , +-21159 , +-27859 , +18345 , +14449 , +-24023 , +20289 , +-6583 , +11329 , +19213 , +-14339 , +-17759 , +-20863 , +-7587 , +17095 , +24555 , +-2919 , +-1877 , +9159 , +-20715 , +9231 , +-17335 , +18885 , +-28045 , +14235 , +-18629 , +-3463 , +7157 , +-22321 , +15279 , +-16533 , +21989 , +-18911 , +14069 , +-3255 , +-14825 , +-25209 , +-23819 , +32697 , +7081 , +-23665 , +20017 , +-1097 , +-201 , +16125 , +12845 , +6765 , +32145 , +16597 , +4211 , +-17783 , +1275 , +20737 , +-29173 , +9749 , +27863 , +-26781 , +-31383 , +-25905 , +-17 , +-5777 , +-14607 , +-19711 , +287 , +21563 , +-25 , +-14627 , +-23923 , +23333 , +-25 , +-8625 , +-6289 , +-15651 , +5349 , +19285 , +26673 , +16651 , +-19043 , +-31521 , +28987 , +-6053 , +12939 , +23069 , +29727 , +-22251 , +-23191 , +5725 , +17243 , +-16829 , +-10463 , +-21149 , +4231 , +24379 , +21579 , +-30659 , +-23277 , +-29255 , +26655 , +2717 , +-12931 , +22651 , +13805 , +26805 , +28427 , +27227 , +-22245 , +-6773 , +16385 , +15841 , +29595 , +4557 , +-26027 , +-12965 , +-11553 , +9011 , +24821 , +6011 , +21329 , +-945 , +28525 , +20587 , +19027 , +-795 , +-29653 , +5987 , +16045 , +13003 , +21809 , +-30519 , +-2165 , +823 , +8021 , +-31557 , +27125 , +-7011 , +16367 , +567 , +15555 , +16647 , +-18157 , +-14677 , +6939 , +6377 , +-16299 , +23047 , +-29343 , +32379 , +6123 , +-28831 , +-28491 , +-32361 , +-19843 , +31241 , +-23315 , +-23547 , +-26293 , +10011 , +-30459 , +28253 , +-29461 , +-3173 , +24093 , +15705 , +22663 , +-10475 , +26865 , +-8267 , +20361 , +31395 , +10701 , +7287 , +-4643 , +29849 , +777 , +-17953 , +4773 , +-32627 , +9729 , +7335 , +-12941 , +3065 , +-377 , +6121 , +13821 , +-4273 , +-11037 , +1397 , +18007 , +-21619 , +-8633 , +-16733 , +12207 , +1123 , +29639 , +-29257 , +8575 , +20151 , +-22575 , +-20565 , +-1207 , +19407 , +-3543 , +32399 , +-7991 , +-5923 , +10841 , +-9119 , +10425 , +-17633 , +-30547 , +-2461 , +-25093 , +-28557 , +-6735 , +-1807 , +-29861 , +-5013 , +-4063 , +-13343 , +-30271 , +-13841 , +-28321 , +28495 , +-30481 , +31051 , +14453 , +4351 , +2737 , +-3373 , +17285 , +29235 , +2207 , +30185 , +16325 , +-18947 , +31819 , +-13145 , +14327 , +12321 , +511 , +3053 , +-13991 , +19553 , +-29197 , +10237 , +14121 , +9827 , +-21497 , +13711 , +13463 , +-5637 , +16887 , +-20627 , +-25281 , +-27635 , +19481 , +-26487 , +-11239 , +11233 , +-29555 , +-11625 , +253 , +3323 , +-23299 , +-32479 , +-7019 , +22897 , +-27951 , +-11995 , +31443 , +11467 , +1511 , +-731 , +9201 , +-22701 , +-30259 , +-6713 , +-29731 , +27117 , +-1679 , +5865 , +2105 , +-25995 , +13673 , +-28361 , +-23339 , +2193 , +-27491 , +12361 , +-26975 , +-29939 , +1919 , +1333 , +19751 , +11697 , +26065 , +32169 , +-9595 , +18331 , +-8499 , +-20599 , +-5663 , +4627 , +995 , +-24327 , +-921 , +-10267 , +26101 , +-6909 , +9403 , +21823 , +15627 , +25771 , +-1803 , +24571 , +4745 , +-21377 , +-3307 , +28807 , +-6677 , +-26949 , +-2047 , +9011 , +-15365 , +-22053 , +15605 , +18953 , +18573 , +945 , +17287 , +-22741 , +685 , +10497 , +9231 , +-6235 , +13153 , +-28265 , +-8533 , +-2357 , +-8479 , +18657 , +-5451 , +16905 , +-22461 , +31491 , +-17223 , +1345 , +28613 , +18037 , +31467 , +14243 , +11125 , +-21999 , +-26587 , +12547 , +-3471 , +-6213 , +-29353 , +-24655 , +-19809 , +13159 , +27017 , +-6447 , +-30495 , +1727 , +28747 , +32053 , +13267 , +-3791 , +32429 , +25779 , +-26373 , +15503 , +28347 , +20987 , +-11125 , +15907 , +12663 , +-25357 , +-13427 , +-21433 , +-10423 , +-28269 , +-18263 , +-12165 , +16127 , +14637 , +-21683 , +-4603 , +-23747 , +13401 , +29047 , +-19203 , +-16769 , +-17091 , +-7207 , +6641 , +-17017 , +27249 , +3237 , +27125 , +-18341 , +-13749 , +8375 , +-3265 , +-5699 , +28357 , +-15537 , +6715 , +23839 , +-32315 , +-29613 , +13093 , +19231 , +31239 , +18679 , +-2009 , +-9089 , +2145 , +-4349 , +-3097 , +-29801 , +-10831 , +-17787 , +-18271 , +-9131 , +10529 , +28167 , +15305 , +-23885 , +3849 , +11595 , +11797 , +-28761 , +6215 , +-5501 , +-22497 , +15529 , +18967 , +-8701 , +889 , +28065 , +22117 , +133 , +14403 , +-16035 , +-19283 , +-47 , +-26809 , +-30571 , +-19631 , +-23039 , +14481 , +-1197 , +6505 , +11067 , +-2427 , +-31491 , +28969 , +27097 , +19831 , +24253 , +-27987 , +27955 , +-2111 , +12417 , +-30891 , +21199 , +-24991 , +-3981 , +23969 , +-2537 , +30221 , +-18197 , +1411 , +24211 , +8395 , +-13069 , +-12999 , +26789 , +-21495 , +-31953 , +-26967 , +-24391 , +821 , +20325 , +23857 , +-14073 , +-20775 , +-23961 , +9223 , +447 , +14377 , +-10087 , +-6901 , +3023 , +2343 , +-4391 , +-26587 , +-25075 , +8501 , +13831 , +-5357 , +17655 , +30251 , +-17167 , +-15921 , +-15123 , +23027 , +-22321 , +5977 , +30435 , +-17249 , +13375 , +22301 , +-26727 , +-23805 , +-29511 , +-14661 , +345 , +-22069 , +18051 , +6253 , +18475 , +-4849 , +-24781 , +-16937 , +-20339 , +11385 , +18079 , +4967 , +-1877 , +-31799 , +-6569 , +-995 , +27671 , +-28673 , +8095 , +1529 , +14853 , +22759 , +14307 , +-20803 , +-31237 , +-10439 , +11189 , +-7847 , +11025 , +28459 , +24641 , +17331 , +-22109 , +14219 , +-21695 , +27911 , +14219 , +25949 , +-5763 , +-25407 , +27357 , +-19483 , +-9277 , +2507 , +30489 , +8525 , +-32173 , +25201 , +29927 , +-10311 , +-20761 , +-27471 , +-21431 , +-25897 , +1311 , +30485 , +22879 , +-28155 , +8577 , +27153 , +-7277 , +-14631 , +7917 , +-30261 , +-173 , +12363 , +12943 , +-30583 , +-19889 , +-24003 , +-27033 , +-13963 , +-19919 , +31133 , +31283 , +-11263 , +5577 , +23797 , +13035 , +-18501 , +-12077 , +-5749 , +24761 , +30887 , +-3541 , +-23307 , +17267 , +7185 , +7295 , +2867 , +-2669 , +28145 , +12683 , +4419 , +-14933 , +5813 , +-22567 , +-3013 , +26207 , +6559 , +-32023 , +-21275 , +11489 , +21413 , +26103 , +-8241 , +5601 , +4793 , +-18135 , +-24085 , +-14067 , +23981 , +22863 , +-5725 , +21251 , +1163 , +-13799 , +1137 , +-12849 , +4451 , +25287 , +-5899 , +-20517 , +-20051 , +28013 , +-17003 , +-1683 , +12317 , +-20313 , +27529 , +-1887 , +5885 , +23495 , +-27007 , +-9253 , +4865 , +-12897 , +-12115 , +-13635 , +-20829 , +11689 , +25445 , +-16981 , +32249 , +20427 , +-31693 , +-13383 , +-11507 , +-9597 , +20089 , +10017 , +-27977 , +10155 , +22907 , +-32697 , +16881 , +-10327 , +17153 , +1829 , +-7241 , +-28887 , +1639 , +-15547 , +-16559 , +-10407 , +30785 , +31299 , +-22727 , +-26471 , +-16795 , +-9033 , +-10129 , +10171 , +7311 , +12725 , +2635 , +23987 , +-4757 , +14535 , +-14627 , +-20007 , +8255 , +31325 , +-23617 , +-12647 , +4851 , +-16695 , +29553 , +-26451 , +8373 , +-7233 , +1839 , +8405 , +-17147 , +-14277 , +-26293 , +30737 , +29527 , +-30965 , +30719 , +-8617 , +-23765 , +-18497 , +2255 , +17357 , +20633 , +-4581 , +-17321 , +-27525 , +-7815 , +12319 , +2733 , +-14707 , +7921 , +-26001 , +4141 , +8961 , +21391 , +-5295 , +-7461 , +-16151 , +-8735 , +11307 , +14393 , +-21739 , +3985 , +12657 , +29593 , +-22435 , +-20237 , +10531 , +-19201 , +7751 , +297 , +-4157 , +111 , +1615 , +-30027 , +25549 , +5579 , +28049 , +-23409 , +28593 , +4393 , +30477 , +-2111 , +585 , +27565 , +22613 , +-7809 , +-21041 , +29919 , +18637 , +2489 , +9565 , +-9085 , +-9379 , +1595 , +20699 , +25839 , +-17747 , +25155 , +12155 , +21997 , +16347 , +-7533 , +16565 , +-14335 , +-9295 , +24083 , +-21575 , +24663 , +-13721 , +731 , +-8851 , +-27389 , +2505 , +24543 , +-11047 , +4595 , +2563 , +2799 , +-10701 , +22061 , +4299 , +15207 , +-17343 , +8635 , +-14565 , +12597 , +-24475 , +-13317 , +-5775 , +-16263 , +4355 , +6773 , +-28033 , +-9831 , +-29051 , +-20425 , +6245 , +26081 , +-31021 , +-21079 , +-2967 , +20623 , +-30911 , +-26387 , +-21197 , +5241 , +-8941 , +9899 , +15229 , +-23019 , +23659 , +-1163 , +-7855 , +4641 , +-31285 , +-619 , +-5183 , +-22353 , +-15871 , +20333 , +22299 , +3267 , +-4951 , +-30133 , +-12889 , +105 , +-6877 , +20925 , +-1831 , +17743 , +24071 , +-10379 , +-25331 , +27099 , +-23777 , +26517 , +30649 , +-9537 , +-29213 , +-27255 , +22575 , +4381 , +24683 , +8551 , +27343 , +13587 , +-16665 , +11711 , +11963 , +3287 , +32669 , +-8715 , +3609 , +-28589 , +-30369 , +-2787 , +4291 , +-1739 , +30847 , +-29369 , +-24193 , +-22639 , +16967 , +32617 , +-8771 , +-19731 , +-28935 , +-27735 , +26571 , +32740 , +571 , +4667 , +13197 , +12857 , +10783 , +-13133 , +17847 , +21357 , +19591 , +14313 , +-8835 , +-31265 , +-13523 , +-20923 , +221 , +-25513 , +22037 , +29337 , +-7361 , +-4563 , +-23417 , +-29821 , +7875 , +16337 , +-4989 , +3893 , +14317 , +6133 , +-12103 , +-2083 , +25563 , +-9963 , +-757 , +6255 , +2311 , +30615 , +10617 , +18953 , +-3467 , +9313 , +-17511 , +27075 , +-21129 , +-15371 , +-16739 , +16137 , +2515 , +-30207 , +27067 , +-7565 , +13455 , +-28289 , +-4819 , +-17119 , +25883 , +-14011 , +-16983 , +-18295 , +-27381 , +3365 , +5717 , +-18721 , +14935 , +-15485 , +-5821 , +-5159 , +31753 , +-10391 , +-2457 , +11803 , +-9857 , +26399 , +16657 , +-9987 , +-17385 , +-181 , +-25633 , +22259 , +-5263 , +-17791 , +-31935 , +-5031 , +23587 , +7515 , +-413 , +-9521 , +20721 , +1817 , +-16723 , +29973 , +18055 , +-29011 , +13755 , +15197 , +-24145 , +9311 , +-9773 , +-26585 , +-26617 , +-12323 , +20701 , +21909 , +19263 , +-7467 , +-17957 , +25415 , +-28979 , +-2031 , +-13085 , +1205 , +20513 , +-26875 , +2453 , +-5 , +6503 , +21491 , +-21483 , +-6847 , +-22855 , +-15235 , +-24453 , +1675 , +1491 , +8379 , +11481 , +14347 , +14419 , +-5929 , +-30295 , +-3831 , +-12177 , +26405 , +8391 , +-6869 , +-32727 , +26293 , +-21783 , +-20909 , +4873 , +-2443 , +-7271 , +-24837 , +-13737 , +-28481 , +2987 , +21769 , +-27697 , +32631 , +-3533 , +9509 , +4833 , +-11101 , +-17403 , +-2409 , +-2979 , +-12415 , +8609 , +-22633 , +-31563 , +1565 , +23479 , +-28113 , +179 , +11119 , +30231 , +18825 , +-26453 , +-13843 , +16683 , +10189 , +-25027 , +-13657 , +-26127 , +-15241 , +-11135 , +8413 , +16495 , +-5325 , +23241 , +29205 , +-2895 , +11051 , +10713 , +4795 , +4667 , +-26901 , +-25707 , +12077 , +25091 , +-13135 , +-2749 , +31073 , +23277 , +-8375 , +27713 , +13037 , +-30531 , +14179 , +-25289 , +-5201 , +20881 , +1383 , +-4649 , +-13095 , +-11815 , +23515 , +-12017 , +-14191 , +1747 , +-30167 , +26055 , +-31233 , +-133 , +-12285 , +26643 , +25075 , +19467 , +313 , +-4883 , +23537 , +25583 , +12809 , +-8081 , +18385 , +14907 , +1031 , +-16759 , +7119 , +-18263 , +-21659 , +32315 , +-19669 , +22793 , +17619 , +10055 , +-8901 , +-27325 , +-27691 , +2675 , +4361 , +26055 , +-15973 , +5175 , +-25245 , +-31101 , +13405 , +12797 , +-21123 , +-17815 , +5933 , +16851 , +-1539 , +-15019 , +-21935 , +-31577 , +32415 , +21649 , +-3045 , +2813 , +3139 , +-29239 , +-5565 , +5159 , +3983 , +31879 , +-21571 , +-10243 , +25595 , +5663 , +-7405 , +-19687 , +-29833 , +3129 , +-5831 , +11657 , +8819 , +9657 , +-16149 , +-11257 , +-6009 , +22081 , +-32133 , +23479 , +13695 , +19491 , +20533 , +2139 , +13049 , +-21283 , +27441 , +-13047 , +-19845 , +-18415 , +-32597 , +8043 , +-2037 , +-30473 , +-14375 , +-2709 , +20811 , +-20899 , +2121 , +-6793 , +-12023 , +20765 , +8373 , +-7891 , +1887 , +-24307 , +9817 , +-32095 , +3651 , +-16251 , +-19249 , +25609 , +-15703 , +-6581 , +-31129 , +31227 , +-32241 , +-4589 , +-4869 , +-6109 , +17573 , +3949 , +17227 , +18553 , +27603 , +-3253 , +-4397 , +-8959 , +7515 , +-8211 , +2597 , +-23561 , +-32015 , +13151 , +20411 , +-14699 , +-14763 , +-7057 , +23897 , +23101 , +8671 , +16933 , +-6179 , +-5061 , +-8791 , +-22083 , +-2153 , +-12295 , +-28395 , +27423 , +-15061 , +-22603 , +-32525 , +-27697 , +20183 , +8127 , +29201 , +-10125 , +15967 , +21547 , +-14247 , +21693 , +14167 , +-9971 , +19039 , +23025 , +9727 , +-8913 , +24965 , +973 , +-22885 , +24395 , +11917 , +-13295 , +7505 , +-4675 , +19119 , +-11159 , +-27017 , +-5949 , +-29385 , +7923 , +1901 , +-16589 , +-21101 , +27943 , +2045 , +7597 , +6649 , +-675 , +-25557 , +-30627 , +-9611 , +-8511 , +9871 , +22311 , +-10111 , +5059 , +6957 , +-29587 , +25379 , +15129 , +-29999 , +32311 , +18301 , +-2249 , +7903 , +-13829 , +21999 , +-13249 , +-25165 , +-30007 , +-21595 , +-21379 , +-28811 , +18955 , +-26441 , +-5275 , +7021 , +-23883 , +31419 , +-12547 , +-18969 , +3845 , +25569 , +30693 , +-18819 , +-10057 , +-6519 , +22467 , +28409 , +-23621 , +-8871 , +-4541 , +-9561 , +-29835 , +-30755 , +1163 , +32309 , +19049 , +-11371 , +7983 , +-28673 , +25725 , +10641 , +24241 , +239 , +-13395 , +-26481 , +-31113 , +32215 , +-2235 , +-19577 , +25151 , +321 , +-6765 , +-819 , +16923 , +3537 , +43 , +13733 , +-15131 , +10511 , +23181 , +27229 , +-22213 , +-20783 , +17267 , +4831 , +-8967 , +-27389 , +-24459 , +8145 , +-31961 , +14343 , +3149 , +19499 , +10363 , +-14449 , +12171 , +-29879 , +-8625 , +27627 , +19405 , +-5237 , +29717 , +-17427 , +29049 , +-15001 , +-30895 , +-25797 , +22515 , +-28921 , +-24043 , +6435 , +20563 , +11353 , +8177 , +26621 , +19105 , +5041 , +4467 , +-31495 , +25999 , +7893 , +-10727 , +-22401 , +169 , +24737 , +-23347 , +5891 , +-14061 , +-10475 , +-17699 , +27225 , +-18241 , +20983 , +26991 , +-5223 , +-32731 , +26081 , +-18053 , +5483 , +21119 , +-15395 , +-8635 , +-10525 , +-29575 , +-12925 , +11859 , +-20775 , +11633 , +-17019 , +-9497 , +14279 , +-25815 , +15569 , +7669 , +15381 , +-22525 , +-17371 , +5783 , +-5383 , +21429 , +27175 , +3089 , +17875 , +16009 , +7677 , +20285 , +24053 , +18185 , +3689 , +29317 , +31505 , +19009 , +-21159 , +4197 , +-15875 , +32371 , +-32762 , +-10155 , +29721 , +24657 , +19337 , +6729 , +24349 , +-21839 , +28147 , +-30549 , +-27273 , +20681 , +-17435 , +26825 , +1829 , +-3357 , +-17751 , +-5669 , +4869 , +-14949 , +-28979 , +-9619 , +-22351 , +25489 , +30513 , +29793 , +4829 , +-32345 , +11435 , +30565 , +549 , +-591 , +-491 , +18915 , +-3989 , +16307 , +239 , +22661 , +29867 , +26009 , +11883 , +27689 , +-24743 , +12651 , +-15085 , +11859 , +-2251 , +12811 , +-14639 , +-27607 , +11937 , +7783 , +-5227 , +26609 , +10623 , +-9423 , +-8087 , +-22273 , +27521 , +8993 , +11009 , +-1485 , +-30967 , +18847 , +-30241 , +-10513 , +-23425 , +4099 , +10469 , +-14705 , +-17887 , +1357 , +-32147 , +18019 , +-29591 , +26713 , +17629 , +-24029 , +3801 , +1181 , +5323 , +29423 , +15705 , +345 , +-31865 , +-839 , +1547 , +7001 , +4671 , +8783 , +23465 , +16673 , +-26227 , +10177 , +2137 , +2481 , +-4715 , +-1177 , +22789 , +-587 , +5791 , +15699 , +14641 , +11073 , +-2525 , +-17083 , +-10409 , +-1019 , +-20363 , +-22741 , +27073 , +-14837 , +-19769 , +5657 , +11225 , +3815 , +-21039 , +17845 , +11271 , +-1675 , +23779 , +6721 , +521 , +-10731 , +29053 , +14079 , +1477 , +19797 , +31589 , +23359 , +7853 , +7481 , +9543 , +15811 , +-15481 , +-7963 , +-25149 , +-24895 , +17107 , +-9507 , +-31479 , +-14245 , +-5219 , +14787 , +14071 , +13721 , +11989 , +-12421 , +-13915 , +-26667 , +20773 , +-19719 , +-26489 , +-3389 , +-15027 , +-15251 , +-19453 , +1757 , +-14595 , +-29699 , +3457 , +-15773 , +20007 , +27387 , +-18415 , +-3891 , +-3371 , +-26715 , +5497 , +-7993 , +-9843 , +-9389 , +18381 , +14499 , +16413 , +-29899 , +-16501 , +-20129 , +-15623 , +-19575 , +15923 , +-4087 , +-3311 , +-4779 , +9563 , +13767 , +21545 , +-10597 , +27213 , +7755 , +23475 , +-23273 , +1561 , +9413 , +-30685 , +-13457 , +14893 , +10085 , +10445 , +10485 , +-32395 , +-24251 , +-4555 , +-17451 , +-31253 , +-11533 , +-9487 , +19921 , +-3407 , +-28327 , +-21255 , +4991 , +31401 , +-3265 , +22397 , +-18955 , +-5235 , +-27331 , +-23221 , +-16627 , +-23155 , +-21447 , +-25709 , +-8173 , +20313 , +-25003 , +-19119 , +2821 , +7881 , +23159 , +-28901 , +-10685 , +-29207 , +9775 , +7037 , +8915 , +-11113 , +6713 , +-2101 , +32009 , +-359 , +1403 , +-1661 , +12237 , +-2505 , +-4503 , +-29669 , +-32179 , +23375 , +-5355 , +-2207 , +6195 , +32497 , +-30827 , +9807 , +-5023 , +23415 , +29443 , +1633 , +-8663 , +-7913 , +-21771 , +6003 , +18689 , +28421 , +-8847 , +17425 , +-24899 , +-12031 , +14697 , +-26025 , +31819 , +-26249 , +26033 , +-699 , +12517 , +12303 , +-10633 , +26265 , +12235 , +27857 , +14655 , +-12001 , +25727 , +6059 , +12113 , +25497 , +-7821 , +9375 , +3775 , +-3067 , +-7857 , +1095 , +-7729 , +31617 , +-28003 , +-7945 , +23805 , +-27997 , +-23035 , +8279 , +879 , +-29113 , +5897 , +375 , +12781 , +21747 , +10037 , +-20639 , +18521 , +-31579 , +993 , +-24511 , +-22103 , +307 , +3679 , +-26389 , +-13731 , +-31971 , +16055 , +11523 , +1399 , +16105 , +-26395 , +4999 , +28661 , +15609 , +11399 , +10225 , +25283 , +31205 , +-26855 , +28619 , +-3267 , +26445 , +-32593 , +-823 , +4639 , +-6853 , +2861 , +859 , +-30465 , +19443 , +-21507 , +-561 , +-29113 , +-25011 , +26691 , +13279 , +10153 , +31885 , +-5217 , +32465 , +4895 , +-4161 , +29021 , +-24057 , +28245 , +-23159 , +-2001 , +4129 , +-11087 , +-19325 , +-18327 , +29837 , +11201 , +-32491 , +21681 , +-9825 , +-10699 , +-9523 , +-17089 , +-15569 , +-31401 , +-5583 , +15759 , +5549 , +24837 , +1821 , +-21349 , +8633 , +-16859 , +3995 , +14231 , +-21447 , +7075 , +22329 , +-16603 , +19193 , +-25119 , +-14623 , +16135 , +-4679 , +-16197 , +17713 , +14439 , +-5173 , +30703 , +-173 , +-27009 , +28199 , +30243 , +-21927 , +1497 , +-29171 , +-11693 , +21775 , +13831 , +11 , +-15403 , +-7597 , +-551 , +-23641 , +-21313 , +-15371 , +-9707 , +-12433 , +10995 , +3587 , +-16723 , +-20083 , +26507 , +31409 , +-19843 , +-25367 , +23757 , +30363 , +11649 , +-25931 , +19123 , +-12875 , +-20089 , +6291 , +4565 , +4239 , +-27285 , +2851 , +-21277 , +19005 , +31447 , +23831 , +-32603 , +7839 , +26219 , +731 , +-17815 , +-5815 , +-3453 , +-30049 , +29955 , +-2863 , +-27547 , +-32527 , +-9153 , +25255 , +27651 , +-32289 , +1753 , +-9355 , +-27097 , +20093 , +-16641 , +-24599 , +31033 , +-16621 , +-3779 , +4639 , +1127 , +-5727 , +-1545 , +20329 , +22893 , +21763 , +-30359 , +-3407 , +-10045 , +-28541 , +22037 , +-26805 , +2133 , +2041 , +21953 , +13393 , +19647 , +27735 , +-19219 , +-6025 , +-4859 , +-30517 , +17615 , +20075 , +22731 , +-9133 , +-26685 , +-3677 , +10501 , +-12331 , +-31669 , +-1093 , +-11461 , +-8007 , +18047 , +-19895 , +-30917 , +-26627 , +-2035 , +-8903 , +12109 , +-23087 , +-26963 , +-21079 , +2809 , +-1617 , +20763 , +15667 , +-9175 , +12013 , +21129 , +15825 , +7929 , +9695 , +-15201 , +-3535 , +17371 , +8549 , +16367 , +1681 , +25693 , +16651 , +25327 , +25103 , +27223 , +-20581 , +-14487 , +-30585 , +8621 , +24119 , +3715 , +-23319 , +11391 , +-23563 , +15143 , +-11245 , +20959 , +-26127 , +4867 , +-14299 , +7955 , +-29723 , +-16897 , +23649 , +21321 , +21835 , +23609 , +12661 , +3527 , +741 , +-13709 , +-5533 , +13997 , +-28445 , +19735 , +8653 , +6701 , +7541 , +22953 , +-20523 , +-20937 , +26593 , +14011 , +22637 , +31427 , +-3043 , +-21903 , +31289 , +-25481 , +-21779 , +28521 , +-10789 , +-9745 , +20079 , +-22463 , +1497 , +17257 , +-25795 , +2443 , +-16665 , +21759 , +28163 , +-3523 , +28873 , +4971 , +-14961 , +10933 , +24487 , +6955 , +-1671 , +-32213 , +-12829 , +6729 , +-727 , +677 , +20089 , +-21363 , +1915 , +-3207 , +-10293 , +4659 , +30419 , +25149 , +-20733 , +-18133 , +18873 , +27201 , +-15383 , +4295 , +999 , +-3449 , +-27337 , +-24587 , +22509 , +6719 , +13683 , +-10751 , +27967 , +3003 , +-30647 , +-29247 , +6869 , +28129 , +20577 , +-17585 , +-4545 , +11313 , +9657 , +15435 , +22333 , +-13007 , +-4999 , +17027 , +-12329 , +3949 , +-7091 , +20791 , +22771 , +1257 , +-6079 , +17619 , +9079 , +25885 , +-2283 , +23831 , +-16941 , +19819 , +-25583 , +-15901 , +-25055 , +10259 , +20583 , +31327 , +24763 , +-3655 , +27905 , +20157 , +-27819 , +-27315 , +-15135 , +-29587 , +25749 , +-26999 , +32756 , +9427 , +4131 , +-15635 , +20073 , +7813 , +24401 , +8495 , +-29549 , +-12035 , +5663 , +-10435 , +28465 , +-7465 , +-23321 , +16043 , +-12205 , +-32129 , +-2459 , +-8269 , +-19283 , +-11913 , +-19879 , +-30041 , +8559 , +-1533 , +-13157 , +18411 , +23197 , +-6299 , +-18255 , +22129 , +8681 , +6295 , +6637 , +-3927 , +3591 , +-31357 , +18429 , +4095 , +-28021 , +3767 , +-32754 , +-6441 , +-12229 , +28579 , +6745 , +18677 , +-14871 , +11079 , +-25539 , +-17783 , +-1585 , +27511 , +-287 , +23959 , +13151 , +19085 , +575 , +30203 , +23969 , +32671 , +-6973 , +-17449 , +10763 , +-6851 , +22369 , +13459 , +-29735 , +-11615 , +1581 , +-13747 , +-23587 , +-16527 , +-29323 , +23001 , +13539 , +10731 , +13143 , +28469 , +14469 , +14249 , +15833 , +26755 , +-21381 , +2257 , +15747 , +14205 , +12413 , +13775 , +9331 , +31085 , +-29541 , +28561 , +-32263 , +7599 , +-18421 , +-17865 , +-17745 , +21145 , +30859 , +14929 , +-27379 , +-3835 , +12853 , +3223 , +-3455 , +7733 , +-37 , +8223 , +3347 , +23647 , +-21549 , +-29931 , +4455 , +-15981 , +-24225 , +20977 , +28013 , +-29371 , +28285 , +6455 , +-21657 , +-11215 , +-4551 , +-18011 , +12679 , +31461 , +-19563 , +12017 , +-16887 , +13999 , +-13105 , +-9983 , +-2099 , +-13031 , +30535 , +-30819 , +-5273 , +18907 , +-9265 , +18609 , +-13125 , +25439 , +27525 , +28923 , +-10983 , +-14935 , +-2769 , +-10421 , +-27183 , +31711 , +2827 , +-17865 , +-26807 , +12341 , +-11985 , +18511 , +-25449 , +31339 , +-13221 , +17119 , +25503 , +-2879 , +-13993 , +-19679 , +14751 , +20343 , +29889 , +10737 , +15441 , +6843 , +-17551 , +-32241 , +-24703 , +32551 , +-29875 , +-25395 , +-12513 , +-25419 , +3225 , +4431 , +-14883 , +-14273 , +-5157 , +17981 , +28745 , +24427 , +-13269 , +-4611 , +29789 , +27441 , +31247 , +23921 , +13727 , +-14141 , +-2353 , +-19165 , +28083 , +4371 , +-2991 , +21765 , +12661 , +-2363 , +-9869 , +-27991 , +-17773 , +21159 , +-6441 , +10745 , +-12889 , +-26969 , +-27571 , +24681 , +5315 , +-8367 , +-16741 , +21177 , +18073 , +23493 , +-16931 , +25889 , +29193 , +17445 , +-931 , +19989 , +17979 , +5793 , +9705 , +-19597 , +-20681 , +21209 , +-30805 , +-11705 , +-24833 , +27623 , +-18303 , +10481 , +23331 , +10445 , +8663 , +-25617 , +9953 , +11117 , +-32517 , +3341 , +-24143 , +-10743 , +-1797 , +-8933 , +-19863 , +18221 , +-13067 , +20521 , +22217 , +-23493 , +23289 , +19515 , +12193 , +27213 , +28503 , +27271 , +8539 , +-581 , +-30595 , +-11481 , +-7905 , +12309 , +9039 , +-9387 , +-14751 , +-2933 , +-22533 , +-8671 , +-18177 , +-1285 , +3923 , +18347 , +-27687 , +26963 , +-10069 , +19157 , +-11289 , +27545 , +26659 , +14725 , +-5169 , +-11681 , +26001 , +-2221 , +5123 , +30645 , +13255 , +32457 , +-4269 , +-23895 , +6263 , +-3819 , +-9209 , +8507 , +11403 , +10309 , +18811 , +20691 , +-21263 , +17405 , +-5583 , +-12995 , +-15355 , +10415 , +6763 , +-481 , +25435 , +26965 , +21317 , +15095 , +17943 , +-27739 , +587 , +-17021 , +-19501 , +22223 , +-25201 , +6861 , +7143 , +31917 , +19529 , +31379 , +8521 , +11651 , +-1049 , +17739 , +12003 , +30259 , +14755 , +-32623 , +11373 , +-30477 , +-22363 , +-28123 , +27587 , +-20339 , +27797 , +-24223 , +26299 , +28171 , +24753 , +20277 , +25987 , +-18181 , +29547 , +-873 , +-23181 , +-9699 , +-393 , +22401 , +6251 , +-10079 , +29555 , +26217 , +21667 , +-3617 , +13549 , +-13773 , +-13045 , +5005 , +-3065 , +28341 , +-5603 , +-12171 , +27277 , +24993 , +6969 , +-14413 , +-13943 , +2055 , +30843 , +-2455 , +-19363 , +27205 , +3347 , +-5131 , +8287 , +-12661 , +25119 , +22701 , +-3861 , +22979 , +25089 , +-4331 , +-22531 , +-4327 , +11317 , +3993 , +841 , +1511 , +-3663 , +14019 , +-8743 , +-20941 , +29105 , +-23055 , +11799 , +31653 , +12057 , +16019 , +30837 , +-28929 , +-2485 , +2013 , +-29063 , +30231 , +-13447 , +22275 , +-3495 , +6733 , +-9849 , +4593 , +-18663 , +30083 , +31065 , +1147 , +13591 , +17813 , +-5711 , +-16349 , +27439 , +30291 , +-12411 , +-443 , +25671 , +31223 , +5849 , +-809 , +31093 , +18461 , +19477 , +-12901 , +-14197 , +15163 , +1499 , +4057 , +-18637 , +-31589 , +30567 , +3223 , +-9591 , +28367 , +-15525 , +-21163 , +6963 , +9905 , +10019 , +17729 , +28147 , +17101 , +-26941 , +-23317 , +-1847 , +-16021 , +-7881 , +28805 , +-893 , +-19211 , +-2747 , +12441 , +23253 , +22267 , +24281 , +5435 , +4345 , +-18005 , +-27429 , +-7223 , +32443 , +-12353 , +12169 , +1823 , +-11747 , +771 , +-24757 , +14927 , +28519 , +4411 , +31759 , +-14889 , +-21055 , +26545 , +1309 , +-14495 , +-16307 , +-19173 , +-5769 , +31729 , +9149 , +-5607 , +-3931 , +1189 , +26729 , +24623 , +-25575 , +-25115 , +-20239 , +24383 , +22781 , +-16095 , +-17085 , +-18057 , +23187 , +10507 , +-9657 , +-18987 , +-19193 , +12361 , +-29209 , +277 , +-12083 , +-32081 , +22447 , +-8911 , +-12687 , +-26377 , +24039 , +18259 , +-3339 , +-2309 , +24355 , +19539 , +-19287 , +-23445 , +-16287 , +17321 , +-32639 , +-10235 , +4001 , +10469 , +-12307 , +19791 , +-11525 , +-13393 , +-22735 , +15565 , +-971 , +3637 , +5183 , +28343 , +-10015 , +-5589 , +-14835 , +24631 , +-10513 , +29755 , +21611 , +-3301 , +-2617 , +-27129 , +20577 , +-24559 , +15333 , +-18793 , +-19199 , +-23717 , +2283 , +2391 , +-12091 , +7183 , +-25541 , +-17519 , +16223 , +-27195 , +-22511 , +-18343 , +3095 , +-2861 , +18713 , +15127 , +-27483 , +15623 , +14983 , +-6033 , +17535 , +10975 , +-24913 , +-23101 , +-16195 , +5949 , +13343 , +-6365 , +-25493 , +7587 , +20277 , +-21549 , +11615 , +-793 , +28729 , +-7891 , +-26221 , +-21901 , +-12817 , +25647 , +-19201 , +4081 , +-21321 , +22885 , +-14349 , +-5235 , +-9693 , +4967 , +-10779 , +19115 , +9479 , +16337 , +31955 , +-26855 , +10785 , +-27979 , +1305 , +-20785 , +19743 , +-22373 , +-17981 , +-479 , +13891 , +22261 , +8559 , +5245 , +-21383 , +8983 , +12185 , +-21601 , +9195 , +6065 , +1665 , +-26301 , +-9955 , +-20285 , +24949 , +-23699 , +-12159 , +5655 , +16305 , +-20721 , +-28013 , +23615 , +-6213 , +16723 , +-909 , +1025 , +-9427 , +-13507 , +-779 , +28763 , +-11493 , +-18435 , +-27073 , +-29969 , +23779 , +-19057 , +-1059 , +20231 , +12171 , +12291 , +9569 , +29447 , +-11885 , +30509 , +-21137 , +-6047 , +-22707 , +-31007 , +21859 , +27159 , +443 , +-5719 , +1371 , +-11859 , +17891 , +-20995 , +-24361 , +27291 , +-15193 , +-6659 , +-30765 , +-939 , +23327 , +-22107 , +7253 , +-15695 , +29549 , +5003 , +9363 , +3309 , +32279 , +12303 , +24959 , +-17633 , +31715 , +22299 , +12771 , +21041 , +-20439 , +-6055 , +-26117 , +-8617 , +5039 , +-7709 , +-30835 , +23559 , +-24579 , +18823 , +-21891 , +-8335 , +2875 , +-8071 , +-17945 , +12919 , +3203 , +6537 , +32187 , +8491 , +-16199 , +-13855 , +29901 , +11449 , +18413 , +-29643 , +28535 , +-8979 , +13093 , +20099 , +-2395 , +26659 , +-9539 , +581 , +-10375 , +-5689 , +13633 , +-6351 , +-21669 , +-8385 , +18107 , +26723 , +-19309 , +9073 , +-16233 , +1061 , +-6301 , +8373 , +-5645 , +13851 , +30621 , +29003 , +26747 , +-9215 , +-15685 , +-22951 , +445 , +3299 , +-4489 , +27997 , +-4857 , +-9521 , +5095 , +-13273 , +-12873 , +-2281 , +20235 , +-21675 , +-4579 , +-20223 , +-29965 , +26437 , +-11573 , +18175 , +25163 , +-24691 , +-16789 , +623 , +-5003 , +-773 , +15907 , +5577 , +-12501 , +9731 , +22113 , +-19107 , +27787 , +-26177 , +26679 , +25225 , +-31311 , +-22175 , +26425 , +-7821 , +10711 , +18477 , +30665 , +-11971 , +18915 , +-5643 , +-29193 , +24259 , +-14201 , +10247 , +9435 , +2509 , +24275 , +25781 , +-22937 , +-2873 , +11599 , +9531 , +-25665 , +-18685 , +20889 , +23109 , +15897 , +10595 , +22639 , +20187 , +-32758 , +9625 , +-7083 , +30185 , +10091 , +-20515 , +24743 , +-12763 , +3999 , +-31959 , +6449 , +5267 , +11389 , +30697 , +-29115 , +32121 , +26015 , +-17095 , +23901 , +11225 , +-7621 , +23711 , +-27103 , +8037 , +-8837 , +59 , +-11247 , +-12035 , +-25769 , +29571 , +-2923 , +13725 , +-27157 , +-10625 , +-15983 , +24547 , +31565 , +-1155 , +26757 , +30717 , +5099 , +-6329 , +5667 , +16927 , +-22177 , +-5151 , +-29089 , +-5241 , +1477 , +21945 , +6423 , +21991 , +-23657 , +9061 , +-25831 , +-26263 , +9733 , +-16417 , +13257 , +-2789 , +-20023 , +14127 , +14127 , +-6667 , +16003 , +-8783 , +-9067 , +-25533 , +30863 , +-7739 , +31139 , +-30809 , +19293 , +-16373 , +-24087 , +12685 , +-21427 , +4635 , +773 , +7715 , +-16901 , +-20553 , +21811 , +-5165 , +-7125 , +-25973 , +14441 , +26933 , +-8179 , +-21409 , +21995 , +-9837 , +-29409 , +32725 , +-24981 , +8145 , +22149 , +-29799 , +-875 , +2037 , +-799 , +-6109 , +21551 , +26387 , +-15193 , +-18459 , +9653 , +18891 , +-23307 , +-22007 , +-20891 , +-5827 , +-28939 , +-28761 , +-8993 , +-24951 , +26023 , +31613 , +-3521 , +-29507 , +-16831 , +25643 , +10157 , +14673 , +265 , +-16155 , +12411 , +-13531 , +675 , +6315 , +-3909 , +10219 , +-21005 , +-1017 , +16477 , +-22479 , +-10635 , +24899 , +4791 , +-26169 , +-13557 , +-9447 , +-9551 , +18629 , +-16031 , +-24073 , +-31921 , +-14597 , +-20037 , +-6225 , +-11059 , +10733 , +-17579 , +28085 , +-25029 , +30537 , +-22217 , +-10799 , +31629 , +-2083 , +-20599 , +-23211 , +-28611 , +10517 , +-1673 , +29411 , +3671 , +1263 , +8059 , +13973 , +-7651 , +-10125 , +7743 , +13499 , +23063 , +24747 , +-6673 , +31511 , +9133 , +26137 , +6681 , +26769 , +29761 , +-29001 , +6647 , +14187 , +-18747 , +-24985 , +-5799 , +517 , +-27181 , +-8725 , +4587 , +14857 , +-17849 , +-8093 , +5401 , +2597 , +5713 , +24385 , +-31131 , +-26037 , +5401 , +25791 , +26173 , +-20897 , +-31031 , +31965 , +-10929 , +-26759 , +-24275 , +9427 , +-18323 , +-4209 , +-4915 , +12555 , +25817 , +6079 , +30333 , +24987 , +-4833 , +-3849 , +7549 , +-8897 , +9845 , +-14539 , +22025 , +-13627 , +-373 , +-6339 , +14459 , +-16109 , +14823 , +-10539 , +13529 , +17819 , +12983 , +-22665 , +17141 , +4429 , +-20431 , +23435 , +-6401 , +21527 , +28267 , +-10723 , +-7519 , +-20777 , +28327 , +19743 , +-5485 , +7129 , +-22471 , +-18927 , +14521 , +32199 , +12763 , +9545 , +21173 , +3369 , +31615 , +-26723 , +-8957 , +23639 , +-20307 , +7845 , +-11633 , +10741 , +-9379 , +-6287 , +-1843 , +-17941 , +-8377 , +5053 , +-6063 , +-4905 , +-6721 , +-8791 , +-32277 , +-12785 , +21011 , +-517 , +10293 , +-12273 , +-10665 , +-13113 , +-27207 , +28535 , +-16181 , +5301 , +-22661 , +29825 , +6561 , +4275 , +-3045 , +-29955 , +-22165 , +-29653 , +-30869 , +26817 , +32735 , +-25153 , +-25983 , +15015 , +4925 , +-2945 , +-24491 , +-28669 , +-28643 , +12197 , +32475 , +31903 , +29133 , +14531 , +19605 , +10539 , +-1237 , +6279 , +27307 , +-30149 , +-22541 , +15851 , +21385 , +30141 , +11941 , +-20497 , +-2575 , +-12555 , +10959 , +8659 , +-2917 , +235 , +2031 , +25039 , +-24001 , +32623 , +17605 , +6723 , +4667 , +-31093 , +-22735 , +23935 , +5541 , +-12167 , +30853 , +-3095 , +31969 , +31263 , +25185 , +-6975 , +30145 , +-12795 , +1031 , +12633 , +24081 , +11725 , +-10183 , +15041 , +-7497 , +-11731 , +-31863 , +-13807 , +-15537 , +-26267 , +9017 , +13073 , +4663 , +-25545 , +-19311 , +-30343 , +18737 , +-16033 , +11439 , +24743 , +2675 , +1933 , +22765 , +3547 , +-6581 , +-16933 , +8109 , +-6937 , +-727 , +25285 , +14773 , +26479 , +-10687 , +24993 , +-1013 , +-8549 , +17053 , +26263 , +19017 , +22355 , +-23367 , +-32481 , +18801 , +30965 , +29851 , +-13077 , +-5299 , +11917 , +22631 , +-9873 , +-5563 , +-25971 , +-22149 , +-30773 , +19889 , +19721 , +-16895 , +-26801 , +3771 , +13415 , +-12523 , +-26519 , +-2643 , +16543 , +-11445 , +32295 , +18383 , +12523 , +9681 , +-31197 , +23999 , +-31733 , +21001 , +-20729 , +-17853 , +749 , +-9317 , +30077 , +-18005 , +-8717 , +23311 , +4009 , +29091 , +-11101 , +-14617 , +-8415 , +-9851 , +24549 , +16693 , +20841 , +-11457 , +22195 , +16821 , +-6427 , +11423 , +1367 , +29789 , +-26543 , +12595 , +12067 , +9349 , +21185 , +-7013 , +-3417 , +-29587 , +-15855 , +32099 , +2151 , +-7835 , +8669 , +14429 , +21529 , +29785 , +19711 , +7287 , +16471 , +-16659 , +-15485 , +-14571 , +-8995 , +-19177 , +-8421 , +-10011 , +14135 , +13111 , +-4571 , +6971 , +-6649 , +-8023 , +27919 , +-2585 , +16049 , +24295 , +5729 , +19853 , +11671 , +7447 , +297 , +25215 , +10451 , +-22485 , +-31237 , +-14319 , +13679 , +-12429 , +8801 , +3189 , +30491 , +30137 , +4829 , +10517 , +16993 , +26325 , +-9385 , +21345 , +10599 , +2507 , +30235 , +17969 , +-1247 , +18271 , +24913 , +-25701 , +11525 , +32041 , +17139 , +20293 , +-22709 , +-10953 , +23361 , +325 , +27555 , +-9699 , +32197 , +4469 , +3687 , +-24689 , +-14145 , +11083 , +31325 , +22395 , +-11487 , +23091 , +-2333 , +-21599 , +-30455 , +15969 , +-5965 , +-19549 , +28343 , +31283 , +17683 , +-8275 , +-32249 , +-4097 , +12175 , +-20615 , +29285 , +-6029 , +-17867 , +-29189 , +26441 , +-18071 , +16453 , +-22167 , +3373 , +1341 , +21359 , +8155 , +8455 , +10923 , +-19571 , +22631 , +12861 , +-737 , +18641 , +-8023 , +-11487 , +23957 , +-26489 , +-22801 , +-4119 , +-13331 , +-21427 , +-5949 , +-31713 , +-30525 , +-7231 , +-20983 , +26281 , +24521 , +-22333 , +10387 , +25649 , +-19815 , +32297 , +-12225 , +24613 , +-9193 , +24825 , +-27767 , +-19411 , +-31679 , +-3045 , +-2905 , +-31195 , +-889 , +28315 , +27423 , +19603 , +15533 , +-15273 , +-7713 , +14751 , +-26607 , +319 , +-22061 , +-15219 , +-15465 , +20233 , +-18169 , +2479 , +17395 , +-25243 , +-29135 , +14567 , +-9083 , +25793 , +-28463 , +-13673 , +5811 , +31601 , +17865 , +-19683 , +31167 , +30073 , +12401 , +19653 , +-29921 , +-31055 , +-18383 , +12363 , +12121 , +24467 , +-5473 , +-19509 , +-31919 , +-933 , +29197 , +18493 , +-14805 , +-8489 , +-26459 , +28007 , +27555 , +-21875 , +-20475 , +29791 , +-4387 , +-25733 , +-19121 , +-14215 , +32193 , +-12469 , +-30263 , +-2359 , +5333 , +-9963 , +-26641 , +11279 , +9109 , +-26747 , +15633 , +24893 , +20809 , +-14937 , +-12443 , +-4513 , +31321 , +15889 , +-26463 , +-17375 , +32305 , +26781 , +-25325 , +-13377 , +-2677 , +-13655 , +-30915 , +19845 , +26961 , +12743 , +-28697 , +-583 , +8689 , +28919 , +-17735 , +33 , +10035 , +10335 , +16215 , +-3597 , +-30567 , +-28795 , +30447 , +27221 , +-31187 , +-17913 , +9821 , +-24249 , +-20003 , +20173 , +31931 , +29991 , +-24235 , +10697 , +-24961 , +-31061 , +18519 , +-8151 , +5387 , +-23733 , +-27759 , +-24811 , +-1333 , +13893 , +23539 , +23777 , +15309 , +-2029 , +19083 , +-11063 , +-15659 , +-27551 , +-15141 , +17699 , +-5383 , +32389 , +31157 , +26657 , +3511 , +-21389 , +-22903 , +-24829 , +-31343 , +28739 , +-21173 , +-14389 , +-741 , +10263 , +4795 , +-19073 , +25245 , +-865 , +32077 , +-15657 , +22569 , +26127 , +-13193 , +30589 , +30767 , +-20589 , +-8055 , +-18495 , +18073 , +12617 , +11019 , +30413 , +9823 , +30907 , +-24687 , +25447 , +11175 , +6103 , +7441 , +-30943 , +8783 , +21089 , +-6209 , +20501 , +-24299 , +25077 , +19301 , +-743 , +-32475 , +-30603 , +-459 , +-7045 , +-28109 , +-22265 , +23597 , +-29381 , +-7403 , +-24691 , +4833 , +4791 , +30421 , +3737 , +21979 , +-13581 , +-16811 , +-9237 , +13169 , +-22713 , +-20905 , +4959 , +8739 , +18327 , +-13785 , +26739 , +24165 , +14357 , +-1377 , +3637 , +12547 , +20839 , +-30253 , +7609 , +-18949 , +-19597 , +6937 , +17181 , +15301 , +21127 , +-2133 , +-5901 , +-11457 , +-28901 , +-30791 , +-26043 , +10231 , +-12283 , +20485 , +-11519 , +14599 , +-26831 , +19453 , +-2307 , +2669 , +2263 , +-953 , +-22679 , +-6423 , +23867 , +487 , +11973 , +19017 , +13531 , +-25131 , +15199 , +3147 , +18221 , +-4855 , +-24511 , +-7183 , +25557 , +14625 , +21685 , +-9385 , +15967 , +13683 , +27193 , +-13295 , +-907 , +-32603 , +12527 , +31743 , +-363 , +17091 , +17057 , +29347 , +-9393 , +16351 , +-21453 , +7935 , +1271 , +14111 , +-4711 , +26085 , +4579 , +-6565 , +2131 , +12505 , +7961 , +-30157 , +21601 , +5469 , +17811 , +12969 , +21443 , +-21289 , +-26127 , +-15307 , +15461 , +-19237 , +-20815 , +-671 , +28837 , +-28659 , +4325 , +22751 , +-25029 , +16243 , +-18577 , +9251 , +-17471 , +27733 , +-9029 , +-23945 , +-25443 , +-25977 , +15087 , +-27495 , +21381 , +6993 , +8871 , +-821 , +7023 , +-10051 , +25651 , +30579 , +-245 , +-28307 , +-31933 , +45 , +-2371 , +-25343 , +11561 , +31593 , +-19181 , +-12067 , +27023 , +-9091 , +-9797 , +-25203 , +32169 , +16447 , +-15615 , +-871 , +-1547 , +-11235 , +-19005 , +18143 , +-5521 , +-7751 , +-27671 , +-29849 , +-24247 , +-10501 , +-9893 , +32445 , +5155 , +-23891 , +6017 , +-25907 , +17347 , +15757 , +-22737 , +-30921 , +-22961 , +-18449 , +-14041 , +25123 , +3075 , +-23603 , +-4849 , +417 , +-2453 , +13155 , +22245 , +-14977 , +-9705 , +-7101 , +-9477 , +4509 , +17109 , +3825 , +-6037 , +2247 , +21101 , +13049 , +-26091 , +-24559 , +-28205 , +22407 , +1553 , +-23899 , +-29471 , +22659 , +-31831 , +-16855 , +12433 , +30755 , +8149 , +12171 , +25523 , +3329 , +-2005 , +10335 , +-11739 , +-23359 , +-19361 , +-31563 , +25231 , +29463 , +-10699 , +-5775 , +20111 , +25963 , +6143 , +-7387 , +21891 , +-19729 , +-28275 , +7525 , +435 , +16693 , +-9299 , +19109 , +30733 , +-19135 , +-5603 , +-11125 , +-13729 , +-30413 , +-11255 , +-4919 , +17421 , +-439 , +17147 , +5751 , +-22199 , +17287 , +-16295 , +-16405 , +-7987 , +-22325 , +-26273 , +1291 , +15 , +13917 , +-28271 , +12847 , +12797 , +-32493 , +7089 , +8045 , +28725 , +4833 , +20805 , +-899 , +-31047 , +16375 , +24699 , +-23285 , +23083 , +-16305 , +-22347 , +5515 , +-6015 , +-6701 , +15729 , +6299 , +-955 , +-14617 , +1993 , +-15151 , +2625 , +13709 , +15981 , +-7395 , +12737 , +-9485 , +27667 , +-10861 , +-10423 , +20369 , +-17291 , +5847 , +-11833 , +-30783 , +-14393 , +-5667 , +-23981 , +27859 , +-27469 , +21079 , +-20893 , +-1365 , +2247 , +-4735 , +-2943 , +-17967 , +32635 , +-15497 , +13193 , +-4591 , +-16483 , +-22249 , +-931 , +20879 , +1867 , +19027 , +-23015 , +-19363 , +26227 , +29957 , +-25385 , +22681 , +8133 , +-17327 , +729 , +25345 , +18469 , +3189 , +7243 , +14343 , +23731 , +18211 , +32119 , +7539 , +1843 , +-32677 , +29563 , +-1935 , +-14067 , +-3139 , +-24697 , +-32717 , +-15165 , +19053 , +15503 , +-17153 , +24043 , +18783 , +1927 , +11213 , +-6235 , +-32717 , +16921 , +24159 , +6547 , +4239 , +-14371 , +28625 , +-31919 , +9717 , +-20973 , +9665 , +-18833 , +13853 , +26071 , +5591 , +24293 , +-24121 , +-10017 , +-22555 , +531 , +-12769 , +30893 , +19583 , +-25555 , +20101 , +-18361 , +-16369 , +-11203 , +14067 , +-6023 , +-19853 , +-363 , +11981 , +-4483 , +-21747 , +-23091 , +23615 , +-12991 , +-32413 , +-11721 , +-16369 , +31001 , +16947 , +-14381 , +6645 , +-4619 , +-9975 , +29393 , +-4741 , +31 , +22109 , +14975 , +-16567 , +-8341 , +10787 , +29387 , +8971 , +-15113 , +10991 , +9263 , +-20037 , +-15521 , +-16003 , +25141 , +-32637 , +12659 , +4311 , +-6041 , +12305 , +-22667 , +29415 , +13769 , +11375 , +1741 , +8587 , +-8495 , +13659 , +-31681 , +25655 , +19939 , +-14559 , +11433 , +6663 , +-21951 , +31727 , +-9167 , +-1967 , +7565 , +-591 , +8205 , +21965 , +12213 , +-24469 , +-1367 , +-9699 , +29045 , +15621 , +621 , +-5651 , +11597 , +25781 , +-11541 , +10123 , +22261 , +-31545 , +18593 , +-8197 , +29017 , +4863 , +32551 , +-17261 , +-23795 , +23147 , +2541 , +-28397 , +-20151 , +189 , +24433 , +-25031 , +6497 , +-9175 , +-4359 , +8411 , +187 , +12719 , +-10041 , +-31359 , +13125 , +-3067 , +-16169 , +6271 , +-6031 , +6875 , +-19439 , +-30079 , +-31057 , +-21815 , +-26621 , +8627 , +7513 , +-31343 , +7451 , +-4275 , +-12995 , +-25847 , +-21669 , +-7757 , +-10361 , +-28057 , +16793 , +2825 , +-29893 , +-31713 , +-16595 , +-3001 , +-14029 , +-9157 , +-28629 , +21723 , +22163 , +-721 , +13351 , +1721 , +-19005 , +-17611 , +-26793 , +-28937 , +-16925 , +18465 , +-18845 , +4833 , +-22331 , +-22591 , +-31605 , +4499 , +-12441 , +17579 , +-29595 , +-17897 , +-13079 , +-16997 , +17179 , +13809 , +16391 , +-31929 , +-31211 , +-16317 , +-7411 , +24253 , +15173 , +-7845 , +12883 , +30773 , +-29753 , +-22831 , +22835 , +-2449 , +-20177 , +12319 , +-25213 , +-12669 , +-13005 , +26549 , +393 , +-9151 , +-15385 , +16535 , +21623 , +-9469 , +-28551 , +20589 , +26977 , +22279 , +3171 , +7717 , +-21321 , +12109 , +-24281 , +-771 , +-12233 , +-16413 , +-9087 , +-13265 , +-14991 , +19657 , +24363 , +29427 , +-16719 , +-15045 , +7687 , +28967 , +28287 , +30621 , +28129 , +23649 , +15767 , +-12867 , +-11871 , +-24185 , +-20641 , +-22083 , +777 , +25319 , +-21281 , +31583 , +11749 , +-13617 , +-4549 , +-23067 , +-10803 , +-21849 , +15013 , +20065 , +24147 , +-16761 , +-18721 , +10903 , +-21055 , +27985 , +-1493 , +26699 , +-7601 , +23873 , +8647 , +17693 , +-28195 , +-19179 , +-25889 , +28391 , +-29657 , +24981 , +-9457 , +-15221 , +-26751 , +14261 , +-16557 , +-28847 , +8209 , +19237 , +-13951 , +-13123 , +20859 , +20849 , +-3005 , +-24347 , +-27863 , +27031 , +21901 , +-30383 , +-8455 , +8217 , +18323 , +26699 , +-5511 , +1949 , +20553 , +183 , +-25961 , +-16895 , +32593 , +-1423 , +-17943 , +-18959 , +31351 , +1823 , +26967 , +-25341 , +-3923 , +16269 , +17235 , +-18863 , +-21635 , +20867 , +-22113 , +393 , +-2301 , +-27105 , +13685 , +-31095 , +-26517 , +-22359 , +-15803 , +-25219 , +2777 , +-27153 , +2801 , +-29847 , +15095 , +15385 , +20865 , +19281 , +30939 , +-3321 , +2393 , +-9271 , +-10107 , +5415 , +-1035 , +-5881 , +-18213 , +-32573 , +-8161 , +11145 , +-22245 , +-22037 , +-9301 , +21281 , +25813 , +21695 , +-6235 , +-10605 , +7783 , +-28595 , +-28909 , +32683 , +-12307 , +2531 , +43 , +3031 , +-13629 , +20723 , +-6135 , +-18117 , +15727 , +9053 , +4325 , +6221 , +-6099 , +23121 , +15055 , +-1555 , +-18481 , +-28765 , +9957 , +-11783 , +32589 , +5027 , +19723 , +26215 , +-30807 , +19317 , +13353 , +8927 , +11891 , +4075 , +-6957 , +-5931 , +19135 , +9435 , +28311 , +-19435 , +-28519 , +24821 , +-2143 , +-5141 , +-21761 , +-25055 , +20221 , +-18257 , +17499 , +2641 , +31059 , +13799 , +-19079 , +-3875 , +12305 , +-10031 , +-27901 , +-27557 , +-13515 , +-7283 , +-11923 , +12531 , +-29327 , +15523 , +-18561 , +-16585 , +-13577 , +-31959 , +22333 , +-28797 , +-7517 , +-18603 , +-14999 , +21967 , +-32331 , +20369 , +-14475 , +-16895 , +10771 , +4639 , +12289 , +8405 , +29425 , +-29917 , +-24119 , +28963 , +-1001 , +30531 , +-3797 , +-1597 , +-29805 , +-1343 , +-9195 , +997 , +19951 , +-757 , +20603 , +-545 , +-20243 , +-32551 , +-1701 , +14991 , +-12097 , +20677 , +18983 , +-7887 , +-4167 , +-10145 , +-16185 , +9649 , +-3947 , +-32309 , +-27121 , +24973 , +19227 , +28627 , +-27473 , +9505 , +29541 , +-4993 , +20153 , +-9845 , +11161 , +25653 , +27021 , +2813 , +-18415 , +17735 , +14423 , +-3181 , +28197 , +-25579 , +23813 , +24237 , +-27301 , +-15465 , +-22593 , +31947 , +4893 , +645 , +-4893 , +-16417 , +-9997 , +27877 , +2419 , +22567 , +-29377 , +-7643 , +-12775 , +27017 , +26221 , +32691 , +2201 , +-28315 , +-20299 , +24599 , +25543 , +-11029 , +-2489 , +-375 , +22017 , +-28669 , +16913 , +5899 , +-10707 , +31885 , +29929 , +23289 , +3877 , +27213 , +9549 , +-11727 , +-13897 , +-16581 , +413 , +16539 , +-15071 , +22615 , +11469 , +26699 , +-18949 , +-7411 , +-29283 , +-32752 , +9149 , +18173 , +-30633 , +-18791 , +-9037 , +14433 , +6915 , +6657 , +14445 , +-29985 , +-11233 , +-17429 , +-7997 , +23775 , +-25641 , +27167 , +22853 , +-19609 , +-14403 , +-11371 , +-715 , +-24971 , +28933 , +29215 , +-21499 , +32203 , +-31435 , +4211 , +-9151 , +32345 , +-30363 , +17607 , +19733 , +-6139 , +-30735 , +-18453 , +3647 , +21515 , +8371 , +-28451 , +5767 , +25559 , +13247 , +-8983 , +8373 , +4179 , +7829 , +19507 , +1807 , +10699 , +989 , +6881 , +21837 , +8253 , +5529 , +32417 , +18705 , +-21451 , +23017 , +28879 , +-1827 , +28705 , +-7627 , +11527 , +-9839 , +10797 , +-4879 , +15419 , +23135 , +-29027 , +-5689 , +25679 , +-12479 , +25243 , +-10141 , +21551 , +25077 , +-4199 , +-1643 , +25705 , +16759 , +26405 , +19225 , +17475 , +-14353 , +20291 , +-14901 , +-5297 , +-12491 , +-28863 , +-10665 , +-22641 , +-5185 , +13585 , +2175 , +-24575 , +-14815 , +-29913 , +23751 , +-23621 , +19199 , +-26939 , +16561 , +-25209 , +-5751 , +-26917 , +-24199 , +-31757 , +-26507 , +-25759 , +4421 , +7665 , +-9879 , +-13015 , +30437 , +29675 , +29451 , +32311 , +16393 , +17755 , +6495 , +-25951 , +-29199 , +23265 , +-17195 , +-28195 , +21681 , +3299 , +-18509 , +20639 , +-6941 , +-10599 , +-28143 , +25393 , +-10273 , +19889 , +-27565 , +-10169 , +-10639 , +22113 , +-8159 , +-933 , +12821 , +-5127 , +18393 , +-31357 , +-14159 , +22027 , +-25457 , +18377 , +10947 , +8691 , +-21885 , +2565 , +31781 , +-18185 , +-25581 , +-27853 , +1853 , +-5411 , +-1223 , +-30647 , +-1353 , +17671 , +2437 , +12949 , +18881 , +-29181 , +-22901 , +-14703 , +9915 , +15785 , +31977 , +17207 , +4215 , +18867 , +-21069 , +-32281 , +-5655 , +7891 , +-19859 , +-29015 , +5225 , +7753 , +-21107 , +-7907 , +1123 , +30719 , +-7835 , +-29247 , +18577 , +-18143 , +-31325 , +2001 , +31667 , +-6349 , +-19639 , +-29793 , +6345 , +32681 , +-24795 , +-13979 , +-22071 , +13309 , +-9535 , +-5977 , +18649 , +-17841 , +-11287 , +31745 , +-5119 , +-30095 , +19093 , +32137 , +29549 , +-8309 , +-2705 , +-5221 , +-3557 , +-10709 , +3261 , +7739 , +10525 , +-289 , +-3103 , +27883 , +-21181 , +15695 , +-18095 , +15615 , +-20635 , +19413 , +-23283 , +4213 , +-8439 , +-17523 , +-29291 , +-21161 , +24491 , +-14085 , +11113 , +-2683 , +18535 , +-8937 , +8951 , +-30955 , +-22979 , +4843 , +-743 , +-17109 , +30911 , +-26199 , +-14837 , +10575 , +-24239 , +19269 , +-29983 , +7493 , +15579 , +20363 , +28041 , +23909 , +24581 , +9141 , +-30925 , +-27789 , +-21013 , +-8569 , +20825 , +-26117 , +-16035 , +2279 , +-13017 , +14369 , +-8051 , +-7437 , +8579 , +26113 , +-3255 , +28055 , +-6277 , +-20095 , +13245 , +4267 , +-8899 , +-9299 , +-28257 , +13701 , +14231 , +18063 , +16361 , +-20971 , +18915 , +19329 , +25881 , +16505 , +-17269 , +4619 , +26081 , +12061 , +2553 , +-193 , +-15775 , +5445 , +31247 , +21893 , +-545 , +-4041 , +21545 , +7417 , +-30461 , +-21311 , +32643 , +-5047 , +9863 , +4449 , +19015 , +-22011 , +-15755 , +23759 , +-28945 , +-8585 , +13279 , +28959 , +-4017 , +-20989 , +-7917 , +-7339 , +25603 , +5105 , +-16807 , +-14467 , +-15515 , +30167 , +-24795 , +-28347 , +-25837 , +10079 , +20947 , +-7919 , +-3881 , +-2383 , +32217 , +-27239 , +14373 , +22839 , +-17271 , +-1543 , +11541 , +20743 , +-7101 , +26705 , +-12837 , +-23887 , +-471 , +14551 , +10941 , +29595 , +-8607 , +21877 , +17545 , +-5933 , +-10555 , +18905 , +-20079 , +-8593 , +31771 , +10261 , +16675 , +20323 , +-2605 , +6579 , +21887 , +-31275 , +-12229 , +-2739 , +11341 , +-21511 , +-14025 , +-20317 , +-12903 , +-10909 , +-28805 , +1851 , +-9909 , +6379 , +-5061 , +11631 , +-5349 , +-11527 , +20341 , +-6135 , +-13041 , +-22433 , +13969 , +-8097 , +12395 , +25019 , +26031 , +-29465 , +9519 , +14143 , +27475 , +-31155 , +2065 , +-23271 , +26267 , +-24305 , +7917 , +24639 , +-30719 , +-23661 , +-25661 , +-31797 , +17545 , +-3905 , +15919 , +-28971 , +-19579 , +-235 , +19293 , +19149 , +3771 , +-3005 , +5253 , +12873 , +-13007 , +15681 , +-15391 , +28777 , +20567 , +31465 , +-22489 , +4259 , +-25663 , +-25843 , +-18819 , +30507 , +3943 , +30221 , +31477 , +-17993 , +-25517 , +-14093 , +12163 , +-3861 , +27619 , +-7155 , +12661 , +6689 , +29045 , +-6661 , +-29329 , +-24121 , +-8537 , +-9391 , +-9767 , +11839 , +-3563 , +-25937 , +6117 , +-15575 , +6269 , +-19123 , +-11527 , +-10943 , +-10099 , +21541 , +14001 , +26299 , +-32497 , +22905 , +21331 , +-15339 , +4513 , +-24839 , +18631 , +-1675 , +22003 , +-22445 , +-28657 , +-26501 , +-21637 , +-23985 , +6979 , +-6503 , +27049 , +1639 , +-31745 , +3057 , +25769 , +-17705 , +103 , +23209 , +-32107 , +1859 , +22167 , +18117 , +-9431 , +13763 , +-31071 , +9849 , +23043 , +14465 , +25339 , +21255 , +23385 , +11217 , +-12415 , +-15845 , +15149 , +3267 , +-8465 , +-20587 , +20231 , +31811 , +-31031 , +28655 , +16943 , +-6481 , +8675 , +783 , +19553 , +-6165 , +31063 , +32669 , +15117 , +17401 , +-29711 , +-4383 , +-15101 , +19481 , +-13255 , +-20203 , +8373 , +2135 , +3289 , +573 , +21741 , +-597 , +-11357 , +-18551 , +15359 , +-6005 , +19201 , +-13025 , +-20085 , +17415 , +-30225 , +-9091 , +-7511 , +-2723 , +27255 , +4937 , +14507 , +-3047 , +-22877 , +-15693 , +-10667 , +18079 , +29687 , +8005 , +8075 , +11093 , +21867 , +18751 , +17299 , +-14805 , +23519 , +13671 , +16843 , +10937 , +-29415 , +-29069 , +24795 , +6877 , +-22219 , +9931 , +-28557 , +20937 , +1705 , +4847 , +-21113 , +-19551 , +-17237 , +1103 , +8441 , +14739 , +-11201 , +-869 , +-12065 , +-3479 , +-18535 , +-3677 , +-9165 , +-4183 , +-26585 , +31143 , +6415 , +30507 , +765 , +6199 , +-12957 , +20779 , +23507 , +17285 , +-26065 , +-29977 , +30335 , +-17851 , +4405 , +-31301 , +1763 , +16889 , +-4807 , +-21845 , +8047 , +26065 , +25785 , +-25977 , +30231 , +19975 , +-28903 , +12929 , +-22587 , +18343 , +21609 , +15685 , +12891 , +5373 , +-8297 , +10375 , +23841 , +-24999 , +2855 , +-26833 , +-14395 , +7027 , +-16277 , +10203 , +-10293 , +19775 , +-16069 , +18443 , +-17265 , +-8121 , +-11215 , +27561 , +16819 , +-28799 , +-13477 , +-32473 , +10269 , +8099 , +23923 , +-1507 , +15727 , +-13563 , +18845 , +16471 , +-5637 , +13809 , +-16997 , +-4239 , +27967 , +-31873 , +30339 , +-21771 , +-32549 , +-23829 , +-27649 , +-5911 , +-26101 , +28011 , +-27143 , +-30485 , +-32355 , +-21363 , +31967 , +-28725 , +31333 , +-24309 , +-31665 , +-8287 , +-20927 , +8737 , +28765 , +17513 , +6531 , +-4759 , +-6849 , +-21233 , +-21261 , +16179 , +-15989 , +-5863 , +-8637 , +19289 , +-3347 , +-15695 , +24327 , +-20837 , +-17059 , +-12993 , +12847 , +28791 , +-4899 , +-16247 , +-10245 , +-21127 , +-5713 , +-18365 , +-14217 , +-32223 , +9991 , +12327 , +-2959 , +20017 , +-7095 , +5269 , +-31501 , +-6009 , +-18239 , +-16481 , +-28363 , +-9355 , +-7719 , +15021 , +799 , +16793 , +-13361 , +-25457 , +25145 , +23351 , +-13069 , +-9201 , +-17113 , +29713 , +-29863 , +-4329 , +27037 , +12731 , +1301 , +-29119 , +-11559 , +-7563 , +-19727 , +29929 , +3745 , +-7035 , +-16987 , +30163 , +28845 , +-16883 , +-17007 , +15415 , +-11087 , +-669 , +-781 , +4447 , +-10557 , +31211 , +-19299 , +32447 , +-19871 , +3437 , +15153 , +9351 , +-29 , +24045 , +-24869 , +-25403 , +2159 , +-12285 , +-24193 , +-15629 , +-6021 , +14771 , +-28801 , +14357 , +14525 , +28105 , +-5917 , +31571 , +30117 , +14249 , +21793 , +28421 , +-8875 , +-8273 , +-9911 , +-23969 , +-993 , +-12285 , +-14139 , +14195 , +-24721 , +29165 , +26761 , +-16935 , +26449 , +-9287 , +-17197 , +-9791 , +-20893 , +26369 , +31071 , +3979 , +77 , +-14449 , +-29667 , +-29731 , +-10569 , +-17743 , +14961 , +16451 , +-11065 , +-6385 , +18655 , +11323 , +14613 , +1291 , +9549 , +10971 , +-16863 , +-6259 , +-29769 , +7385 , +-24239 , +32103 , +-25239 , +-14541 , +2147 , +25381 , +-7503 , +15933 , +32105 , +7525 , +12067 , +13623 , +-18115 , +-27723 , +-8129 , +2671 , +29823 , +-7191 , +28351 , +-6189 , +30469 , +9709 , +-13765 , +-12279 , +-25123 , +14373 , +30573 , +-4093 , +4029 , +11325 , +-5915 , +3363 , +22523 , +27787 , +2625 , +26567 , +-24567 , +12769 , +30183 , +-5529 , +-16527 , +25055 , +19771 , +-727 , +23101 , +28121 , +11093 , +-10755 , +-14845 , +18981 , +10813 , +-25289 , +-4785 , +5619 , +29349 , +16029 , +-5729 , +-29781 , +19993 , +16139 , +-29729 , +-11839 , +13245 , +28289 , +-29863 , +-15351 , +-14461 , +-12603 , +-27853 , +19869 , +17379 , +-31119 , +-6551 , +-5345 , +17943 , +14479 , +-11715 , +-4695 , +29899 , +-26441 , +-22729 , +-27119 , +-1699 , +-27751 , +28821 , +-24367 , +17295 , +-7129 , +8779 , +23121 , +4035 , +27933 , +30073 , +-11321 , +10159 , +12065 , +11101 , +20627 , +-10851 , +13147 , +-4399 , +-31735 , +-32233 , +17033 , +-29627 , +-18475 , +29737 , +-16229 , +-18387 , +29397 , +11285 , +-31543 , +7175 , +-18335 , +20621 , +1583 , +-7737 , +30775 , +-22937 , +-19239 , +30161 , +18117 , +2777 , +-10387 , +-18565 , +-2557 , +-6099 , +-15051 , +20469 , +9941 , +7423 , +-11077 , +26577 , +27349 , +-12817 , +-10527 , +29425 , +3763 , +6623 , +30333 , +19197 , +9485 , +10403 , +21609 , +20581 , +-5693 , +-29633 , +14373 , +-13869 , +5589 , +27805 , +11491 , +14881 , +15285 , +30155 , +-7381 , +-6957 , +-15325 , +165 , +12011 , +14613 , +-23679 , +28185 , +-1517 , +23335 , +24497 , +11487 , +-31833 , +-31649 , +32357 , +25001 , +17251 , +29083 , +-3073 , +-22047 , +18883 , +-26559 , +-21785 , +-3873 , +29867 , +22955 , +-17573 , +-12381 , +20595 , +-4823 , +27605 , +28425 , +-633 , +14453 , +-28201 , +25735 , +-3467 , +20137 , +27465 , +-32419 , +-3435 , +-12865 , +-30643 , +3159 , +4365 , +-11651 , +-8803 , +24057 , +6269 , +-17669 , +-26785 , +22339 , +12041 , +28555 , +-15235 , +-21791 , +3827 , +27199 , +29307 , +28903 , +-21573 , +13531 , +20947 , +-763 , +-25681 , +-27315 , +31439 , +28485 , +7683 , +8355 , +27353 , +-2247 , +5487 , +27787 , +-11687 , +16835 , +-12477 , +-26817 , +19213 , +2365 , +-4353 , +24073 , +-28965 , +16439 , +22121 , +31281 , +18229 , +-12619 , +25133 , +31871 , +3297 , +23001 , +21227 , +-8409 , +-20385 , +3629 , +15059 , +-31155 , +25275 , +-7093 , +18371 , +26355 , +-10523 , +22559 , +-15917 , +-29573 , +-3193 , +2711 , +-27017 , +13457 , +11617 , +17893 , +-14317 , +14775 , +8741 , +-9169 , +-26091 , +-31705 , +-29761 , +22727 , +-11897 , +-18085 , +9279 , +-1045 , +-7633 , +-7683 , +-28119 , +30963 , +24613 , +15973 , +-2741 , +-4337 , +-29211 , +393 , +11289 , +5245 , +24303 , +10877 , +27011 , +3139 , +-14629 , +13415 , +13133 , +-8605 , +-21265 , +-11019 , +24809 , +2713 , +23611 , +-32423 , +13003 , +11659 , +-14285 , +-3647 , +6727 , +12427 , +32189 , +23373 , +18915 , +-1083 , +-26411 , +-26493 , +-22991 , +8955 , +-26981 , +-1963 , +12073 , +-31549 , +23541 , +-5245 , +31233 , +21555 , +18589 , +18605 , +21375 , +-31451 , +-20801 , +24241 , +8921 , +4837 , +-30963 , +-29255 , +9481 , +6513 , +-18081 , +-24925 , +6309 , +14633 , +-11839 , +-28411 , +29241 , +15635 , +31249 , +6043 , +-20199 , +31619 , +-28651 , +31557 , +-4925 , +-5791 , +12309 , +7295 , +12973 , +22491 , +-29713 , +19285 , +-13147 , +-11109 , +-6477 , +-21025 , +1957 , +-23421 , +-29509 , +-4809 , +-27863 , +-12059 , +8253 , +-7951 , +4365 , +-16585 , +4717 , +-3817 , +-4643 , +-13491 , +-24309 , +-6503 , +6581 , +23573 , +12417 , +-7605 , +-18027 , +27337 , +23165 , +-19875 , +26939 , +-2903 , +-30465 , +15949 , +9587 , +20279 , +30205 , +16747 , +30463 , +-10523 , +26483 , +3009 , +-2595 , +-4005 , +32764 , +-32357 , +-17107 , +-11229 , +-1041 , +4467 , +-6273 , +7397 , +-19727 , +-10129 , +-21577 , +-28637 , +-18927 , +-21161 , +12883 , +6505 , +25183 , +18957 , +-17577 , +28687 , +-16385 , +19337 , +11415 , +24423 , +-31283 , +16455 , +-24429 , +10617 , +-26267 , +32075 , +3537 , +-959 , +25547 , +-3695 , +-24909 , +-3747 , +-11655 , +-20471 , +-11823 , +-28599 , +23797 , +26637 , +-1333 , +19225 , +-6411 , +-31655 , +15275 , +-4687 , +-10519 , +10371 , +-29003 , +30587 , +14623 , +-15115 , +-1855 , +22427 , +18257 , +31075 , +31765 , +-31823 , +11459 , +-575 , +-7239 , +24841 , +24285 , +18883 , +-173 , +-1963 , +25145 , +-19767 , +26495 , +27625 , +21573 , +-18333 , +25253 , +10347 , +4443 , +14145 , +589 , +-14317 , +20301 , +15019 , +4355 , +8285 , +-31603 , +9347 , +-5983 , +29251 , +-3141 , +25517 , +-14031 , +13561 , +-19523 , +28949 , +-14271 , +29473 , +3167 , +19231 , +-3909 , +12925 , +-159 , +10145 , +-21699 , +-8649 , +22035 , +-27553 , +1777 , +11145 , +2931 , +-16899 , +-1303 , +28925 , +27321 , +5497 , +14321 , +-6107 , +-17797 , +3107 , +-23833 , +-11823 , +-13255 , +7705 , +3995 , +-2875 , +18561 , +-7369 , +21533 , +28409 , +3971 , +24215 , +19611 , +20803 , +-31201 , +17541 , +-6217 , +-607 , +10127 , +28405 , +-11421 , +-16417 , +13167 , +14463 , +-7633 , +-26401 , +-12193 , +-2599 , +-16081 , +-19387 , +31511 , +17861 , +5699 , +-32589 , +6653 , +28563 , +-24833 , +-7547 , +-29375 , +-30697 , +26617 , +30977 , +4983 , +-27365 , +-19293 , +28185 , +23205 , +26465 , +-20575 , +-14185 , +-27161 , +25361 , +31657 , +-18207 , +28543 , +-4425 , +-17199 , +-10197 , +12143 , +-16195 , +12909 , +-11733 , +-4461 , +-15529 , +31077 , +29019 , +11829 , +-14579 , +-28911 , +-31323 , +-21459 , +-17501 , +11401 , +-25173 , +-13459 , +-22629 , +-28029 , +2667 , +26915 , +5671 , +-8791 , +9611 , +30285 , +13221 , +31601 , +20991 , +11729 , +20629 , +-10373 , +-20657 , +16151 , +787 , +-9893 , +-2231 , +-15075 , +-24883 , +19199 , +32309 , +25107 , +15223 , +-16513 , +-12903 , +22387 , +461 , +4731 , +-11931 , +-3437 , +-2299 , +6123 , +4013 , +9671 , +-315 , +-27523 , +-7445 , +-23057 , +19361 , +5743 , +11941 , +25751 , +-2551 , +-14625 , +-31045 , +-16761 , +-3633 , +-13399 , +16651 , +14055 , +6675 , +20925 , +27061 , +5831 , +-29759 , +-10247 , +4561 , +-14013 , +1669 , +-11649 , +-3937 , +19483 , +-29619 , +16011 , +-12465 , +-29501 , +-2257 , +16081 , +-18649 , +2559 , +-16909 , +22609 , +23111 , +-28161 , +-24829 , +26541 , +-20767 , +29939 , +27101 , +-6393 , +13541 , +1055 , +-24805 , +-25519 , +-8629 , +-19073 , +7897 , +18479 , +4537 , +-15409 , +-25157 , +27971 , +-16437 , +-23757 , +6239 , +-14317 , +703 , +8773 , +-687 , +-28845 , +16559 , +-28757 , +17807 , +5319 , +18517 , +-17349 , +13169 , +-8553 , +24623 , +12677 , +-4049 , +-11995 , +-16313 , +29943 , +-16429 , +-32403 , +28261 , +-20629 , +945 , +18385 , +-2875 , +-28345 , +-15521 , +11131 , +-5289 , +-13553 , +-3027 , +15923 , +-13459 , +-3457 , +14111 , +-32589 , +1525 , +11301 , +17761 , +-6271 , +-11205 , +29049 , +-15547 , +-26551 , +-17643 , +-13453 , +-20043 , +-2123 , +14493 , +22943 , +13871 , +-24643 , +-27533 , +32191 , +-3783 , +-10609 , +19043 , +985 , +-25759 , +-25131 , +1971 , +-24871 , +8359 , +-3427 , +-19767 , +-28257 , +-3451 , +21921 , +30055 , +-9059 , +-14245 , +13359 , +16749 , +-14357 , +-31121 , +18807 , +-14333 , +8681 , +-31905 , +-28573 , +23387 , +2629 , +-7141 , +-8715 , +-19739 , +-24155 , +18017 , +-17383 , +2565 , +30135 , +29103 , +-25343 , +-28335 , +453 , +18107 , +-259 , +-21949 , +7127 , +-23181 , +-26419 , +-6793 , +-22975 , +-32403 , +9857 , +15193 , +24001 , +-8993 , +-4403 , +30571 , +7191 , +-7653 , +-26399 , +19951 , +26395 , +-11381 , +27329 , +5163 , +-23469 , +2585 , +-30689 , +-27879 , +-14065 , +-17861 , +18865 , +-4961 , +-8445 , +-18595 , +17669 , +2893 , +13653 , +-4643 , +7399 , +-27501 , +-27071 , +-13435 , +-19927 , +-10895 , +22825 , +20099 , +-13057 , +-24133 , +-22225 , +-3363 , +-10527 , +-25141 , +-10161 , +13931 , +-17195 , +-5449 , +5877 , +-5295 , +-28079 , +-21233 , +26643 , +4341 , +3217 , +26125 , +10689 , +27513 , +28263 , +-26793 , +2635 , +-28241 , +-863 , +-22229 , +-15919 , +-22121 , +-27949 , +-29917 , +26709 , +-29873 , +28859 , +1893 , +-16287 , +-32111 , +-10225 , +16477 , +19987 , +26283 , +-27937 , +20729 , +-27973 , +16631 , +-1439 , +-30887 , +17651 , +14797 , +-27053 , +12813 , +-8911 , +1025 , +-4911 , +30669 , +20201 , +32477 , +-25945 , +12719 , +17947 , +-14705 , +19505 , +16351 , +-16013 , +27439 , +-20815 , +20693 , +24795 , +1577 , +-3553 , +-27883 , +16533 , +-6593 , +-3185 , +18781 , +-18217 , +2557 , +-22533 , +-18077 , +-9763 , +8369 , +-8281 , +27917 , +-893 , +-13851 , +-1551 , +15907 , +16221 , +-13485 , +-24149 , +9361 , +18517 , +30047 , +10741 , +16149 , +8885 , +-4587 , +-23665 , +3711 , +-28209 , +-25963 , +17087 , +23397 , +-20473 , +24341 , +11667 , +-16809 , +12921 , +-4781 , +19155 , +17057 , +10497 , +-9835 , +10559 , +7037 , +-27931 , +-20971 , +-26757 , +-7225 , +-24615 , +-19197 , +1119 , +24639 , +-2645 , +-20233 , +16331 , +15415 , +-11703 , +15345 , +-19447 , +-18221 , +25195 , +1219 , +-20579 , +-14661 , +9369 , +-23781 , +-10337 , +-32171 , +-20273 , +14825 , +23189 , +-30077 , +-17261 , +-24475 , +-1081 , +10701 , +-19577 , +18815 , +-28899 , +-13781 , +-17269 , +-24101 , +-657 , +-21719 , +-31923 , +7239 , +26983 , +21171 , +-24991 , +-23375 , +-29491 , +-20419 , +-5663 , +-20057 , +-6547 , +27271 , +-20871 , +-21437 , +-12191 , +20425 , +-4853 , +-6481 , +5877 , +24695 , +-22851 , +-9965 , +10227 , +27759 , +31131 , +-8937 , +29317 , +-17733 , +27045 , +8143 , +3981 , +-19519 , +11885 , +573 , +19061 , +1529 , +-8915 , +-24503 , +8843 , +15665 , +18271 , +-18899 , +23773 , +17465 , +-6697 , +-25475 , +16009 , +-14047 , +-22437 , +-28013 , +-30817 , +-1043 , +-32331 , +3983 , +-14737 , +-24623 , +2129 , +20937 , +-25753 , +-6419 , +855 , +-6965 , +1387 , +4213 , +15419 , +21965 , +20137 , +16763 , +27867 , +-12635 , +-19981 , +-28641 , +-24041 , +-12473 , +20637 , +-18109 , +-5401 , +-16967 , +-28471 , +30925 , +-21519 , +-31609 , +31815 , +-939 , +28583 , +-2103 , +14319 , +26725 , +-29993 , +14471 , +11121 , +-6101 , +28111 , +-12607 , +-3657 , +16309 , +-1563 , +-19997 , +-22095 , +22695 , +-19555 , +-2121 , +-16457 , +-16013 , +10553 , +25061 , +-14499 , +-26861 , +26067 , +-32283 , +32205 , +-11971 , +-14085 , +-21637 , +-29541 , +26913 , +6851 , +28079 , +9505 , +21145 , +13407 , +-13759 , +3155 , +-16407 , +5437 , +-7263 , +12063 , +-22541 , +-17253 , +22897 , +22331 , +1773 , +-24671 , +2927 , +6275 , +-11871 , +5107 , +31479 , +-28979 , +4889 , +-31023 , +-32013 , +1095 , +11491 , +-10069 , +-24993 , +6217 , +-20033 , +-19141 , +30003 , +32435 , +-11555 , +16407 , +-6171 , +-4163 , +-10347 , +-4653 , +20827 , +24663 , +-26723 , +-7791 , +14183 , +6907 , +28607 , +-22761 , +8637 , +-12023 , +-22249 , +-24203 , +-12437 , +15517 , +-13625 , +1549 , +-32043 , +27367 , +-12755 , +-17359 , +-25565 , +18181 , +-21089 , +-1731 , +14919 , +32089 , +17825 , +-3791 , +6759 , +20321 , +159 , +29633 , +28125 , +28685 , +17699 , +-12815 , +-8525 , +-32609 , +7819 , +-14285 , +31375 , +17913 , +6215 , +6387 , +-17357 , +11901 , +-15477 , +9143 , +27511 , +16479 , +-8309 , +23739 , +-29769 , +2173 , +-25551 , +10493 , +4309 , +-24127 , +-4265 , +-27939 , +-27981 , +27883 , +29817 , +-21707 , +-18661 , +-28431 , +-12555 , +-4367 , +-30135 , +-9257 , +1729 , +-30431 , +32217 , +7173 , +-10337 , +-13929 , +17985 , +-30179 , +27349 , +-22527 , +20169 , +23387 , +29551 , +-21639 , +-1015 , +5217 , +9447 , +3749 , +29907 , +-19301 , +-915 , +30793 , +10683 , +21005 , +-11119 , +8289 , +-11519 , +15795 , +15237 , +-17987 , +7445 , +18515 , +-31789 , +-2031 , +-17529 , +16345 , +-30833 , +2711 , +6783 , +15663 , +-27113 , +-7397 , +26303 , +-9587 , +-31673 , +-24161 , +9227 , +-5535 , +22321 , +-919 , +2607 , +-14697 , +-32429 , +-859 , +24687 , +-12169 , +10839 , +-6285 , +-28799 , +14595 , +31041 , +-21627 , +8713 , +-22077 , +22831 , +-21707 , +-5237 , +-6615 , +-20345 , +15135 , +-29213 , +-673 , +-32065 , +-21197 , +5445 , +9383 , +-2941 , +16473 , +-7507 , +-11731 , +-21893 , +-13191 , +-25385 , +12389 , +31355 , +-31963 , +24509 , +-32293 , +-6339 , +-25443 , +-7541 , +-29295 , +24219 , +18811 , +-13291 , +-21545 , +-19899 , +-16195 , +-4653 , +-29791 , +-15623 , +-15777 , +-25253 , +18527 , +-10691 , +26235 , +-7089 , +-6057 , +-29035 , +-28457 , +-16673 , +-9353 , +-455 , +-7931 , +8381 , +-27979 , +-13229 , +30451 , +-1895 , +-14363 , +-6991 , +25615 , +-5619 , +-29171 , +-22015 , +8399 , +-2519 , +-15809 , +8837 , +-8489 , +-13741 , +-2827 , +5971 , +3977 , +-4651 , +25569 , +-25085 , +-2271 , +-31287 , +7243 , +1259 , +-23477 , +-6257 , +-8725 , +-26151 , +9275 , +-20015 , +-10697 , +17227 , +19269 , +-23569 , +-13239 , +25635 , +-5641 , +-5125 , +-10969 , +483 , +-14673 , +9011 , +10413 , +-23199 , +13237 , +-20233 , +11987 , +-4601 , +-26163 , +-13245 , +23953 , +20351 , +-12457 , +-11357 , +-201 , +-3595 , +-27677 , +13233 , +31035 , +11469 , +2123 , +-27645 , +11165 , +-27691 , +31559 , +-32079 , +-32589 , +3845 , +25223 , +22081 , +17809 , +-2895 , +-10163 , +32293 , +-7475 , +-25017 , +30085 , +-1613 , +-29205 , +28547 , +-8103 , +11669 , +2851 , +-14303 , +-6325 , +-12335 , +6089 , +-10203 , +-32559 , +8753 , +5401 , +-12671 , +-30873 , +13123 , +2963 , +23135 , +-30167 , +24015 , +-24873 , +-2365 , +-30227 , +-16687 , +2551 , +-1827 , +-1321 , +-9745 , +-17327 , +-10071 , +-7559 , +9331 , +-20757 , +-21449 , +27229 , +-20805 , +2629 , +19803 , +-16593 , +-23487 , +13489 , +8681 , +-27579 , +-9727 , +-7887 , +-405 , +9151 , +9087 , +14027 , +7001 , +797 , +-22983 , +-22429 , +-27437 , +-23461 , +-7269 , +-27381 , +27861 , +-9345 , +-20095 , +18667 , +-30731 , +16575 , +-9945 , +30343 , +-25453 , +-14579 , +-27483 , +-16219 , +-29543 , +24371 , +-23839 , +27807 , +8625 , +-147 , +10769 , +-10955 , +-23563 , +-6271 , +8361 , +-18953 , +17203 , +31059 , +29917 , +-6395 , +-13665 , +32255 , +-21873 , +-24193 , +-26871 , +12149 , +10187 , +-7097 , +18331 , +-8567 , +-6205 , +4461 , +8457 , +-29291 , +-13247 , +23543 , +-25775 , +22405 , +17827 , +7747 , +4589 , +-1157 , +-30385 , +-20265 , +3731 , +25823 , +3761 , +-9789 , +9823 , +-30727 , +-30035 , +27761 , +-7781 , +27403 , +8603 , +12799 , +-23061 , +-19481 , +1981 , +-19943 , +6923 , +-28153 , +18483 , +-2995 , +519 , +23845 , +-5503 , +-11799 , +-2323 , +-16299 , +11895 , +-4019 , +5391 , +-13923 , +5807 , +-1083 , +-2637 , +-18937 , +-1657 , +15075 , +331 , +-11713 , +20635 , +4693 , +-29899 , +18349 , +32435 , +-28353 , +-20503 , +11781 , +-15291 , +-25073 , +28087 , +-18073 , +6763 , +-9257 , +-4099 , +-8977 , +11349 , +-8149 , +-31519 , +14807 , +10061 , +-11923 , +13701 , +-19707 , +-26339 , +1453 , +30917 , +32043 , +5403 , +-17917 , +-1943 , +857 , +-10349 , +31329 , +-7971 , +30743 , +8131 , +20971 , +-19597 , +27393 , +30805 , +23511 , +4877 , +15065 , +-22953 , +-13123 , +-31909 , +-17375 , +30381 , +3181 , +-28005 , +-5067 , +8723 , +-1965 , +26049 , +2273 , +32651 , +-6589 , +7995 , +-7047 , +-17061 , +32727 , +6181 , +-12687 , +-10107 , +3653 , +25605 , +-6023 , +-30019 , +20151 , +-26885 , +16395 , +-6435 , +26405 , +18045 , +-31601 , +23529 , +5035 , +15507 , +-19987 , +22137 , +-23457 , +-10869 , +-30811 , +14523 , +-7249 , +-32721 , +9315 , +-7959 , +32053 , +-10109 , +-25053 , +30267 , +-755 , +21747 , +-4419 , +-19355 , +-79 , +-485 , +3329 , +28047 , +-21935 , +10479 , +-30127 , +31437 , +935 , +-21639 , +-29511 , +-11505 , +17747 , +-31723 , +32131 , +167 , +-16975 , +27427 , +17491 , +-21193 , +23089 , +18243 , +26299 , +31783 , +29235 , +-1011 , +-7079 , +-5209 , +-5547 , +-29885 , +10089 , +29727 , +18517 , +145 , +-7713 , +-25043 , +-12439 , +8127 , +12037 , +18195 , +15629 , +19823 , +-11897 , +-13379 , +15973 , +-21939 , +-6639 , +21035 , +13843 , +-10031 , +-7569 , +-5775 , +27275 , +25965 , +14615 , +-18381 , +13549 , +18763 , +31049 , +-3695 , +18525 , +32643 , +17317 , +-14169 , +-22047 , +9427 , +-5305 , +6787 , +28847 , +6619 , +6997 , +1699 , +-6393 , +-24625 , +22821 , +11743 , +9107 , +-6225 , +-17719 , +-12303 , +-19657 , +3077 , +-21973 , +32607 , +27497 , +27929 , +3241 , +-23553 , +-749 , +-6231 , +-22749 , +-31769 , +24537 , +-8669 , +5795 , +2793 , +-20985 , +-29611 , +13669 , +2179 , +-30509 , +-25163 , +17523 , +7273 , +-25275 , +32265 , +-20023 , +2407 , +24969 , +23721 , +-11559 , +-22805 , +-23863 , +23089 , +27575 , +10479 , +-1153 , +-10053 , +23199 , +-2435 , +-13739 , +26269 , +16411 , +-14691 , +-16009 , +15251 , +31635 , +15317 , +-22925 , +-16249 , +21609 , +-18915 , +23173 , +6587 , +-22641 , +-27817 , +-15497 , +11151 , +-3681 , +-27067 , +-21253 , +4525 , +3443 , +-21497 , +14971 , +-32573 , +32577 , +-14321 , +377 , +2755 , +-23509 , +3737 , +25699 , +-17007 , +-24997 , +1439 , +17895 , +5189 , +21923 , +1119 , +-21289 , +-19755 , +25733 , +-26303 , +28789 , +-7073 , +18903 , +7773 , +-31411 , +21457 , +-18729 , +13417 , +661 , +-2265 , +20935 , +23609 , +30719 , +-23253 , +-15109 , +26289 , +-21493 , +19869 , +29307 , +-3261 , +23277 , +19449 , +-23527 , +-19233 , +3547 , +-13145 , +-28667 , +-19085 , +-23835 , +-17229 , +2535 , +20447 , +-25261 , +15375 , +14461 , +6251 , +-10633 , +2619 , +10149 , +27587 , +-22773 , +-6771 , +-28925 , +-9107 , +8449 , +21723 , +-23277 , +14023 , +29155 , +-11331 , +22209 , +21359 , +1443 , +-9917 , +-17535 , +28749 , +-32257 , +-20183 , +7655 , +18437 , +12873 , +-24689 , +28865 , +-24603 , +-1073 , +18235 , +-30545 , +-31633 , +29351 , +-13759 , +-3533 , +-5055 , +9995 , +-25271 , +-17321 , +-1641 , +-15563 , +-31423 , +4027 , +-28101 , +4527 , +-18541 , +-5589 , +-31223 , +-31689 , +-27423 , +-10557 , +-1063 , +21253 , +-2501 , +-1413 , +23809 , +-13129 , +-31525 , +19779 , +30535 , +-4455 , +5203 , +22431 , +3419 , +-8823 , +30545 , +19639 , +-29227 , +22341 , +-14641 , +-9993 , +10403 , +-19385 , +-27699 , +32033 , +-1277 , +-28125 , +-1141 , +-12821 , +-30205 , +-16811 , +5697 , +28689 , +17267 , +31133 , +-18353 , +10479 , +15705 , +-21539 , +-507 , +-9317 , +-5135 , +8291 , +-26167 , +-13701 , +1567 , +25295 , +23771 , +-2725 , +20591 , +21607 , +-3443 , +-5107 , +-31103 , +4587 , +17903 , +-4745 , +6923 , +16877 , +-30183 , +-21711 , +1613 , +25519 , +23763 , +-30309 , +23305 , +13945 , +-1069 , +-19339 , +-9733 , +-11927 , +1149 , +-8197 , +15315 , +-31783 , +-18933 , +3701 , +27051 , +5675 , +11857 , +12885 , +23551 , +-31963 , +-26381 , +1231 , +-10203 , +-15921 , +-14055 , +-5907 , +-15289 , +-18499 , +13739 , +13099 , +18903 , +-5129 , +-12281 , +-21105 , +32397 , +4677 , +-21191 , +-20419 , +-13349 , +1807 , +-1613 , +-22895 , +-13087 , +21423 , +12169 , +22715 , +-9489 , +-11447 , +1825 , +-11823 , +117 , +-28627 , +6771 , +14951 , +-30085 , +29089 , +-19783 , +32689 , +-3933 , +-11709 , +-18253 , +7947 , +19345 , +-26919 , +16207 , +-4577 , +4593 , +-8779 , +-24337 , +14197 , +21477 , +-8579 , +-22759 , +911 , +11529 , +4753 , +-19275 , +-6529 , +-23333 , +15837 , +27325 , +10751 , +-19009 , +28719 , +-16517 , +-21493 , +-19849 , +-26859 , +65 , +18931 , +-15855 , +-18385 , +-19041 , +12287 , +-21911 , +27657 , +-7655 , +-6791 , +-24289 , +-20107 , +-27803 , +27983 , +23307 , +-20125 , +15901 , +21285 , +4665 , +-29901 , +-9219 , +-783 , +-17827 , +-15979 , +17553 , +6417 , +7119 , +24539 , +-18309 , +-32537 , +3333 , +28633 , +5919 , +26599 , +-32129 , +-10191 , +-18721 , +12089 , +-21165 , +15157 , +22485 , +-18993 , +-8179 , +-4551 , +10507 , +31993 , +29245 , +-24207 , +22577 , +31105 , +23139 , +-12223 , +9169 , +-5825 , +-18841 , +-28129 , +-6127 , +1335 , +-1387 , +-7197 , +7653 , +-6101 , +-233 , +413 , +-15165 , +-32329 , +-23583 , +-5895 , +12003 , +-4633 , +17211 , +-25589 , +-22539 , +2383 , +-21847 , +15535 , +-4525 , +-26203 , +-11669 , +-26537 , +-2365 , +-7469 , +2935 , +15471 , +-3421 , +155 , +-9239 , +-21713 , +4269 , +-9057 , +16897 , +-14093 , +-4057 , +6409 , +-27237 , +6673 , +16029 , +-14439 , +-16349 , +-5833 , +30749 , +17723 , +785 , +-4545 , +16871 , +4651 , +1249 , +-29307 , +22443 , +-383 , +23685 , +18373 , +-31933 , +-31923 , +21349 , +29291 , +-26911 , +-24525 , +5587 , +-12173 , +-7727 , +5499 , +2563 , +9149 , +6065 , +21169 , +-31355 , +20197 , +8735 , +-3655 , +-26313 , +8093 , +-11013 , +5733 , +11209 , +22911 , +-741 , +-30061 , +6823 , +6511 , +-15995 , +-4417 , +-26247 , +10603 , +-12511 , +-10465 , +-30693 , +23781 , +18171 , +11577 , +-2285 , +-29285 , +-6415 , +-20999 , +-28021 , +20721 , +25843 , +-9135 , +11201 , +-567 , +29879 , +16455 , +6413 , +6871 , +28653 , +19091 , +-23471 , +-12933 , +6403 , +-19275 , +16363 , +24859 , +28749 , +-19059 , +-17863 , +32505 , +5071 , +-7561 , +10125 , +11915 , +8545 , +5339 , +-17763 , +13911 , +4987 , +11339 , +17287 , +-2751 , +-28577 , +1307 , +-29375 , +19567 , +-23595 , +31605 , +20885 , +-20071 , +23397 , +-11529 , +-1129 , +483 , +15629 , +23235 , +-3939 , +11577 , +-28553 , +-23009 , +-26699 , +21023 , +-3397 , +12679 , +-10329 , +25105 , +11397 , +-13237 , +17245 , +-6569 , +-15647 , +-24927 , +-21271 , +-679 , +14947 , +9277 , +22261 , +10371 , +-31509 , +-3213 , +31935 , +655 , +-28207 , +-22337 , +26765 , +30311 , +30889 , +-12565 , +-12117 , +-29063 , +13939 , +7071 , +-19747 , +29839 , +30037 , +-10115 , +26203 , +-17883 , +22229 , +-12105 , +7237 , +-32437 , +-18287 , +-25815 , +-31071 , +-25107 , +-5263 , +-26391 , +-8755 , +18359 , +21863 , +-32657 , +-903 , +29805 , +-2655 , +-13027 , +-13789 , +29367 , +17223 , +-5281 , +-21497 , +-8821 , +24237 , +31041 , +13473 , +32758 , +3343 , +29579 , +-13927 , +16759 , +30403 , +-22701 , +30789 , +-19741 , +8187 , +16403 , +-20321 , +21417 , +5111 , +-13745 , +7863 , +10173 , +-17735 , +-32101 , +23221 , +-18977 , +20807 , +18751 , +-22711 , +1667 , +31833 , +4685 , +30371 , +-17633 , +-4711 , +10805 , +-4625 , +-10749 , +-27819 , +9953 , +8015 , +19129 , +19133 , +-8887 , +12877 , +-4401 , +-29551 , +13201 , +13009 , +-7359 , +3173 , +10141 , +-16729 , +3649 , +-15789 , +-7643 , +18787 , +-16999 , +22321 , +11863 , +12013 , +2429 , +27469 , +11751 , +19563 , +4069 , +-20569 , +-24151 , +22459 , +-24469 , +18845 , +-24915 , +-21135 , +28823 , +31027 , +1997 , +-12981 , +28865 , +-1601 , +-23597 , +15659 , +22883 , +5419 , +10243 , +2697 , +2295 , +-7773 , +3903 , +-23949 , +-13751 , +-24113 , +-27245 , +14339 , +6993 , +-16491 , +-20389 , +29007 , +3215 , +22851 , +23247 , +-27919 , +-12069 , +-9903 , +3871 , +-7701 , +-27197 , +-28523 , +-15345 , +29745 , +15461 , +-13573 , +18183 , +10137 , +2751 , +22203 , +19123 , +-2225 , +-4725 , +-2535 , +535 , +26581 , +25245 , +-19565 , +-24539 , +16759 , +-23631 , +-28513 , +-27685 , +20803 , +10697 , +-31007 , +-10025 , +26755 , +8449 , +21477 , +13419 , +21167 , +-6931 , +1877 , +-18627 , +-1553 , +7533 , +-13393 , +23391 , +29197 , +-27645 , +-7805 , +5853 , +8681 , +22961 , +17701 , +15071 , +-15497 , +21833 , +-2325 , +30525 , +29243 , +-11697 , +24027 , +23191 , +-32717 , +10309 , +-17169 , +-22801 , +18783 , +4753 , +12999 , +21179 , +-16979 , +-12089 , +15329 , +-29047 , +-9867 , +-22645 , +12111 , +-22775 , +-15241 , +-9757 , +-21005 , +7087 , +-12475 , +-19689 , +31801 , +-15929 , +1869 , +-18181 , +-16825 , +19465 , +-26305 , +-24873 , +3769 , +3773 , +-17901 , +4277 , +26591 , +22599 , +20089 , +-4295 , +22377 , +13893 , +2261 , +5117 , +29865 , +-221 , +13747 , +13931 , +-28343 , +30775 , +-4411 , +2317 , +-25475 , +-4005 , +-5033 , +10093 , +-20285 , +9981 , +-21181 , +-5021 , +17431 , +22459 , +11633 , +-14083 , +-3413 , +17023 , +-7473 , +13253 , +-9185 , +-30703 , +14525 , +-14169 , +2873 , +13109 , +16917 , +-20157 , +-8161 , +-14791 , +-9831 , +-4671 , +-2803 , +-23271 , +-5909 , +-27087 , +30095 , +13329 , +3595 , +-21407 , +24629 , +-32079 , +22347 , +-27087 , +-21811 , +-9343 , +19909 , +-10131 , +-16097 , +4107 , +1625 , +10793 , +22047 , +-9859 , +28957 , +30863 , +-89 , +9659 , +-24737 , +-3259 , +-27471 , +-22277 , +14357 , +-18119 , +-14835 , +-29731 , +-11563 , +15871 , +-5735 , +-29185 , +29011 , +-89 , +28669 , +29975 , +-12461 , +-23275 , +-809 , +8333 , +-16089 , +7387 , +-26235 , +6547 , +22687 , +-11123 , +-1457 , +-2119 , +2185 , +-24417 , +20003 , +29193 , +32421 , +27831 , +-28465 , +29851 , +27673 , +19591 , +-10313 , +4789 , +-2955 , +1321 , +-28403 , +-21163 , +-1249 , +-22803 , +11659 , +9817 , +1871 , +20415 , +11431 , +30733 , +-2423 , +-21003 , +847 , +-30393 , +13717 , +23461 , +-10975 , +-27145 , +-18447 , +-21881 , +30751 , +1103 , +26065 , +-1977 , +-17685 , +-439 , +14485 , +9049 , +25979 , +-22577 , +-16965 , +14427 , +-5031 , +18757 , +14431 , +-4125 , +20047 , +18093 , +6443 , +5345 , +5289 , +15155 , +1243 , +27499 , +-4629 , +4437 , +8487 , +12319 , +-9469 , +28517 , +-8123 , +-14345 , +26377 , +20667 , +729 , +-18269 , +-7821 , +9011 , +2169 , +-32417 , +4811 , +16733 , +-14697 , +27719 , +25581 , +8447 , +24065 , +-4039 , +-4165 , +3647 , +18137 , +-17625 , +30545 , +-13521 , +-21747 , +-787 , +-20279 , +-5139 , +-14521 , +2731 , +-6043 , +18229 , +-30093 , +-3425 , +27729 , +21373 , +11179 , +6271 , +-17705 , +-14197 , +-4427 , +29257 , +-5355 , +23949 , +-12553 , +32157 , +18491 , +-1103 , +18679 , +-31327 , +-26819 , +15679 , +-1463 , +20803 , +-241 , +-28369 , +20493 , +-11735 , +2907 , +-9407 , +-1051 , +-5127 , +-15943 , +-5993 , +26477 , +-5071 , +16745 , +-28471 , +-8651 , +-13687 , +-6777 , +-9343 , +-22985 , +-13881 , +25033 , +657 , +-16689 , +-28401 , +-11855 , +-22387 , +32305 , +21959 , +12869 , +7135 , +-14997 , +11751 , +15951 , +-411 , +719 , +8915 , +9487 , +10625 , +-17679 , +7351 , +4973 , +9913 , +-12253 , +15961 , +1983 , +5321 , +16489 , +-13967 , +-6155 , +20803 , +-28175 , +9097 , +21081 , +-16745 , +-23029 , +4937 , +8383 , +-319 , +10911 , +-12707 , +5701 , +31311 , +25135 , +-4161 , +-20603 , +-29697 , +31295 , +-4455 , +-29355 , +-22309 , +10329 , +11673 , +29169 , +-9013 , +-14971 , +15049 , +18627 , +29619 , +-24521 , +22503 , +12431 , +9985 , +-17197 , +-7361 , +51 , +-22575 , +-17251 , +-18177 , +15829 , +-8833 , +9009 , +9491 , +171 , +-20291 , +-19837 , +32127 , +-19167 , +-17617 , +5455 , +-723 , +15261 , +-19583 , +-28655 , +-2225 , +22967 , +-4607 , +-3965 , +-1229 , +-2585 , +-13901 , +29583 , +155 , +5575 , +25069 , +-9779 , +13465 , +5831 , +23663 , +25203 , +32477 , +6501 , +11253 , +-6953 , +22427 , +5863 , +-24741 , +-16295 , +1491 , +-26225 , +5411 , +-9491 , +-8645 , +-28839 , +11169 , +26117 , +-25979 , +12077 , +17797 , +-24053 , +24899 , +26777 , +-17671 , +22625 , +-27075 , +-10741 , +3895 , +17359 , +2887 , +-22139 , +671 , +8065 , +-22121 , +-29731 , +-9899 , +-27521 , +11169 , +-6549 , +-20905 , +-16991 , +-145 , +-28861 , +11021 , +31245 , +-5771 , +20473 , +31597 , +17959 , +32750 , +16067 , +-10611 , +-11505 , +5805 , +25161 , +29623 , +5275 , +13183 , +-26677 , +17421 , +-569 , +8953 , +13279 , +18579 , +-23629 , +-14885 , +21935 , +-9009 , +-229 , +11993 , +25763 , +-12829 , +1099 , +10497 , +-20307 , +-27109 , +18843 , +16011 , +-21271 , +-27371 , +-2969 , +22583 , +-17173 , +-25531 , +9343 , +-29411 , +3177 , +-22499 , +-27089 , +15117 , +26999 , +7585 , +-19801 , +-159 , +-26301 , +25721 , +-14595 , +-22439 , +8007 , +13713 , +-26213 , +-18705 , +-4347 , +30253 , +5703 , +-30407 , +57 , +-2175 , +18571 , +-15057 , +15773 , +-3385 , +23731 , +7187 , +-14829 , +-26147 , +-8373 , +-441 , +-1947 , +-27559 , +-3315 , +22425 , +16769 , +-16095 , +-19103 , +-5077 , +9507 , +5251 , +-30389 , +28095 , +31001 , +-5427 , +-32529 , +-7785 , +19195 , +-22681 , +-25213 , +28359 , +26715 , +-1943 , +7625 , +11533 , +387 , +-26957 , +-27905 , +3123 , +24235 , +-9593 , +-2973 , +27609 , +8115 , +-867 , +26917 , +31701 , +-425 , +23487 , +223 , +-757 , +-29973 , +-24865 , +4749 , +31425 , +-9323 , +2993 , +31239 , +-27521 , +-23047 , +-5695 , +27635 , +28761 , +-17535 , +18951 , +6213 , +-4647 , +24587 , +2827 , +-11465 , +-20157 , +29475 , +29043 , +-841 , +-24703 , +-7235 , +11543 , +24167 , +-7571 , +26217 , +8873 , +14359 , +3501 , +-6641 , +-11841 , +-19785 , +31757 , +-22745 , +-20625 , +-3631 , +32087 , +-27283 , +19817 , +31619 , +27811 , +-19427 , +-23157 , +12019 , +18239 , +10407 , +25087 , +-32435 , +-9225 , +-10259 , +31183 , +14645 , +10995 , +3575 , +-1543 , +24771 , +3605 , +10281 , +21265 , +-23049 , +-15931 , +-17921 , +851 , +-7755 , +26195 , +9283 , +-2763 , +-705 , +4559 , +5833 , +27279 , +-4571 , +-30125 , +-2915 , +-13277 , +191 , +16627 , +-27963 , +13757 , +10545 , +-23301 , +18807 , +5835 , +-27953 , +26589 , +-12337 , +-16525 , +9767 , +-13959 , +-9723 , +12839 , +15725 , +-31489 , +-3543 , +4553 , +16251 , +30275 , +-31911 , +1077 , +22849 , +-28779 , +-28807 , +24935 , +3527 , +14363 , +1905 , +-30975 , +-11107 , +-21855 , +15829 , +-22409 , +32465 , +27907 , +27699 , +29595 , +-25995 , +30703 , +-15689 , +25011 , +-29563 , +10061 , +-1427 , +3353 , +-26261 , +-29937 , +-7683 , +25425 , +-27659 , +12431 , +-9003 , +2975 , +27335 , +-931 , +-13071 , +-9701 , +19549 , +11431 , +24329 , +-22699 , +-26247 , +7165 , +12617 , +25693 , +24097 , +-9027 , +-13169 , +-15511 , +-30441 , +17625 , +-6117 , +19689 , +-26163 , +-32193 , +-4141 , +14617 , +-799 , +-12381 , +17643 , +-6625 , +-12523 , +25059 , +12587 , +17057 , +16065 , +9685 , +1185 , +1249 , +17363 , +26281 , +21975 , +1613 , +-6587 , +-2891 , +-9073 , +-25699 , +-13555 , +-6953 , +-8453 , +16747 , +16291 , +-32693 , +-22161 , +30023 , +31727 , +31997 , +2213 , +4949 , +21183 , +5739 , +15973 , +4189 , +2249 , +7921 , +26825 , +-6035 , +-30179 , +-24145 , +-11273 , +-26139 , +-18917 , +11473 , +11849 , +-31463 , +-1553 , +23673 , +5911 , +2151 , +-3705 , +-16891 , +-25 , +12493 , +18189 , +-23563 , +-10205 , +22269 , +-30503 , +571 , +31571 , +255 , +11765 , +-5353 , +22999 , +-8127 , +-32507 , +-15255 , +21537 , +17457 , +-22065 , +-12905 , +16483 , +-9897 , +-29403 , +3537 , +4815 , +3307 , +-17557 , +17145 , +8275 , +-4883 , +9599 , +-5899 , +29637 , +-9025 , +-12223 , +-3705 , +-21085 , +-2503 , +15999 , +17575 , +26189 , +28485 , +-13967 , +-24233 , +-30025 , +-9225 , +-24651 , +-2307 , +-21599 , +-23265 , +-23869 , +-12481 , +-18603 , +-29847 , +-9503 , +-8107 , +5595 , +-28941 , +-18011 , +24549 , +-24655 , +4959 , +-7451 , +11863 , +26371 , +-26509 , +-19407 , +29363 , +-13469 , +-8403 , +17101 , +-16655 , +-12283 , +-11431 , +2085 , +21723 , +11375 , +4527 , +-2869 , +-23719 , +4025 , +25189 , +8683 , +-27561 , +3647 , +75 , +-9921 , +-15599 , +12763 , +1119 , +11151 , +13037 , +-23391 , +-12821 , +-12889 , +-24869 , +-4591 , +-16615 , +29645 , +-1755 , +15059 , +9735 , +25525 , +13257 , +-22807 , +-21909 , +29953 , +-5805 , +627 , +6043 , +14391 , +-463 , +2265 , +-9419 , +31797 , +-11631 , +-32113 , +4139 , +-5587 , +7345 , +18751 , +28257 , +-4071 , +961 , +-22891 , +-2365 , +-20039 , +-27855 , +1377 , +-19489 , +14339 , +7823 , +27999 , +26361 , +-26841 , +-21025 , +-16021 , +31145 , +17141 , +2671 , +14385 , +3051 , +18921 , +-31695 , +1907 , +30397 , +-20843 , +1945 , +-17995 , +6971 , +-26723 , +-25623 , +9849 , +-10713 , +-29133 , +-7663 , +-31495 , +-4075 , +-31993 , +-21495 , +-28319 , +-7689 , +-11833 , +17571 , +15483 , +-14797 , +-1263 , +32740 , +-8711 , +-12733 , +19697 , +11231 , +24859 , +-27443 , +12753 , +-1523 , +25589 , +-23505 , +24055 , +31009 , +-16095 , +2473 , +-27777 , +14181 , +31735 , +19683 , +13515 , +-23155 , +-30909 , +-23533 , +23939 , +-11757 , +24193 , +-17265 , +-17915 , +-27379 , +-5739 , +-4125 , +-10905 , +17541 , +-23805 , +15725 , +5603 , +-30381 , +30879 , +-8079 , +8157 , +27763 , +24273 , +-9541 , +-10419 , +13531 , +3653 , +19367 +}; +#endif +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/apps/apptester/audiobuffer.c b/apps/apptester/audiobuffer.c new file mode 100644 index 0000000..b7c9925 --- /dev/null +++ b/apps/apptester/audiobuffer.c @@ -0,0 +1,146 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "cqueue.h" +#include "string.h" +#include "audiobuffer.h" + + +#ifndef _AUDIO_NO_THREAD_ +static osMutexId g_audio_queue_mutex_id = NULL; +osMutexDef(g_audio_queue_mutex); +#endif + +static CQueue audio_queue; +static unsigned char audio_queue_buf[AUDIO_BUFFER_FRAME_SIZE*AUDIO_BUFFER_FRAME_NUM]; + +void audio_mono2stereo_16bits(uint16_t *dst_buf, uint16_t *src_buf, uint32_t src_len) +{ + uint32_t i = 0; + for (i = 0; i < src_len; ++i) { + dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = src_buf[i]; + } +} + +void audio_stereo2mono_16bits(uint8_t chnlsel, uint16_t *dst_buf, uint16_t *src_buf, uint32_t src_len) +{ + uint32_t i = 0; + for (i = 0; i < src_len; i+=2) { + dst_buf[i/2] = src_buf[i + chnlsel]; + } +} + +void audio_buffer_init(void) +{ +#ifndef _AUDIO_NO_THREAD_ + if (g_audio_queue_mutex_id == NULL) + g_audio_queue_mutex_id = osMutexCreate((osMutex(g_audio_queue_mutex))); +#endif + InitCQueue(&audio_queue, sizeof(audio_queue_buf), (unsigned char *)&audio_queue_buf); + memset(&audio_queue_buf, 0x00, sizeof(audio_queue_buf)); +} + +int audio_buffer_length(void) +{ + int len; +#ifndef _AUDIO_NO_THREAD_ + osMutexWait(g_audio_queue_mutex_id, osWaitForever); +#endif + len = LengthOfCQueue(&audio_queue); +#ifndef _AUDIO_NO_THREAD_ + osMutexRelease(g_audio_queue_mutex_id); +#endif + return len; +} + +int audio_buffer_set(uint8_t *buff, uint16_t len) +{ + int status; + +#ifndef _AUDIO_NO_THREAD_ + osMutexWait(g_audio_queue_mutex_id, osWaitForever); +#endif + status = EnCQueue(&audio_queue, buff, len); +#ifndef _AUDIO_NO_THREAD_ + osMutexRelease(g_audio_queue_mutex_id); +#endif + return status; +} + +int audio_buffer_get(uint8_t *buff, uint16_t len) +{ + uint8_t *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + int status; +#ifndef _AUDIO_NO_THREAD_ + osMutexWait(g_audio_queue_mutex_id, osWaitForever); +#endif + status = PeekCQueue(&audio_queue, len, &e1, &len1, &e2, &len2); + if (len==(len1+len2)){ + memcpy(buff,e1,len1); + memcpy(buff+len1,e2,len2); + DeCQueue(&audio_queue, 0, len); + DeCQueue(&audio_queue, 0, len2); + }else{ + memset(buff, 0x00, len); + status = -1; + } +#ifndef _AUDIO_NO_THREAD_ + osMutexRelease(g_audio_queue_mutex_id); +#endif + return status; +} + +int audio_buffer_set_stereo2mono_16bits(uint8_t *buff, uint16_t len, uint8_t chnlsel) +{ + int status; + +#ifndef _AUDIO_NO_THREAD_ + osMutexWait(g_audio_queue_mutex_id, osWaitForever); +#endif + audio_stereo2mono_16bits(chnlsel, (uint16_t *)buff, (uint16_t *)buff, len>>1); + status = EnCQueue(&audio_queue, buff, len>>1); +#ifndef _AUDIO_NO_THREAD_ + osMutexRelease(g_audio_queue_mutex_id); +#endif + return status; +} + +int audio_buffer_get_mono2stereo_16bits(uint8_t *buff, uint16_t len) +{ + uint8_t *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + int status; + +#ifndef _AUDIO_NO_THREAD_ + osMutexWait(g_audio_queue_mutex_id, osWaitForever); +#endif + status = PeekCQueue(&audio_queue, len>>1, &e1, &len1, &e2, &len2); + if (len>>1== len1+len2){ + audio_mono2stereo_16bits((uint16_t *)buff, (uint16_t *)e1, len1>>1); + audio_mono2stereo_16bits((uint16_t *)(buff+(len1<<1)), (uint16_t *)e2, len2>>1); + DeCQueue(&audio_queue, 0, len1); + DeCQueue(&audio_queue, 0, len2); + status = len; + }else{ + memset(buff, 0x00, len); + status = -1; + } +#ifndef _AUDIO_NO_THREAD_ + osMutexRelease(g_audio_queue_mutex_id); +#endif + return status; +} diff --git a/apps/apptester/audiobuffer.h b/apps/apptester/audiobuffer.h new file mode 100644 index 0000000..0f0e5b4 --- /dev/null +++ b/apps/apptester/audiobuffer.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __AUDIOBUFFER_H__ +#define __AUDIOBUFFER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define AUDIO_BUFFER_FRAME_SIZE (4*1024) +#define AUDIO_BUFFER_FRAME_NUM (1) +#define AUDIO_BUFFER_TOTAL_SIZE (AUDIO_BUFFER_FRAME_SIZE*AUDIO_BUFFER_FRAME_NUM) + +void audio_mono2stereo_16bits(uint16_t *dst_buf, uint16_t *src_buf, uint32_t src_len); + +void audio_stereo2mono_16bits(uint8_t chnlsel, uint16_t *dst_buf, uint16_t *src_buf, uint32_t src_len); + +void audio_buffer_init(void); + +int audio_buffer_length(void); + +int audio_buffer_set(uint8_t *buff, uint16_t len); + +int audio_buffer_get(uint8_t *buff, uint16_t len); + +int audio_buffer_set_stereo2mono_16bits(uint8_t *buff, uint16_t len, uint8_t chnlsel); + +int audio_buffer_get_mono2stereo_16bits(uint8_t *buff, uint16_t len); + +#ifdef __cplusplus + } +#endif + +#endif//__FMDEC_H__ diff --git a/apps/audioplayers/Makefile b/apps/audioplayers/Makefile new file mode 100644 index 0000000..1a0e416 --- /dev/null +++ b/apps/audioplayers/Makefile @@ -0,0 +1,180 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +ifeq ($(A2DP_DECODER_VER),2) +obj_cpp := $(filter-out a2dpplay.cpp,$(obj_cpp)) +obj_cpp += a2dp_decoder/ +endif + +bt_sco_chain_obj = bt_sco_chain.c bt_sco_chain_thirdparty.c bt_sco_chain_thirdparty_alango.c +obj_c := $(filter-out $(bt_sco_chain_obj),$(obj_c)) + +ifeq ($(SPEECH_TX_THIRDPARTY_ALANGO),1) +obj_c += bt_sco_chain_thirdparty_alango.c +else ifeq ($(SPEECH_TX_THIRDPARTY),1) +obj_c += bt_sco_chain_thirdparty.c +else +obj_c += bt_sco_chain.c +endif + +ifeq ($(SCO_DMA_SNAPSHOT),1) +obj_cpp := $(filter-out voicebtpcmplay.cpp,$(obj_cpp)) +else +obj_cpp := $(filter-out voicebtpcmplay_sco_dma_snapshot.cpp,$(obj_cpp)) +endif + +ifeq ($(RB_CODEC),1) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)rbplay/*.cpp)) +endif + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +CFLAGS_a2dpplay.o += -O3 + +ifeq ($(A2DP_AAC_ON),1) +AAC_INCLUDES = \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libAACdec/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libAACenc/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libFDK/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libPCMutils/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libSBRdec/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libSBRenc/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libSYS/include +else +AAC_INCLUDES = +endif + +ccflags-y := \ + $(AAC_INCLUDES) \ + -Iservices/osif \ + -Iservices/audio_process \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/resources \ + -Iservices/fs/fat/ChaN \ + -Iservices/bt_app \ + $(BT_IF_INCLUDES) \ + -Iplatform/drivers/uarthci \ + -Iutils/cqueue \ + -Iservices/audio_dump/include \ + -Iservices/multimedia/speech/inc \ + -Iservices/multimedia/rbcodec/inc \ + -Iservices/multimedia/audio/process/eq/include \ + -Iservices/multimedia/audio/process/resample/include \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/fm/inc \ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/include \ + -Iservices/overlay \ + -Iservices/norflash_api \ + -Iservices/nvrecord \ + -Iservices/nv_section/log_section \ + -Iapps/main \ + -Iapps/audioplayers/rbplay/ \ + -Iapps/audioplayers/a2dp_decoder \ + -Iutils/list \ + -Iutils/heap \ + -Iutils/intersyshci \ + -Irtos/rtos \ + -Iplatform/drivers/ana \ + -Ithirdparty/audio_codec_lib/scalable/ \ + -Ithirdparty/audio_codec_lib/liblhdc-dec/inc \ + -Iapps/apptester \ + -Iapps/key \ + -Iplatform/drivers/bt \ + -Iapps/anc/inc \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/bt_profiles_enhanced/inc \ + -Iservices/app_ai/inc + +ifeq ($(IBRT),1) +ccflags-y += -Iservices/ibrt_ui/inc +ccflags-y += -Iservices/ibrt_core/inc +ccflags-y += -Iservices/app_ibrt/inc +endif + +ifeq ($(A2DP_LDAC_ON),1) +ccflags-y += -Ithirdparty/audio_codec_lib/ldac/inc +endif + +ifeq ($(A2DP_CP_ACCEL),1) +ccflags-y += -Iservices/cp_accel +else ifeq ($(SCO_CP_ACCEL),1) +ccflags-y += -Iservices/cp_accel +endif + +ifeq ($(APP_TEST_AUDIO),1) +CFLAGS_app_audio.o += -DAPP_TEST_AUDIO +endif + +ifeq ($(AUDIO_RESAMPLE),1) +CFLAGS_a2dpplay.o += -D__AUDIO_RESAMPLE__ +CFLAGS_voicebtpcmplay.o += -D__AUDIO_RESAMPLE__ +CFLAGS_voicebtpcmplay_sco_dma_snapshot.o += -D__AUDIO_RESAMPLE__ +endif + +ifeq ($(SW_PLAYBACK_RESAMPLE),1) +CFLAGS_a2dpplay.o += -DSW_PLAYBACK_RESAMPLE +endif + +ifeq ($(RESAMPLE_ANY_SAMPLE_RATE),1) +CFLAGS_a2dpplay.o += -DRESAMPLE_ANY_SAMPLE_RATE +endif + +ifeq ($(SW_SCO_RESAMPLE),1) +CFLAGS_voicebtpcmplay.o += -DSW_SCO_RESAMPLE +CFLAGS_voicebtpcmplay_sco_dma_snapshot.o += -DSW_SCO_RESAMPLE +endif + +ifeq ($(SPEECH_TX_THIRDPARTY_ALANGO),1) +CFLAGS_bt_sco_chain_thirdparty_alango.o += -Ithirdparty/alango_lib/include +endif + +ifeq ($(VOICE_PROMPT),1) +CFLAGS_app_audio.o += -DMEDIA_PLAYER_SUPPORT +endif + +ifeq ($(AUDIO_QUEUE_SUPPORT),1) +CFLAGS_app_audio.o += -D__AUDIO_QUEUE_SUPPORT__ +endif + +ifeq ($(ANC_APP),1) +CFLAGS_app_audio.o += -DANC_APP +endif + +ifeq ($(A2DP_EQ_24BIT),1) +CFLAGS_app_audio.o += -DA2DP_EQ_24BIT +CFLAGS_a2dpplay.o += -DA2DP_EQ_24BIT +endif + +ifeq ($(A2DP_TRACE_CP_ACCEL),1) +CFLAGS_a2dpplay.o += -DA2DP_TRACE_CP_ACCEL +endif + +ifeq ($(A2DP_TRACE_DEC_TIME),1) +CFLAGS_a2dpplay.o += -DA2DP_TRACE_DEC_TIME +endif + +ifeq ($(A2DP_TRACE_CP_DEC_TIME),1) +CFLAGS_a2dpplay.o += -DA2DP_TRACE_CP_DEC_TIME +endif + +ifeq ($(SPEECH_TX_AEC_CODEC_REF),1) +CFLAGS_voicebtpcmplay.o += -DSPEECH_TX_AEC_CODEC_REF +CFLAGS_voicebtpcmplay_sco_dma_snapshot.o += -DSPEECH_TX_AEC_CODEC_REF +endif + +ifeq ($(SPEECH_RX_24BIT),1) +CFLAGS_bt_sco_chain.o += -DSPEECH_RX_24BIT +CFLAGS_voicebtpcmplay.o += -DSPEECH_RX_24BIT +CFLAGS_voicebtpcmplay_sco_dma_snapshot.o += -DSPEECH_RX_24BIT +endif + diff --git a/apps/audioplayers/a2dp_decoder/Makefile b/apps/audioplayers/a2dp_decoder/Makefile new file mode 100644 index 0000000..794450a --- /dev/null +++ b/apps/audioplayers/a2dp_decoder/Makefile @@ -0,0 +1,120 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := a2dp_decoder.o +obj-y += a2dp_decoder_sbc.o +CFLAGS_a2dp_decoder_sbc.o += -O3 + +ifeq ($(A2DP_AAC_ON),1) +obj-y += a2dp_decoder_aac_lc.o +CFLAGS_a2dp_decoder_aac_lc.o += -O3 +AAC_INCLUDES = \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libAACdec/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libAACenc/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libFDK/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libPCMutils/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libSBRdec/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libSBRenc/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libSYS/include +else +AAC_INCLUDES = +endif + +ifeq ($(A2DP_SCALABLE_ON),1) +obj-y += a2dp_decoder_scalable.o +CFLAGS_a2dp_decoder_scalable.o += -O3 +SCALABLE_INCLUDES = \ + -Ithirdparty/audio_codec_lib/scalable +else +SCALABLE_INCLUDES = +endif + +ifeq ($(A2DP_LHDC_ON),1) +obj-y += a2dp_decoder_lhdc.o +CFLAGS_a2dp_decoder_lhdc.o += -O3 +LHDC_INCLUDES = \ + -Ithirdparty/audio_codec_lib/liblhdc-dec/inc +else +LHDC_INCLUDES = +endif + +ifeq ($(A2DP_LDAC_ON),1) +obj-y += a2dp_decoder_ldac.o +CFLAGS_a2dp_decoder_ldac.o += -O3 +LDAC_INCLUDES = \ + -Ithirdparty/audio_codec_lib/ldac/inc +else +LDAC_INCLUDES = +endif + +ccflags-y := \ + $(AAC_INCLUDES) \ + $(SCALABLE_INCLUDES) \ + $(LHDC_INCLUDES) \ + $(LDAC_INCLUDES) \ + -Iservices/audio_process \ + -Iservices/app_ai/inc \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/resources \ + -Iservices/fs/fat/ChaN \ + -Iservices/bt_app \ + -Iservices/bt_app/a2dp_codecs/include \ + $(BT_IF_INCLUDES) \ + -Iplatform/drivers/uarthci \ + -Iutils/cqueue \ + -Iservices/audio_dump/include \ + -Iservices/multimedia/speech/inc \ + -Iservices/multimedia/rbcodec/inc \ + -Iservices/multimedia/audio/process/eq/include \ + -Iservices/multimedia/audio/process/resample/include \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/fm/inc \ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/include \ + -Iservices/overlay \ + -Iservices/norflash_api \ + -Iservices/nvrecord \ + -Iservices/nv_section/log_section \ + -Iapps/main \ + -Iapps/audioplayers/rbplay/ \ + -Iapps/audioplayers/a2dp_decoder \ + -Iutils/list \ + -Iutils/heap \ + -Iplatform/drivers/ana \ + -Iapps/apptester \ + -Iapps/key \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iplatform/drivers/bt \ + -Iutils/crc32 + +ifeq ($(A2DP_LHDC_ON),1) +ccflags-y += -Iservices/bt_if_enhanced/lhdc_license +endif + +ifeq ($(IBRT),1) +ccflags-y += -Iservices/ibrt_core/inc +ccflags-y += -Iservices/ibrt_ui/inc +ccflags-y += -Iservices/app_ibrt/inc +endif + +ifeq ($(A2DP_CP_ACCEL),1) +obj-y += a2dp_decoder_cp.o +ccflags-y += -Iservices/cp_accel +endif + +ifeq ($(A2DP_TRACE_CP_ACCEL),1) +ccflags-y += -DA2DP_TRACE_CP_ACCEL +endif + +ifeq ($(A2DP_TRACE_DEC_TIME),1) +ccflags-y += -DA2DP_TRACE_DEC_TIME +endif + +ifeq ($(A2DP_TRACE_CP_DEC_TIME),1) +ccflags-y += -DA2DP_TRACE_CP_DEC_TIME +endif + diff --git a/apps/audioplayers/a2dp_decoder/a2dp_decoder.cpp b/apps/audioplayers/a2dp_decoder/a2dp_decoder.cpp new file mode 100644 index 0000000..982d504 --- /dev/null +++ b/apps/audioplayers/a2dp_decoder/a2dp_decoder.cpp @@ -0,0 +1,2036 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Standard C Included Files +#include "cmsis.h" +#include "cmsis_os.h" +#include "plat_types.h" +#include +#include "heap_api.h" +#include "hal_location.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "app_bt_media_manager.h" +#include "app_bt.h" +#include "bt_drv_reg_op.h" +#include "app_audio.h" +#include "codec_sbc.h" +#include "avdtp_api.h" +#include "a2dp_decoder.h" +#include "a2dp_decoder_internal.h" +#if defined(IBRT) +#include "btapp.h" +#include "bt_drv_interface.h" +#include "app_ibrt_if.h" +#include "app_tws_ctrl_thread.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_ibrt_audio_analysis.h" +#include "app_tws_ibrt_audio_sync.h" +#endif +#include "crc32.h" +#include "audio_prompt_sbc.h" + +#ifndef A2DP_AUDIO_MEMPOOL_SIZE +#if defined(A2DP_LDAC_ON) +#define A2DP_AUDIO_LDAC_MEMPOOL_SIZE (76*1024) +#endif +#define A2DP_AUDIO_MEMPOOL_SIZE (72*1024) +#endif +#define A2DP_AUDIO_WAIT_TIMEOUT_MS (500) +#define A2DP_AUDIO_MUTE_FRAME_CNT_AFTER_NO_CACHE (25) +#define A2DP_AUDIO_SKIP_FRAME_LIMIT_AFTER_NO_CACHE (50) + +#define A2DP_AUDIO_REFILL_AFTER_NO_CACHE (1) + +#ifdef __A2DP_AUDIO_SYNC_FIX_DIFF_NOPID__ +#define A2DP_AUDIO_SYNC_INTERVAL (25) +#else +#define A2DP_AUDIO_SYNC_INTERVAL (1000) +#endif + +#define A2DP_AUDIO_LATENCY_LOW_FACTOR (1.0f) +#define A2DP_AUDIO_LATENCY_HIGH_FACTOR (1.6f) +#define A2DP_AUDIO_LATENCY_MORE_FACTOR (1.2f) + +#define A2DP_AUDIO_SYNC_FACTOR_REFERENCE (1.0f) +#define A2DP_AUDIO_SYNC_FACTOR_FAST_LIMIT ( 0.00015f) +#define A2DP_AUDIO_SYNC_FACTOR_SLOW_LIMIT (-0.00035f) +#define A2DP_AUDIO_SYNC_FACTOR_NEED_FAST_CACHE (-0.001f) + +#define A2DP_AUDIO_UNDERFLOW_CAUSE_AUDIO_RETRIGGER (1) + +extern A2DP_AUDIO_DECODER_T a2dp_audio_sbc_decoder_config; +#if defined(A2DP_AAC_ON) +extern A2DP_AUDIO_DECODER_T a2dp_audio_aac_lc_decoder_config; +#endif +#if defined(A2DP_LHDC_ON) +extern A2DP_AUDIO_DECODER_T a2dp_audio_lhdc_decoder_config; +#endif + +#if defined(A2DP_LDAC_ON) +extern A2DP_AUDIO_DECODER_T a2dp_audio_ldac_decoder_config; +#endif + + +#if defined(A2DP_SCALABLE_ON) +extern A2DP_AUDIO_DECODER_T a2dp_audio_scalable_decoder_config; +#endif + +osSemaphoreDef(audio_buffer_semaphore); +osMutexDef(audio_buffer_mutex); +osMutexDef(audio_status_mutex); +osMutexDef(audio_stop_mutex); + +#ifdef __A2DP_AUDIO_SYNC_FIX_DIFF_NOPID__ +//#define A2DP_AUDIO_SYNC_FIX_DIFF_INTERVA_PRINT_FLOAT (1) + +#define A2DP_AUDIO_SYNC_FIX_DIFF_INTERVAL (640) +#define A2DP_AUDIO_SYNC_FIX_DIFF_FAST_LIMIT ( 0.003f) +#define A2DP_AUDIO_SYNC_FIX_DIFF_SLOW_LIMIT (-0.003f) + +extern uint32_t app_bt_stream_get_dma_buffer_samples(void); +static int a2dp_audio_sync_fix_diff_proc(uint32_t tick); +static int a2dp_audio_sync_fix_diff_stop(uint32_t tick); +static int32_t a2dp_audio_sync_fix_diff_reset(void); +static int32_t a2dp_audio_sync_fix_diff_start(uint32_t tick); + +typedef enum{ + A2DP_AUDIO_SYNC_FIX_DIFF_STATUS_IDLE, + A2DP_AUDIO_SYNC_FIX_DIFF_STATUS_START, + A2DP_AUDIO_SYNC_FIX_DIFF_STATUS_STOP, +}A2DP_AUDIO_SYNC_FIX_DIFF_STATUS; + +typedef struct { + int32_t tick; + A2DP_AUDIO_SYNC_FIX_DIFF_STATUS status; +}A2DP_AUDIO_SYNC_FIX_DIFF_T; + +static A2DP_AUDIO_SYNC_FIX_DIFF_T a2dp_audio_sync_fix_diff; +#endif + +A2DP_AUDIO_CONTEXT_T a2dp_audio_context; + +static heap_handle_t a2dp_audio_heap; + +static A2DP_AUDIO_LASTFRAME_INFO_T a2dp_audio_lastframe_info; + +static A2DP_AUDIO_DETECT_NEXT_PACKET_CALLBACK a2dp_audio_detect_next_packet_callback = NULL; +static A2DP_AUDIO_DETECT_NEXT_PACKET_CALLBACK a2dp_audio_store_packet_callback = NULL; + +static float a2dp_audio_latency_factor = A2DP_AUDIO_LATENCY_LOW_FACTOR; +static float sync_tune_dest_ratio = 1.0f; + +static uint32_t store_packet_history_loctime = 0; + +static uint32_t check_sum_seed = 0; + +static int a2dp_audio_internal_lastframe_info_ptr_get(A2DP_AUDIO_LASTFRAME_INFO_T **lastframe_info); + +float a2dp_audio_get_sample_reference(void); +int8_t a2dp_audio_get_current_buf_size(void); + +void a2dp_audio_heap_init(void *begin_addr, uint32_t size) +{ + a2dp_audio_heap = heap_register(begin_addr,size); +} + +void *a2dp_audio_heap_malloc(uint32_t size) +{ + void *ptr = heap_malloc(a2dp_audio_heap,size); + ASSERT_A2DP_DECODER(ptr, "%s size:%d", __func__, size); + return ptr; +} + +void *a2dp_audio_heap_cmalloc(uint32_t size) +{ + void *ptr = heap_malloc(a2dp_audio_heap,size); + ASSERT_A2DP_DECODER(ptr, "%s size:%d", __func__, size); + memset(ptr, 0, size); + return ptr; +} + +void *a2dp_audio_heap_realloc(void *rmem, uint32_t newsize) +{ + void *ptr = heap_realloc(a2dp_audio_heap, rmem, newsize); + ASSERT_A2DP_DECODER(ptr, "%s rmem:%p size:%d", __func__, rmem,newsize); + return ptr; +} + +void a2dp_audio_heap_free(void *rmem) +{ + ASSERT_A2DP_DECODER(rmem, "%s rmem:%p", __func__, rmem); + heap_free(a2dp_audio_heap,rmem); +} + +void a2dp_audio_heap_info(size_t *total, size_t *used, size_t *max_used) +{ + multi_heap_info_t info; + heap_get_info(a2dp_audio_heap, &info); + + if (total != NULL) + *total = info.total_bytes; + + if (used != NULL) + *used = info.total_allocated_bytes; + + if (max_used != NULL) + *max_used = info.total_bytes - info.minimum_free_bytes; +} + + +int inline a2dp_audio_semaphore_init(void) +{ + if (a2dp_audio_context.audio_semaphore.semaphore == NULL){ + a2dp_audio_context.audio_semaphore.semaphore = osSemaphoreCreate(osSemaphore(audio_buffer_semaphore), 0); + } + a2dp_audio_context.audio_semaphore.enalbe = false; + return 0; +} + +int inline a2dp_audio_buffer_mutex_init(void) +{ + if (a2dp_audio_context.audio_buffer_mutex == NULL){ + a2dp_audio_context.audio_buffer_mutex = osMutexCreate((osMutex(audio_buffer_mutex))); + } + return 0; +} + +int inline a2dp_audio_buffer_mutex_lock(void) +{ + osMutexWait((osMutexId)a2dp_audio_context.audio_buffer_mutex, osWaitForever); + return 0; +} + +int inline a2dp_audio_buffer_mutex_unlock(void) +{ + osMutexRelease((osMutexId)a2dp_audio_context.audio_buffer_mutex); + return 0; +} + +int inline a2dp_audio_status_mutex_init(void) +{ + if (a2dp_audio_context.audio_status_mutex == NULL){ + a2dp_audio_context.audio_status_mutex = osMutexCreate((osMutex(audio_status_mutex))); + } + return 0; +} + +int inline a2dp_audio_status_mutex_lock(void) +{ + osMutexWait((osMutexId)a2dp_audio_context.audio_status_mutex, osWaitForever); + return 0; +} + +int inline a2dp_audio_status_mutex_unlock(void) +{ + osMutexRelease((osMutexId)a2dp_audio_context.audio_status_mutex); + return 0; +} + +int inline a2dp_audio_semaphore_wait(uint32_t timeout_ms) +{ + osSemaphoreId semaphore_id = (osSemaphoreId)a2dp_audio_context.audio_semaphore.semaphore; + + a2dp_audio_buffer_mutex_lock(); + a2dp_audio_context.audio_semaphore.enalbe = true; + a2dp_audio_buffer_mutex_unlock(); + + int32_t nRet = osSemaphoreWait(semaphore_id, timeout_ms); + if ((0 == nRet) || (-1 == nRet)){ + TRACE_A2DP_DECODER_W("%s wait timerout", __func__); + return -1; + } + return 0; +} + +int inline a2dp_audio_semaphore_release(void) +{ + bool enalbe = false; + + a2dp_audio_buffer_mutex_lock(); + if (a2dp_audio_context.audio_semaphore.enalbe){ + a2dp_audio_context.audio_semaphore.enalbe = false; + enalbe = true; + } + a2dp_audio_buffer_mutex_unlock(); + + if (enalbe){ + osSemaphoreId semaphore_id = (osSemaphoreId)a2dp_audio_context.audio_semaphore.semaphore; + osSemaphoreRelease(semaphore_id); + } + return 0; +} + +list_node_t *a2dp_audio_list_begin(const list_t *list) +{ + a2dp_audio_buffer_mutex_lock(); + list_node_t *node = list_begin(list); + a2dp_audio_buffer_mutex_unlock(); + return node; +} + +list_node_t *a2dp_audio_list_end(const list_t *list) +{ + a2dp_audio_buffer_mutex_lock(); + list_node_t *node = list_end(list); + a2dp_audio_buffer_mutex_unlock(); + return node; +} + +uint32_t a2dp_audio_list_length(const list_t *list) +{ + a2dp_audio_buffer_mutex_lock(); + uint32_t length = list_length(list); + a2dp_audio_buffer_mutex_unlock(); + return length; +} + +void *a2dp_audio_list_node(const list_node_t *node) +{ + a2dp_audio_buffer_mutex_lock(); + void *data = list_node(node); + a2dp_audio_buffer_mutex_unlock(); + return data; +} + +list_node_t *a2dp_audio_list_next(const list_node_t *node) +{ + a2dp_audio_buffer_mutex_lock(); + list_node_t *next =list_next(node); + a2dp_audio_buffer_mutex_unlock(); + return next; +} + +bool a2dp_audio_list_remove(list_t *list, void *data) +{ + a2dp_audio_buffer_mutex_lock(); + bool nRet = list_remove(list, data); + a2dp_audio_buffer_mutex_unlock(); + return nRet; +} + +bool a2dp_audio_list_append(list_t *list, void *data) +{ + a2dp_audio_buffer_mutex_lock(); + bool nRet = list_append(list, data); + a2dp_audio_buffer_mutex_unlock(); + return nRet; +} + +void a2dp_audio_list_clear(list_t *list) +{ + a2dp_audio_buffer_mutex_lock(); + list_clear(list); + a2dp_audio_buffer_mutex_unlock(); +} + +void a2dp_audio_list_free(list_t *list) +{ + a2dp_audio_buffer_mutex_lock(); + list_free(list); + a2dp_audio_buffer_mutex_unlock(); +} + +list_t *a2dp_audio_list_new(list_free_cb callback, list_mempool_zmalloc zmalloc, list_mempool_free free) +{ + a2dp_audio_buffer_mutex_lock(); + list_t *list =list_new(callback, zmalloc, free); + a2dp_audio_buffer_mutex_unlock(); + return list; +} + +uint32_t a2dp_audio_get_passed(uint32_t curr_ticks, uint32_t prev_ticks, uint32_t max_ticks) +{ + if(curr_ticks < prev_ticks) + return ((max_ticks - prev_ticks + 1) + curr_ticks); + else + return (curr_ticks - prev_ticks); +} + +#ifdef A2DP_CP_ACCEL +extern "C" uint32_t get_in_cp_frame_cnt(void); +extern "C" uint32_t get_in_cp_frame_delay(void); +#else +static uint32_t get_in_cp_frame_cnt(void) +{ + return 0; +} + +static uint32_t get_in_cp_frame_delay(void) +{ + return 0; +} +#endif + +int inline a2dp_audio_set_status(enum A2DP_AUDIO_DECODER_STATUS decoder_status) +{ + a2dp_audio_status_mutex_lock(); + a2dp_audio_context.audio_decoder_status = decoder_status; + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +enum A2DP_AUDIO_DECODER_STATUS inline a2dp_audio_get_status(void) +{ + enum A2DP_AUDIO_DECODER_STATUS decoder_status; + a2dp_audio_status_mutex_lock(); + decoder_status = a2dp_audio_context.audio_decoder_status; + a2dp_audio_status_mutex_unlock(); + + return decoder_status; +} + +int inline a2dp_audio_set_store_packet_status(enum A2DP_AUDIO_DECODER_STORE_PACKET_STATUS store_packet_status) +{ + a2dp_audio_status_mutex_lock(); + a2dp_audio_context.store_packet_status = store_packet_status; + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +enum A2DP_AUDIO_DECODER_STORE_PACKET_STATUS inline a2dp_audio_get_store_packet_status(void) +{ + enum A2DP_AUDIO_DECODER_STORE_PACKET_STATUS store_packet_status; + a2dp_audio_status_mutex_lock(); + store_packet_status = a2dp_audio_context.store_packet_status; + a2dp_audio_status_mutex_unlock(); + + return store_packet_status; +} + +int inline a2dp_audio_set_playback_status(enum A2DP_AUDIO_DECODER_PLAYBACK_STATUS playback_status) +{ + a2dp_audio_status_mutex_lock(); + a2dp_audio_context.playback_status = playback_status; + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +enum A2DP_AUDIO_DECODER_PLAYBACK_STATUS inline a2dp_audio_get_playback_status(void) +{ + enum A2DP_AUDIO_DECODER_PLAYBACK_STATUS playback_status; + a2dp_audio_status_mutex_lock(); + playback_status = a2dp_audio_context.playback_status; + a2dp_audio_status_mutex_unlock(); + + return playback_status; +} + +static void a2dp_decoder_info_checker(void) +{ +// app_bt_start_custom_function_in_app_thread(0, 0, (uint32_t)bt_drv_reg_op_bt_info_checker); +} + +int a2dp_audio_sync_pid_config(void) +{ + A2DP_AUDIO_SYNC_T *audio_sync = &a2dp_audio_context.audio_sync; + A2DP_AUDIO_SYNC_PID_T *pid = &audio_sync->pid; + + pid->proportiongain = 0.4f; + pid->integralgain = 0.1f; + pid->derivativegain = 0.6f; + + return 0; +} + +int a2dp_audio_sync_reset_data(void) +{ + A2DP_AUDIO_SYNC_T *audio_sync = &a2dp_audio_context.audio_sync; + + a2dp_audio_status_mutex_lock(); + audio_sync->tick = 0; + audio_sync->cnt = 0; + a2dp_audio_sync_pid_config(); +#ifdef __A2DP_AUDIO_SYNC_FIX_DIFF_NOPID__ + a2dp_audio_sync_fix_diff_reset(); +#endif + a2dp_audio_status_mutex_unlock(); + + TRACE_A2DP_DECODER_I("[SYNC]reset_data"); + return 0; +} + +int a2dp_audio_sync_init(double ratio) +{ +#ifdef __A2DP_AUDIO_SYNC_FIX_DIFF_NOPID__ + a2dp_audio_sync_fix_diff_reset(); +#endif + a2dp_audio_sync_reset_data(); + a2dp_audio_sync_tune_sample_rate(ratio); + sync_tune_dest_ratio = (float)ratio; + return 0; +} + +int a2dp_audio_sync_tune_sample_rate(double ratio) +{ + float resample_rate_ratio; + bool need_tune = false; + + a2dp_audio_status_mutex_lock(); + if (a2dp_audio_context.output_cfg.factor_reference != (float)ratio){ + a2dp_audio_context.output_cfg.factor_reference = (float)ratio; + resample_rate_ratio = (float)(ratio - (double)1.0); + need_tune = true; + } + //a2dp_audio_status_mutex_unlock(); + + if (need_tune){ + app_audio_manager_tune_samplerate_ratio(AUD_STREAM_PLAYBACK, resample_rate_ratio); + TRACE_A2DP_DECODER_I("[SYNC] ppb:%d ratio:%08d", + (int32_t)(resample_rate_ratio * 10000000), + (int32_t)(ratio * 10000000)); + } + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +int a2dp_audio_sync_direct_tune_sample_rate(double ratio) +{ + float resample_rate_ratio; + bool need_tune = false; + + a2dp_audio_status_mutex_lock(); + if (a2dp_audio_context.output_cfg.factor_reference != (float)ratio){ + a2dp_audio_context.output_cfg.factor_reference = (float)ratio; + resample_rate_ratio = (float)(ratio - (double)1.0); + need_tune = true; + } + + if (need_tune){ + af_codec_direct_tune(AUD_STREAM_PLAYBACK, resample_rate_ratio); + + TRACE_A2DP_DECODER_I("[SYNC] ppb:%d ratio:%08d", + (int32_t)(resample_rate_ratio * 10000000), + (int32_t)(ratio * 10000000)); + } + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +bool a2dp_audio_sync_tune_onprocess(void) +{ + bool nRet = false;; + if (a2dp_audio_context.output_cfg.factor_reference != sync_tune_dest_ratio){ + nRet = true; + } + return nRet; +} + +int a2dp_audio_sync_tune(float ratio) +{ + int nRet = 0; + if (sync_tune_dest_ratio == ratio){ + goto exit; + } + sync_tune_dest_ratio = ratio; +#if defined(IBRT) + if (app_ibrt_ui_is_profile_exchanged()){ + if (app_tws_ibrt_mobile_link_connected()){ + APP_TWS_IBRT_AUDIO_SYNC_TUNE_T sync_tune; + sync_tune.factor_reference = ratio; + if (!app_tws_ibrt_audio_sync_tune_need_skip()){ + tws_ctrl_send_cmd(APP_TWS_CMD_SYNC_TUNE, (uint8_t*)&sync_tune, sizeof(APP_TWS_IBRT_AUDIO_SYNC_TUNE_T)); + }else{ + a2dp_audio_sync_tune_cancel(); + nRet = -1; + } + } + }else{ + a2dp_audio_sync_tune_sample_rate(ratio); + } +#else + a2dp_audio_sync_tune_sample_rate(ratio); +#endif +exit: + return nRet; +} + +int a2dp_audio_sync_tune_cancel(void) +{ + sync_tune_dest_ratio = a2dp_audio_context.output_cfg.factor_reference; + return 0; +} + +float a2dp_audio_sync_pid_calc(A2DP_AUDIO_SYNC_PID_T *pid, float diff) +{ + float increment; + float pError,dError,iError; + + pid->error[0] = diff; + pError=pid->error[0]-pid->error[1]; + iError=pid->error[0]; + dError=pid->error[0]-2*pid->error[1]+pid->error[2]; + + increment = pid->proportiongain*pError+pid->integralgain*iError+pid->derivativegain*dError; + + pid->error[2] = pid->error[1]; + pid->error[1] = pid->error[0]; + + pid->result += increment; + + return pid->result; +} + +#ifdef __A2DP_AUDIO_SYNC_FIX_DIFF_NOPID__ +static int a2dp_audio_sync_fix_diff_proc(uint32_t tick) +{ + if (a2dp_audio_sync_fix_diff.status == A2DP_AUDIO_SYNC_FIX_DIFF_STATUS_START){ + if (a2dp_audio_sync_fix_diff.tick > 0){ + a2dp_audio_sync_fix_diff.tick--; + }else{ + a2dp_audio_sync_fix_diff_stop(0); + } + } + return 0; +} + +static int32_t a2dp_audio_sync_fix_diff_start(uint32_t tick) +{ + TRACE_A2DP_DECODER_I("[SYNC] fix diff start"); + + a2dp_audio_sync_fix_diff.status = A2DP_AUDIO_SYNC_FIX_DIFF_STATUS_START; + a2dp_audio_sync_fix_diff.tick = tick; + return 0; +} + +static int a2dp_audio_sync_fix_diff_stop(uint32_t tick) +{ + TRACE_A2DP_DECODER_I("[SYNC] fix diff stop"); + + a2dp_audio_sync_fix_diff.status = A2DP_AUDIO_SYNC_FIX_DIFF_STATUS_STOP; + a2dp_audio_sync_fix_diff.tick = 0; + + return 0; +} + +static int32_t a2dp_audio_sync_fix_diff_reset(void) +{ + TRACE_A2DP_DECODER_I("[SYNC] fix diff reset"); + + a2dp_audio_sync_fix_diff.status = A2DP_AUDIO_SYNC_FIX_DIFF_STATUS_IDLE; + a2dp_audio_sync_fix_diff.tick = 0; + + return 0; +} + +static A2DP_AUDIO_SYNC_FIX_DIFF_STATUS a2dp_audio_sync_fix_diff_status_get(void) +{ + return a2dp_audio_sync_fix_diff.status; +} + +int a2dp_audio_sync_handler(uint8_t *buffer, uint32_t buffer_bytes) +{ + A2DP_AUDIO_LASTFRAME_INFO_T *lastframe_info = NULL; + A2DP_AUDIO_SYNC_T *audio_sync = &a2dp_audio_context.audio_sync; + float diff_mtu = 0; + bool need_tune = false; + bool force_slow = false; + +#if defined(IBRT) + if (!app_tws_ibrt_mobile_link_connected()){ + return -1; + } +#endif + if (a2dp_audio_internal_lastframe_info_ptr_get(&lastframe_info) < 0){ + return -1; + } + + a2dp_audio_sync_fix_diff_proc(audio_sync->tick); + if (a2dp_audio_sync_fix_diff_status_get() == A2DP_AUDIO_SYNC_FIX_DIFF_STATUS_STOP){ +#if defined(IBRT) + if (!app_tws_ibrt_audio_sync_tune_onprocess() && + !a2dp_audio_sync_tune_onprocess() +#else + if (!a2dp_audio_sync_tune_onprocess() +#endif + ){ + int sync_tune_result = 0; + if (a2dp_audio_context.output_cfg.factor_reference != a2dp_audio_context.init_factor_reference){ + sync_tune_result = a2dp_audio_sync_tune(a2dp_audio_context.init_factor_reference); + } + if (!sync_tune_result){ + a2dp_audio_sync_fix_diff_reset(); +#ifdef A2DP_AUDIO_SYNC_FIX_DIFF_INTERVA_PRINT_FLOAT + TRACE_A2DP_DECODER_I("[SYNC] tune ratio normal %f mut:%5.3f->%d", (double)a2dp_audio_context.init_factor_reference, + (double)a2dp_audio_context.average_packet_mut, + a2dp_audio_context.dest_packet_mut); +#else + TRACE_A2DP_DECODER_I("[SYNC] tune ratio normal %d mut:%d->%d", (int32_t)(a2dp_audio_context.init_factor_reference * 10000000), + (int32_t)(a2dp_audio_context.average_packet_mut+0.5f), + a2dp_audio_context.dest_packet_mut); +#endif + }else{ + TRACE_A2DP_DECODER_I("[SYNC] tune ratio normal busy"); + } + + }else{ +#ifdef A2DP_AUDIO_SYNC_FIX_DIFF_INTERVA_PRINT_FLOAT + TRACE_A2DP_DECODER_I("[SYNC] tune ratio busy %f mut:%5.3f->%d", (double)a2dp_audio_context.init_factor_reference, + (double)a2dp_audio_context.average_packet_mut, + a2dp_audio_context.dest_packet_mut); +#else + TRACE_A2DP_DECODER_I("[SYNC] tune ratio busy %d mut:%d->%d", (int32_t)(a2dp_audio_context.init_factor_reference * 10000000), + (int32_t)(a2dp_audio_context.average_packet_mut+0.5f), + a2dp_audio_context.dest_packet_mut); +#endif + } + goto exit; + } + + if (audio_sync->tick%A2DP_AUDIO_SYNC_INTERVAL == 0){ + diff_mtu = a2dp_audio_context.average_packet_mut-(float)a2dp_audio_context.dest_packet_mut; + if (ABS(diff_mtu) < 0.6f){ +#ifdef A2DP_AUDIO_SYNC_FIX_DIFF_INTERVA_PRINT_FLOAT + TRACE_A2DP_DECODER_I("[SYNC] skip mut:%5.3f", (double)diff_mtu); +#else + TRACE_A2DP_DECODER_I("[SYNC] skip mut:0.%d", (int32_t)(diff_mtu*10)); +#endif + goto exit; + }else if (diff_mtu/a2dp_audio_context.dest_packet_mut < -0.2f){ + float curr_ratio = a2dp_audio_context.output_cfg.factor_reference; + float ref_ratio = a2dp_audio_context.init_factor_reference; + if (curr_ratio != (ref_ratio + A2DP_AUDIO_SYNC_FIX_DIFF_SLOW_LIMIT)){ +#ifdef A2DP_AUDIO_SYNC_FIX_DIFF_INTERVA_PRINT_FLOAT + TRACE_A2DP_DECODER_I("[SYNC] force slow mut:%5.3f", (double)diff_mtu); +#else + TRACE_A2DP_DECODER_I("[SYNC] force slow mut:0.%d", (int32_t)(diff_mtu*10)); +#endif + force_slow = true; + } + } + if (a2dp_audio_sync_fix_diff_status_get() == A2DP_AUDIO_SYNC_FIX_DIFF_STATUS_IDLE || + force_slow){ + uint32_t dma_buffer_samples, samples, dma_interval; + double ratio = 1.0, limit_ratio = 1.0; + float sampleRate, ref_ratio, curr_ratio; + float ref_us = 0; + float dest_us = 0; + float sample_us =0; + + dma_buffer_samples = app_bt_stream_get_dma_buffer_samples()/2; + dma_interval = A2DP_AUDIO_SYNC_FIX_DIFF_INTERVAL; + + ref_ratio = a2dp_audio_context.init_factor_reference; + curr_ratio = a2dp_audio_context.output_cfg.factor_reference; + + samples = dma_interval*dma_buffer_samples; + sampleRate = lastframe_info->stream_info.sample_rate * ref_ratio; + + sample_us = 1e6 / sampleRate; + ref_us = sample_us * (float)samples; + dest_us = sample_us * (float)(lastframe_info->frame_samples * diff_mtu); + ratio = ref_us/(ref_us - dest_us)*curr_ratio; + + if (ratio > (double)(ref_ratio + A2DP_AUDIO_SYNC_FIX_DIFF_FAST_LIMIT)){ + limit_ratio = ref_ratio + A2DP_AUDIO_SYNC_FIX_DIFF_FAST_LIMIT; + }else if (ratio < double(ref_ratio + A2DP_AUDIO_SYNC_FIX_DIFF_SLOW_LIMIT)){ + limit_ratio = ref_ratio + A2DP_AUDIO_SYNC_FIX_DIFF_SLOW_LIMIT; + }else{ + limit_ratio = ratio; + } + TRACE_A2DP_DECODER_I("[SYNC] sampleRate:%d ref_ratio:%d samples:%d %d->%d", (int32_t)sampleRate, + (int32_t)(ref_ratio * 10000000), + samples, + (int32_t)ref_us, + (int32_t)dest_us); + need_tune = true; +#if defined(IBRT) + if (!app_tws_ibrt_audio_sync_tune_onprocess() && + !a2dp_audio_sync_tune_onprocess() && +#else + if (!a2dp_audio_sync_tune_onprocess() && +#endif + need_tune){ + if (!a2dp_audio_sync_tune((float)limit_ratio)){ + a2dp_audio_sync_fix_diff_start(dma_interval); +#ifdef A2DP_AUDIO_SYNC_FIX_DIFF_INTERVA_PRINT_FLOAT + TRACE_A2DP_DECODER_I("[SYNC] tune ratio %f mut:%5.3f->%d", limit_ratio, + (double)a2dp_audio_context.average_packet_mut, + a2dp_audio_context.dest_packet_mut); +#else + TRACE_A2DP_DECODER_I("[SYNC] tune ratio %d mut:%d->%d", (int32_t)(limit_ratio * 10000000), + (int32_t)(a2dp_audio_context.average_packet_mut+0.5f), + a2dp_audio_context.dest_packet_mut); +#endif + }else{ + TRACE_A2DP_DECODER_I("[SYNC] tune ratio busy"); + } + } + }else{ + TRACE_A2DP_DECODER_I("[SYNC] avg_mut:%d dest_mtu:%d", (int32_t)(a2dp_audio_context.average_packet_mut+0.5f), + a2dp_audio_context.dest_packet_mut); + } + }else{ + + } +exit: + audio_sync->tick++; + return 0; +} +#else +int a2dp_audio_sync_handler(uint8_t *buffer, uint32_t buffer_bytes) +{ + A2DP_AUDIO_LASTFRAME_INFO_T *lastframe_info = NULL; + A2DP_AUDIO_SYNC_T *audio_sync = &a2dp_audio_context.audio_sync; + float dest_pid_result = .0f; + float diff_mtu = 0; + int32_t frame_mtu = 0; + int32_t total_mtu = 0; + float diff_factor = 0; + +#if defined(IBRT) + if (!app_tws_ibrt_mobile_link_connected()){ + return -1; + } +#endif + if (a2dp_audio_internal_lastframe_info_ptr_get(&lastframe_info) < 0){ + return -1; + } + + if (audio_sync->tick++%A2DP_AUDIO_SYNC_INTERVAL == 0){ + list_t *list = a2dp_audio_context.audio_datapath.input_raw_packet_list; + A2DP_AUDIO_SYNC_PID_T *pid = &audio_sync->pid; + //valid limter 0x80000 + if (audio_sync->cnt < 0x80000){ + audio_sync->cnt += A2DP_AUDIO_SYNC_INTERVAL; + } + frame_mtu = lastframe_info->stream_info.frame_samples/lastframe_info->frame_samples; + total_mtu = audio_sync->cnt * frame_mtu; + diff_mtu = a2dp_audio_context.average_packet_mut-(float)a2dp_audio_context.dest_packet_mut; +#if 1 + TRACE_A2DP_DECODER_I("[SYNC] sample:%d/%d diff:%d/%d/%d/%d curr:%d", lastframe_info->frame_samples, + lastframe_info->stream_info.frame_samples, + (int32_t)(diff_mtu+0.5f), + (int32_t)(a2dp_audio_context.average_packet_mut+0.5f), + a2dp_audio_context.dest_packet_mut, + total_mtu, + a2dp_audio_list_length(list) + get_in_cp_frame_cnt()); +#else + TRACE_A2DP_DECODER_I("[SYNC] diff:%10.9f/%10.9f frame_mut:%d dest:%d total:%d curr:%d", (double)diff_mtu, (double)a2dp_audio_context.average_packet_mut, frame_mtu, + a2dp_audio_context.dest_packet_mut, total_mtu, a2dp_audio_list_length(list)); + TRACE_A2DP_DECODER_I("[SYNC] try tune:%d, %10.9f %10.9f", diff_mtu != 0.f && audio_sync->tick != 1 ? ABS(diff_mtu) > ((float)frame_mtu * 0.2f): 0, + (double)ABS(diff_mtu), (double)((float)frame_mtu * 0.2f)); +#endif + //TRACE(2,"audio_sync tune %d/%d tick", app_tws_ibrt_audio_sync_tune_onprocess(), a2dp_audio_sync_tune_onprocess(), audio_sync->tick); + +#if defined(IBRT) + if ((!app_tws_ibrt_audio_sync_tune_onprocess() && + !a2dp_audio_sync_tune_onprocess()) && +#else + if (!a2dp_audio_sync_tune_onprocess() && +#endif + diff_mtu != 0.f && audio_sync->tick != 1 && + ((ABS(diff_mtu) > ((float)frame_mtu * 0.25f) && diff_mtu > 0)|| + (ABS(diff_mtu) > ((float)frame_mtu * 0.1f) && diff_mtu < 0))){ + diff_factor = diff_mtu/a2dp_audio_context.average_packet_mut; + if (a2dp_audio_sync_pid_calc(pid, diff_factor)){ + dest_pid_result = a2dp_audio_context.output_cfg.factor_reference + pid->result; + + if (dest_pid_result > (A2DP_AUDIO_SYNC_FACTOR_REFERENCE + A2DP_AUDIO_SYNC_FACTOR_FAST_LIMIT)){ + dest_pid_result = A2DP_AUDIO_SYNC_FACTOR_REFERENCE + A2DP_AUDIO_SYNC_FACTOR_FAST_LIMIT; + }else if (dest_pid_result < (A2DP_AUDIO_SYNC_FACTOR_REFERENCE + A2DP_AUDIO_SYNC_FACTOR_SLOW_LIMIT)){ + dest_pid_result = A2DP_AUDIO_SYNC_FACTOR_REFERENCE + A2DP_AUDIO_SYNC_FACTOR_SLOW_LIMIT; + } + + if (a2dp_audio_context.output_cfg.factor_reference != dest_pid_result){ + if (!a2dp_audio_sync_tune(dest_pid_result)){ + audio_sync->cnt = 0; + } + TRACE_A2DP_DECODER_I("[SYNC] tune diff_factor:%10.9f pid:%10.9f tune:%10.9f", (double)diff_factor, (double)pid->result, (double)dest_pid_result); + }else{ + TRACE_A2DP_DECODER_I("[SYNC] tune skip same"); + } + } + }else{ +/* + TRACE_A2DP_DECODER_I("[SYNC] tune busy skip proc:%d/%d mtu:%d tick:%d >0:%d <0:%d tick:%d", app_tws_ibrt_audio_sync_tune_onprocess(), + a2dp_audio_sync_tune_onprocess(), + diff_mtu != 0.f, + audio_sync->tick != 1, + (ABS(diff_mtu) > ((float)frame_mtu * 0.25f) && diff_mtu > 0), + (ABS(diff_mtu) > ((float)frame_mtu * 0.1f) && diff_mtu < 0), + audio_sync->tick); +*/ + } + }else{ + bool need_tune = false; + if (lastframe_info->undecode_min_frames*10 <= a2dp_audio_context.dest_packet_mut*10/3){ + dest_pid_result = a2dp_audio_context.init_factor_reference + A2DP_AUDIO_SYNC_FACTOR_NEED_FAST_CACHE; + need_tune = true; + }else if (lastframe_info->undecode_min_frames*10 <= a2dp_audio_context.dest_packet_mut*20/3){ + dest_pid_result = a2dp_audio_context.init_factor_reference + A2DP_AUDIO_SYNC_FACTOR_SLOW_LIMIT; + need_tune = true; + } +#if defined(IBRT) + if (!app_tws_ibrt_audio_sync_tune_onprocess() && + !a2dp_audio_sync_tune_onprocess() && +#else + if (!a2dp_audio_sync_tune_onprocess() && +#endif + + need_tune){ + if (a2dp_audio_context.output_cfg.factor_reference != dest_pid_result){ + a2dp_audio_sync_reset_data(); + a2dp_audio_sync_tune(dest_pid_result); + TRACE_A2DP_DECODER_I("[SYNC] tune ratio force slow %d/%d->%d", lastframe_info->undecode_min_frames, + lastframe_info->undecode_max_frames, + a2dp_audio_context.dest_packet_mut); + } + } + } + return 0; +} +#endif + +#if A2DP_DECODER_HISTORY_SEQ_SAVE +static int a2dp_audio_reset_history_seq(void) +{ + a2dp_audio_status_mutex_lock(); + for (uint8_t i=0; isequenceNumber - historySeqPre)!= 1){ + TRACE_A2DP_DECODER_W("[INPUT] SEQ ERR %d/%d",historySeqPre, header->sequenceNumber); + a2dp_audio_show_history_seq(); + } + } + historySeq_idx = a2dp_audio_context.historySeq_idx%A2DP_DECODER_HISTORY_SEQ_SAVE; + a2dp_audio_context.historySeq[historySeq_idx] = header->sequenceNumber; +#ifdef A2DP_DECODER_HISTORY_LOCTIME_SAVE + a2dp_audio_context.historyLoctime[historySeq_idx] = hal_fast_sys_timer_get(); +#endif +#ifdef A2DP_DECODER_HISTORY_CHECK_SUM_SAVE + a2dp_audio_context.historyChecksum[historySeq_idx] = crc32(0, buf, len); +#endif + a2dp_audio_context.historySeq_idx++; + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +int a2dp_audio_show_history_seq(void) +{ + uint8_t i = 0, j = 1; + uint16_t reordHistorySeq[A2DP_DECODER_HISTORY_SEQ_SAVE]; +#ifdef A2DP_DECODER_HISTORY_LOCTIME_SAVE + int32_t diff_max_idx = 0; + int32_t diff_max_ms = 0; + int64_t diff_avg_ms = 0; + int32_t diff_avg_cnt = 0; + uint32_t historyLoctime[A2DP_DECODER_HISTORY_SEQ_SAVE]; +#endif +#ifdef A2DP_DECODER_HISTORY_CHECK_SUM_SAVE + uint32_t historyChecksum[A2DP_DECODER_HISTORY_SEQ_SAVE]; +#endif + + a2dp_audio_status_mutex_lock(); + for (i=0; i reordHistorySeq[j+1]) { + uint16_t temp_seq = reordHistorySeq[j]; + reordHistorySeq[j] = reordHistorySeq[j+1]; + reordHistorySeq[j+1] = temp_seq; +#ifdef A2DP_DECODER_HISTORY_LOCTIME_SAVE + uint32_t temp_Loctime = historyLoctime[j]; + historyLoctime[j] = historyLoctime[j+1]; + historyLoctime[j+1] = temp_Loctime; +#endif +#ifdef A2DP_DECODER_HISTORY_CHECK_SUM_SAVE + uint32_t temp_Checksum = historyChecksum[j]; + historyChecksum[j] = historyChecksum[j+1]; + historyChecksum[j+1] = temp_Checksum; +#endif + } + } + } +#ifdef A2DP_DECODER_HISTORY_LOCTIME_SAVE + for (i = 0, j = 1; i diff_max_ms){ + diff_max_ms = tmp_ms; + diff_max_idx = i; + } + if (tmp_ms > (int32_t)MS_TO_FAST_TICKS(50)){ + TRACE_A2DP_DECODER_I("[INPUT] > 30ms seq:%d diff:%d :%d / %d", reordHistorySeq[i], FAST_TICKS_TO_MS(tmp_ms), historyLoctime[i], historyLoctime[j]); + } + } + diff_avg_ms /= diff_avg_cnt; + TRACE_A2DP_DECODER_I("[INPUT] max_diff:%dms idx:%d avg:%dus", FAST_TICKS_TO_MS(diff_max_ms), diff_max_idx, FAST_TICKS_TO_US(diff_avg_ms)); +#endif +// DUMP16("%d ", reordHistorySeq, A2DP_DECODER_HISTORY_SEQ_SAVE); +#ifdef A2DP_DECODER_HISTORY_LOCTIME_SAVE + DUMP32("%x ", historyLoctime, A2DP_DECODER_HISTORY_SEQ_SAVE); +#endif +#ifdef A2DP_DECODER_HISTORY_CHECK_SUM_SAVE + DUMP32("%x ", historyChecksum, A2DP_DECODER_HISTORY_SEQ_SAVE); +#endif + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +#endif + +/* +1, 2^1 +3, 2^2 +7, 2^3 +15, 2^4 +31, 2^5 +*/ +#define AUDIO_ALPHA_PRAMS_1 (3) +#define AUDIO_ALPHA_PRAMS_2 (4) + +static inline float a2dp_audio_alpha_filter(float y, float x) +{ + if (y){ + y = ((AUDIO_ALPHA_PRAMS_1*y)+x)/AUDIO_ALPHA_PRAMS_2; + }else{ + y = x; + } + return y; +} + +static void inline a2dp_audio_convert_16bit_to_24bit(int32_t *out, int16_t *in, int len) +{ + for (int i = len - 1; i >= 0; i--) { + out[i] = ((int32_t)in[i] << 8); + } +} + +static void inline a2dp_audio_channel_select(A2DP_AUDIO_CHANNEL_SELECT_E chnl_sel, uint8_t *buffer, uint32_t buffer_bytes) +{ + uint32_t samples; + uint32_t i; + + ASSERT_A2DP_DECODER(a2dp_audio_context.output_cfg.num_channels == 2, "%s num_channels:%d", __func__, a2dp_audio_context.output_cfg.num_channels); + + if (a2dp_audio_context.output_cfg.bits_depth == 24){ + int32_t *buf_l_p = (int32_t *)buffer; + int32_t *buf_r_p = (int32_t *)buffer + 1; + + samples = buffer_bytes/4/2; + switch (chnl_sel) + { + case A2DP_AUDIO_CHANNEL_SELECT_LRMERGE: + for (i = 0; i>1; + *buf_l_p = tmp_sample; + *buf_r_p = tmp_sample; + } + break; + case A2DP_AUDIO_CHANNEL_SELECT_LCHNL: + for (i = 0; i>1; + *buf_l_p = tmp_sample; + *buf_r_p = tmp_sample; + } + break; + case A2DP_AUDIO_CHANNEL_SELECT_LCHNL: + for (i = 0; iframe_samples) ){ + cp_frame_mtus = cp_frame_mtus /(info->frame_samples) +1; + }else{ + cp_frame_mtus = cp_frame_mtus /(info->frame_samples); + } + + TRACE_A2DP_DECODER_I("[CP] cp_frame_mtus:%d", cp_frame_mtus); + + return cp_frame_mtus; +} + +#else +bool is_cp_need_reset(void) +{ + return false; +} + + +#endif + +#define A2DP_AUDIO_SYSFREQ_BOOST_RESUME_CNT (20) +uint32_t a2dp_audio_sysfreq_cnt = UINT32_MAX; +uint32_t a2dp_audio_sysfreq_dest_boost_cnt = 0; +APP_SYSFREQ_FREQ_T a2dp_audio_sysfreq_normalfreq = APP_SYSFREQ_52M; + +int a2dp_audio_sysfreq_boost_init(uint32_t normalfreq) +{ + a2dp_audio_sysfreq_cnt = UINT32_MAX; + a2dp_audio_sysfreq_dest_boost_cnt = 0; + a2dp_audio_sysfreq_normalfreq = (APP_SYSFREQ_FREQ_T)normalfreq; + TRACE_A2DP_DECODER_I("[BOOST] freq:%d", normalfreq); + return 0; +} + +int a2dp_audio_sysfreq_boost_start(uint32_t boost_cnt) +{ + enum APP_SYSFREQ_FREQ_T sysfreq = APP_SYSFREQ_104M; + + a2dp_audio_sysfreq_cnt = 0; + a2dp_audio_sysfreq_dest_boost_cnt = boost_cnt; + if (a2dp_audio_sysfreq_normalfreq >= APP_SYSFREQ_52M){ + sysfreq = APP_SYSFREQ_104M; + }else{ + sysfreq = APP_SYSFREQ_52M; + } + TRACE_A2DP_DECODER_I("[BOOST] freq:%d cnt:%d", sysfreq, boost_cnt); + app_sysfreq_req(APP_SYSFREQ_USER_BT_A2DP, sysfreq); + return 0; +} + +static int a2dp_audio_sysfreq_boost_porc(void) +{ + if (a2dp_audio_sysfreq_cnt == UINT32_MAX){ + //do nothing + }else if (a2dp_audio_sysfreq_cnt >= a2dp_audio_sysfreq_dest_boost_cnt){ + a2dp_audio_sysfreq_cnt = UINT32_MAX; + TRACE_A2DP_DECODER_I("[BOOST] freq:%d", a2dp_audio_sysfreq_normalfreq); + app_sysfreq_req(APP_SYSFREQ_USER_BT_A2DP, a2dp_audio_sysfreq_normalfreq); + }else{ + a2dp_audio_sysfreq_cnt++; + } + return 0; +} + +int a2dp_audio_sysfreq_boost_running(void) +{ + return a2dp_audio_sysfreq_cnt == UINT32_MAX ? 0 : 1; +} + +int a2dp_audio_store_packet_checker_start(void) +{ + store_packet_history_loctime = 0; + return 0; +} + +int a2dp_audio_store_packet_checker(btif_media_header_t *header) +{ + bool show_info = false; + uint32_t fast_sys_tick = hal_fast_sys_timer_get(); + int32_t tmp_ms = 0; + + if (store_packet_history_loctime){ + tmp_ms = fast_sys_tick - store_packet_history_loctime; + if (tmp_ms > (int32_t)MS_TO_FAST_TICKS(50)){ + show_info = true; + } + } + + if (show_info){ + //TRACE_A2DP_DECODER_I("[INPUT] >50ms seq:%d diff:%d", header->sequenceNumber, FAST_TICKS_TO_MS(tmp_ms)); + a2dp_decoder_info_checker(); + } + + store_packet_history_loctime = fast_sys_tick; + + if (a2dp_audio_context.historySeq_idx && + ((a2dp_audio_context.historySeq_idx-1)%A2DP_DECODER_HISTORY_SEQ_SAVE == 0)){ + a2dp_audio_show_history_seq(); + } + + return 0; +} +//#define DECODER_ERR_TEST +int a2dp_audio_store_packet(btif_media_header_t * header, unsigned char *buf, unsigned int len) +{ + int nRet = A2DP_DECODER_NO_ERROR; + + if( a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_NULL) + {//if mem deinit , drop data + return nRet; + } + a2dp_audio_status_mutex_lock(); + +#ifdef DECODER_ERR_TEST + static uint16_t cnt = 0; + static uint16_t limit = 500; + cnt++; + if(cnt%limit==0){ + cnt = 0; + limit = rand()%500; + uint16_t len2 = rand()%len; + memset(buf+len-len2,0,len2); + TRACE_A2DP_DECODER_I("[INPUT] Fill Err!!!! seq:%d", header->sequenceNumber); + } +#endif +#if A2DP_DECODER_HISTORY_SEQ_SAVE + a2dp_audio_save_history_seq(header, buf, len); +#endif + a2dp_audio_set_store_packet_status(A2DP_AUDIO_DECODER_STORE_PACKET_STATUS_BUSY); + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + a2dp_audio_store_packet_checker(header); + if (a2dp_audio_context.need_detect_first_packet){ + a2dp_audio_context.need_detect_first_packet = false; + a2dp_audio_context.audio_decoder.audio_decoder_preparse_packet(header, buf, len); + } + + if (a2dp_audio_detect_next_packet_callback){ + a2dp_audio_detect_next_packet_callback(header, buf, len); + } + + nRet = a2dp_audio_context.audio_decoder.audio_decoder_store_packet(header, buf, len); +#if defined(IBRT) + if (is_cp_need_reset()){ + TRACE_A2DP_DECODER_I("[CP] find cp error need restart"); + app_ibrt_if_force_audio_retrigger(); + + } + if (nRet == A2DP_DECODER_MTU_LIMTER_ERROR){ + if (app_tws_ibrt_mobile_link_connected()){ + // try again + //a2dp_audio_semaphore_wait(A2DP_AUDIO_WAIT_TIMEOUT_MS); + nRet = a2dp_audio_context.audio_decoder.audio_decoder_store_packet(header, buf, len); + } + if (nRet == A2DP_DECODER_MTU_LIMTER_ERROR){ + int dest_discards_samples = 0; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if(p_ibrt_ctrl == NULL) + { + return A2DP_DECODER_NOT_SUPPORT; + } + if (app_tws_ibrt_mobile_link_connected()){ + bt_syn_trig_checker(p_ibrt_ctrl->mobile_conhandle); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + bt_syn_trig_checker(p_ibrt_ctrl->ibrt_conhandle); + } + dest_discards_samples = app_bt_stream_get_dma_buffer_samples()/2; + a2dp_audio_discards_samples(dest_discards_samples*2); + a2dp_audio_context.audio_decoder.audio_decoder_store_packet(header, buf, len); + TRACE_A2DP_DECODER_I("[INPUT] MTU_LIMTER so discards_packet"); + } + } +#else + if (is_cp_need_reset()){ + TRACE_A2DP_DECODER_I("[CP] find cp error need restart"); + app_audio_decode_err_force_trigger(); + } + + if (nRet == A2DP_DECODER_MTU_LIMTER_ERROR){ + a2dp_audio_synchronize_dest_packet_mut(a2dp_audio_context.dest_packet_mut); + a2dp_audio_context.audio_decoder.audio_decoder_store_packet(header, buf, len); + TRACE_A2DP_DECODER_W("[INPUT] MTU_LIMTER so discards_packet"); + } +#endif + }else{ + TRACE(2,"[INPUT] skip packet status:%d", a2dp_audio_get_status()); + } + + if (a2dp_audio_store_packet_callback){ + a2dp_audio_store_packet_callback(header, buf, len); + } + + a2dp_audio_set_store_packet_status(A2DP_AUDIO_DECODER_STORE_PACKET_STATUS_IDLE); + a2dp_audio_status_mutex_unlock(); + return 0; +} + +uint32_t a2dp_audio_playback_handler(uint8_t *buffer, uint32_t buffer_bytes) +{ + uint32_t len = buffer_bytes; + int nRet = A2DP_DECODER_NO_ERROR; + A2DP_AUDIO_LASTFRAME_INFO_T *lastframe_info = NULL; + list_t *list = a2dp_audio_context.audio_datapath.input_raw_packet_list; + + a2dp_audio_set_playback_status(A2DP_AUDIO_DECODER_PLAYBACK_STATUS_BUSY); + if (a2dp_audio_get_status() != A2DP_AUDIO_DECODER_STATUS_START){ + TRACE_A2DP_DECODER_W("[PLAYBACK] skip handler status:%d", a2dp_audio_get_status()); + goto exit; + } + + a2dp_audio_sysfreq_boost_porc(); + if (a2dp_audio_context.average_packet_mut == 0){ + A2DP_AUDIO_HEADFRAME_INFO_T headframe_info; + a2dp_audio_decoder_headframe_info_get(&headframe_info); + a2dp_audio_context.average_packet_mut = a2dp_audio_list_length(list); + TRACE_A2DP_DECODER_I("[PLAYBACK] init average_packet_mut:%d seq:%d", (uint16_t)(a2dp_audio_context.average_packet_mut+0.5f), headframe_info.sequenceNumber); + }else{ + if (!a2dp_audio_refill_packet()){ + uint16_t packet_mut = 0; + if (!a2dp_audio_internal_lastframe_info_ptr_get(&lastframe_info)){ + packet_mut = a2dp_audio_list_length(list) + get_in_cp_frame_cnt() + get_in_cp_frame_delay() * (lastframe_info->frame_samples /lastframe_info->list_samples); + a2dp_audio_context.average_packet_mut = a2dp_audio_alpha_filter((float)a2dp_audio_context.average_packet_mut, (float)packet_mut); + a2dp_audio_sync_handler(buffer, buffer_bytes); + } + } + } +#if defined(A2DP_AUDIO_REFILL_AFTER_NO_CACHE) + if (a2dp_audio_context.skip_frame_cnt_after_no_cache){ +#if defined(A2DP_CP_ACCEL) + uint32_t cp_delay_mtus = get_in_cp_frame_delay(); + cp_delay_mtus *= get_cp_frame_mtus(&a2dp_audio_lastframe_info); + if (a2dp_audio_list_length(list) >= (a2dp_audio_context.dest_packet_mut - cp_delay_mtus)){ + a2dp_audio_context.skip_frame_cnt_after_no_cache = 0; + } +#else + if (a2dp_audio_list_length(list) >= a2dp_audio_context.dest_packet_mut){ + a2dp_audio_context.skip_frame_cnt_after_no_cache = 0; + } +#endif + + memset(buffer, 0, buffer_bytes); + TRACE_A2DP_DECODER_I("[PLAYBACK] decode refill skip_cnt:%d, list:%d", a2dp_audio_context.skip_frame_cnt_after_no_cache, a2dp_audio_list_length(list)); + a2dp_decoder_info_checker(); + if (a2dp_audio_context.skip_frame_cnt_after_no_cache > 0){ + a2dp_audio_context.skip_frame_cnt_after_no_cache--; + }else{ + a2dp_audio_context.mute_frame_cnt_after_no_cache = A2DP_AUDIO_MUTE_FRAME_CNT_AFTER_NO_CACHE; + } + }else +#endif + { + if (a2dp_audio_context.output_cfg.bits_depth == 24 && + 16 == bt_sbc_player_get_sample_bit()){ + + len = len / (sizeof(int32_t) / sizeof(int16_t)); + + nRet = a2dp_audio_context.audio_decoder.audio_decoder_decode_frame(buffer, len); + if (nRet < 0 || a2dp_audio_context.mute_frame_cnt_after_no_cache){ + TRACE_A2DP_DECODER_I("[PLAYBACK] decode failed nRet=%d mute_cnt:%d", nRet, a2dp_audio_context.mute_frame_cnt_after_no_cache); + a2dp_decoder_info_checker(); + //mute frame + memset(buffer, 0, len); + } + a2dp_audio_convert_16bit_to_24bit((int32_t *)buffer, (int16_t *)buffer, len / sizeof(int16_t)); + + // Restore len to 24-bit sample buffer length + len = len * (sizeof(int32_t) / sizeof(int16_t)); + + }else if (a2dp_audio_context.output_cfg.bits_depth == + a2dp_audio_context.audio_decoder.stream_info.bits_depth){ + + nRet = a2dp_audio_context.audio_decoder.audio_decoder_decode_frame(buffer, len); + if (nRet < 0 || a2dp_audio_context.mute_frame_cnt_after_no_cache){ + //mute frame + TRACE_A2DP_DECODER_I("[PLAYBACK] decode failed nRet=%d mute_cnt:%d", nRet, a2dp_audio_context.mute_frame_cnt_after_no_cache); + a2dp_decoder_info_checker(); + memset(buffer, 0, len); + } + + } + a2dp_audio_channel_select(a2dp_audio_context.chnl_sel, buffer, buffer_bytes); + } + a2dp_audio_semaphore_release(); + + if (nRet == A2DP_DECODER_CACHE_UNDERFLOW_ERROR) + { + if (a2dp_audio_internal_lastframe_info_ptr_get(&lastframe_info) < 0) + { + goto exit; + } + TRACE(2,"CACHE_UNDERFLOW lastseq:%d ftick:%d", lastframe_info->sequenceNumber, hal_fast_sys_timer_get()); + a2dp_audio_show_history_seq(); + uint32_t mute_frames = A2DP_AUDIO_MUTE_FRAME_CNT_AFTER_NO_CACHE; + uint32_t skip_frames = A2DP_AUDIO_SKIP_FRAME_LIMIT_AFTER_NO_CACHE - get_in_cp_frame_delay(); + a2dp_audio_context.mute_frame_cnt_after_no_cache = (uint32_t)((float)mute_frames * + a2dp_audio_latency_factor_get()); + a2dp_audio_context.skip_frame_cnt_after_no_cache = (uint32_t)((float)skip_frames * + a2dp_audio_latency_factor_get()); + + a2dp_audio_context.average_packet_mut = 0; + a2dp_audio_sync_reset_data(); +#if defined(IBRT) + + a2dp_audio_sync_tune_sample_rate(app_tws_ibrt_audio_sync_config_factor_reference_get()); +#else + a2dp_audio_sync_tune_sample_rate(a2dp_audio_context.init_factor_reference); +#endif + a2dp_decoder_info_checker(); + }else{ + if (a2dp_audio_context.mute_frame_cnt_after_no_cache > 0){ + a2dp_audio_context.mute_frame_cnt_after_no_cache--; + a2dp_audio_context.average_packet_mut = 0; + if (a2dp_audio_context.mute_frame_cnt_after_no_cache >= 1){ + a2dp_audio_synchronize_dest_packet_mut(a2dp_audio_context.dest_packet_mut); + } + } + } + if (!a2dp_audio_internal_lastframe_info_ptr_get(&lastframe_info)){ + lastframe_info->stream_info.factor_reference = a2dp_audio_context.output_cfg.factor_reference; + lastframe_info->average_frames = (uint32_t)(a2dp_audio_context.average_packet_mut + 0.5f); + } +exit: + a2dp_audio_set_playback_status(A2DP_AUDIO_DECODER_PLAYBACK_STATUS_IDLE); +#if defined(IBRT) + if (nRet == A2DP_DECODER_CACHE_UNDERFLOW_ERROR){ +#if defined(A2DP_AUDIO_UNDERFLOW_CAUSE_AUDIO_RETRIGGER) + bool force_audio_retrigger = true; +#else + bool force_audio_retrigger = false; +#endif + if (a2dp_audio_latency_factor_get() == A2DP_AUDIO_LATENCY_LOW_FACTOR && + app_tws_ibrt_mobile_link_connected()){ + a2dp_audio_latency_factor_sethigh(); + if (app_tws_ibrt_tws_link_connected() && + app_ibrt_ui_is_profile_exchanged()){ + float latency_factor = a2dp_audio_latency_factor_get(); + tws_ctrl_send_cmd(APP_TWS_CMD_SET_LATENCYFACTOR, (uint8_t*)&latency_factor, sizeof(latency_factor)); + force_audio_retrigger = true; + } + } + if (force_audio_retrigger && !a2dp_audio_context.underflow_onporcess){ + a2dp_audio_context.underflow_onporcess = true; + app_ibrt_if_force_audio_retrigger(); + } + } +#else + if (nRet == A2DP_DECODER_CACHE_UNDERFLOW_ERROR){ + app_audio_decode_err_force_trigger(); + } +#endif + return len; +} + +static void a2dp_audio_packet_free(void *packet) +{ + if (a2dp_audio_context.audio_decoder.audio_decoder_packet_free){ + a2dp_audio_context.audio_decoder.audio_decoder_packet_free(packet); + }else{ + a2dp_audio_heap_free(packet); + } +} + +void a2dp_audio_clear_input_raw_packet_list(void) +{ + //just clean the packet list to start receive ai data again + if(a2dp_audio_context.audio_datapath.input_raw_packet_list) + a2dp_audio_list_clear(a2dp_audio_context.audio_datapath.input_raw_packet_list); +} + +int a2dp_audio_init(uint32_t sysfreq, A2DP_AUDIO_CODEC_TYPE codec_type, A2DP_AUDIO_OUTPUT_CONFIG_T *config, A2DP_AUDIO_CHANNEL_SELECT_E chnl_sel, uint16_t dest_packet_mut) +{ + uint8_t *heap_buff = NULL; + uint32_t heap_size = 0; + double ratio = 0; + + A2DP_AUDIO_OUTPUT_CONFIG_T decoder_output_config; + TRACE_A2DP_DECODER_I("[INIT] freq:%d codec:%d chnl:%d", sysfreq, codec_type, chnl_sel); + TRACE_A2DP_DECODER_I("[INIT] out:%d-%d-%d smp:%d dest:%d", + config->sample_rate, + config->num_channels, + config->bits_depth, + config->frame_samples, + dest_packet_mut); + a2dp_audio_sysfreq_boost_init(sysfreq); + a2dp_audio_sysfreq_boost_start(A2DP_AUDIO_SYSFREQ_BOOST_RESUME_CNT); + a2dp_audio_semaphore_init(); + a2dp_audio_buffer_mutex_init(); + a2dp_audio_status_mutex_init(); + + a2dp_audio_status_mutex_lock(); + + a2dp_audio_detect_next_packet_callback_register(NULL); + a2dp_audio_detect_store_packet_callback_register(NULL); + + +#if defined(A2DP_LDAC_ON) + if(bt_sbc_player_get_codec_type()==BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + heap_size = A2DP_AUDIO_LDAC_MEMPOOL_SIZE; + } + else +#endif + { + heap_size = A2DP_AUDIO_MEMPOOL_SIZE; + } + app_audio_mempool_get_buff(&heap_buff, heap_size); + ASSERT_A2DP_DECODER(heap_buff, "%s size:%d", __func__, heap_size); + a2dp_audio_heap_init(heap_buff, heap_size); + + memset(&a2dp_audio_lastframe_info, 0, sizeof(A2DP_AUDIO_LASTFRAME_INFO_T)); + + a2dp_audio_context.audio_datapath.input_raw_packet_list = a2dp_audio_list_new(a2dp_audio_packet_free, + (list_mempool_zmalloc)a2dp_audio_heap_cmalloc, + (list_mempool_free)a2dp_audio_heap_free); + + a2dp_audio_context.audio_datapath.output_pcm_packet_list = a2dp_audio_list_new(a2dp_audio_packet_free, + (list_mempool_zmalloc)a2dp_audio_heap_cmalloc, + (list_mempool_free)a2dp_audio_heap_free); + + memcpy(&(a2dp_audio_context.output_cfg), config, sizeof(A2DP_AUDIO_OUTPUT_CONFIG_T)); + ratio = a2dp_audio_context.output_cfg.factor_reference; + a2dp_audio_context.output_cfg.factor_reference = 0; + + a2dp_audio_context.init_factor_reference = config->factor_reference; + a2dp_audio_context.chnl_sel = chnl_sel; + a2dp_audio_context.dest_packet_mut = dest_packet_mut; + a2dp_audio_context.average_packet_mut = 0; + + switch (codec_type) + { + case A2DP_AUDIO_CODEC_TYPE_SBC: + decoder_output_config.sample_rate = config->sample_rate; + decoder_output_config.num_channels = 2; + decoder_output_config.bits_depth = 16; + decoder_output_config.frame_samples = config->frame_samples; + decoder_output_config.factor_reference = 1.0f; + memcpy(&(a2dp_audio_context.audio_decoder), &a2dp_audio_sbc_decoder_config, sizeof(A2DP_AUDIO_DECODER_T)); + break; +#if defined(A2DP_AAC_ON) + case A2DP_AUDIO_CODEC_TYPE_MPEG2_4_AAC: + decoder_output_config.sample_rate = config->sample_rate; + decoder_output_config.num_channels = 2; + decoder_output_config.bits_depth = 16; + decoder_output_config.frame_samples = config->frame_samples; + decoder_output_config.factor_reference = 1.0f; + memcpy(&(a2dp_audio_context.audio_decoder), &a2dp_audio_aac_lc_decoder_config, sizeof(A2DP_AUDIO_DECODER_T)); + break; +#endif +#if defined(A2DP_SCALABLE_ON) + case A2DP_AUDIO_CODEC_TYPE_SCALABL: + decoder_output_config.sample_rate = config->sample_rate; + decoder_output_config.num_channels = 2; + decoder_output_config.bits_depth = config->curr_bits; + decoder_output_config.frame_samples = config->frame_samples; + decoder_output_config.factor_reference = 1.0f; + memcpy(&(a2dp_audio_context.audio_decoder), &a2dp_audio_scalable_decoder_config, sizeof(A2DP_AUDIO_DECODER_T)); + break; +#endif +#if defined(A2DP_LHDC_ON) + case A2DP_AUDIO_CODEC_TYPE_LHDC: + decoder_output_config.sample_rate = config->sample_rate; + decoder_output_config.num_channels = 2; + decoder_output_config.bits_depth = config->curr_bits; + decoder_output_config.frame_samples = config->frame_samples; + decoder_output_config.factor_reference = 1.0f; + memcpy(&(a2dp_audio_context.audio_decoder), &a2dp_audio_lhdc_decoder_config, sizeof(A2DP_AUDIO_DECODER_T)); + break; +#endif +#if defined(A2DP_LDAC_ON) + case A2DP_AUDIO_CODEC_TYPE_LDAC: + decoder_output_config.sample_rate = config->sample_rate; + decoder_output_config.num_channels = 2; + decoder_output_config.bits_depth = config->curr_bits; + decoder_output_config.frame_samples = config->frame_samples; + decoder_output_config.factor_reference = 1.0f; + memcpy(&(a2dp_audio_context.audio_decoder), &a2dp_audio_ldac_decoder_config, sizeof(A2DP_AUDIO_DECODER_T)); + break; +#endif + default: + ASSERT_A2DP_DECODER(0, "%s invalid codec_type:%d", __func__, codec_type); + break; + } + + a2dp_audio_context.audio_decoder.audio_decoder_init(&decoder_output_config, (void *)&a2dp_audio_context); + a2dp_audio_context.need_detect_first_packet = true; + a2dp_audio_context.underflow_onporcess = false; + a2dp_audio_context.skip_frame_cnt_after_no_cache = 0; + a2dp_audio_context.mute_frame_cnt_after_no_cache = 0; + + a2dp_audio_context.audio_decoder_status = A2DP_AUDIO_DECODER_STATUS_READY; + + a2dp_audio_context.store_packet_status = A2DP_AUDIO_DECODER_STORE_PACKET_STATUS_IDLE; + a2dp_audio_context.playback_status = A2DP_AUDIO_DECODER_PLAYBACK_STATUS_IDLE; + + a2dp_audio_sync_init(ratio); + +#if A2DP_DECODER_HISTORY_SEQ_SAVE + a2dp_audio_reset_history_seq(); +#endif + a2dp_audio_store_packet_checker_start(); + + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +int a2dp_audio_deinit(void) +{ + TRACE_A2DP_DECODER_I("[DEINIT]"); + + a2dp_audio_status_mutex_lock(); + + a2dp_audio_detect_next_packet_callback_register(NULL); + a2dp_audio_detect_store_packet_callback_register(NULL); + + a2dp_audio_context.audio_decoder.audio_decoder_deinit(); + memset(&(a2dp_audio_context.audio_decoder), 0, sizeof(A2DP_AUDIO_DECODER_T)); + memset(&(a2dp_audio_context.output_cfg), 0, sizeof(A2DP_AUDIO_OUTPUT_CONFIG_T)); + a2dp_audio_list_clear(a2dp_audio_context.audio_datapath.input_raw_packet_list); + a2dp_audio_list_free(a2dp_audio_context.audio_datapath.input_raw_packet_list); + a2dp_audio_context.audio_datapath.input_raw_packet_list = NULL; + a2dp_audio_list_clear(a2dp_audio_context.audio_datapath.output_pcm_packet_list); + a2dp_audio_list_free(a2dp_audio_context.audio_datapath.output_pcm_packet_list); + a2dp_audio_context.audio_datapath.output_pcm_packet_list = NULL; + + size_t total = 0, used = 0, max_used = 0; + a2dp_audio_heap_info(&total, &used, &max_used); + TRACE_A2DP_DECODER_I("[DEINIT] heap info: total - %d, used - %d, max_used - %d.", total, used, max_used); + //ASSERT_A2DP_DECODER(used == 0, "[%s] used != 0", __func__); + + a2dp_audio_set_store_packet_status(A2DP_AUDIO_DECODER_STORE_PACKET_STATUS_IDLE); + a2dp_audio_set_playback_status(A2DP_AUDIO_DECODER_PLAYBACK_STATUS_IDLE); + a2dp_audio_set_status(A2DP_AUDIO_DECODER_STATUS_NULL); +#if A2DP_DECODER_HISTORY_SEQ_SAVE + a2dp_audio_reset_history_seq(); +#endif + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +int a2dp_audio_stop(void) +{ + TRACE_A2DP_DECODER_I("[STOP]"); + int cnt = 0; + + a2dp_audio_set_status(A2DP_AUDIO_DECODER_STATUS_STOP); + a2dp_audio_semaphore_release(); + + cnt = 50; + do { + if (a2dp_audio_get_playback_status() == A2DP_AUDIO_DECODER_PLAYBACK_STATUS_IDLE){ + TRACE_A2DP_DECODER_I("[DEINIT]PLAYBACK_STATUS_IDLE cnt:%d", cnt); + break; + }else{ + osThreadYield(); + } + }while(--cnt > 0); + cnt = 50; + do { + if (a2dp_audio_get_store_packet_status() == A2DP_AUDIO_DECODER_STORE_PACKET_STATUS_IDLE){ + TRACE_A2DP_DECODER_I("[DEINIT] STORE_PACKET_STATUS_IDLE cnt:%d", cnt); + break; + }else{ + osThreadYield(); + } + }while(--cnt > 0); + + return 0; +} + +int a2dp_audio_start(void) +{ + TRACE_A2DP_DECODER_I("[START]"); + a2dp_audio_status_mutex_lock(); + a2dp_audio_set_status(A2DP_AUDIO_DECODER_STATUS_START); + a2dp_audio_status_mutex_unlock(); + return 0; +} + +int a2dp_audio_detect_next_packet_callback_register(A2DP_AUDIO_DETECT_NEXT_PACKET_CALLBACK callback) +{ + a2dp_audio_status_mutex_lock(); + a2dp_audio_detect_next_packet_callback = callback; + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +int a2dp_audio_detect_store_packet_callback_register(A2DP_AUDIO_DETECT_NEXT_PACKET_CALLBACK callback) +{ + a2dp_audio_status_mutex_lock(); + a2dp_audio_store_packet_callback = callback; + a2dp_audio_status_mutex_unlock(); + + return 0; +} + +int a2dp_audio_detect_first_packet(void) +{ + a2dp_audio_status_mutex_lock(); + a2dp_audio_context.need_detect_first_packet = true; + a2dp_audio_status_mutex_unlock(); + return 0; +} + +int a2dp_audio_detect_first_packet_clear(void) +{ + a2dp_audio_status_mutex_lock(); + a2dp_audio_context.need_detect_first_packet = false; + a2dp_audio_status_mutex_unlock(); + return 0; +} + +int a2dp_audio_discards_packet(uint32_t packets) +{ + int nRet = 0; + + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + a2dp_audio_status_mutex_lock(); + nRet = a2dp_audio_context.audio_decoder.audio_decoder_discards_packet(packets); + a2dp_audio_status_mutex_unlock(); + }else{ + nRet = -1; + } + + return nRet; +} + +int a2dp_audio_synchronize_dest_packet_mut(uint32_t mtu) +{ + int nRet = 0; + int cnt = 50; + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + do { + if (a2dp_audio_get_playback_status() == A2DP_AUDIO_DECODER_PLAYBACK_STATUS_IDLE){ + nRet = a2dp_audio_context.audio_decoder.audio_decoder_synchronize_dest_packet_mut(mtu); + break; + }else{ + osThreadYield(); + } + }while(--cnt > 0); + }else{ + nRet = -1; + } + + return nRet; +} + +int a2dp_audio_discards_samples(uint32_t samples) +{ + return a2dp_audio_context.audio_decoder.a2dp_audio_discards_samples(samples); +} + +int a2dp_audio_convert_list_to_samples(uint32_t *samples) +{ + return a2dp_audio_context.audio_decoder.a2dp_audio_convert_list_to_samples(samples); +} + +int a2dp_audio_get_packet_samples(void) +{ + A2DP_AUDIO_LASTFRAME_INFO_T lastframe_info; + uint32_t packet_samples = 0; + uint16_t totalSubSequenceNumber = 1; + + a2dp_audio_lastframe_info_get(&lastframe_info); + + if (lastframe_info.totalSubSequenceNumber){ + totalSubSequenceNumber = lastframe_info.totalSubSequenceNumber; + } + + packet_samples = totalSubSequenceNumber * lastframe_info.frame_samples; + + return packet_samples; +} + +static int a2dp_audio_internal_lastframe_info_ptr_get(A2DP_AUDIO_LASTFRAME_INFO_T **lastframe_info) +{ + int nRet = 0; + + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + *lastframe_info = &a2dp_audio_lastframe_info; + }else{ + *lastframe_info = NULL; + nRet = -1; + } + + return nRet; +} + +int a2dp_audio_lastframe_info_get(A2DP_AUDIO_LASTFRAME_INFO_T *lastframe_info) +{ + int nRet = 0; + + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + a2dp_audio_buffer_mutex_lock(); + memcpy(lastframe_info, &a2dp_audio_lastframe_info, sizeof(A2DP_AUDIO_LASTFRAME_INFO_T)); + a2dp_audio_buffer_mutex_unlock(); + }else{ + memset(lastframe_info, 0, sizeof(A2DP_AUDIO_LASTFRAME_INFO_T)); + nRet = -1; + } + + return nRet; +} + +int a2dp_audio_decoder_internal_check_sum_reset(void) +{ + check_sum_seed = 0; + return 0; +} + +uint32_t a2dp_audio_decoder_internal_check_sum_generate(const uint8_t *buf, uint32_t len) +{ +#if A2DP_DECODER_CHECKER + check_sum_seed = crc32(check_sum_seed, buf, len); +#else + check_sum_seed = 0; +#endif + return check_sum_seed; +} + +int a2dp_audio_lastframe_info_reset_undecodeframe(void) +{ + int nRet = 0; + + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + a2dp_audio_buffer_mutex_lock(); + a2dp_audio_lastframe_info.undecode_frames = 0; + a2dp_audio_lastframe_info.undecode_max_frames = 0; + a2dp_audio_lastframe_info.undecode_min_frames = 0xffff; + a2dp_audio_decoder_internal_check_sum_reset(); + a2dp_audio_lastframe_info.check_sum = 0; + a2dp_audio_buffer_mutex_unlock(); + }else{ + nRet = -1; + } + + return nRet; +} + +int a2dp_audio_decoder_internal_lastframe_info_set(A2DP_AUDIO_DECODER_LASTFRAME_INFO_T *lastframe_info) +{ + a2dp_audio_buffer_mutex_lock(); + a2dp_audio_lastframe_info.sequenceNumber = lastframe_info->sequenceNumber; + a2dp_audio_lastframe_info.timestamp = lastframe_info->timestamp; + a2dp_audio_lastframe_info.curSubSequenceNumber = lastframe_info->curSubSequenceNumber; + a2dp_audio_lastframe_info.totalSubSequenceNumber= lastframe_info->totalSubSequenceNumber; + a2dp_audio_lastframe_info.frame_samples = lastframe_info->frame_samples; + a2dp_audio_lastframe_info.list_samples = lastframe_info->list_samples; + a2dp_audio_lastframe_info.decoded_frames = lastframe_info->decoded_frames; + a2dp_audio_lastframe_info.undecode_frames = lastframe_info->undecode_frames; + + a2dp_audio_lastframe_info.undecode_max_frames = + MAX(a2dp_audio_lastframe_info.undecode_frames, a2dp_audio_lastframe_info.undecode_max_frames); + a2dp_audio_lastframe_info.undecode_min_frames = + MIN(a2dp_audio_lastframe_info.undecode_frames, a2dp_audio_lastframe_info.undecode_min_frames); + + a2dp_audio_lastframe_info.stream_info = lastframe_info->stream_info; + a2dp_audio_lastframe_info.check_sum = lastframe_info->check_sum; + a2dp_audio_buffer_mutex_unlock(); + + return 0; +} + +int a2dp_audio_synchronize_packet(A2DP_AUDIO_SYNCFRAME_INFO_T *sync_info, uint32_t mask) +{ + int nRet = 0; + + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + a2dp_audio_status_mutex_lock(); + nRet = a2dp_audio_context.audio_decoder.audio_decoder_synchronize_packet(sync_info, mask); + if (nRet == A2DP_DECODER_NOT_SUPPORT){ + //can't support synchronize packet, so return fake val; + nRet = A2DP_DECODER_NO_ERROR; + } + a2dp_audio_status_mutex_unlock(); + }else{ + nRet = -1; + } + + return nRet; +} + +int a2dp_audio_decoder_headframe_info_get(A2DP_AUDIO_HEADFRAME_INFO_T *headframe_info) +{ + int nRet = 0; + + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + nRet = a2dp_audio_context.audio_decoder.audio_decoder_headframe_info_get(headframe_info); + }else{ + memset(headframe_info, 0, sizeof(A2DP_AUDIO_HEADFRAME_INFO_T)); + nRet = -1; + } + + return nRet; +} + +int a2dp_audio_refill_packet(void) +{ + int refill_cnt = 0; + +#if defined(A2DP_AUDIO_REFILL_AFTER_NO_CACHE) + refill_cnt += a2dp_audio_context.skip_frame_cnt_after_no_cache; +#endif + refill_cnt += a2dp_audio_context.mute_frame_cnt_after_no_cache; + + return refill_cnt; +} + +bool a2dp_audio_auto_synchronize_support(void) +{ + bool nRet = 0; + + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + a2dp_audio_buffer_mutex_lock(); + nRet = a2dp_audio_context.audio_decoder.auto_synchronize_support > 0 ? true: false; + a2dp_audio_buffer_mutex_unlock(); + }else{ + nRet = 0; + } + + return nRet; +} + +A2DP_AUDIO_OUTPUT_CONFIG_T *a2dp_audio_get_output_config(void) +{ + A2DP_AUDIO_OUTPUT_CONFIG_T *output_config = NULL; + + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + a2dp_audio_buffer_mutex_lock(); + output_config = &a2dp_audio_context.output_cfg; + a2dp_audio_buffer_mutex_unlock(); + }else{ + output_config = NULL; + } + + return output_config; +} + +int a2dp_audio_latency_factor_setlow(void) +{ + a2dp_audio_latency_factor = A2DP_AUDIO_LATENCY_LOW_FACTOR; + return 0; +} + +int a2dp_audio_latency_factor_sethigh(void) +{ + a2dp_audio_latency_factor = A2DP_AUDIO_LATENCY_HIGH_FACTOR; + return 0; +} + +float a2dp_audio_latency_factor_get(void) +{ + return a2dp_audio_latency_factor; +} + +int a2dp_audio_latency_factor_set(float factor) +{ + a2dp_audio_latency_factor = factor; + return 0; +} + +int a2dp_audio_latency_factor_status_get(A2DP_AUDIO_LATENCY_STATUS_E *latency_status, float *more_latency_factor) +{ + if (a2dp_audio_latency_factor == A2DP_AUDIO_LATENCY_HIGH_FACTOR){ + *latency_status = A2DP_AUDIO_LATENCY_STATUS_HIGH; + *more_latency_factor = A2DP_AUDIO_LATENCY_MORE_FACTOR; + }else{ + *latency_status = A2DP_AUDIO_LATENCY_STATUS_LOW; + *more_latency_factor = 1.0f; + } + return 0; +} + +int a2dp_audio_frame_delay_get(void) +{ + return get_in_cp_frame_delay(); +} + +int a2dp_audio_dest_packet_mut_get(void) +{ + return a2dp_audio_context.dest_packet_mut; +} + +int a2dp_audio_set_channel_select(A2DP_AUDIO_CHANNEL_SELECT_E chnl_sel) +{ + int nRet = A2DP_DECODER_NO_ERROR; + + if (a2dp_audio_get_status() == A2DP_AUDIO_DECODER_STATUS_START){ + a2dp_audio_context.chnl_sel = chnl_sel; + if (a2dp_audio_context.audio_decoder.audio_decoder_channel_select) { + nRet = a2dp_audio_context.audio_decoder.audio_decoder_channel_select(chnl_sel); + } + } + + return nRet; +} + +float a2dp_audio_get_sample_reference(void) +{ + TRACE(1,"a2dp_audio_get_sample_reference:%d", (int32_t)(a2dp_audio_context.output_cfg.factor_reference * 10000000)); + return a2dp_audio_context.output_cfg.factor_reference; +} + +int8_t a2dp_audio_get_current_buf_size(void) +{ + TRACE(1,"a2dp_audio_get_current_buf_size:%d",(int8_t)(a2dp_audio_context.average_packet_mut+0.5f)); + return (int8_t)(a2dp_audio_context.average_packet_mut+0.5f); +} diff --git a/apps/audioplayers/a2dp_decoder/a2dp_decoder.h b/apps/audioplayers/a2dp_decoder/a2dp_decoder.h new file mode 100644 index 0000000..af8681b --- /dev/null +++ b/apps/audioplayers/a2dp_decoder/a2dp_decoder.h @@ -0,0 +1,155 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __A2DPPLAY_H__ +#define __A2DPPLAY_H__ + +#include "app_utils.h" +#include "avdtp_api.h" + +#define A2DP_DECODER_HISTORY_SEQ_SAVE (25) +//#define A2DP_DECODER_HISTORY_LOCTIME_SAVE (1) +//#define A2DP_DECODER_HISTORY_CHECK_SUM_SAVE (1) + +typedef uint16_t A2DP_AUDIO_CODEC_TYPE; + +#define A2DP_AUDIO_CODEC_TYPE_SBC (1u<<0) +#define A2DP_AUDIO_CODEC_TYPE_MPEG2_4_AAC (1u<<1) +#define A2DP_AUDIO_CODEC_TYPE_OPUS (1u<<2) +#define A2DP_AUDIO_CODEC_TYPE_SCALABL (1u<<3) +#define A2DP_AUDIO_CODEC_TYPE_LHDC (1u<<4) +#define A2DP_AUDIO_CODEC_TYPE_LDAC (1u<<5) + +#define A2DP_AUDIO_SYNCFRAME_MASK_SEQ (1u<<0) +#define A2DP_AUDIO_SYNCFRAME_MASK_TIMESTAMP (1u<<1) +#define A2DP_AUDIO_SYNCFRAME_MASK_CURRSUBSEQ (1u<<2) +#define A2DP_AUDIO_SYNCFRAME_MASK_TOTALSUBSEQ (1u<<3) + +#define A2DP_AUDIO_SYNCFRAME_MASK_ALL (A2DP_AUDIO_SYNCFRAME_MASK_SEQ | \ + A2DP_AUDIO_SYNCFRAME_MASK_TIMESTAMP | \ + A2DP_AUDIO_SYNCFRAME_MASK_CURRSUBSEQ | \ + A2DP_AUDIO_SYNCFRAME_MASK_TOTALSUBSEQ) + +#define A2DP_AUDIO_SYNCFRAME_CHK(equ, mask_val, mask) (((equ)|!(mask_val&mask))) + +typedef enum { + A2DP_AUDIO_LATENCY_STATUS_LOW, + A2DP_AUDIO_LATENCY_STATUS_HIGH, +} A2DP_AUDIO_LATENCY_STATUS_E; + +typedef struct { + uint32_t sample_rate; + uint8_t num_channels; + uint8_t bits_depth; + uint8_t curr_bits; + uint32_t frame_samples; + float factor_reference; +} A2DP_AUDIO_OUTPUT_CONFIG_T; + +typedef enum { + A2DP_AUDIO_CHANNEL_SELECT_STEREO, + A2DP_AUDIO_CHANNEL_SELECT_LRMERGE, + A2DP_AUDIO_CHANNEL_SELECT_LCHNL, + A2DP_AUDIO_CHANNEL_SELECT_RCHNL, +} A2DP_AUDIO_CHANNEL_SELECT_E; + +typedef struct { + uint16_t sequenceNumber; + uint32_t timestamp; + uint16_t curSubSequenceNumber; + uint16_t totalSubSequenceNumber; + uint32_t frame_samples; + uint32_t list_samples; + uint32_t decoded_frames; + uint32_t undecode_frames; + uint32_t undecode_min_frames; + uint32_t undecode_max_frames; + uint32_t average_frames; + uint32_t check_sum; + A2DP_AUDIO_OUTPUT_CONFIG_T stream_info; +} A2DP_AUDIO_LASTFRAME_INFO_T; + +typedef struct { + uint16_t sequenceNumber; + uint32_t timestamp; + uint16_t curSubSequenceNumber; + uint16_t totalSubSequenceNumber; +} A2DP_AUDIO_HEADFRAME_INFO_T; + +typedef struct{ + float proportiongain; + float integralgain; + float derivativegain; + float error[3]; + float result; +}A2DP_AUDIO_SYNC_PID_T; + +typedef A2DP_AUDIO_LASTFRAME_INFO_T A2DP_AUDIO_SYNCFRAME_INFO_T; + +typedef int(*A2DP_AUDIO_DETECT_NEXT_PACKET_CALLBACK)(btif_media_header_t *, unsigned char *, unsigned int len); + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t a2dp_audio_playback_handler(uint8_t *buffer, uint32_t buffer_bytes); +float a2dp_audio_sync_pid_calc(A2DP_AUDIO_SYNC_PID_T *pid, float diff); +int a2dp_audio_sync_init(double ratio); +int a2dp_audio_sync_reset_data(void); +int a2dp_audio_sync_tune_sample_rate(double ratio); +int a2dp_audio_sync_direct_tune_sample_rate(double ratio); +int a2dp_audio_sync_tune_cancel(void); +int a2dp_audio_sysfreq_boost_start(uint32_t boost_cnt); +int a2dp_audio_sysfreq_boost_running(void); +int a2dp_audio_init(uint32_t sysfreq, A2DP_AUDIO_CODEC_TYPE codec_type, A2DP_AUDIO_OUTPUT_CONFIG_T *config, + A2DP_AUDIO_CHANNEL_SELECT_E chnl_sel, uint16_t dest_packet_mut); +int a2dp_audio_deinit(void); +int a2dp_audio_start(void); +int a2dp_audio_stop(void); +int a2dp_audio_detect_next_packet_callback_register(A2DP_AUDIO_DETECT_NEXT_PACKET_CALLBACK callback); +int a2dp_audio_detect_store_packet_callback_register(A2DP_AUDIO_DETECT_NEXT_PACKET_CALLBACK callback); +int a2dp_audio_detect_first_packet(void); +int a2dp_audio_detect_first_packet_clear(void); +int a2dp_audio_store_packet(btif_media_header_t * header, unsigned char *buf, unsigned int len); +int a2dp_audio_discards_packet(uint32_t packets); +int a2dp_audio_synchronize_dest_packet_mut(uint32_t mtu); +int a2dp_audio_discards_samples(uint32_t samples); +int a2dp_audio_convert_list_to_samples(uint32_t *samples); +int a2dp_audio_synchronize_packet(A2DP_AUDIO_SYNCFRAME_INFO_T *sync_info, uint32_t mask); +int a2dp_audio_decoder_headframe_info_get(A2DP_AUDIO_HEADFRAME_INFO_T *headframe_info); +int a2dp_audio_get_packet_samples(void); +int a2dp_audio_lastframe_info_get(A2DP_AUDIO_LASTFRAME_INFO_T *lastframe_info); +int a2dp_audio_lastframe_info_reset_undecodeframe(void); +void a2dp_audio_clear_input_raw_packet_list(void); +int a2dp_audio_refill_packet(void); +bool a2dp_audio_auto_synchronize_support(void); +A2DP_AUDIO_OUTPUT_CONFIG_T *a2dp_audio_get_output_config(void); +int a2dp_audio_latency_factor_setlow(void); +int a2dp_audio_latency_factor_sethigh(void); +float a2dp_audio_latency_factor_get(void); +int a2dp_audio_latency_factor_set(float factor); +int a2dp_audio_frame_delay_get(void); +int a2dp_audio_dest_packet_mut_get(void); +int a2dp_audio_latency_factor_status_get(A2DP_AUDIO_LATENCY_STATUS_E *latency_status, float *more_latency_factor); +#if A2DP_DECODER_HISTORY_SEQ_SAVE +int a2dp_audio_show_history_seq(void); +#endif +int a2dp_audio_set_channel_select(A2DP_AUDIO_CHANNEL_SELECT_E chnl_sel); + +#ifdef __cplusplus +} +#endif + +#endif//__A2DPPLAY_H__ diff --git a/apps/audioplayers/a2dp_decoder/a2dp_decoder_aac_lc.cpp b/apps/audioplayers/a2dp_decoder/a2dp_decoder_aac_lc.cpp new file mode 100644 index 0000000..f061a5e --- /dev/null +++ b/apps/audioplayers/a2dp_decoder/a2dp_decoder_aac_lc.cpp @@ -0,0 +1,1012 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Standard C Included Files +#include "cmsis.h" +#include "plat_types.h" +#include +#include "heap_api.h" +#include "hal_location.h" +#include "hal_timer.h" +#include "a2dp_decoder_internal.h" +#include "cmsis_os.h" + +#if defined(A2DP_AAC_ON) +#include "heap_api.h" +#include "aacdecoder_lib.h" +#include "aacenc_lib.h" + +#ifndef AAC_MTU_LIMITER +#define AAC_MTU_LIMITER (32) /*must <= 23*/ +#endif +#define AAC_OUTPUT_FRAME_SAMPLES (1024) +#define DECODE_AAC_PCM_FRAME_LENGTH (2048) + +#define AAC_READBUF_SIZE (900) + +#define AAC_MEMPOOL_SIZE (40596) + +typedef struct { + uint16_t sequenceNumber; + uint32_t timestamp; + uint8_t *aac_buffer; + uint32_t aac_buffer_len; +} a2dp_audio_aac_decoder_frame_t; + +int a2dp_audio_aac_lc_reorder_init(void); +int a2dp_audio_aac_lc_reorder_deinit(void); + +static A2DP_AUDIO_CONTEXT_T *a2dp_audio_context_p = NULL; + +static HANDLE_AACDECODER aacDec_handle = NULL; +static uint8_t *aac_mempoll = NULL; +heap_handle_t aac_memhandle = NULL; + +static A2DP_AUDIO_DECODER_LASTFRAME_INFO_T a2dp_audio_aac_lastframe_info; + +static uint16_t aac_mtu_limiter = AAC_MTU_LIMITER; + +static a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_reorder_p = NULL; +static a2dp_audio_aac_decoder_frame_t aac_decoder_last_valid_frame = {0,}; +static bool aac_decoder_last_valid_frame_ready = false; + +static void *a2dp_audio_aac_lc_frame_malloc(uint32_t packet_len) +{ + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = NULL; + uint8_t *aac_buffer = NULL; + + aac_buffer = (uint8_t *)a2dp_audio_heap_malloc(AAC_READBUF_SIZE); + aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_heap_malloc(sizeof(a2dp_audio_aac_decoder_frame_t)); + aac_decoder_frame_p->aac_buffer = aac_buffer; + aac_decoder_frame_p->aac_buffer_len = packet_len; + return (void *)aac_decoder_frame_p; +} + +static void a2dp_audio_aac_lc_free(void *packet) +{ + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)packet; + a2dp_audio_heap_free(aac_decoder_frame_p->aac_buffer); + a2dp_audio_heap_free(aac_decoder_frame_p); +} + +static void a2dp_audio_aac_lc_decoder_init(void) +{ + if (aacDec_handle == NULL){ + TRANSPORT_TYPE transportFmt = TT_MP4_LATM_MCP1; + + aacDec_handle = aacDecoder_Open(transportFmt, 1 /* nrOfLayers */); + ASSERT_A2DP_DECODER(aacDec_handle, "aacDecoder_Open failed"); + + aacDecoder_SetParam(aacDec_handle,AAC_PCM_LIMITER_ENABLE,0); + aacDecoder_SetParam(aacDec_handle, AAC_DRC_ATTENUATION_FACTOR, 0); + aacDecoder_SetParam(aacDec_handle, AAC_DRC_BOOST_FACTOR, 0); + } +} + +static void a2dp_audio_aac_lc_decoder_deinit(void) +{ + if (aacDec_handle){ + aacDecoder_Close(aacDec_handle); + aacDec_handle = NULL; + } +} + +static void a2dp_audio_aac_lc_decoder_reinit(void) +{ + if (aacDec_handle){ + a2dp_audio_aac_lc_decoder_deinit(); + } + a2dp_audio_aac_lc_decoder_init(); +} + +#ifdef A2DP_CP_ACCEL +struct A2DP_CP_AAC_LC_IN_FRM_INFO_T { + uint16_t sequenceNumber; + uint32_t timestamp; +}; + +struct A2DP_CP_AAC_LC_OUT_FRM_INFO_T { + struct A2DP_CP_AAC_LC_IN_FRM_INFO_T in_info; + uint16_t frame_samples; + uint16_t decoded_frames; + uint16_t frame_idx; + uint16_t pcm_len; +}; + +static bool cp_codec_reset; + +extern "C" uint32_t get_in_cp_frame_cnt(void); +extern "C" unsigned int set_cp_reset_flag(uint8_t evt); +extern uint32_t app_bt_stream_get_dma_buffer_samples(void); + +int a2dp_cp_aac_lc_cp_decode(void); + +static int TEXT_AAC_LOC a2dp_cp_aac_lc_after_cache_underflow(void) +{ +#ifdef A2DP_CP_ACCEL + cp_codec_reset = true; +#endif + return 0; +} + +static int a2dp_cp_aac_lc_mcu_decode(uint8_t *buffer, uint32_t buffer_bytes) +{ + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = NULL; + list_node_t *node = NULL; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int ret, dec_ret; + struct A2DP_CP_AAC_LC_IN_FRM_INFO_T in_info; + struct A2DP_CP_AAC_LC_OUT_FRM_INFO_T *p_out_info; + uint8_t *out; + uint32_t out_len; + uint32_t out_frame_len; + uint32_t check_sum = 0; + + + uint32_t cp_buffer_frames_max = 0; + cp_buffer_frames_max = app_bt_stream_get_dma_buffer_samples()/2; + if (cp_buffer_frames_max %(a2dp_audio_aac_lastframe_info.frame_samples) ){ + cp_buffer_frames_max = cp_buffer_frames_max /(a2dp_audio_aac_lastframe_info.frame_samples) +1 ; + }else{ + cp_buffer_frames_max = cp_buffer_frames_max /(a2dp_audio_aac_lastframe_info.frame_samples) ; + } + + out_frame_len = sizeof(*p_out_info) + buffer_bytes; + + ret = a2dp_cp_decoder_init(out_frame_len, cp_buffer_frames_max * 2); + if (ret){ + TRACE_A2DP_DECODER_W("[MCU][AAC] cp_decoder_init failed: ret=%d", ret); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + while ((node = a2dp_audio_list_begin(list)) != NULL) { + aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_list_node(node); + + in_info.sequenceNumber = aac_decoder_frame_p->sequenceNumber; + in_info.timestamp = aac_decoder_frame_p->timestamp; + + ret = a2dp_cp_put_in_frame(&in_info, sizeof(in_info), aac_decoder_frame_p->aac_buffer, aac_decoder_frame_p->aac_buffer_len); + if (ret) { + TRACE_A2DP_DECODER_D("[MCU][AAC] piff !!!!!!ret: %d ", ret); + break; + } + check_sum = a2dp_audio_decoder_internal_check_sum_generate(aac_decoder_frame_p->aac_buffer, aac_decoder_frame_p->aac_buffer_len); + a2dp_audio_list_remove(list, aac_decoder_frame_p); + } + ret = a2dp_cp_get_full_out_frame((void **)&out, &out_len); + if (ret) { + if (!get_in_cp_frame_cnt()){ + TRACE_A2DP_DECODER_I("[MCU][AAC] cp cache underflow list:%d in_cp:%d",a2dp_audio_list_length(list), get_in_cp_frame_cnt()); + return A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + if (!a2dp_audio_sysfreq_boost_running()){ + a2dp_audio_sysfreq_boost_start(1); + } + osDelay(12); + ret = a2dp_cp_get_full_out_frame((void **)&out, &out_len); + if (ret) { + TRACE_A2DP_DECODER_I("[MCU][AAC] cp cache underflow list:%d in_cp:%d",a2dp_audio_list_length(list), get_in_cp_frame_cnt()); + a2dp_cp_aac_lc_after_cache_underflow(); + return A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + } + + if (out_len == 0) { + memset(buffer, 0, buffer_bytes); + a2dp_cp_consume_full_out_frame(); + TRACE_A2DP_DECODER_I("[MCU][AAC] olz!!!%d ", __LINE__); + return A2DP_DECODER_NO_ERROR; + } + if (out_len != out_frame_len){ + TRACE_A2DP_DECODER_I("[MCU][AAC] Bad out len %u (should be %u)", out_len, out_frame_len); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + p_out_info = (struct A2DP_CP_AAC_LC_OUT_FRM_INFO_T *)out; + if (p_out_info->pcm_len) { + a2dp_audio_aac_lastframe_info.sequenceNumber = p_out_info->in_info.sequenceNumber; + a2dp_audio_aac_lastframe_info.timestamp = p_out_info->in_info.timestamp; + a2dp_audio_aac_lastframe_info.curSubSequenceNumber = 0; + a2dp_audio_aac_lastframe_info.totalSubSequenceNumber = 0; + a2dp_audio_aac_lastframe_info.frame_samples = p_out_info->frame_samples; + a2dp_audio_aac_lastframe_info.decoded_frames += p_out_info->decoded_frames; + a2dp_audio_aac_lastframe_info.undecode_frames = + a2dp_audio_list_length(list) + a2dp_cp_get_in_frame_cnt_by_index(p_out_info->frame_idx) - 1; + a2dp_audio_aac_lastframe_info.check_sum= check_sum?check_sum:a2dp_audio_aac_lastframe_info.check_sum; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_aac_lastframe_info); + } + + if (p_out_info->pcm_len == buffer_bytes) { + memcpy(buffer, p_out_info + 1, p_out_info->pcm_len); + dec_ret = A2DP_DECODER_NO_ERROR; + } else { + TRACE_A2DP_DECODER_I("[MCU][AAC] olne!!!%d ", __LINE__); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + + ret = a2dp_cp_consume_full_out_frame(); + if (ret){ + + TRACE_A2DP_DECODER_I("[MCU][AAC] cp consume_full_out_frame() failed: ret=%d", ret); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + return dec_ret; +} + + +#ifdef __CP_EXCEPTION_TEST__ +static bool _cp_assert = false; + int cp_assert(void) +{ + _cp_assert = true; + return 0; +} +#endif + +TEXT_AAC_LOC +int a2dp_cp_aac_lc_cp_decode(void) +{ + int ret; + enum CP_EMPTY_OUT_FRM_T out_frm_st; + uint8_t *out; + uint32_t out_len; + bool need_refill = false; + uint8_t *dec_start; + uint32_t dec_len; + struct A2DP_CP_AAC_LC_IN_FRM_INFO_T *p_in_info; + struct A2DP_CP_AAC_LC_OUT_FRM_INFO_T *p_out_info; + uint8_t *in_buf; + uint32_t in_len; + uint32_t dec_sum; + int error; + uint32_t aac_maxreadBytes = AAC_READBUF_SIZE; + UINT bufferSize = 0, bytesValid = 0; + AAC_DECODER_ERROR decoder_err = AAC_DEC_OK; + CStreamInfo *stream_info=NULL; + if (cp_codec_reset) { + cp_codec_reset = false; + a2dp_audio_aac_lc_decoder_init(); + } + +#ifdef __CP_EXCEPTION_TEST__ + if (_cp_assert){ + _cp_assert = false; + *(int*) 0 = 1; + //ASSERT_A2DP_DECODER(0, "ASSERT_A2DP_DECODER %s %d", __func__, __LINE__); + } +#endif + out_frm_st = a2dp_cp_get_emtpy_out_frame((void **)&out, &out_len); + if (out_frm_st != CP_EMPTY_OUT_FRM_OK && out_frm_st != CP_EMPTY_OUT_FRM_WORKING) { + return 1; + } + ASSERT_A2DP_DECODER(out_len > sizeof(*p_out_info), "%s: Bad out_len %u (should > %u)", __func__, out_len, sizeof(*p_out_info)); + + p_out_info = (struct A2DP_CP_AAC_LC_OUT_FRM_INFO_T *)out; + if (out_frm_st == CP_EMPTY_OUT_FRM_OK) { + p_out_info->pcm_len = 0; + p_out_info->decoded_frames = 0; + } + ASSERT_A2DP_DECODER(out_len > sizeof(*p_out_info) + p_out_info->pcm_len, "%s: Bad out_len %u (should > %u + %u)", __func__, out_len, sizeof(*p_out_info), p_out_info->pcm_len); + + dec_start = (uint8_t *)(p_out_info + 1) + p_out_info->pcm_len; + dec_len = out_len - (dec_start - (uint8_t *)out); + + if(dec_len < DECODE_AAC_PCM_FRAME_LENGTH){ + TRACE_A2DP_DECODER_W("[CP][AAC] aac_lc_decode pcm_len = %d \n", dec_len); + return 2; + } + if(!aacDec_handle){ + TRACE_A2DP_DECODER_W("[CP][AAC] aac_lc_decode not ready"); + return 3; + } + + dec_sum = 0; + error = 0; + + while (dec_sum < dec_len && error == 0) { + ret = a2dp_cp_get_in_frame((void **)&in_buf, &in_len); + if (ret) { + return 4; + } + ASSERT_A2DP_DECODER(in_len > sizeof(*p_in_info), "[CP][AAC] Bad in_len %u (should > %u)", in_len, sizeof(*p_in_info)); + + p_in_info = (struct A2DP_CP_AAC_LC_IN_FRM_INFO_T *)in_buf; + if (need_refill){ + p_in_info->sequenceNumber = UINT16_MAX; + } + in_buf += sizeof(*p_in_info); + in_len -= sizeof(*p_in_info); + + if (in_len < 64) + aac_maxreadBytes = 64; + else if (in_len < 128) + aac_maxreadBytes = 128; + else if (in_len < 256) + aac_maxreadBytes = 256; + else if (in_len < 512) + aac_maxreadBytes = 512; + else if (in_len < 1024) + aac_maxreadBytes = 1024; + + bufferSize = aac_maxreadBytes; + bytesValid = aac_maxreadBytes; + decoder_err = aacDecoder_Fill(aacDec_handle, &in_buf, &bufferSize, &bytesValid); + if (decoder_err != AAC_DEC_OK) { + TRACE_A2DP_DECODER_W("[CP][AAC] decoder_Fill failed:0x%x", decoder_err); + //if aac failed reopen it again + if(is_aacDecoder_Close(aacDec_handle)){ + a2dp_audio_aac_lc_decoder_reinit(); + TRACE_A2DP_DECODER_I("[CP][AAC] aac_lc_decode reinin codec \n"); + } + error = 1; + goto end_decode; + } + + /* decode one AAC frame */ + decoder_err = aacDecoder_DecodeFrame(aacDec_handle, (short *)(dec_start + dec_sum), (dec_len - dec_sum) / 2, 0 /* flags */); + TRACE_A2DP_DECODER_D("[CP][AAC] decoder seq:%d len:%d err:%x", p_in_info->sequenceNumber, + (dec_len - dec_sum), + decoder_err); + if (decoder_err != AAC_DEC_OK){ + TRACE_A2DP_DECODER_W("[CP][AAC] aac_lc_decode failed:0x%x seq:%d", decoder_err, p_in_info->sequenceNumber); + //if aac failed reopen it again + a2dp_audio_aac_lc_decoder_reinit(); + TRACE_A2DP_DECODER_I("[CP][AAC]aac_lc_decode reinin codec \n"); + if(!need_refill){ + need_refill = true; + ret = a2dp_cp_consume_in_frame(); + ASSERT(ret == 0, "%s: a2dp_cp_consume_in_frame() failed: ret=%d", __func__, ret); + continue; + }else{ + need_refill = false; + error = 1; + goto end_decode; + } + } + + stream_info = aacDecoder_GetStreamInfo(aacDec_handle); + if (!stream_info || stream_info->sampleRate <= 0) { + TRACE_A2DP_DECODER_I("[CP][AAC]aac_lc_decode invalid stream info"); + error = 1; + goto end_decode; + } + + bufferSize = stream_info->frameSize * stream_info->numChannels * 2;//sizeof(pcm_buffer[0]); + ASSERT_A2DP_DECODER(AAC_OUTPUT_FRAME_SAMPLES == bufferSize/4, "aac_lc_decode output mismatch samples:%d", bufferSize/4); + + dec_sum += bufferSize; + +end_decode: + memcpy(&p_out_info->in_info, p_in_info, sizeof(*p_in_info)); + p_out_info->decoded_frames++; + p_out_info->frame_samples = AAC_OUTPUT_FRAME_SAMPLES; + p_out_info->frame_idx = a2dp_cp_get_in_frame_index(); + if (need_refill){ + TRACE_A2DP_DECODER_W("[CP][AAC] resume refill seq:%d", p_in_info->sequenceNumber); + }else{ + ret = a2dp_cp_consume_in_frame(); + ASSERT_A2DP_DECODER(ret == 0, "[CP][AAC] a2dp_cp_consume_in_frame() failed: ret=%d", ret); + } + } + + p_out_info->pcm_len += dec_sum; + + if (error || out_len <= sizeof(*p_out_info) + p_out_info->pcm_len) { + ret = a2dp_cp_consume_emtpy_out_frame(); + ASSERT_A2DP_DECODER(ret == 0, "[CP][AAC] a2dp_cp_consume_emtpy_out_frame() failed: ret=%d", ret); + } + + return error; +} +#endif + +static int a2dp_audio_aac_lc_list_checker(void) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = NULL; + int cnt = 0; + + do { + aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_aac_lc_frame_malloc(0); + if (aac_decoder_frame_p){ + a2dp_audio_list_append(list, aac_decoder_frame_p); + } + cnt++; + }while(aac_decoder_frame_p && cnt < AAC_MTU_LIMITER); + + do { + if ((node = a2dp_audio_list_begin(list)) != NULL){ + aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, aac_decoder_frame_p); + } + }while(node); + + TRACE_A2DP_DECODER_I("[AAC][INIT] cnt:%d list:%d", cnt, a2dp_audio_list_length(list)); + + return 0; +} + +int a2dp_audio_aac_lc_channel_select(A2DP_AUDIO_CHANNEL_SELECT_E chnl_sel) +{ + AAC_DECODER_CHANNEL_SELECT_E aac_decoder_channel_select = AAC_DECODER_CHANNEL_SELECT_SELECT_STEREO; + switch(chnl_sel) + { + case A2DP_AUDIO_CHANNEL_SELECT_STEREO: + aac_decoder_channel_select = AAC_DECODER_CHANNEL_SELECT_SELECT_STEREO; + break; + case A2DP_AUDIO_CHANNEL_SELECT_LRMERGE: + aac_decoder_channel_select = AAC_DECODER_CHANNEL_SELECT_SELECT_LRMERGE; + break; + case A2DP_AUDIO_CHANNEL_SELECT_LCHNL: + aac_decoder_channel_select = AAC_DECODER_CHANNEL_SELECT_LCHNL; + break; + case A2DP_AUDIO_CHANNEL_SELECT_RCHNL: + aac_decoder_channel_select = AAC_DECODER_CHANNEL_SELECT_RCHNL; + default: + break; + } + aacDecoder_DecodeFrame_Config(aac_decoder_channel_select); + + return 0; +} + +int a2dp_audio_aac_lc_init(A2DP_AUDIO_OUTPUT_CONFIG_T *config, void *context) +{ + TRACE_A2DP_DECODER_I("[AAC] init"); + + a2dp_audio_context_p = (A2DP_AUDIO_CONTEXT_T *)context; + + memset(&a2dp_audio_aac_lastframe_info, 0, sizeof(A2DP_AUDIO_DECODER_LASTFRAME_INFO_T)); + a2dp_audio_aac_lastframe_info.stream_info = *config; + a2dp_audio_aac_lastframe_info.frame_samples = AAC_OUTPUT_FRAME_SAMPLES; + a2dp_audio_aac_lastframe_info.list_samples = AAC_OUTPUT_FRAME_SAMPLES; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_aac_lastframe_info); + + ASSERT_A2DP_DECODER(a2dp_audio_context_p->dest_packet_mut < AAC_MTU_LIMITER, "%s MTU OVERFLOW:%u/%u", __func__, a2dp_audio_context_p->dest_packet_mut, AAC_MTU_LIMITER); + + aac_mempoll = (uint8_t *)a2dp_audio_heap_malloc(AAC_MEMPOOL_SIZE); + ASSERT_A2DP_DECODER(aac_mempoll, "aac_mempoll = NULL"); + aac_memhandle = heap_register(aac_mempoll, AAC_MEMPOOL_SIZE); + +#ifdef A2DP_CP_ACCEL + int ret; + + cp_codec_reset = true; + ret = a2dp_cp_init(a2dp_cp_aac_lc_cp_decode, CP_PROC_DELAY_2_FRAMES); + ASSERT_A2DP_DECODER(ret == 0, "%s: a2dp_cp_init() failed: ret=%d", __func__, ret); +#else + a2dp_audio_aac_lc_decoder_init(); +#endif + a2dp_audio_aac_lc_reorder_init(); + a2dp_audio_aac_lc_list_checker(); + + a2dp_audio_aac_lc_channel_select(a2dp_audio_context_p->chnl_sel); + + return A2DP_DECODER_NO_ERROR; +} + + +int a2dp_audio_aac_lc_deinit(void) +{ +#ifdef A2DP_CP_ACCEL + a2dp_cp_deinit(); +#endif + a2dp_audio_aac_lc_decoder_deinit(); + a2dp_audio_aac_lc_reorder_deinit(); + size_t total = 0, used = 0, max_used = 0; + heap_memory_info(aac_memhandle, &total, &used, &max_used); + a2dp_audio_heap_free(aac_mempoll); + TRACE_A2DP_DECODER_I("[AAC] deinit MEM: total - %d, used - %d, max_used - %d.", + total, used, max_used); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_aac_lc_mcu_decode_frame(uint8_t *buffer, uint32_t buffer_bytes) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = NULL; + + UINT bufferSize = 0, bytesValid = 0; + AAC_DECODER_ERROR decoder_err = AAC_DEC_OK; + CStreamInfo *stream_info=NULL; + + bool cache_underflow = false; + uint32_t aac_maxreadBytes = AAC_READBUF_SIZE; + int output_byte = 0; + + if(buffer_bytes < DECODE_AAC_PCM_FRAME_LENGTH){ + TRACE_A2DP_DECODER_W("[MCU][AAC] pcm_len = %d \n", buffer_bytes); + return A2DP_DECODER_NO_ERROR; + } + if(!aacDec_handle){ + TRACE_A2DP_DECODER_W("[MCU][AAC] aac_lc_decode not ready"); + return A2DP_DECODER_NO_ERROR; + } + + node = a2dp_audio_list_begin(list); + if (!node){ + TRACE_A2DP_DECODER_W("[MCU][AAC] cache underflow"); + cache_underflow = true; + goto exit; + }else{ + aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_list_node(node); + + if (aac_decoder_frame_p->aac_buffer_len < 64) + aac_maxreadBytes = 64; + else if (aac_decoder_frame_p->aac_buffer_len < 128) + aac_maxreadBytes = 128; + else if (aac_decoder_frame_p->aac_buffer_len < 256) + aac_maxreadBytes = 256; + else if (aac_decoder_frame_p->aac_buffer_len < 512) + aac_maxreadBytes = 512; + else if (aac_decoder_frame_p->aac_buffer_len < 1024) + aac_maxreadBytes = 1024; + + bufferSize = aac_maxreadBytes; + bytesValid = aac_maxreadBytes; + decoder_err = aacDecoder_Fill(aacDec_handle, &(aac_decoder_frame_p->aac_buffer), &bufferSize, &bytesValid); + if (decoder_err != AAC_DEC_OK) { + TRACE_A2DP_DECODER_W("[MCU][AAC] aacDecoder_Fill failed:0x%x", decoder_err); + //if aac failed reopen it again + if(is_aacDecoder_Close(aacDec_handle)){ + a2dp_audio_aac_lc_decoder_reinit(); + TRACE_A2DP_DECODER_I("[MCU][AAC] aac_lc_decode reinin codec \n"); + } + goto end_decode; + } + + /* decode one AAC frame */ + decoder_err = aacDecoder_DecodeFrame(aacDec_handle, (short *)buffer, buffer_bytes/2, 0 /* flags */); + TRACE_A2DP_DECODER_D("[MCU][AAC] decoder seq:%d len:%d err:%x", aac_decoder_frame_p->sequenceNumber, + aac_decoder_frame_p->aac_buffer_len, + decoder_err); + if (decoder_err != AAC_DEC_OK){ + TRACE_A2DP_DECODER_W("[MCU][AAC]aac_lc_decode failed:0x%x", decoder_err); + //if aac failed reopen it again + if(is_aacDecoder_Close(aacDec_handle)){ + a2dp_audio_aac_lc_decoder_reinit(); + TRACE_A2DP_DECODER_I("[MCU][AAC]aac_lc_decode reinin codec \n"); + } + goto end_decode; + } + + stream_info = aacDecoder_GetStreamInfo(aacDec_handle); + if (!stream_info || stream_info->sampleRate <= 0) { + TRACE_A2DP_DECODER_W("[MCU][AAC]aac_lc_decode invalid stream info"); + goto end_decode; + } + + output_byte = stream_info->frameSize * stream_info->numChannels * 2;//sizeof(pcm_buffer[0]); + ASSERT_A2DP_DECODER(AAC_OUTPUT_FRAME_SAMPLES == output_byte/4, "aac_lc_decode output mismatch samples:%d", output_byte/4); +end_decode: + a2dp_audio_aac_lastframe_info.sequenceNumber = aac_decoder_frame_p->sequenceNumber; + a2dp_audio_aac_lastframe_info.timestamp = aac_decoder_frame_p->timestamp; + a2dp_audio_aac_lastframe_info.curSubSequenceNumber = 0; + a2dp_audio_aac_lastframe_info.totalSubSequenceNumber = 0; + a2dp_audio_aac_lastframe_info.frame_samples = AAC_OUTPUT_FRAME_SAMPLES; + a2dp_audio_aac_lastframe_info.decoded_frames++; + a2dp_audio_aac_lastframe_info.undecode_frames = a2dp_audio_list_length(list)-1; + a2dp_audio_aac_lastframe_info.check_sum= a2dp_audio_decoder_internal_check_sum_generate(aac_decoder_frame_p->aac_buffer, aac_decoder_frame_p->aac_buffer_len); + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_aac_lastframe_info); + a2dp_audio_list_remove(list, aac_decoder_frame_p); + } +exit: + if(cache_underflow){ + a2dp_audio_aac_lastframe_info.undecode_frames = 0; + a2dp_audio_aac_lastframe_info.check_sum = 0; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_aac_lastframe_info); + output_byte = A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + return output_byte; +} + +int a2dp_audio_aac_lc_decode_frame(uint8_t *buffer, uint32_t buffer_bytes) +{ +#ifdef A2DP_CP_ACCEL + return a2dp_cp_aac_lc_mcu_decode(buffer, buffer_bytes); +#else + return a2dp_audio_aac_lc_mcu_decode_frame(buffer, buffer_bytes); +#endif +} + +int a2dp_audio_aac_lc_preparse_packet(btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + a2dp_audio_aac_lastframe_info.sequenceNumber = header->sequenceNumber; + a2dp_audio_aac_lastframe_info.timestamp = header->timestamp; + a2dp_audio_aac_lastframe_info.curSubSequenceNumber = 0; + a2dp_audio_aac_lastframe_info.totalSubSequenceNumber = 0; + a2dp_audio_aac_lastframe_info.frame_samples = AAC_OUTPUT_FRAME_SAMPLES; + a2dp_audio_aac_lastframe_info.list_samples = AAC_OUTPUT_FRAME_SAMPLES; + a2dp_audio_aac_lastframe_info.decoded_frames = 0; + a2dp_audio_aac_lastframe_info.undecode_frames = 0; + a2dp_audio_aac_lastframe_info.check_sum = 0; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_aac_lastframe_info); + + TRACE_A2DP_DECODER_I("[AAC][PRE] seq:%d timestamp:%08x", header->sequenceNumber, header->timestamp); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_aac_lc_reorder_init(void) +{ + aac_decoder_frame_reorder_p = NULL; + aac_decoder_last_valid_frame_ready = false; + aac_decoder_last_valid_frame.sequenceNumber = 0; + aac_decoder_last_valid_frame.timestamp = 0; + aac_decoder_last_valid_frame.aac_buffer = NULL; + aac_decoder_last_valid_frame.aac_buffer_len = 0; + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_aac_lc_reorder_deinit(void) +{ + aac_decoder_frame_reorder_p = NULL; + aac_decoder_last_valid_frame_ready = false; + aac_decoder_last_valid_frame.sequenceNumber = 0; + aac_decoder_last_valid_frame.timestamp = 0; + aac_decoder_last_valid_frame.aac_buffer = NULL; + aac_decoder_last_valid_frame.aac_buffer_len = 0; + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_aac_lc_reorder_store_packet(a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p, + btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + aac_decoder_frame_p->sequenceNumber = header->sequenceNumber; + aac_decoder_frame_p->timestamp = header->timestamp; + memcpy(aac_decoder_frame_p->aac_buffer, buffer, buffer_bytes); + aac_decoder_frame_p->aac_buffer_len = buffer_bytes; + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_aac_lc_reorder_proc(a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p, + btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + uint8_t *dest_buf = NULL; + if ((aac_decoder_frame_p->aac_buffer_len + buffer_bytes) > AAC_READBUF_SIZE){ + return A2DP_DECODER_NO_ERROR; + } + TRACE_A2DP_DECODER_W("[AAC][INPUT][REORDER] proc enter seq:%d len:%d", aac_decoder_frame_p->sequenceNumber, aac_decoder_frame_p->aac_buffer_len); + dest_buf = &aac_decoder_frame_p->aac_buffer[aac_decoder_frame_p->aac_buffer_len]; + memcpy(dest_buf, buffer, buffer_bytes); + aac_decoder_frame_p->aac_buffer_len += buffer_bytes; + TRACE_A2DP_DECODER_W("[AAC][INPUT][REORDER] proc exit seq:%d len:%d", aac_decoder_frame_p->sequenceNumber, aac_decoder_frame_p->aac_buffer_len); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_aac_lc_packet_recover_save_last(a2dp_audio_aac_decoder_frame_t *aac_decoder_frame) +{ + aac_decoder_last_valid_frame_ready = true; + aac_decoder_last_valid_frame.sequenceNumber = aac_decoder_frame->sequenceNumber; + aac_decoder_last_valid_frame.timestamp = aac_decoder_frame->timestamp; + return 0; +} + +int a2dp_audio_aac_lc_packet_recover_find_missing(a2dp_audio_aac_decoder_frame_t *aac_decoder_frame) +{ + uint16_t diff_seq = 0; + uint32_t diff_timestamp = 0; + uint32_t diff = 0; + float tmp_pkt_cnt = 0; + uint32_t need_recover_pkt = 0; + + if (!aac_decoder_last_valid_frame_ready){ + return need_recover_pkt; + } + + diff_seq = a2dp_audio_get_passed(aac_decoder_frame->sequenceNumber, aac_decoder_last_valid_frame.sequenceNumber, UINT16_MAX); + diff_timestamp = a2dp_audio_get_passed(aac_decoder_frame->timestamp, aac_decoder_last_valid_frame.timestamp, UINT32_MAX); + + if (diff_seq > 1){ + TRACE_A2DP_DECODER_W("[AAC][INPUT][PLC] seq:%d/%d stmp:%d/%d", aac_decoder_frame->sequenceNumber, aac_decoder_last_valid_frame.sequenceNumber, + aac_decoder_frame->timestamp, aac_decoder_last_valid_frame.timestamp); + diff = diff_timestamp/diff_seq; + if (diff%AAC_OUTPUT_FRAME_SAMPLES == 0){ + tmp_pkt_cnt = diff_timestamp/AAC_OUTPUT_FRAME_SAMPLES; + }else{ + tmp_pkt_cnt = (float)diff_timestamp/ + ((1000.f/(float)a2dp_audio_context_p->output_cfg.sample_rate)*(float)AAC_OUTPUT_FRAME_SAMPLES); + } + need_recover_pkt = (uint32_t)(tmp_pkt_cnt+0.5f); + TRACE_A2DP_DECODER_W("[AAC][INPUT][PLC] diff_seq:%d diff_stmp:%d diff:%d missing:%d", diff_seq, diff_timestamp, diff, need_recover_pkt); + if (need_recover_pkt == diff_seq){ + need_recover_pkt--; + TRACE_A2DP_DECODER_W("[AAC][INPUT][PLC] need_recover_pkt seq:%d", need_recover_pkt); + }else{ + need_recover_pkt = 0; + } + } + return need_recover_pkt; +} + +int a2dp_audio_aac_lc_packet_recover_proc(a2dp_audio_aac_decoder_frame_t *aac_decoder_frame) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int missing_pkt_cnt = 0; + missing_pkt_cnt = a2dp_audio_aac_lc_packet_recover_find_missing(aac_decoder_frame); + if (missing_pkt_cnt <= 4 && a2dp_audio_list_length(list) + missing_pkt_cnt < aac_mtu_limiter){ + for (uint8_t i=0; iaac_buffer_len); + aac_decoder_frame_p->sequenceNumber = UINT16_MAX; + aac_decoder_frame_p->timestamp = UINT32_MAX; + memcpy(aac_decoder_frame_p->aac_buffer, aac_decoder_frame->aac_buffer, aac_decoder_frame->aac_buffer_len); + aac_decoder_frame_p->aac_buffer_len = aac_decoder_frame->aac_buffer_len; + a2dp_audio_list_append(list, aac_decoder_frame_p); + } + } + + return A2DP_DECODER_NO_ERROR; +} + +int inline a2dp_audio_aac_lc_packet_append(a2dp_audio_aac_decoder_frame_t *aac_decoder_frame) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_aac_lc_packet_recover_proc(aac_decoder_frame); + a2dp_audio_aac_lc_packet_recover_save_last(aac_decoder_frame); + a2dp_audio_list_append(list, aac_decoder_frame); + return 0; +} + +#if 1 +int a2dp_audio_aac_lc_store_packet(btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int nRet = A2DP_DECODER_NO_ERROR; + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = NULL; + + if (a2dp_audio_list_length(list) < aac_mtu_limiter && + buffer_bytes <= AAC_READBUF_SIZE){ + if (aac_decoder_frame_reorder_p == NULL){ + aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_aac_lc_frame_malloc(buffer_bytes); + aac_decoder_frame_reorder_p = aac_decoder_frame_p; + TRACE_A2DP_DECODER_W("[AAC][INPUT][REORDER] start seq:%d len:%d", header->sequenceNumber, buffer_bytes); + a2dp_audio_aac_lc_reorder_store_packet(aac_decoder_frame_p, header, buffer, buffer_bytes); + }else{ + if (aac_decoder_frame_reorder_p->aac_buffer[0] == buffer[0] && + aac_decoder_frame_reorder_p->aac_buffer[1] == buffer[1]){ + a2dp_audio_aac_lc_packet_append(aac_decoder_frame_reorder_p); + aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_aac_lc_frame_malloc(buffer_bytes); + aac_decoder_frame_reorder_p = aac_decoder_frame_p; + a2dp_audio_aac_lc_reorder_store_packet(aac_decoder_frame_p, header, buffer, buffer_bytes); + }else{ + aac_decoder_frame_p = aac_decoder_frame_reorder_p; + a2dp_audio_aac_lc_reorder_proc(aac_decoder_frame_p, header, buffer, buffer_bytes); + a2dp_audio_aac_lc_packet_append(aac_decoder_frame_p); + aac_decoder_frame_reorder_p = NULL; + } + } + nRet = A2DP_DECODER_NO_ERROR; + }else{ + TRACE_A2DP_DECODER_W("[AAC][INPUT] list full current list_len:%d buff_len:%d", a2dp_audio_list_length(list), buffer_bytes); + nRet = A2DP_DECODER_MTU_LIMTER_ERROR; + } + + return nRet; +} +#else +int a2dp_audio_aac_lc_store_packet(btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int nRet = A2DP_DECODER_NO_ERROR; + + if (!a2dp_audio_aac_lc_reorder_valid(header, buffer, buffer_bytes)){ + return A2DP_DECODER_NO_ERROR; + } + + if (a2dp_audio_list_length(list) < aac_mtu_limiter && + buffer_bytes <= AAC_READBUF_SIZE){ + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_aac_lc_frame_malloc(buffer_bytes); + TRACE_A2DP_DECODER_D("[AAC][INPUT]seq:%d len:%d", header->sequenceNumber, buffer_bytes); + aac_decoder_frame_p->sequenceNumber = header->sequenceNumber; + aac_decoder_frame_p->timestamp = header->timestamp; + memcpy(aac_decoder_frame_p->aac_buffer, buffer, buffer_bytes); + aac_decoder_frame_p->aac_buffer_len = buffer_bytes; + a2dp_audio_aac_lc_reorder_history(aac_decoder_frame_p); + a2dp_audio_list_append(list, aac_decoder_frame_p); + nRet = A2DP_DECODER_NO_ERROR; + }else{ + TRACE_A2DP_DECODER_I("[AAC][INPUT] list full current list_len:%d buff_len:%d", a2dp_audio_list_length(list), buffer_bytes); + nRet = A2DP_DECODER_MTU_LIMTER_ERROR; + } + + return nRet; +} +#endif + +int a2dp_audio_aac_lc_discards_packet(uint32_t packets) +{ + int nRet = A2DP_DECODER_MEMORY_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = NULL; + +#ifdef A2DP_CP_ACCEL + a2dp_cp_reset_frame(); +#endif + + if (packets <= a2dp_audio_list_length(list)){ + for (uint8_t i=0; iaudio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame = NULL; + + if (a2dp_audio_list_length(list) && ((node = a2dp_audio_list_begin(list)) != NULL)){ + aac_decoder_frame = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_list_node(node); + headframe_info->sequenceNumber = aac_decoder_frame->sequenceNumber; + headframe_info->timestamp = aac_decoder_frame->timestamp; + headframe_info->curSubSequenceNumber = 0; + headframe_info->totalSubSequenceNumber = 0; + }else{ + memset(headframe_info, 0, sizeof(A2DP_AUDIO_HEADFRAME_INFO_T)); + } + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_aac_lc_info_get(void *info) +{ + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_aac_lc_synchronize_packet(A2DP_AUDIO_SYNCFRAME_INFO_T *sync_info, uint32_t mask) +{ + int nRet = A2DP_DECODER_SYNC_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + int list_len; + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = NULL; + +#ifdef A2DP_CP_ACCEL + a2dp_cp_reset_frame(); +#endif + + list_len = a2dp_audio_list_length(list); + + for (uint16_t i=0; isequenceNumber, sync_info->sequenceNumber, + aac_decoder_frame_p->timestamp, sync_info->timestamp); + if (A2DP_AUDIO_SYNCFRAME_CHK(aac_decoder_frame_p->sequenceNumber == sync_info->sequenceNumber, A2DP_AUDIO_SYNCFRAME_MASK_SEQ, mask)&& + A2DP_AUDIO_SYNCFRAME_CHK(aac_decoder_frame_p->timestamp == sync_info->timestamp, A2DP_AUDIO_SYNCFRAME_MASK_TIMESTAMP, mask)){ + nRet = A2DP_DECODER_NO_ERROR; + break; + } + a2dp_audio_list_remove(list, aac_decoder_frame_p); + } + } + + node = a2dp_audio_list_begin(list); + if (node){ + aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_list_node(node); + TRACE_A2DP_DECODER_I("[MCU][SYNC][AAC] sync pkt nRet:%d SEQ:%d timestamp:%d", nRet, aac_decoder_frame_p->sequenceNumber, aac_decoder_frame_p->timestamp); + }else{ + TRACE_A2DP_DECODER_I("[MCU][SYNC][AAC] sync pkt nRet:%d", nRet); + } + + return nRet; +} + +int a2dp_audio_aac_lc_synchronize_dest_packet_mut(uint16_t packet_mut) +{ + list_node_t *node = NULL; + uint32_t list_len = 0; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = NULL; + + list_len = a2dp_audio_list_length(list); + if (list_len > packet_mut){ + do{ + node = a2dp_audio_list_begin(list); + if (node){ + aac_decoder_frame_p = (a2dp_audio_aac_decoder_frame_t *)a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, aac_decoder_frame_p); + } + }while(a2dp_audio_list_length(list) > packet_mut); + } + + if (packet_mut == 0){ + if (aac_decoder_frame_reorder_p){ + a2dp_audio_aac_lc_free(aac_decoder_frame_reorder_p); + a2dp_audio_aac_lc_reorder_init(); + } + } + + TRACE_A2DP_DECODER_I("[MCU][SYNC][AAC] dest pkt list:%d", a2dp_audio_list_length(list)); + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_aac_lc_convert_list_to_samples(uint32_t *samples) +{ + uint32_t list_len = 0; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + + list_len = a2dp_audio_list_length(list); + *samples = AAC_OUTPUT_FRAME_SAMPLES*list_len; + + TRACE_A2DP_DECODER_I("AUD][DECODER][MCU][AAC] list:%d samples:%d", list_len, *samples); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_aac_lc_discards_samples(uint32_t samples) +{ + int nRet = A2DP_DECODER_SYNC_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_aac_decoder_frame_t *aac_decoder_frame_p = NULL; + list_node_t *node = NULL; + int need_remove_list = 0; + uint32_t list_samples = 0; + ASSERT_A2DP_DECODER(!(samples%AAC_OUTPUT_FRAME_SAMPLES), "%s samples err:%d", __func__, samples); + + a2dp_audio_aac_lc_convert_list_to_samples(&list_samples); + if (list_samples >= samples){ + need_remove_list = samples/AAC_OUTPUT_FRAME_SAMPLES; + for (int i=0; i= CP_PROC_DELAY_QTY) { + return 1; + } + mcu_dec_inited = false; + decode_frame = decode_func; + proc_delay = delay; +#ifdef A2DP_TRACE_CP_DEC_TIME + cp_last_dec_time = hal_fast_sys_timer_get(); +#endif + + norflash_api_flush_disable(NORFLASH_API_USER_CP,(uint32_t)cp_accel_init_done); + cp_accel_open(CP_TASK_A2DP_DECODE, &TASK_DESC_A2DP); + while(cp_accel_init_done() == false) { + hal_sys_timer_delay_us(100); + } + norflash_api_flush_enable(NORFLASH_API_USER_CP); + return 0; +} +int a2dp_cp_deinit(void) +{ + cp_accel_close(CP_TASK_A2DP_DECODE); + + return 0; +} + +SRAM_TEXT_LOC +int a2dp_cp_decoder_init(uint32_t out_frame_len, uint8_t max_frames) +{ + uint32_t i; + max_buffer_frames = max_frames; + if (!mcu_dec_inited) { +#ifdef A2DP_TRACE_CP_ACCEL + TRACE_A2DP_DECODER_I("%s: Decoder init", __func__); +#endif + if(cp_accel_init_done() == false){ + TRACE_A2DP_DECODER_I("%s: CP ACCEL not init yet", __func__); + return 6; + } + + cp_heap = heap_register(cp_heap_buf, sizeof(cp_heap_buf)); + if (cp_heap == NULL) { + return 1; + } + + in_frames = heap_malloc(cp_heap, sizeof(in_frames[0]) * CP_IN_FRAME_CNT); + if (in_frames == NULL) { + return 2; + } + + out_frames = heap_malloc(cp_heap, sizeof(out_frames[0]) * CP_OUT_FRAME_CNT); + if (out_frames == NULL) { + return 3; + } + + cp_in_cache = heap_malloc(cp_heap, CP_IN_CACHE_SIZE); + if (cp_in_cache == NULL) { + return 4; + } + + cp_out_cache = heap_malloc(cp_heap, out_frame_len * CP_OUT_FRAME_CNT); + if (cp_out_cache == NULL) { + return 5; + } + + for (i = 0; i < CP_OUT_FRAME_CNT; i++) { + out_frames[i].pos = out_frame_len * i; + out_frames[i].len = out_frame_len; + } + reset_frame_info(); + + mcu_dec_inited = true; + } + + return 0; +} + +CP_TEXT_SRAM_LOC +static uint32_t get_in_frame_cnt(uint32_t in_widx, uint32_t in_ridx) +{ + uint32_t cnt; + + if (in_widx >= in_ridx) { + cnt = in_widx - in_ridx; + } else { + cnt = CP_IN_FRAME_CNT - in_ridx + in_widx; + } + + return cnt; +} + +uint32_t get_in_cp_frame_cnt(void) +{ + return get_in_frame_cnt(cp_in_widx, cp_in_ridx); +} + +uint32_t get_in_cp_frame_delay(void) +{ + return proc_delay; +} + +SRAM_TEXT_LOC +static uint32_t get_in_frame_free_cnt(uint32_t in_widx, uint32_t in_ridx) +{ + uint32_t free_cnt; + + if (in_widx >= in_ridx) { + free_cnt = CP_IN_FRAME_CNT - in_widx + in_ridx; + } else { + free_cnt = in_ridx - in_widx; + } + free_cnt -= 1; + + return free_cnt; +} + +SRAM_TEXT_LOC +int a2dp_cp_put_in_frame(const void *buf1, uint32_t len1, const void *buf2, uint32_t len2) +{ + uint16_t free_cnt; + uint16_t in_widx; + uint16_t in_ridx; + uint16_t prev_in_widx; + uint32_t free_len; + uint32_t in_wpos; + uint32_t in_rpos; + uint32_t aligned_len; + + if (reset_frames) { + return -1; + } + + in_widx = cp_in_widx; + in_ridx = cp_in_ridx; + + if (max_buffer_frames < get_in_cp_frame_cnt()){ + return 1; + } + + free_cnt = get_in_frame_free_cnt(in_widx, in_ridx); + if (free_cnt == 0) { + return 1; + } + + if (in_widx == in_ridx) { + in_wpos = 0; + in_rpos = 0; + } else { + if (in_widx == 0) { + prev_in_widx = CP_IN_FRAME_CNT - 1; + } else { + prev_in_widx = in_widx - 1; + } + in_wpos = in_frames[prev_in_widx].pos + in_frames[prev_in_widx].len; + if (in_wpos >= CP_IN_CACHE_SIZE) { + in_wpos -= CP_IN_CACHE_SIZE; + } + in_rpos = in_frames[in_ridx].pos; + } + + // Align to word boundary + in_wpos = (in_wpos + 3) & ~3; + if (in_wpos >= CP_IN_CACHE_SIZE) { + in_wpos -= CP_IN_CACHE_SIZE; + } + aligned_len = (len1 + len2 + 3) & ~3; + + if (in_wpos >= in_rpos) { + free_len = CP_IN_CACHE_SIZE - in_wpos; + if (in_rpos == 0) { + free_len -= 1; + } + if (free_len < aligned_len) { + free_len = (in_rpos > 0) ? (in_rpos - 1) : 0; + if (free_len < aligned_len) { + return 2; + } + in_wpos = 0; + } + } else { + free_len = in_rpos - in_wpos - 1; + if (free_len < aligned_len) { + return 3; + } + } + + in_frames[in_widx].pos = in_wpos; + in_frames[in_widx].len = len1 + len2; + + if (len1) { + memcpy(&cp_in_cache[in_wpos], buf1, len1); + in_wpos += len1; + } + if (len2) { + memcpy(&cp_in_cache[in_wpos], buf2, len2); + in_wpos += len2; + } + + in_widx += 1; + if (in_widx >= CP_IN_FRAME_CNT) { + in_widx -= CP_IN_FRAME_CNT; + } + cp_in_widx = in_widx; + + return 0; +} + +CP_TEXT_SRAM_LOC +int a2dp_cp_get_in_frame(void **p_buf, uint32_t *p_len) +{ + uint16_t in_widx; + uint16_t in_ridx; + uint32_t in_rpos; + + if (reset_frames) { + return -1; + } + + in_widx = cp_in_widx; + in_ridx = cp_in_ridx; + + if (in_widx == in_ridx) { + return 1; + } + + in_rpos = in_frames[in_ridx].pos; + + if (p_buf) { + *p_buf = &cp_in_cache[in_rpos]; + } + if (p_len) { + *p_len = in_frames[in_ridx].len; + } + + return 0; +} + +CP_TEXT_SRAM_LOC +int a2dp_cp_consume_in_frame(void) +{ + uint16_t in_widx; + uint16_t in_ridx; + + if (reset_frames) { + return 0; + } + + in_widx = cp_in_widx; + in_ridx = cp_in_ridx; + + if (in_widx == in_ridx) { + return 1; + } + + in_ridx += 1; + if (in_ridx >= CP_IN_FRAME_CNT) { + in_ridx -= CP_IN_FRAME_CNT; + } + cp_in_ridx = in_ridx; + + return 0; +} + +CP_TEXT_SRAM_LOC +uint32_t a2dp_cp_get_in_frame_index(void) +{ + return cp_in_ridx; +} + +SRAM_TEXT_LOC +uint32_t a2dp_cp_get_in_frame_cnt_by_index(uint32_t ridx) +{ + return get_in_frame_cnt(cp_in_widx, ridx); +} + +SRAM_TEXT_LOC +void a2dp_cp_reset_frame(void) +{ +#ifdef A2DP_TRACE_CP_ACCEL + TRACE_A2DP_DECODER_I("%s: Reset frames", __func__); +#endif + + reset_frames = true; + + // Notify CP to work again + cp_accel_send_event_mcu2cp(1); +} + +SRAM_TEXT_LOC +bool a2dp_cp_get_frame_reset_status(void) +{ + return reset_frames; +} + +CP_TEXT_SRAM_LOC +enum CP_EMPTY_OUT_FRM_T a2dp_cp_get_emtpy_out_frame(void **p_buf, uint32_t *p_len) +{ + enum CP_EMPTY_OUT_FRM_T ret; + uint8_t out_widx; + uint32_t out_wpos; + enum CP_DEC_STATE_T state ; + + if (reset_frames) { + return CP_EMPTY_OUT_FRM_ERR; + } + + out_widx = cp_out_widx; + state = out_frames[out_widx].state; + + if (state != CP_DEC_STATE_IDLE && state != CP_DEC_STATE_WORKING) { + return CP_EMPTY_OUT_FRM_ERR; + } + + if (state == CP_DEC_STATE_WORKING) { + ret = CP_EMPTY_OUT_FRM_WORKING; + } else { + out_frames[out_widx].state = CP_DEC_STATE_WORKING; + ret = CP_EMPTY_OUT_FRM_OK; + } + + out_wpos = out_frames[out_widx].pos; + + if (p_buf) { + *p_buf = &cp_out_cache[out_wpos]; + } + if (p_len) { + *p_len = out_frames[out_widx].len; + } + + return ret; +} + +CP_TEXT_SRAM_LOC +int a2dp_cp_consume_emtpy_out_frame(void) +{ + uint8_t out_widx; + + if (reset_frames) { + return 0; + } + + out_widx = cp_out_widx; + + if (out_frames[out_widx].state != CP_DEC_STATE_WORKING) { + return 1; + } + + out_frames[out_widx].state = CP_DEC_STATE_DONE; + +#ifdef A2DP_TRACE_CP_ACCEL + TRACE_A2DP_DECODER_I("AD2P-CP out frame W[%d]", out_widx); +#endif + + out_widx += 1; + if (out_widx >= CP_OUT_FRAME_CNT) { + out_widx -= CP_OUT_FRAME_CNT; + } + cp_out_widx = out_widx; + + return 0; +} + +SRAM_TEXT_LOC +int a2dp_cp_get_full_out_frame(void **p_buf, uint32_t *p_len) +{ + uint8_t out_ridx; + uint32_t out_rpos; + enum CP_DEC_STATE_T state ; + + if (reset_frames) { + return -1; + } + + out_ridx = cp_out_ridx; + state = out_frames[out_ridx].state; + + if (state != CP_DEC_STATE_DONE && state != CP_DEC_STATE_INIT_DONE) { + // Notify CP to work again + cp_accel_send_event_mcu2cp(CP_BUILD_ID(CP_TASK_A2DP_DECODE, CP_EVENT_A2DP_DECODE)); + if (state == CP_DEC_STATE_WORKING){ + return CP_EMPTY_OUT_FRM_WORKING; + }else{ + return (10 + state); + } + } + + out_rpos = out_frames[out_ridx].pos; + + if (state == CP_DEC_STATE_DONE) { + if (p_buf) { + *p_buf = &cp_out_cache[out_rpos]; + } + if (p_len) { + *p_len = out_frames[out_ridx].len; + } + } else { + if (p_buf) { + *p_buf = NULL; + } + if (p_len) { + *p_len = 0; + } + } + + return 0; +} + +SRAM_TEXT_LOC +int a2dp_cp_consume_full_out_frame(void) +{ + uint8_t out_ridx; + enum CP_DEC_STATE_T state ; + + if (reset_frames) { + return 0; + } + + out_ridx = cp_out_ridx; + state = out_frames[out_ridx].state; + + if (state != CP_DEC_STATE_DONE && state != CP_DEC_STATE_INIT_DONE) { + return 1; + } + +#ifdef A2DP_TRACE_CP_ACCEL + TRACE_A2DP_DECODER_I("AD2P-CP out frame R[%d]", out_ridx); +#endif + + out_frames[out_ridx].state = CP_DEC_STATE_IDLE; + + out_ridx += 1; + if (out_ridx >= CP_OUT_FRAME_CNT) { + out_ridx -= CP_OUT_FRAME_CNT; + } + cp_out_ridx = out_ridx; + + // Notify CP to work again + cp_accel_send_event_mcu2cp(CP_BUILD_ID(CP_TASK_A2DP_DECODE, CP_EVENT_A2DP_DECODE)); + + return 0; +} + +#endif + diff --git a/apps/audioplayers/a2dp_decoder/a2dp_decoder_cp.h b/apps/audioplayers/a2dp_decoder/a2dp_decoder_cp.h new file mode 100644 index 0000000..3fed4c4 --- /dev/null +++ b/apps/audioplayers/a2dp_decoder/a2dp_decoder_cp.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __A2DP_DECODER_CP_H__ +#define __A2DP_DECODER_CP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "stdbool.h" + +enum CP_PROC_DELAY_T { + CP_PROC_DELAY_0_FRAME = 0, + CP_PROC_DELAY_1_FRAME, + CP_PROC_DELAY_2_FRAMES, + CP_PROC_DELAY_3_FRAMES, + + CP_PROC_DELAY_QTY, +}; + +enum CP_EMPTY_OUT_FRM_T { + CP_EMPTY_OUT_FRM_OK, + CP_EMPTY_OUT_FRM_WORKING, + CP_EMPTY_OUT_FRM_ERR, +}; + +typedef int (*A2DP_CP_DECODE_T)(void); + +int a2dp_cp_init(A2DP_CP_DECODE_T decode_func, enum CP_PROC_DELAY_T delay); + +int a2dp_cp_deinit(void); + +int a2dp_cp_decoder_init(uint32_t out_frame_len, uint8_t max_frames); + +int a2dp_cp_put_in_frame(const void *buf1, uint32_t len1, const void *buf2, uint32_t len2); + +int a2dp_cp_get_in_frame(void **p_buf, uint32_t *p_len); + +int a2dp_cp_consume_in_frame(void); + +uint32_t a2dp_cp_get_in_frame_index(void); + +uint32_t a2dp_cp_get_in_frame_cnt_by_index(uint32_t ridx); + +void a2dp_cp_reset_frame(void); + +bool a2dp_cp_get_in_frame_reset_status(void); + +enum CP_EMPTY_OUT_FRM_T a2dp_cp_get_emtpy_out_frame(void **p_buf, uint32_t *p_len); + +int a2dp_cp_consume_emtpy_out_frame(void); + +int a2dp_cp_get_full_out_frame(void **p_buf, uint32_t *p_len); + +int a2dp_cp_consume_full_out_frame(void); + +unsigned int set_cp_reset_flag(uint8_t evt); + +bool is_cp_need_reset(void); + +bool is_cp_init_done(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/apps/audioplayers/a2dp_decoder/a2dp_decoder_example.cpp b/apps/audioplayers/a2dp_decoder/a2dp_decoder_example.cpp new file mode 100644 index 0000000..34595c0 --- /dev/null +++ b/apps/audioplayers/a2dp_decoder/a2dp_decoder_example.cpp @@ -0,0 +1,137 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Standard C Included Files +#include "cmsis.h" +#include "plat_types.h" +#include +#include "heap_api.h" +#include "hal_location.h" +#include "a2dp_decoder_internal.h" + +static A2DP_AUDIO_CONTEXT_T *a2dp_audio_context_p = NULL; +static A2DP_AUDIO_DECODER_LASTFRAME_INFO_T a2dp_audio_ldac_example_info; +static A2DP_AUDIO_OUTPUT_CONFIG_T a2dp_audio_example_output_config; + +typedef struct { + uint16_t sequenceNumber; + uint32_t timestamp; + uint8_t *buffer; + uint32_t buffer_len; +} a2dp_audio_example_decoder_frame_t; + + +int a2dp_audio_example_decode_frame(uint8_t *buffer, uint32_t buffer_bytes) +{ + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_example_preparse_packet(btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + return A2DP_DECODER_NO_ERROR; +} + + +static void *a2dp_audio_example_frame_malloc(uint32_t packet_len) +{ + a2dp_audio_example_decoder_frame_t *decoder_frame_p = NULL; + uint8_t *buffer = NULL; + + buffer = (uint8_t *)a2dp_audio_heap_malloc(packet_len); + decoder_frame_p = (a2dp_audio_example_decoder_frame_t *)a2dp_audio_heap_malloc(sizeof(a2dp_audio_example_decoder_frame_t)); + decoder_frame_p->buffer = buffer; + decoder_frame_p->buffer_len = packet_len; + return (void *)decoder_frame_p; +} + +void a2dp_audio_example_free(void *packet) +{ + a2dp_audio_example_decoder_frame_t *decoder_frame_p = (a2dp_audio_example_decoder_frame_t *)packet; + a2dp_audio_heap_free(decoder_frame_p->buffer); + a2dp_audio_heap_free(decoder_frame_p); +} + +int a2dp_audio_example_store_packet(btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_example_decoder_frame_t *decoder_frame_p = (a2dp_audio_example_decoder_frame_t *)a2dp_audio_example_frame_malloc(buffer_bytes); + + decoder_frame_p->sequenceNumber = header->sequenceNumber; + decoder_frame_p->timestamp = header->timestamp; + memcpy(decoder_frame_p->buffer, buffer, buffer_bytes); + decoder_frame_p->buffer_len = buffer_bytes; + a2dp_audio_list_append(list, decoder_frame_p); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_example_discards_packet(uint32_t packets) +{ + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_example_headframe_info_get(A2DP_AUDIO_HEADFRAME_INFO_T* headframe_info) +{ + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_example_info_get(void *info) +{ + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_example_init(A2DP_AUDIO_OUTPUT_CONFIG_T *config, void *context) +{ + TRACE_A2DP_DECODER_D("%s", __func__); + a2dp_audio_context_p = (A2DP_AUDIO_CONTEXT_T *)context; + + memset(&a2dp_audio_ldac_example_info, 0, sizeof(A2DP_AUDIO_DECODER_LASTFRAME_INFO_T)); + memcpy(&a2dp_audio_example_output_config, config, sizeof(A2DP_AUDIO_OUTPUT_CONFIG_T)); + a2dp_audio_ldac_example_info.stream_info = &a2dp_audio_example_output_config; + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_example_deinit(void) +{ + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_example_synchronize_packet(A2DP_AUDIO_SYNCFRAME_INFO_T *sync_info, uint32_t mask) +{ + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_example_synchronize_dest_packet_mut(uint16_t packet_mut) +{ + return A2DP_DECODER_NO_ERROR; +} + +A2DP_AUDIO_DECODER_T a2dp_audio_example_decoder_config = { + {44100, 2, 16}, + 0, + a2dp_audio_example_init, + a2dp_audio_example_deinit, + a2dp_audio_example_decode_frame, + a2dp_audio_example_preparse_packet, + a2dp_audio_example_store_packet, + a2dp_audio_example_discards_packet, + a2dp_audio_example_synchronize_packet, + a2dp_audio_example_synchronize_dest_packet_mut, + a2dp_audio_example_headframe_info_get, + a2dp_audio_example_info_get, + a2dp_audio_example_free, + } ; + diff --git a/apps/audioplayers/a2dp_decoder/a2dp_decoder_internal.h b/apps/audioplayers/a2dp_decoder/a2dp_decoder_internal.h new file mode 100644 index 0000000..c3c5525 --- /dev/null +++ b/apps/audioplayers/a2dp_decoder/a2dp_decoder_internal.h @@ -0,0 +1,201 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __A2DP_DECODER_INTERNAL_H__ +#define __A2DP_DECODER_INTERNAL_H__ + +#include "list.h" +#include "a2dp_decoder.h" +#ifdef A2DP_CP_ACCEL +#include "a2dp_decoder_cp.h" +#include "hal_location.h" +#endif +#include "a2dp_decoder_trace.h" + +#define TEXT_A2DP_LOC_A(n, l) __attribute__((section(#n "." #l))) +#define TEXT_A2DP_LOC(n, l) TEXT_A2DP_LOC_A(n, l) + +#define TEXT_SBC_LOC TEXT_A2DP_LOC(.overlay_a2dp_sbc, __LINE__) +#define TEXT_AAC_LOC TEXT_A2DP_LOC(.overlay_a2dp_aac, __LINE__) +#define TEXT_SSC_LOC TEXT_A2DP_LOC(.overlay_a2dp_ssc, __LINE__) +#define TEXT_LDAC_LOC TEXT_A2DP_LOC(.overlay_a2dp_ldac, __LINE__) +#define TEXT_LHDC_LOC TEXT_A2DP_LOC(.overlay_a2dp_lhdc, __LINE__) + +#define A2DP_DECODER_NO_ERROR (0) +#define A2DP_DECODER_DECODE_ERROR (-1) +#define A2DP_DECODER_BUSY_ERROR (-2) +#define A2DP_DECODER_MEMORY_ERROR (-3) +#define A2DP_DECODER_MTU_LIMTER_ERROR (-4) +#define A2DP_DECODER_CACHE_UNDERFLOW_ERROR (-5) +#define A2DP_DECODER_SYNC_ERROR (-6) +#define A2DP_DECODER_NOT_SUPPORT (-128) + +#ifdef MIN +#undef MIN +#endif +#define MIN(a,b) ((a)<(b) ? (a):(b)) +#ifdef MAX +#undef MAX +#endif +#define MAX(a,b) ((a)>(b) ? (a):(b)) + +typedef A2DP_AUDIO_OUTPUT_CONFIG_T AUDIO_DECODER_STREAM_INFO_T; + +typedef int (*AUDIO_DECODER_INIT)(A2DP_AUDIO_OUTPUT_CONFIG_T *, void *); +typedef int (*AUDIO_DECODER_DEINIT)(void); +typedef int (*AUDIO_DECODER_DECODE_FRAME)(uint8_t *, uint32_t); +typedef int (*AUDIO_DECODER_PREPARSE_PACKET)(btif_media_header_t *, uint8_t *, uint32_t); +typedef int (*AUDIO_DECODER_STORE_PACKET)(btif_media_header_t *, uint8_t *, uint32_t); +typedef int (*AUDIO_DECODER_DISCARDS_PACKET)(uint32_t); +typedef int (*AUDIO_DECODER_SYNCHRONIZE_PACKET)(A2DP_AUDIO_SYNCFRAME_INFO_T *, uint32_t); +typedef int (*AUDIO_DECODER_SYNCHRONIZE_DEST_PACKET_MUT)(uint16_t); +typedef int (*AUDIO_DECODER_HEADFRAME_INFO_GET)(A2DP_AUDIO_HEADFRAME_INFO_T*); +typedef int (*AUDIO_DECODER_INFO_GET)(void *); +typedef void(*AUDIO_DECODER_PACKET_FREE)(void *); +typedef int (*AUDIO_DECODER_SYNCHRONIZE_CONVERT_LIST_TO_SAMPLES)(uint32_t *); +typedef int (*AUDIO_DECODER_SYNCHRONIZE_DISCARDS_SAMPLES)(uint32_t); +typedef int (*AUDIO_DECODER_CHANNEL_SELECT)(A2DP_AUDIO_CHANNEL_SELECT_E); + +typedef struct { + AUDIO_DECODER_STREAM_INFO_T stream_info; + uint32_t auto_synchronize_support; + AUDIO_DECODER_INIT audio_decoder_init; + AUDIO_DECODER_DEINIT audio_decoder_deinit; + AUDIO_DECODER_DECODE_FRAME audio_decoder_decode_frame; + AUDIO_DECODER_PREPARSE_PACKET audio_decoder_preparse_packet; + AUDIO_DECODER_STORE_PACKET audio_decoder_store_packet; + AUDIO_DECODER_DISCARDS_PACKET audio_decoder_discards_packet; + AUDIO_DECODER_SYNCHRONIZE_PACKET audio_decoder_synchronize_packet; + AUDIO_DECODER_SYNCHRONIZE_DEST_PACKET_MUT audio_decoder_synchronize_dest_packet_mut; + AUDIO_DECODER_SYNCHRONIZE_CONVERT_LIST_TO_SAMPLES a2dp_audio_convert_list_to_samples; + AUDIO_DECODER_SYNCHRONIZE_DISCARDS_SAMPLES a2dp_audio_discards_samples; + AUDIO_DECODER_HEADFRAME_INFO_GET audio_decoder_headframe_info_get; + AUDIO_DECODER_INFO_GET audio_decoder_info_get; + AUDIO_DECODER_PACKET_FREE audio_decoder_packet_free; + AUDIO_DECODER_CHANNEL_SELECT audio_decoder_channel_select; +} A2DP_AUDIO_DECODER_T; + +typedef struct { + list_t *input_raw_packet_list; + list_t *output_pcm_packet_list; +} A2DP_AUDIO_DATAPATH_T; + +typedef struct { + bool enalbe; + void *semaphore; +} AUDIO_BUFFER_SEMAPHORE_T; + +enum A2DP_AUDIO_DECODER_STATUS { + A2DP_AUDIO_DECODER_STATUS_NULL, + A2DP_AUDIO_DECODER_STATUS_READY, + A2DP_AUDIO_DECODER_STATUS_START, + A2DP_AUDIO_DECODER_STATUS_STOP +}; + +enum A2DP_AUDIO_DECODER_STORE_PACKET_STATUS { + A2DP_AUDIO_DECODER_STORE_PACKET_STATUS_IDLE, + A2DP_AUDIO_DECODER_STORE_PACKET_STATUS_BUSY, +}; + +enum A2DP_AUDIO_DECODER_PLAYBACK_STATUS { + A2DP_AUDIO_DECODER_PLAYBACK_STATUS_IDLE, + A2DP_AUDIO_DECODER_PLAYBACK_STATUS_BUSY, +}; + +typedef struct { + uint16_t sequenceNumber; + uint32_t timestamp; + uint16_t curSubSequenceNumber; + uint16_t totalSubSequenceNumber; + uint32_t frame_samples; + uint32_t list_samples; + uint32_t decoded_frames; + uint32_t undecode_frames; + uint32_t check_sum; + A2DP_AUDIO_OUTPUT_CONFIG_T stream_info; +} A2DP_AUDIO_DECODER_LASTFRAME_INFO_T; + +typedef struct { + A2DP_AUDIO_SYNC_PID_T pid; + uint32_t tick; + uint32_t cnt; +} A2DP_AUDIO_SYNC_T; + +typedef struct { + A2DP_AUDIO_OUTPUT_CONFIG_T output_cfg; + float init_factor_reference; + A2DP_AUDIO_CHANNEL_SELECT_E chnl_sel; + uint16_t dest_packet_mut; + float average_packet_mut; + A2DP_AUDIO_DECODER_T audio_decoder; + A2DP_AUDIO_DATAPATH_T audio_datapath; + list_t *input_raw_packet_list; + list_t *output_pcm_packet_list; + bool need_detect_first_packet; + bool underflow_onporcess; + uint32_t skip_frame_cnt_after_no_cache; + uint32_t mute_frame_cnt_after_no_cache; + AUDIO_BUFFER_SEMAPHORE_T audio_semaphore; + void *audio_buffer_mutex; + void *audio_status_mutex; + void *audio_stop_mutex; + enum A2DP_AUDIO_DECODER_STATUS audio_decoder_status; + enum A2DP_AUDIO_DECODER_STORE_PACKET_STATUS store_packet_status; + enum A2DP_AUDIO_DECODER_PLAYBACK_STATUS playback_status; + A2DP_AUDIO_SYNC_T audio_sync; +#if A2DP_DECODER_HISTORY_SEQ_SAVE + uint16_t historySeq[A2DP_DECODER_HISTORY_SEQ_SAVE]; +#ifdef A2DP_DECODER_HISTORY_LOCTIME_SAVE + uint32_t historyLoctime[A2DP_DECODER_HISTORY_SEQ_SAVE]; +#endif +#ifdef A2DP_DECODER_HISTORY_CHECK_SUM_SAVE + uint32_t historyChecksum[A2DP_DECODER_HISTORY_SEQ_SAVE]; +#endif + uint8_t historySeq_idx; +#endif +} A2DP_AUDIO_CONTEXT_T; + +#ifdef __cplusplus +extern "C" { +#endif + +void *a2dp_audio_heap_malloc(uint32_t size); +void *a2dp_audio_heap_cmalloc(uint32_t size); +void *a2dp_audio_heap_realloc(void *rmem, uint32_t newsize); +void a2dp_audio_heap_free(void *rmem); + +list_node_t *a2dp_audio_list_begin(const list_t *list); +list_node_t *a2dp_audio_list_end(const list_t *list); +uint32_t a2dp_audio_list_length(const list_t *list); +void *a2dp_audio_list_node(const list_node_t *node); +list_node_t *a2dp_audio_list_next(const list_node_t *node); +bool a2dp_audio_list_remove(list_t *list, void *data); +bool a2dp_audio_list_append(list_t *list, void *data); +void a2dp_audio_list_clear(list_t *list); +void a2dp_audio_list_free(list_t *list); +list_t *a2dp_audio_list_new(list_free_cb callback, list_mempool_zmalloc zmalloc, list_mempool_free free); + +int a2dp_audio_semaphore_wait(uint32_t timeout_ms); +int a2dp_audio_semaphore_release(void); +int a2dp_audio_decoder_internal_lastframe_info_set(A2DP_AUDIO_DECODER_LASTFRAME_INFO_T *lastframe_info); +uint32_t a2dp_audio_get_passed(uint32_t curr_ticks, uint32_t prev_ticks, uint32_t max_ticks); +uint32_t a2dp_audio_decoder_internal_check_sum_generate(const uint8_t *buf, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif//__A2DPPLAY_H__ + diff --git a/apps/audioplayers/a2dp_decoder/a2dp_decoder_ldac.cpp b/apps/audioplayers/a2dp_decoder/a2dp_decoder_ldac.cpp new file mode 100644 index 0000000..e03aa3a --- /dev/null +++ b/apps/audioplayers/a2dp_decoder/a2dp_decoder_ldac.cpp @@ -0,0 +1,1117 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Standard C Included Files +#include "cmsis.h" +#include "plat_types.h" +#include +#include "heap_api.h" +#include "hal_location.h" +#include "a2dp_decoder_internal.h" +#include "btapp.h" +#include"ldacBT.h" + +typedef struct +{ + uint16_t sequenceNumber; + uint32_t timestamp; + uint32_t frame_samples; + uint16_t curSubSequenceNumber; + uint16_t totalSubSequenceNumber; + uint8_t *buffer; + uint32_t buffer_len; +} a2dp_audio_ldac_decoder_frame_t; + + + +#ifndef LDAC_MTU_LIMITER +#define LDAC_MTU_LIMITER (200) +#endif +#define DECODE_LDAC_PCM_FRAME_LENGTH (256*4*2*2) + +#define LDAC_LIST_SAMPLES (256) + + +static A2DP_AUDIO_CONTEXT_T *a2dp_audio_context_p = NULL; +static A2DP_AUDIO_DECODER_LASTFRAME_INFO_T a2dp_audio_ldac_lastframe_info; + +static uint16_t ldac_mtu_limiter = LDAC_MTU_LIMITER; +//static btif_media_header_t ldac_header_parser_header_prev = {0,}; +//static bool ldac_header_parser_ready = false; +//static bool ldac_chnl_mode_mono = false; + +HANDLE_LDAC_BT LdacDecHandle = NULL; +//static uint8_t *ldac_mempoll = NULL; +heap_handle_t ldac_memhandle = NULL; + +static uint32_t l2cap_frame_samples = LDAC_LIST_SAMPLES; + +/* Convert LDAC Error Code to string */ +#define CASE_RETURN_STR(const) case const: return #const; +static const char * ldac_ErrCode2Str( int ErrCode ) +{ + switch(ErrCode) + { + CASE_RETURN_STR(LDACBT_ERR_NONE); + CASE_RETURN_STR(LDACBT_ERR_NON_FATAL); + CASE_RETURN_STR(LDACBT_ERR_BIT_ALLOCATION); + CASE_RETURN_STR(LDACBT_ERR_NOT_IMPLEMENTED); + CASE_RETURN_STR(LDACBT_ERR_NON_FATAL_ENCODE); + CASE_RETURN_STR(LDACBT_ERR_FATAL); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_BAND); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_GRAD_A); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_GRAD_B); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_GRAD_C); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_GRAD_D); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_GRAD_E); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_IDSF); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_SPEC); + CASE_RETURN_STR(LDACBT_ERR_BIT_PACKING); + CASE_RETURN_STR(LDACBT_ERR_ALLOC_MEMORY); + CASE_RETURN_STR(LDACBT_ERR_FATAL_HANDLE); + CASE_RETURN_STR(LDACBT_ERR_ILL_SYNCWORD); + CASE_RETURN_STR(LDACBT_ERR_ILL_SMPL_FORMAT); + CASE_RETURN_STR(LDACBT_ERR_ILL_PARAM); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_SAMPLING_FREQ); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_SUP_SAMPLING_FREQ); + CASE_RETURN_STR(LDACBT_ERR_CHECK_SAMPLING_FREQ); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_CHANNEL_CONFIG); + CASE_RETURN_STR(LDACBT_ERR_CHECK_CHANNEL_CONFIG); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_FRAME_LENGTH); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_SUP_FRAME_LENGTH); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_FRAME_STATUS); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_NSHIFT); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_CHANNEL_MODE); + CASE_RETURN_STR(LDACBT_ERR_ENC_INIT_ALLOC); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_GRADMODE); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_GRADPAR_A); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_GRADPAR_B); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_GRADPAR_C); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_GRADPAR_D); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_NBANDS); + CASE_RETURN_STR(LDACBT_ERR_PACK_BLOCK_FAILED); + CASE_RETURN_STR(LDACBT_ERR_DEC_INIT_ALLOC); + CASE_RETURN_STR(LDACBT_ERR_INPUT_BUFFER_SIZE); + CASE_RETURN_STR(LDACBT_ERR_UNPACK_BLOCK_FAILED); + CASE_RETURN_STR(LDACBT_ERR_UNPACK_BLOCK_ALIGN); + CASE_RETURN_STR(LDACBT_ERR_UNPACK_FRAME_ALIGN); + CASE_RETURN_STR(LDACBT_ERR_FRAME_LENGTH_OVER); + CASE_RETURN_STR(LDACBT_ERR_FRAME_ALIGN_OVER); + CASE_RETURN_STR(LDACBT_ERR_ALTER_EQMID_LIMITED); + CASE_RETURN_STR(LDACBT_ERR_ILL_EQMID); + CASE_RETURN_STR(LDACBT_ERR_ILL_SAMPLING_FREQ); + CASE_RETURN_STR(LDACBT_ERR_ILL_NUM_CHANNEL); + CASE_RETURN_STR(LDACBT_ERR_ILL_MTU_SIZE); + CASE_RETURN_STR(LDACBT_ERR_HANDLE_NOT_INIT); + default: + return "unknown-error-code"; + } +} + + +char a_ErrorCodeStr[128]; +const char * get_error_code_string( int error_code ) +{ + int errApi, errHdl, errBlk; + + errApi = LDACBT_API_ERR( error_code ); + errHdl = LDACBT_HANDLE_ERR( error_code ); + errBlk = LDACBT_BLOCK_ERR( error_code ); + + a_ErrorCodeStr[0] = '\0'; + strcat( a_ErrorCodeStr, "API:" ); + strcat( a_ErrorCodeStr, ldac_ErrCode2Str( errApi ) ); + strcat( a_ErrorCodeStr, " Handle:" ); + strcat( a_ErrorCodeStr, ldac_ErrCode2Str( errHdl ) ); + strcat( a_ErrorCodeStr, " Block:" ); + strcat( a_ErrorCodeStr, ldac_ErrCode2Str( errBlk ) ); + return a_ErrorCodeStr; +} + + +#define LDAC_FRAME_LEN_INDEX_106 106 +#define LDAC_FRAME_LEN_INDEX_128 128 +#define LDAC_FRAME_LEN_INDEX_160 160 +#define LDAC_FRAME_LEN_INDEX_216 216 +#define LDAC_FRAME_LEN_INDEX_326 326 +#define LDAC_FRAME_LEN_INDEX_161 161 + +static uint8_t get_ldac_frame_num_by_rawdata(uint8_t *buffer, uint32_t buffer_bytes) +{ + uint32_t frame_len = 0; + uint32_t frame_len_with_head = 0; + uint16_t data1 = 0; + uint16_t data2 = 0; + uint8_t frame_cnt = 0; + for(uint32_t i=0; i> 2 & 0xFFFF)); + //TRACE("#frame len:%d",frame_len); + //for ldac head + frame_len_with_head = frame_len + 4; + } + return frame_cnt; +} + +#define LDAC_READBUF_SIZE 1024 /* pick something big enough to hold a bunch of frames */ + + + +/** + * Decode LDAC data... + */ +//#include "os_tcb.h" +extern const char * get_error_code_string( int error_code ); + +#define DCODE_LDAC_PCM_FRAME_LENGTH 10224 *2 + +int check_ldac_header(uint8_t *buffer,uint32_t buff_len) +{ + int channel_mode =0; + int sample_rate=0; + int ret=0; + if(buff_len <2) + ret=-1; + sample_rate=bt_get_ladc_sample_rate(); + channel_mode=bt_ldac_player_get_channelmode(); + //TRACE(3,"%s,%d,%d",__func__,sample_rate,channel_mode); + + uint32_t i=0; + unsigned char sync2 = 0; + unsigned char cci = 0; + + + switch(channel_mode) + { + case LDACBT_CHANNEL_MODE_MONO: + cci = LDAC_CCI_MONO; + break; + case LDACBT_CHANNEL_MODE_DUAL_CHANNEL: + cci = LDAC_CCI_DUAL_CHANNEL; + break; + case LDACBT_CHANNEL_MODE_STEREO: + default: + cci = LDAC_CCI_STEREO; + break; + } + + if(sample_rate == 1*44100) + { + sync2 = (0 << 5) | (cci << 3); + } + else if(sample_rate == 1*48000) + { + sync2 = (1 << 5) | (cci << 3); + } + else if(sample_rate == 2*44100) + { + sync2 = (2 << 5) | (cci << 3); + } + else if(sample_rate == 2*48000) + { + sync2 = (3 << 5) | (cci << 3); + } + else + { + TRACE(0,"sample rate not surpoort !"); + ret=-2; + return ret; + } + + for(i=0; i=buff_len) + { + TRACE(0,"no find ldac header "); + ret=-3; + } + + return ret; +} + +#ifdef A2DP_CP_ACCEL +struct A2DP_CP_LDAC_IN_FRM_INFO_T +{ + uint16_t sequenceNumber; + uint32_t timestamp; + uint16_t curSubSequenceNumber; + uint16_t totalSubSequenceNumber; +}; + +struct A2DP_CP_LDAC_OUT_FRM_INFO_T +{ + struct A2DP_CP_LDAC_IN_FRM_INFO_T in_info; + uint16_t frame_samples; + uint16_t decoded_frames; + uint16_t frame_idx; + uint16_t pcm_len; +}; + +extern "C" uint32_t get_in_cp_frame_cnt(void); +extern "C" unsigned int set_cp_reset_flag(uint8_t evt); +extern uint32_t app_bt_stream_get_dma_buffer_samples(void); + +int a2dp_cp_ldac_cp_decode(void); + +TEXT_LDAC_LOC +static int a2dp_cp_ldac_after_cache_underflow(void) +{ + TRACE(1,"%s", __func__); + int ret = 0; + a2dp_cp_deinit(); + ret = a2dp_cp_init(a2dp_cp_ldac_cp_decode, CP_PROC_DELAY_2_FRAMES); + ASSERT(ret == 0, "%s: a2dp_cp_init() failed: ret=%d", __func__, ret); + + return ret; +} + +static int a2dp_cp_ldac_mcu_decode(uint8_t *buffer, uint32_t buffer_bytes) +{ + a2dp_audio_ldac_decoder_frame_t *ldac_decoder_frame_p = NULL; + list_node_t *node = NULL; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int ret, dec_ret; + struct A2DP_CP_LDAC_IN_FRM_INFO_T in_info; + struct A2DP_CP_LDAC_OUT_FRM_INFO_T *p_out_info; + + uint8_t *out; + uint32_t out_len; + uint32_t out_frame_len; + // uint8_t count=0; + + uint32_t cp_buffer_frames_max = 0; + + if((buffer_bytes < DECODE_LDAC_PCM_FRAME_LENGTH && (LDACBT_CHANNEL_MODE_MONO != bt_ldac_player_get_channelmode())) + || (buffer_bytes < DECODE_LDAC_PCM_FRAME_LENGTH/2 && (LDACBT_CHANNEL_MODE_MONO == bt_ldac_player_get_channelmode()))) + { + TRACE(1,"ldac_decode pcm_len = %d \n", buffer_bytes); + return A2DP_DECODER_NO_ERROR; + } + + if(!LdacDecHandle) + { + TRACE(0,"ldac decode not ready"); + return A2DP_DECODER_NO_ERROR; + } + + cp_buffer_frames_max = app_bt_stream_get_dma_buffer_samples()/2; + + if (cp_buffer_frames_max %(a2dp_audio_ldac_lastframe_info.frame_samples) ) + { + cp_buffer_frames_max = cp_buffer_frames_max /(a2dp_audio_ldac_lastframe_info.frame_samples) +1 ; + } + else + { + cp_buffer_frames_max = cp_buffer_frames_max /(a2dp_audio_ldac_lastframe_info.frame_samples) ; + } + + out_frame_len = sizeof(*p_out_info) + buffer_bytes; + + ret = a2dp_cp_decoder_init(out_frame_len, cp_buffer_frames_max * 8); + + if (ret) + { + TRACE(2,"%s: a2dp_cp_decoder_init() failed: ret=%d", __func__, ret); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + + while ((node = a2dp_audio_list_begin(list)) != NULL) + { + ldac_decoder_frame_p = (a2dp_audio_ldac_decoder_frame_t *)a2dp_audio_list_node(node); + + in_info.sequenceNumber = ldac_decoder_frame_p->sequenceNumber; + in_info.timestamp = ldac_decoder_frame_p->timestamp; + in_info.curSubSequenceNumber = ldac_decoder_frame_p->curSubSequenceNumber; + in_info.totalSubSequenceNumber = ldac_decoder_frame_p->totalSubSequenceNumber; + ret = a2dp_cp_put_in_frame(&in_info, sizeof(in_info), ldac_decoder_frame_p->buffer, ldac_decoder_frame_p->buffer_len); + + if (ret) + { + //TRACE(2,"%s piff !!!!!!ret: %d ",__func__, ret); + break; + } + // count++; + // TRACE(2,"%s count !!!!!!: %d ",__func__,count); + //TRACE(3,"put seq:%d %d %d",in_info.sequenceNumber,in_info.curSubSequenceNumber,in_info.totalSubSequenceNumber); + a2dp_audio_list_remove(list, ldac_decoder_frame_p); + } + + ret = a2dp_cp_get_full_out_frame((void **)&out, &out_len); + + if (ret) + { + TRACE(0,"%s %d cp find cache underflow",__func__, __LINE__); + TRACE(2,"aud_list_len:%d. cp_get_in_frame:%d", a2dp_audio_list_length(list), get_in_cp_frame_cnt()); + a2dp_cp_ldac_after_cache_underflow(); + return A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + + if (out_len == 0) + { + memset(buffer, 0, buffer_bytes); + a2dp_cp_consume_full_out_frame(); + TRACE(1,"%s olz!!!",__func__); + return A2DP_DECODER_NO_ERROR; + } + if (out_len != out_frame_len) + { + TRACE(3,"%s: Bad out len %u (should be %u)", __func__, out_len, out_frame_len); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + p_out_info = (struct A2DP_CP_LDAC_OUT_FRM_INFO_T *)out; + if (p_out_info->pcm_len) + { + a2dp_audio_ldac_lastframe_info.sequenceNumber = p_out_info->in_info.sequenceNumber; + a2dp_audio_ldac_lastframe_info.timestamp = p_out_info->in_info.timestamp; + a2dp_audio_ldac_lastframe_info.curSubSequenceNumber = p_out_info->in_info.curSubSequenceNumber; + a2dp_audio_ldac_lastframe_info.totalSubSequenceNumber = p_out_info->in_info.totalSubSequenceNumber; + a2dp_audio_ldac_lastframe_info.frame_samples = p_out_info->frame_samples; + a2dp_audio_ldac_lastframe_info.decoded_frames += p_out_info->decoded_frames; + a2dp_audio_ldac_lastframe_info.undecode_frames = + a2dp_audio_list_length(list) + a2dp_cp_get_in_frame_cnt_by_index(p_out_info->frame_idx) - 1; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_ldac_lastframe_info); + } + + if (p_out_info->pcm_len == buffer_bytes) + { + memcpy(buffer, p_out_info + 1, p_out_info->pcm_len); + dec_ret = A2DP_DECODER_NO_ERROR; + } + else + { + TRACE(2,"%s %d cp decoder error !!!!!!", __func__, __LINE__); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + + ret = a2dp_cp_consume_full_out_frame(); + if (ret) + { + + TRACE(2,"%s: a2dp_cp_consume_full_out_frame() failed: ret=%d", __func__, ret); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + return dec_ret; +} + +TEXT_LDAC_LOC +int a2dp_cp_ldac_cp_decode(void) +{ + int ret; + enum CP_EMPTY_OUT_FRM_T out_frm_st; + uint8_t *out; + uint32_t out_len; + uint8_t *dec_start; + uint32_t dec_len; + struct A2DP_CP_LDAC_IN_FRM_INFO_T *p_in_info; + struct A2DP_CP_LDAC_OUT_FRM_INFO_T *p_out_info; + uint8_t *in_buf; + uint32_t in_len; + + int32_t dec_sum; + + int used_bytes=0; + int wrote_bytes=0; + + out_frm_st = a2dp_cp_get_emtpy_out_frame((void **)&out, &out_len); + + if (out_frm_st != CP_EMPTY_OUT_FRM_OK && out_frm_st != CP_EMPTY_OUT_FRM_WORKING) + { + return out_frm_st; + } + + ASSERT(out_len > sizeof(*p_out_info), "%s: Bad out_len %u (should > %u)", __func__, out_len, sizeof(*p_out_info)); + + p_out_info = (struct A2DP_CP_LDAC_OUT_FRM_INFO_T *)out; + if (out_frm_st == CP_EMPTY_OUT_FRM_OK) + { + p_out_info->pcm_len = 0; + p_out_info->decoded_frames = 0; + } + + ASSERT(out_len > sizeof(*p_out_info) + p_out_info->pcm_len, "%s: Bad out_len %u (should > %u + %u)", __func__, out_len, sizeof(*p_out_info), p_out_info->pcm_len); + + dec_start = (uint8_t *)(p_out_info + 1) + p_out_info->pcm_len; + dec_len = out_len - (dec_start - (uint8_t *)out); + + dec_sum = 0; + + while (dec_sum < (int32_t)dec_len) + { + ret = a2dp_cp_get_in_frame((void **)&in_buf, &in_len); + + + + if (ret) + { + TRACE(1,"cp_get_int_frame fail, ret=%d", ret); + return 4; + } + + ASSERT(in_len > sizeof(*p_in_info), "%s: Bad in_len %u (should > %u)", __func__, in_len, sizeof(*p_in_info)); + + p_in_info = (struct A2DP_CP_LDAC_IN_FRM_INFO_T *)in_buf; + in_buf += sizeof(*p_in_info); + in_len -= sizeof(*p_in_info); + //TRACE(2,"decode:seq %d %d %d", p_in_info->sequenceNumber, p_in_info->curSubSequenceNumber,p_in_info->totalSubSequenceNumber); + + if(in_buf[0] != 0xaa) + { + TRACE(2,"decode:seq %d %d", p_in_info->sequenceNumber, p_in_info->curSubSequenceNumber); + DUMP8("%x ",in_buf,30); + } + + ret = ldacBT_decode(LdacDecHandle, in_buf, dec_start+dec_sum, LDACBT_SMPL_FMT_S16, in_len, &used_bytes, &wrote_bytes); + //TRACE("%s wb:%d bb:%d pb:%d",__func__,wrote_bytes,dec_len,dec_sum); + dec_sum += wrote_bytes; + if(ret !=0) + { + TRACE(1,"ldac decode error %d",ret); + TRACE(1,"LdacDecHandle error_code:%d",ldacBT_get_error_code(LdacDecHandle)); + ret=A2DP_DECODER_DECODE_ERROR; + return -1; + } + + ret = a2dp_cp_consume_in_frame(); + + if (ret != 0) + { + TRACE(2,"%s: a2dp_cp_consume_in_frame() failed: ret=%d", __func__, ret); + } + ASSERT(ret == 0, "%s: a2dp_cp_consume_in_frame() failed: ret=%d", __func__, ret); + + memcpy(&p_out_info->in_info, p_in_info, sizeof(*p_in_info)); + p_out_info->decoded_frames++; + p_out_info->frame_samples = 256; + p_out_info->frame_idx = a2dp_cp_get_in_frame_index(); + } + + if ( dec_sum != (int32_t)dec_len ) + { + TRACE(2,"error!!! dec_sum:%d != dec_len:%d", dec_sum, dec_len); + ASSERT(0, "%s", __func__); + } + + p_out_info->pcm_len += dec_sum; + + if (out_len <= sizeof(*p_out_info) + p_out_info->pcm_len) + { + ret = a2dp_cp_consume_emtpy_out_frame(); + ASSERT(ret == 0, "%s: a2dp_cp_consume_emtpy_out_frame() failed: ret=%d", __func__, ret); + } + + return 0; +} + +#endif + +int a2dp_audio_ldac_mcu_decode_frame(uint8_t *buffer,uint32_t buffer_bytes) +{ + + list_node_t *node=NULL; + uint8_t *temp_buf_ptr1=NULL; + uint8_t *temp_buf_ptr2=NULL; + uint16_t pcm_output_bytes; + uint32_t lock; + + a2dp_audio_ldac_decoder_frame_t *ldac_decoder_frame_p=NULL; + int used_bytes=0; + int wrote_bytes=0; + bool cache_underflow=false; + int output_count = 0; + int result=0; + + + if((buffer_bytes < DECODE_LDAC_PCM_FRAME_LENGTH && (LDACBT_CHANNEL_MODE_MONO != bt_ldac_player_get_channelmode())) + || (buffer_bytes < DECODE_LDAC_PCM_FRAME_LENGTH/2 && (LDACBT_CHANNEL_MODE_MONO == bt_ldac_player_get_channelmode()))) + { + TRACE(1,"ldac_decode pcm_len = %d \n", buffer_bytes); + return A2DP_DECODER_NO_ERROR; + } + + if(!LdacDecHandle) + { + TRACE(0,"ldac decode not ready"); + return A2DP_DECODER_NO_ERROR; + } + + list_t *list=a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + + + //TRACE("jtx~~"); + + for(pcm_output_bytes=0; pcm_output_bytesbuffer; + temp_buf_ptr2=buffer+wrote_bytes*output_count; + + if(temp_buf_ptr1[0] != 0xaa) + { + TRACE(2,"decode:seq %d %d",ldac_decoder_frame_p->sequenceNumber,ldac_decoder_frame_p->curSubSequenceNumber); + DUMP8("%x ",temp_buf_ptr1,30); + + } + + lock = int_lock(); + result = ldacBT_decode(LdacDecHandle,temp_buf_ptr1,temp_buf_ptr2, LDACBT_SMPL_FMT_S16, ldac_decoder_frame_p->buffer_len, &used_bytes, &wrote_bytes); + output_count++; + int_unlock(lock); + + // TRACE("%s wb:%d bb:%d pb:%d",__func__,wrote_bytes,buffer_bytes,pcm_output_bytes); + + // DUMP8("%x ",temp_buf_ptr2,10); + + + if(result !=0) + { + output_count=0; + TRACE(4,"%s wb:%d bb:%d pb:%d",__func__,wrote_bytes,buffer_bytes,pcm_output_bytes); + TRACE(2,"decode:seq %d %d",ldac_decoder_frame_p->sequenceNumber,ldac_decoder_frame_p->curSubSequenceNumber); + DUMP8("%x ",temp_buf_ptr1,10); + TRACE(1,"ldac decode error %d",result); + result=A2DP_DECODER_DECODE_ERROR; + goto exit; + } + } + a2dp_audio_ldac_lastframe_info.sequenceNumber=ldac_decoder_frame_p->sequenceNumber; + a2dp_audio_ldac_lastframe_info.timestamp=ldac_decoder_frame_p->timestamp; + a2dp_audio_ldac_lastframe_info.curSubSequenceNumber = ldac_decoder_frame_p->curSubSequenceNumber; + a2dp_audio_ldac_lastframe_info.totalSubSequenceNumber = ldac_decoder_frame_p->totalSubSequenceNumber; + a2dp_audio_ldac_lastframe_info.frame_samples =ldac_decoder_frame_p->frame_samples ; + a2dp_audio_ldac_lastframe_info.decoded_frames++; + a2dp_audio_ldac_lastframe_info.undecode_frames = a2dp_audio_list_length(list)-1; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_ldac_lastframe_info); + a2dp_audio_list_remove(list, ldac_decoder_frame_p); + } + +exit: + if(cache_underflow) + { + a2dp_audio_ldac_lastframe_info.undecode_frames = 0; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_ldac_lastframe_info); + result = A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + return result; + +} + +int a2dp_audio_ldac_decode_frame(uint8_t *buffer, uint32_t buffer_bytes) +{ + int ret = 0; + if (bt_ldac_player_get_channelmode() == LDACBT_CHANNEL_MODE_MONO) + { +#ifdef A2DP_CP_ACCEL + ret = a2dp_cp_ldac_mcu_decode(buffer, buffer_bytes / sizeof(int16_t)); +#else + ret = a2dp_audio_ldac_mcu_decode_frame(buffer, buffer_bytes / sizeof(int16_t)); +#endif + int16_t *out_int16 = (int16_t *)buffer; + int16_t wrote_samples = buffer_bytes / sizeof(int16_t); + for (int32_t i = wrote_samples - 1; i >= 0; i--) { + out_int16[2 * i + 1] = out_int16[i]; + out_int16[2 * i] = out_int16[i]; + } + }else +#ifdef A2DP_CP_ACCEL + ret = a2dp_cp_ldac_mcu_decode(buffer, buffer_bytes); +#else + ret = a2dp_audio_ldac_mcu_decode_frame(buffer, buffer_bytes); +#endif + return ret; +} + +int a2dp_audio_ldac_preparse_packet(btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + a2dp_audio_ldac_lastframe_info.sequenceNumber = header->sequenceNumber; + a2dp_audio_ldac_lastframe_info.timestamp = header->timestamp; + a2dp_audio_ldac_lastframe_info.curSubSequenceNumber = 0; + a2dp_audio_ldac_lastframe_info.totalSubSequenceNumber = 0; + a2dp_audio_ldac_lastframe_info.frame_samples = LDAC_LIST_SAMPLES; + a2dp_audio_ldac_lastframe_info.list_samples = LDAC_LIST_SAMPLES; + a2dp_audio_ldac_lastframe_info.decoded_frames = 0; + a2dp_audio_ldac_lastframe_info.undecode_frames = 0; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_ldac_lastframe_info); + + TRACE(4,"%s seq:%d timestamp:%d frame samples:%d", __func__, header->sequenceNumber, header->timestamp, a2dp_audio_ldac_lastframe_info.frame_samples); + + return A2DP_DECODER_NO_ERROR; + +} + + +static void *a2dp_audio_ldac_frame_malloc(uint32_t packet_len) +{ + a2dp_audio_ldac_decoder_frame_t *decoder_frame_p = NULL; + uint8_t *buffer = NULL; + + buffer = (uint8_t *)a2dp_audio_heap_malloc(packet_len); + decoder_frame_p = (a2dp_audio_ldac_decoder_frame_t *)a2dp_audio_heap_malloc(sizeof(a2dp_audio_ldac_decoder_frame_t)); + decoder_frame_p->buffer = buffer; + decoder_frame_p->buffer_len = packet_len; + return (void *)decoder_frame_p; +} + +void a2dp_audio_ldac_free(void *packet) +{ + a2dp_audio_ldac_decoder_frame_t *decoder_frame_p = (a2dp_audio_ldac_decoder_frame_t *)packet; + a2dp_audio_heap_free(decoder_frame_p->buffer); + a2dp_audio_heap_free(decoder_frame_p); +} + +int a2dp_audio_ldac_header_parser(btif_media_header_t *header,uint32_t frame_num) +{ + return 0; +} + + +int a2dp_audio_ldac_store_packet(btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + + int nRet = A2DP_DECODER_NOT_SUPPORT; + int check_header_status=0; + + uint32_t frame_cnt = 0; + uint32_t frame_num = 0; + uint32_t frame_len = 0; + uint32_t frame_len_with_head = 0; + uint16_t data1 = 0; + uint16_t data2 = 0; + + + buffer++; + buffer_bytes--; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + + // TRACE("buffer:%x %x %x %x %x %x %x",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6]); + //TRACE(1,"buffer:%x",buffer[2]); + + data1 = (uint16_t)(buffer[1]&0x07); + data2 = (uint16_t)buffer[2]; + frame_len = ((data1<< 6 &0xFFFF) | (data2 >> 2 & 0xFFFF)); + //TRACE("#frame len:%d",frame_len); + frame_num = get_ldac_frame_num_by_rawdata(buffer, buffer_bytes); + + + if ((a2dp_audio_list_length(list)+frame_num) < ldac_mtu_limiter) + { + for(uint32_t i=0; i> 2 & 0xFFFF)); + //TRACE("#frame len:%d",frame_len); + // frame_num = get_ldac_frame_num(frame_len); + // if (!frame_num) + // { + // TRACE(1,"ERROR LDAC FRAME !!! frame_num:%d", frame_num); + // DUMP8("%02x ", buffer, 4); + // return A2DP_DECODER_DECODE_ERROR; + // } + //for ldac head + frame_len_with_head =frame_len+4; + //TRACE(2,"frame len:%d num:%d %d",frame_len,frame_num,a2dp_audio_list_length(list)); + l2cap_frame_samples=256*frame_num; + + //TRACE("i %d buffer bytes:%d",i,buffer_bytes); + check_header_status=check_ldac_header(buffer+i,frame_len_with_head); + if(!check_header_status) + { + a2dp_audio_ldac_decoder_frame_t *ldac_decoder_frame_p=(a2dp_audio_ldac_decoder_frame_t *)a2dp_audio_ldac_frame_malloc(frame_len_with_head); + + ldac_decoder_frame_p->sequenceNumber=header->sequenceNumber; + ldac_decoder_frame_p->curSubSequenceNumber=frame_cnt; + ldac_decoder_frame_p->totalSubSequenceNumber=frame_num; + ldac_decoder_frame_p->timestamp=header->timestamp; + ldac_decoder_frame_p->buffer_len=frame_len_with_head; + ldac_decoder_frame_p->frame_samples=256; + memcpy(ldac_decoder_frame_p->buffer,buffer+i,frame_len_with_head); + //TRACE(5,"seq:%d len:%d i:%d buffer bytes:%d data:%x",header->sequenceNumber, frame_len,i,buffer_bytes,ldac_decoder_frame_p->buffer[0]); + //TRACE(5,"store seq:%d %d %d",header->sequenceNumber,ldac_decoder_frame_p->curSubSequenceNumber,ldac_decoder_frame_p->totalSubSequenceNumber); + a2dp_audio_list_append(list, ldac_decoder_frame_p); + } + else + { + TRACE(1,"ERROR LDAC FRAME ret:%d",check_header_status); + DUMP8("%02x ",buffer+i, 6); + break; + } + nRet = A2DP_DECODER_NO_ERROR; + + + } + + } + else + { + +#if 0 + a2dp_audio_ldac_decoder_frame_t *ldac_decoder_frame_p = NULL; + do + { + ldac_decoder_frame_p = (a2dp_audio_ldac_decoder_frame_t *)a2dp_audio_list_back(list); + TRACE(3,"remov seq:%d %d %d",ldac_decoder_frame_p->sequenceNumber,ldac_decoder_frame_p->curSubSequenceNumber,ldac_decoder_frame_p->totalSubSequenceNumber); + a2dp_audio_list_remove(list, ldac_decoder_frame_p); + } + while(ldac_decoder_frame_p->curSubSequenceNumber!=0); +#endif + TRACE(3,"%s list full current list_len step1:%d buff_len:%d", __func__, a2dp_audio_list_length(list), buffer_bytes); + nRet = A2DP_DECODER_MTU_LIMTER_ERROR; + + } + + + + + + return nRet; + +} + +int a2dp_audio_ldac_discards_packet(uint32_t packets) +{ + int nRet = A2DP_DECODER_MEMORY_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_ldac_decoder_frame_t *ldac_decoder_frame_p = NULL; +#ifdef A2DP_CP_ACCEL + a2dp_cp_reset_frame(); +#endif + if (packets <= a2dp_audio_list_length(list)) + { + for (uint8_t i=0; iaudio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_ldac_decoder_frame_t *ldac_decoder_frame_p = NULL; + int cnt = 0; + + do + { + + //TRACE(1,"cnt:%d",cnt); + ldac_decoder_frame_p = (a2dp_audio_ldac_decoder_frame_t *)a2dp_audio_ldac_frame_malloc(216+4); + if (ldac_decoder_frame_p) + { + a2dp_audio_list_append(list, ldac_decoder_frame_p); + } + cnt++; + } + while(ldac_decoder_frame_p && cnt < LDAC_MTU_LIMITER); + + do + { + node = a2dp_audio_list_begin(list); + if (node) + { + ldac_decoder_frame_p = (a2dp_audio_ldac_decoder_frame_t *)a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, ldac_decoder_frame_p); + } + } + while(node); + + TRACE(3,"%s cnt:%d list:%d", __func__, cnt, a2dp_audio_list_length(list)); + + + return 0; +} + + + +int a2dp_audio_ldac_init(A2DP_AUDIO_OUTPUT_CONFIG_T *config, void *context) +{ + TRACE(1,"%s", __func__); + a2dp_audio_context_p = (A2DP_AUDIO_CONTEXT_T *)context; + + memset(&a2dp_audio_ldac_lastframe_info, 0, sizeof(A2DP_AUDIO_DECODER_LASTFRAME_INFO_T)); + a2dp_audio_ldac_lastframe_info.stream_info = *config; + a2dp_audio_ldac_lastframe_info.frame_samples= 256; + a2dp_audio_ldac_lastframe_info.list_samples = 256; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_ldac_lastframe_info); + + ASSERT(a2dp_audio_context_p->dest_packet_mut < LDAC_MTU_LIMITER, "%s MTU OVERFLOW:%u/%u", __func__, a2dp_audio_context_p->dest_packet_mut, LDAC_MTU_LIMITER); + +#ifdef A2DP_CP_ACCEL + int ret; + ret = a2dp_cp_init(a2dp_cp_ldac_cp_decode, CP_PROC_DELAY_2_FRAMES); + ASSERT(ret == 0, "%s: a2dp_cp_init() failed: ret=%d", __func__, ret); +#endif + a2dp_audio_ldac_decoder_init(); + a2dp_audio_ldac_list_checker(); + + return A2DP_DECODER_NO_ERROR; +} + + +int a2dp_audio_ldac_deinit(void) +{ + +#ifdef A2DP_CP_ACCEL + a2dp_cp_deinit(); +#endif + a2dp_audio_ldac_decoder_deinit(); + return A2DP_DECODER_NO_ERROR; +} + + + + +int a2dp_audio_ldac_synchronize_packet(A2DP_AUDIO_SYNCFRAME_INFO_T *sync_info,uint32_t mask) +{ + int nRet = A2DP_DECODER_SYNC_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + int list_len; + a2dp_audio_ldac_decoder_frame_t *ldac_decoder_frame_p = NULL; + + list_len = a2dp_audio_list_length(list); + + for (uint16_t i=0; isequenceNumber == sync_info->sequenceNumber, A2DP_AUDIO_SYNCFRAME_MASK_SEQ, mask)&& + // A2DP_AUDIO_SYNCFRAME_CHK(ldac_decoder_frame_p->timestamp == sync_info->timestamp, A2DP_AUDIO_SYNCFRAME_MASK_TIMESTAMP, mask)) + + if(A2DP_AUDIO_SYNCFRAME_CHK(ldac_decoder_frame_p->sequenceNumber == sync_info->sequenceNumber, A2DP_AUDIO_SYNCFRAME_MASK_SEQ, mask)&& + A2DP_AUDIO_SYNCFRAME_CHK(ldac_decoder_frame_p->curSubSequenceNumber == sync_info->curSubSequenceNumber, A2DP_AUDIO_SYNCFRAME_MASK_CURRSUBSEQ, mask)&& + A2DP_AUDIO_SYNCFRAME_CHK(ldac_decoder_frame_p->totalSubSequenceNumber == sync_info->totalSubSequenceNumber,A2DP_AUDIO_SYNCFRAME_MASK_TOTALSUBSEQ,mask)) + { + nRet = A2DP_DECODER_NO_ERROR; + break; + } + a2dp_audio_list_remove(list, ldac_decoder_frame_p); + } + + node = a2dp_audio_list_begin(list); + if (node) + { + ldac_decoder_frame_p = (a2dp_audio_ldac_decoder_frame_t *)a2dp_audio_list_node(node); + TRACE(4,"%s nRet:%d SEQ:%d timestamp:%d", __func__, nRet, ldac_decoder_frame_p->sequenceNumber, ldac_decoder_frame_p->timestamp); + } + else + { + TRACE(2,"%s nRet:%d", __func__, nRet); + // TRACE(5,"nRet:%d SEQ:%d timestamp:%d sync %d/%d", nRet, ldac_decoder_frame_p->sequenceNumber, ldac_decoder_frame_p->timestamp,sync_info->sequenceNumber,sync_info->timestamp); + } + + return nRet; + +} + +int a2dp_audio_ldac_synchronize_dest_packet_mut(uint16_t packet_mut) +{ + list_node_t *node = NULL; + uint32_t list_len = 0; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_ldac_decoder_frame_t *ldac_decoder_frame_p = NULL; + + list_len = a2dp_audio_list_length(list); + if (list_len > packet_mut) + { + do + { + node = a2dp_audio_list_begin(list); + ldac_decoder_frame_p = (a2dp_audio_ldac_decoder_frame_t *)a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, ldac_decoder_frame_p); + } + while(a2dp_audio_list_length(list) > packet_mut); + } + + TRACE(2,"%s list:%d", __func__, a2dp_audio_list_length(list)); + return A2DP_DECODER_NO_ERROR; + +} + +static int a2dp_audio_ldac_headframe_info_get(A2DP_AUDIO_HEADFRAME_INFO_T* headframe_info) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_ldac_decoder_frame_t *decoder_frame_p = NULL; + + if (a2dp_audio_list_length(list)) + { + node = a2dp_audio_list_begin(list); + decoder_frame_p = (a2dp_audio_ldac_decoder_frame_t *)a2dp_audio_list_node(node); + headframe_info->sequenceNumber = decoder_frame_p->sequenceNumber; + headframe_info->timestamp = decoder_frame_p->timestamp; + headframe_info->curSubSequenceNumber = decoder_frame_p->curSubSequenceNumber; + headframe_info->totalSubSequenceNumber = decoder_frame_p->totalSubSequenceNumber; + } + else + { + memset(headframe_info, 0, sizeof(A2DP_AUDIO_HEADFRAME_INFO_T)); + } + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_ldac_convert_list_to_samples(uint32_t *samples) +{ + uint32_t list_len = 0; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + + list_len = a2dp_audio_list_length(list); + *samples = LDAC_LIST_SAMPLES*list_len; + + TRACE(3, "%s list:%d samples:%d", __func__, list_len, *samples); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_ldac_discards_samples(uint32_t samples) +{ + int nRet = A2DP_DECODER_SYNC_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_ldac_decoder_frame_t *ldac_decoder_frame = NULL; + list_node_t *node = NULL; + int need_remove_list = 0; + uint32_t list_samples = 0; + ASSERT(!(samples%LDAC_LIST_SAMPLES), "%s samples err:%d", __func__, samples); + + a2dp_audio_ldac_convert_list_to_samples(&list_samples); + if (list_samples >= samples) + { + need_remove_list = samples/LDAC_LIST_SAMPLES; + for (int i=0; isequenceNumber,ldac_decoder_frame->curSubSequenceNumber,ldac_decoder_frame->totalSubSequenceNumber); + a2dp_audio_list_remove(list, ldac_decoder_frame); + } + nRet = A2DP_DECODER_NO_ERROR; + } + + return nRet; +} + + +A2DP_AUDIO_DECODER_T a2dp_audio_ldac_decoder_config = +{ + {96000, 2, 16}, + 0, + a2dp_audio_ldac_init, + a2dp_audio_ldac_deinit, + a2dp_audio_ldac_decode_frame, + a2dp_audio_ldac_preparse_packet, + a2dp_audio_ldac_store_packet, + a2dp_audio_ldac_discards_packet, + a2dp_audio_ldac_synchronize_packet, + a2dp_audio_ldac_synchronize_dest_packet_mut, + a2dp_audio_ldac_convert_list_to_samples, + a2dp_audio_ldac_discards_samples, + a2dp_audio_ldac_headframe_info_get, + a2dp_audio_ldac_info_get, + a2dp_audio_ldac_free, +}; + diff --git a/apps/audioplayers/a2dp_decoder/a2dp_decoder_lhdc.cpp b/apps/audioplayers/a2dp_decoder/a2dp_decoder_lhdc.cpp new file mode 100644 index 0000000..7b50ef1 --- /dev/null +++ b/apps/audioplayers/a2dp_decoder/a2dp_decoder_lhdc.cpp @@ -0,0 +1,1249 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Standard C Included Files +#include "cmsis.h" +#include "plat_types.h" +#include +#include "heap_api.h" +#include "hal_location.h" +#include "hal_timer.h" +#include "a2dp_decoder_internal.h" + +typedef struct +{ + uint16_t sequenceNumber; + uint32_t timestamp; + uint16_t curSubSequenceNumber; + uint16_t totalSubSequenceNumber; + uint8_t *buffer; + uint32_t buffer_len; +} a2dp_audio_lhdc_decoder_frame_t; + +#define LHDC_MTU_LIMITER (100) + +#if defined(A2DP_LHDC_V3) +#define A2DP_LHDC_OUTPUT_FRAME_SAMPLES (256) +#else +#define A2DP_LHDC_OUTPUT_FRAME_SAMPLES (512) +#endif + +#define A2DP_LHDC_DEFAULT_LATENCY (1) +#if defined(A2DP_LHDC_V3) +#define PACKET_BUFFER_LENGTH (2 * 1024) +#else +#define PACKET_BUFFER_LENGTH (4 * 1024) +#endif + +#define LHDC_READBUF_SIZE (512) + +#define A2DP_LHDC_HDR_F_MSK 0x80 +#define A2DP_LHDC_HDR_S_MSK 0x40 +#define A2DP_LHDC_HDR_L_MSK 0x20 +#define A2DP_LHDC_HDR_FLAG_MSK (A2DP_LHDC_HDR_F_MSK | A2DP_LHDC_HDR_S_MSK | A2DP_LHDC_HDR_L_MSK) + +#define A2DP_LHDC_HDR_LATENCY_LOW 0x00 +#define A2DP_LHDC_HDR_LATENCY_MID 0x01 +#define A2DP_LHDC_HDR_LATENCY_HIGH 0x02 +#define A2DP_LHDC_HDR_LATENCY_MASK (A2DP_LHDC_HDR_LATENCY_MID | A2DP_LHDC_HDR_LATENCY_HIGH) + +#if defined(A2DP_LHDC_V3) +#define A2DP_LHDC_HDR_FRAME_NO_MASK 0xfc +#else +#define A2DP_LHDC_HDR_FRAME_NO_MASK 0x1c +#endif + +typedef enum +{ + ASM_PKT_WAT_STR, + ASM_PKT_WAT_LST, +} ASM_PKT_STATUS; + +typedef enum +{ + VERSION_2 = 200, + VERSION_3 = 300 +} lhdc_ver_t; + +/** + * get lhdc frame header + */ + +/** + LHDC frame +*/ +typedef struct _lhdc_frame_Info +{ + uint32_t frame_len; // 该 frame 的长处,若是分离压缩,则表示å•ä¸€å£°é“çš„ frame 长度。 + uint32_t isSplit; // 是å¦ä¸ºåˆ†ç¦»æ–¹å¼åŽ‹ç¼© + uint32_t isLeft; // å·¦å£°é“ == true, å³å£°é“ == false + +} lhdc_frame_Info_t; + +#ifdef A2DP_CP_ACCEL +struct A2DP_CP_LHDC_IN_FRM_INFO_T +{ + uint16_t sequenceNumber; + uint32_t timestamp; + uint16_t curSubSequenceNumber; + uint16_t totalSubSequenceNumber; +}; + +struct A2DP_CP_LHDC_OUT_FRM_INFO_T +{ + struct A2DP_CP_LHDC_IN_FRM_INFO_T in_info; + uint16_t frame_samples; + uint16_t decoded_frames; + uint16_t frame_idx; + uint16_t pcm_len; +}; +#endif + +extern "C" +{ + typedef struct bes_bt_local_info_t + { + uint8_t bt_addr[BTIF_BD_ADDR_SIZE]; + const char *bt_name; + uint8_t bt_len; + uint8_t ble_addr[BTIF_BD_ADDR_SIZE]; + const char *ble_name; + uint8_t ble_len; + } bes_bt_local_info; + + typedef int (*LHDC_GET_BT_INFO)(bes_bt_local_info *bt_info); + + void lhdcInit(uint32_t bitPerSample, uint32_t sampleRate, uint32_t scaleTo16Bits, lhdc_ver_t version); + //void lhdcInit(uint32_t bitPerSample, uint32_t sampleRate, uint32_t scaleTo16Bits); +#if defined(A2DP_LHDC_V3) + uint32_t lhdcPutData(uint8_t *pIn, uint32_t len); +#else + uint32_t lhdcPutData(uint8_t *pIn, int32_t len); +#endif + uint32_t lhdcDecodeProcess(uint8_t *pOutBuf); + void lhdcDestroy(); + bool lhdcSetLicenseKeyTable(uint8_t *licTable, LHDC_GET_BT_INFO pFunc); + const char *getVersionCode(); + bool larcIsEnabled(); +} + +static A2DP_AUDIO_CONTEXT_T *a2dp_audio_context_p = NULL; +static A2DP_AUDIO_DECODER_LASTFRAME_INFO_T a2dp_audio_lhdc_lastframe_info; +static A2DP_AUDIO_OUTPUT_CONFIG_T a2dp_audio_lhdc_output_config; +static uint16_t lhdc_mtu_limiter = LHDC_MTU_LIMITER; + +static uint8_t serial_no; +static bool is_synced; +static ASM_PKT_STATUS asm_pkt_st; +static uint8_t packet_buffer[PACKET_BUFFER_LENGTH]; +static uint32_t packet_buf_len = 0; +static uint32_t lhdc_total_frame_nb = 0; + +#if defined(A2DP_LHDC_LARC) +static uint32_t lhdc_drop_frame = 0; +static uint32_t lhdc_last_time = 0; +static struct A2DP_CP_LHDC_IN_FRM_INFO_T last_frame_info; +//static uint16_t demo_frame_cnt = 0; +#endif + + +extern int bes_bt_local_info_get(bes_bt_local_info *local_info); + +//Local API declare +void sav_lhdc_log_bytes_len(uint32_t bytes_len); + +#define STATISTICS_UPDATE_INTERVAL 1000 // in ms +#define INTERVAL_TIMEBASE 1000 //in ms +typedef struct +{ + uint32_t sum_bytes; + uint32_t last_times; //in ms + float last_avg_val; + int32_t update_interval; //in ms +} LHDC_TRACFIC_STATISTICS; + +LHDC_TRACFIC_STATISTICS statistic = {0, 0, 0, STATISTICS_UPDATE_INTERVAL}; + +void sav_lhdc_log_bytes_len(uint32_t bytes_len) +{ + uint32_t time_current = GET_CURRENT_MS(); + float time_diff = time_current - statistic.last_times; + statistic.sum_bytes += bytes_len; + if (time_diff >= statistic.update_interval) + { + + statistic.last_avg_val = ((float)(statistic.sum_bytes * 8) / 1000) / (time_diff / INTERVAL_TIMEBASE); + TRACE_A2DP_DECODER_I("Avarage rate about %d kbps", (int)statistic.last_avg_val); + + statistic.sum_bytes = 0; + statistic.last_times = time_current; + } +} + +#if defined(A2DP_LHDC_LARC) && defined(A2DP_LHDC_V3) +static void sav_lhdc_save_last_info(struct A2DP_CP_LHDC_IN_FRM_INFO_T *f_info) +{ + + memcpy(&last_frame_info, f_info, sizeof(struct A2DP_CP_LHDC_IN_FRM_INFO_T)); +} + +static void sav_lhdc_get_next_info(struct A2DP_CP_LHDC_IN_FRM_INFO_T *f_info) +{ + f_info->timestamp = last_frame_info.timestamp; + f_info->sequenceNumber = last_frame_info.sequenceNumber; + f_info->totalSubSequenceNumber = last_frame_info.totalSubSequenceNumber; + f_info->curSubSequenceNumber = last_frame_info.curSubSequenceNumber + 1; + if (f_info->curSubSequenceNumber > last_frame_info.totalSubSequenceNumber) + { + f_info->curSubSequenceNumber = 1; + f_info->timestamp = last_frame_info.timestamp + (A2DP_LHDC_OUTPUT_FRAME_SAMPLES * last_frame_info.totalSubSequenceNumber); + f_info->sequenceNumber = last_frame_info.sequenceNumber + 1; + } +} +#endif + +static void *a2dp_audio_lhdc_frame_malloc(uint32_t packet_len) +{ + a2dp_audio_lhdc_decoder_frame_t *decoder_frame_p = NULL; + uint8_t *buffer = NULL; + + buffer = (uint8_t *)a2dp_audio_heap_malloc(packet_len); + decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_heap_malloc(sizeof(a2dp_audio_lhdc_decoder_frame_t)); + decoder_frame_p->buffer = buffer; + decoder_frame_p->buffer_len = packet_len; + return (void *)decoder_frame_p; +} + +static void reset_lhdc_assmeble_packet(void) +{ + is_synced = false; + asm_pkt_st = ASM_PKT_WAT_STR; + packet_buf_len = 0; +} + +static void initial_lhdc_assemble_packet(bool splitFlg) +{ + memset(packet_buffer, 0, PACKET_BUFFER_LENGTH); + reset_lhdc_assmeble_packet(); + serial_no = 0xff; +} + +/** + * A2DP packet 组包 + */ +#if defined(A2DP_LHDC_V3) +int assemble_lhdc_packet(uint8_t *input, uint32_t input_len, uint8_t **pLout, uint32_t *pLlen) +{ + uint8_t hdr = 0, seqno = 0xff; + int ret = -1; + uint32_t status = 0; + + hdr = (*input); + input++; + seqno = (*input); + input++; + input_len -= 2; + + //Check latency and update value when changed. + status = hdr & A2DP_LHDC_HDR_LATENCY_MASK; + + //Get number of frame in packet. + status = (hdr & A2DP_LHDC_HDR_FRAME_NO_MASK) >> 2; + if (status <= 0) + { + TRACE_A2DP_DECODER_I("No any frame in packet."); + return 0; + } + lhdc_total_frame_nb = status; + if (seqno != serial_no) + { + TRACE_A2DP_DECODER_I("Packet lost! now(%d), expect(%d)", seqno, serial_no); + } + serial_no = seqno + 1; + + sav_lhdc_log_bytes_len(input_len); + + if (pLlen && pLout) + { + *pLlen = input_len; + *pLout = input; + } + ret = lhdc_total_frame_nb; + + return ret; +} +#else +int assemble_lhdc_packet(uint8_t *input, uint32_t input_len, uint8_t **pLout, uint32_t *pLlen) +{ + uint8_t hdr = 0, seqno = 0xff; + int ret = -1; + //uint32_t status = 0; + + hdr = (*input); + input++; + seqno = (*input); + input++; + input_len -= 2; + + if (is_synced) + { + if (seqno != serial_no) + { + reset_lhdc_assmeble_packet(); + if ((hdr & A2DP_LHDC_HDR_FLAG_MSK) == 0 || + (hdr & A2DP_LHDC_HDR_S_MSK) != 0) + { + goto lhdc_start; + } + else + TRACE_A2DP_DECODER_I("drop packet No. %u", seqno); + return 0; + } + serial_no = seqno + 1; + } + +lhdc_start: + switch (asm_pkt_st) + { + case ASM_PKT_WAT_STR: + { + if ((hdr & A2DP_LHDC_HDR_FLAG_MSK) == 0) + { + memcpy(&packet_buffer[0], input, input_len); + if (pLlen && pLout) + { + *pLlen = input_len; + *pLout = packet_buffer; + } + //TRACE_A2DP_DECODER_I("Single payload size = %d", *pLlen); + asm_pkt_st = ASM_PKT_WAT_STR; + packet_buf_len = 0; //= packet_buf_left_len = packet_buf_right_len = 0; + lhdc_total_frame_nb = (hdr & A2DP_LHDC_HDR_FRAME_NO_MASK) >> 2; + ; + //TRACE_A2DP_DECODER_I("Single packet. total %d frames", lhdc_total_frame_nb); + ret = lhdc_total_frame_nb; + } + else if (hdr & A2DP_LHDC_HDR_S_MSK) + { + ret = 0; + if (packet_buf_len + input_len >= PACKET_BUFFER_LENGTH) + { + packet_buf_len = 0; + asm_pkt_st = ASM_PKT_WAT_STR; + TRACE_A2DP_DECODER_I("ASM_PKT_WAT_STR:Frame buffer overflow!(%d)", packet_buf_len); + break; + } + memcpy(&packet_buffer, input, input_len); + packet_buf_len = input_len; + asm_pkt_st = ASM_PKT_WAT_LST; + lhdc_total_frame_nb = (hdr & A2DP_LHDC_HDR_FRAME_NO_MASK) >> 2; + //TRACE_A2DP_DECODER_I("start of multi packet."); + } + else + ret = -1; + + if (ret >= 0) + { + if (!is_synced) + { + is_synced = true; + serial_no = seqno + 1; + } + } + break; + } + case ASM_PKT_WAT_LST: + { + if (packet_buf_len + input_len >= PACKET_BUFFER_LENGTH) + { + packet_buf_len = 0; + asm_pkt_st = ASM_PKT_WAT_STR; + TRACE_A2DP_DECODER_I("ASM_PKT_WAT_LST:Frame buffer overflow(%d)", packet_buf_len); + break; + } + memcpy(&packet_buffer[packet_buf_len], input, input_len); + //TRACE_A2DP_DECODER_I("multi:payload size = %d", input_len); + packet_buf_len += input_len; + ret = 0; + + if (hdr & A2DP_LHDC_HDR_L_MSK) + { + + if (pLlen && pLout) + { + *pLlen = packet_buf_len; + *pLout = packet_buffer; + } + //TRACE_A2DP_DECODER_I("end of multi packet. total %d frames.", lhdc_total_frame_nb); + packet_buf_len = 0; //packet_buf_left_len = packet_buf_right_len = 0; + ret = lhdc_total_frame_nb; + asm_pkt_st = ASM_PKT_WAT_STR; + } + break; + } + default: + ret = 0; + break; + } + return ret; +} +#endif + +static int parse_lhdc_info(uint8_t *in, lhdc_frame_Info_t *h) +{ +#define LHDC_HDR_LEN 4 + uint32_t hdr = 0; + int ret = -1; + memcpy(&hdr, in, LHDC_HDR_LEN); + h->frame_len = (int)((hdr >> 8) & 0x1fff); + h->isSplit = ((hdr & 0x00600000) == 0x00600000); + h->isLeft = ((hdr & 0xf) == 0); + + if ((hdr & 0xff000000) != 0x4c000000) + { + } + else + { + ret = 0; + } + return ret; +} + +#ifdef A2DP_CP_ACCEL + +extern "C" uint32_t get_in_cp_frame_cnt(void); +extern "C" unsigned int set_cp_reset_flag(uint8_t evt); +extern uint32_t app_bt_stream_get_dma_buffer_samples(void); + +int a2dp_cp_lhdc_cp_decode(void); + +TEXT_LHDC_LOC +static int a2dp_cp_lhdc_after_cache_underflow(void) +{ + int ret = 0; +#ifdef A2DP_CP_ACCEL + a2dp_cp_deinit(); + lhdcDestroy(); + ret = a2dp_cp_init(a2dp_cp_lhdc_cp_decode, CP_PROC_DELAY_2_FRAMES); + ASSERT(ret == 0, "%s: a2dp_cp_init() failed: ret=%d", __func__, ret); +#endif + return ret; +} + +//uint32_t demoTimer = 0; +static int a2dp_cp_lhdc_mcu_decode(uint8_t *buffer, uint32_t buffer_bytes) +{ + a2dp_audio_lhdc_decoder_frame_t *lhdc_decoder_frame_p = NULL; + list_node_t *node = NULL; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int ret, dec_ret; + struct A2DP_CP_LHDC_IN_FRM_INFO_T in_info; + struct A2DP_CP_LHDC_OUT_FRM_INFO_T *p_out_info; + + uint8_t *out; + uint32_t out_len; + uint32_t out_frame_len; + uint32_t cp_buffer_frames_max = 0; + +#if defined(A2DP_LHDC_LARC) + //bool forceRecovery = false; + bool larcEnabled = larcIsEnabled(); + uint32_t frame_number = 0; + + if (larcEnabled) + { + /* The LARC is enabled. */ + + uint32_t time_diff = 0, time_now = GET_CURRENT_MS(); + + if (lhdc_last_time == 0) + { + lhdc_last_time = time_now; + } + // if (demoTimer == 0) { + // demoTimer = time_now; + // } + time_diff = time_now - lhdc_last_time; + lhdc_last_time = time_now; + + frame_number = (uint32_t)((float)time_diff / ((A2DP_LHDC_OUTPUT_FRAME_SAMPLES * 1000) / a2dp_audio_lhdc_output_config.sample_rate)); + + TRACE_A2DP_DECODER_I("%s:current total list len %d, need frames %d", __func__, a2dp_audio_list_length(list) + get_in_cp_frame_cnt(), frame_number); + // if (time_now - demoTimer >= (5 * 1000)) { + // forceRecovery = true; + // demoTimer = time_now; + // demo_frame_cnt = (a2dp_audio_lhdc_output_config.sample_rate * 120) / (A2DP_LHDC_OUTPUT_FRAME_SAMPLES * 1000); + // } + } +#endif + + cp_buffer_frames_max = app_bt_stream_get_dma_buffer_samples() / 2; + + if (cp_buffer_frames_max % (a2dp_audio_lhdc_lastframe_info.frame_samples)) + { + cp_buffer_frames_max = cp_buffer_frames_max / (a2dp_audio_lhdc_lastframe_info.frame_samples) + 1; + } + else + { + cp_buffer_frames_max = cp_buffer_frames_max / (a2dp_audio_lhdc_lastframe_info.frame_samples); + } + + out_frame_len = sizeof(*p_out_info) + buffer_bytes; + + ret = a2dp_cp_decoder_init(out_frame_len, cp_buffer_frames_max * 8); + if (ret) + { + TRACE_A2DP_DECODER_I("%s: a2dp_cp_decoder_init() failed: ret=%d", __func__, ret); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + +#if defined(A2DP_LHDC_LARC) + uint32_t put_cnt = 0; + uint32_t drop_cnt = 0; + while (larcEnabled && + ((a2dp_audio_list_length(list) < frame_number && get_in_cp_frame_cnt() == 0))) + { + sav_lhdc_get_next_info(&in_info); + ret = a2dp_cp_put_in_frame(&in_info, sizeof(in_info), NULL, 0x55); + if (ret) + { + //TRACE_A2DP_DECODER_I("%s piff !!!!!!ret: %d ",__func__, ret); + break; + } + sav_lhdc_save_last_info(&in_info); + lhdc_drop_frame++; + frame_number--; + //demo_frame_cnt--; + put_cnt++; + } + //forceRecovery = false; + TRACE_A2DP_DECODER_I("Recover %d frames", put_cnt); + put_cnt = 0; + drop_cnt = 0; +#endif + while ((node = a2dp_audio_list_begin(list)) != NULL) + { + lhdc_decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_list_node(node); + in_info.sequenceNumber = lhdc_decoder_frame_p->sequenceNumber; + in_info.timestamp = lhdc_decoder_frame_p->timestamp; + in_info.curSubSequenceNumber = lhdc_decoder_frame_p->curSubSequenceNumber; + in_info.totalSubSequenceNumber = lhdc_decoder_frame_p->totalSubSequenceNumber; + +#if defined(A2DP_LHDC_LARC) + if (!lhdc_drop_frame) + { + ret = a2dp_cp_put_in_frame(&in_info, sizeof(in_info), lhdc_decoder_frame_p->buffer, lhdc_decoder_frame_p->buffer_len); + if (ret) + { + //TRACE_A2DP_DECODER_I("%s piff !!!!!!ret: %d ",__func__, ret); + break; + } + sav_lhdc_save_last_info(&in_info); + put_cnt++; + } + else + { + lhdc_drop_frame--; + drop_cnt++; + } +#else + ret = a2dp_cp_put_in_frame(&in_info, sizeof(in_info), lhdc_decoder_frame_p->buffer, lhdc_decoder_frame_p->buffer_len); + if (ret) + { + //TRACE_A2DP_DECODER_I("%s piff !!!!!!ret: %d ",__func__, ret); + break; + } +#endif + a2dp_audio_list_remove(list, lhdc_decoder_frame_p); + node = a2dp_audio_list_begin(list); + } +#if defined(A2DP_LHDC_LARC) + TRACE_A2DP_DECODER_I("Put %d frames, drop %d frames", put_cnt, drop_cnt); +#endif + + ret = a2dp_cp_get_full_out_frame((void **)&out, &out_len); + + if (ret) + { + TRACE_A2DP_DECODER_I("%s %d cp find cache underflow", __func__, ret); + TRACE_A2DP_DECODER_I("aud_list_len:%d. cp_get_in_frame:%d", a2dp_audio_list_length(list), get_in_cp_frame_cnt()); + a2dp_cp_lhdc_after_cache_underflow(); + return A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + + if (out_len == 0) + { + memset(buffer, 0, buffer_bytes); + a2dp_cp_consume_full_out_frame(); + TRACE_A2DP_DECODER_I("%s olz!!!%d ", __func__, __LINE__); + return A2DP_DECODER_NO_ERROR; + } + if (out_len != out_frame_len) + { + TRACE_A2DP_DECODER_I("%s: Bad out len %u (should be %u)", __func__, out_len, out_frame_len); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + p_out_info = (struct A2DP_CP_LHDC_OUT_FRM_INFO_T *)out; + if (p_out_info->pcm_len) + { + a2dp_audio_lhdc_lastframe_info.sequenceNumber = p_out_info->in_info.sequenceNumber; + a2dp_audio_lhdc_lastframe_info.timestamp = p_out_info->in_info.timestamp; + a2dp_audio_lhdc_lastframe_info.curSubSequenceNumber = p_out_info->in_info.curSubSequenceNumber; + a2dp_audio_lhdc_lastframe_info.totalSubSequenceNumber = p_out_info->in_info.totalSubSequenceNumber; + a2dp_audio_lhdc_lastframe_info.frame_samples = p_out_info->frame_samples; + a2dp_audio_lhdc_lastframe_info.decoded_frames += p_out_info->decoded_frames; + a2dp_audio_lhdc_lastframe_info.undecode_frames = + a2dp_audio_list_length(list) + a2dp_cp_get_in_frame_cnt_by_index(p_out_info->frame_idx) - 1; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_lhdc_lastframe_info); + + TRACE_A2DP_DECODER_I("lhdc_decoder seq:%d cursub:%d ttlsub:%d decoded:%d/%d", + a2dp_audio_lhdc_lastframe_info.sequenceNumber, + a2dp_audio_lhdc_lastframe_info.curSubSequenceNumber, + a2dp_audio_lhdc_lastframe_info.totalSubSequenceNumber, + a2dp_audio_lhdc_lastframe_info.decoded_frames, + a2dp_audio_lhdc_lastframe_info.undecode_frames); + } + + if (p_out_info->pcm_len == buffer_bytes) + { + memcpy(buffer, p_out_info + 1, p_out_info->pcm_len); + dec_ret = A2DP_DECODER_NO_ERROR; + } + else + { + TRACE_A2DP_DECODER_I("%s %d cp decoder error !!!!!!", __func__, __LINE__); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + + ret = a2dp_cp_consume_full_out_frame(); + if (ret) + { + + TRACE_A2DP_DECODER_I("%s: a2dp_cp_consume_full_out_frame() failed: ret=%d", __func__, ret); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + return dec_ret; +} + +#ifdef __CP_EXCEPTION_TEST__ +static bool _cp_assert = false; +int cp_assert(void) +{ + _cp_assert = true; + return 0; +} +#endif + +#define LHDC_DECODED_FRAME_SIZE 1024 + +TEXT_LHDC_LOC +int a2dp_cp_lhdc_cp_decode(void) +{ + int ret; + enum CP_EMPTY_OUT_FRM_T out_frm_st; + uint8_t *out; + uint32_t out_len; + uint8_t *dec_start; + uint32_t dec_len; + struct A2DP_CP_LHDC_IN_FRM_INFO_T *p_in_info; + struct A2DP_CP_LHDC_OUT_FRM_INFO_T *p_out_info; + uint8_t *in_buf; + uint32_t in_len; + + int32_t dec_sum; + uint32_t lhdc_out_len = 0; + +#ifdef __CP_EXCEPTION_TEST__ + if (_cp_assert) + { + _cp_assert = false; + *(int *)0 = 1; + //ASSERT(0, "ASSERT %s %d", __func__, __LINE__); + } +#endif + out_frm_st = a2dp_cp_get_emtpy_out_frame((void **)&out, &out_len); + + if (out_frm_st != CP_EMPTY_OUT_FRM_OK && out_frm_st != CP_EMPTY_OUT_FRM_WORKING) + { + return out_frm_st; + } + ASSERT(out_len > sizeof(*p_out_info), "%s: Bad out_len %u (should > %u)", __func__, out_len, sizeof(*p_out_info)); + + p_out_info = (struct A2DP_CP_LHDC_OUT_FRM_INFO_T *)out; + if (out_frm_st == CP_EMPTY_OUT_FRM_OK) + { + p_out_info->pcm_len = 0; + p_out_info->decoded_frames = 0; + } + + ASSERT(out_len > sizeof(*p_out_info) + p_out_info->pcm_len, "%s: Bad out_len %u (should > %u + %u)", __func__, out_len, sizeof(*p_out_info), p_out_info->pcm_len); + + dec_start = (uint8_t *)(p_out_info + 1) + p_out_info->pcm_len; + dec_len = out_len - (dec_start - (uint8_t *)out); + + dec_sum = 0; + + while (dec_sum < (int32_t)dec_len) + { + uint32_t lhdc_decode_temp = 0; + + ret = a2dp_cp_get_in_frame((void **)&in_buf, &in_len); + + if (ret) + { + TRACE_A2DP_DECODER_I("cp_get_int_frame fail, ret=%d", ret); + return 4; + } + + ASSERT(in_len > sizeof(*p_in_info), "%s: Bad in_len %u (should > %u)", __func__, in_len, sizeof(*p_in_info)); + + p_in_info = (struct A2DP_CP_LHDC_IN_FRM_INFO_T *)in_buf; + in_buf += sizeof(*p_in_info); + in_len -= sizeof(*p_in_info); + +#if defined(A2DP_LHDC_V3) +#if defined(A2DP_LHDC_LARC) + if (in_len == 0x55 && larcIsEnabled()) + { + //TRACE_A2DP_DECODER_I("recover:sn(%d), tt(%d), csssn(%d), ttsssn(%d)", p_in_info->sequenceNumber, p_in_info->timestamp, p_in_info->curSubSequenceNumber, p_in_info->totalSubSequenceNumber); + in_len = 0; + } +#endif + lhdcPutData(in_buf, in_len); + //TRACE_A2DP_DECODER_I("%s:put length=%d, dec_len=%d", __func__, in_len, dec_len); +#else + lhdcPutData(in_buf, in_len); +#endif + uint32_t loop_cnt = 0; + do + { + //TRACE_A2DP_DECODER_I("loop %d , dec_start %p, dec_sum %d, lhdc_decode_temp %d", loop_cnt, dec_start, dec_sum, lhdc_decode_temp); + lhdc_out_len = lhdcDecodeProcess(dec_start + dec_sum + lhdc_decode_temp); + if (lhdc_out_len > 0) + { + lhdc_decode_temp += lhdc_out_len; + loop_cnt++; + } + else + { + //TRACE_A2DP_DECODER_I("decodeProcess error!!! ret=%d", lhdc_out_len); + break; + } + } while (lhdc_decode_temp < dec_len && lhdc_decode_temp > 0); + + //TRACE_A2DP_DECODER_I("lhdc_cp_decode seq:%d len:%d err:%d", p_in_info->sequenceNumber, + // dec_len - dec_sum, + // lhdc_out_len); + + //TRACE_A2DP_DECODER_I("%s:decode loop run times=%d, lhdc_decode_temp=%d", __func__, loop_cnt, lhdc_decode_temp); + dec_sum += lhdc_decode_temp; + + if ((lhdc_decode_temp % LHDC_DECODED_FRAME_SIZE)) + { + TRACE_A2DP_DECODER_I("error!!! dec_sum: %d decode_temp: %d", dec_sum, lhdc_decode_temp); + return -1; + } + + ret = a2dp_cp_consume_in_frame(); + + if (ret != 0) + { + TRACE_A2DP_DECODER_I("%s: a2dp_cp_consume_in_frame() failed: ret=%d", __func__, ret); + } + ASSERT(ret == 0, "%s: a2dp_cp_consume_in_frame() failed: ret=%d", __func__, ret); + + memcpy(&p_out_info->in_info, p_in_info, sizeof(*p_in_info)); + p_out_info->decoded_frames++; + p_out_info->frame_samples = A2DP_LHDC_OUTPUT_FRAME_SAMPLES; + p_out_info->frame_idx = a2dp_cp_get_in_frame_index(); + } + + if ((dec_sum % LHDC_DECODED_FRAME_SIZE)) + { + TRACE_A2DP_DECODER_I("error!!! dec_sum:%d != dec_len:%d", dec_sum, dec_len); + ASSERT(0, "%s", __func__); + } + + p_out_info->pcm_len += dec_sum; + + if (out_len <= sizeof(*p_out_info) + p_out_info->pcm_len) + { + ret = a2dp_cp_consume_emtpy_out_frame(); + ASSERT(ret == 0, "%s: a2dp_cp_consume_emtpy_out_frame() failed: ret=%d", __func__, ret); + } + + return 0; +} +#endif + +#if 1 +static int a2dp_audio_lhdc_list_checker(void) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_lhdc_decoder_frame_t *lhdc_decoder_frame_p = NULL; + int cnt = 0; + + do + { + lhdc_decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_lhdc_frame_malloc(LHDC_READBUF_SIZE); + if (lhdc_decoder_frame_p) + { + a2dp_audio_list_append(list, lhdc_decoder_frame_p); + } + cnt++; + } while (lhdc_decoder_frame_p && cnt < LHDC_MTU_LIMITER); + + do + { + node = a2dp_audio_list_begin(list); + if (node) + { + lhdc_decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, lhdc_decoder_frame_p); + } + } while (node); + + TRACE_A2DP_DECODER_I("%s cnt:%d list:%d", __func__, cnt, a2dp_audio_list_length(list)); + + return 0; +} +#endif + +int a2dp_audio_lhdc_mcu_decode_frame(uint8_t *buffer, uint32_t buffer_bytes) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_lhdc_decoder_frame_t *lhdc_decoder_frame_p = NULL; + + bool cache_underflow = false; + int output_byte = 0; + + uint32_t lhdc_out_len = 0; + + node = a2dp_audio_list_begin(list); + if (!node) + { + TRACE_A2DP_DECODER_I("lhdc_decode cache underflow"); + cache_underflow = true; + goto exit; + } + else + { + lhdc_decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_list_node(node); +#if defined(A2DP_LHDC_V3) + lhdcPutData(lhdc_decoder_frame_p->buffer, lhdc_decoder_frame_p->buffer_len); +#else + lhdcPutData(lhdc_decoder_frame_p->buffer, lhdc_decoder_frame_p->buffer_len); +#endif + do + { + lhdc_out_len = lhdcDecodeProcess(buffer + output_byte); + if (lhdc_out_len > 0) + { + output_byte += lhdc_out_len; + } + else + { + break; + } + } while (output_byte < (int)buffer_bytes && output_byte > 0); + + if (output_byte != (int)buffer_bytes) + { + TRACE_A2DP_DECODER_I("[warning] lhdc_decode_frame output_byte:%d lhdc_out_len:%d buffer_bytes:%d", output_byte, lhdc_out_len, buffer_bytes); + TRACE_A2DP_DECODER_I("[warning] lhdc_decode_frame frame_len:%d rtp seq:%d timestamp:%d decoder_frame:%d/%d ", + lhdc_decoder_frame_p->buffer_len, + lhdc_decoder_frame_p->sequenceNumber, + lhdc_decoder_frame_p->timestamp, + lhdc_decoder_frame_p->curSubSequenceNumber, + lhdc_decoder_frame_p->totalSubSequenceNumber); + output_byte = buffer_bytes; + int32_t dump_byte = lhdc_decoder_frame_p->buffer_len; + int32_t dump_offset = 0; + while (1) + { + uint32_t dump_byte_output = 0; + dump_byte_output = dump_byte > 32 ? 32 : dump_byte; + DUMP8("%02x ", lhdc_decoder_frame_p->buffer + dump_offset, dump_byte_output); + dump_offset += dump_byte_output; + dump_byte -= dump_byte_output; + if (dump_byte <= 0) + { + break; + } + } + ASSERT(0, "%s", __func__); + } + + a2dp_audio_lhdc_lastframe_info.sequenceNumber = lhdc_decoder_frame_p->sequenceNumber; + a2dp_audio_lhdc_lastframe_info.timestamp = lhdc_decoder_frame_p->timestamp; + a2dp_audio_lhdc_lastframe_info.curSubSequenceNumber = lhdc_decoder_frame_p->curSubSequenceNumber; + a2dp_audio_lhdc_lastframe_info.totalSubSequenceNumber = lhdc_decoder_frame_p->totalSubSequenceNumber; + a2dp_audio_lhdc_lastframe_info.frame_samples = A2DP_LHDC_OUTPUT_FRAME_SAMPLES; + a2dp_audio_lhdc_lastframe_info.decoded_frames++; + a2dp_audio_lhdc_lastframe_info.undecode_frames = a2dp_audio_list_length(list) - 1; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_lhdc_lastframe_info); + a2dp_audio_list_remove(list, lhdc_decoder_frame_p); + } +exit: + if (cache_underflow) + { + reset_lhdc_assmeble_packet(); + a2dp_audio_lhdc_lastframe_info.undecode_frames = 0; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_lhdc_lastframe_info); + output_byte = A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + return output_byte; +} + +int a2dp_audio_lhdc_decode_frame(uint8_t *buffer, uint32_t buffer_bytes) +{ +#ifdef A2DP_CP_ACCEL + return a2dp_cp_lhdc_mcu_decode(buffer, buffer_bytes); +#else + return a2dp_audio_lhdc_mcu_decode_frame(buffer, buffer_bytes); +#endif +} + +int a2dp_audio_lhdc_preparse_packet(btif_media_header_t *header, uint8_t *buffer, uint32_t buffer_bytes) +{ + a2dp_audio_lhdc_lastframe_info.sequenceNumber = header->sequenceNumber; + a2dp_audio_lhdc_lastframe_info.timestamp = header->timestamp; + a2dp_audio_lhdc_lastframe_info.curSubSequenceNumber = 0; + a2dp_audio_lhdc_lastframe_info.totalSubSequenceNumber = 0; + a2dp_audio_lhdc_lastframe_info.frame_samples = A2DP_LHDC_OUTPUT_FRAME_SAMPLES; + a2dp_audio_lhdc_lastframe_info.list_samples = A2DP_LHDC_OUTPUT_FRAME_SAMPLES; + a2dp_audio_lhdc_lastframe_info.decoded_frames = 0; + a2dp_audio_lhdc_lastframe_info.undecode_frames = 0; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_lhdc_lastframe_info); + + TRACE_A2DP_DECODER_I("%s seq:%d timestamp:%08x", __func__, header->sequenceNumber, header->timestamp); + + return A2DP_DECODER_NO_ERROR; +} + +void a2dp_audio_lhdc_free(void *packet) +{ + a2dp_audio_lhdc_decoder_frame_t *decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)packet; + a2dp_audio_heap_free(decoder_frame_p->buffer); + a2dp_audio_heap_free(decoder_frame_p); +} + +int a2dp_audio_lhdc_store_packet(btif_media_header_t *header, uint8_t *buffer, uint32_t buffer_bytes) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int nRet = A2DP_DECODER_NO_ERROR; + uint32_t frame_num = 0; + uint32_t frame_cnt = 0; + uint32_t lSize = 0; + uint8_t *lPTR = NULL; + lhdc_frame_Info_t lhdc_frame_Info; + uint32_t ptr_offset = 0; + + if ((frame_num = assemble_lhdc_packet(buffer, buffer_bytes, &lPTR, &lSize)) > 0) + { + if (lPTR != NULL && lSize != 0) + { + ptr_offset = 0; + //TRACE_A2DP_DECODER_I("%s: There are %d frames in packet", __func__, frame_num); + while (parse_lhdc_info(lPTR + ptr_offset, &lhdc_frame_Info) == 0 && ptr_offset < lSize && frame_cnt < frame_num) + { + a2dp_audio_lhdc_decoder_frame_t *decoder_frame_p = NULL; + if (!lhdc_frame_Info.frame_len) + { + DUMP8("%02x ", lPTR + ptr_offset, 32); + ASSERT(0, "lhdc_frame_Info error frame_len:%d offset:%d ptr:%08x/%08x", lhdc_frame_Info.frame_len, ptr_offset, (uint32_t)buffer, (uint32_t)lPTR); + } + ASSERT(lhdc_frame_Info.frame_len <= (lSize - ptr_offset), "%s frame_len:%d ptr_offset:%d buffer_bytes:%d", + __func__, lhdc_frame_Info.frame_len, ptr_offset, lSize); + uint32_t list_length = a2dp_audio_list_length(list); + if (list_length < lhdc_mtu_limiter) + { + decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_lhdc_frame_malloc(lhdc_frame_Info.frame_len); + } + else + { + nRet = A2DP_DECODER_MTU_LIMTER_ERROR; + break; + } + frame_cnt++; + + decoder_frame_p->sequenceNumber = header->sequenceNumber; + decoder_frame_p->timestamp = header->timestamp; + decoder_frame_p->curSubSequenceNumber = frame_cnt; + decoder_frame_p->totalSubSequenceNumber = frame_num; + memcpy(decoder_frame_p->buffer, lPTR + ptr_offset, lhdc_frame_Info.frame_len); + decoder_frame_p->buffer_len = lhdc_frame_Info.frame_len; + a2dp_audio_list_append(list, decoder_frame_p); + + ptr_offset += lhdc_frame_Info.frame_len; +#if 0 + TRACE_A2DP_DECODER_I("lhdc_store_packet save seq:%d timestamp:%d len:%d lSize:%d list_length:%d frame_len:%d Split:%d/%d", + header->sequenceNumber, + header->timestamp, + buffer_bytes, + lSize, + list_length, + lhdc_frame_Info.frame_len, + lhdc_frame_Info.isSplit, + lhdc_frame_Info.isLeft); +#endif + } + } + } + else + { + // TRACE_A2DP_DECODER_I("lhdc_store_packet skip seq:%d timestamp:%d len:%d l:%d", header->sequenceNumber, header->timestamp,buffer_bytes, lSize); + } + + return nRet; +} + +int a2dp_audio_lhdc_discards_packet(uint32_t packets) +{ +#ifdef A2DP_CP_ACCEL + a2dp_cp_reset_frame(); +#endif + + int nRet = a2dp_audio_context_p->audio_decoder.audio_decoder_synchronize_dest_packet_mut(a2dp_audio_context_p->dest_packet_mut); + + reset_lhdc_assmeble_packet(); + +#if defined(A2DP_LHDC_LARC) + lhdc_drop_frame = 0; +#endif + return nRet; +} + +static int a2dp_audio_lhdc_headframe_info_get(A2DP_AUDIO_HEADFRAME_INFO_T *headframe_info) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_lhdc_decoder_frame_t *decoder_frame_p = NULL; + + if (a2dp_audio_list_length(list)) + { + node = a2dp_audio_list_begin(list); + decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_list_node(node); + headframe_info->sequenceNumber = decoder_frame_p->sequenceNumber; + headframe_info->timestamp = decoder_frame_p->timestamp; + headframe_info->curSubSequenceNumber = 0; + headframe_info->totalSubSequenceNumber = 0; + } + else + { + memset(headframe_info, 0, sizeof(A2DP_AUDIO_HEADFRAME_INFO_T)); + } + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_lhdc_info_get(void *info) +{ + return A2DP_DECODER_NO_ERROR; +} + +extern uint32_t __lhdc_license_start[]; + +int a2dp_audio_lhdc_init(A2DP_AUDIO_OUTPUT_CONFIG_T *config, void *context) +{ + TRACE_A2DP_DECODER_I("%s %s ch:%d freq:%d bits:%d", __func__, getVersionCode(), + config->num_channels, + config->sample_rate, + config->bits_depth); + + uint8_t lhdc_license_key = 0; + uint8_t *lhdc_license_data=(uint8_t * )__lhdc_license_start + 0x98; + TRACE(5,"lhdc_license_data:%p, lhdc license %02x %02x %02x %02x",lhdc_license_data, + lhdc_license_data[0],lhdc_license_data[1],lhdc_license_data[2],lhdc_license_data[3]); + + + a2dp_audio_context_p = (A2DP_AUDIO_CONTEXT_T *)context; + + memset(&a2dp_audio_lhdc_lastframe_info, 0, sizeof(A2DP_AUDIO_DECODER_LASTFRAME_INFO_T)); + memcpy(&a2dp_audio_lhdc_output_config, config, sizeof(A2DP_AUDIO_OUTPUT_CONFIG_T)); + a2dp_audio_lhdc_lastframe_info.stream_info = a2dp_audio_lhdc_output_config; + a2dp_audio_lhdc_lastframe_info.frame_samples = A2DP_LHDC_OUTPUT_FRAME_SAMPLES; + a2dp_audio_lhdc_lastframe_info.list_samples = A2DP_LHDC_OUTPUT_FRAME_SAMPLES; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_lhdc_lastframe_info); + + lhdc_license_key = lhdcSetLicenseKeyTable(lhdc_license_data, bes_bt_local_info_get); + + TRACE_A2DP_DECODER_I("lhdc_license_key:%d", lhdc_license_key); + +#if defined(A2DP_LHDC_V3) + lhdcInit(config->bits_depth, config->sample_rate, 0, VERSION_3); +#else + lhdcInit(config->bits_depth, config->sample_rate, 0, VERSION_2); +#endif + initial_lhdc_assemble_packet(false); + +#ifdef A2DP_CP_ACCEL + int ret; + ret = a2dp_cp_init(a2dp_cp_lhdc_cp_decode, CP_PROC_DELAY_2_FRAMES); + ASSERT(ret == 0, "%s: a2dp_cp_init() failed: ret=%d", __func__, ret); +#endif + a2dp_audio_lhdc_list_checker(); + +#if defined(A2DP_LHDC_LARC) + lhdc_last_time = 0; + lhdc_drop_frame = 0; +#endif + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_lhdc_deinit(void) +{ +#ifdef A2DP_CP_ACCEL + a2dp_cp_deinit(); +#endif + lhdcDestroy(); + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_lhdc_synchronize_packet(A2DP_AUDIO_SYNCFRAME_INFO_T *sync_info, uint32_t mask) +{ + int nRet = A2DP_DECODER_SYNC_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + int list_len; + a2dp_audio_lhdc_decoder_frame_t *lhdc_decoder_frame; + +#ifdef A2DP_CP_ACCEL + a2dp_cp_reset_frame(); +#endif + + list_len = a2dp_audio_list_length(list); + + for (uint16_t i = 0; i < list_len; i++) + { + node = a2dp_audio_list_begin(list); + lhdc_decoder_frame = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_list_node(node); + if (A2DP_AUDIO_SYNCFRAME_CHK(lhdc_decoder_frame->sequenceNumber == sync_info->sequenceNumber, A2DP_AUDIO_SYNCFRAME_MASK_SEQ, mask) && + A2DP_AUDIO_SYNCFRAME_CHK(lhdc_decoder_frame->curSubSequenceNumber == sync_info->curSubSequenceNumber, A2DP_AUDIO_SYNCFRAME_MASK_CURRSUBSEQ, mask) && + A2DP_AUDIO_SYNCFRAME_CHK(lhdc_decoder_frame->totalSubSequenceNumber == sync_info->totalSubSequenceNumber, A2DP_AUDIO_SYNCFRAME_MASK_TOTALSUBSEQ, mask)) + { + nRet = A2DP_DECODER_NO_ERROR; + break; + } + a2dp_audio_list_remove(list, lhdc_decoder_frame); + } + + node = a2dp_audio_list_begin(list); + if (node) + { + lhdc_decoder_frame = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_list_node(node); + TRACE_A2DP_DECODER_I("%s nRet:%d SEQ:%d timestamp:%d %d/%d", __func__, nRet, lhdc_decoder_frame->sequenceNumber, lhdc_decoder_frame->timestamp, + lhdc_decoder_frame->curSubSequenceNumber, lhdc_decoder_frame->totalSubSequenceNumber); + } + else + { + TRACE_A2DP_DECODER_I("%s nRet:%d", __func__, nRet); + } + + return nRet; +} + +int a2dp_audio_lhdc_synchronize_dest_packet_mut(uint16_t packet_mut) +{ + list_node_t *node = NULL; + uint32_t list_len = 0; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_lhdc_decoder_frame_t *lhdc_decoder_frame_p = NULL; + + list_len = a2dp_audio_list_length(list); + if (list_len > packet_mut) + { + do + { + node = a2dp_audio_list_begin(list); + lhdc_decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, lhdc_decoder_frame_p); + } while (a2dp_audio_list_length(list) > packet_mut); + } + + TRACE_A2DP_DECODER_I("%s list:%d", __func__, a2dp_audio_list_length(list)); + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_lhdc_convert_list_to_samples(uint32_t *samples) +{ + uint32_t list_len = 0; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + + list_len = a2dp_audio_list_length(list); + + *samples = A2DP_LHDC_OUTPUT_FRAME_SAMPLES * list_len; + + TRACE_A2DP_DECODER_I("%s list:%d samples:%d", __func__, list_len, *samples); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_lhdc_discards_samples(uint32_t samples) +{ + int nRet = A2DP_DECODER_SYNC_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_lhdc_decoder_frame_t *lhdc_decoder_frame_p = NULL; + list_node_t *node = NULL; + int need_remove_list = 0; + uint32_t list_samples = 0; + + ASSERT(!(samples % A2DP_LHDC_OUTPUT_FRAME_SAMPLES), "%s samples err:%d", __func__, samples); + + a2dp_audio_lhdc_convert_list_to_samples(&list_samples); + if (list_samples >= samples) + { + need_remove_list = samples / A2DP_LHDC_OUTPUT_FRAME_SAMPLES; + for (int i = 0; i < need_remove_list; i++) + { + node = a2dp_audio_list_begin(list); + lhdc_decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, lhdc_decoder_frame_p); + } + nRet = A2DP_DECODER_NO_ERROR; + + node = a2dp_audio_list_begin(list); + lhdc_decoder_frame_p = (a2dp_audio_lhdc_decoder_frame_t *)a2dp_audio_list_node(node); + TRACE_A2DP_DECODER_I("%s discard %d sample cur seq:%d", __func__, samples, lhdc_decoder_frame_p->sequenceNumber); + } + + return nRet; +} + +A2DP_AUDIO_DECODER_T a2dp_audio_lhdc_decoder_config = { + {96000, 2, 24}, + 1, + a2dp_audio_lhdc_init, + a2dp_audio_lhdc_deinit, + a2dp_audio_lhdc_decode_frame, + a2dp_audio_lhdc_preparse_packet, + a2dp_audio_lhdc_store_packet, + a2dp_audio_lhdc_discards_packet, + a2dp_audio_lhdc_synchronize_packet, + a2dp_audio_lhdc_synchronize_dest_packet_mut, + a2dp_audio_lhdc_convert_list_to_samples, + a2dp_audio_lhdc_discards_samples, + a2dp_audio_lhdc_headframe_info_get, + a2dp_audio_lhdc_info_get, + a2dp_audio_lhdc_free, + } ; + diff --git a/apps/audioplayers/a2dp_decoder/a2dp_decoder_sbc.cpp b/apps/audioplayers/a2dp_decoder/a2dp_decoder_sbc.cpp new file mode 100644 index 0000000..e53066c --- /dev/null +++ b/apps/audioplayers/a2dp_decoder/a2dp_decoder_sbc.cpp @@ -0,0 +1,969 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Standard C Included Files +#include "cmsis.h" +#include "plat_types.h" +#include +#include "heap_api.h" +#include "hal_location.h" +#include "codec_sbc.h" +#include "a2dp_decoder_internal.h" +#include "hal_timer.h" +#include "cmsis_os.h" + +#ifndef SBC_MTU_LIMITER +#define SBC_MTU_LIMITER (250) /*must <= 332*/ +#endif +#define SBC_PCMLEN_DEFAULT (512) + +#define SBC_LIST_SAMPLES (128) + +static A2DP_AUDIO_CONTEXT_T *a2dp_audio_context_p = NULL; +extern A2DP_AUDIO_DECODER_T a2dp_audio_sbc_decoder_config; + +typedef struct { + btif_sbc_decoder_t *sbc_decoder; + btif_sbc_pcm_data_t *pcm_data; +} a2dp_audio_sbc_decoder_t; + +typedef struct { + uint16_t sequenceNumber; + uint32_t timestamp; + uint16_t curSubSequenceNumber; + uint16_t totalSubSequenceNumber; + uint8_t *sbc_buffer; + uint32_t sbc_buffer_len; +} a2dp_audio_sbc_decoder_frame_t; + +static a2dp_audio_sbc_decoder_t a2dp_audio_sbc_decoder; +static btif_sbc_decoder_t *a2dp_audio_sbc_decoder_preparse = NULL; + +static A2DP_AUDIO_DECODER_LASTFRAME_INFO_T a2dp_audio_sbc_lastframe_info; + +static uint16_t sbc_mtu_limiter = SBC_MTU_LIMITER; + +static btif_media_header_t sbc_decoder_last_valid_frame = {0,}; +static bool sbc_decoder_last_valid_frame_ready = false; +static bool sbc_chnl_mode_mono = false; + +static int a2dp_audio_sbc_header_parser_init(void); + +static void *a2dp_audio_sbc_subframe_malloc(uint32_t sbc_len) +{ + a2dp_audio_sbc_decoder_frame_t *sbc_decoder_frame_p = NULL; + uint8_t *sbc_buffer = NULL; + + sbc_buffer = (uint8_t *)a2dp_audio_heap_malloc(sbc_len); + sbc_decoder_frame_p = (a2dp_audio_sbc_decoder_frame_t *)a2dp_audio_heap_malloc(sizeof(a2dp_audio_sbc_decoder_frame_t)); + sbc_decoder_frame_p->sbc_buffer = sbc_buffer; + sbc_decoder_frame_p->sbc_buffer_len = sbc_len; + return (void *)sbc_decoder_frame_p; +} + +static void a2dp_audio_sbc_subframe_free(void *packet) +{ + a2dp_audio_sbc_decoder_frame_t *sbc_decoder_frame_p = (a2dp_audio_sbc_decoder_frame_t *)packet; + a2dp_audio_heap_free(sbc_decoder_frame_p->sbc_buffer); + a2dp_audio_heap_free(sbc_decoder_frame_p); +} + +static void sbc_codec_init(void) +{ + btif_sbc_init_decoder(a2dp_audio_sbc_decoder.sbc_decoder); + a2dp_audio_sbc_decoder.sbc_decoder->maxPcmLen = SBC_PCMLEN_DEFAULT; + a2dp_audio_sbc_decoder.pcm_data->data = NULL; + a2dp_audio_sbc_decoder.pcm_data->dataLen = 0; +} + +#ifdef A2DP_CP_ACCEL +struct A2DP_CP_SBC_IN_FRM_INFO_T { + uint16_t sequenceNumber; + uint32_t timestamp; + uint16_t curSubSequenceNumber; + uint16_t totalSubSequenceNumber; +}; + +struct A2DP_CP_SBC_OUT_FRM_INFO_T { + struct A2DP_CP_SBC_IN_FRM_INFO_T in_info; + uint16_t frame_samples; + uint16_t decoded_frames; + uint16_t frame_idx; + uint16_t pcm_len; +}; + +static bool cp_codec_reset; +extern "C" uint32_t get_in_cp_frame_cnt(void); +extern "C" unsigned int set_cp_reset_flag(uint8_t evt); + +int a2dp_cp_sbc_cp_decode(void); + +extern uint32_t app_bt_stream_get_dma_buffer_samples(void); + +static int TEXT_SBC_LOC a2dp_cp_sbc_after_cache_underflow(void) +{ +#ifdef A2DP_CP_ACCEL + cp_codec_reset = true; +#endif + return 0; +} + +static int a2dp_cp_sbc_mcu_decode(uint8_t *buffer, uint32_t buffer_bytes) +{ + a2dp_audio_sbc_decoder_frame_t *sbc_decoder_frame = NULL; + list_node_t *node = NULL; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int ret, dec_ret; + struct A2DP_CP_SBC_IN_FRM_INFO_T in_info; + struct A2DP_CP_SBC_OUT_FRM_INFO_T *p_out_info = NULL; + uint8_t *out = NULL; + uint32_t out_len; + uint32_t out_frame_len; + uint32_t cp_buffer_frames_max = 0; + uint32_t check_sum = 0; + + cp_buffer_frames_max = app_bt_stream_get_dma_buffer_samples()/2; + if (cp_buffer_frames_max %(a2dp_audio_sbc_lastframe_info.frame_samples) ){ + cp_buffer_frames_max = cp_buffer_frames_max /(a2dp_audio_sbc_lastframe_info.frame_samples) +1 ; + }else{ + cp_buffer_frames_max = cp_buffer_frames_max /(a2dp_audio_sbc_lastframe_info.frame_samples) ; + } + + out_frame_len = sizeof(*p_out_info) + buffer_bytes; + ret = a2dp_cp_decoder_init(out_frame_len, cp_buffer_frames_max * 2); + if (ret){ + TRACE_A2DP_DECODER_W("[SBC][INIT] cp_decoder_init() failed: ret=%d", ret); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + while ((node = a2dp_audio_list_begin(list)) != NULL) { + sbc_decoder_frame = (a2dp_audio_sbc_decoder_frame_t *)a2dp_audio_list_node(node); + + in_info.sequenceNumber = sbc_decoder_frame->sequenceNumber; + in_info.timestamp = sbc_decoder_frame->timestamp; + in_info.curSubSequenceNumber = sbc_decoder_frame->curSubSequenceNumber; + in_info.totalSubSequenceNumber = sbc_decoder_frame->totalSubSequenceNumber; + + ret = a2dp_cp_put_in_frame(&in_info, sizeof(in_info), sbc_decoder_frame->sbc_buffer, sbc_decoder_frame->sbc_buffer_len); + if (ret) { + TRACE_A2DP_DECODER_D("[MCU][SBC] piff !!!!!!ret: %d ", ret); + break; + } + check_sum = a2dp_audio_decoder_internal_check_sum_generate(sbc_decoder_frame->sbc_buffer, sbc_decoder_frame->sbc_buffer_len); + a2dp_audio_list_remove(list, sbc_decoder_frame); + } + + ret = a2dp_cp_get_full_out_frame((void **)&out, &out_len); + if (ret) { + if (!get_in_cp_frame_cnt()){ + TRACE_A2DP_DECODER_I("[MCU][SBC] cp cache underflow list:%d in_cp:%d",a2dp_audio_list_length(list), get_in_cp_frame_cnt()); + return A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + if (!a2dp_audio_sysfreq_boost_running()){ + a2dp_audio_sysfreq_boost_start(1); + } + osDelay(8); + ret = a2dp_cp_get_full_out_frame((void **)&out, &out_len); + if (ret) { + TRACE_A2DP_DECODER_I("[MCU][SBC] cp cache underflow list:%d in_cp:%d",a2dp_audio_list_length(list), get_in_cp_frame_cnt()); + a2dp_cp_sbc_after_cache_underflow(); + return A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + } + + if (out_len == 0) { + TRACE_A2DP_DECODER_I("[MCU][SBC] olz!!!%d ",__LINE__); + memset(buffer, 0, buffer_bytes); + a2dp_cp_consume_full_out_frame(); + return A2DP_DECODER_NO_ERROR; + } + if(out_len != out_frame_len){ + TRACE_A2DP_DECODER_I("[MCU][SBC] Bad out len %u (should be %u)", out_len, out_frame_len); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + p_out_info = (struct A2DP_CP_SBC_OUT_FRM_INFO_T *)out; + if (p_out_info->pcm_len) { + a2dp_audio_sbc_lastframe_info.sequenceNumber = p_out_info->in_info.sequenceNumber; + a2dp_audio_sbc_lastframe_info.timestamp = p_out_info->in_info.timestamp; + a2dp_audio_sbc_lastframe_info.curSubSequenceNumber = p_out_info->in_info.curSubSequenceNumber; + a2dp_audio_sbc_lastframe_info.totalSubSequenceNumber = p_out_info->in_info.totalSubSequenceNumber; + a2dp_audio_sbc_lastframe_info.frame_samples = p_out_info->frame_samples; + a2dp_audio_sbc_lastframe_info.decoded_frames += p_out_info->decoded_frames; + a2dp_audio_sbc_lastframe_info.undecode_frames = + a2dp_audio_list_length(list) + a2dp_cp_get_in_frame_cnt_by_index(p_out_info->frame_idx) - 1; + a2dp_audio_sbc_lastframe_info.check_sum= check_sum?check_sum:a2dp_audio_sbc_lastframe_info.check_sum; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_sbc_lastframe_info); + } + + if (p_out_info->pcm_len == buffer_bytes) { + memcpy(buffer, p_out_info + 1, p_out_info->pcm_len); + dec_ret = A2DP_DECODER_NO_ERROR; + } else { + TRACE_A2DP_DECODER_I("[MCU][SBC] line:%d cp decoder error !!!!!!", __LINE__); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + + ret = a2dp_cp_consume_full_out_frame(); + if(ret){ + TRACE_A2DP_DECODER_I("[MCU][SBC] cp_consume_full_out_frame failed: ret=%d", ret); + set_cp_reset_flag(true); + return A2DP_DECODER_DECODE_ERROR; + } + return dec_ret; +} + + +#ifdef __CP_EXCEPTION_TEST__ +static bool _cp_assert = false; + int cp_assert_sbc(void) +{ + _cp_assert = true; + return 0; +} +#endif + + +TEXT_SBC_LOC +int a2dp_cp_sbc_cp_decode(void) +{ + int ret = 0; + enum CP_EMPTY_OUT_FRM_T out_frm_st; + uint8_t *out = NULL; + uint32_t out_len = 0; + uint8_t *dec_start = NULL; + uint32_t dec_len = 0; + struct A2DP_CP_SBC_IN_FRM_INFO_T *p_in_info = NULL; + struct A2DP_CP_SBC_OUT_FRM_INFO_T *p_out_info = NULL; + uint8_t *in_buf = NULL; + uint32_t in_len = 0; + uint16_t bytes_parsed = 0; + float sbc_subbands_gain[8]={1,1,1,1,1,1,1,1}; + btif_sbc_decoder_t *sbc_decoder = NULL; + btif_sbc_pcm_data_t *pcm_data = NULL; + bt_status_t decoder_err = 0; + int error = 0; + + if (cp_codec_reset) { + cp_codec_reset = false; + sbc_codec_init(); + } + + +#ifdef __CP_EXCEPTION_TEST__ + if (_cp_assert){ + _cp_assert = false; + *(int*) 0 = 1; + //ASSERT_A2DP_DECODER(0, "ASSERT_A2DP_DECODER %s %d", __func__, __LINE__); + } +#endif + + sbc_decoder = a2dp_audio_sbc_decoder.sbc_decoder; + pcm_data = a2dp_audio_sbc_decoder.pcm_data; + + out_frm_st = a2dp_cp_get_emtpy_out_frame((void **)&out, &out_len); + if (out_frm_st != CP_EMPTY_OUT_FRM_OK && out_frm_st != CP_EMPTY_OUT_FRM_WORKING) { + return 1; + } + + ASSERT_A2DP_DECODER(out_len > sizeof(*p_out_info), "[CP][SBC] Bad out_len %u (should > %u)", out_len, sizeof(*p_out_info)); + + p_out_info = (struct A2DP_CP_SBC_OUT_FRM_INFO_T *)out; + if (out_frm_st == CP_EMPTY_OUT_FRM_OK) { + p_out_info->pcm_len = 0; + p_out_info->decoded_frames = 0; + } + ASSERT_A2DP_DECODER(out_len > sizeof(*p_out_info) + p_out_info->pcm_len, "[CP][SBC] Bad out_len %u (should > %u + %u)", out_len, sizeof(*p_out_info), p_out_info->pcm_len); + + dec_start = (uint8_t *)(p_out_info + 1) + p_out_info->pcm_len; + dec_len = out_len - (dec_start - (uint8_t *)out); + + pcm_data->data = dec_start; + pcm_data->dataLen = 0; + error = 0; + + while (pcm_data->dataLen < dec_len && error == 0) { + ret = a2dp_cp_get_in_frame((void **)&in_buf, &in_len); + if (ret) { + p_out_info->pcm_len += pcm_data->dataLen; + return 4; + } + ASSERT_A2DP_DECODER(in_len > sizeof(*p_in_info), "%s: Bad in_len %u (should > %u)", __func__, in_len, sizeof(*p_in_info)); + + p_in_info = (struct A2DP_CP_SBC_IN_FRM_INFO_T *)in_buf; + in_buf += sizeof(*p_in_info); + in_len -= sizeof(*p_in_info); + + decoder_err = btif_sbc_decode_frames(sbc_decoder, in_buf, in_len, + &bytes_parsed, + pcm_data, + dec_len, + sbc_subbands_gain); + switch (decoder_err) + { + case BT_STS_SUCCESS: + case BT_STS_CONTINUE: + break; + case BT_STS_NO_RESOURCES: + error = 1; + ASSERT_A2DP_DECODER(0, "sbc_decode BT_STS_NO_RESOURCES pcm has no more buffer, i think can't reach here"); + break; + case BT_STS_FAILED: + default: + error = 1; + sbc_codec_init(); + break; + } + + memcpy(&p_out_info->in_info, p_in_info, sizeof(*p_in_info)); + p_out_info->decoded_frames++; + p_out_info->frame_samples = sbc_decoder->maxPcmLen/4; + p_out_info->frame_idx = a2dp_cp_get_in_frame_index(); + + ret = a2dp_cp_consume_in_frame(); + ASSERT_A2DP_DECODER(ret == 0, "%s: a2dp_cp_consume_in_frame() failed: ret=%d", __func__, ret); + } + + p_out_info->pcm_len += pcm_data->dataLen; + + if (error || out_len <= sizeof(*p_out_info) + p_out_info->pcm_len) { + ret = a2dp_cp_consume_emtpy_out_frame(); + ASSERT_A2DP_DECODER(ret == 0, "%s: a2dp_cp_consume_emtpy_out_frame() failed: ret=%d", __func__, ret); + } + + return error; +} +#endif + +static int a2dp_audio_sbc_list_checker(void) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_sbc_decoder_frame_t *sbc_decoder_frame = NULL; + int cnt = 0; + + do { + sbc_decoder_frame = (a2dp_audio_sbc_decoder_frame_t *)a2dp_audio_sbc_subframe_malloc(SBC_LIST_SAMPLES); + if (sbc_decoder_frame){ + a2dp_audio_list_append(list, sbc_decoder_frame); + } + cnt++; + }while(sbc_decoder_frame && cnt < SBC_MTU_LIMITER); + + do { + node = a2dp_audio_list_begin(list); + if (node){ + sbc_decoder_frame = (a2dp_audio_sbc_decoder_frame_t *)a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, sbc_decoder_frame); + } + }while(node); + + TRACE_A2DP_DECODER_I("[SBC][INIT] cnt:%d list:%d", cnt, a2dp_audio_list_length(list)); + + return 0; +} + +int a2dp_audio_sbc_init(A2DP_AUDIO_OUTPUT_CONFIG_T *config, void *context) +{ + TRACE_A2DP_DECODER_I("[SBC][INIT]"); + + a2dp_audio_context_p = (A2DP_AUDIO_CONTEXT_T *)context; + + a2dp_audio_sbc_header_parser_init(); + memset(&a2dp_audio_sbc_lastframe_info, 0, sizeof(A2DP_AUDIO_DECODER_LASTFRAME_INFO_T)); + a2dp_audio_sbc_lastframe_info.stream_info = *config; + a2dp_audio_sbc_lastframe_info.frame_samples= SBC_LIST_SAMPLES; + a2dp_audio_sbc_lastframe_info.list_samples = SBC_LIST_SAMPLES; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_sbc_lastframe_info); + + ASSERT_A2DP_DECODER(a2dp_audio_context_p->dest_packet_mut < SBC_MTU_LIMITER, "%s MTU OVERFLOW:%u/%u", __func__, a2dp_audio_context_p->dest_packet_mut, SBC_MTU_LIMITER); + + a2dp_audio_sbc_decoder.sbc_decoder = (btif_sbc_decoder_t *)a2dp_audio_heap_malloc(sizeof(btif_sbc_decoder_t)); + a2dp_audio_sbc_decoder.pcm_data = (btif_sbc_pcm_data_t *)a2dp_audio_heap_malloc(sizeof(btif_sbc_pcm_data_t)); + a2dp_audio_sbc_decoder_preparse = (btif_sbc_decoder_t *)a2dp_audio_heap_malloc(sizeof(btif_sbc_decoder_t)); +#ifdef A2DP_CP_ACCEL + int ret; + cp_codec_reset = true; + ret = a2dp_cp_init(a2dp_cp_sbc_cp_decode, CP_PROC_DELAY_2_FRAMES); + ASSERT_A2DP_DECODER(ret == 0, "%s: a2dp_cp_init() failed: ret=%d", __func__, ret); +#else + sbc_codec_init(); +#endif + a2dp_audio_sbc_list_checker(); + sbc_chnl_mode_mono = false; + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_sbc_deinit(void) +{ +#ifdef A2DP_CP_ACCEL + a2dp_cp_deinit(); +#endif + a2dp_audio_heap_free(a2dp_audio_sbc_decoder_preparse); + a2dp_audio_heap_free(a2dp_audio_sbc_decoder.sbc_decoder); + a2dp_audio_heap_free(a2dp_audio_sbc_decoder.pcm_data); + + TRACE_A2DP_DECODER_I("[SBC][DEINIT]"); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_sbc_mcu_decode_frame(uint8_t *buffer, uint32_t buffer_bytes) +{ + bt_status_t ret = BT_STS_SUCCESS; + uint16_t bytes_parsed = 0; + float sbc_subbands_gain[8]={1,1,1,1,1,1,1,1}; + btif_sbc_decoder_t *sbc_decoder = NULL; + btif_sbc_pcm_data_t *pcm_data = NULL; + uint16_t frame_pcmbyte = 0; + uint16_t pcm_output_byte = 0; + bool cache_underflow = false; + + sbc_decoder = a2dp_audio_sbc_decoder.sbc_decoder; + pcm_data = a2dp_audio_sbc_decoder.pcm_data; + frame_pcmbyte = sbc_decoder->maxPcmLen; + + + a2dp_audio_sbc_decoder_frame_t *sbc_decoder_frame = NULL; + list_node_t *node = NULL; + + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + + pcm_data->data = buffer; + pcm_data->dataLen = 0; + + TRACE_A2DP_DECODER_D("[MCU][SBC] size:%d", a2dp_audio_list_length(list)); + + for (pcm_output_byte = 0; pcm_output_bytesbc_buffer, sbc_decoder_frame->sbc_buffer_len, + &bytes_parsed, + pcm_data, + buffer_bytes, + sbc_subbands_gain); + int_unlock(lock); + TRACE_A2DP_DECODER_D("[MCU][SBC] seq:%d/%d/%d len:%d ret:%d used:%d", + sbc_decoder_frame->curSubSequenceNumber, + sbc_decoder_frame->totalSubSequenceNumber, + sbc_decoder_frame->sequenceNumber, + sbc_decoder_frame->sbc_buffer_len, + ret, + bytes_parsed); + + a2dp_audio_sbc_lastframe_info.sequenceNumber = sbc_decoder_frame->sequenceNumber; + a2dp_audio_sbc_lastframe_info.timestamp = sbc_decoder_frame->timestamp; + a2dp_audio_sbc_lastframe_info.curSubSequenceNumber = sbc_decoder_frame->curSubSequenceNumber; + a2dp_audio_sbc_lastframe_info.totalSubSequenceNumber = sbc_decoder_frame->totalSubSequenceNumber; + a2dp_audio_sbc_lastframe_info.frame_samples = sbc_decoder->maxPcmLen/4; + a2dp_audio_sbc_lastframe_info.decoded_frames++; + a2dp_audio_sbc_lastframe_info.undecode_frames = a2dp_audio_list_length(list)-1; + a2dp_audio_sbc_lastframe_info.check_sum = a2dp_audio_decoder_internal_check_sum_generate(sbc_decoder_frame->sbc_buffer, sbc_decoder_frame->sbc_buffer_len); + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_sbc_lastframe_info); + a2dp_audio_list_remove(list, sbc_decoder_frame); + switch (ret) + { + case BT_STS_SUCCESS: + if (pcm_data->dataLen != buffer_bytes){ + TRACE_A2DP_DECODER_W("[MCU][SBC] WARNING pcm buff mismatch %d/%d", pcm_data->dataLen, buffer_bytes); + } + if (pcm_data->dataLen == buffer_bytes){ + if (pcm_output_byte+frame_pcmbyte != buffer_bytes){ + TRACE_A2DP_DECODER_W("[MCU][SBC]WARNING loop not break %d/%d frame_pcm:%d", pcm_output_byte, buffer_bytes, frame_pcmbyte); + goto exit; + } + } + break; + case BT_STS_CONTINUE: + continue; + break; + case BT_STS_NO_RESOURCES: + ASSERT_A2DP_DECODER(0, "sbc_decode BT_STS_NO_RESOURCES pcm has no more buffer, i think can't reach here"); + break; + case BT_STS_FAILED: + default: + sbc_codec_init(); + goto exit; + } + }else{ + TRACE_A2DP_DECODER_W("[MCU][SBC] A2DP PACKET CACHE UNDERFLOW"); + ret = BT_STS_FAILED; + cache_underflow = true; + goto exit; + } + + } +exit: + if (cache_underflow){ + TRACE_A2DP_DECODER_W("[MCU][SBC] A2DP PACKET CACHE UNDERFLOW need add some process"); + a2dp_audio_sbc_lastframe_info.undecode_frames = 0; + a2dp_audio_sbc_lastframe_info.check_sum = 0; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_sbc_lastframe_info); + ret = A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + return ret; +} + +int a2dp_audio_sbc_decode_frame(uint8_t *buffer, uint32_t buffer_bytes) +{ + int nRet = 0; + if (sbc_chnl_mode_mono){ + int i = 0; + int16_t *src = NULL,*dest = NULL; +#ifdef A2DP_CP_ACCEL + nRet = a2dp_cp_sbc_mcu_decode(buffer, buffer_bytes/2); +#else + nRet = a2dp_audio_sbc_mcu_decode_frame(buffer, buffer_bytes/2); +#endif + i = buffer_bytes / 2; + dest = (int16_t *)buffer + i - 1; + i = i / 2; + src = (int16_t *)buffer + i - 1; + for (; i>=0; i--){ + *dest = *src; + dest--; + *dest = *src; + dest--; + src--; + } + }else{ +#ifdef A2DP_CP_ACCEL + nRet = a2dp_cp_sbc_mcu_decode(buffer, buffer_bytes); +#else + nRet = a2dp_audio_sbc_mcu_decode_frame(buffer, buffer_bytes); +#endif + } + return nRet; +} + +int a2dp_audio_sbc_preparse_packet(btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + uint16_t bytes_parsed = 0; + uint32_t frame_num = 0; + uint8_t *parser_p = buffer; + + frame_num = *parser_p; + parser_p++; + buffer_bytes--; + + // TODO: Remove the following sbc init and decode codes. They might conflict with the calls + // during CP process. CP process is triggered by audioflinger PCM callback. + + + if (*parser_p != 0x9c){ + TRACE_A2DP_DECODER_I("[SBC][PRE] ERROR SBC FRAME !!! frame_num:%d", frame_num); + DUMP8("%02x ", parser_p, 12); + }else{ + btif_sbc_decode_frames_parser(a2dp_audio_sbc_decoder_preparse,parser_p, buffer_bytes, &bytes_parsed); + TRACE_A2DP_DECODER_I("[SBC][PRE] seq:%d tStmp:%08x smpR:%d ch:%d len:%d", + header->sequenceNumber, + header->timestamp, + a2dp_audio_sbc_decoder_preparse->streamInfo.sampleFreq, + a2dp_audio_sbc_decoder_preparse->streamInfo.channelMode, + a2dp_audio_sbc_decoder_preparse->maxPcmLen); + TRACE_A2DP_DECODER_I("[SBC][PRE] frmN:%d par:%d/%d", frame_num, buffer_bytes, bytes_parsed); + + a2dp_audio_sbc_lastframe_info.sequenceNumber = header->sequenceNumber; + a2dp_audio_sbc_lastframe_info.timestamp = header->timestamp; + a2dp_audio_sbc_lastframe_info.curSubSequenceNumber = 0; + a2dp_audio_sbc_lastframe_info.totalSubSequenceNumber = frame_num; + a2dp_audio_sbc_lastframe_info.frame_samples = a2dp_audio_sbc_decoder_preparse->maxPcmLen/4; + a2dp_audio_sbc_lastframe_info.list_samples = SBC_LIST_SAMPLES; + a2dp_audio_sbc_lastframe_info.decoded_frames = 0; + a2dp_audio_sbc_lastframe_info.undecode_frames = 0; + a2dp_audio_decoder_internal_lastframe_info_set(&a2dp_audio_sbc_lastframe_info); + } + if (a2dp_audio_sbc_decoder_preparse->streamInfo.channelMode == BTIF_SBC_CHNL_MODE_MONO){ + sbc_chnl_mode_mono = true; + } + return A2DP_DECODER_NO_ERROR; +} + + +static int a2dp_audio_sbc_header_parser_init(void) +{ + a2dp_audio_sbc_decoder_config.auto_synchronize_support = true; + sbc_decoder_last_valid_frame_ready = false; + memset(&sbc_decoder_last_valid_frame, 0, sizeof(sbc_decoder_last_valid_frame)); + return 0; +} + +static int a2dp_audio_sbc_packet_recover_save_last(btif_media_header_t *sbc_decoder_frame) +{ + sbc_decoder_last_valid_frame = *sbc_decoder_frame; + sbc_decoder_last_valid_frame_ready = true; + return 0; +} + +static int a2dp_audio_sbc_packet_recover_find_missing(btif_media_header_t *sbc_decoder_frame, uint8_t frame_cnt) +{ + uint16_t diff_seq = 0; + uint32_t diff_timestamp = 0; + uint32_t diff = 0; + uint32_t need_recover_pkt = 0; + + if (!sbc_decoder_last_valid_frame_ready){ + return need_recover_pkt; + } + + diff_seq = a2dp_audio_get_passed(sbc_decoder_frame->sequenceNumber, sbc_decoder_last_valid_frame.sequenceNumber, UINT16_MAX); + diff_timestamp = a2dp_audio_get_passed(sbc_decoder_frame->timestamp, sbc_decoder_last_valid_frame.timestamp, UINT32_MAX); + if (diff_seq > 1){ + diff = diff_timestamp/diff_seq; + if (diff%SBC_LIST_SAMPLES == 0){ + need_recover_pkt = diff_timestamp/SBC_LIST_SAMPLES; + if (need_recover_pkt > frame_cnt){ + need_recover_pkt -= frame_cnt; + } + }else{ + diff_seq--; + need_recover_pkt = diff_seq * frame_cnt; + } + TRACE_A2DP_DECODER_W("[SBC][INPUT][PLC] seq:%d/%d stmp:%d/%d", sbc_decoder_frame->sequenceNumber, sbc_decoder_last_valid_frame.sequenceNumber, + sbc_decoder_frame->timestamp, sbc_decoder_last_valid_frame.timestamp); + TRACE_A2DP_DECODER_W("[SBC][INPUT][PLC] diff_seq:%d diff_stmp:%d diff:%d missing:%d", diff_seq, diff_timestamp, diff, need_recover_pkt); + } + + return need_recover_pkt; +} + +static int a2dp_audio_sbc_packet_recover_proc(btif_media_header_t *sbc_decoder_frame, a2dp_audio_sbc_decoder_frame_t *sbc_raw_frame, uint8_t frame_cnt) +{ + int nRet = A2DP_DECODER_NO_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int missing_pkt_cnt = 0; + missing_pkt_cnt = a2dp_audio_sbc_packet_recover_find_missing(sbc_decoder_frame, frame_cnt); + if (missing_pkt_cnt && sbc_raw_frame && + (a2dp_audio_list_length(list)+missing_pkt_cnt) < sbc_mtu_limiter){ + for (uint8_t i =0; isbc_buffer_len); + if (!frame_p){ + nRet = A2DP_DECODER_MEMORY_ERROR; + goto exit; + } + frame_p->sequenceNumber = UINT16_MAX; + frame_p->timestamp = UINT32_MAX; + memcpy(frame_p->sbc_buffer, sbc_raw_frame->sbc_buffer, sbc_raw_frame->sbc_buffer_len); + frame_p->sbc_buffer_len = sbc_raw_frame->sbc_buffer_len; + a2dp_audio_list_append(list, frame_p); + } + } +exit: + return nRet; +} + +#define FRAME_LIST_MAX (20) +int a2dp_audio_sbc_store_packet(btif_media_header_t * header, uint8_t *buffer, uint32_t buffer_bytes) +{ + int nRet = A2DP_DECODER_NO_ERROR; + + uint32_t frame_cnt = 0; + uint32_t frame_num = 0; + uint32_t frame_len = 0; + uint8_t *parser_p = buffer; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + uint16_t bytes_parsed = 0; + a2dp_audio_sbc_decoder_frame_t *frame_list[FRAME_LIST_MAX] = {0,}; + uint8_t frame_list_idx = 0; + bool find_err = false; + uint32_t i = 0; + + frame_num = *parser_p; + + if (!frame_num){ + TRACE_A2DP_DECODER_W("[SBC][INPUT] ERROR SBC FRAME !!! frame_num:%d", frame_num); + DUMP8("%02x ", parser_p, 12); + return A2DP_DECODER_DECODE_ERROR; + } + + parser_p++; + buffer_bytes--; + frame_len = buffer_bytes/frame_num; + + if ((a2dp_audio_list_length(list)+frame_num) < sbc_mtu_limiter){ + for (i=0; isequenceNumber = header->sequenceNumber; + frame_p->timestamp = header->timestamp; + frame_p->curSubSequenceNumber = frame_cnt; + frame_p->totalSubSequenceNumber = frame_num; + memcpy(frame_p->sbc_buffer, (parser_p+i), bytes_parsed); + frame_p->sbc_buffer_len = bytes_parsed; + frame_list[frame_list_idx++] = frame_p; + if (frame_list_idx >= FRAME_LIST_MAX){ + find_err = true; + break; + } + }else{ + TRACE_A2DP_DECODER_W("[SBC][INPUT] ERROR SBC FRAME !!!"); + DUMP8("%02x ", parser_p+i, 12); + find_err = true; + break; + } + } + if (find_err){ + TRACE_A2DP_DECODER_W("[SBC][INPUT] FIND ERR !!!"); + for (i = 0; iaudio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_sbc_decoder_frame_t *sbc_decoder_frame = NULL; + uint16_t totalSubSequenceNumber; + uint8_t j = 0; + +#ifdef A2DP_CP_ACCEL + a2dp_cp_reset_frame(); +#endif + + node = a2dp_audio_list_begin(list); + if (!node){ + goto exit; + } + sbc_decoder_frame = (a2dp_audio_sbc_decoder_frame_t *)a2dp_audio_list_node(node); + + for (j=0; jcurSubSequenceNumber != 0){ + a2dp_audio_list_remove(list, sbc_decoder_frame); + }else{ + break; + } + } + + node = a2dp_audio_list_begin(list); + if (!node){ + goto exit; + } + sbc_decoder_frame = (a2dp_audio_sbc_decoder_frame_t *)a2dp_audio_list_node(node); + ASSERT_A2DP_DECODER(sbc_decoder_frame->curSubSequenceNumber == 0, "sbc_discards_packet not align curSubSequenceNumber:%d", + sbc_decoder_frame->curSubSequenceNumber); + + totalSubSequenceNumber = sbc_decoder_frame->totalSubSequenceNumber; + + if (packets <= a2dp_audio_list_length(list)/totalSubSequenceNumber){ + for (uint8_t i=0; iaudio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_sbc_decoder_frame_t *sbc_decoder_frame = NULL; + + if (a2dp_audio_list_length(list) && ((node = a2dp_audio_list_begin(list)) != NULL)){ + sbc_decoder_frame = (a2dp_audio_sbc_decoder_frame_t *)a2dp_audio_list_node(node); + headframe_info->sequenceNumber = sbc_decoder_frame->sequenceNumber; + headframe_info->timestamp = sbc_decoder_frame->timestamp; + headframe_info->curSubSequenceNumber = sbc_decoder_frame->curSubSequenceNumber; + headframe_info->totalSubSequenceNumber = sbc_decoder_frame->totalSubSequenceNumber; + }else{ + memset(headframe_info, 0, sizeof(A2DP_AUDIO_HEADFRAME_INFO_T)); + } + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_sbc_info_get(void *info) +{ + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_sbc_synchronize_packet(A2DP_AUDIO_SYNCFRAME_INFO_T *sync_info, uint32_t mask) +{ + int nRet = A2DP_DECODER_SYNC_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + int list_len; + a2dp_audio_sbc_decoder_frame_t *sbc_decoder_frame = NULL; + +#ifdef A2DP_CP_ACCEL + a2dp_cp_reset_frame(); +#endif + + list_len = a2dp_audio_list_length(list); + + for (uint16_t i=0; isequenceNumber == sync_info->sequenceNumber, A2DP_AUDIO_SYNCFRAME_MASK_SEQ, mask)&& + A2DP_AUDIO_SYNCFRAME_CHK(sbc_decoder_frame->curSubSequenceNumber == sync_info->curSubSequenceNumber, A2DP_AUDIO_SYNCFRAME_MASK_CURRSUBSEQ, mask)&& + A2DP_AUDIO_SYNCFRAME_CHK(sbc_decoder_frame->totalSubSequenceNumber == sync_info->totalSubSequenceNumber,A2DP_AUDIO_SYNCFRAME_MASK_TOTALSUBSEQ,mask)){ + nRet = A2DP_DECODER_NO_ERROR; + break; + } + a2dp_audio_list_remove(list, sbc_decoder_frame); + } + } + + node = a2dp_audio_list_begin(list); + if (node){ + sbc_decoder_frame = (a2dp_audio_sbc_decoder_frame_t *)a2dp_audio_list_node(node); + TRACE_A2DP_DECODER_I("[MCU][SYNC][SBC] sync pkt nRet:%d SEQ:%d timestamp:%d %d/%d", + nRet, sbc_decoder_frame->sequenceNumber, sbc_decoder_frame->timestamp, + sbc_decoder_frame->curSubSequenceNumber, sbc_decoder_frame->totalSubSequenceNumber); + }else{ + TRACE_A2DP_DECODER_I("[MCU][SYNC][SBC] sync pkt nRet:%d", nRet); + } + + return nRet; +} + +int a2dp_audio_sbc_synchronize_dest_packet_mut(uint16_t packet_mut) +{ + list_node_t *node = NULL; + uint32_t list_len = 0; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_sbc_decoder_frame_t *sbc_decoder_frame = NULL; + + list_len = a2dp_audio_list_length(list); + if (list_len > packet_mut){ + do{ + node = a2dp_audio_list_begin(list); + if (node){ + sbc_decoder_frame = (a2dp_audio_sbc_decoder_frame_t *)a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, sbc_decoder_frame); + } + }while(a2dp_audio_list_length(list) > packet_mut); + } + + TRACE_A2DP_DECODER_I("[MCU][SYNC][SBC] dest pkt list:%d", a2dp_audio_list_length(list)); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_sbc_convert_list_to_samples(uint32_t *samples) +{ + uint32_t list_len = 0; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + + list_len = a2dp_audio_list_length(list); + *samples = SBC_LIST_SAMPLES*list_len; + + TRACE_A2DP_DECODER_I("[MCU][SBC] list:%d samples:%d", list_len, *samples); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_sbc_discards_samples(uint32_t samples) +{ + int nRet = A2DP_DECODER_SYNC_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_sbc_decoder_frame_t *sbc_decoder_frame = NULL; + list_node_t *node = NULL; + int need_remove_list = 0; + uint32_t list_samples = 0; + ASSERT_A2DP_DECODER(!(samples%SBC_LIST_SAMPLES), "%s samples err:%d", __func__, samples); + + a2dp_audio_sbc_convert_list_to_samples(&list_samples); + if (list_samples >= samples){ + need_remove_list = samples/SBC_LIST_SAMPLES; + for (int i=0; i +#include "heap_api.h" +#include "hal_location.h" +#include "a2dp_decoder_internal.h" +#include "app_audio.h" +#if defined(A2DP_SCALABLE_ON) +#include "heap_api.h" +#include "ssc.h" + +#define SCALABLE_MTU_LIMITER (32) +#define SCALABLE_MEMPOOL_SIZE 1024 + +#define SCALABLE_OUTPUT_FRAME_SAMPLES (SCALABLE_FRAME_SIZE) + +typedef void *HANDLE_DECODER; +static A2DP_AUDIO_CONTEXT_T *a2dp_audio_context_p = NULL; +static A2DP_AUDIO_OUTPUT_CONFIG_T output_config; + +static unsigned char *scalable_decoder_place = NULL; +static unsigned char *scalable_decoder_temp_buf = NULL; +static short ss_pcm_buff[SCALABLE_FRAME_SIZE*4]; +static int scalable_uhq_flag __attribute__((unused)) = 0; + +static HANDLE_DECODER scalableDec_handle = NULL; + +static A2DP_AUDIO_DECODER_LASTFRAME_INFO_T lastframe_info; + + +typedef struct { + uint16_t sequenceNumber; + uint32_t timestamp; + uint8_t *buffer; + int buffer_len; +} a2dp_audio_scalable_decoder_frame_t; + +static void ss_to_24bit_buf(int32_t * out, int32_t * in, int size) +{ + for (int i = 0; i < size; i++) { + out[i] = in[i]; + } +} + +static void a2dp_audio_scalable_decoder_init(void) +{ + if (scalableDec_handle == NULL) { + scalableDec_handle = scalable_decoder_place; + + + ssc_decoder_init(scalableDec_handle, output_config.num_channels, output_config.sample_rate); + + } +} + +static int scalableDecoder_Close(HANDLE_DECODER handle) +{ + if (handle) { + a2dp_audio_heap_free(handle); + a2dp_audio_heap_free(scalable_decoder_temp_buf); + } + + return 0; +} + +static void a2dp_audio_scalable_decoder_deinit(void) +{ + if (scalableDec_handle) { + scalableDecoder_Close(scalableDec_handle); + scalableDec_handle = NULL; + } +} + +static void a2dp_audio_scalable_decoder_reinit(void) +{ + if (scalableDec_handle) { + a2dp_audio_scalable_decoder_deinit(); + } + a2dp_audio_scalable_decoder_init(); +} + +static bool is_valid_frame(a2dp_audio_scalable_decoder_frame_t * decoder_frame_p) +{ + int hw_tmp, len, bitrate_bps, frame_len, frame_size; + + int sampling_rate = 44100; + unsigned char *input_buf = decoder_frame_p->buffer; + if (decoder_frame_p->buffer_len < SCALABLE_HEAD_SIZE) { + TRACE_A2DP_DECODER_E("invalid scalable a2dp frame, length < SCALABLE_HEAD_SIZE !!!!!!!"); + return false; + } + + scalable_uhq_flag = 0; + + switch ((input_buf[3]&0xf7)) { + case 0xF0: + bitrate_bps = 88000; + break; + case 0xF1: + bitrate_bps = 96000; + break; + case 0xF2: + bitrate_bps = 128000; + break; + case 0xF3: + bitrate_bps = 192000; + break; + case 0xF4: + bitrate_bps = 229000; + break; + case 0xF5: + scalable_uhq_flag = 1; + bitrate_bps = 328000; + sampling_rate = 96000; + break; + default: + bitrate_bps = 192000; + break; + } + + frame_size = SCALABLE_FRAME_SIZE; + + len = bitrate_bps * frame_size / sampling_rate / 8; + if (scalable_uhq_flag == 0) { + hw_tmp = (len * 3) >> 7; + len = hw_tmp + len; + len = len + ((len & 1) ^ 1); + } else { + len = 369; //744/2-4+1 + } + TRACE_A2DP_DECODER_D + ("scalable a2dp frame, length:%d bitrate:%d sampling_rate:%d", + decoder_frame_p->buffer_len, bitrate_bps, sampling_rate); + frame_len = SCALABLE_HEAD_SIZE + len - 1; + + if (decoder_frame_p->buffer_len < frame_len) { + TRACE_A2DP_DECODER_E + ("invalid scalable a2dp frame, length:%d < %d !!!!!!!", decoder_frame_p->buffer_len, frame_len); + return false; + } + return true; + +} + + +#ifdef A2DP_CP_ACCEL +struct A2DP_CP_scalable_IN_FRM_INFO_T { + uint16_t sequenceNumber; + uint32_t timestamp; +}; + +struct A2DP_CP_scalable_OUT_FRM_INFO_T { + struct A2DP_CP_scalable_IN_FRM_INFO_T in_info; + uint16_t frame_samples; + uint16_t decoded_frames; + uint16_t frame_idx; + uint16_t pcm_len; +}; + +static bool cp_codec_reset; +extern uint32_t app_bt_stream_get_dma_buffer_samples(void); + +TEXT_SSC_LOC static int a2dp_cp_scalable_mcu_decode(uint8_t * buffer, uint32_t buffer_bytes) +{ + a2dp_audio_scalable_decoder_frame_t *decoder_frame_p = NULL; + list_node_t *node = NULL; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int ret, dec_ret; + struct A2DP_CP_scalable_IN_FRM_INFO_T in_info; + struct A2DP_CP_scalable_OUT_FRM_INFO_T *p_out_info; + uint8_t *out; + uint32_t out_len; + uint32_t out_frame_len; + uint32_t cp_buffer_frames_max = 0; + + cp_buffer_frames_max = app_bt_stream_get_dma_buffer_samples()/2; + if (cp_buffer_frames_max %(lastframe_info.frame_samples) ){ + cp_buffer_frames_max = cp_buffer_frames_max /(lastframe_info.frame_samples) +1; + }else{ + cp_buffer_frames_max = cp_buffer_frames_max /(lastframe_info.frame_samples); + } + + out_frame_len = sizeof(*p_out_info) + buffer_bytes; + ret = a2dp_cp_decoder_init(out_frame_len, cp_buffer_frames_max * 2); + + ASSERT(ret == 0, "%s: a2dp_cp_decoder_init() failed: ret=%d", __func__, ret); + + while ((node = a2dp_audio_list_begin(list)) != NULL) { + decoder_frame_p = (a2dp_audio_scalable_decoder_frame_t *) + a2dp_audio_list_node(node); + + if (false == is_valid_frame(decoder_frame_p)) { + return A2DP_DECODER_DECODE_ERROR; + } + + in_info.sequenceNumber = decoder_frame_p->sequenceNumber; + in_info.timestamp = decoder_frame_p->timestamp; + + ret = a2dp_cp_put_in_frame(&in_info, sizeof(in_info), decoder_frame_p->buffer, decoder_frame_p->buffer_len); + if (ret) { + break; + } + + a2dp_audio_list_remove(list, decoder_frame_p); + } + + ret = a2dp_cp_get_full_out_frame((void **)&out, &out_len); + if (ret) { + return A2DP_DECODER_DECODE_ERROR; + } + if (out_len == 0) { + memset(buffer, 0, buffer_bytes); + a2dp_cp_consume_full_out_frame(); + return A2DP_DECODER_NO_ERROR; + } + ASSERT(out_len == out_frame_len, "%s: Bad out len %u (should be %u)", __func__, out_len, out_frame_len); + + p_out_info = (struct A2DP_CP_scalable_OUT_FRM_INFO_T *)out; + if (p_out_info->pcm_len) { + lastframe_info.sequenceNumber = p_out_info->in_info.sequenceNumber; + lastframe_info.timestamp = p_out_info->in_info.timestamp; + lastframe_info.curSubSequenceNumber = 0; + lastframe_info.totalSubSequenceNumber = 0; + lastframe_info.frame_samples = p_out_info->frame_samples; + lastframe_info.decoded_frames += p_out_info->decoded_frames; + lastframe_info.undecode_frames = + a2dp_audio_list_length(list) + a2dp_cp_get_in_frame_cnt_by_index(p_out_info->frame_idx) - 1; + a2dp_audio_decoder_internal_lastframe_info_set(&lastframe_info); + } + + if (p_out_info->pcm_len == buffer_bytes) { + memcpy(buffer, p_out_info + 1, p_out_info->pcm_len); + dec_ret = A2DP_DECODER_NO_ERROR; + } else { + dec_ret = A2DP_DECODER_DECODE_ERROR; + } + + ret = a2dp_cp_consume_full_out_frame(); + ASSERT(ret == 0, "%s: a2dp_cp_consume_full_out_frame() failed: ret=%d", __func__, ret); + + return dec_ret; +} + +TEXT_SSC_LOC int a2dp_cp_scalable_cp_decode(void) +{ + int ret; + enum CP_EMPTY_OUT_FRM_T out_frm_st; + uint8_t *out; + uint32_t out_len; + uint8_t *dec_start; + uint32_t dec_len; + struct A2DP_CP_scalable_IN_FRM_INFO_T *p_in_info; + struct A2DP_CP_scalable_OUT_FRM_INFO_T *p_out_info; + uint8_t *in_buf; + uint32_t in_len; + uint32_t dec_sum; + int error, output_samples = 0,output_byte = 0; + + if (cp_codec_reset) + { + cp_codec_reset = false; + a2dp_audio_scalable_decoder_init(); + } + + out_frm_st = a2dp_cp_get_emtpy_out_frame((void **)&out, &out_len); + + if (out_frm_st != CP_EMPTY_OUT_FRM_OK && out_frm_st != CP_EMPTY_OUT_FRM_WORKING) + { + return 1; + } + + ASSERT(out_len > sizeof(*p_out_info), "%s: Bad out_len %u (should > %u)", __func__, out_len, sizeof(*p_out_info)); + + p_out_info = (struct A2DP_CP_scalable_OUT_FRM_INFO_T *)out; + if (out_frm_st == CP_EMPTY_OUT_FRM_OK) + { + p_out_info->pcm_len = 0; + p_out_info->decoded_frames = 0; + } + + ASSERT(out_len > sizeof(*p_out_info) + p_out_info->pcm_len, + "%s: Bad out_len %u (should > %u + %u)", __func__, out_len, sizeof(*p_out_info), p_out_info->pcm_len); + + dec_start = (uint8_t *) (p_out_info + 1) + p_out_info->pcm_len; + dec_len = out_len - (dec_start - (uint8_t *) out); + if (!scalableDec_handle) { + TRACE(0,"scalable_decode not ready"); + return 3; + } + + dec_sum = 0; + error = 0; + + while (dec_sum < dec_len && error == 0) + { + ret = a2dp_cp_get_in_frame((void * *) &in_buf, &in_len); + + if (ret) + { + break; + } + + ASSERT(in_len > sizeof(*p_in_info), "%s: Bad in_len %u (should > %u)", __func__, in_len, sizeof(*p_in_info)); + p_in_info = (struct A2DP_CP_scalable_IN_FRM_INFO_T *)in_buf; + in_buf += sizeof(*p_in_info); + in_len -= sizeof(*p_in_info); + /* decode one SSC frame */ + output_samples = ssc_decode(scalableDec_handle,(const unsigned char*)in_buf, ss_pcm_buff, SCALABLE_FRAME_SIZE, 0, 2); + if (0 == output_samples) + { + a2dp_audio_scalable_decoder_reinit(); + TRACE(0, "scalable_decode reinin codec \n"); + error = A2DP_DECODER_DECODE_ERROR; + goto exit; + } + + ss_to_24bit_buf((int32_t *) (dec_start+dec_sum), (int32_t *) ss_pcm_buff, output_samples); + output_byte = output_samples * 4; + dec_sum += output_byte; +exit: + memcpy(&p_out_info->in_info, ss_pcm_buff, sizeof(*p_in_info)); + p_out_info->decoded_frames++; + p_out_info->frame_samples = SCALABLE_OUTPUT_FRAME_SAMPLES; + p_out_info->frame_idx = a2dp_cp_get_in_frame_index(); + + ret = a2dp_cp_consume_in_frame(); + ASSERT(ret == 0, "%s: a2dp_cp_consume_in_frame() failed: ret=%d", __func__, ret); + } + + p_out_info->pcm_len += dec_sum; + + if (error || out_len <= sizeof(*p_out_info) + p_out_info->pcm_len) { + ret = a2dp_cp_consume_emtpy_out_frame(); + ASSERT(ret == 0, "%s: a2dp_cp_consume_emtpy_out_frame() failed: ret=%d", __func__, ret); + } + + return error; +} +#endif + +static int a2dp_audio_scalable_init(A2DP_AUDIO_OUTPUT_CONFIG_T * config, void *context) +{ + TRACE_A2DP_DECODER_D("%s", __func__); + + TRACE(0,"\n\nA2DP SSC-LC INIT\n"); + + a2dp_audio_context_p = (A2DP_AUDIO_CONTEXT_T *) context; + + memcpy(&output_config, config, sizeof(A2DP_AUDIO_OUTPUT_CONFIG_T)); + + memset(&lastframe_info, 0, sizeof(A2DP_AUDIO_DECODER_LASTFRAME_INFO_T)); + lastframe_info.stream_info = output_config; + lastframe_info.frame_samples = SCALABLE_FRAME_SIZE; + lastframe_info.list_samples = SCALABLE_FRAME_SIZE; + a2dp_audio_decoder_internal_lastframe_info_set(&lastframe_info); + + ASSERT(a2dp_audio_context_p->dest_packet_mut < SCALABLE_MTU_LIMITER, + "%s MTU OVERFLOW:%u/%u", __func__, a2dp_audio_context_p->dest_packet_mut, SCALABLE_MTU_LIMITER); + + int decoder_size; + + decoder_size = ssc_decoder_get_size(output_config.num_channels); //todo: get size with codec capability + + TRACE(0, "decoder size %d", decoder_size); + + scalable_decoder_place = (unsigned char *)a2dp_audio_heap_malloc(decoder_size); + ASSERT_A2DP_DECODER(scalable_decoder_place, "no memory resource for scalable_decoder_place"); + + scalable_decoder_temp_buf = (unsigned char *)a2dp_audio_heap_malloc(SCALABLE_FRAME_SIZE * 16); + ASSERT_A2DP_DECODER(scalable_decoder_temp_buf, "no memory resource for scalable_decoder_temp_buf"); + +#ifdef A2DP_CP_ACCEL + int ret; + cp_codec_reset = true; + ret = a2dp_cp_init(a2dp_cp_scalable_cp_decode, CP_PROC_DELAY_1_FRAME); + ASSERT(ret == 0, "%s: a2dp_cp_init() failed: ret=%d", __func__, ret); +#else + a2dp_audio_scalable_decoder_init(); +#endif + + return A2DP_DECODER_NO_ERROR; +} + +static int a2dp_audio_scalable_deinit(void) +{ +#ifdef A2DP_CP_ACCEL + a2dp_cp_deinit(); +#endif + + a2dp_audio_scalable_decoder_deinit(); + + TRACE(0,"\n\nA2DP SCALABLE DEINIT\n"); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_scalable_mcu_decode_frame(uint8_t * buffer, uint32_t buffer_bytes) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_scalable_decoder_frame_t *decoder_frame_p = NULL; + int ret = A2DP_DECODER_NO_ERROR; + + bool cache_underflow = false; + int output_byte = 0, output_samples = 0; + uint8_t *output = buffer; + // TRACE(1,"bbd %d",buffer_bytes ); + if (buffer_bytes < (SCALABLE_FRAME_SIZE * output_config.num_channels * output_config.bits_depth / 8)) { + TRACE(1,"scalable_decode pcm_len = %d \n", buffer_bytes); + return A2DP_DECODER_NO_ERROR; + } + if (!scalableDec_handle) { + TRACE(0,"scalable_decode not ready"); + return A2DP_DECODER_NO_ERROR; + } + + while (output < buffer + buffer_bytes) { + node = a2dp_audio_list_begin(list); + if (!node) { + TRACE(0,"scalable_decode cache underflow"); + cache_underflow = true; + goto exit; + } else { + decoder_frame_p = (a2dp_audio_scalable_decoder_frame_t *) + a2dp_audio_list_node(node); + + if (false == is_valid_frame(decoder_frame_p)) { + TRACE_A2DP_DECODER_E("%s %d invalid a2dp frame", __func__, __LINE__); + ret = A2DP_DECODER_DECODE_ERROR; + goto exit; + } + + /* decode one SSC frame */ + output_samples = + ssc_decode(scalableDec_handle, + decoder_frame_p->buffer, ss_pcm_buff, SCALABLE_FRAME_SIZE,0,2); + + TRACE_A2DP_DECODER_D + ("scalable_decode seq:%d len:%d output_samples:%d", + decoder_frame_p->sequenceNumber, decoder_frame_p->buffer_len, output_samples); + + if (0 == output_samples) { + TRACE(0,"scalable_decode failed !!!!!!"); + //if failed reopen it again + a2dp_audio_scalable_decoder_reinit(); + TRACE(0,"scalable_decode reinin codec \n"); + ret = A2DP_DECODER_DECODE_ERROR; + goto exit; + } + ss_to_24bit_buf((int32_t *) output, (int32_t *) ss_pcm_buff, output_samples * 2); + output_byte = output_samples * 8; + + + output += output_byte; + ASSERT(SCALABLE_FRAME_SIZE == output_samples, "scalable_decode output mismatch samples:%d", output_samples); + lastframe_info.sequenceNumber = decoder_frame_p->sequenceNumber; + lastframe_info.timestamp = decoder_frame_p->timestamp; + lastframe_info.curSubSequenceNumber = 0; + lastframe_info.totalSubSequenceNumber = 0; + lastframe_info.frame_samples = SCALABLE_FRAME_SIZE; + lastframe_info.decoded_frames++; + lastframe_info.undecode_frames = a2dp_audio_list_length(list) - 1; + a2dp_audio_decoder_internal_lastframe_info_set(&lastframe_info); + a2dp_audio_list_remove(list, decoder_frame_p); + + } + + } + + exit: + if (cache_underflow) { + lastframe_info.undecode_frames = 0; + a2dp_audio_decoder_internal_lastframe_info_set(&lastframe_info); + ret = A2DP_DECODER_CACHE_UNDERFLOW_ERROR; + } + //TRACE(0,"abd"); + return ret; +} + +static int a2dp_audio_scalable_decode_frame(uint8_t * buffer, uint32_t buffer_bytes) +{ +#ifdef A2DP_CP_ACCEL + return a2dp_cp_scalable_mcu_decode(buffer, buffer_bytes); +#else + return a2dp_audio_scalable_mcu_decode_frame(buffer, buffer_bytes); +#endif +} + +static int a2dp_audio_scalable_preparse_packet(btif_media_header_t * header, uint8_t * buffer, uint32_t buffer_bytes) +{ + lastframe_info.sequenceNumber = header->sequenceNumber; + lastframe_info.timestamp = header->timestamp; + lastframe_info.curSubSequenceNumber = 0; + lastframe_info.totalSubSequenceNumber = 0; + lastframe_info.frame_samples = SCALABLE_FRAME_SIZE; + lastframe_info.list_samples = SCALABLE_FRAME_SIZE; + lastframe_info.decoded_frames = 0; + lastframe_info.undecode_frames = 0; + a2dp_audio_decoder_internal_lastframe_info_set(&lastframe_info); + + TRACE(3,"%s seq:%d timestamp:%08x", __func__, header->sequenceNumber, header->timestamp); + + return A2DP_DECODER_NO_ERROR; +} + +static void *a2dp_audio_scalable_frame_malloc(uint32_t packet_len) +{ + a2dp_audio_scalable_decoder_frame_t *decoder_frame_p = NULL; + uint8_t *buffer = NULL; + + buffer = (uint8_t *) a2dp_audio_heap_malloc(SCALABLE_READBUF_SIZE); + decoder_frame_p = (a2dp_audio_scalable_decoder_frame_t *) + a2dp_audio_heap_malloc(sizeof(a2dp_audio_scalable_decoder_frame_t)); + decoder_frame_p->buffer = buffer; + decoder_frame_p->buffer_len = packet_len; + return (void *)decoder_frame_p; +} + +static void a2dp_audio_scalable_free(void *packet) +{ + a2dp_audio_scalable_decoder_frame_t *decoder_frame_p = (a2dp_audio_scalable_decoder_frame_t *) packet; + a2dp_audio_heap_free(decoder_frame_p->buffer); + a2dp_audio_heap_free(decoder_frame_p); +} + +static int a2dp_audio_scalable_store_packet(btif_media_header_t * header, uint8_t * buffer, uint32_t buffer_bytes) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + int nRet = A2DP_DECODER_NO_ERROR; + if (a2dp_audio_list_length(list) < SCALABLE_MTU_LIMITER) { + a2dp_audio_scalable_decoder_frame_t *decoder_frame_p = (a2dp_audio_scalable_decoder_frame_t *) + a2dp_audio_scalable_frame_malloc(buffer_bytes); + TRACE_A2DP_DECODER_D("%s seq:%d len:%d", __func__, header->sequenceNumber, buffer_bytes); + decoder_frame_p->sequenceNumber = header->sequenceNumber; + decoder_frame_p->timestamp = header->timestamp; + memcpy(decoder_frame_p->buffer, buffer, buffer_bytes); + decoder_frame_p->buffer_len = buffer_bytes; + a2dp_audio_list_append(list, decoder_frame_p); + nRet = A2DP_DECODER_NO_ERROR; + } else { + TRACE(2,"%s list full current len:%d", __func__, a2dp_audio_list_length(list)); + nRet = A2DP_DECODER_MTU_LIMTER_ERROR; + } + + return nRet; +} + +static int a2dp_audio_scalable_discards_packet(uint32_t packets) +{ + int nRet = A2DP_DECODER_MEMORY_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_scalable_decoder_frame_t *decoder_frame_p = NULL; + +#ifdef A2DP_CP_ACCEL + a2dp_cp_reset_frame(); +#endif + + if (packets <= a2dp_audio_list_length(list)) { + for (uint8_t i = 0; i < packets; i++) { + if ((node = a2dp_audio_list_begin(list)) != NULL){ + decoder_frame_p = (a2dp_audio_scalable_decoder_frame_t *) + a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, decoder_frame_p); + } + } + nRet = A2DP_DECODER_NO_ERROR; + } + + TRACE(3,"%s packets:%d nRet:%d", __func__, packets, nRet); + return nRet; +} + +static int a2dp_audio_scalable_headframe_info_get(A2DP_AUDIO_HEADFRAME_INFO_T* headframe_info) +{ + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + a2dp_audio_scalable_decoder_frame_t *decoder_frame_p = NULL; + + if (a2dp_audio_list_length(list)){ + if ((node = a2dp_audio_list_begin(list)) != NULL){ + decoder_frame_p = (a2dp_audio_scalable_decoder_frame_t *)a2dp_audio_list_node(node); + headframe_info->sequenceNumber = decoder_frame_p->sequenceNumber; + headframe_info->timestamp = decoder_frame_p->timestamp; + headframe_info->curSubSequenceNumber = 0; + headframe_info->totalSubSequenceNumber = 0; + } + }else{ + memset(headframe_info, 0, sizeof(A2DP_AUDIO_HEADFRAME_INFO_T)); + } + + return A2DP_DECODER_NO_ERROR; +} + +static int a2dp_audio_scalable_info_get(void *info) +{ + return A2DP_DECODER_NO_ERROR; +} + +static int a2dp_audio_scalable_synchronize_packet(A2DP_AUDIO_SYNCFRAME_INFO_T * sync_info, uint32_t mask) +{ + int nRet = A2DP_DECODER_SYNC_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + list_node_t *node = NULL; + int list_len; + a2dp_audio_scalable_decoder_frame_t *decoder_frame_p = NULL; + +#ifdef A2DP_CP_ACCEL + a2dp_cp_reset_frame(); +#endif + + list_len = a2dp_audio_list_length(list); + + for (uint16_t i = 0; i < list_len; i++) { + if ((node = a2dp_audio_list_begin(list)) != NULL){ + decoder_frame_p = (a2dp_audio_scalable_decoder_frame_t *) + a2dp_audio_list_node(node); + if (A2DP_AUDIO_SYNCFRAME_CHK(decoder_frame_p->sequenceNumber == sync_info->sequenceNumber, A2DP_AUDIO_SYNCFRAME_MASK_SEQ, mask)&& + A2DP_AUDIO_SYNCFRAME_CHK(decoder_frame_p->timestamp == sync_info->timestamp, A2DP_AUDIO_SYNCFRAME_MASK_TIMESTAMP, mask)) { + nRet = A2DP_DECODER_NO_ERROR; + break; + } + a2dp_audio_list_remove(list, decoder_frame_p); + } + } + + node = a2dp_audio_list_begin(list); + if (node) { + decoder_frame_p = (a2dp_audio_scalable_decoder_frame_t *) + a2dp_audio_list_node(node); + TRACE(4,"%s nRet:%d SEQ:%d timestamp:%d", __func__, nRet, + decoder_frame_p->sequenceNumber, decoder_frame_p->timestamp); + } else { + TRACE(2,"%s nRet:%d", __func__, nRet); + } + + return nRet; +} + +static int a2dp_audio_scalable_synchronize_dest_packet_mut(uint16_t packet_mut) +{ + list_node_t *node = NULL; + uint32_t list_len = 0; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_scalable_decoder_frame_t *decoder_frame_p = NULL; + + list_len = a2dp_audio_list_length(list); + if (list_len > packet_mut) { + do { + node = a2dp_audio_list_begin(list); + if (node) + { + decoder_frame_p = (a2dp_audio_scalable_decoder_frame_t *) + a2dp_audio_list_node(node); + a2dp_audio_list_remove(list, decoder_frame_p); + } + } while (a2dp_audio_list_length(list) > packet_mut); + } + + TRACE(2,"%s list:%d", __func__, a2dp_audio_list_length(list)); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_scalable_convert_list_to_samples(uint32_t *samples) +{ + uint32_t list_len = 0; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + + list_len = a2dp_audio_list_length(list); + *samples = SCALABLE_FRAME_SIZE*list_len; + + TRACE(3, "%s list:%d samples:%d", __func__, list_len, *samples); + + return A2DP_DECODER_NO_ERROR; +} + +int a2dp_audio_scalable_discards_samples(uint32_t samples) +{ + int nRet = A2DP_DECODER_SYNC_ERROR; + list_t *list = a2dp_audio_context_p->audio_datapath.input_raw_packet_list; + a2dp_audio_scalable_decoder_frame_t *scalable_decoder_frame = NULL; + list_node_t *node = NULL; + int need_remove_list = 0; + uint32_t list_samples = 0; + ASSERT(!(samples%SCALABLE_FRAME_SIZE), "%s samples err:%d", __func__, samples); + + a2dp_audio_scalable_convert_list_to_samples(&list_samples); + if (list_samples >= samples){ + need_remove_list = samples/SCALABLE_FRAME_SIZE; + for (int i=0; i +#include +#include +#include +#include +#include "tgt_hardware.h" +#ifdef MBED +#include "SDFileSystem.h" +#endif +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_codec.h" +#include "audioflinger.h" +#include "cqueue.h" +#include "app_audio.h" +#include "app_overlay.h" +#include "analog.h" +#ifdef RTOS +#include "cmsis_os.h" +#endif + + +extern "C" { +#if defined(A2DP_LHDC_ON) +#include "hal_sysfreq.h" +#include "lhdcUtil.h" +#endif +} + +extern "C" { +#if defined(A2DP_LDAC_ON) +#include "hal_sysfreq.h" +//#include "speech_memory.h" +#include"ldacBT.h" +#define MED_MEM_HEAP_SIZE (1024*20) +HANDLE_LDAC_BT hLdacData = NULL; +#endif +} + +#include "a2dp_api.h" + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) +#include "hal_sysfreq.h" +#include "hal_chipid.h" +#include "audio_resample_ex.h" +#endif + +#include "btapp.h" +#include "hal_location.h" +#include "cmsis.h" + +#define TEXT_A2DP_LOC_A(n, l) __attribute__((section(#n "." #l))) +#define TEXT_A2DP_LOC(n, l) TEXT_A2DP_LOC_A(n, l) + +#define TEXT_SBC_LOC TEXT_A2DP_LOC(.overlay_a2dp_sbc, __LINE__) +#define TEXT_AAC_LOC TEXT_A2DP_LOC(.overlay_a2dp_aac, __LINE__) +#define TEXT_SSC_LOC TEXT_A2DP_LOC(.overlay_a2dp_ssc, __LINE__) +#define TEXT_LDAC_LOC TEXT_A2DP_LOC(.overlay_a2dp_ldac, __LINE__) +#define TEXT_LHDC_LOC TEXT_A2DP_LOC(.overlay_a2dp_lhdc, __LINE__) + +//#define A2DP_AUDIO_SYNC_WITH_LOCAL (1) + +#define A2DP_AUDIO_SYNC_TRACE(s,...) +//TRACE(s, ##__VA_ARGS__) + +#ifdef A2DP_AUDIO_SYNC_WITH_LOCAL +#define A2DP_AUDIO_SYNC_WITH_LOCAL_SAMPLERATE_DEFAULT (0) +#define A2DP_AUDIO_SYNC_WITH_LOCAL_SAMPLERATE_INC (2) +#define A2DP_AUDIO_SYNC_WITH_LOCAL_SAMPLERATE_DEC (-2) +#define A2DP_AUDIO_SYNC_WITH_LOCAL_SAMPLERATE_STEP (0.00005f) +#define A2DPPLAY_SYNC_STATUS_SET (0x01) +#define A2DPPLAY_SYNC_STATUS_RESET (0x02) +#define A2DPPLAY_SYNC_STATUS_PROC (0x04) + +enum A2DP_AUDIO_SYNC_STATUS { + A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_DEC, + A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_INC, + A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_DEFAULT, +}; +#endif + +#define A2DPPLAY_CACHE_OK_THRESHOLD (sbc_frame_size<<6) + +enum A2DPPLAY_STRTEAM_T { + A2DPPLAY_STRTEAM_PUT= 0, + A2DPPLAY_STRTEAM_GET, + A2DPPLAY_STRTEAM_QTY, +}; + +/* sbc queue */ +#define SBC_TEMP_BUFFER_SIZE 128 +#define SBC_QUEUE_SIZE_DEFAULT (SBC_TEMP_BUFFER_SIZE*64) +#define SBC_QUEUE_SIZE (1024*11) + +/* sbc decoder */ +static bool need_init_decoder = true; +static btif_sbc_decoder_t* sbc_decoder = NULL; + +static float sbc_eq_band_gain[CFG_HW_AUD_EQ_NUM_BANDS]; + +CQueue sbc_queue; + +static uint32_t g_sbc_queue_size = SBC_QUEUE_SIZE_DEFAULT; +static uint16_t sbc_frame_size = SBC_TEMP_BUFFER_SIZE; +static uint16_t sbc_frame_rev_len = 0; +static uint16_t sbc_frame_num = 0; +static uint32_t assumed_mtu_interval = 0; + +static uint32_t dec_start_time; +static uint32_t last_dec_time; +#ifdef A2DP_TRACE_DEC_TIME +static const bool dec_trace_time = true; +#else +static bool dec_trace_time; +#endif +static bool dec_reset_queue; + +static enum APP_AUDIO_CACHE_T a2dp_cache_status = APP_AUDIO_CACHE_QTY; + +#define A2DP_SYNC_WITH_GET_MUTUX_TIMEROUT_CNT (5) +#define A2DP_SYNC_WITH_GET_MUTUX_TIMEROUT_MS (20) +static osThreadId a2dp_put_thread_tid = NULL; +static bool a2dp_get_need_sync = false; + +extern enum AUD_SAMPRATE_T a2dp_sample_rate; +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) +#ifdef CHIP_BEST1000 +static bool allow_resample = false; +#else +static const bool allow_resample = true; +#endif +#endif + +extern int a2dp_timestamp_parser_needsync(void); + +#define A2DP_SYNC_WITH_GET_MUTUX_ALLOC() do{ \ + if (a2dp_put_thread_tid == NULL){ \ + a2dp_put_thread_tid = osThreadGetId(); \ + } \ + }while(0) + +#define A2DP_SYNC_WITH_GET_MUTUX_FREE() do{ \ + a2dp_put_thread_tid = NULL; \ + }while(0) + +#define A2DP_SYNC_WITH_GET_MUTUX_WAIT() do{ \ + a2dp_get_need_sync = true; \ + if (a2dp_put_thread_tid){ \ + osSignalClear(a2dp_put_thread_tid, 0x80); \ + osSignalWait(0x80, A2DP_SYNC_WITH_GET_MUTUX_TIMEROUT_MS); \ + }\ + }while(0) + +#define A2DP_SYNC_WITH_GET_MUTUX_SET() do{ \ + if (a2dp_get_need_sync){ \ + a2dp_get_need_sync = false; \ + if (a2dp_put_thread_tid){ \ + osSignalSet(a2dp_put_thread_tid, 0x80); \ + } \ + } \ + }while(0) + +//#define A2DP_SYNC_WITH_PUT_MUTUX (1) +#define A2DP_SYNC_WITH_PUT_MUTUX_TIMEROUT_CNT (1) +#define A2DP_SYNC_WITH_PUT_MUTUX_TIMEROUT_MS (3) +static osThreadId a2dp_get_thread_tid = NULL; +static bool a2dp_get_put_sync = false; + +#define A2DP_SYNC_WITH_PUT_MUTUX_ALLOC() do{ \ + if (a2dp_get_thread_tid == NULL){ \ + a2dp_get_thread_tid = osThreadGetId(); \ + } \ + }while(0) + +#define A2DP_SYNC_WITH_PUT_MUTUX_FREE() do{ \ + a2dp_get_thread_tid = NULL; \ + }while(0) + +#define A2DP_SYNC_WITH_PUT_MUTUX_WAIT() do{ \ + a2dp_get_put_sync = true; \ + if (a2dp_get_thread_tid){\ + osSignalClear(a2dp_get_thread_tid, 0x80); \ + osSignalWait(0x5, A2DP_SYNC_WITH_PUT_MUTUX_TIMEROUT_MS); \ + }\ + }while(0) + +#define A2DP_SYNC_WITH_PUT_MUTUX_SET() do{ \ + if (a2dp_get_put_sync){ \ + a2dp_get_put_sync = false; \ + if (a2dp_get_thread_tid){\ + osSignalSet(a2dp_get_thread_tid, 0x80); \ + }\ + } \ + }while(0) + + +int a2dp_audio_sbc_set_frame_info(int rcv_len, int frame_num) +{ + if ((!rcv_len)||(!frame_num)){ + return 0; + } + + if (sbc_frame_rev_len != rcv_len || sbc_frame_num != frame_num){ + sbc_frame_rev_len = rcv_len; + sbc_frame_num = frame_num; + sbc_frame_size = rcv_len/frame_num; + } + + return 0; +} + +extern struct BT_DEVICE_T app_bt_device; +extern uint8_t a2dp_channel_num[BT_DEVICE_NUM]; +void expand_1_channel_to_2_channels_16bits(unsigned char *in, unsigned int in_len) +{ + int cnt = 0; + int len = in_len; + short* ptr = (short*)in + in_len/2; + short* ptr_out = (short*)in + in_len; + + while(len > 0){ + *(ptr_out - 2*cnt - 1) = *(ptr - cnt); + *(ptr_out - 2*cnt - 2) = *(ptr - cnt); + cnt += 1; + len -= 2; + } +} + +#ifdef A2DP_AUDIO_SYNC_WITH_LOCAL +static enum A2DP_AUDIO_SYNC_STATUS sync_status = A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_DEFAULT; + +static int a2dp_audio_sync_proc(uint8_t status, int shift) +{ +#if !(defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE)) + struct AF_STREAM_CONFIG_T *cfg; + + bool need_shift = false; + static int cur_shift = 0; + static int dest_shift = 0; + + LOCK_APP_AUDIO_QUEUE(); + if (status & A2DPPLAY_SYNC_STATUS_RESET){ + sync_status = A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_DEFAULT; + cur_shift = 0; + dest_shift = 0; + } + if (status & A2DPPLAY_SYNC_STATUS_SET){ + dest_shift = shift; + } + if (cur_shift > dest_shift){ + cur_shift--; + need_shift = true; + } + if (cur_shift= A2DPPLAY_STRTEAM_QTY) + return false; + + stream_running[stream] = run; + + if (stream_running[A2DPPLAY_STRTEAM_PUT] && stream_running[A2DPPLAY_STRTEAM_GET]) + return true; + else + return false; +} + +#if defined(A2DP_AAC_ON) +#define AAC_READBUF_SIZE (2048) + +uint32_t aac_maxreadBytes = AAC_READBUF_SIZE; +uint32_t aac_frame_mute = 0; + +int decode_aac_frame(unsigned char *pcm_buffer, unsigned int pcm_len); +#endif + +#if defined(A2DP_LHDC_ON) +#include "hal_timer.h" +#define A2DP_LHDC_DEFAULT_LATENCY 1 +uint8_t latencyIndex = 0; +uint8_t latencyUpdated = 0; + +uint16_t latencyTable[] = {50, 150, 300}; + +uint8_t magicTag[] = {'l','h','d','c'}; +typedef struct { + uint8_t tag[4]; + uint32_t packetLen; + uint8_t dptr[0]; +} LHDC_HEADER; + +typedef struct { + uint16_t frame_len; + bool isSplit; + bool isLeft; +} LHDC_FRAME_HDR; + +#define LHDC_READBUF_SIZE 1024 * 4 /* pick something big enough to hold a bunch of frames */ +uint8_t lhdcTempBuf[LHDC_READBUF_SIZE]; +uint8_t lhdc_input_mid_buf[LHDC_READBUF_SIZE]; +#define L2CAP_MTU 672 +#define PACKET_MTU_SIZE (L2CAP_MTU-12) + + +void initial_lhdc_assemble_packet(bool splitFlg); +/** + * get lhdc frame header + */ +bool get_lhdc_header(uint8_t * in, LHDC_FRAME_HDR * h); + +uint32_t get_lhdc_frame(uint8_t * frame_q, size_t q_available_size, uint8_t * out_buf, uint32_t * out_size, uint32_t * out_frames); +/** + * Grabe lhdc data from queue + */ +int get_lhdc_data(unsigned char * frame, unsigned int len); +int assemble_lhdc_packet(uint8_t * input, uint32_t input_len, + uint8_t** pLout, uint32_t * pLlen, + uint8_t** pRout, uint32_t * pRlen); + +#endif +#if defined(A2DP_LDAC_ON) +#define LDAC_FRAME_LEN_INDEX_106 106 +#define LDAC_FRAME_LEN_INDEX_128 128 +#define LDAC_FRAME_LEN_INDEX_160 160 +#define LDAC_FRAME_LEN_INDEX_216 216 +#define LDAC_FRAME_LEN_INDEX_326 326 + +uint8_t get_ldac_frame_num(uint16_t frame_length_index){ + uint8_t frame_num = 0; + switch(frame_length_index) + { + case LDAC_FRAME_LEN_INDEX_106: + frame_num = 6; + break; + case LDAC_FRAME_LEN_INDEX_128: + frame_num = 5; + break; + case LDAC_FRAME_LEN_INDEX_160: + frame_num = 4; + break; + case LDAC_FRAME_LEN_INDEX_216: + frame_num = 3; + break; + case LDAC_FRAME_LEN_INDEX_326: + frame_num = 2; + break; + default: + ASSERT(0, "Unknown ldac frame format: %d !!!!!",frame_length_index); + break; + } + return frame_num; +} +#endif + + +#define DELAY_MTU_LIMIT 8 + +static volatile int delay_mtu_limit = DELAY_MTU_LIMIT; +static volatile int mtu_count = 0; +static volatile int delay_mtu_count = 0; +bool app_bt_stream_trigger_onprocess(void); +void app_bt_stream_trigger_start(uint8_t offset); + +void a2dp_audio_set_mtu_limit(uint8_t mut) +{ + delay_mtu_limit = mut; +} + +static uint32_t old_t = 0; +static uint32_t ssb_err = 0; +static uint32_t ssb_err_max = 0; +static uint32_t ssb_err_min = 0xffffffff; +static uint32_t lagest_mtu_in1s = 0; +static uint32_t least_mtu_in1s = 0xffffffff; +static uint32_t check_interval = 50; + +int store_sbc_buffer(unsigned char *buf, unsigned int len) +{ + int POSSIBLY_UNUSED size; + int cnt = 0; + int nRet = 0; +#if defined(A2DP_LHDC_ON) + uint32_t newLen = 0; + bool mtu_plus = false; +#endif +#if defined(A2DP_LDAC_ON) + uint16_t frame_length_index = 0; +#endif + uint32_t now_t = TICKS_TO_MS(hal_sys_timer_get()); + ssb_err = now_t - old_t; + old_t = now_t; + + if(ssb_err < 500){ + if(ssb_err_max < ssb_err) + ssb_err_max = ssb_err; + if(ssb_err_min > ssb_err) + ssb_err_min = ssb_err; + } + + if (!a2dp_audio_isrunning(A2DPPLAY_STRTEAM_PUT, true)){ + TRACE(3,"%s not ready:%d cache_status:%d",__func__, len, a2dp_cache_status); + } + uint8_t overlay_id = app_get_current_overlay(); + + if(overlay_id == APP_OVERLAY_A2DP) + { + //TRACE(8,"sbc %d %x %x %x %x mtu_count:%d sbcqueue:%d,sbc_frame_rev_len=%d", len, buf[0], + // buf[1],buf[2],buf[3],mtu_count,APP_AUDIO_LengthOfCQueue(&sbc_queue),sbc_frame_rev_len); + } +#if defined(A2DP_LDAC_ON) + else if(overlay_id == APP_OVERLAY_A2DP_LDAC) + { + uint16_t data1 = (uint16_t)(buf[1]&0x07); + uint16_t data2 = (uint16_t)buf[2]; + frame_length_index = ((data1<< 6 &0xFFFF) | (data2 >> 2 & 0xFFFF)); + sbc_frame_num = get_ldac_frame_num(frame_length_index); + //TRACE(10,"ldac %d %d %x %x %x %x mtu_count:%d sbcqueue:%d,sbc_frame_rev_len=%d,sbc_frame_num %d", len, sbc_frame_size,buf[0], + // buf[1],buf[2],buf[3],mtu_count,APP_AUDIO_LengthOfCQueue(&sbc_queue),sbc_frame_rev_len,sbc_frame_num); + } +#endif + else + { + //TRACE(8,"AAC %d %x %x %x %x mtu_count:%d sbcqueue:%d,sbc_frame_rev_len=%d", len, buf[0], + // buf[1],buf[2],buf[3],mtu_count,APP_AUDIO_LengthOfCQueue(&sbc_queue),sbc_frame_rev_len); + } + + switch (a2dp_cache_status) { + case APP_AUDIO_CACHE_CACHEING: + { +#if defined(A2DP_LHDC_ON) + newLen = 0; + if(overlay_id == APP_OVERLAY_A2DP_LHDC){ + uint32_t lSize = 0, rSize = 0; + uint8_t *lPTR = NULL, *rPTR = NULL; + //TRACE(2,"%s:APP_AUDIO_CACHE_CACHEING Enter len = %d",__func__, len); + //TRACE(2,"%s: input len(%d)",__func__, len); + if (assemble_lhdc_packet(buf, len, &lPTR, &lSize, &rPTR, &rSize) > 0){ + if (lPTR != NULL && lSize != 0){ + newLen = lSize + sizeof(LHDC_HEADER); + memcpy(lhdcTempBuf + sizeof(LHDC_HEADER), lPTR, lSize); + memcpy(lhdcTempBuf, magicTag, sizeof(magicTag)); + memcpy(lhdcTempBuf + sizeof(magicTag), &lSize, sizeof(unsigned int)); + mtu_plus = true; + } + }else { + nRet = 0; + } + + } +#endif + + LOCK_APP_AUDIO_QUEUE(); +#if defined(A2DP_LHDC_ON) + if(overlay_id == APP_OVERLAY_A2DP_LHDC){ + nRet = APP_AUDIO_EnCQueue(&sbc_queue, lhdcTempBuf, newLen); + size = APP_AUDIO_LengthOfCQueue(&sbc_queue); + }else +#endif + +#if defined(A2DP_LDAC_ON) + if(overlay_id == APP_OVERLAY_A2DP_LDAC){ + //if(bt_sbc_player_get_codec_type() == BTIF_AVDTP_CODEC_TYPE_NON_A2DP){ + nRet = APP_AUDIO_EnCQueue(&sbc_queue, buf, len); + size = APP_AUDIO_LengthOfCQueue(&sbc_queue); + }else +#endif + +#if defined(A2DP_AAC_ON) + if(overlay_id == APP_OVERLAY_A2DP_AAC){ + nRet = AvailableOfCQueue(&sbc_queue); + if (nRet >= (int)(len + 2)) + { + nRet = APP_AUDIO_EnCQueue(&sbc_queue, (uint8_t *)&len, 2); + nRet = APP_AUDIO_EnCQueue(&sbc_queue, buf, len); + } + else + nRet = CQ_ERR; + }else +#endif + + { + nRet = APP_AUDIO_EnCQueue(&sbc_queue, buf, len); + } + size = APP_AUDIO_LengthOfCQueue(&sbc_queue); +#if defined(A2DP_LHDC_ON) + if(overlay_id == APP_OVERLAY_A2DP_LHDC){ + if (mtu_plus) { + if (delay_mtu_count == 0) + mtu_count = 0; + delay_mtu_count++; + mtu_count++; + mtu_plus = false; + } + }else{ +#endif + if(overlay_id == APP_OVERLAY_A2DP +#if defined(A2DP_LDAC_ON) + || overlay_id == APP_OVERLAY_A2DP_LDAC +#endif + ){ + if (delay_mtu_count == 0) + mtu_count = 0; + delay_mtu_count += sbc_frame_num; + mtu_count += sbc_frame_num; +// TRACE(1,"+mtu_count = %d",mtu_count); + }else{ + if (delay_mtu_count == 0) + mtu_count = 0; + delay_mtu_count++; + mtu_count++; + } +#if defined(A2DP_LHDC_ON) + } +#endif + UNLOCK_APP_AUDIO_QUEUE(); + bool flag = 0; +#if defined(A2DP_AAC_ON) + if(overlay_id == APP_OVERLAY_A2DP_AAC) + flag = 1; +#endif +#if defined(A2DP_SCALABLE_ON) + if(overlay_id == APP_OVERLAY_A2DP_SCALABLE) + flag = 1; +#endif +#if defined(A2DP_LHDC_ON) + if(overlay_id == APP_OVERLAY_A2DP_LHDC) + flag = 1; +#endif +#if defined(A2DP_LDAC_ON) + if(overlay_id == APP_OVERLAY_A2DP_LDAC) + { + flag = 1; + TRACE(0,"y# ldac cache"); + } +#endif + + if(flag) + { +#ifdef __A2DP_PLAYER_USE_BT_TRIGGER__ + if(app_bt_stream_trigger_onprocess()&&mtu_count){ + TRACE(0,"cache ok use dma trigger\n"); + a2dp_cache_status = APP_AUDIO_CACHE_OK; + app_bt_stream_trigger_start(0); + } +#else + if (delay_mtu_count >= delay_mtu_limit){ + TRACE(2,"aac cache ok:%d,mtu_count=%d\n", size,mtu_count); + a2dp_cache_status = APP_AUDIO_CACHE_OK; + } +#endif + }else{ +#ifdef __A2DP_PLAYER_USE_BT_TRIGGER__ + if(app_bt_stream_trigger_onprocess()&&mtu_count){ + TRACE(0,"cache ok use dma trigger\n"); + a2dp_cache_status = APP_AUDIO_CACHE_OK; + app_bt_stream_trigger_start(0); + } +#else + if (delay_mtu_count >= delay_mtu_limit){ + TRACE(4,"cache ok:%d,%d,%d,mtu_count=%d\n", size,len,sbc_frame_size,mtu_count); + a2dp_cache_status = APP_AUDIO_CACHE_OK; + }else if (sbc_frame_size && (size>=A2DPPLAY_CACHE_OK_THRESHOLD)){ + TRACE(2,"cache ok:%d,mtu_count=%d\n", size,mtu_count); + a2dp_cache_status = APP_AUDIO_CACHE_OK; + }else{ + TRACE(1,"cache add:%d\n", len); + } +#endif + } + + if(nRet == CQ_ERR){ + TRACE(0,"cache add overflow\n"); + a2dp_cache_status = APP_AUDIO_CACHE_OK; + } + if (a2dp_cache_status == APP_AUDIO_CACHE_OK){ + old_t = 0; + ssb_err = 0; + ssb_err_max = 0; + ssb_err_min = 0xffffffff; + lagest_mtu_in1s = 0; + least_mtu_in1s = 0xffffffff; + check_interval = 50; +#ifdef __LOCK_AUDIO_THREAD__ + af_unlock_thread(); +#endif + A2DP_SYNC_WITH_GET_MUTUX_ALLOC(); + A2DP_SYNC_WITH_GET_MUTUX_WAIT(); +#ifdef __LOCK_AUDIO_THREAD__ + af_lock_thread(); +#endif + } + break; + } + case APP_AUDIO_CACHE_OK: + { + delay_mtu_count = 0; +#if defined(A2DP_LHDC_ON) + newLen = 0; + if(overlay_id == APP_OVERLAY_A2DP_LHDC){ + uint32_t lSize = 0, rSize = 0; + uint8_t *lPTR = NULL, *rPTR = NULL; + //TRACE(2,"%s: input len(%d)",__func__, len); + if (assemble_lhdc_packet(buf, len, &lPTR, &lSize, &rPTR, &rSize) > 0){ + if (lPTR != NULL && lSize != 0){ + newLen = lSize + sizeof(LHDC_HEADER); + memcpy(lhdcTempBuf + sizeof(LHDC_HEADER), lPTR, lSize); + memcpy(lhdcTempBuf, magicTag, sizeof(magicTag)); + memcpy(lhdcTempBuf + sizeof(magicTag), &lSize, sizeof(unsigned int)); + mtu_plus = true; + } + } + + } +#endif + do{ + LOCK_APP_AUDIO_QUEUE(); +#if defined(A2DP_LHDC_ON) + if(overlay_id == APP_OVERLAY_A2DP_LHDC){ + nRet = APP_AUDIO_EnCQueue(&sbc_queue, lhdcTempBuf, newLen); + }else +#endif +#if defined(A2DP_AAC_ON) + if(overlay_id == APP_OVERLAY_A2DP_AAC){ + nRet = AvailableOfCQueue(&sbc_queue); + if (nRet >= (int)(len + 2)) + { + nRet = APP_AUDIO_EnCQueue(&sbc_queue, (uint8_t *)&len, 2); + nRet = APP_AUDIO_EnCQueue(&sbc_queue, buf, len); + } + else + nRet = CQ_ERR; + }else +#endif + + { + nRet = APP_AUDIO_EnCQueue(&sbc_queue, buf, len); + } + if (CQ_OK == nRet){ +#if defined(A2DP_LHDC_ON) + if(overlay_id == APP_OVERLAY_A2DP_LHDC){ + if (mtu_plus) { + mtu_count++; + mtu_plus = false; + } + } else { +#endif + if(overlay_id == APP_OVERLAY_A2DP +#if defined(A2DP_LDAC_ON) + || overlay_id == APP_OVERLAY_A2DP_LDAC +#endif + ){ + mtu_count += sbc_frame_num; +// TRACE(1,"+mtu_count = %d",mtu_count); + }else{ + mtu_count++; + } +#if defined(A2DP_LHDC_ON) + } +#endif + } +// size = APP_AUDIO_LengthOfCQueue(&sbc_queue); + UNLOCK_APP_AUDIO_QUEUE(); +// TRACE(3,"cache add:%d %d/%d \n", len, size, g_sbc_queue_size); + if (CQ_OK == nRet){ + nRet = 0; + break; + }else{ + TRACE(1,"cache flow control:%d\n", cnt); +#ifdef A2DP_AUDIO_SYNC_WITH_LOCAL + a2dp_audio_sync_proc(A2DPPLAY_SYNC_STATUS_SET, 0); +#endif + nRet = -1; +#ifdef __LOCK_AUDIO_THREAD__ + af_unlock_thread(); +#endif + A2DP_SYNC_WITH_GET_MUTUX_ALLOC(); + A2DP_SYNC_WITH_GET_MUTUX_WAIT(); +#ifdef __LOCK_AUDIO_THREAD__ + af_lock_thread(); +#endif + } + }while(cnt++= A2DP_SYNC_WITH_PUT_MUTUX_TIMEROUT_CNT){ + TRACE(0,"ldac No Data return"); + result = 1; + break; + } + continue; + } + + if (ldac_recovery) { + uint32_t parse_bytes; + + result = ldac_seek_header(len, &parse_bytes); + if (result == 0) { + ldac_recovery = false; + } + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&sbc_queue, 0, parse_bytes); + UNLOCK_APP_AUDIO_QUEUE(); + continue; + } + + break; + } + + if(skip_ldac_frame > 0){ + skip_ldac_frame--; + } +#endif + + return result; +} + +TEXT_LDAC_LOC +int decode_ldac_frame(uint8_t *out, uint32_t out_max, uint32_t *p_out_len, const uint8_t *in, uint32_t in_len, uint32_t *p_consume_len) +{ + int result; + int n_read_bytes, used_bytes, wrote_bytes; + + n_read_bytes = LDAC_READBUF_SIZE; + + result = ldacBT_decode(hLdacData, ldac_input_mid_buf, out, LDACBT_SMPL_FMT_S16, n_read_bytes, &used_bytes, &wrote_bytes); + + if (p_out_len) { + *p_out_len = wrote_bytes; + } + if (p_consume_len) { + *p_consume_len = used_bytes; + } + + return result; +} + +TEXT_LDAC_LOC +int consume_ldac_frame(const uint8_t *data, uint32_t len) +{ + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&sbc_queue, 0, len); + mtu_count--; + UNLOCK_APP_AUDIO_QUEUE(); + + return 0; +} + +TEXT_LDAC_LOC +void decode_ldac_end(uint32_t expect_out_len, uint32_t out_len, uint32_t in_len) +{ + if (expect_out_len != out_len) { + if (hLdacData) { + int error_code; + error_code = ldacBT_get_error_code(hLdacData); + TRACE(6,"error_code = %4d, %4d, %4d,FrameHeader[%02x:%02x:%02x]\n", LDACBT_API_ERR(error_code), LDACBT_HANDLE_ERR(error_code),\ + LDACBT_BLOCK_ERR(error_code), ldac_input_mid_buf[0], ldac_input_mid_buf[1], ldac_input_mid_buf[2]); + if( LDACBT_FATAL(error_code) ){ + ldac_dec_deinit(); + } + } + if (hLdacData == NULL) { + /* Recovery Process */ + int result; + result = ldac_dec_init(); + if (result) { + ldac_dec_deinit(); + } + ldac_recovery = true; + } + } +} +#endif + +#if defined(A2DP_AAC_ON) +#include "aacdecoder_lib.h" +#include "aacenc_lib.h" +#include "heap_api.h" +#define DECODE_AAC_PCM_FRAME_LENGTH (1024*4) + +HANDLE_AACDECODER aacDec_handle = NULL; +#define AAC_MEMPOLL_SIZE (40596) +heap_handle_t aac_memhandle = NULL; +uint8_t *aac_mempoll = NULL; + +static unsigned char aac_input_mid_buf[AAC_READBUF_SIZE]; +STATIC_ASSERT(sizeof(aac_input_mid_buf) >= 2048, "aac_input_mid_buf too small"); +static uint32_t byte_in_buffer = 0; + +int aac_meminit() +{ + int ret = 1; + if (aac_mempoll == NULL) + ret = app_audio_mempool_get_buff((uint8_t **)&aac_mempoll, AAC_MEMPOLL_SIZE); + if (ret > 0 && aac_memhandle == NULL) + { + aac_memhandle = heap_register(aac_mempoll,AAC_MEMPOLL_SIZE); + } + return ret; +} + +void aac_memdeinit() +{ + extern int total_calloc; + aac_mempoll = 0; + aac_memhandle = 0; + total_calloc = 0; + byte_in_buffer = 0; +} + +volatile int aac_slave_codec_patch_bytes = 0; + +int aacdec_init(void) +{ + if (aacDec_handle == NULL) { + TRANSPORT_TYPE transportFmt = TT_MP4_LATM_MCP1; + aacDec_handle = aacDecoder_Open(transportFmt, 1 /* nrOfLayers */); + + if (!aacDec_handle) + { + TRACE(1,"%s Error initializing AAC decoder", __func__); + return 1; + } + aacDecoder_SetParam(aacDec_handle,AAC_PCM_LIMITER_ENABLE,0); + aacDecoder_SetParam(aacDec_handle, AAC_DRC_ATTENUATION_FACTOR, 0); + aacDecoder_SetParam(aacDec_handle, AAC_DRC_BOOST_FACTOR, 0); + } + return 0; +} + +int aacdec_deinit(void) +{ + if (aacDec_handle != NULL) { + aacDecoder_Close(aacDec_handle); + aacDec_handle = NULL; + size_t total = 0, used = 0, max_used = 0; + heap_memory_info(aac_memhandle,&total, &used, &max_used); + TRACE(3,"AAC MALLOC MEM: total - %d, used - %d, max_used - %d.", + total, used, max_used); + } + return 0; +} + +TEXT_AAC_LOC +static int pcm_buffer_read_no_protction(CQueue *queue, uint8_t *buff, uint16_t len) +{ + uint8_t *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + int status; + status = PeekCQueue(queue, len, &e1, &len1, &e2, &len2); + //TRACE(5,"pcm_buffer_read_no_protction len=%d,len1=%d,len2=%d,e1=0x%x,e2=0x%x",len,len1,len2,e1,e2); + if (len==(len1+len2)){ + memcpy(buff,e1,len1); + memcpy(buff+len1,e2,len2); + DeCQueue(queue, 0, len); + }else{ + memset(buff, 0x00, len); + status = -1; + } + return status; +} + +TEXT_AAC_LOC +int load_aac_frame(uint8_t **p_data, uint32_t *p_len) +{ + //uint32_t lock; + unsigned short aac_len =0 ; + int status; + + LOCK_APP_AUDIO_QUEUE(); + status = pcm_buffer_read_no_protction(&sbc_queue, (uint8_t *)&aac_len, 2); + if(status != CQ_OK){ + UNLOCK_APP_AUDIO_QUEUE(); + //a2dp_cache_status = APP_AUDIO_CACHE_CACHEING; + return 1; + } + + if (aac_len < 64) { + aac_maxreadBytes = 64; + } else if (aac_len < 128) { + aac_maxreadBytes = 128; + } else if (aac_len < 256) { + aac_maxreadBytes = 256; + } else if (aac_len < 512) { + aac_maxreadBytes = 512; + } else if (aac_len < 1024) { + aac_maxreadBytes = 1024; + } else { + if (aac_len >= 2048) { + // Header is bad! + dec_reset_queue = true; + return 2; + } + aac_maxreadBytes = 2048; + } + + status = pcm_buffer_read_no_protction(&sbc_queue,aac_input_mid_buf, aac_len); + if(status != CQ_OK){ + UNLOCK_APP_AUDIO_QUEUE(); + //a2dp_cache_status = APP_AUDIO_CACHE_CACHEING; + return 1; + } + mtu_count--; + UNLOCK_APP_AUDIO_QUEUE(); + + //uint32_t a2dp_queue_bytes = LengthOfCQueue(&sbc_queue); + //TRACE(3,"d aac_len=%d, a2dp_bytes=%d, aac_maxreadBytes=%d\n", aac_len, a2dp_queue_bytes, aac_maxreadBytes); + + if (p_data) { + *p_data = (unsigned char *)aac_input_mid_buf; + } + if (p_len) { + *p_len = aac_maxreadBytes; + } + + return 0; +} + +TEXT_AAC_LOC +int decode_aac_frame(uint8_t *out, uint32_t out_max, uint32_t *p_out_len, const uint8_t *in, uint32_t in_len, uint32_t *p_consume_len) +{ + unsigned int bufferSize = in_len; + unsigned int bytesValid = in_len; + AAC_DECODER_ERROR err = AAC_DEC_OK; + CStreamInfo* info=NULL; + + //at leat should large than AAC_MAX_NSAMPS*2 (one channel) + if(out_max < 2048){ + TRACE(2,"%s daac pcm_len = %d \n", __func__, out_max); + return 1; + } + + if(a2dp_channel_num[app_bt_device.curr_a2dp_stream_id] == 1){ + out_max >>= 1; + } + + //int tt = hal_sys_timer_get(); + err = aacDecoder_Fill(aacDec_handle, (uint8_t **)&in, &bufferSize, &bytesValid); + if (err != AAC_DEC_OK) { + TRACE(1,"aacDecoder_Fill failed:0x%x", err); + //if aac failed reopen it again + if(is_aacDecoder_Close(aacDec_handle)){ + aacDec_handle = NULL; + aacdec_init(); + TRACE(1,"%s reopen aac codec \n", __func__); + } + return 2; + } + /* decode one AAC frame */ + err = aacDecoder_DecodeFrame(aacDec_handle, (short *)out, out_max/2, 0 /* flags */); + +#if 0 + TRACE_IMM(0," "); + for(uint32_t i=0;isampleRate <= 0) { + TRACE(2,"%s Invalid stream info %d", __func__, info->sampleRate); + return 4; + } + int frame_len = info->frameSize * info->numChannels * 2;//sizeof(pcm_buffer[0]); + //TRACE(4,"aac: %d,frameSize=%d,numChannels=%d use %d ms\n", frame_len,info->frameSize,info->numChannels,TICKS_TO_MS(hal_sys_timer_get()-tt)); + + if (p_out_len) { + *p_out_len = frame_len; + } + if (p_consume_len) { + *p_consume_len = in_len - bytesValid; + } + + if(a2dp_channel_num[app_bt_device.curr_a2dp_stream_id] == 1){ + expand_1_channel_to_2_channels_16bits(out, frame_len); + *p_out_len = frame_len << 1; + } + return 0; +} +#endif + +#ifdef A2DP_EQ_24BIT +static void convert_16bit_to_24bit(int32_t *out, int16_t *in, int len) +{ + for (int i = len - 1; i >= 0; i--) { + out[i] = ((int32_t)in[i] << 8); + } +} +#endif + +#if defined(A2DP_SCALABLE_ON) + +extern "C" { +#include "ssc.h" +} + + +unsigned char *scalable_input_mid_buf = NULL; +unsigned char *scalable_decoder_place = NULL; +unsigned char *scalable_decoder_temp_buf = NULL; +void *hSSDecoder = NULL; + +#if 0 +uint8_t ss_dump[484*10]; +uint32_t ss_dump_index = 0; +#endif +extern "C" int ssc_decoder_init( + void *s, + int channels, + int Fs +); + +TEXT_SSC_LOC +void ss_to_24bit_buf(int32_t *out, int32_t *in, int size) +{ + for(int i = 0; i < size; i++) { + out[i] = in[i]; + } +} + +TEXT_SSC_LOC +void ss_to_16bit_buf(int16_t *out, int32_t *in, int size) +{ + for(int i = 0; i < size; i++) { + out[i] = in[i]; + } +} + +static int ss_pcm_buff[SCALABLE_FRAME_SIZE << 1]; +static int scalable_uhq_flag = 0; + +TEXT_SSC_LOC +int load_scalable_frame(uint8_t **p_data, uint32_t *p_len) +{ + int hw_tmp,len,bitrate_bps,frame_size; + int r = 0; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + int sampling_rate = 44100; + int extends_flag; + + TRACE(0,"##decode_scalable_frame"); + uint8_t head[4]; + + LOCK_APP_AUDIO_QUEUE(); + len1 = len2 = 0; + e1 = e2 = 0; + r = PeekCQueue(&sbc_queue, SCALABLE_HEAD_SIZE, &e1, &len1, &e2, &len2); + UNLOCK_APP_AUDIO_QUEUE(); + if(r == CQ_ERR) { + //osDelay(2); + TRACE(2,"no data head xxx %d/%d" , LengthOfCQueue(&sbc_queue),AvailableOfCQueue(&sbc_queue)); + //goto get_scalable_head_again; + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&sbc_queue, head, 4); + UNLOCK_APP_AUDIO_QUEUE(); + hal_trace_dump("sss %01x",1,4,head); + return 1; + } + else { + // normal + if (e1) { + memcpy(scalable_input_mid_buf, e1, len1); + } + if (e2) { + memcpy(scalable_input_mid_buf + len1, e2, len2); + } + } + + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&sbc_queue, 0, 4); + UNLOCK_APP_AUDIO_QUEUE(); + + scalable_uhq_flag = 0; + + extends_flag = ((scalable_input_mid_buf[3]>>3)&1); + switch ((scalable_input_mid_buf[3]&0xf7)) { + case 0xF0: + bitrate_bps = 88000; + break; + case 0xF1: + bitrate_bps = 96000; + break; + case 0xF2: + bitrate_bps = 128000; + break; + case 0xF3: + bitrate_bps = 192000; + break; + case 0xF5: + scalable_uhq_flag = 1; + bitrate_bps = 328000; + sampling_rate = 96000; + break; + default: + bitrate_bps = 88000; + break; + } + + frame_size = SCALABLE_FRAME_SIZE; + + len = bitrate_bps*frame_size/sampling_rate/8; + if(scalable_uhq_flag == 0) + { + hw_tmp = (len*3)>>7; + len = hw_tmp+len; + len = len+((len & 1)^1); + } + else{ + len=369;//744/2-4+1 + } + TRACE(4,"len %d,uhq:%d ext:%d extbitrate_bps %d", len,scalable_uhq_flag, extends_flag,bitrate_bps); + + LOCK_APP_AUDIO_QUEUE(); + len1 = len2 = 0; + e1 = e2 = 0; + r = PeekCQueue(&sbc_queue, len-1, &e1, &len1, &e2, &len2); + if(r == CQ_ERR) { + //osDelay(2); + TRACE(0,"no data "); + UNLOCK_APP_AUDIO_QUEUE(); + return 2; + } + else { + // normal + if (e1) { + memcpy(scalable_input_mid_buf+4, e1, len1); + } + if (e2) { + memcpy(scalable_input_mid_buf+4+len1, e2, len2); + } + } +// UNLOCK_APP_AUDIO_QUEUE(); + + // LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&sbc_queue, 0, len-1); + UNLOCK_APP_AUDIO_QUEUE(); +// TRACE(2,"len1 %d, len2 %d\n", len1, len2); + + if (p_data) { + *p_data = scalable_input_mid_buf; + } + if (p_len) { + *p_len = len - 1; + } + + return 0; +} + +TEXT_SSC_LOC +int decode_scalable_frame(uint8_t *out, uint32_t out_max, uint32_t *p_out_len, const uint8_t *in, uint32_t in_len, uint32_t *p_consume_len) +{ + uint32_t out_len; + int decoder_size; + int output_samples; + int err; + + out_len = SCALABLE_FRAME_SIZE * 2; + + if (hSSDecoder == NULL) { + hSSDecoder = (void *)scalable_decoder_place; + //err = ssc_decoder_create(44100, 2, hSSDecoder); + decoder_size = ssc_decoder_get_size(2,96000); + err = ssc_decoder_init(hSSDecoder,2,96000); + TRACE(2,"decoder_size %d init ret %d\n", decoder_size,err); + } + + if(a2dp_channel_num[app_bt_device.curr_a2dp_stream_id] == 1){ + ASSERT(0, "UHQ should check audio channel number"); + } + output_samples = ssc_decode(hSSDecoder, scalable_input_mid_buf, (int *)ss_pcm_buff, SCALABLE_FRAME_SIZE, scalable_decoder_temp_buf); + if (scalable_uhq_flag) { + ss_to_24bit_buf((int32_t *)out, (int32_t *)ss_pcm_buff, out_len); + out_len *= 4; + } + else { + ss_to_16bit_buf((int16_t *)out, (int32_t *)ss_pcm_buff, out_len); + out_len *= 2; + } + + TRACE(2,"pcm_len %d o:%d", out_len, output_samples); + + if (p_out_len) { + *p_out_len = out_len; + } + if (p_consume_len) { + *p_consume_len = 0; + } + + return 0; +} +#endif + +static unsigned int sbc_next_frame_size; +static btif_sbc_pcm_data_t sbc_pcm_data; +static uint8_t sbc_underflow; + +TEXT_SBC_LOC +void decode_sbc_begin(void) +{ + sbc_underflow = 0; +} + +TEXT_SBC_LOC +int load_sbc_frame(uint8_t **p_data, uint32_t *p_len) +{ + unsigned char retry = 0; + int r = 0; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + + if (!sbc_next_frame_size){ + sbc_next_frame_size = sbc_frame_size; + } + + if (need_init_decoder) { + sbc_next_frame_size = sbc_frame_size; + } + +get_again: + LOCK_APP_AUDIO_QUEUE(); + len1 = len2 = 0; + r = PeekCQueue(&sbc_queue, sbc_next_frame_size, &e1, &len1, &e2, &len2); + UNLOCK_APP_AUDIO_QUEUE(); + if(r == CQ_ERR) { +#ifdef __LOCK_AUDIO_THREAD__ + TRACE(1,"cache sbc_underflow retry:%d\n", retry); + goto exit; +#elif defined (A2DP_SYNC_WITH_PUT_MUTUX) + int size; + A2DP_SYNC_WITH_PUT_MUTUX_ALLOC(); + A2DP_SYNC_WITH_PUT_MUTUX_WAIT(); + if (retry++>= 1; + } + + uint32_t lock = int_lock(); + ret = btif_sbc_decode_frames(sbc_decoder, (uint8_t *)in, in_len, + &parse_len, + &sbc_pcm_data, + out_max, + sbc_eq_band_gain); + int_unlock(lock); + parse_len_total_frame += parse_len; + if(parse_len_total_frame >= sbc_frame_size){ + mtu_count --; + // TRACE(1,"-mtu_count = %d",mtu_count); + parse_len_total_frame -= sbc_frame_size; + } + if (ret == BT_STS_SUCCESS) { + sbc_next_frame_size = sbc_frame_size; + } else { + sbc_next_frame_size = (sbc_frame_size > parse_len) ? (sbc_frame_size - parse_len) : sbc_frame_size; + + if (ret == BT_STS_FAILED) { + need_init_decoder = true; + TRACE(1,"err mutelen:%d\n",sbc_pcm_data.dataLen); + } else if(ret == BT_STS_NO_RESOURCES) { + TRACE(1,"no_res mutelen:%d\n",sbc_pcm_data.dataLen); + } + } + + if (p_out_len) { + *p_out_len = sbc_pcm_data.dataLen; + } + if (p_consume_len) { + *p_consume_len = parse_len; + } + + if(a2dp_channel_num[app_bt_device.curr_a2dp_stream_id] == 1){ + expand_1_channel_to_2_channels_16bits(sbc_pcm_data.data, sbc_pcm_data.dataLen); + sbc_pcm_data.dataLen <<= 1; + *p_out_len = sbc_pcm_data.dataLen; + } + + return (ret == BT_STS_CONTINUE || ret == BT_STS_SUCCESS) ? 0 : 1; +} + +TEXT_SBC_LOC +int consume_sbc_frame(const uint8_t *data, uint32_t len) +{ + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&sbc_queue, 0, len); + UNLOCK_APP_AUDIO_QUEUE(); + + return 0; +} + +TEXT_SBC_LOC +void decode_sbc_end(uint32_t expect_out_len, uint32_t out_len, uint32_t in_len) +{ +#ifndef A2DP_TRACE_DEC_TIME + if (sbc_underflow || need_init_decoder) { + dec_trace_time = true; + } +#endif + +#ifdef A2DP_AUDIO_SYNC_WITH_LOCAL + if(expect_out_len == out_len){ + int size; + LOCK_APP_AUDIO_QUEUE(); + size = LengthOfCQueue(&sbc_queue); + UNLOCK_APP_AUDIO_QUEUE(); +// TRACE(2,"decode_sbc_frame Queue remain size:%d frame_size:%d\n",size, sbc_frame_size); + A2DP_AUDIO_SYNC_TRACE(6,"sync status:%d qsize:%d/%d fsize:%d, thr:%d used:%d", sync_status,size, g_sbc_queue_size, sbc_frame_size, A2DPPLAY_CACHE_OK_THRESHOLD, in_len); +/* +nor: + if (size>7488+1170*2) + goto inc + if (size<7488-1170) + goto dec +dec: + if (size>=7488+1170) + goto nor +inc: + if (size<=7488) + goto nor +*/ + switch (sync_status) { + case A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_DEC: + if (size >= (A2DPPLAY_CACHE_OK_THRESHOLD + in_len)){ + a2dp_audio_sync_proc(A2DPPLAY_SYNC_STATUS_SET, A2DP_AUDIO_SYNC_WITH_LOCAL_SAMPLERATE_DEFAULT); + sync_status = A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_DEFAULT; + A2DP_AUDIO_SYNC_TRACE(0,"default pll freq"); + }else{ + a2dp_audio_sync_proc(A2DPPLAY_SYNC_STATUS_PROC, 0); + } + break; + case A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_INC: + if (size <= (A2DPPLAY_CACHE_OK_THRESHOLD)){ + a2dp_audio_sync_proc(A2DPPLAY_SYNC_STATUS_SET, A2DP_AUDIO_SYNC_WITH_LOCAL_SAMPLERATE_DEFAULT); + sync_status = A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_DEFAULT; + A2DP_AUDIO_SYNC_TRACE(0,"default pll freq"); + }else{ + a2dp_audio_sync_proc(A2DPPLAY_SYNC_STATUS_PROC, 0); + } + break; + case A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_DEFAULT: + default: + if (size > (A2DPPLAY_CACHE_OK_THRESHOLD + (in_len<<1))){ + a2dp_audio_sync_proc(A2DPPLAY_SYNC_STATUS_SET, A2DP_AUDIO_SYNC_WITH_LOCAL_SAMPLERATE_INC); + sync_status = A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_INC; + A2DP_AUDIO_SYNC_TRACE(0,"inc pll freq"); + }else if (size < (A2DPPLAY_CACHE_OK_THRESHOLD - in_len)){ + a2dp_audio_sync_proc(A2DPPLAY_SYNC_STATUS_SET, A2DP_AUDIO_SYNC_WITH_LOCAL_SAMPLERATE_DEC); + sync_status = A2DP_AUDIO_SYNC_STATUS_SAMPLERATE_DEC; + A2DP_AUDIO_SYNC_TRACE(0,"dec pll freq"); + }else{ + a2dp_audio_sync_proc(A2DPPLAY_SYNC_STATUS_PROC, 0); + } + break; + } + } +#endif +} + +#if defined(A2DP_LHDC_ON) +#define PACKET_BUFFER_LENGTH 4 * 1024 + +uint8_t serial_no; +bool is_synced; +bool is_splited; +ASM_PKT_STATUS asm_pkt_st; +uint8_t packet_buffer[PACKET_BUFFER_LENGTH]; +uint32_t packet_buf_len = 0; +uint32_t frames_nb_in_buffer = 0; +uint32_t total_frame_nb = 0; +void reset_lhdc_assmeble_packet() +{ + is_synced = false; + asm_pkt_st = ASM_PKT_WAT_STR; + packet_buf_len = 0; + total_frame_nb = 0; +} + +void initial_lhdc_assemble_packet(bool splitFlg){ + memset(packet_buffer, 0, PACKET_BUFFER_LENGTH); + reset_lhdc_assmeble_packet(); + serial_no = 0xff; + is_splited = splitFlg; + TRACE(1,"is_splited = %s\n", splitFlg ? "true" : "false"); +} + + +/** + * get lhdc frame header + */ +bool get_lhdc_header(uint8_t * in, LHDC_FRAME_HDR * h) { + #define LHDC_HDR_LEN 4 + uint32_t hdr = 0; + bool ret = false; + memcpy(&hdr, in , LHDC_HDR_LEN); + h->frame_len = ( int)( ( hdr >> 8) & 0x1fff); + h->isSplit = ( ( hdr & 0x00600000) == 0x00600000); + h->isLeft = ((hdr & 0xf) == 0); + + if ( ( hdr & 0xff000000) != 0x4c000000){ + TRACE(0,"lhdc hdr err!\n"); + ret = false; + } else { + //TRACE(4,"frame_len = %d, g_lhdc_split = %s, g_lhdc_channel = %s(%d)", h->frame_len, h->isSplit ? "true" : "false", h->isLeft ? "left" : "right", (hdr & 0xf) ); + ret = true; + } + return ret; +} + +/** + *Get splited lhdc frames fit to MTU size + */ +uint32_t get_lhdc_frame(uint8_t * frame_q, size_t q_available_size, uint8_t * out_buf, uint32_t * out_size, uint32_t * out_frames){ + LHDC_FRAME_HDR hdr; + size_t emptSize = q_available_size >= PACKET_MTU_SIZE ? PACKET_MTU_SIZE : q_available_size; + uint32_t * offset = out_size; + //uint32_t * frame_cnt = out_frames; + bool start = TRUE; + *offset = 0; // *frame_cnt = 0; + while (start) { + + if (get_lhdc_header(frame_q + *offset, &hdr) == false ){ + start = false; + continue; + } + + if (emptSize < hdr.frame_len) { + start = false; + continue; + } + + memcpy(out_buf + *offset, frame_q + *offset, hdr.frame_len); + emptSize -= hdr.frame_len; + *offset += hdr.frame_len; + (*out_frames)++; + } + return *offset; +} +/** + * Grabe lhdc data from queue + */ +int get_lhdc_data(unsigned char * frame, unsigned int len) +{ + int status; + unsigned int len1 = 0, len2 = 0; + unsigned char *e1 = NULL, *e2 = NULL; + LOCK_APP_AUDIO_QUEUE(); + unsigned int queu_len = (unsigned int)LengthOfCQueue(&sbc_queue); + len = queu_len < len ? queu_len : len; + status = PeekCQueue(&sbc_queue, len, &e1, &len1, &e2, &len2); + UNLOCK_APP_AUDIO_QUEUE(); + if(status != CQ_OK){ + return 0; + } + + if (e1) { + memcpy(frame, e1, len1); + } + if (e2) { + memcpy(frame + len1, e2, len2); + } + return len; +} + + +int assemble_lhdc_packet(uint8_t * input, uint32_t input_len, uint8_t** pLout, uint32_t * pLlen, uint8_t** pRout, uint32_t * pRlen){ + uint8_t hdr = 0, seqno = 0xff; + int ret = -1; + uint32_t status = 0; + + hdr = (*input); + input++; + seqno = (*input); + input++; + input_len -= 2; + + status = hdr & A2DP_LHDC_HDR_LATENCY_MASK; + if (latencyUpdated != (uint8_t)status) { + latencyUpdated = (uint8_t)status; + TRACE(1,"New latency setting = 0x%02x", latencyUpdated); + } + + if( is_synced) + { + if( seqno != serial_no ) + { + reset_lhdc_assmeble_packet(); + if( (hdr & A2DP_LHDC_HDR_FLAG_MSK) == 0 || + (hdr & A2DP_LHDC_HDR_S_MSK) != 0 ) + { + goto lhdc_start; + } + else + TRACE(1,"drop packet No. %u", seqno); + return 0; + } + serial_no = seqno + 1; + } + +lhdc_start: + switch (asm_pkt_st) { + case ASM_PKT_WAT_STR:{ + if( (hdr & A2DP_LHDC_HDR_FLAG_MSK) == 0 ) + { + memcpy(&packet_buffer[0], input, input_len); + if (pLlen && pLout) { + *pLlen = input_len; + *pLout = packet_buffer; + } + if (pRout && pRlen) { + *pRout = NULL; + *pRlen = 0; + } + //TRACE(1,"Single payload size = %d", *pLlen); + asm_pkt_st = ASM_PKT_WAT_STR; + packet_buf_len = 0;//= packet_buf_left_len = packet_buf_right_len = 0; + total_frame_nb = 0; + ret = 1; + } + else if( hdr & A2DP_LHDC_HDR_S_MSK ) + { + ret = 0; + if (packet_buf_len + input_len >= PACKET_BUFFER_LENGTH) { + packet_buf_len = 0; + asm_pkt_st = ASM_PKT_WAT_STR; + TRACE(1,"ASM_PKT_WAT_STR:Frame buffer overflow!(%d)", packet_buf_len); + break; + } + memcpy(&packet_buffer, input, input_len); + packet_buf_len = input_len; + asm_pkt_st = ASM_PKT_WAT_LST; + //TRACE(1,"multi:first payload size = %d", input_len); + } + else + ret = -1; + + if( ret >= 0 ) + { + if( !is_synced ) + { + is_synced = true; + serial_no = seqno + 1; + } + } + break; + } + case ASM_PKT_WAT_LST:{ + if (packet_buf_len + input_len >= PACKET_BUFFER_LENGTH) { + packet_buf_len = 0; + asm_pkt_st = ASM_PKT_WAT_STR; + TRACE(1,"ASM_PKT_WAT_LST:Frame buffer overflow(%d)", packet_buf_len); + break; + } + memcpy(&packet_buffer[packet_buf_len], input, input_len); + //TRACE(1,"multi:payload size = %d", input_len); + packet_buf_len += input_len; + ret = 0; + + if( hdr & A2DP_LHDC_HDR_L_MSK ) + { + + if (pLlen && pLout) { + *pLlen = packet_buf_len; + *pLout = packet_buffer; + } + //TRACE(1,"multi: all payload size = %d", packet_buf_len); + packet_buf_len = 0; //packet_buf_left_len = packet_buf_right_len = 0; + total_frame_nb = 0; + ret = 1; + asm_pkt_st = ASM_PKT_WAT_STR; + } + break; + } + default: + ret = 0; + break; + + } + return ret; +} +/** + * Decode LHDC data... + */ +TEXT_LHDC_LOC +int load_lhdc_frame(uint8_t **p_data, uint32_t *p_len) +{ + int ret; + LHDC_HEADER *ph = NULL; + uint8_t retry = 0; + int status; + uint8_t *_buff = NULL; + uint32_t _buff_len = 0; + + ret = 1; + + A2DP_SYNC_WITH_PUT_MUTUX_ALLOC(); + + if (latencyIndex != latencyUpdated) { + latencyIndex = latencyUpdated; + goto _exit; + } + + while (true) { + int result = lhdcReadyForInput(); + if (result == 1) { + /* code */ + status = get_lhdc_data(lhdc_input_mid_buf, sizeof(LHDC_HEADER)); + if(status == 0){ + //No data return... + if (retry++ >= A2DP_SYNC_WITH_PUT_MUTUX_TIMEROUT_CNT){ + TRACE(1,"%s:No Data return", __func__); + break; + } + A2DP_SYNC_WITH_PUT_MUTUX_WAIT(); + continue; + } + retry = 0; + ph = (LHDC_HEADER *)&lhdc_input_mid_buf[0]; + result = memcmp((const char*)magicTag, (const char*)ph->tag, sizeof(magicTag)); + if (result != 0) { + uint8_t tmp[sizeof(magicTag) + 1]; + size_t i; + for ( i = 0; i < sizeof(magicTag); i++) { + sprintf((char*)&tmp[i], "%c", (char)ph->tag[i]); + } + tmp[i] = 0; + continue; + } + + status = get_lhdc_data(lhdc_input_mid_buf, sizeof(LHDC_HEADER) + ph->packetLen); + if(status == 0){ + //No data return... + TRACE(1,"Fetch data error[lenght = %d]", ph->packetLen); + continue; + } + ph = (LHDC_HEADER *)&lhdc_input_mid_buf[0]; + + //TRACE(2,"%s:Get packet[%d]", __func__, ph->packetLen); + + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&sbc_queue, 0, sizeof(LHDC_HEADER) + ph->packetLen); + mtu_count--; + UNLOCK_APP_AUDIO_QUEUE(); + _buff = ph->dptr; + _buff_len = ph->packetLen; + ret = 0; + } else { + _buff = NULL; + _buff_len = 0; + ret = 0; + } + break; + } + +_exit: + A2DP_SYNC_WITH_PUT_MUTUX_FREE(); + + if (p_data) { + *p_data = _buff; + } + if (p_len) { + *p_len = _buff_len; + } + + return ret; +} + +TEXT_LHDC_LOC +int decode_lhdc_frame(uint8_t *out, uint32_t out_max, uint32_t *p_out_len, const uint8_t *in, uint32_t in_len, uint32_t *p_consume_len) +{ + uint32_t need_again; + uint32_t out_len; + + if(a2dp_channel_num[app_bt_device.curr_a2dp_stream_id] == 1){ + ASSERT(0, "lhdc should check audio channel number"); + } + + out_len = lhdcDecodeProcess(out, (uint8_t *)in, in_len, &need_again); + + if (p_out_len) { + *p_out_len = (out_len >= 0) ? out_len : 0; + } + if (p_consume_len) { + *p_consume_len = (out_len >= 0) ? in_len : 0; + } + + return (out_len >= 0) ? 0 : 1; +} + +TEXT_LHDC_LOC +void decode_lhdc_end(uint32_t expect_out_len, uint32_t out_len, uint32_t in_len) +{ + if (expect_out_len != out_len) { + dec_reset_queue = true; + } +} +#endif + +#ifdef A2DP_CP_ACCEL +#include "cp_accel.h" + +#define CP_CACHE_ATTR ALIGNED(4) CP_BSS_LOC +#define CP_DEC_SLOT_CNT 3 + +enum CP_DEC_STATE_T { + CP_DEC_STATE_IDLE, + CP_DEC_STATE_WORKING, + CP_DEC_STATE_DONE, + CP_DEC_STATE_FAILED, +}; + +static CP_CACHE_ATTR uint8_t cp_in_cache[1024 * 10]; +static CP_CACHE_ATTR uint8_t cp_out_cache[1024 * 16]; +static CP_BSS_LOC uint32_t cp_in_wpos; +static CP_BSS_LOC uint32_t cp_in_rpos; +static CP_BSS_LOC uint32_t cp_dec_start_time; +static CP_BSS_LOC uint32_t cp_last_dec_time; +#ifdef A2DP_TRACE_CP_DEC_TIME +static CP_DATA_LOC const bool cp_dec_trace_time = true; +#else +static CP_BSS_LOC bool cp_dec_trace_time; +#endif +static CP_BSS_LOC uint8_t cp_dec_idx; + +static bool mcu_dec_inited; +static enum APP_OVERLAY_ID_T cp_overlay_type; +static enum CP_DEC_STATE_T cp_dec_state[CP_DEC_SLOT_CNT]; +static uint8_t cp_dec_mtu_cnt[CP_DEC_SLOT_CNT]; +static uint32_t cp_out_len[CP_DEC_SLOT_CNT]; +static uint8_t mcu_dec_idx; +static uint32_t cp_in_size; +static uint32_t cp_out_size; +static uint32_t cp_out_loop_size; + +static uint32_t cp_get_in_cache_data_len(uint32_t in_wpos, uint32_t in_rpos); +static void cp_get_in_cache_data(uint8_t *data, uint32_t len, uint32_t in_wpos, uint32_t in_rpos); +static uint32_t cp_update_in_cache_pos(uint32_t in_pos, uint32_t len); + +#if defined(A2DP_LDAC_ON) +static CP_BSS_LOC bool cp_ldac_fatal_error; + +TEXT_LDAC_LOC +int cp_load_ldac_frame(uint8_t **p_data, uint32_t *p_len) +{ + uint32_t len; + uint32_t in_rpos; + uint32_t in_wpos; + + if (hLdacData == NULL || cp_ldac_fatal_error){ + return 1; + } + + in_rpos = cp_in_rpos; + in_wpos = cp_in_wpos; + +_get_hdr: + len = cp_get_in_cache_data_len(in_wpos, in_rpos); + if (len == 0) { + return 2; + } + if (len > LDAC_READBUF_SIZE) { + len = LDAC_READBUF_SIZE; + } + + cp_get_in_cache_data(&ldac_input_mid_buf[0], len, in_wpos, in_rpos); + + if (ldac_recovery) { + uint32_t parse_bytes; + int result; + + result = ldac_seek_header(len, &parse_bytes); + if (result == 0) { + ldac_recovery = false; + } + in_rpos = cp_update_in_cache_pos(in_rpos, parse_bytes); + goto _get_hdr; + } + + return 0; +} + +TEXT_LDAC_LOC +static int cp_consume_ldac_frame(const uint8_t *data, uint32_t len) +{ + cp_in_rpos = cp_update_in_cache_pos(cp_in_rpos, len); + + return 0; +} + +TEXT_LDAC_LOC +void cp_decode_ldac_end(uint32_t expect_out_len, uint32_t out_len, uint32_t in_len) +{ + if (expect_out_len != out_len) { + if (hLdacData) { + int error_code; + error_code = ldacBT_get_error_code(hLdacData); + TRACE(6,"error_code = %4d, %4d, %4d,FrameHeader[%02x:%02x:%02x]\n", LDACBT_API_ERR(error_code), LDACBT_HANDLE_ERR(error_code),\ + LDACBT_BLOCK_ERR(error_code), ldac_input_mid_buf[0], ldac_input_mid_buf[1], ldac_input_mid_buf[2]); + if( LDACBT_FATAL(error_code) ){ + cp_ldac_fatal_error = true; + } + } + } +} + +TEXT_LDAC_LOC +void mcu_decode_ldac_end(uint32_t expect_out_len, uint32_t out_len, uint32_t in_len) +{ + if (expect_out_len != out_len) { + if (cp_ldac_fatal_error) { + ldac_dec_deinit(); + } + if (hLdacData == NULL) { + /* Recovery Process */ + int result; + result = ldac_dec_init(); + if (result) { + ldac_dec_deinit(); + } + ldac_recovery = true; + cp_ldac_fatal_error = false; + } + } +} +#endif + +#if defined(A2DP_LHDC_ON) +TEXT_LHDC_LOC +int cp_load_lhdc_frame(uint8_t **p_data, uint32_t *p_len) +{ + int ret; + LHDC_HEADER ph; + uint32_t len; + uint32_t in_rpos; + uint32_t in_wpos; + uint8_t *frame_buf = NULL; + uint32_t frame_len = 0; + int result; + + ret = 1; + + if (latencyIndex != latencyUpdated) { + latencyIndex = latencyUpdated; + goto _exit; + } + + result = lhdcReadyForInput(); + if (result == 0) { + ret = 0; + goto _exit; + } + + in_rpos = cp_in_rpos; + in_wpos = cp_in_wpos; + +_get_hdr: + len = cp_get_in_cache_data_len(in_wpos, in_rpos); + if (len < sizeof(ph)) { + goto _exit; + } + + cp_get_in_cache_data(&lhdc_input_mid_buf[0], sizeof(ph), in_wpos, in_rpos); + + memcpy(&ph, &lhdc_input_mid_buf[0], sizeof(ph)); + result = memcmp((const char*)magicTag, (const char*)ph.tag, sizeof(magicTag)); + if (result != 0) { + in_rpos = cp_update_in_cache_pos(in_rpos, 1); + goto _get_hdr; + } + + if (len < sizeof(ph) + ph.packetLen) { + goto _exit; + } + + in_rpos = cp_update_in_cache_pos(in_rpos, sizeof(ph)); + + cp_get_in_cache_data(&lhdc_input_mid_buf[sizeof(ph)], ph.packetLen, in_wpos, in_rpos); + + in_rpos = cp_update_in_cache_pos(in_rpos, ph.packetLen); + cp_in_rpos = in_rpos; + + frame_buf = &((LHDC_HEADER *)&lhdc_input_mid_buf[0])->dptr[0]; + frame_len = ph.packetLen; + + ret = 0; + +_exit: + if (p_data) { + *p_data = frame_buf; + } + if (p_len) { + *p_len = frame_len; + } + + return ret; +} +#endif + +#if defined(A2DP_AAC_ON) +TEXT_AAC_LOC +int cp_load_aac_frame(uint8_t **p_data, uint32_t *p_len) +{ + uint32_t len; + unsigned short aac_len = 0; + uint32_t in_rpos; + uint32_t in_wpos; + + in_rpos = cp_in_rpos; + in_wpos = cp_in_wpos; + + len = cp_get_in_cache_data_len(in_wpos, in_rpos); + if (len < 2) { + return 1; + } + + if (in_wpos > in_rpos || cp_in_size >= in_rpos + 2) { + aac_len = cp_in_cache[in_rpos] | (cp_in_cache[in_rpos + 1] << 8); + } else { + aac_len = cp_in_cache[in_rpos] | (cp_in_cache[0] << 8); + } + in_rpos = cp_update_in_cache_pos(in_rpos, 2); + + if (aac_len < 64) { + aac_maxreadBytes = 64; + } else if (aac_len < 128) { + aac_maxreadBytes = 128; + } else if (aac_len < 256) { + aac_maxreadBytes = 256; + } else if (aac_len < 512) { + aac_maxreadBytes = 512; + } else if (aac_len < 1024) { + aac_maxreadBytes = 1024; + } else { + if (aac_len >= 2048) { + // Header is bad! + dec_reset_queue = true; + return 2; + } + aac_maxreadBytes = 2048; + } + + if (len < 2 + (uint32_t)aac_len) { + return 3; + } + + cp_dec_mtu_cnt[cp_dec_idx]++; + + cp_get_in_cache_data(&aac_input_mid_buf[0], aac_len, in_wpos, in_rpos); + // Consume the packet + in_rpos = cp_update_in_cache_pos(in_rpos, aac_len); + cp_in_rpos = in_rpos; + + if (p_data) { + *p_data = (unsigned char *)aac_input_mid_buf; + } + if (p_len) { + *p_len = aac_maxreadBytes; + } + + return 0; +} +#endif + +TEXT_SBC_LOC +int cp_load_sbc_frame(uint8_t **p_data, uint32_t *p_len) +{ + uint32_t len; + uint32_t in_wpos; + uint32_t in_rpos; + + if (!sbc_next_frame_size){ + sbc_next_frame_size = sbc_frame_size; + } + + if (need_init_decoder) { + sbc_next_frame_size = sbc_frame_size; + } + + in_wpos = cp_in_wpos; + in_rpos = cp_in_rpos; + + if (in_wpos == in_rpos) { + return 1; + } + + if (in_wpos > in_rpos) { + len = in_wpos - in_rpos; + } else { + len = cp_in_size - in_rpos; + } + + if (len > sbc_next_frame_size) { + len = sbc_next_frame_size; + } + + if (p_data) { + *p_data = &cp_in_cache[in_rpos]; + } + if (p_len) { + *p_len = len; + } + + return 0; +} + +TEXT_SBC_LOC +static int cp_consume_sbc_frame(const uint8_t *data, uint32_t len) +{ + cp_in_rpos = cp_update_in_cache_pos(cp_in_rpos, len); + + return 0; +} + +CP_TEXT_SRAM_LOC +static uint32_t cp_get_in_cache_data_len(uint32_t in_wpos, uint32_t in_rpos) +{ + uint32_t len; + + if (in_wpos >= in_rpos) { + len = in_wpos - in_rpos; + } else { + len = cp_in_size - in_rpos + in_wpos; + } + + return len; +} + +CP_TEXT_SRAM_LOC +static void cp_get_in_cache_data(uint8_t *data, uint32_t len, uint32_t in_wpos, uint32_t in_rpos) +{ + // Assuming cp_get_in_cache_data_len(in_wpos, in_rpos) >= len + + if (in_wpos > in_rpos || cp_in_size >= in_rpos + len) { + memcpy(&data[0], &cp_in_cache[in_rpos], len); + } else { + uint32_t copy_len; + + copy_len = cp_in_size - in_rpos; + memcpy(&data[0], &cp_in_cache[in_rpos], copy_len); + memcpy(&data[copy_len], &cp_in_cache[0], len - copy_len); + } +} + +CP_TEXT_SRAM_LOC +static uint32_t cp_update_in_cache_pos(uint32_t in_pos, uint32_t len) +{ + // Consume the packet + in_pos += len; + if (in_pos >= cp_in_size) { + in_pos -= cp_in_size; + } + + return in_pos; +} + +CP_TEXT_SRAM_LOC +static int cp_decode_a2dp_begin(enum APP_OVERLAY_ID_T overlay_type) +{ + cp_dec_start_time = hal_fast_sys_timer_get(); +#ifndef A2DP_TRACE_CP_DEC_TIME + cp_dec_trace_time = false; +#endif + + if (cp_dec_state[cp_dec_idx] != CP_DEC_STATE_IDLE && cp_dec_state[cp_dec_idx] != CP_DEC_STATE_WORKING) { + return 1; + } + + if (cp_dec_state[cp_dec_idx] == CP_DEC_STATE_IDLE) { + cp_dec_state[cp_dec_idx] = CP_DEC_STATE_WORKING; + cp_out_len[cp_dec_idx] = 0; + cp_dec_mtu_cnt[cp_dec_idx] = 0; + } + + return 0; +} + +CP_TEXT_SRAM_LOC +static int cp_load_a2dp_encoded_data(enum APP_OVERLAY_ID_T overlay_type, uint8_t **p_data, uint32_t *p_len) +{ + int ret = -1; + + if (0) { +#if defined(A2DP_LDAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LDAC) { + ret = cp_load_ldac_frame(p_data, p_len); +#endif +#if defined(A2DP_LHDC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LHDC) { + ret = cp_load_lhdc_frame(p_data, p_len); +#endif +#if defined(A2DP_AAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_AAC) { + ret = cp_load_aac_frame(p_data, p_len); +#endif + } else if (overlay_type == APP_OVERLAY_A2DP) { + ret = cp_load_sbc_frame(p_data, p_len); + } + + return ret; +} + +CP_TEXT_SRAM_LOC +static int cp_decode_a2dp_process(enum APP_OVERLAY_ID_T overlay_type, uint8_t *out, uint32_t out_max, uint32_t *p_out_len, + const uint8_t *in, uint32_t in_len, uint32_t *p_consume_len) +{ + int ret = -1; + + if (p_out_len) { + *p_out_len = 0; + } + if (p_consume_len) { + *p_consume_len = 0; + } + + if (0) { +#if defined(A2DP_LDAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LDAC) { + ret = decode_ldac_frame(out, out_max, p_out_len, in, in_len, p_consume_len); +#endif +#if defined(A2DP_AAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_AAC) { + ret = decode_aac_frame(out, out_max, p_out_len, in, in_len, p_consume_len); +#endif +#if defined(A2DP_SCALABLE_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_SCALABLE) { + ret = decode_scalable_frame(out, out_max, p_out_len, in, in_len, p_consume_len); +#endif +#if defined(A2DP_LHDC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LHDC) { + ret = decode_lhdc_frame(out, out_max, p_out_len, in, in_len, p_consume_len); +#endif + } else if (overlay_type == APP_OVERLAY_A2DP) { + ret = decode_sbc_frame(out, out_max, p_out_len, in, in_len, p_consume_len); + } + + return ret; +} + +CP_TEXT_SRAM_LOC +static int cp_consume_a2dp_encoded_data(enum APP_OVERLAY_ID_T overlay_type, const uint8_t *data, uint32_t len) +{ + if (0) { +#if defined(A2DP_LDAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LDAC) { + cp_consume_ldac_frame(data, len); +#endif + } else if (overlay_type == APP_OVERLAY_A2DP) { + cp_consume_sbc_frame(data, len); + } + + return 0; +} + +CP_TEXT_SRAM_LOC +static void cp_decode_a2dp_end(enum APP_OVERLAY_ID_T overlay_type, uint32_t expect_out_len, uint32_t out_len, uint32_t in_len, bool retry) +{ + uint32_t etime; + uint8_t old_cp_dec_idx; + + if (0) { +#if defined(A2DP_LDAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LDAC) { + cp_decode_ldac_end(expect_out_len, out_len, in_len); +#endif + } + + old_cp_dec_idx = cp_dec_idx; + + cp_out_len[cp_dec_idx] += out_len; + + if (!retry) { + if (expect_out_len == out_len) { + cp_dec_state[cp_dec_idx] = CP_DEC_STATE_DONE; + } else { + cp_dec_state[cp_dec_idx] = CP_DEC_STATE_FAILED; + } + + cp_dec_idx++; + if (cp_dec_idx >= CP_DEC_SLOT_CNT) { + cp_dec_idx = 0; + } + } + + etime = hal_fast_sys_timer_get(); + if (cp_dec_trace_time) { + TRACE(4,"cp_decode[%u]: %u us in %u us (r=%u)", old_cp_dec_idx, FAST_TICKS_TO_US(etime - cp_dec_start_time), FAST_TICKS_TO_US(etime - cp_last_dec_time), retry); + } +#ifdef A2DP_TRACE_CP_ACCEL + if (retry) { + TRACE(3,"cp_decode[%u]:retry: cp_out_len=%u out_len=%u", old_cp_dec_idx, cp_out_len[old_cp_dec_idx], out_len); + } +#endif + cp_last_dec_time = etime; +} + +CP_TEXT_SRAM_LOC +static int cp_decode_a2dp_frame(enum APP_OVERLAY_ID_T overlay_type, unsigned char *pcm_buffer, unsigned int pcm_len) +{ + uint32_t all_out_len = 0, all_in_len = 0; + int ret, ret2; + uint32_t out_len; + uint8_t *enc_data; + uint32_t enc_len; + uint32_t consume_len; + bool retry = false; + + ret = cp_decode_a2dp_begin(overlay_type); + if (ret) { + return 0; + } + + while (all_out_len < pcm_len) { + ret = cp_load_a2dp_encoded_data(overlay_type, &enc_data, &enc_len); + if (ret) { + retry = true; + break; + } + + ret = cp_decode_a2dp_process(overlay_type, &pcm_buffer[all_out_len], pcm_len - all_out_len, &out_len, enc_data, enc_len, &consume_len); + + ret2 = cp_consume_a2dp_encoded_data(overlay_type, enc_data, consume_len); + + all_out_len += out_len; + + if (ret || ret2) { + break; + } + } + + cp_decode_a2dp_end(overlay_type, pcm_len, all_out_len, all_in_len, retry); + + return all_out_len; +} + +CP_TEXT_SRAM_LOC +unsigned int cp_a2dp_main(uint8_t event) +{ + uint32_t out_wpos; + uint32_t out_len; + uint32_t pcm_len; + + do { + if (cp_dec_state[cp_dec_idx] == CP_DEC_STATE_WORKING) { + if (cp_out_len[cp_dec_idx] < cp_out_loop_size) { + pcm_len = cp_out_loop_size - cp_out_len[cp_dec_idx]; + } else { + cp_out_len[cp_dec_idx] = 0; + pcm_len = cp_out_loop_size; + } + } else { + pcm_len = cp_out_loop_size; + } + out_wpos = cp_out_loop_size * cp_dec_idx + cp_out_loop_size - pcm_len; + + out_len = cp_decode_a2dp_frame(cp_overlay_type, &cp_out_cache[out_wpos], cp_out_loop_size); + } while (out_len == pcm_len); + + return 0; +} + +FRAM_TEXT_LOC +static void mcu_decode_a2dp_init(uint32_t out_max) +{ + uint32_t i; + + if (mcu_dec_inited == false) { + mcu_dec_inited = true; + + cp_in_size = sizeof(cp_in_cache); + cp_out_size = out_max * CP_DEC_SLOT_CNT; + ASSERT(cp_out_size <= sizeof(cp_out_cache), "%s: cp_out_cache too small (should >= %u)", __func__, cp_out_size); + cp_out_loop_size = out_max; + + cp_overlay_type = app_get_current_overlay(); + + for (i = 0; i < CP_DEC_SLOT_CNT; i++) { + cp_dec_state[i] = CP_DEC_STATE_IDLE; + cp_dec_mtu_cnt[i] = 0; + cp_out_len[i] = 0; + } + +#if defined(A2DP_LHDC_ON) + // Increase latency to improve data buffering + mcu_dec_idx = 1; +#else + mcu_dec_idx = CP_DEC_SLOT_CNT - 1; +#endif + for (i = mcu_dec_idx; i < CP_DEC_SLOT_CNT; i++) { + cp_dec_state[i] = CP_DEC_STATE_DONE; + cp_out_len[i] = cp_out_loop_size; + } + } +} + +FRAM_TEXT_LOC +static int mcu_load_a2dp_encoded_data(uint8_t **p_data, uint32_t *p_len) +{ + uint32_t free_len; + uint32_t in_wpos, in_rpos; + uint32_t size; + int r = 0; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + + in_wpos = cp_in_wpos; + in_rpos = cp_in_rpos; + + if (in_wpos < in_rpos) { + free_len = in_rpos - in_wpos - 1; + } else { + free_len = cp_in_size - in_wpos + in_rpos - 1; + } + + if (free_len == 0) { + return 0; + } + + LOCK_APP_AUDIO_QUEUE(); + size = LengthOfCQueue(&sbc_queue); + UNLOCK_APP_AUDIO_QUEUE(); + + if (size > free_len) { + size = free_len; + } + + LOCK_APP_AUDIO_QUEUE(); + r = PeekCQueue(&sbc_queue, size, &e1, &len1, &e2, &len2); + UNLOCK_APP_AUDIO_QUEUE(); + + if (r == CQ_ERR) { + TRACE(2,"%s: Failed to get %u from sbc_queue", __func__, size); + return 1; + } + + if (in_wpos < in_rpos) { + if (len1) { + memcpy(&cp_in_cache[in_wpos], e1, len1); + in_wpos += len1; + } + if (len2) { + memcpy(&cp_in_cache[in_wpos], e2, len2); + in_wpos += len2; + } + } else { + free_len = cp_in_size - in_wpos; + if (len1) { + if (free_len > len1) { + free_len = len1; + } + memcpy(&cp_in_cache[in_wpos], e1, free_len); + len1 -= free_len; + e1 += free_len; + in_wpos = cp_update_in_cache_pos(in_wpos, free_len); + if (len1) { + memcpy(&cp_in_cache[in_wpos], e1, len1); + in_wpos = cp_update_in_cache_pos(in_wpos, len1); + } + if (in_wpos < in_rpos) { + free_len = in_rpos - in_wpos - 1; + } else { + free_len = cp_in_size - in_wpos; + } + } + if (len2) { + if (free_len > len2) { + free_len = len2; + } + memcpy(&cp_in_cache[in_wpos], e2, free_len); + len2 -= free_len; + e2 += free_len; + in_wpos = cp_update_in_cache_pos(in_wpos, free_len); + if (len2) { + memcpy(&cp_in_cache[in_wpos], e2, len2); + in_wpos = cp_update_in_cache_pos(in_wpos, len2); + } + } + } + + cp_in_wpos = in_wpos; + + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&sbc_queue, NULL, size); + UNLOCK_APP_AUDIO_QUEUE(); + + return 0; +} + +FRAM_TEXT_LOC +static int mcu_decode_a2dp_process(uint8_t *out, uint32_t out_max, uint32_t *p_out_len, + const uint8_t *in, uint32_t in_len, uint32_t *p_consume_len) +{ + int ret = 0; + uint32_t out_rpos; + +#ifdef A2DP_TRACE_CP_ACCEL + TRACE(3,"mcu_dec_proc[%u]: state=%u len=%u", mcu_dec_idx, cp_dec_state[mcu_dec_idx], cp_out_len[mcu_dec_idx]); +#endif + + cp_accel_send_event_mcu2cp(CP_BUILD_ID(CP_TASK_A2DP_DECODE, CP_EVENT_A2DP_DECODE)); + + if (cp_dec_state[mcu_dec_idx] != CP_DEC_STATE_DONE) { + ret = 1; + goto _exit; + } + if (cp_out_len[mcu_dec_idx] != out_max) { + ret = 2; + goto _exit; + } + + out_rpos = cp_out_loop_size * mcu_dec_idx; + + memcpy(out, &cp_out_cache[out_rpos], out_max); + + if (p_out_len) { + *p_out_len = out_max; + } + +_exit: + if (cp_dec_state[mcu_dec_idx] == CP_DEC_STATE_DONE || cp_dec_state[mcu_dec_idx] == CP_DEC_STATE_FAILED) { + if (mtu_count > cp_dec_mtu_cnt[mcu_dec_idx]) { + mtu_count -= cp_dec_mtu_cnt[mcu_dec_idx]; + } else { + mtu_count = 0; + } + + cp_dec_state[mcu_dec_idx] = CP_DEC_STATE_IDLE; + + mcu_dec_idx++; + if (mcu_dec_idx >= CP_DEC_SLOT_CNT) { + mcu_dec_idx = 0; + } + } + + return ret; +} + +static struct cp_task_desc TASK_DESC_A2DP = {CP_ACCEL_STATE_CLOSED, cp_a2dp_main, NULL, NULL, NULL}; +void cp_a2dp_init(void) +{ + mcu_dec_inited = false; + norflash_api_flush_disable(NORFLASH_API_USER_CP,(uint32_t)cp_accel_init_done); + cp_accel_open(CP_TASK_A2DP_DECODE, &TASK_DESC_A2DP); + while(cp_accel_init_done() == false) { + hal_sys_timer_delay_us(100); + } + norflash_api_flush_enable(NORFLASH_API_USER_CP); +} + +void cp_a2dp_deinit(void) +{ + cp_accel_close(CP_TASK_A2DP_DECODE); +} +#endif + +FRAM_TEXT_LOC +static int decode_a2dp_begin(enum APP_OVERLAY_ID_T overlay_type) +{ +#ifdef TIMER1_BASE + dec_start_time = hal_fast_sys_timer_get(); +#else + dec_start_time = hal_sys_timer_get(); +#endif +#ifndef A2DP_TRACE_DEC_TIME + dec_trace_time = false; +#endif + +#ifndef A2DP_CP_ACCEL + if (overlay_type == APP_OVERLAY_A2DP) { + decode_sbc_begin(); + } +#endif + + return 0; +} + +FRAM_TEXT_LOC +static int load_a2dp_encoded_data(enum APP_OVERLAY_ID_T overlay_type, uint8_t **p_data, uint32_t *p_len) +{ + int ret = -1; + +#ifdef A2DP_CP_ACCEL + ret = mcu_load_a2dp_encoded_data(p_data, p_len); +#else + if (0) { +#if defined(A2DP_LDAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LDAC) { + ret = load_ldac_frame(p_data, p_len); +#endif +#if defined(A2DP_AAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_AAC) { + ret = load_aac_frame(p_data, p_len); +#endif +#if defined(A2DP_SCALABLE_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_SCALABLE) { + ret = load_scalable_frame(p_data, p_len); +#endif +#if defined(A2DP_LHDC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LHDC) { + ret = load_lhdc_frame(p_data, p_len); +#endif + } else if (overlay_type == APP_OVERLAY_A2DP) { + ret = load_sbc_frame(p_data, p_len); + } +#endif + + return ret; +} + +FRAM_TEXT_LOC +static int decode_a2dp_process(enum APP_OVERLAY_ID_T overlay_type, uint8_t *out, uint32_t out_max, uint32_t *p_out_len, + const uint8_t *in, uint32_t in_len, uint32_t *p_consume_len) +{ + int ret = -1; + + if (p_out_len) { + *p_out_len = 0; + } + if (p_consume_len) { + *p_consume_len = 0; + } + +#ifdef A2DP_CP_ACCEL + ret = mcu_decode_a2dp_process(out, out_max, p_out_len, in, in_len, p_consume_len); +#else + if (0) { +#if defined(A2DP_LDAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LDAC) { + ret = decode_ldac_frame(out, out_max, p_out_len, in, in_len, p_consume_len); +#endif +#if defined(A2DP_AAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_AAC) { + ret = decode_aac_frame(out, out_max, p_out_len, in, in_len, p_consume_len); +#endif +#if defined(A2DP_SCALABLE_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_SCALABLE) { + ret = decode_scalable_frame(out, out_max, p_out_len, in, in_len, p_consume_len); +#endif +#if defined(A2DP_LHDC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LHDC) { + ret = decode_lhdc_frame(out, out_max, p_out_len, in, in_len, p_consume_len); +#endif + } else if (overlay_type == APP_OVERLAY_A2DP) { + ret = decode_sbc_frame(out, out_max, p_out_len, in, in_len, p_consume_len); + } +#endif + + return ret; +} + +FRAM_TEXT_LOC +static int consume_a2dp_encoded_data(enum APP_OVERLAY_ID_T overlay_type, const uint8_t *data, uint32_t len) +{ +#ifndef A2DP_CP_ACCEL + if (0) { +#if defined(A2DP_LDAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LDAC) { + consume_ldac_frame(data, len); +#endif + } else if (overlay_type == APP_OVERLAY_A2DP) { + consume_sbc_frame(data, len); + } +#endif + + return 0; +} + +FRAM_TEXT_LOC +static void decode_a2dp_end(enum APP_OVERLAY_ID_T overlay_type, uint32_t expect_out_len, uint32_t out_len, uint32_t in_len) +{ + uint32_t etime; + +#ifdef A2DP_CP_ACCEL + + if (0) { +#if defined(A2DP_LDAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LDAC) { + mcu_decode_ldac_end(expect_out_len, out_len, in_len); +#endif + } + +#else + + if (0) { +#if defined(A2DP_LDAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LDAC) { + decode_ldac_end(expect_out_len, out_len, in_len); +#endif +#if defined(A2DP_LHDC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LHDC) { + decode_lhdc_end(expect_out_len, out_len, in_len); +#endif + } else if (overlay_type == APP_OVERLAY_A2DP) { + decode_sbc_end(expect_out_len, out_len, in_len); + } + +#endif + + if (dec_reset_queue) { + dec_reset_queue = false; + LOCK_APP_AUDIO_QUEUE(); + ResetCQueue(&sbc_queue); + TRACE(0,"Reset queue"); + UNLOCK_APP_AUDIO_QUEUE(); + } + +#ifdef TIMER1_BASE + etime = hal_fast_sys_timer_get(); + if (dec_trace_time) { + TRACE(2,"a2dp decode: %u us in %u us", FAST_TICKS_TO_US(etime - dec_start_time), FAST_TICKS_TO_US(etime - last_dec_time)); + } +#else + etime = hal_sys_timer_get(); + if (dec_trace_time) { + TRACE(2,"a2dp decode: %u ms in %u ms", TICKS_TO_MS(etime - dec_start_time), TICKS_TO_MS(etime - last_dec_time)); + } +#endif + last_dec_time = etime; +} + +FRAM_TEXT_LOC +static int decode_a2dp_frame(enum APP_OVERLAY_ID_T overlay_type, unsigned char *pcm_buffer, unsigned int pcm_len) +{ + uint32_t all_out_len = 0, all_in_len = 0; + int ret, ret2; + uint32_t out_len; + uint8_t *enc_data; + uint32_t enc_len; + uint32_t consume_len; + +#ifdef A2DP_CP_ACCEL + mcu_decode_a2dp_init(pcm_len); +#endif + + ret = decode_a2dp_begin(overlay_type); + if (ret) { + return 0; + } + + while (all_out_len < pcm_len) { + ret = load_a2dp_encoded_data(overlay_type, &enc_data, &enc_len); + if (ret) { + break; + } + + ret = decode_a2dp_process(overlay_type, pcm_buffer + all_out_len, pcm_len - all_out_len, &out_len, enc_data, enc_len, &consume_len); + + ret2 = consume_a2dp_encoded_data(overlay_type, enc_data, consume_len); + + all_out_len += out_len; + all_in_len += consume_len; + + if (ret || ret2) { + break; + } + } + + decode_a2dp_end(overlay_type, pcm_len, all_out_len, all_in_len); + + return all_out_len; +} + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) +#define AAC_RESAMPLE_ITER_LEN (1024 * 2 * 2) +#define SBC_RESAMPLE_ITER_LEN (128 * 2 * 2) + +static struct APP_RESAMPLE_T *a2dp_resample; + +FRAM_TEXT_LOC +static int a2dp_resample_iter(uint8_t *buf, uint32_t len) +{ + enum APP_OVERLAY_ID_T overlay_type; + + overlay_type = app_get_current_overlay(); + + uint32_t l = decode_a2dp_frame(overlay_type, buf, len); + if (l != len) { + TRACE(2,"a2dp_audio_more_data decode err %d/%d", l, len); + return 1; + } + return 0; +} +#endif + +extern bool process_delay(int32_t delay_ms); + +void static attempt_slow_samplerate(uint8_t overlay_type) +{ + uint32_t current_mtu_conut =0; + if (check_interval >0) + check_interval--; + assumed_mtu_interval = 20; + current_mtu_conut = mtu_count; + + if (lagest_mtu_in1s < current_mtu_conut) + lagest_mtu_in1s = current_mtu_conut; + if (least_mtu_in1s > current_mtu_conut) + least_mtu_in1s = current_mtu_conut; + + if (check_interval == 0) + { + int32_t delay_ms = 0; + if(overlay_type == APP_OVERLAY_A2DP){ + delay_ms = (delay_mtu_limit-(int)lagest_mtu_in1s)*128*1000/a2dp_sample_rate; + }else +#if defined(A2DP_AAC_ON) + if(overlay_type == APP_OVERLAY_A2DP_AAC){ + delay_ms = (delay_mtu_limit-(int)lagest_mtu_in1s)*1024*1000/a2dp_sample_rate; + }else +#endif +#if defined(A2DP_SCALABLE_ON) + if(overlay_type == APP_OVERLAY_A2DP_SCALABLE){ + delay_ms = (delay_mtu_limit-(int)lagest_mtu_in1s)*864*1000/a2dp_sample_rate; + }else +#endif +#if defined(A2DP_LHDC_ON) + if(overlay_type == APP_OVERLAY_A2DP_LHDC){ + delay_ms = (delay_mtu_limit-(int)lagest_mtu_in1s)*512*1000/a2dp_sample_rate; + }else +#endif +#if defined(A2DP_LDAC_ON) + if(overlay_type == APP_OVERLAY_A2DP_LDAC){ + delay_ms = (delay_mtu_limit-(int)lagest_mtu_in1s)*256*1000/a2dp_sample_rate; + }else +#endif + { + delay_ms = (delay_mtu_limit-(int)lagest_mtu_in1s)*assumed_mtu_interval; + } + TRACE(6,"store_interval=%d,lagest_mtu_in1s=%d,least_mtu_in1s=%d,delay_ms=%d,frame_len=%d,mtu_count=%d",ssb_err_max,lagest_mtu_in1s,least_mtu_in1s,delay_ms,sbc_frame_rev_len,mtu_count); + process_delay(delay_ms); + check_interval = 50; + lagest_mtu_in1s = 0; + least_mtu_in1s = 0xffffffff; + } +} + +// A2DP_EQ_24BIT == 1, buf should be 32bit(24bit) +// A2DP_EQ_24BIT == 0, buf should be 16bit +uint32_t a2dp_audio_more_data(uint8_t overlay_type, uint8_t *buf, uint32_t len) +{ + uint32_t l = 0; + + if (!a2dp_audio_isrunning(A2DPPLAY_STRTEAM_GET, true)){ + } + +#ifdef A2DP_EQ_24BIT + // Change len to 16-bit sample buffer length + if ((bt_sbc_player_get_sample_bit() == 16) +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + || allow_resample +#endif + ) { + len = len / (sizeof(int32_t) / sizeof(int16_t)); + } +#endif + + if (a2dp_cache_status == APP_AUDIO_CACHE_CACHEING){ +#if FPGA==0 + TRACE(1,"a2dp_audio_more_data cache not ready skip frame %d\n" ,overlay_type); +#endif + } else { +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + if (allow_resample) + { + app_playback_resample_run(a2dp_resample, buf, len); + } + else +#endif + { + l = decode_a2dp_frame((enum APP_OVERLAY_ID_T)overlay_type, buf, len); + if (l != len) { + TRACE(2,"a2dp_audio_more_data decode err %d/%d", l, len); + if (l < len){ + memset(buf + l, 0, len - l); + //a2dp_cache_status = APP_AUDIO_CACHE_CACHEING; + TRACE(0,"set to APP_AUDIO_CACHE_CACHEING"); + } + } else { + //TRACE(2,"a2dp_audio_more_data decode success %d/%d", l, len); + } + } + if (a2dp_cache_status == APP_AUDIO_CACHE_OK) { + attempt_slow_samplerate(overlay_type); + } + } + +#ifdef A2DP_EQ_24BIT + if ((bt_sbc_player_get_sample_bit() == 16) +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + || allow_resample +#endif + ) { + convert_16bit_to_24bit((int32_t *)buf, (int16_t *)buf, len / sizeof(int16_t)); + // Restore len to 24-bit sample buffer length + len = len * (sizeof(int32_t) / sizeof(int16_t)); + } +#endif + + A2DP_SYNC_WITH_GET_MUTUX_SET(); + + return len; +} + +#if defined(A2DP_LDAC_ON) +/* Convert LDAC Error Code to string */ +#define CASE_RETURN_STR(const) case const: return #const; +static const char * ldac_ErrCode2Str( int ErrCode ) +{ + switch(ErrCode){ + CASE_RETURN_STR(LDACBT_ERR_NONE); + CASE_RETURN_STR(LDACBT_ERR_NON_FATAL); + CASE_RETURN_STR(LDACBT_ERR_BIT_ALLOCATION); + CASE_RETURN_STR(LDACBT_ERR_NOT_IMPLEMENTED); + CASE_RETURN_STR(LDACBT_ERR_NON_FATAL_ENCODE); + CASE_RETURN_STR(LDACBT_ERR_FATAL); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_BAND); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_GRAD_A); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_GRAD_B); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_GRAD_C); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_GRAD_D); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_GRAD_E); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_IDSF); + CASE_RETURN_STR(LDACBT_ERR_SYNTAX_SPEC); + CASE_RETURN_STR(LDACBT_ERR_BIT_PACKING); + CASE_RETURN_STR(LDACBT_ERR_ALLOC_MEMORY); + CASE_RETURN_STR(LDACBT_ERR_FATAL_HANDLE); + CASE_RETURN_STR(LDACBT_ERR_ILL_SYNCWORD); + CASE_RETURN_STR(LDACBT_ERR_ILL_SMPL_FORMAT); + CASE_RETURN_STR(LDACBT_ERR_ILL_PARAM); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_SAMPLING_FREQ); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_SUP_SAMPLING_FREQ); + CASE_RETURN_STR(LDACBT_ERR_CHECK_SAMPLING_FREQ); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_CHANNEL_CONFIG); + CASE_RETURN_STR(LDACBT_ERR_CHECK_CHANNEL_CONFIG); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_FRAME_LENGTH); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_SUP_FRAME_LENGTH); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_FRAME_STATUS); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_NSHIFT); + CASE_RETURN_STR(LDACBT_ERR_ASSERT_CHANNEL_MODE); + CASE_RETURN_STR(LDACBT_ERR_ENC_INIT_ALLOC); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_GRADMODE); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_GRADPAR_A); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_GRADPAR_B); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_GRADPAR_C); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_GRADPAR_D); + CASE_RETURN_STR(LDACBT_ERR_ENC_ILL_NBANDS); + CASE_RETURN_STR(LDACBT_ERR_PACK_BLOCK_FAILED); + CASE_RETURN_STR(LDACBT_ERR_DEC_INIT_ALLOC); + CASE_RETURN_STR(LDACBT_ERR_INPUT_BUFFER_SIZE); + CASE_RETURN_STR(LDACBT_ERR_UNPACK_BLOCK_FAILED); + CASE_RETURN_STR(LDACBT_ERR_UNPACK_BLOCK_ALIGN); + CASE_RETURN_STR(LDACBT_ERR_UNPACK_FRAME_ALIGN); + CASE_RETURN_STR(LDACBT_ERR_FRAME_LENGTH_OVER); + CASE_RETURN_STR(LDACBT_ERR_FRAME_ALIGN_OVER); + CASE_RETURN_STR(LDACBT_ERR_ALTER_EQMID_LIMITED); + CASE_RETURN_STR(LDACBT_ERR_ILL_EQMID); + CASE_RETURN_STR(LDACBT_ERR_ILL_SAMPLING_FREQ); + CASE_RETURN_STR(LDACBT_ERR_ILL_NUM_CHANNEL); + CASE_RETURN_STR(LDACBT_ERR_ILL_MTU_SIZE); + CASE_RETURN_STR(LDACBT_ERR_HANDLE_NOT_INIT); + default: + return "unknown-error-code"; + } +} + + +char a_ErrorCodeStr[128]; +const char * get_error_code_string( int error_code ) +{ + int errApi, errHdl, errBlk; + + errApi = LDACBT_API_ERR( error_code ); + errHdl = LDACBT_HANDLE_ERR( error_code ); + errBlk = LDACBT_BLOCK_ERR( error_code ); + + a_ErrorCodeStr[0] = '\0'; + strcat( a_ErrorCodeStr, "API:" ); + strcat( a_ErrorCodeStr, ldac_ErrCode2Str( errApi ) ); + strcat( a_ErrorCodeStr, " Handle:" ); + strcat( a_ErrorCodeStr, ldac_ErrCode2Str( errHdl ) ); + strcat( a_ErrorCodeStr, " Block:" ); + strcat( a_ErrorCodeStr, ldac_ErrCode2Str( errBlk ) ); + return a_ErrorCodeStr; +} +#endif + +extern uint8_t bt_sbc_player_get_bitsDepth(void); +#if defined(A2DP_LDAC_ON) +uint32_t ldac_buffer_used = 0; +#endif + +static const char *a2dp_get_codec_name(enum APP_OVERLAY_ID_T overlay_type) +{ + const char *codec_name; + + if (0) { +#if defined(A2DP_LDAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LDAC) { + codec_name = "LDAC"; +#endif +#if defined(A2DP_AAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_AAC) { + codec_name = "AAC"; +#endif +#if defined(A2DP_SCALABLE_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_SCALABLE) { + codec_name = "SCALABLE"; +#endif +#if defined(A2DP_LHDC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_LHDC) { + codec_name = "LHDC"; +#endif + } else if (overlay_type == APP_OVERLAY_A2DP) { + codec_name = "SBC"; + } else { + codec_name = "UNKNOWN"; + } + + return codec_name; +} + +static void a2dp_trace_codec_name(const char *prefix, enum APP_OVERLAY_ID_T overlay_type) +{ + TRACE(3,"\n\n%s: codecType=%x->:%s\n", prefix, overlay_type,a2dp_get_codec_name(overlay_type)); +} + +int a2dp_audio_init(void) +{ + const float EQLevel[25] = { + 0.0630957, 0.0794328, 0.1, 0.1258925, 0.1584893, + 0.1995262, 0.2511886, 0.3162278, 0.398107 , 0.5011872, + 0.6309573, 0.794328 , 1, 1.258925 , 1.584893 , + 1.995262 , 2.5118864, 3.1622776, 3.9810717, 5.011872 , + 6.309573 , 7.943282 , 10 , 12.589254, 15.848932 + };//-12~12 + uint8_t *buff = NULL; + uint8_t i; + + enum APP_OVERLAY_ID_T overlay_type; + + overlay_type = app_get_current_overlay(); + + a2dp_trace_codec_name(__func__, overlay_type); + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + APP_RESAMPLE_ITER_CALLBACK iter_cb; + + uint32_t iter_len; + + iter_cb = a2dp_resample_iter; + + if (0) { +#if defined(A2DP_AAC_ON) + } else if (overlay_type == APP_OVERLAY_A2DP_AAC) { + iter_len = AAC_RESAMPLE_ITER_LEN; +#endif + } else if (overlay_type == APP_OVERLAY_A2DP) { + iter_len = SBC_RESAMPLE_ITER_LEN; + } else { + ASSERT(false, "%s: Bad app overlay type for play resample: %d", __func__, overlay_type); + } + +#ifdef CHIP_BEST1000 + if(hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2 && hal_sysfreq_get() <= HAL_CMU_FREQ_52M) + { + allow_resample = true; + } +#endif + if (allow_resample) + { +#ifdef RESAMPLE_ANY_SAMPLE_RATE + float ratio; + if (a2dp_sample_rate % AUD_SAMPRATE_8000) { + ratio = (float)CODEC_FREQ_22P5792M * ((float)a2dp_sample_rate / AUD_SAMPRATE_44100) / CODEC_FREQ_26M; + } else { + ratio = (float)CODEC_FREQ_24P576M * ((float)a2dp_sample_rate / AUD_SAMPRATE_48000) / CODEC_FREQ_26M; + } + a2dp_resample = app_playback_resample_any_open(AUD_CHANNEL_NUM_2, + iter_cb, iter_len, ratio); +#else + a2dp_resample = app_playback_resample_open(a2dp_sample_rate, AUD_CHANNEL_NUM_2, + iter_cb, iter_len); +#endif + } +#endif + + for (i=0; i= 24 ? 1 : 0); + //extern const char __testkey_start[]; + extern const char testkey_bin[]; + lhdcSetLicenseKeyTable((uint8_t *)testkey_bin); + + TRACE(0,"lhdcSetLicenseKeyTable,testkey_bin:\n"); + for(uint8_t i=0;i<128;i++){ + TRACE(1,"i = %d", i); + DUMP8("0x%02x ", &testkey_bin[i], 32); + i+= 31; + } + lhdcInit(bits_depth, sample_rate, 0); + initial_lhdc_assemble_packet(false); + } +#endif + +#ifdef SBC_QUEUE_SIZE + if (0) { +#if defined(A2DP_AAC_ON) || defined(A2DP_SCALABLE_ON) || defined(A2DP_LHDC_ON) + } else if(overlay_type == APP_OVERLAY_A2DP_AAC){ + #if defined(MIX_MIC_DURING_MUSIC) + g_sbc_queue_size = app_audio_mempool_free_buff_size() - 4096; + #else + g_sbc_queue_size = app_audio_mempool_free_buff_size(); + #endif +#endif +#if defined(A2DP_SCALABLE_ON) + } else if(overlay_type == APP_OVERLAY_A2DP_SCALABLE){ + #if defined(MIX_MIC_DURING_MUSIC) + g_sbc_queue_size = app_audio_mempool_free_buff_size() - 4096; + #else + g_sbc_queue_size = app_audio_mempool_free_buff_size(); + #endif +#endif +#if defined(A2DP_LHDC_ON) + } else if(overlay_type == APP_OVERLAY_A2DP_LHDC){ + #if defined(MIX_MIC_DURING_MUSIC) + g_sbc_queue_size = app_audio_mempool_free_buff_size() - 4096; + #else + g_sbc_queue_size = app_audio_mempool_free_buff_size(); + #endif +#endif + } else { + g_sbc_queue_size = SBC_QUEUE_SIZE; + } +#else + g_sbc_queue_size = app_audio_mempool_free_buff_size(); +#endif + +#if defined(A2DP_LDAC_ON) + if(overlay_type == APP_OVERLAY_A2DP_LDAC) + { + //if((bt_sbc_player_get_codec_type() == BTIF_AVDTP_CODEC_TYPE_NON_A2DP)){ + //app_audio_mempool_get_buff(&g_medMemHeap, MED_MEM_HEAP_SIZE); + //speech_heap_init((uint8_t *)(&g_medMemHeap[0]), MED_MEM_HEAP_SIZE); + g_sbc_queue_size = app_audio_mempool_free_buff_size() - MED_MEM_HEAP_SIZE; + TRACE(1,"A2DP_LDAC_ON g_sbc_queue_size %d\n", g_sbc_queue_size); + } +#endif + + app_audio_mempool_get_buff(&buff, g_sbc_queue_size); + ASSERT((buff!=NULL), "%s:get sbc queue buff fail, size %d bytes!", __func__, g_sbc_queue_size); + memset(buff, 0, g_sbc_queue_size); + a2dp_audio_isrunning(A2DPPLAY_STRTEAM_PUT, false); + a2dp_audio_isrunning(A2DPPLAY_STRTEAM_GET, false); + + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_InitCQueue(&sbc_queue, g_sbc_queue_size, buff); + UNLOCK_APP_AUDIO_QUEUE(); + +#if defined(A2DP_LDAC_ON) + if(overlay_type == APP_OVERLAY_A2DP_LDAC){ + ldac_buffer_used = app_audio_mempool_total_buf() - app_audio_mempool_free_buff_size(); + ldac_recovery = false; + ldac_dec_init(); + } +#endif + +#ifdef A2DP_AUDIO_SYNC_WITH_LOCAL + a2dp_audio_sync_proc(A2DPPLAY_SYNC_STATUS_SET|A2DPPLAY_SYNC_STATUS_RESET, A2DP_AUDIO_SYNC_WITH_LOCAL_SAMPLERATE_DEFAULT); +#endif + +#ifdef A2DP_CP_ACCEL + cp_a2dp_init(); +#endif + + a2dp_cache_status = APP_AUDIO_CACHE_CACHEING; + need_init_decoder = true; + dec_reset_queue = false; + + sbc_frame_rev_len = 0; + sbc_frame_num = 0; + sbc_frame_size = SBC_TEMP_BUFFER_SIZE; + mtu_count = 0; + assumed_mtu_interval = 0; + return 0; +} + +int a2dp_audio_deinit(void) +{ + enum APP_OVERLAY_ID_T overlay_type; + + overlay_type = app_get_current_overlay(); + + a2dp_trace_codec_name(__func__, overlay_type); + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + if (allow_resample) { + app_playback_resample_close(a2dp_resample); + a2dp_resample = NULL; +#ifdef CHIP_BEST1000 + allow_resample = false; +#endif + } +#endif + +#ifdef A2DP_CP_ACCEL + cp_a2dp_deinit(); +#endif + +#if defined(A2DP_LDAC_ON) + if(overlay_type == APP_OVERLAY_A2DP_LDAC){ + ldac_dec_deinit(); + } +#endif + +#if defined(A2DP_LHDC_ON) + if(overlay_type == APP_OVERLAY_A2DP_LHDC){ + lhdcDestroy(); + } +#endif + +#if defined(A2DP_AAC_ON) + aacdec_deinit(); + aac_memdeinit(); +#endif + + A2DP_SYNC_WITH_GET_MUTUX_SET(); + A2DP_SYNC_WITH_PUT_MUTUX_SET(); + + A2DP_SYNC_WITH_GET_MUTUX_FREE(); + A2DP_SYNC_WITH_PUT_MUTUX_FREE(); + + a2dp_audio_isrunning(A2DPPLAY_STRTEAM_PUT, false); + a2dp_audio_isrunning(A2DPPLAY_STRTEAM_GET, false); + + a2dp_cache_status = APP_AUDIO_CACHE_QTY; + need_init_decoder = true; + + sbc_frame_rev_len = 0; + sbc_frame_num = 0; + sbc_frame_size = SBC_TEMP_BUFFER_SIZE; + mtu_count = 0; + assumed_mtu_interval = 0; + + return 0; +} + +float a2dp_audio_latency_factor_get(void) +{ + return 1.0f; +} +#endif diff --git a/apps/audioplayers/app_audio.cpp b/apps/audioplayers/app_audio.cpp new file mode 100644 index 0000000..b85a1ec --- /dev/null +++ b/apps/audioplayers/app_audio.cpp @@ -0,0 +1,791 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "app_bt_trace.h" +#include "string.h" + +#include "cqueue.h" +#include "list.h" +#include "hal_aud.h" +#include "resources.h" +#include "app_thread.h" +#include "app_audio.h" +#include "app_media_player.h" +#include "app_ring_merge.h" +#include "nvrecord.h" +#include + +#include "a2dp_api.h" + +#include "btapp.h" +#include "app_bt_media_manager.h" + +extern uint8_t __StackLimit[]; +extern uint8_t __HeapLimit[]; + +static const size_t heap_size = __StackLimit - __HeapLimit - 512; + +static bool app_audio_init = false; + +static uint32_t capture_audio_buff_size_used; +// from the bottom of the system available memory pool, size is APP_CAPTURE_AUDIO_BUFFER_SIZE +// can be overlayed with the sco used audio buffer +static uint8_t* capture_audio_buffer = __HeapLimit + heap_size - APP_CAPTURE_AUDIO_BUFFER_SIZE; + +int app_capture_audio_mempool_init(void) +{ + TRACE_AUD_HDL_I("[CAPMEM][INIT] size %d.", APP_CAPTURE_AUDIO_BUFFER_SIZE); + capture_audio_buff_size_used = 0; + memset((uint8_t *)capture_audio_buffer, 0, APP_CAPTURE_AUDIO_BUFFER_SIZE); + + return 0; +} + +uint32_t app_capture_audio_mempool_free_buff_size() +{ + return APP_CAPTURE_AUDIO_BUFFER_SIZE - capture_audio_buff_size_used; +} + +int app_capture_audio_mempool_get_buff(uint8_t **buff, uint32_t size) +{ + uint32_t buff_size_free; + uint8_t* capture_buf_addr = (uint8_t *)capture_audio_buffer; + buff_size_free = app_capture_audio_mempool_free_buff_size(); + + if (size % 4){ + size = size + (4 - size % 4); + } + + TRACE_AUD_HDL_I("[CAPMEM][GET] current free %d to allocate %d", buff_size_free, size); + + ASSERT(size <= buff_size_free, "[%s] size = %d > free size = %d", __func__, size, buff_size_free); + + *buff = capture_buf_addr + capture_audio_buff_size_used; + + capture_audio_buff_size_used += size; + TRACE_AUD_HDL_I("[CAPMEM][GET] %d, now used %d left %d", + size, capture_audio_buff_size_used, app_capture_audio_mempool_free_buff_size()); + + return 0; +} + +osPoolDef (app_audio_status_mempool, 20, APP_AUDIO_STATUS); +osPoolId app_audio_status_mempool = NULL; + +// control queue access +osMutexId g_app_audio_queue_mutex_id = NULL; +osMutexDef(g_app_audio_queue_mutex); + +// control pcmbuff access +static CQueue app_audio_pcm_queue; +static osMutexId app_audio_pcmbuff_mutex_id = NULL; +osMutexDef(app_audio_pcmbuff_mutex); + +#ifdef __AUDIO_QUEUE_SUPPORT__ + +typedef struct { + list_t *audio_list; +}APP_AUDIO_CONFIG; + +APP_AUDIO_CONFIG app_audio_conifg = { + .audio_list = NULL +}; + +#endif + +void LOCK_APP_AUDIO_QUEUE() +{ + osMutexWait(g_app_audio_queue_mutex_id, osWaitForever); +} + +void UNLOCK_APP_AUDIO_QUEUE() +{ + osMutexRelease(g_app_audio_queue_mutex_id); +} + +uint32_t app_audio_lr_balance(uint8_t *buf, uint32_t len, int8_t balance) +{ + short *balance_buf=(short *)buf; + uint32_t balance_len = len/2; + float factor; + + ASSERT((balance >= -100) && (balance <= 100), "balance = %d is invalid!", balance); + + if(balance > 0) + { + //reduce L channel + factor = 1 - 0.01 * balance; + for(uint32_t i=0; iid == APP_PLAY_BACK_AUDIO) + num++; + } + return num; +} +#endif +#endif + +static bool need_flush_flash_switch_audio = false; +void app_audio_switch_flash_flush_req(void) +{ + uint32_t lock; + + lock = int_lock(); + need_flush_flash_switch_audio = true; + int_unlock(lock); +} + +static void app_audio_switch_flash_proc(void) +{ + // no need to do this across the audio switch, + // will use suspend flash erase to assure that no audio + // irq is missing for handling caused by long time global irq disabling + // during flash erase. + // Just flash the nvrecord flash periodically + return; + + uint32_t lock; + bool need_flush_flash = false; + + lock = int_lock(); + if (need_flush_flash_switch_audio){ + need_flush_flash_switch_audio = false; + need_flush_flash = true; + } + int_unlock(lock); + + if (need_flush_flash){ +#ifndef FPGA + nv_record_flash_flush(); +#endif + } +} + +#ifdef VOICE_DATAPATH +static bool app_audio_handle_pre_processing(APP_MESSAGE_BODY *msg_body) +{ + uint16_t stream_type; + APP_AUDIO_GET_AUD_ID(msg_body->message_ptr, stream_type); + + bool isToResetCaptureStream = false; + if ((BT_STREAM_SBC == stream_type) || (BT_STREAM_MEDIA == stream_type)) + { + if (app_audio_manager_capture_is_active()) + { + isToResetCaptureStream = true; + } + } + + if (isToResetCaptureStream) + { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP, + BT_STREAM_CAPTURE, 0, 0); + + APP_MESSAGE_BLOCK msg; + msg.msg_body = *msg_body; + msg.mod_id = APP_MODUAL_AUDIO_MANAGE; + app_mailbox_put(&msg); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START, + BT_STREAM_CAPTURE, 0, 0); + + return false; + } + else + { + return true; + } +} +#endif + +static int app_audio_handle_process(APP_MESSAGE_BODY *msg_body) +{ + int nRet = -1; + + APP_AUDIO_STATUS aud_status; + + if (app_audio_init == false) + return -1; + +#ifdef VOICE_DATAPATH + bool isContinue = app_audio_handle_pre_processing(msg_body); + if (!isContinue) + { + return -1; + } +#endif + + APP_AUDIO_GET_ID(msg_body->message_id, aud_status.id); + APP_AUDIO_GET_STATUS(msg_body->message_id, aud_status.status); + APP_AUDIO_GET_AUD_ID(msg_body->message_ptr, aud_status.aud_id); + APP_AUDIO_GET_FREQ(msg_body->message_Param0, aud_status.freq); + + switch (aud_status.status) + { + case APP_BT_SETTING_OPEN: +#ifdef __AUDIO_QUEUE_SUPPORT__ + TRACE_AUD_HDL_I( + "[OPEN] before status_id: 0x%x%s, aud_id: %d, len = %d", + aud_status.id, + player2str(aud_status.id), + aud_status.aud_id, + list_length(app_audio_conifg.audio_list)); + + if (app_audio_list_append(&aud_status)) + { + app_bt_stream_open(&aud_status); + TRACE_AUD_HDL_I( + "[OPEN] after status_id: 0x%x%s, len = %d", + aud_status.id, + player2str(aud_status.id), + list_length(app_audio_conifg.audio_list)); + } +#else + app_bt_stream_open(&aud_status); +#endif + + break; + case APP_BT_SETTING_CLOSE: + app_audio_switch_flash_proc(); +#ifdef __AUDIO_QUEUE_SUPPORT__ + APP_AUDIO_STATUS next_status; + TRACE_AUD_HDL_I( + "[CLOSE] current id: 0x%x%s", + aud_status.id, + player2str(aud_status.id)); + app_bt_stream_close(aud_status.id); + app_audio_switch_flash_proc(); +#ifdef MEDIA_PLAYER_SUPPORT + if (aud_status.id == APP_PLAY_BACK_AUDIO) + { + TRACE_AUD_HDL_I("[CLOSE] list: %d", app_audio_get_list_playback_num()); + if (app_audio_get_list_playback_num() == 1) + { + TRACE_AUD_HDL_I("=======>APP_BT_SETTING_CLOSE MEDIA"); + bt_media_stop(BT_STREAM_MEDIA, BT_DEVICE_ID_1); + } + } +#endif + if (app_audio_list_rmv_callback(&aud_status, &next_status, APP_BT_SETTING_Q_POS_HEAD, false)) + { + TRACE_AUD_HDL_I( + "[CLOSE] %p, next id: 0x%x%s, status %d", + &next_status, + next_status.id, + player2str(next_status.id), + next_status.status); + app_bt_stream_open(&next_status); + } +#else + app_bt_stream_close(aud_status.id); + app_audio_switch_flash_proc(); +#endif + break; + case APP_BT_SETTING_SETUP: + app_bt_stream_setup(aud_status.id, msg_body->message_ptr); + break; + case APP_BT_SETTING_RESTART: + app_bt_stream_restart(&aud_status); + break; + case APP_BT_SETTING_CLOSEALL: + app_bt_stream_closeall(); +#ifdef __AUDIO_QUEUE_SUPPORT__ + app_audio_list_clear(); +#endif + app_audio_switch_flash_proc(); + break; + default: + break; + } + + return nRet; +} + +#ifdef __AUDIO_QUEUE_SUPPORT__ +static void app_audio_handle_free(void* data) +{ +#ifdef MEDIA_PLAYER_SUPPORT + APP_AUDIO_STATUS * status = (APP_AUDIO_STATUS * )data; + + if(status->id == APP_PLAY_BACK_AUDIO) + { + TRACE_AUD_HDL_I("[HANDLE_FREE] , aud_id: 0x%x, type = 0x%x", status->aud_id, status->aud_type); + } +#endif + osPoolFree (app_audio_status_mempool, data); +} + +void app_audio_list_create() +{ + if (app_audio_conifg.audio_list == NULL) + { + app_audio_conifg.audio_list = list_new(app_audio_handle_free, NULL, NULL); + } +} + +bool app_audio_list_stream_exist() +{ + APP_AUDIO_STATUS *audio_handle = NULL; + list_node_t *node = NULL; + + for (node = list_begin(app_audio_conifg.audio_list); node != list_end(app_audio_conifg.audio_list); node = list_next(node)) { + + audio_handle = (APP_AUDIO_STATUS *)list_node(node); + if(audio_handle == NULL) + { + return false; + } + if (audio_handle->id == APP_BT_STREAM_HFP_PCM || + audio_handle->id == APP_BT_STREAM_HFP_CVSD || + audio_handle->id == APP_BT_STREAM_HFP_VENDOR || + audio_handle->id == APP_BT_STREAM_A2DP_SBC || + audio_handle->id == APP_BT_STREAM_A2DP_AAC || +#ifdef VOICE_DATAPATH + audio_handle->id == APP_BT_STREAM_VOICEPATH || +#endif +#ifdef __AI_VOICE__ + audio_handle->id == APP_BT_STREAM_AI_VOICE || +#endif +#ifdef __THIRDPARTY + audio_handle->id == APP_BT_STREAM_THIRDPARTY_VOICE || +#endif + audio_handle->id == APP_BT_STREAM_A2DP_VENDOR + ) { + TRACE_AUD_HDL_I("[STREAM_LIST][EXIST] id 0x%x", audio_handle->id); + return true; + } + } + + return false; +} + +bool app_audio_list_filter_exist(APP_AUDIO_STATUS* aud_status) +{ +#ifdef MEDIA_PLAYER_SUPPORT + APP_AUDIO_STATUS *audio_handle = NULL; + list_node_t *node = NULL; + uint8_t cnt = 0; + + if (aud_status->id == APP_PLAY_BACK_AUDIO){ + if(aud_status->aud_id == AUD_ID_BT_CALL_INCOMING_CALL) { + for (node = list_begin(app_audio_conifg.audio_list); node != list_end(app_audio_conifg.audio_list); node = list_next(node)) { + audio_handle = (APP_AUDIO_STATUS *)list_node(node); + if(audio_handle == NULL) + { + return false; + } + if (audio_handle->id == APP_PLAY_BACK_AUDIO && audio_handle->aud_id == AUD_ID_BT_CALL_INCOMING_CALL) { + TRACE_AUD_HDL_I("[STREAM_LIST][FILTER] id 0x%x", audio_handle->id); + return true; + } + } + } else { + for (node = list_begin(app_audio_conifg.audio_list); node != list_end(app_audio_conifg.audio_list); node = list_next(node)) { + audio_handle = (APP_AUDIO_STATUS *)list_node(node); + if (cnt++ > 1) { + TRACE_AUD_HDL_I("[STREAM_LIST][FILTER] cnt %d", cnt); + return true; + } + } + } + } +#endif + return false; +} + +bool app_audio_list_playback_exist(void) +{ +#ifdef MEDIA_PLAYER_SUPPORT + APP_AUDIO_STATUS *audio_handle = NULL; + list_node_t *node = NULL; + + for (node = list_begin(app_audio_conifg.audio_list); node != list_end(app_audio_conifg.audio_list); node = list_next(node)) { + audio_handle = (APP_AUDIO_STATUS *)list_node(node); + if(audio_handle == NULL) + { + return false; + } + if (audio_handle->id == APP_PLAY_BACK_AUDIO) { + TRACE_AUD_HDL_I("[STREAM_LIST][PLAYBACK_EXIST]"); + return true; + } + } +#endif + return false; +} + +void app_audio_list_playback_clear(void) +{ +#ifdef MEDIA_PLAYER_SUPPORT + APP_AUDIO_STATUS *audio_handle = NULL; + list_node_t *node = NULL; + + for (node = list_begin(app_audio_conifg.audio_list); node != list_end(app_audio_conifg.audio_list); node = list_next(node)) { + audio_handle = (APP_AUDIO_STATUS *)list_node(node); + if(audio_handle == NULL) + { + TRACE_AUD_HDL_I("[STREAM_LIST][CLR] find null\n "); + return; + } + if (audio_handle->id == APP_PLAY_BACK_AUDIO){ + list_remove(app_audio_conifg.audio_list, list_node(node)); + } + } +#endif +} + +bool app_audio_list_append(APP_AUDIO_STATUS* aud_status) +{ + APP_AUDIO_STATUS *data_to_append = NULL; + bool add_data_to_head_of_list = false; + bool ret = true; + TRACE_AUD_HDL_I("[STREAM_LIST][APPEND] id 0x%x%s", aud_status->id, player2str(aud_status->id)); +#ifdef MEDIA_PLAYER_SUPPORT + if (aud_status->id == APP_PLAY_BACK_AUDIO) + { + //ignore redundant ring ind from hfp... + if (app_audio_list_filter_exist(aud_status)) + { + return false; + } + + if (app_audio_list_playback_exist()) + { + if (list_length(app_audio_conifg.audio_list) >= MAX_AUDIO_BUF_LIST) + { + if (app_audio_list_stream_exist()) + { + data_to_append = (APP_AUDIO_STATUS *)osPoolCAlloc (app_audio_status_mempool); + if(data_to_append == NULL) + { + return false; + } + memcpy(data_to_append, (const void *)list_front(app_audio_conifg.audio_list), sizeof(APP_AUDIO_STATUS)); + add_data_to_head_of_list = true; + } + + app_audio_list_clear(); + TRACE_AUD_HDL_E("[STREAM_LIST][APPEND] FIXME!!!!\n "); + } + else + { + ret = false; + } + } + } + else +#endif + { + add_data_to_head_of_list = true; + } + + if (data_to_append == NULL) + { + data_to_append = (APP_AUDIO_STATUS *)osPoolCAlloc (app_audio_status_mempool); + if(data_to_append == NULL) + { + return false; + } + memcpy(data_to_append, aud_status, sizeof(APP_AUDIO_STATUS)); + } + + if (add_data_to_head_of_list) + { + list_prepend(app_audio_conifg.audio_list, (void*)data_to_append); + } + else + { + list_append(app_audio_conifg.audio_list, (void*)data_to_append); + } + + TRACE_AUD_HDL_I("[STREAM_LIST][APPEND] id 0x%x%s status %d len %d ret %d", data_to_append->id, player2str(data_to_append->id), \ + data_to_append->status, list_length(app_audio_conifg.audio_list), ret); + return ret; +} + +bool app_audio_list_rmv_callback(APP_AUDIO_STATUS *status_close, APP_AUDIO_STATUS *status_next, enum APP_BT_AUDIO_Q_POS pos, bool pop_next) +{ + void *data_to_remove = NULL; + bool ret = false; + + //for status: first bt_a2dp->APP_BT_SETTING_CLOSE,then ring-> APP_BT_SETTING_CLOSE + TRACE_AUD_HDL_I("[STREAM_LIST][RMV] audio list len %d close_id 0x%x%s", list_length(app_audio_conifg.audio_list), \ + status_close->id, player2str(status_close->id)); + if(list_length(app_audio_conifg.audio_list) == 0) + { + return false; + } + +#ifdef MEDIA_PLAYER_SUPPORT + APP_AUDIO_STATUS *audio_handle = NULL; + list_node_t *node = NULL; + if (status_close->id == APP_PLAY_BACK_AUDIO) + { + for (node = list_begin(app_audio_conifg.audio_list); node != list_end(app_audio_conifg.audio_list); node = list_next(node)) + { + audio_handle = (APP_AUDIO_STATUS *)list_node(node); + if(audio_handle == NULL) + { + return ret; + } + if (audio_handle->id == APP_PLAY_BACK_AUDIO) + { + list_node_t *nod_next = list_next(node); + data_to_remove = list_node(node); + + if (pop_next) + { + memcpy(status_next, list_node(node), sizeof(APP_AUDIO_STATUS)); + ret = true; + break; + } + if (nod_next != NULL) + { + memcpy(status_next, list_node(nod_next), sizeof(APP_AUDIO_STATUS)); + ASSERT(status_next->id == APP_PLAY_BACK_AUDIO, "[%s] 111ERROR: status_next->id != APP_PLAY_BACK_AUDIO", __func__); + + ret = true; + } + else if (app_audio_list_stream_exist()) + { + void *indata = list_front(app_audio_conifg.audio_list); + if(indata == NULL) + { + return ret; + } + memcpy(status_next, indata, sizeof(APP_AUDIO_STATUS)); + ASSERT(status_next->id != APP_PLAY_BACK_AUDIO, "[%s] 222ERROR: status_next->id != APP_PLAY_BACK_AUDIO", __func__); + + ret = true; + } + break; + } + } + } + else //maybe...a2dp send >> APP_BT_SETTING_CLOSE, when ring +#endif + { + if (app_audio_list_stream_exist()) + { + if(pos == APP_BT_SETTING_Q_POS_HEAD) + { + data_to_remove = list_front(app_audio_conifg.audio_list); + } + else if (pos == APP_BT_SETTING_Q_POS_TAIL) + { + data_to_remove = list_back(app_audio_conifg.audio_list); + } + } + } + + if (data_to_remove) + { + list_remove(app_audio_conifg.audio_list, data_to_remove); + } + TRACE_AUD_HDL_I("[STREAM_LIST][RMV] end len:%d ret %d data %p", list_length(app_audio_conifg.audio_list), ret, data_to_remove); + return ret; +} + +void app_audio_list_clear() +{ + list_clear(app_audio_conifg.audio_list); +} +#endif + +void app_audio_open(void) +{ + if(app_audio_init) + { + return; + } + if (g_app_audio_queue_mutex_id == NULL) + { + g_app_audio_queue_mutex_id = osMutexCreate((osMutex(g_app_audio_queue_mutex))); + } + else + { + ASSERT(0, "[%s] ERROR: g_app_audio_queue_mutex_id != NULL", __func__); + } + + if (app_audio_status_mempool == NULL) + app_audio_status_mempool = osPoolCreate(osPool(app_audio_status_mempool)); + ASSERT(app_audio_status_mempool, "[%s] ERROR: app_audio_status_mempool != NULL", __func__); + +#ifdef __AUDIO_QUEUE_SUPPORT__ + app_audio_list_create(); +#endif + app_ring_merge_init(); + + app_set_threadhandle(APP_MODUAL_AUDIO, app_audio_handle_process); + + app_bt_stream_init(); + + app_audio_init = true; +} + +void app_audio_close(void) +{ + app_set_threadhandle(APP_MODUAL_AUDIO, NULL); + app_audio_init = false; +} + + diff --git a/apps/audioplayers/app_audio.h b/apps/audioplayers/app_audio.h new file mode 100644 index 0000000..0023090 --- /dev/null +++ b/apps/audioplayers/app_audio.h @@ -0,0 +1,224 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_AUDIO_H__ +#define __APP_AUDIO_H__ + +#include "app_bt_stream.h" +#include "heap_api.h" + +//should solve this problem +//#include "./../../utils/cqueue/cqueue.h" +//#include "cqueue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//This buff is used as queue +#ifndef APP_AUDIO_BUFFER_SIZE +#if (RAM_SIZE >= 0x48000) + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + +#if defined(A2DP_EQ_24BIT) +#define APP_AUDIO_BUFFER_SIZE (1024 * 210) +#else +#define APP_AUDIO_BUFFER_SIZE (1024 * 140) +#endif + +#else +#define APP_AUDIO_BUFFER_SIZE (1024 * 100) +#endif + +#elif (RAM_SIZE >= 0x40000) + +#ifdef NEW_NV_RECORD_ENABLED +#define APP_AUDIO_BUFFER_SIZE (1024 * 62) +#else +#define APP_AUDIO_BUFFER_SIZE (1024 * 59) +#endif + +#else // RAM_SIZE < 0x40000 + +#ifdef APP_TEST_AUDIO +#define APP_AUDIO_BUFFER_SIZE (1024 * 10) +#elif defined(SPEECH_RX_NS) +#define APP_AUDIO_BUFFER_SIZE (1024 * 37) +#else +#define APP_AUDIO_BUFFER_SIZE (1024 * 32) +#endif + +#endif // RAM_SIZE < 0x40000 +#endif + +#if defined(VOB_ENCODING_ALGORITHM) && (VOB_ENCODING_ALGORITHM == ENCODING_ALGORITHM_OPUS) + +#ifdef __ALEXA_WWE +#ifdef __ALEXA_WWE_LITE +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (63*1024) +#else +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (305*1024) +#endif + +#elif defined(SPEECH_CAPTURE_TWO_CHANNEL) +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (76*1024) +#elif defined(__DUAL_MIC_RECORDING__) +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (79*1024) +#else +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (67*1024) +#endif + +#elif defined(__AMA_VOICE__) && (VOB_ENCODING_ALGORITHM == ENCODING_ALGORITHM_SBC) +#if defined(CHIP_BEST1400) && defined(__AI_VOICE__) +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (13*1024) +#else +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (17*1024) +#endif +#elif defined(__KWS_ALEXA__) +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (160*1024) +#elif defined(AI_CAPTURE_DATA_AEC) +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (19*1024-512) +#elif defined(GSOUND_HOTWORD_EXTERNAL) +/// gsound_external_hotword_configuration +#ifdef VOICE_DETECTOR_EN +/// VAD_enabled_configuration +#ifdef VAD_USE_8K_SAMPLE_RATE +/// vad_use_8K_sample_rate_configuration +#define APP_CAPTURE_AUDIO_BUFFER_SIZE ((32 + 16 + 32)*1024-512) +/// vad_use_8K_sample_rate_configuration +#else +/// vad_use_16K_sample_rate_configuration +#define APP_CAPTURE_AUDIO_BUFFER_SIZE ((32 + 32)*1024-512) +/// vad_use_16K_sample_rate_configuration +#endif +/// VAD_enabled_configuration +#else +/// VAD_disabled_configuration +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (32*1024-512) +/// VAD_disabled_configuration +#endif +/// gsound_external_hotword_configuration +#else +#ifdef VOICE_DETECTOR_EN +/// VAD_enabled_configuration +#define APP_CAPTURE_AUDIO_BUFFER_SIZE ((13 + 32)*1024-512) +/// VAD_enabled_configuration +#else +/// VAD_disabled_configuration +#define APP_CAPTURE_AUDIO_BUFFER_SIZE (13*1024-512) +/// VAD_disabled_configuration +#endif +#endif + +#if defined(A2DP_SCALABLE_ON) +#define SCALABLE_FRAME_SIZE (864) +#define SCALABLE_HEAD_SIZE (4) /* pick something big enough to hold a bunch of frames */ +#define SCALABLE_READBUF_SIZE (500) /* pick something big enough to hold a bunch of frames */ +#define SCALABLE_DECODER_SIZE (17456) /* pick something big enough to hold a bunch of frames */ +#define SBM_FAST_SPEED 67380 // 840 2.76% +#define SBM_SLOW_SPEED 63730 // 888 2.76% +#define SBM_NUM_NORMAL 100 +#endif + +#define MAX_AUDIO_BUF_LIST 20 +enum APP_AUDIO_CACHE_T { + APP_AUDIO_CACHE_CACHEING= 0, + APP_AUDIO_CACHE_OK, + APP_AUDIO_CACHE_QTY, +}; + +#define APP_AUDIO_SET_MESSAGE(appevt, id, status) (appevt = (((uint32_t)id&0xffff)<<16)|(status&0xffff)) +#define APP_AUDIO_GET_ID(appevt, id) (id = (appevt>>16)&0xffff) +#define APP_AUDIO_GET_STATUS(appevt, status) (status = appevt&0xffff) +#define APP_AUDIO_GET_AUD_ID(appevt, aud_id) (aud_id = appevt) +#define APP_AUDIO_GET_FREQ(appevt, freq) (freq = appevt) + +#define APP_AUDIO_InitCQueue(a, b, c) InitCQueue(a, b, c) +#define APP_AUDIO_AvailableOfCQueue(a) AvailableOfCQueue(a) +#define APP_AUDIO_LengthOfCQueue(a) LengthOfCQueue(a) +#define APP_AUDIO_PeekCQueue(a, b, c, d, e, f) PeekCQueue(a, b, c, d, e, f) +#define APP_AUDIO_EnCQueue(a, b, c) EnCQueue(a, b, c) +#define APP_AUDIO_DeCQueue(a, b, c) DeCQueue(a, b, c) + +#define app_audio_mempool_init syspool_init + +#define app_audio_mempool_noclr_init syspool_init + +#define app_audio_mempool_use_mempoolsection_init syspool_init + +#define app_audio_mempool_free_buff_size syspool_free_size + +#define app_audio_mempool_get_buff syspool_get_buff + +#if defined(A2DP_LDAC_ON) +#define app_audio_mempool_total_buf syspool_total_size +#define app_audio_mempool_force_set_buff_used syspool_force_used_size +#endif + + +void UNLOCK_APP_AUDIO_QUEUE(); + +void LOCK_APP_AUDIO_QUEUE(); + +uint32_t app_audio_lr_balance(uint8_t *buf, uint32_t len, int8_t balance); + +void app_audio_mempool_init_with_specific_size(uint32_t size); + +int app_audio_pcmbuff_init(uint8_t *buff, uint16_t len); + +int app_audio_pcmbuff_length(void); + +int app_audio_pcmbuff_put(uint8_t *buff, uint16_t len); + +int app_audio_pcmbuff_get(uint8_t *buff, uint16_t len); + +int app_audio_pcmbuff_discard(uint16_t len); + +void app_audio_memcpy_16bit(int16_t *des, int16_t *src, int len); + +void app_audio_memset_16bit(int16_t *des, int16_t val, int len); + + +int app_audio_sendrequest(uint16_t id, uint8_t status, uint32_t ptr); + + +int app_audio_sendrequest_param(uint16_t id, uint8_t status, uint32_t ptr, uint32_t param); + +void app_audio_open(void); + +void app_audio_close(void); + +bool app_audio_list_append(APP_AUDIO_STATUS* aud_status); + +bool app_audio_list_playback_exist(void); + +void app_audio_list_playback_clear(void); + +bool app_audio_list_rmv_callback(APP_AUDIO_STATUS *status_close, APP_AUDIO_STATUS *status_next, enum APP_BT_AUDIO_Q_POS pos, bool pop_next); + +void app_audio_list_clear(); + +int app_capture_audio_mempool_init(void); + +uint32_t app_capture_audio_mempool_free_buff_size(); + +int app_capture_audio_mempool_get_buff(uint8_t **buff, uint32_t size); + +#ifdef __cplusplus +} +#endif + +#endif//__FMDEC_H__ diff --git a/apps/audioplayers/bt_sco_chain.c b/apps/audioplayers/bt_sco_chain.c new file mode 100644 index 0000000..1ef715a --- /dev/null +++ b/apps/audioplayers/bt_sco_chain.c @@ -0,0 +1,1483 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** +// Speech process macro change table +// TX: Transimt process +// RX: Receive process +// 16k: base 25M/208M(1300,1302) base 28M/104M(1400,1402) +|-------|--------------------|-----------------------------------|----------------------------------|-----------|----------------------| +| TX/RX | New | Old | description | MIPS(M) | Note | +| | | | | 16k 8k | | +|-------|--------------------|-----------------------------------|----------------------------------|-----------|----------------------| +| | SPEECH_TX_DC_FILTER| | Direct Current filter | 1~2 \ | | +| | SPEECH_TX_AEC | SPEECH_ECHO_CANCEL | Acoustic Echo Cancellation(old) | 40 \ | HWFFT: 37 | +| | SPEECH_TX_AEC2 | SPEECH_AEC_FIX | Acoustic Echo Cancellation(new) | 39 \ | enable NLP | +| | SPEECH_TX_AEC3 | | Acoustic Echo Cancellation(new) | 14/18 \ | 2 filters/4 filters | +| | SPEECH_TX_AEC2FLOAT| | Acoustic Echo Cancellation(new) | 23/22 \ | nlp/af(blocks=1) | +| | SPEECH_TX_AEC2FLOAT| | Acoustic Echo Cancellation(ns) | 14/10 \ | banks=256/banks=128 | +| | (ns_enabled) | | | 8/6 \ | banks=64/banks=32 | +| | SPEECH_TX_NS | SPEECH_NOISE_SUPPRESS | 1 mic noise suppress(old) | 30 \ | HWFFT: 19 | +| | SPEECH_TX_NS2 | LC_MMSE_NOISE_SUPPRESS | 1 mic noise suppress(new) | 16 \ | HWFFT: 12 | +| | SPEECH_TX_NS3 | | 1 mic noise suppress(new) | 26 \ | | +| | SPEECH_TX_NS2FLOAT | LC_MMSE_NOISE_SUPPRESS_FLOAT | 1 mic noise suppress(new float) | 12.5 \ | banks=64 | +| TX | SPEECH_TX_2MIC_NS | DUAL_MIC_DENOISE | 2 mic noise suppres(long space) | \ | | +| | SPEECH_TX_2MIC_NS2 | 2MIC_DENOISE | 2 mic noise suppres(short space) | 22 | delay_taps 5M | +| | freq_smooth_enable 1.5M | | +| | wnr_enable 1.5M | +| | SPEECH_TX_2MIC_NS4 | SENSORMIC_DENOISE | sensor mic noise suppress | 31.5 | | +| | SPEECH_TX_2MIC_NS3 | FAR_FIELD_SPEECH_ENHANCEMENT | 2 mic noise suppres(far field) | \ | | +| | SPEECH_TX_2MIC_NS5 | LEFTRIGHT_DENOISE | 2 mic noise suppr(left right end)| \ | | +| | SPEECH_TX_2MIC_NS6 | FF_2MIC_DENOISE | 2 mic noise suppr(far field) | 70 | | +| | SPEECH_TX_AGC | SPEECH_AGC | Automatic Gain Control | 3 | | +| | SPEECH_TX_COMPEXP | | Compressor and expander | 4 | | +| | SPEECH_TX_EQ | SPEECH_WEIGHTING_FILTER_SUPPRESS | Default EQ | 0.5 \ | each section | +|-------|--------------------|-----------------------------------|----------------------------------|-----------|----------------------| +| | SPEECH_RX_NS | SPEAKER_NOISE_SUPPRESS | 1 mic noise suppress(old) | 30 \ | | +| RX | SPEECH_RX_NS2 | LC_MMSE_NOISE_SUPPRESS_SPK | 1 mic noise suppress(new) | 16 \ | | +| | SPEECH_RX_AGC | SPEECH_AGC_SPK | Automatic Gain Control | 3 | | +| | SPEECH_RX_EQ | SPEAKER_WEIGHTING_FILTER_SUPPRESS | Default EQ | 0.5 \ | each section | +|-------|--------------------|-----------------------------------|----------------------------------|-----------|----------------------| +**/ + +#include "plat_types.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "audio_dump.h" +#include "speech_cfg.h" +#include "bt_sco_chain.h" +#include "bt_sco_chain_cfg.h" +#include "bt_sco_chain_tuning.h" +#if defined(SPEECH_TX_2MIC_NS4) +#include "app_anc.h" +#endif +#include "app_utils.h" + +#if defined(SCO_CP_ACCEL) +#include "hal_location.h" +#include "bt_sco_chain_cp.h" + +#define SCO_CP_ACCEL_ALGO_START() \ + *_pcm_len = pcm_len; \ + } \ + CP_TEXT_SRAM_LOC \ + void _speech_tx_process_mid(short *pcm_buf, short *ref_buf, int *_pcm_len) \ + { \ + int pcm_len = *_pcm_len; + +#define SCO_CP_ACCEL_ALGO_END() \ + *_pcm_len = pcm_len; \ + } \ + void _speech_tx_process_post(short *pcm_buf, short *ref_buf, int *_pcm_len) \ + { \ + int pcm_len = *_pcm_len; + +#define SPEECH_TX_AEC2FLOAT_CORE 1 +#define SPEECH_TX_NS2FLOAT_CORE 0 +#define SPEECH_RX_NS2FLOAT_CORE 0 + +#else +#define SCO_CP_ACCEL_ALGO_START() +#define SCO_CP_ACCEL_ALGO_END() + +#define SPEECH_TX_AEC2FLOAT_CORE 0 +#define SPEECH_TX_NS2FLOAT_CORE 0 +#define SPEECH_RX_NS2FLOAT_CORE 0 + +#endif + +#if defined(SCO_OPTIMIZE_FOR_RAM) +extern uint8_t *sco_overlay_ram_buf; +extern int sco_overlay_ram_buf_len; +#endif + +//#define BT_SCO_CHAIN_PROFILE +//#define BT_SCO_CHAIN_AUDIO_DUMP + +#if defined(BT_SCO_CHAIN_PROFILE) +static uint32_t tx_start_ticks = 0; +static uint32_t tx_end_ticks = 0; +#endif + +extern const SpeechConfig speech_cfg_default; +static SpeechConfig *speech_cfg = NULL; + +FrameResizeState *speech_frame_resize_st = NULL; + +#if defined(SPEECH_TX_24BIT) +int32_t *aec_echo_buf = NULL; + +static int16_t *tx_pcmbuf16 = NULL; +static int32_t *tx_pcmbuf32 = NULL; +#else +short *aec_echo_buf = NULL; +#endif + +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) +// Use to free buffer +#if defined(SPEECH_TX_24BIT) +static int32_t *aec_echo_buf_ptr; +static int16_t *tx_refbuf16 = NULL; +static int32_t *tx_refbuf32 = NULL; +#else +static short *aec_echo_buf_ptr; +#endif +static short *aec_out_buf; +#endif + +/*--------------------TX state--------------------*/ +#if defined(SPEECH_TX_DC_FILTER) +SpeechDcFilterState *speech_tx_dc_filter_st = NULL; +#endif + +#if defined(SPEECH_TX_MIC_CALIBRATION) +SpeechIirCalibState *speech_tx_mic_calib_st = NULL; +extern const SpeechIirCalibConfig speech_tx_mic_calib_cfg; +#endif + +#if defined(SPEECH_TX_MIC_FIR_CALIBRATION) +SpeechFirCalibState *speech_tx_mic_fir_calib_st = NULL; +extern const SpeechFirCalibConfig speech_tx_mic_fir_calib_cfg; +#endif + + +// AEC +#if defined(SPEECH_TX_AEC) +SpeechAecState *speech_tx_aec_st = NULL; +void *speech_tx_aec_lib_st = NULL; +#endif + +#if defined(SPEECH_TX_AEC2) +SpeechAec2State *speech_tx_aec2_st = NULL; +#endif + +#if defined(SPEECH_TX_AEC3) +short delay = 70; +short bufferstate[356]; +short buf_out[256]; +void CODEC_OpVecCpy( + short *pshwDes, + short *pshwSrc, + short swLen) +{ + short i = 0; + + for (i = 0; i < swLen; i++) + { + pshwDes[i] = pshwSrc[i]; + } +} + +SubBandAecState *speech_tx_aec3_st = NULL; +#endif + +#if defined(SPEECH_TX_AEC2FLOAT) +static Ec2FloatState *speech_tx_aec2float_st = NULL; +#endif + +// 2MIC NS +#if defined(SPEECH_TX_2MIC_NS) +// float mic2_ft_caliration[] = {0.395000,0.809000,0.939000,1.748000,1.904000,1.957000,1.944000,1.906000,1.935000,1.940000,1.937000,1.931000,1.929000,1.911000,1.887000,1.871000,1.846000,1.779000,1.748000,2.086000,2.055000,2.002000,1.903000,1.885000,1.854000,1.848000,1.848000,1.844000,1.852000,1.870000,1.866000,1.843000,1.838000,1.824000,1.861000,1.871000,1.866000,1.833000,1.800000,1.769000,1.749000,1.690000,1.664000,1.573000,1.602000,1.692000,1.759000,1.758000,1.698000,1.628000,1.525000,1.509000,1.492000,1.515000,1.530000,1.644000,1.653000,1.617000,1.667000,1.746000,1.663000,1.606000,1.560000,1.500000,1.579000,1.632000,1.623000,1.549000,1.524000,1.512000,1.493000,1.476000,1.421000,1.396000,1.386000,1.459000,1.463000,1.496000,1.568000,1.544000,1.555000,1.547000,1.619000,1.630000,1.574000,1.491000,1.414000,1.383000,1.352000,1.464000,1.474000,1.450000,1.419000,1.425000,1.411000,1.479000,1.517000,1.486000,1.428000,1.389000,1.330000,1.284000,1.267000,1.249000,1.256000,1.215000,1.250000,1.402000,1.386000,1.334000,1.287000,1.329000,1.337000,1.292000,1.226000,1.212000,1.142000,1.087000,1.086000,1.112000,1.145000,1.194000,1.163000,1.131000,1.162000,1.166000,1.259000,1.218000,1.218000,1.322000,1.347000,1.436000,1.890000,1.693000,1.591000,1.518000,1.422000,1.345000,1.331000,1.308000,1.330000,1.305000,1.218000,1.286000,1.340000,1.399000,1.406000,1.353000,1.280000,1.246000,1.185000,1.129000,1.014000,0.985000,0.981000,1.189000,1.533000,1.694000,1.613000,1.464000,1.419000,1.448000,1.449000,1.442000,1.367000,1.283000,1.232000,1.381000,1.484000,1.497000,1.554000,1.438000,1.365000,1.326000,1.332000,1.335000,1.367000,1.301000,1.288000,1.168000,1.103000,1.067000,1.026000,1.076000,1.126000,1.068000,1.045000,0.978000,0.926000,0.939000,0.854000,0.772000,0.902000,0.742000,1.073000,1.220000,1.177000,1.762000,1.573000,1.390000,1.406000,1.148000,1.054000,1.210000,1.344000,1.849000,2.078000,1.756000,1.646000,1.597000,1.447000,1.322000,1.279000,1.007000,0.921000,0.871000,0.864000,1.067000,1.129000,1.128000,1.027000,0.983000,0.889000,0.774000,0.759000,0.724000,0.949000,1.237000,1.499000,1.658000,1.837000,1.492000,1.452000,1.151000,1.100000,0.996000,0.986000,1.023000,1.071000,1.252000,1.295000,1.309000,1.343000,1.220000,1.161000,1.142000,1.041000,0.974000,0.885000,0.799000,0.669000,0.732000,0.953000,0.861000,0.881000,0.988000,0.891000}; +#endif + +#if defined(SPEECH_TX_2MIC_NS2) +Speech2MicNs2State *speech_tx_2mic_ns2_st = NULL; +#endif + +// #if defined(SPEECH_CS_VAD) +// VADState *speech_cs_vad_st = NULL; +// #endif + +#if defined(SPEECH_TX_2MIC_NS4) +SensorMicDenoiseState *speech_tx_2mic_ns4_st = NULL; +#endif + +#if defined(SPEECH_TX_2MIC_NS5) +LeftRightDenoiseState *speech_tx_2mic_ns5_st = NULL; +#endif + +#if defined(SPEECH_TX_2MIC_NS6) +SpeechFF2MicNs2State *speech_tx_2mic_ns6_st = NULL; +#endif + +#if defined(SPEECH_TX_3MIC_NS) +Speech3MicNsState *speech_tx_3mic_ns_st = NULL; +#endif + +#if defined(SPEECH_TX_3MIC_NS3) +TripleMicDenoise3State *speech_tx_3mic_ns3_st = NULL; +#endif + +// NS +#if defined(SPEECH_TX_NS) +SpeechNsState *speech_tx_ns_st = NULL; +#endif + +#if defined(SPEECH_TX_NS2) +SpeechNs2State *speech_tx_ns2_st = NULL; +#endif + +#if defined(SPEECH_TX_NS2FLOAT) +SpeechNs2FloatState *speech_tx_ns2float_st = NULL; +#endif + +#if defined(SPEECH_TX_NS3) +static Ns3State *speech_tx_ns3_st = NULL; +#endif + +#if defined(SPEECH_TX_WNR) +static WnrState *speech_tx_wnr_st = NULL; +#endif + +#if defined(SPEECH_TX_NOISE_GATE) +static NoisegateState *speech_tx_noise_gate_st = NULL; +#endif + +// Gain +#if defined(SPEECH_TX_COMPEXP) +static CompexpState *speech_tx_compexp_st = NULL; +#endif + +#if defined(SPEECH_TX_AGC) +static AgcState *speech_tx_agc_st = NULL; +#endif + +// EQ +#if defined(SPEECH_TX_EQ) +EqState *speech_tx_eq_st = NULL; +#endif + +// GAIN +#if defined(SPEECH_TX_POST_GAIN) +SpeechGainState *speech_tx_post_gain_st = NULL; +#endif + +/*--------------------RX state--------------------*/ +// NS +#if defined(SPEECH_RX_NS) +SpeechNsState *speech_rx_ns_st = NULL; +#endif + +#if defined(SPEECH_RX_NS2) +SpeechNs2State *speech_rx_ns2_st = NULL; +#endif + +#if defined(SPEECH_RX_NS2FLOAT) +SpeechNs2FloatState *speech_rx_ns2float_st = NULL; +#endif + +#if defined(SPEECH_RX_NS3) +static Ns3State *speech_rx_ns3_st = NULL; +#endif + +// GAIN +#if defined(SPEECH_RX_AGC) +static AgcState *speech_rx_agc_st = NULL; +#endif + +// EQ +#if defined(SPEECH_RX_EQ) +EqState *speech_rx_eq_st = NULL; +#endif + +// GAIN +#if defined(SPEECH_RX_POST_GAIN) +SpeechGainState *speech_rx_post_gain_st = NULL; +#endif + +#if defined(BONE_SENSOR_TDM) +#define SPEECH_TX_CHANNEL_NUM (SPEECH_CODEC_CAPTURE_CHANNEL_NUM + 1) +#else +#define SPEECH_TX_CHANNEL_NUM (SPEECH_CODEC_CAPTURE_CHANNEL_NUM) +#endif + +static bool dualmic_enable = true; + +void switch_dualmic_status(void) +{ + TRACE(3,"[%s] dualmic status: %d -> %d", __FUNCTION__, dualmic_enable, !dualmic_enable); + dualmic_enable ^= true; +} + +static int speech_tx_sample_rate = 16000; +static int speech_rx_sample_rate = 16000; +static int speech_tx_frame_len = 256; +static int speech_rx_frame_len = 256; +static bool speech_tx_frame_resizer_enable = false; +static bool speech_rx_frame_resizer_enable = false; + +static int32_t _speech_tx_process_(void *pcm_buf, void *ref_buf, int32_t *pcm_len); +static int32_t _speech_rx_process_(void *pcm_buf, int32_t *pcm_len); +enum APP_SYSFREQ_FREQ_T speech_get_proper_sysfreq(int *needed_mips); + + +void *speech_get_ext_buff(int size) +{ + void *pBuff = NULL; + if (size % 4) + { + size = size + (4 - size % 4); + } + + pBuff = speech_calloc(size, sizeof(uint8_t)); + TRACE(2,"[%s] len:%d", __func__, size); + + return pBuff; +} + +int speech_store_config(const SpeechConfig *cfg) +{ + if (speech_cfg) + { + memcpy(speech_cfg, cfg, sizeof(SpeechConfig)); + } + else + { + TRACE(1,"[%s] WARNING: Please phone call...", __func__); + } + + return 0; +} + +int speech_tx_init(int sample_rate, int frame_len) +{ + TRACE(3,"[%s] Start, sample_rate: %d, frame_len: %d", __func__, sample_rate, frame_len); + +#if defined(SPEECH_TX_DC_FILTER) + int channel_num = SPEECH_TX_CHANNEL_NUM; + int data_separation = 0; + + speech_tx_dc_filter_st = speech_dc_filter_create(sample_rate, &speech_cfg->tx_dc_filter); + speech_dc_filter_ctl(speech_tx_dc_filter_st, SPEECH_DC_FILTER_SET_CHANNEL_NUM, &channel_num); + speech_dc_filter_ctl(speech_tx_dc_filter_st, SPEECH_DC_FILTER_SET_DATA_SEPARATION, &data_separation); +#endif + +#if defined(SPEECH_TX_MIC_CALIBRATION) + speech_tx_mic_calib_st = speech_iir_calib_init(sample_rate, frame_len, &speech_tx_mic_calib_cfg); +#endif + +#if defined(SPEECH_TX_MIC_FIR_CALIBRATION) + speech_tx_mic_fir_calib_st = speech_fir_calib_init(sample_rate, frame_len, &speech_tx_mic_fir_calib_cfg); +#endif + +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) +// #if !(defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE)) + aec_out_buf = (short *)speech_calloc(frame_len, sizeof(short)); +#if defined(SPEECH_TX_24BIT) + aec_echo_buf = (int32_t *)speech_calloc(frame_len, sizeof(int32_t)); +#else + aec_echo_buf = (short *)speech_calloc(frame_len, sizeof(short)); +#endif + aec_echo_buf_ptr = aec_echo_buf; +// #endif +#endif + +#if defined(SPEECH_TX_AEC) + speech_tx_aec_st = speech_aec_create(sample_rate, frame_len, &speech_cfg->tx_aec); + speech_aec_ctl(speech_tx_aec_st, SPEECH_AEC_GET_LIB_ST, &speech_tx_aec_lib_st); +#endif + +#if defined(SPEECH_TX_AEC2) + speech_tx_aec2_st = speech_aec2_create(sample_rate, frame_len, &speech_cfg->tx_aec2); +#endif +#if defined(SPEECH_TX_AEC3) + speech_tx_aec3_st = SubBandAec_init(sample_rate, frame_len, &speech_cfg->tx_aec3); +#endif + +#if defined(SPEECH_TX_AEC2FLOAT) + speech_tx_aec2float_st = ec2float_create(sample_rate, frame_len, SPEECH_TX_AEC2FLOAT_CORE, &speech_cfg->tx_aec2float); +#endif + +#if defined(SPEECH_TX_2MIC_NS) + dual_mic_denoise_init(sample_rate, frame_len, &speech_cfg->tx_2mic_ns, NULL); + // dual_mic_denoise_ctl(DUAL_MIC_DENOISE_SET_CALIBRATION_COEF, mic2_ft_caliration); +#endif + +#if defined(SPEECH_TX_2MIC_NS2) + speech_tx_2mic_ns2_st = speech_2mic_ns2_create(sample_rate, frame_len, &speech_cfg->tx_2mic_ns2); +#endif + +// #if defined(SPEECH_CS_VAD) +// speech_cs_vad_st = VAD_process_state_init(sample_rate, 64, &speech_cfg->cs_vad); +// #endif + +#if defined(SPEECH_TX_2MIC_NS3) + far_field_speech_enhancement_init(); + far_field_speech_enhancement_start(); +#endif + +#if defined(SPEECH_TX_2MIC_NS5) + speech_tx_2mic_ns5_st = leftright_denoise_create(sample_rate, 64, &speech_cfg->tx_2mic_ns5); +#endif + +#if defined(SPEECH_TX_2MIC_NS6) + speech_tx_2mic_ns6_st = speech_ff_2mic_ns2_create(16000,128); +#endif + +#if defined(SPEECH_TX_2MIC_NS4) + //speech_tx_2mic_ns4_st = sensormic_denoise_create(sample_rate, 64, &speech_cfg->tx_2mic_ns4); + speech_tx_2mic_ns4_st = sensormic_denoise_create(sample_rate, 128, 256, 31, &speech_cfg->tx_2mic_ns4); +#endif + +#if defined(SPEECH_TX_3MIC_NS) + speech_tx_3mic_ns_st = speech_3mic_ns_create(sample_rate, 64, &speech_cfg->tx_3mic_ns); +#endif + +#if defined(SPEECH_TX_3MIC_NS3) + speech_tx_3mic_ns3_st = triple_mic_denoise3_init(sample_rate, frame_len, &speech_cfg->tx_3mic_ns3); +#endif + +#if defined(SPEECH_TX_NS) + speech_tx_ns_st = speech_ns_create(sample_rate, frame_len, &speech_cfg->tx_ns); +#if defined(SPEECH_TX_AEC) + speech_ns_ctl(speech_tx_ns_st, SPEECH_NS_SET_AEC_STATE, speech_tx_aec_lib_st); + int32_t echo_supress = -39; + speech_ns_ctl(speech_tx_ns_st, SPEECH_NS_SET_AEC_SUPPRESS, &echo_supress); +#endif +#endif + +#if defined(SPEECH_TX_NS2) + speech_tx_ns2_st = speech_ns2_create(sample_rate, frame_len, &speech_cfg->tx_ns2); +#if defined(SPEECH_TX_AEC) + speech_ns2_set_echo_state(speech_tx_ns2_st, speech_tx_aec_lib_st); + speech_ns2_set_echo_suppress(speech_tx_ns2_st, -40); +#endif +#endif + +#if defined(SPEECH_TX_NS2FLOAT) + speech_tx_ns2float_st = speech_ns2float_create(sample_rate, frame_len, SPEECH_TX_NS2FLOAT_CORE, &speech_cfg->tx_ns2float); +#if defined(SPEECH_TX_AEC) + speech_ns2float_set_echo_state(speech_tx_ns2float_st, speech_tx_aec_lib_st); + speech_ns2float_set_echo_suppress(speech_tx_ns2float_st, -40); +#endif +#endif + +#if defined(SPEECH_TX_NS3) + speech_tx_ns3_st = ns3_create(sample_rate, frame_len, &speech_cfg->tx_ns3); +#endif + +#if defined(SPEECH_TX_WNR) + speech_tx_wnr_st = wnr_create(sample_rate, frame_len, &speech_cfg->tx_wnr); +#endif + +#if defined(SPEECH_TX_NOISE_GATE) + speech_tx_noise_gate_st = speech_noise_gate_create(sample_rate, frame_len, &speech_cfg->tx_noise_gate); +#endif + +#if defined(SPEECH_TX_COMPEXP) + speech_tx_compexp_st = compexp_create(sample_rate, frame_len, &speech_cfg->tx_compexp); +#endif + +#if defined(SPEECH_TX_AGC) + speech_tx_agc_st = agc_state_create(sample_rate, frame_len, &speech_cfg->tx_agc); +#endif + +#if defined(SPEECH_TX_EQ) + speech_tx_eq_st = eq_init(sample_rate, frame_len, &speech_cfg->tx_eq); +#endif + +#if defined(SPEECH_TX_POST_GAIN) + speech_tx_post_gain_st = speech_gain_create(sample_rate, frame_len, &speech_cfg->tx_post_gain); +#endif + + TRACE(1,"[%s] End", __func__); + + return 0; +} + +int speech_rx_init(int sample_rate, int frame_len) +{ + TRACE(3,"[%s] Start, sample_rate: %d, frame_len: %d", __func__, sample_rate, frame_len); + +#if defined (SPEECH_RX_NS) + speech_rx_ns_st = speech_ns_create(sample_rate, frame_len, &speech_cfg->rx_ns); +#endif + +#if defined(SPEECH_RX_NS2) + speech_rx_ns2_st = speech_ns2_create(sample_rate, frame_len, &speech_cfg->rx_ns2); +#endif + +#if defined(SPEECH_RX_NS2FLOAT) + speech_rx_ns2float_st = speech_ns2float_create(sample_rate, frame_len, SPEECH_RX_NS2FLOAT_CORE, &speech_cfg->rx_ns2float); +#endif + +#if defined(SPEECH_RX_NS3) + speech_rx_ns3_st = ns3_create(sample_rate, frame_len, &speech_cfg->rx_ns3); +#endif + +#if defined(SPEECH_RX_AGC) + speech_rx_agc_st = agc_state_create(sample_rate, frame_len, &speech_cfg->rx_agc); +#endif + +#if defined(SPEECH_RX_EQ) + speech_rx_eq_st = eq_init(sample_rate, frame_len, &speech_cfg->rx_eq); +#endif + +#if defined(SPEECH_RX_POST_GAIN) + speech_rx_post_gain_st = speech_gain_create(sample_rate, frame_len, &speech_cfg->rx_post_gain); +#endif + + TRACE(1,"[%s] End", __func__); + + return 0; +} + +int speech_init(int tx_sample_rate, int rx_sample_rate, + int tx_frame_ms, int rx_frame_ms, + int sco_frame_ms, + uint8_t *buf, int len) +{ + TRACE(1,"[%s] Start...", __func__); + + //ASSERT(frame_ms == SPEECH_PROCESS_FRAME_MS, "[%s] frame_ms(%d) != SPEECH_PROCESS_FRAME_MS(%d)", __func__, + // frame_ms, + // SPEECH_PROCESS_FRAME_MS); + + speech_tx_sample_rate = tx_sample_rate; + speech_rx_sample_rate = rx_sample_rate; + speech_tx_frame_len = SPEECH_FRAME_MS_TO_LEN(tx_sample_rate, tx_frame_ms); + speech_rx_frame_len = SPEECH_FRAME_MS_TO_LEN(rx_sample_rate, rx_frame_ms); + + speech_heap_init(buf, len); + +#if defined(SCO_OPTIMIZE_FOR_RAM) + TRACE(2,"[%s] sco_overlay_ram_buf_len = %d", __func__, sco_overlay_ram_buf_len); + if (sco_overlay_ram_buf_len >= 1024) + { + speech_heap_add_block(sco_overlay_ram_buf, sco_overlay_ram_buf_len); + } +#endif + + // When phone call again, speech cfg will be default. + // If do not want to reset speech cfg, need define bt_sco_chain_init() + // and call in apps.cpp: app_init() + speech_cfg = (SpeechConfig *)speech_calloc(1, sizeof(SpeechConfig)); + speech_store_config(&speech_cfg_default); + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + audio_dump_init(speech_tx_frame_len, sizeof(short), 2); +#endif + +#ifdef AUDIO_DEBUG_V0_1_0 + speech_tuning_open(); +#endif + + int aec_enable = 0; +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) + aec_enable = 1; +#endif + + int capture_sample_size = sizeof(int16_t), playback_sample_size = sizeof(int16_t); +#if defined(SPEECH_TX_24BIT) + capture_sample_size = sizeof(int32_t); +#endif +#if defined(SPEECH_RX_24BIT) + playback_sample_size = sizeof(int32_t); +#endif + + CAPTURE_HANDLER_T tx_handler = (tx_frame_ms == sco_frame_ms) ? NULL : _speech_tx_process_; + PLAYBACK_HANDLER_T rx_handler = (rx_frame_ms == sco_frame_ms) ? NULL : _speech_rx_process_; + + speech_tx_frame_resizer_enable = (tx_handler != NULL); + speech_rx_frame_resizer_enable = (rx_handler != NULL); + + if (speech_tx_frame_resizer_enable || speech_rx_frame_resizer_enable) { + speech_frame_resize_st = frame_resize_create(SPEECH_FRAME_MS_TO_LEN(tx_sample_rate, sco_frame_ms), + SPEECH_TX_CHANNEL_NUM, + speech_tx_frame_len, + capture_sample_size, + playback_sample_size, + aec_enable, + tx_handler, + rx_handler + ); + } + +#if defined(SCO_CP_ACCEL) + // NOTE: change channel number for different case. + sco_cp_init(speech_tx_frame_len, 1); +#endif + + speech_tx_init(speech_tx_sample_rate, speech_tx_frame_len); + speech_rx_init(speech_rx_sample_rate, speech_rx_frame_len); + +#if !defined(SCO_CP_ACCEL) + int needed_freq = 0; + enum APP_SYSFREQ_FREQ_T min_system_freq = speech_get_proper_sysfreq(&needed_freq); + enum APP_SYSFREQ_FREQ_T freq = hal_sysfreq_get(); + + if (freq < min_system_freq) { + freq = min_system_freq; + + app_sysfreq_req(APP_SYSFREQ_USER_BT_SCO, freq); + + int system_freq = hal_sys_timer_calc_cpu_freq(5, 0); + TRACE(2,"[%s]: app_sysfreq_req %d", __FUNCTION__, freq); + TRACE(2,"[%s]: sys freq calc : %d\n", __FUNCTION__, system_freq); + + if (system_freq <= needed_freq * 1000 * 1000) { + TRACE(3,"[%s] WARNING: system freq(%d) seems to be lower than needed(%d).", __FUNCTION__, system_freq/1000000, needed_freq); + } + } +#endif + + TRACE(1,"[%s] End", __func__); + + return 0; +} + +int speech_tx_deinit(void) +{ + TRACE(1,"[%s] Start...", __func__); + +#if defined(SPEECH_TX_POST_GAIN) + speech_gain_destroy(speech_tx_post_gain_st); +#endif + +#if defined(SPEECH_TX_EQ) + eq_destroy(speech_tx_eq_st); +#endif + +#if defined(SPEECH_TX_AGC) + agc_state_destroy(speech_tx_agc_st); +#endif + +#if defined(SPEECH_TX_3MIC_NS) + speech_3mic_ns_destroy(speech_tx_3mic_ns_st); +#endif + +#if defined(SPEECH_TX_3MIC_NS3) + triple_mic_denoise3_destroy(speech_tx_3mic_ns3_st); +#endif + +#if defined(SPEECH_TX_2MIC_NS) + dual_mic_denoise_deinit(); +#endif + +#if defined(SPEECH_TX_2MIC_NS2) + speech_2mic_ns2_destroy(speech_tx_2mic_ns2_st); +#endif + +// #if defined(SPEECH_CS_VAD) +// VAD_destroy(speech_cs_vad_st); +// #endif + +#if defined(SPEECH_TX_2MIC_NS3) + far_field_speech_enhancement_deinit(); +#endif + +#if defined(SPEECH_TX_2MIC_NS4) + sensormic_denoise_destroy(speech_tx_2mic_ns4_st); +#endif + +#if defined(SPEECH_TX_2MIC_NS5) + leftright_denoise_destroy(speech_tx_2mic_ns5_st); +#endif + +#if defined(SPEECH_TX_2MIC_NS6) + speech_ff_2mic_ns2_destroy(speech_tx_2mic_ns6_st); +#endif + +#if defined(SPEECH_TX_NS) + speech_ns_destroy(speech_tx_ns_st); +#endif + +#if defined(SPEECH_TX_NS2) + speech_ns2_destroy(speech_tx_ns2_st); +#endif + +#if defined(SPEECH_TX_NS2FLOAT) + speech_ns2float_destroy(speech_tx_ns2float_st); +#endif + +#ifdef SPEECH_TX_NS3 + ns3_destroy(speech_tx_ns3_st); +#endif + +#ifdef SPEECH_TX_WNR + wnr_destroy(speech_tx_wnr_st); +#endif + +#ifdef SPEECH_TX_NOISE_GATE + speech_noise_gate_destroy(speech_tx_noise_gate_st); +#endif + +#ifdef SPEECH_TX_COMPEXP + compexp_destroy(speech_tx_compexp_st); +#endif + +#if defined(SPEECH_TX_AEC) + speech_aec_destroy(speech_tx_aec_st); +#endif + +#if defined(SPEECH_TX_AEC2) + speech_aec2_destroy(speech_tx_aec2_st); +#endif + +#if defined(SPEECH_TX_AEC3) + SubBandAec_destroy(speech_tx_aec3_st); +#endif + +#if defined(SPEECH_TX_AEC2FLOAT) + ec2float_destroy(speech_tx_aec2float_st); +#endif + +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) + speech_free(aec_echo_buf_ptr); + speech_free(aec_out_buf); +#endif + +#if defined(SPEECH_TX_MIC_CALIBRATION) + speech_iir_calib_destroy(speech_tx_mic_calib_st); +#endif + +#if defined(SPEECH_TX_MIC_FIR_CALIBRATION) + speech_fir_calib_destroy(speech_tx_mic_fir_calib_st); +#endif + +#if defined(SPEECH_TX_DC_FILTER) + speech_dc_filter_destroy(speech_tx_dc_filter_st); +#endif + + TRACE(1,"[%s] End", __func__); + + return 0; +} + +int speech_rx_deinit(void) +{ + TRACE(1,"[%s] Start...", __func__); + +#if defined(SPEECH_RX_POST_GAIN) + speech_gain_destroy(speech_rx_post_gain_st); +#endif + +#if defined(SPEECH_RX_EQ) + eq_destroy(speech_rx_eq_st); +#endif + +#if defined(SPEECH_RX_AGC) + agc_state_destroy(speech_rx_agc_st); +#endif + +#if defined(SPEECH_RX_NS) + speech_ns_destroy(speech_rx_ns_st); +#endif + +#if defined(SPEECH_RX_NS2) + speech_ns2_destroy(speech_rx_ns2_st); +#endif + +#if defined(SPEECH_RX_NS2FLOAT) + speech_ns2float_destroy(speech_rx_ns2float_st); +#endif + +#ifdef SPEECH_RX_NS3 + ns3_destroy(speech_rx_ns3_st); +#endif + + TRACE(1,"[%s] End", __func__); + + return 0; +} + +int speech_deinit(void) +{ + TRACE(1,"[%s] Start...", __func__); + + speech_rx_deinit(); + speech_tx_deinit(); + +#if defined(SCO_CP_ACCEL) + sco_cp_deinit(); +#endif + + if (speech_frame_resize_st != NULL) { + frame_resize_destroy(speech_frame_resize_st); + speech_tx_frame_resizer_enable = false; + speech_rx_frame_resizer_enable = false; + } + +#ifdef AUDIO_DEBUG_V0_1_0 + speech_tuning_close(); +#endif + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + audio_dump_deinit(); +#endif + + speech_free(speech_cfg); + speech_cfg = NULL; + + size_t total = 0, used = 0, max_used = 0; + speech_memory_info(&total, &used, &max_used); + TRACE(3,"SPEECH MALLOC MEM: total - %d, used - %d, max_used - %d.", total, used, max_used); + ASSERT(used == 0, "[%s] used != 0", __func__); + + TRACE(1,"[%s] End", __func__); + + return 0; +} + +float speech_tx_get_required_mips(void) +{ + float mips = 0; + +#if defined(SPEECH_TX_DC_FILTER) + mips += speech_dc_filter_get_required_mips(speech_tx_dc_filter_st); +#endif + +#if defined(SPEECH_TX_MIC_CALIBRATION) + mips += speech_iir_calib_get_required_mips(speech_tx_mic_calib_st); +#endif + +#if defined(SPEECH_TX_MIC_FIR_CALIBRATION) + mips += speech_fir_calib_get_required_mips(speech_tx_mic_fir_calib_st); +#endif + +#if defined(SPEECH_TX_AEC) + mips += speech_aec_get_required_mips(speech_tx_aec_st); +#endif + +#if defined(SPEECH_TX_AEC2) + mips += speech_aec2_get_required_mips(speech_tx_aec2_st); +#endif + +#if defined(SPEECH_TX_AEC3) + mips += SubBandAec_get_required_mips(speech_tx_aec3_st); +#endif + +#if defined(SPEECH_TX_AEC2FLOAT) + mips += ec2float_get_required_mips(speech_tx_aec2float_st); +#endif + +#if defined(SPEECH_TX_2MIC_NS) + mips += dual_mic_denoise_get_required_mips(); +#endif + +#if defined(SPEECH_TX_2MIC_NS2) + mips += speech_2mic_ns2_get_required_mips(speech_tx_2mic_ns2_st); +#endif + +// #if defined(SPEECH_CS_VAD) +// mips += VAD_process_get_required_mips(speech_cs_vad_st); +// #endif + +#if defined(SPEECH_TX_2MIC_NS3) + mips += far_field_speech_enhancement_get_required_mips(); +#endif + +#if defined(SPEECH_TX_2MIC_NS5) + mips += leftright_denoise_get_required_mips(speech_tx_2mic_ns5_st); +#endif + +#if defined(SPEECH_TX_2MIC_NS6) + mips += speech_ff_2mic_ns2_get_required_mips(speech_tx_2mic_ns6_st); +#endif + +#if defined(SPEECH_TX_2MIC_NS4) + mips += sensormic_denoise_get_required_mips(speech_tx_2mic_ns4_st); +#endif + +#if defined(SPEECH_TX_3MIC_NS) + mips += speech_3mic_get_required_mips(speech_tx_3mic_ns_st); +#endif + +#if defined(SPEECH_TX_3MIC_NS3) + mips += triple_mic_denoise3_get_required_mips(speech_tx_3mic_ns3_st); +#endif + +#if defined(SPEECH_TX_NS) + mips += speech_ns_get_required_mips(speech_tx_ns_st); +#endif + +#if defined(SPEECH_TX_NS2) + mips += speech_ns2_get_required_mips(speech_tx_ns2_st); +#endif + +#if defined(SPEECH_TX_NS2FLOAT) + mips += speech_ns2float_get_required_mips(speech_tx_ns2float_st); +#endif + +#if defined(SPEECH_TX_NS3) + mips += ns3_get_required_mips(speech_tx_ns3_st); +#endif + +#if defined(SPEECH_TX_WNR) + mips += wnr_get_required_mips(speech_tx_wnr_st); +#endif + +#if defined(SPEECH_TX_NOISE_GATE) + mips += speech_noise_gate_get_required_mips(speech_tx_noise_gate_st); +#endif + +#if defined(SPEECH_TX_COMPEXP) + mips += compexp_get_required_mips(speech_tx_compexp_st); +#endif + +#if defined(SPEECH_TX_AGC) + mips += agc_get_required_mips(speech_tx_agc_st); +#endif + +#if defined(SPEECH_TX_EQ) + mips += eq_get_required_mips(speech_tx_eq_st); +#endif + +#if defined(SPEECH_TX_POST_GAIN) + mips += speech_gain_get_required_mips(speech_tx_post_gain_st); +#endif + + return mips; +} + +float speech_rx_get_required_mips(void) +{ + float mips = 0; + +#if defined (SPEECH_RX_NS) + mips += speech_ns_get_required_mips(speech_rx_ns_st); +#endif + +#if defined(SPEECH_RX_NS2) + mips += speech_ns2_get_required_mips(speech_rx_ns2_st); +#endif + +#if defined(SPEECH_RX_NS2FLOAT) + mips += speech_ns2float_get_required_mips(speech_rx_ns2float_st); +#endif + +#if defined(SPEECH_RX_NS3) + mips += ns3_get_required_mips(speech_rx_ns3_st); +#endif + +#if defined(SPEECH_RX_AGC) + mips += agc_get_required_mips(speech_rx_agc_st); +#endif + +#if defined(SPEECH_RX_EQ) + mips += eq_get_required_mips(speech_rx_eq_st); +#endif + +#if defined(SPEECH_RX_POST_GAIN) + mips += speech_gain_get_required_mips(speech_rx_post_gain_st); +#endif + + return mips; +} + +float speech_get_required_mips(void) +{ + return speech_tx_get_required_mips() + speech_rx_get_required_mips(); +} + +#define SYSTEM_BASE_MIPS (18) + +enum APP_SYSFREQ_FREQ_T speech_get_proper_sysfreq(int *needed_mips) +{ + enum APP_SYSFREQ_FREQ_T freq = APP_SYSFREQ_32K; + int required_mips = (int)ceilf(speech_get_required_mips() + SYSTEM_BASE_MIPS); + + if (required_mips >= 104) + freq = APP_SYSFREQ_208M; + else if (required_mips >= 78) + freq = APP_SYSFREQ_104M; + else if (required_mips >= 52) + freq = APP_SYSFREQ_78M; + else if (required_mips >= 26) + freq = APP_SYSFREQ_52M; + else + freq = APP_SYSFREQ_26M; + + *needed_mips = required_mips; + + return freq; +} + +int speech_set_config(const SpeechConfig *cfg) +{ +#if defined(SPEECH_TX_DC_FILTER) + speech_dc_filter_set_config(speech_tx_dc_filter_st, &cfg->tx_dc_filter); +#endif +#if defined(SPEECH_TX_AEC) + speech_aec_set_config(speech_tx_aec_st, &cfg->tx_aec); +#endif +#if defined(SPEECH_TX_AEC2) + speech_aec2_set_config(speech_tx_aec2_st, &cfg->tx_aec2); +#endif +#if defined(SPEECH_TX_AEC2FLOAT) + ec2float_set_config(speech_tx_aec2float_st, &cfg->tx_aec2float, SPEECH_TX_AEC2FLOAT_CORE); +#endif +#if defined(SPEECH_TX_2MIC_NS) + TRACE(1,"[%s] WARNING: Can not support tuning SPEECH_TX_2MIC_NS", __func__); +#endif +#if defined(SPEECH_TX_2MIC_NS2) + speech_2mic_ns2_set_config(speech_tx_2mic_ns2_st, &cfg->tx_2mic_ns2); +#endif +#if defined(SPEECH_TX_2MIC_NS4) + sensormic_denoise_set_config(speech_tx_2mic_ns4_st, &cfg->tx_2mic_ns4); +#endif +#if defined(SPEECH_TX_2MIC_NS5) + leftright_denoise_set_config(speech_tx_2mic_ns5_st, &cfg->tx_2mic_ns5); +#endif +#if defined(SPEECH_TX_3MIC_NS) + speech_3mic_ns_set_config(speech_tx_3mic_ns_st, &cfg->tx_3mic_ns); +#endif +#if defined(SPEECH_TX_NS) + speech_ns_set_config(speech_tx_ns_st, &cfg->tx_ns); +#endif +#if defined(SPEECH_TX_NS2) + speech_ns2_set_config(speech_tx_ns2_st, &cfg->tx_ns2); +#endif +#if defined(SPEECH_TX_NS2FLOAT) + speech_ns2float_set_config(speech_tx_ns2float_st, &cfg->tx_ns2float); +#endif +#if defined(SPEECH_TX_NS3) + ns3_set_config(speech_tx_ns3_st, &cfg->tx_ns3); +#endif +#if defined(SPEECH_TX_NOISE_GATE) + speech_noise_gate_set_config(speech_tx_noise_gate_st, &cfg->tx_noise_gate); +#endif +#if defined(SPEECH_TX_COMPEXP) + compexp_set_config(speech_tx_compexp_st, &cfg->tx_compexp); +#endif +#if defined(SPEECH_TX_AGC) + agc_set_config(speech_tx_agc_st, &cfg->tx_agc); +#endif +#if defined(SPEECH_TX_EQ) + eq_set_config(speech_tx_eq_st, &cfg->tx_eq); +#endif +#if defined(SPEECH_TX_POST_GAIN) + speech_gain_set_config(speech_tx_post_gain_st, &cfg->tx_post_gain); +#endif +// #if defined(SPEECH_CS_VAD) +// VAD_set_config(speech_cs_vad_st, &cfg->cs_vad); +// #endif +#if defined(SPEECH_RX_NS) + speech_ns_set_config(speech_rx_ns_st, &cfg->rx_ns); +#endif +#if defined(SPEECH_RX_NS2) + speech_ns2_set_config(speech_rx_ns2_st, &cfg->rx_ns2); +#endif +#if defined(SPEECH_RX_NS2FLOAT) + speech_ns2float_set_config(speech_rx_ns2float_st, &cfg->rx_ns2float, SPEECH_RX_NS2FLOAT_CORE); +#endif +#if defined(SPEECH_RX_NS3) + ns3_set_config(speech_rx_ns3_st, &cfg->rx_ns3); +#endif +#if defined(SPEECH_RX_NOISE_GATE) + speech_noise_gate_set_config(speech_rx_noise_gate_st, &cfg->rx_noise_gate); +#endif +#if defined(SPEECH_RX_COMPEXP) + compexp_set_config(speech_rx_compexp_st, &cfg->rx_compexp); +#endif +#if defined(SPEECH_RX_AGC) + agc_set_config(speech_rx_agc_st, &cfg->rx_agc); +#endif +#if defined(SPEECH_RX_EQ) + eq_set_config(speech_rx_eq_st, &cfg->rx_eq); +#endif +#if defined(SPEECH_RX_POST_GAIN) + speech_gain_set_config(speech_rx_post_gain_st, &cfg->rx_post_gain); +#endif + // Add more process + + return 0; +} + +void _speech_tx_process_pre(short *pcm_buf, short *ref_buf, int *_pcm_len) +{ + int pcm_len = *_pcm_len; + +#if defined(BT_SCO_CHAIN_PROFILE) + tx_start_ticks = hal_fast_sys_timer_get(); +#endif + + // TRACE(2,"[%s] pcm_len = %d", __func__, pcm_len); + +#ifdef AUDIO_DEBUG_V0_1_0 + if (speech_tuning_get_status()) + { + speech_set_config(speech_cfg); + + speech_tuning_set_status(false); + + // If has MIPS problem, can move this block code into speech_rx_process or return directly + // return 0 + } +#endif + +#if defined(SPEECH_TX_24BIT) +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) + tx_refbuf16 = (int16_t *)ref_buf; + tx_refbuf32 = (int32_t *)ref_buf; + for (int i = 0; i < pcm_len / SPEECH_CODEC_CAPTURE_CHANNEL_NUM; i++) { + tx_refbuf16[i] = (tx_refbuf32[i] >> 8); + } +#endif + + tx_pcmbuf16 = (int16_t *)pcm_buf; + tx_pcmbuf32 = (int32_t *)pcm_buf; + for (int i = 0; i < pcm_len; i++) { + tx_pcmbuf16[i] = (tx_pcmbuf32[i] >> 8); + } +#endif + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + audio_dump_clear_up(); +#endif + +#if 0 + // Test MIC: Get one channel data + // Enable this, should bypass SPEECH_TX_2MIC_NS and SPEECH_TX_2MIC_NS2 + for(uint32_t i=0; i>= 1; +#endif + +#if defined(SPEECH_TX_DC_FILTER) + speech_dc_filter_process(speech_tx_dc_filter_st, pcm_buf, pcm_len); +#endif + +#if (SPEECH_CODEC_CAPTURE_CHANNEL_NUM == 2) && defined(AUDIO_DUMP) && defined(BT_SCO_CHAIN_AUDIO_DUMP) + audio_dump_add_channel_data_from_multi_channels(0, pcm_buf, pcm_len / 2, 2, 0); + audio_dump_add_channel_data_from_multi_channels(1, pcm_buf, pcm_len / 2, 2, 1); +#endif + +#if defined(SPEECH_TX_MIC_CALIBRATION) + speech_iir_calib_process(speech_tx_mic_calib_st, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_MIC_FIR_CALIBRATION) + speech_fir_calib_process(speech_tx_mic_fir_calib_st, pcm_buf, pcm_len); +#endif + +#if (SPEECH_CODEC_CAPTURE_CHANNEL_NUM == 2) && defined(AUDIO_DUMP) && defined(BT_SCO_CHAIN_AUDIO_DUMP) + audio_dump_add_channel_data_from_multi_channels(2, pcm_buf, pcm_len / 2, 2, 0); + audio_dump_add_channel_data_from_multi_channels(3, pcm_buf, pcm_len / 2, 2, 1); +#endif + +#if defined(SPEECH_TX_2MIC_NS) + dual_mic_denoise_run(pcm_buf, pcm_len, pcm_buf); + // Channel num: two-->one + pcm_len >>= 1; +#endif + +#if defined(SPEECH_TX_2MIC_NS2) + speech_2mic_ns2_process(speech_tx_2mic_ns2_st, pcm_buf, pcm_len, pcm_buf); + // Channel num: two-->one + pcm_len >>= 1; +#endif + +#if defined(SPEECH_TX_2MIC_NS4) + if (dualmic_enable == true) { +#if defined(ANC_APP) + sensormic_denoise_set_anc_status(speech_tx_2mic_ns4_st, app_anc_work_status()); +#endif + sensormic_denoise_process(speech_tx_2mic_ns4_st, pcm_buf, pcm_len, pcm_buf); + } else { + int16_t *pcm16 = (int16_t *)pcm_buf; + for (int i = 0, j = 0; i < pcm_len / 2; i++, j += 2) + pcm16[i] = pcm16[j]; + } + // Channel num: two-->one + pcm_len >>= 1; +#endif + +#if defined(SPEECH_TX_2MIC_NS5) + leftright_denoise_process(speech_tx_2mic_ns5_st, pcm_buf, pcm_len, pcm_buf); + // Channel num: two-->one + pcm_len >>= 1; +#endif + +#if defined(SPEECH_TX_2MIC_NS6) + //TRACE(0,"NS6"); + speech_2mic_ns6_process(speech_tx_2mic_ns6_st, pcm_buf, pcm_len, pcm_buf); + // Channel num: two-->one + pcm_len >>= 1; +#endif + +#if defined(SPEECH_TX_3MIC_NS) + speech_3mic_ns_process(speech_tx_3mic_ns_st, pcm_buf, pcm_len, pcm_buf); + // Channel num: three-->one + pcm_len = pcm_len / 3; +#endif + +#if defined(SPEECH_TX_3MIC_NS3) + triple_mic_denoise3_process(speech_tx_3mic_ns3_st, pcm_buf, pcm_len, pcm_buf); + // Channel num: three-->one + pcm_len = pcm_len / 3; +#endif + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + audio_dump_add_channel_data(0, pcm_buf, pcm_len); +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) + audio_dump_add_channel_data(1, ref_buf, pcm_len); +#else + audio_dump_add_channel_data(1, pcm_buf, pcm_len); +#endif +#endif + +#if defined(SPEECH_TX_AEC) + speech_aec_process(speech_tx_aec_st, pcm_buf, ref_buf, pcm_len, aec_out_buf); + speech_copy_int16(pcm_buf, aec_out_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_AEC2) + speech_aec2_process(speech_tx_aec2_st, pcm_buf, ref_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_AEC3) + CODEC_OpVecCpy(bufferstate + delay, ref_buf, pcm_len); + CODEC_OpVecCpy(buf_out, bufferstate, pcm_len); + CODEC_OpVecCpy(bufferstate, bufferstate + pcm_len, delay); + SubBandAec_process(speech_tx_aec3_st, pcm_buf, buf_out, pcm_buf, pcm_len); + //audio_dump_add_channel_data(1, pcm_buf, pcm_len); +#endif + + SCO_CP_ACCEL_ALGO_START(); + +#if defined(SPEECH_TX_AEC2FLOAT) +#if defined(SPEECH_TX_2MIC_NS4) + if (dualmic_enable == true) + TRACE(2,"[%s] vad: %d", __FUNCTION__, sensormic_denoise_get_vad(speech_tx_2mic_ns4_st)); + ec2float_set_external_vad(speech_tx_aec2float_st, sensormic_denoise_get_vad(speech_tx_2mic_ns4_st)); +#endif + ec2float_process(speech_tx_aec2float_st, pcm_buf, ref_buf, pcm_len, aec_out_buf); + speech_copy_int16(pcm_buf, aec_out_buf, pcm_len); +#endif + + SCO_CP_ACCEL_ALGO_END(); + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + audio_dump_add_channel_data(2, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_NS) + speech_ns_process(speech_tx_ns_st, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_NS2) + speech_ns2_process(speech_tx_ns2_st, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_NS2FLOAT) +#if defined(SPEECH_TX_2MIC_NS4) + if (dualmic_enable == true) + speech_ns2float_set_external_vad(speech_tx_ns2float_st, sensormic_denoise_get_vad(speech_tx_2mic_ns4_st)); +#endif + speech_ns2float_process(speech_tx_ns2float_st, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_NS3) + ns3_process(speech_tx_ns3_st, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_WNR) + wnr_process(speech_tx_wnr_st, pcm_buf, pcm_len); +#endif + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + audio_dump_add_channel_data(3, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_NOISE_GATE) + speech_noise_gate_process(speech_tx_noise_gate_st, pcm_buf, pcm_len); +#endif + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + audio_dump_add_channel_data(4, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_COMPEXP) + compexp_process(speech_tx_compexp_st, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_AGC) + agc_process(speech_tx_agc_st, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_EQ) + eq_process(speech_tx_eq_st, pcm_buf, pcm_len); +#endif + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + // audio_dump_add_channel_data(0, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_TX_POST_GAIN) + speech_gain_process(speech_tx_post_gain_st, pcm_buf, pcm_len); +#endif + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + // audio_dump_add_channel_data(1, pcm_buf, pcm_len); + + audio_dump_add_channel_data(5, pcm_buf, pcm_len); + audio_dump_run(); +#endif + +#if defined(SPEECH_TX_24BIT) + tx_pcmbuf16 = (int16_t *)pcm_buf; + tx_pcmbuf32 = (int32_t *)pcm_buf; + for (int i = pcm_len - 1; i >= 0; i--) { + tx_pcmbuf32[i] = ((int32_t)tx_pcmbuf16[i] << 8); + } +#endif + + *_pcm_len = pcm_len; + +#if defined(BT_SCO_CHAIN_PROFILE) + tx_end_ticks = hal_fast_sys_timer_get(); + TRACE(2,"[%s] takes %d us", __FUNCTION__, + FAST_TICKS_TO_US(tx_end_ticks - tx_start_ticks)); +#endif +} + +#if defined(SCO_CP_ACCEL) +CP_TEXT_SRAM_LOC +int sco_cp_algo(short *pcm_buf, short *ref_buf, int *_pcm_len) +{ +#if defined(SCO_TRACE_CP_ACCEL) + TRACE(1,"[%s] ...", __func__); +#endif + + _speech_tx_process_mid(pcm_buf, ref_buf, _pcm_len); + + return 0; +} +#endif + +int32_t _speech_tx_process_(void *pcm_buf, void *ref_buf, int32_t *_pcm_len) +{ + _speech_tx_process_pre(pcm_buf, ref_buf, (int *)_pcm_len); +#if defined(SCO_CP_ACCEL) + sco_cp_process(pcm_buf, ref_buf, (int *)_pcm_len); + _speech_tx_process_post(pcm_buf, ref_buf, (int *)_pcm_len); +#endif + + return 0; +} + +int32_t _speech_rx_process_(void *pcm_buf, int32_t *_pcm_len) +{ + int32_t pcm_len = *_pcm_len; + +#if defined(BT_SCO_CHAIN_PROFILE) + uint32_t start_ticks = hal_fast_sys_timer_get(); +#endif + +#if defined(SPEECH_RX_24BIT) + int32_t *buf32 = (int32_t *)pcm_buf; + int16_t *buf16 = (int16_t *)pcm_buf; + for (int i = 0; i < pcm_len; i++) { + buf16[i] = (int16_t)(buf32[i] >> 8); + } +#endif + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + // audio_dump_add_channel_data(0, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_RX_NS) + speech_ns_process(speech_rx_ns_st, pcm_buf, pcm_len); +#endif + +#if defined(SPEECH_RX_NS2) + // fix 0dB signal + int16_t *pcm_buf16 = (int16_t *)pcm_buf; + for(int i=0; i= 0; i--) { + buf32[i] = ((int32_t)buf16[i] << 8); + } +#endif + +#if defined(SPEECH_RX_EQ) +#if defined(SPEECH_RX_24BIT) + eq_process_int24(speech_rx_eq_st, pcm_buf, pcm_len); +#else + eq_process(speech_rx_eq_st, pcm_buf, pcm_len); +#endif +#endif + +#if defined(SPEECH_RX_POST_GAIN) + speech_gain_process(speech_rx_post_gain_st, pcm_buf, pcm_len); +#endif + +#if defined(BT_SCO_CHAIN_AUDIO_DUMP) + // audio_dump_add_channel_data(1, pcm_buf, pcm_len); + // audio_dump_run(); +#endif + + *_pcm_len = pcm_len; + +#if defined(BT_SCO_CHAIN_PROFILE) + uint32_t end_ticks = hal_fast_sys_timer_get(); + TRACE(2,"[%s] takes %d us", __FUNCTION__, + FAST_TICKS_TO_US(end_ticks - start_ticks)); +#endif + + return 0; +} + +int speech_tx_process(void *pcm_buf, void *ref_buf, int *pcm_len) +{ + if (speech_tx_frame_resizer_enable == false) { + _speech_tx_process_(pcm_buf, ref_buf, (int32_t *)pcm_len); + } else { + // MUST use (int32_t *)?????? + frame_resize_process_capture(speech_frame_resize_st, pcm_buf, ref_buf, (int32_t *)pcm_len); + } + + return 0; +} + +int speech_rx_process(void *pcm_buf, int *pcm_len) +{ + if (speech_rx_frame_resizer_enable == false) { + _speech_rx_process_(pcm_buf, (int32_t *)pcm_len); + } else { + frame_resize_process_playback(speech_frame_resize_st, pcm_buf, (int32_t *)pcm_len); + } + + return 0; +} diff --git a/apps/audioplayers/bt_sco_chain.h b/apps/audioplayers/bt_sco_chain.h new file mode 100644 index 0000000..a678788 --- /dev/null +++ b/apps/audioplayers/bt_sco_chain.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BT_SCO_CHAIN_H__ +#define __BT_SCO_CHAIN_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Init speech algorithm, init all related states and memory + * Input: + * tx_sample_rate: capture sample rate + * rx_sample_rate: playback sample rate + * tx_frame_ms: capture frame size in ms + * rx_frame_ms: playback frame size in ms + * sco_frame_ms: sco frame size in ms(must be multiply of 7.5) + * buf: buffer to be used for algorithms + * len: buffer size + */ +int speech_init(int tx_sample_rate, int rx_sample_rate, + int tx_frame_ms, int rx_frame_ms, + int sco_frame_ms, + uint8_t *buf, int len); + +/* + * Deinit speech algorithm, free all related states and memory + */ +int speech_deinit(void); + +/* + * Uplink process + * Input: + * pcm_buf: captured buffer by microphone, multi-channel is interleaved. + * ref_buf: reference buffer for acoustic echo canceller. + * buffee sample num should be tx_sample_rate * tx_frame_ms + * pcm_len: capture buffer sample num, should be tx_sample_rate * sco_frame_ms * ch_num + * Output: + * pcm_buf: output buffer of speech algorithm, should be single channel + * pcm_len: output buffer sample num, should be tx_sample_rate * sco_frame_ms + */ +int speech_tx_process(void *pcm_buf, void *ref_buf, int *pcm_len); + +/* + * Downlink process + * Input: + * pcm_buf: input buffer to be processed + * pcm_len: input buffer sample num, should be rx_sample_rate * sco_frame_ms + * Output: + * pcm_buf: output buffer + * pcm_len: output buffer sample num, should be rx_sample_rate * sco_frame_ms + */ +int speech_rx_process(void *pcm_buf, int *pcm_len); + +void *speech_get_ext_buff(int size); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/apps/audioplayers/bt_sco_chain_cfg.h b/apps/audioplayers/bt_sco_chain_cfg.h new file mode 100644 index 0000000..7e5f951 --- /dev/null +++ b/apps/audioplayers/bt_sco_chain_cfg.h @@ -0,0 +1,146 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BT_SCO_CHAIN_CFG_H__ +#define __BT_SCO_CHAIN_CFG_H__ + +#include "speech_cfg.h" + +typedef struct { +#if defined(SPEECH_TX_DC_FILTER) + SpeechDcFilterConfig tx_dc_filter; +#endif +#if defined(SPEECH_TX_AEC) + SpeechAecConfig tx_aec; +#endif +#if defined(SPEECH_TX_AEC2) + SpeechAec2Config tx_aec2; +#endif +#if defined(SPEECH_TX_AEC2FLOAT) + Ec2FloatConfig tx_aec2float; +#endif +#if defined(SPEECH_TX_AEC3) + SubBandAecConfig tx_aec3; +#endif +#if defined(SPEECH_TX_2MIC_NS) + DUAL_MIC_DENOISE_CFG_T tx_2mic_ns; +#endif +#if defined(SPEECH_TX_2MIC_NS2) + Speech2MicNs2Config tx_2mic_ns2; +#endif +#if defined(SPEECH_TX_2MIC_NS4) + SensorMicDenoiseConfig tx_2mic_ns4; +#endif +#if defined(SPEECH_TX_2MIC_NS5) + LeftRightDenoiseConfig tx_2mic_ns5; +#endif +#if defined(SPEECH_TX_3MIC_NS) + Speech3MicNsConfig tx_3mic_ns; +#endif +#if defined(SPEECH_TX_3MIC_NS3) + TripleMicDenoise3Config tx_3mic_ns3; +#endif +#if defined(SPEECH_TX_NS) + SpeechNsConfig tx_ns; +#endif +#if defined(SPEECH_TX_NS2) + SpeechNs2Config tx_ns2; +#endif +#if defined(SPEECH_TX_NS2FLOAT) + SpeechNs2FloatConfig tx_ns2float; +#endif +#if defined(SPEECH_TX_NS3) + Ns3Config tx_ns3; +#endif +#if defined(SPEECH_TX_WNR) + WnrConfig tx_wnr; +#endif +#if defined(SPEECH_TX_NOISE_GATE) + NoisegateConfig tx_noise_gate; +#endif +#if defined(SPEECH_TX_COMPEXP) + CompexpConfig tx_compexp; +#endif +#if defined(SPEECH_TX_AGC) + AgcConfig tx_agc; +#endif +#if defined(SPEECH_TX_EQ) + EqConfig tx_eq; +#endif +#if defined(SPEECH_TX_POST_GAIN) + SpeechGainConfig tx_post_gain; +#endif +// #if defined(SPEECH_CS_VAD) +// VADConfig cs_vad; +// #endif +#if defined(SPEECH_RX_NS) + SpeechNsConfig rx_ns; +#endif +#if defined(SPEECH_RX_NS2) + SpeechNs2Config rx_ns2; +#endif +#if defined(SPEECH_RX_NS2FLOAT) + SpeechNs2FloatConfig rx_ns2float; +#endif +#if defined(SPEECH_RX_NS3) + Ns3Config rx_ns3; +#endif +#if defined(SPEECH_RX_NOISE_GATE) + NoisegateConfig rx_noise_gate; +#endif +#if defined(SPEECH_RX_COMPEXP) + CompexpConfig rx_compexp; +#endif +#if defined(SPEECH_RX_AGC) + AgcConfig rx_agc; +#endif +#if defined(SPEECH_RX_EQ) + EqConfig rx_eq; +#endif +#if defined(SPEECH_RX_POST_GAIN) + SpeechGainConfig rx_post_gain; +#endif + // Add more process +} SpeechConfig; + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/audioplayers/bt_sco_chain_cfg_default.c b/apps/audioplayers/bt_sco_chain_cfg_default.c new file mode 100644 index 0000000..d01b833 --- /dev/null +++ b/apps/audioplayers/bt_sco_chain_cfg_default.c @@ -0,0 +1,796 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "bt_sco_chain_cfg.h" + +#if defined(SPEECH_TX_2MIC_NS4) +static float ff_fb_h[256] = {1.f, }; +#endif + +#if defined(SPEECH_TX_MIC_CALIBRATION) +/**************************************************************************************************** + * Describtion: + * Mic Calibration Equalizer, implementation with 2 order iir filters + * Parameters: + * bypass(0/1): bypass enable or disable. + * mic_num(1~4): the number of microphones. The filter num is (mic_num - 1) + * calib: {bypass, gain, num, {type, frequency, gain, q}}. Please refer to SPEECH_TX_EQ section + * in this file + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz, 0.5M/section; + * Note: + * None +****************************************************************************************************/ +const SpeechIirCalibConfig WEAK speech_tx_mic_calib_cfg = +{ + .bypass = 0, + .mic_num = 2, + .calib = { + { + .bypass = 0, + .gain = 0.f, + .num = 0, + .params = { + {IIR_BIQUARD_LOWSHELF, 150, -2.5, 0.707}, + } + }, + }, +}; +#endif + +#if defined(SPEECH_TX_MIC_FIR_CALIBRATION) +/**************************************************************************************************** + * Describtion: + * Mic Calibration Equalizer, implementation with fir filter + * Parameters: + * bypass(0/1): bypass enable or disable. + * mic_num(1~4): the number of microphones. The filter num is (mic_num - 1) + * calib: {filter, filter_length, nfft}. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz, 0.5M/section; + * Note: + * None +****************************************************************************************************/ +float mic2_ft_caliration[256] = {1.f, }; +const SpeechFirCalibConfig WEAK speech_tx_mic_fir_calib_cfg = +{ + .bypass = 0, + .mic_num = SPEECH_CODEC_CAPTURE_CHANNEL_NUM, + .delay = 0, + .calib = { + { + .filter = mic2_ft_caliration, + .filter_length = ARRAY_SIZE(mic2_ft_caliration), + }, + }, +}; +#endif + +const SpeechConfig WEAK speech_cfg_default = { + +#if defined(SPEECH_TX_DC_FILTER) + .tx_dc_filter = { + .bypass = 0, + .gain = 0, + }, +#endif + +#if defined(SPEECH_TX_AEC) +/**************************************************************************************************** + * Describtion: + * Acoustic Echo Cancellation + * Parameters: + * bypass(0/1): bypass enable or disable. + * delay(>0): delay samples from mic to speak, unit(sample). + * leak_estimate(0~32767): echo supression value. This is a fixed mode. It has relatively large + * echo supression and large damage to speech signal. + * leak_estimate_shift(0~8): echo supression value. if leak_estimate == 0, then leak_estimate_shift + * can take effect. This is a adaptive mode. It has relatively small echo supression and also + * small damage to speech signal. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz, 40M; + * Note: + * If possible, use SPEECH_TX_AEC2FLOAT +****************************************************************************************************/ + .tx_aec = { + .bypass = 0, + .delay = 60, + .leak_estimate = 16383, + .leak_estimate_shift = 4, + }, +#endif + +#if defined(SPEECH_TX_AEC2) +/**************************************************************************************************** + * Describtion: + * Acoustic Echo Cancellation + * Parameters: + * bypass(0/1): bypass enable or disable. + * . + * . + * . + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz, enNlpEnable = 1, 39M; + * Note: + * If possible, use SPEECH_TX_AEC2FLOAT +****************************************************************************************************/ + .tx_aec2 = { + .bypass = 0, + .enEAecEnable = 1, + .enHpfEnable = 1, + .enAfEnable = 0, + .enNsEnable = 0, + .enNlpEnable = 1, + .enCngEnable = 0, + .shwDelayLength = 0, + .shwNlpBandSortIdx = 0.75f, + .shwNlpBandSortIdxLow = 0.5f, + .shwNlpTargetSupp = 3.0f, + .shwNlpMinOvrd = 1.0f, + }, +#endif + +#if defined(SPEECH_TX_AEC2FLOAT) +/**************************************************************************************************** + * Describtion: + * Acoustic Echo Cancellation + * Parameters: + * bypass(0/1): bypass enable or disable. + * hpf_enabled(0/1): high pass filter enable or disable. Used to remove DC for Near and Ref signals. + * af_enabled(0/1): adaptive filter enable or disable. If the echo signal is very large, enable this + * nlp_enabled(0/1): non-linear process enable or disable. Enable this by default. + * ns_enabled(0/1): noise supression enable or disable. Enable this by default. + * cng_enabled(0/1): comfort noise generator enable or disable. + * blocks(1~8): the length of adaptive filter = blocks * frame length + * delay(>0): delay samples from mic to speak, unit(sample). + * min_ovrd(1~6): supression factor, min_ovrd becomes larger and echo suppression becomes larger. + * target_supp(<0): target echo suppression, unit(dB) + * noise_supp(-30~0): noise suppression, unit(dB) + * cng_type(0/1): noise type(0: White noise; 1: Pink noise) + * cng_level(<0): noise gain, unit(dB) + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz; + * Note: + * This is the recommended AEC +****************************************************************************************************/ + .tx_aec2float = { + .bypass = 0, + .hpf_enabled = false, + .af_enabled = false, + .nlp_enabled = true, + .clip_enabled = false, + .stsupp_enabled = false, + .ns_enabled = true, + .cng_enabled = false, + .blocks = 1, + .delay = 70, + .min_ovrd = 2, + .target_supp = -40, + .noise_supp = -15, + .cng_type = 1, + .cng_level = -60, + .clip_threshold = -20.f, + .banks = 64, + }, +#endif + +#if defined(SPEECH_TX_AEC3) + .tx_aec3 = { + .bypass = 0, + .filter_size = 16, + }, +#endif + +#if defined(SPEECH_TX_2MIC_NS) +/**************************************************************************************************** + * Describtion: + * 2 MICs Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz; + * Note: + * None +****************************************************************************************************/ + .tx_2mic_ns = { + .bypass = 0, + .alpha_h = 0.8, + .alpha_slow = 0.9, + .alpha_fast = 0.6, + .thegma = 0.01, + .thre_corr = 0.2, + .thre_filter_diff = 0.2, + .cal_left_gain = 1.0, + .cal_right_gain = 1.0, + .delay_mono_sample = 6, + .wnr_enable = 0, + }, +#endif + +#if defined(SPEECH_TX_2MIC_NS2) +/**************************************************************************************************** + * Describtion: + * 2 MICs Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * delay_taps(0~4): ceil{[d(MIC1~mouth) - d(MIC2~mouth)] / 2}. + * ceil: Returns the largest integer less than or equal to the specified data + * d(MIC~mouth): The dinstance from MIC to mouth + * e.g. 0: 0~2cm; 1: 2~4; 2: 5~6... + * freq_smooth_enable(1): Must enable + * wnr_enable(0/1): wind noise reduction enable or disable. This is also useful for improving + * noise suppression, but it also has some damage to speech signal. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz, 32M; + * Note: + * None +****************************************************************************************************/ + .tx_2mic_ns2 = { + .bypass = 0, + .delay_taps = 0.f, + .freq_smooth_enable = 1, + .wnr_enable = 1, + }, +#endif + +#if defined(SPEECH_TX_2MIC_NS5) +/**************************************************************************************************** + * Describtion: + * 2 MICs Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * delay_taps(0~4): ceil{[d(MIC1~mouth) - d(MIC2~mouth)] / 2}. Default as 0 + * ceil: Returns the largest integer less than or equal to the specified data + * d(MIC~mouth): The dinstance from MIC to mouth + * e.g. 0: 0~2cm; 1: 2~4; 2: 5~6... + * freq_smooth_enable(1): Must enable + * wnr_enable(0/1): wind noise reduction enable or disable. This is also useful for improving + * noise suppression, but it also has some damage to speech signal. + * delay_enable(0/1): enable the delay_taps or not. Ideally, never need to enable the delay and + * delay_taps will be a useless parameter. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz, 32M; + * Note: + * None +****************************************************************************************************/ + .tx_2mic_ns5 = { + .bypass = 0, + .delay_taps = 0.0f, + .freq_smooth_enable = 1, + .wnr_enable = 0, + .delay_enable = 0, + }, +#endif + +#if defined(SPEECH_TX_2MIC_NS4) +/**************************************************************************************************** + * Describtion: + * 2 MICs Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz; + * Note: + * None +****************************************************************************************************/ + .tx_2mic_ns4 = { + .bypass = 0, + .blend_en = 1, + // .left_gain = 1.0f, + // .right_gain = 1.0f, + .delay_tapsM = 0, + .delay_tapsS = 0, + // .delay_tapsC = 32, + //////////////////////////{{a0,a1,a2,a3,a4},{b0,b1,b2,b3,b4}}/////////////////////////// + // .coefH[0] = {1.0, -1.88561808316413, 1.55555555555556, -0.628539361054709, 0.111111111111111}, + // .coefH[1] = {0.323801506930344, -1.29520602772138, 1.94280904158206, -1.29520602772138, 0.323801506930344}, + // .coefL[0] = {1.0, -1.88561808316413, 1.55555555555556, -0.628539361054709, 0.111111111111111}, + // .coefL[1] = {0.00953182640298944, 0.0381273056119578, 0.0571909584179366, 0.0381273056119578, 0.00953182640298944}, + .crossover_freq = 1000, + .ff_fb_coeff = ff_fb_h, + .ff_fb_coeff_len = ARRAY_SIZE(ff_fb_h), + }, +#endif + +#if defined(SPEECH_TX_3MIC_NS) +/**************************************************************************************************** + * Describtion: + * 3 MICs Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * delay_tapsM(0~4): MIC L/R delay samples. Refer to SPEECH_TX_2MIC_NS2 delay_taps + * delay_tapsS(0~4): MIC L/S delay samples. Refer to SPEECH_TX_2MIC_NS2 delay_taps + * freq_smooth_enable(1): Must enable + * wnr_enable(0/1): wind noise reduction enable or disable. This is also useful for improving + * noise suppression, but it also has some damage to speech signal. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz; + * Note: + * None +****************************************************************************************************/ + .tx_3mic_ns = { + .bypass = 0, + .blend_en = 1, + .authen_en = 1, + .delay_tapsM = 0.65f, + .delay_tapsS = 2, + .denoise_dB = -15.0f, + // .coefH[0] = {1.0,-3.3384,4.2195,-2.3924,0.5136}, + // .coefH[1] = {0.7165,-2.8660,4.2990,-2.8660,0.7165}, + // .coefL[0] = {1.0,-3.3384,4.2195,-2.3924,0.5136}, + // .coefL[1] = {0.00014,0.00056,0.00084,0.00056,0.00014}, + .crossover_freq = 1000, + .freq_smooth_enable = 1, + .wnr_enable = 0, + }, +#endif + +#if defined(SPEECH_TX_3MIC_NS3) +/**************************************************************************************************** + * Describtion: + * 3 MICs Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * delay_taps(0~4): ceil{[d(MIC1~mouth) - d(MIC2~mouth)] / 2}. + * ceil: Returns the largest integer less than or equal to the specified data + * d(MIC~mouth): The dinstance from MIC to mouth + * e.g. 0: 0~2cm; 1: 2~4; 2: 5~6... + * freq_smooth_enable(1): Must enable + * wnr_enable(0/1): wind noise reduction enable or disable. This is also useful for improving + * noise suppression, but it also has some damage to speech signal. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz, 32M; + * Note: + * None +****************************************************************************************************/ + .tx_3mic_ns3 = { + .bypass = 0, + .endfire_enable = 1, + .broadside_enable = 1, + .delay_taps = 0.7f, + .freq_smooth_enable = 1, + .wnr_enable = 0, + }, +#endif + +#if defined(SPEECH_TX_NS) +/**************************************************************************************************** + * Describtion: + * Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz, 30M; + * Note: + * If possible, use SPEECH_TX_NS2 or SPEECH_TX_NS2FLOAT +****************************************************************************************************/ + .tx_ns = { + .bypass = 0, + .denoise_dB = -12, + }, +#endif + +#if defined(SPEECH_TX_NS2) +/**************************************************************************************************** + * Describtion: + * Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * denoise_dB(-30~0): noise suppression, unit(dB). + * e.g. -15: Can reduce 15dB of stationary noise. + * Resource consumption: + * RAM: fs = 16k: RAM = 8k; + * fs = 8k: RAM = 4k; + * RAM = frame_size * 30 + * FLASE: None + * MIPS: fs = 16kHz, 16M; + * Note: + * None +****************************************************************************************************/ + .tx_ns2 = { + .bypass = 0, + .denoise_dB = -15, + }, +#endif + +#if defined(SPEECH_TX_NS2FLOAT) +/**************************************************************************************************** + * Describtion: + * Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * denoise_dB(-30~0): noise suppression, unit(dB). + * e.g. -15: Can reduce 15dB of stationary noise. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz; + * Note: + * This is a 'float' version for SPEECH_TX_NS2. + * It needs more MIPS and RAM, but can redece quantization noise. +****************************************************************************************************/ + .tx_ns2float = { + .bypass = 0, + .denoise_dB = -15, + .banks = 64, + }, +#endif + +#if defined(SPEECH_TX_NS3) +/**************************************************************************************************** + * Describtion: + * Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * mode: None + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz; + * Note: + * None +****************************************************************************************************/ + .tx_ns3 = { + .bypass = 0, + .mode = NS3_SUPPRESSION_HIGH, + }, +#endif + +#if defined(SPEECH_TX_WNR) +/**************************************************************************************************** + * Describtion: + * Wind Noise Suppression + * Parameters: + * bypass(0/1): bypass enable or disable. + * lpf_cutoff: lowpass filter for wind noise detection + * hpf_cutoff: highpass filter for wind noise suppression + * power_ratio_thr: ratio of the power spectrum of the lower frequencies over the total power + spectrum for all frequencies + * power_thr: normalized power of the low frequencies + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz; + * Note: + * None +****************************************************************************************************/ + .tx_wnr = { + .bypass = 0, + .lpf_cutoff = 1000, + .hpf_cutoff = 400, + .power_ratio_thr = 0.9f, + .power_thr = 1.f, + }, +#endif + +#if defined(SPEECH_TX_NOISE_GATE) +/**************************************************************************************************** + * Describtion: + * Noise Gate + * Parameters: + * bypass(0/1): bypass enable or disable. + * data_threshold(0~32767): distinguish between noise and speech, unit(sample). + * data_shift(1~3): 1: -6dB; 2: -12dB; 3: -18dB + * factor_up(float): attack time, unit(s) + * factor_down(float): release time, unit(s) + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz; + * Note: + * None +****************************************************************************************************/ + .tx_noise_gate = { + .bypass = 0, + .data_threshold = 640, + .data_shift = 1, + .factor_up = 0.001f, + .factor_down = 0.5f, + }, +#endif + +#if defined(SPEECH_TX_COMPEXP) +/**************************************************************************************************** + * Describtion: + * Compressor and expander + * Parameters: + * bypass(0/1): bypass enable or disable. + * ... + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz; + * Note: + * None +****************************************************************************************************/ + .tx_compexp = { + .bypass = 0, + .comp_threshold = -10.f, + .comp_ratio = 2.f, + .expand_threshold = -45.f, + .expand_ratio = 0.5556f, + .attack_time = 0.001f, + .release_time = 0.6f, + .makeup_gain = 6, + .delay = 128, + }, +#endif + +#if defined(SPEECH_TX_AGC) +/**************************************************************************************************** + * Describtion: + * Automatic Gain Control + * Parameters: + * bypass(0/1): bypass enable or disable. + * target_level(>0): signal can not exceed (-1 * target_level)dB. + * compression_gain(>0): excepted gain. + * limiter_enable(0/1): 0: target_level does not take effect; 1: target_level takes effect. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz, 3M; + * Note: + * None +****************************************************************************************************/ + .tx_agc = { + .bypass = 0, + .target_level = 3, + .compression_gain = 6, + .limiter_enable = 1, + }, +#endif + +#if defined(SPEECH_TX_EQ) +/**************************************************************************************************** + * Describtion: + * Equalizer, implementation with 2 order iir filters + * Parameters: + * bypass(0/1): bypass enable or disable. + * gain(float): normalized gain. It is usually less than or equal to 0 + * num(0~6): the number of EQs + * params: {type, frequency, gain, q}. It supports a lot of types, please refer to iirfilt.h file + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz, 0.5M/section; + * Note: + * None +****************************************************************************************************/ + .tx_eq = { + .bypass = 0, + .gain = 0.f, + .num = 1, + .params = { + {IIR_BIQUARD_HPF, {{60, 0, 0.707f}}}, + }, + }, +#endif + +#if defined(SPEECH_TX_POST_GAIN) +/**************************************************************************************************** + * Describtion: + * Linear Gain + * Parameters: + * bypass(0/1): bypass enable or disable. + * Resource consumption: + * RAM: None + * FLASE: None + * MIPS: fs = 16kHz; + * Note: + * None +****************************************************************************************************/ + .tx_post_gain = { + .bypass = 0, + .gain_dB = 6.0f, + }, +#endif + +// #if defined(SPEECH_CS_VAD) +// /**************************************************************************************************** +// * Describtion: +// * Voice Activity Detector +// * Parameters: +// * bypass(0/1): bypass enable or disable. +// * Resource consumption: +// * RAM: None +// * FLASE: None +// * MIPS: fs = 16kHz; +// * Note: +// * None +// ****************************************************************************************************/ +// .tx_vad = { +// .snrthd = 5.f, +// .energythd = 100.f, +// }, +// #endif + +#if defined(SPEECH_RX_NS) +/**************************************************************************************************** + * Describtion: + * Acoustic Echo Cancellation + * Parameters: + * Refer to SPEECH_TX_NS + * Note: + * None +****************************************************************************************************/ + .rx_ns = { + .bypass = 0, + .denoise_dB = -12, + }, +#endif + +#if defined(SPEECH_RX_NS2) +/**************************************************************************************************** + * Describtion: + * Acoustic Echo Cancellation + * Parameters: + * Refer to SPEECH_TX_NS2 + * Note: + * None +****************************************************************************************************/ + .rx_ns2 = { + .bypass = 0, + .denoise_dB = -15, + }, +#endif + +#if defined(SPEECH_RX_NS2FLOAT) +/**************************************************************************************************** + * Describtion: + * Acoustic Echo Cancellation + * Parameters: + * Refer to SPEECH_TX_NS2FLOAT + * Note: + * None +****************************************************************************************************/ + .rx_ns2float = { + .bypass = 0, + .denoise_dB = -15, + .banks = 64, + }, +#endif + +#if defined(SPEECH_RX_NS3) +/**************************************************************************************************** + * Describtion: + * Acoustic Echo Cancellation + * Parameters: + * Refer to SPEECH_TX_NS3 + * Note: + * None +****************************************************************************************************/ + .rx_ns3 = { + .bypass = 0, + .mode = NS3_SUPPRESSION_HIGH, + }, +#endif + +#if defined(SPEECH_RX_NOISE_GATE) +/**************************************************************************************************** + * Describtion: + * Noise Gate + * Parameters: + * Refer to SPEECH_TX_NOISE_GATE + * Note: + * None +****************************************************************************************************/ + .rx_noise_gate = { + .bypass = 0, + .data_threshold = 640, + .data_shift = 1, + .factor_up = 0.001f, + .factor_down = 0.5f, + }, +#endif + +#if defined(SPEECH_RX_COMPEXP) +/**************************************************************************************************** + * Describtion: + * Compressor and expander + * Parameters: + * Refer to SPEECH_TX_COMPEXP + * Note: + * None +****************************************************************************************************/ + .rx_compexp = { + .bypass = 0, + .comp_threshold = -10.f, + .comp_slope = 0.5f, + .expand_threshold = -40.f, + .expand_slope = -0.5f, + .attack_time = 0.01f, + .release_time = 0.6f, + .makeup_gain = 6, + .delay = 128, + }, +#endif + +#if defined(SPEECH_RX_AGC) +/**************************************************************************************************** + * Describtion: + * Automatic Gain Control + * Parameters: + * Refer to SPEECH_TX_AGC + * Note: + * None +****************************************************************************************************/ + .rx_agc = { + .bypass = 0, + .target_level = 3, + .compression_gain = 6, + .limiter_enable = 1, + }, +#endif + +#if defined(SPEECH_RX_EQ) +/**************************************************************************************************** + * Describtion: + * Equalizer, implementation with 2 order iir filters + * Parameters: + * Refer to SPEECH_TX_EQ + * Note: + * None +****************************************************************************************************/ + .rx_eq = { + .bypass = 0, + .gain = 0.f, + .num = 1, + .params = { + {IIR_BIQUARD_HPF, {{60, 0, 0.707f}}}, + }, + }, +#endif + +#if defined(SPEECH_RX_POST_GAIN) +/**************************************************************************************************** + * Describtion: + * Linear Gain + * Parameters: + * Refer to SPEECH_TX_POST_GAIN + * Note: + * None +****************************************************************************************************/ + .rx_post_gain = { + .bypass = 0, + .gain_dB = 6.0f, + }, +#endif + +}; diff --git a/apps/audioplayers/bt_sco_chain_cp.c b/apps/audioplayers/bt_sco_chain_cp.c new file mode 100644 index 0000000..0d19521 --- /dev/null +++ b/apps/audioplayers/bt_sco_chain_cp.c @@ -0,0 +1,228 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + * Usage: + * 1. Enable SCO_CP_ACCEL ?= 1 to enable dual core in sco + * 2. Enable SCO_TRACE_CP_ACCEL ?= 1 to see debug log. + * 3. Change channel number if the algo(run in cp) input is more than one channel: sco_cp_init(speech_tx_frame_len, 1); + * 4. The code between SCO_CP_ACCEL_ALGO_START(); and SCO_CP_ACCEL_ALGO_END(); will run in CP core. + * 5. These algorithms will work in AP. Need to move this algorithms from overlay to fast ram. + * + * NOTE: + * 1. spx fft and hw fft will share buffer, so just one core can use these fft. + * 2. audio_dump_add_channel_data function can not work correctly in CP core, because + * audio_dump_add_channel_data is possible called after audio_dump_run(); + * 3. AP and CP just can use 85% + * + * + * + * TODO: + * 1. FFT, RAM, CODE overlay + **/ +#if defined(SCO_CP_ACCEL) +#include "cp_accel.h" +#include "hal_location.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "cmsis_os.h" +#include "speech_cfg.h" +#include "math.h" +#include "norflash_api.h" + +// malloc data from pool in init function +#define FRAME_LEN_MAX (256) +#define CHANNEL_NUM_MAX (2) + +enum CP_SCO_STATE_T { + CP_SCO_STATE_NONE = 0, + CP_SCO_STATE_IDLE, + CP_SCO_STATE_WORKING, +}; + +enum SCO_CP_CMD_T { + SCO_CP_CMD_PRO = 0, + SCO_CP_CMD_OTHER, + + SCO_CP_CMD_QTY, +}; + +static CP_DATA_LOC enum CP_SCO_STATE_T g_cp_state = CP_SCO_STATE_NONE; + +// TODO: Use malloc to replace array +// static CP_BSS_LOC char g_cp_heap_buf[1024 * 100]; +static CP_BSS_LOC short g_in_pcm_buf[FRAME_LEN_MAX * CHANNEL_NUM_MAX]; +static CP_BSS_LOC short g_out_pcm_buf[FRAME_LEN_MAX * CHANNEL_NUM_MAX]; +static CP_BSS_LOC short g_in_ref_buf[FRAME_LEN_MAX]; +static CP_BSS_LOC int g_pcm_len; + +static CP_BSS_LOC int g_frame_len; +static CP_BSS_LOC int g_channel_num; + +static int g_require_cnt = 0; +static int g_run_cnt = 0; + +int sco_cp_process(short *pcm_buf, short *ref_buf, int *_pcm_len) +{ + int32_t pcm_len = *_pcm_len; + uint32_t wait_cnt = 0; + + ASSERT(g_frame_len * g_channel_num == pcm_len, "[%s] g_frame_len(%d) * g_channel_num(%d) != pcm_len(%d)", __func__, g_frame_len, g_channel_num, pcm_len); + + // Check CP has new data to get and can get data from buffer +#if defined(SCO_TRACE_CP_ACCEL) + TRACE(4,"[%s] g_require_cnt: %d, status: %d, pcm_len: %d", __func__, g_require_cnt, g_cp_state, pcm_len); +#endif + + while (g_cp_state == CP_SCO_STATE_WORKING) + { + hal_sys_timer_delay_us(10); + + if (wait_cnt++ > 300000) { // 3s + ASSERT(0, "cp is hung %d", g_cp_state); + } + } + + if (g_cp_state == CP_SCO_STATE_IDLE) + { + speech_copy_int16(g_in_pcm_buf, pcm_buf, pcm_len); + if (ref_buf) + { + speech_copy_int16(g_in_ref_buf, ref_buf, pcm_len / g_channel_num); + } + speech_copy_int16(pcm_buf, g_out_pcm_buf, g_pcm_len); + *_pcm_len = g_pcm_len; + g_pcm_len = pcm_len; + + g_require_cnt++; + g_cp_state = CP_SCO_STATE_WORKING; + cp_accel_send_event_mcu2cp(CP_BUILD_ID(CP_TASK_SCO, CP_EVENT_SCO_PROCESSING)); + } + else + { + // Multi channels to one channel +#if 0 + for (int i = 0; i < pcm_len / g_channel_num; i++) + { + pcm_buf[i] = pcm_buf[2*i]; + } + + *_pcm_len = pcm_len / g_channel_num; +#endif + + // Check abs(g_require_cnt - g_run_cnt) > threshold, reset or assert + + TRACE(2,"[%s] ERROR: status = %d", __func__, g_cp_state); + } + + return 0; +} + +extern int sco_cp_algo(short *pcm_buf, short *ref_buf, int *_pcm_len); + +CP_TEXT_SRAM_LOC +static unsigned int sco_cp_main(uint8_t event) +{ +#if defined(SCO_TRACE_CP_ACCEL) + TRACE(2,"[%s] g_run_cnt: %d", __func__, g_run_cnt); +#endif + + // LOCK BUFFER + + // process pcm +#if 0 + // speech_copy_int16(g_out_pcm_buf, g_in_pcm_buf, g_pcm_len); + + for (int i = 0; i < g_pcm_len; i++) + { + g_out_pcm_buf[i] = (short)(sinf(2 * 3.1415926 * i / 16 ) * 10000); + } +#else + sco_cp_algo(g_in_pcm_buf, g_in_ref_buf, &g_pcm_len); + speech_copy_int16(g_out_pcm_buf, g_in_pcm_buf, g_pcm_len); +#endif + + // set status + g_run_cnt++; + g_cp_state = CP_SCO_STATE_IDLE; + +#if defined(SCO_TRACE_CP_ACCEL) + TRACE(1,"[%s] CP_SCO_STATE_IDLE", __func__); +#endif + + // UNLOCK BUFFER + + return 0; +} + +static struct cp_task_desc TASK_DESC_SCO = {CP_ACCEL_STATE_CLOSED, sco_cp_main, NULL, NULL, NULL}; +int sco_cp_init(int frame_len, int channel_num) +{ + TRACE(3,"[%s] frame_len: %d, channel_num: %d", __func__, frame_len, channel_num); + ASSERT(frame_len <= FRAME_LEN_MAX, "[%s] frame_len(%d) > FRAME_LEN_MAX", __func__, frame_len); + ASSERT(channel_num <= CHANNEL_NUM_MAX, "[%s] channel_num(%d) > CHANNEL_NUM_MAX", __func__, channel_num); + + g_require_cnt = 0; + g_run_cnt = 0; + + norflash_api_flush_disable(NORFLASH_API_USER_CP,(uint32_t)cp_accel_init_done); + cp_accel_open(CP_TASK_SCO, &TASK_DESC_SCO); + + uint32_t cnt=0; + while(cp_accel_init_done() == false) { + hal_sys_timer_delay_us(100); + + cnt++; + if (cnt % 10 == 0) { + if (cnt == 10 * 200) { // 200ms + ASSERT(0, "[%s] ERROR: Can not init cp!!!", __func__); + } else { + TRACE(1, "[%s] Wait CP init done...%d(ms)", __func__, cnt/10); + } + } + } + norflash_api_flush_enable(NORFLASH_API_USER_CP); +#if 0 + speech_heap_cp_start(); + speech_heap_add_block(g_cp_heap_buf, sizeof(g_cp_heap_buf)); + speech_heap_cp_end(); +#endif + + g_frame_len = frame_len; + g_channel_num = channel_num; + g_pcm_len = frame_len; // Initialize output pcm_len + + speech_set_int16(g_in_pcm_buf, 0, g_frame_len * g_channel_num); + speech_set_int16(g_out_pcm_buf, 0, g_frame_len * g_channel_num); + speech_set_int16(g_in_ref_buf, 0, g_frame_len); + g_cp_state = CP_SCO_STATE_IDLE; + + TRACE(2,"[%s] status = %d", __func__, g_cp_state); + + return 0; + +} + +int sco_cp_deinit(void) +{ + TRACE(1,"[%s] ...", __func__); + + cp_accel_close(CP_TASK_SCO); + + g_cp_state = CP_SCO_STATE_NONE; + + return 0; +} +#endif diff --git a/apps/audioplayers/bt_sco_chain_cp.h b/apps/audioplayers/bt_sco_chain_cp.h new file mode 100644 index 0000000..acb7988 --- /dev/null +++ b/apps/audioplayers/bt_sco_chain_cp.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BT_SCO_CHAIN_CP_H__ +#define __BT_SCO_CHAIN_CP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "stdbool.h" + +// enum CP_EMPTY_OUT_FRM_T { +// CP_EMPTY_OUT_FRM_OK, +// CP_EMPTY_OUT_FRM_WORKING, +// CP_EMPTY_OUT_FRM_ERR, +// }; + +// typedef int (*A2DP_CP_DECODE_T)(void); + +int sco_cp_init(int frame_len, int channel_num); + +int sco_cp_deinit(void); + +// int sco_cp_set_pcm(short *pcm_buf, int pcm_len); + +// int sco_cp_get_pcm(short *pcm_buf, int pcm_len); + +int sco_cp_process(short *pcm_buf, short *ref_buf, int *_pcm_len); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/apps/audioplayers/bt_sco_chain_thirdparty.c b/apps/audioplayers/bt_sco_chain_thirdparty.c new file mode 100644 index 0000000..a82f36f --- /dev/null +++ b/apps/audioplayers/bt_sco_chain_thirdparty.c @@ -0,0 +1,155 @@ +#include "bt_sco_chain.h" +#include "speech_memory.h" +#include "speech_utils.h" +#include "hal_trace.h" +#include "audio_dump.h" +#include "speech_cfg.h" + +#if defined(SPEECH_TX_24BIT) +int32_t *aec_echo_buf = NULL; + +// Use to free buffer +static int32_t *aec_echo_buf_ptr = NULL; +#else +short *aec_echo_buf = NULL; + +// Use to free buffer +static short *aec_echo_buf_ptr; +#endif + +#if defined(MSBC_8K_SAMPLE_RATE) +#define SPEECH_HEAP_RESERVE_SIZE (1024 * 4) +#else +#define SPEECH_HEAP_RESERVE_SIZE (1024 * 4) +#endif + +#if defined(SPEECH_TX_DC_FILTER) +SpeechDcFilterState *speech_tx_dc_filter_st = NULL; +#endif + +int speech_init(int tx_sample_rate, int rx_sample_rate, + int tx_frame_ms, int rx_frame_ms, + int sco_frame_ms, + uint8_t *buf, int len) +{ + // we shoule keep a minmum buffer for speech heap + // MSBC_16K_SAMPLE_RATE = 0, 560 bytes + // MSBC_16K_SAMPLE_RATE = 1, 2568 bytes + speech_heap_init(buf, SPEECH_HEAP_RESERVE_SIZE); + + uint8_t *free_buf = buf + SPEECH_HEAP_RESERVE_SIZE; + int free_len = len - SPEECH_HEAP_RESERVE_SIZE; + + // use free_buf for your algorithm + memset(free_buf, 0, free_len); + + int frame_len = SPEECH_FRAME_MS_TO_LEN(tx_sample_rate, tx_frame_ms); + +#if defined(SPEECH_TX_24BIT) + aec_echo_buf = (int32_t *)speech_calloc(frame_len, sizeof(int32_t)); +#else + aec_echo_buf = (short *)speech_calloc(frame_len, sizeof(short)); +#endif + aec_echo_buf_ptr = aec_echo_buf; + +#if defined(SPEECH_TX_DC_FILTER) + int channel_num = SPEECH_CODEC_CAPTURE_CHANNEL_NUM; + int data_separation = 0; + + SpeechDcFilterConfig dc_filter_cfg = { + .bypass = 0, + .gain = 0.f, + }; + + speech_tx_dc_filter_st = speech_dc_filter_create(tx_sample_rate, frame_len, &dc_filter_cfg); + speech_dc_filter_ctl(speech_tx_dc_filter_st, SPEECH_DC_FILTER_SET_CHANNEL_NUM, &channel_num); + speech_dc_filter_ctl(speech_tx_dc_filter_st, SPEECH_DC_FILTER_SET_DATA_SEPARATION, &data_separation); +#endif + + audio_dump_init(frame_len, sizeof(int16_t), 3); + + return 0; +} + +int speech_deinit(void) +{ +#if defined(SPEECH_TX_DC_FILTER) + speech_dc_filter_destroy(speech_tx_dc_filter_st); +#endif + + speech_free(aec_echo_buf_ptr); + + size_t total = 0, used = 0, max_used = 0; + speech_memory_info(&total, &used, &max_used); + TRACE(3,"SPEECH MALLOC MEM: total - %d, used - %d, max_used - %d.", total, used, max_used); + ASSERT(used == 0, "[%s] used != 0", __func__); + + return 0; +} + +#if defined(BONE_SENSOR_TDM) +extern void bt_sco_get_tdm_buffer(uint8_t **buf, uint32_t *len); +#endif + +int speech_tx_process(void *_pcm_buf, void *_ref_buf, int *_pcm_len) +{ +#if defined(SPEECH_TX_24BIT) + int32_t *pcm_buf = (int32_t *)_pcm_buf; + int32_t *ref_buf = (int32_t *)_ref_buf; +#else + int16_t *pcm_buf = (int16_t *)_pcm_buf; + int16_t *ref_buf = (int16_t *)_ref_buf; +#endif + + int pcm_len = *_pcm_len; + +#if defined(BONE_SENSOR_TDM) + uint8_t *bone_buf = NULL; + uint32_t bone_len = 0; + bt_sco_get_tdm_buffer(&bone_buf, &bone_len); +#endif + + audio_dump_clear_up(); + audio_dump_add_channel_data(0, ref_buf, pcm_len / SPEECH_CODEC_CAPTURE_CHANNEL_NUM); + audio_dump_add_channel_data_from_multi_channels(1, pcm_buf, pcm_len / SPEECH_CODEC_CAPTURE_CHANNEL_NUM, SPEECH_CODEC_CAPTURE_CHANNEL_NUM, 0); + audio_dump_add_channel_data_from_multi_channels(2, pcm_buf, pcm_len / SPEECH_CODEC_CAPTURE_CHANNEL_NUM, SPEECH_CODEC_CAPTURE_CHANNEL_NUM, 1); + +#if defined(BONE_SENSOR_TDM) + audio_dump_add_channel_data(3, bone_buf, pcm16_len/SPEECH_CODEC_CAPTURE_CHANNEL_NUM); +#endif + + audio_dump_run(); + +#if defined(SPEECH_TX_DC_FILTER) +#if defined(SPEECH_TX_24BIT) + speech_dc_filter_process_int24(speech_tx_dc_filter_st, pcm_buf, pcm_len); +#else + speech_dc_filter_process(speech_tx_dc_filter_st, pcm_buf, pcm_len); +#endif +#endif + + // Add your algrithm here and disable #if macro +#if 1 + for (int i = 0, j = 0; i < pcm_len; i += SPEECH_CODEC_CAPTURE_CHANNEL_NUM, j++) { + // choose main microphone data + pcm_buf[j] = pcm_buf[i]; + // choose reference data, i.e. loopback + //pcm16_buf[j] = ref16_buf[j]; + } + pcm_len /= SPEECH_CODEC_CAPTURE_CHANNEL_NUM; +#endif + +#if defined(BONE_SENSOR_TDM) + memcpy(pcm_buf, bone_buf, bone_len); +#endif + + *_pcm_len = pcm_len; + + return 0; +} + +int speech_rx_process(void *pcm_buf, int *pcm_len) +{ + // Add your algorithm here + return 0; +} \ No newline at end of file diff --git a/apps/audioplayers/bt_sco_chain_thirdparty_alango.c b/apps/audioplayers/bt_sco_chain_thirdparty_alango.c new file mode 100644 index 0000000..980e58e --- /dev/null +++ b/apps/audioplayers/bt_sco_chain_thirdparty_alango.c @@ -0,0 +1,192 @@ +#include "bt_sco_chain.h" +#include "speech_memory.h" +#include "speech_utils.h" +#include "hal_trace.h" +#include "audio_dump.h" +#include "vcp-api.h" +#include "spf-postapi.h" + +#define ALANGO_TRACE(s, ...) TRACE(1,"%s: " s, __FUNCTION__, ## __VA_ARGS__) + +short *aec_echo_buf = NULL; + +// Use to free buffer +static short *aec_echo_buf_ptr; + +static void *mem; + +extern void *voicebtpcm_get_ext_buff(int size); + +extern char* vcp_errorv(err_t err); + +extern PROFILE_TYPE(t) alango_profile; + +static vcp_profile_t *curr_profile = NULL; + +mem_reg_t reg[NUM_MEM_REGIONS]; + +#if SPEECH_CODEC_CAPTURE_CHANNEL_NUM >= 2 +static int16_t *deinterleaved_buf = NULL; + +static void deinterleave_audio(int16_t *dst, int16_t *src, uint32_t len, uint32_t ch_num) +{ + uint32_t samples_per_channel = len / ch_num; + + for (uint32_t i = 0; i < samples_per_channel; i++) { + for (uint32_t j = 0; j < ch_num; j++) { + dst[samples_per_channel * j + i] = src[ch_num * i + j]; + } + } +} +#endif + +int speech_init(int tx_sample_rate, int rx_sample_rate, + int tx_frame_ms, int rx_frame_ms, + int sco_frame_ms, + uint8_t *buf, int len) +{ + speech_heap_init(buf, len); + + int frame_len = SPEECH_FRAME_MS_TO_LEN(tx_sample_rate, tx_frame_ms); + + aec_echo_buf = (short *)speech_calloc(frame_len, sizeof(short)); + aec_echo_buf_ptr = aec_echo_buf; + + // init alango + // check profile + curr_profile = &alango_profile; + err_t err = vcp_check_profile(curr_profile); + if (err.err) { + if (err.err == ERR_INVALID_CRC) + ALANGO_TRACE(0,"Profile error: Invalid CRC!"); + else + ALANGO_TRACE(1,"Profile error: %d", err.err); + } + + ASSERT(frame_len % curr_profile->p_gen->frlen == 0, "Profile error: frame_len(%d) should be divided by frlen(%d)", frame_len, curr_profile->p_gen->frlen); + + unsigned int smem = vcp_get_hook_size(); + mem = speech_malloc(smem); + + vcp_get_mem_size(curr_profile, reg, mem); + + ALANGO_TRACE(0,"Hello, I am VCP8!"); + + for (int i = 0; i < NUM_MEM_REGIONS; i++) { + reg[i].mem = (void *)speech_malloc(reg[i].size); + ALANGO_TRACE(2,"I need %d bytes of memory in memory region %d to work.\n", reg[i].size, i + 1); + } + + err = vcp_init_debug(curr_profile, reg); + if (err.err == ERR_NOT_ENOUGH_MEMORY) { + ALANGO_TRACE(2,"%d more bytes needed in region %d!\n", -reg[err.pid].size, err.pid); + } else if (err.err == ERR_UNKNOWN) { + ALANGO_TRACE(0,"vcp_init_debug() returns UNKNOWN error\n!"); + } else if (err.err != ERR_NO_ERROR) { + ALANGO_TRACE(2,"vcp_init_debug() returns error %d, pid %d!\n", err.err, err.pid); + } + +#if SPEECH_CODEC_CAPTURE_CHANNEL_NUM >= 2 + deinterleaved_buf = speech_malloc(curr_profile->p_gen->frlen * SPEECH_CODEC_CAPTURE_CHANNEL_NUM * sizeof(int16_t)); +#endif + + audio_dump_init(frame_len, sizeof(int16_t), 3); + + return 0; +} + +int speech_deinit(void) +{ + speech_free(aec_echo_buf_ptr); + speech_free(mem); + + for (int i = 0; i < NUM_MEM_REGIONS; i++) + speech_free(reg[i].mem); + +#if SPEECH_CODEC_CAPTURE_CHANNEL_NUM >= 2 + speech_free(deinterleaved_buf); +#endif + + size_t total = 0, used = 0, max_used = 0; + speech_memory_info(&total, &used, &max_used); + TRACE(3,"SPEECH MALLOC MEM: total - %d, used - %d, max_used - %d.", total, used, max_used); + ASSERT(used == 0, "[%s] used != 0", __func__); + + return 0; +} + +#if defined(BONE_SENSOR_TDM) +extern void bt_sco_get_tdm_buffer(uint8_t **buf, uint32_t *len); +#endif + +int speech_tx_process(void *pcm_buf, void *ref_buf, int *pcm_len) +{ + int16_t *pcm16_buf = (int16_t *)pcm_buf; + int16_t *ref16_buf = (int16_t *)ref_buf; + int pcm16_len = *pcm_len; + +#if defined(BONE_SENSOR_TDM) + uint8_t *bone_buf = NULL; + uint32_t bone_len = 0; + bt_sco_get_tdm_buffer(&bone_buf, &bone_len); +#endif + + audio_dump_clear_up(); + audio_dump_add_channel_data(0, ref_buf, pcm16_len / SPEECH_CODEC_CAPTURE_CHANNEL_NUM); + audio_dump_add_channel_data_from_multi_channels(1, pcm16_buf, pcm16_len / SPEECH_CODEC_CAPTURE_CHANNEL_NUM, SPEECH_CODEC_CAPTURE_CHANNEL_NUM, 0); + audio_dump_add_channel_data_from_multi_channels(2, pcm16_buf, pcm16_len / SPEECH_CODEC_CAPTURE_CHANNEL_NUM, SPEECH_CODEC_CAPTURE_CHANNEL_NUM, 1); + +#if defined(BONE_SENSOR_TDM) + audio_dump_add_channel_data(3, bone_buf, pcm16_len/SPEECH_CODEC_CAPTURE_CHANNEL_NUM); +#endif + + audio_dump_run(); + + // Add your algrithm here and disable #if macro +#if 0 + for (int i = 0, j = 0; i < pcm16_len; i += SPEECH_CODEC_CAPTURE_CHANNEL_NUM, j++) { + // choose main microphone data + pcm16_buf[j] = pcm16_buf[i]; + // choose reference data, i.e. loopback + //pcm16_buf[j] = ref16_buf[j]; + } + pcm16_len /= SPEECH_CODEC_CAPTURE_CHANNEL_NUM; +#else + for (int i = 0, j = 0; i < pcm16_len; i += curr_profile->p_gen->frlen * SPEECH_CODEC_CAPTURE_CHANNEL_NUM, j += curr_profile->p_gen->frlen) { +#if SPEECH_CODEC_CAPTURE_CHANNEL_NUM >= 2 + deinterleave_audio(deinterleaved_buf, &pcm16_buf[i], curr_profile->p_gen->frlen * SPEECH_CODEC_CAPTURE_CHANNEL_NUM, SPEECH_CODEC_CAPTURE_CHANNEL_NUM); + err_t err = vcp_process_tx(reg, deinterleaved_buf, &ref16_buf[j], &pcm16_buf[j]); + //memcpy(&pcm16_buf[j], deinterleaved_buf, curr_profile->p_gen->frlen * sizeof(int16_t)); +#else + err_t err = vcp_process_tx(reg, &pcm16_buf[i], &ref16_buf[j], &pcm16_buf[j]); +#endif + if (err.err != ERR_NO_ERROR) { + ALANGO_TRACE(1,"vcp_process_tx error: %d", err.err); + } + } + pcm16_len /= SPEECH_CODEC_CAPTURE_CHANNEL_NUM; +#endif + +#if defined(BONE_SENSOR_TDM) + memcpy(pcm_buf, bone_buf, bone_len); +#endif + + *pcm_len = pcm16_len; + + return 0; +} + +int speech_rx_process(void *pcm_buf, int *pcm_len) +{ + int16_t *pcm16_buf = (int16_t *)pcm_buf; + int pcm16_len = *pcm_len; + + for (int i = 0; i < pcm16_len; i += curr_profile->p_gen->frlen) { + err_t err = vcp_process_rx(reg, &pcm16_buf[i], &pcm16_buf[i]); + if (err.err != ERR_NO_ERROR) { + ALANGO_TRACE(1,"vcp_process_tx error: %d", err.err); + } + } + + return 0; +} \ No newline at end of file diff --git a/apps/audioplayers/bt_sco_chain_tuning.c b/apps/audioplayers/bt_sco_chain_tuning.c new file mode 100644 index 0000000..190ae4d --- /dev/null +++ b/apps/audioplayers/bt_sco_chain_tuning.c @@ -0,0 +1,224 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "bt_sco_chain_cfg.h" +#include "aud_section.h" +#include "hal_trace.h" + +static bool speech_tuning_status = false; + +extern int speech_store_config(const SpeechConfig *cfg); + +#ifdef AUDIO_SECTION_ENABLE +typedef struct { + uint8_t reserved[AUDIO_SECTION_CFG_RESERVED_LEN]; + SpeechConfig cfg; +} AUDIO_SECTION_SPEECH_CFG_T; + +static AUDIO_SECTION_SPEECH_CFG_T audio_section_speech_cfg; + +int store_speech_cfg_into_audio_section(SpeechConfig *cfg) +{ + int res = 0; + + memcpy(&audio_section_speech_cfg.cfg, cfg, sizeof(SpeechConfig)); + + res = audio_section_store_cfg(AUDIO_SECTION_DEVICE_SPEECH, + (uint8_t *)&audio_section_speech_cfg, + sizeof(AUDIO_SECTION_SPEECH_CFG_T)); + + + if(res) + { + TRACE(2,"[%s] ERROR: res = %d", __func__, res); + } + else + { + TRACE(1,"[%s] Store speech cfg into audio section!!!", __func__); + } + + return res; +} + +void *load_speech_cfg_from_audio_section(void) +{ + int res = 0; + res = audio_section_load_cfg(AUDIO_SECTION_DEVICE_SPEECH, + (uint8_t *)&audio_section_speech_cfg, + sizeof(AUDIO_SECTION_SPEECH_CFG_T)); + + void *res_ptr = NULL; + + if (res) + { + TRACE(2,"[%s] ERROR: res = %d", __func__, res); + res_ptr = NULL; + } + else + { + TRACE(1,"[%s] Load speech cfg from audio section!!!", __func__); + res_ptr = (void *)&audio_section_speech_cfg.cfg; + } + + return res_ptr; +} +#endif + +int speech_tuning_set_status(bool en) +{ + speech_tuning_status = en; + + return 0; +} + +bool speech_tuning_get_status(void) +{ + return speech_tuning_status; +} + +uint32_t speech_tuning_check(unsigned char *buf, uint32_t len) +{ + uint32_t res = 0; + + // Check valid + uint32_t config_size = sizeof(SpeechConfig); + + if (config_size != len) + { + TRACE(2,"[speech tuning] len(%d) != config_size(%d)", len, config_size); + res = 1; + } + else + { + TRACE(1,"[speech tuning] len(%d) is OK", len); + //SpeechConfig POSSIBLY_UNUSED *cfg = (SpeechConfig *)buf; + + // Test parameters +//#if defined(SPEECH_TX_2MIC_NS2) +// TRACE(1,"[speech tuning] TX: delay_taps(x100): %d", (int)(cfg->tx_2mic_ns2.delay_taps * 100)); +//#endif +//#if defined(SPEECH_TX_NOISE_GATE) +// TRACE(1,"[speech tuning] TX: data_threshold: %d", cfg->tx_noise_gate.data_threshold); +//#endif +//#if defined(SPEECH_TX_EQ) +// TRACE(1,"[speech tuning] TX: eq num: %d", cfg->tx_eq.num); +//#endif +//#if defined(SPEECH_RX_EQ) +// TRACE(1,"[speech tuning] RX: eq num: %d", cfg->rx_eq.num); +//#endif + } + + return res; +} + +uint32_t speech_tuning_rx_callback(unsigned char *buf, uint32_t len) +{ + uint32_t res = 0; + + res = speech_tuning_check(buf, len); + + if (res) + { + TRACE(1,"[speech tuning] ERROR: Send check res = %d", res); + TRACE(0,"[Speech Tuning] res : 1; info : Send len(%d) != config_size(%d);", len, sizeof(SpeechConfig)); + } + else + { + // Save cfg + speech_store_config((SpeechConfig *)buf); + + // Set status + speech_tuning_set_status(true); + + TRACE(0,"[speech tuning] OK: Send cfg"); + TRACE(0,"[Speech Tuning] res : 0;"); + } + + return res; +} + +#ifdef AUDIO_SECTION_ENABLE +uint32_t speech_tuning_burn_rx_callback(unsigned char *buf, uint32_t len) +{ + uint32_t res = 0; + + res = speech_tuning_check(buf, len); + + if (res) + { + TRACE(1,"[speech tuning] ERROR: Burn check res = %d", res); + TRACE(0,"[Speech Tuning] res : 1; info : Burn len(%d) != config_size(%d);", len, sizeof(SpeechConfig)); + } + else + { + res = store_speech_cfg_into_audio_section((SpeechConfig *)buf); + + if(res) + { + TRACE(1,"[speech tuning] ERROR: Store res = %d", res); + res += 100; + TRACE(0,"[Speech Tuning] res : 2; info : Do not enable AUDIO_SECTION_ENABLE;"); + } + else + { + TRACE(0,"[speech tuning] OK: Store cfg"); + TRACE(0,"[Speech Tuning] res : 0;"); + } + } + + return res; +} +#endif + +int speech_tuning_init(void) +{ +#if defined(HAL_TRACE_RX_ENABLE) && !defined(SPEECH_TX_THIRDPARTY) + hal_trace_rx_register("Speech Tuning", (HAL_TRACE_RX_CALLBACK_T)speech_tuning_rx_callback); + +#ifdef AUDIO_SECTION_ENABLE + hal_trace_rx_register("Speech Tuning Burn", (HAL_TRACE_RX_CALLBACK_T)speech_tuning_burn_rx_callback); +#endif + +#endif + + speech_tuning_set_status(false); + + return 0; +} + +int speech_tuning_open(void) +{ +#ifdef AUDIO_SECTION_ENABLE + SpeechConfig *speech_cfg_load = NULL; + + speech_cfg_load = (SpeechConfig *)load_speech_cfg_from_audio_section(); + + if (speech_cfg_load) + { + speech_store_config(speech_cfg_load); + } +#endif + + speech_tuning_set_status(false); + + return 0; +} + +int speech_tuning_close(void) +{ + speech_tuning_set_status(false); + + return 0; +} diff --git a/apps/audioplayers/bt_sco_chain_tuning.h b/apps/audioplayers/bt_sco_chain_tuning.h new file mode 100644 index 0000000..8fcda75 --- /dev/null +++ b/apps/audioplayers/bt_sco_chain_tuning.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BT_SCO_CHAIN_TUNING_H__ +#define __BT_SCO_CHAIN_TUNING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +// Initialize this module when platform setup +int speech_tuning_init(void); + +// Open this module when speech stream open +int speech_tuning_open(void); + +// Close this module when speech stream close +int speech_tuning_close(void); + +bool speech_tuning_get_status(void); +int speech_tuning_set_status(bool en); + + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/apps/audioplayers/cvsdplay.cpp b/apps/audioplayers/cvsdplay.cpp new file mode 100644 index 0000000..d3c8127 --- /dev/null +++ b/apps/audioplayers/cvsdplay.cpp @@ -0,0 +1,264 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef MBED +#include "mbed.h" +#endif +// Standard C Included Files +#include +#include +#include +#include +#include +#ifdef MBED +//#include "rtos.h" +#endif +#ifdef MBED +#include "SDFileSystem.h" +#endif +#include "cqueue.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "app_audio.h" + + +// BT + +#if 0 +/* mutex */ +osMutexId g_voicecvsd_queue_mutex_id = NULL; +osMutexDef(g_voicecvsd_queue_mutex); + +/* cvsd queue */ +#define VOICECVSD_TEMP_BUFFER_SIZE 128 +#define VOICECVSD_QUEUE_SIZE (VOICECVSD_TEMP_BUFFER_SIZE*20) +CQueue voicecvsd_queue; + +static enum APP_AUDIO_CACHE_T voicecvsd_cache_status = APP_AUDIO_CACHE_QTY; + +#define LOCK_VOICECVSD_QUEUE() \ + osMutexWait(g_voicecvsd_queue_mutex_id, osWaitForever) + +#define UNLOCK_VOICECVSD_QUEUE() \ + osMutexRelease(g_voicecvsd_queue_mutex_id) + +void xLOCK_VOICECVSD_QUEUE(void) +{ + osMutexWait(g_voicecvsd_queue_mutex_id, osWaitForever); +} + +void xUNLOCK_VOICECVSD_QUEUE(void) +{ + osMutexRelease(g_voicecvsd_queue_mutex_id); +} + +//static void dump_buffer_to_psram(char *buf, unsigned int len) +//{ +// static unsigned int offset = 0; +// memcpy((void *)(0x1c000000 + offset), buf, len); +//} + +static void copy_one_trace_to_two_track_16bits(uint16_t *src_buf, uint16_t *dst_buf, uint32_t src_len) +{ + uint32_t i = 0; + for (i = 0; i < src_len; ++i) { + dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = src_buf[i]; + } +} + +int store_voicecvsd_buffer(unsigned char *buf, unsigned int len) +{ + LOCK_VOICECVSD_QUEUE(); + EnCQueue(&voicecvsd_queue, buf, len); +#if 0 + dump_buffer_to_psram((char *)buf, len); + TRACE(1,"%d\n", LengthOfCQueue(&voicecvsd_queue)); +#endif + if (LengthOfCQueue(&voicecvsd_queue) > VOICECVSD_TEMP_BUFFER_SIZE*10) { + voicecvsd_cache_status = APP_AUDIO_CACHE_OK; + } + UNLOCK_VOICECVSD_QUEUE(); + + return 0; +} + +int store_voice_pcm2cvsd(unsigned char *buf, unsigned int len) +{ + uint8_t cvsdtmpbuffer[VOICECVSD_TEMP_BUFFER_SIZE]; + + short * pBuffProcessed = (short *)buf; + uint32_t processed_len = 0; + uint32_t remain_len = 0; + + len >>= 1; + + LOCK_VOICECVSD_QUEUE(); + while(processed_len < len){ + remain_len = len-processed_len; + if (remain_len>VOICECVSD_TEMP_BUFFER_SIZE){ + Pcm8kToCvsd(pBuffProcessed + processed_len, cvsdtmpbuffer, VOICECVSD_TEMP_BUFFER_SIZE); + EnCQueue(&voicecvsd_queue, cvsdtmpbuffer, VOICECVSD_TEMP_BUFFER_SIZE); + processed_len += VOICECVSD_TEMP_BUFFER_SIZE; + }else{ + Pcm8kToCvsd(pBuffProcessed + processed_len, cvsdtmpbuffer, remain_len); + EnCQueue(&voicecvsd_queue, cvsdtmpbuffer, remain_len); + processed_len += remain_len; + } + } + UNLOCK_VOICECVSD_QUEUE(); + +#if 0 + dump_buffer_to_psram((char *)buf, len); + TRACE(1,"%d\n", LengthOfCQueue(&voicecvsd_queue)); +#endif + if (LengthOfCQueue(&voicecvsd_queue) > VOICECVSD_TEMP_BUFFER_SIZE*10) { + voicecvsd_cache_status = APP_AUDIO_CACHE_OK; + } + + return 0; +} + +int get_voicecvsd_buffer_size(void) +{ + int n; + LOCK_VOICECVSD_QUEUE(); + n = LengthOfCQueue(&voicecvsd_queue); + UNLOCK_VOICECVSD_QUEUE(); + return n; +} + +static short tmp_decode_buf[VOICECVSD_TEMP_BUFFER_SIZE*2]; +int decode_cvsd_frame(unsigned char *pcm_buffer, unsigned int pcm_len) +{ + uint32_t r = 0, decode_len = 0; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + + while (decode_len < pcm_len) { +get_again: + LOCK_VOICECVSD_QUEUE(); + len1 = len2 = 0; + r = PeekCQueue(&voicecvsd_queue, VOICECVSD_TEMP_BUFFER_SIZE, &e1, &len1, &e2, &len2); + UNLOCK_VOICECVSD_QUEUE(); + + if(r == CQ_ERR || len1 == 0) { + //return 0; + Thread::wait(4); + goto get_again; + } + + if (len1 != 0) { + //CvsdToPcm8k(e1, (short *)(pcm_buffer + decode_len*4), len1, 0); + CvsdToPcm8k(e1, (short *)(tmp_decode_buf), len1, 0); + copy_one_trace_to_two_track_16bits((uint16_t *)tmp_decode_buf, (uint16_t *)(pcm_buffer + decode_len), len1); + + LOCK_VOICECVSD_QUEUE(); + DeCQueue(&voicecvsd_queue, 0, len1); + UNLOCK_VOICECVSD_QUEUE(); + + decode_len += len1*4; + } + + if (len2 != 0) { + //CvsdToPcm8k(e2, (short *)(pcm_buffer + decode_len*4), len2, 0); + CvsdToPcm8k(e2, (short *)(tmp_decode_buf), len2, 0); + copy_one_trace_to_two_track_16bits((uint16_t *)tmp_decode_buf, (uint16_t *)(pcm_buffer + decode_len), len2); + + LOCK_VOICECVSD_QUEUE(); + DeCQueue(&voicecvsd_queue, 0, len2); + UNLOCK_VOICECVSD_QUEUE(); + + decode_len += len2*4; + } + } + + return 0; +} + +uint32_t decode_cvsd_frame_noblock(uint8_t *pcm_buffer, uint32_t pcm_len) +{ + unsigned int len[2]; + uint8_t *e[2]; + uint32_t decode_len = 0; + + LOCK_VOICECVSD_QUEUE(); + while (decode_len < pcm_len) + { + len[0] = len[1] = 0; + e[0] = e[1] = NULL; + + if(PeekCQueue(&voicecvsd_queue, VOICECVSD_TEMP_BUFFER_SIZE, &e[0], &len[0], &e[1], &len[1]) == CQ_OK) + { + for(uint8_t i=0; i<2; i++) + { + if (len[i] != 0) + { + CvsdToPcm8k(e[i], (short *)(tmp_decode_buf), len[i], 0); + + copy_one_trace_to_two_track_16bits((uint16_t *)tmp_decode_buf, (uint16_t *)(pcm_buffer + decode_len), len[i]); + + DeCQueue(&voicecvsd_queue, 0, len[i]); + + decode_len += len[i]*4; + } + } + } + else + { + break; + } + } + UNLOCK_VOICECVSD_QUEUE(); + return decode_len; +} + +uint32_t voicecvsd_audio_more_data(uint8_t *buf, uint32_t len) +{ + uint32_t l = 0; + uint32_t cur_ticks = 0, ticks = 0; + + if (voicecvsd_cache_status == APP_AUDIO_CACHE_CACHEING) + return 0; + + TRACE(2,"%s enter reamin:%d", __func__, LengthOfCQueue(&voicecvsd_queue)); + + ticks = hal_sys_timer_get(); + l = decode_cvsd_frame_noblock(buf, len); + cur_ticks = hal_sys_timer_get(); + TRACE(3,"%s exit reamin:%d spend:%d\n", __func__, LengthOfCQueue(&voicecvsd_queue) ,TICKS_TO_MS(cur_ticks-ticks)); + + return l; +} + +int voicecvsd_audio_init(void) +{ + uint8_t *buff = NULL; + + app_audio_mempool_get_buff(&buff, VOICECVSD_QUEUE_SIZE); + memset(buff, 0, VOICECVSD_QUEUE_SIZE); + + /* voicebtpcm_pcm queue*/ + APP_AUDIO_InitCQueue(&voicecvsd_queue, VOICECVSD_QUEUE_SIZE, buff); + + Pcm8k_CvsdInit(); + if (g_voicecvsd_queue_mutex_id == NULL) + { + g_voicecvsd_queue_mutex_id = osMutexCreate((osMutex(g_voicecvsd_queue_mutex))); + } + + voicecvsd_cache_status = APP_AUDIO_CACHE_CACHEING; +} +#endif diff --git a/apps/audioplayers/digmici2splay.cpp b/apps/audioplayers/digmici2splay.cpp new file mode 100644 index 0000000..b332b93 --- /dev/null +++ b/apps/audioplayers/digmici2splay.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Standard C Included Files +#include +#include +#include +#include +#include +#include "cqueue.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_trace.h" + +uint8_t digmic_buf[100*1024]; +uint32_t digmic_buf_len = 0; + +uint32_t dig_mic_audio_more_data(uint8_t *buf, uint32_t len) +{ + TRACE(2,"%s:%d\n", __func__, __LINE__); + memcpy(buf, digmic_buf, len); + + return len; +} +uint32_t dig_mic_audio_data_come(uint8_t *buf, uint32_t len) +{ + TRACE(2,"%s:%d\n", __func__, __LINE__); + + memcpy(digmic_buf + digmic_buf_len, buf, len); + +#if 1 + digmic_buf_len = (digmic_buf_len + len)%(100*1024); +#endif + return len; +} diff --git a/apps/audioplayers/flacplay.cpp b/apps/audioplayers/flacplay.cpp new file mode 100644 index 0000000..f3d1c6a --- /dev/null +++ b/apps/audioplayers/flacplay.cpp @@ -0,0 +1,138 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Standard C Included Files +#include +#include +#include +#include +#include +#include "cqueue.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_trace.h" +#ifdef RTOS +#include "cmsis_os.h" +#endif + +/* mutex */ +osMutexId g_flac_queue_mutex_id; +osMutexDef(g_flac_queue_mutex); + +/* flac queue */ +#define FLAC_TEMP_BUFFER_SIZE 2048 +#define FLAC_QUEUE_SIZE (FLAC_TEMP_BUFFER_SIZE*4) +unsigned char flac_queue_buf[FLAC_QUEUE_SIZE]; +CQueue flac_queue; +static uint32_t ok_to_decode = 0; + +#define LOCK_FLAC_QUEUE() \ + osMutexWait(g_flac_queue_mutex_id, osWaitForever) + +#define UNLOCK_FLAC_QUEUE() \ + osMutexRelease(g_flac_queue_mutex_id) + +static void copy_one_trace_to_two_track_16bits(uint16_t *src_buf, uint16_t *dst_buf, uint32_t src_len) +{ + uint32_t i = 0; + for (i = 0; i < src_len; ++i) { + dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = src_buf[i]; + } +} + +int store_flac_buffer(unsigned char *buf, unsigned int len) +{ + LOCK_FLAC_QUEUE(); + EnCQueue(&flac_queue, buf, len); + if (LengthOfCQueue(&flac_queue) > FLAC_TEMP_BUFFER_SIZE*2) { + ok_to_decode = 1; + } + UNLOCK_FLAC_QUEUE(); + + return 0; +} + +int decode_flac_frame(unsigned char *pcm_buffer, unsigned int pcm_len) +{ + uint32_t r = 0, got_len = 0; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; +get_again: + LOCK_FLAC_QUEUE(); + r = PeekCQueue(&flac_queue, (pcm_len - got_len)/2, &e1, &len1, &e2, &len2); + UNLOCK_FLAC_QUEUE(); + + if(r == CQ_ERR || len1 == 0) { + osDelay(2); + goto get_again; + } + + //memcpy(pcm_buffer + got_len, e1, len1); + copy_one_trace_to_two_track_16bits((uint16_t *)e1, (uint16_t *)(pcm_buffer + got_len), len1/2); + + LOCK_FLAC_QUEUE(); + DeCQueue(&flac_queue, 0, len1); + UNLOCK_FLAC_QUEUE(); + + got_len += len1*2; + + if (len2 != 0) { + //memcpy(pcm_buffer + got_len, e2, len2); + copy_one_trace_to_two_track_16bits((uint16_t *)e2, (uint16_t *)(pcm_buffer + got_len), len2/2); + + LOCK_FLAC_QUEUE(); + DeCQueue(&flac_queue, 0, len2); + UNLOCK_FLAC_QUEUE(); + } + + got_len += len2*2; + + if (got_len < pcm_len) + goto get_again; + + return pcm_len; +} + +uint32_t flac_audio_data_come(uint8_t *buf, uint32_t len) +{ + TRACE(1,"data come %d\n", len); + + return 0; +} + +uint32_t flac_audio_more_data(uint8_t *buf, uint32_t len) +{ + uint32_t l = 0; + //uint32_t cur_ticks = 0, ticks = 0; + + if (ok_to_decode == 0) + return 0; + + //ticks = hal_sys_timer_get(); + l = decode_flac_frame(buf, len); + //cur_ticks = hal_sys_timer_get(); +// TRACE(1,"flac %d t\n", (cur_ticks-ticks)); + + return l; +} + +int flac_audio_init(void) +{ + g_flac_queue_mutex_id = osMutexCreate((osMutex(g_flac_queue_mutex))); + /* flac queue*/ + InitCQueue(&flac_queue, FLAC_QUEUE_SIZE, (unsigned char *)&flac_queue_buf); + + return 0; +} diff --git a/apps/audioplayers/fmradio.cpp b/apps/audioplayers/fmradio.cpp new file mode 100644 index 0000000..82b6a4a --- /dev/null +++ b/apps/audioplayers/fmradio.cpp @@ -0,0 +1,529 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_BEST1000 + +#include "cmsis.h" +#include "cmsis_os.h" +#include "hal_trace.h" +#include "fmdec.h" +#include "hal_dma.h" +#include "hal_timer.h" +#include "hal_cmu.h" +#include "hal_analogif.h" +#include "hal_chipid.h" +#include "audioflinger.h" +#include "audiobuffer.h" +#include "cqueue.h" +#include "app_audio.h" +#include "app_utils.h" +#include "app_overlay.h" +#include "string.h" +#include "pmu.h" + +//#define FM_DEBUG 1 + +#define FM_DIGITAL_REG(a) *(volatile uint32_t *)(a) +#define fm_read_rf_reg(reg,val) hal_analogif_reg_read(reg,val) +#define fm_write_rf_reg(reg,val) hal_analogif_reg_write(reg,val) + +#define FM_FRAME_NUM 4 +#define FM_SAMPLE_NUM NUMOFSAMPLE + +#ifdef ATAN2_HARDWARE +#ifdef FM_NEWMODE +#define FM_SAMPLE_BUFFER_SIZE (FM_FRAME_NUM*FM_SAMPLE_NUM*4) +#else +#define FM_SAMPLE_BUFFER_SIZE (FM_FRAME_NUM*FM_SAMPLE_NUM/2*4) +#endif +#else +#define FM_SAMPLE_BUFFER_SIZE (FM_FRAME_NUM*FM_SAMPLE_NUM*4) +#endif +#define FM_AUDIO_BUFFER_SIZE (4096) + +extern int app_bt_stream_local_volume_get(void); +static int32_t *fm_sample_buffer_p; + +static void fm_handler(uint8_t chan, uint32_t remains, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + static int cnt = 0; + int16_t fm_decbuf[(FM_SAMPLE_NUM/9)]; + FmDemodulate((int16_t *)(fm_sample_buffer_p +((cnt%FM_FRAME_NUM)*FM_SAMPLE_NUM)), fm_decbuf,FM_SAMPLE_NUM); + cnt++; + app_audio_pcmbuff_put((uint8_t *)fm_decbuf, (FM_SAMPLE_NUM/9)<<1); + FmDemodulate((int16_t *)(fm_sample_buffer_p +((cnt%FM_FRAME_NUM)*FM_SAMPLE_NUM)), fm_decbuf,FM_SAMPLE_NUM); + cnt++; + app_audio_pcmbuff_put((uint8_t *)fm_decbuf, (FM_SAMPLE_NUM/9)<<1); + +#ifdef FM_DEBUG + { + static uint32_t preTicks; + uint32_t diff_ticks = 0; + uint32_t cur_ticks; + + cur_ticks = hal_sys_timer_get(); + if (!preTicks){ + preTicks = cur_ticks; + }else{ + diff_ticks = TICKS_TO_MS(cur_ticks - preTicks); + preTicks = cur_ticks; + } + TRACE(3,"[fm_handler] diff=%d add:%d remain:%d input", diff_ticks, (FM_SAMPLE_NUM/9)<<1, app_audio_pcmbuff_length()); + } +#endif +} + +uint32_t fm_pcm_more_data(uint8_t *buf, uint32_t len) +{ + app_audio_pcmbuff_get(buf, len); +#ifdef FM_DEBUG + { + static uint32_t preTicks; + uint32_t diff_ticks = 0; + uint32_t cur_ticks= hal_sys_timer_get(); + if (!preTicks){ + preTicks = cur_ticks; + }else{ + diff_ticks = TICKS_TO_MS(cur_ticks - preTicks); + preTicks = cur_ticks; + } + + TRACE(5,"[fm_pcm_more_data] diff=%d get:%d remain:%d output isr:0x%08x cnt:%d", diff_ticks, len/2, app_audio_pcmbuff_length(), FM_DIGITAL_REG(0x40160020), FM_DIGITAL_REG(0x40160028)); + } +#endif + return 0; +} + +uint32_t fm_capture_more_data(uint8_t *buf, uint32_t len) +{ + fm_handler(0,0,0,NULL); + return len; +} + +void fm_radio_digit_init(void) +{ + FM_DIGITAL_REG(0xd0350244) = (FM_DIGITAL_REG(0xd0350244) & ~0x01fff) | 0x20f; //-890k -> 0 if_shift, for 110.5292m adc + +// FM_DIGITAL_REG(0x40180e0c) = 0x34; + //FM_DIGITAL_REG(0x4000a050) = (FM_DIGITAL_REG(0x4000a050) & ~0x18000) | 0x18000; + + + + +#ifdef ATAN2_HARDWARE + + + FM_DIGITAL_REG(0xd0330038) |= (1 << 11); + FM_DIGITAL_REG(0xd0330038) |= (1 << 17); + FM_DIGITAL_REG(0xd0350248) = 0x80c00000; +// FM_DIGITAL_REG(0x40160030) = 1; + // FM_DIGITAL_REG(0x40160000) = 0x21; + + +#else + + + + FM_DIGITAL_REG(0xd0330038) |= (1 << 11); + FM_DIGITAL_REG(0xd0350248) = 0x80c00000; +// FM_DIGITAL_REG(0x40160030) = 1; +// FM_DIGITAL_REG(0x40160000) = 1; + +#endif + + + +#ifdef SINGLECHANLE + //0x4000a010 bit2 д0 µ¥channel dac + FM_DIGITAL_REG(0x4000a010) = (1 << 5) |(1<<4); +#else + + FM_DIGITAL_REG(0x4000a010) = (1 << 5) | (1 << 2)|(1<<4); +#endif + + + + FM_DIGITAL_REG(0x4000a020) = ~0UL; + FM_DIGITAL_REG(0x4000a02c) = 4; + FM_DIGITAL_REG(0x4000a030) = 4; + + FM_DIGITAL_REG(0x4000a034) = (1 << 2) | (1 << 1) | (1 << 0); + + // Start DAC + // FM_DIGITAL_REG(0x4000a010) |= (1 << 1); + +#if 0 +//52M + FM_DIGITAL_REG(0x40000060) |= (1 << 21); + + + FM_DIGITAL_REG(0x40000060) |= (1 << 24); + FM_DIGITAL_REG(0x40000060) |= (1 << 27); + FM_DIGITAL_REG(0x40000060) =(FM_DIGITAL_REG(0x40000060) & ~ (1 << 20)); + + + + + + + + + FM_DIGITAL_REG(0x40000060) |= (1 << 29); +// FM_DIGITAL_REG(0x40000060) |= (1 << 27); + FM_DIGITAL_REG(0x40000064) = (FM_DIGITAL_REG(0x40000064) & ~0xFF) | 0x7A | (1 << 10) | (1<<30); +#endif + + FM_DIGITAL_REG(0x4000a040) = 0xc0810000; + FM_DIGITAL_REG(0x4000a044) = 0x08040c04; + FM_DIGITAL_REG(0x4000a048) = 0x0e01f268; + FM_DIGITAL_REG(0x4000a04c) = 0x00005100; + // FM_DIGITAL_REG(0x40010010) = 0; + // FM_DIGITAL_REG(0x40010014) = 0x03a80005; + //FM_DIGITAL_REG(0x40010018) = 0x00200019; + FM_DIGITAL_REG(0x4000a050) = 0x24200000; //for adc_div_3_6 bypass + FM_DIGITAL_REG(0x4000a050) = (FM_DIGITAL_REG(0x4000a050) & ~0x780) | 0x380; // for channel 1 adc volume, bit10~7 + FM_DIGITAL_REG(0x4000a050) = (FM_DIGITAL_REG(0x4000a050) & ~0x18000) | 0x18000; // for dual channel adc/dac + +#ifdef SINGLECHANLE + //0x4000a050 bit16 д0 µ¥channel dac for codec + FM_DIGITAL_REG(0x4000a050) =(FM_DIGITAL_REG(0x4000a050) & ~ (1 << 16)); +#endif + + + FM_DIGITAL_REG(0x4000a048) = (FM_DIGITAL_REG(0x4000a048) & ~0x00000f00) | 0x40000900; //set for sdm gain + FM_DIGITAL_REG(0x4000a044) = (FM_DIGITAL_REG(0x4000a044) & ~0x60000000) | 0x60000000; //for adc en, and dac en + + // Start DAC + FM_DIGITAL_REG(0x4000a010) |= (1 << 1); + + + +// Delay 2 ms +// for (volatile int kk = 0; kk < 1000/64; kk++); + osDelay(2); + + //hal_sys_timer_delay(MS_TO_TICKS(2)); + // Start ADC + // FM_DIGITAL_REG(0x4000a010) |= (1 << 0); + + +#ifdef ATAN2_HARDWARE + + +#ifdef FM_NEWMODE + FM_DIGITAL_REG(0x40160030) = 1; + FM_DIGITAL_REG(0x40160000) = 0x1; + +#else + FM_DIGITAL_REG(0x40160030) = 1; + FM_DIGITAL_REG(0x40160000) = 0x21; +#endif + +#else + //start FM + FM_DIGITAL_REG(0x40160030) = 1; + FM_DIGITAL_REG(0x40160000) =1; + +#endif +} + +int fm_radio_analog_init(void) +{ + int ret; + + + /* + + // fm initial + rfspi_wvalue( 8'h2c , 16'b0111_0000_0101_1100 ) ; // dig_vtoi_en + rfspi_wvalue( 8'h01 , 16'b1010_1101_1111_1111 ) ; // power on fm lna + rfspi_wvalue( 8'h02 , 16'b1000_0000_1001_0100 ) ; // reg_fm_lna_pu_mixersw + + rfspi_wvalue( 8'h1a , 16'b0101_0000_1011_0000 ) ; // reg_bt_vco_fm_buff_vctrl_dr=1 + + rfspi_wvalue( 8'h18 , 16'b0000_0110_1000_0000 ) ; // power on vco + + rfspi_wvalue( 8'h19 , 16'b0110_0100_0100_0000 ) ; // reg_bt_vco_fm_buff_vctrl + rfspi_wvalue( 8'h1d , 16'b0111_1000_1010_0100 ) ; // reg_bt_rfpll_pu_dr + rfspi_wvalue( 8'h1c , 16'b0000_0000_1100_1000 ) ; // reg_bt_vco_fm_lo_en reg_bt_vco_fm_div_ctrl=8 + + rfspi_wvalue( 8'h0a , 16'b0001_0010_0010_1111 ) ; // reg_btfm_flt_fm_en + + rfspi_wvalue( 8'h2d , 16'b0000_0111_1000_0010 ) ; // bb ldo on reg_bb_ldo_pu_vddr15a_dr + rfspi_wvalue( 8'h07 , 16'b0000_0010_1011_1001 ) ; // reg_btfm_flt_pu_dr + + rfspi_wvalue( 8'h2a , 16'b0001_0110_1100_0000 ) ; // reg_bt_rfpll_sdm_freq_dr + rfspi_wvalue( 8'h26 , 16'b0000_0000_0000_0000 ) ; // vco freq[31:16] ( 2400 + x )*2^25/26MHZ*N (2400+x= frf) + rfspi_wvalue( 8'h25 , 16'b0000_0000_0000_0000 ) ; // vco freq[15:00] fm_freq = frf/(4*reg_bt_vco_fm_div_ctrl) + rfspi_wvalue( 8'h17 , 16'b1000_0000_0000_0000 ) ; // reg_bt_vco_calen + + */ + + + + + + + fm_write_rf_reg( 0x2c , 0b0111000001011100 ) ; // dig_vtoi_en + fm_write_rf_reg( 0x01 , 0b1010110111111111 ) ; // power on fm lna + fm_write_rf_reg( 0x02 , 0b1000000010010100 ) ; // reg_fm_lna_pu_mixersw + + fm_write_rf_reg( 0x1a , 0b0101000010110000 ) ; // reg_bt_vco_fm_buff_vctrl_dr=1 + + fm_write_rf_reg( 0x18 , 0b0000011010000000 ) ; // power on vco + + fm_write_rf_reg( 0x19 , 0b0110010001000000 ) ; // reg_bt_vco_fm_buff_vctrl + fm_write_rf_reg( 0x1d , 0b0111100010100100 ) ; // reg_bt_rfpll_pu_dr + fm_write_rf_reg( 0x1c , 0b0000000011001000 ) ; // reg_bt_vco_fm_lo_en reg_bt_vco_fm_div_ctrl=8 + + fm_write_rf_reg( 0x0a , 0b0001001000101111 ) ; // reg_btfm_flt_fm_en + + fm_write_rf_reg( 0x2d , 0b0000011110000010 ) ; // bb ldo on reg_bb_ldo_pu_vddr15a_dr + fm_write_rf_reg( 0x07 , 0b0000001010111001 ) ; // reg_btfm_flt_pu_dr + + fm_write_rf_reg( 0x2a , 0b0001011011000000 ) ; // reg_bt_rfpll_sdm_freq_dr + fm_write_rf_reg( 0x26 , 0b0000000000000000 ) ; // vco freq[31:16] ( 2400 + x )*2^25/26MHZ*N (2400+x= frf) + fm_write_rf_reg( 0x25 , 0b0000000000000000 ) ; // vco freq[15:00] fm_freq = frf/(4*reg_bt_vco_fm_div_ctrl) + fm_write_rf_reg( 0x17 , 0b1000000000000000 ) ; // reg_bt_vco_calen + + + + + + + + //adcÒ²Òª¿ªµÄ»°£¬ÐèÒªÅä cmu + //0x40000060[29] = 1 ×îºÃÏȶÁÔÙд£¬·ñÔò°Ñ±ðµÄbit³åµôÁË¡£ + + + + + //ÐèÒªÅäÖõÄspi¼Ä´æÆ÷£ºana interface: + + //0x05 = 0xFCB1 // Audio Pll + //0x06 = 0x881C + //0x31 = 0x0100 // audio_freq_en + //0x37 = 0x1000 // codec_bbpll1_fm_adc_clk_en + //0x31 = 0x0130 // codec_tx_en_ldac codec_tx_en_rdac + + + ret = fm_write_rf_reg(0x05 , 0xfcb1); + if (ret) { + return ret; + } + ret = fm_write_rf_reg(0x06 , 0x881c); + if (ret) { + return ret; + } + + ret = fm_write_rf_reg(0x3a , 0xe644); + if (ret) { + return ret; + } + ret = fm_write_rf_reg(0x31 , 0x0100); + if (ret) { + return ret; + } + ret = fm_write_rf_reg(0x37 , 0x1000); + if (ret) { + return ret; + } + ret = fm_write_rf_reg(0x31 , 0x01f0); + if (ret) { + return ret; + } + + + //delay 32ms + osDelay(32); + + + ret = fm_write_rf_reg(0x31 , 0x0130); + if (ret) { + return ret; + } + + //[FM_RX] + fm_write_rf_reg(0x01,0x91ff); //pu fm + fm_write_rf_reg(0x2d,0x07fa); //ldo on + fm_write_rf_reg(0x2e,0x6aaa); //tune fm filter IF + fm_write_rf_reg(0x02,0xe694); + fm_write_rf_reg(0x03,0xfe3a); + fm_write_rf_reg(0x04,0x52a8); + fm_write_rf_reg(0x07,0x02b9); + fm_write_rf_reg(0x0a,0x1a2c); + fm_write_rf_reg(0x0b,0x402b); + fm_write_rf_reg(0x0c,0x7584); + fm_write_rf_reg(0x0e,0x0000); + fm_write_rf_reg(0x0f,0x2e18); + fm_write_rf_reg(0x10,0x02b4); + fm_write_rf_reg(0x13,0x0a48); + + //[vco init] + fm_write_rf_reg(0x18,0x077f); + fm_write_rf_reg(0x19,0x3ff8); + fm_write_rf_reg(0x1a,0xc090); + fm_write_rf_reg(0x1b,0x0f88); + fm_write_rf_reg(0x1c,0x04c6); //[3:0] 5,6,7,8 --> vco/2 + + return 0; +} + +void fm_radio_poweron(void) + +{ + hal_cmu_reset_clear(HAL_CMU_MOD_BTCPU); + osDelay(2000); + + { + //wakp interface + unsigned short read_val; + + fm_read_rf_reg(0x50, &read_val); + } + + pmu_fm_config(1); + + fm_write_rf_reg(0x0c, 0x3584); + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2 || hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_3) //// + { + FM_DIGITAL_REG(0xc00003b4)=0x00060020;//turn off bt sleep + } + else if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_4) + { + FM_DIGITAL_REG(0xc00003b0)=0x00060020;//turn off bt sleep + } + else + { + FM_DIGITAL_REG(0xc00003ac)=0x00060020;//turn off bt sleep + } + FM_DIGITAL_REG(0xd0330038) = 0x00008D0D; + FM_DIGITAL_REG(0xd0340020)=0x010E01C0;// open ana rxon for open adc clk + //fm_write_rf_reg(0x02, 0xe694); +} + +void* fm_radio_get_ext_buff(int size) +{ + uint8_t *pBuff = NULL; + size = size+size%4; + app_audio_mempool_get_buff(&pBuff, size); + return (void*)pBuff; +} + +int fm_radio_player(bool on) +{ + static struct AF_STREAM_CONFIG_T stream_cfg; + static bool isRun = false; + uint8_t *buff = NULL; + + TRACE(2,"fm_radio_player work:%d op:%d", isRun, on); + if (isRun==on) + return 0; + + if (on){ + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_52M); + app_audio_mempool_init(); + fm_radio_poweron(); + fm_radio_analog_init(); + fm_radio_digit_init(); + osDelay(200); + buff = (uint8_t *)fm_radio_get_ext_buff(FM_AUDIO_BUFFER_SIZE*2); + app_audio_pcmbuff_init(buff, FM_AUDIO_BUFFER_SIZE*2); + fm_sample_buffer_p = (int32_t *)fm_radio_get_ext_buff(FM_SAMPLE_BUFFER_SIZE); +#if FPGA==0 + app_overlay_select(APP_OVERLAY_FM); +#endif + memset(&stream_cfg, 0, sizeof(stream_cfg)); + stream_cfg.vol = app_bt_stream_local_volume_get(); + stream_cfg.handler = fm_capture_more_data; + stream_cfg.data_ptr = (uint8_t *)fm_sample_buffer_p; + stream_cfg.data_size = FM_SAMPLE_BUFFER_SIZE; + stream_cfg.device = AUD_STREAM_USE_DPD_RX; + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + buff = (uint8_t *)fm_radio_get_ext_buff(FM_AUDIO_BUFFER_SIZE); + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = AUD_CHANNEL_NUM_1; + stream_cfg.sample_rate = AUD_SAMPRATE_48000; +#if FPGA==0 + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; +#else + stream_cfg.device = AUD_STREAM_USE_EXT_CODEC; +#endif + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.vol = app_bt_stream_local_volume_get(); + stream_cfg.handler = fm_pcm_more_data; + stream_cfg.data_ptr = buff; + stream_cfg.data_size = FM_AUDIO_BUFFER_SIZE; + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + + }else{ + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_32K); + } + + isRun=on; + return 0; +} + +int fm_tune(uint32_t freqkhz) +{ + uint32_t reg; + unsigned long long tmp = 0; + + + //[rfpll_cal] + fm_write_rf_reg(0x21,0x3979); // ref sel 52MHz + fm_write_rf_reg(0x22,0x7A22); // doubler setting + fm_write_rf_reg(0x23,0x0380); + fm_write_rf_reg(0x2b,0x32a0); // sdm + fm_write_rf_reg(0x2a,0x12d1); // cal ini + + //(freq(Mhz)-0.89(Mhz))*(2^28)*3/26 + tmp = freqkhz; + reg =(((tmp-890))<<27)*3/13/1000; + + fm_write_rf_reg(0x25, (reg&0xffff0000)>>16); + fm_write_rf_reg(0x26, reg&0x0000ffff); + + fm_write_rf_reg(0x1d,0x58e4); // pll_cal_en + fm_write_rf_reg(0xf7,0x5597); // rst and enable pll_cal clk + fm_write_rf_reg(0xf7,0x55d7); // rst and enable pll_cal clk + fm_write_rf_reg(0x1d,0x7ae4); // pll cal start + fm_write_rf_reg(0xff,0x0000); // wait 100us + + osDelay(20); + + + fm_write_rf_reg(0x1d,0x7ac4); // close pll loop + + return 0; +} + +void fm_test_main(void) +{ + fm_radio_player(true); + osDelay(20); + fm_tune(90500); +} + +#endif + diff --git a/apps/audioplayers/fmradio.h b/apps/audioplayers/fmradio.h new file mode 100644 index 0000000..32a723e --- /dev/null +++ b/apps/audioplayers/fmradio.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_AUDIO_H__ +#define __FMRADIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int fm_radio_player(bool on); + +void fm_tune(uint32_t freqkhz); + + +#ifdef __cplusplus +} +#endif + +#endif//__FMRADIO_H__ diff --git a/apps/audioplayers/msbcplay.cpp b/apps/audioplayers/msbcplay.cpp new file mode 100644 index 0000000..13cd2cc --- /dev/null +++ b/apps/audioplayers/msbcplay.cpp @@ -0,0 +1,152 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Standard C Included Files +#include +#include +#include +#include +#include +#include "cmsis_os.h" +#include "cqueue.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_trace.h" + +// BT + + +#if 0 +/* mutex */ +osMutexId g_voicemsbc_queue_mutex_id; +osMutexDef(g_voicemsbc_queue_mutex); + +/* msbc queue */ +#define VOICEMSBC_TEMP_BUFFER_SIZE 128 +#define VOICEMSBC_QUEUE_SIZE (VOICEMSBC_TEMP_BUFFER_SIZE*100) +unsigned char voicemsbc_queue_buf[VOICEMSBC_QUEUE_SIZE]; +CQueue voicemsbc_queue; +static uint32_t ok_to_decode = 0; + +#define LOCK_VOICEMSBC_QUEUE() \ + osMutexWait(g_voicemsbc_queue_mutex_id, osWaitForever) + +#define UNLOCK_VOICEMSBC_QUEUE() \ + osMutexRelease(g_voicemsbc_queue_mutex_id) + +static void dump_buffer_to_psram(char *buf, unsigned int len) +{ + static unsigned int offset = 0; + memcpy((void *)(0x1c000000 + offset), buf, len); +} + +static void copy_one_trace_to_two_track_16bits(uint16_t *src_buf, uint16_t *dst_buf, uint32_t src_len) +{ + uint32_t i = 0; + for (i = 0; i < src_len; ++i) { + dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = src_buf[i]; + } +} + +int store_voicemsbc_buffer(unsigned char *buf, unsigned int len) +{ + LOCK_VOICEMSBC_QUEUE(); + EnCQueue(&voicemsbc_queue, buf, len); + dump_buffer_to_psram((char *)buf, len); + TRACE(1,"%d\n", LengthOfCQueue(&voicemsbc_queue)); + if (LengthOfCQueue(&voicemsbc_queue) > VOICEMSBC_TEMP_BUFFER_SIZE*20) { + ok_to_decode = 1; + } + UNLOCK_VOICEMSBC_QUEUE(); + + return 0; +} + +static short tmp_decode_buf[VOICEMSBC_TEMP_BUFFER_SIZE*2]; +int decode_msbc_frame(unsigned char *pcm_buffer, unsigned int pcm_len) +{ + int r = 0; + uint32_t decode_len = 0; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + + while (decode_len < pcm_len) { +get_again: + LOCK_VOICEMSBC_QUEUE(); + len1 = len2 = 0; + r = PeekCQueue(&voicemsbc_queue, VOICEMSBC_TEMP_BUFFER_SIZE, &e1, &len1, &e2, &len2); + UNLOCK_VOICEMSBC_QUEUE(); + + if(r == CQ_ERR || len1 == 0) { + //return 0; + Thread::wait(4); + goto get_again; + } + + if (len1 != 0) { + //msbcToPcm8k(e1, (short *)(pcm_buffer + decode_len*4), len1, 0); + CvsdToPcm8k(e1, (short *)(tmp_decode_buf), len1, 0); + copy_one_trace_to_two_track_16bits((uint16_t *)tmp_decode_buf, (uint16_t *)(pcm_buffer + decode_len), len1); + + LOCK_VOICEMSBC_QUEUE(); + DeCQueue(&voicemsbc_queue, 0, len1); + UNLOCK_VOICEMSBC_QUEUE(); + + decode_len += len1*4; + } + + if (len2 != 0) { + //msbcToPcm8k(e2, (short *)(pcm_buffer + decode_len*4), len2, 0); + CvsdToPcm8k(e2, (short *)(tmp_decode_buf), len2, 0); + copy_one_trace_to_two_track_16bits((uint16_t *)tmp_decode_buf, (uint16_t *)(pcm_buffer + decode_len), len2); + + LOCK_VOICEMSBC_QUEUE(); + DeCQueue(&voicemsbc_queue, 0, len2); + UNLOCK_VOICEMSBC_QUEUE(); + + decode_len += len2*4; + } + } + + return 0; +} + +uint32_t voicemsbc_audio_more_data(uint8_t *buf, uint32_t len) +{ + uint32_t l = 0; + uint32_t cur_ticks = 0, ticks = 0; + + if (ok_to_decode == 0) + return 0; + + ticks = hal_sys_timer_get(); + l = decode_msbc_frame(buf, len); + cur_ticks = hal_sys_timer_get(); + TRACE(1,"msbc %d t\n", (cur_ticks-ticks)); + + return l; +} + +int voicemsbc_audio_init(void) +{ + Pcm8k_CvsdInit(); + + g_voicemsbc_queue_mutex_id = osMutexCreate((osMutex(g_voicemsbc_queue_mutex))); + /* msbc queue*/ + InitCQueue(&voicemsbc_queue, VOICEMSBC_QUEUE_SIZE, (unsigned char *)&voicemsbc_queue_buf); + + return 0; +} +#endif diff --git a/apps/audioplayers/plc_utils.c b/apps/audioplayers/plc_utils.c new file mode 100644 index 0000000..a475edd --- /dev/null +++ b/apps/audioplayers/plc_utils.c @@ -0,0 +1,328 @@ +#include +#include +#include "plc_utils.h" +#include "hal_trace.h" + +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) +#define MSBC_MUTE_PATTERN (0x55) +#else +#define MSBC_MUTE_PATTERN (0x00) +#endif + +#define MSBC_PKTSIZE (60) + +/* + * msbc frame's last byte is a padding byte, we assume it is zero, + * but it is not always true. + * Do not check this by default + */ +//#define ENABLE_PAD_CHECK + +/* + * if msbc frame is filled by 10+ samples in the trail, crc maybe not detect this + * satuation. + * Do not check this by default + */ +//#define ENABLE_TRAILING_ZERO_CHECK + +/* + * + */ +#define ENABLE_BLE_CONFLICT_CHECK + +#define ENABLE_CRC_CHECK + +/* check msbc sequence number */ +#define ENABLE_SEQ_CHECK + +#ifdef ENABLE_CRC_CHECK +static const uint8_t sbc_crc_tbl[256] = { + 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, + 0x9C, 0x81, 0xA6, 0xBB, 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, + 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, 0x87, 0x9A, 0xBD, 0xA0, + 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, + 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, + 0xD6, 0xCB, 0xEC, 0xF1, 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, + 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, 0xDE, 0xC3, 0xE4, 0xF9, + 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, + 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, + 0x08, 0x15, 0x32, 0x2F, 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, + 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, 0x26, 0x3B, 0x1C, 0x01, + 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, + 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, + 0x77, 0x6A, 0x4D, 0x50, 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, + 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A, 0x6C, 0x71, 0x56, 0x4B, + 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, + 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, + 0xA9, 0xB4, 0x93, 0x8E, 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, + 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 0xB2, 0xAF, 0x88, 0x95, + 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, + 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, + 0xE3, 0xFE, 0xD9, 0xC4 +}; +#endif + +static int sco_parse_synchronization_header(uint8_t *buf, uint8_t *sn) +{ + uint8_t sn1, sn2; +#ifdef ENABLE_CRC_CHECK + uint8_t fcs = 0x0F; + uint8_t crc = 0; + uint8_t i, sb, bit, shift; + uint8_t ind = 6, bitOffset = 24; +#endif + *sn = 0xff; +#if defined(MSBC_SYNC_HACKER) + if (((buf[0] != 0x01) && (buf[0] != 0x00)) || + ((buf[1] & 0x0f) != 0x08) || + (buf[2] != 0xad)) { + return -1; + } +#else + if ((buf[0] != 0x01) || + ((buf[1] & 0x0f) != 0x08) || + (buf[2] != 0xad)) { + return -1; + } +#endif + + sn1 = (buf[1] & 0x30) >> 4; + sn2 = (buf[1] & 0xc0) >> 6; + if ((sn1 != 0) && (sn1 != 0x3)) { + return -2; + } + if ((sn2 != 0) && (sn2 != 0x3)) { + return -3; + } + +#ifdef ENABLE_CRC_CHECK + fcs = sbc_crc_tbl[fcs ^ buf[3]]; + if (buf[3] != 0x00) + return -4; + fcs = sbc_crc_tbl[fcs ^ buf[4]]; + if (buf[4] != 0x00) + return -4; + crc = buf[5]; + for (sb = 0; sb < 8; sb++) { + if (bitOffset % 8) { + /* Sum the whole byte */ + fcs = sbc_crc_tbl[fcs ^ buf[ind]]; + ind = ind + 1; + } + else { + if (sb == 7) { + /* Sum the next 4 bits */ + + /* Just sum the most significant 4 bits */ + shift = 7; + for (i = 0; i < 4; i++) { + bit = (uint8_t)((0x01 & (buf[ind] >> shift--)) ^ (fcs >> 7)); + if (bit) { + fcs = (uint8_t)(((fcs << 1) | bit) ^ 0x1C); + } + else { + fcs = (uint8_t)((fcs << 1)); + } + } + } + } + + bitOffset += 4; + } + //TRACE(2,"msbc crc:%d fcs:%d", crc,fcs); + if (crc != fcs) + return -4; +#endif + + *sn = (sn1 & 0x01) | (sn2 & 0x02); + +#ifdef ENABLE_PAD_CHECK + // when pad error detected, we should return sn + if (buf[MSBC_PKTSIZE - 1] != 0x0) { + return -5; + } +#endif + + return 0; +} + +#ifdef ENABLE_BLE_CONFLICT_CHECK +static bool memcmp_U8(uint8_t *x, uint8_t *y, uint16_t size) +{ + for (int i = 0; i < size; i++) { + if (x[i] != y[i]) + return true; + } + + return false; +} + +// when signal is mute, msbc data remains the same except seq num. We should check history flag, +// otherwise a single conflict may be detected twice +static bool update_ble_sco_conflict(PacketLossState* st, uint8_t *last_pkt, uint8_t *pkt) +{ + // do not check padding byte as it maybe useless when msbc_offset is 1 + bool ret = (st->prev_ble_sco_conflict_flag[1] == false && memcmp_U8(last_pkt, pkt, MSBC_PKTSIZE - 1) == false); + + memcpy(&last_pkt[0], &last_pkt[MSBC_PKTSIZE], MSBC_PKTSIZE); + memcpy(&last_pkt[MSBC_PKTSIZE], pkt, MSBC_PKTSIZE); + + return ret; +} + +static bool check_ble_sco_conflict(PacketLossState* st, bool ret) +{ + st->prev_ble_sco_conflict_flag[1] = st->prev_ble_sco_conflict_flag[0]; + st->prev_ble_sco_conflict_flag[0] = ret; + + return ret; +} +#endif + +static bool msbc_check_controller_mute_pattern(uint8_t *pkt, uint8_t pattern) +{ + // do not check padding byte as it maybe useless when msbc_offset is 1 + for (int i = 0; i < MSBC_PKTSIZE - 1; i++) + if (pkt[i] != pattern) + return false; + + return true; +} + +#ifdef ENABLE_TRAILING_ZERO_CHECK +static int msbc_check_pkt_trailing_zeros(uint8_t *pkt) +{ + int idx = MSBC_PKTSIZE; + + for (int i = MSBC_PKTSIZE - 1; i >= 0; i--) { + if (pkt[i] != 0) { + idx = i; + break; + } + } + + return (MSBC_PKTSIZE - 1 - idx); +} +#endif + +static uint8_t get_next_sequence_num(uint8_t seq_num) +{ + return (seq_num + 1 == 4) ? 0 : (seq_num + 1); +} + +void packet_loss_detection_init(PacketLossState *st) +{ + st->last_seq_num = 0xff; + + memset(st->last_pkt, 0, sizeof(st->last_pkt)); + memset(st->prev_ble_sco_conflict_flag, 0, sizeof(st->prev_ble_sco_conflict_flag)); + memset(st->hist, 0, sizeof(st->hist)); +} + +plc_type_t packet_loss_detection_process(PacketLossState *st, uint8_t *sbc_buf) +{ + plc_type_t plc_type = PLC_TYPE_PASS; + +#ifdef ENABLE_BLE_CONFLICT_CHECK + bool ble_sco_conflict = update_ble_sco_conflict(st, st->last_pkt, sbc_buf); +#endif + + uint8_t seq_num; + if (msbc_check_controller_mute_pattern(sbc_buf, MSBC_MUTE_PATTERN) == true) { + plc_type = PLC_TYPE_CONTROLLER_MUTE; + st->last_seq_num = 0xff; + } +#ifdef ENABLE_BLE_CONFLICT_CHECK + else if (check_ble_sco_conflict(st, ble_sco_conflict) == true) { + plc_type = PLC_TYPE_BLE_CONFLICT; + st->last_seq_num = 0xff; + } +#endif + else { + int err = sco_parse_synchronization_header(sbc_buf, &seq_num); + if (err < 0 && err >= -3) { + plc_type = PLC_TYPE_HEADER_ERROR; + st->last_seq_num = 0xff; + } +#ifdef ENABLE_CRC_CHECK + else if (err == -4) { + plc_type = PLC_TYPE_CRC_ERROR; + st->last_seq_num = 0xff; + } +#endif +#ifdef ENABLE_PAD_CHECK + else if (err == -5) { + plc_type = PLC_TYPE_PAD_ERROR; + st->last_seq_num = seq_num; + } +#endif +#ifdef ENABLE_TRAILING_ZERO_CHECK + else if (msbc_check_pkt_trailing_zeros(sbc_buf) > 10) { + plc_type = PLC_TYPE_DATA_MISSING; + st->last_seq_num = 0xff; + } +#endif + else { +#ifdef ENABLE_SEQ_CHECK + if (st->last_seq_num == 0xff) { + if (seq_num == 0xff) { + plc_type = PLC_TYPE_SEQUENCE_DISCONTINUE; + } + else { + plc_type = PLC_TYPE_PASS; + } + st->last_seq_num = seq_num; + } + else { + if (seq_num == 0xff) { + st->last_seq_num = 0xff; + plc_type = PLC_TYPE_SEQUENCE_DISCONTINUE; + } + else if (seq_num == get_next_sequence_num(st->last_seq_num)) { + st->last_seq_num = seq_num; + plc_type = PLC_TYPE_PASS; + } + else { + st->last_seq_num = 0xff; + plc_type = PLC_TYPE_SEQUENCE_DISCONTINUE; + } + } +#else + plc_type = PLC_TYPE_PASS; +#endif + } + } + + packet_loss_detection_update_histogram(st, plc_type); + + return plc_type; +} + +void packet_loss_detection_update_histogram(PacketLossState *st, plc_type_t plc_type) +{ + if (plc_type < 0 || plc_type >= PLC_TYPE_NUM) { + TRACE(2,"[%s] plc type %d is invalid", __FUNCTION__, plc_type); + return; + } + + // The packet is detected as PLC_TYPE_PASS, but causes a decoder error. + if (plc_type == PLC_TYPE_DECODER_ERROR) { + st->hist[0] -= 1; + } + + st->hist[plc_type] += 1; +} + +void packet_loss_detection_report(PacketLossState *st) +{ + uint32_t packet_loss_num = 0; + + for (uint8_t i = 1; i < PLC_TYPE_NUM; i++) { + TRACE(3,"[%s] plc type %d occurs %d times", __FUNCTION__, i, st->hist[i]); + packet_loss_num += st->hist[i]; + } + + uint32_t packet_total_num = st->hist[0] + packet_loss_num; + TRACE(4,"[%s] packet loss percent %d/10000(%d/%d)", __FUNCTION__, + (int32_t)(10000.f * packet_loss_num/ packet_total_num), packet_loss_num, packet_total_num); +} \ No newline at end of file diff --git a/apps/audioplayers/plc_utils.h b/apps/audioplayers/plc_utils.h new file mode 100644 index 0000000..a219dc9 --- /dev/null +++ b/apps/audioplayers/plc_utils.h @@ -0,0 +1,54 @@ +#ifndef PLC_UTILS_H +#define PLC_UTILS_H + +#include +#include + +typedef enum plc_type +{ + PLC_TYPE_PASS = 0, + PLC_TYPE_CONTROLLER_MUTE, + PLC_TYPE_HEADER_ERROR, + PLC_TYPE_CRC_ERROR, + PLC_TYPE_PAD_ERROR, + PLC_TYPE_DATA_MISSING, + PLC_TYPE_SEQUENCE_DISCONTINUE, + PLC_TYPE_BLE_CONFLICT, + PLC_TYPE_DECODER_ERROR, + PLC_TYPE_NUM, +} plc_type_t; + +typedef struct +{ + uint8_t last_seq_num; + uint8_t last_pkt[60 * 2]; + + // for ble sco conflict + bool prev_ble_sco_conflict_flag[2]; + + // histogram + uint32_t hist[PLC_TYPE_NUM]; +} PacketLossState; + +#ifdef __cplusplus +extern "C" { +#endif + +void packet_loss_detection_init(PacketLossState *st); + +plc_type_t packet_loss_detection_process(PacketLossState *st, uint8_t *sbc_buf); + +/* + * Update plc type histogram + * Normally this function is called at the end of packet_loss_detection_process, + * but if a decoder error occurs outside, it should be updated maually. + */ +void packet_loss_detection_update_histogram(PacketLossState *st, plc_type_t plc_type); + +void packet_loss_detection_report(PacketLossState *st); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/apps/audioplayers/rbplay/rb_ctl.cpp b/apps/audioplayers/rbplay/rb_ctl.cpp new file mode 100644 index 0000000..4120dec --- /dev/null +++ b/apps/audioplayers/rbplay/rb_ctl.cpp @@ -0,0 +1,887 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/* rbplay source */ +/* playback control & rockbox codec porting & codec thread */ + +#ifdef MBED +#include "mbed.h" +#include "rtos.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "SDFileSystem.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "audioflinger.h" +#include "cqueue.h" +#include "app_audio.h" + +#include "eq.h" +#include "pga.h" +#include "metadata.h" +#include "dsp_core.h" +#include "codecs.h" +#include "codeclib.h" +#include "compressor.h" +#include "channel_mode.h" +#include "audiohw.h" +#include "codec_platform.h" +#include "metadata_parsers.h" + +#include "hal_overlay.h" +#include "app_overlay.h" +#include "rbpcmbuf.h" +#include "rbplay.h" +#include "app_thread.h" +#include "app_utils.h" +#include "app_key.h" + +#include "rbplaysd.h" +#include "rb_ctl.h" + +/* Internals */ + +void rb_ctl_wait_lock_thread(bool lock); +void app_rbcodec_ctl_set_play_status(bool st); +extern bool app_rbcodec_check_hfp_active(void ); + +#include "SDFileSystem.h" + +extern "C" void hal_sysfreq_print(void); + +#define _LOG_TAG "[rb_ctl] " +#undef __attribute__(a) + +#define RBPLAY_DEBUG 1 +#if RBPLAY_DEBUG +#define _LOG_DBG(str,...) TRACE(0,_LOG_TAG""str, ##__VA_ARGS__) +#define _LOG_ERR(str,...) TRACE(0,_LOG_TAG"err:"""str, ##__VA_ARGS__) +#else +#define _LOG_DBG(str,...) +#define _LOG_ERR(str,...) TRACE(0,_LOG_TAG"err:"""str, ##__VA_ARGS__) +#endif + +#include "rb_ctl.h" +void rb_thread_send_resume(void); + +typedef struct { + uint32_t evt; + uint32_t arg; +} RBCTL_MSG_BLOCK; + +static osThreadId rb_ctl_tid; +static void rb_ctl_thread(void const *argument); +static int rb_ctl_default_priority; +osThreadDef(rb_ctl_thread, osPriorityHigh, 1, 1024 * 4, "rb_ctl"); + +#define RBCTL_MAILBOX_MAX (20) +osMailQDef (rb_ctl_mailbox, RBCTL_MAILBOX_MAX, RBCTL_MSG_BLOCK); +static osMailQId rb_ctl_mailbox = NULL; + +int rb_ctl_mailbox_put(RBCTL_MSG_BLOCK* msg_src); + +//playlist +extern playlist_struct sd_playlist; + + +rb_ctl_struct rb_ctl_context; + +extern void rb_thread_set_decode_vars(int fd, int type ,void* id3); +extern void rb_play_codec_run(void); +extern void rb_codec_set_halt(int halt); +extern void rb_player_sync_set_wait_thread(osThreadId tid); +extern void rb_player_sync_wait_close(void ); +extern bool rb_pcmbuf_suspend_play_loop(void); +void app_rbplay_load_playlist(playlist_struct *list ); +int rb_thread_post_msg(RB_MODULE_EVT evt,uint32_t arg ); + +static rb_ctl_status rb_ctl_get_status(void) +{ + return rb_ctl_context.status; +} + +bool rb_ctl_parse_file(const char* file_path) +{ + /* open file */ + + _LOG_DBG(1,"open file %s\n", file_path); + rb_ctl_context.file_handle = open((const char *)file_path, O_RDWR); + if (rb_ctl_context.file_handle <= 0) { + _LOG_DBG(1,"open file %s failed\n", file_path); + return false; + } + + if (!get_metadata(&rb_ctl_context.song_id3, rb_ctl_context.file_handle, rb_ctl_context.rb_fname)) { + _LOG_DBG(0,"get_metadata failed\n"); + close(rb_ctl_context.file_handle); + return false; + } + + _LOG_DBG(4,"%s bitr:%d,saps %d, freq:%d\n",__func__,rb_ctl_context.song_id3.bitrate,rb_ctl_context.song_id3.samples,rb_ctl_context.song_id3.frequency); + + rb_thread_set_decode_vars(rb_ctl_context.file_handle, rb_ctl_context.song_id3.codectype,&rb_ctl_context.song_id3); + + return true; +} + +void rb_ctl_vol_operation(bool inc ) +{ + uint32_t ret; + struct AF_STREAM_CONFIG_T *stream_cfg = NULL; + + _LOG_DBG(2,"%s inc:%d , ",__func__,inc); + + if(inc ) { + if(rb_ctl_context.rb_player_vol < 16 ) { + rb_ctl_context.rb_player_vol++; + + } + } else { + if(rb_ctl_context.rb_player_vol > 1 ) { + rb_ctl_context.rb_player_vol--; + } + } + if(rb_ctl_context.status != RB_CTL_PLAYING) + return ; + + ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg, true); + if (ret == 0) { + stream_cfg->vol = rb_ctl_context.rb_player_vol; + af_stream_setup(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, stream_cfg); + } +} + +bool rb_ctl_is_playing(void) +{ + return (rb_ctl_context.status == RB_CTL_PLAYING); +} + +void rb_ctl_set_vol(uint32_t vol) +{ + uint32_t ret; + struct AF_STREAM_CONFIG_T *stream_cfg = NULL; + + _LOG_DBG(2,"%s set vol as :%d , ",__func__,vol); + + if(rb_ctl_context.status != RB_CTL_PLAYING) + return ; + + vol = (vol > 16)?16:vol; + rb_ctl_context.rb_player_vol = vol; + + ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg, true); + if (ret == 0) { + stream_cfg->vol = rb_ctl_context.rb_player_vol; + af_stream_setup(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, stream_cfg); + } +} + +void rb_ctl_stop_play(void ) +{ + _LOG_DBG(1,"%s \n",__func__); + + rb_codec_set_halt(1); +//close file + _LOG_DBG(0," af stream stop \n"); + af_stream_stop(AUD_STREAM_ID_0,AUD_STREAM_PLAYBACK); + _LOG_DBG(0," af stream close \n"); + af_stream_close(AUD_STREAM_ID_0,AUD_STREAM_PLAYBACK); + _LOG_DBG(0," close file \n"); + if(rb_ctl_context.file_handle != -1) + close(rb_ctl_context.file_handle ); + rb_ctl_context.file_handle = -1; +//release frequency + _LOG_DBG(0," release freq \n"); + + return ; +} + +void rb_ctl_sync_stop_play(void ) +{ + rb_player_sync_set_wait_thread(osThreadGetId()); + + rb_ctl_stop_play(); + + rb_player_sync_wait_close(); + //close file + _LOG_DBG(0," close file \n"); + if(rb_ctl_context.file_handle != -1) + close(rb_ctl_context.file_handle ); + rb_ctl_context.file_handle = -1; +} + +void rb_ctl_pause_playing(void ) +{ + af_stream_stop(AUD_STREAM_ID_0,AUD_STREAM_PLAYBACK); + _LOG_DBG(0," af stream close \n"); + af_stream_close(AUD_STREAM_ID_0,AUD_STREAM_PLAYBACK); +//wait decoder suspend + //osDelay(200); + // while(!rb_pcmbuf_suspend_play_loop()) { + //osThreadYield(); + // osDelay(1); + // } + + _LOG_DBG(1,"%s sucessed ",__func__); +} + +void rb_ctl_resume_playing(void ) +{ +#ifndef __TWS__ + rb_pcmbuf_init(); +#endif +} + + +void rb_ctl_set_priority(int priority) +{ + osThreadSetPriority(rb_ctl_tid, (osPriority)priority); +} + +int rb_ctl_get_priority(void) +{ + return (int)osThreadGetPriority(rb_ctl_tid); +} + +int rb_ctl_get_default_priority(void) +{ + return rb_ctl_default_priority; +} + +void rb_ctl_reset_priority(void) +{ + osThreadSetPriority(rb_ctl_tid, (osPriority)rb_ctl_default_priority); +} + +#ifdef __IAG_BLE_INCLUDE__ +extern "C" void app_ble_inform_music_switch(uint16_t index); +#endif +static int rb_ctl_handle_event(RBCTL_MSG_BLOCK *msg_body) +{ + RB_MODULE_EVT evt =(RB_MODULE_EVT) msg_body->evt; + uint32_t arg = msg_body->arg; +// hal_sysfreq_print(); + + + switch(evt) { + case RB_MODULE_EVT_PLAY: + if(rb_ctl_context.status != RB_CTL_IDLE) { + if(rb_ctl_context.status == RB_CTL_SUSPEND) + rb_thread_send_resume(); + else + _LOG_DBG(2,"%s st %d not in idle \n",__func__,rb_ctl_context.status); + break; + } + _LOG_DBG(3," %s start %d/%d ",__func__, rb_ctl_context.curr_song_idx ,sd_playlist.total_songs); + if(sd_playlist.total_songs > 0 ) { + playlist_item *it; + + it = app_rbplay_get_playitem(rb_ctl_context.curr_song_idx) ; + + if(it == NULL) { + _LOG_DBG(2," %s get item fail idx %d",__func__,rb_ctl_context.curr_song_idx); + } + + _LOG_DBG(2,"%s start songidx %d \n",__func__,rb_ctl_context.curr_song_idx); + + memcpy(rb_ctl_context.rb_audio_file,it->file_path,sizeof(uint16_t)*FILE_PATH_LEN - 4); + memcpy(rb_ctl_context.rb_fname,it->file_name,sizeof(rb_ctl_context.rb_fname)); + + if(rb_ctl_parse_file((const char*)rb_ctl_context.rb_audio_file)) { + _LOG_DBG(2,"%s start init, the tid 0x%x\n",__func__,osThreadGetId()); + rb_play_codec_init(); + _LOG_DBG(1,"%s start run\n",__func__); + rb_play_codec_run(); + rb_ctl_context.status = RB_CTL_PLAYING; + app_rbcodec_ctl_set_play_status(true); + break; + } else { + _LOG_DBG(2,"%s evt %d parse fail,find next\n",__func__,msg_body->evt); + rb_thread_post_msg(RB_MODULE_EVT_PLAY_NEXT,true); + } + + } else { + _LOG_DBG(2,"%s evt %d no songs\n",__func__,msg_body->evt); + } + break; + case RB_MODULE_EVT_STOP: + if(rb_ctl_context.status == RB_CTL_IDLE) { + _LOG_DBG(2,"%s st %d in idle \n",__func__,rb_ctl_context.status); + break; + } + if(rb_ctl_context.status == RB_CTL_SUSPEND) { + //osDelay(100); + rb_ctl_resume_playing(); + rb_ctl_context.status = RB_CTL_PLAYING; + } + rb_ctl_sync_stop_play(); + rb_ctl_context.status = RB_CTL_IDLE; + app_rbcodec_ctl_set_play_status(false); + break; + case RB_MODULE_EVT_SUSPEND: + if (rb_ctl_context.status != RB_CTL_PLAYING) { + _LOG_DBG(2,"%s st %d not running \n",__func__,rb_ctl_context.status); + break; + } + rb_ctl_pause_playing(); + rb_ctl_context.status = RB_CTL_SUSPEND; + break; + case RB_MODULE_EVT_RESUME: + if (rb_ctl_context.status != RB_CTL_SUSPEND) { + _LOG_DBG(2,"%s st %d not suspend \n",__func__,rb_ctl_context.status); + break; + } + rb_ctl_resume_playing(); + rb_ctl_context.status = RB_CTL_PLAYING; + break; + case RB_MODULE_EVT_PLAY_NEXT: + if( rb_ctl_context.status == RB_CTL_PLAYING) { + rb_thread_post_msg(RB_MODULE_EVT_STOP,0 ); + } else if( rb_ctl_context.status == RB_CTL_SUSPEND) { + rb_thread_post_msg(RB_MODULE_EVT_STOP,0 ); + } else { + + } + if(arg == 0) { + rb_ctl_context.curr_song_idx--; + + if(rb_ctl_context.curr_song_idx == 0xffff) + rb_ctl_context.curr_song_idx = sd_playlist.total_songs -1; + + } else { + + rb_ctl_context.curr_song_idx++; + + if(rb_ctl_context.curr_song_idx >= sd_playlist.total_songs) + rb_ctl_context.curr_song_idx = 0; + } + + #ifdef __IAG_BLE_INCLUDE__ + app_ble_inform_music_switch(rb_ctl_context.curr_song_idx); + #endif + + rb_thread_post_msg(RB_MODULE_EVT_PLAY,0 ); + break; + case RB_MODULE_EVT_CHANGE_VOL: + rb_ctl_vol_operation(arg); + break; + case RB_MODULE_EVT_SET_VOL: + rb_ctl_set_vol(arg); + break; + case RB_MODULE_EVT_CHANGE_IDLE: + rb_ctl_stop_play(); + rb_ctl_context.status = RB_CTL_IDLE; + break; + case RB_MODULE_EVT_PLAY_IDX: + if(arg > sd_playlist.total_songs -1 ) { + break; + } + if( rb_ctl_context.status == RB_CTL_PLAYING) { + rb_thread_post_msg(RB_MODULE_EVT_STOP,0 ); + } else if( rb_ctl_context.status == RB_CTL_SUSPEND) { + rb_thread_post_msg(RB_MODULE_EVT_STOP,0 ); + } else { + + } + + rb_ctl_context.curr_song_idx = (uint16_t)arg; + + rb_thread_post_msg(RB_MODULE_EVT_PLAY,0 ); + break; +//for voice cocah +#if 0 + case SBCREADER_ACTION_INIT: + //prepare fs + voiceCocah_prepare_fs(); + //init the data buff + voiceCocah_read_sbc_data(); + break; + case SBCREADER_ACTION_RUN: + //fill sbc queue + voiceCocah_read_sbc_data(); + break; + case SBCREADER_ACTION_STOP: + //release the res + voiceCocah_stop_clean(); + rb_ctl_reset_priority(); + break; +#endif + +#ifdef __TWS__ + case RB_MODULE_EVT_RESTORE_DUAL_PLAY: + extern void rb_restore_dual_play(uint8_t stream_type); + rb_restore_dual_play(arg); + break; +#endif + case RB_MODULE_EVT_DEL_FILE: + static rb_ctl_status prev_status = rb_ctl_context.status; + if( rb_ctl_context.status == RB_CTL_PLAYING) { + rb_thread_post_msg(RB_MODULE_EVT_STOP,0 ); + rb_thread_post_msg(RB_MODULE_EVT_DEL_FILE,arg); + } else if( rb_ctl_context.status == RB_CTL_SUSPEND) { + rb_thread_post_msg(RB_MODULE_EVT_STOP,0 ); + rb_thread_post_msg(RB_MODULE_EVT_DEL_FILE,arg); + } else { + app_ctl_remove_file(arg); + if(prev_status == RB_CTL_PLAYING) { + rb_thread_post_msg(RB_MODULE_EVT_PLAY,0 ); + } + } + + break; +#if defined(TWS_LINEIN_PLAYER) + case RB_MODULE_EVT_LINEIN_START: + extern int app_linein_codec_start(void); + app_linein_codec_start(); + break; + + case RB_MODULE_EVT_RECONFIG_STREAM: + extern void rb_tws_reconfig_stream(uint32_t arg); + rb_tws_reconfig_stream(arg); + break; + + case RB_MODULE_EVT_SET_TWS_MODE: + break; +#endif +#ifdef SBC_RECORD_TEST + + case SBC_RECORD_ACTION_START: + { + rb_ctl_context.sbc_record_on = true; + app_rbplay_set_store_flag(true); + app_rbplay_open_sbc_file(); + + } + break; + + case SBC_RECORD_ACTION_DATA_IND: + { + if(rb_ctl_context.sbc_record_on) { + app_rbplay_process_sbc_data(); + } + } + break; + + case SBC_RECORD_ACTION_STOP: + { + rb_ctl_context.sbc_record_on = false; + app_rbplay_set_store_flag(false); + app_rbplay_close_sbc_file(); + } + break; +#endif + default: + break; + } + if(SBC_RECORD_ACTION_DATA_IND !=msg_body->evt) + _LOG_DBG(3,"%s rbcodec evt %d ,st %d ended\n",__func__,msg_body->evt,rb_ctl_context.status); + return 0; +} + +int rb_thread_post_msg(RB_MODULE_EVT evt,uint32_t arg ) +{ + int ret; + RBCTL_MSG_BLOCK msg; + + if(!rb_ctl_tid) + return 0; + /* APIs */ + msg.evt = (uint32_t)evt; + msg.arg = (uint32_t)arg; + ret = rb_ctl_mailbox_put(&msg); + + _LOG_DBG(3,"%s ret %d evt:%d\n",__func__,ret ,evt); + return 0; +} + +void app_wait_player_stoped(void ) +{ + while(rb_ctl_context.status != RB_CTL_IDLE) + osThreadYield(); +} + +void app_wait_player_suspend(void ) +{ + if(rb_ctl_context.status == RB_CTL_IDLE) + return; + + while(rb_ctl_context.status != RB_CTL_SUSPEND) + osThreadYield(); +} + +void app_wait_player_resumed(void ) +{ + if(rb_ctl_context.status == RB_CTL_IDLE) + return; + + while(rb_ctl_context.status != RB_CTL_PLAYING) + osThreadYield(); +} + +void rb_thread_send_play(void ) +{ + _LOG_DBG(1," %s ",__FUNCTION__); + rb_thread_post_msg(RB_MODULE_EVT_PLAY, (uint32_t)osThreadGetId()); +} + +void rb_thread_send_stop(void ) +{ + _LOG_DBG(1," %s ",__FUNCTION__); + rb_thread_post_msg(RB_MODULE_EVT_STOP, (uint32_t)osThreadGetId()); + + osDelay(200); + app_wait_player_stoped(); +} + +void rb_thread_send_pause(void) +{ + _LOG_DBG(1," %s ",__FUNCTION__); + + rb_thread_post_msg(RB_MODULE_EVT_SUSPEND,(uint32_t)osThreadGetId()); + app_wait_player_suspend(); + + _LOG_DBG(1," %s end",__FUNCTION__); +} + +void rb_thread_send_resume(void) +{ + _LOG_DBG(1," %s ",__FUNCTION__); + + rb_thread_post_msg(RB_MODULE_EVT_RESUME,(uint32_t)osThreadGetId()); + + _LOG_DBG(1," %s end",__FUNCTION__); +} + +void rb_play_dual_play_restore(uint8_t stream_type ) +{ + _LOG_DBG(2,"%s %d \n", __func__, __LINE__); + + rb_thread_post_msg(RB_MODULE_EVT_RESTORE_DUAL_PLAY, stream_type); + _LOG_DBG(2,"%s %d \n", __func__, __LINE__); +} + +void rb_thread_send_switch(bool next) +{ + _LOG_DBG(2,"%s %d \n", __func__, __LINE__); + + rb_thread_post_msg(RB_MODULE_EVT_PLAY_NEXT,next); + + _LOG_DBG(2,"%s %d \n", __func__, __LINE__); +} + +void rb_play_linein_start(void ) +{ + _LOG_DBG(2,"%s %d \n", __func__, __LINE__); + + rb_thread_post_msg(RB_MODULE_EVT_LINEIN_START, 0); + _LOG_DBG(2,"%s %d \n", __func__, __LINE__); +} + +void rb_play_reconfig_stream(uint32_t arg ) +{ + _LOG_DBG(3,"%s %d arg:0x%x\n", __func__, __LINE__, arg); + + rb_thread_post_msg(RB_MODULE_EVT_RECONFIG_STREAM, arg); + _LOG_DBG(2,"%s %d \n", __func__, __LINE__); +} + +void rb_play_set_tws_mode(uint32_t arg ) +{ + _LOG_DBG(3,"%s %d arg:0x%x\n", __func__, __LINE__, arg); + + rb_thread_post_msg(RB_MODULE_EVT_SET_TWS_MODE, arg); + _LOG_DBG(2,"%s %d \n", __func__, __LINE__); +} + +void rb_thread_send_play_idx(uint32_t array_subidx) +{ + _LOG_DBG(2," %s array_subidx %d, ",__FUNCTION__,array_subidx); + + rb_thread_post_msg(RB_MODULE_EVT_PLAY_IDX,array_subidx); +} + + +void rb_thread_send_vol(bool inc) +{ + _LOG_DBG(2," %s inc %d, ",__FUNCTION__,inc); + + rb_thread_post_msg(RB_MODULE_EVT_CHANGE_VOL,inc); +} + +void rb_thread_send_status_change(void ) +{ + _LOG_DBG(1," %s , ",__FUNCTION__); + + rb_thread_post_msg(RB_MODULE_EVT_CHANGE_IDLE,0); +} + +void rb_thread_set_vol(uint32_t vol) +{ + _LOG_DBG(1," %s , ",__FUNCTION__); + + rb_thread_post_msg(RB_MODULE_EVT_SET_VOL, vol); +} + +void rb_thread_send_del_file(uint16_t idx ) +{ + _LOG_DBG(1," %s , ",__FUNCTION__); + + rb_thread_post_msg(RB_MODULE_EVT_DEL_FILE,idx); +} + +void rb_thread_send_sbc_record_start(void ) +{ + _LOG_DBG(1," %s , ",__FUNCTION__); + + rb_thread_post_msg(SBC_RECORD_ACTION_START,(uint32_t)osThreadGetId()); +} + +void rb_thread_send_sbc_record_data_ind(void ) +{ + if(!rb_ctl_context.sbc_record_on) + return ; + // _LOG_DBG(1," %s , ",__FUNCTION__); + rb_thread_post_msg(SBC_RECORD_ACTION_DATA_IND,(uint32_t)osThreadGetId()); +} + +void rb_thread_send_sbc_record_stop(void ) +{ + _LOG_DBG(1," %s , ",__FUNCTION__); + + rb_thread_post_msg(SBC_RECORD_ACTION_STOP,(uint32_t)osThreadGetId()); +} + + +//interface for audio module +static bool user_key_pause_stream = false; +void app_rbplay_audio_reset_pause_status(void) +{ + user_key_pause_stream = false; +} + +int app_rbplay_audio_onoff(bool onoff, uint16_t aud_id) +{ + _LOG_DBG(3," %s onoff %d, get status:%d",__FUNCTION__,onoff, rb_ctl_get_status()); + + if(app_rbcodec_check_hfp_active()&& !onoff) { + if( RB_CTL_PLAYING == rb_ctl_get_status()) { + rb_thread_send_pause(); + } + } else if ( !onoff) { + //rb_thread_send_stop(); + rb_thread_send_pause(); + } else { + if(!user_key_pause_stream) { + if( RB_CTL_SUSPEND == rb_ctl_get_status()) { + rb_thread_send_resume(); + app_wait_player_resumed(); + } else { + rb_thread_send_play(); + } + } + } + + return 0; +} + +void app_rbplay_pause_resume(void) +{ + _LOG_DBG(2," %s get status:%d",__func__, rb_ctl_get_status()); + + user_key_pause_stream = true; + if( RB_CTL_SUSPEND == rb_ctl_get_status()) { + user_key_pause_stream = false; + rb_thread_send_resume(); + } + if( RB_CTL_PLAYING == rb_ctl_get_status()) { + user_key_pause_stream = true; + rb_thread_send_pause(); + } +} +//sbc reader run within thread + +static int rb_ctl_mailbox_init(void) +{ + rb_ctl_mailbox = osMailCreate(osMailQ(rb_ctl_mailbox), NULL); + if (rb_ctl_mailbox == NULL) { + TRACE(0,"Failed to Create rb_ctl_mailbox\n"); + return -1; + } + return 0; +} + +int rb_ctl_mailbox_put(RBCTL_MSG_BLOCK* msg_src) +{ + osStatus status; + + RBCTL_MSG_BLOCK *msg_p = NULL; + + msg_p = (RBCTL_MSG_BLOCK*)osMailAlloc(rb_ctl_mailbox, 0); + if(!msg_p) { + TRACE(3,"%s fail, evt:%d,arg=%d \n",__func__,msg_src->evt,msg_src->arg); + return -1; + } + + ASSERT(msg_p, "osMailAlloc error"); + + msg_p->evt = msg_src->evt; + msg_p->arg = msg_src->arg; + + status = osMailPut(rb_ctl_mailbox, msg_p); + + return (int)status; +} + +int rb_ctl_mailbox_free(RBCTL_MSG_BLOCK* msg_p) +{ + osStatus status; + + status = osMailFree(rb_ctl_mailbox, msg_p); + + return (int)status; +} + +int rb_ctl_mailbox_get(RBCTL_MSG_BLOCK** msg_p) +{ + osEvent evt; + evt = osMailGet(rb_ctl_mailbox, osWaitForever); + if (evt.status == osEventMail) { + *msg_p = (RBCTL_MSG_BLOCK *)evt.value.p; + return 0; + } + return -1; +} + +#if 0 +void rb_ctl_action_init(void) +{ + + bool ind = voiceCocah_get_indication(); + TRACE(2," %s Cocah %d",__func__,ind); + + if( !ind) return ; + + // rb_ctl_set_priority(osPriorityHigh); + + rb_thread_post_msg(SBCREADER_ACTION_INIT,(uint32_t)osThreadGetId()); +} + +void rb_ctl_action_run(void) +{ + bool ind = voiceCocah_get_indication(); + TRACE(2," %s Cocah %d",__func__,ind); + + if( !ind) return ; + + rb_thread_post_msg(SBCREADER_ACTION_RUN,(uint32_t)osThreadGetId()); +} + +void rb_ctl_action_stop(void) +{ + bool ind = voiceCocah_get_indication(); + TRACE(2," %s Cocah %d",__func__,ind); + + if( !ind) return ; + + rb_thread_post_msg(SBCREADER_ACTION_STOP,(uint32_t)osThreadGetId()); + +} +#endif +static void rb_ctl_thread(void const *argument) +{ + osEvent evt; +#if 1 + app_sysfreq_req(APP_SYSFREQ_USER_APP_PLAYER, APP_SYSFREQ_208M); + + app_rbplay_load_playlist(&sd_playlist); +#endif + memset(&rb_ctl_context,0x0,sizeof(rb_ctl_struct)); + rb_ctl_context.rb_player_vol = 6; + rb_ctl_context.status = RB_CTL_IDLE; + + + rb_ctl_context.curr_song_idx = 0; + //load playlist here + + //voiceCocah_init(); + + rb_ctl_context.init_done = true; + + while(1) { + RBCTL_MSG_BLOCK *msg_p = NULL; + + app_sysfreq_req(APP_SYSFREQ_USER_APP_PLAYER, APP_SYSFREQ_32K); + + if (!rb_ctl_mailbox_get(&msg_p)) { + app_sysfreq_req(APP_SYSFREQ_USER_APP_PLAYER, APP_SYSFREQ_104M); + + rb_ctl_handle_event(msg_p); + + rb_ctl_mailbox_free(msg_p); + } + } +} + + +int rb_ctl_init(void) +{ + _LOG_DBG(1,"%s \n",__func__); + + rb_ctl_context.init_done = false; + rb_ctl_context.sbc_record_on = false; + + app_rbplay_open(); + + rb_ctl_mailbox_init(); + + rb_ctl_tid = osThreadCreate(osThread(rb_ctl_thread), NULL); + rb_ctl_default_priority = osPriorityAboveNormal; + + if (rb_ctl_tid == NULL) { + TRACE(0,"Failed to Create rb_ctl_thread\n"); + return 0; + } + _LOG_DBG(1,"Leave %s \n",__func__); + return 0; +} + +uint8_t rb_ctl_get_vol(void) +{ + return rb_ctl_context.rb_player_vol; +} + +bool rb_ctl_is_init_done(void) +{ + return rb_ctl_context.init_done; +} + +bool rb_ctl_is_paused(void) +{ + return ( RB_CTL_SUSPEND == rb_ctl_get_status()); +} + +uint16_t rb_ctl_songs_count(void) +{ + return sd_playlist.total_songs; +} + diff --git a/apps/audioplayers/rbplay/rb_ctl.h b/apps/audioplayers/rbplay/rb_ctl.h new file mode 100644 index 0000000..1b243c2 --- /dev/null +++ b/apps/audioplayers/rbplay/rb_ctl.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/* rbplay source */ +/* playback control & rockbox codec porting & codec thread */ +#ifndef __RB_CTL_H__ +#define __RB_CTL_H__ + + +typedef enum { + RB_MODULE_EVT_NONE, + RB_MODULE_EVT_PLAY, + RB_MODULE_EVT_PLAY_IDX, + RB_MODULE_EVT_STOP, + RB_MODULE_EVT_SUSPEND, + RB_MODULE_EVT_RESUME, + RB_MODULE_EVT_PLAY_NEXT, + RB_MODULE_EVT_CHANGE_VOL, + RB_MODULE_EVT_SET_VOL, + RB_MODULE_EVT_CHANGE_IDLE, + RB_MODULE_EVT_DEL_FILE, + + RB_MODULE_EVT_RESTORE_DUAL_PLAY, + RB_MODULE_EVT_LINEIN_START, + RB_MODULE_EVT_RECONFIG_STREAM, + RB_MODULE_EVT_SET_TWS_MODE, + + SBCREADER_ACTION_NONE, + SBCREADER_ACTION_INIT, + SBCREADER_ACTION_RUN, + SBCREADER_ACTION_STOP, + + SBC_RECORD_ACTION_START, + SBC_RECORD_ACTION_DATA_IND, + SBC_RECORD_ACTION_STOP, + + RB_MODULE_EVT_MAX +} RB_MODULE_EVT; + +typedef enum { + RB_CTL_IDLE, + RB_CTL_PLAYING, + RB_CTL_SUSPEND, +} rb_ctl_status; + +typedef struct { + struct mp3entry song_id3; + char rb_fname[FILE_SHORT_NAME_LEN]; + rb_ctl_status status ; //playing,idle,pause, + uint16_t rb_audio_file[FILE_PATH_LEN]; + uint16_t curr_song_idx ; + uint8_t rb_player_vol ; + int file_handle; + int init_done; + BOOL sbc_record_on; +} rb_ctl_struct; + +extern int app_rbmodule_post_msg(RB_MODULE_EVT evt,uint32_t arg); +extern int rb_ctl_is_audio_file(const char* file_path); + +uint8_t rb_ctl_get_vol(void); +#endif + diff --git a/apps/audioplayers/rbplay/rbpcmbuf.cpp b/apps/audioplayers/rbplay/rbpcmbuf.cpp new file mode 100644 index 0000000..ff41f92 --- /dev/null +++ b/apps/audioplayers/rbplay/rbpcmbuf.cpp @@ -0,0 +1,140 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/* rbpcmbuf source */ +/* pcmbuf management & af control & mixer */ +#include +#include +#include +#include +#include + +#ifdef MBED +#include "mbed.h" +#include "rtos.h" +#endif +#include "audioflinger.h" +#include "cqueue.h" +#include "app_audio.h" +#include "app_utils.h" +#include "hal_trace.h" + +#include "rbplay.h" +#include "rbpcmbuf.h" +#include "utils.h" + +#define RB_PCMBUF_DMA_BUFFER_SIZE (1024*12) +#define RB_PCMBUF_MEDIA_BUFFER_SIZE (1024*12) +#define RB_DECODE_OUT_BUFFER_SIZE 1024 + +static uint8_t *rb_decode_out_buff; +static uint8_t *rbplay_dma_buffer; +static uint8_t *rb_pcmbuf_media_buf; +static CQueue rb_pcmbuf_media_buf_queue; +static osMutexId _rb_media_buf_queue_mutex_id = NULL; +static osMutexDef(_rb_media_buf_queue_mutex); + +#define LOCK_MEDIA_BUF_QUEUE() \ + if(osErrorISR == osMutexWait(_rb_media_buf_queue_mutex_id, osWaitForever)) {\ + error("%s LOCK_MEDIA_BUF_QUEUE from IRQ!!!!!!!\n",__func__);\ + }\ + +#define UNLOCK_MEDIA_BUF_QUEUE() \ + if(osErrorISR == osMutexRelease(_rb_media_buf_queue_mutex_id)){ \ + error("%s UNLOCK_MEDIA_BUF_QUEUE from IRQ!!!!!!\n"); \ + } \ + +static uint32_t rbplay_more_data(uint8_t *buf, uint32_t len) +{ + CQItemType *e1 = NULL; + CQItemType *e2 = NULL; + unsigned int len1 = 0; + unsigned int len2 = 0; + + LOCK_MEDIA_BUF_QUEUE(); + int ret = PeekCQueue(&rb_pcmbuf_media_buf_queue, len, &e1, &len1, &e2, &len2); + UNLOCK_MEDIA_BUF_QUEUE(); + + if (ret == CQ_OK) { + if (len1 > 0) + memcpy(buf, e1, len1); + if (len2 > 0) + memcpy(buf + len1, e2, len - len1); + LOCK_MEDIA_BUF_QUEUE(); + DeCQueue(&rb_pcmbuf_media_buf_queue, 0, len); + UNLOCK_MEDIA_BUF_QUEUE(); + } else { + warn("RBplay cache underflow"); + } + + return len; +} + +extern uint8_t rb_ctl_get_vol(void); +void rb_pcmbuf_init(void) +{ + info("pcmbuff init"); + if(!_rb_media_buf_queue_mutex_id) + _rb_media_buf_queue_mutex_id = osMutexCreate((osMutex(_rb_media_buf_queue_mutex))); + + app_audio_mempool_init(); + + app_audio_mempool_get_buff(&rb_pcmbuf_media_buf, RB_PCMBUF_MEDIA_BUFFER_SIZE); + InitCQueue(&rb_pcmbuf_media_buf_queue, RB_PCMBUF_MEDIA_BUFFER_SIZE, (unsigned char *)rb_pcmbuf_media_buf); + + app_audio_mempool_get_buff(&rbplay_dma_buffer, RB_PCMBUF_DMA_BUFFER_SIZE); + app_audio_mempool_get_buff(&rb_decode_out_buff, RB_DECODE_OUT_BUFFER_SIZE); + + struct AF_STREAM_CONFIG_T stream_cfg; + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; + stream_cfg.sample_rate = AUD_SAMPRATE_44100; + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.vol = rb_ctl_get_vol(); + stream_cfg.handler = rbplay_more_data; + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(rbplay_dma_buffer); + stream_cfg.data_size = RB_PCMBUF_DMA_BUFFER_SIZE; + + af_stream_open(AUD_STREAM_ID_0,AUD_STREAM_PLAYBACK, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0,AUD_STREAM_PLAYBACK); +} + +void *rb_pcmbuf_request_buffer(int *size) +{ + *size = RB_DECODE_OUT_BUFFER_SIZE / 4; + return rb_decode_out_buff; +} + +void rb_pcmbuf_write(unsigned int size) +{ + int ret ; + do { + LOCK_MEDIA_BUF_QUEUE(); + ret = EnCQueue(&rb_pcmbuf_media_buf_queue, (CQItemType *)rb_decode_out_buff, size*(2*2)); + UNLOCK_MEDIA_BUF_QUEUE(); + osThreadYield(); + } while (ret == CQ_ERR); +} + +void rb_pcmbuf_stop(void) +{ + af_stream_stop(AUD_STREAM_ID_0,AUD_STREAM_PLAYBACK); + af_stream_close(AUD_STREAM_ID_0,AUD_STREAM_PLAYBACK); +} + diff --git a/apps/audioplayers/rbplay/rbpcmbuf.h b/apps/audioplayers/rbplay/rbpcmbuf.h new file mode 100644 index 0000000..cfcbb5e --- /dev/null +++ b/apps/audioplayers/rbplay/rbpcmbuf.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef RBPCMBUF_HEADER +#define RBPCMBUF_HEADER + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _RB_PCMBUF_AUD_STATE_T { + RB_PCMBUF_AUD_STATE_STOP = 0, + RB_PCMBUF_AUD_STATE_START, +} RB_PCMBUF_AUD_STATE_T; + +void rb_pcmbuf_init(void); +void rb_pcmbuf_stop(void); +void *rb_pcmbuf_request_buffer(int *size); +void rb_pcmbuf_write(unsigned int size); + +#ifdef __cplusplus +} +#endif + +#endif /* RBPCMBUF_HEADER */ diff --git a/apps/audioplayers/rbplay/rbplay.cpp b/apps/audioplayers/rbplay/rbplay.cpp new file mode 100644 index 0000000..dee5d3e --- /dev/null +++ b/apps/audioplayers/rbplay/rbplay.cpp @@ -0,0 +1,615 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/* rbplay source */ +/* playback control & rockbox codec porting & codec thread */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef MBED +#include "mbed.h" +#include "rtos.h" +#endif +#include "metadata.h" +#include "codecs.h" +#include "eq_export.h" +#include "hal_overlay.h" +#include "app_overlay.h" +#include "audioflinger.h" +#include "hal_trace.h" +#include "apps.h" + +#include "rbpcmbuf.h" +#include "rbplaysd.h" +#include "app_thread.h" +#include "app_utils.h" +#include "app_key.h" +#include "rbplay.h" +#include "utils.h" + +#ifdef __TWS__ +#include "app_tws.h" +#endif + +// TODO: remove +#define BT_STREAM_RBCODEC 0x10 //from rockbox decoder + +extern "C" { + void flac_codec_main(int r); + void flac_codec_run(void); + void wav_codec_main(int r); + void wav_codec_run(void); + void mpa_codec_main(int r); + void mpa_codec_run(void); + void ape_codec_main(int r); + void ape_codec_run(void); + void sbc_codec_main(int r); + void sbc_codec_run(void); +} + +extern void rb_pcm_player_open(enum AUD_BITS_T bits,enum AUD_SAMPRATE_T sample_rate,enum AUD_CHANNEL_NUM_T channel_num,uint8_t vol) ; + +#if defined(__TWS__) +typedef struct _rb_tws_codec_info{ + uint8_t update_codec_info; + int32_t sample_freq; + uint8_t channel_num; +} rb_tws_codec_info; + +rb_tws_codec_info codec_info = {1, 44100, 2}; +#endif + +static osThreadId rb_decode_tid = NULL; +static osThreadId rb_caller_tid = NULL; + +typedef struct { + uint32_t evt; + uint32_t arg; +} RBTHREAD_MSG_BLOCK; + +#define RBTHREAD_MAILBOX_MAX (10) +osMailQDef (rb_decode_mailbox, RBTHREAD_MAILBOX_MAX, RBTHREAD_MSG_BLOCK); +int rb_decode_mailbox_put(RBTHREAD_MSG_BLOCK* msg_src); +static osMailQId rb_decode_mailbox = NULL; + +static void rb_decode_thread(void const *argument); +osThreadDef(rb_decode_thread, osPriorityAboveNormal, 1, 1024 * 2, "rb_decorder"); + +// rbcodec info +static int song_fd; +static int song_format; +static struct mp3entry *current_id3; +static uint8_t rbplay_loop_on; + +static volatile int rb_decode_halt_flag = 1; + +struct codec_api ci_api; +struct codec_api *ci = &ci_api; + +// TODO +volatile osThreadId thread_tid_waiter = NULL; + +void init_dsp(void); +void codec_configure(int setting, intptr_t value); + +uint16_t g_rbplayer_curr_song_idx = 0; + +extern void app_rbplay_exit(void); + +extern void bt_change_to_iic(APP_KEY_STATUS *status, void *param); + +extern void rb_thread_send_switch(bool next); +extern void rb_thread_send_status_change(void ); + +enum APP_SYSFREQ_FREQ_T rb_player_get_work_freq(void); + +static void rb_player_sync_close_done(void) +{ + thread_tid_waiter = NULL; +} + +extern void rb_check_stream_reconfig(int32_t freq, uint8_t ch); +static void f_codec_pcmbuf_insert_callback( + const void *ch1, const void *ch2, int count) +{ + struct dsp_buffer src; + struct dsp_buffer dst; + + src.remcount = count; + src.pin[0] = (const unsigned char *)ch1; + src.pin[1] = (const unsigned char *)ch2; + src.proc_mask = 0; + + if (rb_codec_running() == 0) + return ; + +#ifndef __TWS__ + while (src.remcount > 0) { + dst.remcount = 0; + dst.p16out = (short *)rb_pcmbuf_request_buffer(&dst.bufcount); + + if (dst.p16out == NULL) { + warn("No pcm buffer"); + osThreadYield(); + } else { + dsp_process(ci->dsp, &src, &dst); + + if (dst.remcount > 0) { + rb_pcmbuf_write(dst.remcount); + } + } + } +#else + + if(codec_info.update_codec_info){ + rb_set_sbc_encoder_freq_ch(codec_info.sample_freq, codec_info.channel_num); //should call this to set trigger timer + rb_check_stream_reconfig(codec_info.sample_freq, codec_info.channel_num); + codec_info.update_codec_info = 0; + } + + if(tws_local_player_need_tran_2_slave()){ + rb_tws_start_master_player(BT_STREAM_RBCODEC); + } + while(1){ + uint8_t * pcm_buff = NULL; + dst.remcount = 0; + dst.bufcount = MIN(src.remcount, 128); /* Arbitrary min request */ + dst.p16out = (short *)rb_pcmbuf_request_buffer(&dst.bufcount); + pcm_buff = (uint8_t *)dst.p16out; + ASSERT(pcm_buff, "Should request buffer"); + + dsp_process(ci->dsp, &src, &dst); + + if (dst.remcount > 0) { + while(rb_push_pcm_in_tws_buffer(pcm_buff, dst.remcount*2*2) == 0){ + osDelay(2); + } + } + + if (src.remcount <= 0) { + return; /* No input remains and DSP purged */ + } + } +#endif +} + +static void f_audio_codec_update_elapsed(unsigned long elapsed) +{ + //info("Update elapsed: %d", elapsed); + return; +} + +static size_t f_codec_filebuf_callback(void *ptr, size_t size) +{ + ssize_t ret; + ret = read(song_fd, ptr, size); + if(ret < 0) { + error("File read error: %d",ret); + } + + return ret; + +} + +static void * f_codec_request_buffer_callback(size_t *realsize, size_t reqsize) +{ + return NULL; +} + +static void * f_codec_advance_buffer_callback(size_t amount) +{ + off_t ret = lseek(song_fd, (off_t)(ci->curpos + amount), SEEK_SET); + if(ret < 0) { + error("File seek fail"); + return NULL; + } + + ci->curpos += amount; + return (void *)ci; + +} + +static bool f_codec_seek_buffer_callback(size_t newpos) +{ + off_t ret = lseek(song_fd, (off_t)newpos, SEEK_SET); + if(ret < 0) { + error("File seek fail"); + return false; + } + + ci->curpos = newpos; + return true; +} + +static void f_codec_seek_complete_callback(void) +{ + info("Seek complete"); + dsp_configure(ci->dsp, DSP_FLUSH, 0); +} + +static void f_audio_codec_update_offset(size_t offset) +{ +} + +static void f_codec_configure_callback(int setting, intptr_t value) +{ + dsp_configure(ci->dsp, setting, value); +#ifdef __TWS__ + if(setting == DSP_SET_FREQUENCY){ + if(codec_info.sample_freq != value) + codec_info.update_codec_info = 1; + codec_info.sample_freq = value; + } + else if(setting == DSP_SET_STEREO_MODE){ + if(codec_info.channel_num != (value == STEREO_MONO ? 1 : 2)) + codec_info.update_codec_info = 1; + codec_info.channel_num = value == STEREO_MONO ? 1 : 2; + } +#endif +} + +static enum codec_command_action f_codec_get_command_callback(intptr_t *param) +{ + if (rb_decode_halt_flag == 1) + return CODEC_ACTION_HALT ; + + return CODEC_ACTION_NULL; +} + +static bool f_codec_loop_track_callback(void) +{ + return false; +} + +static void init_ci_file(void) +{ + ci->codec_get_buffer = 0; + ci->pcmbuf_insert = f_codec_pcmbuf_insert_callback; + ci->set_elapsed = f_audio_codec_update_elapsed; + ci->read_filebuf = f_codec_filebuf_callback; + ci->request_buffer = f_codec_request_buffer_callback; + ci->advance_buffer = f_codec_advance_buffer_callback; + ci->seek_buffer = f_codec_seek_buffer_callback; + ci->seek_complete = f_codec_seek_complete_callback; + ci->set_offset = f_audio_codec_update_offset; + ci->configure = f_codec_configure_callback; + ci->get_command = f_codec_get_command_callback; + ci->loop_track = f_codec_loop_track_callback; +} + +static void rb_play_init(void) +{ + init_dsp(); + + init_ci_file(); + +#ifndef __TWS__ + rb_pcmbuf_init(); +#endif +} + +void rb_play_codec_init(void) +{ + RBTHREAD_MSG_BLOCK msg; + msg.evt = (uint32_t)RB_CTRL_CMD_CODEC_INIT; + msg.arg = (uint32_t)0; + rb_decode_mailbox_put(&msg); +} + +void rb_play_codec_run(void) +{ + RBTHREAD_MSG_BLOCK msg; + msg.evt = (uint32_t)RB_CTRL_CMD_CODEC_RUN; + msg.arg = (uint32_t)0; + rb_decode_mailbox_put(&msg); +} + +static int rb_codec_init_desc(void ) +{ + info("Init decode format: %d", song_format); + + switch (song_format) { + case AFMT_MPA_L1: + case AFMT_MPA_L2: + case AFMT_MPA_L3: + app_overlay_select(APP_OVERLAY_MPA); + mpa_codec_main(CODEC_LOAD); + break; + // TODO: add APP_OVERLAY_APE +#if 0 + case AFMT_APE: + app_overlay_select(APP_OVERLAY_APE); + ape_codec_main(CODEC_LOAD); + break; + case AFMT_SBC: + app_overlay_select(APP_OVERLAY_A2DP); + sbc_codec_main(CODEC_LOAD); + break; + case AFMT_FLAC: + app_overlay_select(APP_OVERLAY_FLAC); + flac_codec_main(CODEC_LOAD); + break; + case AFMT_PCM_WAV: + app_overlay_select(APP_OVERLAY_WAV); + wav_codec_main(CODEC_LOAD); + break; +#endif + default: + error("unkown codec type init\n"); + break; + } + + return 0; +} + +static int rb_codec_loop_on(void) +{ +#ifdef __TWS__ + //set start transfer to slave + tws_local_player_set_tran_2_slave_flag(1); +#endif + switch (song_format) { + case AFMT_MPA_L1: + case AFMT_MPA_L2: + case AFMT_MPA_L3: + mpa_codec_run(); + break; +#if 0 + case AFMT_SBC: + sbc_codec_run(); + break; + case AFMT_FLAC: + flac_codec_run(); + break; + case AFMT_PCM_WAV: + wav_codec_run(); + break; + case AFMT_APE: + ape_codec_run(); + break; +#endif + default: + error("unkown codec type run\n"); + break; + } + return 0; +} + +static int rb_thread_process_evt(RB_CTRL_CMD_T evt) +{ + info("Decode event:%d", evt); + + switch(evt) { + case RB_CTRL_CMD_CODEC_INIT: + rb_decode_halt_flag = 0; + + rb_play_init(); + + /* get id3 */ + /* init ci info */ + ci->filesize = filesize(song_fd); + ci->id3 = current_id3; + ci->curpos = 0; + + dsp_configure(ci->dsp, DSP_RESET, 0); + dsp_configure(ci->dsp, DSP_FLUSH, 0); + + rb_codec_init_desc(); + break; + case RB_CTRL_CMD_CODEC_RUN: + rbplay_loop_on = 1; + + info("Play start"); + app_sysfreq_req(APP_SYSFREQ_USER_APP_PLAYER, rb_player_get_work_freq()); + app_stop_10_second_timer(APP_POWEROFF_TIMER_ID); + rb_codec_loop_on(); +#if defined(__BTIF_AUTOPOWEROFF__) + app_start_10_second_timer(APP_POWEROFF_TIMER_ID); +#endif + song_fd = 0; + rb_decode_halt_flag = 1; + if(thread_tid_waiter) { + rb_player_sync_close_done(); + } else { + rb_thread_send_status_change(); + rb_thread_send_switch(true); + } +#ifdef __TWS__ + //should update codec info after play one music + codec_info.update_codec_info = 1; +#endif + rbplay_loop_on = 0; + info("Play end"); + break; + default: + error("Unkown rb cmd %d\n",evt); + break; + } + + return 0; +} + +int rb_decode_mailbox_put(RBTHREAD_MSG_BLOCK* msg_src) +{ + osStatus status; + + RBTHREAD_MSG_BLOCK *msg_p = NULL; + + msg_p = (RBTHREAD_MSG_BLOCK*)osMailAlloc(rb_decode_mailbox, 0); + if(!msg_p) { + TRACE(3,"%s fail, evt:%d,arg=%d \n",__func__,msg_src->evt,msg_src->arg); + return -1; + } + + msg_p->evt = msg_src->evt; + msg_p->arg = msg_src->arg; + + status = osMailPut(rb_decode_mailbox, msg_p); + + return (int)status; +} + +int rb_decode_mailbox_free(RBTHREAD_MSG_BLOCK* msg_p) +{ + osStatus status; + + status = osMailFree(rb_decode_mailbox, msg_p); + + return (int)status; +} + +int rb_decode_mailbox_get(RBTHREAD_MSG_BLOCK** msg_p) +{ + osEvent evt; + evt = osMailGet(rb_decode_mailbox, osWaitForever); + if (evt.status == osEventMail) { + *msg_p = (RBTHREAD_MSG_BLOCK *)evt.value.p; + return 0; + } + return -1; +} + +static void rb_decode_thread(void const *argument) +{ + RB_CTRL_CMD_T action; + RBTHREAD_MSG_BLOCK* msg_p; + + while(1) { + app_sysfreq_req(APP_SYSFREQ_USER_APP_PLAYER, APP_SYSFREQ_32K); + // evt = osSignalWait(0, osWaitForever); + if(0 == rb_decode_mailbox_get(&msg_p)) { + app_sysfreq_req(APP_SYSFREQ_USER_APP_PLAYER, APP_SYSFREQ_104M); + + action = (RB_CTRL_CMD_T) msg_p->evt; + rb_caller_tid = (osThreadId) msg_p->arg ; + + TRACE(3,"[%s] action:%d ,tid,0x%x", __func__, action,rb_caller_tid); + rb_thread_process_evt(action); + + rb_decode_mailbox_free(msg_p); + if( rb_caller_tid) + osSignalSet(rb_decode_tid, 0x1203); + rb_caller_tid = NULL; + } + + } +} + +int app_rbplay_open(void) +{ + if (rb_decode_tid != NULL) { + warn("Decode thread reopen"); + return -1; + } + + rb_decode_mailbox = osMailCreate(osMailQ(rb_decode_mailbox), NULL); + if (rb_decode_mailbox == NULL) { + error("Failed to Create rb_decode_mailbox"); + return -1; + } + + rb_decode_tid = osThreadCreate(osThread(rb_decode_thread), NULL); + if (rb_decode_tid == NULL) { + error("Failed to Create rb_thread \n"); + return -1; + } + + return 0; +} + +int rb_codec_running(void) +{ + return ((rb_decode_halt_flag == 0)?1:0); +} + +void rb_codec_set_halt(int halt) +{ + rb_decode_halt_flag = halt; +} + +void rb_thread_set_decode_vars(int fd, int type ,void* id3) +{ + song_fd =fd; + song_format = type; + current_id3 = (struct mp3entry *)id3; +} + +void rb_player_sync_set_wait_thread(osThreadId tid) +{ + if(rbplay_loop_on) + thread_tid_waiter = tid; + else + thread_tid_waiter = NULL; +} + +void rb_player_sync_wait_close(void ) +{ + while(NULL != thread_tid_waiter) { + osThreadYield(); + } +} + +enum APP_SYSFREQ_FREQ_T rb_player_get_work_freq(void) +{ + enum APP_SYSFREQ_FREQ_T freq; + + hal_sysfreq_print(); + + info("bitrate:%d freq:%d\n", ci->id3->bitrate, ci->id3->frequency); +#ifndef __TWS__ + enum AUD_SAMPRATE_T sample_rate = AUD_SAMPRATE_44100; + sample_rate =(enum AUD_SAMPRATE_T ) ci->id3->frequency; + if(sample_rate > AUD_SAMPRATE_48000) + freq = APP_SYSFREQ_208M; + else if (sample_rate > AUD_SAMPRATE_44100) + freq = APP_SYSFREQ_104M; + else + freq = APP_SYSFREQ_52M; + + if(ci->id3->bitrate > 192) + freq = APP_SYSFREQ_208M; + else if (ci->id3->bitrate > 128) + freq = APP_SYSFREQ_104M; + else + freq = APP_SYSFREQ_52M; + + switch( song_format ) { + case AFMT_APE: + freq = APP_SYSFREQ_208M; + break; + case AFMT_FLAC: + freq = APP_SYSFREQ_208M; + break; + case AFMT_PCM_WAV: + freq = APP_SYSFREQ_208M; + break; + default: + break; + } +#else + freq = APP_SYSFREQ_208M; +#endif + info("Decode thread run at: %d", freq); + return freq; +} + + diff --git a/apps/audioplayers/rbplay/rbplay.h b/apps/audioplayers/rbplay/rbplay.h new file mode 100644 index 0000000..db7c2d9 --- /dev/null +++ b/apps/audioplayers/rbplay/rbplay.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/* rbplay header */ +/* playback control & rockbox codec porting & codec thread */ +#ifndef RBPLAY_HEADER +#define RBPLAY_HEADER + +/* ---- APIs ---- */ +typedef enum _RB_CTRL_CMD_T { + RB_CTRL_CMD_NONE = 0, + RB_CTRL_CMD_SCAN_SONGS, + RB_CTRL_CMD_CODEC_PARSE_FILE, + RB_CTRL_CMD_CODEC_INIT, + RB_CTRL_CMD_CODEC_RUN, + RB_CTRL_CMD_CODEC_PAUSE, + RB_CTRL_CMD_CODEC_STOP, + RB_CTRL_CMD_CODEC_DEINIT, + + RB_CTRL_CMD_CODEC_SEEK, + + RB_CTRL_CMD_CODEC_MAX, +} RB_CTRL_CMD_T; + +int app_rbplay_open(void); +void rb_play_codec_init(void); +int rb_codec_running(void); + +#endif /* RBPLAY_HEADER */ diff --git a/apps/audioplayers/rbplay/rbplaysd.cpp b/apps/audioplayers/rbplay/rbplaysd.cpp new file mode 100644 index 0000000..68281dc --- /dev/null +++ b/apps/audioplayers/rbplay/rbplaysd.cpp @@ -0,0 +1,225 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/* rbplay source */ +/* playback control & rockbox codec porting & codec thread */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hal_trace.h" +#include "metadata.h" +#include "SDFileSystem.h" +#include "rbplaysd.h" +#include "utils.h" + +#define SD_LABEL "sd" +#define PLAYLIST_PATH "/sd/Playlist" + +static SDFileSystem *sdfs = NULL; + +// TODO: remove ? +static playlist_item sd_curritem; + +playlist_struct sd_playlist; + +static void playlist_insert(playlist_item* item) +{ + int fd; + fd = open(PLAYLIST_PATH, O_RDWR | O_CREAT); + if (fd <= 0) { + error("Playlist open fail"); + return; + } + + lseek(fd, item->song_idx * sizeof(playlist_item), SEEK_SET); + write(fd, item, sizeof(playlist_item)); + close(fd); +} + +static bool sdcard_mount(void) +{ + if (sdfs) { + info("SD card already mount"); + return true; + } + + sdfs = new SDFileSystem(SD_LABEL); + if (sdfs == NULL) { + error("No memory for sd file system"); + return false; + } + + DIR *d; + d = opendir("/" SD_LABEL); + + if (!d) { + warn("SD card mount error"); + return false; + } + + closedir(d); + return true; +} + +static void app_rbplay_gen_playlist(playlist_struct *list) +{ + struct dirent *p; + DIR *d; + uint32_t total; + int fd = 0; + struct mp3entry current_id3; + playlist_item* sd_curritem_p = &sd_curritem; + + memset(list,0x0,sizeof(playlist_struct)); + + d = opendir("/" SD_LABEL); + if (!d) { + error("SD card open fail"); + return; + } + + info("---------gen audio list---------"); + + total = 0; + while (p = readdir(d)) { + if (probe_file_format(p->d_name) == AFMT_UNKNOWN) + continue; + + memset(&sd_curritem,0x0,sizeof(playlist_item)); + sd_curritem.song_idx = total; + + sprintf(sd_curritem.file_path, "/" SD_LABEL "/%s", p->d_name); + sprintf(sd_curritem.file_name, "%s", p->d_name); + + info("Adding music: %s", sd_curritem.file_path); + + fd = open(sd_curritem.file_path, O_RDONLY); + + if (fd <= 0) { + error("File %s open error", p->d_name); + break; + } + + get_metadata(¤t_id3, fd, sd_curritem.file_path); + close(fd); + + if(current_id3.bitrate == 0 || current_id3.filesize == 0 || current_id3.length == 0) + break; + + info("bits:%d, type:%d, freq:%d", current_id3.bitrate, + current_id3.codectype, current_id3.frequency); + + sd_curritem_p->bitrate = current_id3.bitrate; + sd_curritem_p->codectype = current_id3.codectype; + sd_curritem_p->filesize = current_id3.filesize; + sd_curritem_p->length = current_id3.length; + sd_curritem_p->frequency = current_id3.frequency; + +#ifdef PARSER_DETAIL + char *str; + str = current_id3.title; + if(str != NULL) { + memset(sd_curritem_p->title,0x0,MP3_TITLE_LEN); + memcpy(sd_curritem_p->title ,str,strlen(str)>MP3_TITLE_LEN?MP3_TITLE_LEN:strlen(str)); + } + + str = current_id3.artist; + if(str != NULL) { + memset(sd_curritem_p->artist,0x0,MP3_ARTIST_LEN); + memcpy(sd_curritem_p->artist ,str,strlen(str)>MP3_ARTIST_LEN?MP3_ARTIST_LEN:strlen(str)); + } + + str = current_id3.album; + if(str != NULL) { + memset(sd_curritem_p->album,0x0,MP3_ALBUM_LEN); + memcpy(sd_curritem_p->album ,str,strlen(str)>MP3_ALBUM_LEN?MP3_ALBUM_LEN:strlen(str)); + } + + str = current_id3.genre_string; + if(str != NULL) { + memset(sd_curritem_p->genre,0x0,MP3_GENRE_LEN); + memcpy(sd_curritem_p->genre ,str,strlen(str)>MP3_GENRE_LEN?MP3_GENRE_LEN:strlen(str)); + } + + str = current_id3.composer; + if(str != NULL) { + memset(sd_curritem_p->composer,0x0,MP3_COMPOSER_LEN); + memcpy(sd_curritem_p->composer ,str,strlen(str)>MP3_COMPOSER_LEN?MP3_COMPOSER_LEN:strlen(str)); + } +#endif + playlist_insert(sd_curritem_p); + total++; + } + + list->total_songs = total ; + list->current_item = sd_curritem_p; + + closedir(d); + info("---------%d audio file searched---------" , total); + +} + +void app_rbplay_load_playlist(playlist_struct *list) +{ + if(sdcard_mount() == false) + return; + + remove(PLAYLIST_PATH); + + app_rbplay_gen_playlist(list); +} + +playlist_item *app_rbplay_get_playitem(const int idx) +{ + int fd; + if(idx >= sd_playlist.total_songs) { + warn("Index exceed: %d / %d", idx, sd_playlist.total_songs); + return NULL; + } + + fd = open(PLAYLIST_PATH, O_RDONLY); + + if (fd <= 0) { + warn("SD card playlist can not open"); + return NULL; + } + + lseek(fd, sizeof(playlist_item) * idx, SEEK_SET); + read(fd, sd_playlist.current_item, sizeof(playlist_item)); + info("Get playitem: %d: %s", idx, sd_playlist.current_item->file_path); + + close(fd); + + return sd_playlist.current_item; +} + +int app_ctl_remove_file(const int idx) +{ + playlist_item *item = app_rbplay_get_playitem(idx); + if (!item) + return -1; + remove(item->file_path); + + return 0; +} + + diff --git a/apps/audioplayers/rbplay/rbplaysd.h b/apps/audioplayers/rbplay/rbplaysd.h new file mode 100644 index 0000000..32f79dc --- /dev/null +++ b/apps/audioplayers/rbplay/rbplaysd.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __RBPLAYSD_H_ +#define __RBPLAYSD_H_ + +#include + +//playlist +#define FILE_PATH_LEN (128+4) +#define FILE_SHORT_NAME_LEN (128) +#define MP3_TITLE_LEN (128) +#define MP3_ARTIST_LEN (128) +#define MP3_ALBUM_LEN (128) +#define MP3_GENRE_LEN (128) +#define MP3_COMPOSER_LEN (128) +#define MP3_YEAR_STRING_LEN (8) +#define MP3_TRACK_LEN (128) + +typedef struct { + char file_path[FILE_PATH_LEN]; + char file_name[FILE_SHORT_NAME_LEN]; +#ifdef PARSER_DETAIL + uint16_t title[MP3_TITLE_LEN]; + uint16_t artist[MP3_ARTIST_LEN]; + uint16_t album[MP3_ALBUM_LEN]; + uint16_t genre[MP3_GENRE_LEN]; + uint16_t composer[MP3_COMPOSER_LEN]; + uint16_t year[MP3_YEAR_STRING_LEN]; + uint16_t track[MP3_TRACK_LEN]; +#endif + uint16_t song_idx; + + unsigned int codectype; + unsigned int bitrate; + unsigned long frequency; + + unsigned long filesize; /* without headers; in bytes */ + unsigned long length; /* song length in ms */ +} playlist_item; + +typedef struct { + playlist_item *current_item; + uint16_t total_songs; +} playlist_struct; + +void app_rbplay_load_playlist(playlist_struct *list); +playlist_item *app_rbplay_get_playitem(const int idx); +int app_ctl_remove_file(const int idx); + +#endif diff --git a/apps/audioplayers/rbplay/utils.h b/apps/audioplayers/rbplay/utils.h new file mode 100644 index 0000000..fb0fa5e --- /dev/null +++ b/apps/audioplayers/rbplay/utils.h @@ -0,0 +1,26 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef RBPLAY_UTILS_H +#define RBPLAY_UTILS_H + +#undef warn +#undef error + +#define info(str, ...) TRACE(str, ##__VA_ARGS__) +#define warn(str, ...) TRACE("\033[31mwarn: \033[0m" str, ##__VA_ARGS__) +#define error(str, ...) TRACE("\033[31merr: \033[0m" str, ##__VA_ARGS__) + +#endif diff --git a/apps/audioplayers/voice_test.c b/apps/audioplayers/voice_test.c new file mode 100644 index 0000000..ba47baf --- /dev/null +++ b/apps/audioplayers/voice_test.c @@ -0,0 +1,185 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "app_utils.h" +#include "audioflinger.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "string.h" +#include "audio_dump.h" +// #include "local_wav.h" + +#define CHANNEL_NUM (2) + +#define CHAR_BYTES (1) +#define SHORT_BYTES (2) +#define INT_BYTES (4) + +#define SAMPLE_BITS (16) +#define SAMPLE_BYTES (SAMPLE_BITS / 8) + + +#define TX_SAMPLE_RATE (16000) +#define RX_SAMPLE_RATE (16000) + + +#define TX_FRAME_LEN (256) +#define RX_FRAME_LEN (256) + +#define TX_BUF_SIZE (TX_FRAME_LEN * CHANNEL_NUM * SAMPLE_BYTES * 2) +#define RX_BUF_SIZE (RX_FRAME_LEN * CHANNEL_NUM * SAMPLE_BYTES * 2) + +#if SAMPLE_BYTES == SHORT_BYTES +typedef short VOICE_PCM_T; +#elif SAMPLE_BYTES == INT_BYTES +typedef int VOICE_PCM_T; +#else +#error "Invalid SAMPLE_BYTES!!!" +#endif + +static uint8_t POSSIBLY_UNUSED codec_capture_buf[TX_BUF_SIZE]; +static uint8_t POSSIBLY_UNUSED codec_playback_buf[RX_BUF_SIZE]; + +static uint32_t POSSIBLY_UNUSED codec_capture_cnt = 0; +static uint32_t POSSIBLY_UNUSED codec_playback_cnt = 0; + +#define CODEC_STREAM_ID AUD_STREAM_ID_0 + +static uint32_t codec_capture_callback(uint8_t *buf, uint32_t len) +{ + int POSSIBLY_UNUSED pcm_len = len / sizeof(VOICE_PCM_T) / CHANNEL_NUM; + VOICE_PCM_T POSSIBLY_UNUSED *pcm_buf[CHANNEL_NUM]; + int interval_len = len * 2 / CHANNEL_NUM; + + for (int i=0; i +#include +#include +#include +#include +#include "cmsis_os.h" +#include "plat_types.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "cqueue.h" +#include "app_audio.h" +#include "app_overlay.h" +#include "app_ring_merge.h" +#include "tgt_hardware.h" +#include "bt_sco_chain.h" +#include "iir_resample.h" +#include "hfp_api.h" +#include "audio_prompt_sbc.h" +#ifdef TX_RX_PCM_MASK +#include "bt_drv_interface.h" +#endif + +#define ENABLE_LPC_PLC + +#define ENABLE_PLC_ENCODER + +// BT +#include "a2dp_api.h" +#ifdef TX_RX_PCM_MASK +#include "hal_chipid.h" +#include "bt_drv_interface.h" + +#endif + +#include "plc_utils.h" +extern "C" { + +#include "plc_8000.h" +#include "speech_utils.h" + +#if defined(HFP_1_6_ENABLE) +#include "codec_sbc.h" +#if defined(ENABLE_LPC_PLC) +#include "lpc_plc_api.h" +#else +#include "plc_16000.h" +#endif +#endif + +#if defined(CVSD_BYPASS) +#include "Pcm8k_Cvsd.h" +#endif + +#if defined(SPEECH_TX_24BIT) +extern int32_t *aec_echo_buf; +#else +extern short *aec_echo_buf; +#endif + +#if defined( SPEECH_TX_AEC ) || defined( SPEECH_TX_AEC2 ) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) +static uint8_t *echo_buf_queue; +static uint16_t echo_buf_q_size; +static uint16_t echo_buf_q_wpos; +static uint16_t echo_buf_q_rpos; +static bool echo_buf_q_full; +#endif +#endif +static void *speech_plc; +} + +//#define PENDING_MSBC_DECODER_ALG + +// #define SPEECH_RX_PLC_DUMP_DATA + +#ifdef SPEECH_RX_PLC_DUMP_DATA +#include "audio_dump.h" +int16_t *audio_dump_temp_buf = NULL; +#endif + +// app_bt_stream.cpp::bt_sco_player(), used buffer size +#define APP_BT_STREAM_USE_BUF_SIZE (1024*2) +#if defined(SCO_OPTIMIZE_FOR_RAM) +uint8_t *sco_overlay_ram_buf = NULL; +int sco_overlay_ram_buf_len = 0; +#endif + +static bool resample_needed_flag = false; +static int sco_frame_length; +static int codec_frame_length; +static int16_t *upsample_buf_for_msbc = NULL; +static int16_t *downsample_buf_for_msbc = NULL; +static IirResampleState *upsample_st = NULL; +static IirResampleState *downsample_st = NULL; + +#define VOICEBTPCM_TRACE(s,...) +//TRACE(s, ##__VA_ARGS__) + +/* voicebtpcm_pcm queue */ +#define FRAME_NUM (4) + +#define VOICEBTPCM_PCM_16k_FRAME_LENGTH (SPEECH_FRAME_MS_TO_LEN(16000, SPEECH_SCO_FRAME_MS)) +#define VOICEBTPCM_PCM_16K_QUEUE_SIZE (VOICEBTPCM_PCM_16k_FRAME_LENGTH*FRAME_NUM) + +#define VOICEBTPCM_PCM_8k_FRAME_LENGTH (SPEECH_FRAME_MS_TO_LEN(8000, SPEECH_SCO_FRAME_MS)) +#define VOICEBTPCM_PCM_8K_QUEUE_SIZE (VOICEBTPCM_PCM_8k_FRAME_LENGTH*FRAME_NUM) + +// #endif +CQueue voicebtpcm_p2m_pcm_queue; +CQueue voicebtpcm_m2p_pcm_queue; + +static int32_t voicebtpcm_p2m_cache_threshold; +static int32_t voicebtpcm_m2p_cache_threshold; + +static int32_t voicebtpcm_p2m_pcm_cache_size; +static int32_t voicebtpcm_m2p_pcm_cache_size; + +static enum APP_AUDIO_CACHE_T voicebtpcm_cache_m2p_status = APP_AUDIO_CACHE_QTY; +static enum APP_AUDIO_CACHE_T voicebtpcm_cache_p2m_status = APP_AUDIO_CACHE_QTY; + +extern bool bt_sco_codec_is_msbc(void); +#define ENCODE_TEMP_PCM_LEN (120) + +#define MSBC_FRAME_SIZE (60) +#if defined(HFP_1_6_ENABLE) +static btif_sbc_decoder_t msbc_decoder; +#if FPGA==1 +#define CFG_HW_AUD_EQ_NUM_BANDS (8) +const int8_t cfg_hw_aud_eq_band_settings[CFG_HW_AUD_EQ_NUM_BANDS] = {0, 0, 0, 0, 0, 0, 0, 0}; +#endif +static float msbc_eq_band_gain[CFG_HW_AUD_EQ_NUM_BANDS]= {0,0,0,0,0,0,0,0}; + +#define MSBC_ENCODE_PCM_LEN (240) + +unsigned char *temp_msbc_buf; +unsigned char *temp_msbc_buf1; + +#if defined(ENABLE_LPC_PLC) +LpcPlcState *msbc_plc_state = NULL; +#else +struct PLC_State msbc_plc_state; +#endif + +#ifdef ENABLE_PLC_ENCODER +static btif_sbc_encoder_t *msbc_plc_encoder; +static int16_t *msbc_plc_encoder_buffer = NULL; +#define MSBC_CODEC_DELAY (73) +static uint8_t enc_tmp_buf[MSBC_FRAME_SIZE - 3]; +static uint8_t dec_tmp_buf[MSBC_ENCODE_PCM_LEN]; +#endif + +//static sbc_encoder_t sbc_Encoder1; +//static btif_sbc_pcm_data_t PcmEncData1; +static btif_sbc_encoder_t *msbc_encoder; +static btif_sbc_pcm_data_t msbc_encoder_pcmdata; +static unsigned char msbc_counter = 0x08; +#endif + +int decode_msbc_frame(unsigned char *pcm_buffer, unsigned int pcm_len); +int decode_cvsd_frame(unsigned char *pcm_buffer, unsigned int pcm_len); + +//playback flow +//bt-->store_voicebtpcm_m2p_buffer-->decode_voicebtpcm_m2p_frame-->audioflinger playback-->speaker +//used by playback, store data from bt to memory +int store_voicebtpcm_m2p_buffer(unsigned char *buf, unsigned int len) +{ + //TRACE(2,"[%s]: %d", __FUNCTION__, FAST_TICKS_TO_US(hal_fast_sys_timer_get())); + int size; +#if defined(HFP_1_6_ENABLE) + if (bt_sco_codec_is_msbc()) + { + decode_msbc_frame(buf, len); + } + else +#endif + { +#if defined(CVSD_BYPASS) + decode_cvsd_frame(buf, len); +#endif + if(speech_plc){ + speech_plc_8000((PlcSt_8000 *)speech_plc, (short *)buf, len); + } + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_EnCQueue(&voicebtpcm_m2p_pcm_queue, (unsigned char *)buf, len); + UNLOCK_APP_AUDIO_QUEUE(); + } + + size = APP_AUDIO_LengthOfCQueue(&voicebtpcm_m2p_pcm_queue); + + if (size >= voicebtpcm_m2p_cache_threshold) + { + voicebtpcm_cache_m2p_status = APP_AUDIO_CACHE_OK; + } + + //TRACE(2,"m2p :%d/%d", len, size); + + return 0; +} + + +#if defined(CVSD_BYPASS) +#define VOICECVSD_TEMP_BUFFER_SIZE 120 +#define VOICECVSD_ENC_SIZE 60 +static short cvsd_decode_buff[VOICECVSD_TEMP_BUFFER_SIZE*2]; + +int decode_cvsd_frame(unsigned char *pcm_buffer, unsigned int pcm_len) +{ + uint32_t r = 0, decode_len = 0; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + + while (decode_len < pcm_len) + { + LOCK_APP_AUDIO_QUEUE(); + len1 = len2 = 0; + e1 = e2 = 0; + r = APP_AUDIO_PeekCQueue(&voicebtpcm_m2p_pcm_queue, VOICECVSD_TEMP_BUFFER_SIZE, &e1, &len1, &e2, &len2); + UNLOCK_APP_AUDIO_QUEUE(); + + if (r == CQ_ERR) + { + memset(pcm_buffer, 0, pcm_len); + TRACE(0,"cvsd spk buff underflow"); + return 0; + } + + if (len1 != 0) + { + CvsdToPcm8k(e1, (short *)(cvsd_decode_buff), len1, 0); + + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, len1); + UNLOCK_APP_AUDIO_QUEUE(); + + decode_len += len1*2; + } + + if (len2 != 0) + { + CvsdToPcm8k(e2, (short *)(cvsd_decode_buff), len2, 0); + + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, len2); + UNLOCK_APP_AUDIO_QUEUE(); + + decode_len += len2*2; + } + } + + memcpy(pcm_buffer, cvsd_decode_buff, decode_len); + + return decode_len; +} + +int encode_cvsd_frame(unsigned char *pcm_buffer, unsigned int pcm_len) +{ + uint32_t r = 0; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + uint32_t processed_len = 0; + uint32_t remain_len = 0, enc_len = 0; + + while (processed_len < pcm_len) + { + remain_len = pcm_len-processed_len; + + if (remain_len>=(VOICECVSD_ENC_SIZE*2)) + { + enc_len = VOICECVSD_ENC_SIZE*2; + } + else + { + enc_len = remain_len; + } + + LOCK_APP_AUDIO_QUEUE(); + len1 = len2 = 0; + e1 = e2 = 0; + r = APP_AUDIO_PeekCQueue(&voicebtpcm_p2m_pcm_queue, enc_len, &e1, &len1, &e2, &len2); + UNLOCK_APP_AUDIO_QUEUE(); + + if (r == CQ_ERR) + { + memset(pcm_buffer, 0x55, pcm_len); + TRACE(0,"cvsd spk buff underflow"); + return 0; + } + + if (e1) + { + Pcm8kToCvsd((short *)e1, (unsigned char *)(pcm_buffer + processed_len), len1/2); + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&voicebtpcm_p2m_pcm_queue, NULL, len1); + UNLOCK_APP_AUDIO_QUEUE(); + processed_len += len1; + } + if (e2) + { + Pcm8kToCvsd((short *)e2, (unsigned char *)(pcm_buffer + processed_len), len2/2); + LOCK_APP_AUDIO_QUEUE(); + DeCQueue(&voicebtpcm_p2m_pcm_queue, NULL, len2); + UNLOCK_APP_AUDIO_QUEUE(); + processed_len += len2; + } + } + +#if 0 + for (int cc = 0; cc < 32; ++cc) + { + TRACE(1,"%x-", e1[cc]); + } +#endif + + TRACE(3,"%s: processed_len %d, pcm_len %d", __func__, processed_len, pcm_len); + + return processed_len; +} +#endif + +#if defined(HFP_1_6_ENABLE) +inline int sco_parse_synchronization_header(uint8_t *buf, uint8_t *sn) +{ + uint8_t sn1, sn2; + *sn = 0xff; + if ((buf[0] != 0x01) || + ((buf[1]&0x0f) != 0x08) || + (buf[2] != 0xad)){ + return -1; + } + + sn1 = (buf[1]&0x30)>>4; + sn2 = (buf[1]&0xc0)>>6; + if ((sn1 != 0) && (sn1 != 0x3)){ + return -2; + } + if ((sn2 != 0) && (sn2 != 0x3)){ + return -3; + } + + *sn = (sn1&0x01)|(sn2&0x02); + + return 0; +} + +#if 1 +#define MSBC_LEN_FORMBT_PER_FRAME (120) //Bytes; only for BES platform. +#define SAMPLES_LEN_PER_FRAME (120) +#define MSBC_LEN_PER_FRAME (57+3) + +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) || defined(CHIP_BEST2001) +#define MSBC_MUTE_PATTERN (0x5555) +#else +#define MSBC_MUTE_PATTERN (0x0000) +#endif + +#if !defined(PENDING_MSBC_DECODER_ALG) +short DecPcmBuf[SAMPLES_LEN_PER_FRAME]; +unsigned char DecMsbcBuf[MSBC_LEN_PER_FRAME]; +unsigned short DecMsbcBufAll[MSBC_LEN_FORMBT_PER_FRAME*5]; +unsigned int next_frame_flag = 0; +static int msbc_find_first_sync = 0; +static unsigned int msbc_offset = 0; + +static PacketLossState pld; + +int decode_msbc_frame(unsigned char *msbc_btpcm_buffer, unsigned int msbc_len) +{ + + btif_sbc_pcm_data_t pcm_data; + unsigned int msbc_offset_lowdelay = 0; + unsigned int i,j; + unsigned short *msbc_buffer=(unsigned short *)msbc_btpcm_buffer; + int frame_flag[6]; // 1: good frame; 0:bad frame; + bt_status_t ret; + unsigned int frame_counter=0; + unsigned short byte_decode = 0; + unsigned int msbc_offset_total = 0; + int msbc_offset_drift[6] = {0, }; + + //unsigned int timer_begin=hal_sys_timer_get(); + + //TRACE(1,"decode_msbc_frame,msbc_len:%d",msbc_len); +#ifdef TX_RX_PCM_MASK + if(btdrv_is_pcm_mask_enable() ==1) + { + memcpy((uint8_t *)DecMsbcBufAll,msbc_buffer,msbc_len); + } + else +#endif + { + for(i =0; i=msbc_offset_total) + frame_flag[j]=3; + else + frame_flag[j]=1; + } + } + } + + } +#ifdef TX_RX_PCM_MASK + if(btdrv_is_pcm_mask_enable() ==0) +#endif + { + for(j =0; j1)msbc_find_first_sync=0; + } + } + + while(frame_counter>8; + DecMsbcBuf[i]=DecMsbcBufAll[i+msbc_offset_lowdelay+msbc_offset_drift[frame_counter]+frame_counter*(MSBC_LEN_FORMBT_PER_FRAME/2)]>>8; + } + + //TRACE(1,"msbc header:0x%x",DecMsbcBuf[0]); + +#ifdef SPEECH_RX_PLC_DUMP_DATA + audio_dump_add_channel_data(2, (short *)DecMsbcBuf, MSBC_LEN_PER_FRAME/2); +#endif + + plc_type_t plc_type = packet_loss_detection_process(&pld, DecMsbcBuf); + + if(plc_type != PLC_TYPE_PASS) { + memset(DecPcmBuf, 0, sizeof(DecPcmBuf)); + goto do_plc; + } + + pcm_data.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + pcm_data.numChannels = 1; + pcm_data.dataLen = 0; + pcm_data.data = (uint8_t *)DecPcmBuf; + + ret = btif_sbc_decode_frames(&msbc_decoder, + (unsigned char *)DecMsbcBuf, + MSBC_LEN_PER_FRAME, &byte_decode, + &pcm_data, SAMPLES_LEN_PER_FRAME*2, + msbc_eq_band_gain); + + //ASSERT(ret == BT_STS_SUCCESS, "[%s] msbc decoder should never fail", __FUNCTION__); + if (ret != BT_STS_SUCCESS) { + plc_type = PLC_TYPE_DECODER_ERROR; + packet_loss_detection_update_histogram(&pld, plc_type); + } + +do_plc: + if (plc_type == PLC_TYPE_PASS) { +#if defined(ENABLE_LPC_PLC) + lpc_plc_save(msbc_plc_state, DecPcmBuf); +#else + PLC_good_frame(&msbc_plc_state, DecPcmBuf, DecPcmBuf); +#endif +#ifdef SPEECH_RX_PLC_DUMP_DATA + audio_dump_add_channel_data(0, (short *)DecPcmBuf, MSBC_ENCODE_PCM_LEN/2); +#endif + } + else + { + TRACE(1,"PLC bad frame, plc_type: %d", plc_type); +#if defined(PLC_DEBUG_PRINT_DATA) + DUMP8("0x%02x, ", DecMsbcBuf, 60); +#endif +#ifdef SPEECH_RX_PLC_DUMP_DATA + for(uint32_t i=0; i< MSBC_ENCODE_PCM_LEN/2; i++) + { + audio_dump_temp_buf[i] = (plc_type - 1) * 5000; + } + audio_dump_add_channel_data(0, audio_dump_temp_buf, MSBC_ENCODE_PCM_LEN/2); +#endif +#if defined(ENABLE_LPC_PLC) + lpc_plc_generate(msbc_plc_state, DecPcmBuf, +#if defined(ENABLE_PLC_ENCODER) + msbc_plc_encoder_buffer +#else + NULL +#endif + ); + +#if defined(ENABLE_PLC_ENCODER) + pcm_data.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + pcm_data.numChannels = 1; + pcm_data.dataLen = MSBC_ENCODE_PCM_LEN; + pcm_data.data = (uint8_t *)(msbc_plc_encoder_buffer + MSBC_CODEC_DELAY); + + uint16_t encoded_bytes = 0, buf_len = MSBC_FRAME_SIZE - 3; + ret = btif_sbc_encode_frames(msbc_plc_encoder, &pcm_data, &encoded_bytes, enc_tmp_buf, &buf_len, 0xFFFF); + ASSERT(ret == BT_STS_SUCCESS, "[%s] plc encoder must success", __FUNCTION__); + ASSERT(encoded_bytes == MSBC_ENCODE_PCM_LEN, "[%s] plc encoder encoded bytes error", __FUNCTION__); + ASSERT(buf_len == MSBC_FRAME_SIZE - 3, "[%s] plc encoder encoded stream length error", __FUNCTION__); + + pcm_data.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + pcm_data.numChannels = 1; + pcm_data.dataLen = 0; + pcm_data.data = dec_tmp_buf; + ret = btif_sbc_decode_frames(&msbc_decoder, enc_tmp_buf, MSBC_FRAME_SIZE - 3, &byte_decode, &pcm_data, MSBC_ENCODE_PCM_LEN, msbc_eq_band_gain); + ASSERT(ret == BT_STS_SUCCESS, "[%s] plc decoder must success", __FUNCTION__); + ASSERT(byte_decode == MSBC_FRAME_SIZE - 3, "[%s] plc decoder decoded bytes error", __FUNCTION__); +#endif + +#else + pcm_data.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + pcm_data.numChannels = 1; + pcm_data.dataLen = 0; + pcm_data.data = (uint8_t *)DecPcmBuf; + + ret = btif_sbc_decode_frames(&msbc_decoder, + (unsigned char *)indices0, + MSBC_LEN_PER_FRAME, &byte_decode, + &pcm_data, SAMPLES_LEN_PER_FRAME*2, + msbc_eq_band_gain); + + PLC_bad_frame(&msbc_plc_state, DecPcmBuf, DecPcmBuf); + + ASSERT(ret == BT_STS_SUCCESS, "[%s] msbc decoder should never fail", __FUNCTION__); +#endif + } + +#ifdef SPEECH_RX_PLC_DUMP_DATA + audio_dump_add_channel_data(1, (short *)DecPcmBuf, MSBC_ENCODE_PCM_LEN/2); + audio_dump_run(); +#endif + + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_EnCQueue(&voicebtpcm_m2p_pcm_queue, (unsigned char *)DecPcmBuf, (unsigned int)(SAMPLES_LEN_PER_FRAME*2)); + UNLOCK_APP_AUDIO_QUEUE(); + frame_counter++; + } +#ifdef TX_RX_PCM_MASK + if(btdrv_is_pcm_mask_enable() ==0) +#endif + { + for(i =0; i MSBC_LEN_PER_FRAME*2) + msbc_queue_len = MSBC_LEN_PER_FRAME*2; + else if(msbc_queue_len < MSBC_LEN_PER_FRAME) + return 0; + + r = APP_AUDIO_PeekCQueue(&msbc_temp_queue, msbc_queue_len, &e1, &len1, &e2, &len2); + if(r == CQ_OK) + { + if (len1) + { + memcpy(DecVerifyMsbcBuf, e1, len1); + } + if (len2 != 0) + { + memcpy(DecVerifyMsbcBuf + len1, e2, len2); + } + }else{ + //can't happen + + } + + //DUMP8("%02x", DecVerifyMsbcBuf, msbc_queue_len); + //find sync head + for(int i = 0; i < (msbc_queue_len - 3); i ++){ + //verify sync success + if(sco_parse_synchronization_header(DecVerifyMsbcBuf + i, &sync_num) >= 0){ + verify_result = 1; + msbc_sync_offset = i; + break; + } + } + TRACE(3,"%02x %02x %02x", (DecVerifyMsbcBuf +msbc_sync_offset)[0], + (DecVerifyMsbcBuf +msbc_sync_offset)[1], + (DecVerifyMsbcBuf +msbc_sync_offset)[2]); + TRACE(5,"msbc:%d %d %d %d %d\n", + verify_result, + msbc_queue_len, + msbc_sync_offset, + last_msbc_sync_num, + sync_num); + + if(!verify_result){ + //remove msbc frame remain 3 byted as it may include syn head + APP_AUDIO_DeCQueue(&msbc_temp_queue, 0, msbc_queue_len - 3); + goto msbc_find_sync_again; + }else{ + //remove invalid msbc frame space + APP_AUDIO_DeCQueue(&msbc_temp_queue, 0, msbc_sync_offset); + if(msbc_sync_offset >= MSBC_LEN_PER_FRAME) + goto msbc_find_sync_again; + } + + //cal plc number + if((last_msbc_sync_num + 1)%4 == sync_num){ + plc_num = 0; + }else{ + for(int i = 0; i < 4; i ++){ + if((last_msbc_sync_num + i)%4 == sync_num){ + break; + } + plc_num ++; + } + } + last_msbc_sync_num = sync_num; + + //failed check sync should do plc + if(plc_num > 0){ + for(int i = 0; i < plc_num; i ++){ + ret = btif_sbc_decode_frames(&msbc_decoder, + (unsigned char *)indices0, + MSBC_LEN_PER_FRAME, &byte_decode, + &pcm_data, SAMPLES_LEN_PER_FRAME*2, + msbc_eq_band_gain); + + if (ret == BT_STS_SUCCESS) + { + TRACE(1,"PLC bad frame:%d\n", ret); + //timer_begin=hal_sys_timer_get(); + PLC_bad_frame(&msbc_plc_state, DecPcmBuf, DecPcmBuf); + //TRACE(1,"msbc + plc:%d", (hal_sys_timer_get()-timer_begin)); + pcm_data.data = (unsigned char*)DecPcmBuf; + pcm_data.dataLen = 0; + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_EnCQueue(&voicebtpcm_m2p_pcm_queue, + (unsigned char *)DecPcmBuf, + (unsigned int)(SAMPLES_LEN_PER_FRAME*2)); + UNLOCK_APP_AUDIO_QUEUE(); + } + else + { + ASSERT(0, "ERROR inices0", __func__); + } + } + } + + { + ret = btif_sbc_decode_frames(&msbc_decoder, + (unsigned char *)DecVerifyMsbcBuf + msbc_sync_offset + 2, + MSBC_LEN_PER_FRAME, &byte_decode, + &pcm_data, SAMPLES_LEN_PER_FRAME*2, + msbc_eq_band_gain); + + if (ret == BT_STS_SUCCESS) + { + PLC_good_frame(&msbc_plc_state, DecPcmBuf, DecPcmBuf); + pcm_data.data = (unsigned char*)DecPcmBuf; + pcm_data.dataLen = 0; + } + else + { + TRACE(1,"PLC bad frame:%d\n"); + PLC_bad_frame(&msbc_plc_state, DecPcmBuf, DecPcmBuf); + pcm_data.data = (unsigned char*)DecPcmBuf; + pcm_data.dataLen = 0; + TRACE(1,"ERROR msbc frame!ret:%d\n",ret); + } + //remove msbc frame + APP_AUDIO_DeCQueue(&msbc_temp_queue, 0, MSBC_LEN_PER_FRAME); + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_EnCQueue(&voicebtpcm_m2p_pcm_queue, + (unsigned char *)DecPcmBuf, + (unsigned int)(SAMPLES_LEN_PER_FRAME*2)); + UNLOCK_APP_AUDIO_QUEUE(); + frame_decode_num ++; + if(frame_decode_num <= (msbc_len/(MSBC_LEN_PER_FRAME*2) - 1)) + goto msbc_find_sync_again; + } + return 0; +} +#endif // #if !defined(PENDING_MSBC_DECODER_ALG) + +#else +int decode_msbc_frame(unsigned char *pcm_buffer, unsigned int pcm_len) +{ + int ttt = 0; + //int t = 0; + uint8_t underflow = 0; +#if defined(MSBC_PLC_ENABLE) + uint8_t plc_type = 0; + uint8_t need_check_pkt = 1; + uint8_t msbc_raw_sn = 0xff; + static uint8_t msbc_raw_sn_pre; + static uint8_t msbc_raw_sn_pre2; + static bool msbc_find_first_sync = 0; +#endif + int r = 0; + unsigned char *e1 = NULL, *e2 = NULL, *msbc_buff = NULL; + unsigned int len1 = 0, len2 = 0; + static btif_sbc_pcm_data_t pcm_data; + static unsigned int msbc_next_frame_size; + bt_status_t ret = BT_STS_SUCCESS; + unsigned short byte_decode = 0; + + unsigned int pcm_offset = 0; + unsigned int pcm_processed = 0; + +#if defined(MSBC_PLC_ENABLE) + pcm_data.data = (unsigned char*)msbc_buf_before_plc; +#else + pcm_data.data = (unsigned char*)pcm_buffer; +#endif + if (!msbc_next_frame_size) + { + msbc_next_frame_size = MSBC_FRAME_SIZE; + } + +//reinit: + if(need_init_decoder) + { + TRACE(0,"init msbc decoder\n"); + pcm_data.data = (unsigned char*)(pcm_buffer + pcm_offset); + pcm_data.dataLen = 0; + + btif_sbc_init_decoder(&msbc_decoder); + + msbc_decoder.streamInfo.mSbcFlag = 1; + msbc_decoder.streamInfo.bitPool = 26; + msbc_decoder.streamInfo.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + msbc_decoder.streamInfo.channelMode = BTIF_SBC_CHNL_MODE_MONO; + msbc_decoder.streamInfo.allocMethod = BTIF_SBC_ALLOC_METHOD_LOUDNESS; + /* Number of blocks used to encode the stream (4, 8, 12, or 16) */ + msbc_decoder.streamInfo.numBlocks = BTIF_MSBC_BLOCKS; + /* The number of subbands in the stream (4 or 8) */ + msbc_decoder.streamInfo.numSubBands = 8; + msbc_decoder.streamInfo.numChannels = 1; +#if defined(MSBC_PLC_ENCODER) + btif_sbc_init_encoder(&sbc_Encoder1); + sbc_Encoder1.streamInfo.mSbcFlag = 1; + sbc_Encoder1.streamInfo.numChannels = 1; + sbc_Encoder1.streamInfo.channelMode = BTIF_SBC_CHNL_MODE_MONO; + + sbc_Encoder1.streamInfo.bitPool = 26; + sbc_Encoder1.streamInfo.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + sbc_Encoder1.streamInfo.allocMethod = BTIF_SBC_ALLOC_METHOD_LOUDNESS; + sbc_Encoder1.streamInfo.numBlocks = BTIF_MSBC_BLOCKS; + sbc_Encoder1.streamInfo.numSubBands = 8; + +#endif +#if defined(MSBC_PLC_ENABLE) + InitPLC(&msbc_plc_state); + msbc_need_check_sync_header = 0; + msbc_raw_sn_pre = 0xff; + msbc_raw_sn_pre2 = 0xff; + msbc_find_first_sync = true; +#endif + } + +#if defined(MSBC_PLC_ENABLE) + need_check_pkt = 1; +#endif + msbc_buff = msbc_buf_before_decode; + +get_again: + LOCK_APP_AUDIO_QUEUE(); + len1 = len2 = 0; + e1 = e2 = 0; + r = APP_AUDIO_PeekCQueue(&voicebtpcm_m2p_pcm_queue, msbc_next_frame_size, &e1, &len1, &e2, &len2); + UNLOCK_APP_AUDIO_QUEUE(); + + if (r == CQ_ERR) + { + pcm_processed = pcm_len; + memset(pcm_buffer, 0, pcm_len); + TRACE(0,"msbc spk buff underflow"); + goto exit; + } + + if (!len1) + { + TRACE(2,"len1 underflow %d/%d\n", len1, len2); + goto get_again; + } + + if (len1 > 0 && e1) + { + memcpy(msbc_buff, e1, len1); + } + if (len2 > 0 && e2) + { + memcpy(msbc_buff + len1, e2, len2); + } + + if (msbc_find_first_sync){ + + for(uint8_t i=0;i 0 && sync_offset != (MSBC_FRAME_SIZE - 3)) + { + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, sync_offset); + UNLOCK_APP_AUDIO_QUEUE(); + TRACE(1,"fix sync:%d", sync_offset); + msbc_raw_sn_pre = (msbc_raw_sn+3)%4; // Find pre sn + msbc_raw_sn_pre2 = msbc_raw_sn_pre; + goto get_again; + //TRACE(4,"***msbc_need_check_sync %d :%x %x %x\n", sync_offset, msbc_buf_before_decode[0], + // msbc_buf_before_decode[1], + // msbc_buf_before_decode[2]); + } + else if(sync_offset == (MSBC_FRAME_SIZE - 3)) + { + //APP_AUDIO_DeCQueue(&voicebtpcm_m2p_queue, 0, sync_offset); + //just jump sync length + padding length(1byte) + //will in plc again, so can check sync again + //TRACE(4,"***msbc_need_check_sync %d :%x %x %x\n", sync_offset, msbc_buf_before_decode[0], + // msbc_buf_before_decode[1], + // msbc_buf_before_decode[2]); + msbc_next_frame_size = (MSBC_FRAME_SIZE - 3) - 1; + }else if (!sync_offset){ + + }else{ + TRACE(1,"3 msbc_need_check_sync %d\n", sync_offset); + } + } + // 0 - normal decode without plc proc, 1 - normal decode with plc proc, 2 - special decode with plc proc + plc_type = 0; + + if (msbc_can_plc) + { + if (sco_parse_synchronization_header(msbc_buf_before_decode, &msbc_raw_sn)){ + plc_type = 2; + msbc_need_check_sync_header = 1; + }else{ + plc_type = 1; + } + } + else + { + plc_type = 0; + } + + if (msbc_raw_sn_pre == 0xff){ + // do nothing + msbc_raw_sn_pre = msbc_raw_sn; + }else{ + if (((msbc_raw_sn_pre+1)%4) == msbc_raw_sn){ + // do nothing + msbc_raw_sn_pre = msbc_raw_sn; + }else if (msbc_raw_sn == 0xff){ + TRACE(1,"sbchd err:%d", MSBC_FRAME_SIZE-3); + msbc_need_check_sync_header = 1; + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, MSBC_FRAME_SIZE-3); + UNLOCK_APP_AUDIO_QUEUE(); + msbc_raw_sn_pre = (msbc_raw_sn_pre+1)%4; + plc_type = 2; + }else{ + TRACE(2,"seq err:%d/%d", msbc_raw_sn, msbc_raw_sn_pre); + msbc_need_check_sync_header = 1; + plc_type = 2; + msbc_raw_sn_pre = (msbc_raw_sn_pre+1)%4; + } + } + + need_check_pkt = 0; + } + //TRACE(3,"type %d, seqno 0x%x, q_space %d\n", plc_type, cur_pkt_seqno, APP_AUDIO_AvailableOfCQueue(&voicebtpcm_m2p_queue)); +#endif + + //DUMP8("%02x ", msbc_buf_before_decode, msbc_next_frame_size); + //TRACE(0,"\n"); + +#if defined(MSBC_PLC_ENABLE) + if (plc_type == 1) + { + ret = btif_sbc_decode_frames(&msbc_decoder, (unsigned char *)msbc_buf_before_decode, + msbc_next_frame_size, &byte_decode, + &pcm_data, pcm_len - pcm_offset, + msbc_eq_band_gain); + + ttt = hal_sys_timer_get(); +#if defined(MSBC_PCM_PLC_ENABLE) + speech_plc_16000_AddToHistory((PlcSt_16000 *)speech_plc, (short *)pcm_data.data, pcm_len/2); + memcpy(pcm_buffer, pcm_data.data, pcm_len); +#else + PLC_good_frame(&msbc_plc_state, (short *)pcm_data.data, (short *)pcm_buffer); +#endif +#ifdef SPEECH_RX_PLC_DUMP_DATA + audio_dump_add_channel_data(0, (short *)pcm_buffer, pcm_len/2); +#endif + } + else if (plc_type == 2) + { +#if defined(MSBC_PCM_PLC_ENABLE) + ret = BT_STS_SUCCESS; + ttt = hal_sys_timer_get(); +#if defined(MSBC_PLC_ENCODER) + speech_plc_16000_Dofe((PlcSt_16000 *)speech_plc, (short *)pcm_buffer, EncInBuf, pcm_len/2); +#else + speech_plc_16000_Dofe((PlcSt_16000 *)speech_plc, (short *)pcm_buffer, NULL, pcm_len/2); +#endif +#else + PLC_bad_frame(&msbc_plc_state, (short *)pcm_data.data, (short *)pcm_buffer); +#endif +#if defined(MSBC_PLC_ENCODER) + { + uint16_t bytes_encoded = 0, buf_len = MSBC_ENCODE_PCM_LEN; + PcmEncData1.data = (uint8_t *)(EncInBuf+MSBC_ENC_BUFFER_OFFSET); + PcmEncData1.dataLen = pcm_len; + PcmEncData1.numChannels = 1; + PcmEncData1.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + btif_sbc_encode_frames(&sbc_Encoder1, &PcmEncData1, &bytes_encoded, Encodedbuf1, &buf_len, 0xFFFF); + #ifdef __SBC_FUNC_IN_ROM__ + ret = SBC_ROM_FUNC.sbc_frames_decode(&msbc_decoder, Encodedbuf1, MSBC_FRAME_SIZE-3, &byte_decode, + &pcm_data, pcm_len - pcm_offset, msbc_eq_band_gain); + #else + ret = btif_sbc_decode_frames(&msbc_decoder, Encodedbuf1, MSBC_FRAME_SIZE-3, &byte_decode, + &pcm_data, pcm_len - pcm_offset, msbc_eq_band_gain); + #endif + + } +#endif + TRACE(2,"b t:%d ret:%d\n", (hal_sys_timer_get()-ttt), ret); +#ifdef SPEECH_RX_PLC_DUMP_DATA + for(uint32_t i=0; i< pcm_len/2; i++) + { + audio_dump_temp_buf[i] = 32767; + } + audio_dump_add_channel_data(0, audio_dump_temp_buf, pcm_len/2); +#endif + } + else +#endif + { + ret = btif_sbc_decode_frames(&msbc_decoder, (unsigned char *)msbc_buf_before_decode, + msbc_next_frame_size, &byte_decode, + &pcm_data, pcm_len - pcm_offset, + msbc_eq_band_gain); +#if defined(MSBC_PCM_PLC_ENABLE) + speech_plc_16000_AddToHistory((PlcSt_16000 *)speech_plc, (short *)pcm_data.data, pcm_len/2); + memcpy(pcm_buffer, pcm_data.data, pcm_len); +#endif +#ifdef SPEECH_RX_PLC_DUMP_DATA + for(uint32_t i=0; i< pcm_len/2; i++) + { + audio_dump_temp_buf[i] = -32767; + } + audio_dump_add_channel_data(0, audio_dump_temp_buf, pcm_len/2); +#endif + } + +#ifdef SPEECH_RX_PLC_DUMP_DATA + audio_dump_add_channel_data(1, (short *)pcm_buffer, pcm_len/2); + audio_dump_run(); +#endif + +#if 0 + TRACE(1,"[0] %x", msbc_buf_before_decode[0]); + TRACE(1,"[1] %x", msbc_buf_before_decode[1]); + TRACE(1,"[2] %x", msbc_buf_before_decode[2]); + TRACE(1,"[3] %x", msbc_buf_before_decode[3]); + TRACE(1,"[4] %x", msbc_buf_before_decode[4]); +#endif + + //TRACE(2,"sbcd ret %d %d\n", ret, byte_decode); + + if(ret == BT_STS_CONTINUE) + { + need_init_decoder = false; + LOCK_APP_AUDIO_QUEUE(); + VOICEBTPCM_TRACE(2,"000000 byte_decode =%d, current_len1 =%d",byte_decode, msbc_next_frame_size); + APP_AUDIO_DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, byte_decode); + UNLOCK_APP_AUDIO_QUEUE(); + + msbc_next_frame_size = (MSBC_FRAME_SIZE -byte_decode)>0?(MSBC_FRAME_SIZE -byte_decode):MSBC_FRAME_SIZE; + goto get_again; + } + + else if(ret == BT_STS_SUCCESS) + { + need_init_decoder = false; + pcm_processed = pcm_data.dataLen; + pcm_data.dataLen = 0; + + LOCK_APP_AUDIO_QUEUE(); +#if defined(MSBC_PLC_ENABLE) + if (plc_type == 0) + { + byte_decode += 1;//padding + APP_AUDIO_DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, byte_decode); + } + else + { +#if defined(MSBC_PCM_PLC_ENABLE) + if (plc_type == 2){ + pcm_processed = pcm_len; + }else{ + if(msbc_next_frame_size < MSBC_FRAME_SIZE) + msbc_next_frame_size += 1; //padding + APP_AUDIO_DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, msbc_next_frame_size); + } +#else + if(msbc_next_frame_size < MSBC_FRAME_SIZE) + msbc_next_frame_size += 1; //padding + APP_AUDIO_DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, msbc_next_frame_size); +#endif + } +#else + if(msbc_next_frame_size < MSBC_FRAME_SIZE) + msbc_next_frame_size += 1; //padding + APP_AUDIO_DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, msbc_next_frame_size); +#endif + UNLOCK_APP_AUDIO_QUEUE(); + + msbc_next_frame_size = MSBC_FRAME_SIZE; + +#if defined(MSBC_PLC_ENABLE) + // plc after a good frame + if (!msbc_can_plc) + { + msbc_can_plc = true; + } +#endif + } + else if(ret == BT_STS_FAILED) + { + need_init_decoder = true; + pcm_processed = pcm_len; + pcm_data.dataLen = 0; + + memset(pcm_buffer, 0, pcm_len); + TRACE(1,"err mutelen:%d\n",pcm_processed); + + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, byte_decode); + UNLOCK_APP_AUDIO_QUEUE(); + + msbc_next_frame_size = MSBC_FRAME_SIZE; + + /* leave */ + } + else if(ret == BT_STS_NO_RESOURCES) + { + need_init_decoder = true; + pcm_processed = pcm_len; + pcm_data.dataLen = 0; + + memset(pcm_buffer, 0, pcm_len); + TRACE(1,"no_res mutelen:%d\n",pcm_processed); + + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, byte_decode); + UNLOCK_APP_AUDIO_QUEUE(); + + msbc_next_frame_size = MSBC_FRAME_SIZE; + } + +exit: + if (underflow||need_init_decoder) + { + TRACE(2,"media_msbc_decoder underflow len:%d,need_init_decoder=%d\n ", pcm_len,need_init_decoder); + } + +// TRACE(1,"pcm_processed %d", pcm_processed); + + return pcm_processed; +} +#endif + +#endif + +//capture flow +//mic-->audioflinger capture-->store_voicebtpcm_p2m_buffer-->get_voicebtpcm_p2m_frame-->bt +//used by capture, store data from mic to memory +int store_voicebtpcm_p2m_buffer(unsigned char *buf, unsigned int len) +{ + int POSSIBLY_UNUSED size; + unsigned int avail_size = 0; + LOCK_APP_AUDIO_QUEUE(); +// merge_two_trace_to_one_track_16bits(0, (uint16_t *)buf, (uint16_t *)buf, len>>1); +// r = APP_AUDIO_EnCQueue(&voicebtpcm_p2m_queue, buf, len>>1); + avail_size = APP_AUDIO_AvailableOfCQueue(&voicebtpcm_p2m_pcm_queue); + if (len <= avail_size) + { + APP_AUDIO_EnCQueue(&voicebtpcm_p2m_pcm_queue, buf, len); + } + else + { + VOICEBTPCM_TRACE(2,"mic buff overflow %d/%d", len, avail_size); + APP_AUDIO_DeCQueue(&voicebtpcm_p2m_pcm_queue, 0, len - avail_size); + APP_AUDIO_EnCQueue(&voicebtpcm_p2m_pcm_queue, buf, len); + } + size = APP_AUDIO_LengthOfCQueue(&voicebtpcm_p2m_pcm_queue); + UNLOCK_APP_AUDIO_QUEUE(); + + VOICEBTPCM_TRACE(2,"p2m :%d/%d", len, size); + + return 0; +} + +#if defined(HFP_1_6_ENABLE) +unsigned char get_msbc_counter(void) +{ + if (msbc_counter == 0x08) + { + msbc_counter = 0x38; + } + else if (msbc_counter == 0x38) + { + msbc_counter = 0xC8; + } + else if (msbc_counter == 0xC8) + { + msbc_counter = 0xF8; + } + else if (msbc_counter == 0xF8) + { + msbc_counter = 0x08; + } + + return msbc_counter; +} +#endif + +#if defined(TX_RX_PCM_MASK) +CQueue Tx_esco_queue; +CQueue Rx_esco_queue; +CQueue* get_tx_esco_queue_ptr() +{ + return &Tx_esco_queue; +} +CQueue* get_rx_esco_queue_ptr() +{ + return &Rx_esco_queue; +} + +#endif + +//used by capture, get the memory data which has be stored by store_voicebtpcm_p2m_buffer() +int get_voicebtpcm_p2m_frame(unsigned char *buf, unsigned int len) +{ + int got_len = 0; + + // TRACE(2,"[%s] pcm_len = %d", __func__, len / 2); + if (voicebtpcm_cache_p2m_status == APP_AUDIO_CACHE_CACHEING) + { + app_audio_memset_16bit((short *)buf, 0, len/2); + TRACE(1,"[%s] APP_AUDIO_CACHE_CACHEING", __func__); + return len; + } + + int msbc_encode_temp_len = MSBC_FRAME_SIZE * 2; + + ASSERT(len % msbc_encode_temp_len == 0 , "[%s] len(%d) is invalid", __func__, len); + + int loop_cnt = len / msbc_encode_temp_len; + len = msbc_encode_temp_len; + + for (int cnt=0; cntmax0) + { + max0 = buf[i+0]; + } + + if(buf[i+0]max1) + { + max1 = buf[i+1]; + } + + if(buf[i+1]48K +single phase coef Number:=24, upsample factor:=6, + 64, -311, 210, -320, 363, -407, 410, -356, 196, 191,-1369,30721, 3861,-2265, 1680,-1321, 1049, -823, 625, -471, 297, -327, 34, 19, + 72, -254, 75, -117, 46, 58, -256, 583,-1141, 2197,-4866,28131,10285,-4611, 2935,-2061, 1489,-1075, 755, -523, 310, -291, -19, 31, + 65, -175, -73, 84, -245, 457, -786, 1276,-2040, 3377,-6428,23348,17094,-6200, 3592,-2347, 1588,-1073, 703, -447, 236, -203, -92, 49, + 49, -92, -203, 236, -447, 703,-1073, 1588,-2347, 3592,-6200,17094,23348,-6428, 3377,-2040, 1276, -786, 457, -245, 84, -73, -175, 65, + 31, -19, -291, 310, -523, 755,-1075, 1489,-2061, 2935,-4611,10285,28131,-4866, 2197,-1141, 583, -256, 58, 46, -117, 75, -254, 72, + 19, 34, -327, 297, -471, 625, -823, 1049,-1321, 1680,-2265, 3861,30721,-1369, 191, 196, -356, 410, -407, 363, -320, 210, -311, 64, +*/ + +const static short coef_8k_upto_48k[6][US_COEF_NUM]__attribute__((section(".sram_data"))) = +{ + {64, -311, 210, -320, 363, -407, 410, -356, 196, 191,-1369,30721, 3861,-2265, 1680,-1321, 1049, -823, 625, -471, 297, -327, 34, 19}, + {72, -254, 75, -117, 46, 58, -256, 583,-1141, 2197,-4866,28131,10285,-4611, 2935,-2061, 1489,-1075, 755, -523, 310, -291, -19, 31 }, + {65, -175, -73, 84, -245, 457, -786, 1276,-2040, 3377,-6428,23348,17094,-6200, 3592,-2347, 1588,-1073, 703, -447, 236, -203, -92, 49 }, + {49, -92, -203, 236, -447, 703,-1073, 1588,-2347, 3592,-6200,17094,23348,-6428, 3377,-2040, 1276, -786, 457, -245, 84, -73, -175, 65 }, + {31, -19, -291, 310, -523, 755,-1075, 1489,-2061, 2935,-4611,10285,28131,-4866, 2197,-1141, 583, -256, 58, 46, -117, 75, -254, 72 }, + {19, 34, -327, 297, -471, 625, -823, 1049,-1321, 1680,-2265, 3861,30721,-1369, 191, 196, -356, 410, -407, 363, -320, 210, -311, 64 } +}; + +/* +16K -->48K + +single phase coef Number:=24, upsample factor:=3, + 1, -291, 248, -327, 383, -405, 362, -212, -129, 875,-2948,29344, 7324,-3795, 2603,-1913, 1418,-1031, 722, -478, 292, -220, -86, 16, + 26, -212, 6, 45, -185, 414, -764, 1290,-2099, 3470,-6431,20320,20320,-6431, 3470,-2099, 1290, -764, 414, -185, 45, 6, -212, 26, + 16, -86, -220, 292, -478, 722,-1031, 1418,-1913, 2603,-3795, 7324,29344,-2948, 875, -129, -212, 362, -405, 383, -327, 248, -291, 1, +*/ + +const static short coef_16k_upto_48k[3][US_COEF_NUM] __attribute__((section(".sram_data"))) = +{ + {1, -291, 248, -327, 383, -405, 362, -212, -129, 875,-2948,29344, 7324,-3795, 2603,-1913, 1418,-1031, 722, -478, 292, -220, -86, 16}, + {26, -212, 6, 45, -185, 414, -764, 1290,-2099, 3470,-6431,20320,20320,-6431, 3470,-2099, 1290, -764, 414, -185, 45, 6, -212, 26}, + {16, -86, -220, 292, -478, 722,-1031, 1418,-1913, 2603,-3795, 7324,29344,-2948, 875, -129, -212, 362, -405, 383, -327, 248, -291, 1} +}; + +static short us_para_lst[US_COEF_NUM-1]; + +static inline short us_get_coef_para(U32 samp_idx,U32 coef_idx) +{ + if(bt_sco_samplerate_ratio == 6) + return coef_8k_upto_48k[samp_idx][coef_idx]; + else + return coef_16k_upto_48k[samp_idx][coef_idx]; +} + +void us_fir_init (void) +{ + app_audio_memset_16bit(us_para_lst, 0, sizeof(us_para_lst)/sizeof(short)); +} + + +__attribute__((section(".fast_text_sram"))) U32 us_fir_run (short* src_buf, short* dst_buf, U32 in_samp_num) +{ + U32 in_idx, samp_idx, coef_idx, real_idx, out_idx; + int para, out; + + for (in_idx = 0, out_idx = 0; in_idx < in_samp_num; in_idx++) + { + for (samp_idx = 0; samp_idx < bt_sco_samplerate_ratio; samp_idx++) + { + out = 0; + for (coef_idx = 0; coef_idx < US_COEF_NUM; coef_idx++) + { + real_idx = coef_idx + in_idx; + para = (real_idx < (US_COEF_NUM-1))?us_para_lst[real_idx]:src_buf[real_idx - (US_COEF_NUM-1)]; + out += para * us_get_coef_para(samp_idx,coef_idx); + } + + dst_buf[out_idx] = (short)(out>>16); + out_idx++; + } + } + + if (in_samp_num >= (US_COEF_NUM-1)) + { + app_audio_memcpy_16bit(us_para_lst, + (src_buf+in_samp_num-US_COEF_NUM+1), + (US_COEF_NUM-1)); + } + else + { + U32 start_idx = (US_COEF_NUM-1-in_samp_num); + + app_audio_memcpy_16bit(us_para_lst, + (us_para_lst+in_samp_num), + start_idx); + + app_audio_memcpy_16bit((us_para_lst + start_idx), + src_buf, + in_samp_num); + } + return out_idx; +} + +uint32_t voicebtpcm_pcm_resample (short* src_samp_buf, uint32_t src_smpl_cnt, short* dst_samp_buf) +{ + return us_fir_run (src_samp_buf, dst_samp_buf, src_smpl_cnt); +} + +#endif + +static int speech_tx_aec_frame_len = 0; + +int speech_tx_aec_get_frame_len(void) +{ + return speech_tx_aec_frame_len; +} + +void speech_tx_aec_set_frame_len(int len) +{ + TRACE(2,"[%s] len = %d", __func__, len); + speech_tx_aec_frame_len = len; +} + +#if 1 +//used by capture, store data from mic to memory +uint32_t voicebtpcm_pcm_audio_data_come(uint8_t *buf, uint32_t len) +{ + int16_t POSSIBLY_UNUSED ret = 0; + bool POSSIBLY_UNUSED vdt = false; + int size = 0; + +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + uint32_t queue_len; + + uint32_t len_per_channel = len / SPEECH_CODEC_CAPTURE_CHANNEL_NUM; + + ASSERT(len_per_channel == speech_tx_aec_get_frame_len() * sizeof(short), "%s: Unmatched len: %u != %u", __func__, len_per_channel, speech_tx_aec_get_frame_len() * sizeof(short)); + ASSERT(echo_buf_q_rpos + len_per_channel <= echo_buf_q_size, "%s: rpos (%u) overflow: len=%u size=%u", __func__, echo_buf_q_rpos, len_per_channel, echo_buf_q_size); + + if (echo_buf_q_rpos == echo_buf_q_wpos) { + queue_len = echo_buf_q_full ? echo_buf_q_size : 0; + echo_buf_q_full = false; + } else if (echo_buf_q_rpos < echo_buf_q_wpos) { + queue_len = echo_buf_q_wpos - echo_buf_q_rpos; + } else { + queue_len = echo_buf_q_size + echo_buf_q_wpos - echo_buf_q_rpos; + } + ASSERT(queue_len >= len_per_channel, "%s: queue underflow: q_len=%u len=%u rpos=%u wpos=%u size=%u", + __func__, queue_len, len_per_channel, echo_buf_q_rpos, echo_buf_q_wpos, echo_buf_q_size); + + aec_echo_buf = (int16_t *)(echo_buf_queue + echo_buf_q_rpos); + echo_buf_q_rpos += len_per_channel; + if (echo_buf_q_rpos >= echo_buf_q_size) { + echo_buf_q_rpos = 0; + } +#endif +#endif + short *pcm_buf = (short*)buf; +#if defined(SPEECH_TX_24BIT) + int pcm_len = len / sizeof(int32_t); +#else + int pcm_len = len / sizeof(int16_t); +#endif + + if(app_get_current_overlay() == APP_OVERLAY_HFP){ + speech_tx_process(pcm_buf, aec_echo_buf, &pcm_len); + +#if defined(SPEECH_TX_24BIT) + int32_t *buf24 = (int32_t *)pcm_buf; + int16_t *buf16 = (int16_t *)pcm_buf; + for (int i = 0; i < pcm_len; i++) + buf16[i] = (buf24[i] >> 8); +#endif + + if (resample_needed_flag == true) { + iir_resample_process(upsample_st, pcm_buf, upsample_buf_for_msbc, pcm_len); + pcm_buf = upsample_buf_for_msbc; + pcm_len = sco_frame_length; + } + }else{ + memset(buf, 0, len); + } + + LOCK_APP_AUDIO_QUEUE(); + store_voicebtpcm_p2m_buffer((uint8_t *)pcm_buf, pcm_len * sizeof(short)); + size = APP_AUDIO_LengthOfCQueue(&voicebtpcm_p2m_pcm_queue); + UNLOCK_APP_AUDIO_QUEUE(); + + if (size >= voicebtpcm_p2m_cache_threshold) + { + voicebtpcm_cache_p2m_status = APP_AUDIO_CACHE_OK; + } + + return pcm_len*2; +} +#else +//used by capture, store data from mic to memory +uint32_t voicebtpcm_pcm_audio_data_come(uint8_t *buf, uint32_t len) +{ + int16_t POSSIBLY_UNUSED ret = 0; + bool POSSIBLY_UNUSED vdt = false; + int size = 0; + + short *pcm_buf = (short*)buf; + uint32_t pcm_len = len / 2; + + // TRACE(2,"[%s] pcm_len = %d", __func__, pcm_len); + + LOCK_APP_AUDIO_QUEUE(); + store_voicebtpcm_p2m_buffer((uint8_t *)pcm_buf, pcm_len*2); + size = APP_AUDIO_LengthOfCQueue(&voicebtpcm_p2m_queue); + UNLOCK_APP_AUDIO_QUEUE(); + + if (size > VOICEBTPCM_PCM_TEMP_BUFFER_SIZE) + { + voicebtpcm_cache_p2m_status = APP_AUDIO_CACHE_OK; + } + + return pcm_len*2; +} +#endif + +//used by playback, play data from memory to speaker +uint32_t voicebtpcm_pcm_audio_more_data(uint8_t *buf, uint32_t len) +{ + uint32_t l = 0; + //TRACE(3,"[%s]: pcm_len = %d, %d", __FUNCTION__, len / 2, FAST_TICKS_TO_US(hal_fast_sys_timer_get())); + if ((voicebtpcm_cache_m2p_status == APP_AUDIO_CACHE_CACHEING) +#ifndef FPGA + ||(app_get_current_overlay() != APP_OVERLAY_HFP) +#endif + ) + { + app_audio_memset_16bit((short *)buf, 0, len/2); + l = len; + } + else + { +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) || defined(SPEECH_TX_THIRDPARTY) +#if !(defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE)) +#if defined(SPEECH_TX_24BIT) && defined(SPEECH_RX_24BIT) + memcpy(aec_echo_buf, buf, len / sizeof(int16_t) * sizeof(int32_t)); +#elif defined(SPEECH_TX_24BIT) && !defined(SPEECH_RX_24BIT) + short *buf_p=(short *)buf; + for (uint32_t i = 0; i < len / sizeof(int16_t); i++) { + aec_echo_buf[i] = ((int32_t)buf_p[i] << 8); + } +#elif !defined(SPEECH_TX_24BIT) && defined(SPEECH_RX_24BIT) + int32_t *buf32_p = (int32_t *)buf; + for (uint32_t i = 0; i < len / sizeof(int16_t); i++) { + aec_echo_buf[i] = (buf32_p[i] >> 8); + } +#else + app_audio_memcpy_16bit((int16_t *)aec_echo_buf, (int16_t *)buf, len/2); +#endif +#endif +#endif + + int decode_len = len; + uint8_t *decode_buf = buf; + + if (resample_needed_flag == true) { + decode_len = sco_frame_length * 2; + decode_buf = (uint8_t *)downsample_buf_for_msbc; + } + + unsigned int len1 = 0, len2 = 0; + unsigned char *e1 = NULL, *e2 = NULL; + int r = 0; + + LOCK_APP_AUDIO_QUEUE(); + len1 = len2 = 0; + e1 = e2 = 0; + r = APP_AUDIO_PeekCQueue(&voicebtpcm_m2p_pcm_queue, decode_len, &e1, &len1, &e2, &len2); + UNLOCK_APP_AUDIO_QUEUE(); + if (r == CQ_ERR) + { + TRACE(0,"pcm buff underflow"); + memset(decode_buf, 0, decode_len); + l = len; + goto fail; + } + + if (!len1) + { + TRACE(2,"pcm len1 underflow %d/%d\n", len1, len2); + memset(decode_buf, 0, decode_len); + l = len; + goto fail; + } + + if (len1 > 0 && e1) + { + memcpy(decode_buf, e1, len1); + } + if (len2 > 0 && e2) + { + memcpy(decode_buf + len1, e2, len2); + } + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_DeCQueue(&voicebtpcm_m2p_pcm_queue, 0, decode_len); + UNLOCK_APP_AUDIO_QUEUE(); + } // if (voicebtpcm_cache_m2p_status == APP_AUDIO_CACHE_CACHEING) + + // downsample_buf_for_msbc size is len * 2 + if (resample_needed_flag == true) { + iir_resample_process(downsample_st, downsample_buf_for_msbc, (int16_t *)buf, sco_frame_length); + } + +fail: + short * POSSIBLY_UNUSED pcm_buf = (short*)buf; + int POSSIBLY_UNUSED pcm_len = len / 2; + +#if defined(SPEECH_RX_24BIT) + int32_t *buf32 = (int32_t *)buf; + for (int i = pcm_len - 1; i >= 0; i--) { + buf32[i] = ((int32_t)pcm_buf[i] << 8); + } +#endif + + speech_rx_process(pcm_buf, &pcm_len); + + buf = (uint8_t *)pcm_buf; + len = pcm_len * sizeof(short); + +#if defined(SPEECH_RX_24BIT) + len = len / sizeof(int16_t) * sizeof(int32_t); +#endif + +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + uint32_t queue_len; + + ASSERT(len == speech_tx_aec_get_frame_len() * sizeof(short), "%s: Unmatched len: %u != %u", __func__, len, speech_tx_aec_get_frame_len() * sizeof(short)); + ASSERT(echo_buf_q_wpos + len <= echo_buf_q_size, "%s: wpos (%u) overflow: len=%u size=%u", __func__, echo_buf_q_wpos, len, echo_buf_q_size); + + if (echo_buf_q_rpos == echo_buf_q_wpos) { + queue_len = echo_buf_q_full ? echo_buf_q_size : 0; + } else if (echo_buf_q_rpos < echo_buf_q_wpos) { + queue_len = echo_buf_q_wpos - echo_buf_q_rpos; + } else { + queue_len = echo_buf_q_size + echo_buf_q_wpos - echo_buf_q_rpos; + } + ASSERT(queue_len + len <= echo_buf_q_size, "%s: queue overflow: q_len=%u len=%u rpos=%u wpos=%u size=%u", + __func__, queue_len, len, echo_buf_q_rpos, echo_buf_q_wpos, echo_buf_q_size); + + app_audio_memcpy_16bit((int16_t *)(echo_buf_queue + echo_buf_q_wpos), (int16_t *)buf, len / 2); + echo_buf_q_wpos += len; + if (echo_buf_q_wpos >= echo_buf_q_size) { + echo_buf_q_wpos = 0; + } + if (echo_buf_q_rpos == echo_buf_q_wpos) { + echo_buf_q_full = true; + } +#endif +#endif + + return l; +} + +void *voicebtpcm_get_ext_buff(int size) +{ + uint8_t *pBuff = NULL; + if (size % 4) + { + size = size + (4 - size % 4); + } + app_audio_mempool_get_buff(&pBuff, size); + VOICEBTPCM_TRACE(2,"[%s] len:%d", __func__, size); + return (void*)pBuff; +} + +int voicebtpcm_pcm_echo_buf_queue_init(uint32_t size) +{ +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + echo_buf_queue = (uint8_t *)voicebtpcm_get_ext_buff(size); + echo_buf_q_size = size; + echo_buf_q_wpos = 0; + echo_buf_q_rpos = 0; + echo_buf_q_full = false; +#endif +#endif + return 0; +} + +void voicebtpcm_pcm_echo_buf_queue_reset(void) +{ +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + echo_buf_q_wpos = 0; + echo_buf_q_rpos = 0; + echo_buf_q_full = false; +#endif +#endif +} + +void voicebtpcm_pcm_echo_buf_queue_deinit(void) +{ +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + echo_buf_queue = NULL; + echo_buf_q_size = 0; + echo_buf_q_wpos = 0; + echo_buf_q_rpos = 0; + echo_buf_q_full = false; +#endif +#endif +} + +extern enum AUD_SAMPRATE_T speech_codec_get_sample_rate(void); + +// sco sample rate: encoder/decoder sample rate +// codec sample rate: hardware sample rate +int voicebtpcm_pcm_audio_init(int sco_sample_rate, int codec_sample_rate) +{ + uint8_t POSSIBLY_UNUSED *speech_buf = NULL; + int POSSIBLY_UNUSED speech_len = 0; + + sco_frame_length = SPEECH_FRAME_MS_TO_LEN(sco_sample_rate, SPEECH_SCO_FRAME_MS); + codec_frame_length = SPEECH_FRAME_MS_TO_LEN(codec_sample_rate, SPEECH_SCO_FRAME_MS); + + TRACE(3,"[%s] TX: sample rate = %d, frame len = %d", __func__, codec_sample_rate, codec_frame_length); + TRACE(3,"[%s] RX: sample rate = %d, frame len = %d", __func__, codec_sample_rate, codec_frame_length); + + // init cqueue + uint8_t *p2m_pcm_buff = NULL; + uint8_t *m2p_pcm_buff = NULL; +#if defined(TX_RX_PCM_MASK) + uint8_t *Mic_frame_buff = NULL; + uint8_t *Rx_esco_buff = NULL; + uint32_t pcm_buf_size= 240*sizeof(uint8_t); +#endif + if (bt_sco_codec_is_msbc()) + { + voicebtpcm_p2m_pcm_cache_size=VOICEBTPCM_PCM_16K_QUEUE_SIZE; + voicebtpcm_m2p_pcm_cache_size=VOICEBTPCM_PCM_16K_QUEUE_SIZE; + } + else + { + voicebtpcm_p2m_pcm_cache_size=VOICEBTPCM_PCM_8K_QUEUE_SIZE; + voicebtpcm_m2p_pcm_cache_size=VOICEBTPCM_PCM_8K_QUEUE_SIZE; + } + + voicebtpcm_p2m_cache_threshold=voicebtpcm_p2m_pcm_cache_size/2; + voicebtpcm_m2p_cache_threshold=voicebtpcm_m2p_pcm_cache_size/2; + + app_audio_mempool_get_buff(&p2m_pcm_buff, voicebtpcm_p2m_pcm_cache_size); + app_audio_mempool_get_buff(&m2p_pcm_buff, voicebtpcm_m2p_pcm_cache_size); +#if defined(TX_RX_PCM_MASK) + app_audio_mempool_get_buff(&Mic_frame_buff, pcm_buf_size); + app_audio_mempool_get_buff(&Rx_esco_buff, pcm_buf_size); +#endif + + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_InitCQueue(&voicebtpcm_p2m_pcm_queue, voicebtpcm_p2m_pcm_cache_size, p2m_pcm_buff); + APP_AUDIO_InitCQueue(&voicebtpcm_m2p_pcm_queue, voicebtpcm_m2p_pcm_cache_size, m2p_pcm_buff); + +#if defined(TX_RX_PCM_MASK) + APP_AUDIO_InitCQueue(&Tx_esco_queue,pcm_buf_size,Mic_frame_buff); + APP_AUDIO_InitCQueue(&Rx_esco_queue,pcm_buf_size,Rx_esco_buff); +#endif + UNLOCK_APP_AUDIO_QUEUE(); + + voicebtpcm_cache_m2p_status = APP_AUDIO_CACHE_CACHEING; + voicebtpcm_cache_p2m_status = APP_AUDIO_CACHE_CACHEING; + +#if defined(HFP_1_6_ENABLE) + + memset(DecPcmBuf,0,SAMPLES_LEN_PER_FRAME*sizeof(short)); + memset(DecMsbcBuf,0,MSBC_LEN_PER_FRAME*sizeof(unsigned char)); + memset(DecMsbcBufAll,0, sizeof(DecMsbcBufAll)); + + if (bt_sco_codec_is_msbc()) + { + app_audio_mempool_get_buff((uint8_t **)&msbc_encoder, sizeof(btif_sbc_encoder_t)); +#if !defined(PENDING_MSBC_DECODER_ALG) + app_audio_mempool_get_buff(&temp_msbc_buf, MSBC_ENCODE_PCM_LEN); + app_audio_mempool_get_buff(&temp_msbc_buf1, MSBC_FRAME_SIZE); +#else + app_audio_mempool_get_buff(&msbc_buf_before_decode, MSBC_FRAME_SIZE * sizeof(short)); + app_audio_mempool_get_buff(&temp_msbc_buf, MSBC_ENCODE_PCM_LEN * sizeof(short)); + app_audio_mempool_get_buff(&temp_msbc_buf1, MSBC_ENCODE_PCM_LEN * sizeof(short)); +#endif + //init msbc encoder + btif_sbc_init_encoder(msbc_encoder); + msbc_encoder->streamInfo.mSbcFlag = 1; + msbc_encoder->streamInfo.numChannels = 1; + msbc_encoder->streamInfo.channelMode = BTIF_SBC_CHNL_MODE_MONO; + + msbc_encoder->streamInfo.bitPool = 26; + msbc_encoder->streamInfo.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + msbc_encoder->streamInfo.allocMethod = BTIF_SBC_ALLOC_METHOD_LOUDNESS; + msbc_encoder->streamInfo.numBlocks = BTIF_MSBC_BLOCKS; + msbc_encoder->streamInfo.numSubBands = 8; + + msbc_counter = 0x08; + + //init msbc decoder + const float EQLevel[25] = + { + 0.0630957, 0.0794328, 0.1, 0.1258925, 0.1584893, + 0.1995262, 0.2511886, 0.3162278, 0.398107, 0.5011872, + 0.6309573, 0.794328, 1, 1.258925, 1.584893, + 1.995262, 2.5118864, 3.1622776, 3.9810717, 5.011872, + 6.309573, 7.943282, 10, 12.589254, 15.848932 + };//-12~12 + uint8_t i; + + for (i=0; istreamInfo.mSbcFlag = 1; + msbc_plc_encoder->streamInfo.bitPool = 26; + msbc_plc_encoder->streamInfo.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + msbc_plc_encoder->streamInfo.channelMode = BTIF_SBC_CHNL_MODE_MONO; + msbc_plc_encoder->streamInfo.allocMethod = BTIF_SBC_ALLOC_METHOD_LOUDNESS; + /* Number of blocks used to encode the stream (4, 8, 12, or 16) */ + msbc_plc_encoder->streamInfo.numBlocks = BTIF_MSBC_BLOCKS; + /* The number of subbands in the stream (4 or 8) */ + msbc_plc_encoder->streamInfo.numSubBands = 8; + msbc_plc_encoder->streamInfo.numChannels = 1; + app_audio_mempool_get_buff((uint8_t **)&msbc_plc_encoder_buffer, sizeof(int16_t) * (SAMPLES_LEN_PER_FRAME + MSBC_CODEC_DELAY)); +#endif + } + else +#endif + { + speech_plc = (PlcSt_8000 *)speech_plc_8000_init(voicebtpcm_get_ext_buff); + } + +#if defined(CVSD_BYPASS) + Pcm8k_CvsdInit(); +#endif + +#ifdef SPEECH_RX_PLC_DUMP_DATA + audio_dump_temp_buf = (int16_t *)voicebtpcm_get_ext_buff(sizeof(int16_t) * 120); + audio_dump_init(120, sizeof(short), 3); +#endif + + resample_needed_flag = (sco_sample_rate == codec_sample_rate) ? 0 : 1; + + if (resample_needed_flag == true) { + // upsample_buf_for_msbc -> uplink resampler + // downsample_buf_for_msbc -> downlink resampler + // store msbc pcm buffer + upsample_buf_for_msbc = (int16_t *)voicebtpcm_get_ext_buff(sizeof(int16_t) * sco_frame_length); + downsample_buf_for_msbc = (int16_t *)voicebtpcm_get_ext_buff(sizeof(int16_t) * sco_frame_length); + } + +#if defined(SCO_OPTIMIZE_FOR_RAM) + sco_overlay_ram_buf_len = hal_overlay_get_text_free_size((enum HAL_OVERLAY_ID_T)APP_OVERLAY_HFP); + sco_overlay_ram_buf = (uint8_t *)hal_overlay_get_text_free_addr((enum HAL_OVERLAY_ID_T)APP_OVERLAY_HFP); +#endif + + speech_len = app_audio_mempool_free_buff_size() - APP_BT_STREAM_USE_BUF_SIZE; + speech_buf = (uint8_t *)voicebtpcm_get_ext_buff(speech_len); + + int tx_frame_ms = SPEECH_PROCESS_FRAME_MS; + int rx_frame_ms = SPEECH_PROCESS_FRAME_MS; +#if !defined(SPEECH_RX_NS2FLOAT) + rx_frame_ms = SPEECH_SCO_FRAME_MS; +#endif + speech_init(codec_sample_rate, codec_sample_rate, tx_frame_ms, rx_frame_ms, SPEECH_SCO_FRAME_MS, speech_buf, speech_len); + + if (resample_needed_flag == true) { + // Resample state must be created after speech init, as it uses speech heap + upsample_st = iir_resample_init(codec_frame_length, iir_resample_choose_mode(codec_sample_rate, sco_sample_rate)); + downsample_st = iir_resample_init(sco_frame_length, iir_resample_choose_mode(sco_sample_rate, codec_sample_rate)); + } + +#if defined(HFP_1_6_ENABLE) && defined(ENABLE_LPC_PLC) + msbc_plc_state = lpc_plc_create(sco_sample_rate); +#endif + + return 0; +} + +int voicebtpcm_pcm_audio_deinit(void) +{ + TRACE(1,"[%s] Close...", __func__); + // TRACE(2,"[%s] app audio buffer free = %d", __func__, app_audio_mempool_free_buff_size()); + +#if defined(HFP_1_6_ENABLE) && defined(ENABLE_LPC_PLC) + lpc_plc_destroy(msbc_plc_state); +#endif + + if (resample_needed_flag == true) { + iir_resample_destroy(upsample_st); + iir_resample_destroy(downsample_st); + } + + speech_deinit(); + +#if defined(HFP_1_6_ENABLE) +#if !defined(PENDING_MSBC_DECODER_ALG) + packet_loss_detection_report(&pld); +#endif +#endif + +#if defined(SCO_OPTIMIZE_FOR_RAM) + sco_overlay_ram_buf = NULL; + sco_overlay_ram_buf_len = 0; +#endif + + voicebtpcm_pcm_echo_buf_queue_deinit(); + + // TRACE(1,"Free buf = %d", app_audio_mempool_free_buff_size()); + + return 0; +} \ No newline at end of file diff --git a/apps/audioplayers/voicebtpcmplay_sco_dma_snapshot.cpp b/apps/audioplayers/voicebtpcmplay_sco_dma_snapshot.cpp new file mode 100644 index 0000000..65e8c29 --- /dev/null +++ b/apps/audioplayers/voicebtpcmplay_sco_dma_snapshot.cpp @@ -0,0 +1,948 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Standard C Included Files +#include +#include +#include +#include +#include +#include "cmsis_os.h" +#include "plat_types.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "cqueue.h" +#include "app_audio.h" +#include "app_overlay.h" +#include "app_ring_merge.h" +#include "tgt_hardware.h" +#include "bt_sco_chain.h" +#include "iir_resample.h" +#include "hfp_api.h" +#include "audio_prompt_sbc.h" +#ifdef TX_RX_PCM_MASK +#include "bt_drv_interface.h" +#endif + +#define ENABLE_LPC_PLC + +#define ENABLE_PLC_ENCODER + +// BT +#include "a2dp_api.h" +#include "plc_utils.h" +extern "C" { + +#include "plc_8000.h" +#include "speech_utils.h" +#if defined(HFP_1_6_ENABLE) +#include "codec_sbc.h" +#ifndef ENABLE_LPC_PLC +#include "plc_16000.h" +#endif +#endif +#if defined(CVSD_BYPASS) +#include "Pcm8k_Cvsd.h" +#endif +#ifndef ENABLE_LPC_PLC +static void *speech_plc; +#endif +} + +#if defined(ENABLE_LPC_PLC) +#include "lpc_plc_api.h" +#endif + +#if defined(SPEECH_TX_24BIT) +extern int32_t *aec_echo_buf; +#else +extern short *aec_echo_buf; +#endif + +// #define SPEECH_RX_PLC_DUMP_DATA + +// #define PLC_DEBUG_PRINT_DATA + +//#define DEBUG_SCO_DUMP + +#ifdef SPEECH_RX_PLC_DUMP_DATA +#include "audio_dump.h" +int16_t *audio_dump_temp_buf = NULL; +#endif + +// app_bt_stream.cpp::bt_sco_player(), used buffer size +#define APP_BT_STREAM_USE_BUF_SIZE (1024*2) +#if defined(SCO_OPTIMIZE_FOR_RAM) +uint8_t *sco_overlay_ram_buf = NULL; +int sco_overlay_ram_buf_len = 0; +#endif + +static bool resample_needed_flag = false; +static int sco_frame_length; +static int codec_frame_length; +static int16_t *resample_buf = NULL; +static IirResampleState *uplink_resample_st = NULL; +static IirResampleState *downlink_resample_st = NULL; + +#define MSBC_FRAME_SIZE (60) + +#if defined(HFP_1_6_ENABLE) +static btif_sbc_decoder_t *msbc_decoder; +static float msbc_eq_band_gain[CFG_HW_AUD_EQ_NUM_BANDS]= {0,0,0,0,0,0,0,0}; + +#define MSBC_ENCODE_PCM_LEN (240) + +#ifndef ENABLE_LPC_PLC +struct PLC_State msbc_plc_state; +#endif + +#ifdef ENABLE_PLC_ENCODER +static btif_sbc_encoder_t *msbc_plc_encoder; +static int16_t *msbc_plc_encoder_buffer = NULL; +#define MSBC_CODEC_DELAY (73) +#endif + +static btif_sbc_encoder_t *msbc_encoder; +#endif + +#if defined(ENABLE_LPC_PLC) +LpcPlcState *msbc_plc_state = NULL; +#endif + +#define VOICEBTPCM_TRACE(s,...) +//TRACE(s, ##__VA_ARGS__) + +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) || defined(CHIP_BEST2001) +#define MSBC_MUTE_PATTERN (0x55) +#else +#define MSBC_MUTE_PATTERN (0x00) +#endif +#define MSBC_LEN_FORMBT_PER_FRAME (60) //Bytes; only for BES platform. +#define SAMPLES_LEN_PER_FRAME (120) +#define MSBC_LEN_PER_FRAME (57+3) +#define BYTES_PER_PCM_FRAME (SAMPLES_LEN_PER_FRAME*2) + +// Add 1 to ensure it never be out of bounds when msbc_offset is 1 +unsigned char msbc_buf_all[MSBC_LEN_FORMBT_PER_FRAME*3+1]; +#if defined(HFP_1_6_ENABLE) +static int msbc_find_first_sync = 0; +static unsigned int msbc_offset = 0; +static unsigned int next_frame_flag = 0; +#endif +static PacketLossState pld; + +extern bool bt_sco_codec_is_msbc(void); + +int process_downlink_msbc_frames(unsigned char *msbc_buf, unsigned int msbc_len, unsigned char *pcm_buf,unsigned int pcm_len); +int process_downlink_cvsd_frames(unsigned char *cvsd_buf, unsigned int cvsd_len, unsigned char *pcm_buf,unsigned int pcm_len); +int process_uplink_msbc_frames(unsigned char *pcm_buf, unsigned int pcm_len, unsigned char *msbc_buf,unsigned int msbc_len); +int process_uplink_cvsd_frames(unsigned char *pcm_buf, unsigned int pcm_len, unsigned char *cvsd_buf,unsigned int cvsd_len); + + +int process_downlink_bt_voice_frames(uint8_t *in_buf, uint32_t in_len, uint8_t *out_buf,uint32_t out_len,int32_t codec_type) +{ + //TRACE(3,"[%s] in_len = %d, out_len = %d", __FUNCTION__, in_len, out_len); + +#if defined(SPEECH_RX_24BIT) + out_len /= 2; +#endif + + int16_t *pcm_buf = (int16_t *)out_buf; + int pcm_len = out_len / sizeof(int16_t); + + if (resample_needed_flag == true) { + pcm_buf = resample_buf; + pcm_len = sco_frame_length; + } + + if (bt_sco_codec_is_msbc()) { + process_downlink_msbc_frames(in_buf, in_len, (uint8_t *)pcm_buf, pcm_len * sizeof(int16_t)); + + // Down sampling + if (resample_needed_flag) { + iir_resample_process(downlink_resample_st, pcm_buf, (int16_t *)out_buf, pcm_len); + pcm_buf = (int16_t *)out_buf; + pcm_len >>= 1; + } + } else { + process_downlink_cvsd_frames(in_buf, in_len, (uint8_t *)pcm_buf, pcm_len * sizeof(int16_t)); + + // Up sampling + if (resample_needed_flag) { + iir_resample_process(downlink_resample_st, pcm_buf, (int16_t *)out_buf, pcm_len); + pcm_buf = (int16_t *)out_buf; + pcm_len <<= 1; + } + } + +#if defined(SPEECH_RX_24BIT) + int32_t *buf32 = (int32_t *)out_buf; + for (int i = pcm_len - 1; i >= 0; i--) { + buf32[i] = ((int32_t)pcm_buf[i] << 8); + } +#endif + + speech_rx_process(pcm_buf, &pcm_len); + +#if defined(SPEECH_RX_24BIT) + out_len *= 2; +#endif + + return 0; +} + +int process_uplink_bt_voice_frames(uint8_t *in_buf, uint32_t in_len, uint8_t *ref_buf, uint32_t ref_len, uint8_t *out_buf,uint32_t out_len,int32_t codec_type) +{ + //TRACE(3,"[%s] in_len = %d, out_len = %d", __FUNCTION__, in_len, out_len); + +#if defined(SPEECH_TX_24BIT) + int32_t *pcm_buf = (int32_t *)in_buf; + int pcm_len = in_len / sizeof(int32_t); +#else + int16_t *pcm_buf = (int16_t *)in_buf; + int pcm_len = in_len / sizeof(int16_t); +#endif + +#if defined(SPEECH_TX_AEC_CODEC_REF) + ASSERT(pcm_len % (SPEECH_CODEC_CAPTURE_CHANNEL_NUM + 1) == 0, "[%s] pcm_len(%d) should be divided by %d", __FUNCTION__, pcm_len, SPEECH_CODEC_CAPTURE_CHANNEL_NUM + 1); + // copy reference buffer +#if defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) || defined(SPEECH_TX_THIRDPARTY) + for (int i = SPEECH_CODEC_CAPTURE_CHANNEL_NUM, j = 0; i < pcm_len; i += SPEECH_CODEC_CAPTURE_CHANNEL_NUM + 1, j++) { + aec_echo_buf[j] = pcm_buf[i]; + } +#endif + for (int i = 0, j = 0; i < pcm_len; i += SPEECH_CODEC_CAPTURE_CHANNEL_NUM + 1, j += SPEECH_CODEC_CAPTURE_CHANNEL_NUM) { + for (int k = 0; k < SPEECH_CODEC_CAPTURE_CHANNEL_NUM; k++) + pcm_buf[j + k] = pcm_buf[i + k]; + } + pcm_len = pcm_len / (SPEECH_CODEC_CAPTURE_CHANNEL_NUM + 1) * SPEECH_CODEC_CAPTURE_CHANNEL_NUM; +#elif (defined(SPEECH_TX_AEC) || defined(SPEECH_TX_AEC2) || defined(SPEECH_TX_AEC3) || defined(SPEECH_TX_AEC2FLOAT) || defined(SPEECH_TX_THIRDPARTY)) + int ref_pcm_len = ref_len / sizeof(int16_t); + ASSERT(pcm_len / SPEECH_CODEC_CAPTURE_CHANNEL_NUM == ref_pcm_len, "[%s] Length error: %d / %d != %d", __func__, pcm_len, SPEECH_CODEC_CAPTURE_CHANNEL_NUM, ref_pcm_len); + + for (int i = 0; i < ref_pcm_len; i++) { + aec_echo_buf[i] = ref_buf[i]; + } +#endif + speech_tx_process(pcm_buf, aec_echo_buf, &pcm_len); + +#if defined(SPEECH_TX_24BIT) + int32_t *buf24 = (int32_t *)pcm_buf; + int16_t *buf16 = (int16_t *)pcm_buf; + for (int i = 0; i < pcm_len; i++) + buf16[i] = (buf24[i] >> 8); +#endif + + int16_t *pcm_buf_16bits = (int16_t *)pcm_buf; + + if (bt_sco_codec_is_msbc()) { + // Up sampling + if (resample_needed_flag) { + iir_resample_process(uplink_resample_st, (int16_t *)pcm_buf_16bits, resample_buf, pcm_len); + pcm_buf_16bits = resample_buf; + pcm_len = sco_frame_length; + } + + process_uplink_msbc_frames((uint8_t *)pcm_buf_16bits, pcm_len * sizeof(int16_t), out_buf, out_len); + } else { + // Down sampling + if (resample_needed_flag) { + iir_resample_process(uplink_resample_st, (int16_t *)pcm_buf_16bits, resample_buf, pcm_len); + pcm_buf_16bits = resample_buf; + pcm_len = sco_frame_length; + } + + process_uplink_cvsd_frames((uint8_t *)pcm_buf_16bits, pcm_len * sizeof(int16_t), out_buf, out_len); + } + return 0; +} + +int process_downlink_msbc_frames(unsigned char *msbc_buf, unsigned int msbc_len, unsigned char *pcm_buf,unsigned int pcm_len) +{ +#if defined(HFP_1_6_ENABLE) + + + btif_sbc_pcm_data_t pcm_data; + unsigned int msbc_offset_lowdelay = 0; + unsigned int i,j; + unsigned char *msbc_buffer=(unsigned char *)msbc_buf; + int frame_flag[6]; // 1: good frame; 0:bad frame; + bt_status_t ret; + unsigned int frame_counter=0; + unsigned short byte_decode = 0; + unsigned int msbc_offset_total = 0; + int msbc_offset_drift[6] = {0, }; + + short *dec_pcm_buf=( short *)pcm_buf; + unsigned char dec_msbc_buf[MSBC_LEN_PER_FRAME] = {0, }; + + //unsigned int timer_begin=hal_sys_timer_get(); + + //TRACE(2,"process_downlink_msbc_frames:pcm_len:%d,msbc_len:%d",pcm_len,msbc_len); + + //TRACE(1,"decode_msbc_frame,msbc_len:%d",msbc_len); + for(i =0; i=msbc_offset_total) + { + frame_flag[j]=3; + } + else + { + frame_flag[j]=1; + } + } + } + } + + for(j =0; j1)msbc_find_first_sync=0; + } + + while((frame_counterstreamInfo.mSbcFlag = 1; + msbc_encoder->streamInfo.numChannels = 1; + msbc_encoder->streamInfo.channelMode = BTIF_SBC_CHNL_MODE_MONO; + + msbc_encoder->streamInfo.bitPool = 26; + msbc_encoder->streamInfo.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + msbc_encoder->streamInfo.allocMethod = BTIF_SBC_ALLOC_METHOD_LOUDNESS; + msbc_encoder->streamInfo.numBlocks = BTIF_MSBC_BLOCKS; + msbc_encoder->streamInfo.numSubBands = 8; + + //init msbc decoder + const float EQLevel[25] = + { + 0.0630957, 0.0794328, 0.1, 0.1258925, 0.1584893, + 0.1995262, 0.2511886, 0.3162278, 0.398107, 0.5011872, + 0.6309573, 0.794328, 1, 1.258925, 1.584893, + 1.995262, 2.5118864, 3.1622776, 3.9810717, 5.011872, + 6.309573, 7.943282, 10, 12.589254, 15.848932 + };//-12~12 + uint8_t i; + + for (i=0; istreamInfo.mSbcFlag = 1; + msbc_decoder->streamInfo.bitPool = 26; + msbc_decoder->streamInfo.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + msbc_decoder->streamInfo.channelMode = BTIF_SBC_CHNL_MODE_MONO; + msbc_decoder->streamInfo.allocMethod = BTIF_SBC_ALLOC_METHOD_LOUDNESS; + /* Number of blocks used to encode the stream (4, 8, 12, or 16) */ + msbc_decoder->streamInfo.numBlocks = BTIF_MSBC_BLOCKS; + /* The number of subbands in the stream (4 or 8) */ + msbc_decoder->streamInfo.numSubBands = 8; + msbc_decoder->streamInfo.numChannels = 1; + + //init msbc plc +#ifndef ENABLE_LPC_PLC + InitPLC(&msbc_plc_state); +#endif + + next_frame_flag = 0; + msbc_find_first_sync = 0; + + packet_loss_detection_init(&pld); + +#if defined(ENABLE_PLC_ENCODER) + app_audio_mempool_get_buff((uint8_t **)&msbc_plc_encoder, sizeof(btif_sbc_encoder_t)); + btif_sbc_init_encoder(msbc_plc_encoder); + msbc_plc_encoder->streamInfo.mSbcFlag = 1; + msbc_plc_encoder->streamInfo.bitPool = 26; + msbc_plc_encoder->streamInfo.sampleFreq = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + msbc_plc_encoder->streamInfo.channelMode = BTIF_SBC_CHNL_MODE_MONO; + msbc_plc_encoder->streamInfo.allocMethod = BTIF_SBC_ALLOC_METHOD_LOUDNESS; + /* Number of blocks used to encode the stream (4, 8, 12, or 16) */ + msbc_plc_encoder->streamInfo.numBlocks = BTIF_MSBC_BLOCKS; + /* The number of subbands in the stream (4 or 8) */ + msbc_plc_encoder->streamInfo.numSubBands = 8; + msbc_plc_encoder->streamInfo.numChannels = 1; + app_audio_mempool_get_buff((uint8_t **)&msbc_plc_encoder_buffer, sizeof(int16_t) * (SAMPLES_LEN_PER_FRAME + MSBC_CODEC_DELAY)); +#endif + } + else +#endif + { +#ifndef ENABLE_LPC_PLC + speech_plc = (PlcSt_8000 *)speech_plc_8000_init(voicebtpcm_get_ext_buff); +#endif + } + +#if defined(CVSD_BYPASS) + Pcm8k_CvsdInit(); +#endif + +#ifdef SPEECH_RX_PLC_DUMP_DATA + audio_dump_temp_buf = (int16_t *)voicebtpcm_get_ext_buff(sizeof(int16_t) * 120); + audio_dump_init(120, sizeof(short), 3); +#endif + + resample_needed_flag = (sco_sample_rate == codec_sample_rate) ? 0 : 1; + + if (resample_needed_flag) { + TRACE(1, "[%s] SCO <-- Resample --> CODEC", __func__); + resample_buf = (int16_t *)voicebtpcm_get_ext_buff(sizeof(int16_t) * sco_frame_length); + } + +#if defined(SCO_OPTIMIZE_FOR_RAM) + sco_overlay_ram_buf_len = hal_overlay_get_text_free_size((enum HAL_OVERLAY_ID_T)APP_OVERLAY_HFP); + sco_overlay_ram_buf = (uint8_t *)hal_overlay_get_text_free_addr((enum HAL_OVERLAY_ID_T)APP_OVERLAY_HFP); +#endif + + speech_len = app_audio_mempool_free_buff_size() - APP_BT_STREAM_USE_BUF_SIZE; + speech_buf = (uint8_t *)voicebtpcm_get_ext_buff(speech_len); + + int tx_frame_ms = SPEECH_PROCESS_FRAME_MS; + int rx_frame_ms = SPEECH_SCO_FRAME_MS; + speech_init(codec_sample_rate, codec_sample_rate, tx_frame_ms, rx_frame_ms, SPEECH_SCO_FRAME_MS, speech_buf, speech_len); + + if (resample_needed_flag) { + uplink_resample_st = iir_resample_init(codec_frame_length, iir_resample_choose_mode(codec_sample_rate, sco_sample_rate)); + downlink_resample_st = iir_resample_init(sco_frame_length, iir_resample_choose_mode(sco_sample_rate, codec_sample_rate)); + } + +#if defined(ENABLE_LPC_PLC) + msbc_plc_state = lpc_plc_create(sco_sample_rate); +#endif + + return 0; +} + +int voicebtpcm_pcm_audio_deinit(void) +{ + TRACE(1,"[%s] Close...", __func__); + // TRACE(2,"[%s] app audio buffer free = %d", __func__, app_audio_mempool_free_buff_size()); + +#if defined(ENABLE_LPC_PLC) + lpc_plc_destroy(msbc_plc_state); +#endif + + if (resample_needed_flag) { + iir_resample_destroy(uplink_resample_st); + iir_resample_destroy(downlink_resample_st); + } + + speech_deinit(); + + packet_loss_detection_report(&pld); + +#if defined(SCO_OPTIMIZE_FOR_RAM) + sco_overlay_ram_buf = NULL; + sco_overlay_ram_buf_len = 0; +#endif + + // TRACE(1,"Free buf = %d", app_audio_mempool_free_buff_size()); + + return 0; +} \ No newline at end of file diff --git a/apps/audioplayers/wavplay.cpp b/apps/audioplayers/wavplay.cpp new file mode 100644 index 0000000..016204a --- /dev/null +++ b/apps/audioplayers/wavplay.cpp @@ -0,0 +1,253 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef MBED +#include "mbed.h" +#endif +// Standard C Included Files +#include +#include +#include +#include +#include + +#include "hal_uart.h" +#include "hal_trace.h" +#include "hal_timer.h" + +/*! + * * @brief Standard Winodws PCM wave file header length + * */ +#define WAVE_FILE_HEADER_SIZE 0x2CU + +typedef struct wave_header +{ + uint8_t riff[4]; + uint32_t size; + uint8_t waveFlag[4]; + uint8_t fmt[4]; + uint32_t fmtLen; + uint16_t tag; + uint16_t channels; + uint32_t sampFreq; + uint32_t byteRate; + uint16_t blockAlign; + uint16_t bitSamp; + uint8_t dataFlag[4]; + uint32_t length; +} wave_header_t; + +/*! + * * @brief Wave file structure + * */ +typedef struct wave_file +{ + wave_header_t header; + uint32_t *data; +}wave_file_t; + +/* player */ +static unsigned int g_total_play_count = 0; +static unsigned int g_curr_play_index = 0; + +/* wave */ +wave_file_t g_wave_file_info; +static char g_wav_header[WAVE_FILE_HEADER_SIZE]; +FILE *g_wave_file_handle = NULL; +static int32_t (*wav_file_palyback_callback)(int32_t ) = NULL; + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// +void wav_file_set_playeback_cb(int32_t (* cb)(int32_t)) +{ + wav_file_palyback_callback = cb; +} +bool wav_file_isplaydone(void) +{ + return (g_curr_play_index >= g_total_play_count)? true : false; +} +uint32_t wav_file_audio_more_data(uint8_t *buf, uint32_t len) +{ +// static uint32_t g_preIrqTime = 0; + uint32_t reallen = 0; +// int32_t stime,etime; + int32_t status; + + /* play done ? */ + if(wav_file_isplaydone()) { + memset(buf, 0, len); + status = 0; + if (wav_file_palyback_callback) + wav_file_palyback_callback(status); + return (len); + } +// stime = hal_sys_timer_get(); + /* read file */ + if (g_wave_file_handle) + reallen = fread(buf, 1, len, g_wave_file_handle); +// etime = hal_sys_timer_get(); + if (reallen != len){ + memset(buf, 0, len); + status = -1; + if (wav_file_palyback_callback) + wav_file_palyback_callback(status); + return (len); + } + +// TRACE(5,"wav_file_audio_more_data irqDur:%d fsSpend:%d, readbuff:0x%08x %d/%d\n ", TICKS_TO_MS(stime - g_preIrqTime),TICKS_TO_MS(etime - stime),buf,reallen,len); +// g_preIrqTime = stime; + + /* walk index */ + g_curr_play_index += reallen; + + return reallen; +} + +uint32_t get_wav_data(wave_file_t *waveFile) +{ + uint8_t *dataTemp = (uint8_t *)waveFile->data; + + // check for RIFF + memcpy(waveFile->header.riff, dataTemp, 4); + dataTemp += 4; + if( memcmp( (uint8_t*)waveFile->header.riff, "RIFF", 4) ) + { + return 0; + } + + // Get size + memcpy(&waveFile->header.size, dataTemp, 4); + dataTemp += 4; + + TRACE(1,"WAV header size [%d]\n", waveFile->header.size); + + // .wav file flag + memcpy(waveFile->header.waveFlag, dataTemp, 4); + dataTemp += 4; + if( memcmp( (uint8_t*)waveFile->header.waveFlag, "WAVE", 4) ) + { + return 0; + } + + // fmt + memcpy(waveFile->header.fmt, dataTemp, 4); + dataTemp += 4; + if( memcmp( (uint8_t*)waveFile->header.fmt, "fmt ", 4) ) + { + return 0; + } + + // fmt length + memcpy(&waveFile->header.fmtLen, dataTemp, 4); + dataTemp += 4; + + // Tag: PCM or not + memcpy(&waveFile->header.tag, dataTemp, 4); + dataTemp += 2; + + // Channels + memcpy(&waveFile->header.channels, dataTemp, 4); + dataTemp += 2; + + TRACE(1,"WAV channels [%d]\n", waveFile->header.channels); + + // Sample Rate in Hz + memcpy(&waveFile->header.sampFreq, dataTemp, 4); + dataTemp += 4; + memcpy(&waveFile->header.byteRate, dataTemp, 4); + dataTemp += 4; + + TRACE(1,"WAV sample_rate [%d]\n", waveFile->header.sampFreq); + TRACE(1,"WAV byteRate [%d]\n", waveFile->header.byteRate); + + // quantize bytes for per samp point + memcpy(&waveFile->header.blockAlign, dataTemp, 4); + dataTemp += 2; + memcpy(&waveFile->header.bitSamp, dataTemp, 4); + dataTemp += 2; + + TRACE(1,"WAV bitSamp [%d]\n", waveFile->header.bitSamp); + + // Data + memcpy(waveFile->header.dataFlag, dataTemp, 4); + dataTemp += 4; + if( memcmp( (uint8_t*)waveFile->header.dataFlag, "data ", 4) ) + { + return 0; + } + memcpy(&waveFile->header.length, dataTemp, 4); + dataTemp += 4; + + return 0; +} + + +void audio_wav_init(wave_file_t *newWav) +{ + get_wav_data(newWav); + + // Configure the play audio g_format + //g_format.bits = newWav->header.bitSamp; + //g_format.sample_rate = newWav->header.sampFreq; + //g_format.mclk = 256 * g_format.sample_rate ; + //g_format.mono_streo = (sai_mono_streo_t)((newWav->header.channels) - 1); +} + +uint32_t play_wav_file(char *file_path) +{ + uint32_t bytesToRead = 0; + + wave_file_t *newWav = &g_wave_file_info; + + memset(&g_wave_file_info, 0, sizeof(g_wave_file_info)); + + g_wave_file_handle = fopen(file_path, "rb"); + + if(g_wave_file_handle == NULL) { + TRACE(1,"WAV file %s open fail\n", file_path); + return 1; + } + + fread(&g_wav_header, WAVE_FILE_HEADER_SIZE, 1, g_wave_file_handle); + + newWav->data = (uint32_t *)&g_wav_header; + + audio_wav_init(newWav); + + // Remove header size from byte count + // Adjust note duration by divider value, wav tables in pcm_data.h are 200ms by default + bytesToRead = (newWav->header.length - WAVE_FILE_HEADER_SIZE); + + g_curr_play_index = 0; + g_total_play_count = bytesToRead; + + return newWav->header.sampFreq; +} + +uint32_t stop_wav_file(void) +{ + memset(&g_wave_file_info, 0, sizeof(g_wave_file_info)); + g_curr_play_index = 0; + g_total_play_count = 0; + if (g_wave_file_handle){ + fclose(g_wave_file_handle); + g_wave_file_handle = NULL; + } + if (wav_file_palyback_callback) + wav_file_palyback_callback = NULL; + + return 0; +} diff --git a/apps/battery/Makefile b/apps/battery/Makefile new file mode 100644 index 0000000..2c8e0d1 --- /dev/null +++ b/apps/battery/Makefile @@ -0,0 +1,18 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +subdir-ccflags-y += -Iplatform/drivers/ana \ + $(BT_IF_INCLUDES) \ + -Iservices/ble_app/app_main \ + -Iservices/app_ibrt/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/ibrt_core/inc + +ifeq ($(VOICE_PROMPT),1) +CFLAGS_app_battery.o += -DMEDIA_PLAYER_SUPPORT +endif + diff --git a/apps/battery/app_battery.cpp b/apps/battery/app_battery.cpp new file mode 100644 index 0000000..9b823ec --- /dev/null +++ b/apps/battery/app_battery.cpp @@ -0,0 +1,903 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "tgt_hardware.h" +#include "pmu.h" +#include "hal_timer.h" +#include "hal_gpadc.h" +#include "hal_trace.h" +#include "hal_gpio.h" +#include "hal_iomux.h" +#include "hal_chipid.h" +#include "app_thread.h" +#include "app_battery.h" +#include "apps.h" +#include "app_status_ind.h" +#ifdef BT_USB_AUDIO_DUAL_MODE +#include "btusb_audio.h" +#endif +#include + +#ifdef __INTERCONNECTION__ +#include "app_ble_mode_switch.h" +#endif + +#if (defined(BTUSB_AUDIO_MODE) || defined(BTUSB_AUDIO_MODE)) +extern "C" bool app_usbaudio_mode_on(void); +#endif + +#define APP_BATTERY_TRACE(s,...) +// TRACE(s, ##__VA_ARGS__) + +#ifndef APP_BATTERY_MIN_MV +#define APP_BATTERY_MIN_MV (3200) +#endif + +#ifndef APP_BATTERY_MAX_MV +#define APP_BATTERY_MAX_MV (4200) +#endif + +#ifndef APP_BATTERY_PD_MV +#define APP_BATTERY_PD_MV (3100) +#endif + +#ifndef APP_BATTERY_CHARGE_TIMEOUT_MIN +#define APP_BATTERY_CHARGE_TIMEOUT_MIN (90) +#endif + +#ifndef APP_BATTERY_CHARGE_OFFSET_MV +#define APP_BATTERY_CHARGE_OFFSET_MV (20) +#endif + +#ifndef CHARGER_PLUGINOUT_RESET +#define CHARGER_PLUGINOUT_RESET (0) +#endif + +#ifndef CHARGER_PLUGINOUT_DEBOUNCE_MS +#define CHARGER_PLUGINOUT_DEBOUNCE_MS (50) +#endif + +#ifndef CHARGER_PLUGINOUT_DEBOUNCE_CNT +#define CHARGER_PLUGINOUT_DEBOUNCE_CNT (3) +#endif + +#define APP_BATTERY_CHARGING_PLUGOUT_DEDOUNCE_CNT (APP_BATTERY_CHARGING_PERIODIC_MS<500?3:1) + +#define APP_BATTERY_CHARGING_EXTPIN_MEASURE_CNT (APP_BATTERY_CHARGING_PERIODIC_MS<2*1000?2*1000/APP_BATTERY_CHARGING_PERIODIC_MS:1) +#define APP_BATTERY_CHARGING_EXTPIN_DEDOUNCE_CNT (6) + +#define APP_BATTERY_CHARGING_OVERVOLT_MEASURE_CNT (APP_BATTERY_CHARGING_PERIODIC_MS<2*1000?2*1000/APP_BATTERY_CHARGING_PERIODIC_MS:1) +#define APP_BATTERY_CHARGING_OVERVOLT_DEDOUNCE_CNT (3) + +#define APP_BATTERY_CHARGING_SLOPE_MEASURE_CNT (APP_BATTERY_CHARGING_PERIODIC_MS<20*1000?20*1000/APP_BATTERY_CHARGING_PERIODIC_MS:1) +#define APP_BATTERY_CHARGING_SLOPE_TABLE_COUNT (6) + + +#define APP_BATTERY_REPORT_INTERVAL (5) + +#define APP_BATTERY_MV_BASE ((APP_BATTERY_MAX_MV-APP_BATTERY_PD_MV)/(APP_BATTERY_LEVEL_NUM)) + +#define APP_BATTERY_STABLE_COUNT (5) +#define APP_BATTERY_MEASURE_PERIODIC_FAST_MS (200) +#ifdef BLE_ONLY_ENABLED +#define APP_BATTERY_MEASURE_PERIODIC_NORMAL_MS (25000) +#else +#define APP_BATTERY_MEASURE_PERIODIC_NORMAL_MS (10000) +#endif +#define APP_BATTERY_CHARGING_PERIODIC_MS (APP_BATTERY_MEASURE_PERIODIC_NORMAL_MS) + +#define APP_BATTERY_SET_MESSAGE(appevt, status, volt) (appevt = (((uint32_t)status&0xffff)<<16)|(volt&0xffff)) +#define APP_BATTERY_GET_STATUS(appevt, status) (status = (appevt>>16)&0xffff) +#define APP_BATTERY_GET_VOLT(appevt, volt) (volt = appevt&0xffff) +#define APP_BATTERY_GET_PRAMS(appevt, prams) ((prams) = appevt&0xffff) + +enum APP_BATTERY_MEASURE_PERIODIC_T +{ + APP_BATTERY_MEASURE_PERIODIC_FAST = 0, + APP_BATTERY_MEASURE_PERIODIC_NORMAL, + APP_BATTERY_MEASURE_PERIODIC_CHARGING, + + APP_BATTERY_MEASURE_PERIODIC_QTY, +}; + +struct APP_BATTERY_MEASURE_CHARGER_STATUS_T +{ + HAL_GPADC_MV_T prevolt; + int32_t slope_1000[APP_BATTERY_CHARGING_SLOPE_TABLE_COUNT]; + int slope_1000_index; + int cnt; +}; + + +typedef void (*APP_BATTERY_EVENT_CB_T)(enum APP_BATTERY_STATUS_T, APP_BATTERY_MV_T volt); + +struct APP_BATTERY_MEASURE_T +{ + uint32_t start_time; + enum APP_BATTERY_STATUS_T status; +#ifdef __INTERCONNECTION__ + uint8_t currentBatteryInfo; + uint8_t lastBatteryInfo; + uint8_t isMobileSupportSelfDefinedCommand; +#else + uint8_t currlevel; +#endif + APP_BATTERY_MV_T currvolt; + APP_BATTERY_MV_T lowvolt; + APP_BATTERY_MV_T highvolt; + APP_BATTERY_MV_T pdvolt; + uint32_t chargetimeout; + enum APP_BATTERY_MEASURE_PERIODIC_T periodic; + HAL_GPADC_MV_T voltage[APP_BATTERY_STABLE_COUNT]; + uint16_t index; + struct APP_BATTERY_MEASURE_CHARGER_STATUS_T charger_status; + APP_BATTERY_EVENT_CB_T cb; + APP_BATTERY_CB_T user_cb; +}; + +static enum APP_BATTERY_CHARGER_T app_battery_charger_forcegetstatus(void); + +static void app_battery_pluginout_debounce_start(void); +static void app_battery_pluginout_debounce_handler(void const *param); +osTimerDef (APP_BATTERY_PLUGINOUT_DEBOUNCE, app_battery_pluginout_debounce_handler); +static osTimerId app_battery_pluginout_debounce_timer = NULL; +static uint32_t app_battery_pluginout_debounce_ctx = 0; +static uint32_t app_battery_pluginout_debounce_cnt = 0; + +static void app_battery_timer_handler(void const *param); +osTimerDef (APP_BATTERY, app_battery_timer_handler); +static osTimerId app_battery_timer = NULL; +static struct APP_BATTERY_MEASURE_T app_battery_measure; + +static int app_battery_charger_handle_process(void); + +#ifdef __INTERCONNECTION__ +uint8_t* app_battery_get_mobile_support_self_defined_command_p(void) +{ + return &app_battery_measure.isMobileSupportSelfDefinedCommand; +} +#endif + + +void app_battery_irqhandler(uint16_t irq_val, HAL_GPADC_MV_T volt) +{ + uint8_t i; + uint32_t meanBattVolt = 0; + HAL_GPADC_MV_T vbat = volt; + APP_BATTERY_TRACE(2,"%s %d",__func__, vbat); + if (vbat == HAL_GPADC_BAD_VALUE) + { + app_battery_measure.cb(APP_BATTERY_STATUS_INVALID, vbat); + return; + } + +#if (defined(BTUSB_AUDIO_MODE) || defined(BTUSB_AUDIO_MODE)) + if(app_usbaudio_mode_on()) return ; +#endif + app_battery_measure.voltage[app_battery_measure.index++%APP_BATTERY_STABLE_COUNT] = vbat<<2; + + if (app_battery_measure.index > APP_BATTERY_STABLE_COUNT) + { + for (i=0; iapp_battery_measure.highvolt) + { + app_battery_measure.cb(APP_BATTERY_STATUS_OVERVOLT, meanBattVolt); + } + else if((meanBattVolt>app_battery_measure.pdvolt) && (meanBattVoltAPP_BATTERY_LEVEL_MAX) + level = APP_BATTERY_LEVEL_MAX; + + app_battery_measure.currvolt = meanBattVolt; +#ifdef __INTERCONNECTION__ + APP_BATTERY_INFO_T* pBatteryInfo = (APP_BATTERY_INFO_T*)&app_battery_measure.currentBatteryInfo; + pBatteryInfo->batteryLevel = level; +#else + app_battery_measure.currlevel = level; +#endif + } +} + +static void app_battery_timer_start(enum APP_BATTERY_MEASURE_PERIODIC_T periodic) +{ + uint32_t periodic_millisec = 0; + + if (app_battery_measure.periodic != periodic){ + app_battery_measure.periodic = periodic; + switch (periodic) + { + case APP_BATTERY_MEASURE_PERIODIC_FAST: + periodic_millisec = APP_BATTERY_MEASURE_PERIODIC_FAST_MS; + break; + case APP_BATTERY_MEASURE_PERIODIC_CHARGING: + periodic_millisec = APP_BATTERY_CHARGING_PERIODIC_MS; + break; + case APP_BATTERY_MEASURE_PERIODIC_NORMAL: + periodic_millisec = APP_BATTERY_MEASURE_PERIODIC_NORMAL_MS; + default: + break; + } + osTimerStop(app_battery_timer); + osTimerStart(app_battery_timer, periodic_millisec); + } +} + +static void app_battery_timer_handler(void const *param) +{ + hal_gpadc_open(HAL_GPADC_CHAN_BATTERY, HAL_GPADC_ATP_ONESHOT, app_battery_irqhandler); +} + +static void app_battery_event_process(enum APP_BATTERY_STATUS_T status, APP_BATTERY_MV_T volt) +{ + uint32_t app_battevt; + APP_MESSAGE_BLOCK msg; + + APP_BATTERY_TRACE(3,"%s %d,%d",__func__, status, volt); + msg.mod_id = APP_MODUAL_BATTERY; + APP_BATTERY_SET_MESSAGE(app_battevt, status, volt); + msg.msg_body.message_id = app_battevt; + msg.msg_body.message_ptr = (uint32_t)NULL; + app_mailbox_put(&msg); + +} + +int app_battery_handle_process_normal(uint32_t status, union APP_BATTERY_MSG_PRAMS prams) +{ + int8_t level = 0; + + switch (status) + { + case APP_BATTERY_STATUS_UNDERVOLT: + TRACE(1,"UNDERVOLT:%d", prams.volt); + app_status_indication_set(APP_STATUS_INDICATION_CHARGENEED); +#ifdef MEDIA_PLAYER_SUPPORT +#if defined(IBRT) + +#else + app_voice_report(APP_STATUS_INDICATION_CHARGENEED, 0); +#endif +#endif + case APP_BATTERY_STATUS_NORMAL: + case APP_BATTERY_STATUS_OVERVOLT: + app_battery_measure.currvolt = prams.volt; + level = (prams.volt-APP_BATTERY_PD_MV)/APP_BATTERY_MV_BASE; + + if (levelAPP_BATTERY_LEVEL_MAX) + level = APP_BATTERY_LEVEL_MAX; +#ifdef __INTERCONNECTION__ + APP_BATTERY_INFO_T* pBatteryInfo; + pBatteryInfo = (APP_BATTERY_INFO_T*)&app_battery_measure.currentBatteryInfo; + pBatteryInfo->batteryLevel = level; + if(level == APP_BATTERY_LEVEL_MAX) + { + level = 9; + } + else + { + level /= 10; + } +#else + app_battery_measure.currlevel = level; +#endif + app_status_battery_report(level); + break; + case APP_BATTERY_STATUS_PDVOLT: +#ifndef BT_USB_AUDIO_DUAL_MODE + TRACE(1,"PDVOLT-->POWEROFF:%d", prams.volt); + osTimerStop(app_battery_timer); + app_shutdown(); +#endif + break; + case APP_BATTERY_STATUS_CHARGING: + TRACE(1,"CHARGING-->APP_BATTERY_CHARGER :%d", prams.charger); + if (prams.charger == APP_BATTERY_CHARGER_PLUGIN) + { +#ifdef BT_USB_AUDIO_DUAL_MODE + TRACE(1,"%s:PLUGIN.", __func__); + btusb_switch(BTUSB_MODE_USB); +#else +#if CHARGER_PLUGINOUT_RESET + app_reset(); +#else + app_battery_measure.status = APP_BATTERY_STATUS_CHARGING; +#endif +#endif + }else{ + app_reset(); + } + break; + case APP_BATTERY_STATUS_INVALID: + default: + break; + } + + app_battery_timer_start(APP_BATTERY_MEASURE_PERIODIC_NORMAL); + return 0; +} + +int app_battery_handle_process_charging(uint32_t status, union APP_BATTERY_MSG_PRAMS prams) +{ + switch (status) + { + case APP_BATTERY_STATUS_OVERVOLT: + case APP_BATTERY_STATUS_NORMAL: + case APP_BATTERY_STATUS_UNDERVOLT: + app_battery_measure.currvolt = prams.volt; + app_status_battery_report(prams.volt); + break; + case APP_BATTERY_STATUS_CHARGING: + TRACE(1,"CHARGING:%d", prams.charger); + if (prams.charger == APP_BATTERY_CHARGER_PLUGOUT) + { +#ifdef BT_USB_AUDIO_DUAL_MODE + TRACE(1,"%s:PlUGOUT.", __func__); + btusb_switch(BTUSB_MODE_BT); +#else +#if CHARGER_PLUGINOUT_RESET + TRACE(0,"CHARGING-->RESET"); + osTimerStop(app_battery_timer); + app_shutdown(); +#else + app_battery_measure.status = APP_BATTERY_STATUS_NORMAL; +#endif +#endif + } + else if (prams.charger == APP_BATTERY_CHARGER_PLUGIN) + { +#ifdef BT_USB_AUDIO_DUAL_MODE + TRACE(1,"%s:PLUGIN.", __func__); + btusb_switch(BTUSB_MODE_USB); +#endif + } + break; + case APP_BATTERY_STATUS_INVALID: + default: + break; + } + + if (app_battery_charger_handle_process()<=0) + { + if (app_status_indication_get() != APP_STATUS_INDICATION_FULLCHARGE) + { + TRACE(1,"FULL_CHARGING:%d", app_battery_measure.currvolt); + app_status_indication_set(APP_STATUS_INDICATION_FULLCHARGE); +#ifdef MEDIA_PLAYER_SUPPORT +#if defined(BT_USB_AUDIO_DUAL_MODE) || defined(IBRT) +#else + app_voice_report(APP_STATUS_INDICATION_FULLCHARGE, 0); +#endif +#endif + } + } + + app_battery_timer_start(APP_BATTERY_MEASURE_PERIODIC_CHARGING); + + return 0; +} + +static int app_battery_handle_process(APP_MESSAGE_BODY *msg_body) +{ + uint8_t status; + union APP_BATTERY_MSG_PRAMS msg_prams; + + APP_BATTERY_GET_STATUS(msg_body->message_id, status); + APP_BATTERY_GET_PRAMS(msg_body->message_id, msg_prams.prams); + + uint32_t generatedSeed = hal_sys_timer_get(); + for (uint8_t index = 0; index < sizeof(bt_addr); index++) + { + generatedSeed ^= (((uint32_t)(bt_addr[index])) << (hal_sys_timer_get()&0xF)); + } + srand(generatedSeed); + + if (status == APP_BATTERY_STATUS_PLUGINOUT){ + app_battery_pluginout_debounce_start(); + } + else + { + switch (app_battery_measure.status) + { + case APP_BATTERY_STATUS_NORMAL: + app_battery_handle_process_normal((uint32_t)status, msg_prams); + break; + + case APP_BATTERY_STATUS_CHARGING: + app_battery_handle_process_charging((uint32_t)status, msg_prams); + break; + + default: + break; + } + } + if (NULL != app_battery_measure.user_cb) + { + uint8_t batteryLevel; +#ifdef __INTERCONNECTION__ + APP_BATTERY_INFO_T* pBatteryInfo; + pBatteryInfo = (APP_BATTERY_INFO_T*)&app_battery_measure.currentBatteryInfo; + pBatteryInfo->chargingStatus = ((app_battery_measure.status == APP_BATTERY_STATUS_CHARGING)? 1:0); + batteryLevel = pBatteryInfo->batteryLevel; + +#else + batteryLevel = app_battery_measure.currlevel; +#endif + app_battery_measure.user_cb(app_battery_measure.currvolt, + batteryLevel, app_battery_measure.status,status,msg_prams); + } + + return 0; +} + +int app_battery_register(APP_BATTERY_CB_T user_cb) +{ + if(NULL == app_battery_measure.user_cb) + { + app_battery_measure.user_cb = user_cb; + return 0; + } + return 1; +} + +int app_battery_get_info(APP_BATTERY_MV_T *currvolt, uint8_t *currlevel, enum APP_BATTERY_STATUS_T *status) +{ + if (currvolt) + { + *currvolt = app_battery_measure.currvolt; + } + + if (currlevel) + { +#ifdef __INTERCONNECTION__ + *currlevel = app_battery_measure.currentBatteryInfo; +#else + *currlevel = app_battery_measure.currlevel; +#endif + } + + if (status) + { + *status = app_battery_measure.status; + } + + return 0; +} + +int app_battery_open(void) +{ + APP_BATTERY_TRACE(3,"%s batt range:%d~%d",__func__, APP_BATTERY_MIN_MV, APP_BATTERY_MAX_MV); + int nRet = APP_BATTERY_OPEN_MODE_INVALID; + + if (app_battery_timer == NULL) + app_battery_timer = osTimerCreate (osTimer(APP_BATTERY), osTimerPeriodic, NULL); + + if (app_battery_pluginout_debounce_timer == NULL) + app_battery_pluginout_debounce_timer = osTimerCreate (osTimer(APP_BATTERY_PLUGINOUT_DEBOUNCE), osTimerOnce, &app_battery_pluginout_debounce_ctx); + + app_battery_measure.status = APP_BATTERY_STATUS_NORMAL; +#ifdef __INTERCONNECTION__ + app_battery_measure.currentBatteryInfo = APP_BATTERY_DEFAULT_INFO; + app_battery_measure.lastBatteryInfo = APP_BATTERY_DEFAULT_INFO; + app_battery_measure.isMobileSupportSelfDefinedCommand = 0; +#else + app_battery_measure.currlevel = APP_BATTERY_LEVEL_MAX; +#endif + app_battery_measure.currvolt = APP_BATTERY_MAX_MV; + app_battery_measure.lowvolt = APP_BATTERY_MIN_MV; + app_battery_measure.highvolt = APP_BATTERY_MAX_MV; + app_battery_measure.pdvolt = APP_BATTERY_PD_MV; + app_battery_measure.chargetimeout = APP_BATTERY_CHARGE_TIMEOUT_MIN; + + app_battery_measure.periodic = APP_BATTERY_MEASURE_PERIODIC_QTY; + app_battery_measure.cb = app_battery_event_process; + app_battery_measure.user_cb = NULL; + + app_battery_measure.charger_status.prevolt = 0; + app_battery_measure.charger_status.slope_1000_index = 0; + app_battery_measure.charger_status.cnt = 0; + + app_set_threadhandle(APP_MODUAL_BATTERY, app_battery_handle_process); + + if (app_battery_ext_charger_detecter_cfg.pin != HAL_IOMUX_PIN_NUM) + { + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&app_battery_ext_charger_detecter_cfg, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)app_battery_ext_charger_detecter_cfg.pin, HAL_GPIO_DIR_IN, 1); + } + + if (app_battery_ext_charger_enable_cfg.pin != HAL_IOMUX_PIN_NUM) + { + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&app_battery_ext_charger_detecter_cfg, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)app_battery_ext_charger_detecter_cfg.pin, HAL_GPIO_DIR_OUT, 1); + } + + if (app_battery_charger_indication_open() == APP_BATTERY_CHARGER_PLUGIN) + { + app_battery_measure.status = APP_BATTERY_STATUS_CHARGING; + app_battery_measure.start_time = hal_sys_timer_get(); + //pmu_charger_plugin_config(); + if (app_battery_ext_charger_enable_cfg.pin != HAL_IOMUX_PIN_NUM) + { + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)app_battery_ext_charger_detecter_cfg.pin, HAL_GPIO_DIR_OUT, 0); + } + +#if (CHARGER_PLUGINOUT_RESET == 0) + nRet = APP_BATTERY_OPEN_MODE_CHARGING_PWRON; +#else + nRet = APP_BATTERY_OPEN_MODE_CHARGING; +#endif + } + else + { + app_battery_measure.status = APP_BATTERY_STATUS_NORMAL; + //pmu_charger_plugout_config(); + nRet = APP_BATTERY_OPEN_MODE_NORMAL; + } + return nRet; +} + +int app_battery_start(void) +{ + APP_BATTERY_TRACE(2,"%s %d",__func__, APP_BATTERY_MEASURE_PERIODIC_FAST_MS); + + app_battery_timer_start(APP_BATTERY_MEASURE_PERIODIC_FAST); + + return 0; +} + +int app_battery_stop(void) +{ + osTimerStop(app_battery_timer); + + return 0; +} + +int app_battery_close(void) +{ + hal_gpadc_close(HAL_GPADC_CHAN_BATTERY); + + return 0; +} + + +static int32_t app_battery_charger_slope_calc(int32_t t1, int32_t v1, int32_t t2, int32_t v2) +{ + int32_t slope_1000; + slope_1000 = (v2-v1)*1000/(t2-t1); + return slope_1000; +} + +static int app_battery_charger_handle_process(void) +{ + int nRet = 1; + int8_t i=0,cnt=0; + uint32_t slope_1000 = 0; + uint32_t charging_min; + static uint8_t overvolt_full_charge_cnt = 0; + static uint8_t ext_pin_full_charge_cnt = 0; + + charging_min = hal_sys_timer_get() - app_battery_measure.start_time; + charging_min = TICKS_TO_MS(charging_min)/1000/60; + if (charging_min >= app_battery_measure.chargetimeout) + { + // TRACE(0,"TIMEROUT-->FULL_CHARGING"); + nRet = -1; + goto exit; + } + + if ((app_battery_measure.charger_status.cnt++%APP_BATTERY_CHARGING_OVERVOLT_MEASURE_CNT) == 0) + { + if (app_battery_measure.currvolt>=(app_battery_measure.highvolt+APP_BATTERY_CHARGE_OFFSET_MV)) + { + overvolt_full_charge_cnt++; + } + else + { + overvolt_full_charge_cnt = 0; + } + if (overvolt_full_charge_cnt>=APP_BATTERY_CHARGING_OVERVOLT_DEDOUNCE_CNT) + { + //TRACE(0,"OVERVOLT-->FULL_CHARGING"); + nRet = -1; + goto exit; + } + } + + if ((app_battery_measure.charger_status.cnt++%APP_BATTERY_CHARGING_EXTPIN_MEASURE_CNT) == 0) + { + if (app_battery_ext_charger_detecter_cfg.pin != HAL_IOMUX_PIN_NUM) + { + if (hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)app_battery_ext_charger_detecter_cfg.pin)) + { + ext_pin_full_charge_cnt++; + } + else + { + ext_pin_full_charge_cnt = 0; + } + if (ext_pin_full_charge_cnt>=APP_BATTERY_CHARGING_EXTPIN_DEDOUNCE_CNT) + { + TRACE(0,"EXT PIN-->FULL_CHARGING"); + nRet = -1; + goto exit; + } + } + } + + if ((app_battery_measure.charger_status.cnt++%APP_BATTERY_CHARGING_SLOPE_MEASURE_CNT) == 0) + { + if (!app_battery_measure.charger_status.prevolt) + { + app_battery_measure.charger_status.slope_1000[app_battery_measure.charger_status.slope_1000_index%APP_BATTERY_CHARGING_SLOPE_TABLE_COUNT] = slope_1000; + app_battery_measure.charger_status.prevolt = app_battery_measure.currvolt; + for (i=0; i0) + cnt++; + else + cnt--; + TRACE(3,"slope_1000[%d]=%d cnt:%d", i,app_battery_measure.charger_status.slope_1000[i], cnt); + } + TRACE(3,"app_battery_charger_slope_proc slope*1000=%d cnt:%d nRet:%d", slope_1000, cnt, nRet); + if (cnt>1) + { + nRet = 1; + }/*else (3>=cnt && cnt>=-3){ + nRet = 0; + }*/else + { + if (app_battery_measure.currvolt>=(app_battery_measure.highvolt-APP_BATTERY_CHARGE_OFFSET_MV)) + { + TRACE(0,"SLOPE-->FULL_CHARGING"); + nRet = -1; + } + } + } + app_battery_measure.charger_status.slope_1000_index++; + } +exit: + return nRet; +} + +static enum APP_BATTERY_CHARGER_T app_battery_charger_forcegetstatus(void) +{ + enum APP_BATTERY_CHARGER_T status = APP_BATTERY_CHARGER_QTY; + enum PMU_CHARGER_STATUS_T charger; + + charger = pmu_charger_get_status(); + + if (charger == PMU_CHARGER_PLUGIN) + { + status = APP_BATTERY_CHARGER_PLUGIN; + // TRACE(0,"force APP_BATTERY_CHARGER_PLUGIN"); + } + else + { + status = APP_BATTERY_CHARGER_PLUGOUT; + // TRACE(0,"force APP_BATTERY_CHARGER_PLUGOUT"); + } + + return status; +} + +static void app_battery_charger_handler(enum PMU_CHARGER_STATUS_T status) +{ + TRACE(2,"%s: status=%d", __func__, status); + pmu_charger_set_irq_handler(NULL); + app_battery_event_process(APP_BATTERY_STATUS_PLUGINOUT, + (status == PMU_CHARGER_PLUGIN) ? APP_BATTERY_CHARGER_PLUGIN : APP_BATTERY_CHARGER_PLUGOUT); +} + +static void app_battery_pluginout_debounce_start(void) +{ + TRACE(1,"%s", __func__); + app_battery_pluginout_debounce_ctx = (uint32_t)app_battery_charger_forcegetstatus(); + app_battery_pluginout_debounce_cnt = 1; + osTimerStart(app_battery_pluginout_debounce_timer, CHARGER_PLUGINOUT_DEBOUNCE_MS); +} + +static void app_battery_pluginout_debounce_handler(void const *param) +{ + enum APP_BATTERY_CHARGER_T status_charger = app_battery_charger_forcegetstatus(); + + if(app_battery_pluginout_debounce_ctx == (uint32_t) status_charger){ + app_battery_pluginout_debounce_cnt++; + } + else + { + TRACE(2,"%s dithering cnt %u", __func__, app_battery_pluginout_debounce_cnt); + app_battery_pluginout_debounce_cnt = 0; + app_battery_pluginout_debounce_ctx = (uint32_t)status_charger; + } + + if (app_battery_pluginout_debounce_cnt >= CHARGER_PLUGINOUT_DEBOUNCE_CNT){ + TRACE(2,"%s %s", __func__, status_charger == APP_BATTERY_CHARGER_PLUGOUT ? "PLUGOUT" : "PLUGIN"); + if (status_charger == APP_BATTERY_CHARGER_PLUGIN) + { + if (app_battery_ext_charger_enable_cfg.pin != HAL_IOMUX_PIN_NUM) + { + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)app_battery_ext_charger_detecter_cfg.pin, HAL_GPIO_DIR_OUT, 0); + } + app_battery_measure.start_time = hal_sys_timer_get(); + } + else + { + if (app_battery_ext_charger_enable_cfg.pin != HAL_IOMUX_PIN_NUM) + { + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)app_battery_ext_charger_detecter_cfg.pin, HAL_GPIO_DIR_OUT, 1); + } + } + app_battery_event_process(APP_BATTERY_STATUS_CHARGING, status_charger); + pmu_charger_set_irq_handler(app_battery_charger_handler); + osTimerStop(app_battery_pluginout_debounce_timer); + }else{ + osTimerStart(app_battery_pluginout_debounce_timer, CHARGER_PLUGINOUT_DEBOUNCE_MS); + } +} + +int app_battery_charger_indication_open(void) +{ + enum APP_BATTERY_CHARGER_T status = APP_BATTERY_CHARGER_QTY; + uint8_t cnt = 0; + + APP_BATTERY_TRACE(1,"%s",__func__); + + pmu_charger_init(); + + do + { + status = app_battery_charger_forcegetstatus(); + if (status == APP_BATTERY_CHARGER_PLUGIN) + break; + osDelay(20); + } + while(cnt++<5); + + if (app_battery_ext_charger_detecter_cfg.pin != HAL_IOMUX_PIN_NUM) + { + if (!hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)app_battery_ext_charger_detecter_cfg.pin)) + { + status = APP_BATTERY_CHARGER_PLUGIN; + } + } + + pmu_charger_set_irq_handler(app_battery_charger_handler); + + return status; +} + +int8_t app_battery_current_level(void) +{ +#ifdef __INTERCONNECTION__ + return app_battery_measure.currentBatteryInfo & 0x7f; +#else + return app_battery_measure.currlevel; +#endif +} + +int8_t app_battery_is_charging(void) +{ + return (APP_BATTERY_STATUS_CHARGING == app_battery_measure.status); +} + +typedef uint16_t NTP_VOLTAGE_MV_T; +typedef uint16_t NTP_TEMPERATURE_C_T; + +#define NTC_CAPTURE_STABLE_COUNT (5) +#define NTC_CAPTURE_TEMPERATURE_STEP (4) +#define NTC_CAPTURE_TEMPERATURE_REF (15) +#define NTC_CAPTURE_VOLTAGE_REF (1100) + +typedef void (*NTC_CAPTURE_MEASURE_CB_T)(NTP_TEMPERATURE_C_T); + +struct NTC_CAPTURE_MEASURE_T +{ + NTP_TEMPERATURE_C_T temperature; + NTP_VOLTAGE_MV_T currvolt; + NTP_VOLTAGE_MV_T voltage[NTC_CAPTURE_STABLE_COUNT]; + uint16_t index; + NTC_CAPTURE_MEASURE_CB_T cb; +}; + +static struct NTC_CAPTURE_MEASURE_T ntc_capture_measure; + +void ntc_capture_irqhandler(uint16_t irq_val, HAL_GPADC_MV_T volt) +{ + uint32_t meanVolt = 0; + TRACE(3,"%s %d irq:0x%04x",__func__, volt, irq_val); + + if (volt == HAL_GPADC_BAD_VALUE) + { + return; + } + + ntc_capture_measure.voltage[ntc_capture_measure.index++%NTC_CAPTURE_STABLE_COUNT] = volt; + + if (ntc_capture_measure.index > NTC_CAPTURE_STABLE_COUNT) + { + for (uint8_t i=0; i + + +#define APP_BATTERY_LEVEL_MIN (0) + +#ifdef __INTERCONNECTION__ +#define APP_BATTERY_LEVEL_MAX (100) +#define APP_BATTERY_DEFAULT_INFO 0xE4 + +typedef struct +{ + uint8_t chargingStatus : 1; + uint8_t batteryLevel : 7; +}APP_BATTERY_INFO_T; + +uint8_t* app_battery_get_mobile_support_self_defined_command_p(void); +#else // #ifdef __INTERCONNECTION__ +#define APP_BATTERY_LEVEL_MAX (9) +#endif // #ifdef __INTERCONNECTION__ + +#define APP_BATTERY_LEVEL_NUM (APP_BATTERY_LEVEL_MAX-APP_BATTERY_LEVEL_MIN+1) + +enum APP_BATTERY_STATUS_T { + APP_BATTERY_STATUS_NORMAL, + APP_BATTERY_STATUS_CHARGING, + APP_BATTERY_STATUS_OVERVOLT, + APP_BATTERY_STATUS_UNDERVOLT, + APP_BATTERY_STATUS_PDVOLT, + APP_BATTERY_STATUS_PLUGINOUT, + APP_BATTERY_STATUS_INVALID, + + APP_BATTERY_STATUS_QTY +}; + +#define APP_BATTERY_OPEN_MODE_INVALID (-1) +#define APP_BATTERY_OPEN_MODE_NORMAL (0) +#define APP_BATTERY_OPEN_MODE_CHARGING (1) +#define APP_BATTERY_OPEN_MODE_CHARGING_PWRON (2) + +typedef uint16_t APP_BATTERY_MV_T; + +enum APP_BATTERY_CHARGER_T +{ + APP_BATTERY_CHARGER_PLUGOUT = 0, + APP_BATTERY_CHARGER_PLUGIN, + APP_BATTERY_CHARGER_QTY, +}; + +union APP_BATTERY_MSG_PRAMS{ + APP_BATTERY_MV_T volt; + enum APP_BATTERY_CHARGER_T charger; + uint32_t prams; +}; + +typedef void (*APP_BATTERY_CB_T)(APP_BATTERY_MV_T currvolt, uint8_t currlevel,enum APP_BATTERY_STATUS_T curstatus,uint32_t status, union APP_BATTERY_MSG_PRAMS prams); + + +int app_battery_get_info(APP_BATTERY_MV_T *currvolt, uint8_t *currlevel, enum APP_BATTERY_STATUS_T *status); + +/** + * Battery App owns its own context where it will periodically update the + * battery level and state. Makes sense for it to act as a Model and publish + * battery change events to any interested users. + * + * Note: Callback will execute out of BES "App Thread" context. + * + * TODO: ideally implemented as proper observer pattern with support for multiple + * listeners + * + * Returns + * - 0: On success + * - 1: If registration failed + */ +int app_battery_register(APP_BATTERY_CB_T user_cb); + +int app_battery_open(void); + +int app_battery_start(void); + +int app_battery_stop(void); + +int app_battery_close(void); + +int app_battery_charger_indication_open(void); + +int8_t app_battery_current_level(void); + +int8_t app_battery_is_charging(void); + +int ntc_capture_open(void); + +int ntc_capture_start(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/apps/btusbaudio/Makefile b/apps/btusbaudio/Makefile new file mode 100644 index 0000000..e29b52a --- /dev/null +++ b/apps/btusbaudio/Makefile @@ -0,0 +1,41 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) + + +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y += \ + $(BT_IF_INCLUDES) \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/bt_app \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/audioflinger \ + -Iservices/nvrecord \ + -Iservices/overlay \ + -Iservices/resources \ + -Iservices/audio_process \ + -Iapps/apptester \ + -Iapps/factory \ + -Iutils/crc32 \ + -Iplatform/drivers/bt \ + -Iplatform/drivers/ana \ + -Iapps/audioplayers/rbplay \ + -Itests/anc_usb \ + -Iapps/anc/inc \ + -Iapps/ota \ + -Ithirdparty/userapi \ + -Iservices/voicepath \ + -Iservices/voicepath/gsound/gsound_service \ + -Iservices/voicepath/gsound/gsound_target \ + -Iservices/communication \ + -Iutils/cqueue \ + -Iservices/ai_voice/ama/ama_manager \ + -Iservices/ai_voice/manager \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/interconnection + + diff --git a/apps/btusbaudio/btusb_audio.c b/apps/btusbaudio/btusb_audio.c new file mode 100644 index 0000000..06b4875 --- /dev/null +++ b/apps/btusbaudio/btusb_audio.c @@ -0,0 +1,307 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "stdio.h" +#include "cmsis_os.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "app_audio.h" + +#include "a2dp_api.h" +#include "app_bt.h" +#include "btapp.h" +#include "usb_audio_app.h" +#include "btusb_audio.h" + +extern void btusbaudio_entry(void); +extern void btusbaudio_exit(void); +extern a2dp_stream_t* app_bt_get_steam(enum BT_DEVICE_ID_T id); +extern int app_bt_get_bt_addr(enum BT_DEVICE_ID_T id,bt_bdaddr_t *bdaddr); +extern bool app_bt_a2dp_service_is_connected(void); +int app_bt_A2DP_OpenStream(a2dp_stream_t *Stream, bt_bdaddr_t *Addr); +int app_bt_A2DP_CloseStream(a2dp_stream_t *Stream); + +extern bool btapp_hfp_is_call_active(void); +static bool btusb_usb_is_on = false; +static enum BTUSB_MODE btusb_mode = BTUSB_MODE_INVALID; +static bool btusb_bt_audio_is_suspend = false; + +#define BT_USB_DEBUG() //TRACE(2,"_debug: %s,%d",__func__,__LINE__) +extern struct BT_DEVICE_T app_bt_device; + +static void _btusb_stream_open(unsigned int timeout_ms) +{ + a2dp_stream_t *stream = NULL; + bt_bdaddr_t bdaddr; + uint32_t stime = 0; + uint32_t etime = 0; + + stime = hal_sys_timer_get(); + //BT_USB_DEBUG(); + stream = (a2dp_stream_t*)app_bt_get_steam(BT_DEVICE_ID_1); + + app_bt_get_bt_addr(BT_DEVICE_ID_1,&bdaddr); + if(stream) + { + //struct BT_DEVICE_T *bt_dev = &app_bt_device; + //A2DP_Register((a2dp_stream_t *)bt_dev->a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream, &a2dp_avdtpcodec, NULL, (A2dpCallback) a2dp_callback); + //AVRCP_Register((AvrcpChannel *)bt_dev->avrcp_channel[BT_DEVICE_ID_1]->avrcp_channel_handle, (AvrcpCallback)avrcp_callback_CT, BTIF_AVRCP_CT_CATEGORY_1 | BTIF_AVRCP_CT_CATEGORY_2 | BTIF_AVRCP_TG_CATEGORY_2); + BT_USB_DEBUG(); + osDelay(10); + app_bt_A2DP_OpenStream(stream,&bdaddr); + } + else + { + BT_USB_DEBUG(); + return; + } + while(1) + { + if(app_bt_a2dp_service_is_connected()){ + etime = hal_sys_timer_get(); + TRACE(1,"_debug: a2dp service connected, wait time = 0x%x.",TICKS_TO_MS(etime - stime)); + break; + } + else + { + etime = hal_sys_timer_get(); + if(TICKS_TO_MS(etime - stime) >= timeout_ms) + { + TRACE(1,"_debug: a2dp service connect timeout = 0x%x.", + TICKS_TO_MS(etime - stime)); + break; + } + osDelay(10); + } + } + //BT_USB_DEBUG(); +} + +static void _btusb_stream_close(unsigned int timeout_ms) +{ + a2dp_stream_t *stream = NULL; + uint32_t stime = 0; + uint32_t etime = 0; + + stime = hal_sys_timer_get(); + BT_USB_DEBUG(); + stream = (a2dp_stream_t*)app_bt_get_steam(BT_DEVICE_ID_1); + if(stream) + { + BT_USB_DEBUG(); + app_bt_A2DP_CloseStream(stream); + } + else + { + BT_USB_DEBUG(); + return; + } + stime = hal_sys_timer_get(); + while(1) + { + if(!app_bt_a2dp_service_is_connected()){ + //struct BT_DEVICE_T *bt_dev = &app_bt_device; + //AVRCP_Deregister(bt_dev->avrcp_channel[BT_DEVICE_ID_1]->avrcp_channel_handle); + //A2DP_Deregister(stream); + etime = hal_sys_timer_get(); + TRACE(1,"a2dp service diconnected, wait time = 0x%x.", + TICKS_TO_MS(etime - stime)); + break; + } + else + { + etime = hal_sys_timer_get(); + if(TICKS_TO_MS(etime - stime) >= timeout_ms) + { + TRACE(1,"a2dp service diconnect timeout = 0x%x.", + TICKS_TO_MS(etime - stime)); + break; + } + osDelay(10); + } + } + BT_USB_DEBUG(); +} + +static void btusb_usbaudio_entry(void) +{ + BT_USB_DEBUG(); + btusbaudio_entry(); + btusb_usb_is_on = true ; +} + +void btusb_usbaudio_open(void) +{ + BT_USB_DEBUG(); + if(!btusb_usb_is_on) + { + btusb_usbaudio_entry(); + BT_USB_DEBUG(); + } + else + { + usb_audio_app(1); + } + BT_USB_DEBUG(); +} + +void btusb_usbaudio_close(void) +{ + BT_USB_DEBUG(); + if(btusb_usb_is_on) + { + usb_audio_app(0); + BT_USB_DEBUG(); + } + else + { + BT_USB_DEBUG(); + } +} + +void btusb_btaudio_close(bool is_wait) +{ + BT_USB_DEBUG(); + //if(!btusb_bt_audio_is_suspend) + { + BT_USB_DEBUG(); + if(is_wait) + { + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_CLOSEALL, 0); + _btusb_stream_close(BTUSB_OUTTIME_MS); + } + else + { + _btusb_stream_close(0); + } + btusb_bt_audio_is_suspend = true; + } +} + +void btusb_btaudio_open(bool is_wait) +{ + BT_USB_DEBUG(); + //if(btusb_bt_audio_is_suspend) + { + TRACE(2,"%s: %d.",__func__,__LINE__); + if(is_wait) + { + _btusb_stream_open(BTUSB_OUTTIME_MS); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE, 0); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_SETUP, 0); + } + else + { + _btusb_stream_open(0); + } + TRACE(2,"%s: %d.",__func__,__LINE__); + btusb_bt_audio_is_suspend = false; + } +} + +void btusb_switch(enum BTUSB_MODE mode) +{ + //BT_USB_DEBUG(); + if(mode != BTUSB_MODE_BT && mode != BTUSB_MODE_USB) + { + ASSERT(0, "%s:%d, mode = %d.",__func__,__LINE__,mode); + } + + if(btusb_mode == mode) { + BT_USB_DEBUG(); + return; + } + + if(btusb_mode == BTUSB_MODE_INVALID) + { + if(mode == BTUSB_MODE_BT) { + TRACE(1,"%s: switch to BT mode.",__func__); + btusb_mode = BTUSB_MODE_BT; + } + else { + TRACE(1,"%s: switch to USB mode.",__func__); + //btusb_btaudio_close(true); + osDelay(500); + btusb_usbaudio_open(); + btusb_mode = BTUSB_MODE_USB; + } + } + else + { + if(mode == BTUSB_MODE_BT) { + TRACE(1,"%s: switch to BT mode.",__func__); + if(btusb_usb_is_on) + { + TRACE(1,"%s: btusb_usbaudio_close.",__func__); + btusb_usbaudio_close(); + TRACE(1,"%s: btusb_usbaudio_close done.",__func__); + osDelay(500); + } + btusb_mode = BTUSB_MODE_BT; + btusb_btaudio_open(true); + TRACE(1,"%s: switch to BT mode done.",__func__); + } + else { + if(btapp_hfp_is_call_active() == 1) + { + TRACE(1,"%s: hfp is call active.",__func__); + return; + } + TRACE(1,"%s: switch to USB mode.",__func__); + btusb_btaudio_close(true); + TRACE(1,"%s: btusb_btaudio_close done.",__func__); + osDelay(500); + btusb_usbaudio_open(); + btusb_mode = BTUSB_MODE_USB; + TRACE(1,"%s: switch to USB mode done.",__func__); + } + } +} + +bool btusb_is_bt_mode(void) +{ + BT_USB_DEBUG(); + return btusb_mode == BTUSB_MODE_BT ? true : false; +} + +bool btusb_is_usb_mode(void) +{ + return btusb_mode == BTUSB_MODE_USB ? true : false; +} + + +#if defined(BT_USB_AUDIO_DUAL_MODE_TEST) +void test_btusb_switch(void) +{ + if(btusb_mode == BTUSB_MODE_BT) + { + btusb_switch(BTUSB_MODE_USB); + } + else + { + btusb_switch(BTUSB_MODE_BT); + } +} + +void test_btusb_switch_to_bt(void) +{ + btusb_switch(BTUSB_MODE_BT); +} + +void test_btusb_switch_to_usb(void) +{ + btusb_switch(BTUSB_MODE_USB); +} +#endif diff --git a/apps/btusbaudio/btusb_audio.h b/apps/btusbaudio/btusb_audio.h new file mode 100644 index 0000000..134cae9 --- /dev/null +++ b/apps/btusbaudio/btusb_audio.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _BTUSB_AUDIO_H_ +#define _BTUSB_AUDIO_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#define BTUSB_OUTTIME_MS 1000 +enum BTUSB_MODE{ + BTUSB_MODE_BT, + BTUSB_MODE_USB, + BTUSB_MODE_INVALID +}; + +void btusb_usbaudio_open(void); +void btusb_usbaudio_close(void); +void btusb_btaudio_open(bool is_wait); +void btusb_btaudio_close(bool is_wait); +void btusb_switch(enum BTUSB_MODE mode); +bool btusb_is_bt_mode(void); +bool btusb_is_usb_mode(void); +#ifdef __cplusplus +} +#endif +#endif // _BTUSB_AUDIO_H_ + diff --git a/apps/btusbaudio/usbaudio_thread.c b/apps/btusbaudio/usbaudio_thread.c new file mode 100644 index 0000000..1772489 --- /dev/null +++ b/apps/btusbaudio/usbaudio_thread.c @@ -0,0 +1,139 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "app_utils.h" +#include "usb_audio_app.h" +#include "usbaudio_thread.h" + +static void usb_thread(void const *argument); +osThreadDef(usb_thread, osPriorityHigh, 1, 2048, "usb"); + +osMailQDef (usb_mailbox, USB_MAILBOX_MAX, USB_MESSAGE); +static osMailQId usb_mailbox = NULL; +static uint8_t usb_mailbox_cnt = 0; +#define USBAUDIO_DEBUG TRACE +static int usb_mailbox_init(void) +{ + USBAUDIO_DEBUG("%s,%d",__func__,__LINE__); + usb_mailbox = osMailCreate(osMailQ(usb_mailbox), NULL); + if (usb_mailbox == NULL) { + USBAUDIO_DEBUG("Failed to Create usb_mailbox\n"); + return -1; + } + usb_mailbox_cnt = 0; + return 0; +} + +int usb_mailbox_put(USB_MESSAGE* msg_src) +{ + osStatus status; + USB_MESSAGE *msg_p = NULL; + + USBAUDIO_DEBUG("%s,%d",__func__,__LINE__); + if(usb_mailbox_cnt >= 1) + { + USBAUDIO_DEBUG("%s,%d usb_mailbox_cnt = %d.", + __func__,__LINE__,usb_mailbox_cnt); + return 0; + } + msg_p = (USB_MESSAGE*)osMailAlloc(usb_mailbox, 0); + ASSERT(msg_p, "osMailAlloc error"); + msg_p->id = msg_src->id; + msg_p->ptr = msg_src->ptr; + msg_p->param0 = msg_src->param0; + msg_p->param1 = msg_src->param1; + + status = osMailPut(usb_mailbox, msg_p); + if (osOK == status) + usb_mailbox_cnt++; + USBAUDIO_DEBUG("%s,%d,usb_mailbox_cnt = %d.",__func__,__LINE__,usb_mailbox_cnt); + return (int)status; +} + +int usb_mailbox_free(USB_MESSAGE* msg_p) +{ + osStatus status; + + USBAUDIO_DEBUG("%s,%d",__func__,__LINE__); + status = osMailFree(usb_mailbox, msg_p); + if (osOK == status) + usb_mailbox_cnt--; + USBAUDIO_DEBUG("%s,%d,usb_mailbox_cnt = %d.",__func__,__LINE__,usb_mailbox_cnt); + return (int)status; +} + +int usb_mailbox_get(USB_MESSAGE **msg_p) +{ + osEvent evt; + evt = osMailGet(usb_mailbox, osWaitForever); + if (evt.status == osEventMail) { + *msg_p = (USB_MESSAGE*)evt.value.p; + return 0; + } + return -1; +} + +static void usb_thread(void const *argument) +{ + // USB_FUNC_T usb_funcp; + USBAUDIO_DEBUG("%s,%d",__func__,__LINE__); + while(1){ + USB_MESSAGE *msg_p = NULL; + + if (!usb_mailbox_get(&msg_p)) { + //TRACE(2,"_debug: %s,%d",__func__,__LINE__); + USBAUDIO_DEBUG("usb_thread: id = 0x%x, ptr = 0x%x,param0 = 0x%x,param1 = 0x%x.", + msg_p->id,msg_p->ptr,msg_p->param0,msg_p->param1); + usb_mailbox_free(msg_p); + usb_audio_app_loop(); + + } + } +} + +static void usb_enqueue_cmd(uint32_t data) +{ + USB_MESSAGE usb_msg; + + usb_msg.id = 0; + usb_msg.param0 = 0; + usb_msg.param1 = 0; + usb_msg.ptr = 0; + usb_mailbox_put(&usb_msg); +} + +int usb_os_init(void) +{ + osThreadId usb_tid; + + USBAUDIO_DEBUG("%s,%d",__func__,__LINE__); + if (usb_mailbox_init()) { + USBAUDIO_DEBUG("_debug: %s,%d",__func__,__LINE__); + return -1; + } + usb_tid = osThreadCreate(osThread(usb_thread), NULL); + if (usb_tid == NULL) { + USBAUDIO_DEBUG("Failed to Create usb_thread\n"); + return 0; + } + + usb_audio_set_enqueue_cmd_callback(usb_enqueue_cmd); + + return 0; +} + + diff --git a/apps/btusbaudio/usbaudio_thread.h b/apps/btusbaudio/usbaudio_thread.h new file mode 100644 index 0000000..c9ecc07 --- /dev/null +++ b/apps/btusbaudio/usbaudio_thread.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __USB_THREAD_H__ +#define __USB_THREAD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define USB_MAILBOX_MAX (20) + +typedef struct { + uint32_t id; + uint32_t ptr; + uint32_t param0; + uint32_t param1; +} USB_MESSAGE; + + +//typedef int (*USB_MOD_HANDLER_T)(USB_MESSAGE_BODY *); +typedef void (*USB_FUNC_T)(uint32_t, uint32_t); + +int usb_mailbox_put(USB_MESSAGE* msg_src); + +int usb_mailbox_free(USB_MESSAGE* msg_p); + +int usb_mailbox_get(USB_MESSAGE** msg_p); + +int usb_os_init(void); + +#ifdef __cplusplus + } +#endif + +#endif // __USB_THREAD_H__ + diff --git a/apps/cmd/Makefile b/apps/cmd/Makefile new file mode 100644 index 0000000..0fd0a4c --- /dev/null +++ b/apps/cmd/Makefile @@ -0,0 +1,10 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +subdir-ccflags-y += \ + -Iservices/audio_process \ + -Iservices/multimedia/audio/process/filters/include diff --git a/apps/cmd/app_cmd.cpp b/apps/cmd/app_cmd.cpp new file mode 100644 index 0000000..be00252 --- /dev/null +++ b/apps/cmd/app_cmd.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef __PC_CMD_UART__ +#include "cmsis_os.h" +#include "list.h" +#include "string.h" +#include "app_thread.h" +#include "app_cmd.h" +#include "hal_cmd.h" +#include "hal_trace.h" +#include "audio_process.h" + +#define APP_CMD_TRACE(s,...) TRACE(s, ##__VA_ARGS__) + +void cmd_event_process(hal_cmd_rx_status_t status) +{ + APP_CMD_TRACE(1,"%s",__func__); + APP_MESSAGE_BLOCK msg; + msg.mod_id = APP_MODUAL_CMD; + msg.msg_body.message_id = status; + msg.msg_body.message_ptr = (uint32_t)NULL; + app_mailbox_put(&msg); + return; +} + +static int app_cmd_handle_process(APP_MESSAGE_BODY *msg_body) +{ + hal_cmd_run((hal_cmd_rx_status_t)msg_body->message_id); + return 0; +} + +uint8_t app_cmd_flag = 0; + +void app_cmd_open(void) +{ + APP_CMD_TRACE(1,"%s",__func__); + + app_cmd_flag = 1; + + app_set_threadhandle(APP_MODUAL_CMD, app_cmd_handle_process); + hal_cmd_set_callback(cmd_event_process); + hal_cmd_open(); + return; +} + +void app_cmd_close(void) +{ + APP_CMD_TRACE(1,"%s",__func__); + if(app_cmd_flag) + { + app_cmd_flag = 0; + hal_cmd_close(); + app_set_threadhandle(APP_MODUAL_CMD, NULL); + } + return; +} +#endif + diff --git a/apps/cmd/app_cmd.h b/apps/cmd/app_cmd.h new file mode 100644 index 0000000..eb6f7f3 --- /dev/null +++ b/apps/cmd/app_cmd.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_CMD_H__ +#define __APP_CMD_H__ +#ifdef __PC_CMD_UART__ + +#include "hal_cmd.h" +typedef struct { + void *param; +} APP_CMD_HANDLE; + +void app_cmd_open(void); + +void app_cmd_close(void); +#endif +#endif//__FMDEC_H__ diff --git a/apps/common/Makefile b/apps/common/Makefile new file mode 100644 index 0000000..f49635c --- /dev/null +++ b/apps/common/Makefile @@ -0,0 +1,17 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +subdir-ccflags-y += \ + -Iplatform/drivers/ana \ + -Iservices/ibrt_ui/inc \ + -Iservices/ibrt_core/inc + +ifeq ($(RAND_FROM_MIC),1) +subdir-ccflags-y += \ + -Iservices/bt_app \ + -Iservices/app_ai/inc +endif diff --git a/apps/common/app_spec_ostimer.cpp b/apps/common/app_spec_ostimer.cpp new file mode 100644 index 0000000..7d94eb6 --- /dev/null +++ b/apps/common/app_spec_ostimer.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "stdint.h" +#include "app_spec_ostimer.h" +#include "hal_trace.h" + + +/// Create timer +osStatus app_spec_timer_create (SPEC_TIMER_CTX_T *spec_timer_ctx, const osTimerDef_t *timer_def, os_timer_type type, void *argument) +{ + spec_timer_ctx->type = type; + spec_timer_ctx->argument = argument; + spec_timer_ctx->timerid = osTimerCreate(timer_def, type, spec_timer_ctx); + return spec_timer_ctx->timerid ? osOK: osErrorOS; +} + +/// Start or restart timer +osStatus app_spec_timer_start (SPEC_TIMER_CTX_T *spec_timer_ctx, uint32_t millisec) +{ + osStatus status; + + //TRACE(1,"%s", __func__); + if (millisec > UINT16_MAX){ + spec_timer_ctx->interval = millisec; + spec_timer_ctx->ctx = millisec; + status = osTimerStart(spec_timer_ctx->timerid, UINT16_MAX); + }else{ + spec_timer_ctx->interval = millisec; + spec_timer_ctx->ctx = millisec; + status = osTimerStart(spec_timer_ctx->timerid, (uint32_t)millisec); + } + + return status; +} + +/// Stop timer +osStatus app_spec_timer_stop (SPEC_TIMER_CTX_T *spec_timer_ctx) +{ + return osTimerStop(spec_timer_ctx->timerid); +} + +/// Delete timer +osStatus app_spec_timer_delete (SPEC_TIMER_CTX_T *spec_timer_ctx) +{ + return osTimerDelete(spec_timer_ctx->timerid); +} + +void app_spec_timer_handler(void const *para) +{ + SPEC_TIMER_CTX_T *spec_timer_ctx = (SPEC_TIMER_CTX_T *)para; + + if (spec_timer_ctx->ctx > UINT16_MAX){ + spec_timer_ctx->ctx -= UINT16_MAX; + if (spec_timer_ctx->ctx > UINT16_MAX){ + osTimerStart(spec_timer_ctx->timerid, UINT16_MAX); + }else{ + osTimerStart(spec_timer_ctx->timerid, spec_timer_ctx->ctx); + } + }else{ + (*spec_timer_ctx->ptimer)(spec_timer_ctx->argument); + if (spec_timer_ctx->type == osTimerPeriodic){ + app_spec_timer_start(spec_timer_ctx, spec_timer_ctx->interval); + } + } +} + +#if 0 +//tester +uint32_t ibrt_test_arg; +void app_tws_ibrt_test_timer_cb(void const *para); +specTimerDef (IBRT_TEST_TIMER, app_tws_ibrt_test_timer_cb); + +void app_tws_ibrt_test_timer_cb(void const *para) +{ + TRACE(2,"%s %08x", __func__, para); +} + +void app_tws_ibrt_test_timer(void) +{ + app_spec_timer_create(specTimerCtx(IBRT_TEST_TIMER), specTimer(IBRT_TEST_TIMER), osTimerOnce, &ibrt_test_arg); + app_spec_timer_start(specTimerCtx(IBRT_TEST_TIMER), 0x10100); +} +#endif diff --git a/apps/common/app_spec_ostimer.h b/apps/common/app_spec_ostimer.h new file mode 100644 index 0000000..6d37803 --- /dev/null +++ b/apps/common/app_spec_ostimer.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_SPEC_OSTIMER__ +#define __APP_SPEC_OSTIMER__ +#include "cmsis_os.h" + +typedef struct{ + osTimerId timerid; + os_timer_type type; + os_ptimer ptimer; + uint32_t interval; + uint32_t ctx; + void *argument; +}SPEC_TIMER_CTX_T; + +#define specTimerDef(name, function) \ +SPEC_TIMER_CTX_T spec_timer_ctx_##name = \ +{NULL, osTimerOnce, function, 0, 0, NULL}; \ +osTimerDef(name, app_spec_timer_handler) + +#define specTimer osTimer + +#define specTimerCtx(name) \ +&spec_timer_ctx_##name + +void app_spec_timer_handler(void const *para); +osStatus app_spec_timer_create (SPEC_TIMER_CTX_T *spec_timer_ctx, const osTimerDef_t *timer_def, os_timer_type type, void *argument); +osStatus app_spec_timer_start (SPEC_TIMER_CTX_T *spec_timer_ctx, uint32_t millisec); +osStatus app_spec_timer_stop (SPEC_TIMER_CTX_T *spec_timer_ctx); +osStatus app_spec_timer_delete (SPEC_TIMER_CTX_T *spec_timer_ctx); + +#endif diff --git a/apps/common/app_thread.c b/apps/common/app_thread.c new file mode 100644 index 0000000..14cce17 --- /dev/null +++ b/apps/common/app_thread.c @@ -0,0 +1,164 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "app_utils.h" +#include "app_thread.h" + + +static APP_MOD_HANDLER_T mod_handler[APP_MODUAL_NUM]; + +static void app_thread(void const *argument); +osThreadDef(app_thread, osPriorityHigh, 1, 1024*3, "app_thread"); + +osMailQDef (app_mailbox, APP_MAILBOX_MAX, APP_MESSAGE_BLOCK); +static osMailQId app_mailbox = NULL; +static uint8_t app_mailbox_cnt = 0; +osThreadId app_thread_tid; + +static int app_mailbox_init(void) +{ + app_mailbox = osMailCreate(osMailQ(app_mailbox), NULL); + if (app_mailbox == NULL) { + TRACE(0,"Failed to Create app_mailbox\n"); + return -1; + } + app_mailbox_cnt = 0; + return 0; +} + +int app_mailbox_put(APP_MESSAGE_BLOCK* msg_src) +{ + osStatus status; + + APP_MESSAGE_BLOCK *msg_p = NULL; + + msg_p = (APP_MESSAGE_BLOCK*)osMailAlloc(app_mailbox, 0); + + if (!msg_p){ + osEvent evt; + TRACE_IMM(0,"osMailAlloc error dump"); + for (uint8_t i=0; imod_id, + ((APP_MESSAGE_BLOCK *)(evt.value.p))->src_thread, + ((APP_MESSAGE_BLOCK *)(evt.value.p))->system_time, + ((APP_MESSAGE_BLOCK *)(evt.value.p))->msg_body.message_id, + ((APP_MESSAGE_BLOCK *)(evt.value.p))->msg_body.message_ptr, + ((APP_MESSAGE_BLOCK *)(evt.value.p))->msg_body.message_Param0, + ((APP_MESSAGE_BLOCK *)(evt.value.p))->msg_body.message_Param1, + ((APP_MESSAGE_BLOCK *)(evt.value.p))->msg_body.message_Param2); + }else{ + TRACE_IMM(2,"cnt:%d %d", i, evt.status); + break; + } + } + TRACE_IMM(0,"osMailAlloc error dump end"); + } + + ASSERT(msg_p, "osMailAlloc error"); + msg_p->src_thread = (uint32_t)osThreadGetId(); + msg_p->dest_thread = (uint32_t)NULL; + msg_p->system_time = hal_sys_timer_get(); + msg_p->mod_id = msg_src->mod_id; + msg_p->msg_body.message_id = msg_src->msg_body.message_id; + msg_p->msg_body.message_ptr = msg_src->msg_body.message_ptr; + msg_p->msg_body.message_Param0 = msg_src->msg_body.message_Param0; + msg_p->msg_body.message_Param1 = msg_src->msg_body.message_Param1; + msg_p->msg_body.message_Param2 = msg_src->msg_body.message_Param2; + + status = osMailPut(app_mailbox, msg_p); + if (osOK == status) + app_mailbox_cnt++; + return (int)status; +} + +int app_mailbox_free(APP_MESSAGE_BLOCK* msg_p) +{ + osStatus status; + + status = osMailFree(app_mailbox, msg_p); + if (osOK == status) + app_mailbox_cnt--; + + return (int)status; +} + +int app_mailbox_get(APP_MESSAGE_BLOCK** msg_p) +{ + osEvent evt; + evt = osMailGet(app_mailbox, osWaitForever); + if (evt.status == osEventMail) { + *msg_p = (APP_MESSAGE_BLOCK *)evt.value.p; + return 0; + } + return -1; +} + +static void app_thread(void const *argument) +{ + while(1){ + APP_MESSAGE_BLOCK *msg_p = NULL; + + if (!app_mailbox_get(&msg_p)) { + if (msg_p->mod_id < APP_MODUAL_NUM) { + if (mod_handler[msg_p->mod_id]) { + int ret = mod_handler[msg_p->mod_id](&(msg_p->msg_body)); + if (ret) + TRACE(2,"mod_handler[%d] ret=%d", msg_p->mod_id, ret); + } + } + app_mailbox_free(msg_p); + } + } +} + +int app_os_init(void) +{ + if (app_mailbox_init()) + return -1; + + app_thread_tid = osThreadCreate(osThread(app_thread), NULL); + if (app_thread_tid == NULL) { + TRACE(0,"Failed to Create app_thread\n"); + return 0; + } + return 0; +} + +int app_set_threadhandle(enum APP_MODUAL_ID_T mod_id, APP_MOD_HANDLER_T handler) +{ + if (mod_id>=APP_MODUAL_NUM) + return -1; + + mod_handler[mod_id] = handler; + return 0; +} + +void * app_os_tid_get(void) +{ + return (void *)app_thread_tid; +} + +bool app_is_module_registered(enum APP_MODUAL_ID_T mod_id) +{ + return mod_handler[mod_id]; +} + diff --git a/apps/common/app_thread.h b/apps/common/app_thread.h new file mode 100644 index 0000000..fe763d4 --- /dev/null +++ b/apps/common/app_thread.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_THREAD_H__ +#define __APP_THREAD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define APP_MAILBOX_MAX (20) + +enum APP_MODUAL_ID_T { + APP_MODUAL_KEY = 0, + APP_MODUAL_AUDIO, + APP_MODUAL_BATTERY, + APP_MODUAL_BT, + APP_MODUAL_FM, + APP_MODUAL_SD, + APP_MODUAL_LINEIN, + APP_MODUAL_USBHOST, + APP_MODUAL_USBDEVICE, + APP_MODUAL_WATCHDOG, + APP_MODUAL_AUDIO_MANAGE, + APP_MODUAL_ANC, + APP_MODUAL_SMART_MIC, +#ifdef __PC_CMD_UART__ + APP_MODUAL_CMD, +#endif +#ifdef TILE_DATAPATH + APP_MODUAL_TILE, +#endif + APP_MODUAL_MIC, +#ifdef VOICE_DETECTOR_EN + APP_MODUAL_VOICE_DETECTOR, +#endif + APP_MODUAL_CUSTOM_FUNCTION, + APP_MODUAL_OHTER, + APP_MODUAL_WNR, + + APP_MODUAL_NUM +}; + +typedef struct { + uint32_t message_id; + uint32_t message_ptr; + uint32_t message_Param0; + uint32_t message_Param1; + uint32_t message_Param2; +} APP_MESSAGE_BODY; + +typedef struct { + uint32_t src_thread; + uint32_t dest_thread; + uint32_t system_time; + uint32_t mod_id; + APP_MESSAGE_BODY msg_body; +} APP_MESSAGE_BLOCK; + +typedef int (*APP_MOD_HANDLER_T)(APP_MESSAGE_BODY *); + +int app_mailbox_put(APP_MESSAGE_BLOCK* msg_src); + +int app_mailbox_free(APP_MESSAGE_BLOCK* msg_p); + +int app_mailbox_get(APP_MESSAGE_BLOCK** msg_p); + +int app_os_init(void); + +int app_set_threadhandle(enum APP_MODUAL_ID_T mod_id, APP_MOD_HANDLER_T handler); + +void * app_os_tid_get(void); + +bool app_is_module_registered(enum APP_MODUAL_ID_T mod_id); + +#ifdef __cplusplus + } +#endif + +#endif//__FMDEC_H__ diff --git a/apps/common/app_utils.c b/apps/common/app_utils.c new file mode 100644 index 0000000..0849b14 --- /dev/null +++ b/apps/common/app_utils.c @@ -0,0 +1,281 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "hal_wdt.h" +#include "pmu.h" +#include "analog.h" +#include "app_utils.h" +#ifdef RTOS +#include "cmsis_os.h" +#endif + +#define FREQ_FREE 0UL +#define FREQ_26M 26UL +#define FREQ_52M 52UL +#define FREQ_78M 78UL +#define FREQ_104M 104UL +#define FREQ_208M 208UL + +/* + * qos_users, quality of services users, this kind of user must run with the + * minist frequency they requiested, if there are more users, the frequency + * should be boost for these users + * e.g. the key word recorgnithion function request 26M Hz, and the music + * also need 26M, if both of them are running, the cpu freq should boost to + * 26M + 26M = 52M Hz + */ +/* + * NOTE: + * The macro QOS_USERS works only when the APP_SYSFREQ_USER_APP_XXX is not large than + * 32, currently this works, but if the are more user, another way needed + */ +#define QOS_USERS ((1 << (APP_SYSFREQ_USER_AI_VOICE)) | \ + (1 << (APP_SYSFREQ_USER_BT_A2DP))) + +static const uint32_t freq_map[] = { + [HAL_CMU_FREQ_32K] = FREQ_FREE, + [HAL_CMU_FREQ_26M] = FREQ_26M, + [HAL_CMU_FREQ_52M] = FREQ_52M, + [HAL_CMU_FREQ_78M] = FREQ_78M, + [HAL_CMU_FREQ_104M] = FREQ_104M, + [HAL_CMU_FREQ_208M] = FREQ_208M, +}; + +static const uint32_t user_map[] = { + [0] = APP_SYSFREQ_USER_AI_VOICE, + [1] = APP_SYSFREQ_USER_BT_A2DP, +}; +/* + * qos_freqs_map + * filled with user's freq, one user's freq occupy 4bits, + * that limit the frequecy number is not large than 16 + * + * bit field structure: + ----------------------------------------------------- + |user7 | user6 |..................|user1 | user 0| + ----------------------------------------------------- + |31~28 | 27~24 |..................|7~4 | 3~0 | + ----------------------------------------------------- + * + * Ok, this is ugly, but there is not so much frequecy level, + * and maybe work for a long time + */ +static uint32_t qos_freqs_map; + +/* + * qos_users_map + * filled with user's number, one user's occupy 1 bit, + * + bit field structure: + ----------------------------------------------------- + |user31~7(reseverd)| user7 |........| user 1| user 0| + ----------------------------------------------------- + * + */ +static uint32_t qos_users_map; + +static int app_qosfreq_req(enum APP_SYSFREQ_USER_T user, enum APP_SYSFREQ_FREQ_T freq) +{ + int ret; + int qos_freq_num = 0; + uint32_t max_qos_freq = 0; + int user_idx; + int i; + uint32_t lock; + + if (freq >= APP_SYSFREQ_FREQ_QTY) + return -1; + + lock = int_lock(); + for (i = 0; i < ARRAY_SIZE(user_map); i++) { + if (user == user_map[i]) { + break; + } + } + + if (i >= ARRAY_SIZE(user_map)) { + int_unlock(lock); + ASSERT(0, "can not find qos user"); + return 0; + } + + user_idx = i; + if ((int)freq != (int)HAL_CMU_FREQ_32K) { // require freq + qos_freqs_map &= ~(0xf << (4 * i)); + qos_freqs_map |= freq << (4 * i); + qos_users_map |= 1 << user_idx; + } else { //release freq + qos_freqs_map &= ~(0xf << (4 * i)); + qos_users_map &= ~ (1 << user_idx); + } + + //scan the qos_user_map and sum every user's request freq + for(i = 0; i < ARRAY_SIZE(user_map); i++) { + if ((qos_users_map >> i) & 0x1) { + uint32_t real_freq; + int freq_num; + + freq_num = (qos_freqs_map >> (4 * i )) & 0xf; + real_freq = freq_map[freq_num]; + max_qos_freq += real_freq; + } + } + + for (i = 0; i < ARRAY_SIZE(freq_map); i++) { + if (i) { + if ((max_qos_freq > freq_map[i-1]) && (max_qos_freq <= freq_map[i])) { + qos_freq_num = i; + break; + } + } else { + if (max_qos_freq == freq_map[i]) { + qos_freq_num = i; + break; + } + } + } + + if (i >= ARRAY_SIZE(freq_map)) { + qos_freq_num = (HAL_CMU_FREQ_QTY - 1); + int_unlock(lock); + TRACE(0, "WARNING: required sysfreq exceed"); + // ASSERT(0, "can not find actual freq"); + return 0; + } + + user = APP_SYSFREQ_USER_QOS; + TRACE(2, "User %d require sysfreq %d", user, qos_freq_num); + ret = hal_sysfreq_req((enum HAL_SYSFREQ_USER_T)user, (enum HAL_CMU_FREQ_T)qos_freq_num); + + int_unlock(lock); + return ret; +} + +int app_sysfreq_req(enum APP_SYSFREQ_USER_T user, enum APP_SYSFREQ_FREQ_T freq) +{ + int ret; + + // if user is qos user + if ((1 << user) & QOS_USERS) { + ret = app_qosfreq_req(user, freq); + } else { // if user is NOT qos user + ret = hal_sysfreq_req((enum HAL_SYSFREQ_USER_T)user, (enum HAL_CMU_FREQ_T)freq); + } + + return ret; +} + +#ifdef RTOS + +extern int rtx_task_idle_health_check(void); +static void watchdog_ping_handler(void const *n); +static osTimerId wdt_ping_timer_id; +osTimerDef(wdt_ping_timer, watchdog_ping_handler); +static uint32_t wdt_ping_period; + +static void watchdog_ping(void) +{ + hal_wdt_ping(HAL_WDT_ID_0); +#ifndef CHIP_BEST2000 + pmu_wdt_feed(); +#endif +} + +static void app_wdt_irq_handle(enum HAL_WDT_ID_T id, uint32_t status) +{ + analog_aud_codec_mute(); + ASSERT(0, "%s id:%d status:%d",__func__, id, status); +} + +static void pmu_wdt_irq_handle(void) +{ + analog_aud_codec_mute(); + ASSERT(1, "%s", __func__); +} + +static void watchdog_ping_handler(void const *unused) +{ + int ret; + + watchdog_ping(); + ret = rtx_task_idle_health_check(); + if (ret < 0) { + ASSERT(0, "System soft lockup"); + } + + osTimerStart(wdt_ping_timer_id, wdt_ping_period); +} + +int app_wdt_open(int seconds) +{ + uint32_t lock = int_lock(); + + hal_wdt_set_irq_callback(HAL_WDT_ID_0, app_wdt_irq_handle); + hal_wdt_set_timeout(HAL_WDT_ID_0, seconds); + hal_wdt_start(HAL_WDT_ID_0); + pmu_wdt_set_irq_handler(pmu_wdt_irq_handle); +#ifndef CHIP_BEST2000 + pmu_wdt_config(seconds * 1100, seconds * 1100); + pmu_wdt_start(); +#endif + int_unlock(lock); + wdt_ping_timer_id = osTimerCreate(osTimer(wdt_ping_timer), osTimerOnce, NULL); + if (!wdt_ping_timer_id) { + TRACE(0,"Warning: can not create watchdog ping timer"); + return -1; + } + wdt_ping_period = seconds * 1000 / 4; + + osTimerStart(wdt_ping_timer_id, wdt_ping_period); + return 0; +} + +int app_wdt_reopen(int seconds) +{ + uint32_t lock = int_lock(); + hal_wdt_stop(HAL_WDT_ID_0); + hal_wdt_set_timeout(HAL_WDT_ID_0, seconds); + hal_wdt_start(HAL_WDT_ID_0); +#ifndef CHIP_BEST2000 + pmu_wdt_config(seconds * 1000, seconds * 1000); + pmu_wdt_start(); +#endif + int_unlock(lock); + + osTimerStart(wdt_ping_timer_id, wdt_ping_period); + return 0; +} + +int app_wdt_close(void) +{ + uint32_t lock; + + osTimerStop(wdt_ping_timer_id); + + lock = int_lock(); + hal_wdt_stop(HAL_WDT_ID_0); +#ifndef CHIP_BEST2000 + pmu_wdt_stop(); +#endif + int_unlock(lock); + + return 0; +} + +#endif + diff --git a/apps/common/app_utils.h b/apps/common/app_utils.h new file mode 100644 index 0000000..912d6cc --- /dev/null +++ b/apps/common/app_utils.h @@ -0,0 +1,108 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_UTILS_H__ +#define __APP_UTILS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_sysfreq.h" + +// APP_SYSFREQ_USER_APP_0 is APP_MAIN +#define APP_SYSFREQ_USER_BT_MAIN APP_SYSFREQ_USER_APP_1 +#define APP_SYSFREQ_USER_HCI APP_SYSFREQ_USER_APP_2 +#define APP_SYSFREQ_USER_BT_A2DP APP_SYSFREQ_USER_APP_3 +#define APP_SYSFREQ_USER_UNUSED APP_SYSFREQ_USER_APP_4 +#define APP_SYSFREQ_USER_AI_VOICE APP_SYSFREQ_USER_APP_5 +#define APP_SYSFREQ_USER_BT_SCO APP_SYSFREQ_USER_APP_6 +#define APP_SYSFREQ_USER_OTA APP_SYSFREQ_USER_APP_7 +#define APP_SYSFREQ_USER_PROMPT_MIXER APP_SYSFREQ_USER_APP_8 +#define APP_SYSFREQ_USER_APP_NT APP_SYSFREQ_USER_APP_9 +#define APP_SYSFREQ_USER_ANC_WNR APP_SYSFREQ_USER_APP_10 +#ifdef __RAND_FROM_MIC__ +#define APP_SYSFREQ_USER_RANDOM APP_SYSFREQ_USER_APP_11 +#endif +#ifdef __DUAL_MIC_RECORDING__ +#define APP_SYSFREQ_USER_RECORDING APP_SYSFREQ_USER_APP_12 +#endif +/* + * Pseudo user, if one of user is belong to qos(quality of service) user, + * when request cpu freq, it will changed to this user + */ +#define APP_SYSFREQ_USER_QOS APP_SYSFREQ_USER_APP_12 + +enum APP_SYSFREQ_USER_T { + APP_SYSFREQ_USER_APP_INIT = HAL_SYSFREQ_USER_INIT, + APP_SYSFREQ_USER_APP_0 = HAL_SYSFREQ_USER_APP_0, + APP_SYSFREQ_USER_APP_1 = HAL_SYSFREQ_USER_APP_1, + APP_SYSFREQ_USER_APP_2 = HAL_SYSFREQ_USER_APP_2, + APP_SYSFREQ_USER_APP_3 = HAL_SYSFREQ_USER_APP_3, + APP_SYSFREQ_USER_APP_4 = HAL_SYSFREQ_USER_APP_4, + APP_SYSFREQ_USER_APP_5 = HAL_SYSFREQ_USER_APP_5, + APP_SYSFREQ_USER_APP_6 = HAL_SYSFREQ_USER_APP_6, + APP_SYSFREQ_USER_APP_7 = HAL_SYSFREQ_USER_APP_7, + APP_SYSFREQ_USER_APP_8 = HAL_SYSFREQ_USER_APP_8, + APP_SYSFREQ_USER_APP_9 = HAL_SYSFREQ_USER_APP_9, + APP_SYSFREQ_USER_APP_10 = HAL_SYSFREQ_USER_APP_10, + APP_SYSFREQ_USER_APP_11 = HAL_SYSFREQ_USER_APP_11, + APP_SYSFREQ_USER_APP_12 = HAL_SYSFREQ_USER_APP_12, + APP_SYSFREQ_USER_APP_13 = HAL_SYSFREQ_USER_APP_13, + APP_SYSFREQ_USER_APP_14 = HAL_SYSFREQ_USER_APP_14, + APP_SYSFREQ_USER_APP_15 = HAL_SYSFREQ_USER_APP_15, + APP_SYSFREQ_USER_QTY +}; + +enum APP_SYSFREQ_FREQ_T { + APP_SYSFREQ_32K = HAL_CMU_FREQ_32K, + APP_SYSFREQ_26M = HAL_CMU_FREQ_26M, + APP_SYSFREQ_52M = HAL_CMU_FREQ_52M, + APP_SYSFREQ_78M = HAL_CMU_FREQ_78M, + APP_SYSFREQ_104M = HAL_CMU_FREQ_104M, + APP_SYSFREQ_208M = HAL_CMU_FREQ_208M, + + APP_SYSFREQ_FREQ_QTY = HAL_CMU_FREQ_QTY +}; + +enum APP_WDT_THREAD_CHECK_USER_T { + APP_WDT_THREAD_CHECK_USER_APP, + APP_WDT_THREAD_CHECK_USER_AF, + APP_WDT_THREAD_CHECK_USER_BT, + APP_WDT_THREAD_CHECK_USER_3, + APP_WDT_THREAD_CHECK_USER_4, + APP_WDT_THREAD_CHECK_USER_5, + APP_WDT_THREAD_CHECK_USER_6, + APP_WDT_THREAD_CHECK_USER_7, + APP_WDT_THREAD_CHECK_USER_8, + APP_WDT_THREAD_CHECK_USER_9, + APP_WDT_THREAD_CHECK_USER_10, + + APP_WDT_THREAD_CHECK_USER_QTY +}; + +int app_sysfreq_req(enum APP_SYSFREQ_USER_T user, enum APP_SYSFREQ_FREQ_T freq); + +int app_wdt_open(int seconds); + +int app_wdt_reopen(int seconds); + +int app_wdt_close(void); + +#ifdef __cplusplus +} +#endif + +#endif//__FMDEC_H__ diff --git a/apps/common/randfrommic.c b/apps/common/randfrommic.c new file mode 100644 index 0000000..ffa16eb --- /dev/null +++ b/apps/common/randfrommic.c @@ -0,0 +1,267 @@ +#ifdef __RAND_FROM_MIC__ +#include "audioflinger.h" +#include "hal_trace.h" +#include "app_utils.h" +#include "string.h" +#include "stdlib.h" +#include "stdio.h" +#include "app_bt_stream.h" +#include "randfrommic.h" +#include "hal_timer.h" +#include "cmsis_os.h" +#include "cmsis_gcc.h" +#include "app_audio.h" + +#if BT_DRV_DEBUG +#define RAND_TRACE(n, fmt, ...) TRACE(n, fmt, ##__VA_ARGS__) +#define RAND_DUMP(s,buff,len) DUMP8(s,buff,len) +#else +#define RAND_TRACE(n, fmt, ...) +#define RAND_DUMP(s,buff,len) +#endif + +static void generateRand(bool on); +static uint32_t rand_data_handle(uint8_t *buf, uint32_t len); + +static uint8_t deviceId = 0; +static uint8_t *captureBuffer = NULL; +static uint32_t randSeed = 1; +static bool randInitialised = false; + +// 4 bytes aligned +#define RAND_GRAB_BITS_PER_SAMPLE 4 +#define RAND_GRAB_BITS_MASK_PER_SAMPLE ((1 << RAND_GRAB_BITS_PER_SAMPLE)-1) + +RAND_NUMBER_T randomBuffer = +{ + 25, + RAND_STATUS_CLOSE, +}; + +/** + * Description: parse mic data according to the stream cfg(bit mode and channel number) + * only the lowest byte of each frame is taken + * ADC format: + * 16bit mode -> [15:0] is valid + * 24bit mode -> [23:4] is valid + * 32bit mode -> [31:12] is valid + * + */ +static int randDataParse(uint8_t *buf, uint32_t len, enum AUD_BITS_T bits, + enum AUD_CHANNEL_NUM_T ch_num) +{ + uint8_t index = 0; + + union { + uint32_t seedValue; + uint8_t value[4]; + }seedData; + + if ((NULL == buf) || + ((RANDOM_CAPTURE_BUFFER_SIZE/2) > len)) // ping-pong buffer + { + return -1; + } + + RAND_TRACE(1, "%s", __func__); + RAND_DUMP("%x ",buf, 16); + + switch (bits) + { + case AUD_BITS_16: + { + uint16_t* content = (uint16_t *)buf; + + for (index = 0;index < 4; index++) + { + seedData.value[index] = ((*content) & RAND_GRAB_BITS_MASK_PER_SAMPLE) | + (((*(content+ch_num)) & RAND_GRAB_BITS_MASK_PER_SAMPLE) << RAND_GRAB_BITS_PER_SAMPLE); + content += ((8/RAND_GRAB_BITS_PER_SAMPLE)*ch_num); + } + break; + } + case AUD_BITS_24: + { + uint32_t* content = (uint32_t *)buf; + for (index = 0;index < 4; index++) + { + // bit 23:4 are valid + seedData.value[index] = (((*content) >> 4) & RAND_GRAB_BITS_MASK_PER_SAMPLE) | + ((((*(content+ch_num)) >> 4)&RAND_GRAB_BITS_MASK_PER_SAMPLE) << RAND_GRAB_BITS_PER_SAMPLE); + content += ((8/RAND_GRAB_BITS_PER_SAMPLE)*ch_num); + } + break; + } + case AUD_BITS_32: + { + uint32_t* content = (uint32_t *)buf; + for (index = 0;index < 4; index++) + { + // bit 31:12 are valid + seedData.value[index] = (((*content) >> 12) & RAND_GRAB_BITS_MASK_PER_SAMPLE) | + ((((*(content+ch_num)) >> 12) & RAND_GRAB_BITS_MASK_PER_SAMPLE) << RAND_GRAB_BITS_PER_SAMPLE); + content += ((8/RAND_GRAB_BITS_PER_SAMPLE)*ch_num); + } + break; + } + default: + { + return -1; + } + break; + } + + randSeed = seedData.seedValue; + + return 0; +} + +static void generateRand(bool on) +{ + struct AF_STREAM_CONFIG_T stream_cfg; + + RAND_TRACE(2, "%s op:%d", __func__, on); + + if (on) + { + randomBuffer.skipRound = 10; + + randomBuffer.status = random_mic_is_on(&deviceId); + RAND_TRACE(2, "%s random status = %d", __func__, randomBuffer.status); + + if (RAND_STATUS_CLOSE == randomBuffer.status) + { + app_sysfreq_req(APP_SYSFREQ_USER_RANDOM, APP_SYSFREQ_208M); + app_capture_audio_mempool_init(); + app_capture_audio_mempool_get_buff(&captureBuffer, + RANDOM_CAPTURE_BUFFER_SIZE); + memset(&stream_cfg, 0, sizeof(stream_cfg)); + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = AUD_CHANNEL_NUM_1; + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.sample_rate = AUD_SAMPRATE_8000; + stream_cfg.vol = TGT_VOLUME_LEVEL_15; + stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; + stream_cfg.handler = rand_data_handle; + + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(captureBuffer); + stream_cfg.data_size = RANDOM_CAPTURE_BUFFER_SIZE; + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + randomBuffer.status = RAND_STATUS_OPEN; + } + else if(RAND_STATUS_MIC_OPENED == randomBuffer.status) + { + af_stream_start(deviceId, AUD_STREAM_CAPTURE); + } + } + else + { + // release the acquired system clock + app_sysfreq_req(APP_SYSFREQ_USER_RANDOM, APP_SYSFREQ_32K); + if (RAND_STATUS_MIC_OPENED == randomBuffer.status) + { + af_stream_stop(deviceId, AUD_STREAM_CAPTURE); + } + else if (RAND_STATUS_OPEN == randomBuffer.status) + { + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + } + randomBuffer.status = RAND_STATUS_CLOSE; + } +} + +static uint32_t rand_data_handle(uint8_t *buf, uint32_t len) +{ + if (buf == NULL) + { + return len; + } + + if ((1 == randomBuffer.skipRound) && + (!randDataParse(buf, len, AUD_BITS_16, AUD_CHANNEL_NUM_1))) + { + generateRand(false); + randomBuffer.skipRound = 0; + } + else if (1 != randomBuffer.skipRound) + { + randomBuffer.skipRound--; + } + + return len; +} + +void initSeed(void) +{ + uint8_t count = 100; // avoid deed loop + + RAND_TRACE(2, "%s:+++ initialised = %d", __func__, randInitialised); + + if (randInitialised) + { + generateRand(true); + + while ((0 != randomBuffer.skipRound) && (0 != count)) + { + osDelay(10); + count --; + } + } + + if ((0 == count) || (false == randInitialised)) + { + RAND_TRACE(1, "%s not ready", __func__); + randSeed = (uint32_t)hal_sys_timer_get(); + generateRand(false); + } + + srand(randSeed); + RAND_TRACE(2, "%s:--- count = %d", __func__, count); +} + +void random_status_sync(void) +{ + if (RAND_STATUS_OPEN == randomBuffer.status) + { + RAND_TRACE(1, "%s random mic has already on,should be closed", __func__); + generateRand(false); + } +} + +void random_data_process(uint8_t *buf, uint32_t len,enum AUD_BITS_T bits, + enum AUD_CHANNEL_NUM_T ch_num) +{ + if (buf == NULL) + { + return; + } + + if ((RAND_STATUS_MIC_STARTED == randomBuffer.status) || + (RAND_STATUS_MIC_OPENED == randomBuffer.status)) + { + if (len >= RANDOM_CAPTURE_BUFFER_SIZE/2) + { + RAND_TRACE(4, "%s buf address = 0x%p, bits = %d, channel num = %d", __func__, buf, bits, ch_num); + RAND_DUMP("%02x ", buf, 32); + if ((1 == randomBuffer.skipRound) && + (!randDataParse(buf, len, bits, ch_num))) + { + generateRand(false); + randomBuffer.skipRound = 0; + } + else if (1 != randomBuffer.skipRound) + { + randomBuffer.skipRound--; + } + } + } +} + +void randInit(void) +{ + randInitialised = true; +} + +#endif diff --git a/apps/common/randfrommic.h b/apps/common/randfrommic.h new file mode 100644 index 0000000..1eb4ca5 --- /dev/null +++ b/apps/common/randfrommic.h @@ -0,0 +1,33 @@ +#ifdef __RAND_FROM_MIC__ +#ifndef __RANDFROMMIC_H__ +#define __RANDFROMMIC_H__ +#ifdef __cplusplus +extern "C" { +#endif + +#define RANDOM_CAPTURE_BUFFER_SIZE 512 + +// random module state machine +typedef enum { + RAND_STATUS_CLOSE = 0x00, // initial state + RAND_STATUS_OPEN = 0x01, // indicate MIC has been started by random module + RAND_STATUS_MIC_STARTED = 0x02, // indicate MIC has been started + RAND_STATUS_MIC_OPENED = 0x03, // indicate MIC has been opened but not start + RAND_STATUS_NUM = 0x0F +}RAND_STATUS_E; + +typedef struct{ + uint8_t skipRound; // used to indicate the number of rounds should be skipped to avoid all zero value + RAND_STATUS_E status; +}__attribute__ ((__packed__))RAND_NUMBER_T; + +void initSeed(void); +void random_status_sync(void); +void random_data_process(uint8_t *buf, uint32_t len,enum AUD_BITS_T bits, enum AUD_CHANNEL_NUM_T ch_num); +void randInit(void); + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/apps/factory/1k_2ch_44k_16bit.txt b/apps/factory/1k_2ch_44k_16bit.txt new file mode 100644 index 0000000..ce23428 --- /dev/null +++ b/apps/factory/1k_2ch_44k_16bit.txt @@ -0,0 +1,882 @@ +0, 0, +4652, 4653, +9211, 9210, +13583, 13583, +17679, 17680, +21418, 21417, +24722, 24722, +27525, 27524, +29770, 29770, +31413, 31413, +32418, 32418, +32767, 32767, +32452, 32452, +31478, 31479, +29867, 29867, +27651, 27651, +24875, 24874, +21594, 21594, +17876, 17876, +13795, 13795, +9435, 9434, +4884, 4884, +234, 234, +-4421, -4422, +-8986, -8987, +-13370, -13371, +-17483, -17482, +-21240, -21241, +-24568, -24568, +-27398, -27398, +-29672, -29673, +-31345, -31346, +-32384, -32383, +-32766, -32765, +-32483, -32483, +-31542, -31542, +-29963, -29963, +-27776, -27775, +-25026, -25026, +-21769, -21769, +-18071, -18071, +-14007, -14006, +-9659, -9658, +-5114, -5114, +-466, -467, +4190, 4190, +8763, 8763, +13157, 13157, +17284, 17284, +21062, 21063, +24413, 24413, +27269, 27268, +29572, 29573, +31277, 31277, +32347, 32347, +32762, 32762, +32512, 32513, +31605, 31605, +30057, 30057, +27898, 27899, +25175, 25176, +21943, 21943, +18265, 18265, +14217, 14217, +9881, 9881, +5345, 5345, +700, 700, +-3959, -3958, +-8537, -8536, +-12943, -12943, +-17086, -17086, +-20883, -20883, +-24257, -24256, +-27139, -27139, +-29470, -29471, +-31207, -31207, +-32309, -32308, +-32757, -32756, +-32540, -32541, +-31665, -31666, +-30149, -30148, +-28020, -28020, +-25324, -25325, +-22115, -22116, +-18458, -18458, +-14427, -14428, +-10104, -10102, +-5575, -5575, +-934, -934, +3727, 3727, +8312, 8311, +12728, 12728, +16886, 16886, +20702, 20702, +24100, 24099, +27008, 27008, +29369, 29368, +31135, 31135, +32270, 32269, +32750, 32750, +32567, 32567, +31725, 31725, +30239, 30239, +28141, 28140, +25472, 25471, +22287, 22288, +18650, 18651, +14636, 14637, +10326, 10325, +5805, 5805, +1166, 1166, +-3495, -3495, +-8086, -8086, +-12513, -12513, +-16686, -16685, +-20521, -20521, +-23940, -23940, +-26875, -26875, +-29265, -29263, +-31062, -31060, +-32228, -32228, +-32741, -32742, +-32592, -32592, +-31783, -31781, +-30328, -30329, +-28260, -28259, +-25618, -25617, +-22458, -22457, +-18842, -18843, +-14844, -14845, +-10547, -10547, +-6034, -6034, +-1400, -1400, +3263, 3263, +7859, 7859, +12297, 12296, +16484, 16485, +20338, 20338, +23781, 23780, +26741, 26740, +29158, 29159, +30986, 30986, +32184, 32185, +32731, 32733, +32615, 32616, +31839, 31838, +30417, 30416, +28377, 28377, +25763, 25763, +22627, 22628, +19032, 19033, +15052, 15052, +10767, 10767, +6263, 6264, +1633, 1634, +-3030, -3030, +-7632, -7633, +-12079, -12080, +-16283, -16283, +-20155, -20154, +-23620, -23619, +-26604, -26605, +-29051, -29051, +-30908, -30909, +-32140, -32141, +-32720, -32721, +-32638, -32638, +-31893, -31892, +-30502, -30502, +-28494, -28493, +-25907, -25906, +-22796, -22795, +-19222, -19222, +-15259, -15259, +-10987, -10987, +-6493, -6492, +-1866, -1866, +2797, 2797, +7404, 7405, +11862, 11862, +16079, 16079, +19971, 19971, +23457, 23457, +26468, 26468, +28943, 28942, +30830, 30831, +32094, 32093, +32707, 32707, +32657, 32656, +31946, 31946, +30586, 30586, +28608, 28608, +26049, 26050, +22962, 22963, +19411, 19411, +15466, 15465, +11207, 11206, +6722, 6722, +2099, 2099, +-2565, -2565, +-7177, -7178, +-11644, -11645, +-15875, -15875, +-19785, -19784, +-23294, -23294, +-26330, -26330, +-28833, -28832, +-30751, -30751, +-32046, -32046, +-32692, -32692, +-32676, -32675, +-31997, -31997, +-30670, -30670, +-28721, -28721, +-26190, -26190, +-23128, -23129, +-19598, -19599, +-15671, -15672, +-11425, -11426, +-6950, -6950, +-2331, -2332, +2332, 2333, +6949, 6949, +11426, 11426, +15671, 15671, +19598, 19598, +23128, 23128, +26190, 26190, +28722, 28720, +30669, 30669, +31997, 31996, +32676, 32675, +32692, 32692, +32046, 32046, +30751, 30751, +28832, 28833, +26330, 26330, +23293, 23294, +19785, 19785, +15876, 15875, +11645, 11645, +7177, 7177, +2566, 2565, +-2100, -2100, +-6722, -6721, +-11207, -11208, +-15465, -15465, +-19412, -19412, +-22963, -22962, +-26049, -26049, +-28608, -28608, +-30586, -30586, +-31946, -31946, +-32657, -32657, +-32707, -32707, +-32095, -32093, +-30830, -30830, +-28943, -28943, +-26467, -26468, +-23457, -23457, +-19970, -19971, +-16079, -16079, +-11862, -11863, +-7406, -7404, +-2798, -2798, +1866, 1866, +6492, 6493, +10987, 10987, +15260, 15259, +19222, 19222, +22795, 22795, +25906, 25907, +28493, 28493, +30502, 30502, +31893, 31893, +32638, 32637, +32721, 32721, +32141, 32140, +30909, 30909, +29051, 29052, +26605, 26605, +23619, 23619, +20155, 20155, +16282, 16282, +12080, 12080, +7631, 7632, +3031, 3031, +-1633, -1633, +-6263, -6264, +-10767, -10767, +-15053, -15052, +-19033, -19033, +-22627, -22627, +-25763, -25763, +-28377, -28377, +-30416, -30416, +-31839, -31838, +-32616, -32616, +-32732, -32731, +-32184, -32185, +-30986, -30985, +-29159, -29159, +-26740, -26740, +-23780, -23780, +-20339, -20339, +-16485, -16484, +-12297, -12296, +-7859, -7859, +-3263, -3262, +1399, 1401, +6034, 6034, +10547, 10546, +14845, 14844, +18842, 18842, +22457, 22458, +25619, 25619, +28260, 28259, +30329, 30328, +31783, 31783, +32593, 32593, +32742, 32742, +32228, 32228, +31061, 31060, +29264, 29264, +26875, 26875, +23940, 23940, +20521, 20521, +16686, 16686, +12512, 12513, +8085, 8085, +3495, 3494, +-1167, -1167, +-5804, -5805, +-10325, -10326, +-14636, -14636, +-18651, -18651, +-22287, -22288, +-25472, -25472, +-28141, -28141, +-30239, -30239, +-31725, -31725, +-32568, -32567, +-32750, -32751, +-32270, -32269, +-31134, -31135, +-29368, -29369, +-27007, -27008, +-24099, -24099, +-20703, -20703, +-16886, -16886, +-12728, -12728, +-8311, -8311, +-3726, -3728, +934, 933, +5575, 5575, +10104, 10104, +14426, 14427, +18458, 18458, +22115, 22115, +25324, 25324, +28021, 28021, +30149, 30148, +31666, 31665, +32541, 32541, +32757, 32757, +32310, 32309, +31206, 31206, +29471, 29472, +27139, 27139, +24257, 24257, +20883, 20883, +17085, 17086, +12943, 12944, +8537, 8537, +3958, 3959, +-700, -700, +-5345, -5345, +-9882, -9881, +-14217, -14217, +-18265, -18265, +-21942, -21943, +-25176, -25175, +-27899, -27899, +-30056, -30056, +-31605, -31605, +-32513, -32513, +-32762, -32761, +-32347, -32347, +-31277, -31277, +-29573, -29573, +-27269, -27269, +-24413, -24414, +-21062, -21062, +-17284, -17284, +-13156, -13157, +-8762, -8762, +-4190, -4190, +467, 466, +5115, 5115, +9659, 9658, +14006, 14007, +18070, 18070, +21769, 21769, +25026, 25025, +27776, 27776, +29962, 29963, +31541, 31542, +32482, 32483, +32765, 32765, +32383, 32383, +31346, 31346, +29672, 29672, +27397, 27398, +24568, 24568, +21240, 21241, +17482, 17482, +13371, 13370, +8987, 8987, +4421, 4422, +-233, -234, +-4883, -4883, +-9435, -9435, +-13795, -13795, +-17876, -17875, +-21594, -21594, +-24874, -24875, +-27651, -27651, +-29868, -29867, +-31478, -31478, +-32451, -32451, +-32767, -32767, +-32419, -32418, +-31413, -31413, +-29770, -29770, +-27525, -27525, +-24722, -24722, +-21418, -21417, +-17680, -17680, +-13583, -13582, +-9211, -9212, +-4653, -4653, +-1, 1, +4652, 4652, +9211, 9211, +13584, 13582, +17679, 17679, +21418, 21418, +24722, 24722, +27525, 27525, +29771, 29771, +31412, 31413, +32418, 32419, +32767, 32767, +32452, 32451, +31478, 31478, +29868, 29867, +27650, 27651, +24874, 24874, +21593, 21593, +17876, 17875, +13795, 13795, +9435, 9436, +4883, 4884, +234, 233, +-4421, -4422, +-8987, -8987, +-13370, -13370, +-17483, -17483, +-21240, -21240, +-24568, -24569, +-27398, -27398, +-29672, -29672, +-31346, -31346, +-32383, -32384, +-32765, -32765, +-32483, -32484, +-31542, -31542, +-29963, -29963, +-27775, -27775, +-25026, -25026, +-21769, -21769, +-18070, -18071, +-14006, -14007, +-9658, -9658, +-5115, -5115, +-467, -467, +4190, 4190, +8762, 8763, +13157, 13157, +17285, 17284, +21062, 21062, +24413, 24413, +27269, 27269, +29573, 29572, +31276, 31277, +32347, 32346, +32762, 32762, +32513, 32512, +31605, 31604, +30056, 30057, +27899, 27899, +25176, 25176, +21943, 21943, +18265, 18265, +14217, 14217, +9881, 9881, +5344, 5345, +700, 700, +-3958, -3958, +-8537, -8537, +-12942, -12943, +-17085, -17086, +-20883, -20883, +-24257, -24257, +-27138, -27138, +-29471, -29471, +-31206, -31207, +-32309, -32308, +-32757, -32757, +-32541, -32540, +-31666, -31666, +-30148, -30148, +-28021, -28020, +-25325, -25325, +-22115, -22116, +-18458, -18458, +-14427, -14427, +-10103, -10103, +-5575, -5575, +-934, -933, +3727, 3726, +8312, 8311, +12729, 12728, +16886, 16886, +20703, 20702, +24099, 24100, +27007, 27008, +29369, 29369, +31135, 31134, +32270, 32270, +32750, 32750, +32568, 32567, +31724, 31724, +30239, 30240, +28140, 28142, +25472, 25473, +22287, 22288, +18651, 18651, +14636, 14635, +10325, 10325, +5805, 5805, +1167, 1167, +-3495, -3495, +-8085, -8085, +-12512, -12513, +-16685, -16685, +-20521, -20521, +-23941, -23940, +-26875, -26875, +-29264, -29265, +-31060, -31061, +-32228, -32228, +-32742, -32742, +-32593, -32593, +-31782, -31782, +-30328, -30328, +-28260, -28260, +-25618, -25619, +-22458, -22458, +-18842, -18842, +-14845, -14844, +-10546, -10546, +-6035, -6035, +-1400, -1400, +3262, 3263, +7859, 7859, +12296, 12297, +16485, 16485, +20339, 20339, +23780, 23780, +26741, 26741, +29159, 29158, +30985, 30985, +32185, 32185, +32732, 32733, +32615, 32616, +31839, 31839, +30416, 30416, +28377, 28377, +25763, 25762, +22627, 22628, +19032, 19032, +15053, 15052, +10767, 10767, +6264, 6263, +1633, 1634, +-3030, -3030, +-7632, -7632, +-12081, -12079, +-16282, -16283, +-20154, -20155, +-23618, -23619, +-26604, -26605, +-29051, -29051, +-30910, -30909, +-32140, -32141, +-32721, -32720, +-32637, -32637, +-31892, -31893, +-30502, -30502, +-28493, -28493, +-25907, -25907, +-22795, -22796, +-19222, -19222, +-15260, -15259, +-10987, -10987, +-6493, -6492, +-1867, -1867, +2798, 2798, +7405, 7405, +11862, 11862, +16079, 16079, +19971, 19970, +23457, 23456, +26468, 26468, +28942, 28942, +30831, 30830, +32095, 32095, +32707, 32706, +32657, 32657, +31946, 31945, +30587, 30586, +28607, 28607, +26049, 26049, +22963, 22963, +19411, 19411, +15466, 15465, +11206, 11208, +6721, 6721, +2100, 2099, +-2565, -2565, +-7177, -7177, +-11644, -11644, +-15875, -15876, +-19785, -19785, +-23293, -23294, +-26330, -26330, +-28833, -28832, +-30751, -30751, +-32046, -32047, +-32692, -32692, +-32675, -32675, +-31997, -31997, +-30669, -30669, +-28720, -28720, +-26190, -26190, +-23129, -23128, +-19598, -19598, +-15671, -15671, +-11425, -11426, +-6949, -6949, +-2332, -2332, +2333, 2333, +6950, 6950, +11426, 11427, +15670, 15671, +19599, 19598, +23128, 23128, +26190, 26189, +28720, 28720, +30670, 30669, +31996, 31996, +32675, 32676, +32692, 32692, +32046, 32046, +30751, 30751, +28832, 28831, +26330, 26329, +23293, 23293, +19784, 19785, +15875, 15875, +11645, 11645, +7177, 7178, +2564, 2565, +-2100, -2099, +-6722, -6722, +-11207, -11206, +-15466, -15466, +-19410, -19411, +-22962, -22962, +-26049, -26049, +-28608, -28607, +-30586, -30586, +-31945, -31946, +-32658, -32657, +-32707, -32707, +-32095, -32094, +-30832, -30830, +-28943, -28943, +-26468, -26467, +-23457, -23456, +-19971, -19970, +-16080, -16080, +-11862, -11863, +-7406, -7405, +-2797, -2797, +1867, 1866, +6492, 6492, +10987, 10987, +15260, 15259, +19222, 19222, +22796, 22796, +25907, 25906, +28494, 28493, +30502, 30502, +31893, 31893, +32637, 32637, +32720, 32721, +32140, 32140, +30909, 30909, +29052, 29052, +26605, 26605, +23619, 23619, +20155, 20155, +16281, 16282, +12080, 12079, +7632, 7632, +3031, 3030, +-1634, -1633, +-6263, -6264, +-10767, -10767, +-15052, -15053, +-19033, -19032, +-22627, -22628, +-25763, -25763, +-28377, -28377, +-30416, -30416, +-31838, -31838, +-32616, -32616, +-32732, -32732, +-32185, -32185, +-30986, -30986, +-29158, -29158, +-26741, -26741, +-23780, -23780, +-20339, -20338, +-16485, -16484, +-12296, -12296, +-7859, -7859, +-3262, -3263, +1400, 1400, +6035, 6034, +10546, 10546, +14845, 14845, +18842, 18842, +22457, 22458, +25619, 25619, +28260, 28260, +30327, 30328, +31782, 31782, +32592, 32592, +32742, 32742, +32229, 32227, +31061, 31061, +29264, 29264, +26875, 26874, +23940, 23941, +20521, 20521, +16685, 16686, +12513, 12513, +8086, 8085, +3495, 3495, +-1167, -1167, +-5804, -5805, +-10325, -10324, +-14636, -14636, +-18651, -18651, +-22287, -22287, +-25471, -25473, +-28141, -28140, +-30239, -30240, +-31724, -31725, +-32567, -32567, +-32750, -32751, +-32270, -32269, +-31135, -31135, +-29369, -29369, +-27007, -27007, +-24099, -24099, +-20703, -20703, +-16886, -16886, +-12728, -12728, +-8311, -8312, +-3727, -3727, +934, 934, +5576, 5575, +10104, 10104, +14427, 14427, +18459, 18458, +22115, 22115, +25325, 25324, +28020, 28020, +30148, 30148, +31665, 31666, +32541, 32541, +32757, 32757, +32309, 32310, +31206, 31206, +29472, 29472, +27139, 27138, +24257, 24257, +20883, 20883, +17086, 17086, +12942, 12942, +8537, 8537, +3958, 3958, +-700, -701, +-5344, -5345, +-9881, -9881, +-14218, -14217, +-18264, -18265, +-21942, -21943, +-25175, -25176, +-27899, -27898, +-30057, -30057, +-31605, -31605, +-32512, -32513, +-32761, -32761, +-32347, -32347, +-31277, -31277, +-29573, -29572, +-27269, -27269, +-24414, -24414, +-21062, -21062, +-17284, -17285, +-13156, -13157, +-8763, -8762, +-4190, -4190, +467, 467, +5114, 5114, +9658, 9659, +14006, 14006, +18071, 18071, +21769, 21769, +25026, 25026, +27775, 27776, +29963, 29962, +31543, 31542, +32483, 32483, +32765, 32765, +32384, 32384, +31345, 31345, +29671, 29672, +27398, 27398, +24568, 24568, +21241, 21241, +17483, 17483, +13369, 13370, +8986, 8987, +4422, 4421, +-233, -234, +-4885, -4884, +-9435, -9435, +-13795, -13794, +-17876, -17875, +-21594, -21594, +-24875, -24874, +-27651, -27651, +-29867, -29868, +-31478, -31478, +-32452, -32451, +-32768, -32767, +-32419, -32418, +-31412, -31413, +-29771, -29771, +-27525, -27526, +-24722, -24721, +-21417, -21418, +-17680, -17679, +-13583, -13583, +-9211, -9210, +-4653, -4653 \ No newline at end of file diff --git a/apps/factory/1k_2ch_48k_16bit.txt b/apps/factory/1k_2ch_48k_16bit.txt new file mode 100644 index 0000000..69bf402 --- /dev/null +++ b/apps/factory/1k_2ch_48k_16bit.txt @@ -0,0 +1,96 @@ +0, +0, +4234, +4234, +8396, +8396, +12414, +12414, +16220, +16220, +19748, +19748, +22938, +22938, +25736, +25736, +28094, +28094, +29970, +29970, +31334, +31334, +32162, +32162, +32440, +32440, +32162, +32162, +31334, +31334, +29970, +29970, +28094, +28094, +25736, +25736, +22938, +22938, +19748, +19748, +16220, +16220, +12414, +12414, +8396, +8396, +4234, +4234, +0, +0, +-4234, +-4234, +-8396, +-8396, +-12414, +-12414, +-16220, +-16220, +-19748, +-19748, +-22938, +-22938, +-25736, +-25736, +-28094, +-28094, +-29970, +-29970, +-31334, +-31334, +-32162, +-32162, +-32440, +-32440, +-32162, +-32162, +-31334, +-31334, +-29970, +-29970, +-28094, +-28094, +-25736, +-25736, +-22938, +-22938, +-19748, +-19748, +-16220, +-16220, +-12414, +-12414, +-8396, +-8396, +-4234, +-4234 \ No newline at end of file diff --git a/apps/factory/Makefile b/apps/factory/Makefile new file mode 100644 index 0000000..03130f6 --- /dev/null +++ b/apps/factory/Makefile @@ -0,0 +1,43 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y += \ + -Iutils/boot_struct \ + -Iutils/intersyshci \ + -Iutils/hwtimer_list \ + -Iservices/bt_app \ + -Iservices/nvrecord \ + $(BT_IF_INCLUDES) \ + -Iservices/resources \ + -Iservices/overlay \ + -Iservices/multimedia/algorithm/fft/include \ + -Iapps/key \ + -Iplatform/drivers/bt \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/usb/usb_dev/inc \ + -Iapps/battery \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iutils/cqueue \ + -Iservices/nv_section/factory_section \ + -Iservices/app_ai/inc \ + +ifeq ($(AUDIO_RESAMPLE),1) +CFLAGS_app_factory_audio.o += -D__AUDIO_RESAMPLE__ +endif +ifeq ($(SW_CAPTURE_RESAMPLE),1) +CFLAGS_app_factory_audio.o += -DSW_CAPTURE_RESAMPLE +endif + +ifeq ($(POWERKEY_I2C_SWITCH),1) +CFLAGS_app_factory.o += -DPOWERKEY_I2C_SWITCH +endif + +ifeq ($(SPEECH_TX_AEC_CODEC_REF),1) +CFLAGS_app_factory_audio.o += -DSPEECH_TX_AEC_CODEC_REF +endif + diff --git a/apps/factory/app_factory.cpp b/apps/factory/app_factory.cpp new file mode 100644 index 0000000..653b387 --- /dev/null +++ b/apps/factory/app_factory.cpp @@ -0,0 +1,689 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "list.h" +#include "hal_trace.h" +#include "hal_bootmode.h" +#include "hal_cmu.h" +#include "hal_sleep.h" +#include "app_key.h" +#include "app_factory.h" +#include "bt_drv_interface.h" +#include "bt_drv_reg_op.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_dev.h" +#include "nvrecord_env.h" +#include "resources.h" +#include "app_bt_stream.h" +#include "app_media_player.h" +#include "pmu.h" + +// for init +#include "apps.h" +#include "app_status_ind.h" +#include "app_thread.h" +#include "app_key.h" +#include "app_pwl.h" +#include "app_overlay.h" +#include "app_battery.h" +#include "app_utils.h" + +// for bt +#include "besbt.h" +#include "app_bt.h" +#include "app_factory_bt.h" + +// for audio +#include "audioflinger.h" +#include "app_audio.h" +#include "app_utils.h" + + + +// for progress +#include "hal_uart.h" +#include "tool_msg.h" + +#include "factory_section.h" + +#ifdef __FACTORY_MODE_SUPPORT__ + +#define APP_FACTORYMODE_RETRY_LIMITED (2) + +typedef enum APP_FACTORYMODE_STATUS_INDICATION_T { + APP_FACTORYMODE_STATUS_INDICATION_RUNNING = 0, + APP_FACTORYMODE_STATUS_INDICATION_PASS, + APP_FACTORYMODE_STATUS_INDICATION_FAILED, + APP_FACTORYMODE_STATUS_INDICATION_INVALID, + + APP_FACTORYMODE_STATUS_INDICATION_NUM +}APP_FACTORYMODE_STATUS_INDICATION_T; + +static void app_factorymode_timehandler(void const *param); +void app_bt_key_shutdown(APP_KEY_STATUS *status, void *param); +void app_factorymode_result_set(bool result); + +static osThreadId app_factorymode_tid= NULL; +static struct message_t send_msg = { { PREFIX_CHAR, }, }; +static unsigned char send_seq = 0; + +osTimerId app_factory_timer = NULL; +osTimerDef (APP_FACTORY_TIMER, app_factorymode_timehandler); + +int app_factorymode_languageswitch_proc(void) +{ +#ifdef MEDIA_PLAYER_SUPPORT + int lan; + int new_lan; + struct nvrecord_env_t *nvrecord_env; + + + APP_FACTORY_TRACE(1,"%s",__func__); + lan = app_play_audio_get_lang(); + new_lan = lan; + app_play_audio_set_lang(new_lan); + + nv_record_env_get(&nvrecord_env); + nvrecord_env->media_language.language = new_lan; + nv_record_env_set(nvrecord_env); + + APP_FACTORY_TRACE(2,"languages old:%d new:%d",lan ,new_lan); + media_PlayAudio(AUD_ID_LANGUAGE_SWITCH, 0); +#endif + return 0; +} + +void app_factorymode_languageswitch(APP_KEY_STATUS *status, void *param) +{ + app_factorymode_languageswitch_proc(); +} + +void app_factorymode_enter(void) +{ + APP_FACTORY_TRACE(1,"%s",__func__); + hal_sw_bootmode_set(HAL_SW_BOOTMODE_TEST_MODE|HAL_SW_BOOTMODE_TEST_SIGNALINGMODE); + hal_cmu_sys_reboot(); +} + +extern "C" { + +static bool isInFactoryMode = false; + +bool app_factorymode_get(void) +{ + return isInFactoryMode; +} + +void app_factorymode_set(bool set) +{ + isInFactoryMode = set; +} + +} +#ifdef POWERKEY_I2C_SWITCH +void app_factorymode_i2c_switch(APP_KEY_STATUS *status, void *param) +{ + static int i = 0; + + i++; + if (i & 1) { + TRACE(0,"set analog i2c mode !!!"); + osDelay(100); + hal_iomux_set_analog_i2c(); + } else { + hal_iomux_set_uart0(); + osDelay(100); + TRACE(0,"hal_iomux_set_uart0 !!!"); + } +} +#endif + +#ifdef __IBRT_IBRT_TESTMODE__ +void bt_drv_ibrt_test_key_click(APP_KEY_STATUS *status, void *param); +void bt_drv_ibrt_test_key_click(APP_KEY_STATUS *status, void *param) +{ + btdrv_connect_ibrt_device(bt_addr); +} +#endif + +void app_factorymode_key_init(void) +{ + const APP_KEY_HANDLE app_factorymode_handle_cfg[] = { +#ifdef POWERKEY_I2C_SWITCH + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_RAMPAGECLICK},"bt i2c key",app_factorymode_i2c_switch, NULL}, +#endif +#ifdef __POWERKEY_CTRL_ONOFF_ONLY__ + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_UP},"bt function key",app_bt_key_shutdown, NULL}, +#else + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_LONGLONGPRESS},"bt function key",app_bt_key_shutdown, NULL}, +#endif +#ifdef __IBRT_IBRT_TESTMODE__ + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"bt function key",bt_drv_ibrt_test_key_click, NULL}, +#else + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"bt function key",app_factorymode_languageswitch, NULL}, +#endif + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_DOUBLECLICK},"bt function key",app_factorymode_bt_xtalcalib, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_LONGPRESS},"bt function key",app_factorymode_bt_signalingtest, NULL}, + }; + + uint8_t i = 0; + + APP_FACTORY_TRACE(1,"%s",__func__); + + app_key_handle_clear(); + for (i=0; i<(sizeof(app_factorymode_handle_cfg)/sizeof(APP_KEY_HANDLE)); i++){ + app_key_handle_registration(&app_factorymode_handle_cfg[i]); + } +} + +static void app_factorymode_audioloopswitch(APP_KEY_STATUS *status, void *param) +{ + static bool onaudioloop = false; + + onaudioloop = onaudioloop?false:true; + + if (onaudioloop) + app_audio_sendrequest(APP_FACTORYMODE_AUDIO_LOOP, (uint8_t)APP_BT_SETTING_OPEN, 0); + else + app_audio_sendrequest(APP_FACTORYMODE_AUDIO_LOOP, (uint8_t)APP_BT_SETTING_CLOSE, 0); +} + +void app_factorymode_test_key_init(void) +{ + const APP_KEY_HANDLE app_factorymode_handle_cfg[] = { + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"bt function key",app_factorymode_audioloopswitch, NULL}, + }; + + uint8_t i = 0; + APP_FACTORY_TRACE(1,"%s",__func__); + for (i=0; i<(sizeof(app_factorymode_handle_cfg)/sizeof(APP_KEY_HANDLE)); i++){ + app_key_handle_registration(&app_factorymode_handle_cfg[i]); + } +} + +void app_factorymode_result_clean(void) +{ + osSignalClear(app_factorymode_tid, 0x01); + osSignalClear(app_factorymode_tid, 0x02); +} + +void app_factorymode_result_set(bool result) +{ + if (result) + osSignalSet(app_factorymode_tid ,0x01); + else + osSignalSet(app_factorymode_tid ,0x02); +} + +bool app_factorymode_result_wait(void) +{ + bool nRet; + osEvent evt; + + while(1) + { + //wait any signal + evt = osSignalWait(0x0, osWaitForever); + + //get role from signal value + if(evt.status == osEventSignal) + { + if(evt.value.signals & 0x01) + { + nRet = true; + break; + } + else if(evt.value.signals & 0x02) + { + nRet = false; + break; + } + } + } + return nRet; +} + +static int app_factorymode_send_progress (uint8_t progress) +{ + APP_MESSAGE_BLOCK msg; + + msg.mod_id = APP_MODUAL_OHTER; + msg.msg_body.message_id = 2; + msg.msg_body.message_Param0 = progress; + app_mailbox_put(&msg); + + return 0; +} + +static int app_factorymode_send_code (uint32_t progress) +{ + APP_MESSAGE_BLOCK msg; + + msg.mod_id = APP_MODUAL_OHTER; + msg.msg_body.message_id = 3; + msg.msg_body.message_Param0 = progress; + app_mailbox_put(&msg); + + return 0; +} + +int app_factorymode_proc(void) +{ + uint8_t cnt = 0; + bool nRet; + app_factorymode_tid = osThreadGetId(); + + app_factorymode_send_progress(60); + app_factorymode_bt_init_connect(); + + do{ + app_factorymode_result_clean(); + app_factorymode_bt_create_connect(); + nRet = app_factorymode_result_wait(); + }while(!nRet && ++cnt < APP_FACTORYMODE_RETRY_LIMITED); + + if (!nRet) + goto exit; + app_factorymode_send_progress(90); + app_factorymode_result_clean(); + if (!nRet) + goto exit; + app_factorymode_send_progress(100); + osDelay(100); +exit: + app_factorymode_result_clean(); + if (nRet){ + return 0; + }else{ + return -1; + } +} + +static unsigned char app_factorymode_msg_check_sum(unsigned char *buf, unsigned char len) +{ + int i; + unsigned char sum = 0; + + for (i = 0; i < len; i++) { + sum += buf[i]; + } + + return sum; +} + +static int app_factorymode_msg_uart_send(const unsigned char *buf, size_t len) +{ + uint32_t sent = 0; + + while (sent < len) { + hal_uart_blocked_putc(HAL_UART_ID_0, buf[sent++]); + } + + if (sent != len) { + return 1; + } + + return 0; +} + +static int app_factorymode_msg_send_ping(void) +{ + int ret; + + send_msg.hdr.type = 0x88; + send_msg.hdr.seq = send_seq++; + send_msg.hdr.len = 2; + send_msg.data[0] = 0xaa; + send_msg.data[1] = 0x55; + send_msg.data[2] = ~app_factorymode_msg_check_sum((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg) - 1); + + ret = app_factorymode_msg_uart_send((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg)); + + return ret; +} + +static int app_factorymode_msg_send_progress (uint8_t progress) +{ + int ret; + + send_msg.hdr.type = 0x88; + send_msg.hdr.seq = send_seq++; + send_msg.hdr.len = 2; + send_msg.data[0] = progress; + send_msg.data[1] = 100; + send_msg.data[2] = ~app_factorymode_msg_check_sum((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg) - 1); + + ret = app_factorymode_msg_uart_send((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg)); + + return ret; +} + +static int app_factorymode_msg_send_32bitcode(uint32_t code) +{ + int ret; + + send_msg.hdr.type = 0x88; + send_msg.hdr.seq = send_seq++; + send_msg.hdr.len = 4; + send_msg.data[0] = 0xf2; + *(uint32_t *)&(send_msg.data[1]) = code; + send_msg.data[4] = ~app_factorymode_msg_check_sum((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg) - 1); + + ret = app_factorymode_msg_uart_send((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg)); + + return ret; +} + +static int app_factorymode_process(APP_MESSAGE_BODY *msg_body) +{ + if (msg_body->message_id == 1){ + app_factorymode_msg_send_ping(); + } + if (msg_body->message_id == 2){ + app_factorymode_msg_send_progress(msg_body->message_Param0); + } + if (msg_body->message_id == 3){ + app_factorymode_msg_send_32bitcode(msg_body->message_Param0); + } + return 0; +} + +static int app_factorymode_uart_init(void) +{ + struct HAL_UART_CFG_T uart_cfg; + + memset(&uart_cfg, 0, sizeof(struct HAL_UART_CFG_T)); + uart_cfg.parity = HAL_UART_PARITY_NONE, + uart_cfg.stop = HAL_UART_STOP_BITS_1, + uart_cfg.data = HAL_UART_DATA_BITS_8, + uart_cfg.flow = HAL_UART_FLOW_CONTROL_NONE,//HAL_UART_FLOW_CONTROL_RTSCTS, + uart_cfg.tx_level = HAL_UART_FIFO_LEVEL_1_2, + uart_cfg.rx_level = HAL_UART_FIFO_LEVEL_1_4, + uart_cfg.baud = 921600, + uart_cfg.dma_rx = false, + uart_cfg.dma_tx = false, + uart_cfg.dma_rx_stop_on_err = false; + hal_uart_close(HAL_UART_ID_0); + hal_uart_open(HAL_UART_ID_0, &uart_cfg); + + return 0; +} + + +static void app_factorymode_timehandler(void const *param) +{ + APP_MESSAGE_BLOCK msg; + + msg.mod_id = APP_MODUAL_OHTER; + msg.msg_body.message_id = 1; + app_mailbox_put(&msg); +} + +static uint8_t app_factorymode_indication_init(void) +{ + struct APP_PWL_CFG_T cfg; + + memset(&cfg, 0, sizeof(struct APP_PWL_CFG_T)); + app_pwl_open(); + app_pwl_setup(APP_PWL_ID_0, &cfg); + app_pwl_setup(APP_PWL_ID_1, &cfg); + return 0; +} + +static uint8_t app_factorymode_status_indication(APP_FACTORYMODE_STATUS_INDICATION_T status) +{ + struct APP_PWL_CFG_T cfg0; + struct APP_PWL_CFG_T cfg1; + APP_FACTORY_TRACE(2,"%s %d",__func__, status); + memset(&cfg0, 0, sizeof(struct APP_PWL_CFG_T)); + memset(&cfg1, 0, sizeof(struct APP_PWL_CFG_T)); + app_pwl_stop(APP_PWL_ID_0); + app_pwl_stop(APP_PWL_ID_1); + switch (status) { + case APP_FACTORYMODE_STATUS_INDICATION_RUNNING: + cfg0.part[0].level = 0; + cfg0.part[0].time = (300); + cfg0.part[1].level = 1; + cfg0.part[1].time = (300); + cfg0.parttotal = 2; + cfg0.startlevel = 0; + cfg0.periodic = true; + + cfg1.part[0].level = 1; + cfg1.part[0].time = (300); + cfg1.part[1].level = 0; + cfg1.part[1].time = (300); + cfg1.parttotal = 2; + cfg1.startlevel = 1; + cfg1.periodic = true; + + app_pwl_setup(APP_PWL_ID_0, &cfg0); + app_pwl_start(APP_PWL_ID_0); + app_pwl_setup(APP_PWL_ID_1, &cfg1); + app_pwl_start(APP_PWL_ID_1); + break; + case APP_FACTORYMODE_STATUS_INDICATION_PASS: + cfg0.part[0].level = 1; + cfg0.part[0].time = (5000); + cfg0.parttotal = 1; + cfg0.startlevel = 1; + cfg0.periodic = false; + + app_pwl_setup(APP_PWL_ID_0, &cfg0); + app_pwl_start(APP_PWL_ID_0); + break; + case APP_FACTORYMODE_STATUS_INDICATION_FAILED: + cfg1.part[0].level = 1; + cfg1.part[0].time = (5000); + cfg1.parttotal = 1; + cfg1.startlevel = 1; + cfg1.periodic = false; + + app_pwl_setup(APP_PWL_ID_1, &cfg1); + app_pwl_start(APP_PWL_ID_1); + + break; + + default: + break; + } + return 0; +} + +int app_factorymode_init(uint32_t factorymode) +{ + uint8_t cnt = 0; + int nRet = 0; + uint32_t capval = 0x00; + struct nvrecord_env_t *nvrecord_env; + APP_FACTORY_TRACE(1,"app_factorymode_init mode:%x\n", factorymode); + + osThreadSetPriority(osThreadGetId(), osPriorityRealtime); + app_factorymode_uart_init(); +#ifdef __WATCHER_DOG_RESET__ + app_wdt_open(60); +#endif + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_52M); + list_init(); + app_os_init(); + app_factorymode_indication_init(); + app_battery_open(); + if (app_key_open(false)){ + nRet = -1; + goto exit; + } + app_set_threadhandle(APP_MODUAL_OHTER, app_factorymode_process); + app_factory_timer = osTimerCreate (osTimer(APP_FACTORY_TIMER), osTimerPeriodic, NULL); + osTimerStart(app_factory_timer, 300); + app_factorymode_send_progress(10); + + app_bt_init(); + af_open(); + app_audio_open(); + app_overlay_open(); + + nv_record_env_init(); + nvrec_dev_data_open(); + nv_record_env_get(&nvrecord_env); +#ifdef MEDIA_PLAYER_SUPPORT + app_play_audio_set_lang(nvrecord_env->media_language.language); + app_voice_report(APP_STATUS_INDICATION_POWERON, 0); +#endif + app_status_indication_set(APP_STATUS_INDICATION_POWERON); + app_factorymode_status_indication(APP_FACTORYMODE_STATUS_INDICATION_RUNNING); + + if (factorymode&HAL_SW_BOOTMODE_CALIB){ + btdrv_start_bt(); + app_factorymode_send_progress(20); + + do { + nRet = app_factorymode_bt_xtalcalib_proc(); + }while(nRet && cnt++ pcmpatten->len) + { + do{ + if (pcmpatten->cuur_buf_pos) + { + curr_size = pcmpatten->len-pcmpatten->cuur_buf_pos; + memcpy(buf,&(pcmpatten->buf[pcmpatten->cuur_buf_pos/2]), curr_size); + remain_size -= curr_size; + pcmpatten->cuur_buf_pos = 0; + } + else if (remain_size>pcmpatten->len) + { + memcpy(buf+curr_size, pcmpatten->buf, pcmpatten->len); + curr_size += pcmpatten->len; + remain_size -= pcmpatten->len; + } + else + { + memcpy(buf+curr_size,pcmpatten->buf, remain_size); + pcmpatten->cuur_buf_pos = remain_size; + remain_size = 0; + } + }while(remain_size); + } + else + { + if ((pcmpatten->len - pcmpatten->cuur_buf_pos) >= len) + { + memcpy(buf, &(pcmpatten->buf[pcmpatten->cuur_buf_pos/2]),len); + pcmpatten->cuur_buf_pos += len; + } + else + { + curr_size = pcmpatten->len-pcmpatten->cuur_buf_pos; + memcpy(buf, &(pcmpatten->buf[pcmpatten->cuur_buf_pos/2]),curr_size); + pcmpatten->cuur_buf_pos = len - curr_size; + memcpy(buf+curr_size, pcmpatten->buf, pcmpatten->cuur_buf_pos); + } + } + + return 0; +} + +#include "fft128dot.h" + +#define N 64 +#define NFFT 128 + +struct mic_st_t{ + FftTwiddle_t w[N]; + FftTwiddle_t w128[N*2]; + FftData_t x[N*2]; + FftData_t data_odd[N]; + FftData_t data_even[N]; + FftData_t data_odd_d[N]; + FftData_t data_even_d[N]; + FftData_t data[N*2]; + signed long out[N]; +}; + +int app_factorymode_mic_cancellation_run(void * mic_st, signed short *inbuf, int sample) +{ + struct mic_st_t *st = (struct mic_st_t *)mic_st; + int i,k,jj,ii; + //int dataWidth = 16; // input word format is 16 bit twos complement fractional format 1.15 + int twiddleWidth = 16; // input word format is 16 bit twos complement fractional format 2.14 + FftMode_t ifft = FFT_MODE; + + make_symmetric_twiddles(st->w,N,twiddleWidth); + make_symmetric_twiddles(st->w128,N*2,twiddleWidth); + // input data + for (i=0; ix[i].re = inbuf[i]; + st->x[i].im = 0; + } + + for(ii = 0; ii < 1; ii++) + { + k = 0; + for (jj = 0; jj < N*2; jj+=2) + { + FftData_t tmp; + + tmp.re = st->x[jj].re; + tmp.im = st->x[jj].im; + + st->data_even[k].re = tmp.re;//(int) (double(tmp.re)*double(1 << FFTR4_INPUT_FORMAT_Y)) ; + st->data_even[k].im = tmp.im;//(int) (double(tmp.im)*double(1 << FFTR4_INPUT_FORMAT_Y)) ; + tmp.re = st->x[jj+1].re; + tmp.im = st->x[jj+1].im; + st->data_odd[k].re = tmp.re;//(int) (double(tmp.re)*double(1 << FFTR4_INPUT_FORMAT_Y)) ; + st->data_odd[k].im = tmp.im;//(int) (double(tmp.im)*double(1 << FFTR4_INPUT_FORMAT_Y)) ; + k++; + } + + fftr4(NFFT/2, st->data_even, st->w, FFTR4_TWIDDLE_WIDTH, FFTR4_DATA_WIDTH, ifft); + fftr4(NFFT/2, st->data_odd, st->w, FFTR4_TWIDDLE_WIDTH, FFTR4_DATA_WIDTH, ifft); + + for (jj = 0; jj < NFFT/2; jj++) + { + + int idx = dibit_reverse_int(jj, NFFT/2); + st->data_even_d[jj].re = st->data_even[idx].re; + st->data_even_d[jj].im = st->data_even[idx].im; + st->data_odd_d[jj].re = st->data_odd[idx].re; + st->data_odd_d[jj].im = st->data_odd[idx].im; + } + for (jj=0;jjdata_odd_d[jj].re) * st->w128[jj].re - (long long)(st->data_odd_d[jj].im) * st->w128[jj].im; + mbi = (long long)(st->data_odd_d[jj].im) * st->w128[jj].re + (long long)(st->data_odd_d[jj].re) * st->w128[jj].im; + ta.re = int(mbr>>(FFTR4_TWIDDLE_WIDTH-2)); + ta.im = int(mbi>>(FFTR4_TWIDDLE_WIDTH-2)); + st->data[jj].re = (st->data_even_d[jj].re + ta.re)/2; + st->data[jj].im = (st->data_even_d[jj].im + ta.im)/2; + //data[jj] = sat(data[jj],FFTR4_DATA_WIDTH); + st->data[jj+NFFT/2].re = (st->data_even_d[jj].re - ta.re)/2; + st->data[jj+NFFT/2].im = (st->data_even_d[jj].im - ta.im)/2; + //data[jj+NFFT/2] = sat(data[jj+NFFT/2],FFTR4_DATA_WIDTH); + + a = st->data[jj].re;///double(1 << FFTR4_OUTPUT_FORMAT_Y);// * double(1 << FFTR4_SCALE); + tmp.re = (int)a; + a = st->data[jj].im;///double(1 << FFTR4_OUTPUT_FORMAT_Y);// * double(1 << FFTR4_SCALE); + tmp.im = (int)a; + st->x[ii*NFFT+jj].re = (int) tmp.re; + st->x[ii*NFFT+jj].im = (int) tmp.im; + a = st->data[jj+NFFT/2].re;///double(1 << FFTR4_OUTPUT_FORMAT_Y);// * double(1 << FFTR4_SCALE); + tmp.re = (int)a; + a = st->data[jj+NFFT/2].im;///double(1 << FFTR4_OUTPUT_FORMAT_Y);// * double(1 << FFTR4_SCALE); + tmp.im = (int)a; + st->x[ii*NFFT+jj+NFFT/2].re = (int) tmp.re; + st->x[ii*NFFT+jj+NFFT/2].im = (int) tmp.im; + } + } + + for (i=0; iout[i] = st->x[i].re * st->x[i].re + st->x[i].im * st->x[i].im; + } + + return 0; + +} + +void *app_factorymode_mic_cancellation_init(void* (* alloc_ext)(int)) +{ + struct mic_st_t *mic_st; + mic_st = (struct mic_st_t *)alloc_ext(sizeof(struct mic_st_t)); + return (void *)mic_st; +} + +#endif + diff --git a/apps/factory/app_factory_audio.h b/apps/factory/app_factory_audio.h new file mode 100644 index 0000000..51afdcf --- /dev/null +++ b/apps/factory/app_factory_audio.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_FACTORY_BT_H__ +#define __APP_FACTORY__BTH__ + +#include "app_utils.h" + +typedef struct { + uint16_t *buf; + uint32_t len; + uint32_t cuur_buf_pos; +}audio_test_pcmpatten_t; + +int app_factorymode_audioloop(bool on, enum APP_SYSFREQ_FREQ_T freq); + +int app_factorymode_output_pcmpatten(audio_test_pcmpatten_t *pcmpatten, uint8_t *buf, uint32_t len); + +int app_factorymode_mic_cancellation_run(void * mic_st, signed short *inbuf, int sample); + +void *app_factorymode_mic_cancellation_init(void* (* alloc_ext)(int)); + +#endif diff --git a/apps/factory/app_factory_bt.cpp b/apps/factory/app_factory_bt.cpp new file mode 100644 index 0000000..9f2dc20 --- /dev/null +++ b/apps/factory/app_factory_bt.cpp @@ -0,0 +1,331 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "hal_sleep.h" +#include "bt_drv_interface.h" +#include "intersyshci.h" +#include "apps.h" +#include "app_factory.h" +#include "app_factory_bt.h" +#include "app_utils.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_dev.h" +#include "pmu.h" +#include "tgt_hardware.h" +#include "app_battery.h" +#include "bt_drv_reg_op.h" +#include "conmgr_api.h" +#include "me_api.h" +#include "hal_bootmode.h" +#include "hal_chipid.h" + + +#define APP_FACT_CPU_WAKE_LOCK HAL_CPU_WAKE_LOCK_USER_3 + +#ifdef __FACTORY_MODE_SUPPORT__ +static uint8_t inquiry_buff[] = {0x01, 0x72, 0x77, 0xb0, 0x18, 0x57, 0x60,\ + 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00}; + + +static btif_cmgr_handler_t *app_factorymode_cmgrHandler; + + +static void bt_error_check_timer_handler(void const *param); +osTimerDef(bt_error_check_timer, bt_error_check_timer_handler); +static osTimerId bt_error_check_timer_id = NULL; +uint8_t test_mode_type=0; +static void bt_error_check_timer_handler(void const *param) +{ + //dump rssi + bt_drv_rssi_dump_handler(); + //check BT core status + if(bt_drv_error_check_handler()) + { + if(test_mode_type==1) + { + hal_sw_bootmode_set(HAL_SW_BOOTMODE_TEST_MODE|HAL_SW_BOOTMODE_TEST_SIGNALINGMODE); + } + else if(test_mode_type==2) + { + hal_sw_bootmode_set(HAL_SW_BOOTMODE_TEST_MODE|HAL_SW_BOOTMODE_TEST_NOSIGNALINGMODE); + } + hal_cmu_sys_reboot(); + } +} + +static void app_factorymode_bt_inquiry_buff_update(void) +{ + bt_bdaddr_t flsh_dongle_addr; + int ret = -1; + + ret = nvrec_dev_get_dongleaddr(&flsh_dongle_addr); + if(0 == ret) { + memcpy((void *)&inquiry_buff[1],(void *)flsh_dongle_addr.address,BTIF_BD_ADDR_SIZE); + DUMP8("0x%02x ", &inquiry_buff[2], BTIF_BD_ADDR_SIZE); + } +} + +static void app_factorymode_CmgrCallback(btif_cmgr_handler_t *cHandler, + cmgr_event_t Event, + bt_status_t Status) +{ + APP_FACTORY_TRACE(4,"%s cHandler:%p Event:%d status:%d", __func__, cHandler, Event, Status); + if (Event == BTIF_CMEVENT_DATA_LINK_CON_CNF){ + if (Status == BT_STS_SUCCESS){ + APP_FACTORY_TRACE(0,"connect ok"); + app_factorymode_result_set(true); + btif_cmgr_remove_data_link(cHandler); + + }else{ + APP_FACTORY_TRACE(0,"connect failed"); + app_factorymode_result_set(false); + } + } + + if (Event == BTIF_CMEVENT_DATA_LINK_DIS){ + if (Status == BT_STS_SUCCESS){ + APP_FACTORY_TRACE(0,"disconnect ok"); + }else{ + APP_FACTORY_TRACE(0,"disconnect failed"); + } + } +} + +static void app_factorymode_bt_InquiryResult_add(void) +{ + U8 len = 15; + bool rssi = false, extended = false; + U8* parm = (U8*)inquiry_buff; + + /* Found one or more devices. Report to clients */ + APP_FACTORY_TRACE(4,"%s len:%d rssi:%d extended:%d", __func__, len, rssi, extended); + DUMP8("0x%02x ", parm, len); + btif_me_inquiry_result_setup(parm, rssi, extended); +} + +void app_factorymode_bt_create_connect(void) +{ + bt_status_t status; + bt_bdaddr_t *bdAddr = (bt_bdaddr_t *)(inquiry_buff+1); + + status = btif_cmgr_create_data_link(app_factorymode_cmgrHandler, bdAddr); + APP_FACTORY_TRACE(2,"%s:%d", __func__, status); +} + +void app_factorymode_bt_init_connect(void) +{ + app_factorymode_cmgrHandler = btif_cmgr_handler_create(); + + btif_cmgr_register_handler(app_factorymode_cmgrHandler, + app_factorymode_CmgrCallback); + app_factorymode_bt_inquiry_buff_update(); + app_factorymode_bt_InquiryResult_add(); +} + +extern osTimerId app_bt_accessmode_timer; + +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) +#define XTAL_FCAP_RANGE (0x1FF) +#else +#define XTAL_FCAP_RANGE (0xFF) +#endif + +void app_factorymode_bt_xtalrangetest(APP_KEY_STATUS *status, void *param) +{ + dev_addr_name devinfo; + uint32_t fcap = 0; + APP_FACTORY_TRACE(1,"%s",__func__); +#ifdef __WATCHER_DOG_RESET__ + app_wdt_close(); +#endif + hal_cpu_wake_lock(APP_FACT_CPU_WAKE_LOCK); + app_stop_10_second_timer(APP_PAIR_TIMER_ID); + app_stop_10_second_timer(APP_POWEROFF_TIMER_ID); + if (app_bt_accessmode_timer){ + osTimerStop(app_bt_accessmode_timer); + } + if (!bt_error_check_timer_id){ + bt_error_check_timer_id = osTimerCreate(osTimer(bt_error_check_timer), osTimerPeriodic, NULL); + } + if (bt_error_check_timer_id != NULL) { + osTimerStart(bt_error_check_timer_id, 1000); + } + test_mode_type = 1; + app_status_indication_set(APP_STATUS_INDICATION_TESTMODE); + pmu_sleep_en(0); + BESHCI_Close(); + btdrv_hciopen(); + btdrv_hci_reset(); + +#ifndef BT_50_FUNCTION + btdrv_sleep_config(0); + osDelay(2000); + btdrv_ins_patch_test_init(); + btdrv_feature_default(); +#endif + devinfo.btd_addr = bt_addr; + devinfo.ble_addr = ble_addr; + devinfo.localname = BT_LOCAL_NAME; + nvrec_dev_localname_addr_init(&devinfo); + btdrv_write_localinfo((char *)devinfo.localname, strlen(devinfo.localname) + 1, devinfo.btd_addr); + + btdrv_vco_test_start(78); + while(1){ + btdrv_rf_set_xtal_fcap(fcap%XTAL_FCAP_RANGE, 1); + osDelay(300); + TRACE(2,"xtal tune:%d", fcap%XTAL_FCAP_RANGE); + fcap++; + } +} + +void app_factorymode_bt_signalingtest(APP_KEY_STATUS *status, void *param) +{ + dev_addr_name devinfo; + APP_FACTORY_TRACE(1,"%s",__func__); +#ifdef __WATCHER_DOG_RESET__ + app_wdt_close(); +#endif + hal_cpu_wake_lock(APP_FACT_CPU_WAKE_LOCK); + app_stop_10_second_timer(APP_PAIR_TIMER_ID); + app_stop_10_second_timer(APP_POWEROFF_TIMER_ID); + if (app_bt_accessmode_timer){ + osTimerStop(app_bt_accessmode_timer); + } + if (!bt_error_check_timer_id){ + bt_error_check_timer_id = osTimerCreate(osTimer(bt_error_check_timer), osTimerPeriodic, NULL); + } + if (bt_error_check_timer_id != NULL) { + osTimerStart(bt_error_check_timer_id, 1000); + } + test_mode_type = 1; + app_status_indication_set(APP_STATUS_INDICATION_TESTMODE); + pmu_sleep_en(0); + BESHCI_Close(); + btdrv_hciopen(); + btdrv_ins_patch_test_init(); + btdrv_hci_reset(); + +#ifndef BT_50_FUNCTION + btdrv_sleep_config(0); + osDelay(2000); + btdrv_testmode_start(); + btdrv_feature_default(); +#endif + devinfo.btd_addr = bt_addr; + devinfo.ble_addr = ble_addr; + devinfo.localname = BT_LOCAL_NAME; + devinfo.ble_name= BT_LOCAL_NAME; + nvrec_dev_localname_addr_init(&devinfo); +#ifdef __IBRT_IBRT_TESTMODE__ + uint8_t ibrt_address[6] = {0x11,0x22,0x33,0x44,0x55,0x66}; + memcpy(bt_addr,ibrt_address,6); + memcpy(devinfo.btd_addr,ibrt_address,6); +#endif + btdrv_write_localinfo((char *)devinfo.localname, strlen(devinfo.localname) + 1, devinfo.btd_addr); + bt_drv_extra_config_after_init(); + btdrv_enable_dut(); +#ifdef __IBRT_IBRT_TESTMODE__ + btdrv_enable_ibrt_test(); +#endif +} + +int app_battery_stop(void); +void app_factorymode_bt_nosignalingtest(APP_KEY_STATUS *status, void *param) +{ + dev_addr_name devinfo; + APP_FACTORY_TRACE(1,"%s",__func__); +#ifdef __WATCHER_DOG_RESET__ + app_wdt_close(); +#endif + hal_cpu_wake_lock(APP_FACT_CPU_WAKE_LOCK); + app_stop_10_second_timer(APP_PAIR_TIMER_ID); + app_stop_10_second_timer(APP_POWEROFF_TIMER_ID); + app_status_indication_set(APP_STATUS_INDICATION_TESTMODE1); + osTimerStop(app_bt_accessmode_timer); + if (!bt_error_check_timer_id){ + bt_error_check_timer_id = osTimerCreate(osTimer(bt_error_check_timer), osTimerPeriodic, NULL); + } + if (bt_error_check_timer_id != NULL) { + osTimerStart(bt_error_check_timer_id, 1000); + } + test_mode_type = 2; + app_battery_stop(); + pmu_sleep_en(0); + BESHCI_Close(); + btdrv_hciopen(); + btdrv_ins_patch_test_init(); + bt_drv_reg_op_key_gen_after_reset(false); + btdrv_hci_reset(); +#ifndef BT_50_FUNCTION + btdrv_sleep_config(0); +#endif + osDelay(2000); + btdrv_testmode_start(); +#ifndef BT_50_FUNCTION + btdrv_feature_default(); + devinfo.btd_addr = bt_addr; + devinfo.ble_addr = ble_addr; + devinfo.localname = BT_LOCAL_NAME; + devinfo.ble_name= BT_LOCAL_NAME; + nvrec_dev_localname_addr_init(&devinfo); + btdrv_write_localinfo((char *)devinfo.localname, strlen(devinfo.localname) + 1, devinfo.btd_addr); +#endif + bt_drv_extra_config_after_init(); + btdrv_hcioff(); +#ifdef __BT_DEBUG_TPORTS__ + { + extern void bt_enable_tports(void); + bt_enable_tports(); + //hal_iomux_tportopen(); + } +#endif + btdrv_uart_bridge_loop(); +} +int app_factorymode_bt_xtalcalib_proc(void) +{ + uint32_t capval = 0x80; + int nRet; + + APP_FACTORY_TRACE(1,"%s",__func__); + hal_cpu_wake_lock(APP_FACT_CPU_WAKE_LOCK); + APP_FACTORY_TRACE(1,"calib default, capval:%d", capval); + btdrv_hciopen(); + btdrv_hci_reset(); +#ifndef BT_50_FUNCTION + btdrv_ins_patch_test_init(); +#endif + btdrv_hcioff(); + capval = 0x80; + bt_drv_calib_open(); + nRet = bt_drv_calib_result_porc(&capval); + bt_drv_calib_close(); + TRACE(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!calib ret:%d, capval:%d", nRet, capval); + if (!nRet) + nvrec_dev_set_xtal_fcap((unsigned int)capval); + + return nRet; +} + +void app_factorymode_bt_xtalcalib(APP_KEY_STATUS *status, void *param) +{ + APP_FACTORY_TRACE(1,"%s",__func__); + app_factorymode_bt_xtalcalib_proc(); +} + +#endif + diff --git a/apps/factory/app_factory_bt.h b/apps/factory/app_factory_bt.h new file mode 100644 index 0000000..5255c96 --- /dev/null +++ b/apps/factory/app_factory_bt.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_FACTORY_BT_H__ +#define __APP_FACTORY__BTH__ + +#include "app_key.h" + + +void app_factorymode_bt_create_connect(void); + +void app_factorymode_bt_init_connect(void); + +int app_factorymode_bt_xtalcalib_proc(void); + +void app_factorymode_bt_xtalrangetest(APP_KEY_STATUS *status, void *param); + +void app_factorymode_bt_signalingtest(APP_KEY_STATUS *status, void *param); + +void app_factorymode_bt_nosignalingtest(APP_KEY_STATUS *status, void *param); + +void app_factorymode_bt_xtalcalib(APP_KEY_STATUS *status, void *param); + +#endif diff --git a/apps/factory/app_factory_cdc_comm.c b/apps/factory/app_factory_cdc_comm.c new file mode 100644 index 0000000..f67f90d --- /dev/null +++ b/apps/factory/app_factory_cdc_comm.c @@ -0,0 +1,314 @@ +#ifdef __USB_COMM__ +#include "stdint.h" +#include "stdbool.h" +#include "plat_types.h" +#include "string.h" +#include "stdio.h" +#include "tool_msg.h" +#include "sys_api_cdc_comm.h" +#include "app_factory_cdc_comm.h" + +static enum PARSE_STATE parse_state; +static struct message_t recv_msg; +static struct message_t send_msg = { { PREFIX_CHAR, }, }; + +static unsigned char check_sum(unsigned char *buf, unsigned char len) +{ + int i; + unsigned char sum = 0; + + for (i = 0; i < len; i++) { + sum += buf[i]; + } + + return sum; +} + +int send_reply(const unsigned char *payload, unsigned int len) +{ + int ret = 0; + + if (len + 1 > sizeof(send_msg.data)) { + TRACE(1,"Packet length too long: %u", len); + return -1; + } + + send_msg.hdr.type = recv_msg.hdr.type; + send_msg.hdr.seq = recv_msg.hdr.seq; + send_msg.hdr.len = len; + memcpy(&send_msg.data[0], payload, len); + send_msg.data[len] = ~check_sum((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg) - 1); + + ret = send_data((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg)); + + return ret; +} + +static void reset_parse_state(unsigned char **buf, size_t *len) +{ + parse_state = PARSE_HEADER; + memset(&recv_msg.hdr, 0, sizeof(recv_msg.hdr)); + + *buf = (unsigned char *)&recv_msg.hdr; + *len = sizeof(recv_msg.hdr); +} + +static enum ERR_CODE check_msg_hdr(void) +{ + enum ERR_CODE errcode = ERR_NONE; + + switch (recv_msg.hdr.type) { + case TYPE_SYS: + if (recv_msg.hdr.len != 1 && recv_msg.hdr.len != 5) { + //TRACE(1,"SYS msg length error: %u", recv_msg.hdr.len); + errcode = ERR_LEN; + } + break; + case TYPE_READ: + if (recv_msg.hdr.len != 4) { + //TRACE(1,"READ msg length error: %u", recv_msg.hdr.len); + errcode = ERR_LEN; + } + break; + case TYPE_WRITE: + if (recv_msg.hdr.len <= 4 || recv_msg.hdr.len > 20) { + //TRACE(1,"WRITE msg length error: %u", recv_msg.hdr.len); + errcode = ERR_LEN; + } + break; + default: + break; + } + + if (errcode == ERR_NONE && recv_msg.hdr.len + 1 > sizeof(recv_msg.data)) { + errcode = ERR_LEN; + } + + return errcode; +} + +static enum ERR_CODE handle_sys_cmd(enum SYS_CMD_TYPE cmd, unsigned char *param, unsigned int len) +{ + unsigned char cret[5]; + unsigned int bootmode; + + cret[0] = ERR_NONE; + + if (cmd == SYS_CMD_SET_BOOTMODE || cmd == SYS_CMD_CLR_BOOTMODE) { + if (len != 4) { + TRACE(2,"Invalid SYS CMD len %u for cmd: 0x%x", len, cmd); + return ERR_DATA_LEN; + } + } else { + if (len != 0) { + TRACE(2,"Invalid SYS CMD len %u for cmd: 0x%x", len, cmd); + return ERR_DATA_LEN; + } + } + + switch (cmd) { + case SYS_CMD_REBOOT: { + TRACE(0,"--- Reboot---"); + send_reply(cret, 1); + system_reboot(); + break; + } + case SYS_CMD_SHUTDOWN: { + TRACE(0,"--- Shutdown ---"); + send_reply(cret, 1); + system_shutdown(); + break; + } + case SYS_CMD_SET_BOOTMODE: { + TRACE(0,"--- Set bootmode ---"); + memcpy(&bootmode, param, 4); + system_set_bootmode(bootmode); + send_reply(cret, 1); + break; + } + case SYS_CMD_CLR_BOOTMODE: { + TRACE(0,"--- Clear bootmode ---"); + memcpy(&bootmode, param, 4); + system_clear_bootmode(bootmode); + send_reply(cret, 1); + break; + } + case SYS_CMD_GET_BOOTMODE: { + TRACE(0,"--- Get bootmode ---"); + bootmode = system_get_bootmode(); + memcpy(&cret[1], &bootmode, 4); + send_reply(cret, 5); + break; + } + default: { + TRACE(1,"Invalid command: 0x%x", recv_msg.data[0]); + return ERR_SYS_CMD; + } + } + + return ERR_NONE; +} + +static enum ERR_CODE handle_data(unsigned char **buf, size_t *len, int *extra) +{ + enum ERR_CODE errcode = ERR_NONE; +#if 0 + uint32_t rlen = 0; +#endif + *extra = 0; + + // Checksum + if (check_sum((unsigned char *)&recv_msg, MSG_TOTAL_LEN(&recv_msg)) != 0xFF) { + TRACE(0,"Checksum error"); + return ERR_CHECKSUM; + } + + switch (recv_msg.hdr.type) { + case TYPE_SYS: { + TRACE_TIME(0,"------ SYS CMD ------"); + errcode = handle_sys_cmd((enum SYS_CMD_TYPE)recv_msg.data[0], &recv_msg.data[1], recv_msg.hdr.len - 1); + if (errcode != ERR_NONE) { + return errcode; + } + break; + } + case TYPE_READ: { + TRACE_TIME(0,"------ READ CMD ------"); +#if 0 + uint32_t addr = (recv_msg.data[0] << 16) | (recv_msg.data[1] << 8) | recv_msg.data[2]; + uint8_t data[4] = {0}; + rlen = read_reg(addr, data); + if(rlen == 0) + return ERR_LEN; + else { + send_reply(data, rlen); + } +#endif + break; + } + case TYPE_WRITE: { + TRACE_TIME(0,"------ WRITE CMD ------"); +#if 0 + uint32_t addr = (recv_msg.data[0] << 16) | (recv_msg.data[1] << 8) | recv_msg.data[2]; + uint32_t wdata = (recv_msg.data[3] << 24) | (recv_msg.data[4] << 16) | (recv_msg.data[5] << 8) | recv_msg.data[6]; + uint8_t data[1] = {0}; + errcode = write_reg(addr, wdata); + if (errcode != ERR_NONE) + return errcode; + else + send_reply(data, 1); +#endif + break; + } + + default: + break; + } + + return ERR_NONE; +} + +static int parse_packet(unsigned char **buf, size_t *len) +{ + enum ERR_CODE errcode; + int rlen = *len; + unsigned char *data; + int i; + int extra; + unsigned char cret; + + switch (parse_state) { + case PARSE_HEADER: + ASSERT(rlen > 0 && rlen <= sizeof(recv_msg.hdr), "Invalid rlen!"); + + if (recv_msg.hdr.prefix == PREFIX_CHAR) { + errcode = check_msg_hdr(); + if (errcode != ERR_NONE) { + goto _err; + } + parse_state = PARSE_DATA; + *buf = &recv_msg.data[0]; + *len = recv_msg.hdr.len + 1; + } else { + data = (unsigned char *)&recv_msg.hdr.prefix; + for (i = 1; i < rlen; i++) { + if (data[i] == PREFIX_CHAR) { + memmove(&recv_msg.hdr.prefix, &data[i], rlen - i); + break; + } + } + *buf = &data[rlen - i]; + *len = sizeof(recv_msg.hdr) + i - rlen; + } + break; + case PARSE_DATA: + errcode = handle_data(buf, len, &extra); + if (errcode != ERR_NONE) { + goto _err; + } + // Receive next message + reset_parse_state(buf, len); + break; + default: + TRACE(1,"Invalid parse_state: %d", parse_state); + break; + } + + return 0; + +_err: + cancel_input(); + cret = (unsigned char)errcode; + send_reply(&cret, 1); + + return 1; +} + +void comm_loop(void) +{ + int ret; + unsigned char *buf = NULL; + size_t len = 0; + size_t buf_len, rlen; + +_sync: + reset_transport(); + reset_parse_state(&buf, &len); + + while (1) { + rlen = 0; + if (parse_state == PARSE_HEADER) { + set_recv_timeout(default_recv_timeout_idle); + } else { + set_recv_timeout(default_recv_timeout_short); + } + buf_len = 0; + + ret = recv_data_ex(buf, buf_len, len, &rlen); + if (ret) { + TRACE(1,"Receiving data failed: %d", ret); + goto _err; + } + + if (len != rlen) { + TRACE(2,"Receiving part of the data: expect=%u real=%u", len, rlen); + goto _err; + } + + ret = parse_packet(&buf, &len); + if (ret) { + TRACE(0,"Parsing packet failed"); + goto _err; + } + } + +_err: + ret = handle_error(); + if (ret == 0) { + TRACE(0,"retry ..."); + goto _sync; + } + + return; +} +#endif diff --git a/apps/factory/app_factory_cdc_comm.h b/apps/factory/app_factory_cdc_comm.h new file mode 100644 index 0000000..726f206 --- /dev/null +++ b/apps/factory/app_factory_cdc_comm.h @@ -0,0 +1,17 @@ +#ifndef __APP_FACTORY_CDC_COMM__H__ +#define __APP_FACTORY_CDC_COMM__H__ +#ifdef __USB_COMM__ +#ifdef __cplusplus +extern "C" { +#endif + +void comm_loop(void); + +int send_reply(const unsigned char *payload, unsigned int len); + +#ifdef __cplusplus +} +#endif +#endif +#endif + diff --git a/apps/factory/sys_api_cdc_comm.c b/apps/factory/sys_api_cdc_comm.c new file mode 100644 index 0000000..2ae4a6b --- /dev/null +++ b/apps/factory/sys_api_cdc_comm.c @@ -0,0 +1,229 @@ +#ifdef __USB_COMM__ +#include "sys_api_cdc_comm.h" +#include "app_factory_cdc_comm.h" +#include "hal_bootmode.h" +#include "hwtimer_list.h" +#include "pmu.h" +#ifdef CHIP_HAS_USB +#include "usb_cdc.h" +#endif + +#define TIMEOUT_INFINITE ((uint32_t)-1) + +const unsigned int default_recv_timeout_short = MS_TO_TICKS(500); +const unsigned int default_recv_timeout_idle = TIMEOUT_INFINITE; //MS_TO_TICKS(10 * 60 * 1000); +const unsigned int default_recv_timeout_4k_data = MS_TO_TICKS(500); +const unsigned int default_send_timeout = MS_TO_TICKS(500); + +static uint32_t send_timeout; +static uint32_t recv_timeout; + +static volatile bool cancel_xfer = false; + +static uint32_t xfer_err_time = 0; +static uint32_t xfer_err_cnt = 0; + +static HWTIMER_ID xfer_timer; + +static const struct USB_SERIAL_CFG_T cdc_cfg = { + .mode = USB_SERIAL_API_NONBLOCKING, +}; + +void reset_transport(void) +{ + cancel_xfer = false; + + if (xfer_timer) { + hwtimer_stop(xfer_timer); + } else { + xfer_timer = hwtimer_alloc(NULL, NULL); + } + + usb_serial_flush_recv_buffer(); + usb_serial_init_xfer(); + set_recv_timeout(default_recv_timeout_short); + set_send_timeout(default_send_timeout); +} + +void set_recv_timeout(unsigned int timeout) +{ + recv_timeout = timeout; +} + +void set_send_timeout(unsigned int timeout) +{ + send_timeout = timeout; +} + +static void usb_send_timeout(void *param) +{ + usb_serial_cancel_send(); +} + +static void usb_send_timer_start(void) +{ + if (send_timeout == TIMEOUT_INFINITE) { + return; + } + + if (xfer_timer) { + hwtimer_update_then_start(xfer_timer, usb_send_timeout, NULL, send_timeout); + } +} + +static void usb_send_timer_stop(void) +{ + if (xfer_timer) { + hwtimer_stop(xfer_timer); + } +} + +static int usb_send_data(const unsigned char *buf, size_t len) +{ + int ret; + + usb_send_timer_start(); + ret = usb_serial_send(buf, len); + usb_send_timer_stop(); + return ret; +} + +int send_data(const unsigned char *buf, size_t len) +{ + if (cancel_xfer) { + return -1; + } + return usb_send_data(buf, len); +} + +static void usb_recv_timeout(void *param) +{ + usb_serial_cancel_recv(); +} + +static void usb_recv_timer_start(void) +{ + if (recv_timeout == TIMEOUT_INFINITE) { + return; + } + + if (xfer_timer) { + hwtimer_update_then_start(xfer_timer, usb_recv_timeout, NULL, recv_timeout); + } +} + +static void usb_recv_timer_stop(void) +{ + if (xfer_timer) { + hwtimer_stop(xfer_timer); + } +} + +static int usb_recv_data(unsigned char *buf, size_t len, size_t *rlen) +{ + int ret; + + usb_recv_timer_start(); + ret = usb_serial_recv(buf, len); + usb_recv_timer_stop(); + if (ret == 0) { + *rlen = len; + } + return ret; +} + +int recv_data_ex(unsigned char *buf, size_t len, size_t expect, size_t *rlen) +{ + if (cancel_xfer) { + return -1; + } + return usb_recv_data(buf, expect, rlen); +} + +static int usb_handle_error(void) +{ + int ret; + + TRACE(0,"****** Send break ******"); + + // Send break signal, to tell the peer to reset the connection + ret = usb_serial_send_break(); + if (ret) { + TRACE(1,"Sending break failed: %d", ret); + } + return ret; +} + +int handle_error(void) +{ + int ret = 0; + uint32_t err_time; + + hal_sys_timer_delay(MS_TO_TICKS(50)); + + if (!cancel_xfer) { + ret = usb_handle_error(); + } + + err_time = hal_sys_timer_get(); + if (xfer_err_cnt == 0 || err_time - xfer_err_time > MS_TO_TICKS(5000)) { + xfer_err_cnt = 0; + xfer_err_time = err_time; + } + xfer_err_cnt++; + if (xfer_err_cnt < 3) { + hal_sys_timer_delay(MS_TO_TICKS(100)); + } else if (xfer_err_cnt < 5) { + hal_sys_timer_delay(MS_TO_TICKS(500)); + } else { + hal_sys_timer_delay(MS_TO_TICKS(2000)); + } + + return ret; +} + +static int usb_cancel_input(void) +{ + return usb_serial_flush_recv_buffer(); +} + +int cancel_input(void) +{ + return usb_cancel_input(); +} + +void system_reboot(void) +{ + hal_sys_timer_delay(MS_TO_TICKS(10)); + hal_cmu_sys_reboot(); +} + +void system_shutdown(void) +{ +#if 0 + if (dld_transport == TRANSPORT_USB) { + // Avoid PC usb serial driver hanging + usb_serial_close(); + } +#endif + hal_sys_timer_delay(MS_TO_TICKS(10)); + pmu_shutdown(); +} + +void system_set_bootmode(unsigned int bootmode) +{ + bootmode &= ~(HAL_SW_BOOTMODE_READ_ENABLED | HAL_SW_BOOTMODE_WRITE_ENABLED); + hal_sw_bootmode_set(bootmode); +} + +void system_clear_bootmode(unsigned int bootmode) +{ + bootmode &= ~(HAL_SW_BOOTMODE_READ_ENABLED | HAL_SW_BOOTMODE_WRITE_ENABLED); + hal_sw_bootmode_clear(bootmode); +} + +unsigned int system_get_bootmode(void) +{ + return hal_sw_bootmode_get(); +} +#endif diff --git a/apps/factory/sys_api_cdc_comm.h b/apps/factory/sys_api_cdc_comm.h new file mode 100644 index 0000000..9a8bf7b --- /dev/null +++ b/apps/factory/sys_api_cdc_comm.h @@ -0,0 +1,41 @@ +#ifndef __SYS_API_USB_CDC_H__ +#define __SYS_API_USB_CDC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tool_msg.h" +#include "hal_trace.h" +#include "hal_timer.h" + +#define TRACE_TIME(num,str, ...) TRACE(num+1,"[%05u] " str, TICKS_TO_MS(hal_sys_timer_get()), ##__VA_ARGS__) + +extern const unsigned int default_recv_timeout_short; +extern const unsigned int default_recv_timeout_idle; +extern const unsigned int default_recv_timeout_4k_data; +extern const unsigned int default_send_timeout; + +void reset_transport(void); + +void set_recv_timeout(unsigned int timeout); +void set_send_timeout(unsigned int timeout); + +int send_data(const unsigned char *buf, size_t len); +int recv_data_ex(unsigned char *buf, size_t len, size_t expect, size_t *rlen); +int handle_error(void); +int cancel_input(void); + +void system_reboot(void); +void system_shutdown(void); +void system_flash_boot(void); +void system_set_bootmode(unsigned int bootmode); +void system_clear_bootmode(unsigned int bootmode); +unsigned int system_get_bootmode(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/apps/key/Makefile b/apps/key/Makefile new file mode 100644 index 0000000..508c5bf --- /dev/null +++ b/apps/key/Makefile @@ -0,0 +1,8 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +subdir-ccflags-y += -Iutils/list \ No newline at end of file diff --git a/apps/key/app_key.cpp b/apps/key/app_key.cpp new file mode 100644 index 0000000..73ce657 --- /dev/null +++ b/apps/key/app_key.cpp @@ -0,0 +1,167 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "list.h" +#include "string.h" +#include "app_thread.h" +#include "app_key.h" +#include "hal_trace.h" + +#define APP_KEY_TRACE(s,...) //TRACE(s, ##__VA_ARGS__) + +#define KEY_EVENT_CNT_LIMIT (3) + +typedef struct { + list_t *key_list; +}APP_KEY_CONFIG; + +APP_KEY_CONFIG app_key_conifg = { + .key_list = NULL +}; + +osPoolDef (app_key_handle_mempool, 20, APP_KEY_HANDLE); +osPoolId app_key_handle_mempool = NULL; +static uint8_t key_event_cnt = 0; + +static int key_event_process(uint32_t key_code, uint8_t key_event) +{ + uint32_t app_keyevt; + APP_MESSAGE_BLOCK msg; + + if (key_event_cnt>KEY_EVENT_CNT_LIMIT){ + return 0; + }else{ + key_event_cnt++; + } + + msg.mod_id = APP_MODUAL_KEY; + APP_KEY_SET_MESSAGE(app_keyevt, key_code, key_event); + msg.msg_body.message_id = app_keyevt; + msg.msg_body.message_ptr = (uint32_t)NULL; + app_mailbox_put(&msg); + + return 0; +} + +void app_key_simulate_key_event(uint32_t key_code, uint8_t key_event) +{ + key_event_process(key_code, key_event); +} + +static void app_key_handle_free(void *key_handle) +{ + osPoolFree (app_key_handle_mempool, key_handle); +} + +static APP_KEY_HANDLE *app_key_handle_find(const APP_KEY_STATUS *key_status) +{ + APP_KEY_HANDLE *key_handle = NULL; + list_node_t *node = NULL; + + for (node = list_begin(app_key_conifg.key_list); node != list_end(app_key_conifg.key_list); node = list_next(node)) { + key_handle = (APP_KEY_HANDLE *)list_node(node); + if ((key_handle->key_status.code == key_status->code)&&(key_handle->key_status.event == key_status->event)) + return key_handle; + } + + return NULL; +} + +static int app_key_handle_process(APP_MESSAGE_BODY *msg_body) +{ + APP_KEY_STATUS key_status; + APP_KEY_HANDLE *key_handle = NULL; + + APP_KEY_GET_CODE(msg_body->message_id, key_status.code); + APP_KEY_GET_EVENT(msg_body->message_id, key_status.event); + + APP_KEY_TRACE(3,"%s code:%d event:%d",__func__,key_status.code, key_status.event); + + key_event_cnt--; + + key_handle = app_key_handle_find(&key_status); + + if (key_handle != NULL && key_handle->function!= NULL) + ((APP_KEY_HANDLE_CB_T)key_handle->function)(&key_status,key_handle->param); + + return 0; +} + +int app_key_handle_registration(const APP_KEY_HANDLE *key_handle) +{ + APP_KEY_HANDLE *dest_key_handle = NULL; + APP_KEY_TRACE(1,"%s",__func__); + dest_key_handle = app_key_handle_find(&(key_handle->key_status)); + + APP_KEY_TRACE(2,"%s dest handle:0x%x",__func__,dest_key_handle); + if (dest_key_handle == NULL){ + dest_key_handle = (APP_KEY_HANDLE *)osPoolCAlloc (app_key_handle_mempool); + APP_KEY_TRACE(2,"%s malloc:0x%x",__func__,dest_key_handle); + list_append(app_key_conifg.key_list, dest_key_handle); + } + if (dest_key_handle == NULL) + return -1; + APP_KEY_TRACE(5,"%s set handle:0x%x code:%d event:%d function:%x",__func__,dest_key_handle, key_handle->key_status.code, key_handle->key_status.event, key_handle->function); + dest_key_handle->key_status.code = key_handle->key_status.code; + dest_key_handle->key_status.event = key_handle->key_status.event; + dest_key_handle->string = key_handle->string; + dest_key_handle->function = key_handle->function; + dest_key_handle->param = key_handle->param;; + + return 0; +} + +void app_key_handle_clear(void) +{ + list_clear(app_key_conifg.key_list); +} + +int app_key_open(int checkPwrKey) +{ + APP_KEY_TRACE(2,"%s %x",__func__, app_key_conifg.key_list); + + if (app_key_conifg.key_list == NULL) + app_key_conifg.key_list = list_new(app_key_handle_free, NULL, NULL); + + if (app_key_handle_mempool == NULL) + app_key_handle_mempool = osPoolCreate(osPool(app_key_handle_mempool)); + + app_set_threadhandle(APP_MODUAL_KEY, app_key_handle_process); + + return hal_key_open(checkPwrKey, key_event_process); +} + +int app_key_close(void) +{ + hal_key_close(); + if (app_key_conifg.key_list != NULL) + list_free(app_key_conifg.key_list); + app_set_threadhandle(APP_MODUAL_KEY, NULL); + return 0; +} + +uint32_t app_key_read_status(uint32_t code) +{ + return (uint32_t)hal_key_read_status((enum HAL_KEY_CODE_T)code); +} + +#if defined(_AUTO_TEST_) +int simul_key_event_process(uint32_t key_code, uint8_t key_event) +{ + return key_event_process(key_code, key_event); +} +#endif + diff --git a/apps/key/app_key.h b/apps/key/app_key.h new file mode 100644 index 0000000..e7cccc5 --- /dev/null +++ b/apps/key/app_key.h @@ -0,0 +1,109 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_KEY_H__ +#define __APP_KEY_H__ + +#include "hal_key.h" + +#define APP_KEY_SET_MESSAGE(appevt, code, evt) (appevt = (((uint32_t)code&0xffffff)<<8)|(evt&0xff)) +#define APP_KEY_GET_CODE(appevt, code) (code = (appevt>>8)&0xffffff) +#define APP_KEY_GET_EVENT(appevt, evt) (evt = appevt&0xff) + +#define APP_KEY_CODE_GOOGLE APP_KEY_CODE_FN15 +#define APP_KEY_CODE_VOICEPATH APP_KEY_CODE_FN15 +#define APP_KEY_CODE_TILE APP_KEY_CODE_FN15 + +enum APP_KEY_CODE_T { + APP_KEY_CODE_NONE = HAL_KEY_CODE_NONE, + APP_KEY_CODE_PWR = HAL_KEY_CODE_PWR, + APP_KEY_CODE_FN1 = HAL_KEY_CODE_FN1, + APP_KEY_CODE_FN2 = HAL_KEY_CODE_FN2, + APP_KEY_CODE_FN3 = HAL_KEY_CODE_FN3, + APP_KEY_CODE_FN4 = HAL_KEY_CODE_FN4, + APP_KEY_CODE_FN5 = HAL_KEY_CODE_FN5, + APP_KEY_CODE_FN6 = HAL_KEY_CODE_FN6, + APP_KEY_CODE_FN7 = HAL_KEY_CODE_FN7, + APP_KEY_CODE_FN8 = HAL_KEY_CODE_FN8, + APP_KEY_CODE_FN9 = HAL_KEY_CODE_FN9, + APP_KEY_CODE_FN10 = HAL_KEY_CODE_FN10, + APP_KEY_CODE_FN11 = HAL_KEY_CODE_FN11, + APP_KEY_CODE_FN12 = HAL_KEY_CODE_FN12, + APP_KEY_CODE_FN13 = HAL_KEY_CODE_FN13, + APP_KEY_CODE_FN14 = HAL_KEY_CODE_FN14, + APP_KEY_CODE_FN15 = HAL_KEY_CODE_FN15, +}; + +enum APP_KEY_EVENT_T { + APP_KEY_EVENT_NONE = HAL_KEY_EVENT_NONE, + APP_KEY_EVENT_DOWN = HAL_KEY_EVENT_DOWN, + APP_KEY_EVENT_FIRST_DOWN = HAL_KEY_EVENT_FIRST_DOWN, + APP_KEY_EVENT_CONTINUED_DOWN = HAL_KEY_EVENT_CONTINUED_DOWN, + APP_KEY_EVENT_UP = HAL_KEY_EVENT_UP, + APP_KEY_EVENT_UP_AFTER_LONGPRESS = HAL_KEY_EVENT_UP_AFTER_LONGPRESS, + APP_KEY_EVENT_LONGPRESS = HAL_KEY_EVENT_LONGPRESS, + APP_KEY_EVENT_LONGLONGPRESS = HAL_KEY_EVENT_LONGLONGPRESS, + APP_KEY_EVENT_CLICK = HAL_KEY_EVENT_CLICK, + APP_KEY_EVENT_DOUBLECLICK = HAL_KEY_EVENT_DOUBLECLICK, + APP_KEY_EVENT_TRIPLECLICK = HAL_KEY_EVENT_TRIPLECLICK, + APP_KEY_EVENT_ULTRACLICK = HAL_KEY_EVENT_ULTRACLICK, + APP_KEY_EVENT_RAMPAGECLICK = HAL_KEY_EVENT_RAMPAGECLICK, + APP_KEY_EVENT_SIXTHCLICK = HAL_KEY_EVENT_SIXTHCLICK, + APP_KEY_EVENT_SEVENTHCLICK = HAL_KEY_EVENT_SEVENTHCLICK, + APP_KEY_EVENT_EIGHTHCLICK = HAL_KEY_EVENT_EIGHTHCLICK, + APP_KEY_EVENT_NINETHCLICK = HAL_KEY_EVENT_NINETHCLICK, + APP_KEY_EVENT_TENTHCLICK = HAL_KEY_EVENT_TENTHCLICK, + APP_KEY_EVENT_REPEAT = HAL_KEY_EVENT_REPEAT, + APP_KEY_EVENT_GROUPKEY_DOWN = HAL_KEY_EVENT_GROUPKEY_DOWN, + APP_KEY_EVENT_GROUPKEY_REPEAT = HAL_KEY_EVENT_GROUPKEY_REPEAT, + APP_KEY_EVENT_INITDOWN = HAL_KEY_EVENT_INITDOWN, + APP_KEY_EVENT_INITUP = HAL_KEY_EVENT_INITUP, + APP_KEY_EVENT_INITLONGPRESS = HAL_KEY_EVENT_INITLONGPRESS, + APP_KEY_EVENT_INITLONGLONGPRESS = HAL_KEY_EVENT_INITLONGLONGPRESS, + APP_KEY_EVENT_INITFINISHED = HAL_KEY_EVENT_INITFINISHED, + + APP_KEY_EVENT_NUM = HAL_KEY_EVENT_NUM, +}; + +typedef struct { + uint32_t code; + uint8_t event; +}APP_KEY_STATUS; + +typedef void (*APP_KEY_HANDLE_CB_T)(APP_KEY_STATUS*, void *param); + +typedef struct { + APP_KEY_STATUS key_status; + const char* string; + APP_KEY_HANDLE_CB_T function; + void *param; +} APP_KEY_HANDLE; + +int app_key_open(int checkPwrKey); + +int app_key_close(void); + +uint32_t app_key_read_status(uint32_t code); + +int app_key_handle_registration(const APP_KEY_HANDLE *key_handle); + +void app_key_handle_clear(void); + +void app_key_simulate_key_event(uint32_t key_code, uint8_t key_event); + +#if defined(_AUTO_TEST_) +int simul_key_event_process(uint32_t key_code, uint8_t key_event); +#endif +#endif//__FMDEC_H__ diff --git a/apps/main/Makefile b/apps/main/Makefile new file mode 100644 index 0000000..3f37eae --- /dev/null +++ b/apps/main/Makefile @@ -0,0 +1,142 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) + +ifneq ($(wildcard $(cur_dir)../../config/$(T)/app_status_ind.c),) +obj-y += ../../config/$(T)/app_status_ind.c +else +obj-y += ../../config/$(DEFAULT_CFG_SRC)/app_status_ind.c +endif + +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y += \ + $(BT_IF_INCLUDES) \ + -Iservices/bt_app \ + -Iservices/audioflinger \ + -Iservices/norflash_api \ + -Iservices/nvrecord \ + -Iservices/nv_section/factory_section \ + -Iservices/nv_section/log_section \ + -Iservices/overlay \ + -Iservices/resources \ + -Iservices/audio_process \ + -Iapps/apptester \ + -Iapps/factory \ + -Iutils/crc32 \ + -Iplatform/drivers/bt \ + -Iplatform/drivers/ana \ + -Iapps/audioplayers/rbplay \ + -Itests/anc_usb \ + -Iapps/anc/inc \ + -Iapps/ota \ + -Ithirdparty/userapi \ + -Iservices/voicepath \ + -Iservices/ble_app \ + -Iservices/ble_app/app_main \ + -Iservices/ble_app/app_gfps \ + -Iservices/voicepath/gsound/gsound_service \ + -Iservices/voicepath/gsound/gsound_target \ + -Iservices/voicepath/gsound/gsound_custom/inc \ + -Iservices/voicepath/gsound/gsound_target_api_read_only \ + -Iservices/communication \ + -Iutils/cqueue \ + -Iservices/ai_voice/audio \ + -Iservices/ai_voice/manager \ + -Iservices/ai_voice/transport \ + -Iservices/app_ai/inc \ + -Iservices/interconnection/red \ + -Iservices/interconnection/green \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/bridge/ \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/src/gap/ \ + -Iservices/ble_stack/hl/src/gap/gapc/ \ + -Iservices/ble_stack/hl/src/gap/gapm/ \ + -Iservices/ble_stack/hl/src/gap/smpc/ \ + -Iservices/ble_stack/ke/src/ \ + -Iservices/ble_stack/hl/src/gatt/attc/ \ + -Iservices/ble_stack/hl/src/gatt/attm/ \ + -Iservices/ble_stack/hl/src/gatt/atts/ \ + -Iservices/ble_stack/hl/src/gatt/gattc/ \ + -Iservices/ble_stack/hl/src/gatt/gattm/ \ + -Iservices/ble_stack/hl/src/gatt/ \ + -Iservices/ble_stack/hl/src/l2c/l2cc/ \ + -Iservices/ble_stack/hl/src/l2c/l2cm/ \ + -Iservices/ble_stack/hci/api/ \ + -Iservices/ble_stack/hci/src/ \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/app/src/ \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/bt_app/a2dp_codecs/include \ + -Ithirdparty/tile \ + -Iservices/app_tws/inc \ + -Ithirdparty/tile/tile_target + +ifeq ($(VOICE_DATAPATH_ENABLED),1) +ccflags-y += -Iservices/voicepath/$(VOICE_DATAPATH_TYPE) +endif + +ifeq ($(IBRT),1) +ccflags-y += -Iservices/ibrt_core/inc +ccflags-y += -Iservices/ibrt_ui/inc +ccflags-y += -Iservices/app_ibrt/inc +endif + +ifeq ($(APP_TEST_AUDIO),1) +CFLAGS_apps_tester.o += -DAPP_TEST_AUDIO +endif + +ifeq ($(OTA_ENABLE),1) +ccflags-y += -Iservices/ota +ifeq ($(IBRT),1) +ccflags-y += -Iservices/ibrt_ota/inc +endif +endif + +CFLAGS_apps.o += $(LDS_SECTION_FLAGS) + +ifeq ($(ANC_APP),1) +CFLAGS_apps_tester.o += -DANC_APP +CFLAGS_apps.o += -DANC_APP +endif + +ifeq ($(RB_CODEC),1) +CFLAGS_apps.o += -DRB_CODEC +endif + +ifeq ($(VOICE_PROMPT),1) +CFLAGS_apps.o += -DMEDIA_PLAYER_SUPPORT +endif + +ifeq ($(ENGINEER_MODE),1) +CFLAGS_apps.o += -D__ENGINEER_MODE_SUPPORT__ +endif + +ifeq ($(MCU_HIGH_PERFORMANCE_MODE),1) +CFLAGS_apps.o += -DMCU_HIGH_PERFORMANCE_MODE +endif + +ifeq ($(BTADDR_FOR_DEBUG),1) +CFLAGS_apps.o += -DBTADDR_FOR_DEBUG +endif + +ifeq ($(FORCE_SIGNALINGMODE),1) +CFLAGS_apps.o += -DFORCE_SIGNALINGMODE +endif + +ifeq ($(FORCE_NOSIGNALINGMODE),1) +CFLAGS_apps.o += -DFORCE_NOSIGNALINGMODE +endif + +ifeq ($(POWERKEY_I2C_SWITCH),1) +CFLAGS_apps.o += -DPOWERKEY_I2C_SWITCH +endif + diff --git a/apps/main/app_status_ind.h b/apps/main/app_status_ind.h new file mode 100644 index 0000000..4391d49 --- /dev/null +++ b/apps/main/app_status_ind.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_STATUS_IND_H__ +#define __APP_STATUS_IND_H__ + +#ifdef RTOS +#include "cmsis_os.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum APP_STATUS_INDICATION_T { + APP_STATUS_INDICATION_POWERON = 0, + APP_STATUS_INDICATION_INITIAL, + APP_STATUS_INDICATION_PAGESCAN, + APP_STATUS_INDICATION_POWEROFF, + APP_STATUS_INDICATION_CHARGENEED, + APP_STATUS_INDICATION_CHARGING, + APP_STATUS_INDICATION_FULLCHARGE, + APP_STATUS_INDICATION_NO_REPEAT_NUM, + /* repeatable status: */ + APP_STATUS_INDICATION_BOTHSCAN = APP_STATUS_INDICATION_NO_REPEAT_NUM, + APP_STATUS_INDICATION_CONNECTING, + APP_STATUS_INDICATION_CONNECTED, + APP_STATUS_INDICATION_DISCONNECTED, + APP_STATUS_INDICATION_CALLNUMBER, + APP_STATUS_INDICATION_INCOMINGCALL, + APP_STATUS_INDICATION_PAIRSUCCEED, + APP_STATUS_INDICATION_PAIRFAIL, + APP_STATUS_INDICATION_HANGUPCALL, + APP_STATUS_INDICATION_REFUSECALL, + APP_STATUS_INDICATION_ANSWERCALL, + APP_STATUS_INDICATION_CLEARSUCCEED, + APP_STATUS_INDICATION_CLEARFAIL, + APP_STATUS_INDICATION_WARNING, + APP_STATUS_INDICATION_ALEXA_START, + APP_STATUS_INDICATION_ALEXA_STOP, + APP_STATUS_INDICATION_GSOUND_MIC_OPEN, + APP_STATUS_INDICATION_GSOUND_MIC_CLOSE, + APP_STATUS_INDICATION_GSOUND_NC, + APP_STATUS_INDICATION_INVALID, + APP_STATUS_INDICATION_MUTE, + APP_STATUS_INDICATION_TESTMODE, + APP_STATUS_INDICATION_TESTMODE1, + APP_STATUS_INDICATION_DU, + APP_STATUS_INDICATION_DUDU, + APP_STATUS_RING_WARNING, +#ifdef __INTERACTION__ + APP_STATUS_INDICATION_FINDME, +#endif + APP_STATUS_INDICATION_FIND_MY_BUDS, + APP_STATUS_INDICATION_TILE_FIND, + APP_STATUS_INDICATION_NUM +}APP_STATUS_INDICATION_T; + +const char *status2str(uint16_t status); +int app_status_indication_filter_set(APP_STATUS_INDICATION_T status); +APP_STATUS_INDICATION_T app_status_indication_get(void); +int app_status_indication_set(APP_STATUS_INDICATION_T status); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/apps/main/apps.cpp b/apps/main/apps.cpp new file mode 100644 index 0000000..24afe85 --- /dev/null +++ b/apps/main/apps.cpp @@ -0,0 +1,2847 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "stdio.h" +#include "cmsis_os.h" +#include "list.h" +#include "string.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_bootmode.h" +#include "hal_sleep.h" +#include "pmu.h" +#include "audioflinger.h" +#include "apps.h" +#include "app_thread.h" +#include "app_key.h" +#include "app_bt_media_manager.h" +#include "app_pwl.h" +#include "app_audio.h" +#include "app_overlay.h" +#include "app_battery.h" +#include "app_utils.h" +#include "app_status_ind.h" +#include "bt_drv_interface.h" +#include "besbt.h" +#include "norflash_api.h" +#include "nvrecord.h" +#include "nvrecord_dev.h" +#include "nvrecord_env.h" +#include "crash_dump_section.h" +#include "log_section.h" +#include "factory_section.h" +#include "a2dp_api.h" +#include "me_api.h" +#include "os_api.h" +#include "btapp.h" +#include "app_bt.h" +#include "bt_if.h" +#include "gapm_task.h" +#include "app_ble_include.h" +#include "app_bt_func.h" +#include "tgt_hardware.h" +#include "hal_i2c.h" +#ifdef __AI_VOICE__ +#include "app_ai_if.h" +#include "app_ai_tws.h" +#include "ai_manager.h" +#include "app_ai_manager_api.h" +#endif +#include "app_tws_ibrt_cmd_handler.h" +#include "audio_process.h" + +#ifdef __PC_CMD_UART__ +#include "app_cmd.h" +#endif + +#ifdef __FACTORY_MODE_SUPPORT__ +#include "app_factory.h" +#include "app_factory_bt.h" +#endif + +#ifdef __INTERCONNECTION__ +#include "app_interconnection.h" +#include "app_interconnection_ble.h" +#include "app_interconnection_logic_protocol.h" +#include "app_ble_mode_switch.h" +#endif + +#ifdef __INTERACTION__ +#include "app_interaction.h" +#endif + +#ifdef BISTO_ENABLED +#include "app_ai_manager_api.h" +#include "gsound_custom_reset.h" +#include "nvrecord_gsound.h" +#include "gsound_custom_actions.h" +#include "gsound_custom_ota.h" +#endif + +#ifdef IBRT_OTA +#include "ota_bes.h" +#endif + +#ifdef MEDIA_PLAYER_SUPPORT +#include "resources.h" +#include "app_media_player.h" +#endif + +#ifdef VOICE_DATAPATH +#include "app_voicepath.h" +#endif + +#ifdef BT_USB_AUDIO_DUAL_MODE +#include "btusb_audio.h" +#include "usbaudio_thread.h" +#endif + +#ifdef TILE_DATAPATH +#include "tile_target_ble.h" +#endif + +#if defined(IBRT) +#include "app_ibrt_if.h" +#include "app_ibrt_customif_ui.h" +#include "app_ibrt_ui_test.h" +#include "app_ibrt_voice_report.h" +#include "app_tws_if.h" +#include "app_ibrt_customif_cmd.h" +#endif + +#ifdef GFPS_ENABLED +#include "app_gfps.h" +#endif + +#ifdef BTIF_BLE_APP_DATAPATH_SERVER +#include "app_ble_cmd_handler.h" +#endif + +#ifdef ANC_APP +#include "app_anc.h" +#endif + +#ifdef __THIRDPARTY +#include "app_thirdparty.h" +#endif + +#ifdef OTA_ENABLED +#include "nvrecord_ota.h" +#include "ota_common.h" +#endif + +#ifdef AUDIO_DEBUG_V0_1_0 +extern "C" int speech_tuning_init(void); +#endif + +#if (defined(BTUSB_AUDIO_MODE) || defined(BT_USB_AUDIO_DUAL_MODE)) +extern "C" bool app_usbaudio_mode_on(void) ; +#endif + +#ifdef BES_OTA_BASIC +extern "C" void ota_flash_init(void); +#endif + +#define APP_BATTERY_LEVEL_LOWPOWERTHRESHOLD (1) +#define POWERON_PRESSMAXTIME_THRESHOLD_MS (5000) + +#ifdef FPGA +uint32_t __ota_upgrade_log_start[100]; +#endif + +enum APP_POWERON_CASE_T { + APP_POWERON_CASE_NORMAL = 0, + APP_POWERON_CASE_DITHERING, + APP_POWERON_CASE_REBOOT, + APP_POWERON_CASE_ALARM, + APP_POWERON_CASE_CALIB, + APP_POWERON_CASE_BOTHSCAN, + APP_POWERON_CASE_CHARGING, + APP_POWERON_CASE_FACTORY, + APP_POWERON_CASE_TEST, + APP_POWERON_CASE_LINKLOSE_REBOOT, + APP_POWERON_CASE_INVALID, + + APP_POWERON_CASE_NUM +}; + +#ifdef RB_CODEC +extern int rb_ctl_init(); +extern bool rb_ctl_is_init_done(void); +extern void app_rbplay_audio_reset_pause_status(void); +#endif + +#ifdef __SUPPORT_ANC_SINGLE_MODE_WITHOUT_BT__ +extern bool app_pwr_key_monitor_get_val(void); +static bool anc_single_mode_on = false; +extern "C" bool anc_single_mode_is_on(void) +{ + return anc_single_mode_on; +} +#endif + +#ifdef __ANC_STICK_SWITCH_USE_GPIO__ +extern bool app_anc_switch_get_val(void); +#endif + +#ifdef GFPS_ENABLED +extern "C" void app_fast_pairing_timeout_timehandler(void); +#endif + +uint8_t app_poweroff_flag = 0; +static enum APP_POWERON_CASE_T g_pwron_case = APP_POWERON_CASE_INVALID; + +#ifndef APP_TEST_MODE +static uint8_t app_status_indication_init(void) +{ + struct APP_PWL_CFG_T cfg; + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)cfg_hw_pinmux_pwl, sizeof(cfg_hw_pinmux_pwl)/sizeof(struct HAL_IOMUX_PIN_FUNCTION_MAP)); + memset(&cfg, 0, sizeof(struct APP_PWL_CFG_T)); + app_pwl_open(); + app_pwl_setup(APP_PWL_ID_0, &cfg); + app_pwl_setup(APP_PWL_ID_1, &cfg); + return 0; +} +#endif + +#if defined(__BTIF_EARPHONE__) && defined(__BTIF_AUTOPOWEROFF__) + +void PairingTransferToConnectable(void); + +typedef void (*APP_10_SECOND_TIMER_CB_T)(void); + +void app_pair_timerout(void); +void app_poweroff_timerout(void); +void CloseEarphone(void); + +typedef struct +{ + uint8_t timer_id; + uint8_t timer_en; + uint8_t timer_count; + uint8_t timer_period; + APP_10_SECOND_TIMER_CB_T cb; +}APP_10_SECOND_TIMER_STRUCT; + +#define INIT_APP_TIMER(_id, _en, _count, _period, _cb) \ + { \ + .timer_id = _id, \ + .timer_en = _en, \ + .timer_count = _count, \ + .timer_period = _period, \ + .cb = _cb, \ + } + +APP_10_SECOND_TIMER_STRUCT app_10_second_array[] = +{ + INIT_APP_TIMER(APP_PAIR_TIMER_ID, 0, 0, 6, PairingTransferToConnectable), + INIT_APP_TIMER(APP_POWEROFF_TIMER_ID, 0, 0, 90, CloseEarphone), +#ifdef GFPS_ENABLED + INIT_APP_TIMER(APP_FASTPAIR_LASTING_TIMER_ID, 0, 0, APP_FAST_PAIRING_TIMEOUT_IN_SECOND/10, + app_fast_pairing_timeout_timehandler), +#endif +}; + +void app_stop_10_second_timer(uint8_t timer_id) +{ + APP_10_SECOND_TIMER_STRUCT *timer = &app_10_second_array[timer_id]; + + timer->timer_en = 0; + timer->timer_count = 0; +} + +void app_start_10_second_timer(uint8_t timer_id) +{ + APP_10_SECOND_TIMER_STRUCT *timer = &app_10_second_array[timer_id]; + + timer->timer_en = 0; + timer->timer_count = 0; +} + +void app_set_10_second_timer(uint8_t timer_id, uint8_t enable, uint8_t period) +{ + APP_10_SECOND_TIMER_STRUCT *timer = &app_10_second_array[timer_id]; + + timer->timer_en = enable; + timer->timer_count = period; +} + +void app_10_second_timer_check(void) +{ + APP_10_SECOND_TIMER_STRUCT *timer = app_10_second_array; + unsigned int i; + + for(i = 0; i < ARRAY_SIZE(app_10_second_array); i++) { + if (timer->timer_en) { + timer->timer_count++; + if (timer->timer_count >= timer->timer_period) { + timer->timer_en = 0; + if (timer->cb) + timer->cb(); + } + } + timer++; + } +} + +void CloseEarphone(void) +{ + int activeCons; + osapi_lock_stack(); + activeCons = btif_me_get_activeCons(); + osapi_unlock_stack(); + +#ifdef ANC_APP + if(app_anc_work_status()) { + app_set_10_second_timer(APP_POWEROFF_TIMER_ID, 1, 30); + return; + } +#endif /* ANC_APP */ + if(activeCons == 0) { + TRACE(0,"!!!CloseEarphone\n"); + app_shutdown(); + } +} +#endif /* #if defined(__BTIF_EARPHONE__) && defined(__BTIF_AUTOPOWEROFF__) */ + +int signal_send_to_main_thread(uint32_t signals); +uint8_t stack_ready_flag = 0; +void app_notify_stack_ready(uint8_t ready_flag) +{ + TRACE(2,"app_notify_stack_ready %d %d", stack_ready_flag, ready_flag); + + stack_ready_flag |= ready_flag; + +#ifdef __IAG_BLE_INCLUDE__ + if(stack_ready_flag == (STACK_READY_BT|STACK_READY_BLE)) +#endif + { + signal_send_to_main_thread(0x3); + } +} + +bool app_is_stack_ready(void) +{ + bool ret = false; + + if (stack_ready_flag == (STACK_READY_BT +#ifdef __IAG_BLE_INCLUDE__ + | STACK_READY_BLE +#endif + )) + { + ret = true; + } + + return ret; +} + +static void app_stack_ready_cb(void) +{ + TRACE(0,"stack init done"); +#ifdef BLE_ENABLE + app_ble_stub_user_init(); + app_ble_start_connectable_adv(BLE_ADVERTISING_INTERVAL); +#endif +} + +//#if (HF_CUSTOM_FEATURE_SUPPORT & HF_CUSTOM_FEATURE_BATTERY_REPORT) || (HF_SDK_FEATURES & HF_FEATURE_HF_INDICATORS) +#if defined(SUPPORT_BATTERY_REPORT) || defined(SUPPORT_HF_INDICATORS) +extern void app_hfp_set_battery_level(uint8_t level); +#endif + +int app_status_battery_report(uint8_t level) +{ +#ifdef __SUPPORT_ANC_SINGLE_MODE_WITHOUT_BT__ + if (anc_single_mode_on) //anc power on,anc only mode + return 0; +#endif +#if defined(__BTIF_EARPHONE__) + if (app_is_stack_ready()) + { + app_bt_state_checker(); + } + app_10_second_timer_check(); +#endif + if (level <= APP_BATTERY_LEVEL_LOWPOWERTHRESHOLD) + { + //add something + } + + if (app_is_stack_ready()) + { +// #if (HF_CUSTOM_FEATURE_SUPPORT & HF_CUSTOM_FEATURE_BATTERY_REPORT) || (HF_SDK_FEATURES & HF_FEATURE_HF_INDICATORS) +#if defined(SUPPORT_BATTERY_REPORT) || defined(SUPPORT_HF_INDICATORS) +#if defined(IBRT) + if (app_tws_ibrt_mobile_link_connected()) + { + app_hfp_set_battery_level(level); + } +#else + app_hfp_set_battery_level(level); +#endif +#else + TRACE(1,"[%s] Can not enable SUPPORT_BATTERY_REPORT", __func__); +#endif + osapi_notify_evm(); + } + return 0; +} + +void stopAuto_Shutdowm_Timer(void); +void app_bt_power_off_customize() +{ +#if(TWS_Sync_Shutdowm) + app_ibrt_poweroff_notify_force(); +#endif + app_shutdown(); +} + +#ifdef MEDIA_PLAYER_SUPPORT + +void app_status_set_num(const char* p) +{ + media_Set_IncomingNumber(p); +} + +static u8 last_voice_waring = APP_STATUS_INDICATION_NUM; +int app_voice_report_handler(APP_STATUS_INDICATION_T status, uint8_t device_id, uint8_t isMerging) +{ +#if (defined(BTUSB_AUDIO_MODE) || defined(BT_USB_AUDIO_DUAL_MODE)) + if(app_usbaudio_mode_on()) return 0; +#endif + TRACE(3,"%s %d",__func__, status); + AUD_ID_ENUM id = MAX_RECORD_NUM; +#ifdef __SUPPORT_ANC_SINGLE_MODE_WITHOUT_BT__ + if(anc_single_mode_on) + return 0; +#endif +if(((last_voice_waring == APP_STATUS_INDICATION_POWERON)&&(status == APP_STATUS_INDICATION_POWERON))|| + ((last_voice_waring == APP_STATUS_INDICATION_BOTHSCAN)&&(status == APP_STATUS_INDICATION_BOTHSCAN))|| + ((last_voice_waring == APP_STATUS_INDICATION_BOTHSCAN)&&(status == APP_STATUS_INDICATION_DISCONNECTED))){ + last_voice_waring = status; + return 0; + } + if (app_poweroff_flag == 1){ + switch (status) { + case APP_STATUS_INDICATION_POWEROFF: + id = AUD_ID_POWER_OFF; + break; + default: + return 0; + break; + } + }else{ + switch (status) { + case APP_STATUS_INDICATION_POWERON: + id = AUD_ID_POWER_ON; + break; + case APP_STATUS_INDICATION_POWEROFF: + id = AUD_ID_POWER_OFF; + break; + case APP_STATUS_INDICATION_CONNECTED: + id = AUD_ID_BT_CONNECTED; + break; + case APP_STATUS_INDICATION_DISCONNECTED: + id = AUD_ID_BT_DIS_CONNECT; + break; + case APP_STATUS_INDICATION_CALLNUMBER: + id = AUD_ID_BT_CALL_INCOMING_NUMBER; + break; + case APP_STATUS_INDICATION_CHARGENEED: + id = AUD_ID_BT_CHARGE_PLEASE; + break; + case APP_STATUS_INDICATION_FULLCHARGE: + id = AUD_ID_BT_CHARGE_FINISH; + break; + case APP_STATUS_INDICATION_PAIRSUCCEED: + id = AUD_ID_BT_PAIRING_SUC; + break; + case APP_STATUS_INDICATION_PAIRFAIL: + id = AUD_ID_BT_PAIRING_FAIL; + break; + + case APP_STATUS_INDICATION_HANGUPCALL: + id = AUD_ID_BT_CALL_HUNG_UP; + break; + + case APP_STATUS_INDICATION_REFUSECALL: + id = AUD_ID_BT_CALL_REFUSE; + isMerging = false; + break; + + case APP_STATUS_INDICATION_ANSWERCALL: + id = AUD_ID_BT_CALL_ANSWER; + break; + + case APP_STATUS_INDICATION_CLEARSUCCEED: + id = AUD_ID_BT_CLEAR_SUCCESS; + break; + + case APP_STATUS_INDICATION_CLEARFAIL: + id = AUD_ID_BT_CLEAR_FAIL; + break; + case APP_STATUS_INDICATION_INCOMINGCALL: + id = AUD_ID_BT_CALL_INCOMING_CALL; + break; + case APP_STATUS_INDICATION_BOTHSCAN: + id = AUD_ID_BT_PAIR_ENABLE; + break; + case APP_STATUS_INDICATION_WARNING: + id = AUD_ID_BT_WARNING; + break; + case APP_STATUS_INDICATION_ALEXA_START: + id = AUDIO_ID_BT_ALEXA_START; + break; + case APP_STATUS_INDICATION_ALEXA_STOP: + id = AUDIO_ID_BT_ALEXA_STOP; + break; + case APP_STATUS_INDICATION_GSOUND_MIC_OPEN: + id = AUDIO_ID_BT_GSOUND_MIC_OPEN; + break; + case APP_STATUS_INDICATION_GSOUND_MIC_CLOSE: + id = AUDIO_ID_BT_GSOUND_MIC_CLOSE; + break; + case APP_STATUS_INDICATION_GSOUND_NC: + id = AUDIO_ID_BT_GSOUND_NC; + break; +#ifdef __BT_WARNING_TONE_MERGE_INTO_STREAM_SBC__ + case APP_STATUS_RING_WARNING: + id = AUD_ID_RING_WARNING; + break; +#endif + case APP_STATUS_INDICATION_MUTE: + id = AUDIO_ID_BT_MUTE; + break; +#ifdef __INTERACTION__ + case APP_STATUS_INDICATION_FINDME: + id = AUD_ID_BT_FINDME; + break; +#endif + case APP_STATUS_INDICATION_FIND_MY_BUDS: + id = AUDIO_ID_FIND_MY_BUDS; + break; + case APP_STATUS_INDICATION_TILE_FIND: + id = AUDIO_ID_FIND_TILE; + break; + case APP_STATUS_INDICATION_DUDU: + id = AUDIO_ID_BT_DUDU; + break; + case APP_STATUS_INDICATION_DU: + id = AUDIO_ID_BT_DU; + break; + default: + break; + } + } + + uint16_t aud_pram = 0; + if (isMerging){ + aud_pram |= PROMOT_ID_BIT_MASK_MERGING; + } +#ifdef BT_USB_AUDIO_DUAL_MODE + if(!btusb_is_usb_mode()) + { +#if defined(IBRT) + app_ibrt_if_voice_report_handler(id, aud_pram); +#else + trigger_media_play(id, device_id, aud_pram); +#endif + } + +#else +#if defined(IBRT) + aud_pram |= PROMOT_ID_BIT_MASK_CHNLSEl_ALL; + app_ibrt_if_voice_report_handler(id, aud_pram); +#else + trigger_media_play(id, device_id, aud_pram); +#endif +#endif + + return 0; +} + +extern "C" int app_voice_report(APP_STATUS_INDICATION_T status, uint8_t device_id) +{ + return app_voice_report_handler(status, device_id, true); +} + +extern "C" int app_voice_report_generic(APP_STATUS_INDICATION_T status, uint8_t device_id, uint8_t isMerging) +{ + return app_voice_report_handler(status, device_id, isMerging); +} + +extern "C" int app_voice_stop(APP_STATUS_INDICATION_T status, uint8_t device_id) +{ + AUD_ID_ENUM id = MAX_RECORD_NUM; + + TRACE(2,"%s %d", __func__, status); + + if (status == APP_STATUS_INDICATION_FIND_MY_BUDS) + id = AUDIO_ID_FIND_MY_BUDS; + + if (id != MAX_RECORD_NUM) + trigger_media_stop(id, device_id); + + return 0; +} + +#endif +/* +static void app_poweron_normal(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + g_pwron_case = APP_POWERON_CASE_NORMAL; + + signal_send_to_main_thread(0x2); +} +*/ +#if 0//!defined(BLE_ONLY_ENABLED) +static void app_poweron_scan(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + g_pwron_case = APP_POWERON_CASE_BOTHSCAN; + + signal_send_to_main_thread(0x2); +} +#endif + +#if 0//def __ENGINEER_MODE_SUPPORT__ +#if !defined(BLE_ONLY_ENABLED) +static void app_poweron_factorymode(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_REBOOT); + app_factorymode_enter(); +} +#endif +#endif + +#ifndef __POWERKEY_CTRL_ONOFF_ONLY__ +static bool g_pwron_finished = false; +static void app_poweron_finished(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + g_pwron_finished = true; + signal_send_to_main_thread(0x2); +} +#endif + +void app_poweron_wait_finished(void) +{ +#ifndef __POWERKEY_CTRL_ONOFF_ONLY__ + if (!g_pwron_finished) +#endif + { + osSignalWait(0x2, osWaitForever); + } +} + +#if defined(__POWERKEY_CTRL_ONOFF_ONLY__) +void app_bt_key_shutdown(APP_KEY_STATUS *status, void *param); +const APP_KEY_HANDLE pwron_key_handle_cfg[] = { + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_UP}, "power on: shutdown" , app_bt_key_shutdown, NULL}, +}; +#elif defined(__ENGINEER_MODE_SUPPORT__) +const APP_KEY_HANDLE pwron_key_handle_cfg[] = { + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITUP}, "power on: normal" , app_poweron_normal, NULL}, +#if !defined(BLE_ONLY_ENABLED) + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITLONGPRESS}, "power on: both scan" , app_poweron_scan , NULL}, +// {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITLONGLONGPRESS},"power on: factory mode", app_poweron_factorymode , NULL}, +#endif + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITFINISHED}, "power on: finished" , app_poweron_finished , NULL}, +}; +#else +const APP_KEY_HANDLE pwron_key_handle_cfg[] = { + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITUP}, "power on: normal" , app_poweron_normal, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITLONGPRESS}, "power on: both scan" , app_poweron_scan , NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_INITFINISHED}, "power on: finished" , app_poweron_finished , NULL}, +}; +#endif + +#ifndef APP_TEST_MODE +static void app_poweron_key_init(void) +{ + uint8_t i = 0; + TRACE(1,"%s",__func__); + + for (i=0; i<(sizeof(pwron_key_handle_cfg)/sizeof(APP_KEY_HANDLE)); i++){ + app_key_handle_registration(&pwron_key_handle_cfg[i]); + } +} + +static uint8_t app_poweron_wait_case(void) +{ +// uint32_t stime = 0, etime = 0; + +#ifdef __POWERKEY_CTRL_ONOFF_ONLY__ + g_pwron_case = APP_POWERON_CASE_NORMAL; +#else + TRACE(1,"poweron_wait_case enter:%d", g_pwron_case); + if (g_pwron_case == APP_POWERON_CASE_INVALID){ + stime = hal_sys_timer_get(); + osSignalWait(0x2, POWERON_PRESSMAXTIME_THRESHOLD_MS); + etime = hal_sys_timer_get(); + } + TRACE(2,"powon raw case:%d time:%d", g_pwron_case, TICKS_TO_MS(etime - stime)); +#endif + return g_pwron_case; + +} +#endif + +static void app_wait_stack_ready(void) +{ + uint32_t stime, etime; + stime = hal_sys_timer_get(); + osSignalWait(0x3, 1000); + etime = hal_sys_timer_get(); + TRACE(1,"app_wait_stack_ready: wait:%d ms", TICKS_TO_MS(etime - stime)); + + app_stack_ready_cb(); +} + +extern "C" int system_shutdown(void); +int app_shutdown(void) +{ + system_shutdown(); + return 0; +} + +int system_reset(void); +int app_reset(void) +{ + system_reset(); + return 0; +} + +static void app_postponed_reset_timer_handler(void const *param); +osTimerDef(APP_POSTPONED_RESET_TIMER, app_postponed_reset_timer_handler); +static osTimerId app_postponed_reset_timer = NULL; +#define APP_RESET_PONTPONED_TIME_IN_MS 2000 +static void app_postponed_reset_timer_handler(void const *param) +{ +// hal_cmu_sys_reboot(); + app_reset(); +} + +void app_start_postponed_reset(void) +{ + if (NULL == app_postponed_reset_timer) + { + app_postponed_reset_timer = osTimerCreate(osTimer(APP_POSTPONED_RESET_TIMER), osTimerOnce, NULL); + } + + hal_sw_bootmode_set(HAL_SW_BOOTMODE_ENTER_HIDE_BOOT); + + osTimerStart(app_postponed_reset_timer, APP_RESET_PONTPONED_TIME_IN_MS); +} + +void app_bt_key_shutdown(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); +#ifdef __POWERKEY_CTRL_ONOFF_ONLY__ + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_REBOOT); + app_reset(); +#else + app_shutdown(); +#endif +} + +void app_bt_key_enter_testmode(APP_KEY_STATUS *status, void *param) +{ + TRACE(1,"%s\n",__FUNCTION__); + + if(app_status_indication_get() == APP_STATUS_INDICATION_BOTHSCAN){ +#ifdef __FACTORY_MODE_SUPPORT__ + app_factorymode_bt_signalingtest(status, param); +#endif + } +} + +void app_bt_key_enter_nosignal_mode(APP_KEY_STATUS *status, void *param) +{ + TRACE(1,"%s\n",__FUNCTION__); + if(app_status_indication_get() == APP_STATUS_INDICATION_BOTHSCAN){ +#ifdef __FACTORY_MODE_SUPPORT__ + app_factorymode_bt_nosignalingtest(status, param); +#endif + } +} + +void app_bt_singleclick(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); +} + +void app_bt_doubleclick(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); +} + +void app_power_off(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"app_power_off\n"); +} + +extern "C" void OS_NotifyEvm(void); + +#define PRESS_KEY_TO_ENTER_OTA_INTERVEL (15000) // press key 15s enter to ota +#define PRESS_KEY_TO_ENTER_OTA_REPEAT_CNT ((PRESS_KEY_TO_ENTER_OTA_INTERVEL - 2000) / 500) +void app_otaMode_enter(APP_KEY_STATUS *status, void *param) +{ + TRACE(1,"%s",__func__); + + hal_norflash_disable_protection(HAL_NORFLASH_ID_0); + + hal_sw_bootmode_set(HAL_SW_BOOTMODE_ENTER_HIDE_BOOT); +#ifdef __KMATE106__ + app_status_indication_set(APP_STATUS_INDICATION_OTA); + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); + osDelay(1200); +#endif + hal_cmu_sys_reboot(); +} + +#ifdef __USB_COMM__ +void app_usb_cdc_comm_key_handler(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d", __func__, status->code, status->event); + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_REBOOT); + hal_sw_bootmode_set(HAL_SW_BOOTMODE_CDC_COMM); + pmu_usb_config(PMU_USB_CONFIG_TYPE_DEVICE); + hal_cmu_reset_set(HAL_CMU_MOD_GLOBAL); +} +#endif + +#if 0 +void app_dfu_key_handler(APP_KEY_STATUS *status, void *param) +{ + TRACE(1,"%s ",__func__); + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_REBOOT); + hal_sw_bootmode_set(HAL_SW_BOOTMODE_FORCE_USB_DLD); + pmu_usb_config(PMU_USB_CONFIG_TYPE_DEVICE); + hal_cmu_reset_set(HAL_CMU_MOD_GLOBAL); +} +#else +void app_dfu_key_handler(APP_KEY_STATUS *status, void *param) +{ + TRACE(1,"%s ",__func__); + hal_sw_bootmode_clear(0xffffffff); + hal_sw_bootmode_set(HAL_SW_BOOTMODE_FORCE_USB_DLD | HAL_SW_BOOTMODE_SKIP_FLASH_BOOT); + pmu_usb_config(PMU_USB_CONFIG_TYPE_DEVICE); + hal_cmu_reset_set(HAL_CMU_MOD_GLOBAL); +} +#endif + +void app_ota_key_handler(APP_KEY_STATUS *status, void *param) +{ + static uint32_t time = hal_sys_timer_get(); + static uint16_t cnt = 0; + + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + + if (TICKS_TO_MS(hal_sys_timer_get() - time) > 600) // 600 = (repeat key intervel)500 + (margin)100 + cnt = 0; + else + cnt++; + + if (cnt == PRESS_KEY_TO_ENTER_OTA_REPEAT_CNT) { + app_otaMode_enter(NULL, NULL); + } + + time = hal_sys_timer_get(); +} +extern "C" void app_bt_key(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); +#define DEBUG_CODE_USE 0 + switch(status->event) + { + case APP_KEY_EVENT_CLICK: + TRACE(0,"first blood!"); +#if DEBUG_CODE_USE + if (status->code == APP_KEY_CODE_PWR) + { +#ifdef __INTERCONNECTION__ + // add favorite music + // app_interconnection_handle_favorite_music_through_ccmp(1); + + // ask for ota update + ota_update_request(); + return; +#else + static int m = 0; + if (m == 0) { + m = 1; + hal_iomux_set_analog_i2c(); + } + else { + m = 0; + hal_iomux_set_uart0(); + } +#endif + } +#endif + break; + case APP_KEY_EVENT_DOUBLECLICK: + TRACE(0,"double kill"); +#if DEBUG_CODE_USE + if (status->code == APP_KEY_CODE_PWR) + { +#ifdef __INTERCONNECTION__ + // play favorite music + app_interconnection_handle_favorite_music_through_ccmp(2); +#else + app_otaMode_enter(NULL, NULL); +#endif + return; + } +#endif + break; + case APP_KEY_EVENT_TRIPLECLICK: + TRACE(0,"triple kill"); + if (status->code == APP_KEY_CODE_PWR) + { + +#ifndef __BT_ONE_BRING_TWO__ + if(btif_me_get_activeCons() < 1){ +#else + if(btif_me_get_activeCons() < 2){ +#endif + app_bt_accessmode_set(BTIF_BT_DEFAULT_ACCESS_MODE_PAIR); +#ifdef __INTERCONNECTION__ + app_interceonnection_start_discoverable_adv(INTERCONNECTION_BLE_FAST_ADVERTISING_INTERVAL, + APP_INTERCONNECTION_FAST_ADV_TIMEOUT_IN_MS); + return; +#endif +#ifdef GFPS_ENABLED + app_enter_fastpairing_mode(); +#endif + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + } + return; + } + break; + case APP_KEY_EVENT_ULTRACLICK: + TRACE(0,"ultra kill"); + break; + case APP_KEY_EVENT_RAMPAGECLICK: + TRACE(0,"rampage kill!you are crazy!"); + break; + + case APP_KEY_EVENT_UP: + break; + } +#if 0//def __FACTORY_MODE_SUPPORT__ + if (app_status_indication_get() == APP_STATUS_INDICATION_BOTHSCAN && (status->event == APP_KEY_EVENT_DOUBLECLICK)){ + app_factorymode_languageswitch_proc(); + }else +#endif + { +#ifdef __SUPPORT_ANC_SINGLE_MODE_WITHOUT_BT__ + if(!anc_single_mode_on) +#endif + bt_key_send(status); + } +} + +#ifdef RB_CODEC +extern bool app_rbcodec_check_hfp_active(void ); +void app_switch_player_key(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + + if(!rb_ctl_is_init_done()) { + TRACE(0,"rb ctl not init done"); + return ; + } + + if( app_rbcodec_check_hfp_active() ) { + app_bt_key(status,param); + return; + } + + app_rbplay_audio_reset_pause_status(); + + if(app_rbplay_mode_switch()) { + app_voice_report(APP_STATUS_INDICATION_POWERON, 0); + app_rbcodec_ctr_play_onoff(true); + } else { + app_rbcodec_ctr_play_onoff(false); + app_voice_report(APP_STATUS_INDICATION_POWEROFF, 0); + } + return ; + +} +#endif + +void app_voice_assistant_key(APP_KEY_STATUS *status, void *param) +{ + TRACE(2,"%s event %d", __func__, status->event); +#if defined(BISTO_ENABLED) || defined(__AI_VOICE__) + if (app_ai_manager_is_in_multi_ai_mode()) + { + if (app_ai_manager_spec_get_status_is_in_invalid()) { + TRACE(0,"AI feature has been diabled"); + return; + } + +#ifdef MAI_TYPE_REBOOT_WITHOUT_OEM_APP + if (app_ai_manager_get_spec_update_flag()) { + TRACE(0,"device reboot is ongoing..."); + return; + } +#endif + + if (app_ai_manager_is_need_reboot()) + { + TRACE(1, "%s ai need to reboot", __func__); + return; + } + + if(app_ai_manager_voicekey_is_enable()) { + if (AI_SPEC_GSOUND == app_ai_manager_get_current_spec()) { +#ifdef BISTO_ENABLED + gsound_custom_actions_handle_key(status, param); +#endif + } else if(AI_SPEC_INIT != app_ai_manager_get_current_spec()) { + app_ai_key_event_handle(status, 0); + } + } + } + else + { + app_ai_key_event_handle(status, 0); +#if defined(BISTO_ENABLED) + gsound_custom_actions_handle_key(status, param); +#endif + } +#endif +} + +#ifdef IS_MULTI_AI_ENABLED +void app_voice_gva_onoff_key(APP_KEY_STATUS *status, void *param) +{ + uint8_t current_ai_spec = app_ai_manager_get_current_spec(); + + TRACE(2,"%s current_ai_spec %d", __func__, current_ai_spec); + if (current_ai_spec == AI_SPEC_INIT) + { + app_ai_manager_enable(true, AI_SPEC_GSOUND); + } + else if(current_ai_spec == AI_SPEC_GSOUND) + { + app_ai_manager_enable(false, AI_SPEC_GSOUND); + } + else if(current_ai_spec == AI_SPEC_AMA) + { + app_ai_manager_switch_spec(AI_SPEC_GSOUND); + } + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); +} + +void app_voice_ama_onoff_key(APP_KEY_STATUS *status, void *param) +{ + uint8_t current_ai_spec = app_ai_manager_get_current_spec(); + + TRACE(2,"%s current_ai_spec %d", __func__, current_ai_spec); + if (current_ai_spec == AI_SPEC_INIT) + { + app_ai_manager_enable(true, AI_SPEC_AMA); + } + else if(current_ai_spec == AI_SPEC_AMA) + { + app_ai_manager_enable(false, AI_SPEC_AMA); + } + else if(current_ai_spec == AI_SPEC_GSOUND) + { + app_ai_manager_switch_spec(AI_SPEC_AMA); + } + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); +} +#endif + +#if defined(BT_USB_AUDIO_DUAL_MODE_TEST) && defined(BT_USB_AUDIO_DUAL_MODE) +extern "C" void test_btusb_switch(void); +void app_btusb_audio_dual_mode_test(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"test_btusb_switch"); + test_btusb_switch(); +} +#endif + +extern void switch_dualmic_status(void); + +void app_switch_dualmic_key(APP_KEY_STATUS *status, void *param) +{ + switch_dualmic_status(); +} + +#ifdef POWERKEY_I2C_SWITCH +extern void app_factorymode_i2c_switch(APP_KEY_STATUS *status, void *param); +#endif + +#ifdef TILE_DATAPATH +extern "C" void app_tile_key_handler(APP_KEY_STATUS *status, void *param); +#endif + +#ifdef __POWERKEY_CTRL_ONOFF_ONLY__ +#if defined(__APP_KEY_FN_STYLE_A__) +const APP_KEY_HANDLE app_key_handle_cfg[] = { + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_UP},"bt function key",app_bt_key_shutdown, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_LONGPRESS},"bt function key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_UP},"bt function key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_DOUBLECLICK},"bt function key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_UP},"bt volume up key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_LONGPRESS},"bt play backward key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN3,APP_KEY_EVENT_UP},"bt volume down key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN3,APP_KEY_EVENT_LONGPRESS},"bt play forward key",app_bt_key, NULL}, +#ifdef SUPPORT_SIRI + {{APP_KEY_CODE_NONE ,APP_KEY_EVENT_NONE},"none function key",app_bt_key, NULL}, +#endif + +}; +#else //#elif defined(__APP_KEY_FN_STYLE_B__) +const APP_KEY_HANDLE app_key_handle_cfg[] = { + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_UP},"bt function key",app_bt_key_shutdown, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_LONGPRESS},"bt function key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_UP},"bt function key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_DOUBLECLICK},"bt function key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_REPEAT},"bt volume up key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_UP},"bt play backward key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN3,APP_KEY_EVENT_REPEAT},"bt volume down key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN3,APP_KEY_EVENT_UP},"bt play forward key",app_bt_key, NULL}, +#ifdef SUPPORT_SIRI + {{APP_KEY_CODE_NONE ,APP_KEY_EVENT_NONE},"none function key",app_bt_key, NULL}, +#endif + +}; +#endif +#else +#if defined(__APP_KEY_FN_STYLE_A__) +//-- +const APP_KEY_HANDLE app_key_handle_cfg[] = { + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_LONGLONGPRESS},"bt function key",app_bt_key_shutdown, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_LONGPRESS},"bt function key",app_bt_key, NULL}, +#if defined(BT_USB_AUDIO_DUAL_MODE_TEST) && defined(BT_USB_AUDIO_DUAL_MODE) + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"bt function key",app_bt_key, NULL}, +#ifdef RB_CODEC + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"bt function key",app_switch_player_key, NULL}, +#else + //{{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"btusb mode switch key.",app_btusb_audio_dual_mode_test, NULL}, +#endif +#endif + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_DOUBLECLICK},"bt function key",app_bt_key, NULL}, +#ifdef TILE_DATAPATH + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_TRIPLECLICK},"bt function key",app_tile_key_handler, NULL}, +#else + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_TRIPLECLICK},"bt function key",app_bt_key, NULL}, +#endif +#if RAMPAGECLICK_TEST_MODE + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_ULTRACLICK},"bt function key",app_bt_key_enter_nosignal_mode, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_RAMPAGECLICK},"bt function key",app_bt_key_enter_testmode, NULL}, +#endif +#ifdef POWERKEY_I2C_SWITCH + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_RAMPAGECLICK},"bt i2c key",app_factorymode_i2c_switch, NULL}, +#endif + //{{APP_KEY_CODE_FN1,APP_KEY_EVENT_UP},"bt volume up key",app_bt_key, NULL}, + //{{APP_KEY_CODE_FN1,APP_KEY_EVENT_LONGPRESS},"bt play backward key",app_bt_key, NULL}, +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_DOUBLECLICK},"bt mode src snk key",app_bt_key, NULL}, +#endif + //{{APP_KEY_CODE_FN2,APP_KEY_EVENT_UP},"bt volume down key",app_bt_key, NULL}, + //{{APP_KEY_CODE_FN2,APP_KEY_EVENT_LONGPRESS},"bt play forward key",app_bt_key, NULL}, + //{{APP_KEY_CODE_FN15,APP_KEY_EVENT_UP},"bt volume down key",app_bt_key, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"bt function key",app_bt_key, NULL}, + +#ifdef SUPPORT_SIRI + {{APP_KEY_CODE_NONE ,APP_KEY_EVENT_NONE},"none function key",app_bt_key, NULL}, +#endif +#if defined( __BT_ANC_KEY__)&&defined(ANC_APP) +#if defined(IBRT) + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"bt anc key",app_anc_key, NULL}, +#else + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_CLICK},"bt anc key",app_anc_key, NULL}, +#endif +#endif +#ifdef TILE_DATAPATH + {{APP_KEY_CODE_TILE, APP_KEY_EVENT_DOWN}, "tile function key", app_tile_key_handler, NULL}, + {{APP_KEY_CODE_TILE, APP_KEY_EVENT_UP}, "tile function key", app_tile_key_handler, NULL}, +#endif + +#if defined(VOICE_DATAPATH) || defined(__AI_VOICE__) + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_FIRST_DOWN}, "google assistant key", app_voice_assistant_key, NULL}, +#if defined(IS_GSOUND_BUTTION_HANDLER_WORKAROUND_ENABLED) || defined(PUSH_AND_HOLD_ENABLED) || defined(__TENCENT_VOICE__) + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_UP}, "google assistant key", app_voice_assistant_key, NULL}, +#endif + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_UP_AFTER_LONGPRESS}, "google assistant key", app_voice_assistant_key, NULL}, + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_LONGPRESS}, "google assistant key", app_voice_assistant_key, NULL}, + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_CLICK}, "google assistant key", app_voice_assistant_key, NULL}, + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_DOUBLECLICK}, "google assistant key", app_voice_assistant_key, NULL}, +#endif +#ifdef IS_MULTI_AI_ENABLED + {{APP_KEY_CODE_FN13, APP_KEY_EVENT_CLICK}, "gva on-off key", app_voice_gva_onoff_key, NULL}, + {{APP_KEY_CODE_FN14, APP_KEY_EVENT_CLICK}, "ama on-off key", app_voice_ama_onoff_key, NULL}, +#endif +#if defined(BT_USB_AUDIO_DUAL_MODE_TEST) && defined(BT_USB_AUDIO_DUAL_MODE) + {{APP_KEY_CODE_FN15, APP_KEY_EVENT_CLICK}, "btusb mode switch key.", app_btusb_audio_dual_mode_test, NULL}, +#endif +}; +#else //#elif defined(__APP_KEY_FN_STYLE_B__) +const APP_KEY_HANDLE app_key_handle_cfg[] = { + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_LONGLONGPRESS},"bt function key",app_bt_key_shutdown, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_LONGPRESS},"bt function key",app_bt_key, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"bt function key",app_bt_key, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_DOUBLECLICK},"bt function key",app_bt_key, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_TRIPLECLICK},"bt function key",app_bt_key, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_ULTRACLICK},"bt function key",app_bt_key_enter_nosignal_mode, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_RAMPAGECLICK},"bt function key",app_bt_key_enter_testmode, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_REPEAT},"bt volume up key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_UP},"bt play backward key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_REPEAT},"bt volume down key",app_bt_key, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_UP},"bt play forward key",app_bt_key, NULL}, +#ifdef SUPPORT_SIRI + {{APP_KEY_CODE_NONE ,APP_KEY_EVENT_NONE},"none function key",app_bt_key, NULL}, +#endif + + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_FIRST_DOWN}, "google assistant key", app_voice_assistant_key, NULL}, +#if defined(IS_GSOUND_BUTTION_HANDLER_WORKAROUND_ENABLED) || defined(PUSH_AND_HOLD_ENABLED) + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_UP}, "google assistant key", app_voice_assistant_key, NULL}, +#endif + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_UP_AFTER_LONGPRESS}, "google assistant key", app_voice_assistant_key, NULL}, + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_LONGPRESS}, "google assistant key", app_voice_assistant_key, NULL}, + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_CLICK}, "google assistant key", app_voice_assistant_key, NULL}, + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_DOUBLECLICK}, "google assistant key", app_voice_assistant_key, NULL}, +}; +#endif +#endif + +extern struct BT_DEVICE_T app_bt_device; +extern uint8_t avrcp_get_media_status(void); +/******************************delay_report_tone_timer*********************************************************/ +APP_STATUS_INDICATION_T delay_report_tone_num = APP_STATUS_INDICATION_NUM; +osTimerId delay_report_toneid = NULL; +void startdelay_report_tone(int ms,APP_STATUS_INDICATION_T status); +void stopdelay_report_tone(void); +static void delay_report_tonefun(const void *); +osTimerDef(defdelay_report_tone,delay_report_tonefun); +void delay_report_toneinit(void) +{ + delay_report_toneid = osTimerCreate(osTimer(defdelay_report_tone),osTimerOnce,(void *)0); +} +static void delay_report_tonefun(const void *) +{ + TRACE(3,"\n\n!!!!!!enter %s,delay_report_tone_num = %d \n\n",__func__,delay_report_tone_num); + if(MobileLinkLose_reboot){ + return; + } + //static ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + //uint8_t default_mobileaddr[6] = {0x0,0x0,0x0,0x0,0x0,0x0}; + //DUMP8("%02x ", p_ibrt_ctrl->mobile_addr.address, 6); + //app_status_indication_set(APP_STATUS_INDICATION_TWS_CONNECTED); + if(Curr_Is_Master()){ + app_ibrt_sync_volume_info(); + } + if(delay_report_tone_num == APP_STATUS_INDICATION_DUDU){ + if(Curr_Is_Master()&&(avrcp_get_media_status() != 1)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)){ + app_voice_report(delay_report_tone_num,0); + /*if((!memcmp(default_mobileaddr,p_ibrt_ctrl->mobile_addr.address,6))&&(p_ibrt_ctrl->access_mode == 0x3)){ + TRACE(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + }*/ + if((nv_record_get_paired_dev_count()==1)){ + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + } + } + } + delay_report_tone_num = APP_STATUS_INDICATION_NUM; +} + +void startdelay_report_tone(int ms,APP_STATUS_INDICATION_T status) +{ + TRACE(3,"\n\n !!!!!!!!!!start %s\n\n",__func__); + delay_report_tone_num = status; + osTimerStart(delay_report_toneid,ms); +} + +/********************************delay_report_tone_timer*******************************************************/ + +/******************************low_latlatency_delay_switch_timer*********************************************************/ +uint8_t latency_mode_is_open = false; + +osTimerId low_latlatency_delay_switchid = NULL; +void startlow_latlatency_delay_switch(int ms); +void stoplow_latlatency_delay_switch(void); +static void low_latlatency_delay_switchfun(const void *); +osTimerDef(deflow_latlatency_delay_switch,low_latlatency_delay_switchfun); +void low_latlatency_delay_switchinit(void) +{ + low_latlatency_delay_switchid = osTimerCreate(osTimer(deflow_latlatency_delay_switch),osTimerOnce,(void *)0); +} + +void app_ibrt_ui_test_mtu_change_sync_notify(void) +{ + extern volatile uint8_t avdtp_playback_delay_sbc_mtu; + extern volatile uint8_t avdtp_playback_delay_aac_mtu; + + TRACE(3,"SWITC GAME MODE !!!latency_mode_is_open = %d###",latency_mode_is_open); + if(!latency_mode_is_open) + { + avdtp_playback_delay_sbc_mtu = 32; + avdtp_playback_delay_aac_mtu = 3; + app_ibrt_if_force_audio_retrigger_slave_sync(); + } + else + { + avdtp_playback_delay_sbc_mtu = 50; + avdtp_playback_delay_aac_mtu = 6; + app_ibrt_if_force_audio_retrigger_slave_sync(); + } + latency_mode_is_open = !latency_mode_is_open; + TRACE(3,"set SBC_MTU=%d AAC_MTU=%d\n", avdtp_playback_delay_sbc_mtu, avdtp_playback_delay_aac_mtu); +} + +static void low_latlatency_delay_switchfun(const void *) +{ + extern volatile uint8_t avdtp_playback_delay_sbc_mtu; + extern volatile uint8_t avdtp_playback_delay_aac_mtu; + + latency_mode_is_open = !latency_mode_is_open; + if(latency_mode_is_open){ + avdtp_playback_delay_sbc_mtu = 32; + avdtp_playback_delay_aac_mtu = 3; + TRACE(3,"%s latency_mode_is_open!!",__func__); + }else{ + avdtp_playback_delay_sbc_mtu = 50; + avdtp_playback_delay_aac_mtu = 6; + TRACE(3,"%s latency_mode_is_close!!",__func__); + } + app_ibrt_if_force_audio_retrigger(); + app_ibrt_customif_test3_cmd_send(&latency_mode_is_open,1); +} + +void startlow_latlatency_delay_switch(int ms) +{ + osTimerStart(low_latlatency_delay_switchid,ms); +} + +void stoplow_latlatency_delay_switch(void) +{ + osTimerStop(low_latlatency_delay_switchid); + +} + + + +/********************************low_latlatency_delay_switch_timer*******************************************************/ + + + +void app_latency_switch_key_handler(void) +{ + + if((btif_me_get_activeCons() > 0)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)) + { + if(latency_mode_is_open){ + app_voice_report(APP_STATUS_INDICATION_ALEXA_STOP,0);//close latlatency mode + }else{ + app_voice_report(APP_STATUS_INDICATION_ALEXA_START,0);//close latlatency mode + } + startlow_latlatency_delay_switch(1500); + } +} + +void app_key_init(void) +{ +#if defined(IBRT) + app_ibrt_ui_test_key_init(); +#else + uint8_t i = 0; + TRACE(1,"%s",__func__); + + app_key_handle_clear(); + for (i=0; i<(sizeof(app_key_handle_cfg)/sizeof(APP_KEY_HANDLE)); i++){ + app_key_handle_registration(&app_key_handle_cfg[i]); + } +#endif +} + +void app_key_init_on_charging(void) +{ + uint8_t i = 0; + const APP_KEY_HANDLE key_cfg[] = { + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_REPEAT},"ota function key",app_ota_key_handler, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"bt function key",app_dfu_key_handler, NULL}, +#ifdef __USB_COMM__ + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_LONGPRESS},"usb cdc key",app_usb_cdc_comm_key_handler, NULL}, +#endif + }; + + TRACE(1,"%s",__func__); + for (i=0; i<(sizeof(key_cfg)/sizeof(APP_KEY_HANDLE)); i++){ + app_key_handle_registration(&key_cfg[i]); + } +} + +void stopAuto_Shutdowm_Timer(void); + +bool MobileLinkLose_reboot = false; +bool IsMobileLinkLossing = FALSE; +bool IsTwsLinkLossing = FALSE; +bool enterpairing_flag = false; +bool IsTwsLinkdiscon = false; +bool reconnect_fail_fail_flag= false; +static void app_enterpairing_timehandler(void const *param); +osTimerDef (APP_ENTERPAIRING_TIMER, app_enterpairing_timehandler); +static osTimerId enterpairing_timer = NULL; +static void app_enterpairing_timehandler(void const *param) +{ + static ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + static app_ibrt_ui_t *p_ui_ctrl = app_ibrt_ui_get_ctx(); + TRACE(3,"xqd log --%s\n", __func__); + TRACE(3,"MyLog: is_tws_con = %d, nv_role = 0x%x", app_tws_ibrt_tws_link_connected(), p_ibrt_ctrl->nv_role); + reconnect_fail_fail_flag = true; + enterpairing_flag = false; + if(IsMobileLinkLossing) + { + TRACE(3,"xqd---log:return evt 0!!!\n"); + return; + } + if(p_ui_ctrl->box_state == IBRT_IN_BOX_CLOSED){ + TRACE(3,"xqd---log:return evt 1!!!\n"); + return; + } + if((app_battery_is_charging())||((app_device_bt_is_connected())&&(app_tws_ibrt_mobile_link_connected())&&(app_tws_ibrt_mobile_link_connected())))return; + + if (app_tws_ibrt_mobile_link_connected() || app_tws_ibrt_slave_ibrt_link_connected()) { + TRACE(3,"xqd---log:return evt 2!!!\n"); + return; + } + + if (app_ibrt_ui_get_enter_pairing_mode()) { + TRACE(3,"xqd---log:return evt 3!!!\n"); + if((IBRT_UNKNOW != p_ibrt_ctrl->nv_role)&&(nv_record_get_paired_dev_count()>=2)){ + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + } + app_status_indication_set(APP_STATUS_INDICATION_BOTHSCAN); + return; + } + + if(app_tws_ibrt_tws_link_connected() && (p_ibrt_ctrl->current_role == IBRT_MASTER)) + { + TRACE(3,"xqd---log:return evt 4!!!\n"); + + //p_ui_ctrl->config.enter_pairing_on_reconnect_mobile_failed = true; + //p_ui_ctrl->config.nv_slave_enter_pairing_on_mobile_disconnect = true; + //app_ibrt_if_enter_freeman_pairing(); + //app_ibrt_if_enter_pairing_after_tws_connected(); + app_ibrt_ui_set_enter_pairing_mode(IBRT_CONNECT_MOBILE_FAILED); + app_ibrt_ui_judge_scan_type(IBRT_CONNECTE_TRIGGER,MOBILE_LINK, 0); + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + } + else if ((!app_tws_ibrt_tws_link_connected()) && (p_ibrt_ctrl->nv_role == IBRT_MASTER)&&(p_ibrt_ctrl->access_mode != 0x3)) + { + TRACE(3,"xqd---log:return evt 5!!!\n"); + app_ibrt_ui_set_enter_pairing_mode(IBRT_CONNECT_MOBILE_FAILED); + app_ibrt_ui_judge_scan_type(IBRT_CONNECTE_TRIGGER,MOBILE_LINK, 0); + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + } + else if((!app_tws_ibrt_tws_link_connected()) && (p_ibrt_ctrl->nv_role == IBRT_SLAVE)) + { + app_ibrt_ui_set_enter_pairing_mode(IBRT_CONNECT_MOBILE_FAILED); + app_ibrt_ui_judge_scan_type(IBRT_CONNECTE_TRIGGER, MOBILE_LINK, 0); + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + } + +} +void app_enterpairing_timer_start(void) +{ + static ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TRACE(3,"xqd log --app_enterpairing_timer_start, enterpairing_flag = %d,nv_role = %d\n", enterpairing_flag,p_ibrt_ctrl->nv_role); + if(p_ibrt_ctrl->nv_role == IBRT_UNKNOW)return; + + enterpairing_flag = true; + + osTimerStop(enterpairing_timer); + osTimerStart(enterpairing_timer, 11000); +} +void app_enterpairing_timer_stop(void) +{ + TRACE(3,"xqd log --app_enterpairing_timer_stop\n"); + if(enterpairing_flag) + osTimerStop(enterpairing_timer); +} +void app_enterpairing_timer_open(void) +{ + if(NULL == enterpairing_timer) + { + enterpairing_timer = osTimerCreate (osTimer(APP_ENTERPAIRING_TIMER), osTimerOnce, (void *)0); + } + +} +extern bool IsMobileLinkLossing; +extern bool IsTwsLinkLossing; +bool LINKLOSE_REBOOT_ENABLE = false; + +osTimerId Auto_Shutdowm_Timerid = NULL; +void startAuto_Shutdowm_Timer(int ms); + +static void Auto_Shutdowm_Timerfun(const void *); +osTimerDef(defAuto_Shutdowm_Timer,Auto_Shutdowm_Timerfun); +void Auto_Shutdowm_Timerinit(void) +{ + Auto_Shutdowm_Timerid = osTimerCreate(osTimer(defAuto_Shutdowm_Timer),osTimerPeriodic,(void *)0); + startAuto_Shutdowm_Timer(5000); +} +extern struct btdevice_volume *btdevice_volume_p; + +static void Auto_Shutdowm_Timerfun(const void *) +{ + static uint32_t auto_shutdown_cnt = 0; + static ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + static app_ibrt_ui_t *p_ui_ctrl = app_ibrt_ui_get_ctx(); + struct nvrecord_env_t *nvrecord_env; + nv_record_env_get(&nvrecord_env); + static uint8_t trace_cnt = 0; + APP_BATTERY_MV_T currvolt =0; + //static uint8_t charge_full_timeout_cnt = 0; + trace_cnt ++; + if(trace_cnt >= 2){ + trace_cnt = 0; + /* + TRACE(0,"xqd---log:curr_role = %d,nv_role = %d,box_state = %d,access_mode = %d,channel = %d",p_ibrt_ctrl->current_role,p_ibrt_ctrl->nv_role,p_ui_ctrl->box_state,p_ibrt_ctrl->access_mode,tgt_tws_get_channel_is_right()); + TRACE(0,"curr_avrcp_status = %d£¬localbat = %d,slave_bat = %d",avrcp_get_media_status(),p_ibrt_ctrl->local_battery_volt,p_ibrt_ctrl->peer_battery_volt); + TRACE(0,"a2dp vol : %d", btdevice_volume_p->a2dp_vol); + // TRACE(0,"hfp vol: %d", btdevice_volume_p->hfp_vol); + TRACE(0,"qxw---nv_ibrt_mode addr:"); + DUMP8("0x%x ", nvrecord_env->ibrt_mode.record.bdAddr.address, 6); + TRACE(0,"qxw---peer addr:"); + DUMP8("%02x ", p_ibrt_ctrl->peer_addr.address, 6); + TRACE(0,"qxw---local addr:"); + DUMP8("%02x ", p_ibrt_ctrl->local_addr.address, 6); + TRACE(0,"qxw---nv_master addr:"); + DUMP8("%02x ", nvrecord_env->master_bdaddr.address, 6); + TRACE(0,"qxw---nv_slave addr:"); + DUMP8("%02x ", nvrecord_env->slave_bdaddr.address, 6);*/ + //TRACE(2,"charge_gpio statu:%d,chargefull_gpio statu:%d,curr_charge status = %d!",hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)cfg_hw_charge_indication_cfg.pin),hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)cfg_hw_charge_full_indication_cfg.pin),app_battery_is_charging()); + } + + //TRACE(3,"GIOI25 = %d,charge sta = %d!!!!!",hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)app_battery_charger_full_indicator_cfg.pin),app_battery_is_charging()); + if(app_battery_is_charging()){ + if((p_ui_ctrl->box_state != IBRT_IN_BOX_CLOSED)){ + app_ibrt_ui_event_entry(IBRT_CLOSE_BOX_EVENT); + } + } + app_battery_get_info(&currvolt, NULL, NULL); + if(p_ui_ctrl->box_state == IBRT_OUT_BOX){ + if(app_device_bt_is_connected()) + { + IsMobileLinkLossing = FALSE; + IsTwsLinkLossing = FALSE; + MobileLinkLose_reboot = FALSE; + } + if((!app_device_bt_is_connected())&& p_ibrt_ctrl->current_role != BTIF_BCR_SLAVE) + { + auto_shutdown_cnt++; + if(auto_shutdown_cnt == Auto_Shutdowm_TIME/5) + { + TRACE(0,"xqd---shutdown!!@@@@@@!!"); + auto_shutdown_cnt = 0; + app_bt_power_off_customize(); + } + } + else + { + auto_shutdown_cnt = 0; + } + /*if((auto_shutdown_cnt % 4 == 0)&&(MobileLinkLose_reboot)&&(!app_qxw_bt_is_connected())&&(p_ibrt_ctrl->current_role != BTIF_BCR_SLAVE)){ + app_ibrt_if_event_entry(IBRT_PHONE_CONNECT_EVENT); + }*/ + }else{ + auto_shutdown_cnt = 0; + } + +#if(QXW_TOUCH_INEAR_DET) + last_tws_con_status = app_tws_ibrt_tws_link_connected(); +#endif +} + +void startAuto_Shutdowm_Timer(int ms) +{ + osTimerStart(Auto_Shutdowm_Timerid,ms); +} +void stopAuto_Shutdowm_Timer(void) +{ + TRACE(0,"%s",__func__); + osTimerStop(Auto_Shutdowm_Timerid); +} + +/********************************Auto_Shutdowm_Timer_timer*******************************************************/ +extern void touch_reset(void); +/*******************************once_delay_event_Timer__timer*********************************************************/ +uint8_t once_event_case = 0; +osTimerId once_delay_event_Timer_id = NULL; +void startonce_delay_event_Timer_(int ms); +void stoponce_delay_event_Timer_(void); +static void once_delay_event_Timer_fun(const void *); +osTimerDef(defonce_delay_event_Timer_,once_delay_event_Timer_fun); +void once_delay_event_Timer_init(void) +{ + TRACE(3,"%s",__func__); + once_delay_event_Timer_id = osTimerCreate(osTimer(defonce_delay_event_Timer_),osTimerOnce,(void *)0); +} +static void once_delay_event_Timer_fun(const void *) +{ + static ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if((p_ibrt_ctrl->current_role == IBRT_SLAVE)) + { + once_event_case = 0; + TRACE(3,"delay_report_tonefun RETURN!!!"); + return; + } + TRACE(3,"\n\n!!!!!!enter %s,mobile_link = %d,event = %d\n\n",__func__,app_tws_ibrt_mobile_link_connected(),once_event_case); + switch(once_event_case) + { + case 1: + if(/*(avrcp_get_media_status() != 1)&&*/(app_bt_device.a2dp_state[BT_DEVICE_ID_1] == 1)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == 0)&& + (p_ibrt_ctrl->current_role == IBRT_MASTER)) + app_voice_report(APP_STATUS_INDICATION_CONNECTED,0); + break; + case 2: + if((IsMobileLinkLossing || app_device_bt_is_connected()))break; + app_voice_report(APP_STATUS_INDICATION_DISCONNECTED,0); + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + app_status_indication_set(APP_STATUS_INDICATION_BOTHSCAN); + //once_event_case = 3; + // startonce_delay_event_Timer_(2000); + break; + case 3: + if(IsMobileLinkLossing) + { + return; + } + if((app_device_bt_is_connected()))return; + app_status_indication_set(APP_STATUS_INDICATION_BOTHSCAN); + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + if(p_ibrt_ctrl->nv_role == IBRT_MASTER) + { + app_ibrt_if_enter_pairing_after_tws_connected(); + } + else if(p_ibrt_ctrl->nv_role == IBRT_SLAVE) + { + app_ibrt_ui_set_enter_pairing_mode(IBRT_CONNECT_MOBILE_FAILED); + app_ibrt_ui_judge_scan_type(IBRT_CONNECTE_TRIGGER,MOBILE_LINK, 0); + } + else if(p_ibrt_ctrl->nv_role == IBRT_UNKNOW) + { + app_ibrt_ui_judge_scan_type(IBRT_FREEMAN_PAIR_TRIGGER,NO_LINK_TYPE, IBRT_UI_NO_ERROR); + app_ibrt_ui_set_freeman_enable(); + } + break; + + case 4: + if(!app_device_bt_is_connected()){ + app_voice_report_generic(APP_STATUS_INDICATION_DISCONNECTED, 0,0); + } + LINKLOSE_REBOOT_ENABLE = true; + break; + case 5: + if(!app_device_bt_is_connected()&&!app_tws_ibrt_tws_link_connected()){ + app_voice_report_generic(APP_STATUS_INDICATION_DISCONNECTED, 0,0); + } + LINKLOSE_REBOOT_ENABLE = true; + break; + case 8: + app_ibrt_sync_volume_info(); + break; + case 9: + touch_reset(); + break; + default: + break; + + } + once_event_case = 0; +} + +void startonce_delay_event_Timer_(int ms) +{ + TRACE(3,"\n\n !!!!!!!!!!start %s\n\n",__func__); + osTimerStart(once_delay_event_Timer_id,ms); +} +void stoponce_delay_event_Timer_(void) +{ + TRACE(3,"\n\n!!!!!!!!!! stop %s\n\n",__func__); + osTimerStop(once_delay_event_Timer_id); +} + +/********************************once_delay_event_Timer__timer*******************************************************/ +/***********************************************************************************************/ +#include "hal_gpio.h" +#include "tgt_hardware.h" +extern struct BT_DEVICE_T app_bt_device; +extern void hal_gpio_pin_set(enum HAL_GPIO_PIN_T pin); +osTimerId app_mute_timer = NULL; +static void app_mute_timehandler(void const *n); +osTimerDef (APP_MUTE_TIMER, app_mute_timehandler); +/* +static void app_mute_ctrl_init(void) +{ + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&MuteOutPwl, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)MuteOutPwl.pin, HAL_GPIO_DIR_OUT, 0); + + app_mute_timer = osTimerCreate (osTimer(APP_MUTE_TIMER), osTimerOnce, NULL); +} +*/ + +void app_mute_ctrl(bool Status) +{ + if(Status == true) + { + hal_gpio_pin_set((enum HAL_GPIO_PIN_T)MuteOutPwl.pin); + } + else + { + hal_gpio_pin_clr((enum HAL_GPIO_PIN_T)MuteOutPwl.pin); + } +} + +void app_mutetimer_start() +{ + osTimerStart(app_mute_timer, 190); +} +static void app_mute_timehandler(void const *n) +{ + app_mute_ctrl(true); +} + +bool Curr_Is_Master(void) +{ + static ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if(p_ibrt_ctrl->current_role == IBRT_MASTER) + return 1; + else + return 0; +} + +bool Curr_Is_Slave(void) +{ + static ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if(p_ibrt_ctrl->current_role == IBRT_SLAVE) + return 1; + else + return 0; +} + +uint8_t get_curr_role(void) +{ + static ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + return p_ibrt_ctrl->current_role; +} + +uint8_t get_nv_role(void) +{ + static ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + return p_ibrt_ctrl->nv_role; +} + +extern bt_status_t LinkDisconnectDirectly(bool PowerOffFlag); +void a2dp_suspend_music_force(void); + +bool app_is_power_off_in_progress(void) +{ + return app_poweroff_flag?TRUE:FALSE; +} + +#if GFPS_ENABLED +#define APP_GFPS_BATTERY_TIMEROUT_VALUE (10000) +static void app_gfps_battery_show_timeout_timer_cb(void const *n); +osTimerDef (GFPS_BATTERY_SHOW_TIMEOUT_TIMER, app_gfps_battery_show_timeout_timer_cb); +static osTimerId app_gfps_battery_show_timer_id = NULL; +#include "app_gfps.h" +static void app_gfps_battery_show_timeout_timer_cb(void const *n) +{ + TRACE(1,"%s", __func__); + app_gfps_set_battery_datatype(HIDE_UI_INDICATION); +} + +void app_gfps_battery_show_timer_start() +{ + if (app_gfps_battery_show_timer_id == NULL) + app_gfps_battery_show_timer_id = osTimerCreate(osTimer(GFPS_BATTERY_SHOW_TIMEOUT_TIMER), osTimerOnce, NULL); + osTimerStart(app_gfps_battery_show_timer_id, APP_GFPS_BATTERY_TIMEROUT_VALUE); +} + +void app_gfps_battery_show_timer_stop() +{ + if (app_gfps_battery_show_timer_id) + osTimerStop(app_gfps_battery_show_timer_id); +} +#endif + +int app_deinit(int deinit_case) +{ + int nRet = 0; + TRACE(2,"%s case:%d",__func__, deinit_case); + +#ifdef __PC_CMD_UART__ + app_cmd_close(); +#endif +#if (defined(BTUSB_AUDIO_MODE) || defined(BT_USB_AUDIO_DUAL_MODE)) + if(app_usbaudio_mode_on()) return 0; +#endif + if (!deinit_case){ + app_poweroff_flag = 1; +#if defined(APP_LINEIN_A2DP_SOURCE) + app_audio_sendrequest(APP_A2DP_SOURCE_LINEIN_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE,0); +#endif +#if defined(APP_I2S_A2DP_SOURCE) + app_audio_sendrequest(APP_A2DP_SOURCE_I2S_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE,0); +#endif + app_status_indication_filter_set(APP_STATUS_INDICATION_BOTHSCAN); + app_audio_sendrequest(APP_BT_STREAM_INVALID, (uint8_t)APP_BT_SETTING_CLOSEALL, 0); + osDelay(500); + LinkDisconnectDirectly(true); + osDelay(500); + app_status_indication_set(APP_STATUS_INDICATION_POWEROFF); +#ifdef MEDIA_PLAYER_SUPPORT + app_voice_report(APP_STATUS_INDICATION_POWEROFF, 0); +#endif +#ifdef __THIRDPARTY + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_DEINIT); +#endif +#if FPGA==0 + nv_record_flash_flush(); + norflash_api_flush_all(); +#if defined(DUMP_LOG_ENABLE) + log_dump_flush_all(); +#endif +#endif + osDelay(1000); + af_close(); + } + + return nRet; +} + +#ifdef APP_TEST_MODE +extern void app_test_init(void); +int app_init(void) +{ + int nRet = 0; + //uint8_t pwron_case = APP_POWERON_CASE_INVALID; + TRACE(1,"%s",__func__); + app_poweroff_flag = 0; + + app_sysfreq_req(APP_SYSFREQ_USER_APP_INIT, APP_SYSFREQ_52M); + list_init(); + af_open(); + app_os_init(); + app_pwl_open(); + app_audio_open(); + app_audio_manager_open(); + app_overlay_open(); + if (app_key_open(true)) + { + nRet = -1; + goto exit; + } + + app_test_init(); +exit: + app_sysfreq_req(APP_SYSFREQ_USER_APP_INIT, APP_SYSFREQ_32K); + return nRet; +} +#else /* !defined(APP_TEST_MODE) */ + +int app_bt_connect2tester_init(void) +{ + btif_device_record_t rec; + bt_bdaddr_t tester_addr; + uint8_t i; + bool find_tester = false; + struct nvrecord_env_t *nvrecord_env; + btdevice_profile *btdevice_plf_p; + nv_record_env_get(&nvrecord_env); + + if (nvrecord_env->factory_tester_status.status != NVRAM_ENV_FACTORY_TESTER_STATUS_DEFAULT) + return 0; + + if (!nvrec_dev_get_dongleaddr(&tester_addr)){ + nv_record_open(section_usrdata_ddbrecord); + for (i = 0; nv_record_enum_dev_records(i, &rec) == BT_STS_SUCCESS; i++) { + if (!memcmp(rec.bdAddr.address, tester_addr.address, BTIF_BD_ADDR_SIZE)){ + find_tester = true; + } + } + if(i==0 && !find_tester){ + memset(&rec, 0, sizeof(btif_device_record_t)); + memcpy(rec.bdAddr.address, tester_addr.address, BTIF_BD_ADDR_SIZE); + nv_record_add(section_usrdata_ddbrecord, &rec); + btdevice_plf_p = (btdevice_profile *)app_bt_profile_active_store_ptr_get(rec.bdAddr.address); + nv_record_btdevicerecord_set_hfp_profile_active_state(btdevice_plf_p, true); + nv_record_btdevicerecord_set_a2dp_profile_active_state(btdevice_plf_p, true); + } + if (find_tester && i>2){ + nv_record_ddbrec_delete(&tester_addr); + nvrecord_env->factory_tester_status.status = NVRAM_ENV_FACTORY_TESTER_STATUS_TEST_PASS; + nv_record_env_set(nvrecord_env); + } + } + + return 0; +} + +int app_nvrecord_rebuild(void) +{ + struct nvrecord_env_t *nvrecord_env; + nv_record_env_get(&nvrecord_env); + + nv_record_sector_clear(); + nv_record_env_init(); + nv_record_update_factory_tester_status(NVRAM_ENV_FACTORY_TESTER_STATUS_TEST_PASS); + nv_record_env_set(nvrecord_env); + nv_record_flash_flush(); + + return 0; +} + +#if (defined(BTUSB_AUDIO_MODE) || defined(BT_USB_AUDIO_DUAL_MODE)) +#include "app_audio.h" +#include "usb_audio_frm_defs.h" +#include "usb_audio_app.h" + +static bool app_usbaudio_mode = false; + +extern "C" void btusbaudio_entry(void); +void app_usbaudio_entry(void) +{ + btusbaudio_entry(); + app_usbaudio_mode = true ; +} + +bool app_usbaudio_mode_on(void) +{ + return app_usbaudio_mode; +} + +void app_usb_key(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + +} + +const APP_KEY_HANDLE app_usb_handle_cfg[] = { + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_UP},"USB HID FN1 UP key",app_usb_key, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_UP},"USB HID FN2 UP key",app_usb_key, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_UP},"USB HID PWR UP key",app_usb_key, NULL}, +}; + +void app_usb_key_init(void) +{ + uint8_t i = 0; + TRACE(1,"%s",__func__); + for (i=0; i<(sizeof(app_usb_handle_cfg)/sizeof(APP_KEY_HANDLE)); i++){ + app_key_handle_registration(&app_usb_handle_cfg[i]); + } +} +#endif /* (defined(BTUSB_AUDIO_MODE) || defined(BT_USB_AUDIO_DUAL_MODE)) */ + +//#define OS_HAS_CPU_STAT 1 +#if OS_HAS_CPU_STAT +extern "C" void rtx_show_all_threads_usage(void); +#define _CPU_STATISTICS_PEROID_ 6000 +#define CPU_USAGE_TIMER_TMO_VALUE (_CPU_STATISTICS_PEROID_/3) +static void cpu_usage_timer_handler(void const *param); +osTimerDef(cpu_usage_timer, cpu_usage_timer_handler); +static osTimerId cpu_usage_timer_id = NULL; +static void cpu_usage_timer_handler(void const *param) +{ + rtx_show_all_threads_usage(); +} +#endif + +#ifdef USER_REBOOT_PLAY_MUSIC_AUTO +bool a2dp_need_to_play = false; +#endif +extern void btif_me_write_bt_sleep_enable(uint8_t sleep_en); + +int btdrv_tportopen(void); + + +void app_ibrt_init(void) +{ + app_bt_global_handle_init(); +#if defined(IBRT) + ibrt_config_t config; + app_tws_ibrt_init(); + app_ibrt_ui_init(); + app_ibrt_ui_test_init(); + app_ibrt_if_config_load(&config); + app_ibrt_customif_ui_start(); +#ifdef IBRT_SEARCH_UI + app_tws_ibrt_start(&config, true); + app_ibrt_search_ui_init(false,IBRT_NONE_EVENT); +#else + app_tws_ibrt_start(&config, false); +#endif + +#ifdef POWER_ON_ENTER_TWS_PAIRING_ENABLED + app_ibrt_ui_event_entry(IBRT_TWS_PAIRING_EVENT); +#endif + +#endif +} + +#ifdef GFPS_ENABLED +static void app_tell_battery_info_handler(uint8_t *batteryValueCount, + uint8_t *batteryValue) +{ + GFPS_BATTERY_STATUS_E status; + if (app_battery_is_charging()) + { + status = BATTERY_CHARGING; + } + else + { + status = BATTERY_NOT_CHARGING; + } + + // TODO: add the charger case's battery level +#ifdef IBRT + if (app_tws_ibrt_tws_link_connected()) + { + *batteryValueCount = 2; + } + else + { + *batteryValueCount = 1; + } +#else + *batteryValueCount = 1; +#endif + + TRACE(2,"%s,*batteryValueCount is %d",__func__,*batteryValueCount); + if (1 == *batteryValueCount) + { + batteryValue[0] = ((app_battery_current_level()+1) * 10) | (status << 7); + } + else + { + batteryValue[0] = ((app_battery_current_level()+1) * 10) | (status << 7); + batteryValue[1] = ((app_battery_current_level()+1) * 10) | (status << 7); + + } +} +#endif +/* +#define regaddr0 0x40 +#define regaddr1 0x41 +#define regaddr2 0x42 +#define regaddr3 0x43 + +#define regaddr4 0xc8 + +#define decice_firstreg 0x00 +*/ +void touch_evt_handler(enum HAL_GPIO_PIN_T pin) +{ + TRACE(3,"SCL_TOUCH !!!!"); + + /* + unsigned char keyEventBUff0 ; + unsigned char keyEventBUff1 ; + unsigned char keyEventBUff2 ; + unsigned char keyEventBUff3 ; + unsigned char temp = 0; + //hal_gpio_i2c_simple_recv((unsigned char)0x60, 0x40, 1,&keyEventBUff,4); + I2C_ReadByte(regaddr0,&keyEventBUff0); + I2C_ReadByte(regaddr1,&keyEventBUff1); + I2C_ReadByte(regaddr2,&keyEventBUff2); + I2C_ReadByte(regaddr3,&keyEventBUff3); + unsigned char firstaddr; + + I2C_ReadByte(decice_firstreg,&firstaddr); + TRACE(3,"0X00 REG = 0x%x",firstaddr); + unsigned char keyEventBUff4byte[4] ; + I2C_Read4Byte(regaddr0,keyEventBUff4byte); + + I2C_ReadByte(0xC8,&temp); + temp |= 0x01; + I2C_WriteByte(0xC8,temp); + TRACE(3,"REG0X40 = 0x%x, REG0X41 = 0x%x, REG0X42 = 0x%x, REG0X43 = 0x%x",keyEventBUff0,keyEventBUff1,keyEventBUff2,keyEventBUff3); + TRACE(3,"keyEventBUff4BYTE :"); + DUMP8("0x%02x ",keyEventBUff4byte,4); + + uint8_t keyEventBUff0[4]; + uint8_t keyEventBUff4[1]; + + touch_key_i2c_read(regaddr0,&keyEventBUff0[0],1); + touch_key_i2c_read(regaddr1,&keyEventBUff0[1],1); + touch_key_i2c_read(regaddr2,&keyEventBUff0[2],1); + touch_key_i2c_read(regaddr3,&keyEventBUff0[3],1); + touch_key_i2c_read(regaddr4,keyEventBUff4,1); + TRACE(3,"keyEventBUff0 :"); + DUMP8("0x%02x ",keyEventBUff0,4); + TRACE(3,"keyEventBUff1 :"); + DUMP8("0x%02x ",keyEventBUff4,1); + keyEventBUff4[0] |= 0x1; + touch_key_i2c_write(0,regaddr4,1,keyEventBUff4); + */ +} + + +void touch_evt_handler_sda(enum HAL_GPIO_PIN_T pin) +{ + TRACE(3,"SDA_TOUCH!!!"); +} + +void tou_io_init(void) +{ + TRACE(3,"%s!!!",__func__); + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&TOUCH_I2C_SCL, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)TOUCH_I2C_SCL.pin, HAL_GPIO_DIR_IN, 1); + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&TOUCH_I2C_SDA, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)TOUCH_I2C_SDA.pin, HAL_GPIO_DIR_IN, 1); + + struct HAL_GPIO_IRQ_CFG_T gpiocfg_sda; + gpiocfg_sda.irq_enable = true; + gpiocfg_sda.irq_debounce = true; + gpiocfg_sda.irq_type = HAL_GPIO_IRQ_TYPE_EDGE_SENSITIVE; + gpiocfg_sda.irq_polarity=HAL_GPIO_IRQ_POLARITY_LOW_FALLING ; + gpiocfg_sda.irq_handler = touch_evt_handler; + hal_gpio_setup_irq((enum HAL_GPIO_PIN_T)TOUCH_I2C_SCL.pin, &gpiocfg_sda); + + struct HAL_GPIO_IRQ_CFG_T gpiocfg; + gpiocfg.irq_enable = true; + gpiocfg.irq_debounce = true; + gpiocfg.irq_type = HAL_GPIO_IRQ_TYPE_EDGE_SENSITIVE; + gpiocfg.irq_polarity=HAL_GPIO_IRQ_POLARITY_LOW_FALLING ; + gpiocfg.irq_handler = touch_evt_handler_sda; + hal_gpio_setup_irq((enum HAL_GPIO_PIN_T)TOUCH_I2C_SDA.pin, &gpiocfg); + + +} + +/******************************LED_status_timer*********************************************************/ +osTimerId LED_statusid = NULL; +void startLED_status(int ms); +void stopLED_status(void); +static void LED_statusfun(const void *); +osTimerDef(defLED_status,LED_statusfun); +void LED_statusinit(void) +{ + LED_statusid = osTimerCreate(osTimer(defLED_status),osTimerOnce,(void *)0); +} +static void LED_statusfun(const void *) +{ + //TRACE("\n\n!!!!!!enter %s\n\n",__func__); + if((Curr_Is_Slave()||app_device_bt_is_connected())&&(!app_battery_is_charging())){ + app_status_indication_set(APP_STATUS_INDICATION_CONNECTED); + }else if(!app_device_bt_is_connected()&&(!app_battery_is_charging())){ + app_status_indication_set(APP_STATUS_INDICATION_BOTHSCAN); + }else if(app_battery_is_charging()){ + app_status_indication_set(APP_STATUS_INDICATION_CHARGING); + } + //unsigned char firstaddr; + //I2C_ReadByte(decice_firstreg,&firstaddr); + //TRACE(3,"0X00 REG = 0x%x",firstaddr); + startLED_status(1000); +} + +void startLED_status(int ms) +{ + //TRACE("\n\n !!!!!!!!!!start %s\n\n",__func__); + osTimerStart(LED_statusid,ms); +} +void stopLED_status(void) +{ + //TRACE("\n\n!!!!!!!!!! stop %s\n\n",__func__); + osTimerStop(LED_statusid); +} + +/********************************LED_status_timer*******************************************************/ + + +/******************************TOUCH_INT_TEST_timer*********************************************************/ +void touch_reset(void); +osTimerId TOUCH_INT_TESTid = NULL; +void startTOUCH_INT_TEST(int ms); +void stopTOUCH_INT_TEST(void); +static void TOUCH_INT_TESTfun(const void *); +osTimerDef(defTOUCH_INT_TEST,TOUCH_INT_TESTfun); +void TOUCH_INT_TESTinit(void) +{ + TOUCH_INT_TESTid = osTimerCreate(osTimer(defTOUCH_INT_TEST),osTimerOnce,(void *)0); + + //startTOUCH_INT_TEST(100); + //touch_reset(); +} +static void TOUCH_INT_TESTfun(const void *) +{ + TRACE(3,"\n!!!!!!enter %s\n",__func__); + //app_i2c_demo_init(); + //hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&TOUCH_INT, 1); + //hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)TOUCH_INT.pin, HAL_GPIO_DIR_IN, 0); + tou_io_init(); +} + +void startTOUCH_INT_TEST(int ms) +{ + TRACE(3,"\n !!!!!!!!!!start %s\n",__func__); + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&TOUCH_I2C_SCL, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)TOUCH_I2C_SCL.pin, HAL_GPIO_DIR_OUT, 0); + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&TOUCH_I2C_SDA, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)TOUCH_I2C_SDA.pin, HAL_GPIO_DIR_OUT, 0); + //hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&TOUCH_INT, 1); + //hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)TOUCH_INT.pin, HAL_GPIO_DIR_OUT, 0); + + osTimerStart(TOUCH_INT_TESTid,ms); +} +void stopTOUCH_INT_TEST(void) +{ + osTimerStop(TOUCH_INT_TESTid); +} + +void touch_reset(void) +{ + startTOUCH_INT_TEST(50); +} + +/********************************TOUCH_INT_TEST_timer*******************************************************/ + +void user_io_timer_init(void) +{ + //app_mute_ctrl_init(); + LED_statusinit(); + pwrkey_detinit(); + Auto_Shutdowm_Timerinit(); + delay_report_toneinit(); + once_delay_event_Timer_init(); + TOUCH_INT_TESTinit(); + //app_i2c_demo_init(); + //tou_io_init(); +} + +extern uint32_t __coredump_section_start[]; +extern uint32_t __ota_upgrade_log_start[]; +extern uint32_t __log_dump_start[]; +extern uint32_t __crash_dump_start[]; +extern uint32_t __custom_parameter_start[]; +extern uint32_t __lhdc_license_start[]; +extern uint32_t __aud_start[]; +extern uint32_t __userdata_start[]; +extern uint32_t __factory_start[]; + +#if defined(A2DP_LHDC_ON) +extern "C" +{ + typedef struct bes_bt_local_info_t + { + uint8_t bt_addr[BTIF_BD_ADDR_SIZE]; + const char *bt_name; + uint8_t bt_len; + uint8_t ble_addr[BTIF_BD_ADDR_SIZE]; + const char *ble_name; + uint8_t ble_len; + } bes_bt_local_info; + + typedef int (*LHDC_GET_BT_INFO)(bes_bt_local_info *bt_info); + extern bool lhdcSetLicenseKeyTable(uint8_t * licTable, LHDC_GET_BT_INFO pFunc); +} +extern int bes_bt_local_info_get(bes_bt_local_info *local_info); + +void lhdc_license_check() +{ + uint8_t lhdc_license_key = 0; + uint8_t *lhdc_license_data=(uint8_t * )__lhdc_license_start + 0x98; + TRACE(5,"lhdc_license_data:%p, lhdc license %02x %02x %02x %02x",lhdc_license_data, + lhdc_license_data[0],lhdc_license_data[1],lhdc_license_data[2],lhdc_license_data[3]); + + app_overlay_select(APP_OVERLAY_A2DP_LHDC); + TRACE(1, "current_overlay = %d", app_get_current_overlay()); + + lhdc_license_key = lhdcSetLicenseKeyTable(lhdc_license_data, bes_bt_local_info_get); + TRACE(0, "lhdc_license_key:%d", lhdc_license_key); + + if(lhdc_license_key) + { + TRACE(0, "LHDC OK"); + } + else + { + TRACE(0, "LHDC ERROR"); + } +} +#endif + +int app_init(void) +{ + int nRet = 0; + struct nvrecord_env_t *nvrecord_env; +#ifdef POWER_ON_ENTER_TWS_PAIRING_ENABLED + bool need_check_key = false; +#else + bool need_check_key = true; +#endif + uint8_t pwron_case = APP_POWERON_CASE_INVALID; +#ifdef BT_USB_AUDIO_DUAL_MODE + uint8_t usb_plugin = 0; +#endif +#ifdef IBRT_SEARCH_UI + bool is_charging_poweron=false; +#endif + TRACE(0,"please check all sections sizes and heads is correct ........"); + TRACE(2,"__coredump_section_start: %p length: 0x%x", __coredump_section_start, CORE_DUMP_SECTION_SIZE); + TRACE(2,"__ota_upgrade_log_start: %p length: 0x%x", __ota_upgrade_log_start, OTA_UPGRADE_LOG_SIZE); + TRACE(2,"__log_dump_start: %p length: 0x%x", __log_dump_start, LOG_DUMP_SECTION_SIZE); + TRACE(2,"__crash_dump_start: %p length: 0x%x", __crash_dump_start, CRASH_DUMP_SECTION_SIZE); + TRACE(2,"__custom_parameter_start: %p length: 0x%x", __custom_parameter_start, CUSTOM_PARAMETER_SECTION_SIZE); + TRACE(2,"__lhdc_license_start: %p length: 0x%x", __lhdc_license_start, LHDC_LICENSE_SECTION_SIZE); + TRACE(2,"__userdata_start: %p length: 0x%x", __userdata_start, USERDATA_SECTION_SIZE*2); + TRACE(2,"__aud_start: %p length: 0x%x", __aud_start, AUD_SECTION_SIZE); + TRACE(2,"__factory_start: %p length: 0x%x", __factory_start, FACTORY_SECTION_SIZE); + + TRACE(0,"app_init\n"); + +#ifdef __RPC_ENABLE__ +extern int rpc_service_setup(void); + rpc_service_setup(); +#endif + +#ifdef IBRT + // init tws interface + app_tws_if_init(); +#endif // #ifdef IBRT + + nv_record_init(); + factory_section_init(); + +#ifdef ANC_APP + app_anc_ios_init(); +#endif + app_sysfreq_req(APP_SYSFREQ_USER_APP_INIT, APP_SYSFREQ_104M); +#if defined(MCU_HIGH_PERFORMANCE_MODE) + TRACE(1,"sys freq calc : %d\n", hal_sys_timer_calc_cpu_freq(5, 0)); +#endif + list_init(); + nRet = app_os_init(); + if (nRet) { + goto exit; + } +#if OS_HAS_CPU_STAT + cpu_usage_timer_id = osTimerCreate(osTimer(cpu_usage_timer), osTimerPeriodic, NULL); + if (cpu_usage_timer_id != NULL) { + osTimerStart(cpu_usage_timer_id, CPU_USAGE_TIMER_TMO_VALUE); + } +#endif + + //app_status_indication_init(); + +#ifdef BTADDR_FOR_DEBUG + gen_bt_addr_for_debug(); +#endif + +#ifdef FORCE_SIGNALINGMODE + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_TEST_NOSIGNALINGMODE); + hal_sw_bootmode_set(HAL_SW_BOOTMODE_TEST_MODE | HAL_SW_BOOTMODE_TEST_SIGNALINGMODE); +#elif defined FORCE_NOSIGNALINGMODE + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_TEST_SIGNALINGMODE); + hal_sw_bootmode_set(HAL_SW_BOOTMODE_TEST_MODE | HAL_SW_BOOTMODE_TEST_NOSIGNALINGMODE); +#endif + + if (hal_sw_bootmode_get() & HAL_SW_BOOTMODE_REBOOT_FROM_CRASH){ + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_REBOOT_FROM_CRASH); + TRACE(0,"Crash happened!!!"); + #ifdef VOICE_DATAPATH + gsound_dump_set_flag(true); + #endif + } + + if (hal_sw_bootmode_get() & HAL_SW_BOOTMODE_REBOOT){ + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_REBOOT); + pwron_case = APP_POWERON_CASE_REBOOT; + need_check_key = false; + TRACE(0,"Initiative REBOOT happens!!!"); +#ifdef USER_REBOOT_PLAY_MUSIC_AUTO + if(hal_sw_bootmode_get() & HAL_SW_BOOTMODE_LOCAL_PLAYER) + { + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_LOCAL_PLAYER); + a2dp_need_to_play = true; + TRACE(0,"a2dp_need_to_play = true"); + } +#endif + } + + if (hal_sw_bootmode_get() & HAL_SW_BOOTMODE_TEST_MODE){ + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_TEST_MODE); + pwron_case = APP_POWERON_CASE_TEST; + need_check_key = false; + TRACE(0,"To enter test mode!!!"); + } + + +#ifdef BT_USB_AUDIO_DUAL_MODE + usb_os_init(); +#endif + nRet = app_battery_open(); + TRACE(1,"BATTERY %d",nRet); + if (pwron_case != APP_POWERON_CASE_TEST){ +#ifdef USER_REBOOT_PLAY_MUSIC_AUTO + TRACE(0,"hal_sw_bootmode_clear HAL_SW_BOOTMODE_LOCAL_PLAYER!!!!!!"); + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_LOCAL_PLAYER); +#endif + switch (nRet) { + case APP_BATTERY_OPEN_MODE_NORMAL: + nRet = 0; + break; + case APP_BATTERY_OPEN_MODE_CHARGING: + app_status_indication_set(APP_STATUS_INDICATION_CHARGING); + TRACE(0,"CHARGING!"); + app_battery_start(); + + app_key_open(false); + app_key_init_on_charging(); + nRet = 0; +#if defined(BT_USB_AUDIO_DUAL_MODE) + usb_plugin = 1; +#elif defined(BTUSB_AUDIO_MODE) + goto exit; +#endif + break; + case APP_BATTERY_OPEN_MODE_CHARGING_PWRON: + TRACE(0,"CHARGING PWRON!"); +#ifdef IBRT_SEARCH_UI + is_charging_poweron=true; +#endif + app_status_indication_set(APP_STATUS_INDICATION_CHARGING); + need_check_key = false; + nRet = 0; + break; + case APP_BATTERY_OPEN_MODE_INVALID: + default: + nRet = -1; + goto exit; + break; + } + } + + if (app_key_open(need_check_key)){ + TRACE(0,"PWR KEY DITHER!"); + nRet = -1; + goto exit; + } + + hal_sw_bootmode_set(HAL_SW_BOOTMODE_REBOOT); + app_poweron_key_init(); +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("Power on."); +#endif + app_bt_init(); + af_open(); + app_audio_open(); + app_audio_manager_open(); + app_overlay_open(); + + nv_record_env_init(); + nvrec_dev_data_open(); + factory_section_open(); + /******************************************************************************/ + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&TOUCH_I2C_SCL, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)TOUCH_I2C_SCL.pin, HAL_GPIO_DIR_OUT, 1); + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&TOUCH_I2C_SDA, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)TOUCH_I2C_SDA.pin, HAL_GPIO_DIR_OUT, 1); + /*****************************************************************************/ +// app_bt_connect2tester_init(); + nv_record_env_get(&nvrecord_env); +/* +if( bt_addr[0] < 0x22 ||bt_addr[0] > 0x33 ||bt_addr[1] != 0x22 || bt_addr[2] != 0x22 ||bt_addr[3] != 0x22||bt_addr[4] != 0x22||bt_addr[5] != 0x22) + { + TRACE(3,"BT ADDR ERRO!!!\n"); + nRet = -1; + goto exit; + } +*/ +#ifdef BISTO_ENABLED + nv_record_gsound_rec_init(); +#endif + +#ifdef BLE_ENABLE + app_ble_mode_init(); + app_ble_customif_init(); +#ifdef IBRT + app_ble_force_switch_adv(BLE_SWITCH_USER_IBRT, false); +#endif // #ifdef IBRT +#endif + + audio_process_init(); +#ifdef __PC_CMD_UART__ + app_cmd_open(); +#endif +#ifdef AUDIO_DEBUG_V0_1_0 + speech_tuning_init(); +#endif +#ifdef ANC_APP + app_anc_open_module(); +#endif + +#ifdef MEDIA_PLAYER_SUPPORT + app_play_audio_set_lang(nvrecord_env->media_language.language); +#endif + app_bt_stream_volume_ptr_update(NULL); + +#ifdef __THIRDPARTY + app_thirdparty_init(); + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO2,THIRDPARTY_INIT); +#endif + + // TODO: freddie->unify all of the OTA modules +#if defined(IBRT_OTA) + ota_flash_init(); +#endif + +#ifdef OTA_ENABLED + /// init OTA common module + ota_common_init_handler(); +#endif // OTA_ENABLED + +#ifdef IBRT + // for TWS side decision, the last bit is 1:right, 0:left + if (app_tws_is_unknown_side()) + { + //app_tws_set_side_from_addr(factory_section_get_bt_address()); + app_tws_set_side_from_gpio(); + } +#endif + + + btdrv_start_bt(); +#if defined (__GMA_VOICE__) && defined(IBRT_SEARCH_UI) + app_ibrt_reconfig_btAddr_from_nv(); +#endif + + if (pwron_case != APP_POWERON_CASE_TEST) { + BesbtInit(); + app_wait_stack_ready(); + bt_drv_extra_config_after_init(); + bt_generate_ecdh_key_pair(); + app_bt_start_custom_function_in_bt_thread((uint32_t)0, + 0, (uint32_t)app_ibrt_init); + } +#if defined(BLE_ENABLE) && defined(IBRT) + app_ble_force_switch_adv(BLE_SWITCH_USER_IBRT, true); +#endif + app_sysfreq_req(APP_SYSFREQ_USER_APP_INIT, APP_SYSFREQ_52M); + TRACE(1,"\n\n\nbt_stack_init_done:%d\n\n\n", pwron_case); + + if (pwron_case == APP_POWERON_CASE_REBOOT){ + app_status_indication_init(); + user_io_timer_init(); + app_status_indication_set(APP_STATUS_INDICATION_POWERON); +#ifdef MEDIA_PLAYER_SUPPORT + app_voice_report(APP_STATUS_INDICATION_POWERON, 0); +#endif + app_bt_start_custom_function_in_bt_thread((uint32_t)1, + 0, (uint32_t)btif_me_write_bt_sleep_enable); + btdrv_set_lpo_times(); + +#if defined(IBRT_OTA) + bes_ota_init(); +#endif + //app_bt_accessmode_set(BTIF_BAM_NOT_ACCESSIBLE); +#if defined(IBRT) +#ifdef IBRT_SEARCH_UI + if(is_charging_poweron==false) + { + if(IBRT_UNKNOW == nvrecord_env->ibrt_mode.mode) + { + TRACE(0,"ibrt_ui_log:power on unknow mode"); + app_ibrt_enter_limited_mode(); + if(app_tws_is_right_side()){ + TRACE(0,"app_start_tws_serching_direactly"); + app_start_tws_serching_direactly(); + } + } + else + { + TRACE(1,"ibrt_ui_log:power on %d fetch out", nvrecord_env->ibrt_mode.mode); + app_ibrt_ui_event_entry(IBRT_FETCH_OUT_EVENT); + } + startLED_status(1000); + once_event_case = 9; + startonce_delay_event_Timer_(1000); + startpwrkey_det(200); + } +#elif defined(IS_MULTI_AI_ENABLED) + //when ama and bisto switch, earphone need reconnect with peer, master need reconnect with phone + uint8_t box_action = app_ai_tws_reboot_get_box_action(); + if (box_action != 0xFF) + { + TRACE(2, "%s box_actionstate %d", __func__, box_action); + app_ibrt_ui_event_entry(box_action|IBRT_SKIP_FALSE_TRIGGER_MASK); + } +#endif +#else + app_bt_accessmode_set(BTIF_BAM_NOT_ACCESSIBLE); +#endif + + app_key_init(); + app_battery_start(); +#if defined(__BTIF_EARPHONE__) && defined(__BTIF_AUTOPOWEROFF__) + app_start_10_second_timer(APP_POWEROFF_TIMER_ID); +#endif + +#if defined(__IAG_BLE_INCLUDE__) && defined(BTIF_BLE_APP_DATAPATH_SERVER) + BLE_custom_command_init(); +#endif +#ifdef __THIRDPARTY + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_INIT); + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_START); + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO2,THIRDPARTY_BT_CONNECTABLE); + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO3,THIRDPARTY_START); +#endif +#if defined( __BTIF_EARPHONE__) && defined(__BTIF_BT_RECONNECT__) +#if !defined(IBRT) + app_bt_profile_connect_manager_opening_reconnect(); +#endif +#endif + } +#ifdef __ENGINEER_MODE_SUPPORT__ + else if(pwron_case == APP_POWERON_CASE_TEST){ + app_status_indication_init(); + app_factorymode_set(true); + app_status_indication_set(APP_STATUS_INDICATION_POWERON); +#ifdef MEDIA_PLAYER_SUPPORT + app_voice_report(APP_STATUS_INDICATION_POWERON, 0); +#endif +#ifdef __WATCHER_DOG_RESET__ + app_wdt_close(); +#endif + TRACE(0,"!!!!!ENGINEER_MODE!!!!!\n"); + nRet = 0; + app_nvrecord_rebuild(); + app_factorymode_key_init(); + if (hal_sw_bootmode_get() & HAL_SW_BOOTMODE_TEST_SIGNALINGMODE){ + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_TEST_MASK); + app_factorymode_bt_signalingtest(NULL, NULL); + } + if (hal_sw_bootmode_get() & HAL_SW_BOOTMODE_TEST_NOSIGNALINGMODE){ + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_TEST_MASK); + app_factorymode_bt_nosignalingtest(NULL, NULL); + } + } +#endif + else{ + user_io_timer_init(); + app_status_indication_init(); + app_status_indication_set(APP_STATUS_INDICATION_POWERON); +#ifdef MEDIA_PLAYER_SUPPORT + app_voice_report(APP_STATUS_INDICATION_POWERON, 0); +#endif + if (need_check_key){ + pwron_case = app_poweron_wait_case(); + } + else + { + pwron_case = APP_POWERON_CASE_NORMAL; + } + if (need_check_key) + { +#ifndef __POWERKEY_CTRL_ONOFF_ONLY__ + app_poweron_wait_finished(); +#endif + } + if (pwron_case != APP_POWERON_CASE_INVALID && pwron_case != APP_POWERON_CASE_DITHERING){ + TRACE(1,"power on case:%d\n", pwron_case); + nRet = 0; +#ifndef __POWERKEY_CTRL_ONOFF_ONLY__ + //app_status_indication_set(APP_STATUS_INDICATION_INITIAL); +#endif + app_bt_start_custom_function_in_bt_thread((uint32_t)1, + 0, (uint32_t)btif_me_write_bt_sleep_enable); + btdrv_set_lpo_times(); + +#ifdef IBRT_OTA + bes_ota_init(); +#endif + +#ifdef __INTERCONNECTION__ + app_interconnection_init(); +#endif + +#ifdef __INTERACTION__ + app_interaction_init(); +#endif + +#if defined(__IAG_BLE_INCLUDE__) && defined(BTIF_BLE_APP_DATAPATH_SERVER) + BLE_custom_command_init(); +#endif +#ifdef GFPS_ENABLED + app_gfps_set_battery_info_acquire_handler(app_tell_battery_info_handler); + app_gfps_set_battery_datatype(SHOW_UI_INDICATION); +#endif + osDelay(500); + + switch (pwron_case) { + case APP_POWERON_CASE_CALIB: + break; + case APP_POWERON_CASE_BOTHSCAN: + app_status_indication_set(APP_STATUS_INDICATION_BOTHSCAN); +#ifdef MEDIA_PLAYER_SUPPORT + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); +#endif +#if defined( __BTIF_EARPHONE__) +#if defined(IBRT) +#ifdef IBRT_SEARCH_UI + if(false==is_charging_poweron) + app_ibrt_enter_limited_mode(); +#endif +#else + app_bt_accessmode_set(BTIF_BT_DEFAULT_ACCESS_MODE_PAIR); +#endif +#ifdef GFPS_ENABLED + app_enter_fastpairing_mode(); +#endif +#if defined(__BTIF_AUTOPOWEROFF__) + app_start_10_second_timer(APP_PAIR_TIMER_ID); +#endif +#endif +#ifdef __THIRDPARTY + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO2,THIRDPARTY_BT_DISCOVERABLE); +#endif + break; + case APP_POWERON_CASE_NORMAL: +#if defined( __BTIF_EARPHONE__ ) && !defined(__EARPHONE_STAY_BOTH_SCAN__) +#if defined(IBRT) +#ifdef IBRT_SEARCH_UI + app_status_indication_set(APP_STATUS_INDICATION_BOTHSCAN); + if(is_charging_poweron==false) + { + startLED_status(1000); + once_event_case = 9; + startonce_delay_event_Timer_(1000); + if(IBRT_UNKNOW == nvrecord_env->ibrt_mode.mode) + { + TRACE(0,"ibrt_ui_log:power on unknow mode"); + app_ibrt_enter_limited_mode(); + if(app_tws_is_right_side()){ + app_start_tws_serching_direactly(); + } + } + else + { + TRACE(1,"ibrt_ui_log:power on %d fetch out", nvrecord_env->ibrt_mode.mode); + app_ibrt_ui_event_entry(IBRT_FETCH_OUT_EVENT); + // app_status_indication_set(APP_STATUS_INDICATION_CHARGING); + //break; + } + startpwrkey_det(200); + } +#elif defined(IS_MULTI_AI_ENABLED) + //when ama and bisto switch, earphone need reconnect with peer, master need reconnect with phone + //app_ibrt_ui_event_entry(IBRT_OPEN_BOX_EVENT); + //TRACE(1,"ibrt_ui_log:power on %d fetch out", nvrecord_env->ibrt_mode.mode); + //app_ibrt_ui_event_entry(IBRT_FETCH_OUT_EVENT); +#endif +#else + app_bt_accessmode_set(BTIF_BAM_NOT_ACCESSIBLE); +#endif +#endif + case APP_POWERON_CASE_REBOOT: + case APP_POWERON_CASE_ALARM: + default: + //app_status_indication_set(APP_STATUS_INDICATION_PAGESCAN); +#if defined( __BTIF_EARPHONE__) && defined(__BTIF_BT_RECONNECT__) && !defined(IBRT) + app_bt_profile_connect_manager_opening_reconnect(); +#endif +#ifdef __THIRDPARTY + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO2,THIRDPARTY_BT_CONNECTABLE); +#endif + + break; + } + + app_key_init(); + app_battery_start(); + +#if defined(A2DP_LHDC_ON) + lhdc_license_check(); +#endif + +#if defined(__BTIF_EARPHONE__) && defined(__BTIF_AUTOPOWEROFF__) + app_start_10_second_timer(APP_POWEROFF_TIMER_ID); +#endif +#ifdef __THIRDPARTY + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_INIT); + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_START); + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO3,THIRDPARTY_START); +#endif + +#ifdef RB_CODEC + rb_ctl_init(); +#endif + }else{ + af_close(); + app_key_close(); + nRet = -1; + } + } +exit: + +#ifdef IS_MULTI_AI_ENABLED + app_ai_tws_clear_reboot_box_state(); +#endif + +#ifdef __BT_DEBUG_TPORTS__ + { + extern void bt_enable_tports(void); + bt_enable_tports(); + //hal_iomux_tportopen(); + } +#endif + +#ifdef ANC_APP + app_anc_set_init_done(); +#endif +#ifdef BT_USB_AUDIO_DUAL_MODE + if(usb_plugin) + { + btusb_switch(BTUSB_MODE_USB); + } + else + { + btusb_switch(BTUSB_MODE_BT); + } +#else //BT_USB_AUDIO_DUAL_MODE +#if defined(BTUSB_AUDIO_MODE) + if(pwron_case == APP_POWERON_CASE_CHARGING) { +#ifdef __WATCHER_DOG_RESET__ + app_wdt_close(); +#endif + af_open(); + app_key_handle_clear(); + app_usb_key_init(); + app_usbaudio_entry(); + } + +#endif // BTUSB_AUDIO_MODE +#endif // BT_USB_AUDIO_DUAL_MODE + app_sysfreq_req(APP_SYSFREQ_USER_APP_INIT, APP_SYSFREQ_32K); + + return nRet; +} + +#endif /* APP_TEST_MODE */ diff --git a/apps/main/apps.h b/apps/main/apps.h new file mode 100644 index 0000000..96d3b27 --- /dev/null +++ b/apps/main/apps.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APPS_H__ +#define __APPS_H__ + +#include "app_status_ind.h" + +#define STACK_READY_BT 0x01 +#define STACK_READY_BLE 0x02 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +int app_init(void); + +int app_deinit(int deinit_case); + +int app_shutdown(void); + +int app_reset(void); + +int app_status_battery_report(uint8_t level); + +int app_voice_report( APP_STATUS_INDICATION_T status,uint8_t device_id); +int app_voice_report_generic(APP_STATUS_INDICATION_T status, uint8_t device_id, uint8_t isMerging); +int app_voice_stop(APP_STATUS_INDICATION_T status, uint8_t device_id); + + +/*FixME*/ +void app_status_set_num(const char* p); + +////////////10 second tiemr/////////////// +#define APP_FAST_PAIRING_TIMEOUT_IN_SECOND 120 + +#define APP_PAIR_TIMER_ID 0 +#define APP_POWEROFF_TIMER_ID 1 +#define APP_FASTPAIR_LASTING_TIMER_ID 2 + +void app_stop_10_second_timer(uint8_t timer_id); +void app_start_10_second_timer(uint8_t timer_id); + +void app_notify_stack_ready(uint8_t ready_flag); + +void app_start_postponed_reset(void); + +bool app_is_power_off_in_progress(void); + +#define CHIP_ID_C 1 +#define CHIP_ID_D 2 + +void app_disconnect_all_bt_connections(void); +bool app_is_stack_ready(void); + +extern uint8_t latency_mode_is_open; +bool Curr_Is_Master(void); +bool Curr_Is_Slave(void); +extern uint8_t get_nv_role(void); +extern uint8_t get_curr_role(void); +extern uint8_t app_poweroff_flag; +extern bool MobileLinkLose_reboot; +extern bool factory_mode_status; +extern uint8_t app_poweroff_flag; +extern bool MobileLinkLose_reboot; +extern void startclr_info_timer(int ms); +extern void app_enterpairing_timer_start(void); +extern void app_enterpairing_timer_stop(void); +extern void startdelay_report_tone(int ms,APP_STATUS_INDICATION_T status); +extern void box_cmd_app_bt_enter_mono_pairing_mode(void); +extern int app_nvrecord_rebuild(void); +extern void app_bt_power_off_customize(); +//////////////////// + + +#ifdef __cplusplus +} +#endif +#endif//__FMDEC_H__ diff --git a/apps/main/apps_tester.cpp b/apps/main/apps_tester.cpp new file mode 100644 index 0000000..cfead04 --- /dev/null +++ b/apps/main/apps_tester.cpp @@ -0,0 +1,312 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "stdio.h" +#include "cmsis_os.h" +#include "string.h" + +#include "hal_iomux.h" +#include "app_key.h" +#include "hal_trace.h" +#include "hal_sleep.h" + +#include "audioflinger.h" +#include "audiobuffer.h" +#include "app_thread.h" +#include "app_utils.h" +#include "bt_drv_interface.h" +#include "besbt.h" + +#if defined(APP_TEST_AUDIO) && defined(ANC_APP) +#include "anc_usb_app.h" +#include "usb_audio_app.h" +//#include "dualadc_audio_app.h" +#endif + +#define APP_TESTER_CPU_WAKE_LOCK HAL_CPU_WAKE_LOCK_USER_3 + +extern "C" int hal_analogif_reg_write(unsigned short reg, unsigned short val); +extern "C" void OS_NotifyEvm(void); +extern void app_anc_usb_init(void); + +#define REG(a) *(volatile uint32_t *)(a) + +void bt_signaling_test(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + + hal_cpu_wake_lock(APP_TESTER_CPU_WAKE_LOCK); + btdrv_testmode_start(); + btdrv_enable_dut(); +} + +void bt_stack_test(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + + btdrv_start_bt(); + BesbtInit(); +} + +void bt_ble_test(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + + hal_cpu_wake_lock(APP_TESTER_CPU_WAKE_LOCK); + btdrv_testmode_start(); + + btdrv_hcioff(); + hal_iomux_set_uart1(); + btdrv_uart_bridge_loop(); +} + +void bt_test_104m(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + + hal_analogif_reg_write(0x35,0x0); + hal_analogif_reg_write(0x36,0x8000); + hal_analogif_reg_write(0x37,0x1000); + hal_analogif_reg_write(0x31,0xfd31); + REG(0xd0350248) = 0X80C00000; + hal_analogif_reg_write(0xC,0x3790); +} + +void bt_change_to_iic(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + + hal_iomux_set_analog_i2c(); +} + +void bt_change_to_uart0(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + + hal_iomux_set_uart0(); +} + +void app_switch_i2c_uart(APP_KEY_STATUS *status, void *param) +{ + static uint32_t flag = 1; + + TRACE(2,"[%s] flag = %d",__func__, flag); + if(flag) + { + bt_change_to_iic(NULL, NULL); + } + else + { + bt_change_to_uart0(NULL, NULL); + } + flag = !flag; +} + +void test_power_off(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"app_power_off\n"); +} + +extern APP_KEY_STATUS bt_key; + +void test_bt_key(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + if(bt_key.code == 0xff) + { + bt_key.code = status->code; + bt_key.event = status->event; + OS_NotifyEvm(); + } +} + +#ifdef __APP_TEST_SDMMC__ +#include "app_sdmmc.h" + +#define SD_BUF_SIZE (10) +uint8_t sd_buf[SD_BUF_SIZE]={0,1,2,3,4,5,6,7,8,9}; + +void test_sd_card() +{ + sd_open(); + + dump_data2sd(APP_SDMMC_DUMP_OPEN, NULL , 0); + dump_data2sd(APP_SDMMC_DUMP_WRITE,sd_buf, SD_BUF_SIZE); + dump_data2sd(APP_SDMMC_DUMP_CLOSE, NULL, 0); +} +#endif + +#ifdef APP_TEST_AUDIO +extern void adc_looptester(bool on, enum AUD_IO_PATH_T input_path, enum AUD_SAMPRATE_T sample_rate); +void test_codec_loop(APP_KEY_STATUS *status, void *param) +{ + audio_buffer_init(); + adc_looptester(true, AUD_INPUT_PATH_MAINMIC, AUD_SAMPRATE_8000); +} + +#ifdef ANC_APP +void test_anc(APP_KEY_STATUS *status, void *param) +{ + anc_usb_app((bool)param); +} + +void test_usb_audio(APP_KEY_STATUS *status, void *param) +{ + usb_audio_app((bool)param); + //dualadc_audio_app((bool)param); +} +#endif +#endif + +void bt_change_to_jlink(APP_KEY_STATUS *status, void *param) +{ + hal_iomux_set_jtag(); + + hal_cmu_jtag_clock_enable(); + +} + +void bt_enable_tports(void) +{ + hal_iomux_set_bt_tport(); + bt_drv_bt_tport_type_config(); +} + +#ifdef APP_TEST_AUDIO +extern void da_tester(uint8_t on); +void bt_test_dsp_process(APP_KEY_STATUS *status, void *param) +{ + da_tester(1); +} +#endif +#define MENU_TITLE_MAX_SIZE (50) +APP_KEY_HANDLE app_testcase[] = { +#if defined(APP_TEST_AUDIO) && defined(ANC_APP) + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_UP},"USB AUDIO TEST OFF",test_usb_audio, (void *)0}, + {{APP_KEY_CODE_FN5,APP_KEY_EVENT_UP},"USB AUDIO TEST ON",test_usb_audio, (void *)1}, + {{APP_KEY_CODE_FN3,APP_KEY_EVENT_UP},"ANC TEST OFF",test_anc, (void *)0}, + {{APP_KEY_CODE_FN6,APP_KEY_EVENT_UP},"ANC TEST ON",test_anc, (void *)1}, +#else +#ifdef APP_TEST_AUDIO + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_LONGPRESS},"LONGPRESS: test_codec_loop",test_codec_loop, NULL}, +#endif + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_UP},"bt_signaling_test",bt_signaling_test, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_UP},"bt gogogogo" ,bt_stack_test, NULL}, + {{APP_KEY_CODE_FN3,APP_KEY_EVENT_UP},"bt change to 104m",bt_test_104m, NULL}, + {{APP_KEY_CODE_FN4,APP_KEY_EVENT_UP},"ble test mode" ,bt_ble_test, NULL}, +#ifdef APP_TEST_AUDIO + {{APP_KEY_CODE_FN5,APP_KEY_EVENT_UP},"dsp eq test" ,bt_test_dsp_process, NULL}, +#endif + {{APP_KEY_CODE_FN5,APP_KEY_EVENT_LONGPRESS},"LONGPRESS: bt volume up key" ,test_bt_key, NULL}, + + {{APP_KEY_CODE_FN6,APP_KEY_EVENT_UP},"bt volume down key" ,test_bt_key, NULL}, + {{APP_KEY_CODE_FN6,APP_KEY_EVENT_LONGPRESS},"LONGPRESS: bt volume down key" ,test_bt_key, NULL}, + + {{APP_KEY_CODE_FN7,APP_KEY_EVENT_CLICK},"bt function key" ,test_bt_key, NULL}, + {{APP_KEY_CODE_FN7,APP_KEY_EVENT_DOUBLECLICK},"DOUBLECLICK: bt function key" ,test_bt_key, NULL}, + {{APP_KEY_CODE_FN7,APP_KEY_EVENT_LONGPRESS},"LONGPRESS: bt function key" ,test_bt_key, NULL}, + + {{APP_KEY_CODE_FN8,APP_KEY_EVENT_UP},"open jlink" ,bt_change_to_jlink, NULL}, + {{APP_KEY_CODE_FN9,APP_KEY_EVENT_UP},"iic_map2_P3_0" ,bt_change_to_iic, NULL}, + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_LONGPRESS},"LONGPRESS: power off" ,test_power_off, NULL}, +#endif // !(APP_TEST_AUDIO && ANC_APP) + {{0xff, APP_KEY_EVENT_NONE}, NULL, (uint32_t)NULL, 0}, +}; + +int app_testcase_disp_menu(APP_KEY_HANDLE* testcase, bool printall) +{ + char buf[MENU_TITLE_MAX_SIZE+1]; + if (strlen(testcase->string)>(MENU_TITLE_MAX_SIZE-15)){ + TRACE(0,"string too long, please check again\n"); + return -1; + } + + if (printall){ + memset(buf, '-', sizeof(buf)-3); + buf[0] = '|'; + buf[MENU_TITLE_MAX_SIZE-3] = '|'; + buf[MENU_TITLE_MAX_SIZE-2] = '\r'; + buf[MENU_TITLE_MAX_SIZE-1] = '\n'; + buf[MENU_TITLE_MAX_SIZE] = '\0'; + TRACE(1,"%s", buf); + osDelay(1); + } + + do{ + snprintf(buf, sizeof(buf), "| (0x%X)%s", testcase->key_status.code, testcase->string); + memset(buf+strlen(buf), ' ', sizeof(buf)-strlen(buf)-3); + buf[MENU_TITLE_MAX_SIZE-3] = '|'; + buf[MENU_TITLE_MAX_SIZE-2] = '\r'; + buf[MENU_TITLE_MAX_SIZE-1] = '\n'; + buf[MENU_TITLE_MAX_SIZE] = '\0'; + TRACE(1,"%s", buf); + testcase++; + }while(testcase->key_status.code != 0xff && printall); + + if (printall){ + memset(buf, '-', sizeof(buf)-3); + buf[0] = '|'; + buf[MENU_TITLE_MAX_SIZE-3] = '|'; + buf[MENU_TITLE_MAX_SIZE-2] = '\r'; + buf[MENU_TITLE_MAX_SIZE-1] = '\n'; + buf[MENU_TITLE_MAX_SIZE] = '\0'; + TRACE(1,"%s", buf); + osDelay(1); + } + + return 0; +} + +int app_testcase_key_response(APP_MESSAGE_BODY *msg_body) +{ + uint8_t i = 0; + APP_KEY_STATUS key_status; + + APP_KEY_GET_CODE(msg_body->message_id, key_status.code); + APP_KEY_GET_EVENT(msg_body->message_id, key_status.event); + + if ((key_status.code)>(sizeof(app_testcase)/sizeof(APP_KEY_HANDLE))) + return -1; + + for (i=0; i<(sizeof(app_testcase)/sizeof(APP_KEY_HANDLE)); i++){ + if (app_testcase[i].key_status.code == key_status.code && (app_testcase[i].key_status.event == key_status.event)) + break; + } + + if (i>=(sizeof(app_testcase)/sizeof(APP_KEY_HANDLE))) + return -1; + + if (app_testcase[i].function != (uint32_t)NULL){ + if (app_testcase[i].string != (uint32_t)NULL) + app_testcase_disp_menu(&app_testcase[i],0); + ((APP_KEY_HANDLE_CB_T)app_testcase[i].function)(&key_status,app_testcase[i].param); + } + + return 0; +} + +void app_test_init(void) +{ + uint8_t i = 0; + TRACE(1,"%s",__func__); + for (i=0; i<(sizeof(app_testcase)/sizeof(APP_KEY_HANDLE)); i++){ + app_key_handle_registration(&app_testcase[i]); + } + app_testcase_disp_menu(app_testcase, 1); + +#if defined(APP_TEST_AUDIO) && defined(ANC_APP) + app_anc_usb_init(); +#endif +} diff --git a/apps/mic/Makefile b/apps/mic/Makefile new file mode 100644 index 0000000..4df152e --- /dev/null +++ b/apps/mic/Makefile @@ -0,0 +1,59 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y += \ + -Iservices/audio_process \ + -Iservices/app_ai/inc \ + -Iservices/bt_app \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + $(BT_IF_INCLUDES) \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iservices/multimedia/audio/process/resample/include \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/audio/process/drc/include \ + -Iservices/multimedia/audio/process/anc/include\ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/factory_section \ + -Iservices/nv_section/include \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iapps/key \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/audioplayers/rbplay \ + -Iapps/factory \ + -Iservices/ble_app \ + -Iservices/tws/inc \ + -Iutils/hwtimer_list \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/ble_app/app_tws \ + -Iapps/wings \ + -Iapps/battery \ + -Iapps/ota \ + -Iapps/mic \ + -Ithirdparty/audio_codec_lib/liblhdc-dec/inc \ + -Ithirdparty/cyberon/cspotter/src \ + -Iutils/crc32 \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/bt_app/a2dp_codecs/include + diff --git a/apps/mic/app_mic.cpp b/apps/mic/app_mic.cpp new file mode 100644 index 0000000..aadf058 --- /dev/null +++ b/apps/mic/app_mic.cpp @@ -0,0 +1,254 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +//#include "mbed.h" +#include +#include + +#include "cmsis_os.h" +#include "tgt_hardware.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_chipid.h" +#include "analog.h" +#include "app_bt_stream.h" +#include "app_overlay.h" +#include "app_audio.h" +#include "app_utils.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "hal_codec.h" +#include "apps.h" + +#include "app_ring_merge.h" + +#include "bt_drv.h" +#include "bt_xtal_sync.h" +#include "besbt.h" +#include "app_bt_func.h" +#include "app_mic.h" + + +#include "app_thread.h" +#include "cqueue.h" +#include "btapp.h" +#include "app_bt_media_manager.h" +#include "string.h" +#include "hal_location.h" +#include "hal_codec.h" +#include "hal_sleep.h" +#include "app_hfp.h" + +extern bool app_hfp_siri_is_active(void); +extern int a2dp_volume_2_level_convert(uint8_t vol); +extern bool mic_is_already_on; + +typedef enum { + MIC_EVENT_START, + MIC_EVENT_STOP, + MIC_EVENT_CHECK, +}MIC_EVENT_TYPE; + +static MIC_APP_TYPE current_mictype = MIC_APP_NONE; +static struct AF_STREAM_CONFIG_T mic_config[MIC_APP_MAX]; +osMutexId app_mic_mutex_id = NULL; +osMutexDef(app_mic_mutex); + + +// flag of is first mic date, if true ,will delete to avoid POP voice +bool first_mic_in = false; + +static int internal_mic_start(MIC_APP_TYPE new_mictype) +{ + TRACE(1,"MIC_EVENT_START,current_mictype=%d",current_mictype); + assert(new_mictype != MIC_APP_NONE); + if (current_mictype != MIC_APP_NONE) { + TRACE(0,"MIC START ERROR################"); + return false; + } + if (new_mictype == MIC_APP_SOC_CALL) + { + if (btapp_hfp_get_call_state() || app_hfp_siri_is_active()) + { + TRACE(2,"[%s] tws_mic_start_telephone_call: %d", __func__, mic_config[new_mictype].sample_rate); + if (mic_config[new_mictype].data_ptr != NULL) + { + } + else + { + TRACE(1,"[%s] Warning sco play not started",__func__); + } + current_mictype = MIC_APP_SOC_CALL; + } + } + else if (new_mictype == MIC_APP_SPEECH_RECO) + { + } + else if (new_mictype == MIC_APP_CSPOTTER) + { + first_mic_in = true; + current_mictype = MIC_APP_CSPOTTER; + } + else if (new_mictype == MIC_APP_MICRECORD) + { + current_mictype = MIC_APP_MICRECORD; + } + else if (new_mictype == MIC_APP_OTHER) + { + TRACE(0,"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + } + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &mic_config[new_mictype]); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + return false; +} + +static int internal_mic_stop(MIC_APP_TYPE new_mictype) +{ + TRACE(1,"MIC_EVENT_STOP,current_mictype=%d",current_mictype); + //assert(currentMicStauts == currentStatus); + if (new_mictype != current_mictype) { + TRACE(0,"MIC STOP ERROR ################"); + return false; + } + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + first_mic_in = false; + current_mictype = MIC_APP_NONE; + app_sysfreq_req(APP_SYSFREQ_USER_APP_3, APP_SYSFREQ_32K); + return true; +} + +static int app_mic_process(APP_MESSAGE_BODY *msg_body) +{ + MIC_EVENT_TYPE mic_event = (MIC_EVENT_TYPE)msg_body->message_id; + MIC_APP_TYPE new_mictype = (MIC_APP_TYPE)msg_body->message_ptr; + int ret = -1; + TRACE(4,"%s mic_event:%d new_mictype:%d current_mictype:%d",__func__,mic_event, new_mictype, current_mictype); + + osMutexWait(app_mic_mutex_id, osWaitForever); + if (mic_event == MIC_EVENT_START) + ret = internal_mic_start(new_mictype); + else if (mic_event == MIC_EVENT_STOP) + ret = internal_mic_stop(new_mictype); + else if (mic_event == MIC_EVENT_CHECK) + { + TRACE(1,"MIC_EVENT_CHECK,current_mictype=%d",current_mictype); + if (current_mictype != new_mictype) + { + if (current_mictype != MIC_APP_NONE) + internal_mic_stop(current_mictype); + if (new_mictype != MIC_APP_CSPOTTER) + internal_mic_start(new_mictype); + ret = 0; + } + } + else + assert(0); + osMutexRelease(app_mic_mutex_id); + return ret; +} + +void app_mic_init() +{ + app_mic_mutex_id = osMutexCreate((osMutex(app_mic_mutex))); + app_set_threadhandle(APP_MODUAL_MIC, app_mic_process); +} + +int app_mic_register(MIC_APP_TYPE mic_type, struct AF_STREAM_CONFIG_T *newStream) +{ + TRACE(2,"app_mic_registration mic_type:%d,newStream=%p\n",mic_type,newStream); + if (mic_type > MIC_APP_NONE && mic_type < MIC_APP_MAX) + { + osMutexWait(app_mic_mutex_id, osWaitForever); + if (memcmp(&mic_config[mic_type],newStream,sizeof(struct AF_STREAM_CONFIG_T)) != 0) + { + TRACE(0,"app_mic_registration Warning mic stream config changed!!!"); + } + memcpy(&mic_config[mic_type],newStream,sizeof(struct AF_STREAM_CONFIG_T)); + osMutexRelease(app_mic_mutex_id); + return 0; + } + return -1; +} + +int app_mic_deregister(MIC_APP_TYPE mic_type) +{ + TRACE(1,"app_mic_deregister mic_type:%d\n",mic_type); + if (mic_type > MIC_APP_NONE && mic_type < MIC_APP_MAX) + { + osMutexWait(app_mic_mutex_id, osWaitForever); + memset(&mic_config[mic_type],0,sizeof(struct AF_STREAM_CONFIG_T)); + osMutexRelease(app_mic_mutex_id); + return 0; + } + return -1; +} + +bool app_mic_is_registed(MIC_APP_TYPE mic_type) +{ + TRACE(1,"app_mic_is_registed mic_type:%d\n",mic_type); + bool ret = false; + if (mic_type > MIC_APP_NONE && mic_type < MIC_APP_MAX) + { + osMutexWait(app_mic_mutex_id, osWaitForever); + ret = mic_config[mic_type].data_ptr != NULL; + osMutexRelease(app_mic_mutex_id); + } + return ret; +} + +bool app_mic_start(MIC_APP_TYPE mic_type) +{ + APP_MESSAGE_BLOCK msg; + msg.mod_id = APP_MODUAL_MIC; + msg.msg_body.message_id = MIC_EVENT_START; + msg.msg_body.message_ptr = mic_type; + app_mailbox_put(&msg); + return true; +} + +bool app_mic_stop(MIC_APP_TYPE mic_type) +{ + APP_MESSAGE_BLOCK msg; + msg.mod_id = APP_MODUAL_MIC; + msg.msg_body.message_id = MIC_EVENT_STOP; + msg.msg_body.message_ptr = mic_type; + app_mailbox_put(&msg); + return true; +} + +void app_mic_check(MIC_APP_TYPE mic_type) +{ + APP_MESSAGE_BLOCK msg; + msg.mod_id = APP_MODUAL_MIC; + msg.msg_body.message_id = MIC_EVENT_CHECK; + msg.msg_body.message_ptr = mic_type; + app_mailbox_put(&msg); +} + +MIC_APP_TYPE app_mic_status(void) +{ + MIC_APP_TYPE ret; + osMutexWait(app_mic_mutex_id, osWaitForever); + ret= current_mictype; + osMutexRelease(app_mic_mutex_id); + return ret; +} + diff --git a/apps/mic/app_mic.h b/apps/mic/app_mic.h new file mode 100644 index 0000000..67551d8 --- /dev/null +++ b/apps/mic/app_mic.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_MIC_H__ +#define __APP_MIC_H__ + +#include +#include + +#include "cmsis_os.h" +#include "tgt_hardware.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "hal_trace.h" +#include "app_bt_stream.h" +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +typedef enum { + MIC_APP_NONE, + MIC_APP_SOC_CALL, + MIC_APP_SPEECH_RECO, + MIC_APP_CSPOTTER, + MIC_APP_MICRECORD, + MIC_APP_OTHER, + MIC_APP_MAX, +}MIC_APP_TYPE; + +void app_mic_init(); + +bool app_mic_start(MIC_APP_TYPE mic_type); + +bool app_mic_stop(MIC_APP_TYPE mic_type); + +int app_mic_register(MIC_APP_TYPE mic_type, struct AF_STREAM_CONFIG_T *newStream); + +int app_mic_deregister(MIC_APP_TYPE mic_type); + +bool app_mic_is_registed(MIC_APP_TYPE mic_type); + +void app_mic_check(MIC_APP_TYPE mic_type); + +MIC_APP_TYPE app_mic_status(void); + +#ifdef __cplusplus +} +#endif + +#endif//__APP_MIC_H__ diff --git a/apps/pwl/Makefile b/apps/pwl/Makefile new file mode 100644 index 0000000..10c01ca --- /dev/null +++ b/apps/pwl/Makefile @@ -0,0 +1,8 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y += -Iplatform/drivers/ana diff --git a/apps/pwl/app_pwl.cpp b/apps/pwl/app_pwl.cpp new file mode 100644 index 0000000..2e657c9 --- /dev/null +++ b/apps/pwl/app_pwl.cpp @@ -0,0 +1,185 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "tgt_hardware.h" +#include "hal_gpio.h" +#include "hal_iomux.h" +#include "hal_trace.h" +#include "pmu.h" +#include "app_pwl.h" +#include "string.h" + +#define APP_PWL_TRACE(s,...) +//TRACE(s, ##__VA_ARGS__) + +#if (CFG_HW_PLW_NUM > 0) +static void app_pwl_timehandler(void const *param); + +osTimerDef (APP_PWL_TIMER0, app_pwl_timehandler); // define timers +#if (CFG_HW_PLW_NUM == 2) +osTimerDef (APP_PWL_TIMER1, app_pwl_timehandler); +#endif + +struct APP_PWL_T { + enum APP_PWL_ID_T id; + struct APP_PWL_CFG_T config; + uint8_t partidx; + osTimerId timer; +}; + +static struct APP_PWL_T app_pwl[APP_PWL_ID_QTY]; + +static void app_pwl_timehandler(void const *param) +{ + struct APP_PWL_T *pwl = (struct APP_PWL_T *)param; + struct APP_PWL_CFG_T *cfg = &(pwl->config); + APP_PWL_TRACE(2,"%s %x",__func__, param); + + osTimerStop(pwl->timer); + + pwl->partidx++; + if (cfg->periodic){ + if (pwl->partidx >= cfg->parttotal){ + pwl->partidx = 0; + } + }else{ + if (pwl->partidx >= cfg->parttotal){ + return; + } + } + + APP_PWL_TRACE(3,"idx:%d pin:%d lvl:%d", pwl->partidx, cfg_hw_pinmux_pwl[pwl->id].pin, cfg->part[pwl->partidx].level); + if(!cfg->part[pwl->partidx].level){ +#if defined(__PMU_VIO_DYNAMIC_CTRL_MODE__) + pmu_viorise_req(pwl->id == APP_PWL_ID_0 ? PMU_VIORISE_REQ_USER_PWL0 : PMU_VIORISE_REQ_USER_PWL1, true); +#endif + hal_gpio_pin_set((enum HAL_GPIO_PIN_T)cfg_hw_pinmux_pwl[pwl->id].pin); + }else{ + hal_gpio_pin_clr((enum HAL_GPIO_PIN_T)cfg_hw_pinmux_pwl[pwl->id].pin); +#if defined(__PMU_VIO_DYNAMIC_CTRL_MODE__) + pmu_viorise_req(pwl->id == APP_PWL_ID_0 ? PMU_VIORISE_REQ_USER_PWL0 : PMU_VIORISE_REQ_USER_PWL1, false); +#endif + } + osTimerStart(pwl->timer, cfg->part[pwl->partidx].time); +} +#endif + +int app_pwl_open(void) +{ +#if (CFG_HW_PLW_NUM > 0) + uint8_t i; + APP_PWL_TRACE(1,"%s",__func__); + for (i=0;i 0) + struct APP_PWL_T *pwl = NULL; + struct APP_PWL_CFG_T *cfg = NULL; + + + if (id >= APP_PWL_ID_QTY) { + return -1; + } + + APP_PWL_TRACE(2,"%s %d",__func__, id); + + pwl = &app_pwl[id]; + cfg = &(pwl->config); + + if (pwl->id == APP_PWL_ID_QTY){ + return -1; + } + + pwl->partidx = 0; + if (pwl->partidx >= cfg->parttotal){ + return -1; + } + + osTimerStop(pwl->timer); + + APP_PWL_TRACE(3,"idx:%d pin:%d lvl:%d", pwl->partidx, cfg_hw_pinmux_pwl[pwl->id].pin, cfg->part[pwl->partidx].level); + if(!cfg->part[pwl->partidx].level){ +#if defined(__PMU_VIO_DYNAMIC_CTRL_MODE__) + pmu_viorise_req(pwl->id == APP_PWL_ID_0 ? PMU_VIORISE_REQ_USER_PWL0 : PMU_VIORISE_REQ_USER_PWL1, false); +#endif + hal_gpio_pin_set((enum HAL_GPIO_PIN_T)cfg_hw_pinmux_pwl[pwl->id].pin); + }else{ + hal_gpio_pin_clr((enum HAL_GPIO_PIN_T)cfg_hw_pinmux_pwl[pwl->id].pin); +#if defined(__PMU_VIO_DYNAMIC_CTRL_MODE__) + pmu_viorise_req(pwl->id == APP_PWL_ID_0 ? PMU_VIORISE_REQ_USER_PWL0 : PMU_VIORISE_REQ_USER_PWL1, false); +#endif + } + osTimerStart(pwl->timer, cfg->part[pwl->partidx].time); +#endif + return 0; +} + +int app_pwl_setup(enum APP_PWL_ID_T id, struct APP_PWL_CFG_T *cfg) +{ +#if (CFG_HW_PLW_NUM > 0) + if (cfg == NULL || id >= APP_PWL_ID_QTY) { + return -1; + } + APP_PWL_TRACE(2,"%s %d",__func__, id); + + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)cfg_hw_pinmux_pwl[id].pin, HAL_GPIO_DIR_OUT, cfg->startlevel?0:1); + app_pwl[id].id = id; + memcpy(&(app_pwl[id].config), cfg, sizeof(struct APP_PWL_CFG_T)); + + osTimerStop(app_pwl[id].timer); +#endif + return 0; +} + +int app_pwl_stop(enum APP_PWL_ID_T id) +{ +#if (CFG_HW_PLW_NUM > 0) + if (id >= APP_PWL_ID_QTY) { + return -1; + } + + osTimerStop(app_pwl[id].timer); + hal_gpio_pin_set((enum HAL_GPIO_PIN_T)cfg_hw_pinmux_pwl[id].pin); +#endif + return 0; +} + +int app_pwl_close(void) +{ +#if (CFG_HW_PLW_NUM > 0) + uint8_t i; + for (i=0;id_name, len); + } + closedir(d); + TRACE(0,"--------root end-------\n"); +} + +extern uint32_t play_wav_file(char *file_path); +extern uint32_t stop_wav_file(void); +extern uint32_t wav_file_audio_more_data(uint8_t *buf, uint32_t len); + +void test_wave_play(bool on) +{ + struct AF_STREAM_CONFIG_T stream_cfg; + uint32_t reallen; + uint32_t totalreadsize; + uint32_t stime, etime; + + char wave[] = "/sd/test_music.wav"; + + static bool isRun = false; + + if (isRun==on) + return; + else + isRun=on; + + + TRACE(2,"%s %d\n", __func__, on); + memset(&stream_cfg, 0, sizeof(stream_cfg)); + if (on){ + play_wav_file(wave); + + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; + stream_cfg.sample_rate = AUD_SAMPRATE_48000; + + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.vol = 0x03; + + stream_cfg.handler = wav_file_audio_more_data; + stream_cfg.data_ptr = app_test_playback_buff; + stream_cfg.data_size = APP_TEST_PLAYBACK_BUFF_SIZE; + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + }else{ + stop_wav_file(); + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + } + + return; +} + + +FIL pcm_fil; +FRESULT pcm_res; +UINT pcm_num; +uint32_t pcm_save_more_data(uint8_t *buf, uint32_t len) +{ +// TRACE(2,"%s\n len:%d", __func__, len); + + audio_buffer_set_stereo2mono_16bits(buf, len, 1); + pcm_res = f_write(&pcm_fil,(uint8_t *)buf,len>>1,&pcm_num); + if(pcm_res != FR_OK) + { + TRACE(2,"[%s]:error-->res = %d", __func__, pcm_res); + } + return 0; +} + +void ad_tester(bool run) +{ + char filename[] = "/sd/audio_dump.bin"; + + struct AF_STREAM_CONFIG_T stream_cfg; + + TRACE(2,"%s %d\n", __func__, run); + + if (run){ + memset(&stream_cfg, 0, sizeof(stream_cfg)); + pcm_res = f_open(&pcm_fil,"test2.bin",FA_CREATE_ALWAYS | FA_WRITE); + if (pcm_res) { + TRACE(2,"[%s]:Cannot creat test2.bin...%d",__func__, pcm_res); + return; + } + + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; + stream_cfg.sample_rate = AUD_SAMPRATE_48000; + + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; + stream_cfg.vol = 0x03; + + stream_cfg.handler = pcm_save_more_data; + stream_cfg.data_ptr = app_test_playback_buff; + stream_cfg.data_size = APP_TEST_PLAYBACK_BUFF_SIZE; + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + }else{ + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + osDelay(1000); + + f_close(&pcm_fil); + } +} + +// if dump data into sd, buffer length should make sd card speed enough +// Bench32.exe can test sd card speed in PC, then make sure bufer length, buffer length < 16k(sd driver) +void dump_data2sd(enum APP_SDMMC_DUMP_T opt, uint8_t *buf, uint32_t len) +{ + static FIL sd_fil; + FRESULT res; + + + ASSERT(opt < APP_SDMMC_DUMP_NUM, "[%s] opt(%d) >= APP_SDMMC_DUMP_NUM", __func__, opt); + + if(opt == APP_SDMMC_DUMP_OPEN) + { +// res = f_open(&sd_fil,"dump.bin",FA_CREATE_ALWAYS | FA_WRITE); + res = f_open(&sd_fil,"test.txt",FA_READ); + +// ASSERT(pcm_res == FR_OK,"[%s]:Cannot creat dump.bin, res = %d",__func__, pcm_res); + } + if(opt == APP_SDMMC_DUMP_READ) + { + res = f_read(&sd_fil, buf, len, &pcm_num); + +// ASSERT(pcm_res == FR_OK,"[%s]:Cannot creat dump.bin, res = %d",__func__, pcm_res); + } + else if(opt == APP_SDMMC_DUMP_WRITE) + { + res = f_write(&sd_fil, buf, len, &pcm_num); + +// ASSERT(pcm_res == FR_OK,"[%s]:Write dump.bin failed, res = %d", __func__, pcm_res); + } + else if(opt == APP_SDMMC_DUMP_CLOSE) + { + res = f_close(&sd_fil); + } + + if(res == FR_OK) + { + TRACE(3,"[%s] SUCESS: opt = %d, res = %d",__func__, opt, res); + } + else + { + TRACE(3,"[%s] ERROR: opt = %d, res = %d",__func__, opt, res); + } +} diff --git a/apps/sdmmc/app_sdmmc.h b/apps/sdmmc/app_sdmmc.h new file mode 100644 index 0000000..01dced3 --- /dev/null +++ b/apps/sdmmc/app_sdmmc.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_SDMMC_H__ +#define __APP_SDMMC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum APP_SDMMC_DUMP_T{ + APP_SDMMC_DUMP_OPEN = 0, + APP_SDMMC_DUMP_READ, + APP_SDMMC_DUMP_WRITE, + APP_SDMMC_DUMP_CLOSE, + APP_SDMMC_DUMP_NUM +}; + +int sd_open(); + +void dump_data2sd(enum APP_SDMMC_DUMP_T opt, uint8_t *buf, uint32_t len); + +#ifdef __cplusplus + } +#endif + +#endif//__FMDEC_H__ diff --git a/apps/usbaudio/Makefile b/apps/usbaudio/Makefile new file mode 100644 index 0000000..64ee009 --- /dev/null +++ b/apps/usbaudio/Makefile @@ -0,0 +1,193 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) + +obj-y += ../../tests/anc_usb/usb_audio_app.c +obj-y += ../../tests/anc_usb/safe_queue.c +obj-y += ../../tests/anc_usb/memutils.c + +ifeq ($(USB_AUDIO_SPEECH),1) +obj-y += ../../tests/anc_usb/speech_process.c +endif + +ifeq ($(ANC_APP),1) +obj-y += ../../tests/anc_usb/anc_usb_app.c +endif + +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + + +ccflags-y += \ + -Iutils/boot_struct \ + -Iutils/crc32 \ + -Iutils/hexdump \ + -Iutils/hwtimer_list \ + -Itests/programmer \ + -Iplatform/drivers/usb/usb_dev/inc \ + -Iplatform/drivers/ana \ + -Iservices/multimedia/audio/process/adp/include \ + -Iservices/multimedia/audio/process/anc/include \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/audio/process/resample/include \ + -Iservices/multimedia/speech/inc \ + -Iservices/audio_process \ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/include \ + -Iservices/overlay \ + -Itests/anc_usb + +CFLAGS_usbaudio_entry.o += -DUSB_AUDIO_APP +CFLAGS_usb_audio_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) +CFLAGS_adda_loop_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) + +ANC_USB_CFG_FLAGS := + +# ANC option +ifeq ($(ANC_APP),1) +ANC_USB_CFG_FLAGS += -DANC_APP +endif + +# USB audio option +ifeq ($(USB_AUDIO_APP),1) +ANC_USB_CFG_FLAGS += -DUSB_AUDIO_APP +endif + +ifeq ($(USB_HIGH_SPEED),1) +ANC_USB_CFG_FLAGS += -DUSB_HIGH_SPEED +endif + +ifeq ($(AUDIO_RESAMPLE),1) +ANC_USB_CFG_FLAGS += -D__AUDIO_RESAMPLE__ +endif + +ifeq ($(ADC_CH_SEP_BUFF),1) +ANC_USB_CFG_FLAGS += -DADC_CH_SEP_BUFF +endif + +include platform/drivers/usb/usb_dev/uaud_cfg_flags.mk + +platform/drivers/usb/usb_dev/uaud_cfg_flags.mk: ; + +ANC_USB_CFG_FLAGS += $(UAUD_CFG_FLAGS) + +# USB audio configuration +ifeq ($(USB_AUDIO_DYN_CFG),1) +ifneq ($(AUDIO_RESAMPLE),1) +SW_CAPTURE_RESAMPLE ?= 1 +endif +endif + +ifeq ($(AUDIO_PLAYBACK_24BIT),1) +ANC_USB_CFG_FLAGS += -DAUDIO_PLAYBACK_24BIT +endif + +# DSD configuration +ifeq ($(HW_FIR_DSD_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__HW_FIR_DSD_PROCESS__ +endif + +# EQ configuration +ifeq ($(HW_FIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__HW_FIR_EQ_PROCESS__ +endif + +ifeq ($(HW_IIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__HW_IIR_EQ_PROCESS__ +endif + +ifeq ($(SW_IIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__SW_IIR_EQ_PROCESS__ +endif + +ifeq ($(HW_DAC_IIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__HW_DAC_IIR_EQ_PROCESS__ +endif + +ifeq ($(SW_CAPTURE_RESAMPLE),1) +ANC_USB_CFG_FLAGS += -DSW_CAPTURE_RESAMPLE +endif + +CFLAGS_usbaudio_entry.o += $(ANC_USB_CFG_FLAGS) +CFLAGS_usb_audio_app.o += $(ANC_USB_CFG_FLAGS) +CFLAGS_anc_usb_app.o += $(ANC_USB_CFG_FLAGS) + +ifeq ($(ANC_KEY_DOUBLE_CLICK_ON_OFF),1) +CFLAGS_anc_usb_app.o += -DANC_KEY_DOUBLE_CLICK_ON_OFF +endif + +ifeq ($(ANC_FF_ENABLED),1) +CFLAGS_anc_usb_app.o += -DANC_FF_ENABLED +endif + +ifeq ($(ANC_FB_ENABLED),1) +CFLAGS_anc_usb_app.o += -DANC_FB_ENABLED +endif + +ifeq ($(AUDIO_SECTION_SUPPT),1) +CFLAGS_anc_usb_app.o += -D__AUDIO_SECTION_SUPPT__ +endif + +ifeq ($(ANC_INIT_OFF),1) +CFLAGS_anc_usb_app.o += -DANC_INIT_OFF +endif + +ifeq ($(PC_CMD_UART),1) +CFLAGS_usbaudio_entry.o += -D__PC_CMD_UART__ +endif + +ifeq ($(DELAY_STREAM_OPEN),1) +CFLAGS_usb_audio_app.o += -DDELAY_STREAM_OPEN +endif + +ifeq ($(NOISE_GATING),1) +CFLAGS_usb_audio_app.o += -DNOISE_GATING +endif + +ifeq ($(NOISE_REDUCTION),1) +CFLAGS_usb_audio_app.o += -DNOISE_REDUCTION +endif + +ifeq ($(ANC_L_R_MISALIGN_WORKAROUND),1) +CFLAGS_usb_audio_app.o += -DANC_L_R_MISALIGN_WORKAROUND +endif + +ifeq ($(ANDROID_ACCESSORY_SPEC),1) +CFLAGS_usb_audio_app.o += -DANDROID_ACCESSORY_SPEC +ifeq ($(ANDROID_VOICE_CMD_KEY),1) +CFLAGS_usb_audio_app.o += -DANDROID_VOICE_CMD_KEY +endif +endif + +ifeq ($(DUAL_AUX_MIC_MORE_FILTER),1) +CFLAGS_usb_audio_app.o += -DDUAL_AUX_MIC_MORE_FILTER +endif + +ifeq ($(FREQ_RESP_EQ),1) +CFLAGS_usb_audio_app.o += -DFREQ_RESP_EQ +endif + +ifeq ($(KEEP_SAME_LATENCY),1) +CFLAGS_usb_audio_app.o += -DKEEP_SAME_LATENCY +CFLAGS_speech_process.o += -DKEEP_SAME_LATENCY +endif + +ifeq ($(USB_AUDIO_PWRKEY_TEST),1) +CFLAGS_usb_audio_app.o += -DUSB_AUDIO_PWRKEY_TEST +endif + +ifeq ($(AUDIO_RESAMPLE),1) +# If neither best1000 nor best2000 +ifeq ($(filter best1000 best2000,$(CHIP)),) +PLL_TUNE_SAMPLE_RATE ?= 1 +endif +ifeq ($(PLL_TUNE_SAMPLE_RATE),1) +CFLAGS_usb_audio_app.o += -DPLL_TUNE_SAMPLE_RATE +endif +endif + +ifeq ($(USB_AUDIO_SPEECH),1) +CFLAGS_usbaudio_entry.o += -DUSB_AUDIO_SPEECH +CFLAGS_usb_audio_app.o += -DUSB_AUDIO_SPEECH +endif diff --git a/apps/usbaudio/usbaudio_entry.c b/apps/usbaudio/usbaudio_entry.c new file mode 100644 index 0000000..3afc6bf --- /dev/null +++ b/apps/usbaudio/usbaudio_entry.c @@ -0,0 +1,347 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include "hal_cmu.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_iomux.h" +#include "hal_dma.h" +#include "hal_key.h" +#include "hal_gpadc.h" +#include "hal_sleep.h" +#include "hal_sysfreq.h" +#include "cmsis.h" +#include "pmu.h" +#include "analog.h" +#include "string.h" +#include "hwtimer_list.h" +#include "audioflinger.h" +#if defined(ANC_APP) +#include "anc_usb_app.h" +#endif +#include "usb_audio_app.h" +#include "dualadc_audio_app.h" +#include "usb_audio_frm_defs.h" +#include "tgt_hardware.h" +#include "audio_process.h" + +#ifdef RTOS +#include "cmsis_os.h" +#endif +#ifdef __PC_CMD_UART__ +#include "hal_cmd.h" +#endif + +#ifdef USB_AUDIO_SPEECH +#define CODEC_BUFF_FRAME_NUM (2 * 16) +#define USB_BUFF_FRAME_NUM (CODEC_BUFF_FRAME_NUM * 2) +#else +#define CODEC_BUFF_FRAME_NUM 4 +#define USB_BUFF_FRAME_NUM 8 +#endif + +#if (CODEC_BUFF_FRAME_NUM >= USB_BUFF_FRAME_NUM) +#error "Codec buffer frame num should be less than usb buffer frame num (on the requirement of conflict ctrl)" +#endif + +#ifdef USB_AUDIO_DYN_CFG +#define USB_AUDIO_PLAYBACK_BUFF_SIZE NON_EXP_ALIGN(MAX_FRAME_SIZE_PLAYBACK * CODEC_BUFF_FRAME_NUM, DAC_BUFF_ALIGN) +#define USB_AUDIO_CAPTURE_BUFF_SIZE NON_EXP_ALIGN(MAX_FRAME_SIZE_CAPTURE * CODEC_BUFF_FRAME_NUM, ADC_BUFF_ALIGN) + +#define USB_AUDIO_RECV_BUFF_SIZE NON_EXP_ALIGN(MAX_FRAME_SIZE_RECV * USB_BUFF_FRAME_NUM, RECV_BUFF_ALIGN) +#define USB_AUDIO_SEND_BUFF_SIZE NON_EXP_ALIGN(MAX_FRAME_SIZE_SEND * USB_BUFF_FRAME_NUM, SEND_BUFF_ALIGN) + +#if defined(CHIP_BEST1000) +// FIR EQ is working on 16-bit +// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int16_t) +#define USB_AUDIO_FIR_EQ_BUFF_SIZE USB_AUDIO_PLAYBACK_BUFF_SIZE +#elif defined(CHIP_BEST2000) +// FIR EQ is working on 32-bit +// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int32_t) +#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE*2) +#elif defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) +// FIR EQ is working on 32-bit +// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int32_t) +#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE*2) +#endif + +#else +#define USB_AUDIO_PLAYBACK_BUFF_SIZE NON_EXP_ALIGN(FRAME_SIZE_PLAYBACK * CODEC_BUFF_FRAME_NUM, DAC_BUFF_ALIGN) +#define USB_AUDIO_CAPTURE_BUFF_SIZE NON_EXP_ALIGN(FRAME_SIZE_CAPTURE * CODEC_BUFF_FRAME_NUM, ADC_BUFF_ALIGN) + +#define USB_AUDIO_RECV_BUFF_SIZE NON_EXP_ALIGN(FRAME_SIZE_RECV * USB_BUFF_FRAME_NUM, RECV_BUFF_ALIGN) +#define USB_AUDIO_SEND_BUFF_SIZE NON_EXP_ALIGN(FRAME_SIZE_SEND * USB_BUFF_FRAME_NUM, SEND_BUFF_ALIGN) + +#if defined(CHIP_BEST1000) +// FIR EQ is working on 16-bit +#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE * sizeof(int16_t) / SAMPLE_SIZE_PLAYBACK) +#elif defined(CHIP_BEST2000) +// FIR EQ is working on 16-bit +#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE * sizeof(int32_t) / SAMPLE_SIZE_PLAYBACK) +#elif defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) +// FIR EQ is working on 16-bit +#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE * sizeof(int32_t) / SAMPLE_SIZE_PLAYBACK) +#endif +#endif + +#if (defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_))) && (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) +// Resample input buffer size should be (half_of_max_sample_num * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE). +// half_of_max_sample_num = 48000 / 1000 * CODEC_BUFF_FRAME_NUM / 2 * 48 / 44 +#define RESAMPLE_INPUT_BUFF_SIZE ALIGN(48000 / 1000 * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE * CODEC_BUFF_FRAME_NUM / 2 * 48 / 44, 4) +#else +#define RESAMPLE_INPUT_BUFF_SIZE 0 +#endif +// Resample history buffer size should be +// sizeof(struct RESAMPLE_CTRL_T) + ((SAMPLE_NUM + phase_coef_num) * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) +#define RESAMPLE_HISTORY_BUFF_SIZE (50 + (256 * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE)) +#define USB_AUDIO_RESAMPLE_BUFF_SIZE (RESAMPLE_INPUT_BUFF_SIZE + RESAMPLE_HISTORY_BUFF_SIZE) + +#define ALIGNED4 ALIGNED(4) + +#if defined(USB_AUDIO_APP) || defined(DUALADC_AUDIO_TEST) + +#ifdef AUDIO_ANC_FB_MC +static uint8_t ALIGNED4 playback_buff[USB_AUDIO_PLAYBACK_BUFF_SIZE * 9];//max 48->384 or 44.1->44.1*8; +#else +static uint8_t ALIGNED4 playback_buff[USB_AUDIO_PLAYBACK_BUFF_SIZE]; +#endif + +static uint8_t ALIGNED4 capture_buff[USB_AUDIO_CAPTURE_BUFF_SIZE]; + +#endif + +#ifdef USB_AUDIO_APP +#if defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) +static uint8_t ALIGNED4 eq_buff[USB_AUDIO_FIR_EQ_BUFF_SIZE+USB_AUDIO_IIR_EQ_BUFF_SIZE]; +#elif defined(__HW_FIR_EQ_PROCESS__) && !defined(__HW_IIR_EQ_PROCESS__) +static uint8_t ALIGNED4 eq_buff[USB_AUDIO_FIR_EQ_BUFF_SIZE]; +#elif !defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) +static uint8_t ALIGNED4 eq_buff[USB_AUDIO_IIR_EQ_BUFF_SIZE]; +#else +static uint8_t ALIGNED4 eq_buff[0]; +#endif + +#ifdef SW_CAPTURE_RESAMPLE +static uint8_t ALIGNED4 resample_buff[USB_AUDIO_RESAMPLE_BUFF_SIZE]; +#else +static uint8_t ALIGNED4 resample_buff[0]; +#endif + +static uint8_t ALIGNED4 recv_buff[USB_AUDIO_RECV_BUFF_SIZE]; +static uint8_t ALIGNED4 send_buff[USB_AUDIO_SEND_BUFF_SIZE]; +#endif + +#ifdef CFG_HW_KEY_LED_PIN +const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_key_led[1] = { + {CFG_HW_KEY_LED_PIN, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL}, +}; +#endif + +#ifdef CFG_MIC_KEY +extern void mic_key_open (void); +#endif + +static void uart_i2c_switch(void) +{ + static int flag = 0; + + flag ^= 1; + + if (flag) { + hal_iomux_set_analog_i2c(); + } else { + hal_iomux_set_uart0(); + } +} + +static int POSSIBLY_UNUSED key_event_process(uint32_t key_code, uint8_t key_event) +{ + TRACE(3,"%s: code=0x%X, event=%u", __FUNCTION__, key_code, key_event); + +#ifdef CFG_HW_KEY_LED_PIN + if (key_event == HAL_KEY_EVENT_DOWN) { + hal_gpio_pin_set(CFG_HW_KEY_LED_PIN); + } else if (key_event == HAL_KEY_EVENT_UP) { + hal_gpio_pin_clr(CFG_HW_KEY_LED_PIN); + } +#endif + +#ifdef USB_AUDIO_APP + if (usb_audio_app_key(key_code, key_event) == 0) { + return 0; + } +#endif + +#ifdef ANC_APP + if (anc_usb_app_key(key_code, key_event) == 0) { + return 0; + } +#endif + + if (key_event == HAL_KEY_EVENT_CLICK) { + if (key_code == HAL_KEY_CODE_FN9) { + uart_i2c_switch(); + } + } + + return 0; +} + +void anc_usb_open(void) +{ + TRACE(1,"%s", __FUNCTION__); + +#ifdef __AUDIO_RESAMPLE__ + hal_cmu_audio_resample_enable(); +#endif + +#ifdef USB_AUDIO_APP + struct USB_AUDIO_BUF_CFG cfg; + + memset(&cfg, 0, sizeof(cfg)); + cfg.play_buf = playback_buff; +#ifdef AUDIO_ANC_FB_MC + cfg.play_size = sizeof(playback_buff) / 9; +#else + cfg.play_size = sizeof(playback_buff); +#endif + cfg.cap_buf = capture_buff; + cfg.cap_size = sizeof(capture_buff); + cfg.recv_buf = recv_buff; + cfg.recv_size = sizeof(recv_buff); + cfg.send_buf = send_buff; + cfg.send_size = sizeof(send_buff); + cfg.eq_buf = eq_buff; + cfg.eq_size = sizeof(eq_buff); + cfg.resample_buf = resample_buff; + cfg.resample_size = sizeof(resample_buff); + + usb_audio_app_init(&cfg); + usb_audio_app(1); +#endif + +#ifdef ANC_APP + anc_usb_app_init(AUD_INPUT_PATH_MAINMIC, SAMPLE_RATE_PLAYBACK, SAMPLE_RATE_CAPTURE); +#endif + +#ifdef DUALADC_AUDIO_TEST + dualadc_audio_app_init(playback_buff, USB_AUDIO_PLAYBACK_BUFF_SIZE, + capture_buff, USB_AUDIO_CAPTURE_BUFF_SIZE); + dualadc_audio_app(1); +#endif + +#if defined(CFG_MIC_KEY) + mic_key_open(); +#endif +#ifdef BT_USB_AUDIO_DUAL_MODE + return; +#endif + // Allow sleep + hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_32K); + + while (1) { +#ifdef USB_AUDIO_APP + usb_audio_app_loop(); +#endif + +#ifdef ANC_APP + anc_usb_app_loop(); +#endif + +#ifdef RTOS + // Let the task sleep + osDelay(20); +#else // !RTOS + +#ifdef __PC_CMD_UART__ + hal_cmd_run(); +#endif + + hal_sleep_enter_sleep(); + +#endif // !RTOS + } +} + +void anc_usb_close(void) +{ + usb_audio_app(0); +} + +#ifdef CFG_HW_GPADCKEY +void gpadc_key_handler(uint16_t irq_val, HAL_GPADC_MV_T volt) +{ + static uint16_t stable_cnt = 0; + static uint16_t click_cnt = 0; + static uint32_t click_time; + uint32_t time; + enum HAL_KEY_EVENT_T event; + bool send_event = false; + + time = hal_sys_timer_get(); + + if (volt < 100) { + stable_cnt++; + //TRACE(5,"adc_key down: volt=%u stable=%u click_cnt=%u click_time=%u time=%u", volt, stable_cnt, click_cnt, click_time, time); + } else { + if (stable_cnt > 1) { + //TRACE(5,"adc_key up: volt=%u stable=%u click_cnt=%u click_time=%u time=%u", volt, stable_cnt, click_cnt, click_time, time); + if (click_cnt == 0 || (time - click_time) < MS_TO_TICKS(500)) { + click_time = time; + click_cnt++; + if (click_cnt >= 3) { + send_event = true; + } + } else { + send_event = true; + } + } + stable_cnt = 0; + + if (click_cnt > 0 && (time - click_time) >= MS_TO_TICKS(500)) { + send_event = true; + } + + if (send_event) { + //TRACE(5,"adc_key click: volt=%u stable=%u click_cnt=%u click_time=%u time=%u", volt, stable_cnt, click_cnt, click_time, time); + if (click_cnt == 1) { + event = HAL_KEY_EVENT_CLICK; + } else if (click_cnt == 2) { + event = HAL_KEY_EVENT_DOUBLECLICK; + } else { + event = HAL_KEY_EVENT_TRIPLECLICK; + } + key_event_process(CFG_HW_GPADCKEY, event); + click_cnt = 0; + } + } +} +#endif + +// GDB can set a breakpoint on the main function only if it is +// declared as below, when linking with STD libraries. +int btusbaudio_entry(void) +{ + anc_usb_open(); + return 0; +} + +void btusbaudio_exit(void) +{ + anc_usb_close(); +} + + diff --git a/apps/usbhost/Makefile b/apps/usbhost/Makefile new file mode 100644 index 0000000..a2b6b88 --- /dev/null +++ b/apps/usbhost/Makefile @@ -0,0 +1,7 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + diff --git a/apps/usbhost/app_usbhost.c b/apps/usbhost/app_usbhost.c new file mode 100644 index 0000000..464546b --- /dev/null +++ b/apps/usbhost/app_usbhost.c @@ -0,0 +1,21 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "app_thread.h" + + + diff --git a/apps/usbhost/app_usbhost.h b/apps/usbhost/app_usbhost.h new file mode 100644 index 0000000..c12f1ee --- /dev/null +++ b/apps/usbhost/app_usbhost.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_USBHOST_H__ +#define __APP_USBHOST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif//__FMDEC_H__ diff --git a/apps/voice_detector/Makefile b/apps/voice_detector/Makefile new file mode 100644 index 0000000..dc16155 --- /dev/null +++ b/apps/voice_detector/Makefile @@ -0,0 +1,24 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +subdir-ccflags-y += \ + -Iservices/bt_app \ + -Iplatform/drivers/ana \ + -Iapps/voice_detector \ + -Iservices/audio_dump/include \ + -Ithirdparty/cyberon_lib/include \ + -Ithirdparty/cyberon_lib/src \ + -Iservices/multimedia/speech/inc + +ifeq ($(VD_TEST),1) +subdir-ccflags-y += -DVD_TEST +endif + +ifeq ($(I2C_VAD),1) +subdir-ccflags-y += -DI2C_VAD +endif + diff --git a/apps/voice_detector/app_voice_detector.cpp b/apps/voice_detector/app_voice_detector.cpp new file mode 100644 index 0000000..77f40e0 --- /dev/null +++ b/apps/voice_detector/app_voice_detector.cpp @@ -0,0 +1,267 @@ +#include +#include +#include "cmsis_os.h" +#include "tgt_hardware.h" +#include "audioflinger.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "app_thread.h" +#include "voice_detector.h" +#include "app_voice_detector.h" + +#define APP_VD_DEBUG + +#ifdef APP_VD_DEBUG +#define APP_VD_LOG(str, ...) LOG_DEBUG(LOG_MOD(AUD), str, ##__VA_ARGS__) +#else +#define APP_VD_LOG(...) do{}while(0) +#endif +#define APP_VD_ERR(str, ...) LOG_ERROR(LOG_MOD(AUD), str, ##__VA_ARGS__) + +osMutexId vd_mutex_id = NULL; +osMutexDef(vd_mutex); + +static int cmd_arr_evt_vad_start[] = { + VOICE_DET_CMD_AUD_CAP_STOP, + VOICE_DET_CMD_AUD_CAP_CLOSE, + VOICE_DET_CMD_VAD_OPEN, + VOICE_DET_CMD_VAD_START, + VOICE_DET_CMD_SYS_CLK_32K, +}; +#if 0 +static int cmd_arr_evt_cap_start[] = { + VOICE_DET_CMD_VAD_STOP, + VOICE_DET_CMD_VAD_CLOSE, + VOICE_DET_CMD_AUD_CAP_OPEN, + VOICE_DET_CMD_AUD_CAP_START, +}; +#else +static int cmd_arr_evt_cap_start[] = { + VOICE_DET_CMD_AUD_CAP_OPEN, + VOICE_DET_CMD_AUD_CAP_START, + VOICE_DET_CMD_VAD_STOP, + VOICE_DET_CMD_VAD_CLOSE, +}; +#endif +static int cmd_arr_evt_close[] = { + VOICE_DET_CMD_AUD_CAP_STOP, + VOICE_DET_CMD_AUD_CAP_CLOSE, + VOICE_DET_CMD_VAD_STOP, + VOICE_DET_CMD_VAD_CLOSE, + VOICE_DET_CMD_EXIT, +}; +#if 1 +static int cmd_arr_evt_cap_close[] = { + VOICE_DET_CMD_AUD_CAP_STOP, + VOICE_DET_CMD_AUD_CAP_CLOSE, + VOICE_DET_CMD_EXIT, +}; +#endif +static int cmd_arr_evt_vad_close[] = { + VOICE_DET_CMD_VAD_STOP, + VOICE_DET_CMD_VAD_CLOSE, + VOICE_DET_CMD_EXIT, +}; + +static int app_voice_detector_process(APP_MESSAGE_BODY *msg_body) +{ + enum voice_detector_id id = (enum voice_detector_id)msg_body->message_id; + enum voice_detector_evt evt = (enum voice_detector_evt)msg_body->message_ptr; + int ret = 0, num, *cmds; + + voice_detector_enhance_perform(id);// set sys clock to 104M or 208M + + osMutexWait(vd_mutex_id, osWaitForever); + switch(evt) { + case VOICE_DET_EVT_VAD_START: + if (voice_detector_query_status(id) == VOICE_DET_STATE_VAD_CLOSE) { + cmds = &cmd_arr_evt_vad_start[0]; + num = ARRAY_SIZE(cmd_arr_evt_vad_start); + } else { + cmds = &cmd_arr_evt_vad_start[2]; + num = ARRAY_SIZE(cmd_arr_evt_vad_start) - 2; + } + break; + case VOICE_DET_EVT_AUD_CAP_START: + cmds = cmd_arr_evt_cap_start; + num = ARRAY_SIZE(cmd_arr_evt_cap_start); + break; + case VOICE_DET_EVT_CLOSE: + if (voice_detector_query_status(id) == VOICE_DET_STATE_VAD_CLOSE) { + cmds = &cmd_arr_evt_cap_close[0]; + num = ARRAY_SIZE(cmd_arr_evt_cap_close); + } else { + cmds = &cmd_arr_evt_vad_close[0]; + num = ARRAY_SIZE(cmd_arr_evt_vad_close); + } + break; + default: + cmds = cmd_arr_evt_close; + num = ARRAY_SIZE(cmd_arr_evt_close); + break; + } + ret = voice_detector_send_cmd_array(id, cmds, num); + if (ret) { + APP_VD_ERR("%s, send cmd error %d", __func__, ret); + } + ret = voice_detector_run(id, VOICE_DET_MODE_EXEC_CMD); + if (ret) { + APP_VD_ERR("%s, run cmd error %d", __func__, ret); + } + if (evt == VOICE_DET_EVT_CLOSE) { + voice_detector_close(id); + } + osMutexRelease(vd_mutex_id); + return ret; +} + +static void voice_detector_send_msg(uint32_t id, uint32_t evt) +{ + APP_MESSAGE_BLOCK msg; + + msg.mod_id = APP_MODUAL_VOICE_DETECTOR; + msg.msg_body.message_id = id; + msg.msg_body.message_ptr = evt; + + app_mailbox_put(&msg); +} + +static void voice_detector_wakeup_system(int state, void *param) +{ + enum voice_detector_id id = VOICE_DETECTOR_ID_0; + + if (voice_detector_query_status(id) == VOICE_DET_STATE_VAD_START) { + app_voice_detector_send_event(id, VOICE_DET_EVT_AUD_CAP_START); + } + + APP_VD_LOG("%s, state=%d", __func__, state); + // APP_VD_LOG("cpu freq=%d", hal_sys_timer_calc_cpu_freq(5,0)); +} + +static void voice_not_detector_wakeup_system(int state, void *param) +{ + enum voice_detector_id id = VOICE_DETECTOR_ID_0; + + if (voice_detector_query_status(id) == VOICE_DET_STATE_VAD_START) { + app_voice_detector_send_event(id, VOICE_DET_EVT_VAD_START); + } + + APP_VD_LOG("%s, state=%d", __func__, state); + // APP_VD_LOG("cpu freq=%d", hal_sys_timer_calc_cpu_freq(5,0)); +} + +void app_voice_detector_init(void) +{ + APP_VD_LOG("%s", __func__); + + if(vd_mutex_id == NULL){ + vd_mutex_id = osMutexCreate((osMutex(vd_mutex))); + app_set_threadhandle(APP_MODUAL_VOICE_DETECTOR, app_voice_detector_process); + } +} + +int app_voice_detector_open(enum voice_detector_id id, enum AUD_VAD_TYPE_T vad_type) +{ + int r; + + APP_VD_LOG("%s", __func__); + + if (!vd_mutex_id) { + APP_VD_LOG("%s, mutex is null", __func__); + return -1; + } + osMutexWait(vd_mutex_id, osWaitForever); + r = voice_detector_open(id, vad_type); + if (!r) { + voice_detector_setup_callback(id, VOICE_DET_FIND_APP, + voice_detector_wakeup_system, NULL); + voice_detector_setup_callback(id, VOICE_DET_NOT_FIND_APP, + voice_not_detector_wakeup_system, NULL); + } + osMutexRelease(vd_mutex_id); + return r; +} + +int app_voice_detector_setup_vad(enum voice_detector_id id, + struct AUD_VAD_CONFIG_T *conf) +{ + int r; + + APP_VD_LOG("%s", __func__); + + if (!vd_mutex_id) { + APP_VD_LOG("%s, mutex is null", __func__); + return -1; + } + osMutexWait(vd_mutex_id, osWaitForever); + r = voice_detector_setup_vad(id, conf); + osMutexRelease(vd_mutex_id); + return r; +} + +int app_voice_detector_setup_stream(enum voice_detector_id id, + enum AUD_STREAM_T stream_id, + struct AF_STREAM_CONFIG_T *stream) +{ + int r; + + APP_VD_LOG("%s", __func__); + + if (!vd_mutex_id) { + APP_VD_LOG("%s, mutex is null", __func__); + return -1; + } + osMutexWait(vd_mutex_id, osWaitForever); + r = voice_detector_setup_stream(id, stream_id, stream); + osMutexRelease(vd_mutex_id); + return r; +} + +int app_voice_detector_setup_callback(enum voice_detector_id id, + enum voice_detector_cb_id func_id, + voice_detector_cb_t func, + void *param) +{ + int r; + + APP_VD_LOG("%s", __func__); + + if (!vd_mutex_id) { + APP_VD_LOG("%s, mutex is null", __func__); + return -1; + } + osMutexWait(vd_mutex_id, osWaitForever); + r = voice_detector_setup_callback(id, func_id, func, param); + osMutexRelease(vd_mutex_id); + return r; +} + +int app_voice_detector_send_event(enum voice_detector_id id, + enum voice_detector_evt evt) +{ + APP_VD_LOG("%s, id=%d, evt=%d", __func__, id, evt); + + voice_detector_send_msg(id, evt); + return 0; +} + +void app_voice_detector_close(enum voice_detector_id id) +{ + APP_VD_LOG("%s", __func__); + + voice_detector_send_msg(id, VOICE_DET_EVT_CLOSE); +} + +void app_voice_detector_capture_start(enum voice_detector_id id) +{ + APP_VD_LOG("%s", __func__); + + voice_detector_send_msg(id, VOICE_DET_EVT_AUD_CAP_START); +} + +void app_voice_detector_get_vad_data_info(enum voice_detector_id id, + struct CODEC_VAD_BUF_INFO_T* vad_buf_info) +{ + voice_detector_get_vad_data_info(id, vad_buf_info); +} + diff --git a/apps/voice_detector/app_voice_detector.h b/apps/voice_detector/app_voice_detector.h new file mode 100644 index 0000000..405a07a --- /dev/null +++ b/apps/voice_detector/app_voice_detector.h @@ -0,0 +1,107 @@ +#ifndef __APP_VOICE_DETECTOR_H__ +#define __APP_VOICE_DETECTOR_H__ +#include "hal_aud.h" +#include "audioflinger.h" +#include "voice_detector.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* event of voice detector */ +enum voice_detector_evt { + VOICE_DET_EVT_IDLE, + VOICE_DET_EVT_OPEN, + VOICE_DET_EVT_VAD_START, + VOICE_DET_EVT_AUD_CAP_START, + VOICE_DET_EVT_CLOSE, +}; + +/* + * Initialize voice detector. + * This function should be called by main thread. + */ +void app_voice_detector_init(); + +/* + * Open voice detector specified by a unique id. + * This function must be callbed firstly. + * return: 0(success) !0(fail) + */ +int app_voice_detector_open(enum voice_detector_id id, enum AUD_VAD_TYPE_T vad_type); + +/* + * Configure VAD by specified structure conf. + * This function is optional to be called because of VAD also + * can be initialized by default parameter. + * return: 0(success) !0(fail) + */ +int app_voice_detector_setup_vad(enum voice_detector_id id, + struct AUD_VAD_CONFIG_T *conf); +/* + * Setup capture(or playback) stream to voice detector. + * The capture stream will be used to open or start audio device. + * This function must be called at least once; + * return: 0(success) !0(fail) + */ +int app_voice_detector_setup_stream(enum voice_detector_id id, + enum AUD_STREAM_T stream_id, + struct AF_STREAM_CONFIG_T *stream); +/* + * Setup callback function to voice detector. + * voice detector has several callbacks and normally we use func_id to specifiy + * it's type. + * + * parameters: + * id: voice detector identify number + * func_id: callback type identify number + * + * VOICE_DET_CB_PREVIOUS: + * This callback will be invoked before any command executed; + * VOICE_DET_CB_RUN_WAIT: + * This callback will be invoked while command queue is empty; + * VOICE_DET_CB_RUN_DONE: + * This callback will be invoked while one command executed done; + * VOICE_DET_CB_POST: + * This callback will be invoked after all commands finished; + * VOICE_DET_CB_ERROR: + * This callback will be invoked while one command executed error; + * VOICE_DET_CB_APP: + * This callback will be invoked while VAD interrupt comes; + * + * func: callback subrotine + * param: arguments of callback subrotine. + * return: 0(success) !0(fail) + */ +int app_voice_detector_setup_callback(enum voice_detector_id id, + enum voice_detector_cb_id func_id, + voice_detector_cb_t func, + void *param); +/* + * Send events to voice detector. + * This function maybe invoked in any thread. + * return: 0(success) !0(fail) + */ +int app_voice_detector_send_event(enum voice_detector_id id, + enum voice_detector_evt evt); + +/* + * Close a voice detector specified by a unique id. + */ +void app_voice_detector_close(enum voice_detector_id id); + +/* + * change a voice detector specified by a unique id to capture + */ +void app_voice_detector_capture_start(enum voice_detector_id id); + +/* + * get vad data info by a unique id. + */ +void app_voice_detector_get_vad_data_info(enum voice_detector_id id, struct CODEC_VAD_BUF_INFO_T* vad_buf_info); + +#ifdef __cplusplus +} +#endif + +#endif /* __APP_VOICE_DETECTOR_H__ */ diff --git a/apps/voice_detector/vad_sensor.h b/apps/voice_detector/vad_sensor.h new file mode 100644 index 0000000..590bf20 --- /dev/null +++ b/apps/voice_detector/vad_sensor.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __VAD_SENSOR_H__ +#define __VAD_SENSOR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int vad_sensor_open(void); +int vad_sensor_engine_start(void); +int vad_sensor_engine_stop(void); +int vad_sensor_close(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/apps/voice_detector/voice_detector.c b/apps/voice_detector/voice_detector.c new file mode 100644 index 0000000..a0d864d --- /dev/null +++ b/apps/voice_detector/voice_detector.c @@ -0,0 +1,904 @@ +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_aud.h" +#include "hal_timer.h" +#include "hal_sleep.h" +#include "analog.h" +#include "audioflinger.h" +//#include "app_audio.h" +#include "app_utils.h" +#include "voice_detector.h" +#include +#include "audio_dump.h" +#include "speech_ssat.h" + +#include "pmu.h" +#ifdef __CYBERON +#include "CSpotterSDKApi.h" +#endif + +#ifdef I2C_VAD +#include "vad_sensor.h" +#endif + +/* This macro is used to show trace info for debugging */ +#define VD_DEBUG + +#ifdef VD_DEBUG +#define VD_LOG TRACE +#else +#define VD_LOG(...) do{}while(0) +#endif + +#ifdef VD_TEST +#define VD_TRACE TRACE +#else +#define VD_TRACE(...) do{}while(0) +#endif + +#define CMD_QUEUE_DATA_SIZE 15 + +struct command_queue { + int idx; + int out; + int data[CMD_QUEUE_DATA_SIZE]; +}; + +struct voice_detector_dev { + uint8_t init; + uint8_t dfl; + uint8_t run; + enum voice_detector_state state; + uint32_t wakeup_cnt; + uint32_t arguments[VOICE_DET_CB_QTY]; + voice_detector_cb_t callback[VOICE_DET_CB_QTY]; + struct command_queue cmd_queue; + struct AUD_VAD_CONFIG_T conf; + struct AF_STREAM_CONFIG_T cap_conf; + struct AF_STREAM_CONFIG_T ply_conf; + struct CODEC_VAD_BUF_INFO_T vad_buf_info; + uint32_t sys_clk; +}; + +static struct voice_detector_dev voice_det_devs[VOICE_DETECTOR_QTY]; +uint32_t vad_buf_len = 0; + +short vad_buf[VAD_BUFFER_LEN] = {0}; + +#ifdef __CYBERON +static uint32_t POSSIBLY_UNUSED cyb_buf[20*1024]; +static uint32_t POSSIBLY_UNUSED cyb_buf_used = 0; + +extern unsigned char __g_cybase_start[]; +extern unsigned char __g_cygroup_start[]; +#define BASE_MODEL_DATA (__g_cybase_start) +#define COMMAND_MODEL_DATA (__g_cygroup_start) +HANDLE h_CSpotter = NULL; +#endif + +static void voice_detector_vad_callback(int found); +static void voice_detector_exec_callback(struct voice_detector_dev *pdev, + enum voice_detector_cb_id id); + +#define to_voice_dev(id) (&voice_det_devs[(id)]) + +static int cmd_queue_enqueue(struct command_queue *q, int c) +{ + if (q->idx >= CMD_QUEUE_DATA_SIZE) { + VD_LOG(2, "%s, overflow cmd=%d", __func__, c); + return -2; + } + if (q->idx < 0) { + q->idx = 0; + } + q->data[q->idx++] = c; +// VD_LOG(2, "%s, cmd=%d", __func__, c); + return 0; +} + +static int cmd_queue_dequeue(struct command_queue *q) +{ + int cmd; + + if (q->idx < 0) { +// VD_LOG(1, "%s, empty", __func__); + return -2; + } + if (q->out < 0) { + q->out = 0; + } + cmd = q->data[q->out++]; + if (q->out >= q->idx) { + q->out = -1; + q->idx = -1; + } +// VD_LOG(2, "%s, cmd=%d", __func__, cmd); + return cmd; +} + +static int cmd_queue_is_empty(struct command_queue *q) +{ + return (q->idx < 0) ? 1 : 0; +} + +static void voice_detector_init_cmd_queue(struct command_queue *q) +{ + if (q) { + q->idx = -1; + q->out = -1; + } +} + +static void voice_detector_init_vad(struct AUD_VAD_CONFIG_T *c, int id, enum AUD_VAD_TYPE_T vad_type) +{ + if (c) { + c->type = vad_type; +#ifdef VAD_USE_8K_SAMPLE_RATE + c->sample_rate = AUD_SAMPRATE_8000; +#else + c->sample_rate = AUD_SAMPRATE_16000; +#endif + c->bits = AUD_BITS_16; + c->handler = voice_detector_vad_callback; + c->udc = VAD_DEFAULT_UDC; + c->upre = VAD_DEFAULT_UPRE; +#ifdef I2C_VAD + c->frame_len = VAD_DEFAULT_SENSOR_FRAME_LEN; +#else + c->frame_len = VAD_DEFAULT_MIC_FRAME_LEN; +#endif + c->mvad = VAD_DEFAULT_MVAD; + c->dig_mode = VAD_DEFAULT_DIG_MODE; + c->pre_gain = VAD_DEFAULT_PRE_GAIN; + c->sth = VAD_DEFAULT_STH; + c->dc_bypass = VAD_DEFAULT_DC_BYPASS; + c->frame_th[0] = VAD_DEFAULT_FRAME_TH0; + c->frame_th[1] = VAD_DEFAULT_FRAME_TH0; + c->frame_th[2] = VAD_DEFAULT_FRAME_TH0; + c->range[0] = VAD_DEFAULT_RANGE0; + c->range[1] = VAD_DEFAULT_RANGE1; + c->range[2] = VAD_DEFAULT_RANGE2; + c->range[3] = VAD_DEFAULT_RANGE3; + c->psd_th[0] = VAD_DEFAULT_PSD_TH0; + c->psd_th[1] = VAD_DEFAULT_PSD_TH1; + } +} + +int voice_detector_open(enum voice_detector_id id, enum AUD_VAD_TYPE_T vad_type) +{ + struct voice_detector_dev *pdev; + + if (id >= VOICE_DETECTOR_QTY) { + VD_LOG(1, "%s, invalid id=%d", __func__, id); + return -1; + } + + pdev = to_voice_dev(id); + if (pdev->init) { + VD_LOG(1, "%s, dev already open", __func__); + return -2; + } + if (pdev->run) { + VD_LOG(1, "%s, dev not stoped", __func__); + return -3; + } + + memset(pdev, 0x0, sizeof(struct voice_detector_dev)); + memset(&pdev->cap_conf, 0x0, sizeof(struct AF_STREAM_CONFIG_T)); + memset(&pdev->ply_conf, 0x0, sizeof(struct AF_STREAM_CONFIG_T)); + voice_detector_init_cmd_queue(&pdev->cmd_queue); + voice_detector_init_vad(&pdev->conf, id, vad_type); + pdev->state = VOICE_DET_STATE_IDLE; + pdev->run = 0; + pdev->dfl = 1; + pdev->init = 1; + + return 0; +} + +void voice_detector_close(enum voice_detector_id id) +{ + struct voice_detector_dev *pdev; + + if (id >= VOICE_DETECTOR_QTY) { + VD_LOG(2, "%s, invalid id=%d", __func__, id); + return; + } + + pdev = to_voice_dev(id); + if (pdev->init) { + if (pdev->run) { + cmd_queue_enqueue(&pdev->cmd_queue, VOICE_DET_CMD_EXIT); + } + pdev->init = 0; + } +} + +int voice_detector_setup_vad(enum voice_detector_id id, + struct AUD_VAD_CONFIG_T *conf) +{ + struct voice_detector_dev *pdev; + + if (id >= VOICE_DETECTOR_QTY) { + VD_LOG(2, "%s, invalid id=%d", __func__, id); + return -1; + } + + pdev = to_voice_dev(id); + if (!pdev->init) { + VD_LOG(1, "%s, dev not open", __func__); + return -2; + } + + if (conf) { + memcpy(&pdev->conf, conf, sizeof(*conf)); + pdev->conf.handler = voice_detector_vad_callback; + pdev->dfl = 0; + } + return 0; +} + +int voice_detector_setup_stream(enum voice_detector_id id, + enum AUD_STREAM_T stream_id, struct AF_STREAM_CONFIG_T *stream) +{ + struct voice_detector_dev *pdev; + + if (id >= VOICE_DETECTOR_QTY) { + VD_LOG(2, "%s, invalid id=%d", __func__, id); + return -1; + } + + pdev = to_voice_dev(id); + if (!pdev->init) { + VD_LOG(1, "%s, dev not open", __func__); + return -2; + } + + if (stream_id == AUD_STREAM_CAPTURE) + memcpy(&pdev->cap_conf, stream, sizeof(struct AF_STREAM_CONFIG_T)); + else + memcpy(&pdev->ply_conf, stream, sizeof(struct AF_STREAM_CONFIG_T)); + + return 0; +} + +int voice_detector_setup_callback(enum voice_detector_id id, + enum voice_detector_cb_id func_id, voice_detector_cb_t func, void *param) +{ + struct voice_detector_dev *pdev; + + if (id >= VOICE_DETECTOR_QTY) { + VD_LOG(2, "%s, invalid id=%d", __func__, id); + return -1; + } + + pdev = to_voice_dev(id); + if (!pdev->init) { + VD_LOG(1, "%s, dev not open", __func__); + return -2; + } + + if (func_id >= VOICE_DET_CB_QTY) { + VD_LOG(2, "%s, invalid func_id=%d", __func__, func_id); + return -3; + } + pdev->arguments[func_id] = (uint32_t)param; + pdev->callback[func_id] = func; + return 0; +} + +int voice_detector_send_cmd(enum voice_detector_id id, enum voice_detector_cmd cmd) +{ + int r; + struct voice_detector_dev *pdev; + + if (id >= VOICE_DETECTOR_QTY) { + VD_LOG(2, "%s, invalid id=%d", __func__, id); + return -1; + } + pdev = to_voice_dev(id); + + r = cmd_queue_enqueue(&pdev->cmd_queue, (int)cmd); + return r; +} + +int voice_detector_send_cmd_array(enum voice_detector_id id, int *cmd_array, int num) +{ + int r, i; + struct voice_detector_dev *pdev; + + if (id >= VOICE_DETECTOR_QTY) { + VD_LOG(2, "%s, invalid id=%d", __func__, id); + return -1; + } + pdev = to_voice_dev(id); + + for(i = 0; i < num; i++) { + r = cmd_queue_enqueue(&pdev->cmd_queue, cmd_array[i]); + if (r) + return r; + } + return 0; +} + +enum voice_detector_state voice_detector_query_status(enum voice_detector_id id) +{ + struct voice_detector_dev *pdev; + + if (id >= VOICE_DETECTOR_QTY) { + return VOICE_DET_STATE_IDLE; + } + pdev = to_voice_dev(id); + + VD_LOG(2, "%s, state=%d", __func__, pdev->state); + return pdev->state; +} + +static void voice_detector_vad_callback(int found) +{ + struct voice_detector_dev *pdev; + enum voice_detector_id id = VOICE_DETECTOR_ID_0; + + pdev = to_voice_dev(id); + + pdev->wakeup_cnt++; + + VD_LOG(3, "%s, voice detector[%d], wakeup_cnt=%d", + __func__, id, pdev->wakeup_cnt); + + if (pdev->wakeup_cnt == 1) { + /* + * VOICE_DET_CB_APP should be called only once + * after CPU is waked up from sleeping. + * The VAD already can gernerates interrupts at this monment or later. + */ + voice_detector_exec_callback(pdev, found ? VOICE_DET_FIND_APP : VOICE_DET_NOT_FIND_APP); + } +} + +static int voice_detector_vad_open(struct voice_detector_dev *pdev) +{ + struct AUD_VAD_CONFIG_T *c = &pdev->conf; + + if (pdev->dfl) { + VD_LOG(1, "%s, use dfl vad", __func__); + } + af_vad_open(c); +#ifdef I2C_VAD + vad_sensor_open(); +#endif + return 0; +} + +static int voice_detector_vad_start(struct voice_detector_dev *pdev) +{ + /* wakeup_cnt is cleared while VAD starts */ + pdev->wakeup_cnt = 0; + af_vad_start(); +#ifdef I2C_VAD + vad_sensor_engine_start(); +#endif + return 0; +} + +static int voice_detector_vad_stop(struct voice_detector_dev *pdev) +{ + af_vad_stop(); + +#ifdef I2C_VAD + vad_sensor_engine_stop(); +#else + /* get vad buf info after stopping it */ + af_vad_get_data_info(&(pdev->vad_buf_info)); + TRACE(4,"vad_buf base_addr:0x%x, buf_size:0x%x, data_count:%d, addr_count:%d", + pdev->vad_buf_info.base_addr, pdev->vad_buf_info.buf_size, + pdev->vad_buf_info.data_count, pdev->vad_buf_info.addr_count); +#if defined(CHIP_BEST2300) + vad_buf_len = pdev->vad_buf_info.data_count/2; +#else + vad_buf_len = pdev->vad_buf_info.data_count; +#endif +#endif + return 0; +} + +void voice_detector_get_vad_data_info(enum voice_detector_id id, + struct CODEC_VAD_BUF_INFO_T* vad_buf_info) +{ + + struct voice_detector_dev *pdev; + + pdev = to_voice_dev(id); + + vad_buf_info->base_addr = pdev->vad_buf_info.base_addr; + vad_buf_info->buf_size = pdev->vad_buf_info.buf_size; + vad_buf_info->data_count = pdev->vad_buf_info.data_count; + vad_buf_info->addr_count = pdev->vad_buf_info.addr_count; + +} + +static int voice_detector_vad_close(struct voice_detector_dev *pdev) +{ +#ifdef I2C_VAD + vad_sensor_close(); +#endif + af_vad_close(); + return 0; +} + +static int voice_detector_aud_cap_open(struct voice_detector_dev *pdev) +{ + struct AF_STREAM_CONFIG_T *conf = &pdev->cap_conf; + + if ((!conf->handler) || (!conf->data_ptr)) { + VD_LOG(1, "%s, capture stream is null", __func__); + return -1; + } + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, conf); + return 0; +} + +static int voice_detector_aud_cap_start(struct voice_detector_dev *pdev) +{ + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + return 0; +} + +static int voice_detector_aud_cap_stop(struct voice_detector_dev *pdev) +{ + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + return 0; +} + +static int voice_detector_aud_cap_close(struct voice_detector_dev *pdev) +{ + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + return 0; +} + +static int voice_detector_sys_clk(struct voice_detector_dev *pdev) +{ +#ifdef VD_TEST + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, (enum APP_SYSFREQ_FREQ_T)(pdev->sys_clk)); +#else + app_sysfreq_req(APP_SYSFREQ_USER_AI_VOICE, (enum APP_SYSFREQ_FREQ_T)(pdev->sys_clk)); +#endif +// VD_TRACE(2,"%s, cpu freq=%d", __func__, hal_sys_timer_calc_cpu_freq(5,0)); + return 0; +} + +static int voice_detector_exit(struct voice_detector_dev *pdev) +{ + //TODO: exit process + return 0; +} + +static int voice_detector_idle(struct voice_detector_dev *pdev) +{ + //TODO: idle process + return 0; +} + +struct cmd_vector { + const char *name; + int cmd; + int (*func)(struct voice_detector_dev *pdev); +}; + +static struct cmd_vector cmd_vectors[] = { + {"idle", VOICE_DET_CMD_IDLE, voice_detector_idle}, + {"exit", VOICE_DET_CMD_EXIT, voice_detector_exit}, + {"vad open", VOICE_DET_CMD_VAD_OPEN, voice_detector_vad_open}, + {"vad start",VOICE_DET_CMD_VAD_START, voice_detector_vad_start}, + {"vad stop", VOICE_DET_CMD_VAD_STOP, voice_detector_vad_stop}, + {"vad close",VOICE_DET_CMD_VAD_CLOSE, voice_detector_vad_close}, + {"cap start",VOICE_DET_CMD_AUD_CAP_START, voice_detector_aud_cap_start}, + {"cap stop", VOICE_DET_CMD_AUD_CAP_STOP, voice_detector_aud_cap_stop}, + {"cap open", VOICE_DET_CMD_AUD_CAP_OPEN, voice_detector_aud_cap_open}, + {"cap close",VOICE_DET_CMD_AUD_CAP_CLOSE, voice_detector_aud_cap_close}, + {"clk32k", VOICE_DET_CMD_SYS_CLK_32K, voice_detector_sys_clk}, + {"clk26m", VOICE_DET_CMD_SYS_CLK_26M, voice_detector_sys_clk}, + {"clk52m", VOICE_DET_CMD_SYS_CLK_52M, voice_detector_sys_clk}, + {"clk104m", VOICE_DET_CMD_SYS_CLK_104M, voice_detector_sys_clk}, +}; + +static int voice_detector_process_cmd(struct voice_detector_dev *pdev, int cmd) +{ + int err; + + VD_LOG(3, "%s, cmd[%d]: %s", __func__, cmd, cmd_vectors[(int)cmd].name); + + switch(cmd) { + case VOICE_DET_CMD_SYS_CLK_32K: + pdev->sys_clk = APP_SYSFREQ_32K; + break; + case VOICE_DET_CMD_SYS_CLK_26M: + pdev->sys_clk = APP_SYSFREQ_26M; + break; + case VOICE_DET_CMD_SYS_CLK_52M: + pdev->sys_clk = APP_SYSFREQ_52M; + break; + case VOICE_DET_CMD_SYS_CLK_104M: + pdev->sys_clk = APP_SYSFREQ_104M; + break; + default: + break; + } + err = cmd_vectors[(int)cmd].func(pdev); + return err; +} + +static void voice_detector_set_status(struct voice_detector_dev *pdev, enum voice_detector_state s) +{ + if ((s == VOICE_DET_STATE_SYS_CLK_104M) + || (s == VOICE_DET_STATE_SYS_CLK_52M) + || (s == VOICE_DET_STATE_SYS_CLK_26M) + || (s == VOICE_DET_STATE_SYS_CLK_32K)) { + return; + } + pdev->state = s; + VD_LOG(2, "%s, state=%d", __func__, pdev->state); +} + +static void voice_detector_exec_callback(struct voice_detector_dev *pdev, + enum voice_detector_cb_id id) +{ + voice_detector_cb_t func; + + func = pdev->callback[id]; + if (func) { + void *argv = (void *)(pdev->arguments[id]); + + func(pdev->state, argv); + } +} + +int voice_detector_enhance_perform(enum voice_detector_id id) +{ + struct voice_detector_dev *pdev = to_voice_dev(id); + + pdev->sys_clk = APP_SYSFREQ_26M; + + return app_sysfreq_req(APP_SYSFREQ_USER_AI_VOICE, + (enum APP_SYSFREQ_FREQ_T)(pdev->sys_clk)); +} + +int voice_detector_run(enum voice_detector_id id, int continous) +{ + int exit = 0; + int exit_code = 0; + struct voice_detector_dev *pdev; + + if (id >= VOICE_DETECTOR_QTY) { + return -1; + } + + pdev = to_voice_dev(id); + if (!pdev->init) + return -2; + + voice_detector_exec_callback(pdev, VOICE_DET_CB_PREVIOUS); + pdev->run = 1; + while (1) { + int err = 0; + int cmd = cmd_queue_dequeue(&pdev->cmd_queue); + + if (cmd < 0) { + // cmd is invalid, invoke waitting callback + voice_detector_exec_callback(pdev, VOICE_DET_CB_RUN_WAIT); + } else { + // cmd is okay, process it + err = voice_detector_process_cmd(pdev, cmd); + if (!err) { + voice_detector_set_status(pdev, (enum voice_detector_state)cmd); + voice_detector_exec_callback(pdev, VOICE_DET_CB_RUN_DONE); + } else { + voice_detector_exec_callback(pdev, VOICE_DET_CB_ERROR); + VD_LOG(3, "%s, process cmd %d error, %d", __func__, cmd, err); + } + } + switch(continous) { + case VOICE_DET_MODE_ONESHOT: + // not continous, run only once + exit_code = err; + exit = 1; + break; + case VOICE_DET_MODE_EXEC_CMD: + // continous run,exit until cmd queue is empty + if (cmd_queue_is_empty(&pdev->cmd_queue)) { + exit = 1; + exit_code = err; + // invoke waitting callback + voice_detector_exec_callback(pdev, VOICE_DET_CB_RUN_WAIT); + } + break; + case VOICE_DET_MODE_LOOP: + //continous run forever, exit until receive VOICE_DET_CMD_EXIT + if (cmd == VOICE_DET_CMD_EXIT) { + exit = 1; + exit_code = err; + } + break; + default: + break; + } + if (exit) { + break; + } + } + pdev->run = 0; + voice_detector_exec_callback(pdev, VOICE_DET_CB_POST); + + return exit_code; +} + +#ifdef VD_TEST + +#include "app_voice_detector.h" + +#define AUDIO_CAP_BUFF_SIZE (160*2*2*2) + +static uint32_t buff_capture[AUDIO_CAP_BUFF_SIZE/4]; +static uint32_t voice_det_evt = 0; +static uint8_t vad_data_buf[8 * 1024]; + +static void voice_detector_send_evt(uint32_t evt) +{ + voice_det_evt = evt; +} + +static void print_vad_raw_data(uint8_t *buf, uint32_t len) +{ + VD_TRACE(3,"%s, buf=%x, len=%d", __func__, (uint32_t)buf, len); + //TODO: print data +} + + +static int State_M_1 = 0; +void dc_filter_f(short *in, int len, float left_gain, float right_gain) +{ + int tmp1; + for (int i = 0; i> 4; + tmp1 = in[i]; + tmp1 -= State_M_1; + in[i] = speech_ssat_int16(tmp1); + } +} + + +static uint32_t mic_data_come(uint8_t *buf, uint32_t len) +{ + static int come_cnt = 0; + short *p16data = (short *)buf; + uint32_t sample_len = len / 2; + int retcode = 0; + + dc_filter_f(p16data, sample_len, 0.0, 0.0); + + audio_dump_clear_up(); + audio_dump_add_channel_data(0, p16data, sample_len); + //audio_dump_add_channel_data(1, temp_buf, sample_len); + audio_dump_run(); + +#ifdef __CYBERON + retcode = CSpotter_AddSample(h_CSpotter, p16data, sample_len); + + if (retcode == CSPOTTER_SUCCESS) { + int id, score; + + id = CSpotter_GetResult(h_CSpotter); + TRACE(1,"##### CSpotterGetResult return ID : %d\n", id); + + score = CSpotter_GetResultScore(h_CSpotter); + TRACE(1,"CSpotter_GetResultScore return Score: %d", score); + + CSpotter_Reset(h_CSpotter); + + } +#endif + + if(come_cnt % 100 == 0) { + TRACE(1,"retcode: %d", retcode); + } + come_cnt++; + //if ((come_cnt % 200) == 0) { + // VD_TRACE(3,"%s, buf=%x, len=%d", __func__, (uint32_t)buf, len); + // } + if ((come_cnt % 300) == 0) { + come_cnt = 0; + voice_detector_send_evt(VOICE_DET_EVT_VAD_START); + VD_TRACE(1,"%s, close audio stream ...", __func__); + } + + return 0; +} + +#ifdef __CYBERON +static int CSpotter_Init_bes() +{ +#define TIMES (1000) + int err; + int state_size, mem_size; + uint8_t *state_buffer, *mem_pool; + uint8_t *p_combuf = (uint8_t *)cyb_buf; + + TRACE(1,"%s",__func__); + + state_size = CSpotter_GetStateSize((BYTE*)COMMAND_MODEL_DATA); + TRACE(2,"%s, state_size=%d",__func__, state_size); + + state_buffer = p_combuf+ cyb_buf_used; + cyb_buf_used += state_size; + if (!state_buffer) { + TRACE(0,"alloc state buff failed"); + err = -1; + goto fail; + } + + mem_size = CSpotter_GetMemoryUsage_Sep((BYTE*)BASE_MODEL_DATA, (BYTE*)COMMAND_MODEL_DATA, TIMES); + TRACE(1,"mem_size=%d",mem_size); + + mem_pool = p_combuf+ cyb_buf_used; + cyb_buf_used += mem_size; + if (!mem_pool) { + TRACE(0,"alloc mem pool failed"); + err = -2; + goto fail; + } + + h_CSpotter = CSpotter_Init_Sep((BYTE*)BASE_MODEL_DATA, (BYTE*)COMMAND_MODEL_DATA, + TIMES, mem_pool, mem_size, state_buffer, state_size, &err); + if (!h_CSpotter) { + TRACE(1,"CSpotter Init fail! err : %d\n", err); + err = -3; + goto fail; + } + + return 0; + +fail: + return err; +} +#endif + +static void cmd_wait_handler(int state, void *param) +{ + voice_detector_send_evt(VOICE_DET_EVT_IDLE); + + VD_TRACE(2,"%s, state=%d", __func__, state); +// hal_sys_timer_delay(MS_TO_TICKS(100)); +// while(1); + +// hal_sleep_enter_sleep(); +} + +static void cmd_done_handler(int state, void *param) +{ + VD_TRACE(2,"%s, state=%d", __func__, state); +} + +static void cpu_det_find_wakeup_handler(int state, void *param) +{ + static uint32_t cpu_wakeup_cnt = 0; + + cpu_wakeup_cnt++; + VD_TRACE(3,"%s, state=%d, cnt=%d", __func__, state, cpu_wakeup_cnt); + //VD_TRACE(2,"%s, calc sys freq=%d", __func__, hal_sys_timer_calc_cpu_freq(5,0)); + + voice_detector_send_evt(VOICE_DET_EVT_AUD_CAP_START); +} + +static void cpu_det_notfind_wakeup_handler(int state, void *param) +{ + + VD_TRACE(2,"%s, state=%d", __func__, state); + //VD_TRACE(2,"%s, calc sys freq=%d", __func__, hal_sys_timer_calc_cpu_freq(5,0)); + + voice_detector_send_evt(VOICE_DET_EVT_VAD_START); +} + +void voice_detector_test(void) +{ + enum voice_detector_id id = VOICE_DETECTOR_ID_0; + int r, run; + struct AF_STREAM_CONFIG_T stream_cfg; + enum HAL_SLEEP_STATUS_T sleep; + uint32_t len; + + VD_TRACE(1,"%s, start", __func__); + + af_open(); + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + stream_cfg.sample_rate = AUD_SAMPRATE_16000; + stream_cfg.bits = AUD_BITS_16; + stream_cfg.vol = 16; + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.io_path = AUD_INPUT_PATH_VADMIC; + stream_cfg.channel_num = AUD_CHANNEL_NUM_1; + stream_cfg.handler = mic_data_come; + stream_cfg.data_ptr = (uint8_t *)buff_capture; + stream_cfg.data_size = AUDIO_CAP_BUFF_SIZE; + + audio_dump_init(AUDIO_CAP_BUFF_SIZE / 2 / 2, sizeof(short), 1); + +#ifdef __CYBERON + CSpotter_Init_bes(); +#endif + + r = voice_detector_open(id); + if (r) { + VD_TRACE(2,"%s, error %d", __func__, r); + return; + } + + voice_detector_setup_stream(id, AUD_STREAM_CAPTURE, &stream_cfg); + voice_detector_setup_callback(id, VOICE_DET_CB_RUN_WAIT, cmd_wait_handler, NULL); + voice_detector_setup_callback(id, VOICE_DET_CB_RUN_DONE, cmd_done_handler, NULL); + voice_detector_setup_callback(id, VOICE_DET_FIND_APP, cpu_det_find_wakeup_handler, NULL); + voice_detector_setup_callback(id, VOICE_DET_NOT_FIND_APP, cpu_det_notfind_wakeup_handler, NULL); + + VD_TRACE(2,"%s, calc sys freq=%d", __func__, hal_sys_timer_calc_cpu_freq(5,0)); + + voice_detector_send_cmd(id, VOICE_DET_CMD_AUD_CAP_OPEN); + voice_detector_send_cmd(id, VOICE_DET_CMD_AUD_CAP_CLOSE); + voice_detector_send_evt(VOICE_DET_EVT_VAD_START); + run = 0; + + while (1) { + if (voice_det_evt != VOICE_DET_EVT_IDLE) { + switch(voice_det_evt) { + case VOICE_DET_EVT_VAD_START: + if (voice_detector_query_status(id) == VOICE_DET_STATE_VAD_CLOSE) { + voice_detector_send_cmd(id, VOICE_DET_CMD_AUD_CAP_STOP); + voice_detector_send_cmd(id, VOICE_DET_CMD_AUD_CAP_CLOSE); + } + //TODO: save current system clock + voice_detector_send_cmd(id, VOICE_DET_CMD_VAD_OPEN); + voice_detector_send_cmd(id, VOICE_DET_CMD_VAD_START); + voice_detector_send_cmd(id, VOICE_DET_CMD_SYS_CLK_32K); + run = 1; + break; + case VOICE_DET_EVT_AUD_CAP_START: + voice_detector_send_cmd(id, VOICE_DET_CMD_SYS_CLK_26M); + voice_detector_send_cmd(id, VOICE_DET_CMD_AUD_CAP_OPEN); + voice_detector_send_cmd(id, VOICE_DET_CMD_AUD_CAP_START); + voice_detector_send_cmd(id, VOICE_DET_CMD_VAD_STOP); + voice_detector_send_cmd(id, VOICE_DET_CMD_VAD_CLOSE); + //voice_detector_send_cmd(id, VOICE_DET_CMD_AUD_CAP_OPEN); + //voice_detector_send_cmd(id, VOICE_DET_CMD_AUD_CAP_START); + run = 1; + break; + default: + run = 0; + break; + } + voice_det_evt = VOICE_DET_EVT_IDLE; + } + if (run) { + run = 0; + voice_detector_run(id, VOICE_DET_MODE_EXEC_CMD); + } + +#ifndef RTOS + extern void af_thread(void const *argument); + af_thread(NULL); +#endif + +// while(1); + sleep = hal_sleep_enter_sleep(); + if (sleep == HAL_SLEEP_STATUS_DEEP) { + VD_TRACE(0,"wake up from deep sleep"); + } + + len = voice_detector_recv_vad_data(VOICE_DETECTOR_ID_0, + vad_data_buf, sizeof(vad_data_buf)); + if (len) { + print_vad_raw_data(vad_data_buf, len); + } + } +} +#endif diff --git a/apps/voice_detector/voice_detector.h b/apps/voice_detector/voice_detector.h new file mode 100644 index 0000000..8e4664c --- /dev/null +++ b/apps/voice_detector/voice_detector.h @@ -0,0 +1,198 @@ +#ifndef __VOICE_DETECTOR_H__ +#define __VOICE_DETECTOR_H__ +#include "hal_aud.h" +#include "audioflinger.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* identify number of voice detector */ +enum voice_detector_id { + VOICE_DETECTOR_ID_0, + VOICE_DETECTOR_QTY, +}; + +#if defined(CHIP_BEST2300P) +#define VAD_BUFFER_LEN 8192 +#else +#define VAD_BUFFER_LEN 2048 +#endif + +/* commands of voice detector */ +enum voice_detector_cmd { + VOICE_DET_CMD_IDLE, + VOICE_DET_CMD_EXIT, + VOICE_DET_CMD_VAD_OPEN, + VOICE_DET_CMD_VAD_START, + VOICE_DET_CMD_VAD_STOP, + VOICE_DET_CMD_VAD_CLOSE, + VOICE_DET_CMD_AUD_CAP_START, + VOICE_DET_CMD_AUD_CAP_STOP, + VOICE_DET_CMD_AUD_CAP_OPEN, + VOICE_DET_CMD_AUD_CAP_CLOSE, + VOICE_DET_CMD_SYS_CLK_32K, + VOICE_DET_CMD_SYS_CLK_26M, + VOICE_DET_CMD_SYS_CLK_52M, + VOICE_DET_CMD_SYS_CLK_104M, +}; + +/* state of voice detector */ +enum voice_detector_state { + VOICE_DET_STATE_IDLE = VOICE_DET_CMD_IDLE, + VOICE_DET_STATE_EXIT = VOICE_DET_CMD_EXIT, + VOICE_DET_STATE_VAD_OPEN = VOICE_DET_CMD_VAD_OPEN, + VOICE_DET_STATE_VAD_START = VOICE_DET_CMD_VAD_START, + VOICE_DET_STATE_VAD_STOP = VOICE_DET_CMD_VAD_STOP, + VOICE_DET_STATE_VAD_CLOSE = VOICE_DET_CMD_VAD_CLOSE, + VOICE_DET_STATE_AUD_CAP_START = VOICE_DET_CMD_AUD_CAP_START, + VOICE_DET_STATE_AUD_CAP_STOP = VOICE_DET_CMD_AUD_CAP_STOP, + VOICE_DET_STATE_AUD_CAP_OPEN = VOICE_DET_CMD_AUD_CAP_OPEN, + VOICE_DET_STATE_AUD_CAP_CLOSE = VOICE_DET_CMD_AUD_CAP_CLOSE, + VOICE_DET_STATE_SYS_CLK_32K = VOICE_DET_CMD_SYS_CLK_32K, + VOICE_DET_STATE_SYS_CLK_26M = VOICE_DET_CMD_SYS_CLK_26M, + VOICE_DET_STATE_SYS_CLK_52M = VOICE_DET_CMD_SYS_CLK_52M, + VOICE_DET_STATE_SYS_CLK_104M = VOICE_DET_CMD_SYS_CLK_104M, +}; + +/* running mode of voice detector */ +enum voice_detector_mode { + VOICE_DET_MODE_ONESHOT, + VOICE_DET_MODE_EXEC_CMD, + VOICE_DET_MODE_LOOP, +}; + +/* callback type of voice detector */ +enum voice_detector_cb_id { + VOICE_DET_CB_PREVIOUS, + VOICE_DET_CB_RUN_WAIT, + VOICE_DET_CB_RUN_DONE, + VOICE_DET_CB_POST, + VOICE_DET_CB_ERROR, + VOICE_DET_CB_APP, + VOICE_DET_FIND_APP, + VOICE_DET_NOT_FIND_APP, + VOICE_DET_CB_QTY, +}; + +/* callback function definition */ +typedef void (*voice_detector_cb_t)(int current_state, void *arguments); + +/* VAD default parameters */ +#define VAD_DEFAULT_UDC 0x1//0xa +#define VAD_DEFAULT_UPRE 0x4 +#define VAD_DEFAULT_SENSOR_FRAME_LEN 8 // 1.6K sample rate +#define VAD_DEFAULT_MIC_FRAME_LEN 0x50 // 16K sample rate +#define VAD_DEFAULT_MVAD 0x7 +#define VAD_DEFAULT_DIG_MODE 0x1 +#define VAD_DEFAULT_PRE_GAIN 0x4 +#define VAD_DEFAULT_STH 0x10 +#define VAD_DEFAULT_DC_BYPASS 0x0 +#define VAD_DEFAULT_FRAME_TH0 0x32 +#define VAD_DEFAULT_FRAME_TH1 0x1f4 +#define VAD_DEFAULT_FRAME_TH2 0x1388 +#define VAD_DEFAULT_RANGE0 0xf +#define VAD_DEFAULT_RANGE1 0x32 +#define VAD_DEFAULT_RANGE2 0x96 +#define VAD_DEFAULT_RANGE3 0x12c +#define VAD_DEFAULT_PSD_TH0 0x0 +#define VAD_DEFAULT_PSD_TH1 0x07ffffff + +/* + * open voice detector specified by a unique id + * must be callbed firstly + * return: 0(success) !0(fail) + */ +int voice_detector_open(enum voice_detector_id id, enum AUD_VAD_TYPE_T vad_type); + +/* + * configure VAD by specified structure conf + * Optional be called because of voice detector will initial vad by default parameter + * return: 0(success) !0(fail) + */ +int voice_detector_setup_vad(enum voice_detector_id id, struct AUD_VAD_CONFIG_T *conf); + +/* + * setup capture(or playback) stream to voice detector. The capture stream will + * be used to open or start audio device. + * must be called before voice_detector_run(); + * return: 0(success) !0(fail) + */ +int voice_detector_setup_stream(enum voice_detector_id id, + enum AUD_STREAM_T stream_id, struct AF_STREAM_CONFIG_T *stream); + +/* + * setup callback function to voice detector. This callback function will be called + * when voice_detector_run() starts. + * parameters: + * func_id: callback type id + * func: callback fuction + * param: the arguments of callback function. + * return: 0(success) !0(fail) + */ + +int voice_detector_setup_callback(enum voice_detector_id id, + enum voice_detector_cb_id func_id, voice_detector_cb_t func, void *param); + +/* + * query the status of voice detector. Before send any command to voice detector + * by invoke voice_detector_send_cmd(), the status should be queried by this + * function. + * return: the state of voice detector + */ +enum voice_detector_state voice_detector_query_status(enum voice_detector_id id); + +/* + * receive data from voice detector's VAD buffer. + * return: The number of bytes received from VAD private buffer + */ +int voice_detector_recv_vad_data(enum voice_detector_id id, + uint8_t *pbuf, uint32_t buf_size); +/* + * send commands to voice detector. These commands will be saved in a queue + * before they are executed exactly. + * return: 0(success) !0(fail) + */ +int voice_detector_send_cmd(enum voice_detector_id id, enum voice_detector_cmd cmd); + +/* + * send commands array to voice detector. These commands will be saved in a queue + * before they are executed exactly. + * return: 0(success) !0(fail) + */ +int voice_detector_send_cmd_array(enum voice_detector_id id, int *cmd_array, int num); + +int voice_detector_enhance_perform(enum voice_detector_id id); + +/* + * This function is a special subrotine which should be invoked by a thread + * It will execute these commands stored in a queue. + * parameters: + * id: voice detector identify number + * continous: + * 2: This function will not return until the VOICE_DET_EXIT_CMD be sent + * 1: This function will not return until the cmd queue is empty + * 0: This function just execute only once. + * return: 0(success) !0(error) + */ +int voice_detector_run(enum voice_detector_id id, int continous); + +/* + * close a voice detector specified by a unique id. + */ +void voice_detector_close(enum voice_detector_id id); + +/* + * get vad data info by a unique id. + */ +void voice_detector_get_vad_data_info(enum voice_detector_id id, struct CODEC_VAD_BUF_INFO_T* vad_buf_info); + +#ifdef VD_TEST +void voice_detector_test(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/config/Makefile b/config/Makefile new file mode 100644 index 0000000..90dd8d5 --- /dev/null +++ b/config/Makefile @@ -0,0 +1,54 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +#obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) + +FILE_LIST := tgt_hardware.c + +ifneq ($(SLAVE_BIN_FLASH_OFFSET),) +FILE_LIST += slave_code.S +$(obj)/$(DEFAULT_CFG_SRC)/slave_code.o : out/$(SLAVE_BIN_TARGET_NAME)/$(SLAVE_BIN_TARGET_NAME).bin +AFLAGS_slave_code.o += -DSLAVE_BIN_NAME=$(SLAVE_BIN_TARGET_NAME).bin -Iout/$(SLAVE_BIN_TARGET_NAME) +endif + +obj-y := $(patsubst $(cur_dir)%,%,$(foreach f,$(FILE_LIST), \ + $(if $(wildcard $(cur_dir)$(T)/$(f)),$(cur_dir)$(T)/$(f),$(cur_dir)$(DEFAULT_CFG_SRC)/$(f)))) + +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y += \ + -Iplatform/hal \ + -Iplatform/drivers/usb/usb_dev/inc \ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/include \ + -Iservices/multimedia/speech/inc \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/audio/process/drc/include \ + -Iservices/multimedia/audio/process/limiter/include + +ifeq ($(BT_DEV_NAME),) +BT_DEV_NAME := $(T).$(BUILD_HOSTNAME).$(BUILD_USERNAME) +endif + +ccflags-y += -DBT_DEV_NAME=$(BT_DEV_NAME) $(CUST_TGT_FLAGS) + +ifneq ($(BT_DEV_ADDR),) +ccflags-y += -DBT_DEV_ADDR=$(BT_DEV_ADDR) +endif + +ifneq ($(BLE_DEV_ADDR),) +ccflags-y += -DBT_DEV_ADDR=$(BLE_DEV_ADDR) +endif + +ifneq ($(USB_AUDIO_SEND_CHAN),) +ccflags-y += -DUSB_AUDIO_SEND_CHAN=$(USB_AUDIO_SEND_CHAN) +endif + +ifeq ($(SPEECH_TX_AEC_CODEC_REF),1) +ccflags-y += -DSPEECH_TX_AEC_CODEC_REF +endif + +ifeq ($(ANC_NOISE_TRACKER),1) +ccflags-y += -DANC_NOISE_TRACKER +endif diff --git a/config/_default_cfg_src_/app_status_ind.c b/config/_default_cfg_src_/app_status_ind.c new file mode 100644 index 0000000..e02220b --- /dev/null +++ b/config/_default_cfg_src_/app_status_ind.c @@ -0,0 +1,294 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "stdbool.h" +#include "hal_trace.h" +#include "app_pwl.h" +#include "app_status_ind.h" +#include "string.h" + +static APP_STATUS_INDICATION_T app_status = APP_STATUS_INDICATION_NUM; +static APP_STATUS_INDICATION_T app_status_ind_filter = APP_STATUS_INDICATION_NUM; + +const char *app_status_indication_str[] = +{ + "[POWERON]", + "[INITIAL]", + "[PAGESCAN]", + "[POWEROFF]", + "[CHARGENEED]", + "[CHARGING]", + "[FULLCHARGE]", + /* repeatable status: */ + "[BOTHSCAN]", + "[CONNECTING]", + "[CONNECTED]", + "[DISCONNECTED]", + "[CALLNUMBER]", + "[INCOMINGCALL]", + "[PAIRSUCCEED]", + "[PAIRFAIL]", + "[HANGUPCALL]", + "[REFUSECALL]", + "[ANSWERCALL]", + "[CLEARSUCCEED]", + "[CLEARFAIL]", + "[WARNING]", + "[ALEXA_START]", + "[ALEXA_STOP]", + "[GSOUND_MIC_OPEN]", + "[GSOUND_MIC_CLOSE]", + "[GSOUND_NC]", + "[INVALID]", + "[MUTE]", + "[TESTMODE]", + "[TESTMODE1]", + "[RING_WARNING]", +#ifdef __INTERACTION__ + "[FINDME]", +#endif + "[MY_BUDS_FIND]", + "[TILE_FIND]", +}; + + +const char *status2str(uint16_t status) +{ + const char *str = NULL; + + if (status >= 0 && status < APP_STATUS_INDICATION_NUM) + { + str = app_status_indication_str[status]; + } + else + { + str = "[UNKNOWN]"; + } + + return str; +} + +int app_status_indication_filter_set(APP_STATUS_INDICATION_T status) +{ + app_status_ind_filter = status; + return 0; +} + +APP_STATUS_INDICATION_T app_status_indication_get(void) +{ + return app_status; +} + +int app_status_indication_set(APP_STATUS_INDICATION_T status) +{ + struct APP_PWL_CFG_T cfg0; + struct APP_PWL_CFG_T cfg1; + + TRACE(2,"%s %d",__func__, status); + + if (app_status == status) + return 0; + + if (app_status_ind_filter == status) + return 0; + + app_status = status; + memset(&cfg0, 0, sizeof(struct APP_PWL_CFG_T)); + memset(&cfg1, 0, sizeof(struct APP_PWL_CFG_T)); + app_pwl_stop(APP_PWL_ID_0); + app_pwl_stop(APP_PWL_ID_1); + switch (status) { + case APP_STATUS_INDICATION_POWERON: + cfg0.part[0].level = 1; + cfg0.part[0].time = (3000); + cfg0.part[1].level = 0; + cfg0.part[1].time = (200); + cfg0.parttotal = 2; + cfg0.startlevel = 1; + cfg0.periodic = false; + + app_pwl_setup(APP_PWL_ID_0, &cfg0); + app_pwl_start(APP_PWL_ID_0); + + break; + case APP_STATUS_INDICATION_INITIAL: + break; + case APP_STATUS_INDICATION_PAGESCAN: + cfg0.part[0].level = 1; + cfg0.part[0].time = (300); + cfg0.part[1].level = 0; + cfg0.part[1].time = (8000); + cfg0.parttotal = 2; + cfg0.startlevel = 1; + cfg0.periodic = true; + app_pwl_setup(APP_PWL_ID_0, &cfg0); + app_pwl_start(APP_PWL_ID_0); + break; + case APP_STATUS_INDICATION_BOTHSCAN: + cfg0.part[0].level = 0; + cfg0.part[0].time = (300); + cfg0.part[1].level = 1; + cfg0.part[1].time = (300); + cfg0.parttotal = 2; + cfg0.startlevel = 0; + cfg0.periodic = true; + + cfg1.part[0].level = 1; + cfg1.part[0].time = (300); + cfg1.part[1].level = 0; + cfg1.part[1].time = (300); + cfg1.parttotal = 2; + cfg1.startlevel = 1; + cfg1.periodic = true; + + app_pwl_setup(APP_PWL_ID_0, &cfg0); + app_pwl_start(APP_PWL_ID_0); + app_pwl_setup(APP_PWL_ID_1, &cfg1); + app_pwl_start(APP_PWL_ID_1); + break; + case APP_STATUS_INDICATION_CONNECTING: + cfg0.part[0].level = 1; + cfg0.part[0].time = (300); + cfg0.part[1].level = 0; + cfg0.part[1].time = (300); + cfg0.parttotal = 2; + cfg0.startlevel = 0; + cfg0.periodic = true; + + cfg1.part[0].level = 1; + cfg1.part[0].time = (300); + cfg1.part[1].level = 0; + cfg1.part[1].time = (300); + cfg1.parttotal = 2; + cfg1.startlevel = 1; + cfg1.periodic = true; + + app_pwl_setup(APP_PWL_ID_0, &cfg0); + app_pwl_start(APP_PWL_ID_0); + app_pwl_setup(APP_PWL_ID_1, &cfg1); + app_pwl_start(APP_PWL_ID_1); + break; + case APP_STATUS_INDICATION_CONNECTED: + cfg0.part[0].level = 1; + cfg0.part[0].time = (500); + cfg0.part[1].level = 0; + cfg0.part[1].time = (3000); + cfg0.parttotal = 2; + cfg0.startlevel = 1; + cfg0.periodic = true; + + cfg1.part[0].level = 0; + cfg1.part[0].time = (500); + cfg1.part[1].level = 0; + cfg1.part[1].time = (3000); + cfg1.parttotal = 2; + cfg1.startlevel = 0; + cfg1.periodic = true; + app_pwl_setup(APP_PWL_ID_0, &cfg0); + app_pwl_start(APP_PWL_ID_0); + app_pwl_setup(APP_PWL_ID_1, &cfg1); + app_pwl_start(APP_PWL_ID_1); + break; + case APP_STATUS_INDICATION_CHARGING: + cfg1.part[0].level = 1; + cfg1.part[0].time = (5000); + cfg1.parttotal = 1; + cfg1.startlevel = 1; + cfg1.periodic = true; + app_pwl_setup(APP_PWL_ID_1, &cfg1); + app_pwl_start(APP_PWL_ID_1); + break; + case APP_STATUS_INDICATION_FULLCHARGE: + cfg0.part[0].level = 1; + cfg0.part[0].time = (5000); + cfg0.parttotal = 1; + cfg0.startlevel = 1; + cfg0.periodic = true; + app_pwl_setup(APP_PWL_ID_0, &cfg0); + app_pwl_start(APP_PWL_ID_0); + break; + case APP_STATUS_INDICATION_POWEROFF: + cfg1.part[0].level = 1; + cfg1.part[0].time = (3000); + cfg1.part[1].level = 0; + cfg1.part[1].time = (200); + cfg1.parttotal = 2; + cfg1.startlevel = 1; + cfg1.periodic = false; + + app_pwl_setup(APP_PWL_ID_1, &cfg1); + app_pwl_start(APP_PWL_ID_1); + break; + case APP_STATUS_INDICATION_CHARGENEED: + cfg1.part[0].level = 1; + cfg1.part[0].time = (500); + cfg1.part[1].level = 0; + cfg1.part[1].time = (2000); + cfg1.parttotal = 2; + cfg1.startlevel = 1; + cfg1.periodic = true; + app_pwl_setup(APP_PWL_ID_1, &cfg1); + app_pwl_start(APP_PWL_ID_1); + break; + case APP_STATUS_INDICATION_TESTMODE: + cfg0.part[0].level = 0; + cfg0.part[0].time = (300); + cfg0.part[1].level = 1; + cfg0.part[1].time = (300); + cfg0.parttotal = 2; + cfg0.startlevel = 0; + cfg0.periodic = true; + + cfg1.part[0].level = 0; + cfg1.part[0].time = (300); + cfg1.part[1].level = 1; + cfg1.part[1].time = (300); + cfg1.parttotal = 2; + cfg1.startlevel = 1; + cfg1.periodic = true; + + app_pwl_setup(APP_PWL_ID_0, &cfg0); + app_pwl_start(APP_PWL_ID_0); + app_pwl_setup(APP_PWL_ID_1, &cfg1); + app_pwl_start(APP_PWL_ID_1); + break; + case APP_STATUS_INDICATION_TESTMODE1: + cfg0.part[0].level = 0; + cfg0.part[0].time = (1000); + cfg0.part[1].level = 1; + cfg0.part[1].time = (1000); + cfg0.parttotal = 2; + cfg0.startlevel = 0; + cfg0.periodic = true; + + cfg1.part[0].level = 0; + cfg1.part[0].time = (1000); + cfg1.part[1].level = 1; + cfg1.part[1].time = (1000); + cfg1.parttotal = 2; + cfg1.startlevel = 1; + cfg1.periodic = true; + + app_pwl_setup(APP_PWL_ID_0, &cfg0); + app_pwl_start(APP_PWL_ID_0); + app_pwl_setup(APP_PWL_ID_1, &cfg1); + app_pwl_start(APP_PWL_ID_1); + break; + default: + break; + } + return 0; +} diff --git a/config/_default_cfg_src_/res/SOUND_MUTE.txt b/config/_default_cfg_src_/res/SOUND_MUTE.txt new file mode 100644 index 0000000..ff9fc2e --- /dev/null +++ b/config/_default_cfg_src_/res/SOUND_MUTE.txt @@ -0,0 +1,132 @@ +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, diff --git a/config/_default_cfg_src_/res/cn/SOUND_ANSWER.txt b/config/_default_cfg_src_/res/cn/SOUND_ANSWER.txt new file mode 100644 index 0000000..cdf76ff --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_ANSWER.txt @@ -0,0 +1,190 @@ +0x9c,0x31,0x10,0x34,0x31,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x75,0x9b,0x6e,0x5b, +0x20,0x9c,0x12,0x6d,0x19,0xd2,0x0e,0x5b,0x29,0x13,0x44,0x22,0x3e,0x1a,0x21,0xa4, +0x29,0xaa,0x7a,0x05,0xb4,0xdb,0x56,0x51,0x9c,0x31,0x10,0xa6,0x32,0x21,0x00,0x00, +0x13,0x13,0x72,0xb4,0xa5,0xcc,0x6b,0x49,0x63,0xca,0xa2,0x1d,0x7a,0xba,0x5d,0x31, +0x4b,0xbb,0x75,0x2c,0x8b,0xd5,0xc4,0x23,0xe4,0x32,0xc4,0x32,0x92,0xb1,0xaa,0xbe, +0x9c,0x31,0x10,0xbd,0x32,0x33,0x00,0x00,0x8c,0xbb,0x7b,0xb3,0x7c,0x33,0x84,0x2a, +0xaa,0xbb,0x8b,0x4b,0xa5,0x3b,0xac,0x3a,0xbc,0xbb,0xf2,0xd3,0xe0,0xbc,0x79,0xcb, +0x72,0x24,0xa2,0x43,0xb4,0xcb,0x94,0x89,0x9c,0x31,0x10,0x51,0x43,0x34,0x00,0x00, +0x92,0x48,0xa5,0xc9,0xb5,0x88,0x91,0x36,0x78,0xb6,0x68,0x97,0x81,0x14,0x91,0x18, +0x5a,0x36,0x73,0x0b,0x9c,0xa5,0xb2,0x98,0xa1,0xb6,0x6e,0x25,0xd6,0xc8,0xbc,0xc7, +0x9c,0x31,0x10,0x8b,0x87,0x67,0x30,0x00,0x85,0xdb,0x81,0xdb,0x85,0xdb,0x89,0xdb, +0x9d,0x8b,0xc0,0x9e,0x7e,0x22,0x81,0x8b,0x81,0xa2,0xab,0x1a,0x6e,0x4b,0x75,0x9b, +0x59,0xeb,0x5d,0xd2,0x6d,0xdc,0x79,0xeb,0x9c,0x31,0x10,0x9c,0x55,0x67,0x20,0x00, +0x7b,0x87,0x6b,0x68,0x6b,0x67,0x65,0xb6,0x7d,0x25,0x73,0x79,0xbb,0x85,0xca,0x27, +0xe2,0xa9,0x9b,0xb3,0x5c,0x79,0x6b,0x57,0x5c,0x97,0x92,0x89,0x82,0x37,0x64,0x65, +0x9c,0x31,0x10,0xfc,0x75,0x78,0x30,0x00,0x75,0x97,0x6b,0x57,0x6a,0x97,0x5b,0x67, +0x4b,0x66,0x44,0x87,0x3b,0x88,0x33,0x84,0x34,0x96,0x3b,0x4b,0x42,0xb8,0x49,0x45, +0x52,0x85,0x6b,0x77,0x63,0x79,0x8a,0xa6,0x9c,0x31,0x10,0x18,0x86,0x98,0x30,0x00, +0x93,0x67,0x9a,0x98,0xac,0x58,0xb3,0x86,0xab,0x67,0x93,0x87,0x7c,0x66,0x64,0x9c, +0x52,0x64,0x53,0x69,0x7b,0x83,0x83,0x58,0x88,0xa5,0xd4,0x29,0x53,0xa7,0x19,0x35, +0x9c,0x31,0x10,0x1e,0x85,0x89,0x40,0x00,0x21,0xcb,0x5d,0x55,0x8d,0x87,0xa2,0x95, +0xa2,0x77,0x86,0x96,0x85,0x77,0x75,0x46,0x91,0x5a,0x95,0xa8,0xa9,0x96,0xae,0x46, +0x95,0xa7,0x50,0x56,0x34,0x99,0x49,0x67,0x9c,0x31,0x10,0x76,0xb5,0x78,0x40,0x00, +0x84,0xa5,0x92,0xd2,0x94,0xac,0x83,0x49,0x66,0xb6,0x5f,0x24,0x7e,0xb8,0xb7,0x37, +0xcc,0xa8,0x96,0xc8,0x3c,0xb5,0x0c,0xb6,0x43,0x3a,0xad,0x39,0xf6,0xa7,0xec,0xc4, +0x9c,0x31,0x10,0xb8,0xc6,0x79,0x40,0x00,0x87,0x0b,0x4e,0xab,0x35,0x4b,0x58,0xf2, +0x99,0x0b,0xbe,0xe3,0xbb,0x14,0x96,0xe2,0x63,0x5b,0x31,0x63,0x38,0xd5,0x7d,0x2a, +0xbe,0x4b,0xcd,0x72,0xa8,0xcb,0x69,0x6a,0x9c,0x31,0x10,0xad,0xc7,0x89,0x40,0x00, +0x28,0xe5,0x2c,0x8a,0x76,0xea,0xc0,0x92,0xcf,0x23,0xaa,0x9b,0x71,0x1c,0x2e,0xac, +0x28,0xd9,0x70,0xdc,0xc0,0xda,0xce,0xdd,0xaa,0x92,0x77,0x23,0x34,0x52,0x24,0xf2, +0x9c,0x31,0x10,0xad,0xc7,0x89,0x40,0x00,0x6a,0xc5,0xc0,0xf3,0xd0,0xcc,0xa6,0xaa, +0x77,0x13,0x38,0x51,0x24,0xf5,0x68,0x84,0xbf,0x2b,0xcc,0xd2,0xa4,0xa3,0x77,0x1a, +0x3c,0x12,0x29,0x2e,0x68,0x93,0xbf,0x23,0x9c,0x31,0x10,0xad,0xc7,0x89,0x40,0x00, +0xca,0xd1,0x9e,0x9b,0x77,0x14,0x44,0x14,0x29,0x1d,0x66,0xe0,0xbd,0x13,0xca,0xe2, +0x9c,0x9c,0x77,0x14,0x48,0x1c,0x2b,0x4b,0x66,0xb1,0xbd,0x03,0xca,0xeb,0x9a,0x94, +0x9c,0x31,0x10,0xb5,0xc7,0x99,0x40,0x00,0x77,0x1b,0x4a,0x1c,0x2d,0x4b,0x68,0xa9, +0xbd,0x0c,0xc6,0xe4,0x94,0x9b,0x77,0x5b,0x4e,0x1c,0x2f,0x52,0x6a,0xea,0xbd,0x13, +0xc5,0x24,0x94,0x9b,0x77,0x53,0x4e,0x24,0x9c,0x31,0x10,0xdd,0xc8,0x99,0x40,0x00, +0x2f,0x0a,0x6e,0xea,0xc3,0x0c,0xc3,0x24,0x8c,0x9a,0x77,0x13,0x4e,0x64,0x33,0x0b, +0x76,0xe9,0xc5,0x13,0xbf,0x24,0x8a,0x93,0x73,0x1b,0x48,0x5b,0x37,0x15,0x80,0xe8, +0x9c,0x31,0x10,0x69,0xc8,0x99,0x50,0x00,0xc6,0xd3,0xb9,0x23,0x84,0x94,0x73,0x63, +0x44,0x52,0x3a,0xe5,0x88,0xda,0xc6,0xd3,0xb4,0xda,0x80,0x9c,0x71,0x1c,0x40,0x52, +0x40,0xec,0x92,0x93,0xc8,0xdb,0xae,0xdb,0x9c,0x31,0x10,0x01,0xc7,0x99,0x50,0x00, +0x7c,0x5a,0x6b,0x5b,0x3c,0x1a,0x4a,0xea,0x9c,0x8d,0xc6,0xe3,0xa6,0x9b,0x78,0x9b, +0x65,0x1b,0x38,0xe4,0x56,0xd8,0xa8,0xd3,0xc6,0xeb,0x9e,0x93,0x74,0xe4,0x5c,0xda, +0x9c,0x31,0x10,0x69,0xc8,0x99,0x50,0x00,0x35,0x24,0x66,0xcd,0xb2,0xea,0xc3,0x1a, +0x96,0xdb,0x73,0x1a,0x52,0x9b,0x39,0x51,0x76,0xdd,0xba,0xe4,0xbf,0x0b,0x8c,0xe3, +0x6d,0x1b,0x46,0x5c,0x3d,0x14,0x84,0xe9,0x9c,0x31,0x10,0x01,0xc7,0x99,0x50,0x00, +0xc0,0xcb,0xba,0xa3,0x86,0x9b,0x67,0x5b,0x3a,0x1a,0x48,0xec,0x96,0x94,0xc7,0x1c, +0xb2,0xa2,0x7e,0x93,0x5b,0x1b,0x34,0xe5,0x58,0xd2,0xa2,0x9a,0xc9,0x23,0xa8,0xd4, +0x9c,0x31,0x10,0x09,0xc7,0x88,0x30,0x00,0x77,0x24,0x4e,0xa2,0x39,0x51,0x66,0xcd, +0xaa,0xf4,0xc4,0xca,0x9e,0xda,0x6d,0x23,0x48,0x55,0x47,0x0a,0x74,0xe9,0xa4,0xd3, +0xb0,0xd5,0x8e,0xa3,0x71,0x1b,0x62,0x93,0x9c,0x31,0x10,0x04,0xa5,0x76,0x10,0x00, +0x09,0x16,0x32,0x70,0x7f,0x5a,0xaa,0x14,0xc0,0xdc,0xda,0xda,0xcd,0x1b,0x8c,0xdb, +0x52,0xdc,0x3e,0xda,0x54,0xdb,0x84,0xdb,0xb2,0xdb,0xb6,0xdb,0x94,0x9b,0x6e,0xdb, +0x9c,0x31,0x10,0xc2,0x92,0x33,0x00,0x00,0x20,0xe4,0x12,0x53,0x43,0xa6,0x92,0x61, +0xca,0xca,0xce,0xec,0xab,0x12,0x6d,0x23,0x3c,0x4b,0x37,0x63,0x5a,0x55,0x8a,0xd2, +0xae,0x6a,0xb4,0xcd,0x99,0x2a,0x6e,0x0b,0x9c,0x31,0x10,0x62,0x83,0x23,0x00,0x00, +0x29,0x6a,0x22,0x8c,0x50,0xf5,0x9e,0x91,0xcc,0xd5,0xbc,0xe3,0x90,0xca,0x60,0xdb, +0x3a,0x94,0x49,0x1b,0x76,0xcb,0x9c,0xa2,0xa2,0xe3,0x9c,0xca,0x84,0xdc,0x5e,0xec, +0x9c,0x31,0x10,0xa6,0x72,0x32,0x00,0x00,0x36,0x51,0x64,0xea,0x86,0xeb,0x8c,0xd5, +0x9c,0xa3,0x8f,0x65,0x66,0xc9,0x62,0xa3,0x76,0xe9,0x77,0x15,0x6e,0x91,0x7f,0x60, +0x84,0xd5,0x77,0x15,0x86,0xf1,0x92,0xd4,0x9c,0x31,0x10,0xea,0x64,0x32,0x00,0x00, +0x81,0xdc,0x51,0x9b,0x5a,0x1b,0x71,0xc2,0x86,0x2b,0xb2,0x0c,0xcd,0x84,0x99,0x59, +0x62,0x9a,0x46,0x1a,0x72,0x54,0x99,0xa3,0xab,0x25,0xb9,0xac,0x82,0xa8,0x3c,0xea, +0x9c,0x31,0x10,0x8c,0xa8,0x98,0x40,0x00,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x81,0xdb, +0x81,0xdb,0x8e,0xa4,0x89,0x9b,0x89,0x5b,0xa2,0x1b,0xa5,0x5b,0xb6,0x5c,0xa8,0x5a, +0xc6,0x12,0xc6,0xeb,0x91,0x4b,0x55,0xe5,0x9c,0x31,0x10,0x6f,0xa6,0x77,0x40,0x00, +0x48,0xd8,0x42,0x9c,0x36,0xe0,0x2e,0x96,0x2e,0x74,0x2d,0x03,0x23,0x2a,0x12,0x92, +0x10,0x9d,0x24,0xd0,0x46,0x9e,0x56,0xa2,0x63,0x16,0x74,0x9a,0x88,0xe5,0x94,0xd0, +0x9c,0x31,0x10,0x35,0x96,0x89,0x50,0x00,0xbb,0x67,0xcb,0xa5,0xd3,0x46,0xd3,0xa7, +0xcc,0x28,0xcc,0x99,0xcb,0x38,0xbb,0xba,0xa3,0x67,0xab,0x64,0xab,0x75,0xb1,0x86, +0xbb,0x7b,0xca,0x67,0xcb,0xa7,0xd9,0x34,0x9c,0x31,0x10,0xae,0xa5,0x88,0x60,0x00, +0xb4,0x8d,0xb5,0x4d,0xc1,0x95,0xb5,0x25,0xad,0xad,0x99,0x2d,0x92,0xb1,0x8e,0x4d, +0x85,0x69,0x75,0x4d,0x70,0x6d,0x79,0x59,0x80,0x92,0x81,0x72,0x81,0x66,0x79,0x65, +0x9c,0x31,0x10,0x53,0x75,0x58,0x50,0x00,0x54,0x1d,0x63,0x94,0x23,0xa8,0x14,0x61, +0x2d,0x31,0x3b,0x1e,0x61,0x62,0xac,0x92,0xb2,0x95,0x8c,0x91,0x73,0x99,0x44,0x24, +0x33,0x61,0x34,0x95,0x1b,0xa5,0x43,0x19,0x9c,0x31,0x10,0x0e,0x95,0x77,0x50,0x00, +0x75,0x55,0x7d,0x51,0x65,0x69,0x4d,0x49,0x54,0x65,0x68,0x75,0x59,0x6d,0x4a,0x8d, +0x3a,0x45,0x2e,0x88,0x2e,0x35,0x3e,0x75,0x45,0x51,0x4d,0x8a,0x45,0x96,0x45,0x46, +0x9c,0x31,0x10,0xa2,0x95,0x67,0x40,0x00,0x44,0x61,0x3e,0x80,0x3d,0x0c,0x4d,0x94, +0x6a,0x79,0x81,0x8d,0x8a,0x8a,0x85,0x11,0x81,0x89,0x7a,0x4d,0x7e,0x6d,0x82,0x4d, +0x84,0x51,0x84,0x51,0x85,0x8d,0x81,0x52,0x9c,0x31,0x10,0xac,0x85,0x67,0x30,0x00, +0x9d,0xcb,0xb9,0xbb,0xa5,0xc2,0xa2,0x22,0x92,0x2a,0x91,0x54,0x91,0xa5,0xa9,0xc2, +0xad,0x52,0xa5,0xb3,0xb5,0x34,0xc6,0x3c,0xc1,0xd4,0xb1,0x99,0x81,0x45,0x70,0xab, +0x9c,0x31,0x10,0x87,0x85,0x67,0x40,0x00,0xa1,0xb1,0xb5,0x6d,0x95,0x69,0x7d,0x68, +0x59,0x6c,0x4d,0x8c,0x45,0x35,0x49,0x91,0x66,0x71,0x7c,0x65,0x8a,0x4d,0xa5,0x6d, +0xbd,0x71,0x95,0x52,0x81,0x4e,0x8d,0xb2,0x9c,0x31,0x10,0x1a,0x84,0x67,0x40,0x00, +0x66,0x4a,0x38,0x6a,0x2e,0x4d,0x66,0xd1,0xbe,0x0d,0xca,0x69,0xce,0x49,0xb6,0x6d, +0xa1,0x51,0x9c,0x91,0x8a,0x51,0x69,0x65,0x71,0x6d,0x80,0x49,0x64,0x8d,0x22,0x71, +0x9c,0x31,0x10,0x3f,0x94,0x67,0x40,0x00,0x48,0x71,0x70,0x6d,0x99,0x45,0xa0,0x91, +0x9a,0x6d,0x81,0x89,0x60,0x4c,0x6d,0x6d,0x8c,0x75,0x9e,0x6d,0xa8,0x72,0x85,0x4e, +0x41,0x8e,0x19,0x4a,0x4a,0xa9,0xc1,0x48,0x9c,0x31,0x10,0x29,0xc4,0x56,0x40,0x00, +0x92,0xa8,0x90,0x94,0x7d,0x31,0x66,0xb9,0x60,0xa9,0x76,0xa5,0x9b,0x29,0xac,0xa9, +0x94,0x94,0x62,0xd1,0x45,0x15,0x58,0xcd,0x90,0x92,0xbf,0x4e,0xb2,0x32,0x78,0xaa, +0x9c,0x31,0x10,0x13,0xc5,0x67,0x40,0x00,0x41,0x62,0x3e,0x51,0x71,0x6a,0xb4,0x94, +0xcf,0x5c,0xa5,0x5d,0x5b,0x5a,0x2d,0x2b,0x43,0x49,0x87,0x2b,0xc8,0x8b,0xcd,0x6d, +0x94,0x53,0x4c,0x6a,0x2a,0x92,0x4d,0x65,0x9c,0x31,0x10,0x38,0xc5,0x67,0x30,0x00, +0x94,0x52,0xcb,0x6d,0xc5,0x4b,0x8a,0xa3,0x49,0x14,0x2b,0x88,0x53,0x74,0x9c,0x4c, +0xce,0x73,0xc0,0x0c,0x83,0xa2,0x44,0x04,0x2b,0xac,0x58,0x51,0xa1,0x5b,0xce,0x53, +0x9c,0x31,0x10,0x9a,0xc6,0x77,0x30,0x00,0xb8,0x9a,0x7d,0x1b,0x40,0x52,0x2f,0x26, +0x5e,0xd3,0xa8,0xe3,0xce,0xd4,0xb4,0x98,0x79,0x5c,0x3e,0x51,0x30,0xec,0x66,0xce, +0xac,0xe0,0xcc,0xdd,0xae,0x51,0x73,0x1b,0x9c,0x31,0x10,0xb8,0xc6,0x79,0x40,0x00, +0x3a,0x5b,0x32,0xe2,0x6c,0xd4,0xb2,0xda,0xcf,0x24,0xaa,0x53,0x6d,0x23,0x38,0x5c, +0x36,0xd9,0x74,0xdc,0xb6,0xd2,0xca,0xec,0xa2,0x8c,0x6b,0x22,0x38,0xa4,0x3c,0xd1, +0x9c,0x31,0x10,0xa6,0xc5,0x78,0x30,0x00,0x7a,0xc9,0xba,0x95,0xc6,0xea,0x9c,0x1b, +0x65,0x51,0x36,0x4d,0x42,0xa3,0x82,0xc7,0xbe,0xb9,0xc4,0xb3,0x94,0x3a,0x5f,0x45, +0x34,0xca,0x48,0x9b,0x88,0xd1,0xba,0xb8,0x9c,0x31,0x10,0x95,0xc5,0x68,0x40,0x00, +0xba,0xb1,0x98,0xae,0x6b,0x43,0x37,0x58,0x3c,0x8b,0x7e,0xe3,0xb9,0x3b,0xc0,0x92, +0xa5,0x47,0x74,0xd7,0x39,0x26,0x34,0xad,0x6e,0xd3,0xad,0x19,0xc2,0xa8,0xaf,0x45, +0x9c,0x31,0x10,0xa1,0xc5,0x89,0x30,0x00,0x81,0x43,0x3d,0x32,0x33,0x3d,0x66,0xc2, +0xa5,0x2b,0xc0,0xc4,0xb9,0x32,0x86,0xd3,0x3d,0x1a,0x33,0x4d,0x64,0x33,0x9f,0x33, +0xbe,0xbc,0xbb,0x3b,0x88,0xc3,0x3d,0x22,0x9c,0x31,0x10,0x2e,0xc5,0x88,0x30,0x00, +0x35,0x46,0x64,0x3a,0x9d,0x2b,0xbe,0x44,0xbd,0x33,0x88,0xca,0x3d,0x19,0x36,0xce, +0x64,0x3b,0x9d,0x2a,0xbe,0x44,0xbd,0x33,0x86,0xd3,0x3b,0x11,0x38,0xce,0x66,0x3a, +0x9c,0x31,0x10,0x94,0xc6,0x88,0x30,0x00,0x9e,0xd3,0xc0,0xab,0xbb,0x53,0x84,0xab, +0x39,0x80,0x38,0xe5,0x66,0x9b,0xa0,0xd3,0xc2,0x6b,0xbb,0x54,0x7e,0x63,0x39,0x88, +0x3c,0xe5,0x66,0xdb,0xa0,0xd2,0xc2,0x63,0x9c,0x31,0x10,0x09,0xc7,0x88,0x30,0x00, +0xbb,0x14,0x7c,0xa4,0x35,0x40,0x3a,0xec,0x66,0xdc,0xa4,0xcb,0xc6,0xaa,0xbb,0x14, +0x78,0x9c,0x35,0x49,0x3a,0xa2,0x68,0xd4,0xaa,0xd4,0xc8,0xa2,0xb9,0x13,0x74,0x5c, +0x9c,0x31,0x10,0x09,0xc7,0x88,0x30,0x00,0x31,0x4b,0x3c,0xe9,0x6c,0xdb,0xac,0xcc, +0xca,0xa3,0xb7,0x1b,0x6e,0x54,0x2f,0x53,0x3a,0xa8,0x6c,0xd3,0xb0,0xd5,0xcc,0xa2, +0xb9,0x13,0x6a,0x55,0x2d,0x53,0x3a,0xa9,0x9c,0x31,0x10,0x09,0xc7,0x88,0x30,0x00, +0x6f,0x1a,0xb0,0xd4,0xcc,0xa3,0xb4,0xda,0x68,0x13,0x2d,0x55,0x3c,0xaa,0x71,0x19, +0xb2,0xdc,0xcc,0x9c,0xb5,0x1a,0x66,0x12,0x2d,0x55,0x3e,0xa3,0x75,0x1a,0xb4,0xda, +0x9c,0x31,0x10,0x07,0xc7,0x77,0x30,0x00,0xca,0x9c,0xb3,0x1b,0x64,0x09,0x2f,0x55, +0x3e,0xad,0x75,0x22,0xb4,0xd9,0xca,0x93,0xaf,0x1c,0x62,0x0a,0x31,0x1d,0x40,0xad, +0x77,0x22,0xb4,0xe1,0xca,0x93,0xad,0x14,0x9c,0x31,0x10,0x88,0xc7,0x76,0x30,0x00, +0x5e,0x09,0x31,0x1b,0x42,0xa5,0x79,0x26,0xb6,0xe1,0xc6,0x98,0xab,0x13,0x5e,0x53, +0x35,0x21,0x46,0xa3,0x7d,0x26,0xb4,0xe5,0xc4,0xda,0xa5,0x1a,0x5c,0x51,0x37,0x20, +0x9c,0x31,0x10,0x90,0xc7,0x66,0x30,0x00,0x48,0xa3,0x7f,0x2e,0xb5,0x1d,0xc2,0xdb, +0xa3,0x12,0x5a,0x53,0x38,0xe1,0x4a,0xa2,0x81,0x23,0xb6,0xdc,0xc0,0xdc,0xa1,0x14, +0x58,0x9c,0x3a,0xea,0x4e,0xa9,0x83,0x21,0x9c,0x31,0x10,0x0e,0xc6,0x56,0x40,0x00, +0xb4,0x8b,0xbf,0x8b,0x9e,0x8b,0x5a,0x55,0x3e,0x55,0x51,0x33,0x85,0x6a,0xb3,0x69, +0xbb,0x89,0x98,0x89,0x58,0x72,0x42,0x75,0x57,0x55,0x88,0x6d,0xb1,0x6c,0xb8,0x8b, +0x9c,0x31,0x10,0x52,0xb6,0x55,0x30,0x00,0xa7,0x50,0x31,0x58,0x0a,0xd4,0x34,0xb1, +0x94,0xad,0xe0,0x89,0xe9,0x2e,0x9f,0x11,0x2f,0x91,0x10,0xf1,0x3e,0xed,0x9c,0xa9, +0xde,0x89,0xdf,0x29,0x90,0xd1,0x2d,0x8d,0x9c,0x31,0x10,0x3a,0xb6,0x43,0x10,0x00, +0x16,0xed,0x49,0x0a,0xa2,0xc4,0xde,0x68,0xd8,0xed,0x88,0xd1,0x2d,0x89,0x1d,0x0a, +0x4f,0x21,0xa2,0xa9,0xd8,0x8c,0xd2,0xf0,0x80,0xcc,0x2f,0xa5,0x25,0x29,0x59,0x6e, +0x9c,0x31,0x10,0x8d,0xb6,0x41,0x00,0x00,0xab,0x7e,0xda,0x56,0xca,0x64,0x75,0x32, +0x2c,0xa1,0x2b,0x7a,0x64,0xb2,0xb1,0xa4,0xd6,0x8c,0xbd,0x83,0x6a,0x3a,0x2d,0x7a, +0x34,0x53,0x6f,0x9b,0xb9,0x92,0xd6,0x99,0x9c,0x31,0x10,0xbb,0xb5,0x42,0x00,0x00, +0xb2,0x88,0x5c,0x0c,0x2c,0x71,0x3d,0x0d,0x7d,0x86,0xbe,0x42,0xd1,0xa9,0xa5,0x8d, +0x51,0x71,0x2d,0x90,0x47,0x2d,0x8a,0x68,0xc3,0x2d,0xcb,0xb1,0x94,0x71,0x46,0x70, +0x9c,0x31,0x10,0x80,0xb5,0x43,0x10,0x00,0x31,0x6c,0x52,0x6d,0x98,0x92,0xc9,0x2d, +0xc3,0x8d,0x7f,0x4e,0x3b,0xae,0x36,0x49,0x62,0x92,0xa8,0x90,0xcf,0x49,0xba,0x88, +0x6c,0x25,0x35,0xcd,0x3c,0x31,0x73,0x8d,0x9c,0x31,0x10,0x80,0xb5,0x43,0x10,0x00, +0xb5,0x45,0xcc,0xa9,0xa7,0x6d,0x57,0x52,0x34,0x71,0x49,0x4e,0x87,0x85,0xc0,0x2d, +0xc8,0x91,0x92,0x55,0x49,0x90,0x37,0x4d,0x58,0x6d,0x99,0x8d,0xc4,0x51,0xbc,0x8d, +0x9c,0x31,0x10,0xf3,0xb5,0x32,0x00,0x00,0x79,0x45,0x3d,0xd2,0x3d,0x26,0x6b,0x96, +0xab,0x75,0xc7,0x81,0xab,0x72,0x62,0x35,0x3c,0xb4,0x4b,0x44,0x80,0x90,0xb6,0x35, +0xc3,0xb5,0x96,0x59,0x50,0x88,0x3c,0x65,0x9c,0x31,0x10,0xf3,0xb5,0x32,0x00,0x00, +0x57,0x74,0x94,0xaa,0xc0,0x3a,0xbb,0x95,0x7d,0x45,0x43,0xd2,0x41,0x35,0x6a,0x96, +0xa7,0x72,0xc2,0x85,0xaa,0x84,0x66,0x39,0x41,0xa5,0x4d,0x45,0x7f,0xa1,0xb3,0x26, +0x9c,0x31,0x10,0xd6,0xa5,0x32,0x00,0x00,0xfe,0xba,0xaa,0x68,0x27,0x84,0x04,0x55, +0x37,0x84,0xa9,0xa9,0xf6,0x46,0xe9,0x95,0x76,0x40,0x12,0xc2,0x11,0x35,0x5e,0x85, +0xcd,0x76,0xfa,0x92,0xc6,0x75,0x47,0x36,0x9c,0x31,0x10,0xd6,0xa5,0x32,0x00,0x00, +0x09,0x99,0x27,0x65,0x8a,0x95,0xe6,0x35,0xf3,0xb5,0x9a,0x65,0x24,0x95,0x0b,0x45, +0x43,0x85,0xb0,0x94,0xf3,0x55,0xdd,0x90,0x6c,0x30,0x15,0xb2,0x1a,0x45,0x68,0x85, +0x9c,0x31,0x10,0x53,0xa4,0x22,0x00,0x00,0xce,0x31,0xf1,0xb5,0xb7,0x79,0x40,0x2a, +0x11,0xa8,0x35,0x55,0x95,0xc9,0xe4,0x0a,0xe3,0xc5,0x88,0x45,0x28,0xd5,0x1c,0x15, +0x56,0x75,0xb8,0x91,0xe9,0x75,0xc5,0x85,0x9c,0x31,0x10,0x41,0xa5,0x23,0x00,0x00, +0x5c,0x44,0x1d,0xa5,0x2d,0x55,0x7c,0x85,0xd2,0x49,0xe2,0x99,0x9c,0x74,0x39,0x75, +0x1e,0x65,0x48,0x79,0xa2,0xa5,0xe0,0x51,0xcf,0x81,0x72,0x59,0x28,0xb5,0x2a,0x45, +0x9c,0x31,0x10,0x4b,0xa4,0x32,0x00,0x00,0x6a,0x80,0xc2,0x45,0xe0,0xa5,0xae,0x59, +0x4e,0x65,0x25,0xa5,0x3f,0x55,0x90,0xc4,0xd4,0x35,0xcf,0xa4,0x83,0x44,0x35,0xb5, +0x2b,0x46,0x5e,0x55,0xb4,0x65,0xd9,0x75,0x9c,0x31,0x10,0x53,0xa4,0x22,0x00,0x00, +0xb4,0x89,0x5e,0x35,0x2d,0xc6,0x3d,0x36,0x85,0xc4,0xc9,0x55,0xcc,0xa4,0x8f,0x55, +0x43,0x75,0x2f,0x66,0x5a,0x75,0xaa,0x85,0xd0,0x51,0xb2,0x95,0x68,0x59,0x34,0xa5, +0x9c,0x31,0x10,0xa7,0xa3,0x22,0x00,0x00,0x41,0x11,0x82,0xce,0xc1,0x51,0xc3,0x8e, +0x8f,0x75,0x4c,0x71,0x3a,0x61,0x64,0x2d,0xa4,0xd1,0xc0,0x2d,0xa2,0x8d,0x68,0x50, +0x3f,0x69,0x52,0x8d,0x89,0x6d,0xb9,0x71,0x9c,0x31,0x10,0x44,0x93,0x21,0x00,0x00, +0xe6,0x51,0x8b,0xd0,0x22,0x2c,0x0c,0xb1,0x57,0x0a,0xc3,0xa9,0xee,0x2e,0xba,0xb2, +0x5b,0x11,0x1c,0xd1,0x34,0x4c,0x8a,0xa5,0xda,0x52,0xd2,0x6d,0x8b,0x8c,0x3a,0x68, +0x9c,0x31,0x10,0x6c,0x93,0x11,0x00,0x00,0x26,0xb2,0x58,0x65,0xae,0x84,0xd5,0x29, +0xb1,0xa5,0x69,0x69,0x34,0x99,0x3f,0x65,0x7b,0x91,0xbc,0x56,0xc4,0x78,0x98,0x95, +0x5a,0x70,0x40,0x89,0x58,0x69,0x90,0x81,0x9c,0x31,0x10,0xfc,0x82,0x21,0x00,0x00, +0xea,0x2d,0xd9,0xb1,0x87,0x4e,0x38,0xac,0x26,0x50,0x5b,0x72,0xa9,0x8e,0xc8,0x45, +0xac,0x89,0x6f,0x52,0x48,0x88,0x50,0x4d,0x80,0xac,0xab,0x75,0xad,0x8d,0x8f,0x4d, +0x9c,0x31,0x10,0x2c,0x71,0x12,0x00,0x00,0x4c,0xda,0x2f,0x65,0x4c,0x52,0x8d,0x04, +0xb2,0x5b,0xb3,0x0b,0x92,0x54,0x68,0xe2,0x56,0xeb,0x66,0x93,0x83,0x2c,0x8e,0x32, +0x83,0x23,0x78,0xab,0x72,0x83,0x7b,0x52,0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00, +0xad,0xd2,0xb7,0x2c,0x96,0x5b,0x42,0x8a,0x2a,0x1d,0x1e,0x63,0x75,0xa1,0xe1,0x9d, +0xe9,0x0c,0x95,0x5c,0x5a,0x5a,0x4a,0x52,0x62,0xda,0x8a,0x24,0x96,0x65,0x8d,0xd3, +0x9c,0x31,0x10,0xf9,0x42,0x12,0x00,0x00,0x81,0x94,0x62,0x53,0x61,0x8b,0x89,0x83, +0x9e,0x5c,0x76,0x54,0x46,0x19,0x1e,0x1a,0x15,0x1d,0x56,0x2b,0x88,0x9c,0x9e,0x13, +0x85,0xd3,0x4e,0x13,0x42,0x12,0x3d,0xdb,0x9c,0x31,0x10,0xe7,0x41,0x21,0x00,0x00, +0x79,0x24,0x79,0xad,0x71,0x33,0x7e,0xb1,0x76,0x31,0x56,0x43,0x42,0xc3,0x30,0x4c, +0x29,0xb5,0x45,0x33,0x56,0xa8,0x8a,0xc1,0xc1,0x2e,0xb5,0x32,0x63,0x3a,0x1f,0x10, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_CHARGE_FINISH.txt b/config/_default_cfg_src_/res/cn/SOUND_CHARGE_FINISH.txt new file mode 100644 index 0000000..ff7fb2b --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_CHARGE_FINISH.txt @@ -0,0 +1,310 @@ +0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7e,0x1b, +0x6d,0x1c,0x86,0x1a,0x7a,0x24,0x7d,0xdd,0x82,0xd3,0x7d,0x83,0x61,0x5a,0x55,0xdb, +0x3d,0xe4,0x3d,0xc4,0x4e,0xa3,0x61,0xc5,0x9c,0x31,0x10,0x02,0x32,0x12,0x00,0x00, +0x2a,0xa8,0x1d,0x35,0x39,0x28,0x43,0xd8,0x56,0x28,0x5a,0xa7,0x43,0x38,0x33,0x37, +0x32,0x4b,0x32,0x15,0x33,0x18,0x1b,0x58,0x22,0x95,0x3c,0xe7,0x32,0xb9,0x64,0xba, +0x9c,0x31,0x10,0xa0,0x44,0x32,0x00,0x00,0x6d,0xe5,0x6e,0x1a,0x71,0x9b,0x55,0xdc, +0x4a,0x13,0x59,0x9c,0x4e,0x21,0x39,0x52,0x51,0xe6,0x3a,0x1c,0x2d,0xe4,0x34,0x92, +0x3a,0x0b,0x2a,0x0b,0x46,0x1d,0x45,0x75,0x9c,0x31,0x10,0xfb,0x98,0x88,0x40,0x00, +0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xb3,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb, +0x7b,0x3b,0x7b,0xbb,0x8c,0x3b,0x8b,0x42,0xe7,0x64,0x97,0x1d,0x84,0xba,0x83,0xb3, +0x9c,0x31,0x10,0xc6,0x88,0x98,0x40,0x00,0x9b,0xba,0x7b,0x4b,0x53,0xc3,0x63,0x42, +0x4c,0x3c,0x34,0x33,0x1a,0x2d,0x62,0xaa,0x83,0xc1,0x9c,0x45,0x9b,0xcc,0x93,0xc9, +0x85,0x59,0x76,0xda,0x56,0x5e,0x3e,0x4d,0x9c,0x31,0x10,0xa5,0xa9,0x98,0x50,0x00, +0x6a,0x98,0x6e,0x61,0x72,0x95,0x7a,0x74,0x7d,0xea,0xbf,0x30,0x9e,0x9d,0x6e,0xde, +0x73,0x62,0x82,0xd3,0x56,0xda,0x4a,0x61,0x65,0xe3,0x79,0xdc,0x79,0x5c,0x80,0x9b, +0x9c,0x31,0x10,0x3a,0xa9,0x98,0x30,0x00,0x60,0x99,0x5c,0x53,0x5d,0x1d,0x6d,0x9c, +0x56,0x11,0x6a,0x12,0x6a,0x1b,0x9a,0x9d,0xbe,0xeb,0xc6,0xdb,0xd2,0xa2,0xea,0x23, +0xed,0xa3,0xcd,0xda,0x82,0x5c,0x59,0xd3,0x9c,0x31,0x10,0x69,0x9a,0x97,0x30,0x00, +0x1b,0x9d,0x5b,0x19,0x2a,0x1e,0x10,0x9c,0x41,0xd1,0x6c,0x0d,0x24,0x95,0x0c,0x99, +0x44,0x5e,0x62,0xdd,0x3a,0xa5,0x5a,0xe0,0x3b,0xda,0x43,0xe1,0x4b,0xe1,0x7c,0x5d, +0x9c,0x31,0x10,0x45,0x89,0x66,0x20,0x00,0xe5,0x8a,0xb4,0xdc,0xd1,0x9a,0x9d,0xe0, +0xa6,0x74,0xf9,0xe4,0xf9,0xc9,0xe9,0x64,0x9a,0x14,0x9a,0xca,0x61,0xaa,0x69,0x5d, +0x71,0x0a,0x61,0xd2,0x46,0x1c,0x4a,0x53,0x9c,0x31,0x10,0x3c,0x98,0x66,0x10,0x00, +0x74,0xdc,0x88,0x9b,0x8a,0x99,0x8f,0x0c,0xb9,0x55,0x85,0x59,0x9a,0x59,0x99,0xdd, +0xba,0x2b,0x9a,0x13,0x50,0xd3,0x42,0x53,0x3e,0x5c,0x95,0xa2,0xd1,0xea,0xb2,0x24, +0x9c,0x31,0x10,0xb7,0xb8,0x66,0x20,0x00,0x5e,0x23,0x4d,0x63,0x6e,0x1c,0xa1,0x5a, +0xbd,0xd2,0xa1,0xdc,0x4f,0x55,0x30,0x1b,0x53,0x29,0xb9,0xa2,0xf8,0xdb,0xba,0xdd, +0x35,0x8c,0x05,0x12,0x33,0x5a,0xe5,0x9a,0x9c,0x31,0x10,0xc1,0xc9,0x55,0x30,0x00, +0xce,0x59,0x98,0xb5,0x52,0x56,0x3d,0x65,0x4f,0x85,0xb0,0x45,0xd2,0xb6,0xa6,0x6a, +0x53,0x78,0x2f,0x78,0x47,0x74,0xad,0x65,0xd3,0xa1,0xb4,0x46,0x61,0x86,0x36,0x81, +0x9c,0x31,0x10,0xf0,0xc8,0x45,0x20,0x00,0x39,0x35,0x98,0xb5,0xd0,0x69,0xc3,0x11, +0x6d,0xe1,0x3c,0x21,0x35,0x82,0x86,0xb1,0xc4,0x31,0xc7,0xa5,0x7c,0x65,0x46,0x75, +0x39,0x45,0x70,0xc5,0xb4,0x15,0xc8,0xe5,0x9c,0x31,0x10,0x34,0xc8,0x43,0x10,0x00, +0x91,0x03,0x55,0xc3,0x3f,0x54,0x5b,0xbb,0x9d,0x33,0xc1,0xbc,0xa9,0x44,0x65,0xac, +0x50,0x64,0x4e,0x8c,0x87,0x5c,0xb0,0x9b,0xb7,0x73,0x79,0x7c,0x5c,0x85,0x4d,0x54, +0x9c,0x31,0x10,0x33,0xb8,0x33,0x00,0x00,0x5d,0x76,0xb2,0x72,0xe5,0x54,0xa2,0x98, +0x59,0x36,0x34,0xf9,0x37,0x01,0x88,0xc5,0xc9,0x35,0xc6,0xb9,0x77,0x55,0x56,0xa5, +0x39,0x12,0x5f,0x09,0xa2,0xd5,0xc9,0x25,0x9c,0x31,0x10,0x13,0xb7,0x43,0x00,0x00, +0x9a,0x2d,0x6d,0x91,0x48,0xb1,0x44,0xed,0x78,0xad,0xb3,0x29,0xb4,0xa9,0x85,0x6d, +0x64,0x72,0x47,0x4d,0x5b,0x29,0x96,0x85,0xcb,0x6d,0xae,0x0d,0x75,0xd1,0x36,0x4d, +0x9c,0x31,0x10,0xbc,0xb8,0x32,0x00,0x00,0x25,0x45,0x60,0xa1,0xb1,0x15,0xd4,0xf6, +0xa4,0xe4,0x65,0x35,0x20,0xc9,0x3c,0xea,0x7b,0x26,0xca,0xd1,0xd3,0x01,0x99,0x10, +0x3e,0x70,0x29,0x71,0x60,0xb5,0xb2,0xf5,0x9c,0x31,0x10,0xcf,0xb8,0x43,0x10,0x00, +0xda,0x7b,0xb3,0x7a,0x54,0x51,0x22,0xc9,0x4d,0x4a,0x97,0x7b,0xda,0x9c,0xce,0x62, +0x7a,0x84,0x1f,0xbb,0x33,0x2a,0x78,0x9b,0xcb,0xa4,0xd9,0x3c,0x96,0xb5,0x2c,0x7e, +0x9c,0x31,0x10,0x5d,0xb8,0x54,0x10,0x00,0x24,0x75,0x5f,0x55,0xb7,0x25,0xdc,0x75, +0xad,0x75,0x42,0x86,0x20,0xd5,0x51,0x34,0x9e,0xf5,0xd8,0xa4,0xbb,0x35,0x5c,0x84, +0x1f,0x61,0x3f,0x01,0x88,0xc6,0xd5,0x05,0x9c,0x31,0x10,0x01,0xb6,0x42,0x00,0x00, +0xda,0xf1,0xa1,0x1a,0x37,0xd1,0x26,0x49,0x64,0x86,0xb9,0x6c,0xda,0x6d,0xb9,0xcd, +0x4c,0x4d,0x1b,0x31,0x4c,0xed,0xa1,0x0d,0xd4,0x8c,0xc5,0x6d,0x6a,0x06,0x1b,0x48, +0x9c,0x31,0x10,0x49,0xb6,0x32,0x00,0x00,0x3d,0x89,0x8e,0x58,0xce,0x65,0xcc,0x96, +0x85,0x41,0x24,0xb2,0x2e,0x85,0x7d,0x39,0xc6,0xa5,0xd2,0x55,0x99,0x85,0x34,0x92, +0x23,0x71,0x6e,0x44,0xbc,0xb8,0xd5,0x49,0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00, +0xaa,0xea,0x49,0x54,0x1f,0x79,0x5c,0x45,0xad,0xd5,0xd3,0x2a,0xb5,0xe9,0x5b,0x15, +0x1e,0x59,0x4d,0x95,0xa2,0xa5,0xcf,0x35,0xb9,0xb9,0x69,0x16,0x25,0x65,0x43,0xb5, +0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00,0x96,0x65,0xcc,0x55,0xbe,0x82,0x79,0x25, +0x30,0x55,0x3c,0xba,0x88,0x59,0xc3,0x71,0xc1,0x71,0x86,0x50,0x3b,0x71,0x35,0xb1, +0x79,0x59,0xba,0x99,0xc2,0x59,0x90,0x71,0x9c,0x31,0x10,0x7f,0xb5,0x31,0x00,0x00, +0x49,0xc1,0x36,0xd0,0x6c,0x23,0xae,0x54,0xc1,0xa4,0x9d,0xd3,0x5a,0xca,0x38,0x42, +0x5d,0x2b,0x9f,0x4c,0xbe,0x24,0xa6,0x5b,0x6c,0xbc,0x42,0xbb,0x54,0x34,0x8d,0xc3, +0x9c,0x31,0x10,0x4b,0xa4,0x32,0x00,0x00,0xe9,0x25,0xd5,0xb6,0x78,0x58,0x1c,0x69, +0x1f,0x61,0x7b,0x94,0xd6,0x66,0xd7,0x65,0x8f,0x85,0x3b,0x56,0x22,0x74,0x5f,0x65, +0xb8,0x95,0xd1,0x7a,0xa1,0x79,0x58,0x65,0x9c,0x31,0x10,0xbf,0xa3,0x32,0x00,0x00, +0x31,0x6c,0x4e,0x75,0x9b,0x52,0xc8,0x68,0xb1,0xad,0x77,0x09,0x4b,0x94,0x4f,0x75, +0x81,0x91,0xaf,0x49,0xa5,0x25,0x7e,0x8d,0x61,0x71,0x5c,0x4d,0x79,0x86,0x9b,0x89, +0x9c,0x31,0x10,0xf4,0x95,0x44,0x00,0x00,0xc3,0x24,0x8e,0xd9,0x58,0xec,0x4a,0xa1, +0x66,0xd4,0x96,0xd3,0xb0,0x9b,0x99,0x23,0x72,0xdc,0x58,0xda,0x5d,0x1b,0x76,0xd3, +0x9a,0xd2,0xa3,0x24,0xb4,0xf3,0x9f,0xaa,0x9c,0x31,0x10,0xb0,0x87,0x66,0x20,0x00, +0x69,0xdb,0x3d,0xdb,0x4d,0xd3,0x49,0xdb,0x19,0xdb,0x39,0x9b,0xa1,0xdb,0xed,0xdb, +0xd9,0xdb,0xa1,0xd2,0x7d,0xdb,0x59,0x9b,0x39,0xdc,0x66,0x19,0xce,0xe3,0xde,0x4a, +0x9c,0x31,0x10,0x36,0xb8,0x98,0x20,0x00,0xa7,0x5d,0xb4,0x62,0xab,0x22,0xa5,0x84, +0x79,0xdd,0x71,0xa2,0x75,0xd3,0x5d,0xa4,0x3d,0xdb,0x35,0xda,0x45,0xdb,0x49,0xd4, +0x4d,0xe3,0x61,0xd3,0x71,0xdc,0x75,0xda,0x9c,0x31,0x10,0x39,0xd6,0x78,0x30,0x00, +0x78,0xd3,0x76,0xdb,0x80,0xdb,0x94,0xe2,0x9a,0x93,0x81,0x5a,0x5c,0x53,0x61,0x2d, +0x97,0x13,0xc0,0xda,0xa4,0x9a,0x5e,0xa4,0x3d,0x8a,0x70,0xa3,0xb7,0x13,0xc2,0x2c, +0x9c,0x31,0x10,0x88,0xd7,0x89,0x40,0x00,0x86,0xd3,0x44,0x64,0x3f,0x82,0x82,0xf2, +0xbc,0xc4,0xb6,0xab,0x7a,0xd3,0x42,0x5b,0x47,0x55,0x8a,0xe1,0xbc,0xd3,0xb0,0xda, +0x76,0xdc,0x42,0x0a,0x4b,0x5d,0x8a,0xd9,0x9c,0x31,0x10,0xad,0xc7,0x89,0x40,0x00, +0xf4,0xdb,0xd8,0xd2,0x68,0xdc,0x08,0x12,0x1b,0x5e,0x9e,0xa1,0xf4,0xd3,0xd2,0xe1, +0x64,0xcc,0x08,0x1a,0x1f,0x56,0xa2,0xe2,0xf2,0xcb,0xcc,0xe2,0x64,0xcc,0x0a,0x1a, +0x9c,0x31,0x10,0x09,0xc7,0x88,0x30,0x00,0x23,0x4e,0xa4,0xb0,0xf3,0x0c,0xc8,0xea, +0x64,0xcb,0x0e,0x23,0x23,0x8d,0xa4,0xa9,0xef,0x0b,0xc6,0xe4,0x68,0xd2,0x14,0x5c, +0x21,0x8b,0x9e,0xa9,0xe9,0x14,0xc8,0xa4,0x9c,0x31,0x10,0x09,0xc7,0x88,0x30,0x00, +0x72,0xd2,0x1e,0x9c,0x1b,0x88,0x92,0xab,0xe7,0x14,0xce,0x9c,0x78,0xe3,0x29,0x1c, +0x15,0x99,0x86,0xd5,0xe3,0x2a,0xd0,0x93,0x82,0xe3,0x39,0x9a,0x0e,0xed,0x6f,0x03, +0x9c,0x31,0x10,0xc2,0xc8,0x78,0x40,0x00,0xd8,0xd2,0xd8,0xc4,0x8e,0xea,0x4b,0x4b, +0x10,0x53,0x55,0x10,0xcc,0x84,0xdd,0x0b,0x9c,0xcb,0x5d,0x03,0x1a,0x2a,0x35,0x4d, +0xb6,0x94,0xe3,0x43,0xac,0xca,0x71,0x12,0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00, +0x34,0xdc,0x17,0x19,0x8e,0xcc,0xe1,0x33,0xc0,0x8c,0x80,0xdb,0x53,0x63,0x10,0x64, +0x59,0x28,0xd2,0x8b,0xd4,0xe4,0x94,0xe3,0x6f,0x13,0x28,0x65,0x1d,0x49,0xac,0x9a, +0x9c,0x31,0x10,0x4a,0xc8,0x88,0x40,0x00,0xe7,0x23,0xac,0x8c,0x7e,0xdb,0x57,0x24, +0x02,0x65,0x61,0x28,0xe0,0x8a,0xca,0xe3,0x8a,0xe4,0x7d,0x1c,0x2c,0x9c,0x09,0x48, +0xae,0xcb,0xe9,0x2c,0xa2,0xa4,0x84,0x92,0x9c,0x31,0x10,0xea,0xd9,0x98,0x40,0x00, +0x7b,0x1b,0x40,0x51,0x59,0x1d,0xb2,0xa4,0xa7,0x1b,0x82,0xd2,0x8a,0xdb,0x73,0x25, +0x30,0x5b,0x77,0x28,0xba,0x5b,0x93,0x14,0x80,0xd3,0x92,0xe2,0x65,0x22,0x2c,0xa5, +0x9c,0x31,0x10,0xf2,0xd9,0x88,0x40,0x00,0x8f,0x33,0xb8,0x9a,0x85,0x12,0x88,0xd3, +0x9a,0xeb,0x5d,0x2b,0x2c,0xae,0x97,0x22,0xb0,0x59,0x7b,0x13,0x92,0xd4,0xa0,0x93, +0x5d,0x24,0x2a,0x12,0x8d,0x2b,0xac,0x23,0x9c,0x31,0x10,0xd9,0xd9,0x88,0x30,0x00, +0x7b,0x2b,0x98,0xdb,0xa4,0x9b,0x6a,0xd2,0x2e,0x1c,0x6f,0x43,0xae,0x8a,0x81,0x0c, +0x90,0xd3,0xa6,0xdb,0x81,0x1b,0x47,0x19,0x43,0x2d,0x9e,0xeb,0x96,0x6a,0x84,0xe4, +0x9c,0x31,0x10,0xeb,0xda,0x78,0x30,0x00,0xa0,0xd2,0x9a,0xcb,0x6c,0xeb,0x38,0xb4, +0x61,0x6b,0xa7,0x0a,0x89,0x0c,0x8e,0xea,0xa0,0xcb,0x92,0xcb,0x64,0xeb,0x34,0x61, +0x6d,0x45,0xa7,0x0c,0x89,0x4a,0x8e,0xeb,0x9c,0x31,0x10,0xf3,0xda,0x68,0x30,0x00, +0xa2,0xcc,0x94,0xaa,0x63,0x0b,0x32,0xa2,0x6b,0x64,0x9c,0xed,0x8b,0x0b,0x9a,0xaa, +0x9e,0xeb,0x96,0xeb,0x71,0x0b,0x34,0xab,0x51,0x8c,0x8e,0xab,0x8c,0xab,0xa1,0x0a, +0x9c,0x31,0x10,0x48,0xd9,0x45,0x20,0x00,0xa6,0x95,0xa2,0x66,0x83,0x5a,0x44,0xa1, +0x2d,0x59,0x7d,0x35,0x8e,0xc1,0x9a,0x75,0xac,0x30,0xa8,0xc5,0x99,0x56,0x67,0x8a, +0x2a,0x69,0x46,0xc5,0x8a,0x05,0x92,0xc5,0x9c,0x31,0x10,0x06,0xd9,0x44,0x10,0x00, +0xa6,0x55,0xac,0x66,0xa8,0xa5,0x8b,0x35,0x50,0xb5,0x2b,0x20,0x5c,0xe4,0x8c,0x15, +0x98,0xc6,0xa8,0x45,0xa8,0x85,0x9e,0x75,0x81,0x75,0x52,0x85,0x3e,0x55,0x5e,0xa5, +0x9c,0x31,0x10,0x47,0xc8,0x32,0x00,0x00,0x96,0x09,0xa7,0xe5,0xcc,0xa2,0xbd,0x51, +0xbd,0xb9,0x84,0xb9,0x43,0x41,0x14,0xba,0x30,0xc5,0x82,0x38,0x99,0xb5,0xbb,0xcd, +0xbe,0xad,0xb5,0xcd,0xa2,0xb5,0x5d,0x3e,0x9c,0x31,0x10,0x2f,0xc7,0x32,0x00,0x00, +0x2e,0xa5,0x20,0x18,0x58,0xc9,0x96,0x39,0xa1,0x85,0xbf,0x85,0xc0,0x54,0xab,0xa5, +0x88,0x66,0x45,0x75,0x21,0x89,0x34,0x76,0x74,0x80,0x9e,0x66,0xac,0x79,0xbe,0x75, +0x9c,0x31,0x10,0xaa,0xc6,0x22,0x00,0x00,0xbd,0x61,0xa0,0x81,0x6e,0x69,0x38,0x95, +0x20,0x31,0x45,0xa5,0x8a,0x66,0xa3,0x74,0xa9,0x71,0xbf,0x80,0xbd,0x55,0x94,0x86, +0x61,0x65,0x37,0xa4,0x24,0x16,0x4c,0xb8,0x9c,0x31,0x10,0xaa,0xc6,0x22,0x00,0x00, +0x94,0x59,0xab,0x81,0xa9,0x55,0xbb,0x94,0xbc,0x45,0x92,0x89,0x5c,0x69,0x36,0xa4, +0x28,0x26,0x4d,0xa9,0x92,0x5a,0xae,0x80,0xab,0x65,0xb5,0x85,0xb8,0x65,0x96,0x85, +0x9c,0x31,0x10,0xb2,0xc6,0x32,0x00,0x00,0x60,0x65,0x38,0xa5,0x28,0x36,0x47,0xa4, +0x8e,0x55,0xb1,0x85,0xae,0x55,0xb2,0x96,0xb7,0x55,0x9b,0x95,0x68,0x55,0x3f,0x95, +0x29,0x31,0x3c,0x90,0x87,0x75,0xb1,0x79,0x9c,0x31,0x10,0x08,0xc5,0x32,0x00,0x00, +0xb1,0xa6,0xb1,0xc6,0xb6,0x11,0xa1,0x65,0x70,0x94,0x43,0xd5,0x27,0x90,0x30,0xc2, +0x80,0x44,0xb2,0x94,0xb1,0x58,0xae,0xb5,0xb6,0x26,0xa7,0xd2,0x77,0xa6,0x43,0x35, +0x9c,0x31,0x10,0x5a,0xc8,0x24,0x00,0x00,0x22,0x82,0x24,0x73,0x81,0x92,0xb5,0x63, +0xa9,0x93,0xab,0x74,0xb9,0x7b,0xb3,0x8b,0x7c,0x62,0x3a,0x8a,0x1c,0x93,0x19,0x54, +0x8e,0xbc,0xb5,0x2b,0xa1,0xc3,0xb2,0x41,0x9c,0x31,0x10,0x06,0xd9,0x44,0x10,0x00, +0xa0,0x85,0x9e,0x75,0x7d,0x76,0x5b,0x75,0x47,0x95,0x44,0x55,0x93,0xb5,0x92,0x24, +0x90,0xc4,0x9e,0x25,0xa9,0xb5,0x9d,0x55,0x7b,0x85,0x5d,0x75,0x3e,0x8a,0x44,0x65, +0x9c,0x31,0x10,0xa7,0xda,0x56,0x10,0x00,0xa1,0x14,0x80,0xc5,0x95,0x35,0xa0,0xc5, +0xab,0x15,0x90,0xf5,0x88,0xd5,0x59,0x25,0x3e,0xd9,0x47,0x08,0xa0,0xc5,0x73,0x36, +0x9e,0xa5,0x9f,0x64,0x9e,0x65,0x9b,0x85,0x9c,0x31,0x10,0x74,0xdb,0x57,0x20,0x00, +0x8c,0xc5,0x5f,0x15,0x4b,0x01,0x3c,0x95,0x95,0x45,0x74,0xe4,0x98,0xb5,0x9b,0x55, +0x96,0xa4,0xa4,0xf9,0x8f,0x49,0x6c,0x95,0x5d,0x39,0x30,0xc1,0x81,0x82,0x84,0x65, +0x9c,0x31,0x10,0xc2,0xdb,0x78,0x20,0x00,0x81,0x2a,0xa5,0x0c,0x8a,0xab,0xa7,0x2a, +0x96,0xea,0x78,0xac,0x67,0x0b,0x3f,0x0a,0x55,0x13,0x98,0x0d,0x6d,0x89,0xa7,0x2b, +0x8c,0x8c,0x98,0xea,0xa6,0xea,0x81,0x4c,0x9c,0x31,0x10,0xc2,0xdb,0x78,0x20,0x00, +0x74,0xab,0x58,0xd3,0x30,0x62,0x91,0xc5,0x73,0x0a,0x8e,0xca,0xa0,0x6c,0x83,0x2a, +0xaf,0x53,0x8e,0xc3,0x7e,0xab,0x70,0xec,0x41,0x22,0x51,0x2d,0x98,0x0a,0x66,0xc2, +0x9c,0x31,0x10,0x85,0xdc,0x89,0x30,0x00,0xa6,0x29,0x86,0x4d,0x96,0x31,0xa9,0xd1, +0x81,0xf5,0x7d,0xb5,0x61,0xcd,0x31,0x99,0x7a,0xf0,0x81,0xb5,0x7a,0x35,0xa5,0x75, +0x7d,0xcd,0xa5,0xc5,0x99,0xa9,0x7e,0x25,0x9c,0x31,0x10,0xdd,0xdb,0x99,0x20,0x00, +0x7a,0x13,0x52,0x9b,0x39,0x02,0x91,0xcd,0x6d,0xca,0x92,0x93,0x95,0xd4,0x82,0x5a, +0xad,0xdb,0x8d,0x9b,0x7d,0x9b,0x71,0x9b,0x45,0xd3,0x4d,0xdc,0x90,0xe1,0x69,0x5d, +0x9c,0x31,0x10,0x69,0xdb,0x99,0x30,0x00,0x9d,0x9a,0x8d,0x5b,0x8d,0xdb,0xa9,0x9a, +0x85,0xdc,0x79,0xe2,0x69,0xe3,0x35,0xab,0x6f,0x29,0x89,0xdd,0x72,0x99,0xa1,0xdc, +0x89,0xd3,0x96,0x13,0xa5,0xcb,0x7d,0xca,0x9c,0x31,0x10,0x68,0xda,0xa9,0x20,0x00, +0x75,0xd5,0x5e,0x19,0x38,0x51,0x82,0x0e,0x80,0xd8,0x7e,0x1e,0xa1,0x9d,0x89,0xa1, +0x9e,0x21,0x99,0xa1,0x75,0xe1,0x6d,0xe1,0x52,0x1d,0x46,0x6a,0x8d,0xac,0x7d,0xe2, +0x9c,0x31,0x10,0xcc,0xc9,0xa8,0x30,0x00,0x96,0x39,0xb9,0xb4,0xa1,0xb2,0xc2,0x3b, +0xa5,0xab,0x59,0xbb,0x41,0xbc,0x08,0x3c,0x4a,0x8a,0x99,0x42,0x8a,0x3c,0xa5,0xca, +0xb1,0x3c,0xba,0x43,0xb5,0xab,0x81,0xc3,0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00, +0x4b,0x23,0x25,0x1b,0x1d,0xb5,0x7a,0xa9,0x96,0xc4,0x9c,0xd2,0xaa,0xe4,0xb6,0xda, +0xc0,0x9c,0xa0,0xda,0x60,0x9b,0x31,0x1b,0x12,0x0b,0x52,0xf4,0x8e,0xb2,0x9c,0xcb, +0x9c,0x31,0x10,0xfa,0xc7,0x87,0x10,0x00,0xa4,0xc8,0xb0,0x61,0xbe,0xb1,0xa8,0xe5, +0x74,0xcd,0x46,0xd5,0x32,0x1d,0x3c,0xc0,0x64,0xa9,0x8c,0xe5,0xa2,0xe5,0xa8,0xd9, +0xb0,0xd9,0xb0,0x9d,0x9e,0xd9,0x7c,0xe1,0x9c,0x31,0x10,0xe7,0xc6,0x54,0x00,0x00, +0x4d,0xb9,0x27,0x45,0x2f,0x81,0x62,0x79,0x93,0x88,0xb4,0x66,0xcc,0x61,0xd2,0x95, +0xb0,0x75,0x72,0x85,0x2e,0x55,0x0f,0x75,0x2b,0x75,0x6d,0x74,0xa7,0x76,0xc8,0x65, +0x9c,0x31,0x10,0x52,0xc4,0x43,0x00,0x00,0xda,0xb5,0xd1,0x51,0xa1,0x6d,0x56,0x8a, +0x19,0x31,0x0f,0xc8,0x41,0x4e,0x85,0x51,0xb6,0x34,0xd2,0xd1,0xda,0x85,0xc2,0x08, +0x85,0xd2,0x3a,0x11,0x0f,0xa5,0x21,0x2c,0x9c,0x31,0x10,0x1a,0xc4,0x33,0x00,0x00, +0x5f,0xc2,0x9e,0x35,0xc4,0x34,0xd8,0xc5,0xd3,0x15,0xa5,0x55,0x5c,0xa5,0x1f,0x3a, +0x15,0x41,0x45,0x44,0x86,0x29,0xb6,0x3a,0xd1,0x54,0xd5,0x16,0xb5,0x45,0x74,0xa9, +0x9c,0x31,0x10,0xdd,0xc4,0x42,0x00,0x00,0x31,0x75,0x18,0x6c,0x37,0x46,0x73,0x8c, +0xa9,0x6d,0xc9,0xb2,0xd2,0x2c,0xb9,0x65,0x7e,0x69,0x40,0x6d,0x21,0x91,0x36,0x55, +0x6d,0xa5,0xa0,0x6a,0xc1,0x6d,0xcb,0x50,0x9c,0x31,0x10,0x95,0xc4,0x32,0x00,0x00, +0xb5,0x39,0x81,0xd5,0x4a,0x32,0x2e,0x35,0x3e,0x99,0x6c,0x36,0x9c,0x35,0xbb,0x24, +0xc0,0xb6,0xaa,0xb9,0x7f,0xb0,0x54,0xa1,0x3f,0xc6,0x4c,0x99,0x70,0x46,0x97,0x34, +0x9c,0x31,0x10,0x3b,0xb4,0x54,0x00,0x00,0xde,0x9c,0xe2,0x9a,0xbb,0x1b,0x79,0x24, +0x41,0x23,0x2c,0x93,0x40,0x92,0x71,0x22,0xa4,0xa5,0xc3,0x93,0xbd,0x20,0x99,0x16, +0x6a,0xca,0x46,0x93,0x42,0x5b,0x4e,0xdb,0x9c,0x31,0x10,0x39,0xa9,0xa8,0x40,0x00, +0x5d,0xbb,0x95,0xbb,0xc1,0xbb,0xd5,0xbb,0xcd,0xbb,0xb5,0xbb,0x95,0xbb,0x7d,0xbb, +0x5d,0xba,0x8a,0xcc,0x6e,0x34,0x95,0xbb,0x75,0x5a,0x59,0xb1,0x81,0xad,0x85,0xd2, +0x9c,0x31,0x10,0x26,0xb8,0x99,0x40,0x00,0x7e,0x14,0x7d,0xd2,0x8d,0xe5,0x96,0x5a, +0x95,0xdb,0x92,0x5c,0x79,0xe2,0x55,0xd3,0x3a,0xe9,0x31,0xdd,0x4a,0x93,0x65,0x64, +0x9e,0xd8,0x95,0xd6,0x85,0x09,0x79,0x9c,0x9c,0x31,0x10,0xf6,0xa6,0x99,0x40,0x00, +0x74,0xf0,0x75,0xcd,0x8a,0x1b,0x9e,0xac,0xae,0x52,0xb1,0x3a,0x9c,0xbc,0x6c,0x22, +0x40,0xd4,0x38,0x9b,0x74,0x5b,0xa8,0xba,0xc1,0x2b,0xb1,0x3c,0xa0,0x9b,0x64,0x42, +0x9c,0x31,0x10,0x03,0xa8,0x99,0x40,0x00,0x35,0x23,0x4e,0x2a,0x5a,0x0d,0x69,0xd3, +0x85,0x63,0xb1,0x82,0xae,0x31,0x96,0xa4,0x8e,0x1c,0x8e,0x1a,0x7a,0x9c,0x82,0xd2, +0xb6,0x54,0xc2,0xf3,0xa1,0xe4,0x92,0x03,0x9c,0x31,0x10,0x57,0x98,0x98,0x50,0x00, +0x5a,0xb8,0x25,0x3e,0x33,0x43,0x2b,0x0b,0x41,0xba,0x63,0xe3,0x4c,0x5c,0x4c,0x32, +0x5c,0x1a,0x3c,0x32,0x4b,0xa2,0x74,0x55,0x94,0x3c,0xae,0x4c,0xab,0xe2,0x9e,0x3a, +0x9c,0x31,0x10,0x8b,0x97,0x98,0x40,0x00,0xd3,0x6a,0x9c,0x13,0x80,0x67,0xb2,0x56, +0xb1,0x96,0x93,0x89,0x72,0xa7,0x9a,0x58,0x6b,0x38,0x3a,0x45,0x75,0x56,0x82,0xaa, +0x42,0xb6,0x53,0x86,0xa3,0x77,0x43,0x2a,0x9c,0x31,0x10,0xfa,0x98,0x97,0x20,0x00, +0x7a,0xa9,0xb2,0xba,0x92,0x44,0x64,0x52,0xab,0x63,0x84,0xcb,0x6b,0xba,0x67,0x3d, +0x55,0xb1,0x36,0xa4,0x4a,0xaa,0x54,0xb4,0x6a,0x2a,0x8d,0x54,0x89,0x5c,0x8c,0x49, +0x9c,0x31,0x10,0xf9,0x99,0x88,0x20,0x00,0x94,0x3c,0xa5,0x1b,0x8b,0x92,0xa4,0x04, +0x9c,0x1b,0x7c,0x0b,0xc3,0x14,0x7a,0xaa,0x8b,0x43,0x82,0x34,0x6a,0xd3,0x73,0x39, +0x8a,0x44,0x7b,0xd4,0x79,0xd2,0x8b,0x5a,0x9c,0x31,0x10,0x94,0x79,0x87,0x20,0x00, +0xba,0xd4,0x2c,0xcc,0x9b,0x32,0xa4,0x34,0x13,0xb2,0xd4,0x5a,0x7c,0x4c,0xdb,0xcc, +0xa1,0xcb,0xac,0x4a,0x9a,0x4b,0x34,0x54,0x71,0xe3,0x43,0xc3,0x0a,0xad,0xbb,0x42, +0x9c,0x31,0x10,0xee,0x89,0x87,0x30,0x00,0x32,0x31,0x72,0x23,0x49,0x9b,0x63,0x13, +0x79,0x93,0x5c,0x24,0x8b,0x1a,0x6a,0xa3,0x74,0x21,0x3c,0x22,0x54,0xb5,0x6b,0xc5, +0x53,0xbb,0x6a,0xc2,0x83,0x3b,0x62,0x32,0x9c,0x31,0x10,0xcc,0x99,0x76,0x30,0x00, +0x55,0x89,0x71,0x8a,0x5e,0x4d,0x5d,0x96,0x8a,0x9d,0x96,0x59,0x8a,0xab,0xa9,0xe2, +0x6d,0xe1,0x71,0xe3,0x61,0xa4,0x60,0xe5,0x5d,0xdc,0xc2,0x9c,0x76,0xa1,0xad,0xda, +0x9c,0x31,0x10,0xa9,0xa8,0x67,0x30,0x00,0x88,0x6a,0x69,0xa3,0x65,0xe4,0x62,0xe4, +0x6e,0xa4,0x79,0xe3,0xa1,0x6b,0x99,0xa3,0xad,0x5b,0x8d,0xa3,0x52,0x93,0x3e,0x0b, +0x36,0x1c,0x61,0xda,0x91,0xd9,0xdb,0x22,0x9c,0x31,0x10,0xb5,0xb9,0x66,0x40,0x00, +0xae,0x34,0xae,0x2e,0x81,0x2d,0x51,0xa3,0x2d,0x12,0x42,0x5b,0x5d,0xd3,0xb7,0x22, +0xc1,0x23,0xd9,0x54,0xad,0x13,0x6a,0x13,0x36,0x52,0x0a,0x93,0x29,0x23,0x96,0xa3, +0x9c,0x31,0x10,0x65,0xc9,0x66,0x30,0x00,0xa6,0xb5,0xb3,0x39,0xa8,0x91,0x88,0xb2, +0x5f,0x71,0x4a,0xf1,0x3a,0x91,0x71,0x74,0xa0,0x0d,0xab,0x6d,0xba,0x6d,0xa3,0x4d, +0x76,0xad,0x55,0x89,0x36,0xa9,0x42,0x8a,0x9c,0x31,0x10,0xc1,0xc9,0x55,0x30,0x00, +0x95,0x52,0x92,0xa2,0xb8,0xa5,0xb4,0x58,0x9f,0x74,0x7d,0x65,0x50,0x94,0x2e,0x01, +0x46,0xe4,0x97,0x55,0x87,0x75,0xb8,0x76,0xab,0x66,0xa2,0x96,0x95,0x66,0x6b,0x66, +0x9c,0x31,0x10,0xdc,0xca,0x56,0x40,0x00,0x37,0x36,0x32,0x71,0x81,0x34,0x87,0x04, +0x96,0xf5,0xb0,0xd5,0x99,0x05,0x9c,0xf5,0x94,0xf5,0x68,0xf5,0x4b,0x05,0x2a,0x90, +0x7f,0xb1,0x90,0x95,0x86,0xf5,0xaa,0xf5,0x9c,0x31,0x10,0xe9,0xc9,0x65,0x30,0x00, +0x95,0x2e,0x9a,0xcd,0x98,0xc8,0x82,0xed,0x63,0x09,0x47,0x29,0x2e,0x06,0xa5,0x8c, +0x7d,0x28,0x92,0xac,0xa6,0x8c,0x8d,0x8d,0x9c,0xcd,0x92,0xcd,0x80,0xed,0x65,0x29, +0x9c,0x31,0x10,0x42,0xcb,0x66,0x30,0x00,0x40,0xf1,0x32,0xc2,0xb3,0x05,0x75,0x25, +0x92,0xd5,0xa2,0xe5,0x89,0x25,0xa0,0xe5,0x8c,0xe5,0x85,0x05,0x6e,0xe5,0x55,0x05, +0x24,0xc5,0x91,0x76,0x94,0x96,0x72,0xf6,0x9c,0x31,0x10,0xf4,0xca,0x66,0x40,0x00, +0xab,0x45,0x88,0xc5,0x94,0xd5,0x99,0x25,0x87,0x05,0x78,0xc5,0x63,0x15,0x32,0xf4, +0x51,0x28,0xb6,0x26,0x69,0xb6,0x9a,0xe6,0x9e,0x96,0x89,0x55,0xa0,0xe5,0x90,0xc5, +0x9c,0x31,0x10,0x7b,0xca,0x67,0x40,0x00,0x7f,0x15,0x6d,0x05,0x4a,0xf5,0x24,0x60, +0xa7,0xe1,0x88,0xa5,0x78,0xb5,0xa9,0x55,0x88,0xe5,0x9a,0xc5,0x9d,0x25,0x85,0x15, +0x76,0xa5,0x5f,0x25,0x2a,0xe9,0x5f,0x58,0x9c,0x31,0x10,0xe6,0xcb,0x67,0x40,0x00, +0xb8,0x75,0x67,0x55,0x9c,0xf5,0x9c,0xc5,0x87,0x25,0xa2,0xf5,0x90,0xd5,0x81,0x15, +0x6a,0xf5,0x51,0x05,0x20,0xa0,0xa1,0x81,0x94,0xb5,0x6c,0xe5,0xa9,0x25,0x8c,0xe5, +0x9c,0x31,0x10,0x53,0xca,0x57,0x40,0x00,0x90,0xc5,0xa5,0x25,0x88,0xf5,0x7c,0xb5, +0x63,0x15,0x3b,0x21,0x38,0x96,0xbe,0xc6,0x73,0xa5,0x84,0x85,0xac,0xe5,0x85,0x65, +0x98,0xc5,0xa0,0xb5,0x83,0x55,0x7c,0xb5,0x9c,0x31,0x10,0xe6,0xcb,0x67,0x40,0x00, +0x5c,0xf5,0x31,0x15,0x4d,0x09,0xbc,0x86,0x6d,0x55,0x8a,0xe5,0xa8,0xc5,0x85,0x25, +0x9c,0xf5,0x9c,0xc5,0x83,0x25,0x72,0xf5,0x56,0xf5,0x22,0xda,0x73,0x75,0xb2,0x65, +0x9c,0x31,0x10,0x41,0xcb,0x56,0x40,0x00,0x67,0x14,0x95,0x24,0xa4,0xb5,0x83,0x05, +0xa3,0x26,0x9c,0xb6,0x83,0x05,0x71,0x15,0x50,0xf4,0x1c,0xb9,0x83,0x82,0xa8,0x89, +0x68,0xf5,0x99,0x44,0xa2,0xc4,0x82,0xe5,0x9c,0x31,0x10,0x6a,0xcb,0x56,0x30,0x00, +0x9f,0x25,0xa2,0xd6,0x80,0xf5,0x6d,0x05,0x4d,0x05,0x1e,0xa4,0x8b,0x72,0xa2,0xc6, +0x6a,0xc6,0x95,0x35,0xa0,0xe4,0x84,0xd4,0x9b,0x15,0xa8,0xe5,0x80,0xf5,0x68,0xf5, +0x9c,0x31,0x10,0xdc,0xca,0x56,0x40,0x00,0x49,0x35,0x22,0x50,0x8f,0xb1,0xa0,0xd6, +0x70,0x96,0x91,0x45,0xa4,0xf5,0x8a,0xc5,0x97,0x15,0xaa,0xf4,0x80,0xf5,0x64,0xd5, +0x45,0x45,0x22,0x60,0x8b,0x81,0xa2,0xf6,0x9c,0x31,0x10,0x65,0xc9,0x66,0x30,0x00, +0x74,0x4e,0x8d,0x4d,0xa5,0x0d,0x90,0x6c,0x95,0x0d,0xa8,0xed,0x80,0xed,0x62,0xad, +0x3d,0x6e,0x24,0x05,0x91,0x6c,0x9d,0x49,0x7c,0x4d,0x95,0x0e,0x99,0x2e,0x90,0x8d, +0x9c,0x31,0x10,0x75,0xc9,0x55,0x20,0x00,0xa4,0x95,0x96,0x45,0x82,0xa4,0x6b,0x54, +0x30,0x90,0x2f,0x66,0x8c,0x26,0x78,0xe5,0x92,0x55,0xa9,0x44,0x9f,0xb4,0xa8,0x65, +0x9f,0x76,0x7b,0x76,0x7f,0x76,0x5a,0x75,0x9c,0x31,0x10,0xf7,0xca,0x56,0x30,0x00, +0x2a,0xe9,0x4f,0x58,0x8c,0x55,0x7f,0x35,0x99,0x15,0x9c,0xb6,0x9f,0x05,0xad,0x05, +0x98,0xd5,0x7b,0x15,0x78,0xe5,0x4b,0x09,0x22,0xb5,0x67,0x76,0x82,0xc6,0x88,0xc5, +0x9c,0x31,0x10,0xd9,0xc9,0x45,0x30,0x00,0xa1,0xa5,0xa0,0x78,0xa9,0x58,0xaf,0xa4, +0x86,0x65,0x78,0x75,0x68,0x76,0x3a,0x81,0x32,0x56,0x7a,0x46,0x83,0xc5,0x94,0x64, +0xa2,0x54,0xa4,0xa1,0xae,0x61,0xa1,0x55,0x9c,0x31,0x10,0x3b,0xc9,0x54,0x10,0x00, +0x79,0x96,0x75,0x65,0x58,0x75,0x2e,0x69,0x4c,0xc6,0x7c,0x35,0x8b,0x74,0xa1,0x95, +0xa4,0x65,0xaa,0x66,0xb0,0xa5,0x8e,0x55,0x77,0x75,0x68,0x75,0x45,0x81,0x30,0x52, +0x9c,0x31,0x10,0x98,0xc8,0x53,0x00,0x00,0x63,0x6b,0x82,0xdb,0x97,0x4b,0xa4,0x52, +0xa8,0xc2,0xae,0x52,0xa4,0x63,0x80,0xab,0x72,0x64,0x59,0x84,0x39,0x6d,0x43,0xdc, +0x71,0x23,0x8d,0x73,0x9f,0xb3,0xa8,0x5c,0x9c,0x31,0x10,0x0f,0xc8,0x42,0x00,0x00, +0xad,0x64,0xad,0xbb,0x92,0x52,0x78,0x7a,0x64,0x82,0x4b,0x82,0x39,0x51,0x57,0x6b, +0x7e,0xab,0x99,0x64,0xa6,0x6a,0xac,0x9a,0xaf,0x73,0xa1,0x5c,0x83,0x9c,0x6d,0x73, +0x9c,0x31,0x10,0xe8,0xc7,0x43,0x00,0x00,0x57,0x3a,0x40,0x34,0x42,0xf3,0x68,0x1a, +0x8c,0xaa,0xa1,0xd4,0xab,0x34,0xb0,0xa2,0xad,0x49,0x93,0xbb,0x79,0xb3,0x63,0x3c, +0x4c,0xd2,0x3c,0xac,0x52,0x25,0x79,0xd4,0x9c,0x31,0x10,0x4b,0xc6,0x44,0x10,0x00, +0x98,0x75,0xa8,0x45,0xb2,0x95,0xb4,0xc5,0xa2,0x25,0x84,0x95,0x6a,0x65,0x51,0x95, +0x3b,0x11,0x42,0xb2,0x69,0xa6,0x90,0x49,0xa8,0x75,0xb5,0xa4,0xb8,0x65,0xaa,0x55, +0x9c,0x31,0x10,0x4b,0xc6,0x44,0x10,0x00,0x8d,0x95,0x71,0x75,0x57,0x75,0x3f,0x7a, +0x3a,0xc4,0x5a,0x64,0x85,0x51,0xa3,0x96,0xb3,0x76,0xb9,0x65,0xb0,0x74,0x95,0x85, +0x76,0x75,0x5a,0x65,0x44,0x95,0x39,0x89,0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00, +0x53,0x32,0x7e,0x6d,0xa0,0x6d,0xb1,0x6d,0xb7,0x48,0xb2,0x6d,0x9a,0x92,0x7b,0x8e, +0x5d,0x2d,0x47,0xac,0x3a,0x55,0x4e,0x35,0x78,0x51,0x9c,0x89,0xaf,0x49,0xb7,0x49, +0x9c,0x31,0x10,0x0d,0xc5,0x34,0x00,0x00,0xb5,0x4c,0x9f,0x8d,0x7e,0x8b,0x5e,0x4b, +0x47,0xa9,0x3a,0x34,0x4e,0x54,0x77,0x52,0x9b,0xa1,0xb0,0x4b,0xb9,0x6b,0xb6,0x32, +0x9e,0x74,0x7c,0x8c,0x5a,0x6b,0x43,0xa9,0x9c,0x31,0x10,0xff,0xc6,0x44,0x00,0x00, +0x3a,0x69,0x52,0x66,0x7b,0x65,0x9e,0x85,0xb1,0x74,0xb9,0x95,0xb4,0x65,0x99,0x75, +0x75,0x65,0x54,0x85,0x3f,0x65,0x3d,0xb4,0x5d,0x74,0x85,0x65,0xa4,0x76,0xb5,0x65, +0x9c,0x31,0x10,0x3d,0xc6,0x33,0x00,0x00,0xbc,0x85,0xae,0x74,0x8d,0x84,0x66,0x55, +0x48,0xa6,0x39,0x21,0x48,0x84,0x6f,0x65,0x96,0x99,0xaf,0x65,0xbb,0x81,0xb9,0x75, +0x9e,0x79,0x76,0x75,0x51,0x71,0x3b,0x56,0x9c,0x31,0x10,0x0d,0xc5,0x34,0x00,0x00, +0x3e,0xc3,0x61,0x61,0x8b,0x62,0xaa,0x53,0xba,0x6c,0xbd,0x6c,0xa7,0x6c,0x7f,0x8b, +0x56,0x6a,0x3c,0x72,0x3b,0x91,0x5a,0x6b,0x85,0x44,0xa8,0x6d,0xbb,0x6b,0xbf,0x6a, +0x9c,0x31,0x10,0x1a,0xc4,0x33,0x00,0x00,0xaa,0xb4,0x80,0xc5,0x54,0xa5,0x3a,0x4a, +0x3b,0x69,0x5d,0x36,0x88,0x15,0xab,0xb5,0xbf,0x24,0xbf,0x45,0xa6,0x35,0x78,0x35, +0x4c,0x25,0x34,0x05,0x3f,0x62,0x67,0x44,0x9c,0x31,0x10,0x02,0xc4,0x23,0x00,0x00, +0x93,0xb0,0xb5,0xb5,0xc3,0x26,0xba,0xb2,0x98,0x42,0x67,0x49,0x3f,0x55,0x32,0x85, +0x4d,0x34,0x7b,0x18,0xa6,0x56,0xc0,0xaa,0xc3,0xd5,0xad,0x21,0x7e,0x24,0x4e,0x58, +0x9c,0x31,0x10,0x8d,0xc4,0x22,0x00,0x00,0x33,0x09,0x3d,0x62,0x66,0xb1,0x96,0xc1, +0xba,0x28,0xc5,0xb5,0xb7,0x35,0x8e,0x21,0x5b,0xd5,0x38,0x28,0x36,0x58,0x5a,0xa6, +0x8b,0xb2,0xb3,0xb6,0xc4,0xc8,0xba,0x45,0x9c,0x31,0x10,0xee,0xc3,0x33,0x00,0x00, +0x94,0x95,0x62,0x45,0x3d,0x35,0x37,0x49,0x57,0xa9,0x88,0xa5,0xb1,0xb5,0xc3,0x44, +0xb8,0x45,0x93,0x85,0x63,0x59,0x40,0x25,0x3b,0xba,0x5b,0xa6,0x8a,0xb4,0xb2,0x34, +0x9c,0x31,0x10,0x02,0xc4,0x23,0x00,0x00,0xc0,0xb0,0xb1,0xc9,0x8a,0xaa,0x5d,0x46, +0x41,0x35,0x42,0xb5,0x65,0xa4,0x93,0xb5,0xb6,0xd9,0xbd,0x99,0xa7,0x45,0x7c,0x91, +0x54,0x55,0x40,0xa5,0x4d,0xd5,0x75,0xa5,0x9c,0x31,0x10,0x1c,0xb6,0x54,0x00,0x00, +0xc2,0xed,0xf6,0xcd,0xeb,0x0d,0xaa,0xed,0x52,0xed,0x16,0xed,0x0c,0xcd,0x41,0x0d, +0x98,0xed,0xe5,0x7a,0xf3,0x15,0xbe,0xed,0x6c,0xcd,0x28,0xed,0x10,0xcd,0x32,0xed, +0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00,0x85,0x39,0xd4,0x56,0xed,0x71,0xc2,0x31, +0x78,0x8c,0x37,0x4d,0x1d,0xb1,0x35,0x2d,0x7b,0x8e,0xc5,0x4d,0xe2,0xa1,0xc1,0x11, +0x7f,0xcd,0x44,0x2d,0x2b,0xad,0x3d,0x51,0x9c,0x31,0x10,0x0e,0xb3,0x21,0x00,0x00, +0x76,0xc9,0xb6,0x46,0xd2,0x89,0xb9,0x4d,0x81,0x6c,0x4e,0x31,0x3a,0xb2,0x4a,0x4d, +0x77,0x69,0xaa,0x51,0xc1,0x6e,0xad,0x71,0x7f,0x6c,0x57,0x72,0x48,0x6d,0x57,0x65, +0x9c,0x31,0x10,0x0c,0xa1,0x21,0x00,0x00,0x78,0x4d,0xc5,0xd1,0xe5,0x8c,0xc4,0x32, +0x7c,0x29,0x3f,0x25,0x2d,0xcd,0x4a,0x4d,0x80,0xce,0xb4,0x2a,0xc4,0xad,0xaa,0xa9, +0x79,0x90,0x52,0xb1,0x49,0xc6,0x5e,0x91,0x9c,0x31,0x10,0xf1,0x92,0x11,0x00,0x00, +0x87,0x55,0xc4,0x85,0xd1,0x65,0xaf,0x65,0x78,0xc4,0x4d,0x85,0x43,0x61,0x5b,0x51, +0x83,0xa9,0xa2,0x66,0xa8,0x36,0x95,0x85,0x7a,0x51,0x67,0x84,0x65,0xa1,0x73,0x75, +0x9c,0x31,0x10,0x96,0x72,0x12,0x00,0x00,0x96,0xeb,0xc5,0x15,0xbf,0x0c,0x94,0xea, +0x66,0xeb,0x4d,0x0a,0x50,0xeb,0x72,0xcb,0x89,0x14,0x6e,0xf3,0x5a,0xcb,0x67,0x0a, +0x7a,0xc4,0x8d,0x43,0x90,0xd3,0x87,0x72,0x9c,0x31,0x10,0x17,0x62,0x21,0x00,0x00, +0x64,0x90,0x42,0xc9,0x4d,0x08,0x75,0x2d,0x9b,0x52,0xa4,0xcd,0xa0,0xee,0x86,0x4d, +0x61,0x09,0x55,0x71,0x72,0xb9,0xa2,0xc9,0xc9,0x0d,0xc8,0xed,0xb2,0xee,0x94,0xcd, +0x9c,0x31,0x10,0x50,0x52,0x11,0x00,0x00,0x5e,0xc9,0x49,0x94,0x56,0x23,0x9d,0x93, +0xd6,0x01,0xd9,0xda,0xba,0x9c,0x91,0xf1,0x65,0x9d,0x4d,0xec,0x4e,0x0a,0x6d,0xd5, +0x9a,0x99,0xb1,0x14,0xa2,0x8b,0x95,0xa2,0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00, +0x7d,0x5e,0x5f,0x1c,0x39,0x16,0x35,0xee,0x4a,0x14,0x69,0x9a,0x84,0xd8,0x79,0x69, +0x79,0xe1,0x55,0xa6,0x39,0xe1,0x31,0xe5,0x31,0x65,0x61,0xe4,0x86,0x99,0x8e,0x16, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_CHARGE_PLEASE.txt b/config/_default_cfg_src_/res/cn/SOUND_CHARGE_PLEASE.txt new file mode 100644 index 0000000..d2e5b69 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_CHARGE_PLEASE.txt @@ -0,0 +1,275 @@ +0x9c,0x31,0x10,0x39,0x21,0x21,0x00,0x00,0x7d,0xbb,0x7d,0xbb,0x7d,0xbb,0x7d,0xbb, +0x7d,0xc5,0x98,0xb3,0x62,0x3c,0x5d,0xba,0xb2,0xea,0xbd,0x4a,0x44,0xb3,0x30,0xab, +0x2e,0x3b,0x44,0xbe,0x56,0xba,0x3d,0x31,0x9c,0x31,0x10,0xcf,0x41,0x11,0x00,0x00, +0x65,0x54,0x58,0xa3,0x5c,0x19,0x60,0xec,0x46,0x8b,0x4c,0x13,0x39,0x63,0x62,0xd3, +0x66,0xcb,0x6d,0x22,0x6e,0xd4,0x66,0x5b,0x69,0x1a,0x79,0x11,0x80,0xa2,0x6b,0xab, +0x9c,0x31,0x10,0x1e,0x23,0x21,0x00,0x00,0x53,0xc4,0x5b,0xcc,0x5b,0x4a,0x6c,0xbb, +0x53,0x53,0x24,0x41,0x43,0x45,0xa4,0xb9,0x63,0xb2,0xbb,0xc3,0x24,0xec,0x92,0x0a, +0x95,0xc1,0xa2,0x48,0x6c,0xbc,0x33,0x3d,0x9c,0x31,0x10,0xdf,0x33,0x34,0x20,0x00, +0x74,0x5d,0x98,0xe1,0x89,0x1d,0x28,0xd9,0x52,0xe5,0x59,0x21,0x89,0x1d,0x68,0xd9, +0x3b,0x19,0x86,0xa1,0x55,0x21,0x65,0x19,0xa6,0xe1,0xc5,0x19,0xb6,0xd5,0xd8,0x0c, +0x9c,0x31,0x10,0x3f,0x87,0x67,0x20,0x00,0x89,0xdb,0xa9,0x82,0xc4,0x1d,0x76,0x62, +0x79,0xc3,0x7d,0xe2,0x7a,0x1b,0x71,0xdb,0x69,0xda,0x6d,0xdb,0x6d,0xe3,0x6d,0xdb, +0x71,0xdc,0x69,0xda,0x69,0xda,0x6d,0xec,0x9c,0x31,0x10,0xad,0x54,0x77,0x30,0x00, +0x19,0x69,0x13,0x95,0x34,0x48,0x2c,0x86,0x4c,0x95,0x82,0x57,0xbc,0x88,0xb2,0x79, +0xbb,0x74,0xc1,0xba,0xd4,0x5a,0xbb,0x84,0x92,0xa4,0x43,0x1a,0x5b,0xd8,0x63,0x72, +0x9c,0x31,0x10,0xa3,0x54,0x88,0x30,0x00,0x72,0xb8,0x73,0x0a,0xb4,0xe6,0x97,0x35, +0x7a,0xc7,0x99,0x07,0x98,0xd7,0x89,0x48,0x92,0xc6,0x70,0xd7,0x65,0x75,0x42,0x96, +0x25,0x0a,0x19,0x26,0x18,0x96,0x59,0x1c,0x9c,0x31,0x10,0xe5,0x76,0x88,0x40,0x00, +0x82,0x76,0x7b,0x66,0x8b,0x85,0x82,0x79,0x83,0x54,0x73,0x77,0x7b,0x78,0x7b,0x57, +0x73,0x95,0x82,0x5c,0x83,0x87,0x82,0x46,0x53,0xd4,0x99,0x36,0xf2,0xaa,0x34,0x4a, +0x9c,0x31,0x10,0xc9,0x86,0x99,0x60,0x00,0x8a,0xad,0x7c,0x29,0x69,0x6d,0x62,0x71, +0x54,0x71,0x53,0x8e,0x63,0x4e,0xb8,0x8d,0x6c,0x61,0x5a,0x64,0x59,0x88,0x63,0x58, +0x41,0x95,0x3b,0x72,0x54,0x6a,0x62,0x89,0x9c,0x31,0x10,0x1f,0x76,0x89,0x60,0x00, +0x96,0x81,0x77,0x70,0x88,0x55,0xb3,0x55,0xc9,0x2a,0xc6,0x8a,0xc6,0xed,0xa5,0x21, +0xe4,0xac,0xe5,0x39,0xd4,0xf5,0xe4,0xe6,0xd6,0xc9,0xd5,0x2d,0xe8,0xc9,0x97,0x48, +0x9c,0x31,0x10,0xd1,0x86,0x89,0x60,0x00,0x7b,0x35,0x92,0xb5,0xa4,0x0a,0xa1,0x92, +0x9c,0x66,0xaa,0x4d,0x8d,0x65,0x74,0x6c,0x84,0x6c,0x8b,0x35,0x9b,0xc9,0xb8,0x31, +0xaa,0x4d,0xd9,0x69,0x88,0x45,0x95,0xac,0x9c,0x31,0x10,0x71,0x97,0x99,0x60,0x00, +0x72,0x70,0x73,0x51,0x6c,0x71,0x53,0x89,0x3a,0x2d,0x52,0x8d,0x52,0x6d,0x54,0x49, +0x51,0x91,0x54,0x48,0x61,0x64,0x6b,0x70,0x93,0x59,0xab,0x6d,0x8c,0x6d,0x83,0x71, +0x9c,0x31,0x10,0xde,0x76,0x89,0x50,0x00,0x1c,0x66,0x21,0x96,0x43,0x88,0x75,0x46, +0x51,0xa8,0x9d,0x48,0xb1,0x47,0x8b,0xc5,0x55,0x27,0x72,0xb6,0xc5,0x55,0x96,0x76, +0xbd,0x6b,0x46,0x4b,0x0c,0xa5,0x32,0x54,0x9c,0x31,0x10,0xd6,0x86,0x78,0x60,0x00, +0x33,0xb1,0x64,0x65,0x68,0xb1,0x55,0x75,0x82,0x49,0xc2,0x89,0xcb,0x21,0x7b,0x4c, +0x6a,0xa8,0xb5,0x58,0xd9,0x69,0xa4,0x79,0x3b,0x8d,0x8c,0x51,0xaa,0x61,0xc3,0x31, +0x9c,0x31,0x10,0x8d,0xc6,0x87,0x50,0x00,0x7e,0xed,0x7c,0xcd,0x7f,0x2c,0x7e,0xd1, +0x80,0xea,0x86,0xd5,0x89,0x25,0x7a,0x9c,0x66,0xdd,0x5a,0xde,0x69,0x1e,0x96,0xe1, +0xbe,0x94,0xbf,0x60,0x8e,0xa0,0x53,0x15,0x9c,0x31,0x10,0x9a,0xd6,0x88,0x40,0x00, +0x52,0x64,0x53,0x14,0x72,0xa2,0x9a,0xd3,0xb0,0xa3,0xae,0xd3,0x9a,0xe3,0x75,0x12, +0x48,0xeb,0x33,0x8a,0x56,0xe6,0x8c,0xd2,0xaa,0xdc,0xb4,0xa1,0xb5,0x1b,0x9e,0xa4, +0x9c,0x31,0x10,0xbb,0xd7,0x99,0x30,0x00,0x67,0x1b,0x2e,0xa4,0x27,0x4a,0x62,0xe2, +0x9d,0x14,0xae,0xe4,0xb7,0x12,0xba,0xe3,0xa3,0x5b,0x62,0xe4,0x26,0xda,0x23,0x51, +0x68,0xdd,0x9e,0xcc,0xa6,0xdb,0xaa,0x99,0x9c,0x31,0x10,0xe0,0xd8,0x89,0x40,0x00, +0xba,0xe5,0xae,0xdb,0x74,0x9a,0x37,0x13,0x24,0x52,0x54,0xf2,0x8e,0x8e,0x9a,0xea, +0x9a,0xd2,0xae,0xe3,0xba,0xd4,0x99,0x23,0x5e,0x92,0x35,0x2a,0x37,0x2d,0x6e,0xdb, +0x9c,0x31,0x10,0x68,0xd8,0x79,0x40,0x00,0x8d,0x11,0x90,0xe4,0x9e,0xec,0xb1,0x03, +0xb2,0xf3,0x90,0xeb,0x5e,0xcb,0x3b,0x12,0x43,0x93,0x71,0x0e,0x85,0x2a,0x8e,0xe2, +0x9e,0xe4,0xaa,0xc4,0xae,0xeb,0x90,0xab,0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00, +0x4a,0x9b,0x0d,0x1b,0x0d,0xae,0x56,0xe4,0x82,0xe0,0x9c,0xe3,0xb9,0x24,0xcc,0xe3, +0xd9,0x9a,0xb0,0xdb,0x63,0x1c,0x29,0x9b,0x0c,0x11,0x3c,0x59,0x76,0x1d,0x94,0x5d, +0x9c,0x31,0x10,0x77,0xc8,0x67,0x30,0x00,0xaa,0xcc,0xc2,0xc8,0xd0,0xa5,0xc2,0xa9, +0x82,0xe6,0x4a,0xee,0x1c,0xb5,0x21,0xac,0x5d,0x30,0x85,0x52,0x9f,0x12,0xb4,0xd1, +0xc6,0xd1,0xc7,0x15,0xa2,0x92,0x6c,0xb1,0x9c,0x31,0x10,0xc3,0xc8,0x67,0x20,0x00, +0x42,0xe9,0x20,0x60,0x37,0x05,0x67,0x06,0x89,0x49,0xa1,0x2d,0xb7,0x0d,0xc4,0xb1, +0xbd,0x2d,0x98,0xed,0x6c,0xcd,0x47,0x09,0x26,0x89,0x3a,0xc9,0x65,0x09,0x89,0x2d, +0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00,0xa2,0x94,0xb9,0x75,0xc3,0x25,0xba,0x95, +0x98,0xb5,0x70,0x61,0x49,0x71,0x2b,0x21,0x39,0x55,0x60,0xa6,0x86,0xa5,0xa2,0x65, +0xb9,0x65,0xc4,0x45,0xba,0xa5,0x98,0xa5,0x9c,0x31,0x10,0x7a,0xc7,0x54,0x00,0x00, +0x70,0x55,0x49,0x76,0x2a,0x31,0x35,0x66,0x5c,0xa5,0x85,0x94,0xa2,0x55,0xba,0x75, +0xc3,0x65,0xb9,0xb4,0x9b,0x95,0x75,0x55,0x4e,0x85,0x2d,0x45,0x31,0xa1,0x58,0xa0, +0x9c,0x31,0x10,0x62,0xc7,0x44,0x00,0x00,0x81,0x61,0x9f,0x56,0xb5,0x85,0xbf,0x74, +0xb7,0xa5,0x9e,0x46,0x7f,0x65,0x60,0x74,0x43,0x85,0x37,0xa9,0x4e,0x26,0x71,0x74, +0x8e,0x81,0xa4,0x76,0xb4,0x85,0xb5,0x64,0x9c,0x31,0x10,0x75,0xc6,0x43,0x00,0x00, +0xa9,0x3a,0x94,0x5b,0x79,0x23,0x56,0x4b,0x39,0x81,0x3d,0x4a,0x5b,0x5b,0x80,0x2c, +0x99,0xc3,0xae,0x2b,0xb8,0x3a,0xb1,0xcc,0xa1,0x23,0x89,0xcc,0x6a,0x33,0x4a,0x34, +0x9c,0x31,0x10,0xff,0xc6,0x44,0x00,0x00,0x3a,0xc9,0x4a,0x26,0x6c,0x75,0x8b,0x95, +0xa0,0x65,0xb1,0x95,0xb3,0x65,0xa7,0x95,0x96,0x75,0x7f,0x65,0x62,0x85,0x46,0x65, +0x40,0x82,0x57,0x94,0x79,0x65,0x92,0x55,0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00, +0xc8,0x94,0xdf,0x95,0xd7,0x52,0xbe,0x55,0x9d,0x95,0x6e,0xa5,0x36,0x75,0x0d,0x31, +0x13,0x35,0x47,0x96,0x82,0xc4,0xaa,0x85,0xc8,0x65,0xd6,0x35,0xcd,0x94,0xb5,0xb5, +0x9c,0x31,0x10,0xf9,0xb4,0x23,0x00,0x00,0x90,0x99,0x5f,0x29,0x2f,0x09,0x16,0x49, +0x27,0x81,0x5a,0x91,0x8c,0x92,0xad,0x75,0xc5,0xa5,0xcf,0x75,0xc7,0x55,0xab,0x55, +0x80,0x55,0x51,0xa5,0x2d,0xc5,0x21,0xe5,0x9c,0x31,0x10,0xf3,0xb5,0x32,0x00,0x00, +0x3b,0xa9,0x6e,0x79,0x9a,0x58,0xb3,0x39,0xc2,0x49,0xc4,0x45,0xb2,0x66,0x8e,0x71, +0x65,0x70,0x46,0x75,0x36,0x80,0x3a,0x76,0x55,0x91,0x7e,0x91,0xa2,0x95,0xb5,0x95, +0x9c,0x31,0x10,0x28,0xa3,0x23,0x00,0x00,0xf3,0xb1,0xd8,0x95,0xa4,0x79,0x6b,0x2d, +0x3d,0x59,0x27,0x28,0x29,0x59,0x3f,0x72,0x65,0x85,0x94,0xa9,0xb8,0x75,0xc6,0x8d, +0xbd,0xb1,0xa9,0x6d,0x90,0x99,0x79,0x8c,0x9c,0x31,0x10,0x5b,0x85,0x43,0x00,0x00, +0x1e,0xed,0x01,0x2d,0x04,0xb0,0x0d,0x25,0x27,0x4a,0x68,0xed,0xbc,0xb1,0xe5,0x0d, +0xf2,0xed,0xde,0xec,0xb4,0xae,0x75,0x0c,0x1d,0xa1,0x0b,0x45,0x30,0xaa,0x5d,0x30, +0x9c,0x31,0x10,0xe1,0x98,0x85,0x20,0x00,0x81,0xdd,0xa9,0xdd,0xd5,0xdd,0xdd,0xdd, +0xc5,0xdd,0x91,0xdd,0x61,0xdd,0x39,0xdd,0x25,0xdd,0x29,0xdd,0x55,0xdd,0x91,0xdd, +0xcd,0xdd,0xe1,0x99,0xe9,0x5a,0xd0,0x49,0x9c,0x31,0x10,0x0b,0x99,0x98,0x60,0x00, +0x84,0x25,0x83,0x51,0x3c,0x75,0x2c,0x6d,0x3b,0x69,0x83,0x6d,0xab,0x4d,0xbb,0x4d, +0x93,0x6d,0x6b,0x71,0x4b,0x6d,0x2d,0xad,0x14,0x49,0x3c,0x91,0x85,0xa0,0xcc,0x6c, +0x9c,0x31,0x10,0xdd,0xaa,0x9a,0x60,0x00,0xbb,0xc6,0xcb,0xa8,0x7b,0x4b,0x75,0xc6, +0x5e,0x38,0x5e,0xd6,0x7e,0xa7,0xbd,0xd5,0xac,0x37,0x6b,0xd6,0x53,0x59,0x53,0x56, +0x3a,0xb9,0x2a,0x46,0x4b,0x58,0x73,0x56,0x9c,0x31,0x10,0x5a,0x9b,0xa8,0x30,0x00, +0x84,0x3b,0x5c,0x34,0x5b,0xc4,0x84,0x29,0x7c,0xb4,0x7c,0xb4,0x64,0xa0,0x6c,0x2e, +0x6b,0xa0,0x93,0x45,0x8a,0xca,0xaa,0x22,0xb1,0x25,0xc9,0xa2,0xba,0x9b,0xa3,0x9a, +0x9c,0x31,0x10,0xc4,0x9a,0x98,0x40,0x00,0x95,0xdc,0xc6,0x6e,0xd5,0x41,0xb2,0x1b, +0xb8,0x5b,0xd9,0x4a,0xc2,0x99,0x9b,0x25,0x92,0xd4,0x6b,0xd3,0x5b,0x55,0x81,0xe2, +0x5a,0x5b,0x1c,0xda,0x35,0x94,0x44,0x19,0x9c,0x31,0x10,0xa4,0xa9,0x87,0x30,0x00, +0x61,0x52,0x5d,0x91,0x59,0x14,0x66,0x4e,0x5d,0x88,0x3d,0x92,0x56,0x24,0x5a,0x59, +0x79,0x25,0x80,0xb0,0x92,0x1e,0x73,0x19,0x8e,0x2d,0x71,0x69,0x88,0xed,0x85,0x65, +0x9c,0x31,0x10,0x9c,0x89,0x76,0x10,0x00,0x82,0x73,0x01,0xf2,0x0d,0xe2,0x11,0x13, +0x61,0x26,0x62,0x1a,0x93,0x10,0xbd,0xde,0xd4,0xe1,0x95,0x9b,0xbd,0xdc,0x69,0x93, +0x9e,0x8b,0x86,0x5b,0x9d,0x53,0xa5,0x5b,0x9c,0x31,0x10,0xb0,0x98,0x65,0x10,0x00, +0x92,0xb8,0x6f,0x96,0xa1,0x50,0x9d,0x68,0xa5,0x52,0x81,0x90,0x92,0x8c,0x5e,0x92, +0x99,0x12,0xa2,0xac,0xac,0xf5,0xa1,0x92,0x62,0x8d,0x5a,0x31,0x21,0x6d,0x41,0xed, +0x9c,0x31,0x10,0x1a,0xb9,0x46,0x20,0x00,0x82,0xf2,0xa7,0x33,0xae,0xb3,0x98,0xf3, +0x72,0xeb,0x58,0xe3,0x3c,0xc2,0x4e,0xed,0x86,0xe3,0xd7,0x0a,0xe2,0x8b,0xc7,0x43, +0x68,0xcb,0x46,0xcb,0x0b,0x6a,0x16,0x2a,0x9c,0x31,0x10,0x16,0xca,0x45,0x10,0x00, +0x89,0x32,0xca,0xd6,0xbc,0xd1,0xa5,0x44,0x6e,0xa4,0x5b,0x05,0x2d,0x22,0x3e,0xb4, +0x95,0x25,0xc0,0xf5,0xc6,0xb6,0xa5,0x65,0x7a,0x60,0x51,0x89,0x20,0x82,0x43,0x36, +0x9c,0x31,0x10,0xd7,0xca,0x45,0x20,0x00,0x9a,0xd9,0xbc,0xe8,0xc5,0x15,0xa6,0xe9, +0x86,0xe5,0x43,0x35,0x1e,0x70,0x4b,0xa4,0xaa,0x56,0xb9,0x75,0xb4,0xa5,0xad,0x05, +0x7f,0x05,0x44,0xf1,0x12,0xc2,0x5f,0x49,0x9c,0x31,0x10,0x6d,0xc9,0x45,0x20,0x00, +0xb1,0x24,0xbc,0xb4,0xab,0x55,0xa7,0x75,0x77,0x76,0x38,0x85,0x15,0x48,0x7f,0xa5, +0xb3,0x46,0xba,0x86,0x9f,0x75,0x9d,0x64,0x6b,0x84,0x2f,0x79,0x28,0x76,0x95,0x66, +0x9c,0x31,0x10,0x25,0xc9,0x35,0x20,0x00,0xb7,0x94,0xb8,0x5a,0x9b,0xa1,0x92,0x51, +0x5f,0x9b,0x2d,0x53,0x41,0xbb,0x9c,0x33,0xb7,0xc4,0xb0,0x3c,0x97,0xb3,0x82,0x4b, +0x5c,0xaa,0x35,0x3b,0x62,0xc4,0x8e,0x44,0x9c,0x31,0x10,0xf3,0xc8,0x32,0x10,0x00, +0xac,0x6a,0xae,0x9d,0xa9,0xce,0x81,0xb1,0x59,0x51,0x34,0x26,0x5a,0x4a,0x78,0xb6, +0xa8,0x41,0xb8,0x44,0xbc,0x30,0x94,0x4a,0x5c,0xae,0x31,0x56,0x49,0x1d,0x6b,0x5d, +0x9c,0x31,0x10,0x80,0xc8,0x43,0x00,0x00,0x9f,0x3a,0xbf,0xab,0xc8,0x53,0xa0,0x9c, +0x58,0x4b,0x30,0xba,0x3f,0x42,0x6b,0xa3,0x9e,0x5c,0xc8,0x8c,0xcc,0x73,0x9b,0x82, +0x4a,0x61,0x2c,0x83,0x40,0x7c,0x73,0x74,0x9c,0x31,0x10,0x75,0xc6,0x43,0x00,0x00, +0xa9,0xd2,0xd0,0x1a,0xc7,0xcb,0x84,0xb4,0x3c,0xe6,0x2e,0x0c,0x4b,0xd3,0x82,0xa9, +0xb9,0xbb,0xd4,0x44,0xb6,0xbb,0x67,0x1a,0x30,0xe9,0x33,0xaa,0x5d,0xc4,0x98,0x4c, +0x9c,0x31,0x10,0x67,0xc7,0x42,0x00,0x00,0xc8,0xab,0xd0,0xc3,0x9b,0x42,0x4c,0xb5, +0x2d,0xad,0x41,0x44,0x74,0xba,0xae,0xb2,0xd1,0x44,0xbe,0xb3,0x75,0x23,0x37,0xe1, +0x34,0x32,0x59,0x33,0x93,0xcd,0xc4,0x3c,0x9c,0x31,0x10,0x75,0xc6,0x43,0x00,0x00, +0xce,0xb3,0x9c,0xd2,0x4e,0x3d,0x2f,0x86,0x43,0xc4,0x78,0xd2,0xb1,0x1a,0xd0,0xb3, +0xba,0xd4,0x6e,0x0b,0x35,0x69,0x36,0xc2,0x62,0x3b,0x9d,0xb3,0xc7,0x3b,0xc8,0xcb, +0x9c,0x31,0x10,0x75,0xc6,0x43,0x00,0x00,0x8d,0x3c,0x43,0xf6,0x31,0x93,0x4e,0x23, +0x85,0xb9,0xb6,0xb3,0xcb,0x53,0xad,0xc3,0x68,0x81,0x42,0x49,0x4a,0x32,0x72,0xc4, +0xa0,0xba,0xbf,0xc2,0xb7,0xb2,0x80,0x2b,0x9c,0x31,0x10,0xc6,0xb6,0x33,0x00,0x00, +0x14,0xc1,0x08,0x44,0x48,0x95,0xa2,0x65,0xe7,0x66,0xf2,0x89,0xa2,0x84,0x2e,0x89, +0x08,0x49,0x36,0x85,0x8d,0x71,0xd7,0x65,0xf0,0x85,0xb6,0x85,0x44,0x55,0x0d,0x69, +0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00,0x2f,0xa5,0x7f,0x85,0xca,0x65,0xea,0x85, +0xc0,0x95,0x55,0x15,0x13,0xa5,0x29,0x66,0x73,0xa8,0xbd,0x75,0xe4,0x75,0xc9,0x85, +0x65,0x21,0x19,0xc6,0x26,0x65,0x6b,0x95,0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00, +0xb5,0x86,0xdd,0x65,0xca,0x75,0x6f,0x41,0x1e,0xb5,0x25,0x54,0x67,0x96,0xb2,0x85, +0xd9,0x65,0xc8,0x75,0x74,0x45,0x24,0xa1,0x26,0x61,0x65,0x91,0xae,0x95,0xd6,0x85, +0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00,0xc8,0x89,0x7b,0x54,0x2c,0xb5,0x25,0x45, +0x5e,0xa5,0xa7,0x85,0xd0,0x59,0xc6,0x75,0x87,0x69,0x3b,0xa0,0x28,0x61,0x55,0x86, +0x9c,0x95,0xc7,0x66,0xc3,0x79,0x91,0x89,0x9c,0x31,0x10,0x0e,0xb3,0x21,0x00,0x00, +0x4e,0x84,0x30,0x6c,0x4c,0xa5,0x8b,0x29,0xba,0x69,0xc1,0xb1,0x9f,0x65,0x68,0x6e, +0x42,0xad,0x48,0x70,0x76,0x71,0xa7,0x51,0xba,0x71,0xaa,0x4d,0x83,0x6d,0x5d,0x6d, +0x9c,0x31,0x10,0x4b,0xa4,0x32,0x00,0x00,0x1e,0x75,0x4f,0x75,0xa4,0x76,0xcf,0x55, +0xba,0x75,0x78,0x64,0x36,0xb1,0x12,0x55,0x28,0x85,0x72,0x74,0xbc,0x65,0xde,0x65, +0xd2,0xb9,0xb1,0x65,0x87,0x75,0x6b,0xa2,0x9c,0x31,0x10,0xc4,0xa4,0x33,0x00,0x00, +0x70,0x65,0x82,0x65,0x7b,0xa5,0x58,0x65,0x4d,0x88,0x4d,0x22,0x51,0xd9,0x63,0x69, +0x92,0xe8,0xc7,0x76,0xd4,0x64,0xbf,0x75,0x9f,0x75,0x81,0x85,0x58,0x99,0x35,0x69, +0x9c,0x31,0x10,0x94,0xa4,0x53,0x00,0x00,0x36,0x71,0x55,0x4d,0x76,0x89,0x97,0xa9, +0xb5,0x8d,0xc2,0x8d,0xb2,0x4c,0x92,0x6d,0x7a,0x6d,0x65,0x6d,0x51,0x49,0x48,0x64, +0x5b,0x89,0x79,0x71,0x8e,0xb1,0x9c,0x6d,0x9c,0x31,0x10,0xab,0x94,0x33,0x00,0x00, +0xd0,0xc1,0xce,0xe1,0xa2,0xf1,0x68,0xd1,0x3c,0xf1,0x34,0xec,0x48,0xa5,0x67,0x51, +0x86,0xc9,0xa4,0xd1,0xb8,0xd1,0xa7,0x0a,0x84,0xca,0x65,0x09,0x57,0x0c,0x58,0x2d, +0x9c,0x31,0x10,0xbc,0x74,0x43,0x10,0x00,0x32,0x29,0x8a,0x18,0xc9,0xd9,0xdd,0xa1, +0xba,0x99,0x7a,0xa6,0x40,0xf1,0x23,0x61,0x31,0x21,0x52,0x05,0x8a,0x4c,0xb1,0xa9, +0x9d,0x1d,0x8a,0x5c,0x85,0xd8,0x7e,0x6a,0x9c,0x31,0x10,0xa7,0xa8,0x98,0x30,0x00, +0x7d,0xdb,0x7d,0xdb,0x89,0xdb,0x9d,0x1c,0xd4,0xca,0x97,0x2a,0xa1,0x6a,0xd2,0x1d, +0x8e,0x22,0x6d,0xca,0x61,0xdd,0x5d,0xe4,0x41,0x90,0x15,0xe4,0x09,0xdc,0x12,0x13, +0x9c,0x31,0x10,0x26,0xb5,0x87,0x10,0x00,0x50,0xe0,0x56,0x9e,0x5c,0xdc,0x66,0x28, +0x6e,0x45,0x7c,0xb3,0x8a,0xc4,0x9c,0x49,0xa4,0xad,0x99,0x49,0x80,0xac,0x6a,0xc3, +0x7c,0xb3,0xb6,0x42,0xe3,0x33,0xc0,0x44,0x9c,0x31,0x10,0x3f,0xc6,0x69,0x20,0x00, +0x66,0xcb,0x39,0x34,0x54,0x82,0xa8,0xf3,0xea,0x8b,0xce,0xab,0x71,0x03,0x1c,0x2b, +0x26,0xeb,0x84,0x84,0xdf,0x2b,0xe4,0x93,0x9a,0xdb,0x43,0x2b,0x13,0x52,0x46,0xcd, +0x9c,0x31,0x10,0x0e,0xc7,0x79,0x30,0x00,0xa6,0xe2,0xe0,0xcb,0xca,0xe3,0x7f,0x1c, +0x32,0x93,0x1b,0x03,0x5a,0xf1,0xb6,0xc4,0xdc,0xe3,0xb2,0x94,0x6d,0x22,0x2a,0x43, +0x23,0x34,0x6c,0xcc,0xc0,0xe2,0xd6,0xd3,0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00, +0xa4,0x63,0x63,0x54,0x24,0x22,0x2a,0xea,0x7e,0xce,0xcc,0xe3,0xd0,0x9b,0x98,0x99, +0x5b,0x5c,0x22,0xb5,0x34,0x89,0x8c,0xa2,0xd4,0xd3,0xc8,0xac,0x8c,0x94,0x55,0x22, +0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00,0x24,0xec,0x40,0xca,0x98,0xe9,0xd6,0xdc, +0xc4,0x9a,0x86,0xdc,0x50,0xe2,0x23,0x64,0x48,0xcd,0xa0,0xe8,0xd9,0x1c,0xbc,0x9a, +0x81,0x24,0x4e,0xe2,0x25,0x64,0x4e,0xcd,0x9c,0x31,0x10,0x93,0xc6,0x79,0x30,0x00, +0xa6,0xea,0xd7,0x1b,0xb6,0x9a,0x7d,0x1b,0x4e,0xe3,0x29,0x9b,0x50,0xd4,0xa6,0xe2, +0xd7,0x1b,0xb2,0x9b,0x7d,0x5b,0x50,0xe3,0x27,0x5b,0x4e,0xdd,0xa6,0xe1,0xd7,0x23, +0x9c,0x31,0x10,0x2e,0xc5,0x88,0x30,0x00,0xb2,0x32,0x7b,0x4d,0x55,0x2b,0x29,0x5c, +0x4c,0x9b,0xa4,0x59,0xd7,0x24,0xb4,0x4a,0x7d,0x35,0x5d,0x43,0x2c,0x4d,0x42,0xa8, +0x9c,0x4b,0xd7,0x2c,0xb8,0x43,0x7e,0x34,0x9c,0x31,0x10,0x0e,0xc7,0x79,0x30,0x00, +0x65,0x1b,0x34,0x62,0x39,0x2a,0x90,0x8d,0xd2,0xeb,0xbc,0xd3,0x80,0xa2,0x6f,0x13, +0x40,0x03,0x2f,0x75,0x7e,0x8a,0xcc,0xe3,0xc6,0xd2,0x88,0xa4,0x75,0x14,0x52,0xab, +0x9c,0x31,0x10,0x86,0xc7,0x89,0x30,0x00,0x23,0x89,0x62,0xe4,0xc2,0xd3,0xd3,0x24, +0x92,0x93,0x79,0x23,0x6d,0x13,0x28,0xac,0x3c,0xd1,0xaa,0xa3,0xdd,0x1b,0xa4,0xdc, +0x78,0xdb,0x80,0xdb,0x42,0x13,0x1b,0x5d,0x9c,0x31,0x10,0x2c,0xd7,0x88,0x30,0x00, +0x7e,0xa0,0xac,0xd3,0x9e,0xe2,0x7c,0x95,0x83,0x1b,0x77,0x1a,0x46,0xed,0x5e,0xca, +0xa2,0xaa,0xad,0x12,0x86,0xdb,0x7e,0xdc,0x8a,0x9a,0x5c,0x5c,0x3f,0x92,0x82,0xea, +0x9c,0x31,0x10,0xcb,0xd8,0x89,0x30,0x00,0xb4,0xcb,0x9a,0xdb,0x76,0xa3,0x8b,0x13, +0x84,0xe3,0x40,0x4a,0x4b,0x33,0xa4,0xcc,0xb2,0xe3,0x82,0xdb,0x7c,0xd3,0x98,0xe3, +0x71,0x52,0x2e,0xad,0x66,0xd9,0xb8,0x8b,0x9c,0x31,0x10,0x07,0xd7,0x88,0x40,0x00, +0xa1,0x2a,0x74,0xd3,0x8c,0xdb,0x9c,0xa3,0x55,0x8a,0x2a,0xf4,0x87,0x05,0xbc,0x6a, +0x89,0x1a,0x76,0x92,0xa1,0x23,0x94,0xa3,0x43,0x94,0x35,0x2a,0x9b,0x06,0xb0,0x6a, +0x9c,0x31,0x10,0x77,0xd8,0x98,0x40,0x00,0x7b,0x1b,0x84,0xd2,0xa8,0xe3,0x86,0xa2, +0x3f,0x14,0x42,0xec,0x9c,0xcc,0xa2,0xa3,0x7b,0x22,0x90,0xd2,0xa6,0xdb,0x82,0xe3, +0x47,0x53,0x44,0xad,0x92,0xd3,0x9e,0x99,0x9c,0x31,0x10,0x52,0xc8,0x98,0x40,0x00, +0x81,0x21,0xa8,0xdb,0xc4,0xd4,0x8a,0xe4,0x25,0x5c,0x00,0x13,0x87,0x28,0xc2,0x54, +0x87,0x1c,0xa2,0xe4,0xc4,0x9b,0x9a,0xd2,0x3e,0xda,0x00,0x1b,0x5b,0x4d,0xc2,0xa2, +0x9c,0x31,0x10,0x6b,0xc9,0x99,0x30,0x00,0x90,0xdb,0x96,0xd3,0xc2,0xdc,0xaa,0xe3, +0x62,0xdb,0x15,0x1a,0x25,0x2a,0xb0,0xcc,0xa6,0xdb,0x84,0xe2,0xba,0xdb,0xba,0xd4, +0x80,0xdb,0x39,0x23,0x08,0x49,0x71,0x1b,0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00, +0xc0,0x6e,0x84,0xd4,0xa1,0x09,0xc4,0x63,0xa1,0x23,0x62,0xd3,0x1f,0x51,0x1d,0x34, +0xa9,0x14,0xa6,0x8a,0x81,0x22,0xbc,0xec,0xba,0xdc,0x8a,0xd2,0x50,0xd9,0x0a,0x64, +0x9c,0x31,0x10,0x62,0xc9,0x97,0x30,0x00,0x41,0x65,0xc0,0xe5,0x8a,0xf5,0x91,0x11, +0xca,0xc9,0xab,0x08,0x7a,0xcd,0x49,0x12,0x08,0x48,0x5f,0x62,0xc0,0xb1,0x7f,0x10, +0xa1,0x09,0xcc,0xa9,0x9d,0x0c,0x7a,0xd0,0x9c,0x31,0x10,0xc1,0xd9,0x98,0x30,0x00, +0x61,0x1c,0x40,0x0a,0x77,0x15,0x9e,0xb2,0x78,0xe2,0x93,0x14,0xa6,0x93,0x8b,0x1a, +0x7e,0xe2,0x64,0xdd,0x3e,0x13,0x73,0x4b,0xa0,0xa1,0x76,0xec,0x93,0x1b,0xaa,0x92, +0x9c,0x31,0x10,0xe4,0xc9,0x98,0x30,0x00,0x95,0x1b,0x86,0xe4,0x58,0xdb,0x00,0xa3, +0x45,0x91,0xc6,0xc3,0x78,0xd4,0x92,0xe3,0xda,0xa3,0x9a,0xdb,0x8a,0xd2,0x72,0xdb, +0x13,0x1b,0x14,0xed,0xba,0xe9,0x90,0x93,0x9c,0x31,0x10,0xea,0xd9,0x98,0x40,0x00, +0x7a,0xcb,0xaa,0xdb,0x96,0xa4,0x85,0x24,0x86,0x9a,0x5b,0x13,0x3a,0x14,0x81,0x4d, +0x9a,0x60,0x73,0x2a,0x9f,0x1b,0xa4,0x95,0x85,0x1c,0x8e,0xda,0x72,0xda,0x41,0x1b, +0x9c,0x31,0x10,0xea,0xd9,0x98,0x40,0x00,0x53,0x2d,0x9c,0xe2,0x7e,0x91,0x82,0xcb, +0xac,0xdd,0x90,0xe5,0x89,0x1a,0x8a,0x9a,0x5a,0xdc,0x3c,0x9b,0x75,0x90,0x98,0x8d, +0x75,0x1d,0x96,0xe4,0xa4,0xe2,0x86,0xda,0x9c,0x31,0x10,0xe4,0xc9,0x98,0x30,0x00, +0xa1,0x1b,0x7c,0xdc,0x1b,0x1b,0x0e,0x14,0x91,0x15,0x9c,0xa9,0x73,0x2a,0xc0,0xdc, +0xba,0xd4,0x92,0xdb,0xa0,0xda,0x66,0xdb,0x17,0x1c,0x1a,0x51,0x9c,0xeb,0x94,0xac, +0x9c,0x31,0x10,0x4a,0xc8,0x88,0x40,0x00,0x7d,0x23,0xc3,0x0a,0xb4,0x93,0x97,0x24, +0x9e,0xa3,0x5e,0xda,0x15,0x53,0x24,0x11,0x9c,0xf3,0x94,0x35,0x7f,0x24,0xbc,0xd3, +0xb6,0xcb,0x96,0xda,0x9a,0xe3,0x68,0xdb,0x9c,0x31,0x10,0xcf,0xc9,0x98,0x40,0x00, +0x22,0xdb,0x1a,0x53,0x8b,0x15,0xa2,0xa3,0x79,0x22,0xae,0xda,0xbe,0xd3,0x9a,0xdb, +0x98,0xdc,0x76,0xdb,0x2e,0xdb,0x12,0x5c,0x6f,0x4a,0xac,0x91,0x7d,0x1c,0x9a,0xe5, +0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00,0xbe,0xe3,0xa6,0xda,0x9f,0x13,0x86,0x93, +0x4c,0xdb,0x21,0x1b,0x39,0x6d,0x92,0xe2,0x8c,0xd1,0x99,0x13,0xb2,0xd4,0xb0,0xdb, +0xa8,0xe2,0x92,0xe2,0x60,0xdb,0x38,0xd3,0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00, +0x22,0x14,0x5f,0x4b,0x9a,0x51,0x8f,0x23,0xa2,0xe4,0xb4,0xe3,0xae,0xda,0xa1,0x13, +0x82,0xd4,0x54,0xdb,0x35,0x1b,0x2a,0x5a,0x76,0xe2,0x96,0xa4,0x93,0x1c,0xa6,0xdb, +0x9c,0x31,0x10,0x3b,0xc7,0x87,0x20,0x00,0xb2,0xd5,0xac,0x91,0x9d,0x19,0x74,0xa1, +0x4d,0x25,0x33,0x65,0x35,0x6e,0x7a,0xe8,0x92,0x9c,0x9c,0xd1,0xa8,0xd6,0xb1,0x19, +0xae,0x9d,0x94,0xe1,0x6a,0xe5,0x4f,0x25,0x9c,0x31,0x10,0xdc,0xc8,0x86,0x20,0x00, +0x37,0x10,0x39,0x76,0x78,0xee,0x97,0x08,0x9e,0xe4,0xa6,0xc9,0xb1,0x0e,0xac,0xcd, +0x92,0xf0,0x6a,0xed,0x4f,0x0d,0x38,0xed,0x3d,0x71,0x74,0xee,0x95,0x09,0xa2,0xe8, +0x9c,0x31,0x10,0x3e,0xb7,0x75,0x00,0x00,0xce,0xe9,0xdf,0x2e,0xde,0xad,0xa8,0xf0, +0x58,0xed,0x25,0x0d,0x05,0x10,0x01,0x96,0x52,0xf5,0x99,0x0c,0xbe,0xe9,0xca,0xea, +0xd5,0x09,0xd6,0xcd,0xae,0xed,0x6e,0xd1,0x9c,0x31,0x10,0xa6,0xb5,0x54,0x00,0x00, +0x42,0xea,0x2b,0x23,0x16,0xe4,0x32,0x70,0x68,0xf3,0x9e,0xf4,0xb8,0xe3,0xc9,0x1a, +0xd2,0x8c,0xc4,0xd2,0xa6,0xd3,0x7e,0x94,0x4e,0xd3,0x18,0x9b,0x00,0xd3,0x24,0x92, +0x9c,0x31,0x10,0xa6,0xc3,0x43,0x00,0x00,0x75,0x8d,0x95,0x2d,0xaa,0x11,0xb9,0x31, +0xb8,0xae,0xa4,0x35,0x82,0xb1,0x5f,0x2d,0x42,0xae,0x37,0xc8,0x4a,0x25,0x71,0x05, +0x96,0xa8,0xaf,0x0d,0xbd,0x31,0xbc,0xb1,0x9c,0x31,0x10,0xdd,0xc4,0x42,0x00,0x00, +0xa8,0x71,0x87,0x71,0x63,0x6d,0x48,0x8c,0x38,0x72,0x42,0x8d,0x67,0x68,0x8f,0x86, +0xaa,0x49,0xb8,0xa9,0xbc,0x4e,0xad,0x6d,0x90,0x4d,0x6f,0x71,0x52,0x91,0x3c,0x2c, +0x9c,0x31,0x10,0xee,0xc3,0x33,0x00,0x00,0x3c,0xd5,0x59,0x99,0x82,0x49,0xa1,0x29, +0xb3,0xd5,0xbb,0x31,0xb2,0xb1,0x9c,0x55,0x7c,0x25,0x5c,0xb5,0x44,0xa5,0x3b,0x34, +0x4d,0x22,0x73,0xb1,0x97,0x25,0xac,0x25,0x9c,0x31,0x10,0xdd,0xc4,0x42,0x00,0x00, +0xb7,0x96,0xb6,0x70,0xa4,0x6c,0x88,0x6a,0x69,0x4a,0x4e,0x8d,0x3d,0x30,0x43,0x95, +0x63,0x72,0x89,0x6c,0xa5,0x68,0xb3,0x89,0xb7,0x6e,0xab,0x70,0x94,0x90,0x75,0x52, +0x9c,0x31,0x10,0xa6,0xc3,0x43,0x00,0x00,0x59,0xcd,0x44,0x8d,0x3f,0x44,0x55,0x25, +0x7b,0x2e,0x9b,0x35,0xad,0xb1,0xb6,0xd1,0xb2,0x0e,0x9e,0xc9,0x82,0x29,0x65,0x2d, +0x4e,0x4d,0x41,0x92,0x4c,0xb0,0x6d,0xa9,0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00, +0xa0,0x92,0xcd,0x62,0xe4,0x94,0xe6,0x69,0xc9,0x8a,0x97,0x76,0x5d,0x60,0x2c,0x95, +0x0b,0x21,0x10,0xaa,0x47,0x68,0x8c,0x85,0xbf,0x65,0xda,0x66,0xe4,0x61,0xd2,0x64, +0x9c,0x31,0x10,0x16,0xb3,0x31,0x00,0x00,0xa6,0x90,0x6e,0x52,0x39,0xad,0x14,0x0d, +0x10,0xc6,0x3c,0x4c,0x7e,0x71,0xb4,0x75,0xd3,0x49,0xe1,0x88,0xd5,0x6a,0xac,0xa8, +0x73,0x2e,0x3e,0x8c,0x1a,0x0e,0x14,0xc8,0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00, +0x3b,0x6d,0x7a,0x75,0xb1,0x71,0xd1,0x51,0xdf,0x89,0xd1,0x4d,0xa8,0xd0,0x70,0x2d, +0x3d,0x89,0x1d,0x31,0x1b,0xc5,0x44,0x71,0x81,0x91,0xb4,0x76,0xd1,0x8d,0xdb,0x6c, +0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00,0xc8,0x69,0x9c,0x8e,0x63,0x35,0x34,0xb5, +0x1c,0x08,0x28,0xa6,0x58,0x69,0x93,0xb1,0xc0,0x50,0xd6,0x8d,0xd4,0x49,0xb4,0x8d, +0x81,0xb1,0x4c,0x6d,0x28,0x8d,0x23,0x51,0x9c,0x31,0x10,0xbb,0xb2,0x11,0x00,0x00, +0x43,0xc8,0x79,0xa5,0xae,0x52,0xce,0xa8,0xd4,0xc5,0xbe,0x24,0x90,0x45,0x59,0xa1, +0x2f,0x51,0x24,0xa9,0x3e,0xc4,0x71,0x39,0xa5,0xc5,0xc9,0x25,0xd2,0x26,0xbf,0xd1, +0x9c,0x31,0x10,0x1f,0xb2,0x22,0x00,0x00,0x93,0x55,0x5e,0x75,0x34,0x6d,0x29,0x8d, +0x41,0x8d,0x71,0x4c,0xa3,0x52,0xc6,0x71,0xcf,0xa8,0xba,0x8d,0x8d,0x4d,0x59,0x69, +0x34,0x50,0x30,0xad,0x4c,0x4d,0x7c,0x89,0x9c,0x31,0x10,0x8d,0xb1,0x12,0x00,0x00, +0xad,0x4a,0xcc,0xaa,0xcb,0x85,0xa8,0xb4,0x73,0x52,0x44,0xa9,0x30,0x2b,0x3c,0x45, +0x63,0x2a,0x97,0xb2,0xc2,0xd4,0xcf,0x2b,0xb7,0x2a,0x89,0x2c,0x5b,0x12,0x3f,0x32, +0x9c,0x31,0x10,0x93,0xb2,0x21,0x00,0x00,0x3d,0x6e,0x55,0x8a,0x7f,0x69,0xa8,0x64, +0xbe,0x4e,0xb7,0x8d,0x97,0x6d,0x71,0x48,0x55,0x4e,0x4d,0x90,0x58,0x7a,0x72,0x29, +0x90,0x91,0xa6,0x70,0xa9,0x8d,0x99,0x4d,0x9c,0x31,0x10,0xf1,0x92,0x11,0x00,0x00, +0x83,0x61,0x2b,0xb5,0x03,0x62,0x10,0x51,0x44,0x95,0x8b,0x44,0xc8,0x39,0xe1,0x96, +0xce,0xc8,0x99,0x6a,0x63,0x64,0x43,0x55,0x40,0x59,0x54,0x78,0x74,0x82,0x96,0x84, +0x9c,0x31,0x10,0xd4,0x82,0x11,0x00,0x00,0xd4,0x86,0xd1,0x94,0xa8,0x35,0x74,0x6a, +0x51,0x31,0x4a,0x49,0x57,0x55,0x70,0x70,0x89,0x74,0x97,0x70,0x99,0x59,0x8e,0x71, +0x7d,0x66,0x70,0xa5,0x70,0x71,0x75,0x65,0x9c,0x31,0x10,0xdc,0x52,0x12,0x00,0x00, +0x69,0x92,0xa9,0xda,0xca,0xd2,0xc6,0x33,0x9e,0x5d,0x65,0x12,0x3d,0xe2,0x31,0x53, +0x42,0x04,0x6d,0x64,0x8a,0x53,0x99,0x5a,0xa6,0x2b,0xa5,0xdc,0x81,0xc9,0x59,0x9c, +0x9c,0x31,0x10,0xd9,0x51,0x33,0x00,0x00,0x38,0xc4,0x35,0xc2,0x42,0x43,0x6d,0xbb, +0x9d,0x4c,0xb4,0x89,0x96,0xbb,0x85,0xbb,0x6e,0x3b,0x52,0xb3,0x41,0xbc,0x42,0x3b, +0x52,0x43,0x70,0x4b,0x85,0x3b,0xa0,0xbb,0x9c,0x31,0x10,0x29,0x32,0x20,0x00,0x00, +0xe9,0xea,0x85,0x93,0x19,0x73,0x26,0x4d,0x21,0xb0,0x1d,0xac,0x4d,0xab,0x99,0xae, +0xd9,0xb1,0xaa,0x8b,0x89,0xec,0xe3,0xb2,0xe5,0x45,0x76,0x8c,0x06,0x53,0x6e,0x93, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_CONNECTED.txt b/config/_default_cfg_src_/res/cn/SOUND_CONNECTED.txt new file mode 100644 index 0000000..13bd71d --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_CONNECTED.txt @@ -0,0 +1,240 @@ +0x9c,0x31,0x10,0x02,0x32,0x12,0x00,0x00,0x7b,0xb7,0x7b,0xb7,0x83,0xb7,0x83,0x37, +0xb4,0x26,0xb3,0x39,0xa3,0xa8,0xc4,0x93,0x84,0xda,0x9a,0xa6,0xac,0x58,0xe5,0xc9, +0xca,0x45,0xaa,0xc6,0x94,0xd7,0xac,0xb7,0x9c,0x31,0x10,0x5e,0x42,0x23,0x00,0x00, +0xa9,0x5b,0x91,0x8b,0x82,0x53,0x84,0xdc,0x86,0x6a,0x96,0x23,0x88,0xdb,0x91,0x9b, +0x92,0x5b,0xa1,0x9b,0x99,0x5b,0xaa,0x1b,0x65,0x23,0x55,0x03,0xee,0xa1,0xae,0xb6, +0x9c,0x31,0x10,0x45,0x81,0x23,0x00,0x00,0x6a,0x63,0x63,0xa0,0x78,0x5e,0x89,0x20, +0x90,0xab,0x94,0x55,0x8e,0x71,0x87,0x6c,0x7e,0x9b,0x78,0x92,0x7c,0x5c,0x87,0x09, +0x96,0xa4,0xa9,0x14,0xc2,0x53,0xd0,0x51,0x9c,0x31,0x10,0x20,0xb4,0x46,0x00,0x00, +0x86,0xdb,0x7a,0xdb,0x68,0xa3,0x5d,0x53,0x66,0xe2,0x89,0x14,0xa8,0xda,0xaa,0xe3, +0x8b,0x13,0x59,0x2b,0x3a,0x94,0x4e,0xe1,0x84,0x64,0xb7,0x1b,0xd2,0xda,0xc8,0xa5, +0x9c,0x31,0x10,0xbf,0xc4,0x58,0x20,0x00,0x85,0x97,0x58,0x28,0x3f,0x05,0x50,0x68, +0x7d,0x48,0xa2,0x66,0xaf,0x59,0xab,0x57,0x9e,0x56,0x8c,0x97,0x6a,0x96,0x41,0xa8, +0x36,0x0a,0x5a,0x53,0x91,0x69,0xb1,0x47,0x9c,0x31,0x10,0xbe,0xc5,0x68,0x30,0x00, +0xb4,0xc5,0xa4,0xba,0x92,0xb5,0x84,0xb6,0x69,0x38,0x43,0x46,0x38,0xba,0x60,0xb4, +0x94,0xc8,0xb0,0xa8,0xb1,0x35,0xa2,0xca,0x98,0xa4,0x8a,0x47,0x64,0xc9,0x35,0x11, +0x9c,0x31,0x10,0x04,0xc6,0x68,0x30,0x00,0x30,0xed,0x62,0xcc,0x9e,0xe9,0xba,0xd5, +0xb7,0x12,0xa4,0xeb,0x9a,0x93,0x84,0xda,0x54,0x5d,0x23,0x0b,0x2e,0xe9,0x71,0x1d, +0xae,0x91,0xc4,0xe3,0xb8,0xd4,0xa2,0xd9,0x9c,0x31,0x10,0x04,0xc6,0x68,0x30,0x00, +0x92,0xa3,0x7c,0xdc,0x48,0x53,0x1b,0x54,0x2e,0xd8,0x78,0xe4,0xb8,0x93,0xca,0xe2, +0xb6,0x95,0xa1,0x1a,0x92,0x99,0x77,0x1c,0x3e,0x03,0x13,0x35,0x34,0xc3,0x85,0x2a, +0x9c,0x31,0x10,0xb2,0xc7,0x68,0x40,0x00,0xc2,0xd5,0xcc,0xd9,0xb2,0xe3,0x9d,0x14, +0x92,0xe4,0x77,0x12,0x38,0x53,0x0a,0xee,0x30,0xca,0x8d,0x2b,0xcc,0xcc,0xd0,0xe1, +0xb2,0xdc,0x98,0xe3,0x8e,0xdc,0x73,0x1a,0x9c,0x31,0x10,0x25,0xc7,0x79,0x40,0x00, +0x32,0x53,0x08,0xe5,0x34,0xd3,0x92,0xe2,0xd4,0xd4,0xd4,0xda,0xb0,0xdb,0x97,0x1b, +0x8e,0xdb,0x73,0x1b,0x30,0x4b,0x04,0xed,0x30,0xca,0x94,0xe2,0xda,0xd4,0xd8,0xda, +0x9c,0x31,0x10,0x91,0xc7,0x79,0x50,0x00,0xae,0x9c,0x93,0x12,0x8e,0xe2,0x7b,0x1d, +0x38,0x4b,0x03,0x24,0x2a,0xd2,0x91,0x24,0xda,0xd2,0xd8,0xe3,0xac,0xcc,0x8e,0xe3, +0x90,0xda,0x84,0xdb,0x46,0xe3,0x03,0x41,0x9c,0x31,0x10,0xb8,0xc6,0x79,0x40,0x00, +0x1a,0xf5,0x81,0x04,0xd6,0xaa,0xde,0xd4,0xb0,0xe2,0x8a,0xd3,0x90,0xe4,0x90,0x92, +0x5b,0x63,0x05,0x2d,0x04,0x88,0x6a,0xf2,0xd4,0xcd,0xea,0xe2,0xb9,0x1d,0x86,0xe3, +0x9c,0x31,0x10,0x04,0xd7,0x8a,0x40,0x00,0x84,0xa5,0x8e,0xc8,0x7b,0x27,0x4a,0x25, +0x36,0xdb,0x60,0x95,0x9e,0xd5,0xba,0x97,0xa4,0xd5,0x82,0xab,0x7c,0xc6,0x90,0xb6, +0x8a,0xb7,0x5c,0xb7,0x33,0x36,0x48,0xbb,0x9c,0x31,0x10,0x88,0xd7,0x89,0x40,0x00, +0x8d,0x10,0xba,0xe3,0xae,0xd3,0x89,0x22,0x76,0x94,0x8c,0xe3,0x9a,0x94,0x7b,0x1a, +0x3c,0x4a,0x30,0xee,0x6a,0xc9,0xae,0xe9,0xbc,0xcc,0x98,0xe3,0x74,0x95,0x7d,0x1b, +0x9c,0x31,0x10,0x88,0xd7,0x89,0x40,0x00,0x9e,0xda,0x96,0xdb,0x61,0x13,0x2a,0xec, +0x3e,0x88,0x88,0xec,0xbc,0xcc,0xb0,0xea,0x84,0xd3,0x6e,0x5a,0x8b,0x14,0xa6,0x64, +0x8d,0x0a,0x47,0x1b,0x21,0xa2,0x58,0xc6,0x9c,0x31,0x10,0x2f,0xd7,0x8a,0x30,0x00, +0xaa,0xd4,0xc2,0x98,0x94,0xd7,0x6a,0xa8,0x74,0x36,0xa6,0xc7,0xae,0x29,0x75,0x36, +0x30,0xc7,0x2b,0x04,0x72,0xdb,0xb4,0xa6,0xb6,0xc7,0x84,0xb6,0x69,0x28,0x7c,0xb6, +0x9c,0x31,0x10,0xa3,0xd7,0x89,0x30,0x00,0xaa,0xaa,0xa4,0x8d,0x6c,0xdb,0x38,0xa3, +0x3f,0x41,0x76,0xe5,0xa3,0x1c,0xa4,0xd2,0x88,0xda,0x7f,0x1c,0x82,0x9b,0x8a,0xdb, +0x8b,0x1a,0x88,0xdb,0x78,0xdc,0x62,0xe3,0x9c,0x31,0x10,0x96,0xc5,0x58,0x30,0x00, +0x3a,0x57,0x53,0x51,0x82,0x6a,0xa7,0x4a,0xb5,0x64,0xac,0x58,0x9b,0x57,0x8f,0x54, +0x81,0x5a,0x5e,0x57,0x3b,0x95,0x39,0x6c,0x5f,0x85,0x91,0x63,0xae,0x5b,0xb2,0x56, +0x9c,0x31,0x10,0xf0,0xb4,0x58,0x30,0x00,0xc6,0xd6,0x9f,0x99,0x8c,0xd7,0x86,0x97, +0x62,0xd7,0x1e,0xd6,0x02,0x03,0x30,0x6a,0x82,0x5b,0xbd,0x14,0xd0,0xd7,0xc8,0xd7, +0xae,0x15,0x9d,0x18,0x98,0xda,0x80,0xd6,0x9c,0x31,0x10,0x6d,0xb5,0x58,0x30,0x00, +0x3e,0x56,0x03,0x06,0x0f,0x13,0x59,0x5a,0xa4,0xc9,0xcc,0x95,0xd5,0x19,0xc2,0xd6, +0xa1,0x55,0x90,0xda,0x88,0xd8,0x65,0x15,0x24,0xe8,0x08,0x94,0x2e,0xa6,0x78,0xdb, +0x9c,0x31,0x10,0xeb,0xb5,0x57,0x30,0x00,0xb4,0xda,0xce,0xe3,0xce,0xdc,0xae,0x9a, +0x93,0x1c,0x8b,0x1b,0x83,0x11,0x57,0x24,0x19,0x93,0x0e,0xed,0x43,0x1d,0x8e,0xd8, +0xc0,0xdc,0xd1,0x1b,0xc4,0xda,0xa4,0xe4,0x9c,0x31,0x10,0x3b,0xc7,0x87,0x20,0x00, +0x88,0xdd,0x86,0xdd,0x7e,0xde,0x62,0xdd,0x49,0x1d,0x4c,0xdc,0x6a,0xdd,0x8e,0xdd, +0xa4,0xdd,0xa9,0x1d,0x9e,0xd8,0x9d,0x31,0x9d,0x15,0x8c,0xc4,0x53,0x32,0x04,0x08, +0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00,0x1a,0xa4,0x94,0x9a,0xe2,0xd3,0xb2,0xe3, +0x60,0xd3,0x62,0xdb,0xa8,0x52,0xdc,0xa5,0xa8,0x93,0x4a,0xda,0x09,0x22,0x0f,0xa5, +0x80,0xcc,0xd2,0xe8,0xb0,0xd3,0x62,0x9c,0x9c,0x31,0x10,0xdd,0xc8,0x99,0x40,0x00, +0x68,0xdb,0xb2,0xe3,0xd9,0x1b,0xb4,0xdc,0x68,0xda,0x31,0x1b,0x06,0x4a,0x3e,0xf6, +0xb0,0x93,0xcc,0xe1,0x88,0xda,0x5e,0xdc,0x92,0xdb,0xc6,0xdb,0xc4,0xdb,0x88,0xdc, +0x9c,0x31,0x10,0xdd,0xc8,0x99,0x40,0x00,0x4c,0xdb,0x16,0xe3,0x17,0x5a,0x82,0xd6, +0xcc,0xe1,0xa6,0xd3,0x62,0xda,0x74,0xdc,0xb6,0xdb,0xcb,0x1b,0xa6,0xdb,0x6c,0xdb, +0x3b,0x1a,0x08,0x52,0x3e,0xee,0xb0,0x92,0x9c,0x31,0x10,0xb5,0xc7,0x99,0x40,0x00, +0xc8,0xda,0x82,0xdb,0x60,0xdc,0x97,0x1b,0xc6,0x9b,0xbe,0xdb,0x88,0x9b,0x54,0xdb, +0x23,0x22,0x13,0xa5,0x76,0x8c,0xc6,0xe9,0xaa,0x93,0x68,0xe3,0x75,0x1c,0xb4,0x9b, +0x9c,0x31,0x10,0xc5,0xc8,0x89,0x40,0x00,0xc7,0x1b,0xa2,0xdb,0x6c,0xdb,0x43,0x1b, +0x10,0x0b,0x37,0x25,0xa6,0xe8,0xc6,0xc3,0x86,0xeb,0x60,0xd4,0x94,0xe3,0xc4,0x9b, +0xba,0xdb,0x8a,0xdb,0x5e,0xdb,0x2f,0x1b,0x9c,0x31,0x10,0xdd,0xc8,0x99,0x40,0x00, +0x0d,0x2d,0x64,0xd0,0xc6,0xdb,0xb4,0xdb,0x66,0xdc,0x6c,0xdb,0xb6,0xdb,0xc8,0xdb, +0xa2,0xdb,0x78,0xdb,0x56,0xdb,0x1a,0x5b,0x1d,0x48,0x92,0xe4,0xcf,0x1c,0x90,0xdc, +0x9c,0x31,0x10,0xdd,0xc8,0x99,0x40,0x00,0x58,0xda,0x8c,0xdb,0xc6,0x9b,0xb9,0x1b, +0x8c,0xdb,0x6e,0xdb,0x47,0x1b,0x0c,0x52,0x46,0xed,0xba,0x93,0xbc,0xdb,0x6c,0xda, +0x64,0xdb,0xae,0xdb,0xc4,0xdb,0xa0,0xdb,0x9c,0x31,0x10,0xdd,0xc8,0x99,0x40,0x00, +0x82,0xdb,0x6a,0xdb,0x2d,0x1b,0x07,0x2d,0x76,0xd1,0xd0,0xdb,0x9e,0xe2,0x56,0xd4, +0x82,0xdb,0xc6,0xdb,0xb0,0xdb,0x8e,0xdb,0x84,0xdb,0x66,0xdb,0x14,0xa3,0x1b,0x51, +0x9c,0x31,0x10,0xc5,0xc8,0x89,0x40,0x00,0xa4,0xd5,0xcf,0x33,0x76,0xc4,0x56,0xe2, +0xa6,0xdb,0xc8,0x9b,0x9f,0x1b,0x86,0xdb,0x82,0xdb,0x4b,0x13,0x00,0x0b,0x4a,0xe5, +0xc8,0xaa,0xb0,0xc3,0x5e,0xea,0x76,0xdb,0x9c,0x31,0x10,0xad,0xc7,0x89,0x40,0x00, +0xc3,0x1b,0xb0,0x9b,0x8e,0xe3,0x90,0xd3,0x74,0x9b,0x27,0x9b,0x12,0xf4,0x80,0x99, +0xa4,0x8c,0x82,0xf2,0x8e,0xd3,0xb0,0xd3,0xa6,0xa3,0x9b,0x9b,0x98,0x4b,0x7f,0x2b, +0x9c,0x31,0x10,0x4a,0xc8,0x88,0x40,0x00,0x58,0xdb,0x20,0xa3,0x35,0x80,0x96,0xd6, +0x9b,0x32,0x7e,0xcc,0x98,0xdb,0xb5,0x23,0xa2,0x93,0x9c,0xd3,0x8e,0xab,0x74,0xd3, +0x45,0x13,0x18,0x12,0x5a,0xf6,0x9e,0x9a,0x9c,0x31,0x10,0xff,0xc8,0x97,0x30,0x00, +0x8f,0x0a,0x8a,0xf1,0xa4,0xec,0xac,0xcd,0xa3,0x4e,0x94,0xcd,0x7d,0x0d,0x62,0xcd, +0x2a,0xcc,0x2b,0x72,0x80,0xc6,0x98,0xf1,0x8a,0xed,0x9a,0xe9,0xae,0xed,0xb1,0x31, +0x9c,0x31,0x10,0xff,0xc8,0x97,0x30,0x00,0xa2,0xe9,0x7e,0xed,0x66,0xcd,0x41,0x29, +0x20,0x8c,0x5e,0xf5,0x92,0xc5,0x94,0xed,0x9d,0x11,0xaa,0xcd,0xb5,0x0d,0xac,0xed, +0x82,0xed,0x60,0xcd,0x41,0x2d,0x22,0x48,0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00, +0x4d,0x35,0x8a,0xa2,0x9c,0xc4,0xa4,0xeb,0xae,0x9b,0xba,0xcb,0xb0,0xdb,0x80,0xe3, +0x58,0x8b,0x3f,0x1b,0x26,0x52,0x49,0x25,0x82,0xaa,0x9e,0xc4,0xac,0xe3,0xb2,0xe3, +0x9c,0x31,0x10,0x8f,0xc7,0x87,0x30,0x00,0xc0,0xd0,0xb0,0xad,0x7e,0xdd,0x4c,0x95, +0x31,0x65,0x26,0x5d,0x50,0xf0,0x86,0x85,0xa6,0xe9,0xb4,0xe5,0xbe,0xcd,0xc5,0x21, +0xa6,0xd9,0x6e,0xe1,0x3c,0xe1,0x25,0x1d,0x9c,0x31,0x10,0x00,0xc7,0x86,0x30,0x00, +0x2b,0x25,0x60,0xc6,0x92,0xee,0xb0,0xe1,0xbe,0xd1,0xc8,0xe4,0xc0,0xa1,0x92,0xd9, +0x54,0xdd,0x2b,0x1d,0x1c,0x54,0x3d,0x2a,0x78,0xa5,0xa4,0xca,0xba,0xe4,0xc6,0xe4, +0x9c,0x31,0x10,0xda,0xc5,0x76,0x10,0x00,0xca,0x8a,0xae,0x55,0x76,0xac,0x3f,0x13, +0x24,0x5a,0x28,0x99,0x56,0x4c,0x8b,0x65,0xb1,0x64,0xc3,0x4a,0xca,0x5a,0xbe,0x6b, +0x94,0x53,0x5d,0x13,0x35,0xa3,0x24,0x23,0x9c,0x31,0x10,0xd7,0xc5,0x53,0x00,0x00, +0x37,0x84,0x6a,0x40,0x9d,0x95,0xbd,0x51,0xcd,0x85,0xcb,0x69,0xab,0x6e,0x78,0x6d, +0x44,0x8d,0x20,0x2d,0x21,0x91,0x4e,0x6d,0x8b,0x6d,0xbc,0x4e,0xd8,0x71,0xdc,0x6d, +0x9c,0x31,0x10,0x40,0xc5,0x42,0x00,0x00,0xba,0x49,0x7b,0x8d,0x3c,0x8e,0x13,0x2c, +0x18,0x6d,0x4e,0x65,0x93,0x71,0xc6,0x71,0xe0,0x72,0xdf,0x49,0xb5,0x6d,0x6f,0x72, +0x2d,0xb1,0x0b,0x4e,0x1e,0x68,0x5f,0x55,0x9c,0x31,0x10,0x95,0xc4,0x32,0x00,0x00, +0xa3,0xc9,0xd0,0xa5,0xe4,0x61,0xd7,0xaa,0xa2,0x38,0x58,0xa1,0x1e,0x35,0x0c,0x40, +0x32,0xb9,0x7a,0x20,0xb9,0x42,0xdc,0xa8,0xe4,0xb9,0xc4,0x41,0x7f,0x39,0x38,0x55, +0x9c,0x31,0x10,0xdd,0xc4,0x42,0x00,0x00,0x0e,0x2e,0x1b,0x65,0x59,0x55,0xa0,0x8d, +0xd1,0x49,0xe4,0xae,0xd5,0x94,0x9a,0x25,0x4e,0xcd,0x17,0x15,0x13,0x88,0x45,0x6a, +0x8e,0x90,0xc7,0x4e,0xe1,0x88,0xd9,0x92,0x9c,0x31,0x10,0x1a,0xc4,0x33,0x00,0x00, +0xa6,0x11,0x5b,0xd5,0x20,0x99,0x15,0xc5,0x40,0x36,0x85,0x38,0xc0,0xb5,0xde,0xc5, +0xd7,0xc5,0xa7,0x15,0x5f,0x55,0x24,0x99,0x1b,0x45,0x46,0x31,0x88,0x35,0xc0,0xb5, +0x9c,0x31,0x10,0x52,0xc4,0x43,0x00,0x00,0xdb,0x89,0xcf,0x71,0x9a,0x2d,0x56,0xad, +0x27,0x4d,0x26,0x69,0x52,0x6d,0x90,0x6e,0xc1,0x29,0xd5,0x78,0xc1,0xad,0x8a,0x29, +0x4f,0x6d,0x2d,0x6d,0x36,0x71,0x62,0x70,0x9c,0x31,0x10,0x61,0xc3,0x32,0x00,0x00, +0x99,0x52,0xc0,0xa5,0xc9,0x45,0xae,0x46,0x7c,0x38,0x4e,0x96,0x3b,0xc5,0x4b,0x39, +0x72,0xa6,0x9e,0xb4,0xba,0xa1,0xba,0x55,0x9e,0x35,0x75,0x69,0x55,0xa6,0x4b,0xc4, +0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00,0x35,0x75,0x74,0x85,0xb3,0x55,0xd5,0x85, +0xc7,0x75,0x93,0x35,0x57,0x75,0x34,0x91,0x36,0x55,0x5a,0x76,0x94,0x74,0xc6,0x76, +0xd6,0x81,0xbc,0x85,0x84,0xa9,0x49,0x71,0x9c,0x31,0x10,0xbb,0xb6,0x65,0x00,0x00, +0x26,0xf1,0x2e,0xd5,0x5c,0x8d,0x90,0xa9,0xad,0x4d,0xbc,0xd1,0xba,0xcd,0x9e,0xc9, +0x72,0xed,0x5b,0x0d,0x52,0xad,0x5d,0x48,0x71,0x0a,0x8f,0x6d,0x9e,0x74,0x9f,0x2a, +0x9c,0x31,0x10,0x21,0x97,0x66,0x30,0x00,0xd5,0xe4,0x82,0x6b,0x3d,0xdb,0x21,0xd3, +0x41,0xdb,0x69,0x93,0xa9,0x93,0xe5,0xae,0xc9,0x82,0x56,0xd3,0x32,0x12,0x3e,0x25, +0x51,0xaa,0x51,0xd0,0x85,0xdb,0xb5,0xdb,0x9c,0x31,0x10,0xac,0x85,0x67,0x30,0x00, +0xd5,0xb4,0x7e,0x52,0x41,0xb4,0x4e,0xe3,0x71,0xaa,0x6a,0x33,0x85,0xcc,0xad,0xbb, +0xa5,0xb3,0x62,0x09,0x5e,0xed,0x76,0xab,0x76,0xb1,0x76,0x4b,0x86,0x0d,0x9a,0xe3, +0x9c,0x31,0x10,0xce,0x75,0x77,0x20,0x00,0x84,0x57,0x43,0xb6,0x3c,0x48,0x4b,0x97, +0x61,0x63,0x63,0x68,0x84,0x9b,0xb2,0x57,0xa3,0xa5,0x74,0x65,0x6b,0x68,0x54,0x8a, +0x5a,0x56,0x6a,0x85,0x8b,0x8a,0x9a,0x83,0x9c,0x31,0x10,0x7a,0x75,0x77,0x30,0x00, +0x9b,0xa8,0x7c,0x4b,0x52,0x55,0x58,0xa3,0x32,0x6d,0x34,0x85,0x65,0x96,0x6a,0x33, +0x78,0xbc,0x89,0x66,0x74,0x71,0x64,0x5a,0x4c,0x8c,0x7e,0x77,0x83,0x80,0x92,0x39, +0x9c,0x31,0x10,0xfc,0x65,0x87,0x40,0x00,0x9d,0x30,0xaa,0xac,0x74,0xec,0x75,0x11, +0x74,0xd1,0x7a,0xc1,0x72,0xf5,0x92,0xfa,0xb2,0xee,0xb3,0x0a,0xbc,0xa1,0x85,0x4d, +0x82,0x51,0xc9,0x51,0xa9,0x05,0x82,0xb1,0x9c,0x31,0x10,0xde,0x76,0x89,0x50,0x00, +0x82,0x88,0x82,0x56,0x94,0xd5,0x8a,0x18,0xa2,0xa9,0x7a,0x64,0x61,0x76,0x7a,0x9b, +0x5b,0x27,0x80,0x95,0xe4,0x8a,0x94,0x7b,0x69,0x82,0x7b,0x85,0x8a,0xa8,0x92,0x15, +0x9c,0x31,0x10,0xde,0x76,0x89,0x50,0x00,0x6a,0xb8,0x42,0x7b,0x4a,0x4b,0x32,0x72, +0x4b,0x82,0x3c,0x78,0x18,0x8d,0x03,0x69,0x23,0x75,0x4a,0xc2,0x6d,0x46,0xc1,0x78, +0xc5,0x9a,0x9b,0x58,0x94,0x89,0xbc,0x85,0x9c,0x31,0x10,0x19,0x85,0x78,0x40,0x00, +0x9c,0xda,0x8c,0x4d,0x9b,0x5c,0xb4,0xa8,0x92,0x60,0x83,0x91,0x8a,0xe5,0x7a,0xaa, +0x8b,0x26,0x92,0x52,0x92,0x85,0xad,0xa0,0x9a,0xdc,0xac,0xa4,0xd3,0x9c,0xda,0x61, +0x9c,0x31,0x10,0x76,0xb5,0x78,0x40,0x00,0x8a,0x59,0x7c,0x0a,0x6c,0xd6,0x62,0x23, +0x68,0xb6,0x85,0x36,0xa0,0xc7,0xa0,0xa9,0x7b,0x38,0x46,0xd9,0x2c,0xa6,0x4e,0xc5, +0xa7,0x35,0xf2,0xc8,0xde,0x36,0x78,0xb9,0x9c,0x31,0x10,0x0b,0xc5,0x77,0x40,0x00, +0x49,0x13,0x3c,0x9c,0x61,0x61,0x9c,0x4d,0xc9,0x6b,0xc0,0x4e,0x88,0xaa,0x4a,0x54, +0x2f,0x9a,0x4d,0x5a,0x8d,0x91,0xc7,0x65,0xcd,0x5b,0x99,0x5d,0x54,0x98,0x28,0x9c, +0x9c,0x31,0x10,0x1f,0xc7,0x67,0x30,0x00,0x3c,0xc5,0x80,0xec,0xc0,0x91,0xd6,0xda, +0xac,0xd9,0x67,0x1c,0x28,0xad,0x2c,0xca,0x6e,0xe5,0xb8,0xd0,0xda,0xdc,0xb8,0xd2, +0x73,0x24,0x2c,0x48,0x20,0xf4,0x5e,0xce,0x9c,0x31,0x10,0xaa,0xc7,0x78,0x40,0x00, +0xb4,0xe3,0xe0,0xd3,0xc4,0xa1,0x7c,0xd3,0x2e,0x52,0x17,0x24,0x54,0xd2,0xae,0xdb, +0xe2,0xd2,0xcc,0xac,0x86,0xcc,0x34,0x5a,0x13,0x15,0x4e,0xe1,0xae,0xcc,0xe6,0xda, +0x9c,0x31,0x10,0xb8,0xc6,0x79,0x40,0x00,0xd0,0x54,0x8b,0x22,0x38,0x4c,0x0f,0x93, +0x46,0xe3,0xa8,0xd3,0xe7,0x12,0xd0,0x9c,0x89,0x5b,0x38,0x9c,0x0d,0x82,0x44,0xf2, +0xa8,0xc3,0xe4,0xdb,0xd0,0x95,0x89,0x63,0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00, +0x38,0xdd,0x0f,0x50,0x44,0xe2,0xaa,0xd3,0xe6,0xdb,0xce,0xdd,0x87,0x1b,0x36,0xdd, +0x0f,0x51,0x48,0xe1,0xae,0xd3,0xe8,0xda,0xca,0xdd,0x83,0x1c,0x36,0x9d,0x11,0x49, +0x9c,0x31,0x10,0xaa,0xc7,0x78,0x40,0x00,0x4c,0xf1,0xb2,0xc3,0xe8,0xeb,0xc6,0x8c, +0x7b,0x23,0x30,0x94,0x13,0x4a,0x54,0xe9,0xba,0xc3,0xe8,0xeb,0xc0,0x8c,0x77,0x23, +0x2c,0x8c,0x13,0x54,0x5c,0xe9,0xc0,0xcc,0x9c,0x31,0x10,0xaa,0xc7,0x78,0x40,0x00, +0xe8,0xe2,0xba,0x95,0x71,0x22,0x2a,0x44,0x17,0x5d,0x62,0xd9,0xc6,0xd4,0xe6,0xd9, +0xb2,0x9c,0x69,0x1a,0x24,0x0b,0x1d,0x35,0x72,0xcb,0xd0,0xe3,0xe2,0x91,0xa6,0xa4, +0x9c,0x31,0x10,0xaa,0xc7,0x78,0x40,0x00,0x5f,0x13,0x20,0x0a,0x25,0x34,0x7e,0xc4, +0xd7,0x2b,0xde,0xcb,0x9c,0xab,0x57,0x0c,0x1c,0x2b,0x2a,0xe9,0x8a,0x8c,0xdd,0x2a, +0xd8,0xd5,0x92,0xa3,0x4f,0x14,0x1a,0x73,0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00, +0x38,0xd8,0x9a,0x5c,0xe1,0x5a,0xce,0xdc,0x86,0xdb,0x47,0x5b,0x18,0xad,0x46,0x8a, +0xa8,0xa9,0xe5,0x13,0xc2,0xe3,0x7b,0x13,0x3f,0x2b,0x1b,0x52,0x56,0x9e,0xb4,0xa2, +0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00,0xe0,0xdc,0xb4,0xe2,0x73,0x1c,0x3a,0xe3, +0x21,0x49,0x64,0xe4,0xc0,0xd4,0xdc,0xe4,0xa8,0xd2,0x69,0x24,0x32,0x94,0x25,0x8b, +0x72,0xe8,0xcc,0xcc,0xda,0xa3,0x9c,0x93,0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00, +0x61,0x23,0x2c,0x0b,0x2d,0x65,0x80,0xd9,0xd1,0x13,0xd2,0xa2,0x92,0x94,0x5b,0x1a, +0x28,0x0a,0x37,0x36,0x90,0x8c,0xd9,0x23,0xc8,0x99,0x84,0x9c,0x53,0x1b,0x26,0x1b, +0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00,0x43,0x29,0xa0,0x45,0xdb,0x73,0xbc,0x8b, +0x7c,0xa3,0x4d,0x53,0x24,0x2d,0x50,0xd8,0xae,0x53,0xdd,0x62,0xb2,0x95,0x75,0x23, +0x45,0x5a,0x25,0x35,0x62,0x84,0xbe,0xaa,0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00, +0xd8,0xd2,0xa2,0xdb,0x6b,0x1b,0x3c,0xe3,0x27,0x50,0x72,0x96,0xc8,0xec,0xd2,0xcc, +0x96,0xe1,0x65,0x12,0x36,0x5c,0x2f,0x81,0x82,0xf2,0xcf,0x0b,0xc8,0x9c,0x8a,0x9b, +0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00,0x5f,0x13,0x32,0x13,0x39,0x5d,0x94,0xa9, +0xd7,0x0b,0xc0,0xab,0x80,0x94,0x57,0x1c,0x2a,0x10,0x47,0x2c,0xa6,0x94,0xd7,0x1c, +0xb0,0xa2,0x78,0xd2,0x55,0x23,0x2a,0x5c,0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00, +0x54,0xe8,0xb2,0x83,0xd5,0x2c,0xa4,0xd4,0x70,0xdb,0x4b,0x22,0x28,0xee,0x66,0xcb, +0xc0,0xa2,0xce,0xd9,0x96,0xd3,0x6f,0x24,0x46,0xdb,0x29,0x5a,0x76,0xcd,0xca,0xeb, +0x9c,0x31,0x10,0x52,0xc8,0x98,0x40,0x00,0xc8,0xd3,0x8c,0xda,0x69,0x1b,0x3c,0x9d, +0x31,0x51,0x8c,0xe2,0xd0,0xdb,0xbc,0x9c,0x82,0xe4,0x65,0x1b,0x34,0x52,0x3d,0x1e, +0x9e,0xea,0xd5,0x0a,0xb0,0xe2,0x7a,0xdb,0x9c,0x31,0x10,0x4a,0xc8,0x88,0x40,0x00, +0x5f,0x0c,0x2c,0x59,0x49,0x2c,0xae,0xd4,0xd7,0x1c,0xa2,0xe2,0x74,0xd2,0x5b,0x1b, +0x28,0xac,0x5c,0xe9,0xbc,0x83,0xcf,0x2b,0x96,0xdc,0x72,0xdb,0x53,0x1a,0x26,0xf6, +0x9c,0x31,0x10,0x3a,0xc7,0x98,0x40,0x00,0x70,0x8b,0xca,0x9a,0xc6,0xe2,0x86,0xd3, +0x6f,0x1c,0x48,0xe3,0x2d,0x90,0x86,0xd5,0xd0,0xed,0xb6,0x93,0x80,0xd2,0x6f,0x62, +0x3e,0x1d,0x33,0x8a,0x9a,0xa9,0xd3,0x1b,0x9c,0x31,0x10,0x52,0xc8,0x98,0x40,0x00, +0xa8,0x8c,0x7a,0xe4,0x6e,0xda,0x32,0x4a,0x43,0x1d,0xae,0xac,0xcf,0x12,0x9a,0xda, +0x78,0xe2,0x67,0x15,0x26,0x52,0x58,0xea,0xc2,0x94,0xc5,0x15,0x8a,0xe3,0x7a,0xe2, +0x9c,0x31,0x10,0x52,0xc8,0x98,0x40,0x00,0x5f,0x12,0x22,0xe6,0x70,0xe2,0xce,0x89, +0xb8,0xda,0x80,0xe3,0x7d,0x14,0x50,0xdb,0x23,0x2b,0x88,0xcc,0xd4,0xdb,0xa8,0xe2, +0x7e,0xda,0x7d,0x13,0x40,0xa5,0x2d,0x50,0x9c,0x31,0x10,0x4a,0xc8,0x88,0x40,0x00, +0xa4,0xca,0xd0,0xf4,0x98,0xdd,0x7e,0xc3,0x7a,0xe2,0x30,0x5b,0x3f,0x05,0xba,0xaa, +0xc7,0x22,0x8c,0xca,0x82,0xdb,0x73,0x2c,0x1e,0x41,0x59,0x2b,0xca,0xad,0xb9,0x0c, +0x9c,0x31,0x10,0x3a,0xc7,0x98,0x40,0x00,0x84,0x9a,0x86,0xe2,0x63,0x13,0x1a,0x5d, +0x77,0x28,0xd0,0x52,0xa7,0x14,0x82,0xe5,0x8d,0x1b,0x51,0x12,0x1d,0x6b,0x92,0xdc, +0xce,0x92,0x98,0xdc,0x84,0xe3,0x89,0x1b,0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00, +0x3c,0xa3,0x2b,0x59,0xac,0xc5,0xc6,0xdc,0x8c,0xeb,0x88,0xdb,0x81,0x13,0x26,0x5b, +0x45,0x44,0xc4,0xa2,0xb7,0x2b,0x82,0xdb,0x8e,0xd2,0x71,0x1c,0x1a,0x12,0x67,0x24, +0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00,0xce,0x33,0xa5,0x1b,0x82,0xcb,0x92,0x9b, +0x5d,0x23,0x1a,0x1b,0x87,0x31,0xca,0x1b,0x95,0x0c,0x88,0xd3,0x8e,0xeb,0x44,0xda, +0x27,0x74,0xa5,0x14,0xc2,0x8a,0x88,0xda,0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00, +0x8e,0xe4,0x89,0x1b,0x30,0x9c,0x3f,0x5a,0xba,0xd4,0xac,0xdc,0x82,0xe3,0x96,0xda, +0x77,0x1b,0x24,0x54,0x63,0x4c,0xc4,0x99,0x9d,0x22,0x88,0xdc,0x9a,0xd4,0x5a,0xdb, +0x9c,0x31,0x10,0xe7,0xc8,0x87,0x30,0x00,0x1e,0x64,0x89,0x16,0xc2,0x96,0x8f,0x0d, +0x90,0xe8,0x92,0xed,0x43,0x0d,0x2e,0xf6,0xa6,0xf8,0xb4,0xa8,0x88,0xe5,0x9b,0x0e, +0x85,0x11,0x2e,0xd0,0x49,0x71,0xb6,0xe6,0x9c,0x31,0x10,0x70,0xc8,0x96,0x30,0x00, +0xa3,0x0a,0x88,0xed,0x9e,0xd0,0x6f,0x0c,0x26,0x6e,0x6d,0x65,0xba,0xa8,0x93,0x31, +0x8e,0xf2,0x9a,0xcd,0x57,0x0d,0x2a,0x89,0x8f,0x0e,0xb6,0x91,0x8a,0xf0,0x98,0xec, +0x9c,0x31,0x10,0xe7,0xc8,0x87,0x30,0x00,0x8a,0xe5,0x41,0x05,0x3e,0xf1,0xa4,0xf8, +0xa6,0xb1,0x8a,0xe9,0x9c,0xe6,0x79,0x09,0x34,0xd1,0x5d,0x99,0xb0,0xed,0x99,0x05, +0x8c,0xe5,0x9a,0xcd,0x65,0x11,0x34,0x91,0x9c,0x31,0x10,0xb4,0xc7,0x86,0x20,0x00, +0x7b,0x8c,0xae,0x8d,0x8d,0x1a,0x95,0x25,0x90,0xe5,0x4d,0x5c,0x3e,0x50,0x94,0xda, +0xa6,0x66,0x8a,0xe8,0x9a,0xe0,0x80,0xd5,0x3f,0x16,0x57,0x66,0xa4,0xac,0x98,0xe0, +0x9c,0x31,0x10,0x3c,0xc7,0x76,0x20,0x00,0x8c,0xd2,0x9a,0x84,0x6c,0xd4,0x3c,0xaa, +0x73,0xa9,0xa8,0xde,0x8f,0x0d,0x91,0x0a,0x92,0x99,0x5a,0xda,0x44,0x5d,0x8b,0x15, +0xa2,0x59,0x8b,0x22,0x94,0xe3,0x82,0xd4,0x9c,0x31,0x10,0x1e,0xb7,0x66,0x10,0x00, +0x1c,0xcd,0x2e,0x89,0xb6,0xa9,0xb2,0xb5,0x96,0xed,0xac,0x9c,0x62,0xda,0x12,0xa0, +0x5f,0x6c,0xc4,0xdd,0xa4,0xdb,0x9f,0x63,0x9a,0xe2,0x41,0x22,0x22,0x95,0x89,0x0b, +0x9c,0x31,0x10,0x42,0xb6,0x66,0x20,0x00,0xbe,0x88,0x9a,0x8a,0xa4,0xcc,0x7c,0x83, +0x2c,0xd5,0x42,0x53,0xa8,0xe2,0xb0,0xab,0x9d,0xb3,0x98,0xb2,0x54,0xf3,0x2e,0xe3, +0x6f,0x64,0xb7,0x1b,0xa8,0xcb,0x9c,0x8a,0x9c,0x31,0x10,0x02,0xa6,0x55,0x10,0x00, +0x6a,0xa0,0x01,0x09,0x10,0x90,0xab,0x92,0xea,0x92,0xc9,0xd9,0x96,0xf4,0x2f,0x50, +0x0d,0x0e,0x5e,0xe5,0xe0,0xed,0xe8,0xcd,0x91,0x2d,0x34,0xf1,0x1d,0x11,0x48,0x95, +0x9c,0x31,0x10,0x83,0xa5,0x54,0x00,0x00,0xbf,0x63,0xf2,0x62,0xa7,0xa2,0x44,0x9b, +0x27,0x63,0x4c,0xed,0xa1,0x9b,0xe0,0x9a,0xb9,0x53,0x5c,0x4b,0x28,0xcc,0x4d,0x14, +0x8d,0x1a,0xc5,0x1b,0xba,0xdc,0x70,0xe3,0x9c,0x31,0x10,0x8c,0xa4,0x43,0x00,0x00, +0x3b,0x8d,0x4e,0x4d,0x82,0x4d,0xb2,0x50,0xb6,0x71,0x83,0x7a,0x4b,0x99,0x53,0x95, +0x7a,0x2d,0xa1,0x92,0xaf,0xd1,0x8d,0xb0,0x58,0xb0,0x58,0x92,0x78,0x52,0x93,0x71, +0x9c,0x31,0x10,0x24,0x94,0x32,0x00,0x00,0xc5,0x34,0xa3,0x31,0x4c,0xf1,0x3f,0x71, +0x75,0x10,0x99,0x0a,0xa8,0xe9,0x9a,0xe6,0x62,0xa9,0x4e,0xec,0x76,0xe8,0x90,0xc5, +0x98,0xee,0x90,0xae,0x72,0xb0,0x66,0xd0,0x9c,0x31,0x10,0x9b,0x62,0x22,0x00,0x00, +0x50,0x18,0xf4,0x64,0xf6,0xae,0xa7,0xac,0x46,0xb3,0x2b,0x31,0x5d,0x63,0x9e,0xdd, +0xbc,0xdb,0x9a,0xa4,0x76,0xa3,0x83,0x61,0x80,0x9b,0x70,0x99,0x8e,0xf5,0x9d,0x5d, +0x9c,0x31,0x10,0x78,0x52,0x21,0x00,0x00,0x9a,0x16,0x8f,0x21,0x71,0x4c,0x75,0x94, +0x4c,0x94,0xa6,0x55,0xcd,0xe2,0xa9,0xde,0x89,0xd2,0x72,0xa5,0x51,0xac,0x7a,0x6d, +0xbc,0xe5,0x9d,0xdc,0x71,0xe5,0x76,0x5d,0x9c,0x31,0x10,0xf4,0x52,0x22,0x00,0x00, +0xaa,0x9d,0xc2,0x1b,0xe1,0xca,0xf6,0x5a,0xa3,0x23,0x49,0x6c,0x2a,0xab,0x3a,0x6b, +0x36,0x62,0x42,0x1c,0x41,0xea,0x16,0x2b,0x1a,0x24,0x5a,0xa4,0x82,0xa3,0x7e,0x1a, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_DIS_CONNECT.txt b/config/_default_cfg_src_/res/cn/SOUND_DIS_CONNECT.txt new file mode 100644 index 0000000..dd21229 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_DIS_CONNECT.txt @@ -0,0 +1,245 @@ +0x9c,0x31,0x10,0xcf,0x41,0x11,0x00,0x00,0x7e,0xdb,0x7e,0xdb,0x80,0xdb,0x80,0x9b, +0x8f,0x12,0x89,0x0c,0x9a,0x8b,0x98,0x9d,0xa4,0x84,0x92,0x5b,0x9c,0xa1,0xa4,0x6d, +0xa0,0x99,0xb4,0x8a,0xc2,0xce,0xc0,0x5a,0x9c,0x31,0x10,0x1c,0x31,0x21,0x00,0x00, +0xfa,0x3b,0xbd,0x4b,0xd5,0x3a,0xcd,0x1a,0xde,0xc3,0xda,0x33,0xad,0x25,0xb1,0xb4, +0xa5,0xb4,0x84,0xbb,0x90,0xb2,0x56,0xd3,0x6d,0x33,0x79,0xb3,0x49,0xb1,0x69,0x9c, +0x9c,0x31,0x10,0x8f,0x73,0x47,0x20,0x00,0x7a,0xdd,0x7a,0xdd,0x7a,0xdd,0x7a,0xdd, +0x7a,0xdd,0x7a,0xdd,0x7a,0xdd,0x7a,0xdd,0x7a,0xdd,0x7a,0xdd,0x7a,0xdd,0x7a,0xdd, +0x82,0xdc,0x8b,0x58,0xbc,0x14,0xdd,0x35,0x9c,0x31,0x10,0x9b,0x72,0x37,0x10,0x00, +0xb6,0x16,0x44,0xd3,0x01,0xbb,0x11,0x26,0x3d,0xc4,0x6d,0xaa,0x99,0xa7,0xa6,0x55, +0x9a,0x39,0x82,0x27,0x76,0x46,0x71,0xa8,0x72,0xa7,0x81,0x46,0x89,0x38,0x89,0xb7, +0x9c,0x31,0x10,0xd4,0x42,0x24,0x00,0x00,0xc2,0x23,0x89,0xbc,0x51,0x05,0x1d,0xb5, +0x05,0x2c,0x96,0x33,0xb5,0x47,0x9a,0xbc,0x9a,0x24,0x62,0x46,0x24,0xcb,0x05,0x13, +0x61,0xd3,0x9d,0xcd,0x92,0x37,0x75,0x93,0x9c,0x31,0x10,0xd6,0xa4,0x68,0x40,0x00, +0x7e,0xb7,0x7e,0xb7,0x7e,0xb7,0x7c,0xb7,0x7c,0xb7,0x7c,0xb7,0x7e,0xb7,0x80,0xb7, +0x82,0xb7,0x80,0xb7,0x80,0xb8,0x86,0xb7,0x9d,0x59,0xca,0x16,0xcc,0xc3,0x5e,0x4b, +0x9c,0x31,0x10,0x2f,0xc6,0x68,0x40,0x00,0x4f,0x4a,0x48,0xe2,0x69,0x1e,0x90,0xda, +0xa4,0xe2,0xa4,0x8b,0xa6,0x73,0x9e,0x96,0x77,0x1a,0x3b,0x59,0x2a,0xde,0x58,0xd2, +0x96,0xa1,0xb4,0xdd,0xb2,0xda,0xa0,0x52,0x9c,0x31,0x10,0x96,0xc5,0x58,0x30,0x00, +0x96,0x5c,0x8e,0x56,0x6d,0x93,0x38,0x9a,0x2c,0x5a,0x60,0x53,0xa0,0x58,0xb9,0x59, +0xb1,0x64,0x9e,0x46,0x94,0x5b,0x88,0x56,0x61,0x64,0x30,0x88,0x34,0x6a,0x6f,0x56, +0x9c,0x31,0x10,0x95,0xc5,0x68,0x40,0x00,0xa8,0xb6,0xb8,0xb9,0xab,0x36,0x9a,0xd9, +0x96,0x29,0x88,0xc1,0x5c,0x47,0x27,0x18,0x30,0xb5,0x72,0xba,0xb0,0x15,0xc0,0xc4, +0xaf,0x3c,0x97,0x4b,0x92,0x98,0x88,0x40,0x9c,0x31,0x10,0xbd,0xc5,0x58,0x40,0x00, +0x5c,0x55,0x24,0x87,0x2c,0x58,0x70,0x59,0xb2,0x17,0xc3,0x67,0xb1,0x58,0x9b,0x59, +0x98,0x48,0x8c,0x61,0x5c,0x55,0x1f,0x9b,0x25,0x8a,0x6d,0x56,0xb4,0x59,0xc8,0x57, +0x9c,0x31,0x10,0x14,0xc6,0x69,0x50,0x00,0xb3,0x1b,0x96,0xeb,0x94,0xc9,0x92,0x9c, +0x69,0x1e,0x22,0xea,0x16,0xda,0x5a,0x9c,0xac,0xdb,0xcc,0xe2,0xb9,0x14,0x98,0xe4, +0x90,0xe2,0x94,0x93,0x79,0x1b,0x34,0x13,0x9c,0x31,0x10,0xbd,0xc5,0x58,0x40,0x00, +0x10,0xaa,0x41,0x45,0x99,0x95,0xcb,0x59,0xc2,0x56,0xa1,0x56,0x8f,0x0c,0x97,0x68, +0x8e,0x54,0x56,0x53,0x13,0xa8,0x1e,0x4b,0x72,0x52,0xbf,0x57,0xce,0x5a,0xb0,0x93, +0x9c,0x31,0x10,0xa0,0xc6,0x69,0x40,0x00,0x90,0xa3,0x91,0x1c,0x9e,0x9c,0x7f,0x5a, +0x30,0x12,0x07,0x1c,0x3c,0x92,0x9b,0x22,0xd0,0xdd,0xc4,0xdb,0x9f,0x1a,0x84,0xa4, +0x95,0x0a,0x9c,0xa1,0x71,0x65,0x20,0x54,0x9c,0x31,0x10,0x1a,0xc5,0x69,0x40,0x00, +0x0a,0xd4,0x50,0x3b,0xaa,0xa6,0xd2,0xc4,0xbe,0xb9,0x95,0x27,0x80,0xc5,0x96,0xb9, +0x9e,0x37,0x6d,0x36,0x1a,0x48,0x0e,0xb4,0x56,0x49,0xb0,0xa9,0xd2,0xb4,0xb8,0xb8, +0x9c,0x31,0x10,0xa0,0xc6,0x69,0x40,0x00,0x8f,0x13,0x7c,0x9b,0x96,0xdd,0xa2,0x51, +0x75,0x29,0x1e,0x4c,0x08,0xf4,0x4e,0x94,0xaa,0xda,0xd2,0xe2,0xba,0x9b,0x8f,0x1b, +0x78,0x63,0x93,0x12,0xaa,0x63,0x87,0x54,0x9c,0x31,0x10,0xa0,0xc6,0x69,0x40,0x00, +0x30,0x0a,0x03,0x23,0x38,0x8a,0x98,0xe3,0xd2,0xd4,0xc4,0x9a,0x95,0x1b,0x74,0x93, +0x89,0x5b,0xae,0x9c,0x9d,0x5a,0x4e,0xab,0x05,0x93,0x1a,0xe5,0x79,0x11,0xc8,0xeb, +0x9c,0x31,0x10,0x93,0xc6,0x79,0x30,0x00,0xce,0xd4,0xa0,0xe3,0x7b,0x1b,0x7a,0x9b, +0xa6,0xa3,0xb0,0x54,0x79,0x22,0x1a,0x4b,0x02,0xf4,0x4c,0x8c,0xac,0xe9,0xd4,0xd4, +0xb4,0x9b,0x85,0x13,0x70,0x1b,0x91,0x4a,0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00, +0xb6,0xe9,0x9d,0x4e,0x46,0xa3,0x03,0x93,0x20,0xd3,0x81,0x20,0xc8,0xd4,0xca,0xdb, +0x9c,0xdb,0x79,0x1a,0x7a,0x9c,0xa2,0xe4,0xae,0x51,0x7b,0x1b,0x24,0x0b,0x0e,0xe6, +0x9c,0x31,0x10,0x12,0xc5,0x78,0x20,0x00,0x4e,0x30,0x9e,0xa6,0xc4,0xc8,0xb2,0xaa, +0x90,0xc6,0x7d,0x26,0x81,0x47,0x98,0x47,0x94,0x99,0x6a,0xd7,0x4a,0x26,0x4c,0xc8, +0x64,0x47,0x80,0xb7,0x92,0xb6,0x96,0xb8,0x9c,0x31,0x10,0xc4,0xa4,0x33,0x00,0x00, +0xdd,0x94,0xd0,0x65,0xb4,0x82,0x99,0x32,0x94,0x84,0x99,0x98,0x6b,0x52,0x27,0x86, +0x05,0x81,0x23,0xa4,0x59,0x51,0x87,0x75,0xb0,0x75,0xcb,0x75,0xc9,0x65,0xb6,0x85, +0x9c,0x31,0x10,0x28,0xa3,0x23,0x00,0x00,0x9c,0x69,0x85,0x8d,0x7f,0x6a,0x77,0x49, +0x5a,0x80,0x38,0x0d,0x34,0x71,0x51,0x6c,0x6c,0x91,0x83,0x4a,0xa3,0x69,0xbb,0x59, +0xb8,0x69,0xa3,0x4d,0x8a,0x85,0x7a,0x4d,0x9c,0x31,0x10,0xc2,0x92,0x33,0x00,0x00, +0x76,0xd3,0x82,0x9c,0x77,0x9c,0x49,0x13,0x14,0x10,0x10,0x2b,0x47,0x15,0x7d,0x1b, +0x9e,0x9b,0xbe,0x9c,0xd7,0x5b,0xde,0xe2,0xda,0x94,0xb4,0x5b,0x67,0x5a,0x18,0x9b, +0x9c,0x31,0x10,0x3a,0xa2,0x22,0x00,0x00,0x38,0x4d,0x40,0x6d,0x64,0xa6,0x8b,0x28, +0xa2,0x8d,0xa9,0x8d,0xa8,0x88,0xa0,0x2d,0x93,0x6a,0x81,0x91,0x6c,0x84,0x5d,0x50, +0x5c,0x4a,0x69,0x72,0x7b,0x90,0x88,0x8d,0x9c,0x31,0x10,0x70,0x82,0x22,0x00,0x00, +0xc0,0xd4,0xc6,0x5a,0xc0,0xdb,0xaa,0x9b,0x80,0x89,0x4f,0x1b,0x27,0x26,0x20,0xdb, +0x4d,0x11,0x91,0x1c,0xc4,0xdc,0xce,0xda,0xbb,0x12,0x9c,0xe2,0x8d,0x0d,0x86,0xe3, +0x9c,0x31,0x10,0x04,0x71,0x22,0x00,0x00,0x7f,0x23,0x5e,0x90,0x44,0x5c,0x5d,0x1b, +0x84,0xe3,0x9c,0x93,0x9a,0xda,0x77,0x54,0x60,0x5a,0x6a,0x5b,0x91,0x6e,0xb7,0x18, +0xbe,0xda,0xad,0x54,0x93,0x92,0x80,0xe2,0x9c,0x31,0x10,0x19,0x61,0x21,0x10,0x00, +0x6e,0xb9,0x6a,0xb5,0x66,0xc1,0x63,0x49,0x7d,0x45,0xae,0xb2,0xd2,0x25,0xcb,0x21, +0xb2,0xa2,0x9a,0x3a,0x8f,0x56,0x90,0x42,0x98,0xb6,0x94,0xc2,0x80,0x91,0x74,0x46, +0x9c,0x31,0x10,0x29,0x65,0x47,0x60,0x00,0x83,0x5b,0x8b,0x5b,0x83,0x5b,0x7b,0x5b, +0x6b,0x5b,0x53,0x5b,0x5b,0x5b,0x83,0x5b,0xa3,0x5b,0x93,0x5b,0x73,0x5b,0x63,0x5b, +0x63,0x5b,0x7a,0x64,0xe6,0xad,0xd1,0x6d,0x9c,0x31,0x10,0xde,0xb9,0xaa,0x70,0x00, +0x95,0x87,0x8a,0x84,0xbb,0x59,0xcd,0xb2,0xc8,0xd6,0x86,0x8a,0x7d,0x89,0x5d,0x67, +0x4d,0x67,0x34,0x57,0x44,0x66,0x64,0x67,0x74,0x67,0x83,0x67,0x7b,0x77,0x53,0x77, +0x9c,0x31,0x10,0x51,0xc7,0x66,0x00,0x00,0x4d,0x09,0x41,0x14,0x5f,0x1c,0x9b,0x59, +0xb9,0x1c,0xa5,0x64,0x78,0xe3,0x53,0xa3,0x34,0x1a,0x45,0x54,0x90,0xd3,0xb9,0x12, +0xb5,0x13,0xb2,0x95,0xb2,0xd3,0x82,0x9a,0x9c,0x31,0x10,0x8d,0xc8,0x66,0x10,0x00, +0x39,0x31,0x25,0x51,0x72,0xd1,0xb0,0xa6,0xa6,0xc0,0x99,0x25,0xb9,0x69,0xb3,0x31, +0x5f,0x11,0x1a,0x0a,0x45,0x2d,0x9d,0x4d,0xab,0x49,0x8e,0xcd,0x9c,0x8d,0xba,0x8c, +0x9c,0x31,0x10,0x38,0xc9,0x56,0x10,0x00,0x82,0xac,0x29,0x2d,0x1a,0xe9,0x80,0xac, +0xb4,0xc4,0x9d,0x20,0x95,0x04,0xba,0xed,0xa6,0xc9,0x42,0xeb,0x0a,0xa5,0x51,0x89, +0xb2,0xeb,0xa8,0xad,0x92,0xb2,0xad,0x0a,0x9c,0x31,0x10,0xd1,0xc9,0x66,0x20,0x00, +0xb9,0x2e,0x64,0xcd,0x13,0x11,0x22,0xd1,0x9c,0x8d,0xb6,0xed,0x9b,0x6d,0xa8,0xed, +0xc2,0xad,0x88,0xa9,0x25,0x45,0x04,0x49,0x6d,0x8c,0xbd,0x0e,0xa2,0xcd,0xa8,0x6d, +0x9c,0x31,0x10,0x38,0xc9,0x56,0x10,0x00,0xc3,0x03,0xa5,0x2a,0x40,0xec,0x02,0xd2, +0x35,0x8a,0xb2,0x53,0xa4,0x8b,0xa5,0x2c,0xc9,0x6a,0xba,0xeb,0x60,0x8b,0x11,0x4b, +0x0c,0x33,0x90,0xc5,0xad,0x49,0xa1,0x8b,0x9c,0x31,0x10,0x1e,0xca,0x66,0x00,0x00, +0xc2,0xb5,0xc4,0xb5,0x85,0x05,0x2f,0x34,0x02,0x81,0x5f,0x81,0xb2,0xf5,0x98,0xe5, +0xba,0xa4,0xc7,0x16,0x9b,0x35,0x4e,0xf9,0x0d,0x0a,0x29,0x28,0xae,0x79,0x96,0xb5, +0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00,0xaf,0x14,0xcd,0x16,0xac,0xf9,0x68,0xd5, +0x23,0x15,0x06,0xa0,0x8e,0xf2,0xa1,0x01,0x9f,0x45,0xce,0xd5,0xb4,0xc5,0x8a,0xe1, +0x3f,0x05,0x02,0xd1,0x5b,0x75,0xae,0xd5,0x9c,0x31,0x10,0xb2,0xca,0x76,0x10,0x00, +0x88,0xc5,0xca,0x86,0xb7,0x25,0xa1,0x55,0x60,0xf5,0x17,0x3a,0x22,0xe8,0xac,0x35, +0x80,0xb6,0xb9,0x85,0xc3,0x25,0xa9,0x06,0x84,0x84,0x39,0x05,0x04,0x62,0x75,0xe4, +0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00,0x98,0xf9,0x8d,0x26,0xd0,0x54,0xa8,0xf5, +0xa3,0x16,0x61,0x34,0x1b,0x29,0x24,0xe6,0xa6,0x58,0x7a,0xa2,0xb9,0x51,0xbf,0x00, +0xa7,0x31,0x8e,0xc5,0x44,0xe6,0x06,0x80,0x9c,0x31,0x10,0x2f,0xcb,0x76,0x10,0x00, +0x67,0x95,0x9d,0x0a,0x84,0xf9,0xca,0x99,0xa8,0xd5,0xa7,0x05,0x79,0x16,0x2f,0x10, +0x16,0xa1,0x8e,0xe2,0x82,0xe0,0x9f,0x41,0xc2,0xf5,0xa3,0x1a,0xa2,0xd9,0x67,0x08, +0x9c,0x31,0x10,0xb6,0xca,0x85,0x10,0x00,0x25,0x19,0x2e,0xf9,0x86,0x47,0x7c,0xa6, +0xbc,0xf5,0xaf,0x15,0xb5,0x46,0xa0,0xf7,0x57,0x08,0x1f,0x2b,0x3d,0x5a,0x7c,0x69, +0x86,0xa8,0xc0,0xa7,0xb0,0xe6,0xb7,0x16,0x9c,0x31,0x10,0xc9,0xc9,0x76,0x20,0x00, +0x99,0x09,0x4f,0x2d,0x1f,0x95,0x3d,0xd8,0x76,0x79,0x8e,0x95,0xbc,0x31,0xb6,0x8d, +0xb8,0xe9,0x9a,0xe9,0x51,0x08,0x27,0x4d,0x2f,0x72,0x6e,0x76,0x8e,0xb0,0xb6,0x6c, +0x9c,0x31,0x10,0x5d,0xc9,0x65,0x20,0x00,0xb8,0xa5,0xbb,0x0a,0xa6,0xe9,0x61,0x29, +0x31,0x25,0x24,0x84,0x60,0x89,0x86,0xa6,0xab,0x25,0xbb,0x48,0xb9,0x2c,0xb3,0x0d, +0x7e,0xf1,0x42,0xd6,0x24,0xb6,0x3d,0x91,0x9c,0x31,0x10,0x4c,0xc8,0x66,0x20,0x00, +0x79,0x50,0x99,0x94,0xb6,0xf5,0xb8,0x79,0xb8,0xfa,0xa0,0x75,0x62,0xcd,0x37,0x09, +0x24,0x65,0x54,0xa5,0x82,0x85,0xa4,0xe5,0xb7,0x25,0xbb,0x09,0xb7,0x2d,0x8f,0x0d, +0x9c,0x31,0x10,0xa8,0xc7,0x65,0x20,0x00,0x55,0x91,0x2e,0x90,0x2b,0x95,0x5f,0x36, +0x8a,0x36,0xac,0x31,0xbe,0x4c,0xc0,0x68,0xb5,0x69,0x83,0x6a,0x4e,0x8d,0x29,0x91, +0x2e,0xd0,0x60,0x90,0x8d,0x91,0xb0,0x71,0x9c,0x31,0x10,0x70,0xc6,0x45,0x00,0x00, +0xc0,0x5a,0xc3,0x89,0xb1,0x59,0x7f,0x39,0x4c,0x45,0x2c,0x46,0x32,0xe1,0x5d,0x81, +0x8a,0xb5,0xac,0xa9,0xbd,0x89,0xc1,0x85,0xaf,0x75,0x83,0x65,0x5a,0x65,0x3c,0x85, +0x9c,0x31,0x10,0xaf,0xc6,0x24,0x00,0x00,0x33,0x89,0x50,0x72,0x7a,0x71,0xa0,0xb1, +0xb8,0x79,0xc3,0x75,0xba,0x75,0x96,0x71,0x67,0x69,0x3e,0x95,0x2c,0x66,0x3f,0x75, +0x6f,0x59,0x9c,0x91,0xb9,0x61,0xc7,0x89,0x9c,0x31,0x10,0x0d,0xc5,0x34,0x00,0x00, +0xbf,0x6a,0x9b,0x6b,0x6c,0x6b,0x43,0x6c,0x2f,0x02,0x3d,0x8a,0x69,0x4c,0x96,0x94, +0xb4,0x63,0xc1,0x6a,0xbd,0x6b,0xa0,0x6c,0x75,0x8b,0x4e,0x6b,0x37,0x4a,0x3d,0x8d, +0x9c,0x31,0x10,0x02,0xc4,0x23,0x00,0x00,0x63,0x15,0x8d,0xb8,0xac,0x35,0xba,0xb6, +0xbc,0x22,0xa6,0x20,0x7e,0xe4,0x56,0xa1,0x3d,0xd2,0x3e,0x44,0x5d,0x28,0x86,0x16, +0xa5,0xba,0xb6,0xb4,0xbb,0x34,0xa9,0xb6,0x9c,0x31,0x10,0xf9,0xb4,0x23,0x00,0x00, +0x88,0x9a,0x38,0x20,0x04,0xb5,0x02,0x75,0x37,0x76,0x84,0x51,0xc2,0x75,0xe5,0x91, +0xed,0x86,0xcf,0x75,0x8b,0x84,0x3f,0x31,0x10,0xa6,0x10,0x45,0x3e,0x85,0x82,0x85, +0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00,0xbc,0x6d,0xdc,0x55,0xe0,0x6d,0xc2,0x44, +0x83,0xa9,0x42,0x2d,0x20,0x85,0x26,0x4a,0x4a,0x8c,0x80,0x91,0xb2,0xc9,0xcc,0x35, +0xc8,0x4d,0xaa,0xb2,0x7b,0x4d,0x51,0x85,0x9c,0x31,0x10,0x8c,0xa4,0x43,0x00,0x00, +0x01,0x88,0x1b,0x6d,0x5b,0x4d,0x9f,0x6d,0xd9,0xad,0xf0,0x4d,0xdc,0x91,0x9f,0x4d, +0x5a,0x89,0x22,0x6d,0x0b,0xc9,0x20,0xb1,0x48,0x3a,0x7c,0x8c,0xa9,0x49,0xc0,0x65, +0x9c,0x31,0x10,0x03,0xa4,0x42,0x00,0x00,0xc7,0x4e,0xcb,0x91,0xcb,0x51,0xb3,0x69, +0x91,0x8d,0x69,0xac,0x46,0x79,0x22,0x14,0x0d,0xae,0x28,0x89,0x65,0x29,0xa6,0x49, +0xcd,0x8d,0xd8,0x2e,0xd9,0x4d,0xc4,0x6d,0x9c,0x31,0x10,0x39,0xa6,0x54,0x00,0x00, +0x94,0xed,0x67,0x0d,0x46,0x71,0x3a,0xed,0x33,0x42,0x38,0xe9,0x64,0xd1,0x97,0x31, +0xbe,0xed,0xc4,0xcd,0xbb,0x2d,0xa2,0xcd,0x7f,0x11,0x56,0xf1,0x3e,0xed,0x42,0xd1, +0x9c,0x31,0x10,0xa8,0xaa,0xa8,0x30,0x00,0x53,0xbb,0x73,0xbb,0x93,0xbb,0xb3,0xbb, +0xab,0xbb,0x93,0xbb,0x73,0xba,0x7d,0x55,0x65,0xcb,0x5d,0x43,0x6c,0xbb,0x84,0xbb, +0x9c,0x3b,0xee,0xd4,0x7c,0xe1,0xad,0x5b,0x9c,0x31,0x10,0x69,0x9a,0x97,0x30,0x00, +0x3e,0x62,0x34,0x5a,0x3c,0x4d,0xbb,0xc1,0x8c,0x46,0x3c,0x4c,0x34,0x11,0x4b,0xda, +0x1b,0xdd,0x1c,0x1d,0x33,0x9e,0x63,0x65,0x53,0xa8,0x93,0xe5,0xab,0xaa,0xbc,0x21, +0x9c,0x31,0x10,0xe2,0x98,0x87,0x20,0x00,0xb5,0x42,0xc4,0xdb,0x9c,0x5b,0x63,0xd2, +0x4b,0x9d,0x64,0x93,0x5c,0xb4,0x4c,0x49,0x63,0xc5,0x8b,0x3a,0x7b,0x9b,0x73,0x33, +0x93,0xcc,0x85,0x4b,0x45,0x53,0x6d,0xc3,0x9c,0x31,0x10,0xc8,0x98,0x98,0x30,0x00, +0x6d,0x23,0x2c,0xb3,0x13,0xc3,0x23,0xab,0x1b,0x2b,0x42,0x33,0x5b,0x33,0x9a,0xc3, +0xb4,0x44,0x8b,0xba,0x96,0x3a,0x8b,0xac,0x4c,0x23,0x93,0x32,0xa5,0x9c,0xc6,0x1d, +0x9c,0x31,0x10,0x55,0x99,0x98,0x30,0x00,0xf4,0x28,0xc3,0xb4,0xc8,0xc4,0xb3,0xca, +0xaa,0xca,0xad,0x64,0xac,0x53,0x8b,0x43,0xaa,0xcb,0xad,0x3c,0xac,0x34,0xd4,0x31, +0x9d,0x94,0x93,0x0c,0x94,0xb0,0x79,0xc5,0x9c,0x31,0x10,0xc2,0x99,0x89,0x30,0x00, +0x84,0xc4,0x5a,0xeb,0x84,0x42,0x55,0xd3,0x5c,0x64,0x8e,0x4a,0x1b,0x34,0x9a,0x95, +0x6c,0xa2,0x63,0x92,0xab,0x3b,0x72,0x4c,0xb1,0x21,0x73,0x8c,0xba,0x1c,0x6b,0xab, +0x9c,0x31,0x10,0x45,0x8a,0x99,0x30,0x00,0x99,0x5b,0x22,0x93,0x92,0x44,0x43,0x92, +0xb4,0x43,0x72,0x94,0x92,0x63,0x5b,0x59,0x25,0x15,0x3a,0x9a,0x3a,0x22,0x64,0xe4, +0x73,0xe4,0xdd,0xa2,0xc2,0x9c,0xad,0x1b,0x9c,0x31,0x10,0x27,0xaa,0xa9,0x30,0x00, +0x5c,0x34,0x75,0xa9,0x62,0xbd,0x71,0x52,0x94,0xc3,0x8d,0x3b,0x94,0xcc,0x72,0xb9, +0x53,0xb3,0x4c,0x34,0x5c,0x4b,0x7b,0xca,0x9b,0xbc,0xbb,0xd3,0xa3,0x5a,0x4b,0x4b, +0x9c,0x31,0x10,0x01,0xba,0x99,0x40,0x00,0x6a,0x32,0x52,0x63,0x65,0xe2,0x85,0xd5, +0x9a,0x52,0xb2,0x1b,0x91,0xd4,0x6a,0xd9,0x59,0x13,0x53,0x14,0x55,0x1b,0xa2,0x5b, +0x9d,0xdb,0xc9,0x2b,0x86,0x64,0x76,0x6b,0x9c,0x31,0x10,0x2a,0xba,0x99,0x30,0x00, +0x41,0xea,0x41,0xa4,0x61,0xe3,0x98,0xeb,0xbd,0xab,0xc9,0xa3,0x7d,0xe3,0x6a,0xeb, +0x29,0xa3,0x36,0x22,0x62,0xf3,0xbd,0xdb,0xc6,0x6b,0xe1,0x65,0x7a,0x22,0x5d,0xdb, +0x9c,0x31,0x10,0xbd,0xba,0x88,0x30,0x00,0x1e,0x5d,0x25,0xd8,0x82,0xe2,0xc5,0xae, +0xda,0x61,0xd5,0xa2,0x6a,0x5e,0x46,0x18,0x0f,0x75,0x1d,0x02,0xb9,0xd1,0xc6,0x66, +0xf2,0x23,0xba,0x62,0x55,0x63,0x31,0x6d,0x9c,0x31,0x10,0x54,0xcb,0x89,0x30,0x00, +0x36,0x42,0x6a,0x1b,0x99,0x64,0xb2,0x11,0xb9,0x8d,0x92,0x13,0x62,0x02,0x45,0x04, +0x32,0x03,0x8d,0x13,0x92,0x24,0xc5,0x1b,0xae,0x5b,0x79,0x13,0x62,0xdb,0x14,0xda, +0x9c,0x31,0x10,0x6f,0xcb,0x88,0x20,0x00,0x6e,0xe2,0x7c,0xd6,0xb6,0xa9,0xb9,0x5b, +0xa6,0x1c,0x5d,0x93,0x51,0xd2,0x12,0x5d,0x9d,0x22,0x7a,0x63,0xd1,0x64,0xae,0x71, +0x89,0x2c,0x5e,0xa4,0x18,0x6b,0x63,0x9a,0x9c,0x31,0x10,0x37,0xcc,0x98,0x30,0x00, +0x89,0x6d,0xaa,0x6d,0xbd,0x90,0xaa,0x2e,0x61,0xcd,0x56,0x2e,0x0d,0xc5,0xad,0x8c, +0x6e,0x2d,0xd9,0x8d,0xa2,0x4d,0x8d,0x8d,0x56,0x4d,0x19,0x2e,0x6e,0xe4,0x85,0x49, +0x9c,0x31,0x10,0xae,0xcb,0x88,0x10,0x00,0xaf,0x16,0xb9,0x52,0xa6,0x59,0x5d,0xd5, +0x4a,0x5b,0x22,0x23,0xa5,0x31,0x7a,0x6d,0xd0,0xec,0xa2,0xd9,0x85,0x23,0x52,0xa4, +0x18,0x13,0x87,0x0b,0x7d,0x0b,0xba,0xcb,0x9c,0x31,0x10,0x30,0xcb,0x97,0x10,0x00, +0xb0,0xa9,0xa5,0x0d,0x5f,0x09,0x3f,0x0d,0x39,0x51,0xa4,0x72,0x7f,0x30,0xce,0x71, +0x9f,0x4d,0x84,0x8d,0x4d,0x0d,0x20,0x46,0x91,0x40,0x78,0xc5,0xc1,0x26,0xa4,0xc4, +0x9c,0x31,0x10,0xf1,0xcb,0x97,0x20,0x00,0xa4,0xe9,0x5b,0x0d,0x34,0xed,0x55,0x8d, +0x94,0x71,0x8f,0x51,0xc2,0x91,0x9b,0x4d,0x84,0xad,0x45,0x09,0x2c,0x66,0x96,0xe8, +0x72,0xc9,0xc8,0xe9,0x9a,0xe9,0xa0,0xcd,0x9c,0x31,0x10,0x6f,0xcb,0x88,0x20,0x00, +0x5a,0x23,0x29,0xb4,0x6f,0x64,0x85,0x31,0x9a,0xad,0xb8,0xeb,0x96,0xa2,0x81,0x9c, +0x42,0x13,0x35,0x4b,0x99,0x8a,0x71,0xcc,0xc9,0xdb,0x91,0xd2,0x9d,0xa4,0x5e,0x22, +0x9c,0x31,0x10,0xe0,0xcb,0x89,0x20,0x00,0x25,0x73,0x7b,0x22,0x7d,0x23,0x9e,0xa3, +0xb1,0x1b,0x96,0x5b,0x81,0x93,0x3a,0x02,0x41,0xe5,0x99,0x32,0x6e,0x2b,0xc9,0xa4, +0x8e,0x23,0x99,0xab,0x5a,0x23,0x25,0x63,0x9c,0x31,0x10,0x6f,0xcb,0x88,0x20,0x00, +0x87,0x13,0x75,0x52,0xaa,0x8b,0xa9,0x13,0x96,0x53,0x81,0x93,0x36,0x12,0x49,0xf5, +0x99,0x29,0x72,0x23,0xc9,0x6c,0x8a,0x22,0x9d,0xac,0x56,0x23,0x29,0x63,0x86,0xc3, +0x9c,0x31,0x10,0xea,0xca,0x98,0x20,0x00,0x78,0xd2,0xa3,0x94,0xac,0x9a,0x92,0xd2, +0x81,0x55,0x36,0x92,0x49,0xed,0x9c,0xe9,0x72,0x24,0xc9,0x63,0x8a,0x62,0x9d,0xa4, +0x56,0x1b,0x2c,0xda,0x87,0x4e,0x79,0x10,0x9c,0x31,0x10,0xea,0xca,0x98,0x20,0x00, +0xa7,0x14,0xac,0xd4,0x92,0x92,0x81,0x5c,0x32,0x12,0x4a,0x25,0x98,0xe2,0x72,0x22, +0xc9,0x64,0x8e,0x22,0x99,0xdc,0x56,0x1c,0x28,0xd2,0x87,0x04,0x7c,0xca,0xa3,0x13, +0x9c,0x31,0x10,0x6c,0xca,0x97,0x20,0x00,0xb4,0x4a,0x8f,0x4c,0x84,0xb2,0x31,0x2c, +0x4e,0xf2,0x9a,0x75,0x74,0xf4,0xc8,0xd1,0x90,0xed,0x95,0x0d,0x52,0xea,0x2a,0x88, +0x8d,0x6a,0x7c,0x8d,0xa5,0x8d,0xb2,0x6d,0x9c,0x31,0x10,0xd6,0xc9,0x97,0x20,0x00, +0x8f,0xcd,0x7e,0x71,0x31,0x6d,0x53,0x36,0x9a,0x71,0x76,0xf0,0xc5,0x0d,0x92,0xcd, +0x91,0x28,0x52,0xae,0x2a,0x24,0x8b,0x8a,0x80,0x2c,0xa3,0xcd,0xb6,0x11,0x8b,0x8d, +0x9c,0x31,0x10,0x0f,0xc9,0x87,0x10,0x00,0x7c,0x8c,0x31,0x8d,0x55,0x79,0x9c,0x8e, +0x7b,0x2c,0xc2,0xe9,0x96,0xce,0x89,0x08,0x52,0xcd,0x2e,0x24,0x87,0xaa,0x8c,0x2c, +0x9b,0xb1,0xbc,0x4d,0x8b,0x4d,0x72,0xac,0x9c,0x31,0x10,0x98,0xc9,0x96,0x10,0x00, +0x35,0x72,0x53,0x74,0x9c,0xce,0x82,0xe9,0xbc,0xe9,0x9e,0xcd,0x83,0x0c,0x50,0xcd, +0x30,0x44,0x87,0x52,0x8c,0x71,0x9d,0x8d,0xba,0x69,0x8d,0x2e,0x6e,0xcc,0x35,0x11, +0x9c,0x31,0x10,0x17,0xc9,0x97,0x10,0x00,0x55,0x6c,0x9c,0xc6,0x84,0xe8,0xb8,0xed, +0xa2,0xd1,0x7f,0x0d,0x4e,0xed,0x36,0x65,0x87,0x11,0x92,0x71,0x9d,0x4d,0xb6,0xa9, +0x8d,0x0d,0x64,0xcd,0x37,0x11,0x5d,0x6d,0x9c,0x31,0x10,0x8a,0xc8,0x97,0x10,0x00, +0x9a,0xa9,0x8d,0x29,0xb2,0xd1,0xa4,0xcd,0x7b,0x2d,0x47,0x49,0x3a,0x71,0x8c,0xf4, +0x92,0x4e,0x9f,0x64,0xb2,0xad,0x8f,0x11,0x5e,0xad,0x36,0x8d,0x61,0xa5,0x9a,0xad, +0x9c,0x31,0x10,0x53,0xc8,0x87,0x20,0x00,0x91,0x35,0xae,0xb1,0xa2,0xc9,0x77,0x0c, +0x43,0x49,0x3e,0xd6,0x8d,0x14,0x94,0x69,0x9f,0x4a,0xb0,0xb5,0x8f,0x0d,0x5a,0xc9, +0x32,0x49,0x67,0x65,0x9c,0xb4,0x95,0x4d,0x9c,0x31,0x10,0x53,0xc8,0x87,0x20,0x00, +0xaa,0xc5,0xa2,0xed,0x75,0x0c,0x3d,0x4e,0x42,0xf5,0x8f,0x04,0x98,0xad,0x9f,0x31, +0xaa,0xed,0x8e,0xed,0x54,0xed,0x32,0x49,0x6f,0x52,0xa0,0x8c,0x97,0x49,0xa8,0xcd, +0x9c,0x31,0x10,0x3b,0xc7,0x87,0x20,0x00,0x9e,0xe1,0x6e,0xe1,0x37,0x1d,0x49,0x5d, +0x99,0x0d,0x9e,0xa4,0x9e,0xe1,0xa6,0xdd,0x89,0x14,0x4d,0x1d,0x30,0x20,0x7b,0x65, +0xa6,0x1a,0x9b,0x14,0xa2,0xa5,0x98,0xdd,0x9c,0x31,0x10,0xb3,0xc7,0x77,0x20,0x00, +0x66,0xd3,0x32,0x53,0x55,0x42,0xa0,0xb4,0xa3,0x1b,0x9c,0xcb,0x9e,0xe3,0x7c,0xdb, +0x43,0x1b,0x3b,0x2d,0x8c,0xc3,0xac,0x99,0x9c,0xeb,0x9a,0xcb,0x8e,0xdb,0x5b,0x23, +0x9c,0x31,0x10,0xb4,0xc7,0x86,0x20,0x00,0x32,0x5c,0x69,0x2a,0xaa,0x95,0xa8,0xd9, +0x96,0xe5,0x90,0x99,0x6e,0xd9,0x3c,0x5a,0x4f,0x58,0x9c,0xb0,0xb1,0x0e,0x9c,0xe1, +0x8c,0xe1,0x7c,0xd5,0x4e,0xe5,0x43,0x10,0x9c,0x31,0x10,0xd5,0xb6,0x77,0x20,0x00, +0x86,0xde,0xe1,0x2b,0xcc,0xca,0x9e,0xe3,0x80,0xdb,0x3f,0x63,0x04,0xe4,0x58,0xda, +0xcc,0x93,0xe0,0xeb,0xae,0xd4,0x82,0xdb,0x51,0x1b,0x12,0x21,0x3c,0xe4,0xb0,0x55, +0x9c,0x31,0x10,0xcd,0xb6,0x67,0x20,0x00,0xe3,0x2b,0xbe,0xd3,0x8a,0xe3,0x5c,0xca, +0x20,0x1d,0x2b,0x63,0x92,0xd2,0xdb,0x12,0xcc,0xeb,0x94,0xcc,0x60,0xe4,0x2e,0xe3, +0x29,0x40,0x7b,0x2d,0xcb,0x0b,0xd4,0xdd,0x9c,0x31,0x10,0xf8,0xb5,0x66,0x20,0x00, +0xa2,0xe9,0x6a,0xd3,0x3b,0xa8,0x27,0x55,0x68,0xd5,0xba,0xaa,0xd4,0xcb,0xaf,0x21, +0x77,0x1b,0x45,0x6c,0x28,0x94,0x58,0xe9,0xaa,0x54,0xd2,0xe3,0xb8,0xda,0x7e,0xdb, +0x9c,0x31,0x10,0x11,0xb5,0x56,0x10,0x00,0x4d,0x2c,0x2c,0x09,0x4c,0xf6,0x9a,0x51, +0xcd,0x13,0xbe,0xd3,0x88,0xe3,0x55,0x13,0x30,0x1b,0x47,0x14,0x8e,0x98,0xc5,0x1e, +0xc4,0xda,0x94,0xd4,0x5e,0xd9,0x38,0x9b,0x9c,0x31,0x10,0xa4,0xb4,0x66,0x10,0x00, +0x43,0x9a,0x80,0xdd,0xbb,0x1c,0xc5,0x12,0x9b,0x1b,0x67,0x1a,0x40,0xdc,0x41,0x5b, +0x77,0x1b,0xae,0x99,0xc3,0x63,0xa4,0xd5,0x6f,0x2b,0x45,0x0c,0x3c,0x69,0x6d,0x1b, +0x9c,0x31,0x10,0x11,0xb5,0x56,0x10,0x00,0xa6,0x92,0xc3,0x2d,0xac,0xc3,0x76,0xf3, +0x4c,0xc2,0x40,0xb2,0x65,0x4d,0x9c,0xa9,0xbb,0x0d,0xae,0xe2,0x7e,0xd4,0x52,0xe2, +0x44,0x9c,0x5f,0x51,0x90,0xad,0xb5,0x0b,0x9c,0x31,0x10,0x0d,0xa3,0x36,0x10,0x00, +0xe6,0x69,0x8d,0x12,0x32,0xa7,0x10,0x56,0x3a,0xac,0x9a,0x08,0xe4,0x64,0xde,0x54, +0x8b,0x68,0x39,0x69,0x21,0x56,0x46,0x16,0x97,0x68,0xd7,0x07,0xd0,0x67,0x89,0x57, +0x9c,0x31,0x10,0xa8,0xa2,0x35,0x00,0x00,0x41,0x73,0x2d,0x42,0x4e,0x54,0x8f,0x54, +0xc6,0x2b,0xc5,0xb1,0x8b,0x84,0x4f,0x4c,0x3c,0xac,0x57,0x49,0x8b,0x63,0xb6,0x94, +0xb6,0x6b,0x8a,0x8b,0x5a,0x62,0x4c,0xd3,0x9c,0x31,0x10,0xc2,0x92,0x33,0x00,0x00, +0x42,0x42,0x90,0x6c,0xca,0x63,0xcc,0xcc,0x8e,0xe4,0x4e,0xdc,0x3b,0x10,0x59,0x29, +0x8e,0xc4,0xb5,0x35,0xac,0x54,0x7e,0x6a,0x59,0x51,0x57,0x22,0x70,0xd4,0x8f,0x2d, +0x9c,0x31,0x10,0xe7,0x82,0x33,0x00,0x00,0xc0,0x82,0xae,0x69,0x7a,0xd3,0x5a,0xdd, +0x5f,0x1a,0x7b,0x29,0x95,0x1d,0x9f,0x1c,0x94,0x5b,0x74,0xd8,0x69,0x24,0x76,0xd2, +0x86,0xdb,0x8a,0xcc,0x86,0xf1,0x7c,0xd4,0x9c,0x31,0x10,0xc1,0x51,0x23,0x00,0x00, +0x08,0xb9,0x22,0x2c,0x9d,0xeb,0xcc,0x84,0xa1,0x53,0x86,0x41,0x81,0x2a,0x7c,0xbc, +0x66,0x34,0x90,0x52,0xa1,0x93,0x84,0xca,0x71,0xb3,0x8a,0xcc,0x89,0x33,0x76,0x31, +0x9c,0x31,0x10,0xe4,0x41,0x23,0x00,0x00,0x98,0xab,0xa5,0xbd,0x51,0x4a,0x6e,0xc2, +0xd1,0x1a,0xf7,0x25,0x94,0xac,0x75,0x5a,0xa4,0xbb,0x7f,0x53,0x3e,0xac,0x4a,0xab, +0x84,0x33,0x71,0xca,0x42,0x3c,0x5d,0xca,0x9c,0x31,0x10,0xd1,0x42,0x22,0x00,0x00, +0x65,0x9c,0x3d,0xa0,0x5a,0x16,0xa9,0x5b,0xeb,0x6b,0x8a,0x0b,0x8a,0x1c,0xcd,0x8b, +0x81,0xd9,0x12,0x1b,0x0a,0x23,0x62,0x14,0x89,0x5b,0x5d,0x94,0x25,0x6a,0x46,0x63, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_EIGHT.txt b/config/_default_cfg_src_/res/cn/SOUND_EIGHT.txt new file mode 100644 index 0000000..6582e8b --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_EIGHT.txt @@ -0,0 +1,110 @@ +0x9c,0x31,0x10,0xd8,0x43,0x31,0x00,0x00,0x7d,0xdd,0x7d,0xdd,0x7d,0xdd,0x75,0xdd, +0x6e,0x21,0x1d,0xd9,0x0d,0xda,0x46,0x5c,0x5d,0x9e,0xd5,0x2e,0xd1,0x9d,0xa5,0xa4, +0x7e,0x5d,0x1e,0x19,0x30,0xaa,0xba,0x14,0x9c,0x31,0x10,0x69,0xc7,0x65,0x10,0x00, +0x80,0x6d,0x80,0x6d,0x81,0x6d,0x81,0x6d,0x85,0x96,0x8d,0x4c,0x9c,0xc6,0x8f,0x70, +0x70,0x4d,0x65,0x6d,0x78,0x6c,0x7f,0x6a,0x7d,0x6d,0x7d,0x6c,0x56,0x92,0x26,0x70, +0x9c,0x31,0x10,0x54,0xcb,0x89,0x30,0x00,0x6a,0x23,0xc1,0x1c,0x81,0xda,0xda,0x1a, +0x66,0x1c,0x1e,0x13,0x6e,0x2b,0xc0,0x1c,0x5e,0x9a,0xe6,0x52,0x81,0xdc,0xb6,0x1c, +0x45,0xaa,0x10,0xd1,0xcb,0x55,0x4a,0x5c,0x9c,0x31,0x10,0x8b,0xcc,0x89,0x40,0x00, +0xca,0x11,0x8d,0x4c,0xa6,0x51,0x69,0x8e,0x05,0xf9,0x96,0xf4,0x74,0xf1,0x8e,0x0e, +0xb5,0x49,0x8a,0x65,0xa1,0xa5,0x1a,0x85,0x49,0x85,0xad,0x28,0x52,0x89,0xd6,0x09, +0x9c,0x31,0x10,0x3f,0xcc,0x89,0x50,0x00,0x7a,0x2d,0xbd,0xb5,0x51,0xd1,0x15,0x59, +0x9f,0x2d,0x65,0x50,0xa6,0x31,0x9d,0x0d,0xa6,0x69,0x8d,0x69,0x2a,0x85,0x3d,0xc5, +0xb1,0x08,0x52,0x88,0xd1,0xe9,0x7a,0x4e,0x9c,0x31,0x10,0x3f,0xcc,0x89,0x50,0x00, +0xbd,0xb1,0x56,0x31,0x11,0x16,0xa3,0x51,0x5d,0x50,0xae,0x31,0x95,0x2d,0xaa,0x6d, +0x89,0xc9,0x36,0x45,0x35,0xe5,0xb4,0xc9,0x4e,0xc9,0xd5,0xc9,0x7e,0x8d,0xb5,0x51, +0x9c,0x31,0x10,0x3f,0xcc,0x89,0x50,0x00,0x5e,0x71,0x08,0xf9,0xaf,0x91,0x55,0x50, +0xba,0x2d,0x8d,0x2d,0xb2,0x29,0x81,0xe5,0x36,0x01,0x36,0x2a,0xb4,0x8c,0x53,0x08, +0xd5,0x8d,0x7e,0xcd,0xb1,0x55,0x66,0x31,0x9c,0x31,0x10,0x21,0xdc,0x88,0x40,0x00, +0x3c,0xf6,0x9b,0x6d,0x65,0x70,0x9e,0x0d,0x85,0x4e,0x95,0xee,0x7e,0x09,0x55,0xe0, +0x62,0x6e,0x94,0x48,0x6f,0x08,0xa5,0x49,0x82,0xee,0x91,0x71,0x72,0x55,0x3c,0xf5, +0x9c,0x31,0x10,0x38,0xcc,0x78,0x50,0x00,0xc7,0x2e,0x3d,0xf1,0xd1,0xd1,0x81,0x6a, +0xb5,0x8c,0x7e,0x65,0x25,0xe3,0x56,0xd5,0x98,0x0b,0x6f,0x01,0xc1,0x22,0x8a,0xca, +0xa1,0x8c,0x5e,0x4c,0x01,0x2b,0xca,0xa5,0x9c,0x31,0x10,0xa2,0xcd,0x89,0x50,0x00, +0x3a,0x0d,0xd9,0xd1,0x7d,0xed,0xb1,0xad,0x82,0x29,0x19,0xcd,0x6e,0x75,0x88,0xee, +0x82,0x69,0xb5,0x89,0x96,0x49,0x95,0xc9,0x62,0x09,0x05,0x81,0xca,0x0a,0x3a,0x6e, +0x9c,0x31,0x10,0xa8,0xcc,0x98,0x50,0x00,0xdd,0x70,0x7a,0x2c,0xad,0x4c,0x7a,0x71, +0x0d,0x71,0x8b,0x71,0x68,0x12,0x9e,0x6d,0xa1,0x6d,0xa2,0x4d,0x8e,0x09,0x56,0x09, +0x15,0x64,0xc1,0x68,0x47,0x4a,0xd5,0x6e,0x9c,0x31,0x10,0xa8,0xcc,0x98,0x50,0x00, +0x82,0x6d,0xa5,0x51,0x7a,0x51,0x05,0x55,0x9b,0x90,0x5c,0xb1,0xae,0x0d,0x99,0x8d, +0xa6,0x0d,0x8a,0x49,0x41,0xc9,0x2d,0xc9,0xb0,0xac,0x57,0x69,0xcd,0x6d,0x8e,0x8d, +0x9c,0x31,0x10,0x8c,0xcc,0x78,0x40,0x00,0x9d,0x53,0x72,0x54,0x01,0x34,0xb3,0x4b, +0x4d,0xb1,0xc1,0x93,0x8e,0x0c,0xa9,0x8b,0x8a,0x6a,0x29,0xaa,0x5e,0xb4,0x70,0x2c, +0x8e,0xa3,0xa9,0xe3,0xa6,0x03,0x9e,0x22,0x9c,0x31,0x10,0x04,0xcc,0x88,0x40,0x00, +0x6d,0xa9,0x11,0xa4,0x8e,0x09,0x53,0x0e,0xc1,0x2d,0x9e,0x2d,0xa9,0xb1,0x9a,0x31, +0x11,0xb5,0x6a,0xf4,0x54,0xd1,0xa1,0xf2,0xaa,0x0d,0xad,0xcd,0xa6,0x29,0x55,0xa9, +0x9c,0x31,0x10,0x04,0xcc,0x88,0x40,0x00,0x19,0xc5,0x7d,0x28,0x67,0x29,0xbd,0x6d, +0xa6,0x2d,0xa9,0xd1,0x8d,0xf1,0x05,0xb6,0x76,0xf1,0x4d,0xd0,0xb5,0x51,0xa6,0x0d, +0xad,0xad,0xa2,0x4d,0x35,0xc9,0x3a,0x6e,0x9c,0x31,0x10,0x36,0xcc,0x87,0x50,0x00, +0x64,0x6e,0x82,0xc8,0xb5,0xec,0xae,0x0d,0xa5,0xed,0x79,0xcd,0x05,0x89,0x7e,0x6a, +0x52,0xae,0xbd,0x4d,0xa6,0x0d,0xad,0xad,0x9a,0x31,0x19,0xd4,0x56,0xd8,0x58,0xb2, +0x9c,0x31,0x10,0xb0,0xcc,0x88,0x50,0x00,0x9d,0xf2,0xb2,0x0d,0xb2,0x0d,0xa2,0x2d, +0x59,0xc9,0x19,0xc5,0x75,0x48,0x67,0x09,0xc1,0xad,0xa6,0x0e,0xa9,0xb2,0x89,0xf1, +0x0d,0xb1,0x6e,0xd1,0x51,0xb0,0xb1,0x6d,0x9c,0x31,0x10,0x38,0xcc,0x78,0x50,0x00, +0xaa,0x0b,0xb1,0xeb,0x9e,0x2c,0x39,0xc3,0x36,0x4d,0x68,0xab,0x7e,0xa9,0xb9,0xe1, +0xaa,0x0b,0xa5,0xcb,0x71,0xeb,0x11,0xa2,0x76,0x24,0x56,0xad,0xbd,0x6c,0xa5,0xeb, +0x9c,0x31,0x10,0xcc,0xcb,0x78,0x50,0x00,0xae,0xab,0x95,0x12,0x22,0xd2,0x57,0xb1, +0x5a,0x13,0x9e,0xec,0xb2,0xed,0xb1,0x0c,0x9f,0x04,0x54,0xc4,0x22,0xe3,0x72,0x28, +0x6d,0xc9,0xbe,0xaa,0xad,0x0c,0xaa,0xb5,0x9c,0x31,0x10,0x38,0xcc,0x78,0x50,0x00, +0x82,0x0c,0x15,0xb4,0x6a,0xab,0x55,0xc9,0xb1,0x8a,0xaa,0x0b,0xb1,0xcb,0x9a,0x2b, +0x35,0xcb,0x3e,0x54,0x64,0xcd,0x86,0x6b,0xb5,0xe2,0xae,0x2a,0xa1,0xea,0x69,0xeb, +0x9c,0x31,0x10,0xcc,0xcb,0x78,0x50,0x00,0x18,0xa2,0x74,0xe3,0x5f,0x8c,0xbe,0x8c, +0xa8,0xec,0xae,0xd3,0x8d,0x13,0x20,0xb3,0x59,0x91,0x5a,0x4a,0xa2,0xeb,0xae,0xec, +0xb0,0xe4,0x9f,0x0c,0x4e,0xc4,0x2b,0x04,0x9c,0x31,0x10,0xcc,0xcb,0x78,0x50,0x00, +0x6e,0x4a,0x73,0xaa,0xbc,0xaa,0xab,0x0b,0xa8,0xd3,0x7c,0xeb,0x1c,0xb4,0x6b,0x6d, +0x59,0x0b,0xb2,0xaa,0xa8,0xea,0xb0,0xca,0x95,0x13,0x36,0xca,0x47,0x72,0x62,0x0c, +0x9c,0x31,0x10,0xfe,0xcb,0x77,0x40,0x00,0x8d,0x36,0xb2,0xf2,0xab,0x25,0xa3,0x01, +0x64,0xf5,0x24,0xc0,0x72,0xd0,0x65,0xa5,0xb8,0xb6,0xa7,0x06,0xaa,0xd6,0x87,0x05, +0x28,0xc9,0x5f,0xa8,0x5c,0xa4,0xa2,0xc5,0x9c,0x31,0x10,0xfe,0xcb,0x77,0x40,0x00, +0xaa,0xe5,0xae,0xe5,0x99,0x25,0x4a,0xe5,0x3d,0x16,0x6a,0x25,0x7d,0x85,0xb4,0xe1, +0xab,0x15,0xa2,0xd5,0x72,0xf4,0x26,0xc0,0x6d,0x42,0x61,0x56,0xb0,0xba,0xa7,0x09, +0x9c,0x31,0x10,0xfe,0xcb,0x77,0x40,0x00,0xac,0xe9,0x8b,0x19,0x36,0xc9,0x55,0x88, +0x60,0x54,0x98,0xf5,0xaa,0xe6,0xaf,0x06,0x99,0x05,0x58,0xd1,0x39,0x02,0x6a,0x75, +0x77,0x84,0xb0,0xc4,0xab,0x15,0xa2,0xd5,0x9c,0x31,0x10,0xfe,0xcb,0x77,0x40,0x00, +0x77,0x05,0x2e,0xc5,0x67,0x36,0x63,0x36,0xaa,0xc5,0xa7,0x09,0xaa,0xd9,0x8b,0x19, +0x40,0xd9,0x55,0x68,0x62,0x65,0x94,0xf5,0xaa,0xf5,0xad,0x05,0x97,0x05,0x5a,0xe5, +0x9c,0x31,0x10,0x63,0xca,0x77,0x40,0x00,0x3c,0xe6,0x6a,0x14,0x79,0xe4,0xae,0xc5, +0xa9,0x25,0xa0,0xd5,0x75,0x15,0x34,0x95,0x69,0x56,0x67,0x66,0xa8,0xa5,0xa5,0x05, +0xa8,0xc5,0x85,0x45,0x42,0xc9,0x57,0xa8,0x9c,0x31,0x10,0x7b,0xca,0x67,0x40,0x00, +0x64,0x19,0x94,0xe5,0xa7,0x05,0xa9,0x15,0x95,0x05,0x58,0xd5,0x45,0x02,0x68,0x15, +0x7d,0xc1,0xa8,0xc5,0xa9,0x21,0x9e,0xd1,0x72,0xf5,0x3c,0xb5,0x65,0x72,0x6b,0x45, +0x9c,0x31,0x10,0x17,0xba,0x76,0x40,0x00,0xc9,0x0d,0xca,0x10,0xc9,0xd0,0x82,0x8c, +0x0d,0x95,0x37,0x34,0x4c,0xd1,0xad,0xd1,0xc9,0xf2,0xd2,0x11,0x9e,0x31,0x31,0x8c, +0x1a,0x6e,0x4c,0x6e,0x8a,0xe9,0xc9,0xc8,0x9c,0x31,0x10,0x24,0xba,0x66,0x30,0x00, +0xd5,0xc8,0xb1,0x88,0x56,0x09,0x05,0xa1,0x4d,0xc5,0x6b,0x2a,0xc9,0x4d,0xce,0x0d, +0xc1,0x8a,0x76,0x4d,0x09,0xb9,0x3e,0xf4,0x55,0x91,0xb5,0xb5,0xca,0x11,0xd1,0xf1, +0x9c,0x31,0x10,0x24,0xba,0x66,0x30,0x00,0x8e,0x51,0x25,0x89,0x22,0xb1,0x50,0x4d, +0x9a,0x89,0xca,0x29,0xd2,0x31,0x9d,0xd1,0x45,0x8d,0x0e,0x00,0x51,0x49,0x77,0x09, +0xc9,0x89,0xce,0x09,0xb1,0x4d,0x6a,0x4d,0x9c,0x31,0x10,0x9e,0xb9,0x66,0x30,0x00, +0x09,0x64,0x4b,0x1b,0x5a,0x1a,0xc0,0x9a,0xca,0x53,0xc1,0x14,0x7f,0x13,0x1d,0x24, +0x37,0xa9,0x54,0x5b,0xa9,0xdc,0xc5,0xdc,0xcd,0xdb,0x8e,0xdb,0x35,0x53,0x22,0x5d, +0x9c,0x31,0x10,0x0c,0xba,0x56,0x30,0x00,0x54,0xea,0x8a,0xa9,0xc5,0xaa,0xce,0x52, +0xa1,0xb4,0x51,0xd4,0x15,0xcb,0x4d,0xcb,0x72,0x6c,0xc1,0xa4,0xca,0x2b,0xb5,0x6b, +0x6a,0x4b,0x21,0xcb,0x42,0x4a,0x65,0xaa,0x9c,0x31,0x10,0x3a,0xb9,0x55,0x30,0x00, +0xb2,0xe5,0xc6,0xf1,0xbe,0xb1,0x79,0x45,0x2f,0x15,0x37,0x36,0x60,0x26,0xa1,0x75, +0xc6,0xe5,0xc6,0xf1,0x89,0x11,0x42,0xf5,0x2b,0x05,0x5a,0xb4,0x8f,0x54,0xc2,0xa5, +0x9c,0x31,0x10,0x45,0xb8,0x44,0x10,0x00,0xc9,0x75,0x97,0x49,0x54,0xe9,0x2a,0x95, +0x55,0x35,0x80,0xe5,0xc0,0xb5,0xc2,0xf5,0x9b,0x55,0x5f,0x55,0x2a,0x38,0x57,0x54, +0x76,0x86,0xbb,0x01,0xc4,0xe1,0xa1,0x15,0x9c,0x31,0x10,0x19,0xb9,0x44,0x20,0x00, +0x6b,0x51,0x32,0x94,0x4b,0x28,0x76,0x92,0xad,0x22,0xc6,0xe2,0xa1,0x36,0x6d,0x14, +0x3c,0xa4,0x4d,0x24,0x78,0x85,0xab,0x75,0xbc,0xd6,0x9a,0xda,0x6b,0x59,0x42,0xa4, +0x9c,0x31,0x10,0xa1,0xa8,0x44,0x20,0x00,0x2d,0x15,0x84,0x65,0xcf,0x66,0xe9,0x15, +0x9a,0xf9,0x4d,0x0a,0x12,0x69,0x45,0x85,0x8e,0x75,0xd7,0x04,0xd2,0xf4,0x8b,0x14, +0x47,0x34,0x20,0xa5,0x5d,0x26,0x94,0xd6,0x9c,0x31,0x10,0xe3,0xa6,0x33,0x00,0x00, +0xd0,0x66,0xbc,0xa1,0x7f,0x85,0x4a,0x64,0x31,0x81,0x6b,0x25,0x9c,0xc5,0xc4,0x75, +0xa7,0x41,0x77,0x71,0x49,0x71,0x43,0xd1,0x74,0x01,0xa4,0x95,0xb9,0xc1,0x9b,0x85, +0x9c,0x31,0x10,0x38,0x96,0x33,0x10,0x00,0x5e,0x34,0x1e,0x20,0x21,0xb1,0x76,0xc2, +0xc9,0x06,0xe3,0x35,0xa3,0x06,0x58,0xd5,0x1e,0xb5,0x3b,0x35,0x87,0x49,0xca,0xc9, +0xd1,0x39,0x8e,0xb9,0x58,0xf9,0x2c,0xa5,0x9c,0x31,0x10,0x2e,0x95,0x23,0x00,0x00, +0x4e,0xd1,0x89,0x91,0xbe,0xb1,0xbf,0x4d,0x86,0x05,0x5d,0xc6,0x3a,0x6d,0x5b,0x6c, +0x88,0xb5,0xb7,0x55,0xa8,0x95,0x8b,0x4d,0x58,0x92,0x51,0x4d,0x67,0x4d,0x8a,0x4d, +0x9c,0x31,0x10,0x84,0x85,0x22,0x00,0x00,0xd5,0x94,0xc4,0xad,0x88,0xc5,0x4e,0xad, +0x32,0xe8,0x56,0xe5,0x95,0x0d,0xb9,0x6d,0xb6,0xcd,0x8e,0x85,0x5d,0x0d,0x53,0x0d, +0x63,0x11,0x8d,0x0d,0xa9,0x10,0xa8,0xed,0x9c,0x31,0x10,0x6f,0x65,0x22,0x00,0x00, +0xbd,0xeb,0x41,0x63,0x0d,0xea,0x2a,0x13,0xa6,0x23,0xdd,0xdc,0xe6,0x23,0x9d,0xe4, +0x58,0xe4,0x2a,0x1d,0x46,0xe2,0x7a,0x9b,0xc8,0x1a,0xbd,0x93,0xa5,0x52,0x6b,0x12, +0x9c,0x31,0x10,0xf2,0x64,0x22,0x00,0x00,0x3a,0x1c,0x59,0xeb,0x58,0x63,0xad,0x92, +0xa0,0xd2,0xaa,0x94,0x83,0x9a,0x61,0xe5,0x59,0xa3,0x75,0x5a,0x9c,0x92,0xc5,0x94, +0xbf,0x15,0xbe,0xdb,0xa0,0xdb,0x9c,0xda,0x9c,0x31,0x10,0x7e,0x64,0x21,0x00,0x00, +0x8d,0x0d,0x84,0xac,0x87,0x6d,0x87,0x51,0x85,0x6d,0x70,0xb6,0x70,0x8d,0x5e,0x49, +0x4a,0x8c,0x3f,0xa5,0x4b,0x4d,0x4b,0x0a,0x50,0x8d,0x33,0x4d,0x2d,0x15,0x27,0x4c, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_FINDME.txt b/config/_default_cfg_src_/res/cn/SOUND_FINDME.txt new file mode 100644 index 0000000..ce3fa72 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_FINDME.txt @@ -0,0 +1,645 @@ +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0xa3,0xbd,0xdd,0x99,0x78,0x77,0x77,0x77,0x77,0x87,0x77,0x87,0x87, +0xe8,0x87,0x4c,0x69,0x8a,0x14,0x79,0x6c,0x77,0x81,0x77,0x4c,0x77,0xa2,0x77,0x3c, +0x77,0xb3,0x77,0x2b,0x77,0xc4,0x77,0x1a,0x9c,0x31,0x10,0x29,0x43,0xdd,0x46,0x43, +0x7c,0xa8,0x02,0x4d,0x7d,0x36,0x21,0xc1,0x5d,0x3c,0x42,0x3a,0x3c,0xc5,0x63,0x30, +0x1b,0xd1,0x84,0xaa,0x39,0xd5,0x46,0xa1,0x77,0xde,0x29,0x1d,0x75,0x60,0x0b,0x99, +0x9c,0x31,0x10,0xe0,0x43,0xdd,0x45,0x42,0x89,0x32,0x47,0x4c,0x47,0xf2,0x78,0x8c, +0x26,0x72,0x89,0xcd,0x35,0x70,0x7b,0x0f,0x54,0x2d,0x2b,0xd2,0x73,0x6a,0x2c,0x95, +0x82,0xe7,0x3d,0x19,0x52,0xa3,0x5d,0x1d,0x9c,0x31,0x10,0x6f,0x43,0xdc,0x45,0x42, +0x32,0x9f,0x8d,0x23,0x22,0xd8,0x8c,0xaa,0x43,0x51,0x5c,0x30,0x54,0x0b,0x3b,0x76, +0x74,0xc6,0x2a,0x79,0x75,0xc3,0x49,0x7c,0x46,0xc1,0x68,0x7d,0x37,0xc1,0x87,0x7c, +0x9c,0x31,0x10,0x59,0x43,0xdc,0x35,0x43,0x28,0xc2,0x66,0x7a,0x59,0xc5,0x35,0x77, +0x7a,0x89,0x24,0xb3,0x7b,0x4e,0x34,0x2d,0x6b,0x93,0x53,0xe8,0x4b,0xd9,0x73,0xe2, +0x3b,0xdf,0x63,0xdc,0x4b,0xe5,0x44,0x16,0x9c,0x31,0x10,0x5c,0x43,0xcc,0x35,0x42, +0x6e,0xea,0x21,0x51,0x7d,0xef,0x32,0x8d,0x6c,0x72,0x44,0x0a,0x4a,0xf5,0x75,0x89, +0x29,0x76,0x67,0x08,0x37,0xb6,0x58,0xc8,0x56,0x36,0x4a,0x49,0x74,0xb4,0x3b,0xcc, +0x9c,0x31,0x10,0xb1,0x43,0xcc,0x25,0x32,0x73,0x71,0x5c,0xcf,0x42,0x6d,0x6d,0xd3, +0x31,0xa9,0x6e,0x98,0x31,0x24,0x5e,0xdd,0x50,0xdf,0x3e,0xa2,0x71,0x1a,0x3e,0x66, +0x61,0x95,0x5d,0xab,0x52,0x91,0x6c,0xaf,0x9c,0x31,0x10,0x98,0x42,0xcc,0x35,0x32, +0x33,0x8e,0x7b,0x72,0x34,0xcb,0x6a,0x33,0x56,0x4a,0x48,0xb5,0x77,0xc9,0x47,0x34, +0x79,0x4a,0x45,0xb3,0x5a,0xcc,0x64,0x71,0x3b,0xce,0x63,0x2e,0x4d,0x12,0x62,0x6a, +0x9c,0x31,0x10,0x2c,0x42,0xcc,0x25,0x32,0x4d,0x96,0x51,0xe6,0x7e,0x1a,0x41,0x61, +0x7e,0x5f,0x31,0x9d,0x6e,0x23,0x51,0xd8,0x4d,0xa8,0x62,0x94,0x3c,0xac,0x63,0x91, +0x4b,0xaf,0x54,0x8e,0x5a,0xb1,0x45,0xcc,0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32, +0x79,0x32,0x37,0x0b,0x67,0xf3,0x38,0x8b,0x66,0x72,0x59,0xcd,0x55,0x31,0x5b,0x0f, +0x44,0x2e,0x6c,0x11,0x33,0x2b,0x6d,0x15,0x32,0x67,0x6d,0x99,0x42,0x23,0x3d,0x9d, +0x9c,0x31,0x10,0x49,0x43,0xcc,0x34,0x32,0x61,0xdf,0x3d,0xa1,0x62,0x1b,0x3d,0x65, +0x62,0x97,0x4c,0xa9,0x53,0x53,0x5b,0xec,0x54,0x50,0x5a,0xef,0x45,0x8e,0x69,0xb0, +0x36,0xcd,0x68,0x71,0x38,0x0d,0x77,0x31,0x9c,0x31,0x10,0x49,0x43,0xcc,0x34,0x32, +0x39,0x4e,0x65,0xf0,0x4a,0x4f,0x54,0xae,0x4b,0x92,0x53,0xeb,0x5c,0x55,0x43,0x28, +0x5c,0xd8,0x32,0xa4,0x5d,0x1c,0x32,0x60,0x6d,0x60,0x32,0x9c,0x6d,0x24,0x32,0xd8, +0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32,0x6c,0xa7,0x33,0x95,0x6b,0xea,0x44,0x52, +0x5a,0xed,0x55,0x50,0x49,0xef,0x56,0x8f,0x38,0xb0,0x67,0x8e,0x37,0x70,0x68,0xce, +0x46,0x6f,0x5a,0x0f,0x45,0x2e,0x5b,0x11,0x9c,0x31,0x10,0xa5,0x32,0xcb,0x34,0x32, +0x48,0x6c,0x18,0x11,0x46,0x65,0x19,0x9d,0x45,0x54,0x3a,0xad,0x04,0x45,0x5b,0x3c, +0x04,0x34,0x3b,0x4d,0x04,0x25,0x3a,0xdc,0x45,0x95,0x19,0x6e,0x47,0x04,0x17,0x79, +0x9c,0x31,0x10,0x05,0x43,0xcc,0x35,0x32,0x54,0x8e,0x4a,0x71,0x45,0xcd,0x69,0x32, +0x47,0x0c,0x67,0xf3,0x38,0x8c,0x66,0x72,0x39,0xcd,0x55,0x30,0x5b,0x0f,0x44,0x2e, +0x6c,0x12,0x23,0x2b,0x6c,0xd5,0x32,0xa7,0x9c,0x31,0x10,0x49,0x43,0xcc,0x34,0x32, +0x6d,0x59,0x42,0x23,0x5d,0x9d,0x42,0x1f,0x4d,0xa1,0x62,0x5b,0x4d,0x65,0x62,0xd7, +0x4c,0xa9,0x63,0x93,0x3b,0xec,0x64,0x51,0x4a,0xae,0x65,0x8f,0x49,0xb0,0x56,0xcd, +0x9c,0x31,0x10,0x49,0x43,0xcc,0x34,0x32,0x58,0x71,0x48,0x0d,0x57,0x31,0x49,0x4e, +0x65,0xef,0x3a,0x4f,0x64,0xee,0x3b,0x92,0x63,0xeb,0x3c,0x55,0x63,0x28,0x3c,0xd8, +0x52,0xa4,0x4d,0x1c,0x52,0xa0,0x4d,0x20,0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32, +0x42,0x9c,0x5c,0xe4,0x33,0x19,0x6c,0x67,0x33,0x95,0x6b,0xaa,0x24,0x52,0x6a,0xed, +0x35,0x50,0x59,0xee,0x46,0x8f,0x58,0xaf,0x57,0x8f,0x47,0x6f,0x68,0xcf,0x36,0x6e, +0x9c,0x31,0x10,0x5e,0x42,0xcb,0x34,0x32,0x73,0x82,0x2a,0xf5,0x55,0x88,0x48,0xed, +0x57,0x15,0x47,0x60,0x38,0xa1,0x46,0xd6,0x39,0x2c,0x66,0x45,0x39,0xba,0x45,0xb9, +0x59,0x48,0x26,0x2e,0x58,0xd6,0x27,0x1c,0x9c,0x31,0x10,0xa2,0x42,0xbb,0x24,0x32, +0x6f,0x61,0x30,0x96,0x5d,0xe8,0x42,0x0c,0x4c,0x71,0x54,0x05,0x3a,0x74,0x46,0x01, +0x48,0x7a,0x48,0x01,0x56,0x78,0x3a,0x06,0x74,0x75,0x3c,0x08,0x52,0xed,0x5d,0x92, +0x9c,0x31,0x10,0xdc,0x32,0xcb,0x24,0x22,0x08,0xe5,0x57,0x18,0x07,0xda,0x38,0x26, +0x27,0x4c,0x18,0xb0,0x46,0xc2,0x38,0xbd,0x26,0xb4,0x58,0x49,0x07,0x2a,0x57,0xd5, +0x28,0x1c,0x16,0xe1,0x29,0x96,0x15,0x69,0x9c,0x31,0x10,0xed,0x32,0xbb,0x34,0x32, +0x26,0x0c,0x37,0x6d,0x09,0x8a,0x53,0xf0,0x2d,0x08,0x10,0x76,0x50,0x86,0x0c,0xf1, +0x14,0x89,0x49,0x6e,0x17,0x8e,0x26,0x69,0x3a,0x95,0x23,0xe1,0x3c,0x9e,0x41,0xd9, +0x9c,0x31,0x10,0x11,0x32,0xcb,0x24,0x32,0x17,0x24,0x47,0xcd,0x17,0xb2,0x07,0xc4, +0x57,0xbc,0x07,0xb9,0x37,0xc9,0x28,0x2c,0x17,0x50,0x28,0xa1,0x36,0x5d,0x09,0x98, +0x54,0xe5,0x0b,0x16,0x33,0x69,0x2c,0x8d,0x9c,0x31,0x10,0xb3,0x32,0xbb,0x24,0x21, +0x13,0xed,0x4d,0x0e,0x30,0xed,0x10,0x8d,0x4d,0x6e,0x13,0x8e,0x4a,0x68,0x16,0x91, +0x07,0x66,0x59,0x99,0x04,0xdc,0x5b,0xa1,0x02,0xd5,0x3d,0x28,0x41,0x4d,0x1e,0x36, +0x9c,0x31,0x10,0x48,0x42,0xbb,0x24,0x21,0x50,0x41,0x4f,0x3c,0x50,0xba,0x5e,0xc9, +0x40,0xac,0x6e,0x51,0x31,0xa6,0x5d,0x59,0x42,0x9d,0x5c,0x62,0x53,0x95,0x4a,0xe9, +0x65,0x12,0x49,0x69,0x57,0x0c,0x57,0xed,0x9c,0x31,0x10,0xfb,0x32,0xcb,0x24,0x21, +0x30,0x8e,0x0d,0xe9,0x32,0x11,0x0c,0x69,0x34,0x15,0x4a,0xe1,0x15,0x1d,0x49,0x59, +0x16,0x25,0x08,0xd1,0x57,0x2c,0x08,0x45,0x37,0xba,0x27,0xbd,0x17,0xc4,0x28,0x31, +0x9c,0x31,0x10,0xc4,0x31,0xbb,0x24,0x31,0x3e,0xce,0x01,0x25,0x3d,0x58,0x03,0x1e, +0x3a,0xe1,0x25,0x95,0x18,0x65,0x48,0x92,0x35,0x6d,0x2c,0x0c,0x51,0xed,0x0f,0x0e, +0x4e,0x6d,0x12,0x8c,0x0b,0x6d,0x55,0x91,0x9c,0x31,0x10,0x48,0x42,0xbb,0x24,0x21, +0x44,0x64,0x6c,0x15,0x42,0xe2,0x5d,0x1d,0x61,0xd8,0x4e,0x25,0x50,0xd1,0x4e,0xb0, +0x50,0xc5,0x5f,0x3a,0x40,0x39,0x6e,0xc5,0x30,0xb2,0x5e,0x4d,0x41,0x29,0x5d,0xd9, +0x9c,0x31,0x10,0x6d,0x32,0xbb,0x23,0x22,0x29,0x27,0x36,0x77,0x49,0xc6,0x0d,0xb9, +0x4a,0x85,0x0c,0xfa,0x4b,0x44,0x0c,0x3a,0x2c,0x04,0x0b,0x7a,0x34,0xe4,0x2a,0x99, +0x35,0x85,0x21,0xf8,0x2e,0x27,0x21,0x76,0x9c,0x31,0x10,0xbd,0x33,0xbb,0x34,0x22, +0x3a,0xa5,0x43,0xd0,0x3c,0x2e,0x42,0xc9,0x1d,0x34,0x22,0x41,0x1d,0x41,0x42,0x34, +0x1c,0xc9,0x43,0x2d,0x1b,0x51,0x24,0xa6,0x39,0xd9,0x27,0x1d,0x17,0x62,0x29,0x98, +0x9c,0x31,0x10,0x79,0x7a,0xed,0xaa,0x98,0x5b,0xc5,0x5b,0xa5,0x5b,0xc5,0x5b,0xa5, +0x5b,0xc5,0x5b,0xa5,0x5b,0xba,0x13,0xb0,0xaa,0x51,0x25,0x95,0x59,0xd5,0x5d,0xa5, +0x59,0xc5,0x5d,0xb5,0x59,0xb5,0x5d,0xb5,0x9c,0x31,0x10,0x9f,0x43,0xed,0x46,0x54, +0x26,0xae,0xb8,0x50,0x07,0xa1,0x97,0x5e,0x29,0x19,0x75,0xe4,0x4a,0x92,0x33,0xed, +0x6c,0x8c,0x11,0xf1,0x4e,0x8a,0x30,0x70,0x30,0x08,0x6e,0x72,0x12,0x0d,0x8c,0x6c, +0x9c,0x31,0x10,0x30,0x43,0xdd,0x45,0x53,0x0c,0x09,0x83,0x33,0x4d,0x4d,0x41,0xef, +0x6e,0x52,0x20,0xea,0x7e,0xd7,0x30,0xa4,0x6f,0x5c,0x60,0x9f,0x2f,0x22,0x70,0xda, +0x2e,0xa7,0x71,0x95,0x3d,0xab,0x52,0x91,0x9c,0x31,0x10,0x29,0x43,0xdd,0x46,0x43, +0x79,0x5c,0x07,0x99,0x76,0xe1,0x0a,0x14,0x73,0xe4,0x2d,0x16,0x50,0xe5,0x70,0x14, +0x2d,0xe5,0x93,0x16,0x0a,0xe1,0x75,0x99,0x28,0x5e,0x38,0x21,0x66,0xd9,0x19,0xa5, +0x9c,0x31,0x10,0xd6,0x43,0xdd,0x35,0x43,0x82,0xa8,0x3d,0x58,0x62,0x24,0x5d,0x9c, +0x32,0x20,0x7d,0xa0,0x12,0x5c,0x7d,0x64,0x32,0x98,0x5c,0xa8,0x53,0x55,0x4b,0xeb, +0x64,0x52,0x3a,0xed,0x75,0x50,0x39,0xef,0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43, +0x56,0x8f,0x68,0xb0,0x27,0xce,0x87,0x6f,0x38,0xcf,0x66,0x6e,0x59,0xd0,0x45,0x6d, +0x6a,0xd2,0x44,0xaa,0x7b,0x95,0x33,0xe8,0x6c,0x18,0x53,0xa4,0x3c,0x5b,0x63,0x61, +0x9c,0x31,0x10,0x44,0x43,0xdc,0x35,0x42,0x3c,0x5e,0x63,0x5d,0x4c,0x64,0x53,0x96, +0x6b,0xeb,0x34,0x11,0x7b,0x70,0x34,0x8b,0x6a,0xf5,0x45,0x47,0x5a,0x39,0x56,0x04, +0x39,0x3c,0x66,0xc1,0x38,0x7e,0x57,0xc0,0x9c,0x31,0x10,0x6f,0x43,0xdc,0x45,0x42, +0x47,0x7e,0x58,0xc0,0x56,0x7e,0x4a,0x01,0x65,0x3b,0x2b,0x04,0x74,0x38,0x3b,0xc9, +0x53,0x73,0x5c,0x8f,0x32,0xac,0x8d,0x55,0x22,0x65,0x7d,0x9d,0x32,0x1d,0x5d,0xa5, +0x9c,0x31,0x10,0xd6,0x43,0xdd,0x35,0x43,0x52,0x5a,0x3d,0x26,0x72,0xd6,0x3c,0x69, +0x63,0xd3,0x4b,0xac,0x54,0x91,0x5a,0x6e,0x45,0xcf,0x79,0x6f,0x27,0x0e,0x68,0x30, +0x48,0x0e,0x46,0xef,0x79,0x4f,0x25,0xee,0x9c,0x31,0x10,0x44,0x43,0xdc,0x35,0x42, +0x7a,0x43,0x34,0xf9,0x6b,0x07,0x54,0x34,0x5b,0xcd,0x63,0xae,0x3c,0x13,0x73,0x67, +0x3c,0x5a,0x43,0x61,0x6c,0x61,0x33,0x5a,0x7c,0x27,0x33,0xd4,0x7b,0xad,0x54,0x4e, +0x9c,0x31,0x10,0xdc,0x42,0xcc,0x35,0x43,0x5e,0x72,0x62,0x0a,0x3c,0xf6,0x63,0xc7, +0x3a,0xf9,0x55,0x85,0x59,0x3a,0x47,0x84,0x77,0x3a,0x29,0x45,0x75,0x78,0x4b,0x07, +0x53,0xb6,0x5c,0xca,0x42,0x72,0x6e,0x0e,0x9c,0x31,0x10,0xc1,0x42,0xcc,0x35,0x42, +0x31,0x2d,0x6e,0xd3,0x40,0x68,0x4f,0x99,0x70,0x23,0x2f,0x9e,0x70,0x1d,0x4f,0x64, +0x50,0x97,0x6e,0xa9,0x31,0x52,0x7d,0xee,0x32,0x8e,0x5c,0xb2,0x53,0xcb,0x4b,0x34, +0x9c,0x31,0x10,0x8d,0x42,0xcc,0x34,0x42,0x65,0x49,0x39,0x76,0x67,0x08,0x47,0xf6, +0x58,0xc8,0x56,0x35,0x4a,0x4a,0x64,0xb3,0x4b,0xcc,0x63,0x30,0x4d,0x10,0x52,0x2c, +0x6d,0xd4,0x31,0x68,0x7e,0x99,0x31,0x23,0x9c,0x31,0x10,0x77,0x43,0xcc,0x45,0x42, +0x7e,0xde,0x31,0x1e,0x7e,0xa3,0x41,0x59,0x5e,0x28,0x52,0x14,0x4d,0x2c,0x63,0x10, +0x4c,0x2f,0x64,0x4d,0x4a,0xf2,0x55,0x8b,0x59,0x73,0x47,0x0a,0x67,0xf4,0x28,0x8b, +0x9c,0x31,0x10,0x3f,0x44,0xcc,0x54,0x33,0x6b,0x39,0x2d,0x06,0x6a,0x78,0x2d,0xa7, +0x49,0xd7,0x4e,0x28,0x41,0x75,0x4e,0xaa,0x29,0x13,0x6e,0xec,0x28,0xf1,0x6f,0x0f, +0x28,0xce,0x6e,0xf1,0x21,0x0c,0x46,0xd3,0x9c,0x31,0x10,0x41,0x7a,0xee,0xba,0x98, +0x56,0x65,0x58,0x85,0x55,0x55,0x1b,0xb2,0x84,0x45,0x1a,0xb5,0x55,0x35,0x58,0xb5, +0x56,0x35,0x57,0xb5,0x57,0x35,0x56,0xb5,0x59,0x35,0x55,0xb5,0x5a,0x45,0x54,0xa5, +0x9c,0x31,0x10,0xcc,0x43,0xed,0x46,0x53,0x36,0x92,0x87,0xe5,0x18,0x1c,0x66,0xd6, +0x39,0x29,0x46,0x48,0x79,0x39,0x26,0x3a,0x79,0x45,0x26,0xad,0x78,0x56,0x67,0xa1, +0x37,0x60,0x69,0x15,0x35,0xe9,0x4a,0x8c,0x9c,0x31,0x10,0xd8,0x53,0xdd,0x45,0x43, +0x6b,0xf8,0x54,0xc4,0x89,0xfa,0x37,0x03,0x87,0xbb,0x49,0x04,0x75,0xb9,0x5a,0xc6, +0x63,0xf7,0x7c,0x89,0x42,0x73,0x8d,0xcd,0x41,0x2e,0x7e,0xd2,0x50,0x69,0x5f,0x98, +0x9c,0x31,0x10,0x38,0x47,0xdd,0x76,0x54,0x50,0x45,0x1f,0x3d,0x50,0x39,0x1f,0x45, +0x50,0xad,0x1e,0x51,0x11,0xa5,0x5d,0x59,0x12,0x9d,0x5c,0x62,0x63,0x95,0x1a,0xe9, +0x15,0x0d,0x19,0x6d,0x57,0x0d,0x17,0x6d,0x9c,0x31,0x10,0x1c,0x43,0xed,0x46,0x42, +0x71,0x0e,0x4d,0x6d,0x33,0x0d,0x8b,0x6a,0x15,0x15,0x89,0xe0,0x36,0x9d,0x48,0x59, +0x78,0x28,0x27,0x4d,0x78,0xb6,0x06,0xbd,0x78,0xc1,0x46,0xb2,0x58,0xd1,0x67,0x24, +0x9c,0x31,0x10,0x43,0x44,0xdd,0x46,0x54,0x3f,0x5d,0x81,0x1a,0x3c,0x69,0x24,0x8d, +0x78,0xed,0x28,0x89,0x74,0xf4,0x2c,0x85,0x70,0x75,0x51,0x04,0x2c,0x71,0x95,0x09, +0x08,0xed,0x98,0x91,0x05,0x69,0x9b,0x99,0x9c,0x31,0x10,0x18,0x43,0xed,0x45,0x53, +0x29,0x70,0x36,0xd1,0x68,0x6a,0x17,0x97,0x87,0xe5,0x17,0xdd,0x67,0xde,0x57,0xa2, +0x28,0x59,0x97,0x28,0x09,0x13,0x96,0x2d,0x0a,0x4f,0x74,0xf1,0x2b,0x8c,0x33,0x74, +0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43,0x85,0x49,0x19,0xb5,0x86,0xc8,0x37,0xf6, +0x58,0x89,0x66,0x75,0x1a,0x0a,0x94,0xf3,0x0b,0x8c,0x73,0xb0,0x4c,0x90,0x32,0xac, +0x7d,0x94,0x31,0xe8,0x7e,0x19,0x21,0xa3,0x9c,0x31,0x10,0x02,0x43,0xdd,0x36,0x43, +0x7c,0xb9,0x43,0x3d,0x3c,0x44,0x43,0xb1,0x3b,0x4d,0x45,0x29,0x39,0xd4,0x47,0x25, +0x57,0x59,0x49,0x1c,0x74,0xdd,0x2b,0x9a,0x72,0x61,0x2e,0x19,0x6f,0xe1,0x51,0x1a, +0x9c,0x31,0x10,0x4b,0x42,0xdd,0x35,0x43,0x26,0xb0,0x79,0x8e,0x35,0x6f,0x5a,0xd0, +0x64,0x6d,0x3b,0xd3,0x53,0xa9,0x4c,0x96,0x62,0xe6,0x2c,0xda,0x62,0xa2,0x4d,0x1e, +0x42,0x9e,0x6d,0x22,0x12,0xda,0x8c,0xa5,0x9c,0x31,0x10,0xcb,0x43,0xdd,0x35,0x42, +0x33,0x57,0x5b,0xe9,0x64,0x14,0x2b,0x2b,0x75,0x12,0x3a,0x2d,0x56,0x10,0x58,0xee, +0x37,0x4f,0x67,0xef,0x38,0x4f,0x66,0xae,0x59,0x90,0x45,0xad,0x5a,0x92,0x44,0xab, +0x9c,0x31,0x10,0x72,0x43,0xdc,0x45,0x43,0x5b,0x4a,0x33,0xf1,0x6c,0x10,0x43,0x6b, +0x5c,0x57,0x43,0x24,0x4c,0x9e,0x63,0x1d,0x4c,0x65,0x73,0x56,0x4c,0x2b,0x53,0xd0, +0x5b,0x71,0x54,0x8a,0x6a,0xb6,0x25,0x86,0x9c,0x31,0x10,0x94,0x33,0xdc,0x45,0x42, +0x66,0xe6,0x1a,0x11,0x22,0xee,0x1e,0x0e,0x1e,0xed,0x22,0x0d,0x1a,0xea,0x26,0x15, +0x16,0xdd,0x29,0x25,0x13,0xcd,0x2c,0x35,0x50,0xb9,0x2f,0x4d,0x0f,0xa1,0x30,0x65, +0x9c,0x31,0x10,0x44,0x43,0xdc,0x35,0x42,0x53,0xa2,0x6c,0x1f,0x33,0x9b,0x7b,0xe6, +0x23,0xd5,0x7b,0xac,0x24,0x50,0x7a,0xf1,0x35,0x0b,0x7a,0x35,0x45,0xc8,0x59,0x78, +0x66,0xc5,0x48,0x79,0x57,0xc5,0x47,0x79,0x9c,0x31,0x10,0x44,0x43,0xdc,0x35,0x42, +0x58,0xc6,0x46,0x77,0x59,0xc8,0x45,0xb4,0x5a,0x8c,0x54,0xf0,0x4b,0x11,0x54,0x6b, +0x4b,0x96,0x53,0xe5,0x3b,0xdc,0x53,0xdf,0x4b,0xe2,0x54,0x19,0x3b,0xa8,0x64,0x53, +0x9c,0x31,0x10,0x4a,0x34,0xcc,0x44,0x31,0x1e,0x6d,0x12,0x0f,0x1c,0xf1,0x13,0x8b, +0x1b,0x75,0x15,0x08,0x09,0xb7,0x17,0x07,0x07,0xf7,0x18,0xc7,0x15,0xf6,0x1a,0x88, +0x54,0x34,0x1c,0x4b,0x12,0xb1,0x1d,0xcf,0x9c,0x31,0x10,0x23,0x43,0xdc,0x44,0x42, +0x54,0xac,0x5b,0x54,0x54,0x27,0x6b,0xda,0x53,0xe1,0x5b,0xe0,0x43,0xdb,0x6b,0xe6, +0x44,0x15,0x6b,0x6c,0x34,0x8f,0x7a,0xf1,0x35,0x0b,0x6a,0x35,0x26,0x07,0x79,0x38, +0x9c,0x31,0x10,0xd8,0x33,0xdc,0x44,0x42,0x1c,0x15,0x60,0xe5,0x20,0x16,0x1c,0xe5, +0x63,0x19,0x19,0xdd,0x27,0x21,0x15,0xd1,0x2a,0x31,0x12,0xc1,0x2d,0x45,0x10,0xa9, +0x2e,0x59,0x0f,0x95,0x2f,0x74,0x0f,0x78,0x9c,0x31,0x10,0xb0,0x44,0xdc,0x35,0x42, +0x2d,0xf1,0x4a,0x0c,0x35,0xd4,0x4a,0x29,0x55,0x96,0x4a,0x67,0x2d,0x38,0x4a,0xc5, +0x4c,0xda,0x4b,0x44,0x4c,0x5b,0x4b,0xc3,0x4b,0xdb,0x4c,0x23,0x43,0x7b,0x2c,0xa4, +0x9c,0x31,0x10,0xda,0x44,0xcc,0x45,0x32,0x42,0x19,0x2e,0x25,0x41,0x58,0x2e,0xc7, +0x68,0xd5,0x2f,0x4a,0x48,0x73,0x2f,0x8c,0x48,0x50,0x4f,0x8f,0x48,0x4d,0x6f,0x72, +0x28,0x8b,0x6f,0x34,0x28,0xe9,0x6e,0x97,0x9c,0x31,0x10,0x48,0x42,0xcc,0x35,0x23, +0x33,0x0e,0x6b,0xf2,0x44,0x8b,0x5a,0x74,0x56,0x09,0x48,0xb5,0x67,0xc9,0x37,0x35, +0x69,0x89,0x45,0x74,0x6b,0x0b,0x54,0x31,0x5c,0x4e,0x62,0xee,0x5d,0x52,0x71,0xe9, +0x9c,0x31,0x10,0x19,0x42,0xcc,0x34,0x22,0x3e,0x17,0x61,0x65,0x4e,0x9c,0x51,0x20, +0x5e,0x61,0x31,0x5b,0x6e,0x25,0x31,0xd6,0x6d,0x6a,0x52,0xd2,0x5c,0x6e,0x63,0xcf, +0x3b,0x31,0x65,0x0c,0x49,0xf2,0x46,0x8b,0x9c,0x31,0x10,0x19,0x42,0xcc,0x34,0x22, +0x68,0x73,0x28,0x0b,0x76,0xf3,0x49,0x8c,0x55,0xb2,0x7a,0xcd,0x44,0x6f,0x7c,0x10, +0x53,0x2c,0x3c,0xd3,0x72,0x69,0x4d,0x97,0x51,0xe4,0x6d,0xdc,0x31,0xe0,0x5d,0xe0, +0x9c,0x31,0x10,0x08,0x32,0xcc,0x34,0x31,0x07,0x70,0x36,0x96,0x09,0x5e,0x34,0xa4, +0x0c,0x50,0x30,0xb1,0x10,0x46,0x2c,0xbd,0x14,0x39,0x27,0xc5,0x59,0x35,0x22,0xc4, +0x1e,0x31,0x5d,0xc9,0x24,0x35,0x18,0xc4,0x9c,0x31,0x10,0xbc,0x32,0xcc,0x24,0x31, +0x29,0x39,0x13,0xbe,0x2d,0x41,0x0f,0xb0,0x30,0x4d,0x0c,0xa6,0x33,0x5d,0x0a,0x94, +0x35,0x6e,0x09,0x86,0x75,0x7d,0x09,0x74,0x35,0x8e,0x4a,0x66,0x33,0x9d,0x0d,0x58, +0x9c,0x31,0x10,0x95,0x31,0xcc,0x34,0x32,0x70,0xaa,0x10,0x4e,0x2c,0xb4,0x14,0x40, +0x28,0xbe,0x58,0x3d,0x23,0xc0,0x1d,0x39,0x1e,0xc1,0x22,0x39,0x1a,0xbc,0x27,0x3d, +0x15,0xb9,0x2b,0x45,0x11,0xb1,0x2e,0x52,0x9c,0x31,0x10,0x75,0x31,0xcb,0x23,0x31, +0x07,0x72,0x59,0x0f,0x26,0x2b,0x39,0xd6,0x05,0xa4,0x5a,0x1e,0x25,0x9c,0x39,0xe5, +0x26,0x15,0x39,0x2c,0x47,0x4e,0x17,0xf3,0x28,0xc9,0x36,0x38,0x2a,0x84,0x33,0xfc, +0x9c,0x31,0x10,0x38,0x33,0xcb,0x34,0x32,0x0c,0x81,0x31,0xf9,0x0f,0x01,0x2f,0x7a, +0x11,0x00,0x4d,0x7a,0x33,0x86,0x2a,0xf0,0x55,0x8d,0x29,0x69,0x37,0x14,0x27,0xdd, +0x38,0xa1,0x06,0x50,0x19,0x31,0x25,0xc1,0x9c,0x31,0x10,0x21,0x33,0xcc,0x24,0x31, +0x33,0x80,0x0b,0x75,0x32,0x8e,0x0c,0x65,0x31,0x9d,0x0e,0x59,0x2f,0xaa,0x11,0x4e, +0x2b,0xb0,0x15,0x41,0x67,0xba,0x19,0x3d,0x23,0xc0,0x1d,0x39,0x1e,0xc2,0x62,0x39, +0x9c,0x31,0x10,0x9b,0x32,0xcc,0x24,0x32,0x1a,0xbc,0x27,0x3d,0x15,0xb9,0x2b,0x44, +0x11,0xb1,0x2f,0x51,0x0e,0xa5,0x31,0x5c,0x0c,0x95,0x33,0x6d,0x0a,0x89,0x34,0x79, +0x0a,0x79,0x33,0x89,0x0c,0x69,0x32,0x99,0x9c,0x31,0x10,0x36,0x32,0xcb,0x24,0x31, +0x27,0x1d,0x37,0xe5,0x28,0x91,0x35,0xed,0x4a,0x89,0x33,0xf5,0x2c,0x81,0x31,0xf8, +0x2e,0x81,0x2f,0x79,0x11,0x01,0x2d,0x78,0x33,0x85,0x2a,0xf1,0x15,0x8d,0x29,0x6a, +0x9c,0x31,0x10,0x78,0x34,0xcb,0x24,0x32,0x2d,0xc5,0x29,0xf7,0x4e,0x08,0x29,0xb4, +0x2e,0x4c,0x09,0x91,0x2e,0x4f,0x09,0x8d,0x26,0x33,0x29,0xca,0x25,0xf6,0x2a,0x07, +0x4d,0xb9,0x32,0x64,0x4d,0x3b,0x32,0xe2,0x9c,0x31,0x10,0x53,0x8a,0xcd,0xa9,0x98, +0x6e,0x25,0x6d,0x95,0x6d,0xe5,0x6d,0xd5,0x6d,0xa5,0x6e,0x15,0x6d,0x65,0x6e,0x59, +0x6d,0x21,0x6e,0x99,0x6d,0x21,0x6e,0x99,0x69,0x64,0x40,0x45,0xab,0xb2,0x2c,0x8d, +0x9c,0x31,0x10,0xa9,0x57,0xdd,0x66,0x54,0x89,0xe2,0x16,0x19,0x98,0x60,0x17,0x99, +0x56,0xe1,0x59,0x19,0x55,0xe1,0x5a,0x1d,0x54,0xd9,0x5b,0x21,0x13,0xd5,0x5c,0x29, +0x53,0x4d,0x5c,0xb1,0x52,0xc5,0x5c,0xb9,0x9c,0x31,0x10,0x9f,0x44,0xdc,0x46,0x53, +0x65,0xc0,0x39,0xc2,0x46,0x32,0x58,0xd0,0x27,0x25,0x77,0xde,0x08,0x99,0x76,0x64, +0x2a,0x11,0x54,0x6d,0x4c,0x08,0x32,0x71,0x8e,0x05,0x10,0x70,0x70,0x09,0x2e,0x72, +0x9c,0x31,0x10,0x41,0x43,0xcc,0x35,0x43,0x5a,0x45,0x44,0x77,0x4c,0x08,0x62,0xf4, +0x3d,0x8d,0x41,0xaf,0x5e,0x92,0x30,0xea,0x7f,0x17,0x20,0x64,0x7f,0x5d,0x30,0x5e, +0x5f,0x22,0x60,0xd9,0x2e,0x68,0x71,0x94,0x9c,0x31,0x10,0x41,0x43,0xcc,0x35,0x43, +0x2d,0xac,0x62,0xd0,0x4c,0x70,0x44,0x0d,0x7a,0xf2,0x25,0x8b,0x79,0x74,0x37,0x0a, +0x57,0xb4,0x48,0xca,0x46,0x73,0x6a,0x4c,0x34,0xf1,0x6b,0x8e,0x33,0xae,0x6c,0x92, +0x9c,0x31,0x10,0x5c,0x43,0xcc,0x35,0x42,0x42,0xaa,0x5d,0x56,0x62,0x26,0x2d,0xda, +0x81,0xe1,0x2d,0xdf,0x51,0xdd,0x5d,0xa3,0x42,0x59,0x6d,0x27,0x43,0x15,0x7c,0x2b, +0x43,0xd1,0x5b,0x2e,0x45,0x0f,0x4a,0x30,0x9c,0x31,0x10,0x2c,0x42,0xcc,0x25,0x32, +0x66,0x4e,0x28,0xb1,0x57,0x8d,0x47,0x71,0x49,0x0d,0x56,0x30,0x3a,0x4f,0x74,0xee, +0x4b,0x51,0x63,0xec,0x5c,0x54,0x52,0xe9,0x6d,0x17,0x32,0x65,0x6d,0x9b,0x32,0x21, +0x9c,0x31,0x10,0x98,0x42,0xcc,0x35,0x32,0x5d,0x9f,0x52,0x1c,0x3d,0xa4,0x62,0x58, +0x4d,0x28,0x63,0x15,0x4c,0x6b,0x53,0xd1,0x5b,0x6e,0x34,0xcf,0x6a,0x70,0x36,0x0d, +0x69,0x32,0x57,0x4c,0x47,0xf2,0x68,0x8c,0x9c,0x31,0x10,0xc1,0x42,0xcc,0x35,0x42, +0x46,0xb2,0x59,0xcd,0x55,0x70,0x5b,0x0e,0x44,0x2e,0x5c,0x11,0x43,0x2b,0x5c,0xd4, +0x42,0xa8,0x5d,0x98,0x62,0x24,0x2d,0xdc,0x71,0xdf,0x3d,0xe1,0x52,0x1b,0x5d,0x65, +0x9c,0x31,0x10,0xc1,0x42,0xcc,0x35,0x42,0x42,0x97,0x6c,0xe9,0x43,0x53,0x7b,0xec, +0x34,0x50,0x5a,0xef,0x45,0x8e,0x49,0xb0,0x66,0xcd,0x28,0x31,0x58,0x0d,0x46,0xf1, +0x49,0x8e,0x55,0xb0,0x3a,0xcf,0x74,0x6e,0x9c,0x31,0x10,0x12,0x42,0xcb,0x35,0x32, +0x57,0x89,0x46,0xed,0x59,0x15,0x45,0x5c,0x5a,0xa5,0x24,0xce,0x5b,0x35,0x24,0x3c, +0x5b,0x46,0x44,0x2d,0x3a,0xd4,0x65,0x1d,0x59,0xe6,0x46,0x8d,0x57,0xf1,0x48,0x82, +0x9c,0x31,0x10,0x8d,0x42,0xcc,0x34,0x42,0x5a,0xef,0x35,0x4e,0x69,0xb1,0x36,0xcd, +0x58,0x71,0x68,0x0c,0x37,0x31,0x79,0x4d,0x35,0xf0,0x6a,0x8f,0x54,0xae,0x4b,0x91, +0x53,0xab,0x3c,0x54,0x62,0xe8,0x4d,0x18,0x9c,0x31,0x10,0x49,0x43,0xcc,0x34,0x32, +0x62,0x64,0x5d,0x5c,0x42,0x20,0x6d,0x60,0x42,0x5c,0x7d,0x24,0x42,0xd8,0x5c,0xa8, +0x53,0x54,0x4b,0xeb,0x64,0x51,0x3a,0xee,0x65,0x4f,0x49,0xf0,0x46,0x8e,0x68,0xb0, +0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32,0x37,0xcd,0x77,0x30,0x39,0x0e,0x65,0xef, +0x3a,0x4f,0x44,0xed,0x4b,0x52,0x44,0x2b,0x6c,0x15,0x33,0x68,0x5c,0x98,0x42,0xe4, +0x6d,0x1c,0x42,0xa0,0x5d,0x20,0x52,0xdc,0x9c,0x31,0x10,0xbd,0x44,0xcc,0x34,0x32, +0x2e,0x71,0x49,0x8c,0x26,0x33,0x69,0xea,0x25,0xd4,0x6a,0x49,0x4d,0x56,0x4a,0xc8, +0x4c,0xd6,0x4b,0x47,0x6c,0x37,0x2b,0xe7,0x6b,0xb7,0x2c,0x88,0x4b,0x16,0x2d,0x08, +0x9c,0x31,0x10,0x9f,0x8a,0xdd,0xaa,0x98,0x6d,0x45,0x6e,0x25,0x6d,0x45,0x6e,0x25, +0x6d,0x45,0x6d,0xba,0x45,0xd5,0xa6,0x05,0x2c,0xe5,0x6e,0x95,0x6c,0x55,0x6f,0x15, +0x6c,0x55,0x6f,0x25,0x6c,0x45,0x6f,0x25,0x9c,0x31,0x10,0x10,0x44,0xdd,0x46,0x53, +0x40,0x40,0x5f,0x3c,0x60,0xb6,0x3e,0x49,0x81,0xac,0x1c,0xd5,0x63,0xa1,0x5a,0x5c, +0x26,0x19,0x57,0xe1,0x29,0x15,0x74,0x64,0x4c,0x91,0x51,0x69,0x6f,0x91,0x0d,0xe9, +0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43,0x89,0x8a,0x25,0x73,0x7b,0x0c,0x54,0x31, +0x3c,0x4f,0x62,0xed,0x1d,0x13,0x92,0x29,0x1d,0xd7,0x71,0xa4,0x5e,0x1c,0x31,0xa0, +0x9e,0x21,0x01,0xdb,0xad,0xa5,0x12,0x57,0x9c,0x31,0x10,0x02,0x43,0xdd,0x36,0x43, +0x79,0xd0,0x26,0xa5,0x37,0xd9,0x68,0xa1,0x15,0xdd,0x8b,0x1e,0x12,0xe1,0x4d,0x99, +0x50,0x62,0x30,0x99,0x6d,0xe0,0x13,0x1d,0x6b,0x5d,0x15,0x21,0x48,0xd9,0x77,0x25, +0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43,0x23,0xaa,0x9c,0x96,0x12,0xe6,0x7c,0xda, +0x42,0xa2,0x3d,0x1e,0x82,0x9e,0x2d,0x22,0x72,0xda,0x4c,0xe6,0x43,0x16,0x6c,0x29, +0x33,0xd3,0x7b,0x6d,0x34,0xd0,0x5a,0x6f,0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43, +0x46,0x0e,0x49,0x31,0x57,0x4d,0x57,0xb1,0x48,0xcd,0x66,0x31,0x3a,0x4e,0x64,0xaf, +0x5b,0x90,0x43,0x6d,0x6c,0xd3,0x32,0x69,0x6d,0x97,0x21,0xe5,0x6e,0x1c,0x51,0xa0, +0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43,0x3e,0x21,0x91,0x9b,0x0d,0xe5,0x92,0x17, +0x1d,0x29,0x63,0x13,0x5c,0x2d,0x24,0x10,0x7a,0xef,0x05,0x4e,0x99,0xb1,0x16,0xcd, +0x78,0x32,0x58,0x0c,0x26,0xf1,0x89,0x8d,0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43, +0x15,0xb0,0x7a,0x8f,0x34,0x6d,0x5b,0xd2,0x53,0xaa,0x1c,0x95,0x82,0xe7,0x2d,0x19, +0x72,0xa3,0x4d,0x5d,0x42,0x9f,0x8d,0x21,0x02,0xdb,0x8c,0xe5,0x33,0x57,0x5c,0x28, +0x9c,0x31,0x10,0x53,0x42,0xcd,0x35,0x43,0x60,0x14,0x3e,0xab,0x72,0x12,0x3c,0xad, +0x74,0x10,0x4a,0x6f,0x56,0x8f,0x68,0x2f,0x38,0xcf,0x65,0xee,0x4b,0x10,0x73,0xad, +0x3d,0x12,0x61,0xab,0x5e,0x94,0x40,0x68,0x9c,0x31,0x10,0xd9,0x42,0xdc,0x35,0x42, +0x6b,0xd0,0x33,0xab,0x8c,0x56,0x33,0x65,0x4c,0x9d,0x73,0x1e,0x3c,0x64,0x63,0x57, +0x5c,0x2a,0x43,0xd1,0x6b,0xb0,0x34,0x4b,0x6a,0xf5,0x35,0x47,0x7a,0x39,0x36,0x04, +0x9c,0x31,0x10,0x51,0x43,0xdc,0x34,0x32,0x59,0x3b,0x47,0x02,0x47,0xfc,0x88,0x42, +0x26,0xfc,0x69,0x43,0x55,0xfa,0x3a,0x06,0x75,0x36,0x3b,0x0a,0x74,0x71,0x4b,0x8f, +0x43,0xec,0x6c,0x16,0x23,0x65,0x6c,0x5c,0x9c,0x31,0x10,0xab,0x42,0xdc,0x45,0x32, +0x53,0x5f,0x4c,0x63,0x63,0x98,0x4c,0x29,0x53,0xd2,0x5b,0xaf,0x44,0x8d,0x4a,0xf4, +0x45,0x48,0x4a,0x37,0x56,0x05,0x59,0x3a,0x37,0x04,0x68,0x3b,0x48,0x03,0x67,0x3a, +0x9c,0x31,0x10,0xab,0x42,0xdc,0x45,0x32,0x39,0x05,0x46,0x38,0x5a,0x07,0x45,0x75, +0x5a,0xcb,0x44,0xb0,0x4b,0x50,0x44,0x2b,0x4b,0xd6,0x53,0xe5,0x4c,0x1c,0x43,0x9f, +0x4b,0xe2,0x33,0xd9,0x5b,0xe8,0x34,0x13,0x9c,0x31,0x10,0x2e,0x43,0xcc,0x45,0x32, +0x5e,0xae,0x21,0x8e,0x6d,0x72,0x43,0x0a,0x4b,0xf6,0x54,0xc7,0x3a,0x38,0x76,0x86, +0x38,0x39,0x78,0x86,0x26,0x78,0x7a,0x47,0x34,0xb6,0x6c,0x0a,0x42,0xf3,0x6d,0x4d, +0x9c,0x31,0x10,0x53,0x34,0xcc,0x35,0x42,0x11,0xae,0x1e,0x92,0x10,0xe9,0x1f,0x57, +0x10,0x64,0x0f,0x9d,0x10,0x1e,0x1f,0x63,0x10,0x98,0x1e,0xe9,0x21,0x53,0x1d,0xed, +0x22,0x4f,0x1c,0xb1,0x13,0xcb,0x1b,0x34,0x9c,0x31,0x10,0xf1,0x44,0xcc,0x35,0x32, +0x2a,0xa4,0x4c,0xba,0x4b,0x83,0x6b,0xdb,0x2c,0x64,0x6a,0xfa,0x2d,0x44,0x6a,0x39, +0x26,0x06,0x69,0x77,0x46,0xa8,0x68,0xf5,0x4f,0x2a,0x48,0x93,0x4f,0x6c,0x28,0x50, +0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32,0x6f,0x1f,0x40,0xdc,0x5e,0xe4,0x41,0x57, +0x5e,0x29,0x62,0x12,0x4d,0x2e,0x63,0x0e,0x3b,0xf1,0x74,0x8b,0x2a,0x74,0x66,0x09, +0x38,0xf5,0x67,0x89,0x47,0x35,0x59,0x49,0x9c,0x31,0x10,0x6e,0x43,0xcc,0x34,0x31, +0x55,0x74,0x5b,0x0b,0x63,0xf2,0x3c,0x8d,0x72,0xaf,0x3d,0xd2,0x71,0x6a,0x3e,0x96, +0x60,0xa5,0x5f,0x5c,0x40,0x60,0x6f,0x61,0x40,0x9a,0x6f,0x27,0x31,0x14,0x6e,0x2c, +0x9c,0x31,0x10,0x3b,0x43,0xcc,0x44,0x42,0x32,0x10,0x6d,0x31,0x33,0x4c,0x6b,0xb4, +0x45,0x09,0x69,0xf6,0x46,0x88,0x48,0x37,0x58,0x87,0x46,0x76,0x6a,0x09,0x34,0xb4, +0x7b,0xcb,0x33,0x71,0x7d,0x0f,0x32,0x2d,0x9c,0x31,0x10,0x09,0x43,0xcc,0x45,0x31, +0x7e,0x13,0x31,0x28,0x7e,0xd8,0x30,0xa3,0x6f,0x1e,0x40,0x9e,0x4e,0xe3,0x51,0x18, +0x4e,0x68,0x51,0xd3,0x4d,0x6d,0x62,0xcf,0x5c,0x70,0x54,0x0c,0x4a,0xf3,0x55,0x8a, +0x9c,0x31,0x10,0x05,0x43,0xcc,0x35,0x32,0x59,0x75,0x37,0x49,0x67,0xb5,0x38,0xc9, +0x66,0x34,0x3a,0x4b,0x74,0xb2,0x4b,0xcd,0x73,0x6f,0x3c,0xd1,0x52,0x6b,0x5d,0xd5, +0x31,0xa7,0x5e,0x5a,0x31,0x62,0x7e,0x5e,0x9c,0x31,0x10,0x2d,0x42,0xcc,0x33,0x32, +0x41,0x5d,0x6e,0x63,0x51,0x98,0x4d,0xa8,0x62,0x54,0x4c,0xec,0x73,0x50,0x4b,0xef, +0x64,0x8e,0x4a,0xb1,0x45,0xcc,0x69,0x33,0x37,0x4b,0x67,0xb3,0x48,0xcb,0x56,0x72, +0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32,0x6a,0x0c,0x34,0xf1,0x6b,0x4f,0x33,0xee, +0x4c,0x52,0x52,0xea,0x3d,0x15,0x62,0x67,0x4d,0x9a,0x41,0xe2,0x5d,0xde,0x31,0xde, +0x5d,0xe2,0x42,0x1a,0x3d,0x66,0x62,0x96,0x9c,0x31,0x10,0x60,0x42,0xcc,0x24,0x32, +0x4c,0xaa,0x43,0x92,0x5b,0xad,0x44,0x90,0x5a,0xaf,0x45,0x8e,0x59,0x71,0x56,0xcd, +0x38,0x31,0x58,0x0d,0x56,0xf1,0x49,0x4e,0x45,0xb0,0x4a,0x8f,0x44,0xae,0x6b,0x92, +0x9c,0x31,0x10,0x50,0x41,0xcb,0x24,0x32,0x47,0xed,0x38,0x95,0x46,0x61,0x59,0xa1, +0x45,0x50,0x5a,0x30,0x45,0x42,0x5a,0x41,0x45,0x30,0x5a,0x4c,0x45,0xa6,0x39,0x5d, +0x47,0x14,0x57,0xe8,0x48,0x8e,0x55,0xf2,0x9c,0x31,0x10,0x08,0x32,0xcc,0x34,0x31, +0x15,0x40,0x27,0xb9,0x19,0x3e,0x22,0xbd,0x1e,0x3c,0x1e,0xbe,0x23,0x3e,0x19,0xbd, +0x27,0x40,0x15,0xb6,0x2b,0x49,0x11,0xac,0x2e,0x55,0x0e,0xa2,0x30,0x61,0x0d,0x94, +0x9c,0x31,0x10,0x36,0x32,0xcb,0x24,0x31,0x39,0x2d,0x26,0x45,0x59,0x3c,0x06,0x35, +0x39,0x4a,0x26,0xa9,0x38,0x58,0x27,0x9e,0x17,0x61,0x29,0x10,0x15,0x6d,0x4b,0x0a, +0x13,0x70,0x4d,0x05,0x31,0x76,0x2f,0x05,0x9c,0x31,0x10,0x50,0x43,0xcb,0x24,0x31, +0x4f,0x74,0x51,0x06,0x4d,0x75,0x33,0x08,0x6b,0x6d,0x35,0x11,0x49,0x64,0x36,0x99, +0x48,0x5a,0x37,0xa4,0x67,0x4d,0x58,0x32,0x47,0x40,0x58,0x3e,0x47,0x36,0x38,0x4c, +0x9c,0x31,0x10,0x38,0x33,0xcb,0x34,0x32,0x47,0xaa,0x17,0x55,0x28,0x9c,0x35,0xe1, +0x4a,0x15,0x34,0x68,0x0c,0x0d,0x32,0x6d,0x2e,0x09,0x30,0x71,0x30,0x09,0x2e,0x71, +0x32,0x09,0x0c,0x6d,0x33,0x8d,0x0a,0xea,0x9c,0x31,0x10,0x66,0x33,0xcb,0x24,0x21, +0x55,0x95,0x09,0x61,0x37,0x1d,0x27,0xd5,0x38,0x29,0x27,0x49,0x38,0xb5,0x26,0xbe, +0x38,0xc1,0x06,0xb0,0x38,0xd1,0x27,0x25,0x37,0xdc,0x28,0x19,0x36,0xe6,0x29,0x91, +0x9c,0x31,0x10,0x50,0x43,0xcb,0x24,0x31,0x55,0x6c,0x4b,0x0a,0x53,0x75,0x4d,0x04, +0x50,0xf9,0x4f,0x82,0x4e,0xf8,0x31,0x85,0x6c,0xf6,0x53,0x89,0x6a,0xec,0x55,0x92, +0x49,0x65,0x36,0x98,0x47,0xd9,0x57,0xa5,0x9c,0x31,0x10,0xab,0x33,0xcb,0x24,0x31, +0x07,0x4c,0x38,0xb5,0x06,0xc2,0x58,0xc0,0x07,0x35,0x78,0x4e,0x07,0xa4,0x57,0x59, +0x08,0x9e,0x55,0xe0,0x0a,0x12,0x54,0x6a,0x0c,0x0c,0x52,0x71,0x2e,0x09,0x50,0x70, +0x9c,0x31,0x10,0x8c,0x33,0xcb,0x24,0x32,0x10,0x09,0x2e,0x71,0x32,0x08,0x2c,0x6d, +0x14,0x11,0x4a,0xe5,0x15,0x99,0x49,0x5d,0x16,0xa5,0x48,0x52,0x17,0xad,0x47,0xc4, +0x37,0xba,0x27,0xb8,0x37,0xc9,0x08,0x2e,0x9c,0x31,0x10,0xbd,0x33,0xbb,0x34,0x22, +0x3e,0x50,0x22,0x21,0x3b,0xdd,0x25,0x18,0x58,0xe6,0x08,0x10,0x35,0x69,0x0c,0x0d, +0x31,0x6d,0x2f,0x8d,0x2d,0xed,0x53,0x8d,0x2a,0x69,0x37,0x15,0x06,0xe5,0x3a,0x19, +0x9c,0x31,0x10,0x61,0x43,0xbb,0x34,0x21,0x42,0x5d,0x5d,0xa4,0x41,0x51,0x5e,0xad, +0x40,0xc8,0x5e,0xba,0x40,0xbd,0x6e,0xc4,0x40,0xb2,0x6e,0x4d,0x31,0xa9,0x5d,0x56, +0x32,0x9d,0x6c,0x5c,0x33,0x9a,0x6a,0xe5,0x9c,0x31,0x10,0x4a,0x32,0xbb,0x23,0x21, +0x0a,0xc5,0x4c,0xba,0x0b,0x84,0x2b,0xda,0x0c,0x64,0x2b,0x19,0x35,0x25,0x32,0x58, +0x2d,0xe6,0x09,0xb7,0x2e,0x68,0x01,0x35,0x2e,0xea,0x28,0xd3,0x0f,0x2c,0x30,0xb0, +0x9c,0x31,0x10,0xd9,0x32,0xbb,0x33,0x22,0x17,0x2f,0x28,0xae,0x07,0x31,0x28,0xcc, +0x0e,0xf3,0x31,0x2a,0x2e,0x75,0x11,0xa8,0x4d,0xf7,0x0a,0x46,0x0d,0x58,0x2a,0xe5, +0x0c,0x99,0x53,0xa5,0x2b,0xd9,0x2c,0x65,0x9c,0x31,0x10,0xf9,0x32,0xbb,0x24,0x11, +0x4c,0xe6,0x14,0x19,0x29,0xe0,0x36,0x9d,0x27,0xda,0x38,0xa1,0x25,0xd4,0x1a,0x29, +0x44,0xce,0x1b,0x31,0x23,0xc5,0x3b,0xb9,0x03,0xbd,0x3b,0xc1,0x24,0x35,0x3a,0xc9, +0x9c,0x31,0x10,0xf0,0x31,0xbb,0x23,0x21,0x22,0x96,0x4c,0xe9,0x23,0x53,0x1b,0xed, +0x34,0x50,0x3a,0xef,0x15,0x4e,0x39,0xf1,0x16,0x8d,0x18,0xb2,0x27,0xcc,0x37,0x72, +0x39,0x0d,0x16,0x31,0x3a,0x0e,0x24,0xef,0x9c,0x31,0x10,0x7f,0x31,0xba,0x23,0x21, +0x2b,0x42,0x24,0x3a,0x3c,0x07,0x23,0x34,0x3c,0xce,0x32,0xac,0x2d,0x55,0x32,0x65, +0x4d,0x5d,0x22,0x5d,0x2d,0x65,0x42,0x95,0x2c,0xed,0x13,0x0e,0x4c,0x74,0x03,0xc7, +0x9c,0x31,0x10,0xf0,0x31,0xbb,0x23,0x21,0x3b,0x6c,0x34,0x91,0x2a,0x6e,0x35,0xcf, +0x39,0x70,0x17,0x0e,0x38,0x30,0x28,0x4e,0x26,0xf0,0x59,0x8f,0x15,0xaf,0x3a,0x90, +0x44,0xad,0x2b,0x93,0x43,0xaa,0x2c,0x96,0x9c,0x31,0x10,0x7d,0x31,0xbb,0x12,0x21, +0x32,0xe6,0x2d,0x19,0x22,0x63,0x2d,0x5e,0x12,0x5e,0x4d,0x62,0x22,0x5a,0x3d,0x26, +0x32,0xd6,0x3c,0xaa,0x13,0x93,0x3b,0xad,0x44,0x90,0x1a,0xaf,0x35,0x8e,0x29,0xb1, +0x9c,0x31,0x10,0xf0,0x31,0xbb,0x23,0x21,0x16,0xcd,0x28,0x72,0x37,0xcc,0x37,0x31, +0x29,0x0d,0x35,0xf0,0x2a,0x4e,0x14,0xef,0x2b,0x51,0x33,0xec,0x2c,0x54,0x23,0x29, +0x3c,0xd7,0x22,0xa5,0x2d,0x5b,0x42,0x61,0x9c,0x31,0x10,0xf0,0x31,0xbb,0x23,0x21, +0x3d,0x5f,0x22,0x5d,0x4d,0x63,0x32,0x99,0x1c,0xe6,0x43,0x16,0x1c,0x2a,0x13,0xd3, +0x4b,0x6d,0x24,0xd0,0x3a,0x6f,0x36,0x0f,0x29,0x30,0x27,0x0e,0x37,0xf0,0x18,0x4e, +0x9c,0x31,0x10,0x4a,0x32,0xbb,0x23,0x21,0x4b,0x57,0x24,0xc7,0x0a,0xd7,0x4d,0x48, +0x0a,0x56,0x4d,0xc9,0x29,0xd4,0x2e,0x2b,0x29,0x93,0x0e,0x6c,0x29,0x51,0x16,0x8e, +0x49,0x4f,0x2e,0x90,0x29,0x6d,0x46,0x52,0x9c,0x31,0x10,0xb1,0x42,0xbb,0x23,0x21, +0x54,0xcb,0x56,0xf4,0x49,0x0a,0x56,0xd5,0x49,0x28,0x56,0x96,0x35,0x88,0x56,0x37, +0x45,0xc7,0x51,0xf7,0x46,0x07,0x55,0x97,0x36,0x68,0x65,0x56,0x3a,0xa9,0x69,0x15, +0x9c,0x31,0x10,0xa1,0x33,0xba,0x24,0x21,0x17,0x15,0x27,0x61,0x18,0xa1,0x26,0x50, +0x39,0x31,0x25,0xc1,0x39,0xbd,0x26,0x36,0x39,0x4d,0x06,0xa5,0x38,0x5d,0x08,0x19, +0x36,0xe5,0x29,0x8d,0x34,0xf1,0x2b,0x85,0x9c,0x31,0x10,0x5e,0x33,0xba,0x22,0x11, +0x0c,0x9d,0x2b,0x80,0x0c,0x1e,0x04,0x20,0x2b,0x7d,0x2c,0xc1,0x22,0xdc,0x25,0x43, +0x02,0x5a,0x25,0xa6,0x29,0xf7,0x0e,0x09,0x09,0xb4,0x0e,0x2c,0x29,0x90,0x16,0x50, +0x9c,0x31,0x10,0xc5,0x32,0xba,0x23,0x21,0x29,0xac,0x36,0x33,0x09,0xc9,0x2d,0xf7, +0x12,0x26,0x25,0x99,0x2a,0x84,0x25,0x1b,0x2b,0x02,0x04,0x9c,0x23,0xa1,0x2b,0xfd, +0x24,0x21,0x2b,0x7c,0x2c,0xa2,0x2a,0xfb,0x9c,0x31,0x10,0xc3,0x32,0xba,0x22,0x11, +0x35,0x24,0x32,0x79,0x35,0x86,0x32,0x37,0x35,0xe9,0x29,0xf4,0x2e,0x0c,0x29,0xd1, +0x2e,0x0f,0x49,0xcd,0x06,0x12,0x29,0xea,0x25,0xd5,0x4a,0x27,0x2d,0x98,0x32,0x85, +0x9c,0x31,0x10,0x1a,0x32,0xaa,0x12,0x11,0x2e,0x7a,0x29,0xe3,0x2d,0x7b,0x2a,0xc2, +0x2c,0x9c,0x2b,0xc2,0x4b,0x9c,0x2c,0xc2,0x4a,0xbb,0x0d,0xa3,0x29,0xda,0x2e,0x65, +0x29,0x18,0x2f,0x27,0x08,0x76,0x37,0xa9,0x9c,0x31,0x10,0x94,0x32,0xba,0x22,0x20, +0x29,0xf3,0x2d,0xec,0x21,0xf1,0x2d,0xef,0x29,0xee,0x2d,0xf2,0x0a,0x0b,0x2d,0xd4, +0x2a,0x28,0x2d,0x97,0x2a,0x66,0x0d,0x39,0x0a,0xc4,0x2c,0xda,0x23,0x23,0x2c,0x7b, +0x9c,0x31,0x10,0xea,0x31,0xaa,0x12,0x21,0x26,0x86,0x18,0x79,0x28,0x46,0x36,0xb8, +0x39,0xc6,0x15,0x37,0x3b,0x48,0x43,0xb4,0x1c,0xcb,0x32,0x71,0x2d,0xcf,0x21,0x6d, +0x3e,0x93,0x20,0xe9,0x3f,0x57,0x40,0x64,0x9c,0x31,0x10,0x79,0x31,0xba,0x22,0x11, +0x3b,0xdc,0x33,0xdf,0x2b,0xe1,0x23,0xda,0x3b,0xa7,0x24,0x15,0x4b,0x6c,0x34,0x90, +0x3a,0xf1,0x35,0x0b,0x2a,0x75,0x35,0xc8,0x29,0x78,0x36,0x85,0x28,0xb9,0x47,0x84, +0x9c,0x31,0x10,0x02,0x32,0xba,0x12,0x11,0x23,0xdc,0x4c,0x42,0x0b,0x5b,0x34,0xc3, +0x2a,0xda,0x2d,0x25,0x22,0x78,0x0d,0x87,0x0a,0x36,0x2d,0xc9,0x0a,0x14,0x2d,0xec, +0x09,0xf1,0x2d,0xef,0x29,0xee,0x0d,0xf2,0x9c,0x31,0x10,0x2b,0x31,0xaa,0x22,0x21, +0x30,0x17,0x3f,0x2a,0x10,0xd2,0x3e,0x6f,0x12,0x0d,0x1d,0x33,0x23,0x4a,0x2b,0xb6, +0x24,0xc7,0x29,0xf8,0x16,0x86,0x28,0x78,0x28,0x45,0x36,0xb8,0x29,0xc6,0x25,0x37, +0x9c,0x31,0x10,0xea,0x31,0xaa,0x12,0x21,0x4b,0x48,0x23,0xb4,0x2c,0x8b,0x22,0x71, +0x2d,0xcf,0x31,0x6d,0x2e,0x93,0x20,0xe8,0x3f,0x18,0x30,0x63,0x3f,0x9d,0x20,0x5e, +0x2f,0x62,0x40,0x99,0x2f,0x27,0x41,0x14,0x9c,0x31,0x10,0x61,0x31,0xaa,0x22,0x11, +0x2e,0x6c,0x21,0xd0,0x3d,0x70,0x32,0xcc,0x2c,0x33,0x44,0x49,0x2a,0xb6,0x15,0xc7, +0x29,0x37,0x27,0x47,0x17,0xb7,0x38,0xc7,0x26,0x36,0x2a,0x88,0x24,0x74,0x2b,0xcb, +0x9c,0x31,0x10,0xa0,0x31,0xaa,0x12,0x11,0x23,0x32,0x2d,0x0e,0x22,0x2e,0x2e,0x12, +0x31,0x69,0x3e,0xd7,0x20,0xe4,0x3f,0x1c,0x10,0x9f,0x2f,0x21,0x30,0xda,0x2e,0xa6, +0x21,0x55,0x4d,0xeb,0x22,0x11,0x2c,0xef,0x9c,0x31,0x10,0xa0,0x31,0xaa,0x12,0x11, +0x33,0x4d,0x3b,0xb2,0x34,0xca,0x1a,0x75,0x36,0x49,0x28,0xb6,0x27,0xc8,0x36,0xf5, +0x29,0x89,0x35,0x74,0x3b,0x0b,0x44,0x32,0x2c,0x4e,0x42,0xae,0x1d,0x92,0x31,0xaa, +0x9c,0x31,0x10,0xdb,0x32,0xaa,0x22,0x11,0x27,0x2b,0x28,0x92,0x2f,0x6d,0x28,0x6f, +0x0f,0x70,0x20,0x8d,0x2f,0x32,0x28,0xca,0x0e,0xf5,0x21,0x48,0x0e,0x57,0x29,0xe6, +0x35,0xb8,0x2a,0x85,0x34,0xd9,0x33,0x65,0x9c,0x31,0x10,0xce,0x32,0xaa,0x11,0x11, +0x2c,0x1a,0x34,0x45,0x0b,0x39,0x35,0x05,0x32,0x78,0x2d,0xc6,0x31,0xb7,0x0e,0x68, +0x09,0x35,0x0e,0xea,0x28,0xd3,0x2f,0x2d,0x28,0x90,0x07,0x4f,0x20,0xad,0x2f,0x12, +0x9c,0x31,0x10,0xd8,0x33,0xaa,0x21,0x21,0x20,0xeb,0x2e,0xd4,0x29,0x49,0x0e,0x36, +0x29,0xe7,0x35,0x98,0x2a,0xa6,0x2c,0xd9,0x33,0x85,0x2b,0xf9,0x4c,0x45,0x2b,0x39, +0x2d,0x26,0x2a,0x78,0x2d,0xc7,0x21,0xd6,0x9c,0x31,0x10,0x84,0x32,0xaa,0x11,0x21, +0x2e,0x69,0x21,0x54,0x06,0xcb,0x28,0xf2,0x27,0x0d,0x08,0xd0,0x2f,0x0f,0x20,0xcd, +0x2e,0xf2,0x21,0x0b,0x2e,0xb4,0x29,0x69,0x2e,0x36,0x29,0xe7,0x4d,0x97,0x32,0x86, +0x9c,0x31,0x10,0xce,0x32,0xaa,0x11,0x11,0x2c,0xf8,0x33,0x46,0x2c,0x39,0x34,0x05, +0x23,0x78,0x2c,0xa6,0x2a,0xd8,0x0d,0x67,0x0a,0x37,0x2d,0xe8,0x29,0xb5,0x0e,0x69, +0x29,0x54,0x2e,0xab,0x21,0x12,0x2e,0xed,0x9c,0x31,0x10,0x45,0x32,0xaa,0x21,0x21, +0x28,0xf0,0x2f,0x0f,0x28,0xed,0x2e,0xf2,0x29,0x0b,0x36,0xb4,0x29,0x69,0x2e,0x56, +0x31,0xe7,0x2d,0xb7,0x2a,0x86,0x34,0xf8,0x2b,0x45,0x24,0x39,0x2c,0x25,0x23,0x59, +0x9c,0x31,0x10,0x84,0x32,0xaa,0x11,0x21,0x24,0xe6,0x4a,0x98,0x25,0xa7,0x21,0xd7, +0x2e,0x48,0x21,0x55,0x2e,0xca,0x30,0xf3,0x4f,0x0d,0x30,0xd0,0x0f,0x0f,0x48,0xce, +0x17,0x11,0x00,0xeb,0x2e,0xb4,0x29,0x49,0x9c,0x31,0x10,0xce,0x32,0xaa,0x11,0x11, +0x2e,0x36,0x09,0xe8,0x25,0xb7,0x2a,0x86,0x24,0xf8,0x4b,0x46,0x24,0x39,0x2b,0xe5, +0x2b,0x99,0x4c,0xa6,0x0a,0xd8,0x2d,0x67,0x0a,0x37,0x2d,0xe8,0x09,0xb5,0x0e,0x69, +0x9c,0x31,0x10,0xa0,0x31,0xaa,0x12,0x11,0x12,0xa8,0x3d,0x58,0x12,0x24,0x2d,0xdc, +0x31,0xe0,0x4d,0xe0,0x42,0x1b,0x3d,0xa5,0x32,0x57,0x2c,0xe9,0x33,0x14,0x2c,0x2c, +0x34,0x11,0x2b,0x2f,0x45,0x0e,0x49,0xf1,0x9c,0x31,0x10,0xb5,0x31,0xaa,0x21,0x11, +0x46,0x4d,0x48,0xb2,0x37,0x8c,0x37,0x72,0x48,0xcd,0x26,0x71,0x4a,0x0e,0x25,0x2f, +0x4b,0x10,0x44,0x2d,0x3c,0x12,0x33,0x6a,0x4c,0x96,0x32,0xe7,0x4d,0x19,0x32,0x63, +0x9c,0x31,0x10,0xa0,0x31,0xaa,0x12,0x11,0x3d,0x5d,0x22,0x5f,0x3d,0x61,0x32,0x5b, +0x4d,0x24,0x32,0xd8,0x3c,0xa8,0x23,0x55,0x3b,0xeb,0x34,0x12,0x3b,0x2d,0x35,0x10, +0x2a,0x2f,0x46,0x0f,0x29,0x30,0x37,0x0e,0x9c,0x31,0x10,0x1a,0x32,0xaa,0x12,0x11, +0x2c,0x18,0x2c,0x07,0x2b,0x97,0x2c,0x87,0x2b,0x17,0x2d,0x07,0x2a,0x96,0x2d,0x68, +0x2a,0x35,0x2d,0xea,0x21,0xd4,0x0e,0x2b,0x21,0x92,0x2e,0x4d,0x29,0x71,0x2e,0x6e, +0x9c,0x31,0x10,0xb1,0x30,0xa9,0x12,0x11,0x25,0xbc,0x39,0xc5,0x25,0xb1,0x19,0x52, +0x06,0xa1,0x38,0x5c,0x27,0x99,0x17,0x69,0x29,0x0d,0x35,0x70,0x2a,0x85,0x33,0xf5, +0x2c,0x81,0x31,0xf8,0x2e,0x81,0x2f,0x79,0x9c,0x31,0x10,0x2c,0x31,0xa9,0x12,0x11, +0x11,0x01,0x2d,0x78,0x33,0x05,0x2b,0xf6,0x34,0x89,0x29,0xed,0x36,0x11,0x08,0x61, +0x37,0x9d,0x27,0x55,0x38,0xa9,0x26,0xc9,0x38,0xb5,0x26,0x3d,0x38,0xc5,0x26,0xb1, +0x9c,0x31,0x10,0xe5,0x31,0xa9,0x11,0x10,0x3c,0x54,0x33,0xc9,0x2b,0xd7,0x24,0x66, +0x3b,0x39,0x25,0x24,0x3a,0x5b,0x36,0x02,0x29,0x5c,0x17,0x01,0x38,0x5d,0x38,0x01, +0x37,0x3d,0x39,0x22,0x26,0x3c,0x3a,0x03,0x9c,0x31,0x10,0xdc,0x32,0xa9,0x12,0x21, +0x22,0xba,0x2d,0x65,0x22,0x58,0x2d,0xa8,0x2a,0x15,0x25,0xea,0x29,0xd2,0x2e,0x0e, +0x29,0xcf,0x26,0x11,0x21,0xec,0x2d,0xf4,0x22,0x09,0x2d,0xb7,0x2a,0x66,0x25,0x59, +0x9c,0x31,0x10,0x39,0x31,0xa9,0x21,0x11,0x2b,0x11,0x33,0x69,0x2d,0x0d,0x31,0x6d, +0x2f,0x0a,0x2f,0x70,0x31,0x0d,0x2d,0x6d,0x33,0x11,0x2b,0x65,0x34,0x95,0x29,0xdd, +0x36,0x21,0x28,0xd5,0x37,0x2d,0x27,0xc9,0x9c,0x31,0x10,0xe5,0x31,0xa9,0x11,0x10, +0x3c,0x0e,0x33,0xcf,0x3c,0x11,0x33,0xec,0x2b,0xd4,0x34,0x29,0x2b,0x57,0x34,0xc6, +0x3a,0xb9,0x35,0x84,0x39,0xfb,0x26,0x43,0x39,0x1c,0x27,0x42,0x38,0x1c,0x38,0x42, +0x9c,0x31,0x10,0x96,0x32,0xa9,0x12,0x11,0x2b,0x9c,0x0c,0x82,0x2b,0x1b,0x2d,0x04, +0x2a,0x9a,0x2d,0x65,0x2a,0x57,0x2d,0xa8,0x22,0x15,0x2d,0xeb,0x21,0xf2,0x2d,0xee, +0x29,0xef,0x25,0xf1,0x29,0xec,0x2d,0xd4,0x9c,0x31,0x10,0xbe,0x32,0x99,0x12,0x11, +0x34,0x29,0x33,0x97,0x30,0x86,0x37,0x39,0x30,0xe5,0x36,0xda,0x45,0x43,0x32,0x5b, +0x35,0xc3,0x25,0xdb,0x36,0x43,0x39,0x5b,0x26,0xa4,0x34,0xf9,0x3b,0x26,0x34,0x97, +0x9c,0x31,0x10,0x11,0x31,0x99,0x21,0x11,0x3d,0xa1,0x31,0x55,0x3e,0xa9,0x20,0xc9, +0x4f,0x35,0x20,0x3d,0x4f,0x41,0x30,0xb1,0x3e,0xcd,0x31,0x29,0x4d,0xd5,0x42,0x1d, +0x3c,0x61,0x43,0x9a,0x3a,0xe5,0x35,0x11,0x9c,0x31,0x10,0xd0,0x31,0x99,0x11,0x11, +0x36,0x5a,0x35,0xc4,0x45,0xfa,0x4a,0x24,0x35,0x7a,0x3a,0x85,0x35,0x19,0x36,0xe6, +0x38,0xd7,0x37,0x28,0x34,0x95,0x27,0x6a,0x30,0x73,0x37,0x8c,0x30,0x50,0x37,0x8f, +0x9c,0x31,0x10,0x11,0x31,0x99,0x21,0x11,0x41,0x39,0x2e,0x45,0x41,0xb1,0x2d,0xcd, +0x22,0x29,0x2c,0xd5,0x33,0x21,0x3b,0xdd,0x24,0x19,0x2a,0x61,0x25,0x99,0x39,0x65, +0x27,0x15,0x37,0xe4,0x38,0x95,0x36,0x65,0x9c,0x31,0x10,0xd0,0x31,0x99,0x11,0x11, +0x32,0x66,0x25,0x58,0x36,0xc7,0x24,0xf7,0x46,0xe8,0x34,0xd5,0x33,0x2a,0x34,0xb3, +0x47,0x4c,0x48,0x91,0x47,0x4e,0x34,0x8f,0x47,0x50,0x34,0x8d,0x37,0x52,0x34,0xac, +0x9c,0x31,0x10,0x00,0x31,0x99,0x11,0x00,0x47,0x33,0x34,0xca,0x46,0xf5,0x45,0x09, +0x46,0xb6,0x35,0x27,0x46,0x97,0x35,0x87,0x46,0x37,0x35,0xc6,0x45,0xf8,0x46,0x06, +0x35,0xb7,0x3a,0x47,0x45,0x77,0x46,0x88,0x9c,0x31,0x10,0x6b,0x30,0x98,0x01,0x10, +0x25,0x3c,0x2b,0x04,0x44,0x77,0x2b,0xca,0x33,0xb2,0x3c,0x4f,0x33,0x6c,0x3c,0x95, +0x43,0x26,0x4c,0xdc,0x53,0x1f,0x4c,0xa2,0x43,0x19,0x4c,0x68,0x43,0x53,0x4c,0x2d, +0x9c,0x31,0x10,0x0a,0x30,0x88,0x11,0x00,0x30,0x0e,0x3f,0x33,0x41,0x4a,0x4d,0xb6, +0x22,0xc6,0x4c,0x3a,0x44,0x43,0x4a,0x7c,0x36,0x42,0x48,0xbd,0x48,0x02,0x36,0xfc, +0x59,0xc3,0x34,0xfa,0x3b,0x85,0x43,0x78,0x9c,0x31,0x10,0xc2,0x30,0x98,0x11,0x11, +0x4a,0x48,0x34,0xf4,0x3b,0x0c,0x34,0x6f,0x3b,0x91,0x33,0xea,0x2b,0xd6,0x43,0xe5, +0x2b,0xdc,0x33,0x9f,0x3b,0xe2,0x43,0xd9,0x4b,0xa7,0x44,0x14,0x4b,0x6c,0x34,0x8f, +0x9c,0x31,0x10,0x47,0x31,0x88,0x11,0x11,0x33,0x58,0x34,0xa5,0x46,0xf9,0x45,0x04, +0x36,0x9a,0x31,0x63,0x42,0x3b,0x41,0xc3,0x35,0xdb,0x4a,0x23,0x45,0x9b,0x46,0x64, +0x45,0x5a,0x46,0xa4,0x41,0x19,0x46,0xc5,0x9c,0x31,0x10,0x46,0x30,0x88,0x10,0x00, +0x43,0xf2,0x4c,0x0d,0x43,0x70,0x4c,0x8f,0x32,0xee,0x3d,0x11,0x32,0x6c,0x3d,0x93, +0x31,0xe9,0x3e,0x16,0x41,0x67,0x3e,0x99,0x30,0xe3,0x3f,0x1c,0x40,0xa0,0x4f,0x61, +0x9c,0x31,0x10,0xaf,0x21,0x88,0x11,0x01,0x14,0x0d,0x17,0xb2,0x04,0x2b,0x03,0x94, +0x04,0x49,0x17,0x76,0x24,0xa7,0x07,0x18,0x00,0xe5,0x12,0xd9,0x11,0x44,0x06,0x5a, +0x19,0xa4,0x09,0xfa,0x16,0x04,0x05,0x9a,0x9c,0x31,0x10,0x0a,0x30,0x88,0x11,0x00, +0x4a,0x09,0x44,0xf4,0x3b,0x8c,0x43,0xb1,0x4c,0xcf,0x52,0xad,0x4d,0x93,0x41,0xe9, +0x4e,0x58,0x41,0x64,0x4e,0x9d,0x41,0x5f,0x4e,0x62,0x41,0x9a,0x3d,0xe6,0x42,0x16, +0x9c,0x31,0x10,0x84,0x32,0x88,0x01,0x01,0x47,0x35,0x44,0xc8,0x46,0xf6,0x35,0x07, +0x46,0xb8,0x45,0x66,0x36,0x58,0x39,0xa5,0x45,0xf9,0x42,0x06,0x45,0x98,0x46,0x66, +0x35,0x57,0x46,0xc7,0x44,0xf6,0x43,0x09,0x9c,0x31,0x10,0xc1,0x31,0x87,0x11,0x11, +0x44,0xcc,0x37,0x43,0x34,0x9a,0x47,0x55,0x44,0x98,0x47,0x67,0x44,0x96,0x47,0x49, +0x44,0xb4,0x43,0x2b,0x44,0xe2,0x46,0xfc,0x41,0x11,0x32,0xae,0x41,0x60,0x46,0x6e, +0x9c,0x31,0x10,0x3e,0x31,0x88,0x01,0x01,0x35,0xa7,0x46,0x17,0x45,0xe7,0x35,0xb7, +0x46,0x47,0x39,0x76,0x46,0x88,0x45,0x35,0x46,0xc9,0x44,0xf4,0x4a,0xeb,0x44,0xd2, +0x57,0x0c,0x44,0xd1,0x47,0x0e,0x34,0xcf,0x9c,0x31,0x10,0xf5,0x30,0x87,0x01,0x10, +0x4e,0x51,0x49,0xac,0x56,0x14,0x39,0xe9,0x45,0xd7,0x42,0x26,0x3d,0x79,0x42,0xa4, +0x45,0x1b,0x4b,0x02,0x54,0x9c,0x43,0x82,0x44,0x1c,0x44,0x02,0x4b,0x9c,0x4c,0x62, +0x9c,0x31,0x10,0x7d,0x30,0x77,0x01,0x10,0x44,0xed,0x3b,0x8e,0x43,0x69,0x3d,0x15, +0x41,0xe1,0x4e,0x1d,0x40,0xd6,0x4e,0xa9,0x40,0x4d,0x4f,0x31,0x30,0x40,0x3f,0x3d, +0x30,0x39,0x3e,0xc9,0x40,0xad,0x3e,0x51,0x9c,0x31,0x10,0x31,0x30,0x77,0x00,0x10, +0x41,0xa4,0x3d,0xd9,0x42,0x9d,0x4c,0x61,0x33,0x95,0x3b,0x65,0x35,0x11,0x39,0xe9, +0x46,0x11,0x48,0x69,0x37,0x92,0x36,0xe9,0x49,0x11,0x45,0xe5,0x4a,0x15,0x44,0x61, +0x9c,0x31,0x10,0x58,0x20,0x77,0x01,0x10,0x0b,0x99,0x03,0x5e,0x1c,0x21,0x02,0xd6, +0x1d,0x29,0x12,0x51,0x1d,0xad,0x11,0xc8,0x0d,0xb5,0x01,0xc1,0x0d,0xbd,0x11,0xb9, +0x1d,0xc4,0x12,0x31,0x0d,0x4d,0x12,0xa9,0x9c,0x31,0x10,0xd9,0x20,0x77,0x00,0x00, +0x1e,0x55,0x11,0xc9,0x1d,0xf6,0x22,0x28,0x15,0x77,0x0a,0xa7,0x0c,0xf8,0x0b,0x26, +0x0c,0x58,0x03,0xc6,0x0b,0xd8,0x0c,0x46,0x13,0x38,0x1c,0xe7,0x12,0xb7,0x15,0x68, +0x9c,0x31,0x10,0x56,0x20,0x76,0x00,0x00,0x1a,0x5d,0x1d,0xc3,0x09,0xfa,0x0e,0x25, +0x19,0x97,0x2e,0x49,0x21,0x94,0x36,0x6c,0x11,0x91,0x1e,0x2f,0x11,0xce,0x05,0xb2, +0x02,0x6c,0x0d,0x33,0x13,0x0b,0x14,0x73,0x9c,0x31,0x10,0xc1,0x20,0x67,0x00,0x00, +0x13,0x8d,0x1b,0xb0,0x14,0xce,0x02,0xaf,0x1d,0x90,0x12,0x0d,0x1d,0xf2,0x11,0xeb, +0x1d,0xd3,0x12,0x6a,0x2d,0x15,0x23,0x28,0x24,0x16,0x1c,0x67,0x1a,0xd7,0x1d,0xa7, +0x9c,0x31,0x10,0x95,0x20,0x77,0x01,0x00,0x05,0x5c,0x0a,0x9d,0x04,0x59,0x1b,0xa1, +0x13,0x55,0x1c,0x29,0x12,0xcd,0x1c,0xad,0x22,0xc9,0x1d,0x34,0x22,0x41,0x2d,0x3d, +0x12,0x39,0x1c,0xc5,0x12,0xb4,0x1c,0xc9,0x9c,0x31,0x10,0xd9,0x20,0x77,0x00,0x00, +0x11,0x8b,0x0e,0x34,0x11,0xea,0x15,0xd5,0x12,0x49,0x1d,0x56,0x1a,0xc8,0x1c,0xd6, +0x1b,0x47,0x24,0x57,0x13,0xc7,0x0b,0xd7,0x14,0x47,0x2b,0x57,0x24,0xc8,0x32,0xf6, +0x9c,0x31,0x10,0x1a,0x20,0x76,0x01,0x00,0x2a,0x08,0x24,0xed,0x2b,0x11,0x14,0x65, +0x0b,0x99,0x13,0xd8,0x1b,0xa4,0x23,0x4d,0x1c,0x35,0x23,0x41,0x1c,0x41,0x23,0x35, +0x0b,0xcd,0x13,0xa9,0x2b,0xd5,0x14,0x1d,0x9c,0x31,0x10,0x02,0x20,0x66,0x01,0x00, +0x3e,0x61,0x32,0x15,0x4c,0xe8,0x33,0x8d,0x2b,0x6e,0x25,0x09,0x39,0x71,0x37,0x09, +0x27,0x71,0x39,0x09,0x25,0xf1,0x2a,0x8d,0x23,0xe9,0x2c,0x11,0x12,0x65,0x1d,0x99, +0x9c,0x31,0x10,0x4e,0x20,0x66,0x00,0x00,0x30,0xb6,0x1f,0x69,0x28,0x34,0x4f,0xcc, +0x38,0x11,0x3f,0xcf,0x38,0x0e,0x3f,0xd1,0x18,0x4b,0x2f,0x74,0x28,0xa9,0x26,0xf7, +0x09,0x47,0x1e,0x38,0x22,0x05,0x2d,0x7a,0x9c,0x31,0x10,0x83,0x20,0x66,0x00,0x10, +0x25,0x91,0x39,0x69,0x37,0x11,0x37,0x69,0x29,0x10,0x35,0xe9,0x3a,0x95,0x24,0x65, +0x2c,0x19,0x32,0xdd,0x3d,0x21,0x21,0xd5,0x3e,0x2d,0x31,0x48,0x2e,0xb5,0x20,0xc1, +0x9c,0x31,0x10,0x4e,0x20,0x66,0x00,0x00,0x1f,0x70,0x30,0x8d,0x2f,0x32,0x30,0xca, +0x36,0xd5,0x21,0x48,0x36,0x37,0x39,0xe7,0x45,0x98,0x4a,0xa6,0x44,0xd9,0x33,0x65, +0x1c,0x19,0x3c,0x45,0x3b,0x59,0x1d,0x05,0x9c,0x31,0x10,0x4e,0x20,0x66,0x00,0x00, +0x22,0x98,0x35,0xa6,0x31,0xf7,0x36,0x28,0x29,0x75,0x26,0xaa,0x31,0x13,0x46,0xec, +0x28,0xd1,0x17,0x0e,0x20,0xcf,0x2f,0x10,0x28,0xed,0x2e,0xd2,0x29,0x2b,0x36,0x74, +0x9c,0x31,0x10,0x02,0x20,0x66,0x01,0x00,0x33,0x25,0x3b,0xd9,0x44,0x1e,0x2a,0xdd, +0x05,0x1d,0x19,0xe1,0x26,0x99,0x28,0x61,0x37,0x99,0x27,0x61,0x19,0x19,0x15,0xe1, +0x1a,0x1d,0x24,0xdd,0x2b,0x21,0x33,0xd9,0x9c,0x31,0x10,0xc2,0x20,0x65,0x00,0x00, +0x3e,0x03,0x39,0xb9,0x2e,0x46,0x29,0x76,0x36,0x8a,0x31,0x32,0x46,0xae,0x31,0x2f, +0x46,0xb1,0x41,0x4b,0x36,0x95,0x41,0x67,0x36,0x38,0x41,0xc4,0x45,0xfb,0x4a,0x22, +0x9c,0x31,0x10,0x2a,0x20,0x56,0x01,0x00,0x3e,0xd9,0x41,0x21,0x4d,0xdd,0x4a,0x1d, +0x44,0xde,0x3b,0x1e,0x33,0xdd,0x3c,0x1d,0x3a,0xde,0x3d,0x21,0x32,0x59,0x3d,0xa5, +0x39,0xd1,0x35,0xa9,0x31,0xcd,0x3d,0xb1,0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00, +0x35,0x14,0x2e,0x8c,0x2d,0x72,0x2e,0x0d,0x2e,0x11,0x25,0x8e,0x2a,0x91,0x29,0x0c, +0x33,0x12,0x3c,0x8b,0x4b,0x95,0x40,0x48,0x27,0x98,0x1c,0x45,0x2b,0x9b,0x34,0x62, +0x9c,0x31,0x10,0x83,0x20,0x66,0x00,0x10,0x2a,0x59,0x35,0x9e,0x29,0x5d,0x26,0x9d, +0x18,0x5c,0x27,0x9d,0x37,0x5c,0x39,0x1d,0x36,0x5d,0x49,0xa1,0x35,0x59,0x2a,0xa1, +0x34,0x55,0x3b,0x29,0x43,0xd1,0x3c,0x2d,0x9c,0x31,0x10,0xc2,0x20,0x65,0x00,0x00, +0x39,0x95,0x4e,0x4a,0x31,0x72,0x46,0x6e,0x41,0x6f,0x46,0x71,0x41,0x8c,0x4e,0x54, +0x41,0xa9,0x46,0x17,0x41,0xe6,0x55,0xd9,0x42,0x44,0x45,0x7b,0x3a,0xa2,0x3c,0xfd, +0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00,0x39,0x00,0x42,0x9e,0x39,0x80,0x42,0x1e, +0x3d,0xe0,0x45,0xbe,0x42,0x60,0x39,0x3d,0x36,0xc1,0x30,0xdc,0x33,0x43,0x30,0x7a, +0x2f,0x65,0x2c,0x58,0x27,0xa7,0x28,0x16,0x9c,0x31,0x10,0xc2,0x20,0x65,0x00,0x00, +0x25,0xe9,0x31,0xf3,0x26,0x0c,0x31,0xd1,0x36,0x0e,0x31,0xce,0x36,0x11,0x29,0xeb, +0x35,0xf4,0x32,0x09,0x35,0xb6,0x32,0x27,0x35,0x78,0x3a,0x85,0x35,0x3a,0x3a,0xc4, +0x9c,0x31,0x10,0xa6,0x20,0x55,0x01,0x00,0x35,0xb6,0x2a,0x46,0x34,0xf6,0x2b,0x06, +0x2c,0x36,0x2c,0x06,0x3b,0x76,0x34,0xc5,0x42,0xb5,0x3d,0x85,0x39,0xf1,0x46,0x49, +0x39,0x31,0x3e,0xcd,0x30,0xa9,0x47,0x11,0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00, +0x44,0x34,0x3f,0xcb,0x48,0x12,0x4b,0xce,0x50,0x0f,0x43,0xd0,0x44,0x0d,0x43,0xb2, +0x38,0x2a,0x47,0x95,0x4c,0x69,0x43,0x57,0x34,0xa6,0x3a,0xf9,0x39,0x05,0x42,0x9a, +0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00,0x41,0x64,0x42,0x5a,0x35,0xc4,0x39,0xfb, +0x4a,0x24,0x25,0x9a,0x3a,0x85,0x39,0x39,0x36,0xc6,0x3c,0xf7,0x3f,0x27,0x38,0xb6, +0x4f,0x69,0x48,0x74,0x43,0x8b,0x40,0x51,0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00, +0x47,0x8e,0x48,0x4f,0x43,0x90,0x38,0x4d,0x4b,0x92,0x48,0x6b,0x3f,0x54,0x4c,0xa9, +0x4b,0x16,0x40,0xe7,0x42,0xd7,0x45,0x26,0x3a,0x79,0x35,0x85,0x3e,0x19,0x41,0xe5, +0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00,0x41,0xb9,0x3e,0x45,0x45,0x78,0x46,0xa6, +0x4d,0x17,0x42,0xe8,0x44,0xd6,0x43,0x29,0x44,0xb4,0x43,0x4c,0x50,0x71,0x4f,0x4e, +0x48,0x8f,0x4f,0x50,0x44,0x8e,0x3f,0x51,0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00, +0x44,0xac,0x47,0x14,0x38,0xc9,0x4e,0xf5,0x4d,0x08,0x4a,0xb6,0x4d,0x47,0x52,0x77, +0x4d,0xa7,0x56,0x18,0x51,0xe6,0x4d,0xd8,0x52,0x27,0x45,0x97,0x42,0x67,0x39,0x56, +0x9c,0x31,0x10,0x65,0x20,0x54,0x00,0x00,0x42,0xa2,0x4d,0x1b,0x4e,0xe5,0x48,0xd8, +0x4b,0x08,0x54,0xd5,0x53,0x2b,0x4c,0xb2,0x4f,0x2e,0x48,0xce,0x4e,0xf2,0x3c,0xeb, +0x4a,0xb4,0x49,0x49,0x46,0x76,0x45,0xa8,0x9c,0x31,0x10,0x7d,0x20,0x44,0x00,0x00, +0x46,0x36,0x3e,0x08,0x3d,0x75,0x46,0xca,0x44,0xd2,0x3f,0x2e,0x48,0x6e,0x4f,0x72, +0x48,0x4a,0x4b,0x96,0x48,0x66,0x4f,0x39,0x50,0xe3,0x4e,0xbd,0x4d,0x60,0x4e,0x1e, +0x9c,0x31,0x10,0x85,0x10,0x55,0x00,0x00,0x0c,0x07,0x1b,0x76,0x2c,0xe8,0x2a,0xb6, +0x1d,0x48,0x22,0x55,0x1d,0xc9,0x11,0xf4,0x16,0x2b,0x19,0x92,0x06,0x4d,0x11,0x90, +0x2e,0x6f,0x19,0x8f,0x26,0x50,0x39,0x8d,0x9c,0x31,0x10,0x0a,0x10,0x54,0x00,0x00, +0x26,0x35,0x39,0xe7,0x2d,0xd8,0x2a,0x25,0x45,0x7a,0x1a,0x83,0x0d,0x1c,0x0b,0x02, +0x0c,0xbd,0x2b,0x81,0x34,0x1d,0x24,0x00,0x2b,0x9d,0x34,0x81,0x2b,0x3c,0x34,0xe2, +0x9c,0x31,0x10,0x65,0x20,0x54,0x00,0x00,0x55,0x5b,0x4e,0xa4,0x49,0x39,0x4e,0xc6, +0x51,0x16,0x46,0xe9,0x40,0xf4,0x42,0xec,0x48,0xf1,0x4a,0xef,0x38,0xee,0x42,0xf2, +0x48,0xeb,0x4a,0xd4,0x55,0x09,0x52,0xb6,0x9c,0x31,0x10,0x12,0x10,0x44,0x00,0x00, +0x20,0xe7,0x26,0x98,0x21,0x85,0x26,0x19,0x1a,0x24,0x1d,0x5a,0x1a,0xe4,0x0c,0x9b, +0x13,0xa3,0x1b,0xdb,0x24,0x43,0x23,0x3b,0x2d,0x03,0x12,0x7a,0x2d,0xa5,0x29,0xf8, +0x9c,0x31,0x10,0x12,0x10,0x44,0x00,0x00,0x36,0x26,0x41,0x77,0x36,0x88,0x31,0x15, +0x36,0xea,0x28,0xd3,0x2f,0x2c,0x18,0xb1,0x27,0x4e,0x10,0x8f,0x17,0x30,0x08,0xad, +0x27,0x12,0x20,0xeb,0x26,0xd4,0x19,0x29,0x9c,0x31,0x10,0x12,0x10,0x44,0x00,0x00, +0x2e,0x95,0x09,0x88,0x1e,0x16,0x11,0xe7,0x1d,0x97,0x1a,0x66,0x25,0x18,0x33,0x06, +0x3c,0x99,0x33,0x65,0x2c,0x39,0x2c,0x05,0x33,0x99,0x34,0x86,0x2b,0x18,0x35,0x07, +0x9c,0x31,0x10,0x12,0x10,0x44,0x00,0x00,0x2a,0x97,0x35,0x87,0x3a,0x36,0x2d,0xc8, +0x31,0xf5,0x2e,0x0a,0x31,0xb4,0x2e,0x6b,0x21,0x52,0x26,0x8d,0x19,0x50,0x2e,0x8e, +0x29,0x4f,0x2e,0x90,0x29,0x6d,0x26,0x52,0x9c,0x31,0x10,0x98,0x10,0x43,0x00,0x00, +0x31,0x88,0x26,0x17,0x21,0xc5,0x2d,0xda,0x22,0x23,0x25,0x9c,0x2a,0x81,0x25,0x3d, +0x1b,0x00,0x24,0x9e,0x23,0x80,0x24,0x1e,0x1c,0x00,0x23,0x9e,0x24,0x60,0x2b,0x3d, +0x9c,0x31,0x10,0x98,0x10,0x43,0x00,0x00,0x3c,0xc2,0x3a,0xdc,0x2d,0x23,0x22,0x7a, +0x35,0x86,0x2a,0x37,0x25,0xa8,0x2a,0x15,0x25,0xea,0x29,0xf2,0x1d,0xed,0x32,0x0f, +0x35,0xf0,0x3a,0x0d,0x35,0xd2,0x2a,0x2b,0x9c,0x31,0x10,0xd0,0x10,0x33,0x00,0x00, +0x2f,0x94,0x38,0x68,0x3b,0x57,0x2c,0xa6,0x2b,0x19,0x2d,0x05,0x32,0xba,0x21,0x64, +0x36,0x5b,0x35,0xc3,0x31,0xfb,0x3e,0x24,0x41,0x9a,0x52,0x65,0x4d,0x39,0x5a,0xe5, +0x9c,0x31,0x10,0xd0,0x10,0x33,0x00,0x00,0x4c,0xd7,0x5b,0x07,0x58,0xb6,0x4f,0x49, +0x50,0x94,0x3f,0x6b,0x30,0x72,0x33,0x8d,0x3c,0x50,0x3b,0x90,0x3c,0x4d,0x2f,0x92, +0x40,0x6b,0x33,0x74,0x34,0x89,0x43,0x55,0x9c,0x31,0x10,0xd0,0x10,0x33,0x00,0x00, +0x44,0xa8,0x4f,0x37,0x44,0xc6,0x4e,0xf9,0x4c,0xe5,0x52,0xda,0x49,0x24,0x56,0x9b, +0x45,0x43,0x3a,0x7c,0x35,0xa1,0x36,0x1d,0x35,0xe1,0x39,0xbd,0x4a,0x41,0x39,0x7d, +0x9c,0x31,0x10,0x98,0x10,0x43,0x00,0x00,0x3c,0xa2,0x43,0x1c,0x34,0xe2,0x32,0xdb, +0x3d,0x44,0x4a,0x79,0x35,0x86,0x42,0x57,0x4d,0x89,0x52,0x34,0x4d,0xca,0x49,0xf3, +0x45,0xec,0x51,0xf1,0x4d,0xef,0x42,0x0e,0x9c,0x31,0x10,0xd0,0x10,0x33,0x00,0x00, +0x4b,0xb1,0x50,0x2c,0x5b,0x93,0x48,0x6a,0x53,0x75,0x48,0x88,0x4f,0x57,0x4c,0xa6, +0x47,0x18,0x4d,0x05,0x36,0xb9,0x45,0x45,0x46,0x5a,0x41,0x84,0x46,0x1a,0x41,0xe4, +0x9c,0x31,0x10,0xd0,0x10,0x33,0x00,0x00,0x4d,0xba,0x46,0x44,0x51,0x79,0x46,0x85, +0x45,0x38,0x46,0xc6,0x44,0xf7,0x47,0x07,0x34,0xb6,0x3f,0x49,0x44,0x94,0x4f,0x4b, +0x44,0x72,0x47,0x6d,0x38,0x90,0x4b,0x6f,0x9c,0x31,0x10,0x7a,0x00,0x32,0x00,0x00, +0x08,0xb7,0x35,0xd0,0x0a,0xa9,0x34,0xda,0x0b,0xa0,0x30,0xe8,0x10,0x11,0x2e,0x71, +0x12,0x0c,0x2a,0xfc,0x17,0x86,0x26,0xfb,0x1a,0x00,0x22,0x7d,0x1f,0x03,0x1e,0xfb, +0x9c,0x31,0x10,0x7a,0x00,0x32,0x00,0x00,0x23,0x04,0x1b,0x79,0x27,0x08,0x16,0x74, +0x2a,0x8f,0x13,0x69,0x2d,0x1b,0x10,0xdf,0x2f,0x22,0x0f,0xd8,0x30,0xad,0x0e,0xcd, +0x30,0xba,0x0f,0xbf,0x70,0xc8,0x4f,0x33,0x9c,0x31,0x10,0x62,0x00,0x22,0x00,0x00, +0x3e,0xd2,0x03,0xa7,0x3a,0x5a,0x47,0x21,0x34,0xe2,0x4c,0x99,0x2f,0xe8,0x12,0x12, +0x2b,0x6c,0x1a,0x11,0x22,0xf2,0x20,0x12,0x1c,0xed,0x26,0x12,0x17,0x6c,0x2c,0x17, +0x9c,0x31,0x10,0x62,0x00,0x22,0x00,0x00,0x11,0x62,0x31,0x9e,0x0a,0x5f,0x35,0xa5, +0x09,0x56,0x38,0xac,0x07,0x4d,0x39,0x35,0x06,0xc2,0x38,0x42,0x07,0x39,0x36,0xc7, +0x09,0xb1,0x35,0xd1,0x0c,0x2a,0x2f,0xd8,0x9c,0x31,0x10,0x4a,0x00,0x12,0x00,0x00, +0x02,0x28,0x37,0xdb,0x0f,0x25,0x70,0xdc,0x13,0xa0,0x66,0xdd,0x5e,0x1f,0x1c,0xdd, +0x25,0xa1,0x17,0x5b,0x6c,0xa2,0x11,0x5a,0x30,0x25,0x09,0xd5,0x38,0x29,0x06,0x50, +0x9c,0x31,0x10,0xee,0x00,0x21,0x00,0x00,0x2f,0x52,0x50,0xeb,0x70,0x97,0x4e,0xa5, +0x31,0x9a,0x0d,0xa0,0x30,0x60,0x51,0x1b,0x2f,0x25,0x10,0xd6,0x2d,0x69,0x52,0xd1, +0x6a,0x6d,0x16,0x91,0x28,0xef,0x18,0xcc,0x9c,0x31,0x10,0xc6,0x00,0x11,0x00,0x00, +0x1a,0x72,0x15,0xce,0x19,0x70,0x16,0x8b,0x18,0x71,0x17,0x8c,0x56,0xf5,0x58,0xce, +0x56,0x31,0x1a,0x0f,0x15,0xb0,0x5a,0x90,0x54,0x6d,0x5b,0x13,0x54,0x2b,0x5c,0x95, +0x9c,0x31,0x10,0x49,0x00,0x10,0x00,0x00,0x49,0xa9,0x4e,0x61,0x49,0xb5,0x4e,0x25, +0x49,0xb5,0x4e,0x15,0x49,0x85,0x4e,0x45,0x49,0x85,0x2e,0x15,0x4a,0x05,0x4d,0xa9, +0x4a,0x21,0x4d,0x29,0x4a,0xd1,0x4d,0x19,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x50,0x55,0x1a,0x55,0x50,0x55,0x56,0x55,0x54,0x55,0x56,0x55,0x54,0x55,0x56,0x55, +0x54,0x55,0x56,0x55,0x58,0x55,0x52,0x55,0x58,0x55,0x56,0x55,0x58,0x55,0x51,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x59,0x55,0x51,0x55,0x59,0x55,0x51,0x55, +0x59,0x55,0x51,0x55,0x59,0x55,0x51,0x55,0x59,0x55,0x51,0x55,0x59,0x55,0x51,0x55, +0x59,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x55,0x56,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, diff --git a/config/_default_cfg_src_/res/cn/SOUND_FIVE.txt b/config/_default_cfg_src_/res/cn/SOUND_FIVE.txt new file mode 100644 index 0000000..6875884 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_FIVE.txt @@ -0,0 +1,120 @@ +0x9c,0x31,0x10,0x90,0x31,0x22,0x00,0x00,0x7b,0x77,0x7b,0x77,0x83,0x77,0x82,0x77, +0xb4,0x55,0xbb,0x58,0xbc,0x67,0xcd,0x75,0xb3,0x68,0x8d,0x68,0xba,0x73,0x9e,0x75, +0x92,0xb9,0x83,0x77,0xbc,0x78,0xb1,0x7a,0x9c,0x31,0x10,0x5e,0xb4,0x12,0x00,0x00, +0x7f,0x81,0x7f,0x79,0x7f,0x74,0x80,0x65,0x80,0x61,0x83,0x94,0x89,0x30,0xa0,0xc0, +0xb0,0x66,0x7d,0x3a,0x35,0xa5,0x2b,0x21,0x67,0xc9,0xa6,0x58,0xb6,0x75,0xad,0x85, +0x9c,0x31,0x10,0x15,0xc5,0x24,0x00,0x00,0x85,0x6b,0x68,0x4b,0x48,0xa2,0x38,0x2c, +0x70,0x85,0xc8,0x53,0xd2,0x8a,0xa5,0x62,0x91,0x6b,0x87,0x8b,0x4f,0x4a,0x1b,0x6a, +0x32,0x4c,0x9b,0xac,0xd9,0x4b,0xba,0x8a,0x9c,0x31,0x10,0x2a,0xc7,0x34,0x00,0x00, +0x8e,0x75,0x90,0x65,0x98,0x95,0x59,0x25,0x1b,0xa5,0x19,0x54,0x73,0x85,0xdc,0x69, +0xdb,0x79,0x97,0x85,0x7b,0x55,0x9d,0x95,0x8f,0x65,0x34,0xc9,0x13,0x38,0x33,0x79, +0x9c,0x31,0x10,0x0a,0xc8,0x44,0x00,0x00,0xa9,0x86,0xf0,0x75,0xbf,0x74,0x79,0x85, +0x81,0x65,0xac,0xa5,0x74,0x25,0x24,0xc5,0x11,0x46,0x47,0x71,0xca,0x71,0xf3,0x75, +0xa5,0x75,0x70,0x75,0x97,0x75,0xab,0x85,0x9c,0x31,0x10,0xe8,0xc7,0x43,0x00,0x00, +0x51,0x2c,0x1d,0x4a,0x11,0xab,0x65,0xd2,0xe7,0xab,0xe6,0x43,0x8b,0x3b,0x76,0xab, +0xaa,0x53,0x9c,0x9a,0x44,0xd9,0x1b,0x29,0x12,0xb1,0x7b,0xca,0xf5,0xac,0xdb,0x3b, +0x9c,0x31,0x10,0x9e,0xc7,0x34,0x10,0x00,0x7e,0x85,0x7d,0x45,0xb0,0xb5,0x92,0x15, +0x3f,0xc1,0x15,0x4a,0x13,0x61,0x8a,0x90,0xfd,0x69,0xd1,0x72,0x77,0x95,0x84,0x44, +0xb0,0xb5,0x8d,0x36,0x43,0xba,0x13,0x59,0x9c,0x31,0x10,0x4b,0xc6,0x44,0x10,0x00, +0x0f,0x40,0x88,0xa8,0xfc,0x55,0xd1,0x55,0x79,0xc5,0x88,0x24,0xaf,0xd5,0x8a,0x16, +0x46,0xc5,0x13,0x45,0x10,0x79,0x89,0x65,0xfa,0x85,0xce,0x45,0x76,0xc5,0x8b,0x44, +0x9c,0x31,0x10,0xff,0xc6,0x44,0x00,0x00,0xaa,0x85,0x87,0x76,0x50,0x95,0x19,0x65, +0x11,0x90,0x81,0x65,0xf5,0x86,0xce,0x45,0x75,0xb4,0x85,0x75,0x9b,0x46,0x95,0xd5, +0x67,0x24,0x24,0xd4,0x0b,0x4a,0x62,0x76,0x9c,0x31,0x10,0x62,0xc7,0x44,0x00,0x00, +0xe2,0x74,0xdc,0x74,0x81,0x75,0x84,0x85,0xa2,0x55,0x98,0xa5,0x71,0x49,0x30,0xaa, +0x0a,0x6a,0x50,0x74,0xd2,0x74,0xde,0x95,0x86,0x45,0x81,0xa5,0x9a,0x35,0xa1,0xc5, +0x9c,0x31,0x10,0x7a,0xc7,0x54,0x00,0x00,0x89,0x34,0x40,0xc4,0x0d,0x5a,0x30,0x6a, +0xaa,0x65,0xe7,0x94,0xa0,0x15,0x7a,0xd5,0x92,0x16,0xa1,0xa5,0xa0,0x55,0x5e,0x85, +0x1f,0x75,0x15,0x90,0x77,0x65,0xdf,0x86,0x9c,0x31,0x10,0xd6,0xc7,0x44,0x10,0x00, +0xc0,0x55,0x78,0xa5,0x8b,0x75,0x99,0x45,0xa9,0xd6,0x81,0x19,0x36,0xb5,0x0d,0x40, +0x40,0x81,0xbd,0x85,0xde,0x86,0x8d,0x45,0x7a,0xb4,0x94,0x35,0x9f,0xa6,0xa4,0x65, +0x9c,0x31,0x10,0x85,0xc8,0x45,0x00,0x00,0x5f,0x85,0x24,0x60,0x1b,0x71,0x79,0x75, +0xdb,0x75,0xba,0x65,0x77,0x85,0x8b,0x75,0x94,0x55,0xa6,0xa5,0x8b,0x35,0x43,0xa4, +0x18,0x59,0x37,0x86,0xaa,0x65,0xdb,0x85,0x9c,0x31,0x10,0x62,0xc7,0x44,0x00,0x00, +0x98,0x34,0x7c,0xb5,0x8f,0x46,0x97,0x84,0xab,0xa4,0x6e,0x39,0x31,0xba,0x19,0x45, +0x5c,0x81,0xcb,0x84,0xc9,0x75,0x7d,0x76,0x81,0x95,0x90,0x34,0xa1,0xb5,0xa4,0x22, +0x9c,0x31,0x10,0x0a,0xc8,0x44,0x00,0x00,0x59,0x91,0x26,0x70,0x23,0x70,0x7c,0x75, +0xd4,0x76,0xb2,0x65,0x76,0x85,0x89,0x75,0x93,0x56,0xa7,0xa5,0x94,0x34,0x4b,0xa5, +0x22,0x56,0x32,0x7a,0x98,0x75,0xd8,0x84,0x9c,0x31,0x10,0x42,0xc8,0x34,0x00,0x00, +0x9e,0x5b,0x72,0x9d,0x89,0x74,0x91,0x63,0xad,0xab,0x87,0x3b,0x40,0xab,0x20,0x4a, +0x3f,0x89,0xab,0x76,0xd4,0x8c,0x91,0x5a,0x77,0x9a,0x8b,0x6b,0x94,0x73,0xaf,0xa3, +0x9c,0x31,0x10,0x62,0xc7,0x44,0x00,0x00,0x79,0x15,0x38,0xb6,0x22,0x45,0x50,0x80, +0xb7,0x74,0xcd,0x86,0x86,0x45,0x77,0xa5,0x8b,0x55,0x97,0x85,0xac,0xa9,0x6f,0x35, +0x33,0xa6,0x21,0x21,0x5c,0x95,0xc6,0x74,0x9c,0x31,0x10,0x2a,0xc7,0x34,0x00,0x00, +0xcb,0x79,0x81,0x6a,0x76,0x95,0x8a,0x45,0x9d,0x85,0xaa,0x89,0x65,0x55,0x31,0x95, +0x24,0x32,0x67,0x99,0xca,0x75,0xc4,0x84,0x7b,0x65,0x75,0x95,0x8b,0x45,0xa1,0x95, +0x9c,0x31,0x10,0xff,0xc6,0x44,0x00,0x00,0xa9,0x75,0x61,0x74,0x2d,0x75,0x28,0x56, +0x6e,0xa2,0xc9,0x64,0xc0,0x85,0x7b,0x65,0x75,0xb5,0x8a,0x15,0xa5,0xc5,0xaa,0x55, +0x5c,0xa9,0x28,0x74,0x2b,0x35,0x79,0xb2,0x9c,0x31,0x10,0xff,0xc6,0x44,0x00,0x00, +0xd3,0x65,0xbd,0x75,0x74,0x64,0x71,0xb5,0x86,0x16,0xa4,0xd6,0xac,0x65,0x57,0x98, +0x26,0x94,0x2c,0x45,0x7c,0x9a,0xd8,0x65,0xc0,0x74,0x73,0x64,0x6f,0xb5,0x86,0x15, +0x9c,0x31,0x10,0xff,0xc6,0x44,0x00,0x00,0xa5,0xb6,0xae,0x85,0x59,0x44,0x24,0xc4, +0x2c,0x35,0x7c,0x82,0xd5,0x85,0xbf,0x74,0x73,0x64,0x6d,0xa5,0x87,0x26,0xa5,0xb5, +0xac,0x85,0x58,0x34,0x23,0xc4,0x29,0x26,0x9c,0x31,0x10,0xb7,0xc6,0x34,0x00,0x00, +0x7b,0x82,0xd8,0x85,0xc3,0x68,0x75,0x74,0x6e,0x95,0x88,0x46,0xa6,0x95,0xaf,0xa4, +0x5d,0x18,0x23,0xe5,0x28,0x16,0x76,0x92,0xd5,0x85,0xc4,0x78,0x77,0x65,0x6e,0xa5, +0x9c,0x31,0x10,0x2a,0xc7,0x34,0x00,0x00,0x86,0x56,0xa4,0x85,0xaf,0x84,0x5e,0x45, +0x25,0xb5,0x29,0x4a,0x70,0x82,0xd1,0x71,0xc7,0x74,0x79,0x69,0x6c,0x85,0x85,0x65, +0xa0,0x75,0xb3,0xa5,0x68,0x25,0x26,0xca,0x9c,0x31,0x10,0x62,0xc7,0x44,0x00,0x00, +0x25,0x36,0x64,0x85,0xcb,0x80,0xd2,0x75,0x81,0x66,0x68,0x95,0x83,0x55,0xa1,0x74, +0xb3,0x95,0x68,0x25,0x25,0xc6,0x24,0x36,0x64,0x84,0xcb,0x74,0xd3,0x75,0x82,0x66, +0x9c,0x31,0x10,0xb8,0xc7,0x23,0x00,0x00,0x68,0x99,0x85,0x55,0xa4,0x84,0xb1,0x91, +0x64,0x25,0x26,0xca,0x25,0x46,0x6b,0x99,0xd1,0x78,0xce,0x74,0x7d,0x69,0x6a,0x95, +0x86,0x55,0xa5,0x85,0xad,0x84,0x5d,0x35,0x9c,0x31,0x10,0x32,0xc7,0x24,0x00,0x00, +0x25,0xc9,0x27,0x3a,0x70,0x95,0xd4,0x74,0xca,0x74,0x7a,0x69,0x6d,0x95,0x8a,0x45, +0xa8,0x95,0xa3,0x75,0x51,0x59,0x23,0xa8,0x2f,0x51,0x83,0x82,0xd9,0x7a,0xbe,0x69, +0x9c,0x31,0x10,0x3d,0xc6,0x33,0x00,0x00,0x74,0x78,0x72,0xa5,0x8e,0x05,0xaf,0xe5, +0x98,0x35,0x41,0x9a,0x22,0x76,0x3a,0x55,0x99,0xa8,0xde,0x78,0xac,0x56,0x6b,0xa5, +0x75,0x85,0x93,0x35,0xb3,0xe5,0x8a,0x05,0x9c,0x31,0x10,0xa0,0xc7,0x33,0x00,0x00, +0x37,0xa4,0x24,0x55,0x48,0x76,0xac,0x85,0xdc,0x71,0x9a,0x64,0x68,0x95,0x7a,0x66, +0x9a,0x65,0xb0,0xa5,0x75,0x35,0x2d,0xc1,0x27,0x45,0x5d,0x84,0xc1,0x75,0xd3,0x71, +0x9c,0x31,0x10,0xa0,0xc7,0x33,0x00,0x00,0x8a,0x56,0x69,0x95,0x81,0x44,0xa4,0x85, +0xaa,0x86,0x5e,0x45,0x26,0xb4,0x2e,0x49,0x78,0x82,0xd2,0x79,0xc2,0x68,0x76,0x78, +0x6c,0x96,0x89,0x46,0xac,0xa5,0x9a,0x54,0x9c,0x31,0x10,0x32,0xc7,0x24,0x00,0x00, +0x46,0x89,0x23,0x7a,0x40,0x66,0x9d,0x89,0xda,0x78,0xa8,0x51,0x6c,0x96,0x75,0x65, +0x98,0x74,0xae,0x99,0x74,0x49,0x2f,0xb5,0x2b,0x52,0x69,0x75,0xc5,0x71,0xc9,0x75, +0x9c,0x31,0x10,0x0d,0xc6,0x13,0x00,0x00,0x82,0xb2,0x6e,0x51,0x8b,0x21,0xa8,0xdd, +0x8c,0xa1,0x45,0xd5,0x29,0xb0,0x4d,0x35,0xaa,0xd6,0xd4,0x36,0x99,0x21,0x6e,0x64, +0x82,0x9d,0xa2,0xd0,0x95,0xb5,0x54,0x39,0x9c,0x31,0x10,0x9f,0xc5,0x23,0x00,0x00, +0x2a,0xc5,0x40,0xaa,0x98,0xd9,0xd3,0x34,0xa8,0x19,0x72,0xe6,0x7e,0x15,0x9e,0x45, +0x93,0xb5,0x58,0xb1,0x30,0x46,0x41,0x96,0x95,0x45,0xd1,0x34,0xa9,0x15,0x75,0x66, +0x9c,0x31,0x10,0xb7,0xc5,0x13,0x00,0x00,0x81,0x9c,0x9e,0xd2,0x8b,0x22,0x51,0xd3, +0x30,0xab,0x49,0xb5,0xa0,0xd4,0xd0,0xa2,0xa1,0xa9,0x75,0xdb,0x88,0xad,0x9d,0x4c, +0x7f,0x13,0x4b,0x6b,0x30,0x8b,0x55,0x48,0x9c,0x31,0x10,0x9f,0xc5,0x23,0x00,0x00, +0xb0,0xc5,0xcd,0x26,0x95,0x29,0x77,0xc5,0x91,0x35,0x94,0xb5,0x6a,0xb5,0x3f,0x55, +0x36,0x94,0x77,0x41,0xc6,0x3a,0xb9,0xa1,0x83,0x35,0x82,0xc5,0x96,0x31,0x80,0x26, +0x9c,0x31,0x10,0x9f,0xc5,0x23,0x00,0x00,0x56,0x55,0x37,0x98,0x4d,0xc5,0xa3,0xc6, +0xca,0xa2,0x9c,0xa4,0x7e,0xc0,0x8e,0xb5,0x88,0xa6,0x63,0xb5,0x42,0xc6,0x41,0x25, +0x84,0xc8,0xc4,0x39,0xae,0x36,0x85,0x45,0x9c,0x31,0x10,0xb7,0xc5,0x13,0x00,0x00, +0x8a,0xba,0x8b,0xab,0x6d,0x3b,0x4a,0xe2,0x3e,0x93,0x71,0x4e,0xb9,0xc4,0xb8,0xb1, +0x8d,0xc2,0x8a,0x44,0x8c,0xac,0x71,0x2a,0x4e,0xe2,0x3d,0x8d,0x68,0x4c,0xb3,0xc2, +0x9c,0x31,0x10,0x10,0xc5,0x22,0x00,0x00,0xbc,0xb8,0x91,0xb5,0x87,0xb2,0x89,0x25, +0x71,0x24,0x51,0xe9,0x3f,0x06,0x66,0xc5,0xb1,0xb4,0xbc,0xa5,0x95,0x32,0x89,0x46, +0x85,0xb4,0x6b,0xa5,0x50,0x6a,0x45,0x86,0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00, +0x5a,0x94,0xe2,0x94,0xf0,0x46,0xab,0x9a,0x95,0x75,0x85,0x55,0x53,0x84,0x19,0x94, +0x0b,0x35,0x77,0x92,0xef,0x76,0xe5,0x59,0xa8,0xa4,0x8d,0x56,0x73,0x66,0x45,0x95, +0x9c,0x31,0x10,0xc3,0xb5,0x12,0x00,0x00,0x10,0x55,0x20,0x79,0x9e,0x89,0xf3,0x59, +0xd0,0x76,0xa1,0xa1,0x88,0x54,0x64,0x78,0x33,0xa5,0x0d,0x25,0x47,0x94,0xcd,0x96, +0xf0,0x32,0xb9,0x99,0x95,0x70,0x77,0x59,0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00, +0x50,0x96,0x1f,0x75,0x19,0x54,0x8d,0x96,0xee,0x55,0xd6,0x74,0xa4,0xa5,0x81,0x45, +0x60,0x76,0x37,0xb5,0x0d,0x24,0x4f,0xa5,0xd4,0x72,0xec,0x45,0xba,0xa4,0x90,0x58, +0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00,0x6b,0x69,0x48,0x96,0x19,0x46,0x2c,0x84, +0xac,0x94,0xf0,0x35,0xc9,0x92,0x9b,0x85,0x73,0x44,0x4d,0x95,0x23,0x70,0x22,0x55, +0x90,0xa6,0xed,0x45,0xd7,0x79,0xa1,0x95,0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00, +0x75,0x15,0x50,0xa5,0x2c,0xb9,0x21,0x06,0x7b,0xd4,0xe4,0x34,0xe1,0x61,0xab,0xb6, +0x7a,0x25,0x4e,0x94,0x2c,0xd9,0x24,0x16,0x74,0xd5,0xdb,0x41,0xe2,0x65,0xaf,0xa5, +0x9c,0x31,0x10,0x5e,0xb4,0x12,0x00,0x00,0x79,0x51,0x4c,0x89,0x2a,0xa9,0x2b,0x11, +0x7c,0xc9,0xd8,0x55,0xde,0x85,0xae,0x81,0x77,0x65,0x49,0x75,0x2b,0xa5,0x33,0x24, +0x80,0xb4,0xd4,0x45,0xdb,0x76,0xae,0xa5,0x9c,0x31,0x10,0x4f,0xb5,0x11,0x00,0x00, +0x6d,0x68,0x3b,0x76,0x30,0x89,0x47,0x58,0x90,0xa6,0xd9,0x50,0xd4,0x75,0x9a,0x95, +0x57,0x55,0x36,0x85,0x3e,0x88,0x5e,0x46,0xa5,0xb4,0xd8,0x46,0xbc,0x86,0x84,0x85, +0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00,0x4e,0x51,0x41,0x95,0x53,0x61,0x73,0x65, +0xad,0xa5,0xc1,0x35,0xa5,0xb6,0x77,0x45,0x51,0x74,0x53,0x86,0x62,0x55,0x81,0x82, +0xa7,0x74,0xab,0x64,0x96,0xa5,0x70,0x46,0x9c,0x31,0x10,0xdf,0xa4,0x21,0x00,0x00, +0x37,0xe3,0x45,0x35,0x60,0x3b,0x94,0xd2,0xbc,0x2c,0xba,0xcc,0x96,0x2a,0x5e,0xbd, +0x47,0x3a,0x4e,0x23,0x6d,0x4b,0x98,0xb4,0xb0,0xb2,0xaa,0x3a,0x86,0xba,0x65,0x3b, +0x9c,0x31,0x10,0xc8,0x93,0x22,0x00,0x00,0x2c,0xdb,0x3e,0xea,0x78,0x95,0xb2,0xdb, +0xcd,0x1a,0xb3,0x1b,0x78,0xe4,0x57,0x25,0x48,0x53,0x61,0x59,0x86,0x13,0xa9,0x9b, +0xb6,0x4a,0x9d,0x54,0x78,0x9a,0x5d,0x0a,0x9c,0x31,0x10,0x61,0x83,0x21,0x00,0x00, +0x3a,0x51,0x5c,0x71,0x8a,0x65,0xaa,0x71,0xa5,0x52,0x8e,0xae,0x60,0x30,0x4e,0xb0, +0x54,0x28,0x75,0xcd,0x8b,0x12,0x9e,0xd1,0x9a,0x0e,0x89,0xce,0x74,0x0c,0x6a,0xad, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_FOUR.txt b/config/_default_cfg_src_/res/cn/SOUND_FOUR.txt new file mode 100644 index 0000000..c6140e5 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_FOUR.txt @@ -0,0 +1,130 @@ +0x9c,0x31,0x10,0xe8,0x44,0x42,0x00,0x00,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb, +0x63,0x33,0x83,0x38,0x53,0xcd,0x7b,0xca,0x72,0xcb,0x7c,0x42,0xa3,0xbc,0x7c,0x31, +0x82,0x1c,0x76,0x1a,0x4d,0x3d,0x33,0x3a,0x9c,0x31,0x10,0x88,0x53,0x44,0x10,0x00, +0x5b,0x67,0x68,0x68,0x6a,0x85,0x73,0x99,0x6c,0xb5,0x73,0x98,0x73,0x67,0x66,0xa7, +0x44,0x4c,0x59,0x22,0x63,0x76,0x42,0x77,0x3a,0x6a,0x6b,0x5c,0x6c,0x92,0x89,0xe8, +0x9c,0x31,0x10,0xeb,0x54,0x55,0x10,0x00,0x5d,0x43,0x83,0x2b,0x71,0xc2,0x9c,0xc2, +0x65,0x1d,0x6b,0xcb,0x7e,0x6a,0x57,0x3c,0x7b,0x35,0x63,0xab,0x6a,0x08,0x80,0x2a, +0x83,0xdd,0x9c,0xc5,0xa6,0x32,0xcc,0xda,0x9c,0x31,0x10,0x53,0x45,0x55,0x10,0x00, +0x84,0x5d,0xa3,0xb4,0x9b,0xb2,0x2b,0x4a,0x4b,0x5a,0x52,0xca,0x83,0xc3,0x4a,0x9e, +0x2b,0xac,0x53,0x49,0x69,0x2a,0xba,0xa3,0x6b,0x29,0xd4,0x34,0xd5,0xcd,0x4b,0x32, +0x9c,0x31,0x10,0x68,0x56,0x66,0x10,0x00,0x76,0x85,0x79,0x98,0x67,0x69,0x84,0x66, +0xa5,0x45,0x75,0x6a,0x87,0x75,0xbc,0x37,0x9c,0x67,0xd9,0x77,0xa5,0xa6,0xc8,0x97, +0xd8,0x8b,0x9a,0x64,0x98,0x95,0x79,0x48,0x9c,0x31,0x10,0x68,0x56,0x66,0x10,0x00, +0xb6,0x88,0x95,0x66,0xa9,0x87,0xa6,0x99,0x83,0x88,0x65,0xb3,0xb9,0x79,0x9a,0xc5, +0x88,0x47,0x74,0x39,0x51,0x69,0x35,0xa6,0x46,0x42,0x79,0x99,0x5a,0x47,0xb9,0xaa, +0x9c,0x31,0x10,0x8b,0x66,0x65,0x10,0x00,0x8c,0x49,0xc1,0x4c,0x84,0x29,0x52,0x15, +0x3a,0x99,0x4a,0x64,0x7d,0x52,0x6a,0x2c,0xaa,0x3a,0x7b,0x34,0x75,0xa4,0x7a,0xca, +0x74,0x12,0x9b,0xbd,0xb3,0xa4,0x9d,0x41,0x9c,0x31,0x10,0x72,0x66,0x66,0x30,0x00, +0xa2,0x2a,0x9b,0xd4,0x81,0xbb,0x83,0x54,0x94,0xa5,0x9a,0x8b,0xad,0xd8,0x8b,0x3a, +0x7a,0xc5,0x74,0xbc,0x64,0xbc,0x14,0x5b,0x3d,0x64,0x45,0x1c,0x5a,0xa3,0x5a,0xa9, +0x9c,0x31,0x10,0xbd,0x65,0x66,0x10,0x00,0xad,0x46,0x6e,0x9a,0x61,0x66,0x82,0x65, +0x52,0x89,0x5c,0xa3,0x53,0x0a,0x30,0x77,0x42,0x08,0x4b,0x86,0x4d,0xd7,0x2a,0xac, +0x6a,0xa1,0x58,0x79,0xc8,0x94,0xa5,0x58,0x9c,0x31,0x10,0x49,0x66,0x67,0x20,0x00, +0xaa,0x1c,0x6c,0x91,0x5c,0xbd,0x84,0xda,0xb4,0x4d,0xf6,0x51,0xbb,0x93,0x93,0x73, +0x3d,0x1c,0x35,0x20,0x8d,0x3d,0x73,0x3b,0xe3,0x4b,0xaa,0x5b,0x82,0xcb,0x7a,0xbc, +0x9c,0x31,0x10,0x3a,0x76,0x76,0x10,0x00,0x5c,0xd8,0x5a,0x33,0x49,0xa5,0x65,0xc1, +0x7c,0x33,0x62,0x9e,0x83,0x31,0x94,0x3a,0x8b,0xbd,0xad,0x4b,0xab,0x41,0x88,0xbc, +0x6c,0xc4,0x64,0x3a,0x42,0xa9,0x1b,0x2d,0x9c,0x31,0x10,0x96,0x76,0x66,0x00,0x00, +0x3d,0x44,0x52,0xe0,0x42,0xdc,0x5b,0xd5,0x6b,0x49,0x8c,0xd1,0x64,0x56,0x9c,0x0b, +0x8c,0x18,0x96,0x3c,0x9d,0x15,0x6a,0x39,0x63,0x21,0x91,0x8d,0x9a,0xcb,0x8b,0xd9, +0x9c,0x31,0x10,0x01,0x76,0x77,0x00,0x00,0x96,0xb3,0xa1,0xcc,0x8b,0x5a,0x5c,0x42, +0x7d,0x4c,0x79,0xbb,0x7c,0x42,0x78,0xaa,0x7b,0x9d,0x9c,0xc3,0xad,0x21,0x6e,0xb4, +0x83,0xb4,0xc3,0xb2,0x75,0xd2,0xa4,0x35,0x9c,0x31,0x10,0x3a,0x76,0x76,0x10,0x00, +0x7b,0xc5,0xb2,0x50,0x62,0x42,0x5b,0x26,0x5a,0xab,0x48,0x38,0x32,0xab,0x1b,0xae, +0x38,0x9b,0x5b,0x49,0x63,0xc3,0xe2,0x46,0xd2,0x5b,0xdc,0xc0,0xaa,0x55,0xcc,0xdd, +0x9c,0x31,0x10,0x56,0x98,0x87,0x30,0x00,0x94,0xcb,0x7c,0x42,0x7b,0xac,0x83,0xb3, +0x73,0x39,0x83,0xbb,0x63,0xcc,0x6c,0xbb,0x7b,0xc3,0x94,0x2c,0x7b,0x2a,0x83,0x33, +0x7b,0xbb,0x8a,0xcb,0xf6,0x4a,0x72,0x5b,0x9c,0x31,0x10,0x7f,0xa6,0x76,0x20,0x00, +0x3f,0xa2,0x5c,0xa4,0x6d,0x16,0x6d,0x83,0x72,0x82,0x79,0x03,0x72,0xd3,0x74,0x9b, +0x6e,0x64,0x7a,0xa3,0x8d,0x22,0x97,0x63,0x97,0x1d,0x7a,0x8a,0x62,0xd3,0x6c,0x1c, +0x9c,0x31,0x10,0x4b,0xb7,0x75,0x20,0x00,0x84,0xec,0x97,0x4d,0x9a,0xcc,0x82,0xed, +0x67,0x0d,0x66,0xd1,0x8f,0x0e,0xc6,0xf2,0xc3,0x0d,0x7f,0x0c,0x36,0xad,0x23,0x0a, +0x74,0xc8,0xe5,0x4d,0xf8,0xed,0x93,0x96,0x9c,0x31,0x10,0x95,0xc8,0x76,0x10,0x00, +0x55,0x18,0x3d,0x55,0x66,0xf2,0xa7,0x0d,0xcf,0x0c,0xaa,0xca,0x6d,0x49,0x36,0x68, +0x3d,0x0e,0x7c,0xd1,0xba,0xf4,0xca,0xd1,0x90,0xf6,0x53,0x4d,0x23,0x59,0x43,0x10, +0x9c,0x31,0x10,0x26,0xc8,0x87,0x00,0x00,0x91,0x0d,0xcd,0x05,0xca,0xc5,0x8c,0xe9, +0x44,0xed,0x1b,0x91,0x4f,0x29,0xab,0x09,0xd7,0x09,0xc0,0xc8,0x7f,0x2a,0x2e,0x6a, +0x11,0x21,0x5b,0x04,0xbc,0xe9,0xdc,0xf2,0x9c,0x31,0x10,0xcd,0xc8,0x98,0x20,0x00, +0xb8,0xda,0x79,0x1a,0x24,0x4b,0x0e,0xcd,0x6a,0x92,0xd0,0x99,0xe2,0xa4,0xb2,0x9c, +0x6d,0x1b,0x14,0x51,0x16,0x94,0x80,0x9d,0xdc,0xa2,0xe0,0xe2,0xaa,0x9c,0x67,0x1c, +0x9c,0x31,0x10,0x3b,0xc7,0x87,0x20,0x00,0x0c,0x08,0x18,0x64,0x8c,0xb6,0xe4,0xb2, +0xdd,0x24,0xa4,0x90,0x67,0x46,0x06,0x4a,0x16,0x6c,0x8e,0xb9,0xe6,0xb2,0xdb,0x21, +0xa2,0x90,0x65,0x49,0x02,0x0d,0x14,0x6c,0x9c,0x31,0x10,0x6e,0xd8,0x97,0x20,0x00, +0x88,0xb6,0xb6,0xd2,0xad,0x0d,0x90,0xc8,0x75,0x29,0x42,0x69,0x44,0xd0,0x84,0xb6, +0xb6,0xb6,0xb1,0x0c,0x92,0xa8,0x79,0x4a,0x44,0x25,0x3e,0xad,0x7e,0x96,0xb6,0xd5, +0x9c,0x31,0x10,0x6e,0xd8,0x97,0x20,0x00,0xb5,0x30,0x94,0xc9,0x7b,0x65,0x4a,0x05, +0x38,0xe6,0x74,0xac,0xb2,0xd4,0xb9,0x56,0x98,0xd1,0x81,0x69,0x54,0x89,0x31,0x64, +0x62,0xe5,0xaa,0xee,0xbf,0x11,0xa0,0xb4,0x9c,0x31,0x10,0xf0,0xd8,0x88,0x20,0x00, +0x85,0x2b,0x64,0xd3,0x33,0x64,0x4e,0xdb,0x9a,0xd1,0xc0,0xd3,0xaa,0xd4,0x8c,0xdc, +0x77,0x22,0x3e,0x51,0x36,0x9d,0x7e,0xad,0xbc,0xe9,0xb7,0x2a,0x94,0xdc,0x83,0x4d, +0x9c,0x31,0x10,0x31,0xd8,0x88,0x10,0x00,0x58,0x92,0x2d,0xa0,0x58,0xd5,0xab,0x0d, +0xc2,0x91,0xa4,0xd1,0x86,0xa5,0x75,0x2d,0x3c,0x48,0x36,0xd3,0x80,0xa5,0xc0,0xeb, +0xb9,0x21,0x90,0xa3,0x81,0x14,0x62,0xca,0x9c,0x31,0x10,0x6e,0xd8,0x97,0x20,0x00, +0x2d,0x52,0x4a,0xf5,0xa1,0x0c,0xc8,0xa9,0xa9,0x2a,0x84,0xe9,0x7f,0x2d,0x52,0xb5, +0x29,0x90,0x60,0xe6,0xb7,0x06,0xc6,0xa8,0x98,0xac,0x7e,0xd2,0x7d,0x55,0x4c,0x8e, +0x9c,0x31,0x10,0xe8,0xd8,0x98,0x20,0x00,0x2b,0x42,0x6e,0x89,0xc0,0xdc,0xc2,0xac, +0x8e,0xa3,0x7c,0xe2,0x7d,0x12,0x48,0x94,0x2d,0x0c,0x74,0xd9,0xc4,0xe2,0xbe,0xe5, +0x8c,0x9c,0x7a,0xdb,0x7f,0x1a,0x4c,0x9c,0x9c,0x31,0x10,0x76,0xd8,0x87,0x20,0x00, +0x2b,0x61,0x6e,0xc0,0xc3,0x09,0xc0,0xb2,0x8a,0xd2,0x76,0xcc,0x85,0x2d,0x5f,0x11, +0x29,0x75,0x58,0xea,0xb7,0x04,0xca,0xc8,0x93,0x11,0x72,0xf5,0x85,0x0d,0x74,0xe9, +0x9c,0x31,0x10,0xe8,0xd8,0x98,0x20,0x00,0x34,0x92,0x3e,0xa2,0x9c,0xad,0xce,0xdc, +0xa4,0xd2,0x76,0x92,0x80,0xa4,0x8a,0xe3,0x52,0xe3,0x27,0x51,0x6a,0xc4,0xc2,0xd5, +0xc0,0xe3,0x83,0x21,0x72,0xdc,0x90,0xd4,0x9c,0x31,0x10,0xe8,0xd8,0x98,0x20,0x00, +0x80,0xd3,0x36,0x51,0x34,0xdc,0x90,0xad,0xce,0xe2,0xa6,0xd1,0x72,0xcc,0x7c,0xdd, +0x9a,0xdb,0x73,0x19,0x28,0x9a,0x42,0xa3,0xa4,0xe4,0xcc,0xdb,0x98,0xd2,0x6e,0x9b, +0x9c,0x31,0x10,0x31,0xd8,0x88,0x10,0x00,0x86,0x9b,0x9e,0xe4,0x6b,0x1b,0x24,0x5b, +0x46,0xb2,0xaa,0xac,0xca,0xd4,0x92,0xca,0x6c,0x9a,0x8a,0xe3,0xa2,0x9c,0x6e,0xdc, +0x24,0x09,0x3c,0xdb,0xa2,0xb5,0xce,0xeb,0x9c,0x31,0x10,0x1e,0xd7,0x87,0x20,0x00, +0x96,0x90,0x6a,0xc5,0x86,0xda,0xa6,0xe5,0x7e,0xe0,0x32,0x9e,0x2d,0x85,0x86,0xc5, +0xc8,0xdd,0xa8,0xf1,0x6e,0x9c,0x7c,0x9a,0xa6,0x69,0x96,0xa0,0x4d,0x58,0x20,0x26, +0x9c,0x31,0x10,0x98,0xd7,0x88,0x20,0x00,0x5a,0xb2,0xb4,0xa3,0xbf,0x0c,0x84,0xd4, +0x6c,0xda,0x94,0xe3,0xaa,0xe3,0x7b,0x13,0x35,0x53,0x2d,0xa3,0x7f,0x14,0xc0,0xcb, +0xac,0xd2,0x72,0xa3,0x75,0x63,0xa7,0x05,0x9c,0x31,0x10,0x6e,0xd8,0x97,0x20,0x00, +0xa6,0xe9,0x68,0xec,0x2c,0xf1,0x37,0x8d,0x8f,0x06,0xbf,0x09,0x9e,0xd0,0x6e,0xd1, +0x7d,0x2d,0xab,0x09,0xa5,0x09,0x66,0xed,0x33,0x30,0x39,0x71,0x83,0x0a,0xb8,0xe8, +0x9c,0x31,0x10,0x1e,0xd7,0x87,0x20,0x00,0xa4,0xd8,0x75,0x2d,0x79,0x32,0xa7,0x24, +0xa8,0xd1,0x74,0xd2,0x43,0xa2,0x34,0x24,0x6a,0xb8,0xaa,0xaa,0xae,0x8e,0x82,0xc8, +0x70,0xa1,0x94,0xdd,0xae,0xdd,0x8c,0xdd,0x9c,0x31,0x10,0xb7,0xd8,0x87,0x10,0x00, +0x56,0xed,0x38,0x8e,0x4d,0x44,0x8e,0xe4,0xb3,0x0e,0x96,0xf5,0x72,0xf0,0x7f,0x0d, +0xa6,0xea,0xa2,0xed,0x74,0xd1,0x4d,0x11,0x3c,0x68,0x62,0xcd,0x9e,0xb5,0xaa,0xf1, +0x9c,0x31,0x10,0xfa,0xc7,0x87,0x10,0x00,0x8e,0xd9,0x62,0xd5,0x9b,0x22,0xd8,0xe0, +0xb0,0xe1,0x56,0xa6,0x19,0x9d,0x08,0xdd,0x5a,0xb4,0xc0,0xaa,0xcc,0xd6,0x88,0xd0, +0x68,0xdd,0xa2,0xe6,0xd0,0xe1,0xa4,0x9d,0x9c,0x31,0x10,0x53,0xc8,0x87,0x20,0x00, +0x54,0xed,0x23,0x2e,0x0e,0xad,0x56,0xd8,0xb8,0xd6,0xcc,0xea,0x8c,0xe4,0x68,0xe9, +0x98,0xd2,0xca,0xf1,0xa8,0xec,0x60,0xc9,0x33,0x0a,0x18,0x24,0x42,0xce,0xa2,0xb5, +0x9c,0x31,0x10,0x53,0xc8,0x87,0x20,0x00,0xcc,0xf4,0x9e,0xed,0x6a,0xe6,0x86,0xc4, +0xc0,0xed,0xb6,0xf2,0x74,0xf1,0x46,0xec,0x24,0xad,0x2f,0x64,0x86,0xe2,0xc5,0x0a, +0xae,0xd0,0x75,0x15,0x76,0xf2,0xad,0x29,0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00, +0xbe,0xcb,0x8e,0xd3,0x58,0xdb,0x3d,0x63,0x26,0x5a,0x56,0xb3,0xa8,0xad,0xc0,0xda, +0x90,0xd2,0x6c,0xd4,0x8e,0x9c,0xbc,0xa2,0xa8,0xe3,0x70,0xdc,0x53,0x1b,0x3c,0xda, +0x9c,0x31,0x10,0x14,0xc8,0x88,0x10,0x00,0x33,0x6c,0x73,0x0d,0xb7,0x01,0xb2,0xd3, +0x7c,0xdd,0x70,0xe3,0x9e,0xe2,0xbc,0xe4,0x98,0xd4,0x66,0xd2,0x4c,0xd3,0x3a,0x5c, +0x45,0x0a,0x8a,0xca,0xb6,0xdd,0xa0,0xe3,0x9c,0x31,0x10,0x3d,0xb7,0x77,0x00,0x00, +0x70,0xf0,0x7d,0x24,0xcf,0x1d,0xe4,0xd1,0x90,0xca,0x3e,0x9d,0x1c,0xe3,0x06,0x19, +0x27,0x0d,0x9e,0x93,0xde,0xe2,0xb6,0xe3,0x7a,0xe4,0x88,0xda,0xc9,0x1b,0xd0,0xd4, +0x9c,0x31,0x10,0xb2,0xb7,0x76,0x00,0x00,0x87,0x13,0x42,0xd9,0x20,0xdc,0x14,0x5c, +0x40,0xd3,0x98,0xa1,0xc8,0xe4,0xa8,0xe4,0x82,0xda,0x96,0x92,0xca,0xdc,0xbc,0xdc, +0x70,0xda,0x26,0xe3,0x05,0x23,0x13,0xb2,0x9c,0x31,0x10,0x28,0xb6,0x87,0x00,0x00, +0x82,0xa5,0xd2,0x9a,0xbd,0xa2,0x7d,0x34,0x79,0xc3,0xad,0x4a,0xc5,0x4c,0x99,0x3b, +0x66,0x32,0x49,0xab,0x39,0xb4,0x31,0x3b,0x55,0xc3,0xa9,0xbc,0xd9,0xbb,0xc6,0x3b, +0x9c,0x31,0x10,0x76,0xc5,0x66,0x00,0x00,0x8f,0x1b,0x7e,0x54,0x63,0x53,0x3e,0x62, +0x37,0xac,0x76,0x5c,0xb4,0x51,0xb2,0x54,0x92,0x54,0x87,0x92,0x8d,0x1a,0x86,0x6d, +0x7c,0x6b,0x83,0x62,0x88,0x54,0x75,0x5b,0x9c,0x31,0x10,0x1c,0xb6,0x54,0x00,0x00, +0x3c,0xe4,0x3f,0x09,0x6c,0xee,0xa6,0xec,0xc4,0xf0,0xc0,0xee,0x96,0xf1,0x52,0xec, +0x17,0x31,0x04,0x6e,0x4b,0x05,0xbe,0xa4,0xea,0xca,0xd0,0xf2,0xa8,0xd0,0x8b,0x11, +0x9c,0x31,0x10,0xb4,0xb4,0x55,0x00,0x00,0x64,0xdc,0x4f,0x1a,0x67,0x1a,0x82,0xd5, +0x78,0x9a,0x60,0xda,0x68,0xdc,0x85,0x1b,0x9e,0x9a,0xb2,0xdc,0xb5,0x5c,0x88,0x1a, +0x3f,0x1b,0x10,0xe3,0x2d,0x6b,0x81,0x23,0x9c,0x31,0x10,0xa9,0xb4,0x43,0x00,0x00, +0xc7,0x8d,0xdf,0xa1,0xce,0x41,0xa2,0xa0,0x6b,0x46,0x42,0x4c,0x39,0x75,0x4d,0x31, +0x74,0x96,0x9a,0x76,0xa8,0x8c,0xa7,0x49,0xa1,0x8a,0x97,0x6c,0x7f,0x8d,0x5c,0x49, +0x9c,0x31,0x10,0x5d,0xb3,0x43,0x00,0x00,0x45,0x0d,0x47,0x59,0x66,0xb2,0x91,0x95, +0xb3,0x8e,0xbf,0x4d,0xaf,0x65,0x86,0xa5,0x59,0x45,0x42,0x4d,0x46,0x31,0x64,0x70, +0x8c,0x32,0xaa,0x74,0xb4,0x70,0xa7,0x8e,0x9c,0x31,0x10,0xf7,0xa3,0x42,0x00,0x00, +0x9a,0x6a,0x5e,0x28,0x39,0x29,0x36,0x46,0x4f,0x8c,0x73,0x71,0x95,0x35,0xb1,0x75, +0xba,0x92,0xaa,0x91,0x89,0x6d,0x64,0x69,0x4e,0x69,0x4f,0x69,0x66,0x89,0x83,0x69, +0x9c,0x31,0x10,0x85,0x93,0x54,0x00,0x00,0xb6,0x9b,0xc9,0x1b,0xbd,0x23,0x96,0xe4, +0x67,0x24,0x4c,0xdb,0x4e,0xe2,0x66,0xd8,0x82,0x8c,0x90,0xd3,0x98,0xa4,0x94,0xdb, +0x8d,0x1b,0x80,0xdb,0x71,0x1b,0x6d,0x5b,0x9c,0x31,0x10,0x92,0x63,0x31,0x00,0x00, +0x0a,0x48,0x61,0x2a,0x8c,0xb1,0x96,0xd2,0xb4,0xed,0xac,0x0d,0x92,0x91,0x59,0x12, +0x4c,0xf4,0x68,0x6c,0x74,0xad,0x70,0x92,0x90,0xd1,0x7f,0x2d,0x4e,0xce,0x4e,0xec, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_HUNG_UP.txt b/config/_default_cfg_src_/res/cn/SOUND_HUNG_UP.txt new file mode 100644 index 0000000..0164f01 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_HUNG_UP.txt @@ -0,0 +1,155 @@ +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x76,0x43,0x20,0x21,0x00,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0xd6,0xa4,0x9c,0x31,0x10,0xea,0xcb,0x79,0x87,0x67, +0x7d,0xd5,0x85,0xd5,0x7d,0xa5,0xbe,0xa4,0x84,0x88,0x3a,0xe5,0xdd,0x15,0x0e,0x15, +0xee,0x55,0x20,0xd5,0xbf,0x15,0x68,0x55,0x6b,0x55,0xb4,0x95,0x26,0xd5,0xe5,0x55, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb, +0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2,0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24, +0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2,0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3, +0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c,0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44, +0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00,0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60, +0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71,0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa, +0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75,0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00, +0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30,0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75, +0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca,0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75, +0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00,0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30, +0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5,0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea, +0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15,0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00, +0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb,0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b, +0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35,0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb, +0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00,0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04, +0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52,0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e, +0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90,0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55, +0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21,0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9, +0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5,0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70, +0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65,0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00, +0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41,0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55, +0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba,0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50, +0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69,0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21, +0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65,0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00, +0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba,0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85, +0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50,0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75, +0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00,0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6, +0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb,0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb, +0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10,0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71, +0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51,0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95, +0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00,0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01, +0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78,0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d, +0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76,0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55, +0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a,0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba, +0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75,0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda, +0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85,0x9c,0x31,0x10,0x9c,0xc5,0x54,0x30,0x00, +0xcb,0x6d,0x92,0x2e,0x30,0x89,0x77,0xd6,0xcb,0x69,0x7b,0x28,0x34,0x51,0x8e,0x92, +0xc8,0x89,0x65,0x09,0x3a,0x72,0xa1,0x84,0xba,0xa6,0x56,0x6e,0x4a,0x4e,0xb0,0x89, +0x9c,0x31,0x10,0xd0,0xcb,0x78,0x77,0x56,0xac,0xeb,0x48,0xeb,0x56,0xcb,0xd5,0x03, +0x86,0x65,0x3b,0x6c,0xe0,0x8b,0x0d,0x0b,0xef,0x2b,0x20,0x6b,0xbf,0x8b,0x68,0x2b, +0x6b,0xab,0xb8,0x4b,0x27,0x6b,0xe8,0xab,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb,0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2, +0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24,0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2, +0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3,0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c, +0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44,0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00, +0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60,0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71, +0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa,0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75, +0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00,0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30, +0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75,0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca, +0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75,0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00, +0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30,0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5, +0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea,0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15, +0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00,0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb, +0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b,0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35, +0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb,0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00, +0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04,0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52, +0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e,0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90, +0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55,0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21, +0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9,0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5, +0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70,0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65, +0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00,0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41, +0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55,0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba, +0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50,0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69, +0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21,0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65, +0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00,0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba, +0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85,0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50, +0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75,0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00, +0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6,0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb, +0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb,0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10, +0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71,0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51, +0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95,0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00, +0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01,0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78, +0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d,0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76, +0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55,0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a, +0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba,0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75, +0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda,0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_INCOMING_CALL.txt b/config/_default_cfg_src_/res/cn/SOUND_INCOMING_CALL.txt new file mode 100644 index 0000000..20f69e4 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_INCOMING_CALL.txt @@ -0,0 +1,250 @@ +0x9c,0x31,0x10,0x90,0x31,0x22,0x00,0x00,0x7b,0x77,0x7b,0x77,0x73,0x77,0x73,0x77, +0x48,0x67,0x3d,0x48,0x34,0x79,0x81,0xb8,0x63,0x97,0x65,0x56,0x32,0x46,0x1e,0x67, +0x34,0x47,0x74,0xa7,0xad,0xa6,0xa6,0x8c,0x9c,0x31,0x10,0xbe,0x72,0x22,0x00,0x00, +0x80,0xda,0x7e,0xd2,0x7c,0xd3,0x7a,0x9c,0x7c,0xd4,0x84,0x92,0x92,0x9a,0x9a,0x9b, +0x86,0xdb,0x62,0xeb,0x3a,0x63,0x29,0x52,0x32,0x95,0x6d,0x05,0xba,0xd3,0xdb,0x32, +0x9c,0x31,0x10,0x73,0xb4,0x24,0x00,0x00,0x83,0x63,0x7d,0x63,0x77,0x6b,0x73,0x8b, +0x77,0x8b,0x83,0x73,0x90,0x4b,0x94,0x8c,0x88,0xab,0x74,0xc3,0x5d,0x8b,0x55,0x85, +0x6f,0x43,0xa6,0x49,0xcb,0x73,0xb6,0x6a,0x9c,0x31,0x10,0xdc,0xc8,0x86,0x20,0x00, +0x7a,0xed,0x5b,0x0d,0x48,0xcd,0x60,0xed,0x90,0xed,0xb0,0xed,0xae,0xe8,0x9e,0xce, +0x87,0x0e,0x64,0xec,0x2c,0xcd,0x3f,0x8c,0xa1,0x29,0xb7,0x25,0x7d,0x04,0x80,0x80, +0x9c,0x31,0x10,0xfa,0xca,0x99,0x40,0x00,0xd5,0xd4,0xad,0x9b,0x35,0xe2,0x0e,0x23, +0x4a,0x35,0xad,0xf1,0x89,0xe2,0x76,0x15,0xae,0x0b,0xbe,0x1a,0xa6,0x1b,0x75,0xd4, +0x32,0x1b,0x04,0xdb,0x8a,0x44,0xb9,0x51,0x9c,0x31,0x10,0xe4,0xc9,0xaa,0x40,0x00, +0x59,0xc3,0xa1,0xc3,0xc0,0xc3,0x99,0xb3,0xad,0xa3,0x65,0xb3,0x06,0xbb,0x25,0xbb, +0xc5,0x69,0x6d,0x54,0x72,0x3c,0xcd,0xaa,0x8c,0xa3,0xbd,0x23,0xb0,0x4b,0x29,0xe3, +0x9c,0x31,0x10,0xea,0xca,0xaa,0x50,0x00,0x09,0xda,0x5e,0xf5,0x9d,0xa3,0x61,0xd1, +0xa2,0x13,0xa9,0x93,0x95,0xd2,0xe1,0x64,0x81,0x33,0x2a,0x22,0x09,0x5b,0x57,0x9a, +0xb9,0x85,0x5e,0x0b,0xa5,0xda,0xb1,0xa3,0x9c,0x31,0x10,0xea,0xca,0xaa,0x50,0x00, +0x91,0xda,0xed,0xad,0x71,0x6b,0x26,0x52,0x08,0x9c,0x63,0x89,0xb1,0x84,0x5e,0x54, +0xad,0xda,0xad,0xa3,0x95,0x9b,0xf1,0xdc,0x69,0xa2,0x26,0x5b,0x04,0x5c,0x67,0x41, +0x9c,0x31,0x10,0x7e,0xca,0xb9,0x50,0x00,0xb1,0x51,0x62,0x1e,0xad,0xe1,0xa9,0xa1, +0x91,0x9e,0xee,0x59,0x71,0xa0,0x22,0xa1,0x04,0x62,0x6b,0x4c,0xb1,0x55,0x5e,0x1e, +0xa9,0xe1,0xb1,0xa1,0x8d,0x9e,0xea,0x99,0x9c,0x31,0x10,0xea,0xca,0xaa,0x50,0x00, +0x79,0xa2,0x1a,0xa4,0x08,0x64,0x6f,0x01,0xad,0x4c,0x5e,0x1c,0xa9,0xe2,0xb1,0xa3, +0x8d,0xd3,0xe2,0xa4,0x8d,0x62,0x16,0x9b,0x08,0x64,0x6b,0x01,0xb1,0x8c,0x62,0x24, +0x9c,0x31,0x10,0x5e,0xca,0xaa,0x40,0x00,0x9d,0xe2,0xb5,0xdb,0x89,0x9b,0xda,0xd2, +0xa1,0x1b,0x16,0xa4,0x04,0xa2,0x5f,0x0a,0xb5,0x85,0x66,0x23,0x91,0xe3,0xb5,0xdc, +0x91,0xd3,0xca,0x5b,0xad,0x6a,0x22,0x5c,0x9c,0x31,0x10,0xcf,0xda,0xaa,0x50,0x00, +0x38,0xdb,0x6f,0x11,0x9d,0x8d,0x6e,0x23,0x85,0xe2,0x9d,0xdc,0x85,0xdb,0x9e,0xe3, +0x9d,0x63,0x52,0x13,0x38,0xe3,0x6b,0x1a,0xa1,0x85,0x72,0x22,0x7d,0xe3,0xa1,0xdc, +0x9c,0x31,0x10,0x5b,0xda,0xb9,0x50,0x00,0x8d,0x99,0x96,0x61,0x9d,0xa0,0x5a,0x19, +0x31,0x25,0x66,0xd8,0xa9,0xd6,0x76,0x25,0x71,0xe1,0xa1,0xd9,0x95,0x9d,0x92,0xa1, +0x91,0x96,0x5e,0x20,0x30,0xe1,0x66,0x8c,0x9c,0x31,0x10,0x4d,0xd9,0xa9,0x40,0x00, +0xad,0x4c,0x7a,0x5d,0x69,0xa2,0xa1,0xb3,0xa5,0x43,0x8d,0xcc,0x81,0xaa,0x5e,0xc3, +0x34,0x23,0x6e,0x3e,0xa9,0x60,0x81,0x9c,0x69,0xbc,0x95,0xca,0xb1,0xb3,0x95,0xcb, +0x9c,0x31,0x10,0xf5,0xc8,0xa9,0x40,0x00,0x59,0x2c,0x2b,0x31,0x05,0x4c,0x79,0xd9, +0xc1,0x16,0x85,0xca,0x69,0xba,0xa9,0x34,0xe1,0xb1,0xa9,0xcd,0x41,0xb3,0x0d,0xc3, +0x23,0x4b,0x9d,0x96,0xb5,0xd9,0x7d,0xab,0x9c,0x31,0x10,0x74,0xd8,0x9a,0x40,0x00, +0x79,0xa8,0x99,0xc5,0xb1,0xc9,0x85,0x97,0x52,0xd7,0x38,0x15,0x6a,0x5b,0x9d,0x44, +0x96,0x17,0x75,0xd7,0x7d,0x27,0xa6,0x26,0xa9,0xc9,0x6d,0xb6,0x39,0xb7,0x46,0xc7, +0x9c,0x31,0x10,0xb8,0xd7,0xa9,0x40,0x00,0x8a,0x9d,0xa6,0xd9,0x8a,0xab,0x72,0xbc, +0x8d,0x4b,0xb2,0xa9,0x94,0xc4,0x53,0x33,0x30,0x3b,0x64,0xd2,0xa4,0xa5,0xa2,0xd2, +0x7c,0xb2,0x76,0xbb,0x9e,0xc3,0xa4,0xac,0x9c,0x31,0x10,0xbb,0xd7,0x99,0x30,0x00, +0x6f,0x6a,0x36,0x0a,0x4a,0xed,0x90,0x92,0xb0,0xdb,0x95,0x23,0x78,0xd4,0x8a,0x9a, +0x98,0xdc,0x75,0x1b,0x4b,0x1b,0x54,0x9a,0x82,0xd4,0x9a,0xdb,0x90,0x9b,0x85,0x5b, +0x9c,0x31,0x10,0x26,0xb7,0x65,0x00,0x00,0x98,0xad,0xa3,0xb4,0x92,0x8a,0x5d,0x0d, +0x46,0xf1,0x55,0x08,0x6e,0xed,0x8c,0xed,0xaa,0xed,0xb4,0xed,0xaf,0x0d,0x96,0xed, +0x68,0xed,0x3c,0xed,0x36,0xed,0x52,0xed,0x9c,0x31,0x10,0x5d,0xb3,0x43,0x00,0x00, +0x7e,0x51,0xa3,0x4c,0xb8,0x85,0xb6,0x39,0xa1,0x85,0x79,0x2d,0x4f,0x91,0x3d,0x45, +0x4e,0x6c,0x73,0x52,0x96,0x8d,0xac,0x64,0xb2,0x5a,0xa0,0x40,0x7e,0xd5,0x5d,0x50, +0x9c,0x31,0x10,0xe5,0xa2,0x43,0x00,0x00,0x1b,0x66,0x33,0x11,0x6d,0xc9,0xa6,0x89, +0xc4,0x75,0xc5,0x65,0xac,0xb0,0x76,0x8d,0x44,0xca,0x36,0x51,0x4e,0x4d,0x7c,0x4c, +0xa6,0x4a,0xbc,0xb0,0xad,0x65,0x89,0xb5,0x9c,0x31,0x10,0xc2,0x92,0x33,0x00,0x00, +0x52,0x01,0x2c,0x8d,0x2b,0xac,0x52,0xc2,0x95,0xa2,0xc0,0x04,0xc1,0x2a,0xa2,0xdc, +0x73,0x0c,0x50,0x63,0x57,0x03,0x6e,0x6b,0x87,0x22,0x92,0x5c,0x9d,0x92,0x94,0x9b, +0x9c,0x31,0x10,0xa6,0x72,0x32,0x00,0x00,0x85,0x65,0x55,0x4a,0x38,0xb4,0x4c,0xdb, +0xa1,0x0c,0xd6,0xa2,0xbd,0x21,0x76,0x8b,0x65,0x9c,0x76,0xd1,0x87,0x1d,0x8d,0x62, +0x89,0x23,0x8f,0x52,0xad,0x54,0xa0,0xa2,0x9c,0x31,0x10,0x29,0x72,0x33,0x00,0x00, +0x65,0x5c,0x48,0x13,0x79,0xa3,0xb6,0x9b,0xc9,0x9c,0xa4,0xe1,0x7a,0x5c,0x70,0x6b, +0x8c,0xd4,0x85,0x22,0x6e,0xdc,0x7c,0x9b,0xb4,0x9b,0xc8,0x62,0xa0,0xc3,0x60,0x2c, +0x9c,0x31,0x10,0x03,0xa8,0x99,0x40,0x00,0x79,0xdb,0x7d,0xdb,0x81,0xdb,0x81,0xdb, +0x7d,0xdb,0x7d,0xdb,0x85,0xdb,0x85,0xdb,0x8e,0x1b,0x99,0x9b,0xf7,0x24,0xf8,0xcb, +0x8e,0x6b,0x7d,0x53,0x6e,0x65,0x61,0x90,0x9c,0x31,0x10,0x4d,0xa6,0x79,0x30,0x00, +0x46,0x57,0x30,0xb9,0x16,0x9b,0x11,0x53,0x1e,0x36,0x32,0x37,0x39,0xa9,0x4d,0xc6, +0x6d,0xb7,0x8d,0xa7,0x9d,0xc8,0x99,0xa6,0x91,0xc6,0x89,0xa7,0x89,0xb7,0x95,0xb7, +0x9c,0x31,0x10,0xa5,0xc4,0x67,0x30,0x00,0x8c,0x23,0x8f,0x93,0x8c,0x63,0x7f,0x53, +0x6f,0x63,0x70,0x13,0x8c,0x5b,0xad,0x5b,0xae,0x1b,0x83,0x92,0x4d,0x1b,0x41,0x8c, +0x75,0x2a,0xbd,0x95,0xd7,0x61,0xa2,0x5c,0x9c,0x31,0x10,0x81,0xc7,0x78,0x30,0x00, +0x4c,0xda,0x21,0x1b,0x4e,0xd4,0xa4,0xe3,0xd8,0xdc,0xbe,0xda,0x75,0x1b,0x30,0x4a, +0x2f,0x2c,0x72,0xcb,0xbc,0xe3,0xcc,0xd4,0x9a,0xe1,0x53,0x1c,0x27,0x22,0x48,0xd6, +0x9c,0x31,0x10,0x86,0xc7,0x89,0x30,0x00,0x9c,0xda,0xce,0xdc,0xb8,0xda,0x74,0xe4, +0x34,0x4a,0x31,0x2d,0x76,0xca,0xc1,0x2b,0xca,0xcb,0x92,0xea,0x4d,0x13,0x27,0x22, +0x54,0xd5,0xa8,0xe2,0xd2,0xd4,0xae,0x9a,0x9c,0x31,0x10,0xad,0xc7,0x89,0x40,0x00, +0x69,0x1c,0x2c,0x52,0x39,0x2c,0x8a,0xcb,0xcd,0x2b,0xc2,0xd3,0x82,0xe3,0x40,0xdc, +0x2b,0x51,0x6a,0xdc,0xbb,0x1a,0xcc,0x9c,0x9a,0xdb,0x57,0x1b,0x28,0xa4,0x50,0xd9, +0x9c,0x31,0x10,0xaa,0xc7,0x78,0x40,0x00,0xa6,0xdd,0xce,0xda,0xaa,0xdc,0x68,0xdb, +0x30,0x52,0x3d,0x1e,0x8e,0xd9,0xcb,0x1c,0xb8,0xd9,0x7a,0xdd,0x3e,0xe2,0x31,0x49, +0x7a,0xe6,0xc4,0xd2,0xc2,0xa4,0x8a,0xda,0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00, +0x51,0x5c,0x2e,0xae,0x68,0xc9,0xb8,0xeb,0xc6,0xd1,0x96,0xe4,0x5d,0x1a,0x2e,0x12, +0x55,0x2c,0xaa,0x8c,0xca,0xe3,0xa2,0xd3,0x6c,0xdb,0x38,0x1c,0x43,0x93,0x9a,0xa8, +0x9c,0x31,0x10,0xad,0xc7,0x89,0x40,0x00,0xc9,0x03,0xaa,0xf3,0x78,0xcb,0x44,0xeb, +0x35,0x51,0x86,0xde,0xc5,0x22,0xb2,0x93,0x84,0xeb,0x53,0x4b,0x2c,0xb4,0x70,0xd9, +0xc0,0xd3,0xba,0xab,0x8e,0xd3,0x65,0x2b,0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00, +0x2e,0x52,0x55,0x26,0xb4,0xa2,0xbe,0xd2,0x98,0xe4,0x74,0xd3,0x3a,0xa3,0x39,0x52, +0xa2,0xdc,0xc4,0xe3,0xa2,0xda,0x84,0xdc,0x4f,0x12,0x24,0xed,0x84,0xd1,0xc4,0x93, +0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00,0xa8,0xee,0x92,0xd9,0x6b,0x24,0x24,0x0a, +0x5d,0x1d,0xc0,0xa3,0xae,0xd9,0x99,0x14,0x82,0xdb,0x34,0xac,0x33,0x59,0xae,0xc5, +0xb6,0xe3,0x9d,0x2b,0x96,0x9c,0x53,0x53,0x9c,0x31,0x10,0xd5,0xc8,0x88,0x20,0x00, +0x1a,0x52,0x85,0x32,0xc2,0x55,0x9e,0xca,0xa2,0xd2,0x7a,0xdb,0x20,0x6c,0x45,0x91, +0xba,0x9c,0xa4,0xd4,0xa3,0x22,0xa0,0xa4,0x49,0x53,0x18,0x13,0x90,0xea,0xb4,0x64, +0x9c,0x31,0x10,0x74,0xc9,0x78,0x30,0x00,0x98,0xeb,0xae,0xe2,0x7e,0xe4,0x26,0xab, +0x43,0x42,0xb0,0xc4,0x9f,0x0b,0xa4,0xc2,0xa8,0x8b,0x58,0xeb,0x1c,0x41,0x75,0x24, +0xb0,0xa4,0x97,0x4a,0xb1,0x2c,0x97,0x14,0x9c,0x31,0x10,0xc3,0xc8,0x67,0x20,0x00, +0x47,0x74,0x28,0x31,0x8c,0x91,0xa4,0x4d,0x9c,0xc9,0xb1,0x49,0x89,0x8d,0x39,0x85, +0x36,0xf1,0x8c,0x4d,0x9a,0x4d,0xaa,0x8a,0xb3,0x01,0x83,0xc4,0x41,0xa9,0x37,0x31, +0x9c,0x31,0x10,0x4d,0xc9,0x56,0x30,0x00,0x72,0x25,0x8e,0xca,0xb8,0xe9,0xbf,0x46, +0x93,0x0c,0x50,0xe8,0x2c,0xd2,0x58,0x8e,0x85,0x0b,0xbb,0x02,0xcb,0x0b,0xa6,0xeb, +0x66,0xe4,0x26,0xcd,0x3c,0xeb,0x71,0x08,0x9c,0x31,0x10,0xf0,0xc8,0x45,0x20,0x00, +0xb1,0x74,0xd3,0x71,0xbb,0xa6,0x7f,0x86,0x2c,0x15,0x27,0xe4,0x5c,0x64,0xa0,0x59, +0xd4,0xa9,0xce,0x6a,0x98,0x65,0x41,0x8a,0x19,0x99,0x43,0x38,0x84,0xa4,0xc9,0x75, +0x9c,0x31,0x10,0x5f,0xc7,0x34,0x20,0x00,0xdc,0x05,0xb3,0xc6,0x66,0x62,0x1e,0x31, +0x26,0xd5,0x63,0x20,0xaf,0x80,0xde,0x95,0xcd,0x75,0x90,0x66,0x3c,0x9a,0x13,0x66, +0x3f,0x76,0x86,0x85,0xce,0x79,0xe1,0x58,0x9c,0x31,0x10,0x2f,0xc7,0x32,0x00,0x00, +0xb9,0x85,0x6a,0x79,0x21,0x69,0x1c,0xa6,0x56,0x20,0xa4,0xb2,0xe1,0x65,0xda,0x96, +0x9d,0x64,0x4c,0x84,0x15,0x41,0x28,0xb6,0x6f,0x35,0xc1,0xa5,0xe7,0x35,0xca,0xb5, +0x9c,0x31,0x10,0x37,0xc7,0x22,0x00,0x00,0x85,0x45,0x38,0xa1,0x13,0x44,0x3a,0xb9, +0x84,0x36,0xcf,0xb8,0xe2,0x19,0xbb,0xc1,0x6f,0x21,0x32,0xc5,0x1a,0x25,0x4b,0xd9, +0x93,0x15,0xd8,0xe1,0xd8,0x01,0xab,0xc1,0x9c,0x31,0x10,0x37,0xc7,0x22,0x00,0x00, +0x65,0x29,0x31,0xc1,0x21,0x20,0x56,0xd6,0x9f,0x16,0xd6,0xd9,0xce,0x26,0x9a,0xc9, +0x60,0x38,0x32,0xb5,0x31,0x30,0x5f,0xb5,0xab,0x46,0xcd,0xa1,0xc3,0x55,0x8b,0x89, +0x9c,0x31,0x10,0xfa,0xc6,0x42,0x00,0x00,0x62,0xb4,0x3a,0xb3,0x40,0xcb,0x67,0xa3, +0xa6,0xdb,0xc1,0x92,0xb5,0xe5,0x8b,0x8b,0x67,0xea,0x4e,0x8a,0x4d,0xec,0x6d,0x1b, +0x97,0x53,0xaf,0xa2,0xa7,0xd3,0x8c,0xa4,0x9c,0x31,0x10,0x8e,0xb6,0x43,0x00,0x00, +0x61,0x68,0x3c,0xc5,0x37,0x10,0x62,0xb6,0x99,0x0c,0xbe,0xc5,0xb6,0xe5,0x97,0x09, +0x6c,0xd0,0x54,0xf5,0x52,0xf1,0x69,0x09,0x8a,0xc6,0x9e,0xf1,0xa4,0xcd,0x88,0xec, +0x9c,0x31,0x10,0x09,0xa5,0x53,0x00,0x00,0x61,0x6d,0x52,0x75,0x4d,0x50,0x6c,0xad, +0x90,0x0a,0xa4,0xc8,0xb5,0x4d,0x95,0x72,0x91,0x8d,0x80,0x2c,0x7d,0x8d,0x85,0x2d, +0x79,0x8d,0x63,0x6d,0x4a,0x50,0x3b,0x74,0x9c,0x31,0x10,0x11,0xa5,0x43,0x00,0x00, +0x47,0x59,0x74,0x4e,0xa5,0x84,0xc8,0x6e,0xe0,0x35,0xc3,0x91,0xb0,0x6d,0x90,0x49, +0x65,0x91,0x52,0xac,0x58,0x4e,0x47,0x70,0x42,0x89,0x4f,0x09,0x6e,0x8d,0xa7,0x51, +0x9c,0x31,0x10,0x7e,0xa7,0x33,0x00,0x00,0xd3,0x76,0xc9,0x75,0xac,0x75,0x7c,0x75, +0x68,0x85,0x5e,0x74,0x3e,0x85,0x58,0x65,0x67,0x88,0x6c,0x65,0xa8,0x95,0x98,0x45, +0xa6,0xb5,0xa4,0x25,0x50,0x91,0x76,0x81,0x9c,0x31,0x10,0xf1,0xa7,0x32,0x00,0x00, +0x51,0x41,0x8f,0xc5,0x75,0x35,0x61,0xa8,0xc3,0x55,0x64,0x65,0x7a,0x95,0xa3,0x65, +0x44,0x76,0x75,0x89,0x88,0x66,0x69,0x80,0x8c,0x76,0x9a,0x74,0x83,0x75,0x7e,0x76, +0x9c,0x31,0x10,0x8c,0x96,0x33,0x00,0x00,0x72,0xb5,0x89,0x25,0x2e,0x64,0x95,0xc5, +0xc0,0x21,0x5d,0x55,0xaf,0x01,0x76,0x81,0x55,0x94,0x98,0xb6,0x64,0xc6,0xa7,0x85, +0x70,0x56,0x69,0x95,0xb0,0xa5,0x5c,0xd5,0x9c,0x31,0x10,0x13,0x85,0x33,0x00,0x00, +0x73,0xcd,0xac,0x31,0x59,0x49,0xbb,0x69,0x64,0x69,0x91,0x89,0xca,0x6d,0x36,0xed, +0x7d,0x49,0xc6,0xae,0x74,0xe9,0x63,0x68,0x4c,0x64,0x69,0x11,0x94,0xe9,0x70,0xc5, +0x9c,0x31,0x10,0x69,0x75,0x33,0x10,0x00,0x5a,0x1c,0xb6,0x0b,0x45,0x23,0x22,0x5e, +0x25,0x93,0x8d,0xdb,0xad,0x62,0xc2,0x1a,0xe9,0xdb,0xb2,0x19,0xda,0x0b,0x79,0x13, +0x7f,0x1c,0xb8,0xe5,0x62,0x56,0x5d,0x9d,0x9c,0x31,0x10,0x35,0x85,0x24,0x10,0x00, +0x95,0x0b,0x68,0xaa,0x6d,0x31,0x86,0x8b,0x7b,0x74,0x5c,0x84,0xa1,0x94,0xc8,0xab, +0x82,0xf4,0x7c,0xd2,0x5d,0x13,0x34,0xca,0x56,0xcb,0x54,0xea,0x59,0x23,0x8c,0xcc, +0x9c,0x31,0x10,0xa7,0x85,0x33,0x10,0x00,0x90,0xa6,0x85,0x26,0x6c,0xad,0x65,0x0c, +0x8a,0xad,0x30,0xcd,0x95,0x8e,0x8c,0xaa,0x63,0x09,0x6a,0x4d,0x77,0xc4,0x4a,0x70, +0x6b,0x08,0x92,0xb1,0x9b,0x4a,0xb6,0xf2,0x9c,0x31,0x10,0x56,0x86,0x34,0x20,0x00, +0xe0,0xe4,0xe5,0x33,0x98,0x93,0x8d,0x6b,0x7a,0x6d,0x4f,0x44,0x80,0x93,0x51,0x2a, +0x73,0x09,0x64,0xd1,0x75,0x0a,0x64,0xac,0x6f,0x6d,0x6e,0x8b,0x7b,0x22,0xb0,0xf4, +0x9c,0x31,0x10,0xe3,0x75,0x34,0x10,0x00,0x71,0x6c,0xbd,0x9b,0xc5,0x81,0x62,0x62, +0xae,0x6b,0x54,0x23,0x0f,0xac,0xb1,0xe3,0x50,0xdb,0x7f,0xa3,0x7c,0xdc,0x39,0xe4, +0x76,0x1c,0x59,0xe2,0x2a,0x61,0x9d,0x59,0x9c,0x31,0x10,0x31,0x87,0x35,0x00,0x00, +0x40,0xec,0x91,0x0c,0x58,0xb2,0x3b,0x72,0xa0,0xab,0x34,0xf3,0x81,0x0d,0x90,0xeb, +0x75,0x21,0x96,0x8b,0x8b,0x0d,0x7c,0xe3,0xb2,0xea,0xa2,0xcb,0x7f,0x0b,0x9c,0xcb, +0x9c,0x31,0x10,0x06,0x96,0x34,0x00,0x00,0x91,0x94,0x84,0x2d,0x71,0x6b,0x94,0xd1, +0x7f,0x2b,0x94,0xcb,0x75,0x2b,0x82,0xa2,0x83,0x24,0x66,0x8c,0x8f,0x8b,0xa6,0x21, +0x87,0x42,0x81,0x0e,0x2a,0x4c,0x35,0x82,0x9c,0x31,0x10,0x20,0xc9,0x46,0x10,0x00, +0x7a,0xeb,0x8e,0xeb,0x90,0xeb,0x8c,0xcb,0x6c,0xeb,0x51,0x0b,0x5c,0xcc,0x95,0x0a, +0xc2,0xcb,0xa4,0xec,0x7e,0xea,0x43,0x0b,0x30,0xa2,0x6f,0x85,0xde,0x2c,0x99,0x90, +0x9c,0x31,0x10,0x9a,0xca,0x46,0x10,0x00,0xc6,0xc5,0x69,0x06,0x31,0x35,0x1e,0x49, +0xc1,0xc6,0xa2,0x35,0xa7,0x75,0xc6,0xc4,0x5a,0xd5,0x27,0x59,0x1e,0x78,0xd9,0x45, +0x7c,0xd6,0xbc,0xd4,0xc1,0x49,0x5a,0xa6,0x9c,0x31,0x10,0x25,0xca,0x67,0x10,0x00, +0x29,0x49,0x24,0xa8,0xd4,0xf6,0x71,0x25,0xc2,0xb4,0xb5,0x55,0x74,0xb6,0x2d,0x04, +0x1c,0xa9,0xcd,0x36,0x6e,0xd5,0xbf,0x04,0xb2,0xe5,0x84,0xd5,0x3b,0x20,0x0e,0x46, +0x9c,0x31,0x10,0x83,0xcb,0x66,0x00,0x00,0xbd,0x74,0x78,0x84,0xad,0x46,0xb8,0xc6, +0x8f,0x01,0x5c,0xf9,0x00,0xd0,0x9d,0x76,0x8e,0x36,0x8d,0x94,0xc8,0x95,0x8f,0x2a, +0x80,0xe5,0x0d,0x09,0x5f,0x04,0xb4,0x86,0x9c,0x31,0x10,0x8d,0xcc,0x67,0x20,0x00, +0x5f,0x46,0xdc,0xb5,0x89,0x01,0x9c,0xf5,0x32,0xf1,0x1c,0xc6,0xcd,0x34,0x4c,0xe4, +0xd0,0xe6,0x96,0xf5,0xa1,0x14,0x6a,0xd9,0x08,0xfa,0x8d,0x65,0x8a,0x54,0x85,0x65, +0x9c,0x31,0x10,0xa7,0xcc,0x78,0x30,0x00,0xc5,0xac,0x85,0xea,0x9d,0xaa,0x36,0x64, +0x21,0x24,0xc6,0x29,0x4a,0x4b,0xd5,0x8c,0x85,0xeb,0xaa,0x52,0x6d,0xac,0x15,0xd4, +0x6e,0xc9,0x94,0x8a,0x72,0xcd,0xc9,0xcb,0x9c,0x31,0x10,0x8c,0xcc,0x78,0x40,0x00, +0x81,0xea,0xa9,0xa4,0x56,0x6b,0x09,0x21,0xaf,0x0c,0x59,0x6b,0xb1,0xea,0x9d,0xab, +0x9a,0x24,0x91,0xab,0x42,0x43,0x19,0x64,0xc1,0xea,0x4a,0x6c,0xd1,0xac,0x85,0xca, +0x9c,0x31,0x10,0x21,0xcc,0x77,0x30,0x00,0xac,0xf5,0x80,0xf5,0x34,0xf0,0x33,0x06, +0xb8,0xa5,0x51,0x64,0xd6,0xc6,0x7f,0x05,0xb2,0xe5,0x79,0x05,0x2c,0xd4,0x45,0x2a, +0xaa,0x75,0x5d,0x74,0xd2,0xc5,0x81,0x16,0x9c,0x31,0x10,0x8c,0xcc,0x78,0x40,0x00, +0xad,0x8b,0x7a,0x2a,0x2d,0xab,0x42,0x2d,0xa8,0xeb,0x5a,0xea,0xd1,0x8c,0x82,0x2c, +0xad,0x8a,0x82,0x0b,0x35,0xc4,0x2d,0xe4,0xb1,0x69,0x52,0xcc,0xd1,0x8c,0x82,0x0b, +0x9c,0x31,0x10,0xf0,0xcb,0x88,0x40,0x00,0xad,0x12,0x8a,0x13,0x49,0xd4,0x15,0x89, +0xb6,0x93,0x4e,0x9c,0xc9,0x1a,0x89,0x9a,0xa9,0x9c,0x8e,0x5c,0x62,0x1a,0x09,0xad, +0x9f,0x1c,0x60,0xa1,0xad,0xdc,0x99,0x9c,0x9c,0x31,0x10,0xfe,0xcb,0x77,0x40,0x00, +0x9d,0x54,0x9d,0x08,0x7a,0xe9,0x24,0xd4,0x57,0x19,0x84,0x05,0x87,0xd4,0xb0,0xc5, +0x97,0x26,0xa4,0xb5,0x94,0xb5,0x47,0x15,0x26,0xc0,0x83,0x82,0x6d,0x35,0xb4,0x75, +0x9c,0x31,0x10,0xfe,0xcb,0x77,0x40,0x00,0x9b,0x05,0xa6,0xd5,0xa9,0x55,0x6f,0x05, +0x28,0xd4,0x48,0xf6,0x7e,0x25,0x8d,0xb5,0xae,0xe5,0xa3,0x05,0xa6,0xc5,0x98,0xb5, +0x4f,0x45,0x22,0xea,0x6f,0xa8,0x74,0x74,0x9c,0x31,0x10,0x63,0xca,0x77,0x40,0x00, +0xaa,0x75,0xa3,0x25,0xa3,0x15,0xa5,0x65,0x80,0x25,0x45,0x05,0x28,0xa4,0x83,0xe2, +0x75,0x95,0xb0,0x15,0x9c,0xf5,0xa0,0xc5,0xa7,0x95,0x72,0xa5,0x44,0xb5,0x2e,0x70, +0x9c,0x31,0x10,0xd5,0xcb,0x77,0x30,0x00,0x85,0x21,0x77,0x86,0xae,0xb5,0x9c,0xd5, +0xa2,0xd5,0xa7,0x35,0x70,0xf5,0x4a,0xc5,0x2c,0xc0,0x83,0x51,0x77,0x75,0xaa,0x95, +0x98,0xe5,0xa4,0xd5,0xa5,0x35,0x7a,0xb5,0x9c,0x31,0x10,0xfe,0xcb,0x77,0x40,0x00, +0x54,0xf5,0x28,0xe9,0x7b,0xa5,0x72,0xc9,0xa6,0x99,0x98,0xf5,0xa1,0x15,0xa5,0x15, +0x8a,0xd5,0x5f,0x35,0x33,0x04,0x57,0x2a,0x80,0x06,0x8d,0x45,0xa3,0x15,0x9b,0x35, +0x9c,0x31,0x10,0xd5,0xcb,0x77,0x30,0x00,0xa2,0xd5,0xa0,0xe9,0x6d,0x05,0x52,0xd5, +0x2c,0xb0,0x85,0x62,0x71,0x65,0xaa,0xa5,0x92,0xd5,0xa2,0xd5,0xa3,0x25,0x8a,0xe5, +0x69,0x15,0x3c,0xf1,0x4a,0xe2,0x82,0x45,0x9c,0x31,0x10,0x71,0xcb,0x76,0x40,0x00, +0x81,0xa1,0xa6,0xf5,0x95,0x15,0xa2,0xa5,0x9e,0xe5,0x7c,0xf5,0x63,0x15,0x30,0xf5, +0x63,0x49,0x78,0x26,0x93,0x25,0x9f,0x05,0x99,0x35,0xa2,0xe5,0x9a,0xc5,0x78,0xe5, +0x9c,0x31,0x10,0xd2,0xcb,0x86,0x30,0x00,0x63,0x0d,0x31,0x0c,0x69,0x54,0x76,0x2e, +0x94,0xed,0x9a,0xed,0x9b,0x2d,0xa2,0xed,0x98,0xad,0x7a,0xed,0x65,0x0d,0x34,0xe8, +0x5f,0x32,0x7a,0x2e,0x91,0x0d,0x9c,0xed,0x9c,0x31,0x10,0x02,0xbb,0x86,0x40,0x00, +0xae,0x6d,0xc9,0xed,0xb5,0x6d,0x82,0x0d,0x56,0x2d,0x06,0x09,0x09,0x64,0x89,0x28, +0x7b,0x49,0xc9,0xed,0x9d,0xed,0xc1,0x4d,0xbe,0x0d,0x8a,0x4e,0x6d,0xae,0x31,0xee, +0x9c,0x31,0x10,0x76,0xcb,0x87,0x40,0x00,0x32,0xd6,0x79,0x71,0x74,0xd0,0xa2,0xb1, +0x90,0xcd,0x98,0xed,0xa3,0x2d,0x8e,0xad,0x80,0xed,0x6b,0x0d,0x48,0xee,0x44,0xc5, +0x84,0x88,0x7f,0x89,0xa0,0xed,0x8e,0xed,0x9c,0x31,0x10,0x69,0xcb,0x66,0x40,0x00, +0x9e,0xa5,0xa1,0x01,0x83,0x11,0x80,0xc1,0x63,0x15,0x3a,0xf0,0x5f,0x5a,0x7e,0x26, +0x8d,0x15,0x9b,0x01,0x93,0x45,0xa2,0xd5,0x98,0xc5,0x81,0x15,0x7e,0xd4,0x61,0x05, +0x9c,0x31,0x10,0x71,0xcb,0x76,0x40,0x00,0x3a,0xd4,0x67,0x78,0x7c,0x46,0x8e,0xf5, +0x94,0xf5,0x95,0x46,0xa2,0xf6,0x94,0xc5,0x80,0xf5,0x80,0xd4,0x65,0x15,0x40,0xe0, +0x5f,0x56,0x82,0x36,0x89,0x25,0x9a,0xf5,0x9c,0x31,0x10,0x8d,0xbb,0x87,0x40,0x00, +0x9e,0x8d,0xc5,0xad,0xa9,0x8d,0x81,0xed,0x8d,0xe9,0x52,0x29,0x19,0xea,0x0d,0xc5, +0x99,0x08,0x76,0xe9,0xbd,0xed,0x92,0x2d,0xc1,0x8d,0xb9,0xed,0x81,0xed,0x96,0x2d, +0x9c,0x31,0x10,0x76,0xcb,0x87,0x40,0x00,0x70,0xed,0x63,0x11,0x32,0xb6,0x81,0x71, +0x74,0xd0,0x9a,0xad,0x88,0xcd,0x99,0x0d,0xa3,0x0d,0x8e,0xcd,0x80,0xed,0x82,0xcd, +0x65,0x0d,0x48,0xc9,0x4f,0x0a,0x8c,0x4d,0x9c,0x31,0x10,0x71,0xcb,0x76,0x40,0x00, +0x7f,0x60,0x9e,0xf5,0x8b,0x25,0xa2,0xc4,0x9a,0xe4,0x7e,0xf5,0x8b,0x25,0x70,0xf6, +0x63,0x06,0x30,0xba,0x83,0x88,0x74,0xb8,0x98,0xd9,0x8a,0xb5,0x99,0x24,0xa5,0x15, +0x9c,0x31,0x10,0xb4,0xba,0x86,0x30,0x00,0x9d,0xad,0x81,0xcd,0x85,0x4d,0x4e,0x2d, +0x15,0xea,0x0d,0xc4,0xa0,0xa8,0x6f,0xc9,0xc5,0xed,0x8e,0x2d,0xcc,0xed,0xb9,0xed, +0x8a,0x0e,0x92,0xad,0x6d,0xad,0x42,0x2d,0x9c,0x31,0x10,0x71,0xcb,0x76,0x40,0x00, +0x34,0xb8,0x6d,0x68,0x7e,0x76,0x8d,0x05,0x96,0xd5,0x93,0x35,0xa4,0xf5,0x92,0xe5, +0x80,0xe5,0x8a,0xf5,0x6b,0x05,0x5b,0x15,0x32,0xca,0x85,0x56,0x74,0xf5,0x98,0xe5, +0x9c,0x31,0x10,0xec,0xca,0x76,0x40,0x00,0x8e,0x85,0x9b,0x15,0xa3,0x35,0x88,0xf5, +0x80,0xd5,0x88,0xc5,0x69,0x15,0x53,0x15,0x3c,0x90,0x91,0x01,0x75,0xb6,0xa0,0xe5, +0x88,0xc5,0x9e,0xa5,0x9d,0x25,0x83,0x25,0x9c,0x31,0x10,0x3c,0xba,0x76,0x30,0x00, +0x89,0xe9,0x89,0x6d,0x52,0x2d,0x1e,0x09,0x0d,0xa0,0xa0,0xe8,0x6b,0x69,0xbe,0x0d, +0x91,0xcd,0xbd,0x2d,0xb6,0x2d,0x82,0x4d,0x8e,0x2d,0x81,0x2d,0x4e,0x0d,0x1d,0xea, +0x9c,0x31,0x10,0x3c,0xba,0x76,0x30,0x00,0x1e,0x05,0x9c,0xc8,0x6f,0x29,0xbe,0x0d, +0x95,0xed,0xbd,0x4d,0xb2,0x0d,0x82,0x4d,0x8a,0x31,0x79,0x6d,0x4a,0x0d,0x1d,0xc9, +0x2e,0x2a,0x9c,0x8d,0x7a,0xe9,0xba,0x2d,0x9c,0x31,0x10,0x1c,0xba,0x65,0x20,0x00, +0x96,0x2d,0xbd,0x6d,0xa9,0xcd,0x7a,0x2d,0x8a,0x2c,0x6d,0xac,0x46,0x11,0x15,0x8c, +0x4e,0xd5,0x94,0x92,0x8a,0x4d,0xb1,0xed,0x9a,0x6d,0xbd,0xcd,0x9d,0xad,0x75,0xc9, +0x9c,0x31,0x10,0x67,0xb9,0x65,0x10,0x00,0x87,0x29,0x62,0xad,0x47,0x2d,0x1a,0x91, +0x6b,0xd4,0x92,0x31,0x9a,0xee,0xae,0xae,0xa3,0x6d,0xb4,0xed,0x8e,0xad,0x72,0xec, +0x7b,0x0d,0x51,0x0d,0x36,0xed,0x34,0x88,0x9c,0x31,0x10,0xc0,0xb9,0x54,0x10,0x00, +0x8f,0x01,0x91,0x75,0xaf,0x06,0xa6,0xa5,0xaa,0xc5,0xa3,0x24,0x7b,0x24,0x72,0xd6, +0x60,0xc6,0x3d,0x16,0x31,0x05,0x75,0x28,0x90,0xb4,0xa8,0xf5,0xae,0xf5,0xa9,0x25, +0x9c,0x31,0x10,0x9c,0xb7,0x42,0x00,0x00,0xa6,0xcd,0x84,0xd6,0x6e,0xd1,0x62,0xd0, +0x44,0xcd,0x38,0xa8,0x69,0x85,0x8e,0x69,0xa3,0x2a,0xb0,0xca,0xab,0x29,0xaa,0xe8, +0x92,0x89,0x63,0x2a,0x49,0x6d,0x30,0xad,0x9c,0x31,0x10,0x5b,0xb7,0x33,0x00,0x00, +0x46,0x6a,0x83,0x95,0x9d,0x85,0xb7,0x54,0xb6,0x55,0xac,0xa9,0x9d,0x99,0x72,0x6a, +0x4d,0x39,0x3d,0x79,0x42,0x98,0x6b,0x61,0x93,0x75,0xb0,0x76,0xbf,0x76,0xb6,0x85, +0x9c,0x31,0x10,0x64,0xb5,0x23,0x00,0x00,0x98,0x84,0x65,0x21,0x3f,0x81,0x35,0x51, +0x52,0xc1,0x7e,0x56,0xa6,0x86,0xbc,0x55,0xb8,0x81,0xa1,0x64,0x7c,0x65,0x54,0xba, +0x47,0x5a,0x4f,0x95,0x73,0x59,0x90,0x75,0x9c,0x31,0x10,0xd6,0xa5,0x32,0x00,0x00, +0xc8,0x45,0xd5,0xa5,0xbf,0xb4,0x97,0x85,0x5e,0x05,0x38,0x85,0x31,0x51,0x50,0xd5, +0x7c,0x45,0x9f,0x85,0xb7,0x45,0xb9,0xa5,0xa7,0x94,0x85,0x74,0x5a,0x45,0x49,0x81, +0x9c,0x31,0x10,0x2d,0x95,0x21,0x00,0x00,0x16,0xc6,0x55,0x4c,0x8e,0xf1,0xbd,0x51, +0xce,0x48,0xc0,0xcc,0x9b,0x2d,0x67,0x0e,0x44,0xee,0x3c,0xb2,0x4f,0x4d,0x72,0x89, +0x90,0xce,0xa8,0xec,0xa9,0x71,0x9b,0x71,0x9c,0x31,0x10,0x62,0x75,0x12,0x00,0x00, +0x8e,0xd2,0x2a,0x35,0x08,0x8c,0x03,0x0d,0x41,0x04,0x7a,0xeb,0xaa,0xe2,0xca,0xd3, +0xb4,0xd2,0x9e,0xcb,0x72,0xac,0x5b,0x22,0x4c,0xea,0x5d,0x0a,0x7a,0xcc,0x87,0x03, +0x9c,0x31,0x10,0x8c,0x55,0x21,0x00,0x00,0xc2,0x35,0xd2,0x11,0xc5,0x0d,0xad,0x0c, +0x75,0xcd,0x43,0x09,0x17,0x0e,0x36,0x55,0x60,0xd5,0x89,0x2d,0xb5,0xd2,0xa2,0x49, +0x9a,0x29,0x51,0xf0,0x6a,0x31,0x92,0x30,0x9c,0x31,0x10,0xcd,0x53,0x11,0x00,0x00, +0x9d,0xb3,0xd9,0x0c,0xb4,0x4b,0x8e,0x9a,0x72,0x53,0x5b,0x5a,0x6a,0x6d,0x7a,0x2b, +0x8d,0xe3,0x7c,0xe3,0x6e,0x23,0x7d,0x94,0x91,0x13,0x7e,0x13,0x5a,0x92,0x5a,0xd4, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_LANGUAGE_SWITCH.txt b/config/_default_cfg_src_/res/cn/SOUND_LANGUAGE_SWITCH.txt new file mode 100644 index 0000000..0164f01 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_LANGUAGE_SWITCH.txt @@ -0,0 +1,155 @@ +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x76,0x43,0x20,0x21,0x00,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0xd6,0xa4,0x9c,0x31,0x10,0xea,0xcb,0x79,0x87,0x67, +0x7d,0xd5,0x85,0xd5,0x7d,0xa5,0xbe,0xa4,0x84,0x88,0x3a,0xe5,0xdd,0x15,0x0e,0x15, +0xee,0x55,0x20,0xd5,0xbf,0x15,0x68,0x55,0x6b,0x55,0xb4,0x95,0x26,0xd5,0xe5,0x55, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb, +0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2,0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24, +0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2,0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3, +0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c,0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44, +0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00,0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60, +0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71,0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa, +0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75,0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00, +0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30,0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75, +0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca,0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75, +0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00,0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30, +0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5,0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea, +0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15,0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00, +0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb,0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b, +0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35,0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb, +0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00,0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04, +0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52,0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e, +0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90,0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55, +0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21,0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9, +0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5,0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70, +0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65,0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00, +0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41,0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55, +0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba,0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50, +0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69,0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21, +0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65,0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00, +0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba,0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85, +0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50,0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75, +0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00,0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6, +0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb,0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb, +0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10,0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71, +0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51,0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95, +0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00,0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01, +0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78,0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d, +0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76,0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55, +0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a,0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba, +0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75,0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda, +0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85,0x9c,0x31,0x10,0x9c,0xc5,0x54,0x30,0x00, +0xcb,0x6d,0x92,0x2e,0x30,0x89,0x77,0xd6,0xcb,0x69,0x7b,0x28,0x34,0x51,0x8e,0x92, +0xc8,0x89,0x65,0x09,0x3a,0x72,0xa1,0x84,0xba,0xa6,0x56,0x6e,0x4a,0x4e,0xb0,0x89, +0x9c,0x31,0x10,0xd0,0xcb,0x78,0x77,0x56,0xac,0xeb,0x48,0xeb,0x56,0xcb,0xd5,0x03, +0x86,0x65,0x3b,0x6c,0xe0,0x8b,0x0d,0x0b,0xef,0x2b,0x20,0x6b,0xbf,0x8b,0x68,0x2b, +0x6b,0xab,0xb8,0x4b,0x27,0x6b,0xe8,0xab,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb,0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2, +0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24,0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2, +0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3,0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c, +0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44,0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00, +0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60,0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71, +0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa,0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75, +0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00,0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30, +0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75,0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca, +0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75,0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00, +0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30,0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5, +0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea,0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15, +0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00,0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb, +0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b,0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35, +0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb,0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00, +0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04,0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52, +0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e,0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90, +0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55,0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21, +0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9,0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5, +0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70,0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65, +0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00,0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41, +0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55,0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba, +0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50,0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69, +0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21,0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65, +0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00,0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba, +0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85,0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50, +0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75,0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00, +0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6,0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb, +0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb,0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10, +0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71,0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51, +0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95,0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00, +0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01,0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78, +0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d,0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76, +0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55,0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a, +0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba,0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75, +0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda,0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_NINE.txt b/config/_default_cfg_src_/res/cn/SOUND_NINE.txt new file mode 100644 index 0000000..66cf4f6 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_NINE.txt @@ -0,0 +1,130 @@ +0x9c,0x31,0x10,0x54,0x43,0x32,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x81,0xdb, +0x85,0x51,0xa2,0x5a,0x99,0xdc,0x8c,0xdc,0x9e,0x24,0x8d,0x5a,0xc7,0x0c,0xa5,0x98, +0xc4,0xa3,0xb1,0x9d,0xce,0x95,0xd5,0xe2,0x9c,0x31,0x10,0x5d,0x77,0x77,0x30,0x00, +0x83,0xbb,0x8b,0xbb,0x8b,0xb3,0x93,0xbb,0xdb,0x9a,0xe0,0x56,0xa3,0x43,0x93,0x33, +0x6b,0x4a,0x63,0xbc,0x5b,0xb2,0x63,0xbb,0x53,0xbb,0x53,0xbb,0x4b,0xbb,0x44,0x3c, +0x9c,0x31,0x10,0x1b,0x87,0x87,0x30,0x00,0x61,0xc2,0x69,0xb3,0x75,0xbb,0x81,0xbb, +0x89,0xbb,0x9d,0x35,0xcc,0x9c,0x5f,0x52,0x71,0xa1,0x71,0xb4,0x8d,0xc3,0x91,0xa9, +0x95,0xc5,0x91,0xbc,0x85,0xb1,0x7d,0xc3,0x9c,0x31,0x10,0xf2,0x65,0x78,0x40,0x00, +0x62,0xe5,0x6a,0x59,0x7d,0x21,0x7c,0xe2,0x7a,0x9a,0x80,0xde,0x50,0xe2,0x5b,0x15, +0x3a,0x90,0x38,0x9c,0x3b,0xa4,0x3a,0xa4,0x5c,0x55,0x7b,0x59,0x7a,0xb2,0x6a,0xe2, +0x9c,0x31,0x10,0x85,0x55,0x68,0x40,0x00,0x58,0x8e,0x46,0xda,0xa5,0x61,0x78,0xcd, +0xb8,0x20,0xa5,0x64,0xa4,0xdd,0x66,0x9d,0x78,0xa5,0xb6,0xd5,0x96,0x55,0xa9,0x61, +0x45,0x61,0x02,0xd5,0x18,0xa1,0x78,0xa1,0x9c,0x31,0x10,0x2b,0x86,0x88,0x40,0x00, +0x83,0x76,0x83,0x78,0x8a,0x89,0x7b,0x63,0x83,0x76,0x7b,0x8d,0x84,0x76,0x83,0x45, +0x7a,0xc6,0x8b,0x33,0x84,0x87,0x8c,0xbc,0xb4,0x19,0xb9,0xa2,0x5d,0x5a,0x73,0x2c, +0x9c,0x31,0x10,0x35,0x85,0x89,0x30,0x00,0x89,0xd2,0xaa,0x43,0x9e,0x8d,0xa6,0x58, +0x85,0xa3,0x61,0x49,0x50,0x89,0x4d,0x93,0x51,0x48,0x69,0xa9,0x91,0x35,0xa0,0x98, +0xa1,0x79,0x65,0x66,0x35,0x96,0x0e,0x58,0x9c,0x31,0x10,0x9a,0xc6,0x77,0x30,0x00, +0x78,0xd4,0x81,0x23,0x88,0xcb,0x8e,0xe1,0x8a,0xd2,0x78,0xde,0x64,0xe3,0x5c,0xd3, +0x71,0x19,0x96,0xda,0xb4,0xd3,0xb1,0x1e,0x8a,0x91,0x5d,0x6e,0x3a,0x60,0x42,0xd1, +0x9c,0x31,0x10,0x94,0xc6,0x88,0x30,0x00,0x72,0xe5,0xa6,0xd4,0xb6,0xda,0xa8,0xda, +0x9e,0xdc,0x9a,0xe3,0x74,0xd4,0x34,0x1c,0x1b,0x09,0x50,0xf1,0xa0,0xcc,0xc4,0xe4, +0xb2,0xda,0x98,0x93,0x9b,0x5a,0x8c,0x5c,0x9c,0x31,0x10,0x88,0xd7,0x89,0x40,0x00, +0x67,0x5c,0x42,0xeb,0x50,0xc9,0x84,0xe3,0xac,0xdc,0xa6,0xd3,0x8b,0x2a,0x82,0xcb, +0x8e,0xec,0x7e,0xdb,0x50,0x14,0x3d,0x12,0x6a,0xf2,0xa7,0x04,0xb4,0xec,0x94,0xda, +0x9c,0x31,0x10,0x90,0xd7,0x99,0x40,0x00,0x7c,0x93,0x8c,0xe4,0x8e,0x53,0x65,0x5b, +0x33,0x34,0x4c,0xc1,0x98,0xa3,0xbe,0xe4,0xa1,0x0b,0x77,0x22,0x81,0x1b,0xa2,0xa3, +0x87,0x1c,0x3e,0x23,0x27,0x88,0x70,0xe5,0x9c,0x31,0x10,0xcb,0xd8,0x89,0x30,0x00, +0xc0,0xe4,0xb8,0xc2,0x7a,0xeb,0x6a,0x9c,0xa3,0x0b,0xac,0xa2,0x63,0x53,0x16,0x43, +0x3a,0xed,0xaa,0xea,0xcc,0xc2,0x8c,0xec,0x5c,0xdb,0x88,0xd3,0xca,0xdb,0x96,0x9b, +0x9c,0x31,0x10,0xf8,0xd8,0x99,0x40,0x00,0x33,0x54,0x12,0x59,0x6e,0xb3,0xc8,0x9d, +0xa8,0xda,0x60,0xda,0x6c,0xd4,0xba,0xd3,0xc6,0x9b,0x6a,0x9b,0x25,0x54,0x30,0xeb, +0x90,0xf0,0xb8,0x95,0x84,0xdc,0x62,0xda,0x9c,0x31,0x10,0xf8,0xd8,0x99,0x40,0x00, +0x90,0xd3,0xc0,0x9c,0xa6,0x92,0x5e,0x9b,0x3b,0x54,0x40,0xeb,0x88,0xf0,0xa6,0xa4, +0x82,0xdc,0x71,0x12,0x98,0xd3,0xb6,0x54,0x9a,0x4b,0x60,0xa2,0x43,0x94,0x40,0x9b, +0x9c,0x31,0x10,0x66,0xd9,0xa9,0x30,0x00,0x85,0x59,0xa5,0x4c,0x7d,0xcc,0x71,0xc3, +0xa1,0xbb,0xb1,0xb3,0x91,0xb3,0x65,0xb4,0x4a,0xab,0x3c,0xa2,0x80,0xc3,0xa4,0xbc, +0x79,0x42,0x75,0x44,0xa1,0x43,0xa9,0x43,0x9c,0x31,0x10,0xf4,0xda,0x99,0x30,0x00, +0x92,0x64,0x75,0xe3,0x52,0xa3,0x34,0xcb,0x76,0x0c,0xa9,0x91,0x7a,0x14,0x72,0x13, +0xa6,0x13,0xa2,0x14,0x8e,0x5b,0x89,0xa3,0x59,0xdc,0x30,0xea,0x63,0x22,0xb2,0x25, +0x9c,0x31,0x10,0x56,0xd9,0x89,0x30,0x00,0x7b,0x6a,0x71,0x2b,0xa6,0xe4,0x9e,0xa2, +0x8a,0xe4,0x98,0x1b,0x68,0x5a,0x37,0x04,0x4d,0x24,0xa8,0x19,0x82,0x1c,0x6c,0x94, +0xa0,0xd1,0x9d,0x14,0x86,0xd3,0xa3,0x1a,0x9c,0x31,0x10,0x48,0xda,0x88,0x40,0x00, +0x7e,0x5c,0x46,0x63,0x3c,0xac,0x82,0xd4,0x9a,0x20,0x6e,0x65,0x8d,0xdb,0x9d,0x61, +0x85,0x9c,0x9e,0x1b,0x91,0x5a,0x59,0x94,0x42,0x4c,0x56,0x1c,0x98,0xd8,0x7d,0x53, +0x9c,0x31,0x10,0x53,0xcb,0x78,0x30,0x00,0x77,0x05,0xbd,0x2a,0xa1,0x0a,0x9c,0xcd, +0xc8,0xcb,0x7e,0xc9,0x26,0xec,0x0e,0xd4,0x55,0x70,0xbe,0xb5,0x6a,0x8d,0x88,0xc9, +0xbd,0x0b,0x99,0x2c,0xaa,0xca,0xbe,0xd2,0x9c,0x31,0x10,0x53,0xcb,0x78,0x30,0x00, +0x65,0x0d,0x25,0x13,0x0c,0x93,0x7b,0x6c,0xac,0xe9,0x66,0xcb,0xa0,0xcd,0xb3,0x0a, +0x8f,0x0a,0xb8,0xec,0xb0,0xac,0x59,0x0a,0x2b,0x0a,0x0c,0x6c,0x89,0x66,0xa9,0x09, +0x9c,0x31,0x10,0x4b,0xcb,0x68,0x30,0x00,0x68,0xa9,0xa4,0xcc,0xa9,0x0c,0x8d,0x0a, +0xc0,0xca,0xa6,0xac,0x57,0x2b,0x2f,0x12,0x0c,0x6b,0x8b,0x66,0xa8,0xea,0x64,0xa8, +0xa0,0xec,0xab,0x0d,0x8c,0xea,0xba,0xca,0x9c,0x31,0x10,0x53,0xcb,0x78,0x30,0x00, +0xae,0xeb,0x5f,0x2b,0x36,0xcb,0x10,0xb4,0x79,0xac,0xae,0x89,0x66,0xaa,0x99,0x2c, +0xae,0xec,0x88,0xab,0xaf,0x0a,0xb9,0x0b,0x6c,0xec,0x3e,0xac,0x17,0x13,0x55,0x51, +0x9c,0x31,0x10,0x4b,0xcb,0x68,0x30,0x00,0xba,0x4b,0x6f,0x2d,0x89,0x2b,0xb0,0x8a, +0x8e,0xea,0x9f,0x0c,0xc2,0xcc,0x7e,0xeb,0x4a,0xea,0x23,0x03,0x2c,0xad,0xba,0xcb, +0x83,0x49,0x74,0xaa,0xaa,0xec,0x99,0x0c,0x9c,0x31,0x10,0x50,0xca,0x67,0x30,0x00, +0x8e,0x95,0xc7,0x25,0x8f,0x15,0x5e,0xc5,0x31,0x35,0x1a,0x60,0x93,0xe6,0xa2,0x76, +0x68,0xd5,0x97,0x74,0xaa,0x95,0x88,0xf6,0xaf,0x45,0xb2,0x85,0x6d,0x55,0x46,0xc5, +0x9c,0x31,0x10,0x50,0xca,0x67,0x30,0x00,0x1e,0xf9,0x4d,0x48,0xb8,0x36,0x75,0xa6, +0x7a,0xb5,0xae,0xc4,0x95,0x65,0x90,0x95,0xc1,0x16,0x8f,0x05,0x58,0xc5,0x33,0x45, +0x1c,0x50,0x99,0xc5,0x9e,0x96,0x6e,0xc6,0x9c,0x31,0x10,0xe4,0xca,0x67,0x20,0x00, +0x95,0x74,0xaa,0x84,0x8b,0x15,0xa7,0x35,0xb8,0x66,0x71,0x95,0x48,0x84,0x2b,0x34, +0x3a,0xd9,0xb6,0x96,0x83,0x95,0x74,0x64,0xa5,0x44,0x9b,0x15,0x8c,0x85,0xbd,0x95, +0x9c,0x31,0x10,0x79,0xcb,0x67,0x20,0x00,0x8e,0xc5,0x6a,0xf5,0x35,0x25,0x20,0xaa, +0x73,0x76,0xae,0x84,0x79,0x34,0x82,0xf5,0xae,0xc6,0x91,0x36,0x96,0xb5,0xbf,0x05, +0x7b,0x25,0x5c,0xa5,0x2d,0x55,0x24,0x81,0x9c,0x31,0x10,0xcc,0xca,0x57,0x20,0x00, +0x9d,0xb4,0x98,0xb5,0x78,0xc6,0x8f,0x85,0xac,0x65,0x91,0x55,0xa3,0x05,0xac,0x65, +0x73,0xb5,0x46,0x25,0x2b,0xa1,0x36,0x89,0xb4,0xf6,0x89,0x75,0x7c,0x44,0x9b,0xb5, +0x9c,0x31,0x10,0x6b,0xca,0x66,0x20,0x00,0xa4,0x76,0x91,0x16,0xad,0x55,0x9e,0x55, +0x6f,0x95,0x36,0x85,0x2b,0x1a,0x4f,0x34,0xbc,0x54,0x7f,0xc6,0x7c,0x36,0xa3,0x95, +0x9e,0xa4,0x94,0xe4,0xb1,0x65,0x92,0x66,0x9c,0x31,0x10,0x82,0xca,0x56,0x10,0x00, +0x67,0x75,0x2e,0xb4,0x2e,0xd9,0x67,0x76,0xb8,0x25,0x7d,0xd4,0x7e,0x35,0xa5,0x85, +0x9a,0xb6,0x98,0xe5,0xaf,0x45,0x8a,0x95,0x61,0x45,0x2c,0xe5,0x30,0xa0,0x7d,0xa5, +0x9c,0x31,0x10,0x82,0xca,0x56,0x10,0x00,0xb2,0x26,0x7b,0xb5,0x7e,0x54,0xa7,0x64, +0x96,0xc5,0x9e,0xf5,0xab,0x05,0x84,0xe5,0x56,0xf5,0x2d,0x25,0x30,0x81,0x93,0x94, +0xaa,0x55,0x7d,0x76,0x7e,0x95,0xa9,0x35,0x9c,0x31,0x10,0x9a,0xca,0x46,0x10,0x00, +0x94,0xd5,0x9a,0xf5,0xa6,0xf5,0x84,0xf5,0x54,0xe5,0x2b,0x21,0x34,0x91,0x97,0x84, +0xa4,0x75,0x7b,0x76,0x7c,0x96,0xa9,0x35,0x94,0xc5,0x9d,0x14,0xa6,0xd5,0x81,0x05, +0x9c,0x31,0x10,0x16,0xca,0x45,0x10,0x00,0x50,0xd6,0x2d,0x31,0x38,0x86,0x9f,0x74, +0xa0,0x84,0x7b,0x56,0x7a,0xa6,0xab,0x26,0x94,0xd5,0x99,0x14,0xa6,0xd5,0x85,0x16, +0x54,0xd6,0x2b,0x31,0x36,0x91,0x99,0x74,0x9c,0x31,0x10,0xac,0xc9,0x45,0x10,0x00, +0xa6,0x04,0x7a,0xd6,0x7c,0x26,0xa6,0xb5,0x9b,0x35,0x97,0xa4,0xa7,0x45,0x86,0xa6, +0x56,0x45,0x2c,0xb1,0x36,0x16,0x97,0xe4,0xaa,0x05,0x79,0xe6,0x7a,0x16,0xa4,0xc5, +0x9c,0x31,0x10,0x6d,0xc9,0x45,0x20,0x00,0xa3,0x25,0x96,0xc4,0xa2,0x35,0x81,0xb5, +0x59,0x35,0x2c,0xc1,0x38,0x06,0x98,0xe4,0xad,0x04,0x79,0xe6,0x78,0x16,0xa2,0xd5, +0xa8,0x25,0x98,0xd4,0xa0,0x25,0x81,0xc5,0x9c,0x31,0x10,0x16,0xca,0x45,0x10,0x00, +0x5a,0xa5,0x27,0x50,0x3c,0x86,0x9b,0x75,0xae,0x74,0x75,0x65,0x7a,0x95,0xa1,0x55, +0xaa,0x95,0x95,0x51,0x9e,0x95,0x7d,0x55,0x58,0x95,0x25,0x51,0x3c,0x8a,0x9d,0x66, +0x9c,0x31,0x10,0x6d,0xc9,0x45,0x20,0x00,0xb3,0x04,0x75,0xd4,0x7a,0x15,0x9d,0xc6, +0xb0,0x25,0x93,0xc5,0xa0,0x25,0x7b,0xc5,0x5d,0x25,0x1e,0xc4,0x41,0x18,0xa0,0xd6, +0xb1,0x25,0x72,0xc4,0x78,0x25,0x9b,0xb6,0x9c,0x31,0x10,0x6d,0xc9,0x45,0x20,0x00, +0xb0,0x36,0x90,0xb5,0x9f,0x34,0x79,0xa5,0x5f,0x45,0x21,0xb5,0x43,0x38,0xa0,0xb6, +0xb4,0x35,0x74,0xa4,0x76,0x44,0x97,0xa6,0xb1,0x56,0x91,0x95,0x9c,0x54,0x77,0x95, +0x9c,0x31,0x10,0x79,0xc8,0x35,0x10,0x00,0x62,0x3c,0x24,0xca,0x3f,0x11,0x97,0xdd, +0xb9,0x1b,0x79,0xc9,0x74,0x3b,0x92,0xb5,0xb3,0x55,0x95,0xa2,0x9c,0x51,0x79,0x9b, +0x67,0x5c,0x2a,0xa9,0x3c,0x33,0x8e,0xc5,0x9c,0x31,0x10,0xf6,0xc8,0x34,0x10,0x00, +0xbb,0x39,0x7d,0xa9,0x72,0x5d,0x89,0x96,0xb2,0x7c,0x9a,0x78,0x9d,0x81,0x7a,0x6c, +0x69,0x8c,0x30,0x78,0x38,0x65,0x87,0x9d,0xba,0x59,0x88,0x92,0x71,0x76,0x83,0x7b, +0x9c,0x31,0x10,0x42,0xc8,0x34,0x00,0x00,0xae,0x89,0x9c,0x59,0x9a,0xad,0x7b,0x44, +0x6d,0xb1,0x3d,0x4b,0x33,0x8e,0x76,0x79,0xb6,0x79,0x93,0x75,0x72,0x84,0x7a,0x69, +0xa7,0x99,0xa4,0x4c,0x9c,0xbe,0x7e,0x32,0x9c,0x31,0x10,0x0a,0xc8,0x44,0x00,0x00, +0x6e,0xb4,0x48,0x36,0x33,0x91,0x68,0x64,0xaf,0x86,0x9f,0x65,0x7a,0x84,0x75,0x55, +0x9c,0x96,0xa6,0x45,0x9e,0xb4,0x86,0x35,0x71,0xb6,0x57,0x35,0x37,0xa5,0x56,0x56, +0x9c,0x31,0x10,0x86,0xc7,0x24,0x10,0x00,0x9d,0xb5,0xa6,0x34,0x81,0xb5,0x73,0x36, +0x90,0xb5,0xa8,0x21,0xa1,0xd5,0x8d,0x15,0x72,0xd1,0x61,0x25,0x3f,0xc9,0x4e,0x28, +0x8a,0xb5,0xab,0x35,0x8f,0xa5,0x78,0x55,0x9c,0x31,0x10,0x72,0xb6,0x33,0x10,0x00, +0x81,0xb6,0xc1,0x46,0xc3,0xa5,0xa1,0x55,0x6d,0x85,0x55,0x66,0x1b,0x95,0x11,0x36, +0x6e,0xb5,0xca,0x24,0xb5,0xa5,0x83,0x52,0x79,0x85,0xb7,0x85,0xbd,0x65,0x90,0x91, +0x9c,0x31,0x10,0x51,0xb6,0x22,0x00,0x00,0x7a,0x71,0x64,0x55,0x3c,0xa0,0x0f,0x24, +0x49,0xd1,0xae,0x26,0xb2,0xa5,0xab,0x69,0xa3,0x65,0xc1,0xa5,0x9b,0x32,0x6c,0xb5, +0x56,0x25,0x53,0xc5,0x42,0x45,0x3a,0x75,0x9c,0x31,0x10,0xd0,0xa6,0x11,0x00,0x00, +0x85,0xcd,0xdc,0xa2,0xe8,0xe1,0xcd,0x99,0xca,0xda,0xd0,0xa9,0x8a,0xce,0x3b,0xb1, +0x0e,0x49,0x01,0xb1,0x17,0x41,0x74,0xc0,0xc1,0x38,0xe4,0xbe,0xeb,0xbd,0xdd,0xb1, +0x9c,0x31,0x10,0x4f,0xb5,0x11,0x00,0x00,0xa4,0xc5,0x7d,0x36,0x4c,0xb5,0x34,0x48, +0x39,0x98,0x64,0x5a,0x8c,0x75,0xad,0x85,0xb8,0x64,0xbc,0x85,0xac,0x66,0x86,0x86, +0x58,0x66,0x37,0x75,0x3b,0x61,0x53,0x84,0x9c,0x31,0x10,0x5e,0xb4,0x12,0x00,0x00, +0x7c,0x35,0xa9,0xc5,0xc6,0x35,0xc2,0xc5,0xa8,0x56,0x79,0x88,0x53,0xa5,0x3c,0x55, +0x3e,0x95,0x5a,0x55,0x83,0x79,0xab,0x95,0xbd,0x61,0xb7,0x95,0x9f,0x45,0x7a,0x9a, +0x9c,0x31,0x10,0x50,0xa4,0x20,0x00,0x00,0x37,0xab,0x16,0x52,0x1b,0xa2,0x4b,0x53, +0x84,0xa2,0xb8,0xdc,0xd4,0xa1,0xcf,0x5b,0xb2,0xa3,0x84,0xdb,0x58,0x9c,0x3c,0xd3, +0x3b,0x9a,0x55,0xd3,0x76,0xa3,0x9c,0xdb,0x9c,0x31,0x10,0x6c,0x93,0x11,0x00,0x00, +0xea,0x16,0xf7,0xb5,0xcd,0x04,0x87,0xd5,0x45,0x50,0x28,0x9a,0x2c,0x69,0x49,0x5a, +0x75,0x95,0xa3,0x34,0xbc,0xa1,0xbc,0x65,0xa7,0x96,0x84,0x65,0x64,0xb5,0x51,0x65, +0x9c,0x31,0x10,0xf5,0x83,0x32,0x00,0x00,0x2b,0x1b,0x50,0xda,0x82,0x94,0x9f,0x1c, +0xb4,0x5b,0xb7,0x1a,0x9e,0xda,0x7a,0xda,0x5d,0x61,0x56,0x4e,0x59,0x51,0x68,0x9c, +0x7f,0x2b,0x98,0xdb,0xa2,0x5a,0x98,0x9b,0x9c,0x31,0x10,0x8a,0x63,0x21,0x00,0x00, +0xa3,0x71,0x88,0xf2,0x4d,0x6d,0x32,0xb1,0x2e,0x8d,0x48,0xd0,0x74,0xaa,0x9f,0xaa, +0xac,0xc5,0xa8,0x31,0x9e,0xcd,0x75,0x11,0x5b,0x31,0x50,0x8d,0x60,0xcd,0x70,0xd5, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_ONE.txt b/config/_default_cfg_src_/res/cn/SOUND_ONE.txt new file mode 100644 index 0000000..6fa01bf --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_ONE.txt @@ -0,0 +1,90 @@ +0x9c,0x31,0x10,0x05,0x84,0x37,0x31,0x00,0x7e,0xd7,0x7e,0xd7,0x7e,0xd7,0x7e,0xd7, +0x80,0xd7,0x82,0xd7,0x84,0x97,0x82,0xe7,0x80,0x97,0x7f,0x57,0x7d,0x17,0x7f,0x27, +0x84,0x57,0x84,0xc7,0x95,0x46,0xc9,0x03,0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00, +0x8a,0x9a,0x94,0x5e,0x8e,0xd1,0x6c,0x9b,0x48,0x9c,0x48,0xdb,0x6e,0xdb,0x9d,0x12, +0xc4,0xa3,0xc4,0xdc,0x88,0x51,0x38,0xec,0x20,0x8d,0x4e,0xe1,0x92,0x95,0xd0,0xda, +0x9c,0x31,0x10,0x15,0xd6,0x89,0x40,0x00,0xb4,0x9b,0x9b,0x1b,0x63,0x1b,0x3c,0xdd, +0x48,0xd9,0x76,0xe4,0xa4,0xda,0xc0,0xa1,0xb8,0x9d,0x82,0x12,0x42,0xee,0x2e,0xc9, +0x57,0x2b,0x90,0xd4,0xbd,0x20,0xc8,0xde,0x9c,0x31,0x10,0x99,0xd6,0x8a,0x40,0x00, +0xa7,0x24,0x5c,0xea,0x2a,0x87,0x38,0xe5,0x74,0x9a,0xae,0xb3,0xce,0xcb,0xc0,0x96, +0x82,0x47,0x39,0x1a,0x24,0xc2,0x53,0x3a,0x96,0xa4,0xc7,0x58,0xd0,0x99,0xa7,0x44, +0x9c,0x31,0x10,0x2d,0xd6,0x8a,0x50,0x00,0x58,0xcb,0x20,0x95,0x32,0xd7,0x76,0x98, +0xb6,0xc4,0xd4,0xba,0xc2,0xb5,0x7e,0x38,0x31,0x29,0x1e,0xc4,0x54,0xb9,0x9e,0xa5, +0xcf,0x47,0xd2,0xa8,0xa3,0x46,0x4e,0xca,0x9c,0x31,0x10,0x9d,0xd6,0x79,0x40,0x00, +0x1a,0x82,0x32,0xb2,0x7e,0xc4,0xbe,0xa9,0xd8,0x9d,0xc0,0x92,0x76,0x54,0x29,0x5d, +0x1c,0xd8,0x59,0x24,0xa6,0x8a,0xd3,0x6b,0xd2,0xcc,0x9d,0xaa,0x46,0xf5,0x14,0x83, +0x9c,0x31,0x10,0x9d,0xd6,0x79,0x40,0x00,0x36,0xf2,0x86,0xcd,0xc6,0xe1,0xda,0x9c, +0xbc,0xd2,0x6c,0x0b,0x21,0x26,0x1c,0xd1,0x61,0x2c,0xae,0x83,0xdb,0x2a,0xd0,0xcb, +0x97,0xa2,0x3d,0x35,0x10,0xc3,0x38,0xf1,0x9c,0x31,0x10,0xb4,0xd7,0x79,0x50,0x00, +0x8e,0xd5,0xce,0xe1,0xdc,0x9b,0xb6,0xdb,0x64,0x4b,0x1b,0x25,0x1c,0xc9,0x64,0xeb, +0xb6,0x83,0xdd,0x21,0xce,0xd3,0x8f,0x23,0x37,0x24,0x10,0xd5,0x3c,0xe1,0x94,0xdd, +0x9c,0x31,0x10,0xb4,0xd7,0x79,0x50,0x00,0xd3,0x1a,0xdc,0x9a,0xb2,0xdb,0x5e,0x43, +0x19,0x35,0x20,0xc3,0x6c,0xf2,0xbc,0x84,0xde,0xea,0xca,0xd2,0x87,0x32,0x31,0x13, +0x12,0x9d,0x46,0xd2,0x9c,0xe4,0xd5,0x14,0x9c,0x31,0x10,0x3c,0xd7,0x89,0x50,0x00, +0xd8,0x9a,0xa9,0x1a,0x54,0x52,0x16,0xeb,0x28,0xd5,0x76,0xda,0xc0,0x9d,0xdc,0xdb, +0xc2,0xda,0x7a,0xe4,0x2b,0x49,0x16,0xe4,0x52,0xcc,0xa6,0xa2,0xd7,0x14,0xd0,0xe2, +0x9c,0x31,0x10,0x9d,0xd6,0x79,0x40,0x00,0x9d,0x54,0x46,0x2b,0x14,0x91,0x34,0xa4, +0x89,0x0b,0xcb,0x33,0xd8,0x4b,0xb6,0xe3,0x6a,0x4c,0x21,0x9b,0x20,0xd1,0x67,0x24, +0xb4,0x43,0xd6,0xeb,0xc9,0x0b,0x8d,0xaa,0x9c,0x31,0x10,0x2b,0xd7,0x79,0x30,0x00, +0x3a,0xe5,0x18,0xcc,0x44,0xe1,0x96,0xdc,0xcf,0x1a,0xd2,0x9c,0xa8,0xd2,0x5a,0x52, +0x1e,0xed,0x2a,0xcb,0x77,0x2a,0xbc,0x8c,0xd6,0xea,0xbc,0xd5,0x7c,0xea,0x31,0x0a, +0x9c,0x31,0x10,0x2b,0xd7,0x79,0x30,0x00,0x1c,0xe5,0x54,0xd2,0xa4,0xeb,0xd3,0x03, +0xcc,0xaa,0x9b,0x0d,0x4c,0x62,0x1c,0xe2,0x38,0xdd,0x87,0x12,0xc4,0xec,0xd2,0x8b, +0xb2,0xe2,0x6c,0x9d,0x29,0x02,0x24,0xea,0x9c,0x31,0x10,0x9d,0xd6,0x79,0x40,0x00, +0x65,0x15,0xae,0x99,0xd3,0x1c,0xc4,0xd3,0x8d,0x5a,0x40,0xb5,0x1e,0x82,0x46,0xf2, +0x92,0xd4,0xc9,0x61,0xce,0x9d,0xa7,0x13,0x5c,0x12,0x25,0x26,0x30,0xc9,0x77,0x33, +0x9c,0x31,0x10,0x9d,0xd6,0x79,0x40,0x00,0xb8,0x84,0xd0,0xa9,0xb8,0xd5,0x7d,0x2a, +0x37,0x52,0x24,0xde,0x56,0xd2,0xa2,0xab,0xcd,0x0b,0xc6,0xe1,0x99,0x15,0x4e,0x52, +0x24,0xe9,0x3e,0x9e,0x87,0x11,0xc1,0x2c,0x9c,0x31,0x10,0x9d,0xd6,0x79,0x40,0x00, +0xce,0x8c,0xaf,0x21,0x6c,0x5d,0x2f,0x42,0x2c,0xe9,0x69,0x0d,0xae,0x99,0xce,0xe4, +0xbe,0xd3,0x89,0x22,0x42,0xed,0x24,0x8a,0x4c,0xe9,0x96,0xd5,0xc7,0x1a,0xc8,0xa4, +0x9c,0x31,0x10,0x9d,0xd6,0x79,0x40,0x00,0xa1,0x14,0x5c,0x09,0x28,0xed,0x36,0xcb, +0x79,0x2a,0xb9,0x15,0xcc,0x99,0xb5,0x24,0x78,0xe4,0x39,0x51,0x2a,0xed,0x5c,0xcb, +0xa2,0xaa,0xc8,0xd5,0xc0,0xd9,0x93,0x1b,0x9c,0x31,0x10,0x9d,0xd6,0x79,0x40,0x00, +0x4e,0xa4,0x2a,0x98,0x44,0xe5,0x88,0xcb,0xbf,0x2a,0xc8,0x95,0xa7,0x19,0x68,0x5b, +0x33,0x55,0x34,0xd8,0x6d,0x24,0xac,0xd3,0xc8,0xa2,0xb7,0x15,0x82,0xda,0x43,0x23, +0x9c,0x31,0x10,0x9d,0xd6,0x79,0x40,0x00,0x2c,0x95,0x54,0xd9,0x96,0xa4,0xc3,0x13, +0xc0,0xa1,0x99,0x1d,0x58,0x4a,0x30,0xea,0x42,0xd6,0x7e,0xd9,0xb7,0x1c,0xc4,0x94, +0xab,0x21,0x70,0xa4,0x3b,0x4b,0x36,0xe1,0x9c,0x31,0x10,0x9d,0xd6,0x79,0x40,0x00, +0x68,0xdd,0xa4,0xda,0xc4,0xe4,0xb6,0xd5,0x86,0xd9,0x4a,0xec,0x32,0xcc,0x52,0xe1, +0x90,0xd5,0xbc,0xda,0xbe,0x9a,0x9b,0x1c,0x5e,0x52,0x36,0xeb,0x44,0xd5,0x7c,0xe1, +0x9c,0x31,0x10,0x27,0xd5,0x79,0x40,0x00,0xb3,0x29,0xc0,0x38,0xa9,0x35,0x72,0x48, +0x3f,0x17,0x3a,0xc4,0x6a,0xbb,0xa2,0xb5,0xc0,0xb6,0xb3,0x38,0x84,0xb6,0x4d,0x48, +0x38,0xaa,0x58,0xb4,0x92,0xb8,0xba,0xb7,0x9c,0x31,0x10,0x83,0xd5,0x78,0x30,0x00, +0xb8,0xb8,0x94,0xa7,0x5c,0x36,0x3a,0xb3,0x4c,0xcd,0x80,0xa6,0xb0,0xc6,0xbc,0x27, +0xa0,0xc6,0x6c,0x28,0x41,0x3b,0x44,0xa1,0x70,0x47,0xa6,0x98,0xbc,0x46,0xab,0x2a, +0x9c,0x31,0x10,0x0a,0xc5,0x68,0x20,0x00,0x78,0xd6,0x17,0x13,0x00,0xdb,0x46,0x99, +0xb5,0x55,0xf6,0x9a,0xe3,0x42,0x92,0xb7,0x2c,0xdb,0x00,0x95,0x32,0xc4,0x9a,0xbb, +0xe8,0xb2,0xea,0xca,0xa8,0xaa,0x46,0x43,0x9c,0x31,0x10,0xbe,0xc5,0x68,0x30,0x00, +0x06,0xb6,0x22,0xbb,0x80,0xa6,0xda,0xd8,0xec,0x29,0xba,0xc3,0x5a,0x29,0x0f,0x3a, +0x18,0xb3,0x6c,0xb7,0xca,0xb9,0xec,0x35,0xc7,0x38,0x6e,0xc9,0x1d,0x13,0x14,0xc7, +0x9c,0x31,0x10,0xbf,0xc4,0x58,0x20,0x00,0x59,0x0a,0xb9,0x55,0xeb,0x17,0xd1,0x98, +0x80,0x66,0x29,0x97,0x12,0x5b,0x4c,0x15,0xab,0x95,0xe5,0x58,0xd6,0x97,0x8e,0x47, +0x37,0x69,0x15,0x46,0x43,0x24,0x9d,0x49,0x9c,0x31,0x10,0x8c,0xc5,0x67,0x20,0x00, +0xde,0x63,0xd7,0x5c,0x97,0x53,0x42,0x2b,0x19,0x51,0x3d,0x65,0x93,0x4b,0xd7,0x62, +0xd8,0x55,0x9e,0x59,0x4d,0x1b,0x1e,0x5c,0x39,0x5c,0x88,0x52,0xce,0x5b,0xd7,0x5b, +0x9c,0x31,0x10,0xa4,0xc5,0x57,0x20,0x00,0xa4,0x6a,0x56,0x24,0x24,0x95,0x36,0x62, +0x7f,0x88,0xc7,0x8d,0xd7,0x4a,0xa9,0x6b,0x5d,0x24,0x27,0x93,0x34,0x69,0x7a,0x8a, +0xc2,0x85,0xd5,0x6b,0xac,0x6c,0x62,0x43,0x9c,0x31,0x10,0x11,0xc4,0x67,0x20,0x00, +0x2b,0x92,0x34,0x59,0x76,0x5e,0xbd,0x53,0xd1,0x63,0xaa,0x53,0x65,0x62,0x31,0x8a, +0x39,0xa3,0x77,0x5e,0xb9,0x50,0xcc,0x64,0xa7,0x53,0x65,0x62,0x34,0x8a,0x3d,0x63, +0x9c,0x31,0x10,0x97,0xc4,0x68,0x20,0x00,0x78,0xbb,0xb8,0xb5,0xc8,0xc7,0xa2,0xa8, +0x62,0xc6,0x37,0x16,0x42,0xc7,0x80,0xaa,0xba,0xb6,0xc2,0xb6,0x9a,0xa7,0x5c,0x48, +0x39,0x16,0x4a,0xd6,0x86,0xaa,0xba,0xb5,0x9c,0x31,0x10,0xd0,0xc4,0x67,0x10,0x00, +0xbe,0x5b,0x92,0x52,0x59,0x24,0x3b,0x4b,0x53,0x61,0x8d,0x56,0xbc,0x19,0xb8,0x25, +0x8b,0x52,0x56,0x62,0x3d,0x8c,0x59,0x63,0x93,0x5c,0xbd,0x18,0xb4,0x1d,0x84,0x53, +0x9c,0x31,0x10,0xb7,0xb4,0x57,0x00,0x00,0x28,0xb2,0x05,0x43,0x43,0x2a,0xad,0x15, +0xf2,0x9a,0xda,0x9c,0x81,0x13,0x26,0xab,0x0b,0x4a,0x4c,0xe3,0xb5,0x65,0xf2,0x88, +0xd0,0x6c,0x74,0xd4,0x24,0xaa,0x17,0x8b,0x9c,0x31,0x10,0xb7,0xb4,0x57,0x00,0x00, +0x5e,0xa3,0xc0,0x9c,0xea,0xd9,0xbc,0x9c,0x63,0x13,0x20,0x6b,0x29,0x4b,0x78,0xe2, +0xcc,0x9d,0xda,0xda,0x9c,0xa3,0x4d,0x93,0x24,0x6b,0x44,0xdb,0x96,0x9b,0xce,0xd4, +0x9c,0x31,0x10,0x10,0xb3,0x35,0x00,0x00,0xc4,0x51,0x87,0x2b,0x48,0x63,0x2f,0x34, +0x51,0x8a,0x9b,0x52,0xce,0x85,0xc3,0x4b,0x87,0x4a,0x48,0xab,0x2f,0x2c,0x53,0x8a, +0x9b,0x2c,0xca,0x63,0xbc,0x72,0x81,0x43,0x9c,0x31,0x10,0x90,0xb2,0x23,0x00,0x00, +0x49,0xb6,0x38,0x49,0x5d,0x4c,0x9b,0x2e,0xc2,0x71,0xb2,0x4d,0x7e,0xae,0x4f,0x45, +0x45,0x51,0x66,0x91,0x98,0xa9,0xb5,0x69,0xa7,0x51,0x7e,0x41,0x59,0x51,0x53,0x70, +0x9c,0x31,0x10,0x80,0xa1,0x22,0x00,0x00,0x5c,0x55,0xab,0x5c,0xd2,0x68,0xb5,0x95, +0x74,0x53,0x43,0x5c,0x46,0x60,0x72,0x5e,0xa5,0xa5,0xb8,0x21,0x9f,0x62,0x73,0x8c, +0x56,0x61,0x5a,0x23,0x78,0x6e,0x98,0x9a,0x9c,0x31,0x10,0x55,0x92,0x22,0x00,0x00, +0xc6,0xa1,0xa6,0xd6,0x6c,0x99,0x47,0x23,0x50,0xdb,0x7a,0xe4,0xa0,0x8b,0xa7,0x2b, +0x8a,0xdd,0x69,0x59,0x5a,0xdb,0x69,0x64,0x80,0xda,0x94,0xe3,0x94,0x63,0x85,0x1c, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_OVER.txt b/config/_default_cfg_src_/res/cn/SOUND_OVER.txt new file mode 100644 index 0000000..b5e2051 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_OVER.txt @@ -0,0 +1,195 @@ +0x9c,0x31,0x10,0x8e,0x32,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x79,0xdb, +0x7e,0x1b,0x5a,0x12,0x3d,0x1a,0x4e,0x0c,0x3a,0x9d,0x6d,0xd9,0x71,0xab,0x7d,0xe2, +0x9a,0x1e,0xc9,0xcb,0xa5,0x9a,0xb4,0x9a,0x9c,0x31,0x10,0x8e,0x32,0x11,0x00,0x00, +0xd2,0x13,0xc2,0x12,0xc5,0x5c,0xb2,0x24,0x89,0x93,0x79,0xdd,0x55,0x6b,0x56,0xab, +0x75,0xd2,0x81,0xe2,0x90,0xcd,0xa2,0x0c,0x7a,0x22,0x76,0x1b,0x59,0xd2,0x61,0x94, +0x9c,0x31,0x10,0xd1,0x42,0x22,0x00,0x00,0x55,0x52,0x6e,0x1c,0x62,0x5b,0x65,0x54, +0x66,0x23,0x7d,0x1b,0x8d,0x9a,0x96,0x1c,0x95,0xd3,0x92,0x53,0x91,0x1c,0x7d,0xd3, +0x69,0xdb,0x7b,0x0d,0x6d,0x60,0x3e,0x03,0x9c,0x31,0x10,0xdb,0x43,0x33,0x00,0x00, +0x6a,0x93,0x4d,0x9a,0x51,0xec,0x51,0x19,0x66,0xdb,0x80,0x83,0x44,0xe3,0xa5,0xdd, +0x89,0x8c,0x79,0xa1,0xa0,0x54,0xb1,0xd9,0x3e,0x0c,0x8d,0x9b,0x79,0x2b,0x75,0xa3, +0x9c,0x31,0x10,0xfb,0x88,0x77,0x30,0x00,0x7d,0xdb,0x81,0xdb,0x85,0xdb,0x7d,0x9b, +0xa9,0x8a,0xa8,0x95,0x5e,0x5b,0x61,0xd3,0xce,0xac,0xb4,0xe1,0x59,0x9b,0x4d,0xeb, +0x5d,0xd4,0x69,0xda,0x69,0xe4,0x65,0xd4,0x9c,0x31,0x10,0xc0,0x76,0x77,0x30,0x00, +0x6d,0x5b,0x5e,0x32,0x63,0xb4,0x64,0xb3,0x64,0x3a,0x6b,0xbc,0x73,0xbb,0x8c,0x38, +0xac,0xbb,0xc3,0x35,0xb4,0x4a,0x5c,0x23,0x14,0x45,0x23,0xab,0x5c,0x3a,0x8b,0xbb, +0x9c,0x31,0x10,0x5f,0x65,0x77,0x30,0x00,0xd3,0x66,0xb4,0x86,0xa2,0x38,0x9d,0xaa, +0x95,0x73,0x9c,0x4a,0xa4,0xa7,0xcc,0x33,0xc4,0x99,0xac,0x67,0xa2,0x68,0x84,0xb6, +0x9c,0x28,0x74,0xe6,0x72,0x58,0x3a,0x77,0x9c,0x31,0x10,0x5f,0x75,0x88,0x40,0x00, +0x56,0x50,0x45,0x98,0x55,0xa8,0x31,0xe9,0x22,0x19,0x21,0xde,0x31,0xe6,0x55,0x5d, +0x52,0x85,0x74,0x98,0x8b,0x2c,0x96,0x20,0x95,0x51,0xba,0x61,0xb8,0xa1,0xa2,0xa1, +0x9c,0x31,0x10,0xf2,0x65,0x78,0x40,0x00,0xb0,0x1e,0xcb,0x22,0x83,0x1e,0x7c,0x19, +0xb3,0x8d,0x92,0x29,0xa2,0xe5,0xab,0x59,0x74,0x51,0x7a,0x94,0x6b,0x20,0x32,0xa0, +0x73,0x2d,0x42,0xaa,0xbb,0x4e,0xb4,0x52,0x9c,0x31,0x10,0x17,0x95,0x78,0x30,0x00, +0x81,0x48,0x8a,0x29,0x98,0xaa,0xc1,0xe2,0x7e,0x06,0x41,0xe8,0x45,0xaa,0x70,0xca, +0x82,0x15,0x7d,0xc2,0x65,0xb6,0x59,0xbd,0x61,0x29,0x8a,0xb7,0x9d,0x54,0xb1,0x95, +0x9c,0x31,0x10,0x2e,0xc6,0x77,0x20,0x00,0x85,0x1d,0x7b,0x26,0x6f,0x19,0x6b,0x10, +0x7e,0xdc,0xa0,0xdc,0xb1,0x1b,0x98,0xe2,0x64,0xdb,0x3c,0x93,0x44,0xec,0x72,0xca, +0xa6,0xe3,0xb4,0xd2,0xa2,0xe4,0x8e,0x4a,0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00, +0x94,0xe4,0x96,0x94,0x71,0x5b,0x32,0xa1,0x26,0x98,0x62,0xd5,0xaa,0xe5,0xc2,0xd4, +0xa8,0xe2,0x84,0x92,0x81,0x23,0x98,0x9a,0x8d,0x1d,0x48,0x1c,0x15,0x51,0x3e,0xe8, +0x9c,0x31,0x10,0x1b,0xc6,0x89,0x30,0x00,0x9d,0x0c,0xd0,0xab,0xb8,0xd4,0x85,0x23, +0x70,0x53,0x97,0x1a,0xae,0x54,0x79,0x9c,0x16,0x5b,0x08,0xa1,0x68,0x8c,0xce,0xeb, +0xd8,0xcc,0x96,0xeb,0x64,0xd3,0x7a,0xe2,0x9c,0x31,0x10,0x90,0xd7,0x99,0x40,0x00, +0x9c,0xdc,0x96,0xe3,0x62,0xd3,0x35,0x63,0x4e,0xcc,0x94,0xea,0xba,0xcb,0x9e,0xe3, +0x71,0x13,0x6a,0xa3,0x91,0x1b,0xae,0xdc,0x8b,0x1a,0x46,0x9b,0x2b,0x9a,0x66,0xce, +0x9c,0x31,0x10,0x74,0xd8,0x9a,0x40,0x00,0xad,0xd6,0xb5,0x97,0x81,0xd6,0x5d,0x97, +0x79,0x47,0xae,0x26,0xad,0x47,0x72,0x26,0x31,0x48,0x36,0xa4,0x81,0xbb,0xb9,0xc6, +0xa1,0x97,0x65,0xd6,0x65,0x97,0x95,0xc7,0x9c,0x31,0x10,0x74,0xd8,0x9a,0x40,0x00, +0xb6,0x26,0x99,0xb8,0x61,0xb7,0x39,0x37,0x4a,0x94,0x89,0xbb,0xae,0x57,0x8d,0x97, +0x65,0xd6,0x75,0xa7,0xa1,0xc7,0xa9,0xb6,0x89,0xb8,0x65,0xc6,0x49,0x37,0x4e,0xa5, +0x9c,0x31,0x10,0x39,0xc7,0x9a,0x40,0x00,0x8a,0xab,0xcc,0xd6,0x98,0x96,0x56,0xc7, +0x7a,0xb7,0xc2,0xb7,0xbe,0xc7,0x96,0xa7,0x6c,0xb7,0x33,0x37,0x0b,0x69,0x6c,0x84, +0xcc,0xb7,0xa8,0xd8,0x54,0x97,0x70,0xb7,0x9c,0x31,0x10,0xde,0xc8,0xa9,0x30,0x00, +0xbd,0xc3,0xb9,0x2a,0x95,0xcd,0x7d,0xb2,0x52,0xb2,0x04,0xb2,0x45,0xdc,0xc1,0x2c, +0xb5,0xb2,0x55,0xc3,0x61,0xbc,0xbd,0xb2,0xbd,0x3b,0x8e,0x33,0x89,0xc3,0x6e,0x34, +0x9c,0x31,0x10,0xe4,0xc9,0x98,0x30,0x00,0x12,0x5c,0x21,0x01,0xb6,0xea,0xcc,0xe6, +0x5e,0xd1,0x52,0xdb,0xba,0xdc,0xc8,0xdb,0x87,0x23,0x8c,0xda,0x82,0xd3,0x22,0xdb, +0x05,0x6b,0xa2,0xce,0xd8,0xd8,0x6a,0xdc,0x9c,0x31,0x10,0x5c,0xd8,0x98,0x30,0x00, +0x64,0xdb,0x99,0x1a,0xa6,0xdb,0x85,0x5b,0x82,0xd4,0x82,0xda,0x59,0x1b,0x3f,0x6e, +0x88,0xd8,0xaa,0xd3,0x7a,0xdc,0x64,0xda,0x95,0x1b,0xa6,0xdc,0x87,0x5a,0x82,0xd4, +0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00,0x86,0xdb,0x3b,0x53,0x05,0x6d,0x88,0xf0, +0xd4,0xdd,0x7a,0xda,0x48,0xdb,0xa5,0x12,0xcc,0x9b,0x97,0x5b,0x84,0xd3,0x7d,0x1b, +0x39,0x12,0x0f,0xb5,0x8c,0xe1,0xcc,0xe3,0x9c,0x31,0x10,0x53,0xc8,0x87,0x20,0x00, +0x7a,0xe9,0x52,0xed,0xa5,0x29,0xc8,0x8d,0x9d,0x49,0x7c,0xe9,0x6b,0x09,0x2e,0xcd, +0x29,0xd5,0x9d,0x26,0xbf,0x4c,0x75,0x0a,0x61,0x0d,0xa9,0x2d,0xc2,0xc8,0xa0,0x8e, +0x9c,0x31,0x10,0xce,0xc9,0x87,0x20,0x00,0x6c,0xcd,0x4e,0xf1,0x26,0x69,0x5a,0xe6, +0xae,0xcc,0xa2,0xea,0x6c,0xcd,0x78,0xed,0xb4,0xcc,0xc2,0xf1,0x86,0xcd,0x4e,0xf1, +0x2c,0xed,0x45,0x55,0x97,0x0a,0xab,0x10,0x9c,0x31,0x10,0xfa,0xc7,0x87,0x10,0x00, +0x81,0x19,0x73,0x5d,0xa1,0x19,0xc7,0x25,0x9a,0x9d,0x54,0xe5,0x2b,0x5d,0x3d,0x72, +0x8e,0xa8,0xae,0xa6,0x88,0xa5,0x73,0x25,0x9f,0x65,0xc7,0x65,0x9b,0x21,0x4b,0x25, +0x9c,0x31,0x10,0xdc,0xc8,0x86,0x20,0x00,0x23,0x30,0x47,0x96,0x99,0x31,0xaf,0x31, +0x89,0x11,0x7d,0x11,0xaa,0xed,0xbe,0xce,0x80,0xcc,0x31,0x0d,0x20,0x89,0x66,0xea, +0xae,0xcd,0xab,0x09,0x88,0xe9,0x90,0xed,0x9c,0x31,0x10,0x24,0xc7,0x66,0x20,0x00, +0xb0,0xc4,0x9a,0xd2,0x4d,0x14,0x1a,0x94,0x45,0x40,0x9f,0x14,0xbb,0x13,0x9f,0x12, +0x8e,0xd3,0xa2,0xdc,0x94,0xd3,0x52,0xd3,0x22,0x55,0x43,0x03,0x94,0xd1,0xbd,0x13, +0x9c,0x31,0x10,0xf4,0xc6,0x65,0x10,0x00,0xad,0x64,0x98,0x65,0x95,0x89,0x7f,0x69, +0x4c,0xd2,0x2c,0x28,0x54,0x4e,0x9a,0x51,0xba,0x90,0xae,0x96,0x9c,0x89,0x8d,0x8d, +0x6a,0x8d,0x43,0x69,0x3d,0x8d,0x68,0x88,0x9c,0x31,0x10,0x48,0xb7,0x77,0x20,0x00, +0xb6,0xd3,0xe8,0xdc,0xe0,0xdb,0xb7,0x1b,0x7a,0xd3,0x3d,0x0a,0x1a,0xcc,0x26,0xd2, +0x64,0x53,0xb8,0x1c,0xe0,0x23,0xce,0x21,0x9c,0x24,0x68,0xad,0x44,0x63,0x36,0x19, +0x9c,0x31,0x10,0x12,0xa9,0xa8,0x30,0x00,0x19,0x3c,0x69,0x4a,0xb9,0x44,0xed,0xc3, +0xf5,0xb2,0xba,0x44,0x66,0x3a,0x3a,0xd2,0x36,0xce,0x56,0xb1,0x6e,0x2c,0x89,0xa0, +0xa1,0x24,0xa9,0x3c,0x94,0xd3,0x6d,0x5b,0x9c,0x31,0x10,0x6d,0x99,0xa9,0x50,0x00, +0x33,0xda,0x44,0xcb,0x64,0xac,0x84,0xa1,0x9d,0x44,0xa5,0xcb,0xb5,0xda,0xa6,0x43, +0x7d,0xbc,0x4c,0xb3,0x5c,0x30,0x6b,0x34,0x6b,0x31,0x53,0x4c,0x53,0x4d,0x73,0x53, +0x9c,0x31,0x10,0x60,0x89,0x99,0x50,0x00,0x8b,0x54,0x83,0x53,0x5c,0x2a,0x54,0xcb, +0x5d,0x3a,0x84,0xd4,0x7c,0xcb,0x6c,0x42,0x9b,0xa6,0xaa,0x8b,0xa1,0x98,0x78,0xa1, +0x98,0x96,0xe9,0x2a,0xb2,0x43,0x72,0xd4,0x9c,0x31,0x10,0xa1,0x89,0x99,0x60,0x00, +0xa3,0x45,0xcb,0x4d,0x8a,0x71,0x82,0x69,0xa2,0x31,0xc1,0x09,0x89,0x6d,0x59,0x95, +0x58,0xa5,0x69,0xa9,0x72,0xd9,0x8c,0xad,0xa5,0x41,0xad,0x6c,0x9d,0x64,0x63,0x4c, +0x9c,0x31,0x10,0x7e,0x78,0x9a,0x60,0x00,0x52,0xa9,0x21,0x29,0x03,0x22,0x22,0xd6, +0x90,0xda,0x93,0x61,0x93,0x1d,0xa4,0x95,0xb6,0xdd,0x96,0xb1,0x86,0xc5,0x65,0xa9, +0x70,0xa1,0x50,0x8d,0x50,0xa9,0x62,0xd9,0x9c,0x31,0x10,0x56,0x78,0xaa,0x60,0x00, +0x4a,0x2a,0x46,0x66,0x86,0x0e,0x2e,0x22,0x31,0xdd,0x51,0xd5,0x4d,0x5c,0x29,0x18, +0x29,0x31,0x25,0xd5,0x46,0x59,0x2e,0x29,0x55,0xcd,0x35,0x5d,0x54,0xe1,0x71,0x21, +0x9c,0x31,0x10,0xa3,0x69,0xa9,0x50,0x00,0xa6,0x39,0x47,0x86,0x47,0x7b,0x88,0x79, +0x67,0x3c,0xd6,0x5b,0xa5,0x5a,0x84,0x5c,0x82,0x72,0x74,0x9c,0x86,0xa3,0x97,0x71, +0x77,0x63,0x88,0x64,0x99,0x8c,0x48,0xa3,0x9c,0x31,0x10,0xe3,0x79,0x9a,0x60,0x00, +0x67,0x66,0x47,0x0e,0x64,0xe5,0x62,0x9d,0x62,0xcc,0x32,0xd8,0x60,0xb4,0x72,0xd5, +0x70,0xd9,0x72,0x1d,0x92,0xa1,0xb3,0x59,0x93,0x29,0x87,0x19,0x99,0x59,0xab,0x21, +0x9c,0x31,0x10,0x8b,0x69,0x99,0x50,0x00,0xab,0x93,0x9a,0x8b,0x3a,0x48,0x1b,0x39, +0x7b,0x04,0xaa,0x56,0x69,0x57,0x48,0x94,0xd9,0x8b,0x67,0x54,0x75,0x32,0x67,0x7b, +0x98,0x8b,0x37,0x96,0x37,0x8b,0x88,0x92,0x9c,0x31,0x10,0x8b,0x69,0x99,0x50,0x00, +0x69,0x45,0x6a,0x88,0x6a,0x49,0x78,0x74,0x44,0x8c,0x83,0xb1,0x83,0xc6,0x91,0x9d, +0x72,0x77,0x65,0x45,0x95,0x3b,0xc5,0x56,0xc7,0x85,0xa8,0xc3,0x87,0xd9,0x98,0x8b, +0x9c,0x31,0x10,0xb6,0x79,0x89,0x50,0x00,0x98,0x66,0x88,0x49,0x29,0x96,0x8b,0xd7, +0x8b,0xa0,0xba,0x9d,0x9c,0x24,0x8c,0x48,0x7b,0x2a,0x6a,0xa7,0x5c,0xbc,0x7a,0xd2, +0x68,0x66,0x78,0xd4,0xa8,0x5b,0x98,0xc3,0x9c,0x31,0x10,0x8b,0x69,0x99,0x50,0x00, +0x18,0x8c,0x58,0x85,0x98,0x96,0x09,0xb7,0x08,0x97,0x68,0x47,0x9a,0x6b,0xca,0x55, +0x9c,0x95,0xbc,0x6a,0xab,0x73,0x8a,0x9a,0xaa,0x85,0x59,0xba,0x58,0x89,0x67,0x84, +0x9c,0x31,0x10,0x21,0x79,0x98,0x50,0x00,0x86,0xb9,0x86,0xe5,0x55,0xd5,0xb3,0x43, +0x72,0x6a,0x83,0x9d,0x43,0xa6,0x54,0xc8,0x67,0x74,0x48,0x48,0x38,0x12,0x67,0x55, +0x87,0x39,0x88,0x85,0x77,0x8e,0x95,0x12,0x9c,0x31,0x10,0xae,0x79,0x99,0x50,0x00, +0x85,0x18,0x86,0x49,0x58,0x67,0x38,0x64,0x77,0x88,0x75,0x68,0x68,0x74,0x5c,0x5d, +0x7d,0x60,0x8e,0x98,0x8d,0x49,0x49,0xa5,0x27,0x66,0x39,0x39,0x3a,0x48,0x8b,0x52, +0x9c,0x31,0x10,0x3c,0x7a,0xa9,0x50,0x00,0x68,0x45,0x96,0xc3,0xa7,0x24,0xa7,0x2b, +0x77,0x31,0x85,0xb3,0x86,0x93,0x7a,0xc4,0x9d,0x34,0xab,0xb2,0xa7,0xca,0x78,0x4b, +0x89,0x4a,0x98,0x3b,0x06,0x3d,0x36,0x3a,0x9c,0x31,0x10,0x2f,0x7a,0x98,0x40,0x00, +0x47,0xbb,0x38,0xac,0x28,0x92,0x47,0x3c,0xa9,0x52,0x69,0xb3,0x96,0xc1,0xb6,0xbe, +0xd7,0xb4,0x88,0x29,0xb9,0x3b,0xe9,0x42,0x4a,0xcc,0x0c,0x3a,0x2a,0x3b,0x64,0x2b, +0x9c,0x31,0x10,0x3b,0xba,0x87,0x30,0x00,0x78,0xb6,0x75,0x89,0x7a,0xac,0x7e,0xca, +0x86,0x4c,0x89,0xad,0x85,0xaa,0x75,0xcc,0x65,0xae,0x5e,0x31,0x76,0x0d,0xa5,0x69, +0xc1,0x89,0xa2,0x2a,0x4a,0x8d,0x01,0xed,0x9c,0x31,0x10,0xd1,0xc9,0x66,0x20,0x00, +0x4c,0x51,0x96,0xd1,0xd7,0x6d,0xcc,0xe5,0x7e,0xb1,0x35,0x11,0x1a,0x89,0x5f,0x0c, +0xb9,0x2a,0xd8,0xd1,0xbc,0xcd,0x87,0x11,0x5c,0xe9,0x26,0x84,0x35,0x6e,0x88,0xe9, +0x9c,0x31,0x10,0xe8,0xc8,0x55,0x20,0x00,0xcb,0x25,0xc9,0xb5,0x9f,0x74,0x7b,0x65, +0x46,0x99,0x19,0x88,0x57,0x06,0xb2,0xc5,0xd0,0x75,0xb1,0x55,0x91,0x95,0x78,0x75, +0x30,0x44,0x1d,0xe6,0x71,0x04,0xc7,0x85,0x9c,0x31,0x10,0xbd,0xc8,0x46,0x10,0x00, +0xcb,0x44,0xa4,0x42,0x8f,0x4b,0x69,0x04,0x1a,0x42,0x2b,0xca,0x8a,0x84,0xd2,0xaa, +0xc1,0x8b,0x9a,0x24,0x8d,0x4a,0x5f,0x22,0x10,0x35,0x35,0xab,0x9c,0xd2,0xd8,0x8c, +0x9c,0x31,0x10,0xa5,0xc8,0x56,0x10,0x00,0xb9,0xaa,0x96,0x2b,0x8f,0x4c,0x59,0x2a, +0x08,0x33,0x39,0x8d,0xa4,0xe9,0xda,0x6b,0xb3,0xac,0x96,0x2a,0x93,0x6b,0x54,0xeb, +0x02,0x52,0x39,0xad,0xa8,0x8b,0xde,0xeb,0x9c,0x31,0x10,0xbd,0xc8,0x46,0x10,0x00, +0xb3,0x4b,0x94,0x4b,0x95,0x8a,0x5c,0x83,0x02,0xb5,0x2b,0x63,0xa2,0x89,0xe1,0x2c, +0xb8,0xeb,0x94,0xaa,0x97,0x4b,0x6e,0x84,0x0a,0xe3,0x17,0x69,0x8e,0x6c,0xe1,0x6c, +0x9c,0x31,0x10,0xd0,0xd8,0x36,0x10,0x00,0xa2,0x42,0x8b,0x93,0x8a,0x74,0x82,0x73, +0x4f,0x92,0x3f,0x8d,0x76,0x53,0xaa,0xb1,0xab,0x3c,0x8e,0xbc,0x8a,0x4a,0x8a,0xa3, +0x63,0x7c,0x3a,0x52,0x5e,0xa4,0x9c,0x5c,0x9c,0x31,0x10,0x14,0xd8,0x45,0x10,0x00, +0xb3,0x84,0x97,0x75,0x89,0x66,0x8d,0x85,0x7a,0x64,0x45,0x70,0x44,0x95,0x83,0x46, +0xb0,0xa5,0xa6,0x34,0x89,0xb5,0x8a,0x46,0x8b,0x95,0x63,0x75,0x38,0x59,0x5e,0xa6, +0x9c,0x31,0x10,0x7c,0xd7,0x45,0x10,0x00,0x9d,0x15,0xb3,0xd4,0x95,0x25,0x86,0xa5, +0x8e,0x55,0x83,0x95,0x4e,0x8a,0x3a,0x72,0x76,0x64,0xab,0x84,0xae,0x66,0x89,0x95, +0x87,0x54,0x8f,0x85,0x79,0x65,0x43,0x70,0x9c,0x31,0x10,0x11,0xc7,0x35,0x10,0x00, +0x07,0xb5,0x8e,0x32,0xe4,0xb5,0xcf,0x34,0x89,0xb5,0x92,0x45,0x9e,0x95,0x69,0x65, +0x00,0x61,0x0f,0xa0,0x98,0x22,0xe6,0xb5,0xc9,0x39,0x86,0xb5,0x93,0x45,0x9f,0x85, +0x9c,0x31,0x10,0x1d,0xd6,0x35,0x00,0x00,0x75,0x75,0x40,0x50,0x45,0xd5,0x8b,0x02, +0xb2,0xd5,0xa6,0x44,0x81,0xa5,0x87,0x75,0x91,0x55,0x7b,0x99,0x47,0x75,0x3f,0x76, +0x81,0x75,0xaf,0x54,0xa9,0xc5,0x82,0x05,0x9c,0x31,0x10,0x47,0xd7,0x44,0x00,0x00, +0x82,0xb6,0x93,0x35,0x86,0xa4,0x56,0x85,0x37,0x24,0x6b,0xd5,0xa8,0x06,0xb0,0xe5, +0x8c,0x04,0x7a,0xd5,0x92,0x35,0x91,0x86,0x6c,0x75,0x3b,0x60,0x4b,0xb4,0x96,0x46, +0x9c,0x31,0x10,0x17,0xd7,0x24,0x00,0x00,0xb2,0x86,0x9f,0x89,0x78,0x50,0x86,0xb5, +0x99,0x36,0x86,0xa5,0x55,0x74,0x36,0x28,0x6a,0xe6,0xaa,0x0a,0xaf,0xd0,0x8c,0x20, +0x74,0xa6,0x93,0x76,0x99,0x59,0x78,0x99,0x9c,0x31,0x10,0x80,0xd7,0x35,0x00,0x00, +0x45,0x79,0x3b,0x45,0x81,0xb4,0xb0,0x15,0xa8,0xe6,0x7f,0x05,0x76,0xc5,0x9b,0x55, +0x97,0x75,0x71,0x89,0x40,0x85,0x41,0x51,0x89,0xb4,0xb0,0x20,0xa3,0xd5,0x7c,0x25, +0x9c,0x31,0x10,0x0f,0xd7,0x34,0x00,0x00,0x77,0xb5,0x9d,0x65,0x99,0x65,0x72,0x85, +0x45,0x99,0x3f,0x34,0x81,0xd4,0xae,0x16,0xa3,0xd6,0x80,0x35,0x71,0x84,0x99,0x94, +0x9f,0x35,0x7a,0xa5,0x50,0x70,0x3c,0x29,0x9c,0x31,0x10,0xa5,0xc7,0x35,0x00,0x00, +0x61,0xe6,0xd3,0x19,0xcd,0xb5,0x95,0x65,0x5d,0x55,0x96,0xa5,0xcc,0x45,0x96,0x85, +0x45,0x75,0x02,0x75,0x25,0x76,0xae,0x82,0xd6,0x31,0xaf,0xc4,0x6d,0x35,0x6a,0x85, +0x9c,0x31,0x10,0xa5,0xc7,0x35,0x00,0x00,0xbe,0x85,0xc0,0x45,0x73,0x95,0x29,0x71, +0x02,0x3a,0x5b,0xd6,0xcb,0x24,0xc3,0x94,0x95,0x85,0x5e,0x56,0x86,0x95,0xcb,0x75, +0xae,0x55,0x60,0x85,0x24,0x95,0x0c,0x19,0x9c,0x31,0x10,0xa5,0xc7,0x35,0x00,0x00, +0x70,0xe5,0xcd,0x1a,0xba,0xb5,0x8e,0x65,0x5d,0x65,0x8b,0x95,0xc4,0x65,0xb0,0x75, +0x67,0x65,0x2c,0xa5,0x10,0x09,0x63,0xe6,0xc9,0x25,0xb8,0x95,0x91,0x84,0x5e,0x35, +0x9c,0x31,0x10,0x9e,0xc7,0x34,0x10,0x00,0x7f,0xb6,0xb9,0x36,0xbc,0xb5,0x80,0x34, +0x3f,0xb5,0x1a,0x31,0x37,0xa4,0xb2,0x85,0xc0,0x36,0x9f,0xd6,0x6e,0x15,0x66,0xc4, +0xa5,0x45,0xbb,0x95,0xac,0x75,0x61,0x45,0x9c,0x31,0x10,0xf6,0xc8,0x34,0x10,0x00, +0x31,0xaa,0x1a,0x30,0x6a,0xc3,0xcc,0x4e,0xac,0x8e,0x89,0x93,0x5c,0x48,0x7e,0xb1, +0xb2,0x43,0xb3,0xad,0x9c,0x64,0x53,0x72,0x31,0xab,0x22,0x3d,0x82,0xc1,0xc9,0x38, +0x9c,0x31,0x10,0x79,0xc8,0x35,0x10,0x00,0xa2,0x9a,0x82,0x7c,0x5c,0x64,0x8a,0xab, +0xac,0x42,0xa9,0xab,0x9e,0x63,0x5b,0x73,0x36,0xa3,0x22,0x3d,0x80,0xbb,0xc7,0x41, +0xa0,0x9a,0x7f,0x7b,0x5c,0x64,0x87,0xac,0x9c,0x31,0x10,0x79,0xc8,0x35,0x10,0x00, +0xa9,0x4b,0xa1,0x9a,0xa0,0x6b,0x6d,0x6c,0x48,0xad,0x26,0x32,0x65,0xb8,0xbf,0x53, +0xa7,0x85,0x89,0x8d,0x60,0x53,0x76,0xa2,0xa4,0x62,0x9a,0x7c,0xa0,0x95,0x7f,0x4c, +0x9c,0x31,0x10,0x61,0xc8,0x25,0x10,0x00,0x62,0xaa,0x4b,0x59,0x34,0x79,0x96,0x9c, +0xaf,0x3e,0x94,0xbc,0x7d,0x52,0x5f,0x79,0x91,0x92,0x9d,0x54,0x98,0xa4,0x98,0x6b, +0x68,0x6b,0x5a,0xab,0x43,0x3a,0x6d,0xba,0x9c,0x31,0x10,0x11,0xc7,0x35,0x10,0x00, +0xaf,0x35,0x93,0x75,0x86,0xa5,0x6d,0x35,0x7e,0xb5,0xad,0x55,0xa5,0x79,0x7e,0x75, +0x45,0x99,0x21,0x34,0x74,0xc4,0xbd,0x25,0xa7,0xa6,0x80,0x75,0x58,0x55,0x7d,0xa5, +0x9c,0x31,0x10,0x54,0xb6,0x24,0x00,0x00,0xc0,0x42,0x9f,0x4c,0x7b,0x0c,0x52,0x8c, +0x77,0x6a,0xa2,0x6a,0x97,0x02,0x91,0x0c,0x6c,0xac,0x6f,0x2c,0x8a,0xea,0x76,0xd1, +0x5d,0x2a,0x3a,0xab,0x4b,0x0d,0xb1,0x0c,0x9c,0x31,0x10,0x65,0xb7,0x34,0x10,0x00, +0xbe,0xab,0xa5,0x2a,0x94,0xca,0x7a,0xca,0x6b,0x4b,0x18,0x35,0x3f,0xae,0xc6,0x93, +0xba,0xe9,0x9d,0x49,0x56,0x6b,0x69,0x6d,0xaa,0x8c,0x92,0xeb,0x87,0x2a,0x5e,0x8b, +0x9c,0x31,0x10,0x1b,0x96,0x22,0x00,0x00,0x29,0xba,0xcc,0x66,0xab,0x16,0xa1,0x30, +0x2c,0x84,0x41,0x75,0x8c,0x96,0x7f,0x36,0x9f,0x05,0x6c,0xa8,0x85,0x45,0x94,0x92, +0x7f,0x45,0x82,0xd5,0x5c,0xe1,0x83,0x25,0x9c,0x31,0x10,0x4a,0xa6,0x25,0x10,0x00, +0x84,0xab,0x83,0x2b,0x7e,0xcb,0x75,0x0b,0x84,0xeb,0x82,0xd3,0x86,0xeb,0x7e,0xcb, +0x79,0x0b,0x81,0x0b,0x86,0xb4,0xb3,0x64,0xae,0x4a,0x2f,0x21,0x1d,0x2a,0x38,0x4c, +0x9c,0x31,0x10,0xec,0xa7,0x24,0x00,0x00,0xdb,0x6e,0xe4,0x74,0x8f,0x6a,0x4e,0x69, +0x25,0x6a,0x40,0x6c,0x7f,0x4c,0xd2,0xb3,0x9b,0x0a,0x7d,0x0a,0x62,0xcb,0xa7,0x2c, +0xaa,0x8b,0x87,0x4b,0x62,0x83,0x6b,0x2b,0x9c,0x31,0x10,0x16,0x86,0x12,0x00,0x00, +0xd2,0x75,0xb5,0x65,0x92,0xa5,0x31,0x18,0x82,0xe5,0x86,0xe5,0x97,0x16,0x4c,0xc5, +0x73,0x21,0x88,0xb5,0xab,0x41,0x82,0xa1,0x6b,0x55,0x66,0xa5,0x7f,0x45,0x8e,0xa9, +0x9c,0x31,0x10,0xda,0x64,0x12,0x00,0x00,0x71,0xcd,0x6c,0x34,0x69,0xb3,0xb4,0x42, +0x89,0xb3,0x54,0x6a,0x25,0x4c,0x5c,0x4c,0xb9,0x4c,0xd0,0x43,0x85,0x42,0x50,0xb2, +0x55,0x73,0x88,0x93,0xb3,0x33,0x8e,0x6b,0x9c,0x31,0x10,0xcd,0x53,0x11,0x00,0x00, +0x7f,0x14,0x30,0x92,0x57,0x44,0x7c,0x5a,0xa6,0xad,0xb1,0x14,0x72,0x21,0x5d,0x93, +0x65,0x52,0x72,0x52,0x81,0xab,0x66,0x04,0x6d,0x19,0x56,0x5b,0x35,0x4c,0x4f,0x1c, +0x9c,0x31,0x10,0xe5,0x53,0x21,0x00,0x00,0x76,0x25,0x9e,0x25,0x7d,0x9d,0x2d,0x5d, +0x35,0x9d,0x41,0xdc,0x9b,0x21,0x85,0x22,0x56,0x69,0x4c,0xe5,0x4d,0xa1,0x82,0x14, +0x86,0x21,0x79,0xad,0x51,0x69,0x41,0x5c,0x9c,0x31,0x10,0xc0,0x43,0x21,0x00,0x00, +0x42,0x49,0xb9,0xd0,0x8e,0x05,0x71,0x91,0x49,0xe9,0x6f,0x21,0x4d,0x5e,0x3d,0xdc, +0xa0,0xd5,0xcd,0x9e,0x7e,0x55,0x1d,0x6d,0x35,0xe1,0x89,0x58,0x9d,0xa9,0x9e,0x5d, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_PAIRING.txt b/config/_default_cfg_src_/res/cn/SOUND_PAIRING.txt new file mode 100644 index 0000000..7d4868b --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_PAIRING.txt @@ -0,0 +1,180 @@ +0x9c,0x31,0x10,0xa9,0x53,0x21,0x01,0x00,0x7d,0xb5,0x7d,0xb5,0x75,0xb5,0x72,0x25, +0x38,0xb8,0x31,0xd9,0x49,0xa1,0x41,0xc1,0x39,0xa5,0x3a,0x45,0x41,0xc5,0x4a,0x31, +0x41,0x19,0x42,0x55,0x39,0x95,0x51,0xb5,0x9c,0x31,0x10,0x6a,0xa7,0x86,0x20,0x00, +0x79,0xbb,0x79,0xbb,0x7d,0xbb,0x7d,0xbb,0x7d,0xbb,0x7d,0xbb,0x7d,0xbb,0x8a,0x3b, +0xa1,0x44,0xe6,0x29,0xf0,0x1d,0xe0,0x1b,0xb9,0x29,0xc9,0xab,0xbe,0xb4,0xae,0x32, +0x9c,0x31,0x10,0xfa,0xb8,0x65,0x10,0x00,0x97,0x6d,0x7d,0x51,0x59,0x4c,0x4f,0x26, +0x45,0x26,0x3b,0x28,0x39,0x25,0x41,0x26,0x47,0x00,0x4b,0x09,0x55,0x0e,0x5c,0xcd, +0x5f,0x04,0x60,0xa5,0x6f,0x14,0x7b,0x16,0x9c,0x31,0x10,0x56,0x98,0x87,0x30,0x00, +0x93,0xc4,0xa4,0x2b,0xd5,0x63,0xdb,0x54,0xed,0x29,0xcc,0x8c,0xc6,0x95,0xb3,0xa9, +0x7b,0x31,0x7b,0xc3,0x72,0xa4,0x4a,0xb6,0x6a,0xb1,0x5a,0xc1,0x73,0xce,0x74,0x2b, +0x9c,0x31,0x10,0x65,0x98,0x97,0x40,0x00,0x89,0x3b,0xa4,0xcb,0x7c,0x39,0xa4,0x52, +0xa3,0xb1,0xa4,0x1e,0x9b,0xa4,0xc4,0x34,0x8b,0xc9,0xd4,0x55,0x9b,0xc4,0xbb,0x28, +0x9b,0xba,0x94,0x42,0xb3,0x34,0x9b,0x26,0x9c,0x31,0x10,0x1b,0x87,0x87,0x30,0x00, +0xaa,0x3c,0xed,0x62,0x8d,0x2a,0xb1,0x2b,0x78,0xc2,0x95,0xcd,0x85,0xa2,0x9d,0xa1, +0x6d,0x9b,0x78,0x44,0x89,0x5b,0xa6,0x53,0x95,0x2a,0xa1,0xa3,0x9c,0xbd,0x62,0x2b, +0x9c,0x31,0x10,0xa3,0x96,0x87,0x30,0x00,0x84,0x32,0x9a,0x55,0x8c,0xd3,0x8d,0xaa, +0x81,0x42,0x72,0x5c,0x6e,0xb4,0x78,0xa2,0xa1,0xcb,0x91,0x6b,0x80,0xab,0x62,0x9c, +0x69,0xbc,0x72,0xcb,0x9e,0x4a,0xc1,0xc1,0x9c,0x31,0x10,0x74,0xb7,0x87,0x30,0x00, +0x79,0xa3,0x6a,0x34,0x69,0x3a,0x71,0xb4,0x95,0xdb,0xaa,0x3a,0x89,0xab,0x56,0x3c, +0x41,0x3b,0x66,0x3c,0xa0,0xba,0xce,0x32,0xad,0x4b,0x4b,0x32,0x21,0x95,0x41,0x43, +0x9c,0x31,0x10,0xe7,0xc8,0x87,0x30,0x00,0x99,0x12,0xbc,0xed,0x9b,0x0c,0x63,0x2c, +0x49,0x0a,0x4a,0xb1,0x96,0xd5,0xc6,0xea,0xab,0x49,0x66,0xd1,0x3e,0xf4,0x3a,0x6e, +0x92,0xf0,0xc6,0xcd,0xb3,0x0a,0x76,0x6d,0x9c,0x31,0x10,0x58,0xc9,0x89,0x40,0x00, +0x43,0x13,0x2e,0xa2,0x7f,0x22,0xc0,0x95,0xbf,0x13,0x92,0xe2,0x4f,0x22,0x26,0x42, +0x63,0x2d,0xba,0xe3,0xb8,0xc3,0xa6,0xeb,0x72,0xdb,0x30,0xdb,0x39,0x09,0xa2,0xd4, +0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00,0xc0,0xeb,0xa8,0xd3,0x8c,0xdb,0x55,0x63, +0x20,0x65,0x6e,0xe8,0xc4,0x84,0xb6,0xe4,0x98,0xe3,0x70,0x93,0x30,0x9c,0x35,0x41, +0xa4,0xea,0xc6,0xdc,0xa8,0xe5,0x88,0xd3,0x9c,0x31,0x10,0xdd,0xc8,0x99,0x40,0x00, +0x5b,0x5b,0x22,0x63,0x5e,0xea,0xbe,0x8c,0xbc,0xe3,0x98,0xd3,0x7e,0xe3,0x47,0x23, +0x25,0x5b,0x82,0xcd,0xca,0xea,0xb0,0xcb,0x8c,0xe4,0x76,0xda,0x3a,0x54,0x2f,0x4b, +0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00,0x96,0xe9,0xcc,0xd4,0xa8,0x9c,0x88,0xe2, +0x77,0x13,0x32,0x53,0x37,0x1d,0xa0,0xe1,0xce,0xd3,0xa2,0xe4,0x84,0x9b,0x77,0x1a, +0x32,0x49,0x36,0xee,0xa0,0xd2,0xcc,0xd9,0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00, +0xa2,0xe4,0x84,0x9c,0x7e,0xda,0x3c,0x52,0x2b,0x26,0x8c,0xd8,0xcc,0xd3,0xac,0xdc, +0x86,0xd3,0x87,0x1b,0x50,0x9c,0x1f,0x09,0x6e,0xeb,0xc6,0xd4,0xbf,0x1b,0x8c,0xdb, +0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00,0x89,0x14,0x6d,0x1a,0x1e,0xec,0x42,0x8a, +0xac,0xe2,0xce,0x9b,0xa0,0xdb,0x86,0x9b,0x84,0xdb,0x3e,0x13,0x21,0x5d,0x76,0xe0, +0xca,0xd4,0xbf,0x23,0x8c,0xd3,0x89,0x23,0x9c,0x31,0x10,0x12,0xc7,0x9a,0x30,0x00, +0x70,0xa7,0x26,0xd9,0x36,0x94,0x9c,0xc7,0xd2,0xb8,0xae,0xb7,0x88,0xb6,0x8a,0xb7, +0x5a,0xc7,0x19,0x14,0x48,0xbb,0xb0,0xb5,0xd2,0xa7,0xa6,0xc7,0x8a,0xb8,0x88,0xb6, +0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00,0x48,0x5c,0x15,0x53,0x54,0xa9,0xbd,0x0d, +0xd4,0xe3,0xa4,0x92,0x8a,0xdc,0x86,0xdb,0x40,0x53,0x13,0x1c,0x56,0xe0,0xc1,0x15, +0xd6,0xe3,0xa4,0x92,0x8c,0xdb,0x84,0xdc,0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00, +0x40,0x5b,0x11,0x53,0x54,0xe9,0xbc,0xcd,0xd8,0xe2,0xaa,0x92,0x8e,0xe4,0x84,0xd3, +0x48,0xa3,0x13,0x49,0x46,0xec,0xae,0xd4,0xda,0x9a,0xb8,0xdb,0x90,0xd4,0x83,0x1a, +0x9c,0x31,0x10,0x1b,0xc6,0x89,0x30,0x00,0x55,0x23,0x17,0x9b,0x32,0x8e,0x98,0xf0, +0xda,0x4c,0xc5,0x24,0x96,0xd2,0x87,0x23,0x63,0x13,0x20,0xf4,0x24,0x89,0x7c,0xdd, +0xd0,0xe3,0xd1,0x53,0xa4,0xe3,0x8a,0xd3,0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00, +0x6e,0xa3,0x30,0x09,0x1c,0xf6,0x5e,0xc3,0xbb,0x21,0xd6,0xdc,0xb2,0x93,0x92,0xa2, +0x7a,0xd4,0x46,0xa4,0x1d,0x80,0x42,0xf4,0x9d,0x14,0xd2,0x9b,0xc2,0xe2,0x9c,0xd4, +0x9c,0x31,0x10,0xdd,0xc5,0x87,0x10,0x00,0x83,0x4b,0x5b,0x30,0x29,0x56,0x30,0x13, +0x7c,0xd0,0xc0,0xc4,0xc7,0x2d,0xaa,0xca,0x8e,0xba,0x6a,0xb4,0x3c,0x32,0x36,0x5b, +0x60,0xb4,0x98,0xb2,0xae,0xc3,0xa4,0x44,0x9c,0x31,0x10,0x06,0xa4,0x44,0x00,0x00, +0xdd,0x41,0xaa,0xa9,0x67,0x65,0x23,0x24,0x02,0x99,0x2a,0xa2,0x74,0xe6,0xb5,0x12, +0xe1,0x13,0xf2,0x94,0xd4,0xa9,0x8a,0xd3,0x32,0xdc,0x04,0xe2,0x10,0x9a,0x4a,0xdc, +0x9c,0x31,0x10,0xb5,0xa2,0x23,0x00,0x00,0x96,0x4d,0xd2,0x4d,0xf0,0x76,0xd9,0x44, +0x95,0x65,0x47,0x48,0x17,0x91,0x17,0x51,0x45,0x8d,0x8f,0x89,0xce,0x95,0xe4,0x29, +0xc8,0x89,0x8c,0x2d,0x4c,0xa9,0x2b,0x8d,0x9c,0x31,0x10,0xb5,0xa2,0x23,0x00,0x00, +0x34,0x65,0x5b,0x30,0x95,0x65,0xc4,0x79,0xca,0xa5,0xa6,0xad,0x72,0x51,0x4d,0x6a, +0x45,0x4c,0x56,0x75,0x78,0x8d,0x9e,0xa5,0xae,0x75,0xa4,0x25,0x89,0x69,0x6f,0x75, +0x9c,0x31,0x10,0x70,0x82,0x22,0x00,0x00,0x0b,0x9d,0x12,0x8b,0x50,0xf2,0x9e,0x84, +0xc6,0xda,0xc0,0xe4,0x9a,0xd9,0x6f,0x14,0x52,0xd1,0x50,0xf3,0x69,0x0d,0x8f,0x23, +0xa0,0xe3,0x97,0x0b,0x84,0xec,0x74,0xd1,0x9c,0x31,0x10,0xea,0x64,0x32,0x00,0x00, +0x25,0xda,0x25,0xcd,0x5d,0xea,0xae,0x13,0xc9,0xa3,0x99,0xdb,0x6d,0xda,0x49,0xdd, +0x42,0x5b,0x4d,0xda,0x5e,0x5b,0x92,0x32,0xae,0x1b,0xa2,0x18,0x6a,0x64,0x48,0x56, +0x9c,0x31,0x10,0xba,0x96,0x88,0x50,0x00,0x73,0x77,0x73,0x77,0x73,0x77,0x7b,0x77, +0x7b,0x77,0x83,0x77,0x7b,0x77,0x73,0x77,0x72,0x77,0x73,0x77,0x72,0x77,0x7b,0x66, +0x83,0x76,0x83,0x65,0x89,0x76,0xc1,0x13,0x9c,0x31,0x10,0x02,0xa9,0xa9,0x50,0x00, +0xc0,0xbe,0xd9,0xb3,0xa1,0xe2,0x8d,0xcb,0x99,0xcb,0xde,0x42,0xcd,0xab,0x59,0xa4, +0x09,0xa3,0x1d,0x3b,0x29,0xcb,0x31,0xd4,0x1d,0xca,0x42,0x43,0x59,0xbb,0x3e,0x33, +0x9c,0x31,0x10,0x4b,0xc8,0x97,0x20,0x00,0x62,0xe5,0x5d,0x05,0x6e,0xe5,0x90,0xcd, +0xac,0xcd,0xa2,0xd1,0x6b,0x11,0x30,0xd1,0x37,0x4c,0x93,0x0d,0xe1,0x2d,0xe3,0x0d, +0x9e,0xe9,0x55,0x29,0x22,0x49,0x41,0x0a,0x9c,0x31,0x10,0xdb,0xc8,0x77,0x20,0x00, +0xa4,0xc0,0xdd,0x01,0xc7,0x01,0x9c,0xc5,0x7f,0x29,0x4b,0x4d,0x15,0xb5,0x4f,0x12, +0xb9,0x11,0xdc,0xd5,0xb2,0xd1,0x84,0xd1,0x5c,0xcd,0x1e,0x09,0x32,0x29,0x96,0x66, +0x9c,0x31,0x10,0x08,0xc9,0x76,0x10,0x00,0xd6,0xe5,0xc1,0x24,0x97,0x0a,0x7b,0x29, +0x3f,0x35,0x17,0x90,0x63,0x14,0xc4,0xd2,0xd2,0x91,0xa4,0x90,0x86,0xce,0x64,0xe5, +0x1a,0xa5,0x32,0xc8,0x9b,0x09,0xd7,0x2a,0x9c,0x31,0x10,0x39,0xc8,0x66,0x00,0x00, +0xb9,0x69,0x8f,0x0d,0x80,0xf1,0x40,0xda,0x17,0xd0,0x64,0xd4,0xc4,0x92,0xce,0x92, +0x9c,0xad,0x89,0x09,0x6a,0xe5,0x1e,0x66,0x32,0xcc,0x9d,0x6d,0xd7,0x4e,0xb5,0x0d, +0x9c,0x31,0x10,0xb6,0xc8,0x67,0x00,0x00,0x8c,0xcc,0x84,0xf1,0x44,0xfa,0x15,0xad, +0x64,0x70,0xc8,0x6d,0xd0,0xf2,0x9a,0xcc,0x89,0x0d,0x70,0xc6,0x1c,0x65,0x2d,0x28, +0x9b,0x89,0xda,0xce,0xb4,0xad,0x88,0xf0,0x9c,0x31,0x10,0x02,0xc8,0x67,0x10,0x00, +0x89,0x2d,0x4d,0x16,0x0f,0x30,0x5a,0x0d,0xc6,0xce,0xd5,0x6d,0x98,0xa8,0x88,0xc9, +0x7e,0xee,0x22,0x80,0x1d,0xcd,0x91,0x4e,0xde,0x6d,0xba,0xec,0x87,0x11,0x91,0x2d, +0x9c,0x31,0x10,0x02,0xc8,0x67,0x10,0x00,0x60,0xec,0x06,0x95,0x40,0x2a,0xc1,0x6d, +0xdf,0x48,0x9c,0xce,0x83,0x0d,0x93,0x10,0x3a,0xf5,0x03,0xad,0x70,0x50,0xde,0x6d, +0xcd,0x4e,0x86,0xc9,0x8e,0xe8,0x84,0xc9,0x9c,0x31,0x10,0xe6,0xd8,0x67,0x20,0x00, +0x48,0x41,0x49,0xcd,0x8f,0xae,0xb4,0xb1,0x96,0xac,0x7e,0xad,0x8e,0xee,0x77,0x29, +0x38,0x49,0x56,0x49,0xa5,0x6d,0xb3,0x69,0x89,0x2d,0x80,0xd1,0x94,0x91,0x69,0x0d, +0x9c,0x31,0x10,0x63,0xd9,0x77,0x20,0x00,0x30,0xf1,0x66,0x6a,0xb2,0xcd,0xad,0x28, +0x7f,0x0d,0x87,0x2d,0x98,0xd1,0x5a,0xf1,0x2b,0x14,0x74,0x6e,0xba,0xae,0xa2,0xe8, +0x79,0x0d,0x8f,0x4e,0x9b,0x11,0x51,0x15,0x9c,0x31,0x10,0x2a,0xd9,0x87,0x10,0x00, +0x25,0x10,0x7e,0x4e,0xc2,0x6d,0x9a,0xc8,0x73,0x0d,0x97,0x8d,0x9f,0x51,0x4b,0x51, +0x20,0xd5,0x82,0x12,0xc6,0x2d,0x94,0x89,0x71,0x0a,0x9d,0x89,0xa5,0x4d,0x4f,0x6d, +0x9c,0x31,0x10,0xeb,0xd9,0x87,0x20,0x00,0x1a,0x92,0x7c,0x2c,0xc4,0x4d,0x94,0x8a, +0x71,0x29,0x9d,0x49,0xab,0x0a,0x5b,0x2d,0x1c,0x44,0x69,0x09,0xbf,0x0a,0x99,0x28, +0x71,0x6d,0x99,0x0d,0xb2,0xed,0x71,0x0d,0x9c,0x31,0x10,0x6d,0xd9,0x88,0x20,0x00, +0x26,0xec,0x49,0xa2,0xad,0x1a,0xa7,0x1c,0x76,0xdb,0x8c,0xdb,0xb1,0x1b,0x8c,0xdb, +0x3f,0x13,0x30,0x54,0x88,0xa1,0xb0,0xa4,0x84,0xa4,0x7e,0xea,0xa8,0xa3,0xa2,0xa4, +0x9c,0x31,0x10,0x75,0xd9,0x98,0x20,0x00,0x62,0xdb,0x30,0xe4,0x59,0x59,0xa9,0x13, +0x9b,0x14,0x78,0xd3,0x94,0xd3,0xad,0x1b,0x88,0xd3,0x4a,0xdb,0x38,0x0a,0x7a,0xdc, +0xa8,0xa4,0x88,0xe2,0x7e,0xe3,0xa0,0xa3,0x9c,0x31,0x10,0xcd,0xc8,0x98,0x20,0x00, +0xc8,0xdb,0x6a,0xdb,0x09,0x52,0x0c,0xe5,0x9e,0xaa,0xc4,0xa2,0x82,0xdc,0x8f,0x5c, +0xcc,0xd2,0xb6,0xda,0x54,0xdc,0x05,0x63,0x23,0x73,0xaa,0xdc,0xb8,0xc9,0x80,0xd3, +0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00,0x99,0x1c,0xcc,0xdb,0xac,0xe2,0x4a,0xdb, +0x07,0x24,0x2f,0xa2,0xb0,0xcd,0xb6,0xd3,0x7e,0xa2,0x9b,0x23,0xcc,0xdc,0xa8,0xda, +0x4a,0xda,0x0d,0x23,0x2d,0xa3,0xa6,0xcd,0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00, +0xb4,0xd3,0x84,0xe2,0x97,0x2b,0xca,0xdb,0xac,0xd3,0x54,0xdc,0x13,0x5b,0x23,0x34, +0x98,0xda,0xb8,0xc9,0x8a,0xdb,0x8f,0x25,0xc6,0xdb,0xb8,0x92,0x64,0xdb,0x1d,0x5b, +0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00,0x14,0x1a,0x7e,0xf2,0xbc,0x9d,0x92,0xcb, +0x82,0xda,0xba,0xe3,0xc8,0xdc,0x7e,0xd3,0x30,0xdb,0x0e,0x1c,0x51,0x4a,0xb6,0xa1, +0xa7,0x24,0x7e,0xd4,0xa1,0x12,0xcc,0xe2,0x9c,0x31,0x10,0x52,0xc8,0x98,0x40,0x00, +0xa2,0xe4,0x4c,0xd4,0x17,0x5a,0x23,0x34,0x94,0xd1,0xba,0x8a,0x8c,0xe4,0x84,0xe3, +0xbe,0xd2,0xc4,0xd3,0x7a,0xe4,0x2e,0xdb,0x0c,0x13,0x4f,0x42,0xb6,0xa9,0xad,0x25, +0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00,0x7e,0xcc,0x96,0xda,0xce,0xe3,0xb2,0xdc, +0x5a,0xdb,0x1d,0x1a,0x16,0x19,0x76,0xec,0xbc,0x96,0x9b,0x13,0x7e,0xe2,0xac,0xdb, +0xd2,0xdc,0x9a,0xdb,0x44,0xd3,0x19,0x5b,0x9c,0x31,0x10,0x3a,0xc7,0x98,0x40,0x00, +0x23,0x2e,0x8c,0xd0,0xbc,0x91,0x94,0xec,0x7e,0xdc,0xb3,0x53,0xd0,0xe3,0x90,0xd2, +0x3e,0xd3,0x19,0x22,0x2d,0xa6,0x92,0xc4,0xb8,0xe0,0x92,0xa3,0x7e,0xd5,0xb5,0x1b, +0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00,0xcc,0xe3,0x8c,0xd3,0x3e,0xdb,0x1b,0x63, +0x2f,0xa5,0x90,0xcb,0xba,0xe2,0x94,0xe3,0x7a,0xd4,0xad,0x5a,0xca,0xe3,0x94,0xdb, +0x46,0x9b,0x23,0x5b,0x29,0x2c,0x82,0xd1,0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00, +0xba,0xd4,0x9c,0xe4,0x76,0xd3,0x9a,0xda,0xca,0xdc,0xa6,0xdb,0x56,0xd2,0x2b,0x1b, +0x24,0x51,0x68,0xee,0xb2,0x8c,0xaa,0xda,0x7c,0xe2,0x86,0xdd,0xbe,0xdb,0xba,0xda, +0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00,0x70,0xe3,0x37,0x1b,0x22,0x1c,0x47,0x89, +0x9e,0xe4,0xb7,0x1c,0x8e,0x93,0x78,0xe3,0xa9,0x1c,0xcb,0x23,0x94,0xd2,0x4a,0xdb, +0x27,0x5b,0x28,0xa3,0x74,0xa1,0xb4,0x95,0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00, +0xaa,0xe3,0x7c,0xd2,0x86,0xe3,0xbe,0x9b,0xbc,0xdb,0x72,0xe3,0x38,0xd3,0x24,0xa3, +0x3f,0x89,0x92,0xe5,0xb9,0x1b,0x98,0xd3,0x76,0xe3,0x98,0xd3,0xc6,0xdb,0xaa,0x9b, +0x9c,0x31,0x10,0x86,0xc7,0x89,0x30,0x00,0x62,0x93,0x35,0x23,0x24,0x0b,0x4f,0x1c, +0xa0,0xa9,0xb9,0x0c,0x90,0xeb,0x76,0xd3,0x9c,0xe3,0xc4,0xdb,0xa2,0xdb,0x5c,0xdb, +0x33,0x1b,0x26,0x0a,0x58,0xf5,0xa4,0x8a,0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00, +0xba,0xe3,0x90,0xdb,0x76,0xdb,0x9a,0xda,0xc0,0xe4,0xa0,0xd2,0x60,0xe2,0x35,0x1c, +0x24,0x12,0x55,0x2e,0xa2,0x91,0xbd,0x23,0x94,0xdb,0x74,0xdb,0x92,0xdb,0xbe,0xdc, +0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00,0xaa,0xda,0x6a,0x9c,0x38,0xdb,0x24,0x53, +0x4b,0x1c,0x98,0xe0,0xbf,0x16,0x9e,0xe2,0x76,0xd3,0x88,0xe3,0xb6,0xd3,0xb2,0xe3, +0x78,0xd3,0x40,0xe2,0x24,0x9c,0x3d,0x48,0x9c,0x31,0x10,0x9a,0xc5,0x88,0x20,0x00, +0x86,0x56,0xb9,0x2b,0xac,0xcb,0x80,0xb3,0x7e,0xc4,0xa8,0xb2,0xb8,0x3b,0x8c,0xc2, +0x4e,0xbc,0x2b,0x3a,0x31,0x5e,0x6e,0x11,0xae,0xda,0xb6,0xac,0x8e,0xcb,0x76,0xb2, +0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00,0x96,0xe3,0xba,0xdb,0xa2,0xdb,0x64,0x9a, +0x35,0x1c,0x2a,0x12,0x55,0x2e,0x98,0x92,0xb9,0x23,0x9e,0xd3,0x78,0xe3,0x82,0x92, +0xac,0xe4,0xb2,0xdb,0x82,0xda,0x4a,0xdb,0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00, +0x2c,0xe2,0x39,0x53,0x76,0xde,0xb0,0xe0,0xb2,0xdc,0x8a,0xdb,0x76,0xdb,0x93,0x1a, +0xb2,0xdd,0x9f,0x1a,0x68,0x9a,0x3b,0x1c,0x2c,0x12,0x50,0xed,0x94,0xca,0xba,0xe2, +0x9c,0x31,0x10,0x55,0xc5,0x77,0x10,0x00,0xa6,0x4d,0x7e,0x6a,0x7d,0x52,0xa0,0x5b, +0xad,0x65,0x8c,0x51,0x57,0x63,0x33,0x94,0x35,0xac,0x6c,0x43,0xa8,0x70,0xb9,0x4e, +0x99,0x68,0x7c,0x55,0x89,0x62,0xa7,0x5c,0x9c,0x31,0x10,0x69,0xc6,0x78,0x10,0x00, +0xa2,0xd3,0x76,0x9a,0x46,0xdc,0x30,0x13,0x47,0x1c,0x84,0xe0,0xb5,0x16,0xb0,0xda, +0x8a,0xdc,0x7c,0xdb,0x94,0xd3,0xa6,0xe3,0x92,0xdb,0x64,0xdb,0x3d,0x13,0x34,0xec, +0x9c,0x31,0x10,0xd3,0xc5,0x78,0x10,0x00,0x5c,0x92,0x98,0xdd,0xb6,0xa5,0xa4,0xd7, +0x82,0xa8,0x83,0x46,0x9a,0xb7,0xa0,0xb7,0x84,0xc7,0x58,0xa7,0x3a,0xc7,0x41,0x15, +0x70,0xdb,0xa4,0x95,0xb4,0xc6,0x9a,0x29,0x9c,0x31,0x10,0x30,0xb5,0x68,0x10,0x00, +0x82,0xe6,0x94,0x97,0xb4,0xc8,0xa2,0xb6,0x60,0xb7,0x22,0xb7,0x0a,0x26,0x2e,0xe9, +0x7a,0x89,0xb4,0xd3,0xbc,0xaa,0xb2,0xc6,0xbe,0x97,0xc4,0xd8,0xa0,0x98,0x64,0xc5, +0x9c,0x31,0x10,0x18,0xb5,0x58,0x10,0x00,0x36,0xc8,0x1c,0xe6,0x19,0x57,0x4c,0xda, +0x9a,0xd3,0xc2,0xd9,0xba,0xc6,0xb0,0xe7,0xb8,0xd7,0xae,0xc7,0x84,0xd6,0x54,0xd8, +0x34,0xd6,0x1e,0x47,0x2b,0x29,0x68,0xc4,0x9c,0x31,0x10,0x9f,0xb4,0x67,0x00,0x00, +0xa7,0x24,0xbc,0xcb,0xb4,0xea,0xb7,0x4b,0xba,0xeb,0x9e,0xd3,0x70,0xa3,0x48,0xdb, +0x31,0x5b,0x22,0xe4,0x42,0xd2,0x84,0xa2,0xb4,0xd5,0xba,0xda,0xb6,0xdc,0xba,0xd2, +0x9c,0x31,0x10,0x8d,0xb5,0x66,0x00,0x00,0xaa,0xe3,0x81,0x15,0x54,0x99,0x39,0x1c, +0x28,0x52,0x39,0x2d,0x70,0x8a,0xa6,0xe1,0xbc,0xd6,0xb8,0xe1,0xb8,0xd3,0xac,0xdb, +0x88,0xdd,0x5e,0xd9,0x40,0xdc,0x30,0x9b,0x9c,0x31,0x10,0x20,0xb4,0x46,0x00,0x00, +0x39,0x5b,0x68,0xe1,0x9f,0x1d,0xb8,0x92,0xba,0xdb,0xb8,0xd4,0xaa,0xda,0x85,0x1b, +0x58,0x9c,0x3c,0xd2,0x32,0x9b,0x45,0x1c,0x74,0x98,0xa5,0x25,0xbe,0xca,0xc0,0xe2, +0x9c,0x31,0x10,0x8d,0xb2,0x35,0x00,0x00,0xb6,0x86,0x9a,0xa9,0x6e,0x6a,0x44,0x4c, +0x2f,0x6b,0x3a,0x34,0x65,0xa2,0x97,0x74,0xb8,0x83,0xc2,0x52,0xbb,0x8d,0xa5,0x20, +0x7e,0x75,0x50,0xa3,0x2f,0x72,0x33,0x4c,0x9c,0x31,0x10,0x95,0xb2,0x25,0x00,0x00, +0x5b,0x72,0x8f,0x42,0xb3,0x4d,0xc0,0x82,0xbc,0x93,0xa8,0x8d,0x82,0x51,0x53,0x4c, +0x32,0x4c,0x34,0xa2,0x59,0x8b,0x8b,0x63,0xb1,0x4b,0xc3,0x23,0xc0,0x93,0xa6,0x84, +0x9c,0x31,0x10,0x1a,0xb2,0x24,0x00,0x00,0x78,0x69,0x49,0x4c,0x31,0x4b,0x3d,0x14, +0x63,0x4c,0x91,0xaa,0xb9,0x2a,0xcc,0x6d,0xbd,0x4a,0x91,0x8a,0x5d,0x4c,0x3b,0x4a, +0x37,0x6b,0x4f,0x8b,0x78,0x53,0xa3,0x4b,0x9c,0x31,0x10,0xa5,0xb1,0x22,0x00,0x00, +0xbf,0x65,0xc0,0x8b,0xa3,0x08,0x78,0x5c,0x54,0x12,0x44,0xa4,0x4d,0x0c,0x67,0x28, +0x89,0x96,0xa7,0x5a,0xb2,0x58,0xa7,0x5e,0x8b,0x53,0x6e,0x5b,0x5d,0x51,0x5a,0x9b, +0x9c,0x31,0x10,0x4d,0x92,0x32,0x00,0x00,0x11,0xab,0x57,0x15,0xa9,0x0d,0xea,0xd1, +0xfc,0xe3,0xd2,0xdc,0x85,0x1a,0x40,0xdb,0x1e,0x9c,0x26,0x53,0x48,0x92,0x78,0xdb, +0xa6,0x99,0xc2,0xde,0xbf,0x1e,0x9d,0x18,0x9c,0x31,0x10,0x58,0x82,0x12,0x00,0x00, +0x63,0x83,0x29,0x63,0x1a,0x4b,0x2d,0x34,0x5a,0x61,0x92,0x73,0xbc,0x4c,0xc5,0x8c, +0xad,0x49,0x88,0x64,0x69,0x63,0x60,0x93,0x63,0x6a,0x6a,0x6a,0x77,0x4d,0x89,0x72, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_PAIRING_FAIL.txt b/config/_default_cfg_src_/res/cn/SOUND_PAIRING_FAIL.txt new file mode 100644 index 0000000..3be7659 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_PAIRING_FAIL.txt @@ -0,0 +1,310 @@ +0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x81,0x9b, +0x8e,0x12,0x8e,0x52,0x95,0xeb,0xad,0xee,0xbd,0xe1,0xb5,0xa4,0xba,0x1b,0xae,0x13, +0xa1,0x6a,0x9d,0xe4,0xa1,0xdc,0x93,0x2a,0x9c,0x31,0x10,0x29,0x32,0x20,0x00,0x00, +0x91,0x8d,0x95,0xd0,0x91,0x50,0x96,0x92,0x7d,0x93,0x69,0xd0,0x6a,0x0e,0x52,0x33, +0x59,0xcc,0x46,0x96,0x69,0xd9,0x66,0x0a,0x89,0x77,0x7e,0x2c,0x7f,0x12,0xfb,0x97, +0x9c,0x31,0x10,0x8a,0x63,0x21,0x00,0x00,0x85,0x05,0x86,0xd1,0x9d,0x4c,0x99,0x8a, +0x96,0xe8,0x87,0x10,0x7e,0xd2,0x8d,0x6e,0x80,0xd5,0x7e,0xcd,0x6e,0xc5,0x6e,0x92, +0x4f,0x31,0x3c,0xec,0x3c,0xf0,0x46,0xaa,0x9c,0x31,0x10,0x3e,0xb7,0x75,0x00,0x00, +0x7c,0xed,0x7c,0xed,0x7e,0xed,0x7e,0xed,0x7e,0xed,0x7e,0xed,0x7e,0xed,0x7e,0xed, +0x7e,0xed,0x7e,0xed,0x80,0xed,0x82,0xed,0x86,0xed,0x96,0xa9,0xc0,0xc4,0xca,0x4e, +0x9c,0x31,0x10,0xa4,0xa7,0x54,0x00,0x00,0xdc,0xad,0xda,0xe4,0xeb,0x09,0xab,0x21, +0x71,0x04,0x69,0x6a,0x4f,0x22,0x23,0x24,0x19,0x0a,0x0b,0x28,0x01,0x49,0x0b,0x29, +0x29,0x0d,0x2b,0x0d,0x28,0xee,0x45,0x11,0x9c,0x31,0x10,0xec,0x98,0x78,0x20,0x00, +0x24,0x37,0x0b,0xb7,0x44,0x37,0x42,0xc7,0x4c,0x37,0x5a,0xc7,0x6d,0xd6,0x8c,0xd7, +0x64,0x17,0x9e,0x17,0x82,0xb5,0x76,0x2b,0x89,0xb9,0x7d,0x11,0x93,0x3a,0x76,0x39, +0x9c,0x31,0x10,0x4d,0x99,0x88,0x30,0x00,0xb3,0xe1,0x93,0xd3,0x93,0xb4,0xc3,0x72, +0x7c,0x65,0xc3,0xa1,0xbd,0xa3,0xc4,0x33,0xdb,0x52,0xba,0xbc,0xbc,0x13,0xab,0x3c, +0xa4,0x5c,0x9a,0xe3,0xa4,0x5a,0xa3,0x9c,0x9c,0x31,0x10,0xc6,0x88,0x98,0x40,0x00, +0xb4,0x3a,0xe2,0xc2,0xcd,0xb5,0xc4,0x29,0xcd,0x43,0xa3,0xbc,0xd5,0x44,0xad,0x4a, +0x84,0x2a,0xe6,0x13,0x78,0xbb,0xa5,0x4a,0x79,0xa5,0x65,0x2b,0x8a,0x4b,0x7c,0xc4, +0x9c,0x31,0x10,0xce,0x76,0x88,0x30,0x00,0x59,0x13,0x73,0x25,0xa3,0xc8,0x8a,0xd9, +0x61,0x58,0xc6,0x66,0x53,0x56,0x35,0x97,0xde,0x88,0x68,0xc5,0x82,0x87,0xea,0x36, +0x52,0x59,0x3d,0x69,0x11,0x93,0xba,0x48,0x9c,0x31,0x10,0x1c,0xb8,0x87,0x30,0x00, +0x7d,0xe2,0x81,0xe4,0x75,0x9c,0x76,0x1e,0x75,0x99,0x8a,0x26,0x8d,0x5e,0x7a,0x55, +0x66,0x28,0x65,0xe1,0x7d,0xa5,0xa1,0x4a,0xaa,0x21,0x5d,0x65,0x26,0x20,0x4c,0xce, +0x9c,0x31,0x10,0xfc,0xc9,0x88,0x30,0x00,0x9c,0xec,0xba,0xe2,0x88,0xca,0x4b,0x16, +0x3a,0xea,0x85,0x12,0xd6,0x9b,0xae,0xe4,0x5e,0xa4,0x30,0xd9,0x47,0x2c,0xc0,0xc4, +0xc6,0xda,0xa7,0x21,0x51,0x1e,0x18,0x12,0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00, +0x69,0x9a,0xd0,0xa4,0xb1,0x5a,0x9b,0x23,0x55,0x0c,0x10,0x23,0x73,0x29,0xd2,0x54, +0xa8,0xda,0x97,0x23,0x5d,0x0b,0x10,0x6c,0x75,0x21,0xd2,0x8c,0xa8,0xa3,0x97,0x5c, +0x9c,0x31,0x10,0xcd,0xc8,0x98,0x20,0x00,0x5e,0xd3,0x10,0xa4,0x71,0x20,0xd0,0x8d, +0xac,0xe3,0x91,0x64,0x68,0xd1,0x12,0x94,0x65,0x32,0xd0,0x8d,0xb4,0xd9,0x8f,0x23, +0x73,0x14,0x18,0x59,0x50,0xe6,0xc8,0x9a,0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00, +0xc0,0xd3,0x90,0xdc,0x79,0x20,0x28,0x16,0x3b,0x24,0xb8,0x98,0xcb,0x14,0x96,0x9b, +0x80,0xdd,0x3e,0x20,0x21,0x4a,0x98,0xe5,0xd7,0x1b,0xa8,0x9a,0x84,0xd9,0x56,0xdd, +0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00,0x17,0x5c,0x72,0xd3,0xd0,0xe2,0xbe,0xdb, +0x8a,0xe4,0x6b,0x52,0x1e,0x5a,0x46,0xe4,0xbc,0x93,0xd1,0x22,0x9a,0x94,0x7a,0xdc, +0x44,0x21,0x1f,0x4b,0x86,0xec,0xd7,0x13,0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00, +0xbc,0xd9,0x84,0xdc,0x61,0x56,0x1c,0xe9,0x4c,0xd0,0xbc,0x9e,0xd6,0xda,0x9e,0x92, +0x77,0x25,0x3e,0x13,0x1f,0x50,0x80,0xe4,0xd6,0xd6,0xc6,0xd9,0x88,0xdb,0x65,0x5c, +0x9c,0x31,0x10,0x32,0xc7,0x89,0x20,0x00,0x22,0x22,0x3a,0xea,0xaa,0x4d,0xdf,0x2a, +0xb4,0x4b,0x79,0x23,0x4c,0xe2,0x19,0x9c,0x56,0xcc,0xc2,0xa9,0xe2,0xcc,0xa2,0xab, +0x6d,0x54,0x3a,0x1b,0x1f,0x8a,0x70,0xec,0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00, +0xd3,0x14,0xda,0xe2,0x90,0xd3,0x67,0x1b,0x2e,0x53,0x25,0x1c,0x82,0xd9,0xdd,0x1c, +0xd2,0xdb,0x8c,0xd3,0x5f,0x23,0x24,0x52,0x2a,0xed,0x8e,0x8c,0xdf,0x22,0xce,0xd3, +0x9c,0x31,0x10,0x81,0xc7,0x78,0x30,0x00,0x8c,0xe3,0x5f,0x1b,0x22,0x11,0x2a,0xf4, +0x8c,0x86,0xdf,0x28,0xd4,0xc4,0x92,0xed,0x5b,0x12,0x1e,0x1a,0x28,0xf3,0x88,0x86, +0xe1,0x30,0xd8,0x84,0x94,0xe3,0x60,0xd2,0x9c,0x31,0x10,0x86,0xc7,0x89,0x30,0x00, +0x20,0x12,0x1e,0xec,0x80,0x8b,0xdd,0x2a,0xde,0xd4,0x9c,0xdb,0x68,0xd3,0x28,0x5a, +0x19,0x1e,0x6a,0x98,0xd1,0x1b,0xe6,0xdc,0xaa,0xdb,0x72,0xd3,0x34,0xa3,0x13,0x4a, +0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00,0x54,0xab,0xbc,0xcc,0xea,0xe3,0xbc,0x9b, +0x83,0x5a,0x45,0x1b,0x11,0x99,0x38,0xd6,0x9e,0xa2,0xe7,0x0b,0xd0,0xa2,0x95,0x15, +0x59,0x22,0x1a,0xa4,0x26,0xda,0x7c,0x9c,0x9c,0x31,0x10,0xef,0xc6,0x77,0x10,0x00, +0xd7,0x22,0xdc,0x94,0xa6,0xda,0x6c,0xe3,0x2e,0x01,0x21,0x36,0x5c,0x9b,0xb1,0x11, +0xd2,0xec,0xae,0x9c,0x83,0x12,0x5c,0xac,0x43,0x92,0x4c,0x93,0x73,0x23,0x94,0xe3, +0x9c,0x31,0x10,0xb4,0xb4,0x55,0x00,0x00,0xc1,0x02,0xcb,0x15,0xc6,0x63,0x98,0x9a, +0x5a,0xdc,0x33,0x23,0x3e,0xd3,0x6e,0xdb,0xaa,0xdb,0xcc,0xda,0xc4,0xdc,0x98,0xdb, +0x5c,0xdb,0x34,0xdb,0x36,0xdb,0x64,0xdb,0x9c,0x31,0x10,0x28,0xa3,0x23,0x00,0x00, +0xb8,0x32,0xfa,0x4c,0xf7,0x61,0xad,0x51,0x48,0x69,0x0a,0x95,0x13,0x4e,0x54,0x75, +0xa3,0x65,0xd7,0x6e,0xd3,0x70,0x9b,0x76,0x57,0x70,0x34,0x71,0x39,0x69,0x5f,0x6d, +0x9c,0x31,0x10,0x55,0x92,0x22,0x00,0x00,0xa8,0x49,0xf4,0xd5,0xea,0xda,0xa2,0xa2, +0x59,0x1c,0x28,0x99,0x27,0x0b,0x54,0xad,0x9d,0x11,0xc6,0xe5,0xbc,0xcb,0x96,0xe3, +0x64,0x92,0x46,0xd3,0x4a,0x93,0x6a,0xeb,0x9c,0x31,0x10,0x70,0x82,0x22,0x00,0x00, +0xa8,0x95,0xd4,0x50,0xcc,0xd4,0x9c,0x8d,0x63,0x1a,0x3a,0xe4,0x3f,0x13,0x71,0x12, +0xa0,0xe3,0xb5,0x13,0xb0,0x8b,0x91,0x32,0x62,0x84,0x4c,0xaa,0x67,0x1c,0x84,0x5b, +0x9c,0x31,0x10,0xfc,0x73,0x43,0x00,0x00,0xa9,0xc3,0xc9,0xb1,0xbd,0xbc,0x75,0x3c, +0x49,0xbb,0x5d,0xba,0x79,0xbb,0x7e,0x3b,0x9d,0xbb,0xa1,0x3b,0x79,0xac,0x65,0x3b, +0x7d,0x2a,0x85,0x12,0x81,0x33,0x88,0xd5,0x9c,0x31,0x10,0x1f,0xb9,0xaa,0x40,0x00, +0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77,0x83,0x67,0x8a,0x88, +0xa2,0x23,0xbd,0xac,0xd2,0xa5,0xb4,0x54,0x6b,0x58,0x73,0x87,0x8b,0x67,0x7a,0x96, +0x9c,0x31,0x10,0xaf,0xc6,0x89,0x20,0x00,0x61,0x9d,0x54,0xcb,0x58,0x9a,0x5e,0xdc, +0x60,0xe3,0x60,0xda,0x5c,0xdb,0x5f,0x4b,0x6d,0x53,0x83,0x2b,0x9b,0x2b,0xa0,0xdb, +0x78,0xd3,0x3a,0x93,0x39,0x53,0x9c,0x93,0x9c,0x31,0x10,0x31,0xd8,0x88,0x10,0x00, +0xc4,0xdb,0xbe,0xda,0x7a,0xe4,0x36,0x5b,0x3f,0x0a,0x90,0xd3,0xcb,0x14,0xba,0xdb, +0x8a,0xa2,0x67,0x1c,0x4a,0x52,0x56,0xa2,0x8e,0x9d,0xb4,0xda,0xaa,0xe3,0x88,0xdc, +0x9c,0x31,0x10,0xdb,0xc8,0x77,0x20,0x00,0x57,0x28,0x0c,0xd2,0x2c,0x94,0xa4,0x75, +0xf0,0xd2,0xcc,0xac,0x80,0xed,0x41,0x09,0x0b,0x75,0x48,0xd1,0xb8,0xb0,0xea,0xcd, +0xb6,0x8d,0x79,0x09,0x3e,0xb1,0x0f,0xad,0x9c,0x31,0x10,0x4c,0xc8,0x66,0x20,0x00, +0x57,0x12,0xc4,0xd1,0xe8,0xed,0xa8,0xb2,0x69,0x35,0x28,0x75,0x13,0xa4,0x73,0x50, +0xd7,0x0e,0xe2,0xd0,0x98,0x91,0x61,0x0e,0x20,0x24,0x1f,0x66,0x89,0x44,0xe3,0x6c, +0x9c,0x31,0x10,0x54,0xc8,0x76,0x20,0x00,0xd8,0xee,0x8a,0xac,0x59,0x0d,0x18,0x25, +0x2e,0xa9,0x9c,0xea,0xe9,0x8c,0xcd,0x4d,0x81,0x0d,0x4c,0xec,0x10,0x8e,0x40,0x4c, +0xb2,0x6d,0xeb,0x4e,0xbb,0x2d,0x79,0x8d,0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00, +0x47,0x0d,0x0f,0x15,0x52,0x91,0xc0,0x70,0xea,0xcd,0xae,0xe9,0x75,0x4d,0x41,0x31, +0x11,0x75,0x5c,0xd2,0xca,0x91,0xe8,0x8d,0xa4,0xa9,0x6f,0x29,0x38,0xf1,0x13,0x8d, +0x9c,0x31,0x10,0x10,0xc9,0x66,0x10,0x00,0x69,0x1a,0xd0,0xd2,0xe0,0xb0,0x9c,0x91, +0x70,0xee,0x3a,0xd9,0x13,0x6c,0x6b,0x12,0xd4,0xf2,0xe0,0xd1,0x98,0xb1,0x6e,0xed, +0x38,0xb5,0x15,0x6c,0x71,0x16,0xd4,0xf6,0x9c,0x31,0x10,0x1a,0xc8,0x77,0x10,0x00, +0xdc,0xf1,0x94,0x91,0x73,0x11,0x3e,0x95,0x13,0xb0,0x69,0x32,0xd3,0x11,0xde,0xf1, +0x96,0xb1,0x75,0x31,0x4a,0x95,0x13,0x95,0x5a,0xf2,0xca,0xf5,0xe2,0xf1,0x9c,0xd1, +0x9c,0x31,0x10,0x72,0xc7,0x77,0x10,0x00,0x75,0x23,0x56,0xe2,0x15,0x74,0x48,0xab, +0xbc,0xa9,0xe7,0x2c,0xa8,0xa4,0x79,0x22,0x69,0x24,0x1c,0x5b,0x30,0x69,0xa2,0x2d, +0xe6,0xf3,0xba,0xe9,0x7e,0xe3,0x75,0x24,0x9c,0x31,0x10,0x1a,0xc8,0x77,0x10,0x00, +0x32,0x44,0x1b,0x02,0x80,0xa8,0xdc,0xe9,0xcc,0xce,0x8a,0xb1,0x7f,0x15,0x54,0xd5, +0x0d,0x98,0x4d,0x0a,0xc3,0x05,0xe5,0x01,0xa2,0xc1,0x7f,0x09,0x76,0xed,0x22,0x68, +0x9c,0x31,0x10,0x3b,0xc7,0x87,0x20,0x00,0x1a,0xae,0x8c,0xa9,0xe7,0x20,0xc8,0xdd, +0x86,0xdd,0x85,0x21,0x59,0x25,0x0b,0xa5,0x3c,0xce,0xb8,0xd4,0xe9,0x21,0xae,0xde, +0x82,0xdc,0x82,0xd5,0x3c,0x1e,0x05,0x49,0x9c,0x31,0x10,0x81,0xc7,0x78,0x30,0x00, +0x5a,0xa1,0xd2,0xe5,0xe4,0xda,0x9e,0x93,0x83,0x14,0x7d,0x1a,0x2a,0x52,0x05,0x25, +0x6c,0xa9,0xe4,0xd3,0xe4,0xcc,0x96,0x9a,0x80,0xdb,0x7a,0xdb,0x26,0x01,0x02,0xe6, +0x9c,0x31,0x10,0x1e,0xd7,0x87,0x20,0x00,0x76,0xa4,0xb2,0xd8,0xb0,0xd6,0x8a,0xa0, +0x80,0xdd,0x7e,0xd9,0x56,0x5e,0x3d,0x49,0x6a,0xe8,0xae,0xe2,0xb7,0x18,0x90,0xd9, +0x7e,0xe1,0x80,0xdd,0x65,0x1d,0x3d,0x69,0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00, +0x30,0xcd,0xba,0xe2,0xfa,0xe3,0xc2,0xdb,0x82,0xdb,0x80,0xdb,0x6a,0xe3,0x16,0x52, +0x08,0xec,0x7a,0x9b,0xec,0xd3,0xe6,0xdb,0x98,0xe3,0x7a,0xdb,0x80,0xda,0x4b,0x1b, +0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00,0x03,0xab,0x30,0xc5,0xb2,0xe2,0xf6,0xe3, +0xc8,0xdb,0x84,0xd4,0x7c,0x9a,0x74,0x9b,0x30,0x5c,0x07,0x83,0x56,0xe9,0xcf,0x1c, +0xf0,0xd3,0xb2,0xdb,0x7d,0x23,0x7e,0xd3,0x9c,0x31,0x10,0xfa,0xc7,0x87,0x10,0x00, +0x6c,0xe1,0x22,0x4c,0x10,0xee,0x70,0x9a,0xdc,0xd9,0xe6,0xdd,0xa6,0xe1,0x7e,0xda, +0x7c,0xe1,0x5b,0x19,0x18,0xaa,0x20,0xe0,0x84,0xd1,0xe0,0xe1,0xe0,0xe5,0xa2,0xd9, +0x9c,0x31,0x10,0xa1,0xc6,0x76,0x20,0x00,0x80,0xdc,0x76,0xdd,0x4d,0x9a,0x16,0xe9, +0x2e,0xc5,0x94,0xa3,0xe2,0xe1,0xda,0xdb,0xa0,0xdd,0x80,0xdc,0x6c,0xe1,0x41,0x22, +0x1b,0x15,0x40,0xd6,0x9e,0xa8,0xde,0xdb,0x9c,0x31,0x10,0xaf,0xc5,0x76,0x30,0x00, +0xd2,0x5b,0xa1,0x5c,0x7f,0x9a,0x63,0x23,0x3c,0x52,0x24,0x9a,0x4c,0x5e,0x9e,0x64, +0xd5,0x50,0xcb,0x52,0xa0,0x6c,0x7e,0x5b,0x5f,0x4a,0x3e,0x6c,0x34,0x66,0x59,0x8c, +0x9c,0x31,0x10,0x85,0xc6,0x96,0x30,0x00,0x99,0x1c,0xc3,0x20,0xbe,0xe1,0xa3,0x1d, +0x84,0x9e,0x67,0x1d,0x4e,0xa5,0x48,0xd0,0x5e,0x61,0x84,0xac,0xa4,0xd5,0xae,0xd1, +0x9c,0xaa,0x80,0x15,0x6a,0x1a,0x60,0x64,0x9c,0x31,0x10,0xe4,0xa7,0x98,0x40,0x00, +0x11,0xcc,0x35,0x13,0x6d,0x2a,0xa5,0x4a,0xd5,0x4c,0xd1,0xcb,0xae,0x32,0x7d,0x44, +0x5d,0xab,0x5d,0xbc,0x5a,0x4a,0x6a,0xb5,0x82,0x42,0x95,0x32,0x94,0x92,0xa0,0x4b, +0x9c,0x31,0x10,0x3f,0x97,0x98,0x50,0x00,0xba,0xc7,0x91,0x79,0x61,0x6a,0x33,0xb1, +0x3b,0x48,0x53,0x0d,0x5c,0xa5,0x6c,0xc6,0x7c,0x46,0x93,0x55,0x93,0x93,0x94,0x6c, +0x8b,0x69,0x93,0x88,0x9a,0x75,0x9a,0x60,0x9c,0x31,0x10,0x9f,0x86,0x88,0x50,0x00, +0x82,0x47,0x93,0xcb,0xa4,0xee,0x8d,0x9b,0x6b,0x14,0x49,0x24,0x68,0x94,0x6b,0x95, +0x98,0x58,0xa9,0x6a,0xca,0xd8,0xc9,0xac,0xda,0x82,0xaa,0x13,0x99,0x26,0x9b,0xe6, +0x9c,0x31,0x10,0xee,0x76,0xa9,0x50,0x00,0x92,0xf7,0x54,0xe8,0x83,0x3a,0x86,0xf8, +0xa2,0xc3,0x73,0x65,0x57,0x2a,0x36,0x88,0x37,0x07,0x2b,0x49,0x0c,0x77,0x5a,0xa5, +0x47,0x75,0x59,0x06,0x38,0xa8,0x3d,0x39,0x9c,0x31,0x10,0x5b,0x77,0x99,0x50,0x00, +0x45,0xa7,0x1d,0x28,0x34,0x55,0x6c,0xa4,0x8c,0x65,0xa3,0x49,0xa4,0xab,0x93,0xb8, +0x53,0x38,0x73,0x87,0x64,0x94,0x74,0x45,0x7b,0x69,0x8b,0xa7,0x93,0x56,0x94,0x67, +0x9c,0x31,0x10,0xe5,0x76,0x88,0x40,0x00,0x65,0xc8,0x86,0x88,0x6d,0x29,0x64,0x87, +0x4c,0x96,0x3d,0x57,0x64,0x68,0x85,0xe6,0x5c,0x47,0x59,0x23,0x65,0x79,0x66,0x98, +0x94,0x7b,0x7b,0x65,0x6c,0x35,0x74,0x36,0x9c,0x31,0x10,0x74,0x66,0x88,0x50,0x00, +0xb5,0x88,0x74,0xb6,0x51,0x76,0x5a,0xa5,0x2e,0xe8,0x0d,0xa9,0x0d,0x28,0x55,0x8a, +0xbe,0x68,0xc4,0x85,0xb2,0x66,0x9b,0x44,0xc8,0x89,0x70,0x53,0x39,0x89,0x68,0x8d, +0x9c,0x31,0x10,0x74,0x66,0x88,0x50,0x00,0x80,0x77,0x6a,0xa7,0x6c,0x80,0x5c,0x73, +0x94,0x3d,0x93,0xe8,0x90,0x59,0x99,0x4a,0x5a,0x8b,0xb1,0x96,0x68,0x42,0xca,0xa3, +0x8a,0xa3,0xaa,0x4c,0x82,0x67,0x82,0x73,0x9c,0x31,0x10,0xc0,0x66,0x88,0x40,0x00, +0x6d,0x7c,0x7c,0x9a,0x6d,0xa3,0x5d,0x97,0x6c,0x29,0x4a,0x55,0x5b,0x53,0x53,0x88, +0x79,0x4a,0x7b,0x8a,0x93,0x83,0xc4,0xa3,0x86,0x77,0x84,0x8b,0x5a,0x66,0x78,0x68, +0x9c,0x31,0x10,0xfc,0x66,0x78,0x50,0x00,0x94,0xae,0xa7,0x92,0xb8,0xa2,0xb6,0xd2, +0x98,0xe5,0x86,0x11,0xa2,0x0c,0x43,0x9c,0x54,0x60,0x62,0x71,0x67,0x2a,0x59,0x5e, +0x68,0xda,0x76,0xd1,0x52,0x85,0x44,0xd4,0x9c,0x31,0x10,0xfb,0x66,0x89,0x50,0x00, +0x58,0x5c,0x5a,0x74,0x2b,0xa5,0x79,0x28,0x9b,0x5a,0x62,0xa8,0x63,0x54,0x84,0x28, +0x8b,0x98,0x73,0x86,0x96,0x35,0x84,0x56,0x94,0x79,0xa8,0x67,0xc9,0x18,0x61,0x68, +0x9c,0x31,0x10,0x45,0x67,0x98,0x40,0x00,0xa2,0xb3,0x7b,0x94,0xa3,0x77,0x8b,0x76, +0x6c,0x7a,0x84,0x77,0x3c,0x87,0x7c,0x75,0x84,0x89,0x64,0x6a,0x63,0x82,0x83,0x75, +0x91,0x7a,0x49,0x6b,0x8a,0x67,0x7a,0x87,0x9c,0x31,0x10,0x74,0x66,0x88,0x50,0x00, +0x71,0x97,0x02,0xa4,0x24,0x79,0x4a,0x56,0x82,0x83,0x83,0x59,0xa4,0x8e,0xbb,0x7b, +0x6b,0x72,0xab,0x4a,0x7c,0x62,0x91,0x45,0xc9,0x78,0x8a,0x84,0x91,0x9a,0xb8,0x38, +0x9c,0x31,0x10,0x66,0x67,0x89,0x50,0x00,0xb3,0x35,0xd3,0x88,0xac,0xa9,0xcb,0x76, +0x73,0xb7,0x8d,0x97,0x44,0x96,0x45,0x69,0x55,0x26,0x44,0x87,0x53,0x58,0x9b,0x56, +0xbb,0x56,0xcb,0xa8,0x9b,0x9b,0x9b,0x86,0x9c,0x31,0x10,0xfb,0x66,0x89,0x50,0x00, +0xcb,0x39,0x91,0x63,0xa2,0x98,0x99,0xb7,0x9a,0xa7,0x7b,0x52,0x81,0x59,0x8b,0x5a, +0x3b,0xba,0x45,0x77,0x64,0xb3,0x63,0x75,0x84,0x78,0x44,0x7a,0xa3,0x48,0x33,0x75, +0x9c,0x31,0x10,0xe5,0x76,0x88,0x40,0x00,0x8b,0x53,0x8a,0x66,0x83,0xc9,0x64,0x8c, +0x84,0x36,0xa4,0x70,0xbe,0x7b,0xb4,0x95,0x7d,0x87,0x4d,0x68,0x5c,0x63,0x79,0x78, +0x8b,0xa7,0xa2,0x89,0xca,0x4e,0x5b,0x55,0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00, +0x76,0xe1,0x72,0xda,0x76,0xdd,0x85,0x23,0x92,0xea,0x8c,0xd2,0x75,0x21,0x5f,0x1b, +0x5b,0x5d,0x7f,0x0c,0xae,0xd2,0xbc,0xe2,0x8e,0xda,0x56,0xe4,0x3a,0x9d,0x5c,0xda, +0x9c,0x31,0x10,0xa4,0xc7,0x87,0x40,0x00,0x9c,0xd4,0xbe,0xe5,0xb3,0x25,0x88,0x9a, +0x5d,0x5a,0x36,0xe5,0x4c,0xdc,0x90,0xcd,0xc0,0x9e,0xbd,0x22,0x90,0xe1,0x5b,0x58, +0x2e,0x60,0x40,0xec,0x8c,0xd6,0xc8,0xd6,0x9c,0x31,0x10,0x8f,0xc7,0x87,0x30,0x00, +0xc5,0x1c,0x92,0xa1,0x5b,0x21,0x2e,0x1d,0x38,0xac,0x8a,0x99,0xcc,0xd5,0xc8,0xdd, +0x94,0xa2,0x59,0x21,0x26,0x59,0x3c,0xac,0x92,0xa1,0xd0,0xd9,0xc6,0xdd,0x90,0x99, +0x9c,0x31,0x10,0x09,0xc7,0x88,0x30,0x00,0x57,0x1b,0x20,0x5b,0x3c,0xa9,0x9c,0x9b, +0xd8,0xcc,0xc2,0x94,0x86,0xa2,0x4d,0x23,0x18,0x65,0x46,0xa2,0xb0,0x9a,0xe3,0x13, +0xb8,0xdc,0x78,0xe3,0x41,0x1a,0x19,0x6d,0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00, +0x5a,0xdc,0xc2,0xd2,0xe2,0xd2,0xa8,0xe4,0x6d,0x24,0x36,0xe2,0x1d,0x59,0x6e,0xd4, +0xce,0xd5,0xda,0xda,0x9a,0xe2,0x67,0x23,0x2a,0x9d,0x25,0x4b,0x86,0xd1,0xdb,0x1c, +0x9c,0x31,0x10,0xe7,0xc8,0x87,0x30,0x00,0xce,0xcd,0x8a,0xcd,0x5b,0x09,0x20,0x64, +0x38,0xea,0x9e,0xcd,0xdf,0x2d,0xc0,0xc9,0x82,0xe9,0x52,0xe9,0x22,0xcd,0x4e,0x8c, +0xa6,0xad,0xd3,0x0d,0xaa,0xed,0x7b,0x2d,0x9c,0x31,0x10,0x1e,0xb7,0x66,0x10,0x00, +0x44,0x9b,0x17,0x6d,0x38,0x1a,0x78,0x94,0xa8,0xd3,0x99,0x1b,0x8b,0x1b,0x86,0xdb, +0x7a,0xdb,0x60,0xdb,0x56,0xdb,0x6a,0xdb,0x88,0xdb,0xa4,0xdb,0xb6,0xdb,0xa8,0xdb, +0x9c,0x31,0x10,0xa7,0xa3,0x22,0x00,0x00,0x91,0x85,0x4d,0x24,0x32,0x4c,0x4f,0x55, +0x8c,0x6d,0xc1,0xad,0xc4,0xa9,0x9f,0x81,0x6d,0x05,0x48,0x74,0x43,0x59,0x66,0x51, +0x95,0x51,0xac,0x81,0xa8,0x89,0x8e,0x75,0x9c,0x31,0x10,0xc8,0x93,0x22,0x00,0x00, +0x58,0xaa,0x2e,0xe3,0x36,0x9a,0x66,0x9c,0x9d,0x23,0xbf,0x22,0xbb,0x2d,0x94,0xda, +0x67,0x62,0x4c,0x9b,0x50,0xa5,0x74,0x6c,0x9a,0xf1,0xad,0x53,0xa0,0xdb,0x89,0x5a, +0x9c,0x31,0x10,0x70,0x82,0x22,0x00,0x00,0x58,0x5b,0x37,0x23,0x4c,0x63,0x7e,0xdc, +0xa1,0x02,0xaf,0x1b,0xa9,0x64,0x83,0x61,0x63,0x9c,0x63,0x0c,0x6e,0x93,0x78,0x12, +0x8c,0xda,0x9f,0x6c,0x90,0xe3,0x84,0x9b,0x9c,0x31,0x10,0x21,0x61,0x22,0x00,0x00, +0x89,0x54,0x61,0x52,0x30,0x93,0x5c,0x1c,0x92,0xe4,0x9e,0x92,0xba,0x9a,0xce,0x53, +0x8f,0x1d,0x35,0x1a,0x2c,0x9b,0x4a,0xec,0x7c,0xe3,0xc7,0x92,0xda,0x91,0x8f,0x63, +0x9c,0x31,0x10,0x3f,0x62,0x11,0x00,0x00,0x47,0x4e,0x41,0x36,0x5b,0x0d,0x88,0xc8, +0xc2,0xc6,0xc8,0x89,0x8f,0x29,0x5f,0x14,0x63,0x0d,0x74,0xf1,0x91,0x36,0xa8,0xc8, +0xa6,0xb5,0x82,0xf1,0x67,0x45,0x6c,0x70,0x9c,0x31,0x10,0xe7,0x41,0x21,0x00,0x00, +0x4d,0x5c,0xa6,0x39,0xc6,0x54,0xad,0x56,0x98,0x42,0x91,0x31,0x3e,0xb9,0x0e,0x3d, +0x4e,0x1c,0xb8,0x1b,0xe1,0x43,0xd1,0x32,0xc1,0x2b,0x76,0x2b,0x09,0xd5,0x5a,0x11, +0x9c,0x31,0x10,0x08,0x96,0x66,0x20,0x00,0x81,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb, +0x79,0xdb,0x79,0xdb,0x7d,0xdb,0x81,0xdb,0x81,0xdb,0x81,0xdb,0x81,0xdb,0x81,0xdb, +0x96,0x1a,0xaa,0x1b,0xc2,0xeb,0xc2,0xc5,0x9c,0x31,0x10,0xfa,0xa7,0x66,0x20,0x00, +0xb3,0x09,0xba,0x1c,0xce,0x33,0xba,0x73,0x84,0xe1,0x5e,0xe3,0x5c,0x8b,0x59,0x49, +0x56,0xd5,0x58,0xe2,0x62,0xd3,0x41,0x12,0x20,0x9c,0x44,0x8d,0x3c,0xd9,0x2e,0xdd, +0x9c,0x31,0x10,0x6c,0xca,0x97,0x20,0x00,0x72,0xed,0x6a,0xed,0x50,0xed,0x4e,0xcd, +0x9d,0x0d,0xba,0xad,0x9c,0xed,0x6a,0xcd,0x25,0x11,0x6f,0xb5,0xdc,0x91,0x8a,0xb0, +0xe6,0x92,0x8a,0x91,0x28,0xec,0x56,0x8e,0x9c,0x31,0x10,0xe9,0xcb,0x87,0x20,0x00, +0xb2,0x88,0x76,0xc5,0xd4,0xe6,0x9a,0xc5,0x75,0x01,0x1e,0xca,0x75,0x88,0x9c,0xc8, +0x85,0x4e,0xd2,0xd1,0x79,0x10,0x6a,0xd2,0x0e,0x89,0xae,0xe9,0x70,0xa5,0xb7,0x45, +0x9c,0x31,0x10,0x6f,0xcb,0x88,0x20,0x00,0xad,0x4b,0x7a,0x8b,0x41,0x8b,0x36,0x9c, +0xb5,0x21,0x61,0xdb,0xd9,0x9d,0x7d,0x92,0x86,0x1b,0x15,0x64,0x7f,0x1a,0x89,0x1b, +0x8a,0xe4,0xc5,0x22,0x72,0x5a,0x81,0x54,0x9c,0x31,0x10,0xe9,0xcb,0x87,0x20,0x00, +0x04,0xa5,0xb1,0x41,0x64,0xc0,0xbd,0x85,0x9e,0x89,0x8d,0x6d,0x52,0xc5,0x24,0xe4, +0xb6,0x89,0x5a,0xe6,0xd6,0xe5,0x80,0xc4,0x9b,0x05,0x28,0xe9,0x55,0x32,0x9e,0x70, +0x9c,0x31,0x10,0x77,0xcb,0x98,0x20,0x00,0x76,0x61,0xcd,0x1c,0x7a,0x23,0x95,0xe2, +0x1e,0x23,0x66,0xb4,0x90,0xac,0x7e,0x69,0xc4,0xec,0x7e,0x25,0x89,0xa2,0x19,0xe2, +0x7f,0x6c,0x85,0x24,0x96,0xe2,0xb4,0xe3,0x9c,0x31,0x10,0xe9,0xcb,0x87,0x20,0x00, +0x85,0x59,0x84,0xd0,0x1a,0xf1,0x81,0x94,0x7e,0xb2,0x9d,0x75,0xb0,0x94,0x89,0x31, +0x80,0xce,0x1a,0xf1,0x85,0xac,0x7c,0xb1,0xa3,0x92,0xac,0xb0,0x8f,0x29,0x7c,0xca, +0x9c,0x31,0x10,0x77,0xcb,0x98,0x20,0x00,0x1d,0x9a,0x7f,0x5a,0x7d,0x5d,0x9a,0xdb, +0xad,0x22,0x8a,0x64,0x81,0x9b,0x22,0x21,0x73,0x64,0x85,0x25,0x8e,0xe2,0xb5,0x22, +0x8a,0xa4,0x89,0xa3,0x2e,0x63,0x5a,0xed,0x9c,0x31,0x10,0xae,0xcb,0x88,0x10,0x00, +0x95,0x32,0x7e,0xaa,0xc1,0x2d,0x86,0xab,0x95,0xab,0x46,0x9c,0x35,0x9b,0xa1,0x22, +0x66,0x24,0xc9,0x5b,0x86,0x5a,0x9d,0x9c,0x5e,0x22,0x20,0xcc,0x96,0x94,0x69,0x59, +0x9c,0x31,0x10,0xe9,0xcb,0x87,0x20,0x00,0xb7,0x29,0x96,0xca,0x9c,0xe9,0x7e,0xe9, +0x2e,0xd0,0x63,0x72,0x8a,0x71,0x85,0x55,0xb8,0x95,0x8d,0x51,0x98,0xd9,0x5b,0x31, +0x26,0xa9,0x9b,0x0e,0x62,0xec,0xbf,0x0d,0x9c,0x31,0x10,0x6f,0xcb,0x88,0x20,0x00, +0x91,0xdb,0xa1,0x93,0x7d,0xd4,0x39,0xa3,0x4e,0x9b,0x90,0xe2,0x76,0x64,0xc1,0x23, +0x8a,0x63,0x9d,0xac,0x6e,0x32,0x21,0x62,0x7a,0xea,0x75,0x25,0x9a,0xaa,0xad,0x2b, +0x9c,0x31,0x10,0x6c,0xca,0x97,0x20,0x00,0x91,0x71,0x98,0xf5,0x63,0x2d,0x1e,0x8a, +0x8d,0x88,0x6a,0xa9,0xb3,0x8a,0x9e,0xa8,0x9b,0x29,0x8f,0x09,0x5d,0x05,0x20,0xaa, +0x8f,0x49,0x6a,0xc8,0xb5,0x2a,0x9c,0xcd,0x9c,0x31,0x10,0xea,0xca,0x98,0x20,0x00, +0x9d,0xda,0x8e,0x1b,0x5e,0x14,0x21,0x55,0x87,0x09,0x6d,0x8a,0xaa,0xd5,0xa1,0x53, +0x96,0x52,0x96,0x1c,0x66,0x5c,0x1d,0x91,0x7b,0x9a,0x74,0xd6,0x9f,0x1b,0xac,0xda, +0x9c,0x31,0x10,0xea,0xca,0x98,0x20,0x00,0x96,0x9b,0x99,0xe4,0x76,0x5a,0x29,0xa3, +0x56,0xdd,0x84,0x61,0x83,0x1b,0xb8,0xa3,0x92,0x9b,0x9c,0xda,0x85,0xd4,0x49,0x59, +0x29,0x5c,0x8e,0x4d,0x6d,0x91,0xb6,0x52,0x9c,0x31,0x10,0xea,0xca,0x98,0x20,0x00, +0x9d,0x9b,0x9e,0x1b,0x92,0x23,0x6e,0x63,0x2a,0x21,0x5a,0xe6,0x88,0xa9,0x82,0xa2, +0xb9,0x24,0x92,0x5c,0xa1,0x5b,0x85,0xd3,0x55,0xd3,0x25,0x9c,0x7b,0x58,0x79,0x15, +0x9c,0x31,0x10,0x46,0xca,0x88,0x30,0x00,0x9e,0xdc,0xa8,0xd3,0x96,0x93,0x9d,0x4b, +0x7d,0xdc,0x49,0x9a,0x2d,0x25,0x82,0x8c,0x75,0x50,0xaa,0x93,0xa1,0x54,0x9a,0x5b, +0x99,0x92,0x81,0xdc,0x49,0x9b,0x2d,0x2c,0x9c,0x31,0x10,0xf2,0xca,0x88,0x20,0x00, +0x86,0x8b,0x75,0x4a,0xa2,0x93,0xa1,0x14,0x96,0x5b,0x9d,0x53,0x81,0xdc,0x55,0xda, +0x29,0x74,0x7b,0x29,0x7d,0x1c,0x96,0xd3,0xad,0x13,0x92,0x92,0xa1,0x54,0x8a,0x0b, +0x9c,0x31,0x10,0xf2,0xca,0x88,0x20,0x00,0x61,0xd3,0x2d,0xd2,0x5a,0xb5,0x8c,0xeb, +0x7e,0x69,0xb9,0x63,0x8e,0x64,0xa5,0xdb,0x92,0x24,0x6d,0xda,0x3e,0x1b,0x31,0x09, +0x92,0x46,0x75,0x5b,0xaa,0xa2,0xa1,0x23,0x9c,0x31,0x10,0x5e,0xca,0x98,0x30,0x00, +0x96,0x5b,0xa1,0x5b,0x86,0x13,0x5d,0x9b,0x2a,0x1a,0x56,0xad,0x91,0x2b,0x76,0x59, +0xb9,0x9b,0x8d,0xdc,0xa6,0x1b,0x91,0x92,0x7d,0x9c,0x4d,0xe3,0x29,0x6b,0x6b,0x20, +0x9c,0x31,0x10,0xea,0xca,0x98,0x20,0x00,0x91,0x55,0x7e,0x94,0xb5,0x52,0x86,0x1a, +0xa9,0xdc,0x91,0xda,0x79,0xa3,0x51,0xe3,0x25,0x64,0x6f,0x20,0x91,0x0d,0x7a,0x8c, +0xb9,0x53,0x85,0xda,0xaa,0x1b,0x91,0x9b,0x9c,0x31,0x10,0xe4,0xc9,0x98,0x30,0x00, +0x80,0xd3,0x5a,0xe3,0x2a,0xda,0x51,0x6e,0x9e,0x63,0x6f,0x11,0xb6,0xd3,0x94,0x9c, +0x9d,0x5b,0xa4,0x9a,0x81,0x64,0x6e,0xd3,0x3d,0x12,0x2a,0x12,0x99,0x5e,0x7c,0x63, +0x9c,0x31,0x10,0xe4,0xc9,0x98,0x30,0x00,0x8f,0x62,0xb2,0x5a,0x89,0x13,0xac,0xdb, +0x92,0x9c,0x7c,0xd3,0x60,0xdb,0x2a,0xdb,0x45,0x6e,0xaa,0xa0,0x6e,0xd2,0xa9,0x14, +0xa2,0x9b,0x89,0x1b,0xac,0x9c,0x88,0xdb,0x9c,0x31,0x10,0xdf,0xc9,0x99,0x20,0x00, +0x7c,0xa3,0x58,0xe3,0x22,0x9b,0x57,0xa3,0xaa,0x8c,0x6b,0x12,0xae,0xe2,0xa4,0xa4, +0x8b,0x1b,0xac,0x9b,0x86,0xdb,0x74,0xe3,0x58,0xe3,0x22,0x9a,0x5d,0x9a,0xaa,0x8d, +0x9c,0x31,0x10,0xd6,0xc9,0x97,0x20,0x00,0x6f,0x0c,0xa7,0x10,0xa4,0xad,0x89,0x2d, +0xa6,0xed,0x90,0xce,0x74,0xe9,0x5a,0xf0,0x28,0xf1,0x49,0x92,0xb2,0xc2,0x78,0xe8, +0x8f,0x12,0xb0,0xd1,0x8b,0x0d,0x9d,0x0d,0x9c,0x31,0x10,0xe4,0xc9,0x98,0x30,0x00, +0x9e,0xdb,0x7a,0xdb,0x5e,0xdc,0x37,0x23,0x2e,0xe3,0x9e,0xe8,0x92,0x96,0x7a,0xd2, +0xaa,0xe2,0x9c,0xdc,0x8e,0xd3,0xa0,0xdb,0x8c,0xe3,0x6e,0xe3,0x4a,0xd4,0x24,0x5c, +0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00,0x6b,0x8a,0xb0,0x69,0x7b,0x25,0x88,0xd2, +0xaa,0xdb,0x96,0xe3,0x8f,0x1b,0x9a,0x92,0x83,0x1b,0x60,0xd4,0x3f,0x9a,0x30,0x5b, +0x90,0xea,0xa6,0x8e,0x76,0xda,0x8e,0xe3,0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00, +0xa8,0xdb,0x96,0xdb,0x8e,0xdb,0x96,0x9b,0x82,0xdb,0x54,0xdb,0x30,0xdb,0x43,0x65, +0xa6,0xcb,0x9a,0xe1,0x74,0xe4,0x90,0xd3,0xac,0xda,0x98,0xdc,0x8a,0xdb,0x92,0xdb, +0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00,0x82,0xdb,0x4e,0xdb,0x28,0xa3,0x51,0x52, +0xac,0xd5,0x9a,0xea,0x74,0xd3,0x8e,0xdb,0xae,0xe3,0x9a,0xdb,0x84,0xdb,0x8c,0xdb, +0x82,0xdb,0x4e,0xd3,0x22,0x63,0x51,0x49,0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00, +0xb0,0xe5,0xa2,0xdb,0x72,0xd3,0x82,0xe3,0xae,0xdb,0xa2,0xdb,0x82,0xdb,0x84,0xdb, +0x84,0xdb,0x56,0xdb,0x24,0x5c,0x49,0x49,0xae,0xec,0xae,0xd3,0x74,0xd2,0x74,0xe3, +0x9c,0x31,0x10,0xa5,0xc7,0x98,0x20,0x00,0xa8,0xd3,0xb2,0xda,0x8a,0xdb,0x77,0x1c, +0x7e,0xda,0x63,0x13,0x2a,0x1c,0x3d,0x48,0xa0,0xac,0xbd,0x14,0x84,0xda,0x68,0xdb, +0x98,0xdc,0xba,0xda,0x98,0xdb,0x73,0x1b,0x9c,0x31,0x10,0xa5,0xc7,0x98,0x20,0x00, +0x70,0x9b,0x67,0x1b,0x3a,0x5c,0x3b,0x48,0x8e,0xac,0xbf,0x14,0x9a,0xda,0x6e,0xdb, +0x86,0xdc,0xb2,0xda,0xa6,0x9b,0x7a,0xdc,0x64,0xda,0x5b,0x1b,0x3e,0x5c,0x43,0x12, +0x9c,0x31,0x10,0x46,0xb7,0x88,0x20,0x00,0x8d,0xe1,0xee,0x15,0xc1,0xda,0x71,0xab, +0x85,0xc4,0xd5,0xb3,0xd5,0xbb,0x81,0xbb,0x41,0x3b,0x22,0x3b,0x00,0xb3,0x1a,0x3c, +0x8d,0xc8,0xe1,0xa5,0xc1,0xca,0x81,0xab,0x9c,0x31,0x10,0xa8,0xc6,0x78,0x20,0x00, +0x84,0xe3,0xa5,0x1b,0xa8,0xda,0x88,0xe4,0x64,0x93,0x4f,0x23,0x3c,0x13,0x4d,0x24, +0x84,0xa0,0xac,0xcd,0xa4,0xe2,0x84,0xd3,0x84,0xe3,0xa0,0xcc,0xa6,0xea,0x8a,0xd3, +0x9c,0x31,0x10,0x53,0xb6,0x78,0x20,0x00,0x4d,0x37,0x1e,0x37,0x00,0x17,0x1e,0x5a, +0x85,0x22,0xd2,0x3b,0xc9,0xb5,0x91,0xb9,0x89,0xb5,0xb5,0xb9,0xc5,0xc7,0x95,0xa6, +0x4d,0x36,0x1e,0x38,0x00,0xb8,0x26,0x39,0x9c,0x31,0x10,0x77,0xb5,0x67,0x20,0x00, +0x84,0xa0,0xce,0xd5,0xcc,0xe2,0x9c,0xdc,0x93,0x22,0xb0,0xdc,0xbb,0x1a,0x94,0xdb, +0x56,0x93,0x25,0x23,0x0a,0x03,0x27,0x35,0x7c,0x90,0xc7,0x25,0xd2,0xd1,0xaa,0xa4, +0x9c,0x31,0x10,0xb6,0xb5,0x67,0x10,0x00,0x9a,0xd2,0xa8,0xe4,0xae,0xd1,0x8c,0xe5, +0x52,0xd2,0x27,0x24,0x12,0x42,0x2e,0xf5,0x78,0x81,0xc0,0xec,0xce,0xcb,0xb2,0xeb, +0xa0,0xd2,0xa2,0xe4,0x9a,0xd2,0x7a,0xe3,0x9c,0x31,0x10,0xcc,0xb3,0x56,0x00,0x00, +0x4e,0x97,0x2a,0xc6,0x1e,0xb7,0x42,0xc4,0x88,0xad,0xc2,0xc4,0xcc,0xa8,0xb4,0xb5, +0xa2,0xba,0x96,0xb5,0x86,0xb8,0x68,0xb5,0x46,0xb9,0x2e,0xb6,0x35,0x4a,0x60,0x95, +0x9c,0x31,0x10,0xc5,0xb2,0x45,0x00,0x00,0x9c,0xb3,0xc3,0x13,0xc2,0x65,0xad,0x52, +0x9b,0x1a,0x8c,0x9b,0x76,0x64,0x55,0x92,0x38,0x63,0x34,0x13,0x54,0x24,0x88,0x52, +0xb2,0x9c,0xbf,0x1b,0xb5,0x1b,0xa4,0x5a,0x9c,0x31,0x10,0xc5,0xb2,0x45,0x00,0x00, +0x92,0x5b,0x7c,0x9a,0x60,0x1b,0x44,0x5b,0x3c,0x5a,0x51,0x5e,0x7b,0x99,0xa1,0x24, +0xb4,0x92,0xb5,0x2b,0xac,0x4d,0x99,0x69,0x7c,0x14,0x5a,0x62,0x41,0x54,0x3e,0x6b, +0x9c,0x31,0x10,0xe0,0xa2,0x45,0x00,0x00,0x29,0x4b,0x73,0x6b,0xbc,0x4b,0xeb,0x1b, +0xf8,0x53,0xe3,0x63,0xad,0x54,0x60,0x59,0x1f,0x1c,0x05,0x1a,0x16,0x5c,0x44,0x62, +0x81,0x4b,0xbe,0x6b,0xea,0x53,0xef,0x62,0x9c,0x31,0x10,0x0a,0xa1,0x25,0x00,0x00, +0xca,0x44,0x8a,0x62,0x4d,0x14,0x27,0x8b,0x20,0xb3,0x39,0x4b,0x65,0x8b,0x96,0x52, +0xbe,0x5d,0xd3,0x03,0xce,0x73,0xaf,0x0b,0x7e,0xa3,0x51,0xa3,0x39,0x93,0x3c,0x5c, +0x9c,0x31,0x10,0x60,0x91,0x23,0x00,0x00,0x2b,0x22,0x70,0xa2,0xb2,0x2b,0xdc,0x5d, +0xe9,0x52,0xd8,0x5a,0xaa,0x93,0x6e,0x4d,0x3a,0xaa,0x26,0xa3,0x35,0x62,0x5a,0x0b, +0x86,0xa3,0xaa,0x9d,0xbc,0x5a,0xb6,0x53,0x9c,0x31,0x10,0xff,0x82,0x23,0x00,0x00, +0xb9,0xa4,0x76,0xdb,0x44,0xd1,0x2e,0xac,0x3a,0xcc,0x5a,0xe2,0x84,0xe2,0xae,0x95, +0xc2,0x98,0xb4,0xe4,0x92,0x93,0x75,0x2b,0x5f,0x1b,0x57,0x1a,0x64,0xf4,0x7a,0xd3, +0x9c,0x31,0x10,0x0c,0x62,0x33,0x00,0x00,0xbe,0xe2,0xde,0xd5,0xc8,0xda,0xb4,0x9c, +0x72,0xd1,0x2e,0xa4,0x14,0x4c,0x38,0x63,0x82,0xdc,0xbc,0xa0,0xdb,0x15,0xd4,0xda, +0xb3,0x14,0x83,0x1a,0x57,0x5c,0x42,0x5a,0x9c,0x31,0x10,0xfd,0x53,0x31,0x00,0x00, +0x22,0x9d,0x22,0x61,0x41,0x9a,0x8d,0xa4,0xb9,0x98,0xb9,0x99,0x9d,0x60,0x61,0x9e, +0x25,0xdd,0x09,0x9a,0x36,0x14,0x5a,0x21,0x61,0xa0,0x93,0xae,0x8d,0x59,0x81,0xdc, +0x9c,0x31,0x10,0xb3,0x62,0x12,0x00,0x00,0x8c,0x82,0x77,0xb2,0x51,0x02,0x2e,0xf4, +0x42,0xcd,0x50,0xaa,0x62,0x93,0x68,0xcc,0x70,0x92,0x7d,0x12,0x80,0xeb,0x84,0xe3, +0x84,0xcb,0x81,0x0b,0x7c,0xf2,0x7d,0x05,0x9c,0x31,0x10,0x4e,0x51,0x22,0x00,0x00, +0x96,0xba,0xb7,0x33,0xc8,0x26,0xd1,0xe2,0xd9,0xc4,0xe9,0xca,0xe5,0x23,0xcd,0xcb, +0xc2,0xcc,0xa6,0xea,0x81,0x44,0x7a,0x2a,0x87,0x3c,0x96,0x4a,0x94,0xc3,0x94,0x24, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_PAIRING_SUCCESS.txt b/config/_default_cfg_src_/res/cn/SOUND_PAIRING_SUCCESS.txt new file mode 100644 index 0000000..543cdfe --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_PAIRING_SUCCESS.txt @@ -0,0 +1,285 @@ +0x9c,0x31,0x10,0x8e,0x32,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x75,0xdb,0x72,0x1b, +0x41,0x9c,0x39,0x9e,0x79,0xc1,0x6d,0xda,0x79,0xd6,0x75,0x12,0x77,0x2a,0xa9,0x92, +0xa2,0x13,0xa1,0x5a,0x9d,0x5c,0xb6,0x19,0x9c,0x31,0x10,0xa6,0x32,0x21,0x00,0x00, +0xcc,0xb3,0x94,0xab,0x7b,0x5a,0x8a,0x43,0x92,0x3d,0x8b,0xb4,0x7c,0xc1,0x54,0x4a, +0x6b,0xc9,0x8b,0xd3,0x75,0xb6,0x8b,0xba,0x73,0x43,0x7d,0x3c,0x6a,0xab,0x5c,0xbb, +0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00,0x76,0x60,0x69,0xa6,0x6a,0x66,0x7c,0xa5, +0xaa,0x5c,0xcd,0x99,0x8b,0x68,0x8a,0x0d,0x75,0x19,0x71,0xd9,0x5d,0x61,0x6a,0x58, +0x3d,0xda,0x72,0xdd,0xa9,0x65,0x6a,0x5e,0x9c,0x31,0x10,0x26,0xb7,0x65,0x00,0x00, +0x7e,0xed,0x83,0x0d,0x8a,0xb2,0xa7,0x04,0xc1,0x0d,0xae,0xb6,0xa6,0xc4,0xb8,0x2d, +0xbc,0xce,0x9a,0x89,0x83,0x31,0x7b,0x51,0x61,0x0c,0x45,0x69,0x3d,0x11,0x3a,0xad, +0x9c,0x31,0x10,0x6e,0xb8,0x76,0x10,0x00,0x39,0xdb,0x3d,0xa3,0x41,0x92,0x4d,0x53, +0x51,0xd3,0x5a,0x4a,0x5e,0x15,0x71,0x9a,0x6e,0x1a,0x79,0x94,0x6d,0xdb,0x7e,0x19, +0x7e,0x26,0x7e,0xeb,0x82,0xdc,0x86,0x29,0x9c,0x31,0x10,0xa0,0x97,0x98,0x30,0x00, +0xa1,0x96,0xc6,0x8a,0xcc,0x55,0xb4,0x67,0xdc,0x79,0xa4,0x87,0xbd,0x85,0x8c,0x86, +0x9a,0x57,0x6b,0x46,0x94,0x4c,0x7a,0x52,0x90,0x87,0x86,0xcb,0x92,0x96,0xa4,0x46, +0x9c,0x31,0x10,0xf5,0x88,0x88,0x30,0x00,0xb1,0x9b,0xcc,0xc4,0xf3,0xaa,0xc3,0xb2, +0xf3,0xdc,0xc9,0xc9,0xcc,0x3b,0xab,0x35,0xcc,0x09,0xa4,0x23,0xa2,0xac,0xac,0x1b, +0xb2,0xcb,0x83,0xb3,0x93,0x22,0xaa,0xc5,0x9c,0x31,0x10,0xe7,0x77,0x88,0x20,0x00, +0x60,0x79,0xdc,0x93,0x72,0x98,0xdb,0xab,0x2e,0x72,0xda,0x17,0x90,0x7a,0x84,0xb8, +0xbb,0xa6,0x2e,0xa5,0x56,0x77,0x83,0x08,0xed,0x24,0x5c,0xca,0x7d,0xd9,0x5b,0x33, +0x9c,0x31,0x10,0x93,0x97,0x88,0x40,0x00,0x7b,0x45,0x6b,0x47,0x9c,0xa8,0x94,0x6a, +0x86,0x28,0x4b,0xa3,0x63,0x78,0x92,0x64,0xb2,0x27,0xae,0x7c,0x8c,0x86,0x22,0xa4, +0x2c,0x4a,0x8a,0x58,0xda,0xa6,0xed,0x46,0x9c,0x31,0x10,0xf2,0xb7,0x88,0x30,0x00, +0x70,0xb4,0x53,0x6b,0x55,0x32,0x8e,0xa3,0xb8,0xcb,0xb3,0x33,0x65,0xd5,0x36,0x2a, +0x40,0x91,0x92,0xf6,0xd9,0xc2,0xc3,0x11,0x5d,0x43,0x21,0x9d,0x24,0xe3,0xa3,0x22, +0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00,0xba,0x93,0x9f,0x2c,0x6b,0x1a,0x4e,0xcc, +0x4e,0x4b,0x99,0x24,0xc4,0xa9,0x9f,0x14,0x62,0xca,0x44,0xec,0x46,0xa4,0x9d,0x1b, +0xca,0xa3,0xa5,0x1b,0x62,0xd3,0x3c,0xdc,0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00, +0x42,0xac,0x9c,0xa0,0xce,0x84,0xaf,0x64,0x62,0xed,0x3a,0x8a,0x3e,0xaa,0x98,0x9a, +0xcf,0x55,0xb7,0x14,0x68,0xa1,0x37,0x2b,0x30,0xcc,0x95,0x19,0xd2,0xe4,0xc0,0xdb, +0x9c,0x31,0x10,0x6b,0xc9,0x99,0x30,0x00,0x70,0x93,0x35,0x23,0x28,0xf4,0x89,0x02, +0xd0,0x9a,0xca,0xe4,0x82,0xdb,0x3b,0x1a,0x1e,0xa4,0x72,0xd9,0xca,0x93,0xd1,0x1b, +0x98,0xdb,0x4b,0x1a,0x1a,0x52,0x52,0xec,0x9c,0x31,0x10,0x5a,0xc8,0x89,0x20,0x00, +0xbe,0x84,0xd7,0x21,0xaa,0x93,0x5e,0xa4,0x24,0x53,0x35,0x53,0xa0,0xea,0xd8,0xcb, +0xbe,0xeb,0x7a,0xd3,0x35,0x5b,0x1b,0x23,0x76,0xcc,0xd0,0xe2,0xd0,0xdb,0x98,0xd4, +0x9c,0x31,0x10,0x14,0xc8,0x88,0x10,0x00,0x54,0xe2,0x1e,0x5b,0x42,0xea,0xaa,0xcc, +0xda,0xd9,0xb8,0xdc,0x76,0xdb,0x34,0xe4,0x1d,0x11,0x72,0xdd,0xcf,0x1a,0xd6,0xe3, +0x9a,0xd3,0x5a,0xe3,0x22,0x52,0x37,0x2c,0x9c,0x31,0x10,0x32,0xc7,0x89,0x20,0x00, +0x98,0x93,0xdd,0x2b,0xc4,0xcb,0x84,0xe3,0x49,0x53,0x1c,0xec,0x4e,0xca,0xb4,0xab, +0xde,0xd3,0xb2,0xe3,0x74,0xd3,0x3a,0xe4,0x1d,0x59,0x64,0x9c,0xc5,0x1b,0xdc,0x9a, +0x9c,0x31,0x10,0x7c,0xc7,0x88,0x10,0x00,0xa4,0xdb,0x6a,0xd4,0x34,0x5b,0x25,0x8a, +0x6e,0xf2,0xcb,0x15,0xda,0x9b,0xa0,0x9a,0x68,0xdc,0x30,0x53,0x23,0x5c,0x70,0xe2, +0xcb,0x14,0xda,0xa3,0xa2,0xd3,0x6d,0x1b,0x9c,0x31,0x10,0xba,0xc7,0x79,0x20,0x00, +0x32,0x53,0x1f,0x5c,0x68,0xa1,0xc5,0x0c,0xde,0xa3,0xac,0xd2,0x76,0xdb,0x3a,0x94, +0x19,0x4a,0x54,0xf3,0xb9,0x0c,0xe4,0xe2,0xba,0xdb,0x81,0x1b,0x46,0xe3,0x17,0x02, +0x9c,0x31,0x10,0x32,0xc7,0x89,0x20,0x00,0x40,0xdd,0xa4,0xd2,0xe4,0xe3,0xc8,0xdc, +0x8f,0x23,0x57,0x12,0x18,0xf4,0x2c,0xca,0x88,0xab,0xdb,0x14,0xd8,0xe2,0xa0,0xd3, +0x6a,0xdb,0x28,0x52,0x1a,0xeb,0x64,0x8c,0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00, +0xc5,0x21,0xe4,0x94,0xb8,0xa2,0x80,0xd3,0x3c,0xa4,0x13,0x81,0x42,0xeb,0xa4,0xd5, +0xe4,0xe2,0xce,0xdb,0x97,0x1c,0x59,0x5a,0x1a,0xed,0x24,0xc9,0x78,0xab,0xd1,0x14, +0x9c,0x31,0x10,0x5b,0xc6,0x77,0x00,0x00,0xde,0xe2,0xb0,0xd3,0x76,0xa4,0x32,0x01, +0x1b,0x36,0x50,0xd1,0xa7,0x13,0xd2,0xa3,0xbe,0xdb,0x8e,0xd3,0x5f,0x23,0x3d,0x5a, +0x42,0x8c,0x6a,0xe3,0x95,0x23,0xa6,0x9b,0x9c,0x31,0x10,0x3b,0xb4,0x54,0x00,0x00, +0xd7,0x85,0xca,0x21,0x9a,0xe4,0x59,0x53,0x2d,0x1b,0x39,0x1c,0x6e,0x9a,0xa8,0xdc, +0xcc,0xdb,0xc8,0xdb,0xa0,0xdc,0x61,0x1a,0x32,0x9a,0x34,0xdb,0x5e,0xdb,0x95,0x1b, +0x9c,0x31,0x10,0x90,0xb2,0x23,0x00,0x00,0xb9,0x76,0xbf,0x51,0x9e,0x28,0x69,0x92, +0x47,0xac,0x46,0x31,0x62,0x7a,0x8b,0x4c,0xaa,0x85,0xac,0xce,0x92,0x8d,0x71,0x95, +0x5c,0x45,0x5b,0x71,0x6d,0x8c,0x88,0x52,0x9c,0x31,0x10,0x55,0x92,0x22,0x00,0x00, +0xf2,0x59,0xf0,0xe3,0xb5,0x24,0x66,0xdb,0x2d,0x62,0x22,0x94,0x4b,0x13,0x91,0x0c, +0xc0,0xa3,0xc3,0x5c,0x9e,0x91,0x6d,0x1e,0x49,0x1a,0x42,0x9d,0x62,0xaa,0x91,0x24, +0x9c,0x31,0x10,0x70,0x82,0x22,0x00,0x00,0xd0,0x9c,0xd2,0xb1,0xa8,0xd3,0x68,0x9b, +0x38,0x9b,0x41,0x1d,0x70,0x8a,0x98,0xd1,0xb4,0x66,0xb6,0xa9,0x8f,0x5c,0x61,0x14, +0x58,0xd3,0x6a,0xe2,0x7a,0xd4,0x8e,0xe2,0x9c,0x31,0x10,0x6a,0xb9,0xaa,0x60,0x00, +0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77, +0x7b,0x77,0x7b,0x77,0x7b,0x77,0x83,0x77,0x8b,0x78,0xa2,0x54,0xee,0xb4,0x9a,0x5b, +0x9c,0x31,0x10,0xe2,0xb7,0x89,0x50,0x00,0x61,0x24,0x72,0x33,0x8d,0x52,0x7a,0x34, +0x65,0x31,0x70,0x5b,0x66,0xac,0x61,0x1b,0x69,0xcb,0x55,0x24,0x31,0xab,0x39,0xca, +0x5a,0x5b,0x72,0x4c,0x76,0xba,0x76,0x3b,0x9c,0x31,0x10,0x57,0xd7,0x77,0x10,0x00, +0x7d,0x14,0x78,0xca,0x74,0xc3,0x7e,0xdc,0x90,0xf2,0x96,0xec,0x80,0xdc,0x5c,0xd9, +0x51,0x24,0x7a,0x8d,0xb7,0x18,0xc4,0x9b,0x92,0x9d,0x51,0x59,0x37,0x35,0x6c,0xa3, +0x9c,0x31,0x10,0x78,0xd8,0x78,0x20,0x00,0xb2,0xe9,0xc2,0xcc,0x9e,0xec,0x72,0xea, +0x52,0xb4,0x4b,0x82,0x77,0x02,0xab,0x2d,0xb4,0xca,0x94,0xea,0x73,0x0c,0x4e,0x62, +0x4d,0x44,0x7f,0x02,0xad,0x2b,0xae,0xcc,0x9c,0x31,0x10,0xfd,0xc7,0x76,0x10,0x00, +0x9a,0xc9,0x59,0x13,0x1a,0x02,0x2e,0xd4,0x90,0x95,0xdf,0x10,0xce,0x55,0x8c,0x94, +0x54,0xd1,0x18,0x0d,0x36,0x58,0x9e,0x55,0xe5,0x13,0xc6,0x91,0x82,0x94,0x4e,0xd3, +0x9c,0x31,0x10,0xfd,0xc7,0x76,0x10,0x00,0x16,0x5c,0x40,0x18,0xa8,0x5d,0xe4,0xd3, +0xbe,0x98,0x7e,0xde,0x48,0xda,0x14,0xec,0x48,0x24,0xb2,0x21,0xe4,0xa5,0xb4,0x5a, +0x78,0xa2,0x48,0xa4,0x16,0xed,0x50,0x23,0x9c,0x31,0x10,0x72,0xc7,0x77,0x10,0x00, +0xb6,0x22,0xe4,0xa4,0xae,0xa3,0x77,0x22,0x46,0xe3,0x17,0x33,0x52,0x64,0xba,0x61, +0xe2,0xe4,0xac,0xa4,0x76,0xe1,0x4a,0xeb,0x19,0x2d,0x50,0xa3,0xb6,0x62,0xe0,0xec, +0x9c,0x31,0x10,0x72,0xc7,0x77,0x10,0x00,0xac,0xa3,0x79,0x22,0x4e,0xe3,0x1a,0xf5, +0x4a,0x62,0xb2,0x62,0xe2,0xe5,0xb0,0xa2,0x7b,0x1a,0x54,0xdc,0x1c,0xa4,0x40,0xa1, +0xaa,0x64,0xe2,0xe4,0xb6,0xa1,0x7c,0xdc,0x9c,0x31,0x10,0x5d,0xc8,0x78,0x20,0x00, +0x5c,0xec,0x20,0x62,0x36,0xd3,0x9e,0xac,0xe3,0x0a,0xbe,0xcb,0x82,0xec,0x68,0xea, +0x2c,0x62,0x29,0x05,0x88,0xca,0xdb,0x0b,0xca,0xcc,0x8a,0xea,0x73,0x0b,0x40,0xd5, +0x9c,0x31,0x10,0x5d,0xc8,0x78,0x20,0x00,0x1d,0x81,0x69,0x03,0xcb,0x0d,0xd8,0xe9, +0x9a,0xeb,0x7b,0x14,0x5b,0x09,0x1b,0x15,0x42,0xcb,0xac,0xc9,0xe0,0xed,0xb0,0xea, +0x82,0xea,0x72,0xec,0x30,0x62,0x1f,0x05,0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00, +0x7c,0xa2,0xd6,0xdb,0xce,0xdc,0x90,0xda,0x7f,0x1c,0x59,0x1b,0x15,0x2c,0x40,0xd4, +0xae,0xd9,0xe3,0x1c,0xb2,0xda,0x84,0xdb,0x7a,0xdb,0x3a,0x64,0x13,0x4b,0x64,0xe1, +0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00,0xce,0xdc,0xdc,0xdb,0x9e,0x9b,0x82,0xda, +0x70,0xdc,0x26,0x11,0x16,0xe5,0x7c,0x9b,0xe1,0x1a,0xd6,0xdc,0x92,0xdb,0x80,0xdb, +0x6f,0x23,0x20,0x12,0x16,0xeb,0x84,0x94,0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00, +0xe8,0xda,0xd4,0xdb,0x8e,0xdb,0x80,0xdb,0x6f,0x23,0x1e,0x09,0x10,0xf4,0x82,0x95, +0xea,0xd9,0xdc,0xd3,0x92,0xe5,0x7e,0x9b,0x76,0xda,0x2a,0x53,0x05,0x15,0x68,0xe1, +0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00,0xe0,0xd3,0xea,0xdb,0x9e,0xd3,0x7c,0xe3, +0x7e,0xdc,0x4b,0x1a,0x01,0x2b,0x36,0xcc,0xbc,0xe2,0xfa,0xdb,0xc0,0xe3,0x7e,0xd3, +0x7e,0xda,0x6e,0xdc,0x1e,0x52,0x07,0x1d,0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00, +0x74,0xa2,0xea,0xd3,0xec,0xdb,0x9c,0x9b,0x77,0x1b,0x7e,0xdc,0x5d,0x92,0x0e,0x23, +0x1e,0xe9,0x9a,0x8d,0xf4,0xe3,0xd8,0xdb,0x88,0xdb,0x76,0xda,0x80,0xdc,0x55,0x93, +0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00,0x0a,0xac,0x28,0xd2,0xa4,0xd3,0xf4,0xe3, +0xd0,0xdb,0x86,0xdc,0x7a,0xda,0x82,0xdc,0x57,0x9b,0x0e,0xa4,0x24,0x99,0x98,0x94, +0xec,0xe3,0xd7,0x13,0x90,0xda,0x78,0xdb,0x9c,0x31,0x10,0xa6,0xc6,0x87,0x20,0x00, +0x80,0xdd,0x63,0x1d,0x1c,0x15,0x18,0xf2,0x78,0x91,0xdd,0x1d,0xe4,0xe4,0xa6,0x95, +0x7d,0x21,0x7a,0xe1,0x6c,0xda,0x38,0x61,0x1b,0x0c,0x56,0xed,0xb2,0xd6,0xdc,0xda, +0x9c,0x31,0x10,0x4d,0xc5,0x67,0x10,0x00,0xbf,0x69,0x8c,0x5b,0x76,0x4c,0x6f,0x63, +0x57,0x9a,0x42,0xab,0x55,0x2b,0x7d,0x43,0x99,0x5b,0x9f,0xab,0xa2,0x5b,0x9d,0x5b, +0x93,0x5b,0x86,0x5b,0x79,0x5b,0x6b,0x5b,0x9c,0x31,0x10,0xb5,0xa2,0x23,0x00,0x00, +0x12,0x0d,0x29,0x89,0x64,0x41,0x99,0x72,0xb7,0x80,0xc7,0xc9,0xc0,0x8d,0x9b,0x4d, +0x67,0x25,0x38,0x29,0x2a,0x69,0x40,0x29,0x6c,0xa9,0x98,0x75,0xb9,0x8d,0xc4,0x91, +0x9c,0x31,0x10,0x55,0x92,0x22,0x00,0x00,0xde,0xa1,0x86,0x8b,0x34,0xb4,0x16,0x9a, +0x29,0x0a,0x52,0xe3,0x86,0xd3,0xb3,0x5b,0xc4,0xd4,0xae,0xdb,0x82,0xec,0x65,0x1a, +0x5f,0x0b,0x6c,0x93,0x7a,0xad,0x8d,0x18,0x9c,0x31,0x10,0xbe,0x72,0x22,0x00,0x00, +0xea,0xa4,0xe4,0xdb,0xa2,0x94,0x5d,0x2a,0x40,0xdb,0x4f,0x9b,0x72,0xa2,0x96,0xe5, +0xae,0xcb,0xa5,0x12,0x90,0xa4,0x87,0x09,0x80,0xa4,0x70,0xd3,0x70,0xe3,0x82,0x9b, +0x9c,0x31,0x10,0xdc,0x52,0x12,0x00,0x00,0xb5,0x99,0xb9,0x44,0x7e,0x64,0x66,0x2c, +0x85,0xda,0xce,0x6d,0xb9,0x1a,0x5a,0x11,0x55,0xe5,0xc6,0x4a,0xd1,0x21,0x6d,0xf5, +0x55,0xda,0x9a,0xec,0x81,0xa3,0x0a,0x13,0x9c,0x31,0x10,0x9b,0x62,0x22,0x00,0x00, +0x42,0xda,0x8a,0xcc,0xb2,0xca,0x9e,0xd4,0x71,0x5a,0x92,0x54,0xa0,0x93,0x72,0xdc, +0x43,0x25,0x47,0x62,0x8a,0xab,0xc2,0x5b,0xaa,0xe4,0x7a,0x8b,0x80,0x61,0x89,0x54, +0x9c,0x31,0x10,0x8c,0xa8,0x98,0x40,0x00,0x7d,0xdb,0x79,0xdb,0x79,0xdb,0x81,0xdb, +0x81,0x9b,0x81,0x9b,0x8d,0x1c,0x9c,0x92,0x7e,0xda,0x9d,0xd9,0xcd,0xa5,0x8e,0x96, +0x62,0x12,0x61,0xd9,0x72,0x2a,0x72,0x1c,0x9c,0x31,0x10,0xa3,0x97,0xa8,0x40,0x00, +0x54,0x53,0x53,0x6a,0x6b,0x8c,0x6b,0x8c,0x64,0x91,0x5b,0x72,0x5b,0x4b,0x63,0x93, +0x78,0xbc,0xe3,0x65,0x7e,0x49,0x7b,0x8a,0x85,0xb3,0x4d,0x7b,0x1a,0x54,0x2b,0x7b, +0x9c,0x31,0x10,0xa3,0x97,0xa8,0x40,0x00,0x2b,0x9b,0x21,0x6b,0x30,0x44,0x40,0x6b, +0x49,0xd1,0x52,0xcd,0x73,0x43,0x94,0x73,0xbb,0x9a,0xa3,0x46,0xae,0x7a,0xb4,0x91, +0xa3,0x92,0x9b,0x8b,0x5a,0x53,0x75,0x26,0x9c,0x31,0x10,0x22,0x87,0xa9,0x30,0x00, +0x8d,0x72,0x94,0x83,0x62,0x9c,0x8a,0x73,0xb3,0x89,0xd5,0xc4,0x56,0x8b,0x46,0x3c, +0x54,0x73,0x52,0x7b,0x30,0x8a,0x48,0x7b,0x59,0x64,0x90,0x7b,0x5a,0xa3,0x79,0xab, +0x9c,0x31,0x10,0x92,0x97,0x97,0x20,0x00,0xc5,0x33,0xc9,0xc2,0x9b,0x55,0xb5,0xbb, +0xad,0xbb,0x84,0x1b,0xd1,0x2a,0x98,0xbc,0x9c,0x4a,0xc0,0xc3,0xa8,0xae,0x65,0x31, +0x7d,0x42,0x56,0x44,0x31,0xc2,0x19,0xc3,0x9c,0x31,0x10,0x8d,0x97,0x76,0x20,0x00, +0x4a,0x92,0x5a,0xce,0x2e,0xe4,0x4b,0x28,0x60,0xa6,0x50,0x91,0x6c,0xc2,0x82,0xcd, +0x7a,0x1b,0x86,0x62,0xb2,0x1c,0xaa,0x62,0xa2,0x4b,0x9d,0xd5,0xa5,0x8a,0xb5,0x8c, +0x9c,0x31,0x10,0x4f,0x88,0x77,0x20,0x00,0x7d,0xd3,0x96,0x4a,0xa6,0x9b,0x76,0x9c, +0x76,0x23,0x9c,0xd3,0xbc,0xe3,0x79,0xa3,0x8a,0x61,0xa1,0x1c,0x95,0x9d,0x4d,0xa9, +0xc6,0x6b,0x99,0x24,0xc1,0xeb,0xa0,0xe3,0x9c,0x31,0x10,0xb1,0xa8,0x77,0x30,0x00, +0x86,0x5b,0x81,0xa2,0x77,0x6b,0x75,0x2c,0x64,0xec,0x6c,0xa2,0x82,0x22,0x85,0xa3, +0x9c,0xe3,0x89,0x14,0x89,0x13,0x5e,0xdb,0x46,0x1b,0x2d,0x5a,0x60,0xdb,0x6a,0x15, +0x9c,0x31,0x10,0x32,0xb9,0x76,0x20,0x00,0x99,0xce,0xae,0x90,0xad,0xd1,0x92,0x1a, +0x61,0xdc,0x41,0xdc,0x2d,0xa1,0x46,0x24,0x79,0xe5,0xb6,0x22,0xd5,0x62,0xdd,0xa4, +0xa9,0xa2,0x57,0x29,0x24,0xdc,0x01,0x5c,0x9c,0x31,0x10,0x48,0xca,0x77,0x30,0x00, +0x48,0xc5,0x79,0x46,0xaf,0x14,0xb9,0x04,0xba,0xf6,0x9d,0x09,0x65,0x19,0x50,0xa5, +0x36,0xb6,0x38,0xe5,0x7b,0x74,0xc1,0x88,0xaa,0xda,0xce,0x66,0x96,0x95,0x6b,0x25, +0x9c,0x31,0x10,0x50,0xca,0x67,0x30,0x00,0x48,0xf1,0x33,0x21,0x28,0xc5,0x87,0x59, +0xa6,0xd5,0xc1,0x14,0xd0,0x95,0xb3,0x25,0x80,0xe5,0x53,0xa5,0x34,0x99,0x12,0x95, +0x71,0x56,0x9b,0x16,0xa5,0x04,0xce,0xa4,0x9c,0x31,0x10,0xea,0xc9,0x67,0x30,0x00, +0xc2,0xcd,0xaf,0x72,0x72,0xfa,0x41,0x91,0x12,0x10,0x22,0x91,0x9c,0xa9,0x95,0x6d, +0xaf,0x2d,0xc8,0x8d,0xb6,0xac,0xaf,0x2d,0x7b,0x2d,0x35,0x11,0x16,0x31,0x27,0x94, +0x9c,0x31,0x10,0x4d,0xc9,0x56,0x30,0x00,0xa2,0x4c,0x97,0x0d,0xa9,0x4c,0xbc,0xab, +0xb2,0xeb,0xa8,0xcb,0x8d,0x22,0x40,0x42,0x1f,0x42,0x16,0xc6,0x9a,0x8e,0x9b,0x83, +0x92,0xe9,0xb6,0xa8,0xb6,0xeb,0xaf,0x05,0x9c,0x31,0x10,0xf7,0xca,0x56,0x30,0x00, +0x98,0xd6,0x62,0xf5,0x25,0x69,0x08,0x30,0x77,0xa5,0xac,0xe5,0x8a,0xa6,0xa1,0x05, +0xbb,0x15,0xae,0xe5,0xa2,0xf5,0x7d,0x05,0x40,0xc5,0x0f,0x19,0x33,0x48,0xac,0x44, +0x9c,0x31,0x10,0xdf,0xca,0x66,0x30,0x00,0x9d,0x55,0x8b,0x16,0xa6,0xa6,0xbb,0x15, +0xab,0x15,0x90,0xb5,0x63,0x15,0x2f,0x35,0x0e,0x51,0x71,0x84,0xa3,0x05,0x98,0x95, +0x9b,0x45,0xaf,0x05,0xb4,0xb5,0xa3,0x35,0x9c,0x31,0x10,0xcf,0xca,0x55,0x20,0x00, +0x76,0xf5,0x46,0xb5,0x1f,0x4a,0x35,0x29,0x84,0x58,0x91,0x74,0xa0,0xd5,0xb0,0xc5, +0xb9,0x46,0xb6,0xc5,0x90,0xe5,0x5d,0x35,0x34,0xd5,0x1e,0xb1,0x55,0x55,0x7e,0xb5, +0x9c,0x31,0x10,0x34,0xc8,0x43,0x10,0x00,0x9d,0x74,0xad,0xdb,0xb6,0x03,0xc1,0xcb, +0xa8,0x7a,0x79,0x43,0x4e,0xa4,0x2e,0x75,0x31,0xb6,0x60,0x24,0x85,0xbb,0xa3,0x5a, +0xb4,0x7c,0xc0,0x9c,0xba,0x55,0x92,0x93,0x9c,0x31,0x10,0x62,0xc7,0x44,0x00,0x00, +0x68,0x65,0x46,0x81,0x2f,0x31,0x3f,0x75,0x65,0xb5,0x90,0x25,0xac,0xa5,0xc0,0x45, +0xc9,0x81,0xb2,0x75,0x88,0x65,0x55,0x95,0x2e,0x6a,0x23,0xb4,0x4b,0x50,0x7e,0x71, +0x9c,0x31,0x10,0xff,0xc6,0x44,0x00,0x00,0xa7,0x95,0xc1,0x6a,0xcf,0x89,0xc2,0x55, +0x96,0xa5,0x63,0x45,0x35,0xb4,0x1e,0x3a,0x3b,0x6a,0x6e,0x75,0x9d,0x81,0xba,0x64, +0xcd,0x75,0xce,0x99,0xa8,0x66,0x71,0x65,0x9c,0x31,0x10,0xd6,0xc7,0x44,0x10,0x00, +0x3c,0x95,0x1e,0x31,0x2f,0x94,0x61,0x64,0x93,0x85,0xb5,0x76,0xcd,0x72,0xd4,0x86, +0xb3,0x55,0x7a,0x84,0x40,0x84,0x1e,0x40,0x29,0xa5,0x5b,0x56,0x8d,0x86,0xb1,0x66, +0x9c,0x31,0x10,0x4b,0xc6,0x44,0x10,0x00,0xca,0x74,0xd5,0x84,0xb9,0x44,0x7f,0xa5, +0x42,0x86,0x1d,0x21,0x2b,0xa4,0x5d,0x65,0x8e,0x95,0xb0,0x65,0xca,0x85,0xd5,0x85, +0xb6,0x45,0x7a,0x95,0x3d,0x95,0x1e,0x36,0x9c,0x31,0x10,0x0d,0xc5,0x34,0x00,0x00, +0x32,0x93,0x64,0x51,0x91,0x6a,0xb1,0x43,0xcc,0xb4,0xd4,0x6c,0xac,0x4b,0x6b,0x4a, +0x32,0xb2,0x20,0x91,0x40,0x24,0x72,0x65,0x9b,0x6c,0xb6,0x4a,0xd0,0x6a,0xcc,0x72, +0x9c,0x31,0x10,0x45,0xc5,0x44,0x00,0x00,0x98,0x8d,0x54,0x52,0x25,0x25,0x28,0xad, +0x56,0x4d,0x86,0x91,0xa7,0x4d,0xc1,0xad,0xd2,0x49,0xb7,0x6d,0x75,0x6d,0x38,0xb5, +0x22,0x70,0x42,0x4d,0x74,0x89,0x9b,0x6d,0x9c,0x31,0x10,0x87,0xc5,0x33,0x00,0x00, +0xb3,0xc9,0xcc,0x28,0xc5,0xc4,0x8e,0xa5,0x4a,0x65,0x26,0x8a,0x38,0xca,0x68,0xa4, +0x94,0x44,0xad,0x25,0xc3,0xca,0xc6,0xa6,0x9b,0xc5,0x56,0x44,0x2b,0x99,0x38,0x45, +0x9c,0x31,0x10,0x1a,0xc4,0x33,0x00,0x00,0x64,0x94,0x8f,0x55,0xaa,0x05,0xbe,0x6a, +0xc2,0x15,0x9d,0x45,0x5c,0xb0,0x30,0x96,0x39,0x4a,0x64,0xa4,0x8f,0x40,0xaa,0x15, +0xbb,0xd6,0xbc,0x16,0x97,0x35,0x5d,0x55,0x9c,0x31,0x10,0x95,0xc4,0x32,0x00,0x00, +0x37,0x0a,0x41,0xc6,0x68,0x25,0x8d,0xc0,0xa6,0xa4,0xb7,0x56,0xb2,0xa5,0x8f,0x45, +0x60,0xb4,0x46,0xa5,0x4d,0xd8,0x69,0x26,0x89,0xb5,0xa3,0xa5,0xaf,0x35,0xa8,0x35, +0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00,0xa1,0x85,0x6a,0x65,0x44,0x94,0x3a,0x4a, +0x4e,0x75,0x75,0x46,0x96,0xd1,0xa1,0x75,0x95,0x90,0x84,0x52,0x77,0xa5,0x72,0x49, +0x7f,0x95,0x8f,0x51,0x97,0x81,0x90,0x22,0x9c,0x31,0x10,0x06,0xa4,0x44,0x00,0x00, +0x7b,0x51,0x54,0x6b,0x37,0x53,0x3c,0xd4,0x60,0x8b,0x9f,0x6b,0xcd,0x2b,0xd1,0x63, +0x9d,0x1b,0x62,0x62,0x3a,0x9c,0x33,0x92,0x42,0xd4,0x78,0x9a,0xbc,0xdb,0xd7,0x1c, +0x9c,0x31,0x10,0x8c,0xa4,0x43,0x00,0x00,0xb7,0x4c,0x79,0x90,0x50,0x65,0x3a,0x49, +0x43,0xad,0x6f,0xb1,0xaf,0x6e,0xca,0x0d,0xa8,0xcc,0x82,0x4d,0x5f,0x29,0x50,0x89, +0x4c,0x28,0x6f,0x6d,0x9a,0x91,0xa3,0xb1,0x9c,0x31,0x10,0x69,0x97,0x63,0x00,0x00, +0xad,0xdd,0x7d,0xdd,0x5d,0xdd,0x41,0xdd,0x3d,0xdd,0x61,0xdd,0x8d,0xdd,0xa1,0xdd, +0x99,0xdd,0x85,0xdd,0x71,0xdd,0x61,0xdd,0x59,0xdd,0x6e,0x1d,0x84,0xda,0xd7,0x4e, +0x9c,0x31,0x10,0xc3,0xa9,0x43,0x00,0x00,0x69,0x71,0x9c,0x82,0x63,0x72,0x85,0x8b, +0x61,0x63,0x7c,0x93,0x78,0x62,0xa5,0x91,0x9c,0x2e,0x2f,0xd4,0xa6,0x32,0x41,0xaa, +0xa5,0x63,0x4a,0x8b,0x9c,0x7b,0x67,0x74,0x9c,0x31,0x10,0x1c,0xba,0x65,0x20,0x00, +0x82,0x0c,0x91,0x48,0xe6,0xa6,0x7d,0xc6,0x4a,0x09,0x5d,0xcc,0x81,0xed,0x5e,0x0d, +0x65,0xec,0x75,0xed,0x85,0xee,0x75,0xed,0x7e,0x0c,0x71,0xb2,0xb2,0xae,0x64,0xed, +0x9c,0x31,0x10,0x47,0xaa,0x44,0x10,0x00,0x71,0x74,0x96,0x86,0xd9,0x31,0x6c,0xc4, +0xd5,0x51,0x96,0xaa,0x61,0x25,0x12,0xe1,0x54,0xe1,0x5d,0x05,0x74,0xe5,0x73,0x01, +0x88,0xd5,0x6b,0x15,0x48,0xd5,0x51,0x19,0x9c,0x31,0x10,0x79,0xc8,0x35,0x10,0x00, +0x82,0x33,0x98,0xab,0x9b,0x4c,0x93,0x9b,0x68,0x5b,0x49,0x9b,0x4f,0x4b,0x97,0xba, +0xcd,0x42,0xc5,0xab,0x8c,0x5c,0x49,0x7b,0x26,0x8c,0x43,0x93,0xc0,0x51,0xc3,0xaa, +0x9c,0x31,0x10,0xf9,0xc9,0x56,0x20,0x00,0xb4,0xac,0x93,0x2c,0x7a,0xab,0x2d,0x72, +0x0c,0x49,0xa1,0x6a,0xd6,0x8c,0xbb,0x2d,0x88,0xcc,0x92,0xeb,0x43,0x29,0x02,0x31, +0x7f,0xcc,0xe0,0x0d,0xb9,0xad,0x86,0x4a,0x9c,0x31,0x10,0xfc,0xd9,0x45,0x30,0x00, +0x8d,0xb4,0x73,0x50,0x3d,0x62,0x66,0xb6,0xb2,0x25,0x9f,0xc4,0x83,0x24,0x88,0xb5, +0x85,0x39,0x43,0xa5,0x4c,0x66,0xab,0x76,0xa6,0x86,0x88,0x65,0x80,0x95,0x93,0x54, +0x9c,0x31,0x10,0xe4,0xd9,0x55,0x30,0x00,0x53,0xb9,0x3b,0x25,0x99,0xc4,0xb0,0x24, +0x8d,0xb5,0x7c,0x45,0x97,0x96,0x66,0x75,0x33,0x35,0x7e,0xd6,0xb9,0x06,0x92,0xd5, +0x7d,0x14,0x93,0xc4,0x79,0x45,0x35,0x82,0x9c,0x31,0x10,0xfc,0xd9,0x45,0x30,0x00, +0x63,0xa5,0xba,0x34,0x98,0xb4,0x80,0x35,0x8c,0xb5,0x8a,0x3a,0x3e,0xb5,0x4e,0x56, +0xb2,0x8a,0xa2,0x65,0x83,0x84,0x87,0x74,0x93,0x64,0x4c,0xaa,0x3d,0x3a,0xa4,0xc5, +0x9c,0x31,0x10,0xfc,0xd9,0x45,0x30,0x00,0xab,0x24,0x85,0xb4,0x84,0x34,0x97,0x95, +0x5c,0x75,0x34,0x39,0x90,0xd6,0xb4,0x06,0x89,0xe6,0x82,0x15,0x97,0xb0,0x6d,0x50, +0x31,0x52,0x7a,0xc5,0xb9,0x15,0x8e,0xd5,0x9c,0x31,0x10,0x68,0xd9,0x56,0x30,0x00, +0x82,0x2a,0x91,0x8a,0x7a,0x8c,0x35,0x03,0x67,0x2a,0xb8,0x8b,0x95,0x4b,0x82,0x8b, +0x8f,0x4a,0x84,0x8a,0x3d,0x29,0x54,0xcc,0xb4,0xed,0x9a,0xed,0x84,0xeb,0x89,0x0a, +0x9c,0x31,0x10,0x48,0xd9,0x45,0x20,0x00,0x8e,0x68,0x45,0x98,0x46,0x56,0xac,0xa6, +0xa4,0x45,0x87,0xa4,0x87,0x54,0x92,0x85,0x53,0x7a,0x3a,0x49,0x9d,0xb4,0xac,0x25, +0x8a,0xc5,0x86,0x35,0x93,0xa5,0x60,0x64,0x9c,0x31,0x10,0xc4,0xd9,0x46,0x20,0x00, +0x34,0x92,0x8b,0x8c,0xb0,0x2c,0x8f,0xac,0x84,0x2c,0x91,0x6b,0x6c,0x89,0x36,0xcb, +0x77,0x4b,0xb2,0x63,0x93,0x6b,0x86,0x6b,0x8d,0x4b,0x78,0xab,0x3b,0x04,0x65,0x2a, +0x9c,0x31,0x10,0x7f,0xc8,0x44,0x20,0x00,0xe1,0x34,0xb2,0xb5,0x93,0x35,0x93,0xb5, +0x85,0x55,0x08,0x80,0x2d,0x94,0xd2,0x55,0xc1,0x86,0x99,0x66,0x8c,0x86,0x91,0x75, +0x1f,0x99,0x17,0x46,0xb9,0xa5,0xca,0x25,0x9c,0x31,0x10,0x56,0xc9,0x44,0x30,0x00, +0xa2,0xa4,0x88,0x55,0x93,0x95,0x3a,0x6a,0x08,0x76,0x9c,0x85,0xcb,0x55,0xae,0xa5, +0x89,0x55,0x92,0x95,0x54,0x64,0x09,0x64,0x77,0xa5,0xc9,0x35,0xb2,0xb6,0x93,0x35, +0x9c,0x31,0x10,0x37,0xc8,0x34,0x20,0x00,0x8d,0xdd,0x6e,0x3b,0x0f,0x76,0x5a,0xbc, +0xbb,0x34,0xb9,0xc4,0x9b,0x33,0x8a,0xab,0x7f,0x63,0x22,0x7a,0x3e,0xa0,0xa8,0x51, +0xb8,0x99,0xa9,0x6a,0x88,0x72,0x87,0x9b,0x9c,0x31,0x10,0x37,0xc8,0x34,0x20,0x00, +0x3a,0x64,0x2e,0x8d,0x91,0x74,0xb4,0x6c,0xb3,0x9b,0x90,0x4b,0x89,0xb3,0x58,0x54, +0x2a,0x72,0x75,0xa2,0xa8,0x42,0xb4,0xc2,0x9d,0x32,0x87,0xbb,0x6d,0x4b,0x30,0x84, +0x9c,0x31,0x10,0xf0,0xc7,0x53,0x00,0x00,0x5c,0x5b,0x97,0x93,0xaf,0x63,0xac,0x9b, +0x8c,0x44,0x7d,0x3d,0x49,0xad,0x49,0x5b,0x83,0xa3,0x8b,0xb2,0xb8,0x5b,0xaa,0x83, +0x93,0x73,0x59,0x1b,0x29,0xbb,0x5b,0xcb,0x9c,0x31,0x10,0x47,0xc8,0x32,0x00,0x00, +0x76,0x25,0xb7,0xdd,0xca,0x99,0xb0,0xdd,0x7f,0xb1,0x28,0x2c,0x3d,0xdd,0x5f,0x95, +0x9d,0x66,0xd5,0x1d,0xc2,0x4d,0x9f,0x3c,0x3a,0x28,0x28,0xe0,0x4f,0x9d,0x7e,0xd1, +0x9c,0x31,0x10,0x2f,0xc7,0x32,0x00,0x00,0xcf,0x55,0xcc,0x56,0xb5,0xb5,0x5a,0x39, +0x1f,0xd4,0x42,0x35,0x65,0x71,0xbc,0xb5,0xd1,0x15,0xbf,0xe4,0x7d,0x34,0x25,0x7a, +0x37,0x9a,0x54,0x25,0xa3,0xe1,0xd3,0x05,0x9c,0x31,0x10,0x47,0xc8,0x32,0x00,0x00, +0xc4,0xd1,0x99,0x39,0x35,0x29,0x2e,0xd9,0x4b,0x1d,0x88,0xde,0xd0,0x29,0xc8,0xc5, +0xad,0xc0,0x4f,0xa8,0x27,0xdd,0x42,0x24,0x70,0x49,0xc2,0xbe,0xcc,0x31,0xb9,0x4d, +0x9c,0x31,0x10,0x2f,0xc7,0x32,0x00,0x00,0x6e,0x39,0x2a,0xb4,0x3b,0x55,0x5d,0x61, +0xad,0xa5,0xce,0x25,0xbe,0xb5,0x89,0x64,0x37,0x69,0x33,0x96,0x52,0x35,0x96,0xb1, +0xcc,0x35,0xc2,0x94,0x9c,0x86,0x48,0x26,0x9c,0x31,0x10,0x37,0xc7,0x22,0x00,0x00, +0x2d,0xc8,0x4a,0x39,0x80,0xa4,0xc5,0x61,0xc8,0x62,0xab,0x96,0x5e,0x20,0x2c,0xc1, +0x43,0x44,0x70,0x7a,0xb8,0x96,0xcc,0x41,0xb5,0xa5,0x72,0x59,0x2f,0xa6,0x3c,0x75, +0x9c,0x31,0x10,0x2f,0xc7,0x32,0x00,0x00,0x64,0x56,0xaa,0xa8,0xce,0x45,0xbb,0x95, +0x82,0x76,0x36,0x74,0x34,0x85,0x5b,0x40,0x9d,0xb5,0xcd,0x46,0xc0,0x8a,0x8f,0x84, +0x41,0x49,0x32,0xa9,0x54,0x44,0x8f,0xa2,0x9c,0x31,0x10,0x2f,0xc7,0x32,0x00,0x00, +0xc8,0x55,0xc3,0x75,0x9a,0x96,0x4b,0x36,0x30,0xb5,0x4e,0x45,0x85,0x91,0xc2,0x65, +0xc4,0x75,0xa3,0x96,0x58,0x30,0x31,0xb5,0x48,0x45,0x7b,0x95,0xbc,0x65,0xc6,0x75, +0x9c,0x31,0x10,0xa3,0xc7,0x31,0x00,0x00,0xaa,0x4d,0x61,0x20,0x33,0x60,0x43,0xa9, +0x73,0xc5,0xb5,0xbd,0xc6,0x39,0xaf,0x4d,0x6c,0x29,0x39,0x5c,0x41,0xa9,0x6c,0xc5, +0xad,0xbd,0xc5,0x39,0xb3,0x45,0x73,0xb6,0x9c,0x31,0x10,0xb2,0xc6,0x32,0x00,0x00, +0x3c,0xc6,0x3e,0x44,0x68,0x85,0xa5,0x85,0xc2,0x65,0xb4,0x84,0x7b,0x79,0x42,0x94, +0x3d,0x55,0x63,0x76,0x9f,0x9a,0xc1,0x55,0xb6,0x84,0x81,0x75,0x46,0x75,0x3c,0x6a, +0x9c,0x31,0x10,0x9c,0xc5,0x21,0x00,0x00,0x5f,0x2d,0x9a,0xe6,0xbf,0x0c,0xb8,0x55, +0x86,0xc2,0x4b,0xb6,0x3d,0x35,0x5c,0x35,0x96,0xe5,0xbd,0x0c,0xb9,0xd3,0x8b,0xc3, +0x51,0xab,0x3d,0xbd,0x57,0xb5,0x90,0x5d,0x9c,0x31,0x10,0x9f,0xc5,0x23,0x00,0x00, +0xba,0x05,0xba,0x55,0x90,0x31,0x56,0x15,0x3e,0x48,0x55,0x95,0x8c,0xd9,0xb8,0x05, +0xb9,0xd5,0x93,0x21,0x5a,0xa5,0x40,0x55,0x54,0xa5,0x88,0xd5,0xb6,0x05,0xb9,0x55, +0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00,0xaa,0x65,0x3d,0x59,0x04,0xb1,0x27,0x45, +0x8b,0xb9,0xe7,0x0a,0xf2,0xc6,0xb0,0x54,0x48,0x75,0x09,0xb4,0x22,0x25,0x81,0xd9, +0xdf,0x11,0xef,0xb6,0xb4,0x69,0x52,0x79,0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00, +0x10,0x98,0x21,0x1a,0x7b,0xe4,0xd9,0x42,0xec,0x84,0xb5,0x75,0x59,0x64,0x16,0x79, +0x24,0x49,0x78,0xb2,0xd1,0x72,0xe4,0x55,0xb1,0x95,0x5d,0x75,0x1f,0x55,0x2c,0x91, +0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00,0x7a,0x34,0xca,0xb5,0xd9,0x45,0xab,0x95, +0x60,0x79,0x26,0x55,0x34,0x95,0x7b,0x66,0xc2,0x99,0xd0,0x45,0xa7,0xa5,0x64,0x52, +0x30,0x64,0x3b,0x95,0x7a,0x45,0xbb,0xa1,0x9c,0x31,0x10,0x26,0xb3,0x11,0x00,0x00, +0xc8,0x00,0xa3,0xc9,0x68,0x49,0x3b,0x15,0x42,0x46,0x79,0x05,0xb2,0xd1,0xc0,0x85, +0x9f,0xc1,0x6a,0xc1,0x43,0x99,0x48,0x41,0x78,0x12,0xaa,0xe2,0xb7,0x10,0x9b,0xb5, +0x9c,0x31,0x10,0xa7,0xa3,0x22,0x00,0x00,0x5f,0x91,0x1a,0x68,0x1e,0x6d,0x6e,0x4d, +0xc6,0xa9,0xde,0x31,0xb2,0x8d,0x64,0x6d,0x2c,0x6d,0x2f,0x6d,0x71,0x71,0xba,0x91, +0xce,0x4d,0xab,0x65,0x6c,0x6d,0x3d,0x75,0x9c,0x31,0x10,0x3a,0xa2,0x22,0x00,0x00, +0x3e,0x70,0x72,0x49,0xab,0x8d,0xbb,0x6a,0xa2,0x90,0x70,0x2d,0x4e,0x71,0x4d,0x2a, +0x74,0xd1,0xa0,0x6d,0xad,0xad,0x9b,0x11,0x78,0x89,0x5e,0x45,0x5b,0x71,0x75,0x75, +0x9c,0x31,0x10,0xf1,0x92,0x11,0x00,0x00,0xab,0x7a,0xc0,0xc5,0xa7,0x75,0x79,0xa0, +0x56,0x80,0x55,0xa5,0x76,0x6a,0x9b,0x81,0xa7,0x55,0x97,0x61,0x7e,0x89,0x6a,0x71, +0x6a,0x84,0x79,0x15,0x8b,0x55,0x94,0x86,0x9c,0x31,0x10,0x96,0x72,0x12,0x00,0x00, +0xbf,0x53,0x8f,0x04,0x65,0x62,0x54,0x8c,0x64,0xeb,0x8a,0xe3,0xa1,0x2a,0x9c,0xeb, +0x92,0xd3,0x8d,0x0d,0x7e,0xe2,0x78,0xab,0x84,0x82,0x94,0xf4,0x9c,0xd2,0x9f,0x2c, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_PAIR_ENABLE.txt b/config/_default_cfg_src_/res/cn/SOUND_PAIR_ENABLE.txt new file mode 100644 index 0000000..f4e0ae3 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_PAIR_ENABLE.txt @@ -0,0 +1,255 @@ +0x9c,0x31,0x10,0x11,0x21,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x8a,0x1b,0x85,0x9b, +0xdf,0xa3,0xa1,0xb2,0x52,0x59,0x56,0x23,0x19,0x2b,0x6d,0xec,0xa9,0x64,0x3a,0x22, +0xbd,0xe3,0xe2,0xf5,0xb6,0x98,0x8c,0xb0,0x9c,0x31,0x10,0x20,0x33,0x33,0x00,0x00, +0x4a,0x43,0x4c,0x2b,0x99,0xbc,0x83,0x33,0x72,0xcb,0x66,0x4c,0x3b,0xb2,0x72,0xb3, +0x72,0x4a,0xb3,0x53,0x43,0x52,0xf2,0x94,0x91,0x9d,0xad,0xaa,0x85,0x2b,0x1b,0xc3, +0x9c,0x31,0x10,0x10,0x56,0x43,0x20,0x00,0x43,0x25,0x83,0xa5,0x8c,0x25,0x53,0xa5, +0x7b,0xb5,0x8b,0xa5,0x7b,0xa5,0x5b,0x35,0x94,0x21,0x6b,0xc5,0x9c,0x25,0x54,0x29, +0x9b,0xb5,0x6b,0xb5,0xab,0x9a,0xf1,0x86,0x9c,0x31,0x10,0x14,0xab,0x96,0x30,0x00, +0x99,0xce,0x8d,0x88,0x87,0x25,0x81,0xc6,0x91,0xe8,0x81,0xc9,0xae,0x51,0x39,0xf1, +0x6d,0x4d,0x85,0xed,0x6e,0x4d,0x66,0x0d,0x75,0xcd,0x7d,0xad,0x6d,0xed,0x6a,0x0d, +0x9c,0x31,0x10,0xa4,0x77,0x74,0x10,0x00,0x3d,0x3c,0x62,0x3a,0x61,0x3b,0x73,0xbb, +0x94,0x3b,0x94,0xc4,0x8b,0x3e,0x89,0x3a,0x79,0xc5,0x8c,0x29,0x94,0x99,0x95,0xaa, +0x92,0x9e,0xda,0xaa,0x79,0xc4,0xb0,0xa8,0x9c,0x31,0x10,0x9c,0x89,0x76,0x10,0x00, +0x86,0x0b,0x9e,0x54,0x9e,0x11,0xaa,0x25,0x9e,0x23,0x9a,0x6c,0xa2,0x51,0x8d,0xe4, +0x75,0x5b,0x79,0x12,0x69,0x53,0x4e,0x1d,0x33,0x50,0x4a,0x8c,0x20,0xd3,0x5d,0x14, +0x9c,0x31,0x10,0x5d,0x89,0x76,0x20,0x00,0x5e,0xa4,0x5b,0x0b,0x4a,0x5a,0x3d,0x1a, +0x59,0xa2,0x65,0xe3,0x15,0x9b,0x48,0xad,0x71,0x44,0x5a,0x08,0x96,0xa5,0xa6,0x18, +0x81,0x5a,0x65,0xec,0x6d,0x63,0x82,0x64,0x9c,0x31,0x10,0xf0,0x8a,0x86,0x40,0x00, +0x64,0x5d,0x9d,0x59,0xab,0x58,0xda,0x55,0xca,0xd1,0xc3,0xda,0xce,0x21,0xde,0x69, +0xd3,0xb1,0xb1,0xad,0xa9,0x18,0xdb,0x5d,0x9f,0x1d,0x3e,0x59,0x91,0xda,0x91,0x15, +0x9c,0x31,0x10,0xc5,0x9a,0x87,0x20,0x00,0x3c,0xd1,0x46,0x59,0x5c,0xa1,0x61,0xe1, +0x8c,0xe5,0x7c,0x11,0x8a,0xd5,0x52,0xd4,0x8c,0x4e,0x6d,0x61,0x63,0xe1,0x53,0x65, +0x62,0xd1,0x6c,0x1d,0x6d,0x9d,0x73,0x4d,0x9c,0x31,0x10,0x71,0x9a,0x87,0x30,0x00, +0xc2,0xd1,0x64,0x21,0x5d,0x59,0x65,0x65,0x82,0xad,0x61,0xec,0x73,0x99,0xcd,0x56, +0xb3,0x8d,0x8c,0x19,0xbc,0x69,0x93,0x25,0x6c,0x1d,0x6c,0x1d,0x93,0xa5,0x7c,0x21, +0x9c,0x31,0x10,0xd4,0x99,0x66,0x30,0x00,0x95,0x6c,0x7b,0xa2,0x6a,0xeb,0x98,0xb4, +0xb8,0xd9,0x6d,0xc4,0x4d,0xdb,0x92,0x18,0x7d,0xdb,0x74,0x03,0x7d,0x24,0x9e,0xd4, +0x92,0x4c,0xc2,0x02,0xc9,0x13,0xd5,0x11,0x9c,0x31,0x10,0xc0,0xc8,0x65,0x20,0x00, +0x89,0x6c,0x89,0x84,0x7f,0x16,0x6e,0x6d,0x60,0x0e,0x5f,0x4e,0x81,0x70,0xad,0x8d, +0xb8,0x8d,0xa0,0xf1,0x68,0xb2,0x3e,0xd5,0x22,0xac,0x32,0x69,0xa0,0xc9,0xe7,0x6d, +0x9c,0x31,0x10,0xe4,0xd9,0x67,0x40,0x00,0xb3,0x4d,0x9c,0xf1,0x80,0x8d,0x5f,0x0d, +0x40,0xe9,0x3c,0x8a,0x83,0x05,0xb1,0x49,0xa5,0x0d,0x9c,0xcd,0x9e,0xd0,0x82,0xf1, +0x49,0x51,0x30,0xf5,0x48,0xf5,0x9c,0x0d,0x9c,0x31,0x10,0xcc,0xd9,0x57,0x40,0x00, +0xab,0x0b,0x97,0x6b,0x9d,0x0b,0xae,0x4c,0x8b,0x14,0x4b,0x32,0x37,0x02,0x40,0x53, +0x92,0x2c,0xab,0x6c,0x8f,0x8c,0x90,0xab,0xb0,0x8a,0xa6,0xea,0x67,0x09,0x43,0xca, +0x9c,0x31,0x10,0xf2,0xda,0x77,0x50,0x00,0x32,0x75,0x65,0x86,0xaa,0xe6,0x9a,0xb5, +0x80,0xe5,0x9d,0x35,0xb9,0x14,0x94,0xb5,0x58,0x91,0x43,0x71,0x32,0xa1,0x80,0xf4, +0xad,0x44,0x89,0x25,0x7e,0xb5,0xaa,0xf5,0x9c,0x31,0x10,0xf2,0xda,0x77,0x50,0x00, +0xb7,0x16,0x88,0xf6,0x58,0x96,0x43,0x42,0x32,0x92,0x88,0xd4,0xad,0x54,0x81,0x24, +0x7c,0xa4,0xac,0xe5,0xb5,0x05,0x89,0x15,0x5c,0xb6,0x47,0x42,0x32,0x72,0x89,0x05, +0x9c,0x31,0x10,0xf2,0xda,0x77,0x50,0x00,0xad,0x64,0x7c,0xf4,0x7c,0xb4,0xac,0xf5, +0xaf,0x25,0x8d,0x06,0x68,0xb5,0x4f,0x55,0x2c,0x60,0x79,0x84,0xb3,0x25,0x80,0xa5, +0x72,0xc6,0xa7,0x36,0xac,0xf6,0x8e,0xe5,0x9c,0x31,0x10,0xf2,0xda,0x77,0x50,0x00, +0x7c,0xd5,0x5d,0x35,0x30,0xba,0x53,0xc8,0xb6,0x24,0x8e,0xd4,0x69,0x54,0x99,0x15, +0xae,0xa5,0x8e,0xf6,0x91,0x36,0x78,0xd5,0x4b,0x26,0x2c,0x20,0x91,0xa4,0xad,0x64, +0x9c,0x31,0x10,0x74,0xda,0x78,0x50,0x00,0x6a,0x6b,0x78,0xcb,0xaf,0x4c,0x96,0xcc, +0x88,0xcb,0x9c,0xcb,0x6d,0x2b,0x3f,0x03,0x3a,0x4d,0xa6,0xcb,0x99,0xab,0x64,0xaa, +0x8c,0x8a,0xab,0x2a,0x85,0x0b,0x88,0xab,0x9c,0x31,0x10,0xe9,0xdb,0x78,0x50,0x00, +0xa4,0xeb,0x6e,0xec,0x43,0x04,0x3e,0x85,0x9f,0x0a,0x95,0x4a,0x68,0xaa,0x8a,0xca, +0xa3,0x2b,0x82,0xeb,0x86,0xcb,0xa7,0x0c,0x7e,0xcb,0x50,0xeb,0x3c,0xab,0x7b,0x8d, +0x9c,0x31,0x10,0x49,0xca,0x68,0x50,0x00,0xc8,0x2c,0x68,0x8b,0x75,0x8b,0xbc,0xca, +0x9a,0x8a,0x7d,0x2a,0xb4,0xeb,0xbe,0xab,0x51,0x0b,0x17,0x24,0x0c,0x25,0xb7,0x0b, +0xa3,0xa2,0x5c,0x4a,0x92,0xea,0xb9,0x6a,0x9c,0x31,0x10,0xd4,0xcb,0x68,0x50,0x00, +0x84,0xcb,0x8e,0xeb,0xc1,0x2c,0x9a,0xcc,0x3e,0xeb,0x0f,0x13,0x34,0xf1,0xca,0x6b, +0x83,0x6b,0x5e,0xcc,0xaa,0xac,0xaf,0x2c,0x7c,0xeb,0x98,0xcb,0xc7,0x2a,0x82,0xcb, +0x9c,0x31,0x10,0x4a,0xcb,0x77,0x50,0x00,0x32,0xe5,0x0b,0x0a,0x5b,0x46,0xc4,0x64, +0x75,0x54,0x68,0xf4,0xb2,0xb4,0xa1,0x35,0x7a,0xe6,0xa8,0xd6,0xc1,0x36,0x64,0xd5, +0x29,0x05,0x0a,0xc0,0x95,0x44,0xae,0xc5,0x9c,0x31,0x10,0xe9,0xc9,0x57,0x40,0x00, +0x66,0xed,0x7d,0x6e,0xb8,0x4d,0x99,0x6b,0x80,0xaa,0xb2,0xc9,0xb1,0x0a,0x54,0xeb, +0x1f,0x24,0x1a,0x2e,0xa7,0x8c,0xa0,0xaa,0x76,0xc9,0x79,0x4a,0xaa,0x8b,0xa5,0x4c, +0x9c,0x31,0x10,0x0e,0xb8,0x36,0x10,0x00,0xa4,0x4b,0xbf,0x36,0x8d,0x24,0x38,0x95, +0x05,0x79,0x26,0xca,0x74,0xe5,0x7f,0x35,0x86,0xa7,0x85,0x38,0x98,0xc7,0x99,0x17, +0x94,0xf7,0x9a,0xf7,0x94,0xf7,0x87,0x07,0x9c,0x31,0x10,0xa1,0x95,0x22,0x00,0x00, +0x64,0xed,0x36,0x8c,0x24,0xed,0x37,0x0d,0x77,0x05,0xa7,0x0d,0xc8,0x6a,0xdb,0x4e, +0xcf,0x49,0x90,0x70,0x44,0xe9,0x28,0xed,0x38,0xe5,0x51,0x11,0x74,0xb0,0xa9,0x09, +0x9c,0x31,0x10,0x2d,0x95,0x21,0x00,0x00,0xbe,0xad,0x9f,0x46,0x8c,0xee,0x86,0x89, +0x71,0x4d,0x62,0xca,0x6c,0xe4,0x82,0xec,0x91,0x29,0x91,0x11,0x8a,0x8e,0x81,0x91, +0x6e,0x92,0x6b,0x10,0x7d,0x29,0x88,0x6d,0x9c,0x31,0x10,0x56,0x64,0x11,0x00,0x00, +0xdb,0xda,0xc0,0xb8,0x8f,0x15,0x58,0xd9,0x56,0xb5,0x8d,0xb5,0x90,0x14,0x9d,0x95, +0x50,0xc5,0x60,0xb5,0x79,0x44,0x96,0xe0,0x8b,0x2a,0x34,0xb9,0x35,0x15,0x6f,0x31, +0x9c,0x31,0x10,0xda,0x64,0x12,0x00,0x00,0xca,0x6c,0xcd,0x29,0x7f,0x0c,0x7a,0xec, +0x1c,0xec,0x36,0x6b,0x61,0xa3,0x9a,0xb3,0x82,0x93,0x49,0x53,0x56,0x92,0x7f,0x0a, +0xb2,0xeb,0xb8,0xd5,0x93,0x4c,0x7c,0x4b,0x9c,0x31,0x10,0xf2,0x64,0x22,0x00,0x00, +0x3f,0x1a,0x51,0x58,0x8e,0x1a,0x9d,0xdc,0x4a,0x1c,0x35,0xad,0x69,0xdb,0x86,0x2a, +0x91,0x21,0x99,0xdb,0x7a,0xdd,0x58,0xd4,0x52,0x5b,0x5a,0x62,0x6d,0x9b,0x6e,0x1a, +0x9c,0x31,0x10,0x97,0xa7,0x76,0x00,0x00,0x7c,0xdb,0x7c,0xdb,0x80,0xdb,0x7e,0xdb, +0x80,0xdb,0x80,0xdb,0x80,0xdb,0x7e,0xdb,0x7e,0xdb,0x7e,0xdb,0x7e,0xdb,0x80,0xdb, +0x86,0xdb,0x96,0x9a,0xdf,0xad,0xf0,0x9b,0x9c,0x31,0x10,0xe2,0xa7,0x76,0x20,0x00, +0xd6,0xd1,0xcd,0x04,0xc7,0x0b,0xb9,0x13,0xa8,0x54,0x8b,0x1b,0x8c,0x8b,0xb4,0xd1, +0xa8,0x5a,0x62,0xcd,0x3a,0xe3,0x3e,0x5b,0x3d,0x1b,0x20,0x9b,0x0d,0x1b,0x07,0x23, +0x9c,0x31,0x10,0xe1,0xb8,0x77,0x10,0x00,0x3e,0x1b,0x42,0x1b,0x45,0xdb,0x49,0xd4, +0x46,0x23,0x4e,0x1a,0x69,0xdb,0x75,0x62,0x71,0x1c,0x82,0x5b,0x81,0xd3,0x7a,0x13, +0x82,0xa2,0x8b,0x25,0x82,0x69,0x8a,0xf4,0x9c,0x31,0x10,0xac,0x98,0x86,0x10,0x00, +0x9b,0x44,0x9c,0xc1,0xa3,0xbb,0x8d,0x45,0xae,0x42,0xb7,0x3c,0xab,0xd3,0xb4,0xcc, +0xba,0xcb,0x9c,0x50,0xac,0xcd,0xa3,0xd5,0xa3,0xc9,0xc5,0x5a,0x9d,0xc4,0xbc,0xd0, +0x9c,0x31,0x10,0xe2,0x98,0x87,0x20,0x00,0xc2,0xc5,0xba,0x3a,0xa2,0xa3,0xb1,0x1b, +0x81,0x3d,0xa1,0x21,0x89,0x9c,0xb3,0x94,0x81,0x3b,0xb3,0xc9,0xa9,0xdc,0x8b,0x41, +0x79,0x55,0x9b,0x4b,0x83,0x53,0x74,0xba,0x9c,0x31,0x10,0xaf,0x87,0x87,0x20,0x00, +0x85,0xbc,0xa2,0x42,0x70,0xa3,0x85,0x8c,0xde,0x23,0xc1,0xba,0x99,0xe5,0x99,0xd9, +0xc1,0x5d,0x4a,0xb4,0x59,0x48,0x8d,0xc5,0xa9,0x3a,0x65,0xaa,0x99,0x9b,0x39,0xad, +0x9c,0x31,0x10,0x8a,0x97,0x87,0x20,0x00,0x82,0x41,0x79,0xcb,0x81,0x3d,0xaa,0x32, +0x9e,0x1b,0x7a,0xab,0x6e,0x4a,0x75,0xc4,0x79,0xb4,0x99,0x18,0xb5,0xcc,0x92,0x4c, +0x59,0x3a,0x41,0xcc,0x3d,0xcc,0x75,0x31,0x9c,0x31,0x10,0xe5,0xa7,0x87,0x20,0x00, +0x8e,0x2d,0x9d,0x3b,0x92,0x5a,0x5d,0x52,0x49,0xbc,0x56,0x3a,0x85,0xab,0xa9,0xc3, +0xb1,0xc4,0x7c,0xab,0x3e,0x3a,0x2d,0xbd,0x4e,0x44,0x91,0xb1,0xe6,0x4c,0xce,0x43, +0x9c,0x31,0x10,0x2e,0xb8,0x88,0x20,0x00,0x71,0x92,0x49,0xe3,0x4d,0xdb,0x65,0xd3, +0xa6,0x1d,0xc9,0xa1,0xa1,0xdb,0x52,0x1c,0x41,0xd3,0x3d,0xe2,0x7e,0x2b,0xc9,0x8b, +0xd2,0x4c,0x74,0xa1,0x39,0xf3,0x2d,0x8c,0x9c,0x31,0x10,0x3b,0xc7,0x87,0x20,0x00, +0x66,0xcd,0x9e,0xf5,0xba,0xdc,0x94,0xd9,0x63,0x91,0x50,0xe5,0x52,0x64,0x87,0x69, +0xc6,0x8e,0xaf,0xa0,0x6c,0xaa,0x4a,0xac,0x48,0x86,0x6e,0xda,0xc2,0xf8,0xc0,0xa5, +0x9c,0x31,0x10,0xa5,0xc7,0x98,0x20,0x00,0x7c,0x0b,0x4b,0x1b,0x3e,0xaa,0x61,0x9d, +0xb4,0x8b,0xd0,0xb1,0x98,0x64,0x4f,0x93,0x39,0x13,0x4f,0x2c,0xaa,0x5b,0xd3,0x09, +0xa9,0x25,0x56,0x63,0x33,0x13,0x42,0xa5,0x9c,0x31,0x10,0x92,0xc8,0x87,0x10,0x00, +0xa5,0x0c,0xd2,0xed,0xb4,0xd1,0x64,0x8a,0x33,0x2c,0x36,0xfa,0x99,0x08,0xce,0x85, +0xbc,0xf5,0x72,0xd1,0x37,0x85,0x2a,0x99,0x8e,0xec,0xd0,0x8a,0xbf,0x2d,0x7e,0xf0, +0x9c,0x31,0x10,0x0c,0xc8,0x98,0x10,0x00,0x3f,0x54,0x24,0x63,0x7c,0xe2,0xce,0x94, +0xc3,0x1b,0x8c,0xdb,0x47,0x1c,0x22,0x12,0x6a,0xed,0xc8,0xd3,0xc9,0x1b,0x94,0xe3, +0x52,0xd4,0x24,0x11,0x59,0x1e,0xbe,0xa0,0x9c,0x31,0x10,0xcd,0xc8,0x98,0x20,0x00, +0xce,0xcc,0xa0,0xe4,0x5e,0xda,0x26,0x9c,0x43,0x52,0xac,0xe2,0xd2,0xd4,0xac,0xdb, +0x6c,0xda,0x30,0xe4,0x31,0x51,0x96,0xd6,0xd2,0xe9,0xba,0xd2,0x7c,0xdc,0x3f,0x1a, +0x9c,0x31,0x10,0x42,0xc8,0x99,0x20,0x00,0x22,0xe4,0x74,0xd1,0xca,0xd4,0xcc,0xe3, +0x90,0xd2,0x52,0xdc,0x22,0x12,0x50,0xed,0xb6,0xd2,0xd6,0xdb,0xaa,0xe3,0x66,0xd3, +0x2c,0xe4,0x2f,0x49,0x92,0xe5,0xd6,0xdb,0x9c,0x31,0x10,0x32,0xc7,0x89,0x20,0x00, +0xc2,0xd2,0x80,0xe4,0x43,0x53,0x1e,0xb4,0x62,0xd0,0xc4,0x95,0xd6,0xea,0x9e,0x92, +0x5b,0x23,0x28,0x14,0x39,0x4b,0x9c,0xf1,0xdb,0x05,0xc0,0xe2,0x7c,0xd3,0x43,0x5b, +0x9c,0x31,0x10,0x42,0xc8,0x99,0x20,0x00,0x20,0xec,0x5c,0xd1,0xbe,0xdc,0xdc,0xdb, +0xaa,0xdb,0x64,0xdb,0x2c,0xe4,0x29,0x09,0x82,0xe5,0xd4,0xd3,0xd4,0xdb,0x90,0xdb, +0x51,0x1c,0x20,0x51,0x3c,0xed,0x9c,0xd2,0x9c,0x31,0x10,0xb7,0xc6,0x99,0x20,0x00, +0xdd,0x5b,0xc6,0xdb,0x80,0xdc,0x47,0x9a,0x1e,0x1c,0x4c,0xd9,0xac,0x55,0xe1,0x22, +0xba,0xd3,0x79,0x23,0x41,0x93,0x1d,0x2c,0x52,0x8b,0xb4,0xaa,0xe0,0xd3,0xb8,0xe4, +0x9c,0x31,0x10,0x38,0xc6,0x98,0x20,0x00,0x79,0x59,0x45,0x9b,0x1d,0x6e,0x4e,0xc3, +0xac,0xb1,0xe0,0xcc,0xc0,0xe5,0x81,0x19,0x49,0x53,0x1a,0xed,0x40,0x89,0xa0,0xab, +0xe0,0xdb,0xcd,0x1c,0x8e,0xe2,0x57,0x14,0x9c,0x31,0x10,0x7c,0xc7,0x88,0x10,0x00, +0x20,0x62,0x2a,0xea,0x80,0x86,0xd5,0x32,0xdc,0xd2,0xa6,0x9c,0x6c,0xe3,0x2e,0x4b, +0x19,0x14,0x58,0xea,0xb6,0xc4,0xe4,0xe3,0xc2,0xdb,0x89,0x14,0x51,0x23,0x22,0xe4, +0x9c,0x31,0x10,0xef,0xc6,0x77,0x10,0x00,0x34,0x81,0x7a,0x9b,0xba,0xec,0xc9,0x1a, +0xa4,0x93,0x81,0x23,0x64,0xe3,0x53,0x52,0x50,0xd3,0x68,0xdb,0x8c,0xe3,0xa2,0xdb, +0xab,0x1b,0xa4,0x9b,0x8a,0xdb,0x68,0xdb,0x9c,0x31,0x10,0x5d,0xb3,0x43,0x00,0x00, +0x1f,0x6c,0x25,0x95,0x5c,0x65,0x9f,0x4d,0xd2,0x6d,0xdd,0x6d,0xb7,0x91,0x70,0x69, +0x2f,0x51,0x1e,0x69,0x43,0xae,0x80,0x4c,0xb8,0x69,0xd5,0x71,0xc7,0x8d,0x90,0x71, +0x9c,0x31,0x10,0x88,0xb2,0x33,0x00,0x00,0x54,0x85,0x33,0x51,0x37,0x71,0x5f,0x48, +0x96,0x4e,0xc0,0xac,0xc6,0x4d,0xa7,0x71,0x75,0xa9,0x4b,0x95,0x3e,0x45,0x53,0x91, +0x7f,0x45,0xa8,0x91,0xb7,0x69,0xa7,0x65,0x9c,0x31,0x10,0x98,0xa1,0x32,0x00,0x00, +0x85,0xad,0x3f,0x8b,0x24,0xa4,0x39,0x1b,0x6e,0x1c,0xa8,0x50,0xc8,0x1e,0xbe,0x91, +0x94,0x1c,0x65,0x9a,0x4c,0x13,0x50,0x5b,0x6a,0x54,0x8e,0x14,0xa5,0xa4,0xa3,0x51, +0x9c,0x31,0x10,0xca,0x81,0x22,0x00,0x00,0xc0,0x63,0x5b,0x63,0x11,0x52,0x0a,0x24, +0x4b,0x6b,0x9a,0x0b,0xce,0xa3,0xd2,0x19,0xa7,0x95,0x67,0xab,0x3b,0x83,0x3f,0x52, +0x61,0x23,0x8a,0x5b,0xa8,0x54,0xa9,0x5a,0x9c,0x31,0x10,0x88,0x71,0x21,0x00,0x00, +0xa8,0x9e,0x66,0x59,0x39,0x89,0x39,0x69,0x59,0x09,0x79,0x25,0x96,0xdd,0xb0,0x49, +0xa7,0x24,0x78,0x96,0x57,0x2e,0x48,0xd8,0x43,0x32,0x5e,0x50,0x9d,0x1e,0xb4,0xe5, +0x9c,0x31,0x10,0xae,0x61,0x23,0x00,0x00,0xc2,0xc4,0x82,0x33,0x42,0x8b,0x05,0x23, +0x1c,0xe3,0x7a,0xd2,0xbc,0x6c,0xbb,0x13,0x9c,0xe4,0x79,0x22,0x4d,0x4c,0x48,0x9a, +0x63,0x23,0x7c,0x03,0x7b,0x34,0x71,0x50,0x9c,0x31,0x10,0x53,0xb8,0x99,0x60,0x00, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x68,0x83,0x68,0x9c,0x68,0xb5,0x34,0xf3,0x95,0xe3,0x8e,0xb2,0x4e,0x5b,0x4a, +0x9c,0x31,0x10,0xc3,0xd8,0x98,0x50,0x00,0x70,0xd1,0x6e,0x92,0x72,0x93,0x72,0x9b, +0x70,0xec,0x74,0xf3,0x71,0x23,0x69,0x1b,0x5f,0x0b,0x5d,0x0a,0x72,0xcb,0x9a,0x93, +0xae,0x9b,0x94,0x63,0x5c,0xe3,0x36,0x5a,0x9c,0x31,0x10,0xeb,0xd9,0x87,0x20,0x00, +0x58,0xee,0xa4,0xcc,0xca,0xed,0xb4,0xce,0x86,0xcc,0x64,0xed,0x4a,0x64,0x5a,0xae, +0x92,0xa9,0xb4,0xcc,0xae,0xca,0x92,0xad,0x7c,0xcd,0x5a,0xf1,0x41,0x50,0x6b,0x0e, +0x9c,0x31,0x10,0x87,0xc9,0x77,0x10,0x00,0xcd,0x10,0xf0,0xf1,0xbc,0xf2,0x88,0xf0, +0x5e,0xcd,0x10,0x61,0x1c,0xac,0x8e,0xc6,0xe5,0x04,0xd3,0x09,0x99,0x0e,0x85,0x30, +0x49,0x15,0x03,0x19,0x3c,0x91,0xb6,0x90,0x9c,0x31,0x10,0x1a,0xc8,0x77,0x10,0x00, +0xe8,0x6d,0xb6,0xcd,0x8b,0x4c,0x7b,0x4d,0x2a,0xcd,0x05,0xa9,0x65,0x2c,0xd4,0xf1, +0xe0,0xad,0xa0,0x6d,0x87,0x09,0x6b,0x29,0x12,0x85,0x1c,0xac,0x93,0x2a,0xe7,0x4d, +0x9c,0x31,0x10,0x8d,0xc8,0x66,0x10,0x00,0xcb,0x4d,0x8e,0xce,0x86,0xb1,0x52,0xd1, +0x05,0x39,0x3c,0x4e,0xb6,0xac,0xeb,0x0d,0xb3,0x2e,0x87,0x50,0x82,0xf1,0x34,0x7a, +0x05,0xc9,0x61,0x10,0xd4,0xb2,0xde,0x8d,0x9c,0x31,0x10,0x02,0xc8,0x67,0x10,0x00, +0x9c,0xad,0x87,0x49,0x7b,0x4d,0x1a,0x20,0x0f,0x2e,0x85,0x69,0xe7,0x0c,0xce,0xcd, +0x8c,0x6d,0x89,0x09,0x6b,0x45,0x06,0x8a,0x22,0x4c,0xa7,0x49,0xef,0x69,0xbf,0x0c, +0x9c,0x31,0x10,0x27,0xd8,0x67,0x10,0x00,0x80,0x8d,0x84,0xad,0x6b,0x2c,0x3d,0x35, +0x5c,0x0a,0xa2,0x8c,0xb7,0x4d,0x93,0x4e,0x7f,0x10,0x86,0xb1,0x5e,0xba,0x37,0xd0, +0x68,0x91,0xae,0x4e,0xb4,0xcc,0x8d,0x0d,0x9c,0x31,0x10,0x27,0xd8,0x67,0x10,0x00, +0x81,0x6e,0x89,0x10,0x54,0x5a,0x33,0xc9,0x72,0xf4,0xb8,0x92,0xb2,0xad,0x86,0xac, +0x83,0x4e,0x8b,0x71,0x4e,0x75,0x31,0xca,0x7b,0x30,0xbe,0xb1,0xac,0x8d,0x80,0x70, +0x9c,0x31,0x10,0xa2,0xd9,0x77,0x10,0x00,0x87,0x0d,0x8d,0x2d,0x48,0xd1,0x2d,0x6e, +0x81,0x10,0xc2,0xd1,0xa8,0xad,0x7c,0xad,0x8b,0x0d,0x93,0x2d,0x48,0xf5,0x27,0x8d, +0x7e,0xf4,0xc6,0xb2,0xa8,0x8d,0x78,0x8d,0x9c,0x31,0x10,0xe5,0xd9,0x78,0x20,0x00, +0x8b,0x0c,0x9b,0x2b,0x4f,0x13,0x1f,0x72,0x76,0xd4,0xca,0x8b,0xaa,0x6a,0x74,0xac, +0x86,0xeb,0xa5,0x0a,0x61,0x23,0x16,0xd5,0x60,0x6a,0xc8,0x8a,0xb4,0xa4,0x74,0xe2, +0x9c,0x31,0x10,0xf0,0xd8,0x88,0x20,0x00,0x7e,0xd3,0xab,0x14,0x79,0x53,0x18,0x09, +0x3f,0x4d,0xbb,0x53,0xc3,0x91,0x7b,0x94,0x75,0x1b,0xad,0x5a,0x99,0x64,0x33,0x63, +0x1b,0xb2,0x94,0xee,0xce,0xea,0x8c,0xaa,0x9c,0x31,0x10,0x6d,0xd9,0x88,0x20,0x00, +0x68,0xec,0x9c,0xe2,0xb2,0xa3,0x62,0xdc,0x14,0x4a,0x53,0x06,0xc2,0xc9,0xae,0xca, +0x6c,0xcd,0x82,0xd2,0xb6,0xd2,0x96,0xdc,0x3a,0xdb,0x20,0x5b,0x84,0xb0,0xc2,0xad, +0x9c,0x31,0x10,0x67,0xd8,0x99,0x20,0x00,0x8c,0xa3,0x6c,0xe2,0x9c,0xe3,0xb4,0xdb, +0x79,0x1b,0x31,0x5a,0x37,0x6c,0x98,0xdb,0xb4,0xd9,0x7e,0xdc,0x77,0x1c,0xa8,0xda, +0xaa,0xdb,0x6d,0x1c,0x33,0x1a,0x41,0xab,0x9c,0x31,0x10,0xd3,0xd8,0x99,0x30,0x00, +0x9a,0xdd,0xac,0xd1,0x7e,0xd3,0x7d,0x1c,0xa8,0xdb,0xa4,0xda,0x6d,0x1c,0x3b,0x5b, +0x41,0x34,0x92,0xdb,0xac,0xd2,0x82,0xd4,0x7b,0x1b,0xa4,0xe2,0xa6,0xdb,0x74,0xdc, +0x9c,0x31,0x10,0x4e,0xd9,0x99,0x30,0x00,0x43,0x13,0x3a,0xa4,0x82,0xf1,0xac,0x9c, +0x8a,0xd4,0x78,0xda,0x9c,0xe3,0xaa,0xe4,0x80,0xdb,0x52,0xdb,0x38,0x4a,0x6a,0xd5, +0xa8,0xaa,0x96,0xda,0x78,0xd4,0x90,0xdb,0x9c,0x31,0x10,0x66,0xd9,0xa9,0x30,0x00, +0xa9,0xba,0x91,0xc4,0x61,0xbb,0x3d,0xc3,0x4e,0xb1,0x95,0xa5,0xa1,0xc3,0x7d,0xc1, +0x7d,0xb3,0xa5,0xbc,0xa1,0xc3,0x75,0xba,0x4e,0x3c,0x3c,0xaa,0x71,0xdb,0xa5,0x45, +0x9c,0x31,0x10,0x79,0xc8,0x98,0x30,0x00,0xa8,0xc9,0x70,0xd9,0xa2,0xed,0xd8,0x94, +0xa4,0xda,0x4b,0x23,0x0f,0x1a,0x13,0x76,0x96,0xc4,0xce,0xd0,0x8e,0xec,0x72,0xdd, +0xbc,0xd2,0xd6,0xe2,0x88,0xa4,0x39,0x13,0x9c,0x31,0x10,0xde,0xc8,0xa9,0x30,0x00, +0x09,0x43,0x2b,0x29,0xad,0xb5,0xc2,0x4c,0x7d,0xba,0x79,0xb3,0xc6,0x44,0xc9,0xc3, +0x79,0x3b,0x36,0x3b,0x0c,0x44,0x37,0x1a,0xb1,0xca,0xbe,0x44,0x7d,0xab,0x79,0xbb, +0x9c,0x31,0x10,0xf5,0xc8,0xa9,0x40,0x00,0xc5,0xc3,0xc5,0xbb,0x75,0x3b,0x39,0xba, +0x10,0xc4,0x33,0x19,0xad,0xc3,0xc2,0x4d,0x81,0xab,0x75,0xba,0xc1,0xc3,0xc9,0xbb, +0x7d,0xbb,0x3e,0x3b,0x19,0x43,0x27,0x31,0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00, +0x9c,0xce,0xc9,0x33,0x8e,0xd2,0x6e,0x93,0xb1,0x23,0xd2,0xdb,0x90,0xdb,0x4f,0x1b, +0x29,0x9b,0x14,0xf5,0x76,0x98,0xca,0x8c,0xa6,0xec,0x6a,0xdb,0x93,0x12,0xd8,0xe3, +0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00,0xb2,0xdb,0x5c,0x9b,0x36,0xdb,0x18,0x0b, +0x45,0x15,0xb0,0xb0,0xc1,0x0c,0x80,0xdc,0x74,0xe2,0xbe,0xd2,0xce,0xdc,0x84,0xdb, +0x46,0xdb,0x2b,0x13,0x1b,0x35,0x76,0xc9,0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00, +0xc6,0xdb,0xa8,0xec,0x6c,0xd3,0x8f,0x1a,0xd0,0xe4,0xb2,0xdb,0x68,0xda,0x42,0xdb, +0x20,0x64,0x31,0x40,0x9c,0xec,0xc6,0xdd,0x90,0xd2,0x6a,0xe2,0xa5,0x1c,0xd2,0xdb, +0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00,0xa0,0xda,0x5a,0xdb,0x39,0x1c,0x18,0x0a, +0x4e,0xf6,0xb2,0x99,0xbe,0xd2,0x80,0xec,0x6e,0x93,0xae,0xdb,0xca,0xdb,0x92,0xdb, +0x56,0xdb,0x3b,0x1b,0x1e,0x52,0x56,0xf4,0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00, +0xb4,0x84,0xbc,0xe1,0x7c,0xdb,0x6c,0x94,0xac,0xdb,0xca,0xdb,0x96,0xe4,0x5a,0x9a, +0x3b,0x5b,0x1e,0x1a,0x56,0xab,0xb2,0x8d,0xbe,0xea,0x80,0xdb,0x68,0x9c,0xa2,0xdb, +0x9c,0x31,0x10,0xf6,0xc8,0x99,0x30,0x00,0xca,0xdb,0xa0,0xdb,0x62,0x9b,0x3f,0x1b, +0x1e,0x52,0x44,0xee,0xa2,0x98,0xc2,0xd3,0x8e,0xe4,0x66,0xd3,0x8e,0xda,0xc2,0xdc, +0xb2,0xdb,0x76,0xdb,0x4c,0xdb,0x2a,0xa4,0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00, +0x2f,0x88,0x82,0xe6,0xc1,0x1b,0xa8,0xda,0x6e,0xe3,0x72,0xdb,0xab,0x1a,0xc2,0xdb, +0x96,0xe3,0x62,0x9b,0x3d,0x5b,0x20,0xa3,0x54,0xa1,0xa8,0xd6,0xbe,0xe2,0x86,0xd3, +0x9c,0x31,0x10,0x86,0xc7,0x89,0x30,0x00,0x64,0xe3,0x8a,0x93,0xbe,0xdb,0xb6,0xdb, +0x82,0xdc,0x54,0xda,0x2c,0xa4,0x2d,0x81,0x7a,0xee,0xbe,0xd2,0xae,0xdb,0x74,0xdc, +0x6d,0x13,0x9a,0x9a,0xba,0xdc,0xa4,0xda,0x9c,0x31,0x10,0x86,0xc7,0x89,0x30,0x00, +0x74,0xdb,0x4b,0x1c,0x24,0x0a,0x3c,0xf5,0x8e,0x91,0xbe,0xdc,0xa2,0xdb,0x6e,0xdb, +0x74,0xdb,0x9e,0xd3,0xb6,0xec,0xa2,0x8b,0x74,0xe3,0x49,0x1b,0x24,0x52,0x48,0xf4, +0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00,0x96,0x8c,0xbc,0xe1,0x9c,0xd5,0x6e,0xda, +0x72,0xdb,0x98,0x9b,0xb2,0xdc,0xa4,0xda,0x7a,0xdc,0x4d,0x1b,0x28,0x5a,0x46,0xec, +0x90,0x8c,0xbc,0xe1,0xa2,0xd5,0x72,0xe2,0x9c,0x31,0x10,0x32,0xc7,0x89,0x20,0x00, +0x70,0xd3,0x90,0xe3,0xad,0x13,0xa8,0xe3,0x82,0xdb,0x52,0xdb,0x2c,0x4a,0x40,0xf5, +0x86,0x81,0xb6,0xeb,0xa6,0xd4,0x7a,0xe2,0x6e,0xd3,0x86,0xdb,0xa1,0x1b,0xa8,0x9b, +0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00,0x8e,0xdd,0x64,0x9a,0x3a,0x64,0x39,0x41, +0x70,0xb4,0xa9,0x0d,0xb0,0xe8,0x8a,0xd5,0x6e,0xe2,0x79,0x1b,0x90,0x5b,0xa3,0x1b, +0x9c,0xda,0x7f,0x1c,0x55,0x1b,0x38,0xa3,0x9c,0x31,0x10,0x53,0xb6,0x78,0x20,0x00, +0x21,0x33,0x91,0xae,0xd9,0xb2,0xc1,0xb9,0x7d,0xb7,0x69,0xb6,0x81,0xb8,0xa1,0xb8, +0xb9,0x25,0xa9,0xc7,0x69,0xa8,0x1d,0xc6,0x02,0x96,0x49,0xcc,0xaa,0x21,0xd1,0xca, +0x9c,0x31,0x10,0xae,0xb5,0x77,0x10,0x00,0xae,0x92,0x7a,0xe2,0x6f,0x14,0x82,0xda, +0x9f,0x1c,0xb0,0xd3,0xa0,0xe2,0x6a,0xdc,0x28,0xa3,0x13,0x49,0x4e,0xee,0xa3,0x0a, +0xc4,0xe3,0xaa,0xd4,0x82,0xe2,0x74,0xdc,0x9c,0x31,0x10,0x03,0xb4,0x57,0x10,0x00, +0x80,0xe2,0x98,0xcb,0xa6,0xab,0x96,0xcb,0x68,0xe3,0x36,0x9c,0x2b,0x92,0x5a,0xdd, +0x9a,0xd9,0xb8,0xdc,0xa8,0xd3,0x8d,0x23,0x83,0x1c,0x8a,0x92,0x8e,0xe4,0x78,0xd2, +0x9c,0x31,0x10,0xcc,0xb3,0x56,0x00,0x00,0x50,0xc6,0x3a,0xbb,0x56,0xa2,0x8c,0xca, +0xb2,0xa6,0xb0,0xc7,0x96,0xa9,0x82,0xc4,0x80,0xb7,0x7a,0xba,0x61,0x34,0x49,0x4b, +0x56,0x95,0x82,0xd5,0xa4,0x9b,0xa4,0xc3,0x9c,0x31,0x10,0x8f,0x92,0x45,0x00,0x00, +0xd0,0xce,0x86,0x99,0x62,0x64,0x65,0x13,0x78,0xa3,0x82,0x9c,0x80,0x4a,0x7c,0xaa, +0x7f,0x4d,0x80,0xe2,0x7b,0x13,0x75,0x1b,0x6e,0xdb,0x6e,0xe3,0x76,0xd3,0x83,0x1b, +0x9c,0x31,0x10,0x93,0x71,0x33,0x00,0x00,0xa7,0x5a,0x9c,0xa4,0x8f,0x8a,0x8e,0x25, +0x82,0xda,0x7d,0x22,0x75,0x55,0x5b,0x99,0x3f,0x1a,0x3e,0x5d,0x58,0xd9,0x7d,0x1c, +0xac,0x53,0xd1,0x9b,0xda,0xdc,0xbf,0x22,0x9c,0x31,0x10,0xbe,0x72,0x22,0x00,0x00, +0x88,0xd4,0x5a,0xac,0x3a,0xd9,0x38,0x56,0x60,0xf0,0xa2,0x5d,0xd5,0x1c,0xc9,0x28, +0x8e,0xe3,0x47,0x0d,0x1a,0xd0,0x2c,0xcd,0x77,0x1b,0xcd,0x1c,0xe9,0x0c,0xc9,0x1a, +0x9c,0x31,0x10,0xbe,0x72,0x22,0x00,0x00,0x84,0xa2,0x42,0xc9,0x2c,0xdc,0x46,0xa4, +0x78,0xd2,0xa4,0xde,0xbd,0x09,0xb8,0xe4,0x9c,0xc4,0x71,0x20,0x4c,0xc5,0x40,0x9a, +0x4c,0xdc,0x7c,0x5a,0xb4,0xd3,0xcc,0xa3,0x9c,0x31,0x10,0xbe,0x72,0x22,0x00,0x00, +0xaa,0xd4,0x66,0xe2,0x38,0x8b,0x3d,0x24,0x66,0xa1,0xa3,0x1d,0xc6,0x9a,0xba,0xd4, +0x8a,0x94,0x62,0xa3,0x56,0x9b,0x64,0x92,0x7c,0xdd,0x91,0x62,0x98,0xd5,0x9c,0x93, +0x9c,0x31,0x10,0x66,0x51,0x12,0x00,0x00,0xbd,0xc4,0x63,0x3b,0x29,0xb3,0x22,0xb7, +0x3a,0xc8,0x66,0x19,0x95,0x36,0xbd,0xc7,0x9d,0xb7,0x55,0x57,0x3a,0x08,0x5a,0x46, +0x8e,0xe9,0x96,0xc8,0x91,0x15,0x90,0x39,0x9c,0x31,0x10,0x64,0x43,0x12,0x00,0x00, +0x6d,0x92,0x45,0x9b,0x25,0x8b,0x42,0x63,0x6d,0x93,0x99,0x84,0xad,0xec,0xb9,0x92, +0x74,0xf4,0x0d,0xec,0x0d,0xd1,0x41,0xd3,0x65,0x93,0x4e,0x03,0x41,0xcc,0x4d,0x9b, +0x9c,0x31,0x10,0x46,0x42,0x33,0x00,0x00,0x42,0xdb,0x39,0xd2,0x35,0x5b,0x42,0x52, +0x62,0x13,0x49,0xe3,0x1a,0xd9,0x07,0x74,0x49,0xa5,0x66,0x52,0x71,0xcb,0x6d,0xdb, +0x7e,0x23,0xb6,0x1b,0xd1,0x52,0xad,0xdb,0x9c,0x31,0x10,0xe7,0x41,0x21,0x00,0x00, +0x6a,0x3b,0x25,0xc2,0x12,0xbb,0x3e,0x33,0x91,0x3a,0xaa,0xbb,0x88,0x48,0x7c,0xc6, +0x75,0xa5,0x7a,0x42,0x80,0xb1,0x9a,0xb5,0xa5,0xbc,0x85,0xb6,0x46,0x99,0x36,0x30, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_POWER_OFF.txt b/config/_default_cfg_src_/res/cn/SOUND_POWER_OFF.txt new file mode 100644 index 0000000..7b587ce --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_POWER_OFF.txt @@ -0,0 +1,190 @@ +0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00,0x7d,0xdd,0x7d,0xdd,0x86,0x1d,0x85,0xa1, +0xc7,0xa5,0xb5,0xd5,0x82,0x11,0x7d,0x69,0x91,0xd6,0x8a,0x16,0x9a,0x5c,0x8d,0x9e, +0xa9,0x08,0xaa,0x10,0xda,0x29,0x9e,0x16,0x9c,0x31,0x10,0xcd,0xa9,0x64,0x10,0x00, +0x80,0xed,0x82,0xed,0x88,0xed,0x8e,0xa9,0xdb,0x46,0x64,0xad,0xad,0x8d,0x70,0x2d, +0x41,0x8c,0x9e,0x4d,0xc5,0x4e,0x3a,0x8d,0x3d,0x2c,0x92,0xad,0x67,0x2d,0x72,0xcd, +0x9c,0x31,0x10,0xc6,0xa9,0x45,0x00,0x00,0x69,0x05,0x74,0xe5,0x87,0x05,0x80,0xe1, +0x6f,0x05,0x70,0xf1,0x6e,0xf5,0x78,0xf9,0x6c,0xf9,0x7f,0x05,0x82,0xd9,0xd5,0x2a, +0x5e,0x81,0x5f,0x71,0x7c,0x79,0x79,0x85,0x9c,0x31,0x10,0x74,0xb9,0x54,0x00,0x00, +0x76,0x74,0x81,0x56,0x88,0xa5,0x77,0x35,0x6a,0xd1,0x61,0x06,0x7a,0xd0,0x97,0x05, +0xae,0xf5,0x8e,0xe5,0x49,0x05,0x1e,0xf5,0x4e,0xf5,0xf3,0x04,0xfa,0xe5,0xd5,0x02, +0x9c,0x31,0x10,0xa5,0xc8,0x56,0x10,0x00,0x62,0x8a,0x39,0xb3,0x36,0x2a,0xaf,0xaa, +0xbc,0x4c,0xa5,0x8a,0x8a,0x4b,0xb1,0x8c,0x4e,0xaa,0x00,0x73,0x65,0xad,0xec,0x09, +0xbf,0xcb,0x88,0x0d,0x8f,0x89,0x4c,0xb3,0x9c,0x31,0x10,0x8f,0xda,0x66,0x10,0x00, +0x3e,0xd5,0x81,0x16,0xae,0xd4,0x99,0x05,0x7e,0xe5,0x96,0xf5,0x63,0x15,0x34,0x99, +0x7f,0x66,0xb6,0x94,0x93,0x55,0x78,0xb5,0x9f,0x15,0x67,0x15,0x2a,0x7a,0x7f,0x96, +0x9c,0x31,0x10,0x9d,0xdb,0x67,0x10,0x00,0xbe,0xa4,0x8d,0x35,0x74,0xd5,0xa0,0xf5, +0x69,0x11,0x22,0x9a,0x87,0x65,0xbe,0x94,0x85,0x26,0x74,0xe5,0xae,0xd5,0x69,0x31, +0x16,0x86,0x8f,0x84,0xc2,0x95,0x7b,0x15,0x9c,0x31,0x10,0x44,0xdb,0x77,0x20,0x00, +0x7b,0x05,0xb6,0xb5,0x65,0x55,0x10,0x41,0x9f,0xb5,0xb4,0xa5,0x6e,0xc5,0x89,0x76, +0xba,0x64,0x5f,0x55,0x0c,0xc1,0xa1,0x45,0xb4,0xc6,0x5e,0xf4,0x9f,0x15,0xb4,0xb5, +0x9c,0x31,0x10,0xc2,0xdb,0x78,0x20,0x00,0x67,0x0a,0x16,0xcc,0x93,0x4c,0xb0,0x6a, +0x61,0x2c,0xa7,0x0b,0xac,0xb2,0x67,0x13,0x24,0xf5,0x85,0x4b,0xac,0x52,0x65,0x2d, +0xa9,0x2a,0xa4,0x8a,0x71,0x15,0x2f,0x14,0x9c,0x31,0x10,0x4a,0xdb,0x88,0x20,0x00, +0x72,0x58,0xac,0x65,0x6a,0x9c,0xa6,0x98,0xa0,0xdd,0x71,0xdb,0x36,0x2a,0x66,0xa1, +0xac,0x25,0x6a,0x5b,0xa6,0xda,0xa1,0x1c,0x75,0x9b,0x3e,0x1a,0x5a,0x6c,0xac,0x55, +0x9c,0x31,0x10,0xe0,0xcb,0x89,0x20,0x00,0x5a,0x1a,0xca,0xdc,0xbd,0x5b,0x82,0x12, +0x0d,0x93,0x15,0x9d,0xe1,0x52,0x62,0x5b,0xbe,0x94,0xcd,0x1a,0x82,0x13,0x25,0xcb, +0x05,0x8c,0xd5,0xd2,0x6a,0x1c,0xb6,0x93,0x9c,0x31,0x10,0x52,0xdb,0x98,0x20,0x00, +0xa5,0x1a,0x7d,0x9d,0x59,0x94,0x3d,0x49,0xa2,0x5a,0x7a,0x1d,0x96,0x99,0xa5,0x24, +0x82,0x1a,0x5d,0x5c,0x39,0x09,0x9e,0xd4,0x7e,0x54,0x93,0x19,0xa9,0x1d,0x85,0x9b, +0x9c,0x31,0x10,0x71,0xdb,0x89,0x30,0x00,0x65,0x5b,0x39,0x02,0x93,0x0d,0x86,0x52, +0x8b,0x2b,0xa9,0x64,0x85,0xea,0x69,0xab,0x39,0x23,0x86,0xd4,0x81,0xda,0x92,0xe4, +0xa5,0x63,0x8e,0x2a,0x75,0xa3,0x3d,0x74,0x9c,0x31,0x10,0x77,0xcb,0x98,0x20,0x00, +0x5f,0x13,0x7d,0xe1,0xa2,0xe5,0xd5,0xa1,0xae,0x74,0x89,0xeb,0x05,0xb4,0x3a,0xe2, +0x75,0xa3,0x9a,0x63,0xdd,0x62,0xba,0x24,0x99,0xe3,0x19,0xec,0x1e,0xe9,0x6d,0xa5, +0x9c,0x31,0x10,0x2b,0xca,0x98,0x10,0x00,0x8f,0x2b,0xe1,0x6a,0xbe,0x6c,0xa6,0x23, +0x21,0xeb,0x17,0x69,0x61,0xa5,0x86,0xe2,0xdd,0xa3,0xca,0x9c,0xae,0x63,0x32,0x62, +0x07,0x2a,0x59,0xa6,0x7e,0x61,0xd9,0xe4,0x9c,0x31,0x10,0xb4,0xd9,0x98,0x10,0x00, +0xa9,0x1b,0x99,0x1b,0x5e,0xda,0x3d,0x6c,0x68,0xa3,0x7f,0x23,0xaa,0xe3,0xad,0x23, +0x9b,0x1c,0x65,0x19,0x3d,0x6d,0x62,0xdb,0x7f,0x22,0xaa,0xdc,0xaf,0x1a,0x9d,0x1c, +0x9c,0x31,0x10,0x76,0xd8,0x87,0x20,0x00,0x6b,0x68,0x3b,0x36,0x5c,0xb5,0x7c,0xd5, +0xa7,0x11,0xb1,0x0d,0x9f,0x4d,0x71,0x8d,0x3d,0x16,0x56,0xf8,0x7a,0xd1,0xa5,0x2d, +0xb3,0x09,0xa3,0x29,0x75,0x48,0x3e,0x92,0x9c,0x31,0x10,0xe2,0xc7,0x97,0x10,0x00, +0x20,0xec,0x6e,0x62,0xc7,0x1d,0xeb,0x15,0xcd,0x19,0x71,0x1d,0x00,0x61,0x18,0xe5, +0x64,0x61,0xc1,0x21,0xec,0xd9,0xd5,0x19,0x7d,0x59,0x08,0x61,0x0d,0x2c,0x5c,0x61, +0x9c,0x31,0x10,0x75,0xc7,0x86,0x10,0x00,0xbb,0x15,0xec,0xd1,0xd8,0x95,0x89,0x21, +0x16,0x25,0x05,0x34,0x4c,0x6a,0xad,0x1d,0xe8,0xcd,0xe0,0x95,0x9b,0x21,0x2c,0x1d, +0x07,0x29,0x3c,0x65,0x95,0x21,0xd8,0xd9,0x9c,0x31,0x10,0x40,0xc6,0x65,0x00,0x00, +0xe4,0x61,0xb0,0x89,0x54,0x29,0x1b,0x92,0x2a,0x38,0x6d,0x95,0xb8,0x6d,0xe1,0x69, +0xcd,0x69,0x7e,0x69,0x2d,0x69,0x1a,0x4d,0x4c,0x6d,0x9a,0x8d,0xd7,0x4d,0xdd,0x6d, +0x9c,0x31,0x10,0xd2,0xc5,0x55,0x00,0x00,0x9d,0xa9,0x43,0x71,0x19,0x45,0x3b,0xad, +0x86,0x8d,0xcc,0x31,0xe0,0xb1,0xac,0x8d,0x52,0x4d,0x1e,0x89,0x35,0xad,0x7a,0x48, +0xc2,0x56,0xde,0x90,0xb5,0x85,0x5d,0x55,0x9c,0x31,0x10,0xcf,0xc5,0x43,0x00,0x00, +0x22,0x88,0x31,0x89,0x73,0x49,0xbb,0x51,0xdc,0xb4,0xba,0x6d,0x65,0x4d,0x26,0xb0, +0x2f,0x71,0x6d,0x4d,0xb5,0x69,0xd9,0xb1,0xbe,0x6d,0x6c,0x4d,0x2b,0xb1,0x2f,0x71, +0x9c,0x31,0x10,0x45,0xc5,0x44,0x00,0x00,0x6a,0x49,0xb0,0x69,0xd6,0x8d,0xbf,0x51, +0x71,0x4d,0x2e,0xa6,0x2e,0x95,0x68,0x4d,0xaf,0x6d,0xd6,0x91,0xc0,0x6d,0x74,0x4d, +0x2f,0xad,0x2d,0x71,0x64,0x4d,0xac,0x89,0x9c,0x31,0x10,0x95,0xc4,0x32,0x00,0x00, +0xd5,0xc9,0xc2,0xa6,0x78,0x30,0x32,0x55,0x2c,0xa5,0x63,0xa5,0xab,0xd6,0xd5,0x45, +0xc3,0x26,0x78,0xa4,0x32,0xd6,0x2c,0xa8,0x62,0xa5,0xaa,0x42,0xd3,0xba,0xc3,0x29, +0x9c,0x31,0x10,0xdd,0xc4,0x42,0x00,0x00,0x7b,0x68,0x34,0xae,0x2c,0x50,0x61,0x6d, +0xa8,0x8d,0xd2,0x75,0xc3,0x6d,0x7c,0x48,0x36,0xb1,0x2d,0x50,0x60,0x8e,0xa6,0x89, +0xd0,0x71,0xc2,0x71,0x7e,0x4d,0x3a,0x8e,0x9c,0x31,0x10,0x95,0xc4,0x32,0x00,0x00, +0x2f,0x29,0x5f,0xb4,0xa3,0xc5,0xcd,0x2a,0xc1,0x35,0x83,0x31,0x40,0xc2,0x31,0x29, +0x5b,0x35,0x9b,0xd1,0xc5,0xaa,0xbf,0xc8,0x8c,0x26,0x4f,0x55,0x37,0x95,0x54,0xc9, +0x9c,0x31,0x10,0xe1,0xb4,0x33,0x00,0x00,0x9d,0x95,0xf3,0x55,0xf7,0x49,0xac,0x85, +0x43,0x81,0x04,0x55,0x20,0x89,0x7e,0x95,0xd5,0x41,0xeb,0x75,0xbe,0x34,0x6a,0x78, +0x24,0x86,0x1c,0x75,0x5c,0xa6,0xae,0x65,0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00, +0xd9,0x99,0xcb,0x44,0x90,0x91,0x50,0x75,0x2d,0x69,0x43,0x8a,0x81,0x55,0xb6,0x65, +0xc5,0x65,0xaa,0x85,0x76,0x76,0x42,0x61,0x37,0xa9,0x59,0x69,0x8a,0xa1,0xad,0x14, +0x9c,0x31,0x10,0x83,0xa5,0x54,0x00,0x00,0xf8,0x9b,0xe4,0xa2,0x97,0x1b,0x42,0xdb, +0x1a,0xdb,0x22,0xdb,0x4a,0xec,0x88,0xa3,0xb9,0x11,0xbe,0x92,0x9d,0x63,0x86,0xa4, +0x78,0xdb,0x7a,0x93,0x7b,0x1b,0x7a,0x5b,0x9c,0x31,0x10,0x7e,0x95,0x43,0x00,0x00, +0x60,0xa5,0x5d,0x66,0x4e,0xc4,0x51,0x09,0x74,0xb2,0xb8,0xf5,0xde,0x89,0xbf,0x49, +0x6e,0xc4,0x3b,0x0d,0x38,0xcd,0x4b,0x09,0x62,0xd2,0x98,0xf1,0xcf,0x0d,0xb2,0x8c, +0x9c,0x31,0x10,0xf2,0x85,0x55,0x10,0x00,0x7f,0x1b,0x48,0x95,0x3a,0xa3,0x4a,0xd0, +0x6e,0x33,0xa2,0x9d,0xc8,0xdc,0xad,0x1a,0x74,0xda,0x50,0xd3,0x3e,0xd2,0x3b,0x1c, +0x4e,0xda,0x73,0x22,0x92,0xd4,0x90,0xd2,0x9c,0x31,0x10,0x48,0x74,0x65,0x20,0x00, +0x81,0x3c,0x6d,0x49,0x4d,0xbd,0x38,0xbc,0x49,0x3b,0x7e,0x44,0xa2,0xc0,0xaa,0xa4, +0x9a,0x4a,0x81,0x3d,0x65,0x32,0x5a,0xdc,0x81,0xa2,0xac,0xc9,0xbd,0xb9,0xbd,0x3e, +0x9c,0x31,0x10,0x47,0x65,0x67,0x30,0x00,0xc2,0x77,0x74,0x79,0x24,0x76,0x2a,0x67, +0x59,0x89,0x99,0x65,0xba,0x75,0xb3,0xb9,0x8a,0x67,0x53,0x46,0x54,0x76,0x4c,0x58, +0x7c,0x48,0xac,0x95,0x8a,0xe7,0x82,0x4b,0x9c,0x31,0x10,0x5f,0x65,0x77,0x30,0x00, +0x5a,0x58,0x42,0x61,0x43,0x84,0x71,0x7a,0x7c,0x55,0x82,0x98,0x73,0x5e,0x32,0x99, +0x3a,0x70,0x45,0x53,0x65,0x7c,0x84,0x84,0x8d,0x5a,0x7c,0xc9,0x74,0x36,0x74,0x57, +0x9c,0x31,0x10,0x7a,0x65,0x88,0x40,0x00,0x7a,0x99,0xb5,0x59,0xb9,0x65,0xa6,0xea, +0x85,0x96,0x75,0x5a,0x62,0x1e,0x56,0x11,0x45,0x18,0x62,0x9c,0x65,0xd8,0x65,0xac, +0x61,0xd4,0x96,0x59,0x65,0x71,0x92,0x1e,0x9c,0x31,0x10,0x74,0x65,0x77,0x40,0x00, +0x8b,0x6a,0x8d,0x4e,0x62,0xb1,0x5b,0x61,0x33,0x4d,0x4a,0x91,0x79,0x59,0x94,0x4d, +0x85,0x85,0x9a,0x8d,0x8c,0x4d,0x85,0xad,0x7b,0x49,0xd2,0x71,0xa1,0x6d,0xac,0x89, +0x9c,0x31,0x10,0x58,0x75,0x79,0x40,0x00,0x94,0xa5,0xa3,0x19,0xaa,0xd1,0x80,0x9d, +0x84,0xed,0x7a,0xd9,0x42,0xd1,0x33,0x69,0x40,0x9d,0x40,0x4c,0x3b,0x20,0x70,0x64, +0x9a,0xdd,0xa1,0x66,0x99,0x22,0x92,0x52,0x9c,0x31,0x10,0xd0,0x75,0x89,0x40,0x00, +0x55,0xde,0x79,0xee,0x91,0x55,0x96,0x95,0xa5,0x1d,0xa9,0xe5,0xe6,0xe5,0xa0,0xcc, +0x35,0x90,0x2a,0x28,0x65,0xf1,0x85,0xd5,0xa5,0xd1,0x85,0xe1,0x75,0xa5,0x85,0x59, +0x9c,0x31,0x10,0x6a,0x76,0x89,0x40,0x00,0x83,0xb7,0x9c,0x56,0x32,0x87,0x83,0xb7, +0x6a,0x08,0x53,0x97,0x39,0xc4,0x0c,0x3b,0x34,0x6a,0x9a,0xa2,0xb2,0x35,0x9c,0x7a, +0x81,0xa8,0x33,0x34,0x1a,0x76,0xd2,0x98,0x9c,0x31,0x10,0x76,0xb5,0x78,0x40,0x00, +0x8f,0x3b,0x94,0x2b,0x88,0x42,0x6e,0xb5,0x56,0x39,0x62,0xa3,0x90,0x48,0xbe,0xb9, +0xb8,0x38,0x7c,0xa3,0x3c,0xb9,0x29,0x57,0x64,0x18,0xbb,0x17,0xee,0x45,0xc6,0x37, +0x9c,0x31,0x10,0x09,0xc7,0x88,0x30,0x00,0x75,0x13,0x50,0x9c,0x4c,0xe3,0x6e,0xd2, +0x9e,0xe4,0xb9,0x1b,0xa8,0x9b,0x7d,0x2a,0x4e,0x8b,0x3e,0xe6,0x60,0xda,0x96,0xc9, +0xba,0xf5,0xb2,0x93,0x86,0xd3,0x54,0x63,0x9c,0x31,0x10,0x8c,0xc6,0x98,0x30,0x00, +0x3c,0xd4,0x54,0xa9,0x8a,0x93,0xb6,0x9c,0xba,0xa3,0x93,0x1a,0x60,0xe2,0x39,0x53, +0x46,0xde,0x7d,0x21,0xb2,0xd3,0xc1,0x1b,0xa1,0x1b,0x6f,0x1b,0x3c,0xa3,0x3a,0x93, +0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00,0x6c,0xa3,0xaa,0xda,0xc7,0x25,0xae,0x9a, +0x7c,0xd4,0x42,0xa3,0x34,0xa1,0x60,0xcc,0xa0,0xed,0xc6,0xca,0xb8,0x62,0x87,0x1b, +0x4a,0x54,0x2f,0x25,0x50,0x9a,0x94,0xd3,0x9c,0x31,0x10,0x37,0xc6,0x78,0x40,0x00, +0xc7,0x2a,0xc0,0xcd,0x95,0x6b,0x54,0x53,0x2d,0x51,0x44,0xf3,0x87,0x04,0xc1,0x34, +0xc8,0xca,0xa1,0x22,0x63,0x22,0x2d,0x5b,0x36,0xce,0x7a,0xea,0xbc,0x82,0xce,0xf3, +0x9c,0x31,0x10,0x05,0xc5,0x88,0x40,0x00,0xac,0xaa,0x6c,0xc3,0x2e,0xd5,0x2c,0x9d, +0x6c,0xe1,0xb6,0x9a,0xd4,0xc3,0xb8,0xc3,0x7b,0x2d,0x34,0x5c,0x24,0xb0,0x5c,0xbb, +0xae,0x44,0xd6,0xb5,0xbe,0x39,0x82,0xc3,0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00, +0x3a,0x51,0x20,0xed,0x50,0xce,0xa4,0xe3,0xd7,0x19,0xc8,0x9a,0x93,0x1a,0x46,0x14, +0x1d,0x26,0x42,0xda,0x96,0xdb,0xd4,0xda,0xd2,0x9c,0x9d,0x1a,0x4e,0x5d,0x19,0x92, +0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00,0x34,0xe3,0x8a,0xd2,0xd0,0xe4,0xd8,0x9a, +0xa9,0x1c,0x5a,0xa3,0x1b,0x91,0x2a,0xde,0x7f,0x1b,0xcc,0xdd,0xda,0xd9,0xb1,0x1a, +0x66,0xda,0x21,0x64,0x24,0xce,0x70,0xea,0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00, +0xc4,0xc9,0xdc,0xe2,0xb6,0xd5,0x73,0x22,0x26,0xe5,0x1e,0xd1,0x62,0xe3,0xba,0xda, +0xdc,0xd4,0xbe,0xa3,0x7f,0x14,0x30,0x63,0x1a,0x98,0x54,0x95,0xae,0xa4,0xdc,0xd4, +0x9c,0x31,0x10,0x94,0xc6,0x88,0x30,0x00,0xc8,0x59,0x8b,0x1b,0x38,0x10,0x16,0xed, +0x4a,0x8c,0xa2,0xe4,0xda,0xd1,0xcc,0x5b,0x95,0x1b,0x42,0x13,0x19,0x1e,0x42,0x99, +0x99,0x12,0xd7,0x22,0xd0,0x95,0x9b,0x5b,0x9c,0x31,0x10,0x30,0xc6,0x89,0x40,0x00, +0x4c,0x5c,0x19,0x53,0x36,0xe1,0x8c,0xd3,0xd3,0x23,0xd4,0xd4,0xa3,0x5b,0x56,0xa3, +0x19,0x89,0x2e,0xe3,0x82,0xd3,0xcf,0x24,0xd8,0xdb,0xab,0x1b,0x60,0xda,0x1d,0x5b, +0x9c,0x31,0x10,0xa6,0xc5,0x78,0x30,0x00,0x26,0x9e,0x76,0xe6,0xc6,0x98,0xdc,0xd1, +0xb4,0xb9,0x6d,0x37,0x24,0xee,0x22,0x05,0x6a,0xe3,0xbc,0x95,0xdc,0xd9,0xba,0x2a, +0x77,0x48,0x2c,0x48,0x1e,0x40,0x5e,0xaa,0x9c,0x31,0x10,0xb8,0xc6,0x79,0x40,0x00, +0xb4,0xe3,0xda,0xd4,0xc0,0x5b,0x83,0x23,0x36,0x0a,0x1a,0xf3,0x50,0x84,0xa6,0xf3, +0xd8,0xc3,0xc6,0x6a,0x8d,0x0b,0x42,0x13,0x1d,0x25,0x46,0x9a,0x9a,0xdb,0xd4,0xda, +0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00,0xcc,0x95,0x99,0x1a,0x4e,0x5d,0x1d,0x42, +0x3a,0xf1,0x8c,0xc3,0xce,0xeb,0xd0,0xd5,0xa1,0x5a,0x5c,0xeb,0x23,0x48,0x30,0xe6, +0x7c,0xd3,0xc7,0x24,0xd4,0xd9,0xad,0x22,0x9c,0x31,0x10,0x93,0xc6,0x79,0x30,0x00, +0x6b,0x1a,0x2a,0xf4,0x2a,0xc4,0x6c,0xf2,0xb8,0xcb,0xd4,0xeb,0xb6,0x94,0x7b,0x1b, +0x36,0x64,0x22,0x99,0x5a,0x94,0xaa,0xe3,0xd5,0x0b,0xc0,0x63,0x88,0xdb,0x42,0x0a, +0x9c,0x31,0x10,0x93,0xc6,0x79,0x30,0x00,0x23,0x34,0x4a,0xc3,0x9a,0xeb,0xce,0xca, +0xc6,0xab,0x97,0x0b,0x52,0xa4,0x25,0x43,0x3e,0xf1,0x88,0xc3,0xc8,0xeb,0xcc,0xcc, +0xa3,0x22,0x60,0xdb,0x2b,0x51,0x34,0xe5,0x9c,0x31,0x10,0x94,0xc6,0x88,0x30,0x00, +0x78,0xdb,0xbe,0xe4,0xce,0xd0,0xac,0xe3,0x71,0x13,0x32,0xee,0x2a,0x89,0x64,0xea, +0xb0,0xca,0xd2,0xed,0xb6,0x8c,0x80,0xe2,0x3e,0x52,0x28,0xe9,0x56,0x8e,0xa2,0xe3, +0x9c,0x31,0x10,0x94,0xc6,0x88,0x30,0x00,0xd0,0xd4,0xc0,0xa1,0x8f,0x14,0x4a,0x5a, +0x27,0x1e,0x48,0xd9,0x92,0xdb,0xcb,0x19,0xc6,0x9c,0x99,0x1b,0x58,0xa4,0x29,0x48, +0x3a,0xec,0x80,0xd4,0xc3,0x2c,0xcc,0xd3,0x9c,0x31,0x10,0xa1,0xc5,0x89,0x30,0x00, +0xa7,0x4a,0x6a,0xab,0x31,0x5c,0x32,0x14,0x6e,0xda,0xb4,0xa3,0xcc,0xca,0xb0,0xb4, +0x78,0xbb,0x3a,0x43,0x2c,0xc1,0x5e,0xb5,0xa6,0xba,0xcc,0xbc,0xba,0x31,0x88,0xcb, +0x9c,0x31,0x10,0xaf,0xc6,0x89,0x20,0x00,0x48,0x4b,0x2b,0x2d,0x4e,0xd2,0x96,0xe3, +0xc8,0xca,0xc2,0xa4,0x95,0x13,0x56,0xab,0x2d,0x42,0x42,0xeb,0x86,0xcc,0xc2,0xeb, +0xc8,0xd4,0xa1,0x22,0x67,0x13,0x31,0x2b,0x9c,0x31,0x10,0xaf,0xc6,0x89,0x20,0x00, +0x38,0xcc,0x76,0xe1,0xb9,0x14,0xca,0xe2,0xa8,0xdc,0x72,0xdb,0x3a,0xa4,0x32,0xd9, +0x66,0x9d,0xac,0xda,0xca,0xe4,0xb2,0x9a,0x80,0xe3,0x46,0x0a,0x31,0x2c,0x58,0xcb, +0x9c,0x31,0x10,0xaf,0xc6,0x89,0x20,0x00,0x9c,0xe3,0xc8,0xd3,0xba,0xa3,0x8d,0x0c, +0x52,0xab,0x2f,0x4a,0x4c,0xea,0x8e,0xcd,0xc2,0xe2,0xc0,0xd4,0x95,0x22,0x5e,0xdb, +0x33,0x1b,0x42,0xd5,0x80,0xe2,0xbc,0xdb,0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00, +0xc4,0xda,0xa0,0xdd,0x6a,0xd2,0x38,0xb5,0x38,0xc8,0x70,0xac,0xb4,0xd3,0xc8,0xa4, +0xa8,0x93,0x76,0xe3,0x40,0x4a,0x34,0xf3,0x64,0x85,0xa6,0xe2,0xc6,0xdc,0xb0,0x92, +0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00,0x81,0x1b,0x4a,0x54,0x33,0x1c,0x58,0xd8, +0x9a,0xdd,0xc4,0xdb,0xb8,0xdb,0x8b,0x1a,0x56,0xe4,0x35,0x49,0x4e,0xe5,0x8c,0xd3, +0xbf,0x1a,0xba,0xda,0x93,0x1b,0x61,0x1b,0x9c,0x31,0x10,0xa8,0xc6,0x78,0x20,0x00, +0x3b,0x2c,0x48,0xc4,0x82,0xf2,0xba,0xcb,0xc0,0xeb,0x9a,0xd4,0x69,0x1a,0x3c,0xac, +0x42,0xd0,0x76,0xe5,0xb2,0xdb,0xc2,0xdc,0xa0,0x9a,0x70,0xdc,0x42,0x52,0x3e,0xf4, +0x9c,0x31,0x10,0x12,0xc5,0x78,0x20,0x00,0x6c,0x89,0xaa,0xd5,0xc2,0x97,0xa6,0x56, +0x76,0xa9,0x48,0x25,0x3d,0x4d,0x66,0xb1,0xa2,0xb9,0xc2,0xa5,0xac,0x3a,0x7c,0xb5, +0x50,0x39,0x3d,0x03,0x5c,0xe7,0x98,0x98,0x9c,0x31,0x10,0xa8,0xc6,0x78,0x20,0x00, +0xc0,0xec,0xb0,0xcb,0x85,0x2a,0x54,0xdb,0x3b,0x5a,0x56,0xdd,0x92,0xda,0xbc,0xdc, +0xb4,0xda,0x89,0x1c,0x5b,0x1a,0x3c,0xe4,0x52,0xcb,0x8a,0xea,0xb8,0xd4,0xb6,0xe2, +0x9c,0x31,0x10,0xe9,0xb5,0x78,0x20,0x00,0x9e,0xa9,0x45,0x46,0x04,0xda,0x20,0x93, +0x8a,0xca,0xea,0xa6,0xee,0xd8,0xa4,0x96,0x4e,0xc8,0x0a,0x36,0x1c,0xc4,0x80,0x2b, +0xe4,0xc5,0xf0,0xb9,0xaa,0x34,0x56,0xa9,0x9c,0x31,0x10,0x92,0xb6,0x78,0x10,0x00, +0x10,0xb5,0x19,0xda,0x75,0x16,0xd5,0xc6,0xed,0xa9,0xb1,0x45,0x5d,0xa8,0x14,0xa6, +0x16,0x4b,0x6d,0x34,0xd2,0x27,0xed,0xb8,0xb1,0x38,0x61,0xb6,0x1d,0x27,0x1a,0x27, +0x9c,0x31,0x10,0x6f,0xb5,0x77,0x20,0x00,0x6a,0xe9,0xcd,0x0c,0xec,0xa5,0xb6,0x9a, +0x66,0xda,0x24,0x9b,0x1b,0x91,0x62,0xe5,0xc5,0x14,0xea,0xdb,0xba,0xe3,0x6b,0x1b, +0x28,0xdb,0x1b,0x52,0x62,0xdd,0xc3,0x1b,0x9c,0x31,0x10,0x02,0xb5,0x67,0x00,0x00, +0xe6,0x8b,0xb8,0xeb,0x6d,0x13,0x31,0x1a,0x1f,0x5c,0x5c,0xcc,0xb8,0xe2,0xe0,0xd3, +0xb8,0xe4,0x6e,0xe2,0x37,0x12,0x24,0xed,0x5f,0x0a,0xb4,0xab,0xdc,0x93,0xb8,0xa4, +0x9c,0x31,0x10,0x8c,0xb4,0x56,0x10,0x00,0x72,0xd1,0x3d,0xa3,0x2a,0x5b,0x5a,0xe2, +0xaa,0x1c,0xd4,0x8c,0xba,0xa4,0x78,0xe8,0x41,0x54,0x2e,0x0b,0x59,0x2e,0xa4,0x59, +0xd3,0x52,0xba,0xac,0x78,0x8b,0x45,0x2a,0x9c,0x31,0x10,0x9c,0xb4,0x65,0x00,0x00, +0x34,0x19,0x57,0x95,0x9c,0xa4,0xc9,0x5d,0xba,0x9d,0x7c,0x95,0x49,0x28,0x3a,0xd9, +0x5b,0xa1,0x9c,0x52,0xc7,0x70,0xb7,0x0d,0x78,0xa2,0x4a,0xe5,0x43,0x0c,0x60,0xaa, +0x9c,0x31,0x10,0x40,0xb3,0x55,0x00,0x00,0xa1,0x53,0xc6,0x20,0xac,0x94,0x6c,0x1d, +0x45,0x9a,0x4c,0x22,0x70,0x5c,0xa6,0x9a,0xbc,0x0c,0xa0,0xb3,0x6b,0x52,0x4e,0x9c, +0x57,0x5b,0x76,0x62,0xa0,0x4d,0xb1,0x23,0x9c,0x31,0x10,0xf2,0xa3,0x44,0x00,0x00, +0xb2,0x61,0x5b,0x42,0x31,0xa5,0x46,0x64,0x77,0x54,0xb1,0x51,0xc7,0x1c,0xa3,0x63, +0x61,0x0b,0x42,0x5b,0x54,0x5b,0x7b,0x5a,0xa6,0x64,0xb6,0x4b,0x9a,0x53,0x69,0x6a, +0x9c,0x31,0x10,0x8a,0x92,0x43,0x00,0x00,0x22,0x1a,0x40,0xd9,0x7d,0x64,0xb7,0x55, +0xcc,0x51,0xa2,0x9d,0x5e,0xa5,0x43,0x15,0x5a,0xa9,0x7e,0xdd,0x9e,0x85,0xaa,0xaa, +0x92,0xed,0x6c,0xcd,0x5f,0x9d,0x6a,0xe1,0x9c,0x31,0x10,0x29,0x72,0x33,0x00,0x00, +0x7d,0x93,0xb4,0xd3,0xdd,0x24,0xba,0x6b,0x60,0x9a,0x31,0x03,0x4c,0x53,0x79,0x6b, +0x93,0x63,0x9c,0xcd,0x9d,0x1a,0x82,0xa1,0x67,0x0c,0x6b,0x24,0x7a,0x98,0x82,0x9b, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_POWER_ON.txt b/config/_default_cfg_src_/res/cn/SOUND_POWER_ON.txt new file mode 100644 index 0000000..a3ba039 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_POWER_ON.txt @@ -0,0 +1,190 @@ +0x9c,0x31,0x10,0x70,0x45,0x44,0x00,0x00,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb, +0x6b,0xbb,0x84,0x33,0x82,0xa2,0x8b,0xb4,0x4c,0x32,0x9b,0xd4,0x54,0x0a,0x5c,0x24, +0x8c,0xca,0x33,0x35,0x2c,0xaa,0x59,0xbc,0x9c,0x31,0x10,0xd3,0x99,0x97,0x30,0x00, +0x7b,0xbb,0x73,0xbb,0x7b,0xbb,0x7b,0xbb,0x8c,0x3b,0x8b,0x42,0xde,0x5b,0x6d,0xc4, +0x9b,0xa5,0x93,0x0a,0x5b,0xa2,0x73,0xca,0x8c,0x54,0x9c,0xd3,0x4a,0xcc,0x7b,0x9b, +0x9c,0x31,0x10,0xa7,0xa8,0x98,0x30,0x00,0x5d,0xd2,0x61,0x9b,0x7e,0x23,0xba,0x99, +0xdb,0x25,0x9d,0xb4,0x86,0x13,0x79,0xd2,0x49,0xdc,0x3d,0xda,0x55,0x9b,0x51,0xdc, +0x4d,0xdb,0x56,0x1b,0x65,0x9c,0x71,0x5b,0x9c,0x31,0x10,0xf5,0x88,0x88,0x30,0x00, +0x63,0xc3,0x7b,0x23,0x6c,0x1b,0x94,0x4b,0x73,0x53,0x73,0xa3,0x93,0x23,0xa3,0x43, +0x6c,0x3b,0x7b,0x43,0x54,0x63,0x4a,0x4c,0x25,0x19,0x13,0x63,0x0e,0xf3,0x62,0xbc, +0x9c,0x31,0x10,0xc4,0x9a,0x98,0x40,0x00,0x64,0x5b,0x73,0x53,0x85,0x11,0x7b,0x24, +0xb3,0xc3,0x4b,0x5a,0x94,0xe4,0x64,0x9b,0x82,0x9d,0x64,0x13,0xa3,0x99,0xa6,0x14, +0xcb,0x91,0xb4,0xa3,0xb1,0xe5,0xc4,0x9a,0x9c,0x31,0x10,0xd9,0x99,0xa9,0x40,0x00, +0x8b,0xbd,0xc3,0xa1,0x94,0x34,0x91,0x33,0xa6,0x4b,0x7e,0x2c,0x8c,0x99,0x84,0x34, +0x68,0xa3,0x63,0xa1,0x7b,0xbc,0x6e,0x44,0x64,0xc4,0xa5,0x3a,0x4c,0x41,0x99,0xb4, +0x9c,0x31,0x10,0xe1,0x99,0xaa,0x50,0x00,0x7e,0x79,0x7b,0x68,0x9b,0x53,0x75,0xb7, +0xab,0x78,0x7c,0x65,0x85,0x9a,0x9c,0x98,0xc4,0x67,0xa3,0x43,0xac,0x7b,0x6c,0xa5, +0x68,0x58,0x83,0x9a,0x8a,0x83,0xb4,0x89,0x9c,0x31,0x10,0x3a,0xa9,0xaa,0x40,0x00, +0x83,0x77,0x79,0x87,0x64,0x66,0x53,0xb8,0x6c,0x77,0x95,0xa7,0xaa,0x68,0x8d,0x34, +0x4a,0x3c,0x5b,0x45,0x21,0x85,0x78,0xb9,0x83,0x88,0xe0,0x61,0x8e,0x8e,0x54,0x75, +0x9c,0x31,0x10,0x01,0xba,0x99,0x40,0x00,0x51,0x43,0x42,0x22,0x7d,0xb4,0x9e,0x0b, +0xc1,0x8b,0x82,0x2c,0x69,0x99,0x3a,0xe3,0x3d,0xd5,0x86,0x5a,0xb1,0x59,0xce,0x15, +0x89,0x42,0x5a,0x0b,0x1a,0x5b,0x39,0x6b,0x9c,0x31,0x10,0xfa,0xca,0x99,0x40,0x00, +0x99,0x0a,0xa1,0xa3,0xb1,0xf4,0x7e,0x95,0x65,0x89,0x3e,0xe5,0x6e,0x32,0xa9,0x62, +0xa6,0x14,0xad,0xcb,0x72,0x53,0x51,0x8c,0x2d,0xf4,0x83,0x4a,0xa9,0xea,0xba,0x24, +0x9c,0x31,0x10,0x64,0xcb,0xa9,0x30,0x00,0xa5,0x99,0x6a,0x1d,0x35,0xa1,0x3e,0x26, +0x9d,0x20,0xaa,0x55,0xc9,0x61,0x9a,0x65,0x59,0xdd,0x1d,0x59,0x5e,0xd5,0x9d,0x4a, +0xb2,0xd1,0xc9,0x25,0x7e,0x69,0x4d,0xd9,0x9c,0x31,0x10,0xd2,0xca,0xa9,0x40,0x00, +0x10,0x19,0x8b,0x11,0x90,0xd5,0xc3,0x25,0xbc,0x98,0x76,0x5e,0x3a,0x99,0x19,0x21, +0xa5,0xa5,0x89,0xa1,0xce,0x65,0xad,0x55,0x69,0xe1,0x23,0x22,0x2a,0xf2,0xb5,0x29, +0x9c,0x31,0x10,0xc0,0xcb,0xa8,0x40,0x00,0x81,0xd9,0xd9,0x95,0xa1,0xd5,0x61,0xe1, +0x12,0x25,0x56,0xd8,0xa9,0x4e,0x8e,0x59,0xd1,0x61,0x96,0x18,0x55,0x9d,0x09,0xa6, +0x76,0x88,0xa1,0x50,0x9a,0x9a,0xc5,0x64,0x9c,0x31,0x10,0xf9,0xca,0xa9,0x30,0x00, +0x92,0x95,0x51,0x19,0x0d,0x19,0x8e,0xc5,0x95,0x24,0x9f,0x22,0xc0,0x99,0x8a,0x99, +0x51,0x59,0x04,0x95,0xa2,0x92,0x8c,0xe4,0x9e,0xe5,0xc4,0xd9,0x7e,0x59,0x51,0x9d, +0x9c,0x31,0x10,0xd2,0xca,0xa9,0x40,0x00,0x0c,0xd0,0xae,0x22,0x89,0x28,0x9a,0xe1, +0xc5,0x15,0x7e,0x59,0x49,0xa1,0x11,0x18,0xb5,0xed,0x89,0x21,0x9a,0x99,0xc5,0x15, +0x7e,0x1d,0x45,0xe1,0x15,0x14,0xb5,0xf5,0x9c,0x31,0x10,0x68,0xc9,0xa9,0x40,0x00, +0x88,0x44,0x8f,0x2a,0xc8,0xb4,0x82,0x43,0x3d,0xc3,0x1c,0xb1,0xb1,0xeb,0x90,0xb5, +0x8a,0xaa,0xc0,0xb4,0x8a,0x43,0x3d,0xbb,0x18,0xb2,0xb1,0xdb,0x98,0xbc,0x82,0xb3, +0x9c,0x31,0x10,0x43,0xc9,0xa9,0x30,0x00,0xc1,0x3b,0x91,0xc3,0x3a,0x3b,0x10,0xb1, +0xaa,0x65,0xa4,0xb3,0x7a,0x33,0xbd,0x3c,0x9d,0xc2,0x3e,0x3c,0x0c,0xa9,0xa2,0x5d, +0xb0,0xb3,0x76,0x32,0xb1,0x3c,0xa9,0x3b,0x9c,0x31,0x10,0xc2,0xd9,0x9a,0x30,0x00, +0x62,0x37,0x40,0x15,0x8a,0x6a,0xa1,0x46,0x7a,0x17,0x91,0xb7,0x99,0x36,0x6a,0x37, +0x38,0x96,0x82,0x5b,0xa9,0x44,0x7e,0x18,0x85,0xc7,0x99,0x36,0x71,0xb7,0x38,0x96, +0x9c,0x31,0x10,0xd3,0xd8,0x99,0x30,0x00,0x75,0x66,0xb0,0x61,0x89,0x14,0x7c,0xdb, +0x98,0x9a,0x7f,0x23,0x3c,0x0a,0x67,0x65,0xb2,0xa1,0x97,0x0c,0x78,0xa2,0x8e,0xdb, +0x82,0xdb,0x42,0x09,0x61,0x36,0xac,0x92,0x9c,0x31,0x10,0xdd,0xc8,0x99,0x40,0x00, +0xc5,0x1b,0x76,0x9c,0x88,0xdb,0x81,0x1b,0x14,0x5a,0x42,0xf3,0xd0,0x85,0xd0,0xea, +0x80,0xd4,0x7a,0xdb,0x73,0x1b,0x20,0xa3,0x50,0xe1,0xc6,0x8d,0xcf,0x22,0x8a,0xdb, +0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00,0x78,0xdb,0x67,0x1b,0x26,0xec,0x5a,0xd0, +0xc0,0x9d,0xca,0xe2,0x90,0xdc,0x77,0x1b,0x5b,0x1b,0x29,0x6c,0x64,0xca,0xc2,0xaa, +0xca,0xd4,0x92,0xe2,0x75,0x1b,0x4e,0xe3,0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00, +0x2b,0x92,0x6e,0xd6,0xc6,0xe0,0xca,0xd5,0x8e,0xe2,0x6d,0x13,0x46,0xa4,0x31,0x49, +0x76,0xec,0xc9,0x13,0xc8,0x9b,0x90,0x9b,0x69,0x1b,0x3a,0x1b,0x33,0x54,0x82,0xe9, +0x9c,0x31,0x10,0x9e,0xc7,0x99,0x30,0x00,0xcf,0x0c,0xc8,0xe2,0x8c,0x93,0x5e,0xe3, +0x32,0x0a,0x3b,0x2d,0x8c,0x92,0xd3,0x24,0xc4,0xd3,0x88,0xdb,0x57,0x1b,0x2e,0x9c, +0x46,0xe1,0x96,0xd5,0xd2,0xe1,0xc0,0xd4,0x9c,0x31,0x10,0x8c,0xc6,0x98,0x30,0x00, +0x84,0xe2,0x4d,0x53,0x28,0xec,0x4e,0x8a,0xa2,0xe4,0xd6,0xd2,0xbc,0xe4,0x7e,0xda, +0x45,0x1c,0x29,0x59,0x58,0xdd,0xa6,0xe1,0xd2,0x95,0xb6,0xd9,0x7d,0x14,0x42,0xa3, +0x9c,0x31,0x10,0x7f,0xc6,0x97,0x10,0x00,0x2d,0x8c,0x5c,0xe9,0xa5,0x15,0xcc,0x9e, +0xb2,0x9c,0x7a,0xdd,0x48,0x9d,0x3b,0x15,0x60,0xe5,0x97,0x19,0xb6,0x9d,0xa8,0x9d, +0x85,0x1d,0x64,0x5d,0x53,0x59,0x5c,0xe1,0x9c,0x31,0x10,0xab,0xa5,0x64,0x00,0x00, +0x70,0xe2,0xe9,0x0c,0xf8,0x55,0xcf,0x31,0x99,0x1a,0x44,0xe1,0x12,0xd4,0x28,0xdd, +0x76,0xe1,0xbc,0xe5,0xea,0xd6,0xe8,0xdd,0xa4,0x9d,0x4c,0xd9,0x1a,0xdd,0x26,0xdd, +0x9c,0x31,0x10,0x78,0xa3,0x43,0x00,0x00,0x6a,0x90,0xbc,0x6e,0xe9,0x4d,0xd1,0x28, +0x89,0x55,0x3f,0x69,0x19,0x71,0x34,0xad,0x81,0x71,0xc8,0x4a,0xd9,0x4d,0xb2,0x70, +0x70,0x6e,0x36,0x4d,0x27,0x69,0x55,0x6c,0x9c,0x31,0x10,0x3a,0xa2,0x22,0x00,0x00, +0x9a,0x4e,0xbf,0x7a,0xb9,0x4c,0x92,0x52,0x60,0x09,0x3d,0x34,0x48,0x6e,0x76,0x31, +0xa1,0x78,0xb2,0x8a,0xa5,0x68,0x85,0x6e,0x5e,0x50,0x4e,0xae,0x60,0x15,0x7f,0x4d, +0x9c,0x31,0x10,0x55,0x92,0x22,0x00,0x00,0xb4,0xa3,0xc3,0x43,0xaa,0xf5,0x73,0x12, +0x46,0xe3,0x42,0x1a,0x5c,0xd3,0x86,0x89,0xa4,0xdd,0xaa,0xe8,0x90,0xe5,0x71,0x9a, +0x5f,0x0c,0x5d,0x65,0x6e,0x51,0x87,0x6c,0x9c,0x31,0x10,0x29,0x72,0x33,0x00,0x00, +0xea,0xdb,0xde,0xa2,0xa8,0xdb,0x6b,0x13,0x2e,0x93,0x20,0xd3,0x4e,0x9b,0x92,0xdb, +0xb2,0x9b,0xba,0x49,0xa0,0xb6,0x63,0x12,0x30,0xdb,0x34,0xaa,0x62,0xda,0x88,0xdc, +0x9c,0x31,0x10,0x29,0x72,0x33,0x00,0x00,0xb3,0x1a,0xba,0xa4,0x8b,0x12,0x4f,0x1b, +0x3d,0x5b,0x56,0x9a,0x73,0x1c,0x9a,0xdb,0xae,0x9c,0x93,0x12,0x64,0xaa,0x55,0x5b, +0x61,0xad,0x65,0x12,0x7c,0xeb,0x97,0x0c,0x9c,0x31,0x10,0xce,0x62,0x44,0x00,0x00, +0xa5,0xc2,0x72,0x4a,0x4c,0xbc,0x51,0xc2,0x3e,0xbb,0x66,0xb4,0x95,0xc4,0x9a,0x43, +0x75,0xaa,0x5a,0x2b,0x5c,0xca,0x55,0x5b,0x65,0xc3,0x8c,0x2b,0xa7,0x32,0x8d,0xce, +0x9c,0x31,0x10,0xad,0x43,0x44,0x10,0x00,0x64,0x31,0x7c,0x98,0x3b,0x88,0x05,0x7a, +0x54,0x44,0xb3,0x7a,0x84,0x25,0x0b,0x62,0x54,0x68,0x4b,0x67,0x53,0x5b,0x6b,0x18, +0xdc,0x94,0x9e,0x6e,0x2d,0x21,0x74,0xdd,0x9c,0x31,0x10,0x3a,0x54,0x66,0x30,0x00, +0x92,0x67,0x93,0x85,0xa3,0x56,0xc3,0x99,0xbb,0x77,0x81,0x77,0x5a,0x87,0x63,0x74, +0x73,0x47,0x74,0x9b,0x8d,0x95,0x93,0x37,0x92,0xa3,0x95,0x9e,0xc5,0x1a,0xd3,0x94, +0x9c,0x31,0x10,0x90,0x44,0x67,0x30,0x00,0x9a,0x87,0xec,0x68,0xb5,0x65,0x2d,0xa7, +0x22,0x67,0x84,0x35,0xa3,0xe8,0xa4,0x39,0xaa,0x69,0x94,0xb7,0x8b,0x55,0x5b,0x57, +0x84,0x84,0x94,0xab,0x1b,0x74,0x3a,0x26,0x9c,0x31,0x10,0xad,0x54,0x77,0x30,0x00, +0x63,0x8b,0x51,0x57,0x98,0x69,0xa1,0xd5,0xc9,0x38,0x6c,0x87,0x93,0x94,0x92,0x69, +0x73,0x97,0x78,0x91,0x79,0x69,0x9c,0x96,0x95,0x58,0x76,0x6d,0x9a,0x87,0x7d,0x91, +0x9c,0x31,0x10,0x18,0x54,0x68,0x40,0x00,0x42,0xdd,0x85,0x21,0x87,0x15,0x64,0xa1, +0x94,0x65,0x70,0xd1,0x54,0x9d,0x85,0x25,0x56,0x95,0x77,0x1d,0x69,0x32,0x96,0x16, +0xd6,0xd5,0xc3,0x19,0xe9,0x9c,0xc6,0x1c,0x9c,0x31,0x10,0x88,0x54,0x88,0x40,0x00, +0x85,0xa5,0x96,0x71,0x85,0x89,0xb9,0xdd,0x66,0x25,0x91,0x55,0x42,0x25,0x45,0xe6, +0x29,0x22,0x46,0x5a,0x79,0xda,0x91,0x55,0xc6,0xd8,0xd9,0x9c,0xa5,0xe1,0xa6,0x71, +0x9c,0x31,0x10,0xde,0x65,0x89,0x30,0x00,0x73,0x57,0x84,0xa5,0x6c,0x57,0x6b,0x77, +0x74,0x97,0x7d,0x37,0x8b,0x97,0xb2,0x56,0x93,0x88,0xb2,0x88,0xa2,0x56,0x7b,0xb6, +0x6b,0x28,0x41,0xaa,0x42,0x62,0x02,0x47,0x9c,0x31,0x10,0xd0,0x75,0x89,0x40,0x00, +0x96,0xb1,0x96,0x56,0x74,0xda,0x52,0xe6,0x58,0xd1,0x56,0xd9,0x59,0xa5,0x76,0x21, +0x8a,0x95,0x84,0xe1,0x87,0x19,0x64,0x95,0x16,0x61,0x11,0xa5,0x60,0xdd,0x77,0x51, +0x9c,0x31,0x10,0xdb,0xa5,0x88,0x40,0x00,0x7e,0x5b,0x7d,0x98,0x75,0x13,0x71,0xc3, +0x75,0x5a,0x88,0x4d,0x95,0xb4,0x8d,0x55,0x75,0x67,0x56,0xa9,0x4d,0x45,0x7d,0x83, +0xc9,0x8b,0xe1,0x7c,0xa0,0x75,0x2d,0x63,0x9c,0x31,0x10,0x94,0xc6,0x88,0x30,0x00, +0x5b,0x22,0x68,0xd6,0x8c,0xe3,0xb0,0xd0,0xa8,0x63,0x80,0xd4,0x56,0x14,0x4a,0xe2, +0x66,0x9b,0x94,0xe2,0xb9,0x13,0xb0,0x6b,0x87,0x4b,0x54,0x2b,0x3e,0xcd,0x58,0xec, +0x9c,0x31,0x10,0xb8,0xc6,0x79,0x40,0x00,0x8d,0x12,0xb8,0xa3,0xba,0x5b,0x92,0xdb, +0x58,0x5c,0x35,0x0c,0x4b,0x21,0x82,0xd3,0xb4,0xe3,0xc0,0xd4,0xa1,0x1b,0x66,0xa3, +0x37,0x81,0x3c,0xb3,0x75,0x0b,0xb2,0xec,0x9c,0x31,0x10,0xa6,0xc5,0x78,0x30,0x00, +0xc8,0xa4,0xb0,0xd7,0x73,0x34,0x37,0x38,0x30,0x9d,0x68,0xe5,0xae,0x93,0xcc,0xd2, +0xb6,0xbb,0x7a,0xb8,0x36,0x6d,0x2a,0x80,0x60,0x54,0xac,0xb5,0xd4,0x4d,0xc0,0x39, +0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00,0x82,0xdb,0x36,0xe3,0x22,0x98,0x58,0xdc, +0xaa,0x9b,0xd8,0xa6,0xc6,0x91,0x87,0x24,0x34,0x9a,0x1a,0xa1,0x52,0xcd,0xaa,0xac, +0xda,0x94,0xca,0x98,0x8b,0x1b,0x32,0x59,0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00, +0x16,0xeb,0x4e,0xd6,0xaa,0xe4,0xde,0xd3,0xce,0xa0,0x8b,0x13,0x32,0x1a,0x12,0xec, +0x4c,0x8d,0xaa,0xe3,0xe4,0x93,0xd0,0xa0,0x8b,0x14,0x2e,0x19,0x0f,0x2c,0x4a,0x4d, +0x9c,0x31,0x10,0x84,0xc6,0x89,0x50,0x00,0xac,0xe3,0xe6,0xd3,0xd2,0xa2,0x89,0x53, +0x2c,0x1a,0x0c,0xec,0x4c,0x8c,0xae,0xeb,0xe8,0x8b,0xd2,0x6a,0x89,0x0b,0x2c,0x62, +0x0c,0xa3,0x4c,0xd5,0xb2,0xa3,0xe8,0xd4,0x9c,0x31,0x10,0x0b,0xc6,0x88,0x50,0x00, +0xd0,0x68,0x85,0x0b,0x28,0x60,0x0c,0x9a,0x50,0x9e,0xb4,0xdc,0xea,0x9d,0xce,0xa1, +0x81,0x12,0x24,0x61,0x0c,0x98,0x54,0xd6,0xba,0x9b,0xec,0xde,0xcc,0x61,0x7f,0x13, +0x9c,0x31,0x10,0x0c,0xc6,0x79,0x50,0x00,0x22,0x72,0x0c,0x91,0x56,0x9c,0xbe,0x9b, +0xec,0xe5,0xc8,0x53,0x79,0x1b,0x1e,0x6a,0x0c,0xd9,0x58,0x9c,0xc0,0xa3,0xec,0xdd, +0xc6,0xa4,0x77,0x13,0x1e,0xb3,0x10,0xc8,0x9c,0x31,0x10,0xb6,0xc5,0x79,0x50,0x00, +0x5c,0xd7,0xc2,0x96,0xec,0xdc,0xc4,0x19,0x75,0x46,0x1e,0xd8,0x12,0x22,0x5e,0xc6, +0xc2,0xa5,0xea,0xc9,0xc2,0x3a,0x73,0x38,0x1c,0xea,0x12,0x83,0x62,0xe5,0xc4,0x96, +0x9c,0x31,0x10,0x2c,0xc4,0x88,0x50,0x00,0xea,0xcb,0xc0,0x3d,0x71,0x3c,0x1e,0xde, +0x16,0x99,0x64,0xd8,0xc4,0xa2,0xe8,0xd2,0xbe,0x35,0x6f,0x43,0x1f,0x4e,0x18,0xa3, +0x66,0xd0,0xc4,0xaa,0xe6,0xc9,0xbc,0xbd,0x9c,0x31,0x10,0x39,0xc5,0x78,0x50,0x00, +0x6f,0x38,0x1d,0x6e,0x18,0x8a,0x68,0xe1,0xc6,0x95,0xe6,0xe2,0xbc,0x98,0x6b,0x55, +0x1d,0x3c,0x1a,0x9e,0x6c,0xd4,0xc6,0xa7,0xe4,0xc1,0xba,0xb6,0x6a,0xc5,0x1d,0x4a, +0x9c,0x31,0x10,0xb6,0xc5,0x79,0x50,0x00,0x1c,0x9b,0x6c,0xe5,0xc8,0xa8,0xe2,0xc4, +0xb8,0xb7,0x6a,0xc5,0x1f,0x38,0x1e,0xab,0x6e,0xd6,0xc6,0xa7,0xe2,0xc5,0xb9,0x36, +0x6c,0xc6,0x21,0x48,0x20,0xab,0x6c,0xd6,0x9c,0x31,0x10,0xb6,0xc5,0x79,0x50,0x00, +0xc2,0xa8,0xe0,0xb4,0xb8,0xc6,0x6e,0xb6,0x23,0x47,0x1e,0x9c,0x68,0xd6,0xc0,0xa9, +0xe0,0xc4,0xb8,0xb6,0x70,0xb5,0x25,0x59,0x20,0x8a,0x68,0xd5,0xc0,0xa8,0xe0,0xc5, +0x9c,0x31,0x10,0x10,0xc4,0x78,0x40,0x00,0xba,0xb6,0x71,0x33,0x27,0x5c,0x20,0x1d, +0x64,0xc4,0xbc,0xb8,0xde,0xb1,0xba,0x46,0x74,0xa8,0x2c,0xec,0x20,0x1a,0x60,0xd2, +0xb4,0xa8,0xdc,0xc1,0xbe,0x49,0x7b,0x28,0x9c,0x31,0x10,0x30,0xc6,0x89,0x40,0x00, +0x30,0xad,0x1e,0x8a,0x5a,0xe2,0xb0,0xd3,0xdb,0x22,0xc0,0x9c,0x83,0x1b,0x36,0x64, +0x1e,0x91,0x54,0xe3,0xa8,0xd3,0xd8,0xe3,0xc4,0x54,0x89,0x1b,0x3c,0x5b,0x1e,0xd9, +0x9c,0x31,0x10,0x37,0xc6,0x78,0x40,0x00,0x4c,0xde,0xa0,0xd2,0xd6,0xe5,0xc8,0x54, +0x8f,0x22,0x44,0x49,0x21,0x2a,0x46,0xce,0x98,0xe2,0xd0,0xdd,0xca,0x92,0x99,0x22, +0x4e,0x4a,0x21,0x2d,0x3e,0xd4,0x8e,0xe2,0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00, +0xce,0xd4,0xce,0xa1,0x9d,0x1b,0x56,0x93,0x23,0x5d,0x3a,0x99,0x86,0xdc,0xca,0xd2, +0xce,0xa3,0xa1,0x13,0x5c,0xa5,0x27,0x43,0x36,0xe9,0x7e,0xcc,0xc4,0xe2,0xd0,0xd4, +0x9c,0x31,0x10,0xa8,0xc6,0x78,0x20,0x00,0xa7,0x1b,0x64,0xe4,0x2b,0x49,0x32,0xec, +0x76,0xd3,0xbf,0x22,0xd2,0xd6,0xad,0x1a,0x6d,0x22,0x31,0x1a,0x2e,0xdd,0x6c,0xd9, +0xb9,0x24,0xd3,0x1b,0xb1,0x22,0x71,0x1a,0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00, +0x32,0xec,0x2c,0xcd,0x68,0xe1,0xb4,0xdd,0xd2,0xda,0xb4,0xe2,0x77,0x13,0x38,0xb5, +0x2c,0xc9,0x62,0xea,0xae,0xd5,0xd3,0x22,0xb8,0x9b,0x7c,0xdb,0x3c,0x64,0x2a,0xd9, +0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00,0x5a,0x9c,0xa6,0xdb,0xd0,0xd1,0xbc,0xa3, +0x82,0xd5,0x40,0x5a,0x2a,0xe2,0x54,0xcd,0xa0,0xe2,0xcc,0xd3,0xbc,0x63,0x88,0xdd, +0x48,0x51,0x2d,0x2d,0x50,0xcb,0x98,0xe2,0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00, +0xca,0x8b,0xc0,0x64,0x8e,0xd4,0x4e,0x5a,0x2d,0x5e,0x4c,0xd8,0x92,0xdc,0xc8,0xd3, +0xc2,0xa6,0x8f,0x12,0x52,0xa2,0x2f,0x44,0x4a,0xe8,0x8c,0xd5,0xc4,0xa3,0xc2,0x95, +0x9c,0x31,0x10,0xa6,0xc5,0x78,0x30,0x00,0x95,0x31,0x58,0xca,0x33,0x04,0x46,0xe8, +0x88,0x8a,0xc0,0xe7,0xc2,0x87,0x99,0x50,0x5e,0xbc,0x35,0x24,0x44,0xcd,0x82,0x94, +0xbc,0xd9,0xc4,0x83,0x9b,0x56,0x61,0x2b,0x9c,0x31,0x10,0x29,0xc5,0x79,0x30,0x00, +0x35,0x45,0x40,0xaa,0x7e,0xb5,0xbc,0xc8,0xc4,0x94,0x9d,0x59,0x63,0x18,0x36,0xe6, +0x42,0x89,0x7c,0xd3,0xb8,0xb9,0xc4,0xb3,0x9f,0x4b,0x67,0x26,0x38,0xe8,0x40,0x07, +0x9c,0x31,0x10,0x29,0xc5,0x79,0x30,0x00,0x78,0xe5,0xb6,0x98,0xc4,0xd4,0xa0,0xac, +0x6b,0x25,0x3c,0x58,0x40,0x85,0x76,0x57,0xb2,0x98,0xc2,0xd6,0xa0,0x9b,0x6d,0x44, +0x40,0x49,0x40,0x94,0x72,0x59,0xae,0x97,0x9c,0x31,0x10,0x12,0xc5,0x78,0x20,0x00, +0xc2,0xd7,0xa2,0x9d,0x6e,0xc2,0x40,0x39,0x40,0xb2,0x72,0xcc,0xac,0xa6,0xc0,0xd7, +0xa2,0x99,0x71,0x43,0x44,0x39,0x42,0xc4,0x70,0x3d,0xaa,0xb3,0xc0,0xc8,0xa2,0x99, +0x9c,0x31,0x10,0x4b,0xb6,0x68,0x20,0x00,0x61,0xe5,0x0d,0x18,0x09,0xe6,0x61,0x9c, +0xd1,0xb2,0xf9,0xd9,0xc1,0x88,0x61,0xd6,0x14,0x96,0x0d,0xe8,0x61,0x0a,0xcd,0xd4, +0xf5,0xb6,0xbd,0x29,0x61,0xc6,0x14,0xa6,0x9c,0x31,0x10,0x77,0xb5,0x67,0x20,0x00, +0x11,0x2d,0x64,0x8c,0xcc,0xe9,0xf5,0x1a,0xbc,0x9d,0x61,0x11,0x18,0x1a,0x17,0x25, +0x68,0x93,0xce,0xe2,0xf2,0xda,0xbc,0x9d,0x5f,0x1a,0x16,0x12,0x19,0x2e,0x6c,0x89, +0x9c,0x31,0x10,0x77,0xb5,0x67,0x20,0x00,0xd0,0xec,0xf0,0xca,0xb4,0xa4,0x5b,0x12, +0x18,0x1a,0x1f,0x26,0x74,0xd1,0xd2,0xea,0xeb,0x0a,0xac,0xe5,0x55,0x12,0x1a,0x19, +0x29,0x26,0x7e,0xd3,0xd2,0xe2,0xe2,0xc9,0x9c,0x31,0x10,0x77,0xb5,0x67,0x20,0x00, +0xa4,0xa4,0x51,0x14,0x1e,0x59,0x32,0xe5,0x86,0x93,0xd2,0xe3,0xdb,0x0b,0x9a,0xa2, +0x4d,0x15,0x20,0x59,0x3a,0xe5,0x8e,0x92,0xd4,0xe3,0xd2,0xcc,0x8e,0xa9,0x47,0x15, +0x9c,0x31,0x10,0x03,0xb4,0x57,0x10,0x00,0x24,0x12,0x47,0x34,0x98,0x4b,0xd2,0xda, +0xca,0xd4,0x88,0x61,0x47,0x5c,0x2c,0x03,0x51,0x34,0x9c,0x8c,0xd1,0x21,0xc0,0xa3, +0x7c,0x95,0x43,0x22,0x32,0x13,0x5b,0x63,0x9c,0x31,0x10,0x38,0xb4,0x56,0x00,0x00, +0xa2,0x64,0xcd,0x53,0xb8,0xda,0x76,0x9b,0x3f,0x1c,0x36,0x13,0x67,0x64,0xac,0x59, +0xcc,0xd4,0xa8,0xdb,0x64,0xd3,0x3b,0x23,0x44,0x0b,0x7b,0x2b,0xb8,0xca,0xc5,0x1b, +0x9c,0x31,0x10,0x10,0xb3,0x35,0x00,0x00,0x94,0x4b,0x54,0x33,0x3d,0xcc,0x57,0x03, +0x93,0xcc,0xbf,0x08,0xb3,0xcc,0x7b,0x2c,0x4d,0xa2,0x4c,0x73,0x6d,0x8b,0x9d,0x83, +0xb3,0x4c,0x9e,0x8b,0x71,0x62,0x56,0x93,0x9c,0x31,0x10,0x6f,0xa2,0x44,0x00,0x00, +0x3c,0x0c,0x76,0x5a,0xb7,0x5a,0xca,0x1c,0x9e,0x4b,0x5b,0x63,0x3d,0x9b,0x55,0x1c, +0x87,0xa3,0xb0,0x52,0xb1,0x6b,0x89,0x15,0x5e,0x1a,0x52,0x61,0x68,0x5c,0x8c,0x54, +0x9c,0x31,0x10,0x8a,0x92,0x43,0x00,0x00,0xc7,0x1c,0xbc,0xa8,0x7f,0x19,0x48,0xde, +0x42,0x59,0x6c,0xd4,0x9a,0xed,0xad,0x1a,0x9a,0xa0,0x74,0xe0,0x5c,0xa2,0x61,0x19, +0x7a,0xd8,0x93,0x26,0x98,0xe2,0x8d,0x15,0x9c,0x31,0x10,0x8b,0x71,0x23,0x00,0x00, +0x63,0x73,0x35,0x5b,0x44,0xa3,0x80,0x62,0xaf,0x9c,0xae,0x4e,0x91,0x20,0x6a,0xda, +0x59,0x15,0x67,0x44,0x89,0xa8,0x9f,0x5c,0x92,0x94,0x7e,0x6b,0x6b,0x82,0x67,0x2c, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_REFUSE.txt b/config/_default_cfg_src_/res/cn/SOUND_REFUSE.txt new file mode 100644 index 0000000..b911fcb --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_REFUSE.txt @@ -0,0 +1,605 @@ +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x59,0x15,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x59,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x15,0x55,0x95,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x51,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x59,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x51,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x56,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x15,0x55,0x55,0x55,0x15,0x55,0x15,0x55,0x55,0x55,0x55,0x55,0x65,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x95,0x55,0x45,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x65,0x55,0x55,0x55,0x15,0x55, +0x65,0x55,0x15,0x55,0x55,0x55,0x55,0x55,0x45,0x55,0x95,0x55,0x95,0x55,0x95,0x15, +0x9c,0x31,0x10,0x74,0x10,0x00,0x00,0x00,0xb5,0x55,0x96,0x55,0xa6,0x55,0xb0,0x55, +0xa4,0x55,0x70,0x95,0x7e,0x56,0x89,0x15,0x91,0x59,0x6d,0x55,0x78,0x15,0xbf,0x55, +0xc6,0x55,0x81,0x55,0x9a,0x59,0xb6,0x55,0x9c,0x31,0x10,0x74,0x10,0x00,0x00,0x00, +0xb1,0x56,0xbe,0x15,0x75,0x65,0x60,0x55,0x67,0x51,0x72,0x15,0xaa,0x55,0x98,0x55, +0x8e,0x56,0xbf,0x95,0xd6,0x55,0xa5,0x55,0x7c,0x55,0xa7,0x59,0xc2,0x65,0xd8,0x95, +0x9c,0x31,0x10,0x95,0x94,0x31,0x22,0x11,0x7e,0xd5,0x7e,0xd5,0x7c,0xd5,0x74,0xd5, +0x66,0xd5,0x58,0xd5,0x46,0xd5,0x36,0xc5,0x26,0x28,0x18,0xea,0x12,0x98,0x0e,0xd5, +0x10,0xd5,0x12,0xd5,0x13,0x15,0x12,0xd5,0x9c,0x31,0x10,0x05,0x95,0x21,0x11,0x11, +0x14,0xed,0x14,0xf4,0x16,0xf1,0x18,0xd4,0x18,0xf1,0x18,0xf0,0x1b,0x11,0x1c,0xcd, +0x19,0x0d,0x18,0xf1,0x20,0xf1,0x20,0xcc,0x1e,0xed,0x20,0xf1,0x25,0x09,0x22,0x69, +0x9c,0x31,0x10,0x4e,0xb8,0x64,0x33,0x21,0x6d,0x0d,0x70,0x6d,0xa5,0x86,0x78,0xac, +0x19,0x0d,0x66,0xed,0xba,0xed,0x64,0xed,0x18,0xed,0x7a,0xed,0xb4,0xed,0x50,0xed, +0x24,0xed,0x92,0xed,0xb2,0xed,0x3e,0xed,0x9c,0x31,0x10,0x99,0xb5,0x32,0x22,0x20, +0x2d,0x15,0x9e,0xa9,0xa2,0xe5,0x2e,0x91,0x3d,0x54,0xae,0xa1,0x94,0xd5,0x24,0x91, +0x4f,0x19,0xb7,0x12,0x82,0xd5,0x22,0xe5,0x69,0x15,0xb8,0xc4,0x66,0x95,0x20,0xe5, +0x9c,0x31,0x10,0x04,0xb4,0x32,0x22,0x20,0x7c,0x80,0xb5,0x15,0x52,0xd5,0x28,0xd5, +0x92,0x85,0xad,0x11,0x3a,0x95,0x37,0x52,0xa6,0x58,0x98,0xa5,0x2f,0x15,0x4f,0x10, +0xae,0xe0,0x82,0x55,0x27,0x15,0x5e,0xea,0x9c,0x31,0x10,0x8b,0xb4,0x33,0x22,0x20, +0xb9,0x96,0x76,0x55,0x1e,0xd5,0x70,0xd5,0xc3,0x84,0x68,0x55,0x21,0x14,0x82,0x40, +0xc1,0x55,0x5a,0x95,0x2d,0x15,0x94,0x56,0xb4,0xd5,0x4a,0x55,0x3b,0x56,0xa6,0x65, +0x9c,0x31,0x10,0x04,0xb4,0x32,0x22,0x20,0xa6,0xd4,0x3a,0x95,0x4b,0x65,0xb4,0xa1, +0x96,0x95,0x30,0x95,0x5f,0x29,0xbf,0x12,0x84,0x95,0x2c,0xd2,0x72,0xd5,0xc1,0x54, +0x70,0x95,0x2e,0xd5,0x88,0x80,0xbf,0x15,0x9c,0x31,0x10,0x34,0xb5,0x42,0x33,0x21, +0x5f,0x6d,0x36,0x88,0x9c,0x12,0xb7,0x95,0x4e,0x4d,0x40,0x8c,0xab,0x52,0xab,0x71, +0x40,0x6d,0x50,0x90,0xb8,0x70,0x9b,0x4d,0x38,0x6d,0x63,0x92,0xc0,0x8c,0x89,0x4c, +0x9c,0x31,0x10,0x4e,0xb4,0x32,0x22,0x10,0x32,0xd5,0x76,0xd5,0xc3,0x58,0x74,0x51, +0x34,0xd5,0x8a,0x80,0xc1,0x15,0x62,0x96,0x3b,0x15,0x9c,0x56,0xb9,0x11,0x52,0x95, +0x45,0x11,0xac,0xa5,0xac,0xd4,0x44,0x95,0x9c,0x31,0x10,0x04,0xb4,0x32,0x22,0x20, +0x55,0x54,0xb8,0xe1,0x9c,0x95,0x3c,0xd5,0x67,0x69,0xc1,0x12,0x8a,0xd9,0x38,0xd5, +0x7a,0xd5,0xc3,0x05,0x78,0x95,0x38,0xd5,0x8c,0x80,0xc1,0x15,0x66,0x95,0x3f,0x15, +0x9c,0x31,0x10,0x8f,0xb4,0x32,0x12,0x10,0x9e,0x95,0xba,0xd2,0x56,0x95,0x49,0x12, +0xae,0x98,0xae,0xa5,0x48,0x95,0x59,0x51,0xba,0xe1,0x9e,0x55,0x40,0xd5,0x69,0x25, +0xc3,0x14,0x8e,0x51,0x3c,0xd4,0x7c,0xd5,0x9c,0x31,0x10,0xc1,0xb4,0x33,0x22,0x10, +0xc5,0x44,0x7a,0x95,0x3c,0xd5,0x8e,0x81,0xc3,0x55,0x6a,0x55,0x43,0x15,0xa0,0x56, +0xbb,0x15,0x58,0x95,0x4d,0x55,0xae,0xa4,0xae,0xe4,0x4c,0x95,0x5b,0x54,0xba,0xe1, +0x9c,0x31,0x10,0x76,0xb3,0x22,0x21,0x10,0xa1,0x55,0x44,0x65,0x6d,0xa9,0xc3,0xa2, +0x90,0x15,0x40,0x56,0x7e,0x55,0xc5,0x85,0x7e,0x14,0x41,0x55,0x91,0x00,0xc3,0x96, +0x6d,0x15,0x46,0x95,0xa2,0x0a,0xbc,0x61,0x9c,0x31,0x10,0x34,0xb5,0x42,0x33,0x21, +0x5e,0x6d,0x50,0x8c,0xb1,0x72,0xb1,0x71,0x51,0x6d,0x5e,0x90,0xbc,0x70,0xa3,0x6d, +0x48,0x6e,0x70,0x8d,0xc4,0x35,0x91,0x75,0x44,0x50,0x81,0x6c,0xc5,0x6a,0x7f,0x6c, +0x9c,0x31,0x10,0x6e,0xb3,0x32,0x21,0x10,0x45,0x55,0x93,0x11,0xc2,0x95,0x6e,0x15, +0x4a,0x95,0xa3,0x16,0xbb,0x51,0x60,0x15,0x54,0x95,0xb1,0x25,0xb0,0x55,0x54,0x15, +0x61,0x90,0xbc,0x61,0xa2,0x59,0x4b,0x52,0x9c,0x31,0x10,0x76,0xb3,0x22,0x21,0x10, +0x71,0xa9,0xc2,0x92,0x92,0x15,0x47,0x55,0x82,0x95,0xc4,0x84,0x81,0x45,0x48,0x55, +0x93,0x00,0xc2,0x96,0x71,0x15,0x4d,0x55,0xa4,0x06,0xbc,0x61,0x62,0x15,0x57,0x92, +0x9c,0x31,0x10,0x7b,0xb3,0x32,0x12,0x10,0xb2,0x28,0xb1,0x25,0x56,0x55,0x64,0xa1, +0xbc,0x61,0xa3,0x15,0x4e,0x55,0x73,0x65,0xc3,0x90,0x93,0x11,0x49,0x55,0x84,0x55, +0xc5,0x95,0x82,0x15,0x4a,0x55,0x94,0x11,0x9c,0x31,0x10,0x6e,0xb3,0x32,0x21,0x10, +0xc2,0x95,0x72,0x16,0x4f,0x95,0xa4,0x16,0xbc,0x51,0x64,0x15,0x59,0x95,0xb1,0x25, +0xb1,0x55,0x58,0x55,0x66,0x94,0xbb,0x61,0xa3,0x15,0x50,0x55,0x75,0x99,0xc2,0x92, +0x9c,0x31,0x10,0x76,0xb3,0x22,0x21,0x10,0x94,0x05,0x4c,0x55,0x85,0x55,0xc4,0x85, +0x83,0x15,0x4d,0x55,0x95,0x00,0xc1,0x96,0x74,0x15,0x52,0x55,0xa4,0x06,0xba,0x61, +0x65,0x15,0x5b,0x92,0xb1,0x28,0xb0,0x25,0x9c,0x31,0x10,0x6e,0xb3,0x32,0x21,0x10, +0x5a,0x15,0x67,0x91,0xba,0x61,0xa2,0x56,0x52,0x55,0x76,0xa6,0xc0,0x95,0x94,0x15, +0x4f,0x55,0x85,0x51,0xc2,0x98,0x84,0x11,0x50,0x55,0x95,0x11,0xbf,0x95,0x75,0x15, +0x9c,0x31,0x10,0x34,0xb5,0x42,0x33,0x21,0x54,0x6d,0xa3,0x4d,0xb9,0x6d,0x68,0x68, +0x5d,0x31,0xaf,0x76,0xaf,0x50,0x5c,0x6c,0x69,0x8d,0xb9,0x70,0xa2,0x6d,0x55,0x6d, +0x77,0x71,0xbf,0x8c,0x93,0x6d,0x51,0x6c,0x9c,0x31,0x10,0xb7,0xb3,0x22,0x11,0x10, +0x86,0x6d,0xc0,0xa5,0x84,0x4d,0x52,0x71,0x94,0x40,0xbd,0x8d,0x75,0x31,0x56,0x8d, +0xa2,0x25,0xb7,0x94,0x68,0x4d,0x5e,0xac,0xae,0x59,0xad,0x55,0x5e,0x4d,0x69,0xb4, +0x9c,0x31,0x10,0x53,0xa3,0x22,0x21,0x10,0xef,0x61,0xc3,0x15,0x2e,0x55,0x6f,0x66, +0xf9,0x91,0xa7,0x15,0x27,0x55,0x8c,0x65,0xfd,0x84,0x89,0x11,0x27,0x55,0xa8,0x41, +0xf9,0x95,0x6d,0x65,0x30,0x45,0xc3,0x16,0x9c,0x31,0x10,0x92,0xa3,0x22,0x11,0x10, +0xed,0x91,0x54,0x51,0x40,0xc5,0xda,0x55,0xdb,0x71,0x40,0x51,0x55,0xb1,0xec,0x58, +0xc4,0x45,0x31,0x6c,0x6f,0x96,0xf7,0xb0,0xa8,0x29,0x2b,0x71,0x8c,0x6d,0xfb,0xc9, +0x9c,0x31,0x10,0x01,0xa3,0x32,0x21,0x20,0x8b,0x15,0x2b,0x95,0xa8,0x10,0xf7,0xa6, +0x6f,0x18,0x34,0x95,0xc3,0x15,0xea,0x61,0x57,0x15,0x43,0x92,0xd8,0x28,0xd9,0x65, +0x43,0x55,0x58,0x95,0xe9,0x51,0xc2,0x55,0x9c,0x31,0x10,0x53,0xa3,0x22,0x21,0x10, +0x35,0x65,0x70,0xa6,0xf3,0x95,0xa8,0x11,0x2e,0x55,0x8b,0x51,0xf7,0x88,0x8c,0x15, +0x2f,0x45,0xa7,0x01,0xf2,0x95,0x71,0x15,0x37,0x45,0xc0,0x06,0xe6,0x61,0x58,0x15, +0x9c,0x31,0x10,0xb8,0xa5,0x42,0x23,0x20,0x46,0x6c,0xd5,0x51,0xd4,0x6d,0x46,0x4d, +0x5b,0x8d,0xe5,0x70,0xbe,0x6e,0x38,0x6d,0x72,0x8d,0xef,0x6c,0xa4,0x6d,0x31,0x6c, +0x8c,0x6d,0xf4,0x89,0x8c,0x12,0x31,0x76,0x9c,0x31,0x10,0x81,0xa3,0x22,0x23,0x20, +0xa4,0x51,0xee,0x55,0x72,0x15,0x3a,0x55,0xbd,0x55,0xe3,0x61,0x5c,0x65,0x48,0xa2, +0xd0,0x25,0xd4,0x65,0x49,0x65,0x59,0xa1,0xe2,0x51,0xbe,0x16,0x3a,0x55,0x72,0xa6, +0x9c,0x31,0x10,0x66,0xa4,0x22,0x11,0x10,0xed,0xa1,0xa5,0x54,0x34,0x81,0x8b,0x61, +0xee,0x91,0x8b,0x64,0x35,0x95,0xa4,0x50,0xeb,0x91,0x72,0x34,0x3c,0x81,0xbb,0x51, +0xe0,0x85,0x5b,0x59,0x49,0x95,0xcf,0x69,0x9c,0x31,0x10,0x9f,0xa3,0x32,0x22,0x10, +0xcf,0x55,0x49,0x55,0x5e,0x55,0xde,0x62,0xb9,0x65,0x3d,0x66,0x71,0x95,0xe7,0x92, +0xa4,0x55,0x37,0x95,0x8a,0x55,0xea,0x95,0x8b,0x15,0x39,0x55,0xa2,0x55,0xe6,0x52, +0x9c,0x31,0x10,0x4b,0xa3,0x32,0x21,0x10,0x73,0x55,0x3f,0x96,0xba,0x15,0xdd,0x62, +0x5d,0x55,0x4d,0x92,0xce,0x59,0xcd,0x61,0x4c,0x54,0x60,0x91,0xdc,0x55,0xb9,0x55, +0x40,0x55,0x74,0x62,0xe6,0x99,0xa4,0x11,0x9c,0x31,0x10,0xc1,0xa3,0x23,0x21,0x11, +0x3b,0x95,0x8c,0x15,0xe8,0x89,0x8c,0x05,0x3c,0x54,0xa4,0x01,0xe4,0x45,0x75,0x55, +0x43,0x45,0xb9,0x56,0xd9,0x55,0x5f,0x51,0x50,0x85,0xca,0x25,0xca,0x55,0x4c,0x26, +0x9c,0x31,0x10,0xbf,0xa4,0x32,0x21,0x10,0x61,0x65,0xd6,0xa1,0xb4,0xd9,0x42,0x95, +0x70,0x95,0xdf,0x12,0xa0,0xd4,0x3c,0xa1,0x89,0x25,0xe0,0xd5,0x88,0xd5,0x3e,0xa5, +0x9e,0x91,0xdf,0x16,0x72,0x99,0x44,0xd2,0x9c,0x31,0x10,0xdd,0xb9,0x75,0x55,0x42, +0x98,0xed,0xa8,0xed,0x70,0xed,0x68,0xed,0xab,0x0d,0xa6,0x6e,0xb7,0xc6,0x4e,0x68, +0x93,0x6d,0xac,0x8d,0x3f,0x0d,0xcf,0x0d,0x5c,0x8d,0x7d,0x6d,0xbe,0x8d,0x38,0xed, +0x9c,0x31,0x10,0xb9,0xb9,0x33,0x31,0x21,0xc5,0x49,0x72,0x79,0x67,0x65,0xca,0xc1, +0x3a,0xd1,0xb5,0x5a,0x8a,0x79,0x53,0x59,0xd2,0xe5,0x44,0xb5,0x9f,0x65,0xa0,0x79, +0x43,0x39,0xd3,0x04,0x54,0x95,0x87,0x70,0x9c,0x31,0x10,0x56,0xb9,0x32,0x22,0x21, +0xb4,0x91,0x3b,0x14,0xc9,0x38,0x66,0x85,0x6f,0x70,0xc4,0xb1,0x3a,0xe5,0xbb,0x46, +0x7e,0x75,0x5b,0x66,0xce,0xd6,0x40,0xc5,0xa9,0x66,0x96,0x75,0x49,0x46,0xd0,0xf4, +0x9c,0x31,0x10,0xc4,0xb9,0x33,0x22,0x20,0x4c,0xa5,0x93,0x70,0xaa,0x85,0x3d,0x29, +0xcf,0x28,0x5c,0x84,0x7b,0x70,0xbc,0xa5,0x39,0x09,0xc3,0x39,0x72,0x79,0x65,0x65, +0xc8,0xc2,0x3c,0xd5,0xb1,0x56,0x88,0x79,0x9c,0x31,0x10,0x59,0xb8,0x33,0x22,0x20, +0x53,0xb9,0xce,0xd5,0x44,0x75,0x9d,0xd5,0xa0,0x19,0x43,0x79,0xcf,0x28,0x54,0x35, +0x87,0xe0,0xb2,0x34,0x3b,0x35,0xc7,0x68,0x66,0x05,0x6f,0xe4,0xc2,0x72,0x3a,0xe5, +0x9c,0x31,0x10,0x8e,0xb9,0x33,0x22,0x10,0xbb,0x4a,0x7c,0x79,0x5b,0x65,0xcc,0xd1, +0x40,0xc5,0xa7,0x66,0x94,0x75,0x4b,0x49,0xd0,0xf5,0x4a,0xa5,0x93,0x71,0xa8,0x84, +0x3f,0x29,0xcb,0x18,0x5c,0x85,0x7b,0x70,0x9c,0x31,0x10,0xd9,0xb9,0x33,0x22,0x21, +0xba,0xa1,0x3b,0x05,0xc1,0x39,0x72,0x79,0x65,0x65,0xc6,0xc1,0x3c,0xd5,0xb1,0x56, +0x88,0x79,0x53,0x59,0xce,0xe5,0x44,0xb5,0x9d,0x65,0x9e,0x88,0x45,0x39,0xcd,0x08, +0x9c,0x31,0x10,0xf4,0xb8,0x43,0x33,0x21,0x54,0x1b,0x88,0xf1,0xb4,0x14,0x3c,0x9d, +0xc7,0xb5,0x68,0x0c,0x70,0xf3,0xc2,0x3b,0x3b,0x73,0xb9,0xcc,0x7d,0x04,0x5b,0xe4, +0xcb,0x5a,0x41,0x4b,0xa6,0xe3,0x94,0x04,0x9c,0x31,0x10,0xd6,0xb8,0x32,0x22,0x20, +0x4b,0x9a,0xcf,0x04,0x4c,0x55,0x91,0xe0,0xa8,0x24,0x3f,0x59,0xc9,0x48,0x5e,0x25, +0x7b,0xe0,0xb8,0x55,0x3b,0x05,0xbf,0x79,0x72,0x05,0x65,0xc5,0xc4,0x92,0x3e,0xb4, +0x9c,0x31,0x10,0x9c,0xb8,0x32,0x22,0x10,0xaf,0xb6,0x88,0x09,0x53,0xaa,0xca,0xd5, +0x46,0x75,0x9b,0xd5,0x9c,0x14,0x45,0x79,0xcb,0x28,0x54,0x35,0x85,0xe0,0xb0,0x34, +0x3d,0x35,0xc5,0x68,0x66,0x16,0x6f,0xd4,0x9c,0x31,0x10,0xc7,0xb8,0x33,0x21,0x10, +0xbe,0x76,0x3c,0xe5,0xb7,0x99,0x7c,0x09,0x5b,0xc5,0xc6,0xb5,0x42,0x95,0xa5,0xc6, +0x92,0x15,0x4b,0x99,0xca,0xf5,0x4c,0x55,0x91,0xd1,0xa6,0x24,0x41,0x55,0xc7,0x48, +0x9c,0x31,0x10,0x0e,0xb8,0x33,0x22,0x11,0x5c,0x25,0x7b,0xe0,0xb6,0x51,0x3b,0x04, +0xbd,0x79,0x70,0x05,0x65,0xc5,0xc4,0x91,0x3e,0xb5,0xad,0xa9,0x86,0x09,0x53,0xa9, +0xc8,0xd5,0x46,0x75,0x9b,0xc5,0x9c,0x19,0x9c,0x31,0x10,0x8d,0xb8,0x33,0x21,0x20, +0x45,0x79,0xc9,0x28,0x54,0x45,0x85,0xd4,0xae,0x45,0x3f,0x39,0xc3,0x59,0x66,0x15, +0x6f,0xd5,0xbc,0x75,0x3c,0xe5,0xb5,0x99,0x7a,0x09,0x5d,0xb5,0xc6,0xb2,0x42,0x95, +0x9c,0x31,0x10,0x9e,0xb8,0x42,0x22,0x20,0xa4,0xdb,0x91,0x0c,0x4d,0xcc,0xc9,0x7b, +0x4d,0x33,0x90,0xea,0xa5,0x1b,0x42,0xac,0xc6,0xa4,0x5d,0x13,0x7a,0xea,0xb7,0x29, +0x3e,0x7c,0xbc,0xbe,0x71,0x0c,0x65,0xe3,0x9c,0x31,0x10,0xd6,0xb8,0x32,0x22,0x20, +0xc0,0x92,0x3e,0xb5,0xad,0xa6,0x86,0x09,0x53,0xaa,0xc6,0xd5,0x46,0x75,0x99,0xc5, +0x9a,0x15,0x47,0x79,0xc7,0x14,0x54,0x45,0x85,0xd0,0xac,0x44,0x3f,0x29,0xbf,0x58, +0x9c,0x31,0x10,0x9c,0xb8,0x32,0x22,0x10,0x66,0x26,0x6f,0xd4,0xba,0x76,0x3c,0xe4, +0xb3,0x9a,0x7a,0x05,0x5d,0xb6,0xc2,0xb2,0x42,0xa5,0xa3,0xb6,0x8e,0x18,0x4d,0x8a, +0xc6,0xf4,0x4c,0x65,0x8f,0xd1,0xa2,0x34,0x9c,0x31,0x10,0x13,0xb8,0x33,0x22,0x10, +0x41,0x59,0xc3,0x48,0x5c,0x35,0x79,0xd0,0xb4,0x65,0x3d,0x04,0xb9,0x79,0x70,0x15, +0x65,0xc5,0xbe,0x91,0x3e,0xc5,0xab,0xa5,0x84,0x19,0x55,0xa9,0xc4,0xd5,0x48,0x85, +0x9c,0x31,0x10,0x59,0xb8,0x33,0x22,0x20,0x97,0xc5,0x98,0x28,0x47,0x69,0xc5,0x18, +0x54,0x45,0x83,0xd0,0xac,0x45,0x3f,0x29,0xbd,0x59,0x66,0x25,0x6f,0xc5,0xb8,0x75, +0x3e,0xe5,0xb1,0x99,0x7a,0x19,0x5d,0xb5,0x9c,0x31,0x10,0xd6,0xb8,0x32,0x22,0x20, +0xc0,0xb2,0x42,0xa5,0xa1,0xb6,0x8e,0x18,0x4d,0x8a,0xc4,0xf4,0x4e,0x65,0x8d,0xc1, +0xa2,0x34,0x43,0x45,0xc1,0x38,0x5e,0x35,0x79,0xd0,0xb2,0x65,0x3f,0x05,0xb7,0x78, +0x9c,0x31,0x10,0x13,0xb8,0x33,0x22,0x10,0x70,0x15,0x65,0xb5,0xbc,0x92,0x40,0xc5, +0xa9,0xa6,0x84,0x19,0x55,0x9a,0xc2,0xd5,0x48,0x85,0x97,0xb5,0x98,0x29,0x49,0x69, +0xc3,0x29,0x56,0x45,0x83,0xd1,0xa8,0x45,0x9c,0x31,0x10,0xe9,0xb8,0x43,0x33,0x20, +0x41,0x94,0xbc,0xac,0x67,0x13,0x6f,0xe3,0xb8,0x43,0x41,0x72,0xb2,0xbd,0x7a,0x0e, +0x5d,0xd4,0xc0,0x5a,0x44,0x52,0xa0,0xdb,0x8e,0x14,0x4f,0xc4,0xc3,0x7a,0x4f,0x33, +0x9c,0x31,0x10,0x0b,0xb8,0x23,0x22,0x10,0x8d,0xc1,0xa0,0x39,0x45,0x49,0xbf,0x38, +0x5c,0x45,0x79,0xc0,0xae,0x61,0x41,0x05,0xb5,0x79,0x70,0x29,0x67,0xb5,0xba,0xa1, +0x42,0xc1,0xa7,0x99,0x82,0x19,0x55,0x99,0x9c,0x31,0x10,0x59,0xb8,0x33,0x22,0x20, +0xc0,0xd5,0x4a,0x85,0x95,0xb5,0x96,0x39,0x49,0x69,0xc1,0x18,0x56,0x55,0x83,0xc0, +0xa8,0x55,0x43,0x25,0xb9,0x59,0x66,0x35,0x6f,0xc5,0xb4,0x85,0x40,0xe5,0xaf,0x89, +0x9c,0x31,0x10,0xce,0xb8,0x22,0x22,0x20,0x7a,0x29,0x5d,0xa9,0xbc,0xb2,0x44,0xa4, +0x9f,0xa6,0x8c,0x28,0x4f,0x8a,0xc0,0xf4,0x50,0x75,0x8d,0xc0,0x9e,0x39,0x47,0x49, +0xbd,0x38,0x5e,0x45,0x79,0xc0,0xae,0x61,0x9c,0x31,0x10,0x27,0xa8,0x32,0x21,0x20, +0x05,0x05,0xe9,0x69,0x60,0x25,0x4f,0xb5,0xf2,0xa2,0x08,0xc5,0xcd,0x96,0x88,0x29, +0x2f,0x9a,0xfc,0xd5,0x16,0x85,0xab,0xb5,0xac,0x34,0x17,0x69,0xfd,0x14,0x2e,0x55, +0x9c,0x31,0x10,0x6d,0xa8,0x32,0x21,0x10,0x87,0xc0,0xce,0x54,0x09,0x35,0xf1,0x48, +0x4e,0x36,0x61,0xb4,0xe6,0x86,0x06,0xe4,0xdb,0x8a,0x72,0x29,0x3d,0xa6,0xf8,0xb6, +0x0e,0xa5,0xbd,0xa6,0x9a,0x35,0x21,0x7a,0x9c,0x31,0x10,0x62,0xa8,0x23,0x23,0x10, +0xfd,0x05,0x22,0x75,0x99,0xb1,0xbe,0x45,0x0f,0x49,0xf7,0x38,0x40,0x45,0x71,0xc0, +0xdc,0x71,0x07,0x05,0xe5,0x69,0x62,0x25,0x4d,0xb5,0xf0,0xa1,0x0a,0xc1,0xcd,0x91, +0x9c,0x31,0x10,0xea,0xa8,0x42,0x23,0x21,0x8a,0x0d,0x2e,0xcd,0xfb,0x6b,0x19,0x43, +0xa9,0xdb,0xac,0x1b,0x17,0xac,0xfa,0x8b,0x32,0x2b,0x83,0xdb,0xcd,0x2b,0x09,0x94, +0xee,0xa4,0x51,0x1b,0x5e,0xdb,0xe6,0x43,0x9c,0x31,0x10,0xf3,0xa8,0x32,0x22,0x20, +0x06,0xe5,0xd7,0x8a,0x74,0x29,0x3d,0xa5,0xf4,0xc6,0x10,0xa4,0xb9,0xa6,0x9a,0x39, +0x21,0x7a,0xfa,0xf4,0x24,0x75,0x97,0xb4,0xbc,0x44,0x11,0x45,0xf3,0x34,0x3e,0x45, +0x9c,0x31,0x10,0xf6,0xa8,0x22,0x22,0x21,0x71,0xb0,0xd8,0x71,0x09,0x05,0xe3,0x69, +0x62,0x35,0x4f,0xa5,0xec,0xa2,0x0c,0xc1,0xc9,0x9a,0x86,0x38,0x2f,0x8a,0xf6,0xe1, +0x1a,0x81,0xa7,0xa5,0xaa,0x39,0x19,0x69,0x9c,0x31,0x10,0xa4,0xa8,0x32,0x22,0x11, +0xf5,0x14,0x32,0x65,0x83,0xb4,0xca,0x64,0x0d,0x25,0xeb,0x48,0x50,0x35,0x5f,0xb4, +0xe2,0x86,0x0a,0xe4,0xd5,0x7a,0x74,0x39,0x3f,0x96,0xf2,0xc6,0x12,0xa5,0xb7,0xa6, +0x9c,0x31,0x10,0xe2,0xa8,0x33,0x21,0x10,0x98,0x39,0x25,0x79,0xf7,0x05,0x26,0x75, +0x95,0xb5,0xba,0x44,0x13,0x45,0xef,0x38,0x42,0x45,0x71,0xb4,0xd4,0x75,0x0b,0x05, +0xdf,0x69,0x62,0x35,0x4f,0xa5,0xe8,0xa1,0x9c,0x31,0x10,0xeb,0xa8,0x22,0x22,0x20, +0x0e,0xc1,0xc5,0x8a,0x86,0x39,0x33,0x8a,0xf2,0xe2,0x1c,0x91,0xa7,0xa2,0xa8,0x48, +0x1b,0x5a,0xf3,0x18,0x32,0x65,0x83,0xb0,0xc6,0x65,0x0f,0x28,0xe7,0x48,0x52,0x49, +0x9c,0x31,0x10,0x80,0xa8,0x43,0x32,0x20,0x5f,0xd3,0xe0,0x4b,0x0c,0x73,0xd3,0xbc, +0x73,0x1c,0x40,0xcb,0xee,0x63,0x16,0x5b,0xb6,0xcb,0x9a,0x23,0x28,0xad,0xf3,0x85, +0x28,0x3b,0x94,0xda,0xb8,0x2b,0x14,0xa3,0x9c,0x31,0x10,0xf6,0xa8,0x22,0x22,0x21, +0xed,0x38,0x42,0x55,0x71,0xb0,0xd2,0x71,0x0d,0x05,0xdd,0x69,0x62,0x35,0x51,0xa5, +0xe6,0xa2,0x10,0xc0,0xc5,0x8a,0x84,0x39,0x33,0x8a,0xf0,0xd1,0x1e,0x91,0xa5,0xa5, +0x9c,0x31,0x10,0xa4,0xa8,0x32,0x22,0x11,0xa6,0x45,0x1d,0x59,0xef,0x14,0x34,0x65, +0x83,0xa0,0xc4,0x64,0x13,0x29,0xe3,0x48,0x52,0x45,0x61,0xa4,0xdc,0x91,0x0e,0xe4, +0xd1,0x7a,0x72,0x39,0x41,0x96,0xea,0xc6,0x9c,0x31,0x10,0x75,0xa8,0x22,0x21,0x10, +0x16,0xb5,0xb5,0x96,0x96,0x49,0x29,0x7a,0xee,0xf5,0x28,0x75,0x93,0xa1,0xb6,0x58, +0x17,0x49,0xe9,0x38,0x42,0x55,0x71,0xa0,0xce,0x71,0x11,0x04,0xd9,0x69,0x62,0x49, +0x9c,0x31,0x10,0x3f,0xa8,0x22,0x21,0x20,0x51,0x95,0xe2,0xa2,0x12,0xc1,0xc1,0x8a, +0x84,0x39,0x35,0x8a,0xec,0xd1,0x20,0x91,0xa3,0x92,0xa4,0x48,0x1f,0x5a,0xeb,0x18, +0x36,0x65,0x83,0xa0,0xc2,0x65,0x13,0x28,0x9c,0x31,0x10,0x27,0xa8,0x32,0x21,0x20, +0xe1,0x49,0x52,0x45,0x61,0xa4,0xda,0x95,0x10,0xe5,0xcd,0x7a,0x72,0x49,0x43,0x95, +0xe6,0xc6,0x1a,0xb5,0xb1,0x96,0x94,0x48,0x29,0x6a,0xea,0xf5,0x2a,0x85,0x93,0xa4, +0x9c,0x31,0x10,0xe3,0xa8,0x22,0x11,0x21,0xb4,0x59,0x19,0x39,0xe5,0x28,0x44,0x55, +0x71,0xa0,0xcc,0x71,0x13,0x05,0xd7,0x59,0x62,0x49,0x51,0x95,0xde,0xb2,0x16,0xc1, +0xbd,0x8a,0x84,0x49,0x37,0x7a,0xe6,0xe1,0x9c,0x31,0x10,0x5e,0xa8,0x42,0x33,0x21, +0x24,0x4b,0xa2,0xcb,0xa4,0x2b,0x25,0xab,0xea,0x85,0x37,0x3d,0x83,0xd3,0xbf,0x33, +0x17,0x93,0xde,0xa4,0x53,0x2b,0x61,0xcb,0xd7,0x4b,0x14,0x73,0xcb,0xbc,0x73,0x24, +0x9c,0x31,0x10,0xb4,0xa8,0x22,0x11,0x10,0x43,0x8a,0xe2,0xc2,0x1c,0xb5,0xaf,0x86, +0x94,0x49,0x2b,0x69,0xe8,0xf9,0x2e,0x85,0x91,0xa1,0xb2,0x68,0x1d,0x39,0xe1,0x28, +0x46,0x65,0x71,0xa0,0xca,0x86,0x17,0x04,0x9c,0x31,0x10,0x3f,0xa8,0x22,0x21,0x20, +0xd3,0x59,0x62,0x45,0x53,0x95,0xda,0xb2,0x18,0xd1,0xbd,0x76,0x82,0x49,0x39,0x7a, +0xe4,0xe2,0x24,0xa1,0xa1,0x96,0xa0,0x58,0x25,0x5a,0xe5,0x14,0x3a,0x75,0x81,0x90, +0x9c,0x31,0x10,0x27,0xa8,0x32,0x21,0x20,0xbc,0x75,0x1b,0x24,0xdb,0x49,0x54,0x55, +0x63,0x95,0xd2,0x95,0x18,0xe5,0xc7,0x6a,0x72,0x49,0x47,0x85,0xde,0xc6,0x20,0xb5, +0xaf,0x86,0x92,0x59,0x2f,0x6a,0xe4,0xf4,0x9c,0x31,0x10,0xe3,0xa8,0x22,0x11,0x21, +0x30,0x85,0x91,0x91,0xb0,0x69,0x1f,0x39,0xdf,0x28,0x46,0x65,0x71,0x90,0xc6,0x85, +0x19,0x05,0xcf,0x59,0x64,0x59,0x55,0x85,0xd8,0xb2,0x1c,0xd1,0xb9,0x76,0x82,0x48, +0x9c,0x31,0x10,0x70,0xa8,0x32,0x21,0x11,0x3b,0x76,0xe0,0xe5,0x28,0xa5,0x9f,0x85, +0xa0,0x55,0x27,0x49,0xe1,0x14,0x3c,0x75,0x81,0x95,0xba,0x74,0x1d,0x25,0xd5,0x38, +0x56,0x55,0x63,0x94,0xce,0x96,0x1a,0xe4,0x9c,0x31,0x10,0x47,0xa8,0x32,0x32,0x20, +0xc5,0x6a,0x72,0x59,0x47,0x8a,0xdc,0xc6,0x22,0xb5,0xab,0x76,0x90,0x59,0x31,0x69, +0xe0,0xf5,0x32,0x85,0x8f,0x95,0xae,0x64,0x23,0x35,0xdd,0x24,0x4a,0x5a,0x71,0x99, +0x9c,0x31,0x10,0x26,0xa8,0x22,0x22,0x30,0xc4,0x89,0x1d,0x04,0xcd,0x59,0x64,0x59, +0x55,0x85,0xd4,0xb2,0x20,0xd5,0xb7,0x76,0x82,0x59,0x3d,0x69,0xdc,0xe6,0x2a,0xa1, +0x9f,0x82,0x9e,0x68,0x2b,0x4a,0xdd,0x14,0x9c,0x31,0x10,0x2a,0xa8,0x22,0x12,0x20, +0x3e,0x75,0x81,0x90,0xb8,0x75,0x1f,0x18,0xd5,0x39,0x56,0x65,0x63,0x85,0xcc,0xa6, +0x1c,0xe5,0xc3,0x69,0x72,0x59,0x49,0x79,0xd8,0xc2,0x24,0xb5,0xab,0x76,0x90,0x59, +0x9c,0x31,0x10,0xf6,0xa8,0x22,0x22,0x21,0x33,0x5a,0xdc,0xf5,0x36,0x85,0x8f,0x84, +0xac,0x69,0x25,0x39,0xd7,0x28,0x4a,0x75,0x73,0x90,0xc2,0x85,0x1f,0x05,0xcb,0x49, +0x64,0x69,0x57,0x85,0xd0,0xb2,0x22,0xd1,0x9c,0x31,0x10,0x3a,0xa8,0x32,0x21,0x21, +0xb5,0x76,0x82,0x55,0x3f,0x66,0xd8,0xe5,0x2e,0xa6,0x9d,0x85,0x9e,0x65,0x2d,0x45, +0xdb,0x16,0x40,0x75,0x81,0x95,0xb6,0x74,0x23,0x25,0xd1,0x38,0x58,0x66,0x65,0x84, +0x9c,0x31,0x10,0xa9,0xa8,0x22,0x11,0x11,0xc8,0xa2,0x20,0xe5,0xbf,0x6a,0x72,0x59, +0x4b,0x7a,0xd4,0xc1,0x28,0xb5,0xa9,0x76,0x90,0x69,0x37,0x59,0xd8,0xf5,0x36,0x95, +0x8f,0x85,0xaa,0x74,0x29,0x39,0xd5,0x24,0x9c,0x31,0x10,0x6d,0xa8,0x32,0x21,0x10, +0x4c,0x75,0x71,0x84,0xc0,0x95,0x23,0x05,0xc9,0x49,0x66,0x65,0x59,0x85,0xce,0xb2, +0x24,0xd5,0xb3,0x76,0x80,0x56,0x41,0x65,0xd6,0xe6,0x30,0xa5,0x9b,0x76,0x9c,0x64, +0x9c,0x31,0x10,0x0f,0xa8,0x42,0x32,0x20,0x2f,0xa4,0xd7,0x8b,0x42,0x43,0x80,0xc2, +0xb5,0x43,0x28,0x8a,0xd0,0x95,0x5a,0x3d,0x65,0xc3,0xc8,0x53,0x24,0x73,0xbd,0xac, +0x74,0x2c,0x4c,0xbc,0xd3,0x63,0x2b,0x63,0x9c,0x31,0x10,0x68,0xa8,0x22,0x21,0x11, +0xa7,0x76,0x8e,0x69,0x39,0x5a,0xd6,0xf5,0x38,0x95,0x8f,0x80,0xa8,0x79,0x2b,0x39, +0xd1,0x29,0x4c,0x75,0x73,0x80,0xbc,0x95,0x25,0x05,0xc5,0x49,0x66,0x6a,0x59,0x75, +0x9c,0x31,0x10,0xbc,0xa8,0x22,0x22,0x11,0xcc,0xb2,0x28,0xd1,0xb3,0x6a,0x80,0x69, +0x43,0x6a,0xd4,0xe1,0x32,0xa1,0x9b,0x71,0x9a,0x79,0x33,0x49,0xd5,0x15,0x42,0x85, +0x81,0x80,0xb2,0x84,0x29,0x19,0xcb,0x38,0x9c,0x31,0x10,0xf6,0xa8,0x22,0x22,0x21, +0x58,0x7a,0x67,0x84,0xc4,0xa6,0x26,0xe4,0xbb,0x5a,0x74,0x69,0x4f,0x7a,0xce,0xc2, +0x2e,0xc6,0xa7,0x76,0x8e,0x69,0x3b,0x59,0xd2,0xf5,0x3a,0x95,0x8d,0x85,0xa6,0x74, +0x9c,0x31,0x10,0xb4,0xa8,0x22,0x11,0x10,0x2f,0x39,0xcf,0x28,0x4e,0x75,0x73,0x80, +0xba,0x96,0x29,0x04,0xc3,0x4a,0x66,0x65,0x5b,0x75,0xc8,0xb1,0x2a,0xd5,0xb1,0x66, +0x80,0x69,0x45,0x6a,0xd0,0xe6,0x34,0xb5,0x9c,0x31,0x10,0x78,0xa8,0x32,0x12,0x10, +0x99,0x76,0x9a,0x74,0x35,0x4a,0xd1,0x14,0x46,0x85,0x7f,0x80,0xb0,0x85,0x2b,0x15, +0xc7,0x39,0x5c,0x75,0x65,0x75,0xc2,0xb6,0x2a,0xe5,0xb7,0x55,0x74,0x69,0x4f,0x65, +0x9c,0x31,0x10,0xf6,0xa8,0x22,0x22,0x21,0xcc,0xd6,0x30,0xc5,0xa5,0x66,0x8c,0x78, +0x3d,0x5a,0xd0,0xf5,0x3e,0x96,0x8d,0x71,0xa4,0x89,0x31,0x29,0xcb,0x28,0x50,0x85, +0x75,0x74,0xb8,0x95,0x2b,0x05,0xc3,0x40,0x9c,0x31,0x10,0x12,0xa8,0x42,0x32,0x21, +0x6a,0x2d,0x5b,0xbc,0xc8,0x5b,0x2f,0x6b,0xad,0xb3,0x82,0x3b,0x46,0xab,0xce,0x72, +0x39,0x5b,0x97,0xb2,0x9a,0x3b,0x37,0x9b,0xcd,0x8b,0x48,0x43,0x80,0xbb,0xae,0x43, +0x9c,0x31,0x10,0x3a,0xa8,0x32,0x21,0x21,0x2f,0x15,0xc5,0x29,0x5c,0x76,0x67,0x74, +0xbe,0xb6,0x2c,0xe5,0xb7,0x5a,0x74,0x79,0x53,0x6a,0xc8,0xd5,0x32,0xc5,0xa5,0x65, +0x8a,0x79,0x41,0x55,0xcc,0xf5,0x3e,0xa5,0x9c,0x31,0x10,0x98,0xa8,0x65,0x44,0x43, +0x8d,0x6d,0xa2,0x8d,0x35,0x2d,0xc9,0x0d,0x52,0x8d,0x7b,0x6d,0xbc,0x29,0x6f,0x82, +0x86,0xcd,0x81,0x0d,0x82,0xed,0x82,0xed,0x80,0xed,0x82,0xed,0x82,0xed,0x80,0xed, +0x9c,0x31,0x10,0x67,0x97,0x65,0x55,0x43,0x85,0xb5,0x85,0xb5,0x81,0xb5,0x81,0xb5, +0x81,0xb5,0x89,0xb5,0x91,0x3a,0xd2,0x1a,0xd1,0xb1,0xc5,0xb5,0xc1,0xb5,0xbd,0xb5, +0x8c,0x91,0x6e,0x32,0x81,0xb5,0x7d,0xb5,0x9c,0x31,0x10,0xf5,0x42,0x10,0x11,0x12, +0xb2,0x66,0x5b,0x55,0x9c,0x55,0xa1,0x65,0x75,0x55,0xbc,0x55,0x88,0x95,0xac,0x59, +0xa2,0x55,0xa4,0x55,0x72,0x55,0x94,0x95,0x40,0x51,0x85,0x55,0x91,0x65,0x4c,0x55, +0x9c,0x31,0x10,0x57,0x42,0x01,0x00,0x02,0x76,0x22,0x5d,0xdd,0x61,0xe2,0x85,0x9a, +0x7e,0x5d,0x65,0xe9,0x82,0x93,0x4c,0xdc,0x3b,0x5a,0x69,0x23,0x2a,0xdc,0x79,0x92, +0x41,0xa3,0x1e,0x5c,0x46,0x62,0x15,0xe3,0x9c,0x31,0x10,0x67,0x43,0x10,0x00,0x00, +0x33,0x25,0x42,0xf6,0x28,0xd6,0x5c,0xf7,0x3c,0xe7,0x3b,0x08,0x6e,0xc7,0x36,0xe5, +0x71,0x0a,0x7c,0xe7,0x58,0x7e,0x5f,0x1e,0x4c,0xd9,0x5f,0x08,0x60,0xea,0x47,0x16, +0x9c,0x31,0x10,0x58,0x41,0x00,0x00,0x00,0x53,0xad,0x38,0xc9,0x77,0x31,0x35,0x08, +0x6a,0x6f,0x3b,0x83,0x4a,0xfa,0x6a,0xce,0x30,0x29,0x7d,0x28,0x3f,0x14,0x43,0x73, +0x8e,0x89,0x5b,0x0d,0x74,0x18,0x97,0x93,0x9c,0x31,0x10,0x3e,0x30,0x00,0x00,0x00, +0x51,0x55,0x91,0xa5,0xd3,0x85,0x43,0x91,0xb2,0xe5,0x78,0xc9,0x60,0x51,0xa1,0x01, +0x4b,0x05,0xa2,0x55,0x5a,0x05,0x7e,0x95,0x88,0x05,0x81,0x59,0x7d,0x49,0x69,0xe5, +0x9c,0x31,0x10,0x1b,0x20,0x00,0x00,0x00,0x99,0xd9,0x61,0xd5,0x8f,0xd4,0x90,0x95, +0x34,0x55,0x91,0xd5,0x58,0x85,0x66,0xd5,0x8b,0x55,0x49,0x15,0x8a,0x55,0x7b,0x15, +0x66,0x55,0x89,0x55,0x6f,0xd5,0x7e,0x95,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x95,0x55,0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x65,0x55,0x55,0x59,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x59,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x54,0x55,0x55,0x55,0x55,0x55,0x50,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x59,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x55,0x55,0x55,0x15,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x95,0x55,0x95,0x55,0x95,0x55,0x95,0x55, +0x95,0x55,0x95,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x55,0x15,0x55,0x55,0x55,0x15,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x55,0x55,0x55,0x15,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x15,0x55,0x55,0x55,0x15,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x15,0x55,0x15,0x55,0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x55,0x55,0x55, +0x9c,0x31,0x10,0xc5,0x40,0x00,0x00,0x00,0x7a,0x15,0x74,0xe5,0x6b,0xd5,0x68,0x15, +0x5b,0x95,0x51,0x15,0x43,0x45,0x3e,0x26,0x3d,0x55,0x42,0xe5,0x37,0x16,0x3d,0xd5, +0x35,0xd5,0x39,0x55,0x36,0x12,0x36,0x15,0x9c,0x31,0x10,0x0c,0x41,0x10,0x01,0x00, +0x33,0x1b,0x32,0xdb,0x2d,0x54,0x2e,0xe3,0x30,0xdb,0x31,0x1b,0x2c,0xdc,0x2a,0xd3, +0x37,0x1c,0x4c,0x4b,0x90,0x5d,0x7f,0x1b,0x7e,0xd3,0x7c,0xdb,0x7e,0xdb,0x7e,0xdc, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x56,0x55,0x55,0x55,0x55,0x95,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x45,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x55,0x95,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_SEVEN.txt b/config/_default_cfg_src_/res/cn/SOUND_SEVEN.txt new file mode 100644 index 0000000..5910173 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_SEVEN.txt @@ -0,0 +1,125 @@ +0x9c,0x31,0x10,0x11,0x21,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x79,0xdb,0x79,0xdb, +0x49,0x12,0x62,0x23,0x50,0x62,0x42,0x5a,0x6e,0x8e,0x3e,0x03,0x55,0xa3,0x55,0xdb, +0x3a,0x23,0x46,0x9b,0x2d,0x22,0x49,0x69,0x9c,0x31,0x10,0x05,0x74,0x66,0x10,0x00, +0x7b,0x77,0x7b,0x77,0x7b,0x77,0x73,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77, +0x7b,0x77,0x7b,0x77,0x7b,0x78,0x83,0x87,0xad,0x76,0xcc,0x77,0xb1,0x7a,0xce,0x30, +0x9c,0x31,0x10,0xee,0x66,0x56,0x20,0x00,0x0e,0x98,0x23,0xb7,0x34,0x9a,0x5b,0xba, +0x4b,0xb3,0x3c,0x18,0x33,0xb8,0x3b,0x37,0x43,0x15,0x3b,0x66,0x4b,0xa5,0x54,0x37, +0x63,0xaa,0x7b,0xb3,0x8b,0xb6,0x63,0x27,0x9c,0x31,0x10,0x39,0x54,0x56,0x40,0x00, +0x56,0xa1,0x36,0xa5,0x56,0xa1,0x56,0xd1,0x6b,0x25,0x79,0xb6,0x74,0x5a,0x55,0x1a, +0x85,0x22,0xb0,0xc1,0xe9,0x0d,0xe9,0x6c,0xe6,0x48,0xb5,0x0c,0xa8,0x78,0x55,0xb1, +0x9c,0x31,0x10,0x85,0x55,0x68,0x40,0x00,0x68,0x5d,0x86,0x95,0x57,0xad,0x88,0x1d, +0x56,0xcd,0x55,0x25,0x14,0x5c,0x04,0xd8,0x17,0x9c,0x18,0xa0,0x22,0xa5,0x67,0x5d, +0x86,0x55,0xc7,0x62,0xb7,0x2e,0xb6,0x46,0x9c,0x31,0x10,0x51,0x65,0x88,0x30,0x00, +0x91,0x87,0xaa,0x7b,0x81,0x75,0x8c,0x84,0xad,0x59,0x9c,0x88,0x93,0x68,0xb3,0x54, +0xb8,0x95,0x9d,0x57,0x78,0x9e,0x4a,0x66,0x44,0x32,0x72,0xc9,0x53,0x89,0x3a,0x34, +0x9c,0x31,0x10,0xf2,0x76,0x78,0x20,0x00,0x53,0x67,0x5b,0xba,0x3b,0x98,0x21,0xc4, +0x42,0xa4,0x3b,0xcb,0x62,0x9c,0x7b,0x41,0xab,0xc5,0xb3,0x2b,0x95,0x57,0x9d,0x36, +0x7c,0x19,0x7d,0x33,0x88,0xd8,0x92,0xa9,0x9c,0x31,0x10,0xe5,0x76,0x88,0x40,0x00, +0xbc,0x86,0xc3,0x98,0xba,0x52,0xda,0x8e,0xd4,0x96,0xca,0x53,0xb8,0x8a,0xb2,0x84, +0x93,0x35,0x69,0x6d,0x42,0xb8,0x4a,0x34,0x5b,0x92,0x53,0x8c,0x7c,0x4c,0x9b,0xa7, +0x9c,0x31,0x10,0xd4,0x77,0x98,0x50,0x00,0x8b,0x81,0x9a,0x6a,0xa2,0x69,0x82,0x75, +0x8b,0x75,0x8b,0x66,0x6b,0x6d,0x74,0x77,0x63,0x82,0x7b,0x41,0x25,0x9b,0x5c,0x8d, +0x73,0x3b,0x7c,0x95,0x83,0x86,0x9c,0x65,0x9c,0x31,0x10,0x5b,0x77,0x99,0x50,0x00, +0x8c,0x94,0xa4,0x54,0xdc,0x5d,0x95,0xac,0x6c,0x45,0x72,0x65,0xab,0x93,0xa3,0x79, +0xcc,0x9e,0x74,0x55,0x1b,0x71,0x42,0xa5,0x59,0x3c,0x4b,0xb9,0x5b,0x61,0x4c,0x48, +0x9c,0x31,0x10,0xfd,0x76,0x98,0x40,0x00,0x6e,0xcc,0x34,0x3a,0x0b,0x53,0x52,0xa6, +0x33,0x2c,0x69,0x86,0x63,0x96,0x8a,0x57,0xb1,0x74,0xca,0x9a,0x83,0x6c,0xaa,0x76, +0x94,0x91,0x5b,0x75,0x85,0x3c,0x9c,0x99,0x9c,0x31,0x10,0xc6,0x76,0x99,0x50,0x00, +0xdc,0x64,0x84,0x49,0x8e,0xbd,0x2d,0x53,0x5a,0x62,0x4c,0x9b,0x5b,0x25,0x3c,0xa4, +0x31,0x9b,0x31,0x4c,0x22,0x75,0x61,0x94,0x78,0x5a,0xc0,0x85,0x79,0x71,0xd4,0x79, +0x9c,0x31,0x10,0x4a,0x76,0x9a,0x50,0x00,0xa2,0xf8,0xa6,0xcf,0x87,0x4b,0x82,0x4c, +0x49,0x4d,0x56,0xb0,0x54,0xcf,0x6b,0x70,0xb2,0x53,0xd5,0x6d,0xb4,0xce,0x98,0xd2, +0xc5,0x2c,0xc4,0xad,0xba,0xef,0x58,0xef,0x9c,0x31,0x10,0xe2,0x76,0x79,0x40,0x00, +0x78,0xed,0x78,0xe6,0x67,0x0a,0x58,0x59,0x49,0x24,0x67,0x18,0x4a,0x60,0x59,0x1c, +0x79,0x15,0x66,0x29,0x97,0xaa,0x74,0x92,0x94,0x49,0xab,0xa8,0xc8,0xa5,0x5c,0x95, +0x9c,0x31,0x10,0xeb,0x75,0x88,0x50,0x00,0x72,0xed,0x69,0x1d,0x95,0xcd,0x66,0x0c, +0x55,0x98,0x45,0xf5,0x4a,0x71,0x35,0x1a,0x32,0x52,0x5a,0x11,0xa1,0x61,0x87,0x21, +0xc4,0xcc,0x86,0x20,0x86,0xa0,0xb9,0xa9,0x9c,0x31,0x10,0xd5,0xa6,0x88,0x50,0x00, +0x86,0x53,0x85,0x9b,0x86,0x3a,0x79,0x42,0x64,0xb6,0x61,0xcb,0x79,0x30,0x9c,0xca, +0xa2,0x33,0x91,0x44,0x5e,0x45,0x36,0x24,0x41,0x52,0x95,0x32,0xea,0x42,0xe5,0xbb, +0x9c,0x31,0x10,0x8d,0xc5,0x78,0x40,0x00,0x7c,0xab,0x5c,0xc7,0x58,0x19,0x7a,0xc8, +0xa8,0x25,0xb2,0x24,0x87,0x69,0x53,0x07,0x43,0x63,0x64,0xb7,0x9e,0x2a,0xc4,0xd7, +0xa8,0x28,0x6b,0x55,0x3e,0x22,0x47,0x3b,0x9c,0x31,0x10,0x39,0xc5,0x78,0x50,0x00, +0x7c,0x99,0xbb,0x36,0xc6,0xb5,0x93,0x37,0x55,0x23,0x35,0x4e,0x50,0x3b,0x90,0xb7, +0xc7,0x22,0xbe,0x33,0x85,0x46,0x48,0x17,0x31,0x1b,0x58,0x57,0xa0,0x98,0xd0,0xd7, +0x9c,0x31,0x10,0x37,0xc6,0x78,0x40,0x00,0xba,0x52,0x77,0x23,0x3a,0x0a,0x33,0x25, +0x66,0xda,0xb0,0xcb,0xd4,0xeb,0xae,0x93,0x69,0x9b,0x2e,0xa3,0x34,0xe9,0x74,0x94, +0xc1,0x22,0xd7,0x13,0xa2,0xdb,0x57,0x53,0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00, +0x25,0x63,0x3c,0xcd,0x86,0xa4,0xd0,0x93,0xd4,0xe2,0x95,0x12,0x46,0xe4,0x21,0x92, +0x46,0xdc,0x9d,0x1a,0xdc,0x9c,0xce,0x9b,0x83,0x1b,0x34,0x5a,0x1f,0x1d,0x54,0xe3, +0x9c,0x31,0x10,0x0b,0xc6,0x88,0x50,0x00,0xaf,0x1c,0xe2,0xda,0xc2,0x9b,0x71,0x1b, +0x24,0x5b,0x22,0xa0,0x6a,0x93,0xc5,0x63,0xe4,0xd6,0xb2,0xe3,0x5a,0xd3,0x19,0x2b, +0x2c,0x83,0x80,0xab,0xd4,0xcb,0xe1,0x2b,0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00, +0xa1,0x0b,0x44,0xad,0x15,0x89,0x3c,0xe2,0x9a,0xd2,0xe2,0x66,0xd6,0x92,0x89,0x24, +0x30,0x11,0x15,0x26,0x52,0x99,0xb5,0x1c,0xea,0xa0,0xc8,0x55,0x73,0x62,0x20,0x95, +0x9c,0x31,0x10,0x94,0xc6,0x88,0x30,0x00,0x1a,0xe8,0x68,0x8c,0xc9,0x23,0xeb,0x0d, +0xb6,0xea,0x5b,0x13,0x13,0x6a,0x26,0xc5,0x82,0x6b,0xda,0xca,0xe4,0xeb,0xa1,0x0b, +0x46,0x6c,0x0f,0x41,0x36,0xec,0x9a,0x8a,0x9c,0x31,0x10,0x22,0xc7,0x88,0x40,0x00, +0xe4,0xa6,0xd8,0x91,0x8d,0x24,0x34,0x51,0x10,0xe6,0x4c,0xda,0xb3,0x1c,0xea,0xe0, +0xca,0x95,0x76,0xe2,0x20,0x95,0x14,0xe8,0x60,0xcd,0xc9,0x2b,0xec,0xcc,0xba,0xe9, +0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00,0x63,0x0b,0x16,0xf4,0x20,0xc3,0x78,0xb3, +0xd6,0xc1,0xe8,0xeb,0xa9,0x0b,0x4e,0xac,0x11,0x49,0x2e,0xe5,0x8e,0xda,0xe0,0x9e, +0xde,0x99,0x97,0x1c,0x3e,0x5a,0x11,0x55,0x9c,0x31,0x10,0x30,0xc6,0x89,0x40,0x00, +0x40,0xe9,0xa3,0x0b,0xe6,0xaa,0xd0,0x54,0x83,0x63,0x2e,0x0b,0x15,0x33,0x54,0xc4, +0xb9,0x2b,0xe8,0xcb,0xc0,0xab,0x6f,0x4b,0x20,0xac,0x1c,0x91,0x68,0xa4,0xc9,0x13, +0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00,0xe7,0x1e,0xb2,0xda,0x5c,0xdc,0x19,0x22, +0x28,0xd5,0x7e,0xa1,0xd6,0xcc,0xde,0xe9,0xa1,0x15,0x4c,0xaa,0x17,0x4a,0x36,0xeb, +0x92,0xcb,0xde,0xec,0xd6,0x93,0x91,0x23,0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00, +0x3c,0x4b,0x17,0x25,0x48,0xd8,0xa7,0x1c,0xe0,0xd9,0xc8,0x5d,0x81,0x1a,0x32,0x12, +0x1c,0xeb,0x58,0xce,0xb7,0x2b,0xe0,0xcb,0xbc,0xa1,0x71,0x14,0x28,0xad,0x24,0x90, +0x9c,0x31,0x10,0xbf,0xc6,0x88,0x40,0x00,0x6c,0xa3,0xc3,0x12,0xde,0xe5,0xae,0xda, +0x63,0x23,0x23,0x1b,0x2e,0xd5,0x7c,0xa0,0xcc,0xd4,0xd8,0xe1,0xa1,0x15,0x54,0xe3, +0x21,0x49,0x38,0xe4,0x8a,0xd3,0xd2,0xe4,0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00, +0xd2,0x8a,0x95,0x6b,0x48,0x8c,0x21,0x5c,0x44,0xe1,0x98,0xd4,0xd4,0x9a,0xc6,0x55, +0x87,0x22,0x40,0x42,0x25,0x35,0x54,0xcb,0xa7,0x2b,0xd6,0xca,0xbe,0x6c,0x7b,0x0b, +0x9c,0x31,0x10,0x94,0xc6,0x88,0x30,0x00,0x36,0x5a,0x28,0xda,0x62,0xd5,0xb3,0x22, +0xd4,0xd4,0xb2,0xa1,0x71,0x15,0x32,0xab,0x2e,0xc9,0x6c,0xe3,0xbb,0x13,0xd3,0x24, +0xaa,0xd3,0x67,0x22,0x2e,0xdc,0x34,0xd3,0x9c,0x31,0x10,0xa6,0xc5,0x78,0x30,0x00, +0x76,0xd2,0xc0,0x99,0xd0,0xd8,0xa3,0x29,0x61,0x54,0x2b,0x27,0x3a,0xbb,0x80,0xb4, +0xc4,0xb8,0xcc,0xb5,0x9b,0x3a,0x58,0xc6,0x2d,0x13,0x42,0xd9,0x8a,0x99,0xc6,0xc7, +0x9c,0x31,0x10,0xa6,0xc5,0x78,0x30,0x00,0xc6,0xa7,0x95,0x36,0x54,0x39,0x2f,0x16, +0x48,0xd3,0x8e,0x99,0xc8,0x58,0xc2,0x18,0x8f,0x55,0x4e,0x1a,0x2f,0x37,0x50,0xb2, +0x97,0x38,0xc8,0xc8,0xbe,0x29,0x89,0x44,0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00, +0x4a,0x4b,0x2f,0x25,0x56,0xd1,0x9f,0x23,0xca,0xd2,0xb8,0xa4,0x81,0x1a,0x46,0x52, +0x33,0x24,0x5c,0xd3,0xa3,0x22,0xca,0xd2,0xb2,0xa4,0x7c,0xd3,0x44,0x52,0x34,0xec, +0x9c,0x31,0x10,0x9a,0xc6,0x77,0x30,0x00,0x62,0x8e,0xa5,0x2a,0xc8,0xca,0xb0,0xa2, +0x7b,0x14,0x42,0x59,0x38,0xe3,0x64,0x8e,0xa9,0x22,0xc9,0x0c,0xac,0xe8,0x75,0x0d, +0x40,0xa9,0x3a,0xd0,0x6c,0xa6,0xac,0xd4,0x9c,0x31,0x10,0x95,0xc5,0x68,0x40,0x00, +0xc6,0xd8,0xa8,0xa6,0x71,0x37,0x3e,0x68,0x3e,0x92,0x70,0x58,0xae,0x97,0xc4,0xd9, +0xa4,0x97,0x6d,0x46,0x3e,0xe9,0x42,0x94,0x76,0x68,0xb0,0x87,0xc0,0xe8,0xa0,0x88, +0x9c,0x31,0x10,0xbe,0xc5,0x68,0x30,0x00,0x6b,0x56,0x3e,0xda,0x46,0x97,0x7a,0xd3, +0xb2,0x98,0xbe,0xc5,0x9b,0x2b,0x67,0x45,0x3f,0x59,0x4a,0x88,0x7e,0xd5,0xb2,0x98, +0xba,0xc5,0x96,0xa8,0x64,0xd6,0x41,0x27,0x9c,0x31,0x10,0x45,0xb5,0x68,0x30,0x00, +0x1e,0xab,0x88,0xb4,0xea,0xb8,0xf2,0xb5,0xa4,0xc8,0x3e,0xc6,0x01,0x27,0x26,0xbb, +0x92,0xa5,0xee,0xc8,0xea,0x96,0x9a,0xd6,0x38,0xb8,0x05,0x15,0x30,0xca,0x9a,0xa6, +0x9c,0x31,0x10,0x77,0xb5,0x67,0x20,0x00,0xee,0xa3,0xe4,0x93,0x92,0xe3,0x34,0x9c, +0x07,0x81,0x3a,0xeb,0xa5,0x15,0xee,0xe1,0xdc,0x9c,0x88,0xda,0x2c,0x9c,0x0b,0x42, +0x44,0xe9,0xaf,0x0d,0xf1,0x23,0xd4,0xd3,0x9c,0x31,0x10,0xc3,0xb5,0x67,0x30,0x00, +0x7c,0xe2,0x28,0x4c,0x11,0x1b,0x50,0xe0,0xb9,0x15,0xf0,0xdb,0xcc,0x9c,0x73,0x19, +0x20,0x0c,0x11,0x25,0x58,0xd9,0xc1,0x1a,0xf1,0x1b,0xc4,0x9b,0x6b,0x1b,0x20,0x13, +0x9c,0x31,0x10,0xc3,0xb5,0x67,0x30,0x00,0x1c,0xee,0x68,0x8a,0xc8,0xe2,0xea,0xd3, +0xb6,0xa3,0x61,0x1b,0x1c,0x52,0x22,0xf4,0x76,0x85,0xd0,0xf1,0xe7,0x0c,0xaa,0xea, +0x57,0x0c,0x1c,0x71,0x2e,0xd2,0x82,0xa5,0x9c,0x31,0x10,0x2b,0xb4,0x67,0x10,0x00, +0xd4,0x92,0xde,0xe3,0x9c,0xd3,0x4b,0xa4,0x1a,0xec,0x38,0x88,0x90,0xeb,0xda,0xcd, +0xd6,0xaa,0x8e,0xd3,0x41,0x62,0x1d,0x65,0x46,0xca,0x9e,0xe9,0xdd,0x15,0xcc,0xe2, +0x9c,0x31,0x10,0x03,0xb4,0x57,0x10,0x00,0x80,0xd5,0x38,0xe2,0x21,0x8a,0x57,0x25, +0xac,0x92,0xdf,0x6c,0xbe,0xca,0x71,0x2b,0x2e,0x4c,0x29,0x52,0x69,0x22,0xba,0x95, +0xda,0x9b,0xae,0x9b,0x61,0x53,0x2a,0x53,0x9c,0x31,0x10,0x1b,0xb4,0x47,0x10,0x00, +0x33,0x1c,0x7c,0xe1,0xc7,0x2b,0xd6,0x54,0x9c,0x94,0x51,0x6a,0x28,0x13,0x43,0x34, +0x8e,0x4a,0xcf,0xb3,0xcc,0xc3,0x88,0xf3,0x45,0x0b,0x2a,0x6a,0x55,0x64,0xa0,0x44, +0x9c,0x31,0x10,0x8c,0xb4,0x56,0x10,0x00,0xd3,0x21,0xbc,0xda,0x74,0xdc,0x3b,0x53, +0x34,0xab,0x6a,0xc8,0xb5,0x2e,0xd0,0xc2,0xa6,0xb2,0x5c,0xcb,0x32,0xf3,0x43,0x0b, +0x84,0x5d,0xc2,0x90,0xc7,0x2a,0x8a,0xcd,0x9c,0x31,0x10,0xac,0xb4,0x45,0x00,0x00, +0x4d,0x73,0x38,0x49,0x5d,0x5b,0xa2,0xdd,0xc6,0xda,0xaa,0xda,0x68,0x54,0x3d,0x63, +0x46,0x5a,0x7f,0x1c,0xb6,0x94,0xbd,0x22,0x8c,0x9c,0x55,0x23,0x42,0xd2,0x60,0xe4, +0x9c,0x31,0x10,0x7d,0xa3,0x45,0x00,0x00,0xb0,0x49,0xf0,0x6b,0xcc,0x54,0x6a,0x23, +0x25,0x52,0x2c,0x23,0x72,0x5c,0xc3,0x5b,0xd5,0x59,0x9d,0x5d,0x50,0x62,0x32,0x53, +0x53,0x5a,0x95,0x5b,0xc1,0x5b,0xb2,0x54,0x9c,0x31,0x10,0xc2,0x92,0x33,0x00,0x00, +0x70,0xe8,0x15,0x4d,0x16,0x63,0x66,0xda,0xc2,0x66,0xde,0xd0,0xa7,0x1b,0x52,0x9d, +0x2c,0x5b,0x4d,0x22,0x90,0xd2,0xc0,0xac,0xb4,0xd4,0x7d,0x28,0x4c,0xde,0x4a,0xd1, +0x9c,0x31,0x10,0x5d,0x81,0x33,0x00,0x00,0x65,0xab,0xc2,0x12,0xdf,0xa6,0xab,0x5a, +0x5a,0xa2,0x31,0x5a,0x4b,0x25,0x88,0x4a,0xb1,0x24,0xaa,0x99,0x82,0x53,0x5e,0x9c, +0x5b,0x5c,0x76,0x22,0x93,0x52,0x9a,0x25,0x9c,0x31,0x10,0x7b,0x52,0x23,0x00,0x00, +0xe2,0x12,0x66,0x6c,0x2e,0x8a,0x3c,0xf4,0x85,0x52,0xb9,0x5d,0xb5,0xe1,0x92,0xdc, +0x75,0xf3,0x6a,0x5d,0x4d,0x0a,0x66,0x2b,0x7a,0x63,0x8e,0x1b,0xa2,0x0a,0x99,0xe3, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_SIX.txt b/config/_default_cfg_src_/res/cn/SOUND_SIX.txt new file mode 100644 index 0000000..37840a9 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_SIX.txt @@ -0,0 +1,130 @@ +0x9c,0x31,0x10,0x21,0x61,0x22,0x00,0x00,0x7e,0xdb,0x7e,0xdb,0x7e,0xdb,0x7f,0x1b, +0x7e,0xe4,0x88,0x9a,0x8e,0xe4,0x83,0x15,0x70,0x18,0x6f,0x15,0x82,0xa9,0xa0,0xd6, +0xa8,0xd9,0x8a,0xd4,0x57,0x13,0x39,0x23,0x9c,0x31,0x10,0xb6,0xa2,0x21,0x00,0x00, +0x7e,0x65,0x84,0x4e,0x86,0x89,0x82,0x52,0x78,0x8c,0x72,0x4d,0x77,0x29,0x87,0x88, +0x95,0x72,0x8f,0x4d,0x71,0x50,0x54,0x84,0x5c,0x71,0x8f,0x4a,0xc3,0x71,0xba,0x4d, +0x9c,0x31,0x10,0x10,0xb4,0x66,0x00,0x00,0x74,0xdb,0x4e,0xdb,0x54,0x9b,0x84,0xdc, +0xb8,0xda,0xb8,0xdb,0x80,0xdb,0x45,0x65,0x38,0x90,0x62,0xec,0x9c,0x53,0xc2,0xeb, +0xc4,0xd2,0x99,0x64,0x52,0x93,0x2c,0xab,0x9c,0x31,0x10,0x39,0xb5,0x66,0x10,0x00, +0x42,0x8c,0x7a,0xe9,0xac,0xcd,0xc6,0xe1,0xbc,0x94,0x86,0xa2,0x45,0x89,0x2f,0x2e, +0x51,0x12,0x86,0xe4,0xaf,0x13,0xc5,0x1b,0xb6,0xd9,0x78,0x53,0x3c,0xa6,0x34,0xc9, +0x9c,0x31,0x10,0xea,0xb7,0x98,0x30,0x00,0x5d,0xbb,0x8d,0xbb,0xb5,0xbb,0xc5,0xbb, +0xa1,0xbb,0x5a,0x3c,0x35,0xb2,0x49,0xc2,0x79,0xbc,0xa9,0x32,0xe4,0xd6,0xb2,0x5b, +0x3d,0x3a,0x05,0x93,0x4d,0xab,0xc5,0xb3,0x9c,0x31,0x10,0xde,0xc8,0xa9,0x30,0x00, +0xb1,0xcb,0x99,0xc4,0x75,0xb2,0x3c,0xb4,0x32,0x20,0x7d,0xcd,0xc6,0x41,0xb1,0x33, +0x85,0x2c,0x69,0xca,0x3c,0xbd,0x36,0x11,0x89,0xe3,0xcd,0xbc,0xb9,0xa2,0x8d,0x45, +0x9c,0x31,0x10,0xde,0xc8,0xa9,0x30,0x00,0x62,0x4a,0x24,0x9a,0x41,0x66,0xa9,0x39, +0xd5,0xa4,0xa9,0xc2,0x81,0x64,0x5a,0x1b,0x25,0xcc,0x51,0xd8,0xb9,0x96,0xd1,0x4a, +0xa5,0xd4,0x76,0x23,0x39,0x43,0x22,0xba,0x9c,0x31,0x10,0x6a,0xc8,0xa9,0x20,0x00, +0x7d,0x9e,0xd1,0xd8,0xc5,0x35,0x8d,0x1a,0x62,0x63,0x24,0x23,0x35,0xb6,0xa1,0xe0, +0xd9,0x9d,0xb5,0xc3,0x79,0xd2,0x46,0x23,0x1a,0x5d,0x61,0xa8,0xc9,0xad,0xd5,0xd2, +0x9c,0x31,0x10,0x6a,0xc8,0xa9,0x20,0x00,0x9d,0xb3,0x62,0x2b,0x24,0x4c,0x2a,0x19, +0x99,0xdb,0xdd,0xab,0xbd,0xb2,0x81,0x4b,0x4a,0x2c,0x11,0xcb,0x51,0x51,0xc5,0x8e, +0xe1,0xda,0xa5,0xb3,0x66,0x3b,0x24,0xc4,0x9c,0x31,0x10,0x6a,0xc8,0xa9,0x20,0x00, +0x1e,0x90,0x91,0xce,0xe1,0xc9,0xc9,0xa4,0x85,0x43,0x4e,0xbc,0x11,0x39,0x45,0x5c, +0xc1,0x1c,0xe9,0xc2,0xad,0x3b,0x6a,0x3b,0x29,0x43,0x17,0x2a,0x81,0xa6,0xe2,0x59, +0x9c,0x31,0x10,0x6a,0xc8,0xa9,0x20,0x00,0xd5,0xac,0x89,0x3a,0x52,0xc4,0x10,0x21, +0x39,0xde,0xb9,0x39,0xee,0x2c,0xb5,0xbb,0x6e,0x43,0x31,0xb3,0x0a,0xdc,0x71,0x93, +0xe1,0xcb,0xe1,0xbc,0x91,0x3a,0x52,0x3b,0x9c,0x31,0x10,0xdf,0xc9,0x99,0x20,0x00, +0x0e,0x54,0x2b,0x14,0xb2,0xf1,0xf4,0xc5,0xc0,0xd9,0x72,0xe4,0x3d,0x13,0x04,0xf4, +0x5e,0xe1,0xdc,0xc5,0xee,0xea,0x9a,0xdb,0x5c,0xd3,0x1c,0x9c,0x17,0x01,0x9e,0xed, +0x9c,0x31,0x10,0x51,0xc8,0xa8,0x30,0x00,0xf6,0x41,0xc9,0xb4,0x79,0xab,0x4e,0x4a, +0x08,0x21,0x3d,0xee,0xc9,0x2a,0xf6,0x2a,0xa9,0xc5,0x66,0x4a,0x32,0x32,0x06,0xce, +0x79,0xa2,0xed,0xc1,0xd9,0xc5,0x85,0x39,0x9c,0x31,0x10,0x4f,0xd8,0xa9,0x20,0x00, +0x6e,0x3b,0x48,0x3c,0x4a,0x9a,0x95,0xd3,0xbe,0x44,0x9d,0x2a,0x79,0xac,0x66,0x53, +0x40,0x2a,0x61,0xd4,0xa8,0xbb,0xb6,0x33,0x89,0x33,0x76,0x43,0x5e,0x42,0x3a,0x55, +0x9c,0x31,0x10,0x66,0xd9,0xa9,0x30,0x00,0x75,0xa9,0xb9,0xb4,0xad,0xc3,0x7d,0xcb, +0x76,0x33,0x55,0xbb,0x3e,0xa9,0x91,0xad,0xc1,0xc2,0x99,0xc3,0x79,0xbb,0x79,0xaa, +0x44,0xb4,0x46,0x1b,0xa9,0x3a,0xb9,0xdc,0x9c,0x31,0x10,0xfa,0xd9,0x99,0x20,0x00, +0x88,0x9b,0x7c,0xc2,0x7a,0xd4,0x38,0x19,0x53,0x25,0xb6,0xa2,0xb7,0x1b,0x80,0x8c, +0x82,0xd2,0x77,0x24,0x2c,0x52,0x62,0xf3,0xc4,0x9c,0xab,0x1a,0x78,0xd4,0x8e,0xda, +0x9c,0x31,0x10,0xcf,0xda,0x98,0x20,0x00,0x76,0x25,0x21,0x12,0x69,0xf2,0xcd,0xa5, +0x9a,0x18,0x75,0xde,0x99,0xc9,0x75,0xdc,0x14,0xc9,0x6e,0x34,0xcd,0x64,0x92,0x29, +0x75,0xdd,0xa9,0xd1,0x75,0xd3,0x10,0xca,0x9c,0x31,0x10,0x0e,0xda,0x98,0x10,0x00, +0x6a,0x4e,0xd1,0x59,0x86,0x23,0x79,0xa4,0xb1,0xe2,0x7d,0xd3,0x15,0xa5,0x5a,0xc8, +0xc9,0xd4,0x86,0x0c,0x79,0xd1,0xb1,0xd5,0x89,0xdb,0x2a,0x59,0x3e,0x36,0xb5,0xe9, +0x9c,0x31,0x10,0x0e,0xda,0x98,0x10,0x00,0x91,0x6a,0x7a,0x25,0xad,0xe1,0x99,0xdc, +0x4d,0xdc,0x2c,0xd1,0x86,0x8e,0xa5,0x90,0x7a,0x54,0x9d,0xd4,0xa5,0x9a,0x75,0xdc, +0x3e,0x52,0x45,0xed,0x9d,0xa2,0x91,0x22,0x9c,0x31,0x10,0x16,0xda,0x88,0x10,0x00, +0x89,0xe5,0xa5,0xa2,0x95,0xe3,0x65,0xdb,0x35,0xac,0x5f,0x21,0xa5,0xe4,0x86,0x24, +0x95,0xe2,0xa5,0x9b,0x8d,0xdc,0x5d,0x9a,0x34,0xda,0x6f,0x4d,0xa6,0x19,0x82,0x9c, +0x9c,0x31,0x10,0x85,0xdb,0x77,0x10,0x00,0x9c,0xe6,0xa2,0xd4,0x8a,0xf5,0x5c,0xf6, +0x30,0xc4,0x71,0x62,0xa9,0x04,0x81,0x14,0x9e,0xd6,0xa4,0xc5,0x8a,0xe5,0x61,0x05, +0x32,0xe9,0x65,0x75,0xaa,0xf8,0x80,0xda,0x9c,0x31,0x10,0x51,0xda,0x87,0x20,0x00, +0x98,0x6d,0xa6,0xac,0x91,0x4d,0x6d,0x2e,0x3d,0x11,0x48,0xd4,0xa8,0x2e,0x86,0x8d, +0x8f,0x6c,0xa9,0x4d,0x95,0x2e,0x7e,0x8d,0x54,0xcd,0x2e,0x48,0x87,0xcd,0xa3,0x0e, +0x9c,0x31,0x10,0x6d,0xda,0x77,0x30,0x00,0x7c,0xf5,0xa4,0x64,0xa0,0xd5,0x8b,0x66, +0x6b,0x45,0x3e,0xf5,0x48,0xb9,0xa8,0x56,0x87,0x15,0x8b,0x94,0xaa,0xc5,0x94,0xa5, +0x82,0xc6,0x65,0x65,0x37,0x09,0x5f,0x65,0x9c,0x31,0x10,0xfa,0xda,0x66,0x30,0x00, +0xae,0x14,0x7c,0xe6,0x93,0x86,0xa8,0xf5,0x90,0xd4,0x80,0xa5,0x65,0x45,0x32,0xe9, +0x65,0x95,0xae,0x34,0x7a,0xe5,0x95,0x65,0xa8,0xe5,0x90,0xd6,0x82,0xe5,0x69,0x34, +0x9c,0x31,0x10,0x6d,0xda,0x77,0x30,0x00,0x38,0xe9,0x57,0x24,0xac,0x55,0x83,0x36, +0x8b,0x36,0xa8,0x95,0x95,0x15,0x85,0x05,0x73,0x05,0x44,0xe5,0x3e,0x96,0xa5,0x15, +0x93,0x34,0x7c,0xc4,0xa6,0xe5,0x9d,0x26,0x9c,0x31,0x10,0x75,0xda,0x67,0x30,0x00, +0x86,0xd6,0x7c,0xe5,0x5d,0x14,0x30,0x94,0x79,0xb5,0xa8,0x66,0x79,0x05,0x93,0x35, +0xa6,0xa4,0x91,0x14,0x85,0x15,0x74,0xd5,0x49,0x21,0x3c,0x96,0x9f,0x35,0x95,0x04, +0x9c,0x31,0x10,0xc2,0xc9,0x57,0x30,0x00,0x74,0x6a,0xbb,0x4a,0xbe,0xcc,0x98,0xa4, +0x89,0x2c,0x5e,0xeb,0x00,0xea,0x16,0xd1,0xd6,0x8b,0x99,0x6d,0x74,0x6d,0xc1,0x2b, +0xba,0xe9,0x94,0xca,0x87,0x2b,0x5c,0xcc,0x9c,0x31,0x10,0xdc,0xd9,0x56,0x20,0x00, +0x41,0x0c,0x4a,0xb2,0xaa,0xab,0x8d,0x8b,0x78,0x2b,0x9f,0xaa,0xa0,0x8c,0x88,0xcc, +0x85,0x4c,0x72,0x8b,0x49,0x62,0x3c,0x2c,0xa1,0x8c,0x96,0xab,0x78,0xa9,0x91,0x89, +0x9c,0x31,0x10,0xd2,0xda,0x56,0x30,0x00,0xa6,0x95,0x8b,0x35,0x84,0xf5,0x80,0xd5, +0x5b,0x35,0x34,0xa4,0x75,0x92,0xac,0x46,0x7d,0x85,0x7c,0x94,0xa3,0x24,0x98,0xf4, +0x82,0xd5,0x89,0x35,0x76,0xb6,0x4f,0x41,0x9c,0x31,0x10,0x5d,0xda,0x57,0x30,0x00, +0x3a,0x65,0x99,0x95,0x9c,0x84,0x77,0x25,0x82,0xf5,0xa8,0xc5,0x91,0x45,0x80,0xa5, +0x8b,0x35,0x72,0xc5,0x4d,0x31,0x3c,0x85,0xa3,0x66,0x96,0x95,0x77,0x25,0x83,0x04, +0x9c,0x31,0x10,0xca,0xda,0x46,0x30,0x00,0xa6,0xc4,0x8d,0x45,0x82,0x95,0x8b,0x55, +0x74,0x95,0x4f,0x61,0x3a,0x46,0x97,0xb5,0x9e,0x44,0x7b,0x84,0x7a,0x95,0xa5,0x26, +0x92,0xd6,0x86,0xf6,0x87,0x05,0x84,0xc4,0x9c,0x31,0x10,0x6e,0xda,0x47,0x40,0x00, +0x59,0x35,0x3c,0x90,0x6b,0x81,0xb4,0x56,0x7d,0x95,0x78,0x65,0x91,0x85,0xa2,0x74, +0x85,0x65,0x84,0x95,0x8b,0x55,0x70,0xa5,0x4d,0x61,0x40,0x59,0x9d,0xb5,0x9c,0x45, +0x9c,0x31,0x10,0xef,0xca,0x46,0x30,0x00,0x71,0x95,0x72,0x74,0xc3,0x64,0xac,0x95, +0x8b,0x35,0x88,0xb6,0x95,0x15,0x44,0xd5,0x05,0x29,0x22,0xc5,0xed,0x24,0x90,0xc4, +0x73,0x25,0x7a,0xc6,0xd9,0x16,0x96,0xd6,0x9c,0x31,0x10,0x80,0xc8,0x36,0x30,0x00, +0x8b,0xb3,0x8c,0x52,0x90,0x81,0x31,0x89,0x05,0x52,0x4d,0xde,0xf2,0x26,0x7d,0xbc, +0x74,0x52,0x85,0x89,0xd9,0x79,0x8d,0x73,0x8c,0x8d,0x8e,0x75,0x86,0x6c,0x29,0xa2, +0x9c,0x31,0x10,0x55,0xc9,0x46,0x30,0x00,0x06,0x80,0x61,0x69,0xee,0x6c,0x77,0x4d, +0x74,0xad,0x87,0x0c,0xd4,0xea,0x88,0xe9,0x87,0x0a,0x90,0xeb,0x86,0xeb,0x2e,0xec, +0x0a,0xc2,0x55,0x2b,0xee,0xcc,0x7e,0xec,0x9c,0x31,0x10,0x55,0xc9,0x46,0x30,0x00, +0x6f,0x0b,0x7e,0xaa,0xcd,0x2a,0x92,0x8a,0x85,0x4b,0x90,0x8c,0x91,0x2c,0x48,0x8c, +0x17,0x74,0x2e,0x4b,0xd5,0x88,0xa6,0x29,0x69,0xab,0x74,0x2d,0xb5,0xad,0xb2,0x4c, +0x9c,0x31,0x10,0x55,0xc9,0x46,0x30,0x00,0x7b,0x8a,0x92,0x69,0x8d,0x4a,0x6a,0x8b, +0x27,0x43,0x1a,0x56,0x91,0xad,0xd4,0x4a,0x6d,0x69,0x72,0x89,0x8d,0x0b,0xc8,0xed, +0x84,0xed,0x89,0x0c,0x8c,0xcb,0x7f,0x0a,0x9c,0x31,0x10,0xc8,0xc8,0x46,0x30,0x00, +0x40,0xca,0x16,0xe1,0x5b,0x2b,0xde,0xee,0x8c,0xad,0x6b,0x6b,0x7a,0x49,0xbb,0xa9, +0xa4,0x2b,0x7b,0x8c,0x90,0x6d,0x87,0x2c,0x5c,0xab,0x23,0x73,0x2a,0x29,0xb5,0xca, +0x9c,0x31,0x10,0x44,0xc8,0x45,0x30,0x00,0xbc,0x06,0x71,0xe6,0x71,0x16,0x99,0xb5, +0xc0,0x44,0x88,0x84,0x87,0x75,0x83,0x65,0x74,0x86,0x3b,0x82,0x1a,0x36,0x7d,0xc5, +0xd7,0x34,0x88,0x94,0x6e,0x85,0x7e,0x56,0x9c,0x31,0x10,0x34,0xc8,0x36,0x20,0x00, +0xbb,0xbc,0xa0,0x3b,0x80,0xba,0x8a,0x4a,0x7e,0x9a,0x58,0x63,0x21,0x93,0x41,0x65, +0xc6,0xa4,0xad,0x3a,0x71,0xca,0x6e,0x2a,0x9c,0xbc,0xb9,0x4c,0x85,0x94,0x8c,0x83, +0x9c,0x31,0x10,0xf0,0xc8,0x45,0x20,0x00,0x85,0x64,0x6b,0x74,0x3a,0x94,0x1e,0x29, +0x90,0xd6,0xcb,0x26,0x82,0xb5,0x6b,0x54,0x78,0x64,0xb7,0x95,0x9b,0x46,0x82,0xa6, +0x8f,0x55,0x7c,0x85,0x62,0x75,0x2f,0x85,0x9c,0x31,0x10,0xd0,0xc7,0x35,0x20,0x00, +0x3e,0x52,0xb3,0xb5,0xb3,0x15,0x79,0xe4,0x6c,0x15,0x87,0xa5,0xb4,0x75,0x8d,0x45, +0x87,0xc5,0x8b,0x25,0x74,0xa5,0x59,0x65,0x2b,0x41,0x5f,0xb5,0xbe,0x55,0x9d,0x55, +0x9c,0x31,0x10,0x0c,0xc7,0x23,0x10,0x00,0x77,0xc6,0x6d,0x15,0x94,0xc4,0xae,0x44, +0x86,0x74,0x8c,0xa8,0x83,0x35,0x6f,0xa5,0x4e,0x75,0x32,0x38,0x7f,0xd6,0xbc,0x2a, +0x8e,0x95,0x75,0x84,0x71,0x45,0x9b,0xb6,0x9c,0x31,0x10,0x86,0xc7,0x24,0x10,0x00, +0xa2,0x46,0x82,0x75,0x91,0x95,0x85,0x49,0x6b,0xa5,0x4e,0x79,0x3a,0x38,0x8a,0xc8, +0xb5,0x29,0x88,0xa5,0x76,0x75,0x70,0x55,0x97,0xa4,0x9d,0x44,0x7c,0x85,0x8c,0x82, +0x9c,0x31,0x10,0xf6,0xb6,0x13,0x00,0x00,0xad,0x45,0x6e,0x8b,0x32,0xa2,0x00,0x1d, +0x52,0xd4,0xe4,0x63,0xb0,0x3b,0x73,0xf3,0x65,0x0c,0x85,0xc3,0xc0,0x7a,0x8f,0x52, +0x78,0x89,0xa9,0x91,0x99,0x4c,0x56,0x9d,0x9c,0x31,0x10,0xc9,0xb7,0x24,0x00,0x00, +0x1d,0x14,0x14,0x8b,0x9f,0x69,0xda,0x82,0x89,0x24,0x6c,0xec,0x6a,0xac,0xa3,0x2b, +0xb4,0xca,0x76,0xe2,0x83,0x2b,0x98,0xac,0x7f,0x14,0x68,0xcb,0x40,0xea,0x3a,0xeb, +0x9c,0x31,0x10,0xc3,0xb5,0x12,0x00,0x00,0x7d,0x98,0xc5,0x66,0xb6,0x5a,0x8b,0xb2, +0x6f,0x45,0x6f,0x88,0x6a,0xa5,0x2f,0x12,0x48,0xd5,0xbb,0x54,0xc4,0x35,0x9a,0xe9, +0x73,0x21,0x6f,0x96,0x9c,0x96,0x93,0x21,0x9c,0x31,0x10,0xce,0xa5,0x22,0x00,0x00, +0x5f,0xa5,0x4b,0x65,0x3e,0x49,0x79,0xb9,0xb4,0x45,0xae,0x85,0x9f,0x85,0x7c,0x55, +0x5e,0x95,0x54,0x75,0x38,0x75,0x51,0x7a,0xaf,0x75,0xe0,0x76,0xbd,0x75,0x86,0x75, +0x9c,0x31,0x10,0xce,0xa5,0x22,0x00,0x00,0x5f,0x65,0x4b,0x89,0x35,0x99,0x3f,0x45, +0xb8,0xc5,0xf3,0x25,0xb7,0x99,0x84,0x89,0x54,0x46,0x45,0xb4,0x30,0x12,0x49,0xa4, +0xc1,0x84,0xb9,0x29,0x8e,0xd6,0x87,0x36,0x9c,0x31,0x10,0x14,0x94,0x12,0x00,0x00, +0x81,0x03,0xcd,0x6b,0x92,0x01,0x3b,0xca,0x52,0x8d,0x66,0x8c,0xa3,0xb3,0xa6,0x6a, +0x6d,0x4a,0x6e,0xf2,0x68,0x95,0x71,0x2b,0x7c,0xeb,0x76,0xf3,0x87,0x0b,0x82,0x82, +0x9c,0x31,0x10,0x17,0x62,0x21,0x00,0x00,0x57,0xae,0x7c,0xad,0x36,0xea,0x43,0x91, +0x62,0x2e,0x9f,0x2d,0xe9,0x15,0x9a,0xed,0x57,0x4c,0x4d,0x0d,0x4d,0x11,0x7b,0x32, +0x66,0x6e,0x6b,0x88,0x8c,0x25,0x97,0x89,0x9c,0x31,0x10,0x3f,0x62,0x11,0x00,0x00, +0x88,0x89,0x30,0x8d,0x1a,0xea,0x5f,0x2d,0x84,0xad,0x93,0x11,0x96,0x29,0x80,0xec, +0x6a,0xad,0x58,0xc1,0x54,0xee,0x60,0xf5,0x66,0xd1,0x78,0xd1,0x8a,0xe9,0x6b,0x35, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_THREE.txt b/config/_default_cfg_src_/res/cn/SOUND_THREE.txt new file mode 100644 index 0000000..52fd053 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_THREE.txt @@ -0,0 +1,120 @@ +0x9c,0x31,0x10,0x80,0x44,0x54,0x20,0x00,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x5b,0x72,0xbb,0x92,0xc3,0x8e,0x54,0xa9,0x64,0x85,0xb1,0x65,0xe2,0x8d,0xbd,0x50, +0x95,0x2d,0xc4,0x71,0xbb,0x2d,0xac,0x4d,0x9c,0x31,0x10,0xf9,0x55,0x54,0x10,0x00, +0x6b,0x4a,0x8a,0xbb,0x6b,0xce,0x64,0x41,0x7c,0x3a,0x9b,0xb9,0x7c,0x3b,0x7c,0xc5, +0x74,0x45,0xa3,0xbd,0xaa,0xe2,0x7c,0xae,0x53,0xa0,0x4c,0x31,0x31,0x9b,0x5b,0x2c, +0x9c,0x31,0x10,0x3b,0x55,0x56,0x20,0x00,0x56,0x9c,0x63,0x58,0x67,0x20,0x78,0xe1, +0x69,0x21,0x9b,0x15,0xa6,0xe1,0xa6,0x66,0xa9,0x56,0xb6,0xd6,0x88,0x69,0xab,0x5d, +0x76,0x89,0xa2,0x25,0xa4,0x9c,0x64,0xdc,0x9c,0x31,0x10,0x7c,0x65,0x66,0x20,0x00, +0x9a,0x86,0xa4,0xb9,0x84,0x86,0xa3,0x77,0x53,0x79,0x84,0x66,0x74,0x5a,0x99,0x76, +0x73,0x75,0xa6,0x46,0x93,0xa9,0xc2,0x78,0xac,0xb3,0x89,0x54,0x92,0x58,0x80,0xeb, +0x9c,0x31,0x10,0x25,0x56,0x65,0x20,0x00,0x93,0x0c,0x2d,0xd1,0x7d,0xba,0x74,0x84, +0x6d,0x26,0x8a,0x4c,0xa2,0xe2,0x3b,0x59,0x34,0xf1,0x53,0x15,0x9c,0x2a,0x52,0x0b, +0x7b,0xbc,0x76,0x3c,0x02,0x90,0x5b,0x59,0x9c,0x31,0x10,0x5b,0x67,0x66,0x20,0x00, +0x7b,0xad,0x73,0x14,0x82,0xca,0x5d,0x52,0xba,0xbb,0x93,0x63,0x8b,0x0a,0x7c,0x1c, +0x93,0x63,0x9b,0x5c,0x94,0xdc,0xb3,0xc2,0xaa,0x1b,0xa1,0x99,0x7c,0xb4,0x9c,0xb9, +0x9c,0x31,0x10,0x1b,0x79,0x86,0x20,0x00,0x73,0xb4,0x6b,0x3c,0x83,0x34,0x6c,0x34, +0x43,0x39,0x43,0xbc,0x43,0xc0,0x73,0xbb,0x1b,0xbb,0x1c,0x36,0xdc,0x32,0xe9,0xd8, +0xc3,0x3b,0x84,0x4b,0x94,0x4d,0x93,0x4b,0x9c,0x31,0x10,0xa8,0x87,0x76,0x20,0x00, +0x89,0xa2,0x72,0xb2,0x46,0x2b,0x4e,0x9b,0x36,0x89,0x3b,0x0b,0x3a,0x8d,0x56,0x0a, +0x6d,0x94,0x7c,0xdc,0x92,0x22,0x75,0x98,0x96,0x1d,0xb1,0xdb,0xbd,0x91,0xde,0x1c, +0x9c,0x31,0x10,0x1c,0x98,0x75,0x00,0x00,0xb1,0xee,0xd2,0x8c,0x95,0x12,0x5a,0x2d, +0x6d,0x65,0x8d,0xee,0x52,0xe4,0x7d,0x6e,0x99,0xa9,0x89,0x8d,0x61,0xd4,0x72,0x12, +0x71,0xc8,0x55,0xa9,0x59,0xf2,0x69,0xac,0x9c,0x31,0x10,0xc7,0xb7,0x76,0x20,0x00, +0x7c,0x1a,0x81,0x1c,0x7e,0xa4,0x84,0xd2,0x86,0xd3,0x92,0xea,0x8a,0xdd,0x78,0xda, +0x71,0x18,0x72,0x9b,0x83,0x25,0x96,0xe5,0xa1,0x29,0x75,0x1b,0x1f,0x1d,0x15,0x22, +0x9c,0x31,0x10,0xeb,0xd9,0x87,0x20,0x00,0x87,0x0d,0xb0,0xcd,0xa9,0x0d,0x70,0xad, +0x46,0xf0,0x4f,0x1a,0x98,0xda,0xba,0xf8,0xa6,0xf8,0x85,0x16,0x57,0x71,0x36,0x49, +0x76,0x70,0xb0,0x52,0xa2,0x8e,0x92,0xb1,0x9c,0x31,0x10,0xfd,0xda,0x97,0x30,0x00, +0x7a,0xd0,0x3c,0xf4,0x37,0x98,0xa5,0x36,0xb3,0x32,0x8e,0xf0,0x98,0xec,0x79,0x0e, +0x1e,0x65,0x59,0x62,0xc2,0xe1,0x95,0x41,0x90,0xe1,0xa6,0xa5,0x5a,0xe6,0x16,0x21, +0x9c,0x31,0x10,0x53,0xda,0xa8,0x30,0x00,0x99,0x58,0xa8,0x61,0x7a,0x25,0xb1,0x6a, +0x95,0xe9,0x31,0xe4,0x36,0x2d,0xb1,0x6d,0x81,0x29,0x9a,0x65,0xb1,0xe5,0x7a,0xdd, +0x35,0xdd,0x53,0xa5,0x95,0x5d,0x82,0x9d,0x9c,0x31,0x10,0x60,0xdb,0x97,0x30,0x00, +0xbc,0xc9,0xa0,0xe8,0x7d,0x05,0x2e,0xce,0x59,0x8c,0x90,0xca,0x83,0x44,0xc2,0xc9, +0x9f,0x05,0x7a,0xe5,0x2c,0x89,0x63,0x62,0x80,0xa0,0x91,0x62,0xc4,0x85,0x9d,0x00, +0x9c,0x31,0x10,0xce,0xdb,0xa8,0x30,0x00,0x71,0xd5,0x24,0xd1,0x6e,0x4e,0x75,0x10, +0x9e,0x95,0xc1,0x19,0x99,0xd8,0x69,0xdd,0x24,0xd0,0x75,0x9a,0x6d,0x19,0xb2,0x61, +0xb9,0x5d,0x99,0xe1,0x5d,0xa1,0x25,0x5d,0x9c,0x31,0x10,0x52,0xdb,0x98,0x20,0x00, +0x79,0x29,0x6d,0x6d,0xbd,0xeb,0xb1,0xab,0x95,0xf3,0x4d,0xeb,0x32,0x36,0x7c,0xf0, +0x71,0xf3,0xc5,0xac,0xae,0x2b,0x96,0x2b,0x41,0xe2,0x36,0xf4,0x7d,0x33,0x7a,0x6b, +0x9c,0x31,0x10,0x69,0xdb,0x99,0x30,0x00,0xc9,0x63,0xaa,0x6b,0x8e,0x24,0x31,0xea, +0x47,0xb2,0x79,0x2c,0x86,0xe3,0xc9,0x23,0xa6,0x5b,0x82,0x1b,0x2d,0x9c,0x53,0x99, +0x75,0x53,0x93,0x14,0xc5,0x13,0xa6,0x4b,0x9c,0x31,0x10,0x7a,0xdb,0xa8,0x20,0x00, +0x79,0xd5,0x25,0x1a,0x5f,0x11,0x71,0x50,0xa3,0x11,0xc1,0x15,0xa2,0x15,0x71,0xd4, +0x20,0xd5,0x66,0x8e,0x71,0x90,0xae,0xd5,0xbd,0x55,0x9d,0xd5,0x65,0xd9,0x20,0xcc, +0x9c,0x31,0x10,0x52,0xdb,0x98,0x20,0x00,0x6d,0xc5,0x6d,0x4c,0xba,0x12,0xb9,0x92, +0x99,0x9b,0x5d,0xdd,0x20,0xc8,0x75,0x53,0x75,0x56,0xbd,0xda,0xb5,0x9a,0x95,0x9b, +0x51,0x9c,0x29,0x54,0x78,0xe0,0x79,0x9c,0x9c,0x31,0x10,0x69,0xdb,0x99,0x30,0x00, +0xc1,0xa3,0xad,0xe3,0x95,0xa2,0x49,0xdb,0x2d,0xe5,0x78,0xea,0x7d,0xea,0xc5,0x63, +0xae,0x2b,0x8d,0xab,0x45,0xe2,0x32,0x75,0x79,0x33,0x81,0xf2,0xc5,0x6b,0xaa,0x2b, +0x9c,0x31,0x10,0xe6,0xdb,0x98,0x30,0x00,0x89,0xeb,0x3d,0xe1,0x36,0xb5,0x7d,0x2d, +0x86,0x2a,0xc9,0x6b,0xaa,0x6b,0x86,0x24,0x3d,0xe1,0x3a,0xf3,0x7d,0x6e,0x8a,0x6a, +0xc5,0x6a,0xa6,0x63,0x86,0x24,0x39,0xe2,0x9c,0x31,0x10,0xe6,0xdb,0x98,0x30,0x00, +0x3e,0xf2,0x7d,0x6d,0x8e,0x6b,0xc5,0x63,0xa6,0x63,0x82,0x23,0x39,0xe2,0x42,0xe9, +0x7d,0x66,0x92,0xa3,0xc5,0x63,0xa6,0x5a,0x7e,0x1b,0x35,0xe4,0x42,0xe8,0x81,0xa4, +0x9c,0x31,0x10,0x4a,0xdb,0x88,0x20,0x00,0x96,0xa4,0xc5,0x63,0xa2,0x52,0x7a,0x14, +0x35,0xdc,0x42,0xe0,0x81,0x94,0x96,0x53,0xc5,0x53,0xa2,0x13,0x7a,0x0b,0x31,0x9c, +0x46,0xd9,0x81,0x93,0x9a,0x54,0xc5,0x93,0x9c,0x31,0x10,0x63,0xda,0x88,0x30,0x00, +0xa2,0x4b,0x76,0x4a,0x31,0x5d,0x47,0x51,0x81,0x4a,0x9f,0x0c,0xc5,0x4b,0xa2,0x0c, +0x72,0x0a,0x31,0x65,0x4b,0x8a,0x81,0x49,0x9f,0x0c,0xc5,0x53,0xa2,0x0c,0x72,0x4a, +0x9c,0x31,0x10,0x50,0xda,0x98,0x40,0x00,0x2d,0x5c,0x4f,0x4d,0x81,0x49,0xa3,0x12, +0xc1,0x4b,0x9d,0xcc,0x6e,0x12,0x2d,0x13,0x4f,0x0d,0x81,0x52,0xa2,0x93,0xc1,0x53, +0x9d,0xd3,0x69,0xd3,0x2d,0x13,0x4e,0x8d,0x9c,0x31,0x10,0xd9,0xd9,0x88,0x30,0x00, +0x82,0x42,0xa7,0x8b,0xc4,0x8b,0x9e,0x93,0x69,0x1b,0x2a,0x12,0x53,0x45,0x84,0x4b, +0xab,0x53,0xc2,0x93,0x9e,0x9a,0x64,0xdb,0x2c,0x12,0x53,0x0c,0x86,0x54,0xad,0x53, +0x9c,0x31,0x10,0x5f,0xd9,0x87,0x30,0x00,0xc2,0xc9,0x9c,0xcd,0x60,0xed,0x2a,0x24, +0x54,0xe9,0x86,0x4e,0xb1,0x0d,0xc2,0xad,0x9c,0xd1,0x60,0xed,0x2a,0x25,0x54,0xc8, +0x88,0x4d,0xb3,0x0d,0xc2,0xd1,0x9a,0xd1,0x9c,0x31,0x10,0xd7,0xd9,0x77,0x30,0x00, +0x5c,0xf1,0x2a,0x69,0x52,0xd0,0x88,0x91,0xb4,0xf5,0xc4,0xd9,0x9c,0xd1,0x5a,0xed, +0x2a,0x8a,0x50,0xd1,0x8a,0xb1,0xb6,0xf1,0xc2,0xd4,0x9c,0xf1,0x5b,0x0d,0x2a,0xd6, +0x9c,0x31,0x10,0xad,0xd7,0x76,0x30,0x00,0x4e,0x74,0x88,0x6c,0xb8,0xac,0xc2,0xa1, +0x9d,0x22,0x5b,0x21,0x30,0xf3,0x4c,0xb4,0x84,0xac,0xb4,0xac,0xc0,0xe3,0xa1,0x23, +0x65,0x62,0x3b,0x32,0x48,0xeb,0x78,0xeb,0x9c,0x31,0x10,0xf2,0xd6,0x74,0x00,0x00, +0xaa,0x36,0xbe,0x72,0xa8,0x51,0x76,0xb0,0x46,0x71,0x41,0x71,0x69,0x51,0x9d,0x51, +0xbc,0x51,0xb3,0x71,0x89,0x6d,0x51,0x71,0x3a,0x91,0x56,0x51,0x8d,0x6d,0xba,0x71, +0x9c,0x31,0x10,0xf2,0xd5,0x53,0x00,0x00,0xc0,0x75,0x99,0x51,0x58,0x72,0x35,0x78, +0x4a,0x55,0x83,0x51,0xb8,0x74,0xc6,0x75,0xa2,0x31,0x5f,0x91,0x35,0x78,0x45,0x35, +0x7c,0x4e,0xb4,0x71,0xc7,0x75,0xa6,0x31,0x9c,0x31,0x10,0xf2,0xd5,0x53,0x00,0x00, +0x63,0x6c,0x37,0x54,0x43,0x16,0x79,0x4e,0xb2,0x6d,0xc7,0x51,0xa9,0x31,0x66,0x6c, +0x38,0x54,0x42,0x35,0x77,0x6e,0xb0,0x6d,0xc7,0x52,0xaa,0x51,0x69,0x8c,0x3a,0x51, +0x9c,0x31,0x10,0x5e,0xd5,0x43,0x10,0x00,0x43,0x39,0x76,0x6a,0xae,0x49,0xc5,0x55, +0xa9,0x55,0x69,0x8c,0x3c,0x74,0x45,0x19,0x77,0x8e,0xad,0x2e,0xc3,0x7a,0xa7,0x39, +0x68,0x90,0x3d,0x50,0x47,0x14,0x79,0x91,0x9c,0x31,0x10,0xf2,0xd5,0x53,0x00,0x00, +0xaf,0x4d,0xc2,0x56,0xa4,0x52,0x66,0x91,0x3d,0x95,0x4a,0x34,0x7c,0x90,0xb0,0x72, +0xc0,0x76,0x9f,0x52,0x62,0x8d,0x3e,0xb1,0x4e,0x34,0x82,0x8c,0xb2,0x71,0xbd,0x91, +0x9c,0x31,0x10,0x7b,0xc5,0x43,0x10,0x00,0xb2,0x51,0x3c,0xb2,0x01,0xd9,0x28,0x55, +0x8e,0xad,0xe7,0x94,0xf3,0xad,0xa2,0x40,0x33,0x8d,0x05,0xd5,0x37,0x6a,0x9c,0x8d, +0xeb,0x6a,0xe9,0x85,0x92,0x44,0x29,0x6c,0x9c,0x31,0x10,0x40,0xc5,0x42,0x00,0x00, +0x0a,0xad,0x43,0x64,0xa9,0x8d,0xee,0x66,0xdf,0x85,0x82,0x4e,0x23,0x6d,0x11,0x61, +0x53,0x62,0xb5,0x48,0xee,0x6a,0xd2,0x68,0x6f,0x2d,0x1b,0x49,0x19,0x40,0x64,0x6d, +0x9c,0x31,0x10,0x40,0xc5,0x42,0x00,0x00,0xc3,0x4e,0xee,0x51,0xc3,0x7a,0x5e,0x55, +0x17,0x6e,0x25,0x31,0x76,0xb4,0xcd,0x55,0xe9,0x71,0xb0,0x6d,0x4b,0x68,0x15,0x8d, +0x33,0x35,0x89,0x92,0xd8,0x69,0xe0,0x6a,0x9c,0x31,0x10,0xae,0xc4,0x33,0x10,0x00, +0x9a,0xb5,0x3c,0x39,0x19,0x59,0x44,0x89,0x9d,0x58,0xe1,0x39,0xd9,0x55,0x88,0xa5, +0x31,0x49,0x1e,0x56,0x55,0x32,0xae,0x42,0xe2,0xa1,0xc8,0xe5,0x71,0x84,0x27,0x54, +0x9c,0x31,0x10,0x7b,0xc5,0x43,0x10,0x00,0x25,0x48,0x66,0x89,0xbd,0x4d,0xe0,0x51, +0xb6,0x91,0x5f,0x4e,0x23,0x8a,0x32,0x49,0x7a,0x8d,0xc9,0x75,0xd9,0x55,0xa2,0x8d, +0x4e,0x50,0x26,0x8d,0x42,0x31,0x8f,0xb5,0x9c,0x31,0x10,0x08,0xc5,0x32,0x00,0x00, +0xd1,0xa6,0xcf,0xc1,0x8e,0xa2,0x41,0xc1,0x2a,0x45,0x53,0x95,0xa2,0xc5,0xd4,0x22, +0xbe,0xc2,0x76,0x95,0x38,0x49,0x34,0x39,0x6a,0xc5,0xb5,0x35,0xd1,0x34,0xab,0x48, +0x9c,0x31,0x10,0x95,0xc4,0x32,0x00,0x00,0x61,0x19,0x33,0xd8,0x42,0x15,0x83,0xe1, +0xc1,0x96,0xc6,0xc9,0x93,0x15,0x50,0xd1,0x36,0xa5,0x58,0x30,0x9b,0xc5,0xc3,0x25, +0xb2,0x49,0x78,0x99,0x47,0xc5,0x44,0xa5,0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00, +0x68,0xa5,0xd9,0x3a,0xf5,0x85,0xb0,0x75,0x47,0x85,0x11,0x65,0x38,0x75,0x9f,0xa1, +0xe4,0x31,0xd1,0x96,0x7c,0x58,0x2e,0xa9,0x24,0x35,0x67,0x95,0xbd,0x75,0xd7,0x89, +0x9c,0x31,0x10,0x0e,0xb3,0x21,0x00,0x00,0xa9,0x69,0x5b,0x6c,0x2f,0x81,0x43,0x69, +0x8c,0x85,0xc5,0x25,0xc1,0x8d,0x88,0x2e,0x4b,0x85,0x3c,0x4c,0x65,0x8e,0xa4,0x59, +0xbe,0x6d,0xa1,0x91,0x6b,0x74,0x4b,0xad,0x9c,0x31,0x10,0xa7,0xa3,0x22,0x00,0x00, +0x2f,0x51,0x8e,0xae,0xd9,0x28,0xd1,0xaa,0x89,0x29,0x40,0x8e,0x31,0x24,0x65,0x88, +0xae,0x69,0xc4,0x71,0xa1,0x71,0x65,0x71,0x45,0x68,0x57,0x65,0x8c,0x91,0xae,0x49, +0x9c,0x31,0x10,0x4d,0x92,0x32,0x00,0x00,0xc9,0x1c,0x7a,0x5a,0x39,0x13,0x3a,0x1b, +0x79,0x1b,0xb4,0x5a,0xb5,0x1b,0x8c,0x64,0x5f,0x12,0x54,0x63,0x6e,0x9b,0x92,0xdd, +0x98,0xe9,0x86,0xd2,0x70,0xda,0x6a,0x93,0x9c,0x31,0x10,0x17,0x62,0x21,0x00,0x00, +0x31,0x12,0xb8,0xe9,0xdd,0x0d,0x99,0x2d,0x2c,0xcd,0x1b,0x2d,0x72,0xf1,0xc9,0x09, +0xc7,0x08,0x6f,0x0e,0x1c,0x4d,0x25,0x05,0x90,0xb1,0xdf,0x05,0xd9,0x12,0x81,0x0d, +0x9c,0x31,0x10,0x17,0x62,0x21,0x00,0x00,0x3f,0x2a,0x3f,0x74,0x8c,0xee,0xb6,0xd5, +0xa9,0x24,0x60,0x8d,0x2f,0x71,0x26,0x45,0x71,0x59,0xb0,0x84,0xb3,0xaa,0x7e,0x4d, +0x59,0x0a,0x22,0xd4,0x33,0x89,0x7a,0x91,0x9c,0x31,0x10,0x17,0x62,0x21,0x00,0x00, +0xb9,0xa6,0x9e,0x11,0x5f,0xd1,0x30,0x45,0x33,0x92,0x78,0x69,0xad,0x25,0xae,0xaa, +0x78,0x6c,0x4f,0x0d,0x38,0xad,0x4a,0xf1,0x7b,0x2d,0x92,0xcd,0x95,0x09,0x82,0xb5, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_TWO.txt b/config/_default_cfg_src_/res/cn/SOUND_TWO.txt new file mode 100644 index 0000000..f34bc65 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_TWO.txt @@ -0,0 +1,120 @@ +0x9c,0x31,0x10,0xd1,0x42,0x22,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x79,0xdb,0x7a,0x1b, +0x5d,0xa5,0x5d,0xdc,0x7d,0x63,0x79,0x1b,0x7b,0x64,0x71,0x11,0x8e,0xe2,0xad,0x93, +0xd0,0xdc,0xc6,0x5d,0x89,0x59,0x4a,0x0b,0x9c,0x31,0x10,0x23,0x67,0x36,0x20,0x00, +0x79,0xd7,0x85,0xd7,0x79,0xd7,0x89,0xd7,0x85,0xd7,0x7d,0xd7,0x79,0xd7,0x89,0xd7, +0x85,0xd7,0x85,0xd7,0x79,0xd7,0x7d,0xd7,0x85,0xd6,0x85,0xd6,0xae,0x17,0xf4,0xec, +0x9c,0x31,0x10,0x7d,0x89,0x57,0x40,0x00,0xd4,0x16,0x4d,0xae,0xa1,0xaa,0x33,0xa5, +0x6c,0x29,0x4c,0xac,0x6a,0xb0,0x83,0xb1,0x6b,0xad,0x8c,0x2d,0x6b,0x2d,0x7b,0xad, +0x73,0xad,0x7c,0x2d,0x83,0x2d,0x7b,0xad,0x9c,0x31,0x10,0xc5,0x75,0x23,0x00,0x00, +0x86,0x69,0x73,0xa3,0x69,0x15,0x80,0x1c,0x6e,0xa3,0x96,0xd0,0x71,0x5b,0x7c,0x86, +0x6d,0x45,0x76,0xca,0x72,0x98,0x65,0x09,0x6d,0x6e,0x80,0x5d,0x8b,0x21,0xc5,0xd8, +0x9c,0x31,0x10,0xc3,0xdc,0x99,0x60,0x00,0x81,0xed,0x81,0xed,0x89,0xc9,0x95,0xa9, +0x7a,0xad,0x69,0xed,0x45,0x4e,0x87,0x29,0x6a,0x4c,0x99,0x10,0xa2,0x0d,0x91,0xc9, +0x7e,0xa9,0x2c,0xc1,0x95,0xe6,0x57,0xca,0x9c,0x31,0x10,0x21,0xdc,0x88,0x40,0x00, +0xa9,0x2c,0xa5,0xf0,0x95,0x4c,0x8a,0xad,0x19,0x0a,0x92,0xc6,0x52,0xcc,0xad,0x2c, +0xa5,0xd1,0x9d,0xcd,0x82,0xd1,0x18,0xc9,0x8a,0xa6,0x52,0xcc,0xb5,0x4c,0xa9,0xad, +0x9c,0x31,0x10,0xb6,0xdc,0x99,0x40,0x00,0x9d,0xcd,0x7a,0xad,0x18,0xc1,0x85,0xe6, +0x57,0xa9,0xb9,0xac,0xa9,0xad,0x9d,0x6d,0x7a,0x6d,0x0d,0x45,0x8a,0xaa,0x52,0xcd, +0xc1,0x6d,0xad,0xad,0xa1,0x89,0x6e,0x89,0x9c,0x31,0x10,0x11,0xdc,0xa8,0x40,0x00, +0x15,0x24,0x86,0x2a,0x5b,0x2e,0xc9,0xac,0xad,0xad,0xa1,0x2d,0x66,0x69,0x15,0x44, +0x89,0x69,0x5b,0xaa,0xcd,0xad,0xaa,0x0e,0xa0,0xed,0x5a,0x28,0x19,0xe6,0x88,0xa8, +0x9c,0x31,0x10,0x3b,0xdd,0x98,0x20,0x00,0x62,0xca,0xcd,0xed,0xaa,0x2d,0x9d,0x89, +0x4d,0xe5,0x22,0x02,0x84,0xe8,0x6a,0xa6,0xcd,0xec,0xaa,0x4d,0x99,0x8d,0x45,0xa5, +0x2a,0x2a,0x80,0xcc,0x6e,0xa6,0xd1,0xe9,0x9c,0x31,0x10,0xac,0xdd,0x89,0x20,0x00, +0xaa,0x4d,0x99,0xad,0x3d,0xa1,0x2e,0x29,0x7c,0xa9,0x72,0xa1,0xd1,0xe5,0xaa,0x69, +0x99,0xb1,0x39,0x85,0x32,0x4d,0x80,0xb0,0x6e,0x86,0xd1,0xc9,0xa6,0x49,0x9d,0xcd, +0x9c,0x31,0x10,0xa7,0xdd,0xa8,0x30,0x00,0x3d,0xa9,0x2a,0x2a,0x88,0xac,0x6a,0x8a, +0xd5,0xcc,0xa2,0x69,0x9d,0xad,0x49,0xca,0x1d,0xc0,0x90,0xed,0x5e,0xc5,0xd5,0xe9, +0xa2,0x4d,0x9d,0xad,0x5d,0xed,0x0d,0x80,0x9c,0x31,0x10,0x9c,0xdd,0xa9,0x20,0x00, +0x99,0xe6,0x52,0xec,0xcd,0xea,0xa6,0x2d,0x9d,0xad,0x76,0x31,0x01,0x96,0x96,0xe8, +0x52,0x12,0xc1,0xd0,0xa9,0xad,0xa1,0xb1,0x8a,0x2d,0x11,0x90,0x6b,0x1a,0x6c,0xd1, +0x9c,0x31,0x10,0xbf,0xdd,0xb8,0x30,0x00,0x92,0x11,0xc1,0x6d,0x9a,0x2d,0x95,0xed, +0x41,0xea,0x2d,0xe4,0x9c,0xee,0x5a,0xa8,0xd5,0xc9,0x96,0x6d,0xa1,0xad,0x6e,0x2d, +0x09,0x92,0x9a,0xcc,0x52,0x2e,0xba,0x11,0x9c,0x31,0x10,0x21,0xdd,0xa7,0x30,0x00, +0xa6,0xd6,0xa0,0xe8,0x8a,0xf8,0x2e,0xd4,0x4b,0x26,0x8e,0x4b,0x6f,0x14,0xce,0xc6, +0x93,0x36,0x9c,0xe6,0x69,0x28,0x0e,0xca,0x9f,0x56,0x57,0x16,0xbb,0x1c,0xa4,0xd7, +0x9c,0x31,0x10,0x8d,0xdd,0xb7,0x20,0x00,0x9c,0xf7,0x8c,0xe8,0x38,0xd5,0x3c,0xf4, +0x9a,0x66,0x63,0x26,0xd2,0xe5,0x8f,0x37,0xa2,0xe7,0x75,0x27,0x16,0xda,0x83,0x7c, +0x6c,0xb8,0x9b,0x09,0xb6,0xaa,0x96,0xf7,0x9c,0x31,0x10,0x10,0xdc,0xb7,0x20,0x00, +0x96,0xa7,0x5b,0x28,0x18,0xa6,0xa3,0x64,0x59,0x65,0xbd,0x58,0x9e,0xf6,0x9d,0x07, +0x8c,0xd8,0x44,0xd6,0x30,0xa4,0xa4,0x73,0x5b,0x45,0xc7,0x25,0x91,0x25,0x9f,0x17, +0x9c,0x31,0x10,0x10,0xdc,0xb7,0x20,0x00,0x84,0xf6,0x3e,0xd5,0x3c,0xe3,0xa0,0x45, +0x5f,0x27,0xc6,0xd4,0x91,0x14,0x9d,0x07,0x85,0x06,0x42,0xe4,0x38,0xd3,0xa6,0x54, +0x5b,0x07,0xc4,0xf5,0x93,0x04,0x99,0x07,0x9c,0x31,0x10,0x10,0xdc,0xb7,0x20,0x00, +0x8a,0xe6,0x4a,0xe5,0x2e,0xc4,0xa6,0xc2,0x5b,0x24,0xb9,0x36,0x9b,0x15,0x93,0x35, +0x92,0xe7,0x61,0x38,0x20,0xd8,0x95,0xa8,0x6f,0x16,0x95,0x67,0xb0,0xe9,0x88,0xf9, +0x9c,0x31,0x10,0x08,0xdc,0xa7,0x20,0x00,0x9a,0xea,0x79,0x08,0x30,0xc8,0x5d,0x19, +0x9a,0x4e,0x64,0xdb,0xbe,0x97,0x8c,0xe6,0x92,0xf5,0x90,0xd5,0x5d,0x17,0x2a,0xd9, +0x95,0x76,0x73,0x13,0x8d,0x55,0xae,0xe7,0x9c,0x31,0x10,0xe4,0xdb,0xb7,0x20,0x00, +0x81,0xdd,0x99,0xe1,0x81,0xdd,0x4d,0xd9,0x38,0xd0,0xa5,0x09,0x61,0x95,0x9e,0x59, +0xa2,0x19,0x86,0x19,0x9d,0xdd,0x7a,0x19,0x45,0xd6,0x45,0x50,0x9c,0x55,0x65,0x1d, +0x9c,0x31,0x10,0xcd,0xda,0xb7,0x30,0x00,0xa1,0x5d,0x9d,0x59,0x85,0x59,0x9d,0x5d, +0x79,0x59,0x49,0x56,0x3c,0x50,0x9c,0x09,0x68,0xd5,0x9a,0x59,0xa1,0x55,0x85,0xd5, +0x9d,0x99,0x7d,0x59,0x5a,0x18,0x34,0x59,0x9c,0x31,0x10,0xc1,0xcb,0xb7,0x20,0x00, +0xa6,0x51,0x72,0x0d,0x8a,0xd1,0xd6,0x19,0x92,0x59,0xae,0x55,0x9e,0x19,0x52,0x9d, +0x01,0xdc,0x43,0x69,0xb5,0x71,0x5a,0x29,0xc5,0xa1,0xb1,0xa1,0x91,0xa5,0xb9,0xa1, +0x9c,0x31,0x10,0x5a,0xda,0xa6,0x30,0x00,0x78,0xe6,0x5e,0x20,0x34,0x26,0x8b,0x11, +0x85,0xc1,0x7b,0x89,0xaa,0x15,0x8e,0x95,0x8e,0x91,0x92,0x55,0x6e,0x55,0x51,0x96, +0x3c,0xc4,0x98,0x05,0x78,0x55,0x85,0xa1,0x9c,0x31,0x10,0x7f,0xca,0xa6,0x30,0x00, +0xc9,0x20,0x9a,0xa1,0xa6,0x99,0x96,0x55,0x62,0x95,0x19,0xd6,0x0e,0x11,0xc0,0x21, +0x70,0x6d,0x91,0x2d,0xc4,0xe4,0x9a,0x66,0xa5,0xe4,0x95,0xe2,0x61,0xdc,0x25,0x9e, +0x9c,0x31,0x10,0xdf,0xdb,0xb6,0x30,0x00,0x41,0x94,0x9c,0xd9,0x7c,0xe1,0x7d,0x65, +0xa1,0x61,0x89,0x59,0x91,0x59,0x8d,0x58,0x75,0x99,0x61,0xdc,0x38,0xde,0x86,0x15, +0x95,0xcd,0x72,0x4d,0x9a,0x15,0x95,0xd9,0x9c,0x31,0x10,0xfa,0xcb,0xb6,0x30,0x00, +0x96,0x5d,0xa6,0x1d,0x82,0x1d,0x5e,0x1d,0x16,0x1c,0x2a,0xe2,0xc1,0xed,0x7d,0xb2, +0x7d,0xa9,0xbd,0xa5,0x99,0xa1,0x9d,0xe1,0x99,0x9d,0x75,0xdd,0x4e,0x1d,0x05,0x62, +0x9c,0x31,0x10,0x5e,0xcb,0xb7,0x40,0x00,0x62,0xe1,0xc2,0x99,0x6e,0xd1,0x8e,0x95, +0xbe,0x19,0x96,0x19,0x9e,0x19,0x95,0xd9,0x6d,0xd9,0x46,0x1d,0x05,0x1e,0x79,0xd5, +0xb5,0xcd,0x72,0x0d,0x96,0x11,0xb5,0xd5,0x9c,0x31,0x10,0x67,0xca,0xb6,0x30,0x00, +0x99,0xd9,0x9d,0xd9,0x8d,0xd9,0x6d,0x99,0x3e,0x1c,0x08,0x59,0x84,0xd2,0xb1,0x0d, +0x71,0x51,0x8d,0x99,0xb9,0x99,0x9d,0x59,0x95,0xd9,0x8d,0x99,0x6d,0x9d,0x41,0xdc, +0x9c,0x31,0x10,0x67,0xca,0xb6,0x30,0x00,0x08,0x5a,0x75,0x51,0xb5,0x4d,0x7d,0xd1, +0x89,0x95,0xb1,0x99,0xa1,0x9d,0x8d,0x9d,0x8d,0x9c,0x75,0xa1,0x45,0xe1,0x10,0xe2, +0x66,0x19,0xb6,0x12,0x8a,0x11,0x7d,0xd5,0x9c,0x31,0x10,0x47,0xca,0xa5,0x20,0x00, +0xac,0xf5,0xae,0xe6,0x92,0xe6,0x88,0xe5,0x7a,0xd7,0x55,0x08,0x18,0xb9,0x4b,0x7a, +0xb7,0x57,0x9b,0x53,0x79,0x33,0x9b,0x14,0xb7,0x05,0x9d,0x06,0x82,0xe6,0x7e,0xe7, +0x9c,0x31,0x10,0x71,0xc9,0xa6,0x20,0x00,0x60,0xe1,0x20,0xe0,0x2f,0xae,0xa7,0x71, +0xb1,0x69,0x7f,0x1d,0x8d,0x19,0xb5,0x19,0xa9,0x1d,0x89,0x1d,0x80,0xd9,0x70,0xd5, +0x36,0xda,0x16,0x94,0x84,0x61,0xbc,0x6d,0x9c,0x31,0x10,0xfd,0xc9,0xa5,0x20,0x00, +0x8c,0x99,0x7a,0xd6,0xa6,0xf3,0xb3,0x11,0x8f,0x12,0x7d,0x33,0x79,0x10,0x53,0x2d, +0x18,0x6c,0x54,0xc7,0xb4,0xa4,0xa4,0xc9,0x7c,0xce,0x90,0xb0,0xb0,0xb1,0x9e,0xb0, +0x9c,0x31,0x10,0x71,0xc9,0xa6,0x20,0x00,0x7e,0x9d,0x7c,0xdd,0x6a,0xe1,0x32,0xe0, +0x29,0x66,0x8d,0x2d,0xb5,0x25,0x8f,0x19,0x81,0x15,0xa3,0x15,0xad,0x19,0x8c,0xdd, +0x7c,0xdd,0x78,0xdd,0x5a,0xdd,0x26,0x5e,0x9c,0x31,0x10,0x08,0xc7,0xa5,0x20,0x00, +0x4a,0x4a,0xa2,0x06,0xaa,0x2a,0x87,0x10,0x88,0x12,0xa8,0x11,0xa4,0x11,0x83,0x52, +0x79,0x71,0x70,0x6e,0x4f,0xae,0x2c,0x6d,0x6c,0x12,0xaa,0x37,0xa0,0x74,0x86,0x8f, +0x9c,0x31,0x10,0x89,0xc8,0x95,0x10,0x00,0x91,0x95,0xa8,0x96,0x98,0x76,0x7c,0x74, +0x78,0x55,0x6d,0x79,0x42,0x59,0x3a,0xdb,0x84,0xa7,0xaa,0xa1,0x97,0x81,0x87,0x65, +0x9a,0x67,0xa5,0x58,0x89,0x69,0x79,0x7b,0x9c,0x31,0x10,0x3d,0xc8,0x95,0x00,0x00, +0x77,0x79,0x65,0x85,0x3c,0x24,0x4c,0x62,0x90,0x42,0xa6,0x58,0x92,0x5c,0x8b,0x6b, +0x9f,0x78,0x9d,0x77,0x81,0x87,0x76,0x75,0x73,0x65,0x5e,0x97,0x3c,0x47,0x5d,0x58, +0x9c,0x31,0x10,0x21,0xb7,0x94,0x00,0x00,0xb0,0xb5,0xc4,0xed,0xa5,0x19,0xa0,0xcd, +0xc1,0x15,0xaa,0x99,0x76,0xdd,0x68,0xa1,0x60,0xe5,0x33,0x61,0x07,0xa2,0x5d,0x68, +0xb7,0x19,0xba,0xc9,0xa4,0xd5,0xac,0xa6,0x9c,0x31,0x10,0x21,0xb7,0x94,0x00,0x00, +0xc0,0xe0,0x98,0x9e,0x6e,0xe1,0x68,0xdd,0x5c,0xd9,0x2a,0xdc,0x19,0x66,0x71,0x14, +0xb6,0xcd,0xb8,0xdd,0xa8,0xa9,0xb9,0x21,0xb4,0xd9,0x80,0xd9,0x5e,0xdd,0x5c,0x9d, +0x9c,0x31,0x10,0x39,0xb7,0x84,0x00,0x00,0x50,0xdd,0x28,0x5e,0x42,0x8c,0x96,0x9e, +0xbc,0xf9,0xb0,0xe5,0xa8,0xcd,0xb2,0xd5,0x94,0xe9,0x66,0xdd,0x52,0xd5,0x4e,0xdd, +0x36,0xa2,0x3e,0xd0,0x88,0xce,0xba,0xe5,0x9c,0x31,0x10,0x4d,0xa5,0x86,0x20,0x00, +0xec,0xdb,0xcc,0xb3,0xd4,0xab,0xb0,0xbb,0x5b,0x43,0x32,0xbc,0x30,0xbb,0x13,0x33, +0x05,0x3b,0x74,0xd4,0xea,0xa0,0xf8,0xbd,0xd2,0xc3,0xbe,0xc3,0x9c,0xb4,0x4c,0xbb, +0x9c,0x31,0x10,0xa4,0xa4,0x73,0x00,0x00,0x18,0x9c,0x16,0x9a,0x1a,0x24,0x4d,0x1c, +0xb2,0xcd,0xf3,0x65,0xea,0xe5,0xc2,0x99,0xa3,0x1d,0x74,0xe1,0x3e,0xdd,0x21,0x1d, +0x12,0xe1,0x31,0x9d,0x88,0xd9,0xd4,0xd8,0x9c,0x31,0x10,0xca,0xb3,0x52,0x00,0x00, +0xb6,0x36,0xac,0x54,0x99,0xa6,0x7d,0x69,0x62,0x34,0x56,0x89,0x52,0x6d,0x59,0x71, +0x7b,0x81,0xa4,0x49,0xb9,0x99,0xb4,0x4d,0x9d,0xad,0x73,0x51,0x41,0x69,0x29,0x96, +0x9c,0x31,0x10,0x99,0xb4,0x63,0x00,0x00,0x3e,0xdc,0x7d,0x26,0xb4,0xe0,0xcf,0x12, +0xc4,0xe5,0x9f,0x65,0x71,0x15,0x4d,0x15,0x44,0xe9,0x54,0xe1,0x74,0xcd,0x92,0xa2, +0xa4,0xe8,0xaa,0xd1,0xa1,0x21,0x86,0xe1,0x9c,0x31,0x10,0xf7,0xa3,0x42,0x00,0x00, +0x48,0x65,0x17,0x91,0x0f,0x69,0x40,0x8e,0x93,0x51,0xe0,0x92,0xfd,0x64,0xde,0xb6, +0x94,0x34,0x3e,0x8d,0x10,0x68,0x1d,0x4d,0x5b,0x91,0xa0,0x2d,0xcd,0x92,0xd5,0x48, +0x9c,0x31,0x10,0x6a,0xa2,0x42,0x00,0x00,0xb5,0xae,0x81,0x70,0x50,0x8e,0x3e,0x4d, +0x49,0x48,0x6b,0xae,0x8f,0x55,0xa7,0x8a,0xaa,0x71,0x9b,0xad,0x85,0x69,0x6e,0x71, +0x5f,0x69,0x5f,0x89,0x6f,0x31,0x83,0x2c,0x9c,0x31,0x10,0x20,0x82,0x42,0x00,0x00, +0xcc,0xd6,0xde,0xa4,0xc8,0x9a,0x8e,0x94,0x52,0xa6,0x3b,0x14,0x50,0xa2,0x74,0xdc, +0x96,0xda,0xa4,0xec,0x9d,0x09,0x86,0xa9,0x72,0x91,0x6e,0x59,0x74,0xad,0x7e,0xa1, +0x9c,0x31,0x10,0x81,0x42,0x42,0x00,0x00,0xe9,0x0a,0xf9,0xdd,0xd5,0x49,0xdd,0xa5, +0xb1,0x39,0xa1,0xc3,0xbd,0xbb,0xb1,0x34,0x99,0xc2,0x86,0xbc,0x61,0xc3,0x5d,0x2b, +0xa1,0x34,0xdd,0xca,0xdd,0x3c,0xcd,0xb9,0x9c,0x31,0x10,0xc0,0x53,0x34,0x10,0x00, +0x6d,0xb7,0x5e,0x47,0x61,0xc6,0xa9,0xb8,0xa5,0x37,0x95,0xc8,0x91,0xa7,0x96,0x36, +0x7d,0xb7,0x75,0xb7,0x95,0xa7,0x85,0xc9,0x59,0xb7,0x46,0x37,0x3e,0x32,0x43,0x62, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_WARNING.txt b/config/_default_cfg_src_/res/cn/SOUND_WARNING.txt new file mode 100644 index 0000000..0164f01 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_WARNING.txt @@ -0,0 +1,155 @@ +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x76,0x43,0x20,0x21,0x00,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0xd6,0xa4,0x9c,0x31,0x10,0xea,0xcb,0x79,0x87,0x67, +0x7d,0xd5,0x85,0xd5,0x7d,0xa5,0xbe,0xa4,0x84,0x88,0x3a,0xe5,0xdd,0x15,0x0e,0x15, +0xee,0x55,0x20,0xd5,0xbf,0x15,0x68,0x55,0x6b,0x55,0xb4,0x95,0x26,0xd5,0xe5,0x55, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb, +0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2,0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24, +0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2,0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3, +0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c,0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44, +0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00,0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60, +0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71,0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa, +0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75,0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00, +0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30,0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75, +0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca,0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75, +0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00,0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30, +0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5,0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea, +0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15,0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00, +0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb,0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b, +0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35,0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb, +0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00,0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04, +0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52,0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e, +0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90,0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55, +0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21,0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9, +0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5,0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70, +0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65,0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00, +0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41,0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55, +0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba,0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50, +0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69,0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21, +0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65,0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00, +0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba,0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85, +0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50,0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75, +0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00,0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6, +0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb,0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb, +0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10,0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71, +0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51,0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95, +0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00,0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01, +0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78,0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d, +0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76,0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55, +0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a,0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba, +0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75,0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda, +0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85,0x9c,0x31,0x10,0x9c,0xc5,0x54,0x30,0x00, +0xcb,0x6d,0x92,0x2e,0x30,0x89,0x77,0xd6,0xcb,0x69,0x7b,0x28,0x34,0x51,0x8e,0x92, +0xc8,0x89,0x65,0x09,0x3a,0x72,0xa1,0x84,0xba,0xa6,0x56,0x6e,0x4a,0x4e,0xb0,0x89, +0x9c,0x31,0x10,0xd0,0xcb,0x78,0x77,0x56,0xac,0xeb,0x48,0xeb,0x56,0xcb,0xd5,0x03, +0x86,0x65,0x3b,0x6c,0xe0,0x8b,0x0d,0x0b,0xef,0x2b,0x20,0x6b,0xbf,0x8b,0x68,0x2b, +0x6b,0xab,0xb8,0x4b,0x27,0x6b,0xe8,0xab,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb,0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2, +0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24,0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2, +0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3,0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c, +0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44,0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00, +0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60,0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71, +0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa,0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75, +0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00,0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30, +0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75,0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca, +0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75,0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00, +0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30,0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5, +0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea,0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15, +0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00,0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb, +0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b,0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35, +0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb,0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00, +0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04,0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52, +0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e,0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90, +0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55,0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21, +0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9,0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5, +0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70,0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65, +0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00,0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41, +0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55,0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba, +0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50,0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69, +0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21,0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65, +0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00,0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba, +0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85,0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50, +0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75,0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00, +0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6,0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb, +0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb,0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10, +0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71,0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51, +0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95,0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00, +0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01,0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78, +0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d,0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76, +0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55,0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a, +0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba,0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75, +0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda,0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/cn/SOUND_ZERO.txt b/config/_default_cfg_src_/res/cn/SOUND_ZERO.txt new file mode 100644 index 0000000..2897805 --- /dev/null +++ b/config/_default_cfg_src_/res/cn/SOUND_ZERO.txt @@ -0,0 +1,100 @@ +0x9c,0x31,0x10,0x91,0x63,0x33,0x00,0x00,0x7e,0xdb,0x7e,0xdb,0x7c,0xdb,0x7f,0x1b, +0x64,0x1c,0x83,0x5c,0xae,0x6a,0xb6,0x12,0x8f,0x5c,0x4c,0xcb,0x4c,0x95,0x70,0x98, +0xc2,0x4b,0x9e,0x5b,0x7c,0x94,0x30,0xdc,0x9c,0x31,0x10,0x30,0xc6,0x89,0x40,0x00, +0x7a,0xdb,0x7c,0xdb,0x7e,0xdb,0x82,0xdb,0x84,0xdb,0x85,0x1b,0x7a,0x9b,0x70,0xdb, +0x68,0x9b,0x71,0x1b,0x92,0x13,0xc3,0x24,0xb7,0x6b,0x6c,0xc3,0x0d,0x6c,0x08,0xd9, +0x9c,0x31,0x10,0x1c,0xd7,0x9a,0x40,0x00,0x76,0x99,0xaa,0xd6,0xb8,0xa6,0xac,0xba, +0x9e,0xb4,0x74,0xb8,0x32,0x29,0x1a,0xa7,0x5e,0xe3,0xb4,0x8a,0xce,0xd8,0xae,0xa5, +0x94,0xb7,0x88,0xc8,0x5b,0x27,0x1c,0x26,0x9c,0x31,0x10,0xc0,0xd8,0x9a,0x50,0x00, +0x25,0xcc,0x85,0xb4,0xd5,0x96,0xc5,0xd7,0x8d,0xa8,0x85,0xc6,0x8d,0x27,0x62,0x47, +0x18,0x94,0x25,0xdd,0x91,0xb6,0xd9,0x96,0xbd,0xd5,0x85,0x18,0x8d,0xd6,0xa1,0x08, +0x9c,0x31,0x10,0x9f,0xe8,0xba,0x50,0x00,0x71,0x23,0x42,0x12,0x4a,0xe6,0x88,0x99, +0xb0,0xd3,0x9e,0xe2,0x80,0x93,0x8c,0xe4,0x96,0x93,0x73,0x1b,0x3e,0x5b,0x43,0x13, +0x86,0xa9,0xb4,0xcc,0xa1,0x24,0x7e,0x92,0x9c,0x31,0x10,0x10,0xe8,0xbb,0x50,0x00, +0x8b,0x1b,0x9e,0xe2,0x7b,0x13,0x40,0xe3,0x39,0x53,0x7a,0xd5,0xb3,0x22,0xa4,0xcb, +0x80,0xeb,0x85,0x13,0xa2,0xe3,0x8a,0x5a,0x4d,0x5b,0x30,0x5b,0x66,0xe2,0xa6,0x95, +0x9c,0x31,0x10,0x10,0xe8,0xbb,0x50,0x00,0xa8,0xeb,0x84,0xd3,0x80,0xa3,0xa1,0x13, +0x9a,0xe3,0x65,0x12,0x38,0x24,0x4b,0x89,0x8e,0xec,0xaa,0xd3,0x93,0x1b,0x7e,0x9b, +0x95,0x13,0xa6,0xa3,0x7c,0x93,0x4b,0xa3,0x9c,0x31,0x10,0x10,0xe8,0xbb,0x50,0x00, +0x3a,0x53,0x6c,0xaa,0xa0,0x8d,0x9c,0xea,0x87,0x0b,0x8c,0xe3,0xa3,0x1b,0x92,0xdc, +0x61,0x22,0x40,0x1c,0x4f,0x99,0x89,0x1e,0xa0,0xe1,0x90,0xd4,0x88,0xe3,0x9a,0xd3, +0x9c,0x31,0x10,0x56,0xd9,0xbb,0x40,0x00,0xc1,0xcb,0x75,0x2a,0x22,0xcc,0x08,0xa1, +0x51,0xde,0xad,0xa1,0xb1,0xcc,0x99,0xbb,0xa5,0xb3,0xbe,0x43,0x9d,0xab,0x4d,0xcb, +0x15,0xaa,0x1e,0x55,0x79,0x92,0xb1,0xe3,0x9c,0x31,0x10,0xd9,0xd9,0xba,0x40,0x00, +0xa5,0xa3,0x9d,0xc3,0xb1,0xbb,0xb5,0xb3,0x7d,0x4b,0x3a,0x2b,0x14,0xc5,0x3a,0x18, +0x95,0xe4,0xad,0x94,0xa1,0xd2,0xa5,0xb4,0xb5,0xba,0xa1,0xc3,0x65,0x33,0x32,0x44, +0x9c,0x31,0x10,0xe0,0xd8,0xbb,0x30,0x00,0x1c,0x2a,0x51,0xe4,0x99,0x12,0xa5,0xd3, +0xa1,0xb3,0xad,0xbb,0xb1,0xc3,0x95,0xb2,0x5d,0xbc,0x2e,0x3a,0x22,0x4c,0x69,0xa9, +0xa1,0xbd,0xa5,0xc2,0xa5,0xbb,0xb1,0xbb,0x9c,0x31,0x10,0xc1,0xd9,0xaa,0x40,0x00, +0xaa,0x4b,0x85,0xa3,0x51,0xcb,0x29,0x3b,0x2e,0x32,0x79,0x96,0xa5,0xe8,0xa1,0xa6, +0xa9,0xb9,0xa9,0xcc,0xa2,0x2b,0x7d,0xbb,0x4e,0x43,0x24,0xb4,0x3a,0x11,0x89,0xf3, +0x9c,0x31,0x10,0xc2,0xd9,0x9a,0x30,0x00,0xa5,0x89,0xa1,0xc4,0xa9,0xaa,0xa5,0x35, +0x99,0x98,0x75,0x57,0x4a,0x37,0x28,0x86,0x49,0xeb,0x8d,0x51,0xa1,0x9b,0xa5,0xa5, +0xa9,0xc7,0xa5,0x28,0x95,0xc6,0x6d,0x47,0x9c,0x31,0x10,0x5c,0xd8,0xaa,0x40,0x00, +0x46,0xb4,0x28,0x31,0x5a,0x6c,0x90,0xab,0x9d,0xba,0xa5,0xb4,0xa9,0xc2,0xa1,0x3b, +0x91,0xc3,0x69,0x3a,0x3e,0xbc,0x2e,0x5c,0x66,0x39,0x95,0x2c,0xa1,0xb2,0xa9,0x43, +0x9c,0x31,0x10,0xd3,0xd8,0x99,0x30,0x00,0xa9,0x24,0xa1,0x22,0x8a,0xdb,0x60,0xdc, +0x3c,0xe1,0x37,0x5c,0x71,0x05,0x96,0xd0,0xa5,0x1d,0xaa,0xa2,0xa6,0xe2,0x9b,0x1d, +0x80,0xd2,0x5b,0x1a,0x3a,0x5d,0x41,0x00,0x9c,0x31,0x10,0x7f,0xd8,0x89,0x20,0x00, +0x78,0xd4,0x9a,0x9c,0xa6,0xe9,0xa8,0xa4,0xa4,0x9b,0x97,0x12,0x7a,0xdc,0x57,0x13, +0x38,0x0a,0x46,0xcd,0x7c,0xa1,0x9a,0xac,0xa8,0xe4,0xa8,0xe2,0xa2,0x94,0x92,0xdc, +0x9c,0x31,0x10,0x31,0xd8,0x88,0x10,0x00,0x74,0x99,0x51,0x14,0x34,0x52,0x4e,0xf2, +0x82,0x6d,0x9e,0xe9,0xaa,0xa3,0xa9,0x1c,0xa0,0xda,0x8e,0xda,0x6c,0x9c,0x49,0x1a, +0x37,0x2c,0x5d,0x23,0x8a,0xda,0xa5,0x1c,0x9c,0x31,0x10,0x04,0xd8,0x76,0x00,0x00, +0xac,0xd1,0xa9,0x0c,0x9d,0x0d,0x85,0x2a,0x63,0x0c,0x42,0xd2,0x3d,0x24,0x6b,0x01, +0x92,0xe5,0xab,0x0d,0xac,0xe9,0xa6,0xe9,0x96,0xe9,0x7c,0xcd,0x5b,0x2d,0x3e,0x65, +0x9c,0x31,0x10,0x6c,0xd7,0x76,0x00,0x00,0x45,0x0c,0x74,0x5a,0x98,0xe3,0xac,0x5b, +0xad,0x13,0xa4,0x9b,0x90,0xe3,0x72,0x5b,0x53,0x53,0x3a,0x63,0x51,0x32,0x80,0x65, +0xa3,0x5a,0xae,0x5b,0xab,0x23,0x9e,0xe4,0x9c,0x31,0x10,0x74,0xd7,0x66,0x00,0x00, +0x89,0x12,0x68,0xdb,0x48,0xeb,0x3d,0x2b,0x5f,0x0c,0x8a,0xc9,0xa9,0x1b,0xae,0xe4, +0xa8,0xcb,0x98,0xd3,0x7c,0x9a,0x5d,0x5b,0x3c,0x02,0x45,0x4d,0x70,0x62,0x9b,0x2a, +0x9c,0x31,0x10,0xd8,0xd7,0x76,0x10,0x00,0xae,0x54,0xaf,0x13,0xa6,0xe3,0x8e,0xdb, +0x6c,0x9b,0x4b,0x22,0x37,0x2d,0x56,0xe3,0x84,0xd1,0xa9,0x1c,0xb2,0xe4,0xae,0xdb, +0x9e,0xdb,0x7e,0x9b,0x59,0x5b,0x38,0x11,0x9c,0x31,0x10,0x74,0xd7,0x66,0x00,0x00, +0x43,0x5e,0x72,0xa4,0x9d,0x60,0xb2,0x4c,0xb2,0xdd,0xa6,0xea,0x8a,0xdb,0x64,0xd4, +0x40,0xac,0x37,0x50,0x60,0x8c,0x90,0xd6,0xb0,0xa9,0xb5,0x12,0xac,0xd5,0x94,0xdb, +0x9c,0x31,0x10,0xfb,0xd7,0x67,0x00,0x00,0x6e,0xa2,0x49,0x1a,0x34,0xec,0x52,0xdb, +0x86,0x91,0xad,0x13,0xb4,0xec,0xb0,0xdb,0x9c,0x92,0x78,0xdb,0x4f,0x5c,0x32,0x5b, +0x4b,0x29,0x7c,0xa4,0xa7,0x4c,0xb4,0x9a,0x9c,0x31,0x10,0x74,0xd7,0x66,0x00,0x00, +0xb2,0xe9,0xa0,0x9c,0x7c,0xd4,0x53,0x53,0x32,0x51,0x45,0x22,0x78,0xa6,0xa5,0x13, +0xb6,0x91,0xb5,0x23,0xa4,0xa4,0x7c,0xd4,0x53,0x0b,0x32,0x52,0x45,0x2a,0x78,0xa5, +0x9c,0x31,0x10,0x5d,0xd6,0x66,0x10,0x00,0xa7,0x53,0xb6,0x12,0xb7,0x6b,0xa2,0x64, +0x79,0x13,0x4d,0x4b,0x30,0x2c,0x48,0xe9,0x7e,0x9a,0xab,0x4c,0xb8,0x64,0xb7,0x22, +0x9e,0x5a,0x73,0x13,0x47,0x5b,0x30,0xec,0x9c,0x31,0x10,0xf9,0xd6,0x55,0x10,0x00, +0x52,0x76,0x88,0x50,0xaf,0x84,0xb9,0x69,0xb4,0x96,0x97,0x41,0x68,0x85,0x3e,0x59, +0x35,0xc1,0x5f,0x60,0x93,0x96,0xb3,0x4a,0xba,0xa0,0xb1,0x60,0x8a,0x75,0x58,0x99, +0x9c,0x31,0x10,0xe8,0xd7,0x56,0x10,0x00,0x35,0x22,0x40,0x8b,0x71,0x55,0xa1,0x8b, +0xb9,0x42,0xbb,0x8a,0xa6,0x54,0x75,0x6c,0x46,0x82,0x32,0x73,0x52,0x6d,0x87,0x43, +0xb0,0x8a,0xbc,0x72,0xb5,0x6c,0x92,0x64,0x9c,0x31,0x10,0x7c,0xd7,0x45,0x10,0x00, +0x5e,0x85,0x37,0x34,0x3b,0x92,0x6c,0x65,0x9e,0x99,0xba,0x40,0xbc,0x91,0xa6,0x66, +0x75,0x79,0x45,0x95,0x32,0x88,0x54,0x72,0x8b,0x52,0xb3,0x79,0xbe,0x89,0xb2,0x75, +0x9c,0x31,0x10,0xf9,0xd6,0x55,0x10,0x00,0x89,0x65,0x55,0xb5,0x33,0x15,0x41,0x88, +0x77,0x45,0xa9,0xa6,0xbf,0x41,0xba,0x95,0x99,0x75,0x64,0x75,0x39,0x35,0x36,0xb2, +0x64,0x64,0x9c,0x99,0xbd,0x49,0xbf,0xb2,0x9c,0x31,0x10,0x76,0xd6,0x54,0x10,0x00, +0xa5,0x54,0x72,0x44,0x41,0x99,0x31,0x94,0x56,0x72,0x8f,0x82,0xb9,0x79,0xc2,0x88, +0xad,0x55,0x7d,0x45,0x49,0xc5,0x31,0x79,0x4d,0x86,0x86,0x61,0xb5,0x85,0xc3,0x68, +0x9c,0x31,0x10,0xc2,0xd6,0x54,0x00,0x00,0xb1,0x65,0x83,0x55,0x4f,0xe5,0x32,0x49, +0x48,0x95,0x80,0x54,0xb1,0x91,0xc3,0x45,0xb4,0x65,0x87,0x66,0x51,0xd5,0x33,0x49, +0x47,0x85,0x7e,0x64,0xb0,0xa4,0xc3,0x45,0x9c,0x31,0x10,0x6e,0xd6,0x44,0x10,0x00, +0xb3,0x65,0x85,0x55,0x50,0xd1,0x33,0x49,0x4a,0x85,0x80,0x55,0xb2,0xa1,0xc4,0x45, +0xb0,0x75,0x80,0x55,0x4d,0xc5,0x36,0x68,0x50,0x96,0x85,0x55,0xb4,0xa5,0xc2,0x58, +0x9c,0x31,0x10,0x60,0xd5,0x44,0x00,0x00,0xab,0x6d,0x78,0x09,0x48,0xb1,0x38,0x88, +0x59,0x88,0x8f,0x49,0xb9,0x9a,0xbf,0x91,0xa1,0x48,0x6c,0x6c,0x41,0x2d,0x3d,0xca, +0x67,0x4d,0x9d,0x95,0xbe,0x28,0xb8,0xc5,0x9c,0x31,0x10,0x1d,0xd6,0x35,0x00,0x00, +0x91,0x45,0x5d,0xaa,0x3d,0x35,0x49,0xa8,0x78,0x49,0xaa,0xa1,0xc0,0x41,0xae,0x99, +0x7e,0x59,0x4e,0x95,0x3c,0x64,0x58,0x85,0x8b,0x66,0xb7,0x85,0xbd,0x75,0x9d,0x51, +0x9c,0x31,0x10,0x9c,0xd5,0x34,0x10,0x00,0x69,0xaa,0x43,0x23,0x44,0xb5,0x6e,0x2c, +0xa1,0xab,0xbf,0x21,0xb1,0xa9,0x85,0x34,0x53,0x94,0x3f,0x4c,0x55,0x84,0x87,0x22, +0xb3,0xaa,0xbb,0x4b,0x9c,0x4b,0x6a,0x64,0x9c,0x31,0x10,0x1a,0xc4,0x33,0x00,0x00, +0x0c,0x91,0x10,0xe5,0x5f,0xa5,0xc3,0xe4,0xf9,0x00,0xd8,0xd6,0x80,0xba,0x29,0x45, +0x0b,0x35,0x3c,0x34,0x9b,0x09,0xe7,0xc5,0xe7,0xb5,0xa3,0x45,0x49,0xb5,0x14,0xb4, +0x9c,0x31,0x10,0x87,0xc5,0x33,0x00,0x00,0x28,0xb5,0x7a,0x36,0xd0,0xd5,0xe9,0x14, +0xb6,0xc4,0x63,0xa1,0x25,0x46,0x23,0xa9,0x64,0xc8,0xba,0x21,0xe1,0x25,0xbf,0x39, +0x75,0xb5,0x36,0x35,0x28,0xa5,0x5b,0xc9,0x9c,0x31,0x10,0x8d,0xc4,0x22,0x00,0x00, +0xaa,0x19,0xd4,0x46,0xbc,0x45,0x7d,0x35,0x43,0x38,0x33,0x94,0x5c,0xd6,0xa0,0x06, +0xc8,0x49,0xb6,0xc1,0x81,0x34,0x4e,0x35,0x40,0x36,0x60,0xb5,0x99,0x15,0xb9,0x35, +0x9c,0x31,0x10,0x26,0xb3,0x11,0x00,0x00,0xd6,0x66,0x80,0x29,0x31,0xe8,0x1f,0x15, +0x53,0xd1,0xa8,0x85,0xd5,0x35,0xbd,0x31,0x7d,0x35,0x47,0x45,0x3c,0xb5,0x65,0xc9, +0xa1,0xb1,0xba,0xb5,0xa3,0x46,0x75,0x15,0x9c,0x31,0x10,0x9e,0xa2,0x11,0x00,0x00, +0x2a,0xc5,0x2e,0xa5,0x72,0xe0,0xbb,0x29,0xc9,0xc5,0x9b,0x94,0x5e,0x16,0x43,0xd2, +0x5a,0x20,0x8c,0xb9,0xad,0xb5,0xa5,0xc5,0x81,0x8a,0x64,0xa5,0x61,0xa5,0x74,0xd0, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_ALEXA_START.txt b/config/_default_cfg_src_/res/en/SOUND_ALEXA_START.txt new file mode 100644 index 0000000..9f0d0c3 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_ALEXA_START.txt @@ -0,0 +1,363 @@ +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf8,0x39,0xef,0x7b,0xdd,0x6d, +0x7b,0xde,0xe7,0x3c,0x1b,0x17,0x3d,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xd6,0xc6,0xb9,0xef,0x7b,0xbe,0x0e,0x83,0xdd,0x07,0x7c, +0x1e,0xf7,0xbd,0xee,0xe8,0x3d,0xcf,0x7b,0xdd,0xb0,0x8b,0xdc,0xf8,0x3c,0x1c,0xf8, +0x3d,0xcf,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xc1,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x93,0xde, +0xf7,0xbd,0xef,0x46,0xc1,0xf0,0x7c,0x1d,0x91,0x74,0x61,0x07,0xba,0x5a,0xd8,0x41, +0xd0,0x66,0x41,0xef,0x8c,0x5e,0xf1,0x7b,0x60,0xf8,0x3d,0xef,0x07,0x41,0xee,0x7b, +0xbd,0xef,0x83,0xdc,0xe7,0x5b,0xa1,0x07,0xbe,0x0e,0xf6,0xc5,0xef,0x7b,0xdd,0xd0, +0x7b,0xde,0xf7,0xba,0x5b,0x07,0xbd,0xf0,0x78,0xb5,0xd0,0x7b,0xde,0xf4,0x7b,0xe0, +0xf7,0xc1,0xd9,0x27,0xc1,0xef,0x7b,0xa1,0xee,0x7c,0x1e,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x9b,0xdd,0x07,0xbe,0x0f,0x68,0x41,0xcf, +0x73,0xdd,0x0d,0x7b,0xa1,0x07,0x3a,0x5d,0x07,0x3d,0xee,0x79,0xbe,0x0d,0x73,0x9e, +0xee,0x8b,0xe0,0xe7,0xc1,0xdd,0x08,0x35,0xf0,0x7b,0xda,0x2e,0x7b,0xe0,0xf7,0x8b, +0x9a,0xe7,0xbd,0xee,0xb8,0xc2,0x10,0x73,0x9d,0x8c,0x84,0x1c,0xe7,0x3c,0x9b,0x07, +0x3d,0xcf,0x7a,0x36,0x0e,0x7b,0x9e,0xe9,0x7b,0x9e,0xe8,0x3d,0xdb,0x18,0x39,0xee, +0x83,0xd2,0x0e,0x73,0x9e,0xf6,0x9c,0x31,0x27,0x50,0x10,0x00,0x00,0x00,0x76,0x30, +0xce,0xf0,0xef,0x1b,0xa5,0xe1,0x9e,0x1a,0x6b,0x33,0xc3,0xbb,0xbb,0xf2,0x68,0x78, +0x77,0x75,0xf2,0xee,0xf0,0xee,0xf2,0xa5,0xde,0x1d,0xe1,0xe8,0x63,0xbb,0xbb,0xbb, +0xbe,0x47,0x77,0x77,0x77,0x58,0x0e,0xee,0xee,0xef,0x12,0xa1,0xdd,0xe2,0x1e,0x2a, +0xb3,0xb3,0xbb,0xbb,0x3f,0x68,0x87,0x77,0x75,0xce,0xf0,0xee,0xee,0xfa,0xc9,0xd9, +0xde,0x1d,0xea,0xf3,0x3b,0xc3,0xbc,0x2f,0x57,0x77,0x77,0x77, +0x9c,0x31,0x27,0xc4,0x50,0x00,0x00,0x00,0x82,0xb6,0x77,0x66,0x77,0x0b,0x6c,0xcc, +0xf1,0x0d,0xf4,0x1d,0xe1,0xdd,0xdb,0xa7,0x4b,0x43,0xc3,0xb7,0xc3,0xa7,0x77,0x87, +0x70,0x3e,0x8d,0x0e,0xce,0xe6,0x1a,0x55,0x9d,0xe1,0xc6,0xc4,0xab,0x3b,0xb3,0x40, +0x90,0x57,0x77,0x88,0xfe,0x56,0xea,0xf0,0xcf,0x6e,0x1e,0x25,0x95,0xdc,0x72,0x8b, +0x43,0x3b,0x36,0x57,0xe5,0x96,0x78,0x8f,0x94,0x8a,0xf1,0x0c,0xd5,0xe9,0xab,0x5a, +0x19,0xa8,0xfd,0xd4,0x3b,0x43,0x9c,0x31,0x27,0xef,0x73,0x11,0x01,0x00,0x74,0x6f, +0x33,0xa6,0xbd,0x04,0x21,0xdd,0xc5,0x6e,0x85,0x43,0xcd,0x82,0xe4,0x21,0x7c,0x90, +0xbe,0x15,0x34,0xfb,0x85,0xbb,0x50,0x76,0x29,0xfc,0x28,0xa9,0xf3,0x9c,0x43,0x8a, +0xc0,0x87,0xf6,0xd1,0x2a,0x7e,0xd2,0xd5,0x63,0xbe,0xe4,0xda,0xa9,0xb4,0x8d,0x47, +0xf7,0x66,0x8e,0x6c,0xa6,0x84,0x93,0xb5,0x7e,0x12,0xc7,0x14,0xfb,0xb0,0xb9,0x8e, +0xd6,0xa9,0x09,0x94,0x86,0x9a,0x71,0x27,0x5a,0x4d,0x6d,0x5a, +0x9c,0x31,0x27,0xd2,0xb3,0x21,0x11,0x00,0x81,0xe2,0x64,0x7a,0xa7,0x0c,0xff,0x48, +0xb6,0xb5,0xf5,0x55,0x88,0xed,0x73,0x57,0xb1,0x5c,0xda,0x58,0x29,0x63,0x47,0x2a, +0x15,0xf5,0x1e,0x88,0x5b,0xe4,0x51,0x07,0x1a,0xea,0x1d,0x89,0x8d,0xb4,0xaf,0x44, +0x76,0x2a,0xad,0x21,0x79,0xcb,0xe5,0x14,0x37,0x97,0xd0,0x7e,0x4f,0x63,0x7e,0xac, +0x9b,0x53,0x00,0xff,0x5d,0x73,0xd9,0xea,0xce,0xeb,0x8d,0x35,0x32,0x16,0x47,0x33, +0x46,0x60,0xb4,0x52,0xd2,0x0c,0x9c,0x31,0x27,0x92,0xc6,0x42,0x01,0x00,0x7a,0x9b, +0xc3,0xe6,0x56,0xe2,0x97,0x96,0x48,0xc9,0xdd,0x6f,0xcc,0x9f,0xa3,0x5e,0x20,0x21, +0x5d,0x07,0x42,0x42,0x43,0x72,0x75,0x47,0x83,0x64,0x6a,0x6e,0x2a,0xec,0xa9,0xf8, +0xb2,0x99,0xe9,0xbe,0x05,0x22,0x94,0x23,0xdb,0x28,0xce,0xf6,0xc5,0x8f,0x2f,0x6b, +0x8c,0xa6,0x8c,0xc6,0x70,0x9e,0x8c,0x9e,0xe5,0x17,0xbe,0x9b,0x96,0x24,0x06,0x82, +0x33,0x3b,0x5d,0x4b,0x46,0x7d,0xf5,0x60,0xfb,0x3d,0x96,0x30, +0x9c,0x31,0x27,0xda,0xd6,0x52,0x21,0x00,0x94,0xfb,0xd0,0x62,0x0a,0xf4,0x73,0xe2, +0x24,0x69,0xd1,0x27,0xce,0x27,0x33,0xa0,0xc6,0xae,0x2e,0x97,0x02,0x6d,0x5b,0xdc, +0x90,0x83,0x16,0x96,0xcd,0xe9,0xc6,0x4d,0x5b,0x4b,0xcd,0x6d,0x0b,0x71,0x3a,0x59, +0xe2,0x75,0x21,0x52,0x86,0x22,0xe2,0x5d,0x5e,0x25,0xd1,0xb6,0xe6,0x26,0x42,0xad, +0x64,0xd7,0x49,0xdb,0x6a,0xb4,0x12,0xa9,0x92,0xc4,0xfd,0x4e,0x52,0xad,0x79,0xd3, +0x43,0xc5,0xe4,0x44,0x12,0x7d,0x9c,0x31,0x27,0xa2,0xd6,0x42,0x32,0x00,0xac,0x91, +0x02,0x94,0x67,0x25,0xa6,0x0a,0xc6,0xc9,0xd2,0xf0,0x24,0x30,0x53,0x75,0x91,0x13, +0x5e,0x76,0xad,0x62,0x4a,0xdd,0x6e,0x16,0xad,0xb2,0x8c,0x65,0xc4,0x8b,0x59,0x2b, +0xda,0x57,0x7c,0x5c,0xef,0x8a,0x4c,0xb7,0x22,0x98,0x82,0x58,0x50,0xc3,0xa9,0x23, +0x1d,0xb1,0x95,0xad,0x1a,0xa9,0x0c,0x65,0x4c,0xdc,0xba,0x85,0xb1,0xd1,0x52,0x2a, +0xc8,0xbb,0x4f,0xe4,0x17,0x73,0x66,0x29,0x96,0x2a,0x9e,0x57, +0x9c,0x31,0x27,0x35,0xd6,0x53,0x32,0x00,0x9a,0x2b,0x58,0x9c,0x93,0x5c,0xb1,0x33, +0x46,0x26,0x29,0xee,0x62,0x00,0x13,0x75,0xd9,0x0b,0x61,0xb6,0xc1,0x35,0xd9,0xb3, +0x4d,0x5d,0xd3,0xcc,0x57,0x9e,0xa1,0xa6,0x1e,0x73,0x52,0x5d,0x0b,0x51,0x66,0xb0, +0x2d,0xd4,0x31,0x8a,0xe2,0xf3,0x27,0x05,0xc0,0xd2,0xd4,0x4d,0xed,0x73,0x02,0x84, +0x81,0x80,0xbb,0xf6,0xf8,0xe7,0x16,0x78,0xd0,0x69,0x2d,0x5e,0x5a,0xed,0xc1,0xc5, +0x3e,0x9a,0xab,0x23,0xc5,0xed,0x9c,0x31,0x27,0xe7,0xd7,0x63,0x43,0x00,0x66,0x4f, +0xd2,0xb2,0x69,0x50,0x63,0x25,0x3c,0x4e,0xa6,0x26,0x4b,0x78,0xbc,0x2e,0xac,0x8d, +0xd3,0x96,0xde,0xb5,0x2a,0x1d,0x2c,0x81,0xb9,0xfc,0x25,0xd9,0xe2,0x73,0xed,0x2b, +0x45,0x36,0x66,0x4f,0x18,0xb2,0xd1,0x8e,0x68,0xf1,0x40,0x58,0x9b,0x1c,0xdd,0x62, +0x2a,0x36,0xa6,0xa1,0xdb,0x96,0x7a,0x8e,0x57,0xbe,0xa4,0xc9,0xdb,0x78,0xbc,0xe2, +0x06,0x55,0xec,0xc3,0xd3,0x7a,0x53,0xae,0xa5,0x4a,0x15,0x14, +0x9c,0x31,0x27,0x59,0xd7,0x64,0x44,0x10,0x3c,0x71,0x56,0x0e,0xa2,0xe2,0xba,0xdd, +0xdf,0x16,0xa9,0x49,0xd5,0x62,0x8d,0x48,0x6b,0xf2,0x62,0xd8,0x5d,0xf8,0xa3,0x08, +0xac,0x9b,0x51,0xc0,0x2f,0x55,0xd6,0x6a,0x9a,0xa2,0xb7,0xb2,0xd7,0x32,0x45,0xa0, +0xa1,0xce,0x0e,0x6b,0x6f,0x31,0x94,0x55,0x3a,0x31,0x2f,0x77,0xc5,0xd2,0x26,0xfe, +0x81,0x14,0xa4,0x2c,0xbd,0x62,0xc8,0x52,0x64,0xfa,0xc4,0xcd,0xb3,0xb6,0x71,0x62, +0xdd,0x51,0x85,0x6a,0xf8,0x11,0x9c,0x31,0x27,0x7d,0xd8,0x64,0x45,0x10,0x4c,0x67, +0x57,0x37,0x3a,0x7d,0x2b,0xbd,0xbd,0x75,0xf1,0x6b,0x23,0x27,0x2d,0x99,0x2e,0xa5, +0x89,0xda,0xda,0xed,0x49,0x4b,0xaf,0x2e,0xac,0x3c,0xa7,0x56,0x6a,0xfa,0xa4,0x6e, +0xab,0x6f,0x70,0x7d,0x1d,0x77,0x96,0xe7,0x71,0x19,0x67,0xc8,0x89,0x4d,0x82,0xf3, +0x95,0x38,0xa6,0xe3,0x88,0xed,0x94,0x16,0xd2,0xe7,0x3b,0xd0,0x8c,0x2a,0x8c,0xc5, +0xd9,0x56,0xac,0xb7,0x89,0x69,0x0a,0xe8,0xb1,0x4f,0x20,0x1d, +0x9c,0x31,0x27,0x48,0xd9,0x75,0x65,0x20,0x84,0xd8,0x9f,0x30,0x76,0x78,0xcb,0x49, +0xe0,0xe9,0x32,0x9e,0x58,0xcd,0x54,0x83,0x49,0x28,0x7b,0xab,0x5a,0x39,0xb3,0x38, +0x54,0x7c,0x74,0x21,0xf4,0xdd,0x07,0xa7,0x43,0x19,0xa7,0x2d,0x4a,0xb8,0x2b,0x55, +0x2b,0x22,0xcb,0x45,0x10,0xd5,0x3a,0x6a,0xe7,0x13,0xc0,0xd2,0xc2,0x0d,0xaa,0xfd, +0x85,0x6a,0x15,0x45,0xcb,0xfa,0xb9,0x25,0x13,0x46,0x96,0x4c,0x9b,0x66,0xcc,0x41, +0xb5,0x62,0x11,0xd8,0xb8,0xaa,0x9c,0x31,0x27,0xd9,0xd8,0x75,0x55,0x30,0xc5,0x41, +0x1e,0xe8,0x76,0xed,0x23,0x4c,0xa8,0xac,0xeb,0x6e,0x3b,0x9e,0x9a,0x5e,0x18,0xa5, +0x0c,0xb9,0x31,0xf0,0x4d,0x68,0x79,0x52,0xd1,0x6b,0x35,0x29,0x6a,0xa3,0x16,0xa2, +0x2d,0xd3,0xc8,0xca,0x4d,0x39,0x35,0x24,0xfc,0x38,0xcd,0xc7,0x44,0x0c,0xd2,0xcf, +0xaa,0xf4,0x62,0xa5,0xff,0xad,0xb9,0x2d,0x58,0x7a,0x04,0xac,0xc8,0xa8,0xde,0x19, +0xa9,0x45,0x51,0x4a,0x34,0xe1,0x9a,0xc0,0x17,0x70,0x6b,0x34, +0x9c,0x31,0x27,0x51,0xd9,0x75,0x66,0x30,0xc4,0xe5,0x5a,0xdc,0xd7,0x6d,0xbb,0xc9, +0xb9,0xad,0xb5,0xa5,0x64,0x7b,0x19,0xa4,0xcf,0x1c,0xe9,0xb5,0x4a,0x04,0xcd,0x8d, +0x74,0xe3,0x29,0x45,0x1c,0xb1,0xd7,0x90,0xc3,0x18,0xcd,0x10,0xda,0xcc,0x81,0x4c, +0xed,0xc0,0xa3,0x02,0x72,0xd4,0x73,0xc2,0x25,0xd5,0x89,0x13,0x6c,0x0e,0x1b,0x95, +0xf1,0x26,0xac,0x49,0xab,0x65,0xb1,0x4d,0x12,0x34,0x8b,0xda,0x4d,0x88,0x83,0xe9, +0xc4,0xac,0x4e,0x0c,0xec,0x62,0x9c,0x31,0x27,0x0d,0xea,0x95,0x65,0x20,0x9a,0xb8, +0xb8,0x18,0xc3,0x14,0xef,0x8e,0x25,0x29,0xfa,0xf1,0x44,0xb6,0x5c,0xd1,0x52,0xf5, +0x6c,0x57,0x96,0x76,0x35,0x18,0xa8,0xbb,0x1c,0x62,0x0d,0x1b,0x45,0x98,0x43,0xe2, +0xe2,0xce,0xab,0xc8,0x45,0xb4,0x98,0x54,0x2f,0x9c,0x8d,0x30,0x95,0x5b,0x18,0xbe, +0x6d,0x1f,0x29,0xf4,0xe8,0xb2,0x02,0x72,0xed,0x69,0xab,0xce,0xe7,0xd0,0xb3,0xc7, +0x2a,0x31,0x4e,0xa6,0xad,0x33,0xda,0xb2,0x8e,0x9a,0x75,0x3d, +0x9c,0x31,0x27,0x98,0xd8,0x76,0x55,0x20,0xd0,0x6e,0x0e,0xca,0x2b,0x55,0x54,0x39, +0x6f,0x4d,0x57,0xe0,0x7c,0x50,0xdb,0x6d,0x39,0x38,0xdb,0x3b,0xd9,0xaa,0xc7,0xb6, +0x51,0xac,0xf5,0x6c,0xd0,0x88,0x18,0xab,0xbe,0x14,0xae,0xb0,0x14,0x5b,0xc2,0xdf, +0x1d,0xae,0xf7,0x85,0x75,0xa7,0x49,0xb6,0x64,0xb9,0x46,0x8b,0xda,0xc9,0xe0,0xe1, +0x09,0xba,0x1c,0x30,0xf1,0x8c,0x87,0x39,0x54,0x24,0x9e,0xb2,0x53,0x18,0x67,0xd4, +0xe4,0x97,0xaf,0x59,0x54,0x2a,0x9c,0x31,0x27,0xb8,0xd8,0x65,0x45,0x20,0xaa,0xa5, +0xaa,0xa7,0x87,0x9e,0x37,0x9a,0x8f,0x4d,0x68,0x8d,0x42,0x86,0x59,0x60,0x96,0xf8, +0xab,0x39,0xd0,0xf5,0xd0,0x53,0x7b,0xa1,0x59,0x8a,0x90,0xdb,0xe2,0xf2,0xe5,0xe9, +0x8e,0x2a,0x99,0x4c,0x3b,0x7e,0x5a,0xbe,0x99,0xa9,0xc7,0x3e,0x6d,0xc8,0xd6,0x4d, +0xaf,0x1e,0x19,0xe9,0x12,0xfa,0x22,0x95,0x45,0xd2,0x15,0x15,0xc3,0x9a,0x8a,0xf8, +0x1a,0xc6,0xea,0x36,0xb0,0xb1,0xe5,0x1b,0x72,0xda,0xd4,0xd2, +0x9c,0x31,0x27,0xfe,0xd7,0x55,0x44,0x10,0x54,0x28,0x68,0x5c,0x99,0x8b,0xec,0xdb, +0x1f,0x56,0xbd,0x79,0xf1,0x4a,0xe9,0xe3,0x83,0xe5,0x22,0xc4,0x41,0xf7,0x99,0xcf, +0x77,0x6c,0x31,0xcb,0xd4,0xf1,0xc8,0x94,0xd5,0xd1,0x29,0x85,0x3a,0x0b,0x7a,0x33, +0x5d,0x3c,0x57,0x17,0x3d,0x4c,0xd4,0xb9,0xd3,0x34,0x81,0xba,0x72,0xe3,0x55,0x6c, +0x98,0xf8,0xb3,0x2d,0xea,0xae,0x6e,0x71,0x52,0x98,0xa2,0xdf,0x33,0x15,0xb3,0x43, +0xd2,0xbf,0x51,0x69,0x91,0xbc,0x9c,0x31,0x27,0xd3,0xd7,0x55,0x35,0x20,0x33,0x56, +0xcb,0x58,0xee,0xed,0xab,0xbb,0xc2,0x1b,0x32,0x72,0xec,0xa9,0x2c,0xa8,0x7e,0x66, +0xf0,0x43,0x61,0xc8,0xb8,0x62,0xac,0x34,0x35,0x6b,0x3d,0xf1,0x04,0x5f,0xd8,0x83, +0xd2,0x8a,0xbc,0x8c,0xd6,0x40,0xe7,0x75,0x75,0x66,0xa5,0x44,0xc7,0xba,0x46,0xe3, +0xca,0x7a,0x05,0x05,0xb3,0x53,0x4a,0x95,0x04,0xc9,0x6c,0x55,0xea,0x28,0x23,0x6d, +0xa3,0x44,0xeb,0x05,0xee,0xc9,0x72,0xe1,0xb3,0x27,0x13,0x26, +0x9c,0x31,0x27,0x29,0xd6,0x55,0x44,0x20,0x5d,0x97,0x68,0x50,0xf4,0x71,0xac,0xae, +0xb1,0xca,0x5a,0x61,0x8b,0x7d,0x1e,0x52,0x5c,0x66,0xf6,0xb7,0x3e,0xb5,0x1e,0xb6, +0x66,0x64,0x92,0xdd,0x6d,0x20,0x97,0x92,0xe7,0xd2,0xe5,0x2d,0x5d,0x4d,0xa6,0x86, +0x97,0x9d,0x69,0x1c,0x70,0x25,0xd5,0x4e,0x19,0xbe,0x77,0x5b,0xb4,0x76,0x3a,0x96, +0x17,0x77,0xe9,0x98,0xfc,0x46,0x05,0xa7,0x6a,0xf7,0x8b,0x9d,0x57,0x12,0x3d,0x77, +0xba,0xdf,0xcc,0xf1,0x50,0x75,0x9c,0x31,0x27,0xd0,0xd6,0x55,0x43,0x20,0xac,0x13, +0xdb,0xdf,0x14,0x8b,0xcb,0x4b,0xcc,0x25,0x31,0x86,0x6e,0x6b,0x4d,0x8a,0xb5,0xe6, +0x76,0x9b,0x96,0xcc,0xb9,0x8b,0x0a,0xdb,0xda,0x63,0x45,0x90,0x97,0x2d,0x48,0x1a, +0xcf,0xf9,0xc1,0x91,0x54,0xbf,0x60,0x83,0xa0,0x68,0xd4,0xaa,0xf8,0x31,0xcc,0xfa, +0x92,0xb2,0x82,0x9c,0x64,0xe4,0x55,0x4d,0x4c,0x1a,0x18,0xc2,0x70,0xaf,0x4c,0x29, +0x86,0x65,0x4f,0x68,0x54,0xba,0xc3,0x3e,0x6c,0x36,0xf1,0x26, +0x9c,0x31,0x27,0x98,0xd5,0x34,0x32,0x10,0xc1,0xa6,0x55,0x38,0x75,0x1b,0x34,0xdd, +0x98,0x25,0x02,0xae,0xb7,0xb7,0x8b,0x45,0x9c,0xd3,0x63,0x9b,0xb8,0x61,0x9c,0xbb, +0x53,0xfc,0xe8,0xdc,0x98,0xd2,0x3b,0x14,0x7d,0x59,0xab,0xeb,0xb1,0x0b,0x63,0xb1, +0x35,0xab,0x77,0x19,0x5b,0xe9,0x52,0x33,0x6d,0x56,0xdc,0x76,0x9c,0x52,0x6a,0x7b, +0x31,0xab,0xaa,0x37,0x7d,0xde,0x29,0x56,0xc2,0x4c,0xbe,0xc6,0x98,0xc4,0xeb,0x86, +0x79,0x23,0x78,0x12,0xd6,0x43,0x9c,0x31,0x27,0x2f,0xc4,0x43,0x32,0x00,0xaa,0x79, +0x62,0x95,0xf1,0xed,0x0f,0xc0,0xd8,0x25,0x97,0xcf,0x88,0x71,0xc8,0x3b,0xc8,0xba, +0xa1,0x48,0x96,0xa1,0x8e,0xdd,0x1f,0x17,0x8b,0x89,0xc6,0xe1,0x9e,0x98,0xa9,0x85, +0x04,0xb3,0x14,0x2a,0x95,0x68,0xc8,0xe6,0x63,0x9f,0xe3,0x5b,0xc9,0x17,0xb2,0x99, +0x5b,0x91,0x70,0x78,0xa2,0xd5,0x3b,0x6d,0x54,0xcd,0x97,0x6a,0xd3,0x1c,0x80,0x5d, +0xb5,0x8a,0x2f,0xe9,0x8b,0xcc,0xf8,0x92,0xe3,0x6e,0x35,0xcb, +0x9c,0x31,0x27,0x5c,0xc4,0x32,0x22,0x00,0x34,0x08,0x12,0x0c,0xd7,0x9e,0x2a,0x2d, +0x1b,0x43,0x5a,0x65,0xda,0xd9,0x41,0xe7,0x90,0xb3,0xac,0xa2,0x08,0x5e,0x87,0x46, +0x76,0xc1,0x65,0x75,0x64,0xb9,0x59,0xba,0x08,0xd3,0x2c,0x35,0x38,0x9e,0x49,0x16, +0x54,0xf6,0x6c,0xdf,0x31,0x2a,0x63,0x46,0x37,0xb0,0xe3,0xca,0xa9,0xa3,0xaf,0x49, +0x3c,0x52,0xe1,0x2e,0x63,0x02,0xac,0xef,0x6a,0x92,0x69,0x65,0x7b,0x05,0xd4,0xca, +0xc6,0xc9,0x92,0xca,0x2d,0xe7,0x9c,0x31,0x27,0xfe,0xc3,0x23,0x12,0x00,0x16,0x87, +0x52,0x81,0x96,0xbd,0xc7,0xeb,0x33,0x47,0x92,0x55,0x75,0x85,0xb5,0x73,0xcb,0x53, +0xd7,0x42,0x24,0x55,0x06,0xba,0xa8,0x94,0x93,0xab,0x52,0xb5,0x4e,0x6b,0x1f,0xa9, +0x63,0x32,0xaf,0xbd,0x51,0x34,0xb6,0xe2,0xbf,0x10,0x60,0xb3,0x93,0x0c,0xbe,0xfd, +0x8d,0x3a,0x19,0x9e,0xbb,0xb2,0xdb,0x0f,0x74,0xd1,0xa9,0x99,0x9e,0x84,0x46,0xb6, +0x11,0xbc,0xe9,0x7a,0x28,0xe2,0x47,0x70,0xf3,0x2f,0x46,0xaf, +0x9c,0x31,0x27,0x5d,0xc3,0x22,0x00,0x00,0x67,0x77,0x4e,0xa5,0x82,0x37,0x12,0xfd, +0x7a,0x7a,0x2a,0xcb,0xd5,0x1a,0x37,0x28,0xa6,0x77,0xb7,0xa8,0x2d,0xaf,0x53,0x51, +0x43,0x96,0x2b,0x18,0x25,0xdc,0x12,0x57,0xd4,0x67,0xef,0xbe,0x74,0xa8,0x5b,0x9c, +0x42,0xb2,0xf7,0x02,0x4b,0x31,0xd5,0xf2,0x55,0x5e,0xc5,0x22,0xaa,0xae,0x9f,0x7b, +0x15,0x78,0xab,0x39,0x93,0x46,0x33,0x26,0x79,0xdb,0x4c,0xa7,0x90,0x8f,0xca,0x37, +0xcd,0xe1,0x99,0x7f,0x95,0x93,0x9c,0x31,0x27,0x01,0xc3,0x11,0x11,0x00,0xc6,0x9e, +0x97,0x24,0xc8,0x8e,0x78,0x8f,0x29,0x44,0xc6,0xce,0x36,0x53,0x6d,0x6a,0xa8,0x8a, +0xdc,0xed,0x43,0x41,0x08,0x1a,0xab,0xd2,0x76,0x96,0x8a,0x89,0xe8,0xe3,0xa1,0x76, +0xca,0x82,0x3a,0x22,0x16,0xda,0x83,0xd5,0x7b,0x54,0xee,0xb7,0x5d,0x29,0xb0,0x95, +0x50,0x35,0xd0,0x8b,0xe3,0x5b,0xa2,0xda,0xbd,0x90,0xbf,0x17,0x3a,0x71,0xf1,0x86, +0x2f,0x84,0x4a,0x7a,0xfd,0x2f,0x27,0x32,0x7e,0x09,0x26,0x34, +0x9c,0x31,0x27,0x51,0xc1,0x10,0x00,0x00,0xd1,0xb2,0x9e,0x58,0xab,0x4b,0x41,0x92, +0x59,0x54,0xd0,0x6d,0x53,0xb2,0xaa,0x82,0xc3,0xb1,0x14,0x5c,0x4d,0x4f,0x74,0x84, +0xb7,0x17,0x25,0xd6,0x41,0x50,0xc6,0x14,0x86,0xc2,0x9f,0xd0,0x73,0x1d,0x65,0xb4, +0x1d,0x62,0x0a,0x0b,0x8c,0xee,0x63,0xb1,0x55,0x56,0x49,0xd6,0x95,0x29,0xa6,0xe3, +0xec,0xe4,0x5a,0x01,0xd4,0xee,0x22,0xb9,0xca,0xa4,0x47,0x15,0x5a,0xa1,0x31,0x60, +0xa2,0x97,0xe7,0x5c,0xc5,0x55,0x9c,0x31,0x27,0xc6,0xc1,0x01,0x00,0x00,0x8a,0x7c, +0xfe,0x5e,0xab,0xa1,0x85,0x3d,0x21,0x16,0x02,0xb4,0x68,0x52,0xa9,0x80,0x49,0xee, +0x48,0x57,0x42,0x6a,0x16,0xf2,0xb9,0xbc,0xa4,0xcb,0x41,0x65,0xaa,0x45,0x1a,0x20, +0x9a,0xb9,0x56,0xd1,0x51,0x5f,0x29,0x65,0xa2,0x03,0x8b,0x8d,0x64,0x5d,0x56,0xa8, +0x4e,0x76,0x0b,0x2a,0x03,0x34,0xcc,0x18,0x14,0xdb,0x2c,0x57,0xf2,0xb7,0x09,0x2c, +0xac,0x59,0x6e,0x53,0xd4,0x5a,0x4a,0xa7,0xf8,0x70,0x46,0x81, +0x9c,0x31,0x27,0x3e,0xc1,0x01,0x11,0x00,0x40,0xed,0x2c,0x8e,0x43,0x4d,0xed,0x77, +0x9d,0x73,0x0e,0x58,0x8e,0x4d,0x1b,0x16,0x15,0x6f,0x4d,0xf3,0x8f,0xd9,0xb6,0xdc, +0x12,0x64,0xc7,0x5a,0x0a,0xf2,0x51,0x89,0x52,0xed,0xbb,0x69,0x3a,0x1a,0xa0,0x35, +0xc9,0x7b,0x76,0x28,0xfe,0xc6,0x54,0xe2,0x73,0x26,0x45,0x4f,0x45,0x04,0x51,0x11, +0x27,0xa0,0xc3,0x88,0x5f,0xc8,0xa4,0x8d,0x95,0x4a,0x48,0xd8,0xf0,0xfc,0x65,0x1b, +0xf0,0x4e,0x0b,0x56,0x66,0x20,0x9c,0x31,0x27,0xef,0xc0,0x01,0x10,0x00,0x40,0xc8, +0xb4,0x55,0xaa,0xb7,0x24,0x22,0xc0,0x56,0xe6,0x15,0x3b,0x9c,0x2d,0x5f,0xe8,0xb2, +0xcc,0x54,0xd0,0x70,0xee,0x30,0xa9,0xa9,0xcb,0x26,0x05,0x6a,0xe9,0xcb,0xd8,0x62, +0xdc,0x2a,0x97,0x15,0x55,0x5c,0x46,0x32,0x24,0x2a,0x86,0x71,0x1e,0xa9,0x56,0x6d, +0x5d,0x3a,0x87,0x2d,0xfe,0xc2,0x75,0x1c,0x56,0xd7,0x20,0x79,0x8a,0xa7,0xc7,0x52, +0x24,0xc1,0x62,0x63,0x33,0x0c,0x42,0xe1,0x2f,0x54,0x8b,0xe5, +0x9c,0x31,0x27,0x6a,0xc1,0x11,0x10,0x00,0x7f,0x72,0x24,0xae,0x32,0x7c,0x94,0x95, +0x5a,0x91,0xde,0x47,0xcb,0xb0,0xd5,0xff,0xaf,0xe4,0x46,0x09,0x11,0xb1,0x47,0x13, +0x68,0x5a,0xb4,0x52,0xf7,0x19,0xae,0x9b,0x92,0xce,0xdc,0xa0,0xd9,0x89,0x4f,0xa0, +0x9a,0xa3,0x12,0x24,0x97,0x4a,0xe9,0xb5,0x91,0x63,0x36,0x90,0xcd,0x2d,0x74,0x0f, +0xa7,0x7a,0x2a,0xce,0x9d,0x4d,0x15,0x6b,0x02,0x2f,0x2e,0xc8,0xd3,0x92,0x5b,0x33, +0xce,0xd0,0x57,0x1a,0x63,0x63,0x9c,0x31,0x27,0x83,0xb0,0x10,0x10,0x00,0xea,0xec, +0xb4,0x5d,0xaa,0x9c,0x2c,0x6c,0xbe,0x54,0x3e,0x84,0xf8,0x8c,0xad,0x0f,0xb9,0x9b, +0x01,0x5f,0x37,0x16,0x65,0x32,0xad,0xc2,0xe4,0xea,0xa5,0x42,0xef,0x8a,0xd7,0x4a, +0xc0,0xf3,0x20,0xce,0xd5,0xf2,0xc1,0x4d,0x63,0x0b,0x1b,0xa5,0xb3,0x5f,0x54,0x43, +0x17,0x2d,0xb4,0xab,0x19,0xe1,0x3a,0xfc,0x5e,0x9b,0x55,0x56,0x32,0xb5,0x56,0xb6, +0x8b,0xb5,0x47,0x5b,0x4a,0xc4,0x0a,0xa4,0x2a,0x6f,0x32,0x15, +0x9c,0x31,0x27,0xb8,0xb0,0x11,0x00,0x00,0xd9,0xad,0x3e,0x49,0x2b,0x86,0xdd,0x30, +0x6c,0x14,0xc2,0x95,0x32,0x72,0x29,0x93,0x49,0x75,0x04,0x5c,0x3e,0x74,0x98,0x02, +0xba,0xb9,0x3a,0x8b,0xd5,0x52,0x18,0xab,0xa2,0xaa,0x92,0x04,0xd0,0xdb,0x55,0xaa, +0x7f,0x67,0x69,0x4b,0xc0,0x12,0x6f,0x61,0x55,0x8b,0xf4,0xed,0xf0,0x28,0xee,0x16, +0x9c,0x35,0x58,0xf8,0xcb,0xe6,0x4a,0xbc,0x50,0xa7,0xc9,0x11,0x5f,0x6f,0x37,0xe1, +0xc2,0x8f,0x79,0x50,0xd7,0x95,0x9c,0x31,0x27,0x0c,0xb0,0x11,0x10,0x00,0x75,0x24, +0x64,0xca,0x5b,0xbc,0x03,0x39,0xab,0x46,0x5e,0x05,0x94,0x83,0x11,0x33,0xca,0x18, +0xf1,0xd5,0xc9,0x5c,0x8c,0x6a,0x5a,0x70,0xd0,0xe5,0x3f,0x6b,0x8f,0x57,0xd0,0x8a, +0x99,0xed,0x2a,0x6b,0x09,0x48,0x1d,0xae,0xca,0x6d,0x87,0x5d,0x32,0x5b,0x37,0x00, +0x06,0x13,0xf7,0xaa,0x2e,0xaa,0x69,0xdc,0x23,0x95,0xe8,0x6b,0x2c,0x35,0xf6,0x92, +0x0e,0x2c,0x72,0xea,0x2d,0x37,0x82,0xad,0xb8,0x51,0x87,0x1d, +0x9c,0x31,0x27,0xcf,0xb0,0x10,0x11,0x00,0x30,0xdd,0x9a,0xad,0x81,0x31,0xc2,0x49, +0x86,0xa7,0x44,0x00,0xe3,0x49,0xd3,0x96,0x8b,0xa2,0x0a,0xa2,0xe5,0x9c,0x4c,0x46, +0x70,0x39,0xb0,0x66,0xad,0xf4,0x49,0x65,0xa7,0x23,0xc4,0x91,0x3e,0x13,0xb2,0x30, +0xc2,0x55,0x4b,0xa0,0xd8,0x5a,0x55,0x3e,0xe3,0x2f,0x12,0xd2,0xdc,0xec,0xf0,0x34, +0x3a,0x55,0x13,0x8f,0x17,0xcb,0x27,0xab,0x10,0xb4,0x17,0xcc,0x70,0x47,0x73,0x32, +0x71,0x57,0xfe,0xaa,0x61,0xd0,0x9c,0x31,0x27,0x40,0xb0,0x11,0x11,0x00,0x45,0xe2, +0x67,0x15,0x42,0x91,0x25,0x7b,0xa6,0xa2,0xc8,0x26,0x31,0xc3,0x6d,0xed,0x98,0x5d, +0x8e,0x05,0x6a,0xb1,0xcd,0x3e,0x27,0xa7,0x5a,0x8e,0x37,0x68,0x08,0xb4,0xbc,0x33, +0x63,0x2e,0x55,0xe5,0xe0,0x69,0x3b,0x0d,0x37,0x46,0x6e,0xe9,0xd5,0x9e,0x86,0x33, +0x8d,0x32,0x23,0x06,0x4b,0x58,0xd7,0x6b,0x47,0xd1,0xd3,0x30,0xeb,0xa6,0xde,0x5d, +0x74,0xf6,0xde,0x38,0x28,0xca,0xd2,0x63,0x98,0x72,0x15,0x5c, +0x9c,0x31,0x27,0x69,0xb1,0x11,0x01,0x00,0x90,0xad,0xf9,0x54,0xb0,0x77,0xc6,0x4e, +0x98,0x75,0x98,0xe7,0x28,0x2d,0x2d,0xfe,0x2d,0x50,0x51,0x6a,0x21,0xbf,0x79,0x14, +0xc8,0xb0,0x7e,0x45,0x76,0x55,0x94,0xd2,0x0a,0xf2,0x5a,0x1a,0x84,0x86,0xdd,0xb0, +0x43,0x97,0x2f,0x3e,0xa5,0x76,0x90,0x24,0x89,0x28,0x2d,0x32,0x60,0x75,0x2d,0x9e, +0xd3,0x62,0x0b,0xa7,0x4f,0x37,0x03,0xcc,0x4f,0x74,0x8e,0x05,0x50,0x8e,0xc5,0xcb, +0xcc,0x4a,0x62,0x23,0x8c,0xec,0x9c,0x31,0x27,0x37,0xb0,0x10,0x00,0x00,0xbf,0xa9, +0xd6,0xe8,0x5a,0xe8,0x0c,0xba,0xb5,0x34,0xfe,0x6b,0x2d,0xaa,0x6c,0x19,0x69,0x2e, +0x42,0xdc,0x01,0xcb,0xcd,0xa9,0xb0,0xad,0xc7,0x69,0x02,0x50,0x4c,0x4e,0x16,0xa4, +0xb9,0x1a,0xd7,0xa2,0x89,0xbc,0x55,0xc4,0xc8,0x53,0x2b,0x6d,0xbb,0xd9,0xa5,0x1c, +0xb6,0xe6,0xde,0x4b,0x16,0x2a,0x19,0x38,0x9b,0x44,0x9c,0x23,0xad,0xb4,0x7f,0x45, +0x54,0xe3,0x54,0x41,0x87,0x58,0xa4,0xab,0x1e,0xdd,0x32,0x69, +0x9c,0x31,0x27,0x12,0xa0,0x10,0x00,0x00,0xd1,0xad,0x6c,0xa2,0x5b,0xba,0x3a,0x80, +0x6e,0xa4,0xef,0xc5,0x24,0xe5,0x48,0xd8,0x72,0x91,0x2a,0xdb,0x59,0xac,0x0b,0x5a, +0x3d,0x5b,0xc3,0xe4,0x74,0x56,0x54,0x49,0x74,0xc8,0x88,0x90,0xe5,0xa4,0x51,0x97, +0x52,0xb7,0xd6,0xa3,0xe1,0x81,0xbb,0xa9,0xb5,0xe0,0x85,0x44,0xd0,0x68,0x7b,0x31, +0x8d,0x34,0xd7,0x8a,0xda,0x88,0x8d,0xbd,0xce,0x05,0xd5,0x2b,0x65,0x78,0x35,0xf9, +0xa6,0x8a,0xb9,0x5f,0x65,0x4d,0x9c,0x31,0x27,0xa6,0xa0,0x10,0x10,0x00,0x5c,0x51, +0xd7,0x66,0x4b,0xc9,0xc4,0x88,0x38,0x16,0xc2,0xb8,0xed,0x34,0x29,0x13,0x51,0xbb, +0x10,0x54,0x32,0xcb,0x26,0x22,0xba,0x92,0x4c,0xc4,0xa1,0x71,0xde,0xae,0x5b,0x2a, +0x9a,0xe6,0x59,0x0f,0xe5,0x2f,0x75,0xab,0x28,0x2b,0x7d,0x85,0x86,0x34,0x57,0x5f, +0xe6,0xd4,0x68,0xaa,0x6d,0x80,0xa3,0x2d,0x52,0x21,0x8d,0x95,0x80,0xb4,0x9a,0xd9, +0x83,0xf5,0x78,0x8e,0x94,0x93,0x8a,0xb4,0x7c,0xe4,0xad,0x85, +0x9c,0x31,0x27,0x4c,0xa1,0x11,0x01,0x00,0x1a,0xec,0x88,0x14,0xcf,0x12,0x6a,0x6d, +0x98,0x3f,0x98,0xcb,0xd8,0xbe,0xfc,0x24,0x0f,0xdb,0x39,0xe1,0xac,0x3c,0x62,0x92, +0xed,0xc2,0x7a,0xd5,0x66,0xf8,0x79,0x0d,0x42,0x31,0x4f,0x5a,0xc3,0x38,0xe0,0x23, +0x5c,0x88,0x51,0xb8,0xaa,0x83,0x8a,0x98,0x8f,0x56,0xae,0x65,0xbd,0x2d,0xaf,0xe8, +0x27,0x71,0xb3,0x2c,0x41,0x95,0x03,0x87,0xf4,0x7d,0x25,0xe8,0xb0,0xd3,0x0a,0x73, +0x50,0x64,0x9a,0x26,0x44,0xd9,0x9c,0x31,0x27,0x77,0xa1,0x10,0x11,0x00,0x47,0xc9, +0xf6,0x35,0x54,0x5f,0x35,0x2f,0xdd,0xbe,0xb1,0x71,0x5f,0xb2,0xf6,0xac,0xa6,0xcf, +0x65,0xc5,0xfc,0xd5,0x38,0xe5,0xc4,0xe6,0x7e,0x9e,0xf5,0xe4,0xfd,0x3a,0x6c,0xd1, +0x6d,0x0d,0x53,0xc7,0x96,0x78,0x2a,0x79,0xed,0x3a,0x4c,0xba,0xce,0xda,0x6d,0xef, +0x6e,0xa6,0xae,0xde,0xba,0x52,0x43,0xa2,0xa8,0xfc,0xcb,0x65,0x5c,0xc5,0x89,0xb5, +0x79,0xf5,0x19,0x3a,0x9a,0x24,0xf0,0xe7,0x7d,0x7d,0x18,0x5f, +0x9c,0x31,0x27,0x00,0xa1,0x11,0x00,0x00,0xa5,0xba,0x5b,0x17,0x8a,0x6d,0x83,0x1a, +0xce,0x61,0x42,0x15,0xf2,0xdb,0x2e,0x13,0xb6,0x60,0xc6,0x1b,0x7b,0xef,0xad,0x74, +0x08,0xa7,0xc4,0x6a,0xd8,0x50,0x4e,0x9b,0x12,0xd9,0x59,0x1e,0xd1,0xb3,0xd5,0xc4, +0x95,0xcc,0x4c,0x2c,0xae,0x23,0x27,0xd0,0xe4,0xdb,0x57,0x0b,0x5e,0xa4,0xf7,0xba, +0x31,0xad,0x6c,0xc6,0x21,0xd3,0xac,0xcd,0x69,0xb3,0x93,0x4d,0x4c,0x79,0x64,0xb2, +0x72,0x45,0x04,0xdd,0x5b,0xb5,0x9c,0x31,0x27,0x4c,0xa1,0x11,0x01,0x00,0xce,0x73, +0x66,0x67,0xcb,0x01,0x79,0x08,0xd5,0x84,0xc8,0xf9,0x5e,0xc7,0x1b,0xa6,0x64,0xd1, +0xaa,0x5c,0xbb,0xc3,0xa6,0xfd,0x12,0xaf,0xbe,0xe2,0x08,0x8d,0xda,0xc9,0x8b,0xaf, +0x30,0x3c,0xfb,0x66,0x58,0xc4,0x14,0x54,0x95,0xcf,0x51,0x24,0xed,0x66,0x7d,0x08, +0x28,0xd8,0x36,0x4a,0x79,0x9a,0xe6,0x56,0x5b,0x65,0xc9,0xbc,0xac,0xb6,0xfc,0xae, +0xf9,0x68,0x54,0x84,0xb1,0x3c,0xb4,0x21,0x42,0x3a,0x99,0xe2, +0x9c,0x31,0x27,0xc9,0xa0,0x01,0x01,0x00,0xa4,0xd2,0x2f,0xd5,0xcb,0x82,0x93,0xa4, +0xab,0x95,0x92,0x46,0xd4,0x58,0xa9,0xe2,0xd2,0x92,0xc8,0x59,0x1d,0x35,0x11,0x16, +0xb8,0x9b,0x89,0xf3,0x39,0x5d,0xf6,0x02,0xca,0x52,0x9d,0x8e,0xd7,0x4b,0x75,0x7e, +0xa5,0x10,0x8b,0x6b,0x86,0xc1,0x9e,0xd3,0x96,0x29,0x6a,0x32,0x5f,0xa9,0xf9,0x72, +0x7a,0x30,0x56,0xd6,0x15,0x19,0x98,0xb7,0xa7,0xc6,0x4a,0xa9,0x66,0x84,0x86,0x91, +0xca,0xa3,0xac,0xe6,0x4b,0xb5,0x9c,0x31,0x27,0x7d,0x90,0x10,0x00,0x00,0x3e,0x50, +0x78,0x4e,0xb7,0xcd,0x19,0xae,0x1a,0x6f,0x35,0x09,0xe1,0x38,0xd9,0x2d,0x1b,0xc2, +0xb9,0xb2,0x8b,0x55,0x6c,0x9b,0x79,0x94,0x70,0x89,0x36,0xf7,0xf3,0xa3,0xd3,0x2d, +0xa1,0x00,0xb7,0xa4,0xdb,0x19,0x3b,0x5f,0x6a,0xb7,0x5d,0xb6,0xfa,0x9b,0x6f,0xae, +0xf6,0xe9,0xa4,0xdb,0x02,0x93,0x02,0x51,0xb1,0x1a,0x33,0x16,0x63,0x72,0x0b,0x50, +0x8f,0x48,0xfb,0xa4,0x1f,0xe2,0x31,0xbf,0x01,0xc9,0xa9,0x1b, +0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0x13,0x9e,0x5a,0xe1,0xb6,0xe7,0xba,0x53, +0xc1,0x6f,0xa3,0x85,0xc3,0x16,0xdc,0xc6,0xda,0xe9,0xa9,0xb1,0xcc,0xdd,0x27,0x23, +0x8b,0x5f,0xc4,0x92,0x46,0xf6,0xe9,0x78,0x8d,0x2d,0xd8,0x4d,0x0f,0x10,0x1b,0x2d, +0x21,0x14,0xdd,0xb6,0x8a,0x24,0x42,0xcd,0x4f,0x23,0x28,0x51,0xa2,0xde,0x1c,0xea, +0xac,0x71,0xb4,0x26,0x25,0x95,0xd3,0x66,0x9c,0xd8,0xcb,0xe6,0xec,0x5c,0x57,0x46, +0x8d,0xe8,0xdc,0xcd,0xb2,0xdb,0x9c,0x31,0x27,0x55,0x90,0x20,0x00,0x00,0x5a,0xc9, +0x6e,0xcb,0x5a,0x52,0xe7,0x07,0xb1,0x36,0x62,0x6e,0x02,0xa3,0x6e,0xc8,0x0c,0x6e, +0x43,0x17,0x44,0xa8,0x93,0x6d,0xa4,0xc3,0x51,0x55,0x33,0x5f,0xb1,0x19,0x52,0x18, +0xec,0x8d,0x4c,0x5c,0x6d,0x8d,0x64,0x9d,0xc6,0xda,0x52,0xe4,0xf2,0x90,0xb5,0x9d, +0xa9,0xdb,0x53,0x6e,0x95,0xee,0x2a,0x26,0xda,0x29,0x67,0xe6,0x49,0xa6,0x48,0xb1, +0x22,0xd3,0x55,0x16,0x9d,0x4a,0x56,0xe3,0xb2,0x3c,0xe3,0x6d, +0x9c,0x31,0x27,0x23,0x91,0x11,0x01,0x00,0xb3,0x38,0x8f,0x5b,0xb2,0x80,0x8c,0x9f, +0xba,0x79,0x18,0xe4,0xc7,0x87,0x6d,0xb4,0x43,0x8a,0xca,0x0b,0xf2,0xce,0xc9,0xb3, +0x8a,0x72,0xc5,0xfb,0xf9,0x0f,0x19,0xeb,0x3b,0x91,0x50,0xdc,0x23,0xb2,0x1f,0xc6, +0x26,0x2f,0x2a,0xa2,0xd2,0x72,0x60,0x3c,0x8c,0xde,0xe0,0xb2,0xa1,0x7c,0x5f,0xb9, +0x8e,0xfd,0x6c,0x87,0x62,0xfb,0x02,0xef,0xd8,0xfd,0xa3,0xc5,0xce,0x2e,0x5b,0xad, +0x6f,0x3b,0x6c,0x83,0x10,0x5a,0x9c,0x31,0x27,0x97,0x91,0x11,0x11,0x00,0xc4,0x6a, +0xca,0xcb,0xa1,0x25,0x61,0x91,0xda,0xe4,0xfd,0xc0,0xb5,0x90,0x53,0x23,0x56,0x16, +0x64,0xab,0xbc,0xf4,0xaf,0x3d,0xf4,0x62,0xb7,0x9e,0x64,0xd2,0x3b,0x55,0x24,0x68, +0x2b,0x77,0x94,0x74,0xf1,0xb1,0x2c,0xbf,0x1b,0xf3,0x5c,0x98,0x75,0xe6,0xa1,0x55, +0x4c,0xcc,0x14,0x52,0x6a,0x0a,0x47,0x1d,0x5a,0x39,0x7b,0x6c,0x1d,0xd6,0xca,0xc7, +0xa1,0x64,0x98,0xda,0x17,0xde,0x96,0xa3,0x7b,0xd4,0x85,0xb3, +0x9c,0x31,0x27,0x89,0x81,0x10,0x01,0x00,0xa9,0x85,0xc9,0x94,0xcb,0xe8,0x72,0x67, +0xab,0x25,0x9a,0xd7,0x28,0x07,0xe8,0x52,0xea,0xa0,0x10,0x58,0x91,0x53,0x62,0x61, +0x3e,0xaa,0xb2,0x0a,0xb4,0x61,0xc2,0x1d,0x61,0x96,0x86,0x7b,0x8c,0x70,0x91,0x68, +0x47,0x0a,0x1a,0xd3,0xde,0xa8,0x9e,0xcb,0x36,0x9b,0x65,0xd7,0x68,0xe8,0xbb,0xc3, +0x48,0xb2,0x94,0xb3,0x67,0x38,0x5e,0x3c,0x08,0xce,0x53,0x53,0x6f,0xd3,0x1c,0x52, +0x88,0x94,0x8e,0x04,0xa8,0xbd,0x9c,0x31,0x27,0x89,0x81,0x10,0x01,0x00,0x36,0xcb, +0xaf,0x91,0xf3,0x93,0xce,0x5c,0x24,0x67,0x44,0x8d,0xc8,0x28,0xaa,0x19,0x4d,0x8a, +0x2e,0x12,0x9a,0x65,0x1d,0x23,0xb5,0xf1,0xb9,0xa0,0x97,0x76,0x41,0xed,0xe0,0x92, +0xaf,0xa0,0xd7,0x8a,0xf5,0x24,0x99,0x18,0x95,0xb3,0x25,0xb5,0xd8,0x8c,0x27,0x6d, +0x81,0x92,0x96,0xeb,0xde,0xe4,0xc8,0x35,0x52,0x4d,0xb9,0x40,0x14,0x2f,0x0c,0xf2, +0x25,0x50,0x75,0xff,0x2a,0x85,0x66,0xca,0x1a,0x37,0x4b,0x3d, +0x9c,0x31,0x27,0xb2,0x81,0x11,0x11,0x00,0x2c,0xf7,0xba,0xe4,0x1e,0xc0,0xb6,0x85, +0x8a,0xcb,0x3a,0x1c,0xac,0xb6,0x65,0x54,0xa9,0x1c,0xa6,0xf3,0x74,0x1a,0x2f,0x32, +0x69,0xa1,0xa8,0x59,0xbb,0x70,0x3d,0x18,0x49,0x08,0x5c,0x8d,0x57,0x8f,0x4d,0x46, +0x64,0xaf,0x13,0x96,0x80,0xea,0xb9,0x76,0x6a,0xb7,0x36,0xc4,0x35,0x46,0x18,0x91, +0xd9,0x17,0x15,0xcc,0x13,0x4a,0x41,0xe7,0x4e,0x75,0x62,0x1b,0x66,0x65,0x30,0x4c, +0xc8,0x63,0x08,0x19,0x76,0x51,0x9c,0x31,0x27,0xb2,0x81,0x11,0x11,0x00,0x70,0xb1, +0xc7,0x0b,0x66,0x74,0x18,0x8d,0x49,0x2e,0x0f,0x40,0xb3,0x50,0x7e,0x20,0x8d,0xab, +0x6a,0xd8,0x6a,0x52,0x48,0xdd,0xc7,0xca,0xf5,0x92,0x4a,0xdb,0xe2,0x2b,0x53,0x1b, +0xde,0x66,0x9f,0x90,0x8d,0x96,0xd8,0x47,0x45,0x56,0x8e,0x1d,0xa3,0x64,0x41,0x87, +0x17,0x8c,0x33,0x85,0x90,0x87,0x2b,0x20,0xca,0x5f,0x96,0x16,0x46,0xaa,0x78,0x52, +0xa5,0x93,0x15,0x38,0x93,0xc6,0xfa,0x53,0x38,0x59,0x5e,0x30, +0x9c,0x31,0x27,0x3e,0x72,0x11,0x00,0x00,0xd9,0x31,0xcc,0x11,0x0a,0x82,0xad,0xe2, +0x46,0x54,0x7b,0xb5,0x6e,0x82,0xad,0x87,0x8d,0x95,0x1c,0x9e,0x51,0x66,0x9e,0xfc, +0xab,0xb8,0xf6,0x34,0x10,0x46,0x44,0x4d,0xd9,0x40,0xcc,0x1c,0xb4,0x0d,0x25,0xe8, +0x4e,0xf7,0x9f,0x8a,0xef,0x64,0x90,0xac,0x54,0x67,0xc7,0xcd,0x7e,0x2b,0xe3,0x85, +0x76,0x9a,0x5e,0x18,0xcf,0x19,0xa2,0xb1,0xa2,0x05,0xe9,0x85,0x47,0xd5,0x3b,0xba, +0x68,0xb1,0xf5,0x65,0xec,0x19,0x9c,0x31,0x27,0x13,0x74,0x32,0x11,0x00,0xdb,0x27, +0x40,0xe4,0x97,0x53,0xa1,0x7e,0xaa,0xf1,0x9e,0xd8,0x76,0xa2,0xb3,0xe2,0xa1,0xd5, +0xe2,0xa7,0xee,0x73,0xd0,0xb1,0x8f,0x9b,0xa7,0x9f,0x6a,0xdf,0xe8,0x4e,0xad,0x07, +0xc0,0x2f,0x61,0x6d,0xce,0x82,0x5c,0xb9,0x03,0xa0,0xfd,0x44,0x66,0x16,0xd1,0xf4, +0x7e,0xe3,0xf0,0x5c,0x17,0x05,0xe8,0x94,0xf8,0x49,0xcb,0x8e,0xb1,0xb0,0x1c,0x07, +0xa1,0x8b,0x9e,0x87,0xf1,0x3d,0x06,0xc0,0x2e,0x9f,0x7a,0x11, +0x9c,0x31,0x27,0x87,0x31,0x00,0x00,0x00,0xce,0x8f,0xa0,0x55,0xb7,0x2d,0xab,0x08, +0x52,0x6c,0xa0,0x9b,0x26,0x24,0xdc,0x91,0x98,0x31,0x71,0xb9,0x2d,0x04,0x76,0xe3, +0x6d,0xaa,0xfb,0x89,0x26,0xda,0xd4,0x36,0x94,0x8d,0xcf,0xe4,0xc1,0x46,0xdb,0xa7, +0xb3,0xa6,0x4d,0xb7,0x2d,0x9b,0xb6,0x91,0x6d,0x75,0x2e,0xa5,0xb8,0xda,0x77,0x7d, +0xdc,0x6d,0xb8,0x91,0x25,0x98,0xd3,0x73,0xc6,0xf5,0x0e,0x46,0xe6,0xfb,0x7d,0x24, +0x8d,0xb6,0xbb,0x5b,0x16,0x9b,0x9c,0x31,0x27,0x3f,0x20,0x00,0x00,0x00,0x3e,0x6a, +0xec,0xae,0xed,0x67,0xaa,0x15,0x9d,0xde,0x52,0xa4,0x53,0x3b,0xb8,0x63,0x78,0x97, +0x66,0x7b,0x62,0xcc,0xd4,0xce,0xf9,0x2b,0x16,0x1e,0x19,0xc4,0x23,0x2b,0xbd,0x3b, +0xb0,0x5e,0x55,0x67,0x77,0xeb,0x87,0x0c,0xb5,0x0f,0x15,0xb2,0x61,0x9a,0x1c,0xc1, +0x23,0xc4,0x34,0x3b,0x5f,0x27,0x48,0x57,0x7a,0x51,0x30,0xec,0xce,0xeb,0xcd,0xa6, +0x1a,0x5d,0xd2,0xd5,0xb4,0x44,0x3b,0xc7,0xa5,0x97,0x48,0x77, diff --git a/config/_default_cfg_src_/res/en/SOUND_ALEXA_STOP.txt b/config/_default_cfg_src_/res/en/SOUND_ALEXA_STOP.txt new file mode 100644 index 0000000..ef0f208 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_ALEXA_STOP.txt @@ -0,0 +1,693 @@ +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0x9c,0xf7, +0xbd,0xf0,0x77,0xc1,0xd0,0x74,0x1c,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xc2,0x10,0x84,0x21,0x08,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xe7,0xb9,0xcf,0x7b,0xdd,0xd0,0x7c,0x5a,0xf7,0x43,0xde,0xf8,0x3d, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xee,0x7b,0xe1,0x07,0xbd,0xdf,0x07,0x3d,0xee,0x83, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbc,0x21,0x08,0x3d,0xee,0x67,0xc1,0xd0,0x7b,0xde,0xf1,0x83,0xdc, +0xd7,0x3d,0xdd,0x07,0x41,0xcf,0x7b,0xba,0x10,0x7b,0x9e,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x6c,0x60,0xf8,0x41,0xcf,0x09,0x39,0xf2, +0x7c,0x22,0x51,0x83,0xe1,0x17,0xbc,0x60,0xe8,0x31,0xcf,0x77,0x41,0xd0,0x73,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xc1,0xee,0x7b,0xde,0xf7,0x8b, +0x5f,0x07,0xbd,0xce,0xc7,0xc6,0x2f,0x73,0xde,0x0d,0x83,0xdd,0x07,0xbb,0xde,0xf8, +0x3d,0xef,0x77,0xbd,0xcf,0x83,0x9c,0xec,0x7c,0x20,0xf7,0xbd,0xda,0xd7,0xc1,0x8f, +0x73,0xbd,0xef,0x83,0x21,0x06,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x93,0xdd, +0x08,0xc5,0xef,0x17,0x3a,0x10,0x7b,0xdd,0xac,0x73,0xda,0xe8,0x3b,0x9e,0xe8,0x39, +0xee,0x78,0x39,0xcf,0x83,0xde,0xee,0x5b,0x60,0xe7,0x3d,0xd6,0xe7,0x41,0xaf,0x73, +0xba,0x0d,0x8c,0x1e,0xf7,0x94,0x19,0x07,0xbd,0xee,0xfa,0xb1,0xed,0x7b,0xde,0x34, +0x8c,0x9a,0xf8,0x3c,0x5a,0xd7,0xc2,0x10,0x67,0xc5,0xf0,0x8c,0x60,0xe7,0x9c,0x98, +0xc7,0x41,0xeb,0x09,0xb5,0xaf,0x7b,0xbe,0x30,0x63,0xda,0xf7, +0x9c,0x31,0x27,0xcd,0x11,0x00,0x00,0x00,0x62,0xd5,0xb3,0x0d,0xb6,0xdc,0x37,0x16, +0x13,0x6e,0x4d,0x87,0x44,0x36,0xdc,0x53,0x00,0x87,0x6d,0xb9,0xb6,0xd8,0xee,0xe3, +0x71,0x6a,0x91,0x64,0xb6,0xdd,0xd7,0x2c,0x53,0x6d,0x9d,0xa5,0xb4,0x9a,0xdb,0xca, +0xac,0x2d,0x11,0xb7,0x59,0xbf,0xc9,0x93,0x6c,0xa6,0x5f,0x8b,0x36,0xdb,0x91,0x59, +0x47,0x6d,0xb9,0x59,0x88,0xce,0xe3,0x78,0x0f,0x38,0x58,0xa6,0xe6,0x19,0x49,0xb2, +0x8d,0xd7,0x17,0xa5,0x36,0xdb,0x9c,0x31,0x27,0x00,0x22,0x10,0x00,0x00,0x78,0x63, +0x50,0x8d,0xaa,0xeb,0xb9,0x20,0xd2,0x56,0x2e,0x7b,0xb7,0x44,0xac,0x44,0xf1,0x76, +0x4d,0x55,0x1a,0x81,0x40,0xe2,0xac,0x53,0xba,0x80,0xc5,0x62,0x87,0x7c,0xb3,0x6a, +0xdf,0x30,0x68,0x22,0x95,0x4d,0x56,0x15,0xcc,0xaa,0xf2,0xd8,0x29,0xcb,0x55,0x71, +0x62,0x4a,0x38,0xac,0x73,0x29,0x6c,0x4d,0x54,0x20,0xe8,0xfc,0x92,0xb6,0xc4,0x95, +0x84,0xb5,0x55,0x55,0xeb,0x9a,0x8a,0xf5,0x95,0x53,0xe5,0x95, +0x9c,0x31,0x27,0x25,0x32,0x10,0x00,0x00,0x38,0x69,0x45,0x4d,0x2b,0x39,0xd2,0xd5, +0xda,0x56,0x7f,0xaa,0xb1,0x26,0xab,0xf8,0xf7,0x33,0x51,0x57,0x3a,0xaa,0x7d,0x0a, +0xa9,0xee,0x21,0x7a,0x19,0x6f,0x77,0xa2,0x86,0x42,0xc2,0x2b,0xb7,0xcb,0x55,0x6e, +0x14,0x48,0xb1,0xaa,0xb3,0x4e,0x0f,0x4b,0x56,0x97,0x86,0xc2,0x46,0xac,0x37,0x18, +0x8e,0x51,0x58,0x95,0xc8,0xa7,0x52,0xb4,0x49,0xdd,0xdc,0xb5,0x5c,0x85,0x6b,0xe2, +0x6a,0x97,0x48,0x47,0x01,0x15,0x9c,0x31,0x27,0x00,0x22,0x10,0x00,0x00,0xf9,0x19, +0xf0,0x11,0x2b,0x4c,0x2d,0x4e,0x5a,0x54,0xe6,0x28,0x9a,0x54,0xaa,0x5a,0xd7,0x6a, +0x72,0x5c,0xf9,0xe0,0xa4,0xe2,0xb7,0xa5,0xc4,0xc5,0xb5,0x63,0x67,0xf1,0xbb,0x4a, +0x98,0x14,0x65,0x86,0x95,0xd1,0x10,0x8b,0x29,0x2b,0x40,0xcb,0x58,0xdd,0x55,0xe2, +0x9e,0x16,0x2c,0xaa,0x1d,0x31,0x69,0x95,0x53,0x15,0x82,0xb4,0xca,0xad,0xc4,0xce, +0x3e,0x35,0x71,0x9a,0x9a,0x3c,0xaa,0xd9,0x34,0xa6,0x58,0xd5, +0x9c,0x31,0x27,0xba,0x32,0x22,0x10,0x00,0x24,0xbb,0x3e,0x47,0x9d,0x03,0x86,0x95, +0x77,0x32,0x56,0xf2,0xb6,0xfa,0xad,0x46,0x41,0xe5,0x91,0x92,0xd9,0x5a,0xec,0x49, +0x2a,0xe7,0x35,0xf9,0x52,0xdd,0x13,0xcd,0x37,0x8d,0xe8,0x84,0x12,0x25,0xaa,0x83, +0x6d,0x93,0x4d,0x43,0x0b,0x63,0x73,0x89,0x5d,0xb5,0x84,0x9b,0x2a,0x7c,0xa4,0xb0, +0xd2,0xa1,0x4b,0xb3,0x3b,0x54,0xb2,0x2d,0x99,0x75,0xa7,0x77,0x0f,0xed,0x6c,0xe5, +0x07,0x4a,0xa7,0x2a,0x13,0xcd,0x9c,0x31,0x27,0x99,0x54,0x44,0x20,0x00,0x8f,0xb1, +0x3c,0x3c,0x20,0xfe,0x82,0x7f,0x92,0x79,0xe7,0x01,0x0b,0x03,0x3c,0x25,0xfa,0x1e, +0x26,0xe8,0xcb,0xd4,0x0c,0x24,0xed,0xa5,0x99,0x69,0x08,0x5a,0x6c,0xb1,0x4d,0xc8, +0xc2,0xa4,0x26,0x9b,0x4d,0xa4,0x36,0xc2,0xbd,0x9c,0xe0,0x89,0x93,0x8d,0x8d,0x99, +0x09,0x38,0xdb,0x1c,0x57,0x5e,0x99,0x95,0xfb,0x0a,0xc3,0xd3,0xda,0x84,0x75,0x18, +0xaa,0xa8,0xce,0xb0,0xe8,0xb8,0xb8,0xb7,0xe2,0x4c,0x6a,0xb7, +0x9c,0x31,0x27,0xc9,0x75,0x54,0x40,0x00,0x7d,0x69,0x19,0x3f,0x8b,0x10,0x61,0xb7, +0x71,0x0a,0x0b,0xa1,0x5f,0x2a,0x2c,0x3d,0x41,0x22,0xa5,0x27,0x5f,0x06,0x05,0x0c, +0x12,0x05,0xa3,0x31,0x78,0xde,0xa9,0x88,0x84,0xe8,0xc2,0x5a,0x92,0x09,0xbc,0x71, +0x37,0x1f,0xc0,0x69,0x34,0x44,0x50,0x8b,0x06,0x4f,0xb2,0x9e,0xaa,0xa2,0xd4,0x74, +0x94,0x35,0x87,0xac,0xa1,0x77,0x49,0x38,0x1b,0xb9,0xe5,0x6d,0xa4,0x6a,0xe3,0xe5, +0x1b,0x48,0xd2,0x29,0xeb,0xce,0x9c,0x31,0x27,0xec,0xca,0x96,0x50,0x00,0x80,0x4f, +0xf8,0x09,0x29,0x04,0x5f,0xef,0x89,0xd9,0xf4,0x3f,0x20,0x51,0xac,0x07,0x84,0xbe, +0xbd,0x28,0x11,0x04,0x82,0x61,0xd0,0x3a,0x1f,0x17,0x3a,0xe0,0x4b,0x56,0x35,0xa3, +0xc2,0xd9,0x64,0x9a,0xe4,0x82,0xcd,0x8b,0x05,0x45,0x39,0x76,0xd8,0xd8,0x0d,0x83, +0xb8,0xb0,0x6b,0x30,0xb3,0xd1,0x63,0x34,0xaa,0x3c,0xc3,0xc6,0x71,0xd9,0xe7,0x03, +0x61,0x0c,0x9d,0xb2,0xee,0x5e,0xab,0x37,0x5b,0x3c,0xcc,0x19, +0x9c,0x31,0x27,0xe7,0xd9,0x85,0x50,0x00,0xc1,0xa8,0xd8,0xdb,0x6b,0x47,0x3a,0xaf, +0x4c,0xc8,0xa8,0xa7,0x5e,0x17,0x48,0x96,0xbe,0xb9,0x89,0xf8,0x34,0x6f,0x63,0x22, +0xf6,0xd2,0xca,0x31,0xc4,0xe3,0x72,0xbc,0x09,0xc9,0x4c,0x4b,0xf8,0x39,0x53,0xdb, +0x4c,0x71,0x04,0xab,0x47,0x69,0xa3,0xad,0x64,0x71,0x30,0x4c,0x6a,0xf8,0x74,0xa5, +0xa7,0xc6,0x38,0x10,0xef,0x54,0x84,0xb5,0xfe,0x96,0xc9,0xb9,0xe1,0xcb,0x95,0x55, +0xf3,0xd0,0x38,0xfa,0x34,0xe6,0x9c,0x31,0x27,0x80,0xd6,0x65,0x30,0x00,0xe0,0x15, +0x2d,0x98,0xb1,0x38,0x52,0xb5,0x2f,0xcc,0x4e,0xec,0xde,0x58,0x78,0x98,0x44,0xae, +0x0e,0xa8,0x1f,0xe7,0x5e,0xb4,0xf5,0x5e,0x74,0x9f,0x4a,0x22,0x6a,0xed,0xc1,0x55, +0xd5,0x72,0x24,0x44,0xcc,0xe3,0x6e,0x0a,0x69,0x19,0x2f,0xc4,0x15,0xec,0xb4,0x3b, +0xe6,0x32,0x5a,0x68,0xb1,0xab,0xdf,0xd6,0xc8,0x62,0x78,0xa0,0x61,0x94,0xb2,0xad, +0x16,0xfb,0xa1,0xb9,0xc2,0x16,0x38,0x59,0x85,0xa4,0x2c,0x10, +0x9c,0x31,0x27,0xc0,0xd6,0x43,0x10,0x00,0xe5,0x0b,0xd2,0x31,0x5d,0x15,0x7a,0xd1, +0xbc,0x38,0x23,0x91,0x61,0x23,0x78,0xfd,0xa8,0x93,0x32,0xa8,0xe0,0x41,0x1a,0xa0, +0xf4,0x34,0x89,0x3f,0x3b,0x21,0xda,0xf2,0x26,0xc7,0xdd,0x81,0xc4,0xcb,0xeb,0xdf, +0xaa,0xb1,0x78,0xd0,0xf0,0xaa,0x54,0xf1,0x30,0x0d,0xe6,0xad,0x6a,0x81,0x7c,0x34, +0x28,0x49,0x09,0x7b,0x0f,0xce,0xba,0x33,0x65,0xb7,0xaf,0x2d,0xe2,0x1e,0x49,0x31, +0x8c,0xe1,0xd6,0xdf,0x1d,0x91,0x9c,0x31,0x27,0x4f,0xd6,0x42,0x10,0x00,0xd9,0xa1, +0x2f,0x6e,0x9a,0xd0,0xf9,0x3e,0x47,0xc0,0x23,0xe9,0xbf,0xab,0x92,0x00,0x2c,0x2d, +0xf7,0x09,0x61,0xa4,0xdb,0x66,0x71,0xfc,0x8f,0x7f,0xbe,0x22,0x78,0xa6,0xd6,0x7c, +0xe5,0x66,0xa1,0xb1,0x11,0xd3,0xab,0x32,0xba,0x5a,0xbb,0x08,0xa5,0x92,0x3c,0x30, +0x6f,0x2b,0x58,0x7a,0x58,0xec,0x1b,0xe6,0xd9,0x75,0xb9,0x47,0x7e,0x31,0x78,0x95, +0x9c,0xe5,0x63,0xd2,0xe7,0x49,0xaa,0x68,0x56,0x46,0x9c,0x4d, +0x9c,0x31,0x27,0xe8,0xd5,0x54,0x10,0x00,0xc9,0x2b,0xe8,0x2f,0xd4,0x9d,0xf7,0x0f, +0xdb,0x2c,0x3b,0x32,0xa0,0xbd,0x5a,0xb9,0x9e,0xcc,0x76,0x99,0x94,0x78,0xb9,0x81, +0xb0,0xff,0x37,0x85,0x4c,0xa4,0x3d,0x2f,0x53,0xd8,0x6a,0x7d,0x36,0x77,0x69,0xc0, +0x65,0x3b,0xf2,0x4e,0x89,0x00,0x17,0x1a,0xa8,0x53,0x30,0xaa,0xbb,0x4b,0x3f,0x49, +0xda,0x86,0x79,0xbd,0x4f,0xad,0x25,0x90,0x06,0x45,0x4a,0x0c,0xa4,0x97,0x56,0x94, +0x18,0x6b,0x0c,0xfc,0x97,0x0a,0x9c,0x31,0x27,0x44,0xd5,0x44,0x00,0x00,0xb4,0x2a, +0x4b,0x4c,0xde,0x74,0x72,0xde,0x2a,0x2c,0x78,0x4b,0xbb,0xdb,0xbb,0xa2,0x0c,0x67, +0xc8,0x09,0xb3,0xe8,0x6b,0x54,0x2f,0xbc,0xb1,0x56,0x5e,0x26,0x1a,0xc5,0xaf,0xbb, +0xeb,0x42,0xd8,0x6e,0x76,0xa7,0xae,0x3e,0xef,0x10,0x65,0x53,0x75,0xb5,0xc8,0x95, +0x1a,0xeb,0x13,0x4b,0xce,0x53,0x06,0x28,0xa9,0x69,0xe2,0x2d,0x11,0x2f,0xe0,0xdf, +0x22,0x6f,0x28,0x81,0x51,0xe8,0x9a,0xe9,0x56,0xf3,0xfc,0x96, +0x9c,0x31,0x27,0x59,0xd5,0x52,0x00,0x00,0x9b,0xbd,0x3f,0xa7,0x52,0x60,0x62,0x9b, +0x12,0xf0,0xb8,0x63,0x6d,0xf8,0x3b,0xed,0x6d,0xfa,0xad,0xb9,0x7f,0x0c,0x13,0x66, +0x70,0x54,0x41,0x26,0x97,0xe9,0x25,0x5c,0xcb,0x65,0xe6,0x4c,0xf7,0x9a,0x34,0x8e, +0x40,0xdf,0x1f,0x42,0x59,0x63,0x2e,0x16,0x98,0xe1,0xc5,0xd4,0x26,0x9c,0x35,0x0f, +0x08,0x6a,0x19,0x58,0x94,0x71,0x9d,0x70,0x53,0xc8,0x64,0x50,0xaa,0x99,0x84,0xcb, +0xde,0x64,0x73,0x26,0x90,0x33,0x9c,0x31,0x27,0x4b,0xd4,0x53,0x00,0x00,0x7f,0xb1, +0xf9,0x1f,0x7c,0x51,0x7d,0xf5,0xee,0xf5,0x0c,0x7a,0xf4,0x51,0x9c,0x69,0xd6,0x68, +0x33,0xa9,0x2d,0x5e,0x51,0x7a,0xf0,0x81,0x5b,0x67,0x71,0x2b,0xe1,0xba,0x4f,0x31, +0x61,0x96,0x20,0xc3,0x92,0x71,0x39,0x13,0x6e,0xb0,0x53,0x09,0x07,0x2e,0xc9,0x3b, +0xa1,0x8d,0xe5,0xb4,0x83,0x43,0xfb,0x73,0xc8,0xee,0x07,0xd4,0x59,0x71,0x49,0x93, +0x66,0xad,0xed,0x8a,0x82,0x4b,0x66,0xdd,0x08,0x65,0xa0,0x49, +0x9c,0x31,0x27,0xdc,0xd4,0x42,0x00,0x00,0x63,0x7d,0x99,0x68,0x86,0x50,0x39,0xcb, +0x02,0xbd,0x60,0xa9,0x15,0x69,0x94,0xaa,0x09,0x79,0x34,0xa8,0xe3,0xda,0x90,0x16, +0x91,0x81,0xc8,0x9b,0x76,0xae,0x42,0xb7,0x3e,0x06,0xda,0x3c,0xf5,0x8e,0xce,0x5b, +0x06,0x1d,0x07,0x84,0x54,0x45,0xae,0x8f,0x1d,0x84,0xba,0xec,0x01,0x8c,0xb6,0xf2, +0xe8,0xa5,0x18,0xb9,0x22,0x6c,0xf7,0xb1,0xe9,0x3d,0xd5,0xb2,0x6e,0x70,0x9d,0x39, +0x17,0xd5,0x16,0x92,0x52,0x58,0x9c,0x31,0x27,0x09,0xd5,0x32,0x00,0x00,0x52,0xad, +0x37,0x24,0x3c,0x5c,0x5a,0xed,0xaa,0x85,0xaa,0xf5,0x1e,0x23,0xa4,0xc2,0x67,0xea, +0xb6,0x88,0xab,0x54,0x36,0x38,0x52,0x5d,0x23,0xa9,0xd7,0xaf,0x16,0x75,0x5e,0x38, +0xd1,0x5a,0x98,0xab,0x7d,0x4a,0x15,0xb7,0x9f,0x5c,0x62,0xfb,0x27,0x06,0x0d,0xc2, +0xf7,0x2f,0x22,0x74,0xb7,0xad,0x4c,0xea,0x18,0x93,0xd7,0xd6,0x92,0x13,0x2f,0xb7, +0xaf,0x5c,0x2f,0xd0,0x70,0x52,0x30,0xcd,0x04,0xe6,0xa2,0x32, +0x9c,0x31,0x27,0x94,0xd4,0x32,0x00,0x00,0x42,0x81,0x13,0x4f,0x74,0x6b,0xd4,0x52, +0x3a,0x05,0xdb,0x17,0x96,0x74,0x34,0xb4,0x4c,0x99,0xbb,0xc8,0xa9,0x69,0xd5,0xb4, +0x33,0xb6,0x31,0x28,0x56,0xef,0x3c,0x95,0xb4,0xb6,0xc7,0xee,0xd0,0x8d,0x68,0x3d, +0xc1,0xac,0x50,0xf0,0x76,0xfa,0x6d,0xf8,0xa9,0xec,0xa4,0x32,0x9d,0x74,0xbe,0x65, +0x37,0xea,0x58,0xd2,0xcf,0x10,0x94,0x34,0x35,0x25,0x61,0xe7,0x2e,0x1f,0x69,0x57, +0xa1,0x43,0x7c,0xd4,0x9d,0x90,0x9c,0x31,0x27,0x8c,0xd4,0x22,0x00,0x00,0x3b,0x95, +0x27,0x86,0xe6,0x83,0x3c,0x26,0xf9,0x85,0xff,0xc4,0xf4,0xcc,0x7c,0xaa,0x06,0x48, +0x46,0x38,0xbc,0xdd,0x8f,0x98,0xf4,0x9f,0x1d,0xa1,0x95,0x2d,0xe0,0x7d,0x61,0xc7, +0x3f,0xdc,0x84,0x86,0x50,0x3a,0x56,0x72,0xfc,0xee,0x91,0xa2,0xb9,0x8a,0x3e,0x12, +0x58,0x61,0xc3,0xec,0x9e,0x8a,0xa7,0xc9,0xd8,0xc1,0x98,0x4f,0x34,0x14,0xe2,0xc3, +0xb6,0xdb,0xac,0xb9,0x4b,0xf6,0x2e,0xbb,0x2c,0xe8,0x84,0x73, +0x9c,0x31,0x27,0x09,0xd5,0x32,0x00,0x00,0x38,0xf1,0xe7,0x0f,0x0c,0xa1,0xf3,0x24, +0xed,0x26,0x28,0x46,0x22,0xbb,0xb4,0x86,0x67,0x12,0x7b,0xf8,0xd0,0x16,0xc8,0x72, +0x95,0x74,0x31,0xd6,0xdd,0xab,0xa7,0x56,0x35,0x34,0xb6,0x10,0xeb,0x8d,0x92,0x39, +0xa9,0x91,0x0c,0xb6,0xb4,0x63,0xea,0x89,0xfa,0x30,0xd7,0xbc,0x13,0xdc,0x6a,0x8c, +0x87,0x69,0xe8,0xe1,0x9a,0xec,0xae,0x75,0xd7,0x40,0x60,0x22,0xea,0x75,0x5e,0xc7, +0xb1,0x32,0x3e,0xfd,0xa2,0x9c,0x9c,0x31,0x27,0x50,0xd4,0x41,0x00,0x00,0x3b,0xa1, +0x55,0x1a,0x08,0xc3,0x04,0xb2,0x11,0x96,0x32,0x45,0x6b,0xad,0xfc,0x58,0x8f,0x46, +0x7e,0x99,0x15,0x17,0xae,0x06,0xf6,0x1f,0xc6,0x1f,0x50,0x69,0x10,0x55,0x42,0x60, +0x2f,0x2a,0xcc,0x82,0x09,0x3d,0xb5,0xfc,0xd8,0xb0,0xcd,0x6d,0x0d,0x87,0x0e,0x32, +0xa2,0x42,0x21,0xe4,0x53,0x6b,0xb4,0x35,0xe9,0x35,0x05,0xe7,0x3a,0xf6,0x42,0x3a, +0xd3,0xcd,0x67,0xb8,0x3f,0x27,0x4e,0xac,0x9c,0xd5,0x5d,0x41, +0x9c,0x31,0x27,0xf4,0xd3,0x21,0x00,0x00,0x3f,0xd0,0x94,0x4a,0x72,0xda,0x92,0x39, +0x41,0xd2,0x3c,0xa2,0x73,0x9c,0xc4,0x48,0x49,0xc2,0x92,0xe9,0x48,0x14,0x4f,0xea, +0xd6,0x2f,0x30,0xa6,0xaa,0xa5,0xf1,0x42,0x77,0x6c,0xa9,0xec,0x3e,0xf7,0x00,0x44, +0x8e,0x62,0x0d,0xd0,0xe7,0xf2,0xa3,0x62,0xf2,0x3d,0x64,0xc4,0x0c,0x14,0x42,0xd1, +0xe4,0x74,0x29,0x78,0x94,0x8c,0x26,0x56,0x1d,0x4e,0x3a,0x30,0x24,0x58,0x6f,0x82, +0x72,0x28,0x0e,0xa7,0x1e,0xf5,0x9c,0x31,0x27,0xb2,0xc4,0x30,0x00,0x00,0x0f,0xf5, +0xd6,0xfe,0x2a,0xe0,0x5c,0x5d,0x75,0x96,0x75,0x47,0x02,0x65,0x2c,0x74,0xa6,0xc1, +0x85,0x5b,0x5c,0x1c,0xc3,0x6a,0xbc,0x16,0x1d,0x03,0x25,0x65,0x2e,0x7c,0x85,0x0a, +0x8d,0x30,0xb4,0x1a,0x55,0x1b,0xaa,0x72,0x30,0xaa,0xf0,0xdb,0x08,0xc4,0x56,0x71, +0x86,0xa9,0x64,0xac,0x91,0xcb,0x42,0x99,0x5b,0xa2,0xdf,0x89,0x2a,0xbb,0x0b,0xb4, +0x93,0x15,0x61,0x2e,0x75,0xb4,0x0a,0x8b,0x4e,0xb6,0x74,0x55, +0x9c,0x31,0x27,0x3d,0xc4,0x31,0x00,0x00,0x26,0x09,0x1d,0x75,0x89,0x00,0x15,0x8b, +0x14,0xa2,0x6f,0xdb,0x59,0xba,0xec,0xaf,0xd6,0xbb,0xb4,0xbc,0x16,0x34,0x07,0xd6, +0x1a,0x5a,0x18,0x8e,0xf4,0x5d,0x1b,0xbc,0xa3,0x14,0x09,0x2b,0x78,0xbe,0x3b,0x30, +0x76,0xfe,0x8a,0x89,0x0b,0x91,0xcd,0x16,0x82,0x64,0x33,0x4d,0xd2,0xf4,0xc8,0x98, +0x1b,0x64,0x0c,0x8f,0x89,0x44,0xb5,0x39,0xbc,0x1c,0x86,0xb7,0x58,0xf3,0x97,0x8a, +0x4d,0x87,0xa1,0xa6,0x8b,0xba,0x9c,0x31,0x27,0x46,0xc3,0x30,0x00,0x00,0x3c,0x2c, +0x66,0x6b,0x0b,0x17,0x3e,0xac,0xb8,0x56,0x5d,0xd9,0x11,0x64,0xac,0xf2,0x49,0x63, +0x3a,0x5c,0xe2,0x49,0xc5,0x2c,0xb8,0x72,0xe2,0x94,0x15,0x55,0x5f,0x99,0x28,0x8a, +0x87,0x90,0x8e,0x66,0x45,0x45,0xb8,0xc6,0xec,0x2b,0x1f,0xca,0x01,0x65,0x56,0x62, +0xa1,0x3b,0x1d,0x2d,0x1f,0xb8,0x25,0x56,0x5c,0xfd,0x4f,0x2d,0x6a,0xb7,0x16,0x5b, +0xdf,0xd1,0x52,0xcf,0xa8,0xb5,0x2a,0x88,0xe3,0x83,0x77,0x55, +0x9c,0x31,0x27,0xb2,0xc4,0x30,0x00,0x00,0x4d,0x4a,0x0a,0xd6,0xab,0x24,0xe3,0xed, +0xb5,0x46,0x69,0x45,0xab,0xfc,0xad,0x48,0x51,0x07,0x79,0x5c,0xf6,0xe3,0x11,0x0a, +0xb5,0xba,0x23,0x9a,0x55,0x50,0xb3,0x96,0x23,0x2a,0x8a,0x56,0xa5,0x3e,0x15,0x55, +0x13,0x1c,0x60,0x2b,0x2a,0x3a,0xe1,0x0e,0x56,0x6d,0x2a,0x6a,0x0a,0xad,0x63,0x0d, +0x54,0x16,0x5c,0xf4,0x30,0x69,0x4a,0xb4,0xa8,0xb3,0x0e,0x82,0x4e,0x94,0xa7,0x24, +0xaa,0x8c,0x36,0xe2,0x58,0x55,0x9c,0x31,0x27,0x76,0xc3,0x10,0x00,0x00,0x5d,0xae, +0x80,0x48,0xab,0x2d,0x73,0x42,0x39,0x56,0x6c,0xf8,0x20,0x12,0xad,0x84,0xef,0x64, +0x55,0x5c,0xe1,0x6e,0x0e,0xac,0xb3,0x33,0x34,0xa3,0x15,0x4c,0xa1,0x6e,0x74,0xaa, +0x8f,0x66,0xda,0xbd,0x55,0x67,0x36,0x11,0x58,0xab,0x31,0x92,0xb1,0x8a,0x56,0x6f, +0x07,0x81,0x52,0xad,0x9e,0x2e,0x0d,0x49,0x5c,0xb3,0x6a,0x27,0x2a,0xb1,0xe1,0x41, +0x55,0x15,0x4b,0x57,0x47,0x86,0xaa,0x92,0xad,0xe2,0x31,0x55, +0x9c,0x31,0x27,0x46,0xc3,0x30,0x00,0x00,0x6d,0x04,0xb4,0xa6,0x2b,0x30,0x6f,0xe5, +0x0a,0x56,0x71,0x62,0x21,0xec,0xad,0xba,0xae,0xb4,0xb1,0x5c,0x81,0x4d,0xca,0x72, +0xb0,0xd0,0x76,0x15,0x05,0x4b,0x34,0xb5,0xac,0x2a,0x96,0x63,0xdc,0x5a,0x55,0x70, +0x56,0xd0,0xc8,0x2b,0x29,0x3a,0x39,0xaa,0x56,0x70,0x13,0x33,0x54,0xad,0xdd,0x5a, +0x47,0x21,0x5c,0x57,0x4d,0xee,0xca,0xaf,0xa0,0xe5,0x5c,0x55,0x4a,0xb1,0x2d,0x3b, +0x0a,0x9a,0x6d,0x97,0x76,0x55,0x9c,0x31,0x27,0xaa,0xc4,0x20,0x00,0x00,0x75,0xc5, +0xda,0xe4,0xab,0x28,0x13,0xdd,0xb1,0x56,0x76,0x47,0xc2,0xfd,0x2d,0xf0,0xd1,0x67, +0x75,0x5c,0x03,0x60,0x10,0x8a,0xae,0x56,0xbf,0xe2,0x15,0x4a,0x01,0x82,0x46,0x2a, +0x9d,0xde,0xdf,0x7d,0x55,0x7c,0xf6,0xde,0xd2,0xab,0x29,0x5b,0x61,0x0d,0x56,0x78, +0x7c,0x91,0xad,0x2e,0x00,0x0f,0xb4,0xa5,0x5b,0xaa,0x31,0xca,0x0a,0xac,0xef,0xb7, +0xd5,0x15,0x49,0xc2,0xb2,0xaa,0x2a,0xa3,0xc3,0x06,0x55,0x55, +0x9c,0x31,0x27,0x76,0xc3,0x10,0x00,0x00,0x83,0x9b,0x40,0xb2,0xab,0x24,0x02,0xb1, +0x35,0x56,0x76,0xab,0xa4,0xd2,0xae,0x0b,0xb0,0x4f,0x15,0x5b,0x37,0x63,0x5f,0xaa, +0xab,0xbb,0xb0,0xb7,0x55,0x4a,0x5a,0x90,0x58,0xaa,0xa8,0x60,0xbc,0xad,0x55,0x87, +0x66,0x69,0x0a,0xab,0x24,0x5a,0x7a,0x16,0x56,0x7f,0x79,0xc4,0x6a,0xae,0x07,0x31, +0xee,0x55,0x5a,0xbc,0xe2,0xa0,0xaa,0xaa,0xd8,0x2e,0xc8,0x55,0x4a,0xdc,0x8b,0x9e, +0xaa,0xac,0x09,0x03,0x51,0x55,0x9c,0x31,0x27,0x9a,0xc4,0x00,0x00,0x00,0x8a,0x54, +0xde,0xc6,0xab,0x24,0x4a,0xaf,0x51,0x56,0x84,0x5c,0x1c,0x62,0xae,0x03,0xad,0x15, +0x35,0x5a,0x57,0x2e,0xe2,0x6a,0xaa,0x0b,0xac,0x64,0xd5,0x4b,0x81,0x3f,0x25,0xaa, +0xaf,0xe8,0xb1,0x53,0x55,0x8d,0x52,0xdd,0x06,0xab,0x21,0xa2,0x6b,0x11,0x56,0x88, +0xb3,0xbe,0xa2,0xad,0xfd,0xca,0x1a,0x35,0x59,0xe0,0x4e,0x6c,0x4a,0xa9,0x5d,0x60, +0x96,0x95,0x4c,0x89,0x40,0xad,0x2a,0xb3,0x33,0x87,0xd3,0x55, +0x9c,0x31,0x27,0x82,0xc4,0x10,0x00,0x00,0x8e,0x12,0xdb,0x50,0xab,0x21,0xb6,0x22, +0x85,0x56,0x98,0x4b,0xa1,0x02,0xad,0xf8,0xf8,0xfa,0xf5,0x59,0x51,0x2d,0x95,0xea, +0xa8,0xa9,0x60,0x2c,0x55,0x4d,0xb4,0xbf,0x5f,0x2a,0xb6,0x0b,0x89,0x4a,0x55,0x8e, +0x6e,0xfa,0x92,0xab,0x23,0x85,0xcd,0x3d,0x56,0xaa,0x8e,0x0e,0xca,0xad,0xe8,0x78, +0x2e,0x85,0x58,0xa0,0x97,0x0b,0xaa,0xa8,0x00,0xe0,0x96,0x55,0x4f,0x55,0xdb,0x23, +0xaa,0xb9,0x55,0x7d,0x3d,0x55,0x9c,0x31,0x27,0x6e,0xc3,0x00,0x00,0x00,0x8f,0xc1, +0x83,0x32,0x2b,0x29,0xa9,0xd8,0x64,0x56,0xb5,0xe5,0x79,0xb6,0xad,0xba,0xd8,0xac, +0x6d,0x57,0xf5,0x75,0x18,0xda,0xa7,0x96,0xde,0xad,0x35,0x50,0xea,0x56,0x1a,0x6a, +0xbc,0x29,0x86,0xb6,0xd5,0x90,0x07,0x0e,0x51,0xab,0x2c,0x7d,0xd2,0xa4,0x56,0xc4, +0xb5,0x89,0x28,0xad,0xa7,0x67,0x4a,0x69,0x57,0x72,0x30,0xc2,0x9a,0xa7,0x41,0x9b, +0xe1,0x35,0x52,0x29,0xce,0x03,0x4a,0xbd,0x9f,0x70,0x06,0x95, +0x9c,0x31,0x27,0x76,0xc3,0x10,0x00,0x00,0x8e,0xd9,0xd5,0x72,0xab,0x30,0x14,0x5c, +0x15,0x56,0xd0,0x98,0x2b,0x4a,0xad,0x8b,0x3b,0x3d,0x55,0x56,0xf8,0xdd,0x7b,0x2a, +0xa7,0x2a,0xee,0x77,0x55,0x53,0xf1,0x89,0xd4,0xaa,0xbf,0xa9,0x7b,0x41,0x55,0x8d, +0x59,0xb5,0xe2,0xab,0x30,0x75,0x43,0x49,0x56,0xd6,0xa7,0xf8,0xea,0xad,0x5e,0x32, +0xd5,0x95,0x56,0x71,0x9d,0xae,0x2a,0xa7,0x54,0x52,0x63,0x55,0x56,0x2c,0x83,0xb8, +0xaa,0xc1,0xeb,0x35,0x35,0x55,0x9c,0x31,0x27,0x5e,0xc3,0x20,0x00,0x00,0x8c,0x5e, +0xd4,0xf4,0xcb,0x32,0x32,0x7d,0xfd,0x56,0xd5,0x74,0x04,0x72,0xad,0x1f,0x49,0xb9, +0x25,0x55,0xf8,0x2c,0x32,0xca,0xa7,0xc7,0xa8,0x62,0x55,0x58,0x55,0x3b,0x41,0x8a, +0xc3,0x3d,0x8b,0x6b,0x55,0x8c,0x50,0xd6,0xc8,0xab,0x37,0x8a,0x51,0xc9,0x96,0xd2, +0xf4,0x4c,0x52,0xac,0xdb,0x58,0x1a,0x35,0x55,0x87,0xb7,0x56,0x68,0xa8,0x0e,0x9e, +0xf0,0x11,0x59,0xcd,0x6f,0x61,0xaa,0xc4,0x7d,0x62,0xae,0x55, +0x9c,0x31,0x27,0x8d,0xb3,0x10,0x00,0x00,0x9a,0x56,0xdb,0x1c,0xab,0x7b,0xd3,0xd5, +0x75,0x57,0xaa,0xdb,0xfb,0x2a,0xad,0x58,0xcc,0xf5,0x95,0x52,0x50,0x63,0xeb,0xaa, +0xa0,0x75,0xc7,0x56,0x55,0x55,0xd3,0x93,0xa4,0xaa,0xca,0x5c,0xe1,0x11,0x55,0x9d, +0xea,0x19,0xfa,0xab,0x89,0x24,0xb3,0xa5,0x57,0x99,0x58,0xf9,0xaa,0xac,0xd6,0x4e, +0x53,0x15,0x51,0xdb,0x62,0xef,0x2a,0xa1,0x94,0x3c,0xdd,0x55,0x58,0x16,0x8a,0xb2, +0xaa,0xcb,0x30,0xe2,0xfd,0x55,0x9c,0x31,0x27,0x38,0xb2,0x20,0x00,0x00,0xa1,0xc3, +0xcb,0x52,0xab,0x91,0xf8,0xb6,0xb5,0x57,0x79,0x32,0x8e,0xca,0xac,0x59,0xa3,0x62, +0xd5,0x51,0x98,0xb8,0x50,0x2a,0xa2,0xce,0xdf,0xb1,0x55,0x5a,0x21,0x1b,0x80,0xaa, +0xcb,0xbe,0xd2,0xd6,0x55,0xa5,0x42,0xb5,0x7a,0xab,0x9a,0x4e,0xba,0x95,0x57,0x5c, +0xcf,0x75,0x0a,0xab,0xe6,0x6c,0xe8,0xd5,0x51,0x6d,0xb2,0x4c,0xaa,0xa3,0xfb,0xb9, +0x93,0x55,0x5b,0xb2,0xa3,0x14,0x2a,0xcc,0x7a,0x3d,0xf6,0x55, +0x9c,0x31,0x27,0xaa,0xb1,0x10,0x00,0x00,0xa9,0x49,0x49,0xeb,0x2b,0x9d,0xfe,0x0c, +0x25,0x57,0x3a,0xd5,0x88,0xca,0xab,0x8a,0xd2,0x12,0x15,0x51,0x54,0x9f,0xe3,0xaa, +0xa4,0xcd,0xdf,0x4c,0x55,0x5c,0xdb,0x51,0x8e,0xaa,0xcd,0x73,0x08,0xf9,0x55,0xae, +0x8d,0xd1,0xd4,0xab,0xa8,0x06,0x43,0x45,0x57,0x26,0x29,0x76,0xca,0xab,0x2b,0xd3, +0x4b,0xd5,0x51,0x0d,0xa7,0xe1,0xaa,0xa5,0x6b,0x4f,0x4f,0x55,0x5d,0xa4,0xc9,0xc0, +0xaa,0xcd,0xfc,0xbf,0x85,0x55,0x9c,0x31,0x27,0xaa,0xb1,0x10,0x00,0x00,0xb3,0xd2, +0xe7,0x6a,0xab,0xb0,0x73,0xb6,0xd5,0x57,0x09,0x5a,0x7d,0xca,0xaa,0xd2,0xe9,0xba, +0xd5,0x50,0xfd,0xeb,0x73,0x2a,0xa6,0x73,0xc1,0xdf,0x55,0x5f,0x4a,0x9a,0xa2,0xaa, +0xce,0xe2,0x39,0x2a,0x55,0xb5,0xbe,0x12,0x4a,0xab,0xae,0x82,0xcd,0x35,0x56,0xe2, +0x75,0xca,0x4a,0xaa,0x76,0xc7,0xb3,0x55,0x51,0x04,0x5f,0x5f,0xaa,0xa7,0xc9,0x37, +0x3b,0x55,0x61,0x28,0x7f,0x6a,0xaa,0xd0,0x0a,0x72,0xe1,0x55, +0x9c,0x31,0x27,0xaa,0xb1,0x10,0x00,0x00,0xb9,0x7b,0x02,0x0a,0xab,0xad,0x2c,0xac, +0xf5,0x56,0xb3,0x7a,0xb9,0x6a,0xaa,0x25,0xed,0x11,0x55,0x51,0x44,0x30,0x5f,0xaa, +0xa8,0xc4,0xc8,0x44,0x55,0x61,0x6e,0x72,0x98,0xaa,0xd0,0x6f,0x85,0x71,0x55,0xbd, +0x1d,0x6b,0x4c,0xab,0xa8,0xf5,0x8f,0x75,0x56,0x93,0x31,0xde,0x8a,0xaa,0x04,0x91, +0xfc,0x55,0x51,0x95,0x14,0xb5,0x22,0xa9,0xa5,0xd3,0xe4,0x55,0x62,0x0a,0x0e,0xb8, +0xaa,0xd0,0x86,0xf7,0x39,0x55,0x9c,0x31,0x27,0xb2,0xb1,0x00,0x00,0x00,0xbd,0xf5, +0x9a,0x36,0xdb,0xa1,0xe6,0x14,0x6a,0x36,0x69,0x64,0x3c,0xdb,0x69,0xcf,0xcb,0x35, +0x36,0xd1,0xf1,0x23,0x2a,0x6d,0xaa,0xf4,0x4f,0xe6,0xdb,0x63,0x25,0x2e,0x8d,0xa6, +0xd1,0x14,0xc8,0xeb,0x6d,0xbf,0x72,0x3e,0x38,0xdb,0x96,0xe5,0x95,0x4d,0xb6,0x35, +0x04,0xfc,0xdb,0x69,0xa2,0xf5,0xda,0x36,0xd2,0x79,0x98,0xe2,0x4d,0xac,0x27,0xc8, +0x56,0xdb,0x63,0x83,0x3a,0x71,0xc6,0xd1,0x29,0x25,0x1b,0x4d, +0x9c,0x31,0x27,0xaa,0xb1,0x10,0x00,0x00,0xc1,0x59,0xba,0xa2,0xab,0x8f,0x0b,0x15, +0xc5,0x56,0x0a,0x52,0x9c,0xaa,0xa9,0x81,0x49,0xb8,0x55,0x52,0xe9,0xa5,0xaf,0x2a, +0xad,0x22,0xa6,0x5f,0x55,0x63,0xf4,0x3e,0x98,0xaa,0xd1,0xda,0x49,0x55,0x55,0xc3, +0x2e,0x7f,0x42,0xab,0x82,0x52,0xb5,0x15,0x55,0xdd,0x67,0xba,0x2a,0xa9,0x6f,0xe9, +0x52,0xd5,0x53,0x6e,0xa3,0x63,0x2a,0xad,0xfa,0xaf,0x45,0x55,0x64,0x5d,0x73,0x7c, +0xca,0xd2,0x80,0xc0,0xfd,0x55,0x9c,0x31,0x27,0xb2,0xb1,0x00,0x00,0x00,0xc2,0x89, +0xf9,0xb6,0xdb,0x75,0x71,0xcc,0x69,0xb5,0xbf,0x98,0x28,0xdb,0x69,0x6d,0x0d,0x8d, +0x36,0xd3,0xc9,0x2a,0xe2,0x4d,0xae,0x73,0x8c,0x46,0xdb,0x64,0xad,0x3f,0x71,0xa6, +0xd4,0x34,0x7a,0xe3,0x8d,0xc5,0x46,0x19,0xb8,0xdb,0x6b,0x23,0xac,0x4d,0xb5,0x97, +0xa3,0xc8,0xdb,0x69,0x4a,0x65,0xd1,0xb6,0xd4,0x15,0xd3,0xa3,0x6d,0xaf,0x4e,0xae, +0x44,0xdb,0x65,0xb3,0x13,0x8d,0xa6,0xd5,0x72,0x83,0x2c,0x6d, +0x9c,0x31,0x27,0x2f,0xb0,0x00,0x00,0x00,0xc5,0x50,0x16,0xed,0xb7,0x5e,0x00,0xe9, +0x1b,0x6d,0x72,0xf8,0x54,0x26,0xd9,0x3f,0x17,0xb7,0x6d,0xb4,0x79,0x6f,0x6e,0xdb, +0x6f,0xee,0x4e,0x5d,0xb6,0xe6,0x33,0x33,0xc3,0x6d,0xd6,0xf4,0xaa,0x88,0x9b,0xc5, +0xbb,0x74,0xc9,0xb7,0x50,0x11,0xe2,0x1b,0x6d,0x52,0x48,0xac,0x36,0xd9,0x41,0xbb, +0x74,0x4d,0xb4,0xdb,0x0e,0xed,0x23,0x70,0x6c,0x6d,0x21,0x26,0xe6,0x96,0x8b,0x44, +0x6d,0xd8,0x1e,0x65,0x88,0xdb,0x9c,0x31,0x27,0xb2,0xb1,0x00,0x00,0x00,0xc5,0xa6, +0x05,0x26,0xdb,0x42,0xe3,0x84,0x4d,0xb5,0x34,0xa5,0x1a,0xdc,0x69,0x41,0x4d,0x51, +0xa6,0xd5,0x28,0xd3,0x9b,0x6d,0xb0,0xe8,0x27,0xb6,0xdb,0x67,0x61,0x3f,0x8e,0x26, +0xd9,0xf8,0xcc,0xe3,0x6d,0xc4,0x51,0x8a,0x36,0xdb,0x32,0xe9,0xd4,0x4e,0x35,0x1a, +0xd5,0xd8,0xdb,0x69,0x4c,0xaf,0x51,0xb6,0xd5,0x7d,0xe4,0x1b,0x6d,0xb1,0x4c,0x20, +0x27,0x1b,0x67,0xeb,0x67,0x8e,0x26,0xdb,0x47,0x0e,0xe4,0x8d, +0x9c,0x31,0x27,0xb2,0xb1,0x00,0x00,0x00,0xc2,0x76,0xc2,0x36,0x9b,0x22,0xfb,0xdd, +0x6d,0xb5,0x05,0x58,0xa8,0x9c,0x69,0x64,0xee,0xad,0xa6,0xd5,0xe1,0xed,0x23,0x6d, +0xb1,0xa2,0xb4,0x24,0xdb,0x68,0x23,0x6c,0x6a,0x36,0xdc,0x2c,0xf0,0xdc,0x4d,0xc0, +0x41,0xbe,0x37,0x1b,0x12,0x23,0x05,0x4d,0xb4,0xf0,0xd6,0x76,0x9c,0x69,0x8c,0x6f, +0x6d,0xb4,0xd6,0x4f,0xd7,0x1b,0x51,0xb1,0xc9,0x9c,0xa6,0xd3,0x68,0x79,0x5e,0x71, +0xb6,0xdd,0xcc,0xf2,0x9b,0x6d,0x9c,0x31,0x27,0x2f,0xb0,0x00,0x00,0x00,0xbd,0x10, +0xb2,0xc9,0xb6,0xfd,0x4c,0x6a,0x5b,0x6c,0xdc,0x49,0x2c,0x39,0x19,0xb3,0xe9,0x97, +0x6d,0xb6,0xb3,0x6a,0xce,0xdb,0x72,0x37,0x59,0x9d,0xc6,0xe9,0x6e,0xa3,0x4b,0x4d, +0xde,0x90,0xb9,0x96,0xdb,0xb6,0x6f,0xd2,0xed,0xb6,0xe8,0xde,0xb1,0x5b,0x6c,0xd0, +0xbe,0x3b,0xa6,0xd9,0xe5,0x4b,0x97,0x6d,0xb7,0x1f,0xae,0xec,0xdb,0x72,0x90,0x19, +0x9d,0xb6,0xe9,0xb6,0xdc,0x4c,0x4d,0xde,0x18,0x79,0x64,0xdb, +0x9c,0x31,0x27,0x2f,0xb0,0x00,0x00,0x00,0xb0,0x86,0xce,0xee,0x36,0xdb,0x54,0x9d, +0x5a,0x6c,0xd0,0xf3,0x1a,0xb8,0xda,0x15,0x76,0x58,0x4d,0xb7,0x64,0xc8,0x50,0xdb, +0x72,0x99,0x04,0xa1,0xb6,0xe9,0xb8,0x03,0x3c,0x6d,0xde,0x3c,0xb3,0x74,0xdb,0xab, +0xd6,0xa8,0xea,0x36,0xcc,0x91,0x52,0x13,0x6c,0xcc,0x91,0xa4,0x36,0xda,0x49,0xfa, +0x76,0x4d,0xb7,0xc8,0xb2,0x8e,0xd3,0x72,0xdd,0x19,0xa5,0xb6,0xe9,0xfd,0x4b,0xcc, +0x4d,0xdd,0xd6,0x75,0x77,0x1b,0x9c,0x31,0x27,0x2f,0xb0,0x00,0x00,0x00,0xa5,0x9b, +0x11,0x09,0xb6,0xbe,0x4a,0x99,0x93,0x6c,0xcc,0x16,0x4b,0xa8,0xda,0x72,0x35,0x65, +0x6d,0xb8,0x06,0xcc,0xf0,0xd3,0x73,0x36,0x89,0x61,0xc6,0xea,0xa6,0x2c,0x5b,0x6d, +0xdd,0x2e,0x65,0x88,0xdb,0x9f,0xb4,0xf2,0xf2,0x36,0xb3,0xa8,0x61,0xdb,0x6c,0xce, +0xaa,0xbc,0x26,0xda,0x9e,0xb7,0x49,0x49,0xb8,0x43,0x44,0xb3,0x1b,0x73,0x27,0x0c, +0xde,0x26,0xea,0x6d,0xa9,0xbb,0x6d,0xdc,0x8f,0x52,0x94,0xdb, +0x9c,0x31,0x27,0x2f,0xb0,0x00,0x00,0x00,0x9b,0x6d,0x4b,0x32,0x36,0xab,0x94,0x99, +0xa2,0x6c,0xd7,0x8c,0xac,0x48,0xda,0xd1,0x26,0x57,0x4d,0xb8,0x7d,0xb0,0x90,0xdb, +0x73,0x35,0x95,0x61,0xb6,0xea,0x90,0x52,0x43,0x6d,0xdb,0xa7,0xa5,0x44,0xdb,0x93, +0xb0,0xce,0xce,0x36,0x9e,0x2d,0xd1,0x9b,0x6c,0xe2,0x1b,0x42,0xc6,0xdb,0x0c,0x2b, +0x84,0x91,0xb8,0xb9,0xc7,0x12,0xd3,0x73,0x56,0x0d,0x69,0xb6,0xea,0xe2,0x9a,0x43, +0x6d,0xda,0xd5,0x86,0x77,0x1b,0x9c,0x31,0x27,0x2f,0xb0,0x00,0x00,0x00,0x8d,0x72, +0x8e,0xc9,0xb6,0x95,0x40,0x1d,0xd3,0x6c,0xed,0x14,0x43,0x36,0xdb,0x35,0xf2,0x77, +0x6d,0xb8,0xc3,0x66,0x8c,0xdb,0x73,0x1f,0x84,0x62,0x36,0xeb,0x22,0xb1,0xbb,0x4d, +0xdb,0x04,0x75,0x88,0xdb,0x88,0xbe,0x2c,0xee,0x36,0x8f,0x06,0x56,0x1a,0x6c,0xfb, +0xba,0x1b,0x36,0xdb,0x57,0xfa,0x67,0x71,0xb8,0xc9,0x84,0xb0,0xdb,0x73,0x3e,0x5d, +0x62,0x26,0xeb,0xc1,0x33,0xb3,0x6d,0xd9,0xd2,0xd5,0x56,0xdb, +0x9c,0x31,0x27,0xb2,0xb1,0x00,0x00,0x00,0x81,0x19,0xb5,0xb6,0xda,0x86,0xc4,0xf2, +0x71,0xb5,0x0a,0x69,0x94,0x93,0x6b,0x80,0xaf,0xe9,0xb6,0xd8,0xeb,0x1a,0x1b,0x6d, +0xb3,0x92,0x3c,0x38,0xdb,0x6c,0x6e,0x5a,0x6d,0xc6,0xd8,0x10,0xd2,0xd2,0x4d,0x79, +0x11,0x65,0x36,0xda,0x7f,0x0a,0xc2,0x69,0xb5,0x16,0x55,0x66,0xa4,0x6b,0xa5,0x2f, +0x49,0xb4,0xd9,0x0d,0x8e,0xcb,0x71,0xb3,0xbe,0x2c,0x17,0x13,0x6c,0xd4,0x8e,0x31, +0xc6,0xd6,0x8c,0xb8,0x94,0x4d,0x9c,0x31,0x27,0x2f,0xb0,0x00,0x00,0x00,0x71,0xb2, +0xc8,0xaa,0x36,0x7a,0x74,0x8a,0x1c,0x6d,0x2d,0xbe,0xa4,0x36,0xdb,0xcb,0x60,0x34, +0x6d,0xb9,0x0d,0x30,0x8d,0x1b,0x73,0xc5,0x5d,0x65,0xa6,0xec,0xc6,0x72,0x4b,0x6d, +0xd4,0x06,0x96,0x65,0x1b,0x6b,0xd9,0x6e,0xed,0xb6,0x7c,0xb2,0x95,0xdb,0x6d,0x47, +0xef,0x34,0x36,0xdb,0xee,0x95,0x68,0x91,0xb9,0x1d,0xcc,0x8d,0x1b,0x73,0xe2,0x99, +0x5a,0x26,0xec,0x92,0xd3,0x3b,0x6d,0xd1,0x3a,0x56,0x76,0xdb, +0x9c,0x31,0x27,0x2f,0xb0,0x00,0x00,0x00,0x65,0x1e,0xce,0xc9,0xb6,0x7b,0xca,0x5d, +0x5c,0x6d,0x5c,0xd5,0xb4,0x36,0xdc,0x14,0x84,0x49,0x4d,0xb9,0x3c,0x6c,0x72,0xd3, +0x74,0x17,0x5c,0x9e,0x36,0xec,0x6c,0x42,0xb4,0x8d,0xcd,0xff,0x84,0x86,0xdb,0x5e, +0x88,0x4a,0xc9,0xb6,0x7e,0xcf,0x99,0xa4,0x6d,0x75,0xc3,0x2b,0xa6,0xdc,0x2c,0x8b, +0x27,0x6d,0xb9,0x45,0xc2,0x6c,0xdb,0x74,0x2b,0x35,0x25,0xb6,0xeb,0xc9,0x3c,0x42, +0x6d,0xca,0xcc,0xc8,0x56,0xdb,0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x35,0x86, +0x0f,0x11,0xb6,0x0a,0xcb,0x55,0xdb,0x6d,0x1e,0x0c,0xc3,0xb6,0xdc,0x8f,0x69,0x57, +0x91,0xba,0x90,0x08,0xb0,0xdb,0x78,0x3e,0x61,0x19,0x26,0xf6,0x8b,0xe2,0xbb,0x8d, +0xcf,0xfd,0x77,0x84,0x9b,0x2d,0x78,0xce,0xad,0xb6,0x13,0xda,0x51,0x1b,0x6d,0x4a, +0xc6,0x2c,0xb6,0xdc,0xca,0x89,0x58,0x6d,0xba,0xbf,0x6c,0x90,0xdb,0x78,0x4b,0x65, +0xde,0xb6,0xf5,0x2c,0x62,0x3b,0x6d,0xca,0x0e,0x95,0x74,0xdb, +0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x25,0x14,0xe8,0xa9,0xb6,0x1c,0xc6,0xd9, +0xdb,0x6d,0x71,0xa5,0x34,0x46,0xdc,0xda,0x56,0x68,0x8d,0xba,0x9a,0xb4,0x6f,0x1b, +0x78,0x84,0x59,0x9d,0xb6,0xf5,0x2c,0x72,0xb3,0x6d,0xc6,0x40,0x77,0x56,0xdb,0x20, +0xcd,0x2c,0xce,0x36,0x2e,0x06,0x25,0xdb,0x6d,0x9b,0x5e,0x34,0x44,0xdc,0xd5,0xf4, +0x56,0x71,0xba,0x4a,0x6c,0x90,0xdb,0x78,0x78,0x9c,0xdd,0xa6,0xf4,0xa1,0xdb,0xbb, +0x6d,0xc2,0x27,0xc6,0x69,0x1b,0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x1d,0x5d, +0x2e,0xed,0xb6,0x3d,0x4e,0x95,0x5b,0x6d,0xbd,0x0e,0x2c,0x46,0xdc,0xd7,0xca,0x56, +0x6d,0xba,0x2f,0x6c,0xd3,0x1b,0x78,0xb4,0xa9,0x9d,0xb6,0xf3,0xca,0x64,0xb3,0x4d, +0xbc,0x5b,0x77,0x47,0x1b,0x18,0x3f,0x4e,0x8d,0xb6,0x4e,0x6e,0x55,0x9b,0x6d,0xdf, +0x63,0xb4,0x46,0xdc,0xe4,0x48,0x65,0x8d,0xba,0x5e,0xea,0xcf,0x1b,0x79,0x4f,0x71, +0xe1,0xa6,0xf2,0x56,0xcb,0x33,0x6d,0xb4,0x82,0x86,0x66,0xdb, +0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x12,0x5c,0xca,0xcd,0xb6,0x63,0x3f,0x5d, +0x9b,0x6e,0x09,0x73,0xb4,0xb6,0xdc,0xf4,0xa9,0x66,0x8d,0xba,0x80,0x50,0xd1,0x1b, +0x79,0x57,0x69,0xdd,0xb6,0xef,0xbd,0xdb,0xac,0x8d,0xae,0x3e,0x78,0x88,0xdb,0x13, +0x9d,0x2e,0xa9,0xb6,0x79,0x19,0xdd,0x13,0x6e,0x1e,0xc3,0xb3,0x36,0xdc,0xf1,0x9a, +0x68,0x8d,0xba,0xb0,0x4e,0xf2,0xdb,0x79,0x9a,0x61,0xd9,0xb6,0xed,0x84,0x4b,0xab, +0x6d,0xa8,0x12,0xc8,0x65,0x1b,0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x12,0x72, +0xec,0xcd,0xb6,0x89,0xdd,0xe1,0xda,0x6e,0x3a,0x1c,0xc3,0xa8,0xdd,0x0b,0xa6,0x77, +0x6d,0xba,0xfa,0x30,0xf0,0xdb,0x79,0xce,0xdd,0xe5,0xb6,0xeb,0x15,0x3b,0x2b,0x8d, +0xa1,0xac,0x87,0x56,0x9b,0x13,0x77,0x0a,0xd1,0xb6,0x9f,0xe9,0xe9,0x9b,0x6e,0x4c, +0x94,0x44,0x34,0xdd,0x05,0x66,0x78,0x6d,0xbb,0x10,0x6d,0x0e,0xdb,0x79,0x7a,0xe1, +0x99,0xb6,0xe8,0x50,0xbc,0x3b,0x6d,0x9e,0x85,0x88,0x76,0xdb, +0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x1a,0x8d,0x10,0xcd,0xb6,0xb2,0xad,0xa9, +0xdb,0x6e,0x4f,0xfb,0xac,0xb6,0xdc,0xf7,0x95,0x77,0x6d,0xcb,0x41,0x2e,0xb0,0xdb, +0x79,0xa1,0x9d,0xd9,0xb6,0xe6,0x57,0x2c,0xb3,0x6d,0x99,0xfd,0x59,0x67,0x1b,0x1c, +0x11,0x51,0x0d,0xb6,0xc2,0x7d,0x61,0x5b,0x6e,0x5e,0x7a,0xbb,0xc6,0xdd,0x00,0xe5, +0x57,0x6d,0xbb,0x80,0xb2,0xee,0xd3,0x79,0x9c,0x5d,0xa2,0x36,0xe3,0xd8,0xa3,0xbb, +0x8d,0x95,0xf0,0x77,0x74,0xdb,0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x20,0x49, +0x2e,0xed,0xb6,0xd0,0x89,0xa2,0x1b,0x6e,0x5e,0x71,0x34,0xb6,0xdd,0x03,0x87,0x57, +0x6d,0xbb,0xd5,0x72,0xce,0xdb,0x79,0x7a,0x9d,0xdd,0xc6,0xe1,0x46,0xab,0x3b,0x6d, +0x93,0xab,0x89,0x76,0xdb,0x28,0x1d,0x2b,0x09,0xb6,0xe0,0x0d,0xdd,0x9b,0x6e,0x5a, +0x29,0xb3,0xa6,0xdc,0xf2,0x07,0x47,0x6d,0xbb,0xf6,0x91,0x0c,0xe3,0x79,0x2c,0xa1, +0x59,0xa6,0xde,0x99,0x24,0x3b,0x6d,0x91,0x11,0x88,0x88,0xdb, +0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x30,0xe1,0x2e,0xee,0x36,0xf4,0xb1,0xe1, +0x9a,0x6e,0x5f,0x8a,0x34,0x46,0xdc,0xed,0xa7,0x67,0x6d,0xbc,0x0c,0xf2,0xec,0xdb, +0x78,0x6c,0x5e,0x25,0xb6,0xdb,0x64,0x2b,0xb3,0x6d,0x8f,0x39,0x88,0x77,0x1b,0x3a, +0x35,0x2d,0x2d,0x37,0x06,0x1d,0x9d,0xdb,0x6e,0x67,0x62,0x33,0xc6,0xdc,0xf7,0x56, +0x67,0x6d,0xbc,0x0a,0x0e,0xec,0x9b,0x77,0x83,0x62,0x1a,0x36,0xd9,0x25,0xa3,0xc2, +0x6d,0x8f,0xdc,0x76,0x64,0xdb,0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x44,0x73, +0x52,0xee,0x37,0x10,0x45,0x95,0xa3,0x6e,0x5a,0xb2,0x3c,0x46,0xdc,0xf5,0x75,0x56, +0x89,0xbc,0x4d,0x14,0xed,0x1b,0x77,0x14,0x1a,0x21,0xb6,0xd6,0x8d,0xa2,0xc3,0x6d, +0x8e,0xc6,0x6a,0x76,0xdb,0x4b,0x3d,0x0a,0xed,0xb7,0x17,0x29,0x5d,0xdc,0x6e,0x5c, +0xba,0x3a,0xb4,0xdd,0x21,0x05,0x59,0x91,0xbc,0x83,0xd1,0x10,0xdb,0x75,0xf5,0xd9, +0xd9,0x36,0xd3,0x9e,0x2b,0x3b,0x6d,0x8f,0x12,0x78,0x58,0xdb, +0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x53,0xd3,0x0b,0x09,0xc7,0x1d,0xd9,0x61, +0x92,0x6e,0x5a,0x92,0x2c,0x46,0xdd,0x36,0x06,0x86,0x6d,0xbc,0x96,0x31,0x0e,0xdb, +0x75,0x19,0x95,0xa5,0xb6,0xd1,0xcf,0xa3,0xc3,0x6d,0x90,0xd8,0x77,0x76,0xdb,0x5c, +0xd8,0xca,0xed,0xb7,0x24,0x19,0x9a,0x5b,0x6e,0x52,0xc1,0xc3,0xb6,0xdd,0x37,0x87, +0x6a,0x6d,0xbc,0x77,0xd0,0xec,0xd3,0x73,0xf8,0x59,0x99,0xb6,0xd0,0x54,0x3b,0xb2, +0x6d,0x93,0xdb,0xa5,0x76,0xdb,0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x65,0x38, +0xee,0xed,0xb7,0x27,0x31,0xd9,0x9b,0x6e,0x56,0x42,0x3c,0x26,0xdd,0x51,0x88,0x87, +0x6d,0xbc,0x48,0xb3,0x0e,0xdb,0x72,0xa3,0x1a,0x15,0x36,0xce,0xb2,0x33,0x43,0x6d, +0x96,0x1c,0x76,0x66,0xdb,0x6d,0x57,0x0f,0x0d,0xb7,0x2c,0xd1,0x9d,0x9b,0x6e,0x55, +0xda,0xc4,0x36,0xdd,0x60,0xf8,0x79,0x6d,0xbc,0x31,0x95,0x0f,0x1b,0x71,0x87,0xce, +0x5a,0x36,0xcd,0x58,0xd2,0x2c,0x6d,0x98,0xfe,0x88,0x67,0x1b, +0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x74,0x67,0x30,0xa9,0xb7,0x2c,0x1d,0x5d, +0xd3,0x6e,0x53,0x52,0x3b,0xb6,0xdd,0x7c,0x59,0x87,0x6d,0xbc,0x11,0xb3,0x0a,0xdb, +0x70,0x5c,0x55,0x9a,0x36,0xcc,0x50,0x2c,0x44,0x6d,0x9c,0x05,0x97,0x96,0xdb,0x79, +0xe0,0xf0,0xe9,0xb7,0x2a,0xe1,0xdd,0x9b,0x6e,0x56,0xeb,0xbc,0x46,0xdd,0x98,0x57, +0x78,0x6d,0xbb,0xe5,0xf2,0xcc,0xdb,0x6f,0x3f,0x59,0xda,0x36,0xcb,0xa7,0x43,0xbb, +0x6d,0x9f,0x71,0x98,0x76,0xdb,0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x7f,0x8c, +0xf0,0xcd,0xb7,0x2b,0x09,0x5e,0x1b,0x6e,0x5a,0x3b,0x44,0x36,0xdd,0xa5,0x49,0x87, +0x6d,0xbb,0x9d,0x0f,0x08,0x9b,0x6e,0x2e,0xd9,0x59,0x36,0xcb,0x61,0xa4,0xc4,0x6d, +0xa3,0xb5,0x97,0x88,0xdb,0x86,0x14,0xf1,0x09,0xb7,0x28,0x31,0xa1,0x93,0x6e,0x54, +0xa3,0xb4,0x36,0xdd,0xaa,0x6a,0x78,0x8d,0xbb,0x3b,0x6c,0xf0,0xdb,0x6d,0x05,0x5e, +0x1d,0xb6,0xcb,0xb8,0xcc,0x44,0x6d,0xa8,0xd4,0x88,0x66,0xdb, +0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x8b,0x52,0xae,0xe9,0x37,0x26,0x25,0x9d, +0xdb,0x6e,0x55,0xe2,0xb4,0x36,0xdd,0xab,0x3c,0x77,0x8d,0xba,0xc9,0xae,0xee,0xdb, +0x6b,0xc5,0x92,0x5d,0xb6,0xcb,0x9c,0x43,0xc3,0x6d,0xac,0xed,0xb8,0x86,0xdb,0x8f, +0xee,0xac,0xe9,0xb7,0x27,0x01,0x9e,0x5b,0x6e,0x68,0x03,0x3b,0xb8,0xdd,0xc9,0xb9, +0x87,0x8d,0xba,0x54,0x4f,0x0c,0xdb,0x6a,0x6d,0x59,0x61,0x36,0xcb,0xb8,0xd4,0x32, +0x8d,0xb0,0x69,0x99,0x76,0xdb,0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x91,0x45, +0x0e,0xed,0xb7,0x25,0xc5,0x15,0xe3,0x6e,0x76,0xcc,0xcc,0x46,0xdd,0xd0,0x27,0x88, +0x49,0xb9,0xe8,0xcd,0x0e,0xdb,0x69,0xe6,0x55,0xd5,0xb6,0xcc,0xe4,0xbb,0xbb,0x8d, +0xb3,0x43,0x87,0x76,0x9b,0x91,0x4e,0xec,0xf1,0xb7,0x23,0x89,0x59,0xdb,0x6e,0x7d, +0xa4,0xb3,0xc6,0xdd,0xc4,0x6c,0x87,0x4d,0xb9,0x69,0xad,0x0e,0xdb,0x69,0x41,0xd5, +0xdd,0xc6,0xce,0x15,0x44,0x3b,0x4d,0xb6,0xaa,0x78,0x66,0xdb, +0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x92,0x4c,0xcd,0x0d,0xb7,0x23,0xa0,0x9a, +0x1b,0x6e,0x8d,0x74,0x3b,0x36,0xdd,0xc5,0x58,0x76,0x4d,0xb8,0xed,0xb2,0xae,0xdb, +0x68,0x79,0x1a,0x22,0x46,0xce,0x7b,0xcc,0xb3,0x4d,0xb8,0x5f,0x86,0x77,0x1b,0x93, +0x5e,0xeb,0x0d,0xb7,0x29,0xfd,0xe1,0xe3,0x6e,0xa1,0x4a,0xcb,0xb6,0xdd,0xbb,0xa7, +0x87,0x89,0xb8,0x5e,0xce,0xae,0xe3,0x67,0xd2,0x15,0x99,0xa6,0xcf,0xc2,0x44,0x43, +0x6d,0xbb,0xfa,0x89,0x86,0xdb,0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x94,0x6c, +0xac,0xcd,0xb7,0x28,0x8a,0xd6,0x1b,0x4e,0xa5,0xa3,0x3c,0x36,0xdd,0x9e,0x0c,0x97, +0x6d,0xb7,0xd2,0x27,0x0e,0xdb,0x67,0x88,0x21,0xdd,0xc6,0xd1,0xde,0x44,0x3b,0x4d, +0xbf,0xce,0x66,0x76,0xdb,0x94,0x60,0xcb,0x0d,0xb7,0x25,0xa5,0x62,0x22,0x6e,0xa4, +0xe4,0x3b,0xa6,0xdd,0x77,0x89,0x57,0x6d,0xb7,0x53,0x6c,0xd0,0xdb,0x67,0x80,0xe6, +0x1d,0xb6,0xd3,0xfa,0xb4,0x32,0x6d,0xc2,0x8c,0x87,0x76,0xdb, +0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x92,0xa0,0x6d,0x0d,0xb7,0x23,0xe2,0x5e, +0x1b,0x6e,0xa9,0xa4,0x3b,0x36,0xdd,0x51,0xa5,0x78,0x71,0xb6,0xd5,0x12,0xec,0xdb, +0x67,0xb0,0x5d,0xa1,0xb6,0xd6,0x58,0x5b,0xbb,0x6d,0xc4,0xac,0x56,0x76,0xdb,0x90, +0x3a,0xac,0xed,0xb7,0x22,0x0e,0x5e,0x1a,0x6e,0xa7,0xc3,0x4c,0x36,0xdd,0x26,0x69, +0x65,0x6d,0xb6,0x7f,0x24,0xce,0xdb,0x67,0xf8,0x26,0x1d,0xb6,0xd7,0xc9,0x4c,0xbb, +0x6d,0xc5,0x85,0x67,0x78,0xdb,0x9c,0x31,0x27,0x0a,0xa0,0x00,0x00,0x00,0x8f,0x86, +0xe8,0xed,0xb7,0x26,0x79,0x99,0xda,0x6e,0xb0,0xb4,0xc3,0x48,0xdd,0x07,0xb8,0x88, +0x6d,0xb6,0x1a,0x48,0xee,0xe3,0x67,0xe2,0xe5,0x59,0xa6,0xd8,0xce,0xab,0xbb,0x8d, +0xc6,0x15,0xa8,0x74,0x9b,0x8e,0xd0,0x4f,0x11,0xb7,0x2d,0x7a,0x19,0x94,0x6e,0xbb, +0x5c,0xbb,0xb4,0xdc,0xd7,0x63,0x78,0x71,0xb5,0xaa,0xd0,0xee,0xd3,0x68,0x59,0x22, +0x19,0xb6,0xda,0x9e,0xd4,0x3b,0x6d,0xc5,0xc4,0x55,0x66,0xdb, +0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0x97,0xc1,0xd6,0x21,0xb7,0x65,0x1c,0xc3, +0x33,0x6f,0x7c,0xc7,0x98,0x76,0xdd,0x47,0x74,0xad,0x0d,0xb2,0xc1,0x09,0x9d,0x5b, +0x61,0xac,0x44,0xbb,0x36,0xd8,0x2a,0x87,0x67,0x6d,0xcd,0x12,0xb1,0x0c,0xdb,0x98, +0x3d,0xda,0x21,0x37,0x6c,0x33,0xbc,0x3c,0x6f,0x75,0x99,0x68,0x66,0xdc,0xe5,0xb1, +0x0f,0x2d,0xb2,0x32,0x5e,0x61,0x9b,0x62,0x62,0x4b,0xbb,0x36,0xda,0x60,0x76,0x79, +0x6d,0xcc,0x8a,0xed,0x2e,0xdb,0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0x97,0xa1, +0x5d,0xdd,0x37,0x7c,0xd3,0xb3,0xc4,0x6f,0x7e,0xd8,0x87,0x94,0xdc,0x80,0x28,0xcc, +0xed,0xb1,0x94,0x5d,0x9d,0x23,0x63,0x10,0x43,0x34,0xb6,0xdc,0x26,0x88,0x79,0x8d, +0xcc,0xf4,0xf0,0xaa,0xdb,0x9a,0xf9,0xd5,0xe1,0xb7,0x86,0xf5,0x3b,0x43,0x6f,0x65, +0xb6,0x76,0x76,0xdc,0x12,0x8f,0x2e,0xed,0xb1,0x63,0xdd,0x95,0x9b,0x64,0x41,0x34, +0xbb,0x36,0xde,0x0e,0x87,0x68,0x4d,0xcd,0x6e,0xaa,0xca,0xdb, +0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0x9d,0x7d,0xde,0x19,0xb7,0x8c,0x14,0xbb, +0x4b,0x6f,0x47,0xb6,0x97,0x68,0xdb,0xa8,0x74,0xb0,0xad,0xb1,0x4d,0x92,0x5d,0xe3, +0x65,0xb2,0xd3,0xbb,0xb6,0xdf,0xde,0x89,0x86,0x6d,0xcb,0xb0,0x6d,0x0c,0xdb,0x9b, +0xc6,0x1e,0x65,0xb7,0x95,0xeb,0x43,0xbb,0x6f,0x42,0xb6,0x58,0x56,0xdb,0x59,0x0b, +0x4f,0x2d,0xb1,0x14,0x9d,0xa6,0x23,0x66,0x86,0xbc,0x3b,0xb6,0xe0,0xb3,0x76,0x88, +0x6d,0xca,0xca,0xed,0x10,0xdb,0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0x9e,0xa1, +0x65,0x65,0xb7,0x9e,0xdc,0xac,0x44,0x6f,0x30,0x88,0x86,0x66,0xdb,0x0f,0x8a,0xcd, +0x0d,0xb1,0x04,0xea,0x22,0x1b,0x67,0x58,0xb3,0xa3,0xb6,0xe1,0xa6,0x67,0x87,0x6d, +0xcb,0x18,0xb0,0xd0,0xdb,0xa1,0xfd,0x91,0xe1,0xb7,0xa1,0xec,0x3a,0xb3,0x6f,0x0e, +0x17,0x76,0x66,0xda,0xaf,0x90,0xf0,0xed,0xb1,0x08,0x59,0xd5,0x9b,0x68,0xcf,0x4b, +0x3b,0x36,0xe3,0x66,0x88,0x77,0x6d,0xca,0x62,0xca,0xee,0xdb, +0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0xa2,0x4a,0x62,0x59,0xb7,0xa4,0x03,0xbb, +0x3b,0x6e,0xec,0x37,0x79,0x76,0xda,0x57,0x0c,0xec,0xed,0xb1,0x29,0x1d,0xdd,0xdb, +0x6a,0x2c,0x4b,0xbb,0xb6,0xe4,0xa7,0x66,0x77,0x6d,0xc9,0xec,0xed,0x0e,0xdb,0xa4, +0x69,0xa1,0xdd,0xb7,0xa4,0xcc,0x43,0xc3,0x6e,0xc7,0x29,0x86,0x66,0xda,0x0e,0x2f, +0x0f,0x0d,0xb1,0x6f,0x1d,0xdd,0xdb,0x6b,0x76,0xcb,0xb3,0xb6,0xe5,0x11,0x68,0x88, +0x6d,0xc8,0xae,0xce,0xce,0xdb,0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0xa8,0xbd, +0x66,0x1d,0xb7,0xaa,0x66,0x3a,0xc3,0x6e,0x9a,0x93,0x77,0x76,0xd9,0xaa,0x6c,0xae, +0xed,0xb1,0xab,0xe5,0xda,0x1b,0x6c,0xd9,0xb4,0x3b,0xb6,0xe5,0x96,0x77,0x87,0x6d, +0xc8,0x7c,0x90,0xee,0xdb,0xae,0x4a,0x5d,0xdd,0xb7,0xa8,0x4b,0x34,0xb3,0x6e,0x65, +0xc6,0x77,0x66,0xd9,0x6b,0x8a,0xca,0xed,0xb2,0x24,0x22,0x21,0x9b,0x6d,0xe1,0x33, +0xbb,0xb6,0xe5,0x80,0x67,0x67,0x6d,0xc8,0xde,0xce,0xee,0xdb, +0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0xb3,0x66,0x1e,0x1d,0xb5,0xa3,0x73,0xc3, +0xbb,0x6e,0x36,0xf6,0x77,0x76,0xd9,0x45,0xee,0xcc,0xed,0xb2,0xb5,0xe1,0xa5,0xdb, +0x6e,0xec,0x4b,0x33,0xb6,0xe5,0x25,0x48,0x77,0x6d,0xc8,0xa0,0xee,0xee,0xdb,0xb7, +0x86,0x61,0xe1,0xb7,0x9b,0x6b,0xb3,0x3b,0x6e,0x05,0x76,0x77,0x76,0xd9,0x2b,0xae, +0xf0,0xed,0xb3,0x41,0x6e,0x15,0xdb,0x6f,0xab,0xb4,0xc4,0x36,0xe5,0x26,0x77,0x76, +0x6d,0xca,0x49,0x0e,0xee,0xdb,0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0xba,0x26, +0x9a,0x19,0xb7,0x8b,0x53,0x2b,0xbb,0x6d,0xd7,0xd7,0x87,0x76,0xd9,0x2a,0xf1,0x0f, +0x0d,0xb3,0xc8,0x9e,0xa1,0xdb,0x70,0x2d,0x34,0x3b,0xb6,0xe4,0xe6,0x85,0x77,0x6d, +0xcb,0x09,0x0d,0x0e,0xdb,0xbc,0x95,0x9a,0x1d,0xb7,0x82,0xac,0xc4,0x3b,0x6d,0xb6, +0x86,0x96,0x76,0xd9,0x27,0x2c,0xee,0xed,0xb4,0x51,0xa1,0xdd,0xdb,0x70,0xcb,0x2a, +0xab,0xb6,0xe4,0x6c,0x78,0x86,0x6d,0xcb,0x66,0xad,0x10,0xdb, +0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0xbf,0x31,0x5d,0xe1,0xb7,0x75,0x8c,0x44, +0x3b,0x6d,0x89,0xb5,0x67,0x76,0xd9,0x27,0x70,0xb0,0xed,0xb4,0xdf,0x21,0xdd,0x9b, +0x71,0x49,0x44,0xc3,0x36,0xe4,0x84,0x47,0x87,0x6d,0xcd,0x8c,0xed,0x12,0xdb,0xc1, +0x82,0x22,0x21,0xb7,0x65,0xe3,0xbb,0xbb,0x6d,0x64,0x78,0x78,0x76,0xd9,0x2f,0xd2, +0xee,0xed,0xb5,0x45,0x5e,0x61,0x5b,0x71,0x70,0x34,0x3b,0x26,0xe4,0x46,0x67,0x68, +0x6d,0xcf,0x89,0x11,0x2e,0xdb,0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0xc4,0x02, +0x21,0x59,0xb7,0x58,0x9b,0xab,0x3b,0x6d,0x47,0xd7,0x77,0x78,0xd9,0x47,0x8a,0xee, +0xed,0xb5,0xb3,0x1d,0xdd,0x9b,0x71,0x9c,0xca,0xc4,0x36,0xe4,0x33,0x66,0x87,0x6d, +0xd1,0x03,0x0f,0x0e,0xdb,0xc2,0x62,0x55,0xdd,0xb7,0x43,0x93,0x43,0xb3,0x6d,0x2d, +0x85,0x68,0x86,0xd9,0x7d,0x30,0xcf,0x0d,0xb6,0x52,0x21,0x9a,0x5b,0x71,0xdd,0x34, +0x4b,0x36,0xe4,0x0f,0x78,0x87,0x6d,0xd2,0x4e,0xe9,0x2c,0x9b, +0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0xc0,0x71,0xdd,0xd1,0xb7,0x2e,0x2b,0xb3, +0x33,0x6d,0x0f,0xd6,0x88,0x76,0xd9,0xa5,0x4f,0x2b,0x0d,0xb6,0xd3,0x1e,0x21,0x5b, +0x71,0xfc,0xa4,0x4c,0x36,0xe4,0x10,0x45,0x78,0x6d,0xd4,0x6a,0xef,0x0a,0xdb,0xbf, +0xc2,0x15,0xd9,0xb7,0x1a,0x53,0x43,0x3b,0x6c,0xf5,0x88,0xa8,0x86,0xd9,0xcd,0x32, +0xae,0xa9,0xb7,0x3c,0x61,0xd9,0xe3,0x72,0x15,0xb3,0x44,0x36,0xe4,0x92,0x78,0x77, +0x6d,0xd7,0x24,0xed,0x12,0xdb,0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0xbe,0x45, +0xe2,0x1d,0xb7,0x07,0x74,0x53,0x42,0x6c,0xe2,0x58,0x58,0x56,0xd9,0xea,0xf0,0xee, +0xb1,0xb7,0x74,0x26,0x1d,0x53,0x72,0x2f,0x3c,0x4b,0x36,0xe5,0x56,0x54,0x68,0x4d, +0xd9,0x4c,0xea,0xec,0xdb,0xbc,0x3d,0xea,0x1d,0xb6,0xf7,0x3a,0xb3,0x2b,0x6c,0xd4, +0x15,0x88,0x76,0xda,0x0e,0x30,0xee,0x6d,0xb7,0x9d,0x55,0x59,0x9b,0x71,0xeb,0xba, +0x44,0xa6,0xe5,0xe3,0x85,0x66,0x8d,0xdb,0x7f,0x14,0xee,0xdb, +0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0xb8,0x45,0xe1,0xd9,0xb6,0xe7,0x93,0xb3, +0x43,0x6c,0xd7,0xc5,0x67,0x66,0xda,0x44,0x8e,0x8e,0xed,0xb7,0xbc,0xe1,0xda,0x9b, +0x71,0xb1,0x3c,0x42,0xb6,0xe6,0x68,0x79,0x86,0x6d,0xdc,0x80,0xce,0xec,0xdb,0xb2, +0x02,0x19,0xe5,0xb6,0xd5,0x83,0x3b,0xb3,0x6c,0xd9,0x48,0x87,0x68,0xda,0x84,0x53, +0x10,0xed,0xb8,0x02,0x9a,0x19,0xa3,0x71,0xbe,0xab,0x3b,0xb6,0xe6,0xe3,0x77,0x84, +0x6d,0xdc,0xc2,0xf0,0xae,0x9b,0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0xab,0x82, +0x1d,0xd6,0x36,0xc5,0x54,0xc3,0x43,0x6c,0xd9,0x08,0x76,0x84,0xda,0xb6,0x4f,0x10, +0xed,0xb8,0x43,0x5d,0x99,0x9b,0x71,0xea,0x3b,0x43,0x36,0xe7,0x86,0x67,0x78,0x6d, +0xdd,0x2d,0x0c,0xb0,0xdb,0xa5,0xc5,0xe2,0x1d,0xb6,0xb6,0xe3,0x33,0x2b,0x6c,0xd9, +0xb7,0x76,0x64,0xda,0xde,0x0e,0xd0,0xed,0xb8,0x64,0x22,0x1e,0x23,0x71,0xe6,0xbc, +0xbc,0x26,0xe8,0x14,0x75,0x75,0x6d,0xdd,0x74,0xec,0xf2,0xdb, +0x9c,0x31,0x27,0x65,0x90,0x00,0x00,0x00,0x9f,0x4d,0xa1,0x95,0xb6,0xac,0x2b,0x3c, +0x4b,0x6c,0xea,0x76,0x77,0x56,0xdb,0x13,0x2e,0xee,0xad,0xb8,0x66,0xe1,0xde,0x1b, +0x71,0xad,0xbb,0xbb,0x36,0xe8,0xa4,0x77,0x89,0x6d,0xdd,0x63,0x0e,0xca,0xdb,0x98, +0x6d,0xd9,0x99,0x36,0xa2,0x7b,0xbb,0xbb,0x6c,0xfb,0xf7,0x96,0x56,0xdb,0x4d,0x0d, +0x0e,0xed,0xb8,0x83,0x5d,0xda,0x1b,0x71,0x93,0xb2,0xb3,0xb6,0xe8,0xd3,0x77,0x77, +0x6d,0xdc,0x45,0x10,0xce,0xdb,0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0xa2,0x66, +0x1d,0xe1,0xb6,0x36,0x73,0xc3,0x33,0x6c,0x1f,0x77,0x77,0x76,0xda,0xf5,0x4f,0x0e, +0xed,0xb9,0x03,0x19,0x9e,0x5b,0x73,0x0d,0x3b,0x4b,0x36,0xf2,0xee,0x77,0x68,0x6d, +0xf6,0xd2,0xee,0xec,0xdb,0x94,0xa6,0x21,0xdd,0xb6,0x2c,0x54,0x33,0xbc,0x6c,0x44, +0x47,0x57,0x76,0xdb,0x34,0x91,0x0c,0xed,0xb9,0x0d,0x1d,0xe2,0x1b,0x73,0x6e,0x34, +0xba,0xb6,0xf4,0x2d,0x76,0x79,0x6d,0xf4,0x86,0xec,0xee,0xdb, +0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0x87,0x41,0xdd,0x95,0xb6,0x20,0x2b,0x3b, +0xbb,0x6c,0x64,0x57,0x86,0x78,0xdb,0x7b,0xae,0xce,0xe9,0xb9,0x36,0xa1,0xa1,0xdb, +0x73,0xc9,0x3b,0xbb,0x36,0xf4,0xa7,0x66,0x87,0x6d,0xef,0x9d,0x10,0xee,0xdb,0x76, +0xd1,0xda,0x1d,0xb6,0x1b,0x23,0xc3,0x43,0x6c,0x96,0xb7,0x97,0x66,0xdb,0xc5,0x90, +0xf0,0xed,0xb9,0x3b,0x59,0x9a,0x1b,0x74,0x00,0xbb,0x43,0xb6,0xf5,0x28,0x78,0x78, +0x6d,0xeb,0x22,0xf2,0xea,0x9b,0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0x69,0xf1, +0xdd,0xe2,0x36,0x1c,0x6b,0x33,0xba,0x6c,0xc4,0xc7,0x68,0x58,0xdb,0xe9,0xef,0x0f, +0x0d,0xb9,0x12,0x59,0xdd,0x9b,0x74,0x68,0x3b,0x3d,0x36,0xf6,0x2e,0x88,0x87,0x6d, +0xe7,0x5c,0xef,0x10,0xdb,0x5e,0xe5,0xe1,0xd9,0xb6,0x1f,0x9b,0xbc,0x43,0x6c,0xe8, +0x08,0x78,0x74,0xdb,0xfb,0xaf,0x2e,0xf1,0xb9,0x03,0x5d,0x9e,0x13,0x74,0xe6,0x3b, +0xbb,0x36,0xf6,0xc1,0x77,0x77,0x6d,0xe3,0x72,0xce,0xce,0xdb, +0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0x54,0xf9,0xe1,0x99,0xb6,0x20,0xab,0xbb, +0xbb,0x6d,0x08,0xe9,0x66,0x56,0xdc,0x22,0xcc,0xef,0x0d,0xb9,0x13,0x9d,0xdd,0xdb, +0x75,0x4f,0x3b,0xbb,0x36,0xf6,0xe4,0x86,0x78,0x6d,0xde,0x24,0xee,0xee,0xdb,0x49, +0x02,0x1d,0xe1,0xb6,0x25,0x8b,0xc4,0x3b,0x6d,0x37,0x39,0x57,0x86,0xdc,0x4d,0x4c, +0xae,0xf1,0xb9,0x20,0x1e,0x22,0x13,0x75,0xd6,0x33,0xba,0xb6,0xf6,0xba,0x77,0x58, +0x6d,0xd7,0xb6,0xce,0xce,0xdb,0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0x3d,0x1d, +0xda,0x1e,0x36,0x2c,0xb3,0xc3,0xbb,0x6d,0x5f,0xc8,0x87,0x76,0xdc,0x6f,0xae,0xae, +0xed,0xb9,0x42,0xdd,0xa5,0x9b,0x76,0x8b,0xbb,0xbb,0xb6,0xf6,0xb9,0x79,0x77,0x6d, +0xd1,0x77,0x11,0x0e,0xdb,0x32,0xa5,0xd6,0x1d,0xb6,0x35,0x03,0xb3,0xbb,0x6d,0x85, +0x58,0x97,0x66,0xdc,0x7c,0xcb,0x10,0xed,0xb9,0x4d,0x99,0xa1,0xdb,0x77,0x22,0x33, +0xb3,0xb6,0xf5,0xe4,0x77,0x76,0x6d,0xca,0x76,0xd0,0xf0,0xdb, +0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0x2b,0xe1,0xdd,0xdd,0xb6,0x49,0x23,0xaa, +0xc3,0x6d,0xb0,0x57,0x67,0x66,0xdc,0x80,0xef,0x0f,0x0d,0xb9,0x41,0x1d,0x9d,0xd3, +0x77,0x7b,0xc3,0xbb,0x46,0xf4,0xd6,0x77,0x78,0x6d,0xc4,0x3c,0xed,0x0e,0xdb,0x26, +0x71,0xe1,0xe1,0xb6,0x57,0xdc,0x44,0x33,0x6d,0xd1,0xd6,0x78,0x86,0xdc,0x8f,0xae, +0xd0,0xed,0xb9,0x66,0x95,0x9e,0x1b,0x77,0xe0,0xc3,0x3b,0x36,0xf3,0x5b,0x69,0x87, +0x6d,0xbd,0xfd,0x0c,0xcc,0xdb,0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0x23,0xe1, +0xd9,0xa1,0xb6,0x6a,0x53,0xc3,0x2a,0x6d,0xee,0x27,0x76,0x88,0xdc,0x94,0xf0,0xd0, +0xe9,0xb9,0x8e,0xdd,0xda,0x1b,0x78,0x3c,0x43,0xbb,0x36,0xf1,0x90,0x87,0x77,0x6d, +0xb7,0x79,0x0f,0x0c,0xdb,0x21,0xb9,0x99,0x99,0xb6,0x7f,0x4c,0x44,0x42,0x6e,0x06, +0xc6,0x78,0x86,0xdc,0x8b,0x2c,0xef,0x0d,0xb9,0xa5,0x16,0xa2,0x1b,0x78,0x96,0x3c, +0xbc,0x36,0xef,0xea,0x66,0x77,0x6d,0xb1,0xe9,0x0c,0xae,0xdb, +0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0x22,0x39,0xa1,0xd9,0xb6,0x93,0x13,0xcb, +0x3b,0x6e,0x1a,0xc5,0x66,0x68,0xdc,0x7d,0x30,0xce,0xe9,0xb9,0xc3,0x5e,0x19,0xdb, +0x78,0xc1,0x34,0x3c,0x36,0xed,0x91,0x86,0x56,0x4d,0xac,0x8c,0xee,0xaf,0x1b,0x25, +0xfa,0x21,0x9d,0xb6,0xaa,0x4a,0xbc,0xc3,0x6e,0x29,0x09,0x76,0x68,0xdc,0x74,0xd0, +0xed,0x09,0xb9,0xf0,0x59,0xa2,0x5b,0x78,0xb7,0x3b,0xc4,0xb6,0xea,0xbf,0x87,0x68, +0x6d,0xa7,0xee,0xee,0xee,0xdb,0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0x2b,0x26, +0x15,0xe1,0xb6,0xc0,0x33,0xb3,0x43,0x6e,0x37,0xd8,0x48,0x66,0xdc,0x6e,0x4b,0x32, +0xed,0xba,0x05,0x25,0xde,0x1b,0x78,0x59,0x4c,0xbb,0xb6,0xe8,0x33,0x66,0x65,0x8d, +0xa4,0xda,0xf0,0xee,0xdb,0x32,0x0a,0x25,0xdd,0xb6,0xd1,0xfc,0x3b,0x44,0x6e,0x36, +0x67,0x56,0x96,0xdc,0x63,0x2c,0xd3,0x0d,0xba,0x4d,0x22,0x22,0x1b,0x78,0x54,0xab, +0xb3,0xc6,0xe5,0xb7,0x75,0x68,0x6d,0xa2,0x74,0xd2,0xec,0xdb, +0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0x38,0xda,0x1e,0x61,0xb6,0xde,0x14,0x3b, +0xbb,0x6e,0x2e,0xf4,0x57,0xa6,0xdc,0x5e,0x2c,0xcf,0x0d,0xba,0x7a,0xa2,0x22,0x1b, +0x77,0xf4,0xcb,0x4b,0xc6,0xe3,0xab,0x87,0x89,0x6d,0xa1,0x5e,0x8d,0x0a,0xdb,0x3f, +0x75,0xd1,0x95,0xb6,0xe7,0x95,0x33,0xbc,0x6e,0x2f,0x95,0x96,0x74,0xdc,0x6a,0xad, +0x2e,0xed,0xba,0xaa,0x56,0x21,0x9b,0x77,0x7a,0xcc,0x43,0xa6,0xe1,0x1c,0x58,0x87, +0x6d,0x9f,0x7c,0xac,0xac,0x9b,0x9c,0x31,0x27,0x40,0x80,0x00,0x00,0x00,0x47,0x26, +0x5e,0x99,0xb6,0xf5,0x9b,0x3c,0x3b,0x6e,0x2e,0x25,0x68,0x86,0xdc,0x72,0xec,0xf0, +0xb1,0xba,0xd3,0xa2,0x11,0xdb,0x76,0xc9,0x5b,0xc3,0xb6,0xde,0x4a,0x48,0x86,0x4d, +0x9e,0x38,0xd2,0xca,0xdb,0x4e,0x38,0xf5,0x5d,0xb6,0xfe,0xa2,0xad,0x42,0x6e,0x2d, +0xe7,0x67,0x76,0xdc,0x7e,0xe8,0x91,0x0d,0xbb,0x00,0x2e,0x55,0xd3,0x76,0x3b,0x2d, +0x5b,0xa6,0xdc,0x3c,0x57,0x65,0xad,0x9e,0x3c,0xaf,0x4a,0x9b, +0x9c,0x31,0x27,0x58,0x80,0x10,0x00,0x00,0x54,0x7b,0x6b,0x8d,0xb7,0x05,0x6b,0x0e, +0x5b,0x6e,0x30,0xc5,0xad,0xb4,0xdc,0x9b,0x1b,0xf6,0x71,0xbb,0x12,0x38,0x01,0x1b, +0x75,0x74,0x90,0xcd,0xa6,0xda,0x7a,0x5e,0x91,0x4d,0x9e,0xf9,0xcd,0xd7,0x5b,0x5b, +0xba,0xac,0x4d,0x37,0x0c,0x6b,0x44,0xdc,0x6e,0x28,0xce,0x66,0x3a,0xdc,0x90,0xae, +0xa4,0x85,0xbb,0x1a,0x59,0x79,0x23,0x74,0xfb,0xad,0x41,0xb6,0xd9,0x87,0x15,0xaa, +0x4d,0xa1,0x59,0xc8,0x35,0x5b,0x9c,0x31,0x27,0x19,0x70,0x11,0x00,0x00,0x47,0xe4, +0xad,0x6c,0x8b,0x19,0xf1,0x5c,0xd8,0x56,0x40,0xdc,0x7c,0x29,0x2d,0x56,0xa9,0x57, +0x35,0x5e,0x37,0x71,0x94,0x88,0xb7,0xc4,0x66,0x9d,0x59,0x4f,0xa5,0xd7,0x1a,0xa2, +0x86,0x90,0x69,0x7f,0x95,0x54,0xfa,0x7b,0x9e,0xab,0x2b,0x4d,0xbd,0x15,0x56,0x52, +0xb3,0x44,0x43,0x2d,0x74,0x54,0xd6,0x25,0x5d,0xd1,0x8c,0x35,0x10,0xb5,0x42,0x9d, +0xdd,0x19,0x4c,0xe0,0xb3,0xbf,0x2a,0x89,0xf3,0x55,0x7a,0x55, +0x9c,0x31,0x27,0x9c,0x71,0x01,0x00,0x00,0x62,0x98,0x1a,0xe7,0x2b,0x2d,0xca,0x8a, +0xd5,0x86,0x47,0x19,0x22,0x3a,0x8d,0x8a,0x2e,0xb9,0x45,0x1d,0xa9,0x9b,0xb2,0x4a, +0xb3,0xda,0xcc,0xad,0x55,0x4b,0x61,0xd2,0x0a,0x22,0x8e,0x2b,0x6c,0x9a,0x45,0x6c, +0x39,0x85,0x3b,0x2b,0x2b,0x2b,0x2e,0x21,0x56,0x45,0x5a,0x6e,0x52,0xad,0xb3,0x1c, +0xd6,0xf5,0x9d,0x6b,0x84,0x49,0x51,0x32,0x10,0x56,0xad,0x8a,0x49,0x74,0xfd,0x53, +0x22,0x93,0x3a,0xaa,0xaa,0x55,0x9c,0x31,0x27,0x30,0x71,0x11,0x10,0x00,0x74,0xae, +0xee,0xa9,0x7d,0x24,0xad,0xf3,0xc2,0xd2,0x48,0xaf,0xa4,0x79,0xc5,0xc7,0xa7,0x41, +0xeb,0x1d,0x0b,0x1b,0x5e,0x49,0xd0,0x2a,0x86,0xe9,0xc7,0x08,0x55,0xe8,0x0f,0x20, +0x99,0x87,0x2e,0x1c,0xc1,0x7f,0xd8,0xd1,0xb4,0x81,0x2a,0x10,0x99,0x8c,0xb6,0x56, +0x51,0x7b,0x3e,0x05,0xd5,0x5b,0x3e,0x53,0xcc,0x65,0x23,0x83,0x58,0x8e,0xae,0xe1, +0x99,0x4d,0x89,0x72,0x0b,0x83,0x97,0x1f,0x6a,0x6f,0x2d,0x40, +0x9c,0x31,0x27,0xd5,0x75,0x33,0x12,0x00,0x83,0x3c,0x86,0x26,0x37,0x25,0x7e,0xdc, +0x08,0x6a,0x5c,0xfa,0x17,0x12,0xed,0xda,0x0c,0xad,0x42,0x3b,0xe4,0x17,0x62,0x74, +0x0d,0x87,0xcd,0x3a,0xb9,0x0a,0x0f,0x9e,0x7a,0xcf,0x24,0xdf,0xc3,0x14,0x5c,0x86, +0xbe,0x6d,0xe7,0x41,0x1f,0x7d,0x0c,0x0d,0x72,0x5e,0xfd,0xc5,0x08,0xce,0x05,0xe4, +0x12,0x9a,0x3b,0xec,0x29,0x5f,0x53,0xed,0x76,0x96,0xca,0x66,0x9a,0x77,0xd9,0x21, +0x7a,0xc4,0x9d,0x19,0x27,0x53,0x9c,0x31,0x27,0x1e,0x32,0x11,0x10,0x00,0x83,0x74, +0xc9,0x3e,0x88,0x8b,0x3e,0x2e,0x87,0x6e,0x03,0x86,0xb6,0x57,0x65,0xff,0x0c,0x8e, +0x0c,0x68,0x05,0xe9,0xd3,0x67,0x06,0x5c,0x12,0x66,0x10,0x14,0xe7,0xb6,0xd1,0x53, +0x4f,0x12,0x39,0xa0,0x3f,0x90,0x24,0x61,0xb5,0xaa,0xb4,0x38,0xc7,0x52,0xca,0x7d, +0x89,0xa6,0xe6,0xf5,0x48,0xb2,0xc6,0x7c,0x19,0x12,0x4e,0xb2,0x5a,0x8f,0x5c,0x5b, +0x78,0x47,0x22,0xa9,0x16,0xac,0x5e,0xb9,0x6f,0xd1,0x62,0xc3, +0x9c,0x31,0x27,0x50,0x20,0x11,0x11,0x00,0x6c,0xd1,0x19,0xac,0x71,0x64,0x62,0x2b, +0x81,0x25,0x9e,0xc1,0x4d,0x2a,0x33,0x05,0xa7,0x39,0xf3,0xc8,0x3c,0xfd,0x73,0x96, +0xf8,0x65,0xdb,0x3a,0x96,0x22,0x77,0x79,0x27,0x4f,0x3c,0x2a,0x82,0xf4,0xe5,0x8f, +0x2a,0xdc,0xc3,0x84,0x8f,0x9d,0x58,0x90,0xa0,0xd9,0x3f,0x79,0x66,0x5a,0x82,0x8a, +0xaa,0xfb,0x2b,0x8a,0xa6,0x44,0x27,0x5b,0x49,0xbb,0xa8,0x72,0x28,0xca,0xe8,0xef, +0xe1,0x50,0x46,0xb2,0x9f,0xb1,0x9c,0x31,0x27,0x3f,0x20,0x00,0x00,0x00,0x9b,0x97, +0x31,0x32,0xef,0x41,0x5d,0xd4,0xa5,0xdd,0xd0,0xdc,0x3b,0xb3,0xbb,0x15,0x43,0x68, +0x97,0x7a,0x79,0x29,0x06,0x4e,0xf6,0x51,0xcd,0xd9,0xdd,0xab,0x4b,0x5c,0x24,0x3b, +0x53,0x08,0x86,0x76,0x77,0x9b,0x2c,0xc5,0x11,0x0e,0xb4,0x19,0xe5,0x9d,0xdd,0x9b, +0xe3,0xc3,0x2c,0x3b,0x7f,0x2c,0x8a,0x88,0x76,0xe9,0x6a,0xaf,0x10,0xf7,0x71,0x11, +0xca,0x21,0xf0,0x96,0x9b,0xba,0xb3,0xba,0xb1,0x37,0x68,0x77, +0x9c,0x31,0x27,0x3f,0x20,0x00,0x00,0x00,0x61,0x92,0xac,0xb0,0xcf,0x0e,0xe5,0x59, +0x61,0x9d,0xa2,0xa3,0x2c,0x3b,0x39,0xe3,0x83,0x75,0x86,0x74,0x9e,0x49,0x10,0x4f, +0x12,0xaa,0xb1,0x56,0x1d,0xe1,0xa1,0x2a,0x34,0x33,0x39,0x58,0x96,0x86,0x77,0x5e, +0xce,0xef,0x0e,0xef,0x68,0x91,0x99,0x1a,0x1d,0xac,0xd3,0x3e,0x34,0x3c,0x53,0x6a, +0x66,0x78,0x78,0x98,0xb3,0x12,0xee,0xf1,0xf9,0x51,0x52,0x1d,0xe9,0x0d,0x34,0xc3, +0x3b,0xc1,0x12,0xa6,0x69,0x77,0x9c,0x31,0x27,0x3f,0x20,0x00,0x00,0x00,0xa1,0xf5, +0x4f,0x0e,0xef,0x9e,0xa1,0xe5,0xa1,0xde,0x33,0xc3,0x2b,0xb3,0xbb,0x36,0x94,0x57, +0x67,0x76,0x2e,0x4b,0x2c,0xf0,0xee,0x8e,0xd6,0x61,0x99,0xe2,0x59,0x2c,0x2b,0xbb, +0xbe,0xf9,0x66,0x78,0x77,0xaf,0xca,0xca,0xf0,0xef,0x2b,0x99,0xe1,0xe1,0xde,0x98, +0xbc,0x54,0x3b,0xbb,0x6b,0x98,0x77,0x57,0x68,0x1e,0x52,0xcf,0x0e,0xf2,0xe2,0x9d, +0xdd,0x99,0xd7,0x4b,0x2a,0xc4,0xbb,0x36,0x07,0x78,0x66,0x77, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x4c,0x66,0xf9,0x42,0x0e,0xb6,0x3a,0x0f, +0x73,0x5e,0x38,0x5b,0xe9,0x27,0xb9,0x10,0xf7,0xbd,0x8f,0x77,0x4e,0x0f,0x83,0xde, +0xf3,0x83,0xdd,0x27,0x3d,0x96,0xd7,0xcd,0xee,0x7b,0xa5,0xf0,0x93,0xa1,0x07,0xa3, +0xd3,0x07,0xc9,0xcf,0x85,0x39,0xb0,0x63,0xde,0x31,0x7c,0x9f,0x17,0xbb,0x1c,0xe7, +0xbe,0x0d,0x7a,0x39,0xaf,0x6c,0x1c,0xf7,0x53,0x9c,0xe7,0xb9,0xd9,0x28,0x3d,0xf1, +0x6b,0xa9,0x4e,0x7b,0x9c,0xe7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x94,0x23, +0x07,0x42,0x0f,0x17,0x41,0xb0,0x83,0xdd,0xcf,0x7b,0xe0,0xf7,0x3c,0x1e,0xf7,0x3e, +0x0f,0x78,0x39,0xf0,0x73,0xe0,0xee,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xb5,0xcf,0x84,0x20,0xf7,0x7b,0xa0,0xe8,0x3d,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, +0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef, +0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde, +0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x7b, +0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7, +0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef, +0x7b,0xbd,0xef,0x7b,0xde,0xf7,0x9c,0x31,0x27,0x75,0x00,0x00,0x00,0x00,0x7b,0xde, +0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef,0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd, +0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde,0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b, +0xbd,0xef,0x7b,0xde,0xf7,0x7b,0xde,0xf7,0xbd,0xee,0xf7,0xbd,0xef,0x7b,0xdd,0xef, +0x7b,0xde,0xf7,0xbb,0xde,0xf7,0xbd,0xef,0x77,0xbd,0xef,0x7b,0xde,0xef,0x7b,0xde, +0xf7,0xbd,0xde,0xf7,0xbd,0xef,0x7b,0xbd,0xef,0x7b,0xde,0xf7, diff --git a/config/_default_cfg_src_/res/en/SOUND_ANSWER.txt b/config/_default_cfg_src_/res/en/SOUND_ANSWER.txt new file mode 100644 index 0000000..1ab597d --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_ANSWER.txt @@ -0,0 +1,195 @@ +0x9c,0x31,0x10,0xc8,0x54,0x44,0x00,0x00,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb, +0x8c,0x43,0x82,0xc3,0x9c,0xab,0x93,0x9c,0xa3,0xaa,0x9a,0xbb,0xb3,0xbc,0x9d,0xc3, +0x93,0x39,0xbc,0x3b,0xd1,0x2d,0xcc,0xab,0x9c,0x31,0x10,0xc0,0x97,0x75,0x10,0x00, +0x85,0xdd,0x81,0xe1,0x7d,0xdd,0x72,0x1d,0x72,0x1e,0x75,0xdd,0x7e,0x19,0x86,0x19, +0x8c,0x5a,0xde,0xc5,0x3a,0x14,0xb2,0x5d,0x51,0xa5,0x72,0xa5,0x75,0x66,0x5a,0x5c, +0x9c,0x31,0x10,0x75,0xca,0x98,0x40,0x00,0x81,0xdb,0x7d,0xdb,0x7d,0xdb,0x85,0x9b, +0x95,0x9c,0x95,0x94,0x81,0xd1,0x5d,0xd2,0x24,0xd3,0x86,0x05,0x65,0x5b,0x9e,0x6b, +0xb9,0xa3,0xb1,0xa2,0x82,0x64,0x25,0xe9,0x9c,0x31,0x10,0xe5,0xdb,0xa8,0x40,0x00, +0x63,0x2e,0x7d,0x5a,0x76,0x90,0xa1,0x95,0x96,0x5d,0x9d,0x9d,0x7a,0x61,0x41,0xa9, +0x73,0x64,0x71,0x16,0x83,0x19,0xa9,0x58,0x92,0x95,0x9d,0x5d,0x69,0xdd,0x39,0x22, +0x9c,0x31,0x10,0x78,0xda,0xa8,0x40,0x00,0x77,0x8c,0x69,0x0d,0x97,0x59,0xa4,0x9d, +0x9a,0x21,0x92,0x25,0x59,0xa2,0x38,0x9d,0x7d,0x95,0x6d,0x9c,0xaa,0x1d,0xa5,0xe2, +0x99,0xde,0x8a,0x5d,0x42,0x1c,0x4a,0x5c,0x9c,0x31,0x10,0xe5,0xdb,0xa8,0x40,0x00, +0x80,0xe9,0x72,0x25,0xb5,0x61,0xa1,0xd9,0x9d,0xdd,0x75,0xdd,0x31,0xd9,0x63,0x21, +0x75,0x21,0x8a,0x9d,0xb9,0x5d,0x9e,0x20,0x99,0xd9,0x59,0xdd,0x2d,0x1e,0x72,0x4c, +0x9c,0x31,0x10,0xcd,0xdb,0x98,0x40,0x00,0x71,0x82,0xa6,0x54,0xb1,0x92,0xa2,0x14, +0x89,0xab,0x3e,0x1c,0x3d,0xd1,0x79,0x29,0x76,0x2c,0xbd,0xa3,0xa9,0xe3,0x9d,0xdd, +0x6d,0x9b,0x31,0xe1,0x57,0x73,0x75,0x5c,0x9c,0x31,0x10,0x53,0xda,0xa8,0x30,0x00, +0x97,0x19,0xbc,0xd9,0xa6,0x96,0x91,0xdd,0x4d,0xd9,0x30,0x15,0x6d,0x8d,0x75,0x59, +0xb6,0x5c,0xb1,0x22,0xa2,0x22,0x71,0x1d,0x39,0xe0,0x47,0xad,0x74,0x65,0x8a,0xa5, +0x9c,0x31,0x10,0xcd,0xdb,0x98,0x40,0x00,0xbd,0x73,0xaa,0x6d,0x95,0xe3,0x56,0x61, +0x2c,0xca,0x66,0x43,0x71,0xc4,0xb2,0x03,0xb5,0x8d,0xa5,0xca,0x75,0x89,0x39,0x9b, +0x42,0xec,0x70,0xec,0x8e,0x6a,0xc1,0x6a,0x9c,0x31,0x10,0x4b,0xdb,0x97,0x40,0x00, +0xb1,0x32,0x90,0xd5,0x57,0x31,0x2e,0x88,0x68,0xe6,0x77,0x06,0xb5,0x00,0xb8,0xe5, +0xa4,0xc6,0x70,0xe9,0x38,0xad,0x4b,0x8c,0x70,0xcd,0x99,0x31,0xbe,0xb1,0xb1,0x11, +0x9c,0x31,0x10,0x61,0xdb,0x88,0x50,0x00,0x85,0x63,0x52,0x54,0x35,0x84,0x68,0x91, +0x7d,0xca,0xb9,0x8c,0xb6,0x4b,0x99,0x52,0x62,0x12,0x30,0xcb,0x5a,0x43,0x72,0x0c, +0xaa,0x4b,0xb9,0x93,0xa6,0x53,0x76,0x1c,0x9c,0x31,0x10,0x79,0xdb,0x98,0x50,0x00, +0x41,0x63,0x46,0xe9,0x69,0x21,0x91,0xe3,0xbd,0x64,0xb2,0x24,0x85,0x9b,0x51,0x9b, +0x35,0xdc,0x64,0x9b,0x81,0x93,0xb9,0xd3,0xba,0x13,0x95,0x93,0x62,0x53,0x31,0x4a, +0x9c,0x31,0x10,0xce,0xda,0x87,0x40,0x00,0x59,0x24,0x75,0x6a,0xad,0x8e,0xc2,0xf2, +0xa2,0xd1,0x73,0x70,0x38,0x35,0x49,0x92,0x6e,0xd1,0x9f,0x0d,0xc4,0x91,0xaf,0x2d, +0x81,0x2d,0x44,0x31,0x3d,0xd1,0x66,0x71,0x9c,0x31,0x10,0xe2,0xda,0x76,0x30,0x00, +0x8e,0xd9,0xc0,0xb5,0xb7,0x55,0x8c,0xd5,0x54,0x84,0x37,0x45,0x5e,0x42,0x81,0x26, +0xbb,0x54,0xbd,0x24,0x96,0x75,0x63,0x55,0x32,0xe2,0x56,0x85,0x79,0x45,0xb1,0x45, +0x9c,0x31,0x10,0xc2,0xda,0x65,0x20,0x00,0xc0,0x5a,0xa1,0x53,0x71,0xe4,0x38,0x31, +0x4e,0x79,0x6c,0xaa,0xa6,0x7a,0xc0,0x4b,0xaa,0x94,0x7e,0xbc,0x42,0x25,0x45,0xdd, +0x67,0x54,0x96,0x63,0xbe,0x6b,0xb0,0xbb,0x9c,0x31,0x10,0x38,0xda,0x64,0x00,0x00, +0x87,0x63,0x52,0x54,0x3c,0xdd,0x62,0x14,0x89,0x8c,0xbb,0x9b,0xb6,0x83,0x91,0x53, +0x5e,0x83,0x39,0x84,0x5c,0x4b,0x7c,0xab,0xb6,0x73,0xb9,0x73,0x9a,0x52,0x6c,0xaa, +0x9c,0x31,0x10,0x94,0xd9,0x53,0x10,0x00,0x3a,0x30,0x58,0x91,0x70,0x9a,0xae,0x7a, +0xb9,0x6a,0xa0,0x41,0x76,0xe9,0x3f,0x08,0x50,0xf1,0x6b,0x43,0xa3,0xa3,0xbc,0x32, +0xa6,0x9b,0x7e,0xb4,0x4a,0x34,0x48,0xf3,0x9c,0x31,0x10,0x05,0xc9,0x53,0x00,0x00, +0x53,0x1b,0xaa,0xa3,0xf9,0x34,0xd3,0xc4,0x90,0x8d,0x22,0x3e,0x0e,0xd5,0x47,0x23, +0x98,0x9a,0xf6,0x64,0xd9,0xa5,0x9c,0x7c,0x30,0x44,0x07,0xc5,0x46,0x3c,0x85,0x92, +0x9c,0x31,0x10,0x0f,0xc8,0x42,0x00,0x00,0xef,0x64,0xdc,0xae,0xa8,0x5e,0x43,0x5b, +0x07,0xad,0x3f,0x35,0x78,0x7b,0xe3,0xa1,0xe3,0x73,0xa9,0x6d,0x54,0x5e,0x08,0xac, +0x3c,0x4a,0x74,0x72,0xd9,0xb1,0xe7,0x6d,0x9c,0x31,0x10,0x7f,0xc7,0x52,0x00,0x00, +0xb0,0xb4,0x5d,0x94,0x0f,0xe3,0x37,0x0b,0x6e,0x43,0xd0,0xe9,0xe3,0x2b,0xb0,0x35, +0x64,0x1d,0x18,0xda,0x38,0x99,0x6c,0xb2,0xc7,0x6b,0xdd,0xab,0xae,0xb3,0x68,0x24, +0x9c,0x31,0x10,0x98,0xc8,0x53,0x00,0x00,0x20,0x8b,0x3a,0x5b,0x6b,0x73,0xc0,0xab, +0xd6,0x63,0xad,0x7b,0x6c,0x3d,0x28,0xad,0x3f,0x63,0x6a,0x7a,0xba,0x9a,0xcf,0x6c, +0xab,0xa5,0x6e,0x45,0x30,0x9c,0x43,0x5b,0x9c,0x31,0x10,0x2a,0xc7,0x34,0x00,0x00, +0x6b,0x71,0xb7,0xa1,0xc8,0x55,0xa8,0xa9,0x6f,0x39,0x36,0xa9,0x43,0x39,0x6c,0x71, +0xb4,0xa1,0xc3,0x55,0xa8,0x86,0x73,0x34,0x3c,0xb8,0x46,0x35,0x6c,0x75,0xad,0xa5, +0x9c,0x31,0x10,0x2d,0xb7,0x44,0x10,0x00,0xfc,0xec,0xd0,0xf9,0x6e,0x92,0x09,0x05, +0x12,0xc5,0x56,0xe9,0xcf,0x12,0xee,0xc4,0xcd,0x51,0x72,0x71,0x10,0xe5,0x17,0x2c, +0x54,0xed,0xc4,0xf1,0xe8,0xf5,0xcd,0x3a,0x9c,0x31,0x10,0x2d,0xb7,0x44,0x10,0x00, +0x7e,0x45,0x1f,0x09,0x1b,0x45,0x50,0xad,0xb4,0xf5,0xe1,0x10,0xc9,0x32,0x82,0x8a, +0x31,0x09,0x23,0x0d,0x56,0x91,0xa3,0x50,0xce,0xf0,0xc1,0x30,0x8c,0x92,0x46,0xee, +0x9c,0x31,0x10,0xb0,0xb6,0x44,0x10,0x00,0x2f,0x11,0x4e,0xae,0x8f,0x4c,0xc0,0xd0, +0xc1,0x51,0x96,0x2d,0x61,0x11,0x3e,0xea,0x4b,0x10,0x79,0x31,0xa7,0x0d,0xb4,0xb1, +0xa2,0xad,0x7b,0x4d,0x5d,0x15,0x52,0xf1,0x9c,0x31,0x10,0x2f,0xa5,0x44,0x10,0x00, +0x54,0x62,0x96,0x94,0xc3,0x0a,0xc0,0xe4,0x96,0xf0,0x67,0x25,0x49,0x13,0x4a,0xe1, +0x6a,0xed,0x95,0x1d,0xae,0xe4,0xae,0xe8,0x93,0x2d,0x70,0x92,0x54,0xb6,0x52,0xa6, +0x9c,0x31,0x10,0x2e,0x95,0x56,0x30,0x00,0x61,0xa2,0xaa,0x25,0xd5,0xb9,0xca,0xb6, +0x8d,0xc6,0x59,0xca,0x39,0x4a,0x51,0xb4,0x7e,0x36,0x9d,0xc9,0xa6,0x49,0x96,0x34, +0x79,0xd6,0x60,0x46,0x64,0xd5,0x70,0xb6,0x9c,0x31,0x10,0x0b,0x85,0x56,0x30,0x00, +0x89,0xb9,0x97,0x39,0x92,0x39,0x85,0xca,0x89,0x46,0x81,0x23,0x72,0x28,0x5d,0x2a, +0x75,0xb7,0x92,0x36,0xb2,0x16,0xa5,0xb1,0x59,0xc7,0x35,0xbc,0x61,0xc9,0xa1,0x65, +0x9c,0x31,0x10,0x49,0x75,0x55,0x30,0x00,0xcb,0xa9,0x73,0x84,0x3b,0x40,0x4a,0x70, +0x72,0x74,0x7a,0x74,0x2e,0x59,0x2b,0x92,0x74,0x4a,0xdd,0x92,0xa2,0x66,0x6a,0x41, +0x1b,0x99,0x22,0x76,0x61,0x52,0x53,0x6e,0x9c,0x31,0x10,0xf6,0x75,0x46,0x40,0x00, +0x75,0x25,0x92,0x05,0xb3,0x85,0x71,0x6c,0x4b,0x48,0x4b,0x74,0x53,0x0c,0x52,0x6d, +0x79,0x15,0xb3,0x91,0x93,0x69,0x74,0x92,0x5a,0x96,0x32,0xaa,0x62,0xc5,0x79,0xc1, +0x9c,0x31,0x10,0xf0,0x65,0x57,0x50,0x00,0xdb,0x71,0xa1,0xcd,0xac,0x69,0x72,0x8d, +0x6b,0x6d,0x3a,0xa9,0xc3,0x8c,0xb4,0xb1,0xf4,0xb1,0xbe,0x51,0x64,0x75,0x1d,0x92, +0x02,0x8e,0x5a,0x6a,0x5c,0xc5,0xc3,0x45,0x9c,0x31,0x10,0xd6,0x66,0x67,0x40,0x00, +0xda,0x8c,0xdb,0x8c,0x94,0x34,0x84,0x6d,0x74,0x69,0xab,0x71,0x6c,0x6e,0x83,0x65, +0x2b,0x6d,0x79,0x51,0x4b,0x41,0x83,0x4d,0x63,0x75,0xab,0x91,0xbd,0x45,0x9d,0xa8, +0x9c,0x31,0x10,0x50,0x66,0x68,0x40,0x00,0x88,0xdc,0xa6,0x9c,0x99,0x69,0x78,0xa5, +0x65,0x16,0x56,0x59,0x99,0x15,0x96,0x65,0x7a,0xe9,0xb9,0x1e,0xab,0x15,0x68,0x8d, +0xa8,0xd8,0x66,0x28,0x16,0xe9,0x14,0xde,0x9c,0x31,0x10,0xed,0x78,0x78,0x60,0x00, +0x46,0x71,0x77,0x4d,0x76,0x81,0x77,0x4d,0x67,0x75,0x87,0x49,0x97,0x85,0x87,0x75, +0x67,0x75,0x97,0x4d,0x87,0x61,0x76,0x69,0xc7,0x31,0xc2,0x35,0x47,0x92,0x36,0xb6, +0x9c,0x31,0x10,0x2f,0x67,0x79,0x60,0x00,0x72,0x9e,0xa4,0xd1,0x42,0xcd,0x04,0x98, +0x54,0xa4,0x44,0xe8,0x26,0x61,0x54,0x99,0x86,0x5d,0x76,0x5d,0x78,0x5d,0x88,0xdd, +0xd6,0x61,0x78,0x99,0x16,0x59,0x98,0xd9,0x9c,0x31,0x10,0xb2,0x66,0x79,0x60,0x00, +0x6c,0x9d,0x49,0x25,0xca,0xa9,0xc7,0x62,0x87,0x59,0x28,0xc5,0x37,0x4c,0x45,0x28, +0x37,0x28,0x15,0x6d,0x97,0x1d,0xb6,0xd5,0x74,0xd9,0xd8,0xe1,0xe6,0xdd,0xe7,0x19, +0x9c,0x31,0x10,0xd1,0x65,0x69,0x50,0x00,0x72,0xa9,0x93,0x26,0x65,0x1a,0x68,0x95, +0x8c,0xcc,0x98,0x60,0xf3,0x29,0xed,0x71,0x7b,0x56,0x6d,0x56,0x8d,0x1e,0x40,0x91, +0x33,0x19,0x92,0x65,0xcd,0x65,0x73,0x6a,0x9c,0x31,0x10,0xe2,0x76,0x79,0x40,0x00, +0x77,0x0e,0x89,0x1a,0x54,0xdd,0x66,0xe1,0x84,0xe1,0x66,0x94,0x56,0x90,0x85,0x20, +0x28,0xf5,0x3a,0xdd,0x69,0x0a,0x69,0x25,0x98,0x9d,0x69,0x99,0x48,0xa1,0x97,0x55, +0x9c,0x31,0x10,0x6d,0x76,0x78,0x40,0x00,0x67,0x39,0x76,0x9a,0x59,0x62,0x86,0x51, +0x95,0x0d,0x86,0x6d,0x77,0x2d,0x78,0x51,0xa6,0xd1,0x74,0xa5,0x94,0x58,0x67,0x21, +0xb6,0xa1,0x9a,0x95,0xaa,0xe5,0xe8,0xe1,0x9c,0x31,0x10,0x4b,0xb6,0x68,0x20,0x00, +0x86,0xc3,0x82,0xb8,0x7f,0x6a,0x76,0xe7,0x71,0x52,0x75,0xeb,0x81,0x57,0x89,0x56, +0x91,0x47,0x85,0xd6,0x6d,0xc9,0x46,0x46,0x2d,0xc7,0x60,0xc7,0xc8,0xc5,0xed,0x48, +0x9c,0x31,0x10,0x7a,0xc9,0x87,0x30,0x00,0xa1,0x0d,0x7e,0xd1,0x5d,0x2d,0x3e,0xf0, +0x3f,0x56,0x90,0xd1,0xb2,0xd0,0xac,0xb2,0xb2,0xcd,0xa8,0xcd,0x76,0x8d,0x39,0x09, +0x20,0x69,0x67,0x05,0xa0,0xe9,0x9f,0x29,0x9c,0x31,0x10,0xf2,0xc9,0x77,0x30,0x00, +0x9f,0x01,0xbb,0x28,0xaf,0x02,0x77,0x30,0x3d,0x4d,0x24,0xd2,0x51,0x89,0x99,0x11, +0xa1,0x55,0x9b,0x11,0xa7,0x11,0xb6,0xd2,0x98,0xf5,0x62,0x8d,0x37,0x29,0x28,0x81, +0x9c,0x31,0x10,0x45,0xc9,0x75,0x20,0x00,0x72,0xc5,0xa2,0xc0,0x99,0x00,0x93,0x06, +0xad,0x29,0xb4,0xe9,0x8b,0x09,0x58,0xa8,0x30,0xed,0x2e,0xd2,0x82,0x72,0xa0,0x8d, +0x96,0xcc,0x94,0xd1,0xb3,0x50,0xb0,0xea,0x9c,0x31,0x10,0xc9,0xc9,0x76,0x20,0x00, +0x87,0x31,0x58,0xa9,0x2e,0xed,0x2c,0xce,0x84,0x71,0xa2,0x8c,0x96,0xcd,0x94,0xcd, +0xb5,0x55,0xb1,0x09,0x85,0x2d,0x58,0xa8,0x34,0xe9,0x28,0x86,0x7c,0x6d,0xa2,0x85, +0x9c,0x31,0x10,0x1d,0xc8,0x86,0x10,0x00,0x96,0xc9,0x94,0xed,0xb3,0xcd,0xb1,0x4d, +0x89,0x8d,0x60,0x89,0x3b,0x6a,0x22,0x25,0x6e,0xe5,0xa5,0x08,0x99,0x86,0x93,0x29, +0xaf,0x8a,0xb6,0xd1,0x8f,0x11,0x66,0x71,0x9c,0x31,0x10,0x84,0xc9,0x75,0x10,0x00, +0x45,0x50,0x26,0xd6,0x57,0xb2,0xa3,0x35,0x9d,0x31,0x8e,0xf1,0xa4,0xec,0xba,0xb1, +0x98,0xb6,0x74,0xd5,0x51,0x19,0x30,0xd4,0x3b,0x38,0x92,0x9a,0xa2,0x95,0x8e,0x91, +0x9c,0x31,0x10,0x80,0xc9,0x86,0x10,0x00,0x98,0xad,0xb8,0xe9,0xa5,0x09,0x81,0x29, +0x5c,0xc9,0x3e,0xe9,0x26,0x65,0x70,0xc4,0xa6,0xe5,0x97,0x25,0x91,0x09,0xad,0x29, +0xb4,0xad,0x8c,0xed,0x72,0xcd,0x4f,0x31,0x9c,0x31,0x10,0x30,0xc9,0x75,0x00,0x00, +0x2f,0x35,0x43,0x99,0x96,0xf9,0xa0,0xd9,0x8e,0xb5,0x9a,0x90,0xb6,0xed,0xa0,0xe5, +0x81,0x25,0x64,0xc5,0x45,0x06,0x2a,0x85,0x67,0x61,0xa3,0x40,0x97,0x65,0x91,0x2a, +0x9c,0x31,0x10,0x84,0xc9,0x75,0x10,0x00,0xa6,0xe9,0xb4,0xc5,0x92,0xc9,0x7c,0xed, +0x5e,0xc9,0x3a,0xc5,0x2e,0x64,0x82,0x60,0xa4,0xa1,0x90,0xe2,0x92,0xe1,0xad,0x05, +0xac,0xc9,0x8a,0xed,0x78,0xed,0x58,0xed,0x9c,0x31,0x10,0x5d,0xc9,0x65,0x20,0x00, +0x36,0xed,0x38,0xc9,0x8e,0x49,0xa2,0x68,0x8c,0xa9,0x92,0xca,0xad,0x05,0xa4,0xa8, +0x88,0xcd,0x7a,0xed,0x5d,0x0e,0x39,0x11,0x3c,0xd1,0x90,0x55,0xa0,0x55,0x8a,0x91, +0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00,0x92,0xac,0xaa,0xe8,0xa6,0xa9,0x8a,0xc9, +0x7e,0xc9,0x5e,0xea,0x3a,0xc9,0x3a,0x85,0x8a,0x42,0xa0,0xa1,0x8a,0xe0,0x8f,0x01, +0xa7,0x05,0xa6,0xc1,0x8c,0xe5,0x83,0x0a,0x9c,0x31,0x10,0x83,0xc9,0x84,0x10,0x00, +0x65,0x75,0x41,0x85,0x34,0x44,0x7b,0x63,0xa2,0x83,0x8f,0x93,0x8d,0x94,0xa1,0x86, +0xaa,0x87,0x93,0x97,0x86,0x98,0x6e,0x88,0x48,0x98,0x30,0x79,0x66,0xda,0xa1,0xba, +0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00,0x93,0x55,0x87,0x15,0x98,0xf4,0xad,0x35, +0x9a,0xf9,0x88,0xda,0x78,0xba,0x54,0xf9,0x34,0xf8,0x4d,0x1a,0x96,0x75,0x9a,0x75, +0x86,0x71,0x90,0x91,0xa6,0xcc,0xa2,0x84,0x9c,0x31,0x10,0xdf,0xc8,0x84,0x20,0x00, +0x8a,0x45,0x81,0x64,0x64,0x63,0x42,0x84,0x39,0x13,0x7f,0x62,0xa3,0x92,0x8c,0xc3, +0x88,0xc4,0x9d,0x95,0xa8,0xb7,0x90,0xb8,0x84,0xb9,0x77,0x99,0x54,0xaa,0x38,0x8a, +0x9c,0x31,0x10,0x1e,0xc8,0x84,0x10,0x00,0x57,0xdb,0x9b,0x5c,0x97,0x4c,0x86,0x3b, +0x92,0x3a,0xa6,0x59,0x9f,0x17,0x89,0x37,0x82,0x55,0x67,0x55,0x46,0x74,0x3c,0x24, +0x7c,0x82,0xa0,0xa2,0x8d,0xd3,0x89,0xc4,0x9c,0x31,0x10,0x42,0xc9,0x84,0x20,0x00, +0x9b,0x85,0xa6,0x97,0x93,0x89,0x86,0x8a,0x7a,0x6b,0x5b,0x8b,0x3d,0x7b,0x50,0x8b, +0x93,0x4b,0x99,0x3b,0x87,0x3a,0x8e,0x49,0xa0,0x59,0x9f,0x68,0x8b,0x76,0x87,0x86, +0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00,0x73,0x08,0x51,0x29,0x3a,0xee,0x69,0x91, +0x9d,0x70,0x91,0x71,0x85,0x51,0x91,0x12,0xa1,0x0e,0x96,0xc9,0x84,0xe9,0x84,0xc8, +0x6a,0xec,0x48,0xed,0x40,0xa9,0x7e,0xc2,0x9c,0x31,0x10,0x24,0xb8,0x84,0x20,0x00, +0xbe,0x0a,0x92,0xc9,0x86,0xc8,0xaa,0x8c,0xbe,0xd1,0xa1,0xd5,0x89,0xdd,0x85,0x9d, +0x4d,0x9d,0x0d,0xdd,0x10,0xd4,0x90,0x4d,0xb8,0x8d,0x8d,0x4d,0x89,0x91,0xad,0x95, +0x9c,0x31,0x10,0x6d,0xb8,0x74,0x10,0x00,0xc1,0x09,0xa0,0xed,0x8f,0x11,0x80,0xd1, +0x44,0xed,0x0e,0xe9,0x1c,0xa4,0x96,0x44,0xb6,0x45,0x92,0x86,0x8e,0xa5,0xae,0xae, +0xbc,0xf0,0x9b,0x11,0x8b,0x31,0x7b,0x12,0x9c,0x31,0x10,0xe2,0xb8,0x75,0x10,0x00, +0x41,0x4d,0x0d,0x09,0x29,0x05,0x9e,0x69,0xb2,0x69,0x8e,0x6d,0x8e,0x91,0xb2,0x91, +0xba,0xcd,0x97,0x09,0x8b,0x29,0x73,0x25,0x3b,0x25,0x0d,0x05,0x33,0x0a,0xa2,0x6d, +0x9c,0x31,0x10,0x6d,0xb8,0x74,0x10,0x00,0xb0,0x74,0x90,0x74,0x92,0x95,0xb4,0x91, +0xba,0x8e,0x92,0xc9,0x86,0xe5,0x6a,0xe5,0x39,0x05,0x10,0xe5,0x3b,0x09,0xa4,0x90, +0xae,0x94,0x90,0x95,0x94,0xb6,0xb6,0xd1,0x9c,0x31,0x10,0xb1,0xb7,0x74,0x00,0x00, +0xb6,0x6d,0x90,0xc4,0x83,0x01,0x69,0x01,0x39,0x26,0x11,0x05,0x3f,0x2d,0xa4,0x54, +0xb0,0x59,0x90,0x3a,0x92,0x5a,0xb2,0xb0,0xb4,0x2c,0x8e,0x89,0x82,0xa5,0x68,0xca, +0x9c,0x31,0x10,0x6d,0xb8,0x74,0x10,0x00,0x3a,0xea,0x14,0xed,0x3e,0xed,0xa0,0x94, +0xb0,0x95,0x92,0x75,0x90,0x95,0xb4,0xb1,0xb6,0x71,0x92,0xad,0x80,0xad,0x6a,0xa9, +0x3e,0xc9,0x16,0xcd,0x3a,0xed,0x9e,0x90,0x9c,0x31,0x10,0x3b,0xb7,0x73,0x00,0x00, +0xb2,0x3c,0x93,0x3c,0x90,0x4b,0xb4,0x6a,0xba,0x19,0x93,0x47,0x7f,0x57,0x6c,0x66, +0x43,0x86,0x19,0x86,0x3a,0x76,0x9c,0x19,0xb5,0x1a,0x96,0x1b,0x8f,0x2b,0xb0,0x5a, +0x9c,0x31,0x10,0xb1,0xb7,0x74,0x00,0x00,0xb6,0x71,0x8e,0xb1,0x7c,0xcd,0x6e,0xed, +0x49,0x09,0x1f,0x0a,0x39,0x29,0x98,0x70,0xb0,0x94,0x94,0x95,0x8c,0x95,0xaa,0xd5, +0xb6,0x71,0x92,0xd1,0x7c,0xd1,0x70,0xf1,0x9c,0x31,0x10,0x1d,0xb7,0x64,0x10,0x00, +0x50,0xf5,0x28,0xd5,0x34,0x8c,0x8a,0x4d,0xb0,0x51,0x9c,0x76,0x8c,0x76,0xa6,0xd2, +0xb2,0x74,0x90,0xd0,0x7a,0xd0,0x6e,0xf1,0x54,0xf2,0x2c,0xee,0x3a,0xc9,0x8c,0x68, +0x9c,0x31,0x10,0x80,0xb6,0x64,0x10,0x00,0xb2,0x11,0x9e,0x51,0x8c,0x15,0xa4,0xf9, +0xaa,0x95,0x8b,0x0d,0x72,0xe9,0x6b,0x09,0x57,0x0d,0x39,0x0d,0x48,0xac,0x8c,0x90, +0xb0,0xb9,0xa6,0xfa,0x94,0xba,0x96,0xd6,0x9c,0x31,0x10,0x37,0xa5,0x54,0x10,0x00, +0xaa,0xab,0x88,0xe9,0x66,0xe9,0x4d,0x59,0x27,0x0c,0x15,0x0d,0x49,0x1d,0xaa,0xab, +0xd4,0xf2,0xc7,0x2a,0xb9,0x22,0xb2,0xd2,0x9e,0x83,0x76,0x0b,0x44,0x2c,0x14,0x33, +0x9c,0x31,0x10,0x21,0xa5,0x63,0x00,0x00,0x06,0xe6,0x42,0xa1,0xa0,0x65,0xce,0xac, +0xd4,0xed,0xce,0xe6,0xb6,0xa2,0x8e,0x9d,0x6c,0x96,0x4c,0x91,0x22,0xd5,0x0e,0xd8, +0x3a,0x59,0x8c,0xd5,0xc0,0x96,0xcc,0x99,0x9c,0x31,0x10,0x1b,0xa4,0x52,0x00,0x00, +0xd4,0x2c,0xc1,0x52,0x97,0x90,0x73,0xae,0x57,0x89,0x2e,0xc9,0x12,0xa5,0x34,0x86, +0x7e,0xc5,0xba,0x84,0xd2,0x69,0xd6,0x64,0xc1,0x24,0x97,0x25,0x70,0x49,0x48,0x2d, +0x9c,0x31,0x10,0x20,0xa4,0x53,0x10,0x00,0x20,0x15,0x16,0x72,0x45,0x32,0x8f,0x69, +0xca,0x69,0xe4,0x68,0xdf,0x4d,0xb9,0x28,0x7b,0x25,0x3b,0x29,0x14,0x4d,0x10,0x71, +0x3d,0x2e,0x89,0x71,0xcf,0x51,0xf6,0x71,0x9c,0x31,0x10,0x9e,0xa5,0x42,0x00,0x00, +0xec,0x50,0xb3,0x75,0x60,0x34,0x20,0x75,0x0a,0x51,0x22,0x6d,0x63,0x68,0xae,0x6d, +0xe2,0x71,0xea,0x56,0xca,0x79,0x8d,0x72,0x46,0x69,0x1e,0x6d,0x1e,0x4e,0x4a,0x71, +0x9c,0x31,0x10,0x94,0xa4,0x53,0x00,0x00,0x8a,0x69,0xbf,0x6d,0xd8,0x89,0xce,0x6d, +0xa8,0xa9,0x6d,0x45,0x3b,0xc5,0x27,0x49,0x38,0xad,0x6a,0x6d,0xa0,0x6e,0xc6,0x70, +0xce,0x6d,0xb4,0x6d,0x87,0x6d,0x54,0x71,0x9c,0x31,0x10,0xf7,0xa3,0x42,0x00,0x00, +0x37,0x49,0x37,0x2d,0x58,0x2d,0x8a,0x46,0xb3,0x68,0xc7,0x6c,0xb9,0x6d,0x96,0x8d, +0x69,0x6a,0x46,0x69,0x3d,0x2d,0x50,0x8c,0x78,0x2d,0x9e,0x76,0xb7,0x56,0xb7,0x6d, +0x9c,0x31,0x10,0xd0,0x93,0x32,0x00,0x00,0xc0,0x8a,0x74,0x5a,0x30,0xdb,0x12,0x89, +0x25,0x6a,0x5c,0x9e,0x9e,0xd4,0xce,0x65,0xda,0xf1,0xc0,0xdb,0x8c,0xda,0x53,0x14, +0x33,0x23,0x34,0xeb,0x55,0x19,0x81,0x0c,0x9c,0x31,0x10,0xe4,0x82,0x31,0x00,0x00, +0xd5,0x68,0xfb,0xb2,0xe3,0xce,0xa1,0xcd,0x57,0x68,0x27,0xa8,0x23,0x69,0x43,0x85, +0x7c,0x4a,0xad,0x35,0xc8,0x08,0xbd,0x04,0x9b,0x52,0x70,0x3a,0x52,0x2d,0x44,0x51, +0x9c,0x31,0x10,0x61,0x72,0x43,0x00,0x00,0x29,0x63,0x65,0x4b,0xa2,0x2a,0xc2,0x33, +0xba,0xc3,0x98,0xb3,0x72,0x2b,0x4c,0x3b,0x3c,0xc4,0x4d,0xb2,0x6c,0xb2,0x85,0xbd, +0x95,0xca,0xa5,0xc3,0xa5,0x33,0x91,0xb4,0x9c,0x31,0x10,0x60,0x52,0x31,0x00,0x00, +0x6e,0x19,0x32,0x98,0x15,0xd2,0x25,0xe8,0x61,0xe0,0xae,0x5a,0xc5,0x55,0xbd,0xd9, +0x8d,0xe5,0x6d,0x59,0x49,0xd9,0x31,0x2d,0x4b,0x15,0x6e,0x0c,0xa6,0x24,0xc1,0xe1, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_CHARGE_FINISH.txt b/config/_default_cfg_src_/res/en/SOUND_CHARGE_FINISH.txt new file mode 100644 index 0000000..abed867 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_CHARGE_FINISH.txt @@ -0,0 +1,280 @@ +0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00,0x7d,0xdd,0x7d,0xdd,0x7d,0xdd,0x7d,0xdd, +0x85,0x99,0x90,0xcc,0xcf,0x21,0xd7,0x66,0xee,0x16,0xcf,0x8d,0x79,0x16,0x6e,0x59, +0x76,0xa9,0x71,0x14,0x3d,0x99,0x43,0x1d,0x9c,0x31,0x10,0x71,0x53,0x32,0x00,0x00, +0x7d,0x13,0x8a,0x23,0x79,0xe2,0x75,0xeb,0x89,0x5b,0x9a,0x1c,0x81,0x5a,0x72,0x8b, +0x31,0x5a,0x4e,0x63,0x7e,0x1b,0x75,0x52,0x8e,0x9b,0x7d,0x12,0x80,0x0e,0x5d,0x65, +0x9c,0x31,0x10,0xd9,0x63,0x43,0x00,0x00,0x7e,0xc2,0x69,0x2b,0x60,0xb2,0x6e,0x2a, +0x43,0x33,0x44,0x3a,0x71,0xbb,0x7b,0x4d,0x96,0x24,0xa9,0xb2,0xa5,0x28,0xbe,0x3d, +0xc6,0x9b,0x95,0x2c,0x76,0xbb,0x7e,0x3b,0x9c,0x31,0x10,0x3a,0x65,0x44,0x00,0x00, +0x66,0x4a,0x5d,0x5b,0x71,0x9b,0x76,0x92,0x6a,0x23,0x59,0x9b,0x6e,0x64,0x65,0x9c, +0x5d,0x8b,0x69,0x92,0x3e,0xd3,0x5d,0x9b,0xa2,0x1a,0xae,0x5c,0xb6,0x51,0xc1,0xd4, +0x9c,0x31,0x10,0x22,0x65,0x54,0x00,0x00,0x99,0x25,0x71,0xa3,0x42,0x9b,0x45,0x94, +0x80,0xca,0x9a,0x12,0xba,0x9a,0x9a,0x63,0x87,0x2c,0x7a,0x23,0x82,0x1b,0x7d,0xe3, +0x6c,0xe3,0x9d,0xd2,0xc6,0x63,0xaa,0x1b,0x9c,0x31,0x10,0x55,0x55,0x44,0x00,0x00, +0xe3,0xd3,0x4b,0xa4,0x4c,0xd3,0x83,0x1b,0x92,0x9b,0x7a,0x3a,0x32,0xdb,0x95,0xc3, +0xed,0xd5,0xf3,0xa3,0xd0,0xf2,0x34,0xd2,0x45,0x1b,0x01,0x52,0x14,0x6d,0x7b,0x52, +0x9c,0x31,0x10,0xa7,0x64,0x44,0x00,0x00,0x65,0x5c,0x82,0x32,0xa1,0x6c,0x94,0xf3, +0x63,0x5b,0x3e,0x21,0x66,0x54,0xa5,0x22,0x86,0x5d,0x73,0x5a,0x46,0xa3,0x4d,0x64, +0x6a,0xd4,0x7a,0x42,0x82,0x04,0x7d,0xd9,0x9c,0x31,0x10,0x22,0x65,0x54,0x00,0x00, +0x5a,0x25,0x5d,0xd1,0x8a,0x1d,0x9d,0xa3,0xb5,0x6d,0xaa,0x28,0xc7,0x1b,0xd5,0x5a, +0xa9,0xdb,0xc9,0x85,0xf1,0x94,0xce,0xe2,0xc6,0x63,0xbe,0x64,0xae,0x2a,0x9e,0x1b, +0x9c,0x31,0x10,0x22,0x65,0x54,0x00,0x00,0x81,0x84,0xaa,0x02,0x9a,0x1b,0x75,0x2c, +0x7a,0x93,0x82,0x03,0x59,0xec,0x7e,0x19,0x61,0xa1,0x5a,0x5b,0x2e,0x9e,0x50,0xe3, +0x99,0xe3,0xc9,0x19,0xe0,0x4c,0xe5,0xe8,0x9c,0x31,0x10,0xbe,0x65,0x64,0x10,0x00, +0xcd,0xde,0x95,0xa2,0x66,0x41,0x5d,0xb5,0x5d,0xbc,0x5a,0x32,0xa5,0xc1,0xbd,0x45, +0xa5,0x45,0x53,0x4a,0x2e,0xc6,0x2e,0x39,0x54,0xab,0x6c,0xdc,0x62,0xc2,0x75,0x4a, +0x9c,0x31,0x10,0x31,0x65,0x65,0x10,0x00,0xde,0x33,0xc1,0x4d,0x7e,0x22,0x7a,0xab, +0x82,0xab,0x74,0x9a,0x6c,0xa3,0x4e,0x3d,0x5a,0x3b,0x56,0x2b,0x55,0x34,0x2a,0x3a, +0x52,0x42,0x42,0xb4,0x3e,0x3b,0x8d,0x33,0x9c,0x31,0x10,0x04,0x66,0x64,0x10,0x00, +0x6b,0xb3,0x7c,0x3a,0xac,0x2b,0x6d,0x1c,0x39,0xbc,0x12,0xcd,0x44,0xc2,0x4b,0x33, +0x8b,0xa9,0x9b,0xc3,0x6b,0x5c,0x4b,0xbd,0x3b,0xcd,0x4a,0xbc,0x93,0xb9,0xc4,0x53, +0x9c,0x31,0x10,0x86,0x76,0x55,0x10,0x00,0xc9,0x98,0xa1,0x5d,0xa1,0x6a,0x8d,0xcb, +0x6d,0x1d,0x6b,0x13,0x69,0xea,0x5e,0x9a,0x51,0x5a,0x81,0xa4,0x96,0x62,0x9d,0xd4, +0xcd,0x9c,0x99,0x9a,0x75,0x94,0x81,0xa2,0x9c,0x31,0x10,0xb3,0x75,0x54,0x10,0x00, +0xa0,0x55,0xb9,0x8a,0x8a,0xe0,0x52,0xd4,0x47,0x23,0x26,0xab,0x4d,0xdc,0x46,0x1d, +0x59,0x51,0x87,0x63,0x99,0xd9,0x96,0x1b,0xb2,0xda,0x99,0x93,0x89,0x1d,0x76,0x9b, +0x9c,0x31,0x10,0x2f,0x75,0x64,0x00,0x00,0x5d,0x3b,0x51,0x4b,0x30,0xba,0x56,0x2b, +0x7d,0xa3,0xa5,0x33,0xc5,0x42,0xe4,0xbc,0xa6,0x3d,0x70,0x31,0x69,0xbc,0x7d,0x42, +0x6d,0x33,0x51,0xc4,0x50,0x29,0xa8,0x96,0x9c,0x31,0x10,0x21,0x76,0x64,0x10,0x00, +0x91,0xc4,0x7c,0xc0,0x63,0x3a,0x73,0xc5,0x83,0xc2,0x83,0xb5,0x5c,0x24,0x83,0xbc, +0x9c,0x39,0x93,0x5d,0x7e,0x38,0x21,0xba,0x53,0xc2,0x5c,0xb4,0x5a,0xbb,0x64,0xb5, +0x9c,0x31,0x10,0x9b,0xa5,0x44,0x00,0x00,0x86,0xb3,0x8e,0xf2,0x86,0xe8,0x70,0x0c, +0x60,0x6b,0x60,0x4d,0x71,0x53,0x80,0xb3,0x89,0x14,0x78,0x89,0x4e,0x83,0x2c,0xdb, +0x34,0xa3,0x7f,0x63,0xe0,0x52,0xef,0x9c,0x9c,0x31,0x10,0xb8,0xc8,0x35,0x20,0x00, +0x7e,0x5b,0x5d,0xa3,0x4a,0x53,0x6b,0x9c,0xb9,0x5d,0xcc,0x93,0x98,0x61,0x50,0x89, +0x38,0x73,0x4f,0x8d,0xbb,0x7d,0xc2,0x73,0xbd,0x83,0x76,0x6a,0x62,0xb2,0x29,0x13, +0x9c,0x31,0x10,0x25,0xc9,0x35,0x20,0x00,0x5d,0xc9,0xbd,0x2b,0xcb,0xcc,0xa8,0x3d, +0x63,0xab,0x4c,0x72,0x24,0x61,0x8e,0xaa,0xc2,0x43,0xc6,0xb4,0x8b,0x4d,0x64,0xa4, +0x39,0x62,0x2f,0x94,0xb0,0x6b,0xc5,0x7c,0x9c,0x31,0x10,0xd9,0xc9,0x45,0x30,0x00, +0xbb,0x75,0x72,0x65,0x5e,0x95,0x28,0x32,0x55,0xc5,0xc5,0x25,0xbf,0xc4,0xa6,0x35, +0x65,0x95,0x5c,0x85,0x1d,0x38,0x86,0xc5,0xc5,0x26,0xbf,0xc6,0x8d,0x35,0x61,0xa4, +0x9c,0x31,0x10,0x55,0xc9,0x46,0x30,0x00,0x48,0xd3,0x28,0xec,0xaf,0x0c,0xbe,0xcb, +0xb9,0x0a,0x74,0xab,0x67,0x2b,0x2e,0x82,0x4b,0x89,0xc4,0x4a,0xbd,0x6b,0xa8,0x84, +0x67,0x0b,0x61,0x02,0x1c,0x4c,0x7f,0xad,0x9c,0x31,0x10,0xd9,0xc9,0x45,0x30,0x00, +0xc9,0x06,0xb9,0xd5,0x8f,0x25,0x64,0xb5,0x4d,0x6a,0x28,0x75,0xaf,0x84,0xbc,0x54, +0xb6,0x94,0x75,0x55,0x69,0x95,0x31,0x40,0x4c,0xb5,0xc4,0x35,0xb7,0xb6,0xa4,0x46, +0x9c,0x31,0x10,0x7e,0xc9,0x46,0x40,0x00,0x67,0x2b,0x61,0x02,0x22,0x6c,0x85,0xac, +0xc0,0x24,0xb5,0xab,0x8a,0x4a,0x69,0x4b,0x4c,0xf4,0x2a,0xca,0xad,0x29,0xba,0xaa, +0xad,0x52,0x76,0x8b,0x65,0x4c,0x38,0x83,0x9c,0x31,0x10,0xd9,0xc9,0x45,0x30,0x00, +0x50,0xb5,0xc5,0x36,0xb0,0xb6,0xa4,0x46,0x68,0x85,0x61,0x80,0x25,0x36,0x89,0xd6, +0xc3,0x15,0xb0,0xc5,0x8a,0x25,0x62,0xa4,0x4c,0x59,0x36,0x85,0xbb,0x74,0xb2,0x64, +0x9c,0x31,0x10,0x56,0xc9,0x44,0x30,0x00,0xae,0x84,0x6e,0x54,0x66,0xa5,0x32,0x22, +0x65,0xd4,0xc7,0x15,0xac,0xc5,0x9d,0x35,0x62,0x95,0x5c,0x85,0x2a,0x38,0xa0,0xc5, +0xba,0x16,0xaf,0xd6,0x7d,0x26,0x5f,0xc5,0x9c,0x31,0x10,0xac,0xc9,0x45,0x10,0x00, +0x44,0x34,0x4d,0xc5,0xc5,0x36,0xa7,0xa5,0xac,0x55,0x61,0x75,0x64,0x90,0x2c,0x25, +0x8a,0xe6,0xbe,0x05,0xab,0xe5,0x8c,0x15,0x5b,0xb4,0x4f,0x59,0x3d,0x96,0xc0,0x65, +0x9c,0x31,0x10,0x58,0xca,0x44,0x20,0x00,0xaa,0xe5,0xab,0x15,0x66,0xd5,0x61,0x30, +0x32,0x86,0x7d,0x75,0xc4,0x75,0xa7,0x75,0x94,0x95,0x59,0x34,0x54,0xea,0x36,0xf5, +0xbb,0x04,0xaa,0xc4,0xad,0x25,0x6a,0xb5,0x9c,0x31,0x10,0xd7,0xca,0x45,0x20,0x00, +0x61,0x45,0x38,0x82,0x73,0x74,0xc4,0x74,0xa5,0x65,0x9a,0xa5,0x57,0x25,0x5a,0xea, +0x32,0xd5,0xb7,0x24,0xae,0xb4,0xaf,0x45,0x70,0xa5,0x5f,0x46,0x3c,0x91,0x63,0x64, +0x9c,0x31,0x10,0x25,0xc9,0x35,0x20,0x00,0xca,0x12,0xa5,0xcc,0x9f,0x44,0x55,0x94, +0x5f,0x8c,0x32,0x41,0xab,0xca,0xb1,0x23,0xaf,0xdc,0x79,0x1c,0x5c,0xdc,0x48,0x21, +0x57,0xda,0xc5,0x2c,0xa5,0xb5,0xa7,0x5d,0x9c,0x31,0x10,0xe4,0xc9,0x35,0x10,0x00, +0x56,0x84,0x60,0x9a,0x32,0x31,0x9f,0xdb,0xb6,0x14,0xad,0xe4,0x7f,0x14,0x5a,0xd3, +0x4c,0x31,0x4b,0xbc,0xc5,0x4c,0xa6,0x94,0xaa,0x83,0x5d,0x5a,0x60,0xba,0x33,0x14, +0x9c,0x31,0x10,0xd7,0xca,0x45,0x20,0x00,0x8f,0x76,0xbc,0x75,0xa9,0x75,0x8a,0x85, +0x59,0x45,0x52,0xb9,0x3f,0x16,0xbe,0xe5,0xa6,0xe4,0xaf,0x15,0x68,0xc5,0x61,0x36, +0x38,0x92,0x73,0x64,0xc2,0x84,0xa7,0x55,0x9c,0x31,0x10,0x1e,0xc9,0x34,0x30,0x00, +0x9d,0x32,0x57,0xac,0x5f,0x73,0x34,0x60,0xab,0xaa,0xac,0x35,0xaf,0xce,0x7a,0x26, +0x5f,0xcc,0x48,0x32,0x53,0xbe,0xbf,0x4e,0xa5,0x94,0xa8,0x7a,0x64,0x61,0x63,0xaa, +0x9c,0x31,0x10,0x1e,0xc9,0x34,0x30,0x00,0x3a,0x2d,0x7f,0xdb,0xbb,0x1a,0xa6,0xd2, +0x97,0x32,0x5d,0xab,0x5d,0x6b,0x38,0x60,0xa6,0xa1,0xaf,0x43,0xac,0xc5,0x7d,0x35, +0x60,0xbd,0x4c,0x44,0x50,0xae,0xb9,0x5d,0x9c,0x31,0x10,0x91,0xc9,0x35,0x30,0x00, +0xa6,0x8b,0xa9,0x7a,0x6c,0x6a,0x66,0x9a,0x3e,0x4a,0x6f,0xba,0xb8,0x43,0xa7,0xac, +0x9b,0x5c,0x67,0x84,0x60,0x8c,0x3c,0x4d,0x87,0xbc,0xb6,0x3a,0xa7,0xb1,0x90,0x49, +0x9c,0x31,0x10,0x0c,0xc8,0x35,0x30,0x00,0x61,0xb9,0x5a,0x71,0x3e,0x4a,0x9f,0xcc, +0xb1,0x15,0xa7,0xed,0x84,0x14,0x65,0xcb,0x54,0x53,0x44,0x7a,0xaa,0x99,0xad,0x39, +0xa5,0xd2,0x7b,0x1b,0x64,0xdc,0x4d,0x35,0x9c,0x31,0x10,0x43,0xb8,0x35,0x20,0x00, +0x1d,0x52,0xe8,0xc5,0xd2,0xd5,0xc5,0x45,0x6c,0x84,0x4f,0x79,0x10,0x75,0x2b,0x66, +0xee,0xb6,0xd0,0xf5,0xc1,0x35,0x68,0x94,0x4f,0x64,0x0c,0x75,0x31,0x76,0xf4,0x96, +0x9c,0x31,0x10,0xa4,0xb7,0x34,0x20,0x00,0xcd,0x05,0xbf,0x4c,0x68,0x4a,0x53,0xc9, +0x0c,0x09,0x2b,0xcc,0xec,0x6b,0xce,0xea,0xc1,0x6c,0x74,0x34,0x55,0xcb,0x16,0x54, +0x19,0x4d,0xe4,0xe9,0xd2,0x69,0xbd,0xab,0x9c,0x31,0x10,0x37,0xc8,0x34,0x20,0x00, +0x82,0x42,0x6d,0xa2,0x53,0x6c,0x40,0x62,0xa2,0xaa,0xb4,0x3a,0x9b,0xbb,0x8c,0x4c, +0x71,0x8e,0x5f,0x95,0x38,0x35,0x83,0xdc,0xbd,0x22,0x9c,0xb9,0x94,0x58,0x78,0x81, +0x9c,0x31,0x10,0xc8,0xc7,0x25,0x20,0x00,0x6c,0xa9,0x40,0x21,0x59,0xc6,0xb5,0x42, +0xa9,0x76,0x96,0x95,0x84,0x49,0x74,0x94,0x57,0x94,0x3d,0x29,0x8b,0xe5,0xba,0x06, +0x9e,0xc6,0x8f,0x45,0x7f,0x85,0x70,0x85,0x9c,0x31,0x10,0xde,0xb6,0x23,0x00,0x00, +0x16,0x64,0x1d,0x81,0xbe,0x95,0xe6,0x35,0xb1,0xb5,0x8e,0x45,0x79,0x85,0x5c,0x85, +0x22,0x44,0x37,0x91,0xaa,0x86,0xc1,0x56,0xa9,0xb9,0x97,0x35,0x86,0x95,0x6c,0x75, +0x9c,0x31,0x10,0x4b,0xa4,0x32,0x00,0x00,0x00,0x46,0x02,0x75,0x76,0x94,0xbc,0x15, +0xcd,0xda,0xb8,0x34,0x94,0xb0,0x62,0x76,0x29,0x66,0x27,0xd4,0x52,0x35,0x83,0x95, +0xab,0x65,0xc3,0x95,0xbe,0x49,0x98,0x85,0x9c,0x31,0x10,0x44,0x93,0x21,0x00,0x00, +0x66,0x6d,0x39,0x6d,0x37,0x91,0x62,0x8d,0xa9,0x8d,0xdb,0x6d,0xdc,0x71,0xba,0x55, +0x88,0xac,0x55,0x2d,0x40,0xa5,0x53,0x29,0x7b,0xa9,0x9d,0x4a,0xa6,0x71,0xa5,0x89, +0x9c,0x31,0x10,0x87,0x73,0x11,0x00,0x00,0xb0,0xb4,0x3d,0x44,0x00,0xae,0x13,0x69, +0x66,0x8a,0x98,0xe5,0xc6,0xe4,0xb4,0xaa,0x83,0x49,0x5a,0xc5,0x47,0x0d,0x66,0xc4, +0x74,0xb0,0x97,0x0e,0x9e,0xc5,0x7d,0x29,0x9c,0x31,0x10,0x3f,0x62,0x11,0x00,0x00, +0x4e,0xd5,0x2f,0x11,0x51,0x2c,0x52,0x85,0x79,0x69,0xb0,0xec,0x83,0x16,0x5e,0xc4, +0x59,0x0d,0x66,0xd5,0x4f,0x29,0x5a,0x94,0x9b,0x4a,0x97,0x08,0x64,0xd1,0x81,0x8d, +0x9c,0x31,0x10,0x78,0x52,0x21,0x00,0x00,0x99,0x4d,0x47,0x68,0x08,0x2e,0x57,0x29, +0x89,0x9d,0x2a,0x5e,0x6a,0xdd,0xad,0x5d,0x93,0x1c,0x50,0x59,0x4e,0x21,0x7e,0x1e, +0x3d,0xe5,0x56,0x60,0xbd,0xe8,0xd5,0xde,0x9c,0x31,0x10,0x50,0x52,0x11,0x00,0x00, +0xa9,0x13,0x81,0x94,0x8a,0x71,0x76,0x0e,0x32,0x23,0x79,0xeb,0x9d,0x6d,0x8d,0x88, +0x75,0x92,0x75,0xdd,0x81,0x8a,0x50,0xda,0x72,0x35,0x7c,0xaa,0x72,0x1b,0x71,0x14, +0x9c,0x31,0x10,0x6e,0xa7,0x75,0x20,0x00,0x7e,0xed,0x7e,0xed,0x7e,0xed,0x80,0xed, +0x80,0xed,0x7e,0xed,0x7e,0xed,0x7e,0xed,0x7e,0xed,0x7e,0xed,0x80,0xed,0x8b,0x0d, +0x96,0xcd,0xae,0xe8,0xd0,0xac,0xf8,0x61,0x9c,0x31,0x10,0xb7,0xb8,0x66,0x20,0x00, +0xec,0xc6,0xe4,0x55,0x86,0x29,0x7d,0xd9,0x9e,0x1c,0x6d,0x9a,0x2a,0x11,0x25,0xd6, +0x1e,0x1b,0x01,0xd9,0x0d,0x9d,0x3a,0x9b,0x35,0x1a,0x4e,0x1b,0x76,0x1c,0x6d,0x5a, +0x9c,0x31,0x10,0xba,0xa8,0x56,0x20,0x00,0x97,0x34,0x88,0xab,0x93,0x0a,0x9c,0xc3, +0xad,0x04,0xbc,0xa2,0xc1,0x41,0xb4,0xcc,0xba,0xec,0xa9,0x0a,0xa4,0x6a,0xa5,0x6b, +0x90,0xd5,0x92,0xf4,0x8c,0xeb,0x95,0x0b,0x9c,0x31,0x10,0xf0,0x88,0x56,0x20,0x00, +0xb6,0x0b,0xcd,0xf4,0x99,0xb1,0xa1,0xf2,0xa6,0x8d,0xa9,0x4b,0xa9,0xf0,0xf6,0x6b, +0x9d,0x0e,0xda,0xad,0xa1,0x29,0xab,0x49,0xc0,0x8c,0xcb,0xac,0x8c,0x69,0xe7,0x8a, +0x9c,0x31,0x10,0x98,0x79,0x57,0x30,0x00,0x53,0x74,0xcc,0x9d,0xb2,0xdb,0x3c,0x91, +0xda,0xd4,0x66,0x1b,0x80,0xda,0x66,0x12,0x53,0x53,0x74,0x95,0x6b,0xd4,0x3b,0xea, +0xbb,0x5a,0x4b,0xe3,0xb4,0xa3,0x44,0x14,0x9c,0x31,0x10,0x56,0x89,0x57,0x30,0x00, +0x81,0x63,0x4a,0x03,0x55,0x0c,0x72,0x8c,0x4d,0xe2,0x71,0xca,0x79,0xec,0x62,0x2b, +0x81,0x8a,0x72,0x22,0x82,0x8d,0x48,0x6c,0xc2,0x91,0x16,0x69,0xd1,0x0d,0x37,0x05, +0x9c,0x31,0x10,0x56,0x89,0x57,0x30,0x00,0xa8,0xaa,0x52,0x2a,0xa6,0x2c,0x45,0xcb, +0x9d,0xc9,0x56,0x8c,0x80,0xcd,0x83,0x2b,0x71,0x0a,0xc2,0xb2,0x39,0xab,0xd1,0xb4, +0x3d,0xcb,0xa6,0x62,0x35,0x52,0xa2,0x83,0x9c,0x31,0x10,0xcb,0x88,0x57,0x30,0x00, +0x39,0x24,0xbd,0xeb,0x5e,0x0b,0x82,0xcb,0xa8,0xeb,0x4d,0x43,0x97,0x23,0x65,0x4b, +0x8a,0x93,0x72,0xd3,0xac,0x6b,0x66,0xab,0x6d,0x6c,0x7a,0x4d,0x69,0x8a,0x66,0xe9, +0x9c,0x31,0x10,0x5c,0x88,0x46,0x30,0x00,0x74,0xcd,0x8e,0x0d,0x4a,0x62,0xb1,0x29, +0x53,0x91,0x6d,0x12,0x79,0x0c,0x66,0xe5,0x51,0x2d,0xc2,0x2c,0x36,0xc0,0xc4,0xc9, +0x46,0x4d,0xa1,0xed,0x29,0x43,0xbe,0xeb,0x9c,0x31,0x10,0x34,0x87,0x46,0x30,0x00, +0x35,0x9a,0xd0,0xdc,0x5e,0xa3,0xa9,0xa0,0x2a,0x23,0x95,0xd4,0x2a,0x22,0x9d,0x2c, +0x93,0x13,0x8d,0xe3,0x9c,0xdc,0x86,0x54,0x62,0x5b,0x7c,0x8a,0x4a,0xea,0x69,0x1b, +0x9c,0x31,0x10,0x3f,0xa9,0x46,0x20,0x00,0x86,0xcc,0x81,0x05,0x96,0xeb,0x86,0xea, +0x84,0xea,0x68,0xca,0x5b,0x0b,0x66,0xec,0x74,0xcc,0x9f,0x0a,0xba,0xe2,0xa9,0x2b, +0xa0,0x6b,0x4b,0x8b,0x2c,0x6b,0x09,0x23,0x9c,0x31,0x10,0x22,0xb9,0x45,0x30,0x00, +0x6a,0xd6,0x9b,0x05,0xbe,0xe4,0xc1,0x35,0xa6,0xa5,0x6a,0xf5,0x3b,0x26,0x18,0xa0, +0x39,0x14,0xb6,0xf4,0xa0,0xf4,0xf0,0xc2,0xbd,0x26,0xaa,0xd6,0x44,0xd2,0x29,0x92, +0x9c,0x31,0x10,0xce,0xcb,0x57,0x40,0x00,0x2c,0xb1,0x99,0x54,0x7a,0xa9,0xa5,0x25, +0xa4,0xe5,0x9c,0xf6,0x9e,0xd5,0x73,0x25,0x56,0xc5,0x33,0x09,0x6f,0x21,0x92,0x85, +0x7f,0x75,0xb2,0x95,0x8f,0x25,0xa5,0x09,0x9c,0x31,0x10,0xdf,0xca,0x66,0x30,0x00, +0x8a,0x96,0x63,0x45,0x43,0x05,0x3e,0x66,0xa1,0xa5,0x6e,0x85,0xad,0x26,0x97,0x04, +0x98,0xa4,0xa1,0x55,0x78,0xc5,0x56,0xf5,0x35,0x0a,0x65,0x25,0x9e,0x54,0x73,0xc5, +0x9c,0x31,0x10,0x6a,0xcb,0x56,0x30,0x00,0xb4,0x94,0x8f,0x45,0x9e,0xc1,0x9d,0x06, +0x67,0x06,0x50,0xf5,0x2a,0xc0,0x93,0x65,0x7e,0x65,0x93,0x75,0xa2,0x96,0x99,0x25, +0x9c,0xf5,0x96,0xd5,0x5d,0x04,0x47,0x01,0x9c,0x31,0x10,0xdf,0xca,0x66,0x30,0x00, +0x2c,0x52,0xab,0xe4,0x6c,0x25,0xa7,0x95,0x98,0xa5,0x9c,0xf6,0x9d,0x25,0x90,0xb5, +0x59,0x15,0x43,0x11,0x34,0x76,0xb1,0x75,0x6a,0x95,0xaf,0x25,0x94,0xf4,0x9e,0xc5, +0x9c,0x31,0x10,0x65,0xc9,0x66,0x30,0x00,0x9d,0x6d,0x8c,0x6d,0x53,0x0e,0x3f,0x29, +0x38,0x36,0xb9,0x89,0x64,0xac,0xb0,0xee,0x93,0x2c,0xa0,0x91,0x9f,0x6d,0x8a,0x8c, +0x51,0x0e,0x39,0x08,0x3e,0x79,0xbf,0x4a,0x9c,0x31,0x10,0x65,0xc9,0x66,0x30,0x00, +0x5e,0xd0,0xb4,0xee,0x93,0x2c,0xa0,0xb1,0x9f,0x49,0x86,0xac,0x51,0x0e,0x37,0x28, +0x3e,0x59,0xbb,0x6a,0x66,0x90,0xb1,0x0e,0x99,0x0c,0xa0,0x91,0x9f,0x69,0x82,0x8c, +0x9c,0x31,0x10,0xea,0xc9,0x67,0x30,0x00,0x51,0x2d,0x33,0x08,0x40,0x79,0xbd,0x46, +0x66,0xb0,0xb3,0x0a,0x9a,0xec,0x9e,0xcd,0xa3,0x49,0x7e,0xb0,0x51,0x0e,0x31,0x0c, +0x40,0x59,0xb9,0x85,0x6c,0x51,0xaf,0x6a,0x9c,0x31,0x10,0xd1,0xc9,0x66,0x20,0x00, +0x9e,0xac,0xa0,0xcd,0xa3,0x49,0x7c,0xb0,0x53,0x2e,0x2d,0x0c,0x3e,0x76,0xb5,0x89, +0x74,0x51,0xa7,0x8a,0xa4,0x8c,0xa1,0x09,0xa3,0x0c,0x7e,0xcd,0x51,0x0d,0x2b,0x0d, +0x9c,0x31,0x10,0xf9,0xc9,0x56,0x20,0x00,0x3e,0x74,0xb3,0x8c,0x7a,0x2b,0xa1,0x85, +0xaa,0x6a,0x9f,0x2a,0xa2,0xea,0x7c,0xca,0x55,0x0c,0x2d,0x03,0x38,0x75,0xaf,0x8b, +0x82,0x2b,0x99,0xa4,0xae,0x4a,0x9f,0x4b,0x9c,0x31,0x10,0xe1,0xc9,0x46,0x20,0x00, +0xa2,0xe2,0x80,0xcb,0x59,0x23,0x2e,0xc3,0x34,0xb5,0xa7,0x63,0x8a,0x34,0x8f,0xa2, +0xb0,0x72,0xa1,0x4b,0xa2,0xca,0x80,0xec,0x5a,0xeb,0x34,0xe4,0x2e,0x83,0x9f,0x92, +0x9c,0x31,0x10,0x6d,0xc9,0x45,0x20,0x00,0x98,0x11,0x83,0xd8,0xb4,0x25,0xa3,0xa5, +0xa0,0x62,0x81,0x75,0x5e,0x76,0x3b,0x74,0x2f,0x51,0x91,0xb8,0xa5,0x21,0x7d,0xb8, +0xb0,0x42,0xa5,0x99,0xa2,0x62,0x87,0x74,0x9c,0x31,0x10,0x75,0xc9,0x55,0x20,0x00, +0x62,0x75,0x42,0x84,0x2e,0x51,0x81,0xb5,0xac,0x35,0x79,0xb5,0xab,0x55,0xa6,0x95, +0xa3,0x75,0x89,0x75,0x68,0x64,0x4b,0x85,0x2c,0x55,0x6d,0xa6,0xb4,0x49,0x79,0x95, +0x9c,0x31,0x10,0x41,0xc7,0x55,0x10,0x00,0xa3,0x49,0xa8,0x91,0xa4,0x69,0x8c,0x71, +0x6c,0x59,0x51,0x91,0x2d,0x7a,0x5b,0x91,0xb5,0x69,0x82,0x40,0x96,0xc9,0xab,0x44, +0xa5,0x7a,0x93,0xa5,0x73,0x26,0x58,0xc8,0x9c,0x31,0x10,0xb4,0xc9,0x55,0x10,0x00, +0x33,0x71,0x44,0x68,0xaf,0x91,0x8c,0x49,0x8b,0xa1,0xab,0x5a,0xa7,0x80,0x99,0x75, +0x7a,0x64,0x60,0x82,0x3b,0x75,0x37,0x52,0x99,0xb9,0x9d,0x21,0x7f,0xb9,0xad,0x41, +0x9c,0x31,0x10,0x0a,0xc8,0x44,0x00,0x00,0xa5,0xa2,0x9e,0x64,0x87,0x61,0x65,0x88, +0x46,0x71,0x2e,0x55,0x7c,0xd1,0xab,0x0a,0x7a,0xd1,0xa8,0x29,0xa5,0xb8,0xa1,0x51, +0x8f,0x89,0x6f,0x75,0x52,0x69,0x30,0xa9,0x9c,0x31,0x10,0xb1,0xc9,0x53,0x10,0x00, +0x54,0x63,0xb2,0x92,0x80,0x5c,0x9b,0x9a,0xa9,0x61,0xa3,0x7b,0x99,0x8b,0x7e,0x6a, +0x5e,0x8b,0x37,0x7a,0x35,0x41,0x9a,0xd5,0x97,0x12,0x86,0xd2,0xae,0x45,0xa0,0x9d, +0x9c,0x31,0x10,0x99,0xc9,0x63,0x10,0x00,0xa0,0x7a,0x8c,0x63,0x6e,0x94,0x49,0x6b, +0x2f,0x8c,0x63,0x94,0xaf,0x41,0x77,0xbb,0xaa,0x44,0xa2,0x99,0x9f,0x5a,0x9b,0x94, +0x7e,0x7b,0x5b,0x6a,0x3c,0x9a,0x32,0x11,0x9c,0x31,0x10,0xa9,0xca,0x64,0x10,0x00, +0x9b,0xc3,0x8a,0x34,0x8d,0xb3,0xaa,0x61,0x9d,0x7a,0xa3,0x8c,0x96,0x6c,0x71,0x82, +0x4f,0x7a,0x35,0x7b,0x4c,0x7d,0xaf,0x6e,0x72,0x9b,0xa6,0x59,0xa2,0x9b,0x99,0x6e, +0x9c,0x31,0x10,0x97,0xca,0x63,0x00,0x00,0xa7,0x7e,0x89,0x8a,0x69,0x69,0x49,0x8c, +0x2f,0x6e,0x6f,0xb6,0xa1,0x2a,0x7a,0xc9,0xaa,0x4a,0x9b,0x8c,0x9e,0x96,0xa1,0x5d, +0x82,0x92,0x63,0x71,0x48,0x82,0x2b,0x55,0x9c,0x31,0x10,0x1d,0xca,0x64,0x00,0x00, +0x86,0xdb,0x91,0x12,0x82,0xb9,0xa9,0x72,0x98,0x5b,0xa2,0xa5,0x9e,0x74,0x80,0x6a, +0x65,0x8a,0x46,0x8a,0x2c,0x4c,0x8d,0xf3,0x8d,0x22,0x88,0x92,0xa4,0x93,0x96,0x5c, +0x9c,0x31,0x10,0xb1,0xca,0x74,0x10,0x00,0xa0,0x84,0x9f,0x9c,0x82,0x5c,0x66,0x7b, +0x4b,0x93,0x2a,0x4c,0x85,0xdc,0x8e,0x3b,0x84,0x82,0xa7,0x8a,0x93,0x83,0xa1,0x7c, +0xa1,0x85,0x89,0x6d,0x69,0x74,0x55,0x9c,0x9c,0x31,0x10,0x1d,0xca,0x64,0x00,0x00, +0x2d,0x7d,0x66,0xa6,0x9b,0x0e,0x7a,0xae,0xa6,0x8e,0x99,0x6d,0x9c,0x74,0xa5,0x6b, +0x91,0x6b,0x70,0x84,0x59,0x8c,0x39,0x72,0x45,0x50,0x9e,0x50,0x7d,0xa9,0x99,0x82, +0x9c,0x31,0x10,0x26,0xca,0x65,0x10,0x00,0x9f,0x5c,0x96,0x75,0xa5,0x84,0x99,0x82, +0x7b,0x8a,0x63,0x7a,0x4a,0x89,0x2f,0x5c,0x84,0xd4,0x8e,0x6b,0x84,0x73,0xa5,0x63, +0x97,0x92,0x9d,0x8a,0xa5,0x6d,0x89,0x6d,0x9c,0x31,0x10,0xbf,0xc9,0x74,0x00,0x00, +0x6e,0xb0,0x59,0x2d,0x39,0x2d,0x4a,0xa6,0x9c,0x04,0x7d,0x44,0x97,0x6a,0xa0,0xee, +0x98,0xb1,0xa4,0xd0,0x98,0xed,0x7d,0x32,0x64,0xf1,0x4d,0x11,0x34,0xb6,0x6b,0xd8, +0x9c,0x31,0x10,0x8f,0xca,0x73,0x00,0x00,0x9a,0x36,0x81,0x66,0xa0,0x75,0x9b,0x95, +0x9a,0x8d,0xa7,0x84,0x90,0x6c,0x79,0x6c,0x5b,0x6b,0x46,0x83,0x35,0x6c,0x84,0xcc, +0x90,0x84,0x88,0x8c,0xa4,0x63,0x9b,0x7b,0x9c,0x31,0x10,0x19,0xc8,0x75,0x10,0x00, +0x9f,0x49,0xa6,0xe9,0x85,0x69,0x72,0xcd,0x52,0xed,0x3f,0x2d,0x42,0x65,0x92,0x20, +0x89,0x21,0x93,0xc6,0xa3,0x89,0x9b,0x2d,0xa5,0x15,0x9a,0x11,0x80,0xb1,0x66,0xb1, +0x9c,0x31,0x10,0x3e,0xca,0x75,0x10,0x00,0x4d,0x93,0x3b,0x8b,0x58,0x83,0x9c,0x33, +0x87,0x5a,0x99,0x61,0x9f,0x79,0x9b,0x82,0xa3,0x9b,0x96,0x83,0x7d,0x74,0x62,0x63, +0x4a,0x6b,0x3a,0x5b,0x6b,0xac,0x9b,0x6d,0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00, +0x87,0x16,0x9a,0x96,0x9c,0xb1,0x9a,0xcd,0xa3,0x2d,0x91,0x4d,0x79,0x2e,0x5c,0xed, +0x48,0xed,0x3a,0x6e,0x77,0x91,0x99,0x10,0x87,0x50,0x9a,0xee,0x9c,0xed,0x9a,0xcc, +0x9c,0x31,0x10,0x84,0xc9,0x75,0x10,0x00,0xa4,0xc9,0x8c,0xea,0x77,0x09,0x59,0x09, +0x47,0x09,0x3c,0x89,0x81,0x8e,0x95,0x6e,0x89,0x8d,0x99,0x10,0x98,0xf1,0x98,0xcd, +0xa0,0xe5,0x8d,0x05,0x79,0x25,0x5d,0x09,0x9c,0x31,0x10,0xf1,0xc9,0x75,0x30,0x00, +0x4b,0x09,0x3e,0x84,0x83,0x41,0x93,0x26,0x87,0x66,0x97,0x25,0x9b,0x09,0x96,0xec, +0xa1,0x74,0x93,0x19,0x79,0x3a,0x5e,0xb9,0x48,0xf5,0x3e,0x71,0x7f,0x4a,0x95,0x25, +0x9c,0x31,0x10,0xbe,0xb9,0x75,0x20,0x00,0x8f,0x65,0xa9,0x28,0xb5,0x08,0xb0,0xe9, +0xbd,0x31,0xae,0xd6,0x76,0xd6,0x44,0xb5,0x21,0x15,0x00,0xb9,0x5d,0x99,0xab,0x18, +0x8f,0x54,0xa1,0x11,0xb2,0xf1,0xae,0xed,0x9c,0x31,0x10,0x24,0xb8,0x84,0x20,0x00, +0xb1,0x15,0xb8,0xce,0x86,0x0e,0x56,0x0d,0x2a,0x51,0x05,0x94,0x33,0x5d,0xa4,0xe6, +0x91,0x2e,0x94,0xac,0xad,0x28,0xb5,0xe5,0xa9,0x22,0xb6,0x9e,0x96,0xd5,0x62,0xd4, +0x9c,0x31,0x10,0x24,0xb8,0x84,0x20,0x00,0x36,0x14,0x12,0x96,0x15,0x0d,0x90,0xc8, +0x9c,0xcc,0x8d,0x92,0xa5,0xd6,0xb5,0xd6,0xad,0x9e,0xb6,0xe1,0xa5,0x64,0x6d,0xa4, +0x3d,0x25,0x22,0xa6,0x08,0xa1,0x6e,0x9d,0x9c,0x31,0x10,0x6d,0xb8,0x74,0x10,0x00, +0xaa,0xe6,0x91,0x85,0x9d,0x44,0xb3,0x48,0xb1,0x25,0xaf,0x26,0xb0,0x69,0x82,0xac, +0x54,0x90,0x2a,0xf1,0x0a,0xb5,0x3f,0xb9,0xa4,0xf9,0x9b,0x56,0x94,0xf6,0xab,0x10, +0x9c,0x31,0x10,0xac,0xb8,0x74,0x20,0x00,0xb4,0xec,0xac,0xa8,0xb0,0x85,0x92,0xc5, +0x64,0xaa,0x30,0xc9,0x17,0x0d,0x1e,0xa9,0x8a,0x49,0xa4,0x4c,0x94,0x70,0xa0,0x91, +0xb4,0xd1,0xb0,0xd1,0xaf,0x31,0xa0,0xf1,0x9c,0x31,0x10,0xac,0xb8,0x74,0x20,0x00, +0x78,0xf1,0x44,0xcd,0x1f,0x0d,0x0e,0x6e,0x61,0x6a,0xab,0x21,0x9b,0x80,0x97,0x44, +0xad,0x49,0xb7,0x28,0xb1,0x51,0xa4,0xf5,0x87,0x16,0x56,0xf2,0x29,0x2d,0x10,0xec, +0x9c,0x31,0x10,0x6d,0xb8,0x74,0x10,0x00,0x3b,0x91,0x9e,0xf9,0xa5,0x16,0x94,0xf5, +0xa5,0x15,0xb7,0x11,0xb4,0xe9,0xaa,0xa9,0x90,0xec,0x68,0xad,0x32,0xcd,0x16,0xee, +0x1e,0x64,0x82,0x64,0xaa,0x48,0x98,0x8d,0x9c,0x31,0x10,0x05,0xb7,0x74,0x10,0x00, +0x9a,0x71,0xb2,0xb5,0xb8,0x56,0xaf,0x11,0x99,0x0d,0x7d,0x48,0x48,0xe5,0x21,0x25, +0x12,0x06,0x5f,0x45,0xa8,0xe1,0xa1,0x20,0x94,0xe5,0xa6,0xa5,0xb8,0xa9,0xb2,0xed, +0x9c,0x31,0x10,0xb1,0xb7,0x74,0x00,0x00,0xa2,0x91,0x86,0xd1,0x5c,0xd1,0x31,0x11, +0x17,0x0c,0x35,0x91,0x94,0xd9,0xaa,0xfa,0x98,0xf5,0x9b,0x10,0xb3,0x11,0xb6,0xed, +0xa8,0xcd,0x91,0x0d,0x70,0xed,0x43,0x0d,0x9c,0x31,0x10,0x05,0xb7,0x74,0x10,0x00, +0x1e,0xed,0x1c,0x28,0x74,0x61,0xaa,0x69,0x9e,0xb2,0x94,0xb5,0xaa,0xd5,0xb8,0xd4, +0xb1,0x55,0x9b,0x11,0x7f,0x2d,0x52,0xc9,0x2d,0x29,0x18,0xcc,0x4b,0xd4,0x9f,0x4d, +0x9c,0x31,0x10,0x12,0xb6,0x73,0x10,0x00,0xab,0xe3,0x96,0xa0,0x99,0xa3,0xb5,0x95, +0xb9,0x95,0xa2,0x45,0x86,0x76,0x68,0x38,0x3d,0x9a,0x1e,0xa8,0x2e,0x96,0x87,0x5a, +0xb3,0x6d,0xa0,0x9a,0x90,0x97,0xa6,0x96,0x9c,0x31,0x10,0xa6,0xb6,0x73,0x00,0x00, +0xba,0x57,0xae,0x76,0x8f,0x76,0x75,0x77,0x50,0x68,0x2b,0x88,0x1e,0x08,0x60,0x84, +0xa8,0x43,0xaa,0x76,0x93,0x5a,0x9a,0x6a,0xb4,0x58,0xb4,0x99,0x99,0x79,0x7f,0xa6, +0x9c,0x31,0x10,0x2c,0xb6,0x74,0x00,0x00,0x62,0xc9,0x3d,0x4d,0x23,0x0c,0x41,0xd1, +0x8f,0x11,0xaf,0x2a,0x9b,0x05,0x8e,0xe9,0xa3,0x0d,0xb4,0xcd,0xa6,0xcd,0x88,0xf1, +0x6e,0xcd,0x4e,0xcd,0x31,0x0d,0x2c,0x48,0x9c,0x31,0x10,0xa8,0xb5,0x73,0x10,0x00, +0x68,0x55,0xa4,0x21,0xa6,0xee,0x90,0xe6,0x94,0xda,0xae,0xd5,0xb2,0xd4,0x94,0x91, +0x74,0xd9,0x58,0xa5,0x3c,0xe2,0x2c,0x25,0x4f,0x98,0x94,0xc4,0xac,0xcc,0x98,0xa5, +0x9c,0x31,0x10,0x2d,0xb4,0x63,0x10,0x00,0x8c,0x71,0xa0,0xa2,0xb2,0xdd,0xa0,0xed, +0x7f,0x61,0x64,0x89,0x4c,0xd1,0x37,0x6e,0x41,0x6a,0x7c,0xf1,0xaa,0x99,0xa4,0xcd, +0x8f,0x14,0x91,0x25,0xa6,0xa5,0xa6,0xc9,0x9c,0x31,0x10,0x8b,0xb5,0x62,0x00,0x00, +0x8a,0xd1,0x6e,0xb1,0x56,0xa4,0x44,0xd1,0x3e,0x61,0x63,0x19,0x98,0xa2,0xa9,0x25, +0x96,0xd8,0x8c,0x99,0x9b,0x1d,0xa2,0xe1,0x90,0xe9,0x72,0xe5,0x5d,0x19,0x4f,0x19, +0x9c,0x31,0x10,0x33,0xa4,0x62,0x00,0x00,0x10,0x96,0x41,0x0c,0x9e,0x92,0xce,0xf1, +0xb8,0xe9,0x9b,0x10,0xab,0x5a,0xbd,0x1c,0x9e,0xe0,0x64,0x59,0x39,0x15,0x25,0x1d, +0x26,0xaa,0x57,0x18,0xa4,0x8a,0xce,0xe9,0x9c,0x31,0x10,0x1b,0xa4,0x52,0x00,0x00, +0xc2,0x58,0xa6,0x61,0xa2,0xaa,0x9e,0x78,0x71,0x64,0x37,0x66,0x1c,0x95,0x32,0x6d, +0x6d,0x89,0xa8,0x69,0xc7,0x6d,0xc4,0x6d,0xb5,0x91,0xa4,0x6c,0x80,0x81,0x48,0x6d, +0x9c,0x31,0x10,0xfd,0xa2,0x53,0x00,0x00,0x21,0x95,0x27,0x2d,0x5a,0x52,0x9d,0x6c, +0xcb,0x89,0xd4,0x8d,0xc0,0x4d,0x9e,0x8d,0x6e,0xad,0x3e,0x4e,0x22,0x6c,0x2d,0x56, +0x5f,0x8c,0x9f,0x45,0xcd,0x4d,0xd2,0x91,0x9c,0x31,0x10,0xe6,0xa2,0x41,0x00,0x00, +0xbc,0x28,0x99,0x47,0x6a,0x35,0x3e,0xa5,0x2c,0x4c,0x40,0x28,0x73,0x31,0xa5,0x4d, +0xbe,0x36,0xba,0x55,0xaa,0x5b,0x92,0xc2,0x6d,0x25,0x49,0x3b,0x3d,0x39,0x53,0xa4, +0x9c,0x31,0x10,0x92,0x92,0x53,0x00,0x00,0x7d,0x1d,0xc0,0xa9,0xdd,0x51,0xd4,0x91, +0xbb,0x2d,0x90,0xdd,0x55,0x15,0x26,0xe5,0x24,0xd9,0x53,0x21,0x8e,0xd8,0xb8,0xd9, +0xc4,0xed,0xb7,0x15,0x9d,0x19,0x76,0xe9,0x9c,0x31,0x10,0x05,0x92,0x42,0x00,0x00, +0x4f,0x15,0x39,0x11,0x48,0x99,0x74,0xdd,0x9e,0x6d,0xb2,0x95,0xaa,0x91,0x98,0xed, +0x80,0xe0,0x69,0x0d,0x58,0x9d,0x58,0x69,0x6c,0xe1,0x87,0x19,0x9a,0xd5,0x9e,0xe5, +0x9c,0x31,0x10,0x62,0x72,0x41,0x00,0x00,0xd9,0x25,0xa2,0xcd,0x65,0x5a,0x35,0x31, +0x24,0xd8,0x4b,0x0e,0x89,0x60,0xae,0xed,0xb2,0xd1,0xad,0x15,0x9f,0x2d,0x88,0xdc, +0x6a,0xda,0x59,0x20,0x60,0xe6,0x6a,0x98,0x9c,0x31,0x10,0xec,0x52,0x32,0x00,0x00, +0x71,0x9b,0xb4,0xea,0xf6,0x1c,0xf2,0x93,0xae,0x64,0x85,0xe2,0x7e,0x14,0x7e,0x62, +0x7a,0x5b,0xa6,0x13,0xca,0x53,0xc5,0x1c,0x8f,0x22,0x5e,0x13,0x46,0x5a,0x58,0x50, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_CHARGE_PLEASE.txt b/config/_default_cfg_src_/res/en/SOUND_CHARGE_PLEASE.txt new file mode 100644 index 0000000..ec886b0 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_CHARGE_PLEASE.txt @@ -0,0 +1,315 @@ +0x9c,0x31,0x10,0x1c,0x31,0x21,0x00,0x00,0x7d,0xbb,0x7d,0xbb,0x75,0xbb,0x76,0x33, +0x38,0x45,0x59,0xba,0x6b,0x54,0x49,0xa2,0x66,0x3b,0xb9,0x3b,0x95,0xab,0x98,0xca, +0xd4,0xba,0xb5,0xa4,0xd1,0x59,0xbd,0x12,0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00, +0x91,0x6e,0x81,0x9e,0x74,0x65,0x86,0x5d,0x81,0xa1,0x65,0xe8,0x52,0x69,0x3d,0xa9, +0x36,0x5e,0x29,0x9d,0x3d,0x50,0x3e,0x19,0x3d,0xa9,0x46,0x08,0x7e,0x8e,0x9c,0xa9, +0x9c,0x31,0x10,0x6c,0x97,0x65,0x00,0x00,0x81,0xdd,0x89,0x5d,0xbe,0x51,0xc9,0xd8, +0xc1,0xa5,0xb1,0x61,0xdb,0x2a,0xc0,0x8d,0x8e,0x1d,0x6d,0xed,0x7e,0x59,0x72,0x75, +0x4d,0x65,0x41,0xed,0x3d,0xde,0x4a,0x19,0x9c,0x31,0x10,0x65,0x96,0x76,0x00,0x00, +0x45,0xda,0x49,0xd4,0x4d,0x23,0x45,0xdb,0x25,0xd4,0x09,0xa3,0x05,0x9a,0x11,0x1c, +0x31,0xda,0x4d,0x9c,0x69,0xa3,0x81,0xcb,0x8d,0xf3,0x91,0x4b,0x95,0xe2,0x94,0x95, +0x9c,0x31,0x10,0xb0,0x87,0x66,0x20,0x00,0xaa,0x2a,0x9d,0xd3,0xa1,0xa3,0xc2,0x54, +0xc9,0xeb,0xcd,0x4a,0xbe,0x72,0xb1,0x94,0xca,0xec,0xb1,0x9a,0x99,0x64,0xa6,0x14, +0xad,0x9a,0xa2,0x50,0x89,0xdc,0xb9,0xdd,0x9c,0x31,0x10,0x45,0x77,0x67,0x30,0x00, +0xdc,0x3c,0xd2,0xd3,0xdc,0xb9,0x6b,0x2b,0xa2,0xad,0xac,0x53,0x9a,0xc3,0x8b,0x1a, +0xa5,0xa3,0xaa,0xa2,0xa9,0x33,0x93,0x44,0x92,0xec,0x74,0xc3,0x73,0xc2,0x83,0x4c, +0x9c,0x31,0x10,0x8d,0x97,0x76,0x20,0x00,0x8d,0x24,0xbe,0x00,0x93,0x5b,0x65,0xe3, +0x71,0x12,0x82,0x13,0x72,0x24,0x69,0x1c,0x75,0xd9,0x7e,0x1b,0x7d,0xa3,0x75,0x5c, +0x7d,0xdc,0x7e,0x5a,0x7d,0xda,0x85,0xdc,0x9c,0x31,0x10,0x7d,0x85,0x54,0x10,0x00, +0x90,0xd1,0x82,0x9b,0x7a,0xac,0x6e,0x8d,0x7e,0xdd,0x82,0xd8,0x80,0xd2,0x74,0xe3, +0x6e,0x63,0x6c,0xdb,0x71,0x93,0x8e,0x95,0xb4,0x62,0xb0,0xdb,0x76,0x94,0x3d,0x1c, +0x9c,0x31,0x10,0x37,0xa5,0x54,0x10,0x00,0x6a,0x99,0x77,0x1b,0x8c,0x89,0x9c,0x54, +0x94,0xd4,0x73,0x9d,0x4e,0xda,0x4c,0x9c,0x76,0x59,0xb2,0xda,0xd0,0xe2,0xa0,0xdc, +0x45,0x23,0x0c,0xd9,0x28,0xdb,0x99,0x5c,0x9c,0x31,0x10,0xa2,0xb7,0x45,0x10,0x00, +0xc2,0xd1,0xc0,0xed,0x80,0xa9,0x3f,0x0d,0x29,0x09,0x5b,0x25,0xb2,0xd9,0xe0,0xa5, +0xb8,0xd1,0x5d,0x55,0x22,0xd5,0x29,0x0c,0x7a,0x4c,0xc8,0xd1,0xdf,0x05,0xa7,0x0d, +0x9c,0x31,0x10,0x7b,0xb7,0x55,0x20,0x00,0x5f,0x31,0x28,0x6d,0x31,0x6d,0x7d,0x0d, +0xc6,0xe9,0xd4,0x91,0xa0,0xcd,0x63,0x29,0x30,0xac,0x35,0x4d,0x77,0x2d,0xbd,0x2d, +0xd0,0xae,0xa2,0x8e,0x66,0xed,0x34,0xa4,0x9c,0x31,0x10,0x58,0xb7,0x76,0x40,0x00, +0x37,0x1b,0x73,0x1a,0xb9,0x1c,0xce,0xdc,0xa4,0x9c,0x6c,0xd2,0x36,0x5a,0x32,0xdb, +0x7e,0x9c,0xcb,0x14,0xc8,0x9e,0xa3,0x08,0x62,0xc3,0x12,0x00,0x2c,0x80,0xa2,0x4c, +0x9c,0x31,0x10,0x5f,0xb7,0x87,0x40,0x00,0xdd,0x2d,0xbd,0x2d,0x74,0xbc,0x46,0x3b, +0x0c,0xc3,0x44,0xe0,0xb8,0xd2,0xe5,0xc4,0xb5,0xbd,0x71,0xc3,0x3a,0xba,0x0a,0xed, +0x61,0xc5,0xd5,0x2a,0xf1,0xa9,0xa9,0x52,0x9c,0x31,0x10,0x9a,0xb8,0x88,0x30,0x00, +0x61,0xe3,0x25,0xa4,0x12,0x91,0x7e,0x0b,0xe6,0x24,0xe9,0xec,0x99,0xd3,0x52,0x13, +0x10,0xd2,0x22,0x1d,0x99,0xeb,0xf2,0x1a,0xdd,0xca,0x85,0xdb,0x46,0x24,0x05,0x12, +0x9c,0x31,0x10,0x56,0xb7,0x89,0x40,0x00,0x31,0xe2,0xb1,0x34,0xfa,0x23,0xcd,0xc3, +0x75,0xd3,0x32,0x2b,0x02,0x5c,0x51,0xa3,0xc9,0x2a,0xf5,0xcb,0xb5,0xcb,0x61,0xa3, +0x25,0x54,0x0f,0x21,0x6d,0xa4,0xd9,0xdc,0x9c,0x31,0x10,0xf2,0xb7,0x88,0x30,0x00, +0xed,0xbc,0xa1,0xaa,0x52,0x43,0x10,0x32,0x22,0x26,0x8d,0xe2,0xea,0x2b,0xe1,0xb2, +0x89,0xb3,0x46,0xcc,0x0c,0xaa,0x31,0xea,0xa5,0x15,0xf1,0xcb,0xcd,0xb3,0x75,0xcb, +0x9c,0x31,0x10,0xf2,0xb7,0x88,0x30,0x00,0x36,0x32,0x0e,0x5d,0x51,0x93,0xbd,0xca, +0xf1,0xb3,0xbd,0xbc,0x69,0xbb,0x25,0x3c,0x0e,0xa8,0x69,0xbc,0xd5,0xc4,0xf1,0xb3, +0xa5,0xba,0x56,0x43,0x14,0x2a,0x1e,0x46,0x9c,0x31,0x10,0x6f,0xb6,0x88,0x30,0x00, +0x89,0x42,0xe6,0x23,0xe5,0x53,0x8d,0xb4,0x43,0x43,0x0c,0xbb,0x35,0x51,0xa5,0x1d, +0xf2,0x5b,0xd5,0xab,0x79,0x43,0x32,0x3b,0x0e,0xcc,0x51,0x9d,0xc1,0x5a,0xf1,0xaa, +0x9c,0x31,0x10,0x74,0xb7,0x87,0x30,0x00,0xbd,0xc5,0x61,0xba,0x1d,0x45,0x16,0x1a, +0x71,0xe0,0xd9,0x9c,0xed,0xc4,0xa1,0xb3,0x4e,0x43,0x10,0xa1,0x29,0xde,0x91,0x24, +0xe6,0x42,0xdd,0xba,0x85,0xc4,0x3a,0x31,0x9c,0x31,0x10,0x7a,0xb7,0x78,0x30,0x00, +0x11,0xec,0x49,0x83,0xb1,0x58,0xed,0xb7,0xc1,0xa9,0x69,0xb5,0x25,0x48,0x16,0x82, +0x69,0xdb,0xd1,0x98,0xed,0xb6,0xa5,0xb6,0x52,0x39,0x18,0xa3,0x29,0xcd,0x8d,0xb4, +0x9c,0x31,0x10,0x53,0xb6,0x78,0x20,0x00,0xe2,0x26,0xdd,0x57,0x89,0x29,0x3f,0x35, +0x11,0x5b,0x45,0xa2,0xb1,0x37,0xea,0x49,0xc1,0x29,0x69,0xc4,0x25,0x49,0x16,0x93, +0x6d,0xcb,0xd1,0xb7,0xe9,0x96,0xa1,0xd6,0x9c,0x31,0x10,0x48,0xb7,0x77,0x20,0x00, +0x4f,0x15,0x16,0x51,0x30,0xf6,0x98,0xcb,0xe9,0x19,0xd8,0xa1,0x80,0xd6,0x33,0x1a, +0x10,0xed,0x54,0xc1,0xbe,0xe8,0xed,0x1c,0xb6,0xde,0x5e,0xd9,0x22,0xa4,0x27,0x00, +0x9c,0x31,0x10,0xd5,0xb6,0x77,0x20,0x00,0x84,0xf2,0xd9,0x0d,0xdc,0x9d,0x8e,0xe0, +0x3f,0x93,0x16,0x63,0x4c,0xe9,0xb2,0x46,0xe9,0x34,0xbe,0x89,0x64,0xd9,0x24,0xad, +0x25,0x41,0x80,0xdd,0xd4,0xeb,0xdc,0xc4,0x9c,0x31,0x10,0xe9,0xb6,0x87,0x30,0x00, +0x91,0x51,0x47,0x33,0x18,0x2a,0x46,0x5e,0xa8,0xac,0xe2,0x39,0xbd,0x41,0x69,0xac, +0x2e,0x4c,0x22,0xc3,0x79,0x9e,0xcd,0x52,0xd9,0xb8,0x95,0xb2,0x4a,0xc4,0x1c,0x2c, +0x9c,0x31,0x10,0xfc,0xb7,0x77,0x30,0x00,0x44,0xec,0xaa,0x9a,0xe1,0x0b,0xbe,0xe2, +0x6a,0xda,0x30,0xdb,0x27,0x25,0x78,0xcd,0xc8,0xda,0xd6,0xe1,0x94,0xd1,0x4f,0x1c, +0x24,0x5c,0x46,0xdd,0xa6,0xa3,0xdb,0x12,0x9c,0x31,0x10,0xd5,0xb6,0x77,0x20,0x00, +0xbc,0x92,0x6c,0xdb,0x37,0x1b,0x2d,0x25,0x75,0x14,0xc0,0x92,0xd2,0xe2,0x94,0xe3, +0x51,0x5b,0x30,0x0c,0x4b,0x13,0x9c,0xe2,0xcd,0x63,0xb8,0xdc,0x72,0x93,0x45,0x13, +0x9c,0x31,0x10,0x9b,0xb6,0x76,0x10,0x00,0x3a,0xa2,0x71,0x21,0xac,0x54,0xc2,0xd5, +0x98,0xa3,0x63,0x19,0x46,0x52,0x51,0x14,0x8a,0x9c,0xb2,0xdb,0xa8,0xdb,0x7a,0xdb, +0x5a,0xdb,0x50,0xcc,0x6c,0xd3,0x98,0xe2,0x9c,0x31,0x10,0xf3,0xa6,0x75,0x20,0x00, +0xd7,0x14,0xa6,0xd2,0x5d,0x4e,0x43,0x0d,0x49,0x08,0x7b,0x0c,0xaa,0xf1,0xb6,0xed, +0x8c,0xe5,0x70,0xa9,0x62,0xce,0x6a,0xa9,0x78,0x69,0x8a,0xc8,0x92,0x6d,0x86,0x2e, +0x9c,0x31,0x10,0x59,0x75,0x66,0x20,0x00,0x59,0x88,0x33,0xe2,0x5a,0xa8,0x84,0x9b, +0x7b,0xb7,0x6c,0x65,0x6c,0x24,0x88,0x18,0xc4,0x18,0xc2,0x29,0xa9,0x47,0x80,0xa4, +0x90,0xd6,0xbb,0xe8,0xc0,0xb8,0xd3,0xb7,0x9c,0x31,0x10,0xec,0x74,0x56,0x20,0x00, +0xe3,0x65,0xca,0xb9,0xba,0x3b,0x9a,0x46,0x88,0x45,0x7e,0xc8,0x8a,0x99,0x86,0xa6, +0x81,0xb4,0x6e,0x08,0x66,0xc6,0x5e,0x27,0x5a,0x98,0x55,0xb5,0x54,0xa7,0x6a,0x29, +0x9c,0x31,0x10,0xd8,0x65,0x55,0x20,0x00,0x73,0x91,0x52,0x8e,0x3b,0x65,0x1c,0x4d, +0x53,0xc4,0x8b,0x88,0x9b,0x98,0xb4,0x95,0x83,0x69,0x63,0x6d,0x4a,0x69,0x4d,0x71, +0x55,0x8d,0x83,0x2d,0x83,0x4d,0x64,0x4d,0x9c,0x31,0x10,0x84,0x64,0x55,0x10,0x00, +0x56,0x9b,0x46,0x1c,0x3d,0xda,0x5e,0xdc,0x6d,0xd3,0x5e,0xd3,0x49,0xdb,0x3e,0x93, +0x59,0x8a,0x6d,0x4c,0x6c,0x93,0x6d,0xcd,0x81,0x5c,0x7e,0x11,0x85,0x5b,0x9d,0x94, +0x9c,0x31,0x10,0xf9,0x55,0x54,0x10,0x00,0xdb,0x21,0xd3,0xbc,0x9b,0x3e,0x53,0x5b, +0x31,0xd2,0x5a,0xd3,0x4b,0xdb,0x64,0xda,0x53,0x42,0x53,0xbd,0x54,0xc6,0x84,0x22, +0x8d,0x31,0xb4,0xc3,0x83,0xb2,0x79,0xc4,0x9c,0x31,0x10,0xe7,0x45,0x55,0x00,0x00, +0x64,0x4a,0x4b,0x34,0x5c,0x3a,0xea,0xcc,0xb2,0xcb,0xd4,0x44,0x7b,0xe1,0x8c,0xb4, +0x4e,0x3b,0x5a,0xda,0x44,0x42,0x4b,0x2c,0x1b,0x95,0x1b,0x29,0x9b,0x9b,0x9c,0xcb, +0x9c,0x31,0x10,0xf0,0x65,0x65,0x20,0x00,0x7d,0x33,0x71,0x9b,0x81,0x32,0x7d,0x25, +0x89,0x4a,0x99,0x56,0xc0,0xb9,0xb1,0x3a,0x8d,0x4a,0x95,0x29,0x89,0x4e,0x9d,0xdb, +0x75,0xeb,0x86,0x55,0x7e,0xd1,0x65,0xce,0x9c,0x31,0x10,0x2b,0x55,0x65,0x30,0x00, +0x36,0x92,0x7a,0x6a,0x57,0x6a,0x58,0xc1,0x48,0x29,0x75,0x15,0x42,0xad,0x98,0xa9, +0x53,0x09,0xb4,0xb1,0x96,0x69,0xa3,0x15,0xa5,0x6d,0x79,0x69,0xb4,0xed,0x57,0x55, +0x9c,0x31,0x10,0x9f,0x55,0x65,0x20,0x00,0x38,0xcd,0x54,0xed,0xda,0xa9,0xb5,0x2d, +0xd7,0x4c,0x67,0x2d,0x67,0x39,0x6a,0xf2,0x66,0xe6,0x7b,0x0d,0xa6,0xe9,0xa8,0x49, +0xa8,0xd0,0xd2,0xac,0x79,0x04,0x73,0x0c,0x9c,0x31,0x10,0xa6,0x54,0x56,0x20,0x00, +0x5a,0xe0,0x6c,0xad,0x76,0xa2,0x44,0xd2,0x36,0xdd,0x48,0x59,0x20,0xd0,0x74,0xed, +0xa7,0xae,0xbb,0x62,0xba,0xde,0xc7,0x0a,0xb6,0x59,0x98,0x98,0xb2,0xe4,0x78,0x29, +0x9c,0x31,0x10,0xbe,0x54,0x46,0x20,0x00,0x74,0x5e,0x62,0xe2,0x6a,0xda,0x72,0xd6, +0x54,0xdd,0x86,0x9d,0x76,0xdd,0x96,0x65,0x84,0x94,0x64,0xcc,0x44,0xe0,0x27,0x6d, +0x41,0x2d,0x45,0x16,0x87,0x5a,0x85,0x09,0x9c,0x31,0x10,0x9b,0x44,0x46,0x20,0x00, +0xeb,0x1c,0x92,0xe9,0x95,0x31,0x92,0xda,0x87,0x4e,0x79,0x15,0x74,0xa9,0x44,0xe2, +0x45,0x2a,0x36,0x5a,0x48,0x8e,0x37,0x19,0x26,0x9c,0x26,0x9c,0x24,0x60,0x46,0x9c, +0x9c,0x31,0x10,0x18,0x33,0x45,0x20,0x00,0x45,0x29,0x63,0xd1,0x66,0xfa,0x6a,0xea, +0x85,0x21,0x88,0x88,0x9a,0x88,0x86,0xd0,0x36,0xd4,0x26,0xf1,0x59,0x0d,0xb6,0xc9, +0xb7,0x0d,0x37,0x0d,0x34,0xed,0x06,0xf1,0x9c,0x31,0x10,0xc9,0x42,0x32,0x00,0x00, +0x31,0xec,0x35,0x54,0x36,0xd3,0x22,0x19,0x32,0x21,0x26,0x1b,0x3d,0xd5,0x21,0xdc, +0x35,0x63,0x3e,0x51,0x44,0xda,0x4a,0x1a,0x41,0x5c,0x59,0xdc,0x74,0x9b,0x5d,0xd3, +0x9c,0x31,0x10,0xa6,0x32,0x21,0x00,0x00,0x4c,0x14,0x49,0xcc,0x24,0x31,0x5d,0xbb, +0x24,0x53,0x73,0x34,0x63,0x3b,0x5b,0x3a,0x8c,0xcd,0x5a,0xab,0x73,0x3b,0x64,0xc8, +0x43,0x25,0x6c,0x21,0x91,0xc2,0x7b,0x33,0x9c,0x31,0x10,0xa6,0x32,0x21,0x00,0x00, +0xab,0x43,0x9c,0x3b,0xd2,0x36,0xc4,0x99,0x9c,0x44,0xbc,0xb9,0xac,0xb2,0xbd,0xbb, +0xa3,0xca,0xa4,0xcc,0xb2,0xd4,0xa3,0xac,0xd4,0x39,0xba,0x31,0xe6,0x34,0xc3,0xc4, +0x9c,0x31,0x10,0xcf,0x41,0x11,0x00,0x00,0x8e,0xd3,0xb8,0xcd,0xb2,0x9b,0xa0,0xdb, +0xa8,0xf3,0xa3,0x61,0xc8,0xe4,0xc5,0x1c,0xb0,0xd3,0xbe,0xdc,0xa8,0xeb,0xb1,0x43, +0xb1,0x12,0xa3,0x12,0xbe,0xad,0xb1,0x99,0x9c,0x31,0x10,0x8e,0x32,0x11,0x00,0x00, +0xd5,0x9a,0xbc,0xed,0x96,0x11,0x7d,0x15,0x96,0x2b,0x82,0x16,0x92,0x92,0xa6,0x54, +0xc1,0xcc,0xa8,0x5b,0xa2,0xaa,0x7e,0x64,0x64,0xe8,0x8e,0x53,0x92,0xa4,0x8d,0x9d, +0x9c,0x31,0x10,0x3b,0x33,0x21,0x00,0x00,0x7b,0x33,0x9b,0x49,0xab,0x44,0xbb,0xb9, +0x93,0xcd,0x59,0xc2,0x73,0x19,0x4c,0x50,0x13,0x4b,0x45,0x24,0x23,0xb5,0x1b,0x34, +0x3b,0x45,0x2c,0x30,0x1c,0x31,0x2b,0x33,0x9c,0x31,0x10,0xdb,0x43,0x33,0x00,0x00, +0x55,0xdc,0x6e,0x93,0x7d,0x1c,0x5d,0xdb,0x52,0x11,0x83,0x1c,0x65,0xd4,0x5f,0x25, +0x3f,0xa0,0x55,0x1a,0x56,0x53,0x5b,0x52,0x89,0xc5,0x52,0x2d,0x5a,0xe3,0x60,0xe5, +0x9c,0x31,0x10,0xc3,0x77,0x68,0x30,0x00,0x7b,0xb7,0x7c,0x36,0x7b,0x36,0xba,0x86, +0xf0,0xbb,0x6b,0xe7,0x5b,0x18,0x63,0xa6,0x7b,0xc6,0x7b,0xb6,0x63,0xb8,0xa4,0xd9, +0x8b,0xb8,0x6a,0x37,0x34,0x24,0x43,0xb6,0x9c,0x31,0x10,0x77,0x64,0x68,0x40,0x00, +0x2d,0x29,0x58,0x61,0x79,0x19,0x59,0x61,0x73,0x19,0x54,0x89,0x4b,0x25,0x59,0x2d, +0x84,0x99,0x74,0xd9,0x52,0x99,0x53,0x14,0x5a,0x98,0x4a,0xa0,0x6d,0x35,0x7a,0xa6, +0x9c,0x31,0x10,0x60,0x75,0x7a,0x50,0x00,0x9a,0x35,0xa5,0x31,0x96,0x44,0x80,0x3c, +0xb2,0xb8,0xba,0x49,0xa7,0x4e,0xa4,0xbe,0xa4,0xaa,0xb2,0x46,0x85,0xcd,0x51,0x9c, +0x55,0x2c,0x56,0x60,0x5a,0xd1,0x59,0xae,0x9c,0x31,0x10,0xa1,0x75,0x7a,0x60,0x00, +0x68,0xae,0x79,0xd2,0xa9,0xc6,0x66,0xb5,0x35,0x35,0x14,0xa0,0x36,0x4c,0x15,0xcd, +0x35,0xc1,0x36,0x4e,0x21,0x36,0x35,0x9d,0x44,0xcd,0x82,0xc5,0x65,0xb1,0x89,0x45, +0x9c,0x31,0x10,0xd2,0x86,0x8b,0x60,0x00,0xa2,0xe1,0x9a,0xde,0x82,0x9a,0xa3,0x61, +0x9a,0x94,0xaa,0x90,0x92,0xec,0x9a,0xe5,0xc1,0x16,0x92,0x9e,0xaa,0x95,0x9a,0x9d, +0x83,0x5c,0x6a,0xa1,0x5b,0x65,0x3c,0x91,0x9c,0x31,0x10,0xcf,0x77,0x8a,0x50,0x00, +0x19,0x0e,0x18,0x37,0x0b,0x50,0x7b,0xac,0xa6,0x0f,0xba,0xc9,0xa7,0xd2,0xeb,0x0f, +0xd6,0xef,0xc8,0xf3,0x69,0xb1,0x98,0x87,0x68,0xae,0x08,0x73,0x49,0x70,0x56,0xd2, +0x9c,0x31,0x10,0x39,0x87,0x89,0x40,0x00,0x5d,0x41,0x34,0x98,0x34,0x7e,0x54,0x41, +0x7b,0x26,0x62,0x68,0x93,0xc7,0x92,0x47,0x9b,0x57,0x93,0x8b,0x83,0x85,0x72,0x12, +0x6a,0x2a,0x63,0xc6,0x83,0xe9,0x95,0x25,0x9c,0x31,0x10,0x9d,0x87,0x88,0x30,0x00, +0x84,0x68,0x94,0x2b,0x83,0xb4,0x7b,0x28,0x6b,0xa6,0x43,0x68,0x1b,0x68,0x53,0x48, +0x53,0x52,0x7b,0xa7,0xa2,0x4a,0xa1,0x99,0x81,0x94,0x82,0x9a,0x42,0x72,0x7b,0xcc, +0x9c,0x31,0x10,0xb7,0x87,0x97,0x20,0x00,0xbe,0x39,0xa1,0x3c,0xa5,0xa2,0xbc,0xaa, +0xa1,0x43,0x70,0xbd,0x95,0x5a,0xaa,0x3a,0x62,0x4c,0x8a,0x42,0x76,0x34,0x62,0xb2, +0x5a,0x3c,0x9a,0xba,0x7d,0xbc,0xa2,0x32,0x9c,0x31,0x10,0xea,0x77,0x75,0x20,0x00, +0xbd,0x8e,0x8d,0x40,0x24,0x22,0x72,0xe2,0x25,0x2a,0x3d,0x16,0x24,0x2a,0xc2,0x2d, +0x9a,0xd3,0xc2,0x11,0xe6,0xb5,0xc3,0xd1,0xad,0xa4,0xe4,0xae,0xea,0x98,0xd3,0xc4, +0x9c,0x31,0x10,0x0e,0x78,0x76,0x20,0x00,0x9c,0x52,0xc3,0xd3,0x74,0x9a,0x3b,0x5c, +0x33,0x5a,0x3b,0x6b,0x73,0x9a,0x72,0xe3,0x92,0xa5,0x83,0x93,0x5e,0x4c,0x0c,0xe3, +0x21,0x4a,0x29,0x9d,0x74,0xa1,0xe4,0x4b,0x9c,0x31,0x10,0x8f,0xb8,0x65,0x30,0x00, +0x8f,0x9a,0x87,0x44,0x87,0x3a,0x70,0x4c,0x6c,0x95,0x68,0x49,0x7b,0x2c,0x8d,0x68, +0xa6,0xe5,0xa8,0xc8,0x8a,0xf2,0x5e,0xce,0x3b,0x0a,0x3b,0x16,0x73,0x11,0xb2,0x90, +0x9c,0x31,0x10,0x7d,0xc9,0x76,0x30,0x00,0xa7,0x11,0xa5,0x4d,0x88,0xb1,0x60,0xf1, +0x44,0x69,0x44,0xa0,0x8f,0x56,0x9d,0x71,0xba,0xc5,0xb0,0x89,0x91,0x31,0x5b,0x12, +0x3a,0xc9,0x33,0x2d,0x8e,0xad,0x8c,0xf0,0x9c,0x31,0x10,0x6b,0xca,0x66,0x20,0x00, +0xb4,0xf9,0xb0,0xf5,0xa5,0x05,0x70,0xc5,0x4b,0x45,0x22,0x81,0x73,0x65,0x8a,0xe5, +0x9d,0x14,0xb4,0xa1,0xa9,0x05,0x93,0x15,0x5e,0xf6,0x33,0x19,0x3b,0x34,0x94,0x65, +0x9c,0x31,0x10,0x3e,0xca,0x75,0x10,0x00,0x82,0x93,0xb3,0x93,0xab,0x73,0xa4,0x73, +0x82,0x7b,0x55,0x83,0x27,0x4b,0x69,0xe1,0x92,0x3b,0x8e,0x84,0xb6,0x73,0x9f,0x92, +0xa0,0x5b,0x72,0x84,0x4d,0x8a,0x25,0x39,0x9c,0x31,0x10,0x05,0xca,0x74,0x00,0x00, +0x8a,0xc3,0x86,0x74,0x9c,0x7b,0xaf,0x63,0x9e,0x9c,0x98,0x5d,0x6f,0x9b,0x41,0x7a, +0x32,0x44,0x9a,0x7d,0x7c,0xa3,0xa9,0x71,0xa9,0x63,0xa0,0xa5,0x8f,0x53,0x68,0x92, +0x9c,0x31,0x10,0x3e,0xca,0x75,0x10,0x00,0x30,0x8b,0x49,0x7e,0xa0,0x2d,0x7b,0xba, +0xb0,0x72,0xa4,0x64,0xa1,0x9c,0x8a,0x62,0x64,0x8a,0x27,0x85,0x5d,0xc6,0x9c,0x02, +0x7e,0xc9,0xb5,0x6b,0x9d,0x6d,0xa1,0x93,0x9c,0x31,0x10,0x8a,0xca,0x75,0x00,0x00, +0x80,0x69,0x5e,0x7b,0x1e,0x65,0x78,0xeb,0x93,0x09,0x87,0xaa,0xb4,0x74,0x9a,0x7d, +0xa1,0x7a,0x7b,0x81,0x55,0x6b,0x18,0x43,0x8e,0xf1,0x87,0x3a,0x91,0x83,0xb4,0x75, +0x9c,0x31,0x10,0x8a,0xca,0x75,0x00,0x00,0x9a,0x83,0x9f,0x72,0x77,0x8b,0x4b,0x63, +0x1e,0x42,0x98,0xc9,0x82,0x73,0x99,0x6c,0xae,0x73,0x9c,0x8a,0x9b,0x5a,0x74,0x93, +0x40,0x83,0x26,0x2a,0xa0,0x9b,0x7d,0x9c,0x9c,0x31,0x10,0x05,0xca,0x74,0x00,0x00, +0xa1,0x6c,0xae,0x63,0x9c,0x99,0x99,0x53,0x6f,0x94,0x37,0x83,0x30,0x41,0xa3,0x63, +0x7c,0xbc,0xa4,0x7b,0xad,0x5a,0x9e,0x8a,0x94,0x64,0x6d,0x94,0x2f,0x83,0x37,0x6a, +0x9c,0x31,0x10,0x05,0xca,0x74,0x00,0x00,0xa6,0x34,0x79,0xb5,0xa6,0x8c,0xac,0x5a, +0x9f,0x82,0x8f,0x6c,0x69,0x94,0x29,0x83,0x41,0x94,0xaa,0x15,0x7b,0xa3,0xa7,0x9a, +0xac,0x63,0x9f,0x7c,0x8b,0x6c,0x62,0x93,0x9c,0x31,0x10,0x05,0xca,0x74,0x00,0x00, +0x23,0x7b,0x4f,0xbe,0xaa,0x1e,0x7e,0x73,0xa7,0xa2,0xac,0x84,0x9c,0x74,0x86,0x5a, +0x58,0x92,0x1e,0x6d,0x64,0xd5,0xa7,0x42,0x82,0x62,0xaa,0x82,0xa9,0x9c,0x9f,0x83, +0x9c,0x31,0x10,0x8a,0xca,0x75,0x00,0x00,0x7f,0x5a,0x53,0x7b,0x1d,0x64,0x6d,0xd3, +0xa5,0x72,0x88,0x62,0xa7,0x62,0xab,0x8b,0x9e,0x93,0x77,0x72,0x4a,0x73,0x22,0x3b, +0x7c,0xb0,0xa2,0xa1,0x8e,0x7b,0xa5,0x4c,0x9c,0x31,0x10,0xbf,0xc9,0x74,0x00,0x00, +0xaa,0xad,0x9b,0x4d,0x6f,0x4d,0x3e,0xea,0x28,0x21,0x88,0x64,0x9f,0x70,0x93,0xb1, +0xa4,0xcd,0xac,0x6a,0x94,0x8d,0x63,0x4d,0x31,0x48,0x39,0x32,0x94,0x1a,0x9e,0x75, +0x9c,0x31,0x10,0x30,0xc9,0x75,0x00,0x00,0x99,0x2d,0xa5,0x69,0xab,0x31,0x90,0xb1, +0x5a,0xad,0x28,0xce,0x47,0xb4,0x98,0xf1,0xa2,0xad,0x9a,0x89,0xa0,0xed,0xab,0x2d, +0x89,0x09,0x4f,0x09,0x26,0x71,0x57,0x46,0x9c,0x31,0x10,0xad,0xc8,0x75,0x00,0x00, +0x9d,0xc1,0xa5,0xa8,0x9a,0xd1,0xa0,0x71,0xa8,0x8e,0x82,0xe9,0x47,0x09,0x26,0x64, +0x60,0xc1,0x9d,0x06,0xa7,0x6d,0x9b,0x51,0x9b,0x0d,0x9e,0xcd,0x78,0xcd,0x46,0xcd, +0x9c,0x31,0x10,0xb0,0xc8,0x63,0x00,0x00,0x3b,0x69,0x6c,0x3c,0x98,0x4d,0xa7,0x6b, +0x9e,0x7a,0x94,0x92,0x8d,0x8a,0x77,0x83,0x60,0x8c,0x59,0x95,0x68,0x75,0x83,0x6d, +0x98,0x64,0x97,0x5b,0x90,0x93,0x8e,0x73,0x9c,0x31,0x10,0x03,0xa4,0x42,0x00,0x00, +0x93,0xca,0x57,0x65,0x22,0x64,0x18,0x05,0x45,0x51,0x8d,0x30,0xc3,0x2d,0xdb,0x4d, +0xd3,0x4d,0xaa,0x8d,0x71,0x2d,0x3b,0x2d,0x1b,0x4d,0x2e,0x8d,0x6e,0x8d,0xb0,0x69, +0x9c,0x31,0x10,0x33,0xa3,0x31,0x00,0x00,0xd3,0x61,0xcf,0x48,0xa9,0xca,0x73,0x6c, +0x45,0x0d,0x2c,0x2c,0x3a,0x2e,0x6b,0xcc,0xa3,0x6e,0xc6,0x4c,0xc5,0x31,0xa3,0xcc, +0x73,0xb5,0x4f,0x51,0x41,0x4c,0x4f,0x0e,0x9c,0x31,0x10,0xc8,0x93,0x22,0x00,0x00, +0x67,0xa3,0xb2,0xd3,0xe1,0x23,0xde,0x0a,0xac,0x8b,0x6f,0x94,0x44,0xdb,0x37,0x22, +0x4a,0x2b,0x77,0x5a,0x9d,0x53,0xad,0x62,0xa6,0x9a,0x8c,0x65,0x75,0x24,0x66,0xd9, +0x9c,0x31,0x10,0x00,0x73,0x33,0x10,0x00,0x13,0x63,0x42,0x68,0x90,0x8e,0xba,0xda, +0xc3,0x1a,0xad,0x5b,0x7e,0x5b,0x62,0xdb,0x6a,0x9a,0x75,0x1c,0x7c,0xe3,0x8a,0x5b, +0x84,0xe3,0x7e,0xcb,0x7d,0x9a,0x6c,0xc8,0x9c,0x31,0x10,0x78,0x67,0x77,0x30,0x00, +0x63,0xbb,0x7b,0x32,0x93,0x4b,0x83,0xbd,0x7b,0xbb,0x54,0x2c,0x63,0xba,0x73,0xba, +0x84,0x43,0x75,0x25,0x7b,0xc3,0x83,0xb2,0x9d,0xdd,0x2c,0xb1,0x2a,0xb9,0x0c,0x3c, +0x9c,0x31,0x10,0xe9,0x64,0x45,0x30,0x00,0x32,0x74,0x3b,0x70,0x8b,0xb1,0x93,0x4d, +0x92,0x8d,0x83,0x4d,0x63,0xa9,0x5b,0x69,0x75,0xb5,0x8b,0x35,0x73,0x89,0x7a,0x49, +0x8b,0x49,0x73,0x89,0x53,0x6d,0x52,0x6d,0x9c,0x31,0x10,0xeb,0x76,0x77,0x40,0x00, +0x73,0x6d,0x7b,0x6d,0x83,0x6d,0x73,0x6d,0x7b,0x6d,0x7b,0x6d,0x73,0x6d,0x63,0x6d, +0x6b,0x6d,0x73,0x6d,0x83,0x6d,0x8b,0x6d,0xf6,0xba,0xcb,0x32,0xe4,0x82,0xa9,0x66, +0x9c,0x31,0x10,0x59,0x86,0x79,0x60,0x00,0xcc,0x8d,0x65,0x4d,0x2c,0x8d,0x4c,0x6d, +0x53,0x8d,0x53,0x51,0x5b,0x6d,0x62,0x45,0x6b,0xb0,0x73,0x4c,0x79,0x69,0x82,0x55, +0x8b,0x32,0x93,0xce,0x92,0x2e,0x8b,0x8a,0x9c,0x31,0x10,0x90,0x76,0x88,0x60,0x00, +0x76,0xa5,0x67,0x2d,0x55,0x08,0x56,0xa4,0x68,0xec,0x74,0xb8,0x87,0x50,0x94,0xe9, +0xe8,0x99,0xe0,0xf5,0x37,0x8a,0x24,0x92,0x37,0x52,0x56,0xc2,0x47,0x71,0x56,0xc5, +0x9c,0x31,0x10,0x0c,0x65,0x8a,0x60,0x00,0x59,0xd9,0x54,0x21,0x33,0x1d,0x31,0x95, +0x62,0x71,0xa0,0xd5,0xa6,0xd1,0xea,0x29,0xd9,0x98,0xa6,0x50,0xa6,0x64,0x65,0x9c, +0x51,0x60,0x36,0x21,0x69,0xdd,0x96,0x66,0x9c,0x31,0x10,0xa5,0x75,0x89,0x60,0x00, +0x75,0x1e,0x76,0xc2,0x8a,0x2d,0x85,0x25,0x79,0x85,0x62,0x25,0x56,0x69,0x84,0x95, +0xc5,0xd9,0xd6,0xa5,0xda,0x59,0xc4,0xd9,0x79,0xdd,0x25,0xdd,0x06,0x19,0x45,0x9d, +0x9c,0x31,0x10,0xeb,0xb4,0x78,0x40,0x00,0x82,0x65,0x89,0x4e,0x8e,0x16,0x8b,0x13, +0x7f,0x5e,0x6c,0xa4,0x60,0xb7,0x62,0x98,0x76,0xe5,0x99,0x29,0xb2,0xa5,0xae,0xc9, +0x88,0xc7,0x58,0xc6,0x37,0x19,0x2c,0xd5,0x9c,0x31,0x10,0x1c,0xc6,0x78,0x30,0x00, +0x6d,0x14,0x98,0xdb,0xb6,0xcb,0xb0,0xeb,0x90,0xe3,0x70,0x93,0x59,0x1b,0x3c,0x6b, +0x47,0x15,0x7e,0x91,0xb0,0xe3,0xb7,0x1c,0xa2,0xd9,0x9a,0xd3,0x94,0xd4,0x6e,0xab, +0x9c,0x31,0x10,0xa6,0xc6,0x87,0x20,0x00,0x37,0x5d,0x25,0x2a,0x5c,0xd0,0xa4,0xd8, +0xbe,0xaa,0xa9,0x18,0x96,0xde,0x9c,0xdd,0x8e,0x9c,0x58,0xe2,0x24,0x61,0x2d,0x48, +0x76,0xa1,0xb7,0x29,0xba,0xd1,0x9c,0xd5,0x9c,0x31,0x10,0xa6,0xc6,0x87,0x20,0x00, +0x95,0x29,0xa0,0xd8,0x8c,0x95,0x53,0x29,0x20,0x11,0x31,0x4d,0x80,0xb1,0xb9,0x19, +0xb6,0xcd,0x98,0xe5,0x95,0x28,0xa5,0x16,0x90,0x99,0x56,0xe5,0x22,0xa2,0x2b,0x88, +0x9c,0x31,0x10,0x1c,0xc5,0x87,0x20,0x00,0x76,0x44,0xb4,0xda,0xb6,0xa4,0x9b,0x32, +0x94,0xcb,0xa8,0xb5,0x98,0xb1,0x5e,0xc4,0x27,0x42,0x21,0x4c,0x68,0x9b,0xae,0xd3, +0xba,0xc3,0x9d,0x2b,0x92,0xba,0xa7,0x4d,0x9c,0x31,0x10,0xb3,0xc7,0x77,0x20,0x00, +0xa4,0xd0,0x70,0xc4,0x37,0x33,0x1e,0x49,0x48,0xed,0x96,0x9a,0xba,0xd3,0xa6,0xe4, +0x90,0xd2,0x9c,0xe4,0xac,0xc1,0x8c,0xf3,0x50,0xd4,0x26,0xd2,0x2d,0x22,0x70,0xd5, +0x9c,0x31,0x10,0xb3,0xc7,0x77,0x20,0x00,0xac,0xea,0xb2,0xd4,0x98,0xd2,0x92,0xe4, +0xa8,0xd2,0xa6,0xec,0x76,0xc3,0x40,0xd9,0x24,0x5c,0x41,0x1d,0x86,0xa8,0xb0,0xd6, +0xa8,0xda,0x92,0xeb,0x98,0xdb,0xaa,0xdc,0x9c,0x31,0x10,0x2e,0xc6,0x77,0x20,0x00, +0x9c,0xd9,0x6a,0xdc,0x3d,0x22,0x28,0x19,0x4f,0x35,0x8e,0x83,0xb1,0x23,0xa4,0xe3, +0x90,0xd3,0x9c,0xe2,0xab,0x25,0x96,0xc1,0x66,0xeb,0x3d,0x5c,0x2c,0x5a,0x50,0xf3, +0x9c,0x31,0x10,0x93,0xc5,0x86,0x20,0x00,0x8e,0x1e,0xb0,0xd1,0xa4,0xb4,0x92,0xb3, +0x9a,0x49,0xa7,0x2e,0x94,0xbb,0x66,0xc0,0x41,0x2e,0x2e,0x48,0x4e,0xc3,0x88,0x25, +0xaa,0xd1,0xa6,0xae,0x96,0xb9,0x9a,0xc3,0x9c,0x31,0x10,0x69,0xc6,0x78,0x10,0x00, +0xa5,0x1b,0x95,0x1a,0x6e,0x94,0x4f,0x23,0x38,0x12,0x47,0x35,0x72,0x8a,0x92,0xe4, +0xa4,0xe3,0xac,0x93,0xb2,0xec,0xab,0x0a,0x8f,0x23,0x6a,0x93,0x4d,0x1b,0x38,0x5c, +0x9c,0x31,0x10,0x5b,0xc5,0x88,0x10,0x00,0x3f,0x22,0x6a,0x63,0x91,0x1c,0xa6,0xcb, +0xac,0xb3,0xb0,0xb3,0xaa,0xca,0x94,0xb3,0x72,0xc3,0x56,0xbb,0x40,0xbb,0x3b,0x3a, +0x5a,0xb5,0x83,0x4a,0xa0,0xac,0xac,0xcb,0x9c,0x31,0x10,0x4d,0xc5,0x67,0x10,0x00, +0xb3,0x4b,0xb0,0x5a,0x9e,0x65,0x7e,0x51,0x61,0x5c,0x4a,0x9b,0x39,0x23,0x4c,0x61, +0x75,0x06,0x97,0x70,0xaa,0x4d,0xb0,0x62,0xb3,0x5c,0xa7,0x9a,0x8a,0x5c,0x6c,0x62, +0x9c,0x31,0x10,0x55,0xc5,0x77,0x10,0x00,0x56,0x5c,0x41,0x1b,0x40,0x8b,0x60,0x2a, +0x85,0x4d,0xa2,0x69,0xae,0x4d,0xb2,0x62,0xac,0x54,0x97,0x63,0x7a,0x53,0x64,0x64, +0x50,0x9b,0x3d,0x24,0x4b,0x99,0x70,0x1e,0x9c,0x31,0x10,0xd1,0xc5,0x57,0x00,0x00, +0x92,0x91,0xa7,0x4d,0xb0,0x8a,0xb2,0x2b,0xa4,0x8b,0x8c,0x63,0x74,0x73,0x61,0x63, +0x4b,0x92,0x3f,0x83,0x55,0x6d,0x79,0x68,0x99,0x8d,0xaa,0x49,0xb1,0xac,0xaf,0x4b, +0x9c,0x31,0x10,0x10,0xb4,0x66,0x00,0x00,0xbf,0x1a,0x8c,0x64,0x5d,0x13,0x34,0xa4, +0x0c,0x4c,0x05,0x62,0x3a,0x5a,0x84,0xdd,0xc1,0x19,0xda,0x9d,0xe5,0x11,0xd6,0xe4, +0xb3,0x1b,0x80,0x9a,0x56,0xe4,0x2d,0x52,0x9c,0x31,0x10,0xa5,0xb5,0x56,0x00,0x00, +0x04,0x53,0x07,0x75,0x46,0x82,0x8e,0xf3,0xc8,0xc4,0xe0,0xe9,0xe6,0xd5,0xd2,0xe0, +0xaa,0x9d,0x78,0xda,0x4e,0xa3,0x27,0x14,0x02,0x59,0x0f,0x64,0x50,0x94,0x9b,0x22, +0x9c,0x31,0x10,0xbd,0xb5,0x46,0x00,0x00,0xcc,0x94,0xe1,0x22,0xe2,0x8b,0xcb,0x23, +0xa0,0x9b,0x72,0xdb,0x4c,0x9b,0x27,0x1b,0x08,0x5b,0x17,0xa2,0x56,0x95,0x9b,0x11, +0xcc,0xb5,0xdd,0x02,0xde,0xb3,0xcb,0x44,0x9c,0x31,0x10,0x31,0xb5,0x45,0x00,0x00, +0xa2,0xea,0x75,0x0c,0x4c,0xa2,0x29,0x1c,0x0c,0x5a,0x19,0xab,0x56,0x8d,0x9b,0x58, +0xc8,0x66,0xdd,0x12,0xdc,0x9a,0xc9,0x55,0xa4,0xe1,0x79,0x1d,0x50,0x52,0x2d,0x23, +0x9c,0x31,0x10,0x31,0xb5,0x45,0x00,0x00,0x10,0x13,0x19,0xaa,0x4e,0x8d,0x91,0x18, +0xc2,0x66,0xd9,0x11,0xdc,0xab,0xcd,0x4c,0xac,0xaa,0x80,0xd4,0x58,0x9a,0x35,0x24, +0x16,0x93,0x15,0xac,0x44,0x93,0x82,0xe3,0x9c,0x31,0x10,0x23,0xb4,0x44,0x00,0x00, +0xb6,0x54,0xd1,0x2a,0xda,0x9c,0xcb,0x5a,0xb0,0x5e,0x88,0xd8,0x64,0xa5,0x3f,0x13, +0x1c,0xe2,0x13,0xa4,0x3a,0x60,0x76,0x9e,0xae,0xd1,0xcc,0xe3,0xd9,0x14,0xcc,0x99, +0x9c,0x31,0x10,0xf6,0xb5,0x34,0x00,0x00,0xb8,0x64,0x93,0x6a,0x6e,0x8c,0x47,0x63, +0x25,0x8a,0x11,0x4b,0x2f,0x74,0x6a,0x4a,0xa6,0x8b,0xc9,0x6c,0xd8,0x8a,0xd4,0x2d, +0xc1,0x61,0x9b,0x4b,0x72,0xac,0x49,0x49,0x9c,0x31,0x10,0xf6,0xb5,0x34,0x00,0x00, +0x29,0x8d,0x10,0x02,0x24,0x83,0x5c,0x4b,0x9a,0xb3,0xc4,0x4b,0xd7,0xaa,0xd5,0x2c, +0xc3,0xab,0xa3,0x4c,0x7c,0xab,0x56,0x33,0x34,0xab,0x17,0x0b,0x1c,0xc4,0x4e,0x43, +0x9c,0x31,0x10,0xf3,0xb5,0x32,0x00,0x00,0x8c,0xc5,0xbc,0x3a,0xd3,0x95,0xd8,0x45, +0xca,0xc4,0xae,0x55,0x86,0x91,0x60,0x35,0x3c,0x95,0x1f,0x55,0x16,0xb9,0x3d,0x59, +0x78,0x74,0xb0,0x56,0xce,0x75,0xd9,0x75,0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00, +0xcf,0x8a,0xb7,0x58,0x91,0x5a,0x6c,0x64,0x48,0x65,0x2a,0x95,0x16,0x25,0x2f,0x75, +0x66,0x35,0xa1,0xc9,0xc4,0x41,0xd4,0xc1,0xd0,0x10,0xbe,0x86,0x9c,0x51,0x76,0xb5, +0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00,0x4f,0x65,0x2f,0xa1,0x17,0x21,0x25,0xa1, +0x59,0x50,0x97,0xb5,0xc2,0x51,0xd5,0xa5,0xd4,0x35,0xc4,0xb1,0xa6,0x51,0x7f,0xb5, +0x59,0x45,0x37,0xb5,0x1d,0x46,0x1f,0xc0,0x9c,0x31,0x10,0x7f,0xb5,0x31,0x00,0x00, +0x4c,0x2b,0x87,0x52,0xb8,0x2c,0xd0,0x44,0xd5,0x2b,0xc8,0x5b,0xae,0x2a,0x88,0x4b, +0x62,0xa4,0x40,0x4c,0x25,0x34,0x1c,0x4d,0x3f,0x25,0x77,0x3c,0xae,0x33,0xcc,0x3b, +0x9c,0x31,0x10,0xe2,0xb4,0x31,0x00,0x00,0xd7,0x52,0xcd,0x44,0xb8,0x24,0x93,0x24, +0x6d,0x33,0x49,0x28,0x2d,0xd2,0x1a,0x82,0x30,0xbb,0x65,0x1a,0x9e,0x64,0xc2,0x22, +0xd1,0xe3,0xce,0x0a,0xbe,0xbb,0x9d,0x9b,0x9c,0x31,0x10,0x7f,0xb5,0x31,0x00,0x00, +0x77,0x4c,0x50,0xb2,0x33,0xd3,0x1e,0x1a,0x2a,0xd9,0x5a,0xaa,0x94,0x5b,0xbe,0x2c, +0xd0,0x4b,0xd0,0x1a,0xc1,0xd2,0xa4,0xb3,0x7e,0xd4,0x59,0xab,0x3b,0x53,0x23,0x2c, +0x9c,0x31,0x10,0xf3,0xb5,0x32,0x00,0x00,0x23,0xc9,0x4c,0x55,0x84,0x95,0xb4,0x45, +0xca,0x85,0xce,0x55,0xc3,0xb5,0xac,0x65,0x88,0x95,0x62,0x55,0x41,0x95,0x28,0x64, +0x22,0xa9,0x46,0x66,0x7c,0x74,0xae,0x65,0x9c,0x31,0x10,0x16,0xb3,0x31,0x00,0x00, +0xc7,0x71,0xce,0x6c,0xc3,0xd5,0xaf,0x2e,0x8b,0x4d,0x67,0x0a,0x45,0x91,0x2d,0xb0, +0x23,0x96,0x42,0x30,0x75,0x12,0xa7,0x49,0xc3,0x4d,0xcd,0xc9,0xc4,0x75,0xb1,0x50, +0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00,0x90,0x56,0x6c,0x75,0x4a,0x75,0x31,0xa5, +0x25,0x69,0x42,0x58,0x73,0x2a,0xa3,0x95,0xbf,0x65,0xca,0xb5,0xc1,0x34,0xae,0x85, +0x91,0x46,0x70,0xa4,0x4f,0x66,0x37,0xa1,0x9c,0x31,0x10,0xe2,0xb4,0x31,0x00,0x00, +0x2b,0xac,0x45,0xb4,0x71,0x9d,0x9e,0x53,0xb9,0x33,0xc5,0x5b,0xbe,0xac,0xae,0xc4, +0x91,0x22,0x70,0x42,0x50,0xb3,0x3a,0x4a,0x31,0xbe,0x4c,0x43,0x77,0x2b,0x9f,0xba, +0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00,0xb7,0x65,0xc0,0xa0,0xb9,0x89,0xa8,0x75, +0x8b,0x75,0x6b,0x66,0x4d,0x85,0x3a,0x65,0x38,0xb5,0x57,0x76,0x80,0x74,0xa5,0x55, +0xb8,0x85,0xbc,0x54,0xb3,0x85,0x9c,0x65,0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00, +0x7b,0x88,0x5a,0x65,0x44,0x85,0x3a,0x30,0x48,0xa2,0x6d,0x64,0x95,0x95,0xb1,0x56, +0xbc,0x80,0xb8,0x45,0xa4,0x65,0x85,0x79,0x61,0x85,0x48,0x75,0x3d,0x75,0x47,0x85, +0x9c,0x31,0x10,0xbb,0xb2,0x11,0x00,0x00,0x69,0x05,0x93,0x25,0xb2,0x81,0xbf,0x59, +0xb8,0x66,0x9f,0x88,0x7c,0xb9,0x59,0xb0,0x43,0x55,0x3f,0xb6,0x52,0x39,0x77,0x19, +0x9f,0xc5,0xbb,0x25,0xc2,0x69,0xb3,0xa0,0x9c,0x31,0x10,0x1f,0xb2,0x22,0x00,0x00, +0x91,0x6d,0x66,0x09,0x43,0x96,0x37,0x4d,0x44,0x44,0x68,0x4d,0x97,0x6d,0xbe,0x50, +0xcc,0x69,0xbc,0x89,0x92,0x4e,0x61,0x92,0x3c,0x89,0x30,0x4d,0x42,0x4d,0x6c,0x91, +0x9c,0x31,0x10,0x90,0xb2,0x23,0x00,0x00,0x9d,0xad,0xc2,0x69,0xcc,0x69,0xb8,0x49, +0x8e,0x6d,0x61,0x71,0x41,0xb1,0x39,0x45,0x4c,0x6d,0x72,0x29,0x9b,0x2d,0xb7,0x69, +0xbd,0x75,0xab,0x40,0x8a,0x52,0x67,0x65,0x9c,0x31,0x10,0x5d,0xa3,0x56,0x10,0x00, +0x1e,0xb7,0x16,0xa8,0x34,0x26,0x6e,0x62,0xaa,0x9c,0xd2,0x45,0xda,0x29,0xbc,0xc5, +0x88,0xa9,0x54,0xb6,0x34,0xb7,0x36,0xb7,0x50,0xb7,0x7c,0xb7,0xa6,0xb7,0xbc,0xb7, +0x9c,0x31,0x10,0x60,0x91,0x23,0x00,0x00,0xf2,0x4b,0xbf,0x69,0x77,0x24,0x39,0x5b, +0x1f,0x5a,0x2f,0x4c,0x5d,0x5b,0x93,0x12,0xba,0x9c,0xc5,0x5a,0xb2,0x63,0x8d,0x13, +0x67,0x73,0x51,0x54,0x51,0x99,0x63,0x5c,0x9c,0x31,0x10,0x70,0x82,0x22,0x00,0x00, +0x7c,0xdc,0xaa,0x6b,0xc1,0x13,0xbb,0x1a,0x9c,0xe2,0x78,0xe5,0x60,0xd2,0x58,0xd2, +0x64,0x8d,0x76,0xd9,0x8b,0x16,0x94,0xd2,0x93,0x1a,0x8a,0xdc,0x82,0xd2,0x7a,0x94, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_CONNECTED.txt b/config/_default_cfg_src_/res/en/SOUND_CONNECTED.txt new file mode 100644 index 0000000..908e13d --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_CONNECTED.txt @@ -0,0 +1,330 @@ +0x9c,0x31,0x10,0xa2,0x34,0x44,0x10,0x00,0x77,0x77,0x77,0x77,0x77,0x77,0x67,0x67, +0x36,0x99,0x66,0x66,0x6b,0x5a,0x75,0x44,0xa9,0xb4,0xb2,0xaa,0xb7,0x59,0xa7,0x86, +0xa2,0x65,0xe7,0x6c,0x77,0x88,0xe4,0xd9,0x9c,0x31,0x10,0xa2,0x34,0x44,0x10,0x00, +0x59,0xa5,0xc9,0x51,0x6b,0x67,0x4a,0x25,0xdb,0x58,0xa7,0x86,0xe0,0x95,0xb5,0x5d, +0xc8,0x29,0x65,0x58,0xea,0x32,0x98,0x57,0x98,0x99,0xa3,0x1c,0xb5,0x64,0xca,0xd1, +0x9c,0x31,0x10,0xce,0x44,0x55,0x10,0x00,0xac,0x33,0x6d,0x33,0x6b,0xcb,0x8c,0x43, +0xa3,0x4c,0x81,0xb2,0xaa,0xbb,0x62,0xd3,0x8b,0x93,0x5b,0xaa,0x3b,0x45,0x5e,0x09, +0x84,0xb3,0x42,0x54,0x7d,0x43,0x42,0x32,0x9c,0x31,0x10,0xf5,0x44,0x54,0x00,0x00, +0x7c,0x32,0x73,0x45,0x55,0x26,0x3d,0xb9,0x5d,0x0a,0x45,0x32,0x5c,0x34,0x3b,0x49, +0x8b,0x63,0xb2,0xb3,0x6a,0x29,0x7c,0x46,0x76,0x2d,0x76,0xc9,0x7d,0x3a,0x82,0x4b, +0x9c,0x31,0x10,0xab,0x44,0x66,0x20,0x00,0x63,0x77,0x9c,0x97,0x88,0x55,0x61,0x49, +0x6b,0x76,0x84,0x69,0xb0,0x76,0xa8,0x89,0xa3,0x77,0xcc,0x47,0x9b,0x85,0x5a,0x53, +0xa5,0x5a,0xd9,0xb8,0x62,0x67,0x59,0x6a,0x9c,0x31,0x10,0x8c,0x46,0x66,0x20,0x00, +0xa8,0x77,0x38,0x87,0x76,0x74,0x38,0x95,0x97,0x69,0x56,0x88,0x74,0x47,0x95,0x36, +0x25,0x56,0x55,0x88,0xd4,0x78,0x35,0x76,0xc3,0x57,0x21,0x8a,0xb3,0x72,0x14,0x65, +0x9c,0x31,0x10,0x05,0x56,0x76,0x30,0x00,0xa6,0x79,0x37,0x98,0x71,0x7c,0x83,0x78, +0x94,0x66,0x64,0x99,0x45,0x91,0x66,0x55,0x74,0x87,0x86,0x89,0x68,0xb6,0x65,0x4c, +0xb4,0x85,0x57,0x79,0x77,0x85,0x67,0xa5,0x9c,0x31,0x10,0xd7,0x78,0x66,0x10,0x00, +0x8b,0xa1,0x7c,0x2e,0x54,0x22,0x8c,0x1b,0x94,0x8b,0x8b,0xeb,0x7c,0x1a,0x93,0x9c, +0x8b,0xcc,0x7b,0x94,0x74,0x1b,0x73,0xd2,0x74,0x1b,0x6b,0xd3,0xbb,0xd3,0xb1,0xcd, +0x9c,0x31,0x10,0x9a,0x67,0x66,0x10,0x00,0x1d,0xca,0x5b,0x53,0x8b,0xcb,0x6b,0xc2, +0x83,0x43,0xa4,0x63,0x9b,0xb2,0x4c,0x35,0x53,0x81,0x5b,0xd4,0x4a,0x2b,0x53,0x34, +0x33,0x32,0x72,0x1b,0x7a,0x63,0x6b,0xa1,0x9c,0x31,0x10,0x3f,0x87,0x67,0x20,0x00, +0x71,0x1c,0x71,0x1b,0x71,0x13,0x75,0x93,0x71,0x83,0x58,0xcb,0x88,0xe2,0x8a,0x13, +0x81,0x1a,0x92,0xb5,0x6d,0xab,0x7a,0x0b,0x7d,0x63,0x66,0x8b,0x39,0x4b,0x79,0xf4, +0x9c,0x31,0x10,0x68,0x99,0x77,0x40,0x00,0x71,0xdc,0x69,0xd2,0x59,0x93,0x71,0xdb, +0x69,0xd3,0x79,0x9c,0x9d,0xda,0x7d,0xd2,0x71,0xdb,0x76,0x1b,0x81,0xdc,0xa6,0x13, +0x99,0xee,0xe6,0xda,0x91,0xa2,0x41,0x63,0x9c,0x31,0x10,0x69,0xc7,0x65,0x10,0x00, +0x79,0x50,0x7c,0x71,0x7a,0x2e,0x7d,0x44,0x80,0x88,0x7a,0x75,0x74,0x69,0x77,0x72, +0x82,0x95,0x8e,0x28,0x8b,0x4c,0x79,0x51,0x60,0x6e,0x5e,0x91,0x91,0x92,0xc5,0x30, +0x9c,0x31,0x10,0xe4,0xca,0x67,0x20,0x00,0xb4,0xf5,0x62,0xd5,0x2d,0x01,0x43,0x05, +0xb4,0xf5,0xda,0xf1,0xbc,0xf5,0x7a,0xe5,0x37,0x25,0x20,0xc6,0x9e,0xc1,0xd4,0xd1, +0xb5,0x34,0x93,0x25,0x5d,0x16,0x0a,0x61,0x9c,0x31,0x10,0x56,0xda,0x76,0x20,0x00, +0x6d,0x55,0xab,0x34,0x99,0x24,0x8e,0xd5,0x80,0xb6,0x53,0x06,0x4b,0x39,0x9e,0xa4, +0x9e,0xa4,0x8d,0x05,0x91,0x02,0x6b,0x32,0x3a,0x50,0x81,0x84,0xa9,0x25,0x87,0x36, +0x9c,0x31,0x10,0x4e,0xda,0x66,0x20,0x00,0x96,0xb9,0x82,0xb9,0x49,0x09,0x55,0x88, +0xaa,0x85,0x8a,0x96,0x90,0xe5,0x99,0x04,0x63,0x70,0x3c,0x54,0x8d,0x75,0x98,0xea, +0x85,0x49,0xa2,0xb5,0x7e,0xc9,0x48,0xf4,0x9c,0x31,0x10,0xdf,0xca,0x66,0x30,0x00, +0x41,0x45,0xc8,0x56,0x80,0xf1,0xbb,0x21,0xa7,0x04,0x4b,0x31,0x10,0x36,0x97,0xb5, +0xa0,0xe9,0x93,0x39,0xc4,0x98,0x74,0xe9,0x2d,0x09,0x3b,0x39,0xbc,0x46,0x7d,0x25, +0x9c,0x31,0x10,0xcd,0xcb,0x67,0x30,0x00,0xbf,0x11,0x9e,0xe5,0x55,0x05,0x1c,0xa5, +0x8d,0x86,0x9a,0xc9,0x98,0xf5,0xc0,0xc9,0x79,0x15,0x3d,0x11,0x38,0xea,0xb4,0xa5, +0x81,0x21,0xb9,0x11,0x9a,0xd5,0x60,0xf9,0x9c,0x31,0x10,0xcd,0xcb,0x67,0x30,0x00, +0x22,0xc9,0x83,0x86,0x9e,0x99,0x93,0x04,0xba,0xd5,0x7b,0x15,0x4b,0x01,0x32,0xb6, +0xae,0xf5,0x85,0x24,0xb1,0x01,0x9c,0xe5,0x69,0x06,0x2a,0xca,0x77,0x85,0xa0,0x78, +0x9c,0x31,0x10,0xd5,0xcb,0x77,0x30,0x00,0x8d,0x14,0xb8,0xd5,0x81,0x16,0x56,0xf6, +0x32,0xb1,0xa9,0x24,0x85,0x05,0xaa,0xf5,0x9e,0xd6,0x6d,0x15,0x38,0xe9,0x65,0x44, +0xa6,0x74,0x87,0x26,0xb8,0xe6,0x80,0xf5,0x9c,0x31,0x10,0x48,0xca,0x77,0x30,0x00, +0x5b,0x05,0x34,0x70,0x9f,0x84,0x86,0xf6,0xa8,0xf6,0x9e,0xb5,0x71,0x35,0x40,0xe5, +0x5d,0x48,0xa6,0x25,0x85,0x76,0xb8,0xd6,0x80,0xf5,0x5c,0xf5,0x38,0x80,0x97,0x95, +0x9c,0x31,0x10,0x6b,0xca,0x66,0x20,0x00,0x88,0xd6,0xa5,0x05,0xa2,0x95,0x71,0x25, +0x44,0xe4,0x5f,0x68,0xa4,0x26,0x85,0x45,0xb4,0xe5,0x83,0x05,0x62,0xf5,0x38,0x90, +0x97,0xa5,0x8a,0xc6,0xa1,0x15,0x9e,0x95,0x9c,0x31,0x10,0x80,0xba,0x67,0x40,0x00, +0x5a,0x8d,0x15,0xcd,0x3e,0x94,0xc0,0xad,0x92,0x71,0xda,0x0d,0x81,0xed,0x3a,0x0d, +0x01,0x04,0xb2,0x88,0x8d,0xed,0xc6,0x2e,0xb5,0x6e,0x5a,0x2d,0x09,0xd6,0x5e,0xd0, +0x9c,0x31,0x10,0x3c,0xba,0x76,0x30,0x00,0xb4,0xcc,0x96,0x31,0xdd,0x8d,0x6e,0x6d, +0x31,0xea,0x15,0x86,0xb9,0xb0,0x8e,0x4c,0xce,0x6c,0x9d,0xcd,0x49,0xf1,0x0d,0x76, +0x7f,0x2a,0xa9,0x4d,0xaa,0x10,0xc9,0x6d,0x9c,0x31,0x10,0x9e,0xb9,0x66,0x30,0x00, +0x62,0x9b,0x25,0xd3,0x35,0xe5,0xb8,0x5d,0x92,0x52,0xce,0x99,0x89,0xd2,0x3d,0xdb, +0x14,0x4a,0xa3,0x5b,0x96,0x25,0xba,0xdc,0xac,0xa2,0x52,0x62,0x18,0xf5,0x6b,0x5c, +0x9c,0x31,0x10,0x9e,0xb9,0x66,0x30,0x00,0xb0,0x99,0x9d,0xe2,0xc5,0x1c,0x6a,0xd4, +0x2a,0x0a,0x2e,0x24,0xb4,0xe4,0x95,0x5a,0xc6,0x12,0x89,0x92,0x46,0x53,0x19,0x0c, +0x96,0x8e,0xa5,0x9b,0xb2,0xa2,0xb0,0xe2,0x9c,0x31,0x10,0x9e,0xb9,0x66,0x30,0x00, +0x52,0x62,0x25,0x6a,0x5b,0x6a,0xb5,0xa3,0xa1,0x6b,0xb9,0x6d,0x71,0xa5,0x3e,0x13, +0x35,0x51,0x99,0x91,0x99,0x9c,0x9e,0x5c,0x85,0xdb,0x5e,0x23,0x4d,0x98,0x69,0xd3, +0x9c,0x31,0x10,0x73,0x95,0x66,0x10,0x00,0xce,0x3e,0xee,0xe3,0xc2,0x62,0x8b,0x43, +0x6d,0x32,0x4e,0x33,0x61,0xc4,0x9e,0x43,0xaa,0x43,0xa5,0xc3,0xad,0xbb,0xa2,0x3b, +0xa1,0xbb,0xa2,0x3b,0x90,0xbb,0x71,0xbb,0x9c,0x31,0x10,0x87,0x74,0x42,0x00,0x00, +0x6d,0xd8,0x71,0xa2,0x73,0x1a,0x68,0x98,0x9a,0x99,0x28,0x15,0x2d,0xdc,0x55,0x99, +0x57,0x19,0x60,0xae,0x9b,0x5a,0x8c,0x1d,0x67,0x59,0x99,0x1c,0x85,0xe1,0x95,0xdd, +0x9c,0x31,0x10,0x95,0x75,0x43,0x00,0x00,0x99,0x9d,0xba,0x5d,0x69,0xa1,0x91,0xdd, +0x91,0xdd,0x7e,0x22,0x68,0xc0,0x81,0xf0,0x5d,0x31,0x46,0xdd,0x79,0x5d,0x62,0x19, +0x61,0xdd,0x61,0xd9,0x6d,0xdd,0x31,0xdd,0x9c,0x31,0x10,0x7e,0x64,0x21,0x00,0x00, +0x52,0xf0,0x66,0xed,0x69,0x58,0x6a,0xb8,0x8b,0x2d,0x30,0x8a,0x2b,0xa9,0x82,0x0d, +0x74,0xed,0x7f,0x11,0x87,0x0d,0x74,0xc8,0x1c,0xcd,0x7a,0xf2,0x81,0x29,0x81,0x49, +0x9c,0x31,0x10,0x11,0x54,0x21,0x00,0x00,0x8c,0xad,0x9d,0xad,0x1d,0xcd,0x37,0x4d, +0xb0,0xf1,0x85,0xb0,0x91,0x6e,0x8e,0x49,0x76,0x74,0x1a,0x71,0x95,0x4d,0xb6,0x2e, +0xa6,0x51,0x7a,0x2d,0x79,0x8a,0x35,0x31,0x9c,0x31,0x10,0x71,0x53,0x32,0x00,0x00, +0x6a,0x51,0xb5,0xd3,0xc2,0x93,0xa1,0x1a,0x85,0x1e,0x7f,0x53,0x72,0xdb,0xc1,0xda, +0xa8,0xdb,0x9e,0xdc,0x96,0x1a,0x8e,0x1c,0x74,0xda,0x95,0xca,0xc2,0x5c,0xb1,0xdc, +0x9c,0x31,0x10,0xed,0x75,0x66,0x30,0x00,0x83,0x77,0x84,0x77,0x8a,0x87,0x83,0x77, +0x83,0x77,0x82,0x67,0x84,0x78,0x7b,0x77,0x82,0x77,0x7a,0x77,0x7c,0x76,0x83,0x78, +0x7a,0x67,0x7b,0x87,0x95,0x86,0xc0,0xe2,0x9c,0x31,0x10,0xbf,0xa8,0x88,0x30,0x00, +0xaf,0x63,0xa2,0xd5,0x99,0x71,0x9d,0xdc,0xbe,0xa3,0x9e,0x2b,0x82,0x23,0x81,0xe3, +0x85,0xa3,0x6d,0xdb,0x55,0xdb,0x45,0x1b,0x41,0x53,0x25,0x0b,0x21,0x52,0x31,0x5c, +0x9c,0x31,0x10,0xf2,0xa7,0x77,0x40,0x00,0x34,0x94,0x30,0x5c,0x3c,0x9b,0x4c,0x52, +0x5a,0x89,0x6c,0x91,0x7a,0x9b,0x8a,0xd6,0x96,0xd5,0xa1,0x13,0xa8,0xd2,0xb1,0x0b, +0xb8,0xcb,0xba,0xcb,0xba,0xd3,0xae,0xd3,0x9c,0x31,0x10,0x8d,0x97,0x76,0x20,0x00, +0xd2,0x24,0xce,0x6c,0xca,0x6b,0xc2,0xaa,0xc2,0xe2,0xb6,0x5b,0xaa,0x54,0xa2,0x95, +0xa6,0x63,0x9e,0xa1,0x9e,0x2a,0x92,0x25,0x7e,0x13,0x72,0x0a,0x65,0xe4,0x6a,0xab, +0x9c,0x31,0x10,0x08,0x96,0x66,0x20,0x00,0x72,0x6c,0x66,0x1a,0x56,0x54,0x63,0x23, +0x6a,0x34,0x65,0xf1,0x72,0x1c,0x82,0x99,0x96,0x03,0xa5,0xd4,0xa9,0x23,0xb0,0xa2, +0xb4,0x9a,0xc4,0xe3,0xc1,0x4c,0xb1,0x93,0x9c,0x31,0x10,0x43,0x85,0x53,0x00,0x00, +0xd4,0x52,0xb4,0x94,0x90,0xa9,0x6d,0x11,0x5c,0xe9,0x52,0xd2,0x46,0xb5,0x3e,0xf1, +0x3c,0xf1,0x32,0xf1,0x2f,0x2d,0x2f,0x2d,0x2f,0x0d,0x2c,0xed,0x2e,0xed,0x33,0x0d, +0x9c,0x31,0x10,0x95,0x84,0x21,0x00,0x00,0x33,0x18,0x36,0xc5,0x3e,0xad,0x42,0xd5, +0x48,0xb0,0x4f,0x09,0x51,0x6a,0x51,0x2c,0x54,0xb6,0x58,0xcd,0x5c,0xe8,0x60,0xca, +0x64,0xd1,0x67,0x05,0x69,0x2c,0x69,0x0d,0x9c,0x31,0x10,0xa2,0x63,0x11,0x00,0x00, +0x31,0x54,0x40,0x6d,0x4a,0x8c,0x53,0x2e,0x5b,0x19,0x6b,0x46,0x6a,0xba,0x6c,0x64, +0x7d,0x28,0x7d,0x59,0x80,0x99,0x8c,0xb9,0x8e,0xb1,0x8e,0xee,0x90,0xc8,0x95,0x6a, +0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00,0xc5,0xd4,0xd0,0xee,0xe6,0x98,0xd7,0x61, +0xe5,0x5d,0xcd,0xe1,0xc2,0xe9,0x9a,0x19,0xaa,0x65,0x9e,0x08,0xa4,0xa1,0xb4,0x96, +0xa2,0x5e,0xb3,0x18,0xb6,0xa9,0xbd,0xe9,0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00, +0xad,0x4c,0xb9,0x6a,0xc4,0x23,0xc1,0x6a,0xbe,0x2e,0xc9,0x21,0xbd,0x43,0xba,0x95, +0xb5,0xd9,0xc6,0x23,0xb2,0x54,0xb0,0xc9,0xb6,0x1c,0xca,0xe2,0xba,0x94,0xc1,0xad, +0x9c,0x31,0x10,0xe8,0x43,0x11,0x00,0x00,0xd6,0x31,0xc9,0xdc,0xd5,0xa9,0xd1,0xe4, +0xd1,0x1c,0xdc,0x53,0xea,0x88,0xe2,0x9c,0xe5,0xdc,0xe2,0xac,0xe7,0x2b,0xee,0xe0, +0xd5,0x73,0xd1,0x64,0xc9,0x25,0xbc,0x1a,0x9c,0x31,0x10,0xfd,0x53,0x31,0x00,0x00, +0x94,0xdd,0x9a,0x55,0xa2,0x19,0xb6,0x5d,0xbb,0x20,0xb6,0x1d,0xad,0xdd,0xbe,0x1d, +0x9d,0xe6,0xca,0x6e,0xc1,0xf8,0xa8,0x5d,0xbe,0x28,0xa3,0x56,0x9a,0x96,0xb6,0x14, +0x9c,0x31,0x10,0x6b,0x88,0x97,0x30,0x00,0x83,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb, +0x7b,0xbb,0x7b,0xbb,0x83,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x83,0xbb,0x83,0xbb, +0xd5,0x30,0xa1,0x5d,0xb1,0xe3,0xb1,0x55,0x9c,0x31,0x10,0x03,0x87,0x97,0x30,0x00, +0x95,0x52,0x9a,0x39,0xbc,0x3b,0xe5,0xcd,0x5c,0xe3,0x25,0xca,0x55,0x3a,0x7c,0xab, +0x2d,0xa3,0x1d,0x32,0x31,0x3b,0x51,0xc3,0x49,0x43,0x39,0xc3,0x6d,0x3c,0x79,0xbb, +0x9c,0x31,0x10,0xa8,0x87,0x76,0x20,0x00,0x55,0xda,0x61,0xd2,0x95,0x93,0x95,0xdb, +0x7d,0x9b,0x89,0xad,0xa5,0xe2,0x84,0xda,0x74,0x8c,0xa8,0xe4,0xbd,0x2b,0x6d,0x10, +0x71,0x55,0xc9,0xab,0x9e,0x23,0x3e,0x63,0x9c,0x31,0x10,0x7c,0x86,0x86,0x10,0x00, +0x2e,0x31,0x76,0xae,0x5d,0xc2,0x1e,0x4b,0x4e,0x42,0x95,0xbd,0x5a,0x38,0x3e,0x4d, +0x5e,0x5a,0x82,0x2c,0x41,0xb2,0x2d,0x3b,0x45,0x4a,0x7d,0x54,0x46,0x42,0x4e,0x43, +0x9c,0x31,0x10,0x80,0x75,0x76,0x10,0x00,0x4b,0x95,0xd9,0x9a,0xba,0xc6,0xba,0x98, +0xac,0x69,0xc3,0x35,0xbb,0x34,0x93,0x78,0xb2,0xc9,0xd3,0xc7,0xae,0x84,0x8d,0x29, +0x9d,0x29,0x8b,0x38,0xb5,0x75,0x8b,0x72,0x9c,0x31,0x10,0xfb,0x76,0x76,0x20,0x00, +0xaa,0xdc,0x9b,0xe4,0x84,0x43,0x85,0xb3,0xa5,0x9d,0xba,0x11,0xca,0xa9,0xb3,0xcc, +0x8c,0xdd,0x9a,0xd1,0x9b,0x39,0x8a,0xb4,0xa5,0xad,0xd5,0x1b,0xd5,0x2b,0x5a,0x52, +0x9c,0x31,0x10,0xd5,0xb6,0x77,0x20,0x00,0x75,0x22,0x74,0xa3,0x7a,0xe2,0x80,0xe5, +0x8d,0x5b,0x9b,0x4a,0x94,0x9a,0x7c,0xd3,0x5c,0x93,0x4e,0x9b,0x58,0x5c,0x80,0x1c, +0xb4,0x63,0xca,0xeb,0xbb,0x62,0x78,0x5a,0x9c,0x31,0x10,0xb9,0xc6,0x66,0x20,0x00, +0x5a,0x9d,0x4c,0xdd,0x58,0x93,0x85,0x49,0xb0,0xa2,0xb4,0x63,0xa3,0x24,0x7c,0x64, +0x58,0xe3,0x3e,0xe3,0x46,0x61,0x80,0xe3,0xb2,0xa5,0xbd,0x05,0xac,0xd2,0x8a,0x59, +0x9c,0x31,0x10,0xb9,0xc6,0x66,0x20,0x00,0x5f,0x5b,0x39,0x1c,0x36,0x4d,0x6f,0x03, +0xa6,0x90,0xbb,0x4a,0xb6,0x8c,0xa3,0x15,0x78,0x5c,0x4b,0x23,0x2f,0x1b,0x45,0x6b, +0x80,0xa3,0xaa,0xa2,0xb6,0xdc,0xaa,0xa4,0x9c,0x31,0x10,0xa6,0xb5,0x54,0x00,0x00, +0xa9,0x2a,0x62,0xa9,0x31,0x24,0x21,0x8a,0x3d,0xa2,0x6f,0x23,0x9a,0xdc,0xb8,0x9b, +0xc6,0xda,0xbd,0x1a,0x9a,0xdb,0x6a,0xdb,0x46,0x9b,0x3a,0xdb,0x4a,0xdb,0x6e,0xdb, +0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00,0x9d,0x85,0xbf,0x91,0xc2,0x6d,0xa5,0x8e, +0x76,0x98,0x50,0x71,0x41,0x2a,0x4d,0x61,0x6d,0x40,0x94,0x4d,0xb1,0x71,0xb6,0xb1, +0xa2,0x91,0x81,0x91,0x63,0x55,0x54,0xb6,0x9c,0x31,0x10,0x83,0xa5,0x54,0x00,0x00, +0x34,0xdb,0x69,0x6d,0xae,0x70,0xca,0xdc,0xc8,0xd2,0xae,0xcc,0x8a,0xdb,0x4d,0x1b, +0x26,0xda,0x28,0xdb,0x47,0x1b,0x6a,0xdc,0x90,0xdb,0xb2,0xda,0xc3,0x1b,0xb8,0xdb, +0x9c,0x31,0x10,0x34,0xb5,0x43,0x00,0x00,0x8a,0x6d,0x70,0x6d,0x5a,0x68,0x54,0x6d, +0x60,0x6d,0x7c,0xb5,0x9c,0x8d,0xb4,0x69,0xb8,0x4d,0xa0,0x2d,0x73,0x8d,0x4b,0x6e, +0x38,0x50,0x46,0x45,0x72,0xa1,0xb1,0x45,0x9c,0x31,0x10,0x1a,0xc4,0x33,0x00,0x00, +0xad,0x15,0xab,0x50,0x91,0xd1,0x6c,0x41,0x4c,0x11,0x43,0xb6,0x5a,0x45,0x89,0x34, +0xb6,0x85,0xc9,0xc9,0xb9,0x4a,0x89,0x09,0x52,0x45,0x2d,0x45,0x30,0xb5,0x5e,0x14, +0x9c,0x31,0x10,0x52,0xc4,0x43,0x00,0x00,0x9e,0xae,0xcd,0x4e,0xd9,0x4d,0xbe,0x6d, +0x85,0x4c,0x46,0x6c,0x1f,0x49,0x24,0x46,0x58,0x29,0x9d,0x4d,0xce,0x48,0xda,0x6d, +0xc6,0x4a,0x95,0x4e,0x56,0x49,0x26,0x6d,0x9c,0x31,0x10,0x52,0xc4,0x43,0x00,0x00, +0x1b,0x48,0x42,0x65,0x86,0x26,0xbf,0x89,0xd5,0x2d,0xcf,0x88,0xaf,0x29,0x78,0x69, +0x40,0x6d,0x1e,0x48,0x28,0x6a,0x5e,0x4e,0x9f,0x2d,0xc8,0x71,0xd1,0x68,0xc5,0x69, +0x9c,0x31,0x10,0x52,0xc4,0x43,0x00,0x00,0x9f,0x4d,0x66,0x55,0x31,0xb1,0x1a,0x71, +0x36,0xb0,0x76,0x6d,0xb2,0xad,0xcf,0x51,0xd0,0xb1,0xbc,0x71,0x8e,0xad,0x53,0x69, +0x24,0x6a,0x1d,0x69,0x4a,0x89,0x8c,0x44,0x9c,0x31,0x10,0x52,0xc4,0x43,0x00,0x00, +0xbf,0xa6,0xd1,0x25,0xcc,0xa5,0xaf,0x25,0x7b,0xa5,0x43,0x60,0x1d,0x24,0x25,0x65, +0x5c,0x2a,0x9d,0x86,0xc6,0x68,0xd0,0x64,0xc7,0x45,0xa3,0x46,0x6d,0x69,0x36,0xa8, +0x9c,0x31,0x10,0x70,0xc6,0x45,0x00,0x00,0x1a,0x65,0x32,0x89,0x72,0x75,0xae,0x75, +0xcb,0x65,0xcf,0x89,0xbf,0x75,0x94,0x65,0x5b,0x65,0x29,0x75,0x1b,0x89,0x43,0x89, +0x8b,0xb8,0xc4,0x82,0xce,0x71,0xcb,0xc1,0x9c,0x31,0x10,0xc2,0xd8,0x87,0x30,0x00, +0x9a,0xed,0x76,0xed,0x4f,0x2d,0x3c,0x49,0x5f,0x09,0x8c,0x89,0x98,0xe9,0x9c,0xe9, +0x9c,0xa9,0x9d,0x0d,0x8a,0xb1,0x62,0xf0,0x4d,0x31,0x50,0xb5,0x7a,0xf9,0x88,0xb5, +0x9c,0x31,0x10,0xf2,0xc9,0x77,0x30,0x00,0xa8,0xf9,0xb8,0xf9,0xb2,0xf9,0xb7,0x34, +0x88,0xed,0x43,0x2d,0x1c,0xf2,0x31,0x92,0x82,0xe9,0x95,0x24,0xb2,0xe9,0xb5,0x09, +0xb6,0xe5,0xb6,0xe5,0x6a,0xc5,0x33,0x05,0x9c,0x31,0x10,0xf5,0xc9,0x86,0x30,0x00, +0x14,0x49,0x4f,0x69,0x8e,0x85,0x9d,0x28,0xba,0xa9,0xb0,0xc9,0xb6,0xe9,0xa2,0x8e, +0x56,0xd2,0x31,0x0d,0x18,0x50,0x6d,0x14,0x8c,0x95,0xa5,0x32,0xb6,0xd1,0xaa,0xd0, +0x9c,0x31,0x10,0x7a,0xc9,0x87,0x30,0x00,0xbb,0x35,0x8e,0xb9,0x4b,0x31,0x26,0xf1, +0x25,0x15,0x82,0x91,0x88,0xf1,0xb2,0xf1,0xb3,0x11,0xb0,0xec,0xb9,0x2d,0x76,0xea, +0x49,0x49,0x1c,0xd1,0x39,0xd5,0x8a,0x6d,0x9c,0x31,0x10,0xc0,0xca,0x87,0x30,0x00, +0x8b,0x2d,0xba,0xc9,0xa9,0x08,0xb4,0xe9,0xb2,0xea,0x71,0x06,0x48,0xe5,0x14,0xa4, +0x49,0x68,0x86,0xa9,0x91,0x4a,0xbc,0xa9,0xa6,0xe5,0xb8,0xe9,0xaa,0xc5,0x66,0xe9, +0x9c,0x31,0x10,0xeb,0xca,0x87,0x40,0x00,0x42,0xea,0x12,0x8d,0x59,0x6c,0x84,0x8c, +0x9b,0x52,0xba,0xb2,0xa9,0x11,0xba,0xf1,0xa2,0xcd,0x65,0x11,0x43,0x11,0x10,0x95, +0x61,0x8d,0x80,0xcd,0x9f,0x6d,0xb6,0xc9,0x9c,0x31,0x10,0x7a,0xc9,0x87,0x30,0x00, +0xa9,0x09,0xbd,0x04,0x9e,0x85,0x67,0x2d,0x40,0xce,0x12,0x0d,0x61,0xcd,0x7e,0x48, +0xa1,0x6d,0xb4,0x6d,0xa8,0xed,0xbc,0xed,0xa0,0x6a,0x6b,0x0d,0x42,0xae,0x14,0x2c, +0x9c,0x31,0x10,0xc0,0xca,0x87,0x30,0x00,0x61,0x68,0x7a,0xa6,0x9f,0x49,0xb0,0xa6, +0xa7,0x05,0xbb,0x04,0xa2,0xc1,0x6d,0x05,0x48,0xcd,0x16,0x90,0x5b,0x71,0x7a,0xad, +0x9b,0x4d,0xb2,0xad,0xa7,0x0d,0xb5,0x15,0x9c,0x31,0x10,0x74,0xca,0x87,0x20,0x00, +0xa2,0xec,0x71,0x26,0x50,0xec,0x1a,0xd1,0x55,0x8a,0x7a,0xac,0x95,0x4e,0xb0,0xad, +0xa5,0x0c,0xb2,0xed,0xa9,0x15,0x75,0x09,0x55,0x09,0x1e,0xcd,0x51,0x91,0x7c,0xad, +0x9c,0x31,0x10,0x46,0xca,0x88,0x30,0x00,0x8e,0x92,0xb1,0x5b,0xa2,0x5c,0xad,0xda, +0xa6,0x24,0x79,0xf2,0x59,0xdc,0x25,0xe3,0x4a,0xf2,0x7d,0x5c,0x86,0x59,0xa9,0x5c, +0x9e,0x1a,0xad,0xdc,0xaa,0x2c,0x7d,0xe2,0x9c,0x31,0x10,0xce,0xc9,0x87,0x20,0x00, +0x5d,0x0e,0x2e,0xec,0x41,0xb9,0x7e,0x89,0x83,0x51,0xac,0xa9,0xa1,0x0e,0xac,0xcd, +0xab,0x11,0x82,0xd4,0x5f,0x0e,0x35,0x0c,0x3b,0x56,0x7a,0x75,0x7e,0xe8,0xa6,0xce, +0x9c,0x31,0x10,0x7c,0xc7,0x88,0x10,0x00,0xa3,0x22,0xab,0x1c,0xaa,0xda,0x88,0x73, +0x61,0x5c,0x3b,0x11,0x37,0x2d,0x76,0x21,0x80,0x9c,0xa0,0xdb,0xa6,0xda,0xa6,0xdd, +0xab,0x11,0x8c,0x75,0x65,0x22,0x45,0x1b,0x9c,0x31,0x10,0xb3,0xc7,0x77,0x20,0x00, +0x32,0xcd,0x6a,0xf0,0x82,0x56,0x9b,0x19,0xa6,0x9d,0xa6,0xe1,0xa6,0x84,0x90,0x5b, +0x68,0xe3,0x4b,0x23,0x38,0x12,0x5c,0xe4,0x86,0x63,0x97,0x1a,0xa2,0xe4,0xa4,0xe1, +0x9c,0x31,0x10,0x8d,0xb5,0x66,0x00,0x00,0xbe,0x86,0x96,0xd1,0x5e,0xdc,0x36,0x9a, +0x30,0x63,0x47,0x4b,0x74,0xd3,0x99,0x1b,0xa8,0xeb,0xab,0x1b,0xa4,0xdb,0x9a,0xdb, +0x84,0xdb,0x74,0xdb,0x69,0x1b,0x64,0x9b,0x9c,0x31,0x10,0x2a,0xa6,0x65,0x10,0x00, +0x53,0x2d,0x68,0xcd,0x8c,0xcd,0xaf,0x2d,0xb0,0xa9,0xa4,0xcd,0x7b,0x8d,0x53,0xb5, +0x38,0xd1,0x3d,0x29,0x5a,0xed,0x7c,0x71,0xa2,0xce,0xb3,0x2a,0xab,0x08,0x95,0x29, +0x9c,0x31,0x10,0x95,0x97,0x66,0x20,0x00,0x82,0x1b,0x51,0x92,0x36,0x5c,0x4a,0x13, +0x6c,0xe3,0x86,0x1c,0x9a,0x1b,0xbe,0xe4,0xae,0x1b,0x9a,0x13,0x75,0xdb,0x65,0xe3, +0x61,0x5a,0x5a,0x12,0x6e,0xad,0x7e,0x72,0x9c,0x31,0x10,0x63,0x78,0x66,0x00,0x00, +0xf3,0xf4,0xbb,0xe3,0xbc,0xab,0x43,0x62,0x42,0x9c,0x5c,0x1a,0x8e,0x6d,0xa3,0xf1, +0x82,0x2b,0xc2,0xe3,0x7c,0x5a,0x6b,0x8b,0x4b,0xd3,0xac,0x53,0xc3,0xaa,0xab,0x9b, +0x9c,0x31,0x10,0xc7,0x88,0x87,0x20,0x00,0x73,0xbb,0x63,0xbb,0x53,0xbb,0x6b,0xbb, +0x8b,0xbb,0xab,0xbb,0xb3,0xbb,0x93,0xbb,0x93,0xbb,0x7b,0xbb,0xc5,0xd4,0x8b,0x71, +0x5b,0x9c,0x83,0x2a,0x8b,0xc3,0x7b,0xbb,0x9c,0x31,0x10,0x01,0x88,0x76,0x10,0x00, +0x65,0xdb,0x61,0x9b,0x82,0x23,0xa5,0xd3,0x81,0xd3,0x7d,0x95,0xa1,0x41,0x71,0xe2, +0x4d,0xa4,0x61,0xda,0x95,0x9c,0x91,0x4c,0x26,0xc3,0x36,0x43,0x3a,0x0b,0x16,0x13, +0x9c,0x31,0x10,0xf1,0x96,0x65,0x00,0x00,0x32,0x19,0x2a,0xb2,0x33,0x61,0x47,0x91, +0x96,0x8d,0xca,0x55,0xd2,0x19,0xc9,0xe1,0xc1,0xe1,0xbe,0x21,0xae,0x21,0x9d,0xdd, +0x95,0x99,0x8e,0x1d,0x81,0xdd,0x71,0xdd,0x9c,0x31,0x10,0xaf,0x73,0x21,0x00,0x00, +0x36,0xb6,0x47,0x6e,0x72,0x15,0x83,0x2c,0x88,0xe5,0x87,0x14,0x79,0x0a,0x66,0xd9, +0x60,0xf5,0x60,0xc5,0x6a,0xd9,0x70,0xcc,0x72,0x91,0x73,0x2d,0x60,0xce,0x58,0xad, +0x9c,0x31,0x10,0x17,0x62,0x21,0x00,0x00,0x3e,0x88,0x51,0x52,0x63,0x95,0x6a,0xf1, +0x72,0xb5,0x75,0x91,0x66,0x92,0x68,0xcc,0x6e,0x69,0x7b,0x29,0x82,0xf0,0x8b,0xb0, +0x8a,0xb2,0x81,0x0c,0x83,0x71,0x87,0x4e,0x9c,0x31,0x10,0x69,0x53,0x22,0x00,0x00, +0x95,0xe3,0xaa,0x23,0xb9,0x72,0xc2,0x1b,0xb9,0xe5,0xb2,0x1b,0xa1,0x5b,0x84,0xd2, +0x95,0xa4,0x91,0xa2,0x9d,0xd5,0xae,0x2a,0xa5,0xe4,0x96,0x5a,0x91,0x5c,0x8a,0x5b, +0x9c,0x31,0x10,0xd1,0x42,0x22,0x00,0x00,0x81,0x93,0x75,0x1b,0x74,0x9a,0x5a,0x5b, +0x46,0x64,0x6e,0x93,0x54,0xc9,0x6a,0x53,0x69,0xa5,0x5a,0x0b,0x61,0x1b,0x4d,0x5b, +0x46,0x9b,0x3d,0x9c,0x19,0x9b,0x36,0x13,0x9c,0x31,0x10,0xdc,0x52,0x12,0x00,0x00, +0x55,0xe3,0x66,0x63,0x69,0xda,0x61,0xed,0x5d,0x1b,0x69,0x13,0x72,0x23,0x7a,0x1a, +0x65,0xdc,0x6d,0x4c,0x69,0x22,0x65,0xc2,0x4f,0x1b,0x4c,0x5c,0x53,0x1b,0x3c,0xad, +0x9c,0x31,0x10,0xc3,0x43,0x23,0x00,0x00,0x62,0x1b,0x65,0x9b,0x81,0xdc,0x3e,0xaa, +0x71,0x9c,0x73,0x2b,0x54,0xeb,0x66,0x2b,0x71,0xdd,0x7a,0x48,0x79,0x13,0x9a,0xd4, +0x59,0x2c,0xa8,0x53,0xa5,0xc3,0x49,0xa3,0x9c,0x31,0x10,0xf5,0x88,0x88,0x30,0x00, +0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x83,0xbb,0x7b,0xbb,0x83,0xbb,0x7b,0xbb, +0x7b,0xbb,0x7b,0xbb,0x8c,0x3b,0x83,0x3b,0xf5,0xdc,0x9b,0x51,0x9a,0xab,0xa3,0xbb, +0x9c,0x31,0x10,0x3e,0x87,0x78,0x40,0x00,0xc1,0xa8,0xb6,0x27,0x9e,0x3a,0x09,0x96, +0x40,0xa4,0x59,0xb8,0x39,0x36,0x21,0xa8,0x39,0x39,0x61,0x36,0x65,0xb8,0x66,0x28, +0x7d,0x26,0xe2,0x37,0x6c,0xd2,0x0d,0xba,0x9c,0x31,0x10,0xb8,0x87,0x77,0x40,0x00, +0x53,0x4c,0x6c,0x48,0x3b,0x54,0x3a,0x29,0x4a,0x6d,0x5a,0x55,0x63,0x4e,0x61,0x72, +0xd2,0x36,0x54,0x22,0x79,0x45,0x9a,0xb5,0x52,0x8c,0x1b,0xa8,0x13,0xb1,0x2b,0xad, +0x9c,0x31,0x10,0x35,0x86,0x76,0x20,0x00,0x2a,0x64,0x4a,0x2a,0x62,0xdd,0x81,0x49, +0xa6,0x4d,0xba,0x1c,0xc9,0x59,0xe5,0xd1,0xe9,0x63,0xed,0xdc,0xf1,0x1c,0xe1,0xdc, +0xe2,0x22,0xe9,0x4a,0xdd,0xdc,0xc5,0xd4,0x9c,0x31,0x10,0x86,0x86,0x87,0x30,0x00, +0xbc,0xb2,0xa9,0x2d,0x94,0xb3,0x98,0xc3,0x88,0x4b,0x8d,0x5c,0xa2,0x52,0xab,0x43, +0xae,0xba,0xc2,0xac,0xd1,0xa1,0xa1,0xac,0x91,0xb5,0x7a,0x39,0x55,0xc4,0x52,0x43, +0x9c,0x31,0x10,0xba,0x86,0x77,0x20,0x00,0x64,0xe9,0x69,0xec,0x86,0xa5,0x9f,0x1a, +0xbe,0x51,0xd2,0x95,0xe2,0x93,0xc9,0xc8,0xc1,0xcd,0xc2,0x14,0xad,0x99,0x98,0xa4, +0x92,0x0c,0x59,0x58,0x3d,0xa4,0x0d,0xa5,0x9c,0x31,0x10,0xba,0x86,0x77,0x20,0x00, +0x0e,0x11,0x15,0xd3,0x21,0xdc,0x19,0x62,0x16,0x9c,0x16,0x1c,0x1a,0x19,0x1b,0x4c, +0x15,0x8c,0x2d,0x49,0x31,0xd3,0x2c,0x8e,0x3c,0xa1,0x3d,0x63,0x44,0x5d,0x3d,0x9a, +0x9c,0x31,0x10,0x78,0x86,0x75,0x10,0x00,0x65,0x6d,0x7e,0x1e,0x95,0xdd,0x81,0x99, +0xb5,0x8e,0xb9,0xd5,0xd1,0xe1,0xb1,0x1d,0xc9,0xda,0xb1,0xa0,0xb2,0x2a,0x7d,0x69, +0x7a,0xe1,0x8d,0x58,0x79,0xcd,0x71,0xda,0x9c,0x31,0x10,0xe2,0x85,0x66,0x00,0x00, +0x70,0xdb,0x8e,0x62,0x69,0xc3,0x4e,0xd5,0x45,0xd2,0x6a,0x51,0x65,0x1d,0x76,0xad, +0x84,0x38,0x99,0xac,0xa6,0x2d,0x85,0xb8,0x52,0x2d,0x56,0x44,0x2a,0x31,0x36,0xa3, +0x9c,0x31,0x10,0x9b,0xb6,0x76,0x10,0x00,0x7c,0xd3,0x86,0xda,0x88,0xdd,0x89,0x1a, +0x86,0x9c,0x7a,0xda,0x66,0x9a,0x5b,0x25,0x60,0x9a,0x7d,0x1b,0x98,0x9d,0xad,0x59, +0xb2,0xda,0x9f,0x4d,0x6e,0x14,0x3d,0x18,0x9c,0x31,0x10,0x51,0xc7,0x66,0x00,0x00, +0x4e,0xb5,0x56,0xf4,0x8b,0x28,0xb0,0xa6,0xae,0xdc,0xa2,0xe1,0x91,0x1b,0x70,0xdc, +0x46,0xf2,0x34,0xf3,0x57,0x9a,0x98,0xd4,0xa8,0xc3,0xb2,0xc2,0xb2,0x93,0xa3,0x1b, +0x9c,0x31,0x10,0x72,0xc7,0x77,0x10,0x00,0x74,0x5b,0x49,0x13,0x36,0x9b,0x3e,0xec, +0x7e,0xe0,0xa4,0xab,0xa9,0x16,0xae,0xd9,0xb0,0xe3,0x9c,0xd3,0x70,0x93,0x49,0x5b, +0x36,0x9a,0x3d,0x1c,0x80,0xc3,0xa2,0x83,0x9c,0x31,0x10,0x1a,0xc8,0x77,0x10,0x00, +0x9e,0xcd,0xa4,0xf1,0xb3,0x11,0xa8,0xd1,0x85,0x0d,0x56,0xad,0x3b,0x11,0x2e,0x65, +0x6b,0x11,0x9e,0xb2,0x94,0xf0,0x9a,0xf5,0xaa,0xc9,0xad,0x0d,0x9c,0xd5,0x7a,0xf4, +0x9c,0x31,0x10,0x2e,0xc6,0x77,0x20,0x00,0x51,0x5c,0x2f,0xa3,0x39,0x62,0x88,0xe3, +0x9a,0xac,0x8f,0x5b,0x9f,0x12,0xa8,0xcb,0xa0,0x8d,0x9e,0xd2,0x80,0xda,0x4d,0x6c, +0x32,0xf2,0x3d,0x33,0x8b,0x26,0x94,0xd2,0x9c,0x31,0x10,0x54,0xc8,0x76,0x20,0x00, +0x89,0x09,0x9f,0x09,0xa2,0xec,0x98,0xed,0xa3,0x0d,0x96,0xd2,0x5c,0xb0,0x3d,0x2d, +0x34,0x41,0x75,0x2a,0x94,0xb1,0x83,0x11,0x96,0xed,0xa0,0xcc,0x96,0xe9,0x9e,0xc5, +0x9c,0x31,0x10,0x95,0xc8,0x76,0x10,0x00,0xa0,0xe4,0x74,0xce,0x4b,0x4d,0x32,0xb5, +0x4d,0xd4,0x96,0xca,0x8b,0x25,0x8b,0x09,0xa0,0xe5,0x9a,0xe5,0x96,0xea,0xa4,0xe9, +0x94,0xd1,0x64,0xd9,0x45,0x35,0x30,0x25,0x9c,0x31,0x10,0x92,0xc8,0x87,0x10,0x00, +0x6b,0x81,0x9c,0x68,0x81,0x0d,0x90,0xd1,0xa0,0xd1,0x93,0x11,0x96,0xed,0xa3,0x09, +0x8e,0xc9,0x68,0xad,0x4d,0x2d,0x2e,0x0e,0x67,0xc4,0x9e,0x6d,0x7f,0x2a,0x90,0xc8, +0x9c,0x31,0x10,0xdc,0xc8,0x86,0x20,0x00,0xa0,0xce,0x90,0xf2,0x99,0x10,0xa5,0x11, +0x8b,0x0d,0x62,0xc9,0x49,0x49,0x2e,0x2a,0x6f,0x85,0x9a,0x6c,0x7f,0x12,0x94,0xf0, +0x9e,0xd1,0x91,0x11,0x9a,0xd1,0xa3,0x0d,0x9c,0x31,0x10,0x0f,0xc9,0x87,0x10,0x00, +0x8a,0xed,0x64,0xcd,0x4d,0x0d,0x2e,0x8d,0x69,0x61,0x9e,0xa5,0x7d,0x09,0x92,0xed, +0x9e,0xd1,0x90,0xf1,0x98,0xf2,0xa2,0xec,0x8a,0xed,0x64,0xc9,0x4d,0x09,0x30,0x8e, +0x9c,0x31,0x10,0x0f,0xc9,0x87,0x10,0x00,0x69,0x44,0x9e,0xa9,0x7d,0x0a,0x94,0xec, +0x9e,0xce,0x8e,0xed,0x98,0xf1,0xa2,0xf1,0x8c,0xed,0x6a,0xcd,0x4f,0x2d,0x32,0xad, +0x61,0x6c,0x9e,0xc6,0x7b,0x08,0x90,0xe9,0x9c,0x31,0x10,0x26,0xc8,0x87,0x00,0x00, +0xa0,0xae,0x8a,0xec,0x96,0xf1,0xa2,0xed,0x92,0xf1,0x73,0x09,0x57,0x2d,0x3d,0x0d, +0x49,0x76,0x9a,0xcc,0x82,0xed,0x83,0x0d,0xa2,0xed,0x92,0xed,0x92,0xed,0xa0,0xcd, +0x9c,0x31,0x10,0x1a,0xc8,0x77,0x10,0x00,0x99,0x0d,0x7c,0xed,0x5e,0xc9,0x45,0x32, +0x38,0x20,0x8a,0xfa,0x8e,0x79,0x7b,0x38,0x9c,0xee,0x96,0xcd,0x8d,0x09,0x9c,0xc5, +0x9d,0x0d,0x86,0xcd,0x68,0xd5,0x51,0x2d,0x9c,0x31,0x10,0x92,0xc8,0x87,0x10,0x00, +0x36,0x2d,0x71,0xc0,0x9a,0x86,0x77,0x29,0x92,0xcc,0x9c,0xad,0x89,0x11,0x96,0xf5, +0x9e,0xf1,0x90,0xed,0x75,0x09,0x5b,0x09,0x3f,0x0d,0x4d,0x5a,0x98,0xd8,0x80,0xf2, +0x9c,0x31,0x10,0xa9,0xc8,0x86,0x00,0x00,0x83,0x09,0x9e,0xe9,0x8e,0xe9,0x8e,0xe8, +0x9e,0xae,0x96,0xed,0x80,0xed,0x64,0xad,0x49,0x2d,0x3a,0x05,0x7f,0x26,0x90,0x6c, +0x7b,0x0e,0x96,0xd1,0x98,0xb1,0x8d,0x12,0x9c,0x31,0x10,0x1d,0xc8,0x86,0x10,0x00, +0x9a,0xec,0x9d,0x09,0x8a,0xe9,0x6c,0xcd,0x53,0x2e,0x38,0x90,0x63,0xd1,0x9c,0xa6, +0x7b,0x28,0x8c,0xea,0x9e,0xc9,0x8e,0xed,0x90,0xcd,0xa0,0xd0,0x92,0xee,0x73,0x0d, +0x9c,0x31,0x10,0x92,0xc8,0x87,0x10,0x00,0x5c,0xed,0x43,0x0e,0x46,0xcd,0x90,0xd8, +0x8a,0xb2,0x81,0x0c,0x9b,0x0d,0x94,0xed,0x8f,0x0d,0x9a,0xed,0x9d,0x0d,0x80,0xed, +0x64,0xcd,0x51,0x09,0x3e,0x51,0x73,0x65,0x9c,0x31,0x10,0x55,0xb8,0x77,0x00,0x00, +0xb1,0x12,0x7a,0x1c,0x9d,0xe2,0xb9,0xa3,0x9d,0xec,0xa9,0xe9,0xbe,0x2c,0x89,0xd3, +0x4d,0xcb,0x2e,0x4b,0x05,0x63,0x3e,0xf3,0xb1,0x9d,0x8a,0x11,0x92,0x13,0xb5,0xd3, +0x9c,0x31,0x10,0xa0,0xb6,0x77,0x00,0x00,0xa8,0xdb,0xa6,0xa4,0xbc,0xe3,0xa2,0xaa, +0x5f,0x24,0x2d,0x5b,0x0f,0x53,0x1b,0x1c,0x9a,0xe9,0xa0,0xad,0x85,0x1a,0xab,0x24, +0xb5,0x13,0xa8,0xda,0xb7,0x0b,0xae,0x9b,0x9c,0x31,0x10,0x55,0xb8,0x77,0x00,0x00, +0x6d,0xe3,0x31,0xe3,0x1a,0x1c,0x15,0x09,0x81,0xed,0xa5,0x5b,0x89,0xe1,0xa5,0xdd, +0xb5,0xe2,0xa9,0xeb,0xad,0x9c,0xb1,0xca,0x7d,0xdb,0x3d,0x9c,0x1d,0xdb,0x0c,0xdb, +0x9c,0x31,0x10,0x3d,0xb7,0x77,0x00,0x00,0x65,0x4c,0xae,0x99,0x93,0x25,0x98,0xe2, +0xb6,0xe3,0xb5,0x24,0xa8,0xdb,0xac,0xdb,0x86,0xdb,0x44,0x9a,0x1f,0x14,0x14,0x53, +0x53,0x49,0xa6,0x95,0x9e,0xd3,0x96,0xa2,0x9c,0x31,0x10,0xaa,0xb7,0x66,0x00,0x00, +0xac,0xe6,0xbc,0xd9,0xb0,0xa3,0xa6,0xb5,0x8a,0xf1,0x50,0xe3,0x23,0x24,0x16,0xe2, +0x45,0x62,0x98,0xc5,0xa8,0xc0,0x9c,0xd4,0xa4,0xcc,0xb8,0xda,0xb4,0x9c,0xa2,0x9b, +0x9c,0x31,0x10,0xa5,0xb5,0x56,0x00,0x00,0x88,0xaa,0x5e,0xb4,0x34,0xdb,0x23,0x23, +0x3b,0x35,0x7e,0xf1,0xa4,0xe4,0xa2,0xd3,0x9b,0x12,0xa5,0x1c,0xa2,0x53,0x8e,0xca, +0x7a,0x94,0x6a,0xd3,0x62,0xd2,0x63,0x1c,0x9c,0x31,0x10,0x17,0x93,0x43,0x00,0x00, +0x26,0xc5,0x55,0x5c,0x81,0x1e,0xa7,0x29,0xc1,0x5d,0xdf,0x1d,0xe8,0xe1,0xd2,0xe1, +0x9e,0xa1,0x64,0xd9,0x39,0x1d,0x2a,0x9d,0x38,0xdd,0x56,0x99,0x7b,0x19,0x97,0x21, +0x9c,0x31,0x10,0xaf,0x73,0x21,0x00,0x00,0xe4,0xd1,0xc1,0x11,0x8e,0x6a,0x6f,0x44, +0x6e,0xe5,0x85,0x29,0x98,0xf0,0x8c,0x92,0x66,0xf0,0x2e,0x89,0x01,0x4e,0x22,0xed, +0x4d,0x2d,0x7a,0x69,0x9e,0xcd,0xab,0x0c,0x9c,0x31,0x10,0x17,0x62,0x21,0x00,0x00, +0xcf,0x4d,0xa9,0x48,0x96,0xaa,0x7a,0x91,0x78,0x14,0x79,0x31,0x54,0xc5,0x75,0xa9, +0x7e,0x09,0x64,0xa9,0x62,0x75,0x69,0x51,0x83,0x6d,0x9c,0xf5,0xb6,0xd6,0xb2,0x71, +0x9c,0x31,0x10,0xa1,0x63,0x13,0x00,0x00,0x83,0x2a,0x73,0x2b,0x3b,0x63,0x33,0x0c, +0x66,0xab,0x74,0xab,0x83,0x13,0x79,0x34,0x79,0x52,0x82,0xcb,0x96,0x8c,0x99,0x12, +0x90,0xe3,0x93,0x4a,0x67,0x55,0x50,0xab,0x9c,0x31,0x10,0x1b,0x87,0x87,0x30,0x00, +0x79,0xbb,0x79,0xbb,0x79,0xbb,0x79,0xbb,0x79,0xbb,0x85,0xbb,0x91,0xbb,0x99,0xb3, +0xb9,0x35,0xd4,0x12,0x5f,0x41,0x69,0xc4,0x75,0xbb,0x8d,0xc2,0x8d,0xc4,0x7d,0xbb, +0x9c,0x31,0x10,0x3c,0x98,0x66,0x10,0x00,0x79,0xe2,0x7d,0xe4,0x81,0xe3,0x7d,0xd9, +0x81,0xdd,0x91,0xd1,0xca,0x24,0xcc,0xd9,0x2e,0x92,0x45,0x96,0x6a,0x2c,0x65,0x91, +0x35,0xcb,0x31,0xdb,0x45,0xd1,0x49,0xe6,0x9c,0x31,0x10,0x62,0x94,0x65,0x10,0x00, +0x31,0xc9,0x35,0x62,0x4d,0x5e,0x62,0x48,0x77,0x4b,0x8b,0x3c,0x99,0xbc,0x96,0xa8, +0x9a,0x3d,0x9e,0x23,0xa6,0xc0,0x9e,0x3e,0x9a,0xc9,0x9c,0xbb,0x9d,0xc4,0x9b,0x32, +0x9c,0x31,0x10,0x4c,0x84,0x44,0x00,0x00,0xb4,0x91,0xbd,0x8d,0xcb,0x13,0xca,0x81, +0xc5,0x05,0xc0,0x42,0xb6,0x92,0x9c,0x6d,0x94,0xa2,0x9d,0x5a,0xa5,0x34,0x9e,0xab, +0x98,0xd2,0x9f,0x14,0x90,0x93,0x84,0x8b,0x9c,0x31,0x10,0xa7,0x64,0x44,0x00,0x00, +0x84,0xc2,0x7e,0x1c,0x6d,0x63,0x5d,0xf2,0x45,0x6c,0x4d,0xe2,0x31,0xe2,0x2d,0xec, +0x21,0xe4,0x3d,0xc9,0x56,0x4c,0x4e,0x1b,0x49,0xd2,0x65,0x8b,0x59,0x92,0x51,0x9c, +0x9c,0x31,0x10,0x74,0x53,0x34,0x00,0x00,0x04,0x47,0x75,0x44,0x91,0x3b,0x51,0xd6, +0x45,0x55,0x06,0x4a,0x2d,0x55,0x02,0x16,0x10,0xbb,0x12,0x34,0x4e,0xc6,0x45,0xc9, +0x02,0xd5,0x29,0x37,0x42,0x39,0x31,0xc6,0x9c,0x31,0x10,0x89,0x63,0x23,0x00,0x00, +0x33,0x72,0x50,0xdd,0x5c,0xd9,0x4a,0xdb,0x46,0xdd,0x4f,0x32,0x4f,0x22,0x54,0xdc, +0x4c,0x9b,0x59,0x24,0x52,0xab,0x51,0x33,0x56,0xb3,0x4d,0x2b,0x46,0x9a,0x40,0x9b, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_DIS_CONNECT.txt b/config/_default_cfg_src_/res/en/SOUND_DIS_CONNECT.txt new file mode 100644 index 0000000..d1e84ca --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_DIS_CONNECT.txt @@ -0,0 +1,390 @@ +0x9c,0x31,0x10,0x43,0x41,0x12,0x00,0x00,0x7d,0xb7,0x7d,0xb7,0x81,0xb7,0x85,0x47, +0xb2,0x83,0xb9,0x47,0xb1,0x5c,0xb1,0x29,0xb5,0x25,0xd0,0xb4,0xce,0x18,0xe3,0x2b, +0xf3,0x29,0xf1,0xb8,0xea,0x3b,0xf2,0xc4,0x9c,0x31,0x10,0xc1,0x51,0x23,0x00,0x00, +0xb6,0x5a,0xb3,0x13,0xb0,0xe2,0xb2,0xcb,0xbc,0x2b,0xb6,0x3b,0xbd,0xba,0xb9,0x9b, +0xc5,0x3b,0xb6,0x3c,0xc1,0x33,0xb0,0xa3,0xb1,0x4b,0xa5,0xc1,0xaf,0x20,0xa5,0x45, +0x9c,0x31,0x10,0x46,0x42,0x33,0x00,0x00,0xd2,0x52,0xa7,0x9c,0xb4,0xdd,0xcb,0x1a, +0xbd,0xdb,0xd6,0x0b,0xb6,0x4b,0xdd,0x12,0xbe,0x54,0xe9,0x5c,0xe8,0x93,0xcd,0xcb, +0xaa,0x4a,0xd9,0x0b,0xc6,0x5b,0xc9,0x23,0x9c,0x31,0x10,0x6f,0x43,0x33,0x10,0x00, +0x99,0x85,0xb3,0x60,0xaa,0x50,0x8b,0x54,0x9b,0x51,0x88,0xb5,0x68,0x91,0x5b,0x8e, +0x83,0x65,0x51,0x4d,0x41,0x4d,0x4b,0x6d,0x52,0x6d,0x2c,0x99,0x19,0x65,0x33,0x81, +0x9c,0x31,0x10,0x12,0x54,0x23,0x00,0x00,0x5e,0x19,0x49,0xde,0x59,0xec,0x41,0x44, +0x61,0x22,0x55,0xcd,0x55,0x82,0x41,0x89,0x39,0xe3,0x49,0xcd,0x55,0xd8,0x2e,0x19, +0x29,0x44,0x31,0xc5,0x45,0x05,0x38,0x92,0x9c,0x31,0x10,0x7c,0x54,0x44,0x10,0x00, +0x32,0xc1,0x3b,0xcb,0x3b,0x34,0x3c,0x3b,0x4b,0x19,0x59,0xc3,0x5b,0x44,0x4a,0x4d, +0x5b,0x53,0x49,0xc3,0x6b,0xca,0x64,0xab,0x4a,0x2a,0x32,0xdc,0x5b,0xd5,0x4a,0xdb, +0x9c,0x31,0x10,0xc8,0x54,0x44,0x00,0x00,0x4d,0x41,0x4c,0x3c,0x3c,0x49,0x2a,0xb4, +0x6b,0xc4,0x43,0x32,0x54,0x09,0x53,0x24,0x44,0x1c,0x66,0x69,0x53,0x6c,0x5c,0xab, +0x53,0x3c,0x5c,0xa3,0x52,0x3a,0x5b,0x14,0x9c,0x31,0x10,0x68,0x45,0x54,0x00,0x00, +0x9d,0x3d,0x3c,0x32,0x64,0x5b,0x8b,0x2b,0xab,0x2b,0x9c,0xa9,0x73,0x23,0xbb,0x35, +0xa4,0x2e,0x82,0xb2,0x73,0xc1,0xaa,0x4b,0x69,0xa2,0xdb,0x38,0x75,0x46,0x61,0xe6, +0x9c,0x31,0x10,0xd0,0x54,0x54,0x00,0x00,0xc0,0xd9,0x84,0x31,0x9a,0x55,0x7c,0xe9, +0xae,0xe3,0xb1,0x52,0x8b,0xb3,0x86,0x3b,0x9b,0xcc,0x8e,0x3a,0xa4,0xce,0x56,0x73, +0x9c,0xd1,0x85,0xf3,0x8f,0x53,0x7e,0x5a,0x9c,0x31,0x10,0x53,0x45,0x55,0x10,0x00, +0x5d,0x23,0xac,0xcb,0x5e,0x4b,0x96,0xcd,0xd4,0xab,0x93,0x9a,0x1d,0x4b,0x64,0x51, +0xbc,0x34,0xa4,0xba,0xde,0xb5,0x85,0x9b,0x53,0xb3,0xe4,0x1a,0x33,0xaa,0xb5,0x42, +0x9c,0x31,0x10,0xd1,0x55,0x64,0x10,0x00,0x9e,0xbd,0xb4,0xbc,0x73,0xb6,0x8d,0x34, +0x8d,0x32,0x6c,0x28,0x85,0x2c,0x6c,0x1b,0x6b,0x5a,0x9e,0xac,0xde,0x21,0xb1,0x8e, +0x42,0xa2,0x8b,0x2d,0x62,0x0c,0x62,0xb3,0x9c,0x31,0x10,0xb2,0x56,0x74,0x20,0x00, +0x7b,0xb0,0xad,0x30,0xa3,0x2d,0x3b,0x3a,0xa3,0xbd,0x75,0x28,0x9c,0x3e,0x4a,0xc2, +0x7b,0xb5,0x53,0x2b,0xc4,0xac,0x9e,0xca,0xe5,0x4b,0x26,0x42,0x94,0xe0,0x4c,0xd6, +0x9c,0x31,0x10,0x35,0x78,0x77,0x30,0x00,0x7c,0x22,0x73,0xdb,0x74,0xe4,0x84,0xec, +0xf6,0x74,0x74,0xf1,0x54,0x22,0x64,0x1b,0x6d,0x1c,0x64,0xda,0x54,0x1b,0x7c,0x9b, +0xa4,0xdc,0x7c,0x62,0x7b,0xa3,0x84,0x6c,0x9c,0x31,0x10,0x4f,0x76,0x76,0x30,0x00, +0x8a,0x39,0x84,0x2c,0xa5,0xab,0x8c,0x59,0x72,0xc5,0x39,0x39,0x61,0x43,0x8b,0x3d, +0x9a,0x22,0xa2,0x2b,0x79,0x4c,0x90,0xc3,0x93,0xaa,0x92,0xd5,0x84,0x41,0x2c,0x1b, +0x9c,0x31,0x10,0x5d,0x77,0x77,0x30,0x00,0x64,0xb3,0x33,0x3b,0x44,0x2b,0x8d,0x21, +0x5c,0x9c,0x34,0xcd,0x8c,0xba,0x7c,0x4a,0xa4,0x43,0xac,0xbb,0xea,0xca,0xbd,0x43, +0x41,0xe4,0x43,0xc3,0xba,0x4b,0x9b,0x3b,0x9c,0x31,0x10,0x73,0xb7,0x76,0x30,0x00, +0x7c,0x54,0x80,0xdc,0x82,0x94,0x7c,0x99,0x7e,0xc9,0x78,0x92,0x70,0xdb,0x7c,0xdb, +0x8a,0xdd,0x82,0xe4,0x6e,0xd1,0x61,0x13,0x50,0x44,0x78,0x60,0xbd,0x13,0xd7,0x1b, +0x9c,0x31,0x10,0x54,0xc8,0x76,0x20,0x00,0x8f,0x2e,0x59,0x2d,0x38,0x91,0x67,0x8d, +0xb9,0x10,0xbd,0x0e,0xa8,0x51,0x8e,0x89,0x64,0xe9,0x22,0x05,0x51,0xc6,0xbb,0xc9, +0xb1,0xcd,0x89,0xd0,0xa5,0x55,0xa0,0xf9,0x9c,0x31,0x10,0x18,0xda,0x77,0x10,0x00, +0x5d,0x05,0x3e,0x9a,0x86,0x95,0xa8,0xa4,0x84,0xf1,0x81,0x02,0x99,0x01,0x7f,0x14, +0x3c,0xd5,0x5f,0x76,0xab,0x34,0x8f,0x08,0x78,0xda,0x9a,0xc5,0x96,0xf4,0x57,0x15, +0x9c,0x31,0x10,0x63,0xd9,0x77,0x20,0x00,0x3c,0x2a,0x90,0x88,0xa0,0xe8,0x77,0x8a, +0x8f,0x4a,0xa4,0xac,0x7a,0xed,0x45,0x16,0x5b,0xb4,0xa2,0x51,0x84,0x4e,0x7e,0xcd, +0xa1,0x0c,0x93,0x0d,0x69,0x0d,0x46,0x71,0x9c,0x31,0x10,0xce,0xca,0x78,0x30,0x00, +0x67,0x8d,0xb8,0xf2,0x7e,0xca,0x9e,0xab,0xbe,0xcb,0x8f,0x03,0x47,0x0b,0x0e,0x62, +0x89,0x4a,0xad,0x2d,0x7d,0x0c,0xae,0xaa,0xb4,0xaa,0x83,0x0c,0x3b,0x03,0x18,0x64, +0x9c,0x31,0x10,0xce,0xca,0x78,0x30,0x00,0x9e,0xc9,0x9f,0x2a,0x85,0x4c,0xb4,0xcc, +0xac,0xaa,0x78,0xeb,0x2f,0x22,0x28,0xd4,0xb0,0x6d,0x8e,0xea,0x8f,0x4a,0xbc,0xec, +0xa0,0xcb,0x6c,0xcb,0x29,0x2b,0x3d,0x12,0x9c,0x31,0x10,0x48,0xca,0x77,0x30,0x00, +0xb0,0x56,0x86,0xd6,0x9b,0x55,0xb7,0x05,0x98,0xc5,0x68,0xd5,0x27,0x3a,0x4b,0x78, +0xb2,0x35,0x80,0xb5,0xa5,0x55,0xb3,0x25,0x92,0xe5,0x60,0xb5,0x22,0xea,0x5f,0xe5, +0x9c,0x31,0x10,0xcd,0xcb,0x67,0x30,0x00,0xae,0xa4,0x80,0xd8,0xab,0x05,0xad,0x25, +0x8c,0xf5,0x5c,0xd9,0x20,0xd9,0x71,0x72,0xa6,0xb9,0x82,0xd5,0xb0,0xf4,0xa9,0x25, +0x88,0xf5,0x5a,0xe5,0x24,0xc5,0x73,0x72,0x9c,0x31,0x10,0xdf,0xca,0x66,0x30,0x00, +0xa2,0xa4,0x84,0xa4,0xb0,0xe5,0xa7,0x45,0x87,0x05,0x56,0xd5,0x26,0x80,0x7d,0xd2, +0x9e,0xd6,0x86,0xc6,0xb0,0xc5,0xa1,0x34,0x83,0x00,0x52,0xf5,0x2c,0x70,0x83,0xa6, +0x9c,0x31,0x10,0x48,0xca,0x77,0x30,0x00,0x98,0xf5,0x8a,0xd6,0xb0,0xa5,0x9d,0x35, +0x81,0x15,0x54,0xf5,0x2e,0x50,0x85,0x85,0x97,0x26,0x8e,0xe5,0xac,0x95,0x99,0x15, +0x7d,0x25,0x4f,0x25,0x32,0x50,0x91,0x34,0x9c,0x31,0x10,0x48,0xca,0x77,0x30,0x00, +0x91,0x35,0x93,0x05,0xac,0x85,0x94,0xf5,0x7b,0x25,0x4d,0x25,0x38,0x61,0x93,0x04, +0x8d,0x45,0x97,0x35,0xa8,0x95,0x94,0xc5,0x75,0x05,0x49,0x45,0x3e,0x95,0x94,0xc4, +0x9c,0x31,0x10,0x11,0xb9,0x67,0x30,0x00,0x9e,0x93,0xb7,0x1b,0xcc,0xdb,0xa5,0x1a, +0x61,0x9b,0x0f,0x13,0x11,0x65,0xa8,0x93,0x96,0x1a,0xbf,0x1a,0xc5,0xe3,0x9d,0x63, +0x59,0x23,0x0e,0xa2,0x1e,0x74,0xb0,0x54,0x9c,0x31,0x10,0x2a,0xb9,0x66,0x20,0x00, +0x91,0x5a,0xbe,0xd1,0xc2,0x9b,0x99,0xe4,0x50,0xe3,0x0e,0x2b,0x32,0xf0,0xb0,0x94, +0x99,0x5c,0xc2,0x5c,0xba,0x5b,0x8e,0x63,0x41,0x5b,0x05,0x6d,0x57,0x59,0xb1,0x9a, +0x9c,0x31,0x10,0x32,0xb9,0x76,0x20,0x00,0x99,0x5c,0xc5,0x5b,0xb1,0xda,0x7e,0x5b, +0x3d,0xd3,0x08,0xd4,0x67,0x15,0xb2,0x58,0x9e,0x1a,0xc4,0xdd,0xad,0x5b,0x76,0x12, +0x32,0x53,0x14,0xca,0x7e,0x54,0xaa,0x1c,0x9c,0x31,0x10,0xb7,0xb8,0x66,0x20,0x00, +0xa7,0x9b,0xc1,0x1a,0xa5,0x2c,0x69,0x5c,0x2a,0x8c,0x20,0x91,0x91,0x11,0xa5,0xcd, +0xab,0x95,0xbe,0x9a,0x9a,0x1a,0x5d,0x6b,0x26,0x2b,0x31,0xee,0x9c,0x6a,0xa0,0xd1, +0x9c,0x31,0x10,0x76,0xb8,0x66,0x10,0x00,0xb2,0x14,0xb6,0x13,0x92,0x93,0x4e,0x5b, +0x1d,0xec,0x4b,0x29,0xa9,0x23,0x9d,0x5b,0xb5,0x1b,0xb1,0x53,0x81,0xd3,0x46,0x53, +0x21,0x9c,0x5f,0x93,0xa6,0x21,0xa2,0x63,0x9c,0x31,0x10,0xdf,0xb7,0x66,0x20,0x00, +0xb2,0x6c,0xa8,0xab,0x74,0xa3,0x39,0x22,0x28,0x19,0x7b,0x14,0xac,0x9d,0xa9,0x5b, +0xb2,0xda,0x9f,0x13,0x68,0xdb,0x31,0x62,0x34,0xe2,0x86,0xa2,0xa6,0x5c,0xa4,0x9c, +0x9c,0x31,0x10,0xe6,0xb6,0x55,0x20,0x00,0xa2,0x4d,0x8b,0x08,0x5a,0xed,0x32,0x89, +0x43,0x32,0x74,0x6d,0x88,0xa4,0x98,0xe5,0xa4,0xb1,0xa7,0x30,0xa0,0xae,0x8b,0x0d, +0x7e,0xcd,0x7c,0xc9,0x82,0xed,0x8b,0x0d,0x9c,0x31,0x10,0xb0,0x94,0x21,0x00,0x00, +0xb9,0x0a,0xa7,0x85,0x7e,0xe9,0x57,0x49,0x3c,0xf2,0x40,0xcd,0x5c,0xcc,0x7e,0xea, +0x90,0xe1,0x8f,0x2d,0x7c,0xcd,0x69,0x31,0x57,0x12,0x5f,0x09,0x72,0xc8,0x88,0xe9, +0x9c,0x31,0x10,0xaf,0x73,0x21,0x00,0x00,0xcc,0x4d,0xbf,0x6c,0x9d,0x29,0x76,0xf0, +0x5c,0xd2,0x72,0x6a,0x9a,0xe9,0xbc,0xd0,0xb2,0x48,0x98,0xa6,0x7f,0x29,0x61,0x48, +0x4f,0x35,0x5c,0xae,0x73,0x51,0x82,0xea,0x9c,0x31,0x10,0xe5,0x53,0x21,0x00,0x00, +0x8d,0xa4,0x8c,0x99,0x79,0x51,0x32,0x52,0x2a,0x59,0x50,0xd5,0x7e,0x95,0x8a,0x91, +0x89,0x99,0x9e,0x21,0x8a,0x28,0x65,0xa1,0x6a,0x55,0x6d,0x6c,0x76,0x1e,0x76,0xa5, +0x9c,0x31,0x10,0xe5,0x53,0x21,0x00,0x00,0x62,0x1e,0x71,0xe0,0x6e,0x68,0x5d,0xda, +0x5e,0x19,0x61,0xdd,0x54,0xb5,0x39,0xa0,0x5a,0x9e,0x7d,0x21,0x75,0x51,0x85,0xf2, +0xa2,0xb1,0x7e,0x20,0x70,0x9e,0x49,0xd6,0x9c,0x31,0x10,0xae,0x43,0x33,0x20,0x00, +0x03,0x69,0x32,0x6d,0x8a,0x6d,0x7b,0x8d,0xab,0x6d,0x73,0x8d,0xa1,0x6d,0x21,0x49, +0x43,0x8d,0x62,0x49,0x72,0x0d,0xa5,0x51,0x93,0x71,0x45,0x51,0x5a,0x8a,0x6a,0xba, +0x9c,0x31,0x10,0x56,0x98,0x87,0x30,0x00,0x7b,0xbb,0x7b,0xbb,0x83,0xbb,0xb4,0xa8, +0xa8,0x5b,0x7b,0xcc,0x93,0xc3,0xa3,0xc3,0xbc,0x3a,0xa9,0xc3,0x43,0xd6,0x6b,0x52, +0x92,0x38,0xda,0xc4,0x53,0x3d,0x3b,0x53,0x9c,0x31,0x10,0x9f,0x96,0x77,0x20,0x00, +0x7d,0x6a,0x74,0xb3,0x35,0x6d,0x26,0x2b,0x36,0x6a,0x37,0x6b,0x27,0x6b,0x27,0x23, +0x33,0x1b,0x4b,0x1b,0x5b,0x5b,0x67,0x9c,0x7a,0xd3,0x8a,0x52,0x92,0x93,0x9a,0x54, +0x9c,0x31,0x10,0x6e,0x85,0x65,0x00,0x00,0xca,0x12,0xd9,0x20,0xd9,0x23,0xdc,0xad, +0xe1,0x3d,0xe4,0xb2,0xd0,0xba,0xbd,0x33,0xb9,0x43,0xad,0x44,0xa9,0xc2,0xad,0x43, +0xaa,0x44,0xb1,0x3b,0xae,0x3a,0xaa,0x3b,0x9c,0x31,0x10,0x9a,0x74,0x54,0x00,0x00, +0xd5,0xdc,0xc7,0x1d,0xc5,0xe3,0xa3,0x22,0xae,0x5b,0x92,0x14,0x97,0x1b,0x81,0x53, +0x7d,0xd2,0x75,0x92,0x6d,0xd3,0x69,0x14,0x4d,0x5d,0x52,0x5a,0x46,0xa2,0x45,0x6b, +0x9c,0x31,0x10,0x2d,0x64,0x43,0x00,0x00,0x01,0xa9,0x0e,0x5c,0x42,0x91,0x41,0x96, +0x25,0x9d,0x2a,0x15,0x22,0x56,0x3e,0x5c,0x4d,0x5d,0x5a,0xca,0x5d,0x91,0x36,0x54, +0x3d,0x29,0x55,0x69,0x49,0xe9,0x29,0x5d,0x9c,0x31,0x10,0xd9,0x63,0x43,0x00,0x00, +0x3a,0x32,0x51,0xbd,0x48,0xd5,0x41,0x49,0x49,0xc8,0x5a,0xc3,0x55,0xb5,0x40,0x34, +0x6e,0x31,0x7b,0x3b,0x83,0x53,0x69,0xd4,0x76,0x2d,0x96,0x1a,0x85,0xa1,0x7d,0xa3, +0x9c,0x31,0x10,0xb6,0x53,0x43,0x00,0x00,0x8d,0x4d,0x95,0xf3,0x96,0x6b,0x72,0xc3, +0x9a,0x24,0x71,0xaa,0x4a,0xa2,0x55,0x2c,0x7a,0x3d,0x61,0x42,0x29,0x4b,0x31,0xba, +0x5d,0x2b,0x6d,0xb4,0x5a,0x3d,0x52,0x42,0x9c,0x31,0x10,0x4c,0x43,0x22,0x00,0x00, +0x5a,0x60,0x4d,0x92,0x18,0xd5,0x4e,0x6d,0xa6,0xf3,0xb2,0x12,0x7d,0x93,0x65,0x93, +0x82,0x5b,0x81,0xdb,0x71,0x9a,0x95,0x93,0xbd,0xdb,0x9a,0x94,0x69,0xda,0x79,0x63, +0x9c,0x31,0x10,0x17,0x62,0x21,0x00,0x00,0x7f,0x12,0x7e,0x8a,0x74,0xc9,0x68,0xe5, +0x70,0x8c,0x7a,0x70,0x88,0xf1,0x9a,0x95,0xb4,0xd2,0xc4,0xb4,0xaf,0x8d,0x9a,0xad, +0x8c,0x8c,0x86,0xb1,0x7e,0x8d,0x73,0x31,0x9c,0x31,0x10,0xea,0x51,0x11,0x00,0x00, +0x55,0x6c,0x57,0x64,0x46,0xa1,0x3c,0xa5,0x43,0x19,0x3c,0x5a,0x36,0xed,0x38,0x91, +0x40,0x8b,0x48,0x9c,0x39,0x6a,0x43,0x4c,0x48,0x83,0x4c,0xe3,0x61,0x13,0x76,0x8a, +0x9c,0x31,0x10,0x46,0x42,0x33,0x00,0x00,0xa9,0xdc,0xaa,0x1b,0x9e,0x1b,0xa1,0xdb, +0xaa,0x1c,0xba,0x5b,0xc2,0x5b,0xa9,0xda,0xa9,0x9b,0xa1,0xda,0x9e,0x24,0xb2,0x23, +0xbd,0x52,0xc4,0xda,0xd6,0xdb,0x9e,0x4d,0x9c,0x31,0x10,0xe5,0x88,0x89,0x50,0x00, +0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x83,0xbb,0x83,0xbb,0x8b,0xbb,0x8b,0xbb,0xed,0xcb, +0xd2,0x71,0xd2,0xa4,0xf3,0x2b,0xe0,0xb5,0x74,0xda,0x9c,0x3b,0x8b,0x3b,0x63,0xb3, +0x9c,0x31,0x10,0x43,0x99,0x77,0x30,0x00,0x5d,0xdb,0x49,0xdb,0x59,0xdb,0x8e,0x29, +0xc2,0xad,0xa0,0xd1,0x21,0xc4,0x35,0xaa,0x4d,0xf4,0x15,0xeb,0x01,0xda,0x31,0xca, +0x45,0xd4,0x31,0xe4,0x21,0xe2,0x3d,0xe2,0x9c,0x31,0x10,0xa0,0x94,0x67,0x20,0x00, +0x5a,0xc3,0x65,0x33,0x76,0x24,0x82,0xb9,0x8c,0x2c,0xa0,0xbd,0xb5,0x2a,0xb9,0x42, +0xbd,0x63,0xaf,0x5c,0x9e,0x4b,0xa7,0x21,0xcd,0x9a,0xe5,0xbc,0xb6,0x5c,0x51,0xcb, +0x9c,0x31,0x10,0xfc,0xb7,0x77,0x30,0x00,0x64,0xd2,0x70,0xd4,0x9a,0xe4,0xb4,0xeb, +0x96,0xe2,0x55,0x1b,0x30,0xd4,0x62,0xd4,0xd4,0xd3,0xee,0xe2,0x8e,0xa3,0x1f,0x53, +0x08,0x12,0x88,0xf3,0xf4,0xb5,0xe1,0x1c,0x9c,0x31,0x10,0x1c,0xb8,0x87,0x30,0x00, +0x85,0x90,0x42,0x10,0x20,0x99,0x5e,0x1e,0xc1,0x6e,0xda,0x28,0xa1,0x9c,0x49,0xd1, +0x09,0x16,0x42,0x4d,0xc5,0x98,0xdd,0xe9,0xa9,0xa6,0x59,0xd9,0x11,0xdc,0x22,0xe0, +0x9c,0x31,0x10,0x1c,0xb8,0x87,0x30,0x00,0xad,0xca,0xe6,0x16,0xbd,0xe5,0x6d,0xe9, +0x2e,0x9d,0x0a,0x2a,0x89,0xe4,0xe5,0xd4,0xca,0x15,0x7d,0x9d,0x3a,0x21,0x04,0x54, +0x65,0xf1,0xdd,0x6e,0xd5,0xde,0x91,0x4d,0x9c,0x31,0x10,0x9a,0xb8,0x88,0x30,0x00, +0x51,0xd2,0x08,0x5b,0x3e,0x8c,0xcd,0x59,0xde,0x22,0xa5,0xa4,0x61,0xdc,0x1d,0xd2, +0x23,0x1a,0xb5,0xcc,0xe2,0x14,0xb1,0xe3,0x72,0x23,0x32,0x9b,0x0e,0x25,0x99,0xea, +0x9c,0x31,0x10,0x2c,0xb9,0x88,0x40,0x00,0xe5,0x9a,0xbe,0x14,0x7d,0xdc,0x42,0x1b, +0x05,0x11,0x71,0xe4,0xe5,0xac,0xca,0x22,0x8d,0x9a,0x51,0xdb,0x04,0xcc,0x52,0x04, +0xdd,0x99,0xd1,0xe2,0x99,0xa3,0x5d,0xdc,0x9c,0x31,0x10,0xb1,0xb8,0x88,0x40,0x00, +0x15,0x1c,0x2f,0x09,0xc9,0xcb,0xd9,0xd4,0xa9,0x9b,0x6e,0x23,0x26,0x62,0x13,0x33, +0xb2,0x1d,0xe1,0xcb,0xb2,0x0a,0x7a,0x1b,0x3a,0xa4,0x05,0x6c,0x91,0xf1,0xe1,0x63, +0x9c,0x31,0x10,0x39,0xb8,0x78,0x40,0x00,0xbe,0x5c,0x89,0xd3,0x46,0x53,0x00,0x4a, +0x6a,0x14,0xdd,0x34,0xce,0x73,0x99,0x6a,0x56,0x1b,0x08,0x94,0x4a,0x85,0xd1,0x51, +0xd6,0x19,0xa9,0x5c,0x65,0xdc,0x1d,0xab,0x9c,0x31,0x10,0x12,0xb8,0x78,0x30,0x00, +0x27,0x28,0xb6,0x13,0xd5,0xd5,0xb5,0xd4,0x71,0x92,0x2e,0x52,0x19,0xec,0x91,0xe4, +0xd5,0x5a,0xca,0x1a,0x85,0x9b,0x3e,0x5c,0x14,0xcb,0x6a,0x1b,0xc9,0x5b,0xce,0x24, +0x9c,0x31,0x10,0x6b,0xb7,0x66,0x30,0x00,0x9c,0xab,0x59,0x20,0x24,0x62,0x43,0x45, +0xaa,0xc3,0xcf,0x02,0xb4,0xdb,0x70,0xa5,0x3c,0xd2,0x36,0xdb,0x80,0xdc,0xbc,0x9c, +0xbe,0xda,0x8c,0xe3,0x5d,0x33,0x42,0xeb,0x9c,0x31,0x10,0xf0,0xa6,0x77,0x20,0x00, +0x33,0xa2,0xae,0xd3,0xe1,0x94,0xb5,0x13,0x5e,0xe3,0x30,0x9b,0x35,0x53,0x88,0xd3, +0xba,0xd5,0xb2,0xcb,0x84,0x8a,0x60,0xd1,0x50,0xd4,0x6a,0x9c,0x88,0x9c,0x92,0x9a, +0x9c,0x31,0x10,0xb0,0x87,0x66,0x20,0x00,0xa2,0x13,0x5a,0x0b,0x49,0xc3,0x71,0x4b, +0x99,0x8a,0xad,0x5a,0xb1,0x5b,0xae,0x24,0x90,0xdd,0xa1,0xda,0xbd,0x92,0xc1,0x9d, +0x9d,0xdb,0x85,0xd3,0x95,0xdc,0x9d,0xa2,0x9c,0x31,0x10,0x59,0x75,0x66,0x20,0x00, +0xb2,0xc5,0x98,0x7a,0xdb,0x46,0xda,0x75,0xb9,0xa9,0xbb,0xd8,0xb1,0x85,0xbc,0x85, +0xdd,0x75,0xec,0x5b,0x93,0x68,0x7b,0xa7,0x7a,0xa6,0x8d,0x87,0x6b,0x47,0x6a,0x67, +0x9c,0x31,0x10,0x14,0x75,0x65,0x10,0x00,0x4d,0xb1,0x49,0xa4,0x61,0xb5,0x80,0x39, +0x7d,0x3d,0x65,0xcc,0x4a,0x21,0x4a,0x43,0x66,0xa2,0x70,0xb2,0x74,0xca,0x71,0x4d, +0x50,0xab,0x34,0x5b,0x32,0x32,0x41,0xc1,0x9c,0x31,0x10,0x20,0x64,0x66,0x10,0x00, +0x43,0x6c,0x24,0x46,0x13,0x89,0x14,0x68,0x0b,0x56,0x20,0x95,0x51,0x67,0x69,0x79, +0x32,0x49,0x2a,0x87,0x13,0x76,0x1a,0x37,0x5c,0x86,0x73,0x87,0x4c,0x77,0x46,0x77, +0x9c,0x31,0x10,0x0b,0x64,0x54,0x10,0x00,0x35,0x2b,0x41,0x1a,0x62,0x1c,0x8a,0x12, +0x81,0xd8,0x5d,0xa2,0x51,0x55,0x41,0x15,0x45,0xa5,0x82,0x13,0x90,0x91,0x79,0xd9, +0x65,0x13,0x62,0x54,0x5d,0x9d,0x7d,0x12,0x9c,0x31,0x10,0xeb,0x54,0x55,0x10,0x00, +0xb3,0x3b,0x84,0x32,0x53,0x33,0x43,0xb4,0x22,0x34,0x63,0xc3,0x9a,0x23,0x92,0xb3, +0x6b,0xca,0x59,0x1a,0x4a,0xbc,0x49,0xbb,0x93,0xbb,0x8a,0xa8,0x9b,0x3c,0x91,0xbd, +0x9c,0x31,0x10,0xeb,0x54,0x55,0x10,0x00,0x81,0xb3,0x52,0xb2,0xa4,0x3b,0x95,0xbc, +0x6c,0xba,0x5a,0x3b,0x2b,0xbb,0x5b,0x3c,0x93,0x33,0xd3,0xaa,0xca,0xb4,0xd9,0xdc, +0xb1,0x44,0xc9,0xa9,0xc2,0x3a,0xc8,0xc3,0x9c,0x31,0x10,0xd8,0x65,0x55,0x20,0x00, +0x9b,0x51,0x82,0x71,0x5d,0xd2,0x53,0x6a,0x5b,0x69,0x9a,0x49,0xa3,0x64,0xb3,0x30, +0xc3,0x94,0xa2,0x91,0x8c,0x4a,0x72,0x12,0x6a,0x52,0x73,0x45,0x95,0xb1,0x7c,0x69, +0x9c,0x31,0x10,0xc0,0x88,0x76,0x20,0x00,0x85,0xdb,0x91,0xd2,0x7d,0xa4,0x79,0xdb, +0x79,0xe3,0x75,0xe3,0x79,0xda,0x86,0x1b,0x81,0xdd,0x7d,0xdc,0x7a,0x19,0x6d,0xd8, +0x79,0xa4,0x89,0xa4,0x6d,0x4c,0xfa,0xe6,0x9c,0x31,0x10,0xad,0x86,0x87,0x40,0x00, +0xbc,0x42,0x76,0x42,0x6c,0xc1,0x79,0xb3,0x3d,0xbc,0x3d,0xb5,0x4e,0xac,0x4e,0xaa, +0x61,0xc2,0x5e,0xaa,0x59,0x11,0x72,0xb2,0x8d,0x44,0x85,0xc6,0x81,0xd4,0x90,0x3b, +0x9c,0x31,0x10,0x0b,0x79,0x87,0x40,0x00,0x5a,0x90,0xaa,0x9b,0x4a,0x2c,0x7a,0x25, +0xca,0x2c,0xda,0x51,0x9a,0xc8,0xaa,0x22,0x92,0x33,0x9a,0xbd,0x9b,0xb4,0xbd,0xac, +0xae,0x31,0x75,0xa9,0x5c,0xb2,0x43,0xac,0x9c,0x31,0x10,0xb6,0x97,0x77,0x30,0x00, +0x61,0x8d,0x5e,0x0c,0x62,0x41,0x5e,0xca,0x66,0xf3,0x77,0x6b,0x8b,0x24,0x86,0x64, +0x92,0x6b,0x9a,0x23,0x9d,0xe2,0xbd,0x63,0xb8,0xe3,0xb5,0x23,0xc0,0xa3,0xc8,0x63, +0x9c,0x31,0x10,0xe3,0x97,0x64,0x00,0x00,0xc4,0xad,0xb5,0x2d,0xad,0x68,0xa5,0x69, +0x95,0x61,0x8d,0x5c,0x7d,0xa5,0x75,0xa1,0x6d,0xdd,0x61,0x9d,0x5d,0x9d,0x59,0xdd, +0x59,0xd9,0x55,0xdd,0x55,0xdd,0x55,0xdd,0x9c,0x31,0x10,0xed,0x83,0x22,0x00,0x00, +0x2e,0x8c,0x32,0x8c,0x37,0x22,0x3f,0x5b,0x46,0xd2,0x4c,0x94,0x50,0x94,0x56,0xd3, +0x5b,0x03,0x5f,0x52,0x65,0x8b,0x6b,0x5b,0x6f,0x51,0x73,0x1d,0x72,0xe3,0x74,0xeb, +0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00,0x12,0xa8,0x2a,0xa9,0x2b,0x60,0x3d,0xd2, +0x6e,0x24,0x5c,0xb9,0x58,0x9e,0x60,0x1e,0x6c,0xca,0x74,0xdd,0x82,0x4d,0x7a,0xd5, +0x9b,0x60,0x9f,0x5d,0xa9,0x8d,0x89,0x64,0x9c,0x31,0x10,0xcb,0x99,0x87,0x30,0x00, +0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x7b,0xbb,0x83,0xbb, +0x83,0xbb,0x8b,0xbb,0x8b,0xbb,0xd4,0x21,0xd9,0xee,0x61,0x63,0x83,0x4b,0x89,0xd2, +0x9c,0x31,0x10,0x20,0x87,0x86,0x20,0x00,0x51,0x6c,0x1c,0x63,0x95,0xb5,0x95,0xaa, +0x35,0x3a,0x21,0xba,0x49,0xc4,0x35,0xc3,0x15,0xbb,0x19,0xba,0x09,0xbc,0x39,0xbb, +0x95,0x3b,0xed,0x42,0x95,0x43,0x31,0xc3,0x9c,0x31,0x10,0xda,0x85,0x65,0x10,0x00, +0xa1,0xc3,0xd9,0x12,0x5d,0x3c,0x36,0xbb,0xab,0x30,0xbe,0x3c,0x4d,0xb5,0x29,0x13, +0x7e,0x3a,0x81,0x34,0x75,0x24,0x8d,0x3a,0xb1,0x64,0xc1,0x61,0xa4,0xd0,0x75,0x5d, +0x9c,0x31,0x10,0xe0,0xb5,0x76,0x20,0x00,0x7a,0xe5,0x77,0x63,0x7a,0xd2,0x83,0x11, +0x8e,0x9d,0x95,0x24,0x8e,0xdb,0x79,0x1a,0x5d,0x1b,0x4e,0xda,0x5e,0x5a,0x90,0x9d, +0xcc,0x6d,0xd4,0x6a,0xa8,0xa1,0x5d,0x63,0x9c,0x31,0x10,0x1f,0xc7,0x67,0x30,0x00, +0x4b,0x1c,0x38,0xeb,0x68,0xf3,0xa6,0x83,0xc4,0xd4,0xba,0xe3,0xa3,0x22,0x72,0xe3, +0x36,0x93,0x18,0x6d,0x5a,0xd3,0xa0,0x90,0xbc,0xdb,0xc0,0xe6,0xba,0xe3,0x98,0xda, +0x9c,0x31,0x10,0x2c,0xc7,0x77,0x40,0x00,0x4f,0x5a,0x10,0x23,0x23,0x93,0x82,0x91, +0xb1,0x08,0xba,0x96,0xbc,0x95,0xb6,0xda,0x8a,0x9b,0x3f,0x5b,0x10,0x1b,0x39,0x9a, +0x8a,0x63,0xa6,0xdb,0xba,0x9a,0xbe,0xdd,0x9c,0x31,0x10,0x1f,0xc7,0x67,0x30,0x00, +0xb6,0xd4,0x8d,0x12,0x45,0x22,0x16,0x1c,0x31,0x9b,0x7c,0x8c,0x9b,0x0c,0xbd,0x02, +0xc0,0x89,0xb9,0x15,0x9a,0xad,0x54,0xa2,0x1e,0xa2,0x27,0x14,0x6c,0xdb,0x95,0x14, +0x9c,0x31,0x10,0x24,0xc7,0x66,0x20,0x00,0xb5,0x19,0xbc,0xa2,0xb7,0x12,0xa6,0x93, +0x6a,0xa4,0x2f,0x53,0x1e,0x6b,0x52,0xe4,0x8a,0x6a,0xaa,0xe3,0xba,0xe4,0xb4,0xdc, +0xac,0xe2,0x80,0xda,0x4d,0x23,0x34,0x63,0x9c,0x31,0x10,0x70,0xc6,0x45,0x00,0x00, +0x40,0xc2,0x6d,0x55,0x8f,0xa5,0xa7,0x89,0xb1,0x65,0xb3,0x89,0xa6,0x75,0x87,0x75, +0x5d,0x85,0x35,0x55,0x30,0x65,0x59,0x55,0x8e,0x65,0xb5,0x71,0xc5,0x81,0xc4,0x85, +0x9c,0x31,0x10,0x08,0xc5,0x32,0x00,0x00,0xa3,0xca,0x6a,0x45,0x30,0x38,0x18,0xca, +0x3e,0x35,0x81,0x35,0xb6,0x45,0xce,0x98,0xce,0xca,0xb4,0xaa,0x7f,0xb5,0x45,0xc0, +0x1e,0x22,0x28,0x41,0x63,0x11,0xa2,0xb6,0x9c,0x31,0x10,0x08,0xc5,0x32,0x00,0x00, +0xc7,0x35,0xce,0x30,0xc1,0x41,0x9a,0x22,0x64,0x35,0x32,0x42,0x1c,0xb0,0x3e,0xd1, +0x7f,0x36,0xb3,0x46,0xc9,0x30,0xca,0x49,0xb6,0x38,0x89,0x49,0x53,0x36,0x28,0x24, +0x9c,0x31,0x10,0xcf,0xc5,0x43,0x00,0x00,0x24,0x69,0x54,0x4e,0x91,0x6a,0xbb,0x6d, +0xc9,0x4c,0xc5,0x89,0xa9,0x45,0x78,0x6a,0x44,0x89,0x21,0x05,0x2f,0x6d,0x69,0x0d, +0xa3,0x4d,0xc4,0x49,0xca,0x65,0xbe,0x65,0x9c,0x31,0x10,0xcf,0xc5,0x43,0x00,0x00, +0x98,0x68,0x65,0x69,0x35,0xa5,0x20,0x71,0x40,0xb5,0x7e,0x74,0xb1,0x8d,0xc7,0x4a, +0xc7,0x90,0xb2,0x75,0x88,0x76,0x57,0x71,0x2f,0x75,0x27,0x71,0x51,0x8d,0x8e,0x8d, +0x9c,0x31,0x10,0x40,0xc5,0x42,0x00,0x00,0xb8,0x8c,0xc5,0x50,0xc0,0x76,0xa9,0x54, +0x7e,0x6d,0x4e,0x4e,0x2a,0x24,0x2c,0x42,0x60,0x25,0x9a,0x68,0xbc,0x80,0xc3,0x62, +0xbc,0x6d,0xa1,0x6d,0x74,0x6c,0x46,0x86,0x9c,0x31,0x10,0x53,0xc6,0x54,0x10,0x00, +0x29,0x41,0x36,0x65,0x6c,0x35,0xa1,0x65,0xbc,0x65,0xc0,0x71,0xb7,0x65,0x99,0x75, +0x6e,0x85,0x43,0x95,0x2b,0x65,0x40,0x79,0x78,0x25,0xac,0x29,0xc0,0x61,0xc0,0x26, +0x9c,0x31,0x10,0xf2,0xc9,0x77,0x30,0x00,0xb8,0xed,0x88,0xcd,0x46,0xed,0x18,0xf5, +0x27,0x34,0x7e,0xf1,0xa3,0x11,0xb3,0x11,0xb1,0x0c,0xab,0x09,0xa3,0x02,0x6e,0xe1, +0x46,0xe0,0x32,0xc9,0x45,0x68,0x80,0xe5,0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00, +0x93,0x22,0xac,0xe1,0xaa,0xe0,0xad,0x01,0xaa,0xe2,0x78,0xc5,0x50,0xe9,0x2a,0xb1, +0x41,0x6c,0x80,0xc9,0x93,0x46,0xb0,0xc6,0xac,0xe0,0xaf,0x04,0xa6,0xe5,0x70,0xea, +0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00,0x4c,0xe5,0x28,0x92,0x47,0x88,0x84,0xa4, +0x93,0x4a,0xb0,0xc9,0xa6,0xe4,0xad,0x09,0xa6,0xe6,0x70,0xe9,0x54,0xe9,0x2c,0xb5, +0x47,0xb0,0x82,0xc9,0x8d,0x6a,0xae,0xcd,0x9c,0x31,0x10,0xce,0xc9,0x87,0x20,0x00, +0xa7,0x09,0xad,0x29,0xa6,0xe5,0x73,0x09,0x54,0xe9,0x2c,0xae,0x45,0x90,0x82,0x8d, +0x8d,0x4e,0xb0,0xc9,0xa5,0x0d,0xab,0x0a,0xa8,0xe4,0x76,0xe5,0x5a,0xed,0x32,0xf1, +0x9c,0x31,0x10,0x89,0xc9,0x88,0x10,0x00,0x3d,0xa3,0x80,0x9d,0x87,0x1a,0xac,0xda, +0xa5,0x14,0xa9,0x14,0xaa,0xda,0x7e,0xcb,0x5e,0xd3,0x3b,0x12,0x37,0x2d,0x7a,0xaa, +0x84,0xe2,0xa6,0xe4,0xa7,0x23,0xa4,0xe2,0x9c,0x31,0x10,0xd5,0xc8,0x88,0x20,0x00, +0xac,0xec,0x86,0xdb,0x63,0x13,0x45,0x4b,0x30,0x5b,0x70,0x71,0x80,0xb5,0xa2,0xeb, +0xa9,0x23,0xa4,0xdc,0xac,0xda,0x8e,0xe3,0x66,0xdc,0x4b,0x5b,0x30,0x02,0x6a,0xa4, +0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00,0x80,0x95,0x9d,0x39,0xa8,0xd2,0xa2,0xf5, +0xa8,0xe9,0x94,0xd1,0x6a,0xf5,0x53,0x0d,0x32,0x45,0x5f,0x22,0x80,0x94,0x93,0x31, +0xa8,0xd1,0xa2,0xe5,0xa8,0xee,0x9a,0xe1,0x9c,0x31,0x10,0xd5,0xc8,0x88,0x20,0x00, +0x70,0xdb,0x56,0xdb,0x38,0x2c,0x53,0x82,0x7e,0x53,0x8d,0x54,0xa6,0xa3,0xa4,0xdb, +0xa6,0xdb,0x9e,0xdb,0x78,0x94,0x5a,0xd3,0x3e,0x9b,0x49,0x69,0x7a,0x8d,0x8b,0x1a, +0x9c,0x31,0x10,0x4f,0xb7,0x86,0x20,0x00,0xc5,0x2e,0xc9,0xc2,0xc6,0x43,0xbd,0xb5, +0x7d,0x22,0x3d,0xb3,0x0d,0xc1,0x13,0x64,0x69,0x9d,0x96,0x38,0xbd,0xb5,0xc5,0xc9, +0xc2,0x2c,0xb9,0xc3,0x85,0xc3,0x4a,0x3c,0x9c,0x31,0x10,0x14,0xb6,0x77,0x10,0x00, +0x21,0x4a,0x15,0xad,0x5a,0xd8,0x92,0xdd,0xb6,0xd2,0xc2,0xdc,0xb8,0xd3,0xa4,0xe3, +0x78,0xdb,0x4f,0x1a,0x3f,0x14,0x44,0xd2,0x68,0xa4,0x8c,0x9b,0xa4,0xe3,0xa4,0xdb, +0x9c,0x31,0x10,0xfb,0x94,0x53,0x00,0x00,0xee,0xe5,0xc2,0xc6,0x90,0xb0,0x6e,0xd6, +0x5f,0x30,0x6e,0xae,0x82,0xf1,0x8c,0xed,0x8c,0x4d,0x85,0x2d,0x78,0x6d,0x6d,0x0c, +0x66,0xee,0x62,0xcd,0x67,0x71,0x6f,0xad,0x9c,0x31,0x10,0xad,0x65,0x55,0x00,0x00, +0x21,0x1b,0x59,0x9b,0x7a,0x53,0x89,0xaa,0x9d,0xd3,0x8d,0xd3,0x66,0x0b,0x29,0x9b, +0x02,0x2b,0x39,0xdb,0x3a,0x1a,0x56,0xdc,0x72,0x9a,0xae,0x5b,0xb2,0x0d,0x1c,0xca, +0x9c,0x31,0x10,0xf4,0x95,0x44,0x00,0x00,0x78,0x8b,0x70,0xe3,0x65,0x29,0x5c,0xa6, +0x63,0x6b,0x6c,0xd9,0x64,0xf4,0x7f,0x5b,0xac,0x93,0xc0,0x53,0xc0,0xe3,0xc5,0x1b, +0xb4,0x9c,0x8d,0x1b,0x66,0xcd,0x62,0xd0,0x9c,0x31,0x10,0xf4,0x95,0x44,0x00,0x00, +0x6c,0x65,0x6a,0xe3,0x5f,0x19,0x58,0xf4,0x4c,0xd3,0x4e,0xec,0x59,0x0b,0x7e,0x52, +0xaa,0xd3,0xca,0xe3,0xd0,0xa4,0xb8,0xdb,0x92,0xdb,0x68,0x93,0x4e,0xdb,0x55,0x1c, +0x9c,0x31,0x10,0x65,0x85,0x44,0x10,0x00,0x5c,0xc9,0x87,0x62,0x7f,0xa1,0x5e,0xde, +0x52,0x61,0x52,0xdc,0x64,0xe4,0x78,0x5b,0xb1,0x1a,0xc8,0xdb,0xb2,0xe4,0x94,0xe2, +0x7b,0x5b,0x60,0xe3,0x50,0x9a,0x62,0xe4,0x9c,0x31,0x10,0xdf,0x88,0x97,0x20,0x00, +0x7b,0xbb,0x8b,0xbb,0x8b,0xbb,0x83,0xbb,0x8b,0x3b,0xb2,0xb5,0xd8,0x9a,0x71,0x64, +0x3b,0x62,0x7b,0x33,0x93,0xb3,0x83,0xbb,0x6b,0xbb,0x83,0xbb,0x83,0xbb,0x94,0xcd, +0x9c,0x31,0x10,0x8a,0x97,0x87,0x20,0x00,0x8a,0x39,0x4e,0x0b,0x72,0xb4,0x81,0xc2, +0x96,0x34,0x79,0xba,0x79,0xbb,0x85,0x34,0x6a,0x43,0x51,0xc3,0x55,0xbb,0x61,0x3b, +0x59,0xbb,0x49,0xbb,0x3d,0xbb,0x3d,0xbb,0x9c,0x31,0x10,0x08,0x96,0x66,0x20,0x00, +0x35,0x83,0x2d,0xa3,0x4d,0x95,0x80,0xe0,0xb1,0xa3,0xdd,0xdb,0xe9,0x64,0xd9,0xa3, +0xc5,0xdb,0xb5,0x9b,0xa5,0xdb,0x99,0xdb,0x95,0xdb,0x89,0xdb,0x7d,0xdb,0x71,0xdb, +0x9c,0x31,0x10,0x0c,0x62,0x33,0x00,0x00,0x0c,0xaa,0x2b,0x23,0x56,0xa3,0x83,0x53, +0x80,0x64,0x6a,0xdd,0x4f,0x1a,0x4f,0x53,0x63,0x22,0x7e,0xe1,0xa4,0xd4,0xae,0xd3, +0xa6,0x5b,0x8c,0x1c,0x6d,0x1b,0x55,0x1b,0x9c,0x31,0x10,0x69,0x53,0x22,0x00,0x00, +0x32,0x5b,0x5a,0x2a,0x72,0x2c,0x6e,0x1b,0x66,0x23,0x4d,0x62,0x39,0x1b,0x2d,0x94, +0x35,0xd3,0x51,0xe2,0x61,0x74,0x72,0x52,0x6a,0x0c,0x60,0xd2,0x59,0x55,0x61,0x9a, +0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00,0x66,0x5d,0x93,0x5d,0x8a,0x28,0x97,0x1d, +0xa1,0xce,0x9c,0xb8,0x9d,0x96,0xa0,0xd1,0xc3,0x22,0xb9,0x45,0xce,0xa0,0xc7,0x35, +0xb6,0x15,0xa2,0x99,0x8d,0x59,0x85,0x0c,0x9c,0x31,0x10,0xb7,0x33,0x22,0x00,0x00, +0x7b,0xdb,0x92,0xbb,0x84,0x1b,0x84,0x43,0x85,0x24,0x7b,0xb3,0x9a,0xd1,0xb4,0x44, +0xaa,0xcb,0xca,0x33,0xab,0x1b,0xac,0x44,0x65,0xc3,0x4c,0xac,0x23,0xcb,0x23,0xdc, +0x9c,0x31,0x10,0x83,0x22,0x21,0x00,0x00,0x5a,0x22,0x9b,0x29,0xa9,0x14,0xcc,0xb5, +0xee,0xcb,0xb3,0xbc,0x36,0xda,0x4b,0xcc,0x23,0xb5,0x19,0x2a,0x62,0x29,0x3c,0x3d, +0x62,0x3b,0x55,0xe1,0x56,0xb4,0x6c,0xa4,0x9c,0x31,0x10,0xcf,0x34,0x21,0x00,0x00, +0x5c,0x19,0x83,0x21,0xa3,0xa4,0x83,0x19,0xab,0xad,0x8c,0xa0,0x8c,0x95,0x8c,0xa1, +0x5b,0xb5,0x53,0x6a,0x6b,0x59,0x1a,0x9d,0x3c,0x28,0x33,0xec,0xcc,0x11,0xb6,0x90, +0x9c,0x31,0x10,0x7d,0x88,0x78,0x30,0x00,0x7b,0xb7,0x7b,0xb7,0x7b,0xb7,0x7b,0xb7, +0x7b,0xb7,0x7b,0xb7,0x7b,0xb7,0x7b,0xb7,0x7b,0xb7,0x83,0xb7,0x83,0xb7,0x83,0xb7, +0x83,0xb7,0x8b,0x37,0xcb,0x06,0xd8,0x1c,0x9c,0x31,0x10,0x56,0x98,0x87,0x30,0x00, +0x84,0x5a,0x8b,0xc2,0xab,0xbb,0xaa,0x34,0x64,0xe9,0x6b,0xc5,0x74,0x4a,0x6c,0x42, +0x64,0x44,0x5b,0xbb,0x5c,0xba,0x6b,0xbc,0x7c,0x3c,0x83,0x3a,0xde,0x43,0x89,0xb3, +0x9c,0x31,0x10,0xf0,0xa6,0x77,0x20,0x00,0x5b,0x0b,0x5b,0x0a,0x59,0x13,0x3a,0x9c, +0x32,0xd3,0x46,0x62,0x57,0x63,0x60,0xe3,0x62,0xdc,0x73,0x12,0x82,0x94,0x8a,0xd3, +0x92,0x5c,0x96,0xd9,0x98,0xe5,0x92,0x5a,0x9c,0x31,0x10,0x87,0x96,0x67,0x20,0x00, +0xa1,0x31,0xa6,0xdd,0xaf,0x1b,0x99,0xe1,0x9d,0xed,0xa6,0x9b,0xba,0x11,0xb6,0x0d, +0xb9,0x93,0xbd,0x52,0xb5,0x85,0xc1,0x13,0xbd,0xa1,0xb1,0x74,0xa2,0x2b,0x9e,0x73, +0x9c,0x31,0x10,0xe3,0x76,0x66,0x20,0x00,0xdd,0x5a,0xc5,0xbc,0x6c,0xa2,0x6c,0x02, +0x6c,0x0d,0x73,0xb3,0x74,0xba,0xa2,0x3c,0x8a,0x2b,0x8b,0xa1,0xaa,0xc5,0xab,0xc3, +0x84,0x2a,0x63,0xeb,0x7e,0x5c,0x5c,0x5a,0x9c,0x31,0x10,0xc4,0x86,0x56,0x10,0x00, +0x5f,0x14,0x66,0x0c,0x5a,0x0a,0x52,0x43,0x56,0x04,0x5e,0x1a,0x52,0x0b,0x41,0x4b, +0x3d,0xe2,0x49,0xed,0x45,0x90,0x55,0xeb,0x65,0xa6,0x6a,0x2a,0x55,0x93,0x69,0x93, +0x9c,0x31,0x10,0x2c,0x75,0x66,0x00,0x00,0x43,0x69,0x2b,0x81,0x33,0x9b,0x49,0x9a, +0x63,0xa1,0x73,0x6a,0x64,0x69,0x9a,0x33,0x7a,0x59,0x74,0x68,0x5b,0x54,0x41,0x88, +0x19,0x58,0x6a,0x54,0x8a,0x9a,0xa3,0xb9,0x9c,0x31,0x10,0x12,0xa6,0x66,0x00,0x00, +0x82,0xf1,0x7f,0x6c,0x6d,0x1a,0x69,0x1b,0x69,0x14,0x77,0x52,0x88,0x93,0xa1,0x0a, +0xa4,0x52,0x94,0xd3,0x70,0x55,0x4c,0xa1,0x2c,0xaa,0x2f,0x2e,0x6a,0xe8,0xbb,0x2c, +0x9c,0x31,0x10,0x51,0xc7,0x66,0x00,0x00,0x9a,0xd3,0x98,0xd2,0x8c,0xd4,0x76,0x92, +0x5c,0xca,0x4e,0x96,0x58,0xa2,0x89,0x21,0xac,0xae,0xa8,0xca,0x9c,0xd1,0x8b,0x1d, +0x6a,0xe2,0x49,0x2b,0x38,0x9d,0x65,0x49,0x9c,0x31,0x10,0xde,0xc7,0x67,0x00,0x00, +0x9c,0xda,0xa9,0x06,0xaa,0xc2,0xa8,0x92,0x9c,0xdc,0x70,0x9a,0x49,0x1a,0x3a,0xb4, +0x4f,0xaa,0x88,0xd4,0xa0,0xd3,0xa4,0xdb,0xa6,0xcb,0xa8,0xeb,0x94,0xeb,0x6c,0x6b, +0x9c,0x31,0x10,0x75,0xc7,0x86,0x10,0x00,0x49,0x9d,0x3a,0x9d,0x51,0x59,0x8a,0x95, +0x9c,0xd9,0x9a,0xd5,0xa0,0xdd,0xa8,0xdd,0xa0,0xed,0x7c,0xf2,0x55,0x68,0x3c,0xdd, +0x41,0x61,0x7e,0xd9,0x9a,0xd9,0x98,0xd9,0x9c,0x31,0x10,0x95,0xc8,0x76,0x10,0x00, +0x9e,0xec,0xa8,0xed,0xa6,0xed,0x8e,0xe1,0x66,0xa1,0x48,0xe6,0x34,0x64,0x5f,0x11, +0x96,0xb5,0x96,0xf1,0x98,0xd1,0xa6,0xed,0xa8,0xcd,0x9a,0xc1,0x80,0xac,0x5d,0x16, +0x9c,0x31,0x10,0xc6,0xc7,0x77,0x00,0x00,0x3c,0xf2,0x3d,0x34,0x82,0xf3,0x9a,0xf2, +0x91,0x14,0xa1,0x0a,0xa8,0xc3,0x9c,0x4c,0x94,0x8b,0x7a,0x2a,0x53,0x6c,0x36,0x74, +0x4d,0xa9,0x8e,0xcd,0x93,0x02,0x93,0x13,0x9c,0x31,0x10,0xae,0xc8,0x77,0x00,0x00, +0xa4,0xee,0xa5,0x0d,0x98,0xcd,0x94,0xe5,0x7a,0x90,0x53,0x55,0x38,0xb5,0x51,0x6c, +0x8e,0xe6,0x8f,0x00,0x92,0xe9,0xa2,0xe6,0xa0,0xe8,0x9a,0xce,0x96,0xc9,0x7a,0xb5, +0x9c,0x31,0x10,0x1a,0xc8,0x77,0x10,0x00,0x51,0x5a,0x38,0xd5,0x4b,0x75,0x8c,0xe6, +0x8f,0x04,0x93,0x0a,0xa3,0x05,0x9e,0xe9,0x9a,0xae,0x98,0xc5,0x7e,0xad,0x54,0xf6, +0x3c,0xf8,0x43,0x1a,0x85,0x0d,0x90,0xf1,0x9c,0x31,0x10,0xae,0xc8,0x77,0x00,0x00, +0x91,0x06,0xa3,0x08,0xa0,0xc6,0x98,0xe1,0x99,0x0d,0x89,0x0d,0x5c,0xc5,0x48,0xed, +0x38,0x65,0x6b,0x2e,0x92,0x91,0x8f,0x15,0x98,0xe9,0xa0,0xed,0x9d,0x0d,0x9b,0x31, +0x9c,0x31,0x10,0xa9,0xc8,0x86,0x00,0x00,0x93,0x30,0x6c,0xd2,0x4f,0x49,0x3a,0xed, +0x4f,0x8d,0x8a,0xea,0x8e,0xe8,0x92,0xea,0xa0,0xe9,0x9e,0xed,0x9a,0xd1,0x98,0xc8, +0x84,0xe6,0x5a,0xc8,0x46,0xe9,0x3a,0x6c,0x9c,0x31,0x10,0xc1,0xc7,0x86,0x00,0x00, +0x6c,0xe2,0x92,0x5d,0x89,0x20,0x9a,0xe2,0xa4,0xa0,0x9d,0x26,0x9d,0x25,0x93,0xa9, +0x6c,0xda,0x4f,0x4d,0x3c,0xcd,0x4f,0x9d,0x8a,0x9d,0x8a,0xe1,0x8e,0xe1,0xa3,0x1d, +0x9c,0x31,0x10,0xae,0xc8,0x77,0x00,0x00,0x9e,0xe5,0x98,0xc9,0x9a,0xc1,0x82,0xc1, +0x5a,0xc5,0x48,0xed,0x38,0x6d,0x6b,0x0e,0x90,0x98,0x8b,0x16,0x9a,0xd1,0xa2,0xed, +0x98,0xe9,0x98,0xad,0x94,0xc1,0x76,0x88,0x9c,0x31,0x10,0xfa,0xc7,0x87,0x10,0x00, +0x55,0x26,0x42,0xdc,0x40,0x61,0x80,0xa8,0x90,0x6d,0x8b,0x21,0x9c,0xdd,0x9e,0xd9, +0x97,0x1c,0x9b,0x1e,0x8d,0x15,0x6b,0x15,0x53,0x15,0x3e,0xdc,0x55,0xa2,0x8e,0x9d, +0x9c,0x31,0x10,0xa9,0xc8,0x86,0x00,0x00,0x8d,0x0d,0x91,0x2d,0xa1,0x0c,0x9b,0x0e, +0x98,0xed,0x99,0x09,0x89,0x06,0x64,0xc9,0x51,0x0d,0x3a,0x8d,0x5f,0x68,0x94,0xb2, +0x87,0x0d,0x93,0x10,0xa1,0x0e,0x99,0x0c,0x9c,0x31,0x10,0x21,0xc8,0x76,0x00,0x00, +0x98,0xca,0x98,0xc1,0x82,0xe1,0x60,0xea,0x4f,0x0c,0x3c,0x2e,0x6d,0x29,0x94,0x90, +0x87,0x0e,0x96,0xf0,0x9c,0xce,0x96,0xe9,0x98,0xb1,0x98,0xe5,0x80,0xc5,0x5e,0xc9, +0x9c,0x31,0x10,0xda,0xb8,0x76,0x00,0x00,0x19,0xa3,0x00,0x91,0x66,0x56,0xa1,0x18, +0x8e,0x1c,0xad,0x9b,0xb9,0xa1,0xad,0xdc,0xad,0x63,0xad,0x8a,0x81,0x8c,0x3d,0x92, +0x19,0xe4,0x04,0x91,0x76,0x14,0xa5,0x23,0x9c,0x31,0x10,0xaf,0xb8,0x76,0x20,0x00, +0x8a,0x71,0xad,0xa6,0xb1,0xa1,0xa5,0xdb,0xb1,0x94,0xb1,0x8a,0x81,0x8c,0x3d,0x9b, +0x1e,0x24,0x08,0xd9,0x79,0xed,0xa5,0x2a,0x8a,0x2a,0xa9,0xdd,0xad,0xa0,0xa5,0xdd, +0x9c,0x31,0x10,0x6e,0xb8,0x76,0x10,0x00,0xb1,0xcb,0xb1,0xca,0x85,0x95,0x41,0x99, +0x22,0x2d,0x08,0xd0,0x72,0x26,0xa9,0x22,0x8a,0x21,0xa1,0xa5,0xad,0xda,0xa1,0xe3, +0xa9,0xdb,0xb1,0xcb,0x8a,0x0a,0x4d,0x93,0x9c,0x31,0x10,0xe6,0xb8,0x86,0x10,0x00, +0x2a,0x5d,0x10,0xa1,0x5e,0x8d,0xa5,0x19,0x8a,0x1e,0x99,0xdc,0xad,0xe1,0xa5,0xdd, +0xa5,0xdc,0xad,0xdd,0x91,0xdd,0x55,0x9d,0x2e,0x19,0x11,0x61,0x42,0x9d,0xa1,0x9a, +0x9c,0x31,0x10,0x06,0xb7,0x76,0x10,0x00,0x91,0x11,0x94,0xd4,0xac,0xd2,0xac,0xe4, +0xa8,0xda,0xab,0x24,0x9b,0x1a,0x62,0xdb,0x37,0x13,0x1a,0xe3,0x2d,0x6c,0x94,0xe2, +0x9a,0xdb,0x8f,0x13,0xa5,0x13,0xae,0xd3,0x9c,0x31,0x10,0xb5,0xb5,0x65,0x10,0x00, +0xa7,0x55,0xa9,0x6e,0xa1,0x70,0x6e,0xe5,0x39,0x5a,0x1f,0x58,0x24,0x62,0x85,0x34, +0x9e,0x72,0x91,0x68,0x9e,0xdd,0xac,0xda,0xa8,0xd4,0xa5,0x29,0x9e,0xf1,0x7c,0xe5, +0x9c,0x31,0x10,0xaa,0xb7,0x66,0x00,0x00,0x46,0xda,0x25,0x1c,0x20,0x49,0x6c,0xdd, +0x9c,0x62,0x95,0x33,0x98,0xf4,0xac,0xea,0xac,0xe3,0xa2,0xcb,0x9e,0x8b,0x88,0x9a, +0x56,0xe4,0x2d,0x1a,0x20,0xa4,0x55,0x42,0x9c,0x31,0x10,0x01,0xb5,0x65,0x00,0x00, +0x94,0x4d,0x9d,0x8e,0x96,0x58,0x9c,0x99,0xaa,0xa1,0xa6,0xa5,0x9a,0xdd,0x8d,0x19, +0x6c,0xd1,0x44,0x9d,0x30,0xd9,0x44,0xdd,0x7c,0xe4,0x9e,0xe2,0x9c,0xe1,0x95,0x21, +0x9c,0x31,0x10,0x69,0x94,0x44,0x00,0x00,0xe5,0x25,0xf1,0x2a,0xba,0xeb,0x7d,0x73, +0x4e,0x6c,0x30,0xe3,0x1f,0x25,0x29,0x22,0x4e,0xe2,0x75,0x1c,0x9c,0xa2,0xbf,0x1b, +0xda,0xdc,0xe2,0xdb,0xca,0xdb,0x9e,0xdb,0x9c,0x31,0x10,0x55,0x92,0x22,0x00,0x00, +0x6e,0xea,0x44,0xdb,0x30,0x94,0x3c,0xcb,0x5c,0x53,0x83,0x1c,0x9e,0x99,0xa1,0x14, +0x95,0xa4,0x8a,0x1b,0x7e,0xdb,0x78,0xe3,0x7d,0x5a,0x81,0x23,0x7e,0xe4,0x7d,0x5a, +0x9c,0x31,0x10,0xaf,0x73,0x21,0x00,0x00,0x4e,0xb1,0x39,0x11,0x54,0xae,0x70,0xcd, +0x93,0x0d,0xb7,0x11,0xbb,0x6e,0xb5,0x0d,0xa7,0x04,0x9a,0xec,0x86,0xce,0x82,0xd2, +0x7e,0x88,0x71,0x15,0x7f,0x08,0x80,0xe9,0x9c,0x31,0x10,0x17,0x62,0x21,0x00,0x00, +0x7a,0xc9,0x8e,0xce,0x8e,0xac,0xa0,0x91,0xc7,0x4d,0xda,0x85,0xc0,0xf2,0x9d,0x2e, +0x78,0xf1,0x47,0x8d,0x53,0x08,0x70,0xe1,0x84,0x71,0x98,0xa8,0x8e,0xb5,0x8c,0x92, +0x9c,0x31,0x10,0xc9,0x42,0x32,0x00,0x00,0xc5,0x5b,0xe9,0xdc,0xe5,0xdc,0xca,0x12, +0xaa,0xdb,0x26,0x1b,0x05,0x9c,0x47,0x5b,0x28,0xdb,0x39,0xdb,0x1d,0x9a,0x3b,0x1d, +0x75,0xe2,0xb6,0x1b,0xc1,0xeb,0xad,0x9a,0x9c,0x31,0x10,0x24,0x98,0x76,0x10,0x00, +0x7d,0xdb,0x79,0xdb,0x75,0xdb,0x79,0xdb,0x79,0xdb,0x79,0xdb,0x79,0xdb,0x79,0xdb, +0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x8a,0x1b,0x85,0xda,0xe3,0x76, +0x9c,0x31,0x10,0x4c,0x88,0x75,0x20,0x00,0xc0,0x94,0x41,0xcc,0x5a,0x29,0x79,0xe9, +0x62,0x09,0x65,0xca,0x79,0xa9,0x85,0xc9,0x7d,0xce,0x5d,0xcd,0x3d,0xd0,0x3d,0xd1, +0x41,0xf0,0x41,0xf1,0x31,0xd1,0x29,0xed,0x9c,0x31,0x10,0x54,0x84,0x54,0x00,0x00, +0x2c,0xe5,0x29,0x51,0x31,0x0a,0x46,0x8c,0x66,0xd3,0x80,0x52,0x84,0xa4,0x8c,0xeb, +0x82,0xf3,0x84,0xec,0x92,0x62,0xa7,0x9b,0xad,0x13,0xb9,0x4b,0xbb,0x0b,0xb8,0x92, +0x9c,0x31,0x10,0x73,0x73,0x42,0x00,0x00,0xe4,0x2a,0xd8,0x5b,0xdc,0xeb,0xc6,0x6c, +0xd2,0x64,0xd2,0x52,0xc6,0xad,0xb5,0x92,0xb6,0x20,0xb1,0x2d,0xa9,0xa1,0x9c,0xbd, +0x9d,0xd4,0x99,0xd0,0x95,0xcd,0x90,0xd3,0x9c,0x31,0x10,0x71,0x53,0x32,0x00,0x00, +0xb1,0xe1,0xca,0x1c,0xb2,0xcc,0xa2,0x12,0xc1,0x4b,0xba,0x5c,0xd2,0x69,0x8d,0xe4, +0x7a,0x51,0x69,0xcc,0x6a,0x93,0x48,0x54,0x45,0x8c,0x71,0x58,0x65,0xce,0x39,0x1a, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_EIGHT.txt b/config/_default_cfg_src_/res/en/SOUND_EIGHT.txt new file mode 100644 index 0000000..c6be372 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_EIGHT.txt @@ -0,0 +1,145 @@ +0x9c,0x31,0x10,0x68,0x43,0x34,0x21,0x00,0x7b,0x6d,0x7b,0x6d,0x83,0x6d,0x8a,0x6d, +0xd4,0x49,0xd4,0x2d,0xb5,0x6d,0xc2,0x4d,0x94,0x6d,0x93,0x6d,0xac,0x89,0x9c,0x8d, +0x7b,0x64,0x92,0x64,0xa9,0x08,0x9a,0x4c,0x9c,0x31,0x10,0x63,0x76,0x87,0x40,0x00, +0x94,0xd1,0xd2,0xba,0x45,0x6a,0x57,0x2a,0x96,0xc9,0x36,0xa9,0x46,0xec,0x87,0x10, +0x56,0xed,0x66,0xcd,0x86,0xed,0x56,0xed,0x66,0xed,0x86,0xed,0x66,0xed,0x66,0xed, +0x9c,0x31,0x10,0xb6,0x53,0x43,0x00,0x00,0xdd,0x55,0x70,0xbd,0x3d,0xad,0xba,0x1a, +0x76,0x40,0x41,0xdc,0x82,0x45,0x89,0x2b,0x55,0xaa,0x9a,0x23,0x8c,0xc3,0x61,0xca, +0x81,0xbb,0x79,0xac,0x72,0x42,0x89,0x3a,0x9c,0x31,0x10,0x2e,0x74,0x54,0x10,0x00, +0xa5,0x14,0xb0,0xc0,0x3d,0xea,0x66,0xa5,0x8e,0x5b,0x46,0x13,0x65,0x52,0x8d,0xa3, +0x65,0x9c,0x7e,0x14,0x91,0xe4,0x7a,0x58,0x7a,0x53,0x95,0xa3,0x81,0xdb,0x81,0xdc, +0x9c,0x31,0x10,0x0f,0xc8,0xa8,0x60,0x00,0x7d,0xbb,0x7d,0xbb,0x7d,0xbb,0x7d,0xbb, +0x7d,0xbb,0x7d,0xbb,0x7d,0xbb,0x81,0xbb,0x8a,0xc5,0x8d,0xb4,0x8f,0x46,0x85,0xc1, +0x4a,0x99,0x29,0xda,0x9d,0x68,0x95,0x1c,0x9c,0x31,0x10,0x92,0xc9,0xa8,0x60,0x00, +0x69,0xa4,0xc6,0xcb,0xb1,0x54,0x1e,0xac,0x35,0xb5,0xb9,0x58,0x7d,0xbb,0x69,0xab, +0xca,0x3a,0xb9,0x5b,0x46,0x33,0x1c,0x2c,0x8e,0x36,0x9d,0x52,0x6a,0x39,0xae,0x34, +0x9c,0x31,0x10,0x7b,0xc9,0x98,0x50,0x00,0xcc,0x93,0x63,0x1a,0x14,0xa3,0x69,0x58, +0xb4,0x84,0x6b,0x23,0x9b,0x2e,0xd6,0x8c,0x79,0x0a,0x14,0xa0,0x4f,0x74,0xbe,0x8c, +0x74,0xcc,0x93,0x23,0xd4,0xdc,0x7f,0x12,0x9c,0x31,0x10,0x53,0xc9,0xa8,0x50,0x00, +0x15,0xb1,0x4f,0x51,0xc1,0x62,0x71,0x96,0x91,0xad,0xd1,0xdc,0x7e,0x43,0x11,0xa1, +0x42,0x54,0xbd,0x43,0x7d,0x2a,0x91,0xba,0xd1,0xcc,0x82,0x35,0x0d,0xb3,0x3e,0x54, +0x9c,0x31,0x10,0xe6,0xc8,0x98,0x50,0x00,0xc4,0x9b,0x84,0x8a,0x90,0xda,0xd2,0xe2, +0x81,0x15,0x0d,0x1c,0x3f,0x6c,0xc8,0x93,0x86,0x8a,0x90,0xe2,0xcc,0x98,0x81,0x15, +0x09,0x24,0x3d,0xac,0xc8,0x8c,0x88,0x93,0x9c,0x31,0x10,0x69,0xc8,0x99,0x50,0x00, +0x92,0xaa,0xcc,0xd2,0x7f,0x0b,0x08,0xec,0x3b,0x6b,0xc6,0x84,0x8e,0xdb,0x94,0xeb, +0xca,0x91,0x7f,0x13,0x07,0x2b,0x35,0xab,0xca,0x84,0x94,0xdb,0x92,0xeb,0xca,0xd1, +0x9c,0x31,0x10,0x69,0xc8,0x99,0x50,0x00,0x84,0xd3,0x09,0x33,0x2b,0x64,0xc8,0x84, +0x9a,0x9b,0x8e,0xe3,0xc6,0xd1,0x8c,0xd4,0x0d,0x2c,0x21,0x23,0xc2,0x8b,0xa0,0x9b, +0x8a,0xe2,0xc2,0xd2,0x9a,0xd4,0x15,0x2b,0x9c,0x31,0x10,0x6f,0xd8,0x88,0x40,0x00, +0x48,0xf4,0x9e,0xca,0x94,0x92,0x81,0x29,0x9c,0xe4,0x92,0xc6,0x51,0x23,0x42,0x6c, +0x97,0x22,0x9a,0x49,0x7f,0x63,0x98,0xe6,0x9a,0xcb,0x5b,0x1b,0x3c,0x1a,0x8b,0x72, +0x9c,0x31,0x10,0x6f,0xd8,0x88,0x40,0x00,0xa2,0x14,0x7f,0x55,0x92,0xeb,0xa0,0x99, +0x69,0x13,0x38,0x12,0x77,0x94,0xa8,0x6b,0x85,0x52,0x8a,0x9a,0xa2,0xa5,0x7a,0xd3, +0x3a,0x64,0x5f,0x82,0xa8,0x9a,0x8f,0x23,0x9c,0x31,0x10,0xb3,0xd7,0x88,0x50,0x00, +0x80,0x96,0x9e,0xdc,0x8d,0x21,0x49,0x1b,0x4b,0xa1,0x9e,0xcc,0x9a,0xa3,0x7f,0x21, +0x95,0x13,0x9b,0x1c,0x5f,0x5c,0x3a,0x1d,0x83,0x61,0xa8,0x0b,0x85,0xa3,0x88,0x9a, +0x9c,0x31,0x10,0x6f,0xd8,0x88,0x40,0x00,0x9e,0xda,0x78,0xdb,0x3c,0x5b,0x5f,0x45, +0xa6,0xb2,0x95,0x13,0x82,0x9c,0x99,0x21,0x92,0xd3,0x53,0x1b,0x40,0xf3,0x8e,0xcc, +0xa4,0x9b,0x87,0x22,0x8a,0xd4,0x9c,0xda,0x9c,0x31,0x10,0x44,0xd8,0x88,0x30,0x00, +0x74,0xdc,0x3a,0x4a,0x63,0x65,0xa6,0xa1,0x99,0x0a,0x80,0xad,0x94,0xc1,0x92,0xe3, +0x57,0x1b,0x3d,0x23,0x86,0xd5,0xaa,0x99,0x8d,0x23,0x82,0xd3,0x9a,0xec,0x80,0xd5, +0x9c,0x31,0x10,0x44,0xd8,0x88,0x30,0x00,0x40,0x51,0x51,0x1b,0x9e,0xe3,0xa4,0xd4, +0x84,0xda,0x88,0xe3,0x98,0xcd,0x6b,0x22,0x38,0x5c,0x68,0xe2,0xa8,0x93,0x9d,0x21, +0x80,0xdc,0x8e,0xcc,0x92,0xeb,0x5b,0x14,0x9c,0x31,0x10,0x8f,0xd7,0x78,0x40,0x00, +0x39,0x32,0x7a,0xc4,0xae,0xa3,0x97,0x1c,0x7e,0x91,0x93,0x1b,0x8e,0xa2,0x50,0xe5, +0x3f,0x42,0x84,0xe4,0xae,0xda,0x94,0xdc,0x7e,0x93,0x93,0x22,0x88,0xa1,0x4e,0x9c, +0x9c,0x31,0x10,0x81,0xd7,0x87,0x40,0x00,0x41,0x55,0x84,0xe2,0xae,0xd9,0x96,0xe2, +0x7e,0x94,0x90,0xe4,0x88,0x95,0x52,0xaa,0x3f,0x48,0x7e,0xed,0xb0,0xd1,0x9e,0xe6, +0x7e,0x94,0x8b,0x1c,0x8c,0x99,0x5d,0x22,0x9c,0x31,0x10,0x2c,0xd7,0x88,0x30,0x00, +0x3b,0x1a,0x70,0xd4,0xac,0xe2,0xa6,0xd3,0x82,0xe2,0x85,0x15,0x90,0xa3,0x6b,0x51, +0x3e,0xad,0x5c,0xd3,0x9e,0xa3,0xae,0xdb,0x8e,0xdc,0x7e,0xe1,0x8c,0xd4,0x7c,0xe4, +0x9c,0x31,0x10,0x81,0xc7,0x78,0x30,0x00,0x1c,0x4a,0x11,0x23,0x88,0xdb,0xe2,0xdc, +0xc6,0xdb,0x82,0x93,0x86,0xd9,0x96,0xe3,0x53,0x13,0x04,0xf4,0x3c,0xc4,0xbe,0xe9, +0xe4,0xd3,0xa2,0xdb,0x7a,0xe4,0x94,0xd3,0x9c,0x31,0x10,0x9a,0xc6,0x77,0x30,0x00, +0x86,0xe1,0x30,0xdc,0x0b,0x4b,0x68,0xe1,0xd2,0xdd,0xd2,0xdb,0x94,0xe5,0x81,0x1a, +0x96,0xd4,0x78,0xe2,0x24,0x14,0x13,0x5c,0x78,0xd9,0xd6,0xdb,0xce,0xd3,0x8e,0xa4, +0x9c,0x31,0x10,0x2e,0xc6,0x77,0x20,0x00,0x81,0x13,0x96,0xda,0x77,0x1d,0x24,0x52, +0x15,0x5c,0x76,0xd9,0xd3,0x1c,0xce,0xd2,0x92,0xe5,0x7f,0x11,0x94,0xe5,0x7e,0xdb, +0x32,0x9a,0x11,0x4a,0x60,0xeb,0xc7,0x0e,0x9c,0x31,0x10,0x36,0xc6,0x67,0x20,0x00, +0xd6,0xf2,0x9e,0xc1,0x7f,0x2c,0x8e,0xd5,0x8a,0xe0,0x4b,0x64,0x10,0xed,0x3c,0xc2, +0xa8,0xe9,0xdc,0x8d,0xb7,0x2b,0x82,0xd0,0x86,0xde,0x92,0x9c,0x6d,0x12,0x24,0x0b, +0x9c,0x31,0x10,0xb0,0xc6,0x68,0x20,0x00,0x1d,0x6c,0x74,0x8a,0xcd,0x23,0xd0,0xdb, +0x9a,0x92,0x7f,0x2b,0x90,0xcd,0x88,0xe2,0x4d,0x5b,0x14,0xb5,0x38,0xc2,0x9c,0xaa, +0xd8,0xd4,0xbf,0x1a,0x8a,0xac,0x82,0xcb,0x9c,0x31,0x10,0xb0,0xc6,0x68,0x20,0x00, +0x92,0xdb,0x7c,0xdb,0x3c,0xdb,0x15,0x52,0x4c,0xdd,0xac,0xe2,0xd8,0x9b,0xb4,0xd3, +0x86,0xeb,0x86,0xc3,0x92,0xea,0x76,0xcc,0x38,0xeb,0x1b,0x41,0x52,0xe5,0xac,0xd3, +0x9c,0x31,0x10,0x8c,0xc5,0x67,0x20,0x00,0xd4,0x62,0xb3,0x53,0x88,0x6d,0x86,0x92, +0x93,0x5c,0x7c,0x61,0x43,0x9b,0x1e,0xa4,0x48,0x4e,0x9e,0x68,0xd1,0x54,0xbb,0x63, +0x8e,0x52,0x82,0x6e,0x91,0x41,0x87,0x6a,0x9c,0x31,0x10,0xa8,0xc6,0x78,0x20,0x00, +0x57,0x14,0x24,0xa3,0x34,0xe2,0x82,0x95,0xc4,0xda,0xc4,0xdb,0x9b,0x1b,0x82,0x9b, +0x8a,0xdb,0x8e,0xe2,0x6e,0xd4,0x3c,0xa3,0x29,0x49,0x5a,0xec,0xa6,0xd4,0xc8,0xe3, +0x9c,0x31,0x10,0x38,0xc5,0x67,0x30,0x00,0xb1,0x55,0x8a,0x62,0x81,0x63,0x8e,0x50, +0x88,0x5d,0x60,0x5c,0x33,0x08,0x38,0x76,0x74,0x4b,0xb3,0x61,0xc1,0x54,0xa4,0x62, +0x88,0x5b,0x86,0x9d,0x8e,0x55,0x81,0x60,0x9c,0x31,0x10,0x10,0xc5,0x57,0x30,0x00, +0x59,0x84,0x32,0x33,0x3e,0x68,0x7c,0x6e,0xb7,0x6b,0xc0,0x73,0x9f,0x63,0x84,0x52, +0x85,0x83,0x8f,0x75,0x81,0x6a,0x58,0x8b,0x34,0x4b,0x42,0x70,0x7d,0x4e,0xb4,0x6a, +0x9c,0x31,0x10,0x8c,0xc5,0x67,0x20,0x00,0xbc,0x5c,0x9e,0x5b,0x84,0x5a,0x84,0x9c, +0x8f,0x53,0x85,0x5a,0x60,0x5c,0x39,0x11,0x3e,0x6b,0x73,0x4d,0xac,0x69,0xbd,0x54, +0xa4,0x5a,0x87,0x5c,0x82,0x9b,0x8d,0x53,0x9c,0x31,0x10,0xa4,0xc5,0x57,0x20,0x00, +0x89,0x69,0x69,0x6c,0x40,0x23,0x3b,0xb4,0x68,0x49,0xa3,0x8b,0xbc,0x6a,0xa7,0x6b, +0x89,0x6c,0x7f,0x4b,0x8b,0x73,0x90,0x6b,0x79,0x6b,0x50,0x73,0x3a,0xaa,0x54,0x45, +0x9c,0x31,0x10,0x8c,0xc5,0x67,0x20,0x00,0x8b,0x5a,0xb3,0x5b,0xb0,0x5a,0x94,0x5b, +0x82,0x1b,0x87,0x49,0x92,0x6d,0x86,0x4c,0x62,0x62,0x3f,0x0b,0x45,0x71,0x73,0x4e, +0xa6,0x62,0xb5,0x54,0xa0,0x62,0x85,0x5c,0x9c,0x31,0x10,0x9e,0xb5,0x57,0x10,0x00, +0x7e,0xa3,0x98,0x9c,0x9e,0x9a,0x6e,0xdb,0x24,0xe3,0x05,0x52,0x36,0xd5,0x91,0x32, +0xce,0xcb,0xcc,0xeb,0xa4,0xcb,0x8a,0xea,0x8b,0x0b,0x91,0x14,0x7a,0xf2,0x52,0xcb, +0x9c,0x31,0x10,0xb4,0xb4,0x55,0x00,0x00,0x3e,0x65,0x4b,0x09,0x66,0xa4,0x83,0x24, +0x94,0x92,0xa0,0xdb,0xa6,0xdb,0xa4,0xdb,0x96,0xdb,0x88,0xdb,0x82,0xdb,0x7c,0xdb, +0x74,0xdb,0x6c,0xdb,0x66,0xdb,0x66,0xdb,0x9c,0x31,0x10,0x55,0x92,0x22,0x00,0x00, +0x41,0x10,0x7a,0x2e,0xae,0x9a,0xcb,0x1a,0xcf,0x62,0xb8,0xdc,0x92,0xab,0x62,0x49, +0x3c,0xe6,0x29,0x1a,0x34,0xe3,0x5a,0xdc,0x86,0xd3,0xa9,0x5a,0xb5,0x65,0xaf,0x12, +0x9c,0x31,0x10,0x23,0x73,0x22,0x00,0x00,0xee,0x9a,0x8b,0x1d,0x3c,0xd9,0x0f,0x2b, +0x04,0xda,0x11,0x1b,0x3e,0x94,0x7e,0xdb,0x9e,0xdb,0x99,0x53,0x80,0xd3,0x7a,0xdc, +0x8a,0xdb,0x98,0xe4,0x91,0x1b,0x74,0xe2,0x9c,0x31,0x10,0xdc,0x52,0x12,0x00,0x00, +0x02,0x5b,0x35,0x5b,0x9d,0x92,0xcf,0x53,0x76,0x1c,0x1e,0x0b,0x09,0x4b,0x50,0xd3, +0xae,0x9a,0xc2,0x93,0x92,0x9d,0x58,0x8a,0x4d,0x4b,0x8e,0x03,0xd2,0x1a,0xda,0x24, +0x9c,0x31,0x10,0x3f,0x62,0x11,0x00,0x00,0x7a,0xc9,0x37,0x51,0x29,0x2e,0x5a,0x89, +0x93,0x2a,0x93,0x19,0x5e,0x89,0x54,0x85,0x76,0xcc,0xaf,0x3a,0xc9,0x08,0xac,0xee, +0x6c,0x2d,0x41,0x04,0x47,0x95,0x67,0x4a,0x9c,0x31,0x10,0xdc,0x52,0x12,0x00,0x00, +0x75,0x53,0x7d,0x9b,0x51,0x64,0x56,0x91,0x96,0x0d,0xf1,0x94,0xf5,0x2b,0xa9,0x8b, +0x4e,0xe2,0x1a,0x65,0x0e,0xa9,0x45,0x1b,0x89,0xdb,0x92,0x63,0x73,0x2d,0x6e,0x23, +0x9c,0x31,0x10,0x41,0x53,0x12,0x00,0x00,0x99,0x52,0xe1,0x8a,0xe6,0x22,0x8e,0x53, +0x51,0x74,0x51,0xd3,0x69,0xe4,0x71,0x5b,0x66,0x9b,0x52,0x6c,0x6d,0x61,0x99,0x5b, +0x99,0x62,0xa6,0xd2,0x99,0xcd,0x9d,0x8c,0x9c,0x31,0x10,0xb6,0x53,0x43,0x00,0x00, +0x8d,0x3a,0x95,0x44,0x9e,0x3b,0x9d,0xbc,0x9d,0x3b,0x9d,0xbb,0xa9,0xb2,0xba,0xb4, +0xbd,0x3c,0xae,0x3a,0x8c,0x44,0x65,0xa1,0x7c,0xc5,0x71,0x9c,0x85,0x2c,0x79,0xc1, +0x9c,0x31,0x10,0x64,0x98,0x88,0x20,0x00,0x7b,0xbb,0x7b,0xbb,0x83,0xbb,0x7b,0xbb, +0x8c,0x43,0x83,0xbb,0xcf,0x6d,0x93,0x42,0x7a,0xa3,0x63,0xbb,0x73,0x3b,0x83,0xc3, +0x92,0xcc,0xbc,0x22,0x45,0xab,0x4a,0xdb,0x9c,0x31,0x10,0xe6,0x87,0x77,0x10,0x00, +0x36,0x25,0x55,0xda,0x52,0x53,0x52,0x13,0x51,0xd3,0x75,0x9a,0x6d,0xdb,0x6d,0x94, +0x81,0xda,0x95,0xda,0x95,0x9c,0xa6,0x22,0x8e,0x1b,0xab,0x65,0x74,0xe9,0x45,0xca, +0x9c,0x31,0x10,0xde,0x98,0x77,0x30,0x00,0x85,0xcd,0x99,0xdb,0x91,0xd2,0x85,0x9b, +0x79,0xe3,0x79,0xa2,0xcf,0x21,0x79,0x0d,0x02,0x1c,0x39,0x8a,0x71,0xd2,0x5d,0x9c, +0x3d,0xeb,0x45,0xaa,0x5d,0xd4,0x69,0xd4,0x9c,0x31,0x10,0xf5,0x75,0x76,0x30,0x00, +0x1a,0x51,0x51,0x85,0x72,0x7b,0xaa,0x68,0xc3,0xb3,0xb4,0x92,0xa3,0x6c,0xc2,0x4a, +0xba,0x68,0xbb,0xb9,0xaa,0xb5,0xc3,0x86,0xbd,0x65,0xf4,0x63,0xec,0x5a,0xec,0x3a, +0x9c,0x31,0x10,0x8f,0x85,0x76,0x20,0x00,0xb2,0x32,0xba,0xe1,0xc9,0x65,0xb1,0xac, +0x95,0x9a,0x9e,0x2b,0xb4,0xbb,0xb1,0xbc,0xaa,0x4b,0x9e,0x4b,0xa9,0x32,0xa8,0x9d, +0xa1,0x92,0x9c,0x40,0xad,0x4b,0xc0,0xdd,0x9c,0x31,0x10,0x4e,0x85,0x76,0x10,0x00, +0xa6,0xdb,0xad,0x41,0xa6,0x2d,0x9d,0x2b,0x8d,0xa2,0x95,0x3c,0x8d,0xc2,0x75,0x43, +0x69,0xda,0x6a,0xc5,0x59,0xbc,0x5a,0xb1,0x4d,0xb2,0x61,0x2c,0x49,0x04,0x38,0x13, +0x9c,0x31,0x10,0x78,0x86,0x75,0x10,0x00,0x39,0xe5,0x48,0xed,0x3e,0x24,0x45,0xaa, +0x4e,0x25,0x52,0x11,0x56,0x8c,0x69,0x51,0x6a,0x52,0x75,0x55,0x7d,0x20,0x75,0xac, +0x7d,0xe9,0x81,0xde,0x7e,0x1d,0x79,0x9d,0x9c,0x31,0x10,0x22,0x65,0x54,0x00,0x00, +0x76,0x4b,0x91,0x49,0x7a,0x9b,0x5d,0x25,0x65,0xeb,0x99,0xaa,0x76,0xa3,0x94,0xd2, +0x49,0xd4,0x55,0xdc,0x71,0x1a,0x35,0x9b,0x75,0xe4,0x61,0x63,0x6a,0x19,0xb5,0x4c, +0x9c,0x31,0x10,0x4b,0x63,0x54,0x00,0x00,0xca,0x34,0x82,0xb3,0xa8,0xcb,0xb8,0xc8, +0x8d,0xc4,0x95,0x3c,0x79,0xd3,0x5e,0x5c,0x45,0xc4,0x86,0x32,0x80,0xa9,0x4e,0xad, +0x41,0xa3,0x72,0x3a,0x86,0x4b,0x49,0xcb,0x9c,0x31,0x10,0xc1,0x63,0x53,0x00,0x00, +0x3f,0x44,0x96,0x34,0x9a,0xb3,0x3d,0x44,0x5a,0x3b,0xa9,0x9b,0x86,0x21,0x69,0xbc, +0x8d,0xcb,0x95,0xbc,0x76,0xb4,0x69,0xb4,0x92,0xcb,0x9c,0xb8,0x67,0x32,0x6d,0xae, +0x9c,0x31,0x10,0x4b,0x63,0x54,0x00,0x00,0x92,0x2c,0x70,0x3a,0x6a,0x42,0x65,0x43, +0x70,0xc5,0x75,0x13,0x52,0x2b,0x5a,0x3b,0x79,0xc2,0x88,0xaa,0x89,0x23,0xa1,0x34, +0x7c,0xc3,0x5c,0xc3,0x31,0x43,0x41,0x43,0x9c,0x31,0x10,0xc8,0x54,0x44,0x00,0x00, +0x3b,0xcb,0x5b,0xa3,0x59,0x9b,0x63,0xc3,0x3a,0x4b,0x81,0x9e,0x78,0xba,0x39,0xab, +0x6a,0x42,0x71,0x52,0x92,0xd3,0x89,0xd4,0x74,0x73,0x62,0x5a,0x6d,0xda,0x7c,0x5b, +0x9c,0x31,0x10,0x0a,0x54,0x33,0x00,0x00,0x5a,0xed,0x7a,0x2d,0x8e,0x99,0x91,0xd1, +0x6e,0x8c,0x8a,0x15,0x32,0xa2,0x72,0x1a,0x82,0x8a,0x91,0xe4,0x91,0xd6,0x85,0x8c, +0x65,0xc9,0x82,0x11,0x89,0xd4,0x79,0xa4,0x9c,0x31,0x10,0xc9,0x42,0x32,0x00,0x00, +0x89,0x75,0xb7,0x2a,0xba,0xe0,0xc1,0xe2,0xc6,0xe2,0xc2,0x16,0xe1,0xc4,0xae,0x89, +0xa6,0x62,0xa9,0xdc,0x8c,0xca,0x81,0x83,0x59,0x0c,0xd9,0x5a,0xa1,0x24,0xd1,0x91, +0x9c,0x31,0x10,0x74,0x53,0x34,0x00,0x00,0xa1,0x37,0x8d,0xb8,0x91,0xc8,0x75,0xc6, +0x91,0xb6,0x9d,0xb9,0x8a,0x6b,0x68,0xd3,0x4d,0xd8,0x86,0x58,0xa9,0xe6,0xb2,0x64, +0xd2,0x58,0xce,0x49,0x7e,0xb9,0x86,0x16,0x9c,0x31,0x10,0x51,0x43,0x34,0x00,0x00, +0x4a,0x15,0xaa,0x96,0xc2,0x28,0xb2,0xa9,0xc9,0xa9,0x9e,0x35,0x39,0x34,0x2e,0x36, +0x48,0xbb,0x65,0xb8,0xa4,0x47,0xca,0x35,0xc1,0xa6,0x61,0xa9,0x4d,0x98,0x59,0xb7, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_FINDME.txt b/config/_default_cfg_src_/res/en/SOUND_FINDME.txt new file mode 100644 index 0000000..ce3fa72 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_FINDME.txt @@ -0,0 +1,645 @@ +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0xa3,0xbd,0xdd,0x99,0x78,0x77,0x77,0x77,0x77,0x87,0x77,0x87,0x87, +0xe8,0x87,0x4c,0x69,0x8a,0x14,0x79,0x6c,0x77,0x81,0x77,0x4c,0x77,0xa2,0x77,0x3c, +0x77,0xb3,0x77,0x2b,0x77,0xc4,0x77,0x1a,0x9c,0x31,0x10,0x29,0x43,0xdd,0x46,0x43, +0x7c,0xa8,0x02,0x4d,0x7d,0x36,0x21,0xc1,0x5d,0x3c,0x42,0x3a,0x3c,0xc5,0x63,0x30, +0x1b,0xd1,0x84,0xaa,0x39,0xd5,0x46,0xa1,0x77,0xde,0x29,0x1d,0x75,0x60,0x0b,0x99, +0x9c,0x31,0x10,0xe0,0x43,0xdd,0x45,0x42,0x89,0x32,0x47,0x4c,0x47,0xf2,0x78,0x8c, +0x26,0x72,0x89,0xcd,0x35,0x70,0x7b,0x0f,0x54,0x2d,0x2b,0xd2,0x73,0x6a,0x2c,0x95, +0x82,0xe7,0x3d,0x19,0x52,0xa3,0x5d,0x1d,0x9c,0x31,0x10,0x6f,0x43,0xdc,0x45,0x42, +0x32,0x9f,0x8d,0x23,0x22,0xd8,0x8c,0xaa,0x43,0x51,0x5c,0x30,0x54,0x0b,0x3b,0x76, +0x74,0xc6,0x2a,0x79,0x75,0xc3,0x49,0x7c,0x46,0xc1,0x68,0x7d,0x37,0xc1,0x87,0x7c, +0x9c,0x31,0x10,0x59,0x43,0xdc,0x35,0x43,0x28,0xc2,0x66,0x7a,0x59,0xc5,0x35,0x77, +0x7a,0x89,0x24,0xb3,0x7b,0x4e,0x34,0x2d,0x6b,0x93,0x53,0xe8,0x4b,0xd9,0x73,0xe2, +0x3b,0xdf,0x63,0xdc,0x4b,0xe5,0x44,0x16,0x9c,0x31,0x10,0x5c,0x43,0xcc,0x35,0x42, +0x6e,0xea,0x21,0x51,0x7d,0xef,0x32,0x8d,0x6c,0x72,0x44,0x0a,0x4a,0xf5,0x75,0x89, +0x29,0x76,0x67,0x08,0x37,0xb6,0x58,0xc8,0x56,0x36,0x4a,0x49,0x74,0xb4,0x3b,0xcc, +0x9c,0x31,0x10,0xb1,0x43,0xcc,0x25,0x32,0x73,0x71,0x5c,0xcf,0x42,0x6d,0x6d,0xd3, +0x31,0xa9,0x6e,0x98,0x31,0x24,0x5e,0xdd,0x50,0xdf,0x3e,0xa2,0x71,0x1a,0x3e,0x66, +0x61,0x95,0x5d,0xab,0x52,0x91,0x6c,0xaf,0x9c,0x31,0x10,0x98,0x42,0xcc,0x35,0x32, +0x33,0x8e,0x7b,0x72,0x34,0xcb,0x6a,0x33,0x56,0x4a,0x48,0xb5,0x77,0xc9,0x47,0x34, +0x79,0x4a,0x45,0xb3,0x5a,0xcc,0x64,0x71,0x3b,0xce,0x63,0x2e,0x4d,0x12,0x62,0x6a, +0x9c,0x31,0x10,0x2c,0x42,0xcc,0x25,0x32,0x4d,0x96,0x51,0xe6,0x7e,0x1a,0x41,0x61, +0x7e,0x5f,0x31,0x9d,0x6e,0x23,0x51,0xd8,0x4d,0xa8,0x62,0x94,0x3c,0xac,0x63,0x91, +0x4b,0xaf,0x54,0x8e,0x5a,0xb1,0x45,0xcc,0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32, +0x79,0x32,0x37,0x0b,0x67,0xf3,0x38,0x8b,0x66,0x72,0x59,0xcd,0x55,0x31,0x5b,0x0f, +0x44,0x2e,0x6c,0x11,0x33,0x2b,0x6d,0x15,0x32,0x67,0x6d,0x99,0x42,0x23,0x3d,0x9d, +0x9c,0x31,0x10,0x49,0x43,0xcc,0x34,0x32,0x61,0xdf,0x3d,0xa1,0x62,0x1b,0x3d,0x65, +0x62,0x97,0x4c,0xa9,0x53,0x53,0x5b,0xec,0x54,0x50,0x5a,0xef,0x45,0x8e,0x69,0xb0, +0x36,0xcd,0x68,0x71,0x38,0x0d,0x77,0x31,0x9c,0x31,0x10,0x49,0x43,0xcc,0x34,0x32, +0x39,0x4e,0x65,0xf0,0x4a,0x4f,0x54,0xae,0x4b,0x92,0x53,0xeb,0x5c,0x55,0x43,0x28, +0x5c,0xd8,0x32,0xa4,0x5d,0x1c,0x32,0x60,0x6d,0x60,0x32,0x9c,0x6d,0x24,0x32,0xd8, +0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32,0x6c,0xa7,0x33,0x95,0x6b,0xea,0x44,0x52, +0x5a,0xed,0x55,0x50,0x49,0xef,0x56,0x8f,0x38,0xb0,0x67,0x8e,0x37,0x70,0x68,0xce, +0x46,0x6f,0x5a,0x0f,0x45,0x2e,0x5b,0x11,0x9c,0x31,0x10,0xa5,0x32,0xcb,0x34,0x32, +0x48,0x6c,0x18,0x11,0x46,0x65,0x19,0x9d,0x45,0x54,0x3a,0xad,0x04,0x45,0x5b,0x3c, +0x04,0x34,0x3b,0x4d,0x04,0x25,0x3a,0xdc,0x45,0x95,0x19,0x6e,0x47,0x04,0x17,0x79, +0x9c,0x31,0x10,0x05,0x43,0xcc,0x35,0x32,0x54,0x8e,0x4a,0x71,0x45,0xcd,0x69,0x32, +0x47,0x0c,0x67,0xf3,0x38,0x8c,0x66,0x72,0x39,0xcd,0x55,0x30,0x5b,0x0f,0x44,0x2e, +0x6c,0x12,0x23,0x2b,0x6c,0xd5,0x32,0xa7,0x9c,0x31,0x10,0x49,0x43,0xcc,0x34,0x32, +0x6d,0x59,0x42,0x23,0x5d,0x9d,0x42,0x1f,0x4d,0xa1,0x62,0x5b,0x4d,0x65,0x62,0xd7, +0x4c,0xa9,0x63,0x93,0x3b,0xec,0x64,0x51,0x4a,0xae,0x65,0x8f,0x49,0xb0,0x56,0xcd, +0x9c,0x31,0x10,0x49,0x43,0xcc,0x34,0x32,0x58,0x71,0x48,0x0d,0x57,0x31,0x49,0x4e, +0x65,0xef,0x3a,0x4f,0x64,0xee,0x3b,0x92,0x63,0xeb,0x3c,0x55,0x63,0x28,0x3c,0xd8, +0x52,0xa4,0x4d,0x1c,0x52,0xa0,0x4d,0x20,0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32, +0x42,0x9c,0x5c,0xe4,0x33,0x19,0x6c,0x67,0x33,0x95,0x6b,0xaa,0x24,0x52,0x6a,0xed, +0x35,0x50,0x59,0xee,0x46,0x8f,0x58,0xaf,0x57,0x8f,0x47,0x6f,0x68,0xcf,0x36,0x6e, +0x9c,0x31,0x10,0x5e,0x42,0xcb,0x34,0x32,0x73,0x82,0x2a,0xf5,0x55,0x88,0x48,0xed, +0x57,0x15,0x47,0x60,0x38,0xa1,0x46,0xd6,0x39,0x2c,0x66,0x45,0x39,0xba,0x45,0xb9, +0x59,0x48,0x26,0x2e,0x58,0xd6,0x27,0x1c,0x9c,0x31,0x10,0xa2,0x42,0xbb,0x24,0x32, +0x6f,0x61,0x30,0x96,0x5d,0xe8,0x42,0x0c,0x4c,0x71,0x54,0x05,0x3a,0x74,0x46,0x01, +0x48,0x7a,0x48,0x01,0x56,0x78,0x3a,0x06,0x74,0x75,0x3c,0x08,0x52,0xed,0x5d,0x92, +0x9c,0x31,0x10,0xdc,0x32,0xcb,0x24,0x22,0x08,0xe5,0x57,0x18,0x07,0xda,0x38,0x26, +0x27,0x4c,0x18,0xb0,0x46,0xc2,0x38,0xbd,0x26,0xb4,0x58,0x49,0x07,0x2a,0x57,0xd5, +0x28,0x1c,0x16,0xe1,0x29,0x96,0x15,0x69,0x9c,0x31,0x10,0xed,0x32,0xbb,0x34,0x32, +0x26,0x0c,0x37,0x6d,0x09,0x8a,0x53,0xf0,0x2d,0x08,0x10,0x76,0x50,0x86,0x0c,0xf1, +0x14,0x89,0x49,0x6e,0x17,0x8e,0x26,0x69,0x3a,0x95,0x23,0xe1,0x3c,0x9e,0x41,0xd9, +0x9c,0x31,0x10,0x11,0x32,0xcb,0x24,0x32,0x17,0x24,0x47,0xcd,0x17,0xb2,0x07,0xc4, +0x57,0xbc,0x07,0xb9,0x37,0xc9,0x28,0x2c,0x17,0x50,0x28,0xa1,0x36,0x5d,0x09,0x98, +0x54,0xe5,0x0b,0x16,0x33,0x69,0x2c,0x8d,0x9c,0x31,0x10,0xb3,0x32,0xbb,0x24,0x21, +0x13,0xed,0x4d,0x0e,0x30,0xed,0x10,0x8d,0x4d,0x6e,0x13,0x8e,0x4a,0x68,0x16,0x91, +0x07,0x66,0x59,0x99,0x04,0xdc,0x5b,0xa1,0x02,0xd5,0x3d,0x28,0x41,0x4d,0x1e,0x36, +0x9c,0x31,0x10,0x48,0x42,0xbb,0x24,0x21,0x50,0x41,0x4f,0x3c,0x50,0xba,0x5e,0xc9, +0x40,0xac,0x6e,0x51,0x31,0xa6,0x5d,0x59,0x42,0x9d,0x5c,0x62,0x53,0x95,0x4a,0xe9, +0x65,0x12,0x49,0x69,0x57,0x0c,0x57,0xed,0x9c,0x31,0x10,0xfb,0x32,0xcb,0x24,0x21, +0x30,0x8e,0x0d,0xe9,0x32,0x11,0x0c,0x69,0x34,0x15,0x4a,0xe1,0x15,0x1d,0x49,0x59, +0x16,0x25,0x08,0xd1,0x57,0x2c,0x08,0x45,0x37,0xba,0x27,0xbd,0x17,0xc4,0x28,0x31, +0x9c,0x31,0x10,0xc4,0x31,0xbb,0x24,0x31,0x3e,0xce,0x01,0x25,0x3d,0x58,0x03,0x1e, +0x3a,0xe1,0x25,0x95,0x18,0x65,0x48,0x92,0x35,0x6d,0x2c,0x0c,0x51,0xed,0x0f,0x0e, +0x4e,0x6d,0x12,0x8c,0x0b,0x6d,0x55,0x91,0x9c,0x31,0x10,0x48,0x42,0xbb,0x24,0x21, +0x44,0x64,0x6c,0x15,0x42,0xe2,0x5d,0x1d,0x61,0xd8,0x4e,0x25,0x50,0xd1,0x4e,0xb0, +0x50,0xc5,0x5f,0x3a,0x40,0x39,0x6e,0xc5,0x30,0xb2,0x5e,0x4d,0x41,0x29,0x5d,0xd9, +0x9c,0x31,0x10,0x6d,0x32,0xbb,0x23,0x22,0x29,0x27,0x36,0x77,0x49,0xc6,0x0d,0xb9, +0x4a,0x85,0x0c,0xfa,0x4b,0x44,0x0c,0x3a,0x2c,0x04,0x0b,0x7a,0x34,0xe4,0x2a,0x99, +0x35,0x85,0x21,0xf8,0x2e,0x27,0x21,0x76,0x9c,0x31,0x10,0xbd,0x33,0xbb,0x34,0x22, +0x3a,0xa5,0x43,0xd0,0x3c,0x2e,0x42,0xc9,0x1d,0x34,0x22,0x41,0x1d,0x41,0x42,0x34, +0x1c,0xc9,0x43,0x2d,0x1b,0x51,0x24,0xa6,0x39,0xd9,0x27,0x1d,0x17,0x62,0x29,0x98, +0x9c,0x31,0x10,0x79,0x7a,0xed,0xaa,0x98,0x5b,0xc5,0x5b,0xa5,0x5b,0xc5,0x5b,0xa5, +0x5b,0xc5,0x5b,0xa5,0x5b,0xba,0x13,0xb0,0xaa,0x51,0x25,0x95,0x59,0xd5,0x5d,0xa5, +0x59,0xc5,0x5d,0xb5,0x59,0xb5,0x5d,0xb5,0x9c,0x31,0x10,0x9f,0x43,0xed,0x46,0x54, +0x26,0xae,0xb8,0x50,0x07,0xa1,0x97,0x5e,0x29,0x19,0x75,0xe4,0x4a,0x92,0x33,0xed, +0x6c,0x8c,0x11,0xf1,0x4e,0x8a,0x30,0x70,0x30,0x08,0x6e,0x72,0x12,0x0d,0x8c,0x6c, +0x9c,0x31,0x10,0x30,0x43,0xdd,0x45,0x53,0x0c,0x09,0x83,0x33,0x4d,0x4d,0x41,0xef, +0x6e,0x52,0x20,0xea,0x7e,0xd7,0x30,0xa4,0x6f,0x5c,0x60,0x9f,0x2f,0x22,0x70,0xda, +0x2e,0xa7,0x71,0x95,0x3d,0xab,0x52,0x91,0x9c,0x31,0x10,0x29,0x43,0xdd,0x46,0x43, +0x79,0x5c,0x07,0x99,0x76,0xe1,0x0a,0x14,0x73,0xe4,0x2d,0x16,0x50,0xe5,0x70,0x14, +0x2d,0xe5,0x93,0x16,0x0a,0xe1,0x75,0x99,0x28,0x5e,0x38,0x21,0x66,0xd9,0x19,0xa5, +0x9c,0x31,0x10,0xd6,0x43,0xdd,0x35,0x43,0x82,0xa8,0x3d,0x58,0x62,0x24,0x5d,0x9c, +0x32,0x20,0x7d,0xa0,0x12,0x5c,0x7d,0x64,0x32,0x98,0x5c,0xa8,0x53,0x55,0x4b,0xeb, +0x64,0x52,0x3a,0xed,0x75,0x50,0x39,0xef,0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43, +0x56,0x8f,0x68,0xb0,0x27,0xce,0x87,0x6f,0x38,0xcf,0x66,0x6e,0x59,0xd0,0x45,0x6d, +0x6a,0xd2,0x44,0xaa,0x7b,0x95,0x33,0xe8,0x6c,0x18,0x53,0xa4,0x3c,0x5b,0x63,0x61, +0x9c,0x31,0x10,0x44,0x43,0xdc,0x35,0x42,0x3c,0x5e,0x63,0x5d,0x4c,0x64,0x53,0x96, +0x6b,0xeb,0x34,0x11,0x7b,0x70,0x34,0x8b,0x6a,0xf5,0x45,0x47,0x5a,0x39,0x56,0x04, +0x39,0x3c,0x66,0xc1,0x38,0x7e,0x57,0xc0,0x9c,0x31,0x10,0x6f,0x43,0xdc,0x45,0x42, +0x47,0x7e,0x58,0xc0,0x56,0x7e,0x4a,0x01,0x65,0x3b,0x2b,0x04,0x74,0x38,0x3b,0xc9, +0x53,0x73,0x5c,0x8f,0x32,0xac,0x8d,0x55,0x22,0x65,0x7d,0x9d,0x32,0x1d,0x5d,0xa5, +0x9c,0x31,0x10,0xd6,0x43,0xdd,0x35,0x43,0x52,0x5a,0x3d,0x26,0x72,0xd6,0x3c,0x69, +0x63,0xd3,0x4b,0xac,0x54,0x91,0x5a,0x6e,0x45,0xcf,0x79,0x6f,0x27,0x0e,0x68,0x30, +0x48,0x0e,0x46,0xef,0x79,0x4f,0x25,0xee,0x9c,0x31,0x10,0x44,0x43,0xdc,0x35,0x42, +0x7a,0x43,0x34,0xf9,0x6b,0x07,0x54,0x34,0x5b,0xcd,0x63,0xae,0x3c,0x13,0x73,0x67, +0x3c,0x5a,0x43,0x61,0x6c,0x61,0x33,0x5a,0x7c,0x27,0x33,0xd4,0x7b,0xad,0x54,0x4e, +0x9c,0x31,0x10,0xdc,0x42,0xcc,0x35,0x43,0x5e,0x72,0x62,0x0a,0x3c,0xf6,0x63,0xc7, +0x3a,0xf9,0x55,0x85,0x59,0x3a,0x47,0x84,0x77,0x3a,0x29,0x45,0x75,0x78,0x4b,0x07, +0x53,0xb6,0x5c,0xca,0x42,0x72,0x6e,0x0e,0x9c,0x31,0x10,0xc1,0x42,0xcc,0x35,0x42, +0x31,0x2d,0x6e,0xd3,0x40,0x68,0x4f,0x99,0x70,0x23,0x2f,0x9e,0x70,0x1d,0x4f,0x64, +0x50,0x97,0x6e,0xa9,0x31,0x52,0x7d,0xee,0x32,0x8e,0x5c,0xb2,0x53,0xcb,0x4b,0x34, +0x9c,0x31,0x10,0x8d,0x42,0xcc,0x34,0x42,0x65,0x49,0x39,0x76,0x67,0x08,0x47,0xf6, +0x58,0xc8,0x56,0x35,0x4a,0x4a,0x64,0xb3,0x4b,0xcc,0x63,0x30,0x4d,0x10,0x52,0x2c, +0x6d,0xd4,0x31,0x68,0x7e,0x99,0x31,0x23,0x9c,0x31,0x10,0x77,0x43,0xcc,0x45,0x42, +0x7e,0xde,0x31,0x1e,0x7e,0xa3,0x41,0x59,0x5e,0x28,0x52,0x14,0x4d,0x2c,0x63,0x10, +0x4c,0x2f,0x64,0x4d,0x4a,0xf2,0x55,0x8b,0x59,0x73,0x47,0x0a,0x67,0xf4,0x28,0x8b, +0x9c,0x31,0x10,0x3f,0x44,0xcc,0x54,0x33,0x6b,0x39,0x2d,0x06,0x6a,0x78,0x2d,0xa7, +0x49,0xd7,0x4e,0x28,0x41,0x75,0x4e,0xaa,0x29,0x13,0x6e,0xec,0x28,0xf1,0x6f,0x0f, +0x28,0xce,0x6e,0xf1,0x21,0x0c,0x46,0xd3,0x9c,0x31,0x10,0x41,0x7a,0xee,0xba,0x98, +0x56,0x65,0x58,0x85,0x55,0x55,0x1b,0xb2,0x84,0x45,0x1a,0xb5,0x55,0x35,0x58,0xb5, +0x56,0x35,0x57,0xb5,0x57,0x35,0x56,0xb5,0x59,0x35,0x55,0xb5,0x5a,0x45,0x54,0xa5, +0x9c,0x31,0x10,0xcc,0x43,0xed,0x46,0x53,0x36,0x92,0x87,0xe5,0x18,0x1c,0x66,0xd6, +0x39,0x29,0x46,0x48,0x79,0x39,0x26,0x3a,0x79,0x45,0x26,0xad,0x78,0x56,0x67,0xa1, +0x37,0x60,0x69,0x15,0x35,0xe9,0x4a,0x8c,0x9c,0x31,0x10,0xd8,0x53,0xdd,0x45,0x43, +0x6b,0xf8,0x54,0xc4,0x89,0xfa,0x37,0x03,0x87,0xbb,0x49,0x04,0x75,0xb9,0x5a,0xc6, +0x63,0xf7,0x7c,0x89,0x42,0x73,0x8d,0xcd,0x41,0x2e,0x7e,0xd2,0x50,0x69,0x5f,0x98, +0x9c,0x31,0x10,0x38,0x47,0xdd,0x76,0x54,0x50,0x45,0x1f,0x3d,0x50,0x39,0x1f,0x45, +0x50,0xad,0x1e,0x51,0x11,0xa5,0x5d,0x59,0x12,0x9d,0x5c,0x62,0x63,0x95,0x1a,0xe9, +0x15,0x0d,0x19,0x6d,0x57,0x0d,0x17,0x6d,0x9c,0x31,0x10,0x1c,0x43,0xed,0x46,0x42, +0x71,0x0e,0x4d,0x6d,0x33,0x0d,0x8b,0x6a,0x15,0x15,0x89,0xe0,0x36,0x9d,0x48,0x59, +0x78,0x28,0x27,0x4d,0x78,0xb6,0x06,0xbd,0x78,0xc1,0x46,0xb2,0x58,0xd1,0x67,0x24, +0x9c,0x31,0x10,0x43,0x44,0xdd,0x46,0x54,0x3f,0x5d,0x81,0x1a,0x3c,0x69,0x24,0x8d, +0x78,0xed,0x28,0x89,0x74,0xf4,0x2c,0x85,0x70,0x75,0x51,0x04,0x2c,0x71,0x95,0x09, +0x08,0xed,0x98,0x91,0x05,0x69,0x9b,0x99,0x9c,0x31,0x10,0x18,0x43,0xed,0x45,0x53, +0x29,0x70,0x36,0xd1,0x68,0x6a,0x17,0x97,0x87,0xe5,0x17,0xdd,0x67,0xde,0x57,0xa2, +0x28,0x59,0x97,0x28,0x09,0x13,0x96,0x2d,0x0a,0x4f,0x74,0xf1,0x2b,0x8c,0x33,0x74, +0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43,0x85,0x49,0x19,0xb5,0x86,0xc8,0x37,0xf6, +0x58,0x89,0x66,0x75,0x1a,0x0a,0x94,0xf3,0x0b,0x8c,0x73,0xb0,0x4c,0x90,0x32,0xac, +0x7d,0x94,0x31,0xe8,0x7e,0x19,0x21,0xa3,0x9c,0x31,0x10,0x02,0x43,0xdd,0x36,0x43, +0x7c,0xb9,0x43,0x3d,0x3c,0x44,0x43,0xb1,0x3b,0x4d,0x45,0x29,0x39,0xd4,0x47,0x25, +0x57,0x59,0x49,0x1c,0x74,0xdd,0x2b,0x9a,0x72,0x61,0x2e,0x19,0x6f,0xe1,0x51,0x1a, +0x9c,0x31,0x10,0x4b,0x42,0xdd,0x35,0x43,0x26,0xb0,0x79,0x8e,0x35,0x6f,0x5a,0xd0, +0x64,0x6d,0x3b,0xd3,0x53,0xa9,0x4c,0x96,0x62,0xe6,0x2c,0xda,0x62,0xa2,0x4d,0x1e, +0x42,0x9e,0x6d,0x22,0x12,0xda,0x8c,0xa5,0x9c,0x31,0x10,0xcb,0x43,0xdd,0x35,0x42, +0x33,0x57,0x5b,0xe9,0x64,0x14,0x2b,0x2b,0x75,0x12,0x3a,0x2d,0x56,0x10,0x58,0xee, +0x37,0x4f,0x67,0xef,0x38,0x4f,0x66,0xae,0x59,0x90,0x45,0xad,0x5a,0x92,0x44,0xab, +0x9c,0x31,0x10,0x72,0x43,0xdc,0x45,0x43,0x5b,0x4a,0x33,0xf1,0x6c,0x10,0x43,0x6b, +0x5c,0x57,0x43,0x24,0x4c,0x9e,0x63,0x1d,0x4c,0x65,0x73,0x56,0x4c,0x2b,0x53,0xd0, +0x5b,0x71,0x54,0x8a,0x6a,0xb6,0x25,0x86,0x9c,0x31,0x10,0x94,0x33,0xdc,0x45,0x42, +0x66,0xe6,0x1a,0x11,0x22,0xee,0x1e,0x0e,0x1e,0xed,0x22,0x0d,0x1a,0xea,0x26,0x15, +0x16,0xdd,0x29,0x25,0x13,0xcd,0x2c,0x35,0x50,0xb9,0x2f,0x4d,0x0f,0xa1,0x30,0x65, +0x9c,0x31,0x10,0x44,0x43,0xdc,0x35,0x42,0x53,0xa2,0x6c,0x1f,0x33,0x9b,0x7b,0xe6, +0x23,0xd5,0x7b,0xac,0x24,0x50,0x7a,0xf1,0x35,0x0b,0x7a,0x35,0x45,0xc8,0x59,0x78, +0x66,0xc5,0x48,0x79,0x57,0xc5,0x47,0x79,0x9c,0x31,0x10,0x44,0x43,0xdc,0x35,0x42, +0x58,0xc6,0x46,0x77,0x59,0xc8,0x45,0xb4,0x5a,0x8c,0x54,0xf0,0x4b,0x11,0x54,0x6b, +0x4b,0x96,0x53,0xe5,0x3b,0xdc,0x53,0xdf,0x4b,0xe2,0x54,0x19,0x3b,0xa8,0x64,0x53, +0x9c,0x31,0x10,0x4a,0x34,0xcc,0x44,0x31,0x1e,0x6d,0x12,0x0f,0x1c,0xf1,0x13,0x8b, +0x1b,0x75,0x15,0x08,0x09,0xb7,0x17,0x07,0x07,0xf7,0x18,0xc7,0x15,0xf6,0x1a,0x88, +0x54,0x34,0x1c,0x4b,0x12,0xb1,0x1d,0xcf,0x9c,0x31,0x10,0x23,0x43,0xdc,0x44,0x42, +0x54,0xac,0x5b,0x54,0x54,0x27,0x6b,0xda,0x53,0xe1,0x5b,0xe0,0x43,0xdb,0x6b,0xe6, +0x44,0x15,0x6b,0x6c,0x34,0x8f,0x7a,0xf1,0x35,0x0b,0x6a,0x35,0x26,0x07,0x79,0x38, +0x9c,0x31,0x10,0xd8,0x33,0xdc,0x44,0x42,0x1c,0x15,0x60,0xe5,0x20,0x16,0x1c,0xe5, +0x63,0x19,0x19,0xdd,0x27,0x21,0x15,0xd1,0x2a,0x31,0x12,0xc1,0x2d,0x45,0x10,0xa9, +0x2e,0x59,0x0f,0x95,0x2f,0x74,0x0f,0x78,0x9c,0x31,0x10,0xb0,0x44,0xdc,0x35,0x42, +0x2d,0xf1,0x4a,0x0c,0x35,0xd4,0x4a,0x29,0x55,0x96,0x4a,0x67,0x2d,0x38,0x4a,0xc5, +0x4c,0xda,0x4b,0x44,0x4c,0x5b,0x4b,0xc3,0x4b,0xdb,0x4c,0x23,0x43,0x7b,0x2c,0xa4, +0x9c,0x31,0x10,0xda,0x44,0xcc,0x45,0x32,0x42,0x19,0x2e,0x25,0x41,0x58,0x2e,0xc7, +0x68,0xd5,0x2f,0x4a,0x48,0x73,0x2f,0x8c,0x48,0x50,0x4f,0x8f,0x48,0x4d,0x6f,0x72, +0x28,0x8b,0x6f,0x34,0x28,0xe9,0x6e,0x97,0x9c,0x31,0x10,0x48,0x42,0xcc,0x35,0x23, +0x33,0x0e,0x6b,0xf2,0x44,0x8b,0x5a,0x74,0x56,0x09,0x48,0xb5,0x67,0xc9,0x37,0x35, +0x69,0x89,0x45,0x74,0x6b,0x0b,0x54,0x31,0x5c,0x4e,0x62,0xee,0x5d,0x52,0x71,0xe9, +0x9c,0x31,0x10,0x19,0x42,0xcc,0x34,0x22,0x3e,0x17,0x61,0x65,0x4e,0x9c,0x51,0x20, +0x5e,0x61,0x31,0x5b,0x6e,0x25,0x31,0xd6,0x6d,0x6a,0x52,0xd2,0x5c,0x6e,0x63,0xcf, +0x3b,0x31,0x65,0x0c,0x49,0xf2,0x46,0x8b,0x9c,0x31,0x10,0x19,0x42,0xcc,0x34,0x22, +0x68,0x73,0x28,0x0b,0x76,0xf3,0x49,0x8c,0x55,0xb2,0x7a,0xcd,0x44,0x6f,0x7c,0x10, +0x53,0x2c,0x3c,0xd3,0x72,0x69,0x4d,0x97,0x51,0xe4,0x6d,0xdc,0x31,0xe0,0x5d,0xe0, +0x9c,0x31,0x10,0x08,0x32,0xcc,0x34,0x31,0x07,0x70,0x36,0x96,0x09,0x5e,0x34,0xa4, +0x0c,0x50,0x30,0xb1,0x10,0x46,0x2c,0xbd,0x14,0x39,0x27,0xc5,0x59,0x35,0x22,0xc4, +0x1e,0x31,0x5d,0xc9,0x24,0x35,0x18,0xc4,0x9c,0x31,0x10,0xbc,0x32,0xcc,0x24,0x31, +0x29,0x39,0x13,0xbe,0x2d,0x41,0x0f,0xb0,0x30,0x4d,0x0c,0xa6,0x33,0x5d,0x0a,0x94, +0x35,0x6e,0x09,0x86,0x75,0x7d,0x09,0x74,0x35,0x8e,0x4a,0x66,0x33,0x9d,0x0d,0x58, +0x9c,0x31,0x10,0x95,0x31,0xcc,0x34,0x32,0x70,0xaa,0x10,0x4e,0x2c,0xb4,0x14,0x40, +0x28,0xbe,0x58,0x3d,0x23,0xc0,0x1d,0x39,0x1e,0xc1,0x22,0x39,0x1a,0xbc,0x27,0x3d, +0x15,0xb9,0x2b,0x45,0x11,0xb1,0x2e,0x52,0x9c,0x31,0x10,0x75,0x31,0xcb,0x23,0x31, +0x07,0x72,0x59,0x0f,0x26,0x2b,0x39,0xd6,0x05,0xa4,0x5a,0x1e,0x25,0x9c,0x39,0xe5, +0x26,0x15,0x39,0x2c,0x47,0x4e,0x17,0xf3,0x28,0xc9,0x36,0x38,0x2a,0x84,0x33,0xfc, +0x9c,0x31,0x10,0x38,0x33,0xcb,0x34,0x32,0x0c,0x81,0x31,0xf9,0x0f,0x01,0x2f,0x7a, +0x11,0x00,0x4d,0x7a,0x33,0x86,0x2a,0xf0,0x55,0x8d,0x29,0x69,0x37,0x14,0x27,0xdd, +0x38,0xa1,0x06,0x50,0x19,0x31,0x25,0xc1,0x9c,0x31,0x10,0x21,0x33,0xcc,0x24,0x31, +0x33,0x80,0x0b,0x75,0x32,0x8e,0x0c,0x65,0x31,0x9d,0x0e,0x59,0x2f,0xaa,0x11,0x4e, +0x2b,0xb0,0x15,0x41,0x67,0xba,0x19,0x3d,0x23,0xc0,0x1d,0x39,0x1e,0xc2,0x62,0x39, +0x9c,0x31,0x10,0x9b,0x32,0xcc,0x24,0x32,0x1a,0xbc,0x27,0x3d,0x15,0xb9,0x2b,0x44, +0x11,0xb1,0x2f,0x51,0x0e,0xa5,0x31,0x5c,0x0c,0x95,0x33,0x6d,0x0a,0x89,0x34,0x79, +0x0a,0x79,0x33,0x89,0x0c,0x69,0x32,0x99,0x9c,0x31,0x10,0x36,0x32,0xcb,0x24,0x31, +0x27,0x1d,0x37,0xe5,0x28,0x91,0x35,0xed,0x4a,0x89,0x33,0xf5,0x2c,0x81,0x31,0xf8, +0x2e,0x81,0x2f,0x79,0x11,0x01,0x2d,0x78,0x33,0x85,0x2a,0xf1,0x15,0x8d,0x29,0x6a, +0x9c,0x31,0x10,0x78,0x34,0xcb,0x24,0x32,0x2d,0xc5,0x29,0xf7,0x4e,0x08,0x29,0xb4, +0x2e,0x4c,0x09,0x91,0x2e,0x4f,0x09,0x8d,0x26,0x33,0x29,0xca,0x25,0xf6,0x2a,0x07, +0x4d,0xb9,0x32,0x64,0x4d,0x3b,0x32,0xe2,0x9c,0x31,0x10,0x53,0x8a,0xcd,0xa9,0x98, +0x6e,0x25,0x6d,0x95,0x6d,0xe5,0x6d,0xd5,0x6d,0xa5,0x6e,0x15,0x6d,0x65,0x6e,0x59, +0x6d,0x21,0x6e,0x99,0x6d,0x21,0x6e,0x99,0x69,0x64,0x40,0x45,0xab,0xb2,0x2c,0x8d, +0x9c,0x31,0x10,0xa9,0x57,0xdd,0x66,0x54,0x89,0xe2,0x16,0x19,0x98,0x60,0x17,0x99, +0x56,0xe1,0x59,0x19,0x55,0xe1,0x5a,0x1d,0x54,0xd9,0x5b,0x21,0x13,0xd5,0x5c,0x29, +0x53,0x4d,0x5c,0xb1,0x52,0xc5,0x5c,0xb9,0x9c,0x31,0x10,0x9f,0x44,0xdc,0x46,0x53, +0x65,0xc0,0x39,0xc2,0x46,0x32,0x58,0xd0,0x27,0x25,0x77,0xde,0x08,0x99,0x76,0x64, +0x2a,0x11,0x54,0x6d,0x4c,0x08,0x32,0x71,0x8e,0x05,0x10,0x70,0x70,0x09,0x2e,0x72, +0x9c,0x31,0x10,0x41,0x43,0xcc,0x35,0x43,0x5a,0x45,0x44,0x77,0x4c,0x08,0x62,0xf4, +0x3d,0x8d,0x41,0xaf,0x5e,0x92,0x30,0xea,0x7f,0x17,0x20,0x64,0x7f,0x5d,0x30,0x5e, +0x5f,0x22,0x60,0xd9,0x2e,0x68,0x71,0x94,0x9c,0x31,0x10,0x41,0x43,0xcc,0x35,0x43, +0x2d,0xac,0x62,0xd0,0x4c,0x70,0x44,0x0d,0x7a,0xf2,0x25,0x8b,0x79,0x74,0x37,0x0a, +0x57,0xb4,0x48,0xca,0x46,0x73,0x6a,0x4c,0x34,0xf1,0x6b,0x8e,0x33,0xae,0x6c,0x92, +0x9c,0x31,0x10,0x5c,0x43,0xcc,0x35,0x42,0x42,0xaa,0x5d,0x56,0x62,0x26,0x2d,0xda, +0x81,0xe1,0x2d,0xdf,0x51,0xdd,0x5d,0xa3,0x42,0x59,0x6d,0x27,0x43,0x15,0x7c,0x2b, +0x43,0xd1,0x5b,0x2e,0x45,0x0f,0x4a,0x30,0x9c,0x31,0x10,0x2c,0x42,0xcc,0x25,0x32, +0x66,0x4e,0x28,0xb1,0x57,0x8d,0x47,0x71,0x49,0x0d,0x56,0x30,0x3a,0x4f,0x74,0xee, +0x4b,0x51,0x63,0xec,0x5c,0x54,0x52,0xe9,0x6d,0x17,0x32,0x65,0x6d,0x9b,0x32,0x21, +0x9c,0x31,0x10,0x98,0x42,0xcc,0x35,0x32,0x5d,0x9f,0x52,0x1c,0x3d,0xa4,0x62,0x58, +0x4d,0x28,0x63,0x15,0x4c,0x6b,0x53,0xd1,0x5b,0x6e,0x34,0xcf,0x6a,0x70,0x36,0x0d, +0x69,0x32,0x57,0x4c,0x47,0xf2,0x68,0x8c,0x9c,0x31,0x10,0xc1,0x42,0xcc,0x35,0x42, +0x46,0xb2,0x59,0xcd,0x55,0x70,0x5b,0x0e,0x44,0x2e,0x5c,0x11,0x43,0x2b,0x5c,0xd4, +0x42,0xa8,0x5d,0x98,0x62,0x24,0x2d,0xdc,0x71,0xdf,0x3d,0xe1,0x52,0x1b,0x5d,0x65, +0x9c,0x31,0x10,0xc1,0x42,0xcc,0x35,0x42,0x42,0x97,0x6c,0xe9,0x43,0x53,0x7b,0xec, +0x34,0x50,0x5a,0xef,0x45,0x8e,0x49,0xb0,0x66,0xcd,0x28,0x31,0x58,0x0d,0x46,0xf1, +0x49,0x8e,0x55,0xb0,0x3a,0xcf,0x74,0x6e,0x9c,0x31,0x10,0x12,0x42,0xcb,0x35,0x32, +0x57,0x89,0x46,0xed,0x59,0x15,0x45,0x5c,0x5a,0xa5,0x24,0xce,0x5b,0x35,0x24,0x3c, +0x5b,0x46,0x44,0x2d,0x3a,0xd4,0x65,0x1d,0x59,0xe6,0x46,0x8d,0x57,0xf1,0x48,0x82, +0x9c,0x31,0x10,0x8d,0x42,0xcc,0x34,0x42,0x5a,0xef,0x35,0x4e,0x69,0xb1,0x36,0xcd, +0x58,0x71,0x68,0x0c,0x37,0x31,0x79,0x4d,0x35,0xf0,0x6a,0x8f,0x54,0xae,0x4b,0x91, +0x53,0xab,0x3c,0x54,0x62,0xe8,0x4d,0x18,0x9c,0x31,0x10,0x49,0x43,0xcc,0x34,0x32, +0x62,0x64,0x5d,0x5c,0x42,0x20,0x6d,0x60,0x42,0x5c,0x7d,0x24,0x42,0xd8,0x5c,0xa8, +0x53,0x54,0x4b,0xeb,0x64,0x51,0x3a,0xee,0x65,0x4f,0x49,0xf0,0x46,0x8e,0x68,0xb0, +0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32,0x37,0xcd,0x77,0x30,0x39,0x0e,0x65,0xef, +0x3a,0x4f,0x44,0xed,0x4b,0x52,0x44,0x2b,0x6c,0x15,0x33,0x68,0x5c,0x98,0x42,0xe4, +0x6d,0x1c,0x42,0xa0,0x5d,0x20,0x52,0xdc,0x9c,0x31,0x10,0xbd,0x44,0xcc,0x34,0x32, +0x2e,0x71,0x49,0x8c,0x26,0x33,0x69,0xea,0x25,0xd4,0x6a,0x49,0x4d,0x56,0x4a,0xc8, +0x4c,0xd6,0x4b,0x47,0x6c,0x37,0x2b,0xe7,0x6b,0xb7,0x2c,0x88,0x4b,0x16,0x2d,0x08, +0x9c,0x31,0x10,0x9f,0x8a,0xdd,0xaa,0x98,0x6d,0x45,0x6e,0x25,0x6d,0x45,0x6e,0x25, +0x6d,0x45,0x6d,0xba,0x45,0xd5,0xa6,0x05,0x2c,0xe5,0x6e,0x95,0x6c,0x55,0x6f,0x15, +0x6c,0x55,0x6f,0x25,0x6c,0x45,0x6f,0x25,0x9c,0x31,0x10,0x10,0x44,0xdd,0x46,0x53, +0x40,0x40,0x5f,0x3c,0x60,0xb6,0x3e,0x49,0x81,0xac,0x1c,0xd5,0x63,0xa1,0x5a,0x5c, +0x26,0x19,0x57,0xe1,0x29,0x15,0x74,0x64,0x4c,0x91,0x51,0x69,0x6f,0x91,0x0d,0xe9, +0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43,0x89,0x8a,0x25,0x73,0x7b,0x0c,0x54,0x31, +0x3c,0x4f,0x62,0xed,0x1d,0x13,0x92,0x29,0x1d,0xd7,0x71,0xa4,0x5e,0x1c,0x31,0xa0, +0x9e,0x21,0x01,0xdb,0xad,0xa5,0x12,0x57,0x9c,0x31,0x10,0x02,0x43,0xdd,0x36,0x43, +0x79,0xd0,0x26,0xa5,0x37,0xd9,0x68,0xa1,0x15,0xdd,0x8b,0x1e,0x12,0xe1,0x4d,0x99, +0x50,0x62,0x30,0x99,0x6d,0xe0,0x13,0x1d,0x6b,0x5d,0x15,0x21,0x48,0xd9,0x77,0x25, +0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43,0x23,0xaa,0x9c,0x96,0x12,0xe6,0x7c,0xda, +0x42,0xa2,0x3d,0x1e,0x82,0x9e,0x2d,0x22,0x72,0xda,0x4c,0xe6,0x43,0x16,0x6c,0x29, +0x33,0xd3,0x7b,0x6d,0x34,0xd0,0x5a,0x6f,0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43, +0x46,0x0e,0x49,0x31,0x57,0x4d,0x57,0xb1,0x48,0xcd,0x66,0x31,0x3a,0x4e,0x64,0xaf, +0x5b,0x90,0x43,0x6d,0x6c,0xd3,0x32,0x69,0x6d,0x97,0x21,0xe5,0x6e,0x1c,0x51,0xa0, +0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43,0x3e,0x21,0x91,0x9b,0x0d,0xe5,0x92,0x17, +0x1d,0x29,0x63,0x13,0x5c,0x2d,0x24,0x10,0x7a,0xef,0x05,0x4e,0x99,0xb1,0x16,0xcd, +0x78,0x32,0x58,0x0c,0x26,0xf1,0x89,0x8d,0x9c,0x31,0x10,0xfd,0x43,0xdd,0x45,0x43, +0x15,0xb0,0x7a,0x8f,0x34,0x6d,0x5b,0xd2,0x53,0xaa,0x1c,0x95,0x82,0xe7,0x2d,0x19, +0x72,0xa3,0x4d,0x5d,0x42,0x9f,0x8d,0x21,0x02,0xdb,0x8c,0xe5,0x33,0x57,0x5c,0x28, +0x9c,0x31,0x10,0x53,0x42,0xcd,0x35,0x43,0x60,0x14,0x3e,0xab,0x72,0x12,0x3c,0xad, +0x74,0x10,0x4a,0x6f,0x56,0x8f,0x68,0x2f,0x38,0xcf,0x65,0xee,0x4b,0x10,0x73,0xad, +0x3d,0x12,0x61,0xab,0x5e,0x94,0x40,0x68,0x9c,0x31,0x10,0xd9,0x42,0xdc,0x35,0x42, +0x6b,0xd0,0x33,0xab,0x8c,0x56,0x33,0x65,0x4c,0x9d,0x73,0x1e,0x3c,0x64,0x63,0x57, +0x5c,0x2a,0x43,0xd1,0x6b,0xb0,0x34,0x4b,0x6a,0xf5,0x35,0x47,0x7a,0x39,0x36,0x04, +0x9c,0x31,0x10,0x51,0x43,0xdc,0x34,0x32,0x59,0x3b,0x47,0x02,0x47,0xfc,0x88,0x42, +0x26,0xfc,0x69,0x43,0x55,0xfa,0x3a,0x06,0x75,0x36,0x3b,0x0a,0x74,0x71,0x4b,0x8f, +0x43,0xec,0x6c,0x16,0x23,0x65,0x6c,0x5c,0x9c,0x31,0x10,0xab,0x42,0xdc,0x45,0x32, +0x53,0x5f,0x4c,0x63,0x63,0x98,0x4c,0x29,0x53,0xd2,0x5b,0xaf,0x44,0x8d,0x4a,0xf4, +0x45,0x48,0x4a,0x37,0x56,0x05,0x59,0x3a,0x37,0x04,0x68,0x3b,0x48,0x03,0x67,0x3a, +0x9c,0x31,0x10,0xab,0x42,0xdc,0x45,0x32,0x39,0x05,0x46,0x38,0x5a,0x07,0x45,0x75, +0x5a,0xcb,0x44,0xb0,0x4b,0x50,0x44,0x2b,0x4b,0xd6,0x53,0xe5,0x4c,0x1c,0x43,0x9f, +0x4b,0xe2,0x33,0xd9,0x5b,0xe8,0x34,0x13,0x9c,0x31,0x10,0x2e,0x43,0xcc,0x45,0x32, +0x5e,0xae,0x21,0x8e,0x6d,0x72,0x43,0x0a,0x4b,0xf6,0x54,0xc7,0x3a,0x38,0x76,0x86, +0x38,0x39,0x78,0x86,0x26,0x78,0x7a,0x47,0x34,0xb6,0x6c,0x0a,0x42,0xf3,0x6d,0x4d, +0x9c,0x31,0x10,0x53,0x34,0xcc,0x35,0x42,0x11,0xae,0x1e,0x92,0x10,0xe9,0x1f,0x57, +0x10,0x64,0x0f,0x9d,0x10,0x1e,0x1f,0x63,0x10,0x98,0x1e,0xe9,0x21,0x53,0x1d,0xed, +0x22,0x4f,0x1c,0xb1,0x13,0xcb,0x1b,0x34,0x9c,0x31,0x10,0xf1,0x44,0xcc,0x35,0x32, +0x2a,0xa4,0x4c,0xba,0x4b,0x83,0x6b,0xdb,0x2c,0x64,0x6a,0xfa,0x2d,0x44,0x6a,0x39, +0x26,0x06,0x69,0x77,0x46,0xa8,0x68,0xf5,0x4f,0x2a,0x48,0x93,0x4f,0x6c,0x28,0x50, +0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32,0x6f,0x1f,0x40,0xdc,0x5e,0xe4,0x41,0x57, +0x5e,0x29,0x62,0x12,0x4d,0x2e,0x63,0x0e,0x3b,0xf1,0x74,0x8b,0x2a,0x74,0x66,0x09, +0x38,0xf5,0x67,0x89,0x47,0x35,0x59,0x49,0x9c,0x31,0x10,0x6e,0x43,0xcc,0x34,0x31, +0x55,0x74,0x5b,0x0b,0x63,0xf2,0x3c,0x8d,0x72,0xaf,0x3d,0xd2,0x71,0x6a,0x3e,0x96, +0x60,0xa5,0x5f,0x5c,0x40,0x60,0x6f,0x61,0x40,0x9a,0x6f,0x27,0x31,0x14,0x6e,0x2c, +0x9c,0x31,0x10,0x3b,0x43,0xcc,0x44,0x42,0x32,0x10,0x6d,0x31,0x33,0x4c,0x6b,0xb4, +0x45,0x09,0x69,0xf6,0x46,0x88,0x48,0x37,0x58,0x87,0x46,0x76,0x6a,0x09,0x34,0xb4, +0x7b,0xcb,0x33,0x71,0x7d,0x0f,0x32,0x2d,0x9c,0x31,0x10,0x09,0x43,0xcc,0x45,0x31, +0x7e,0x13,0x31,0x28,0x7e,0xd8,0x30,0xa3,0x6f,0x1e,0x40,0x9e,0x4e,0xe3,0x51,0x18, +0x4e,0x68,0x51,0xd3,0x4d,0x6d,0x62,0xcf,0x5c,0x70,0x54,0x0c,0x4a,0xf3,0x55,0x8a, +0x9c,0x31,0x10,0x05,0x43,0xcc,0x35,0x32,0x59,0x75,0x37,0x49,0x67,0xb5,0x38,0xc9, +0x66,0x34,0x3a,0x4b,0x74,0xb2,0x4b,0xcd,0x73,0x6f,0x3c,0xd1,0x52,0x6b,0x5d,0xd5, +0x31,0xa7,0x5e,0x5a,0x31,0x62,0x7e,0x5e,0x9c,0x31,0x10,0x2d,0x42,0xcc,0x33,0x32, +0x41,0x5d,0x6e,0x63,0x51,0x98,0x4d,0xa8,0x62,0x54,0x4c,0xec,0x73,0x50,0x4b,0xef, +0x64,0x8e,0x4a,0xb1,0x45,0xcc,0x69,0x33,0x37,0x4b,0x67,0xb3,0x48,0xcb,0x56,0x72, +0x9c,0x31,0x10,0xd4,0x42,0xcc,0x34,0x32,0x6a,0x0c,0x34,0xf1,0x6b,0x4f,0x33,0xee, +0x4c,0x52,0x52,0xea,0x3d,0x15,0x62,0x67,0x4d,0x9a,0x41,0xe2,0x5d,0xde,0x31,0xde, +0x5d,0xe2,0x42,0x1a,0x3d,0x66,0x62,0x96,0x9c,0x31,0x10,0x60,0x42,0xcc,0x24,0x32, +0x4c,0xaa,0x43,0x92,0x5b,0xad,0x44,0x90,0x5a,0xaf,0x45,0x8e,0x59,0x71,0x56,0xcd, +0x38,0x31,0x58,0x0d,0x56,0xf1,0x49,0x4e,0x45,0xb0,0x4a,0x8f,0x44,0xae,0x6b,0x92, +0x9c,0x31,0x10,0x50,0x41,0xcb,0x24,0x32,0x47,0xed,0x38,0x95,0x46,0x61,0x59,0xa1, +0x45,0x50,0x5a,0x30,0x45,0x42,0x5a,0x41,0x45,0x30,0x5a,0x4c,0x45,0xa6,0x39,0x5d, +0x47,0x14,0x57,0xe8,0x48,0x8e,0x55,0xf2,0x9c,0x31,0x10,0x08,0x32,0xcc,0x34,0x31, +0x15,0x40,0x27,0xb9,0x19,0x3e,0x22,0xbd,0x1e,0x3c,0x1e,0xbe,0x23,0x3e,0x19,0xbd, +0x27,0x40,0x15,0xb6,0x2b,0x49,0x11,0xac,0x2e,0x55,0x0e,0xa2,0x30,0x61,0x0d,0x94, +0x9c,0x31,0x10,0x36,0x32,0xcb,0x24,0x31,0x39,0x2d,0x26,0x45,0x59,0x3c,0x06,0x35, +0x39,0x4a,0x26,0xa9,0x38,0x58,0x27,0x9e,0x17,0x61,0x29,0x10,0x15,0x6d,0x4b,0x0a, +0x13,0x70,0x4d,0x05,0x31,0x76,0x2f,0x05,0x9c,0x31,0x10,0x50,0x43,0xcb,0x24,0x31, +0x4f,0x74,0x51,0x06,0x4d,0x75,0x33,0x08,0x6b,0x6d,0x35,0x11,0x49,0x64,0x36,0x99, +0x48,0x5a,0x37,0xa4,0x67,0x4d,0x58,0x32,0x47,0x40,0x58,0x3e,0x47,0x36,0x38,0x4c, +0x9c,0x31,0x10,0x38,0x33,0xcb,0x34,0x32,0x47,0xaa,0x17,0x55,0x28,0x9c,0x35,0xe1, +0x4a,0x15,0x34,0x68,0x0c,0x0d,0x32,0x6d,0x2e,0x09,0x30,0x71,0x30,0x09,0x2e,0x71, +0x32,0x09,0x0c,0x6d,0x33,0x8d,0x0a,0xea,0x9c,0x31,0x10,0x66,0x33,0xcb,0x24,0x21, +0x55,0x95,0x09,0x61,0x37,0x1d,0x27,0xd5,0x38,0x29,0x27,0x49,0x38,0xb5,0x26,0xbe, +0x38,0xc1,0x06,0xb0,0x38,0xd1,0x27,0x25,0x37,0xdc,0x28,0x19,0x36,0xe6,0x29,0x91, +0x9c,0x31,0x10,0x50,0x43,0xcb,0x24,0x31,0x55,0x6c,0x4b,0x0a,0x53,0x75,0x4d,0x04, +0x50,0xf9,0x4f,0x82,0x4e,0xf8,0x31,0x85,0x6c,0xf6,0x53,0x89,0x6a,0xec,0x55,0x92, +0x49,0x65,0x36,0x98,0x47,0xd9,0x57,0xa5,0x9c,0x31,0x10,0xab,0x33,0xcb,0x24,0x31, +0x07,0x4c,0x38,0xb5,0x06,0xc2,0x58,0xc0,0x07,0x35,0x78,0x4e,0x07,0xa4,0x57,0x59, +0x08,0x9e,0x55,0xe0,0x0a,0x12,0x54,0x6a,0x0c,0x0c,0x52,0x71,0x2e,0x09,0x50,0x70, +0x9c,0x31,0x10,0x8c,0x33,0xcb,0x24,0x32,0x10,0x09,0x2e,0x71,0x32,0x08,0x2c,0x6d, +0x14,0x11,0x4a,0xe5,0x15,0x99,0x49,0x5d,0x16,0xa5,0x48,0x52,0x17,0xad,0x47,0xc4, +0x37,0xba,0x27,0xb8,0x37,0xc9,0x08,0x2e,0x9c,0x31,0x10,0xbd,0x33,0xbb,0x34,0x22, +0x3e,0x50,0x22,0x21,0x3b,0xdd,0x25,0x18,0x58,0xe6,0x08,0x10,0x35,0x69,0x0c,0x0d, +0x31,0x6d,0x2f,0x8d,0x2d,0xed,0x53,0x8d,0x2a,0x69,0x37,0x15,0x06,0xe5,0x3a,0x19, +0x9c,0x31,0x10,0x61,0x43,0xbb,0x34,0x21,0x42,0x5d,0x5d,0xa4,0x41,0x51,0x5e,0xad, +0x40,0xc8,0x5e,0xba,0x40,0xbd,0x6e,0xc4,0x40,0xb2,0x6e,0x4d,0x31,0xa9,0x5d,0x56, +0x32,0x9d,0x6c,0x5c,0x33,0x9a,0x6a,0xe5,0x9c,0x31,0x10,0x4a,0x32,0xbb,0x23,0x21, +0x0a,0xc5,0x4c,0xba,0x0b,0x84,0x2b,0xda,0x0c,0x64,0x2b,0x19,0x35,0x25,0x32,0x58, +0x2d,0xe6,0x09,0xb7,0x2e,0x68,0x01,0x35,0x2e,0xea,0x28,0xd3,0x0f,0x2c,0x30,0xb0, +0x9c,0x31,0x10,0xd9,0x32,0xbb,0x33,0x22,0x17,0x2f,0x28,0xae,0x07,0x31,0x28,0xcc, +0x0e,0xf3,0x31,0x2a,0x2e,0x75,0x11,0xa8,0x4d,0xf7,0x0a,0x46,0x0d,0x58,0x2a,0xe5, +0x0c,0x99,0x53,0xa5,0x2b,0xd9,0x2c,0x65,0x9c,0x31,0x10,0xf9,0x32,0xbb,0x24,0x11, +0x4c,0xe6,0x14,0x19,0x29,0xe0,0x36,0x9d,0x27,0xda,0x38,0xa1,0x25,0xd4,0x1a,0x29, +0x44,0xce,0x1b,0x31,0x23,0xc5,0x3b,0xb9,0x03,0xbd,0x3b,0xc1,0x24,0x35,0x3a,0xc9, +0x9c,0x31,0x10,0xf0,0x31,0xbb,0x23,0x21,0x22,0x96,0x4c,0xe9,0x23,0x53,0x1b,0xed, +0x34,0x50,0x3a,0xef,0x15,0x4e,0x39,0xf1,0x16,0x8d,0x18,0xb2,0x27,0xcc,0x37,0x72, +0x39,0x0d,0x16,0x31,0x3a,0x0e,0x24,0xef,0x9c,0x31,0x10,0x7f,0x31,0xba,0x23,0x21, +0x2b,0x42,0x24,0x3a,0x3c,0x07,0x23,0x34,0x3c,0xce,0x32,0xac,0x2d,0x55,0x32,0x65, +0x4d,0x5d,0x22,0x5d,0x2d,0x65,0x42,0x95,0x2c,0xed,0x13,0x0e,0x4c,0x74,0x03,0xc7, +0x9c,0x31,0x10,0xf0,0x31,0xbb,0x23,0x21,0x3b,0x6c,0x34,0x91,0x2a,0x6e,0x35,0xcf, +0x39,0x70,0x17,0x0e,0x38,0x30,0x28,0x4e,0x26,0xf0,0x59,0x8f,0x15,0xaf,0x3a,0x90, +0x44,0xad,0x2b,0x93,0x43,0xaa,0x2c,0x96,0x9c,0x31,0x10,0x7d,0x31,0xbb,0x12,0x21, +0x32,0xe6,0x2d,0x19,0x22,0x63,0x2d,0x5e,0x12,0x5e,0x4d,0x62,0x22,0x5a,0x3d,0x26, +0x32,0xd6,0x3c,0xaa,0x13,0x93,0x3b,0xad,0x44,0x90,0x1a,0xaf,0x35,0x8e,0x29,0xb1, +0x9c,0x31,0x10,0xf0,0x31,0xbb,0x23,0x21,0x16,0xcd,0x28,0x72,0x37,0xcc,0x37,0x31, +0x29,0x0d,0x35,0xf0,0x2a,0x4e,0x14,0xef,0x2b,0x51,0x33,0xec,0x2c,0x54,0x23,0x29, +0x3c,0xd7,0x22,0xa5,0x2d,0x5b,0x42,0x61,0x9c,0x31,0x10,0xf0,0x31,0xbb,0x23,0x21, +0x3d,0x5f,0x22,0x5d,0x4d,0x63,0x32,0x99,0x1c,0xe6,0x43,0x16,0x1c,0x2a,0x13,0xd3, +0x4b,0x6d,0x24,0xd0,0x3a,0x6f,0x36,0x0f,0x29,0x30,0x27,0x0e,0x37,0xf0,0x18,0x4e, +0x9c,0x31,0x10,0x4a,0x32,0xbb,0x23,0x21,0x4b,0x57,0x24,0xc7,0x0a,0xd7,0x4d,0x48, +0x0a,0x56,0x4d,0xc9,0x29,0xd4,0x2e,0x2b,0x29,0x93,0x0e,0x6c,0x29,0x51,0x16,0x8e, +0x49,0x4f,0x2e,0x90,0x29,0x6d,0x46,0x52,0x9c,0x31,0x10,0xb1,0x42,0xbb,0x23,0x21, +0x54,0xcb,0x56,0xf4,0x49,0x0a,0x56,0xd5,0x49,0x28,0x56,0x96,0x35,0x88,0x56,0x37, +0x45,0xc7,0x51,0xf7,0x46,0x07,0x55,0x97,0x36,0x68,0x65,0x56,0x3a,0xa9,0x69,0x15, +0x9c,0x31,0x10,0xa1,0x33,0xba,0x24,0x21,0x17,0x15,0x27,0x61,0x18,0xa1,0x26,0x50, +0x39,0x31,0x25,0xc1,0x39,0xbd,0x26,0x36,0x39,0x4d,0x06,0xa5,0x38,0x5d,0x08,0x19, +0x36,0xe5,0x29,0x8d,0x34,0xf1,0x2b,0x85,0x9c,0x31,0x10,0x5e,0x33,0xba,0x22,0x11, +0x0c,0x9d,0x2b,0x80,0x0c,0x1e,0x04,0x20,0x2b,0x7d,0x2c,0xc1,0x22,0xdc,0x25,0x43, +0x02,0x5a,0x25,0xa6,0x29,0xf7,0x0e,0x09,0x09,0xb4,0x0e,0x2c,0x29,0x90,0x16,0x50, +0x9c,0x31,0x10,0xc5,0x32,0xba,0x23,0x21,0x29,0xac,0x36,0x33,0x09,0xc9,0x2d,0xf7, +0x12,0x26,0x25,0x99,0x2a,0x84,0x25,0x1b,0x2b,0x02,0x04,0x9c,0x23,0xa1,0x2b,0xfd, +0x24,0x21,0x2b,0x7c,0x2c,0xa2,0x2a,0xfb,0x9c,0x31,0x10,0xc3,0x32,0xba,0x22,0x11, +0x35,0x24,0x32,0x79,0x35,0x86,0x32,0x37,0x35,0xe9,0x29,0xf4,0x2e,0x0c,0x29,0xd1, +0x2e,0x0f,0x49,0xcd,0x06,0x12,0x29,0xea,0x25,0xd5,0x4a,0x27,0x2d,0x98,0x32,0x85, +0x9c,0x31,0x10,0x1a,0x32,0xaa,0x12,0x11,0x2e,0x7a,0x29,0xe3,0x2d,0x7b,0x2a,0xc2, +0x2c,0x9c,0x2b,0xc2,0x4b,0x9c,0x2c,0xc2,0x4a,0xbb,0x0d,0xa3,0x29,0xda,0x2e,0x65, +0x29,0x18,0x2f,0x27,0x08,0x76,0x37,0xa9,0x9c,0x31,0x10,0x94,0x32,0xba,0x22,0x20, +0x29,0xf3,0x2d,0xec,0x21,0xf1,0x2d,0xef,0x29,0xee,0x2d,0xf2,0x0a,0x0b,0x2d,0xd4, +0x2a,0x28,0x2d,0x97,0x2a,0x66,0x0d,0x39,0x0a,0xc4,0x2c,0xda,0x23,0x23,0x2c,0x7b, +0x9c,0x31,0x10,0xea,0x31,0xaa,0x12,0x21,0x26,0x86,0x18,0x79,0x28,0x46,0x36,0xb8, +0x39,0xc6,0x15,0x37,0x3b,0x48,0x43,0xb4,0x1c,0xcb,0x32,0x71,0x2d,0xcf,0x21,0x6d, +0x3e,0x93,0x20,0xe9,0x3f,0x57,0x40,0x64,0x9c,0x31,0x10,0x79,0x31,0xba,0x22,0x11, +0x3b,0xdc,0x33,0xdf,0x2b,0xe1,0x23,0xda,0x3b,0xa7,0x24,0x15,0x4b,0x6c,0x34,0x90, +0x3a,0xf1,0x35,0x0b,0x2a,0x75,0x35,0xc8,0x29,0x78,0x36,0x85,0x28,0xb9,0x47,0x84, +0x9c,0x31,0x10,0x02,0x32,0xba,0x12,0x11,0x23,0xdc,0x4c,0x42,0x0b,0x5b,0x34,0xc3, +0x2a,0xda,0x2d,0x25,0x22,0x78,0x0d,0x87,0x0a,0x36,0x2d,0xc9,0x0a,0x14,0x2d,0xec, +0x09,0xf1,0x2d,0xef,0x29,0xee,0x0d,0xf2,0x9c,0x31,0x10,0x2b,0x31,0xaa,0x22,0x21, +0x30,0x17,0x3f,0x2a,0x10,0xd2,0x3e,0x6f,0x12,0x0d,0x1d,0x33,0x23,0x4a,0x2b,0xb6, +0x24,0xc7,0x29,0xf8,0x16,0x86,0x28,0x78,0x28,0x45,0x36,0xb8,0x29,0xc6,0x25,0x37, +0x9c,0x31,0x10,0xea,0x31,0xaa,0x12,0x21,0x4b,0x48,0x23,0xb4,0x2c,0x8b,0x22,0x71, +0x2d,0xcf,0x31,0x6d,0x2e,0x93,0x20,0xe8,0x3f,0x18,0x30,0x63,0x3f,0x9d,0x20,0x5e, +0x2f,0x62,0x40,0x99,0x2f,0x27,0x41,0x14,0x9c,0x31,0x10,0x61,0x31,0xaa,0x22,0x11, +0x2e,0x6c,0x21,0xd0,0x3d,0x70,0x32,0xcc,0x2c,0x33,0x44,0x49,0x2a,0xb6,0x15,0xc7, +0x29,0x37,0x27,0x47,0x17,0xb7,0x38,0xc7,0x26,0x36,0x2a,0x88,0x24,0x74,0x2b,0xcb, +0x9c,0x31,0x10,0xa0,0x31,0xaa,0x12,0x11,0x23,0x32,0x2d,0x0e,0x22,0x2e,0x2e,0x12, +0x31,0x69,0x3e,0xd7,0x20,0xe4,0x3f,0x1c,0x10,0x9f,0x2f,0x21,0x30,0xda,0x2e,0xa6, +0x21,0x55,0x4d,0xeb,0x22,0x11,0x2c,0xef,0x9c,0x31,0x10,0xa0,0x31,0xaa,0x12,0x11, +0x33,0x4d,0x3b,0xb2,0x34,0xca,0x1a,0x75,0x36,0x49,0x28,0xb6,0x27,0xc8,0x36,0xf5, +0x29,0x89,0x35,0x74,0x3b,0x0b,0x44,0x32,0x2c,0x4e,0x42,0xae,0x1d,0x92,0x31,0xaa, +0x9c,0x31,0x10,0xdb,0x32,0xaa,0x22,0x11,0x27,0x2b,0x28,0x92,0x2f,0x6d,0x28,0x6f, +0x0f,0x70,0x20,0x8d,0x2f,0x32,0x28,0xca,0x0e,0xf5,0x21,0x48,0x0e,0x57,0x29,0xe6, +0x35,0xb8,0x2a,0x85,0x34,0xd9,0x33,0x65,0x9c,0x31,0x10,0xce,0x32,0xaa,0x11,0x11, +0x2c,0x1a,0x34,0x45,0x0b,0x39,0x35,0x05,0x32,0x78,0x2d,0xc6,0x31,0xb7,0x0e,0x68, +0x09,0x35,0x0e,0xea,0x28,0xd3,0x2f,0x2d,0x28,0x90,0x07,0x4f,0x20,0xad,0x2f,0x12, +0x9c,0x31,0x10,0xd8,0x33,0xaa,0x21,0x21,0x20,0xeb,0x2e,0xd4,0x29,0x49,0x0e,0x36, +0x29,0xe7,0x35,0x98,0x2a,0xa6,0x2c,0xd9,0x33,0x85,0x2b,0xf9,0x4c,0x45,0x2b,0x39, +0x2d,0x26,0x2a,0x78,0x2d,0xc7,0x21,0xd6,0x9c,0x31,0x10,0x84,0x32,0xaa,0x11,0x21, +0x2e,0x69,0x21,0x54,0x06,0xcb,0x28,0xf2,0x27,0x0d,0x08,0xd0,0x2f,0x0f,0x20,0xcd, +0x2e,0xf2,0x21,0x0b,0x2e,0xb4,0x29,0x69,0x2e,0x36,0x29,0xe7,0x4d,0x97,0x32,0x86, +0x9c,0x31,0x10,0xce,0x32,0xaa,0x11,0x11,0x2c,0xf8,0x33,0x46,0x2c,0x39,0x34,0x05, +0x23,0x78,0x2c,0xa6,0x2a,0xd8,0x0d,0x67,0x0a,0x37,0x2d,0xe8,0x29,0xb5,0x0e,0x69, +0x29,0x54,0x2e,0xab,0x21,0x12,0x2e,0xed,0x9c,0x31,0x10,0x45,0x32,0xaa,0x21,0x21, +0x28,0xf0,0x2f,0x0f,0x28,0xed,0x2e,0xf2,0x29,0x0b,0x36,0xb4,0x29,0x69,0x2e,0x56, +0x31,0xe7,0x2d,0xb7,0x2a,0x86,0x34,0xf8,0x2b,0x45,0x24,0x39,0x2c,0x25,0x23,0x59, +0x9c,0x31,0x10,0x84,0x32,0xaa,0x11,0x21,0x24,0xe6,0x4a,0x98,0x25,0xa7,0x21,0xd7, +0x2e,0x48,0x21,0x55,0x2e,0xca,0x30,0xf3,0x4f,0x0d,0x30,0xd0,0x0f,0x0f,0x48,0xce, +0x17,0x11,0x00,0xeb,0x2e,0xb4,0x29,0x49,0x9c,0x31,0x10,0xce,0x32,0xaa,0x11,0x11, +0x2e,0x36,0x09,0xe8,0x25,0xb7,0x2a,0x86,0x24,0xf8,0x4b,0x46,0x24,0x39,0x2b,0xe5, +0x2b,0x99,0x4c,0xa6,0x0a,0xd8,0x2d,0x67,0x0a,0x37,0x2d,0xe8,0x09,0xb5,0x0e,0x69, +0x9c,0x31,0x10,0xa0,0x31,0xaa,0x12,0x11,0x12,0xa8,0x3d,0x58,0x12,0x24,0x2d,0xdc, +0x31,0xe0,0x4d,0xe0,0x42,0x1b,0x3d,0xa5,0x32,0x57,0x2c,0xe9,0x33,0x14,0x2c,0x2c, +0x34,0x11,0x2b,0x2f,0x45,0x0e,0x49,0xf1,0x9c,0x31,0x10,0xb5,0x31,0xaa,0x21,0x11, +0x46,0x4d,0x48,0xb2,0x37,0x8c,0x37,0x72,0x48,0xcd,0x26,0x71,0x4a,0x0e,0x25,0x2f, +0x4b,0x10,0x44,0x2d,0x3c,0x12,0x33,0x6a,0x4c,0x96,0x32,0xe7,0x4d,0x19,0x32,0x63, +0x9c,0x31,0x10,0xa0,0x31,0xaa,0x12,0x11,0x3d,0x5d,0x22,0x5f,0x3d,0x61,0x32,0x5b, +0x4d,0x24,0x32,0xd8,0x3c,0xa8,0x23,0x55,0x3b,0xeb,0x34,0x12,0x3b,0x2d,0x35,0x10, +0x2a,0x2f,0x46,0x0f,0x29,0x30,0x37,0x0e,0x9c,0x31,0x10,0x1a,0x32,0xaa,0x12,0x11, +0x2c,0x18,0x2c,0x07,0x2b,0x97,0x2c,0x87,0x2b,0x17,0x2d,0x07,0x2a,0x96,0x2d,0x68, +0x2a,0x35,0x2d,0xea,0x21,0xd4,0x0e,0x2b,0x21,0x92,0x2e,0x4d,0x29,0x71,0x2e,0x6e, +0x9c,0x31,0x10,0xb1,0x30,0xa9,0x12,0x11,0x25,0xbc,0x39,0xc5,0x25,0xb1,0x19,0x52, +0x06,0xa1,0x38,0x5c,0x27,0x99,0x17,0x69,0x29,0x0d,0x35,0x70,0x2a,0x85,0x33,0xf5, +0x2c,0x81,0x31,0xf8,0x2e,0x81,0x2f,0x79,0x9c,0x31,0x10,0x2c,0x31,0xa9,0x12,0x11, +0x11,0x01,0x2d,0x78,0x33,0x05,0x2b,0xf6,0x34,0x89,0x29,0xed,0x36,0x11,0x08,0x61, +0x37,0x9d,0x27,0x55,0x38,0xa9,0x26,0xc9,0x38,0xb5,0x26,0x3d,0x38,0xc5,0x26,0xb1, +0x9c,0x31,0x10,0xe5,0x31,0xa9,0x11,0x10,0x3c,0x54,0x33,0xc9,0x2b,0xd7,0x24,0x66, +0x3b,0x39,0x25,0x24,0x3a,0x5b,0x36,0x02,0x29,0x5c,0x17,0x01,0x38,0x5d,0x38,0x01, +0x37,0x3d,0x39,0x22,0x26,0x3c,0x3a,0x03,0x9c,0x31,0x10,0xdc,0x32,0xa9,0x12,0x21, +0x22,0xba,0x2d,0x65,0x22,0x58,0x2d,0xa8,0x2a,0x15,0x25,0xea,0x29,0xd2,0x2e,0x0e, +0x29,0xcf,0x26,0x11,0x21,0xec,0x2d,0xf4,0x22,0x09,0x2d,0xb7,0x2a,0x66,0x25,0x59, +0x9c,0x31,0x10,0x39,0x31,0xa9,0x21,0x11,0x2b,0x11,0x33,0x69,0x2d,0x0d,0x31,0x6d, +0x2f,0x0a,0x2f,0x70,0x31,0x0d,0x2d,0x6d,0x33,0x11,0x2b,0x65,0x34,0x95,0x29,0xdd, +0x36,0x21,0x28,0xd5,0x37,0x2d,0x27,0xc9,0x9c,0x31,0x10,0xe5,0x31,0xa9,0x11,0x10, +0x3c,0x0e,0x33,0xcf,0x3c,0x11,0x33,0xec,0x2b,0xd4,0x34,0x29,0x2b,0x57,0x34,0xc6, +0x3a,0xb9,0x35,0x84,0x39,0xfb,0x26,0x43,0x39,0x1c,0x27,0x42,0x38,0x1c,0x38,0x42, +0x9c,0x31,0x10,0x96,0x32,0xa9,0x12,0x11,0x2b,0x9c,0x0c,0x82,0x2b,0x1b,0x2d,0x04, +0x2a,0x9a,0x2d,0x65,0x2a,0x57,0x2d,0xa8,0x22,0x15,0x2d,0xeb,0x21,0xf2,0x2d,0xee, +0x29,0xef,0x25,0xf1,0x29,0xec,0x2d,0xd4,0x9c,0x31,0x10,0xbe,0x32,0x99,0x12,0x11, +0x34,0x29,0x33,0x97,0x30,0x86,0x37,0x39,0x30,0xe5,0x36,0xda,0x45,0x43,0x32,0x5b, +0x35,0xc3,0x25,0xdb,0x36,0x43,0x39,0x5b,0x26,0xa4,0x34,0xf9,0x3b,0x26,0x34,0x97, +0x9c,0x31,0x10,0x11,0x31,0x99,0x21,0x11,0x3d,0xa1,0x31,0x55,0x3e,0xa9,0x20,0xc9, +0x4f,0x35,0x20,0x3d,0x4f,0x41,0x30,0xb1,0x3e,0xcd,0x31,0x29,0x4d,0xd5,0x42,0x1d, +0x3c,0x61,0x43,0x9a,0x3a,0xe5,0x35,0x11,0x9c,0x31,0x10,0xd0,0x31,0x99,0x11,0x11, +0x36,0x5a,0x35,0xc4,0x45,0xfa,0x4a,0x24,0x35,0x7a,0x3a,0x85,0x35,0x19,0x36,0xe6, +0x38,0xd7,0x37,0x28,0x34,0x95,0x27,0x6a,0x30,0x73,0x37,0x8c,0x30,0x50,0x37,0x8f, +0x9c,0x31,0x10,0x11,0x31,0x99,0x21,0x11,0x41,0x39,0x2e,0x45,0x41,0xb1,0x2d,0xcd, +0x22,0x29,0x2c,0xd5,0x33,0x21,0x3b,0xdd,0x24,0x19,0x2a,0x61,0x25,0x99,0x39,0x65, +0x27,0x15,0x37,0xe4,0x38,0x95,0x36,0x65,0x9c,0x31,0x10,0xd0,0x31,0x99,0x11,0x11, +0x32,0x66,0x25,0x58,0x36,0xc7,0x24,0xf7,0x46,0xe8,0x34,0xd5,0x33,0x2a,0x34,0xb3, +0x47,0x4c,0x48,0x91,0x47,0x4e,0x34,0x8f,0x47,0x50,0x34,0x8d,0x37,0x52,0x34,0xac, +0x9c,0x31,0x10,0x00,0x31,0x99,0x11,0x00,0x47,0x33,0x34,0xca,0x46,0xf5,0x45,0x09, +0x46,0xb6,0x35,0x27,0x46,0x97,0x35,0x87,0x46,0x37,0x35,0xc6,0x45,0xf8,0x46,0x06, +0x35,0xb7,0x3a,0x47,0x45,0x77,0x46,0x88,0x9c,0x31,0x10,0x6b,0x30,0x98,0x01,0x10, +0x25,0x3c,0x2b,0x04,0x44,0x77,0x2b,0xca,0x33,0xb2,0x3c,0x4f,0x33,0x6c,0x3c,0x95, +0x43,0x26,0x4c,0xdc,0x53,0x1f,0x4c,0xa2,0x43,0x19,0x4c,0x68,0x43,0x53,0x4c,0x2d, +0x9c,0x31,0x10,0x0a,0x30,0x88,0x11,0x00,0x30,0x0e,0x3f,0x33,0x41,0x4a,0x4d,0xb6, +0x22,0xc6,0x4c,0x3a,0x44,0x43,0x4a,0x7c,0x36,0x42,0x48,0xbd,0x48,0x02,0x36,0xfc, +0x59,0xc3,0x34,0xfa,0x3b,0x85,0x43,0x78,0x9c,0x31,0x10,0xc2,0x30,0x98,0x11,0x11, +0x4a,0x48,0x34,0xf4,0x3b,0x0c,0x34,0x6f,0x3b,0x91,0x33,0xea,0x2b,0xd6,0x43,0xe5, +0x2b,0xdc,0x33,0x9f,0x3b,0xe2,0x43,0xd9,0x4b,0xa7,0x44,0x14,0x4b,0x6c,0x34,0x8f, +0x9c,0x31,0x10,0x47,0x31,0x88,0x11,0x11,0x33,0x58,0x34,0xa5,0x46,0xf9,0x45,0x04, +0x36,0x9a,0x31,0x63,0x42,0x3b,0x41,0xc3,0x35,0xdb,0x4a,0x23,0x45,0x9b,0x46,0x64, +0x45,0x5a,0x46,0xa4,0x41,0x19,0x46,0xc5,0x9c,0x31,0x10,0x46,0x30,0x88,0x10,0x00, +0x43,0xf2,0x4c,0x0d,0x43,0x70,0x4c,0x8f,0x32,0xee,0x3d,0x11,0x32,0x6c,0x3d,0x93, +0x31,0xe9,0x3e,0x16,0x41,0x67,0x3e,0x99,0x30,0xe3,0x3f,0x1c,0x40,0xa0,0x4f,0x61, +0x9c,0x31,0x10,0xaf,0x21,0x88,0x11,0x01,0x14,0x0d,0x17,0xb2,0x04,0x2b,0x03,0x94, +0x04,0x49,0x17,0x76,0x24,0xa7,0x07,0x18,0x00,0xe5,0x12,0xd9,0x11,0x44,0x06,0x5a, +0x19,0xa4,0x09,0xfa,0x16,0x04,0x05,0x9a,0x9c,0x31,0x10,0x0a,0x30,0x88,0x11,0x00, +0x4a,0x09,0x44,0xf4,0x3b,0x8c,0x43,0xb1,0x4c,0xcf,0x52,0xad,0x4d,0x93,0x41,0xe9, +0x4e,0x58,0x41,0x64,0x4e,0x9d,0x41,0x5f,0x4e,0x62,0x41,0x9a,0x3d,0xe6,0x42,0x16, +0x9c,0x31,0x10,0x84,0x32,0x88,0x01,0x01,0x47,0x35,0x44,0xc8,0x46,0xf6,0x35,0x07, +0x46,0xb8,0x45,0x66,0x36,0x58,0x39,0xa5,0x45,0xf9,0x42,0x06,0x45,0x98,0x46,0x66, +0x35,0x57,0x46,0xc7,0x44,0xf6,0x43,0x09,0x9c,0x31,0x10,0xc1,0x31,0x87,0x11,0x11, +0x44,0xcc,0x37,0x43,0x34,0x9a,0x47,0x55,0x44,0x98,0x47,0x67,0x44,0x96,0x47,0x49, +0x44,0xb4,0x43,0x2b,0x44,0xe2,0x46,0xfc,0x41,0x11,0x32,0xae,0x41,0x60,0x46,0x6e, +0x9c,0x31,0x10,0x3e,0x31,0x88,0x01,0x01,0x35,0xa7,0x46,0x17,0x45,0xe7,0x35,0xb7, +0x46,0x47,0x39,0x76,0x46,0x88,0x45,0x35,0x46,0xc9,0x44,0xf4,0x4a,0xeb,0x44,0xd2, +0x57,0x0c,0x44,0xd1,0x47,0x0e,0x34,0xcf,0x9c,0x31,0x10,0xf5,0x30,0x87,0x01,0x10, +0x4e,0x51,0x49,0xac,0x56,0x14,0x39,0xe9,0x45,0xd7,0x42,0x26,0x3d,0x79,0x42,0xa4, +0x45,0x1b,0x4b,0x02,0x54,0x9c,0x43,0x82,0x44,0x1c,0x44,0x02,0x4b,0x9c,0x4c,0x62, +0x9c,0x31,0x10,0x7d,0x30,0x77,0x01,0x10,0x44,0xed,0x3b,0x8e,0x43,0x69,0x3d,0x15, +0x41,0xe1,0x4e,0x1d,0x40,0xd6,0x4e,0xa9,0x40,0x4d,0x4f,0x31,0x30,0x40,0x3f,0x3d, +0x30,0x39,0x3e,0xc9,0x40,0xad,0x3e,0x51,0x9c,0x31,0x10,0x31,0x30,0x77,0x00,0x10, +0x41,0xa4,0x3d,0xd9,0x42,0x9d,0x4c,0x61,0x33,0x95,0x3b,0x65,0x35,0x11,0x39,0xe9, +0x46,0x11,0x48,0x69,0x37,0x92,0x36,0xe9,0x49,0x11,0x45,0xe5,0x4a,0x15,0x44,0x61, +0x9c,0x31,0x10,0x58,0x20,0x77,0x01,0x10,0x0b,0x99,0x03,0x5e,0x1c,0x21,0x02,0xd6, +0x1d,0x29,0x12,0x51,0x1d,0xad,0x11,0xc8,0x0d,0xb5,0x01,0xc1,0x0d,0xbd,0x11,0xb9, +0x1d,0xc4,0x12,0x31,0x0d,0x4d,0x12,0xa9,0x9c,0x31,0x10,0xd9,0x20,0x77,0x00,0x00, +0x1e,0x55,0x11,0xc9,0x1d,0xf6,0x22,0x28,0x15,0x77,0x0a,0xa7,0x0c,0xf8,0x0b,0x26, +0x0c,0x58,0x03,0xc6,0x0b,0xd8,0x0c,0x46,0x13,0x38,0x1c,0xe7,0x12,0xb7,0x15,0x68, +0x9c,0x31,0x10,0x56,0x20,0x76,0x00,0x00,0x1a,0x5d,0x1d,0xc3,0x09,0xfa,0x0e,0x25, +0x19,0x97,0x2e,0x49,0x21,0x94,0x36,0x6c,0x11,0x91,0x1e,0x2f,0x11,0xce,0x05,0xb2, +0x02,0x6c,0x0d,0x33,0x13,0x0b,0x14,0x73,0x9c,0x31,0x10,0xc1,0x20,0x67,0x00,0x00, +0x13,0x8d,0x1b,0xb0,0x14,0xce,0x02,0xaf,0x1d,0x90,0x12,0x0d,0x1d,0xf2,0x11,0xeb, +0x1d,0xd3,0x12,0x6a,0x2d,0x15,0x23,0x28,0x24,0x16,0x1c,0x67,0x1a,0xd7,0x1d,0xa7, +0x9c,0x31,0x10,0x95,0x20,0x77,0x01,0x00,0x05,0x5c,0x0a,0x9d,0x04,0x59,0x1b,0xa1, +0x13,0x55,0x1c,0x29,0x12,0xcd,0x1c,0xad,0x22,0xc9,0x1d,0x34,0x22,0x41,0x2d,0x3d, +0x12,0x39,0x1c,0xc5,0x12,0xb4,0x1c,0xc9,0x9c,0x31,0x10,0xd9,0x20,0x77,0x00,0x00, +0x11,0x8b,0x0e,0x34,0x11,0xea,0x15,0xd5,0x12,0x49,0x1d,0x56,0x1a,0xc8,0x1c,0xd6, +0x1b,0x47,0x24,0x57,0x13,0xc7,0x0b,0xd7,0x14,0x47,0x2b,0x57,0x24,0xc8,0x32,0xf6, +0x9c,0x31,0x10,0x1a,0x20,0x76,0x01,0x00,0x2a,0x08,0x24,0xed,0x2b,0x11,0x14,0x65, +0x0b,0x99,0x13,0xd8,0x1b,0xa4,0x23,0x4d,0x1c,0x35,0x23,0x41,0x1c,0x41,0x23,0x35, +0x0b,0xcd,0x13,0xa9,0x2b,0xd5,0x14,0x1d,0x9c,0x31,0x10,0x02,0x20,0x66,0x01,0x00, +0x3e,0x61,0x32,0x15,0x4c,0xe8,0x33,0x8d,0x2b,0x6e,0x25,0x09,0x39,0x71,0x37,0x09, +0x27,0x71,0x39,0x09,0x25,0xf1,0x2a,0x8d,0x23,0xe9,0x2c,0x11,0x12,0x65,0x1d,0x99, +0x9c,0x31,0x10,0x4e,0x20,0x66,0x00,0x00,0x30,0xb6,0x1f,0x69,0x28,0x34,0x4f,0xcc, +0x38,0x11,0x3f,0xcf,0x38,0x0e,0x3f,0xd1,0x18,0x4b,0x2f,0x74,0x28,0xa9,0x26,0xf7, +0x09,0x47,0x1e,0x38,0x22,0x05,0x2d,0x7a,0x9c,0x31,0x10,0x83,0x20,0x66,0x00,0x10, +0x25,0x91,0x39,0x69,0x37,0x11,0x37,0x69,0x29,0x10,0x35,0xe9,0x3a,0x95,0x24,0x65, +0x2c,0x19,0x32,0xdd,0x3d,0x21,0x21,0xd5,0x3e,0x2d,0x31,0x48,0x2e,0xb5,0x20,0xc1, +0x9c,0x31,0x10,0x4e,0x20,0x66,0x00,0x00,0x1f,0x70,0x30,0x8d,0x2f,0x32,0x30,0xca, +0x36,0xd5,0x21,0x48,0x36,0x37,0x39,0xe7,0x45,0x98,0x4a,0xa6,0x44,0xd9,0x33,0x65, +0x1c,0x19,0x3c,0x45,0x3b,0x59,0x1d,0x05,0x9c,0x31,0x10,0x4e,0x20,0x66,0x00,0x00, +0x22,0x98,0x35,0xa6,0x31,0xf7,0x36,0x28,0x29,0x75,0x26,0xaa,0x31,0x13,0x46,0xec, +0x28,0xd1,0x17,0x0e,0x20,0xcf,0x2f,0x10,0x28,0xed,0x2e,0xd2,0x29,0x2b,0x36,0x74, +0x9c,0x31,0x10,0x02,0x20,0x66,0x01,0x00,0x33,0x25,0x3b,0xd9,0x44,0x1e,0x2a,0xdd, +0x05,0x1d,0x19,0xe1,0x26,0x99,0x28,0x61,0x37,0x99,0x27,0x61,0x19,0x19,0x15,0xe1, +0x1a,0x1d,0x24,0xdd,0x2b,0x21,0x33,0xd9,0x9c,0x31,0x10,0xc2,0x20,0x65,0x00,0x00, +0x3e,0x03,0x39,0xb9,0x2e,0x46,0x29,0x76,0x36,0x8a,0x31,0x32,0x46,0xae,0x31,0x2f, +0x46,0xb1,0x41,0x4b,0x36,0x95,0x41,0x67,0x36,0x38,0x41,0xc4,0x45,0xfb,0x4a,0x22, +0x9c,0x31,0x10,0x2a,0x20,0x56,0x01,0x00,0x3e,0xd9,0x41,0x21,0x4d,0xdd,0x4a,0x1d, +0x44,0xde,0x3b,0x1e,0x33,0xdd,0x3c,0x1d,0x3a,0xde,0x3d,0x21,0x32,0x59,0x3d,0xa5, +0x39,0xd1,0x35,0xa9,0x31,0xcd,0x3d,0xb1,0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00, +0x35,0x14,0x2e,0x8c,0x2d,0x72,0x2e,0x0d,0x2e,0x11,0x25,0x8e,0x2a,0x91,0x29,0x0c, +0x33,0x12,0x3c,0x8b,0x4b,0x95,0x40,0x48,0x27,0x98,0x1c,0x45,0x2b,0x9b,0x34,0x62, +0x9c,0x31,0x10,0x83,0x20,0x66,0x00,0x10,0x2a,0x59,0x35,0x9e,0x29,0x5d,0x26,0x9d, +0x18,0x5c,0x27,0x9d,0x37,0x5c,0x39,0x1d,0x36,0x5d,0x49,0xa1,0x35,0x59,0x2a,0xa1, +0x34,0x55,0x3b,0x29,0x43,0xd1,0x3c,0x2d,0x9c,0x31,0x10,0xc2,0x20,0x65,0x00,0x00, +0x39,0x95,0x4e,0x4a,0x31,0x72,0x46,0x6e,0x41,0x6f,0x46,0x71,0x41,0x8c,0x4e,0x54, +0x41,0xa9,0x46,0x17,0x41,0xe6,0x55,0xd9,0x42,0x44,0x45,0x7b,0x3a,0xa2,0x3c,0xfd, +0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00,0x39,0x00,0x42,0x9e,0x39,0x80,0x42,0x1e, +0x3d,0xe0,0x45,0xbe,0x42,0x60,0x39,0x3d,0x36,0xc1,0x30,0xdc,0x33,0x43,0x30,0x7a, +0x2f,0x65,0x2c,0x58,0x27,0xa7,0x28,0x16,0x9c,0x31,0x10,0xc2,0x20,0x65,0x00,0x00, +0x25,0xe9,0x31,0xf3,0x26,0x0c,0x31,0xd1,0x36,0x0e,0x31,0xce,0x36,0x11,0x29,0xeb, +0x35,0xf4,0x32,0x09,0x35,0xb6,0x32,0x27,0x35,0x78,0x3a,0x85,0x35,0x3a,0x3a,0xc4, +0x9c,0x31,0x10,0xa6,0x20,0x55,0x01,0x00,0x35,0xb6,0x2a,0x46,0x34,0xf6,0x2b,0x06, +0x2c,0x36,0x2c,0x06,0x3b,0x76,0x34,0xc5,0x42,0xb5,0x3d,0x85,0x39,0xf1,0x46,0x49, +0x39,0x31,0x3e,0xcd,0x30,0xa9,0x47,0x11,0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00, +0x44,0x34,0x3f,0xcb,0x48,0x12,0x4b,0xce,0x50,0x0f,0x43,0xd0,0x44,0x0d,0x43,0xb2, +0x38,0x2a,0x47,0x95,0x4c,0x69,0x43,0x57,0x34,0xa6,0x3a,0xf9,0x39,0x05,0x42,0x9a, +0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00,0x41,0x64,0x42,0x5a,0x35,0xc4,0x39,0xfb, +0x4a,0x24,0x25,0x9a,0x3a,0x85,0x39,0x39,0x36,0xc6,0x3c,0xf7,0x3f,0x27,0x38,0xb6, +0x4f,0x69,0x48,0x74,0x43,0x8b,0x40,0x51,0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00, +0x47,0x8e,0x48,0x4f,0x43,0x90,0x38,0x4d,0x4b,0x92,0x48,0x6b,0x3f,0x54,0x4c,0xa9, +0x4b,0x16,0x40,0xe7,0x42,0xd7,0x45,0x26,0x3a,0x79,0x35,0x85,0x3e,0x19,0x41,0xe5, +0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00,0x41,0xb9,0x3e,0x45,0x45,0x78,0x46,0xa6, +0x4d,0x17,0x42,0xe8,0x44,0xd6,0x43,0x29,0x44,0xb4,0x43,0x4c,0x50,0x71,0x4f,0x4e, +0x48,0x8f,0x4f,0x50,0x44,0x8e,0x3f,0x51,0x9c,0x31,0x10,0xea,0x20,0x55,0x00,0x00, +0x44,0xac,0x47,0x14,0x38,0xc9,0x4e,0xf5,0x4d,0x08,0x4a,0xb6,0x4d,0x47,0x52,0x77, +0x4d,0xa7,0x56,0x18,0x51,0xe6,0x4d,0xd8,0x52,0x27,0x45,0x97,0x42,0x67,0x39,0x56, +0x9c,0x31,0x10,0x65,0x20,0x54,0x00,0x00,0x42,0xa2,0x4d,0x1b,0x4e,0xe5,0x48,0xd8, +0x4b,0x08,0x54,0xd5,0x53,0x2b,0x4c,0xb2,0x4f,0x2e,0x48,0xce,0x4e,0xf2,0x3c,0xeb, +0x4a,0xb4,0x49,0x49,0x46,0x76,0x45,0xa8,0x9c,0x31,0x10,0x7d,0x20,0x44,0x00,0x00, +0x46,0x36,0x3e,0x08,0x3d,0x75,0x46,0xca,0x44,0xd2,0x3f,0x2e,0x48,0x6e,0x4f,0x72, +0x48,0x4a,0x4b,0x96,0x48,0x66,0x4f,0x39,0x50,0xe3,0x4e,0xbd,0x4d,0x60,0x4e,0x1e, +0x9c,0x31,0x10,0x85,0x10,0x55,0x00,0x00,0x0c,0x07,0x1b,0x76,0x2c,0xe8,0x2a,0xb6, +0x1d,0x48,0x22,0x55,0x1d,0xc9,0x11,0xf4,0x16,0x2b,0x19,0x92,0x06,0x4d,0x11,0x90, +0x2e,0x6f,0x19,0x8f,0x26,0x50,0x39,0x8d,0x9c,0x31,0x10,0x0a,0x10,0x54,0x00,0x00, +0x26,0x35,0x39,0xe7,0x2d,0xd8,0x2a,0x25,0x45,0x7a,0x1a,0x83,0x0d,0x1c,0x0b,0x02, +0x0c,0xbd,0x2b,0x81,0x34,0x1d,0x24,0x00,0x2b,0x9d,0x34,0x81,0x2b,0x3c,0x34,0xe2, +0x9c,0x31,0x10,0x65,0x20,0x54,0x00,0x00,0x55,0x5b,0x4e,0xa4,0x49,0x39,0x4e,0xc6, +0x51,0x16,0x46,0xe9,0x40,0xf4,0x42,0xec,0x48,0xf1,0x4a,0xef,0x38,0xee,0x42,0xf2, +0x48,0xeb,0x4a,0xd4,0x55,0x09,0x52,0xb6,0x9c,0x31,0x10,0x12,0x10,0x44,0x00,0x00, +0x20,0xe7,0x26,0x98,0x21,0x85,0x26,0x19,0x1a,0x24,0x1d,0x5a,0x1a,0xe4,0x0c,0x9b, +0x13,0xa3,0x1b,0xdb,0x24,0x43,0x23,0x3b,0x2d,0x03,0x12,0x7a,0x2d,0xa5,0x29,0xf8, +0x9c,0x31,0x10,0x12,0x10,0x44,0x00,0x00,0x36,0x26,0x41,0x77,0x36,0x88,0x31,0x15, +0x36,0xea,0x28,0xd3,0x2f,0x2c,0x18,0xb1,0x27,0x4e,0x10,0x8f,0x17,0x30,0x08,0xad, +0x27,0x12,0x20,0xeb,0x26,0xd4,0x19,0x29,0x9c,0x31,0x10,0x12,0x10,0x44,0x00,0x00, +0x2e,0x95,0x09,0x88,0x1e,0x16,0x11,0xe7,0x1d,0x97,0x1a,0x66,0x25,0x18,0x33,0x06, +0x3c,0x99,0x33,0x65,0x2c,0x39,0x2c,0x05,0x33,0x99,0x34,0x86,0x2b,0x18,0x35,0x07, +0x9c,0x31,0x10,0x12,0x10,0x44,0x00,0x00,0x2a,0x97,0x35,0x87,0x3a,0x36,0x2d,0xc8, +0x31,0xf5,0x2e,0x0a,0x31,0xb4,0x2e,0x6b,0x21,0x52,0x26,0x8d,0x19,0x50,0x2e,0x8e, +0x29,0x4f,0x2e,0x90,0x29,0x6d,0x26,0x52,0x9c,0x31,0x10,0x98,0x10,0x43,0x00,0x00, +0x31,0x88,0x26,0x17,0x21,0xc5,0x2d,0xda,0x22,0x23,0x25,0x9c,0x2a,0x81,0x25,0x3d, +0x1b,0x00,0x24,0x9e,0x23,0x80,0x24,0x1e,0x1c,0x00,0x23,0x9e,0x24,0x60,0x2b,0x3d, +0x9c,0x31,0x10,0x98,0x10,0x43,0x00,0x00,0x3c,0xc2,0x3a,0xdc,0x2d,0x23,0x22,0x7a, +0x35,0x86,0x2a,0x37,0x25,0xa8,0x2a,0x15,0x25,0xea,0x29,0xf2,0x1d,0xed,0x32,0x0f, +0x35,0xf0,0x3a,0x0d,0x35,0xd2,0x2a,0x2b,0x9c,0x31,0x10,0xd0,0x10,0x33,0x00,0x00, +0x2f,0x94,0x38,0x68,0x3b,0x57,0x2c,0xa6,0x2b,0x19,0x2d,0x05,0x32,0xba,0x21,0x64, +0x36,0x5b,0x35,0xc3,0x31,0xfb,0x3e,0x24,0x41,0x9a,0x52,0x65,0x4d,0x39,0x5a,0xe5, +0x9c,0x31,0x10,0xd0,0x10,0x33,0x00,0x00,0x4c,0xd7,0x5b,0x07,0x58,0xb6,0x4f,0x49, +0x50,0x94,0x3f,0x6b,0x30,0x72,0x33,0x8d,0x3c,0x50,0x3b,0x90,0x3c,0x4d,0x2f,0x92, +0x40,0x6b,0x33,0x74,0x34,0x89,0x43,0x55,0x9c,0x31,0x10,0xd0,0x10,0x33,0x00,0x00, +0x44,0xa8,0x4f,0x37,0x44,0xc6,0x4e,0xf9,0x4c,0xe5,0x52,0xda,0x49,0x24,0x56,0x9b, +0x45,0x43,0x3a,0x7c,0x35,0xa1,0x36,0x1d,0x35,0xe1,0x39,0xbd,0x4a,0x41,0x39,0x7d, +0x9c,0x31,0x10,0x98,0x10,0x43,0x00,0x00,0x3c,0xa2,0x43,0x1c,0x34,0xe2,0x32,0xdb, +0x3d,0x44,0x4a,0x79,0x35,0x86,0x42,0x57,0x4d,0x89,0x52,0x34,0x4d,0xca,0x49,0xf3, +0x45,0xec,0x51,0xf1,0x4d,0xef,0x42,0x0e,0x9c,0x31,0x10,0xd0,0x10,0x33,0x00,0x00, +0x4b,0xb1,0x50,0x2c,0x5b,0x93,0x48,0x6a,0x53,0x75,0x48,0x88,0x4f,0x57,0x4c,0xa6, +0x47,0x18,0x4d,0x05,0x36,0xb9,0x45,0x45,0x46,0x5a,0x41,0x84,0x46,0x1a,0x41,0xe4, +0x9c,0x31,0x10,0xd0,0x10,0x33,0x00,0x00,0x4d,0xba,0x46,0x44,0x51,0x79,0x46,0x85, +0x45,0x38,0x46,0xc6,0x44,0xf7,0x47,0x07,0x34,0xb6,0x3f,0x49,0x44,0x94,0x4f,0x4b, +0x44,0x72,0x47,0x6d,0x38,0x90,0x4b,0x6f,0x9c,0x31,0x10,0x7a,0x00,0x32,0x00,0x00, +0x08,0xb7,0x35,0xd0,0x0a,0xa9,0x34,0xda,0x0b,0xa0,0x30,0xe8,0x10,0x11,0x2e,0x71, +0x12,0x0c,0x2a,0xfc,0x17,0x86,0x26,0xfb,0x1a,0x00,0x22,0x7d,0x1f,0x03,0x1e,0xfb, +0x9c,0x31,0x10,0x7a,0x00,0x32,0x00,0x00,0x23,0x04,0x1b,0x79,0x27,0x08,0x16,0x74, +0x2a,0x8f,0x13,0x69,0x2d,0x1b,0x10,0xdf,0x2f,0x22,0x0f,0xd8,0x30,0xad,0x0e,0xcd, +0x30,0xba,0x0f,0xbf,0x70,0xc8,0x4f,0x33,0x9c,0x31,0x10,0x62,0x00,0x22,0x00,0x00, +0x3e,0xd2,0x03,0xa7,0x3a,0x5a,0x47,0x21,0x34,0xe2,0x4c,0x99,0x2f,0xe8,0x12,0x12, +0x2b,0x6c,0x1a,0x11,0x22,0xf2,0x20,0x12,0x1c,0xed,0x26,0x12,0x17,0x6c,0x2c,0x17, +0x9c,0x31,0x10,0x62,0x00,0x22,0x00,0x00,0x11,0x62,0x31,0x9e,0x0a,0x5f,0x35,0xa5, +0x09,0x56,0x38,0xac,0x07,0x4d,0x39,0x35,0x06,0xc2,0x38,0x42,0x07,0x39,0x36,0xc7, +0x09,0xb1,0x35,0xd1,0x0c,0x2a,0x2f,0xd8,0x9c,0x31,0x10,0x4a,0x00,0x12,0x00,0x00, +0x02,0x28,0x37,0xdb,0x0f,0x25,0x70,0xdc,0x13,0xa0,0x66,0xdd,0x5e,0x1f,0x1c,0xdd, +0x25,0xa1,0x17,0x5b,0x6c,0xa2,0x11,0x5a,0x30,0x25,0x09,0xd5,0x38,0x29,0x06,0x50, +0x9c,0x31,0x10,0xee,0x00,0x21,0x00,0x00,0x2f,0x52,0x50,0xeb,0x70,0x97,0x4e,0xa5, +0x31,0x9a,0x0d,0xa0,0x30,0x60,0x51,0x1b,0x2f,0x25,0x10,0xd6,0x2d,0x69,0x52,0xd1, +0x6a,0x6d,0x16,0x91,0x28,0xef,0x18,0xcc,0x9c,0x31,0x10,0xc6,0x00,0x11,0x00,0x00, +0x1a,0x72,0x15,0xce,0x19,0x70,0x16,0x8b,0x18,0x71,0x17,0x8c,0x56,0xf5,0x58,0xce, +0x56,0x31,0x1a,0x0f,0x15,0xb0,0x5a,0x90,0x54,0x6d,0x5b,0x13,0x54,0x2b,0x5c,0x95, +0x9c,0x31,0x10,0x49,0x00,0x10,0x00,0x00,0x49,0xa9,0x4e,0x61,0x49,0xb5,0x4e,0x25, +0x49,0xb5,0x4e,0x15,0x49,0x85,0x4e,0x45,0x49,0x85,0x2e,0x15,0x4a,0x05,0x4d,0xa9, +0x4a,0x21,0x4d,0x29,0x4a,0xd1,0x4d,0x19,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x50,0x55,0x1a,0x55,0x50,0x55,0x56,0x55,0x54,0x55,0x56,0x55,0x54,0x55,0x56,0x55, +0x54,0x55,0x56,0x55,0x58,0x55,0x52,0x55,0x58,0x55,0x56,0x55,0x58,0x55,0x51,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x59,0x55,0x51,0x55,0x59,0x55,0x51,0x55, +0x59,0x55,0x51,0x55,0x59,0x55,0x51,0x55,0x59,0x55,0x51,0x55,0x59,0x55,0x51,0x55, +0x59,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x55,0x56,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, diff --git a/config/_default_cfg_src_/res/en/SOUND_FIVE.txt b/config/_default_cfg_src_/res/en/SOUND_FIVE.txt new file mode 100644 index 0000000..e979930 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_FIVE.txt @@ -0,0 +1,165 @@ +0x9c,0x31,0x10,0xa6,0x54,0x23,0x10,0x00,0x7d,0xdb,0x7d,0xdb,0x79,0xdb,0x75,0xd3, +0x4d,0x9c,0x31,0xcb,0x3d,0xda,0x32,0x6c,0x3e,0x21,0x3d,0xd4,0x54,0xcb,0x60,0xda, +0x85,0xe3,0x71,0xc6,0x82,0x13,0x66,0x70,0x9c,0x31,0x10,0xf5,0x44,0x54,0x00,0x00, +0x23,0xba,0x54,0x43,0x7b,0x33,0x6b,0xb5,0x83,0xc2,0xe6,0x2b,0xe3,0x33,0xd4,0xcc, +0x85,0x43,0xd2,0xc2,0xd1,0xab,0x64,0x1a,0x1b,0x2b,0x6d,0x24,0x08,0xca,0x39,0xcb, +0x9c,0x31,0x10,0x5f,0x54,0x55,0x00,0x00,0x53,0xdb,0x95,0xcb,0x68,0xea,0x6d,0x23, +0x3e,0xe5,0x5b,0xb2,0x63,0xbb,0x5c,0xd3,0x65,0x42,0x6a,0x4c,0x4b,0x4b,0x62,0xc3, +0x95,0x52,0x95,0x13,0x9d,0x54,0x5a,0xb2,0x9c,0x31,0x10,0x53,0x45,0x55,0x10,0x00, +0x84,0x39,0x33,0xa4,0x79,0x84,0x4b,0x34,0x72,0x43,0x7c,0x34,0x0b,0x5b,0x72,0x4b, +0x4b,0x51,0x71,0x33,0x98,0xbc,0x54,0xac,0xac,0xac,0x84,0x33,0x0a,0xca,0x69,0xa3, +0x9c,0x31,0x10,0x02,0x54,0x65,0x20,0x00,0x48,0xc0,0x7c,0xd0,0x84,0xb0,0x54,0xed, +0x53,0x11,0x88,0xcd,0xab,0x0e,0x89,0x12,0xb7,0x66,0xa8,0xae,0x86,0xd2,0x9a,0xed, +0x89,0x25,0x84,0xcc,0x8c,0xcc,0x56,0xe8,0x9c,0x31,0x10,0xa9,0x56,0x66,0x20,0x00, +0x58,0x98,0x28,0x88,0x5a,0x29,0x69,0x78,0xc7,0x93,0xa6,0x87,0x86,0x77,0x99,0xb8, +0xb8,0x68,0xe7,0x55,0xb6,0x9a,0x53,0x76,0x48,0xa6,0x75,0x84,0x73,0x69,0x66,0x56, +0x9c,0x31,0x10,0xa9,0x56,0x66,0x20,0x00,0x27,0x67,0x48,0x67,0x56,0x75,0xb6,0x56, +0x69,0x98,0xb7,0x8a,0xa7,0x54,0x65,0x99,0x77,0x57,0x56,0x77,0x97,0xc8,0xb7,0x51, +0x74,0x4a,0xa5,0x89,0xa6,0x5a,0x43,0x53,0x9c,0x31,0x10,0xbf,0x55,0x76,0x30,0x00, +0x92,0x57,0x99,0x98,0xbd,0x78,0x6d,0x76,0x73,0x84,0x86,0x6a,0x83,0xaa,0x81,0x63, +0x8a,0x48,0xd3,0xc9,0xe5,0x56,0x6e,0xa0,0x3c,0x36,0xaa,0x8b,0xb8,0xa6,0xf5,0x6e, +0x9c,0x31,0x10,0xd0,0x98,0x88,0x30,0x00,0x7b,0xca,0x84,0x2b,0x7b,0x53,0x7b,0x33, +0x83,0xcb,0x83,0xbb,0x7b,0xab,0x7c,0x2b,0x7b,0x4a,0x8b,0x1b,0x9a,0x34,0xca,0x81, +0x66,0x9b,0x5b,0xbb,0x5b,0xac,0x6c,0x2a,0x9c,0x31,0x10,0xaf,0x87,0x87,0x20,0x00, +0x52,0x23,0x82,0x35,0x8c,0xb2,0x91,0xc2,0x86,0x43,0x99,0x44,0x99,0xda,0xad,0xbb, +0xbd,0xa4,0xba,0x3b,0xa1,0xc2,0x79,0xb3,0x82,0x3c,0x81,0xbb,0x79,0xb3,0x6d,0xb2, +0x9c,0x31,0x10,0x89,0x86,0x55,0x20,0x00,0x9e,0x0d,0xa6,0x9e,0x8d,0x04,0x91,0xf0, +0x4e,0x59,0x3a,0x95,0x31,0xec,0x31,0xe0,0x0d,0xd2,0x15,0xa3,0x0d,0xe5,0x10,0xdb, +0x38,0xa4,0x4e,0x30,0x75,0x23,0x4c,0xe6,0x9c,0x31,0x10,0x02,0xa6,0x55,0x10,0x00, +0x72,0xc9,0x78,0x80,0x76,0x84,0x81,0x82,0x84,0xaa,0x8c,0x85,0x8d,0x94,0x80,0x2d, +0x73,0x4d,0x74,0xcd,0x80,0x65,0x92,0xa9,0x9d,0xa9,0xa1,0x0e,0x65,0x31,0x32,0x51, +0x9c,0x31,0x10,0x78,0xca,0x57,0x30,0x00,0x68,0xf5,0x80,0xf5,0x96,0xf5,0xa5,0x05, +0x88,0xd5,0x55,0x25,0x40,0xc9,0x54,0xf9,0xb1,0x05,0xd4,0xd5,0xa9,0x15,0x62,0xc5, +0x3b,0x01,0x14,0xa1,0x93,0x74,0xc8,0xa4,0x9c,0x31,0x10,0xc2,0xc9,0x57,0x30,0x00, +0xca,0xec,0xba,0xe5,0x58,0xcc,0x21,0x2b,0x0e,0xd1,0xba,0x8b,0xb3,0x0c,0xcf,0x4b, +0xd0,0x4b,0x53,0x0b,0x15,0x73,0x12,0xd2,0xba,0x6c,0xa3,0x4c,0xd7,0x0c,0xd8,0xaa, +0x9c,0x31,0x10,0xeb,0xdb,0x57,0x40,0x00,0x6e,0xe1,0x4d,0x35,0x44,0xa9,0x91,0x11, +0x8f,0x02,0xaa,0xe5,0xae,0xf9,0x74,0xf8,0x51,0x34,0x3e,0x69,0x89,0x36,0x8f,0x05, +0xa6,0xe5,0xae,0xf6,0x81,0x05,0x57,0x00,0x9c,0x31,0x10,0x69,0xcb,0x66,0x40,0x00, +0x00,0x81,0x77,0x85,0x9c,0xb5,0xbf,0x04,0xe6,0xf5,0x92,0xf5,0x3a,0xe5,0x02,0xc0, +0x5d,0x95,0x9c,0x75,0xb5,0x25,0xec,0xf6,0xa2,0xf5,0x4c,0xc5,0x0d,0x25,0x3f,0x46, +0x9c,0x31,0x10,0x69,0xcb,0x66,0x40,0x00,0x9c,0x55,0xa3,0x54,0xe8,0xf4,0xb2,0xe5, +0x60,0xd6,0x15,0x5a,0x2a,0xf9,0x94,0x64,0x91,0x84,0xe4,0xb5,0xc7,0x09,0x7c,0xe5, +0x2f,0x44,0x06,0x59,0x7d,0x35,0x7d,0x25,0x9c,0x31,0x10,0x4c,0xdb,0x66,0x40,0x00, +0xb4,0xb6,0xab,0x16,0x90,0xe5,0x5d,0x15,0x3e,0x50,0x69,0xd4,0x7a,0x95,0xa9,0x06, +0xb2,0xf5,0xa1,0x05,0x68,0xd4,0x42,0xe4,0x53,0xc6,0x76,0x06,0x9b,0x76,0xba,0xd5, +0x9c,0x31,0x10,0x54,0xdb,0x76,0x40,0x00,0xad,0x05,0x78,0xe5,0x4d,0x55,0x3a,0xb8, +0x76,0x85,0x83,0x94,0xbe,0x95,0xb1,0x15,0x90,0xe5,0x59,0x12,0x32,0x62,0x67,0x85, +0x78,0xe5,0xb4,0xb4,0xb9,0x24,0xa0,0xd4,0x9c,0x31,0x10,0x4c,0xdb,0x66,0x40,0x00, +0x6a,0xf0,0x38,0xb5,0x4f,0xe6,0x72,0x05,0x9f,0x76,0xba,0xd5,0xb0,0xe5,0x7d,0x08, +0x4d,0x24,0x30,0xb9,0x74,0xc6,0x7f,0x96,0xbc,0x62,0xb7,0x52,0x98,0xc1,0x65,0x05, +0x9c,0x31,0x10,0x4c,0xdb,0x66,0x40,0x00,0x30,0xa0,0x5b,0xb2,0x72,0x55,0xa7,0x35, +0xb9,0x08,0xae,0xd5,0x7d,0x15,0x4d,0x00,0x34,0xa6,0x72,0xe6,0x7f,0x86,0xba,0x65, +0xb3,0x41,0x9a,0xb4,0x66,0xf4,0x34,0xf9,0x9c,0x31,0x10,0x4c,0xdb,0x66,0x40,0x00, +0x57,0x96,0x72,0x19,0xa1,0x65,0xb4,0xe9,0xae,0xe4,0x85,0x35,0x54,0xc5,0x32,0xa1, +0x6f,0x75,0x79,0x05,0xb4,0x95,0xb1,0x54,0xa2,0xb5,0x77,0x29,0x41,0x15,0x42,0xb9, +0x9c,0x31,0x10,0x4c,0xdb,0x66,0x40,0x00,0x74,0x75,0x89,0xc6,0xb6,0x66,0xb1,0x32, +0x96,0xe5,0x6a,0xd5,0x37,0x29,0x59,0x59,0x74,0x28,0x9b,0x65,0xb2,0xf5,0xaa,0xc1, +0x91,0x04,0x5e,0xe5,0x39,0x05,0x65,0x76,0x9c,0x31,0x10,0xeb,0xdb,0x57,0x40,0x00, +0x74,0x5a,0xa5,0x2a,0xaf,0x15,0xa4,0xc1,0x8f,0x10,0x56,0xd4,0x3c,0xe4,0x6b,0x92, +0x76,0x7a,0xa4,0xf9,0xad,0x25,0xa2,0xd5,0x8a,0xf1,0x56,0xe5,0x3f,0x05,0x6d,0x75, +0x9c,0x31,0x10,0x5a,0xcb,0x76,0x30,0x00,0x6e,0x96,0xcc,0xf6,0xd7,0x26,0xbe,0xb5, +0x9f,0x14,0x32,0xe4,0x05,0x19,0x4f,0x56,0x72,0x45,0xbf,0x45,0xd5,0x04,0xc0,0xc5, +0xa5,0x36,0x4c,0xe5,0x0b,0x19,0x3e,0xf8,0x9c,0x31,0x10,0x6a,0xcb,0x56,0x30,0x00, +0x74,0x68,0xa5,0x75,0xd6,0xc6,0xc0,0xfa,0xa9,0x1a,0x6a,0xd9,0x15,0x01,0x28,0xa2, +0x73,0x05,0x85,0x50,0xd4,0x94,0xc3,0x31,0xaa,0xe5,0x90,0xe5,0x2d,0x05,0x14,0xe9, +0x9c,0x31,0x10,0x6a,0xcb,0x56,0x30,0x00,0x5f,0x66,0x74,0x99,0xbc,0xf5,0xc5,0x19, +0xb8,0xd9,0xa9,0x25,0x58,0xe9,0x1d,0x11,0x2c,0xa6,0x76,0xc2,0x89,0x70,0xca,0x94, +0xbf,0x11,0xae,0xf1,0x96,0xf5,0x39,0x09,0x9c,0x31,0x10,0xc5,0xcb,0x76,0x50,0x00, +0x1d,0x0a,0x47,0x45,0x78,0x34,0xa3,0x64,0xc6,0xe5,0xc0,0xf5,0xaf,0x16,0x80,0xb6, +0x2f,0x06,0x1a,0xd5,0x59,0xa6,0x76,0x64,0xb1,0x04,0xc1,0x04,0xbc,0xf4,0xab,0x15, +0x9c,0x31,0x10,0xe6,0xcb,0x67,0x40,0x00,0x7a,0xa6,0x35,0x26,0x18,0xb5,0x5d,0xa6, +0x78,0x85,0xb0,0xf4,0xbe,0xf4,0xb9,0x04,0xaf,0x15,0x7e,0xa6,0x39,0x16,0x1c,0xe9, +0x51,0x99,0x7a,0x44,0xa1,0x24,0xbe,0xf5,0x9c,0x31,0x10,0xe6,0xcb,0x67,0x40,0x00, +0xb9,0x26,0xb0,0xc5,0x90,0xe5,0x41,0x24,0x29,0x14,0x2e,0xf9,0x86,0x46,0x85,0x75, +0xc8,0xf1,0xb3,0x05,0xb8,0xc5,0xa3,0x39,0x5d,0x05,0x38,0xe5,0x0e,0x70,0x7b,0x92, +0x9c,0x31,0x10,0x60,0xcb,0x68,0x40,0x00,0x71,0x0d,0xba,0xcb,0xb2,0xaa,0xb7,0x02, +0xad,0x0a,0x86,0xc3,0x4b,0x0b,0x25,0x03,0x2e,0xec,0x8a,0x4d,0x7b,0x42,0xc8,0xe9, +0xa9,0x0b,0xba,0xab,0xa5,0x0b,0x72,0xcb,0x9c,0x31,0x10,0xd5,0xcb,0x77,0x30,0x00, +0x47,0x06,0x12,0xd9,0x53,0x98,0x7e,0x48,0x8f,0x06,0xc4,0xc6,0xa9,0x55,0xb8,0xf4, +0x9d,0x05,0x6a,0xc5,0x49,0x06,0x0a,0xca,0x5d,0xa8,0x78,0x78,0x95,0x06,0xc2,0xb6, +0x9c,0x31,0x10,0x61,0xcb,0x77,0x20,0x00,0xa9,0x35,0xbb,0x05,0x9b,0x05,0x78,0xb5, +0x4a,0xd5,0x14,0xf5,0x4d,0x98,0x84,0x56,0x82,0xf5,0xc2,0xa5,0xa1,0x55,0xbb,0x05, +0xa6,0xe5,0x82,0xb5,0x5a,0xe5,0x21,0x12,0x9c,0x31,0x10,0xf2,0xca,0x88,0x20,0x00, +0x29,0xcb,0x8c,0x51,0x6e,0x53,0xc6,0x14,0x9e,0x9b,0xb1,0xda,0xa9,0x5c,0x89,0xdb, +0x71,0xda,0x3a,0x1b,0x15,0x2c,0x6b,0xa1,0x7d,0x22,0x96,0x65,0xb4,0xa3,0x9d,0xda, +0x9c,0x31,0x10,0xce,0xc9,0x87,0x20,0x00,0xb6,0xc9,0x9e,0xce,0x87,0x08,0x5e,0xe8, +0x27,0xaa,0x24,0x64,0x8d,0x0a,0x71,0x2a,0xb1,0xcc,0xaa,0xed,0xa7,0x32,0xb6,0xcc, +0x8d,0x51,0x86,0x92,0x48,0x6d,0x20,0x89,0x9c,0x31,0x10,0x3d,0xca,0x77,0x10,0x00, +0x3c,0xe2,0x8e,0x60,0x76,0xe1,0xba,0xf2,0xa5,0x10,0xab,0x31,0xb0,0xf1,0x8d,0x35, +0x83,0x05,0x44,0xe5,0x1c,0xf1,0x40,0xf6,0x8e,0x84,0x78,0xc6,0xb8,0xd2,0xa6,0xd0, +0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00,0xa3,0x49,0xb2,0xe9,0x8d,0x71,0x7f,0x18, +0x4e,0xfa,0x1e,0xd1,0x38,0xb1,0x94,0x54,0x76,0x2e,0xae,0xcc,0xb0,0x6d,0x9a,0xe9, +0xb2,0xc9,0x90,0xe9,0x7e,0xd1,0x5a,0x8d,0x9c,0x31,0x10,0x89,0xc9,0x88,0x10,0x00, +0x26,0xdb,0x26,0x4a,0x8c,0x94,0x80,0x4a,0x98,0xcb,0xc0,0x8c,0x9a,0xd2,0xae,0xdc, +0xa0,0x93,0x7e,0xdb,0x66,0x94,0x37,0x1a,0x16,0xa5,0x6b,0x89,0x94,0xd4,0x81,0x4c, +0x9c,0x31,0x10,0x4b,0xc8,0x97,0x20,0x00,0xbb,0x28,0xad,0x0a,0xa3,0x88,0xae,0xcd, +0x8a,0xc9,0x66,0xcc,0x43,0x2e,0x18,0xd0,0x45,0xb6,0xa0,0xb1,0x84,0xf1,0xa1,0x2e, +0xbe,0xec,0x9e,0xee,0xa7,0x09,0x9c,0xed,0x9c,0x31,0x10,0x92,0xc8,0x87,0x10,0x00, +0x75,0x0a,0x4c,0xac,0x2a,0xee,0x26,0x04,0x82,0xee,0x9c,0x4c,0x88,0xf2,0xb6,0xf1, +0xb4,0x91,0xa1,0x2d,0xa2,0xe9,0x8e,0xed,0x56,0x91,0x2d,0x2d,0x20,0xad,0x5b,0xa4, +0x9c,0x31,0x10,0xfa,0xc7,0x87,0x10,0x00,0xa2,0x8a,0x91,0x0d,0x9e,0xd5,0xbc,0x99, +0xad,0x21,0x9c,0x6d,0x96,0xdd,0x72,0xd9,0x3b,0x19,0x1f,0x5d,0x36,0xa5,0x90,0xb4, +0x9c,0xa6,0x91,0x20,0xaf,0x1a,0xb6,0xd5,0x9c,0x31,0x10,0x26,0xc8,0x87,0x00,0x00, +0xa5,0x09,0x94,0xcd,0x8c,0xec,0x5e,0xae,0x29,0x0c,0x1a,0x92,0x5f,0x60,0xa6,0xca, +0x91,0x09,0x90,0xcd,0xb4,0xcd,0xb6,0xd1,0x9e,0xcd,0x92,0xec,0x7e,0xed,0x46,0xed, +0x9c,0x31,0x10,0xdc,0xc8,0x86,0x20,0x00,0x1b,0x0d,0x2a,0xad,0x8c,0xd5,0xa8,0xb2, +0x8a,0xf0,0x9c,0xee,0xba,0xcc,0xb0,0xee,0x8e,0xcc,0x86,0xed,0x6e,0xcd,0x35,0x30, +0x12,0xf1,0x47,0x75,0xa8,0xe6,0xa5,0x08,0x9c,0x31,0x10,0x1a,0xc8,0x77,0x10,0x00, +0x88,0xe2,0xa4,0xe9,0xc2,0xf1,0xa6,0xd1,0x8b,0x11,0x85,0x05,0x60,0xe9,0x23,0x05, +0x12,0x45,0x6d,0x02,0xb6,0xb4,0x98,0xf2,0x86,0xf0,0xb0,0xf2,0xc2,0xe9,0x9c,0xd1, +0x9c,0x31,0x10,0x29,0xc6,0x86,0x20,0x00,0x7f,0x15,0x7f,0x1d,0x58,0xda,0x1b,0x5c, +0x1c,0x1d,0x88,0xb0,0xbe,0x66,0x92,0xdc,0x82,0xda,0xb2,0x98,0xc4,0x9d,0x92,0xa1, +0x74,0xdd,0x74,0x9c,0x4e,0xe2,0x15,0x1c,0x9c,0x31,0x10,0x75,0xc7,0x86,0x10,0x00, +0x2d,0x72,0x9c,0xd8,0xc0,0xdd,0x8e,0xd2,0x84,0xdc,0xb2,0xda,0xbe,0xdc,0x8c,0xde, +0x72,0xdc,0x70,0x9e,0x4b,0x1d,0x16,0xa5,0x37,0x9d,0xa4,0xd1,0xc2,0xd4,0x90,0xd9, +0x9c,0x31,0x10,0xc1,0xc7,0x86,0x00,0x00,0x82,0xdd,0xb1,0x21,0xc0,0xe5,0x8d,0x21, +0x6a,0xe0,0x64,0xde,0x4b,0x18,0x1c,0x5a,0x43,0x0c,0xa8,0x9a,0xc0,0xd5,0x90,0xa5, +0x80,0xdd,0xaa,0xe5,0xbc,0xe1,0x90,0xe1,0x9c,0x31,0x10,0x49,0xc7,0x76,0x00,0x00, +0x6c,0xdc,0x60,0x9a,0x4a,0xdc,0x28,0x52,0x4f,0x05,0xa2,0x99,0xb8,0xd5,0x94,0x9a, +0x84,0x9c,0xa2,0xe2,0xae,0xdc,0x8c,0xda,0x6e,0xdc,0x64,0xda,0x54,0xdc,0x3e,0xa3, +0x9c,0x31,0x10,0x34,0xb6,0x64,0x00,0x00,0x25,0x60,0x93,0x0e,0xd3,0x44,0xbf,0x0a, +0xa0,0xe8,0xaf,0x2a,0xb0,0xc8,0x93,0x2a,0x75,0x08,0x61,0x29,0x4e,0xe9,0x39,0x09, +0x3d,0x2d,0x68,0xb1,0x9a,0xcd,0xb2,0xcd,0x9c,0x31,0x10,0xbf,0xa3,0x32,0x00,0x00, +0xe2,0x92,0xd6,0x54,0xbf,0x8e,0x98,0x74,0x6e,0x4e,0x4f,0x50,0x41,0x36,0x38,0x29, +0x3b,0x11,0x53,0xac,0x85,0x36,0xae,0x68,0xc4,0x8e,0xc7,0x4c,0xbc,0x69,0xa0,0x2d, +0x9c,0x31,0x10,0xbf,0xa3,0x32,0x00,0x00,0x78,0x0d,0x55,0x69,0x3d,0x71,0x30,0x91, +0x36,0x36,0x59,0xc8,0x8c,0xaa,0xb6,0xad,0xcc,0x69,0xca,0x4d,0xb5,0x6e,0x8d,0x70, +0x63,0x89,0x48,0x4d,0x40,0x8d,0x46,0xc9,0x9c,0x31,0x10,0x44,0x93,0x21,0x00,0x00, +0x2a,0x69,0x61,0x8c,0xa3,0x2d,0xd7,0x51,0xf0,0x55,0xef,0x6d,0xcd,0x64,0x86,0x65, +0x41,0x6d,0x1f,0x8e,0x1d,0x88,0x2b,0x6a,0x46,0x70,0x77,0x71,0xac,0x89,0xd1,0x69, +0x9c,0x31,0x10,0x5c,0x93,0x31,0x00,0x00,0xdc,0x4c,0xcf,0x6d,0xa7,0x8e,0x6f,0x95, +0x45,0x69,0x39,0x4d,0x44,0x4d,0x57,0x6e,0x6b,0x8d,0x82,0x90,0x96,0x4d,0xa5,0x49, +0xaa,0x92,0xa2,0xad,0x8e,0x8e,0x75,0x4c,0x9c,0x31,0x10,0xed,0x83,0x22,0x00,0x00, +0x42,0x83,0x3a,0xcb,0x40,0xca,0x4d,0x13,0x5f,0x25,0x7d,0x1a,0x92,0x9b,0xa2,0xeb, +0xb1,0x1b,0xa9,0x1c,0x93,0x09,0x77,0x5b,0x69,0x5b,0x67,0x0d,0x62,0xcb,0x64,0xdb, +0x9c,0x31,0x10,0x1e,0x63,0x32,0x00,0x00,0x57,0x1a,0x8c,0xea,0xab,0x8c,0xd8,0xd4, +0xdc,0x6c,0xe8,0xa2,0xb2,0x44,0x89,0x19,0x70,0xa5,0x66,0xa1,0x56,0xe6,0x58,0x9b, +0x78,0xf2,0x77,0x23,0x96,0x66,0x8a,0xa4,0x9c,0x31,0x10,0xfe,0x53,0x33,0x00,0x00, +0x9d,0x48,0x9d,0x8c,0x62,0xeb,0x6d,0xa3,0x62,0x0a,0x55,0x13,0x31,0x63,0x2e,0x23, +0x38,0xda,0x64,0x54,0x71,0x24,0x81,0x5b,0x85,0x93,0x6d,0x5b,0x76,0x6b,0x7a,0x2b, +0x9c,0x31,0x10,0x93,0x43,0x43,0x00,0x00,0x52,0xca,0x59,0xbc,0x2e,0x2a,0x3a,0x34, +0x74,0xc1,0x9a,0x3b,0xa0,0xaa,0x6a,0xae,0x69,0x22,0x2c,0xab,0x0c,0xb3,0x1d,0x4c, +0x54,0x63,0x4a,0x5a,0x38,0x3d,0x5c,0x29,0x9c,0x31,0x10,0x0a,0x54,0x33,0x00,0x00, +0x8d,0x4b,0x89,0xdb,0xb1,0x5b,0xaa,0x6c,0xc4,0xdc,0x8d,0xe3,0x85,0x63,0xb9,0x23, +0xc5,0xd9,0x98,0xdd,0x71,0xd9,0xa1,0x63,0x8d,0x85,0x91,0x59,0x80,0xcc,0xa8,0xf2, +0x9c,0x31,0x10,0x91,0x63,0x33,0x00,0x00,0x9c,0xf4,0x8a,0x9b,0x8b,0x26,0x98,0x49, +0xc6,0xea,0xc4,0x63,0xe1,0x5b,0xd0,0xa2,0xda,0xad,0xb6,0x2c,0x59,0xb3,0x45,0x4b, +0x57,0x8b,0x75,0x92,0x84,0xdb,0xb9,0x4c,0x9c,0x31,0x10,0x5b,0x85,0x43,0x00,0x00, +0x93,0x11,0x9d,0x11,0xa7,0x0c,0xa9,0x46,0xa8,0xd0,0x90,0xa9,0x89,0x16,0x82,0xf6, +0x7b,0x6c,0x5f,0x2e,0x31,0x0c,0x34,0x91,0x34,0xa9,0x2e,0xcd,0x33,0x0a,0x41,0x50, +0x9c,0x31,0x10,0xca,0x74,0x34,0x00,0x00,0x3e,0x5c,0x48,0x59,0x45,0x1c,0x48,0x92, +0x6d,0x95,0x84,0xc2,0x9a,0x5b,0x9f,0x03,0xa3,0x9b,0x9f,0x13,0x9d,0xea,0xa0,0xe4, +0x88,0x2b,0x99,0x0b,0x6d,0x5a,0x66,0x24,0x9c,0x31,0x10,0x52,0x75,0x32,0x00,0x00, +0x71,0xd1,0x8e,0x93,0x92,0x92,0xa1,0xdc,0xc1,0x92,0xb0,0xe4,0xa1,0xa2,0x95,0x95, +0xa2,0xcb,0xad,0xe3,0xb6,0x63,0xb6,0x1b,0xaa,0xa2,0xae,0x29,0xb5,0x5e,0xb9,0x19, +0x9c,0x31,0x10,0x2d,0x64,0x43,0x00,0x00,0xc5,0x5a,0x9a,0xd9,0xc3,0x1c,0xc6,0x1e, +0xc9,0x64,0xb1,0xe2,0xb6,0x15,0x99,0x5d,0x7d,0xd9,0x8d,0x58,0x96,0xda,0x91,0xe0, +0x75,0x5d,0x85,0x98,0x91,0x21,0x76,0x0a,0x9c,0x31,0x10,0xc8,0x54,0x44,0x00,0x00, +0x33,0xba,0x5c,0xad,0x6b,0x29,0x35,0xad,0x31,0xa2,0x58,0xab,0x98,0xab,0x52,0x9b, +0x7b,0x93,0x9c,0x9b,0x6b,0x23,0x55,0x13,0x55,0x33,0x5e,0xab,0x2e,0x33,0x5f,0x3b, +0x9c,0x31,0x10,0x0a,0x54,0x33,0x00,0x00,0x57,0x62,0x27,0x6b,0x52,0xf3,0x62,0x2b, +0x5d,0xab,0x68,0xec,0xb9,0x72,0xac,0x33,0x74,0x0c,0x94,0x51,0x79,0xe4,0x92,0x5b, +0x69,0x9a,0x60,0x54,0x78,0xd3,0x4e,0x1b,0x9c,0x31,0x10,0x64,0x43,0x12,0x00,0x00, +0x2a,0x94,0x40,0xda,0x40,0x24,0x4d,0xd3,0x62,0xe2,0xea,0x13,0x98,0xe2,0x92,0xa2, +0x80,0xe5,0x6f,0xab,0x81,0xf2,0x1a,0x5b,0x7d,0xf2,0x56,0x34,0x39,0xb3,0x62,0x23, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_FOUR.txt b/config/_default_cfg_src_/res/en/SOUND_FOUR.txt new file mode 100644 index 0000000..a31b52e --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_FOUR.txt @@ -0,0 +1,155 @@ +0x9c,0x31,0x10,0xd1,0x42,0x22,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x75,0xdb,0x76,0x5b, +0x41,0x24,0x42,0x1b,0x4d,0xcb,0x41,0xe4,0x56,0x50,0x3d,0x2d,0x52,0xe1,0x4e,0x9e, +0x42,0x60,0x4d,0xe4,0x32,0x5a,0x72,0x5c,0x9c,0x31,0x10,0x67,0x44,0x43,0x00,0x00, +0xa3,0x3a,0x53,0xbb,0x34,0x2d,0x3b,0x4a,0x62,0xbc,0x54,0x41,0x44,0x45,0x5c,0x39, +0xbc,0xc3,0x9b,0xbd,0x34,0xb2,0x75,0x4e,0xca,0x42,0xca,0xda,0x33,0xac,0x89,0xb3, +0x9c,0x31,0x10,0xd0,0x54,0x54,0x00,0x00,0xc4,0xb3,0xb4,0xcb,0x7d,0x34,0x9c,0x42, +0x8b,0xcc,0x64,0x31,0x89,0x55,0xb9,0x2a,0x6d,0x2c,0x4b,0xb3,0xd3,0x3a,0xf2,0x44, +0x34,0xf1,0xbc,0x44,0xc4,0x19,0x68,0x45,0x9c,0x31,0x10,0x17,0x66,0x55,0x00,0x00, +0x86,0x1b,0x79,0xdc,0x59,0xa1,0xa1,0xd2,0x6d,0xd4,0x79,0xcb,0xa2,0x1c,0x59,0xcb, +0x96,0x12,0x8d,0x5b,0x5d,0x6c,0xa2,0x54,0x74,0xea,0x69,0x4a,0x99,0x65,0x35,0x9b, +0x9c,0x31,0x10,0xa3,0x66,0x55,0x10,0x00,0xb6,0x03,0x76,0xda,0xb2,0x53,0x59,0xe1, +0x9e,0xac,0x89,0x24,0xa5,0xc2,0x59,0xdc,0x81,0xe3,0x3d,0xea,0xa6,0x1a,0x5d,0x84, +0x8f,0x5d,0x89,0x52,0xbc,0xf5,0x47,0x09,0x9c,0x31,0x10,0xc6,0x66,0x66,0x20,0x00, +0x73,0x43,0x64,0xb2,0x5d,0x23,0xb8,0x43,0x9f,0x3c,0x4a,0xba,0x85,0x2d,0x33,0xd2, +0x7a,0xb3,0x89,0xd3,0x96,0xbb,0x89,0x42,0x82,0x84,0x75,0xcc,0x80,0xcb,0x4e,0x4a, +0x9c,0x31,0x10,0x07,0x66,0x66,0x10,0x00,0x51,0x3c,0xb5,0xbb,0x7b,0xb2,0x50,0xe5, +0x6d,0xc2,0x7a,0x4b,0x5b,0xab,0xad,0xbb,0x9b,0x2a,0x6c,0x4c,0x69,0x9b,0x82,0xa3, +0x6c,0x3b,0x7a,0xab,0x2b,0x52,0x94,0xac,0x9c,0x31,0x10,0xa3,0x66,0x55,0x10,0x00, +0x7d,0xa3,0x6a,0x14,0x55,0xe3,0x65,0xd1,0x96,0x74,0x65,0x0a,0x6e,0x64,0xb8,0xd9, +0x9e,0x15,0x49,0x4b,0x7e,0x19,0x55,0x9c,0x7e,0x05,0x8d,0x22,0x6d,0x93,0xc1,0x5c, +0x9c,0x31,0x10,0x4a,0x66,0x65,0x20,0x00,0x7c,0x3a,0x64,0x33,0x93,0xab,0x83,0x41, +0x85,0x4a,0xab,0xb5,0xab,0xbd,0x7a,0xc4,0x9e,0x4a,0xe2,0xbb,0xd4,0xc4,0x5c,0x32, +0xa5,0xb1,0x7d,0x1b,0x35,0x46,0x83,0x38,0x9c,0x31,0x10,0x5b,0x67,0x66,0x20,0x00, +0x84,0xcc,0x23,0xbc,0x73,0x39,0x5b,0x44,0xcd,0x52,0x62,0x1d,0xa3,0xab,0x53,0xc3, +0xbc,0x15,0x94,0x09,0x86,0x14,0x5b,0x92,0x7d,0xb2,0x83,0x44,0x6c,0xbb,0x7b,0xc4, +0x9c,0x31,0x10,0x56,0x98,0x87,0x30,0x00,0x83,0xb9,0x73,0xb3,0x84,0x34,0x84,0x42, +0x73,0xbb,0x83,0x3b,0x83,0xbb,0x7b,0x43,0x7b,0xbb,0x82,0xba,0xcd,0xc9,0x6f,0x1e, +0x5c,0x32,0x43,0xbd,0x6c,0x44,0x6a,0xa9,0x9c,0x31,0x10,0x39,0x97,0x76,0x30,0x00, +0x7d,0xc9,0x81,0x1c,0x82,0x62,0x96,0xcb,0xa2,0x25,0xae,0x5d,0xad,0x11,0xc2,0xd4, +0x98,0xa9,0x86,0x1b,0x66,0xa3,0x72,0x1b,0x66,0x65,0x5c,0x63,0x65,0x1c,0x5a,0xa1, +0x9c,0x31,0x10,0xad,0x97,0x65,0x30,0x00,0x6d,0x50,0x72,0x04,0x85,0xdc,0xa2,0x91, +0x92,0x51,0x80,0xd6,0x4d,0x6e,0x49,0xd2,0x37,0x25,0x25,0x9d,0x39,0x50,0x36,0x1d, +0x54,0xd1,0x46,0x1c,0x55,0xd1,0x66,0x9a,0x9c,0x31,0x10,0xce,0xc7,0x54,0x10,0x00, +0x7d,0x94,0x80,0x82,0x81,0x56,0x86,0x75,0x82,0x61,0x7f,0x81,0x7c,0x39,0x84,0x89, +0x8e,0x85,0x8f,0x85,0x80,0x75,0x66,0x96,0x55,0x45,0x72,0x95,0xad,0x54,0xca,0x84, +0x9c,0x31,0x10,0x5e,0xda,0x55,0x30,0x00,0x8c,0xf5,0x5f,0x09,0x4c,0xe5,0x5a,0xe6, +0xab,0x16,0xc0,0xc6,0xa7,0x30,0x60,0x94,0x41,0x68,0x46,0x85,0x9d,0x65,0xbe,0x75, +0xb1,0x79,0x82,0x79,0x4b,0x75,0x40,0x56,0x9c,0x31,0x10,0xca,0xda,0x46,0x30,0x00, +0x5f,0x76,0xc2,0x95,0xaf,0x25,0xac,0xf4,0x54,0xc4,0x4b,0x50,0x3c,0x75,0xa3,0x96, +0xb8,0x46,0xaf,0xa5,0x84,0x45,0x4b,0xa4,0x42,0x38,0x5b,0x95,0xc4,0x82,0xa7,0x36, +0x9c,0x31,0x10,0x7e,0xda,0x46,0x20,0x00,0xae,0xe5,0x56,0xc4,0x4f,0x68,0x36,0x61, +0xa1,0x95,0xb6,0x36,0xaf,0xb5,0x86,0x35,0x4f,0xa0,0x40,0x35,0x53,0x96,0xc4,0x85, +0xa7,0x35,0xb0,0xf4,0x5c,0xc5,0x53,0x79,0x9c,0x31,0x10,0xf2,0xda,0x45,0x20,0x00, +0x30,0x56,0x97,0xb6,0xb8,0x25,0xad,0xb4,0x90,0x44,0x57,0x91,0x48,0x66,0x45,0x75, +0xbc,0xb4,0xa7,0x04,0xb5,0x14,0x68,0x95,0x5d,0x9a,0x30,0x25,0x7f,0xd5,0xb6,0x25, +0x9c,0x31,0x10,0xba,0xda,0x35,0x20,0x00,0xab,0xdd,0x9f,0x2d,0x5f,0xb5,0x53,0x60, +0x33,0x85,0xab,0x8e,0xaa,0x56,0xb5,0xb5,0x7f,0x38,0x63,0xc8,0x3b,0x26,0x58,0xda, +0xb7,0x31,0xa6,0xb5,0xad,0x5d,0x6d,0x84,0x9c,0x31,0x10,0x46,0xda,0x45,0x30,0x00, +0x65,0x29,0x2c,0x84,0x81,0x84,0xae,0x55,0xaf,0x95,0x96,0x66,0x6b,0x69,0x54,0xb5, +0x35,0x16,0x9b,0x06,0xa8,0xc5,0xb3,0x34,0x84,0xa4,0x71,0x54,0x42,0x90,0x45,0x55, +0x9c,0x31,0x10,0x5b,0xd9,0x46,0x40,0x00,0xa6,0x4c,0xad,0x4c,0xac,0xcc,0x7c,0xec, +0x71,0x23,0x34,0x4c,0x5b,0xcb,0xaa,0x29,0xaf,0x89,0xa2,0x6a,0x7b,0x4b,0x68,0xe4, +0x32,0x95,0x69,0x8d,0xac,0x4c,0xaf,0x8b,0x9c,0x31,0x10,0x5b,0xd9,0x46,0x40,0x00, +0x9a,0x6a,0x7d,0x49,0x64,0xf1,0x2e,0x92,0x71,0x8c,0xb0,0x2e,0xad,0x8e,0x96,0x6c, +0x7b,0x49,0x62,0xf0,0x2e,0x88,0x77,0x8b,0xb0,0x2d,0xab,0x8e,0x92,0x4d,0x7d,0x4b, +0x9c,0x31,0x10,0xff,0xd9,0x47,0x30,0x00,0x60,0xf2,0x2c,0x91,0x7d,0x8a,0xb2,0x4c, +0xa9,0x8d,0x90,0x4d,0x81,0x53,0x62,0xd2,0x2c,0x91,0x79,0x6a,0xb4,0x4c,0xa9,0x8d, +0x90,0x4c,0x83,0x4b,0x66,0xc9,0x2a,0xb2,0x9c,0x31,0x10,0xc4,0xd9,0x46,0x20,0x00, +0x71,0x6d,0xb2,0x4e,0xa7,0x8d,0x90,0x4a,0x89,0x48,0x72,0xa1,0x2c,0xcd,0x5b,0x45, +0xb0,0x8b,0xa9,0x49,0x92,0xaa,0x8b,0x2b,0x80,0xcc,0x36,0xe3,0x45,0x09,0xaa,0xca, +0x9c,0x31,0x10,0xe4,0xd9,0x55,0x30,0x00,0xac,0x75,0x95,0x86,0x8a,0x56,0x91,0x95, +0x49,0x78,0x2b,0x64,0x95,0x94,0xb5,0x45,0x97,0xb5,0x8a,0x35,0x99,0xa5,0x6b,0x55, +0x1f,0x66,0x67,0xa6,0xbd,0x45,0x9e,0x94,0x9c,0x31,0x10,0x5c,0xd8,0x35,0x10,0x00, +0x8d,0x4a,0x95,0x8b,0x90,0x7c,0x34,0x8c,0x30,0x5c,0xa7,0xb2,0xb1,0x22,0x8c,0xeb, +0x90,0x0c,0xa1,0xdb,0x6c,0x33,0x1d,0x8b,0x5d,0xa1,0xc0,0x5b,0x97,0x7d,0x8b,0xa2, +0x9c,0x31,0x10,0x00,0xd9,0x35,0x20,0x00,0x9b,0x5a,0x9d,0x9b,0x4c,0x6a,0x1f,0x5d, +0x81,0xb5,0xbf,0x3a,0x88,0xaa,0x92,0x63,0xa1,0x81,0x94,0x73,0x3d,0x93,0x27,0x3b, +0x8e,0xd6,0xb9,0x1b,0x7f,0xca,0x99,0x4a,0x9c,0x31,0x10,0x89,0xd9,0x45,0x10,0x00, +0xa3,0x94,0x90,0x66,0x3d,0x91,0x2e,0x3a,0x85,0xd5,0xbc,0x28,0x7c,0xb5,0x9c,0x55, +0xa0,0x8a,0x96,0x64,0x4c,0x75,0x33,0x71,0x63,0x85,0xbf,0x76,0x82,0x55,0x96,0xa5, +0x9c,0x31,0x10,0x36,0xda,0x36,0x20,0x00,0x9b,0x5b,0x9f,0x9b,0x69,0x5a,0x42,0xab, +0x3d,0x2a,0xa4,0xd4,0xa0,0x1b,0x83,0xd2,0x9b,0x33,0x9e,0xb3,0x8d,0x4a,0x59,0x9b, +0x3d,0x62,0x58,0x8d,0xba,0x73,0x84,0x72,0x9c,0x31,0x10,0xdc,0xd9,0x56,0x20,0x00, +0x8d,0x2c,0x96,0xcb,0xa3,0x0b,0x7a,0xca,0x5d,0x2b,0x38,0xa2,0x6b,0x6b,0xb4,0x6a, +0x7d,0x4a,0x8c,0x8d,0x9b,0x4b,0xa0,0x6a,0x79,0x6c,0x64,0x93,0x39,0x2b,0x62,0xee, +0x9c,0x31,0x10,0xef,0xca,0x46,0x30,0x00,0xea,0xf4,0x74,0xe9,0x95,0x11,0xb6,0xd9, +0xd1,0x01,0x7c,0xf5,0x66,0xf5,0x09,0x39,0x00,0x88,0xd5,0x8a,0x9a,0x54,0x77,0x8a, +0xaa,0x95,0xcf,0x45,0x9c,0xc2,0x87,0x04,0x9c,0x31,0x10,0x75,0xda,0x67,0x30,0x00, +0x61,0x05,0x34,0xc5,0x61,0x65,0xbe,0x65,0x69,0x85,0x8a,0x65,0x9f,0x95,0x98,0x55, +0x8b,0x85,0x88,0x65,0x61,0x65,0x2a,0x75,0x71,0xc2,0xb6,0x19,0x67,0xc6,0x88,0x34, +0x9c,0x31,0x10,0xfa,0xda,0x66,0x30,0x00,0xa7,0xa6,0x8c,0x64,0x8d,0x45,0x90,0xe5, +0x68,0xd5,0x35,0x59,0x54,0x98,0xbd,0x16,0x69,0x08,0x86,0xa2,0xa1,0x85,0x92,0x36, +0x89,0xa5,0x96,0x95,0x76,0xf5,0x49,0x56,0x9c,0x31,0x10,0x7f,0xdb,0x76,0x30,0x00, +0x38,0x71,0xa3,0xa9,0x88,0x50,0x75,0x69,0x98,0xd1,0x9c,0xd6,0x83,0x35,0x9e,0xa5, +0x87,0x24,0x5e,0xe5,0x3d,0x04,0x58,0xf9,0xae,0xb1,0x6f,0x5a,0x86,0x95,0xa1,0x55, +0x9c,0x31,0x10,0xe2,0xda,0x76,0x30,0x00,0x8a,0x64,0x8f,0x15,0x9b,0x35,0x7e,0xa6, +0x5d,0x46,0x3e,0xe9,0x67,0x44,0xa8,0x31,0x6f,0xd8,0x8c,0x21,0x9f,0x86,0x84,0xd5, +0x92,0x95,0x9d,0xa4,0x7a,0x76,0x5f,0x29,0x9c,0x31,0x10,0xcb,0xdb,0x76,0x20,0x00, +0x3d,0x06,0x6b,0x18,0xa2,0x91,0x6f,0x69,0x90,0x95,0x9d,0x15,0x85,0x15,0x94,0xa1, +0x9d,0x35,0x76,0xe5,0x64,0xd5,0x41,0x28,0x5f,0x09,0xa4,0x70,0x71,0x86,0x8a,0xa5, +0x9c,0x31,0x10,0x73,0xca,0x76,0x20,0x00,0xbc,0xe1,0x8f,0x95,0xa2,0x55,0xaf,0x35, +0x89,0x15,0x54,0xb5,0x21,0x36,0x0c,0x71,0xc2,0xf9,0x7b,0xa0,0x7e,0x51,0xbd,0x19, +0x95,0x21,0x98,0xb5,0xb2,0xf5,0x99,0x11,0x9c,0x31,0x10,0xcb,0xdb,0x76,0x20,0x00, +0x70,0xf5,0x60,0xf5,0x3c,0xc6,0x81,0x91,0x94,0x85,0x72,0xf8,0x95,0x35,0x94,0xd5, +0x84,0xe9,0x95,0x05,0x91,0x01,0x7c,0xe9,0x6c,0xf5,0x4d,0x11,0x4e,0xb1,0x9e,0xd9, +0x9c,0x31,0x10,0x77,0xca,0x85,0x20,0x00,0x79,0x97,0x80,0xe4,0xbc,0x89,0x95,0x19, +0x95,0x46,0xb2,0xd8,0x92,0xb8,0x6d,0x06,0x47,0x18,0x0a,0xca,0x5f,0xcb,0xb2,0x45, +0x6c,0xd6,0x9f,0x4a,0xb1,0x18,0x90,0xc5,0x9c,0x31,0x10,0xff,0xca,0x75,0x20,0x00, +0xa4,0x62,0xa8,0x94,0x8b,0x93,0x63,0x72,0x38,0x7b,0x10,0x34,0x87,0xe0,0xa1,0x80, +0x74,0x65,0xa8,0x5d,0xab,0x8a,0x93,0x9a,0xac,0x84,0x9a,0x5b,0x7a,0x79,0x53,0x72, +0x9c,0x31,0x10,0xcd,0xc9,0x85,0x20,0x00,0x28,0xc7,0x27,0x33,0xa4,0x24,0x8d,0xa8, +0x84,0xd8,0xaf,0x66,0xa1,0x36,0x95,0x68,0xad,0xda,0x9a,0x79,0x70,0x46,0x48,0x35, +0x21,0x87,0x3e,0xd9,0xab,0x1b,0x87,0x28,0x9c,0x31,0x10,0x42,0xc9,0x84,0x20,0x00, +0x89,0x75,0xb0,0xb5,0x9e,0x87,0x9c,0x78,0xa8,0x38,0x8d,0x88,0x66,0x78,0x3f,0xa7, +0x23,0x48,0x59,0xdc,0xa9,0x4b,0x86,0x57,0x95,0x55,0xb0,0x76,0x9e,0x87,0x9d,0x88, +0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00,0x9c,0xcd,0x82,0xc5,0x56,0xc6,0x3b,0x6d, +0x28,0xfa,0x6f,0xd1,0xa3,0x05,0x88,0xe4,0x9e,0xad,0xac,0xd1,0x9c,0xe9,0xa1,0x04, +0x95,0x05,0x7a,0xf1,0x50,0xb1,0x34,0xcd,0x9c,0x31,0x10,0x83,0xc9,0x84,0x10,0x00, +0x32,0x44,0x7f,0xa2,0x9f,0x95,0x8c,0xa8,0xa0,0x79,0xac,0x67,0xa3,0x77,0x9c,0x68, +0x90,0x8a,0x74,0x89,0x49,0x86,0x31,0x75,0x41,0x54,0x8e,0x35,0x9a,0x47,0x91,0x77, +0x9c,0x31,0x10,0x94,0xc8,0x83,0x10,0x00,0xa6,0x86,0xa8,0x96,0xa0,0xb5,0x95,0x84, +0x89,0x83,0x63,0x64,0x3c,0xd7,0x32,0xda,0x57,0xec,0x9a,0x6c,0x98,0x39,0x97,0x17, +0xa8,0x37,0xa6,0x47,0x9b,0x87,0x92,0x85,0x9c,0x31,0x10,0xbf,0xc9,0x74,0x00,0x00, +0x82,0xc1,0x5a,0xad,0x3b,0x11,0x38,0xf1,0x6b,0x8c,0x9b,0x45,0x93,0x29,0x97,0x11, +0xa4,0xf5,0xa2,0xd5,0x96,0xc9,0x8c,0xc9,0x7e,0xd5,0x56,0xb9,0x3c,0xb0,0x3e,0xa5, +0x9c,0x31,0x10,0xaa,0xc8,0x84,0x00,0x00,0x78,0xa1,0x9d,0x92,0x94,0xc5,0x99,0xb8, +0xa6,0xa8,0xa2,0xc8,0x94,0xa9,0x8b,0xc9,0x7c,0x9b,0x53,0x6b,0x38,0x49,0x44,0x25, +0x85,0x44,0x9c,0x36,0x91,0x67,0x99,0x56,0x9c,0x31,0x10,0xa8,0xc8,0x73,0x00,0x00, +0xa5,0x7a,0x9c,0x8a,0x90,0x73,0x87,0x9d,0x77,0x95,0x50,0x8b,0x3b,0x6b,0x4e,0x43, +0x8b,0x3d,0x9c,0x3d,0x92,0x4c,0x99,0x53,0xa4,0x5a,0x9b,0x64,0x89,0x6d,0x81,0x8d, +0x9c,0x31,0x10,0x76,0xc7,0x84,0x10,0x00,0x71,0x61,0x51,0xa1,0x3f,0x21,0x5b,0x66, +0x90,0xed,0x98,0xa9,0x8e,0xe5,0x96,0xe1,0xa3,0x22,0x96,0xe5,0x84,0xe5,0x7e,0xdc, +0x6d,0x19,0x4f,0x59,0x43,0x1d,0x67,0xa5,0x9c,0x31,0x10,0x23,0xb7,0x63,0x00,0x00, +0xad,0xbc,0xb2,0xb2,0xa5,0x91,0xb6,0x76,0xc2,0x85,0xa3,0x85,0x82,0x7a,0x74,0x43, +0x4f,0x41,0x1c,0x78,0x16,0x69,0x66,0xa6,0xb2,0x82,0xb4,0xa4,0xa9,0x94,0xb7,0xa1, +0x9c,0x31,0x10,0x80,0xb6,0x64,0x10,0x00,0xbb,0x41,0x96,0xe9,0x79,0x55,0x67,0xad, +0x41,0x49,0x1a,0xa9,0x2e,0x12,0x80,0xad,0xb4,0xe9,0xb2,0xe9,0xae,0xad,0xb8,0xad, +0xaa,0xcd,0x8b,0x29,0x72,0xf1,0x54,0x59,0x9c,0x31,0x10,0xa6,0xb6,0x73,0x00,0x00, +0x2f,0x47,0x21,0x76,0x51,0x77,0x97,0x49,0xb3,0x3b,0xb2,0x58,0xb5,0x76,0xb5,0x67, +0x9e,0x47,0x82,0x36,0x66,0x56,0x41,0x57,0x29,0x56,0x3c,0x67,0x70,0x8a,0xa1,0x69, +0x9c,0x31,0x10,0xa8,0xb5,0x73,0x10,0x00,0xb2,0xda,0xb6,0xdd,0xb9,0x31,0xab,0x20, +0x91,0x95,0x77,0xa8,0x56,0xa1,0x36,0x95,0x32,0xd9,0x54,0x9e,0x85,0x1d,0xa6,0x95, +0xb2,0xdd,0xb8,0xe0,0xb0,0xdc,0x9d,0x5c,0x9c,0x31,0x10,0x3a,0xb5,0x64,0x10,0x00, +0x83,0x19,0x63,0x21,0x3f,0x2a,0x33,0x61,0x49,0x55,0x6d,0x10,0x92,0x9d,0xae,0xa9, +0xbc,0xe9,0xba,0x91,0xa9,0x12,0x8e,0xa1,0x6c,0xed,0x46,0xe0,0x34,0xd0,0x43,0x1d, +0x9c,0x31,0x10,0x35,0xb4,0x73,0x10,0x00,0x60,0x21,0x80,0xd9,0xa2,0xce,0xb9,0x16, +0xbc,0xe5,0xaa,0xa1,0x92,0x5d,0x72,0xdd,0x53,0x1a,0x3c,0x99,0x46,0xa1,0x5e,0x61, +0x79,0x18,0x97,0x1d,0xb5,0x69,0xc1,0x61,0x9c,0x31,0x10,0xb1,0xb4,0x53,0x00,0x00, +0xb4,0x41,0x91,0x62,0x6b,0xc5,0x4f,0x70,0x43,0x79,0x4c,0x4c,0x61,0x72,0x79,0x54, +0x96,0x4a,0xb4,0x49,0xc0,0x4d,0xad,0x4c,0x8a,0x6d,0x69,0xb6,0x55,0x6d,0x4c,0x89, +0x9c,0x31,0x10,0x48,0xa3,0x63,0x00,0x00,0x28,0x61,0x50,0x61,0x82,0xa1,0xb0,0x5a, +0xd6,0x59,0xe4,0x61,0xca,0xa4,0x94,0x15,0x5b,0x9d,0x35,0x64,0x2a,0x9d,0x3c,0x55, +0x60,0x59,0x84,0x72,0xa4,0x59,0xbb,0x8d,0x9c,0x31,0x10,0x48,0xa3,0x63,0x00,0x00, +0xc4,0x69,0xb4,0x59,0x8e,0x51,0x63,0xad,0x47,0x64,0x42,0x95,0x51,0x61,0x6d,0xa1, +0x89,0x65,0xa1,0x5d,0xae,0x11,0xad,0x1d,0x9d,0x65,0x7e,0x59,0x62,0x5d,0x55,0x1d, +0x9c,0x31,0x10,0x80,0x93,0x52,0x00,0x00,0x35,0x5c,0x55,0x31,0x7b,0x69,0x9d,0x40, +0xac,0xca,0xae,0xad,0xa8,0xe5,0x95,0x1d,0x76,0xd9,0x5e,0x91,0x5b,0x29,0x66,0xe0, +0x77,0x12,0x86,0xe5,0x8c,0xe1,0x90,0xdd,0x9c,0x31,0x10,0xcb,0x62,0x42,0x00,0x00, +0xe5,0x4b,0xb2,0x88,0x72,0x3d,0x3d,0x5b,0x35,0xa3,0x5d,0xaa,0x92,0xdb,0xb5,0xb4, +0xc2,0x33,0xa4,0xa9,0x75,0xa4,0x74,0xcb,0x5a,0x42,0x75,0x34,0x8a,0x3a,0xa1,0xaa, +0x9c,0x31,0x10,0xec,0x52,0x32,0x00,0x00,0xd5,0x1c,0xb6,0x21,0x91,0xa5,0x65,0x1a, +0x2b,0x43,0x30,0x6a,0x3a,0xda,0x5d,0x14,0x66,0x33,0x9c,0x4a,0xbd,0x1b,0xba,0x64, +0x6e,0x1d,0x3e,0x11,0x36,0x65,0x3a,0x51,0x9c,0x31,0x10,0xec,0x52,0x32,0x00,0x00, +0x39,0x14,0x76,0xab,0xa4,0x8a,0x99,0xec,0x99,0xda,0x9e,0xc3,0x99,0x2d,0x92,0x1a, +0x54,0xcb,0x4d,0xa2,0x55,0x5b,0x5d,0x62,0x6d,0xd4,0x82,0x63,0x8d,0x9b,0x8d,0x24, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_GSOUND_MIC_CLOSE.txt b/config/_default_cfg_src_/res/en/SOUND_GSOUND_MIC_CLOSE.txt new file mode 100644 index 0000000..5d13fb8 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_GSOUND_MIC_CLOSE.txt @@ -0,0 +1,234 @@ +0x9c,0x71,0x14,0x4c,0xcd,0x87,0x56,0x55,0x7e,0xfb,0x57,0xef,0xb5,0x7c,0xfb,0x58, +0x2f,0xc5,0x6e,0xf3,0x29,0xd2,0xa5,0x5e,0xba,0x59,0xb4,0x25,0x54,0x91,0x5c,0xf8, +0x25,0x18,0x7b,0x5d,0xd7,0x35,0x22,0x93,0x5e,0x94,0xb5,0x0a,0xc3,0x5f,0x31,0xb5, +0x9c,0x71,0x14,0x3c,0xcd,0x44,0x00,0x00,0x07,0x78,0x8f,0x77,0x8d,0x0c,0x8e,0x9e, +0xe6,0x30,0x18,0xa3,0x2d,0xb5,0x10,0x2e,0xb3,0x2c,0x44,0x4c,0x47,0xbf,0x2a,0x83, +0xa9,0x65,0xc4,0xd8,0x93,0x8a,0x83,0xc5,0x06,0xd3,0xb2,0x9f,0xbe,0xc5,0x24,0x55, +0x9c,0x71,0x14,0x63,0xcc,0x33,0x00,0x00,0xb8,0xf4,0x53,0xb9,0x18,0xcc,0x66,0x62, +0xd2,0x08,0xd6,0x55,0x62,0x63,0x28,0xda,0x43,0x62,0x6c,0x35,0xd5,0x33,0x92,0xed, +0x36,0xca,0x24,0x43,0xcd,0xf6,0xba,0x19,0x04,0xe6,0xa5,0xa7,0x10,0x16,0x37,0x01, +0x9c,0x71,0x14,0xec,0xcc,0x32,0x00,0x00,0x90,0x0c,0x17,0xaf,0x24,0x79,0x8d,0x69, +0x07,0x04,0x64,0x91,0x6a,0x46,0xa1,0x52,0x19,0x5b,0x46,0x02,0x44,0xa3,0x4b,0xf5, +0x46,0x3c,0x30,0x8c,0x44,0x76,0x3a,0xbe,0x5c,0x33,0x95,0x3e,0xcb,0x6b,0xc2,0xd4, +0x9c,0x71,0x14,0x0f,0xbc,0x22,0x00,0x00,0x10,0xd6,0x5e,0x22,0x34,0x2b,0x5f,0x6c, +0x41,0xc4,0x4c,0xe4,0x9a,0x11,0x95,0x6e,0x66,0x48,0x01,0x95,0x91,0xe4,0x45,0xc9, +0xc1,0xb1,0x60,0x14,0x12,0x15,0xca,0x59,0x62,0xaa,0x98,0xdd,0x51,0xa1,0xc3,0x28, +0x9c,0x71,0x14,0xfb,0xbb,0x22,0x00,0x00,0xe6,0x4e,0x91,0x73,0xa5,0xe7,0x39,0x61, +0xb4,0xf5,0xde,0xa6,0x82,0x76,0x06,0xcf,0x96,0x53,0x9e,0xe6,0xb9,0x8b,0x45,0x1f, +0x75,0xa0,0x84,0x16,0xb7,0xb5,0x86,0x83,0x98,0x5f,0xa5,0x6c,0x87,0xa9,0xe7,0x48, +0x9c,0x71,0x14,0xfb,0xbb,0x22,0x00,0x00,0x56,0x8e,0x9b,0x1e,0xa5,0x44,0x9a,0x9c, +0x15,0xd5,0x38,0xa8,0x4c,0x9c,0xe5,0x34,0x37,0x4c,0xb3,0xf1,0x35,0x46,0xac,0x73, +0x19,0x3c,0xd3,0x9b,0xc2,0x49,0x49,0xdf,0x9a,0xd9,0xa5,0x5a,0xe8,0x69,0xa9,0x46, +0x9c,0x71,0x14,0x52,0xab,0x21,0x00,0x00,0x5d,0xd8,0xe8,0xd2,0x2e,0x85,0xd8,0x96, +0x42,0x90,0xac,0xd0,0x84,0x03,0x25,0xcc,0xc2,0xa2,0x34,0x48,0xe6,0xae,0x40,0xf5, +0xad,0xf4,0x98,0xe0,0x67,0x31,0xf8,0x7e,0xd0,0x88,0xae,0xef,0x68,0xd1,0x6a,0x10, +0x9c,0x71,0x14,0x02,0xab,0x41,0x00,0x00,0xde,0xa9,0x72,0xb5,0x96,0xc6,0xa1,0x64, +0x85,0xf7,0xa7,0x9d,0x66,0x66,0x27,0x87,0x1b,0x78,0x56,0x27,0x60,0x9d,0x79,0xed, +0xe7,0x51,0x23,0x8c,0xfd,0x88,0x48,0x2b,0x7d,0x3c,0xdb,0x1a,0xb8,0x8e,0x04,0x3a, +0x9c,0x71,0x14,0xa1,0xba,0x53,0x00,0x00,0x4a,0xbc,0xda,0x83,0xae,0x54,0x4a,0xda, +0xc2,0xf0,0x78,0xd0,0xdb,0x22,0x6d,0x50,0xe2,0x86,0xf8,0xc6,0x39,0xf6,0x59,0x48, +0x04,0xa1,0x7c,0xda,0x40,0xd2,0x90,0x77,0x55,0x81,0x31,0x86,0xe1,0x46,0x41,0xb1, +0x9c,0x71,0x14,0x89,0xb9,0x44,0x00,0x00,0x88,0x6f,0x45,0xc1,0x9a,0xb5,0x62,0x5b, +0x7a,0x2a,0xd1,0x4a,0x34,0xe3,0xa2,0x67,0xb6,0x35,0x05,0x1b,0x9d,0xa1,0x37,0x6e, +0x1b,0x97,0x15,0xb6,0xe6,0xeb,0x98,0x0a,0x37,0xe7,0x23,0x7e,0x85,0x35,0xc7,0x5b, +0x9c,0x71,0x14,0x0c,0xa9,0x84,0x00,0x00,0x52,0x17,0xb9,0x3c,0x7c,0xb4,0x27,0xbb, +0xdb,0x7b,0x5a,0x47,0xb5,0x99,0x7b,0x3a,0x77,0xba,0xb6,0x7b,0x80,0xa7,0xbb,0x32, +0x7b,0x56,0xd7,0xbb,0x4e,0x7b,0x7d,0x17,0xba,0x2b,0x8c,0x33,0x7a,0x83,0x26,0xf4, +0x9c,0x71,0x14,0xdf,0xac,0x84,0x00,0x00,0x91,0x7a,0xec,0x4f,0x29,0xca,0x92,0x19, +0xea,0x9c,0x37,0x89,0x92,0xb6,0x61,0x7a,0xca,0x1a,0x64,0x9d,0xa1,0x19,0x95,0xd8, +0x9d,0x8f,0x49,0xd9,0x46,0x9d,0xb8,0x8d,0x94,0x74,0xd5,0x31,0xb5,0xd3,0x0e,0x61, +0x9c,0x71,0x14,0xee,0xac,0x51,0x00,0x00,0xe8,0x24,0x8e,0x06,0x42,0xcd,0xc9,0x51, +0x0c,0x1d,0x26,0x47,0xd4,0xb3,0x36,0xcf,0x85,0x0a,0x9d,0xe5,0x81,0x8d,0xd6,0x43, +0xea,0xa7,0x40,0x3b,0xcb,0x93,0x67,0xc0,0x90,0xf7,0x6d,0x08,0x28,0x8b,0x27,0x42, +0x9c,0x71,0x14,0x47,0xbc,0x52,0x00,0x00,0xc5,0xbe,0x9c,0x4b,0x35,0x60,0x49,0x54, +0x73,0xe8,0x4b,0x92,0x99,0xec,0x91,0x97,0x89,0x98,0xd3,0x75,0x61,0x5e,0x99,0x1a, +0xe5,0x9c,0xbd,0x19,0x55,0xda,0x49,0x42,0xc3,0xd7,0x69,0x75,0xc8,0xec,0xa9,0x59, +0x9c,0x71,0x14,0x47,0xbc,0x52,0x00,0x00,0xd3,0x53,0x58,0x14,0x49,0x37,0xa2,0x53, +0x7b,0x6d,0x86,0x81,0x9a,0x63,0xb1,0x9f,0x6a,0x56,0x9a,0xe9,0x86,0xaf,0x19,0xa5, +0xf1,0xa5,0x44,0xe5,0x08,0x24,0x2f,0xb6,0x94,0xa9,0x74,0xc1,0x4d,0x6e,0x45,0x8d, +0x9c,0x71,0x14,0xb3,0xbb,0x52,0x00,0x00,0xb3,0x58,0xd4,0x0f,0x75,0x2b,0x33,0x56, +0x38,0xf1,0xa9,0x28,0x5a,0x67,0x25,0x74,0x5d,0x27,0x02,0x71,0x96,0x0a,0x9b,0x2c, +0xc5,0x72,0xec,0xd3,0x34,0xd2,0x2f,0x11,0x1a,0x2a,0x29,0xe7,0xdc,0x6d,0x66,0x8d, +0x9c,0x71,0x14,0xab,0xbb,0x42,0x00,0x00,0x54,0x33,0x91,0xc8,0xf1,0x3d,0x36,0x0a, +0x3e,0x6a,0xb4,0xdd,0x59,0x11,0xd1,0x68,0x1a,0x98,0xf4,0x65,0xae,0xee,0xd8,0xe4, +0x15,0x38,0x1a,0xd1,0xa2,0x21,0x72,0xde,0x6d,0xdd,0xf5,0xf3,0x35,0x98,0x99,0x25, +0x9c,0x71,0x14,0x3f,0xbb,0x51,0x00,0x00,0x2f,0xbc,0x32,0xce,0x45,0x87,0xd8,0x9a, +0xb2,0x2b,0x95,0x9c,0x75,0xb4,0xc5,0x7b,0x65,0x8a,0x9c,0x5b,0xb5,0x19,0xa6,0x0a, +0xd7,0x28,0xd7,0x44,0xae,0x27,0xbb,0xae,0xae,0x99,0xe7,0xa7,0x3a,0x53,0x96,0x48, +0x9c,0x71,0x14,0x27,0xbb,0x41,0x00,0x00,0x20,0x4d,0xb6,0xe2,0x8b,0xb4,0xa2,0x7b, +0x0d,0x05,0x70,0xdc,0x86,0xc4,0x1b,0x95,0x1f,0x7b,0x5b,0x31,0x75,0xd7,0x42,0xe5, +0x7c,0x2a,0xb2,0xb9,0x8a,0x27,0xe6,0xc2,0x4d,0x35,0xa6,0x62,0x4a,0xb2,0xa2,0x6a, +0x9c,0x71,0x14,0x36,0xba,0x42,0x00,0x00,0x53,0x1c,0xaa,0x5d,0x46,0xad,0x74,0xd7, +0x53,0x55,0x52,0x93,0x17,0xfa,0x89,0xb8,0xec,0x8a,0x35,0xce,0x55,0x29,0x12,0xa8, +0xee,0x73,0xc8,0x9c,0xce,0xad,0xd9,0x4d,0x17,0x69,0x6d,0x28,0xa2,0x93,0x8d,0x69, +0x9c,0x71,0x14,0xf2,0xba,0x31,0x00,0x00,0x99,0x33,0x3b,0xdd,0xcd,0x99,0x4a,0x25, +0xad,0xb8,0x70,0x6f,0xaa,0x6a,0xf6,0xb0,0x51,0xe6,0x58,0xf2,0x25,0x21,0x84,0x8f, +0x4a,0xb1,0x22,0xde,0x61,0x04,0xa8,0xd2,0x04,0x86,0xc9,0x34,0xaf,0x57,0x85,0xd6, +0x9c,0x71,0x14,0xd7,0xaa,0x31,0x00,0x00,0xc7,0x2f,0x6b,0x37,0x29,0x57,0xbe,0xc5, +0x9a,0xd9,0x8c,0x51,0x9b,0xf3,0xcd,0x88,0x94,0x54,0xeb,0xea,0x45,0x91,0x59,0x13, +0xae,0xc3,0x5a,0x4b,0x4a,0x65,0x66,0xbf,0x13,0xc6,0x95,0x49,0x42,0xd7,0xf7,0x09, +0x9c,0x71,0x14,0xb8,0x9a,0x31,0x00,0x00,0xce,0xc0,0xcd,0x39,0xb5,0xbf,0x59,0x59, +0x44,0x49,0x76,0x9a,0x43,0xcb,0x6c,0x2a,0x87,0x42,0xc4,0x2e,0x83,0x62,0x5b,0xda, +0xa5,0xf2,0xad,0x0b,0xe6,0x95,0x85,0x46,0xc3,0xd7,0xe5,0x3f,0xb0,0xd5,0x69,0x96, +0x9c,0x71,0x14,0xab,0x89,0x32,0x00,0x00,0x99,0x1e,0x3a,0xb3,0x4c,0xb1,0xa0,0xb9, +0x4e,0x51,0xc6,0x71,0x3e,0xc2,0x5b,0xcd,0x51,0x48,0xfd,0x53,0x38,0xba,0x23,0x05, +0x24,0x3a,0x21,0xb6,0xd9,0x0a,0x61,0xd1,0x48,0x59,0xa4,0x92,0x2d,0xad,0xe4,0x92, +0x9c,0x71,0x14,0x96,0x99,0x22,0x00,0x00,0xa4,0xb0,0xb9,0x7c,0x9c,0x64,0x6e,0x46, +0x12,0x54,0x5f,0x74,0x37,0x5c,0x11,0x6b,0xb1,0xc6,0xd4,0x23,0x80,0x45,0x4a,0xd8, +0xc2,0xc3,0xcd,0x4a,0xb7,0xed,0x75,0x41,0xa4,0xa5,0x0b,0x51,0xb9,0x25,0xdb,0x2d, +0x9c,0x71,0x14,0x1a,0x99,0x21,0x00,0x00,0x74,0xb3,0xa6,0xd1,0xb1,0x8c,0xbe,0x6a, +0xa6,0x0c,0xcb,0xcd,0x4a,0xca,0x55,0x7b,0x24,0xe4,0x4c,0xe5,0x50,0x5f,0x15,0xeb, +0xf5,0x76,0x1d,0x06,0xb3,0x46,0x7b,0xd6,0x9a,0x35,0xb6,0xcf,0x2b,0x6c,0x5a,0x48, +0x9c,0x71,0x14,0x1a,0x99,0x21,0x00,0x00,0x8b,0xbc,0x44,0xa6,0x0d,0x39,0xc5,0x55, +0x62,0x91,0x6a,0xa6,0x57,0x8d,0x04,0x77,0xda,0xda,0x5b,0xb5,0xc9,0xa0,0x9d,0x0b, +0x65,0x8e,0x58,0x95,0x1d,0x12,0x31,0x2c,0xe5,0x3a,0x48,0x68,0xc6,0x57,0x35,0x8c, +0x9c,0x71,0x14,0x87,0x98,0x21,0x00,0x00,0x71,0xcf,0x19,0xa8,0x51,0xcb,0xa2,0x4d, +0xe6,0x09,0xaa,0xf2,0xe5,0xb2,0xb6,0x2c,0x8c,0xd3,0x53,0x05,0x58,0x76,0xd6,0xdd, +0x76,0x84,0x20,0xda,0x00,0xcd,0xcf,0xd2,0x6d,0x37,0x2d,0xb1,0x45,0x96,0x10,0xf1, +0x9c,0x71,0x14,0x87,0x98,0x21,0x00,0x00,0x38,0xa0,0x93,0x26,0x49,0x52,0x69,0x26, +0x33,0x15,0x7a,0x87,0x19,0x63,0xe9,0xcb,0x6c,0xde,0x1d,0xd5,0xc6,0x12,0xc7,0xa1, +0x8d,0x33,0xd0,0x52,0x07,0x50,0x32,0xbb,0x25,0xc9,0x0d,0x7f,0x25,0x1a,0xae,0xac, +0x9c,0x71,0x14,0x87,0x98,0x21,0x00,0x00,0xce,0x61,0x5e,0x42,0x90,0xbd,0x0f,0x18, +0x1c,0x2a,0x3a,0x6f,0x12,0x94,0xf5,0x33,0x15,0x65,0x51,0xa5,0x70,0x5c,0x59,0xa6, +0x8d,0xc5,0x38,0xde,0xa8,0xaa,0xd8,0x36,0x59,0xae,0x45,0x46,0x61,0x11,0x51,0xf0, +0x9c,0x71,0x14,0x87,0x98,0x21,0x00,0x00,0x18,0x16,0x93,0xd4,0x45,0x76,0x6e,0x6a, +0x74,0x6d,0xd7,0x98,0xee,0x2a,0x06,0xd1,0x5a,0x58,0xde,0x4d,0x51,0x37,0x02,0x41, +0x4e,0x2b,0xb4,0x64,0x1e,0x4d,0x6c,0xd6,0xc9,0x02,0x90,0xc0,0x18,0xad,0xa4,0xa5, +0x9c,0x71,0x14,0x0b,0x98,0x22,0x00,0x00,0xdb,0xc6,0x5a,0x99,0x6c,0x65,0x32,0x32, +0xb5,0x51,0x1b,0xa5,0x33,0x2c,0x5b,0x65,0x62,0xa9,0x83,0xdc,0xc4,0x69,0x4d,0xcc, +0x5b,0xcc,0xa1,0xba,0x55,0x24,0x61,0x41,0x23,0x99,0x13,0x26,0xc1,0xa3,0xb8,0x23, +0x9c,0x71,0x14,0x23,0x98,0x12,0x00,0x00,0x5f,0x20,0xc9,0x02,0xcc,0xb7,0x56,0x2d, +0x45,0x71,0xca,0x35,0x4a,0xb1,0xe5,0x74,0x3e,0xb4,0x55,0x8c,0x2c,0xd1,0x43,0x42, +0x4b,0x58,0x28,0xb8,0xa4,0x83,0xb7,0xde,0xbc,0xeb,0xb2,0xc9,0x24,0xba,0x63,0x0c, +0x9c,0x71,0x14,0xef,0x97,0x21,0x00,0x00,0x79,0x70,0xa4,0x9e,0x4d,0x36,0xa5,0x13, +0x60,0x8c,0x59,0x42,0x58,0x1f,0x6d,0xb0,0xcd,0x1c,0x61,0x50,0xc7,0x18,0xaa,0x96, +0x09,0x7f,0x68,0xd5,0x33,0x95,0x3b,0x0a,0x93,0x93,0x8a,0x56,0xe4,0x87,0xee,0x0e, +0x9c,0x71,0x14,0xef,0x97,0x21,0x00,0x00,0xa8,0x9d,0x0c,0x31,0xad,0xc1,0xc6,0xea, +0xb7,0x0d,0x80,0x40,0xd5,0xa1,0x88,0x3e,0xa4,0x43,0xf5,0xed,0x54,0x60,0xd7,0xdb, +0x32,0xa1,0x16,0xcb,0xf3,0xad,0xbd,0xe4,0x9a,0xbd,0x2c,0x83,0xa5,0x15,0xf9,0xcc, +0x9c,0x71,0x14,0xe2,0x87,0x11,0x00,0x00,0x09,0xa1,0x20,0x4b,0xdc,0x2a,0x86,0xb7, +0x33,0x29,0xbc,0x65,0xbe,0xfa,0xd6,0xf7,0xb5,0x2d,0x15,0xe2,0x90,0x49,0x24,0x67, +0x92,0x16,0xbe,0x50,0x99,0x2d,0x2e,0x51,0xa6,0xa5,0x08,0xb6,0x99,0x4e,0x3b,0x16, +0x9c,0x71,0x14,0x67,0x86,0x01,0x00,0x00,0xf2,0xb9,0x7d,0x00,0xa4,0x96,0x2f,0x14, +0xd6,0xb7,0x21,0x5f,0xa0,0xf2,0x7c,0x31,0x0c,0x36,0x7c,0xd5,0xac,0xe8,0x6d,0xbd, +0x24,0xea,0x8f,0x9c,0xfa,0x75,0x97,0xd8,0x75,0x76,0xbc,0x26,0xb0,0x91,0x89,0x96, +0x9c,0x71,0x14,0xf3,0x86,0x12,0x00,0x00,0x2f,0x64,0xc6,0x7d,0x5b,0xa2,0xa6,0xad, +0x64,0x9b,0xe2,0x35,0xbc,0xf9,0x9b,0x99,0xc9,0xb6,0x08,0x5b,0x2c,0x39,0x41,0xf5, +0x64,0x2f,0xb9,0x36,0x4b,0x1b,0x9c,0x69,0xbc,0xd3,0x13,0xdd,0x81,0x3c,0xdb,0x56, +0x9c,0x71,0x14,0xf3,0x86,0x12,0x00,0x00,0x9d,0xa1,0xb6,0x54,0x23,0x36,0x55,0xb2, +0x39,0x13,0x34,0xc1,0xb5,0xe7,0x1a,0x98,0x4f,0x3c,0x46,0x1b,0xda,0xb1,0xbc,0x9a, +0x54,0xa2,0x66,0x96,0x94,0x9b,0x3f,0x7d,0xb2,0x7b,0xa3,0x36,0x8d,0xb5,0xb5,0x24, +0x9c,0x71,0x14,0xc5,0x85,0x11,0x00,0x00,0x92,0x15,0x9b,0xdd,0xd3,0xd4,0xe9,0xdc, +0x9b,0xe5,0xa5,0x05,0x57,0x0b,0x1a,0x45,0x64,0xd2,0xd6,0x9c,0x35,0x99,0xb5,0x91, +0x53,0x8a,0x3d,0xcb,0x87,0x55,0xce,0xc5,0xbc,0xa1,0xa2,0xa7,0x19,0x27,0x95,0xd3, +0x9c,0x71,0x14,0xc5,0x85,0x11,0x00,0x00,0x49,0xea,0xd3,0x3b,0x60,0x35,0x0c,0x95, +0x73,0x11,0x82,0xe6,0x2b,0x25,0x53,0xc9,0xa6,0x6c,0x91,0x45,0xaa,0x4d,0x97,0xee, +0x1b,0x51,0x49,0x33,0x79,0x14,0x37,0x2d,0xc5,0x25,0x56,0x7e,0x61,0x2a,0x9a,0x99, +0x9c,0x71,0x14,0xc5,0x85,0x11,0x00,0x00,0xc6,0x21,0x3c,0x73,0x64,0xaf,0xe5,0xe8, +0x3c,0x93,0x59,0xa6,0x53,0xaa,0x11,0x38,0x4d,0xa4,0xdd,0xd3,0x78,0xbe,0x2a,0x22, +0x0a,0xc2,0xb1,0xac,0x6d,0x91,0xb3,0xd1,0x98,0xa3,0x24,0x60,0x1c,0xc3,0xf4,0x1c, +0x9c,0x71,0x14,0x40,0x84,0x01,0x00,0x00,0x38,0x78,0xd4,0xaa,0xe5,0x71,0x44,0x69, +0xc9,0x16,0xbe,0x28,0x6c,0x7f,0xa7,0xb7,0x95,0x59,0x58,0xb9,0x6a,0x94,0xa4,0x97, +0x7d,0x3a,0x2b,0xa4,0x5d,0x32,0x62,0xc9,0x88,0xd2,0x46,0xae,0xf4,0x8c,0x2e,0x29, +0x9c,0x71,0x14,0x40,0x84,0x01,0x00,0x00,0xbc,0x0c,0x4a,0x2d,0x01,0x7b,0x2f,0x55, +0x76,0xe6,0x40,0x5c,0xc4,0x18,0x86,0x57,0xa0,0x87,0xd2,0xda,0xa2,0x6c,0x7b,0xc0, +0xe5,0xc0,0x13,0x7a,0xca,0x26,0x8a,0x74,0x96,0x31,0xd5,0x47,0x10,0x63,0xed,0x3e, +0x9c,0x71,0x14,0xd4,0x84,0x12,0x00,0x00,0x4e,0xbc,0x86,0xea,0x96,0x96,0x64,0x4b, +0x43,0x16,0xc1,0x83,0x7b,0x4b,0xbc,0x96,0x95,0x86,0xe4,0xb7,0x4e,0x43,0x83,0xd9, +0xba,0x46,0xa3,0x86,0x27,0x97,0x8a,0x34,0x6a,0xe7,0x26,0xc1,0xa3,0x4b,0xda,0xb6, +0x9c,0x71,0x14,0x58,0x84,0x11,0x00,0x00,0xa2,0x28,0xb7,0xaa,0xa4,0x54,0xc2,0x53, +0xdd,0xd4,0x3e,0x39,0xa5,0x82,0x9b,0x7e,0xad,0x9a,0x85,0x13,0xc1,0x52,0xac,0x4b, +0x10,0xac,0xa6,0x38,0x6b,0xcb,0x5b,0x55,0x33,0xec,0x63,0x37,0xad,0x04,0xca,0x9b, +0x9c,0x71,0x14,0xac,0x83,0x11,0x00,0x00,0x73,0xd9,0x3a,0x0e,0x1b,0xc0,0xc1,0x2c, +0xa8,0xdb,0xb8,0xba,0xa9,0x1d,0x50,0x63,0x69,0xc3,0xf2,0x14,0x32,0x25,0xb4,0x13, +0x9c,0x68,0x66,0x49,0x7c,0x54,0xbf,0xad,0x9d,0x02,0x1a,0xc4,0xd1,0x99,0xdd,0xda, +0x9c,0x71,0x14,0xac,0x83,0x11,0x00,0x00,0x6d,0x43,0x54,0x09,0xdb,0x2c,0xac,0xa3, +0x5d,0xda,0x5b,0x51,0x58,0xdb,0x51,0xbc,0x9a,0x4d,0x5c,0xe2,0xcf,0x4d,0xba,0xbd, +0x5b,0x77,0x1e,0x44,0x5b,0x1c,0x28,0x46,0x22,0xb5,0xe2,0x4c,0xb5,0x48,0x22,0xe5, +0x9c,0x71,0x14,0xa5,0x82,0x02,0x00,0x00,0xb7,0xce,0xbd,0x9b,0x46,0xdb,0x2c,0xeb, +0xad,0x4f,0x84,0x4b,0x04,0xc2,0x71,0x24,0xf5,0x11,0xf6,0x4f,0x3c,0x96,0xc7,0x44, +0xd0,0xaf,0xf0,0xcd,0xc6,0xd0,0xe6,0x22,0xec,0xb8,0x55,0x94,0x61,0x25,0x57,0x09, +0x9c,0x71,0x14,0x29,0x82,0x01,0x00,0x00,0x23,0xb0,0xd1,0x44,0xd8,0x2b,0x96,0xb6, +0x29,0xaa,0xa5,0x31,0x6d,0xae,0x55,0xf0,0xcf,0x2d,0xd1,0x68,0xa7,0xaf,0x86,0x1b, +0x4c,0x26,0xd7,0xb0,0xa9,0x36,0x1a,0x59,0x44,0xe3,0x27,0x95,0xe7,0x6d,0x61,0x74, +0x9c,0x71,0x14,0xbd,0x82,0x12,0x00,0x00,0xf7,0xa3,0xae,0xe3,0xb7,0xbd,0xd3,0x97, +0x84,0x48,0x36,0x95,0x51,0x03,0x28,0x11,0xcd,0x63,0x9d,0x18,0x79,0x2b,0x6b,0xaa, +0xc9,0xe5,0x43,0x3e,0xc5,0xb4,0xcc,0x3b,0xb9,0x2b,0x47,0x53,0xac,0x82,0x54,0x37, +0x9c,0x71,0x14,0x93,0x81,0x01,0x00,0x00,0x16,0xef,0x62,0xe9,0x4a,0x63,0x54,0xaa, +0x19,0xc2,0xd3,0xb5,0x1e,0x76,0xb5,0xd5,0xe3,0x2a,0x55,0xcb,0x68,0x22,0x83,0x2e, +0x01,0x1a,0x21,0x52,0x59,0xcf,0x52,0x25,0x08,0xe1,0x71,0xc5,0x5c,0x6e,0x32,0x12, +0x9c,0x71,0x14,0x8b,0x81,0x11,0x00,0x00,0xdc,0xa3,0xbb,0x52,0xc4,0x7a,0xe3,0xe4, +0x2c,0xb3,0x20,0x4b,0x42,0x0c,0xb6,0x43,0x42,0xa7,0xb3,0xb8,0xb4,0x3a,0xad,0xb4, +0x3b,0xe0,0xb4,0xdc,0x33,0x54,0x8e,0x4b,0x15,0x3a,0xc3,0x29,0x28,0xb1,0xe4,0x3c, +0x9c,0x71,0x14,0x82,0x80,0x02,0x00,0x00,0x36,0x7c,0x16,0x88,0x4b,0xa3,0x2b,0xed, +0x0c,0xaf,0xe1,0x67,0x9c,0xed,0x78,0xa0,0x0a,0x76,0x5f,0x9b,0x35,0x48,0x71,0xfc, +0x9e,0x2c,0x95,0xe5,0x78,0x40,0x90,0xc7,0xbc,0x3a,0x8b,0xde,0x3b,0xfd,0x6d,0x76, +0x9c,0x71,0x14,0x0e,0x80,0x01,0x00,0x00,0xb0,0x34,0xd7,0x86,0x5e,0x43,0x56,0x02, +0x45,0x52,0x26,0x56,0x84,0x88,0x6f,0x7e,0xa5,0x9b,0x4d,0x66,0xd8,0x07,0x0d,0xb5, +0x75,0xbd,0xd9,0x08,0xa3,0x57,0x53,0x05,0x92,0xc1,0x1d,0x23,0x95,0xb3,0xc2,0x7a, +0x9c,0x71,0x14,0x82,0x80,0x02,0x00,0x00,0x6d,0x35,0xfa,0x4a,0x78,0xce,0xf8,0xfd, +0xc6,0x7d,0xc8,0x88,0x59,0xaa,0x8c,0x63,0x56,0x53,0x67,0x6b,0x24,0x4b,0x53,0x32, +0x9c,0x5d,0xa7,0x99,0x49,0x94,0xc3,0x79,0xbd,0xa5,0xb0,0xd0,0x26,0x0a,0x93,0x38, +0x9c,0x71,0x14,0x0e,0x80,0x01,0x00,0x00,0x73,0xe6,0xe4,0x2d,0x5a,0x28,0x16,0x52, +0xd4,0x0e,0x50,0x55,0x68,0x45,0x5f,0xb6,0x87,0xad,0x4f,0x5a,0xd4,0x66,0xeb,0x56, +0x61,0x83,0x45,0x35,0x02,0x54,0x2e,0xa6,0x82,0xa7,0x65,0x45,0x75,0x67,0x54,0x5f, +0x9c,0x71,0x14,0x0e,0x80,0x01,0x00,0x00,0xa8,0xa5,0x7c,0xd2,0x61,0xd5,0x66,0x4b, +0xed,0x60,0x91,0x85,0xb5,0xe4,0x52,0x37,0x67,0x62,0xb0,0x58,0x3d,0x74,0xc6,0x7c, +0x67,0x9a,0xa4,0x7c,0x36,0x5a,0xd3,0x97,0x1c,0x57,0x45,0x9e,0x46,0x96,0xc5,0x71, +0x9c,0x71,0x14,0x0e,0x80,0x01,0x00,0x00,0x41,0xd5,0xc2,0xe3,0x55,0x38,0x22,0x15, +0xc6,0xa6,0x8c,0xd6,0xab,0x87,0x5e,0xcf,0x46,0x4c,0x92,0x51,0xa8,0x95,0x37,0x9b, +0x6d,0x4d,0x86,0xc3,0x3e,0x59,0x36,0x25,0xf5,0x31,0x7a,0x80,0x06,0x4a,0xcb,0x61, +0x9c,0x71,0x14,0x82,0x80,0x02,0x00,0x00,0xc8,0x99,0x0c,0xa0,0xd9,0xb0,0x76,0x78, +0x5c,0x48,0x59,0x35,0x93,0xb3,0x77,0x36,0x86,0x84,0xc4,0x62,0x74,0xb6,0x8a,0x0d, +0x6e,0xc0,0x59,0x7c,0x85,0xa8,0xb5,0xd7,0xf9,0x03,0x7f,0x65,0x05,0xe4,0x40,0x82, +0x9c,0x71,0x14,0x0e,0x80,0x01,0x00,0x00,0x39,0x36,0x74,0x81,0x6a,0x6b,0x26,0x89, +0x55,0x66,0xb7,0x36,0x4c,0x4a,0x4a,0xb9,0x15,0x59,0x8e,0x69,0x70,0x07,0xa4,0xdb, +0x5c,0x3d,0xa6,0x04,0x63,0x4b,0x63,0x85,0x28,0xaa,0x5e,0xad,0x76,0xab,0xf7,0x55, +0x9c,0x71,0x14,0xc0,0x70,0x01,0x00,0x00,0xf3,0xe6,0xbb,0xf3,0x4e,0x74,0x44,0xb2, +0xee,0x6c,0x07,0x37,0xe0,0xc8,0x57,0x3b,0xb5,0xe8,0x29,0x54,0xc7,0xe4,0xdf,0x19, +0x77,0xf1,0xc6,0x2c,0x8a,0xa3,0x85,0xb8,0xe4,0x1b,0x7d,0x15,0xb6,0x91,0x0b,0x69, +0x9c,0x71,0x14,0x4c,0x70,0x02,0x00,0x00,0x34,0x37,0x57,0x2a,0x67,0xb4,0xd7,0xae, +0x2e,0x6b,0xec,0x7a,0x4c,0xdf,0x9c,0x94,0x6b,0x15,0x3f,0x70,0x24,0x96,0x21,0x74, +0x91,0x30,0x35,0x06,0x5d,0x74,0xa3,0x75,0x0d,0x38,0x8f,0xe3,0xe6,0x2d,0x01,0x3e, +0x9c,0x71,0x14,0xd8,0x70,0x11,0x00,0x00,0x9f,0x19,0x56,0x3d,0x85,0x34,0x1c,0xf2, +0x06,0x38,0x2f,0xd9,0x85,0xbe,0x0e,0x94,0x1e,0xcc,0x41,0xb0,0xda,0x1c,0xec,0xf1, +0xfe,0xa7,0x58,0x47,0x26,0x61,0x43,0x1b,0x32,0xb2,0x37,0x32,0x62,0xf5,0x54,0xe0, +0x9c,0x71,0x14,0xc0,0x70,0x01,0x00,0x00,0x87,0x95,0x0b,0x57,0x5d,0xcf,0x25,0x1c, +0xb7,0x5c,0xac,0x86,0x77,0xe1,0x65,0x51,0x17,0x33,0x67,0x4f,0x36,0xa4,0xa5,0x1b, +0x63,0x7c,0x95,0xca,0x7f,0x6f,0xc3,0xa5,0x5c,0x60,0x5b,0xaf,0x36,0x88,0x70,0x5b, +0x9c,0x71,0x14,0x54,0x70,0x12,0x00,0x00,0x5d,0x9e,0xf4,0x1d,0x0e,0x3c,0xee,0xb5, +0x05,0x12,0x74,0xe2,0xe9,0xbe,0x10,0xb8,0x5b,0x0b,0xfa,0x70,0xaf,0x1a,0xb8,0xea, +0x33,0x68,0xe1,0x14,0xcd,0xc7,0x44,0x23,0x55,0x11,0x76,0x6e,0xe3,0x39,0x1d,0xee, +0x9c,0x71,0x14,0x69,0x60,0x02,0x00,0x00,0xdb,0x4c,0xdf,0x06,0xbe,0xdc,0x2c,0x1a, +0x60,0xb0,0x64,0xac,0x42,0xe8,0xc5,0x17,0x0c,0x02,0x6a,0xc8,0x57,0x4e,0x09,0x32, +0xc3,0xc7,0x8b,0xee,0x0a,0xba,0xd5,0xea,0x9a,0xba,0xb6,0x72,0xeb,0xe4,0x0e,0xe3, +0x9c,0x71,0x14,0xe5,0x60,0x01,0x00,0x00,0x26,0xed,0xd2,0xdc,0x88,0x52,0xa9,0xd8, +0x6a,0xcc,0xb6,0x4b,0xdd,0x1a,0xdd,0xcd,0x4a,0x5a,0xe8,0xc6,0x7f,0x4e,0x45,0x0e, +0xc4,0x35,0xe9,0x23,0x64,0xc9,0x51,0x4c,0x77,0xc6,0xcc,0xa7,0xab,0xac,0x2f,0x3b, +0x9c,0x71,0x14,0xe5,0x60,0x01,0x00,0x00,0xc5,0x72,0xaa,0xe2,0xdf,0x86,0x6a,0xe5, +0xee,0xd1,0x43,0x8b,0xc4,0x02,0xc1,0x53,0x0d,0x07,0x5e,0xea,0x9b,0xee,0x3b,0x56, +0xbd,0xbc,0x53,0x4a,0xbc,0xbf,0x8c,0x0a,0x16,0xa0,0x88,0x50,0x49,0x54,0xa4,0xdb, +0x9c,0x71,0x14,0x8a,0x50,0x01,0x00,0x00,0x2c,0xcb,0xb6,0x42,0xe9,0xa2,0xec,0x1d, +0x2e,0xd0,0xe4,0x92,0xdc,0xe6,0x99,0x9f,0x8a,0x46,0x42,0xe4,0x35,0xcc,0xa2,0x47, +0x42,0x34,0x0b,0x35,0xe8,0xc7,0x95,0x0c,0xab,0xfa,0xa1,0xd4,0x32,0x5c,0x76,0xdb, +0x9c,0x71,0x14,0x92,0x50,0x11,0x00,0x00,0xa1,0xa1,0x27,0x11,0x64,0x46,0xa9,0x53, +0x49,0x50,0x3c,0xdb,0x25,0xe6,0x16,0x8a,0x66,0xda,0xf9,0xad,0xc4,0x65,0x4b,0xe4, +0xe0,0x9f,0xe8,0x77,0xa9,0x75,0x57,0xa0,0x74,0x3d,0x90,0x48,0x2a,0xd5,0xe5,0xba, +0x9c,0x71,0x14,0xaf,0x40,0x01,0x00,0x00,0x85,0x45,0xcc,0x61,0x68,0xe7,0x83,0x6e, +0x41,0x59,0xbd,0x95,0x67,0xd2,0x57,0x44,0xd4,0x21,0xfd,0xa8,0x25,0x11,0xe4,0x5d, +0x6b,0x7c,0x12,0x0b,0x2d,0xb3,0xd2,0xd7,0x6d,0x69,0x61,0xb8,0x16,0x98,0xa5,0x65, +0x9c,0x71,0x14,0x23,0x40,0x02,0x00,0x00,0x53,0xd5,0xd3,0xa9,0x76,0x33,0xda,0xd4, +0xd0,0x8d,0x74,0xd4,0xaa,0x35,0x70,0xc1,0x18,0x8c,0x2d,0x7b,0xb2,0xd7,0xc8,0x96, +0x7c,0x64,0x6b,0xc4,0x55,0xc2,0x42,0x97,0x35,0x72,0x56,0x75,0xd3,0xb9,0x80,0x83, +0x9c,0x71,0x14,0x54,0x30,0x01,0x00,0x00,0xe6,0xd6,0x1f,0x10,0x7c,0xd8,0x5a,0xf9, +0x42,0x1c,0x58,0xa6,0xe2,0x76,0x4b,0x11,0x15,0xb3,0xfa,0x5b,0x68,0x55,0x1a,0x04, +0x5f,0xc8,0xd7,0x1d,0x31,0x96,0xc0,0x25,0x69,0x44,0x2a,0x63,0xe5,0xf4,0x45,0x59, +0x9c,0x71,0x14,0x54,0x30,0x01,0x00,0x00,0x37,0x64,0x94,0x55,0x4b,0x72,0xd9,0x39, +0x85,0x6a,0xb6,0x25,0x7c,0x91,0x56,0xb8,0x86,0x09,0xd2,0x60,0x6f,0x16,0xb5,0x75, +0x2f,0x40,0x94,0x35,0x09,0x62,0x61,0x14,0xb9,0x2d,0xa7,0xa0,0x5a,0xab,0x75,0x57, +0x9c,0x71,0x14,0x71,0x20,0x01,0x00,0x00,0xe1,0x2e,0x1a,0x58,0x0f,0x5f,0xb3,0x54, +0xc2,0x6f,0x23,0xa3,0xc2,0xc9,0x6a,0x7a,0xc3,0x49,0x45,0x05,0xb8,0x8a,0xfd,0x24, +0xd1,0xd7,0xaa,0xa8,0x80,0xef,0x69,0x8d,0x14,0x8c,0xec,0x2d,0x2a,0xc2,0x13,0x2b, +0x9c,0x71,0x14,0x71,0x20,0x01,0x00,0x00,0x68,0xc4,0xf9,0xc2,0xc8,0xb2,0xad,0x0c, +0xea,0xe6,0xd7,0xa2,0x0a,0x18,0x35,0x5e,0x2d,0x05,0x04,0x59,0x30,0xb1,0xb4,0x0a, +0xe3,0x85,0x92,0xd9,0x6c,0xad,0xb4,0xb2,0x9c,0x52,0xf3,0xc8,0xb5,0x37,0x54,0xcb, diff --git a/config/_default_cfg_src_/res/en/SOUND_GSOUND_MIC_OPEN.txt b/config/_default_cfg_src_/res/en/SOUND_GSOUND_MIC_OPEN.txt new file mode 100644 index 0000000..01d6d41 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_GSOUND_MIC_OPEN.txt @@ -0,0 +1,96 @@ +0x9c,0x71,0x14,0x5c,0xdb,0x99,0x89,0x88,0x7e,0xed,0x57,0xee,0xd5,0x83,0x0d,0x57, +0xeb,0x51,0xa5,0x88,0x65,0x6c,0x19,0x41,0x0d,0x5b,0x0e,0xd5,0x88,0xed,0x53,0x8e, +0xd5,0x90,0xed,0x5b,0x4e,0xd5,0x4c,0xed,0x56,0x2e,0xd5,0xbe,0xed,0x57,0x6e,0xd5, +0x9c,0x71,0x14,0x1f,0xc6,0x42,0x00,0x00,0x09,0xd0,0x1c,0xde,0x11,0xcb,0x0e,0x90, +0xab,0x35,0x75,0xf2,0x4f,0xb3,0xcd,0x47,0x88,0x52,0x36,0x59,0xea,0x52,0xda,0x20, +0x71,0x06,0xbd,0xda,0x27,0x49,0xe5,0x9c,0x92,0x79,0xdd,0x4b,0xee,0xdf,0x14,0xac, +0x9c,0x71,0x14,0x93,0xc6,0x41,0x00,0x00,0x75,0x05,0x91,0x9d,0x8d,0xc4,0x55,0x2c, +0x11,0xe0,0x19,0x26,0xd7,0x4e,0xe5,0xeb,0xbd,0x55,0x20,0xd2,0x2e,0xdd,0x8d,0xad, +0x68,0x9f,0x8e,0xd1,0x44,0x21,0x9a,0x69,0x0d,0xc2,0x54,0x34,0x25,0x94,0xde,0x6a, +0x9c,0x71,0x14,0xdb,0xc6,0x31,0x00,0x00,0xe4,0x63,0x57,0xb8,0x6c,0x21,0xe8,0x5b, +0x82,0xc5,0xbe,0x8d,0x12,0x4d,0x95,0x71,0xb3,0x1e,0x35,0xa9,0x5b,0x8c,0x53,0x2a, +0x89,0xcd,0x6d,0x1a,0x0c,0x94,0x1f,0x9f,0x19,0x43,0x28,0xd5,0x94,0x63,0xf5,0x2a, +0x9c,0x71,0x14,0x4f,0xc6,0x22,0x00,0x00,0x4d,0xe7,0x4d,0x7c,0x33,0x82,0x1a,0xb2, +0xac,0x0b,0xac,0x58,0x4b,0xba,0x1a,0x32,0xaf,0x36,0xc6,0x2a,0xd4,0xb9,0xc6,0x61, +0x85,0x3c,0x54,0x4b,0xed,0x22,0xa0,0x9a,0xc2,0xeb,0xaa,0x89,0x60,0xac,0x8a,0xc9, +0x9c,0x71,0x14,0x4c,0xc6,0x20,0x00,0x00,0x4e,0xd3,0x55,0x46,0xea,0xc9,0xa4,0x98, +0x34,0xd9,0x34,0x63,0x4a,0x3e,0xd4,0xb6,0x14,0x53,0xf1,0x79,0x6d,0x70,0xbc,0x99, +0xe7,0x69,0xd0,0x64,0x36,0x94,0xb5,0xa9,0x69,0xd8,0xf8,0x3b,0x1f,0x98,0x7a,0xe7, +0x9c,0x71,0x14,0x51,0xc5,0x11,0x00,0x00,0xbf,0x12,0x85,0x70,0x65,0x57,0xf7,0x1b, +0xde,0x71,0x85,0x83,0x23,0xf2,0x71,0x9c,0x74,0x0b,0x08,0xc9,0x4a,0x90,0xd6,0xcb, +0x79,0xbd,0x61,0x17,0x10,0x28,0x4b,0x2c,0x5a,0xb7,0x09,0x9c,0x85,0x14,0x55,0xb4, +0x9c,0x71,0x14,0xaa,0xb5,0x11,0x00,0x00,0x85,0xfb,0x0e,0xd9,0x25,0x3d,0x8c,0x53, +0x83,0x30,0xe8,0x69,0x48,0xe0,0x54,0x10,0xa3,0x2a,0xef,0x65,0xd4,0xcc,0x52,0x29, +0x2d,0x5e,0x37,0x2e,0xda,0x14,0x65,0x46,0xc2,0x1e,0xc2,0xce,0x2e,0xdb,0x10,0x95, +0x9c,0x71,0x14,0xaa,0xb5,0x11,0x00,0x00,0x15,0x5b,0x98,0x6b,0x6d,0xe6,0x56,0x54, +0x4c,0xe8,0x3b,0xee,0xdd,0xe2,0x96,0x8f,0x07,0x01,0x9e,0x2c,0xa7,0xb0,0x2c,0xf5, +0x09,0x2d,0x93,0x55,0xd3,0x50,0xe3,0x5f,0x16,0xc0,0xa8,0x28,0xe8,0x9c,0x2a,0xe9, +0x9c,0x71,0x14,0xaa,0xb5,0x11,0x00,0x00,0xb1,0xcd,0x52,0x29,0x91,0x80,0x74,0xdd, +0xb9,0x6a,0x4e,0x4c,0x53,0xfe,0xec,0xd3,0x27,0x19,0x20,0xad,0x23,0xa0,0x99,0xf3, +0x08,0xc9,0xd2,0xa3,0x85,0x32,0x5c,0xf1,0x5d,0x9e,0x09,0x73,0x0a,0xc2,0xe6,0x84, +0x9c,0x71,0x14,0xaa,0xb5,0x11,0x00,0x00,0xb7,0xec,0xdb,0x08,0xed,0x2d,0x19,0x17, +0xbf,0x2d,0xd4,0x5a,0xc5,0x78,0xc9,0x43,0x2c,0xcc,0x86,0x75,0x93,0x0d,0x12,0xc9, +0xed,0x99,0xb0,0x5c,0x49,0x49,0x42,0x13,0x25,0xdf,0x11,0xcf,0x61,0x17,0x64,0xca, +0x9c,0x71,0x14,0x11,0xbb,0x65,0x00,0x00,0x35,0x7d,0xda,0xf7,0xdd,0xae,0x7d,0xd3, +0x87,0xdd,0x77,0x7d,0xdc,0xa7,0xdd,0x5f,0x7d,0xd4,0x67,0xdd,0xbd,0x7d,0xd9,0x57, +0xdd,0x37,0x7d,0xd9,0x27,0xdd,0xc7,0x81,0xd4,0xb7,0x4d,0xba,0x99,0xac,0xc0,0xf4, +0x9c,0x71,0x14,0x98,0xbc,0x33,0x00,0x00,0x63,0x63,0xa0,0x32,0x24,0xbc,0x4c,0x27, +0x04,0x65,0x59,0x28,0x56,0x25,0xf5,0xb5,0xa0,0x17,0xe5,0x55,0x24,0xb9,0x5d,0x9b, +0x55,0x7b,0x57,0x54,0x4a,0x15,0x9d,0x5b,0x59,0xa2,0xd5,0x79,0x41,0x53,0xec,0xc5, +0x9c,0x71,0x14,0xe3,0xbb,0x32,0x00,0x00,0xd2,0x0e,0x57,0xaf,0x84,0x35,0x0e,0x5b, +0xed,0xa5,0x87,0x42,0x56,0x71,0xf5,0x68,0x72,0x1b,0x50,0xa2,0x7f,0xe7,0x03,0x23, +0x01,0xcd,0x33,0x57,0xe6,0x36,0x52,0x0e,0x59,0x1e,0xf5,0x9d,0x9e,0x57,0x3c,0x65, +0x9c,0x71,0x14,0x77,0xbb,0x21,0x00,0x00,0x48,0x68,0x9c,0x7c,0xda,0x7c,0xf5,0x14, +0x20,0xc2,0xb3,0xeb,0x08,0x85,0xf4,0x67,0x94,0xd6,0x9f,0x25,0xb3,0x4b,0x57,0xab, +0x04,0x41,0x17,0x3c,0x29,0xd4,0x7e,0x2b,0xa5,0x7c,0xd3,0x8e,0x33,0x39,0xc1,0x0d, +0x9c,0x71,0x14,0x6f,0xbb,0x31,0x00,0x00,0x74,0xe5,0xc4,0xea,0x42,0xc2,0x51,0xa7, +0xab,0x29,0x49,0xcd,0x2a,0xc6,0xcb,0x87,0x1c,0xb6,0xc5,0x83,0x68,0xaf,0x4b,0x28, +0xcb,0x7a,0x70,0x44,0x55,0x5b,0xba,0xe0,0x38,0x02,0x8a,0x5d,0x8f,0xa8,0x87,0x12, +0x9c,0x71,0x14,0xcf,0xaa,0x21,0x00,0x00,0xb8,0x10,0xd6,0xca,0xed,0x21,0x97,0x1f, +0x32,0x91,0x78,0xf9,0x12,0x50,0x49,0xc4,0xd8,0xd9,0x75,0xe9,0x59,0x5a,0xd4,0xed, +0xa9,0xda,0x08,0xd7,0x7e,0xcd,0x1f,0x39,0x6e,0x18,0xb2,0x82,0xb0,0x84,0x31,0xea, +0x9c,0x71,0x14,0xe7,0xaa,0x11,0x00,0x00,0x83,0xf8,0x1b,0xa1,0x09,0x6f,0x57,0x43, +0x04,0x3a,0xe0,0x9f,0x67,0xbf,0x04,0x30,0x8a,0x1b,0x36,0x86,0x99,0x2e,0x46,0x3b, +0x21,0x50,0xe5,0x6d,0x28,0xd5,0x76,0x6d,0x52,0xba,0x14,0xce,0xc6,0x98,0x65,0x25, +0x9c,0x71,0x14,0x43,0xaa,0x22,0x00,0x00,0x4c,0x31,0x58,0x0d,0xad,0xb5,0x2e,0xe7, +0x1a,0xa5,0x36,0x80,0x4d,0x35,0x29,0x7d,0xc6,0x83,0xe2,0xcd,0xa5,0xc2,0xc9,0xb5, +0xcd,0x65,0x74,0xd5,0x4b,0x29,0xc4,0x32,0x97,0xac,0x8c,0x38,0x4a,0x9b,0xe9,0x12, +0x9c,0x71,0x14,0x73,0xaa,0x02,0x00,0x00,0x88,0x4a,0x35,0x7a,0x3a,0x7a,0x64,0xba, +0xe9,0xd3,0x75,0x55,0x54,0x1b,0xc3,0xc5,0xb1,0x27,0xdd,0xbc,0x4b,0x9d,0xb9,0xa5, +0xd4,0x99,0xaf,0x46,0x93,0xda,0x59,0xd2,0xbb,0xd2,0x23,0x7b,0xde,0xa4,0x3a,0x7b, +0x9c,0x71,0x14,0x32,0x99,0x11,0x00,0x00,0xe4,0x53,0x59,0x24,0xc4,0x3d,0x14,0x56, +0xef,0xa5,0xd6,0x05,0x56,0xb6,0x65,0x17,0x35,0x5f,0x32,0xa9,0x81,0xec,0x52,0x50, +0x78,0xaa,0x72,0x2b,0x12,0x19,0x5a,0xbe,0x53,0xad,0xc5,0xe9,0x10,0x97,0x87,0x24, +0x9c,0x71,0x14,0xa6,0x99,0x02,0x00,0x00,0x1a,0x17,0x5d,0x25,0x27,0x95,0xc8,0x84, +0x49,0xd8,0x6e,0x6f,0x3c,0xd1,0x06,0x6e,0x60,0x72,0x43,0x56,0xe3,0x30,0x78,0x4e, +0x17,0x33,0x13,0x79,0xce,0x87,0xae,0xa5,0x65,0xf4,0x28,0x43,0xd2,0xad,0xc1,0xc9, +0x9c,0x71,0x14,0x2a,0x99,0x01,0x00,0x00,0x7a,0x33,0x22,0xbc,0xf2,0xbf,0x68,0xc9, +0x66,0x0b,0x4e,0x54,0xc6,0xd3,0x0a,0xc6,0x8e,0x17,0x02,0xcd,0x34,0xda,0xbc,0xf5, +0xc5,0x86,0xaa,0x93,0xf5,0x01,0x92,0xef,0xda,0xe1,0x4b,0x65,0x62,0x44,0xae,0x5b, +0x9c,0x71,0x14,0xaf,0x98,0x11,0x00,0x00,0xcc,0x8c,0x47,0xbf,0xd5,0x39,0x07,0x6b, +0x16,0x19,0x97,0x3e,0x55,0x81,0xf6,0x6c,0x76,0x6b,0xb8,0x35,0x75,0x6e,0x53,0xda, +0x85,0xc0,0x37,0x58,0x7e,0x35,0x4b,0x89,0x58,0xcf,0x72,0xa7,0x18,0x56,0xbc,0xa4, +0x9c,0x71,0x14,0xb7,0x98,0x01,0x00,0x00,0x50,0xe8,0x4c,0x04,0xc3,0x7e,0x78,0x34, +0x6c,0x96,0xa4,0x6d,0xd9,0x59,0xd4,0x5f,0x15,0x96,0xcf,0x2b,0xb3,0xca,0x07,0x77, +0x1a,0x4b,0x55,0xab,0x15,0xea,0x89,0x2b,0x45,0x64,0xca,0x86,0x74,0x0a,0x41,0x04, +0x9c,0x71,0x14,0x06,0x88,0x12,0x00,0x00,0x5f,0x97,0x33,0x09,0x2a,0xe2,0x44,0xb8, +0x0c,0x8d,0x21,0x38,0xcb,0x8a,0xea,0xa9,0x74,0xb4,0xd5,0xea,0x5a,0xbc,0xad,0x23, +0x8b,0x74,0xba,0xb2,0x55,0xeb,0xcf,0x7c,0xb9,0x3a,0x2b,0x3e,0x42,0xb8,0x5c,0x02, +0x9c,0x71,0x14,0x76,0x87,0x02,0x00,0x00,0xbb,0x8c,0x76,0x5d,0x57,0x3c,0x4a,0x6d, +0x29,0x86,0x83,0x78,0x73,0x58,0x48,0xa8,0xec,0x5a,0x42,0xe8,0x58,0x2e,0x55,0xc6, +0xb5,0xc9,0x07,0x87,0x6f,0x38,0x37,0x9d,0x5b,0xd4,0x67,0x90,0x55,0x34,0xb1,0x37, +0x9c,0x71,0x14,0x76,0x87,0x02,0x00,0x00,0x81,0x75,0x8b,0x41,0x04,0x6c,0x58,0x74, +0x6c,0x28,0xc4,0x22,0x68,0x36,0xd7,0x43,0x8e,0x59,0xe6,0x66,0xa0,0x2f,0x85,0xfb, +0x45,0x60,0xe1,0x6b,0xb1,0x3b,0x79,0x69,0x74,0x52,0x28,0xb0,0xc7,0x58,0xec,0xe6, +0x9c,0x71,0x14,0x34,0x77,0x01,0x00,0x00,0x2c,0x9d,0xa7,0xce,0x99,0xd7,0x1b,0x46, +0x1d,0x39,0x23,0xbf,0x9e,0xa2,0xc5,0x86,0xdf,0x92,0x51,0xcb,0xa7,0xdc,0x6b,0x63, +0x15,0x50,0x3a,0x74,0xe5,0x46,0xd9,0x22,0x67,0x95,0xc6,0x29,0xaa,0x8c,0x2c,0x73, +0x9c,0x71,0x14,0x25,0x76,0x02,0x00,0x00,0x99,0xcd,0x54,0x41,0x78,0x76,0xf6,0x5c, +0x40,0xc4,0x69,0xe0,0x63,0xe3,0x8c,0xc9,0x2c,0x88,0x7e,0x66,0x3d,0x10,0x69,0x8e, +0x89,0xaa,0xa8,0x75,0xf3,0xd6,0x59,0x57,0x7c,0x19,0xa8,0x7a,0x68,0x94,0x09,0xe5, +0x9c,0x71,0x14,0x00,0x66,0x02,0x00,0x00,0xdb,0x9c,0xea,0xe8,0xcc,0x2c,0x4a,0xa6, +0xac,0x68,0xe4,0x38,0xf6,0x1a,0xd3,0x1c,0x70,0xce,0x66,0x8f,0x91,0xb1,0x32,0x14, +0x11,0x9d,0xb7,0x3c,0x15,0xee,0x51,0x7e,0xb4,0x19,0xe7,0xde,0x4b,0x17,0xcb,0x73, +0x9c,0x71,0x14,0x36,0x65,0x01,0x00,0x00,0x24,0x91,0x7b,0xdd,0x52,0xa4,0xc6,0x64, +0x31,0xc8,0x6b,0x72,0x4c,0xb0,0xc7,0x6d,0xe2,0xd3,0x4b,0x5b,0xc8,0xb0,0x88,0xfe, +0x43,0x3b,0x11,0x89,0x06,0xaa,0xb1,0x26,0xb6,0x24,0x05,0x51,0xd4,0x6b,0xe9,0xd4, diff --git a/config/_default_cfg_src_/res/en/SOUND_GSOUND_NC.txt b/config/_default_cfg_src_/res/en/SOUND_GSOUND_NC.txt new file mode 100644 index 0000000..7e2889b --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_GSOUND_NC.txt @@ -0,0 +1,648 @@ +0x9c,0x71,0x14,0x97,0x40,0x02,0x10,0x00,0x7f,0xbe,0xf7,0xfb,0xef,0x7f,0xc1,0x07, +0xf4,0x11,0x7e,0x4d,0x57,0xf5,0xf5,0x7e,0xb5,0x37,0xcc,0x93,0x7b,0xb3,0x17,0xf4, +0xf2,0x82,0x45,0x18,0x43,0x51,0x7c,0x50,0xe6,0x82,0x0a,0x4f,0x02,0x73,0x51,0x45, +0x9c,0x71,0x14,0xe0,0x70,0x12,0x10,0x00,0x72,0xb3,0x16,0xed,0xa1,0x6a,0x25,0xa6, +0x4c,0x4b,0x5f,0x2b,0x35,0x95,0x3b,0x52,0x23,0x34,0x9c,0x43,0x41,0xad,0x43,0xac, +0x44,0x33,0x3a,0xb2,0xab,0xc4,0x21,0xc5,0xc1,0x72,0xbb,0x0e,0x30,0x30,0x5c,0x92, +0x9c,0x71,0x14,0xe1,0x71,0x22,0x00,0x00,0x04,0x37,0xc0,0x3c,0x9d,0x06,0xa7,0xa0, +0xd4,0x67,0x16,0xa6,0x42,0x4b,0x73,0x32,0x37,0x84,0x4b,0x65,0x59,0x4a,0xe6,0xe4, +0x4a,0x86,0xd6,0x69,0xb5,0x6a,0xb2,0xc8,0x1c,0xab,0x60,0xda,0x5a,0xde,0xc9,0xcc, +0x9c,0x71,0x14,0x94,0x94,0x54,0x00,0x00,0x9f,0x77,0x7a,0x27,0x87,0xa5,0x87,0x7a, +0x87,0x77,0xa6,0x56,0x7a,0x97,0x75,0xae,0x36,0x8b,0x27,0x66,0xb1,0xa7,0x8c,0x5d, +0x97,0xd6,0xa3,0x4b,0x92,0xda,0x92,0x68,0x3a,0xd9,0x8c,0xbd,0xb8,0x4b,0xa6,0x79, +0x9c,0x71,0x14,0x1f,0xb8,0x65,0x10,0x00,0x8c,0x6c,0x28,0xd8,0x2b,0x8f,0x75,0x38, +0xe7,0xab,0x8e,0x84,0x39,0x28,0xb3,0x94,0x84,0xb8,0xe6,0xc3,0x8f,0xa5,0x37,0x57, +0x65,0x3c,0xb5,0xa1,0x26,0x65,0x86,0xdd,0xaf,0xaa,0xcb,0xb2,0xbf,0x25,0x4a,0xcc, +0x9c,0x71,0x14,0x87,0xc9,0x97,0x30,0x00,0x8a,0x6c,0xbb,0x78,0x43,0x76,0x6c,0xc1, +0x69,0x3a,0x2d,0x24,0x5a,0xea,0x10,0xcf,0xa3,0xd6,0xbb,0xa9,0x4c,0xb3,0xd9,0xc9, +0xa8,0xcc,0xcc,0x67,0x6a,0xc1,0x41,0xac,0x56,0x28,0xd1,0x55,0x5e,0x45,0xae,0x50, +0x9c,0x71,0x14,0x87,0xc9,0x97,0x30,0x00,0xb0,0x93,0xea,0xea,0xd9,0x55,0x74,0x65, +0x65,0xd1,0xc9,0x8c,0x5b,0xd4,0x52,0x41,0x5b,0xc2,0xa4,0xd3,0x4e,0x2d,0x97,0xac, +0x65,0xab,0x6b,0x39,0x88,0xd4,0x63,0x64,0x26,0x55,0xd5,0xbd,0x8b,0x9b,0x94,0x44, +0x9c,0x71,0x14,0x01,0xc9,0x98,0x30,0x00,0x50,0x67,0x52,0xf4,0x88,0x4a,0x4b,0x46, +0xfb,0xdc,0xb0,0x4b,0x3a,0x56,0x8a,0x69,0x3b,0x45,0xf3,0x89,0xb9,0x6a,0x5c,0xa1, +0x68,0x5e,0x49,0x62,0xd3,0x46,0x49,0x4b,0x86,0x87,0xa9,0xac,0x1e,0x5a,0xf4,0x67, +0x9c,0x71,0x14,0xb5,0xc9,0x98,0x20,0x00,0x77,0x2a,0x85,0x93,0x75,0xab,0x49,0x9d, +0xd1,0x66,0x76,0x47,0x92,0x63,0x54,0x3c,0x57,0xb6,0x76,0x84,0xab,0x0d,0x8b,0x12, +0x85,0x83,0x27,0x85,0xa3,0x76,0x98,0x56,0x8e,0x02,0x76,0x90,0x55,0x72,0xc3,0x46, +0x9c,0x71,0x14,0xf2,0xc9,0x97,0x10,0x00,0x2d,0x69,0xd5,0xa3,0x99,0xa4,0x1a,0xdb, +0x94,0x4a,0x9b,0x49,0xc6,0x36,0xb3,0x73,0x72,0xbc,0x68,0x33,0xc0,0xa2,0xa6,0x38, +0xab,0x25,0xa3,0x23,0xd7,0xbb,0x82,0xaa,0x3a,0xda,0xab,0xb3,0xac,0x39,0x69,0xb3, +0x9c,0x71,0x14,0x88,0xb8,0x74,0x10,0x00,0x61,0xa4,0x98,0xfb,0xbb,0xd3,0xad,0xb9, +0xb6,0xd9,0x2e,0x94,0x21,0x96,0x4c,0x53,0x9d,0x58,0x69,0x39,0xa2,0x73,0xbb,0x88, +0x44,0xa0,0x64,0x18,0xb9,0x44,0x9c,0x6b,0x8a,0x46,0x43,0x80,0x7b,0xb4,0xc6,0xbd, +0x9c,0x71,0x14,0x5b,0xb5,0x44,0x00,0x00,0x36,0x4d,0x24,0x50,0x24,0x66,0x8d,0xa9, +0x55,0x93,0xab,0x20,0xca,0xbc,0xbb,0xa2,0x18,0x19,0x5b,0x1d,0x82,0x54,0xa6,0x84, +0xc4,0x4a,0x35,0xa3,0xbd,0xc5,0x45,0xb1,0x96,0xdd,0xec,0x9a,0xaa,0xba,0x43,0x4b, +0x9c,0x71,0x14,0x69,0xa4,0x43,0x00,0x00,0xb3,0xcc,0xca,0x1b,0x22,0x90,0xab,0x57, +0x08,0x0b,0x4a,0xa4,0xa2,0x94,0x69,0x16,0x44,0x31,0xa9,0x9d,0x47,0x19,0x38,0x9d, +0x43,0xa4,0xd9,0xb9,0xd5,0x13,0x98,0x31,0x39,0x1c,0x93,0x74,0x64,0xb5,0x0e,0x1d, +0x9c,0x71,0x14,0x69,0xa4,0x43,0x00,0x00,0x3d,0xaa,0x33,0x33,0xbc,0x31,0xcd,0x34, +0x26,0x6c,0x66,0xbb,0xa8,0x6a,0xbb,0x95,0xab,0x39,0xbb,0xb9,0x94,0xb4,0x47,0xa2, +0xb3,0x5a,0x4b,0xa4,0x43,0xb4,0x3e,0xc3,0x93,0xf3,0xbb,0x49,0x4c,0xb6,0x1c,0xbc, +0x9c,0x71,0x14,0xb0,0x92,0x22,0x00,0x00,0x75,0xdc,0x39,0x47,0x4d,0xa4,0x24,0x5a, +0x44,0xc1,0x89,0xa4,0xb5,0xe3,0xb2,0x3c,0x43,0xa2,0xc1,0x4c,0x32,0x45,0xa4,0x02, +0xb3,0x5a,0xdc,0x47,0x6b,0x4c,0x86,0x23,0xb8,0xab,0xb3,0x8f,0x3b,0xb9,0x62,0xbb, +0x9c,0x71,0x14,0xf6,0x73,0x02,0x00,0x00,0xcd,0x9b,0x59,0xb5,0xcd,0x56,0x9c,0x62, +0x8e,0x17,0x2b,0x1e,0xb4,0x49,0x8d,0x78,0x65,0x2b,0x5d,0xf4,0xd9,0x6e,0x7e,0x9d, +0xd3,0xe8,0xa2,0x8d,0xca,0x13,0xcb,0x1d,0x2b,0x85,0xf6,0xb5,0x58,0x8c,0x61,0xd4, +0x9c,0x71,0x14,0x48,0x72,0x13,0x10,0x00,0xba,0x78,0xdb,0x87,0x69,0xd2,0x76,0x9e, +0x56,0x8d,0xf3,0xa4,0xcf,0xc6,0xa8,0xf4,0x86,0x4e,0xbb,0x88,0xe6,0x77,0x0d,0xf8, +0xad,0xd6,0x54,0xdc,0xc0,0x91,0xc5,0x65,0x1c,0x2b,0x69,0xc2,0xa8,0x9c,0x7e,0x91, +0x9c,0x71,0x14,0x2a,0x74,0x32,0x00,0x00,0xc9,0x9c,0x2c,0x65,0x53,0xc5,0x8b,0xcb, +0xd7,0x43,0xbb,0x55,0x4b,0x47,0xba,0xb3,0x59,0x6a,0x48,0xc1,0x97,0x72,0x49,0x68, +0x23,0x8f,0x73,0xc8,0xeb,0x2b,0x8a,0x83,0x98,0x86,0xa9,0x7c,0x33,0x47,0xb8,0xee, +0x9c,0x71,0x14,0xfb,0x8a,0x75,0x00,0x00,0x7c,0xfc,0x27,0xb0,0xcb,0x73,0x25,0x23, +0xcd,0x3d,0x84,0xa1,0xb8,0x2a,0xa9,0x67,0x22,0xc3,0xd7,0xb3,0x28,0xf2,0xa8,0x2a, +0x44,0x38,0xba,0xa3,0x12,0x3c,0x2d,0x63,0xb3,0x2f,0xb3,0xb0,0xb9,0x2a,0x06,0xa5, +0x9c,0x71,0x14,0x0b,0xa9,0x75,0x00,0x00,0x3d,0xa9,0x15,0x8b,0x35,0x7b,0xac,0x17, +0x98,0x3c,0x65,0x34,0x27,0x16,0x94,0x70,0xbb,0xa7,0x0a,0x23,0x7b,0x7b,0x48,0x17, +0x2a,0x81,0x53,0x46,0xe9,0x3b,0x73,0x9b,0x27,0xa8,0xb3,0x7f,0x6b,0x46,0xe5,0x4a, +0x9c,0x71,0x14,0xab,0xb8,0x65,0x00,0x00,0x75,0x8b,0xb8,0x48,0x4b,0x86,0x99,0xa7, +0x87,0xbc,0x77,0x54,0xb7,0x67,0x42,0x70,0x74,0xc6,0xdc,0xf3,0x7e,0xce,0xa9,0xa5, +0xcb,0xa4,0x25,0xb9,0x82,0x5a,0x87,0x8b,0xd6,0x8a,0x19,0x3b,0x92,0x41,0x87,0x9a, +0x9c,0x71,0x14,0xd1,0xc9,0x86,0x00,0x00,0x75,0x6b,0xbb,0x57,0xbb,0xcc,0x7b,0x39, +0xe7,0x43,0x6e,0x93,0x36,0x66,0xb4,0x4e,0x6c,0xa3,0xfd,0x4c,0x80,0x5b,0xad,0x46, +0xc4,0xd3,0x53,0xa7,0xd8,0x3c,0x74,0xc4,0x2a,0x37,0xbb,0x6a,0x6b,0xc0,0x81,0x19, +0x9c,0x71,0x14,0x7c,0xd9,0x76,0x00,0x00,0x62,0xaa,0xdb,0x35,0xd1,0xca,0x59,0xd8, +0x5c,0x61,0x5f,0x19,0xd8,0xa3,0x21,0x88,0x55,0x55,0x12,0xdb,0x59,0x9d,0xaa,0xac, +0x9c,0xcd,0x4d,0xb8,0x6c,0x9a,0x5d,0xa1,0xc8,0xc3,0xda,0x85,0xda,0x34,0xaa,0xdc, +0x9c,0x71,0x14,0x72,0xda,0x76,0x10,0x00,0x5d,0xa7,0x3b,0x4c,0x52,0xcb,0xd2,0xe7, +0x94,0x11,0x5b,0x2a,0x49,0x53,0xa3,0x81,0xd5,0x94,0x13,0xec,0x64,0x1d,0xac,0x13, +0x93,0xc6,0x51,0xa6,0x74,0x9d,0x5a,0x2e,0x19,0x9b,0x1d,0x76,0x5f,0x33,0xf5,0x21, +0x9c,0x71,0x14,0xfa,0xda,0x86,0x10,0x00,0x74,0x3a,0xdc,0xc6,0x41,0xb3,0xa2,0xc5, +0x69,0xcb,0x66,0x62,0x39,0x42,0xc4,0x5e,0x89,0x94,0xbc,0x36,0x95,0x7b,0x8c,0xf4, +0xb6,0x8c,0x74,0x84,0xd9,0xbd,0x82,0xa4,0xa8,0x35,0x43,0x48,0x65,0xc6,0x36,0xa9, +0x9c,0x71,0x14,0xf3,0xd9,0x77,0x00,0x00,0xba,0x62,0xcc,0x0c,0x1a,0x63,0x9e,0x45, +0xbb,0xca,0x90,0xb9,0x46,0x24,0x4a,0x4c,0x4c,0xd8,0xf3,0x21,0xcc,0x38,0xd9,0x34, +0x21,0x4f,0xc1,0xd7,0xc5,0xa9,0x78,0x2e,0xd4,0xed,0x1a,0x6f,0xa1,0xcb,0xa4,0x5a, +0x9c,0x71,0x14,0x61,0xc9,0x75,0x10,0x00,0xe4,0x9c,0xe4,0x24,0xb0,0x51,0xa4,0xe7, +0x13,0xd8,0x36,0xbe,0xd5,0x22,0x39,0xcc,0x93,0xcf,0x3a,0x43,0x6a,0x43,0x24,0xcb, +0x25,0x71,0x3c,0x13,0xcb,0x64,0x51,0x2b,0x3b,0xcb,0x3b,0xf5,0x82,0xb7,0xe3,0x43, +0x9c,0x71,0x14,0x59,0xc9,0x76,0x00,0x00,0x4b,0xc3,0x36,0xe3,0x4b,0x47,0xc5,0xa5, +0xe1,0x2d,0xb7,0xc4,0x9e,0x99,0x3d,0x83,0x3c,0xa5,0x6d,0xac,0x6b,0x1f,0x34,0xbe, +0xd2,0x6a,0x0b,0xcb,0xca,0xca,0xe0,0x93,0xc7,0xd2,0xc2,0x5e,0xe4,0xc5,0xf0,0x63, +0x9c,0x71,0x14,0x50,0xca,0x87,0x10,0x00,0x5b,0xba,0x37,0xd4,0xc3,0xc4,0x7a,0xbc, +0x6a,0xcb,0x69,0x42,0xb6,0x6a,0xc3,0x4f,0x51,0xb7,0x77,0xd2,0x98,0xa2,0xcc,0xc4, +0x4a,0xa0,0xa2,0xc5,0x77,0xca,0x5e,0x53,0xd5,0x5c,0xd1,0x89,0x13,0x6b,0x1c,0xc1, +0x9c,0x71,0x14,0x6c,0xca,0x77,0x00,0x00,0xbf,0x69,0xd7,0xb5,0x21,0x59,0xd9,0x54, +0xd0,0x49,0x71,0xe1,0xd9,0x35,0x92,0xcb,0x5e,0xca,0x5c,0x92,0x5b,0x2d,0xc5,0x7a, +0xe3,0x4d,0x92,0x28,0xd2,0x9c,0xac,0xee,0x3c,0x41,0xdb,0x7f,0xa5,0xa5,0x2a,0x1c, +0x9c,0x71,0x14,0x66,0xcb,0x66,0x00,0x00,0x4d,0x48,0x96,0xdb,0xe4,0x95,0x49,0xbc, +0xb9,0x5b,0xa0,0x88,0xb6,0x35,0xa3,0x51,0xa6,0x44,0xe6,0xd1,0x8b,0x75,0xda,0x89, +0xd9,0xc6,0x55,0xc7,0xb9,0xda,0x54,0x75,0xb4,0xa6,0x53,0x6d,0xa2,0x39,0x95,0x9b, +0x9c,0x71,0x14,0x51,0xc9,0x55,0x10,0x00,0xc5,0xf4,0xa9,0xb2,0x55,0x64,0x32,0x24, +0x7d,0x0b,0x54,0x38,0xd8,0xb3,0x11,0xb2,0x59,0xcb,0xb1,0xa2,0x70,0xd9,0xc5,0x13, +0xa2,0x46,0x2e,0x37,0x8d,0x1d,0x9d,0xae,0x9c,0x34,0x4c,0x89,0x3e,0x15,0xab,0x8d, +0x9c,0x71,0x14,0x14,0xb8,0x44,0x00,0x00,0x10,0xb8,0x14,0x75,0xab,0x92,0x11,0x4e, +0x4e,0xf3,0xd0,0x10,0xb5,0x35,0xb2,0x29,0x3a,0xe2,0xcc,0x11,0x6a,0x31,0x4a,0xec, +0x8b,0xeb,0x37,0x48,0x83,0xca,0x45,0xc9,0x33,0x49,0x9c,0x44,0x6a,0xa7,0x41,0x23, +0x9c,0x71,0x14,0x5c,0xb8,0x34,0x00,0x00,0xcd,0xe6,0x3c,0x82,0x2d,0x6a,0x4b,0x15, +0x6b,0x8c,0x34,0xd2,0x35,0x5a,0x4b,0x94,0xde,0xac,0x5a,0x34,0x8f,0x50,0x46,0x43, +0x4a,0x41,0x4a,0xc3,0xe3,0x13,0x86,0xcc,0xbb,0xaa,0xea,0xa9,0xc6,0xc9,0x73,0xeb, +0x9c,0x71,0x14,0xbc,0xa5,0x33,0x00,0x00,0x57,0x9d,0xb0,0xe5,0x33,0x12,0xc1,0x38, +0x4b,0x4b,0xd6,0x51,0xad,0x4c,0x24,0xb6,0x39,0xa6,0xab,0x02,0x20,0x65,0xb1,0x2a, +0x2c,0x70,0x61,0x3c,0xca,0xda,0xda,0x39,0x5c,0xec,0x22,0x7c,0x49,0xc3,0x13,0x1a, +0x9c,0x71,0x14,0x33,0xa5,0x32,0x00,0x00,0x29,0xca,0x37,0x2c,0x12,0xb4,0x2b,0x5c, +0x3e,0x1c,0x97,0x11,0x36,0x85,0x23,0x66,0xc9,0x97,0xcb,0x53,0x8f,0x51,0xc9,0xd3, +0x12,0x93,0x49,0x88,0x03,0x8b,0x73,0xb1,0xd7,0x4c,0x5a,0x74,0x20,0xb7,0xcc,0x91, +0x9c,0x71,0x14,0x4c,0x86,0x33,0x00,0x00,0x80,0x6d,0xc8,0x98,0x0b,0x77,0x79,0xa6, +0x87,0x8b,0x51,0x8e,0x12,0x48,0x4c,0x1f,0x7e,0x13,0x07,0x1d,0x5e,0xb9,0x16,0x03, +0xe5,0x4d,0x89,0x33,0x08,0x9c,0x0e,0x64,0x30,0x28,0xda,0x16,0x50,0xd5,0x4a,0xd2, +0x9c,0x71,0x14,0x04,0x86,0x43,0x00,0x00,0x45,0x83,0x45,0xa3,0x39,0x2b,0xa3,0x41, +0xca,0x41,0x13,0x2c,0xc1,0xbd,0xc4,0x56,0x0c,0x15,0x3b,0xbe,0x59,0x2b,0x04,0x27, +0xad,0x46,0x92,0x32,0x66,0x23,0x2f,0x69,0x35,0x0a,0x9c,0x78,0x49,0x17,0x38,0xa4, +0x9c,0x71,0x14,0x04,0x86,0x43,0x00,0x00,0x65,0x71,0xa4,0xf6,0xb2,0x53,0xa2,0xe4, +0x84,0xc1,0x74,0xd4,0x4a,0x33,0xcc,0x92,0x9c,0x37,0xb9,0xc3,0x93,0x4b,0xaa,0xb8, +0xac,0xb2,0x92,0xba,0xc5,0x92,0xae,0x2a,0x5b,0xbe,0x9a,0x9d,0x3a,0x4e,0x7a,0x32, +0x9c,0x71,0x14,0x15,0xc8,0x45,0x20,0x00,0x87,0xbd,0x48,0x9b,0x24,0x84,0xce,0x27, +0xeb,0x63,0x7f,0xba,0xa8,0x94,0x9c,0x94,0x1e,0x39,0x15,0x53,0x84,0xb5,0x47,0x33, +0xdb,0x6f,0xc8,0x39,0x23,0x63,0xb6,0xd0,0x3a,0x9a,0x59,0x69,0x55,0x41,0xb0,0x82, +0x9c,0x71,0x14,0xdd,0xc9,0x56,0x10,0x00,0x89,0xbc,0x9e,0xe6,0x18,0xc0,0x5d,0x56, +0x8c,0x3b,0x33,0x3b,0x36,0x9d,0x57,0xe1,0x09,0x9b,0x5d,0xc4,0x80,0x41,0xa7,0x28, +0x95,0x3f,0x5b,0x79,0x4c,0x8c,0xcf,0x3b,0x2a,0xb8,0xa7,0x7b,0x8b,0x85,0x36,0xb6, +0x9c,0x71,0x14,0xa8,0xc9,0x56,0x30,0x00,0x44,0x5a,0x9c,0x29,0xc4,0xbc,0x83,0x98, +0x74,0xda,0x6e,0xbc,0x53,0xf4,0xd5,0x62,0xad,0x6c,0x63,0x48,0x9c,0xc5,0x67,0x94, +0x35,0x64,0xac,0xa3,0x75,0x49,0x80,0xd2,0x8b,0xd1,0xb3,0x8d,0xc2,0x87,0x26,0x2a, +0x9c,0x71,0x14,0xa8,0xc9,0x56,0x30,0x00,0x57,0x81,0x13,0x45,0x86,0x9b,0xc2,0xaa, +0xd3,0x19,0x82,0x9b,0x46,0xa8,0x25,0x4d,0x62,0xc3,0xe7,0x4a,0xa8,0x8a,0x19,0xf8, +0x57,0x81,0x53,0xa6,0x8b,0x54,0x41,0x54,0x25,0x08,0xc7,0xb2,0x6d,0xc9,0x49,0xc7, +0x9c,0x71,0x14,0xb0,0xc9,0x46,0x30,0x00,0x7c,0x4d,0x66,0x4b,0xd9,0x42,0x43,0xb6, +0x0b,0x40,0xb1,0x32,0x39,0x3c,0xa9,0x7f,0x32,0x96,0x2b,0x86,0x3e,0x4b,0x97,0x2b, +0x8a,0xb1,0x2c,0x59,0x1c,0x95,0x7e,0x33,0x75,0xfa,0xa6,0x42,0x53,0x57,0xcc,0x3b, +0x9c,0x71,0x14,0x4b,0xb9,0x46,0x30,0x00,0xd8,0x1b,0x8a,0x9d,0x38,0x7b,0x3a,0x63, +0xfa,0x46,0x12,0x52,0x17,0xcc,0x58,0xcd,0x1a,0xeb,0x2d,0x49,0x7e,0x39,0x43,0xea, +0x44,0x18,0x5a,0x57,0x6b,0xc5,0xcd,0x1b,0xdb,0x2d,0x4a,0x7f,0x33,0x74,0x1a,0xa2, +0x9c,0x71,0x14,0x4b,0xb9,0x46,0x30,0x00,0x2b,0x5b,0x56,0x1b,0x15,0xc7,0x24,0xbb, +0xec,0xab,0x9e,0x35,0x74,0x9a,0x35,0x57,0x8d,0x63,0xd5,0x37,0xbe,0x83,0x5c,0x48, +0x97,0xcd,0x5a,0x65,0x29,0xa8,0x6c,0x7b,0x83,0xe3,0x4a,0x94,0xec,0x7d,0x21,0x57, +0x9c,0x71,0x14,0xb0,0xc9,0x46,0x30,0x00,0xb6,0xcb,0x57,0xc4,0x34,0x77,0x91,0x67, +0x05,0xa7,0x68,0xd1,0x8a,0x70,0x39,0xb8,0xf4,0xba,0x20,0xd8,0x6c,0xbd,0x68,0x99, +0x43,0x55,0x23,0x48,0x8e,0x17,0xad,0x29,0xbc,0xaa,0x9a,0x7e,0x7b,0x77,0xa5,0xc4, +0x9c,0x71,0x14,0x86,0xca,0x45,0x30,0x00,0x7e,0x8a,0x94,0xb8,0xab,0x9a,0x5a,0x6b, +0x8b,0x1e,0xc0,0x44,0xc6,0x8a,0x89,0x86,0x78,0x96,0x75,0x11,0x4a,0xd1,0xa9,0x91, +0xab,0xc7,0xda,0xca,0xd3,0xa5,0x5e,0x95,0xd8,0xc9,0xd4,0x58,0x28,0xa4,0x3e,0xc9, +0x9c,0x71,0x14,0x86,0xca,0x45,0x30,0x00,0x92,0x0d,0x1d,0x8d,0xa2,0xa4,0x4a,0x45, +0x48,0x2e,0x8e,0xaa,0x46,0x32,0x9a,0x2a,0xe9,0x08,0x30,0xca,0xe0,0xd8,0xcb,0x64, +0x15,0x4a,0x91,0xd8,0x09,0x2c,0x88,0x52,0xb1,0x4c,0x21,0x61,0x2a,0x1c,0xed,0x5a, +0x9c,0x71,0x14,0xf3,0xda,0x25,0x30,0x00,0xad,0x98,0x36,0xad,0xa3,0x71,0x2c,0xc9, +0x84,0x6e,0x51,0xb7,0x55,0x3c,0x32,0x90,0xc1,0x0b,0xf3,0x71,0x80,0x4a,0xb6,0x03, +0x2c,0x90,0x48,0xc8,0x73,0xac,0x39,0x38,0xc5,0x7c,0xcb,0xa6,0xb3,0x1b,0x6c,0x0a, +0x9c,0x71,0x14,0xad,0xd9,0x45,0x20,0x00,0x72,0xc9,0xb6,0x52,0x14,0x98,0x55,0x47, +0xfb,0x4c,0x38,0x28,0x35,0xa6,0x81,0xa7,0x90,0x8b,0x4d,0x93,0x75,0xc1,0xe6,0x6a, +0x6c,0x93,0xe2,0xb8,0x92,0xe2,0x47,0x39,0xb4,0xb6,0x24,0x9b,0x82,0x9b,0x5f,0xb1, +0x9c,0x71,0x14,0x39,0xd9,0x56,0x20,0x00,0x87,0x9a,0x46,0x3b,0xa3,0x85,0x61,0xb9, +0xb0,0x5c,0x6b,0x65,0x43,0xe2,0x52,0x77,0x48,0x9a,0xec,0x8b,0xa0,0xa9,0x46,0xd5, +0xe3,0x6e,0x26,0xa9,0xec,0xec,0x95,0x41,0x55,0xfa,0x0b,0x44,0xd4,0x98,0x25,0xa3, +0x9c,0x71,0x14,0x3a,0xca,0x66,0x30,0x00,0xdc,0x4e,0xca,0x3a,0xb3,0x53,0x72,0xa7, +0x15,0xa3,0xd7,0xaa,0x4a,0xb6,0x1b,0x34,0x71,0xb0,0x79,0x9d,0x7a,0xb9,0xae,0x10, +0x58,0x88,0xbe,0x34,0xe9,0x63,0x90,0x42,0x5e,0x3a,0x1d,0x9f,0x6d,0x13,0xc8,0x51, +0x9c,0x71,0x14,0x28,0xcb,0x67,0x30,0x00,0x29,0x89,0xb4,0xa6,0x2c,0xc2,0x6a,0xca, +0x5a,0xe9,0x6b,0x6a,0x27,0x06,0x9c,0xbb,0x7d,0xbc,0x48,0x22,0x65,0x8e,0x34,0x37, +0x24,0x2e,0x73,0x46,0xac,0x69,0xd0,0x53,0x19,0xd6,0xa5,0x4d,0x8a,0x47,0xba,0x69, +0x9c,0x71,0x14,0x84,0xcb,0x77,0x20,0x00,0xda,0x81,0xca,0x64,0x1b,0x4d,0x79,0xa4, +0xea,0x5b,0x34,0x6e,0xd7,0x2a,0xdb,0xda,0x65,0x88,0x96,0xdc,0x37,0x81,0xd8,0x98, +0x8b,0xe7,0x91,0xb9,0x57,0x5c,0x48,0x5d,0xa6,0x58,0x1c,0x41,0x93,0x44,0xcb,0xe9, +0x9c,0x71,0x14,0x19,0xca,0x77,0x20,0x00,0xd4,0x22,0x49,0xf3,0x23,0x3a,0x6e,0xb7, +0x4c,0x54,0xe8,0xc5,0x3a,0x93,0x63,0x4d,0x29,0xa6,0xa8,0x53,0x5c,0xdc,0xc1,0xb8, +0x54,0xb8,0x12,0x1c,0xf4,0xda,0x4b,0xa6,0x63,0xac,0x8b,0xd5,0x8e,0x3d,0x84,0x23, +0x9c,0x71,0x14,0x75,0xda,0x87,0x10,0x00,0x62,0x6c,0x37,0xa9,0x3b,0x95,0x8b,0x35, +0x59,0xbb,0x3d,0x94,0x3b,0x72,0xc3,0xa7,0x53,0xb4,0xc7,0xa2,0x5f,0xc2,0x5c,0x3a, +0x32,0xa5,0x5b,0x25,0x05,0xbc,0x83,0x7b,0x3a,0x47,0xa3,0x51,0xbb,0x22,0xc6,0x1a, +0x9c,0x71,0x14,0x47,0xd9,0x77,0x10,0x00,0xb3,0x95,0xcb,0x9a,0x54,0x52,0x76,0xb5, +0x96,0xb1,0xc0,0xd0,0xca,0xbb,0x23,0x4f,0xb6,0xc7,0xdc,0xaa,0xb0,0x3a,0x36,0x1e, +0x23,0x26,0x0e,0xb9,0x06,0x13,0xca,0xc5,0xb6,0xa5,0x2b,0x45,0x3d,0xb9,0x92,0x63, +0x9c,0x71,0x14,0xf3,0xd9,0x77,0x00,0x00,0xc6,0x42,0x37,0x4a,0xdb,0x5c,0xb9,0xb9, +0xfa,0xd3,0x93,0xac,0xb4,0x24,0x02,0x44,0x45,0x4b,0x44,0x0b,0xaa,0xc1,0xa5,0x9c, +0x9c,0x62,0x4e,0x2a,0xdc,0xe4,0xb1,0xaa,0x46,0xd2,0x99,0x76,0x9d,0xd9,0xa2,0x54, +0x9c,0x71,0x14,0x3e,0xc8,0x77,0x20,0x00,0x7f,0x89,0x91,0xa8,0x1b,0x43,0xba,0x4b, +0x19,0x22,0xa0,0xa3,0x36,0x7c,0x43,0x75,0xa4,0x2a,0xe8,0xcc,0xad,0x3c,0xb8,0x15, +0x4a,0x7f,0x54,0x48,0xb5,0xab,0x6f,0x6b,0x34,0xb9,0xbb,0x50,0x82,0x26,0x9d,0x3a, +0x9c,0x71,0x14,0xb5,0xb7,0x67,0x20,0x00,0x7c,0xb7,0xc8,0x8b,0xa5,0x8d,0x5a,0x69, +0x62,0xaa,0xaf,0x58,0x5b,0x93,0x87,0x8c,0x35,0x86,0x53,0x56,0x62,0x40,0x75,0xda, +0x96,0x4b,0x88,0x73,0xc6,0x8b,0x5e,0x4c,0x57,0x74,0xb7,0x80,0x67,0x98,0x2a,0x84, +0x9c,0x71,0x14,0x7d,0x96,0x86,0x20,0x00,0xcb,0x0e,0x7d,0xb0,0xf9,0xa9,0x2e,0x48, +0x8c,0xec,0x9d,0xce,0x67,0x0c,0xe7,0x47,0x4b,0x92,0x84,0xc3,0x38,0x90,0x75,0x2b, +0x05,0x68,0xaf,0xd8,0xac,0xe0,0x96,0xcf,0xa9,0xf6,0xf9,0x89,0x87,0x87,0x56,0xb5, +0x9c,0x71,0x14,0x9b,0x77,0x66,0x20,0x00,0x16,0x06,0xa9,0xa6,0x5d,0x92,0xd8,0x90, +0xa6,0xa4,0x0a,0x5d,0x83,0x9d,0xdd,0x62,0x26,0x95,0x1d,0x95,0x49,0xea,0x19,0xdd, +0x54,0xbc,0xf1,0x49,0x62,0xe9,0x5d,0x1e,0x26,0x56,0x26,0x5d,0x99,0xd6,0x4e,0x0c, +0x9c,0x71,0x14,0x30,0x75,0x65,0x20,0x00,0x44,0x0d,0x04,0xc7,0x08,0x32,0x0d,0x96, +0x2c,0x32,0x69,0x4c,0xa6,0x8f,0x11,0x75,0x2e,0x1a,0x93,0x15,0xa5,0x4c,0x99,0xca, +0xed,0x9d,0x4d,0x19,0x4f,0x41,0x8e,0xd3,0x9a,0xb1,0x05,0xca,0xcf,0x1d,0x91,0x0d, +0x9c,0x71,0x14,0x2c,0x85,0x54,0x00,0x00,0xaa,0x56,0x6b,0x08,0xb3,0xb1,0x56,0x7c, +0x25,0x9b,0xc8,0x88,0x1c,0x83,0x79,0xcb,0x87,0x7d,0x05,0x8b,0xd8,0x45,0x1d,0x49, +0xaa,0xcf,0x23,0x8c,0xf9,0xa4,0xc6,0x63,0x8b,0xc5,0x89,0xb5,0xb6,0x8c,0x34,0x52, +0x9c,0x71,0x14,0xbb,0x85,0x45,0x00,0x00,0xdb,0xa8,0x8d,0xc9,0x49,0xd0,0x55,0x5c, +0x2d,0x98,0xc3,0x52,0x7c,0x9a,0xc9,0xbc,0xa3,0x2a,0xe4,0xcb,0xa7,0xc7,0x6a,0x76, +0x86,0xa6,0x7a,0x79,0x7b,0x89,0x8f,0x48,0x79,0x1b,0xb4,0x8b,0x62,0x88,0x43,0x99, +0x9c,0x71,0x14,0x18,0x75,0x55,0x20,0x00,0x6f,0x0c,0x96,0xc1,0x0d,0x72,0xb2,0xd6, +0x4c,0xf5,0x58,0x90,0x54,0xf2,0xb1,0x51,0x0f,0x14,0xcf,0x09,0x45,0x24,0x93,0xcc, +0xd1,0x42,0x82,0xd4,0x30,0x4d,0x3a,0x71,0x23,0x71,0x12,0x2b,0x57,0x22,0xef,0x49, +0x9c,0x71,0x14,0xd6,0x85,0x55,0x20,0x00,0x59,0xb4,0x95,0xec,0xf0,0x62,0xf2,0x45, +0xed,0x28,0x58,0x69,0x15,0x28,0x71,0x58,0xa6,0xa5,0xec,0x92,0x5d,0x12,0xd5,0x17, +0x89,0x42,0xd6,0x84,0x35,0x04,0x42,0xd5,0x04,0x68,0xf1,0x3d,0x0e,0x93,0xa7,0xb1, +0x9c,0x71,0x14,0xfe,0x85,0x65,0x20,0x00,0x3d,0x2d,0x14,0x10,0xa5,0x45,0x32,0x94, +0x74,0xcc,0x59,0x50,0x86,0x91,0x8d,0x6c,0xec,0xd6,0xaf,0x11,0x72,0x73,0x28,0x2e, +0xea,0x8c,0x97,0x59,0x27,0x65,0x8c,0x8c,0xd8,0xe6,0xe8,0xa8,0xd5,0x4b,0x54,0xa5, +0x9c,0x71,0x14,0xed,0x96,0x66,0x20,0x00,0x98,0x87,0x69,0x98,0x6a,0xab,0x53,0x7b, +0x99,0x77,0xb0,0x89,0x6a,0xb2,0x77,0xaa,0x2e,0x5a,0xf3,0xc7,0xbb,0x38,0x9b,0xc5, +0x88,0xb6,0x64,0x4d,0x07,0x68,0xcd,0xa6,0xcb,0xb8,0x65,0xb7,0xa7,0x39,0xe7,0x69, +0x9c,0x71,0x14,0x76,0x87,0x77,0x30,0x00,0xa5,0xda,0x1a,0x1d,0x95,0xae,0x21,0xdb, +0xe9,0xd9,0xe5,0xa6,0x5c,0xa2,0x1d,0xb2,0x6a,0x1c,0xaf,0x21,0xd9,0x69,0x9e,0x19, +0xd4,0xc5,0x31,0xdd,0x86,0x31,0xb9,0xac,0x5b,0x0a,0x6e,0xcd,0x12,0x2c,0xd2,0xd9, +0x9c,0x71,0x14,0xf9,0x87,0x76,0x30,0x00,0xac,0xd5,0x5a,0x1d,0xc0,0xce,0x56,0x47, +0x55,0xa9,0x69,0xad,0xe9,0xe2,0xa2,0xc6,0x5a,0x9a,0x55,0xc1,0x8a,0x1e,0x0c,0x5e, +0x18,0xbd,0x15,0xd8,0x19,0x5a,0x98,0xd7,0x69,0x95,0x66,0x8a,0x11,0x18,0x18,0x08, +0x9c,0x71,0x14,0x10,0xc9,0x86,0x30,0x00,0x80,0x82,0x27,0xd8,0x24,0x6a,0x7b,0x53, +0xe5,0xbc,0x54,0xb2,0xaa,0x79,0xbd,0xb4,0xab,0x97,0x79,0x43,0x68,0x7c,0x2a,0x69, +0x44,0x9a,0x94,0xc1,0x77,0x5c,0x2b,0xbb,0x2c,0xa9,0xc9,0xde,0xa4,0x46,0x08,0xcb, +0x9c,0x71,0x14,0x52,0xd8,0x87,0x10,0x00,0x63,0xbc,0xb9,0xd4,0x55,0x9a,0xc4,0xa4, +0x31,0x63,0x51,0x62,0xbb,0x14,0x4a,0xaf,0x5b,0xd6,0x65,0xc9,0x62,0xc4,0x4a,0x3d, +0x53,0x96,0x5c,0xa3,0xb1,0x4a,0x57,0x62,0x6b,0x73,0xc1,0xad,0xdb,0xd6,0x3d,0xca, +0x9c,0x71,0x14,0x1b,0xd8,0x77,0x20,0x00,0x61,0xba,0xba,0x3c,0x73,0x9b,0xd3,0x33, +0xd9,0x74,0x4d,0x68,0x4b,0x54,0x69,0xb3,0xd9,0x56,0x04,0xa0,0x5d,0xb5,0xda,0x95, +0x2b,0x9d,0x6a,0x33,0xa2,0x35,0x51,0x74,0x2b,0xa4,0xe2,0xae,0xe5,0x55,0x7d,0x99, +0x9c,0x71,0x14,0x16,0xd9,0x97,0x20,0x00,0x5e,0xc3,0xcb,0x1d,0x43,0x9e,0x54,0x23, +0x53,0x4d,0x4b,0xe4,0x0b,0xdc,0xc6,0xb0,0x54,0x15,0x3c,0x43,0x5b,0xbc,0x4b,0x24, +0xc9,0xa3,0x4c,0xc3,0x7a,0xd3,0x43,0x66,0x2b,0xcb,0xd6,0xb5,0xc5,0x95,0x5b,0x55, +0x9c,0x71,0x14,0x24,0xd9,0x98,0x30,0x00,0x58,0x5a,0x6b,0x07,0xa6,0xa8,0x4a,0x93, +0xe4,0xa4,0x3c,0x9c,0xab,0xb3,0xa7,0xbd,0x4b,0x45,0x92,0x9b,0x55,0x3a,0x4a,0xe5, +0x97,0xaf,0x49,0x94,0x23,0xa4,0x39,0x8b,0x8b,0xb3,0x98,0xc1,0x5a,0x45,0xe3,0x8a, +0x9c,0x71,0x14,0x0e,0xd9,0x87,0x20,0x00,0x55,0x9d,0x2a,0xeb,0xc3,0xb1,0xac,0x24, +0x02,0x5c,0x3c,0x5f,0x0b,0xeb,0xde,0xc4,0x46,0x15,0xfc,0x5b,0x56,0xb5,0xcb,0x05, +0x4b,0x9b,0x3c,0x22,0xe2,0x35,0x61,0x14,0x8c,0xa9,0xa5,0xad,0x1a,0xa5,0x29,0x9b, +0x9c,0x71,0x14,0xac,0xda,0x97,0x20,0x00,0x6a,0x63,0x4b,0x17,0xaa,0x6b,0x63,0x43, +0x89,0x94,0x90,0x9a,0x8c,0x9a,0xa6,0x86,0xab,0x14,0xf9,0xb3,0x8d,0xc3,0xd9,0x29, +0xc1,0x44,0xb6,0x46,0x38,0x55,0xb8,0x6d,0x8a,0xf6,0xd6,0x60,0x5d,0x16,0xb6,0x4a, +0x9c,0x71,0x14,0xb4,0xda,0x87,0x20,0x00,0x9b,0x4c,0x56,0x03,0x99,0x4e,0x42,0xb9, +0x85,0x9d,0xc1,0x69,0x18,0x37,0x0d,0x5c,0x71,0x28,0xd8,0x9a,0x7a,0x82,0xd4,0xeb, +0x92,0x75,0xa2,0x2b,0x8a,0x3e,0xa7,0x94,0x16,0x58,0xcc,0x77,0x9d,0x38,0x97,0xd9, +0x9c,0x71,0x14,0x65,0xc9,0x86,0x10,0x00,0x3a,0x7e,0xe4,0x12,0x5a,0xb8,0x35,0x2f, +0x03,0x4e,0x83,0x33,0x85,0x34,0xac,0x8c,0x39,0xb6,0x13,0x92,0x31,0x89,0x47,0x3a, +0x9b,0xdd,0xb1,0xbc,0x1a,0x33,0x61,0xa3,0x47,0x1b,0x43,0x7d,0xb4,0xa4,0x38,0xd4, +0x9c,0x71,0x14,0x48,0xc8,0x75,0x00,0x00,0x3f,0x55,0x19,0x45,0x6c,0xcf,0x3c,0xc9, +0x64,0x4b,0x6a,0x3b,0x28,0x02,0xa3,0x6f,0x71,0x54,0x36,0x98,0x53,0x7a,0x49,0x5b, +0x3d,0xb0,0x93,0x88,0xfa,0xb5,0x7f,0x9c,0x48,0x07,0xb9,0x6e,0x81,0x35,0xd7,0x35, +0x9c,0x71,0x14,0xfe,0xa7,0x75,0x00,0x00,0x32,0x3c,0x9b,0x07,0xba,0xd3,0x5c,0x69, +0xf7,0xb9,0x8b,0x93,0x27,0xf9,0xae,0x64,0xc2,0x15,0xda,0x29,0x6e,0x6d,0x57,0x9a, +0x33,0x82,0x93,0x98,0xb9,0x5d,0x84,0x73,0xc6,0x94,0xa8,0x5d,0x95,0xd7,0x27,0xcd, +0x9c,0x71,0x14,0xb4,0x87,0x75,0x00,0x00,0x94,0xc5,0x99,0xce,0x73,0x58,0x66,0x54, +0x4c,0x51,0x42,0xa6,0xa3,0x29,0x75,0x79,0x19,0x9b,0x0f,0x92,0xa7,0x23,0xe7,0x57, +0x52,0x6f,0x26,0x97,0xd5,0x2d,0x55,0x57,0x33,0x8f,0xd1,0x69,0x3a,0x5b,0xcf,0x8b, +0x9c,0x71,0x14,0x31,0x86,0x65,0x00,0x00,0xc4,0x8c,0x9a,0xb1,0x5d,0x92,0x52,0x45, +0x49,0x49,0x35,0x06,0xc4,0x28,0xac,0x87,0x69,0x1b,0xb4,0x63,0xb1,0x0b,0x5a,0xb8, +0x89,0x78,0xd3,0x34,0xee,0xa5,0x57,0x0b,0x25,0x87,0x3a,0x8c,0xe6,0xda,0xad,0x92, +0x9c,0x71,0x14,0xe2,0x75,0x54,0x00,0x00,0xbf,0x33,0x2b,0xbb,0x7d,0x7d,0x8d,0x65, +0x39,0xb3,0x42,0xc9,0xb5,0xf6,0x58,0xa5,0x63,0x4a,0x75,0x7a,0xae,0x05,0x8b,0x64, +0x74,0x85,0x3d,0x85,0x54,0x8a,0x57,0x94,0x48,0x28,0x68,0x9e,0x94,0x8a,0x4a,0x36, +0x9c,0x71,0x14,0xfb,0x63,0x32,0x00,0x00,0xd6,0xc3,0x8c,0xed,0x64,0xa2,0x9b,0xb7, +0xb7,0xb5,0x6c,0x69,0x27,0x26,0x89,0x91,0x67,0x8b,0x26,0x79,0xc7,0x66,0x5b,0xe7, +0x86,0x98,0x77,0x86,0x87,0x77,0x48,0x77,0x74,0x67,0x73,0x5b,0x77,0xa6,0xd7,0x77, +0x9c,0x71,0x14,0x54,0x70,0x12,0x00,0x00,0x73,0x12,0xd6,0x23,0x55,0x4c,0x0d,0x43, +0xd2,0x4d,0x3a,0x1c,0xf3,0xf5,0xa2,0x42,0xa7,0x03,0xb0,0xa8,0x29,0x71,0x01,0x7d, +0x1b,0x10,0xe3,0x71,0x4d,0xd4,0x1b,0x1a,0xf1,0xaa,0x50,0x11,0x18,0xd0,0x2a,0x88, +0x9c,0x71,0x14,0x82,0x80,0x02,0x00,0x00,0x3b,0x17,0xd3,0x87,0xa0,0x39,0xa6,0x13, +0xbf,0x6e,0x3b,0xd8,0x03,0x82,0x6e,0x33,0x97,0x93,0x1c,0xce,0x33,0x5b,0xf3,0x60, +0x6b,0x37,0x37,0x83,0x62,0x8e,0x33,0x2c,0x72,0xfa,0xc9,0x2c,0xe9,0x32,0xc0,0x1f, +0x9c,0x71,0x14,0x82,0x80,0x02,0x00,0x00,0x2c,0xf7,0xc2,0xed,0x89,0x30,0xe3,0xb3, +0x39,0x79,0x37,0x7d,0x13,0xc8,0xaf,0x42,0x2b,0x64,0x7b,0x68,0x4d,0x38,0x45,0x29, +0x2f,0x57,0xfe,0x05,0xd1,0xaa,0x62,0x25,0x96,0x76,0x9a,0x6d,0x93,0xc7,0x48,0x5c, +0x9c,0x71,0x14,0x4c,0x70,0x02,0x00,0x00,0x78,0x05,0x68,0x69,0xb0,0x94,0x5a,0x8a, +0x14,0x2c,0xad,0x27,0xbb,0x8d,0x56,0xc5,0x58,0x9d,0x27,0xc5,0xde,0x04,0xae,0x52, +0x89,0xe7,0xdd,0x5e,0x91,0x65,0xec,0x49,0x8f,0x1f,0x99,0xf8,0x46,0x0f,0xbe,0x58, +0x9c,0x71,0x14,0xd7,0x83,0x43,0x00,0x00,0xbe,0x78,0x2b,0xf8,0x84,0xbf,0x67,0xbc, +0x18,0x73,0xbe,0x68,0x4b,0xe4,0x5a,0xbd,0x96,0x2b,0xd3,0x7a,0xbc,0x79,0xcb,0x5a, +0xbb,0xb0,0xe8,0x3b,0x6c,0x63,0xb2,0xda,0xba,0xad,0xb4,0xad,0x64,0x3a,0xb6,0x75, +0x9c,0x71,0x14,0x4d,0x87,0x76,0x20,0x00,0xa1,0xdd,0x9a,0x5d,0xdd,0xa9,0xe1,0xdb, +0x61,0xd5,0xb5,0xa6,0x9b,0xee,0x11,0x81,0x9a,0x58,0xe1,0x6a,0xca,0xd9,0x2c,0x55, +0x6e,0x5f,0x4d,0x62,0x61,0x21,0x89,0xd8,0x49,0x2e,0x30,0x31,0xe1,0x04,0x23,0x15, +0x9c,0x71,0x14,0x15,0xa6,0x77,0x20,0x00,0x73,0xab,0xb6,0x56,0x96,0x5e,0xa7,0x76, +0xa4,0x97,0x65,0x56,0x65,0x06,0x67,0x59,0x34,0x66,0xa7,0x87,0x66,0x35,0xa6,0x59, +0xa5,0x64,0x96,0x96,0xa9,0x99,0x6a,0xb8,0x06,0xaa,0xcd,0x5e,0xb5,0x43,0x65,0xc8, +0x9c,0x71,0x14,0x77,0xc8,0x87,0x10,0x00,0x6a,0xa3,0x36,0xe8,0xc2,0x7c,0x84,0x49, +0x48,0x4a,0x98,0x7b,0xc8,0x87,0xbb,0x7e,0x6b,0xc7,0x04,0xb2,0x54,0xa3,0x33,0x21, +0x91,0x64,0x72,0x5b,0x14,0x9b,0xae,0x7a,0xa6,0xa6,0x25,0x62,0x42,0xab,0x17,0x23, +0x9c,0x71,0x14,0x6c,0xc9,0x88,0x10,0x00,0xb7,0x74,0x67,0x17,0x59,0x59,0x74,0x57, +0x07,0x98,0x4f,0x6b,0x75,0x0b,0xa3,0xa9,0x87,0xbb,0xa9,0x75,0x69,0x97,0x84,0xc8, +0x67,0xb5,0x97,0x7c,0xe7,0x67,0x70,0x76,0x75,0x47,0x67,0x89,0x64,0x76,0x67,0x3a, +0x9c,0x71,0x14,0x6c,0xc9,0x88,0x10,0x00,0x19,0x31,0x37,0xd5,0x3a,0xd7,0x53,0x58, +0x25,0x68,0x33,0x54,0x89,0x04,0x76,0xe6,0x56,0x78,0x35,0x57,0x44,0x67,0x79,0x85, +0x67,0xaa,0x67,0x83,0x47,0x57,0x0a,0x24,0x8a,0x17,0x05,0xdb,0x52,0x75,0xa7,0x28, +0x9c,0x71,0x14,0x6f,0xc8,0x97,0x10,0x00,0x3c,0x72,0xab,0xa2,0x2d,0xe2,0x8b,0x26, +0xb6,0xbb,0x4f,0x8c,0x4b,0x87,0xc2,0xae,0x84,0x33,0x98,0x4d,0x1d,0x94,0x98,0x3b, +0xdd,0xd0,0x5d,0xa7,0xba,0x5c,0x51,0x7c,0xb9,0xe9,0x4b,0xcd,0xb4,0xb9,0x38,0x4b, +0x9c,0x71,0x14,0x5e,0xc9,0x87,0x00,0x00,0x60,0x84,0xb9,0xf9,0xc3,0xc0,0x8b,0xb6, +0xe8,0x2b,0x37,0xaa,0xc4,0x98,0xb9,0x90,0xd3,0xdb,0x29,0xa1,0x77,0xaa,0x46,0xfa, +0x93,0xa5,0x91,0xab,0x8a,0x94,0x8d,0x81,0xb6,0xd6,0xa3,0xa1,0x92,0xba,0xe6,0x33, +0x9c,0x71,0x14,0x16,0xb9,0x76,0x10,0x00,0x55,0x79,0xa0,0x57,0xa3,0x13,0x74,0x38, +0x6b,0xdd,0xd7,0x74,0x17,0x69,0x3c,0x73,0x93,0x2b,0xe7,0xaa,0xdc,0xa9,0xda,0x17, +0x23,0x5b,0x79,0xbb,0xe9,0x24,0xe2,0x6a,0x36,0xa8,0x39,0x21,0x7b,0x62,0x07,0x1a, +0x9c,0x71,0x14,0x03,0xb8,0x86,0x10,0x00,0x50,0x5b,0xbb,0x53,0xc5,0x9e,0x54,0x89, +0x45,0xcb,0xac,0x5c,0x4c,0x98,0xca,0xab,0x5c,0x47,0xb7,0x43,0xa8,0x7c,0x2a,0x16, +0xc3,0x3d,0x84,0x40,0xc7,0xc1,0x1d,0x7c,0xd6,0xcf,0x59,0xa8,0x65,0x58,0x5b,0xc9, +0x9c,0x71,0x14,0xc5,0xb8,0x77,0x20,0x00,0x8e,0x9c,0x4a,0x38,0xc3,0xbf,0xc3,0xa9, +0x66,0xbc,0x69,0x92,0x39,0x88,0x2b,0x9f,0x73,0x34,0x88,0xbb,0x00,0x73,0xb1,0x39, +0x4b,0x42,0x31,0x19,0xa6,0x95,0x8f,0x62,0x28,0x85,0x3a,0x99,0x5b,0x5a,0xc6,0xb2, +0x9c,0x71,0x14,0x8b,0xb8,0x76,0x10,0x00,0xb2,0x5c,0x17,0x47,0x36,0x84,0x73,0x2a, +0x87,0x34,0x7a,0x7b,0xb2,0x26,0x3b,0x11,0x7b,0x23,0x05,0x25,0x67,0xe6,0x2a,0x73, +0xdc,0x96,0x95,0xb9,0x98,0xd3,0x9c,0x5d,0x2b,0x2b,0x4c,0x9a,0x54,0xb6,0xf8,0xb9, +0x9c,0x71,0x14,0xc5,0xb8,0x77,0x20,0x00,0x96,0x6b,0xca,0x87,0xc3,0x62,0x7c,0xb1, +0x58,0x43,0x1c,0x8d,0x33,0x73,0x6b,0x7a,0xdc,0x19,0xf6,0xbd,0x95,0xa2,0xb9,0x0a, +0x32,0x97,0x72,0xda,0xea,0x3b,0x83,0x7b,0xa6,0xb9,0x3c,0x98,0x7c,0x29,0xc8,0x4b, +0x9c,0x71,0x14,0xe3,0xb7,0x76,0x10,0x00,0x4d,0x69,0xb1,0x2a,0x84,0x20,0xa7,0x74, +0x02,0x66,0x93,0x83,0xd9,0xe7,0x40,0x93,0x74,0x99,0x37,0x69,0xa6,0x76,0x2b,0x58, +0x68,0x79,0x86,0xa7,0x66,0x75,0xaf,0x78,0x7a,0x66,0x8b,0x50,0x67,0x32,0x27,0x88, +0x9c,0x71,0x14,0xd3,0xb7,0x56,0x10,0x00,0x33,0x5c,0xb5,0xd3,0x21,0xa4,0x1c,0x8a, +0xac,0x3b,0xa2,0x9c,0x29,0xfa,0xbb,0xb6,0xbb,0x7b,0xca,0x55,0x81,0x3b,0x98,0x2b, +0x46,0xb8,0x33,0x6a,0xec,0x28,0x60,0x3b,0x73,0x4b,0xc5,0x3d,0x45,0x96,0x0a,0x07, +0x9c,0x71,0x14,0x47,0xb7,0x45,0x10,0x00,0xa4,0x95,0x9b,0x33,0xad,0xaa,0xab,0x19, +0xc2,0xd4,0xb3,0xb8,0x3c,0x32,0x8b,0x87,0xc0,0xb7,0x93,0xc3,0xa9,0xbc,0xbb,0x74, +0x4b,0x7d,0x3e,0x34,0x83,0xdb,0x38,0x56,0x24,0xca,0x43,0x88,0xbc,0x3a,0xd4,0x14, +0x9c,0x71,0x14,0xf9,0xb6,0x54,0x00,0x00,0xb0,0xa9,0xa9,0xcc,0x9b,0x9f,0xb1,0x3b, +0xab,0x5c,0x9c,0xcd,0xb7,0xcb,0x52,0x90,0x48,0xba,0xd5,0x54,0x99,0x31,0xb5,0xe4, +0x63,0x30,0x4a,0x53,0x09,0x10,0x6f,0xd0,0xbb,0x3b,0x9a,0xc5,0x3a,0x5a,0x74,0x12, +0x9c,0x71,0x14,0xe1,0xb6,0x44,0x00,0x00,0x90,0x39,0x5a,0xad,0x0a,0xa4,0xb9,0xc7, +0xdb,0xd3,0x7a,0x3a,0x39,0xd4,0x1b,0xa6,0x21,0xa7,0x84,0x93,0x3c,0x41,0xc1,0xf1, +0x5c,0x57,0xd8,0xaa,0x5b,0x14,0xbb,0x45,0x3a,0x04,0x1b,0x82,0xb1,0x39,0xbd,0x22, +0x9c,0x71,0x14,0xd1,0xb5,0x43,0x00,0x00,0x9d,0x99,0xc7,0x5c,0x48,0x66,0x33,0xd8, +0x23,0xbb,0xa4,0xbb,0x48,0xea,0x52,0x52,0xd5,0xc1,0xcb,0x52,0x2a,0x51,0xa7,0xf3, +0x04,0xaf,0x24,0x9a,0x36,0xbc,0x81,0x0d,0x48,0x0e,0x44,0x98,0x34,0xa8,0x4c,0x44, +0x9c,0x71,0x14,0xbc,0xa5,0x33,0x00,0x00,0x54,0x59,0xa4,0xe2,0xad,0x69,0x4d,0xa8, +0x6b,0xac,0x82,0xc5,0xb5,0xe3,0x62,0x4a,0xb6,0xa5,0xcb,0xdb,0x82,0xb5,0x39,0x5b, +0x4a,0x8a,0xbe,0x49,0x3b,0xd3,0xaf,0x2e,0xbb,0xd3,0x9b,0x8f,0xa0,0xa2,0x76,0x06, +0x9c,0x71,0x14,0xf8,0xb7,0x64,0x10,0x00,0x19,0x91,0xa3,0x0b,0xad,0x8b,0xbc,0x9b, +0xea,0xc4,0xa8,0xc3,0x17,0x5a,0xbc,0x74,0xba,0xa8,0x6b,0x3c,0x85,0xbb,0x37,0xb3, +0xb2,0x6a,0x3b,0x46,0x7b,0xba,0x79,0x3b,0x59,0x03,0xba,0x95,0xbb,0x58,0x4b,0xba, +0x9c,0x71,0x14,0xe2,0xa6,0x53,0x10,0x00,0x71,0x73,0x68,0xa9,0x32,0xad,0x7a,0xca, +0x17,0xc1,0x7c,0x8c,0x46,0xf7,0xb1,0x81,0x73,0x58,0xe8,0x42,0x93,0x83,0x48,0xc7, +0x32,0x7d,0x84,0x46,0x96,0xb9,0x42,0x9b,0xd0,0x82,0x2b,0x24,0x82,0xca,0x16,0xd9, +0x9c,0x71,0x14,0xbc,0xa5,0x33,0x00,0x00,0xea,0x05,0xdc,0x05,0xa9,0x71,0xa8,0xd6, +0xd3,0x4b,0x85,0x2c,0xa8,0xb4,0xa2,0x8c,0x28,0xb7,0x93,0x5b,0x72,0x40,0x28,0xc3, +0xd3,0xb2,0xc4,0x3b,0xd3,0x8b,0xa7,0xc5,0x49,0x44,0x1b,0x9e,0x45,0x3c,0x0c,0x4c, +0x9c,0x71,0x14,0xc5,0xb8,0x77,0x20,0x00,0xa0,0x7b,0x38,0xb7,0xbb,0x74,0x7b,0xb6, +0x97,0xbb,0x68,0x7b,0xb7,0x17,0xbb,0x89,0x7b,0xba,0x37,0xbb,0xb3,0x7c,0x3b,0xc7, +0xc3,0xb3,0x7c,0x38,0x38,0xbb,0x31,0x54,0xb1,0x8b,0xa1,0x4f,0x6b,0xbc,0x09,0x14, +0x9c,0x71,0x14,0x22,0xb7,0x76,0x20,0x00,0xc3,0xa4,0x67,0xb5,0x29,0x76,0xb4,0x4b, +0x06,0x49,0xac,0x65,0x57,0xb6,0x67,0x68,0x56,0x97,0xa5,0x86,0x89,0x68,0x88,0x46, +0x96,0x77,0x89,0x86,0x62,0x52,0x83,0x76,0xba,0x36,0x9a,0x92,0x7a,0x27,0xa9,0x9a, +0x9c,0x71,0x14,0x7a,0xa7,0x55,0x10,0x00,0x83,0x6e,0xac,0x19,0x52,0xba,0x78,0xc7, +0xf8,0x99,0x88,0x81,0xda,0x77,0x13,0x80,0x7a,0x83,0xa7,0x1c,0x37,0x83,0x38,0x88, +0x43,0xbc,0x8e,0x3c,0x36,0xf4,0xcc,0x9c,0xac,0xf6,0x53,0x9e,0xb1,0xa0,0xa2,0x83, +0x9c,0x71,0x14,0x2b,0xc9,0x87,0x20,0x00,0x48,0x83,0x43,0x93,0x1a,0x6c,0x79,0x6a, +0x26,0x29,0x90,0x6d,0x27,0x27,0xd5,0x7e,0x75,0x99,0xb8,0x64,0x9f,0x7d,0x48,0x38, +0x43,0x85,0x83,0x38,0xc8,0x2b,0x78,0x82,0x36,0x57,0xa3,0x51,0x71,0xb4,0x65,0xaa, +0x9c,0x71,0x14,0xac,0xc7,0x76,0x00,0x00,0x79,0x3a,0x7a,0x31,0xca,0x96,0x6e,0x37, +0xb7,0xe9,0x86,0x7c,0xaa,0x59,0xa2,0x9d,0x98,0xb8,0x67,0x67,0x8e,0x85,0x57,0xe6, +0x59,0x47,0xb5,0x82,0x89,0x64,0x42,0x98,0xa9,0x76,0x86,0xae,0x78,0x58,0x76,0x6b, +0x9c,0x71,0x14,0xa5,0xc6,0x65,0x00,0x00,0x78,0x53,0x89,0x3c,0xb2,0xa6,0xac,0x69, +0x8d,0xa8,0x8e,0x34,0x39,0x14,0xbd,0x6e,0x9c,0x14,0x1a,0xc3,0x2f,0xac,0x34,0x70, +0xe5,0x89,0xa4,0x9a,0xc8,0x4c,0x97,0xb4,0x47,0xf3,0x52,0x8a,0xb4,0xaa,0x52,0xb5, +0x9c,0x71,0x14,0x4e,0xb6,0x56,0x10,0x00,0xc2,0xa2,0x69,0xd3,0xa5,0x83,0xbc,0x95, +0x43,0xc7,0x26,0x23,0x41,0x0a,0xc9,0x1a,0x82,0x86,0x5c,0xb2,0xbc,0x0a,0xcc,0x6d, +0x35,0x9b,0x12,0x49,0x6a,0x9c,0xc3,0xa2,0x3c,0xd1,0x47,0xa7,0x44,0xb7,0xb9,0xa2, +0x9c,0x71,0x14,0x76,0xb6,0x55,0x00,0x00,0x5a,0x39,0xe4,0x69,0x9c,0x35,0xc6,0x82, +0xca,0x1e,0x56,0xc4,0xaa,0x29,0xca,0xc2,0x3c,0xcb,0x02,0x93,0xa0,0x44,0x3b,0x4a, +0xc2,0xc1,0xc1,0x4b,0x19,0x9c,0x91,0xc2,0x27,0x2a,0x1d,0x5e,0x4d,0x25,0xab,0x1b, +0x9c,0x71,0x14,0x66,0xa5,0x54,0x00,0x00,0x35,0x59,0x94,0x45,0xa3,0x80,0x45,0xbd, +0x0e,0x24,0xfe,0x63,0x9e,0xbc,0x57,0xcb,0x16,0x3c,0xf8,0x3d,0xd4,0x52,0x4c,0x2b, +0x58,0x8e,0x68,0x96,0x46,0xa3,0x5d,0x38,0xc6,0x68,0x63,0x68,0x6a,0x88,0x0d,0xb8, +0x9c,0x71,0x14,0x09,0x95,0x54,0x00,0x00,0xce,0x4b,0x4f,0xe9,0x7c,0xfd,0x45,0x2d, +0xfa,0x78,0xca,0x98,0xad,0x97,0x85,0xcd,0x65,0xb9,0x53,0x43,0x59,0x68,0xa4,0x17, +0xa7,0x53,0x7b,0x44,0xc6,0x8b,0x63,0x38,0x49,0x67,0xa9,0xb5,0x5a,0x8a,0xbb,0xa5, +0x9c,0x71,0x14,0xf6,0x85,0x33,0x00,0x00,0x88,0x6b,0xd5,0x96,0x90,0x61,0x74,0xd6, +0x04,0xc3,0x8f,0xbc,0x27,0x65,0x0d,0x3b,0x89,0x25,0x55,0xd4,0x57,0x5d,0xb5,0x78, +0x62,0x88,0x83,0xc8,0x27,0x42,0x75,0x85,0xc6,0xb5,0xd3,0x7f,0x94,0x98,0xa7,0xac, +0x9c,0x71,0x14,0xae,0x74,0x12,0x10,0x00,0x64,0x80,0x99,0xca,0x2d,0x97,0x4b,0x18, +0x09,0x31,0xd6,0x89,0x19,0x65,0x2e,0x74,0xb3,0x2b,0x44,0x36,0x7c,0xc3,0x27,0xf5, +0xb1,0x8e,0x52,0x17,0x3d,0x89,0x6b,0x2c,0x99,0x18,0xad,0x6f,0x92,0xd4,0xc8,0xb1, +0x9c,0x71,0x14,0x9f,0x75,0x02,0x00,0x00,0xd1,0xa4,0xb8,0x95,0x46,0x2a,0xd1,0x36, +0x98,0x76,0x66,0x77,0x45,0x5a,0xd1,0x64,0x28,0xe9,0xfd,0xdb,0x90,0xad,0x54,0xcc, +0xb2,0x3e,0xa6,0x64,0xd5,0x8a,0x7e,0x37,0x87,0xdb,0x31,0x7a,0x48,0xab,0x64,0x2a, +0x9c,0x71,0x14,0xa1,0xa6,0x02,0x00,0x00,0x83,0x9f,0x48,0x51,0x87,0x7e,0xad,0x9a, +0x89,0x69,0xcd,0x5a,0x56,0x72,0xb9,0x62,0x5b,0x9a,0x4d,0x56,0x7a,0xac,0x95,0xfa, +0x3b,0x5a,0x48,0x87,0xdb,0x96,0x91,0x99,0x48,0xc8,0xea,0x9c,0x37,0x87,0xf5,0x15, +0x9c,0x71,0x14,0xe3,0x96,0x34,0x00,0x00,0x5b,0x83,0x65,0x88,0xb7,0x5b,0x6b,0x86, +0x69,0x37,0x8b,0x64,0x89,0xc8,0xc6,0x99,0x92,0x7b,0xb5,0x36,0x86,0x82,0x66,0xda, +0x28,0x77,0x5a,0x87,0xa6,0x47,0x70,0xe2,0xb5,0x02,0x32,0x4d,0x8d,0xc0,0xcd,0x43, +0x9c,0x71,0x14,0x02,0xc6,0x54,0x00,0x00,0x66,0x8e,0xa6,0x55,0x55,0x6b,0x3d,0xa7, +0xfb,0xdc,0x9b,0x21,0xaa,0x65,0x5b,0x99,0x41,0xb8,0x7a,0xd4,0x7a,0xc5,0xb6,0x34, +0xda,0x3d,0xb6,0x22,0x85,0x2b,0x59,0xb9,0x4a,0xc5,0x1b,0xc8,0xb1,0xaa,0x9b,0x1b, +0x9c,0x71,0x14,0x11,0xc6,0x65,0x10,0x00,0x8c,0x54,0x39,0x42,0x3b,0x95,0xab,0xb8, +0x6c,0xba,0x5a,0x9c,0x31,0xdc,0x39,0x0f,0x55,0xd6,0x9a,0xac,0xca,0x53,0x8d,0x14, +0xb6,0x9b,0x1b,0x87,0xc6,0x45,0x96,0x33,0xa9,0xfa,0xc3,0x8c,0x44,0xb5,0xda,0x43, +0x9c,0x71,0x14,0x9d,0xc6,0x66,0x10,0x00,0x22,0xc7,0x60,0xe5,0xeb,0x60,0x96,0x5c, +0x5b,0x77,0xd3,0x55,0x99,0xe5,0x84,0x7b,0x87,0x99,0x47,0x75,0x9e,0x36,0x78,0xb8, +0x87,0x5d,0x48,0x72,0x2d,0x57,0x0d,0x4e,0xa6,0x19,0x93,0xc8,0xa7,0x7d,0x54,0x59, +0x9c,0x71,0x14,0x3d,0xd7,0x76,0x10,0x00,0x8c,0xb4,0x27,0x74,0x3d,0x8a,0x43,0x99, +0x8b,0x3c,0x90,0x42,0xb6,0xda,0xc3,0x46,0x63,0x53,0xb1,0x51,0x71,0x45,0xba,0x94, +0xbc,0xab,0x1b,0x98,0x8a,0x3d,0x71,0xc3,0xa8,0xf3,0x3b,0xa4,0xc3,0x59,0x4c,0x32, +0x9c,0x71,0x14,0x18,0xd8,0x75,0x20,0x00,0x6a,0xb1,0xe4,0x1d,0xd4,0x3a,0x1e,0x17, +0x44,0x74,0xab,0x42,0xaa,0xb2,0x9c,0x87,0xae,0x27,0x1c,0x59,0x93,0xad,0xea,0xc3, +0x99,0x9a,0xc1,0x86,0xeb,0xda,0x45,0xd9,0x93,0x92,0x5c,0x71,0xcb,0x1a,0xab,0x29, +0x9c,0x71,0x14,0x94,0xd8,0x76,0x20,0x00,0xae,0xa5,0xa8,0xca,0x5d,0x72,0xc1,0xb9, +0x3a,0x5a,0xae,0x3d,0x49,0xbc,0x12,0x6e,0xbd,0xc4,0x4e,0x5b,0x38,0x25,0x37,0x24, +0xb2,0xab,0xae,0x3a,0xf2,0xa2,0x8d,0x31,0xd7,0x3c,0x13,0x95,0xc1,0xba,0xd4,0xa3, +0x9c,0x71,0x14,0x52,0xd8,0x87,0x10,0x00,0x97,0x54,0x26,0x94,0xc3,0x41,0xcb,0xc4, +0x1c,0x5b,0x7e,0x3c,0x2a,0xfb,0xc4,0xab,0xab,0xb8,0x62,0xc3,0x74,0x34,0x49,0x93, +0xc2,0xa9,0xbb,0xd8,0xa5,0xc2,0x5b,0xd3,0xa3,0xab,0x45,0x52,0x4a,0x19,0x63,0x33, +0x9c,0x71,0x14,0x19,0xc9,0x88,0x30,0x00,0xea,0x87,0x7c,0x49,0x66,0x72,0x67,0x87, +0xa9,0x97,0xc6,0x68,0x5b,0x49,0x88,0x5e,0x99,0x70,0x58,0xea,0x02,0xea,0x2a,0xab, +0x96,0xf2,0xc9,0xaa,0xf6,0x96,0x58,0x4a,0xaa,0x35,0x77,0xed,0x38,0x18,0x44,0x8b, +0x9c,0x71,0x14,0xb7,0xdb,0x98,0x20,0x00,0x55,0x6c,0x34,0x16,0xd3,0x68,0xc5,0x2a, +0xc8,0x55,0x8d,0x95,0x28,0x27,0x5b,0x89,0x6d,0xc9,0xa7,0x4a,0x9d,0x64,0xb7,0xf6, +0x3c,0x65,0x7c,0x23,0xe7,0x5a,0x65,0xe7,0x3b,0xa6,0xe5,0x7f,0x8d,0x87,0x54,0xde, +0x9c,0x71,0x14,0x53,0xdc,0x99,0x40,0x00,0x91,0x72,0x39,0xc6,0xe2,0x95,0x71,0xc7, +0xd7,0x13,0x69,0x85,0xb3,0xc7,0x62,0x74,0xcf,0x1a,0xc7,0x76,0x75,0x86,0xb7,0xf5, +0xaa,0x95,0x6a,0x49,0x57,0x1a,0x95,0x75,0xb7,0xd7,0x9c,0x61,0x91,0xa3,0x55,0x95, +0x9c,0x71,0x14,0xdc,0xdc,0x98,0x40,0x00,0x93,0xcd,0x29,0x68,0x58,0x79,0x96,0x58, +0x56,0xa2,0x97,0x66,0x38,0xf7,0xdd,0x92,0x79,0x97,0x47,0x9b,0x59,0x90,0xc3,0xc5, +0x41,0xb0,0x64,0xc7,0x8a,0x56,0x85,0x89,0x18,0x79,0x5b,0x91,0x59,0xb8,0xe8,0x1a, +0x9c,0x71,0x14,0xdc,0xdc,0x98,0x40,0x00,0x89,0x79,0x36,0xd9,0x5b,0x3f,0x65,0xa7, +0x9d,0x2b,0x98,0x11,0xc7,0xb9,0x59,0x81,0x75,0xd8,0xf9,0xda,0x89,0x79,0xb9,0x56, +0x9c,0x73,0x79,0x96,0x19,0x5c,0x3c,0x48,0x8a,0xe7,0x96,0x6f,0xc9,0x48,0xd4,0xe1, +0x9c,0x71,0x14,0x53,0xdc,0x99,0x40,0x00,0x80,0x85,0xc8,0xe6,0x1a,0x8f,0xa5,0xb8, +0x67,0xdb,0x70,0x7e,0x43,0xe5,0xe3,0x81,0xf2,0x99,0x10,0x5d,0x83,0x8d,0xa7,0xf8, +0x9b,0x8d,0x8d,0xb8,0x77,0x9b,0x95,0x5d,0xb7,0x28,0x9c,0x63,0x95,0x34,0x75,0x0a, +0x9c,0x71,0x14,0xe1,0xcc,0x88,0x40,0x00,0xe2,0xb3,0xa6,0x5e,0x36,0xa0,0x74,0x18, +0x91,0xc5,0x96,0xc2,0xca,0x94,0x21,0x7b,0x0a,0x46,0x8f,0x3b,0x00,0xaf,0x4a,0xbe, +0x32,0x86,0x5d,0x19,0xed,0xae,0x7b,0x5c,0x2a,0x2d,0xcc,0x99,0x1c,0xb9,0x8b,0x42, +0x9c,0x71,0x14,0x57,0xcd,0x88,0x30,0x00,0x69,0x0c,0x22,0x90,0xb3,0x5d,0x25,0x3b, +0x87,0xce,0x85,0x65,0x19,0x4e,0xc3,0x9c,0xfb,0xb9,0x8d,0xb4,0xad,0x04,0x34,0xf0, +0x43,0x13,0x0b,0x95,0x51,0x64,0xca,0x83,0xc8,0x15,0xc3,0xa8,0xeb,0x29,0x50,0xbb, +0x9c,0x71,0x14,0xc4,0xdc,0x88,0x40,0x00,0x8e,0x59,0xa9,0x08,0xd4,0x5a,0x8e,0x33, +0xb5,0xf3,0x95,0xd5,0xb8,0x43,0x22,0x91,0x81,0x38,0x88,0x5b,0x8f,0x85,0xb8,0xc8, +0x93,0x83,0x5e,0x44,0x89,0xdb,0x52,0x4c,0x2a,0x77,0x59,0x75,0xc2,0x49,0xc5,0x5c, +0x9c,0x71,0x14,0x67,0xdc,0x78,0x30,0x00,0x86,0x85,0xb8,0xf5,0xe3,0x8f,0x9e,0xb6, +0x37,0x1b,0x3e,0x6b,0x49,0x5c,0xa3,0x88,0x3d,0x28,0xd8,0x1b,0x8f,0x79,0x39,0x28, +0xe2,0x8e,0x85,0xc8,0x56,0x13,0x3f,0x94,0x37,0x38,0x65,0xa1,0x3a,0x28,0x0a,0xda, +0x9c,0x71,0x14,0xb8,0xcb,0x87,0x30,0x00,0xb5,0x6a,0xaa,0x2a,0xcc,0x9e,0x34,0x4a, +0xe7,0xbb,0x20,0x8c,0x33,0x84,0x12,0xd0,0x6a,0xa7,0x9d,0xb4,0xb5,0x53,0xba,0x77, +0xba,0x97,0x3b,0x5b,0x5b,0xa1,0x49,0x6b,0x41,0x65,0x3a,0xcc,0xa9,0xc7,0xc9,0xc2, +0x9c,0x71,0x14,0xb8,0xcb,0x87,0x30,0x00,0xac,0x5c,0x2a,0x57,0x34,0x94,0x49,0xca, +0x4c,0xa2,0x60,0x51,0xb0,0xc7,0x34,0xc1,0xb1,0xc8,0x28,0xaa,0x9e,0x6b,0x3a,0x46, +0xbb,0x92,0x63,0xa9,0x1b,0xa5,0x67,0x51,0xa0,0xa8,0x20,0xc3,0x8a,0x67,0xaa,0x3b, +0x9c,0x71,0x14,0x93,0xcb,0x87,0x40,0x00,0x9d,0x6b,0x49,0xd7,0xbb,0x91,0x53,0x28, +0x5a,0x43,0x62,0x51,0xb1,0x48,0x8a,0xc6,0x6b,0xd7,0x4a,0x3a,0xa1,0x6d,0x49,0xb9, +0x4b,0x89,0x5b,0xa8,0x5a,0x34,0x40,0x3a,0xb3,0xeb,0xcc,0xc0,0x3c,0x96,0xe9,0xbb, +0x9c,0x71,0x14,0x30,0xcb,0x77,0x30,0x00,0xa3,0x5d,0xc9,0x59,0x91,0x81,0x71,0xc8, +0x1a,0x4c,0x1e,0x2e,0x66,0x9d,0x81,0xa7,0x5c,0xa6,0xba,0x94,0x9d,0x6e,0x37,0x18, +0x9a,0x6d,0x7e,0xc6,0xb8,0x1b,0x29,0x5b,0x57,0xdb,0x51,0x99,0x74,0xb6,0x29,0xdc, +0x9c,0x71,0x14,0x40,0xba,0x98,0x30,0x00,0x93,0x07,0x75,0xaf,0x87,0x55,0x18,0x57, +0x6f,0x98,0x5e,0xe7,0x87,0xaf,0x77,0x72,0xd8,0x76,0x6f,0x87,0x78,0xe7,0x76,0xef, +0x77,0x5e,0xe7,0x67,0xae,0x87,0x68,0xd7,0x75,0xd0,0x77,0x28,0x65,0x88,0xef,0x1b, +0x9c,0x71,0x14,0xcb,0xb8,0x88,0x20,0x00,0xbf,0x31,0x25,0x05,0x18,0x5d,0x73,0x79, +0xf3,0x27,0x86,0x83,0x78,0x18,0x47,0x7e,0x65,0x78,0x68,0x57,0x89,0x95,0x77,0xa7, +0x68,0x8c,0xa5,0x79,0xf7,0x67,0x89,0x86,0x78,0xf8,0x67,0x90,0x76,0x79,0x97,0x77, +0x9c,0x71,0x14,0x9a,0x97,0x54,0x10,0x00,0xdc,0x91,0xa9,0xb7,0xab,0xbd,0xbb,0x3f, +0x09,0x8e,0xc1,0xb4,0x0b,0x19,0xa4,0xd2,0x92,0xac,0x69,0x32,0xac,0x7c,0x29,0xd7, +0x6c,0xbf,0x8b,0xeb,0xb8,0x5c,0xb9,0x86,0x1b,0x96,0x54,0xcf,0x36,0x1b,0xe9,0x65, +0x9c,0x71,0x14,0x88,0x96,0x55,0x10,0x00,0xbd,0x44,0x3c,0x93,0xdb,0xd2,0x9a,0x1c, +0xb6,0xb4,0xba,0x3e,0x4b,0xe5,0xc4,0xc3,0x5e,0x2a,0x75,0xd3,0xaa,0x84,0x3a,0xf5, +0xbb,0xb0,0x62,0xba,0xa7,0xbb,0xa0,0x8c,0x3a,0x39,0xb3,0x99,0x6b,0x39,0x38,0x3b, +0x9c,0x71,0x14,0xa4,0x83,0x32,0x10,0x00,0xaf,0x87,0x2a,0xab,0x92,0x9d,0x76,0x98, +0x87,0xa1,0x86,0x76,0x98,0x87,0x75,0x82,0x66,0x97,0xb6,0x6d,0x74,0x44,0xd6,0xe9, +0x6d,0x61,0x65,0x55,0x35,0x71,0x4f,0x56,0x14,0xc9,0x69,0x3e,0x55,0x53,0x54,0x69, +0x9c,0x71,0x14,0x00,0x98,0x76,0x20,0x00,0x54,0xf7,0x74,0xef,0x77,0x4a,0xf7,0x74, +0x6e,0x67,0x4c,0xd7,0xc4,0x68,0x03,0x45,0x53,0x53,0x99,0x58,0x3b,0x18,0x94,0x2e, +0x87,0x4e,0xf9,0x74,0xd1,0x97,0x4f,0x08,0x75,0x2e,0x86,0x58,0xe8,0x75,0xcf,0x77, +0x9c,0x71,0x14,0xa6,0x85,0x53,0x00,0x00,0x3e,0x71,0xb4,0x14,0x43,0x4e,0x3e,0x45, +0x76,0x52,0x66,0x83,0xb6,0xc7,0xbc,0x6c,0x84,0x36,0xf8,0x4a,0x78,0x7b,0xb8,0x47, +0xb3,0x8b,0x63,0x48,0xf6,0xb9,0x92,0x73,0x39,0x87,0x3a,0x9a,0x83,0xa9,0xe7,0xbb, +0x9c,0x71,0x14,0x73,0x84,0x23,0x00,0x00,0xa1,0x7c,0x3a,0x68,0x3b,0xaa,0x7a,0x4b, +0x07,0x9c,0xb3,0x83,0x3b,0x56,0xc3,0xb9,0x79,0x1b,0xc4,0xa5,0xbf,0x1e,0x3c,0x27, +0x14,0xc6,0xb5,0x3c,0xda,0xba,0xd1,0x8d,0xbd,0x17,0x44,0xd3,0x6c,0xbd,0x86,0xb2, +0x9c,0x71,0x14,0x07,0x81,0x12,0x00,0x00,0xdd,0xab,0x4d,0xfc,0x27,0xe1,0x5b,0x4e, +0x4d,0xb5,0xe8,0x21,0x8e,0xa2,0xc4,0xec,0x33,0x8e,0xec,0xd2,0xf0,0x59,0xbf,0x25, +0x38,0xf4,0x4c,0x8f,0x3c,0x25,0xf1,0xad,0x3e,0xeb,0xd5,0xeb,0x4d,0x9e,0x8b,0x4b, +0x9c,0x71,0x14,0x17,0x85,0x55,0x10,0x00,0xe5,0x77,0x8e,0x17,0x77,0xda,0x77,0x7d, +0x27,0x78,0xcb,0x66,0x7c,0x47,0x77,0xbc,0x76,0x6b,0x16,0x78,0xab,0x55,0x8a,0x26, +0x64,0x93,0x66,0xa7,0xc9,0x65,0x74,0x77,0x47,0x63,0x6b,0x69,0x45,0x35,0xa4,0xb9, +0x9c,0x71,0x14,0xce,0xa8,0xa9,0x40,0x00,0x71,0x0f,0x77,0x2c,0xf7,0x74,0xcf,0x77, +0x8e,0xe6,0x7e,0x71,0x9a,0x54,0xa2,0x49,0xaf,0xd6,0x33,0x15,0xad,0x8d,0x7e,0xc3, +0x38,0x4f,0x70,0x32,0x4a,0xea,0x6e,0xcf,0x5d,0x31,0x0c,0x87,0x47,0x14,0xe3,0x69, +0x9c,0x71,0x14,0x07,0x98,0x87,0x20,0x00,0x12,0xc0,0x5d,0xc6,0xc9,0x99,0x28,0x54, +0x0c,0x99,0x3b,0x17,0x57,0x8f,0x6a,0x7d,0x08,0x46,0x6d,0x6a,0x72,0xf7,0x58,0x2f, +0x79,0x8c,0xd9,0xc9,0x8e,0x8c,0x93,0x07,0xa8,0xd0,0x65,0x9d,0x0a,0x9b,0x50,0x7c, +0x9c,0x71,0x14,0xe2,0x85,0x86,0x20,0x00,0xbd,0x1c,0x8a,0xdc,0xec,0xd4,0xb9,0xde, +0x94,0x22,0xc4,0xb9,0xac,0x2c,0x62,0xd5,0x31,0xdc,0xd4,0x99,0xac,0xbe,0x5a,0xdb, +0x48,0xc8,0x3b,0x1a,0xa4,0x0d,0x99,0xc2,0x99,0x23,0x1a,0x9a,0x42,0x2a,0x5b,0xde, +0x9c,0x71,0x14,0xe1,0xa5,0x76,0x10,0x00,0x8c,0x9c,0x88,0xea,0x54,0x90,0x57,0x68, +0x61,0x4a,0x80,0x39,0x57,0x23,0x5b,0x62,0x8b,0x36,0x35,0x8c,0x74,0x3c,0x57,0x5a, +0x66,0x83,0xa6,0x7a,0x69,0x39,0xce,0x45,0x9e,0x58,0xa3,0xc8,0x17,0xa9,0xac,0x92, +0x9c,0x71,0x14,0xe3,0xb7,0x76,0x10,0x00,0x64,0x45,0xe3,0xd8,0x62,0x26,0x45,0xb2, +0x84,0xd5,0x72,0x78,0x5c,0x35,0x79,0xc8,0x96,0x5b,0xf6,0xca,0xd1,0x86,0x6d,0xa7, +0xa6,0xa8,0xa4,0xa5,0xb4,0x22,0x33,0x85,0xc0,0x00,0x73,0x10,0x41,0x8a,0x95,0x19, +0x9c,0x71,0x14,0x94,0xc7,0x75,0x10,0x00,0xae,0x8b,0x98,0x81,0xcb,0x8a,0xad,0xdb, +0x74,0x62,0xbb,0xc4,0xb8,0x34,0xc3,0x53,0x45,0x24,0x0d,0x4c,0x2f,0x0a,0x98,0x2d, +0xad,0xba,0xab,0x88,0xcc,0x2e,0x74,0xc3,0x09,0x72,0x36,0xc5,0x3a,0xaa,0x8b,0x3b, +0x9c,0x71,0x14,0x48,0xc8,0x75,0x00,0x00,0x62,0x63,0xc4,0xb9,0x32,0x3b,0x73,0xb4, +0x8c,0x65,0xa0,0x65,0x1a,0x88,0x53,0x7f,0x8b,0xb7,0x36,0x43,0x98,0x93,0xcc,0x07, +0xb9,0x99,0x74,0x57,0x97,0xc2,0x65,0x74,0x33,0xc8,0x3b,0x2e,0x84,0xc6,0x97,0xca, +0x9c,0x71,0x14,0xb7,0xc7,0x64,0x00,0x00,0xa8,0xb4,0x5b,0x15,0x39,0x8c,0xac,0xb8, +0xac,0x32,0xb7,0x3a,0xdb,0x1b,0x3a,0x72,0x2b,0xb3,0x0b,0xb4,0x0f,0x0a,0x34,0x65, +0x14,0xaa,0x3a,0x2c,0x6a,0xc5,0xa2,0x4b,0x97,0x0b,0xb3,0x8e,0xcb,0xbb,0xc4,0x44, +0x9c,0x71,0x14,0xb7,0xc7,0x64,0x00,0x00,0xa0,0x4b,0xa5,0x84,0x43,0x1a,0x54,0xa1, +0x94,0x6c,0x79,0xbd,0x9c,0x2a,0xc5,0xb7,0xd3,0x38,0x28,0xc2,0x71,0xc4,0x3a,0x92, +0xbb,0xba,0xb2,0xb8,0x52,0xb2,0x39,0x41,0xb0,0xa9,0xbc,0x38,0xe2,0x2a,0x54,0x9b, +0x9c,0x71,0x14,0xb7,0xc7,0x64,0x00,0x00,0xc7,0x33,0x2a,0x45,0xc4,0x70,0xbb,0x28, +0x85,0x43,0xb9,0xc4,0x4a,0x8c,0x43,0x64,0xbc,0xa2,0x44,0xcd,0x0f,0x95,0x16,0x53, +0x65,0xbf,0x9c,0xac,0x0c,0xcb,0x8a,0x93,0xc7,0x3c,0xc2,0xab,0x2b,0x3b,0xc3,0x3b, +0x9c,0x71,0x14,0x94,0xc7,0x75,0x10,0x00,0x82,0xab,0x33,0x4b,0x33,0x06,0x8b,0x33, +0xd4,0x1b,0xac,0xba,0xac,0xf3,0x3c,0xaa,0x53,0x97,0x44,0x2d,0x8f,0xdb,0xac,0x04, +0x3b,0xa6,0xc3,0xc5,0xb4,0x42,0x13,0xc4,0x31,0x04,0x54,0x7a,0x34,0x2c,0xea,0xc2, +0x9c,0x71,0x14,0x8c,0xc7,0x65,0x10,0x00,0xc6,0x5b,0x48,0xc8,0xca,0x77,0xbb,0xea, +0xe2,0xb2,0xbc,0x34,0x38,0x3b,0x41,0x35,0xca,0x50,0x51,0x21,0x3f,0x50,0xcb,0x23, +0xbb,0xd4,0xbb,0xba,0xc5,0xb3,0x75,0xc3,0x58,0xf5,0xc1,0xbd,0x53,0xca,0x23,0xcc, +0x9c,0x71,0x14,0x2c,0xc9,0x76,0x20,0x00,0x57,0x9c,0xa0,0x35,0xdd,0x2c,0xab,0x99, +0xf9,0xbc,0xcb,0x6c,0x99,0xb9,0xcd,0x6b,0x6d,0xb9,0xd8,0xec,0xd8,0x76,0x39,0xd6, +0xea,0x41,0x74,0xb1,0x78,0xc6,0x20,0x32,0x0b,0x03,0xdd,0xba,0x4c,0xc7,0x25,0x50, +0x9c,0x71,0x14,0x2b,0xc9,0x87,0x20,0x00,0x74,0x5c,0xda,0x86,0x4a,0xc5,0x54,0x39, +0x66,0x53,0x72,0x64,0xb6,0x66,0xcb,0x20,0x7d,0x41,0x94,0xc3,0xcc,0x1e,0x8b,0x24, +0xee,0x57,0x4e,0x96,0xe5,0xed,0xbe,0x6d,0xbc,0xf6,0x62,0x89,0x6e,0x36,0xc7,0x5c, +0x9c,0x71,0x14,0x01,0xc9,0x98,0x30,0x00,0x65,0x88,0x60,0xf8,0x99,0x27,0x9a,0x8d, +0xc2,0xc3,0x9b,0x7b,0xa5,0x05,0xa5,0x80,0x7b,0x8c,0x68,0x99,0xbf,0x6a,0x78,0x37, +0x97,0x71,0x7a,0x65,0xf8,0x87,0x05,0x99,0x83,0x7d,0x9a,0xe4,0x2c,0x28,0x59,0xba, +0x9c,0x71,0x14,0x89,0xca,0x97,0x20,0x00,0x55,0x74,0xa8,0xb7,0x52,0xc0,0x84,0x5b, +0x57,0xc9,0x87,0x7c,0xd7,0x08,0x4a,0x58,0x95,0x40,0x07,0xd2,0x54,0xce,0x4e,0x05, +0x5b,0x73,0x9d,0xb5,0xf7,0xd3,0x93,0x84,0xab,0x69,0x4c,0xb1,0x7c,0x38,0xc7,0xbc, +0x9c,0x71,0x14,0x0f,0xca,0x98,0x20,0x00,0x71,0x18,0x64,0xf4,0x87,0x04,0xd8,0x47, +0x3c,0xac,0xda,0xc7,0x76,0x56,0x94,0x68,0xf6,0x99,0x11,0x85,0xb1,0x27,0xab,0x51, +0x85,0x95,0x07,0x87,0x51,0x87,0x5b,0x28,0x71,0x2f,0x97,0x55,0x8b,0x9d,0xca,0xd5, +0x9c,0x71,0x14,0x37,0xca,0xa9,0x40,0x00,0x71,0x39,0x46,0xaf,0x92,0x92,0xf8,0xca, +0xf3,0x82,0xb9,0x08,0x49,0x70,0x8b,0x77,0x07,0xb5,0xb3,0x7b,0x10,0x98,0xb7,0x5a, +0x48,0xc8,0xe1,0xe6,0xd5,0x51,0x75,0x13,0xd8,0xee,0x4a,0xb3,0x06,0x5b,0x6e,0x61, +0x9c,0x71,0x14,0x16,0xca,0x97,0x40,0x00,0x9c,0x73,0x67,0x57,0x39,0x53,0x84,0x40, +0xf5,0xc9,0x6f,0xd6,0x6d,0x15,0x29,0x67,0xa3,0xd7,0x67,0xa8,0x94,0x6b,0x5b,0x29, +0x2a,0xbc,0x7b,0x49,0x37,0x2b,0x72,0x7b,0xb4,0xe9,0x32,0x15,0x5c,0x37,0x5b,0xb0, +0x9c,0x71,0x14,0x87,0xc9,0x97,0x30,0x00,0xcf,0x39,0xe6,0xea,0xaa,0x72,0x72,0xc9, +0xc7,0x2c,0xb6,0x82,0xcb,0x87,0x3a,0x8d,0x74,0x27,0x07,0x3a,0x4d,0x8b,0xc1,0x82, +0xcb,0x7d,0xba,0x1c,0x64,0x8e,0x76,0x94,0x26,0xe7,0x2a,0x9d,0x7c,0xcb,0xd7,0xd2, +0x9c,0x71,0x14,0xe0,0xc8,0x96,0x10,0x00,0xb5,0x6d,0xc8,0x58,0x31,0x6b,0x8b,0xe4, +0x9a,0xb9,0x22,0x4b,0xd8,0x2d,0x28,0xbf,0x52,0x67,0xda,0x42,0x69,0x7b,0x29,0x66, +0xc4,0xc4,0x7c,0x2a,0x86,0xbb,0x72,0x8b,0x25,0xf7,0xbc,0x48,0x6a,0x13,0x55,0x36, +0x9c,0x71,0x14,0x73,0xb7,0x96,0x10,0x00,0x77,0x62,0x8e,0x32,0xa5,0x9f,0x8e,0x95, +0x87,0x54,0x94,0x87,0xbf,0x38,0x92,0xbd,0x74,0x34,0x56,0x83,0x2e,0x78,0xa3,0xa7, +0x74,0x37,0x69,0x36,0x77,0x73,0xa1,0x66,0xb9,0xa8,0x8b,0x69,0x77,0x37,0x68,0x73, +0x9c,0x71,0x14,0x56,0xa5,0x74,0x00,0x00,0xe2,0x6d,0x3c,0xd8,0x43,0x5a,0x55,0xb3, +0xec,0x93,0x5b,0x74,0x16,0x89,0x5b,0x70,0x78,0xd7,0xc5,0x62,0x7c,0x78,0x47,0x38, +0x8b,0x89,0xa8,0x4a,0x19,0x83,0x89,0x67,0x26,0x89,0x73,0x68,0x97,0xa7,0x79,0x7b, +0x9c,0x71,0x14,0x82,0x94,0x63,0x10,0x00,0x83,0x57,0xb9,0xc5,0x8c,0x88,0x47,0xc6, +0xc7,0x6b,0x8d,0x68,0x3c,0x26,0x78,0xaf,0x46,0x56,0x44,0x6a,0x5d,0x86,0xc9,0x45, +0x6e,0xa9,0x59,0x3a,0x35,0x9b,0x9b,0x26,0x9a,0x62,0x32,0xb8,0x44,0x1c,0x30,0x5d, +0x9c,0x71,0x14,0x9d,0x99,0x76,0x20,0x00,0xbc,0xf6,0x7a,0x8e,0x67,0xa6,0xe6,0x7a, +0xed,0x47,0xaa,0xf3,0x7a,0x8f,0x47,0xac,0xd5,0x7c,0x6e,0x03,0xa8,0x33,0xa8,0x50, +0x88,0x81,0x15,0x79,0x2f,0x88,0x9c,0xf8,0x7a,0x0c,0x66,0x8e,0xf7,0x69,0x0f,0x87, +0x9c,0x71,0x14,0x70,0x75,0x43,0x00,0x00,0xc3,0xc3,0xee,0xa5,0x54,0xf8,0x86,0x3b, +0xe9,0xdc,0x9e,0x7d,0x4a,0x37,0x2b,0x9f,0x94,0x2a,0x59,0xdc,0x82,0x85,0x17,0x44, +0xd1,0x7c,0x74,0x57,0xf6,0x45,0x76,0x6c,0xa7,0x7a,0x49,0x63,0xa4,0xc4,0x57,0xc2, +0x9c,0x71,0x14,0xb7,0x75,0x32,0x00,0x00,0x35,0x7c,0x93,0xa6,0x11,0x2d,0x68,0xc2, +0x28,0x0a,0x20,0x8b,0x41,0xc8,0xcd,0x18,0x76,0xc1,0x86,0x4c,0x1b,0x7b,0xa1,0x5b, +0x1a,0x0e,0xca,0x41,0x47,0x23,0x1f,0x49,0x31,0xd6,0x1d,0x1e,0x7a,0x12,0x29,0xa8, +0x9c,0x71,0x14,0xe1,0x71,0x22,0x00,0x00,0x2f,0x69,0xb3,0x48,0xa3,0x37,0xac,0x63, +0xd3,0x69,0x44,0xea,0xb4,0xa0,0x89,0x4a,0x98,0x64,0xbe,0x78,0x4e,0x46,0xa5,0x14, +0x7c,0x54,0xa5,0x75,0x4c,0x71,0x51,0xd6,0x34,0xdc,0x99,0x49,0x56,0xb4,0x5b,0x66, +0x9c,0x71,0x14,0x5e,0x71,0x03,0x00,0x00,0x42,0xdd,0x03,0xd2,0x95,0x3a,0xa0,0xf3, +0x56,0xef,0x2e,0xe4,0xe2,0x91,0x2b,0x23,0x5f,0x42,0x09,0x6f,0x20,0xda,0xc1,0xf1, +0x90,0x1b,0x99,0x21,0x91,0x48,0x16,0x5a,0xd1,0x71,0x53,0x14,0x91,0x80,0xfd,0xb4, +0x9c,0x71,0x14,0x6b,0x72,0x02,0x00,0x00,0x0e,0x18,0x70,0xfb,0x08,0x11,0x1a,0x90, +0xf9,0xb7,0x0e,0x21,0xa0,0xe1,0x8e,0x0e,0x5b,0x11,0x02,0x0d,0x0d,0xdf,0x60,0xc1, +0xb7,0x0d,0x56,0xc1,0x49,0x97,0x19,0xe7,0x41,0xe2,0x10,0x1f,0x21,0x02,0x1d,0xcc, +0x9c,0x71,0x14,0xc3,0x70,0x03,0x00,0x00,0x26,0x18,0x92,0xa2,0x77,0x2c,0xb9,0xc3, +0x00,0x72,0x35,0x14,0xc3,0xaf,0x84,0x40,0xfc,0xa4,0x61,0x92,0x4a,0xe9,0x44,0xff, +0x49,0x54,0xe6,0xb5,0x86,0x76,0x59,0xf7,0xb5,0xa6,0x8c,0x5b,0x96,0xf5,0xfc,0x99, +0x9c,0x71,0x14,0x2b,0x83,0x33,0x10,0x00,0x72,0x77,0x17,0x67,0x6d,0x7a,0x88,0xd7, +0xd7,0x4e,0x83,0x79,0x68,0x79,0x72,0x8d,0xa6,0x59,0x77,0x91,0x9e,0x46,0xda,0x8a, +0x6d,0xb3,0x54,0x4b,0x42,0x28,0xc0,0x48,0xcc,0xd9,0xa9,0xcd,0x57,0x9d,0x46,0x86, +0x9c,0x71,0x14,0x71,0xa8,0x88,0x40,0x00,0x91,0xdd,0xd9,0x5d,0xdd,0x95,0xdd,0xd9, +0x9d,0xdd,0x95,0xdd,0xd9,0x5d,0xdd,0x95,0xdd,0xd9,0x9d,0xd9,0x95,0xdd,0xd9,0x9d, +0xe2,0x99,0xde,0x2a,0x21,0x59,0xa9,0x66,0x0d,0x5c,0x40,0xdb,0x5b,0x4a,0x40,0x99, +0x9c,0x71,0x14,0x32,0xa7,0x88,0x30,0x00,0xb3,0x75,0x6c,0x20,0xab,0xb0,0xcf,0x58, +0x94,0xb6,0x84,0xf1,0x79,0xa6,0x87,0xa8,0x90,0x8a,0x0d,0x02,0xb1,0x06,0xb9,0x00, +0xd5,0x6f,0x2e,0x98,0x29,0x27,0x9e,0x6d,0x88,0xef,0x36,0x76,0xad,0x77,0xad,0x76, +0x9c,0x71,0x14,0x7d,0x96,0x86,0x20,0x00,0xb8,0xf1,0x8a,0x7b,0x57,0x84,0xb2,0xa8, +0x7d,0x84,0x83,0x29,0xc7,0x57,0x12,0x96,0xe5,0xbb,0x13,0x04,0xa5,0x2b,0x7b,0x2b, +0x49,0xc5,0x29,0x4d,0x23,0x8c,0xb9,0x50,0x3a,0xd7,0x1b,0x9f,0x8f,0x51,0x96,0xf8, +0x9c,0x71,0x14,0x4c,0xc8,0x86,0x00,0x00,0x60,0x8a,0xb5,0xa6,0x3b,0x70,0xa1,0x29, +0xa7,0xb4,0xad,0x91,0x99,0xc8,0x2d,0x7a,0x5a,0x18,0x76,0xad,0xa3,0x62,0x19,0x15, +0xbd,0x5f,0x43,0x94,0x06,0x4d,0x3d,0x0b,0x97,0x84,0xad,0xb2,0x44,0x2b,0x65,0xcc, +0x9c,0x71,0x14,0xa8,0xc7,0x85,0x00,0x00,0x76,0x49,0x94,0xe2,0x9d,0x85,0x5a,0x2b, +0x43,0x93,0x9b,0x69,0xb7,0x58,0x9b,0x7b,0x99,0x38,0xb9,0x82,0x70,0xbb,0x53,0x5a, +0x81,0x23,0xac,0xe7,0xe5,0xe8,0xc8,0xab,0xea,0xea,0xc9,0x53,0xca,0x54,0xee,0x98, +0x9c,0x71,0x14,0xd1,0xc9,0x86,0x00,0x00,0x9f,0x8c,0x5b,0x19,0xc1,0x7a,0x8b,0xd6, +0x58,0xa9,0x8a,0x83,0x49,0x27,0x2a,0x57,0x93,0x40,0xf7,0x2b,0x30,0xc3,0x3a,0xe8, +0x8c,0xd5,0x91,0xa8,0x58,0x8c,0x34,0x79,0x26,0xc8,0x14,0xc0,0x71,0xa9,0x97,0x1b, +0x9c,0x71,0x14,0xc9,0xc9,0x96,0x00,0x00,0x5b,0x6b,0x47,0x26,0xba,0xab,0x73,0xc9, +0x26,0x42,0x42,0x84,0x31,0x06,0xcb,0x43,0xbd,0xcb,0x38,0x42,0xcc,0x9c,0x48,0x49, +0x3b,0x3f,0x9b,0xa7,0x89,0xb4,0xc3,0x93,0x29,0x48,0x2c,0x5e,0x8a,0x97,0xf7,0xae, +0x9c,0x71,0x14,0x4c,0xc8,0x86,0x00,0x00,0xb5,0x92,0x89,0x57,0x2d,0x48,0x6a,0xa3, +0x05,0x34,0x43,0x08,0x99,0x61,0x26,0xbf,0x1b,0x8a,0x23,0xd5,0x5c,0x3c,0xa6,0x34, +0x5c,0xb3,0x3d,0x2a,0xc5,0xdb,0x66,0x6d,0x27,0x75,0xec,0xb5,0x7e,0x2a,0xf7,0xe4, +0x9c,0x71,0x14,0x07,0xc7,0x97,0x10,0x00,0x66,0x59,0xb4,0x5a,0x93,0x54,0x98,0x45, +0xbd,0x8b,0x98,0x0c,0x3b,0xd5,0x9c,0xa0,0x5a,0xa6,0x09,0x94,0x7a,0x9a,0x3b,0x89, +0x94,0x93,0x8a,0x16,0x1e,0x95,0x8f,0xa8,0x9c,0x0d,0x84,0x9b,0xe7,0x25,0xb9,0x7c, +0x9c,0x71,0x14,0xc3,0xc8,0x87,0x00,0x00,0x58,0xc2,0xa5,0xba,0x2c,0x54,0xcc,0x39, +0x65,0x69,0xc3,0x93,0xd9,0xf6,0xd1,0x5d,0x93,0xc7,0x89,0x4b,0xae,0x74,0x38,0x87, +0x3b,0x64,0x8c,0x49,0x46,0xbb,0xb4,0x73,0x39,0x07,0xbb,0x5e,0x53,0xb5,0xc8,0xc4, +0x9c,0x71,0x14,0x6b,0xb7,0x86,0x10,0x00,0x2c,0x57,0x90,0xc3,0x6c,0x88,0x43,0x3f, +0xa3,0x72,0xbd,0x54,0xd3,0x44,0x78,0x4c,0x44,0xdb,0x83,0x62,0x8d,0x47,0x54,0xc6, +0x80,0x95,0x56,0xdd,0x15,0x71,0x90,0x67,0x53,0x24,0x7a,0x28,0x78,0x42,0x26,0x69, +0x9c,0x71,0x14,0x57,0xb7,0x76,0x00,0x00,0x11,0x47,0xd7,0xb7,0x03,0xe2,0x76,0x8b, +0x88,0x28,0x3e,0x77,0x64,0x16,0x18,0x9e,0x87,0x78,0xc7,0x46,0x5a,0xb6,0x68,0x77, +0x0b,0xb9,0x96,0x29,0x08,0x2b,0x3f,0x57,0x33,0x2a,0x4b,0x24,0x84,0x31,0x45,0x4a, +0x9c,0x71,0x14,0x4f,0xb7,0x66,0x00,0x00,0x72,0x92,0x2d,0x77,0x1d,0xc5,0x92,0x35, +0x89,0x5c,0x40,0x73,0x18,0xd8,0x5c,0x95,0x70,0x36,0xcb,0x8c,0x80,0x90,0x2a,0x8a, +0x9a,0x99,0x81,0x55,0xc9,0xa8,0x44,0xa6,0x73,0xaa,0xa6,0x31,0x77,0x85,0xab,0x86, +0x9c,0x71,0x14,0xe4,0xb5,0x65,0x00,0x00,0xa8,0xc2,0xdc,0x56,0xc0,0x89,0xbb,0x55, +0x3c,0xc1,0x6a,0xcc,0x58,0x44,0xc1,0x7a,0xf3,0xd8,0x09,0xf1,0x8f,0x3c,0x58,0xd0, +0xf2,0x79,0x2b,0x36,0xe3,0xd2,0x62,0x94,0x35,0x09,0xc3,0x57,0x8b,0xb7,0x99,0xb3, +0x9c,0x71,0x14,0x06,0x94,0x43,0x00,0x00,0xde,0x91,0xde,0x93,0x1c,0x9d,0x4e,0x06, +0xb4,0x25,0x72,0xd4,0x28,0xb3,0x86,0xa7,0x61,0xbb,0xb3,0xbb,0x9b,0xdc,0x27,0xf4, +0xcb,0x7d,0xd3,0xb7,0x5b,0x4b,0x56,0x55,0x35,0x1b,0xcc,0x87,0x1d,0xac,0xfc,0x14, +0x9c,0x71,0x14,0x06,0x94,0x43,0x00,0x00,0xe8,0x14,0x4c,0xc9,0x32,0xb2,0xbb,0x6a, +0x89,0xd9,0xb0,0xb3,0xcc,0x9b,0x31,0xd2,0xb5,0x5c,0x73,0xab,0xb5,0x4c,0x3a,0x25, +0x43,0x90,0xca,0x39,0x33,0xcc,0xa2,0xb2,0xbb,0x8a,0xba,0xce,0xb2,0x4d,0x5b,0xc9, +0x9c,0x71,0x14,0xf2,0x93,0x43,0x00,0x00,0xc7,0x52,0xbb,0x13,0xc4,0xa1,0xc4,0x2a, +0x2c,0xb3,0xa5,0x3d,0x9a,0x84,0x3e,0xab,0x5c,0xba,0x3a,0x33,0x96,0xbb,0xa9,0x1b, +0xb2,0x92,0x1c,0xb9,0x4b,0xb4,0x9b,0xb4,0x69,0xdb,0x32,0x9b,0xc4,0x09,0x53,0xbb, +0x9c,0x71,0x14,0xcf,0x62,0x24,0x10,0x00,0xc4,0xf6,0x19,0x4c,0xa1,0x7e,0xed,0xd6, +0xea,0xa1,0x7a,0xcd,0x59,0x28,0xdd,0x9c,0xce,0xab,0x6c,0xee,0xb8,0x90,0xda,0x0f, +0x1d,0x7a,0xa9,0x45,0xe9,0x1c,0x58,0x49,0x56,0x13,0x2d,0x49,0x01,0x92,0x71,0x59, +0x9c,0x71,0x14,0x6f,0x73,0x34,0x10,0x00,0x4b,0x69,0xd3,0x6b,0x1c,0x2d,0xb0,0xc3, +0x19,0x19,0x2f,0x6e,0xd3,0xb9,0x66,0x37,0x95,0x63,0x58,0xe6,0x30,0x49,0x92,0x89, +0x19,0x23,0x8d,0x13,0x1a,0xe1,0x31,0x71,0x93,0x48,0xa1,0x39,0x53,0x13,0x8a,0xd9, +0x9c,0x71,0x14,0x9d,0x74,0x45,0x20,0x00,0x31,0x18,0x93,0xf4,0x69,0x4e,0xf3,0x65, +0x16,0xae,0x61,0x99,0x65,0xf6,0x41,0x67,0x19,0x07,0xae,0x40,0x7c,0xfd,0x97,0x8e, +0x49,0x70,0x5c,0xd9,0x08,0x0d,0x90,0x70,0x97,0xd0,0x95,0x6a,0x6a,0x17,0x6c,0x19, +0x9c,0x71,0x14,0xf0,0x74,0x55,0x00,0x00,0x82,0x32,0x15,0xe5,0x6d,0x4e,0x21,0x24, +0x93,0x5a,0x5b,0x32,0x35,0x02,0x5a,0x36,0x14,0x63,0xf6,0x9a,0x48,0x66,0x53,0x35, +0x98,0x2a,0x17,0x73,0x17,0xc6,0x30,0x78,0x92,0xf5,0xa5,0x29,0x08,0xa1,0x85,0x95, +0x9c,0x71,0x14,0xd3,0x74,0x44,0x10,0x00,0x28,0x97,0xb3,0xeb,0xb5,0x2f,0x46,0x82, +0x29,0x98,0x3b,0xa7,0x54,0xcc,0xc7,0x4b,0x66,0x62,0x98,0x7a,0x3d,0x95,0x95,0xeb, +0x87,0x57,0x63,0x84,0x4a,0x55,0x48,0x82,0x76,0x9b,0x37,0x62,0x63,0x96,0x08,0x54, +0x9c,0x71,0x14,0xdc,0x53,0x42,0x00,0x00,0x34,0x68,0x86,0x92,0x35,0x46,0x2c,0xa3, +0x6e,0x9c,0x94,0xc7,0x57,0xb2,0x67,0x50,0xcb,0x07,0x28,0xa8,0x9b,0x0f,0x88,0x70, +0xd8,0x6c,0xea,0x48,0x90,0xd2,0x82,0xcc,0x47,0xec,0xfd,0x82,0xac,0x79,0x0c,0xd6, +0x9c,0x71,0x14,0x17,0x11,0x12,0x00,0x00,0x86,0x8c,0xf3,0x2e,0x65,0x7c,0xc8,0xae, +0x24,0x74,0xa6,0xa6,0xb8,0x4e,0xef,0x2c,0xee,0xe2,0x06,0xd7,0x4a,0xa8,0x9b,0xf7, +0xa4,0x32,0xe8,0x73,0x55,0x7d,0x70,0xaf,0x09,0x30,0xe6,0x11,0x0c,0xf7,0x77,0x70, diff --git a/config/_default_cfg_src_/res/en/SOUND_HUNG_UP.txt b/config/_default_cfg_src_/res/en/SOUND_HUNG_UP.txt new file mode 100644 index 0000000..0164f01 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_HUNG_UP.txt @@ -0,0 +1,155 @@ +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x76,0x43,0x20,0x21,0x00,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0xd6,0xa4,0x9c,0x31,0x10,0xea,0xcb,0x79,0x87,0x67, +0x7d,0xd5,0x85,0xd5,0x7d,0xa5,0xbe,0xa4,0x84,0x88,0x3a,0xe5,0xdd,0x15,0x0e,0x15, +0xee,0x55,0x20,0xd5,0xbf,0x15,0x68,0x55,0x6b,0x55,0xb4,0x95,0x26,0xd5,0xe5,0x55, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb, +0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2,0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24, +0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2,0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3, +0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c,0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44, +0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00,0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60, +0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71,0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa, +0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75,0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00, +0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30,0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75, +0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca,0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75, +0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00,0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30, +0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5,0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea, +0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15,0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00, +0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb,0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b, +0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35,0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb, +0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00,0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04, +0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52,0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e, +0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90,0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55, +0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21,0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9, +0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5,0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70, +0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65,0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00, +0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41,0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55, +0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba,0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50, +0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69,0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21, +0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65,0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00, +0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba,0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85, +0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50,0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75, +0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00,0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6, +0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb,0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb, +0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10,0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71, +0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51,0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95, +0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00,0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01, +0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78,0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d, +0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76,0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55, +0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a,0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba, +0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75,0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda, +0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85,0x9c,0x31,0x10,0x9c,0xc5,0x54,0x30,0x00, +0xcb,0x6d,0x92,0x2e,0x30,0x89,0x77,0xd6,0xcb,0x69,0x7b,0x28,0x34,0x51,0x8e,0x92, +0xc8,0x89,0x65,0x09,0x3a,0x72,0xa1,0x84,0xba,0xa6,0x56,0x6e,0x4a,0x4e,0xb0,0x89, +0x9c,0x31,0x10,0xd0,0xcb,0x78,0x77,0x56,0xac,0xeb,0x48,0xeb,0x56,0xcb,0xd5,0x03, +0x86,0x65,0x3b,0x6c,0xe0,0x8b,0x0d,0x0b,0xef,0x2b,0x20,0x6b,0xbf,0x8b,0x68,0x2b, +0x6b,0xab,0xb8,0x4b,0x27,0x6b,0xe8,0xab,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb,0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2, +0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24,0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2, +0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3,0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c, +0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44,0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00, +0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60,0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71, +0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa,0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75, +0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00,0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30, +0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75,0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca, +0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75,0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00, +0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30,0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5, +0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea,0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15, +0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00,0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb, +0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b,0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35, +0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb,0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00, +0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04,0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52, +0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e,0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90, +0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55,0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21, +0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9,0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5, +0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70,0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65, +0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00,0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41, +0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55,0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba, +0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50,0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69, +0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21,0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65, +0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00,0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba, +0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85,0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50, +0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75,0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00, +0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6,0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb, +0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb,0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10, +0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71,0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51, +0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95,0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00, +0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01,0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78, +0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d,0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76, +0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55,0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a, +0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba,0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75, +0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda,0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_INCOMING_CALL.txt b/config/_default_cfg_src_/res/en/SOUND_INCOMING_CALL.txt new file mode 100644 index 0000000..9d13bcd --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_INCOMING_CALL.txt @@ -0,0 +1,445 @@ +0x9c,0x31,0x10,0x29,0x32,0x20,0x00,0x00,0x7d,0xef,0x7d,0xef,0x81,0xef,0x8d,0xd0, +0xba,0x0c,0xe2,0xef,0xe6,0x31,0xdd,0x35,0xc3,0x73,0xa6,0x6f,0x31,0x12,0x0f,0x33, +0x15,0x47,0x5d,0x74,0x67,0x29,0x81,0x33,0x9c,0x31,0x10,0x9b,0x62,0x22,0x00,0x00, +0x76,0x9b,0x6d,0x5b,0x6c,0x9c,0x74,0xb0,0x81,0x23,0x7c,0x5b,0x6e,0xd3,0x55,0x5c, +0x48,0x8c,0x5c,0xd3,0x81,0x12,0x96,0x94,0x7b,0x5a,0x38,0xdb,0x0a,0x5a,0x3b,0xac, +0x9c,0x31,0x10,0xb5,0xa2,0x23,0x00,0x00,0x84,0x6d,0x8a,0x6d,0x84,0x86,0x73,0x6d, +0x64,0x0d,0x6b,0xc5,0x87,0x49,0xa4,0x49,0xa2,0x91,0x7c,0x4d,0x4f,0xb5,0x44,0xb0, +0x6f,0x36,0xb0,0x64,0xcc,0x56,0xa5,0x40,0x9c,0x31,0x10,0xf4,0xb3,0x55,0x10,0x00, +0x6c,0x5b,0x53,0x5c,0x5b,0x5b,0x7e,0x5b,0xa4,0x53,0xb2,0x1b,0x9b,0x9b,0x6a,0x13, +0x47,0x5c,0x4a,0x5a,0x6c,0x5c,0x97,0x5a,0xb9,0x5c,0xc1,0x11,0xa1,0x64,0x61,0x48, +0x9c,0x31,0x10,0x4d,0xb4,0x56,0x20,0x00,0x32,0xb4,0x34,0x8a,0x61,0x2c,0x96,0xca, +0xc2,0xac,0xd2,0x8a,0xb3,0x63,0x66,0x42,0x24,0xee,0x20,0x89,0x55,0x25,0x98,0x91, +0xce,0xe4,0xe2,0xd1,0xbb,0xa4,0x60,0x03,0x9c,0x31,0x10,0x09,0xc4,0x77,0x20,0x00, +0x4a,0xa5,0x49,0x51,0x69,0x9c,0x92,0x12,0xb2,0x24,0xbb,0x52,0x9d,0xa4,0x64,0x11, +0x3d,0x6e,0x45,0x4a,0x70,0x6b,0xa0,0x8a,0xc0,0x24,0xbd,0x53,0x90,0xa3,0x4f,0x9b, +0x9c,0x31,0x10,0xa6,0xc5,0x78,0x30,0x00,0x30,0xb4,0x46,0xa9,0x80,0x46,0xb6,0xb9, +0xce,0xb6,0xb6,0xc7,0x72,0x36,0x33,0x14,0x2c,0xec,0x5e,0x95,0xa0,0x58,0xd0,0x27, +0xcc,0xd7,0x95,0x17,0x42,0x56,0x1c,0x35,0x9c,0x31,0x10,0x38,0xc6,0x98,0x20,0x00, +0x3e,0x9e,0x8a,0xa0,0xcd,0x16,0xdc,0xa1,0xad,0x13,0x54,0x64,0x17,0x12,0x2a,0xea, +0x7c,0xce,0xcb,0x28,0xe4,0x95,0xb9,0x22,0x5e,0xdb,0x13,0x92,0x20,0xde,0x77,0x20, +0x9c,0x31,0x10,0x38,0xc6,0x98,0x20,0x00,0xcc,0xd6,0xea,0xa1,0xba,0xd4,0x5e,0xe2, +0x0f,0xa4,0x1c,0xc3,0x79,0x32,0xd5,0x15,0xee,0x99,0xb6,0xdd,0x54,0xd8,0x09,0xa6, +0x23,0x02,0x87,0x2a,0xe1,0x1d,0xec,0xd8,0x9c,0x31,0x10,0x67,0xd8,0x99,0x20,0x00, +0x92,0xd5,0x5e,0xe1,0x3f,0x1c,0x58,0xcc,0x90,0xea,0xb8,0xe5,0xb0,0xd1,0x84,0xd4, +0x50,0xa3,0x3e,0xd2,0x66,0xdc,0xa0,0xe2,0xbe,0xdb,0xa6,0xd4,0x73,0x1a,0x42,0x5b, +0x9c,0x31,0x10,0x76,0xd8,0x87,0x20,0x00,0x44,0xd2,0x7c,0xf4,0xb2,0xee,0xba,0xcd, +0x92,0xcd,0x5f,0x4e,0x3f,0x15,0x56,0xf8,0x92,0xee,0xbd,0x31,0xb1,0x0d,0x7f,0x09, +0x4c,0xcd,0x3d,0x68,0x6d,0x22,0xa6,0xe4,0x9c,0x31,0x10,0xb7,0xd8,0x87,0x10,0x00, +0xc0,0xe6,0xa0,0xc9,0x69,0x29,0x3e,0x05,0x4a,0x6a,0x86,0x8c,0xb8,0xd1,0xb8,0x6d, +0x88,0x91,0x52,0xf1,0x3d,0x39,0x64,0xd5,0xa0,0x95,0xbe,0xf1,0xa4,0xd0,0x6f,0x12, +0x9c,0x31,0x10,0x95,0xc8,0x76,0x10,0x00,0x08,0x2d,0x15,0x25,0x83,0x48,0xe9,0x6a, +0xf3,0x0c,0x96,0xed,0x31,0x69,0x00,0xf5,0x46,0x70,0xbc,0x31,0xfa,0xc9,0xca,0xec, +0x5f,0x4e,0x0c,0xad,0x1b,0xc9,0x89,0xb0,0x9c,0x31,0x10,0x39,0xc8,0x66,0x00,0x00, +0xe9,0x72,0xec,0x94,0x8e,0x55,0x2c,0xc9,0x04,0xb5,0x54,0x49,0xc2,0x69,0xf7,0x06, +0xbd,0x44,0x55,0x4d,0x0c,0x49,0x29,0x89,0x97,0x70,0xe9,0x31,0xde,0x72,0x80,0xb0, +0x9c,0x31,0x10,0x84,0xc9,0x75,0x10,0x00,0x29,0x0d,0x12,0xf2,0x66,0x8e,0xc8,0xcc, +0xeb,0x2e,0xa9,0x0e,0x4c,0xec,0x16,0x89,0x3f,0x4e,0xa3,0x2d,0xe0,0xec,0xc4,0xb2, +0x6d,0x0d,0x2d,0x54,0x26,0xf1,0x76,0x4e,0x9c,0x31,0x10,0x9d,0xc8,0x55,0x00,0x00, +0xc7,0x84,0xd9,0xc5,0x96,0x79,0x47,0x65,0x24,0x34,0x58,0xa5,0xaf,0x71,0xdb,0x79, +0xb4,0x46,0x61,0x85,0x2c,0xa5,0x3c,0x94,0x8e,0x25,0xcc,0xaa,0xc7,0xa8,0x80,0x45, +0x9c,0x31,0x10,0xb5,0xc8,0x65,0x00,0x00,0x40,0xd2,0x30,0xf1,0x6b,0x0c,0xb2,0xed, +0xcd,0x0e,0x9b,0x08,0x54,0x89,0x38,0x46,0x57,0xc9,0x9c,0x88,0xc4,0x6a,0xaf,0x41, +0x6b,0x48,0x40,0x8d,0x49,0x06,0x83,0x6c,0x9c,0x31,0x10,0x9c,0xc9,0x65,0x10,0x00, +0xb4,0xcd,0xb8,0x92,0x83,0x0d,0x4d,0x49,0x3e,0x6d,0x69,0x09,0xa7,0x31,0xba,0xad, +0x97,0x11,0x5e,0xed,0x4a,0xcd,0x5f,0x09,0x92,0xc9,0xb4,0xd5,0xa7,0x15,0x74,0xcd, +0x9c,0x31,0x10,0xd3,0xb9,0x65,0x00,0x00,0x25,0x11,0x27,0x19,0x74,0x6d,0xc7,0x0d, +0xcd,0x40,0x86,0xa2,0x45,0x31,0x37,0x04,0x64,0xb1,0xa7,0x31,0xc4,0xd9,0xa4,0xad, +0x61,0x95,0x44,0xf0,0x54,0x95,0x87,0x15,0x9c,0x31,0x10,0x17,0xa9,0x76,0x20,0x00, +0xde,0x1a,0xe4,0x5b,0x89,0x94,0x3e,0xe2,0x31,0x5a,0x69,0x24,0xba,0x1c,0xe2,0x0a, +0xa6,0x13,0x49,0xc9,0x21,0x94,0x46,0x13,0x92,0x1c,0xc9,0xa1,0xa5,0x5d,0x62,0x1b, +0x9c,0x31,0x10,0x5a,0xa9,0x75,0x10,0x00,0x33,0x4d,0x40,0xd4,0x8a,0xb6,0xb7,0x0c, +0xc0,0xf1,0x96,0xd5,0x6e,0xb1,0x5f,0x0d,0x81,0x71,0xa4,0xb4,0xa8,0xb2,0x89,0x51, +0x60,0xf1,0x6a,0x71,0x7b,0x06,0x8b,0x51,0x9c,0x31,0x10,0x2d,0x99,0x65,0x10,0x00, +0xb1,0xda,0xad,0x54,0x61,0xc5,0x36,0x26,0x4a,0x49,0x99,0xe0,0xbd,0xd2,0xa9,0xb1, +0x71,0x8d,0x3a,0x14,0x3a,0x52,0x79,0xd8,0x7c,0xf2,0x71,0x69,0x82,0x45,0x86,0x4c, +0x9c,0x31,0x10,0x39,0x88,0x75,0x00,0x00,0x45,0x91,0x7d,0xf1,0xb9,0xb1,0x88,0xec, +0x50,0xed,0x3e,0x2d,0x46,0xaa,0x6a,0x6c,0xce,0xb5,0xe7,0x55,0xb2,0x35,0x54,0x90, +0x40,0x4e,0x71,0x0a,0x9d,0xe4,0x86,0x8c,0x9c,0x31,0x10,0xb5,0x88,0x76,0x00,0x00, +0x6b,0x54,0x47,0x9a,0x8a,0x64,0x99,0x1c,0x70,0x9a,0x5c,0xd3,0x6a,0x4b,0x52,0x4d, +0x1a,0x11,0x2a,0xd3,0x67,0x54,0x93,0x13,0x8a,0x24,0xa5,0xe2,0xb1,0xac,0xad,0x9c, +0x9c,0x31,0x10,0x8e,0x88,0x77,0x10,0x00,0x98,0xe2,0xa8,0xd4,0x99,0x53,0x8d,0x93, +0x85,0x9b,0x6d,0xdb,0x89,0xdb,0x85,0x5b,0x59,0x62,0x3d,0x9b,0x75,0x9b,0x92,0x24, +0x89,0xaa,0xa9,0xea,0xed,0xad,0x91,0x73,0x9c,0x31,0x10,0x69,0x87,0x76,0x10,0x00, +0xac,0xe2,0x96,0x0c,0x85,0x51,0x92,0x1a,0xbc,0x1d,0x7e,0x12,0x65,0x63,0x4e,0xac, +0x29,0xb3,0x11,0x51,0x81,0x04,0x77,0x0e,0x85,0x21,0x52,0x69,0xc2,0xdd,0x7c,0xdb, +0x9c,0x31,0x10,0xe1,0x87,0x86,0x10,0x00,0x6b,0x34,0x69,0x29,0x82,0xba,0x6a,0x3e, +0x89,0x24,0xa6,0xb0,0xad,0x4c,0x6f,0x4a,0xba,0x5b,0x54,0x45,0x39,0x22,0x45,0xa1, +0x71,0xb5,0x65,0x4b,0x8c,0xca,0xa6,0xf5,0x9c,0x31,0x10,0xe6,0x87,0x77,0x10,0x00, +0x91,0x8a,0x7a,0xdb,0xc6,0x9b,0x99,0x5b,0xa5,0xea,0xa4,0xdc,0x6f,0x4a,0x80,0xe3, +0x62,0xcc,0x54,0xe3,0xb5,0x32,0x1a,0x95,0x49,0x9a,0x92,0x6b,0x5d,0xeb,0x49,0xcb, +0x9c,0x31,0x10,0x74,0x76,0x77,0x20,0x00,0xe7,0x63,0x5c,0x33,0x1e,0x1c,0xab,0x6a, +0x19,0x4b,0x9a,0x34,0xc4,0xc1,0x63,0x3b,0x3e,0xf4,0x9a,0x4c,0x62,0x90,0x8d,0xa6, +0xe5,0x13,0xbc,0xdb,0xea,0x62,0x83,0x5c,0x9c,0x31,0x10,0xc7,0x88,0x87,0x20,0x00, +0x7c,0x2b,0x8a,0xbc,0x9c,0x61,0x8b,0x3a,0xb3,0xa4,0x8b,0xc4,0x6c,0x2b,0x7c,0x49, +0x6b,0x4e,0x9b,0x49,0x82,0xa4,0xcd,0xb1,0x4b,0xc4,0x32,0xb5,0x83,0x31,0x62,0x41, +0x9c,0x31,0x10,0x7a,0xa7,0x87,0x40,0x00,0x99,0xe4,0x87,0x32,0x88,0xa5,0x5e,0x49, +0x64,0x2d,0x5d,0xc4,0x89,0xcb,0x99,0xb2,0xad,0x09,0x95,0x42,0x62,0xde,0x3e,0xaa, +0x4a,0x4b,0x7c,0x54,0xba,0x14,0xdd,0x31,0x9c,0x31,0x10,0x2c,0xb9,0x88,0x40,0x00, +0x9d,0xe3,0x69,0xdb,0x4a,0x12,0x4e,0x2c,0x71,0xca,0xa9,0xcc,0xbd,0x99,0xb2,0x14, +0x71,0x63,0x3a,0x5c,0x25,0x94,0x65,0x60,0xa9,0xd2,0xc9,0x9d,0xce,0xdc,0x7c,0xd3, +0x9c,0x31,0x10,0xfc,0xc9,0x88,0x30,0x00,0x5d,0x52,0x48,0x53,0x6b,0x53,0x94,0x9b, +0xa7,0x23,0xa6,0xea,0x86,0x8b,0x5b,0x53,0x42,0x5a,0x6b,0x55,0x8e,0x5b,0xa9,0x59, +0xac,0x63,0x93,0x6d,0x60,0x93,0x3c,0xa3,0x9c,0x31,0x10,0xf3,0xca,0x97,0x40,0x00, +0x59,0x11,0x8e,0xb2,0x9f,0x09,0xb6,0xac,0x9d,0x2e,0x70,0x8d,0x43,0x6d,0x3a,0xe9, +0x8c,0xf6,0x82,0xce,0xc4,0xec,0xa0,0xf0,0x9c,0xf1,0x54,0xe9,0x34,0x92,0x5f,0xd0, +0x9c,0x31,0x10,0x46,0xca,0x88,0x30,0x00,0x88,0x83,0x9a,0xe3,0xbd,0x23,0x9a,0xb3, +0x89,0x5b,0x4e,0x5c,0x28,0x8b,0x7a,0x5a,0x79,0x2a,0xae,0x64,0xad,0x5a,0xa1,0xeb, +0x81,0xe3,0x41,0xcc,0x2d,0x13,0x85,0xd9,0x9c,0x31,0x10,0xfc,0xc9,0x88,0x30,0x00, +0x78,0x55,0xbd,0x2c,0xa4,0xe9,0xa4,0x63,0x7d,0x5c,0x40,0x5a,0x26,0xd4,0x94,0x92, +0x71,0x1b,0xc4,0xda,0x9c,0xe4,0xac,0x94,0x7d,0x43,0x4c,0x5b,0x1c,0xdb,0x96,0xda, +0x9c,0x31,0x10,0x5e,0xca,0x98,0x30,0x00,0x69,0xdc,0xc2,0x5c,0x99,0x99,0xaa,0x1b, +0x81,0xd4,0x5d,0xda,0x11,0x5a,0x87,0x1e,0x71,0x22,0xae,0xdb,0xa9,0x13,0x9e,0x93, +0x99,0x61,0x6e,0x64,0x29,0xda,0x4a,0xec,0x9c,0x31,0x10,0xc0,0xca,0x87,0x30,0x00, +0x92,0x3a,0x7d,0x75,0xc2,0x94,0x93,0x4d,0xa6,0xac,0x85,0x05,0x50,0xc1,0x1e,0xa2, +0x87,0x82,0x72,0xa4,0xad,0x61,0xa8,0x69,0x9b,0x28,0xa0,0xad,0x75,0x0a,0x38,0xcd, +0x9c,0x31,0x10,0x76,0xca,0xa8,0x30,0x00,0x35,0x1d,0x90,0xe0,0x71,0xdd,0xbd,0xa1, +0x91,0xa1,0xa1,0xa1,0x95,0xa1,0x6a,0x25,0x2e,0x64,0x4a,0x6e,0x8c,0x2a,0x79,0xe8, +0xb9,0x25,0x92,0x25,0xa9,0xa5,0x8d,0xa5,0x9c,0x31,0x10,0x6c,0xca,0x97,0x20,0x00, +0x64,0xf1,0x29,0x30,0x57,0x75,0x86,0x52,0x83,0x31,0xba,0x91,0x91,0x2d,0xac,0xd1, +0x90,0xf1,0x62,0xf1,0x29,0x31,0x55,0x9a,0x86,0x35,0x83,0x34,0xba,0x76,0x91,0x31, +0x9c,0x31,0x10,0xdb,0xcb,0x88,0x30,0x00,0xad,0xb3,0x8d,0xb3,0x65,0xf3,0x32,0x2b, +0x41,0xb5,0x91,0x31,0x71,0xeb,0xbd,0x5c,0x8d,0xe3,0xa9,0x92,0x99,0x9b,0x6d,0x9c, +0x3d,0xd3,0x28,0xc3,0x8d,0x89,0x71,0x83,0x9c,0x31,0x10,0xdb,0xcb,0x88,0x30,0x00, +0xb6,0x05,0x9d,0x83,0x9d,0xc2,0xa9,0x83,0x7a,0x0b,0x49,0xcb,0x21,0x93,0x6f,0x0b, +0x81,0xcb,0x92,0xd2,0xb9,0x9b,0x8e,0x24,0xb1,0xeb,0x8a,0x23,0x5d,0xe3,0x2e,0x63, +0x9c,0x31,0x10,0xc0,0xca,0x87,0x30,0x00,0x38,0xfa,0x98,0x76,0x72,0xb0,0xc4,0xcc, +0x96,0xce,0xa6,0xe5,0xa0,0x89,0x77,0x09,0x46,0xe9,0x20,0x69,0x6d,0xc5,0x8a,0xac, +0x93,0xad,0xbe,0x91,0x93,0x32,0xb2,0xf5,0x9c,0x31,0x10,0xc0,0xca,0x87,0x30,0x00, +0x90,0xf1,0x60,0xd1,0x31,0x2d,0x28,0x4d,0x94,0x8c,0x76,0xa9,0xb5,0x29,0xaa,0xca, +0x9f,0x29,0xb0,0xe8,0x7f,0x48,0x4e,0xee,0x21,0x11,0x45,0x94,0x9e,0x92,0x78,0xd2, +0x9c,0x31,0x10,0x48,0xca,0x77,0x30,0x00,0xc2,0xb9,0x9c,0xc4,0xa5,0x10,0xaa,0xa1, +0x6f,0x01,0x45,0x11,0x1c,0xc5,0x61,0xd4,0x9a,0xd4,0x83,0x39,0xc2,0xaa,0x98,0xc5, +0xa6,0xe4,0xa4,0xb4,0x66,0xe5,0x3f,0x06,0x9c,0x31,0x10,0x48,0xca,0x77,0x30,0x00, +0x1e,0xa6,0x6b,0x86,0x9c,0xe4,0x87,0x34,0xbe,0xd6,0x9a,0xd6,0xa5,0x15,0xa0,0xb4, +0x64,0xe5,0x3b,0x05,0x20,0x91,0x73,0x62,0x9a,0xf5,0x89,0x54,0xb9,0x05,0x9c,0xd5, +0x9c,0x31,0x10,0xf2,0xc9,0x77,0x30,0x00,0xa2,0xf1,0xa2,0x70,0x66,0xad,0x3d,0x09, +0x1e,0x49,0x6f,0xc6,0x9e,0xe9,0x85,0x6c,0xb2,0xed,0xa4,0x8d,0x9a,0xc9,0xa6,0xa9, +0x6e,0xe9,0x3f,0x49,0x22,0xad,0x61,0xc9,0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00, +0xa0,0xd0,0x87,0x12,0xa8,0xb1,0xa8,0xad,0x96,0xed,0xa1,0x0d,0x83,0x0d,0x49,0x0d, +0x28,0xf0,0x45,0x35,0x9c,0x52,0x90,0x8d,0x96,0xcc,0xab,0x0d,0x9f,0x2e,0x99,0x31, +0x9c,0x31,0x10,0x8d,0xc8,0x66,0x10,0x00,0x90,0xd0,0x60,0x90,0x3e,0xce,0x30,0x44, +0x77,0x28,0x9f,0x4a,0x93,0x6e,0x99,0x0c,0xa2,0xd2,0x98,0x92,0x93,0x0c,0x7f,0x2d, +0x5d,0x52,0x44,0xd0,0x47,0x14,0x80,0x72,0x9c,0x31,0x10,0x1f,0xb6,0x56,0x00,0x00, +0xb2,0x0b,0xaa,0x49,0xa9,0xa4,0xad,0x6c,0xaa,0xc2,0x9a,0xc3,0x73,0x4d,0x51,0xab, +0x2c,0x92,0x35,0xab,0x68,0x2c,0x9a,0xcb,0xac,0xab,0xa9,0x4b,0xa7,0x0b,0xa2,0xcc, +0x9c,0x31,0x10,0x69,0xa6,0x34,0x00,0x00,0xa2,0x23,0x6e,0x82,0x43,0x43,0x17,0x0a, +0x0d,0x53,0x3a,0xad,0x96,0xc9,0xcc,0xeb,0xd9,0x44,0xd2,0x8a,0xc4,0xe3,0xaa,0x84, +0x80,0xe9,0x53,0x4b,0x21,0x04,0x0a,0xcb,0x9c,0x31,0x10,0x41,0xa5,0x23,0x00,0x00, +0x30,0x44,0x76,0x76,0xba,0x62,0xd1,0xc4,0xd3,0xa5,0xc9,0x45,0xad,0x65,0x86,0x65, +0x54,0xa1,0x28,0x99,0x18,0x35,0x2d,0x68,0x6b,0xaa,0xa9,0x49,0xcc,0x99,0xd3,0x56, +0x9c,0x31,0x10,0xc4,0xa4,0x33,0x00,0x00,0xcc,0x74,0xb3,0x86,0x86,0x26,0x55,0x74, +0x29,0xb5,0x16,0x45,0x2b,0x45,0x67,0xd5,0xa9,0x75,0xcf,0xa9,0xda,0x25,0xd1,0x84, +0xb3,0x79,0x84,0x69,0x52,0x99,0x26,0x85,0x9c,0x31,0x10,0xc4,0xa4,0x33,0x00,0x00, +0x13,0x65,0x28,0x3a,0x66,0x79,0xa9,0xb5,0xcf,0x85,0xda,0x65,0xd1,0xaa,0xb4,0x05, +0x87,0x38,0x55,0x46,0x24,0x41,0x0f,0xc1,0x26,0xb1,0x65,0x94,0xa8,0xb9,0xce,0xba, +0x9c,0x31,0x10,0x9b,0xa5,0x44,0x00,0x00,0xda,0x99,0xd5,0x34,0xb6,0x9c,0x88,0xe2, +0x52,0xc4,0x22,0xc4,0x0d,0x1b,0x23,0x0b,0x63,0x1a,0xa6,0xdb,0xcf,0x23,0xdc,0x93, +0xd5,0x64,0xbb,0x1a,0x8a,0x74,0x4e,0x93,0x9c,0x31,0x10,0x31,0xb5,0x45,0x00,0x00, +0x4e,0xda,0x40,0x9c,0x4c,0xd3,0x73,0x23,0x99,0x1b,0xaf,0x1b,0xb2,0xd4,0xab,0x23, +0x9c,0x63,0x80,0x5b,0x64,0xd3,0x48,0xd2,0x38,0xd4,0x4c,0xcb,0x7f,0xa2,0xad,0x25, +0x9c,0x31,0x10,0x40,0xc6,0x65,0x00,0x00,0x9f,0x4d,0xa0,0x69,0x98,0x49,0x93,0x4d, +0x81,0x4d,0x66,0x89,0x4a,0x69,0x3c,0x04,0x65,0x49,0x9b,0x46,0xa5,0x88,0x93,0x8a, +0x94,0xa9,0xa6,0xcd,0x9e,0x72,0x6c,0x4d,0x9c,0x31,0x10,0x54,0xc8,0x76,0x20,0x00, +0x43,0x11,0x2b,0x11,0x3b,0x39,0x8e,0xd6,0xb0,0xd4,0x98,0xd5,0x90,0xf1,0xae,0xf1, +0xb9,0x11,0x8d,0x11,0x58,0xce,0x3b,0x11,0x24,0x8d,0x53,0x82,0xab,0x04,0xb1,0x49, +0x9c,0x31,0x10,0x92,0xc8,0x87,0x10,0x00,0x91,0x09,0x9f,0x28,0xc1,0x09,0xb1,0x0a, +0x7b,0x08,0x4c,0xe9,0x30,0xe9,0x28,0x44,0x70,0xad,0xa8,0x6e,0x9e,0xac,0x9c,0xad, +0xb0,0xb2,0xb2,0xd1,0x9c,0xd1,0x70,0xd2,0x9c,0x31,0x10,0x53,0xc8,0x87,0x20,0x00, +0x47,0x11,0x2b,0x2d,0x33,0x56,0x7d,0x15,0x9c,0xf0,0xa1,0x2e,0xaf,0x0d,0xb7,0x08, +0xb3,0x29,0x94,0xea,0x5e,0xc9,0x3b,0x0d,0x28,0xd1,0x41,0x70,0x88,0xee,0xa1,0x0e, +0x9c,0x31,0x10,0x3b,0xc7,0x87,0x20,0x00,0xa7,0x18,0xae,0xd5,0xb4,0xd6,0xac,0xd5, +0x88,0xdc,0x54,0xa2,0x36,0xe5,0x2a,0x21,0x4f,0x4d,0x8c,0x90,0xa2,0xd9,0xae,0xe5, +0xb2,0xa1,0xb4,0xe1,0xa8,0xe2,0x7a,0xdd,0x9c,0x31,0x10,0xfa,0xc7,0x87,0x10,0x00, +0x4a,0xdc,0x35,0x1d,0x2c,0x0d,0x5b,0x21,0x90,0x69,0xa4,0xe9,0xb2,0xe1,0xb2,0xd5, +0xb2,0xd9,0xa0,0xa1,0x72,0xde,0x4a,0xdd,0x37,0x1d,0x32,0xa5,0x65,0x2c,0x90,0x9e, +0x9c,0x31,0x10,0x2e,0xc6,0x77,0x20,0x00,0xa7,0x0b,0xb3,0x12,0xb0,0xe4,0xae,0xec, +0x98,0x99,0x6d,0x14,0x48,0xdb,0x33,0x22,0x39,0xb5,0x70,0xc4,0x96,0xc9,0xa8,0xe5, +0xb0,0xeb,0xae,0xc9,0xaa,0xde,0x8e,0xa2,0x9c,0x31,0x10,0x3b,0xc7,0x87,0x20,0x00, +0x64,0xdc,0x46,0xde,0x32,0x5d,0x49,0x48,0x7c,0xa1,0x9a,0xea,0xa6,0xd8,0xa8,0xd1, +0xaa,0xe2,0xa4,0xe9,0x86,0xd1,0x60,0xd9,0x47,0x25,0x38,0x9c,0x59,0x29,0x86,0x92, +0x9c,0x31,0x10,0x9c,0xb6,0x87,0x10,0x00,0xb5,0xc0,0xc5,0x4c,0xca,0x34,0xcd,0x30, +0xb2,0x4d,0x7d,0xaa,0x45,0xc2,0x15,0xc4,0x06,0xbb,0x51,0x14,0x96,0x59,0xb1,0xb5, +0xb5,0x2b,0xc2,0x4a,0xbd,0xb4,0x9d,0xc4,0x9c,0x31,0x10,0xdb,0xb6,0x88,0x20,0x00, +0x71,0x2b,0x4e,0x43,0x20,0x3c,0x23,0x22,0x64,0xe2,0x95,0x9d,0xa9,0xc1,0xa9,0xc4, +0xb5,0xb3,0xa9,0xc2,0x8a,0x2b,0x75,0x43,0x6a,0x3a,0x40,0xb4,0x2e,0xaa,0x5d,0x5a, +0x9c,0x31,0x10,0xae,0xb6,0x88,0x00,0x00,0x89,0x9d,0x9d,0x49,0x9d,0xbc,0xa9,0xbb, +0xa1,0xba,0x7d,0xbc,0x65,0xbb,0x79,0xba,0x99,0xbc,0x95,0xba,0x6d,0xbb,0x44,0xb3, +0x3e,0xd4,0x61,0x2a,0x82,0x3c,0x99,0xbb,0x9c,0x31,0x10,0xa2,0xa4,0x77,0x00,0x00, +0xd2,0xda,0xf4,0xdc,0xd6,0x9b,0x8b,0x1a,0x44,0xdc,0x1d,0x1a,0x10,0x24,0x49,0x8a, +0x8c,0xaa,0xb5,0x55,0xb9,0x21,0xb6,0xdc,0xa8,0x5b,0x8b,0x5a,0x6a,0x54,0x65,0x1a, +0x9c,0x31,0x10,0x78,0x95,0x47,0x00,0x00,0x4d,0x98,0x20,0xe7,0x22,0x14,0x5e,0x1c, +0x95,0x53,0xad,0xb9,0xc2,0x28,0xc9,0x35,0xa5,0xd9,0x6d,0x96,0x55,0xc7,0x65,0xa8, +0x81,0xc6,0x91,0x38,0x8a,0x37,0x81,0xb7,0x9c,0x31,0x10,0xca,0x74,0x34,0x00,0x00, +0x71,0x9e,0x62,0x98,0x35,0xed,0x25,0x02,0x66,0xf2,0xc5,0x95,0xd1,0x59,0xa6,0xe5, +0x7d,0x1a,0x5d,0xdb,0x4a,0x1c,0x51,0x5a,0x75,0x5c,0x8e,0x9a,0x9d,0x14,0x99,0xd2, +0x9c,0x31,0x10,0x0a,0x54,0x33,0x00,0x00,0x86,0x9b,0x2c,0xdc,0x3d,0xd9,0x6a,0x5c, +0x81,0x5b,0x96,0x5a,0xbe,0x5d,0xc1,0x29,0x86,0x4b,0x66,0x6b,0x80,0xdd,0x96,0x52, +0x91,0xd9,0xc1,0x16,0xaa,0x59,0x65,0xdb,0x9c,0x31,0x10,0xc1,0x85,0x77,0x10,0x00, +0x75,0x3b,0x7a,0x3b,0x79,0xbb,0x7d,0xbb,0x86,0x3b,0x89,0xbb,0x81,0xb3,0x8a,0xd5, +0x95,0x88,0x5d,0xec,0x3e,0x14,0x55,0x51,0x85,0xad,0x8e,0x42,0x81,0x3b,0x91,0xb3, +0x9c,0x31,0x10,0xdc,0x63,0x45,0x00,0x00,0xe3,0x59,0x6c,0x2d,0x01,0x32,0x35,0xcb, +0x9d,0x2b,0xb5,0xc2,0x82,0x43,0x79,0x3b,0x7e,0x42,0x6d,0xab,0x5c,0x33,0x5a,0x43, +0x7a,0x3b,0xbc,0xb3,0xb6,0x43,0x7d,0xc3,0x9c,0x31,0x10,0x89,0x63,0x23,0x00,0x00, +0x62,0x92,0x4d,0x15,0x44,0xe1,0x5a,0x8d,0x95,0x6a,0xc6,0x9b,0xba,0x8b,0x83,0x23, +0x62,0xdc,0x70,0xea,0x85,0x24,0x8c,0xa9,0x84,0xa4,0x6d,0x63,0x5c,0x53,0x80,0xda, +0x9c,0x31,0x10,0x0a,0x93,0x55,0x00,0x00,0x85,0x1b,0x86,0x5c,0x82,0xdb,0x7d,0x62, +0x78,0x93,0x7d,0x1a,0x89,0x1c,0x8e,0x5a,0x85,0x5c,0x6c,0xdb,0x5a,0x9b,0x71,0x5c, +0x92,0x8c,0xac,0x69,0xc3,0x13,0xab,0x9b,0x9c,0x31,0x10,0x34,0xa5,0x56,0x10,0x00, +0x62,0x53,0x47,0x5b,0x68,0xa3,0x82,0xd3,0x89,0x1a,0x8e,0x9c,0xa0,0xdb,0xa5,0x1a, +0x86,0xdc,0x6c,0xa3,0x87,0x23,0xa4,0x84,0x8a,0xf1,0x55,0x4c,0x2e,0x62,0x4d,0x2b, +0x9c,0x31,0x10,0x53,0xb6,0x78,0x20,0x00,0x79,0xa8,0x81,0xc5,0x85,0xa9,0x95,0xc6, +0x9d,0x27,0x9e,0x48,0x8d,0xa7,0x71,0x46,0x5a,0xa8,0x3c,0x26,0x61,0xe9,0x8d,0x16, +0x96,0x47,0x95,0x37,0xaa,0x83,0xc1,0x6d,0x9c,0x31,0x10,0x86,0xc7,0x89,0x30,0x00, +0x84,0xd3,0x59,0x23,0x44,0xdb,0x6e,0xdb,0x8e,0xdb,0x8d,0x24,0x8e,0xca,0x9f,0x2b, +0xb2,0x9c,0x8e,0xdb,0x4b,0x5a,0x28,0x9c,0x5f,0x2a,0x8e,0x85,0x8c,0xf1,0x8f,0x0c, +0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00,0xa2,0xab,0xbb,0x13,0x9e,0xdc,0x57,0x21, +0x2a,0x14,0x49,0x5b,0x86,0xa0,0x90,0xce,0x91,0x22,0xa2,0x4a,0xbd,0x2d,0xaa,0xca, +0x60,0xe2,0x26,0xa4,0x35,0x49,0x7c,0xa6,0x9c,0x31,0x10,0x20,0xc6,0x88,0x20,0x00, +0x93,0x12,0x97,0x1b,0xa4,0x5a,0xc1,0x6d,0xb2,0x8b,0x6a,0xe2,0x23,0x1c,0x21,0x99, +0x6e,0xde,0x96,0xe0,0x9d,0x1c,0xa8,0x9a,0xc5,0x6c,0xba,0x93,0x72,0xe2,0x23,0x9b, +0x9c,0x31,0x10,0x94,0xc6,0x88,0x30,0x00,0x14,0xe4,0x60,0xc9,0x96,0xa3,0xa0,0xdc, +0xaa,0x9a,0xc3,0x25,0xbe,0x53,0x7e,0xda,0x2d,0x9b,0x0e,0x6c,0x4e,0xd1,0x8e,0x65, +0xa0,0xda,0xaa,0x9b,0xc0,0xdc,0xc2,0x9a,0x9c,0x31,0x10,0x72,0xc7,0x77,0x10,0x00, +0x8c,0xdb,0x3d,0x14,0x10,0x62,0x3d,0x2b,0x82,0x8d,0xa0,0xe1,0xaa,0xdc,0xba,0xc9, +0xc4,0xed,0x9f,0x14,0x50,0xe2,0x16,0x4c,0x2b,0x24,0x6e,0xa0,0x9a,0xd5,0xa8,0xda, +0x9c,0x31,0x10,0x55,0xc5,0x77,0x10,0x00,0xb6,0x5b,0xc6,0x56,0xaf,0xa0,0x69,0x14, +0x26,0x5c,0x1e,0x89,0x58,0x6c,0x8f,0x54,0xa8,0x59,0xb4,0x64,0xc4,0x92,0xbb,0x63, +0x81,0x1c,0x3a,0x9a,0x1c,0x5b,0x41,0x53,0x9c,0x31,0x10,0x5e,0xc5,0x56,0x00,0x00, +0x7b,0x71,0xa0,0x6c,0xb0,0x2a,0xc2,0xb2,0xc3,0x45,0x96,0x31,0x4f,0xab,0x22,0x2c, +0x30,0xaa,0x66,0x4b,0x94,0x6b,0xae,0x4a,0xc2,0xcc,0xca,0x4b,0xa6,0x4a,0x62,0xab, +0x9c,0x31,0x10,0xcf,0xc5,0x43,0x00,0x00,0x29,0x2d,0x24,0xb4,0x52,0x45,0x87,0x4e, +0xa9,0x71,0xc0,0xa9,0xce,0x59,0xb5,0x69,0x76,0x89,0x33,0x71,0x1c,0x8d,0x42,0x6d, +0x7b,0x49,0xa4,0xad,0xbe,0x6d,0xd1,0x31,0x9c,0x31,0x10,0x87,0xc5,0x33,0x00,0x00, +0xc0,0xb9,0x83,0xb1,0x3a,0xc5,0x18,0x44,0x36,0xa5,0x72,0xa5,0xa2,0x55,0xbe,0x25, +0xd2,0xa4,0xc6,0xca,0x8b,0xb9,0x40,0xd6,0x19,0x34,0x32,0xaa,0x6c,0xa5,0x9d,0xd5, +0x9c,0x31,0x10,0x87,0xc5,0x33,0x00,0x00,0xbc,0x10,0xd3,0xb5,0xca,0x3a,0x90,0x38, +0x43,0xd4,0x19,0xb5,0x31,0x26,0x6a,0x35,0x9b,0xd4,0xba,0x01,0xd2,0x36,0xca,0x36, +0x92,0x38,0x47,0x54,0x1b,0xb5,0x31,0x26,0x9c,0x31,0x10,0x08,0xc5,0x32,0x00,0x00, +0x69,0x36,0x9a,0xc4,0xba,0x25,0xd0,0xb8,0xc8,0x29,0x91,0x36,0x47,0x56,0x1d,0xa4, +0x33,0x28,0x6a,0x36,0x9b,0x36,0xbb,0x39,0xd0,0xc8,0xc5,0x25,0x8b,0xb5,0x44,0x46, +0x9c,0x31,0x10,0x1a,0xc4,0x33,0x00,0x00,0x1f,0x24,0x37,0xb5,0x6e,0x36,0x9e,0x35, +0xbd,0xc8,0xcf,0xc6,0xbf,0x26,0x83,0xa9,0x40,0x54,0x22,0x25,0x3e,0x45,0x73,0xa5, +0xa1,0x25,0xbe,0xc5,0xcd,0x34,0xb7,0xb5,0x9c,0x31,0x10,0x9f,0xc5,0x23,0x00,0x00, +0x7a,0xb9,0x3c,0xb2,0x26,0xc1,0x46,0xb1,0x79,0xa9,0xa5,0x31,0xc0,0x41,0xc9,0x25, +0xad,0x35,0x6f,0xd1,0x39,0x01,0x2d,0x45,0x50,0x36,0x81,0xa1,0xa9,0xb5,0xc0,0xb5, +0x9c,0x31,0x10,0x9f,0xc5,0x23,0x00,0x00,0xc2,0xb9,0xa0,0x21,0x66,0x51,0x39,0x04, +0x37,0x59,0x5b,0x26,0x88,0x35,0xab,0xb4,0xbd,0xc5,0xb8,0xa5,0x92,0xb1,0x5f,0x48, +0x3d,0xa1,0x43,0x49,0x65,0x31,0x8d,0xb9,0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00, +0xd9,0x61,0xf0,0x86,0xd8,0x55,0x8c,0xa4,0x39,0x76,0x0d,0x35,0x20,0xe4,0x5c,0x25, +0xa0,0x95,0xd2,0x75,0xdd,0x32,0xbd,0x75,0x7c,0xd5,0x42,0x69,0x2c,0x75,0x41,0xca, +0x9c,0x31,0x10,0xf6,0xb5,0x34,0x00,0x00,0x6e,0x2a,0xa1,0x73,0xc2,0x6b,0xc3,0x6b, +0xa2,0x6c,0x72,0xa2,0x4e,0x74,0x47,0x6b,0x57,0x74,0x75,0x4a,0x91,0x73,0xa3,0x2b, +0xa0,0x8b,0x90,0x63,0x7c,0x2e,0x70,0x68,0x9c,0x31,0x10,0xe5,0x87,0x75,0x10,0x00, +0x0d,0xdd,0x55,0xd9,0x8d,0xd9,0xb5,0xe1,0xb1,0x95,0x89,0xe5,0x55,0xa9,0x55,0xd8, +0x6e,0x55,0xa5,0xd9,0xb9,0x2e,0xb1,0x9d,0xa2,0x61,0x79,0x60,0x58,0x6c,0x52,0x21, +0x9c,0x31,0x10,0xbc,0xa9,0x97,0x30,0x00,0x71,0x9d,0x91,0x9a,0x9c,0xc0,0x9d,0x45, +0xbd,0x4d,0x79,0xdd,0x79,0x29,0x75,0xe9,0x6d,0xe1,0x69,0xd9,0x5a,0x19,0x7e,0x15, +0x8d,0xd1,0x95,0x55,0xa5,0x55,0x7d,0x59,0x9c,0x31,0x10,0x4b,0x97,0x87,0x10,0x00, +0x24,0xd2,0x34,0xcb,0x4e,0x4c,0x56,0x4a,0x84,0xcb,0x95,0xcb,0x7e,0x99,0x55,0x25, +0x7a,0x2b,0x91,0xa2,0xb4,0x34,0xa1,0xb2,0x81,0xcb,0x6c,0xcb,0x7d,0xd3,0x86,0x42, +0x9c,0x31,0x10,0x41,0x96,0x96,0x10,0x00,0x8e,0x35,0xad,0x2b,0xd2,0xb9,0xba,0xc3, +0x9d,0x2b,0x9c,0x1c,0x8d,0x29,0x2a,0x34,0x0a,0x32,0x05,0xbb,0x09,0xbc,0x15,0xba, +0x36,0xc3,0x3c,0x4b,0x10,0xd5,0x11,0xda,0x9c,0x31,0x10,0x05,0x97,0x86,0x20,0x00, +0x3a,0x72,0x2e,0x63,0x26,0x4b,0x66,0x2c,0xb5,0xa5,0xbe,0xab,0xd6,0x29,0xd3,0x2b, +0xca,0x43,0xb5,0xb3,0xbd,0xb4,0x8e,0x2e,0x72,0x2a,0x69,0x29,0x72,0x32,0x55,0xb4, +0x9c,0x31,0x10,0x54,0x97,0x66,0x10,0x00,0x7b,0x14,0x61,0x2a,0xa5,0x63,0xa8,0x94, +0xae,0x93,0xa2,0x49,0xc5,0xc4,0xa9,0x13,0x81,0x9c,0x9a,0x16,0x9a,0x8a,0x8d,0x10, +0x86,0xe5,0x9d,0x5c,0x92,0xb2,0x95,0x35,0x9c,0x31,0x10,0x01,0x88,0x76,0x10,0x00, +0x96,0x22,0x85,0x63,0x8d,0x9c,0x71,0x63,0xac,0x62,0xb0,0xa3,0xbe,0x1c,0x8e,0xd3, +0x5e,0x0c,0x59,0xc2,0x32,0x4b,0x72,0xc9,0xb1,0x94,0xe9,0x9c,0xe6,0x1c,0xaa,0xe2, +0x9c,0x31,0x10,0x4b,0xa8,0x76,0x10,0x00,0x7a,0xab,0x69,0xeb,0x5d,0xa1,0x60,0xa5, +0x81,0x24,0x94,0x50,0xa5,0x9c,0xa9,0x1c,0x88,0xdb,0x5a,0x53,0x49,0x52,0x43,0x5b, +0x5a,0x9c,0x92,0x19,0xc0,0x9d,0xdc,0x9b,0x9c,0x31,0x10,0xb7,0xb8,0x66,0x20,0x00, +0xa1,0x4b,0x75,0x83,0x5a,0x53,0x41,0xd9,0x49,0x4c,0x6d,0x5d,0xa1,0xd4,0xc6,0x09, +0xc1,0x5a,0xa0,0xdc,0x62,0xd3,0x39,0x93,0x1e,0xe2,0x39,0x22,0x82,0x2b,0xb0,0x55, +0x9c,0x31,0x10,0xa5,0xb9,0x67,0x20,0x00,0xdd,0xd3,0xce,0x62,0x95,0xa3,0x4e,0xeb, +0x21,0x6c,0x12,0x64,0x4c,0xda,0x99,0xe1,0xd1,0x93,0xe1,0x94,0xd2,0x53,0x75,0xd3, +0x4a,0x6c,0x02,0x6b,0x1d,0xe9,0x65,0x9b,0x9c,0x31,0x10,0xd1,0xc9,0x66,0x20,0x00, +0x9e,0x6a,0xaf,0x2d,0xb8,0xe8,0x99,0x29,0x6e,0xad,0x4e,0x85,0x35,0x06,0x5b,0x25, +0x89,0x10,0xab,0x38,0xba,0xce,0xb6,0xf1,0x84,0x91,0x5e,0xf5,0x35,0x0c,0x33,0x49, +0x9c,0x31,0x10,0x5e,0xc9,0x67,0x20,0x00,0x74,0xb6,0x95,0x06,0xc2,0xa9,0xc1,0x4c, +0xac,0xed,0x78,0xce,0x4d,0x4d,0x23,0x35,0x48,0xb9,0x7e,0x4d,0xa5,0x0c,0xcb,0x2d, +0xbd,0x0e,0xa4,0xa9,0x68,0x89,0x41,0x71,0x9c,0x31,0x10,0x78,0xca,0x57,0x30,0x00, +0x17,0x05,0x5f,0x45,0x7a,0xb9,0xb2,0xba,0xc6,0xf0,0xbd,0x04,0xab,0x36,0x68,0x9a, +0x3f,0x85,0x16,0xa9,0x59,0x15,0x7a,0xd5,0xad,0x15,0xc2,0xd5,0xbd,0x05,0xab,0x15, +0x9c,0x31,0x10,0x43,0xca,0x56,0x20,0x00,0x7c,0xc9,0x41,0x39,0x22,0x59,0x43,0xa4, +0x7e,0x95,0x95,0x16,0xc0,0xc4,0xaf,0x25,0xb3,0x06,0x9a,0xd8,0x5c,0xc4,0x3d,0x42, +0x24,0x81,0x71,0x24,0x7f,0x11,0xaa,0xe5,0x9c,0x31,0x10,0xcc,0xca,0x57,0x20,0x00, +0xb2,0xe5,0xaa,0xf9,0xb1,0x15,0x84,0xf5,0x52,0xd5,0x35,0x19,0x37,0x05,0x7e,0x76, +0x83,0x65,0xb2,0xd5,0xae,0xf5,0xac,0xf9,0xad,0x09,0x77,0x05,0x4c,0xe5,0x2e,0xd9, +0x9c,0x31,0x10,0x82,0xca,0x56,0x10,0x00,0x41,0x54,0x82,0x65,0x8b,0x55,0xb4,0xd5, +0xaf,0x05,0xac,0xf9,0xa6,0xf5,0x71,0x05,0x4a,0xf5,0x2a,0xea,0x49,0x55,0x82,0x68, +0x8f,0x55,0xb4,0xc6,0xad,0x05,0xad,0x05,0x9c,0x31,0x10,0x00,0xc9,0x55,0x00,0x00, +0xa7,0x65,0x6e,0x85,0x48,0x75,0x2b,0x69,0x48,0xb5,0x85,0x14,0x91,0xb5,0xb2,0x55, +0xb1,0x75,0xad,0x85,0xa6,0x75,0x71,0x75,0x4c,0x75,0x3a,0x6a,0x42,0x94,0x7e,0x49, +0x9c,0x31,0x10,0x36,0xb8,0x35,0x00,0x00,0x9b,0x9a,0xc8,0xa5,0xd1,0x38,0xca,0xd9, +0xbd,0x05,0x7b,0x05,0x44,0xd1,0x21,0x05,0x10,0xe9,0x3c,0xd9,0x73,0x19,0xa6,0xe5, +0xbf,0x05,0xd4,0xd5,0xdb,0x05,0xbe,0xe9,0x9c,0x31,0x10,0x75,0xc6,0x43,0x00,0x00, +0x81,0xac,0x5d,0xc3,0x3e,0x21,0x3d,0x52,0x59,0x3b,0x89,0xbb,0xad,0x33,0xc0,0x32, +0xc0,0x41,0xac,0xab,0x85,0xbb,0x59,0x4b,0x35,0xab,0x32,0x62,0x50,0xa3,0x84,0xcb, +0x9c,0x31,0x10,0x75,0xc6,0x43,0x00,0x00,0xad,0xab,0xc1,0xc4,0xc1,0xbc,0xb0,0x3b, +0x8c,0xd2,0x60,0x3a,0x3b,0xac,0x2e,0xd5,0x47,0x14,0x78,0x5b,0xa5,0x22,0xbc,0xd2, +0xc1,0x2b,0xb7,0x45,0x99,0xc4,0x6e,0x23,0x9c,0x31,0x10,0xfa,0xc6,0x42,0x00,0x00, +0x46,0xca,0x2f,0x2a,0x3b,0x42,0x64,0x43,0x97,0x2b,0xb6,0xcb,0xc1,0xb3,0xbd,0x39, +0xa7,0x2b,0x7f,0xbb,0x55,0xcc,0x37,0xb3,0x33,0x54,0x50,0x1b,0x81,0x44,0xab,0xb2, +0x9c,0x31,0x10,0x08,0xc5,0x32,0x00,0x00,0xbd,0xba,0xbf,0xc5,0xb2,0xca,0x93,0xb4, +0x6a,0x96,0x47,0x40,0x33,0x95,0x3f,0xd1,0x66,0x35,0x97,0x21,0xb3,0xb8,0xbd,0x36, +0xb8,0xb1,0xa5,0xa2,0x83,0x44,0x5c,0x35,0x9c,0x31,0x10,0x62,0xc7,0x44,0x00,0x00, +0x3f,0x75,0x37,0x65,0x4e,0x65,0x78,0x85,0xa1,0x65,0xb6,0x85,0xbb,0x65,0xb7,0x81, +0x9f,0x68,0x70,0x6a,0x44,0xb5,0x28,0x4a,0x3f,0xe4,0x78,0x3a,0x9a,0x30,0xaf,0x6a, +0x9c,0x31,0x10,0x19,0xc8,0x75,0x10,0x00,0xb8,0xe8,0xbb,0x32,0xa9,0x0c,0x79,0x12, +0x4a,0xcd,0x32,0xf1,0x2c,0x44,0x56,0xb2,0x88,0x89,0xa4,0xcd,0xb0,0xca,0xb2,0xd0, +0xb4,0xa9,0xa0,0xd1,0x76,0xf5,0x4e,0xf1,0x9c,0x31,0x10,0x60,0xc6,0x76,0x10,0x00, +0x39,0x5b,0x35,0x2e,0x60,0xd8,0x8c,0xcd,0xa8,0xd0,0xb4,0xed,0xb9,0x1a,0xb4,0xde, +0x96,0xd0,0x6a,0xdd,0x47,0x1a,0x32,0xa4,0x3d,0x40,0x6a,0xa6,0x95,0x28,0xae,0xd6, +0x9c,0x31,0x10,0xd4,0xc6,0x76,0x00,0x00,0xb6,0x91,0xb7,0x35,0xaa,0xc9,0x8a,0xde, +0x62,0xa1,0x45,0x14,0x36,0x5b,0x45,0x1d,0x70,0xa8,0x96,0xc5,0xae,0xe9,0xb2,0xdc, +0xb2,0xdb,0xa6,0xda,0x86,0xdb,0x62,0xdb,0x9c,0x31,0x10,0x6e,0xc5,0x76,0x00,0x00, +0x47,0x9b,0x39,0x11,0x47,0xae,0x70,0x00,0x97,0x6e,0xad,0x51,0xb4,0x65,0xb4,0x51, +0xa4,0x64,0x85,0x53,0x63,0x63,0x4b,0x54,0x3d,0x19,0x46,0xa5,0x6b,0x51,0x92,0x64, +0x9c,0x31,0x10,0x4f,0xc4,0x55,0x00,0x00,0xab,0x24,0xb3,0xb6,0xb3,0x69,0xa5,0x6d, +0x88,0xb1,0x69,0x29,0x50,0x91,0x3e,0x29,0x41,0xda,0x64,0x40,0x8e,0x52,0xaa,0x6c, +0xb4,0x92,0xb6,0x4c,0xa9,0x8e,0x8e,0x88,0x9c,0x31,0x10,0xd8,0xc4,0x44,0x00,0x00, +0x6e,0x72,0x51,0x50,0x3d,0xad,0x3c,0xb1,0x5c,0x29,0x89,0x65,0xaa,0x95,0xb6,0x6d, +0xb7,0x75,0xa9,0xa9,0x91,0x8d,0x72,0x49,0x55,0x51,0x40,0xb1,0x3c,0x95,0x59,0x2d, +0x9c,0x31,0x10,0x52,0xc4,0x43,0x00,0x00,0x86,0x69,0xa7,0x89,0xb3,0x51,0xb5,0x8d, +0xa9,0x4d,0x93,0x6d,0x78,0x2d,0x5e,0x89,0x49,0x8d,0x3e,0x35,0x51,0x30,0x7a,0x72, +0x9e,0x84,0xad,0x4e,0xb2,0xac,0xab,0x0e,0x9c,0x31,0x10,0x26,0xb4,0x42,0x00,0x00, +0xb2,0x88,0x82,0x51,0x53,0xb1,0x28,0x69,0x06,0x05,0x14,0xad,0x5d,0x6d,0xab,0x95, +0xd2,0x49,0xdf,0xad,0xdc,0x08,0xbf,0x92,0x94,0x4c,0x64,0x8e,0x37,0x4d,0x11,0x71, +0x9c,0x31,0x10,0x16,0xb4,0x62,0x00,0x00,0x0b,0x5c,0x42,0x94,0x90,0x6a,0xc4,0xb0, +0xd6,0xd9,0xda,0x99,0xc7,0x5c,0xa1,0x21,0x74,0xdd,0x4a,0x9d,0x25,0x5d,0x0a,0x61, +0x28,0xd8,0x74,0x9e,0xb9,0x1c,0xd4,0x9e,0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00, +0xde,0xa4,0xd4,0x66,0xb1,0x91,0x84,0x55,0x57,0x65,0x2f,0x98,0x10,0x12,0x18,0xa5, +0x59,0x74,0xa5,0x9a,0xcf,0x54,0xd9,0x96,0xd7,0x60,0xbc,0x85,0x91,0x75,0x62,0x65, +0x9c,0x31,0x10,0x9a,0xb3,0x32,0x00,0x00,0x3a,0x6a,0x1c,0x90,0x13,0x6d,0x41,0x86, +0x8d,0x28,0xc5,0x8e,0xd7,0x30,0xd6,0xb2,0xc4,0x49,0x9c,0xb1,0x6c,0x49,0x44,0x4d, +0x2d,0x8e,0x21,0x08,0x35,0x92,0x70,0x50,0x9c,0x31,0x10,0x15,0xb3,0x33,0x00,0x00, +0xaf,0x91,0xcf,0x29,0xd2,0xad,0xc5,0x2d,0xa4,0x91,0x77,0xad,0x50,0x51,0x3e,0x6d, +0x39,0x44,0x3f,0x36,0x5d,0x2c,0x8d,0x91,0xb4,0x69,0xc1,0xa9,0xba,0xcd,0xa5,0x39, +0x9c,0x31,0x10,0x75,0xa4,0x35,0x10,0x00,0x8c,0xb3,0x51,0xc3,0x32,0x73,0x31,0x33, +0x43,0x2b,0x60,0x2b,0x80,0x73,0x9e,0xa3,0xb3,0x8b,0xb6,0x52,0xa3,0x8b,0x7f,0x42, +0x59,0x13,0x48,0x23,0x50,0x76,0x6f,0x4b,0x9c,0x31,0x10,0xad,0xaa,0x76,0x20,0x00, +0x95,0xed,0xad,0xed,0xb5,0xed,0x99,0xed,0x75,0xed,0x55,0xed,0x4d,0xf5,0x5a,0x10, +0x73,0x0a,0xa1,0xf5,0xd9,0xb9,0xbe,0x81,0xb1,0x01,0x92,0x49,0x6a,0x8d,0x59,0xcd, +0x9c,0x31,0x10,0x8b,0x98,0x64,0x00,0x00,0x30,0x89,0x45,0x51,0x32,0xad,0x22,0x10, +0x35,0x4a,0x81,0xe4,0xb8,0x46,0x9f,0x6d,0xb2,0xad,0xb5,0x6e,0xa5,0x6d,0x79,0xed, +0x5e,0x4d,0x5e,0x29,0x69,0x4c,0x55,0xed,0x9c,0x31,0x10,0x2d,0x99,0x65,0x10,0x00, +0x2a,0x49,0x39,0xcd,0x55,0x6d,0x7e,0x0d,0x9a,0x56,0xcd,0xd4,0xde,0x32,0xae,0xa5, +0x81,0x60,0x90,0x61,0xae,0xa2,0xc5,0xc4,0xad,0x0a,0xda,0x6e,0xb1,0x34,0x3a,0x49, +0x9c,0x31,0x10,0x6b,0xa8,0x65,0x00,0x00,0x5b,0x52,0x5a,0x91,0x49,0x11,0x39,0x91, +0x48,0xce,0x52,0x44,0x57,0x29,0x6d,0x69,0x6c,0x6a,0x75,0x05,0x6a,0xc9,0x8c,0xed, +0xa0,0x91,0x70,0xd1,0x7f,0x6e,0xa4,0xcd,0x9c,0x31,0x10,0x98,0x98,0x55,0x10,0x00, +0x6c,0xed,0x52,0xcd,0x8a,0x4d,0x99,0x55,0x65,0x51,0x86,0x8e,0xb1,0xc5,0xad,0x91, +0x9e,0x8d,0x95,0xcd,0xc1,0x44,0x96,0x6d,0x79,0xed,0x7d,0x8d,0x91,0xce,0x89,0xcd, +0x9c,0x31,0x10,0xa5,0x88,0x45,0x10,0x00,0xaa,0x51,0xf6,0x0a,0x9d,0x70,0xa5,0xf9, +0x8d,0xa9,0x86,0xf1,0x75,0x31,0x89,0xa9,0x1a,0xc5,0x7d,0xad,0x69,0xc9,0x52,0x49, +0x89,0xc9,0x95,0x6d,0x6a,0x8d,0x82,0x91,0x9c,0x31,0x10,0x6b,0x78,0x45,0x10,0x00, +0xb9,0xdb,0x5b,0xda,0x7d,0x63,0xb2,0xde,0xe3,0x91,0x75,0x1a,0xa3,0x0d,0x99,0x84, +0x65,0xd1,0x85,0x0c,0xd9,0xcc,0x73,0x59,0x44,0xd3,0xcb,0x0d,0xa5,0x0a,0x72,0x99, +0x9c,0x31,0x10,0x6b,0x78,0x45,0x10,0x00,0x6b,0xc4,0xb4,0x15,0x3c,0x52,0xdb,0x49, +0x8a,0xd2,0xb4,0x54,0xcc,0x8d,0xa1,0x94,0x96,0x92,0x5a,0xda,0x2a,0x62,0x7f,0x0b, +0x2a,0x23,0x2a,0xe4,0x6e,0xdc,0x5a,0x22,0x9c,0x31,0x10,0xa5,0x88,0x45,0x10,0x00, +0x7d,0xed,0xa6,0xad,0x74,0xf1,0x8a,0x4e,0x3e,0x6d,0x51,0x0d,0x0e,0xb6,0x88,0xe9, +0x4e,0x48,0xa1,0xe5,0xb9,0xf1,0xa9,0xc6,0x76,0x6c,0xa1,0xcd,0x01,0xa9,0x0e,0x6d, +0x9c,0x31,0x10,0xea,0xa8,0x36,0x20,0x00,0x6e,0xb9,0x7e,0xf9,0x89,0x15,0xaa,0xf2, +0xb0,0xc7,0xa3,0x2b,0x7c,0xda,0x60,0x86,0x33,0x75,0x2e,0xc5,0x59,0x66,0x80,0x68, +0xc5,0x39,0xea,0xe6,0xdb,0x06,0xad,0x17,0x9c,0x31,0x10,0x1a,0xb9,0x46,0x20,0x00, +0x64,0xd3,0x51,0x13,0x32,0xca,0x42,0xeb,0x6c,0xe4,0xb7,0x15,0xce,0xc4,0xc8,0xe9, +0xba,0xe9,0x72,0xcc,0x43,0x4c,0x20,0x6b,0x17,0x53,0x4a,0xab,0xc2,0xf4,0xd3,0x04, +0x9c,0x31,0x10,0x20,0xc9,0x46,0x10,0x00,0xaa,0xe9,0xa8,0xca,0x83,0x2c,0x60,0x84, +0x4f,0x2b,0x3e,0xe2,0x5a,0xcb,0x97,0x4b,0xa4,0xca,0xb2,0xe2,0xb1,0x14,0x9c,0xcc, +0x6e,0xeb,0x55,0x4a,0x3c,0x6a,0x3b,0x41,0x9c,0x31,0x10,0xa9,0xc9,0x36,0x20,0x00, +0x86,0x84,0x9b,0x55,0xa7,0xbb,0xb9,0x39,0xac,0x93,0x92,0x85,0x65,0x5b,0x4b,0xa2, +0x30,0x5a,0x4a,0x83,0x9d,0x7e,0x8f,0x84,0xab,0x71,0xb7,0x71,0xa7,0x83,0x9a,0x75, +0x9c,0x31,0x10,0xbd,0xc8,0x46,0x10,0x00,0x6d,0x0b,0x45,0x0a,0x32,0x6a,0x45,0x54, +0x9e,0x8d,0x89,0x6b,0xa6,0x8a,0xb3,0x4b,0xa0,0x8b,0xa1,0x0b,0x7b,0x23,0x48,0x6b, +0x3b,0x62,0x34,0x2c,0x95,0xcb,0x8c,0x6a,0x9c,0x31,0x10,0x38,0xc9,0x56,0x10,0x00, +0x97,0x0b,0xae,0xec,0xa2,0xca,0x9d,0x2a,0x98,0xab,0x67,0x0c,0x40,0xec,0x34,0xd3, +0x57,0x29,0xa6,0x69,0x7f,0x8d,0xa2,0x6d,0xa9,0x4c,0x9a,0xc9,0x9c,0xf1,0x92,0xcd, +0x9c,0x31,0x10,0x5b,0xca,0x46,0x20,0x00,0x5a,0xf6,0x45,0x05,0x2e,0xd4,0x71,0x42, +0xa2,0x99,0x81,0x55,0xa6,0xb5,0xa3,0x01,0x9a,0xf9,0x9c,0xf9,0x8c,0xf5,0x58,0xf5, +0x42,0xf9,0x30,0xc0,0x7b,0x62,0x9e,0x76,0x9c,0x31,0x10,0xe1,0xc9,0x46,0x20,0x00, +0x81,0xcb,0xa6,0x49,0xa3,0x41,0x98,0xf4,0x9a,0xec,0x8a,0xeb,0x56,0xea,0x47,0x0b, +0x32,0x8b,0x77,0xad,0xa2,0x0c,0x7f,0xc9,0xa4,0x49,0x9d,0x54,0x9b,0x0c,0x9a,0xb2, +0x9c,0x31,0x10,0x6d,0xc9,0x45,0x20,0x00,0x8e,0x95,0x63,0x55,0x49,0x95,0x33,0x59, +0x65,0xa5,0xae,0x28,0x78,0xc4,0xa2,0x26,0x9e,0xc6,0x9b,0x45,0x9c,0x75,0x92,0x84, +0x6f,0x54,0x4d,0x95,0x3b,0x65,0x4c,0x68,0x9c,0x31,0x10,0xcf,0xca,0x55,0x20,0x00, +0xaf,0x16,0x7e,0xe6,0x94,0xf5,0x9d,0x04,0x9a,0xc4,0x9b,0x36,0x96,0xd6,0x81,0x05, +0x58,0xe4,0x49,0x05,0x32,0xb1,0x93,0x64,0x92,0x75,0x7f,0x76,0x9e,0xa6,0x9d,0x25, +0x9c,0x31,0x10,0x6d,0xc9,0x45,0x20,0x00,0x95,0x74,0x9e,0x46,0x8c,0xb5,0x6e,0x34, +0x4c,0xb5,0x39,0x5a,0x59,0x95,0xb4,0x44,0x73,0xa5,0x97,0x46,0x9b,0xa6,0x98,0x35, +0x9c,0xb6,0x94,0x45,0x82,0x94,0x5a,0x64,0x9c,0x31,0x10,0xd7,0xca,0x45,0x20,0x00, +0x49,0x15,0x34,0xb1,0x8f,0x65,0x9a,0x76,0x7d,0x66,0x9c,0x95,0x9d,0x35,0x94,0xc5, +0xa0,0xf5,0x8b,0x05,0x70,0xe5,0x4d,0x05,0x40,0xf5,0x46,0xd9,0xb1,0x16,0x7a,0xd5, +0x9c,0x31,0x10,0x6d,0xc9,0x45,0x20,0x00,0x93,0x84,0x9a,0x74,0x9c,0x5a,0x95,0xb5, +0x9a,0x38,0x88,0xb5,0x62,0x35,0x4d,0xb9,0x39,0x4a,0x6b,0xb6,0xad,0x34,0x79,0xb4, +0x97,0x34,0x9a,0xa6,0x99,0x46,0x9a,0xa2,0x9c,0x31,0x10,0x6d,0xc9,0x45,0x20,0x00, +0x96,0x54,0x79,0x94,0x58,0x55,0x45,0xa6,0x39,0x21,0x94,0xe4,0x9b,0x05,0x81,0xe6, +0x9d,0x16,0x9f,0xc5,0x96,0x45,0x9d,0x94,0x8b,0x64,0x72,0x75,0x4e,0x75,0x43,0x85, +0x9c,0x31,0x10,0xa9,0xc9,0x36,0x20,0x00,0x45,0x4c,0xac,0xbd,0x87,0x33,0x8b,0xba, +0x9a,0x49,0xa0,0x93,0x92,0x75,0x9e,0x75,0x83,0x8b,0x6b,0x62,0x49,0x9a,0x3f,0x6b, +0x55,0x7b,0xb0,0x7b,0x7f,0x7b,0x94,0x7b,0x9c,0x31,0x10,0x43,0xb8,0x35,0x20,0x00, +0xaf,0x05,0xc2,0xc5,0xa3,0x39,0xc0,0xb5,0x7d,0x25,0x4a,0xb5,0x11,0x45,0x04,0xca, +0x3d,0x21,0xe8,0xb4,0x77,0x24,0xae,0xc5,0xa7,0x46,0xc0,0x8a,0xa1,0x85,0xb8,0x64, +0x9c,0x31,0x10,0x0d,0xb8,0x34,0x10,0x00,0x7f,0x84,0x44,0x45,0x11,0xb5,0x02,0x4a, +0x4d,0xc6,0xe4,0x28,0x7b,0xa4,0xae,0x65,0xa3,0x85,0xbe,0x65,0x99,0x69,0xbe,0xb6, +0x79,0x15,0x4a,0xd5,0x17,0x34,0x06,0xba,0x9c,0x31,0x10,0x43,0xb8,0x35,0x20,0x00, +0x49,0x56,0xe8,0x85,0x75,0x54,0xac,0xb4,0x9d,0x35,0xc2,0xc5,0x95,0x29,0xba,0xc5, +0x7f,0x25,0x52,0xc5,0x19,0x25,0x16,0xe9,0x2c,0xc8,0xe1,0x45,0x86,0x85,0x9d,0x86, +0x9c,0x31,0x10,0x90,0xb9,0x34,0x10,0x00,0x9c,0xb5,0xc3,0x25,0x96,0xc4,0xb5,0x24, +0x8a,0xb5,0x5d,0x36,0x22,0xb6,0x19,0x45,0x20,0x78,0xc5,0x85,0xa4,0x55,0x8d,0x95, +0x9e,0x65,0xb9,0x75,0xa6,0x75,0xa7,0x61,0x9c,0x31,0x10,0x49,0xb9,0x24,0x20,0x00, +0x9e,0x95,0x63,0x55,0x38,0xa5,0x19,0x51,0x16,0x61,0x95,0xa4,0xc8,0x44,0x7b,0x95, +0xa4,0x66,0xa1,0x76,0xbc,0x99,0x97,0x50,0xa8,0xb0,0x6d,0x24,0x44,0xc5,0x1f,0x29, +0x9c,0x31,0x10,0x5b,0xb8,0x25,0x20,0x00,0x1a,0x85,0x5f,0x85,0xda,0x76,0x7b,0x45, +0xa0,0xc5,0x97,0x05,0xc5,0x05,0x92,0xc9,0xad,0x3a,0x80,0xa6,0x5b,0x45,0x26,0xa5, +0x23,0x69,0x34,0x58,0xc9,0xb9,0x98,0x15,0x9c,0x31,0x10,0xd4,0xb8,0x24,0x20,0x00, +0x91,0xd5,0x94,0x15,0xb7,0xc4,0xa8,0x30,0x9d,0xa1,0x9c,0x66,0x65,0x76,0x3c,0x76, +0x1b,0x71,0x24,0x32,0x8d,0xe5,0xc6,0x15,0x7f,0xc5,0x9c,0x49,0x99,0x75,0xbc,0xa0, +0x9c,0x31,0x10,0x15,0xb8,0x24,0x10,0x00,0x8f,0x15,0xa6,0xf5,0x7a,0xd5,0x55,0x15, +0x22,0xd5,0x25,0x2a,0x4e,0xb6,0xcf,0x55,0x8e,0x70,0x95,0x85,0x92,0x55,0xb3,0x81, +0xa2,0x65,0x95,0x85,0x96,0x75,0x67,0x65,0x9c,0x31,0x10,0x15,0xb8,0x24,0x10,0x00, +0x3a,0x95,0x21,0x61,0x2c,0x36,0xa1,0xd6,0xbc,0x05,0x7f,0xd5,0x96,0x48,0x99,0x75, +0xbe,0x99,0x8f,0x25,0xa4,0xe1,0x7a,0xf5,0x52,0xf4,0x22,0xf5,0x26,0xf4,0x5c,0xf6, +0x9c,0x31,0x10,0xd4,0xb8,0x24,0x20,0x00,0xcd,0x06,0x8a,0xb6,0x91,0x55,0x8e,0x81, +0xb9,0x65,0xa2,0x75,0x97,0x65,0x98,0xa5,0x65,0x35,0x36,0xb9,0x1d,0x44,0x36,0x78, +0xaf,0x95,0xac,0x36,0x83,0xa6,0x94,0x55,0x9c,0x31,0x10,0xcc,0xb8,0x34,0x20,0x00, +0xa3,0x75,0xb6,0x95,0x91,0x35,0x9e,0xd5,0x7b,0x06,0x48,0xd5,0x1f,0x25,0x24,0x91, +0x83,0x74,0xc8,0x84,0x81,0x55,0x94,0xc5,0x93,0x05,0xbb,0x05,0x94,0xd5,0x9b,0x15, +0x9c,0x31,0x10,0x7d,0xb7,0x24,0x10,0x00,0x8a,0x8b,0x5b,0x2b,0x2a,0xcc,0x19,0x36, +0x52,0xad,0xc9,0x4a,0x94,0x4a,0x89,0xab,0x8e,0x0c,0xb3,0xcc,0xa6,0x23,0x97,0x8a, +0x9a,0x8a,0x75,0x49,0x3a,0x8a,0x1d,0x8a,0x9c,0x31,0x10,0x15,0xb8,0x24,0x10,0x00, +0x30,0x6a,0xa7,0xa6,0xb2,0x45,0x7f,0xa4,0x8e,0x55,0xa1,0x75,0xb4,0x86,0x91,0x42, +0x98,0xb5,0x87,0x20,0x58,0xb4,0x27,0x44,0x28,0xa0,0x73,0x56,0xc6,0xa6,0x89,0x25, +0x9c,0x31,0x10,0xf7,0xb7,0x23,0x10,0x00,0x8b,0x54,0x8f,0x74,0xba,0x74,0x9a,0x72, +0x8b,0x66,0x89,0x86,0x71,0x55,0x37,0x95,0x27,0x69,0x51,0x75,0xc0,0x95,0x9a,0x39, +0x87,0xc5,0x89,0x34,0xb4,0xb5,0xa6,0x51,0x9c,0x31,0x10,0xf7,0xb7,0x23,0x10,0x00, +0x84,0x85,0x83,0x65,0x75,0x85,0x44,0x75,0x2a,0x85,0x4f,0x54,0xb5,0xb5,0xa4,0x26, +0x85,0xc5,0x8a,0x21,0xb0,0xc5,0xa2,0x35,0x80,0xa6,0x82,0x55,0x6b,0x94,0x41,0x64, +0x9c,0x31,0x10,0x7c,0xb6,0x14,0x00,0x00,0x2c,0x9b,0x65,0x5b,0xba,0x9b,0x9e,0x43, +0x8a,0xbb,0x92,0x3b,0xab,0xaa,0x90,0x4b,0x81,0xab,0x75,0x54,0x5c,0x94,0x3c,0x7a, +0x46,0x62,0x8d,0xc4,0xb1,0x1d,0x93,0xd3,0x9c,0x31,0x10,0xde,0xb6,0x23,0x00,0x00, +0x91,0x24,0x9d,0xb4,0xa2,0x45,0x89,0xa2,0x69,0x55,0x50,0x85,0x3f,0x75,0x52,0x61, +0x8d,0xb6,0xad,0x35,0x94,0xb9,0x8e,0x35,0x9b,0xb1,0x9f,0x36,0x8a,0xb5,0x6f,0x45, +0x9c,0x31,0x10,0x41,0xa5,0x23,0x00,0x00,0x35,0xd9,0x10,0x45,0x24,0xa5,0x7e,0x55, +0xcf,0x85,0xb6,0x71,0xa6,0x64,0xab,0xa5,0xb6,0x25,0x93,0xc5,0x58,0x11,0x28,0xb5, +0x16,0x54,0x42,0x75,0x94,0x91,0xd0,0x3a,0x9c,0x31,0x10,0x41,0xa5,0x23,0x00,0x00, +0xcf,0xb5,0xc6,0x20,0xad,0xc5,0x76,0x29,0x30,0xc6,0x1b,0x55,0x2c,0x91,0x65,0x75, +0xab,0x75,0xd2,0x81,0xcd,0x65,0xbb,0x81,0x9c,0x65,0x68,0x65,0x2f,0xb5,0x26,0x25, +0x9c,0x31,0x10,0xce,0xa5,0x22,0x00,0x00,0x48,0xc5,0x8c,0x35,0xb8,0xa5,0xbc,0x65, +0xb1,0x75,0xa1,0x75,0x85,0x85,0x51,0x59,0x36,0x91,0x44,0x75,0x75,0x75,0xa0,0x76, +0xae,0x85,0xab,0x55,0xa1,0x94,0x8e,0x65,0x9c,0x31,0x10,0x6c,0x93,0x11,0x00,0x00, +0x55,0x85,0x13,0xba,0x13,0x36,0x4f,0xb4,0xa1,0x54,0xc9,0x96,0xcc,0x64,0xbb,0x55, +0x9c,0xe5,0x6f,0x05,0x36,0xd5,0x27,0x30,0x48,0x55,0x87,0xa5,0xb1,0x31,0xba,0xa1, +0x9c,0x31,0x10,0x49,0x83,0x11,0x00,0x00,0xe6,0x65,0xb4,0x66,0x67,0x74,0x1d,0x56, +0x03,0x84,0x31,0x5a,0x7a,0x76,0xad,0x50,0xc4,0x55,0xc3,0x79,0xaf,0x85,0x7c,0x65, +0x4a,0x85,0x36,0x85,0x4a,0x35,0x70,0x98,0x9c,0x31,0x10,0xa2,0x63,0x11,0x00,0x00, +0xae,0xca,0xf4,0xa8,0xf3,0x0e,0xb0,0xb4,0x65,0x09,0x32,0x71,0x17,0x55,0x26,0xb1, +0x4d,0x09,0x73,0x4d,0x9c,0xb5,0xb1,0x0c,0x90,0xa9,0x5e,0xcd,0x47,0x09,0x40,0xd5, +0x9c,0x31,0x10,0xe5,0x53,0x21,0x00,0x00,0x25,0xdc,0x3a,0x12,0x62,0x15,0x89,0xc6, +0x75,0x9c,0x46,0xe1,0x40,0xad,0x6e,0x9c,0x3d,0x5e,0x21,0x9d,0x32,0xe1,0x54,0xde, +0x86,0x24,0x74,0xdc,0x9d,0xe1,0x96,0x21,0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00, +0x6d,0xe2,0x3e,0x14,0x41,0x1b,0x95,0xd4,0x56,0xe3,0x65,0x5a,0x4e,0x94,0x68,0x92, +0x93,0x0c,0x6d,0x1c,0x6c,0x5b,0x56,0x91,0x90,0xc2,0x9a,0x25,0xa2,0x93,0xed,0x53, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_LANGUAGE_SWITCH.txt b/config/_default_cfg_src_/res/en/SOUND_LANGUAGE_SWITCH.txt new file mode 100644 index 0000000..0164f01 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_LANGUAGE_SWITCH.txt @@ -0,0 +1,155 @@ +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x76,0x43,0x20,0x21,0x00,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0xd6,0xa4,0x9c,0x31,0x10,0xea,0xcb,0x79,0x87,0x67, +0x7d,0xd5,0x85,0xd5,0x7d,0xa5,0xbe,0xa4,0x84,0x88,0x3a,0xe5,0xdd,0x15,0x0e,0x15, +0xee,0x55,0x20,0xd5,0xbf,0x15,0x68,0x55,0x6b,0x55,0xb4,0x95,0x26,0xd5,0xe5,0x55, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb, +0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2,0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24, +0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2,0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3, +0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c,0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44, +0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00,0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60, +0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71,0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa, +0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75,0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00, +0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30,0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75, +0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca,0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75, +0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00,0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30, +0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5,0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea, +0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15,0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00, +0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb,0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b, +0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35,0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb, +0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00,0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04, +0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52,0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e, +0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90,0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55, +0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21,0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9, +0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5,0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70, +0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65,0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00, +0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41,0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55, +0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba,0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50, +0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69,0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21, +0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65,0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00, +0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba,0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85, +0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50,0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75, +0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00,0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6, +0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb,0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb, +0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10,0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71, +0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51,0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95, +0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00,0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01, +0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78,0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d, +0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76,0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55, +0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a,0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba, +0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75,0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda, +0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85,0x9c,0x31,0x10,0x9c,0xc5,0x54,0x30,0x00, +0xcb,0x6d,0x92,0x2e,0x30,0x89,0x77,0xd6,0xcb,0x69,0x7b,0x28,0x34,0x51,0x8e,0x92, +0xc8,0x89,0x65,0x09,0x3a,0x72,0xa1,0x84,0xba,0xa6,0x56,0x6e,0x4a,0x4e,0xb0,0x89, +0x9c,0x31,0x10,0xd0,0xcb,0x78,0x77,0x56,0xac,0xeb,0x48,0xeb,0x56,0xcb,0xd5,0x03, +0x86,0x65,0x3b,0x6c,0xe0,0x8b,0x0d,0x0b,0xef,0x2b,0x20,0x6b,0xbf,0x8b,0x68,0x2b, +0x6b,0xab,0xb8,0x4b,0x27,0x6b,0xe8,0xab,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb,0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2, +0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24,0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2, +0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3,0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c, +0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44,0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00, +0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60,0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71, +0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa,0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75, +0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00,0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30, +0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75,0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca, +0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75,0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00, +0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30,0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5, +0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea,0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15, +0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00,0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb, +0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b,0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35, +0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb,0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00, +0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04,0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52, +0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e,0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90, +0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55,0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21, +0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9,0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5, +0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70,0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65, +0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00,0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41, +0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55,0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba, +0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50,0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69, +0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21,0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65, +0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00,0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba, +0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85,0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50, +0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75,0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00, +0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6,0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb, +0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb,0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10, +0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71,0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51, +0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95,0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00, +0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01,0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78, +0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d,0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76, +0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55,0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a, +0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba,0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75, +0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda,0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_NINE.txt b/config/_default_cfg_src_/res/en/SOUND_NINE.txt new file mode 100644 index 0000000..0f35603 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_NINE.txt @@ -0,0 +1,175 @@ +0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x82,0x1b,0x81,0xa3, +0xa6,0xd1,0x79,0x9b,0x41,0x99,0x22,0x22,0x65,0xdd,0x7e,0x6d,0x6a,0x2a,0x52,0x09, +0x76,0x2a,0x6d,0x93,0x56,0x25,0xa9,0xa4,0x9c,0x31,0x10,0x96,0x72,0x12,0x00,0x00, +0x8d,0x4b,0x8b,0x83,0x76,0x6a,0x67,0x2a,0x6f,0x2b,0x76,0xcc,0x82,0xe3,0x93,0x4b, +0x92,0xf4,0x6a,0xec,0x44,0xe1,0x45,0x24,0x72,0xea,0xaa,0x74,0xd5,0x03,0xbc,0xad, +0x9c,0x31,0x10,0x1f,0xb2,0x22,0x00,0x00,0x7d,0x49,0x77,0x6d,0x76,0xad,0x7c,0x4a, +0x88,0x64,0x90,0x69,0x8a,0x72,0x77,0x71,0x63,0x85,0x60,0x69,0x78,0x8c,0x9c,0x51, +0xb2,0x8d,0xa2,0x2a,0x6f,0x65,0x3d,0x55,0x9c,0x31,0x10,0xf6,0xc3,0x23,0x00,0x00, +0x5b,0xb9,0x76,0xc9,0x9d,0x31,0xb1,0xc1,0xa1,0x29,0x76,0x55,0x4c,0xa9,0x47,0x45, +0x68,0x85,0x9a,0x65,0xbf,0x00,0xbf,0x35,0x91,0xd9,0x52,0x15,0x32,0x36,0x46,0x55, +0x9c,0x31,0x10,0x29,0xc3,0x42,0x00,0x00,0x7b,0x0d,0xb3,0x0c,0xd2,0x4c,0xbe,0x0d, +0x7a,0xae,0x37,0x32,0x26,0xae,0x4d,0xa8,0x8d,0xa4,0xc7,0x8c,0xdf,0xd1,0xbb,0x10, +0x68,0x52,0x23,0xad,0x1f,0xa5,0x54,0xa9,0x9c,0x31,0x10,0x12,0xc3,0x43,0x10,0x00, +0x9c,0x2d,0xd5,0x91,0xe6,0x35,0xb4,0x2d,0x59,0x29,0x17,0x25,0x1d,0x09,0x5a,0xad, +0xa7,0x10,0xe1,0x54,0xea,0x91,0xac,0xb1,0x4a,0x09,0x0b,0xca,0x1c,0x8e,0x63,0xb2, +0x9c,0x31,0x10,0x5e,0xd5,0x43,0x10,0x00,0x99,0x71,0xb5,0x70,0xb5,0x50,0x90,0x6d, +0x5d,0x48,0x41,0x8d,0x4f,0x52,0x76,0x76,0x9f,0x76,0xb9,0x91,0xb3,0x71,0x89,0x8d, +0x55,0x71,0x3f,0xb8,0x54,0x74,0x7d,0x95,0x9c,0x31,0x10,0x28,0xd5,0x34,0x00,0x00, +0xa6,0x74,0xbc,0xcc,0xb0,0x6c,0x7f,0xa2,0x4c,0x72,0x3e,0xd2,0x5a,0x8a,0x86,0xab, +0xad,0x73,0xbf,0xad,0xaa,0x8d,0x74,0xa3,0x44,0x6a,0x3e,0xca,0x61,0x8a,0x8f,0xd3, +0x9c,0x31,0x10,0x15,0xd5,0x44,0x20,0x00,0xb4,0x91,0xc0,0xd1,0xa2,0xa9,0x69,0xae, +0x3e,0x89,0x41,0xad,0x68,0xa8,0x98,0xb1,0xba,0xad,0xbf,0x8d,0x9a,0xad,0x5e,0x6d, +0x38,0x29,0x45,0x4d,0x72,0x69,0xa2,0x40,0x9c,0x31,0x10,0x74,0xd9,0x87,0x40,0x00, +0xbe,0xed,0xbc,0xc9,0x8e,0xea,0x4a,0xed,0x32,0xed,0x52,0xcd,0x8a,0xc9,0xb6,0xc9, +0xc8,0xc5,0xa2,0xa9,0x57,0x09,0x27,0x8d,0x4f,0x2d,0x81,0x31,0xa9,0x11,0xc3,0x36, +0x9c,0x31,0x10,0x41,0xda,0x86,0x40,0x00,0xb6,0xf6,0x76,0xd5,0x24,0x70,0x37,0x09, +0x7c,0xe9,0x9f,0x29,0xb8,0xe8,0xba,0xe8,0x95,0x29,0x47,0x6d,0x1f,0x56,0x6c,0xda, +0x92,0x99,0xb0,0xb4,0xb8,0xd5,0xa4,0xd1,0x9c,0x31,0x10,0xf7,0xdb,0x86,0x30,0x00, +0x6c,0xcd,0x20,0x69,0x4d,0x02,0x86,0xe1,0xa1,0x45,0xb8,0xe9,0xac,0xed,0x8d,0x11, +0x3f,0x10,0x2b,0x18,0x7a,0x95,0x8c,0xb1,0xb4,0xad,0xb0,0xee,0x9f,0x09,0x68,0xe9, +0x9c,0x31,0x10,0xdc,0xdb,0x86,0x40,0x00,0x1e,0x85,0x5b,0x46,0x85,0x09,0xa1,0x6d, +0xb6,0xac,0xa6,0xd0,0x8c,0xf1,0x3d,0x0d,0x2f,0x11,0x7c,0x6e,0x86,0xca,0xb6,0xe9, +0xab,0x4d,0xa1,0x0d,0x6c,0xcc,0x22,0x91,0x9c,0x31,0x10,0xcb,0xdb,0x76,0x20,0x00, +0x5d,0x85,0x7f,0x05,0xa1,0x49,0xb4,0x75,0xa4,0xd9,0x93,0x05,0x45,0x31,0x2c,0xd2, +0x7a,0x65,0x81,0x11,0xb7,0x41,0xa7,0x45,0xa4,0xc5,0x74,0xc5,0x28,0xca,0x55,0xc9, +0x9c,0x31,0x10,0xf7,0xdb,0x86,0x30,0x00,0x7c,0xb0,0x9a,0xf1,0xb2,0x6d,0xa5,0x2a, +0x99,0x2d,0x52,0xe9,0x28,0x85,0x73,0x09,0x7d,0x4e,0xb1,0x2d,0xa6,0xce,0xa6,0x90, +0x85,0x0c,0x39,0x0d,0x41,0x31,0x7c,0x2e,0x9c,0x31,0x10,0x7f,0xdb,0x76,0x30,0x00, +0x8b,0x25,0xb4,0xe5,0xa3,0x74,0xa0,0xc5,0x6c,0xc9,0x2a,0xca,0x61,0xc5,0x78,0x94, +0xa0,0xe5,0xaa,0x95,0xa7,0x46,0x97,0x25,0x56,0xc5,0x2e,0x90,0x73,0x34,0x7b,0x65, +0x9c,0x31,0x10,0x7f,0xdb,0x76,0x30,0x00,0xae,0xe6,0xa4,0xb5,0xa8,0xb4,0x89,0x45, +0x41,0x01,0x3c,0xe5,0x7a,0x76,0x85,0x76,0xb0,0xf4,0xa3,0x15,0xa2,0x96,0x79,0x15, +0x33,0x19,0x53,0x58,0x78,0x25,0x95,0x46,0x9c,0x31,0x10,0xfb,0xdb,0x56,0x20,0x00, +0xac,0xe6,0xa3,0x44,0x9c,0xb5,0x6c,0xd5,0x2f,0x09,0x65,0x86,0x76,0x89,0xa0,0xe4, +0xa6,0xe9,0xa3,0x31,0x99,0x05,0x5e,0xb9,0x30,0xd5,0x6f,0x81,0x78,0xea,0xa6,0xc9, +0x9c,0x31,0x10,0xcb,0xdb,0x76,0x20,0x00,0xa2,0xd4,0xa3,0x05,0x91,0x35,0x54,0xb5, +0x36,0xc1,0x75,0x35,0x7d,0x45,0xaa,0xb5,0xa0,0xe4,0xa2,0xd5,0x8d,0x45,0x4a,0xd1, +0x3c,0xa2,0x76,0xe4,0x81,0x94,0xaa,0xc5,0x9c,0x31,0x10,0x42,0xcb,0x66,0x30,0x00, +0xc2,0xe5,0xc6,0xc5,0x8f,0x45,0x10,0xe1,0x08,0xb6,0x6e,0xc1,0x87,0x84,0xd4,0xc5, +0xc2,0xe6,0xc2,0xb9,0x89,0x45,0x0e,0xf0,0x0e,0xb1,0x6c,0xa1,0x8d,0x91,0xd2,0xe5, +0x9c,0x31,0x10,0x42,0xcb,0x66,0x30,0x00,0xc2,0xe5,0xbe,0xb5,0x87,0x26,0x11,0x11, +0x10,0xc2,0x6e,0xa1,0x8d,0x91,0xd0,0xd5,0xbe,0xf4,0xbc,0xb4,0x89,0x25,0x15,0x01, +0x0e,0xa2,0x6c,0xd1,0x89,0x74,0xce,0xd5,0x9c,0x31,0x10,0xdf,0xca,0x66,0x30,0x00, +0xbe,0xd5,0xc0,0x86,0x8f,0x65,0x20,0xf1,0x08,0x51,0x6b,0x41,0x83,0xc5,0xcc,0x85, +0xba,0xd5,0xbe,0xc5,0x97,0x64,0x2e,0xc5,0x02,0x95,0x65,0xc5,0x7f,0x35,0xc6,0x49, +0x9c,0x31,0x10,0xee,0xcb,0x76,0x20,0x00,0xba,0xd6,0xc1,0x06,0x9f,0x25,0x42,0xc4, +0x00,0xe9,0x55,0x75,0x7a,0xb9,0xba,0xb5,0xbe,0xf5,0xbf,0x24,0xab,0x05,0x58,0xc5, +0x07,0x15,0x3f,0x49,0x7a,0x65,0xa7,0x05,0x9c,0x31,0x10,0x53,0xca,0x65,0x30,0x00, +0xc2,0x93,0xbd,0xab,0xb2,0x5c,0x74,0x5c,0x16,0xa1,0x25,0x59,0x77,0x19,0x92,0xe9, +0xc3,0x7b,0xb5,0x72,0xb9,0x4a,0x8e,0x92,0x31,0x8b,0x12,0x38,0x66,0xd1,0x81,0x9b, +0x9c,0x31,0x10,0xc7,0xca,0x76,0x30,0x00,0xba,0x85,0xb6,0xb6,0xb9,0x26,0xa3,0x55, +0x52,0xb4,0x10,0xf9,0x47,0x88,0x7a,0x24,0xa2,0xf5,0xbd,0x15,0xb5,0x26,0xb2,0xd5, +0x78,0xc5,0x25,0x25,0x20,0x81,0x71,0x04,0x9c,0x31,0x10,0xff,0xca,0x75,0x20,0x00, +0x87,0xd2,0xbc,0x63,0xb3,0x5b,0xb8,0x6b,0x9d,0xa3,0x4a,0x7b,0x16,0x7d,0x4b,0xc4, +0x7e,0x14,0xa3,0x7b,0xbb,0x83,0xb4,0xa3,0xb3,0x73,0x7a,0x63,0x2c,0x83,0x20,0x51, +0x9c,0x31,0x10,0x78,0xca,0x57,0x30,0x00,0x6d,0x21,0x85,0x55,0xb6,0xd5,0xb0,0xc5, +0xb6,0xf5,0xa5,0x15,0x59,0x05,0x1e,0xf1,0x38,0xea,0x7a,0x25,0x91,0x61,0xbb,0x31, +0xaf,0x25,0xb6,0xa5,0x92,0xd9,0x45,0x19,0x9c,0x31,0x10,0x48,0xca,0x77,0x30,0x00, +0x1d,0x09,0x51,0x88,0x7e,0x45,0xa0,0xd5,0xb6,0xe6,0xaf,0x45,0xb3,0x05,0x80,0xb4, +0x3a,0xe5,0x20,0xd5,0x61,0xb6,0x80,0xe5,0xa8,0xb5,0xb2,0x94,0xb1,0x25,0xaf,0x45, +0x9c,0x31,0x10,0xc7,0xca,0x76,0x30,0x00,0x74,0xf5,0x36,0xb5,0x26,0x81,0x6d,0xa6, +0x83,0x76,0xac,0xe5,0xae,0x74,0xb0,0xd4,0xab,0x25,0x6f,0x25,0x34,0xd0,0x26,0x50, +0x71,0x61,0x83,0x96,0xaf,0x26,0xae,0x95,0x9c,0x31,0x10,0xdf,0xca,0x66,0x30,0x00, +0xb0,0xa5,0xaf,0x04,0x6f,0x41,0x3c,0xe1,0x24,0x71,0x69,0x82,0x83,0x55,0xa7,0x15, +0xb0,0x85,0xae,0xc5,0xb1,0x04,0x7b,0x21,0x42,0xe6,0x24,0xc6,0x5b,0xc4,0x80,0xe8, +0x9c,0x31,0x10,0x48,0xca,0x77,0x30,0x00,0x9a,0xe5,0xb2,0x75,0xaa,0xd5,0xb7,0x35, +0x8b,0x25,0x51,0x05,0x2b,0x19,0x3f,0x29,0x7e,0x3a,0x8c,0xc5,0xb4,0xd4,0xa9,0x45, +0xb7,0x45,0xa0,0xc9,0x64,0xe5,0x3a,0xd5,0x9c,0x31,0x10,0xc7,0xca,0x76,0x30,0x00, +0x26,0x40,0x6f,0x12,0x81,0x42,0xa7,0x85,0xaf,0x14,0xaa,0xda,0xb6,0xd5,0x81,0x04, +0x50,0xf5,0x2b,0x14,0x3f,0x3a,0x82,0x8a,0x88,0xc5,0xb2,0x94,0xa8,0xf5,0xb5,0x11, +0x9c,0x31,0x10,0xc0,0xca,0x87,0x30,0x00,0xaa,0xcd,0x6b,0x09,0x46,0xed,0x24,0xce, +0x5b,0x8d,0x82,0xec,0x93,0x51,0xb2,0xd1,0xa6,0xf1,0xb8,0xed,0x9c,0xad,0x62,0xcd, +0x40,0xe9,0x22,0x89,0x67,0x26,0x82,0xc9,0x9c,0x31,0x10,0xfc,0xc9,0x88,0x30,0x00, +0x99,0x93,0xb1,0x13,0xa9,0x13,0xb7,0x13,0x9a,0x8b,0x61,0x13,0x43,0x13,0x24,0x53, +0x63,0x4d,0x84,0xd2,0x97,0x52,0xb0,0xd3,0xa8,0xd3,0xb3,0x14,0x9e,0xcb,0x65,0x0a, +0x9c,0x31,0x10,0x7a,0xc9,0x87,0x30,0x00,0x4b,0x29,0x26,0xae,0x51,0xc8,0x86,0xc8, +0x8f,0x6a,0xae,0xed,0xaa,0xed,0xaf,0x0c,0xa9,0x11,0x73,0x0a,0x51,0x0d,0x32,0xec, +0x3b,0x76,0x80,0xb2,0x87,0x10,0xa4,0xcd,0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00, +0xac,0xdb,0xaa,0xdc,0xb1,0x1a,0x88,0xa3,0x5a,0x9c,0x44,0xdb,0x28,0x02,0x65,0x15, +0x86,0x5b,0x95,0x1a,0xaa,0x9b,0xac,0x9c,0xb0,0x9a,0xa2,0x92,0x6f,0x14,0x51,0x1b, +0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00,0x34,0xe2,0x3d,0x74,0x7a,0x95,0x89,0x11, +0x9e,0xdb,0xac,0xe4,0xae,0xda,0xaf,0x13,0x8e,0x9c,0x5e,0xe2,0x48,0xdb,0x2c,0x14, +0x53,0x0c,0x84,0xa9,0x91,0x24,0xa4,0xd3,0x9c,0x31,0x10,0x8f,0xc7,0x87,0x30,0x00, +0xae,0xdd,0xb2,0xd5,0xa9,0x69,0x7e,0xcd,0x56,0xd8,0x41,0x25,0x30,0x61,0x62,0xf0, +0x86,0x52,0x97,0x18,0xa6,0xe6,0xae,0xd9,0xb0,0xa1,0xa0,0xd8,0x76,0xda,0x57,0x25, +0x9c,0x31,0x10,0xbd,0xc7,0x88,0x20,0x00,0x3f,0x1a,0x37,0x2d,0x68,0x90,0x88,0xdb, +0x98,0xe3,0xa6,0xda,0xb1,0x13,0xae,0xdc,0x9c,0xda,0x74,0xdb,0x56,0xdb,0x3e,0xdb, +0x3b,0x64,0x6a,0xc3,0x8a,0xea,0x9c,0xd4,0x9c,0x31,0x10,0x2e,0xc6,0x77,0x20,0x00, +0xa6,0x9a,0xaf,0x1b,0xae,0x9c,0x98,0x9a,0x74,0xdb,0x56,0xdb,0x40,0xe1,0x3d,0xa5, +0x66,0x85,0x88,0xf0,0x9a,0xd5,0xa4,0xda,0xad,0x1b,0xac,0x9b,0x9a,0xd2,0x78,0xe4, +0x9c,0x31,0x10,0x12,0xc5,0x78,0x20,0x00,0x5d,0x38,0x47,0x25,0x3b,0x6b,0x5e,0x83, +0x82,0xe8,0x96,0x97,0xa2,0xc6,0xad,0x38,0xb0,0x37,0x9e,0xb8,0x7e,0xb8,0x60,0xc6, +0x4b,0x28,0x3a,0x58,0x54,0xb2,0x7c,0x2c,0x9c,0x31,0x10,0x2e,0xc6,0x77,0x20,0x00, +0x95,0x20,0xa2,0xd5,0xaa,0xda,0xb0,0x93,0xa4,0xe3,0x88,0xd3,0x68,0x9b,0x51,0x1b, +0x3e,0x11,0x4b,0x2e,0x70,0x8a,0x8e,0xeb,0x9e,0xd3,0xa6,0xe2,0xae,0xd3,0xa9,0x1b, +0x9c,0x31,0x10,0x6f,0xb5,0x77,0x20,0x00,0xa2,0xdb,0x64,0x94,0x32,0xda,0x08,0x5d, +0x07,0x88,0x48,0xb3,0x8b,0x0c,0xb4,0xea,0xca,0xcc,0xdc,0xe2,0xdc,0xdc,0xb6,0x9b, +0x7e,0xe2,0x4b,0x1c,0x1f,0x1a,0x00,0xe5,0x9c,0x31,0x10,0xd5,0xb6,0x77,0x20,0x00, +0x28,0xc9,0x70,0xeb,0xa8,0xd3,0xc2,0xe3,0xd4,0xd4,0xde,0xe2,0xca,0xd3,0x96,0xdb, +0x5e,0xda,0x31,0x24,0x06,0x4a,0x0f,0x2d,0x4e,0x91,0x94,0xe4,0xbc,0xd2,0xd0,0xe3, +0x9c,0x31,0x10,0x2b,0xb4,0x67,0x10,0x00,0xde,0xcb,0xd7,0x22,0xae,0xdc,0x78,0xdb, +0x44,0xdb,0x19,0x5b,0x01,0x63,0x26,0x8c,0x70,0xe9,0xaa,0xd4,0xc6,0xa1,0xd7,0x54, +0xde,0x5a,0xc9,0x1c,0x99,0x1b,0x62,0x9b,0x9c,0x31,0x10,0x77,0xb5,0x67,0x20,0x00, +0x31,0x1b,0x0a,0x53,0x0d,0x25,0x46,0xd1,0x8c,0xe4,0xb8,0xd2,0xcc,0xec,0xda,0xd3, +0xd4,0xe3,0xb4,0xd3,0x84,0xe1,0x52,0xdd,0x27,0x1a,0x06,0xed,0x1e,0xca,0x5e,0xeb, +0x9c,0x31,0x10,0xb9,0xb3,0x56,0x20,0x00,0x9e,0x88,0xbe,0x66,0xd1,0x0a,0xda,0x53, +0xcb,0x19,0xa1,0x59,0x70,0xa7,0x42,0xb5,0x18,0x39,0x0b,0x12,0x32,0x68,0x77,0x19, +0xac,0xd6,0xc4,0xa9,0xd5,0x44,0xd4,0x3a,0x9c,0x31,0x10,0x28,0xb4,0x65,0x10,0x00, +0xba,0xd8,0x90,0xe2,0x62,0xd9,0x37,0x24,0x12,0x51,0x13,0x2e,0x46,0x91,0x88,0xe4, +0xb6,0xd6,0xca,0xe4,0xd8,0xda,0xce,0x9c,0xae,0xdd,0x82,0xd9,0x56,0xe1,0x2d,0x1d, +0x9c,0x31,0x10,0xf4,0xb3,0x55,0x10,0x00,0x10,0x2d,0x1d,0x48,0x57,0x6a,0x96,0x54, +0xbb,0x69,0xce,0x55,0xd5,0x21,0xc6,0x95,0xa6,0x5c,0x7c,0x9a,0x50,0x1b,0x28,0x5a, +0x12,0x52,0x29,0x5e,0x65,0x5a,0xa0,0x5d,0x9c,0x31,0x10,0x63,0xb3,0x44,0x10,0x00, +0xc0,0x10,0xce,0xa4,0xd0,0x13,0xc0,0x63,0xa0,0x52,0x76,0x5b,0x4b,0x54,0x26,0x64, +0x16,0x41,0x31,0x70,0x6f,0x4d,0xa5,0xa1,0xc2,0x0e,0xd1,0x61,0xd0,0x54,0xbb,0x63, +0x9c,0x31,0x10,0xd7,0xb3,0x44,0x00,0x00,0x97,0x56,0x6c,0x58,0x40,0x64,0x1e,0x52, +0x17,0x76,0x3d,0x49,0x7c,0x63,0xad,0x4a,0xc6,0x6a,0xd2,0x94,0xcd,0x59,0xb4,0x5e, +0x8f,0x5a,0x66,0x64,0x3d,0x53,0x1e,0x61,0x9c,0x31,0x10,0x10,0xb3,0x35,0x00,0x00, +0x1a,0x6b,0x44,0x6c,0x83,0x6a,0xaf,0x6c,0xc5,0x6b,0xcf,0x8b,0xc7,0x4b,0xaf,0x8a, +0x8c,0x6c,0x62,0x6b,0x39,0x8b,0x1c,0x2b,0x1e,0x81,0x4c,0x6c,0x89,0x6b,0xb3,0x93, +0x9c,0x31,0x10,0x9f,0xb3,0x34,0x00,0x00,0xcb,0x63,0xd3,0x32,0xc8,0x82,0xad,0x92, +0x86,0x85,0x58,0x29,0x31,0xac,0x18,0x13,0x21,0xa1,0x55,0x53,0x91,0x8c,0xb9,0x52, +0xcd,0xa4,0xd3,0x4a,0xc6,0xad,0xa9,0x68,0x9c,0x31,0x10,0x6b,0xb4,0x34,0x00,0x00, +0x7f,0x8c,0x53,0x43,0x2f,0x93,0x1b,0x2d,0x28,0x81,0x5c,0x73,0x97,0x6c,0xbe,0x6a, +0xd0,0x84,0xd2,0x4b,0xc4,0x81,0xa6,0x6d,0x7b,0x6a,0x4e,0x53,0x2b,0xab,0x17,0x0a, +0x9c,0x31,0x10,0xe4,0xb4,0x35,0x00,0x00,0x28,0x64,0x61,0x71,0x9c,0x95,0xc0,0x4a, +0xd0,0x8c,0xd2,0x23,0xc1,0x8a,0xa2,0x64,0x79,0x92,0x4e,0x54,0x2d,0xaa,0x1a,0x0b, +0x2c,0x84,0x63,0x72,0x9b,0x8c,0xbe,0x4a,0x9c,0x31,0x10,0xe1,0xb4,0x33,0x00,0x00, +0xcc,0x92,0xcc,0x35,0xbd,0x71,0x9f,0x75,0x78,0xa5,0x4f,0x55,0x31,0xb5,0x1f,0x15, +0x2f,0x85,0x64,0x59,0x9a,0x95,0xbd,0x55,0xcd,0xa5,0xce,0x25,0xbe,0x75,0xa1,0x75, +0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00,0x79,0x99,0x50,0x55,0x30,0xb1,0x1e,0x11, +0x2d,0x85,0x61,0x55,0x97,0xa4,0xba,0x51,0xca,0xa1,0xcc,0x32,0xbe,0x85,0xa0,0x65, +0x79,0xa9,0x51,0x71,0x32,0xa1,0x1f,0x01,0x9c,0x31,0x10,0xe2,0xb4,0x31,0x00,0x00, +0x2e,0xc4,0x60,0xa3,0x96,0xd3,0xba,0xa9,0xcc,0xd2,0xce,0x0a,0xbe,0xbc,0xa1,0x34, +0x79,0x54,0x4f,0xaa,0x31,0xd1,0x21,0x01,0x31,0x4b,0x63,0x2c,0x98,0x53,0xba,0xab, +0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00,0xcb,0xa0,0xcd,0x45,0xbe,0x69,0xa0,0x69, +0x77,0x95,0x4e,0x65,0x30,0x95,0x20,0x11,0x32,0x8a,0x64,0x54,0x99,0xb9,0xbb,0x51, +0xcc,0x94,0xcd,0x46,0xbd,0x78,0x9d,0x56,0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00, +0x74,0x91,0x4b,0x66,0x2e,0xb5,0x21,0x14,0x36,0x89,0x69,0x49,0x9c,0x98,0xbb,0x41, +0xca,0xb4,0xc9,0x4a,0xb8,0x69,0x98,0x66,0x71,0x81,0x4c,0x60,0x32,0xb2,0x26,0x49, +0x9c,0x31,0x10,0x9a,0xb3,0x32,0x00,0x00,0x3d,0x75,0x6e,0x12,0x9e,0x8c,0xbc,0x49, +0xc8,0xb1,0xc5,0x71,0xb3,0x71,0x93,0x6d,0x6c,0x69,0x48,0x6c,0x2f,0x92,0x2a,0x95, +0x47,0x8e,0x78,0x49,0xa4,0x69,0xbd,0x6c,0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00, +0xc7,0x75,0xc1,0x8d,0xad,0x85,0x8b,0x6e,0x64,0x2d,0x43,0x91,0x2f,0x09,0x32,0xc8, +0x57,0x8d,0x85,0x6d,0xaa,0x6d,0xbe,0x6d,0xc4,0x41,0xbb,0x65,0xa2,0x6d,0x7f,0x89, +0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00,0x5b,0x4e,0x3f,0xa9,0x32,0x09,0x42,0x91, +0x6a,0x31,0x94,0x8c,0xb0,0x49,0xbe,0xa9,0xbf,0x66,0xad,0x79,0x8e,0x6d,0x69,0x6d, +0x49,0x89,0x35,0x29,0x3a,0xa4,0x5b,0x6e,0x9c,0x31,0x10,0x0e,0xb3,0x21,0x00,0x00, +0x86,0x88,0xa9,0x75,0xbc,0x49,0xc0,0x42,0xb2,0x49,0x94,0x8c,0x6f,0x6e,0x4e,0x89, +0x3a,0x6e,0x3a,0x91,0x57,0x4d,0x82,0x6c,0xa6,0x65,0xba,0x29,0xc0,0x6e,0xb2,0x49, +0x9c,0x31,0x10,0x0e,0xb3,0x21,0x00,0x00,0x93,0x91,0x6d,0x6c,0x4c,0x90,0x3b,0x9a, +0x40,0xc8,0x5f,0x61,0x88,0x88,0xac,0x56,0xbf,0x71,0xbe,0x69,0xa7,0x69,0x81,0x71, +0x59,0x48,0x3f,0x92,0x3b,0x69,0x50,0x8e,0x9c,0x31,0x10,0x93,0xb2,0x21,0x00,0x00, +0x78,0x74,0xa1,0x8e,0xbc,0x6d,0xc3,0x88,0xb4,0x6d,0x8f,0x8d,0x62,0x8d,0x41,0x69, +0x38,0x68,0x49,0x26,0x6f,0x49,0x99,0x94,0xbb,0xad,0xc7,0x31,0xb9,0x89,0x92,0x0e, +0x9c,0x31,0x10,0x37,0xb2,0x12,0x00,0x00,0x62,0x93,0x40,0x6c,0x36,0x69,0x48,0x4a, +0x70,0xa4,0x9e,0x2b,0xc1,0x8b,0xc8,0x4a,0xb0,0x4b,0x83,0x6b,0x57,0x73,0x3c,0x8c, +0x3c,0x4c,0x56,0x83,0x7f,0x2b,0xa9,0x8a,0x9c,0x31,0x10,0x29,0xb1,0x21,0x00,0x00, +0xc2,0xad,0xbf,0xd1,0xa1,0x2a,0x77,0x31,0x54,0xc9,0x45,0x29,0x4d,0x11,0x67,0xb1, +0x8a,0x09,0xa8,0x2a,0xb4,0xcc,0xaa,0xd5,0x90,0x2d,0x71,0xcd,0x5a,0xa6,0x54,0x4d, +0x9c,0x31,0x10,0x0c,0xa1,0x21,0x00,0x00,0x3d,0xb1,0x6a,0x31,0x9c,0x2c,0xbf,0x89, +0xc9,0x88,0xb4,0xaa,0x8b,0xae,0x61,0xad,0x48,0x8d,0x47,0xa9,0x5b,0xb1,0x7b,0xb6, +0x9b,0x8d,0xaf,0x2d,0xad,0x2d,0x97,0xa9,0x9c,0x31,0x10,0xf1,0x92,0x11,0x00,0x00, +0x75,0x89,0x46,0x25,0x34,0x49,0x42,0xb1,0x64,0x65,0x8d,0x81,0xac,0x65,0xb6,0x76, +0xa7,0x76,0x88,0x75,0x6a,0x60,0x5a,0x85,0x5a,0xb5,0x68,0x99,0x7e,0x5a,0x90,0x99, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_ONE.txt b/config/_default_cfg_src_/res/en/SOUND_ONE.txt new file mode 100644 index 0000000..42be5b2 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_ONE.txt @@ -0,0 +1,145 @@ +0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x86,0x1b,0x8d,0x63, +0xce,0xd1,0xe5,0xdc,0xdd,0x4a,0xd5,0x8a,0xa9,0x52,0x81,0xc3,0x3d,0x1a,0x3a,0x91, +0x4d,0xd4,0x6e,0x03,0x71,0x5b,0x86,0x5e,0x9c,0x31,0x10,0xfc,0x82,0x21,0x00,0x00, +0x7b,0x92,0x79,0x69,0x7e,0x69,0x86,0x6d,0x8d,0x6d,0x8f,0xa5,0x8a,0x4e,0x7d,0x6d, +0x75,0x6d,0x77,0x6c,0x85,0x75,0xa3,0x8a,0xb8,0x49,0x92,0x51,0x47,0x8c,0x1d,0x49, +0x9c,0x31,0x10,0x67,0xb5,0x21,0x00,0x00,0x77,0x3c,0x84,0xbb,0x92,0xba,0x93,0xbd, +0x7d,0x3b,0x5b,0x33,0x49,0xba,0x66,0x3a,0xb1,0xb3,0xe2,0x53,0xa8,0x89,0x4a,0x62, +0x12,0x2a,0x1b,0x44,0x89,0xbc,0xea,0xbd,0x9c,0x31,0x10,0xb6,0xc4,0x23,0x10,0x00, +0xa5,0xa5,0x8b,0x45,0x95,0xd5,0x92,0x15,0x6a,0x21,0x4a,0x65,0x43,0x15,0x71,0x35, +0xb7,0x55,0xbf,0xb5,0x9b,0xa5,0x8b,0xe5,0x59,0x19,0x19,0xc6,0x44,0xa2,0xaf,0xd5, +0x9c,0x31,0x10,0x9e,0xc7,0x34,0x10,0x00,0xc6,0x65,0x9a,0x85,0x9a,0x55,0xb2,0xa4, +0x75,0x34,0x1a,0xb5,0x19,0x56,0x7a,0x86,0xd0,0x75,0xbe,0x70,0x9d,0x54,0xb4,0xb5, +0x6f,0x14,0x00,0xc8,0x18,0x5a,0x94,0x86,0x9c,0x31,0x10,0x09,0xd7,0x45,0x30,0x00, +0xa9,0x66,0x9a,0x85,0x94,0x45,0xa0,0xc4,0x71,0x14,0x36,0xb4,0x47,0x56,0x90,0x86, +0xaf,0x66,0x99,0x85,0x98,0x54,0xa4,0xb4,0x62,0x49,0x2a,0x84,0x4f,0x75,0xa0,0x76, +0x9c,0x31,0x10,0x59,0xd8,0x46,0x20,0x00,0xb0,0xec,0x96,0xcb,0xa1,0x0a,0x9c,0xca, +0x45,0x2b,0x22,0xad,0x69,0x2c,0xb2,0xca,0xa9,0x29,0x94,0x6a,0xb1,0x8d,0x82,0x0d, +0x23,0xa3,0x2a,0x68,0x91,0x29,0xbc,0xac,0x9c,0x31,0x10,0xff,0xd9,0x47,0x30,0x00, +0x9a,0xed,0xa2,0xec,0xb2,0xea,0x4d,0x09,0x0a,0xb1,0x51,0x0c,0xc0,0xcd,0xad,0x0c, +0x92,0xb2,0xbf,0x4a,0x8a,0x73,0x15,0x63,0x12,0x6c,0xa5,0x64,0xc0,0x8b,0x8f,0x0a, +0x9c,0x31,0x10,0xbd,0xea,0x56,0x30,0x00,0x9a,0x80,0x9c,0x6b,0x5e,0xad,0x38,0x32, +0x76,0xcc,0xa7,0x34,0x88,0xbd,0x93,0x4b,0xab,0x99,0x76,0x5a,0x39,0x79,0x54,0x91, +0xa7,0x65,0x8a,0x9e,0x89,0x4d,0xaf,0xba,0x9c,0x31,0x10,0x87,0xeb,0x67,0x30,0x00, +0x94,0x45,0x47,0xb9,0x3a,0x34,0x95,0xb5,0x92,0x36,0x81,0x96,0xa7,0x65,0xaf,0x64, +0x5b,0x95,0x38,0x31,0x6e,0xd4,0x9e,0x05,0x78,0xe6,0x9d,0x15,0xbe,0xb5,0x72,0x55, +0x9c,0x31,0x10,0xac,0xeb,0x67,0x40,0x00,0x48,0x89,0x4a,0x88,0x9b,0x44,0x77,0xc5, +0x98,0x16,0xb8,0xe5,0x91,0x04,0x58,0xc4,0x3e,0x12,0x80,0xc5,0x7d,0x54,0x8b,0x64, +0xad,0xb5,0xab,0x06,0x6c,0xd5,0x48,0x39,0x9c,0x31,0x10,0x76,0xda,0x57,0x40,0x00, +0x37,0xd5,0x8e,0x24,0x83,0x95,0xba,0x85,0xf3,0x0a,0x83,0x66,0x38,0x81,0x0a,0xa6, +0x7b,0x75,0x80,0xa4,0xa0,0xc4,0xe5,0x81,0xb8,0x66,0x59,0x15,0x13,0x19,0x3d,0x92, +0x9c,0x31,0x10,0xc3,0xdb,0x67,0x40,0x00,0x90,0x54,0x87,0x94,0xcc,0x94,0xda,0xf5, +0x7d,0x56,0x34,0xc1,0x14,0xaa,0x7d,0x45,0x80,0xe4,0xb2,0xb4,0xe1,0x44,0xa8,0xc5, +0x54,0xd5,0x13,0x05,0x49,0x82,0x88,0x26,0x9c,0x31,0x10,0x37,0xdc,0x67,0x40,0x00, +0x91,0x35,0xd4,0xf4,0xcc,0xc4,0x81,0x29,0x33,0x14,0x14,0x8a,0x81,0x36,0x7d,0x16, +0xb6,0xb5,0xd7,0x15,0xad,0x04,0x5c,0xb4,0x15,0x18,0x45,0x66,0x8a,0x56,0x8b,0x55, +0x9c,0x31,0x10,0x2f,0xdc,0x77,0x40,0x00,0xd3,0x05,0xc4,0xb5,0x8b,0x34,0x3b,0x14, +0x14,0x76,0x7d,0x55,0x7b,0x05,0xb4,0xa5,0xd3,0x15,0xad,0x15,0x66,0xb5,0x1f,0x29, +0x3b,0x45,0x88,0x55,0x89,0x54,0xcf,0x05,0x9c,0x31,0x10,0xdb,0xdb,0x77,0x40,0x00, +0xc2,0x85,0x93,0x35,0x47,0x26,0x14,0x11,0x6f,0xc4,0x78,0xe5,0xae,0xa5,0xcf,0x15, +0xaf,0x46,0x76,0x66,0x29,0x7a,0x2b,0x18,0x84,0x24,0x81,0xa5,0xcc,0xe6,0xc2,0x96, +0x9c,0x31,0x10,0x1c,0xdc,0x67,0x30,0x00,0x9f,0x21,0x58,0xf5,0x18,0xb0,0x55,0x75, +0x7c,0xa6,0x9c,0xf6,0xd1,0x05,0xb2,0xf4,0x8a,0xe4,0x3f,0x21,0x1c,0xa1,0x77,0x11, +0x79,0x11,0xbc,0xe5,0xc6,0xe4,0xa7,0x15,0x9c,0x31,0x10,0x7f,0xdb,0x76,0x30,0x00, +0x70,0xc6,0x2b,0x1a,0x31,0x39,0x82,0x24,0x85,0x74,0xcc,0xf5,0xba,0xc6,0x9f,0x05, +0x5e,0xf5,0x1a,0xd5,0x53,0xb5,0x7e,0x45,0x99,0x15,0xcd,0x04,0xae,0xf4,0x92,0xf1, +0x9c,0x31,0x10,0xf0,0xdb,0x77,0x30,0x00,0x4e,0xe5,0x18,0x91,0x6b,0xc5,0x78,0xa5, +0xac,0xd5,0xc6,0xe5,0xab,0x25,0x88,0xe5,0x3f,0x04,0x22,0x95,0x7b,0x25,0x77,0x45, +0xb8,0xc5,0xbe,0xd5,0xa5,0x15,0x7e,0xf5,0x9c,0x31,0x10,0x67,0xdb,0x66,0x30,0x00, +0x35,0x00,0x2c,0xa5,0x7e,0xd2,0x79,0x86,0xc2,0xc5,0xb6,0xc8,0xa3,0x18,0x7b,0x09, +0x33,0x05,0x34,0xc5,0x7c,0x85,0x7f,0x95,0xc2,0xd5,0xb4,0xe5,0xa0,0xd5,0x7b,0x15, +0x9c,0x31,0x10,0x4c,0xdb,0x66,0x40,0x00,0x31,0x00,0x3a,0xa4,0x7a,0xa6,0x7f,0x96, +0xbe,0xd5,0xb0,0xd5,0xa0,0xe9,0x7f,0x25,0x3a,0xe0,0x38,0x91,0x76,0xf2,0x7d,0x81, +0xb8,0xc5,0xb0,0xc1,0xa0,0xe6,0x87,0x11,0x9c,0x31,0x10,0x7f,0xdb,0x76,0x30,0x00, +0x44,0xe1,0x32,0x81,0x6f,0x74,0x79,0x34,0xae,0xc5,0xb4,0xc6,0xa4,0xe5,0x91,0x35, +0x56,0xe5,0x30,0xf9,0x61,0x85,0x74,0x89,0x9e,0xd5,0xb6,0xf5,0xa7,0x25,0x9b,0x19, +0x9c,0x31,0x10,0xfa,0xda,0x66,0x30,0x00,0x6c,0xb9,0x39,0x29,0x4a,0x85,0x72,0x45, +0x85,0xd5,0xb2,0xf9,0xab,0x04,0xa2,0x41,0x88,0xf1,0x4f,0x22,0x3a,0xd2,0x63,0xe6, +0x76,0x95,0x9e,0xc4,0xae,0xa4,0xa7,0x59,0x9c,0x31,0x10,0x69,0xcb,0x66,0x40,0x00, +0xb7,0x29,0x62,0xda,0x0a,0xf5,0x0a,0x82,0x5e,0xf1,0x7f,0x60,0xd9,0x04,0xd4,0xd5, +0xcc,0xb8,0xa7,0x29,0x49,0x19,0x09,0x2a,0x1a,0xb9,0x6a,0x55,0x91,0x31,0xdb,0x30, +0x9c,0x31,0x10,0xee,0xcb,0x76,0x20,0x00,0xcd,0x25,0xc6,0xc5,0x9e,0xd6,0x41,0x05, +0x09,0x59,0x21,0x28,0x6e,0x59,0x94,0xc5,0xd9,0x05,0xc9,0x55,0xc6,0xf4,0xa0,0xe5, +0x44,0xe5,0x0f,0x35,0x19,0x19,0x70,0x66,0x9c,0x31,0x10,0x73,0xca,0x76,0x20,0x00, +0x8e,0xb5,0xd3,0x01,0xcb,0x96,0xc7,0x19,0xa8,0xe8,0x52,0xd9,0x19,0x26,0x0c,0x55, +0x64,0x54,0x82,0xf1,0xc5,0x52,0xcf,0x41,0xc7,0x21,0xb2,0xe5,0x6e,0xd5,0x2c,0xe5, +0x9c,0x31,0x10,0x73,0xca,0x76,0x20,0x00,0x06,0x76,0x43,0xc6,0x79,0x44,0xa5,0x69, +0xd4,0xd9,0xc6,0xb9,0xc6,0xb5,0x96,0xc6,0x4f,0x05,0x19,0x45,0x0f,0x16,0x6c,0x65, +0x7c,0xb4,0xc6,0xc1,0xcf,0x11,0xc1,0x35,0x9c,0x31,0x10,0xb2,0xca,0x76,0x10,0x00, +0xb9,0x35,0x77,0x05,0x3f,0x09,0x0c,0xb9,0x2b,0xa8,0x76,0xca,0x91,0x19,0xcc,0x99, +0xc8,0xc9,0xc1,0x09,0xaf,0x09,0x6a,0xf9,0x3a,0xf9,0x06,0x69,0x39,0x65,0x76,0xf5, +0x9c,0x31,0x10,0xff,0xca,0x75,0x20,0x00,0x99,0xa3,0xcf,0x7c,0xc9,0x74,0xbe,0x8d, +0xa9,0x8d,0x6e,0x7d,0x3d,0x7e,0x06,0x3e,0x31,0xa3,0x76,0x6b,0x97,0x9b,0xcc,0x74, +0xcc,0x7c,0xbe,0x7c,0xae,0x7d,0x77,0x75,0x9c,0x31,0x10,0x45,0xc9,0x75,0x20,0x00, +0x44,0xd6,0x0e,0x7a,0x1d,0x98,0x6e,0xd4,0x8f,0x14,0xbe,0xd5,0xce,0xd5,0xc2,0xd2, +0xb2,0xcd,0x86,0xad,0x50,0xac,0x20,0xe8,0x0e,0xed,0x56,0x8e,0x84,0xae,0xb0,0xcd, +0x9c,0x31,0x10,0xa8,0xc7,0x65,0x20,0x00,0xcb,0x29,0xc6,0x64,0xb5,0x69,0x94,0x89, +0x69,0xa9,0x45,0xa9,0x2b,0x2d,0x3a,0xa9,0x66,0x89,0x8a,0x8d,0xaa,0x6d,0xb7,0x6d, +0xbd,0x6d,0xb1,0x6d,0x9f,0x4d,0x80,0x4d,0x9c,0x31,0x10,0x6d,0xc6,0x53,0x00,0x00, +0x55,0x3b,0x2b,0xb9,0x22,0xc2,0x45,0xab,0x7c,0xb3,0xae,0xaa,0xce,0x62,0xd7,0xab, +0xc4,0x53,0x9c,0xbb,0x68,0x53,0x35,0xcc,0x15,0x46,0x24,0xc6,0x58,0x1d,0x97,0x34, +0x9c,0x31,0x10,0x75,0xc6,0x43,0x00,0x00,0xc0,0x14,0xd7,0x3d,0xd3,0x2c,0xb7,0x33, +0x8d,0x32,0x5d,0x3b,0x30,0x3c,0x18,0x4e,0x2b,0xc4,0x64,0x53,0x9d,0xc4,0xc2,0xc6, +0xd5,0xc5,0xce,0x35,0xb1,0xb5,0x89,0xab,0x9c,0x31,0x10,0xd7,0xc5,0x53,0x00,0x00, +0x5d,0x6e,0x32,0x91,0x19,0xb4,0x2e,0x92,0x62,0xad,0x9c,0x8d,0xbf,0x90,0xd2,0x91, +0xcc,0x31,0xb2,0x92,0x8d,0x71,0x65,0x91,0x3c,0x71,0x1f,0x76,0x2a,0x99,0x5a,0x74, +0x9c,0x31,0x10,0x6d,0xc6,0x53,0x00,0x00,0x93,0x45,0xb8,0x2d,0xcc,0xbd,0xcb,0xa5, +0xb7,0x45,0x98,0x2d,0x72,0x35,0x49,0x34,0x25,0xa3,0x26,0x35,0x4d,0x9d,0x84,0xb5, +0xad,0x1c,0xc5,0x44,0xcb,0x24,0xba,0xb4,0x9c,0x31,0x10,0x4a,0xc4,0x53,0x00,0x00, +0x9f,0x0e,0x7c,0x51,0x57,0x31,0x33,0x32,0x25,0x29,0x3e,0x24,0x70,0xa9,0x9e,0x0e, +0xba,0x69,0xc7,0x69,0xbe,0x69,0xa8,0x8d,0x8a,0x2e,0x69,0x6d,0x45,0xad,0x2b,0x31, +0x9c,0x31,0x10,0xd2,0xc5,0x55,0x00,0x00,0x32,0x95,0x5a,0x31,0x8b,0x8d,0xae,0x4d, +0xc3,0x91,0xc4,0x71,0xb4,0x8d,0x9a,0x4d,0x7b,0x91,0x58,0x44,0x38,0x6a,0x2c,0x49, +0x46,0x49,0x76,0x69,0x9f,0x2d,0xb7,0x89,0x9c,0x31,0x10,0xd7,0xc5,0x53,0x00,0x00, +0xc3,0x48,0xb9,0x6a,0xa4,0x6e,0x89,0x6d,0x6c,0x4d,0x4c,0x8e,0x31,0x31,0x34,0xb4, +0x5a,0x35,0x88,0xb1,0xa8,0x31,0xbc,0xb1,0xbf,0x51,0xb2,0xac,0x9b,0x4e,0x7f,0x8d, +0x9c,0x31,0x10,0xcf,0xc5,0x43,0x00,0x00,0x60,0x4d,0x41,0xb1,0x2f,0x6c,0x40,0x86, +0x6b,0x61,0x95,0x64,0xb0,0x69,0xbf,0x66,0xba,0x49,0xa8,0x8c,0x90,0x51,0x74,0x51, +0x55,0x6d,0x39,0x28,0x33,0x8a,0x51,0x51,0x9c,0x31,0x10,0x52,0xc4,0x43,0x00,0x00, +0x7e,0xb4,0xa1,0x15,0xb5,0xb2,0xbd,0x51,0xb2,0x94,0x9f,0x55,0x88,0x8e,0x6e,0x69, +0x4f,0xcd,0x36,0x31,0x39,0xb5,0x5d,0x51,0x89,0xcd,0xa7,0x29,0xb9,0xcd,0xba,0x4d, +0x9c,0x31,0x10,0xcf,0xc5,0x43,0x00,0x00,0xac,0x89,0x98,0x41,0x81,0x65,0x67,0x51, +0x4a,0xb1,0x36,0x56,0x41,0x8d,0x67,0x4c,0x91,0x89,0xac,0x4e,0xbb,0x8d,0xb8,0x48, +0xa8,0x85,0x93,0x49,0x7c,0x8d,0x61,0x51,0x9c,0x31,0x10,0x52,0xc4,0x43,0x00,0x00, +0x45,0xb1,0x36,0x4c,0x48,0x8a,0x70,0x45,0x97,0x6c,0xae,0x4d,0xbb,0x6e,0xb4,0x2c, +0xa4,0xb1,0x8e,0x56,0x76,0x91,0x5b,0x49,0x41,0x69,0x35,0x81,0x4c,0x68,0x76,0x6a, +0x9c,0x31,0x10,0x52,0xc4,0x43,0x00,0x00,0x9c,0x51,0xb2,0x8d,0xbb,0x4d,0xb1,0x52, +0xa0,0x79,0x8a,0x91,0x72,0x69,0x56,0x89,0x3d,0x24,0x37,0x8a,0x54,0x31,0x7f,0x90, +0xa2,0x31,0xb6,0xb2,0xbc,0x50,0xb0,0x95,0x9c,0x31,0x10,0xcf,0xc5,0x43,0x00,0x00, +0x9e,0x6a,0x86,0x85,0x6d,0x45,0x52,0x8a,0x3c,0x25,0x3c,0x94,0x5c,0x56,0x86,0x95, +0xa5,0x4c,0xb6,0xad,0xb8,0x4e,0xaa,0xac,0x97,0x45,0x80,0x85,0x68,0x4d,0x50,0xad, +0x9c,0x31,0x10,0xcf,0xc5,0x43,0x00,0x00,0x3d,0x31,0x41,0xb8,0x62,0x56,0x8b,0xad, +0xa8,0x2c,0xb6,0xad,0xb5,0x4e,0xa5,0xa8,0x93,0x45,0x7e,0x85,0x68,0x4d,0x52,0xb1, +0x40,0x32,0x45,0x94,0x65,0x51,0x8b,0x89,0x9c,0x31,0x10,0xbb,0xb5,0x42,0x00,0x00, +0xcd,0x48,0xe8,0x89,0xe4,0x4a,0xc7,0x88,0xa4,0x49,0x7f,0x8d,0x58,0x4d,0x2d,0xb1, +0x0a,0x32,0x15,0xb4,0x52,0x4e,0x98,0xa9,0xc7,0x48,0xde,0x8d,0xdb,0x4d,0xc1,0x8d, +0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00,0xa1,0x55,0x7e,0x95,0x5b,0x45,0x35,0xa5, +0x14,0x35,0x16,0xa9,0x4a,0x5a,0x8d,0xa4,0xc0,0x41,0xda,0x95,0xdb,0x51,0xc4,0x95, +0xa5,0x55,0x83,0x85,0x61,0x55,0x3e,0x95,0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00, +0x1c,0x01,0x15,0xa2,0x41,0x24,0x83,0xb9,0xb7,0x26,0xd1,0xb5,0xd7,0x50,0xc5,0x96, +0xa9,0x54,0x87,0xa5,0x67,0x42,0x47,0x95,0x27,0x35,0x18,0xb0,0x3b,0x41,0x79,0x96, +0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00,0xae,0x39,0xc8,0xb5,0xd1,0x56,0xc3,0x74, +0xaa,0x91,0x89,0x62,0x6a,0x68,0x4c,0x49,0x31,0x71,0x21,0x8c,0x3b,0x62,0x73,0x64, +0xac,0x6d,0xcb,0x72,0xd5,0x4d,0xc5,0x4c,0x9c,0x31,0x10,0x0e,0xb3,0x21,0x00,0x00, +0xa8,0xae,0x85,0x69,0x68,0x70,0x4f,0x52,0x39,0x8d,0x29,0x5a,0x3e,0x8c,0x72,0x68, +0xa7,0xa2,0xc5,0x28,0xce,0x89,0xc1,0x52,0xa5,0x98,0x82,0x74,0x62,0x4e,0x48,0x89, +0x9c,0x31,0x10,0x1f,0xb2,0x22,0x00,0x00,0x34,0x48,0x2d,0x91,0x4b,0x22,0x80,0x80, +0xb0,0x71,0xc7,0x52,0xca,0x30,0xb8,0x15,0x9b,0xb6,0x79,0x88,0x5c,0x85,0x47,0xa2, +0x3a,0x4d,0x3b,0xac,0x5c,0x4e,0x8c,0x64,0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00, +0xb3,0x74,0xc5,0x92,0xc2,0x79,0xae,0x68,0x90,0x86,0x6f,0x46,0x55,0x70,0x44,0x4d, +0x3b,0x52,0x48,0xb1,0x6e,0x74,0x9c,0x96,0xbd,0x55,0xc7,0x84,0xbb,0x29,0x9c,0x86, +0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00,0x79,0x24,0x5a,0x69,0x46,0x75,0x3f,0x71, +0x4a,0x91,0x69,0x71,0x93,0x8d,0xb4,0x45,0xc2,0x69,0xba,0x69,0xa0,0x6d,0x7e,0x6d, +0x60,0x71,0x4a,0x71,0x41,0x4c,0x4b,0x6e,0x9c,0x31,0x10,0xbb,0xb2,0x11,0x00,0x00, +0x68,0x35,0x8e,0xa5,0xaf,0xd5,0xbf,0xb6,0xb9,0xc9,0xa1,0xa9,0x80,0xb5,0x60,0xb5, +0x48,0xb4,0x41,0xb2,0x4f,0x34,0x6e,0x44,0x93,0xaa,0xb2,0x35,0xc0,0x04,0xb8,0x41, +0x9c,0x31,0x10,0x34,0xb2,0x10,0x00,0x00,0x9d,0x40,0x76,0xdb,0x52,0x26,0x3d,0xd5, +0x41,0xd0,0x5a,0x52,0x7f,0x2e,0xa6,0xc4,0xc2,0x44,0xc4,0xbb,0xaa,0xa3,0x7f,0x38, +0x56,0x31,0x3f,0x4c,0x41,0x34,0x58,0xca,0x9c,0x31,0x10,0x9e,0xa2,0x11,0x00,0x00, +0x77,0x31,0xbc,0x25,0xec,0x38,0xf4,0xb9,0xd1,0xd5,0x90,0xa1,0x4e,0x46,0x24,0x10, +0x1f,0x34,0x3c,0x21,0x6d,0x39,0x9d,0xba,0xc0,0x46,0xca,0xb5,0xba,0xb5,0x97,0x31, +0x9c,0x31,0x10,0xd9,0x92,0x21,0x00,0x00,0x5b,0x69,0x1e,0x2d,0x0b,0x8d,0x24,0x55, +0x57,0x6c,0x8e,0x6a,0xba,0x91,0xce,0x51,0xc5,0x71,0xa3,0x51,0x78,0x69,0x57,0x8a, +0x49,0x68,0x53,0x6c,0x6a,0x49,0x82,0x71,0x9c,0x31,0x10,0x02,0x72,0x01,0x00,0x00, +0xd0,0x5e,0xea,0x6a,0xdc,0x3c,0xaf,0x82,0x7b,0x9a,0x4e,0xa3,0x3e,0x82,0x4c,0x45, +0x6c,0x92,0x89,0x6d,0x96,0x7b,0x99,0x6a,0x8f,0x6b,0x7f,0x4a,0x75,0x94,0x76,0x8a, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_OVER.txt b/config/_default_cfg_src_/res/en/SOUND_OVER.txt new file mode 100644 index 0000000..847f36b --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_OVER.txt @@ -0,0 +1,175 @@ +0x9c,0x31,0x10,0x4c,0x43,0x22,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x81,0xdb,0x89,0xdb, +0xa5,0xdb,0xe5,0xe3,0xb9,0xec,0xae,0x63,0x95,0xe9,0xa9,0xdb,0xc5,0xe4,0x76,0x64, +0xa5,0x1a,0x92,0x1a,0xc4,0xda,0x92,0x51,0x9c,0x31,0x10,0xe4,0x99,0x46,0x30,0x00, +0x81,0xeb,0x89,0xeb,0x7d,0xca,0xce,0x34,0x84,0xed,0x0f,0x4c,0xdc,0x8a,0x27,0x2a, +0x60,0xea,0xae,0xab,0x29,0x6b,0xae,0x2b,0x89,0xcb,0x61,0xcb,0x86,0x4b,0x99,0x6b, +0x9c,0x31,0x10,0x2c,0x87,0x23,0x00,0x00,0x2d,0xd1,0xc4,0x34,0x89,0x94,0x62,0x85, +0xbd,0x55,0x66,0xa5,0x79,0x25,0x8e,0xf5,0x76,0xd5,0x6b,0x25,0xa2,0xc1,0x6f,0x35, +0x7c,0xb5,0x89,0x35,0x74,0xb5,0x7b,0x24,0x9c,0x31,0x10,0xe0,0x65,0x23,0x00,0x00, +0xa0,0x62,0x5f,0x0a,0x79,0x5b,0x9e,0x5c,0x35,0x94,0x86,0x0c,0x65,0x5b,0x66,0x12, +0x71,0xda,0x9d,0xdc,0x56,0x1c,0x89,0x5d,0x72,0x63,0x61,0x1a,0x6a,0x92,0x81,0x59, +0x9c,0x31,0x10,0x7d,0x64,0x23,0x00,0x00,0x5e,0x52,0x99,0x5c,0x71,0xe5,0x81,0xee, +0x85,0x93,0x8f,0x19,0x61,0x4a,0x7e,0x1b,0x85,0xeb,0x6a,0x62,0xa1,0x15,0xd2,0x1c, +0x71,0x93,0x89,0xc3,0xf1,0xc9,0xed,0x8a,0x9c,0x31,0x10,0xf0,0xc8,0x45,0x20,0x00, +0x81,0x75,0x80,0x75,0x7f,0x75,0x7b,0x75,0x7d,0x75,0x7f,0x75,0x7f,0x75,0x87,0x7a, +0x88,0x56,0x67,0xa6,0x6d,0x65,0x3c,0x74,0x7c,0xb1,0xba,0x25,0x82,0xa4,0xc1,0x75, +0x9c,0x31,0x10,0x7b,0xca,0x67,0x40,0x00,0x9e,0xe5,0x5f,0x05,0x2c,0xfa,0x58,0xf5, +0xbe,0xf4,0x58,0xe4,0xa9,0x25,0xa2,0xa6,0xd7,0x46,0x64,0xa5,0x41,0x55,0x0e,0x65, +0x95,0xc4,0x9c,0x25,0x77,0xc5,0xb6,0x46,0x9c,0x31,0x10,0xef,0xca,0x46,0x30,0x00, +0xc9,0x96,0x88,0x75,0x37,0x64,0x16,0x60,0x75,0xa4,0xbc,0x42,0x6b,0x96,0xc2,0x76, +0xbf,0x55,0x9a,0xa4,0x2f,0x38,0x1a,0xb4,0x65,0x55,0xc8,0x96,0x6b,0x36,0xbe,0xc9, +0x9c,0x31,0x10,0xc8,0xc8,0x46,0x30,0x00,0xb9,0x4a,0x9a,0xa9,0x2f,0x09,0x18,0xc2, +0x67,0x8d,0xc8,0x6d,0x73,0x2c,0xba,0xea,0xb8,0xca,0x97,0x4b,0x2c,0x8b,0x16,0xe3, +0x6f,0x4c,0xc8,0x8c,0x77,0x13,0xbb,0x2a,0x9c,0x31,0x10,0x25,0xc9,0x35,0x20,0x00, +0xb6,0x61,0x90,0x92,0x28,0x6b,0x19,0x6b,0x7f,0xaa,0xc6,0x4b,0x7a,0x9c,0xbd,0x6d, +0xb1,0x7b,0x85,0x83,0x21,0x83,0x1f,0x53,0x8f,0xbb,0xbd,0x32,0x80,0xb2,0xbf,0x53, +0x9c,0x31,0x10,0xaa,0xc9,0x34,0x20,0x00,0xa8,0x94,0x75,0x6a,0x17,0x9a,0x29,0x43, +0xaf,0xc6,0xac,0x25,0x8c,0xd3,0xbc,0x33,0xa1,0xb3,0x60,0x54,0x0f,0xaa,0x44,0x4a, +0xc2,0xaa,0x9c,0x3c,0x97,0xc4,0xb6,0x3b,0x9c,0x31,0x10,0xb8,0xc8,0x35,0x20,0x00, +0x97,0xd2,0x49,0x42,0x0c,0x84,0x68,0x94,0xcc,0x63,0x8e,0x72,0xa6,0x9a,0xae,0x4a, +0x87,0xa4,0x2a,0x7c,0x16,0x3c,0x99,0xe4,0xc4,0x0b,0x8a,0xd9,0xad,0x39,0xa2,0x9c, +0x9c,0x31,0x10,0x79,0xc8,0x35,0x10,0x00,0x6b,0x6d,0x15,0x9c,0x36,0x53,0xc7,0xba, +0xa7,0x19,0x95,0xeb,0xab,0x1c,0x97,0xc3,0x49,0x5b,0x0a,0x64,0x70,0xbb,0xd3,0x4a, +0x94,0x93,0xa1,0x7d,0xa4,0x64,0x82,0x92,0x9c,0x31,0x10,0x42,0xc8,0x34,0x00,0x00, +0x23,0x89,0x1c,0x42,0xae,0xca,0xc1,0x14,0x91,0xee,0xa4,0x24,0x9b,0xa8,0x5f,0x69, +0x08,0x6b,0x54,0xa3,0xd6,0x64,0xa2,0x7d,0x9b,0x93,0x9f,0x51,0x8c,0x9a,0x30,0x85, +0x9c,0x31,0x10,0x7f,0xc8,0x44,0x20,0x00,0x11,0x45,0xa2,0xd4,0xcb,0x05,0x96,0xe6, +0x9a,0x26,0x99,0xb5,0x6a,0x54,0x09,0x60,0x4b,0x94,0xd2,0x55,0xac,0x76,0x97,0x86, +0x96,0x55,0x8e,0x94,0x34,0x79,0x0e,0x44,0x9c,0x31,0x10,0xb8,0xc8,0x35,0x20,0x00, +0xa3,0xc1,0xcd,0x14,0x9c,0xe6,0x93,0x25,0x93,0xb3,0x6a,0x6a,0x08,0x5a,0x54,0xb9, +0xd3,0x42,0xb0,0x9c,0x96,0x7e,0x8e,0x64,0x8a,0x9b,0x30,0x6a,0x18,0x73,0xad,0xa2, +0x9c,0x31,0x10,0xb8,0xc8,0x35,0x20,0x00,0xc7,0x32,0xa1,0xd3,0x8d,0x2c,0x8d,0xb4, +0x5f,0x6c,0x0c,0x55,0x6a,0xcc,0xd1,0x2a,0xac,0xb8,0x97,0x59,0x86,0x7c,0x7e,0x9d, +0x23,0x53,0x30,0xab,0xc0,0x64,0xbc,0x6c,0x9c,0x31,0x10,0x34,0xc8,0x36,0x20,0x00, +0xa1,0xa3,0x87,0x43,0x88,0xab,0x4a,0x6b,0x11,0x5a,0x91,0xba,0xcc,0x24,0xa8,0xdd, +0x8e,0x34,0x83,0xa3,0x6f,0x7a,0x15,0x43,0x54,0xd2,0xcb,0x32,0xb7,0xaa,0x9a,0x6c, +0x9c,0x31,0x10,0xa0,0xc8,0x25,0x20,0x00,0x7f,0x6d,0x80,0x9c,0x33,0x5a,0x27,0x95, +0xaf,0x7c,0xc5,0x5a,0xa8,0xa9,0x84,0x42,0x84,0xa3,0x5a,0x73,0x16,0x51,0x78,0xc4, +0xca,0x2e,0xb2,0xcd,0x92,0x42,0x80,0x90,0x9c,0x31,0x10,0xf0,0xc8,0x45,0x20,0x00, +0x74,0x74,0x26,0x51,0x3f,0xa5,0xb9,0x55,0xbe,0x76,0xa2,0x85,0x84,0x55,0x80,0x95, +0x49,0x79,0x1c,0x54,0x8d,0xa4,0xcb,0x35,0xae,0xb6,0x8f,0x46,0x80,0x95,0x6d,0x70, +0x9c,0x31,0x10,0x37,0xc8,0x34,0x20,0x00,0x1f,0x4a,0x4f,0xba,0xc2,0x41,0xba,0x99, +0xa0,0x73,0x7f,0x6d,0x7f,0x96,0x42,0x75,0x22,0x73,0x96,0x98,0xc4,0x40,0xae,0xb9, +0x8c,0x45,0x82,0x9e,0x69,0x75,0x24,0x64,0x9c,0x31,0x10,0x11,0xc7,0x35,0x10,0x00, +0x56,0xc5,0xbb,0x24,0xbb,0xa4,0x9f,0x65,0x85,0x66,0x7c,0x95,0x44,0x79,0x28,0x55, +0x8e,0xc4,0xc2,0x15,0xac,0xe1,0x91,0x26,0x83,0xa5,0x6c,0x61,0x2a,0x51,0x49,0xb5, +0x9c,0x31,0x10,0x59,0xc7,0x45,0x10,0x00,0xb0,0x54,0xb7,0x75,0xa4,0x86,0x88,0x55, +0x85,0xa4,0x55,0x75,0x28,0x45,0x70,0xc5,0xb8,0x15,0xb0,0xd4,0x9a,0x25,0x88,0xa6, +0x7d,0x49,0x42,0xa9,0x33,0x45,0x87,0xb5,0x9c,0x31,0x10,0xbe,0xc8,0x44,0x10,0x00, +0xb2,0x45,0xab,0xb5,0x95,0x45,0x8d,0xa4,0x72,0x55,0x3d,0x91,0x44,0x66,0x91,0x95, +0xad,0x54,0xa8,0x95,0x95,0x56,0x8e,0x95,0x6c,0x54,0x41,0x94,0x48,0x66,0x8e,0x86, +0x9c,0x31,0x10,0x04,0xb6,0x44,0x00,0x00,0xca,0x2c,0xcd,0xad,0xae,0x6e,0xa3,0x8c, +0x5e,0x71,0x15,0x26,0x16,0x8a,0x89,0x6d,0xba,0x2c,0xcb,0xd2,0xb2,0x6d,0xa5,0x4c, +0x6a,0x8a,0x27,0x4e,0x12,0x68,0x6b,0xac,0x9c,0x31,0x10,0x5e,0xb7,0x35,0x00,0x00, +0xa8,0x6c,0xc7,0x8b,0xba,0x6a,0xaf,0x4d,0x82,0x93,0x43,0x32,0x1c,0x94,0x49,0x43, +0x8e,0x81,0xb5,0x6d,0xc0,0x6a,0xb3,0x69,0x98,0xb5,0x60,0xeb,0x33,0x12,0x28,0xe4, +0x9c,0x31,0x10,0x4c,0xb6,0x34,0x00,0x00,0x67,0x08,0x98,0xb3,0xbf,0x24,0xb8,0xc9, +0xae,0xe5,0x88,0xec,0x59,0x0a,0x2e,0x83,0x39,0x62,0x74,0x64,0xa1,0x62,0xbe,0x94, +0xb9,0x8c,0xae,0x6a,0x81,0x2d,0x53,0x00,0x9c,0x31,0x10,0x8e,0xb6,0x43,0x00,0x00, +0x2e,0xaa,0x43,0x4e,0x70,0x8c,0xa1,0x52,0xba,0x6c,0xbd,0x72,0xa6,0xcd,0x7d,0x14, +0x51,0x35,0x32,0x85,0x41,0x6d,0x70,0x70,0xa1,0x69,0xbc,0x31,0xbd,0x4a,0xaa,0xe6, +0x9c,0x31,0x10,0x1c,0xb6,0x54,0x00,0x00,0x85,0x0d,0x55,0x29,0x34,0xb4,0x3b,0x51, +0x68,0x51,0x97,0x6d,0xb6,0x8d,0xbd,0x2d,0xac,0xb0,0x8b,0x29,0x60,0xe5,0x3e,0xd1, +0x36,0xd1,0x5a,0xf1,0x87,0x2d,0xae,0xad,0x9c,0x31,0x10,0x8b,0xb6,0x45,0x00,0x00, +0xbb,0x2d,0xb4,0x61,0x9b,0x0d,0x74,0xa1,0x4e,0xa5,0x38,0xed,0x49,0x45,0x70,0xa9, +0x9d,0x0d,0xb4,0xa5,0xb8,0xcd,0xaa,0x91,0x8c,0xe5,0x65,0x45,0x44,0xea,0x3b,0x2d, +0x9c,0x31,0x10,0xae,0xa6,0x45,0x00,0x00,0x2a,0xe9,0x7c,0xf1,0xca,0xe9,0xea,0x69, +0xec,0xf5,0xc7,0x15,0x87,0x14,0x3f,0x0a,0x08,0x49,0x02,0x8d,0x3f,0x05,0x8d,0x09, +0xd2,0xe9,0xe8,0xf1,0xe0,0xd1,0xba,0xb5,0x9c,0x31,0x10,0x02,0xa6,0x55,0x10,0x00, +0x7a,0x91,0x3a,0xd2,0x0e,0xe9,0x13,0x2c,0x48,0xcd,0x93,0x0d,0xca,0xc9,0xe4,0xf1, +0xdb,0x2e,0xb5,0x31,0x77,0x91,0x3b,0x08,0x10,0xed,0x13,0x0d,0x47,0x55,0x91,0x8d, +0x9c,0x31,0x10,0x67,0xa6,0x66,0x20,0x00,0xcc,0xdb,0xe6,0x9b,0xdf,0x1b,0xb2,0x94, +0x76,0xe2,0x2c,0xab,0x04,0x1b,0x13,0x6a,0x4d,0x14,0xa5,0x13,0xdb,0x1b,0xf4,0x9b, +0xe4,0x9c,0xa2,0xec,0x48,0x99,0x09,0x22,0x9c,0x31,0x10,0xce,0xb6,0x65,0x20,0x00, +0x37,0x06,0x40,0xec,0x6a,0xf2,0xa2,0xe9,0xbf,0x2a,0xc4,0xec,0xb2,0x4e,0x91,0x6d, +0x5e,0xe9,0x34,0xd1,0x23,0x6d,0x48,0xed,0x93,0x0d,0xb9,0x2d,0xc2,0xb1,0xc1,0x55, +0x9c,0x31,0x10,0xb1,0xc9,0x53,0x10,0x00,0x9a,0x6b,0x80,0x82,0x57,0x7b,0x41,0x7a, +0x43,0x72,0x82,0x8a,0xa7,0x72,0x9f,0x73,0x9c,0x94,0xab,0x62,0xa8,0x72,0x76,0x93, +0x45,0x6c,0x36,0x74,0x4f,0x94,0xa5,0x3d,0x9c,0x31,0x10,0x99,0xc9,0x63,0x10,0x00, +0xad,0xb4,0x94,0x73,0x9c,0x5a,0xbb,0x93,0xae,0x83,0x75,0x7b,0x44,0x73,0x33,0x7a, +0x38,0x61,0x99,0x5b,0xad,0xc5,0x8a,0x5d,0x8d,0x6c,0xb7,0xab,0xb7,0x6a,0x82,0x5a, +0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00,0x50,0xed,0x39,0x71,0x22,0x51,0x6f,0xad, +0xb4,0xe5,0x92,0x85,0x7e,0xe9,0xab,0x2d,0xbe,0xed,0x98,0xd1,0x6d,0x0d,0x4a,0xed, +0x2a,0xea,0x32,0xc6,0xa0,0x69,0xa9,0x51,0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00, +0x7f,0x35,0x92,0xd1,0xba,0x6c,0xac,0xc9,0x89,0x49,0x6b,0x2d,0x42,0xed,0x1c,0x95, +0x59,0xb8,0xb6,0x99,0x90,0x91,0x78,0xcd,0xa9,0x69,0xbb,0x0e,0x9c,0x6d,0x86,0x8d, +0x9c,0x31,0x10,0xbf,0xc9,0x74,0x00,0x00,0x67,0x0d,0x37,0xb0,0x20,0x91,0x79,0xad, +0xb1,0x25,0x82,0xe5,0x86,0x85,0xb0,0xcd,0xad,0x35,0x94,0xf5,0x8c,0x91,0x62,0x8d, +0x33,0x49,0x28,0xc5,0x89,0x62,0xa5,0x41,0x9c,0x31,0x10,0x09,0xc9,0x83,0x10,0x00, +0x7e,0x95,0x92,0x57,0xb1,0x58,0xa3,0x69,0x99,0x79,0x8f,0x57,0x60,0x56,0x33,0x95, +0x2f,0x44,0x89,0xb3,0x9e,0xb4,0x7f,0xa6,0x93,0x67,0xab,0x58,0xa1,0x38,0x9e,0x58, +0x9c,0x31,0x10,0x42,0xc9,0x84,0x20,0x00,0x90,0x57,0x60,0x66,0x39,0xb6,0x31,0x56, +0x82,0xc5,0x9f,0xb4,0x81,0xa5,0x92,0x65,0xa8,0x46,0x9f,0x36,0xa0,0x76,0x95,0x96, +0x69,0xa7,0x3e,0xb8,0x2f,0x6a,0x6d,0xdc,0x9c,0x31,0x10,0x42,0xc9,0x84,0x20,0x00, +0xa1,0x8b,0x84,0x7a,0x8c,0x47,0xa1,0x46,0x9e,0x66,0x9f,0xc8,0x9e,0xa9,0x76,0x99, +0x4a,0x69,0x30,0x59,0x53,0x89,0x9d,0x1a,0x8b,0x3a,0x85,0x59,0x9c,0x88,0xa2,0xb7, +0x9c,0x31,0x10,0x42,0xc9,0x84,0x20,0x00,0x9b,0x86,0xa2,0x47,0x83,0x48,0x58,0x47, +0x3c,0x85,0x3c,0x32,0x8a,0x60,0x97,0x90,0x82,0xc2,0x93,0xa5,0xa3,0x77,0x9d,0x49, +0x9e,0x68,0x92,0x77,0x6b,0x96,0x47,0xb7,0x9c,0x31,0x10,0xb6,0xca,0x85,0x10,0x00, +0x32,0xf8,0x67,0x7b,0x9f,0x0b,0x84,0xfa,0x88,0xc9,0x9e,0xd7,0xa1,0x06,0x9a,0xf4, +0x9c,0xc5,0x80,0xe7,0x56,0xd7,0x3b,0x06,0x40,0xb4,0x90,0xb3,0x92,0xe3,0x7f,0x14, +0x9c,0x31,0x10,0xcd,0xc9,0x85,0x20,0x00,0x93,0xa7,0x9f,0x89,0x98,0x7a,0x9c,0xab, +0x96,0x89,0x70,0x98,0x4b,0x98,0x37,0x78,0x5e,0xda,0x9f,0x5b,0x88,0x4b,0x85,0x3a, +0x9a,0x58,0x9c,0x76,0x99,0x64,0xa1,0x63,0x9c,0x31,0x10,0x83,0xc9,0x84,0x10,0x00, +0x86,0x85,0x60,0x76,0x43,0x87,0x39,0x37,0x80,0x95,0x9a,0xa4,0x81,0xc4,0x8f,0x95, +0x9d,0x76,0x97,0x77,0x9c,0x89,0x9b,0x4b,0x7a,0x5b,0x57,0x59,0x3f,0x77,0x46,0x64, +0x9c,0x31,0x10,0x83,0xc9,0x84,0x10,0x00,0x92,0x23,0x91,0x43,0x81,0x74,0x93,0x96, +0x9d,0x98,0x97,0x9a,0x9d,0xab,0x96,0x7b,0x71,0x6a,0x50,0x78,0x39,0x77,0x5a,0xc8, +0x9d,0x49,0x89,0x49,0x83,0x39,0x99,0x58,0x9c,0x31,0x10,0x45,0xc9,0x75,0x20,0x00, +0x9b,0x11,0x92,0xed,0x9d,0x4d,0x8f,0x49,0x6b,0x29,0x4d,0x2d,0x3a,0xb2,0x6b,0xd9, +0x9d,0x38,0x85,0x38,0x86,0xb5,0x98,0x91,0x98,0xcd,0x92,0xa9,0x9c,0xe5,0x89,0x05, +0x9c,0x31,0x10,0xcd,0xc9,0x85,0x20,0x00,0x63,0x86,0x47,0x87,0x3d,0x48,0x7c,0xc8, +0x9a,0xb7,0x84,0xc7,0x8b,0x97,0x9a,0x76,0x97,0x65,0x97,0x65,0x9b,0x46,0x81,0x77, +0x5c,0x77,0x45,0x87,0x44,0x35,0x88,0x53,0x9c,0x31,0x10,0x36,0xb9,0x85,0x20,0x00, +0xae,0x09,0x86,0x89,0x9a,0x8e,0xb2,0x55,0xae,0x1d,0xae,0x21,0xad,0x69,0x75,0xa9, +0x31,0xa5,0x09,0xdd,0x1d,0x55,0xa0,0x51,0xa4,0xd0,0x85,0x55,0x9d,0xd9,0xb2,0x1d, +0x9c,0x31,0x10,0xf0,0xb9,0x74,0x10,0x00,0xaf,0x12,0xb5,0x35,0xa6,0xf4,0x6a,0xf0, +0x2b,0x11,0x07,0x0d,0x33,0x31,0xac,0x79,0x9c,0x7a,0x84,0x59,0xa2,0xb5,0xb6,0xf4, +0xa8,0xf5,0xaf,0x56,0xa1,0x15,0x61,0x11,0x9c,0x31,0x10,0xb9,0xb9,0x84,0x20,0x00, +0x26,0x21,0x05,0xe0,0x47,0x29,0xb5,0xad,0x95,0xad,0x81,0x29,0xa1,0x65,0xb5,0xa0, +0xa9,0x9d,0xad,0xd2,0x95,0xce,0x59,0xd2,0x22,0x15,0x05,0x9d,0x57,0x68,0xb6,0xb0, +0x9c,0x31,0x10,0xb9,0xb9,0x84,0x20,0x00,0x92,0x71,0x81,0xb1,0xa5,0xaa,0xb5,0xa6, +0xa9,0x9e,0xb2,0x19,0x92,0x19,0x56,0x19,0x1e,0x1d,0x01,0x66,0x5e,0xe9,0xb2,0xa8, +0x92,0xe4,0x86,0x61,0xa6,0x1d,0xb9,0xda,0x9c,0x31,0x10,0x29,0xb9,0x64,0x20,0x00, +0xae,0xc5,0xaa,0xc1,0x90,0xe1,0x52,0xe5,0x1b,0x0d,0x06,0xb2,0x6b,0x51,0xb5,0x45, +0x93,0x61,0x87,0x41,0xa5,0x01,0xb9,0x01,0xac,0xe0,0xa8,0xc0,0x8a,0xe5,0x4e,0xc9, +0x9c,0x31,0x10,0x24,0xb8,0x84,0x20,0x00,0x1a,0x1d,0x08,0x5e,0x76,0x1a,0xb2,0x91, +0x93,0x4d,0x82,0xd0,0xa6,0x90,0xba,0x55,0xad,0xd9,0xa5,0x5a,0x85,0xd9,0x49,0x9d, +0x16,0x1c,0x0c,0x94,0x79,0x8d,0xb6,0x0a,0x9c,0x31,0x10,0xe5,0xb8,0x84,0x10,0x00, +0x92,0x8a,0x86,0x8d,0xa6,0x54,0xba,0x58,0xae,0x18,0xa1,0xd9,0x82,0x19,0x49,0xd5, +0x1a,0x55,0x10,0xd5,0x75,0x8d,0xb1,0xc9,0x96,0x4e,0x86,0x52,0xa2,0x15,0xba,0x19, +0x9c,0x31,0x10,0x05,0xb7,0x74,0x10,0x00,0xaf,0x2c,0x9e,0xec,0x85,0x51,0x54,0xf1, +0x21,0x4d,0x0e,0x09,0x6a,0xe6,0xb4,0xe2,0x9f,0x62,0x83,0x25,0x9b,0x04,0xba,0xe8, +0xb3,0x29,0x9c,0xc9,0x81,0x05,0x54,0xe9,0x9c,0x31,0x10,0x8d,0xb7,0x84,0x10,0x00, +0x23,0x19,0x0e,0x5d,0x65,0x55,0xb5,0x0e,0xa5,0x4d,0x85,0x11,0x97,0x14,0xbb,0x1d, +0xb7,0x1c,0x9a,0xd9,0x7f,0x15,0x5a,0xd5,0x2b,0x19,0x10,0x59,0x5b,0x55,0xb3,0x0d, +0x9c,0x31,0x10,0x8f,0xb7,0x73,0x10,0x00,0xae,0xc0,0x87,0xa2,0x8e,0x94,0xb7,0x86, +0xbc,0x87,0x9b,0x75,0x7b,0x84,0x5e,0x64,0x33,0x96,0x13,0x37,0x4f,0xc7,0xae,0xa2, +0xb5,0xb0,0x8b,0x91,0x88,0x84,0xb4,0x86,0x9c,0x31,0x10,0x3b,0xb7,0x73,0x00,0x00, +0xc1,0x96,0x9d,0x76,0x77,0x97,0x5f,0x66,0x3b,0x86,0x18,0x47,0x45,0xb7,0xa5,0x95, +0xbb,0xa2,0x92,0x93,0x80,0x85,0xa8,0x87,0xc4,0x87,0xa7,0x74,0x77,0x83,0x58,0x65, +0x9c,0x31,0x10,0x8f,0xb7,0x73,0x10,0x00,0x3b,0x88,0x1e,0x58,0x44,0xb7,0x9f,0x83, +0xbd,0xa0,0x99,0x82,0x83,0x75,0xa3,0x77,0xc0,0x86,0xa9,0x65,0x7a,0x75,0x59,0x66, +0x3e,0x87,0x23,0x57,0x41,0xb8,0x97,0x85,0x9c,0x31,0x10,0xa6,0xb6,0x73,0x00,0x00, +0xbd,0xa2,0x9f,0x85,0x81,0x87,0x9a,0x77,0xbb,0x75,0xaa,0x65,0x7b,0x87,0x59,0x67, +0x43,0x96,0x2e,0x57,0x45,0xe8,0x8e,0xa5,0xb5,0xa3,0xa0,0x75,0x84,0x77,0x97,0x77, +0x9c,0x31,0x10,0xa6,0xb6,0x73,0x00,0x00,0xb6,0x75,0xab,0x77,0x7f,0x89,0x5c,0x67, +0x45,0x87,0x33,0x57,0x49,0xc6,0x89,0x93,0xae,0x94,0x9f,0x77,0x87,0x77,0x96,0x76, +0xb0,0x78,0xa3,0x89,0x7c,0x96,0x5b,0x75,0x9c,0x31,0x10,0x1c,0xb5,0x73,0x00,0x00, +0x48,0xe2,0x3a,0x22,0x53,0x55,0x8c,0xcc,0xad,0x18,0xa0,0xe5,0x8a,0x99,0x94,0xd5, +0xa4,0x5d,0x94,0x61,0x72,0xe1,0x56,0xdc,0x4a,0xd9,0x48,0x1a,0x66,0xd9,0x96,0xa1, +0x9c,0x31,0x10,0x94,0xa4,0x53,0x00,0x00,0xd9,0x95,0xc0,0x69,0xa6,0x49,0xae,0x2d, +0xac,0x2e,0x79,0x4d,0x34,0x69,0x0f,0x68,0x1c,0x70,0x59,0x90,0x9d,0x6a,0xc9,0x8d, +0xd7,0x6d,0xd2,0x69,0xbe,0xb1,0x8d,0xa9,0x9c,0x31,0x10,0x6a,0xa2,0x42,0x00,0x00, +0x4a,0x8d,0x17,0xb5,0x10,0x4a,0x38,0x25,0x7a,0xb9,0xb6,0x88,0xd6,0xa1,0xdc,0x7a, +0xcc,0xad,0xa0,0x81,0x5b,0x4d,0x1e,0x75,0x0e,0x29,0x2f,0x6c,0x67,0x94,0xa2,0xce, +0x9c,0x31,0x10,0xf7,0xa3,0x42,0x00,0x00,0xd5,0x46,0xed,0x2e,0xd7,0x8c,0x99,0x89, +0x4f,0x8d,0x22,0x92,0x19,0x68,0x38,0x6d,0x6b,0x48,0xa4,0x8d,0xca,0x56,0xd3,0x8a, +0xc0,0x69,0x98,0x91,0x65,0x49,0x41,0x8e,0x9c,0x31,0x10,0xf7,0xa3,0x42,0x00,0x00, +0x37,0x4c,0x4b,0xb1,0x6e,0x4c,0x91,0x81,0xab,0x75,0xb4,0x88,0xab,0x66,0x94,0x95, +0x75,0x49,0x5e,0xb1,0x54,0x4d,0x5e,0x85,0x72,0x55,0x87,0xac,0x98,0x69,0x9f,0x6d, +0x9c,0x31,0x10,0x20,0x82,0x42,0x00,0x00,0xed,0x15,0xa9,0x1d,0x58,0xa1,0x29,0x15, +0x28,0x5d,0x46,0x98,0x72,0x65,0x98,0x18,0xb4,0x9e,0xb6,0xb5,0xa3,0x0e,0x83,0x5e, +0x62,0xe0,0x55,0x19,0x5d,0x29,0x74,0xdd,0x9c,0x31,0x10,0x39,0x61,0x32,0x00,0x00, +0xbf,0x0c,0xf6,0x63,0xdc,0x5a,0x9f,0x1c,0x6b,0x2c,0x47,0x91,0x4a,0xd4,0x5c,0xdb, +0x7e,0x4a,0x88,0xa2,0x88,0xa4,0x97,0x14,0x88,0xe5,0x7e,0xa1,0x69,0x54,0x67,0x22, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_PAIRING.txt b/config/_default_cfg_src_/res/en/SOUND_PAIRING.txt new file mode 100644 index 0000000..c223a0a --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_PAIRING.txt @@ -0,0 +1,195 @@ +0x9c,0x31,0x10,0xd1,0x42,0x22,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x81,0xdb, +0x8d,0xe3,0xa6,0x5b,0xa1,0x9d,0xdd,0x92,0xb6,0x42,0xa1,0xe4,0xa2,0xda,0xa1,0x64, +0xa6,0xd9,0x4d,0x5b,0x51,0xe4,0x56,0xd3,0x9c,0x31,0x10,0x20,0xb8,0x77,0x20,0x00, +0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x81,0xdb,0x81,0xdb, +0x92,0x24,0xa9,0x21,0xc6,0xdb,0xb9,0xab,0xaa,0x23,0xb1,0xdc,0xb6,0x1a,0xa5,0xdc, +0x9c,0x31,0x10,0x03,0xa7,0x65,0x00,0x00,0x9f,0x29,0x52,0xec,0x2f,0x2a,0x14,0xe9, +0x0a,0xed,0x0c,0xee,0x12,0xed,0x06,0xe9,0x0f,0x09,0x22,0xed,0x31,0x0d,0x32,0xed, +0x58,0xee,0x5c,0x61,0x4f,0x0a,0x58,0xcd,0x9c,0x31,0x10,0xe2,0x98,0x87,0x20,0x00, +0x43,0x3b,0x3b,0xb4,0x6b,0xb9,0x5b,0xdc,0x5c,0xcd,0x4b,0x48,0x34,0xac,0x2c,0x93, +0x53,0x33,0x74,0x43,0xa9,0x9a,0xe3,0xa3,0xa9,0xc4,0xec,0x44,0xaa,0x20,0x9c,0xce, +0x9c,0x31,0x10,0x6c,0x98,0x99,0x40,0x00,0x61,0xb3,0xa4,0xb2,0x5a,0xe3,0x94,0xd4, +0x72,0x1a,0xae,0xc3,0x81,0xc5,0x9a,0x9b,0xb0,0xb8,0x63,0x4d,0xa2,0xb3,0xa9,0xc2, +0xa2,0x5c,0x6a,0xc3,0xd3,0x3a,0x7a,0xbb,0x9c,0x31,0x10,0x7e,0x99,0x98,0x40,0x00, +0xdb,0xc4,0x93,0xc3,0xcb,0xab,0x8a,0xdc,0xdb,0xd0,0x7b,0x14,0x9b,0xab,0xa4,0x55, +0xad,0xca,0x8a,0xc9,0xa5,0xcd,0x9a,0x93,0x7b,0x88,0xab,0xde,0x74,0x42,0xab,0x28, +0x9c,0x31,0x10,0x56,0x99,0xa8,0x40,0x00,0x54,0xc6,0xbb,0xb5,0x83,0x99,0x9b,0xbb, +0x8b,0xc3,0x85,0xd4,0x8c,0x53,0x7d,0x38,0x7c,0x1a,0x5b,0xb5,0x93,0x21,0x6b,0x45, +0x93,0xcc,0x6b,0x48,0x7d,0x32,0x72,0x2e,0x9c,0x31,0x10,0x45,0x99,0x99,0x50,0x00, +0x64,0xbc,0x8b,0x33,0x5d,0x39,0xa2,0x9c,0x63,0xa3,0xbb,0x43,0x5c,0x42,0x94,0x43, +0xa4,0xc2,0x62,0xbc,0xa5,0xa2,0x63,0x14,0x76,0x3b,0x64,0x64,0x65,0xbb,0x74,0x1a, +0x9c,0x31,0x10,0x49,0x88,0x99,0x40,0x00,0x53,0xbb,0x83,0x3b,0x5b,0x92,0x33,0xb2, +0x6c,0x64,0x4d,0x33,0x7b,0x0c,0x6f,0x51,0x83,0x35,0x3c,0x1b,0x7a,0xc9,0x8b,0xd3, +0x8a,0xac,0xb4,0x55,0xbb,0xe2,0x64,0x8c,0x9c,0x31,0x10,0xed,0x88,0x98,0x30,0x00, +0x5a,0x9a,0xad,0xea,0x83,0xe2,0x3c,0x14,0x86,0x34,0x82,0x42,0x7c,0xba,0x4a,0xc3, +0x99,0xbd,0x64,0x1b,0x7b,0x28,0x93,0xcc,0x64,0x63,0x2a,0xbc,0x9c,0x3d,0x7b,0x39, +0x9c,0x31,0x10,0x8c,0xa8,0x98,0x40,0x00,0x8b,0x22,0x81,0x4a,0x76,0x95,0x5d,0x63, +0x69,0xe4,0x5d,0xda,0x99,0xe3,0x92,0x24,0x96,0x89,0x6e,0xa5,0x39,0xe2,0x59,0xd2, +0x92,0x1c,0xa1,0xe3,0xca,0x19,0x79,0xd4,0x9c,0x31,0x10,0x74,0xb7,0x87,0x30,0x00, +0x51,0x3e,0x52,0x52,0x71,0xa5,0x94,0x3a,0xbd,0xd8,0xb2,0xac,0x62,0x3c,0x49,0xb3, +0x46,0xd3,0x69,0x0b,0xc2,0x32,0xc5,0x35,0x99,0x49,0x4f,0x23,0x35,0xaa,0x39,0x3a, +0x9c,0x31,0x10,0x82,0xb8,0x98,0x30,0x00,0xa1,0xe3,0xd5,0x5b,0xc7,0x53,0x70,0xa4, +0x32,0x62,0x1c,0x9b,0x66,0x9b,0xd9,0xa5,0xd9,0xd9,0xa9,0xd3,0x4a,0x92,0x21,0xdb, +0x21,0x2d,0xb6,0x63,0xdd,0x51,0xcb,0x5c,0x9c,0x31,0x10,0x62,0xc9,0x97,0x30,0x00, +0x7e,0x49,0x55,0x4d,0x3c,0x6e,0x75,0x50,0xbc,0x89,0xa7,0x10,0x9a,0xf2,0x5f,0x29, +0x40,0xce,0x42,0xec,0xaa,0xf5,0xb8,0xaa,0xa9,0x29,0x80,0x4c,0x4d,0x8e,0x30,0x28, +0x9c,0x31,0x10,0x6c,0xca,0x97,0x20,0x00,0x75,0x49,0xbe,0xae,0xab,0x11,0xa6,0xf0, +0x5c,0xce,0x3d,0x10,0x3f,0x12,0xb2,0xe5,0xaa,0xe1,0xb4,0xf1,0x82,0xd5,0x4b,0x4d, +0x2e,0x69,0x7b,0x2a,0xb6,0xb0,0xa9,0x2d,0x9c,0x31,0x10,0xc0,0xca,0x87,0x30,0x00, +0xb0,0xc6,0x64,0xcd,0x3d,0x15,0x3a,0xf2,0xa9,0x0d,0xa4,0xa8,0xb5,0x05,0x96,0xcd, +0x4d,0x0c,0x2e,0x72,0x69,0x31,0xb2,0xb5,0xa1,0x2e,0xbe,0xc9,0x72,0xe9,0x3f,0x52, +0x9c,0x31,0x10,0xea,0xca,0x98,0x20,0x00,0x35,0x51,0x9a,0x2a,0xa1,0x65,0xb2,0x52, +0xa9,0x9c,0x55,0xdb,0x2d,0x9b,0x5a,0x92,0xb1,0x8d,0x96,0x11,0xc1,0xdc,0x81,0xe3, +0x42,0x5b,0x2c,0xdb,0x86,0x6c,0xa5,0x6a,0x9c,0x31,0x10,0xd8,0xca,0x97,0x30,0x00, +0xa5,0x52,0xba,0xa9,0x63,0x09,0x37,0x31,0x45,0x35,0xa6,0xee,0x96,0xcc,0xb9,0x24, +0x9c,0xcd,0x4e,0xed,0x2c,0x6a,0x71,0x45,0xaa,0xad,0x95,0x08,0xc4,0xb2,0x7a,0xf0, +0x9c,0x31,0x10,0xed,0xc9,0x96,0x30,0x00,0x3f,0x2e,0x32,0x2c,0x98,0xd6,0x9a,0x51, +0xa7,0x52,0xb6,0x74,0x63,0x0d,0x35,0x30,0x4b,0x95,0xac,0xd5,0x8e,0xee,0xbd,0x4d, +0x98,0xe9,0x53,0x2d,0x2a,0x29,0x75,0xc6,0x9c,0x31,0x10,0xd8,0xca,0x97,0x30,0x00, +0xa6,0xc9,0x97,0x21,0xbe,0xc9,0x7e,0xed,0x40,0xe9,0x2e,0x44,0x98,0xcd,0x98,0x91, +0xab,0x2d,0xb4,0xb1,0x6a,0xed,0x32,0xf0,0x47,0x35,0xaa,0xd1,0x90,0xf1,0xbb,0x15, +0x9c,0x31,0x10,0x6c,0xca,0x97,0x20,0x00,0x9e,0xcd,0x5b,0x0d,0x2c,0xb5,0x69,0x8c, +0xa8,0xe5,0x93,0x4d,0xbf,0x09,0x89,0x09,0x4f,0x0d,0x2a,0x89,0x8d,0x26,0xa0,0xad, +0x9d,0x2d,0xbc,0xa5,0x74,0xed,0x41,0x0d,0x9c,0x31,0x10,0x57,0xca,0x96,0x30,0x00, +0x32,0xa5,0xa0,0xcc,0x98,0xb1,0xa9,0x2d,0xae,0xad,0x69,0x11,0x34,0xed,0x47,0x56, +0xae,0xb5,0x92,0xcd,0xb2,0xee,0xa0,0xd1,0x5d,0x0d,0x2a,0xf1,0x63,0x94,0xad,0x0d, +0x9c,0x31,0x10,0xdb,0xca,0x95,0x30,0x00,0x91,0x17,0xb6,0xea,0x92,0xd7,0x54,0xf6, +0x28,0x77,0x77,0x63,0xab,0x13,0x95,0x77,0xb9,0x17,0x87,0x16,0x4b,0x07,0x26,0x76, +0x8f,0x24,0xa7,0x06,0x9b,0x67,0xb8,0xe6,0x9c,0x31,0x10,0xe3,0xca,0x96,0x20,0x00, +0x7c,0xed,0x44,0xc9,0x2c,0x44,0x96,0xa5,0xa4,0xcd,0xa1,0x4d,0xb3,0x09,0x79,0x0d, +0x3f,0x0d,0x30,0x8d,0x9a,0xad,0xa2,0xcd,0xa5,0x4d,0xae,0xed,0x75,0x0d,0x38,0xed, +0x9c,0x31,0x10,0xcd,0xc9,0x85,0x20,0x00,0x32,0x46,0xa7,0x0a,0xa1,0x38,0xa6,0xb5, +0xad,0x87,0x76,0xa7,0x35,0x76,0x37,0x59,0xad,0x0c,0xa1,0x48,0xa5,0xc6,0xab,0x98, +0x74,0x88,0x32,0x57,0x38,0x49,0xab,0x1b,0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00, +0xa0,0xf0,0xa3,0xc9,0xaa,0xed,0x76,0xb1,0x36,0xa9,0x30,0xae,0xa6,0x76,0xa5,0x10, +0xa1,0x6c,0xa8,0xcc,0x7c,0xad,0x3c,0xc9,0x2c,0xa6,0x9e,0xd1,0xa8,0xd1,0x9d,0x2d, +0x9c,0x31,0x10,0xbf,0xc9,0x74,0x00,0x00,0xa8,0xcd,0x84,0xcd,0x42,0xe6,0x22,0x21, +0x91,0x28,0xaf,0x51,0x9a,0xf1,0xa8,0x6d,0x8f,0x0d,0x53,0x29,0x1a,0x48,0x77,0x85, +0xb7,0x09,0x9e,0xae,0xa4,0xcd,0x9b,0x2d,0x9c,0x31,0x10,0x23,0xca,0x63,0x10,0x00, +0x66,0x7c,0x20,0x6d,0x51,0xbb,0xb5,0x51,0xa5,0x72,0xa0,0x9b,0xa0,0x7c,0x7c,0x6b, +0x31,0x8c,0x2b,0x7d,0xa1,0x55,0xb1,0x9c,0x9e,0x7a,0xa2,0x62,0x92,0x8a,0x53,0x7a, +0x9c,0x31,0x10,0x2d,0xc9,0x63,0x00,0x00,0x17,0x20,0x72,0xd1,0xb6,0x6b,0xa7,0x4c, +0x9d,0xac,0x9d,0x73,0x78,0x6b,0x28,0xac,0x31,0x7d,0xa4,0x3b,0xb6,0xca,0xa2,0x52, +0x9d,0x7b,0x94,0x9b,0x56,0x5a,0x15,0x59,0x9c,0x31,0x10,0x8a,0xc9,0x52,0x00,0x00, +0x61,0xc1,0xb7,0x3b,0xb5,0xa5,0x9b,0x84,0x9d,0x53,0x88,0x9a,0x38,0x82,0x18,0x4d, +0x83,0x9e,0xbd,0x76,0xb1,0x64,0x97,0xab,0x9d,0x52,0x7c,0x83,0x25,0x95,0x23,0x76, +0x9c,0x31,0x10,0x17,0xc8,0x52,0x00,0x00,0x96,0x64,0xc2,0xba,0xad,0x29,0x96,0xc1, +0x9d,0x52,0x76,0x73,0x21,0xa5,0x29,0x7d,0x99,0x5b,0xc1,0xaa,0xab,0x39,0x95,0xb1, +0x9d,0x5a,0x76,0x83,0x24,0x95,0x26,0x75,0x9c,0x31,0x10,0x7f,0xc7,0x52,0x00,0x00, +0x93,0xb4,0xc1,0x52,0xb1,0x99,0x96,0x69,0x9f,0x92,0x80,0xcb,0x32,0xd5,0x1a,0x96, +0x7c,0xdd,0xbd,0x24,0xbb,0xc3,0x97,0x52,0x9a,0x12,0x8c,0xdb,0x49,0xb3,0x11,0x92, +0x9c,0x31,0x10,0x0f,0xc8,0x42,0x00,0x00,0x54,0xc3,0xb2,0x2d,0xc6,0xbb,0xa3,0x42, +0x98,0x8b,0x9a,0x8c,0x68,0x54,0x1e,0xad,0x25,0x6b,0x93,0x62,0xc4,0xb1,0xb8,0x33, +0x95,0xd5,0x9b,0x2c,0x8c,0xaa,0x44,0x71,0x9c,0x31,0x10,0x8a,0xc9,0x52,0x00,0x00, +0x10,0x59,0x50,0xba,0xb5,0x34,0xca,0xb4,0xa5,0x53,0x97,0x8a,0x9d,0x82,0x79,0x5b, +0x29,0xab,0x12,0x3d,0x79,0xad,0xc2,0x6b,0xc1,0x72,0x97,0x9b,0x99,0x4b,0x9d,0xa3, +0x9c,0x31,0x10,0x17,0xc8,0x52,0x00,0x00,0x66,0x43,0x1f,0xac,0x1b,0x6d,0x8b,0x53, +0xc5,0xca,0xbb,0x0a,0x97,0xdc,0x9b,0x3b,0xa0,0x7b,0x62,0xa3,0x1b,0x55,0x1d,0xa5, +0x8b,0x42,0xc8,0xb1,0xb9,0x4b,0x95,0x94,0x9c,0x31,0x10,0x8a,0xc9,0x52,0x00,0x00, +0x9b,0x7a,0xa2,0x6b,0x67,0x94,0x1f,0x7a,0x16,0x5c,0x7c,0x9d,0xc5,0x72,0xbd,0x61, +0x97,0xa4,0x9b,0x64,0xa9,0x7a,0x7b,0x8b,0x30,0x73,0x0d,0x50,0x5a,0xc2,0xb9,0x4e, +0x9c,0x31,0x10,0x05,0xc9,0x53,0x00,0x00,0xc3,0x7b,0x9b,0xaa,0x93,0x53,0xac,0x85, +0x96,0x9a,0x4a,0x52,0x12,0x96,0x2a,0xa6,0x99,0x29,0xc6,0xa2,0xa9,0x9d,0x91,0x4a, +0xa8,0x82,0xb1,0x93,0x76,0x6a,0x2a,0x69,0x9c,0x31,0x10,0xa7,0xc9,0x64,0x00,0x00, +0x0c,0xa9,0x57,0x65,0xb4,0xf2,0xbc,0x91,0x96,0xe5,0x97,0x30,0xb6,0xf1,0xa2,0xa9, +0x56,0xc9,0x1b,0x4e,0x1a,0xa5,0x7a,0x95,0xbd,0x11,0xaf,0x45,0x93,0x16,0xa2,0xb5, +0x9c,0x31,0x10,0x22,0xc8,0x74,0x00,0x00,0xba,0x4d,0x92,0xcd,0x47,0x0d,0x1b,0xad, +0x27,0x0e,0x86,0x54,0xba,0x68,0xa8,0xc9,0x93,0x32,0xa9,0x49,0xbb,0x0e,0x8d,0x10, +0x48,0xc9,0x21,0x31,0x26,0xae,0x7e,0x58,0x9c,0x31,0x10,0x92,0xc8,0x87,0x10,0x00, +0xb8,0x4d,0xa8,0xad,0x8c,0xcd,0xa2,0xcd,0xbc,0xad,0x94,0xd1,0x50,0xa9,0x2b,0x2d, +0x24,0x24,0x6c,0xaa,0xb0,0x91,0xac,0xc5,0x8e,0xb1,0x9a,0xa9,0xbc,0xcd,0xa4,0xcd, +0x9c,0x31,0x10,0x4b,0xc8,0x97,0x20,0x00,0x64,0xed,0x3a,0xed,0x26,0xad,0x47,0x6c, +0x9c,0xe5,0xb5,0x11,0x94,0xe9,0x88,0xed,0xae,0xed,0xb8,0xd2,0x84,0xf1,0x4e,0xc9, +0x33,0x4d,0x2c,0x88,0x6e,0xd6,0xae,0xd0,0x9c,0x31,0x10,0x3b,0xc7,0x87,0x20,0x00, +0xa8,0xd2,0x87,0x1c,0x95,0x1e,0xb8,0xe4,0xaa,0xdd,0x72,0xd1,0x4a,0xe1,0x35,0x20, +0x39,0x76,0x7c,0xd0,0xae,0xc6,0xa0,0xe8,0x87,0x22,0x9b,0x24,0xb8,0xce,0xa2,0xe8, +0x9c,0x31,0x10,0x23,0xc7,0x97,0x20,0x00,0x6c,0xda,0x49,0x20,0x32,0xdd,0x3b,0xa5, +0x84,0xc5,0xb1,0x25,0x9e,0xe1,0x84,0xdd,0x9b,0x15,0xb8,0xe5,0xa2,0xdd,0x6e,0xd9, +0x4b,0x21,0x37,0x1c,0x3d,0x66,0x7c,0xcc,0x9c,0x31,0x10,0xe1,0xc6,0x88,0x10,0x00, +0xac,0xe3,0xa0,0xeb,0x89,0x13,0x96,0xdb,0xb5,0x63,0xa8,0x9c,0x75,0x22,0x4e,0xdc, +0x37,0x5a,0x37,0x6d,0x72,0x91,0xa8,0x94,0xa6,0xea,0x8a,0xd3,0x8e,0xd3,0xae,0xa3, +0x9c,0x31,0x10,0x4e,0xc7,0x87,0x00,0x00,0xb0,0xa1,0x82,0xd9,0x56,0xdd,0x3d,0x21, +0x30,0x4c,0x5e,0xf6,0x9c,0xd4,0xaa,0xd5,0x90,0xe5,0x8a,0xdd,0xa4,0x99,0xb5,0x1d, +0x96,0xdd,0x64,0xe1,0x46,0xd9,0x34,0xa1,0x9c,0x31,0x10,0xfa,0xc7,0x87,0x10,0x00, +0x47,0x50,0x84,0xe2,0xaa,0xe4,0x9e,0xd2,0x8a,0xe1,0x96,0xe1,0xaf,0x19,0xa4,0x99, +0x7c,0xe5,0x5a,0xd5,0x3f,0x1d,0x32,0xa5,0x5e,0xe4,0x8e,0xca,0x9e,0xf0,0x9e,0xd5, +0x9c,0x31,0x10,0x67,0xc6,0x87,0x10,0x00,0xa4,0xdd,0xa8,0x5d,0xa1,0x21,0x86,0xd1, +0x6a,0xe5,0x54,0xd9,0x3c,0xa2,0x43,0x8c,0x72,0xa2,0x91,0x24,0x9c,0xd2,0xa2,0xe1, +0xad,0x1d,0xaa,0xdd,0x96,0xdc,0x7a,0xda,0x9c,0x31,0x10,0x5b,0xc6,0x77,0x00,0x00, +0x64,0xea,0x4f,0x0c,0x36,0x11,0x51,0x35,0x7e,0x92,0x97,0x14,0xa0,0xeb,0xa6,0xd3, +0xaa,0xdb,0xa3,0x1a,0x8c,0xe4,0x74,0xcb,0x60,0xeb,0x49,0x13,0x38,0xec,0x5a,0xd9, +0x9c,0x31,0x10,0x92,0xb5,0x87,0x00,0x00,0x88,0x2e,0xb2,0xd9,0xc6,0xa5,0xd0,0xc2, +0xd6,0xb3,0xc2,0xbc,0x90,0xba,0x5e,0xb4,0x36,0xc2,0x06,0xb3,0x01,0x43,0x4c,0x1c, +0x94,0xe2,0xbc,0xa3,0xcc,0x4b,0xd6,0xb3,0x9c,0x31,0x10,0xa9,0xb5,0x86,0x10,0x00, +0xd0,0xbc,0xb2,0xb2,0x80,0xcc,0x5a,0xab,0x34,0xc3,0x06,0x44,0x0b,0x21,0x54,0xdd, +0x98,0xa1,0xbe,0xc4,0xce,0xba,0xd4,0xbc,0xcc,0xc2,0xac,0xb5,0x7c,0xc1,0x54,0x34, +0x9c,0x31,0x10,0x95,0xb5,0x76,0x00,0x00,0x2d,0x2a,0x04,0x0b,0x13,0x63,0x5c,0xa2, +0x9d,0x0d,0xc2,0xe1,0xd2,0x94,0xd8,0xe3,0xca,0xd2,0xa6,0xe3,0x78,0xd4,0x52,0xa2, +0x28,0xd4,0x06,0x5a,0x19,0x1d,0x5c,0x99,0x9c,0x31,0x10,0x10,0xb4,0x66,0x00,0x00, +0x9d,0x15,0xc2,0xe1,0xd2,0x95,0xd4,0xd9,0xc9,0x5d,0xa6,0x90,0x7b,0x25,0x50,0x5a, +0x2d,0x64,0x10,0x09,0x1f,0x6e,0x5c,0x88,0x9c,0xe5,0xc7,0x19,0xd4,0xdd,0xd6,0xd9, +0x9c,0x31,0x10,0x38,0xb4,0x56,0x00,0x00,0xc5,0x1d,0xa4,0xe1,0x7d,0x0d,0x56,0xa1, +0x31,0x55,0x12,0x59,0x1b,0xae,0x54,0x89,0x96,0xe5,0xc2,0xd9,0xd3,0x1d,0xd4,0x9a, +0xc5,0x5c,0xa6,0x92,0x7d,0x23,0x54,0x53,0x9c,0x31,0x10,0xb4,0xb4,0x55,0x00,0x00, +0x2f,0x63,0x12,0x13,0x19,0xb4,0x52,0x83,0x92,0xec,0xbe,0xd2,0xd3,0x24,0xd6,0xd2, +0xc4,0xe4,0xa6,0xda,0x80,0xdc,0x5c,0x9a,0x37,0x1c,0x18,0x51,0x1b,0xa5,0x4e,0x90, +0x9c,0x31,0x10,0xb4,0xb4,0x55,0x00,0x00,0x8c,0xde,0xb8,0xd9,0xce,0xdc,0xd4,0xda, +0xc7,0x5d,0xac,0x9a,0x86,0xe4,0x60,0x92,0x39,0x24,0x1a,0x52,0x1b,0xac,0x4c,0xca, +0x86,0xa4,0xb4,0xd2,0xcc,0xe3,0xd4,0xd3,0x9c,0x31,0x10,0xa9,0xb4,0x43,0x00,0x00, +0xc6,0x96,0xad,0x44,0x89,0x76,0x62,0x49,0x3c,0xb1,0x1d,0x45,0x1a,0xd9,0x4a,0x40, +0x86,0x71,0xb4,0x6d,0xcc,0x71,0xd3,0x69,0xc3,0x6d,0xad,0x49,0x8d,0x51,0x6a,0x49, +0x9c,0x31,0x10,0xb4,0xb4,0x55,0x00,0x00,0x43,0x1b,0x22,0xdb,0x1d,0x63,0x46,0x9b, +0x7e,0x9b,0xac,0xdb,0xc6,0x9c,0xd0,0xd0,0xc2,0xeb,0xb0,0x8d,0x92,0xa2,0x6e,0xd3, +0x45,0x1b,0x23,0x1b,0x19,0x63,0x40,0x9b,0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00, +0x79,0x42,0xaa,0x88,0xc7,0x85,0xd2,0x75,0xc8,0x85,0xb4,0x45,0x91,0x59,0x6a,0x64, +0x42,0xb6,0x23,0x95,0x18,0xba,0x42,0x44,0x7c,0x35,0xae,0x75,0xcb,0x75,0xd4,0xa5, +0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00,0xc7,0x85,0xb2,0x45,0x8f,0x45,0x69,0x75, +0x43,0xa6,0x24,0x94,0x17,0x99,0x3f,0x49,0x78,0x35,0xaa,0x95,0xc6,0x55,0xd1,0xb5, +0xc7,0x75,0xb4,0x49,0x92,0x49,0x6c,0x85,0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00, +0x45,0x86,0x25,0xb4,0x16,0x89,0x3c,0x49,0x75,0x25,0xa8,0xa1,0xc5,0x74,0xd1,0xa6, +0xc8,0x65,0xb6,0x55,0x94,0x39,0x6d,0x85,0x46,0x95,0x26,0xb4,0x17,0x4a,0x3b,0x59, +0x9c,0x31,0x10,0xa9,0xb4,0x43,0x00,0x00,0x74,0x2d,0xa7,0x89,0xc4,0x6d,0xcf,0x8d, +0xc5,0x2d,0xb5,0x6d,0x95,0x4d,0x71,0xad,0x4b,0x69,0x2c,0xad,0x1a,0x0d,0x3b,0x76, +0x70,0x0c,0xa1,0xad,0xbf,0x4d,0xcb,0xad,0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00, +0xc3,0x45,0xb3,0x71,0x97,0x59,0x75,0xa5,0x50,0x65,0x30,0xa1,0x1c,0x35,0x37,0x79, +0x6b,0x56,0x9d,0xa4,0xbe,0x65,0xcc,0x95,0xc5,0x34,0xb6,0x92,0x99,0x54,0x76,0xa5, +0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00,0x51,0x54,0x31,0xa6,0x1d,0x21,0x37,0x88, +0x6b,0x4a,0x9d,0xb4,0xbf,0x56,0xcd,0x94,0xc5,0x35,0xb5,0x91,0x98,0x60,0x76,0xb6, +0x52,0x48,0x33,0xa6,0x1f,0x21,0x37,0x88,0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00, +0x6a,0x4a,0x9c,0xa4,0xbd,0x55,0xcb,0x91,0xc4,0x35,0xb4,0x91,0x99,0x54,0x79,0xa6, +0x56,0x55,0x36,0x95,0x22,0x35,0x39,0x88,0x69,0x56,0x9a,0xa4,0xbb,0x61,0xca,0x95, +0x9c,0x31,0x10,0xf3,0xb5,0x32,0x00,0x00,0xc3,0x35,0xb2,0xa2,0x99,0x54,0x7a,0xa6, +0x59,0x55,0x39,0xa5,0x24,0x20,0x38,0x84,0x67,0x56,0x95,0xa4,0xb5,0x56,0xc5,0x94, +0xc1,0x44,0xb3,0x92,0x9a,0x54,0x7b,0xb6,0x9c,0x31,0x10,0x7f,0xb5,0x31,0x00,0x00, +0x5b,0x23,0x3d,0xca,0x29,0x11,0x3a,0xcb,0x67,0x2c,0x94,0xd3,0xb5,0x2a,0xc4,0xca, +0xc0,0x9a,0xb3,0x52,0x99,0x33,0x79,0xd3,0x5a,0xab,0x3f,0xd2,0x2c,0x11,0x3a,0x51, +0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00,0x65,0x55,0x91,0xa5,0xb2,0x55,0xc1,0x91, +0xbf,0x45,0xb2,0xa6,0x9a,0x65,0x7a,0xa5,0x5d,0x59,0x44,0x96,0x32,0x31,0x3d,0xb1, +0x65,0x64,0x90,0xa6,0xb0,0x59,0xbe,0x89,0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00, +0xbd,0x3a,0xb0,0xb4,0x98,0x72,0x7a,0xc1,0x5d,0x55,0x45,0x96,0x34,0x05,0x3f,0xd2, +0x67,0x60,0x93,0xb5,0xb3,0x59,0xbf,0x75,0xbc,0x41,0xac,0x91,0x91,0x71,0x71,0x95, +0x9c,0x31,0x10,0xfa,0xb4,0x21,0x00,0x00,0x56,0xb2,0x44,0x40,0x3a,0x99,0x4b,0x50, +0x72,0xaa,0x9a,0xd1,0xb4,0x2d,0xbd,0x45,0xb8,0x22,0xa5,0x3b,0x87,0xba,0x67,0x44, +0x4f,0x3c,0x41,0x43,0x42,0xaa,0x5e,0x3a,0x9c,0x31,0x10,0x03,0xa3,0x11,0x00,0x00, +0x8e,0xa5,0xd4,0xc0,0xf8,0x46,0xf9,0xb5,0xd8,0xba,0x9e,0xc5,0x5d,0x34,0x25,0xb5, +0x07,0xb1,0x0c,0x11,0x3a,0xc1,0x86,0xc1,0xcc,0x46,0xf2,0xa5,0xf5,0xa5,0xd6,0xa9, +0x9c,0x31,0x10,0xb6,0xa2,0x21,0x00,0x00,0x9a,0xa9,0x57,0xad,0x21,0xce,0x08,0x30, +0x16,0x08,0x4a,0x85,0x91,0x89,0xd1,0xc2,0xf4,0xb1,0xf3,0x52,0xc9,0x30,0x82,0x8d, +0x39,0x90,0x0a,0x56,0x06,0xad,0x2c,0x6c,0x9c,0x31,0x10,0xbb,0xb2,0x11,0x00,0x00, +0x79,0x32,0xa0,0x06,0xbb,0xa5,0xc0,0xd8,0xaa,0xc6,0x83,0xb1,0x5b,0x18,0x42,0xa5, +0x41,0xa1,0x57,0x3a,0x7b,0x49,0xa0,0x92,0xb9,0xa1,0xbc,0x28,0xa7,0x45,0x82,0xc6, +0x9c,0x31,0x10,0x3a,0xa2,0x22,0x00,0x00,0x3f,0x6d,0x15,0x4d,0x15,0x91,0x3a,0x51, +0x77,0x71,0xb3,0x6d,0xd9,0x85,0xdb,0x69,0xba,0x6d,0x84,0x51,0x51,0x8d,0x32,0x6d, +0x32,0x69,0x4e,0x2e,0x7a,0x8d,0xa4,0x28,0x9c,0x31,0x10,0x55,0x92,0x22,0x00,0x00, +0xfd,0x13,0xfd,0x23,0xcd,0x1b,0x80,0x6a,0x3b,0x1b,0x16,0x0a,0x1f,0x1c,0x49,0x25, +0x82,0xda,0xb6,0x91,0xce,0xf4,0xc6,0x51,0xa1,0x22,0x70,0xa4,0x4b,0x1c,0x3c,0xdc, +0x9c,0x31,0x10,0x62,0x83,0x23,0x00,0x00,0x14,0x93,0x52,0xe3,0x98,0xdb,0xcb,0x1b, +0xd6,0xe3,0xba,0x9b,0x8a,0x8b,0x58,0xe3,0x3f,0x1b,0x3e,0xdb,0x56,0xdb,0x7a,0xe3, +0x98,0xdb,0xa8,0xd3,0xa7,0x13,0x95,0x76,0x9c,0x31,0x10,0x31,0x72,0x23,0x00,0x00, +0x74,0x4c,0x4a,0x50,0x38,0xd1,0x48,0x9b,0x67,0x23,0x84,0xdb,0x99,0x24,0x9e,0xdb, +0x96,0xa3,0x86,0xdb,0x75,0x1b,0x63,0x23,0x5e,0xcb,0x6a,0xdb,0x78,0x93,0x83,0x1b, +0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00,0xd5,0x5b,0xda,0x1b,0xea,0x1b,0xe9,0x51, +0xcd,0x5b,0xae,0x15,0x80,0xe1,0x4e,0x0b,0x2a,0x2a,0x30,0xf5,0x59,0xac,0x85,0x90, +0xbe,0xa3,0xcd,0x54,0xd1,0xab,0xb2,0x24,0x9c,0x31,0x10,0xc2,0x51,0x21,0x00,0x00, +0x79,0x4c,0x61,0x32,0x56,0xcb,0x52,0x45,0x59,0xe1,0x82,0xca,0x9c,0xbb,0xbd,0x3c, +0xc7,0x10,0xcf,0x2b,0xb9,0x43,0x98,0x44,0x7c,0xbb,0x5e,0xc4,0x55,0x3d,0x5b,0x3b, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_PAIRING_FAIL.txt b/config/_default_cfg_src_/res/en/SOUND_PAIRING_FAIL.txt new file mode 100644 index 0000000..68cff25 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_PAIRING_FAIL.txt @@ -0,0 +1,285 @@ +0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb, +0x8a,0xa3,0x7e,0x64,0x89,0x95,0x88,0xd2,0x9a,0x65,0x91,0x59,0xa2,0x52,0xa9,0xe3, +0x9a,0x49,0xb2,0x62,0xcd,0xac,0xbe,0x5e,0x9c,0x31,0x10,0x98,0x76,0x34,0x20,0x00, +0x7b,0xad,0x7b,0xad,0x7b,0xad,0x83,0xad,0x8b,0xad,0x83,0xad,0x83,0xad,0x83,0xad, +0x8b,0xad,0x8b,0xa9,0x83,0xad,0x8b,0xb1,0x7b,0xcd,0x84,0x2d,0x93,0xb2,0xed,0xd6, +0x9c,0x31,0x10,0xaf,0xb8,0x76,0x20,0x00,0x8d,0x63,0xbf,0x29,0xa6,0x24,0xb2,0x99, +0xc6,0x32,0xae,0xed,0xaa,0xa3,0xaa,0xa3,0x8a,0x1b,0x6a,0x54,0x5a,0x11,0x4e,0x14, +0x4a,0x0c,0x2d,0x92,0x2d,0xd3,0x31,0x94,0x9c,0x31,0x10,0x5e,0xb7,0x98,0x20,0x00, +0x31,0xba,0x41,0x43,0x41,0xc4,0x4d,0xc3,0x5e,0xb3,0x6a,0x33,0x76,0x3b,0x82,0xa2, +0x8c,0xab,0x8a,0x54,0x86,0xc9,0x8e,0x44,0x84,0x9d,0x82,0x39,0x84,0x3b,0x85,0xbb, +0x9c,0x31,0x10,0x8b,0x97,0x98,0x40,0x00,0x99,0x98,0xc5,0x99,0xb9,0x84,0xcd,0x56, +0xeb,0x5a,0xb5,0x95,0xd1,0x78,0xcb,0x69,0xbd,0xb6,0xb2,0x65,0xb5,0x4b,0x99,0x85, +0xab,0x91,0xaa,0x68,0x9b,0x5c,0x8b,0xa9,0x9c,0x31,0x10,0xe3,0x98,0x98,0x40,0x00, +0x8c,0x32,0x64,0xc3,0x9b,0x48,0x5d,0x3d,0xa4,0xc5,0x5c,0x2a,0x8a,0x9a,0x6b,0x53, +0x5c,0x62,0x8d,0x35,0x93,0x1a,0x93,0x33,0xc1,0xda,0x84,0xb3,0x7a,0x2a,0x43,0x2b, +0x9c,0x31,0x10,0xa9,0xb8,0x98,0x40,0x00,0x6d,0x5c,0x65,0xec,0x7e,0x63,0x90,0xd3, +0x95,0xd3,0x9d,0x9a,0x7a,0x1b,0x5d,0x9c,0x45,0xa3,0x4d,0xe3,0x7a,0xd2,0xa5,0x55, +0xc2,0x1b,0xc1,0x5a,0x99,0xdb,0x59,0xd3,0x9c,0x31,0x10,0xea,0xb7,0x98,0x30,0x00, +0x41,0xbc,0x2a,0xc4,0x5d,0x22,0x9a,0x39,0xd5,0xcc,0xd6,0xbc,0xc6,0x1b,0x6d,0xc3, +0x3a,0xd4,0x19,0x1a,0x1a,0xb2,0x6e,0x63,0xc2,0xc5,0xe1,0x23,0xdd,0xb1,0xa4,0x3b, +0x9c,0x31,0x10,0xa9,0xb8,0x98,0x40,0x00,0x4a,0x1e,0x1d,0xa3,0x05,0xdb,0x39,0x51, +0xa6,0x12,0xdd,0x59,0xed,0x9e,0xda,0xdc,0x75,0xac,0x26,0x19,0x09,0x4b,0x05,0x9c, +0x6a,0x23,0xcd,0x12,0xee,0x99,0xe9,0xad,0x9c,0x31,0x10,0x11,0xc7,0x98,0x30,0x00, +0x99,0x1e,0x5e,0xc2,0x47,0x5a,0x3c,0x2c,0x53,0x1b,0x96,0x94,0xae,0xe2,0xbe,0xa2, +0xb4,0xd4,0x80,0x13,0x51,0x2a,0x39,0x24,0x38,0xcb,0x75,0x12,0xa8,0x9c,0xac,0xe3, +0x9c,0x31,0x10,0x4a,0xc8,0x88,0x40,0x00,0xbf,0x1a,0xbb,0x0b,0x70,0x93,0x4b,0x34, +0x36,0x9a,0x3e,0xdc,0x88,0xe1,0xa2,0xdd,0xa9,0x23,0xbc,0xe2,0xb6,0xd2,0x64,0x4c, +0x45,0x9a,0x2a,0x33,0x4f,0x9b,0x98,0x44,0x9c,0x31,0x10,0x7a,0xc9,0x87,0x30,0x00, +0x99,0x11,0xb0,0xd5,0xba,0xf5,0xaf,0x11,0x5e,0xa8,0x45,0x49,0x24,0x89,0x5f,0x49, +0x9e,0xb1,0x97,0x2c,0xb0,0xed,0xb8,0xf2,0xab,0x11,0x60,0xa9,0x3f,0x84,0x28,0x25, +0x9c,0x31,0x10,0xe4,0xc9,0x98,0x30,0x00,0x69,0x2b,0x9c,0xa3,0x91,0x23,0xb2,0xd3, +0xb4,0xdb,0xa7,0x1b,0x60,0x9a,0x3b,0x5b,0x2c,0x53,0x75,0x24,0x98,0x9b,0x93,0x1b, +0xb4,0xda,0xaa,0x9b,0xa7,0x1c,0x64,0x59,0x9c,0x31,0x10,0x48,0xc9,0x88,0x20,0x00, +0x39,0x54,0x32,0x52,0x79,0x2b,0x94,0x9c,0x97,0x1a,0xb2,0xd4,0xae,0xe3,0x9e,0xd2, +0x5e,0x92,0x35,0x13,0x34,0x9c,0x86,0xea,0x90,0xa5,0x9b,0x20,0xb4,0x9d,0xaa,0xd2, +0x9c,0x31,0x10,0x53,0xc8,0x87,0x20,0x00,0x9b,0x2d,0x58,0x29,0x2d,0x49,0x3d,0x6e, +0x96,0xb0,0x88,0xd0,0xa2,0xca,0xb2,0x95,0xa4,0xc5,0x92,0xf1,0x4e,0x29,0x2c,0xed, +0x47,0xd2,0x9e,0xcd,0x87,0x15,0xa5,0x0e,0x9c,0x31,0x10,0x50,0xc9,0x98,0x20,0x00, +0xb4,0xda,0xa2,0xdc,0x8c,0xd9,0x4a,0xdc,0x28,0xa3,0x59,0x6a,0xa0,0x9c,0x85,0x2b, +0xab,0x1b,0xae,0xda,0x9e,0xdc,0x87,0x1b,0x42,0xd3,0x2a,0x5c,0x69,0x91,0x9c,0xd4, +0x9c,0x31,0x10,0x0f,0xc9,0x87,0x10,0x00,0x89,0x48,0xb1,0x02,0xad,0x09,0xa0,0xe9, +0x7d,0x0d,0x3b,0x2c,0x2a,0x29,0x79,0x85,0x98,0xc9,0x8b,0x6d,0xb2,0xe9,0xab,0x0d, +0x9c,0xed,0x76,0xe9,0x39,0x71,0x2c,0x09,0x9c,0x31,0x10,0x80,0xc9,0x86,0x10,0x00, +0x83,0x22,0x96,0x71,0x8d,0x2d,0xb4,0xa1,0xaa,0xf6,0x96,0xcc,0x6a,0xaa,0x33,0x96, +0x2e,0x68,0x8e,0xe5,0x92,0x71,0x95,0x0e,0xb6,0xa9,0xa8,0xed,0x94,0xe9,0x60,0x89, +0x9c,0x31,0x10,0xcd,0xc9,0x85,0x20,0x00,0x2e,0xb5,0x38,0x51,0x96,0x58,0x94,0x4a, +0x96,0x84,0xb6,0x75,0xab,0x88,0x8e,0x95,0x5a,0x56,0x2e,0xa8,0x3d,0x88,0x9c,0x5b, +0x94,0x37,0x99,0x57,0xb4,0x58,0xab,0x74,0x9c,0x31,0x10,0x41,0xc9,0x86,0x20,0x00, +0x89,0x09,0x50,0xad,0x2b,0x48,0x49,0x8d,0x9e,0xb5,0x94,0xb1,0x9e,0x89,0xb2,0xad, +0xaa,0xf1,0x85,0x29,0x48,0xa9,0x28,0xcd,0x4f,0xb1,0x9c,0xf1,0x94,0xcd,0x9e,0x8d, +0x9c,0x31,0x10,0x13,0xc9,0x64,0x10,0x00,0xb2,0xd0,0xac,0xe6,0x7f,0x29,0x42,0xd5, +0x28,0xb1,0x53,0xd8,0xa0,0xd5,0x98,0xcd,0x9e,0x8e,0xb2,0xed,0xac,0xf1,0x7b,0x15, +0x3d,0x11,0x22,0x52,0x61,0xa8,0xa5,0x05,0x9c,0x31,0x10,0xa7,0xc9,0x64,0x00,0x00, +0x9c,0xec,0x9e,0xb5,0xb1,0x0d,0xac,0xed,0x74,0xed,0x37,0x2c,0x22,0x4e,0x67,0xa5, +0xa7,0x21,0x9e,0xad,0x9e,0xb0,0xb1,0x31,0xad,0x11,0x70,0xcd,0x33,0x05,0x24,0x44, +0x9c,0x31,0x10,0x2d,0xc9,0x63,0x00,0x00,0x6e,0xb8,0xaa,0x9a,0xa2,0x65,0x9e,0x65, +0xae,0xa5,0xaa,0x72,0x6d,0x59,0x2c,0xa9,0x22,0x2a,0x79,0xa3,0xb0,0xa4,0xa4,0x54, +0x9b,0x73,0xac,0xa3,0xa7,0x62,0x67,0x6a,0x9c,0x31,0x10,0x92,0xc9,0x42,0x00,0x00, +0x2a,0xbc,0x29,0x1e,0x83,0xa6,0xaf,0x9e,0xa7,0x4c,0x9a,0x92,0xaa,0x92,0xa2,0x51, +0x61,0x8b,0x29,0xad,0x30,0x33,0x88,0x93,0xac,0x93,0xa5,0x4a,0x99,0x9a,0xa7,0x79, +0x9c,0x31,0x10,0x7f,0xc7,0x52,0x00,0x00,0x9b,0x12,0x5c,0x5c,0x2f,0x66,0x3d,0x8d, +0x8a,0x24,0xa9,0xf2,0xa5,0x82,0x9a,0xd2,0xa6,0xbb,0x96,0x2c,0x5a,0xc5,0x2f,0xd4, +0x44,0x3c,0x8d,0x1a,0xad,0x6a,0xa6,0x1a,0x9c,0x31,0x10,0x17,0xc8,0x52,0x00,0x00, +0x9c,0x82,0xa7,0x7c,0x92,0x75,0x53,0x7d,0x2b,0x6b,0x4b,0xd1,0x95,0x19,0xae,0xb3, +0x9e,0x85,0x98,0x4c,0xa6,0x9c,0x88,0x7a,0x46,0x71,0x26,0x38,0x5c,0xe2,0xa5,0x3c, +0x9c,0x31,0x10,0x8a,0xc9,0x52,0x00,0x00,0xb3,0x74,0x9f,0x9b,0x9d,0x7b,0xa5,0x6a, +0x75,0x7b,0x2e,0x9b,0x21,0x43,0x77,0x7d,0xb5,0xa4,0xb1,0x62,0x9b,0x61,0xa6,0xa0, +0xa3,0x82,0x5c,0x5d,0x17,0x85,0x2d,0xc5,0x9c,0x31,0x10,0x8e,0xc8,0x64,0x10,0x00, +0x94,0x2d,0xbc,0x4d,0xa9,0x71,0x9d,0x4d,0xae,0x8d,0x8e,0x6d,0x37,0x49,0x08,0x45, +0x57,0xa6,0xb7,0x6d,0xba,0xf1,0x9c,0x70,0xa6,0xcd,0xb3,0x4d,0x6d,0x0d,0x11,0x4e, +0x9c,0x31,0x10,0x96,0xc8,0x74,0x10,0x00,0x12,0xb1,0x8a,0x30,0xc4,0x8c,0xab,0x49, +0x9d,0x29,0xb6,0xea,0xa0,0xae,0x3e,0xd2,0x00,0x69,0x41,0xa4,0xb3,0x49,0xbb,0x71, +0x9d,0x10,0xa8,0xf2,0xb8,0xd6,0x74,0x91,0x9c,0x31,0x10,0x54,0xc8,0x76,0x20,0x00, +0x17,0x51,0x0a,0x71,0x7c,0x75,0xc0,0x51,0xaa,0x89,0xa0,0x6d,0xb8,0x85,0xa2,0xc9, +0x40,0xe9,0x00,0x85,0x3d,0x84,0xad,0x41,0xb9,0x69,0xa1,0x69,0xb1,0x6e,0xbb,0x71, +0x9c,0x31,0x10,0x54,0xc8,0x76,0x20,0x00,0x73,0x29,0x15,0xb5,0x0d,0x0c,0x7d,0x19, +0xbc,0xb5,0xac,0xf1,0xa6,0xd5,0xbc,0xce,0x9e,0xd5,0x3c,0xed,0x00,0x52,0x41,0x20, +0xac,0xc9,0xbb,0x0c,0xa6,0xc9,0xb4,0xe4,0x9c,0x31,0x10,0x68,0xc8,0x86,0x30,0x00, +0xb3,0x0a,0x66,0xec,0x0f,0x2d,0x17,0x31,0x89,0x0c,0xbc,0xee,0xaf,0x11,0xb1,0x31, +0xbb,0x0c,0x88,0xed,0x2f,0x28,0x08,0x65,0x56,0xed,0xa8,0x91,0xb4,0xf1,0xb8,0xd1, +0x9c,0x31,0x10,0x8f,0xc7,0x87,0x30,0x00,0xc0,0xa6,0xa2,0xe8,0x4f,0x25,0x04,0x5d, +0x29,0x8d,0x90,0x90,0xb7,0x12,0xbc,0x95,0xc4,0x94,0xb2,0xda,0x68,0xdd,0x10,0xe0, +0x0d,0xa6,0x71,0x1d,0xb3,0x18,0xc4,0xd5,0x9c,0x31,0x10,0x96,0xd7,0x77,0x20,0x00, +0xa3,0x0c,0x9d,0x0c,0x7c,0x92,0x4f,0x13,0x3e,0xb4,0x6b,0x2a,0x94,0xaa,0xa3,0x2c, +0xa7,0x63,0x9f,0x0b,0x84,0xcb,0x57,0x4b,0x3a,0x51,0x5c,0xe3,0x8e,0xa5,0xa4,0xeb, +0x9c,0x31,0x10,0x96,0xd7,0x77,0x20,0x00,0xa9,0x2b,0xa0,0xeb,0x88,0xdb,0x5f,0x52, +0x3a,0x4b,0x55,0x14,0x88,0x9b,0xa4,0xda,0xaa,0xeb,0xa2,0xa3,0x8c,0xda,0x63,0x1b, +0x3c,0x4b,0x4e,0xcd,0x82,0x5b,0xa2,0xe2,0x9c,0x31,0x10,0x96,0xd7,0x77,0x20,0x00, +0xac,0xeb,0xa4,0xaa,0x8e,0xe3,0x67,0x1b,0x3e,0x44,0x4a,0xcd,0x7e,0x9a,0xa2,0xd9, +0xae,0xec,0xa6,0xab,0x8e,0xe2,0x65,0x1a,0x3e,0x4b,0x48,0xcc,0x7c,0x93,0xa2,0xda, +0x9c,0x31,0x10,0x60,0xc6,0x76,0x10,0x00,0xe1,0x2c,0xd0,0xa4,0x9e,0xe1,0x4b,0x5a, +0x00,0x13,0x17,0x56,0x78,0x53,0xc9,0x19,0xe5,0x23,0xce,0x9d,0x96,0xd9,0x45,0x5b, +0x02,0x12,0x1f,0x1b,0x7e,0x24,0xca,0xe3,0x9c,0x31,0x10,0x78,0xc6,0x66,0x10,0x00, +0xe5,0x23,0xca,0xdc,0x8e,0xdb,0x3d,0x5b,0x04,0x9c,0x2a,0xe1,0x82,0x63,0xcc,0xac, +0xe2,0x9a,0xc5,0x1b,0x84,0x9b,0x37,0x5a,0x11,0x6d,0x3b,0x22,0x8a,0xe2,0xcd,0x1c, +0x9c,0x31,0x10,0x68,0xc6,0x55,0x00,0x00,0xde,0x68,0xb9,0xa9,0x7a,0x89,0x36,0x98, +0x1b,0xe9,0x45,0xb6,0x8e,0xa8,0xcc,0xba,0xd6,0x78,0xaf,0xb9,0x75,0x99,0x3b,0x79, +0x25,0xc5,0x4c,0xb5,0x90,0xa9,0xc9,0xd4,0x9c,0x31,0x10,0xff,0xc6,0x44,0x00,0x00, +0xd0,0x76,0xaa,0xb8,0x75,0x95,0x3e,0x69,0x2b,0x91,0x50,0x98,0x93,0x81,0xc8,0xa5, +0xca,0x59,0xa8,0x89,0x70,0x79,0x3a,0x61,0x2d,0x56,0x56,0x61,0x99,0x61,0xc8,0x61, +0x9c,0x31,0x10,0x40,0xc5,0x42,0x00,0x00,0xc8,0x62,0xa5,0x69,0x69,0x89,0x35,0x80, +0x2f,0x45,0x5d,0x64,0xa1,0xc9,0xcc,0x4a,0xc7,0x91,0x9d,0x2a,0x5f,0x48,0x31,0x6d, +0x34,0x6c,0x68,0x6a,0xab,0xad,0xcd,0x6d,0x9c,0x31,0x10,0xcf,0xc5,0x43,0x00,0x00, +0xc1,0xa6,0x92,0x89,0x54,0x90,0x30,0x6d,0x3e,0x4d,0x76,0x6d,0xb3,0x31,0xca,0x72, +0xb6,0x51,0x82,0x29,0x4b,0x8d,0x33,0x4d,0x4c,0x6d,0x87,0x6a,0xb9,0x8c,0xc5,0x6e, +0x9c,0x31,0x10,0x1a,0xc4,0x33,0x00,0x00,0xa9,0x59,0x74,0x25,0x46,0x31,0x3b,0x95, +0x5a,0x81,0x8f,0xb0,0xb8,0xb6,0xbd,0xc0,0x9d,0xc1,0x6e,0x65,0x4c,0xb9,0x49,0xa6, +0x64,0xa0,0x8e,0xa5,0xae,0xb6,0xb0,0x39,0x9c,0x31,0x10,0x23,0xb4,0x44,0x00,0x00, +0xaa,0x9b,0x60,0x8b,0x2e,0xd3,0x31,0x13,0x5c,0xeb,0x95,0x1a,0xbf,0x2b,0xc1,0x54, +0x9b,0x24,0x68,0xda,0x4a,0xa4,0x4e,0x5a,0x6c,0xdb,0x90,0xdb,0xaa,0x26,0xaa,0x62, +0x9c,0x31,0x10,0xaa,0xa4,0x54,0x10,0x00,0xa6,0x90,0x6d,0x15,0x4d,0x1c,0x4c,0xe1, +0x67,0x5e,0x84,0xcc,0x94,0xd9,0x92,0x54,0x7a,0x5b,0x63,0x10,0x52,0xe4,0x56,0x9c, +0x67,0xaa,0x7c,0x58,0x9b,0x66,0xc3,0xb4,0x9c,0x31,0x10,0x90,0xa5,0x65,0x10,0x00, +0xd7,0x19,0xcc,0xdd,0xaa,0x61,0x80,0x5c,0x4d,0x22,0x28,0x9d,0x28,0xde,0x4a,0x91, +0x72,0x50,0x8c,0xe1,0x92,0x65,0x89,0x35,0x77,0x1d,0x72,0xa0,0x7e,0xe5,0x91,0x61, +0x9c,0x31,0x10,0x84,0x96,0x65,0x20,0x00,0xb9,0x68,0xbd,0x29,0xa1,0x99,0x69,0xcd, +0x35,0x9d,0x29,0xd2,0x4e,0x15,0x7a,0x18,0x9d,0xe6,0xaa,0x55,0xa2,0x09,0x95,0xea, +0x9a,0x1d,0x8e,0x70,0x71,0x29,0x64,0x9c,0x9c,0x31,0x10,0xda,0x85,0x65,0x10,0x00, +0x45,0x35,0x2d,0xe3,0x0d,0xb8,0x41,0x2d,0xa9,0x2c,0xde,0x2b,0xd8,0xac,0xbe,0xe3, +0x8d,0xd2,0x55,0x6c,0x32,0x6b,0x35,0x94,0x45,0xb8,0x76,0x5c,0xb2,0x34,0xca,0xc1, +0x9c,0x31,0x10,0x1a,0x76,0x65,0x00,0x00,0xcc,0xcb,0x7c,0x55,0x3c,0x31,0x2a,0xc5, +0x31,0xe3,0x63,0xb2,0x93,0x64,0xaa,0x42,0xa2,0xcc,0x7c,0xdb,0x5a,0xa3,0x5a,0xb2, +0x5c,0xcd,0x7c,0xd2,0x92,0xa3,0x99,0x84,0x9c,0x31,0x10,0x68,0x56,0x66,0x10,0x00, +0xe8,0x74,0xc6,0x48,0x99,0x5c,0x4a,0x65,0x6c,0x87,0x6a,0x77,0xa7,0x42,0xb9,0x39, +0x9a,0x87,0x89,0xd9,0xab,0xb5,0xac,0xaa,0x99,0xa4,0xa8,0x39,0xc8,0xa8,0xc9,0xe6, +0x9c,0x31,0x10,0xd2,0x55,0x66,0x10,0x00,0xca,0xc6,0xc2,0x77,0xb9,0x78,0xc4,0x93, +0x94,0xda,0xb4,0x78,0x94,0x64,0xbb,0x78,0x89,0x68,0xd9,0x29,0x92,0x96,0xc4,0x87, +0x9c,0xb5,0x86,0x99,0x84,0xd9,0x94,0x67,0x9c,0x31,0x10,0xc1,0x46,0x65,0x10,0x00, +0xb3,0x41,0xe0,0xc8,0xf2,0xb6,0x8b,0x5b,0xb2,0xb2,0x54,0x4c,0x7c,0x4a,0x63,0x32, +0xd4,0x55,0x7b,0xc4,0x9d,0x62,0xae,0x24,0x6c,0x4a,0x0b,0x5a,0x44,0x52,0x63,0xa3, +0x9c,0x31,0x10,0xb1,0x56,0x76,0x20,0x00,0xb7,0x8b,0x96,0x94,0x91,0x87,0x94,0x95, +0x56,0x7a,0x47,0x25,0x68,0x37,0x69,0xb9,0x8b,0xa9,0x7a,0x93,0x89,0x77,0x77,0x87, +0x76,0x96,0x31,0x7b,0x56,0x69,0x29,0x75,0x9c,0x31,0x10,0xa9,0x56,0x66,0x20,0x00, +0x68,0xc6,0x67,0xc5,0x79,0x16,0x48,0x96,0x58,0x68,0x06,0x7b,0x17,0xb7,0x46,0x56, +0x46,0x59,0x54,0x86,0x67,0x53,0x48,0x56,0x39,0x48,0x2a,0x28,0x2c,0xdb,0x6d,0x85, +0x9c,0x31,0x10,0x68,0x56,0x66,0x10,0x00,0x6e,0x55,0x8b,0x59,0x5c,0x88,0x86,0xa5, +0x86,0x68,0x34,0xb8,0x34,0xe8,0x53,0x56,0x43,0x05,0x47,0x55,0x35,0x1c,0x55,0x84, +0x55,0x58,0x47,0xea,0x48,0xc4,0x8b,0x47,0x9c,0x31,0x10,0x68,0x89,0x88,0x30,0x00, +0x7c,0x34,0x7c,0x3a,0x7b,0xc3,0x7c,0x43,0x73,0xbc,0x84,0x33,0x93,0xbc,0xe3,0x8b, +0x64,0xb2,0x63,0xb3,0x74,0x2c,0x8b,0xbb,0x8b,0xb3,0x93,0xc3,0xcb,0x9a,0xe9,0xc5, +0x9c,0x31,0x10,0x56,0x98,0x87,0x30,0x00,0x53,0xd4,0x61,0xb9,0x7b,0x43,0x82,0xb2, +0xad,0xcb,0x6d,0x9e,0x64,0xab,0x6d,0x39,0x74,0xb4,0x6d,0x3a,0x73,0xbb,0x6c,0x3b, +0x82,0x33,0x9a,0x15,0x3c,0x22,0x5a,0x32,0x9c,0x31,0x10,0x10,0x96,0x76,0x20,0x00, +0x5e,0x94,0x7a,0xd1,0x77,0x0c,0x63,0x95,0x4e,0x5a,0x39,0x5b,0x2b,0x1c,0x31,0x22, +0x49,0xdc,0x62,0x1b,0x71,0x19,0x81,0x9d,0x85,0x12,0x85,0x9a,0x8d,0x9d,0x9a,0x1b, +0x9c,0x31,0x10,0x63,0x95,0x55,0x00,0x00,0xac,0x58,0xa9,0x24,0xa8,0x9c,0xa2,0xb1, +0x90,0x64,0x8e,0x5b,0x8c,0xdb,0x90,0x8b,0x9d,0x22,0xaa,0xa5,0xaa,0x82,0xa2,0xca, +0x9d,0x24,0xad,0x14,0xc2,0x51,0xca,0x84,0x9c,0x31,0x10,0x39,0xc8,0x66,0x00,0x00, +0x82,0xca,0x7a,0xe8,0x7a,0xc9,0x7e,0xee,0x8c,0xc5,0x98,0xc8,0x92,0xea,0x76,0xcd, +0x5a,0xf0,0x58,0xcd,0x8c,0xea,0xc2,0xd0,0xb2,0xf0,0x84,0xb6,0x51,0x48,0x2e,0x29, +0x9c,0x31,0x10,0x1d,0xc8,0x86,0x10,0x00,0x61,0x86,0xbc,0xa4,0xc3,0x49,0xaa,0xea, +0x78,0xcc,0x43,0xad,0x1a,0x72,0x7b,0x31,0xbc,0x70,0xa9,0x16,0x9e,0xb5,0x7e,0xd4, +0x37,0x31,0x14,0xf2,0x91,0x15,0xb8,0xb5,0x9c,0x31,0x10,0x53,0xc8,0x87,0x20,0x00, +0x99,0x31,0xa0,0xd1,0x89,0x0d,0x33,0x51,0x19,0x75,0x99,0x12,0xb2,0xcd,0x96,0xec, +0xa6,0xd1,0x89,0x0e,0x2d,0x2c,0x1d,0x11,0xa2,0xce,0xb2,0x90,0x96,0xf1,0xaa,0xd6, +0x9c,0x31,0x10,0x75,0xc7,0x86,0x10,0x00,0x8b,0x25,0x2d,0x60,0x1f,0xa5,0xa6,0xde, +0xb0,0x58,0x94,0xd1,0xae,0x9a,0x8e,0xe1,0x31,0xa4,0x20,0xec,0xa1,0x26,0xae,0x21, +0x91,0x18,0xb2,0x99,0x94,0xe1,0x35,0xa0,0x9c,0x31,0x10,0x0f,0xc9,0x87,0x10,0x00, +0x1c,0xf2,0x9d,0x11,0xae,0xad,0x8f,0x09,0xb4,0xe9,0x9c,0xe9,0x41,0x0d,0x16,0x8d, +0x8a,0xf4,0xb2,0xb1,0x91,0x11,0xb1,0x0d,0xa4,0xe9,0x51,0x09,0x14,0x69,0x75,0x29, +0x9c,0x31,0x10,0x53,0xc8,0x87,0x20,0x00,0xb4,0x71,0x91,0x55,0xac,0xf1,0xae,0xcd, +0x63,0x29,0x18,0x29,0x57,0x85,0xb4,0xa5,0x95,0x0d,0xa2,0xf5,0xb6,0xb9,0x79,0x31, +0x27,0x2d,0x39,0xad,0xa9,0x0a,0x9c,0xe5,0x9c,0x31,0x10,0x53,0xc8,0x87,0x20,0x00, +0x98,0xe5,0xb6,0xe9,0x92,0xf1,0x41,0x75,0x22,0x71,0x89,0x50,0xa8,0x91,0x91,0x6d, +0xb1,0x09,0xa8,0xc9,0x61,0x0d,0x1e,0x2d,0x59,0xa5,0xae,0x84,0x91,0x09,0xa2,0xb1, +0x9c,0x31,0x10,0x1d,0xc8,0x86,0x10,0x00,0xb6,0xd4,0x83,0x15,0x37,0x4e,0x2a,0xca, +0x95,0x28,0x9e,0x8c,0x95,0x52,0xb6,0xed,0xa4,0xe9,0x5c,0xed,0x20,0x0d,0x57,0xa5, +0xa8,0xa8,0x93,0x0e,0xa4,0xad,0xb6,0xad,0x9c,0x31,0x10,0x54,0xc8,0x76,0x20,0x00, +0x8b,0x15,0x3f,0x51,0x22,0x4a,0x7d,0x34,0xa4,0x95,0x93,0x49,0xae,0xd1,0xae,0xd4, +0x74,0xed,0x2f,0x29,0x2f,0x19,0x95,0x11,0x9e,0xac,0x97,0x49,0xb5,0x0e,0xa4,0xe9, +0x9c,0x31,0x10,0xdb,0xc8,0x77,0x20,0x00,0x66,0xe8,0x26,0xf1,0x39,0x99,0x9c,0xea, +0x9a,0xe8,0x9d,0x2d,0xb7,0x09,0xa3,0x05,0x60,0xe0,0x22,0xd2,0x41,0x8d,0xa0,0xe9, +0x98,0xed,0x9d,0x0d,0xb7,0x0d,0xa3,0x05,0x9c,0x31,0x10,0x95,0xc8,0x76,0x10,0x00, +0x62,0xc5,0x27,0x0c,0x35,0x55,0x99,0x2a,0x9e,0xc8,0x99,0x2a,0xb6,0xed,0xa8,0xf4, +0x6e,0xf2,0x35,0x48,0x26,0x92,0x85,0x14,0xa2,0x79,0x97,0x36,0xb0,0xcd,0xae,0xed, +0x9c,0x31,0x10,0x1a,0xc8,0x77,0x10,0x00,0x82,0xcd,0x47,0x11,0x1c,0x04,0x5f,0x4e, +0xac,0x8d,0x97,0x0c,0xa6,0xcd,0xb2,0xed,0x98,0xe9,0x5e,0xe9,0x2b,0x2d,0x33,0x38, +0x9b,0x35,0xa0,0xd5,0x99,0x6d,0xb0,0xe9,0x9c,0x31,0x10,0x41,0xc9,0x86,0x20,0x00, +0xa7,0x0a,0x80,0xc8,0x4c,0xed,0x22,0x8d,0x5b,0x45,0xac,0xe5,0x94,0xe9,0x9c,0xe9, +0xae,0xcd,0xa2,0xf1,0x74,0xd1,0x3f,0x11,0x24,0x68,0x7d,0x0d,0xaa,0x8e,0x8b,0x0d, +0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00,0xa4,0xed,0xae,0xf2,0x96,0xf0,0x6c,0xf1, +0x3d,0x0d,0x28,0x8d,0x8a,0xf4,0xa6,0x92,0x8c,0xf2,0xa8,0xd5,0xaa,0xf5,0x94,0xf1, +0x6e,0xf5,0x3e,0xed,0x24,0x45,0x86,0xb0,0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00, +0xa4,0x72,0x88,0xc9,0xaa,0xc9,0xac,0xcd,0x96,0xd1,0x74,0xad,0x44,0xd1,0x20,0x20, +0x7d,0x02,0xaa,0xa5,0x81,0x24,0xa5,0x05,0xae,0xc5,0x98,0xe9,0x82,0xc9,0x54,0xe9, +0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00,0x20,0xd1,0x5b,0xa8,0xaf,0x0d,0x87,0x52, +0x9b,0x31,0xb2,0xd1,0x9d,0x31,0x8c,0xf1,0x69,0x11,0x31,0x2d,0x2e,0xd2,0x9e,0xb4, +0x96,0x51,0x86,0xaa,0xb2,0xa9,0xa4,0xc5,0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00, +0x96,0xc9,0x84,0xca,0x4f,0x09,0x1c,0xcd,0x5f,0xcc,0xad,0x11,0x81,0x51,0x9f,0x19, +0xb0,0xb5,0x9b,0x19,0x96,0xb1,0x72,0xb1,0x36,0xcd,0x22,0x24,0x89,0x26,0x9e,0xe5, +0x9c,0x31,0x10,0x5e,0xc9,0x67,0x20,0x00,0x81,0x80,0xaf,0x49,0xa6,0xd1,0x9d,0x2d, +0x90,0xd1,0x60,0xf1,0x29,0x0d,0x32,0x69,0x9e,0x8c,0x92,0x81,0x8b,0x22,0xb3,0x49, +0x9f,0x05,0x9d,0x09,0x8a,0xf1,0x54,0xf1,0x9c,0x31,0x10,0xb7,0xc9,0x57,0x10,0x00, +0x27,0x0b,0x40,0xd5,0xa2,0x72,0x8a,0x82,0x8f,0x04,0xb1,0x43,0x9f,0x0b,0x9e,0xe4, +0x8a,0xca,0x54,0xf3,0x29,0x23,0x40,0xad,0x9c,0x8a,0x8e,0xc2,0x8f,0x23,0xb1,0x4c, +0x9c,0x31,0x10,0xd1,0xc9,0x66,0x20,0x00,0x9c,0xf1,0xa0,0xed,0x8c,0xad,0x59,0x0d, +0x31,0x29,0x36,0x65,0x96,0xc8,0x93,0x0e,0x89,0x6a,0xad,0x0c,0xa0,0x90,0x9e,0xf1, +0x96,0xee,0x65,0x0c,0x38,0xcd,0x2c,0x69,0x9c,0x31,0x10,0x5e,0xc9,0x67,0x20,0x00, +0x83,0xaa,0x9d,0x11,0x82,0xf0,0xa2,0x6d,0xa4,0xca,0x99,0x29,0xa1,0x0c,0x78,0xed, +0x46,0xcd,0x2a,0xf1,0x57,0x54,0xa2,0x4e,0x84,0xce,0x97,0x29,0xab,0x2d,0x9a,0xd1, +0x9c,0x31,0x10,0x5e,0xc9,0x67,0x20,0x00,0xa0,0xf1,0x90,0xcd,0x5d,0x0d,0x36,0xf1, +0x2e,0x65,0x87,0x8d,0x9b,0x0e,0x84,0xcd,0xa4,0xac,0xa7,0x2d,0x99,0x09,0x9e,0xad, +0x7c,0xed,0x4c,0xed,0x2d,0x29,0x46,0xb2,0x9c,0x31,0x10,0x38,0xc9,0x56,0x10,0x00, +0xa0,0x6e,0x8b,0x48,0x8f,0x29,0xa8,0x8c,0x9e,0xed,0x99,0x33,0x98,0xa9,0x6e,0xea, +0x43,0x0c,0x2a,0xf5,0x61,0x50,0xa6,0x0a,0x83,0x2e,0x99,0x2d,0xa4,0xa9,0x98,0xd1, +0x9c,0x31,0x10,0x75,0xc9,0x55,0x20,0x00,0x9f,0xa8,0x93,0x56,0x63,0x66,0x41,0x98, +0x2e,0x69,0x72,0xb6,0xa4,0x24,0x84,0x84,0x9b,0x86,0xa6,0x66,0x99,0x69,0x9f,0xb4, +0x8e,0x59,0x62,0x6a,0x41,0x95,0x30,0x59,0x9c,0x31,0x10,0xf9,0xc9,0x56,0x20,0x00, +0x73,0x8b,0xa2,0x49,0x85,0x2b,0x9b,0x0c,0xa4,0xcb,0x9a,0xeb,0x9f,0x2b,0x8e,0x8a, +0x64,0xeb,0x43,0x2c,0x30,0xb4,0x6d,0x6a,0xa4,0x48,0x85,0x4c,0x94,0xed,0xa4,0xcb, +0x9c,0x31,0x10,0x20,0xc9,0x46,0x10,0x00,0x9d,0x11,0x9d,0x12,0x92,0x8d,0x6d,0x2c, +0x46,0xea,0x30,0xd2,0x59,0x32,0xa8,0x6d,0x89,0x6c,0x8e,0xaa,0xa2,0xea,0x9f,0x23, +0x98,0xac,0x9a,0xeb,0x77,0x2a,0x54,0xa3,0x9c,0x31,0x10,0x20,0xc9,0x46,0x10,0x00, +0x3b,0x24,0x3c,0x83,0x9b,0x29,0x96,0xeb,0x86,0xad,0x9b,0x2b,0xa2,0xaa,0x9a,0xea, +0x9d,0x24,0x86,0x8b,0x63,0x0a,0x41,0x0b,0x30,0x8c,0x71,0xad,0xa8,0x12,0x85,0x89, +0x9c,0x31,0x10,0x18,0xc9,0x45,0x00,0x00,0x8d,0x55,0xa6,0x76,0x9c,0x95,0x9b,0x44, +0x9a,0x85,0x77,0x86,0x54,0x55,0x36,0xa0,0x3f,0x36,0xa1,0xa6,0x93,0x64,0x85,0x64, +0x96,0xa6,0xa4,0x36,0x98,0xa5,0x9d,0x75,0x9c,0x31,0x10,0xac,0xc9,0x45,0x10,0x00, +0x91,0x55,0x69,0x95,0x44,0x65,0x31,0x79,0x5d,0x95,0xab,0x34,0x86,0xc5,0x88,0x26, +0x9d,0xb5,0xa0,0x44,0x96,0x85,0x9d,0x85,0x88,0x55,0x5f,0x85,0x3d,0x75,0x34,0x51, +0x9c,0x31,0x10,0xac,0xc9,0x45,0x10,0x00,0x7a,0xc6,0xaa,0x16,0x83,0xd4,0x86,0x24, +0x9f,0xb5,0x9c,0x56,0x96,0x75,0x9b,0x85,0x82,0x65,0x5c,0x85,0x3a,0x86,0x36,0x31, +0x87,0xd4,0xa4,0x16,0x83,0xd6,0x84,0x34,0x9c,0x31,0x10,0xe4,0xc9,0x35,0x10,0x00, +0x9f,0xa9,0x9c,0x63,0x96,0x84,0x98,0x83,0x80,0x72,0x58,0x7b,0x3b,0x8c,0x3b,0x45, +0x92,0xc9,0x9e,0x2a,0x81,0xbd,0x85,0x4c,0xa2,0xa2,0x9a,0x6a,0x96,0x83,0x9c,0x7c, +0x9c,0x31,0x10,0xdf,0xc9,0x34,0x00,0x00,0x81,0x73,0x56,0x7a,0x3c,0x93,0x3a,0x46, +0x8e,0xc0,0xa4,0x29,0x85,0xcd,0x83,0x34,0x9d,0xb2,0x9d,0x51,0x97,0x9c,0x9a,0x6c, +0x84,0x8a,0x5b,0x6a,0x3e,0x9d,0x39,0x44,0x9c,0x31,0x10,0x50,0xc9,0x35,0x00,0x00, +0x83,0xc1,0xa9,0x2b,0x85,0xc5,0x83,0x3b,0x94,0xb2,0xa3,0x4b,0x97,0xa4,0x9d,0x5b, +0x83,0x92,0x64,0x63,0x3e,0x9c,0x3a,0x52,0x78,0xb2,0xb1,0x44,0x84,0xab,0x84,0x52, +0x9c,0x31,0x10,0x5a,0xc8,0x24,0x00,0x00,0x8a,0xba,0xa9,0x4c,0x93,0x9b,0x9f,0x6a, +0x86,0x83,0x6e,0x73,0x41,0x82,0x3c,0x72,0x61,0x8e,0xb2,0x73,0x8a,0x71,0x84,0x94, +0x82,0x55,0xa7,0xb4,0x99,0x3a,0x9c,0xc2,0x9c,0x31,0x10,0x64,0xc8,0x23,0x10,0x00, +0x8c,0x19,0x75,0x5e,0x4e,0x1e,0x39,0xe2,0x53,0x15,0xa9,0x6a,0x9a,0x0d,0x80,0x71, +0x81,0x0d,0x9d,0x6d,0xa5,0x11,0x96,0xe5,0x93,0x19,0x77,0x5d,0x5d,0x1d,0x39,0xe1, +0x9c,0x31,0x10,0x7c,0xc8,0x33,0x10,0x00,0x48,0x91,0x91,0xed,0xaa,0x11,0x81,0x61, +0x82,0xa1,0x8f,0xd1,0xa8,0xb1,0x93,0x41,0x98,0x3d,0x7f,0xb9,0x68,0x41,0x41,0xc1, +0x3c,0xb0,0x76,0x51,0xae,0xad,0x89,0xc5,0x9c,0x31,0x10,0x0c,0xc7,0x23,0x10,0x00, +0x80,0x84,0x85,0x44,0xa5,0xb6,0x9a,0x15,0x95,0xe0,0x87,0x05,0x6e,0xd5,0x50,0x39, +0x3b,0xb5,0x5d,0x46,0xa5,0xb5,0x99,0x21,0x7f,0xc6,0x7f,0x16,0x98,0xd1,0xa4,0x25, +0x9c,0x31,0x10,0x24,0xc7,0x13,0x10,0x00,0x95,0xe5,0x8f,0x9d,0x76,0x55,0x5c,0x25, +0x3d,0x5d,0x4b,0x90,0x93,0xed,0xa4,0x09,0x84,0x6c,0x7e,0x94,0x8b,0xd6,0xa4,0xb1, +0x95,0x3d,0x95,0xc9,0x7f,0x29,0x68,0xcd,0x9c,0x31,0x10,0xb8,0xc7,0x23,0x00,0x00, +0x49,0x76,0x42,0x51,0x74,0xa4,0xa8,0x4a,0x8e,0x85,0x81,0x84,0x80,0x44,0x9c,0xb5, +0x9d,0x29,0x95,0xc5,0x88,0x25,0x6f,0xb9,0x55,0x45,0x3f,0xa9,0x5a,0x42,0x9d,0xb1, +0x9c,0x31,0x10,0xf7,0xb7,0x23,0x10,0x00,0xbd,0x35,0x87,0xc6,0x7b,0x35,0xa0,0xb4, +0xc5,0x45,0xae,0xa5,0xa2,0x54,0x6d,0x85,0x43,0x65,0x0b,0x94,0x14,0x39,0x8a,0xb6, +0xd3,0x35,0x99,0xa5,0x7e,0x66,0x87,0x76,0x9c,0x31,0x10,0xf7,0xb7,0x23,0x10,0x00, +0xc1,0x85,0xbb,0x51,0xa7,0xa5,0x7c,0x45,0x54,0x95,0x20,0x65,0x08,0x70,0x53,0x75, +0xcc,0x81,0xb2,0x54,0x89,0xa5,0x7c,0x35,0xaa,0xb5,0xc6,0x35,0xb1,0xb6,0x89,0x45, +0x9c,0x31,0x10,0xcc,0xb7,0x22,0x00,0x00,0x61,0xa5,0x34,0x46,0x0c,0xaa,0x2c,0x35, +0xa9,0xc4,0xc7,0x26,0x8f,0xc4,0x80,0x38,0x94,0x95,0xc9,0x56,0xba,0x94,0x94,0x65, +0x6a,0x91,0x47,0x59,0x1d,0xa0,0x1a,0x36,0x9c,0x31,0x10,0x6b,0xb7,0x13,0x00,0x00, +0x76,0xc5,0xcd,0x42,0xa0,0x9c,0x88,0x7c,0x85,0x6a,0xbb,0x91,0xc7,0x6b,0xa2,0x84, +0x71,0x79,0x4f,0x73,0x25,0x8d,0x18,0x61,0x50,0x88,0xc1,0x85,0xae,0x5c,0x90,0xa9, +0x9c,0x31,0x10,0x43,0xb7,0x23,0x00,0x00,0x81,0x35,0xa9,0xb6,0xc8,0x45,0xa8,0x94, +0x7d,0x59,0x5a,0x85,0x36,0x64,0x1c,0x99,0x38,0x56,0xa9,0xa5,0xbb,0x35,0x96,0xb5, +0x82,0x35,0x99,0xa5,0xc8,0x55,0xb4,0x95,0x9c,0x31,0x10,0xe4,0xb7,0x12,0x00,0x00, +0x88,0x65,0x61,0x91,0x3f,0x59,0x25,0xa3,0x2f,0x39,0x8d,0xc3,0xbd,0x32,0x9d,0xbc, +0x87,0x4d,0x8c,0x9c,0xc0,0x71,0xb7,0x85,0x8b,0x76,0x64,0x82,0x48,0x60,0x2f,0xa4, +0x9c,0x31,0x10,0xe4,0xb7,0x12,0x00,0x00,0x2e,0x43,0x7d,0xbb,0xb7,0x3b,0xa0,0xb6, +0x8c,0x54,0x88,0x8a,0xbb,0x8b,0xad,0x62,0x86,0x98,0x63,0x63,0x4a,0x8c,0x3b,0x78, +0x3c,0x61,0x85,0xa6,0xb0,0x4b,0xa1,0xaa,0x9c,0x31,0x10,0x5c,0xa6,0x12,0x00,0x00, +0x97,0x36,0x9f,0xa5,0xed,0x71,0xb8,0x6c,0x79,0xa4,0x2d,0x3b,0x14,0xba,0x02,0x43, +0x2b,0x99,0xb4,0x6a,0xd6,0x6c,0xc6,0xa3,0x9c,0x49,0xb7,0xb1,0xbf,0x3d,0x88,0xb1, +0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00,0x61,0x14,0x4d,0xb6,0x4c,0x56,0x5a,0x75, +0x8a,0xa4,0xa8,0x36,0xa7,0xb5,0x9b,0x49,0x97,0x95,0x99,0x76,0x74,0x55,0x4f,0xa4, +0x3d,0x45,0x51,0xb5,0x7c,0x49,0xa4,0xb5,0x9c,0x31,0x10,0x53,0xa4,0x22,0x00,0x00, +0xdc,0x06,0xcc,0xe5,0xbf,0x24,0xae,0xb5,0x76,0x65,0x25,0x65,0x02,0xa5,0x1d,0x35, +0x69,0xb5,0xb7,0x35,0xe3,0xa0,0xe6,0x62,0xc8,0x75,0x92,0x85,0x4a,0x54,0x17,0xa5, +0x9c,0x31,0x10,0x7b,0xa4,0x12,0x00,0x00,0x0e,0x29,0x36,0xc5,0x87,0x35,0xc7,0x95, +0xe7,0x55,0xd5,0x81,0xb6,0x79,0x7b,0x65,0x3b,0x65,0x1a,0x89,0x22,0x51,0x5f,0x99, +0xa3,0x36,0xcb,0xa0,0xd0,0x65,0xbe,0x85,0x9c,0x31,0x10,0xdf,0xa4,0x21,0x00,0x00, +0x99,0xbc,0x61,0x3b,0x33,0xe8,0x2f,0x91,0x4b,0xd3,0x83,0x2d,0xa7,0xcc,0xc1,0xb2, +0xbf,0xca,0xae,0xb2,0x80,0x34,0x4d,0x33,0x36,0x4a,0x42,0xab,0x6f,0x4b,0x99,0xaa, +0x9c,0x31,0x10,0x44,0x93,0x21,0x00,0x00,0xeb,0xa8,0xfb,0x30,0xdb,0x8d,0x8f,0x4e, +0x39,0x6d,0x0d,0x91,0x1b,0x51,0x58,0x94,0x9b,0x4d,0xcc,0x8d,0xe1,0x6e,0xc9,0x51, +0x8f,0x91,0x52,0x25,0x30,0x91,0x36,0x30,0x9c,0x31,0x10,0x61,0x83,0x21,0x00,0x00, +0x3e,0xad,0x9e,0x48,0xdf,0x69,0xf4,0x6a,0xcf,0x6d,0x8b,0x92,0x45,0x49,0x20,0xb1, +0x2b,0x51,0x60,0x89,0x98,0x4c,0xb7,0x71,0xb3,0x6c,0x9a,0x95,0x72,0x6e,0x53,0x6d, +0x9c,0x31,0x10,0x3e,0x73,0x34,0x00,0x00,0x19,0xb8,0x39,0x37,0x76,0xb7,0x9d,0x46, +0xa6,0xc6,0x95,0x98,0x7a,0x17,0x61,0x38,0x51,0xc7,0x55,0x38,0x65,0xb7,0x7d,0xa7, +0x86,0x38,0x75,0xd8,0x71,0x02,0x69,0x8a,0x9c,0x31,0x10,0xec,0x52,0x32,0x00,0x00, +0x32,0x92,0x40,0xec,0x7d,0xa3,0x8a,0x66,0x6a,0x92,0x31,0xd2,0x2d,0x5b,0x62,0xdb, +0x89,0x5c,0x97,0x1b,0x79,0xdc,0x74,0xe3,0x3d,0x5a,0x11,0xdb,0x22,0x54,0x40,0xe3, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_PAIRING_SUCCESS.txt b/config/_default_cfg_src_/res/en/SOUND_PAIRING_SUCCESS.txt new file mode 100644 index 0000000..0cb2f12 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_PAIRING_SUCCESS.txt @@ -0,0 +1,345 @@ +0x9c,0x31,0x10,0x8e,0x32,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x79,0xdb,0x76,0x1b, +0x45,0xac,0x36,0x1a,0x5e,0x5b,0x51,0xe3,0x51,0x22,0x5a,0x9a,0x2e,0x22,0x31,0xa4, +0x5d,0xac,0x84,0x6e,0x21,0xcb,0x21,0xa5,0x9c,0x31,0x10,0x0a,0x54,0x33,0x00,0x00, +0x66,0x1b,0x66,0x23,0x76,0x1a,0x55,0xa3,0x75,0xa5,0x7e,0x2a,0x6e,0x1b,0xa5,0xe3, +0x91,0xe3,0x89,0xe4,0x76,0x5b,0x75,0x14,0x96,0xdb,0x92,0x9a,0x96,0x23,0xed,0x15, +0x9c,0x31,0x10,0x5b,0xb8,0x88,0x00,0x00,0x85,0xdb,0x91,0xdb,0xb0,0xc2,0xe8,0xd5, +0x98,0xf1,0x8c,0xad,0xa0,0xe2,0xa1,0x24,0x71,0x62,0x61,0x9c,0x69,0x62,0x5d,0x9c, +0x51,0xa2,0x4d,0xe4,0x4d,0x9b,0x45,0xe2,0x9c,0x31,0x10,0x27,0xb8,0x86,0x20,0x00, +0x3d,0x6a,0x46,0x21,0x4d,0x99,0x56,0x25,0x59,0xe1,0x65,0xe1,0x66,0x0d,0x75,0xd5, +0x71,0xb6,0x86,0xb0,0x81,0x5e,0x8a,0x0d,0x89,0xa0,0x8f,0x6e,0x88,0xcd,0x8d,0xc0, +0x9c,0x31,0x10,0x88,0x97,0xa8,0x30,0x00,0xb9,0x8c,0xde,0x62,0xc1,0x83,0x84,0x83, +0xad,0x8b,0xa1,0x83,0xc6,0x4b,0x9c,0x9b,0xc2,0x8b,0xd2,0x6b,0x98,0x2b,0xd5,0x83, +0x7b,0x82,0x85,0x95,0xc3,0xa0,0xa5,0x6c,0x9c,0x31,0x10,0x2f,0x97,0x99,0x30,0x00, +0xa3,0x57,0x7a,0xb9,0xa2,0x86,0x5b,0x66,0x94,0x49,0xc4,0x96,0x79,0x75,0x6a,0x8c, +0x5b,0x63,0x7e,0x87,0x8b,0x6b,0x6d,0x75,0x8a,0x73,0x5b,0xaa,0x63,0x47,0x88,0x36, +0x9c,0x31,0x10,0xae,0x87,0x98,0x40,0x00,0x66,0xa6,0x9a,0xae,0xa2,0x52,0x85,0xc7, +0x64,0x88,0x7e,0x58,0x69,0x35,0x76,0x68,0x6a,0xb3,0x46,0x99,0x8a,0x47,0x2d,0xdb, +0xaa,0x94,0x70,0x78,0x7b,0x78,0x62,0x86,0x9c,0x31,0x10,0xed,0x88,0x98,0x30,0x00, +0x7a,0x13,0xc3,0x42,0x5a,0xde,0x7c,0x6a,0x91,0x11,0x7d,0x22,0x5d,0xb6,0x2d,0x62, +0xc4,0xb2,0x54,0x05,0x9e,0x4b,0x9b,0x62,0x64,0xbb,0xa4,0xab,0x45,0x23,0x5a,0xc4, +0x9c,0x31,0x10,0xa7,0xa8,0x98,0x30,0x00,0x8a,0x2c,0x75,0x50,0x8e,0x56,0x71,0x22, +0x59,0xa2,0x64,0xd4,0x65,0x5a,0x8d,0x5b,0x9e,0xdb,0x8d,0xdb,0x6e,0x1a,0x35,0x96, +0x55,0x10,0x6a,0x53,0xc1,0xac,0xea,0x54,0x9c,0x31,0x10,0x36,0xb8,0x98,0x20,0x00, +0xa6,0x1b,0x59,0x63,0x4a,0x9b,0x44,0xe3,0x6a,0x12,0xcd,0xdc,0xd1,0xdc,0xb2,0xdb, +0x51,0x9a,0x32,0x9b,0x1d,0x2d,0x72,0x10,0xed,0x14,0xcd,0xdc,0xb2,0x63,0x4d,0x51, +0x9c,0x31,0x10,0x61,0xc8,0x88,0x30,0x00,0x50,0x93,0x40,0x9e,0x91,0x21,0xb6,0x93, +0xa7,0x0d,0x98,0xa3,0x5d,0x52,0x46,0xa2,0x3d,0x25,0x9a,0xd2,0xb2,0xcc,0xb1,0x29, +0x98,0x9d,0x5d,0x4a,0x3e,0x6a,0x45,0xb4,0x9c,0x31,0x10,0xcf,0xc9,0x98,0x40,0x00, +0xa6,0xcd,0xa6,0xcb,0xb6,0xe9,0x9c,0xa4,0x57,0x13,0x38,0x59,0x49,0x6d,0xaa,0x93, +0x9f,0x1b,0xb8,0xe3,0x98,0x9b,0x55,0x0b,0x36,0x23,0x51,0x50,0xa6,0x95,0x9d,0x23, +0x9c,0x31,0x10,0x50,0xc9,0x98,0x20,0x00,0xba,0xeb,0x9a,0xdc,0x52,0xca,0x34,0x14, +0x55,0x51,0xa8,0xa5,0x98,0xdb,0xbe,0xab,0x98,0xe3,0x50,0xcb,0x32,0x0c,0x59,0x52, +0xac,0x63,0x94,0xdb,0xc0,0xa3,0x96,0xeb,0x9c,0x31,0x10,0x62,0xc9,0x97,0x30,0x00, +0x52,0xe9,0x30,0x46,0x61,0xa5,0xaa,0x80,0x94,0xea,0xc0,0x68,0x98,0xf1,0x52,0xd1, +0x2c,0x6a,0x63,0x68,0xa6,0x89,0x95,0x09,0xbe,0xc8,0x96,0xea,0x54,0xcd,0x2c,0x2e, +0x9c,0x31,0x10,0x62,0xc9,0x97,0x30,0x00,0x69,0x89,0xa2,0xa9,0x93,0x0d,0xc2,0xa8, +0x94,0xe5,0x56,0xed,0x2a,0x65,0x6b,0x6e,0xa2,0x6c,0x8f,0x08,0xc4,0xad,0x94,0xe9, +0x56,0xed,0x2a,0x28,0x6b,0xca,0xa4,0xa8,0x9c,0x31,0x10,0xb5,0xca,0x87,0x10,0x00, +0x8f,0x26,0xc2,0xed,0x93,0x05,0x59,0x09,0x28,0xa9,0x6f,0x61,0xa0,0xe8,0x91,0x45, +0xc1,0x09,0x93,0x29,0x59,0x0d,0x2a,0xa9,0x71,0x81,0xa3,0x11,0x8f,0x4d,0xc3,0x2d, +0x9c,0x31,0x10,0xc0,0xca,0x87,0x30,0x00,0x91,0x2d,0x59,0x11,0x2a,0xb9,0x6f,0x91, +0xa4,0xf4,0x8f,0x36,0xc2,0xf5,0x90,0xed,0x58,0xd5,0x26,0x92,0x71,0x61,0xa4,0xf1, +0x8f,0x31,0xc0,0xe9,0x91,0x11,0x5a,0xf1,0x9c,0x31,0x10,0xfb,0xca,0x86,0x20,0x00, +0x26,0xb5,0x71,0x68,0xa6,0xf2,0x8f,0x30,0xc0,0xe9,0x92,0xf5,0x56,0xd1,0x28,0x92, +0x75,0x85,0xa3,0x15,0x91,0x54,0xbc,0xc9,0x90,0xf1,0x58,0xd1,0x24,0x8d,0x79,0x61, +0x9c,0x31,0x10,0xfb,0xca,0x86,0x20,0x00,0xa5,0x0d,0x91,0x35,0xbc,0xc9,0x90,0xc9, +0x58,0xf1,0x22,0xb1,0x79,0x86,0xa9,0x0d,0x91,0x15,0xb8,0xad,0x90,0xc9,0x54,0xf1, +0x24,0xb1,0x7b,0x86,0xa7,0x0d,0x93,0x11,0x9c,0x31,0x10,0x77,0xca,0x85,0x20,0x00, +0xb6,0xc5,0x92,0xd6,0x54,0xea,0x24,0xc7,0x7d,0x82,0xa9,0x16,0x93,0x08,0xb4,0xc6, +0x90,0xe6,0x53,0x29,0x20,0xb7,0x85,0x52,0xaa,0xf6,0x94,0xfa,0xb2,0xd6,0x91,0x04, +0x9c,0x31,0x10,0xc9,0xc9,0x76,0x20,0x00,0x4f,0x51,0x1e,0x68,0x87,0x61,0xad,0x0d, +0x99,0x0d,0xae,0x89,0x8d,0x0d,0x49,0x51,0x1e,0x85,0x8e,0xc5,0xaf,0x11,0x99,0x2d, +0xaa,0xa9,0x8e,0xed,0x43,0x2d,0x1e,0x65,0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00, +0x96,0xcd,0xb3,0x51,0x9b,0x2d,0xa2,0x49,0x88,0xed,0x3f,0x48,0x24,0xee,0x9e,0x35, +0xb7,0x31,0x9b,0x8d,0x9c,0x6d,0x80,0xad,0x37,0x2c,0x31,0x71,0xa4,0x15,0xb6,0xd1, +0x9c,0x31,0x10,0x13,0xc9,0x64,0x10,0x00,0x9f,0x91,0x94,0xc9,0x7c,0xa9,0x32,0xf2, +0x3b,0xb8,0xa6,0x4d,0xba,0xc9,0x9d,0x71,0x8c,0xcd,0x72,0xc9,0x2e,0xb1,0x4d,0xaa, +0xac,0x86,0xba,0xa9,0x9b,0x4d,0x86,0xed,0x9c,0x31,0x10,0x13,0xc9,0x64,0x10,0x00, +0x6a,0xad,0x2c,0xa4,0x5d,0xa1,0xb0,0xa9,0xb6,0x8d,0x99,0x51,0x7e,0xed,0x60,0xcd, +0x2a,0xa5,0x71,0x2d,0xb7,0x11,0xb6,0xcd,0x94,0xed,0x7b,0x0d,0x54,0xe8,0x30,0xd2, +0x9c,0x31,0x10,0x04,0xc8,0x63,0x10,0x00,0x7f,0x45,0xb9,0xc4,0xb4,0x63,0x90,0x43, +0x75,0xbb,0x47,0x7b,0x3a,0x8e,0x91,0x1d,0xbd,0xd3,0xae,0x82,0x89,0x33,0x6d,0xbc, +0x3a,0x4c,0x49,0xd3,0x9d,0x41,0xbe,0x83,0x9c,0x31,0x10,0x8e,0xc8,0x64,0x10,0x00, +0xa7,0x2d,0x80,0xcd,0x65,0x0d,0x36,0x88,0x5d,0xc1,0xa8,0x89,0xbc,0xd1,0x9f,0x32, +0x7b,0x0d,0x58,0xca,0x30,0x65,0x6f,0x2d,0xb3,0x51,0xba,0x91,0x98,0x8c,0x75,0x69, +0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00,0x4e,0xed,0x36,0xf1,0x84,0x91,0xb9,0x2d, +0xb3,0x2e,0x8c,0x91,0x6c,0xec,0x41,0x11,0x43,0x70,0x96,0x6d,0xbc,0xcd,0xad,0x4d, +0x83,0x0d,0x64,0xd2,0x36,0x8d,0x57,0x85,0x9c,0x31,0x10,0x13,0xc9,0x64,0x10,0x00, +0xa5,0x29,0xbe,0x95,0xa2,0x91,0x7b,0x25,0x5d,0x45,0x34,0x60,0x68,0x90,0xaf,0x31, +0xbb,0x6e,0x9c,0xad,0x72,0x8d,0x4b,0x0c,0x39,0x59,0x80,0xb5,0xb6,0x86,0xb5,0x0d, +0x9c,0x31,0x10,0x19,0xc8,0x75,0x10,0x00,0x8f,0x6d,0x6d,0x6d,0x40,0x96,0x45,0xcc, +0x94,0xe9,0xba,0xb1,0xae,0x71,0x84,0xc9,0x63,0x29,0x38,0x64,0x59,0x66,0xa3,0x71, +0xbb,0x8d,0xa6,0xcd,0x7c,0x91,0x54,0xe9,0x9c,0x31,0x10,0x91,0xc8,0x85,0x10,0x00, +0x35,0x17,0x71,0x1a,0xae,0x26,0xba,0xa4,0x9c,0x96,0x74,0xa7,0x47,0x88,0x3d,0xda, +0x85,0x98,0xb6,0x77,0xb7,0x59,0x95,0x59,0x6a,0x68,0x3c,0x27,0x4a,0xa3,0x88,0x75, +0x9c,0x31,0x10,0x50,0xc8,0x85,0x20,0x00,0xaf,0xa6,0xbd,0x76,0x9d,0x86,0x67,0x95, +0x35,0x36,0x4b,0x68,0x7e,0x37,0xb1,0x97,0xc8,0x58,0xa2,0x67,0x65,0x88,0x32,0x8a, +0x47,0x6b,0x7d,0x59,0xbb,0x68,0xc8,0x79,0x9c,0x31,0x10,0xb0,0xc7,0x75,0x20,0x00, +0x9f,0x91,0x5d,0x51,0x2e,0xd1,0x4b,0x69,0x86,0x89,0xc3,0x4d,0xc4,0x4d,0x97,0x6d, +0x50,0x4a,0x2d,0xc8,0x53,0x61,0x95,0xa6,0xc9,0x4d,0xbd,0x65,0x89,0x89,0x41,0x04, +0x9c,0x31,0x10,0xc5,0xc7,0x75,0x00,0x00,0x33,0x6a,0x60,0x15,0xa3,0xb4,0xcd,0x6e, +0xb6,0x6d,0x79,0xb1,0x36,0x6d,0x38,0x94,0x6c,0x31,0xb2,0x6a,0xcd,0x6d,0xac,0x71, +0x6a,0x6d,0x2e,0x96,0x3f,0x94,0x7c,0x6d,0x9c,0x31,0x10,0x71,0xc7,0x75,0x10,0x00, +0xbf,0x6d,0xca,0x71,0x9e,0x8d,0x57,0x4a,0x2d,0xa8,0x4b,0x6a,0x8d,0xae,0xc7,0x6d, +0xc1,0x4c,0x8e,0x8c,0x48,0x2e,0x30,0x85,0x5a,0x28,0x9e,0x8c,0xca,0x6e,0xb9,0x49, +0x9c,0x31,0x10,0x2d,0xc6,0x75,0x20,0x00,0x80,0x6d,0x3e,0x0c,0x36,0x6e,0x67,0x11, +0xab,0x51,0xca,0x51,0xad,0x71,0x70,0x8d,0x35,0x4c,0x3c,0x71,0x76,0x96,0xb7,0x91, +0xc9,0x6c,0xa3,0x88,0x61,0xa9,0x32,0xae,0x9c,0x31,0x10,0x40,0xc6,0x65,0x00,0x00, +0x46,0x6d,0x83,0x45,0xbf,0x61,0xc4,0x49,0x95,0xad,0x54,0x51,0x32,0xb1,0x53,0x4c, +0x94,0x6c,0xc3,0x6d,0xb9,0x4e,0x86,0x8d,0x4b,0x68,0x39,0xa9,0x63,0x4e,0x9f,0x71, +0x9c,0x31,0x10,0xe7,0xc6,0x54,0x00,0x00,0xc3,0x78,0xac,0x84,0x77,0x95,0x43,0x56, +0x41,0xc5,0x73,0x54,0xac,0x91,0xc1,0x32,0x9f,0x92,0x6a,0x70,0x40,0x64,0x4d,0x91, +0x80,0x52,0xb2,0xa5,0xb9,0x35,0x94,0x79,0x9c,0x31,0x10,0xa6,0xb5,0x54,0x00,0x00, +0x40,0x6a,0x06,0x5a,0x32,0xdc,0x96,0x55,0xe7,0x5a,0xde,0x99,0x91,0x1a,0x34,0x9b, +0x13,0x1c,0x4a,0x5c,0xa8,0xe3,0xe4,0xa2,0xc7,0x63,0x7d,0x23,0x30,0xe4,0x23,0x6b, +0x9c,0x31,0x10,0x2c,0xb5,0x53,0x00,0x00,0x5e,0x74,0xb2,0xb1,0xdb,0x2d,0xb8,0xaa, +0x72,0x89,0x35,0x68,0x37,0x86,0x72,0x25,0xb7,0x85,0xcc,0x25,0xa6,0x89,0x67,0x2a, +0x39,0x49,0x45,0x4d,0x7d,0x30,0xb5,0x71,0x9c,0x31,0x10,0x1e,0xa4,0x54,0x00,0x00, +0xfa,0x25,0xae,0x6c,0x42,0x69,0x04,0xaa,0x27,0x24,0x8d,0x25,0xe6,0xe2,0xe3,0x20, +0x9b,0x23,0x40,0x9d,0x17,0x1b,0x40,0xd3,0x9b,0x9a,0xd8,0xe4,0xc9,0x9c,0x87,0x12, +0x9c,0x31,0x10,0x8c,0xa4,0x43,0x00,0x00,0x42,0x8d,0x2f,0x6a,0x57,0x4d,0x9e,0xa9, +0xca,0x05,0xb7,0x8d,0x7d,0x4e,0x46,0x95,0x41,0xb5,0x67,0x2d,0x9d,0xb5,0xb4,0x69, +0xa1,0x91,0x7c,0xb1,0x59,0xce,0x53,0x68,0x9c,0x31,0x10,0x55,0x85,0x64,0x10,0x00, +0x2e,0x42,0xb2,0x42,0xf5,0xb5,0xda,0x2b,0x7a,0x2e,0x2d,0xb9,0x1e,0x43,0x56,0xbb, +0xaa,0x33,0xca,0x1c,0xb6,0x25,0x84,0xb3,0x75,0xa9,0x6d,0x03,0x91,0x18,0xb0,0xbd, +0x9c,0x31,0x10,0x60,0x86,0x65,0x10,0x00,0xb8,0xe1,0x9d,0x28,0x6d,0x66,0x4d,0x19, +0x41,0x61,0x4d,0x6d,0x5d,0x5d,0x71,0x9d,0x7d,0xa2,0x8d,0x6a,0x95,0xb0,0xb1,0xe4, +0xbd,0x60,0xbd,0xda,0xca,0x1a,0xa6,0x18,0x9c,0x31,0x10,0x84,0x96,0x65,0x20,0x00, +0x85,0xe4,0x61,0xa9,0x4d,0x6e,0x42,0x5a,0x55,0x5c,0x71,0x95,0xa9,0xce,0xd1,0x95, +0xc9,0x19,0x88,0x95,0x4d,0xe0,0x20,0xe9,0x2e,0x11,0x7d,0xd5,0xcd,0x58,0xf1,0x59, +0x9c,0x31,0x10,0x3e,0x95,0x65,0x20,0x00,0xd6,0xb9,0x9d,0x23,0x49,0xab,0x04,0xac, +0x18,0x2d,0x61,0x43,0xbd,0x4b,0xea,0x4a,0xd1,0x41,0x97,0x4b,0x51,0x2c,0x29,0xd6, +0x2f,0x33,0x5a,0x5c,0xa6,0xd2,0xca,0x92,0x9c,0x31,0x10,0x84,0x96,0x65,0x20,0x00, +0xc5,0x55,0x82,0x58,0x41,0x51,0x2e,0x09,0x4c,0x8d,0x81,0x9a,0xac,0xe6,0xad,0x58, +0x9d,0x9c,0x6d,0x75,0x5e,0x29,0x4f,0x2e,0x61,0xb5,0x81,0xd9,0x95,0x8c,0x8a,0x71, +0x9c,0x31,0x10,0xea,0x77,0x75,0x20,0x00,0x8c,0x53,0x34,0x45,0x0c,0xda,0x14,0x5e, +0x36,0x39,0x6b,0xc3,0xb5,0x41,0xa4,0xa1,0x84,0x9e,0x64,0xbb,0x44,0x95,0x5b,0x9b, +0x64,0xa2,0x8b,0xb8,0x9c,0x34,0x9a,0xa4,0x9c,0x31,0x10,0xc6,0x66,0x66,0x20,0x00, +0x8c,0xa5,0x1b,0x9b,0x0d,0x12,0x0a,0xb2,0x3a,0x3b,0x54,0x33,0xa2,0xbd,0xaa,0xdc, +0x8c,0xda,0x22,0x32,0x29,0x8b,0x2b,0x2b,0x6a,0xbc,0x4b,0x33,0x93,0x34,0xa9,0x5a, +0x9c,0x31,0x10,0xde,0x66,0x76,0x20,0x00,0x48,0xc2,0x2c,0xc2,0x44,0xc4,0x13,0x51, +0x8c,0xdb,0x7b,0xe4,0xbc,0xe4,0x73,0xd4,0x6d,0xb9,0x75,0x43,0x6e,0x52,0xb4,0xc3, +0x9e,0xbc,0xbc,0x3c,0xad,0x3c,0x85,0xbb,0x9c,0x31,0x10,0xc6,0x66,0x66,0x20,0x00, +0x75,0x39,0x76,0xaa,0x7d,0xbc,0x94,0xcc,0xcc,0x9b,0x7c,0xba,0x94,0xd3,0x96,0x2a, +0xc4,0xab,0x64,0x3c,0x8d,0x23,0x9c,0x02,0xcc,0x1b,0x7c,0xba,0x89,0xc4,0x85,0x34, +0x9c,0x31,0x10,0xee,0x66,0x56,0x20,0x00,0xad,0x05,0x49,0x26,0xc4,0x18,0x7c,0x18, +0xb3,0xb8,0x74,0xc9,0x9c,0x35,0x7b,0xa7,0x43,0xa6,0x92,0x07,0x83,0xaa,0x93,0x36, +0x8c,0xb6,0xc3,0x02,0x90,0x9b,0xb8,0xb5,0x9c,0x31,0x10,0x8b,0x66,0x65,0x10,0x00, +0x9c,0x14,0x79,0xac,0x53,0x12,0x6a,0x23,0xa0,0xdc,0x53,0xa9,0xdb,0x45,0xc1,0x43, +0xb5,0x31,0xb9,0x84,0x85,0xa4,0xb0,0xa1,0x68,0x3a,0x83,0x44,0x53,0x54,0x58,0xcb, +0x9c,0x31,0x10,0xea,0x77,0x75,0x20,0x00,0x43,0xc3,0x51,0xbc,0x6b,0xb9,0x63,0xb5, +0x8a,0x39,0xa2,0xbd,0x9b,0x41,0x82,0xcc,0x9b,0xd1,0x5b,0x3b,0x6b,0x3b,0x42,0xce, +0x3a,0xca,0x54,0x45,0x2b,0xd0,0x6a,0xe0,0x9c,0x31,0x10,0x57,0x76,0x66,0x30,0x00, +0x9d,0x5a,0x9b,0xb5,0x63,0x4e,0x8c,0x74,0x62,0xda,0x8b,0xc9,0x32,0xda,0x1b,0xdb, +0x13,0x69,0x4c,0x34,0x7c,0x4c,0x62,0xe5,0xe3,0x5a,0xc6,0xc5,0x9b,0x4b,0x8c,0xb3, +0x9c,0x31,0x10,0x18,0x85,0x67,0x20,0x00,0x7e,0xb3,0x79,0x22,0x7e,0x29,0x94,0xdc, +0xa6,0xf4,0xc4,0xd4,0xb6,0x71,0xa6,0x62,0xa8,0xf4,0x8e,0xec,0x88,0x64,0x9f,0x5a, +0xa6,0x51,0xa9,0xb3,0xb1,0xd4,0x8a,0x43,0x9c,0x31,0x10,0xf3,0xa6,0x75,0x20,0x00, +0x7a,0xf1,0x78,0xd2,0x72,0xae,0x78,0xd1,0x80,0xd4,0x85,0x71,0x7d,0x10,0x6f,0x75, +0x5d,0x16,0x4b,0x12,0x53,0x51,0x88,0xf4,0xc5,0x51,0xd1,0x12,0xbb,0x92,0x50,0x70, +0x9c,0x31,0x10,0xdb,0xc8,0x77,0x20,0x00,0x55,0x0d,0x4e,0x89,0x7d,0x09,0xb0,0xa9, +0xb4,0xc6,0xa8,0xe5,0x88,0xcc,0x53,0x6c,0x28,0x4d,0x4d,0x8a,0xa2,0xc9,0xa3,0x0d, +0xa8,0xe9,0xb2,0xac,0x9e,0xed,0x62,0x6d,0x9c,0x31,0x10,0xdb,0xc8,0x77,0x20,0x00, +0x2f,0x4d,0x33,0x35,0x83,0x35,0x9a,0xb5,0x9b,0x15,0xaa,0xb1,0xad,0x30,0x90,0xd1, +0x54,0xae,0x24,0x69,0x49,0xa8,0x9b,0x09,0x95,0x2e,0xa1,0x29,0xae,0xa4,0xa7,0x21, +0x9c,0x31,0x10,0x77,0xc8,0x67,0x30,0x00,0x84,0xc1,0x4a,0xed,0x28,0x05,0x5b,0x25, +0x9a,0x90,0x95,0x09,0xa2,0xe9,0xa8,0x92,0xa4,0xf1,0x80,0xd4,0x4a,0xf1,0x2a,0x0a, +0x5f,0x25,0x9a,0x8c,0x93,0x15,0xa2,0xed,0x9c,0x31,0x10,0xe0,0xc8,0x76,0x30,0x00, +0xa6,0x91,0xa3,0x08,0x82,0xed,0x4e,0xf2,0x30,0x25,0x5f,0x48,0x96,0xad,0x93,0x11, +0x9e,0xf4,0xa6,0xb5,0xa5,0x05,0x84,0xca,0x54,0xce,0x32,0x49,0x53,0x24,0x90,0xec, +0x9c,0x31,0x10,0x54,0xc8,0x76,0x20,0x00,0x99,0x11,0x9a,0xe9,0xa2,0xaa,0xa7,0x0d, +0x8c,0xc9,0x5e,0xed,0x38,0xec,0x49,0x61,0x85,0x09,0x99,0x09,0x99,0x0e,0x9e,0xea, +0xa5,0x2c,0x96,0xe9,0x6c,0xed,0x45,0x55,0x9c,0x31,0x10,0x36,0xb7,0x56,0x10,0x00, +0x05,0x76,0x61,0x73,0xa9,0x12,0xb7,0x2c,0xb8,0xec,0xbb,0x0a,0xb0,0xf2,0x77,0x0b, +0x33,0x23,0x1a,0x4a,0x48,0xac,0x88,0x8b,0xa8,0xeb,0xac,0xcb,0xa4,0xcb,0x9c,0xcb, +0x9c,0x31,0x10,0x66,0x95,0x53,0x00,0x00,0xa5,0x0c,0x32,0x36,0x00,0xd6,0x11,0x32, +0x4e,0xcc,0x80,0xf5,0xb0,0xd5,0xcd,0x31,0xe0,0x90,0xd2,0xcd,0xac,0xcd,0x7c,0xed, +0x5d,0x2d,0x5f,0x4d,0x71,0x0d,0x81,0x2d,0x9c,0x31,0x10,0x23,0x73,0x22,0x00,0x00, +0xb5,0x4c,0xda,0xdb,0xca,0xd1,0x82,0x8c,0x2b,0x5c,0x15,0x5b,0x2b,0x62,0x57,0x1b, +0x7e,0xdc,0x87,0x1a,0x92,0xe3,0x80,0xa4,0x5e,0x9b,0x3f,0x1b,0x45,0x6a,0x4a,0xdd, +0x9c,0x31,0x10,0x69,0x53,0x22,0x00,0x00,0x19,0xe4,0x58,0xa2,0x31,0x9b,0x5d,0xe1, +0x95,0x95,0x91,0x5a,0x81,0xf3,0x75,0xeb,0x41,0x9a,0x5a,0x2c,0x91,0x5b,0x65,0xe4, +0x59,0x4c,0x9e,0x23,0xc5,0xd3,0xb5,0xd3,0x9c,0x31,0x10,0x60,0x52,0x31,0x00,0x00, +0x72,0xa1,0x25,0xdd,0x1b,0x59,0x5d,0xa0,0x5c,0x56,0x5a,0x08,0x8e,0x15,0xb5,0x9e, +0x7d,0x1e,0x4d,0x95,0x18,0x55,0x31,0xdc,0x74,0x9a,0x85,0xe1,0x6d,0x51,0xac,0xa2, +0x9c,0x31,0x10,0x5f,0x78,0x96,0x10,0x00,0x8b,0xbb,0x83,0xbb,0x6b,0xbb,0x6b,0xbb, +0x73,0xbb,0x73,0xbb,0x83,0xbb,0x7b,0xbb,0x83,0xbb,0x8b,0xbb,0x7b,0xbb,0x6b,0xbb, +0x83,0x3b,0xdb,0x39,0x7e,0x1d,0x96,0x2b,0x9c,0x31,0x10,0xf0,0x99,0x86,0x20,0x00, +0x84,0x9b,0x84,0x1a,0xab,0x8a,0x90,0x8e,0x61,0x3c,0x89,0x23,0x5b,0xb3,0x9b,0xc4, +0x82,0xe1,0x73,0x52,0x93,0x4b,0x8b,0x4c,0x4b,0xb4,0x33,0x3b,0x7b,0xbb,0x6b,0xbb, +0x9c,0x31,0x10,0x8d,0x88,0x75,0x10,0x00,0x39,0xee,0x6a,0x2d,0x8d,0xce,0xde,0x50, +0x96,0x2c,0x3e,0xa9,0x69,0xf2,0x8e,0x10,0x69,0xf1,0x6d,0xf1,0x75,0xd1,0x65,0xf9, +0x71,0xac,0x5e,0x6a,0x72,0xc8,0x7a,0xee,0x9c,0x31,0x10,0x20,0x79,0x87,0x30,0x00, +0x6b,0xd2,0x8b,0x64,0x3b,0xf3,0x33,0xec,0x0a,0x62,0x39,0x5b,0x69,0x64,0x32,0x52, +0x53,0x31,0x8c,0x1a,0xbd,0x05,0x76,0x23,0x1e,0xb4,0x8e,0x0c,0x7d,0x39,0x74,0x49, +0x9c,0x31,0x10,0x01,0x78,0x96,0x40,0x00,0x72,0xd4,0x71,0xcb,0x8a,0x6d,0x29,0x64, +0x60,0xce,0xa8,0x44,0x81,0xaa,0xa3,0x28,0xb4,0x2a,0xad,0x32,0x8d,0x3d,0xad,0xae, +0xe4,0x39,0xbc,0x3a,0xf2,0x42,0xc2,0x3e,0x9c,0x31,0x10,0xee,0x89,0x87,0x30,0x00, +0xa3,0x3b,0xc3,0xa1,0xcc,0x23,0xc4,0x39,0xac,0xc4,0x9c,0x54,0x94,0x45,0x8b,0x3c, +0x8a,0xb8,0xa1,0xca,0xa9,0xd4,0xa1,0xb4,0x9a,0x41,0xb2,0xac,0xa2,0xa3,0xc3,0x1b, +0x9c,0x31,0x10,0x1c,0x87,0x76,0x30,0x00,0xc4,0xca,0xbc,0x86,0xb1,0x01,0xb5,0xdb, +0xa6,0xdd,0x8e,0x9a,0x8a,0x9b,0x86,0xa2,0x7a,0x5d,0x69,0xdb,0x49,0xe3,0x49,0xe3, +0x3d,0xa1,0x29,0x9c,0x29,0xa2,0x45,0xd3,0x9c,0x31,0x10,0xa8,0x87,0x76,0x20,0x00, +0x45,0xd1,0x45,0x5c,0x39,0xa5,0x51,0x1b,0x51,0x91,0x59,0x9c,0x55,0x14,0x61,0x12, +0x6d,0x51,0x69,0xd5,0x6a,0x53,0x72,0x93,0x6a,0x8b,0x62,0xdb,0x67,0x14,0x76,0x93, +0x9c,0x31,0x10,0x0e,0x67,0x75,0x10,0x00,0x3d,0xb3,0x24,0x98,0x44,0x46,0x5c,0x39, +0x5b,0x43,0x72,0xc5,0x93,0x32,0x42,0xb9,0x2b,0x3a,0x4b,0xa5,0x03,0xbd,0x1b,0x31, +0x33,0x34,0x73,0x34,0x9b,0x42,0x7b,0x33,0x9c,0x31,0x10,0x16,0x67,0x65,0x10,0x00, +0x84,0x44,0x3b,0xb3,0x34,0x21,0x4c,0x13,0x4b,0x34,0x64,0x2b,0x73,0xba,0x64,0x5c, +0x75,0xa4,0x6d,0x23,0x6d,0x24,0x5c,0xaa,0x8c,0x24,0x8d,0xcb,0x9c,0x2b,0x9b,0xab, +0x9c,0x31,0x10,0xbe,0x65,0x64,0x10,0x00,0xbe,0xa4,0x99,0xb1,0x95,0xc0,0x7e,0x4a, +0x86,0xbe,0x8a,0x30,0x97,0x46,0x9b,0x45,0xbe,0x43,0xa5,0xb4,0xc2,0x38,0xbe,0x51, +0xdd,0xbd,0xce,0x44,0xc6,0xd2,0xb1,0xe3,0x9c,0x31,0x10,0x31,0x65,0x65,0x10,0x00, +0xce,0xec,0xc9,0xc3,0x99,0xdb,0x89,0xdb,0x74,0xbb,0x6c,0x4a,0x61,0xbb,0x3d,0x53, +0x50,0xc2,0x78,0xd3,0x66,0x3d,0x84,0xbb,0x8a,0x43,0xb9,0xc3,0x65,0xc2,0xa2,0x5d, +0x9c,0x31,0x10,0x4d,0x55,0x54,0x00,0x00,0x7b,0xe1,0x65,0x3b,0x35,0x3c,0xb3,0x8c, +0xbd,0x41,0x92,0x34,0xd9,0xc1,0xba,0x34,0x72,0xcb,0x94,0xb4,0x5a,0xa3,0x5d,0xc4, +0x3d,0x00,0x7d,0x2c,0x55,0xac,0x7c,0xa1,0x9c,0x31,0x10,0x43,0x56,0x54,0x10,0x00, +0x8d,0xcb,0x8d,0xdd,0xb3,0xec,0x85,0x8a,0xac,0x94,0xa4,0x52,0x9a,0xb3,0x62,0x5c, +0x4a,0xa5,0x63,0xf0,0x2c,0xeb,0x75,0x25,0x8c,0x59,0x93,0x98,0xc5,0x5c,0xb3,0xec, +0x9c,0x31,0x10,0x17,0x66,0x55,0x00,0x00,0x99,0xa3,0x59,0xda,0x5d,0xac,0x4d,0x6b, +0x5c,0xea,0x35,0x93,0x46,0x15,0x65,0x12,0x55,0x02,0x71,0xad,0x65,0xac,0x55,0xd9, +0x5e,0xac,0x86,0x5b,0x7a,0x4b,0x7a,0x93,0x9c,0x31,0x10,0x50,0x56,0x65,0x00,0x00, +0x6a,0xbc,0x6d,0x3c,0x54,0xba,0x2b,0xc3,0x75,0xc4,0x8c,0xda,0x5c,0xcb,0x92,0xc3, +0x6b,0x3c,0x95,0xca,0x75,0xc4,0x92,0x3d,0x5a,0x29,0xba,0x9b,0x6c,0x34,0xab,0x42, +0x9c,0x31,0x10,0x74,0x97,0x75,0x00,0x00,0x7d,0x9d,0x7d,0xde,0x7e,0x19,0x7a,0x15, +0x7e,0x19,0x82,0x55,0x82,0x55,0x7e,0x19,0x82,0x21,0x82,0x65,0x7e,0x60,0x8d,0xd8, +0xc3,0xa6,0x69,0x6d,0x69,0xf1,0x7a,0x28,0x9c,0x31,0x10,0x16,0x86,0x67,0x30,0x00, +0x72,0x2b,0x3a,0xec,0x62,0x2b,0x72,0x22,0x66,0xa3,0x61,0x63,0x5d,0xd3,0x5d,0x95, +0x71,0x5c,0x7d,0x29,0x7d,0x5a,0x8d,0x9d,0x91,0x24,0x91,0x99,0x9d,0x43,0xa1,0x5d, +0x9c,0x31,0x10,0x63,0x86,0x67,0x10,0x00,0xac,0xa4,0xa1,0x99,0xc1,0x6a,0xbd,0xb5, +0xad,0xda,0xa6,0x19,0xae,0x4c,0x99,0x46,0xa5,0xc9,0xa9,0x11,0x99,0x64,0x8e,0x34, +0x89,0xea,0x81,0x93,0x6d,0xcc,0x51,0x5b,0x9c,0x31,0x10,0x9e,0xa6,0x65,0x00,0x00, +0x77,0x8d,0x7c,0xf1,0x7b,0x15,0x7d,0x91,0x77,0x6d,0x73,0x50,0x73,0x4d,0x71,0x0e, +0x7d,0x4e,0x8d,0x0c,0x92,0xf4,0x93,0x12,0x7c,0xb6,0x56,0xb8,0x34,0xb0,0x4b,0x0e, +0x9c,0x31,0x10,0xfd,0xc7,0x76,0x10,0x00,0x84,0xe4,0x96,0xda,0x9c,0xdb,0x93,0x1b, +0x72,0x93,0x57,0x13,0x4a,0x5c,0x6d,0x63,0xa4,0x5b,0xb0,0x9b,0xaa,0x9a,0x95,0x23, +0x60,0xa5,0x3e,0xa2,0x34,0x23,0x86,0xaa,0x9c,0x31,0x10,0x54,0xc8,0x76,0x20,0x00, +0xa4,0x79,0xa5,0x19,0xb4,0xb5,0xa7,0x18,0x78,0xb5,0x41,0xb2,0x2c,0x31,0x5b,0xad, +0x9a,0xc9,0x99,0x49,0xaf,0x29,0xb0,0x8a,0x97,0x66,0x60,0x49,0x37,0xc8,0x36,0xae, +0x9c,0x31,0x10,0x95,0xc8,0x76,0x10,0x00,0x83,0x51,0x98,0x90,0x9d,0x32,0xb7,0x11, +0xa6,0xd0,0x89,0x2d,0x50,0x92,0x31,0x0e,0x4b,0xac,0x9a,0xe8,0x90,0xe5,0xa5,0x02, +0xb2,0xe5,0x9c,0xe8,0x82,0xe9,0x4e,0x8d,0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00, +0x30,0x8e,0x59,0x48,0x9c,0xc4,0x8d,0x09,0xa8,0xea,0xac,0xe9,0x98,0xe9,0x82,0xe9, +0x4c,0xed,0x30,0x4e,0x61,0x65,0x9c,0xa0,0x89,0x25,0xae,0xea,0xaa,0xea,0x96,0xe9, +0x9c,0x31,0x10,0xf2,0xc9,0x77,0x30,0x00,0x87,0x09,0x50,0xcd,0x30,0xae,0x5f,0x84, +0x96,0xc1,0x87,0x26,0xae,0xe2,0xa8,0xe5,0x9c,0xed,0x8a,0xec,0x56,0xb1,0x35,0x31, +0x4f,0x59,0x96,0xce,0x84,0xed,0xab,0x09,0x9c,0x31,0x10,0xce,0xc9,0x87,0x20,0x00, +0xae,0xc9,0x9b,0x09,0x92,0xed,0x5e,0xad,0x39,0x71,0x42,0xd2,0x8f,0x15,0x88,0xb1, +0x9f,0x31,0xb2,0xcd,0x9d,0x0d,0x98,0xed,0x70,0xed,0x3f,0x49,0x36,0x28,0x79,0x46, +0x9c,0x31,0x10,0x7d,0xc9,0x76,0x30,0x00,0x8e,0x69,0x8f,0x2a,0xb4,0x88,0x9e,0xf4, +0x9c,0xd5,0x85,0x11,0x4c,0xd1,0x34,0xd1,0x59,0x99,0x92,0xce,0x83,0x0d,0xaf,0x09, +0xa6,0xc4,0xa1,0x09,0x96,0xe9,0x64,0xa9,0x9c,0x31,0x10,0x41,0xc9,0x86,0x20,0x00, +0x3b,0x6a,0x3a,0x44,0x7d,0x09,0x8c,0x8e,0x97,0x2d,0xb2,0xad,0xa1,0x11,0xa0,0xcd, +0x85,0x0c,0x4a,0xce,0x37,0x10,0x51,0x36,0x92,0xd5,0x86,0xf1,0xab,0x11,0xa8,0xcd, +0x9c,0x31,0x10,0x7a,0xc9,0x87,0x30,0x00,0xa1,0x2d,0x98,0xcd,0x70,0xee,0x41,0x4d, +0x3a,0x69,0x67,0x84,0x94,0xa5,0x8d,0x49,0xb0,0xe9,0xa0,0xc5,0xa0,0xed,0x90,0xed, +0x5e,0xad,0x3d,0x49,0x3a,0x49,0x7d,0x4a,0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00, +0x90,0x84,0x93,0x29,0xb0,0xcd,0x9d,0x0d,0xa4,0xd5,0x8a,0xf1,0x5a,0xa9,0x3d,0x29, +0x3c,0x40,0x83,0x02,0x8c,0x6d,0x97,0x10,0xae,0xb5,0x9a,0xed,0xa4,0xb6,0x86,0xf5, +0x9c,0x31,0x10,0xce,0xc9,0x87,0x20,0x00,0x5a,0x8c,0x41,0x2d,0x3a,0x68,0x83,0x0a, +0x8e,0x89,0x91,0x0c,0xac,0xed,0x96,0xce,0xa6,0xc9,0x8a,0xe9,0x62,0xcd,0x45,0x49, +0x3a,0x49,0x75,0x64,0x94,0x88,0x87,0x2a,0x9c,0x31,0x10,0x41,0xc9,0x86,0x20,0x00, +0xac,0xed,0x98,0xb0,0x9f,0x31,0x9a,0xd5,0x6d,0x31,0x4f,0x11,0x3c,0xf1,0x57,0x75, +0x98,0xcd,0x83,0x0c,0xa3,0x09,0xa2,0xe9,0x94,0xe9,0xa6,0xc5,0x82,0xe9,0x5e,0xc9, +0x9c,0x31,0x10,0x87,0xc9,0x77,0x10,0x00,0x49,0x05,0x3a,0x69,0x7d,0x26,0x90,0x88, +0x89,0x2d,0xa8,0xa9,0x98,0xce,0x9c,0xed,0x9c,0xb5,0x74,0xf5,0x58,0xd5,0x45,0x15, +0x46,0xb1,0x8e,0xf5,0x86,0xb1,0x91,0x15,0x9c,0x31,0x10,0x01,0xb7,0x87,0x10,0x00, +0xcc,0xba,0xa9,0xc4,0xc2,0x3b,0xac,0xc3,0x61,0xc3,0x2d,0xcb,0x09,0xd3,0x19,0xd4, +0xa9,0xe1,0x80,0x54,0xab,0x4b,0xc4,0xb2,0xa2,0x34,0xbd,0xb3,0xac,0xbb,0x66,0x42, +0x9c,0x31,0x10,0x92,0xc8,0x87,0x10,0x00,0x5c,0xad,0x48,0xcd,0x46,0x6c,0x90,0xd1, +0x84,0x52,0x8d,0x31,0xa2,0x91,0x91,0x2d,0x98,0xcd,0x9d,0x48,0x7f,0x26,0x64,0xe5, +0x52,0xe5,0x3c,0x4a,0x7f,0x85,0x90,0x68,0x9c,0x31,0x10,0x3d,0xb7,0x77,0x00,0x00, +0x81,0x95,0xc4,0xa3,0xa4,0x9a,0xa7,0x24,0xc0,0xda,0xa0,0x73,0x64,0xf4,0x40,0xeb, +0x0a,0x9b,0x2b,0x64,0xb4,0x72,0x7a,0x63,0x9b,0x63,0xbe,0x9b,0x97,0x53,0xb6,0xdb, +0x9c,0x31,0x10,0x08,0xc9,0x76,0x10,0x00,0x99,0x11,0x84,0xed,0x70,0xed,0x5b,0x0d, +0x3e,0xcd,0x67,0x79,0x9a,0xce,0x79,0x0c,0x99,0x09,0x9a,0xc9,0x8b,0x09,0x9c,0xcd, +0x99,0x15,0x85,0x0e,0x6c,0xed,0x55,0x28,0x9c,0x31,0x10,0xbc,0xc9,0x76,0x00,0x00, +0x3e,0xae,0x6f,0x68,0x98,0xc6,0x7d,0x05,0x9a,0xe9,0x98,0xc9,0x8c,0xed,0x9c,0xd1, +0x99,0x11,0x82,0xee,0x6a,0xe9,0x57,0x09,0x3e,0xae,0x6d,0x48,0x9a,0xc9,0x7b,0x09, +0x9c,0x31,0x10,0xc2,0xb8,0x66,0x00,0x00,0xa9,0xd2,0xb1,0x5b,0x92,0x24,0xb1,0x9a, +0xb5,0xe3,0x81,0xe3,0x59,0x9c,0x2e,0x5a,0x05,0x13,0x53,0x62,0xb1,0x4d,0x7e,0x4a, +0x9d,0xc2,0xb9,0x8c,0x9a,0x13,0xa5,0x9a,0x9c,0x31,0x10,0xda,0xb8,0x76,0x00,0x00, +0xb9,0xdd,0x89,0xe2,0x51,0xda,0x2a,0x64,0x09,0x64,0x53,0x19,0xb1,0x8c,0x82,0x4c, +0x92,0x0a,0xb5,0x8b,0xa1,0xd3,0x9d,0xa3,0xb2,0x1a,0x91,0xdb,0x51,0xdd,0x2e,0x1a, +0x9c,0x31,0x10,0xaa,0xb7,0x66,0x00,0x00,0x14,0x9a,0x45,0xb4,0xa6,0xdd,0x97,0x11, +0x8d,0x0b,0xaa,0xcc,0xae,0xca,0xa0,0xcb,0xab,0x1a,0x9a,0xd4,0x60,0xdb,0x2b,0x12, +0x12,0xdb,0x3d,0x74,0xa0,0xeb,0x9a,0xe1,0x9c,0x31,0x10,0x93,0xb6,0x55,0x00,0x00, +0x8d,0x45,0xa8,0xe2,0xb1,0x00,0xa6,0xa1,0xa7,0x46,0x98,0xc9,0x62,0xad,0x2b,0x4e, +0x16,0xac,0x41,0xb6,0x9a,0xf0,0x9e,0xf4,0x91,0x12,0xa0,0xcd,0xb3,0x25,0xaa,0x82, +0x9c,0x31,0x10,0x37,0xb6,0x66,0x00,0x00,0xa1,0x13,0x94,0xda,0x64,0xd4,0x29,0x1b, +0x12,0x9a,0x3f,0xac,0x9a,0xdb,0xa6,0xe1,0x92,0xdc,0x9a,0x9c,0xb3,0x12,0xae,0xa3, +0xa1,0x5b,0x95,0x0b,0x6c,0xd3,0x33,0x13,0x9c,0x31,0x10,0x01,0xb5,0x65,0x00,0x00, +0x14,0x91,0x37,0x62,0x95,0x25,0xac,0xe1,0x97,0x21,0x94,0xe1,0xaf,0x1d,0xb6,0x16, +0xa4,0x89,0x8a,0xcc,0x68,0x91,0x3d,0x1a,0x20,0x58,0x38,0xa9,0x84,0x2e,0xaa,0xb0, +0x9c,0x31,0x10,0x9c,0xb4,0x65,0x00,0x00,0xa5,0x31,0x9a,0x6a,0xa7,0xa4,0xb0,0x21, +0xa5,0x12,0x84,0x90,0x63,0x09,0x44,0xd2,0x2d,0x15,0x3a,0x9d,0x78,0x69,0xa8,0xa5, +0xaf,0x61,0xa2,0xe1,0xa2,0xe5,0xab,0x61,0x9c,0x31,0x10,0x90,0xa5,0x65,0x10,0x00, +0xb1,0x21,0x63,0xa1,0x27,0x59,0x0b,0x15,0x0d,0x4d,0x30,0x8d,0x7c,0x88,0xc0,0x8d, +0xda,0xd5,0xda,0xa1,0xd2,0x69,0xb2,0xa0,0x72,0xa6,0x34,0xe1,0x18,0x9d,0x22,0xde, +0x9c,0x31,0x10,0x90,0xa5,0x65,0x10,0x00,0x3f,0x19,0x64,0x51,0x9d,0x1d,0xc6,0xa1, +0xd4,0xe2,0xc6,0xa0,0xa0,0xdd,0x76,0xa2,0x59,0x5d,0x4a,0x95,0x4d,0x11,0x5e,0x49, +0x70,0x61,0x82,0xa9,0x94,0xe6,0x9e,0xed,0x9c,0x31,0x10,0xff,0x95,0x65,0x10,0x00, +0xbd,0xdb,0xc2,0xc2,0xaa,0xbc,0x86,0xa4,0x6d,0xa2,0x61,0xbb,0x62,0x36,0x6a,0x38, +0x75,0xc2,0x7e,0x3e,0x85,0x29,0x8d,0xa9,0x8d,0xac,0x99,0xa4,0x91,0x29,0x90,0xb5, +0x9c,0x31,0x10,0xd8,0x65,0x55,0x20,0x00,0xf3,0x4d,0xca,0x51,0xb2,0x72,0x81,0x8e, +0x73,0xc5,0x3a,0x69,0x2a,0x51,0x1b,0xad,0x22,0x6d,0x84,0xcd,0x99,0x84,0xa5,0x6c, +0x8a,0xb1,0x82,0x6d,0x6b,0x76,0x64,0x6a,0x9c,0x31,0x10,0x19,0x65,0x55,0x10,0x00, +0x9e,0x1a,0x89,0x99,0x76,0x9a,0x59,0x9c,0x42,0x14,0x3d,0xd5,0x75,0x9a,0x55,0xd2, +0x7d,0xdc,0x6e,0x13,0x8c,0x93,0x7d,0x62,0x9d,0x54,0x70,0xdb,0x65,0xeb,0x6d,0x54, +0x9c,0x31,0x10,0xad,0x65,0x55,0x00,0x00,0x61,0x9b,0x4d,0x21,0x6d,0xdb,0x6d,0x65, +0x46,0x6a,0x3d,0xf2,0x46,0xac,0x5d,0x9a,0x6e,0x53,0x46,0x25,0x2a,0x24,0x3a,0x12, +0x4b,0x0b,0x05,0x9b,0x1a,0x52,0x5d,0xda,0x9c,0x31,0x10,0x8e,0x65,0x44,0x10,0x00, +0x6a,0x4d,0x75,0xdc,0x79,0x92,0x5a,0x8d,0x62,0x54,0x4c,0xda,0x55,0x4b,0x68,0xcb, +0x2d,0xec,0x45,0x9a,0x5d,0x62,0x6d,0x1c,0x86,0x0a,0x74,0xe3,0x91,0x73,0x95,0x23, +0x9c,0x31,0x10,0x19,0x65,0x55,0x10,0x00,0x91,0x63,0xa2,0x73,0x7d,0xf3,0xbe,0x73, +0x85,0x55,0x8d,0xeb,0x9a,0xd9,0x7a,0x2a,0xc3,0x34,0x8a,0x9b,0xa1,0xa4,0x92,0x93, +0x8a,0x0a,0x87,0x52,0x72,0xd4,0x91,0x94,0x9c,0x31,0x10,0x19,0x65,0x55,0x10,0x00, +0xa9,0x0d,0x91,0x9a,0x8e,0x6a,0x91,0xd1,0xa6,0x64,0x95,0xcb,0xbe,0x4c,0x9c,0xdb, +0x71,0x4c,0x96,0x51,0x71,0xab,0x5e,0xeb,0x5d,0xa3,0x81,0x9c,0x92,0x91,0x81,0x14, +0x9c,0x31,0x10,0x76,0x55,0x55,0x10,0x00,0x7d,0x2c,0x8b,0x12,0x7d,0x24,0x6b,0x3b, +0x9a,0x32,0x59,0x33,0x34,0x4c,0x55,0xca,0x5c,0xeb,0x59,0xdd,0x4b,0xcb,0x6b,0x59, +0x6b,0x4b,0x5b,0xae,0x47,0x5a,0x44,0x22,0x9c,0x31,0x10,0xf9,0x55,0x54,0x10,0x00, +0x64,0x34,0x8b,0x29,0xab,0xb9,0x9d,0x2c,0x83,0x35,0x8b,0x43,0x6c,0x55,0x7c,0xdb, +0x6c,0x59,0x6d,0xaa,0x71,0xbc,0x8c,0x39,0x9d,0xbb,0x73,0xbe,0x43,0x2b,0x1b,0x41, +0x9c,0x31,0x10,0xc2,0x55,0x55,0x00,0x00,0x2b,0xcb,0x65,0xe4,0x54,0x4b,0x44,0xd2, +0x12,0xab,0x64,0x23,0x64,0xcc,0x8a,0xbb,0x83,0xb3,0x92,0xb3,0xc2,0x2d,0x9a,0x22, +0x83,0x22,0x8e,0x4c,0x6c,0x5b,0x6c,0x39,0x9c,0x31,0x10,0x76,0x55,0x55,0x10,0x00, +0x53,0xc3,0x72,0xbd,0x5d,0xc3,0x63,0x3a,0x4c,0x3d,0x84,0xcc,0x8c,0x39,0x7d,0x2b, +0x9b,0xbc,0xab,0xc1,0xc4,0xab,0x7c,0xac,0x93,0x32,0x3e,0x1b,0x84,0x2c,0x6b,0x2a, +0x9c,0x31,0x10,0x59,0x44,0x44,0x10,0x00,0x22,0xac,0x8e,0x2c,0x7b,0x2a,0x6b,0xd2, +0xc5,0x43,0x95,0xc1,0xae,0x2c,0x8c,0x1a,0x94,0x34,0x7b,0x92,0x9e,0x92,0xab,0x2d, +0x7b,0x43,0x9b,0xa1,0xad,0xb4,0x8b,0xcb,0x9c,0x31,0x10,0xd0,0x54,0x54,0x00,0x00, +0xb5,0xb3,0xb3,0xb4,0xbd,0x3b,0xb4,0xa1,0xab,0xc3,0xab,0x1c,0xa9,0xc3,0xa5,0x31, +0x95,0xa4,0x93,0xb4,0xa4,0x3a,0x81,0xcb,0x92,0xc4,0x6b,0xb3,0x7c,0x3b,0x65,0x3a, +0x9c,0x31,0x10,0x11,0x44,0x34,0x10,0x00,0x83,0xda,0xac,0xb4,0x9b,0x51,0xcc,0x57, +0xd3,0x2c,0xb7,0x27,0x8b,0x4a,0xbc,0x46,0x5d,0x38,0x94,0xb9,0x63,0x27,0x94,0xa5, +0xc4,0x28,0xac,0x46,0x9e,0xb7,0xbb,0x3a,0x9c,0x31,0x10,0x3c,0x53,0x44,0x00,0x00, +0x93,0x48,0x94,0x71,0x8b,0x78,0x76,0x5b,0xa9,0x73,0xac,0xa8,0x94,0x4e,0xa4,0x32, +0xa1,0x92,0xb4,0x6c,0xc3,0x87,0x78,0x73,0x91,0x3d,0x9e,0x64,0x8c,0x82,0x91,0xca, +0x9c,0x31,0x10,0xad,0x43,0x44,0x10,0x00,0x9e,0x99,0x3b,0xa4,0xad,0x99,0x8e,0x8c, +0x79,0x98,0x7e,0xa1,0x4b,0x89,0xb3,0x4a,0x6d,0x53,0x6b,0x34,0x3e,0xad,0x69,0x94, +0x50,0xb4,0x49,0xd7,0x53,0xab,0x3a,0x68,0x9c,0x31,0x10,0x7c,0x54,0x44,0x10,0x00, +0x55,0xc3,0x3c,0xcc,0x73,0x42,0x5d,0x4a,0x54,0xbc,0x5c,0x39,0x5e,0x18,0x5c,0x9d, +0x6d,0x1e,0x7d,0x0c,0x85,0x13,0x94,0xab,0x8a,0x9b,0x7a,0x18,0x4c,0x2c,0x4a,0x8a, +0x9c,0x31,0x10,0x88,0x53,0x44,0x10,0x00,0x31,0x44,0x48,0x6c,0x31,0x4e,0x69,0x73, +0x62,0x73,0x79,0x97,0x72,0x86,0x63,0x87,0x8a,0x9c,0x51,0xc7,0x60,0x84,0x64,0xc8, +0x5b,0x54,0x42,0x76,0x2b,0xa7,0x5b,0x76,0x9c,0x31,0x10,0x47,0x54,0x45,0x00,0x00, +0x34,0x3c,0x52,0xb5,0x64,0xa9,0x5c,0xaa,0x69,0xbc,0x5c,0x33,0x33,0x3a,0x49,0x33, +0x5b,0x2d,0x4c,0x2c,0x54,0x21,0x73,0x43,0x72,0xdd,0x71,0xdb,0x6b,0x59,0x7b,0xdc, +0x9c,0x31,0x10,0x47,0x54,0x45,0x00,0x00,0x62,0xd5,0x3b,0xd1,0x5d,0x62,0x64,0xab, +0x82,0x44,0x74,0x5a,0x6b,0x3a,0x6c,0xdc,0x7d,0xa9,0x7d,0xb3,0x8b,0x35,0x7c,0x2a, +0x93,0x12,0x94,0x3c,0x92,0xa3,0x94,0xc3,0x9c,0x31,0x10,0x96,0x43,0x45,0x00,0x00, +0xaa,0x57,0x8a,0x75,0xa3,0x67,0xab,0x68,0x8c,0x79,0xa1,0x64,0xbc,0x96,0xb2,0x8b, +0xdd,0x96,0xc3,0x93,0xdc,0x7b,0xbc,0xa7,0xda,0x66,0xc3,0x45,0xc1,0x3a,0x7b,0x69, +0x9c,0x31,0x10,0x5f,0x54,0x55,0x00,0x00,0x7b,0x41,0x92,0x32,0xa4,0x3d,0xab,0x5c, +0xb3,0x51,0xae,0x3b,0xa4,0x3c,0x9c,0xdb,0xb5,0xb9,0xad,0x24,0x9c,0x4d,0xb5,0x2a, +0x9d,0x12,0xa4,0x5c,0x93,0xdc,0xbc,0xcb,0x9c,0x31,0x10,0x0a,0x65,0x64,0x00,0x00, +0x99,0xb2,0x92,0x23,0x85,0xb4,0x81,0xb3,0x7d,0xb9,0x81,0xb4,0x75,0xbd,0x79,0xb1, +0x85,0xba,0x89,0xd4,0x91,0xc2,0x8d,0xd9,0xc2,0xcb,0xf6,0xae,0x45,0xaa,0x11,0x22, +0x9c,0x31,0x10,0x4d,0x55,0x54,0x00,0x00,0x4c,0x13,0xa2,0x96,0x2a,0xa2,0x02,0x21, +0x61,0xba,0xa2,0x56,0x8a,0xe4,0x43,0x60,0x54,0x6b,0x8c,0x65,0x94,0x4b,0x74,0xb9, +0x74,0xb2,0x74,0x9c,0x5c,0x1c,0x5b,0x92,0x9c,0x31,0x10,0x8b,0x43,0x53,0x00,0x00, +0x31,0x99,0x3d,0x25,0x74,0xb5,0x78,0xbb,0x95,0x42,0xb0,0xca,0x92,0x4d,0x91,0xcb, +0xba,0x42,0x8a,0xba,0x5d,0xb4,0x55,0xac,0x5e,0x2b,0x41,0xb2,0x26,0x33,0x0d,0xb4, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_PAIR_ENABLE.txt b/config/_default_cfg_src_/res/en/SOUND_PAIR_ENABLE.txt new file mode 100644 index 0000000..c223a0a --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_PAIR_ENABLE.txt @@ -0,0 +1,195 @@ +0x9c,0x31,0x10,0xd1,0x42,0x22,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x81,0xdb, +0x8d,0xe3,0xa6,0x5b,0xa1,0x9d,0xdd,0x92,0xb6,0x42,0xa1,0xe4,0xa2,0xda,0xa1,0x64, +0xa6,0xd9,0x4d,0x5b,0x51,0xe4,0x56,0xd3,0x9c,0x31,0x10,0x20,0xb8,0x77,0x20,0x00, +0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x81,0xdb,0x81,0xdb, +0x92,0x24,0xa9,0x21,0xc6,0xdb,0xb9,0xab,0xaa,0x23,0xb1,0xdc,0xb6,0x1a,0xa5,0xdc, +0x9c,0x31,0x10,0x03,0xa7,0x65,0x00,0x00,0x9f,0x29,0x52,0xec,0x2f,0x2a,0x14,0xe9, +0x0a,0xed,0x0c,0xee,0x12,0xed,0x06,0xe9,0x0f,0x09,0x22,0xed,0x31,0x0d,0x32,0xed, +0x58,0xee,0x5c,0x61,0x4f,0x0a,0x58,0xcd,0x9c,0x31,0x10,0xe2,0x98,0x87,0x20,0x00, +0x43,0x3b,0x3b,0xb4,0x6b,0xb9,0x5b,0xdc,0x5c,0xcd,0x4b,0x48,0x34,0xac,0x2c,0x93, +0x53,0x33,0x74,0x43,0xa9,0x9a,0xe3,0xa3,0xa9,0xc4,0xec,0x44,0xaa,0x20,0x9c,0xce, +0x9c,0x31,0x10,0x6c,0x98,0x99,0x40,0x00,0x61,0xb3,0xa4,0xb2,0x5a,0xe3,0x94,0xd4, +0x72,0x1a,0xae,0xc3,0x81,0xc5,0x9a,0x9b,0xb0,0xb8,0x63,0x4d,0xa2,0xb3,0xa9,0xc2, +0xa2,0x5c,0x6a,0xc3,0xd3,0x3a,0x7a,0xbb,0x9c,0x31,0x10,0x7e,0x99,0x98,0x40,0x00, +0xdb,0xc4,0x93,0xc3,0xcb,0xab,0x8a,0xdc,0xdb,0xd0,0x7b,0x14,0x9b,0xab,0xa4,0x55, +0xad,0xca,0x8a,0xc9,0xa5,0xcd,0x9a,0x93,0x7b,0x88,0xab,0xde,0x74,0x42,0xab,0x28, +0x9c,0x31,0x10,0x56,0x99,0xa8,0x40,0x00,0x54,0xc6,0xbb,0xb5,0x83,0x99,0x9b,0xbb, +0x8b,0xc3,0x85,0xd4,0x8c,0x53,0x7d,0x38,0x7c,0x1a,0x5b,0xb5,0x93,0x21,0x6b,0x45, +0x93,0xcc,0x6b,0x48,0x7d,0x32,0x72,0x2e,0x9c,0x31,0x10,0x45,0x99,0x99,0x50,0x00, +0x64,0xbc,0x8b,0x33,0x5d,0x39,0xa2,0x9c,0x63,0xa3,0xbb,0x43,0x5c,0x42,0x94,0x43, +0xa4,0xc2,0x62,0xbc,0xa5,0xa2,0x63,0x14,0x76,0x3b,0x64,0x64,0x65,0xbb,0x74,0x1a, +0x9c,0x31,0x10,0x49,0x88,0x99,0x40,0x00,0x53,0xbb,0x83,0x3b,0x5b,0x92,0x33,0xb2, +0x6c,0x64,0x4d,0x33,0x7b,0x0c,0x6f,0x51,0x83,0x35,0x3c,0x1b,0x7a,0xc9,0x8b,0xd3, +0x8a,0xac,0xb4,0x55,0xbb,0xe2,0x64,0x8c,0x9c,0x31,0x10,0xed,0x88,0x98,0x30,0x00, +0x5a,0x9a,0xad,0xea,0x83,0xe2,0x3c,0x14,0x86,0x34,0x82,0x42,0x7c,0xba,0x4a,0xc3, +0x99,0xbd,0x64,0x1b,0x7b,0x28,0x93,0xcc,0x64,0x63,0x2a,0xbc,0x9c,0x3d,0x7b,0x39, +0x9c,0x31,0x10,0x8c,0xa8,0x98,0x40,0x00,0x8b,0x22,0x81,0x4a,0x76,0x95,0x5d,0x63, +0x69,0xe4,0x5d,0xda,0x99,0xe3,0x92,0x24,0x96,0x89,0x6e,0xa5,0x39,0xe2,0x59,0xd2, +0x92,0x1c,0xa1,0xe3,0xca,0x19,0x79,0xd4,0x9c,0x31,0x10,0x74,0xb7,0x87,0x30,0x00, +0x51,0x3e,0x52,0x52,0x71,0xa5,0x94,0x3a,0xbd,0xd8,0xb2,0xac,0x62,0x3c,0x49,0xb3, +0x46,0xd3,0x69,0x0b,0xc2,0x32,0xc5,0x35,0x99,0x49,0x4f,0x23,0x35,0xaa,0x39,0x3a, +0x9c,0x31,0x10,0x82,0xb8,0x98,0x30,0x00,0xa1,0xe3,0xd5,0x5b,0xc7,0x53,0x70,0xa4, +0x32,0x62,0x1c,0x9b,0x66,0x9b,0xd9,0xa5,0xd9,0xd9,0xa9,0xd3,0x4a,0x92,0x21,0xdb, +0x21,0x2d,0xb6,0x63,0xdd,0x51,0xcb,0x5c,0x9c,0x31,0x10,0x62,0xc9,0x97,0x30,0x00, +0x7e,0x49,0x55,0x4d,0x3c,0x6e,0x75,0x50,0xbc,0x89,0xa7,0x10,0x9a,0xf2,0x5f,0x29, +0x40,0xce,0x42,0xec,0xaa,0xf5,0xb8,0xaa,0xa9,0x29,0x80,0x4c,0x4d,0x8e,0x30,0x28, +0x9c,0x31,0x10,0x6c,0xca,0x97,0x20,0x00,0x75,0x49,0xbe,0xae,0xab,0x11,0xa6,0xf0, +0x5c,0xce,0x3d,0x10,0x3f,0x12,0xb2,0xe5,0xaa,0xe1,0xb4,0xf1,0x82,0xd5,0x4b,0x4d, +0x2e,0x69,0x7b,0x2a,0xb6,0xb0,0xa9,0x2d,0x9c,0x31,0x10,0xc0,0xca,0x87,0x30,0x00, +0xb0,0xc6,0x64,0xcd,0x3d,0x15,0x3a,0xf2,0xa9,0x0d,0xa4,0xa8,0xb5,0x05,0x96,0xcd, +0x4d,0x0c,0x2e,0x72,0x69,0x31,0xb2,0xb5,0xa1,0x2e,0xbe,0xc9,0x72,0xe9,0x3f,0x52, +0x9c,0x31,0x10,0xea,0xca,0x98,0x20,0x00,0x35,0x51,0x9a,0x2a,0xa1,0x65,0xb2,0x52, +0xa9,0x9c,0x55,0xdb,0x2d,0x9b,0x5a,0x92,0xb1,0x8d,0x96,0x11,0xc1,0xdc,0x81,0xe3, +0x42,0x5b,0x2c,0xdb,0x86,0x6c,0xa5,0x6a,0x9c,0x31,0x10,0xd8,0xca,0x97,0x30,0x00, +0xa5,0x52,0xba,0xa9,0x63,0x09,0x37,0x31,0x45,0x35,0xa6,0xee,0x96,0xcc,0xb9,0x24, +0x9c,0xcd,0x4e,0xed,0x2c,0x6a,0x71,0x45,0xaa,0xad,0x95,0x08,0xc4,0xb2,0x7a,0xf0, +0x9c,0x31,0x10,0xed,0xc9,0x96,0x30,0x00,0x3f,0x2e,0x32,0x2c,0x98,0xd6,0x9a,0x51, +0xa7,0x52,0xb6,0x74,0x63,0x0d,0x35,0x30,0x4b,0x95,0xac,0xd5,0x8e,0xee,0xbd,0x4d, +0x98,0xe9,0x53,0x2d,0x2a,0x29,0x75,0xc6,0x9c,0x31,0x10,0xd8,0xca,0x97,0x30,0x00, +0xa6,0xc9,0x97,0x21,0xbe,0xc9,0x7e,0xed,0x40,0xe9,0x2e,0x44,0x98,0xcd,0x98,0x91, +0xab,0x2d,0xb4,0xb1,0x6a,0xed,0x32,0xf0,0x47,0x35,0xaa,0xd1,0x90,0xf1,0xbb,0x15, +0x9c,0x31,0x10,0x6c,0xca,0x97,0x20,0x00,0x9e,0xcd,0x5b,0x0d,0x2c,0xb5,0x69,0x8c, +0xa8,0xe5,0x93,0x4d,0xbf,0x09,0x89,0x09,0x4f,0x0d,0x2a,0x89,0x8d,0x26,0xa0,0xad, +0x9d,0x2d,0xbc,0xa5,0x74,0xed,0x41,0x0d,0x9c,0x31,0x10,0x57,0xca,0x96,0x30,0x00, +0x32,0xa5,0xa0,0xcc,0x98,0xb1,0xa9,0x2d,0xae,0xad,0x69,0x11,0x34,0xed,0x47,0x56, +0xae,0xb5,0x92,0xcd,0xb2,0xee,0xa0,0xd1,0x5d,0x0d,0x2a,0xf1,0x63,0x94,0xad,0x0d, +0x9c,0x31,0x10,0xdb,0xca,0x95,0x30,0x00,0x91,0x17,0xb6,0xea,0x92,0xd7,0x54,0xf6, +0x28,0x77,0x77,0x63,0xab,0x13,0x95,0x77,0xb9,0x17,0x87,0x16,0x4b,0x07,0x26,0x76, +0x8f,0x24,0xa7,0x06,0x9b,0x67,0xb8,0xe6,0x9c,0x31,0x10,0xe3,0xca,0x96,0x20,0x00, +0x7c,0xed,0x44,0xc9,0x2c,0x44,0x96,0xa5,0xa4,0xcd,0xa1,0x4d,0xb3,0x09,0x79,0x0d, +0x3f,0x0d,0x30,0x8d,0x9a,0xad,0xa2,0xcd,0xa5,0x4d,0xae,0xed,0x75,0x0d,0x38,0xed, +0x9c,0x31,0x10,0xcd,0xc9,0x85,0x20,0x00,0x32,0x46,0xa7,0x0a,0xa1,0x38,0xa6,0xb5, +0xad,0x87,0x76,0xa7,0x35,0x76,0x37,0x59,0xad,0x0c,0xa1,0x48,0xa5,0xc6,0xab,0x98, +0x74,0x88,0x32,0x57,0x38,0x49,0xab,0x1b,0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00, +0xa0,0xf0,0xa3,0xc9,0xaa,0xed,0x76,0xb1,0x36,0xa9,0x30,0xae,0xa6,0x76,0xa5,0x10, +0xa1,0x6c,0xa8,0xcc,0x7c,0xad,0x3c,0xc9,0x2c,0xa6,0x9e,0xd1,0xa8,0xd1,0x9d,0x2d, +0x9c,0x31,0x10,0xbf,0xc9,0x74,0x00,0x00,0xa8,0xcd,0x84,0xcd,0x42,0xe6,0x22,0x21, +0x91,0x28,0xaf,0x51,0x9a,0xf1,0xa8,0x6d,0x8f,0x0d,0x53,0x29,0x1a,0x48,0x77,0x85, +0xb7,0x09,0x9e,0xae,0xa4,0xcd,0x9b,0x2d,0x9c,0x31,0x10,0x23,0xca,0x63,0x10,0x00, +0x66,0x7c,0x20,0x6d,0x51,0xbb,0xb5,0x51,0xa5,0x72,0xa0,0x9b,0xa0,0x7c,0x7c,0x6b, +0x31,0x8c,0x2b,0x7d,0xa1,0x55,0xb1,0x9c,0x9e,0x7a,0xa2,0x62,0x92,0x8a,0x53,0x7a, +0x9c,0x31,0x10,0x2d,0xc9,0x63,0x00,0x00,0x17,0x20,0x72,0xd1,0xb6,0x6b,0xa7,0x4c, +0x9d,0xac,0x9d,0x73,0x78,0x6b,0x28,0xac,0x31,0x7d,0xa4,0x3b,0xb6,0xca,0xa2,0x52, +0x9d,0x7b,0x94,0x9b,0x56,0x5a,0x15,0x59,0x9c,0x31,0x10,0x8a,0xc9,0x52,0x00,0x00, +0x61,0xc1,0xb7,0x3b,0xb5,0xa5,0x9b,0x84,0x9d,0x53,0x88,0x9a,0x38,0x82,0x18,0x4d, +0x83,0x9e,0xbd,0x76,0xb1,0x64,0x97,0xab,0x9d,0x52,0x7c,0x83,0x25,0x95,0x23,0x76, +0x9c,0x31,0x10,0x17,0xc8,0x52,0x00,0x00,0x96,0x64,0xc2,0xba,0xad,0x29,0x96,0xc1, +0x9d,0x52,0x76,0x73,0x21,0xa5,0x29,0x7d,0x99,0x5b,0xc1,0xaa,0xab,0x39,0x95,0xb1, +0x9d,0x5a,0x76,0x83,0x24,0x95,0x26,0x75,0x9c,0x31,0x10,0x7f,0xc7,0x52,0x00,0x00, +0x93,0xb4,0xc1,0x52,0xb1,0x99,0x96,0x69,0x9f,0x92,0x80,0xcb,0x32,0xd5,0x1a,0x96, +0x7c,0xdd,0xbd,0x24,0xbb,0xc3,0x97,0x52,0x9a,0x12,0x8c,0xdb,0x49,0xb3,0x11,0x92, +0x9c,0x31,0x10,0x0f,0xc8,0x42,0x00,0x00,0x54,0xc3,0xb2,0x2d,0xc6,0xbb,0xa3,0x42, +0x98,0x8b,0x9a,0x8c,0x68,0x54,0x1e,0xad,0x25,0x6b,0x93,0x62,0xc4,0xb1,0xb8,0x33, +0x95,0xd5,0x9b,0x2c,0x8c,0xaa,0x44,0x71,0x9c,0x31,0x10,0x8a,0xc9,0x52,0x00,0x00, +0x10,0x59,0x50,0xba,0xb5,0x34,0xca,0xb4,0xa5,0x53,0x97,0x8a,0x9d,0x82,0x79,0x5b, +0x29,0xab,0x12,0x3d,0x79,0xad,0xc2,0x6b,0xc1,0x72,0x97,0x9b,0x99,0x4b,0x9d,0xa3, +0x9c,0x31,0x10,0x17,0xc8,0x52,0x00,0x00,0x66,0x43,0x1f,0xac,0x1b,0x6d,0x8b,0x53, +0xc5,0xca,0xbb,0x0a,0x97,0xdc,0x9b,0x3b,0xa0,0x7b,0x62,0xa3,0x1b,0x55,0x1d,0xa5, +0x8b,0x42,0xc8,0xb1,0xb9,0x4b,0x95,0x94,0x9c,0x31,0x10,0x8a,0xc9,0x52,0x00,0x00, +0x9b,0x7a,0xa2,0x6b,0x67,0x94,0x1f,0x7a,0x16,0x5c,0x7c,0x9d,0xc5,0x72,0xbd,0x61, +0x97,0xa4,0x9b,0x64,0xa9,0x7a,0x7b,0x8b,0x30,0x73,0x0d,0x50,0x5a,0xc2,0xb9,0x4e, +0x9c,0x31,0x10,0x05,0xc9,0x53,0x00,0x00,0xc3,0x7b,0x9b,0xaa,0x93,0x53,0xac,0x85, +0x96,0x9a,0x4a,0x52,0x12,0x96,0x2a,0xa6,0x99,0x29,0xc6,0xa2,0xa9,0x9d,0x91,0x4a, +0xa8,0x82,0xb1,0x93,0x76,0x6a,0x2a,0x69,0x9c,0x31,0x10,0xa7,0xc9,0x64,0x00,0x00, +0x0c,0xa9,0x57,0x65,0xb4,0xf2,0xbc,0x91,0x96,0xe5,0x97,0x30,0xb6,0xf1,0xa2,0xa9, +0x56,0xc9,0x1b,0x4e,0x1a,0xa5,0x7a,0x95,0xbd,0x11,0xaf,0x45,0x93,0x16,0xa2,0xb5, +0x9c,0x31,0x10,0x22,0xc8,0x74,0x00,0x00,0xba,0x4d,0x92,0xcd,0x47,0x0d,0x1b,0xad, +0x27,0x0e,0x86,0x54,0xba,0x68,0xa8,0xc9,0x93,0x32,0xa9,0x49,0xbb,0x0e,0x8d,0x10, +0x48,0xc9,0x21,0x31,0x26,0xae,0x7e,0x58,0x9c,0x31,0x10,0x92,0xc8,0x87,0x10,0x00, +0xb8,0x4d,0xa8,0xad,0x8c,0xcd,0xa2,0xcd,0xbc,0xad,0x94,0xd1,0x50,0xa9,0x2b,0x2d, +0x24,0x24,0x6c,0xaa,0xb0,0x91,0xac,0xc5,0x8e,0xb1,0x9a,0xa9,0xbc,0xcd,0xa4,0xcd, +0x9c,0x31,0x10,0x4b,0xc8,0x97,0x20,0x00,0x64,0xed,0x3a,0xed,0x26,0xad,0x47,0x6c, +0x9c,0xe5,0xb5,0x11,0x94,0xe9,0x88,0xed,0xae,0xed,0xb8,0xd2,0x84,0xf1,0x4e,0xc9, +0x33,0x4d,0x2c,0x88,0x6e,0xd6,0xae,0xd0,0x9c,0x31,0x10,0x3b,0xc7,0x87,0x20,0x00, +0xa8,0xd2,0x87,0x1c,0x95,0x1e,0xb8,0xe4,0xaa,0xdd,0x72,0xd1,0x4a,0xe1,0x35,0x20, +0x39,0x76,0x7c,0xd0,0xae,0xc6,0xa0,0xe8,0x87,0x22,0x9b,0x24,0xb8,0xce,0xa2,0xe8, +0x9c,0x31,0x10,0x23,0xc7,0x97,0x20,0x00,0x6c,0xda,0x49,0x20,0x32,0xdd,0x3b,0xa5, +0x84,0xc5,0xb1,0x25,0x9e,0xe1,0x84,0xdd,0x9b,0x15,0xb8,0xe5,0xa2,0xdd,0x6e,0xd9, +0x4b,0x21,0x37,0x1c,0x3d,0x66,0x7c,0xcc,0x9c,0x31,0x10,0xe1,0xc6,0x88,0x10,0x00, +0xac,0xe3,0xa0,0xeb,0x89,0x13,0x96,0xdb,0xb5,0x63,0xa8,0x9c,0x75,0x22,0x4e,0xdc, +0x37,0x5a,0x37,0x6d,0x72,0x91,0xa8,0x94,0xa6,0xea,0x8a,0xd3,0x8e,0xd3,0xae,0xa3, +0x9c,0x31,0x10,0x4e,0xc7,0x87,0x00,0x00,0xb0,0xa1,0x82,0xd9,0x56,0xdd,0x3d,0x21, +0x30,0x4c,0x5e,0xf6,0x9c,0xd4,0xaa,0xd5,0x90,0xe5,0x8a,0xdd,0xa4,0x99,0xb5,0x1d, +0x96,0xdd,0x64,0xe1,0x46,0xd9,0x34,0xa1,0x9c,0x31,0x10,0xfa,0xc7,0x87,0x10,0x00, +0x47,0x50,0x84,0xe2,0xaa,0xe4,0x9e,0xd2,0x8a,0xe1,0x96,0xe1,0xaf,0x19,0xa4,0x99, +0x7c,0xe5,0x5a,0xd5,0x3f,0x1d,0x32,0xa5,0x5e,0xe4,0x8e,0xca,0x9e,0xf0,0x9e,0xd5, +0x9c,0x31,0x10,0x67,0xc6,0x87,0x10,0x00,0xa4,0xdd,0xa8,0x5d,0xa1,0x21,0x86,0xd1, +0x6a,0xe5,0x54,0xd9,0x3c,0xa2,0x43,0x8c,0x72,0xa2,0x91,0x24,0x9c,0xd2,0xa2,0xe1, +0xad,0x1d,0xaa,0xdd,0x96,0xdc,0x7a,0xda,0x9c,0x31,0x10,0x5b,0xc6,0x77,0x00,0x00, +0x64,0xea,0x4f,0x0c,0x36,0x11,0x51,0x35,0x7e,0x92,0x97,0x14,0xa0,0xeb,0xa6,0xd3, +0xaa,0xdb,0xa3,0x1a,0x8c,0xe4,0x74,0xcb,0x60,0xeb,0x49,0x13,0x38,0xec,0x5a,0xd9, +0x9c,0x31,0x10,0x92,0xb5,0x87,0x00,0x00,0x88,0x2e,0xb2,0xd9,0xc6,0xa5,0xd0,0xc2, +0xd6,0xb3,0xc2,0xbc,0x90,0xba,0x5e,0xb4,0x36,0xc2,0x06,0xb3,0x01,0x43,0x4c,0x1c, +0x94,0xe2,0xbc,0xa3,0xcc,0x4b,0xd6,0xb3,0x9c,0x31,0x10,0xa9,0xb5,0x86,0x10,0x00, +0xd0,0xbc,0xb2,0xb2,0x80,0xcc,0x5a,0xab,0x34,0xc3,0x06,0x44,0x0b,0x21,0x54,0xdd, +0x98,0xa1,0xbe,0xc4,0xce,0xba,0xd4,0xbc,0xcc,0xc2,0xac,0xb5,0x7c,0xc1,0x54,0x34, +0x9c,0x31,0x10,0x95,0xb5,0x76,0x00,0x00,0x2d,0x2a,0x04,0x0b,0x13,0x63,0x5c,0xa2, +0x9d,0x0d,0xc2,0xe1,0xd2,0x94,0xd8,0xe3,0xca,0xd2,0xa6,0xe3,0x78,0xd4,0x52,0xa2, +0x28,0xd4,0x06,0x5a,0x19,0x1d,0x5c,0x99,0x9c,0x31,0x10,0x10,0xb4,0x66,0x00,0x00, +0x9d,0x15,0xc2,0xe1,0xd2,0x95,0xd4,0xd9,0xc9,0x5d,0xa6,0x90,0x7b,0x25,0x50,0x5a, +0x2d,0x64,0x10,0x09,0x1f,0x6e,0x5c,0x88,0x9c,0xe5,0xc7,0x19,0xd4,0xdd,0xd6,0xd9, +0x9c,0x31,0x10,0x38,0xb4,0x56,0x00,0x00,0xc5,0x1d,0xa4,0xe1,0x7d,0x0d,0x56,0xa1, +0x31,0x55,0x12,0x59,0x1b,0xae,0x54,0x89,0x96,0xe5,0xc2,0xd9,0xd3,0x1d,0xd4,0x9a, +0xc5,0x5c,0xa6,0x92,0x7d,0x23,0x54,0x53,0x9c,0x31,0x10,0xb4,0xb4,0x55,0x00,0x00, +0x2f,0x63,0x12,0x13,0x19,0xb4,0x52,0x83,0x92,0xec,0xbe,0xd2,0xd3,0x24,0xd6,0xd2, +0xc4,0xe4,0xa6,0xda,0x80,0xdc,0x5c,0x9a,0x37,0x1c,0x18,0x51,0x1b,0xa5,0x4e,0x90, +0x9c,0x31,0x10,0xb4,0xb4,0x55,0x00,0x00,0x8c,0xde,0xb8,0xd9,0xce,0xdc,0xd4,0xda, +0xc7,0x5d,0xac,0x9a,0x86,0xe4,0x60,0x92,0x39,0x24,0x1a,0x52,0x1b,0xac,0x4c,0xca, +0x86,0xa4,0xb4,0xd2,0xcc,0xe3,0xd4,0xd3,0x9c,0x31,0x10,0xa9,0xb4,0x43,0x00,0x00, +0xc6,0x96,0xad,0x44,0x89,0x76,0x62,0x49,0x3c,0xb1,0x1d,0x45,0x1a,0xd9,0x4a,0x40, +0x86,0x71,0xb4,0x6d,0xcc,0x71,0xd3,0x69,0xc3,0x6d,0xad,0x49,0x8d,0x51,0x6a,0x49, +0x9c,0x31,0x10,0xb4,0xb4,0x55,0x00,0x00,0x43,0x1b,0x22,0xdb,0x1d,0x63,0x46,0x9b, +0x7e,0x9b,0xac,0xdb,0xc6,0x9c,0xd0,0xd0,0xc2,0xeb,0xb0,0x8d,0x92,0xa2,0x6e,0xd3, +0x45,0x1b,0x23,0x1b,0x19,0x63,0x40,0x9b,0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00, +0x79,0x42,0xaa,0x88,0xc7,0x85,0xd2,0x75,0xc8,0x85,0xb4,0x45,0x91,0x59,0x6a,0x64, +0x42,0xb6,0x23,0x95,0x18,0xba,0x42,0x44,0x7c,0x35,0xae,0x75,0xcb,0x75,0xd4,0xa5, +0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00,0xc7,0x85,0xb2,0x45,0x8f,0x45,0x69,0x75, +0x43,0xa6,0x24,0x94,0x17,0x99,0x3f,0x49,0x78,0x35,0xaa,0x95,0xc6,0x55,0xd1,0xb5, +0xc7,0x75,0xb4,0x49,0x92,0x49,0x6c,0x85,0x9c,0x31,0x10,0x6e,0xb4,0x32,0x00,0x00, +0x45,0x86,0x25,0xb4,0x16,0x89,0x3c,0x49,0x75,0x25,0xa8,0xa1,0xc5,0x74,0xd1,0xa6, +0xc8,0x65,0xb6,0x55,0x94,0x39,0x6d,0x85,0x46,0x95,0x26,0xb4,0x17,0x4a,0x3b,0x59, +0x9c,0x31,0x10,0xa9,0xb4,0x43,0x00,0x00,0x74,0x2d,0xa7,0x89,0xc4,0x6d,0xcf,0x8d, +0xc5,0x2d,0xb5,0x6d,0x95,0x4d,0x71,0xad,0x4b,0x69,0x2c,0xad,0x1a,0x0d,0x3b,0x76, +0x70,0x0c,0xa1,0xad,0xbf,0x4d,0xcb,0xad,0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00, +0xc3,0x45,0xb3,0x71,0x97,0x59,0x75,0xa5,0x50,0x65,0x30,0xa1,0x1c,0x35,0x37,0x79, +0x6b,0x56,0x9d,0xa4,0xbe,0x65,0xcc,0x95,0xc5,0x34,0xb6,0x92,0x99,0x54,0x76,0xa5, +0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00,0x51,0x54,0x31,0xa6,0x1d,0x21,0x37,0x88, +0x6b,0x4a,0x9d,0xb4,0xbf,0x56,0xcd,0x94,0xc5,0x35,0xb5,0x91,0x98,0x60,0x76,0xb6, +0x52,0x48,0x33,0xa6,0x1f,0x21,0x37,0x88,0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00, +0x6a,0x4a,0x9c,0xa4,0xbd,0x55,0xcb,0x91,0xc4,0x35,0xb4,0x91,0x99,0x54,0x79,0xa6, +0x56,0x55,0x36,0x95,0x22,0x35,0x39,0x88,0x69,0x56,0x9a,0xa4,0xbb,0x61,0xca,0x95, +0x9c,0x31,0x10,0xf3,0xb5,0x32,0x00,0x00,0xc3,0x35,0xb2,0xa2,0x99,0x54,0x7a,0xa6, +0x59,0x55,0x39,0xa5,0x24,0x20,0x38,0x84,0x67,0x56,0x95,0xa4,0xb5,0x56,0xc5,0x94, +0xc1,0x44,0xb3,0x92,0x9a,0x54,0x7b,0xb6,0x9c,0x31,0x10,0x7f,0xb5,0x31,0x00,0x00, +0x5b,0x23,0x3d,0xca,0x29,0x11,0x3a,0xcb,0x67,0x2c,0x94,0xd3,0xb5,0x2a,0xc4,0xca, +0xc0,0x9a,0xb3,0x52,0x99,0x33,0x79,0xd3,0x5a,0xab,0x3f,0xd2,0x2c,0x11,0x3a,0x51, +0x9c,0x31,0x10,0xeb,0xb5,0x22,0x00,0x00,0x65,0x55,0x91,0xa5,0xb2,0x55,0xc1,0x91, +0xbf,0x45,0xb2,0xa6,0x9a,0x65,0x7a,0xa5,0x5d,0x59,0x44,0x96,0x32,0x31,0x3d,0xb1, +0x65,0x64,0x90,0xa6,0xb0,0x59,0xbe,0x89,0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00, +0xbd,0x3a,0xb0,0xb4,0x98,0x72,0x7a,0xc1,0x5d,0x55,0x45,0x96,0x34,0x05,0x3f,0xd2, +0x67,0x60,0x93,0xb5,0xb3,0x59,0xbf,0x75,0xbc,0x41,0xac,0x91,0x91,0x71,0x71,0x95, +0x9c,0x31,0x10,0xfa,0xb4,0x21,0x00,0x00,0x56,0xb2,0x44,0x40,0x3a,0x99,0x4b,0x50, +0x72,0xaa,0x9a,0xd1,0xb4,0x2d,0xbd,0x45,0xb8,0x22,0xa5,0x3b,0x87,0xba,0x67,0x44, +0x4f,0x3c,0x41,0x43,0x42,0xaa,0x5e,0x3a,0x9c,0x31,0x10,0x03,0xa3,0x11,0x00,0x00, +0x8e,0xa5,0xd4,0xc0,0xf8,0x46,0xf9,0xb5,0xd8,0xba,0x9e,0xc5,0x5d,0x34,0x25,0xb5, +0x07,0xb1,0x0c,0x11,0x3a,0xc1,0x86,0xc1,0xcc,0x46,0xf2,0xa5,0xf5,0xa5,0xd6,0xa9, +0x9c,0x31,0x10,0xb6,0xa2,0x21,0x00,0x00,0x9a,0xa9,0x57,0xad,0x21,0xce,0x08,0x30, +0x16,0x08,0x4a,0x85,0x91,0x89,0xd1,0xc2,0xf4,0xb1,0xf3,0x52,0xc9,0x30,0x82,0x8d, +0x39,0x90,0x0a,0x56,0x06,0xad,0x2c,0x6c,0x9c,0x31,0x10,0xbb,0xb2,0x11,0x00,0x00, +0x79,0x32,0xa0,0x06,0xbb,0xa5,0xc0,0xd8,0xaa,0xc6,0x83,0xb1,0x5b,0x18,0x42,0xa5, +0x41,0xa1,0x57,0x3a,0x7b,0x49,0xa0,0x92,0xb9,0xa1,0xbc,0x28,0xa7,0x45,0x82,0xc6, +0x9c,0x31,0x10,0x3a,0xa2,0x22,0x00,0x00,0x3f,0x6d,0x15,0x4d,0x15,0x91,0x3a,0x51, +0x77,0x71,0xb3,0x6d,0xd9,0x85,0xdb,0x69,0xba,0x6d,0x84,0x51,0x51,0x8d,0x32,0x6d, +0x32,0x69,0x4e,0x2e,0x7a,0x8d,0xa4,0x28,0x9c,0x31,0x10,0x55,0x92,0x22,0x00,0x00, +0xfd,0x13,0xfd,0x23,0xcd,0x1b,0x80,0x6a,0x3b,0x1b,0x16,0x0a,0x1f,0x1c,0x49,0x25, +0x82,0xda,0xb6,0x91,0xce,0xf4,0xc6,0x51,0xa1,0x22,0x70,0xa4,0x4b,0x1c,0x3c,0xdc, +0x9c,0x31,0x10,0x62,0x83,0x23,0x00,0x00,0x14,0x93,0x52,0xe3,0x98,0xdb,0xcb,0x1b, +0xd6,0xe3,0xba,0x9b,0x8a,0x8b,0x58,0xe3,0x3f,0x1b,0x3e,0xdb,0x56,0xdb,0x7a,0xe3, +0x98,0xdb,0xa8,0xd3,0xa7,0x13,0x95,0x76,0x9c,0x31,0x10,0x31,0x72,0x23,0x00,0x00, +0x74,0x4c,0x4a,0x50,0x38,0xd1,0x48,0x9b,0x67,0x23,0x84,0xdb,0x99,0x24,0x9e,0xdb, +0x96,0xa3,0x86,0xdb,0x75,0x1b,0x63,0x23,0x5e,0xcb,0x6a,0xdb,0x78,0x93,0x83,0x1b, +0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00,0xd5,0x5b,0xda,0x1b,0xea,0x1b,0xe9,0x51, +0xcd,0x5b,0xae,0x15,0x80,0xe1,0x4e,0x0b,0x2a,0x2a,0x30,0xf5,0x59,0xac,0x85,0x90, +0xbe,0xa3,0xcd,0x54,0xd1,0xab,0xb2,0x24,0x9c,0x31,0x10,0xc2,0x51,0x21,0x00,0x00, +0x79,0x4c,0x61,0x32,0x56,0xcb,0x52,0x45,0x59,0xe1,0x82,0xca,0x9c,0xbb,0xbd,0x3c, +0xc7,0x10,0xcf,0x2b,0xb9,0x43,0x98,0x44,0x7c,0xbb,0x5e,0xc4,0x55,0x3d,0x5b,0x3b, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_POWER_OFF.txt b/config/_default_cfg_src_/res/en/SOUND_POWER_OFF.txt new file mode 100644 index 0000000..0b26eb1 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_POWER_OFF.txt @@ -0,0 +1,230 @@ +0x9c,0x31,0x10,0xab,0x22,0x11,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x81,0xdb,0x79,0x9b, +0x9d,0xc9,0x38,0xe5,0x3a,0xda,0x55,0xc1,0x91,0xcc,0xaa,0x26,0x0d,0xd1,0x7d,0x55, +0xb1,0x82,0xa9,0xe1,0xbd,0xdb,0xb5,0x69,0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00, +0x6d,0x56,0x8a,0x1e,0x86,0xe4,0x8e,0x21,0x88,0xe5,0x67,0x26,0x5a,0xe9,0x5e,0x22, +0x5d,0x68,0x5b,0x8d,0x39,0xa5,0x19,0x61,0x26,0xd1,0x12,0x15,0x45,0x9d,0x44,0xda, +0x9c,0x31,0x10,0x92,0xa8,0x66,0x20,0x00,0x7d,0xdb,0x7d,0xdb,0x86,0x1b,0x89,0x5a, +0xca,0x9b,0xa9,0x15,0x96,0x9c,0x98,0xd9,0xf6,0xd3,0xa5,0x5b,0x92,0x4a,0xc5,0x13, +0xc6,0x1c,0x29,0xdb,0x0a,0x1b,0x49,0xdb,0x9c,0x31,0x10,0xc6,0xa9,0x45,0x00,0x00, +0x38,0xf5,0x34,0xf5,0x5c,0xf1,0x42,0xf5,0x37,0x15,0x2e,0xd5,0x47,0x15,0x32,0xd0, +0x39,0x00,0x62,0xd6,0x3f,0x06,0x7d,0x04,0x58,0xc5,0x8f,0x46,0x70,0x71,0x99,0x75, +0x9c,0x31,0x10,0x89,0x99,0x56,0x10,0x00,0xa8,0xca,0xb3,0x13,0xc1,0x2d,0xb2,0x4a, +0xdd,0x6b,0xb2,0x8d,0xe5,0x51,0xb6,0xaa,0xa9,0x8e,0xa1,0xcb,0xc5,0xea,0x62,0x4b, +0xda,0x13,0x49,0x4c,0xa6,0x4b,0x81,0x2b,0x9c,0x31,0x10,0xca,0x89,0x67,0x20,0x00, +0x82,0x93,0xc5,0xe2,0xd2,0x63,0x75,0x25,0xe6,0x1c,0x99,0xa0,0xad,0xe2,0x86,0x1c, +0xcd,0x4c,0x65,0xd3,0x9a,0x52,0xb6,0x5b,0x80,0xe4,0x99,0xdb,0x9e,0x93,0x54,0x44, +0x9c,0x31,0x10,0x84,0x89,0x66,0x10,0x00,0x9f,0x54,0x2a,0x10,0xa9,0x4b,0x51,0xdd, +0x7a,0x13,0x91,0x5a,0x46,0x5c,0xb5,0x14,0x16,0x13,0xca,0xe1,0x21,0xe2,0xb4,0xa6, +0x3b,0x5b,0x91,0x19,0x79,0xdc,0xad,0xdb,0x9c,0x31,0x10,0x16,0x8a,0x56,0x10,0x00, +0x32,0x2b,0xa9,0x2a,0x4e,0xe3,0x5d,0x2a,0xb2,0x2b,0x5a,0x0d,0xc9,0xa1,0x46,0x22, +0x89,0xf4,0x61,0xe4,0x81,0xa2,0x5e,0x4b,0x7d,0x4a,0x66,0xac,0x95,0x4b,0x6a,0x09, +0x9c,0x31,0x10,0x31,0x88,0x56,0x10,0x00,0xab,0x0c,0x74,0x4c,0x86,0x6a,0x5f,0x53, +0x79,0x0c,0x9a,0xb4,0x59,0x4b,0xb1,0x88,0x4f,0x0d,0x95,0xc5,0x4a,0x08,0x95,0xeb, +0x31,0xad,0xc2,0x49,0x5d,0xf2,0xc5,0x8d,0x9c,0x31,0x10,0xe6,0xa9,0x56,0x10,0x00, +0x81,0x34,0x84,0xa9,0x68,0xec,0x72,0xc5,0x6b,0x09,0x89,0x09,0x7a,0x6e,0xab,0x44, +0x86,0xa8,0x84,0xeb,0x51,0x34,0x32,0x83,0x59,0x74,0x7c,0x72,0xc7,0x09,0xe3,0x2c, +0x9c,0x31,0x10,0x8d,0xb9,0x57,0x20,0x00,0xac,0xac,0x72,0xca,0x4f,0x2b,0x40,0xab, +0x4b,0x2a,0x95,0x0c,0xd6,0xa3,0xc1,0x0b,0xbd,0x2b,0x4a,0x43,0x37,0x6a,0x04,0xe3, +0x56,0xcb,0xc8,0xd6,0xbf,0x82,0xf4,0x12,0x9c,0x31,0x10,0x51,0xcb,0x57,0x20,0x00, +0x95,0x36,0x64,0xa0,0x57,0x55,0x30,0xa6,0x85,0x41,0x90,0xa5,0xa1,0x25,0xb6,0xe5, +0x9c,0xf5,0x78,0xe9,0x4b,0x49,0x38,0x79,0x77,0xa6,0x92,0x54,0x97,0x55,0xb2,0xd1, +0x9c,0x31,0x10,0x82,0xca,0x56,0x10,0x00,0xa6,0xf4,0x89,0x26,0x4c,0xc1,0x3c,0xf9, +0x57,0x70,0xa4,0x19,0x81,0xe6,0xb6,0x44,0xa1,0x46,0x9c,0xe1,0x5c,0xd8,0x41,0x71, +0x38,0x49,0xa7,0x85,0x76,0xb5,0xb2,0xf5,0x9c,0x31,0x10,0x1e,0xca,0x66,0x00,0x00, +0xa1,0x15,0xa2,0xd5,0x79,0x05,0x42,0xf4,0x34,0xa5,0x83,0xb2,0x90,0x14,0x91,0xc6, +0xb0,0x64,0x9d,0x35,0x94,0xf5,0x56,0xd9,0x3b,0x45,0x46,0x99,0xb3,0x16,0x6f,0x04, +0x9c,0x31,0x10,0x26,0xca,0x65,0x10,0x00,0xb6,0x5a,0x9a,0x9b,0xa1,0x63,0x7d,0x7b, +0x45,0x93,0x2d,0x3a,0x88,0xe3,0x96,0x03,0x87,0xe3,0xb3,0x33,0x98,0xa4,0x99,0x6b, +0x5f,0x73,0x36,0x9b,0x42,0x45,0xb1,0xaa,0x9c,0x31,0x10,0x35,0xca,0x54,0x00,0x00, +0x72,0xaa,0xaf,0x11,0xa0,0xf5,0xa0,0xe4,0x80,0xf5,0x48,0xf4,0x2e,0xc6,0x75,0x71, +0xa8,0x49,0x79,0xb5,0xb8,0x65,0x9d,0x55,0x9a,0xc5,0x68,0xf1,0x3b,0x36,0x34,0x56, +0x9c,0x31,0x10,0x1d,0xca,0x64,0x00,0x00,0xac,0xdc,0x80,0x22,0x9d,0xc4,0xab,0x52, +0xa2,0x83,0x89,0x83,0x4d,0x6b,0x2f,0x8d,0x62,0x89,0xb7,0x53,0x71,0xac,0xb6,0x4a, +0x9f,0x9c,0x9e,0x6b,0x71,0x7b,0x3e,0x93,0x9c,0x31,0x10,0x1d,0xca,0x64,0x00,0x00, +0x2e,0x39,0x99,0xdc,0x98,0x1c,0x87,0xc9,0xb3,0x44,0xa3,0x9b,0x8f,0x72,0x5c,0x76, +0x32,0x94,0x44,0x53,0xbb,0x9c,0x78,0x63,0xa3,0x8b,0xad,0x73,0xa2,0x73,0x7e,0x7c, +0x9c,0x31,0x10,0x30,0xca,0x52,0x00,0x00,0x49,0x7d,0x2b,0x6c,0x73,0xb0,0xb2,0x39, +0x77,0xc1,0xb1,0x49,0xa6,0x9d,0x9a,0x6d,0x6b,0x78,0x39,0x90,0x2f,0x41,0x9f,0xce, +0x95,0x2d,0x8b,0xbc,0xb2,0x54,0xa5,0x8e,0x9c,0x31,0x10,0x30,0xca,0x52,0x00,0x00, +0x8e,0x85,0x55,0x68,0x2d,0xa1,0x48,0x5e,0xb6,0x8d,0x82,0x78,0xa4,0x79,0xab,0x86, +0xa6,0x72,0x7b,0x89,0x3f,0x78,0x2b,0x65,0x77,0xb4,0xad,0x39,0x80,0xbe,0xaf,0x4d, +0x9c,0x31,0x10,0x18,0xca,0x62,0x00,0x00,0xaa,0x9b,0x9a,0x72,0x64,0x72,0x33,0x93, +0x33,0x3c,0xa2,0xbd,0x94,0x3c,0x91,0xa1,0xad,0x69,0xaa,0x7b,0x8a,0x8d,0x4e,0x6d, +0x2c,0x94,0x52,0x74,0xb5,0x6a,0x84,0x92,0x9c,0x31,0x10,0x18,0xca,0x62,0x00,0x00, +0xa2,0x63,0xac,0x94,0xa5,0x6c,0x76,0x83,0x3b,0x7a,0x2c,0x59,0x80,0xb9,0xaa,0x3b, +0x8b,0xb5,0xaa,0x54,0xae,0x8a,0x95,0x79,0x5a,0x6a,0x2e,0x9c,0x3c,0x4d,0xa9,0x9d, +0x9c,0x31,0x10,0xa2,0xc9,0x62,0x00,0x00,0x94,0x53,0x99,0x7a,0xaa,0x92,0xac,0x5b, +0x82,0x94,0x42,0x6c,0x28,0x7b,0x69,0xb9,0xb1,0x21,0x8b,0xda,0xa2,0x34,0xaf,0xac, +0xa0,0x73,0x65,0x6a,0x30,0xa9,0x36,0x12,0x9c,0x31,0x10,0xa2,0xc9,0x62,0x00,0x00, +0x99,0xdc,0x9c,0x35,0x96,0x9c,0xa7,0x7b,0xaf,0x63,0x89,0xa3,0x47,0x5c,0x2b,0x94, +0x5a,0x9c,0xab,0x3b,0x91,0xcb,0x9f,0x33,0xae,0xac,0xa2,0x63,0x6a,0x73,0x32,0xaa, +0x9c,0x31,0x10,0x8a,0xc9,0x52,0x00,0x00,0x34,0x10,0x91,0xe3,0xa0,0x2d,0x98,0x9c, +0xa6,0x7a,0xaf,0x5a,0x88,0xa4,0x47,0x5c,0x2b,0x8d,0x59,0xb5,0xa9,0x19,0x95,0xe0, +0xa1,0x29,0xb2,0xa3,0xa1,0x7c,0x66,0x54,0x9c,0x31,0x10,0x30,0xca,0x52,0x00,0x00, +0x2f,0xa5,0x34,0x41,0x96,0xa2,0x9f,0x76,0x9b,0x6e,0xaa,0x95,0xaf,0x61,0x83,0x8d, +0x3e,0x81,0x27,0x61,0x6a,0xbc,0xaa,0x40,0x98,0xa4,0xa1,0x6d,0xb2,0x79,0x9b,0x91, +0x9c,0x31,0x10,0x2d,0xc9,0x63,0x00,0x00,0x57,0x54,0x2a,0xbd,0x40,0x4e,0xa3,0x6e, +0x9c,0xbb,0x9e,0x42,0xae,0x92,0xa8,0x7b,0x73,0x5b,0x34,0xb3,0x28,0x09,0x83,0xe9, +0xa4,0x5a,0x99,0x5c,0xa9,0x9c,0xb2,0x74,0x9c,0x31,0x10,0x05,0xc9,0x53,0x00,0x00, +0x8b,0x75,0x47,0x93,0x23,0x6c,0x5d,0xcc,0xa9,0x20,0x99,0x90,0xa4,0x93,0xb2,0x65, +0x9c,0x95,0x5a,0x6e,0x2b,0x9d,0x3e,0x6c,0x9d,0x3d,0x9d,0xb4,0x9c,0x8c,0xb1,0x54, +0x9c,0x31,0x10,0xa9,0xca,0x64,0x10,0x00,0xa6,0x7b,0x6e,0x81,0x34,0x8a,0x30,0x49, +0x88,0x8b,0xa2,0x94,0x99,0x74,0xad,0x63,0xac,0x83,0x81,0x8b,0x42,0x7b,0x29,0x4b, +0x6d,0xb9,0xa2,0x89,0x97,0x5c,0xa9,0x65,0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00, +0xb1,0x2d,0x8f,0x6d,0x50,0xb1,0x2c,0xb4,0x55,0xd4,0xa0,0xa5,0x96,0x65,0xa2,0xd1, +0xb1,0x51,0x97,0x25,0x5c,0x89,0x30,0xf5,0x45,0x1a,0x94,0x6d,0x98,0xc9,0x9f,0x2d, +0x9c,0x31,0x10,0x0b,0xc9,0x74,0x10,0x00,0xb1,0x30,0xa0,0xe8,0x6a,0x89,0x39,0x2e, +0x3a,0x88,0x88,0xcd,0x9a,0xed,0x9b,0x6d,0xb0,0xe9,0xa2,0x8d,0x74,0xad,0x3f,0x24, +0x36,0x60,0x7f,0x42,0x9b,0x56,0x99,0x6d,0x9c,0x31,0x10,0xca,0xc9,0x74,0x20,0x00, +0xac,0xa5,0xa6,0x76,0x7c,0xcc,0x45,0x25,0x34,0xa8,0x79,0x69,0x9d,0x12,0x95,0x2d, +0xaa,0x69,0xa8,0x92,0x83,0x0c,0x49,0x48,0x34,0xad,0x73,0x46,0x9b,0x12,0x91,0x31, +0x9c,0x31,0x10,0xc9,0xc9,0x76,0x20,0x00,0xa8,0x89,0xa6,0xad,0x83,0x0d,0x4d,0x2d, +0x32,0x89,0x79,0x65,0x9b,0x11,0x8f,0x2d,0xaa,0x8d,0xa2,0xcd,0x81,0x09,0x51,0x11, +0x36,0x85,0x7d,0x6a,0x98,0xf1,0x8d,0x4a,0x9c,0x31,0x10,0x46,0xc9,0x77,0x20,0x00, +0xa6,0xb1,0x9e,0xed,0x80,0xe9,0x51,0x11,0x38,0x40,0x8b,0x29,0x93,0x2d,0x87,0x6a, +0xa6,0xb1,0x9a,0xce,0x7e,0xad,0x57,0x2a,0x3c,0x64,0x93,0x09,0x91,0x2d,0x83,0x6a, +0x9c,0x31,0x10,0xc7,0xca,0x76,0x30,0x00,0xa2,0xe5,0x94,0xc5,0x80,0xc4,0x69,0x15, +0x3c,0xc6,0x83,0x92,0x9b,0x19,0x74,0xf5,0x96,0x94,0x9a,0xc5,0x7f,0x35,0x7f,0x16, +0x64,0xf5,0x4a,0x90,0x9e,0xf5,0x89,0x35,0x9c,0x31,0x10,0x8e,0xb9,0x55,0x20,0x00, +0x6d,0x82,0xb8,0xc2,0x96,0x59,0x6e,0xe5,0x97,0x32,0x65,0x54,0x3a,0xe8,0x76,0xf8, +0xb8,0x46,0x6b,0x15,0x91,0x40,0x96,0xf5,0x78,0xf1,0x73,0x19,0x48,0xb9,0x71,0x64, +0x9c,0x31,0x10,0xa4,0xa8,0x37,0x10,0x00,0xe2,0x07,0x48,0xb9,0xa3,0x89,0xb8,0xf3, +0x50,0xd6,0xa4,0xda,0x96,0xf7,0x5d,0x46,0xa2,0xc8,0x7c,0xb7,0x61,0x26,0x93,0x07, +0x70,0xc8,0x6f,0x07,0x95,0x07,0x6c,0xe7,0x9c,0x31,0x10,0x5e,0xb8,0x56,0x10,0x00, +0x7e,0xeb,0x86,0xcb,0x76,0xeb,0x80,0xeb,0x80,0xeb,0x7c,0xeb,0x84,0xeb,0x80,0xec, +0x7e,0x8c,0x8b,0x84,0x3d,0x08,0x9f,0x24,0x88,0x6c,0x5d,0x4a,0xa9,0x0a,0x76,0xab, +0x9c,0x31,0x10,0x71,0xa6,0x24,0x00,0x00,0x65,0xb5,0xc2,0xeb,0x58,0x8a,0x81,0x6a, +0x9e,0x6c,0x53,0x24,0x97,0x22,0x84,0x6a,0x5d,0x43,0x98,0xeb,0x76,0x8b,0x6f,0x4b, +0x92,0xcb,0x6c,0xc3,0x7f,0x4a,0x8a,0x8b,0x9c,0x31,0x10,0x20,0x85,0x11,0x00,0x00, +0x39,0x89,0xa5,0xb5,0x80,0x39,0x54,0x96,0xa9,0x79,0x60,0x78,0x78,0x94,0x9c,0x56, +0x57,0x85,0x89,0x86,0x8c,0x65,0x61,0x81,0x93,0x61,0x79,0x64,0x74,0x92,0x92,0x55, +0x9c,0x31,0x10,0x69,0x53,0x22,0x00,0x00,0x16,0x12,0x5e,0x5c,0xc4,0xa3,0x56,0x22, +0x81,0xe3,0x46,0x94,0x81,0xda,0xb9,0x1a,0x1a,0x9b,0xba,0x64,0xa8,0x63,0x47,0x1b, +0xad,0x21,0x4d,0xca,0x53,0x15,0x9d,0x1b,0x9c,0x31,0x10,0x85,0x54,0x32,0x00,0x00, +0x7d,0x9c,0x8a,0x1b,0xc5,0xd9,0x6d,0x4b,0x96,0x5b,0x6d,0x14,0x7e,0x24,0xc5,0xdb, +0xa5,0xdc,0xa6,0x9b,0xa0,0xda,0x72,0x63,0x61,0xa3,0x55,0xdb,0x5e,0x5a,0x9c,0x9a, +0x9c,0x31,0x10,0x1d,0x55,0x34,0x00,0x00,0x9c,0xb8,0x62,0xc7,0x75,0x47,0xc3,0xb7, +0x42,0x47,0x4d,0x36,0x8a,0x36,0x7d,0x47,0x8c,0x37,0x82,0x3a,0xa4,0x9a,0x5b,0x3a, +0xa2,0xb2,0x76,0xd4,0x5a,0xb5,0xb2,0xba,0x9c,0x31,0x10,0x1c,0xa9,0x57,0x30,0x00, +0x80,0xeb,0x7e,0xeb,0x7e,0xeb,0x7e,0xeb,0x7e,0xeb,0x7e,0xeb,0x85,0x0b,0x80,0xca, +0xc1,0x54,0x98,0x0d,0x7b,0xcc,0x6a,0x6a,0x25,0x2a,0x30,0xca,0xc7,0x2b,0xa0,0xab, +0x9c,0x31,0x10,0xe6,0xcb,0x67,0x40,0x00,0x8b,0x05,0x86,0xe5,0x64,0xe9,0x34,0xfa, +0x99,0x76,0x86,0x24,0x77,0x84,0xb0,0xd5,0x82,0xb5,0xc1,0x55,0x78,0xd5,0x50,0xe9, +0x4b,0x24,0x8b,0x16,0x78,0xa6,0x8f,0x45,0x9c,0x31,0x10,0xe5,0xcb,0x57,0x30,0x00, +0x9a,0xc1,0xad,0x04,0x7f,0x15,0x60,0xe9,0x28,0xda,0x8d,0x75,0x84,0x45,0x81,0x75, +0xb8,0xc9,0x94,0xd5,0x8b,0x15,0x58,0xf5,0x2a,0xa5,0x91,0x95,0x84,0x45,0x91,0x65, +0x9c,0x31,0x10,0x6a,0xcb,0x56,0x30,0x00,0xb8,0xd5,0x92,0xf5,0x84,0xe4,0x47,0x15, +0x2e,0x81,0x9f,0x85,0x78,0x85,0xab,0x25,0xaa,0xe5,0x94,0xf4,0x74,0xe4,0x3d,0x35, +0x36,0x86,0xab,0x46,0x70,0xe5,0xc2,0xe4,0x9c,0x31,0x10,0xf7,0xca,0x56,0x30,0x00, +0x9d,0x14,0x9a,0xf5,0x5e,0xb5,0x39,0x79,0x40,0x98,0xb0,0xb4,0x73,0xa4,0xcc,0x45, +0x99,0x56,0x9c,0xe6,0x52,0xc5,0x33,0x49,0x4f,0x04,0xa8,0x45,0x7d,0xe5,0xcc,0x35, +0x9c,0x31,0x10,0x6a,0xcb,0x56,0x30,0x00,0x99,0x25,0x96,0xe5,0x4c,0xe9,0x2e,0xf9, +0x55,0x35,0xa8,0x64,0x85,0x85,0xca,0x85,0x99,0x36,0x94,0xe5,0x4a,0xf5,0x2c,0xe9, +0x5b,0x45,0xa4,0x65,0x89,0x85,0xca,0x95,0x9c,0x31,0x10,0xf7,0xca,0x56,0x30,0x00, +0x9d,0x45,0x93,0x05,0x4c,0xd9,0x2b,0x09,0x53,0x65,0xa4,0x04,0x87,0xe4,0xcc,0x45, +0x9f,0x56,0x98,0xe6,0x50,0xd5,0x31,0x2a,0x41,0x09,0xa8,0x54,0x7f,0xd4,0xce,0x46, +0x9c,0x31,0x10,0xf7,0xca,0x56,0x30,0x00,0xa1,0x56,0x9c,0xe5,0x5e,0xd5,0x33,0x48, +0x30,0x79,0xa9,0x36,0x79,0x05,0xc6,0xd5,0xa7,0x25,0x9e,0xd5,0x6c,0xd5,0x3d,0x51, +0x24,0x25,0x97,0xe4,0x84,0x45,0xb1,0x55,0x9c,0x31,0x10,0x6a,0xcb,0x56,0x30,0x00, +0xb2,0xe5,0x9e,0xf5,0x82,0xf4,0x49,0x04,0x24,0xd5,0x71,0x56,0x9a,0x76,0x8d,0x65, +0xc6,0xa5,0x9b,0x25,0x94,0xe5,0x58,0xf5,0x2c,0xf5,0x44,0xf8,0xa8,0xe4,0x7b,0x15, +0x9c,0x31,0x10,0x7b,0xca,0x55,0x30,0x00,0xc2,0xb6,0xa3,0x16,0xa0,0xe6,0x6c,0xe5, +0x43,0x12,0x24,0x91,0x95,0xb5,0x88,0x35,0xa3,0x85,0xb4,0x94,0x9d,0x25,0x8c,0xd5, +0x57,0x05,0x28,0xf8,0x55,0x15,0xa6,0x86,0x9c,0x31,0x10,0xf7,0xca,0x56,0x30,0x00, +0x7b,0x85,0xc2,0x85,0x9d,0x49,0xa0,0xd5,0x72,0xe5,0x41,0x00,0x28,0xb0,0x8f,0x95, +0x88,0x46,0x9d,0x86,0xb4,0xa4,0x99,0x14,0x96,0xd5,0x5f,0x25,0x32,0xc6,0x40,0xc6, +0x9c,0x31,0x10,0xf7,0xca,0x56,0x30,0x00,0xab,0x35,0x72,0xd5,0xbc,0xf4,0x9e,0xf4, +0xa0,0xe5,0x84,0xe6,0x55,0x16,0x28,0xe9,0x5f,0x14,0xa4,0x84,0x77,0x75,0xc0,0x85, +0x99,0x45,0xa0,0xe5,0x7c,0xe5,0x51,0x19,0x9c,0x31,0x10,0xef,0xca,0x46,0x30,0x00, +0x24,0xe6,0x75,0x46,0x98,0x65,0x81,0x98,0xbc,0x85,0x95,0x35,0xa2,0xe9,0x7c,0xe5, +0x4e,0xf9,0x29,0x1a,0x75,0x06,0x98,0x99,0x7f,0x78,0xb8,0x89,0x97,0x35,0x9e,0xea, +0x9c,0x31,0x10,0x4d,0xc9,0x56,0x30,0x00,0x82,0xad,0x53,0x34,0x26,0xf3,0x6b,0x08, +0x9e,0x89,0x79,0x8c,0xba,0x4d,0x97,0x2c,0x9f,0x0b,0x8a,0x8a,0x61,0x69,0x2e,0xeb, +0x48,0x4e,0xa5,0xae,0x74,0x6b,0xad,0x08,0x9c,0x31,0x10,0xef,0xca,0x46,0x30,0x00, +0xa1,0x14,0x98,0xc9,0x9b,0x02,0x75,0x25,0x40,0xa4,0x31,0x04,0x87,0x62,0x8e,0x36, +0x85,0xb5,0xb2,0x74,0x95,0x14,0xa1,0x35,0x8c,0xa5,0x5f,0x35,0x33,0x01,0x48,0x76, +0x9c,0x31,0x10,0x60,0xca,0x47,0x30,0x00,0xa1,0x85,0x78,0x84,0xa3,0x24,0x9f,0x15, +0x98,0xa1,0x9f,0x35,0x82,0xf5,0x54,0xc5,0x33,0x58,0x56,0x88,0xa9,0x15,0x73,0x16, +0xac,0xa5,0x9b,0x55,0x96,0xa1,0xa1,0x05,0x9c,0x31,0x10,0x55,0xc9,0x46,0x30,0x00, +0x79,0x4b,0x52,0x6c,0x35,0x8b,0x58,0x90,0xaa,0xa3,0x73,0xad,0xaa,0x0d,0x9b,0xcb, +0x94,0x6a,0x9e,0xea,0x7d,0x4a,0x56,0x6b,0x3d,0xa3,0x48,0x16,0xa9,0x8e,0x78,0xca, +0x9c,0x31,0x10,0x5b,0xca,0x46,0x20,0x00,0x9c,0xd4,0x9d,0x34,0x96,0xb5,0x9f,0x26, +0x86,0xe6,0x66,0xd5,0x45,0x25,0x38,0x90,0x91,0x95,0x90,0x46,0x85,0x76,0xa2,0xb5, +0x94,0xf5,0x9d,0x20,0x96,0xb5,0x79,0x16,0x9c,0x31,0x10,0x75,0xc9,0x55,0x20,0x00, +0x55,0x66,0x3e,0x84,0x4f,0x48,0xac,0x86,0x75,0x86,0x99,0x45,0x9b,0xb4,0x92,0x44, +0xa2,0x86,0x8d,0x86,0x74,0x65,0x50,0x85,0x37,0x79,0x69,0x94,0xa9,0x24,0x72,0xe5, +0x9c,0x31,0x10,0x9a,0xca,0x46,0x10,0x00,0x9e,0x96,0x9b,0x35,0x8e,0xe5,0xa2,0xd9, +0x8b,0x25,0x70,0xd5,0x52,0xf9,0x36,0xfa,0x6b,0x25,0xa8,0x84,0x71,0x75,0x9e,0x86, +0x9b,0x46,0x8a,0xe9,0xa2,0xe4,0x90,0xf4,0x9c,0x31,0x10,0x43,0xca,0x56,0x20,0x00, +0x71,0x05,0x5c,0xc6,0x3b,0x35,0x52,0xb8,0xb0,0xf5,0x73,0x35,0x90,0x95,0x9d,0x55, +0x8a,0xb5,0x98,0xf1,0xa3,0x36,0x78,0xb6,0x67,0x05,0x43,0x25,0x38,0x65,0x9f,0xa4, +0x9c,0x31,0x10,0x5b,0xca,0x46,0x20,0x00,0x86,0x61,0x81,0x26,0x9f,0x16,0x96,0xa5, +0x8d,0x49,0xa6,0xe4,0x8a,0xb5,0x65,0x46,0x52,0xc9,0x34,0xf9,0x73,0x65,0xa8,0x49, +0x73,0x94,0x94,0x85,0xa1,0x15,0x8b,0x15,0x9c,0x31,0x10,0x57,0xb9,0x45,0x10,0x00, +0xb4,0x60,0xbf,0x84,0x64,0xb5,0x40,0xd5,0x03,0x71,0x00,0x16,0xd3,0xc5,0x86,0x94, +0x82,0xd5,0xb9,0x76,0xb2,0x46,0x9b,0x85,0xc2,0xd4,0xa4,0x85,0x4b,0x95,0x26,0x85, +0x9c,0x31,0x10,0x16,0xca,0x45,0x10,0x00,0x37,0x0a,0x6d,0x45,0xaa,0x68,0x75,0x84, +0x8c,0x86,0xa1,0x36,0x90,0xf5,0x94,0xd5,0xa3,0x45,0x7e,0xa5,0x5d,0x16,0x47,0x11, +0x3a,0x91,0x97,0x84,0x92,0x85,0x7b,0x36,0x9c,0x31,0x10,0x20,0xc9,0x46,0x10,0x00, +0x8e,0xec,0x9e,0x8b,0x8f,0x6b,0x96,0x63,0x9f,0x4b,0x74,0xeb,0x56,0xaa,0x3d,0x4a, +0x4a,0x93,0xa9,0x0e,0x83,0x0c,0x84,0x89,0x93,0x69,0x9c,0x6b,0x91,0x4c,0x98,0xcb, +0x9c,0x31,0x10,0xac,0xc9,0x45,0x10,0x00,0x96,0x65,0x6d,0x95,0x4d,0x65,0x39,0x7a, +0x61,0x95,0xaa,0x38,0x83,0xb5,0x86,0x36,0x99,0xb5,0x9e,0x54,0x93,0x75,0x97,0x96, +0x89,0x55,0x63,0x95,0x46,0x75,0x41,0x40,0x9c,0x31,0x10,0x1f,0xb9,0x35,0x10,0x00, +0x7f,0x95,0xbe,0x46,0x8d,0x85,0x94,0xa5,0xbb,0x15,0xb1,0x05,0xa6,0xc6,0xa1,0x25, +0x76,0xe4,0x36,0xe5,0x11,0x21,0x1c,0xa6,0x9f,0x35,0xa8,0xc4,0x95,0x05,0x9a,0xf6, +0x9c,0x31,0x10,0x4c,0xb6,0x34,0x00,0x00,0xb6,0x6b,0xb1,0x48,0xa5,0x05,0x8e,0xad, +0x65,0x0a,0x37,0x69,0x1e,0x54,0x4b,0x8b,0x94,0x2b,0x97,0x6b,0x9a,0xcc,0xa5,0x0b, +0xac,0x89,0xa9,0x8b,0x90,0x6e,0x77,0x94,0x9c,0x31,0x10,0x4c,0xb6,0x34,0x00,0x00, +0x54,0xb2,0x3c,0xf1,0x3b,0x33,0x60,0x8b,0x87,0x2b,0x99,0x0c,0xa8,0xaa,0xad,0x89, +0xa8,0x0b,0x93,0xad,0x74,0x33,0x5d,0x72,0x4c,0xd3,0x4e,0xcc,0x5b,0x15,0x71,0x09, +0x9c,0x31,0x10,0x4e,0x96,0x44,0x00,0x00,0x9d,0xda,0xe9,0xe4,0xf9,0xdd,0xe2,0x12, +0xa6,0x5a,0x69,0xd4,0x41,0x9c,0x32,0xaa,0x32,0x19,0x45,0xab,0x61,0xdb,0x86,0x15, +0x9f,0x2c,0xb2,0x1a,0xb6,0x13,0xa5,0xf5,0x9c,0x31,0x10,0xc7,0x86,0x54,0x10,0x00, +0xba,0x11,0xa9,0xcb,0x8e,0x0a,0x85,0xec,0x8d,0x93,0x9e,0x2a,0xbe,0xe3,0xcd,0x2b, +0xc5,0xe9,0xc1,0x9b,0xaf,0x2a,0xb2,0xac,0xa8,0xf4,0xa1,0xd5,0x71,0x9c,0x6d,0x51, +0x9c,0x31,0x10,0x3f,0x66,0x65,0x00,0x00,0x1b,0xbb,0x62,0x23,0x92,0x13,0x63,0x34, +0x4a,0x3b,0x66,0x3b,0x52,0xba,0x84,0x1a,0x84,0x35,0x7b,0xaa,0x6d,0xaa,0x93,0xb4, +0x88,0xac,0x92,0xc3,0xda,0x31,0xab,0x54,0x9c,0x31,0x10,0xa7,0x77,0x76,0x10,0x00, +0x7b,0xcb,0x64,0x2a,0x34,0x33,0x1c,0x43,0x1b,0x44,0x44,0x43,0x2a,0x2a,0x23,0x45, +0x25,0x1a,0x63,0x2b,0x93,0xc9,0x75,0xcc,0x62,0xab,0x6b,0x3b,0x53,0xba,0x64,0x2b, +0x9c,0x31,0x10,0x24,0x87,0x75,0x20,0x00,0x6a,0xe1,0x8a,0x21,0x85,0xa8,0x81,0xa2, +0x76,0x99,0x95,0xd5,0x75,0x15,0x72,0x76,0x49,0x9d,0x48,0x94,0x3a,0x14,0x56,0x69, +0x76,0x6a,0x6d,0x64,0x6d,0x51,0x6e,0x1e,0x9c,0x31,0x10,0x7e,0x77,0x66,0x20,0x00, +0xb4,0xab,0xc5,0x32,0xbb,0xaa,0xca,0x66,0xc4,0x43,0xcc,0x43,0xc2,0xca,0xa4,0xaa, +0x73,0xdb,0x91,0xd3,0x7c,0x53,0x84,0x5b,0xaa,0x3a,0x9c,0xcc,0x85,0x33,0x7b,0x1c, +0x9c,0x31,0x10,0x77,0x76,0x75,0x20,0x00,0x62,0xc1,0x7b,0x33,0x89,0xab,0x73,0x3c, +0x6b,0x41,0x45,0x3b,0x3d,0xad,0x61,0xbc,0x6a,0xb1,0x8c,0x3c,0x72,0x3c,0x61,0xc2, +0x53,0x62,0x66,0xac,0x5c,0x52,0x5b,0xc0,0x9c,0x31,0x10,0xae,0x76,0x65,0x10,0x00, +0x4a,0x24,0x63,0x36,0xa3,0x92,0xc3,0xca,0x9b,0x2b,0x9a,0x1d,0xb2,0x12,0xab,0x2a, +0xb5,0x3d,0x92,0xca,0x73,0x2b,0x5b,0x3b,0x86,0x63,0x6c,0xb4,0x7b,0xaa,0x6a,0x4c, +0x9c,0x31,0x10,0x07,0x66,0x66,0x10,0x00,0x72,0x53,0x96,0x33,0xac,0xd4,0x79,0xd3, +0x9a,0x23,0xae,0x42,0x89,0x54,0x61,0xdb,0x76,0xa3,0x7b,0xbb,0xb1,0x4d,0xd5,0xca, +0xa3,0xbb,0xda,0xb2,0x6e,0x1b,0x79,0x9c,0x9c,0x31,0x10,0x9a,0x67,0x66,0x10,0x00, +0x4a,0xc4,0x2d,0xc3,0x26,0x53,0x5b,0x4a,0x53,0x1a,0x5b,0xbc,0x3a,0x35,0x1b,0x3b, +0x65,0x42,0x8c,0x4a,0xa3,0x54,0x5b,0x4b,0x84,0xe3,0x94,0x34,0xaa,0xbb,0xbb,0xc3, +0x9c,0x31,0x10,0x07,0x66,0x66,0x10,0x00,0x9a,0xbb,0x84,0x2b,0x7e,0xba,0x23,0xac, +0x01,0x13,0x22,0x04,0x74,0x2a,0x36,0xb2,0x25,0x33,0x61,0x5d,0x92,0x4b,0x8a,0xc3, +0x93,0xba,0x94,0x4c,0xd3,0xbb,0x94,0x3b,0x9c,0x31,0x10,0x16,0x67,0x65,0x10,0x00, +0xb3,0x31,0x63,0x54,0xe5,0xdc,0x43,0xab,0x4a,0x42,0x5b,0xc3,0xb4,0x4a,0x5b,0x19, +0x93,0x96,0x84,0x4a,0x92,0x42,0x92,0xb3,0x8c,0x1c,0xa3,0x22,0x52,0xb3,0x4b,0x45, +0x9c,0x31,0x10,0x16,0x67,0x65,0x10,0x00,0x22,0xc5,0x7b,0x38,0x53,0x2b,0x7c,0x53, +0x63,0xcb,0x7c,0xe3,0x5c,0x4b,0x5b,0x3d,0x83,0xc2,0x64,0x52,0x73,0x5d,0x83,0xdb, +0x62,0x43,0x59,0xd2,0x4a,0x52,0x83,0x75,0x9c,0x31,0x10,0x32,0x76,0x55,0x00,0x00, +0x69,0xe2,0x7d,0x5a,0x76,0x6c,0x8e,0xaa,0x76,0xa3,0x78,0xdc,0x6c,0xe2,0x9e,0x93, +0x6a,0x93,0x82,0x5d,0xa7,0x21,0xc1,0xd0,0xc2,0x25,0xae,0x2c,0xb1,0xa2,0xb2,0x1b, +0x9c,0x31,0x10,0x22,0x65,0x54,0x00,0x00,0xea,0x0c,0x9b,0x1b,0x8a,0x63,0xb8,0xd3, +0x83,0x2b,0x4e,0x99,0x36,0xe5,0x32,0xdb,0x61,0x8a,0x39,0xdd,0x45,0xe4,0x6d,0x99, +0x8d,0x13,0x7d,0x1e,0x50,0x29,0x91,0x9d,0x9c,0x31,0x10,0x55,0x55,0x44,0x00,0x00, +0xad,0x43,0x9d,0x41,0x61,0x62,0x69,0x44,0x74,0x9b,0x02,0xdb,0x54,0x49,0x3a,0x36, +0x0c,0x4b,0x1d,0x5c,0x75,0xbb,0xa4,0xa2,0x62,0x4b,0xa3,0xd4,0x7a,0x3c,0x4e,0x39, +0x9c,0x31,0x10,0xdf,0x55,0x43,0x00,0x00,0x74,0x5c,0x79,0x5c,0xb5,0xc4,0x84,0xe0, +0xb8,0x4b,0xcb,0xac,0x7b,0xbd,0x73,0xdb,0x83,0xca,0x83,0xc2,0x12,0xbc,0x4c,0x42, +0x38,0x9a,0x44,0x42,0x8c,0x3d,0x73,0x2d,0x9c,0x31,0x10,0xf8,0x65,0x33,0x00,0x00, +0x71,0xc2,0x66,0x8a,0x7a,0x33,0x36,0x95,0x55,0xc9,0x45,0xdb,0x76,0x25,0x68,0xaa, +0x91,0x51,0x8e,0xdc,0x85,0x55,0x79,0x48,0x7a,0xe3,0x65,0x9c,0x82,0x5b,0x92,0x11, +0x9c,0x31,0x10,0x37,0x44,0x23,0x00,0x00,0x9c,0xd6,0xe2,0x5b,0xe1,0x19,0xd1,0x8b, +0x9a,0xa5,0x89,0x5a,0x81,0x32,0x4e,0xad,0xc9,0xd4,0xa6,0x19,0xd1,0xdb,0xb4,0x94, +0x9e,0x5a,0xa5,0x9b,0xa6,0x1b,0xa2,0x24,0x9c,0x31,0x10,0xc0,0x43,0x21,0x00,0x00, +0x95,0x51,0x7d,0x5c,0x82,0x8e,0x81,0xe1,0x52,0x25,0x4d,0xde,0xa9,0xb5,0xc9,0xd8, +0xc1,0x5a,0xa2,0x11,0x8e,0x1a,0x49,0xe0,0x3d,0x61,0x2d,0x9d,0x52,0x99,0x90,0xdc, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_POWER_ON.txt b/config/_default_cfg_src_/res/en/SOUND_POWER_ON.txt new file mode 100644 index 0000000..f866076 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_POWER_ON.txt @@ -0,0 +1,245 @@ +0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00,0x7d,0xdd,0x7d,0xdd,0x82,0x1d,0x85,0xa1, +0xb2,0xdc,0x99,0xd1,0x76,0x61,0x61,0x25,0x6d,0x58,0x5d,0x52,0x6d,0x15,0x5d,0xac, +0x59,0xcd,0x2e,0x91,0x46,0x61,0x3a,0x9d,0x9c,0x31,0x10,0xae,0x43,0x33,0x20,0x00, +0x2c,0x6d,0x63,0x6d,0x73,0x8d,0x7a,0x71,0x6c,0x6d,0x5b,0x8d,0x64,0xad,0x33,0x2d, +0x63,0x31,0x8b,0xad,0x7d,0x89,0xc4,0x8d,0x1a,0x6d,0x5a,0x4d,0x1c,0x28,0x63,0xa0, +0x9c,0x31,0x10,0x39,0xa8,0x87,0x30,0x00,0x81,0xdd,0x85,0xdd,0x91,0x11,0xdd,0x92, +0x9c,0xb4,0x8d,0x9c,0xc9,0x9d,0xba,0x1e,0x81,0x9d,0x75,0xdc,0x71,0x9d,0x51,0xde, +0x3d,0xdd,0x41,0xdd,0x29,0x9d,0x32,0x1d,0x9c,0x31,0x10,0x82,0xa8,0x55,0x30,0x00, +0x38,0xe6,0x42,0xc6,0x59,0x35,0x5a,0xf5,0x68,0x94,0x75,0x25,0x6e,0xfa,0x8b,0x15, +0x88,0x94,0x97,0x64,0x96,0x85,0xa7,0x64,0x96,0x48,0x9b,0x85,0xa2,0x86,0x81,0x46, +0x9c,0x31,0x10,0xfc,0x99,0x56,0x30,0x00,0xb1,0xcc,0x9d,0xe3,0x95,0x83,0x96,0x2a, +0xbe,0x8a,0x4c,0xe2,0xf2,0x43,0x31,0x83,0xe6,0x2c,0x2e,0xac,0xd8,0x63,0x27,0x29, +0xe8,0x92,0x4b,0x12,0xac,0xed,0x8f,0x4d,0x9c,0x31,0x10,0x48,0x8a,0x56,0x40,0x00, +0x75,0x54,0xda,0xd5,0x44,0xeb,0xb2,0xb1,0x39,0x8b,0xc6,0x22,0x46,0x0a,0xae,0x0c, +0x1d,0x83,0xbd,0xc2,0x5e,0xa3,0x99,0xca,0x52,0x33,0x7a,0x13,0x9d,0xf3,0x51,0x6b, +0x9c,0x31,0x10,0xd7,0x99,0x56,0x40,0x00,0x7d,0xb5,0x7a,0x39,0x7e,0x52,0x78,0xae, +0x85,0x2a,0x59,0x89,0x94,0x25,0x3e,0x31,0x9b,0xc9,0x51,0xd1,0x72,0x31,0xa5,0x91, +0x69,0x11,0x9d,0x0e,0x9e,0xb2,0x41,0xaa,0x9c,0x31,0x10,0x73,0x99,0x57,0x30,0x00, +0xc6,0xab,0x55,0x42,0x88,0x8b,0x7f,0x6a,0x8d,0x34,0x76,0x84,0x84,0xeb,0x9f,0x2a, +0x3d,0x93,0xc1,0xf5,0x4a,0x84,0x90,0xa2,0x8e,0xc1,0x4d,0x6b,0xa6,0xec,0x56,0x0b, +0x9c,0x31,0x10,0xb0,0x79,0x67,0x30,0x00,0x99,0x22,0x5e,0xa2,0x73,0xa3,0x93,0x5c, +0xab,0xea,0x13,0x62,0x9b,0x1b,0xbc,0xe4,0x1a,0x0d,0x6d,0x02,0xbb,0x9b,0x13,0x5b, +0x36,0xd2,0x79,0xe2,0x12,0x23,0xd6,0x5c,0x9c,0x31,0x10,0xfc,0x99,0x56,0x30,0x00, +0x69,0xeb,0x99,0xd3,0x59,0x8c,0x85,0xa1,0x8b,0x52,0x84,0x16,0x92,0xac,0xa2,0xc9, +0x70,0xaa,0x76,0x11,0x4a,0x0b,0x51,0xcc,0x9d,0x8e,0xb7,0x34,0xe5,0x92,0xa5,0xa9, +0x9c,0x31,0x10,0x0c,0xba,0x56,0x30,0x00,0x5d,0xa4,0x4d,0xac,0x62,0x82,0x7d,0x40, +0xc2,0x4c,0xb5,0xce,0xaa,0x04,0x39,0x8c,0x45,0xe8,0x0a,0x0b,0xa6,0x6c,0xd0,0xed, +0xd6,0x94,0xc1,0xc0,0x39,0x84,0x2e,0x22,0x9c,0x31,0x10,0x4b,0xcb,0x68,0x30,0x00, +0x30,0xc1,0xa7,0x04,0x82,0xed,0xcd,0x0b,0x9c,0xcb,0x83,0x13,0x41,0x33,0x38,0x42, +0x81,0xcc,0x8c,0x4b,0xad,0x2b,0xb6,0xcc,0x95,0x2b,0x56,0x62,0x3d,0x6c,0x48,0xf2, +0x9c,0x31,0x10,0xcd,0xcb,0x67,0x30,0x00,0xac,0x62,0x7b,0xa6,0xcc,0x95,0x9c,0xf4, +0x7b,0x26,0x3f,0x05,0x2c,0x30,0x9f,0xe4,0x78,0x86,0xb6,0xe6,0xb1,0x34,0x96,0xd5, +0x56,0xc6,0x33,0x78,0x4c,0xd4,0xb0,0x56,0x9c,0x31,0x10,0x61,0xcb,0x77,0x20,0x00, +0x75,0xe6,0xcc,0x44,0xa1,0x35,0x81,0x16,0x3c,0xd5,0x2a,0x91,0x99,0xd5,0x80,0x26, +0xaf,0x55,0xb2,0xf5,0x9e,0xd6,0x5e,0xf5,0x2f,0x54,0x44,0x89,0xb6,0xf6,0x6b,0x54, +0x9c,0x31,0x10,0x79,0xcb,0x67,0x20,0x00,0xce,0x75,0xa1,0x52,0x90,0xd4,0x40,0xc5, +0x20,0xf2,0x8f,0x85,0x8e,0x24,0x93,0xb5,0xc2,0x85,0x9f,0x04,0x73,0x15,0x2a,0xf1, +0x32,0x99,0xb3,0x75,0x6e,0x95,0xbd,0x16,0x9c,0x31,0x10,0xf6,0xcb,0x66,0x20,0x00, +0xaf,0x14,0x96,0xb5,0x57,0x15,0x17,0x19,0x6b,0x05,0xac,0xa4,0x71,0x66,0xd2,0x74, +0x9f,0x56,0x8a,0xd5,0x3e,0xe4,0x16,0xd1,0x9f,0x65,0x8a,0x65,0x93,0x85,0xc8,0x95, +0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00,0x9b,0x35,0x73,0x25,0x26,0xe5,0x32,0x86, +0xbb,0x95,0x70,0x65,0xb9,0x55,0xb4,0xd4,0x98,0xd6,0x5b,0x24,0x19,0x09,0x58,0xf4, +0xc0,0xa6,0x69,0x65,0xce,0x89,0xa9,0x61,0x9c,0x31,0x10,0x1e,0xca,0x66,0x00,0x00, +0x8c,0xa5,0x45,0x16,0x12,0xd0,0x87,0x76,0xa6,0x44,0x79,0xa6,0xd0,0x61,0xa3,0x49, +0x7c,0xe5,0x30,0xe5,0x1a,0xa2,0xad,0x98,0x8e,0x42,0x93,0xa4,0xcc,0x86,0x9d,0x18, +0x9c,0x31,0x10,0x8c,0xc9,0x56,0x00,0x00,0x69,0x25,0x20,0xf1,0x32,0x74,0xc7,0x8a, +0x78,0x2c,0xa9,0x8b,0xc2,0xab,0x96,0xeb,0x57,0x2b,0x14,0xd3,0x55,0x23,0xca,0xab, +0x6f,0x33,0xbc,0xab,0xbb,0x23,0x8c,0xab,0x9c,0x31,0x10,0x81,0xca,0x54,0x10,0x00, +0x45,0x04,0x0e,0xd1,0x79,0x55,0xbc,0x99,0x73,0x56,0xc2,0xb5,0xb5,0x25,0x7c,0xe5, +0x33,0x06,0x12,0xb4,0x97,0x75,0xac,0x74,0x7f,0x72,0xc2,0x9a,0xad,0x28,0x6c,0xf1, +0x9c,0x31,0x10,0x05,0xc9,0x53,0x00,0x00,0x26,0x8d,0x23,0x3c,0xb5,0xd4,0x98,0x1a, +0x8f,0xd3,0xc3,0x4d,0xa4,0x82,0x5e,0x8b,0x1d,0x86,0x37,0x64,0xc6,0x98,0x8b,0x4e, +0x9a,0xad,0xc2,0x68,0x9b,0x73,0x51,0x95,0x9c,0x31,0x10,0x2d,0xc9,0x63,0x00,0x00, +0x14,0x6b,0x53,0x9a,0xc9,0x63,0x80,0x84,0xa7,0x7a,0xbd,0x82,0x90,0x6c,0x40,0x94, +0x11,0x51,0x73,0xc1,0xc4,0x2d,0x7f,0xbc,0xb2,0x49,0xb9,0x9b,0x82,0x65,0x31,0x92, +0x9c,0x31,0x10,0xa2,0xc9,0x62,0x00,0x00,0x14,0x39,0x90,0xe4,0xb6,0x15,0x84,0xda, +0xba,0x3a,0xb3,0x9c,0x73,0x7c,0x25,0x8a,0x1e,0x3b,0xb1,0xcd,0xa4,0x24,0x8e,0xc2, +0xba,0x53,0xad,0x84,0x5f,0x8c,0x1a,0x83,0x9c,0x31,0x10,0x17,0xc8,0x52,0x00,0x00, +0x37,0x46,0xc3,0xbd,0x94,0x31,0x9a,0xaa,0xbc,0x74,0xa0,0x4c,0x4d,0xbc,0x11,0x55, +0x54,0xca,0xc9,0x18,0x88,0xd1,0xa5,0x1d,0xc0,0xd6,0x8d,0x34,0x3d,0xaa,0x0a,0x18, +0x9c,0x31,0x10,0xa2,0xc9,0x62,0x00,0x00,0x80,0xd8,0xbb,0x12,0x85,0xdc,0xb3,0x3d, +0xbc,0x94,0x77,0x83,0x29,0x71,0x16,0x39,0xab,0xd3,0xa4,0x1d,0x8f,0xcd,0xbc,0x54, +0xb0,0x6b,0x5f,0xaa,0x14,0x63,0x3b,0x85,0x9c,0x31,0x10,0xa2,0xc9,0x62,0x00,0x00, +0xc3,0x6e,0x8b,0x8d,0x9f,0x6b,0xc1,0xa2,0x9a,0x42,0x46,0xa2,0x0c,0x53,0x6d,0xe3, +0xbc,0x0a,0x86,0xea,0xb0,0x23,0xc0,0xac,0x78,0x83,0x30,0x6a,0x11,0x41,0xac,0xc9, +0x9c,0x31,0x10,0x18,0xca,0x62,0x00,0x00,0x9e,0x52,0x90,0x93,0xbd,0x7c,0xae,0x5c, +0x5f,0xac,0x13,0x6c,0x44,0x86,0xbe,0x66,0x88,0x94,0xa7,0x6b,0xbf,0x92,0x91,0x62, +0x44,0x82,0x0f,0x6b,0x7b,0xba,0xb0,0x31,0x9c,0x31,0x10,0xa2,0xc9,0x62,0x00,0x00, +0x8a,0xea,0xbb,0x3a,0xb3,0x73,0x73,0xc3,0x28,0x32,0x28,0x5a,0xa9,0xab,0x95,0x54, +0xa0,0x85,0xc1,0x8d,0x9a,0x5c,0x57,0x84,0x17,0xad,0x57,0x8e,0xb0,0x1c,0x8b,0xf2, +0x9c,0x31,0x10,0x8f,0xca,0x73,0x00,0x00,0xb6,0x4a,0xb9,0x8a,0x82,0x93,0x3c,0x53, +0x18,0x72,0x8a,0xc2,0xa0,0x32,0x97,0x9b,0xc2,0x93,0xa5,0x4b,0x6a,0xa3,0x21,0x93, +0x3d,0x3c,0xa8,0x8d,0x8e,0x9d,0xaf,0x4c,0x9c,0x31,0x10,0x8f,0xca,0x73,0x00,0x00, +0xbb,0x8b,0x8f,0x9b,0x4c,0x43,0x1d,0x93,0x68,0xd3,0xa5,0x0a,0x93,0xaa,0xbe,0x93, +0xab,0x44,0x77,0x93,0x32,0x8a,0x2b,0x21,0x96,0xaa,0x93,0x94,0xa7,0x4d,0xbf,0x84, +0x9c,0x31,0x10,0x07,0xca,0x83,0x00,0x00,0x97,0x27,0x5c,0xb7,0x25,0x27,0x4f,0x29, +0xa0,0x59,0x91,0x37,0xb7,0x36,0xb0,0xb6,0x83,0x07,0x44,0xf7,0x24,0x95,0x7b,0xa3, +0x9c,0xe5,0x9a,0xb8,0xbf,0x0a,0x9f,0x18,0x9c,0x31,0x10,0x8f,0xca,0x73,0x00,0x00, +0x6c,0x7a,0x2e,0x8a,0x40,0x54,0x9c,0x55,0x8d,0xad,0xad,0x94,0xb9,0x51,0x8a,0x81, +0x55,0x83,0x25,0x7d,0x6f,0xbb,0x9b,0x50,0x92,0x68,0xba,0x7b,0xa6,0x8d,0x75,0x8c, +0x9c,0x31,0x10,0x8d,0xca,0x84,0x00,0x00,0x3a,0xe4,0x38,0x73,0x93,0x17,0x8f,0x4b, +0xa5,0x0a,0xb6,0xb6,0x90,0xf4,0x5b,0x07,0x2f,0x2b,0x65,0x6b,0x9a,0x86,0x8c,0xd4, +0xb3,0x06,0xa9,0x29,0x79,0x19,0x44,0xd6,0x9c,0x31,0x10,0x39,0xca,0x84,0x10,0x00, +0x3a,0x93,0x8f,0x17,0x8d,0x3a,0x9d,0x28,0xb2,0xb7,0x92,0xc6,0x63,0x06,0x33,0x1a, +0x6b,0x8a,0x98,0xa5,0x84,0xc4,0xae,0xe7,0xa5,0x28,0x7f,0x27,0x48,0xe6,0x40,0x84, +0x9c,0x31,0x10,0x8a,0xca,0x75,0x00,0x00,0x94,0x6a,0x85,0x9d,0x96,0xab,0xae,0x59, +0x92,0x5b,0x6a,0x7c,0x39,0x84,0x6e,0xcc,0x9b,0x52,0x7c,0x5b,0xa6,0x7d,0xa1,0x94, +0x82,0x91,0x5a,0x6a,0x40,0x42,0x96,0x79,0x9c,0x31,0x10,0x8c,0xba,0x85,0x20,0x00, +0x8d,0x48,0x91,0x47,0xd0,0xc5,0xa0,0xc8,0x73,0x08,0x1b,0x27,0x37,0x4a,0xc0,0x5a, +0x70,0xb4,0xa5,0x26,0xc3,0x29,0x8d,0x06,0x6c,0xe5,0x10,0xbb,0x6d,0xaa,0xb8,0xb3, +0x9c,0x31,0x10,0xbe,0xb9,0x75,0x20,0x00,0x64,0x91,0xa6,0xb9,0xaf,0x45,0x91,0x2e, +0x7c,0xf1,0x30,0xa5,0x32,0xf2,0xce,0x34,0x6b,0x25,0x85,0x6d,0xb8,0xf1,0x80,0x8d, +0x9f,0x31,0x7d,0x0d,0x1c,0xe8,0x54,0xd6,0x9c,0x31,0x10,0x69,0xba,0x65,0x00,0x00, +0xc8,0xf0,0x56,0x65,0x92,0x91,0xb1,0x89,0x5d,0x91,0x8a,0x09,0x96,0x31,0x6d,0xed, +0x99,0xa9,0x75,0xd1,0x3e,0x0d,0x75,0xed,0x85,0xed,0x69,0xec,0x91,0xee,0x8d,0xed, +0x9c,0x31,0x10,0xcb,0x97,0x54,0x00,0x00,0x8a,0x94,0xd5,0x9a,0x85,0xa4,0x76,0x5b, +0x91,0xdb,0x25,0x53,0x1a,0x53,0x10,0x0b,0xca,0xa0,0x96,0x96,0x7a,0x18,0xd0,0xdd, +0x76,0x5b,0x7e,0x99,0xa8,0xdd,0x61,0x99,0x9c,0x31,0x10,0x67,0x76,0x33,0x00,0x00, +0xb7,0x8e,0xe6,0x0d,0x01,0x54,0x8a,0x2a,0x5d,0xed,0x21,0xed,0x99,0xa5,0x56,0x0d, +0x56,0x0d,0xb5,0xc5,0x45,0xe5,0x66,0x49,0x95,0xd1,0x45,0xf1,0x8d,0xb1,0x81,0xa9, +0x9c,0x31,0x10,0x7d,0x64,0x23,0x00,0x00,0x63,0x5c,0xb6,0x5c,0x44,0xa2,0x49,0x6b, +0xb7,0xb1,0x2e,0x8d,0x7d,0x23,0xc0,0xcb,0x8a,0x22,0xc6,0x4b,0x86,0x63,0x71,0xab, +0x6d,0xdb,0x46,0x1c,0x45,0x63,0x91,0x92,0x9c,0x31,0x10,0x11,0x54,0x21,0x00,0x00, +0x6a,0x4d,0x62,0x10,0xad,0x29,0x51,0xc6,0x42,0x8e,0x5a,0x30,0x30,0xcc,0x89,0x52, +0xa2,0xc5,0x32,0x49,0x85,0xda,0x61,0x4a,0x15,0xc8,0x62,0x70,0x71,0xe9,0x62,0x2c, +0x9c,0x31,0x10,0xcd,0x53,0x11,0x00,0x00,0x5c,0x5c,0x71,0x15,0x86,0xa3,0x52,0x69, +0x6e,0x9c,0x79,0x14,0x38,0x52,0xb3,0x02,0x9a,0xa4,0x85,0xa2,0xac,0x8c,0x86,0xaa, +0x6e,0x6c,0xc5,0xf3,0xb1,0x09,0xd4,0x03,0x9c,0x31,0x10,0x69,0x53,0x22,0x00,0x00, +0xda,0x9c,0x8e,0x5c,0x65,0xd9,0x90,0xda,0x76,0x2a,0x4d,0xcc,0x89,0xb5,0x75,0xd3, +0x4c,0xd8,0x59,0xa2,0x57,0x16,0x5e,0x6d,0x46,0x23,0x6d,0x4b,0x86,0x22,0xd2,0x19, +0x9c,0x31,0x10,0x8b,0xa9,0x46,0x30,0x00,0x80,0xeb,0x7a,0xeb,0x7a,0xeb,0x78,0xeb, +0x7e,0xeb,0x94,0xeb,0x90,0xeb,0x70,0xeb,0x49,0x03,0x2e,0x95,0xfd,0x2c,0x34,0xe9, +0xb0,0xc8,0xaf,0x4a,0x6e,0x6c,0xbb,0x6d,0x9c,0x31,0x10,0xb6,0xb9,0x56,0x30,0x00, +0x9c,0xab,0x7a,0xea,0x72,0xea,0x58,0xeb,0x32,0x82,0xb7,0xaa,0x70,0x2c,0x83,0x8d, +0xd2,0xcb,0x84,0x8a,0x65,0xaa,0x40,0x32,0x43,0xb1,0xca,0x0c,0x47,0xad,0xac,0x6c, +0x9c,0x31,0x10,0xfd,0xca,0x68,0x40,0x00,0x91,0x0b,0x98,0xeb,0x96,0xca,0x6b,0x0b, +0x56,0xcb,0x40,0xf4,0xb8,0xcd,0x53,0x2b,0x9e,0x8a,0x99,0x2a,0x98,0xca,0x9e,0xac, +0x69,0x6c,0x32,0x74,0x6f,0x92,0xa4,0x2a,0x9c,0x31,0x10,0xce,0xcb,0x57,0x40,0x00, +0x5d,0x55,0xb0,0xa6,0xa5,0x36,0x98,0xb5,0x67,0x24,0x36,0xc9,0x67,0x44,0xa4,0x84, +0x61,0x75,0xae,0x85,0xad,0x46,0x94,0xd6,0x6c,0xf5,0x2c,0xe9,0x6f,0x45,0x86,0x75, +0x9c,0x31,0x10,0x6a,0xcb,0x56,0x30,0x00,0x77,0x85,0xbc,0x86,0x9f,0x36,0x9e,0xe5, +0x5a,0xf5,0x1a,0xc1,0x8f,0x60,0x66,0x81,0xad,0x41,0xb6,0xc2,0x9b,0x16,0x98,0xe5, +0x1f,0x05,0x40,0xf8,0x8a,0xc4,0x6b,0x45,0x9c,0x31,0x10,0xf7,0xca,0x56,0x30,0x00, +0xd4,0x56,0x9d,0x66,0xae,0xc6,0x5a,0xf5,0x0e,0xa0,0x79,0xb0,0x66,0x25,0xb5,0xa5, +0xbe,0x75,0xad,0x25,0x8e,0xf5,0x1c,0xe9,0x37,0x49,0x82,0x45,0x75,0xb5,0xdc,0x55, +0x9c,0x31,0x10,0xcf,0xca,0x55,0x20,0x00,0xa7,0x55,0xb2,0xc6,0x51,0x02,0x06,0x91, +0x77,0xa4,0x5e,0x50,0xc5,0x85,0xbe,0x95,0xb5,0x25,0x88,0xe6,0x15,0x09,0x35,0x39, +0x7c,0x44,0x7d,0xc5,0xe4,0x45,0xab,0x65,0x9c,0x31,0x10,0xcf,0xca,0x55,0x20,0x00, +0xb4,0xc6,0x45,0x11,0x00,0x95,0x77,0x85,0x5e,0x75,0xcf,0x65,0xc0,0xa4,0xbb,0x15, +0x86,0xe5,0x0a,0xe9,0x31,0x56,0x7a,0x45,0x7f,0xb5,0xe8,0x54,0xb1,0x54,0xb6,0xd5, +0x9c,0x31,0x10,0x2b,0xda,0x55,0x10,0x00,0x63,0x01,0x3c,0x82,0x77,0xb5,0x6e,0x30, +0xa5,0x94,0xa4,0x85,0x9d,0x25,0x86,0xf5,0x44,0xfa,0x51,0x25,0x7c,0x75,0x79,0x95, +0xb6,0x64,0x99,0x65,0xa0,0xb6,0x69,0x05,0x9c,0x31,0x10,0xfb,0xdb,0x56,0x20,0x00, +0x3a,0xc1,0x6f,0x55,0x72,0x75,0x9b,0x75,0xaa,0x95,0x9d,0x25,0x90,0xe5,0x4c,0xf5, +0x46,0xe8,0x7e,0xf5,0x73,0x05,0xb2,0xe5,0x9b,0x05,0xa2,0xe5,0x74,0xf9,0x3e,0xe4, +0x9c,0x31,0x10,0xea,0xda,0x55,0x20,0x00,0x5d,0x75,0x7a,0x26,0x87,0xd6,0xb2,0x25, +0x9b,0x85,0x9c,0xb5,0x5f,0x21,0x3a,0x92,0x75,0xa6,0x70,0x25,0xa3,0xc4,0xa4,0x54, +0xa1,0x55,0x8c,0xc5,0x4d,0x25,0x42,0xa5,0x9c,0x31,0x10,0x50,0xd9,0x55,0x20,0x00, +0x80,0xb5,0x73,0x55,0xb0,0x95,0x9c,0x65,0xa4,0x75,0x7e,0x75,0x42,0x7a,0x50,0x99, +0x81,0x15,0x7b,0xe5,0xb4,0x05,0x99,0xd5,0xa5,0x35,0x71,0x99,0x3d,0x58,0x5c,0xe5, +0x9c,0x31,0x10,0xbc,0xda,0x44,0x10,0x00,0x7e,0x36,0x83,0xb6,0xb2,0x45,0x99,0x85, +0xa0,0xa5,0x69,0x29,0x3c,0xb8,0x61,0x84,0x7e,0x25,0x87,0xd6,0xb2,0x36,0x99,0x85, +0x9e,0x94,0x67,0x39,0x3c,0xb8,0x61,0x76,0x9c,0x31,0x10,0xd7,0xca,0x45,0x20,0x00, +0x82,0x35,0x8f,0xc5,0xe6,0x35,0xaf,0x94,0xc4,0x95,0x55,0x39,0x00,0xb9,0x37,0x65, +0x8a,0x65,0x81,0x95,0xe8,0x68,0xaf,0x69,0xc2,0x95,0x63,0x36,0x0e,0xda,0x1f,0x19, +0x9c,0x31,0x10,0xf2,0xda,0x45,0x20,0x00,0x88,0xc8,0x77,0x14,0xb0,0xd5,0x97,0x16, +0xa2,0xd6,0x7b,0x05,0x52,0xf0,0x42,0xb5,0x87,0x55,0x76,0x86,0xa7,0x75,0x9c,0x81, +0x9f,0x55,0x8a,0xb5,0x5f,0x39,0x3e,0x95,0x9c,0x31,0x10,0x99,0xca,0x44,0x10,0x00, +0x65,0x94,0x80,0x35,0x9b,0xb5,0xd4,0x49,0xaf,0x85,0xb6,0x85,0x61,0x45,0x18,0xc5, +0x23,0x08,0x92,0xf4,0x70,0xe5,0xd1,0x15,0xae,0xc1,0xbd,0x15,0x8e,0xd5,0x49,0x19, +0x9c,0x31,0x10,0x58,0xca,0x44,0x20,0x00,0x0a,0xc5,0x5f,0x55,0x84,0x71,0x8d,0x71, +0xd2,0x85,0xa9,0x56,0xb8,0xb5,0x77,0x25,0x32,0xd2,0x14,0xe2,0x7b,0x41,0x76,0x85, +0xab,0x75,0xbe,0x74,0xaf,0x54,0xae,0xa4,0x9c,0x31,0x10,0xe2,0xc9,0x44,0x20,0x00, +0x6b,0xa4,0x2b,0x51,0x21,0x62,0x7f,0xb6,0x79,0x25,0xaf,0xd5,0xbb,0x15,0xb2,0xc5, +0xab,0x35,0x6d,0x95,0x2b,0x61,0x25,0x62,0x76,0xb5,0x7e,0x15,0xa6,0xe5,0xbc,0x15, +0x9c,0x31,0x10,0x25,0xc9,0x35,0x20,0x00,0xb0,0xd4,0xb1,0x33,0x75,0xab,0x34,0x5a, +0x22,0x82,0x63,0xaa,0x86,0x33,0x93,0xd3,0xc4,0x23,0xa6,0xc2,0xbb,0x42,0x82,0xa3, +0x4c,0x65,0x23,0x9d,0x45,0x63,0x8a,0x8a,0x9c,0x31,0x10,0xe2,0xc9,0x44,0x20,0x00, +0x81,0x54,0xbf,0x95,0xa8,0x56,0xb7,0x95,0x9c,0x64,0x67,0x85,0x31,0x76,0x2d,0x51, +0x6a,0xc1,0x88,0x14,0x97,0xe5,0xbf,0x15,0xa4,0xd5,0xbb,0x35,0x84,0xa5,0x57,0x55, +0x9c,0x31,0x10,0xaa,0xc9,0x34,0x20,0x00,0x2c,0xa0,0x35,0x33,0x7e,0xde,0x82,0x0d, +0xab,0xeb,0xb0,0x0a,0xb0,0xd2,0xaf,0x34,0x7d,0xad,0x4c,0x55,0x2d,0xb2,0x3a,0x28, +0x88,0xd2,0x80,0x1c,0xb4,0xe4,0xaa,0x1c,0x9c,0x31,0x10,0x6b,0xc9,0x34,0x10,0x00, +0xb5,0xd3,0xa7,0x3a,0x7c,0xab,0x4b,0x5c,0x33,0xab,0x36,0x32,0x8c,0xd3,0x7e,0x1b, +0xb2,0xe4,0xa9,0x12,0xb2,0xd1,0xaa,0x43,0x80,0xa4,0x53,0x63,0x3a,0xa3,0x30,0x35, +0x9c,0x31,0x10,0xc9,0xca,0x24,0x10,0x00,0x7b,0xb5,0x85,0x3d,0x9f,0xbd,0xb5,0x41, +0xa8,0xb1,0xb6,0x55,0x87,0x99,0x64,0x6d,0x41,0x88,0x32,0x70,0x57,0x96,0x94,0x5e, +0x84,0x9d,0xbe,0x65,0x9d,0x8d,0xbb,0x71,0x9c,0x31,0x10,0x55,0xc9,0x33,0x00,0x00, +0x99,0xc9,0x78,0x35,0x4f,0xc1,0x3f,0x44,0x35,0xa4,0x84,0xe4,0x83,0x0d,0xa4,0x71, +0xad,0x0d,0xa7,0x61,0xb4,0x21,0x89,0xcd,0x69,0xb6,0x4c,0xc1,0x37,0xbe,0x49,0xbe, +0x9c,0x31,0x10,0xf6,0xc8,0x34,0x10,0x00,0x91,0x7a,0x7b,0x62,0xb7,0xa3,0xa0,0x54, +0xb0,0x84,0xac,0x92,0x80,0x41,0x63,0xc1,0x4b,0x3a,0x33,0xa4,0x57,0x85,0x90,0x5c, +0x80,0xa2,0xba,0x5a,0x9d,0x93,0xb1,0x4b,0x9c,0x31,0x10,0xdf,0xc9,0x34,0x00,0x00, +0xa7,0xa5,0x7c,0x44,0x64,0xb4,0x4c,0x4a,0x31,0x99,0x5f,0x82,0x8e,0x64,0x83,0x9d, +0xb7,0x64,0x9c,0x8b,0xb0,0x62,0xa4,0xa2,0x82,0x43,0x63,0xbb,0x57,0x44,0x2f,0xac, +0x9c,0x31,0x10,0xc8,0xc8,0x33,0x00,0x00,0x58,0x25,0x8d,0xc5,0x7f,0x35,0xb3,0x49, +0x9e,0x2e,0xad,0x49,0xa6,0xc2,0x8c,0xa5,0x63,0xe1,0x62,0x15,0x30,0x65,0x4a,0x8e, +0x84,0xee,0x80,0x85,0xa6,0xf9,0xa5,0x01,0x9c,0x31,0x10,0xe1,0xc9,0x33,0x10,0x00, +0xa8,0xd8,0xaa,0x20,0x97,0x54,0x6a,0x2c,0x6a,0x49,0x41,0xb9,0x39,0xb4,0x72,0x54, +0x86,0x9d,0x91,0x5d,0xae,0x1d,0x9f,0x59,0xb0,0x25,0x9e,0xd9,0x7b,0xa1,0x6a,0x5d, +0x9c,0x31,0x10,0x55,0xc9,0x33,0x00,0x00,0x58,0x21,0x37,0x56,0x51,0xb2,0x88,0xc6, +0x7f,0xb5,0xac,0xc9,0xa0,0xb1,0xae,0x49,0xa6,0x35,0x90,0x39,0x69,0xc5,0x6b,0x35, +0x40,0xc8,0x40,0x24,0x6f,0xd9,0x85,0x1d,0x9c,0x31,0x10,0xda,0xc9,0x32,0x00,0x00, +0x93,0xdd,0xab,0x1d,0xa3,0x59,0xaf,0x21,0x9c,0xdd,0x78,0xa1,0x6c,0x59,0x56,0xa5, +0x3a,0xd2,0x4e,0xb2,0x85,0x41,0x85,0x39,0xab,0x45,0xa1,0xb5,0xb1,0x45,0xa2,0xb9, +0x9c,0x31,0x10,0xda,0xc9,0x32,0x00,0x00,0x90,0x3d,0x6b,0x41,0x6b,0xb9,0x44,0x48, +0x3e,0xa8,0x67,0x59,0x87,0x9d,0x92,0x5d,0xaa,0xa1,0xa3,0x55,0xae,0xa6,0x9c,0x5a, +0x81,0xa2,0x6d,0x59,0x62,0x21,0x40,0x59,0x9c,0x31,0x10,0xbc,0xb8,0x32,0x00,0x00, +0x0a,0x29,0x6f,0xb4,0x86,0x35,0xbf,0xb1,0xc4,0x45,0xd7,0x96,0xca,0x55,0xad,0x91, +0x6a,0x61,0x63,0x75,0x2c,0x84,0x05,0x49,0x1a,0xd5,0x7e,0xf6,0x8c,0xf6,0xc8,0xf5, +0x9c,0x31,0x10,0xbc,0xb8,0x32,0x00,0x00,0xc0,0xf5,0xe0,0xe5,0xc0,0xf0,0xa2,0xe1, +0x65,0x15,0x60,0xc5,0x1f,0x46,0x06,0x71,0x29,0xa5,0x7e,0x35,0x99,0xb5,0xc8,0x44, +0xc7,0x95,0xd8,0x72,0xb7,0x65,0x96,0x85,0x9c,0x31,0x10,0xf4,0xb8,0x42,0x00,0x00, +0x6a,0xb4,0x5a,0x43,0x28,0xb2,0x0e,0x39,0x36,0xc3,0x75,0x3b,0xa2,0xbc,0xbc,0x43, +0xcb,0xab,0xd2,0x53,0xb9,0xa4,0x96,0x54,0x77,0x9b,0x55,0x5b,0x2d,0x9b,0x0b,0x53, +0x9c,0x31,0x10,0xc6,0xb6,0x33,0x00,0x00,0x28,0xe8,0x6c,0x15,0xaa,0xd5,0xc8,0x15, +0xdc,0xc5,0xd6,0x35,0xb6,0xb5,0x8d,0x55,0x6a,0x85,0x47,0x65,0x26,0x85,0x0e,0x6a, +0x35,0x79,0x7a,0x74,0xb1,0x75,0xc9,0x76,0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00, +0xd7,0x55,0xce,0x98,0xaf,0x94,0x89,0x82,0x66,0x72,0x47,0x55,0x25,0xb4,0x12,0x3a, +0x3b,0x96,0x80,0x54,0xb4,0x94,0xcc,0x66,0xd7,0x75,0xcb,0x69,0xab,0xc5,0x88,0x52, +0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00,0x67,0xa5,0x4b,0x44,0x28,0xa9,0x15,0x5a, +0x3c,0x79,0x7f,0x74,0xb0,0x71,0xc9,0x65,0xd4,0x89,0xc7,0x59,0xaa,0xca,0x8a,0x45, +0x6c,0x94,0x51,0x45,0x30,0xa5,0x18,0x5a,0x9c,0x31,0x10,0xf6,0xb5,0x34,0x00,0x00, +0x38,0x72,0x77,0x6a,0xab,0x6c,0xc5,0x4c,0xd2,0x8a,0xc8,0x52,0xad,0xb4,0x90,0x4c, +0x72,0x62,0x56,0x4b,0x34,0x8c,0x17,0x2b,0x2e,0x71,0x6d,0x6c,0xa2,0x6c,0xc2,0x6a, +0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00,0xd1,0x85,0xcc,0x76,0xb1,0x78,0x95,0x48, +0x77,0x66,0x5b,0x61,0x39,0x90,0x1a,0x31,0x28,0x96,0x64,0x65,0x9a,0x85,0xbc,0x65, +0xce,0xa5,0xcc,0x75,0xb4,0x65,0x99,0x39,0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00, +0x7b,0x66,0x60,0x75,0x40,0xa1,0x1f,0x31,0x22,0xa1,0x59,0x64,0x92,0x86,0xb9,0x55, +0xcc,0x84,0xce,0x76,0xb7,0x51,0x9d,0x64,0x7f,0x66,0x64,0x95,0x48,0x94,0x29,0x6a, +0x9c,0x31,0x10,0xe1,0xb4,0x33,0x00,0x00,0x20,0xc4,0x4f,0x55,0x88,0x62,0xb1,0x64, +0xc6,0x75,0xcd,0x85,0xbb,0x31,0xa1,0x96,0x83,0x44,0x69,0xb9,0x50,0x66,0x31,0xb4, +0x1e,0x4a,0x41,0x59,0x7b,0x48,0xa9,0xb5,0x9c,0x31,0x10,0x64,0xb5,0x23,0x00,0x00, +0xc2,0x75,0xcd,0x85,0xc1,0x56,0xab,0x91,0x8d,0x54,0x6f,0xa6,0x55,0x55,0x37,0x91, +0x1d,0x25,0x34,0x78,0x6e,0x5a,0xa2,0x99,0xc1,0x60,0xcd,0x95,0xc5,0x55,0xaf,0x99, +0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00,0x93,0x66,0x74,0x94,0x59,0x55,0x3b,0xb6, +0x22,0x20,0x2f,0x96,0x65,0x55,0x98,0x94,0xb9,0x66,0xc8,0x95,0xc5,0x55,0xaf,0x96, +0x95,0x74,0x78,0x75,0x61,0x65,0x49,0x85,0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00, +0x2d,0x4a,0x2b,0xb1,0x59,0x54,0x8e,0x92,0xb3,0x64,0xc4,0x75,0xc5,0x75,0xb2,0x75, +0x9b,0x75,0x7f,0x65,0x68,0x85,0x51,0x65,0x35,0x85,0x2a,0x79,0x4d,0x76,0x82,0x74, +0x9c,0x31,0x10,0xe1,0xb4,0x33,0x00,0x00,0xa9,0x85,0xbe,0x55,0xc3,0x78,0xb4,0x46, +0x9d,0xa5,0x84,0x35,0x6e,0xa5,0x5a,0x35,0x42,0xa5,0x2f,0x25,0x45,0xa9,0x75,0x29, +0xa1,0x95,0xb9,0x55,0xc2,0xa6,0xb9,0x64,0x9c,0x31,0x10,0xf9,0xb4,0x23,0x00,0x00, +0xa4,0x89,0x8b,0x49,0x70,0x91,0x5d,0x41,0x49,0xc1,0x35,0x14,0x41,0x96,0x6e,0x24, +0x9a,0x99,0xb3,0x66,0xbc,0x98,0xb6,0x79,0xa5,0x66,0x8c,0x78,0x6f,0x56,0x5a,0x81, +0x9c,0x31,0x10,0x96,0xb6,0x53,0x00,0x00,0x48,0xed,0x3a,0xad,0x49,0x0d,0x72,0xcc, +0x9f,0x0d,0xb4,0xe9,0xba,0xed,0xb4,0xc4,0xa0,0x2a,0x80,0xad,0x60,0xcd,0x4e,0xe9, +0x43,0x0d,0x46,0xed,0x66,0xed,0x92,0xed,0x9c,0x31,0x10,0x33,0xa3,0x31,0x00,0x00, +0xe7,0x8d,0xf8,0x4c,0xe8,0xb1,0xbe,0x6d,0x82,0x0d,0x44,0x4e,0x1a,0x48,0x0b,0xaa, +0x1b,0x44,0x59,0x49,0xa7,0x6e,0xe0,0x4c,0xf2,0x89,0xe4,0x6e,0xbb,0x2d,0x77,0x4a, +0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00,0x58,0x4d,0x42,0x89,0x42,0x31,0x5a,0x8d, +0x82,0x2d,0xa8,0x6d,0xbf,0xd5,0xc0,0x30,0xa9,0x96,0x7f,0x15,0x4f,0xd1,0x32,0x35, +0x35,0x91,0x59,0x89,0x8b,0x31,0xb8,0x89,0x9c,0x31,0x10,0x82,0xb3,0x22,0x00,0x00, +0xcd,0x69,0xc3,0x8d,0x9e,0x69,0x6b,0x6d,0x3f,0x6c,0x2f,0x26,0x43,0xa9,0x70,0x31, +0x9f,0xa9,0xbd,0x49,0xc1,0x6d,0xac,0x91,0x87,0x31,0x5e,0xc9,0x46,0x51,0x46,0x71, +0x9c,0x31,0x10,0x8f,0xa3,0x12,0x00,0x00,0x40,0x94,0x87,0x51,0xc1,0xac,0xdb,0x23, +0xd2,0x8b,0xae,0x72,0x74,0x6c,0x40,0x8b,0x2a,0x32,0x3b,0x8d,0x68,0x23,0x97,0xaa, +0xb4,0x63,0xbc,0x4b,0xaf,0xa4,0x8f,0x6b,0x9c,0x31,0x10,0xc8,0x93,0x22,0x00,0x00, +0x4a,0xe1,0x11,0x14,0x0c,0xd2,0x3e,0x5c,0x86,0x9a,0xbf,0x0c,0xd8,0xa2,0xd1,0x23, +0xa8,0xa3,0x6a,0x64,0x38,0x9c,0x2d,0x1a,0x49,0x63,0x7a,0xa3,0xa3,0x22,0xb6,0xe4, +0x9c,0x31,0x10,0x61,0x83,0x21,0x00,0x00,0xec,0x6d,0xb8,0xb1,0x6e,0x70,0x32,0x4d, +0x23,0x2c,0x42,0xa5,0x77,0x85,0xa3,0xaa,0xb5,0x6c,0xae,0x26,0x95,0x91,0x77,0x91, +0x67,0xb5,0x64,0x51,0x6f,0x2d,0x7d,0x71,0x9c,0x31,0x10,0xe5,0x53,0x21,0x00,0x00, +0xc6,0x61,0xde,0xa1,0xb5,0x65,0x91,0x5d,0x5d,0x8d,0x69,0xa1,0x6b,0x5d,0x85,0x11, +0x8d,0x9d,0x85,0xdd,0x6a,0x30,0x6e,0x71,0x79,0x95,0x8d,0x55,0x98,0xe1,0x8a,0xa2, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_REFUSE.txt b/config/_default_cfg_src_/res/en/SOUND_REFUSE.txt new file mode 100644 index 0000000..b911fcb --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_REFUSE.txt @@ -0,0 +1,605 @@ +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x59,0x15,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x59,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x15,0x55,0x95,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x51,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x59,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x51,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x56,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x15,0x55,0x55,0x55,0x15,0x55,0x15,0x55,0x55,0x55,0x55,0x55,0x65,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x95,0x55,0x45,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x65,0x55,0x55,0x55,0x15,0x55, +0x65,0x55,0x15,0x55,0x55,0x55,0x55,0x55,0x45,0x55,0x95,0x55,0x95,0x55,0x95,0x15, +0x9c,0x31,0x10,0x74,0x10,0x00,0x00,0x00,0xb5,0x55,0x96,0x55,0xa6,0x55,0xb0,0x55, +0xa4,0x55,0x70,0x95,0x7e,0x56,0x89,0x15,0x91,0x59,0x6d,0x55,0x78,0x15,0xbf,0x55, +0xc6,0x55,0x81,0x55,0x9a,0x59,0xb6,0x55,0x9c,0x31,0x10,0x74,0x10,0x00,0x00,0x00, +0xb1,0x56,0xbe,0x15,0x75,0x65,0x60,0x55,0x67,0x51,0x72,0x15,0xaa,0x55,0x98,0x55, +0x8e,0x56,0xbf,0x95,0xd6,0x55,0xa5,0x55,0x7c,0x55,0xa7,0x59,0xc2,0x65,0xd8,0x95, +0x9c,0x31,0x10,0x95,0x94,0x31,0x22,0x11,0x7e,0xd5,0x7e,0xd5,0x7c,0xd5,0x74,0xd5, +0x66,0xd5,0x58,0xd5,0x46,0xd5,0x36,0xc5,0x26,0x28,0x18,0xea,0x12,0x98,0x0e,0xd5, +0x10,0xd5,0x12,0xd5,0x13,0x15,0x12,0xd5,0x9c,0x31,0x10,0x05,0x95,0x21,0x11,0x11, +0x14,0xed,0x14,0xf4,0x16,0xf1,0x18,0xd4,0x18,0xf1,0x18,0xf0,0x1b,0x11,0x1c,0xcd, +0x19,0x0d,0x18,0xf1,0x20,0xf1,0x20,0xcc,0x1e,0xed,0x20,0xf1,0x25,0x09,0x22,0x69, +0x9c,0x31,0x10,0x4e,0xb8,0x64,0x33,0x21,0x6d,0x0d,0x70,0x6d,0xa5,0x86,0x78,0xac, +0x19,0x0d,0x66,0xed,0xba,0xed,0x64,0xed,0x18,0xed,0x7a,0xed,0xb4,0xed,0x50,0xed, +0x24,0xed,0x92,0xed,0xb2,0xed,0x3e,0xed,0x9c,0x31,0x10,0x99,0xb5,0x32,0x22,0x20, +0x2d,0x15,0x9e,0xa9,0xa2,0xe5,0x2e,0x91,0x3d,0x54,0xae,0xa1,0x94,0xd5,0x24,0x91, +0x4f,0x19,0xb7,0x12,0x82,0xd5,0x22,0xe5,0x69,0x15,0xb8,0xc4,0x66,0x95,0x20,0xe5, +0x9c,0x31,0x10,0x04,0xb4,0x32,0x22,0x20,0x7c,0x80,0xb5,0x15,0x52,0xd5,0x28,0xd5, +0x92,0x85,0xad,0x11,0x3a,0x95,0x37,0x52,0xa6,0x58,0x98,0xa5,0x2f,0x15,0x4f,0x10, +0xae,0xe0,0x82,0x55,0x27,0x15,0x5e,0xea,0x9c,0x31,0x10,0x8b,0xb4,0x33,0x22,0x20, +0xb9,0x96,0x76,0x55,0x1e,0xd5,0x70,0xd5,0xc3,0x84,0x68,0x55,0x21,0x14,0x82,0x40, +0xc1,0x55,0x5a,0x95,0x2d,0x15,0x94,0x56,0xb4,0xd5,0x4a,0x55,0x3b,0x56,0xa6,0x65, +0x9c,0x31,0x10,0x04,0xb4,0x32,0x22,0x20,0xa6,0xd4,0x3a,0x95,0x4b,0x65,0xb4,0xa1, +0x96,0x95,0x30,0x95,0x5f,0x29,0xbf,0x12,0x84,0x95,0x2c,0xd2,0x72,0xd5,0xc1,0x54, +0x70,0x95,0x2e,0xd5,0x88,0x80,0xbf,0x15,0x9c,0x31,0x10,0x34,0xb5,0x42,0x33,0x21, +0x5f,0x6d,0x36,0x88,0x9c,0x12,0xb7,0x95,0x4e,0x4d,0x40,0x8c,0xab,0x52,0xab,0x71, +0x40,0x6d,0x50,0x90,0xb8,0x70,0x9b,0x4d,0x38,0x6d,0x63,0x92,0xc0,0x8c,0x89,0x4c, +0x9c,0x31,0x10,0x4e,0xb4,0x32,0x22,0x10,0x32,0xd5,0x76,0xd5,0xc3,0x58,0x74,0x51, +0x34,0xd5,0x8a,0x80,0xc1,0x15,0x62,0x96,0x3b,0x15,0x9c,0x56,0xb9,0x11,0x52,0x95, +0x45,0x11,0xac,0xa5,0xac,0xd4,0x44,0x95,0x9c,0x31,0x10,0x04,0xb4,0x32,0x22,0x20, +0x55,0x54,0xb8,0xe1,0x9c,0x95,0x3c,0xd5,0x67,0x69,0xc1,0x12,0x8a,0xd9,0x38,0xd5, +0x7a,0xd5,0xc3,0x05,0x78,0x95,0x38,0xd5,0x8c,0x80,0xc1,0x15,0x66,0x95,0x3f,0x15, +0x9c,0x31,0x10,0x8f,0xb4,0x32,0x12,0x10,0x9e,0x95,0xba,0xd2,0x56,0x95,0x49,0x12, +0xae,0x98,0xae,0xa5,0x48,0x95,0x59,0x51,0xba,0xe1,0x9e,0x55,0x40,0xd5,0x69,0x25, +0xc3,0x14,0x8e,0x51,0x3c,0xd4,0x7c,0xd5,0x9c,0x31,0x10,0xc1,0xb4,0x33,0x22,0x10, +0xc5,0x44,0x7a,0x95,0x3c,0xd5,0x8e,0x81,0xc3,0x55,0x6a,0x55,0x43,0x15,0xa0,0x56, +0xbb,0x15,0x58,0x95,0x4d,0x55,0xae,0xa4,0xae,0xe4,0x4c,0x95,0x5b,0x54,0xba,0xe1, +0x9c,0x31,0x10,0x76,0xb3,0x22,0x21,0x10,0xa1,0x55,0x44,0x65,0x6d,0xa9,0xc3,0xa2, +0x90,0x15,0x40,0x56,0x7e,0x55,0xc5,0x85,0x7e,0x14,0x41,0x55,0x91,0x00,0xc3,0x96, +0x6d,0x15,0x46,0x95,0xa2,0x0a,0xbc,0x61,0x9c,0x31,0x10,0x34,0xb5,0x42,0x33,0x21, +0x5e,0x6d,0x50,0x8c,0xb1,0x72,0xb1,0x71,0x51,0x6d,0x5e,0x90,0xbc,0x70,0xa3,0x6d, +0x48,0x6e,0x70,0x8d,0xc4,0x35,0x91,0x75,0x44,0x50,0x81,0x6c,0xc5,0x6a,0x7f,0x6c, +0x9c,0x31,0x10,0x6e,0xb3,0x32,0x21,0x10,0x45,0x55,0x93,0x11,0xc2,0x95,0x6e,0x15, +0x4a,0x95,0xa3,0x16,0xbb,0x51,0x60,0x15,0x54,0x95,0xb1,0x25,0xb0,0x55,0x54,0x15, +0x61,0x90,0xbc,0x61,0xa2,0x59,0x4b,0x52,0x9c,0x31,0x10,0x76,0xb3,0x22,0x21,0x10, +0x71,0xa9,0xc2,0x92,0x92,0x15,0x47,0x55,0x82,0x95,0xc4,0x84,0x81,0x45,0x48,0x55, +0x93,0x00,0xc2,0x96,0x71,0x15,0x4d,0x55,0xa4,0x06,0xbc,0x61,0x62,0x15,0x57,0x92, +0x9c,0x31,0x10,0x7b,0xb3,0x32,0x12,0x10,0xb2,0x28,0xb1,0x25,0x56,0x55,0x64,0xa1, +0xbc,0x61,0xa3,0x15,0x4e,0x55,0x73,0x65,0xc3,0x90,0x93,0x11,0x49,0x55,0x84,0x55, +0xc5,0x95,0x82,0x15,0x4a,0x55,0x94,0x11,0x9c,0x31,0x10,0x6e,0xb3,0x32,0x21,0x10, +0xc2,0x95,0x72,0x16,0x4f,0x95,0xa4,0x16,0xbc,0x51,0x64,0x15,0x59,0x95,0xb1,0x25, +0xb1,0x55,0x58,0x55,0x66,0x94,0xbb,0x61,0xa3,0x15,0x50,0x55,0x75,0x99,0xc2,0x92, +0x9c,0x31,0x10,0x76,0xb3,0x22,0x21,0x10,0x94,0x05,0x4c,0x55,0x85,0x55,0xc4,0x85, +0x83,0x15,0x4d,0x55,0x95,0x00,0xc1,0x96,0x74,0x15,0x52,0x55,0xa4,0x06,0xba,0x61, +0x65,0x15,0x5b,0x92,0xb1,0x28,0xb0,0x25,0x9c,0x31,0x10,0x6e,0xb3,0x32,0x21,0x10, +0x5a,0x15,0x67,0x91,0xba,0x61,0xa2,0x56,0x52,0x55,0x76,0xa6,0xc0,0x95,0x94,0x15, +0x4f,0x55,0x85,0x51,0xc2,0x98,0x84,0x11,0x50,0x55,0x95,0x11,0xbf,0x95,0x75,0x15, +0x9c,0x31,0x10,0x34,0xb5,0x42,0x33,0x21,0x54,0x6d,0xa3,0x4d,0xb9,0x6d,0x68,0x68, +0x5d,0x31,0xaf,0x76,0xaf,0x50,0x5c,0x6c,0x69,0x8d,0xb9,0x70,0xa2,0x6d,0x55,0x6d, +0x77,0x71,0xbf,0x8c,0x93,0x6d,0x51,0x6c,0x9c,0x31,0x10,0xb7,0xb3,0x22,0x11,0x10, +0x86,0x6d,0xc0,0xa5,0x84,0x4d,0x52,0x71,0x94,0x40,0xbd,0x8d,0x75,0x31,0x56,0x8d, +0xa2,0x25,0xb7,0x94,0x68,0x4d,0x5e,0xac,0xae,0x59,0xad,0x55,0x5e,0x4d,0x69,0xb4, +0x9c,0x31,0x10,0x53,0xa3,0x22,0x21,0x10,0xef,0x61,0xc3,0x15,0x2e,0x55,0x6f,0x66, +0xf9,0x91,0xa7,0x15,0x27,0x55,0x8c,0x65,0xfd,0x84,0x89,0x11,0x27,0x55,0xa8,0x41, +0xf9,0x95,0x6d,0x65,0x30,0x45,0xc3,0x16,0x9c,0x31,0x10,0x92,0xa3,0x22,0x11,0x10, +0xed,0x91,0x54,0x51,0x40,0xc5,0xda,0x55,0xdb,0x71,0x40,0x51,0x55,0xb1,0xec,0x58, +0xc4,0x45,0x31,0x6c,0x6f,0x96,0xf7,0xb0,0xa8,0x29,0x2b,0x71,0x8c,0x6d,0xfb,0xc9, +0x9c,0x31,0x10,0x01,0xa3,0x32,0x21,0x20,0x8b,0x15,0x2b,0x95,0xa8,0x10,0xf7,0xa6, +0x6f,0x18,0x34,0x95,0xc3,0x15,0xea,0x61,0x57,0x15,0x43,0x92,0xd8,0x28,0xd9,0x65, +0x43,0x55,0x58,0x95,0xe9,0x51,0xc2,0x55,0x9c,0x31,0x10,0x53,0xa3,0x22,0x21,0x10, +0x35,0x65,0x70,0xa6,0xf3,0x95,0xa8,0x11,0x2e,0x55,0x8b,0x51,0xf7,0x88,0x8c,0x15, +0x2f,0x45,0xa7,0x01,0xf2,0x95,0x71,0x15,0x37,0x45,0xc0,0x06,0xe6,0x61,0x58,0x15, +0x9c,0x31,0x10,0xb8,0xa5,0x42,0x23,0x20,0x46,0x6c,0xd5,0x51,0xd4,0x6d,0x46,0x4d, +0x5b,0x8d,0xe5,0x70,0xbe,0x6e,0x38,0x6d,0x72,0x8d,0xef,0x6c,0xa4,0x6d,0x31,0x6c, +0x8c,0x6d,0xf4,0x89,0x8c,0x12,0x31,0x76,0x9c,0x31,0x10,0x81,0xa3,0x22,0x23,0x20, +0xa4,0x51,0xee,0x55,0x72,0x15,0x3a,0x55,0xbd,0x55,0xe3,0x61,0x5c,0x65,0x48,0xa2, +0xd0,0x25,0xd4,0x65,0x49,0x65,0x59,0xa1,0xe2,0x51,0xbe,0x16,0x3a,0x55,0x72,0xa6, +0x9c,0x31,0x10,0x66,0xa4,0x22,0x11,0x10,0xed,0xa1,0xa5,0x54,0x34,0x81,0x8b,0x61, +0xee,0x91,0x8b,0x64,0x35,0x95,0xa4,0x50,0xeb,0x91,0x72,0x34,0x3c,0x81,0xbb,0x51, +0xe0,0x85,0x5b,0x59,0x49,0x95,0xcf,0x69,0x9c,0x31,0x10,0x9f,0xa3,0x32,0x22,0x10, +0xcf,0x55,0x49,0x55,0x5e,0x55,0xde,0x62,0xb9,0x65,0x3d,0x66,0x71,0x95,0xe7,0x92, +0xa4,0x55,0x37,0x95,0x8a,0x55,0xea,0x95,0x8b,0x15,0x39,0x55,0xa2,0x55,0xe6,0x52, +0x9c,0x31,0x10,0x4b,0xa3,0x32,0x21,0x10,0x73,0x55,0x3f,0x96,0xba,0x15,0xdd,0x62, +0x5d,0x55,0x4d,0x92,0xce,0x59,0xcd,0x61,0x4c,0x54,0x60,0x91,0xdc,0x55,0xb9,0x55, +0x40,0x55,0x74,0x62,0xe6,0x99,0xa4,0x11,0x9c,0x31,0x10,0xc1,0xa3,0x23,0x21,0x11, +0x3b,0x95,0x8c,0x15,0xe8,0x89,0x8c,0x05,0x3c,0x54,0xa4,0x01,0xe4,0x45,0x75,0x55, +0x43,0x45,0xb9,0x56,0xd9,0x55,0x5f,0x51,0x50,0x85,0xca,0x25,0xca,0x55,0x4c,0x26, +0x9c,0x31,0x10,0xbf,0xa4,0x32,0x21,0x10,0x61,0x65,0xd6,0xa1,0xb4,0xd9,0x42,0x95, +0x70,0x95,0xdf,0x12,0xa0,0xd4,0x3c,0xa1,0x89,0x25,0xe0,0xd5,0x88,0xd5,0x3e,0xa5, +0x9e,0x91,0xdf,0x16,0x72,0x99,0x44,0xd2,0x9c,0x31,0x10,0xdd,0xb9,0x75,0x55,0x42, +0x98,0xed,0xa8,0xed,0x70,0xed,0x68,0xed,0xab,0x0d,0xa6,0x6e,0xb7,0xc6,0x4e,0x68, +0x93,0x6d,0xac,0x8d,0x3f,0x0d,0xcf,0x0d,0x5c,0x8d,0x7d,0x6d,0xbe,0x8d,0x38,0xed, +0x9c,0x31,0x10,0xb9,0xb9,0x33,0x31,0x21,0xc5,0x49,0x72,0x79,0x67,0x65,0xca,0xc1, +0x3a,0xd1,0xb5,0x5a,0x8a,0x79,0x53,0x59,0xd2,0xe5,0x44,0xb5,0x9f,0x65,0xa0,0x79, +0x43,0x39,0xd3,0x04,0x54,0x95,0x87,0x70,0x9c,0x31,0x10,0x56,0xb9,0x32,0x22,0x21, +0xb4,0x91,0x3b,0x14,0xc9,0x38,0x66,0x85,0x6f,0x70,0xc4,0xb1,0x3a,0xe5,0xbb,0x46, +0x7e,0x75,0x5b,0x66,0xce,0xd6,0x40,0xc5,0xa9,0x66,0x96,0x75,0x49,0x46,0xd0,0xf4, +0x9c,0x31,0x10,0xc4,0xb9,0x33,0x22,0x20,0x4c,0xa5,0x93,0x70,0xaa,0x85,0x3d,0x29, +0xcf,0x28,0x5c,0x84,0x7b,0x70,0xbc,0xa5,0x39,0x09,0xc3,0x39,0x72,0x79,0x65,0x65, +0xc8,0xc2,0x3c,0xd5,0xb1,0x56,0x88,0x79,0x9c,0x31,0x10,0x59,0xb8,0x33,0x22,0x20, +0x53,0xb9,0xce,0xd5,0x44,0x75,0x9d,0xd5,0xa0,0x19,0x43,0x79,0xcf,0x28,0x54,0x35, +0x87,0xe0,0xb2,0x34,0x3b,0x35,0xc7,0x68,0x66,0x05,0x6f,0xe4,0xc2,0x72,0x3a,0xe5, +0x9c,0x31,0x10,0x8e,0xb9,0x33,0x22,0x10,0xbb,0x4a,0x7c,0x79,0x5b,0x65,0xcc,0xd1, +0x40,0xc5,0xa7,0x66,0x94,0x75,0x4b,0x49,0xd0,0xf5,0x4a,0xa5,0x93,0x71,0xa8,0x84, +0x3f,0x29,0xcb,0x18,0x5c,0x85,0x7b,0x70,0x9c,0x31,0x10,0xd9,0xb9,0x33,0x22,0x21, +0xba,0xa1,0x3b,0x05,0xc1,0x39,0x72,0x79,0x65,0x65,0xc6,0xc1,0x3c,0xd5,0xb1,0x56, +0x88,0x79,0x53,0x59,0xce,0xe5,0x44,0xb5,0x9d,0x65,0x9e,0x88,0x45,0x39,0xcd,0x08, +0x9c,0x31,0x10,0xf4,0xb8,0x43,0x33,0x21,0x54,0x1b,0x88,0xf1,0xb4,0x14,0x3c,0x9d, +0xc7,0xb5,0x68,0x0c,0x70,0xf3,0xc2,0x3b,0x3b,0x73,0xb9,0xcc,0x7d,0x04,0x5b,0xe4, +0xcb,0x5a,0x41,0x4b,0xa6,0xe3,0x94,0x04,0x9c,0x31,0x10,0xd6,0xb8,0x32,0x22,0x20, +0x4b,0x9a,0xcf,0x04,0x4c,0x55,0x91,0xe0,0xa8,0x24,0x3f,0x59,0xc9,0x48,0x5e,0x25, +0x7b,0xe0,0xb8,0x55,0x3b,0x05,0xbf,0x79,0x72,0x05,0x65,0xc5,0xc4,0x92,0x3e,0xb4, +0x9c,0x31,0x10,0x9c,0xb8,0x32,0x22,0x10,0xaf,0xb6,0x88,0x09,0x53,0xaa,0xca,0xd5, +0x46,0x75,0x9b,0xd5,0x9c,0x14,0x45,0x79,0xcb,0x28,0x54,0x35,0x85,0xe0,0xb0,0x34, +0x3d,0x35,0xc5,0x68,0x66,0x16,0x6f,0xd4,0x9c,0x31,0x10,0xc7,0xb8,0x33,0x21,0x10, +0xbe,0x76,0x3c,0xe5,0xb7,0x99,0x7c,0x09,0x5b,0xc5,0xc6,0xb5,0x42,0x95,0xa5,0xc6, +0x92,0x15,0x4b,0x99,0xca,0xf5,0x4c,0x55,0x91,0xd1,0xa6,0x24,0x41,0x55,0xc7,0x48, +0x9c,0x31,0x10,0x0e,0xb8,0x33,0x22,0x11,0x5c,0x25,0x7b,0xe0,0xb6,0x51,0x3b,0x04, +0xbd,0x79,0x70,0x05,0x65,0xc5,0xc4,0x91,0x3e,0xb5,0xad,0xa9,0x86,0x09,0x53,0xa9, +0xc8,0xd5,0x46,0x75,0x9b,0xc5,0x9c,0x19,0x9c,0x31,0x10,0x8d,0xb8,0x33,0x21,0x20, +0x45,0x79,0xc9,0x28,0x54,0x45,0x85,0xd4,0xae,0x45,0x3f,0x39,0xc3,0x59,0x66,0x15, +0x6f,0xd5,0xbc,0x75,0x3c,0xe5,0xb5,0x99,0x7a,0x09,0x5d,0xb5,0xc6,0xb2,0x42,0x95, +0x9c,0x31,0x10,0x9e,0xb8,0x42,0x22,0x20,0xa4,0xdb,0x91,0x0c,0x4d,0xcc,0xc9,0x7b, +0x4d,0x33,0x90,0xea,0xa5,0x1b,0x42,0xac,0xc6,0xa4,0x5d,0x13,0x7a,0xea,0xb7,0x29, +0x3e,0x7c,0xbc,0xbe,0x71,0x0c,0x65,0xe3,0x9c,0x31,0x10,0xd6,0xb8,0x32,0x22,0x20, +0xc0,0x92,0x3e,0xb5,0xad,0xa6,0x86,0x09,0x53,0xaa,0xc6,0xd5,0x46,0x75,0x99,0xc5, +0x9a,0x15,0x47,0x79,0xc7,0x14,0x54,0x45,0x85,0xd0,0xac,0x44,0x3f,0x29,0xbf,0x58, +0x9c,0x31,0x10,0x9c,0xb8,0x32,0x22,0x10,0x66,0x26,0x6f,0xd4,0xba,0x76,0x3c,0xe4, +0xb3,0x9a,0x7a,0x05,0x5d,0xb6,0xc2,0xb2,0x42,0xa5,0xa3,0xb6,0x8e,0x18,0x4d,0x8a, +0xc6,0xf4,0x4c,0x65,0x8f,0xd1,0xa2,0x34,0x9c,0x31,0x10,0x13,0xb8,0x33,0x22,0x10, +0x41,0x59,0xc3,0x48,0x5c,0x35,0x79,0xd0,0xb4,0x65,0x3d,0x04,0xb9,0x79,0x70,0x15, +0x65,0xc5,0xbe,0x91,0x3e,0xc5,0xab,0xa5,0x84,0x19,0x55,0xa9,0xc4,0xd5,0x48,0x85, +0x9c,0x31,0x10,0x59,0xb8,0x33,0x22,0x20,0x97,0xc5,0x98,0x28,0x47,0x69,0xc5,0x18, +0x54,0x45,0x83,0xd0,0xac,0x45,0x3f,0x29,0xbd,0x59,0x66,0x25,0x6f,0xc5,0xb8,0x75, +0x3e,0xe5,0xb1,0x99,0x7a,0x19,0x5d,0xb5,0x9c,0x31,0x10,0xd6,0xb8,0x32,0x22,0x20, +0xc0,0xb2,0x42,0xa5,0xa1,0xb6,0x8e,0x18,0x4d,0x8a,0xc4,0xf4,0x4e,0x65,0x8d,0xc1, +0xa2,0x34,0x43,0x45,0xc1,0x38,0x5e,0x35,0x79,0xd0,0xb2,0x65,0x3f,0x05,0xb7,0x78, +0x9c,0x31,0x10,0x13,0xb8,0x33,0x22,0x10,0x70,0x15,0x65,0xb5,0xbc,0x92,0x40,0xc5, +0xa9,0xa6,0x84,0x19,0x55,0x9a,0xc2,0xd5,0x48,0x85,0x97,0xb5,0x98,0x29,0x49,0x69, +0xc3,0x29,0x56,0x45,0x83,0xd1,0xa8,0x45,0x9c,0x31,0x10,0xe9,0xb8,0x43,0x33,0x20, +0x41,0x94,0xbc,0xac,0x67,0x13,0x6f,0xe3,0xb8,0x43,0x41,0x72,0xb2,0xbd,0x7a,0x0e, +0x5d,0xd4,0xc0,0x5a,0x44,0x52,0xa0,0xdb,0x8e,0x14,0x4f,0xc4,0xc3,0x7a,0x4f,0x33, +0x9c,0x31,0x10,0x0b,0xb8,0x23,0x22,0x10,0x8d,0xc1,0xa0,0x39,0x45,0x49,0xbf,0x38, +0x5c,0x45,0x79,0xc0,0xae,0x61,0x41,0x05,0xb5,0x79,0x70,0x29,0x67,0xb5,0xba,0xa1, +0x42,0xc1,0xa7,0x99,0x82,0x19,0x55,0x99,0x9c,0x31,0x10,0x59,0xb8,0x33,0x22,0x20, +0xc0,0xd5,0x4a,0x85,0x95,0xb5,0x96,0x39,0x49,0x69,0xc1,0x18,0x56,0x55,0x83,0xc0, +0xa8,0x55,0x43,0x25,0xb9,0x59,0x66,0x35,0x6f,0xc5,0xb4,0x85,0x40,0xe5,0xaf,0x89, +0x9c,0x31,0x10,0xce,0xb8,0x22,0x22,0x20,0x7a,0x29,0x5d,0xa9,0xbc,0xb2,0x44,0xa4, +0x9f,0xa6,0x8c,0x28,0x4f,0x8a,0xc0,0xf4,0x50,0x75,0x8d,0xc0,0x9e,0x39,0x47,0x49, +0xbd,0x38,0x5e,0x45,0x79,0xc0,0xae,0x61,0x9c,0x31,0x10,0x27,0xa8,0x32,0x21,0x20, +0x05,0x05,0xe9,0x69,0x60,0x25,0x4f,0xb5,0xf2,0xa2,0x08,0xc5,0xcd,0x96,0x88,0x29, +0x2f,0x9a,0xfc,0xd5,0x16,0x85,0xab,0xb5,0xac,0x34,0x17,0x69,0xfd,0x14,0x2e,0x55, +0x9c,0x31,0x10,0x6d,0xa8,0x32,0x21,0x10,0x87,0xc0,0xce,0x54,0x09,0x35,0xf1,0x48, +0x4e,0x36,0x61,0xb4,0xe6,0x86,0x06,0xe4,0xdb,0x8a,0x72,0x29,0x3d,0xa6,0xf8,0xb6, +0x0e,0xa5,0xbd,0xa6,0x9a,0x35,0x21,0x7a,0x9c,0x31,0x10,0x62,0xa8,0x23,0x23,0x10, +0xfd,0x05,0x22,0x75,0x99,0xb1,0xbe,0x45,0x0f,0x49,0xf7,0x38,0x40,0x45,0x71,0xc0, +0xdc,0x71,0x07,0x05,0xe5,0x69,0x62,0x25,0x4d,0xb5,0xf0,0xa1,0x0a,0xc1,0xcd,0x91, +0x9c,0x31,0x10,0xea,0xa8,0x42,0x23,0x21,0x8a,0x0d,0x2e,0xcd,0xfb,0x6b,0x19,0x43, +0xa9,0xdb,0xac,0x1b,0x17,0xac,0xfa,0x8b,0x32,0x2b,0x83,0xdb,0xcd,0x2b,0x09,0x94, +0xee,0xa4,0x51,0x1b,0x5e,0xdb,0xe6,0x43,0x9c,0x31,0x10,0xf3,0xa8,0x32,0x22,0x20, +0x06,0xe5,0xd7,0x8a,0x74,0x29,0x3d,0xa5,0xf4,0xc6,0x10,0xa4,0xb9,0xa6,0x9a,0x39, +0x21,0x7a,0xfa,0xf4,0x24,0x75,0x97,0xb4,0xbc,0x44,0x11,0x45,0xf3,0x34,0x3e,0x45, +0x9c,0x31,0x10,0xf6,0xa8,0x22,0x22,0x21,0x71,0xb0,0xd8,0x71,0x09,0x05,0xe3,0x69, +0x62,0x35,0x4f,0xa5,0xec,0xa2,0x0c,0xc1,0xc9,0x9a,0x86,0x38,0x2f,0x8a,0xf6,0xe1, +0x1a,0x81,0xa7,0xa5,0xaa,0x39,0x19,0x69,0x9c,0x31,0x10,0xa4,0xa8,0x32,0x22,0x11, +0xf5,0x14,0x32,0x65,0x83,0xb4,0xca,0x64,0x0d,0x25,0xeb,0x48,0x50,0x35,0x5f,0xb4, +0xe2,0x86,0x0a,0xe4,0xd5,0x7a,0x74,0x39,0x3f,0x96,0xf2,0xc6,0x12,0xa5,0xb7,0xa6, +0x9c,0x31,0x10,0xe2,0xa8,0x33,0x21,0x10,0x98,0x39,0x25,0x79,0xf7,0x05,0x26,0x75, +0x95,0xb5,0xba,0x44,0x13,0x45,0xef,0x38,0x42,0x45,0x71,0xb4,0xd4,0x75,0x0b,0x05, +0xdf,0x69,0x62,0x35,0x4f,0xa5,0xe8,0xa1,0x9c,0x31,0x10,0xeb,0xa8,0x22,0x22,0x20, +0x0e,0xc1,0xc5,0x8a,0x86,0x39,0x33,0x8a,0xf2,0xe2,0x1c,0x91,0xa7,0xa2,0xa8,0x48, +0x1b,0x5a,0xf3,0x18,0x32,0x65,0x83,0xb0,0xc6,0x65,0x0f,0x28,0xe7,0x48,0x52,0x49, +0x9c,0x31,0x10,0x80,0xa8,0x43,0x32,0x20,0x5f,0xd3,0xe0,0x4b,0x0c,0x73,0xd3,0xbc, +0x73,0x1c,0x40,0xcb,0xee,0x63,0x16,0x5b,0xb6,0xcb,0x9a,0x23,0x28,0xad,0xf3,0x85, +0x28,0x3b,0x94,0xda,0xb8,0x2b,0x14,0xa3,0x9c,0x31,0x10,0xf6,0xa8,0x22,0x22,0x21, +0xed,0x38,0x42,0x55,0x71,0xb0,0xd2,0x71,0x0d,0x05,0xdd,0x69,0x62,0x35,0x51,0xa5, +0xe6,0xa2,0x10,0xc0,0xc5,0x8a,0x84,0x39,0x33,0x8a,0xf0,0xd1,0x1e,0x91,0xa5,0xa5, +0x9c,0x31,0x10,0xa4,0xa8,0x32,0x22,0x11,0xa6,0x45,0x1d,0x59,0xef,0x14,0x34,0x65, +0x83,0xa0,0xc4,0x64,0x13,0x29,0xe3,0x48,0x52,0x45,0x61,0xa4,0xdc,0x91,0x0e,0xe4, +0xd1,0x7a,0x72,0x39,0x41,0x96,0xea,0xc6,0x9c,0x31,0x10,0x75,0xa8,0x22,0x21,0x10, +0x16,0xb5,0xb5,0x96,0x96,0x49,0x29,0x7a,0xee,0xf5,0x28,0x75,0x93,0xa1,0xb6,0x58, +0x17,0x49,0xe9,0x38,0x42,0x55,0x71,0xa0,0xce,0x71,0x11,0x04,0xd9,0x69,0x62,0x49, +0x9c,0x31,0x10,0x3f,0xa8,0x22,0x21,0x20,0x51,0x95,0xe2,0xa2,0x12,0xc1,0xc1,0x8a, +0x84,0x39,0x35,0x8a,0xec,0xd1,0x20,0x91,0xa3,0x92,0xa4,0x48,0x1f,0x5a,0xeb,0x18, +0x36,0x65,0x83,0xa0,0xc2,0x65,0x13,0x28,0x9c,0x31,0x10,0x27,0xa8,0x32,0x21,0x20, +0xe1,0x49,0x52,0x45,0x61,0xa4,0xda,0x95,0x10,0xe5,0xcd,0x7a,0x72,0x49,0x43,0x95, +0xe6,0xc6,0x1a,0xb5,0xb1,0x96,0x94,0x48,0x29,0x6a,0xea,0xf5,0x2a,0x85,0x93,0xa4, +0x9c,0x31,0x10,0xe3,0xa8,0x22,0x11,0x21,0xb4,0x59,0x19,0x39,0xe5,0x28,0x44,0x55, +0x71,0xa0,0xcc,0x71,0x13,0x05,0xd7,0x59,0x62,0x49,0x51,0x95,0xde,0xb2,0x16,0xc1, +0xbd,0x8a,0x84,0x49,0x37,0x7a,0xe6,0xe1,0x9c,0x31,0x10,0x5e,0xa8,0x42,0x33,0x21, +0x24,0x4b,0xa2,0xcb,0xa4,0x2b,0x25,0xab,0xea,0x85,0x37,0x3d,0x83,0xd3,0xbf,0x33, +0x17,0x93,0xde,0xa4,0x53,0x2b,0x61,0xcb,0xd7,0x4b,0x14,0x73,0xcb,0xbc,0x73,0x24, +0x9c,0x31,0x10,0xb4,0xa8,0x22,0x11,0x10,0x43,0x8a,0xe2,0xc2,0x1c,0xb5,0xaf,0x86, +0x94,0x49,0x2b,0x69,0xe8,0xf9,0x2e,0x85,0x91,0xa1,0xb2,0x68,0x1d,0x39,0xe1,0x28, +0x46,0x65,0x71,0xa0,0xca,0x86,0x17,0x04,0x9c,0x31,0x10,0x3f,0xa8,0x22,0x21,0x20, +0xd3,0x59,0x62,0x45,0x53,0x95,0xda,0xb2,0x18,0xd1,0xbd,0x76,0x82,0x49,0x39,0x7a, +0xe4,0xe2,0x24,0xa1,0xa1,0x96,0xa0,0x58,0x25,0x5a,0xe5,0x14,0x3a,0x75,0x81,0x90, +0x9c,0x31,0x10,0x27,0xa8,0x32,0x21,0x20,0xbc,0x75,0x1b,0x24,0xdb,0x49,0x54,0x55, +0x63,0x95,0xd2,0x95,0x18,0xe5,0xc7,0x6a,0x72,0x49,0x47,0x85,0xde,0xc6,0x20,0xb5, +0xaf,0x86,0x92,0x59,0x2f,0x6a,0xe4,0xf4,0x9c,0x31,0x10,0xe3,0xa8,0x22,0x11,0x21, +0x30,0x85,0x91,0x91,0xb0,0x69,0x1f,0x39,0xdf,0x28,0x46,0x65,0x71,0x90,0xc6,0x85, +0x19,0x05,0xcf,0x59,0x64,0x59,0x55,0x85,0xd8,0xb2,0x1c,0xd1,0xb9,0x76,0x82,0x48, +0x9c,0x31,0x10,0x70,0xa8,0x32,0x21,0x11,0x3b,0x76,0xe0,0xe5,0x28,0xa5,0x9f,0x85, +0xa0,0x55,0x27,0x49,0xe1,0x14,0x3c,0x75,0x81,0x95,0xba,0x74,0x1d,0x25,0xd5,0x38, +0x56,0x55,0x63,0x94,0xce,0x96,0x1a,0xe4,0x9c,0x31,0x10,0x47,0xa8,0x32,0x32,0x20, +0xc5,0x6a,0x72,0x59,0x47,0x8a,0xdc,0xc6,0x22,0xb5,0xab,0x76,0x90,0x59,0x31,0x69, +0xe0,0xf5,0x32,0x85,0x8f,0x95,0xae,0x64,0x23,0x35,0xdd,0x24,0x4a,0x5a,0x71,0x99, +0x9c,0x31,0x10,0x26,0xa8,0x22,0x22,0x30,0xc4,0x89,0x1d,0x04,0xcd,0x59,0x64,0x59, +0x55,0x85,0xd4,0xb2,0x20,0xd5,0xb7,0x76,0x82,0x59,0x3d,0x69,0xdc,0xe6,0x2a,0xa1, +0x9f,0x82,0x9e,0x68,0x2b,0x4a,0xdd,0x14,0x9c,0x31,0x10,0x2a,0xa8,0x22,0x12,0x20, +0x3e,0x75,0x81,0x90,0xb8,0x75,0x1f,0x18,0xd5,0x39,0x56,0x65,0x63,0x85,0xcc,0xa6, +0x1c,0xe5,0xc3,0x69,0x72,0x59,0x49,0x79,0xd8,0xc2,0x24,0xb5,0xab,0x76,0x90,0x59, +0x9c,0x31,0x10,0xf6,0xa8,0x22,0x22,0x21,0x33,0x5a,0xdc,0xf5,0x36,0x85,0x8f,0x84, +0xac,0x69,0x25,0x39,0xd7,0x28,0x4a,0x75,0x73,0x90,0xc2,0x85,0x1f,0x05,0xcb,0x49, +0x64,0x69,0x57,0x85,0xd0,0xb2,0x22,0xd1,0x9c,0x31,0x10,0x3a,0xa8,0x32,0x21,0x21, +0xb5,0x76,0x82,0x55,0x3f,0x66,0xd8,0xe5,0x2e,0xa6,0x9d,0x85,0x9e,0x65,0x2d,0x45, +0xdb,0x16,0x40,0x75,0x81,0x95,0xb6,0x74,0x23,0x25,0xd1,0x38,0x58,0x66,0x65,0x84, +0x9c,0x31,0x10,0xa9,0xa8,0x22,0x11,0x11,0xc8,0xa2,0x20,0xe5,0xbf,0x6a,0x72,0x59, +0x4b,0x7a,0xd4,0xc1,0x28,0xb5,0xa9,0x76,0x90,0x69,0x37,0x59,0xd8,0xf5,0x36,0x95, +0x8f,0x85,0xaa,0x74,0x29,0x39,0xd5,0x24,0x9c,0x31,0x10,0x6d,0xa8,0x32,0x21,0x10, +0x4c,0x75,0x71,0x84,0xc0,0x95,0x23,0x05,0xc9,0x49,0x66,0x65,0x59,0x85,0xce,0xb2, +0x24,0xd5,0xb3,0x76,0x80,0x56,0x41,0x65,0xd6,0xe6,0x30,0xa5,0x9b,0x76,0x9c,0x64, +0x9c,0x31,0x10,0x0f,0xa8,0x42,0x32,0x20,0x2f,0xa4,0xd7,0x8b,0x42,0x43,0x80,0xc2, +0xb5,0x43,0x28,0x8a,0xd0,0x95,0x5a,0x3d,0x65,0xc3,0xc8,0x53,0x24,0x73,0xbd,0xac, +0x74,0x2c,0x4c,0xbc,0xd3,0x63,0x2b,0x63,0x9c,0x31,0x10,0x68,0xa8,0x22,0x21,0x11, +0xa7,0x76,0x8e,0x69,0x39,0x5a,0xd6,0xf5,0x38,0x95,0x8f,0x80,0xa8,0x79,0x2b,0x39, +0xd1,0x29,0x4c,0x75,0x73,0x80,0xbc,0x95,0x25,0x05,0xc5,0x49,0x66,0x6a,0x59,0x75, +0x9c,0x31,0x10,0xbc,0xa8,0x22,0x22,0x11,0xcc,0xb2,0x28,0xd1,0xb3,0x6a,0x80,0x69, +0x43,0x6a,0xd4,0xe1,0x32,0xa1,0x9b,0x71,0x9a,0x79,0x33,0x49,0xd5,0x15,0x42,0x85, +0x81,0x80,0xb2,0x84,0x29,0x19,0xcb,0x38,0x9c,0x31,0x10,0xf6,0xa8,0x22,0x22,0x21, +0x58,0x7a,0x67,0x84,0xc4,0xa6,0x26,0xe4,0xbb,0x5a,0x74,0x69,0x4f,0x7a,0xce,0xc2, +0x2e,0xc6,0xa7,0x76,0x8e,0x69,0x3b,0x59,0xd2,0xf5,0x3a,0x95,0x8d,0x85,0xa6,0x74, +0x9c,0x31,0x10,0xb4,0xa8,0x22,0x11,0x10,0x2f,0x39,0xcf,0x28,0x4e,0x75,0x73,0x80, +0xba,0x96,0x29,0x04,0xc3,0x4a,0x66,0x65,0x5b,0x75,0xc8,0xb1,0x2a,0xd5,0xb1,0x66, +0x80,0x69,0x45,0x6a,0xd0,0xe6,0x34,0xb5,0x9c,0x31,0x10,0x78,0xa8,0x32,0x12,0x10, +0x99,0x76,0x9a,0x74,0x35,0x4a,0xd1,0x14,0x46,0x85,0x7f,0x80,0xb0,0x85,0x2b,0x15, +0xc7,0x39,0x5c,0x75,0x65,0x75,0xc2,0xb6,0x2a,0xe5,0xb7,0x55,0x74,0x69,0x4f,0x65, +0x9c,0x31,0x10,0xf6,0xa8,0x22,0x22,0x21,0xcc,0xd6,0x30,0xc5,0xa5,0x66,0x8c,0x78, +0x3d,0x5a,0xd0,0xf5,0x3e,0x96,0x8d,0x71,0xa4,0x89,0x31,0x29,0xcb,0x28,0x50,0x85, +0x75,0x74,0xb8,0x95,0x2b,0x05,0xc3,0x40,0x9c,0x31,0x10,0x12,0xa8,0x42,0x32,0x21, +0x6a,0x2d,0x5b,0xbc,0xc8,0x5b,0x2f,0x6b,0xad,0xb3,0x82,0x3b,0x46,0xab,0xce,0x72, +0x39,0x5b,0x97,0xb2,0x9a,0x3b,0x37,0x9b,0xcd,0x8b,0x48,0x43,0x80,0xbb,0xae,0x43, +0x9c,0x31,0x10,0x3a,0xa8,0x32,0x21,0x21,0x2f,0x15,0xc5,0x29,0x5c,0x76,0x67,0x74, +0xbe,0xb6,0x2c,0xe5,0xb7,0x5a,0x74,0x79,0x53,0x6a,0xc8,0xd5,0x32,0xc5,0xa5,0x65, +0x8a,0x79,0x41,0x55,0xcc,0xf5,0x3e,0xa5,0x9c,0x31,0x10,0x98,0xa8,0x65,0x44,0x43, +0x8d,0x6d,0xa2,0x8d,0x35,0x2d,0xc9,0x0d,0x52,0x8d,0x7b,0x6d,0xbc,0x29,0x6f,0x82, +0x86,0xcd,0x81,0x0d,0x82,0xed,0x82,0xed,0x80,0xed,0x82,0xed,0x82,0xed,0x80,0xed, +0x9c,0x31,0x10,0x67,0x97,0x65,0x55,0x43,0x85,0xb5,0x85,0xb5,0x81,0xb5,0x81,0xb5, +0x81,0xb5,0x89,0xb5,0x91,0x3a,0xd2,0x1a,0xd1,0xb1,0xc5,0xb5,0xc1,0xb5,0xbd,0xb5, +0x8c,0x91,0x6e,0x32,0x81,0xb5,0x7d,0xb5,0x9c,0x31,0x10,0xf5,0x42,0x10,0x11,0x12, +0xb2,0x66,0x5b,0x55,0x9c,0x55,0xa1,0x65,0x75,0x55,0xbc,0x55,0x88,0x95,0xac,0x59, +0xa2,0x55,0xa4,0x55,0x72,0x55,0x94,0x95,0x40,0x51,0x85,0x55,0x91,0x65,0x4c,0x55, +0x9c,0x31,0x10,0x57,0x42,0x01,0x00,0x02,0x76,0x22,0x5d,0xdd,0x61,0xe2,0x85,0x9a, +0x7e,0x5d,0x65,0xe9,0x82,0x93,0x4c,0xdc,0x3b,0x5a,0x69,0x23,0x2a,0xdc,0x79,0x92, +0x41,0xa3,0x1e,0x5c,0x46,0x62,0x15,0xe3,0x9c,0x31,0x10,0x67,0x43,0x10,0x00,0x00, +0x33,0x25,0x42,0xf6,0x28,0xd6,0x5c,0xf7,0x3c,0xe7,0x3b,0x08,0x6e,0xc7,0x36,0xe5, +0x71,0x0a,0x7c,0xe7,0x58,0x7e,0x5f,0x1e,0x4c,0xd9,0x5f,0x08,0x60,0xea,0x47,0x16, +0x9c,0x31,0x10,0x58,0x41,0x00,0x00,0x00,0x53,0xad,0x38,0xc9,0x77,0x31,0x35,0x08, +0x6a,0x6f,0x3b,0x83,0x4a,0xfa,0x6a,0xce,0x30,0x29,0x7d,0x28,0x3f,0x14,0x43,0x73, +0x8e,0x89,0x5b,0x0d,0x74,0x18,0x97,0x93,0x9c,0x31,0x10,0x3e,0x30,0x00,0x00,0x00, +0x51,0x55,0x91,0xa5,0xd3,0x85,0x43,0x91,0xb2,0xe5,0x78,0xc9,0x60,0x51,0xa1,0x01, +0x4b,0x05,0xa2,0x55,0x5a,0x05,0x7e,0x95,0x88,0x05,0x81,0x59,0x7d,0x49,0x69,0xe5, +0x9c,0x31,0x10,0x1b,0x20,0x00,0x00,0x00,0x99,0xd9,0x61,0xd5,0x8f,0xd4,0x90,0x95, +0x34,0x55,0x91,0xd5,0x58,0x85,0x66,0xd5,0x8b,0x55,0x49,0x15,0x8a,0x55,0x7b,0x15, +0x66,0x55,0x89,0x55,0x6f,0xd5,0x7e,0x95,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x95,0x55,0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x65,0x55,0x55,0x59,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x59,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x54,0x55,0x55,0x55,0x55,0x55,0x50,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x59,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x55,0x55,0x55,0x15,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x95,0x55,0x95,0x55,0x95,0x55,0x95,0x55, +0x95,0x55,0x95,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x55,0x15,0x55,0x55,0x55,0x15,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x55,0x55,0x55,0x15,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x15,0x55,0x55,0x55,0x15,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x15,0x55,0x15,0x55,0x15,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x55,0x55,0x55, +0x9c,0x31,0x10,0xc5,0x40,0x00,0x00,0x00,0x7a,0x15,0x74,0xe5,0x6b,0xd5,0x68,0x15, +0x5b,0x95,0x51,0x15,0x43,0x45,0x3e,0x26,0x3d,0x55,0x42,0xe5,0x37,0x16,0x3d,0xd5, +0x35,0xd5,0x39,0x55,0x36,0x12,0x36,0x15,0x9c,0x31,0x10,0x0c,0x41,0x10,0x01,0x00, +0x33,0x1b,0x32,0xdb,0x2d,0x54,0x2e,0xe3,0x30,0xdb,0x31,0x1b,0x2c,0xdc,0x2a,0xd3, +0x37,0x1c,0x4c,0x4b,0x90,0x5d,0x7f,0x1b,0x7e,0xd3,0x7c,0xdb,0x7e,0xdb,0x7e,0xdc, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x56,0x55,0x55,0x55,0x55,0x95,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x45,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x55,0x95,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_SEVEN.txt b/config/_default_cfg_src_/res/en/SOUND_SEVEN.txt new file mode 100644 index 0000000..6fc00f9 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_SEVEN.txt @@ -0,0 +1,185 @@ +0x9c,0x31,0x10,0x55,0x43,0x44,0x01,0x00,0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77, +0x62,0x77,0x93,0x53,0xc1,0x78,0x9a,0x59,0xb1,0x48,0xa3,0x96,0x92,0x97,0xbd,0x66, +0xd5,0x69,0xbd,0xb6,0x9e,0x85,0xcb,0xb6,0x9c,0x31,0x10,0xb6,0x53,0x43,0x00,0x00, +0x9b,0x43,0xa9,0x2c,0xa4,0xa2,0xa5,0xa3,0xa5,0x5e,0xc1,0x4b,0xa2,0x62,0xa6,0x53, +0xb9,0xda,0xa9,0x8c,0xc6,0x03,0xc4,0x1d,0x8d,0x09,0xad,0xc1,0xbe,0xf4,0xb4,0xd9, +0x9c,0x31,0x10,0xd0,0x54,0x54,0x00,0x00,0xb2,0xd3,0xac,0xbc,0xb5,0x2b,0xa2,0x3b, +0xbe,0xa9,0xc5,0x33,0xa1,0xb6,0xa1,0x34,0xb3,0x1b,0x9c,0x59,0xa2,0x4b,0x74,0x4c, +0x93,0xcb,0x95,0x39,0x93,0x43,0xa1,0xa3,0x9c,0x31,0x10,0xeb,0x54,0x55,0x10,0x00, +0x91,0xa4,0x9e,0xbb,0xa2,0xe3,0xaa,0xf3,0xb9,0x43,0xc1,0xd2,0x7f,0x49,0xae,0xb4, +0x85,0x35,0x7d,0xc1,0x98,0xa4,0x8b,0xc5,0x6b,0xb2,0x79,0xcb,0x7d,0x22,0x5e,0xd3, +0x9c,0x31,0x10,0xea,0x55,0x65,0x00,0x00,0x6a,0x45,0x83,0x34,0x7b,0xba,0x6e,0x2b, +0x74,0x3a,0x4a,0x5d,0x65,0xb1,0x62,0xab,0x4a,0x54,0x74,0xac,0x7c,0x3b,0x50,0x91, +0x2a,0x3c,0x6b,0xc1,0x4b,0xc5,0x59,0x53,0x9c,0x31,0x10,0x31,0x65,0x65,0x10,0x00, +0x61,0x3b,0x69,0xb2,0x5c,0xb3,0x81,0xa5,0x6d,0x23,0x75,0xc1,0x61,0x4c,0x67,0x38, +0x75,0xb5,0x68,0xd3,0x75,0x1a,0x79,0xab,0x7a,0x4b,0x4e,0xbd,0x3e,0xc9,0x56,0x11, +0x9c,0x31,0x10,0x7c,0x65,0x66,0x20,0x00,0x82,0x88,0x58,0x97,0x8a,0x9b,0x65,0x65, +0x7e,0x46,0x6e,0x67,0x71,0x57,0x83,0xb7,0x70,0x7a,0x7b,0x94,0x7c,0x78,0x3a,0xab, +0x6b,0xb4,0x66,0x33,0x86,0x86,0x91,0x99,0x9c,0x31,0x10,0x52,0x66,0x75,0x20,0x00, +0x6a,0x2e,0x8c,0x21,0x7a,0x3a,0x84,0xad,0xbe,0x3d,0x9b,0xcd,0x49,0xc8,0x79,0x38, +0x74,0xa3,0xbd,0xa2,0x84,0xb4,0x66,0x1d,0xa4,0xd5,0x64,0x48,0x7d,0x50,0xc4,0xb1, +0x9c,0x31,0x10,0x88,0x66,0x67,0x10,0x00,0x2c,0x65,0x52,0xa3,0xc4,0x8b,0xb5,0x8a, +0x7d,0x5c,0x73,0x43,0x81,0x43,0x91,0xa3,0x73,0xc3,0x44,0x4c,0x55,0x4a,0x70,0xc2, +0x73,0x4c,0x86,0x64,0x63,0x8a,0x9d,0x8a,0x9c,0x31,0x10,0xc0,0x88,0x76,0x20,0x00, +0x71,0xdd,0x75,0xce,0x71,0x0a,0x86,0x29,0x69,0xea,0xaa,0x26,0xca,0x14,0x88,0x9a, +0x3a,0xe8,0x41,0xd4,0x3d,0x95,0x3e,0x0d,0x11,0x98,0x1a,0x10,0x3e,0x24,0x3d,0xe6, +0x9c,0x31,0x10,0xad,0x86,0x87,0x40,0x00,0x4d,0xbc,0x48,0x31,0x6a,0x3b,0x85,0x44, +0xb3,0x43,0xae,0x4c,0xa5,0xca,0xae,0x8a,0xb9,0x9a,0x8d,0xac,0xb1,0xbc,0xc8,0x52, +0xc5,0xdc,0x95,0x4d,0xc5,0xb2,0xc1,0xa8,0x9c,0x31,0x10,0x12,0xc6,0x87,0x30,0x00, +0x81,0x14,0x84,0x5a,0x87,0x1e,0x82,0x1d,0x7e,0xe4,0x7b,0x29,0x78,0xe1,0x81,0x51, +0x90,0x8d,0x98,0xd5,0x8c,0xe5,0x66,0xe9,0x4c,0xa5,0x6d,0x1d,0xc7,0x59,0xd8,0x95, +0x9c,0x31,0x10,0x51,0xc9,0x87,0x40,0x00,0x90,0xed,0x3b,0x2c,0x2a,0xa5,0x79,0x22, +0xca,0xc9,0xc2,0xf0,0xa6,0xd4,0x74,0xd2,0x37,0x32,0x1f,0x32,0x8f,0x0d,0xca,0xe4, +0xad,0x04,0x8c,0xe9,0x64,0xee,0x1a,0x6e,0x9c,0x31,0x10,0x7a,0xc9,0x87,0x30,0x00, +0x2d,0x24,0xb2,0xe8,0xc0,0xed,0x96,0xf2,0x8c,0xd2,0x5b,0x29,0x04,0x20,0x52,0xee, +0xd0,0xb5,0xaa,0xf5,0x91,0x10,0x92,0xcd,0x49,0x4e,0x00,0xb2,0x89,0x14,0xd2,0xac, +0x9c,0x31,0x10,0x7a,0xc9,0x87,0x30,0x00,0x92,0xed,0x9f,0x09,0x96,0xcd,0x29,0x31, +0x0d,0x56,0xb9,0x15,0xbc,0xcc,0x87,0x09,0xb6,0xea,0x85,0x0d,0x0a,0xd0,0x37,0x91, +0xd4,0xea,0x9b,0x05,0x91,0x04,0xc4,0xaa,0x9c,0x31,0x10,0xd6,0xda,0x97,0x40,0x00, +0x75,0x0e,0x3e,0x8d,0x71,0x48,0xa6,0xc9,0x7f,0x09,0x94,0xec,0xa0,0xcd,0x65,0x0e, +0x40,0x8a,0x81,0x25,0x9e,0xa8,0x7d,0x0c,0x9e,0xed,0x96,0xd0,0x5d,0x0e,0x48,0x66, +0x9c,0x31,0x10,0x63,0xc9,0x88,0x50,0x00,0x97,0x13,0xaa,0x63,0x83,0x2a,0xc6,0xac, +0x9a,0xe3,0x37,0x12,0x20,0x12,0xa2,0xe4,0x9a,0x6c,0x8b,0x24,0xc8,0x9d,0x90,0xe1, +0x31,0x19,0x2a,0xa3,0xaa,0xf4,0x90,0x6c,0x9c,0x31,0x10,0x49,0xc9,0x97,0x40,0x00, +0x97,0x52,0xc4,0xd1,0x83,0x31,0x29,0x2c,0x35,0x34,0xb6,0xf6,0x88,0xb1,0xa1,0x52, +0xc0,0xee,0x77,0x4d,0x23,0x0d,0x45,0xb0,0xb8,0xcd,0x82,0xee,0xa9,0x2e,0xb9,0x0e, +0x9c,0x31,0x10,0x51,0xc9,0x87,0x40,0x00,0x6f,0x4d,0x22,0xec,0x51,0xb5,0xb4,0xb1, +0x82,0xf1,0xad,0x11,0xb2,0xf1,0x6d,0x4d,0x22,0xed,0x57,0xcd,0xb4,0xc5,0x81,0x29, +0xaf,0x04,0xaf,0x09,0x69,0x45,0x22,0xee,0x9c,0x31,0x10,0xc7,0xca,0x76,0x30,0x00, +0x59,0x64,0xb0,0xe1,0x81,0x11,0xb1,0x01,0xac,0xf1,0x69,0x11,0x24,0xe5,0x5f,0x75, +0xae,0xe4,0x7f,0x21,0xb2,0xf2,0xa8,0xf4,0x67,0x20,0x22,0xd1,0x63,0x71,0xae,0xe1, +0x9c,0x31,0x10,0x74,0xca,0x87,0x20,0x00,0x83,0x26,0xb4,0xe5,0xa7,0x08,0x65,0x21, +0x22,0xca,0x65,0x60,0xaa,0xe4,0x83,0x26,0xb0,0xe6,0xa5,0x05,0x67,0x21,0x26,0xc9, +0x63,0x65,0xac,0xe5,0x83,0x29,0xae,0xe9,0x9c,0x31,0x10,0x74,0xca,0x87,0x20,0x00, +0xa7,0x09,0x6b,0x05,0x24,0xea,0x5f,0x69,0xae,0xe8,0x83,0x29,0xab,0x09,0xab,0x0d, +0x6f,0x2d,0x26,0xee,0x55,0x6c,0xaf,0x0d,0x85,0x2d,0xa5,0x0c,0xad,0x11,0x79,0x2e, +0x9c,0x31,0x10,0xce,0xc9,0x87,0x20,0x00,0x2d,0x31,0x49,0xb0,0xae,0xf5,0x8d,0x12, +0x9b,0x15,0xac,0xf1,0x83,0x15,0x3d,0x15,0x38,0xf5,0xa0,0x95,0x94,0x70,0x92,0xd1, +0xa8,0x8d,0x92,0xb1,0x54,0xad,0x32,0x49,0x9c,0x31,0x10,0xe6,0xb8,0x86,0x10,0x00, +0x88,0x99,0xb8,0x95,0xa2,0x54,0xb9,0x15,0xae,0x0e,0x66,0x15,0x05,0x54,0x43,0x96, +0x96,0x59,0xa6,0xdc,0xae,0x1d,0xa6,0x62,0x8d,0xe1,0x52,0x5d,0x31,0xe1,0x59,0x1d, +0x9c,0x31,0x10,0x2b,0xa7,0x55,0x00,0x00,0x8e,0xb0,0xce,0xcd,0xcc,0xcd,0xbc,0xe2, +0x92,0xc9,0x4d,0x0d,0x17,0x88,0x2e,0xce,0x7c,0xd0,0xb8,0xd5,0xc2,0xea,0xc2,0xd0, +0xa4,0xcd,0x62,0xed,0x27,0x31,0x2c,0xce,0x9c,0x31,0x10,0xd3,0xa5,0x34,0x00,0x00, +0x67,0x2b,0xa4,0x4a,0xc7,0xb5,0xd4,0x89,0xb4,0x52,0x71,0x4c,0x2f,0x8b,0x27,0x72, +0x53,0x4d,0x91,0x43,0xc7,0x83,0xdd,0x49,0xc2,0x43,0x7c,0x4c,0x38,0x8b,0x23,0x83, +0x9c,0x31,0x10,0xc4,0xa4,0x33,0x00,0x00,0x3e,0xa5,0x81,0x85,0xc2,0x81,0xe0,0x99, +0xc7,0x99,0x89,0xe5,0x42,0xd6,0x18,0x95,0x2c,0x85,0x6e,0x85,0xb9,0xd5,0xdd,0x55, +0xd5,0x66,0x9d,0x65,0x4b,0x95,0x18,0xc5,0x9c,0x31,0x10,0x30,0xa3,0x33,0x00,0x00, +0x1f,0x4a,0x5b,0x91,0xa6,0x4d,0xdd,0x0d,0xe7,0xa9,0xb1,0x69,0x5f,0xa5,0x20,0x25, +0x17,0xcd,0x40,0x4d,0x8c,0x71,0xd6,0x8d,0xeb,0x8d,0xc8,0xad,0x7d,0x01,0x33,0xb2, +0x9c,0x31,0x10,0xbf,0xa3,0x32,0x00,0x00,0x0e,0x75,0x25,0x8d,0x6d,0xad,0xbc,0x2d, +0xe7,0x69,0xe2,0x6c,0xa9,0xc9,0x52,0x8d,0x12,0x2d,0x10,0x89,0x42,0x29,0x90,0xa9, +0xda,0x32,0xf8,0xad,0xd7,0x48,0x85,0xa9,0x9c,0x31,0x10,0x76,0xb4,0x22,0x00,0x00, +0x58,0x81,0x42,0x65,0x49,0x45,0x6c,0x65,0x9b,0xa5,0xb9,0x91,0xba,0x84,0xa2,0x46, +0x77,0x85,0x4b,0x99,0x3a,0xb0,0x4d,0x79,0x79,0x46,0xa4,0x74,0xbd,0x79,0xbc,0x75, +0x9c,0x31,0x10,0xe1,0xb4,0x33,0x00,0x00,0xa0,0x65,0x72,0x86,0x48,0x95,0x38,0x95, +0x4b,0x95,0x7b,0x65,0xa7,0x45,0xbf,0x85,0xbd,0x65,0xa4,0x95,0x79,0x85,0x49,0x56, +0x33,0xb5,0x43,0x75,0x75,0xb5,0xa2,0x49,0x9c,0x31,0x10,0x34,0xb5,0x43,0x00,0x00, +0xbc,0x6e,0xc2,0x6d,0xaf,0x91,0x86,0x6d,0x55,0x4d,0x32,0x8d,0x34,0x2e,0x60,0x6c, +0x9a,0x6e,0xb8,0xc5,0xc3,0x8d,0xb9,0x4d,0x9a,0x6d,0x6b,0x8d,0x3b,0x68,0x28,0x52, +0x9c,0x31,0x10,0x1c,0xb6,0x54,0x00,0x00,0x43,0x2d,0x82,0xed,0xb0,0x65,0xbf,0x2d, +0xc0,0xcc,0xab,0x0e,0x86,0xed,0x56,0xed,0x2d,0x2e,0x26,0x2c,0x58,0xe9,0x9f,0x89, +0xbc,0x4d,0xc0,0xf5,0xbc,0xcd,0xa2,0xed,0x9c,0x31,0x10,0x26,0xb7,0x65,0x00,0x00, +0x78,0xed,0x42,0xcd,0x1f,0x2d,0x28,0xae,0x72,0xad,0xbd,0x4d,0xc4,0xd6,0xc0,0xed, +0xb7,0x0d,0x99,0x0d,0x67,0x0d,0x2a,0xf1,0x05,0x90,0x2e,0xae,0xa6,0x6c,0xf4,0x4d, +0x9c,0x31,0x10,0x4c,0xc8,0x66,0x20,0x00,0xa0,0xe5,0x94,0xe9,0x9f,0x00,0x8d,0x25, +0x65,0x4e,0x35,0x34,0x2d,0xb9,0x76,0xd6,0xba,0xd4,0xa8,0x35,0x82,0x8d,0x9c,0x89, +0xba,0xea,0x88,0xe8,0x3b,0x49,0x0e,0xda,0x9c,0x31,0x10,0xfc,0xc9,0x88,0x30,0x00, +0x39,0xa1,0xaf,0x24,0xb7,0x24,0x84,0xa2,0x8e,0xa3,0xc8,0x9c,0xbc,0x5c,0x62,0x9a, +0x2e,0xd3,0x10,0x5d,0x57,0x8b,0xbd,0x11,0xa3,0x9d,0x7d,0x1c,0xa9,0x19,0xd5,0x23, +0x9c,0x31,0x10,0x48,0xc9,0x88,0x20,0x00,0xa4,0xdc,0x5c,0xdb,0x33,0x1a,0x0a,0x14, +0x69,0x45,0xcd,0x08,0x93,0x53,0x77,0x55,0xb9,0x12,0xd1,0x5a,0x93,0x1c,0x56,0xdc, +0x33,0x1b,0x06,0x02,0x7b,0x05,0xcc,0xcb,0x9c,0x31,0x10,0x75,0xd9,0x98,0x20,0x00, +0x81,0x11,0x7d,0x13,0xa0,0xd4,0x9e,0xd2,0x87,0x13,0x75,0x14,0x5d,0x53,0x3e,0x53, +0x77,0x8c,0xa9,0x12,0x7d,0x52,0x7b,0x54,0xa5,0x13,0x9b,0x13,0x87,0x0a,0x7d,0x13, +0x9c,0x31,0x10,0x49,0xda,0x97,0x20,0x00,0x61,0x29,0x3c,0xce,0x71,0x88,0xa9,0x08, +0x7b,0x4a,0x7b,0x29,0xa5,0x28,0x99,0x0d,0x85,0x2d,0x87,0x0c,0x69,0x0d,0x3f,0x0d, +0x61,0x75,0xa6,0xf2,0x7f,0x10,0x74,0xf0,0x9c,0x31,0x10,0x48,0xc9,0x88,0x20,0x00, +0xc2,0xec,0xb2,0xeb,0x8f,0x2a,0xa0,0xb3,0x64,0xac,0x10,0xe3,0x20,0x11,0xb2,0x63, +0x98,0x26,0x66,0x9a,0xac,0x9a,0xba,0x9c,0x90,0x64,0xa8,0xd9,0x88,0xdb,0x31,0x1c, +0x9c,0x31,0x10,0x46,0xca,0x88,0x30,0x00,0x11,0xab,0x62,0xf1,0xb6,0x25,0x76,0x63, +0x8a,0x29,0xb6,0x2c,0xa2,0x23,0x9e,0x6c,0xa1,0xf1,0x59,0xe3,0x26,0x24,0x21,0x49, +0x92,0x0d,0x9d,0x8c,0x72,0x0a,0x9d,0xcb,0x9c,0x31,0x10,0xce,0xc9,0x87,0x20,0x00, +0xb2,0xe6,0x9a,0xc9,0xa5,0x44,0x92,0xe5,0x49,0x0a,0x1f,0x05,0x36,0xa9,0xa8,0x70, +0x90,0x71,0x7a,0x91,0xaa,0x8d,0xac,0xb1,0x98,0x51,0xaa,0x8d,0x7e,0x90,0x3c,0xd1, +0x9c,0x31,0x10,0x17,0xc9,0x97,0x10,0x00,0x20,0xcd,0x4b,0x36,0xaa,0x95,0x8a,0xb4, +0x84,0xb5,0xac,0xb1,0xa4,0xf5,0x98,0xb0,0xaa,0xd2,0x76,0xd1,0x3f,0x30,0x23,0x11, +0x4b,0xba,0xae,0xd5,0x87,0x14,0x84,0xf6,0x9c,0x31,0x10,0x17,0xc9,0x97,0x10,0x00, +0xac,0xf5,0xa5,0x10,0x96,0xb1,0xaa,0xd2,0x78,0xcc,0x3f,0x31,0x23,0x11,0x4f,0x75, +0xa8,0xb5,0x86,0xf0,0x82,0xd1,0xa8,0xd1,0xa4,0xf1,0x96,0xb1,0xab,0x0d,0x85,0x0d, +0x9c,0x31,0x10,0x0f,0xc9,0x87,0x10,0x00,0x49,0x2d,0x2d,0x0d,0x3a,0xd2,0x9c,0x94, +0x90,0x96,0x7c,0xb1,0x9e,0xd4,0xa6,0xd5,0x96,0xd5,0xa7,0x55,0x92,0xf5,0x5a,0xf1, +0x38,0xed,0x2a,0x45,0x7d,0x02,0x96,0xc4,0x9c,0x31,0x10,0x0f,0xc9,0x87,0x10,0x00, +0x85,0x05,0x9a,0xe6,0x9e,0xc5,0x9c,0xe9,0xa7,0x0d,0x92,0x91,0x6a,0xd1,0x52,0xd1, +0x24,0xb5,0x57,0xb0,0x9a,0xee,0x81,0x51,0x95,0x31,0xa5,0x0d,0x9f,0x2d,0xa4,0xc9, +0x9c,0x31,0x10,0xa9,0xc8,0x86,0x00,0x00,0x9b,0x05,0x79,0x45,0x63,0x6a,0x3b,0x25, +0x30,0xa9,0x8c,0x70,0x8a,0x4e,0x84,0xad,0xa2,0x8c,0xa2,0x8e,0xa0,0xd1,0x9f,0x10, +0x84,0x92,0x6c,0x92,0x50,0xf0,0x26,0x32,0x9c,0x31,0x10,0x34,0xc9,0x86,0x00,0x00, +0x5f,0x84,0x96,0xe8,0x83,0x4a,0x9b,0x28,0xa7,0x09,0xa3,0x0a,0x9e,0xc5,0x8e,0xc4, +0x78,0xea,0x67,0x09,0x3a,0xe8,0x32,0xaa,0x82,0x90,0x8e,0x8d,0x8c,0xad,0xa2,0xac, +0x9c,0x31,0x10,0xbc,0xc9,0x76,0x00,0x00,0xa2,0xd1,0xa2,0xf5,0x9a,0xf0,0x82,0xb5, +0x74,0xb6,0x5c,0xd4,0x2c,0xd9,0x49,0x78,0x8c,0xf6,0x8d,0x35,0x97,0x15,0xa2,0xf1, +0xa3,0x11,0xa4,0xf1,0x8f,0x09,0x79,0x29,0x9c,0x31,0x10,0xc5,0xc7,0x75,0x00,0x00, +0x73,0xa8,0x4b,0xa9,0x2c,0x25,0x60,0xc2,0x8c,0x60,0x92,0xc1,0x9e,0x81,0xa4,0x85, +0xa7,0x85,0x9d,0x69,0x85,0x48,0x7b,0x89,0x6e,0x69,0x44,0x89,0x35,0x29,0x6c,0x0d, +0x9c,0x31,0x10,0x3e,0xb7,0x75,0x00,0x00,0x9a,0x0e,0xb0,0x8c,0xc2,0x6d,0xc8,0xad, +0xca,0xcd,0xaf,0x11,0x82,0xd1,0x6c,0xf1,0x46,0xf1,0x09,0x31,0x05,0x55,0x5a,0xb5, +0x9a,0xb5,0xba,0xb5,0xc2,0x91,0xc8,0xd1,0x9c,0x31,0x10,0xbe,0xb6,0x63,0x00,0x00, +0xc5,0x2b,0xa7,0x7b,0x83,0x89,0x67,0x68,0x46,0x89,0x1d,0x9a,0x11,0xdb,0x45,0x8b, +0x8b,0x8b,0xbb,0x7a,0xc8,0x5a,0xcc,0x6a,0xc4,0x48,0xad,0x57,0x8f,0x76,0x71,0x66, +0x9c,0x31,0x10,0x34,0xb5,0x43,0x00,0x00,0x48,0x6d,0x1d,0x92,0x0c,0xd5,0x31,0x91, +0x7b,0x91,0xbd,0x91,0xdb,0x75,0xe3,0x95,0xd0,0x51,0xae,0x75,0x8b,0x4d,0x60,0x6d, +0x34,0x4d,0x10,0x74,0x09,0x75,0x3a,0x8a,0x9c,0x31,0x10,0xa9,0xb4,0x43,0x00,0x00, +0x8e,0xc8,0xce,0xae,0xe4,0xb1,0xe2,0xd5,0xc7,0x4d,0xa4,0xb2,0x7f,0x54,0x59,0x56, +0x33,0x6d,0x14,0x75,0x0e,0x6d,0x42,0xa6,0x93,0xa0,0xce,0xa9,0xe2,0x8d,0xde,0x89, +0x9c,0x31,0x10,0x23,0xb4,0x44,0x00,0x00,0xc0,0xcb,0x9f,0x24,0x7e,0xe3,0x5a,0xe2, +0x36,0x94,0x17,0x23,0x0f,0x1a,0x41,0x0d,0x91,0x4a,0xcb,0x53,0xe1,0x13,0xdf,0x53, +0xc5,0x12,0xa3,0x2c,0x7e,0xa4,0x59,0x1a,0x9c,0x31,0x10,0xa9,0xb4,0x43,0x00,0x00, +0x34,0x49,0x17,0x8d,0x0f,0xac,0x41,0xa6,0x90,0x81,0xca,0xc8,0xe0,0x6a,0xdd,0xad, +0xc4,0x89,0xa2,0xb1,0x7f,0x4d,0x5a,0x8c,0x36,0x69,0x19,0xb1,0x0f,0xb5,0x3c,0xc9, +0x9c,0x31,0x10,0x34,0xb5,0x43,0x00,0x00,0x8a,0x64,0xc9,0x85,0xe1,0x69,0xe0,0xa9, +0xc8,0x69,0xa8,0x90,0x84,0x6d,0x5c,0x89,0x38,0x69,0x1d,0xad,0x10,0x75,0x36,0x95, +0x81,0x8d,0xc2,0x8a,0xdf,0x68,0xe1,0xb1,0x9c,0x31,0x10,0x23,0xb4,0x44,0x00,0x00, +0xca,0xd3,0xab,0x5a,0x84,0xdc,0x5f,0x13,0x38,0xd3,0x1f,0x9b,0x0e,0x63,0x2f,0x2a, +0x78,0xa5,0xbf,0x62,0xde,0x9a,0xe3,0x9d,0xce,0x9a,0xaf,0x22,0x8a,0xa5,0x63,0x1a, +0x9c,0x31,0x10,0x7c,0xb5,0x33,0x00,0x00,0x3c,0x64,0x20,0x96,0x10,0x40,0x2c,0x99, +0x74,0x5a,0xb9,0x98,0xdc,0x69,0xe1,0x9a,0xd0,0x58,0xb2,0x85,0x8f,0x65,0x67,0x99, +0x41,0x75,0x26,0x81,0x14,0x30,0x27,0x96,0x9c,0x31,0x10,0xa9,0xb4,0x43,0x00,0x00, +0x68,0x11,0xad,0x94,0xd5,0x32,0xdf,0xb1,0xd3,0x30,0xb6,0xb1,0x93,0x71,0x6c,0x91, +0x46,0x6d,0x2a,0x89,0x17,0x05,0x24,0xa1,0x61,0x28,0xa7,0x6d,0xd3,0x32,0xe0,0x91, +0x9c,0x31,0x10,0xa9,0xb4,0x43,0x00,0x00,0xd6,0x0d,0xb9,0x8d,0x96,0x71,0x6e,0x91, +0x48,0x52,0x2b,0x71,0x18,0x4d,0x20,0xa5,0x57,0x45,0x9d,0x65,0xcd,0x49,0xdc,0x6d, +0xd6,0x4e,0xbe,0x8d,0x9c,0x6d,0x75,0x8d,0x9c,0x31,0x10,0xd2,0xb3,0x42,0x00,0x00, +0x4e,0x2e,0x31,0x90,0x1e,0x52,0x21,0xcc,0x51,0x66,0x95,0x44,0xc8,0x48,0xda,0x6a, +0xd7,0x4e,0xc1,0x70,0xa2,0x8e,0x7b,0x4e,0x53,0x6c,0x35,0x91,0x21,0x75,0x20,0xd6, +0x9c,0x31,0x10,0x5d,0xb3,0x43,0x00,0x00,0x4c,0x89,0x8f,0x65,0xc6,0x49,0xdb,0xa9, +0xd8,0x89,0xc0,0x6c,0xa0,0xad,0x7a,0x4d,0x54,0x31,0x35,0xb1,0x22,0xb1,0x22,0x76, +0x4b,0xb0,0x8c,0x69,0xc2,0x86,0xd7,0x6d,0x9c,0x31,0x10,0x9a,0xb3,0x32,0x00,0x00, +0xd5,0x88,0xc0,0x25,0xa1,0x44,0x7b,0x49,0x55,0x6e,0x37,0x90,0x26,0xd1,0x27,0x36, +0x4e,0x78,0x8c,0x30,0xbe,0x6a,0xd3,0x69,0xd2,0xa8,0xbe,0x61,0x9e,0x89,0x7a,0x8d, +0x9c,0x31,0x10,0x9a,0xb3,0x32,0x00,0x00,0x55,0x4e,0x38,0x8c,0x29,0x94,0x2d,0x36, +0x54,0x71,0x8f,0x48,0xbf,0xa1,0xd2,0x65,0xd0,0xa8,0xba,0x6e,0x99,0x4d,0x74,0x30, +0x50,0x4a,0x35,0xae,0x2a,0x95,0x36,0xac,0x9c,0x31,0x10,0x88,0xb2,0x33,0x00,0x00, +0x63,0x62,0x9c,0x05,0xc5,0x2c,0xd1,0x91,0xc8,0x92,0xad,0x90,0x8a,0x8c,0x65,0xaa, +0x47,0x09,0x35,0x8c,0x34,0x2d,0x4b,0xaa,0x7a,0x30,0xaa,0xb1,0xc7,0x52,0xcb,0x89, +0x9c,0x31,0x10,0x15,0xb3,0x33,0x00,0x00,0xbc,0x81,0x9d,0x4d,0x79,0x75,0x57,0x6d, +0x3d,0x6d,0x33,0x69,0x40,0x89,0x65,0x71,0x95,0x6d,0xbb,0xc4,0xca,0x49,0xc2,0x56, +0xa7,0x51,0x81,0x51,0x5c,0x29,0x40,0xa5,0x9c,0x31,0x10,0xe1,0xb4,0x33,0x00,0x00, +0x36,0x71,0x42,0x65,0x63,0x92,0x8e,0x84,0xb4,0x65,0xc6,0x69,0xc1,0x59,0xa9,0x35, +0x84,0x95,0x5e,0x95,0x42,0x95,0x3a,0x95,0x47,0x85,0x67,0x55,0x8f,0x61,0xb2,0x71, +0x9c,0x31,0x10,0x0d,0xb3,0x23,0x00,0x00,0xc3,0x41,0xbd,0x95,0xa4,0x95,0x7d,0x75, +0x58,0x99,0x40,0x55,0x3f,0x51,0x53,0x4d,0x74,0xad,0x99,0x69,0xb8,0xb1,0xc4,0xad, +0xb3,0x65,0x8b,0x69,0x60,0x49,0x42,0x4e,0x9c,0x31,0x10,0xa6,0xb5,0x54,0x00,0x00, +0x38,0x49,0x49,0x23,0x72,0xe3,0xa0,0xe3,0xc0,0xdb,0xc4,0xdb,0xaa,0xd2,0x7e,0xd4, +0x58,0xd3,0x44,0x9b,0x48,0xe3,0x60,0xdb,0x7e,0xdb,0x96,0xdb,0xa4,0xdb,0xa4,0xdb, +0x9c,0x31,0x10,0xd0,0x93,0x32,0x00,0x00,0xe2,0xcc,0x8e,0x82,0x3d,0x13,0x0c,0x1d, +0x0b,0x23,0x30,0xa2,0x65,0x13,0x9b,0x1b,0xc5,0x71,0xdc,0xe4,0xd0,0xd4,0xa0,0x8b, +0x64,0x89,0x3c,0xea,0x38,0xac,0x50,0xec,0x9c,0x31,0x10,0x7a,0x83,0x33,0x00,0x00, +0x65,0x23,0xa9,0x13,0xda,0x8b,0xe1,0x24,0xb2,0x9c,0x73,0x21,0x3f,0x1b,0x36,0xd4, +0x52,0x5b,0x7a,0xe3,0x9a,0x5b,0xa9,0x0b,0xa5,0x0c,0x8d,0x1b,0x74,0xb3,0x67,0x23, +0x9c,0x31,0x10,0x8a,0x63,0x21,0x00,0x00,0x26,0xc2,0x4c,0x40,0x7c,0xe8,0xa0,0x86, +0xbc,0xc6,0xb7,0x71,0xa7,0x2d,0x94,0xb9,0x79,0x95,0x5a,0x85,0x3e,0x84,0x4a,0xa5, +0x58,0x71,0x72,0xa9,0x89,0x4d,0x97,0x31,0x9c,0x31,0x10,0x78,0x52,0x21,0x00,0x00, +0xb6,0x61,0x87,0x5c,0x71,0xd5,0x30,0x51,0x2d,0x3a,0x2a,0x39,0x4d,0x0c,0x66,0x12, +0x8b,0x5c,0x91,0x99,0x8e,0x6d,0x76,0xed,0x5c,0x25,0x5d,0x1d,0x55,0x59,0x59,0x9e, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_SIX.txt b/config/_default_cfg_src_/res/en/SOUND_SIX.txt new file mode 100644 index 0000000..f7d2004 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_SIX.txt @@ -0,0 +1,175 @@ +0x9c,0x31,0x10,0x19,0x43,0x44,0x00,0x00,0x7b,0x77,0x7b,0x77,0x83,0x77,0x7a,0x77, +0xac,0x77,0x52,0x37,0x83,0x49,0x70,0x77,0x22,0x85,0x2b,0x76,0x51,0xa8,0x19,0xa5, +0x12,0x95,0x44,0x69,0x40,0x68,0x5a,0x5c,0x9c,0x31,0x10,0xf5,0x44,0x54,0x00,0x00, +0x24,0x31,0x53,0xcc,0x43,0xc3,0x4b,0xc0,0x7a,0xc3,0x6b,0x54,0xa4,0x43,0x5b,0xbb, +0x9b,0xc4,0x75,0x4a,0x8c,0xc3,0x55,0x3b,0x8e,0x3c,0x3d,0x32,0x7c,0x2c,0x8c,0x9b, +0x9c,0x31,0x10,0xbf,0x64,0x54,0x00,0x00,0x72,0x11,0x79,0x4c,0x89,0x92,0x8e,0x1b, +0x62,0x1d,0x5d,0xd4,0x51,0xd3,0x4e,0x5c,0x2e,0x11,0x39,0x8b,0x65,0x49,0x70,0x8b, +0x74,0x5c,0x88,0x94,0x9d,0x8a,0x9c,0xa4,0x9c,0x31,0x10,0xc2,0x55,0x55,0x00,0x00, +0xa3,0x52,0x9b,0xda,0x5b,0xa5,0x64,0x4a,0x73,0x9b,0x21,0x83,0x61,0xad,0x91,0xb8, +0x8c,0x24,0xbc,0x2a,0xa2,0xdd,0xbb,0xd2,0xc1,0xcc,0xac,0x42,0x8b,0x53,0x84,0x2b, +0x9c,0x31,0x10,0x31,0x65,0x65,0x10,0x00,0x7d,0xbb,0x7e,0x33,0x68,0xcc,0x79,0xd3, +0x72,0xca,0x71,0x2b,0x69,0x1b,0xb6,0xc2,0xb5,0xcd,0x95,0x22,0xa0,0x8b,0xa1,0x32, +0xc4,0x4d,0xa4,0xb2,0x8d,0x2c,0x64,0x3b,0x9c,0x31,0x10,0xd2,0x55,0x66,0x10,0x00, +0xb0,0xa7,0x48,0x85,0x8b,0x96,0x99,0x97,0x60,0xc8,0xe2,0x97,0xe9,0x87,0xa3,0xa7, +0x94,0xa8,0x72,0xb3,0x0c,0x77,0x3b,0xc8,0x4d,0x7b,0x35,0x75,0xa4,0x06,0x33,0x75, +0x9c,0x31,0x10,0x51,0x66,0x77,0x20,0x00,0xbc,0x3c,0x49,0xb3,0x84,0x43,0x84,0x4a, +0x33,0x5b,0x2c,0x2c,0x93,0x4b,0xbd,0x42,0x49,0x33,0xaa,0xbb,0x7e,0xba,0x92,0xdc, +0xc2,0x33,0x89,0xbb,0xbc,0x41,0x54,0x34,0x9c,0x31,0x10,0x66,0x77,0x76,0x20,0x00, +0x99,0xa9,0x75,0x3d,0x61,0xa1,0x83,0x2e,0x6b,0xc3,0x63,0xb2,0x42,0xc5,0x63,0x41, +0x8b,0xc2,0x7b,0x5d,0x5b,0x49,0x43,0x2a,0x75,0x45,0x82,0xb3,0xec,0x12,0xba,0xe3, +0x9c,0x31,0x10,0x28,0x77,0x77,0x10,0x00,0xaa,0x53,0xb4,0x63,0xad,0x3a,0x7a,0x43, +0x84,0x4b,0x74,0xdc,0xa3,0x69,0x7c,0xdd,0x8b,0xca,0x94,0x5b,0x83,0xbc,0x5b,0xbc, +0x54,0xb2,0x2d,0xcb,0x7b,0x9b,0x8a,0x22,0x9c,0x31,0x10,0xe9,0x77,0x77,0x20,0x00, +0x74,0x05,0x6b,0x34,0x7b,0xb9,0x59,0x83,0xbb,0x33,0xca,0xb3,0xe4,0x09,0xa0,0x3d, +0xd2,0xa5,0x7a,0x40,0x72,0xab,0x73,0x2c,0x62,0x3b,0x2a,0x6b,0x02,0x74,0x0a,0x5a, +0x9c,0x31,0x10,0x30,0x87,0x87,0x40,0x00,0x51,0xd3,0x7a,0x63,0x56,0x44,0x41,0xc4, +0x3d,0xc3,0x7d,0x99,0x69,0x3d,0x7e,0x63,0x85,0xd2,0x91,0xc2,0x6a,0xc6,0x81,0x99, +0x92,0xb1,0x99,0xcb,0x5e,0x35,0x69,0x4c,0x9c,0x31,0x10,0x62,0x88,0x99,0x30,0x00, +0x4c,0x3b,0x6b,0xb3,0x54,0x34,0x9b,0xb3,0x7b,0x22,0x52,0xab,0x39,0xb4,0x5a,0xc2, +0x62,0x3a,0x79,0xc4,0x8b,0x4b,0xb9,0xc1,0x8b,0xbb,0xe1,0xb5,0xac,0xe3,0xc3,0x72, +0x9c,0x31,0x10,0xa0,0x97,0x98,0x30,0x00,0xc6,0x9c,0xab,0x6a,0x5e,0x53,0xb3,0x25, +0xb4,0x4a,0xa2,0x95,0x8b,0x75,0x7b,0x68,0x62,0x59,0x4a,0x75,0x4b,0x86,0x59,0x69, +0x8a,0x77,0x99,0x74,0x8a,0x69,0x8b,0x89,0x9c,0x31,0x10,0x8f,0xc7,0x87,0x30,0x00, +0x7a,0xb5,0x78,0xf0,0x81,0x21,0x8b,0x1e,0x8f,0x11,0x8c,0xcd,0x78,0x8e,0x60,0x91, +0x5a,0x98,0x76,0xe9,0xa0,0xae,0xb2,0xed,0x96,0xe4,0x61,0x95,0x3b,0x0e,0x43,0x61, +0x9c,0x31,0x10,0xc2,0xd8,0x87,0x30,0x00,0x86,0xd1,0xa3,0x11,0xa3,0x0d,0x8f,0x0d, +0x6f,0x0d,0x52,0x8d,0x55,0x69,0x86,0xc8,0xa1,0x0a,0x9c,0xce,0x93,0x10,0x86,0xb0, +0x59,0x91,0x3c,0xf6,0x73,0x0e,0xa4,0xc9,0x9c,0x31,0x10,0xc2,0xd8,0x87,0x30,0x00, +0x9f,0x29,0x92,0xa9,0x99,0x08,0x76,0xcd,0x38,0x09,0x4d,0x0a,0x9a,0xb1,0xa4,0xed, +0x90,0xe8,0x98,0xc9,0x98,0xf2,0x55,0x91,0x2c,0xb4,0x73,0x10,0xaa,0xa9,0x94,0xe5, +0x9c,0x31,0x10,0x5c,0xd8,0x98,0x30,0x00,0x8e,0xdb,0xa6,0xe3,0x8a,0xa3,0x3d,0x63, +0x35,0x62,0x8d,0x13,0xa6,0x8c,0x8a,0xd3,0x98,0xda,0xab,0x22,0x7c,0xa3,0x35,0x5b, +0x43,0x89,0x97,0x0c,0x9e,0xd4,0x8a,0xdc,0x9c,0x31,0x10,0xc1,0xd9,0x98,0x30,0x00, +0x9c,0xe2,0xa6,0xe2,0x78,0xe4,0x39,0x5b,0x45,0x11,0x95,0x0c,0x9c,0xcd,0x88,0xdb, +0x9e,0xe2,0xa6,0xe2,0x80,0xec,0x45,0x63,0x3a,0xde,0x88,0xe2,0xa0,0x99,0x89,0x13, +0x9c,0x31,0x10,0xd9,0xd9,0x88,0x30,0x00,0x97,0x1d,0xa4,0xe4,0x8c,0xd1,0x58,0xd3, +0x36,0x1a,0x6e,0xcd,0xa4,0xa3,0x8c,0xf2,0x8c,0xdb,0xa0,0xd4,0x98,0xdb,0x70,0xe2, +0x45,0x52,0x4b,0x24,0x94,0xe5,0x96,0xca,0x9c,0x31,0x10,0xe4,0xc9,0x98,0x30,0x00, +0x8b,0x12,0xaf,0x1c,0xc0,0xdb,0x96,0xdb,0x52,0xdc,0x02,0x9d,0x37,0x49,0xbe,0xc1, +0x9c,0xdc,0x8a,0xe4,0xba,0xdb,0xbc,0xd3,0x88,0xd3,0x42,0x92,0x00,0x13,0x57,0x0d, +0x9c,0x31,0x10,0xfc,0xc9,0x88,0x30,0x00,0xbe,0xa1,0x8c,0xea,0x92,0xe4,0xc0,0xdb, +0xb2,0xd2,0x88,0xcb,0x4c,0x83,0x02,0x1c,0x49,0x05,0xb8,0xa1,0x92,0xf2,0x90,0xdc, +0xbc,0xd4,0xb4,0xdb,0x90,0xd2,0x5c,0xc3,0x9c,0x31,0x10,0xe4,0xc9,0x98,0x30,0x00, +0x0a,0xe5,0x2b,0x51,0xb2,0xc2,0x9c,0xd6,0x86,0xda,0xb2,0xe1,0xbc,0xdc,0x98,0xdc, +0x70,0xe3,0x25,0x5b,0x04,0xe6,0x92,0xe8,0xb0,0x9a,0x80,0xd5,0xa8,0xd2,0xc0,0xda, +0x9c,0x31,0x10,0xc1,0xd9,0x98,0x30,0x00,0x8e,0xe5,0x82,0xdd,0x68,0xe1,0x40,0x1b, +0x5f,0x4c,0x9e,0xc9,0x88,0xdb,0x84,0xe4,0x9a,0xe2,0x9a,0xdb,0x88,0xd5,0x7e,0xd2, +0x5c,0xdb,0x3c,0x12,0x76,0xe4,0x9e,0xab,0x9c,0x31,0x10,0x4b,0xc8,0x97,0x20,0x00, +0x87,0x2d,0x94,0xc9,0xbf,0x0e,0xae,0xcc,0x8e,0xec,0x6a,0xce,0x27,0xad,0x10,0xd1, +0x8f,0x14,0xb0,0x8d,0x85,0x2d,0xa0,0xc9,0xbd,0x09,0xa6,0xae,0x8a,0xcc,0x66,0xad, +0x9c,0x31,0x10,0xcd,0xc8,0x98,0x20,0x00,0x27,0x9b,0x13,0x2c,0x8f,0x29,0xae,0x94, +0x85,0x13,0xa0,0xd3,0xbc,0xda,0xa6,0xe5,0x8a,0xea,0x72,0xe2,0x2d,0x94,0x08,0x53, +0x80,0xf1,0xb4,0x65,0x86,0xdb,0x98,0xd2,0x9c,0x31,0x10,0xfc,0xc9,0x88,0x30,0x00, +0xb8,0xd4,0xaa,0xd4,0x90,0xdb,0x76,0xe2,0x3d,0x1c,0x0a,0x4a,0x62,0xdd,0xb4,0xaa, +0x90,0xe3,0x8c,0xdb,0xb0,0xd4,0xae,0xdb,0x90,0xdc,0x82,0xd2,0x60,0xd3,0x1e,0xdb, +0x9c,0x31,0x10,0x4b,0xc8,0x97,0x20,0x00,0x2f,0x8c,0x9b,0x06,0xa9,0x0d,0x86,0xed, +0x98,0xf2,0xb5,0x0c,0xa2,0xd0,0x85,0x2a,0x76,0xe8,0x49,0x6d,0x1c,0x4c,0x60,0xd2, +0xae,0xb1,0x98,0xed,0x85,0x0d,0xa2,0xed,0x9c,0x31,0x10,0x72,0xc7,0x77,0x10,0x00, +0xb3,0x64,0x90,0x88,0x7b,0x1d,0x70,0xa2,0x3f,0x5a,0x2b,0xb4,0x79,0x0b,0xaa,0xdb, +0x96,0xcb,0x8b,0x1b,0xa0,0x93,0xa8,0xec,0x8a,0x9a,0x76,0xd3,0x66,0x94,0x42,0xa3, +0x9c,0x31,0x10,0x50,0xb7,0x67,0x20,0x00,0x01,0x41,0x78,0xc5,0xc8,0xda,0xba,0xdc, +0x9e,0xdb,0xb3,0x23,0xba,0xca,0x90,0xcc,0x68,0x92,0x4a,0xec,0x24,0xa3,0x27,0x02, +0x70,0xd3,0xb6,0xdb,0xba,0xe3,0xa4,0xdb,0x9c,0x31,0x10,0x91,0xa4,0x55,0x00,0x00, +0xba,0xe2,0xb3,0x94,0x80,0xdb,0x53,0x1b,0x45,0x0c,0x3b,0x11,0x3e,0xcc,0x6c,0xcb, +0x94,0x1b,0xa7,0x1b,0xac,0xe3,0xa9,0x5b,0x9a,0xd4,0x84,0xe2,0x68,0x9b,0x50,0x9b, +0x9c,0x31,0x10,0xd0,0x93,0x32,0x00,0x00,0x2a,0xd8,0x5e,0x8b,0x93,0x4b,0xc1,0x0d, +0xe2,0xdb,0xd8,0x9c,0xa8,0x9b,0x74,0xda,0x58,0xc4,0x46,0x94,0x53,0x10,0x72,0xdc, +0x8c,0x63,0x8b,0x63,0x77,0x13,0x6b,0x13,0x9c,0x31,0x10,0xbe,0x72,0x22,0x00,0x00, +0x26,0xa4,0x26,0x43,0x4a,0x6a,0x89,0x1a,0xaa,0x2c,0x92,0xd4,0x7b,0x1a,0x5d,0x33, +0x49,0x22,0x60,0x95,0x98,0x59,0x91,0x0b,0x77,0x2c,0x78,0xda,0x7e,0x6b,0x6c,0xe3, +0x9c,0x31,0x10,0x1e,0x63,0x32,0x00,0x00,0x79,0x23,0xa5,0x0b,0x92,0xd4,0x85,0x1b, +0x9d,0x1b,0x60,0xe2,0x10,0x5b,0x35,0x1b,0x7e,0x94,0xa3,0x1b,0xa2,0xa2,0x8b,0x15, +0x75,0x1a,0x6e,0x93,0x8a,0xd3,0x8f,0x1b,0x9c,0x31,0x10,0xe5,0x53,0x21,0x00,0x00, +0x4d,0x60,0x32,0x95,0x79,0x49,0xbe,0x1d,0xa8,0x91,0x4a,0x56,0x3d,0xe5,0xa6,0x65, +0xa9,0x68,0x55,0x55,0x59,0x96,0x5a,0x0d,0x02,0x19,0x1a,0x9d,0xa9,0x55,0xaa,0x66, +0x9c,0x31,0x10,0x78,0x52,0x21,0x00,0x00,0x55,0x9d,0x91,0xd8,0xcc,0xd9,0x96,0x29, +0x19,0xed,0x79,0x29,0xb3,0x5d,0x58,0xd0,0x2d,0x25,0x8e,0x69,0x99,0x21,0x68,0xa9, +0x96,0x0d,0xd5,0xe4,0x6e,0x19,0x3e,0xe1,0x9c,0x31,0x10,0x78,0x52,0x21,0x00,0x00, +0x78,0x5a,0xb6,0x25,0x49,0x61,0x49,0x5d,0xbe,0x18,0xba,0x21,0x56,0x9d,0xad,0x1d, +0xc6,0x55,0x79,0x8d,0x55,0x74,0x93,0x62,0x7d,0x95,0x59,0x9d,0x76,0xd5,0x84,0x8a, +0x9c,0x31,0x10,0x71,0x53,0x32,0x00,0x00,0x36,0x5b,0x56,0xdb,0x9e,0x52,0xa1,0x9e, +0x32,0x21,0x71,0xda,0x75,0x12,0x66,0x94,0x70,0xe2,0x71,0xd4,0x95,0x93,0x96,0x34, +0xa7,0xa3,0xc9,0x9a,0xa6,0x1a,0x80,0x9b,0x9c,0x31,0x10,0x98,0x89,0x85,0x10,0x00, +0x81,0xdd,0x81,0xdd,0x7d,0xdd,0x79,0xdd,0x81,0xdd,0x7d,0xde,0xb2,0x61,0xa1,0xf0, +0x7c,0xe9,0x6d,0x21,0x8d,0x61,0x89,0x9d,0x9e,0x1d,0xa6,0x21,0xe6,0xb2,0xc7,0x38, +0x9c,0x31,0x10,0x3e,0x88,0x84,0x00,0x00,0x5b,0x35,0x4d,0x31,0x58,0x2c,0x78,0x65, +0x44,0xe4,0x49,0xa1,0x3d,0xdc,0x2e,0x1d,0x32,0x5d,0x49,0xe1,0x65,0x5d,0x8d,0x9d, +0x79,0x9c,0x59,0xdd,0x6e,0x1d,0x7e,0x5e,0x9c,0x31,0x10,0x19,0x88,0x66,0x10,0x00, +0x5e,0x73,0x3e,0x23,0x62,0x73,0x85,0xea,0x6d,0xb4,0x71,0xb3,0x79,0x6b,0x91,0x63, +0xa1,0x4a,0x85,0x8c,0x8a,0x2b,0x85,0xe4,0x99,0xb2,0x85,0x0c,0x80,0xc0,0x61,0x46, +0x9c,0x31,0x10,0x5a,0x89,0x87,0x20,0x00,0x83,0x4b,0xa3,0x32,0x73,0x2b,0x63,0xcb, +0x8c,0x2b,0x94,0x3c,0x82,0xd3,0x92,0x2a,0x79,0x03,0x91,0x1a,0xda,0x25,0x8c,0xca, +0x95,0x32,0xb4,0x3c,0x82,0x3a,0x7c,0x3b,0x9c,0x31,0x10,0xcd,0x89,0x96,0x20,0x00, +0x85,0x4c,0xb4,0x38,0x98,0xc3,0x81,0x5b,0xa3,0x45,0x52,0xb9,0x49,0xab,0xc2,0xb2, +0x5b,0xbc,0x63,0x42,0xa9,0x35,0xb1,0xba,0x79,0xb2,0x79,0xc4,0x7a,0x22,0x9b,0xc6, +0x9c,0x31,0x10,0xf6,0x89,0x97,0x30,0x00,0x65,0xba,0x76,0x4c,0x6c,0xba,0x62,0x2d, +0x81,0xc2,0x8b,0xc5,0x95,0x40,0x85,0x43,0x8c,0xc2,0x8b,0xc5,0x7a,0xcb,0x7a,0xb3, +0x62,0xa4,0x3b,0x9a,0x9b,0x0b,0x8a,0x09,0x9c,0x31,0x10,0x20,0x79,0x87,0x30,0x00, +0x02,0x94,0x5b,0x12,0xb5,0x15,0x94,0x93,0x73,0x91,0x92,0xb4,0x82,0x99,0x74,0x9e, +0x4e,0x41,0x46,0xdc,0x6d,0x5a,0x7b,0x56,0x3a,0xc2,0xd2,0x3b,0x32,0x3a,0x2b,0x3a, +0x9c,0x31,0x10,0xbd,0x78,0x87,0x30,0x00,0xc5,0x3c,0x56,0x1b,0x1e,0x25,0x9c,0xb0, +0x12,0xcc,0x5b,0xb5,0x9a,0xca,0x3d,0x3b,0x4f,0x0b,0xb7,0x2b,0xb6,0x3b,0x6a,0xb4, +0x61,0xbc,0x7a,0xd9,0x7c,0x33,0xa4,0x22,0x9c,0x31,0x10,0x32,0x78,0x86,0x30,0x00, +0x03,0x9b,0x7c,0x25,0x5c,0x2b,0x6b,0x99,0x5b,0xa6,0x8c,0x42,0x65,0xcc,0x94,0xb3, +0x7c,0x3a,0x72,0x38,0x7b,0x3d,0x8a,0x9b,0x83,0x2a,0x64,0x44,0x75,0x45,0x86,0x41, +0x9c,0x31,0x10,0xd2,0x77,0x76,0x30,0x00,0x3e,0x71,0x84,0x6a,0x7a,0x56,0x89,0x51, +0x52,0x2c,0x72,0x09,0x93,0xb4,0x8c,0x2c,0xa5,0xa9,0x8f,0x3b,0x7e,0xc3,0x5e,0x31, +0x5d,0x33,0x54,0xbd,0x62,0xaa,0x6b,0x44,0x9c,0x31,0x10,0x5b,0x67,0x66,0x20,0x00, +0x6c,0x8d,0x2e,0xa9,0xd6,0x4c,0xbc,0x42,0xb2,0xcb,0xd1,0xe3,0xc2,0x3c,0x89,0x43, +0x8a,0xbb,0x33,0x4b,0x3b,0xd2,0x8b,0x64,0x4a,0xc2,0x63,0x74,0x8b,0x1a,0x82,0x2c, +0x9c,0x31,0x10,0x1c,0x66,0x74,0x10,0x00,0x39,0xc4,0xc0,0xab,0x41,0xc2,0x5a,0x43, +0x52,0xb4,0x93,0xbd,0x71,0xbb,0x89,0xb0,0xab,0x30,0xc5,0x45,0xc4,0xba,0xc4,0xcd, +0xac,0x48,0x8b,0xdc,0x61,0x4d,0x6a,0x4d,0x9c,0x31,0x10,0x8b,0x66,0x65,0x10,0x00, +0x62,0x42,0x6c,0x3b,0x9c,0x41,0x93,0x4b,0x84,0x3b,0x9a,0xbb,0x9b,0x2c,0xb1,0xbb, +0xc2,0x2c,0x92,0xbb,0x9b,0x13,0x83,0xa3,0x6e,0x33,0x7c,0x49,0x8b,0xa3,0xab,0x3b, +0x9c,0x31,0x10,0x25,0x56,0x65,0x20,0x00,0xf3,0x23,0x71,0xb5,0xd2,0xab,0x9a,0xb3, +0xbd,0x4a,0x4e,0x2a,0x85,0x2c,0x23,0xc2,0x4a,0x5b,0x22,0x4a,0x3a,0x4d,0x23,0xc3, +0x29,0xb5,0xbc,0x29,0x8b,0xab,0xdb,0x35,0x9c,0x31,0x10,0xa9,0x56,0x66,0x20,0x00, +0xe8,0x85,0xdc,0x66,0xbb,0x64,0xab,0x75,0xb8,0x5b,0xc7,0x86,0xa6,0xc8,0xb2,0xb7, +0x70,0x77,0x70,0x27,0x74,0x65,0x59,0x66,0x5c,0x68,0x9a,0x29,0x0d,0x67,0x4d,0x96, +0x9c,0x31,0x10,0x38,0x55,0x54,0x20,0x00,0x63,0x31,0x6c,0x49,0x2a,0x91,0x08,0xb5, +0x14,0xce,0x86,0x36,0x3a,0x8a,0x42,0x86,0x32,0xc9,0x79,0x85,0x7d,0x64,0x9d,0x2c, +0x40,0x54,0xa4,0x70,0xc5,0x49,0xc3,0x91,0x9c,0x31,0x10,0x76,0x55,0x55,0x10,0x00, +0x91,0xa3,0x7a,0x3d,0x7a,0xb9,0x9b,0x9a,0x64,0x5b,0x4d,0x53,0x34,0x64,0x3b,0x20, +0x4a,0xac,0x59,0x3c,0x3a,0xec,0x22,0xbb,0x49,0x3b,0x7b,0xb2,0x4c,0xbc,0x85,0x42, +0x9c,0x31,0x10,0xe4,0x56,0x65,0x10,0x00,0x8c,0x3b,0x3c,0x39,0x5b,0x3b,0x5a,0x2d, +0x63,0x2a,0x8a,0xab,0x9b,0x33,0x9d,0x3b,0xe5,0x2a,0x9b,0x33,0x9a,0x2b,0x9a,0x22, +0xd1,0xbb,0xb1,0xc3,0x62,0x5c,0x73,0x4b,0x9c,0x31,0x10,0x76,0x55,0x55,0x10,0x00, +0x91,0xdb,0xc8,0xb3,0x75,0xba,0x7c,0x12,0x8b,0x43,0x72,0x43,0xa2,0x4a,0xa3,0x4c, +0xad,0x35,0x6c,0x12,0x84,0xba,0x64,0x9a,0x8d,0x13,0x64,0xc3,0x9c,0xc3,0x84,0xab, +0x9c,0x31,0x10,0x6e,0x55,0x45,0x10,0x00,0x95,0xd3,0xd4,0x4d,0xac,0xca,0x7b,0xb3, +0x43,0xca,0x9c,0xaa,0x94,0x3c,0x45,0x43,0x3b,0xb3,0x4d,0x4c,0x33,0xc2,0x24,0xcc, +0x33,0x3a,0x4a,0x33,0x2a,0xe3,0x64,0x42,0x9c,0x31,0x10,0xda,0x55,0x45,0x00,0x00, +0x94,0x45,0x54,0x53,0x06,0x1a,0x45,0xab,0x6e,0x09,0x74,0x44,0x5d,0x2c,0x8b,0xea, +0x9a,0xf4,0x73,0xd2,0x79,0xe4,0xa2,0xca,0x71,0xa4,0x8d,0xcb,0x6d,0x22,0x76,0xcb, +0x9c,0x31,0x10,0x76,0x55,0x55,0x10,0x00,0x5d,0xbc,0x7e,0x41,0x74,0xca,0x72,0x4c, +0x5b,0x4e,0x78,0x51,0xa0,0xbb,0x91,0x43,0xca,0x2b,0xb8,0x23,0xab,0x1b,0x72,0x99, +0x8d,0x2b,0x9f,0x1b,0x86,0xab,0x5e,0xc3,0x9c,0x31,0x10,0x7b,0x45,0x65,0x10,0x00, +0x3c,0xb5,0x3c,0xc3,0x0a,0xbb,0x2a,0x32,0x19,0xc2,0x3a,0x34,0x33,0xab,0xee,0x3a, +0x5d,0xb5,0x76,0xba,0x5e,0x3c,0xa5,0x33,0x0c,0xda,0x83,0xac,0x71,0xca,0x42,0x3b, +0x9c,0x31,0x10,0x4d,0x55,0x54,0x00,0x00,0x4a,0xc5,0x9a,0xb9,0x93,0x2c,0xa4,0xbd, +0x6d,0xd2,0x44,0xba,0x74,0xcb,0x7c,0x3a,0x5c,0xcc,0x22,0xc3,0x6a,0xa4,0xa2,0x4c, +0x73,0xda,0x6a,0xa2,0x64,0x42,0x73,0x44,0x9c,0x31,0x10,0x67,0x44,0x43,0x00,0x00, +0x9c,0xb3,0x8a,0x3a,0x81,0x9e,0x61,0x18,0xc2,0x1b,0xdc,0xcb,0xd3,0xb2,0xd4,0x9e, +0x94,0xb1,0x62,0x43,0xac,0x53,0xb9,0xd2,0x80,0xb6,0x2a,0x0a,0x03,0x11,0x54,0x6d, +0x9c,0x31,0x10,0xc8,0x54,0x44,0x00,0x00,0x45,0xbb,0x5e,0xaa,0x44,0xdc,0x54,0x5c, +0x54,0x42,0x92,0x4b,0xa5,0x4c,0x93,0x44,0x9b,0xa3,0x8d,0x49,0x94,0x44,0x63,0xbb, +0x6b,0xa0,0x93,0x35,0xbc,0x4b,0xbb,0x3a,0x9c,0x31,0x10,0x62,0x44,0x45,0x00,0x00, +0xda,0x3c,0x93,0xa3,0xaa,0xa3,0xc9,0xd4,0x5a,0xe2,0x15,0xcb,0x41,0xc4,0x7b,0xdb, +0x2b,0xb3,0x4a,0xb3,0x8a,0xbb,0xac,0xb2,0x9a,0x2c,0x9b,0x23,0xea,0xa2,0xb3,0xb5, +0x9c,0x31,0x10,0xc8,0x54,0x44,0x00,0x00,0x9b,0x1b,0x7c,0x21,0xa4,0x5e,0x95,0x31, +0x96,0x1b,0xbc,0xcd,0xae,0xd8,0xbc,0x3b,0xcb,0x1d,0xab,0x59,0x90,0xc4,0x80,0x3c, +0xa0,0xb1,0x62,0x35,0x5b,0xac,0x74,0xa2,0x9c,0x31,0x10,0x68,0x45,0x54,0x00,0x00, +0xf5,0x2c,0x85,0x33,0x85,0xc1,0xad,0xcc,0x6d,0x5b,0xb4,0x42,0xbb,0xbc,0x2a,0xca, +0x62,0x4b,0xc1,0xcb,0x62,0x3b,0x22,0x29,0x2b,0xb5,0x0c,0x43,0x15,0xcc,0x95,0x3b, +0x9c,0x31,0x10,0x3f,0x65,0x42,0x00,0x00,0xb2,0xa1,0xca,0x31,0xa5,0xaa,0x6d,0x60, +0x51,0x64,0x54,0xd9,0x45,0x55,0x61,0x99,0x82,0x15,0x9a,0x5c,0x8a,0x61,0x7a,0x9e, +0x6a,0x60,0x5a,0x2d,0x75,0xe5,0x91,0xe5,0x9c,0x31,0x10,0xaf,0x73,0x21,0x00,0x00, +0x84,0x98,0x7c,0x32,0x76,0xf1,0x7b,0x0d,0x79,0x6c,0x74,0xd1,0x76,0xb0,0x7a,0xda, +0x7a,0xed,0x78,0xed,0x8c,0x6d,0x96,0xb4,0xba,0xd0,0xa4,0xed,0x70,0xf1,0x3f,0x11, +0x9c,0x31,0x10,0xb3,0x62,0x12,0x00,0x00,0x09,0x13,0x4a,0xf1,0x76,0xac,0x86,0xd4, +0x89,0x43,0x50,0x84,0x0c,0xe9,0x22,0x6b,0x5d,0x13,0x84,0xe3,0x89,0x0c,0x83,0x4b, +0x58,0xe3,0x45,0x33,0x4f,0xb2,0x6b,0x2a,0x9c,0x31,0x10,0x69,0x53,0x22,0x00,0x00, +0x9d,0x95,0xb1,0x93,0x71,0x1b,0x69,0x4b,0x4d,0x92,0x72,0x1b,0xb1,0x9c,0xc1,0x53, +0xae,0x93,0x95,0x9a,0x7d,0xdb,0x7d,0x5d,0x86,0x9b,0xad,0x53,0xa9,0xe2,0xba,0xe4, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_THREE.txt b/config/_default_cfg_src_/res/en/SOUND_THREE.txt new file mode 100644 index 0000000..bcd9cf2 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_THREE.txt @@ -0,0 +1,145 @@ +0x9c,0x31,0x10,0x3c,0x53,0x44,0x00,0x00,0x7b,0x77,0x7b,0x77,0x7b,0x77,0x7b,0x77, +0x59,0x67,0x6c,0x65,0x6b,0x6a,0x81,0x76,0x83,0x68,0x90,0x43,0x5c,0xc8,0x96,0x68, +0x7c,0x76,0x63,0x78,0x94,0x97,0x35,0x59,0x9c,0x31,0x10,0xd0,0x54,0x54,0x00,0x00, +0x7b,0x4b,0x69,0x32,0x6a,0xc3,0x53,0xcc,0x41,0xaa,0x7b,0x2a,0x73,0x3b,0x53,0x24, +0x63,0x23,0x52,0xcc,0x7a,0x29,0x3a,0x94,0xab,0xcc,0x6b,0x53,0x94,0x3c,0x8b,0x39, +0x9c,0x31,0x10,0xf9,0x55,0x54,0x10,0x00,0x82,0xbc,0xac,0xb3,0x82,0x32,0xb3,0xc9, +0x8c,0xac,0x95,0x24,0x9a,0xbd,0xac,0x53,0xb4,0xb3,0xc2,0xca,0xf4,0x22,0x64,0x51, +0xc3,0xba,0x54,0x95,0x8b,0xe5,0x79,0x5b,0x9c,0x31,0x10,0xa9,0x56,0x66,0x20,0x00, +0x46,0x37,0x48,0x76,0x54,0x86,0x89,0x77,0x19,0x9b,0x53,0x68,0x3a,0x76,0x75,0x35, +0x55,0x65,0x57,0xac,0x54,0x96,0x58,0x77,0x16,0x65,0x58,0x43,0x99,0xc8,0x8c,0x5c, +0x9c,0x31,0x10,0x1b,0x87,0x87,0x30,0x00,0x79,0xc3,0x8e,0x43,0x82,0x42,0x91,0xc3, +0x85,0xb2,0x79,0x41,0x69,0xc3,0x61,0xb5,0x72,0x3c,0x7e,0xbb,0x86,0x2a,0x8e,0x41, +0xba,0xb3,0xcd,0x5b,0xdd,0xa3,0xa0,0x36,0x9c,0x31,0x10,0x73,0x88,0x87,0x30,0x00, +0x3b,0xca,0x6a,0xc3,0x9a,0xa9,0x9b,0xcb,0x92,0xbb,0x62,0x2b,0x51,0x13,0x23,0x43, +0x5c,0xab,0x4c,0x3b,0x4d,0x2b,0x45,0x43,0x2d,0xcb,0x43,0xd1,0x5a,0xad,0x69,0xbc, +0x9c,0x31,0x10,0x93,0x87,0x77,0x30,0x00,0x84,0xd5,0xb8,0x58,0xdc,0x64,0xb4,0x8a, +0x9d,0x64,0x9a,0x91,0xa2,0x0c,0x7a,0xab,0x76,0xec,0x9b,0x22,0x92,0x8b,0x8a,0x9c, +0xb2,0x33,0xd8,0xd9,0xc4,0x23,0x08,0xa3,0x9c,0x31,0x10,0xfb,0x88,0x77,0x30,0x00, +0x30,0xa3,0x3d,0x5c,0x71,0x5b,0x41,0xab,0x62,0x2a,0x71,0xe3,0x66,0x5b,0x61,0x93, +0x6e,0x62,0x61,0x73,0x62,0x63,0x66,0x5d,0x76,0x33,0x82,0x22,0x39,0xaa,0x85,0x13, +0x9c,0x31,0x10,0xdf,0xb7,0x66,0x20,0x00,0x7e,0xa6,0x7a,0x74,0x8a,0x52,0x82,0xdb, +0x78,0x9a,0x81,0x63,0x86,0xe3,0x82,0xdc,0x98,0xdb,0x92,0xdb,0x65,0x24,0x48,0xec, +0x53,0x29,0x96,0xa3,0xdb,0x23,0xd3,0x23,0x9c,0x31,0x10,0x08,0xc9,0x76,0x10,0x00, +0x72,0xed,0x48,0xcd,0x34,0xa9,0x72,0xad,0xb6,0xc9,0xd9,0x4d,0xa5,0x0d,0x5b,0x4d, +0x24,0x8d,0x3f,0x2d,0x97,0x30,0xc5,0x0e,0xc5,0x0d,0xa4,0xcd,0x63,0x4d,0x1c,0x44, +0x9c,0x31,0x10,0x87,0xc9,0x77,0x10,0x00,0x3a,0xea,0x9f,0x29,0xcb,0x4c,0xbb,0x51, +0x9d,0x11,0x64,0xed,0x14,0x29,0x3a,0x6d,0xa2,0xe6,0xcf,0x45,0xb9,0x69,0x97,0x0a, +0x68,0xe4,0x12,0xa5,0x34,0xc8,0xa3,0x0a,0x9c,0x31,0x10,0x1a,0xc8,0x77,0x10,0x00, +0xd1,0x65,0xb7,0x29,0x93,0x45,0x5e,0xe1,0x0e,0x2a,0x44,0x08,0xb0,0xc6,0xd3,0x45, +0xb1,0x6d,0x8f,0x45,0x55,0x04,0x0a,0xfa,0x52,0x08,0xba,0x51,0xd0,0xc2,0xac,0xec, +0x9c,0x31,0x10,0xce,0xc9,0x87,0x20,0x00,0x8b,0x2a,0x47,0x0c,0x09,0x36,0x62,0x69, +0xc8,0x91,0xce,0xca,0xa3,0x0c,0x81,0x4e,0x36,0xf5,0x13,0x6d,0x76,0xb5,0xce,0x8d, +0xc8,0x91,0x9c,0xad,0x7d,0x31,0x2a,0xb1,0x9c,0x31,0x10,0x41,0xc9,0x86,0x20,0x00, +0x17,0x89,0x85,0x11,0xd2,0xcd,0xc6,0xad,0x9a,0xad,0x73,0x31,0x1e,0xa8,0x25,0x4a, +0x95,0x50,0xd9,0x0a,0xc2,0xd1,0x94,0xcd,0x65,0x0a,0x10,0xa4,0x34,0xcd,0xa5,0x2d, +0x9c,0x31,0x10,0xd8,0xc8,0x75,0x20,0x00,0xd9,0x65,0xbc,0xd5,0x8e,0xa9,0x59,0x06, +0x0e,0xea,0x44,0x75,0xaf,0x05,0xd7,0x4d,0xb6,0xd0,0x8a,0xa2,0x4a,0xd0,0x11,0x59, +0x5a,0x29,0xbc,0x8d,0xd7,0x51,0xaf,0x29,0x9c,0x31,0x10,0x45,0xc9,0x75,0x20,0x00, +0x82,0xed,0x3a,0xb6,0x13,0x50,0x6a,0xc5,0xc6,0xd5,0xd7,0x0c,0xa9,0x29,0x78,0xf8, +0x2a,0x92,0x1b,0x64,0x7d,0x12,0xce,0xd1,0xd2,0xa6,0xa3,0x15,0x6b,0x4d,0x1a,0x84, +0x9c,0x31,0x10,0xad,0xc8,0x75,0x00,0x00,0x27,0x8a,0x91,0x71,0xd8,0xe9,0xca,0x4d, +0x98,0xd1,0x5d,0xaa,0x12,0x40,0x32,0xd6,0x9d,0x68,0xdd,0x6a,0xc6,0x75,0x92,0x81, +0x55,0x2d,0x0c,0xad,0x3a,0xcd,0xa9,0x2d,0x9c,0x31,0x10,0x19,0xc8,0x75,0x10,0x00, +0xe1,0x6d,0xc4,0xcd,0x8c,0x2d,0x49,0x28,0x0a,0xd6,0x48,0x2c,0xb3,0x05,0xe1,0xb1, +0xc1,0x09,0x88,0x51,0x40,0xb0,0x0b,0x3a,0x52,0x88,0xba,0xb2,0xe1,0x2c,0xbb,0x6a, +0x9c,0x31,0x10,0x1d,0xc8,0x86,0x10,0x00,0x82,0xb1,0x36,0xb1,0x09,0x55,0x58,0x49, +0xbe,0x91,0xe1,0x2c,0xbb,0x6e,0x84,0xf0,0x34,0xd2,0x05,0x30,0x58,0x6a,0xc4,0xb1, +0xe6,0xe9,0xbb,0x32,0x7f,0x2c,0x31,0x32,0x9c,0x31,0x10,0x38,0xd8,0x86,0x10,0x00, +0x41,0x70,0x6c,0x2a,0xa2,0x74,0xb0,0xc9,0x9d,0x31,0x81,0x0c,0x5b,0x36,0x3f,0x70, +0x68,0x4e,0xa0,0x70,0xb6,0xea,0x9f,0x11,0x80,0xe9,0x5d,0x51,0x3f,0x50,0x62,0x4e, +0x9c,0x31,0x10,0xfd,0xd8,0x75,0x20,0x00,0x9c,0x94,0xb4,0xe5,0xa1,0x15,0x86,0xa9, +0x63,0x15,0x3e,0x96,0x5a,0x31,0x96,0xb1,0xb7,0x2c,0xa6,0xea,0x8a,0xad,0x68,0xa5, +0x3e,0x0e,0x50,0xac,0x8a,0xe6,0xb5,0x30,0x9c,0x31,0x10,0x64,0xd9,0x86,0x20,0x00, +0xac,0xc9,0x92,0xc9,0x72,0xc9,0x44,0xa5,0x43,0x2a,0x7d,0x09,0xb1,0x2a,0xb4,0xec, +0x9b,0x0a,0x7b,0x0d,0x4f,0x32,0x39,0x88,0x6b,0x32,0xa7,0x0c,0xb9,0x12,0xa3,0x10, +0x9c,0x31,0x10,0x76,0xd8,0x87,0x20,0x00,0x89,0x11,0x61,0x30,0x38,0x9a,0x4e,0x30, +0x90,0x52,0xba,0x70,0xae,0x51,0x92,0x6d,0x74,0x4d,0x44,0x45,0x39,0x2a,0x71,0x08, +0xaf,0x4a,0xbd,0x25,0xa1,0x29,0x87,0x49,0x9c,0x31,0x10,0xb7,0xd8,0x87,0x10,0x00, +0x5f,0x6c,0x35,0x16,0x48,0xd0,0x90,0xb2,0xc0,0xf0,0xb4,0xd5,0x96,0xcd,0x76,0xd1, +0x48,0xd1,0x33,0x85,0x65,0x2d,0xa9,0x29,0xc3,0x2d,0xa8,0xe9,0x8d,0x09,0x6c,0xcd, +0x9c,0x31,0x10,0xb7,0xd8,0x87,0x10,0x00,0x3c,0x44,0x36,0xce,0x76,0xac,0xb8,0xce, +0xc2,0xc9,0xa0,0xcd,0x84,0xcd,0x63,0x0d,0x36,0x8e,0x3e,0xd8,0x84,0xce,0xc0,0xd0, +0xbc,0xea,0x9a,0xcc,0x82,0xee,0x63,0x0c,0x9c,0x31,0x10,0xdf,0xd7,0x87,0x10,0x00, +0x34,0x66,0x3e,0xac,0x84,0x9e,0xc0,0xd9,0xbe,0xd9,0x98,0xe1,0x82,0xe5,0x67,0x15, +0x3a,0x08,0x3a,0xfa,0x7c,0xe1,0xbc,0xdd,0xc1,0x11,0x9c,0xe0,0x83,0x2e,0x6e,0xdc, +0x9c,0x31,0x10,0x5a,0xd6,0x97,0x10,0x00,0x46,0x16,0x35,0x51,0x66,0xad,0xaf,0x19, +0xc4,0xdd,0xa6,0x99,0x87,0x21,0x7a,0x99,0x5b,0xa0,0x37,0x2a,0x4a,0xd0,0x92,0xdd, +0xc2,0xa1,0xb7,0x18,0x90,0x9e,0x7f,0x20,0x9c,0x31,0x10,0x59,0xd7,0x88,0x10,0x00, +0x70,0xcc,0x48,0x51,0x37,0x25,0x6a,0xe0,0xae,0xcd,0xc0,0xd9,0xa0,0xec,0x84,0xcb, +0x7e,0xa2,0x69,0x14,0x3e,0x63,0x40,0xea,0x7e,0x85,0xb8,0xe9,0xbb,0x24,0x96,0xd2, +0x9c,0x31,0x10,0x1e,0xd7,0x87,0x20,0x00,0x82,0xe1,0x7c,0xea,0x61,0x50,0x3a,0xf2, +0x4a,0xc9,0x8c,0xed,0xba,0xda,0xb3,0x19,0x92,0xe1,0x82,0xdd,0x7c,0xdd,0x5d,0x61, +0x3b,0x21,0x4c,0xc5,0x8e,0xf5,0xbe,0xc9,0x9c,0x31,0x10,0x1e,0xd7,0x87,0x20,0x00, +0xb3,0x29,0x90,0xd5,0x80,0xdd,0x7e,0xb1,0x63,0x4e,0x3c,0xf8,0x48,0xc1,0x88,0xf1, +0xba,0xd5,0xb2,0xde,0x92,0xa9,0x84,0xcc,0x82,0xe9,0x69,0x51,0x40,0x6d,0x42,0xd8, +0x9c,0x31,0x10,0x70,0xd6,0x88,0x00,0x00,0x7a,0x95,0xb3,0x21,0xb6,0x94,0x9a,0xe3, +0x86,0x5a,0x85,0x1c,0x74,0x9b,0x4e,0x54,0x3b,0x9a,0x60,0xda,0xa1,0x1d,0xbc,0xda, +0xa6,0xd3,0x8a,0xa4,0x85,0x09,0x82,0xad,0x9c,0x31,0x10,0x98,0xd7,0x88,0x20,0x00, +0x65,0x52,0x3c,0xb4,0x44,0xc0,0x7e,0xed,0xb4,0xc9,0xb6,0xe5,0x98,0xd1,0x86,0xac, +0x84,0xd3,0x74,0x9b,0x4e,0x92,0x39,0x1d,0x5e,0xe1,0x9c,0xd5,0xbc,0xe2,0xa8,0xd4, +0x9c,0x31,0x10,0x59,0xd7,0x88,0x10,0x00,0x8e,0xe1,0x84,0xcd,0x82,0xe2,0x69,0x14, +0x42,0x59,0x40,0xe5,0x72,0xd3,0xaa,0xe2,0xb8,0xd4,0x9e,0xe2,0x8a,0xdd,0x86,0xd2, +0x7e,0xe3,0x5f,0x13,0x3c,0xec,0x48,0xc8,0x9c,0x31,0x10,0x05,0xd6,0x88,0x20,0x00, +0x80,0xac,0xb0,0xcb,0xb5,0x2b,0x9a,0xcb,0x88,0xe4,0x86,0xd2,0x7c,0xe3,0x5d,0x5b, +0x3f,0x24,0x4c,0xcb,0x84,0xe1,0xb0,0x95,0xb1,0x23,0x96,0xca,0x86,0xec,0x88,0xcc, +0x9c,0x31,0x10,0xaf,0xc6,0x89,0x20,0x00,0x80,0xaa,0x43,0x8c,0x01,0x2b,0x16,0x8b, +0x82,0xea,0xdc,0xcc,0xe2,0xe2,0xb2,0xd4,0x92,0xe2,0x92,0xd5,0x84,0xe1,0x4d,0x55, +0x08,0xa3,0x12,0x92,0x70,0xa4,0xd0,0xd3,0x9c,0x31,0x10,0xa8,0xc6,0x78,0x20,0x00, +0xe2,0xea,0xb7,0x13,0x90,0xdb,0x8f,0x23,0x8e,0xd2,0x68,0xe3,0x22,0x0b,0x09,0x2d, +0x48,0xd0,0xad,0x25,0xdc,0xd2,0xc4,0xe3,0x9c,0xdb,0x8e,0xe3,0x94,0xd1,0x80,0xa4, +0x9c,0x31,0x10,0x1b,0xc6,0x89,0x30,0x00,0x47,0x1a,0x0f,0x64,0x20,0x8c,0x76,0xe1, +0xc8,0xd4,0xd7,0x1a,0xb2,0xdc,0x94,0xd1,0x8e,0xec,0x8c,0xcb,0x68,0xea,0x2a,0x4c, +0x11,0x2b,0x44,0xd2,0x9e,0xe3,0xd4,0xd3,0x9c,0x31,0x10,0x94,0xc5,0x77,0x20,0x00, +0xc9,0x6b,0xa3,0x8b,0x8e,0x6a,0x8f,0x4d,0x86,0x28,0x58,0x96,0x1e,0x6a,0x1c,0x50, +0x61,0x26,0xb3,0x52,0xd2,0x64,0xbd,0x53,0x9a,0x6b,0x8f,0x4a,0x91,0x6b,0x7d,0x16, +0x9c,0x31,0x10,0x0a,0xc5,0x68,0x20,0x00,0x49,0x52,0x1d,0x3c,0x2a,0x97,0x72,0xe4, +0xb8,0x99,0xcc,0xd5,0xb6,0x99,0x98,0xc7,0x8c,0x97,0x8b,0x43,0x76,0xbb,0x48,0xb4, +0x23,0x49,0x30,0x8a,0x72,0xe3,0xb4,0x9a,0x9c,0x31,0x10,0xbe,0xc5,0x68,0x30,0x00, +0xc8,0xc5,0xb7,0x29,0x98,0xd6,0x8c,0x94,0x8a,0xd9,0x7c,0x28,0x53,0x55,0x26,0xcb, +0x2c,0x15,0x6a,0xe5,0xae,0x88,0xca,0xd6,0xb8,0x98,0x98,0xd6,0x8a,0x95,0x8c,0xdb, +0x9c,0x31,0x10,0xa6,0xc5,0x78,0x30,0x00,0x80,0xa6,0x5b,0x47,0x2e,0xb9,0x2a,0xc2, +0x5e,0xbc,0xa2,0xb4,0xc2,0xca,0xba,0xa5,0xa0,0x48,0x8e,0xa5,0x8c,0x59,0x84,0x97, +0x66,0xd5,0x38,0x18,0x28,0xd9,0x4e,0x96,0x9c,0x31,0x10,0x8c,0xc5,0x67,0x20,0x00, +0x90,0x72,0xbe,0x44,0xc1,0x6a,0xa8,0x55,0x90,0x21,0x8b,0x55,0x8a,0x5a,0x76,0x5c, +0x4a,0x62,0x28,0x89,0x39,0x66,0x76,0x52,0xb0,0x6c,0xc2,0x4b,0xb1,0x6b,0x97,0x65, +0x9c,0x31,0x10,0xe2,0xc4,0x68,0x00,0x00,0x8d,0x14,0x8e,0xe8,0x80,0x18,0x59,0x56, +0x30,0x3a,0x2e,0x32,0x60,0x4b,0x9e,0xa4,0xc1,0x69,0xb8,0x96,0x9e,0xe7,0x8c,0x86, +0x8c,0x56,0x8a,0xaa,0x72,0xb4,0x46,0xca,0x9c,0x31,0x10,0xd3,0xc5,0x78,0x10,0x00, +0x2b,0x13,0x40,0xd8,0x7c,0x98,0xb0,0xd6,0xc0,0x99,0xae,0xc4,0x92,0xa9,0x88,0xc4, +0x8c,0xbb,0x88,0xa4,0x66,0xc8,0x3a,0x15,0x2e,0xd9,0x52,0x98,0x90,0xd5,0xb8,0x99, +0x9c,0x31,0x10,0xc8,0xc4,0x77,0x10,0x00,0xba,0x60,0xa0,0x5e,0x89,0x50,0x87,0x66, +0x90,0x51,0x85,0x24,0x5e,0x8c,0x36,0x2b,0x36,0x0a,0x63,0x2b,0x9c,0x14,0xba,0x62, +0xb3,0x55,0x99,0x21,0x87,0x8b,0x88,0x64,0x9c,0x31,0x10,0xd0,0xc4,0x67,0x10,0x00, +0x8e,0x8b,0x7e,0x62,0x57,0x94,0x34,0xb3,0x3c,0x44,0x6d,0x70,0xa4,0x56,0xbc,0x60, +0xb0,0x5d,0x94,0x1a,0x83,0x5c,0x87,0x5a,0x8e,0xa4,0x7c,0x53,0x54,0xa3,0x34,0xa4, +0x9c,0x31,0x10,0xd0,0xc4,0x67,0x10,0x00,0x3e,0x4b,0x6f,0x69,0xa5,0x15,0xbb,0x59, +0xae,0x5c,0x94,0x1a,0x85,0x93,0x8a,0x63,0x8f,0x94,0x7d,0x21,0x58,0x54,0x38,0x6c, +0x3e,0x09,0x6c,0x6b,0xa2,0x4c,0xb9,0x62,0x9c,0x31,0x10,0xe2,0xc4,0x68,0x00,0x00, +0xac,0xa8,0x94,0x46,0x86,0x97,0x8a,0xd5,0x8f,0x2b,0x7e,0xb3,0x5b,0x3a,0x3a,0x37, +0x3e,0xc5,0x68,0xba,0x9c,0xb5,0xb6,0xc8,0xac,0xa6,0x94,0x58,0x84,0x96,0x88,0xd8, +0x9c,0x31,0x10,0xd0,0xc4,0x67,0x10,0x00,0x8f,0x4b,0x81,0x6a,0x5e,0x8d,0x3c,0x21, +0x3d,0x64,0x66,0x54,0x9c,0x61,0xb7,0x5c,0xae,0x5a,0x96,0x64,0x86,0x9b,0x88,0x9b, +0x8e,0x5a,0x81,0x1d,0x62,0x9a,0x43,0x13,0x9c,0x31,0x10,0x90,0xc3,0x67,0x00,0x00, +0x3f,0xa5,0x62,0x51,0x94,0xa3,0xb3,0x54,0xae,0x62,0x98,0x54,0x89,0x9a,0x88,0x9d, +0x8d,0x51,0x83,0x64,0x68,0x13,0x49,0x23,0x40,0x8c,0x5d,0x69,0x8d,0x8e,0xae,0x21, +0x9c,0x31,0x10,0x9f,0xb4,0x67,0x00,0x00,0xdc,0xdd,0xb8,0xda,0x9d,0x23,0x94,0x93, +0x94,0xe4,0x82,0x93,0x54,0xdb,0x1e,0xdc,0x09,0x91,0x35,0x2d,0x8b,0x0a,0xd2,0xaa, +0xdf,0x0c,0xc1,0x22,0x9c,0xd4,0x8e,0xd9,0x9c,0x31,0x10,0x9f,0xb4,0x67,0x00,0x00, +0x8b,0x1d,0x7c,0xd2,0x5b,0x23,0x31,0x13,0x17,0x62,0x34,0xd5,0x80,0xd8,0xc2,0xa6, +0xd5,0x12,0xbc,0xec,0x9e,0xca,0x8c,0xeb,0x82,0xcc,0x72,0xe2,0x5a,0xd4,0x3c,0xda, +0x9c,0x31,0x10,0xcc,0xb3,0x56,0x00,0x00,0x2d,0x4c,0x42,0x83,0x7c,0xe6,0xb6,0x8c, +0xcc,0xd1,0xbe,0xae,0xa2,0xb2,0x8a,0xca,0x78,0xa5,0x66,0x48,0x52,0xa7,0x40,0xc6, +0x3d,0x28,0x5c,0xc9,0x92,0xa3,0xc0,0xca,0x9c,0x31,0x10,0x51,0xb2,0x56,0x00,0x00, +0xcb,0x26,0xb3,0x46,0x90,0x2a,0x75,0x45,0x66,0xb7,0x5d,0x38,0x50,0xb5,0x4c,0xc9, +0x5d,0x15,0x80,0xd8,0xa6,0x99,0xba,0xc2,0xb6,0xac,0x9e,0xb3,0x86,0xba,0x70,0x25, +0x9c,0x31,0x10,0x6f,0xa2,0x44,0x00,0x00,0x3c,0x6e,0x1b,0x49,0x0f,0xb4,0x30,0x94, +0x78,0x61,0xc3,0x53,0xf0,0x1d,0xee,0x98,0xc5,0x5d,0x8f,0x52,0x5e,0x63,0x39,0x54, +0x21,0x5a,0x23,0x53,0x42,0x25,0x78,0x91,0x9c,0x31,0x10,0xa8,0xa2,0x35,0x00,0x00, +0xb6,0xb3,0xe2,0x24,0xea,0x69,0xc8,0x94,0x8d,0x83,0x4e,0x32,0x22,0x64,0x16,0x93, +0x2d,0x6b,0x5c,0x6b,0x93,0x8b,0xc4,0x8b,0xde,0x4b,0xd4,0x8b,0xa9,0x93,0x73,0x8b, +0x9c,0x31,0x10,0x3a,0xa2,0x22,0x00,0x00,0x4a,0x91,0x39,0x29,0x41,0x8a,0x59,0x6d, +0x77,0x71,0x91,0x6a,0xa4,0x94,0xad,0x8a,0xa8,0x74,0x97,0x69,0x81,0x75,0x6c,0x69, +0x60,0x72,0x60,0x8d,0x69,0x4d,0x78,0x6d,0x9c,0x31,0x10,0x70,0x82,0x22,0x00,0x00, +0x9d,0x1b,0xc7,0x0d,0xd9,0x61,0xce,0xd4,0xaa,0xdb,0x7e,0x92,0x5d,0x23,0x49,0x24, +0x4c,0xd2,0x64,0xdb,0x7c,0xe3,0x8e,0xe4,0x96,0xdb,0x93,0x5a,0x8e,0xa3,0x88,0x9c, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_TWO.txt b/config/_default_cfg_src_/res/en/SOUND_TWO.txt new file mode 100644 index 0000000..cc51ae5 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_TWO.txt @@ -0,0 +1,165 @@ +0x9c,0x31,0x10,0x71,0x53,0x32,0x00,0x00,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb, +0x82,0x63,0x75,0xab,0x7e,0x5b,0x70,0xd3,0x63,0x59,0x7a,0x1c,0x59,0x95,0x80,0xdb, +0x51,0x91,0x5e,0x83,0x32,0x4b,0x6c,0x8a,0x9c,0x31,0x10,0xa5,0xa9,0x98,0x50,0x00, +0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x7d,0xdb,0x79,0xdb,0x7d,0xda,0x8a,0x1b,0x89,0x9a, +0xe3,0xae,0x95,0x5c,0x69,0x5a,0x5d,0xdb,0x69,0x9b,0x6d,0xdb,0x71,0xda,0x6d,0xda, +0x9c,0x31,0x10,0x17,0x86,0x78,0x50,0x00,0x45,0x35,0x41,0xba,0x2d,0x29,0x35,0xb4, +0x5a,0x26,0x71,0xba,0x85,0xaa,0x81,0x42,0x6d,0x46,0x5d,0x19,0x69,0xaa,0x76,0x4a, +0x7b,0x29,0x7e,0x35,0x75,0xb3,0x69,0xb0,0x9c,0x31,0x10,0xa3,0x86,0x78,0x40,0x00, +0x69,0x38,0x5d,0x2e,0x62,0x37,0x86,0x11,0x95,0xa8,0x99,0xca,0x82,0x67,0x6a,0x93, +0x7e,0xb7,0x71,0x9b,0x95,0x58,0x9d,0x44,0xae,0x55,0xc9,0x19,0xc5,0xba,0xa9,0xb8, +0x9c,0x31,0x10,0x7f,0x77,0x79,0x40,0x00,0xa8,0x95,0x98,0x94,0x97,0x60,0x86,0xa4, +0x86,0xdc,0x85,0x5d,0x66,0x6a,0x87,0x5a,0x48,0x91,0x65,0x15,0x96,0x70,0xea,0xa1, +0xa2,0xd5,0x55,0x9d,0x58,0x98,0x74,0xa5,0x9c,0x31,0x10,0xaf,0xa8,0x89,0x50,0x00, +0x7a,0x1c,0x6e,0x1b,0x79,0x64,0x81,0xcb,0xa5,0x62,0xe1,0xa1,0x4f,0x4b,0x45,0xeb, +0x71,0xe4,0x72,0x0d,0x71,0xa2,0x69,0x99,0x9a,0x0b,0xa8,0xa4,0x5e,0x1b,0x5d,0x62, +0x9c,0x31,0x10,0x4c,0x87,0x89,0x60,0x00,0x72,0x69,0xc3,0x71,0xa2,0x31,0xa4,0x69, +0xe4,0x2d,0xab,0x76,0x7d,0xb6,0x8b,0x62,0x66,0x49,0x9b,0x91,0x8d,0x6d,0xb4,0x2d, +0x43,0x8d,0x0a,0x8d,0x54,0x51,0x83,0xad,0x9c,0x31,0x10,0x69,0x97,0x89,0x60,0x00, +0x73,0xa9,0x7c,0x51,0xa2,0x15,0x99,0xb2,0xa4,0x8a,0x8c,0x41,0x51,0x6d,0x99,0x91, +0x9b,0x91,0x94,0x0d,0x63,0xa5,0x5a,0xa9,0x3a,0x35,0x54,0x75,0x7c,0xa9,0x84,0x49, +0x9c,0x31,0x10,0x69,0x97,0x89,0x60,0x00,0x79,0x4d,0x7c,0x69,0x42,0xb1,0x34,0x31, +0x53,0xad,0x53,0x45,0x53,0x24,0x73,0x6c,0x94,0x90,0x86,0x55,0x53,0x11,0x59,0xca, +0x5d,0x89,0x71,0x29,0xa3,0xb1,0xab,0x91,0x9c,0x31,0x10,0x54,0x87,0x99,0x60,0x00, +0x9d,0x25,0x5a,0x6d,0x73,0x6d,0x53,0x6c,0x5d,0x48,0x9b,0x6d,0xc3,0x99,0xca,0x72, +0x91,0x4e,0x73,0x86,0x73,0x65,0x04,0x4d,0x13,0x75,0x6a,0x6c,0x99,0x64,0x83,0x8c, +0x9c,0x31,0x10,0xa8,0x97,0x89,0x50,0x00,0x8d,0x5c,0x68,0x2a,0x93,0xda,0x91,0x61, +0xa3,0x73,0xb4,0x2b,0xab,0x7b,0x93,0xc3,0xa5,0x85,0xb2,0x29,0x7a,0x9c,0x6d,0xa6, +0x7c,0x93,0x84,0x54,0x53,0x36,0x23,0x9a,0x9c,0x31,0x10,0x39,0x87,0x89,0x40,0x00, +0xac,0xec,0xbb,0x18,0xc0,0x72,0xc2,0xc5,0x9b,0x49,0xeb,0x38,0x82,0xb7,0x62,0x76, +0x73,0x04,0x1d,0xc9,0x09,0x9c,0x32,0x04,0x83,0xa5,0x40,0x96,0x12,0x2a,0x72,0x78, +0x9c,0x31,0x10,0xf6,0xa6,0x99,0x40,0x00,0x85,0xc2,0x87,0x2a,0x81,0x5b,0x8d,0xbc, +0x95,0x1a,0x72,0x4c,0x54,0xc5,0x66,0x29,0x90,0xc1,0xa9,0xbd,0xa5,0x45,0x81,0x38, +0x3d,0x2b,0x01,0x45,0x2a,0xca,0xb8,0xaa,0x9c,0x31,0x10,0x94,0xc6,0x88,0x30,0x00, +0xb0,0xe4,0xb2,0xe4,0x81,0x12,0x4a,0xca,0x32,0x5c,0x57,0x25,0xae,0x9a,0xe9,0x19, +0xc0,0x1b,0x5b,0x14,0x19,0x62,0x21,0x6c,0x72,0x84,0xc4,0x52,0xec,0xe2,0xcc,0xa5, +0x9c,0x31,0x10,0x34,0xd7,0x98,0x30,0x00,0x76,0xdb,0x4c,0xda,0x43,0x53,0x6e,0x9d, +0xa2,0xe2,0xb4,0xdb,0xa6,0xd4,0x7a,0xa9,0x4e,0xe3,0x3b,0x8b,0x65,0x14,0x9f,0x2a, +0xb4,0xdb,0xa7,0x1c,0x88,0x9b,0x5f,0x94,0x9c,0x31,0x10,0x1e,0xd7,0x87,0x20,0x00, +0x39,0x38,0x55,0x0e,0x97,0x1c,0xb8,0xe9,0xaa,0xe6,0x8d,0x1d,0x67,0x91,0x3c,0x72, +0x4c,0xf1,0x8e,0x86,0xb8,0xdc,0xac,0xb1,0x90,0xd1,0x6e,0xd8,0x42,0x22,0x44,0xf5, +0x9c,0x31,0x10,0xf0,0xd8,0x88,0x20,0x00,0x80,0x8a,0xb6,0xcc,0xb2,0xab,0x94,0xd2, +0x76,0xcd,0x4c,0x49,0x40,0xed,0x74,0xea,0xae,0xc3,0xb6,0xd4,0x9a,0xeb,0x7c,0xda, +0x52,0x8c,0x3d,0x43,0x68,0xf2,0xa7,0x24,0x9c,0x31,0x10,0x80,0xd7,0x98,0x20,0x00, +0xb8,0xd2,0xa0,0xdb,0x85,0x23,0x5d,0x63,0x3b,0x93,0x5a,0xcc,0x9a,0xe9,0xb8,0xe4, +0xa7,0x13,0x8b,0x1b,0x67,0xa3,0x3e,0xac,0x4e,0xd1,0x8e,0x94,0xb8,0xe3,0xac,0xa2, +0x9c,0x31,0x10,0x5c,0xd8,0x98,0x30,0x00,0x90,0x94,0x72,0xdb,0x46,0x1a,0x42,0xed, +0x7a,0x9a,0xb2,0xd3,0xb4,0xdc,0x96,0xa2,0x7e,0xdb,0x56,0xd4,0x3d,0x41,0x62,0xec, +0xa0,0xe3,0xb8,0xd2,0xa2,0xd4,0x89,0x1b,0x9c,0x31,0x10,0x80,0xd7,0x98,0x20,0x00, +0x6b,0x62,0x3e,0xad,0x4c,0x90,0x8a,0x95,0xb6,0xe3,0xae,0xe2,0x92,0x95,0x78,0x92, +0x4e,0x12,0x3d,0x1d,0x6c,0xe9,0xa9,0x15,0xb8,0xd1,0x9e,0xdb,0x87,0x25,0x65,0x61, +0x9c,0x31,0x10,0x41,0xd7,0x98,0x10,0x00,0x3d,0x2e,0x4e,0xc8,0x8c,0xd4,0xb8,0xe4, +0xae,0xe1,0x90,0xde,0x7a,0xd1,0x50,0x54,0x3b,0x4c,0x68,0xe9,0xa8,0xdd,0xba,0xd1, +0xa0,0xd4,0x89,0x1c,0x6b,0x22,0x3e,0x9d,0x9c,0x31,0x10,0x59,0xd7,0x88,0x10,0x00, +0x46,0xa9,0x82,0x8d,0xb6,0xd1,0xb2,0xe4,0x96,0x9b,0x80,0xe2,0x5d,0x1c,0x39,0x99, +0x56,0xc6,0x98,0xe1,0xba,0xe5,0xa8,0xda,0x8e,0xdb,0x7a,0x8b,0x4c,0x1b,0x39,0x0c, +0x9c,0x31,0x10,0xed,0xd7,0x88,0x00,0x00,0x68,0xe9,0xa7,0x1d,0xb8,0xda,0xa0,0x9c, +0x8a,0xd2,0x72,0xdc,0x44,0x0a,0x3e,0xf4,0x76,0x9a,0xb1,0x1b,0xb6,0xd4,0x9c,0x9a, +0x87,0x1c,0x6b,0x22,0x3e,0xa4,0x44,0xf2,0x9c,0x31,0x10,0x42,0xd6,0x87,0x10,0x00, +0x80,0x92,0xb4,0xd8,0xb4,0xde,0x98,0x9c,0x85,0x29,0x67,0x9d,0x3c,0xea,0x46,0xa8, +0x84,0xd6,0xb6,0xd4,0xb2,0xe2,0x96,0xd9,0x82,0xe5,0x65,0x9d,0x3c,0xed,0x48,0xa0, +0x9c,0x31,0x10,0x6b,0xd7,0x87,0x00,0x00,0x86,0xd2,0xb8,0xd5,0xb3,0x1d,0x94,0xdd, +0x82,0xe1,0x67,0x5d,0x3e,0xaa,0x46,0xa8,0x84,0xde,0xb7,0x18,0xb2,0xda,0x96,0xd5, +0x84,0xdd,0x6a,0xde,0x42,0x18,0x42,0xb6,0x9c,0x31,0x10,0x59,0xd7,0x88,0x10,0x00, +0x7a,0x9b,0xb1,0x1a,0xb4,0x95,0x9a,0x91,0x88,0xe4,0x74,0xdb,0x4c,0x12,0x3c,0xc5, +0x6a,0xa0,0xa8,0xe6,0xb8,0xd9,0xa0,0xe4,0x88,0xdb,0x7a,0xda,0x58,0xdc,0x3d,0x91, +0x9c,0x31,0x10,0xdd,0xc6,0x78,0x00,0x00,0x39,0x05,0xb3,0x02,0xf2,0xa4,0xce,0xdb, +0x9a,0xe2,0x87,0x1c,0x55,0x52,0x06,0x6c,0x14,0x72,0x84,0xac,0xe7,0x1a,0xe1,0x1b, +0xa8,0xdc,0x8c,0xda,0x76,0xdb,0x2a,0xa3,0x9c,0x31,0x10,0x6c,0xd7,0x76,0x00,0x00, +0x3f,0x41,0x63,0x13,0x9f,0x0c,0xb6,0x99,0xa0,0xd5,0x8a,0xd2,0x83,0x1c,0x6b,0x13, +0x42,0x64,0x48,0x30,0x80,0x66,0xb0,0xe0,0xb0,0xdc,0x94,0x9c,0x86,0x91,0x7e,0xdc, +0x9c,0x31,0x10,0xe3,0xd7,0x77,0x00,0x00,0x5d,0x63,0x3f,0xaa,0x57,0x14,0x93,0x21, +0xb4,0xdd,0xa6,0x91,0x8c,0xe4,0x84,0xa2,0x7a,0xe3,0x54,0x9c,0x3f,0x8a,0x63,0x5b, +0x9f,0x53,0xb7,0x22,0x9f,0x1c,0x89,0x22,0x9c,0x31,0x10,0xae,0xc8,0x77,0x00,0x00, +0x8c,0xf2,0x70,0xcd,0x20,0x69,0x03,0x06,0x55,0x0c,0xc7,0x2a,0xeb,0x08,0xbd,0x0d, +0x93,0x2d,0x8b,0x31,0x69,0x0e,0x1a,0x88,0x06,0xea,0x5f,0x0c,0xcf,0x2d,0xe7,0x09, +0x9c,0x31,0x10,0x1c,0xd8,0x66,0x00,0x00,0x9b,0x11,0x88,0xea,0x84,0xf0,0x76,0xae, +0x4e,0x89,0x41,0x45,0x69,0x4d,0xa3,0x4d,0xb5,0x0d,0x9c,0xad,0x88,0xae,0x86,0xd0, +0x7c,0xee,0x57,0x11,0x3f,0x91,0x5c,0xf2,0x9c,0x31,0x10,0x11,0xc8,0x56,0x00,0x00, +0xb2,0xb1,0xec,0x95,0xc8,0x82,0x94,0xe5,0x8a,0xe2,0x87,0x24,0x4d,0x23,0x02,0xb3, +0x1c,0x43,0x8c,0xa3,0xe7,0x23,0xdb,0x4b,0xa1,0x2b,0x88,0xec,0x8e,0xcb,0x70,0xcb, +0x9c,0x31,0x10,0x9d,0xc8,0x55,0x00,0x00,0x21,0x55,0x03,0xc1,0x55,0xa8,0xc7,0x76, +0xec,0x44,0xb8,0x55,0x88,0x71,0x91,0x85,0x96,0x85,0x5b,0x95,0x03,0x40,0x0d,0x55, +0x7f,0x91,0xe3,0xa5,0xe2,0x76,0xa4,0x54,0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00, +0x88,0x55,0x94,0x75,0x84,0x75,0x3c,0xa5,0x00,0x69,0x30,0x05,0xa1,0x75,0xe7,0xb5, +0xcd,0xa4,0x97,0x55,0x8b,0x45,0x96,0x75,0x7a,0x86,0x2f,0x94,0x00,0x79,0x3d,0x15, +0x9c,0x31,0x10,0xed,0xc7,0x45,0x00,0x00,0xac,0x78,0xe6,0xa6,0xc5,0x84,0x8f,0x56, +0x8b,0x48,0x99,0x85,0x7c,0x85,0x30,0x94,0x01,0x6a,0x3e,0x35,0xac,0xa8,0xe5,0x86, +0xc3,0x54,0x8e,0x65,0x88,0x75,0x98,0x85,0x9c,0x31,0x10,0x85,0xc8,0x45,0x00,0x00, +0x83,0x75,0x3f,0x85,0x06,0x46,0x32,0x74,0x9a,0xaa,0xdf,0x55,0xcb,0x75,0x92,0x81, +0x82,0x75,0x97,0x75,0x92,0x75,0x5a,0x75,0x13,0x61,0x1a,0xb6,0x79,0x55,0xd1,0x65, +0x9c,0x31,0x10,0x0a,0xc8,0x44,0x00,0x00,0xd6,0x95,0x9e,0x54,0x7f,0x75,0x91,0x75, +0x9f,0x65,0x78,0x75,0x2e,0x85,0x08,0x69,0x4a,0x56,0xaf,0xb4,0xdd,0x46,0xb8,0x74, +0x84,0x85,0x85,0x66,0xa0,0x74,0x98,0x75,0x9c,0x31,0x10,0x62,0xc7,0x44,0x00,0x00, +0x5b,0x65,0x15,0x65,0x18,0xd6,0x73,0x04,0xcb,0xc6,0xd3,0x65,0xa0,0x55,0x7e,0x91, +0x8f,0x55,0xa3,0x85,0x86,0x75,0x43,0x75,0x0d,0x31,0x31,0xd5,0x91,0x36,0xd5,0x84, +0x9c,0x31,0x10,0xc8,0xc8,0x33,0x00,0x00,0xc4,0xc1,0x8f,0xb5,0x7a,0xc5,0x98,0x39, +0xa7,0x3d,0x7f,0xbd,0x3b,0x44,0x0c,0xa5,0x3b,0xdd,0x99,0x29,0xd5,0xc1,0xbd,0xc5, +0x8b,0x2d,0x7c,0xcd,0x9b,0x31,0xa8,0x45,0x9c,0x31,0x10,0x42,0xc8,0x34,0x00,0x00, +0x82,0x6b,0x42,0x8b,0x12,0x52,0x34,0xbb,0x8e,0x3d,0xd0,0xa1,0xc2,0x64,0x8f,0x7a, +0x78,0x83,0x96,0x74,0xac,0x82,0x90,0x6b,0x4f,0x8c,0x18,0x6a,0x22,0xa4,0x7a,0x49, +0x9c,0x31,0x10,0x2a,0xc7,0x34,0x00,0x00,0xc4,0xe5,0xca,0x15,0x97,0xd5,0x73,0x15, +0x8b,0xc9,0xb2,0x31,0xa8,0xa5,0x67,0x45,0x27,0xb4,0x10,0x19,0x59,0xc6,0xab,0x44, +0xd1,0x86,0xa7,0x75,0x7c,0x75,0x74,0x76,0x9c,0x31,0x10,0x2a,0xc7,0x34,0x00,0x00, +0xa4,0x74,0xb4,0x75,0x92,0x76,0x4c,0x78,0x1a,0x79,0x1f,0x85,0x79,0x44,0xbd,0xb6, +0xca,0x35,0x96,0xb4,0x77,0x46,0x81,0x95,0xb3,0x55,0xad,0x95,0x80,0x55,0x39,0x95, +0x9c,0x31,0x10,0xa0,0xc7,0x33,0x00,0x00,0x17,0x30,0x33,0xd5,0x90,0x06,0xc1,0xe4, +0xbd,0x16,0x87,0xc5,0x77,0x34,0x87,0x96,0xb7,0x55,0xa8,0x85,0x79,0x66,0x36,0x81, +0x1a,0x41,0x3a,0xc5,0x95,0x26,0xc0,0xb4,0x9c,0x31,0x10,0xa0,0xc7,0x33,0x00,0x00, +0xba,0x46,0x85,0x96,0x78,0x64,0x86,0x85,0xb3,0x76,0xa5,0x65,0x7e,0x85,0x3d,0x65, +0x21,0x70,0x36,0x85,0x8c,0x65,0xbb,0x74,0xbe,0x86,0x8c,0x55,0x78,0xa4,0x80,0x36, +0x9c,0x31,0x10,0xb8,0xc7,0x23,0x00,0x00,0xaa,0xc5,0xab,0x21,0x82,0xd9,0x47,0x14, +0x20,0xd9,0x2f,0x26,0x7c,0xb0,0xb7,0x36,0xbe,0xb5,0x98,0x38,0x79,0xb6,0x7f,0x31, +0x9e,0xc9,0xb1,0x36,0x8d,0xa4,0x5c,0x49,0x9c,0x31,0x10,0xb8,0xc7,0x23,0x00,0x00, +0x2b,0xb9,0x29,0x28,0x60,0xb6,0xa9,0x35,0xbe,0x95,0xa9,0x52,0x80,0x85,0x7b,0x75, +0x8d,0x66,0xaf,0x94,0x9b,0x49,0x70,0xb6,0x3c,0x45,0x25,0x91,0x46,0x75,0x90,0x75, +0x9c,0x31,0x10,0xaa,0xc6,0x22,0x00,0x00,0xba,0x69,0xb4,0x95,0x8c,0x45,0x77,0xa5, +0x80,0x21,0x9e,0xd5,0xad,0x31,0x88,0xa4,0x5b,0x56,0x2d,0x99,0x30,0x44,0x6a,0x9a, +0xa8,0x61,0xbc,0x94,0xa4,0x56,0x81,0x81,0x9c,0x31,0x10,0xaa,0xc6,0x22,0x00,0x00, +0x7b,0x74,0x8d,0x52,0xa9,0xa6,0x9b,0x34,0x74,0xb6,0x44,0x35,0x2a,0x81,0x47,0x85, +0x8a,0x72,0xb4,0x64,0xb4,0x95,0x91,0x46,0x7a,0xb4,0x80,0x15,0x9b,0xd5,0xa7,0x25, +0x9c,0x31,0x10,0x10,0xc5,0x22,0x00,0x00,0x87,0xe5,0x5c,0x06,0x33,0x69,0x36,0x04, +0x6a,0xe6,0xa4,0x91,0xb8,0xd4,0xa5,0x95,0x84,0x49,0x7c,0xb4,0x8a,0xb6,0xa3,0x45, +0x98,0x95,0x77,0x65,0x4d,0x85,0x36,0x50,0x9c,0x31,0x10,0x10,0xc5,0x22,0x00,0x00, +0x49,0x26,0x81,0xc5,0xac,0x24,0xb1,0xda,0x97,0x11,0x7f,0x54,0x80,0x86,0x94,0xd5, +0xa0,0xa5,0x8a,0xc6,0x67,0x24,0x46,0xd5,0x3f,0x96,0x5c,0x50,0x90,0xa5,0xab,0xa6, +0x9c,0x31,0x10,0xc3,0xb5,0x12,0x00,0x00,0xd0,0xa0,0x9c,0x45,0x7f,0x95,0x94,0x62, +0xb4,0x71,0xa9,0x69,0x73,0x99,0x31,0x45,0x0e,0xc5,0x17,0x01,0x6a,0xe1,0xbf,0x16, +0xd6,0xc4,0xbd,0x45,0x89,0x71,0x86,0x95,0x9c,0x31,0x10,0x4f,0xb5,0x11,0x00,0x00, +0x96,0x46,0x9b,0xa2,0x82,0x54,0x52,0x89,0x35,0x79,0x2d,0x75,0x47,0x62,0x90,0x94, +0xc4,0x35,0xcf,0xb4,0xab,0x35,0x81,0xa9,0x7b,0x54,0x77,0x86,0x71,0x85,0x55,0x56, +0x9c,0x31,0x10,0x5e,0xb4,0x12,0x00,0x00,0x3c,0xd5,0x42,0x05,0x75,0xd9,0xb8,0x41, +0xd2,0x85,0xc1,0x85,0x94,0x54,0x79,0xca,0x70,0x31,0x6b,0xb1,0x5b,0x35,0x45,0xa5, +0x45,0x55,0x67,0x95,0x9f,0x69,0xc1,0x65,0x9c,0x31,0x10,0x26,0xb3,0x11,0x00,0x00, +0xc0,0xd1,0xa1,0x14,0x83,0xd9,0x75,0x91,0x6f,0xc9,0x66,0x35,0x54,0xb5,0x4e,0x45, +0x5d,0x35,0x80,0xc9,0xa6,0xa1,0xb7,0xb5,0xb1,0xb9,0x9c,0xc4,0x86,0xb6,0x70,0xc2, +0x9c,0x31,0x10,0x2b,0xa3,0x21,0x00,0x00,0x31,0x89,0x10,0x4c,0x1c,0x6d,0x4f,0x6d, +0x95,0x6c,0xd4,0x6d,0xed,0x6d,0xe3,0xad,0xb8,0x35,0x80,0xce,0x4d,0x2d,0x28,0x8d, +0x24,0x70,0x39,0x6d,0x61,0x95,0x89,0x35,0x9c,0x31,0x10,0x9e,0xa2,0x11,0x00,0x00, +0xb6,0x46,0xd6,0x25,0xd7,0x62,0xb0,0x90,0x75,0xb1,0x4d,0xc1,0x43,0x26,0x4b,0xc9, +0x59,0xd4,0x66,0x32,0x7a,0xd5,0x96,0xa1,0xb3,0xd5,0xbd,0x21,0xaa,0x52,0x86,0xb5, +0x9c,0x31,0x10,0xd9,0x92,0x21,0x00,0x00,0x53,0x6d,0x3f,0x88,0x46,0x51,0x54,0x52, +0x5e,0x91,0x66,0x49,0x78,0xad,0x93,0x4d,0xad,0xa9,0xb3,0x4c,0xa2,0x89,0x87,0x95, +0x6e,0x6d,0x65,0x6c,0x67,0xa9,0x6b,0x6d,0x9c,0x31,0x10,0x1a,0x72,0x11,0x00,0x00, +0x42,0xa5,0x56,0xe9,0x70,0xe5,0x97,0x4d,0xb9,0x51,0xd4,0xca,0xc1,0x48,0xa2,0xe9, +0x71,0x25,0x52,0xb1,0x49,0x6a,0x5c,0xc8,0x6e,0xf0,0x76,0xad,0x7d,0x4a,0x8c,0x71, +0x9c,0x31,0x10,0x17,0x62,0x21,0x00,0x00,0xb7,0x6a,0xc8,0xb5,0xc5,0x0d,0xa7,0x08, +0x76,0x31,0x4c,0xd2,0x64,0xc8,0x76,0xf2,0x76,0x69,0x61,0x4e,0x6d,0x2d,0x96,0xed, +0x9f,0x31,0x98,0x6d,0x9b,0x0d,0xa2,0xc9,0x9c,0x31,0x10,0xdf,0x52,0x10,0x00,0x00, +0xa6,0xb1,0x56,0xf4,0x44,0xfc,0x75,0x65,0xb1,0x73,0xd4,0xd7,0xcb,0x77,0xac,0xdb, +0x76,0xcc,0x59,0x2c,0x74,0xfa,0xa8,0xf3,0xb4,0xe8,0x9c,0xf6,0x6d,0x48,0x6a,0xac, +0x9c,0x31,0x10,0xea,0x51,0x11,0x00,0x00,0x80,0xd3,0xaa,0xdc,0xce,0x11,0xbc,0x9b, +0x88,0xaa,0x50,0x94,0x47,0x6a,0x63,0x03,0x81,0x13,0x9a,0x4b,0x7d,0x5b,0x75,0x23, +0x6e,0x8b,0x99,0x74,0xb8,0xa2,0xbb,0x34,0x9c,0x31,0x10,0xcf,0x41,0x11,0x00,0x00, +0x94,0xcb,0x3f,0x32,0x0e,0xa1,0x31,0x92,0x7d,0x16,0xb6,0xab,0xa1,0x64,0x53,0x12, +0x3c,0xd1,0x7b,0x74,0xae,0xe4,0xc2,0xaa,0xa9,0xa3,0x6a,0x9b,0x28,0x73,0x42,0x0b, +0x9c,0x31,0x10,0x75,0x42,0x11,0x00,0x00,0x69,0xe6,0x9e,0x48,0x89,0xc3,0x8c,0xd2, +0x7d,0x1b,0x8e,0x23,0x9d,0xdc,0xd5,0xa1,0x96,0x4d,0x71,0xd1,0x4a,0x2c,0x5e,0x5b, +0x4a,0x24,0x76,0x22,0x82,0x5b,0x71,0x40,0x9c,0x31,0x10,0xcf,0x41,0x11,0x00,0x00, +0x6e,0xe5,0x7f,0x2d,0x8e,0x64,0xa0,0xd3,0x9e,0xd1,0x8f,0x59,0x78,0xac,0x60,0xc4, +0x67,0x25,0x61,0x13,0x66,0xdb,0x47,0x01,0x1c,0xa2,0x18,0x59,0x1c,0x05,0x30,0xe4, +0x9c,0x31,0x10,0xcf,0x41,0x11,0x00,0x00,0x42,0x81,0x44,0x4e,0x54,0x0a,0x3b,0x24, +0x2c,0x43,0x1e,0xe2,0x3b,0x0c,0x46,0xda,0x3e,0x32,0x41,0x6e,0x3f,0x29,0x4b,0x59, +0x8c,0xeb,0xaf,0xab,0x90,0xe5,0x7a,0x4b,0x9c,0x31,0x10,0x5d,0x42,0x21,0x00,0x00, +0x5d,0xd5,0x4f,0x14,0x51,0x99,0x56,0xb1,0x45,0xe1,0x21,0x54,0x12,0x62,0x19,0xe1, +0x5d,0x9d,0xa2,0x11,0xd1,0xa1,0xc2,0x18,0x81,0xe1,0x46,0x1e,0x2e,0xa1,0x3d,0x65, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_WARNING.txt b/config/_default_cfg_src_/res/en/SOUND_WARNING.txt new file mode 100644 index 0000000..0164f01 --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_WARNING.txt @@ -0,0 +1,155 @@ +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x9c,0x31,0x10,0x51,0x00,0x00,0x00,0x00, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, +0x9c,0x31,0x10,0x76,0x43,0x20,0x21,0x00,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0x7b,0x6d, +0x7b,0x6d,0x7b,0x6d,0x7b,0x6d,0xd6,0xa4,0x9c,0x31,0x10,0xea,0xcb,0x79,0x87,0x67, +0x7d,0xd5,0x85,0xd5,0x7d,0xa5,0xbe,0xa4,0x84,0x88,0x3a,0xe5,0xdd,0x15,0x0e,0x15, +0xee,0x55,0x20,0xd5,0xbf,0x15,0x68,0x55,0x6b,0x55,0xb4,0x95,0x26,0xd5,0xe5,0x55, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb, +0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2,0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24, +0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2,0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3, +0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c,0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44, +0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00,0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60, +0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71,0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa, +0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75,0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00, +0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30,0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75, +0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca,0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75, +0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00,0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30, +0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5,0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea, +0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15,0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00, +0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb,0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b, +0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35,0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb, +0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00,0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04, +0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52,0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e, +0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90,0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55, +0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21,0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9, +0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5,0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70, +0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65,0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00, +0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41,0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55, +0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba,0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50, +0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69,0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21, +0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65,0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00, +0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba,0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85, +0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50,0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75, +0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00,0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6, +0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb,0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb, +0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10,0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71, +0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51,0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95, +0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00,0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01, +0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78,0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d, +0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76,0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55, +0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a,0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba, +0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75,0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda, +0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85,0x9c,0x31,0x10,0x9c,0xc5,0x54,0x30,0x00, +0xcb,0x6d,0x92,0x2e,0x30,0x89,0x77,0xd6,0xcb,0x69,0x7b,0x28,0x34,0x51,0x8e,0x92, +0xc8,0x89,0x65,0x09,0x3a,0x72,0xa1,0x84,0xba,0xa6,0x56,0x6e,0x4a,0x4e,0xb0,0x89, +0x9c,0x31,0x10,0xd0,0xcb,0x78,0x77,0x56,0xac,0xeb,0x48,0xeb,0x56,0xcb,0xd5,0x03, +0x86,0x65,0x3b,0x6c,0xe0,0x8b,0x0d,0x0b,0xef,0x2b,0x20,0x6b,0xbf,0x8b,0x68,0x2b, +0x6b,0xab,0xb8,0x4b,0x27,0x6b,0xe8,0xab,0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00, +0x12,0x73,0xdf,0xac,0x37,0x34,0xa0,0xdb,0x85,0x19,0x54,0xd3,0xca,0x3a,0x1e,0xa2, +0xe7,0x7b,0x1e,0x5a,0xcc,0xbb,0x53,0x24,0x86,0xd4,0x9d,0x23,0x40,0xc4,0xd8,0x4c, +0x9c,0x31,0x10,0x7a,0xcb,0x65,0x20,0x00,0x1b,0x83,0xe1,0x93,0x2d,0x4c,0xb3,0xc2, +0x6d,0x29,0x6e,0xd3,0xb1,0x32,0x31,0xb3,0xdb,0x63,0x20,0x73,0xd3,0xa3,0x43,0x3c, +0x9b,0xcd,0x84,0x2b,0x58,0xcc,0xc2,0x44,0x9c,0x31,0x10,0x52,0xcb,0x55,0x20,0x00, +0x2b,0x35,0xda,0xf5,0x28,0xb5,0xbf,0x60,0x5a,0x62,0x85,0x95,0x98,0x61,0x47,0x71, +0xca,0xa5,0x29,0x05,0xd3,0x15,0x3a,0xaa,0xab,0x78,0x6e,0x65,0x6f,0x89,0xaa,0x75, +0x9c,0x31,0x10,0x37,0xcb,0x66,0x10,0x00,0x3d,0x55,0xce,0xd5,0x2c,0xe5,0xc5,0x30, +0x4c,0x91,0x97,0x75,0x82,0x61,0x5d,0x75,0xb6,0x95,0x37,0x25,0xcc,0xf5,0x38,0xca, +0xb3,0x49,0x60,0x85,0x83,0x75,0x94,0x75,0x9c,0x31,0x10,0xaa,0xca,0x66,0x10,0x00, +0x51,0xb5,0xbe,0x75,0x37,0x15,0xc3,0x30,0x46,0x65,0xa3,0xc5,0x72,0x01,0x71,0xe5, +0xa4,0x25,0x47,0x85,0xc0,0xb5,0x3c,0xea,0xb7,0x59,0x56,0x45,0x91,0xd5,0x82,0x15, +0x9c,0x31,0x10,0x4e,0xca,0x99,0x50,0x00,0x63,0x5b,0xa8,0x9b,0x42,0x9b,0xb9,0xdb, +0x45,0x5b,0xab,0x1b,0x64,0x5b,0x83,0x9b,0x90,0x5b,0x5f,0x5b,0xb5,0x1b,0x7b,0x35, +0xe4,0x2a,0x19,0xdb,0x49,0xdb,0xf9,0xdb,0x9c,0x31,0x10,0x1c,0xc7,0x65,0x30,0x00, +0x71,0x51,0x09,0x89,0xce,0x89,0xca,0x04,0x0c,0x6d,0x74,0x91,0xf7,0x6d,0x49,0x52, +0x26,0x91,0xe6,0x8d,0xa1,0x29,0x08,0x8e,0x9e,0x70,0xe2,0x71,0x2b,0x2c,0x49,0x8d, +0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00,0xf0,0x78,0x78,0x32,0x12,0x94,0xc0,0x90, +0xc6,0x61,0x19,0x59,0x6f,0xa5,0xee,0x55,0x53,0x54,0x29,0x81,0xdb,0xa6,0xa4,0x21, +0x15,0x92,0x95,0x96,0xdc,0x69,0x36,0x5a,0x9c,0x31,0x10,0x0f,0xc7,0x54,0x20,0x00, +0x49,0x99,0xe5,0x95,0x7e,0x35,0x1b,0xb9,0xb6,0x74,0xc3,0x60,0x24,0x45,0x6c,0xa5, +0xe4,0x69,0x5b,0x55,0x2d,0x81,0xcd,0x70,0xa3,0x72,0x20,0x86,0x8e,0xa5,0xd6,0x65, +0x9c,0x31,0x10,0xf5,0xc7,0x55,0x00,0x00,0x41,0x59,0x4a,0x99,0xda,0x85,0x84,0x41, +0x25,0x95,0xab,0x85,0xc0,0x69,0x2f,0x55,0x69,0xa4,0xda,0x79,0x63,0x55,0x34,0xba, +0xc1,0x64,0xa3,0x51,0x2b,0x69,0x88,0x95,0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00, +0xce,0x45,0x4a,0x35,0x4c,0x95,0xcd,0x50,0x86,0x72,0x31,0x71,0xa2,0xa5,0xba,0x69, +0x3c,0x45,0x68,0xb9,0xcf,0x85,0x6c,0x21,0x3d,0x95,0xb6,0x95,0xa2,0x45,0x35,0x65, +0x9c,0x31,0x10,0x34,0xc7,0x55,0x30,0x00,0x83,0x99,0xc6,0x69,0x54,0x55,0x4f,0xba, +0xc0,0x65,0x89,0x55,0x3a,0x81,0x9b,0x85,0xb5,0x65,0x46,0x65,0x68,0x99,0xc3,0x50, +0x71,0x71,0x45,0x85,0xac,0x85,0xa1,0x75,0x9c,0x31,0x10,0xd7,0xc9,0x88,0x40,0x00, +0x40,0xdb,0x87,0x1b,0xcb,0x13,0x9c,0xb6,0xe2,0x32,0x40,0xe3,0x14,0xdb,0xcc,0xdb, +0xdc,0xdb,0x22,0xdb,0x2c,0xdb,0xe2,0xdb,0xbe,0xdb,0x12,0xdb,0x4e,0xdb,0xf0,0xdb, +0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00,0x9e,0x56,0x07,0x71,0x71,0xa9,0xf6,0x10, +0x7b,0xa1,0x0c,0x55,0x93,0xb6,0xef,0x71,0x5b,0x45,0x15,0x69,0xb4,0xb6,0xe1,0x51, +0x3e,0xa6,0x29,0x55,0xcc,0x95,0xca,0x95,0x9c,0x31,0x10,0xf1,0xc5,0x44,0x10,0x00, +0x27,0x59,0x41,0x4c,0xe0,0x81,0xaf,0x01,0x1c,0xc4,0x60,0x4a,0xe6,0x79,0x90,0x78, +0x16,0xa9,0x7e,0x46,0xe9,0x55,0x71,0x4d,0x1b,0x82,0x9b,0xb4,0xde,0x16,0x55,0x21, +0x9c,0x31,0x10,0xdc,0xc6,0x55,0x10,0x00,0x26,0x85,0xb6,0x99,0xd0,0x55,0x3f,0x76, +0x3c,0x49,0xc7,0xa5,0xb8,0x51,0x2e,0x55,0x52,0x85,0xd7,0x95,0x9f,0x61,0x25,0x9a, +0x6e,0x34,0xda,0x91,0x84,0x75,0x23,0x79,0x9c,0x31,0x10,0x1d,0xc6,0x55,0x20,0x00, +0x88,0x65,0xda,0x95,0x69,0x69,0x2a,0xba,0xa0,0x25,0xcc,0x79,0x54,0x79,0x38,0x75, +0xb5,0x75,0xbe,0x79,0x40,0x75,0x4a,0xda,0xc2,0x38,0xa7,0x55,0x38,0x71,0x61,0x85, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/SOUND_ZERO.txt b/config/_default_cfg_src_/res/en/SOUND_ZERO.txt new file mode 100644 index 0000000..910af9f --- /dev/null +++ b/config/_default_cfg_src_/res/en/SOUND_ZERO.txt @@ -0,0 +1,215 @@ +0x9c,0x31,0x10,0x1c,0x31,0x21,0x00,0x00,0x7d,0xbb,0x7d,0xbb,0x75,0xbb,0x76,0x33, +0x3c,0x44,0x59,0x3a,0x1e,0x2b,0x2e,0x29,0x6d,0xad,0xd8,0xd5,0x90,0xb3,0xa1,0x3a, +0xb9,0x9c,0xfa,0x41,0xae,0x2a,0x06,0x3b,0x9c,0x31,0x10,0xb4,0x73,0x33,0x00,0x00, +0x7c,0xdb,0x7e,0xd2,0x7e,0x9b,0x76,0xd3,0x78,0xdb,0x7e,0x9b,0x7a,0xdb,0x78,0xdb, +0x7e,0xdb,0x84,0xe4,0x7e,0xdb,0x84,0xd2,0x94,0x5c,0xbc,0x83,0xec,0x8a,0xdc,0xcd, +0x9c,0x31,0x10,0xf5,0x83,0x32,0x00,0x00,0x7a,0x89,0x4a,0x52,0x30,0x5e,0x2a,0xe3, +0x4a,0xa3,0x84,0xec,0xb2,0xe1,0xb8,0xe2,0xa3,0x1c,0x7f,0x1a,0x65,0x1b,0x64,0xdc, +0x7e,0xd1,0xa3,0x14,0xb4,0xdc,0xac,0xd2,0x9c,0x31,0x10,0x95,0x72,0x10,0x00,0x00, +0x9d,0x31,0x4d,0x76,0x1f,0x6c,0x2e,0x9d,0x72,0xc4,0xb9,0x72,0xcf,0x84,0xaf,0xd3, +0x75,0x82,0x42,0x7a,0x38,0x9b,0x53,0x4a,0x8d,0x83,0xb8,0x8a,0xb8,0x6d,0x94,0x72, +0x9c,0x31,0x10,0xad,0x61,0x21,0x00,0x00,0x3e,0xa1,0x08,0xe5,0x1a,0x5d,0x74,0xde, +0xda,0xe1,0xf8,0xd4,0xca,0xe4,0x7a,0xe1,0x42,0xea,0x3e,0xd9,0x5e,0xd5,0x92,0x9d, +0xc0,0x19,0xc6,0xe1,0x94,0xde,0x52,0xcc,0x9c,0x31,0x10,0xc2,0x51,0x21,0x00,0x00, +0x13,0x33,0x51,0x2b,0xaa,0x39,0xba,0x55,0x91,0x32,0x66,0x2a,0x30,0x2b,0x39,0xcb, +0x7d,0x46,0x90,0xc3,0x75,0xab,0x52,0x93,0x22,0x40,0x42,0xed,0x61,0x33,0x95,0xc0, +0x9c,0x31,0x10,0x88,0x71,0x21,0x00,0x00,0x8f,0x62,0x85,0x19,0x6b,0x1d,0x58,0x21, +0x5f,0x50,0x7e,0x55,0xa4,0xdd,0xaa,0x59,0x86,0x50,0x56,0x66,0x2e,0xed,0x42,0x61, +0x84,0x16,0xc1,0x9c,0xce,0xa2,0xa6,0xd9,0x9c,0x31,0x10,0xf1,0x92,0x11,0x00,0x00, +0x73,0x65,0x60,0x51,0x63,0x74,0x80,0x59,0xa1,0x84,0xad,0xa5,0x99,0x81,0x6c,0x95, +0x3f,0x95,0x3a,0x8a,0x6e,0x61,0xba,0x54,0xe1,0x99,0xc8,0xba,0x7b,0xa8,0x1e,0xd8, +0x9c,0x31,0x10,0x26,0xb4,0x42,0x00,0x00,0x5c,0x8d,0x6c,0x6d,0x8e,0x6e,0xa7,0x6d, +0xa8,0x8d,0x8f,0x8d,0x67,0x91,0x47,0x8d,0x49,0x8c,0x70,0x8e,0xa5,0x6d,0xcb,0xae, +0xc5,0x6c,0x92,0x6a,0x50,0x65,0x24,0x64,0x9c,0x31,0x10,0x23,0xb4,0x44,0x00,0x00, +0x2d,0x4b,0x62,0x93,0xa9,0x12,0xe0,0xcd,0xe7,0x11,0xae,0xd3,0x59,0x1d,0x18,0xe1, +0x0e,0xeb,0x3e,0xe4,0x8d,0x21,0xd3,0xa4,0xf7,0x4c,0xe1,0x49,0x92,0xcc,0x39,0x83, +0x9c,0x31,0x10,0xa9,0xb4,0x43,0x00,0x00,0x06,0xa1,0x13,0xa2,0x52,0x61,0xa1,0x45, +0xe0,0x89,0xf7,0x69,0xd8,0x8c,0x87,0x32,0x2f,0x80,0x04,0xa9,0x17,0xa6,0x57,0x64, +0xa5,0x6a,0xe4,0x89,0xf9,0x69,0xda,0x8d,0x9c,0x31,0x10,0xd7,0xc5,0x53,0x00,0x00, +0x81,0x4e,0x53,0x44,0x3e,0x68,0x49,0x4a,0x6b,0x69,0x95,0x4e,0xb5,0x8d,0xbf,0x88, +0xad,0x8d,0x7f,0x4a,0x50,0x25,0x3a,0x6c,0x47,0x4a,0x6c,0x68,0x98,0x31,0xb9,0x89, +0x9c,0x31,0x10,0xd7,0xc5,0x53,0x00,0x00,0xc1,0x89,0xad,0x69,0x7b,0x45,0x4c,0x21, +0x39,0x64,0x48,0x4a,0x6f,0x69,0x9b,0x0d,0xbc,0x25,0xc3,0x8c,0xab,0x51,0x77,0x66, +0x49,0x2a,0x38,0x4c,0x49,0x32,0x71,0x6c,0x9c,0x31,0x10,0x68,0xc6,0x55,0x00,0x00, +0x9e,0x45,0xbf,0x31,0xc4,0x65,0xa8,0x65,0x71,0x75,0x44,0x35,0x37,0x55,0x4b,0x55, +0x75,0x65,0xa1,0x41,0xc1,0x12,0xc3,0x64,0xa5,0x49,0x6c,0x65,0x40,0x35,0x36,0x55, +0x9c,0x31,0x10,0x40,0xc6,0x65,0x00,0x00,0x4f,0x71,0x7d,0x71,0xab,0x6d,0xc6,0x11, +0xc0,0x55,0x9a,0x75,0x5f,0x71,0x39,0x4c,0x37,0x51,0x59,0x6d,0x88,0x6d,0xb3,0xd1, +0xca,0x19,0xb9,0x72,0x8a,0x51,0x4d,0xb5,0x9c,0x31,0x10,0x54,0xc8,0x76,0x20,0x00, +0x30,0xf0,0x3c,0xcd,0x6b,0x0d,0x9c,0xcd,0xc3,0x52,0xc8,0xe9,0xa9,0x60,0x66,0xc9, +0x32,0xe5,0x2a,0xf1,0x4c,0xac,0x88,0xe9,0xbe,0xc5,0xde,0xf2,0xbc,0x78,0x70,0xfa, +0x9c,0x31,0x10,0xf0,0xd8,0x88,0x20,0x00,0x4f,0x13,0x48,0xda,0x5e,0xe4,0x86,0xdb, +0xa6,0xd2,0xb8,0x9c,0xa2,0x9c,0x6e,0xea,0x37,0x2c,0x38,0xe1,0x6d,0x1b,0xa8,0xd5, +0xc9,0xa3,0xc6,0x99,0x8b,0x55,0x3e,0x0c,0x9c,0x31,0x10,0xfb,0xd8,0xa9,0x30,0x00, +0x22,0x2b,0x55,0xbb,0xa1,0xc4,0xcc,0xba,0xcd,0x43,0x95,0x3c,0x40,0xba,0x1b,0x2a, +0x51,0xa6,0xa9,0xaa,0xd0,0x39,0xc8,0xce,0x8c,0xcb,0x38,0x41,0x17,0x13,0x61,0x95, +0x9c,0x31,0x10,0x66,0xd9,0xa9,0x30,0x00,0xbd,0xb2,0xd1,0x49,0xb1,0x55,0x71,0xc3, +0x20,0x19,0x1d,0x8d,0x85,0x41,0xd5,0xda,0xca,0x55,0x95,0x3a,0x56,0xa2,0x14,0xa4, +0x3d,0x6a,0xa9,0xdc,0xd1,0xbb,0xae,0x22,0x9c,0x31,0x10,0xdc,0xda,0xa9,0x30,0x00, +0x85,0x99,0x4a,0x5d,0x16,0x71,0x59,0xd9,0xc2,0x0c,0xc9,0x99,0x9e,0x21,0x71,0x99, +0x31,0x21,0x26,0x48,0x8d,0x95,0xd1,0xe6,0xb1,0xa5,0x89,0xd9,0x66,0x5d,0x24,0xd4, +0x9c,0x31,0x10,0xd2,0xd9,0xa9,0x20,0x00,0x3d,0xd5,0xad,0x53,0xcd,0x3a,0xa2,0x2c, +0x7d,0x43,0x4f,0x32,0x22,0xd5,0x71,0xb2,0xca,0x21,0xb9,0x36,0x92,0x3a,0x71,0x39, +0x30,0x4e,0x32,0x99,0xa1,0xa9,0xcd,0xc6,0x9c,0x31,0x10,0xea,0xd9,0xaa,0x30,0x00, +0x9d,0x43,0x89,0xc2,0x63,0x44,0x20,0xab,0x59,0xda,0xc5,0xc5,0xb9,0xba,0x8e,0xba, +0x78,0xb4,0x41,0x3b,0x2f,0x39,0x9a,0x1d,0xca,0x23,0x99,0x3a,0x89,0xb4,0x6b,0x4c, +0x9c,0x31,0x10,0x53,0xda,0x9a,0x40,0x00,0x20,0xd1,0x5e,0x35,0xc5,0xb3,0xb2,0x1a, +0x8a,0x1c,0x85,0x63,0x46,0x1b,0x26,0xe3,0x9a,0x4c,0xce,0x02,0x95,0x9b,0x8a,0x4b, +0x6a,0x9c,0x20,0x92,0x61,0x6c,0xc9,0x33,0x9c,0x31,0x10,0x53,0xda,0xa8,0x30,0x00, +0xa9,0xe8,0x8e,0x26,0x85,0x60,0x3d,0xde,0x2f,0x1c,0xaa,0x4a,0xbe,0x11,0x8d,0x91, +0x92,0x11,0x66,0xdd,0x19,0x15,0x71,0x2d,0xc9,0x29,0xa1,0xe5,0x8a,0x29,0x85,0x20, +0x9c,0x31,0x10,0x78,0xda,0xa8,0x40,0x00,0x30,0xe2,0x3a,0xd0,0xb6,0x4d,0xba,0x51, +0x8d,0x91,0x89,0xda,0x57,0x1d,0x26,0xa9,0x8d,0xed,0xc5,0xa5,0x99,0xe8,0x8e,0xa1, +0x71,0xdd,0x24,0x55,0x5d,0x51,0xbd,0x59,0x9c,0x31,0x10,0xfd,0xda,0x97,0x30,0x00, +0xac,0xe9,0x8c,0xa8,0x84,0x8d,0x40,0xd1,0x39,0x8d,0xab,0x49,0xbf,0x0d,0x92,0xce, +0x89,0x4d,0x5d,0x45,0x24,0xf1,0x84,0x95,0xc4,0x71,0xa2,0xd0,0x89,0x11,0x72,0xb1, +0x9c,0x31,0x10,0xfd,0xda,0x97,0x30,0x00,0x2c,0x05,0x5e,0xa5,0xb8,0xcd,0xaf,0x25, +0x8e,0xc9,0x7e,0xed,0x41,0x16,0x41,0xcd,0xa5,0x4d,0xbb,0x30,0x96,0xb1,0x83,0x11, +0x56,0xed,0x30,0xf6,0x88,0x75,0xba,0x6a,0x9c,0x31,0x10,0x31,0xd9,0x95,0x10,0x00, +0xa4,0x27,0x88,0x77,0x68,0x73,0x30,0x11,0x70,0x35,0xb6,0x55,0xae,0xe4,0x8c,0xb4, +0x74,0xb8,0x39,0x38,0x55,0xe2,0xaa,0xc6,0xb5,0xda,0x96,0x47,0x7d,0x66,0x48,0x1a, +0x9c,0x31,0x10,0x8b,0xda,0x95,0x10,0x00,0x43,0x8b,0x99,0x15,0xb6,0xf6,0x9e,0xab, +0x80,0xe8,0x59,0x04,0x39,0x78,0x84,0xcc,0xb2,0x86,0xa8,0xb6,0x86,0xfa,0x67,0x69, +0x36,0xe4,0x6e,0x86,0xac,0xa9,0xaf,0x16,0x9c,0x31,0x10,0xa8,0xda,0x84,0x00,0x00, +0x91,0x14,0x71,0x3a,0x3a,0x69,0x5c,0xf1,0xa5,0x24,0xb3,0x5b,0x98,0xd6,0x78,0xe3, +0x44,0x6a,0x4d,0x68,0x99,0x43,0xb5,0x26,0xa0,0xaa,0x7e,0xc5,0x4c,0xd5,0x3f,0xbb, +0x9c,0x31,0x10,0xa8,0xda,0x84,0x00,0x00,0x8b,0x19,0xb4,0xa4,0xa6,0x97,0x85,0x1a, +0x5d,0x56,0x3b,0x56,0x78,0x8c,0xae,0x98,0xb1,0x25,0x8d,0x48,0x65,0x49,0x38,0x76, +0x6a,0x57,0xa9,0x19,0xb3,0x97,0x94,0xf6,0x9c,0x31,0x10,0x20,0xda,0x74,0x00,0x00, +0x70,0x54,0x3e,0x13,0x59,0xb0,0x9f,0xca,0xb7,0x7d,0xa0,0x22,0x77,0x79,0x44,0x84, +0x4b,0xd4,0x91,0x68,0xb5,0x42,0xa8,0x75,0x80,0xaa,0x4f,0x7a,0x40,0x9e,0x82,0x3c, +0x9c,0x31,0x10,0xa4,0xd9,0x73,0x10,0x00,0xb2,0x71,0xb0,0xcb,0x8a,0x95,0x5c,0x62, +0x39,0x72,0x71,0x25,0xaa,0xbc,0xb6,0xaa,0x96,0x34,0x68,0x9c,0x3a,0x22,0x5f,0x93, +0x9f,0xc4,0xb9,0x53,0xa2,0x42,0x75,0xcb,0x9c,0x31,0x10,0x08,0xd9,0x63,0x00,0x00, +0x40,0x1c,0x4c,0xe0,0x8f,0x71,0xb7,0x3c,0xae,0x9b,0x81,0x92,0x4e,0x4c,0x3f,0xe5, +0x7d,0x12,0xaf,0x93,0xb5,0xac,0x8f,0x43,0x60,0xba,0x37,0x63,0x68,0x35,0xa1,0xdb, +0x9c,0x31,0x10,0x9a,0xda,0x53,0x00,0x00,0xba,0x69,0xa0,0x6e,0x6f,0xa9,0x3e,0x2c, +0x52,0xc8,0x90,0x6a,0xb8,0x61,0xad,0xa8,0x82,0x65,0x4f,0x76,0x3d,0xb6,0x7a,0x35, +0xae,0xad,0xb9,0x76,0x95,0x65,0x63,0xb1,0x9c,0x31,0x10,0x9a,0xda,0x53,0x00,0x00, +0x37,0x39,0x60,0xa2,0x9a,0x89,0xbe,0x50,0xa8,0xa5,0x79,0x69,0x48,0x66,0x40,0xc0, +0x7f,0x2c,0xb3,0xba,0xb9,0x69,0x92,0x68,0x5f,0xb5,0x37,0x3d,0x62,0xa6,0x9a,0x7d, +0x9c,0x31,0x10,0x20,0xd9,0x53,0x00,0x00,0xbe,0x43,0xa6,0xcc,0x7a,0x3c,0x4b,0x85, +0x3f,0xba,0x7d,0x0a,0xaf,0xf5,0xb9,0x2b,0x94,0x93,0x68,0xb4,0x3d,0x01,0x57,0xf2, +0x90,0x2c,0xba,0x92,0xab,0x91,0x85,0x3c,0x9c,0x31,0x10,0x94,0xd9,0x53,0x10,0x00, +0x5b,0xcb,0x3d,0x4d,0x6a,0x7b,0x9a,0xaa,0xba,0x34,0xa2,0xcc,0x7a,0x44,0x53,0x7d, +0x43,0xbb,0x75,0x19,0xa3,0xe4,0xb6,0x2c,0x99,0xab,0x75,0x84,0x50,0x33,0x49,0xf1, +0x9c,0x31,0x10,0xa7,0xca,0x43,0x00,0x00,0x73,0x41,0xd0,0xb1,0xe7,0x60,0xb1,0x7d, +0x67,0x98,0x1d,0x48,0x17,0xbc,0x73,0x46,0xd2,0xa5,0xe4,0x71,0xb3,0x6d,0x6f,0xa9, +0x22,0x41,0x13,0xb8,0x66,0x4e,0xcb,0x95,0x9c,0x31,0x10,0x05,0xc9,0x53,0x00,0x00, +0xe6,0x7a,0xba,0x4b,0x7f,0xd3,0x30,0x15,0x06,0xcb,0x4f,0x3a,0xba,0xa4,0xed,0x7b, +0xc5,0x5a,0x8d,0xac,0x49,0x4a,0x00,0x9d,0x35,0x63,0x9b,0x89,0xec,0x6b,0xd7,0x83, +0x9c,0x31,0x10,0x95,0xd8,0x63,0x00,0x00,0x8f,0x63,0x75,0x9b,0x45,0x51,0x47,0xc3, +0x78,0x44,0xad,0x92,0xb5,0xa3,0x98,0x2c,0x86,0xbb,0x5f,0x5b,0x3a,0x5d,0x58,0x83, +0x92,0x8a,0xbb,0x44,0xab,0xb2,0x90,0x63,0x9c,0x31,0x10,0x82,0xd9,0x64,0x00,0x00, +0x7d,0x10,0x4a,0xd6,0x37,0x29,0x68,0x8d,0xa9,0x55,0xbc,0xc5,0x9e,0xcd,0x8d,0x51, +0x78,0xa9,0x3e,0xd1,0x33,0x85,0x76,0x4d,0xb9,0x31,0xbd,0x09,0x9a,0x8d,0x8b,0x11, +0x9c,0x31,0x10,0x9a,0xd9,0x74,0x00,0x00,0x73,0x0d,0x32,0x91,0x2f,0x69,0x82,0x8d, +0xc4,0xf1,0xb9,0x2a,0x8e,0xb2,0x8b,0x0c,0x7e,0xed,0x34,0xf5,0x1f,0x48,0x80,0x2e, +0xcd,0x55,0xbb,0x09,0x86,0xb1,0x8d,0x0c,0x9c,0x31,0x10,0x1b,0xda,0x75,0x10,0x00, +0x92,0x7a,0x45,0x7b,0x09,0x5a,0x69,0x8c,0xd0,0x92,0xc0,0x63,0x81,0x73,0x8a,0x83, +0xab,0x83,0x6b,0x73,0x09,0x7d,0x2f,0xb1,0xbc,0x34,0xd0,0x73,0x89,0xab,0x7d,0x7c, +0x9c,0x31,0x10,0xaf,0xda,0x75,0x00,0x00,0xb3,0x6a,0x9c,0x73,0x38,0x92,0x06,0x41, +0x71,0xbb,0xce,0x8b,0xa2,0x52,0x79,0x64,0x9e,0x9a,0xbc,0x9c,0x7d,0x59,0x2e,0x74, +0x1b,0x40,0x7f,0xbc,0xbd,0x92,0x93,0x5b,0x9c,0x31,0x10,0xab,0xda,0x86,0x00,0x00, +0x82,0xac,0xa5,0x0d,0xb9,0x31,0x80,0xc9,0x3c,0xd1,0x1c,0x88,0x67,0xce,0xb2,0xec, +0x96,0x6e,0x82,0xcc,0xa3,0x4e,0xb4,0xec,0x92,0x8e,0x54,0xec,0x29,0x6e,0x37,0x34, +0x9c,0x31,0x10,0x36,0xdb,0x86,0x00,0x00,0xa2,0x6a,0xa8,0xd0,0x83,0x4a,0x93,0x11, +0xb4,0xad,0xa8,0xf5,0x75,0x05,0x45,0x11,0x1c,0x65,0x65,0x52,0xb7,0x2c,0x8e,0xd2, +0x7e,0x88,0xa9,0x0e,0xb1,0x30,0x93,0x0d,0x9c,0x31,0x10,0x36,0xdb,0x86,0x00,0x00, +0x6c,0xce,0x40,0xf0,0x1a,0x81,0x87,0x11,0xb5,0x49,0x7b,0x11,0x8a,0xa9,0xb6,0xb1, +0xa0,0xee,0x8d,0x48,0x73,0x0e,0x39,0x08,0x18,0x4a,0x9c,0xac,0xad,0x4a,0x6b,0x6c, +0x9c,0x31,0x10,0x82,0xdb,0x86,0x10,0x00,0x96,0xee,0xbe,0x8c,0x90,0xb1,0x91,0x50, +0x83,0x0e,0x39,0x10,0x12,0x21,0x97,0x0d,0xab,0x68,0x65,0x4d,0x9c,0xad,0xba,0x70, +0x86,0xc9,0x97,0x71,0x94,0xec,0x42,0xf2,0x9c,0x31,0x10,0x0d,0xdb,0x87,0x10,0x00, +0x14,0x75,0x77,0x88,0xaf,0x15,0x68,0xcd,0x94,0x91,0xb6,0xaa,0x89,0x2c,0x95,0x25, +0xa2,0xed,0x5a,0xed,0x2e,0xe9,0x40,0xce,0xa6,0x8c,0x80,0xca,0x7d,0x28,0xad,0x2e, +0x9c,0x31,0x10,0xcc,0xdb,0x87,0x20,0x00,0x96,0xed,0x8e,0xcd,0xa4,0xcd,0x80,0xd1, +0x4d,0x0e,0x2c,0xd9,0x65,0x95,0xaa,0xd6,0x70,0xb0,0x8e,0x92,0xac,0xcd,0x8d,0x2d, +0x97,0x0d,0xa1,0x15,0x6c,0xed,0x46,0xf5,0x9c,0x31,0x10,0xcc,0xdb,0x87,0x20,0x00, +0x2c,0x69,0x87,0x4a,0x9d,0x2c,0x6d,0x32,0x9e,0xcc,0xa4,0xb1,0x86,0xe9,0x9c,0xed, +0x9b,0x09,0x63,0x0c,0x43,0x0e,0x32,0x60,0x94,0xea,0x93,0x24,0x71,0x4d,0xa3,0x0d, +0x9c,0x31,0x10,0x0d,0xdb,0x87,0x10,0x00,0x9c,0xb0,0x88,0xce,0xa0,0xec,0x95,0x0e, +0x63,0x09,0x49,0x0d,0x30,0x61,0x94,0xe9,0x97,0x25,0x6f,0x4c,0xa1,0x0e,0x9e,0xb0, +0x86,0xae,0xa0,0xed,0x97,0x09,0x67,0x09,0x9c,0x31,0x10,0xcc,0xdb,0x87,0x20,0x00, +0x4b,0x2d,0x2c,0x84,0x89,0x2a,0x9d,0x0c,0x6d,0x2e,0x98,0xec,0xa4,0xb2,0x84,0xed, +0x9b,0x0d,0x9d,0x0d,0x74,0xed,0x52,0xed,0x32,0x95,0x69,0x90,0xac,0xf2,0x72,0xb0, +0x9c,0x31,0x10,0x7a,0xca,0x78,0x20,0x00,0x94,0x54,0xd2,0xa3,0x95,0x4b,0xa9,0x4b, +0xc0,0xf2,0x80,0x8b,0x3a,0xcb,0x02,0xe3,0x05,0x14,0xd0,0x29,0x8e,0x8d,0x69,0x42, +0xcd,0x6c,0xad,0x03,0x8e,0xb3,0xc0,0x8c,0x9c,0x31,0x10,0x4a,0xdb,0x88,0x20,0x00, +0x8e,0x22,0x69,0xdc,0x52,0x19,0x31,0x24,0x76,0xcb,0xa6,0x2a,0x6d,0xd5,0x89,0x61, +0xa5,0x5d,0x86,0x19,0x92,0x5c,0xa1,0xda,0x81,0xa3,0x61,0x93,0x4a,0x1b,0x35,0x43, +0x9c,0x31,0x10,0xf2,0xca,0x88,0x20,0x00,0xb9,0xa2,0xa6,0x4c,0x56,0xd9,0xb6,0x1d, +0xc1,0x19,0x81,0x5c,0xb2,0x12,0xb2,0x1b,0x75,0x9b,0x39,0x9b,0x05,0xd3,0x12,0xec, +0xd0,0x53,0x88,0xe3,0x62,0x53,0xc6,0xda,0x9c,0x31,0x10,0xe5,0xda,0x87,0x30,0x00, +0x98,0xee,0x82,0x8c,0x9c,0xae,0x97,0x2c,0x6f,0x2d,0x59,0x0d,0x38,0x79,0x63,0xcc, +0xac,0xb2,0x7a,0x8c,0x78,0xd1,0xa5,0x29,0x93,0x31,0x84,0xcd,0x9c,0xac,0x90,0xea, +0x9c,0x31,0x10,0x6d,0xda,0x77,0x30,0x00,0x6b,0x24,0x55,0x36,0x36,0x45,0x75,0xd1, +0xa7,0x19,0x76,0xa6,0x7e,0xa5,0xa5,0x26,0x93,0x44,0x86,0xe5,0x9c,0xa4,0x8e,0xe5, +0x67,0x05,0x55,0x45,0x3a,0x35,0x79,0xc2,0x9c,0x31,0x10,0x75,0xda,0x67,0x30,0x00, +0xa5,0x38,0x7a,0x92,0x7e,0x94,0xa1,0x46,0x91,0x34,0x86,0xca,0x9a,0xa0,0x8f,0x29, +0x67,0x11,0x53,0x18,0x3c,0x31,0x7b,0xd1,0xa3,0x39,0x7c,0x76,0x7c,0xd4,0x9f,0x56, +0x9c,0x31,0x10,0xe2,0xda,0x76,0x30,0x00,0x96,0xf4,0x88,0xb6,0x95,0x04,0x91,0x15, +0x6a,0xd5,0x51,0x14,0x3e,0x86,0x79,0xc1,0xa2,0xd5,0x80,0x86,0x79,0x24,0x9b,0x36, +0x9a,0xb4,0x88,0xf6,0x91,0x24,0x92,0xd6,0x9c,0x31,0x10,0xfa,0xda,0x66,0x30,0x00, +0x72,0xd4,0x51,0x35,0x3c,0x9a,0x73,0xb0,0xa6,0x9a,0x84,0xb1,0x77,0x49,0x92,0xf6, +0x9e,0xc8,0x8b,0x26,0x8a,0xf4,0x94,0xc6,0x79,0x14,0x55,0x16,0x3e,0xba,0x63,0x94, +0x9c,0x31,0x10,0xfc,0xca,0x77,0x20,0x00,0xcc,0x56,0x9f,0x04,0x65,0x46,0x96,0xa4, +0xc3,0x05,0x9b,0x25,0x8c,0xc5,0xa9,0x05,0x8b,0x15,0x3c,0xc5,0x09,0x24,0x25,0x09, +0xbe,0x55,0xb3,0x89,0x6a,0xc5,0x7e,0xc5,0x9c,0x31,0x10,0xe4,0xca,0x67,0x20,0x00, +0xbd,0x56,0xaa,0xb5,0x8a,0xf5,0x9d,0x35,0x9a,0xc5,0x54,0xe5,0x17,0x45,0x06,0x51, +0x9b,0x49,0xc3,0x32,0x82,0x78,0x6b,0x66,0xa6,0xd4,0xc0,0xc6,0x95,0x41,0x90,0xb9, +0x9c,0x31,0x10,0xc1,0xda,0x67,0x20,0x00,0x8d,0x01,0x77,0x05,0x52,0xf5,0x3a,0xb4, +0x75,0x92,0xa4,0x74,0x91,0x16,0x71,0x24,0x86,0x99,0xa1,0x41,0x92,0xd5,0x84,0xd5, +0x87,0x35,0x80,0xb5,0x61,0x15,0x3e,0xea,0x9c,0x31,0x10,0x10,0xc9,0x66,0x10,0x00, +0x39,0x48,0xc6,0x36,0xc1,0x88,0x6a,0x95,0x6f,0x05,0xb5,0x30,0xbe,0x6a,0x93,0x4c, +0x80,0xce,0x8a,0xcd,0x5b,0x11,0x14,0xc9,0x10,0xf9,0xa6,0xa5,0xd1,0x71,0x8c,0x6a, +0x9c,0x31,0x10,0xa5,0xc8,0x56,0x10,0x00,0x63,0xd1,0x98,0x8d,0xc8,0xc9,0xa9,0x8c, +0x80,0x22,0x7f,0x8b,0x6a,0x64,0x2f,0x6a,0x00,0x04,0x77,0xb1,0xce,0xc5,0xb4,0x89, +0x67,0xac,0x7a,0x0a,0xbb,0xab,0xc2,0xa3,0x9c,0x31,0x10,0x8c,0xc9,0x56,0x00,0x00, +0x8e,0xcb,0x73,0x24,0x6e,0x8a,0x49,0x4c,0x04,0x61,0x47,0x8d,0xbc,0x69,0xcf,0x4c, +0x7e,0xcb,0x6a,0xd3,0x9d,0x2c,0xca,0x8a,0xa5,0x2c,0x74,0xca,0x68,0xeb,0x4f,0x0b, +0x9c,0x31,0x10,0x00,0xc9,0x55,0x00,0x00,0x1c,0x59,0x2f,0xc1,0xa4,0x19,0xd0,0xd2, +0x9a,0x34,0x6c,0xa6,0x86,0x64,0xc3,0x75,0xb7,0x85,0x85,0x55,0x65,0x96,0x51,0x54, +0x2c,0x8a,0x20,0x74,0x8b,0x56,0xc4,0xa4,0x9c,0x31,0x10,0x00,0xc9,0x55,0x00,0x00, +0xb4,0x36,0x75,0xb4,0x7e,0x35,0xb2,0xa5,0xbf,0x55,0x93,0x86,0x69,0x74,0x54,0x65, +0x34,0x90,0x1e,0x4a,0x72,0x91,0xb8,0x69,0xbf,0x72,0x7f,0x84,0x78,0x56,0x9f,0x94, +0x9c,0x31,0x10,0x85,0xc8,0x45,0x00,0x00,0xc2,0x36,0xa2,0xa1,0x75,0x59,0x57,0x85, +0x3e,0x95,0x22,0x21,0x5e,0xe8,0xad,0x12,0xc3,0xc4,0x8d,0x46,0x74,0x84,0x8c,0x85, +0xb9,0x61,0xaa,0x95,0x81,0x51,0x5e,0x84,0x9c,0x31,0x10,0x9d,0xc8,0x55,0x00,0x00, +0x49,0x76,0x2b,0x40,0x4a,0xd6,0x9c,0x00,0xbe,0xd5,0x9b,0x25,0x75,0xb5,0x80,0x55, +0xac,0x84,0xb0,0x76,0x90,0x64,0x69,0x86,0x53,0x65,0x37,0x89,0x3d,0x94,0x89,0x39, +0x9c,0x31,0x10,0x0a,0xc8,0x44,0x00,0x00,0xb4,0xc1,0xa9,0x28,0x7d,0xc6,0x7a,0x38, +0x9a,0x92,0xab,0x64,0x98,0x75,0x77,0x85,0x5e,0x55,0x49,0xa1,0x39,0x39,0x70,0x91, +0xa1,0x79,0xad,0x56,0x87,0xa4,0x78,0x36,0x9c,0x31,0x10,0xb9,0xb8,0x34,0x00,0x00, +0x8f,0x74,0xac,0x71,0xb5,0x61,0x8e,0xc4,0x76,0xe6,0x47,0x34,0x2c,0xaa,0x31,0x54, +0x78,0x89,0xad,0x55,0xb2,0xa9,0x9d,0x25,0x9e,0xf4,0xb0,0xe6,0x93,0x14,0x40,0xd9, +0x9c,0x31,0x10,0x42,0xc8,0x34,0x00,0x00,0x39,0x85,0x4e,0xa8,0x95,0x2e,0xab,0xd2, +0x93,0x33,0x82,0xa4,0x89,0x79,0x87,0x64,0x70,0xa2,0x71,0x53,0x8b,0x94,0x96,0x72, +0x86,0x74,0x76,0x8b,0x77,0x6b,0x7a,0x83,0x9c,0x31,0x10,0x94,0x96,0x23,0x00,0x00, +0x41,0x05,0x70,0xa6,0xc9,0x71,0xce,0x75,0x6f,0x41,0x22,0xf9,0x46,0xc5,0x87,0x45, +0xa0,0xb5,0xa1,0x15,0x9b,0x05,0x80,0xb1,0x51,0x25,0x4c,0xe9,0x76,0xf1,0x9b,0x05, +0x9c,0x31,0x10,0xd7,0x74,0x22,0x00,0x00,0xe9,0x9c,0xa5,0x6b,0x7f,0x1c,0x64,0xdb, +0x46,0x9b,0x4d,0xd3,0x91,0x0a,0xc2,0xdb,0x85,0x53,0x4a,0x24,0x45,0xa4,0x71,0xdb, +0x7e,0x2b,0x7d,0x91,0x71,0xdb,0x81,0xca,0x9c,0x31,0x10,0xcd,0x53,0x11,0x00,0x00, +0x96,0x23,0xa5,0x92,0x85,0xa4,0xa6,0xac,0x84,0xd4,0x4e,0xdc,0x68,0x9b,0x8e,0x54, +0x7d,0x99,0x71,0xa3,0x62,0x31,0x9d,0x5d,0xc6,0x93,0xc1,0xa3,0x96,0x24,0x89,0x94, +0x9c,0x31,0x10,0xcd,0x53,0x11,0x00,0x00,0x95,0xd2,0x56,0x1b,0x75,0x1c,0xb3,0x12, +0xbc,0xda,0x62,0x4d,0x09,0x2b,0x69,0x9c,0xde,0x52,0xf5,0x62,0xbd,0x54,0x89,0xd4, +0x9a,0x92,0x49,0x03,0x46,0x1d,0x7e,0x53,0x9c,0x31,0x10,0xcd,0x53,0x11,0x00,0x00, +0xb5,0x2a,0x96,0xe9,0x35,0x24,0x4e,0x51,0x92,0xaa,0x9d,0x1c,0x8e,0xe4,0x95,0x22, +0xca,0x8b,0x91,0x6b,0x5d,0x8b,0x59,0xda,0x81,0xa4,0x7e,0x12,0x85,0x1d,0x8a,0x29, +0x9c,0x31,0x10,0xc0,0x43,0x21,0x00,0x00,0xe9,0xe2,0xd2,0x18,0x8d,0xe1,0x75,0xe5, +0xa2,0x19,0xcd,0x99,0x72,0x5d,0x25,0x55,0x15,0xed,0x5e,0x29,0xa2,0x15,0x66,0xd9, +0xa9,0x6d,0xf1,0xe5,0xdd,0xd5,0xf1,0xed,0x9c,0x31,0x10,0x1e,0x63,0x32,0x00,0x00, +0xdd,0x5b,0xf4,0x9b,0x9d,0x24,0x40,0x23,0x09,0x24,0x21,0x13,0x47,0x1a,0x58,0xa2, +0x80,0x9b,0x91,0x1b,0x6c,0xdc,0x4e,0xdb,0x56,0x9b,0x7a,0x99,0x92,0xd0,0x7e,0xee, +0x9c,0x31,0x10,0xf4,0x52,0x22,0x00,0x00,0x2e,0xa6,0x12,0x92,0x62,0x44,0x88,0xe9, +0xa9,0x9c,0xb4,0xe2,0x85,0xd4,0x57,0x22,0x1a,0x2b,0x5a,0x52,0x95,0xf3,0x8c,0xe4, +0x65,0x23,0x55,0x9c,0x79,0x4a,0x59,0x52,0x9c,0x31,0x10,0x78,0x52,0x21,0x00,0x00, +0x2d,0xa1,0x25,0x56,0x42,0x28,0x42,0x59,0x21,0xac,0x41,0xdd,0x89,0xa2,0x9a,0x1c, +0x7a,0x59,0x72,0x19,0x84,0xe1,0x99,0x54,0x86,0x22,0x9e,0x60,0xb5,0xa2,0xbe,0x19, +0x9c,0x31,0x10,0x78,0x52,0x21,0x00,0x00,0xa5,0x5a,0x91,0xa8,0xb1,0x55,0xc5,0xd5, +0xa6,0x19,0x86,0x1e,0x91,0xa0,0xa9,0x69,0x92,0x1d,0x9e,0x56,0xbe,0x20,0xc6,0x5d, +0xb9,0x99,0xb4,0xcd,0xd6,0x69,0xee,0x59,0x9c,0x31,0x10,0x78,0x52,0x21,0x00,0x00, +0xe5,0x1a,0xad,0x61,0x95,0xd9,0xb9,0x98,0xc6,0x19,0xca,0x11,0xc6,0x21,0xb5,0xce, +0xb1,0xe5,0x91,0xd5,0x78,0xa2,0x8e,0x21,0x8a,0x1c,0x61,0xa4,0x32,0x5d,0x39,0xed, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/en/dudu.txt b/config/_default_cfg_src_/res/en/dudu.txt new file mode 100644 index 0000000..5d5037c --- /dev/null +++ b/config/_default_cfg_src_/res/en/dudu.txt @@ -0,0 +1,48 @@ +0x9c,0x31,0x14,0x91,0x21,0x11,0x11,0x10,0x7b,0x6d,0x57,0xb6,0xd5,0x7b,0x6d,0x57, +0xb6,0xd5,0x94,0x8d,0xa4,0xb4,0x95,0x3a,0x65,0x56,0xc7,0x14,0x4b,0x71,0x12,0x43, +0x14,0x14,0x29,0x50,0xb8,0x95,0x01,0x8d,0x83,0xbc,0xa5,0x5a,0x4d,0x56,0xb6,0x94, +0x9c,0x31,0x14,0xb4,0x31,0x11,0x11,0x10,0x64,0x89,0x55,0xc5,0x55,0x62,0x6d,0x67, +0x48,0x81,0x7c,0x6d,0x4a,0x45,0x69,0x53,0x6d,0x55,0xca,0x95,0x4b,0x85,0x54,0xb8, +0x95,0x33,0x71,0x54,0xda,0xd6,0x64,0x45,0x57,0xa2,0xd5,0x5a,0x6d,0x25,0x15,0x05, +0x9c,0x31,0x14,0xf4,0xd9,0x86,0x66,0x45,0x7e,0xed,0x57,0xee,0xd5,0x7e,0xed,0x57, +0xee,0xd5,0x7e,0xed,0x58,0x30,0xd5,0x87,0x0c,0x5a,0x57,0xa0,0xc2,0x52,0x54,0xb0, +0xd5,0x36,0xed,0x5b,0x2e,0xd5,0xc6,0xed,0x54,0xae,0xd5,0x36,0xed,0x5b,0x2e,0xd5, +0x9c,0x31,0x14,0x51,0xd4,0x34,0x41,0x12,0xc5,0xc5,0x34,0xa1,0x64,0x39,0xc6,0xdb, +0x4c,0x93,0xc4,0xb5,0xa4,0xa2,0x62,0x3a,0xc1,0xdb,0x4b,0x54,0xc3,0x36,0x34,0x99, +0x1a,0x3c,0x34,0xab,0x5d,0x5c,0xc0,0xa5,0xc4,0x8d,0x13,0x3d,0xa5,0xab,0x5d,0x6a, +0x9c,0x31,0x14,0x2e,0xd4,0x24,0x30,0x12,0xc0,0xb8,0xe4,0x82,0x0a,0x3e,0xe1,0x5b, +0x6a,0x0c,0xbe,0x30,0x84,0x82,0xb2,0x40,0xc3,0x2b,0x64,0x28,0xbd,0x32,0xc4,0x82, +0xb1,0x42,0x40,0xab,0x6c,0xaa,0xbb,0xb3,0x14,0x73,0x0c,0x43,0xc0,0x5b,0x74,0xae, +0x9c,0x31,0x14,0xf4,0xc3,0x23,0x31,0x02,0xf4,0xa9,0x60,0xe2,0x41,0x0a,0x46,0xce, +0xf4,0x94,0xf2,0x36,0xa0,0xe9,0x26,0x0d,0x47,0x9e,0xf4,0x8c,0xef,0x26,0x10,0xe2, +0x76,0x0f,0xc5,0x6e,0xfc,0x60,0xec,0xa6,0xc0,0xe2,0x59,0x12,0xb6,0x6f,0x05,0x82, +0x9c,0x31,0x14,0x11,0xc3,0x13,0x31,0x12,0xe9,0x27,0x20,0xda,0x61,0x15,0xc8,0x3f, +0x04,0xa5,0xe6,0xba,0xd0,0xd1,0x42,0x18,0xd9,0x8f,0x03,0xb2,0xe4,0x35,0x50,0xd8, +0x55,0x1b,0x53,0x2f,0x03,0x98,0xe1,0x28,0x30,0xda,0x6d,0x1d,0xc6,0xdf,0x0d,0x42, +0x9c,0x31,0x14,0xab,0xc2,0x13,0x31,0x11,0xde,0x85,0x80,0xd1,0x33,0x20,0xd1,0x5f, +0x0e,0x8d,0xdb,0x87,0x10,0xda,0x18,0x23,0xd4,0xbf,0x0e,0xad,0xd8,0x8a,0xd0,0xda, +0x02,0x26,0xd9,0x9f,0x04,0xaa,0xd6,0x04,0xd0,0xda,0x55,0x29,0x66,0xaf,0x04,0x50, +0x9c,0x31,0x14,0x0d,0xc2,0x13,0x30,0x02,0xd3,0x14,0xb0,0xe2,0x2d,0x2c,0x56,0xde, +0xfd,0x42,0xd0,0x95,0x80,0xea,0x33,0x2e,0xd4,0xde,0xfd,0x94,0xce,0x16,0x90,0xe9, +0x19,0x31,0xd4,0x3e,0xf3,0xa5,0xcb,0x16,0x40,0xf2,0x0a,0x34,0x66,0x1e,0xf4,0xaa, +0x9c,0x31,0x14,0x11,0xc3,0x13,0x31,0x12,0xc8,0xa4,0xd0,0xfa,0x15,0x36,0xc7,0x2e, +0xec,0x58,0xc6,0x24,0xb1,0x02,0x6d,0x39,0xd6,0x5e,0xe4,0x42,0xc4,0x25,0x91,0x0a, +0x6b,0x3c,0x54,0xee,0xdb,0x94,0xc1,0xb6,0x91,0x12,0x19,0x3e,0xc4,0xbe,0xcb,0x6d, +0x9c,0x31,0x14,0x11,0xc3,0x13,0x31,0x12,0xbf,0x26,0x41,0x22,0x4a,0x40,0xc5,0x9e, +0xc4,0x6b,0xbc,0xa5,0x51,0x2b,0x14,0x43,0x46,0xae,0xb4,0x99,0xba,0x14,0xb1,0x3a, +0x2d,0x45,0xd2,0x4e,0xac,0x89,0xb7,0xb5,0x91,0x41,0x2c,0x48,0x54,0xde,0x9a,0x54, +0x9c,0x31,0x14,0xc0,0xc2,0x13,0x30,0x12,0xb5,0x26,0xa1,0x5a,0x51,0x4a,0xd4,0xce, +0x8c,0xa4,0xb2,0xaa,0x41,0x61,0x4a,0x4d,0x55,0x9e,0x7d,0x6c,0xb0,0x14,0xd1,0x72, +0x54,0x4f,0x46,0xae,0x6c,0x51,0xae,0x08,0xb1,0x82,0x6d,0x51,0xd6,0x4e,0x5c,0x49, +0x9c,0x31,0x14,0x66,0xc2,0x13,0x31,0x01,0xab,0x96,0x11,0x89,0x6b,0x53,0xd0,0xde, +0x53,0x94,0xaa,0x16,0x91,0x9a,0x19,0x55,0xd8,0x4e,0x44,0x64,0xa7,0xa6,0x41,0xb2, +0x4a,0x57,0xe6,0x1e,0x33,0x63,0xa5,0x94,0xd1,0xc1,0x14,0x59,0xd6,0x9e,0x24,0x91, +0x9c,0x31,0x14,0xfb,0xc3,0x13,0x31,0x01,0xa3,0xa8,0xc1,0xd3,0x2d,0x5c,0x42,0x4e, +0x0b,0x89,0xa1,0xa5,0xa1,0xeb,0x6b,0x5e,0x34,0xdd,0xf4,0x9c,0x9f,0xa6,0x92,0x03, +0x11,0x60,0x41,0x3d,0xdb,0xad,0x9e,0x32,0x42,0x12,0x4a,0x61,0xd2,0x1d,0xd4,0x63, +0x9c,0x31,0x14,0x4e,0xc9,0x76,0x54,0x43,0x9b,0x76,0xd2,0x27,0x6d,0x63,0x76,0xdd, +0xa7,0x6d,0x99,0x76,0xd2,0x47,0x6d,0x65,0x76,0xdd,0x97,0x6d,0x98,0x76,0xd2,0x57, +0x6d,0x67,0x76,0xdd,0x77,0x6d,0x94,0x76,0xd1,0xf6,0x6d,0x5e,0xb8,0xd9,0x23,0xa6, +0x9c,0x31,0x14,0xe1,0x67,0x43,0x32,0x21,0x3e,0x6a,0xaa,0x26,0x11,0x8c,0x45,0x59, +0x3b,0x55,0x4b,0xb5,0x57,0x3b,0x55,0xc3,0xb5,0x58,0x3b,0x55,0x53,0xb5,0x98,0x3b, +0x55,0x9b,0xb5,0x58,0x3b,0x55,0x63,0xb5,0x57,0xbb,0x55,0xab,0xb5,0x58,0x3b,0x55, diff --git a/config/_default_cfg_src_/res/eq/EQ_COEF.txt b/config/_default_cfg_src_/res/eq/EQ_COEF.txt new file mode 100644 index 0000000..aa984f2 --- /dev/null +++ b/config/_default_cfg_src_/res/eq/EQ_COEF.txt @@ -0,0 +1,384 @@ +0x7FFF, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, diff --git a/config/_default_cfg_src_/res/gs_hw/en_all.txt b/config/_default_cfg_src_/res/gs_hw/en_all.txt new file mode 100644 index 0000000..e1517bc --- /dev/null +++ b/config/_default_cfg_src_/res/gs_hw/en_all.txt @@ -0,0 +1 @@ +0x00,0x00,0x00,0x00,0x0f,0x46,0x0c,0xfa,0x00,0x00,0x00,0x06,0x43,0x4d,0x34,0x5f,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x38,0x00,0x00,0x5b,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x5c,0x1c,0x00,0x00,0xa9,0x90,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0xb4,0x00,0x00,0x00,0x00,0x10,0x02,0x00,0x00,0x00,0x1c,0x02,0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x14,0x01,0x00,0x00,0x00,0x24,0x01,0x00,0x00,0x00,0x28,0x01,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,0x01,0x34,0x01,0x00,0x00,0x01,0x38,0x01,0x00,0x00,0x00,0xa8,0x01,0x00,0x00,0x00,0xe0,0x03,0x00,0x00,0x00,0x1c,0x04,0x00,0x00,0x00,0xe4,0x03,0x00,0x00,0x00,0xac,0x01,0x00,0x00,0x00,0x3c,0x04,0x00,0x00,0x01,0x64,0x04,0x00,0x00,0x01,0xa8,0x04,0x00,0x00,0x00,0xb0,0x04,0x00,0x00,0x01,0xec,0x04,0x00,0x00,0x00,0xf4,0x04,0x00,0x00,0x01,0x30,0x05,0x00,0x00,0x01,0x74,0x05,0x00,0x00,0x00,0x7c,0x05,0x00,0x00,0x01,0xb8,0x05,0x00,0x00,0x00,0xc0,0x05,0x00,0x00,0x01,0xfc,0x05,0x00,0x00,0x01,0x40,0x06,0x00,0x00,0x00,0x48,0x06,0x00,0x00,0x01,0x84,0x06,0x00,0x00,0x00,0x8c,0x06,0x00,0x00,0x01,0xc8,0x06,0x00,0x00,0x01,0x0c,0x07,0x00,0x00,0x00,0x14,0x07,0x00,0x00,0x01,0x50,0x07,0x00,0x00,0x00,0x58,0x07,0x00,0x00,0x01,0x94,0x07,0x00,0x00,0x01,0xd8,0x07,0x00,0x00,0x00,0xe0,0x07,0x00,0x00,0x01,0x1c,0x08,0x00,0x00,0x01,0x60,0x08,0x00,0x00,0x00,0x68,0x08,0x00,0x00,0x01,0xa4,0x08,0x00,0x00,0x01,0xe8,0x08,0x00,0x00,0x00,0xf0,0x08,0x00,0x00,0x01,0x2c,0x09,0x00,0x00,0x00,0x34,0x09,0x00,0x00,0x00,0xb0,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x28,0x10,0x00,0x00,0x00,0x50,0x10,0x00,0x00,0x00,0xe0,0x10,0x00,0x00,0x00,0x84,0x11,0x00,0x00,0x00,0xf0,0x10,0x00,0x00,0x00,0xe8,0x10,0x00,0x00,0x00,0x0c,0x11,0x00,0x00,0x00,0x14,0x11,0x00,0x00,0x00,0x44,0x26,0x00,0x00,0x00,0x2c,0x11,0x00,0x00,0x00,0x58,0x11,0x00,0x00,0x00,0x68,0x11,0x00,0x00,0x00,0xc0,0x27,0x00,0x00,0x00,0x58,0x10,0x00,0x00,0x00,0x64,0x10,0x00,0x00,0x00,0xc0,0x2b,0x00,0x00,0x00,0xf4,0x2b,0x00,0x00,0x00,0xfc,0x2b,0x00,0x00,0x00,0x14,0x2c,0x00,0x00,0x00,0x1c,0x2c,0x00,0x00,0x00,0xc8,0x2b,0x00,0x00,0x00,0xd4,0x2b,0x00,0x00,0x00,0xb0,0x2c,0x00,0x00,0x00,0xcc,0x2c,0x00,0x00,0x00,0xd8,0x2b,0x00,0x00,0x00,0xdc,0x2b,0x00,0x00,0x00,0xe4,0x2b,0x00,0x00,0x00,0xe8,0x2b,0x00,0x00,0x00,0x68,0x10,0x00,0x00,0x00,0x14,0x2d,0x00,0x00,0x00,0x1c,0x2d,0x00,0x00,0x00,0xa0,0x58,0x00,0x00,0x00,0xa4,0x58,0x00,0x00,0x00,0xa8,0x58,0x00,0x00,0x00,0xac,0x58,0x00,0x00,0x00,0xb0,0x58,0x00,0x00,0x00,0xb4,0x58,0x00,0x00,0x00,0xb8,0x58,0x00,0x00,0x00,0xbc,0x58,0x00,0x00,0x00,0xc0,0x58,0x00,0x00,0x00,0xc4,0x58,0x00,0x00,0x00,0xc8,0x58,0x00,0x00,0x00,0xcc,0x58,0x00,0x00,0x00,0xd0,0x58,0x00,0x00,0x00,0xd4,0x58,0x00,0x00,0x00,0xd8,0x58,0x00,0x00,0x00,0xdc,0x58,0x00,0x00,0x00,0xe0,0x58,0x00,0x00,0x00,0xe4,0x58,0x00,0x00,0x00,0x24,0x2d,0x00,0x00,0x00,0x28,0x2d,0x00,0x00,0x00,0x2c,0x2d,0x00,0x00,0x00,0x3c,0x2d,0x00,0x00,0x00,0x40,0x2d,0x00,0x00,0x00,0xb4,0x10,0x00,0x00,0x00,0xd4,0x10,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x0c,0x00,0x00,0x00,0x28,0x10,0x00,0x00,0xc1,0x60,0x94,0xc7,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x80,0x6d,0x45,0x00,0x00,0xfa,0x42,0x40,0x06,0x00,0x00,0x01,0x00,0x00,0x00,0x0a,0xd7,0x23,0x3d,0xcd,0xcc,0x4c,0x3d,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x41,0x00,0x00,0x20,0x41,0x0a,0x00,0xba,0xba,0x00,0x00,0xc8,0x42,0x0a,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0x33,0x33,0x73,0x3f,0x6f,0x12,0x83,0x3a,0x15,0x00,0xba,0xba,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0xf0,0x01,0x00,0x00,0x30,0x02,0x00,0x00,0x01,0x00,0x00,0x00,0x40,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x07,0x00,0x00,0x90,0x01,0x00,0x00,0xa0,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x60,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0xb0,0x02,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x20,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0xf0,0x02,0x00,0x00,0x40,0x03,0x00,0x00,0x90,0x03,0x00,0x00,0x75,0x00,0x00,0x00,0x20,0x03,0x00,0x00,0x10,0x04,0x00,0x00,0x05,0x00,0x00,0x00,0x7a,0x00,0x00,0x00,0x40,0x06,0x00,0x00,0x03,0x00,0x00,0x00,0x8f,0x02,0x00,0x00,0x71,0x3d,0x00,0x00,0x33,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0x8f,0x02,0x00,0x00,0x71,0x3d,0x00,0x00,0x40,0x06,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x14,0x00,0x00,0x0a,0x00,0xba,0xba,0x00,0x00,0x00,0x00,0x40,0x06,0x00,0x00,0xa0,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xd8,0x03,0x00,0x00,0x38,0x04,0x00,0x00,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x07,0x00,0x00,0x01,0x00,0xba,0xba,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x73,0x33,0x33,0x3f,0x00,0x00,0x80,0xbf,0x00,0x00,0x80,0xbf,0x00,0x00,0x80,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x01,0x00,0xba,0xba,0x20,0x02,0x00,0x00,0x01,0x00,0xba,0xba,0x0b,0x00,0x00,0x00,0x22,0x02,0x00,0x00,0x01,0x00,0x65,0x6e,0x2f,0x78,0x5f,0x67,0x6f,0x6f,0x67,0x6c,0x65,0xca,0xca,0xca,0x01,0x00,0xba,0xba,0x00,0x00,0x00,0x00,0x01,0x00,0xba,0xba,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0xba,0xba,0xba,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x61,0x0a,0x05,0x3e,0x56,0x00,0x00,0xa0,0x69,0x0a,0x05,0x3e,0x56,0x00,0x00,0x80,0x05,0xc2,0xbf,0x72,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xf2,0xde,0x04,0x3e,0x56,0x00,0x00,0x40,0x08,0xdf,0x04,0x3e,0x56,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x09,0x00,0x0b,0x00,0x0c,0x00,0x0e,0x00,0x10,0x00,0x12,0x00,0x14,0x00,0x16,0x00,0x19,0x00,0x1b,0x00,0x1e,0x00,0x20,0x00,0x23,0x00,0x26,0x00,0x29,0x00,0x2d,0x00,0x30,0x00,0x34,0x00,0x38,0x00,0x3c,0x00,0x40,0x00,0x45,0x00,0x4a,0x00,0x4f,0x00,0x54,0x00,0x59,0x00,0x5f,0x00,0x66,0x00,0x6c,0x00,0x73,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x06,0x00,0x07,0x00,0x09,0x00,0x0b,0x00,0x0d,0x00,0x0f,0x00,0x11,0x00,0x14,0x00,0x16,0x00,0x19,0x00,0x1b,0x00,0x1e,0x00,0x21,0x00,0x24,0x00,0x28,0x00,0x2b,0x00,0x2f,0x00,0x33,0x00,0x37,0x00,0x3b,0x00,0x40,0x00,0x45,0x00,0x4a,0x00,0x4f,0x00,0x54,0x00,0x5a,0x00,0x61,0x00,0x67,0x00,0x6e,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x02,0x00,0x03,0x00,0x02,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x04,0x00,0x03,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x06,0x00,0x07,0x00,0x07,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x30,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0xba,0xba,0xba,0xba,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0xba,0xba,0xba,0xba,0x99,0x59,0x99,0x59,0x99,0x59,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x99,0x59,0xba,0xba,0x01,0x00,0x00,0x00,0x2c,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0xba,0xba,0x01,0x00,0xca,0xca,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x60,0x04,0x00,0x00,0x03,0x05,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0xca,0xca,0xca,0xca,0x00,0x18,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa9,0x15,0x01,0x00,0x60,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x35,0x00,0x00,0x40,0x00,0x00,0x00,0x70,0x09,0x00,0x00,0x1a,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x02,0x04,0x00,0xba,0x00,0x00,0x05,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x01,0x00,0x00,0x00,0x01,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x39,0x00,0x00,0x10,0x00,0x00,0x00,0x70,0x0a,0x00,0x00,0x8c,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x02,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x03,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x49,0x00,0x00,0x40,0x00,0x00,0x00,0xb0,0x0a,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x02,0x04,0x00,0xba,0x00,0x00,0x05,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x01,0x00,0x00,0x00,0x04,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x4d,0x00,0x00,0x10,0x00,0x00,0x00,0xb0,0x0b,0x00,0x00,0xc2,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x05,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8e,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x06,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x5d,0x00,0x00,0x40,0x00,0x00,0x00,0xf0,0x0b,0x00,0x00,0x69,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x02,0x04,0x00,0xba,0x00,0x00,0x05,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x01,0x00,0x00,0x00,0x07,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x61,0x00,0x00,0x10,0x00,0x00,0x00,0xf0,0x0c,0x00,0x00,0xba,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x08,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xab,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x09,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x71,0x00,0x00,0x40,0x00,0x00,0x00,0x30,0x0d,0x00,0x00,0x6d,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x02,0x04,0x00,0xba,0x00,0x00,0x05,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x01,0x00,0x00,0x00,0x0a,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x75,0x00,0x00,0x10,0x00,0x00,0x00,0x30,0x0e,0x00,0x00,0xaf,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x0b,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x0c,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x81,0x00,0x00,0x20,0x00,0x00,0x00,0x70,0x0e,0x00,0x00,0xb1,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x04,0x00,0xba,0x00,0x00,0x05,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x01,0x00,0x00,0x00,0x0d,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x0e,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x91,0x00,0x00,0x20,0x00,0x00,0x00,0xf0,0x0e,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x04,0x00,0xba,0x00,0x00,0x05,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x01,0x00,0x00,0x00,0x0f,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x10,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xa1,0x00,0x00,0x20,0x00,0x00,0x00,0x70,0x0f,0x00,0x00,0xf7,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x04,0x00,0xba,0x00,0x00,0x05,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x01,0x00,0x00,0x00,0x11,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0xa9,0x00,0x00,0x08,0x00,0x00,0x00,0xf0,0x0f,0x00,0x00,0xac,0x06,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x04,0x01,0xba,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x00,0x00,0x00,0x00,0x12,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0xca,0xca,0xca,0xca,0x27,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xf1,0xff,0xff,0xff,0xb5,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xf6,0xff,0xff,0xff,0xef,0xff,0xff,0xff,0x12,0x00,0x00,0x00,0xb1,0xff,0xff,0xff,0xa7,0xff,0xff,0xff,0x4c,0xff,0xff,0xff,0xea,0xff,0xff,0xff,0x73,0xff,0xff,0xff,0xb3,0xff,0xff,0xff,0xd3,0xff,0xff,0xff,0xf8,0xff,0xff,0xff,0x38,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0xd0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe8,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xd4,0xff,0xff,0xff,0xb2,0xff,0xff,0xff,0xd4,0xff,0xff,0xff,0x93,0xff,0xff,0xff,0xe5,0xff,0xff,0xff,0x27,0x00,0x00,0x00,0x79,0x00,0x00,0x00,0xe7,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xec,0xff,0xff,0xff,0x1b,0x00,0x00,0x00,0xb6,0xff,0xff,0xff,0x0c,0x00,0x00,0x00,0xd5,0xff,0xff,0xff,0xab,0xff,0xff,0xff,0xe6,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0xe9,0xff,0xff,0xff,0xc5,0xff,0xff,0xff,0x24,0x00,0x00,0x00,0xd7,0xff,0xff,0xff,0x38,0x00,0x00,0x00,0x5c,0xff,0xff,0xff,0xdc,0xff,0xff,0xff,0xce,0xff,0xff,0xff,0xc7,0xff,0xff,0xff,0xf4,0xff,0xff,0xff,0x05,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xaf,0xff,0xff,0xff,0x0c,0x00,0x00,0x00,0x8d,0x00,0x00,0x00,0xd4,0xff,0xff,0xff,0xee,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xc5,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0x29,0xfd,0xff,0xff,0x21,0x04,0x00,0x00,0x20,0x01,0x00,0x00,0x9f,0x04,0x00,0x00,0xa4,0x01,0x00,0x00,0x1a,0x04,0x00,0x00,0x51,0x01,0x00,0x00,0x4c,0x02,0x00,0x00,0x31,0x04,0x00,0x00,0x1a,0x01,0x00,0x00,0xef,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x18,0x01,0x00,0x00,0x60,0xfc,0xff,0xff,0x87,0xff,0xff,0xff,0x51,0x03,0x00,0x00,0xa4,0x02,0x00,0x00,0x71,0xfe,0xff,0xff,0x4d,0xff,0xff,0xff,0x8c,0xfe,0xff,0xff,0x3e,0xfe,0xff,0xff,0x71,0x00,0x00,0x00,0x19,0xff,0xff,0xff,0x32,0x00,0x00,0x00,0x69,0x02,0x00,0x00,0xb0,0xfd,0xff,0xff,0x74,0x03,0x00,0x00,0x16,0x02,0x00,0x00,0xcf,0xfe,0xff,0xff,0xc4,0x00,0x00,0x00,0x56,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0x4a,0x01,0x00,0x00,0xc0,0x01,0x00,0x00,0xa0,0xfc,0xff,0xff,0x20,0xfd,0xff,0xff,0x1a,0xff,0xff,0xff,0x07,0x03,0x00,0x00,0xf3,0x02,0x00,0x00,0xb4,0xff,0xff,0xff,0x3c,0x00,0x00,0x00,0xd2,0xfe,0xff,0xff,0x81,0x00,0x00,0x00,0x76,0x02,0x00,0x00,0x36,0x00,0x00,0x00,0xae,0xfd,0xff,0xff,0xb6,0xff,0xff,0xff,0x29,0x00,0x00,0x00,0xd1,0xff,0xff,0xff,0x6b,0xfe,0xff,0xff,0xcc,0xff,0xff,0xff,0x16,0xff,0xff,0xff,0x24,0x01,0x00,0x00,0x53,0xfe,0xff,0xff,0x1a,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0xcf,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0xea,0x00,0x00,0x00,0x4c,0xfe,0xff,0xff,0x60,0xff,0xff,0xff,0x16,0xfd,0xff,0xff,0xb3,0x01,0x00,0x00,0x5d,0xff,0xff,0xff,0x4e,0x01,0x00,0x00,0xd8,0xfd,0xff,0xff,0x8a,0x00,0x00,0x00,0xdd,0xff,0xff,0xff,0x51,0x01,0x00,0x00,0x5a,0xfe,0xff,0xff,0xa3,0x00,0x00,0x00,0xde,0xfe,0xff,0xff,0x4b,0x02,0x00,0x00,0x75,0xfd,0xff,0xff,0xb4,0xfc,0xff,0xff,0x39,0x01,0x00,0x00,0x6e,0xff,0xff,0xff,0xd5,0xfe,0xff,0xff,0x80,0xfe,0xff,0xff,0x5a,0xff,0xff,0xff,0xc4,0x02,0x00,0x00,0x7e,0xff,0xff,0xff,0xc9,0x09,0x00,0x00,0x3d,0xf9,0xff,0xff,0x7f,0x00,0x00,0x00,0xec,0xfe,0xff,0xff,0x9e,0xfb,0xff,0xff,0x03,0xf7,0xff,0xff,0x0e,0x03,0x00,0x00,0x7e,0x01,0x00,0x00,0x05,0x01,0x00,0x00,0x85,0xfe,0xff,0xff,0x33,0xff,0xff,0xff,0xdc,0xf7,0xff,0xff,0x1f,0xf9,0xff,0xff,0x14,0xfe,0xff,0xff,0x7d,0x00,0x00,0x00,0x01,0xfd,0xff,0xff,0x60,0xfd,0xff,0xff,0x64,0x02,0x00,0x00,0x3f,0xff,0xff,0xff,0x0c,0xfd,0xff,0xff,0xbe,0x00,0x00,0x00,0x04,0x02,0x00,0x00,0xd0,0x05,0x00,0x00,0x5d,0xff,0xff,0xff,0x5a,0xfd,0xff,0xff,0xf1,0xff,0xff,0xff,0x71,0xfe,0xff,0xff,0x45,0x01,0x00,0x00,0x82,0x01,0x00,0x00,0xf4,0xfd,0xff,0xff,0x16,0xfd,0xff,0xff,0x5d,0x00,0x00,0x00,0x01,0xfe,0xff,0xff,0xb8,0x01,0x00,0x00,0x14,0x01,0x00,0x00,0xc0,0x01,0x00,0x00,0x6b,0xff,0xff,0xff,0xc7,0xfe,0xff,0xff,0x9a,0x03,0x00,0x00,0x72,0x00,0x00,0x00,0x51,0x03,0x00,0x00,0xec,0x01,0x00,0x00,0xff,0x03,0x00,0x00,0x60,0xfd,0xff,0xff,0xf7,0xff,0xff,0xff,0xf5,0xfc,0xff,0xff,0x64,0x04,0x00,0x00,0x51,0xfd,0xff,0xff,0xbc,0x03,0x00,0x00,0xa0,0xfc,0xff,0xff,0x87,0x03,0x00,0x00,0x6d,0xfe,0xff,0xff,0x59,0x02,0x00,0x00,0xe2,0xff,0xff,0xff,0xd3,0xfb,0xff,0xff,0xf3,0xfd,0xff,0xff,0x15,0x02,0x00,0x00,0x80,0x02,0x00,0x00,0x3a,0x00,0x00,0x00,0x54,0xff,0xff,0xff,0x6e,0x03,0x00,0x00,0x1e,0xfe,0xff,0xff,0xab,0xfc,0xff,0xff,0x4d,0xfe,0xff,0xff,0xa0,0xfe,0xff,0xff,0x23,0x05,0x00,0x00,0xa6,0x04,0x00,0x00,0x28,0xff,0xff,0xff,0x67,0x00,0x00,0x00,0x2d,0x01,0x00,0x00,0xaf,0xff,0xff,0xff,0xfd,0x00,0x00,0x00,0x71,0x00,0x00,0x00,0x5f,0x01,0x00,0x00,0xb1,0x01,0x00,0x00,0xec,0x01,0x00,0x00,0x09,0x05,0x00,0x00,0x79,0xff,0xff,0xff,0xb8,0x02,0x00,0x00,0xf3,0xfe,0xff,0xff,0x11,0xff,0xff,0xff,0x64,0x04,0x00,0x00,0x20,0x00,0x00,0x00,0xe3,0xf2,0xff,0xff,0x0a,0xfe,0xff,0xff,0x62,0x02,0x00,0x00,0x81,0x07,0x00,0x00,0x2f,0x02,0x00,0x00,0x9a,0xfd,0xff,0xff,0x30,0x02,0x00,0x00,0x5c,0xfe,0xff,0xff,0x32,0x01,0x00,0x00,0xd4,0xfe,0xff,0xff,0x03,0x00,0x00,0x00,0x0b,0x05,0x00,0x00,0x68,0x02,0x00,0x00,0xc3,0x02,0x00,0x00,0xf5,0xfb,0xff,0xff,0x4e,0xfc,0xff,0xff,0xd1,0x00,0x00,0x00,0xe9,0xfc,0xff,0xff,0x4f,0xfb,0xff,0xff,0xe9,0x01,0x00,0x00,0x9e,0x07,0x00,0x00,0x7e,0x01,0x00,0x00,0xf4,0x05,0x00,0x00,0x4f,0xfc,0xff,0xff,0xf7,0xfc,0xff,0xff,0x73,0x01,0x00,0x00,0x96,0x03,0x00,0x00,0x3d,0x05,0x00,0x00,0x49,0xfe,0xff,0xff,0xd3,0xfd,0xff,0xff,0xf3,0xfe,0xff,0xff,0x65,0xfb,0xff,0xff,0x57,0xfd,0xff,0xff,0x82,0xfc,0xff,0xff,0x2f,0x03,0x00,0x00,0x22,0x01,0x00,0x00,0x65,0x00,0x00,0x00,0xc9,0xfc,0xff,0xff,0x5e,0xfc,0xff,0xff,0xbc,0xfd,0xff,0xff,0x90,0x02,0x00,0x00,0x7c,0xff,0xff,0xff,0xd9,0xfa,0xff,0xff,0x6d,0x02,0x00,0x00,0x73,0x05,0x00,0x00,0xe6,0xfb,0xff,0xff,0xb9,0xfc,0xff,0xff,0xb2,0xfe,0xff,0xff,0xf3,0x04,0x00,0x00,0x7f,0xff,0xff,0xff,0x1e,0xfb,0xff,0xff,0x93,0xfd,0xff,0xff,0x29,0x04,0x00,0x00,0xa9,0xfc,0xff,0xff,0xdd,0xfe,0xff,0xff,0x6d,0xfc,0xff,0xff,0x73,0xfa,0xff,0xff,0x5e,0xf8,0xff,0xff,0x09,0xfb,0xff,0xff,0x8d,0x01,0x00,0x00,0xcb,0xfd,0xff,0xff,0x8a,0x00,0x00,0x00,0xc0,0x07,0x00,0x00,0x43,0x06,0x00,0x00,0x8b,0x01,0x00,0x00,0xd5,0xfd,0xff,0xff,0xd7,0xfd,0xff,0xff,0xff,0xfe,0xff,0xff,0x34,0x06,0x00,0x00,0x2b,0xff,0xff,0xff,0x57,0x04,0x00,0x00,0x4f,0x05,0x00,0x00,0x6c,0xfd,0xff,0xff,0x59,0x08,0x00,0x00,0x70,0x05,0x00,0x00,0x28,0x00,0x00,0x00,0xec,0x01,0x00,0x00,0xa0,0x05,0x00,0x00,0x5a,0x00,0x00,0x00,0xee,0xfd,0xff,0xff,0x1c,0x0a,0x00,0x00,0xd3,0x0a,0x00,0x00,0xb5,0xfd,0xff,0xff,0xb3,0x0c,0x00,0x00,0x62,0x08,0x00,0x00,0x52,0x04,0x00,0x00,0xbf,0x04,0x00,0x00,0x43,0x02,0x00,0x00,0xe1,0x07,0x00,0x00,0xde,0xfb,0xff,0xff,0xc0,0x04,0x00,0x00,0x8f,0x08,0x00,0x00,0xbd,0xf8,0xff,0xff,0x37,0xfb,0xff,0xff,0xd0,0xfa,0xff,0xff,0xda,0xfc,0xff,0xff,0x7c,0xf8,0xff,0xff,0x9e,0x03,0x00,0x00,0x62,0x01,0x00,0x00,0x40,0x06,0x00,0x00,0x86,0xfe,0xff,0xff,0xe4,0x09,0x00,0x00,0x1e,0x03,0x00,0x00,0x96,0x09,0x00,0x00,0xce,0xfd,0xff,0xff,0x47,0xff,0xff,0xff,0xda,0x01,0x00,0x00,0x3c,0x01,0x00,0x00,0x3f,0xf0,0xff,0xff,0xb3,0xf5,0xff,0xff,0x73,0x09,0x00,0x00,0x0f,0xfa,0xff,0xff,0x91,0x0a,0x00,0x00,0xda,0x05,0x00,0x00,0x9c,0x00,0x00,0x00,0xed,0x06,0x00,0x00,0x10,0x08,0x00,0x00,0x49,0x04,0x00,0x00,0xe6,0x05,0x00,0x00,0x7d,0xf9,0xff,0xff,0xba,0xf6,0xff,0xff,0x05,0x04,0x00,0x00,0x74,0xf8,0xff,0xff,0x1d,0x03,0x00,0x00,0x4c,0x00,0x00,0x00,0x2f,0x03,0x00,0x00,0x25,0x02,0x00,0x00,0x32,0xfe,0xff,0xff,0x38,0x0d,0x00,0x00,0xe7,0x00,0x00,0x00,0x75,0xfd,0xff,0xff,0xce,0x0b,0x00,0x00,0x73,0xfd,0xff,0xff,0xed,0xfd,0xff,0xff,0xce,0xff,0xff,0xff,0xc6,0xff,0xff,0xff,0x99,0xfa,0xff,0xff,0x6c,0x04,0x00,0x00,0xc8,0x02,0x00,0x00,0x1d,0xfb,0xff,0xff,0xf2,0x07,0x00,0x00,0x23,0xfd,0xff,0xff,0x63,0xfa,0xff,0xff,0xc6,0xfd,0xff,0xff,0x09,0xfc,0xff,0xff,0x35,0x00,0x00,0x00,0x35,0x02,0x00,0x00,0x2f,0xfe,0xff,0xff,0xc0,0x0b,0x00,0x00,0xa6,0xfb,0xff,0xff,0x60,0x02,0x00,0x00,0xa2,0xfe,0xff,0xff,0xe6,0xff,0xff,0xff,0x63,0xfc,0xff,0xff,0xb4,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0x04,0x00,0x00,0x03,0x03,0x00,0x00,0x1c,0xfe,0xff,0xff,0x6d,0x01,0x00,0x00,0x8b,0x04,0x00,0x00,0x3f,0xfe,0xff,0xff,0xed,0xfc,0xff,0xff,0xf3,0x06,0x00,0x00,0x90,0xfd,0xff,0xff,0x81,0xfc,0xff,0xff,0x20,0x02,0x00,0x00,0xb5,0x02,0x00,0x00,0x01,0xfe,0xff,0xff,0xba,0x07,0x00,0x00,0xf8,0xfe,0xff,0xff,0x83,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xeb,0xff,0xff,0xff,0xd3,0xfe,0xff,0xff,0xa2,0xfe,0xff,0xff,0x13,0xfe,0xff,0xff,0x2f,0xff,0xff,0xff,0x38,0x00,0x00,0x00,0x81,0xfc,0xff,0xff,0xae,0xff,0xff,0xff,0x98,0x06,0x00,0x00,0x0c,0x08,0x00,0x00,0x00,0xfd,0xff,0xff,0xee,0x05,0x00,0x00,0x60,0x08,0x00,0x00,0xa1,0xfc,0xff,0xff,0x83,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0xba,0xba,0xba,0x48,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xe0,0x10,0x00,0x00,0x60,0x00,0x00,0x00,0xf0,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xba,0xba,0xba,0xb0,0x2b,0x00,0x00,0x14,0x2d,0x00,0x00,0xba,0xba,0xba,0xba,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0xba,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x70,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0xba,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x80,0x59,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x70,0x11,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x21,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x30,0x25,0x00,0x00,0x01,0xba,0xba,0xba,0x30,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xba,0xba,0x10,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0x62,0x10,0x00,0x00,0x00,0x00,0x00,0x4d,0x62,0x10,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x27,0x00,0x00,0xba,0xba,0xba,0xba,0xe0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xc0,0x03,0x00,0x00,0xa0,0x11,0x00,0x00,0x01,0xba,0xba,0xba,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x50,0x26,0x00,0x00,0x00,0xba,0xba,0xba,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xc8,0x00,0x00,0x00,0xd0,0x27,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x2b,0x00,0x00,0x01,0x00,0x00,0x00,0x70,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x2c,0x00,0x00,0xe0,0x2c,0x00,0x00,0xf0,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2d,0x00,0x00,0x10,0x2d,0x00,0x00,0xca,0xca,0xca,0xca,0x01,0x00,0x00,0x00,0x30,0x2c,0x00,0x00,0x01,0x00,0x00,0x00,0x40,0x2c,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x50,0x2c,0x00,0x00,0x01,0x00,0x00,0x00,0x60,0x2c,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0xba,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xd0,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0x50,0x2d,0x00,0x00,0xa0,0x15,0x00,0x00,0x60,0x2d,0x00,0x00,0x13,0x00,0xba,0xba,0xa0,0x58,0x00,0x00,0xf0,0x58,0x00,0x00,0x20,0x59,0x00,0x00,0x00,0x00,0xba,0xba,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x50,0x59,0x00,0x00,0x60,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x2d,0x00,0x00,0x60,0x31,0x00,0x00,0xe0,0x31,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x36,0x00,0x00,0x80,0x36,0x00,0x00,0xa0,0x36,0x00,0x00,0xa0,0x3a,0x00,0x00,0x20,0x3b,0x00,0x00,0x40,0x3b,0x00,0x00,0x40,0x3f,0x00,0x00,0xc0,0x3f,0x00,0x00,0xe0,0x3f,0x00,0x00,0xe0,0x47,0x00,0x00,0x20,0x48,0x00,0x00,0x20,0x50,0x00,0x00,0x60,0x50,0x00,0x00,0x60,0x58,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0xba,0xba,0x00,0x00,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0xca,0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x05,0x00,0x08,0x00,0x0b,0x00,0x0e,0x00,0x12,0x00,0x17,0x00,0x1c,0x00,0x21,0x00,0x27,0x00,0x2e,0x00,0x35,0x00,0x3c,0x00,0x44,0x00,0x4d,0x00,0x56,0x00,0x5f,0x00,0x69,0x00,0x74,0x00,0x7f,0x00,0x8a,0x00,0x96,0x00,0xa2,0x00,0xaf,0x00,0xbc,0x00,0xca,0x00,0xd8,0x00,0xe7,0x00,0xf6,0x00,0x05,0x01,0x15,0x01,0x25,0x01,0x36,0x01,0x47,0x01,0x59,0x01,0x6b,0x01,0x7e,0x01,0x91,0x01,0xa4,0x01,0xb8,0x01,0xcc,0x01,0xe0,0x01,0xf5,0x01,0x0a,0x02,0x20,0x02,0x36,0x02,0x4d,0x02,0x63,0x02,0x7a,0x02,0x92,0x02,0xaa,0x02,0xc2,0x02,0xda,0x02,0xf3,0x02,0x0c,0x03,0x26,0x03,0x3f,0x03,0x59,0x03,0x74,0x03,0x8e,0x03,0xa9,0x03,0xc4,0x03,0xe0,0x03,0xfb,0x03,0x17,0x04,0x33,0x04,0x50,0x04,0x6d,0x04,0x89,0x04,0xa7,0x04,0xc4,0x04,0xe1,0x04,0xff,0x04,0x1d,0x05,0x3b,0x05,0x59,0x05,0x78,0x05,0x96,0x05,0xb5,0x05,0xd4,0x05,0xf3,0x05,0x12,0x06,0x32,0x06,0x51,0x06,0x70,0x06,0x90,0x06,0xb0,0x06,0xd0,0x06,0xef,0x06,0x0f,0x07,0x2f,0x07,0x4f,0x07,0x6f,0x07,0x8f,0x07,0xb0,0x07,0xd0,0x07,0xf0,0x07,0x10,0x08,0x30,0x08,0x50,0x08,0x71,0x08,0x91,0x08,0xb1,0x08,0xd1,0x08,0xf1,0x08,0x11,0x09,0x30,0x09,0x50,0x09,0x70,0x09,0x90,0x09,0xaf,0x09,0xce,0x09,0xee,0x09,0x0d,0x0a,0x2c,0x0a,0x4b,0x0a,0x6a,0x0a,0x88,0x0a,0xa7,0x0a,0xc5,0x0a,0xe3,0x0a,0x01,0x0b,0x1f,0x0b,0x3c,0x0b,0x59,0x0b,0x77,0x0b,0x93,0x0b,0xb0,0x0b,0xcd,0x0b,0xe9,0x0b,0x05,0x0c,0x20,0x0c,0x3c,0x0c,0x57,0x0c,0x72,0x0c,0x8c,0x0c,0xa7,0x0c,0xc1,0x0c,0xda,0x0c,0xf4,0x0c,0x0d,0x0d,0x26,0x0d,0x3e,0x0d,0x56,0x0d,0x6e,0x0d,0x86,0x0d,0x9d,0x0d,0xb3,0x0d,0xca,0x0d,0xe0,0x0d,0xf6,0x0d,0x0b,0x0e,0x20,0x0e,0x34,0x0e,0x48,0x0e,0x5c,0x0e,0x6f,0x0e,0x82,0x0e,0x95,0x0e,0xa7,0x0e,0xb9,0x0e,0xca,0x0e,0xdb,0x0e,0xeb,0x0e,0xfb,0x0e,0x0a,0x0f,0x19,0x0f,0x28,0x0f,0x36,0x0f,0x44,0x0f,0x51,0x0f,0x5e,0x0f,0x6a,0x0f,0x76,0x0f,0x81,0x0f,0x8c,0x0f,0x97,0x0f,0xa1,0x0f,0xaa,0x0f,0xb3,0x0f,0xbc,0x0f,0xc4,0x0f,0xcb,0x0f,0xd2,0x0f,0xd9,0x0f,0xdf,0x0f,0xe4,0x0f,0xe9,0x0f,0xee,0x0f,0xf2,0x0f,0xf5,0x0f,0xf8,0x0f,0xfb,0x0f,0xfd,0x0f,0xfe,0x0f,0xff,0x0f,0x00,0x10,0x00,0x10,0xff,0x0f,0xfe,0x0f,0xfd,0x0f,0xfb,0x0f,0xf8,0x0f,0xf5,0x0f,0xf2,0x0f,0xee,0x0f,0xe9,0x0f,0xe4,0x0f,0xdf,0x0f,0xd9,0x0f,0xd2,0x0f,0xcb,0x0f,0xc4,0x0f,0xbc,0x0f,0xb3,0x0f,0xaa,0x0f,0xa1,0x0f,0x97,0x0f,0x8c,0x0f,0x81,0x0f,0x76,0x0f,0x6a,0x0f,0x5e,0x0f,0x51,0x0f,0x44,0x0f,0x36,0x0f,0x28,0x0f,0x19,0x0f,0x0a,0x0f,0xfb,0x0e,0xeb,0x0e,0xdb,0x0e,0xca,0x0e,0xb9,0x0e,0xa7,0x0e,0x95,0x0e,0x82,0x0e,0x6f,0x0e,0x5c,0x0e,0x48,0x0e,0x34,0x0e,0x20,0x0e,0x0b,0x0e,0xf6,0x0d,0xe0,0x0d,0xca,0x0d,0xb3,0x0d,0x9d,0x0d,0x86,0x0d,0x6e,0x0d,0x56,0x0d,0x3e,0x0d,0x26,0x0d,0x0d,0x0d,0xf4,0x0c,0xda,0x0c,0xc1,0x0c,0xa7,0x0c,0x8c,0x0c,0x72,0x0c,0x57,0x0c,0x3c,0x0c,0x20,0x0c,0x05,0x0c,0xe9,0x0b,0xcd,0x0b,0xb0,0x0b,0x93,0x0b,0x77,0x0b,0x59,0x0b,0x3c,0x0b,0x1f,0x0b,0x01,0x0b,0xe3,0x0a,0xc5,0x0a,0xa7,0x0a,0x88,0x0a,0x6a,0x0a,0x4b,0x0a,0x2c,0x0a,0x0d,0x0a,0xee,0x09,0xce,0x09,0xaf,0x09,0x90,0x09,0x70,0x09,0x50,0x09,0x30,0x09,0x11,0x09,0xf1,0x08,0xd1,0x08,0xb1,0x08,0x91,0x08,0x71,0x08,0x50,0x08,0x30,0x08,0x10,0x08,0xf0,0x07,0xd0,0x07,0xb0,0x07,0x8f,0x07,0x6f,0x07,0x4f,0x07,0x2f,0x07,0x0f,0x07,0xef,0x06,0xd0,0x06,0xb0,0x06,0x90,0x06,0x70,0x06,0x51,0x06,0x32,0x06,0x12,0x06,0xf3,0x05,0xd4,0x05,0xb5,0x05,0x96,0x05,0x78,0x05,0x59,0x05,0x3b,0x05,0x1d,0x05,0xff,0x04,0xe1,0x04,0xc4,0x04,0xa7,0x04,0x89,0x04,0x6d,0x04,0x50,0x04,0x33,0x04,0x17,0x04,0xfb,0x03,0xe0,0x03,0xc4,0x03,0xa9,0x03,0x8e,0x03,0x74,0x03,0x59,0x03,0x3f,0x03,0x26,0x03,0x0c,0x03,0xf3,0x02,0xda,0x02,0xc2,0x02,0xaa,0x02,0x92,0x02,0x7a,0x02,0x63,0x02,0x4d,0x02,0x36,0x02,0x20,0x02,0x0a,0x02,0xf5,0x01,0xe0,0x01,0xcc,0x01,0xb8,0x01,0xa4,0x01,0x91,0x01,0x7e,0x01,0x6b,0x01,0x59,0x01,0x47,0x01,0x36,0x01,0x25,0x01,0x15,0x01,0x05,0x01,0xf6,0x00,0xe7,0x00,0xd8,0x00,0xca,0x00,0xbc,0x00,0xaf,0x00,0xa2,0x00,0x96,0x00,0x8a,0x00,0x7f,0x00,0x74,0x00,0x69,0x00,0x5f,0x00,0x56,0x00,0x4d,0x00,0x44,0x00,0x3c,0x00,0x35,0x00,0x2e,0x00,0x27,0x00,0x21,0x00,0x1c,0x00,0x17,0x00,0x12,0x00,0x0e,0x00,0x0b,0x00,0x08,0x00,0x05,0x00,0x03,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x6d,0x04,0x45,0x09,0x80,0x0e,0x17,0x04,0x04,0x0a,0x42,0x00,0xcc,0x06,0x9e,0x0d,0xb2,0x04,0x07,0x0c,0x97,0x03,0x61,0x0b,0x61,0x03,0x94,0x0b,0xf7,0x03,0x8a,0x0c,0x48,0x05,0x31,0x0e,0x43,0x07,0x7b,0x00,0xd8,0x09,0x58,0x03,0xfb,0x0c,0xbe,0x06,0xa1,0x00,0xa2,0x0a,0xbf,0x04,0xf9,0x0e,0x4e,0x09,0xbc,0x03,0x44,0x0e,0xe4,0x08,0x9b,0x03,0x69,0x0e,0x4c,0x09,0x45,0x04,0x52,0x0f,0x74,0x0a,0xa8,0x05,0xef,0x00,0x48,0x0c,0xb2,0x07,0x2e,0x03,0xba,0x0e,0x56,0x0a,0x02,0x06,0xbd,0x01,0x87,0x0d,0x5f,0x09,0x45,0x05,0x39,0x01,0x3a,0x0d,0x48,0x09,0x63,0x05,0x8a,0x01,0xbd,0x0d,0xfc,0x09,0x47,0x06,0x9c,0x02,0xfd,0x0e,0x68,0x0b,0xdd,0x07,0x5d,0x04,0xe7,0x00,0x7a,0x0d,0x17,0x0a,0xbd,0x06,0x6d,0x03,0x25,0x00,0xe6,0x0c,0xb0,0x09,0x82,0x06,0x5d,0x03,0x3f,0x00,0x29,0x0d,0x1c,0x0a,0x15,0x07,0x16,0x04,0x1f,0x01,0x2e,0x0e,0x45,0x0b,0x63,0x08,0x87,0x05,0xb2,0x02,0xe3,0x0f,0x1b,0x0d,0x5a,0x0a,0x9e,0x07,0xe9,0x04,0x39,0x02,0x90,0x0f,0xec,0x0c,0x4e,0x0a,0xb5,0x07,0x22,0x05,0x95,0x02,0x0c,0x00,0x89,0x0d,0x0b,0x0b,0x92,0x08,0x1e,0x06,0xb0,0x03,0x45,0x01,0xe0,0x0e,0x7f,0x0c,0x23,0x0a,0xcc,0x07,0x79,0x05,0x2a,0x03,0xe0,0x00,0x9a,0x0e,0x58,0x0c,0x1a,0x0a,0xe1,0x07,0xab,0x05,0x7a,0x03,0x4c,0x01,0xca,0xca,0xca,0xca,0xca,0xca,0x92,0x0b,0xba,0x06,0x7f,0x01,0xe8,0x0b,0xfb,0x05,0xbd,0x0f,0x33,0x09,0x61,0x02,0x4d,0x0b,0xf8,0x03,0x68,0x0c,0x9e,0x04,0x9e,0x0c,0x6b,0x04,0x08,0x0c,0x75,0x03,0xb7,0x0a,0xce,0x01,0xbc,0x08,0x84,0x0f,0x27,0x06,0xa7,0x0c,0x04,0x03,0x41,0x09,0x5e,0x0f,0x5d,0x05,0x40,0x0b,0x06,0x01,0xb1,0x06,0x43,0x0c,0xbb,0x01,0x1b,0x07,0x64,0x0c,0x96,0x01,0xb3,0x06,0xba,0x0b,0xad,0x00,0x8b,0x05,0x57,0x0a,0x10,0x0f,0xb7,0x03,0x4d,0x08,0xd1,0x0c,0x45,0x01,0xa9,0x05,0xfd,0x09,0x42,0x0e,0x78,0x02,0xa0,0x06,0xba,0x0a,0xc6,0x0e,0xc5,0x02,0xb7,0x06,0x9c,0x0a,0x75,0x0e,0x42,0x02,0x03,0x06,0xb8,0x09,0x63,0x0d,0x02,0x01,0x97,0x04,0x22,0x08,0xa2,0x0b,0x18,0x0f,0x85,0x02,0xe8,0x05,0x42,0x09,0x92,0x0c,0xda,0x0f,0x19,0x03,0x4f,0x06,0x7d,0x09,0xa2,0x0c,0xc0,0x0f,0xd6,0x02,0xe3,0x05,0xea,0x08,0xe9,0x0b,0xe0,0x0e,0xd1,0x01,0xba,0x04,0x9c,0x07,0x78,0x0a,0x4d,0x0d,0x1c,0x00,0xe4,0x02,0xa5,0x05,0x61,0x08,0x16,0x0b,0xc6,0x0d,0x6f,0x00,0x13,0x03,0xb1,0x05,0x4a,0x08,0xdd,0x0a,0x6a,0x0d,0xf3,0x0f,0x76,0x02,0xf4,0x04,0x6d,0x07,0xe1,0x09,0x4f,0x0c,0xba,0x0e,0x1f,0x01,0x80,0x03,0xdc,0x05,0x33,0x08,0x86,0x0a,0xd5,0x0c,0x1f,0x0f,0x65,0x01,0xa7,0x03,0xe5,0x05,0x1e,0x08,0x54,0x0a,0x85,0x0c,0xb3,0x0e,0xca,0xca,0xca,0xca,0xca,0xca,0x05,0x00,0x0b,0x00,0x06,0x00,0xfc,0xff,0xfc,0xff,0xe7,0xff,0xe6,0xff,0xe8,0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf5,0xff,0xf0,0xff,0xf4,0xff,0xf7,0xff,0xfa,0xff,0xf7,0xff,0xf9,0xff,0xfb,0xff,0xfc,0xff,0x00,0x00,0xff,0xff,0xfe,0xff,0xfc,0xff,0xfb,0xff,0xf6,0xff,0xf4,0xff,0xf4,0xff,0xf3,0xff,0xf4,0xff,0xed,0xff,0xe9,0xff,0x02,0x00,0x04,0x00,0x05,0x00,0x04,0x00,0x05,0x00,0x07,0x00,0x07,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0xfe,0xff,0xfd,0xff,0xfe,0xff,0x03,0x00,0x04,0x00,0x03,0x00,0xff,0xff,0xfe,0xff,0xfb,0xff,0xfd,0xff,0xfe,0xff,0xfe,0xff,0x02,0x00,0x03,0x00,0x06,0x00,0x00,0x00,0xfe,0xff,0x00,0x00,0x02,0x00,0x04,0x00,0x03,0x00,0x08,0x00,0xfe,0xff,0xfb,0xff,0x00,0x00,0x0d,0x00,0x12,0x00,0x2b,0x00,0x29,0x00,0x1f,0x00,0x1b,0x00,0x1a,0x00,0x18,0x00,0x0c,0x00,0x16,0x00,0x10,0x00,0x11,0x00,0x08,0x00,0x0b,0x00,0x05,0x00,0x05,0x00,0x02,0x00,0x01,0x00,0xff,0xff,0x01,0x00,0x09,0x00,0x09,0x00,0x0b,0x00,0x06,0x00,0x06,0x00,0x0f,0x00,0x0e,0x00,0x13,0x00,0x1f,0x00,0x0b,0x00,0x0f,0x00,0x00,0x00,0xe8,0xff,0xf5,0xff,0x05,0x00,0xef,0xff,0x07,0x00,0xf6,0xff,0x11,0x00,0x07,0x00,0xf6,0xff,0xf7,0xff,0xef,0xff,0xfa,0xff,0xfa,0xff,0xf6,0xff,0x03,0x00,0x26,0x00,0x40,0x00,0x2f,0x00,0x1e,0x00,0x1b,0x00,0xfa,0xff,0xf3,0xff,0xf7,0xff,0xf5,0xff,0x03,0x00,0xf7,0xff,0xe3,0xff,0x05,0x00,0xf1,0xff,0x10,0x00,0xf7,0xff,0xef,0xff,0xfa,0xff,0xf8,0xff,0x09,0x00,0x06,0x00,0x09,0x00,0x12,0x00,0x13,0x00,0x03,0x00,0xfc,0xff,0xf5,0xff,0xeb,0xff,0xf5,0xff,0xdf,0xff,0xfb,0xff,0x0d,0x00,0x34,0x00,0x3a,0x00,0x59,0x00,0x39,0x00,0x0e,0x00,0x02,0x00,0xda,0xff,0xde,0xff,0xf8,0xff,0xf1,0xff,0xf0,0xff,0xee,0xff,0xf0,0xff,0xed,0xff,0x05,0x00,0xf4,0xff,0xf4,0xff,0x08,0x00,0xfa,0xff,0xf8,0xff,0x04,0x00,0x02,0x00,0x16,0x00,0xf7,0xff,0xf9,0xff,0xf2,0xff,0xdd,0xff,0xe8,0xff,0xd4,0xff,0xe7,0xff,0xfb,0xff,0x10,0x00,0x22,0x00,0x37,0x00,0x40,0x00,0x26,0x00,0x07,0x00,0xdb,0xff,0xe0,0xff,0xed,0xff,0xf4,0xff,0x00,0x00,0xeb,0xff,0xfd,0xff,0xf2,0xff,0xda,0xff,0xff,0xff,0xfe,0xff,0xf6,0xff,0xe9,0xff,0xef,0xff,0xf1,0xff,0xed,0xff,0xe9,0xff,0xec,0xff,0xef,0xff,0xfb,0xff,0xfd,0xff,0x04,0x00,0x06,0x00,0x09,0x00,0x04,0x00,0xfd,0xff,0xf2,0xff,0xe9,0xff,0xe1,0xff,0xe0,0xff,0xea,0xff,0xf3,0xff,0xf7,0xff,0xf7,0xff,0xf0,0xff,0xf0,0xff,0xf8,0xff,0xf8,0xff,0x07,0x00,0x01,0x00,0x1b,0x00,0xed,0xff,0xfc,0xff,0xf8,0xff,0xfa,0xff,0xfc,0xff,0xfd,0xff,0xfa,0xff,0xfa,0xff,0xfc,0xff,0xfe,0xff,0xff,0xff,0x01,0x00,0x01,0x00,0x03,0x00,0xff,0xff,0xfb,0xff,0xf5,0xff,0xf2,0xff,0xec,0xff,0xe9,0xff,0xed,0xff,0xf8,0xff,0xfa,0xff,0x07,0x00,0xff,0xff,0x0a,0x00,0x0d,0x00,0x0f,0x00,0x17,0x00,0x17,0x00,0x14,0x00,0x29,0x00,0xea,0xff,0x00,0x00,0x04,0x00,0x07,0x00,0x07,0x00,0x0b,0x00,0x10,0x00,0x18,0x00,0x16,0x00,0x0f,0x00,0x0d,0x00,0x0a,0x00,0x08,0x00,0xfd,0xff,0xf7,0xff,0xf3,0xff,0xf2,0xff,0xf9,0xff,0xfa,0xff,0xfe,0xff,0x0a,0x00,0x0d,0x00,0x14,0x00,0x11,0x00,0x0f,0x00,0x16,0x00,0x1c,0x00,0x1b,0x00,0x1d,0x00,0x1d,0x00,0x19,0x00,0x26,0x00,0x0c,0x00,0x04,0x00,0xf8,0xff,0xf2,0xff,0xf5,0xff,0xf2,0xff,0xea,0xff,0xf2,0xff,0xfa,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xf3,0xff,0xf1,0xff,0xec,0xff,0xed,0xff,0xee,0xff,0xf4,0xff,0xf6,0xff,0xfd,0xff,0xfd,0xff,0x03,0x00,0x04,0x00,0xfb,0xff,0x01,0x00,0xff,0xff,0x04,0x00,0x09,0x00,0x01,0x00,0x00,0x00,0xfb,0xff,0xf8,0xff,0x08,0x00,0xff,0xff,0x06,0x00,0x0e,0x00,0x06,0x00,0x06,0x00,0x18,0x00,0x21,0x00,0x1e,0x00,0x18,0x00,0x14,0x00,0x07,0x00,0x03,0x00,0xff,0xff,0xfb,0xff,0xf6,0xff,0xf9,0xff,0x01,0x00,0x00,0x00,0x05,0x00,0x0a,0x00,0x09,0x00,0x07,0x00,0x05,0x00,0x01,0x00,0x01,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0xff,0xff,0xfc,0xff,0xf2,0xff,0xfc,0xff,0x01,0x00,0x09,0x00,0x00,0x00,0x0e,0x00,0x24,0x00,0x2b,0x00,0x29,0x00,0x24,0x00,0x1e,0x00,0x13,0x00,0x08,0x00,0x08,0x00,0x04,0x00,0xfd,0xff,0x02,0x00,0x03,0x00,0x04,0x00,0x02,0x00,0xfe,0xff,0xff,0xff,0x01,0x00,0xff,0xff,0x02,0x00,0xfe,0xff,0x08,0x00,0x05,0x00,0x06,0x00,0x05,0x00,0x0b,0x00,0x0f,0x00,0xff,0xff,0xee,0xff,0xee,0xff,0x0b,0x00,0xf4,0xff,0xec,0xff,0xf6,0xff,0x11,0x00,0x09,0x00,0x04,0x00,0xf4,0xff,0x01,0x00,0xf4,0xff,0xfa,0xff,0x0e,0x00,0x15,0x00,0xfe,0xff,0x06,0x00,0x0a,0x00,0x02,0x00,0xf3,0xff,0x0e,0x00,0xfa,0xff,0xf7,0xff,0xfe,0xff,0xef,0xff,0x09,0x00,0xf2,0xff,0xf2,0xff,0x03,0x00,0xf5,0xff,0xf7,0xff,0x14,0x00,0xef,0xff,0xfb,0xff,0xf3,0xff,0xf8,0xff,0xef,0xff,0xf0,0xff,0x09,0x00,0xff,0xff,0xf6,0xff,0xfc,0xff,0x0e,0x00,0x05,0x00,0x05,0x00,0x02,0x00,0x01,0x00,0xf2,0xff,0xfd,0xff,0x0c,0x00,0x05,0x00,0x11,0x00,0x05,0x00,0xfa,0xff,0x0f,0x00,0x02,0x00,0xfa,0xff,0x01,0x00,0x0d,0x00,0x08,0x00,0x14,0x00,0x11,0x00,0x01,0x00,0x0c,0x00,0x07,0x00,0xf3,0xff,0xfd,0xff,0xfc,0xff,0xfe,0xff,0xf3,0xff,0x09,0x00,0xeb,0xff,0xf9,0xff,0xed,0xff,0x09,0x00,0xed,0xff,0x0a,0x00,0xed,0xff,0xf9,0xff,0x08,0x00,0x03,0x00,0xf7,0xff,0x03,0x00,0x09,0x00,0x07,0x00,0xfb,0xff,0xf9,0xff,0x0a,0x00,0xf1,0xff,0x0e,0x00,0xf5,0xff,0x0e,0x00,0xfc,0xff,0xf4,0xff,0xf0,0xff,0xf6,0xff,0x01,0x00,0xf7,0xff,0x08,0x00,0xff,0xff,0xfb,0xff,0x01,0x00,0xea,0xff,0xf2,0xff,0xf5,0xff,0xea,0xff,0xe9,0xff,0x0e,0x00,0xf1,0xff,0xfe,0xff,0x00,0x00,0xf9,0xff,0x01,0x00,0xff,0xff,0x0b,0x00,0x12,0x00,0x09,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0xfd,0xff,0xed,0xff,0x13,0x00,0xf6,0xff,0x00,0x00,0x12,0x00,0x0f,0x00,0x06,0x00,0xf4,0xff,0x04,0x00,0xf8,0xff,0xf6,0xff,0xf4,0xff,0xf2,0xff,0xfa,0xff,0xf3,0xff,0xf6,0xff,0xf3,0xff,0x0e,0x00,0xf7,0xff,0xfe,0xff,0xfa,0xff,0x09,0x00,0x10,0x00,0x0e,0x00,0x15,0x00,0x0b,0x00,0xf4,0xff,0xfe,0xff,0x07,0x00,0x06,0x00,0xee,0xff,0xf4,0xff,0xf7,0xff,0xfe,0xff,0x11,0x00,0xfb,0xff,0xff,0xff,0x03,0x00,0x06,0x00,0xef,0xff,0x10,0x00,0xf5,0xff,0xf8,0xff,0xf1,0xff,0x11,0x00,0x02,0x00,0xed,0xff,0x11,0x00,0xf4,0xff,0xe9,0xff,0xf7,0xff,0x13,0x00,0x09,0x00,0xff,0xff,0x10,0x00,0x0e,0x00,0x01,0x00,0xfb,0xff,0x00,0x00,0xfe,0xff,0xf8,0xff,0xf0,0xff,0xf6,0xff,0x16,0x00,0xfe,0xff,0x10,0x00,0xed,0xff,0xfd,0xff,0xf3,0xff,0x16,0x00,0xf0,0xff,0x06,0x00,0x02,0x00,0x04,0x00,0x12,0x00,0x0b,0x00,0xfa,0xff,0xef,0xff,0xff,0xff,0x0a,0x00,0x04,0x00,0x05,0x00,0xfc,0xff,0xff,0xff,0x03,0x00,0x0f,0x00,0x1b,0x00,0x1b,0x00,0x2c,0x00,0x15,0x00,0x0d,0x00,0xf6,0xff,0xe9,0xff,0xe9,0xff,0xf7,0xff,0xf4,0xff,0x01,0x00,0xf0,0xff,0xf3,0xff,0x0d,0x00,0xf8,0xff,0x17,0x00,0xfa,0xff,0x03,0x00,0x00,0x00,0xf9,0xff,0x03,0x00,0x0f,0x00,0xf2,0xff,0xfc,0xff,0xf1,0xff,0xf2,0xff,0xf7,0xff,0xf1,0xff,0xed,0xff,0xf2,0xff,0x10,0x00,0x1d,0x00,0x36,0x00,0x3b,0x00,0x3d,0x00,0x27,0x00,0x09,0x00,0xf9,0xff,0xdb,0xff,0xe3,0xff,0xf2,0xff,0xf4,0xff,0xe2,0xff,0xf1,0xff,0xf1,0xff,0xfc,0xff,0x06,0x00,0x0d,0x00,0xee,0xff,0xfd,0xff,0xf7,0xff,0xfa,0xff,0x10,0x00,0xf4,0xff,0xfc,0xff,0x00,0x00,0xfc,0xff,0xf9,0xff,0xfb,0xff,0xe9,0xff,0xe3,0xff,0xf8,0xff,0x14,0x00,0x20,0x00,0x2a,0x00,0x2a,0x00,0x18,0x00,0x1b,0x00,0x00,0x00,0xea,0xff,0xe8,0xff,0xd8,0xff,0xf7,0xff,0xfb,0xff,0xfe,0xff,0x02,0x00,0xff,0xff,0xf4,0xff,0x0b,0x00,0xed,0xff,0x00,0x00,0x03,0x00,0xf6,0xff,0xf5,0xff,0xf7,0xff,0xfe,0xff,0xf9,0xff,0xf7,0xff,0xeb,0xff,0xec,0xff,0xee,0xff,0xf3,0xff,0xf7,0xff,0xf4,0xff,0xf8,0xff,0xf6,0xff,0xf4,0xff,0xf3,0xff,0xf0,0xff,0xf7,0xff,0xf5,0xff,0xfd,0xff,0xfc,0xff,0xfe,0xff,0xfd,0xff,0xfc,0xff,0xfd,0xff,0xfa,0xff,0xfb,0xff,0xf8,0xff,0xf9,0xff,0xf8,0xff,0xf7,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0x02,0x00,0xfa,0xff,0xfe,0xff,0x01,0x00,0xfd,0xff,0x02,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xfe,0xff,0x03,0x00,0x03,0x00,0x04,0x00,0x06,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x01,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0xfe,0xff,0x0a,0x00,0x03,0x00,0x0a,0x00,0x0c,0x00,0x1a,0x00,0x18,0x00,0x20,0x00,0x1a,0x00,0x19,0x00,0x17,0x00,0x10,0x00,0x14,0x00,0x13,0x00,0x17,0x00,0x19,0x00,0x1b,0x00,0x15,0x00,0x0f,0x00,0x0d,0x00,0x08,0x00,0x07,0x00,0x04,0x00,0x04,0x00,0x07,0x00,0x09,0x00,0x0d,0x00,0x0b,0x00,0x0e,0x00,0x0b,0x00,0x0a,0x00,0x11,0x00,0xf0,0xff,0x07,0x00,0xfa,0xff,0x01,0x00,0x0f,0x00,0xfd,0xff,0xe8,0xff,0xd9,0xff,0xf1,0xff,0x4d,0x00,0x15,0x00,0xff,0xff,0xda,0xff,0x12,0x00,0x12,0x00,0xf9,0xff,0xf8,0xff,0x11,0x00,0x01,0x00,0xf8,0xff,0xef,0xff,0x03,0x00,0xfe,0xff,0xe1,0xff,0x01,0x00,0xed,0xff,0x0e,0x00,0xf7,0xff,0x06,0x00,0x12,0x00,0xfe,0xff,0xf2,0xff,0xe8,0xff,0x01,0x00,0x05,0x00,0x09,0x00,0x0d,0x00,0xf8,0xff,0xf2,0xff,0xd3,0xff,0x02,0x00,0x47,0x00,0x14,0x00,0xe9,0xff,0xe2,0xff,0x04,0x00,0x0e,0x00,0xf0,0xff,0x03,0x00,0xeb,0xff,0x0b,0x00,0x0e,0x00,0xf2,0xff,0x0d,0x00,0xff,0xff,0xf8,0xff,0x01,0x00,0xe7,0xff,0xfc,0xff,0xfb,0xff,0x04,0x00,0x07,0x00,0xfe,0xff,0x0e,0x00,0xeb,0xff,0xf9,0xff,0x11,0x00,0x03,0x00,0xf7,0xff,0xf7,0xff,0xe5,0xff,0xf3,0xff,0x13,0x00,0x31,0x00,0x14,0x00,0xe5,0xff,0xeb,0xff,0x15,0x00,0x0c,0x00,0xf6,0xff,0xfc,0xff,0xe2,0xff,0x03,0x00,0x12,0x00,0xef,0xff,0x1a,0x00,0x12,0x00,0x09,0x00,0x16,0x00,0x04,0x00,0xf0,0xff,0xfe,0xff,0xfd,0xff,0x04,0x00,0xfb,0xff,0x19,0x00,0x07,0x00,0xde,0xff,0x06,0x00,0x27,0x00,0xd0,0xff,0xdd,0xff,0x2f,0x00,0x12,0x00,0xf6,0xff,0xec,0xff,0xf9,0xff,0x10,0x00,0xfd,0xff,0xf9,0xff,0x06,0x00,0x08,0x00,0x01,0x00,0x04,0x00,0xfe,0xff,0xff,0xff,0xfe,0xff,0x03,0x00,0x01,0x00,0xfb,0xff,0x03,0x00,0xfe,0xff,0xf7,0xff,0x01,0x00,0xfd,0xff,0xfd,0xff,0xf9,0xff,0x08,0x00,0x05,0x00,0xe3,0xff,0x1e,0x00,0x03,0x00,0xb7,0xff,0x13,0x00,0x43,0x00,0xf6,0xff,0xea,0xff,0xf0,0xff,0x0d,0x00,0x10,0x00,0xf8,0xff,0xf7,0xff,0xfa,0xff,0xfa,0xff,0x01,0x00,0x01,0x00,0xff,0xff,0x04,0x00,0xfb,0xff,0x06,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x04,0x00,0x02,0x00,0xfa,0xff,0xfd,0xff,0xfc,0xff,0xfd,0xff,0x02,0x00,0x0b,0x00,0xe9,0xff,0x1f,0x00,0xf0,0xff,0xee,0xff,0x3e,0x00,0x18,0x00,0xd9,0xff,0xf4,0xff,0x03,0x00,0x19,0x00,0xff,0xff,0xfe,0xff,0xfe,0xff,0xfa,0xff,0xf9,0xff,0x07,0x00,0xfc,0xff,0xfe,0xff,0x03,0x00,0x02,0x00,0xfc,0xff,0x08,0x00,0x04,0x00,0x05,0x00,0x04,0x00,0x07,0x00,0xfd,0xff,0xfd,0xff,0x05,0x00,0x01,0x00,0x01,0x00,0xdc,0xff,0x18,0x00,0x34,0x00,0xbd,0xff,0xbc,0xff,0x39,0x00,0x20,0x00,0xfd,0xff,0xf4,0xff,0xfa,0xff,0x03,0x00,0x00,0x00,0xff,0xff,0xfc,0xff,0x03,0x00,0xfc,0xff,0xfa,0xff,0x04,0x00,0x02,0x00,0xfb,0xff,0xfe,0xff,0xfd,0xff,0x01,0x00,0xff,0xff,0x02,0x00,0x07,0x00,0x07,0x00,0x08,0x00,0x01,0x00,0xfa,0xff,0xfe,0xff,0xf7,0xff,0xed,0xff,0x2e,0x00,0xee,0xff,0xca,0xff,0x1f,0x00,0x30,0x00,0xea,0xff,0xf4,0xff,0xfd,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x04,0x00,0x02,0x00,0x03,0x00,0x06,0x00,0x02,0x00,0x03,0x00,0xff,0xff,0x01,0x00,0x00,0x00,0x02,0x00,0x03,0x00,0x01,0x00,0x03,0x00,0x03,0x00,0xfe,0xff,0x00,0x00,0x01,0x00,0x06,0x00,0x0c,0x00,0x19,0x00,0xbc,0xff,0x0d,0x00,0x5f,0x00,0xf0,0xff,0xc0,0xff,0xfd,0xff,0x03,0x00,0x05,0x00,0x07,0x00,0xfd,0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x05,0x00,0xff,0xff,0xfd,0xff,0x03,0x00,0x01,0x00,0x01,0x00,0x03,0x00,0x00,0x00,0xff,0xff,0xf9,0xff,0xf7,0xff,0xf8,0xff,0xfc,0xff,0x03,0x00,0x02,0x00,0x09,0x00,0xe0,0xff,0xe8,0xff,0xe8,0xff,0x04,0x00,0xf2,0xff,0xe8,0xff,0xf7,0xff,0xf6,0xff,0xff,0xff,0xf2,0xff,0xf7,0xff,0xf7,0xff,0x06,0x00,0xff,0xff,0x05,0x00,0xfc,0xff,0xf9,0xff,0x0d,0x00,0x00,0x00,0xfe,0xff,0xfc,0xff,0xfb,0xff,0xeb,0xff,0xe6,0xff,0x05,0x00,0x06,0x00,0x19,0x00,0x25,0x00,0x36,0x00,0x27,0x00,0x07,0x00,0x1e,0x00,0xfb,0xff,0x04,0x00,0x06,0x00,0xf7,0xff,0x09,0x00,0x08,0x00,0xf1,0xff,0xff,0xff,0xff,0xff,0xfa,0xff,0xf6,0xff,0xf5,0xff,0xfb,0xff,0xff,0xff,0x01,0x00,0x06,0x00,0xf5,0xff,0xf0,0xff,0xec,0xff,0xfa,0xff,0xec,0xff,0xf2,0xff,0xf5,0xff,0xf2,0xff,0xfb,0xff,0x06,0x00,0x05,0x00,0x2a,0x00,0x29,0x00,0x25,0x00,0x22,0x00,0x1a,0x00,0xfe,0xff,0x0d,0x00,0x00,0x00,0xf6,0xff,0xf9,0xff,0x04,0x00,0x03,0x00,0x01,0x00,0xf6,0xff,0xfa,0xff,0xfb,0xff,0x09,0x00,0xf2,0xff,0xf3,0xff,0xea,0xff,0xef,0xff,0xfd,0xff,0xe8,0xff,0xf7,0xff,0xe5,0xff,0xeb,0xff,0xee,0xff,0xfb,0xff,0xfc,0xff,0xfd,0xff,0xfb,0xff,0x0c,0x00,0x15,0x00,0x1d,0x00,0x27,0x00,0x11,0x00,0x1a,0x00,0x02,0x00,0x06,0x00,0xf8,0xff,0xfc,0xff,0xf0,0xff,0xf4,0xff,0xf3,0xff,0xf9,0xff,0xfa,0xff,0x02,0x00,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0xff,0x07,0x00,0x02,0x00,0x12,0x00,0x02,0x00,0xfe,0xff,0x00,0x00,0xfd,0xff,0x02,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x0f,0x00,0x02,0x00,0x0d,0x00,0x08,0x00,0x08,0x00,0x02,0x00,0x06,0x00,0xf4,0xff,0xff,0xff,0xea,0xff,0xe6,0xff,0xe9,0xff,0xe8,0xff,0xe0,0xff,0xef,0xff,0xf2,0xff,0xf7,0xff,0xf3,0xff,0xea,0xff,0xe2,0xff,0xdc,0xff,0xf0,0xff,0xfc,0xff,0x0b,0x00,0x10,0x00,0x13,0x00,0x0f,0x00,0x11,0x00,0x15,0x00,0x11,0x00,0x0f,0x00,0x13,0x00,0x11,0x00,0x0e,0x00,0x0b,0x00,0x09,0x00,0xfd,0xff,0x03,0x00,0xe9,0xff,0xf0,0xff,0x03,0x00,0xed,0xff,0xec,0xff,0xfc,0xff,0xf6,0xff,0xf1,0xff,0xf1,0xff,0xf5,0xff,0xf3,0xff,0xf5,0xff,0xec,0xff,0xe1,0xff,0xee,0xff,0xf1,0xff,0xfe,0xff,0x00,0x00,0x0d,0x00,0x11,0x00,0x13,0x00,0x16,0x00,0x15,0x00,0x11,0x00,0x11,0x00,0x1a,0x00,0x0d,0x00,0x1a,0x00,0x07,0x00,0x05,0x00,0xfc,0xff,0xfc,0xff,0xe6,0xff,0x00,0x00,0xff,0xff,0xf9,0xff,0x05,0x00,0x04,0x00,0x08,0x00,0x09,0x00,0x06,0x00,0x02,0x00,0xfe,0xff,0x04,0x00,0x04,0x00,0x09,0x00,0xff,0xff,0xfe,0xff,0xfb,0xff,0xfe,0xff,0x03,0x00,0x09,0x00,0x1d,0x00,0x20,0x00,0x1a,0x00,0xf9,0xff,0xd4,0xff,0xd1,0xff,0xf1,0xff,0xff,0xff,0x10,0x00,0x04,0x00,0xfc,0xff,0xfa,0xff,0xfb,0xff,0x03,0x00,0x02,0x00,0x03,0x00,0x03,0x00,0x0b,0x00,0x03,0x00,0x0a,0x00,0x00,0x00,0xfe,0xff,0xfc,0xff,0xf8,0xff,0xfa,0xff,0xf7,0xff,0xf9,0xff,0xfb,0xff,0xfc,0xff,0xf9,0xff,0xfd,0xff,0xfb,0xff,0x04,0x00,0x0b,0x00,0x18,0x00,0x1d,0x00,0x11,0x00,0x02,0x00,0xf9,0xff,0xf6,0xff,0xed,0xff,0xf1,0xff,0xf0,0xff,0xfa,0xff,0xfa,0xff,0x05,0x00,0x04,0x00,0x07,0x00,0xf7,0xff,0x00,0x00,0x01,0x00,0xfe,0xff,0xff,0xff,0xfc,0xff,0xfd,0xff,0xf4,0xff,0xf6,0xff,0xf1,0xff,0xf9,0xff,0xfe,0xff,0x06,0x00,0x03,0x00,0xfd,0xff,0xfb,0xff,0xe9,0xff,0xef,0xff,0xff,0xff,0x24,0x00,0x3a,0x00,0x2f,0x00,0x0e,0x00,0xf3,0xff,0xe0,0xff,0xe8,0xff,0xf0,0xff,0xfd,0xff,0xfc,0xff,0x01,0x00,0xe5,0xff,0xe3,0xff,0x0e,0x00,0x3a,0x00,0x21,0x00,0x1b,0x00,0x05,0x00,0xfc,0xff,0xfe,0xff,0x00,0x00,0x00,0x00,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0x02,0x00,0x00,0x00,0x02,0x00,0xfe,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x01,0x00,0x01,0x00,0xfe,0xff,0xff,0xff,0x10,0x00,0x32,0x00,0x33,0x00,0xe7,0xff,0xd1,0xff,0xc8,0xff,0xdc,0xff,0xfe,0xff,0x03,0x00,0x08,0x00,0x05,0x00,0x03,0x00,0xfe,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x01,0x00,0xff,0xff,0x03,0x00,0x00,0x00,0x04,0x00,0xfe,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0x00,0x00,0xfc,0xff,0x0e,0x00,0x25,0x00,0x09,0x00,0xc4,0xff,0xdd,0xff,0xfa,0xff,0x04,0x00,0x00,0x00,0xfa,0xff,0x04,0x00,0x09,0x00,0x05,0x00,0x03,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x01,0x00,0x01,0x00,0xff,0xff,0x00,0x00,0x01,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x05,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xfe,0xff,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0xfd,0xff,0x07,0x00,0x00,0x00,0xfe,0xff,0x02,0x00,0x01,0x00,0x02,0x00,0xfe,0xff,0xf6,0xff,0xf8,0xff,0x00,0x00,0xff,0xff,0x02,0x00,0x01,0x00,0x0b,0x00,0x05,0x00,0x05,0x00,0x01,0x00,0x07,0x00,0xfe,0xff,0x04,0x00,0xfb,0xff,0xfc,0xff,0x03,0x00,0x06,0x00,0x00,0x00,0x09,0x00,0x02,0x00,0xf4,0xff,0xfc,0xff,0xcc,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfc,0xff,0x03,0x00,0x00,0x00,0x04,0x00,0xfe,0xff,0x03,0x00,0xfc,0xff,0x04,0x00,0x04,0x00,0x04,0x00,0x03,0x00,0x08,0x00,0x09,0x00,0x0f,0x00,0x11,0x00,0x0b,0x00,0x0e,0x00,0x0b,0x00,0x10,0x00,0x0f,0x00,0x19,0x00,0x1c,0x00,0x18,0x00,0x03,0x00,0xf8,0xff,0xf3,0xff,0xdd,0xff,0xe8,0xff,0xb6,0xff,0xfc,0xff,0xfe,0xff,0xec,0xff,0xf9,0xff,0x07,0x00,0xfa,0xff,0x06,0x00,0x00,0x00,0xff,0xff,0x02,0x00,0x09,0x00,0x04,0x00,0x08,0x00,0x06,0x00,0x0c,0x00,0x07,0x00,0x12,0x00,0x06,0x00,0x0b,0x00,0x00,0x00,0x0a,0x00,0x04,0x00,0x15,0x00,0x1a,0x00,0x1f,0x00,0x08,0x00,0xff,0xff,0xef,0xff,0xe7,0xff,0xe2,0xff,0xe5,0xff,0xd7,0xff,0x39,0x00,0x14,0x00,0x1e,0x00,0x15,0x00,0x19,0x00,0x1a,0x00,0x14,0x00,0x1e,0x00,0x0c,0x00,0x0b,0x00,0xfe,0xff,0x0e,0x00,0x19,0x00,0x01,0x00,0x16,0x00,0x0b,0x00,0x08,0x00,0x0c,0x00,0x01,0x00,0x09,0x00,0x0c,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x0a,0x00,0x1a,0x00,0x19,0x00,0x20,0x00,0x00,0x00,0x14,0x00,0xfd,0xff,0x18,0x00,0x17,0x00,0x29,0x00,0x0f,0x00,0x1c,0x00,0x07,0x00,0x0f,0x00,0x12,0x00,0x02,0x00,0xed,0xff,0x07,0x00,0x0b,0x00,0x08,0x00,0x03,0x00,0x07,0x00,0x10,0x00,0xf9,0xff,0x14,0x00,0x07,0x00,0x07,0x00,0x05,0x00,0x13,0x00,0x15,0x00,0x01,0x00,0x14,0x00,0x0d,0x00,0x08,0x00,0x06,0x00,0x08,0x00,0x09,0x00,0x14,0x00,0xf6,0xff,0x14,0x00,0x25,0x00,0x10,0x00,0x0a,0x00,0x14,0x00,0x1d,0x00,0x0d,0x00,0x07,0x00,0x05,0x00,0x0e,0x00,0xed,0xff,0xf3,0xff,0x0e,0x00,0x16,0x00,0x0f,0x00,0x0f,0x00,0x10,0x00,0x0e,0x00,0x09,0x00,0x0d,0x00,0x17,0x00,0xf5,0xff,0x13,0x00,0xfc,0xff,0x06,0x00,0x0c,0x00,0x05,0x00,0x0d,0x00,0x0c,0x00,0x10,0x00,0xed,0xff,0x08,0x00,0xf6,0xff,0xff,0xff,0xee,0xff,0x07,0x00,0xf2,0xff,0xe8,0xff,0xfa,0xff,0x02,0x00,0xf9,0xff,0xf7,0xff,0xef,0xff,0xff,0xff,0xf7,0xff,0x0c,0x00,0xfd,0xff,0xfe,0xff,0x03,0x00,0xf2,0xff,0xee,0xff,0xdf,0xff,0xe5,0xff,0xf7,0xff,0x25,0x00,0x2f,0x00,0x42,0x00,0x1c,0x00,0x10,0x00,0xff,0xff,0xf1,0xff,0xee,0xff,0x1b,0x00,0x0a,0x00,0x06,0x00,0x04,0x00,0x13,0x00,0x07,0x00,0x08,0x00,0xf6,0xff,0x05,0x00,0xff,0xff,0xfb,0xff,0xf0,0xff,0x08,0x00,0x00,0x00,0xfc,0xff,0xec,0xff,0xf7,0xff,0xf6,0xff,0xf0,0xff,0xee,0xff,0xdb,0xff,0xe6,0xff,0xf1,0xff,0xff,0xff,0x1e,0x00,0x3b,0x00,0x40,0x00,0x2f,0x00,0x0b,0x00,0xf0,0xff,0xe3,0xff,0x07,0x00,0xfa,0xff,0x00,0x00,0x03,0x00,0x0c,0x00,0x0c,0x00,0xfe,0xff,0x18,0x00,0x11,0x00,0x17,0x00,0xf4,0xff,0xf6,0xff,0x09,0x00,0xfb,0xff,0xfd,0xff,0xfc,0xff,0xf2,0xff,0xf6,0xff,0xfd,0xff,0xec,0xff,0xf1,0xff,0xe2,0xff,0xde,0xff,0xec,0xff,0x04,0x00,0x06,0x00,0x2a,0x00,0x21,0x00,0x22,0x00,0xf6,0xff,0xde,0xff,0xf0,0xff,0x00,0x00,0xf3,0xff,0xfa,0xff,0xf9,0xff,0x06,0x00,0x16,0x00,0x14,0x00,0xfa,0xff,0xe3,0xff,0xc7,0xff,0xd1,0xff,0x13,0x00,0x3a,0x00,0x19,0x00,0x0d,0x00,0xfa,0xff,0x05,0x00,0xfa,0xff,0x00,0x00,0x08,0x00,0x0d,0x00,0x0f,0x00,0x0b,0x00,0xff,0xff,0xfe,0xff,0x02,0x00,0x04,0x00,0xfd,0xff,0x09,0x00,0x02,0x00,0x11,0x00,0x0e,0x00,0x10,0x00,0x0c,0x00,0x09,0x00,0x02,0x00,0x13,0x00,0x15,0x00,0x07,0x00,0xf8,0xff,0xd4,0xff,0x82,0xff,0x8e,0xff,0xf4,0xff,0x3f,0x00,0x21,0x00,0xf7,0xff,0x05,0x00,0x0a,0x00,0xe7,0xff,0xeb,0xff,0xfe,0xff,0xf1,0xff,0xf5,0xff,0x00,0x00,0x09,0x00,0xfe,0xff,0x07,0x00,0xfe,0xff,0xf5,0xff,0xea,0xff,0xf5,0xff,0x0e,0x00,0x15,0x00,0x03,0x00,0x05,0x00,0xf9,0xff,0xf3,0xff,0x18,0x00,0x0e,0x00,0x13,0x00,0x04,0x00,0x00,0x00,0xae,0xff,0xad,0xff,0x0c,0x00,0x3a,0x00,0x2c,0x00,0x0b,0x00,0xff,0xff,0x0c,0x00,0x04,0x00,0xf2,0xff,0xfd,0xff,0xec,0xff,0x01,0x00,0xfc,0xff,0x07,0x00,0x0e,0x00,0x10,0x00,0x04,0x00,0xfd,0xff,0xeb,0xff,0x00,0x00,0x09,0x00,0x03,0x00,0x1a,0x00,0x0b,0x00,0x17,0x00,0xf2,0xff,0x07,0x00,0xfa,0xff,0xfc,0xff,0xea,0xff,0xe7,0xff,0xe0,0xff,0xe9,0xff,0xf4,0xff,0x00,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0xfa,0xff,0xf6,0xff,0xf6,0xff,0xf7,0xff,0xf7,0xff,0xfe,0xff,0xff,0xff,0x05,0x00,0x02,0x00,0x00,0x00,0xf6,0xff,0xf8,0xff,0xf1,0xff,0xef,0xff,0xea,0xff,0xf3,0xff,0xf8,0xff,0xf4,0xff,0x00,0x00,0x0b,0x00,0xfd,0xff,0xec,0xff,0xdd,0xff,0xe2,0xff,0xe3,0xff,0x00,0x00,0xf9,0xff,0xfd,0xff,0xff,0xff,0x08,0x00,0x07,0x00,0x01,0x00,0xf8,0xff,0x03,0x00,0xf5,0xff,0xfa,0xff,0xfe,0xff,0xfc,0xff,0x00,0x00,0xfc,0xff,0x00,0x00,0x03,0x00,0xfe,0xff,0xfa,0xff,0xf6,0xff,0xec,0xff,0xf4,0xff,0xfe,0xff,0xf8,0xff,0x0a,0x00,0xf5,0xff,0x03,0x00,0xee,0xff,0xe8,0xff,0xe8,0xff,0xf1,0xff,0x08,0x00,0x1c,0x00,0x18,0x00,0x1f,0x00,0x06,0x00,0x01,0x00,0x06,0x00,0x00,0x00,0x10,0x00,0xfb,0xff,0x09,0x00,0xfd,0xff,0x06,0x00,0x02,0x00,0x05,0x00,0x08,0x00,0x08,0x00,0x0e,0x00,0x11,0x00,0x0a,0x00,0x03,0x00,0x05,0x00,0x04,0x00,0x07,0x00,0x13,0x00,0x05,0x00,0x0b,0x00,0x03,0x00,0x01,0x00,0x05,0x00,0x05,0x00,0x07,0x00,0x03,0x00,0x03,0x00,0xfd,0xff,0xf8,0xff,0xf8,0xff,0xf6,0xff,0xfe,0xff,0xfe,0xff,0x0b,0x00,0x07,0x00,0xf4,0xff,0xfa,0xff,0xfe,0xff,0x19,0x00,0x12,0x00,0x0c,0x00,0x06,0x00,0xf3,0xff,0xf7,0xff,0xff,0xff,0x06,0x00,0x04,0x00,0xff,0xff,0xf8,0xff,0xfc,0xff,0xf8,0xff,0x05,0x00,0x06,0x00,0xff,0xff,0x09,0x00,0x02,0x00,0x04,0x00,0x05,0x00,0x03,0x00,0xf6,0xff,0xfa,0xff,0xfd,0xff,0xfd,0xff,0x00,0x00,0x01,0x00,0xf8,0xff,0xe8,0xff,0xde,0xff,0xef,0xff,0x08,0x00,0x1a,0x00,0x25,0x00,0x1c,0x00,0x0e,0x00,0x01,0x00,0x05,0x00,0x05,0x00,0x08,0x00,0xfb,0xff,0xfc,0xff,0x00,0x00,0xf8,0xff,0x02,0x00,0x03,0x00,0x04,0x00,0xfc,0xff,0x05,0x00,0xfd,0xff,0x00,0x00,0xfb,0xff,0x07,0x00,0xf7,0xff,0x06,0x00,0x07,0x00,0x0c,0x00,0x01,0x00,0xfe,0xff,0xee,0xff,0xde,0xff,0xed,0xff,0xf5,0xff,0x0a,0x00,0x0a,0x00,0x16,0x00,0x12,0x00,0x0a,0x00,0x0f,0x00,0x07,0x00,0x02,0x00,0xfb,0xff,0xf8,0xff,0xfa,0xff,0x05,0x00,0xff,0xff,0x09,0x00,0xff,0xff,0x03,0x00,0x07,0x00,0xff,0xff,0x0c,0x00,0x04,0x00,0x05,0x00,0x05,0x00,0x0a,0x00,0x1b,0x00,0x1a,0x00,0x10,0x00,0x0c,0x00,0x03,0x00,0x03,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0xfe,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xf9,0xff,0xf9,0xff,0xfc,0xff,0xfa,0xff,0xfc,0xff,0xf4,0xff,0xfe,0xff,0xfc,0xff,0x00,0x00,0xfe,0xff,0x04,0x00,0x08,0x00,0x04,0x00,0xfb,0xff,0xfd,0xff,0xfe,0xff,0xfd,0xff,0x09,0x00,0x13,0x00,0x19,0x00,0x18,0x00,0x10,0x00,0x10,0x00,0x0b,0x00,0x05,0x00,0x08,0x00,0x06,0x00,0x04,0x00,0x03,0x00,0x01,0x00,0x01,0x00,0xfc,0xff,0x02,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0xfe,0xff,0x05,0x00,0x04,0x00,0x04,0x00,0xff,0xff,0x02,0x00,0xfb,0xff,0xfc,0xff,0xf6,0xff,0xfd,0xff,0x01,0x00,0xfd,0xff,0x00,0x00,0x0e,0x00,0x11,0x00,0x11,0x00,0x14,0x00,0x06,0x00,0x09,0x00,0x09,0x00,0x04,0x00,0x06,0x00,0x04,0x00,0x05,0x00,0x03,0x00,0x08,0x00,0x01,0x00,0x07,0x00,0x06,0x00,0x07,0x00,0x06,0x00,0x07,0x00,0x03,0x00,0x02,0x00,0x05,0x00,0x08,0x00,0x04,0x00,0xff,0xff,0x00,0x00,0x03,0x00,0x05,0x00,0x01,0x00,0xfc,0xff,0xf0,0xff,0xf0,0xff,0xf6,0xff,0xfc,0xff,0x03,0x00,0xfe,0xff,0xfc,0xff,0xfa,0xff,0xfd,0xff,0xfd,0xff,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0xfe,0xff,0x00,0x00,0x04,0x00,0x04,0x00,0x03,0x00,0x00,0x00,0xff,0xff,0x02,0x00,0x08,0x00,0x02,0x00,0xff,0xff,0xff,0xff,0x02,0x00,0xfe,0xff,0xf1,0xff,0xed,0xff,0xeb,0xff,0xf3,0xff,0xf8,0xff,0xfa,0xff,0xfe,0xff,0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x03,0x00,0x02,0x00,0x01,0x00,0xff,0xff,0xfc,0xff,0xfc,0xff,0xfe,0xff,0x00,0x00,0xfe,0xff,0xf9,0xff,0xf8,0xff,0xf8,0xff,0xfa,0xff,0xfb,0xff,0xfc,0xff,0x00,0x00,0xfd,0xff,0xfd,0xff,0xf9,0xff,0xfa,0xff,0xf2,0xff,0xf1,0xff,0xf7,0xff,0xfe,0xff,0x00,0x00,0x01,0x00,0xfd,0xff,0xff,0xff,0x02,0x00,0x06,0x00,0x07,0x00,0x06,0x00,0x04,0x00,0x05,0x00,0x01,0x00,0x01,0x00,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfb,0xff,0xf5,0xff,0xf6,0xff,0xf6,0xff,0xfb,0xff,0xff,0xff,0xfb,0xff,0xfd,0xff,0xfc,0xff,0xc6,0xff,0xdb,0xff,0x5f,0x00,0x2a,0x00,0xed,0xff,0xe1,0xff,0xed,0xff,0x11,0x00,0x1c,0x00,0xde,0xff,0xd5,0xff,0xf5,0xff,0xfa,0xff,0x04,0x00,0xfd,0xff,0x00,0x00,0x02,0x00,0xfd,0xff,0xf4,0xff,0x07,0x00,0xf8,0xff,0xff,0xff,0x03,0x00,0x0f,0x00,0x00,0x00,0xf8,0xff,0x09,0x00,0x02,0x00,0xf9,0xff,0x07,0x00,0xfb,0xff,0x03,0x00,0xc1,0xff,0xe1,0xff,0x7b,0x00,0x4f,0x00,0xda,0xff,0xbd,0xff,0xf7,0xff,0x12,0x00,0x32,0x00,0xf1,0xff,0xe6,0xff,0x06,0x00,0x13,0x00,0x06,0x00,0x01,0x00,0x00,0x00,0xfa,0xff,0x0d,0x00,0xfa,0xff,0x00,0x00,0x04,0x00,0xef,0xff,0xfb,0xff,0xfd,0xff,0x06,0x00,0xfb,0xff,0x04,0x00,0x0a,0x00,0x15,0x00,0xfa,0xff,0xfb,0xff,0x0d,0x00,0xe4,0xff,0xf5,0xff,0x4f,0x00,0x2a,0x00,0xd6,0xff,0xcd,0xff,0x07,0x00,0x05,0x00,0x1c,0x00,0xfd,0xff,0xfd,0xff,0x0b,0x00,0x21,0x00,0xf0,0xff,0x0d,0x00,0xf3,0xff,0xff,0xff,0x02,0x00,0x01,0x00,0xfc,0xff,0xfe,0xff,0xf7,0xff,0x00,0x00,0xf0,0xff,0xfa,0xff,0x06,0x00,0xfa,0xff,0xf8,0xff,0xff,0xff,0xf6,0xff,0x0e,0x00,0xf2,0xff,0xf6,0xff,0xf5,0xff,0xf0,0xff,0xe2,0xff,0xe4,0xff,0xe8,0xff,0xe9,0xff,0xeb,0xff,0xfd,0xff,0x04,0x00,0xf6,0xff,0x06,0x00,0xf4,0xff,0xec,0xff,0xfa,0xff,0xee,0xff,0x01,0x00,0x02,0x00,0x02,0x00,0x05,0x00,0xfd,0xff,0x00,0x00,0xf5,0xff,0x00,0x00,0x05,0x00,0xfb,0xff,0x18,0x00,0xfd,0xff,0x12,0x00,0x06,0x00,0x01,0x00,0xfa,0xff,0xf2,0xff,0xf8,0xff,0xe9,0xff,0xfd,0xff,0xf0,0xff,0x06,0x00,0x03,0x00,0x00,0x00,0xf2,0xff,0x00,0x00,0x02,0x00,0xf8,0xff,0xf8,0xff,0x00,0x00,0xf1,0xff,0x02,0x00,0xf9,0xff,0xf8,0xff,0xfa,0xff,0xf2,0xff,0xf4,0xff,0xed,0xff,0xf2,0xff,0x00,0x00,0x05,0x00,0x02,0x00,0xfd,0xff,0x0f,0x00,0xfb,0xff,0x0a,0x00,0x02,0x00,0x06,0x00,0xf8,0xff,0xfd,0xff,0xff,0xff,0x06,0x00,0x13,0x00,0x0b,0x00,0xfc,0xff,0x02,0x00,0xfb,0xff,0xf9,0xff,0xf8,0xff,0x06,0x00,0x0e,0x00,0x0d,0x00,0x05,0x00,0xff,0xff,0xfa,0xff,0xfc,0xff,0xf9,0xff,0xf7,0xff,0xed,0xff,0x06,0x00,0xff,0xff,0xf9,0xff,0xef,0xff,0xf2,0xff,0xfb,0xff,0xf1,0xff,0xf9,0xff,0x09,0x00,0xf1,0xff,0x0a,0x00,0x03,0x00,0x0f,0x00,0x00,0x00,0x06,0x00,0xec,0xff,0xe5,0xff,0xdd,0xff,0xe6,0xff,0xf5,0xff,0xff,0xff,0x05,0x00,0x13,0x00,0x0f,0x00,0x1c,0x00,0x08,0x00,0x09,0x00,0x0e,0x00,0x00,0x00,0xfe,0xff,0xfb,0xff,0xfd,0xff,0x01,0x00,0x08,0x00,0x03,0x00,0xe7,0xff,0xee,0xff,0xe7,0xff,0xeb,0xff,0xe8,0xff,0xf4,0xff,0xfa,0xff,0x07,0x00,0xf6,0xff,0xf7,0xff,0xec,0xff,0xdd,0xff,0xe5,0xff,0xec,0xff,0x04,0x00,0x00,0x00,0x0e,0x00,0x0e,0x00,0x10,0x00,0x12,0x00,0x1c,0x00,0x13,0x00,0x0f,0x00,0x0c,0x00,0x0f,0x00,0x13,0x00,0x0d,0x00,0x0c,0x00,0x05,0x00,0x09,0x00,0x0c,0x00,0x05,0x00,0xf1,0xff,0xeb,0xff,0xe8,0xff,0xf0,0xff,0xf5,0xff,0xfa,0xff,0xfb,0xff,0x00,0x00,0xf3,0xff,0xe0,0xff,0xf5,0xff,0xe6,0xff,0xed,0xff,0x05,0x00,0x19,0x00,0x1c,0x00,0x11,0x00,0x10,0x00,0x05,0x00,0x03,0x00,0x0a,0x00,0xf9,0xff,0x05,0x00,0xfd,0xff,0x04,0x00,0x0b,0x00,0x0d,0x00,0x07,0x00,0x08,0x00,0xfe,0xff,0x05,0x00,0x09,0x00,0x0c,0x00,0xf8,0xff,0x01,0x00,0x04,0x00,0x0e,0x00,0x05,0x00,0x03,0x00,0x11,0x00,0x10,0x00,0x12,0x00,0xf2,0xff,0x00,0x00,0xf7,0xff,0x06,0x00,0x0b,0x00,0x15,0x00,0x03,0x00,0x12,0x00,0x07,0x00,0x0f,0x00,0x0b,0x00,0xff,0xff,0x03,0x00,0xe9,0xff,0xe8,0xff,0xeb,0xff,0xff,0xff,0xf9,0xff,0x13,0x00,0xff,0xff,0x15,0x00,0xfc,0xff,0xea,0xff,0xf9,0xff,0xf9,0xff,0x0f,0x00,0x10,0x00,0x08,0x00,0xf9,0xff,0x00,0x00,0x05,0x00,0xf3,0xff,0xfe,0xff,0xf8,0xff,0xeb,0xff,0xf5,0xff,0xf4,0xff,0xff,0xff,0x0c,0x00,0x0b,0x00,0x13,0x00,0x16,0x00,0x15,0x00,0x1c,0x00,0x11,0x00,0xf5,0xff,0xf4,0xff,0xdd,0xff,0xe3,0xff,0xf4,0xff,0x01,0x00,0x17,0x00,0x1b,0x00,0x0f,0x00,0xec,0xff,0xe2,0xff,0xe6,0xff,0x05,0x00,0xfe,0xff,0x07,0x00,0x02,0x00,0x08,0x00,0xff,0xff,0xe5,0xff,0xfb,0xff,0xf4,0xff,0xfc,0xff,0xe6,0xff,0xf2,0xff,0xf9,0xff,0x00,0x00,0x04,0x00,0x05,0x00,0x0b,0x00,0x1c,0x00,0x27,0x00,0x10,0x00,0x17,0x00,0xef,0xff,0xe5,0xff,0xe8,0xff,0xf5,0xff,0xfa,0xff,0x1d,0x00,0x0c,0x00,0x12,0x00,0x04,0x00,0xe7,0xff,0xf4,0xff,0xec,0xff,0xf8,0xff,0xf4,0xff,0x00,0x00,0xd6,0xff,0xed,0xff,0xea,0xff,0x0f,0x00,0x1e,0x00,0x06,0x00,0xe8,0xff,0xee,0xff,0xfd,0xff,0x0c,0x00,0x0c,0x00,0x12,0x00,0xf3,0xff,0x06,0x00,0x0a,0x00,0xf5,0xff,0xfd,0xff,0x0a,0x00,0xf7,0xff,0x0a,0x00,0xff,0xff,0x0a,0x00,0x0d,0x00,0x0b,0x00,0xfd,0xff,0x11,0x00,0x06,0x00,0x0f,0x00,0x1d,0x00,0x17,0x00,0x0c,0x00,0x0d,0x00,0xcf,0xff,0xf0,0xff,0xec,0xff,0x02,0x00,0x2a,0x00,0x20,0x00,0x14,0x00,0x04,0x00,0x05,0x00,0xfd,0xff,0xfd,0xff,0xf8,0xff,0x0b,0x00,0x04,0x00,0x00,0x00,0x0e,0x00,0x02,0x00,0xf1,0xff,0x0c,0x00,0x0c,0x00,0xfe,0xff,0x12,0x00,0xfd,0xff,0x07,0x00,0xfb,0xff,0xfe,0xff,0x00,0x00,0x01,0x00,0xf9,0xff,0xf8,0xff,0xfe,0xff,0xf3,0xff,0xe1,0xff,0xe3,0xff,0xf4,0xff,0x10,0x00,0x05,0x00,0x15,0x00,0x22,0x00,0x03,0x00,0x0d,0x00,0x03,0x00,0xf7,0xff,0xf1,0xff,0x08,0x00,0xf6,0xff,0x03,0x00,0x06,0x00,0xff,0xff,0x02,0x00,0xfc,0xff,0xf0,0xff,0x16,0x00,0xf8,0xff,0x01,0x00,0xeb,0xff,0x03,0x00,0xe8,0xff,0xee,0xff,0xf3,0xff,0xe9,0xff,0xed,0xff,0xfd,0xff,0xfa,0xff,0x06,0x00,0x00,0x00,0xdd,0xff,0xff,0xff,0xe5,0xff,0xe4,0xff,0xea,0xff,0xfd,0xff,0xf4,0xff,0xfc,0xff,0x02,0x00,0xec,0xff,0xf6,0xff,0xea,0xff,0x06,0x00,0x00,0x00,0x17,0x00,0x14,0x00,0x0a,0x00,0x0a,0x00,0xfd,0xff,0x13,0x00,0xf3,0xff,0xf6,0xff,0x0a,0x00,0xef,0xff,0xf9,0xff,0xf1,0xff,0x09,0x00,0xfc,0xff,0x00,0x00,0x00,0x00,0x16,0x00,0xf1,0xff,0xf0,0xff,0xe0,0xff,0xf8,0xff,0x04,0x00,0xe9,0xff,0xeb,0xff,0xfd,0xff,0x0a,0x00,0xfe,0xff,0xfd,0xff,0xed,0xff,0x02,0x00,0x05,0x00,0x0c,0x00,0x01,0x00,0x0c,0x00,0x21,0x00,0x17,0x00,0x08,0x00,0x14,0x00,0x1a,0x00,0x01,0x00,0xf3,0xff,0xf4,0xff,0x0b,0x00,0x0c,0x00,0xfb,0xff,0xff,0xff,0xfc,0xff,0x06,0x00,0x13,0x00,0xeb,0xff,0xfe,0xff,0xfa,0xff,0xe9,0xff,0xfb,0xff,0xf0,0xff,0xf2,0xff,0x17,0x00,0x04,0x00,0x0e,0x00,0x0c,0x00,0x09,0x00,0x07,0x00,0xf1,0xff,0xfb,0xff,0x01,0x00,0x0b,0x00,0x1c,0x00,0x01,0x00,0x0e,0x00,0x0f,0x00,0xf7,0xff,0x03,0x00,0x02,0x00,0xfb,0xff,0xf1,0xff,0xfc,0xff,0x08,0x00,0x06,0x00,0x11,0x00,0x08,0x00,0x00,0x00,0x09,0x00,0xf6,0xff,0x0a,0x00,0x00,0x00,0xf9,0xff,0x0f,0x00,0x06,0x00,0xf7,0xff,0x07,0x00,0xf5,0xff,0xe1,0xff,0xf3,0xff,0x29,0x00,0x48,0x00,0x2b,0x00,0xff,0xff,0xe4,0xff,0xce,0xff,0xe2,0xff,0xed,0xff,0x05,0x00,0xff,0xff,0x03,0x00,0x0b,0x00,0x09,0x00,0x0b,0x00,0x05,0x00,0x04,0x00,0xfd,0xff,0xf4,0xff,0x0d,0x00,0x05,0x00,0xfb,0xff,0xec,0xff,0x03,0x00,0x00,0x00,0xf4,0xff,0xff,0xff,0x00,0x00,0xfc,0xff,0xfb,0xff,0xf1,0xff,0xf9,0xff,0x14,0x00,0x26,0x00,0x18,0x00,0xef,0xff,0xdd,0xff,0xe0,0xff,0xf9,0xff,0x04,0x00,0x0d,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x0a,0x00,0x01,0x00,0x01,0x00,0xff,0xff,0xf9,0xff,0xfd,0xff,0x00,0x00,0x00,0x00,0x01,0x00,0xf6,0xff,0xf9,0xff,0xf9,0xff,0x08,0x00,0x04,0x00,0xfa,0xff,0xfc,0xff,0x0e,0x00,0xf4,0xff,0x03,0x00,0x19,0x00,0x22,0x00,0x02,0x00,0xda,0xff,0xca,0xff,0xde,0xff,0x00,0x00,0x27,0x00,0x23,0x00,0x1c,0x00,0x05,0x00,0x01,0x00,0xff,0xff,0xfe,0xff,0xfb,0xff,0xf4,0xff,0xf9,0xff,0xf8,0xff,0x01,0x00,0x0b,0x00,0x05,0x00,0x02,0x00,0xff,0xff,0xfe,0xff,0xfc,0xff,0x09,0x00,0x07,0x00,0x19,0x00,0x0a,0x00,0x17,0x00,0x16,0x00,0x22,0x00,0x24,0x00,0x24,0x00,0x22,0x00,0x16,0x00,0x1d,0x00,0x21,0x00,0x21,0x00,0x29,0x00,0x19,0x00,0x11,0x00,0x1b,0x00,0x14,0x00,0x1e,0x00,0x09,0x00,0x10,0x00,0x0c,0x00,0x07,0x00,0xfa,0xff,0xfa,0xff,0x07,0x00,0x0e,0x00,0x0a,0x00,0x05,0x00,0x0d,0x00,0x10,0x00,0x0d,0x00,0x13,0x00,0x18,0x00,0x0c,0x00,0x0d,0x00,0x10,0x00,0x18,0x00,0x09,0x00,0x11,0x00,0x08,0x00,0x01,0x00,0xfc,0xff,0xfe,0xff,0xfd,0xff,0xf0,0xff,0xe7,0xff,0xe3,0xff,0xea,0xff,0xf1,0xff,0x0a,0x00,0x08,0x00,0x07,0x00,0xfe,0xff,0x00,0x00,0xf7,0xff,0x04,0x00,0x00,0x00,0x08,0x00,0x10,0x00,0x0f,0x00,0x0a,0x00,0x03,0x00,0x04,0x00,0x15,0x00,0x10,0x00,0x05,0x00,0xf5,0xff,0xfa,0xff,0xeb,0xff,0xe2,0xff,0xd4,0xff,0xc5,0xff,0xbe,0xff,0xc8,0xff,0xbf,0xff,0xc6,0xff,0xc7,0xff,0xc4,0xff,0xb2,0xff,0xb7,0xff,0xe0,0xff,0xef,0xff,0xfd,0xff,0xf2,0xff,0xfe,0xff,0x02,0x00,0xfd,0xff,0x06,0x00,0x03,0x00,0x0e,0x00,0xf9,0xff,0xe3,0xff,0xf9,0xff,0xf0,0xff,0x04,0x00,0x11,0x00,0x03,0x00,0x0c,0x00,0x06,0x00,0x08,0x00,0x07,0x00,0x01,0x00,0x24,0x00,0x1f,0x00,0x24,0x00,0x18,0x00,0x0d,0x00,0x1c,0x00,0x04,0x00,0x0d,0x00,0xe9,0xff,0xec,0xff,0xe9,0xff,0xe2,0xff,0xe5,0xff,0xef,0xff,0xed,0xff,0xed,0xff,0xe3,0xff,0xeb,0xff,0xea,0xff,0xfb,0xff,0x0c,0x00,0xed,0xff,0x00,0x00,0xf6,0xff,0xfb,0xff,0x12,0x00,0x01,0x00,0x15,0x00,0x13,0x00,0x11,0x00,0x1b,0x00,0x1d,0x00,0x19,0x00,0x3c,0x00,0x2e,0x00,0x1b,0x00,0x22,0x00,0x1b,0x00,0xfa,0xff,0xe9,0xff,0xe4,0xff,0xe9,0xff,0xec,0xff,0xf1,0xff,0xdf,0xff,0xf9,0xff,0xfc,0xff,0xdf,0xff,0xe8,0xff,0xf3,0xff,0xff,0xff,0xf6,0xff,0x14,0x00,0xfb,0xff,0x0a,0x00,0x05,0x00,0xf3,0xff,0xf4,0xff,0x0b,0x00,0xfa,0xff,0x03,0x00,0x0b,0x00,0x0f,0x00,0x18,0x00,0x15,0x00,0x1e,0x00,0x1c,0x00,0x1c,0x00,0x0b,0x00,0xfa,0xff,0xee,0xff,0xd2,0xff,0xe9,0xff,0xee,0xff,0xf9,0xff,0xff,0xff,0x03,0x00,0xf8,0xff,0xf6,0xff,0xeb,0xff,0xf2,0xff,0xf4,0xff,0xf3,0xff,0xee,0xff,0x0c,0x00,0x19,0x00,0x05,0x00,0x01,0x00,0x1a,0x00,0x2a,0x00,0x0d,0x00,0x09,0x00,0x14,0x00,0x12,0x00,0x18,0x00,0x10,0x00,0x19,0x00,0x1b,0x00,0xfa,0xff,0x0a,0x00,0xf8,0xff,0x09,0x00,0xfe,0xff,0x03,0x00,0xfe,0xff,0xfa,0xff,0xf9,0xff,0xfc,0xff,0xe9,0xff,0xfa,0xff,0xf4,0xff,0xf7,0xff,0xef,0xff,0xfc,0xff,0xfa,0xff,0xf7,0xff,0x01,0x00,0x16,0x00,0x04,0x00,0x02,0x00,0x11,0x00,0x16,0x00,0x0b,0x00,0xfd,0xff,0xec,0xff,0x04,0x00,0xf3,0xff,0xf5,0xff,0xde,0xff,0xdf,0xff,0xd5,0xff,0xde,0xff,0xdf,0xff,0xe7,0xff,0xdb,0xff,0xde,0xff,0xea,0xff,0xea,0xff,0xeb,0xff,0xe0,0xff,0xf3,0xff,0xeb,0xff,0xfc,0xff,0xec,0xff,0xf3,0xff,0x02,0x00,0x08,0x00,0xfb,0xff,0x06,0x00,0x26,0x00,0x1a,0x00,0x13,0x00,0x07,0x00,0x22,0x00,0x0c,0x00,0x0c,0x00,0x04,0x00,0x03,0x00,0x08,0x00,0xfb,0xff,0xf4,0xff,0xec,0xff,0xe5,0xff,0xe5,0xff,0xf5,0xff,0xfd,0xff,0x07,0x00,0x0b,0x00,0x05,0x00,0x07,0x00,0x15,0x00,0x06,0x00,0x00,0x00,0x05,0x00,0x0b,0x00,0x06,0x00,0x01,0x00,0x08,0x00,0x07,0x00,0x01,0x00,0xfa,0xff,0xee,0xff,0x02,0x00,0x03,0x00,0xe5,0xff,0xe2,0xff,0xec,0xff,0xea,0xff,0xe3,0xff,0x10,0x00,0x16,0x00,0x27,0x00,0x0f,0x00,0xea,0xff,0xf9,0xff,0xf3,0xff,0x00,0x00,0x12,0x00,0xf6,0xff,0xfe,0xff,0x0d,0x00,0xfa,0xff,0xf9,0xff,0xf9,0xff,0x02,0x00,0xf4,0xff,0xfe,0xff,0x0f,0x00,0x04,0x00,0xfa,0xff,0xff,0xff,0xf8,0xff,0xed,0xff,0xf0,0xff,0x00,0x00,0xe5,0xff,0xd8,0xff,0xd7,0xff,0xd5,0xff,0xe8,0xff,0xf1,0xff,0x03,0x00,0x2b,0x00,0x0f,0x00,0x23,0x00,0xfd,0xff,0xe7,0xff,0x13,0x00,0x26,0x00,0x03,0x00,0x19,0x00,0x07,0x00,0x0a,0x00,0x10,0x00,0x08,0x00,0xfb,0xff,0xf0,0xff,0xfa,0xff,0xff,0xff,0xf7,0xff,0x06,0x00,0xfe,0xff,0x03,0x00,0x02,0x00,0xf3,0xff,0x15,0x00,0xf4,0xff,0xdc,0xff,0xe5,0xff,0xea,0xff,0xfd,0xff,0xeb,0xff,0xfe,0xff,0x1c,0x00,0x2b,0x00,0x28,0x00,0x08,0x00,0xfd,0xff,0x14,0x00,0x23,0x00,0x1b,0x00,0x1d,0x00,0x0d,0x00,0x0b,0x00,0xfd,0xff,0x04,0x00,0x03,0x00,0x13,0x00,0xfb,0xff,0x04,0x00,0xf2,0xff,0x03,0x00,0xfd,0xff,0x08,0x00,0x07,0x00,0x16,0x00,0x00,0x00,0xfe,0xff,0xe1,0xff,0xf9,0xff,0x10,0x00,0x19,0x00,0x0f,0x00,0x0e,0x00,0xf7,0xff,0xd7,0xff,0xed,0xff,0xed,0xff,0xf2,0xff,0x0d,0x00,0x03,0x00,0x04,0x00,0x06,0x00,0xe9,0xff,0xd4,0xff,0xd1,0xff,0xe1,0xff,0xff,0xff,0x02,0x00,0xff,0xff,0x10,0x00,0xfe,0xff,0xfd,0xff,0xff,0xff,0xed,0xff,0xec,0xff,0xf6,0xff,0x03,0x00,0x04,0x00,0x0e,0x00,0xf3,0xff,0xf6,0xff,0xf7,0xff,0x0a,0x00,0x23,0x00,0x19,0x00,0x19,0x00,0x0a,0x00,0xea,0xff,0xf4,0xff,0xfd,0xff,0xf5,0xff,0x09,0x00,0x11,0x00,0x1e,0x00,0x1c,0x00,0x02,0x00,0xf6,0xff,0xfa,0xff,0xf2,0xff,0x03,0x00,0xf9,0xff,0xfb,0xff,0x0f,0x00,0xf7,0xff,0x00,0x00,0xf1,0xff,0xe8,0xff,0xf8,0xff,0xef,0xff,0xfc,0xff,0x16,0x00,0x09,0x00,0xdf,0xff,0xe9,0xff,0xf5,0xff,0xfe,0xff,0x1f,0x00,0x19,0x00,0x1c,0x00,0x10,0x00,0x09,0x00,0x02,0x00,0xf7,0xff,0xec,0xff,0x12,0x00,0x1f,0x00,0x21,0x00,0x24,0x00,0x1b,0x00,0x08,0x00,0x02,0x00,0xf2,0xff,0xf9,0xff,0x03,0x00,0xff,0xff,0x02,0x00,0x00,0x00,0x08,0x00,0xfe,0xff,0xf3,0xff,0xef,0xff,0x14,0x00,0x02,0x00,0x20,0x00,0x18,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0e,0x00,0x11,0x00,0x02,0x00,0xf8,0xff,0xf6,0xff,0x0e,0x00,0x05,0x00,0x18,0x00,0xfc,0xff,0x14,0x00,0xfe,0xff,0x1a,0x00,0x10,0x00,0xf8,0xff,0x07,0x00,0x00,0x00,0x03,0x00,0x07,0x00,0xfe,0xff,0xfb,0xff,0xef,0xff,0xfa,0xff,0xf0,0xff,0xee,0xff,0xb5,0xff,0x1a,0x00,0x0d,0x00,0x16,0x00,0x28,0x00,0x1d,0x00,0x07,0x00,0x0b,0x00,0x00,0x00,0x0f,0x00,0xfc,0xff,0xfc,0xff,0xf4,0xff,0xf8,0xff,0x06,0x00,0x05,0x00,0x07,0x00,0x03,0x00,0x14,0x00,0xfc,0xff,0x08,0x00,0xf5,0xff,0xf5,0xff,0xf8,0xff,0xfa,0xff,0xf9,0xff,0x01,0x00,0xfc,0xff,0xfa,0xff,0xeb,0xff,0xf1,0xff,0xee,0xff,0xb0,0xff,0x11,0x00,0x0c,0x00,0x09,0x00,0x1a,0x00,0x16,0x00,0xf6,0xff,0x11,0x00,0x0d,0x00,0x0d,0x00,0x0a,0x00,0x0e,0x00,0xf4,0xff,0xed,0xff,0xfc,0xff,0xe9,0xff,0x01,0x00,0xe9,0xff,0x06,0x00,0xf4,0xff,0xe0,0xff,0xf8,0xff,0xd9,0xff,0xe2,0xff,0xe7,0xff,0xfd,0xff,0xfd,0xff,0xff,0xff,0x00,0x00,0xf8,0xff,0xf8,0xff,0xfa,0xff,0xce,0xff,0xf2,0xff,0xfc,0xff,0xfc,0xff,0xd9,0xff,0xea,0xff,0xf7,0xff,0xe8,0xff,0x06,0x00,0xfd,0xff,0xfc,0xff,0x03,0x00,0x07,0x00,0x02,0x00,0xfe,0xff,0xff,0xff,0x03,0x00,0x01,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0xfe,0xff,0xff,0xff,0x04,0x00,0xfe,0xff,0x02,0x00,0x00,0x00,0xfd,0xff,0x14,0x00,0x04,0x00,0xf8,0xff,0x28,0x00,0x44,0x00,0x46,0x00,0x3a,0x00,0xf6,0xff,0xfa,0xff,0x03,0x00,0xff,0xff,0x01,0x00,0xfe,0xff,0x04,0x00,0xfe,0xff,0xfb,0xff,0xff,0xff,0xfe,0xff,0x00,0x00,0xff,0xff,0x01,0x00,0x01,0x00,0xff,0xff,0x01,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0xfe,0xff,0x02,0x00,0xff,0xff,0xfe,0xff,0x00,0x00,0xf0,0xff,0xf9,0xff,0x14,0x00,0x0d,0x00,0xd3,0xff,0xc4,0xff,0xbf,0xff,0xfc,0xff,0xfd,0xff,0x01,0x00,0x03,0x00,0x04,0x00,0x07,0x00,0xff,0xff,0x04,0x00,0x06,0x00,0x00,0x00,0x01,0x00,0xfd,0xff,0x02,0x00,0xff,0xff,0x04,0x00,0x05,0x00,0xff,0xff,0x01,0x00,0xfe,0xff,0x04,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0xfe,0xff,0xe1,0xff,0x19,0x00,0x53,0x00,0x23,0x00,0xe8,0xff,0xde,0xff,0xd4,0xff,0xf9,0xff,0xfd,0xff,0x05,0x00,0x04,0x00,0x03,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0xff,0xff,0xfd,0xff,0xfc,0xff,0xfc,0xff,0xfe,0xff,0x01,0x00,0x02,0x00,0xfd,0xff,0x03,0x00,0x04,0x00,0x02,0x00,0xf9,0xff,0x03,0x00,0x07,0x00,0x00,0x00,0x02,0x00,0x04,0x00,0xfe,0xff,0x2f,0x00,0x10,0x00,0xc2,0xff,0xe0,0xff,0xfb,0xff,0x02,0x00,0x08,0x00,0xfe,0xff,0x01,0x00,0x01,0x00,0x00,0x00,0xfe,0xff,0xfb,0xff,0xfb,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0x02,0x00,0x01,0x00,0xfd,0xff,0xf8,0xff,0xfd,0xff,0xf7,0xff,0xfd,0xff,0x01,0x00,0xfd,0xff,0xff,0xff,0xf7,0xff,0xf9,0xff,0x19,0x00,0x23,0x00,0xcd,0xff,0xb0,0xff,0x0f,0x00,0x26,0x00,0x24,0x00,0x0f,0x00,0x06,0x00,0xf8,0xff,0x07,0x00,0xff,0xff,0xf8,0xff,0xfb,0xff,0xff,0xff,0x01,0x00,0x03,0x00,0x01,0x00,0x03,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x05,0x00,0xfc,0xff,0xf6,0xff,0x00,0x00,0x06,0x00,0xfd,0xff,0x03,0x00,0xff,0xff,0xff,0xff,0xfb,0xff,0xfb,0xff,0xfc,0xff,0xfb,0xff,0xfb,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfa,0xff,0xfe,0xff,0xfe,0xff,0x00,0x00,0xfe,0xff,0xfc,0xff,0xfe,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xfc,0xff,0xfc,0xff,0xfd,0xff,0xfc,0xff,0xfb,0xff,0xfb,0xff,0xfd,0xff,0xfe,0xff,0xf7,0xff,0xfc,0xff,0xfb,0xff,0xf9,0xff,0xfb,0xff,0xfd,0xff,0xfd,0xff,0xfc,0xff,0xfd,0xff,0xfd,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0x02,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xfe,0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xfc,0xff,0xfb,0xff,0xfd,0xff,0xfa,0xff,0xfb,0xff,0xfa,0xff,0xfe,0xff,0xfe,0xff,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x03,0x00,0x04,0x00,0xff,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x03,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0x07,0x00,0x01,0x00,0xf5,0xff,0x01,0x00,0xfb,0xff,0xff,0xff,0x1c,0x00,0x05,0x00,0xf9,0xff,0x16,0x00,0x13,0x00,0xfc,0xff,0xf6,0xff,0xf1,0xff,0x0a,0x00,0x10,0x00,0xf2,0xff,0xf4,0xff,0x01,0x00,0xfc,0xff,0xf1,0xff,0xee,0xff,0x10,0x00,0x0b,0x00,0x13,0x00,0x0f,0x00,0x06,0x00,0x0e,0x00,0xf9,0xff,0x09,0x00,0xeb,0xff,0xec,0xff,0x12,0x00,0x17,0x00,0x17,0x00,0xf3,0xff,0x1a,0x00,0x12,0x00,0xf7,0xff,0x16,0x00,0x0b,0x00,0x17,0x00,0x16,0x00,0x15,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x09,0x00,0xf4,0xff,0x0b,0x00,0x06,0x00,0x08,0x00,0x06,0x00,0x0d,0x00,0xf3,0xff,0x0b,0x00,0xf5,0xff,0x15,0x00,0x05,0x00,0x0f,0x00,0x0e,0x00,0x10,0x00,0x0c,0x00,0xee,0xff,0xf4,0xff,0x06,0x00,0x18,0x00,0xf0,0xff,0x16,0x00,0x0d,0x00,0x0f,0x00,0xfa,0xff,0x0b,0x00,0xf4,0xff,0x02,0x00,0x15,0x00,0x04,0x00,0x10,0x00,0x0d,0x00,0x10,0x00,0x13,0x00,0x14,0x00,0x0d,0x00,0x08,0x00,0xef,0xff,0x03,0x00,0xfb,0xff,0xf8,0xff,0xf4,0xff,0x0d,0x00,0x0e,0x00,0xea,0xff,0x09,0x00,0x0d,0x00,0x00,0x00,0xf6,0xff,0xfc,0xff,0xf0,0xff,0xf4,0xff,0x11,0x00,0x11,0x00,0xee,0xff,0xee,0xff,0xd2,0xff,0xe6,0xff,0xf6,0xff,0xf8,0xff,0x06,0x00,0x0f,0x00,0x0d,0x00,0x08,0x00,0xfe,0xff,0xfc,0xff,0x02,0x00,0xfc,0xff,0x0f,0x00,0xf6,0xff,0xfc,0xff,0xf6,0xff,0x0e,0x00,0x03,0x00,0x0c,0x00,0x0e,0x00,0x0f,0x00,0x03,0x00,0x00,0x00,0xef,0xff,0xf9,0xff,0xfa,0xff,0xfd,0xff,0xe9,0xff,0xf5,0xff,0xdd,0xff,0xe1,0xff,0xd9,0xff,0xe2,0xff,0xfc,0xff,0x0f,0x00,0x16,0x00,0x1d,0x00,0x12,0x00,0x13,0x00,0x06,0x00,0x03,0x00,0x09,0x00,0x02,0x00,0x07,0x00,0x0a,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xef,0xff,0x05,0x00,0x0b,0x00,0x18,0x00,0x10,0x00,0x0d,0x00,0x0e,0x00,0x0e,0x00,0x01,0x00,0xf4,0xff,0x08,0x00,0xfa,0xff,0xf4,0xff,0xda,0xff,0xe1,0xff,0xfa,0xff,0x09,0x00,0x14,0x00,0x10,0x00,0x26,0x00,0x14,0x00,0x0f,0x00,0x0b,0x00,0x05,0x00,0x06,0x00,0x10,0x00,0x0c,0x00,0x0f,0x00,0xf9,0xff,0x01,0x00,0xfc,0xff,0xfe,0xff,0xee,0xff,0xfc,0xff,0x0b,0x00,0x0d,0x00,0x09,0x00,0x10,0x00,0x14,0x00,0x15,0x00,0x13,0x00,0xff,0xff,0xed,0xff,0xe2,0xff,0xea,0xff,0xf2,0xff,0xf9,0xff,0xf3,0xff,0x09,0x00,0x09,0x00,0x10,0x00,0x0a,0x00,0x12,0x00,0x12,0x00,0x0e,0x00,0x21,0x00,0x1a,0x00,0x0e,0x00,0x07,0x00,0xfc,0xff,0x06,0x00,0x0f,0x00,0xf8,0xff,0x02,0x00,0x04,0x00,0xfe,0xff,0x06,0x00,0x0b,0x00,0x01,0x00,0x06,0x00,0x08,0x00,0x14,0x00,0x08,0x00,0x0f,0x00,0xd7,0xff,0xc1,0xff,0xd7,0xff,0xd5,0xff,0xe5,0xff,0xed,0xff,0x03,0x00,0x1c,0x00,0x17,0x00,0x1d,0x00,0x12,0x00,0x03,0x00,0x0a,0x00,0x0e,0x00,0x04,0x00,0x0d,0x00,0x06,0x00,0x07,0x00,0x01,0x00,0x00,0x00,0x06,0x00,0x07,0x00,0x07,0x00,0x02,0x00,0xfe,0xff,0x00,0x00,0xff,0xff,0xf8,0xff,0x02,0x00,0x02,0x00,0x02,0x00,0x14,0x00,0xda,0xff,0xcf,0xff,0xe2,0xff,0xe8,0xff,0xfa,0xff,0x09,0x00,0x0d,0x00,0x12,0x00,0x0e,0x00,0x10,0x00,0x05,0x00,0xf9,0xff,0x08,0x00,0xf3,0xff,0xee,0xff,0xfe,0xff,0xf2,0xff,0x05,0x00,0xf3,0xff,0xee,0xff,0x0c,0x00,0x05,0x00,0x03,0x00,0x03,0x00,0xfd,0xff,0xf6,0xff,0xf6,0xff,0xed,0xff,0xef,0xff,0xfb,0xff,0xf6,0xff,0x10,0x00,0x04,0x00,0x00,0x00,0xff,0xff,0xfa,0xff,0xf8,0xff,0xf1,0xff,0xf3,0xff,0xec,0xff,0xfa,0xff,0xed,0xff,0x10,0x00,0x06,0x00,0x04,0x00,0xec,0xff,0x03,0x00,0x06,0x00,0x03,0x00,0xfd,0xff,0x10,0x00,0xf9,0xff,0x09,0x00,0x08,0x00,0x0f,0x00,0xf9,0xff,0xf4,0xff,0x04,0x00,0x05,0x00,0x0f,0x00,0xed,0xff,0xef,0xff,0x01,0x00,0x11,0x00,0x02,0x00,0x0a,0x00,0xf2,0xff,0xf6,0xff,0xf5,0xff,0xf7,0xff,0xf6,0xff,0x0a,0x00,0x05,0x00,0x02,0x00,0xee,0xff,0xf1,0xff,0xf4,0xff,0x02,0x00,0xed,0xff,0x00,0x00,0x02,0x00,0x02,0x00,0x0a,0x00,0x11,0x00,0x07,0x00,0xec,0xff,0x11,0x00,0x11,0x00,0xf1,0xff,0xeb,0xff,0xfd,0xff,0xf6,0xff,0xed,0xff,0x09,0x00,0xee,0xff,0xf2,0xff,0xef,0xff,0x00,0x00,0x02,0x00,0xfa,0xff,0x08,0x00,0xfc,0xff,0x0c,0x00,0x10,0x00,0x07,0x00,0x0d,0x00,0xee,0xff,0xfe,0xff,0xee,0xff,0xf6,0xff,0x01,0x00,0x0d,0x00,0xfd,0xff,0xfb,0xff,0xee,0xff,0xf7,0xff,0x03,0x00,0xec,0xff,0xf3,0xff,0x05,0x00,0x0b,0x00,0x0f,0x00,0xf8,0xff,0xf2,0xff,0x08,0x00,0xec,0xff,0xf4,0xff,0xfc,0xff,0x01,0x00,0x0b,0x00,0x06,0x00,0x03,0x00,0x00,0x00,0x07,0x00,0xff,0xff,0x0b,0x00,0x03,0x00,0x05,0x00,0x01,0x00,0x07,0x00,0x03,0x00,0x02,0x00,0xfe,0xff,0xfa,0xff,0xfe,0xff,0xfd,0xff,0xfe,0xff,0xff,0xff,0x05,0x00,0x03,0x00,0x02,0x00,0xff,0xff,0x01,0x00,0x04,0x00,0x09,0x00,0x08,0x00,0x06,0x00,0x05,0x00,0x02,0x00,0x06,0x00,0x02,0x00,0x03,0x00,0x01,0x00,0x05,0x00,0x0d,0x00,0x09,0x00,0x02,0x00,0x03,0x00,0xfa,0xff,0xf6,0xff,0xfb,0xff,0xfc,0xff,0xfe,0xff,0xf7,0xff,0xf8,0xff,0xf9,0xff,0xfc,0xff,0xfa,0xff,0xfd,0xff,0xfe,0xff,0x00,0x00,0x03,0x00,0x04,0x00,0xff,0xff,0xfd,0xff,0xfa,0xff,0xf9,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0x01,0x00,0xfd,0xff,0x06,0x00,0x06,0x00,0x03,0x00,0x0a,0x00,0x05,0x00,0xf7,0xff,0xef,0xff,0xe3,0xff,0xe8,0xff,0xe6,0xff,0xee,0xff,0xee,0xff,0xe7,0xff,0xeb,0xff,0xf6,0xff,0xfc,0xff,0x02,0x00,0xff,0xff,0x01,0x00,0x00,0x00,0xfd,0xff,0xfd,0xff,0xfd,0xff,0x00,0x00,0xfa,0xff,0xf4,0xff,0xef,0xff,0xf1,0xff,0xef,0xff,0xee,0xff,0xf5,0xff,0xec,0xff,0x01,0x00,0xfa,0xff,0x00,0x00,0xfb,0xff,0xff,0xff,0x01,0x00,0x0a,0x00,0xfd,0xff,0xfc,0xff,0x0a,0x00,0x01,0x00,0xfe,0xff,0xe2,0xff,0xd0,0xff,0xeb,0xff,0x0d,0x00,0x10,0x00,0x09,0x00,0x05,0x00,0xfd,0xff,0x03,0x00,0x07,0x00,0x01,0x00,0x15,0x00,0x06,0x00,0xff,0xff,0xf9,0xff,0xf2,0xff,0xf8,0xff,0x02,0x00,0xfd,0xff,0x07,0x00,0xff,0xff,0x02,0x00,0xff,0xff,0xfd,0xff,0xfe,0xff,0x01,0x00,0x01,0x00,0x04,0x00,0x00,0x00,0xff,0xff,0xf0,0xff,0xe7,0xff,0xe3,0xff,0xf6,0xff,0x17,0x00,0x21,0x00,0x19,0x00,0x0b,0x00,0xf8,0xff,0xfc,0xff,0xfe,0xff,0x01,0x00,0xff,0xff,0x03,0x00,0xfc,0xff,0x01,0x00,0xfc,0xff,0xfd,0xff,0x00,0x00,0xfd,0xff,0xfb,0xff,0x04,0x00,0xfe,0xff,0x04,0x00,0x00,0x00,0x09,0x00,0x0b,0x00,0xf9,0xff,0x01,0x00,0x06,0x00,0x06,0x00,0xf5,0xff,0xee,0xff,0xe9,0xff,0xfe,0xff,0x29,0x00,0x30,0x00,0x1a,0x00,0x13,0x00,0x03,0x00,0xfb,0xff,0x00,0x00,0x00,0x00,0xfb,0xff,0x00,0x00,0xf3,0xff,0xfb,0xff,0xfe,0xff,0x04,0x00,0x0b,0x00,0x08,0x00,0xfe,0xff,0xfc,0xff,0x01,0x00,0x06,0x00,0xd6,0xff,0x1b,0x00,0x3c,0x00,0xd8,0xff,0xb9,0xff,0xfe,0xff,0x0c,0x00,0x07,0x00,0x08,0x00,0xfc,0xff,0xfa,0xff,0x1d,0x00,0x15,0x00,0x0e,0x00,0xec,0xff,0xea,0xff,0x08,0x00,0xfc,0xff,0xfc,0xff,0x0f,0x00,0x0f,0x00,0x00,0x00,0x08,0x00,0x01,0x00,0xfc,0xff,0xf8,0xff,0xfa,0xff,0x0a,0x00,0xff,0xff,0x07,0x00,0x09,0x00,0x05,0x00,0xdc,0xff,0x26,0x00,0x59,0x00,0xdc,0xff,0x81,0xff,0x04,0x00,0x28,0x00,0x1f,0x00,0x0b,0x00,0xec,0xff,0xed,0xff,0xfd,0xff,0x11,0x00,0xfa,0xff,0xe4,0xff,0xf7,0xff,0xfd,0xff,0x10,0x00,0xf7,0xff,0xfe,0xff,0xfe,0xff,0x01,0x00,0x05,0x00,0xfb,0xff,0x03,0x00,0xfb,0xff,0x02,0x00,0xf8,0xff,0x0e,0x00,0xfd,0xff,0xec,0xff,0x0d,0x00,0xe7,0xff,0x17,0x00,0x49,0x00,0xf4,0xff,0xb1,0xff,0x0d,0x00,0x33,0x00,0x1d,0x00,0x0a,0x00,0xe4,0xff,0xde,0xff,0xef,0xff,0x11,0x00,0xf2,0xff,0xfa,0xff,0x0d,0x00,0x0c,0x00,0x03,0x00,0x0f,0x00,0xf7,0xff,0xee,0xff,0x12,0x00,0x00,0x00,0xfb,0xff,0x0b,0x00,0x0f,0x00,0x04,0x00,0xf5,0xff,0xfe,0xff,0x03,0x00,0xf7,0xff,0xf8,0xff,0xf2,0xff,0xfe,0xff,0x07,0x00,0x00,0x00,0xfc,0xff,0xfe,0xff,0x04,0x00,0x09,0x00,0x06,0x00,0x07,0x00,0x04,0x00,0x06,0x00,0x0b,0x00,0x12,0x00,0x14,0x00,0x15,0x00,0x12,0x00,0x06,0x00,0x02,0x00,0xfd,0xff,0xff,0xff,0xfd,0xff,0xfd,0xff,0xfe,0xff,0xfc,0xff,0xfc,0xff,0xf8,0xff,0xfc,0xff,0xfc,0xff,0x00,0x00,0xff,0xff,0xfa,0xff,0x00,0x00,0x05,0x00,0x0a,0x00,0x0d,0x00,0x0c,0x00,0x09,0x00,0x08,0x00,0x07,0x00,0x00,0x00,0xfd,0xff,0xfb,0xff,0xf8,0xff,0xf8,0xff,0xfe,0xff,0x03,0x00,0x09,0x00,0x0c,0x00,0x0b,0x00,0x0a,0x00,0x08,0x00,0x03,0x00,0x01,0x00,0xff,0xff,0x02,0x00,0x03,0x00,0x03,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x03,0x00,0x0d,0x00,0x0b,0x00,0x07,0x00,0x0d,0x00,0x0b,0x00,0x0d,0x00,0x07,0x00,0x03,0x00,0xfc,0xff,0xf5,0xff,0xf4,0xff,0xf1,0xff,0xef,0xff,0xeb,0xff,0xed,0xff,0xf4,0xff,0xfa,0xff,0x01,0x00,0x05,0x00,0x08,0x00,0x06,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x0a,0x00,0x0b,0x00,0x0a,0x00,0x07,0x00,0x06,0x00,0x05,0x00,0x05,0x00,0xff,0xff,0x01,0x00,0xfa,0xff,0x06,0x00,0xfd,0xff,0xfc,0xff,0xf5,0xff,0xfb,0xff,0xfb,0xff,0xfa,0xff,0x06,0x00,0x03,0x00,0xf0,0xff,0xda,0xff,0xc6,0xff,0xc7,0xff,0xde,0xff,0xf3,0xff,0x06,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x0b,0x00,0x09,0x00,0x01,0x00,0x09,0x00,0xff,0xff,0x07,0x00,0xf9,0xff,0xf7,0xff,0x00,0x00,0xf8,0xff,0x02,0x00,0xf8,0xff,0xf7,0xff,0xfd,0xff,0xfb,0xff,0xea,0xff,0xe8,0xff,0xf1,0xff,0xf5,0xff,0xf6,0xff,0xf2,0xff,0xe1,0xff,0xd9,0xff,0xd5,0xff,0xe1,0xff,0xfa,0xff,0x11,0x00,0x1f,0x00,0x1b,0x00,0x1b,0x00,0x14,0x00,0x11,0x00,0x11,0x00,0x16,0x00,0x10,0x00,0x0d,0x00,0x10,0x00,0x0d,0x00,0x01,0x00,0xfc,0xff,0xf9,0xff,0xf7,0xff,0xff,0xff,0xf6,0xff,0xf6,0xff,0x01,0x00,0x04,0x00,0xff,0xff,0xfa,0xff,0x04,0x00,0xfd,0xff,0x00,0x00,0xeb,0xff,0xdf,0xff,0xe7,0xff,0xfe,0xff,0x21,0x00,0x39,0x00,0x3b,0x00,0x32,0x00,0x13,0x00,0x15,0x00,0x01,0x00,0x0c,0x00,0x08,0x00,0x0b,0x00,0x0c,0x00,0x07,0x00,0x0d,0x00,0x0a,0x00,0x0f,0x00,0x03,0x00,0xfd,0xff,0xff,0xff,0x09,0x00,0x00,0x00,0x19,0x00,0xe7,0xff,0x08,0x00,0x36,0x00,0x18,0x00,0xca,0xff,0xf5,0xff,0x33,0x00,0x12,0x00,0xec,0xff,0xf1,0xff,0x09,0x00,0x0e,0x00,0xf1,0xff,0x04,0x00,0x05,0x00,0x0f,0x00,0xf7,0xff,0x13,0x00,0x0b,0x00,0x05,0x00,0xf1,0xff,0x0a,0x00,0xf2,0xff,0xf4,0xff,0xf8,0xff,0xf9,0xff,0xf0,0xff,0x10,0x00,0xfd,0xff,0x00,0x00,0xf8,0xff,0x1d,0x00,0xd5,0xff,0xfb,0xff,0x3d,0x00,0x25,0x00,0x9e,0xff,0xd9,0xff,0x32,0x00,0x16,0x00,0xec,0xff,0xf0,0xff,0xff,0xff,0x12,0x00,0xfb,0xff,0xef,0xff,0x16,0x00,0x08,0x00,0xee,0xff,0x0b,0x00,0xf9,0xff,0xfe,0xff,0xf8,0xff,0x02,0x00,0xff,0xff,0xf4,0xff,0x01,0x00,0x03,0x00,0x01,0x00,0x06,0x00,0xf8,0xff,0xef,0xff,0xee,0xff,0x1a,0x00,0xea,0xff,0xf4,0xff,0x37,0x00,0x18,0x00,0xb0,0xff,0xe6,0xff,0x12,0x00,0x1a,0x00,0xf6,0xff,0xfd,0xff,0x05,0x00,0xfc,0xff,0x01,0x00,0xed,0xff,0xfd,0xff,0x0a,0x00,0xfc,0xff,0xf4,0xff,0x00,0x00,0x00,0x00,0x04,0x00,0x09,0x00,0x16,0x00,0x09,0x00,0x0a,0x00,0xfc,0xff,0x07,0x00,0x02,0x00,0xef,0xff,0x36,0x00,0x01,0x00,0xba,0xff,0xdf,0xff,0x52,0x00,0x27,0x00,0xeb,0xff,0xdf,0xff,0x03,0x00,0x04,0x00,0x19,0x00,0x09,0x00,0xe7,0xff,0xf4,0xff,0xfd,0xff,0x05,0x00,0x0b,0x00,0xef,0xff,0xff,0xff,0x14,0x00,0x13,0x00,0x0b,0x00,0x0b,0x00,0x08,0x00,0xff,0xff,0xf9,0xff,0xf7,0xff,0xfd,0xff,0x03,0x00,0xf8,0xff,0xfd,0xff,0xfc,0xff,0x37,0x00,0xf5,0xff,0xa8,0xff,0xf8,0xff,0x6f,0x00,0x16,0x00,0xb7,0xff,0xbd,0xff,0x15,0x00,0x17,0x00,0x19,0x00,0xfd,0xff,0xf0,0xff,0xf5,0xff,0x07,0x00,0xfc,0xff,0x1a,0x00,0xfd,0xff,0xf2,0xff,0x15,0x00,0xf9,0xff,0x02,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x15,0x00,0xf7,0xff,0xf3,0xff,0x05,0x00,0xf4,0xff,0x07,0x00,0xf4,0xff,0x0f,0x00,0x03,0x00,0xc2,0xff,0x20,0x00,0x54,0x00,0xed,0xff,0xb6,0xff,0xcc,0xff,0x1f,0x00,0x14,0x00,0x07,0x00,0xf8,0xff,0xf3,0xff,0xf7,0xff,0x03,0x00,0x08,0x00,0x0f,0x00,0xfa,0xff,0xf6,0xff,0xf5,0xff,0xf1,0xff,0xef,0xff,0xf3,0xff,0x0f,0x00,0x0d,0x00,0x01,0x00,0x08,0x00,0xf6,0xff,0xfd,0xff,0x03,0x00,0x08,0x00,0x04,0x00,0xf5,0xff,0xf3,0xff,0xf9,0xff,0xfc,0xff,0xf1,0xff,0xf6,0xff,0xf2,0xff,0x00,0x00,0x0f,0x00,0xf7,0xff,0x02,0x00,0xff,0xff,0xf0,0xff,0xf5,0xff,0xf6,0xff,0xe6,0xff,0xf2,0xff,0xef,0xff,0xe9,0xff,0xee,0xff,0xf5,0xff,0x0b,0x00,0x12,0x00,0x21,0x00,0x19,0x00,0x23,0x00,0x21,0x00,0x0a,0x00,0x05,0x00,0xec,0xff,0xe7,0xff,0xd8,0xff,0x02,0x00,0x0e,0x00,0x01,0x00,0xfc,0xff,0x07,0x00,0x01,0x00,0xff,0xff,0x08,0x00,0x00,0x00,0x0a,0x00,0xfc,0xff,0xf7,0xff,0xea,0xff,0xdf,0xff,0xe2,0xff,0xdf,0xff,0xe2,0xff,0xe1,0xff,0xe8,0xff,0xe0,0xff,0xf2,0xff,0x00,0x00,0x2c,0x00,0x39,0x00,0x34,0x00,0x3d,0x00,0x31,0x00,0x1f,0x00,0xf8,0xff,0xf1,0xff,0xf6,0xff,0xe0,0xff,0x18,0x00,0x20,0x00,0x02,0x00,0x01,0x00,0x15,0x00,0x02,0x00,0x0a,0x00,0xff,0xff,0xfc,0xff,0x04,0x00,0x0b,0x00,0xf6,0xff,0xfb,0xff,0xef,0xff,0xe4,0xff,0xfd,0xff,0xef,0xff,0xeb,0xff,0xf4,0xff,0xfc,0xff,0xf3,0xff,0x04,0x00,0x16,0x00,0x28,0x00,0x30,0x00,0x22,0x00,0x16,0x00,0x0b,0x00,0xf4,0xff,0xf2,0xff,0xfa,0xff,0x06,0x00,0x1e,0x00,0x38,0x00,0x36,0x00,0x11,0x00,0xe9,0xff,0xfc,0xff,0x03,0x00,0xfd,0xff,0x0e,0x00,0x0c,0x00,0x09,0x00,0xfa,0xff,0x02,0x00,0x07,0x00,0x06,0x00,0x04,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x06,0x00,0x01,0x00,0x0c,0x00,0x00,0x00,0x04,0x00,0x07,0x00,0xff,0xff,0xff,0xff,0xf4,0xff,0x01,0x00,0x01,0x00,0xfc,0xff,0x05,0x00,0x13,0x00,0x1c,0x00,0x18,0x00,0x15,0x00,0x16,0x00,0x04,0x00,0xfc,0xff,0x03,0x00,0x00,0x00,0x10,0x00,0xff,0xff,0xfd,0xff,0xfb,0xff,0x02,0x00,0x01,0x00,0xf4,0xff,0xf9,0xff,0xf9,0xff,0xfd,0xff,0xf9,0xff,0x00,0x00,0xf9,0xff,0x03,0x00,0x02,0x00,0xfd,0xff,0x00,0x00,0xfd,0xff,0xfd,0xff,0x06,0x00,0xfb,0xff,0x03,0x00,0xf8,0xff,0xff,0xff,0xcd,0xff,0xbf,0xff,0xd0,0xff,0xe9,0xff,0xee,0xff,0xf1,0xff,0xfa,0xff,0x06,0x00,0xfe,0xff,0xf7,0xff,0xe9,0xff,0xf9,0xff,0xf5,0xff,0xf7,0xff,0xfd,0xff,0xfc,0xff,0xf5,0xff,0xf7,0xff,0xf9,0xff,0xfa,0xff,0x05,0x00,0xfd,0xff,0x02,0x00,0x05,0x00,0xff,0xff,0xff,0xff,0xf7,0xff,0x05,0x00,0x02,0x00,0x02,0x00,0x06,0x00,0x01,0x00,0xfb,0xff,0xf7,0xff,0xe1,0xff,0xdf,0xff,0xd1,0xff,0xd6,0xff,0xe9,0xff,0xe7,0xff,0xea,0xff,0xee,0xff,0xf3,0xff,0xf5,0xff,0xf6,0xff,0xf2,0xff,0xf9,0xff,0xf8,0xff,0x00,0x00,0xff,0xff,0xfe,0xff,0xfa,0xff,0x00,0x00,0xf9,0xff,0xf8,0xff,0xf3,0xff,0xf7,0xff,0xf9,0xff,0xf6,0xff,0xf4,0xff,0xf0,0xff,0xf3,0xff,0xef,0xff,0x12,0x00,0x19,0x00,0x19,0x00,0x1e,0x00,0x17,0x00,0x0d,0x00,0x01,0x00,0xfe,0xff,0xf7,0xff,0xf2,0xff,0xf8,0xff,0xfd,0xff,0x04,0x00,0x06,0x00,0x05,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0xff,0xff,0xfe,0xff,0xfc,0xff,0xf8,0xff,0xfd,0xff,0xfc,0xff,0x00,0x00,0xff,0xff,0xfa,0xff,0xfd,0xff,0xf8,0xff,0xfb,0xff,0xf5,0xff,0x14,0x00,0x28,0x00,0x2f,0x00,0x44,0x00,0x3c,0x00,0x35,0x00,0x26,0x00,0x14,0x00,0x0a,0x00,0xff,0xff,0x02,0x00,0x0a,0x00,0x08,0x00,0x0d,0x00,0x0a,0x00,0x05,0x00,0x02,0x00,0x01,0x00,0xfd,0xff,0x01,0x00,0xfd,0xff,0xf9,0xff,0xfd,0xff,0x02,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x09,0x00,0x06,0x00,0x09,0x00,0x07,0x00,0x01,0x00,0x21,0x00,0x20,0x00,0x3c,0x00,0x2b,0x00,0x18,0x00,0xf6,0xff,0xf0,0xff,0xec,0xff,0xf1,0xff,0xf9,0xff,0x09,0x00,0x04,0x00,0xfb,0xff,0xfb,0xff,0x14,0x00,0x04,0x00,0xfb,0xff,0xf9,0xff,0xf9,0xff,0xfe,0xff,0x09,0x00,0x0a,0x00,0x0b,0x00,0x11,0x00,0x14,0x00,0x0d,0x00,0xfe,0xff,0xf2,0xff,0xf4,0xff,0xff,0xff,0xf4,0xff,0xef,0xff,0x34,0x00,0x34,0x00,0x4a,0x00,0x34,0x00,0xf3,0xff,0xeb,0xff,0xec,0xff,0xe9,0xff,0xf4,0xff,0x04,0x00,0xfa,0xff,0x04,0x00,0xfc,0xff,0x00,0x00,0x04,0x00,0xf7,0xff,0xf9,0xff,0xf4,0xff,0x00,0x00,0xf3,0xff,0xfc,0xff,0xf2,0xff,0xf8,0xff,0x03,0x00,0x08,0x00,0x07,0x00,0x02,0x00,0xf9,0xff,0xf6,0xff,0xfa,0xff,0xf8,0xff,0xff,0xff,0x19,0x00,0x11,0x00,0x0a,0x00,0xf3,0xff,0xda,0xff,0xe5,0xff,0xe4,0xff,0xe1,0xff,0xfe,0xff,0xf5,0xff,0x05,0x00,0xf8,0xff,0xfe,0xff,0xfa,0xff,0xed,0xff,0xeb,0xff,0xfd,0xff,0xfb,0xff,0xf5,0xff,0x04,0x00,0xfc,0xff,0xf1,0xff,0xf8,0xff,0xf0,0xff,0xf3,0xff,0xf8,0xff,0xfd,0xff,0x0d,0x00,0x01,0x00,0xfa,0xff,0x05,0x00,0xfc,0xff,0x01,0x00,0x16,0x00,0xf0,0xff,0xda,0xff,0xe4,0xff,0xd6,0xff,0xc8,0xff,0xcd,0xff,0xca,0xff,0xe1,0xff,0xf0,0xff,0x03,0x00,0x08,0x00,0x0c,0x00,0xf9,0xff,0xee,0xff,0xe6,0xff,0xdc,0xff,0xdf,0xff,0xe6,0xff,0xf1,0xff,0xf9,0xff,0xfe,0xff,0xf9,0xff,0xe8,0xff,0xde,0xff,0xfc,0xff,0xf5,0xff,0xfb,0xff,0xf1,0xff,0x03,0x00,0xeb,0xff,0xf5,0xff,0x06,0x00,0x01,0x00,0xe0,0xff,0xd1,0xff,0xdb,0xff,0xdb,0xff,0xeb,0xff,0xf9,0xff,0x1d,0x00,0x37,0x00,0x26,0x00,0x2e,0x00,0x31,0x00,0x26,0x00,0x17,0x00,0x02,0x00,0x07,0x00,0xfc,0xff,0xfb,0xff,0xff,0xff,0x0b,0x00,0x0d,0x00,0x0e,0x00,0x0e,0x00,0xf6,0xff,0xfe,0xff,0x05,0x00,0x00,0x00,0x07,0x00,0x09,0x00,0xfa,0xff,0xf4,0xff,0xfa,0xff,0xf2,0xff,0xf3,0xff,0xe2,0xff,0xe7,0xff,0xf0,0xff,0xf7,0xff,0x21,0x00,0x32,0x00,0x4d,0x00,0x32,0x00,0x2f,0x00,0x28,0x00,0x24,0x00,0x27,0x00,0x21,0x00,0x2a,0x00,0x1f,0x00,0x0a,0x00,0x07,0x00,0x04,0x00,0x0f,0x00,0x12,0x00,0x09,0x00,0x0c,0x00,0x02,0x00,0x10,0x00,0xfb,0xff,0x0b,0x00,0x0d,0x00,0x04,0x00,0x10,0x00,0x00,0x00,0x08,0x00,0x06,0x00,0x09,0x00,0x0a,0x00,0x15,0x00,0x03,0x00,0x09,0x00,0xfd,0xff,0xff,0xff,0x0c,0x00,0x03,0x00,0x08,0x00,0x08,0x00,0x0e,0x00,0x02,0x00,0x0a,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x09,0x00,0xfd,0xff,0xf6,0xff,0xfb,0xff,0xfc,0xff,0xf1,0xff,0xfb,0xff,0xfa,0xff,0xf9,0xff,0xf6,0xff,0xee,0xff,0x0a,0x00,0x00,0x00,0xff,0xff,0x08,0x00,0x03,0x00,0x04,0x00,0xfc,0xff,0x02,0x00,0xfa,0xff,0x04,0x00,0xf9,0xff,0x04,0x00,0xfc,0xff,0x09,0x00,0xfc,0xff,0x09,0x00,0xfe,0xff,0xfe,0xff,0xf7,0xff,0x01,0x00,0xf0,0xff,0xed,0xff,0xf4,0xff,0xeb,0xff,0xe3,0xff,0xdf,0xff,0xee,0xff,0xe5,0xff,0xf1,0xff,0xe2,0xff,0xf6,0xff,0xda,0xff,0xed,0xff,0xfd,0xff,0x0f,0x00,0x02,0x00,0x05,0x00,0x01,0x00,0x0b,0x00,0xf7,0xff,0xfb,0xff,0xf6,0xff,0xf6,0xff,0xf4,0xff,0xfd,0xff,0xf1,0xff,0xf6,0xff,0xeb,0xff,0xfa,0xff,0xf1,0xff,0xef,0xff,0xe7,0xff,0xf2,0xff,0xea,0xff,0xe0,0xff,0xf5,0xff,0xef,0xff,0xf4,0xff,0xfa,0xff,0xe1,0xff,0xe8,0xff,0xf0,0xff,0xed,0xff,0x04,0x00,0x00,0x00,0xfd,0xff,0x04,0x00,0x0a,0x00,0xfe,0xff,0x01,0x00,0x02,0x00,0x02,0x00,0x07,0x00,0x06,0x00,0x09,0x00,0x06,0x00,0x07,0x00,0x06,0x00,0x09,0x00,0x06,0x00,0x08,0x00,0x08,0x00,0x07,0x00,0x0b,0x00,0x0b,0x00,0x0a,0x00,0x0c,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x0a,0x00,0x0b,0x00,0x0d,0x00,0x0c,0x00,0x0c,0x00,0x12,0x00,0x04,0x00,0x01,0x00,0x05,0x00,0x05,0x00,0x01,0x00,0x03,0x00,0x06,0x00,0x04,0x00,0x03,0x00,0x03,0x00,0x05,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x04,0x00,0x03,0x00,0x02,0x00,0x03,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x07,0x00,0x02,0x00,0x01,0x00,0xff,0xff,0x05,0x00,0x03,0x00,0x04,0x00,0x00,0x00,0xfe,0xff,0xfd,0xff,0xfc,0xff,0xfc,0xff,0xfb,0xff,0xfd,0xff,0xf8,0xff,0xfa,0xff,0xf9,0xff,0xfb,0xff,0xfb,0xff,0xf8,0xff,0xf8,0xff,0xf7,0xff,0xf9,0xff,0xfb,0xff,0xfc,0xff,0xf9,0xff,0xf9,0xff,0xf7,0xff,0xf5,0xff,0xf6,0xff,0xf7,0xff,0xf0,0xff,0x05,0x00,0xfc,0xff,0xf6,0xff,0xf7,0xff,0xfe,0xff,0xfa,0xff,0x01,0x00,0xfc,0xff,0xfd,0xff,0xfb,0xff,0xf8,0xff,0xf3,0xff,0xf3,0xff,0xf5,0xff,0x00,0x00,0x07,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x14,0x00,0x02,0x00,0xee,0xff,0xdd,0xff,0xdb,0xff,0xef,0xff,0x05,0x00,0x0b,0x00,0x08,0x00,0x02,0x00,0xfd,0xff,0x07,0x00,0x02,0x00,0xfc,0xff,0xf7,0xff,0xf4,0xff,0xf8,0xff,0x03,0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x03,0x00,0x01,0x00,0x04,0x00,0xff,0xff,0xfc,0xff,0xf9,0xff,0xf8,0xff,0xfd,0xff,0x02,0x00,0x0a,0x00,0x0c,0x00,0x13,0x00,0x16,0x00,0x16,0x00,0x0b,0x00,0xf6,0xff,0xeb,0xff,0xe1,0xff,0xe2,0xff,0xeb,0xff,0xf2,0xff,0xff,0xff,0x0f,0x00,0x20,0x00,0xf4,0xff,0xfc,0xff,0x02,0x00,0x0e,0x00,0x06,0x00,0x0d,0x00,0xff,0xff,0x04,0x00,0x00,0x00,0x05,0x00,0x06,0x00,0x0a,0x00,0x09,0x00,0x06,0x00,0xf9,0xff,0xf6,0xff,0xec,0xff,0xec,0xff,0xef,0xff,0xfa,0xff,0x0c,0x00,0x25,0x00,0x31,0x00,0x1f,0x00,0x00,0x00,0xe3,0xff,0xe0,0xff,0xe5,0xff,0xef,0xff,0x09,0x00,0x0e,0x00,0x2e,0x00,0x0d,0x00,0x09,0x00,0x0d,0x00,0x0a,0x00,0xfb,0xff,0x06,0x00,0x07,0x00,0x0a,0x00,0x09,0x00,0x05,0x00,0x06,0x00,0x06,0x00,0x0b,0x00,0x10,0x00,0x1a,0x00,0x1c,0x00,0x15,0x00,0x17,0x00,0x0e,0x00,0x03,0x00,0xfe,0xff,0x01,0x00,0xfe,0xff,0xff,0xff,0xfb,0xff,0x04,0x00,0xfd,0xff,0x0b,0x00,0xf6,0xff,0x08,0x00,0x0c,0x00,0x03,0x00,0x05,0x00,0x08,0x00,0x00,0x00,0xf5,0xff,0xfc,0xff,0xf6,0xff,0x03,0x00,0xf4,0xff,0xf8,0xff,0xe9,0xff,0xea,0xff,0xe6,0xff,0xe4,0xff,0x03,0x00,0x0e,0x00,0x15,0x00,0x1d,0x00,0x1c,0x00,0x14,0x00,0x0e,0x00,0x10,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x00,0x0f,0x00,0x08,0x00,0xfc,0xff,0xf8,0xff,0xf7,0xff,0xf2,0xff,0xff,0xff,0x04,0x00,0x00,0x00,0xfa,0xff,0xf3,0xff,0xeb,0xff,0xe7,0xff,0xdf,0xff,0xe8,0xff,0xe0,0xff,0xea,0xff,0xcf,0xff,0xd0,0xff,0xda,0xff,0xe7,0xff,0x02,0x00,0x0d,0x00,0x14,0x00,0x11,0x00,0x11,0x00,0x19,0x00,0x0c,0x00,0x0b,0x00,0x04,0x00,0x0a,0x00,0x0f,0x00,0x12,0x00,0x0f,0x00,0xf9,0xff,0x06,0x00,0xeb,0xff,0xf2,0xff,0xf8,0xff,0x1b,0x00,0xfc,0xff,0x01,0x00,0xf7,0xff,0x03,0x00,0xfd,0xff,0x13,0x00,0x30,0x00,0x34,0x00,0x13,0x00,0x03,0x00,0xfe,0xff,0x04,0x00,0x06,0x00,0x04,0x00,0x01,0x00,0x04,0x00,0xfd,0xff,0xfd,0xff,0xe9,0xff,0xf1,0xff,0xef,0xff,0xe7,0xff,0xfd,0xff,0xf9,0xff,0xfc,0xff,0x02,0x00,0xfb,0xff,0xfe,0xff,0xfc,0xff,0xf8,0xff,0xf8,0xff,0xfb,0xff,0xf9,0xff,0xea,0xff,0xe5,0xff,0xf7,0xff,0x0d,0x00,0x26,0x00,0x45,0x00,0x45,0x00,0x18,0x00,0xfd,0xff,0xf7,0xff,0xfd,0xff,0x02,0x00,0x0c,0x00,0x14,0x00,0x13,0x00,0x0e,0x00,0x01,0x00,0xfc,0xff,0xfc,0xff,0xf9,0xff,0xf4,0xff,0xf7,0xff,0xf2,0xff,0x06,0x00,0x08,0x00,0x0c,0x00,0x0f,0x00,0x08,0x00,0x06,0x00,0x00,0x00,0xea,0xff,0x03,0x00,0xf3,0xff,0xe9,0xff,0xe9,0xff,0xe4,0xff,0xf1,0xff,0x1f,0x00,0x19,0x00,0xfe,0xff,0xec,0xff,0xe3,0xff,0xe3,0xff,0xe8,0xff,0xec,0xff,0x07,0x00,0x08,0x00,0x0a,0x00,0xfb,0xff,0x07,0x00,0x06,0x00,0xfa,0xff,0x06,0x00,0xeb,0xff,0xed,0xff,0xf5,0xff,0xfd,0xff,0x09,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0xea,0xff,0xed,0xff,0xf4,0xff,0xff,0xff,0xfd,0xff,0x01,0x00,0xd2,0xff,0xba,0xff,0xb7,0xff,0xdb,0xff,0xee,0xff,0xf7,0xff,0xf7,0xff,0xf8,0xff,0xfc,0xff,0xf3,0xff,0xe6,0xff,0xf5,0xff,0xf7,0xff,0xfa,0xff,0xfb,0xff,0x03,0x00,0xff,0xff,0x0a,0x00,0xfb,0xff,0xff,0xff,0xea,0xff,0xf5,0xff,0xf6,0xff,0xfa,0xff,0xfa,0xff,0xfb,0xff,0x0d,0x00,0xfb,0xff,0x05,0x00,0x19,0x00,0x4f,0x00,0x56,0x00,0x26,0x00,0xe8,0xff,0xd8,0xff,0xdd,0xff,0xe8,0xff,0xe8,0xff,0xf4,0xff,0x02,0x00,0x0b,0x00,0x0c,0x00,0x08,0x00,0x03,0x00,0xfe,0xff,0x00,0x00,0x0a,0x00,0x01,0x00,0x05,0x00,0x0a,0x00,0x0f,0x00,0x04,0x00,0xf3,0xff,0xe8,0xff,0xf2,0xff,0xf8,0xff,0xfe,0xff,0x01,0x00,0x0f,0x00,0x08,0x00,0x18,0x00,0x1d,0x00,0x4b,0x00,0x4b,0x00,0x55,0x00,0x26,0x00,0x19,0x00,0x07,0x00,0xfa,0xff,0xee,0xff,0xf4,0xff,0x01,0x00,0x02,0x00,0x05,0x00,0x05,0x00,0xfc,0xff,0x01,0x00,0x03,0x00,0x00,0x00,0xff,0xff,0xfd,0xff,0x01,0x00,0x11,0x00,0x0e,0x00,0xf9,0xff,0xf7,0xff,0xec,0xff,0xf7,0xff,0xff,0xff,0x0e,0x00,0x0d,0x00,0x12,0x00,0x01,0x00,0x14,0x00,0xea,0xff,0x03,0x00,0xf4,0xff,0x09,0x00,0xef,0xff,0xf6,0xff,0xfa,0xff,0xf0,0xff,0x08,0x00,0xf0,0xff,0xf6,0xff,0xf2,0xff,0x09,0x00,0xf7,0xff,0xe2,0xff,0xf5,0xff,0x0b,0x00,0x13,0x00,0x11,0x00,0xf2,0xff,0xf5,0xff,0x05,0x00,0xfd,0xff,0x0e,0x00,0xf3,0xff,0x04,0x00,0x03,0x00,0x05,0x00,0x01,0x00,0x06,0x00,0xf0,0xff,0x14,0x00,0xf3,0xff,0xef,0xff,0xf8,0xff,0x12,0x00,0xfa,0xff,0x00,0x00,0x12,0x00,0x08,0x00,0xef,0xff,0x00,0x00,0xf6,0xff,0xf4,0xff,0xf7,0xff,0x10,0x00,0x08,0x00,0xe9,0xff,0x07,0x00,0xe7,0xff,0xf4,0xff,0x00,0x00,0xfc,0xff,0x14,0x00,0x01,0x00,0x04,0x00,0x13,0x00,0x02,0x00,0x0c,0x00,0xee,0xff,0x09,0x00,0x0d,0x00,0xed,0xff,0x12,0x00,0xf9,0xff,0xf4,0xff,0xf0,0xff,0x15,0x00,0xee,0xff,0xf7,0xff,0xf4,0xff,0xf5,0xff,0x04,0x00,0xf0,0xff,0xe7,0xff,0xfa,0xff,0x0c,0x00,0xea,0xff,0x10,0x00,0x08,0x00,0xfc,0xff,0xfc,0xff,0xee,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0x0c,0x00,0xfc,0xff,0x0f,0x00,0x0a,0x00,0x10,0x00,0x0e,0x00,0x0c,0x00,0x03,0x00,0x09,0x00,0x03,0x00,0x0a,0x00,0x07,0x00,0x07,0x00,0x08,0x00,0x02,0x00,0xfc,0xff,0xf7,0xff,0xfb,0xff,0x02,0x00,0x0b,0x00,0x13,0x00,0x1c,0x00,0x1b,0x00,0x14,0x00,0xfc,0xff,0xe6,0xff,0xd4,0xff,0xce,0xff,0xdc,0xff,0xf1,0xff,0x03,0x00,0x10,0x00,0x0b,0x00,0x07,0x00,0x06,0x00,0x00,0x00,0x05,0x00,0x0f,0x00,0x08,0x00,0x04,0x00,0x03,0x00,0x07,0x00,0xff,0xff,0x01,0x00,0x02,0x00,0xff,0xff,0xfb,0xff,0xf8,0xff,0xf4,0xff,0xfa,0xff,0xfa,0xff,0xfc,0xff,0x06,0x00,0x0d,0x00,0x14,0x00,0x1d,0x00,0x1a,0x00,0x11,0x00,0x08,0x00,0xfd,0xff,0xf3,0xff,0xe3,0xff,0xe6,0xff,0xe8,0xff,0xee,0xff,0xf1,0xff,0xf9,0xff,0xfa,0xff,0x02,0x00,0x05,0x00,0xfd,0xff,0xfd,0xff,0xfd,0xff,0x01,0x00,0xf2,0xff,0xfa,0xff,0xf8,0xff,0xfc,0xff,0xfa,0xff,0xfe,0xff,0x01,0x00,0xfb,0xff,0xf9,0xff,0xf5,0xff,0xf3,0xff,0xf2,0xff,0xfe,0xff,0x05,0x00,0x1c,0x00,0x2a,0x00,0x2d,0x00,0x2e,0x00,0x16,0x00,0xff,0xff,0xea,0xff,0xe2,0xff,0xe1,0xff,0xed,0xff,0xed,0xff,0xfd,0xff,0xf9,0xff,0xfb,0xff,0xf4,0xff,0x14,0x00,0x0c,0x00,0x09,0x00,0x06,0x00,0x0c,0x00,0x0c,0x00,0x0a,0x00,0x13,0x00,0x14,0x00,0x00,0x00,0x06,0x00,0x0d,0x00,0x00,0x00,0x01,0x00,0xf6,0xff,0xee,0xff,0x10,0x00,0xf1,0xff,0xfa,0xff,0x0a,0x00,0x00,0x00,0x0f,0x00,0xf9,0xff,0x05,0x00,0xfd,0xff,0xf9,0xff,0xff,0xff,0xf6,0xff,0xf4,0xff,0x0b,0x00,0x00,0x00,0x16,0x00,0x12,0x00,0xfc,0xff,0x02,0x00,0xfa,0xff,0x0e,0x00,0x0d,0x00,0xee,0xff,0xfd,0xff,0xf3,0xff,0x04,0x00,0xf0,0xff,0xf5,0xff,0xf9,0xff,0xfb,0xff,0xf6,0xff,0xff,0xff,0x0f,0x00,0xfc,0xff,0xf4,0xff,0x0f,0x00,0xf4,0xff,0x09,0x00,0xed,0xff,0xf2,0xff,0x0d,0x00,0x02,0x00,0xec,0xff,0xfa,0xff,0x01,0x00,0x12,0x00,0x02,0x00,0xf8,0xff,0x01,0x00,0x12,0x00,0x08,0x00,0xef,0xff,0xfd,0xff,0x07,0x00,0x0b,0x00,0x00,0x00,0x04,0x00,0xf5,0xff,0x13,0x00,0x02,0x00,0xf0,0xff,0x0f,0x00,0x0e,0x00,0x0b,0x00,0x11,0x00,0xf5,0xff,0xf4,0xff,0xfb,0xff,0x04,0x00,0x15,0x00,0xfe,0xff,0xf3,0xff,0x10,0x00,0xfb,0xff,0x05,0x00,0x04,0x00,0x05,0x00,0x04,0x00,0x05,0x00,0xed,0xff,0xfb,0xff,0x0a,0x00,0xf6,0xff,0xfd,0xff,0xf5,0xff,0x12,0x00,0xfe,0xff,0x0e,0x00,0x04,0x00,0xfb,0xff,0x11,0x00,0x05,0x00,0x06,0x00,0x1e,0x00,0x05,0x00,0xee,0xff,0x81,0xff,0xf7,0xff,0xfd,0xff,0x3a,0x00,0x16,0x00,0xfd,0xff,0x8f,0xff,0x07,0x00,0x07,0x00,0x0c,0x00,0x00,0x00,0x15,0x00,0x15,0x00,0x09,0x00,0xfd,0xff,0x1e,0x00,0xf4,0xff,0x01,0x00,0x00,0x00,0x02,0x00,0x05,0x00,0xea,0xff,0x7b,0x00,0x0d,0x00,0x0e,0x00,0xf9,0xff,0xf9,0xff,0x17,0x00,0x1d,0x00,0xf6,0xff,0xf9,0xff,0x03,0x00,0xfa,0xff,0xf7,0xff,0x00,0x00,0xfa,0xff,0xfe,0xff,0x03,0x00,0x06,0x00,0x2e,0x00,0xf7,0xff,0xee,0xff,0x03,0x00,0xf9,0xff,0x01,0x00,0xec,0xff,0x0b,0x00,0x01,0x00,0xf4,0xff,0x0c,0x00,0xf5,0xff,0x01,0x00,0x0f,0x00,0xf7,0xff,0xf5,0xff,0x09,0x00,0xfc,0xff,0x06,0x00,0x13,0x00,0x04,0x00,0xdc,0xff,0x2a,0x00,0x02,0x00,0xe2,0xff,0x05,0x00,0x0e,0x00,0x01,0x00,0x00,0x00,0x29,0x00,0xf2,0xff,0xde,0xff,0x08,0x00,0x21,0x00,0x18,0x00,0x06,0x00,0xf6,0xff,0x12,0x00,0x0e,0x00,0x02,0x00,0x02,0x00,0xf9,0xff,0xfe,0xff,0xfc,0xff,0x06,0x00,0x05,0x00,0xe1,0xff,0x1a,0x00,0xf8,0xff,0x06,0x00,0xed,0xff,0x0c,0x00,0x0e,0x00,0x1b,0x00,0xf5,0xff,0xf6,0xff,0xff,0xff,0x07,0x00,0xf8,0xff,0x01,0x00,0xfd,0xff,0xff,0xff,0xfb,0xff,0x04,0x00,0xca,0xff,0xf3,0xff,0xd1,0xff,0xfd,0xff,0x09,0x00,0x00,0x00,0x04,0x00,0x2c,0x00,0x04,0x00,0xeb,0xff,0x09,0x00,0xfb,0xff,0xfc,0xff,0x12,0x00,0x0a,0x00,0x05,0x00,0x09,0x00,0xff,0xff,0x0a,0x00,0x1a,0x00,0x06,0x00,0xd4,0xff,0x0e,0x00,0x01,0x00,0xe2,0xff,0xfa,0xff,0x15,0x00,0xfe,0xff,0xc6,0xff,0x2e,0x00,0xce,0xff,0x22,0x00,0x0c,0x00,0x18,0x00,0x03,0x00,0x13,0x00,0x13,0x00,0xfc,0xff,0x15,0x00,0xf7,0xff,0xfc,0xff,0x03,0x00,0xff,0xff,0xff,0xff,0xeb,0xff,0x02,0x00,0xf4,0xff,0xfb,0xff,0x0f,0x00,0x12,0x00,0xf4,0xff,0xfc,0xff,0x06,0x00,0x0f,0x00,0xf1,0xff,0xdc,0xff,0x01,0x00,0x00,0x00,0xf2,0xff,0xfb,0xff,0x2d,0x00,0x01,0x00,0x06,0x00,0x08,0x00,0xe2,0xff,0x1b,0x00,0xe8,0xff,0x00,0x00,0xf7,0xff,0x05,0x00,0x12,0x00,0x24,0x00,0xf9,0xff,0xdc,0xff,0x07,0x00,0x1a,0x00,0xb9,0xff,0x09,0x00,0x0c,0x00,0x11,0x00,0x14,0x00,0x09,0x00,0x16,0x00,0x0e,0x00,0xf5,0xff,0x09,0x00,0xe5,0xff,0xfc,0xff,0x22,0x00,0x42,0x00,0x06,0x00,0x06,0x00,0xf3,0xff,0xdb,0xff,0xf3,0xff,0x37,0x00,0x07,0x00,0xf7,0xff,0xdc,0xff,0xf6,0xff,0xee,0xff,0x07,0x00,0x03,0x00,0xc9,0xff,0x01,0x00,0x2a,0x00,0xf7,0xff,0x08,0x00,0xfb,0xff,0xfc,0xff,0x24,0x00,0xd7,0xff,0xf4,0xff,0x01,0x00,0x01,0x00,0x05,0x00,0x0c,0x00,0xf9,0xff,0xf8,0xff,0xaa,0xff,0x07,0x00,0xf3,0xff,0xf7,0xff,0xf7,0xff,0xe4,0xff,0xfc,0xff,0xfb,0xff,0x20,0x00,0x1b,0x00,0x43,0x00,0x1c,0x00,0xf4,0xff,0xfd,0xff,0x03,0x00,0x0c,0x00,0xe6,0xff,0xee,0xff,0xe7,0xff,0xfd,0xff,0x3e,0x00,0x22,0x00,0xf4,0xff,0x0f,0x00,0x06,0x00,0x22,0x00,0x23,0x00,0x15,0x00,0xe5,0xff,0x00,0x00,0x1c,0x00,0xe6,0xff,0xf4,0xff,0x0d,0x00,0xbe,0xff,0x05,0x00,0x0b,0x00,0x10,0x00,0xe4,0xff,0x40,0x00,0x09,0x00,0x02,0x00,0xf6,0xff,0xf2,0xff,0xf7,0xff,0x0c,0x00,0x00,0x00,0xe9,0xff,0x14,0x00,0x03,0x00,0xd3,0xff,0x00,0x00,0x18,0x00,0xf0,0xff,0xfa,0xff,0x0b,0x00,0xed,0xff,0x0a,0x00,0xfd,0xff,0xfa,0xff,0x06,0x00,0x13,0x00,0xf3,0xff,0xf8,0xff,0x07,0x00,0x0b,0x00,0xec,0xff,0xfb,0xff,0x10,0x00,0xfb,0xff,0xf1,0xff,0x18,0x00,0xf6,0xff,0x08,0x00,0x43,0x00,0x18,0x00,0xec,0xff,0x03,0x00,0x17,0x00,0x13,0x00,0xe8,0xff,0xf4,0xff,0x14,0x00,0x02,0x00,0xde,0xff,0x2e,0x00,0x02,0x00,0x06,0x00,0x04,0x00,0x17,0x00,0x0d,0x00,0xe5,0xff,0xe3,0xff,0x20,0x00,0x10,0x00,0xf4,0xff,0xe8,0xff,0x07,0x00,0x0b,0x00,0xfd,0xff,0xd9,0xff,0x06,0x00,0xea,0xff,0x3a,0x00,0x09,0x00,0x03,0x00,0xf1,0xff,0xfa,0xff,0xfb,0xff,0xfe,0xff,0xf8,0xff,0xe7,0xff,0x01,0x00,0x00,0x00,0x12,0x00,0x0b,0x00,0x16,0x00,0xed,0xff,0xca,0xff,0x08,0x00,0xe7,0xff,0xf1,0xff,0xf8,0xff,0x0c,0x00,0x12,0x00,0x12,0x00,0xed,0xff,0x01,0x00,0x31,0x00,0xfe,0xff,0xf4,0xff,0x00,0x00,0x15,0x00,0xfd,0xff,0xf0,0xff,0x18,0x00,0xff,0xff,0x02,0x00,0x02,0x00,0x0c,0x00,0xef,0xff,0x0c,0x00,0x21,0x00,0xf0,0xff,0xf3,0xff,0xf4,0xff,0x34,0x00,0x05,0x00,0xeb,0xff,0xfa,0xff,0x0b,0x00,0x16,0x00,0xff,0xff,0xea,0xff,0x06,0x00,0xdc,0xff,0xf7,0xff,0x11,0x00,0xfe,0xff,0xfd,0xff,0xe1,0xff,0xf6,0xff,0x05,0x00,0x01,0x00,0xfc,0xff,0x09,0x00,0xfe,0xff,0xee,0xff,0xfb,0xff,0xfe,0xff,0xee,0xff,0x01,0x00,0xff,0xff,0xe5,0xff,0x15,0x00,0xf2,0xff,0x00,0x00,0x04,0x00,0xf8,0xff,0x05,0x00,0xf6,0xff,0x0b,0x00,0x30,0x00,0x02,0x00,0xfc,0xff,0xf0,0xff,0x09,0x00,0xf6,0xff,0x0f,0x00,0x02,0x00,0xee,0xff,0x02,0x00,0x1e,0x00,0xf2,0xff,0xfb,0xff,0x05,0x00,0x06,0x00,0xfd,0xff,0x0d,0x00,0xf5,0xff,0x00,0x00,0x02,0x00,0xb6,0xff,0x04,0x00,0xef,0xff,0x1f,0x00,0xdf,0xff,0xf8,0xff,0xfa,0xff,0xf6,0xff,0x23,0x00,0xfa,0xff,0x02,0x00,0xfa,0xff,0x05,0x00,0x04,0x00,0x04,0x00,0xae,0xff,0x00,0x00,0xf5,0xff,0x03,0x00,0xfd,0xff,0x12,0x00,0xf2,0xff,0x49,0x00,0x21,0x00,0x05,0x00,0x02,0x00,0xfd,0xff,0xf8,0xff,0xee,0xff,0xeb,0xff,0x27,0x00,0x01,0x00,0x00,0x00,0x05,0x00,0xe5,0xff,0xea,0xff,0xf3,0xff,0xf6,0xff,0x02,0x00,0xf9,0xff,0xf2,0xff,0x20,0x00,0xf6,0xff,0x00,0x00,0x10,0x00,0xfe,0xff,0xc0,0xff,0xe6,0xff,0xe0,0xff,0x0e,0x00,0xff,0xff,0x9a,0xff,0xd6,0xff,0xfa,0xff,0x30,0x00,0xe6,0xff,0x00,0x00,0xf9,0xff,0x05,0x00,0xfb,0xff,0x32,0x00,0x00,0x00,0xfe,0xff,0x09,0x00,0xc5,0xff,0x0d,0x00,0x2a,0x00,0xff,0xff,0xf6,0xff,0x0c,0x00,0xf7,0xff,0xfc,0xff,0x0c,0x00,0x22,0x00,0xc4,0xff,0xf3,0xff,0x2d,0x00,0xde,0xff,0xf7,0xff,0x07,0x00,0x27,0x00,0xf2,0xff,0xe8,0xff,0xf6,0xff,0xf9,0xff,0xda,0xff,0x47,0x00,0xb3,0xff,0x3d,0x00,0x3f,0x00,0x3f,0x00,0xf9,0xff,0xf1,0xff,0xc8,0xff,0x1b,0x00,0x29,0x00,0x2f,0x00,0x00,0x00,0xec,0xff,0xdd,0xff,0x03,0x00,0xdf,0xff,0xdf,0xff,0xfc,0xff,0x16,0x00,0x08,0x00,0x3c,0x00,0xf5,0xff,0x48,0x00,0x28,0x00,0xf2,0xff,0xe5,0xff,0x02,0x00,0x31,0x00,0x24,0x00,0xdc,0xff,0xf2,0xff,0x1e,0x00,0x56,0x00,0xc3,0xff,0x3f,0x00,0x1f,0x00,0x0b,0x00,0x21,0x00,0xdc,0xff,0x23,0x00,0x04,0x00,0xd2,0xff,0xf6,0xff,0xd2,0xff,0xda,0xff,0x0c,0x00,0x3b,0x00,0xd5,0xff,0xda,0xff,0xf1,0xff,0x03,0x00,0xeb,0xff,0x19,0x00,0x21,0x00,0xde,0xff,0xe6,0xff,0xa8,0xff,0x2d,0x00,0x18,0x00,0xf4,0xff,0xfa,0xff,0x23,0x00,0x03,0x00,0xff,0xff,0xfc,0xff,0x11,0x00,0xb2,0xff,0xe9,0xff,0xf0,0xff,0xe4,0xff,0xce,0xff,0x03,0x00,0xe4,0xff,0x0c,0x00,0xed,0xff,0x19,0x00,0x34,0x00,0x26,0x00,0x60,0x00,0xc6,0xff,0xe7,0xff,0xfc,0xff,0xe6,0xff,0x19,0x00,0x07,0x00,0x03,0x00,0x12,0x00,0xe7,0xff,0x2f,0x00,0xe4,0xff,0xed,0xff,0xef,0xff,0x25,0x00,0x08,0x00,0xc0,0xff,0x0b,0x00,0xfb,0xff,0x8b,0xff,0x0a,0x00,0x0a,0x00,0x53,0x00,0xe9,0xff,0xf4,0xff,0x30,0x00,0xb5,0xff,0x42,0x00,0xeb,0xff,0x14,0x00,0xf3,0xff,0xf2,0xff,0xfc,0xff,0x29,0x00,0xfd,0xff,0xee,0xff,0x51,0x00,0x03,0x00,0xd3,0xff,0x0f,0x00,0xd9,0xff,0xdc,0xff,0xf6,0xff,0xc8,0xff,0xf5,0xff,0x1b,0x00,0x34,0x00,0x1f,0x00,0x04,0x00,0xe3,0xff,0x2b,0x00,0xf8,0xff,0x20,0x00,0xff,0xff,0xde,0xff,0xeb,0xff,0x04,0x00,0x20,0x00,0xe5,0xff,0x16,0x00,0xe1,0xff,0xd0,0xff,0xf5,0xff,0x1c,0x00,0x1b,0x00,0x09,0x00,0x18,0x00,0x24,0x00,0x33,0x00,0x2e,0x00,0xf3,0xff,0xfd,0xff,0x42,0x00,0x10,0x00,0x0c,0x00,0x4e,0x00,0x2c,0x00,0xd0,0xff,0xda,0xff,0x38,0x00,0xfa,0xff,0x10,0x00,0x07,0x00,0xf6,0xff,0xdd,0xff,0x1e,0x00,0x18,0x00,0x3e,0x00,0x39,0x00,0xe9,0xff,0x25,0x00,0x31,0x00,0xd4,0xff,0xfd,0xff,0x1c,0x00,0xfc,0xff,0xd7,0xff,0xde,0xff,0xe4,0xff,0xf3,0xff,0xf3,0xff,0x01,0x00,0x28,0x00,0x36,0x00,0x05,0x00,0x27,0x00,0x12,0x00,0x18,0x00,0x02,0x00,0xbb,0xff,0x93,0xff,0x29,0x00,0xc1,0xff,0xeb,0xff,0x05,0x00,0x23,0x00,0x07,0x00,0xf5,0xff,0x13,0x00,0x1a,0x00,0xd8,0xff,0xe7,0xff,0xf8,0xff,0xc5,0xff,0xf0,0xff,0xe9,0xff,0xf0,0xff,0xfd,0xff,0xdd,0xff,0xb3,0xff,0x20,0x00,0xd6,0xff,0xfd,0xff,0x07,0x00,0xfa,0xff,0x00,0x00,0x1b,0x00,0xd2,0xff,0x3c,0x00,0x43,0x00,0xfb,0xff,0xff,0xff,0xd6,0xff,0xf0,0xff,0xd8,0xff,0xcc,0xff,0x58,0x00,0xe7,0xff,0xf6,0xff,0xba,0xff,0x27,0x00,0x18,0x00,0xfb,0xff,0xcf,0xff,0x1c,0x00,0xee,0xff,0xf1,0xff,0x0e,0x00,0xfb,0xff,0x31,0x00,0xe7,0xff,0x0d,0x00,0x0b,0x00,0xe5,0xff,0xe2,0xff,0x0a,0x00,0xec,0xff,0x25,0x00,0x0b,0x00,0x23,0x00,0xec,0xff,0xf3,0xff,0x18,0x00,0xc8,0xff,0xee,0xff,0x0f,0x00,0xd9,0xff,0xb1,0xff,0x32,0x00,0xf6,0xff,0x9c,0xff,0xef,0xff,0xdf,0xff,0xcc,0xff,0xc6,0xff,0x0d,0x00,0x11,0x00,0x13,0x00,0x16,0x00,0xf6,0xff,0xca,0xff,0x16,0x00,0xf0,0xff,0xdf,0xff,0xd3,0xff,0xff,0xff,0xc1,0xff,0xef,0xff,0xdb,0xff,0x3c,0x00,0x13,0x00,0xeb,0xff,0x37,0x00,0x13,0x00,0x20,0x00,0x10,0x00,0x19,0x00,0xe8,0xff,0xc9,0xff,0x15,0x00,0xfc,0xff,0x11,0x00,0x02,0x00,0x0f,0x00,0xf7,0xff,0xfc,0xff,0x4a,0x00,0x35,0x00,0x06,0x00,0xd0,0xff,0x28,0x00,0xca,0xff,0x25,0x00,0x01,0x00,0xbd,0xff,0xed,0xff,0xa3,0xff,0x23,0x00,0xd8,0xff,0x04,0x00,0xbb,0xff,0x07,0x00,0xec,0xff,0xf2,0xff,0xf6,0xff,0x0a,0x00,0xde,0xff,0x33,0x00,0xfd,0xff,0x04,0x00,0x06,0x00,0xca,0xff,0x4a,0x00,0xd5,0xff,0xf6,0xff,0x19,0x00,0x05,0x00,0xe8,0xff,0x16,0x00,0x09,0x00,0xe4,0xff,0xd7,0xff,0x06,0x00,0xdc,0xff,0xda,0xff,0x22,0x00,0x42,0x00,0x30,0x00,0x05,0x00,0x2e,0x00,0x50,0x00,0xfd,0xff,0xf8,0xff,0xdf,0xff,0x38,0x00,0xdc,0xff,0xee,0xff,0xec,0xff,0x26,0x00,0x2a,0x00,0xd4,0xff,0x20,0x00,0x28,0x00,0xd9,0xff,0xe9,0xff,0x42,0x00,0xfe,0xff,0xda,0xff,0xe8,0xff,0x1d,0x00,0xb7,0xff,0x20,0x00,0x13,0x00,0x32,0x00,0xd4,0xff,0x9f,0xff,0x56,0x00,0xdf,0xff,0x2b,0x00,0x2e,0x00,0xb0,0xff,0x14,0x00,0x12,0x00,0x2c,0x00,0x41,0x00,0x1e,0x00,0x03,0x00,0x01,0x00,0xd9,0xff,0x20,0x00,0xf8,0xff,0xbb,0xff,0x8a,0xff,0x12,0x00,0xd1,0xff,0x52,0x00,0xd3,0xff,0x20,0x00,0x91,0xff,0x1f,0x00,0xeb,0xff,0x45,0x00,0xef,0xff,0xd9,0xff,0x03,0x00,0x40,0x00,0x29,0x00,0xcf,0xff,0xeb,0xff,0x1b,0x00,0x6d,0x00,0xdd,0xff,0x49,0x00,0x26,0x00,0xff,0xff,0xea,0xff,0x02,0x00,0xe4,0xff,0xd8,0xff,0xbf,0xff,0xef,0xff,0xde,0xff,0xca,0xff,0xfd,0xff,0xe8,0xff,0xe3,0xff,0xdd,0xff,0x2c,0x00,0x2c,0x00,0x1b,0x00,0x0a,0x00,0x23,0x00,0xfb,0xff,0xe6,0xff,0x38,0x00,0xdc,0xff,0x27,0x00,0x09,0x00,0xe3,0xff,0x31,0x00,0x0e,0x00,0xe0,0xff,0xe0,0xff,0x62,0x00,0x66,0x00,0xe4,0xff,0xef,0xff,0x3a,0x00,0x0c,0x00,0x07,0x00,0x0d,0x00,0xdf,0xff,0xec,0xff,0xe9,0xff,0x0a,0x00,0xd7,0xff,0xe6,0xff,0x17,0x00,0xf3,0xff,0x0d,0x00,0xdb,0xff,0x49,0x00,0x54,0x00,0x2b,0x00,0xeb,0xff,0x05,0x00,0xf2,0xff,0xed,0xff,0x35,0x00,0xe3,0xff,0x38,0x00,0x10,0x00,0x27,0x00,0x31,0x00,0x11,0x00,0xcf,0xff,0x0d,0x00,0x08,0x00,0xd9,0xff,0x05,0x00,0x01,0x00,0xdf,0xff,0xd9,0xff,0xf9,0xff,0xa9,0xff,0xd6,0xff,0x49,0x00,0x32,0x00,0x12,0x00,0xd1,0xff,0xf7,0xff,0xef,0xff,0xef,0xff,0xe4,0xff,0xee,0xff,0xe6,0xff,0x40,0x00,0xfa,0xff,0xfc,0xff,0xbf,0xff,0x31,0x00,0xee,0xff,0x06,0x00,0x46,0x00,0x26,0x00,0x47,0x00,0xb6,0xff,0xf9,0xff,0x3a,0x00,0x17,0x00,0xcc,0xff,0x03,0x00,0xd1,0xff,0x27,0x00,0x01,0x00,0xd8,0xff,0xff,0xff,0x09,0x00,0x18,0x00,0xf3,0xff,0xf6,0xff,0xea,0xff,0x19,0x00,0xf3,0xff,0xb8,0xff,0xca,0xff,0x02,0x00,0x16,0x00,0xfe,0xff,0x04,0x00,0x00,0x00,0x13,0x00,0xf8,0xff,0x49,0x00,0xfc,0xff,0xf0,0xff,0xd4,0xff,0xd6,0xff,0x08,0x00,0x09,0x00,0xfb,0xff,0x0b,0x00,0x1b,0x00,0x5e,0x00,0x07,0x00,0xf1,0xff,0xac,0xff,0x01,0x00,0xf8,0xff,0xe0,0xff,0xc7,0xff,0x29,0x00,0x09,0x00,0x4f,0x00,0xf2,0xff,0x3b,0x00,0xdf,0xff,0xf6,0xff,0x0e,0x00,0x41,0x00,0xf4,0xff,0xda,0xff,0xab,0xff,0xf4,0xff,0x06,0x00,0xf8,0xff,0x2e,0x00,0x03,0x00,0x01,0x00,0x14,0x00,0xc4,0xff,0x01,0x00,0xf7,0xff,0xea,0xff,0x27,0x00,0xda,0xff,0x18,0x00,0xe1,0xff,0xf7,0xff,0xdb,0xff,0xfd,0xff,0xd4,0xff,0x9b,0xff,0xd6,0xff,0xec,0xff,0xfd,0xff,0xfc,0xff,0x42,0x00,0xe2,0xff,0x28,0x00,0x19,0x00,0x06,0x00,0xbb,0xff,0x3b,0x00,0x00,0x00,0x04,0x00,0x30,0x00,0xc8,0xff,0xf6,0xff,0x00,0x00,0xf3,0xff,0x11,0x00,0x2b,0x00,0xe6,0xff,0x30,0x00,0xe8,0xff,0x2c,0x00,0x04,0x00,0x03,0x00,0xd8,0xff,0x0f,0x00,0x1b,0x00,0xed,0xff,0xfd,0xff,0xe5,0xff,0x29,0x00,0x1f,0x00,0x04,0x00,0xf4,0xff,0xcd,0xff,0x2e,0x00,0x00,0x00,0x9e,0xff,0xcf,0xff,0xf0,0xff,0x03,0x00,0x24,0x00,0x22,0x00,0xd5,0xff,0x04,0x00,0x0e,0x00,0x1b,0x00,0xed,0xff,0xe5,0xff,0x04,0x00,0x0c,0x00,0x41,0x00,0xf8,0xff,0x08,0x00,0x14,0x00,0x1f,0x00,0xc7,0xff,0xf3,0xff,0xe7,0xff,0xfa,0xff,0xeb,0xff,0xd7,0xff,0x28,0x00,0x19,0x00,0x40,0x00,0xf5,0xff,0x10,0x00,0xa2,0xff,0x0c,0x00,0x01,0x00,0x13,0x00,0x1d,0x00,0xe4,0xff,0xe9,0xff,0xc0,0xff,0xd6,0xff,0x16,0x00,0x1a,0x00,0x1e,0x00,0xd2,0xff,0xd3,0xff,0xef,0xff,0xfd,0xff,0x26,0x00,0x05,0x00,0xeb,0xff,0xf8,0xff,0xcb,0xff,0x32,0x00,0xa6,0xff,0xdc,0xff,0x0f,0x00,0x01,0x00,0xf2,0xff,0x1c,0x00,0x1b,0x00,0x22,0x00,0x03,0x00,0x03,0x00,0xed,0xff,0x17,0x00,0x0d,0x00,0x06,0x00,0x14,0x00,0xb9,0xff,0x22,0x00,0x1e,0x00,0x04,0x00,0xf4,0xff,0x1b,0x00,0xda,0xff,0xe8,0xff,0xcf,0xff,0x48,0x00,0x23,0x00,0xe4,0xff,0xf1,0xff,0xf6,0xff,0xda,0xff,0x8b,0xff,0x06,0x00,0xde,0xff,0xe2,0xff,0xf2,0xff,0x02,0x00,0xd9,0xff,0x27,0x00,0x54,0x00,0x09,0x00,0x3b,0x00,0x1c,0x00,0x00,0x00,0xc6,0xff,0x06,0x00,0x07,0x00,0x2e,0x00,0xfa,0xff,0x2c,0x00,0x0d,0x00,0x1f,0x00,0xfe,0xff,0xdd,0xff,0x0c,0x00,0xd1,0xff,0xc1,0xff,0xf0,0xff,0x25,0x00,0x13,0x00,0xf6,0xff,0x50,0x00,0xe1,0xff,0xb0,0xff,0xb2,0xff,0xcc,0xff,0x56,0x00,0x03,0x00,0xe8,0xff,0x1a,0x00,0xde,0xff,0xd7,0xff,0xfe,0xff,0x3e,0x00,0xf2,0xff,0x26,0x00,0xc2,0xff,0xfe,0xff,0x04,0x00,0x25,0x00,0xfb,0xff,0xef,0xff,0xca,0xff,0x4a,0x00,0x05,0x00,0x11,0x00,0xe5,0xff,0x3f,0x00,0xe8,0xff,0x0f,0x00,0x03,0x00,0xea,0xff,0xea,0xff,0x05,0x00,0xec,0xff,0x19,0x00,0xfa,0xff,0xe3,0xff,0xf7,0xff,0xe5,0xff,0x36,0x00,0xd0,0xff,0xe2,0xff,0xed,0xff,0x21,0x00,0x4b,0x00,0xe2,0xff,0x10,0x00,0xec,0xff,0x7f,0x00,0xc4,0xff,0xfc,0xff,0x34,0x00,0x09,0x00,0x0e,0x00,0x19,0x00,0x06,0x00,0x17,0x00,0xcc,0xff,0xf1,0xff,0xff,0xff,0x10,0x00,0xe2,0xff,0x0a,0x00,0x41,0x00,0x02,0x00,0xd8,0xff,0xfa,0xff,0x31,0x00,0x1e,0x00,0xd8,0xff,0xc2,0xff,0x0a,0x00,0xb4,0xff,0x0e,0x00,0x14,0x00,0xf0,0xff,0xfa,0xff,0xf3,0xff,0x1b,0x00,0xd4,0xff,0xdb,0xff,0xfa,0xff,0xfa,0xff,0x25,0x00,0x02,0x00,0xc5,0xff,0xf4,0xff,0x0c,0x00,0x19,0x00,0xc5,0xff,0x1d,0x00,0xed,0xff,0x2e,0x00,0x35,0x00,0xbe,0xff,0x1b,0x00,0x03,0x00,0xd9,0xff,0xe5,0xff,0x4f,0x00,0x2b,0x00,0x31,0x00,0xad,0xff,0xcb,0xff,0x21,0x00,0x4b,0x00,0x72,0x00,0x0f,0x00,0x09,0x00,0xf6,0xff,0x04,0x00,0xfd,0xff,0xf8,0xff,0xd7,0xff,0x30,0x00,0x17,0x00,0xdc,0xff,0x12,0x00,0x24,0x00,0x21,0x00,0xe5,0xff,0x39,0x00,0xda,0xff,0xf1,0xff,0xdd,0xff,0xfb,0xff,0xf4,0xff,0xdd,0xff,0x0a,0x00,0x33,0x00,0xd6,0xff,0xf1,0xff,0xfd,0xff,0x5e,0x00,0xee,0xff,0x32,0x00,0xf4,0xff,0x30,0x00,0x24,0x00,0x14,0x00,0xfe,0xff,0x10,0x00,0xf3,0xff,0x51,0x00,0x07,0x00,0x27,0x00,0x38,0x00,0x28,0x00,0xe9,0xff,0xda,0xff,0xc8,0xff,0x0b,0x00,0xb9,0xff,0xfd,0xff,0x2e,0x00,0x39,0x00,0x00,0x00,0xe9,0xff,0xb7,0xff,0x13,0x00,0x24,0x00,0xc2,0xff,0xde,0xff,0xeb,0xff,0xf9,0xff,0x03,0x00,0x42,0x00,0xcd,0xff,0x01,0x00,0xfb,0xff,0xdb,0xff,0xf9,0xff,0x1e,0x00,0xb9,0xff,0xc2,0xff,0x1b,0x00,0xa6,0xff,0xb7,0xff,0x03,0x00,0xf7,0xff,0x18,0x00,0xf5,0xff,0xf8,0xff,0x20,0x00,0x06,0x00,0xec,0xff,0x1f,0x00,0xd3,0xff,0xf9,0xff,0x03,0x00,0x34,0x00,0xea,0xff,0x21,0x00,0xf5,0xff,0x10,0x00,0xff,0xff,0xd2,0xff,0xf3,0xff,0xfd,0xff,0x25,0x00,0x35,0x00,0x30,0x00,0xe3,0xff,0xdc,0xff,0x2c,0x00,0x22,0x00,0x1e,0x00,0x01,0x00,0xf4,0xff,0x1e,0x00,0xff,0xff,0xff,0xff,0x03,0x00,0x38,0x00,0x1b,0x00,0x11,0x00,0xdc,0xff,0x02,0x00,0x2b,0x00,0x21,0x00,0x1b,0x00,0x24,0x00,0xda,0xff,0xe3,0xff,0x14,0x00,0x37,0x00,0xe3,0xff,0xf5,0xff,0x24,0x00,0xd4,0xff,0xf2,0xff,0xc2,0xff,0x13,0x00,0x29,0x00,0x29,0x00,0xcf,0xff,0x27,0x00,0xf3,0xff,0xcf,0xff,0xc8,0xff,0x92,0xff,0x1c,0x00,0x1f,0x00,0xfa,0xff,0x20,0x00,0x31,0x00,0x08,0x00,0xd6,0xff,0xd4,0xff,0xd4,0xff,0x2d,0x00,0xee,0xff,0x13,0x00,0x20,0x00,0xbf,0xff,0x3e,0x00,0xcd,0xff,0xfc,0xff,0x2a,0x00,0x0a,0x00,0xbb,0xff,0x16,0x00,0x25,0x00,0x05,0x00,0xfc,0xff,0xed,0xff,0xf9,0xff,0xf0,0xff,0x20,0x00,0xde,0xff,0x21,0x00,0x02,0x00,0x08,0x00,0xe5,0xff,0x02,0x00,0xdd,0xff,0x13,0x00,0xdd,0xff,0xd1,0xff,0x00,0x00,0xce,0xff,0xcf,0xff,0xd9,0xff,0x21,0x00,0xfa,0xff,0x22,0x00,0xfc,0xff,0x0d,0x00,0xd8,0xff,0x35,0x00,0xeb,0xff,0x2e,0x00,0x1f,0x00,0x08,0x00,0x02,0x00,0xd3,0xff,0x00,0x00,0xf2,0xff,0x0e,0x00,0x34,0x00,0x08,0x00,0xf5,0xff,0xc5,0xff,0x29,0x00,0x0f,0x00,0xec,0xff,0x23,0x00,0xe9,0xff,0xd4,0xff,0xf7,0xff,0xf6,0xff,0xf9,0xff,0x04,0x00,0x4f,0x00,0xce,0xff,0xff,0xff,0x5c,0x00,0x22,0x00,0x18,0x00,0x1c,0x00,0xd7,0xff,0x18,0x00,0x46,0x00,0x33,0x00,0x23,0x00,0xfb,0xff,0x0b,0x00,0xb6,0xff,0xbd,0xff,0x04,0x00,0xed,0xff,0x1f,0x00,0xbc,0xff,0x12,0x00,0xef,0xff,0x1d,0x00,0x1c,0x00,0x0d,0x00,0xe5,0xff,0x46,0x00,0xde,0xff,0x2c,0x00,0x38,0x00,0xfe,0xff,0x0e,0x00,0x74,0x00,0xf4,0xff,0x16,0x00,0xca,0xff,0xf2,0xff,0xfa,0xff,0x26,0x00,0x02,0x00,0xf4,0xff,0x23,0x00,0xbd,0xff,0x91,0xff,0xe0,0xff,0x22,0x00,0xe5,0xff,0xd4,0xff,0x17,0x00,0xb9,0xff,0xe2,0xff,0xee,0xff,0x01,0x00,0x29,0x00,0xcb,0xff,0x52,0x00,0x1d,0x00,0x12,0x00,0x27,0x00,0xd9,0xff,0x08,0x00,0xf0,0xff,0xea,0xff,0xed,0xff,0xf9,0xff,0xbb,0xff,0xe4,0xff,0x3c,0x00,0x36,0x00,0x27,0x00,0x1d,0x00,0x9d,0xff,0xce,0xff,0xde,0xff,0x4d,0x00,0x20,0x00,0x3a,0x00,0xe1,0xff,0x04,0x00,0x29,0x00,0xed,0xff,0xbd,0xff,0x10,0x00,0xef,0xff,0x58,0x00,0x09,0x00,0x37,0x00,0xbd,0xff,0x0f,0x00,0x08,0x00,0x49,0x00,0x0a,0x00,0x20,0x00,0xdf,0xff,0xe6,0xff,0xe1,0xff,0xaf,0xff,0x31,0x00,0xf4,0xff,0xe7,0xff,0xde,0xff,0x02,0x00,0x03,0x00,0x31,0x00,0x43,0x00,0xec,0xff,0xdd,0xff,0x0f,0x00,0x31,0x00,0x02,0x00,0x1b,0x00,0xe7,0xff,0x08,0x00,0x2f,0x00,0xd4,0xff,0xe0,0xff,0x1e,0x00,0xf3,0xff,0xff,0xff,0xe0,0xff,0x0f,0x00,0x1e,0x00,0x53,0x00,0x07,0x00,0x2e,0x00,0x0a,0x00,0xea,0xff,0x05,0x00,0xf6,0xff,0xe8,0xff,0xf7,0xff,0x2e,0x00,0x39,0x00,0x09,0x00,0x3c,0x00,0x1d,0x00,0xd3,0xff,0x2f,0x00,0xc9,0xff,0xdb,0xff,0x07,0x00,0xd9,0xff,0xf6,0xff,0xda,0xff,0xf1,0xff,0xd7,0xff,0xed,0xff,0x0c,0x00,0x18,0x00,0xc2,0xff,0xb0,0xff,0x38,0x00,0x09,0x00,0x64,0x00,0xe6,0xff,0x05,0x00,0xd9,0xff,0x4a,0x00,0xd1,0xff,0xef,0xff,0xe4,0xff,0x1b,0x00,0x0b,0x00,0x0e,0x00,0xf8,0xff,0x17,0x00,0xe3,0xff,0x52,0x00,0x01,0x00,0xd6,0xff,0x04,0x00,0xc9,0xff,0xe0,0xff,0x2d,0x00,0xcb,0xff,0x57,0x00,0x11,0x00,0x32,0x00,0xfa,0xff,0x01,0x00,0x10,0x00,0x3e,0x00,0xd6,0xff,0xf5,0xff,0xc4,0xff,0x07,0x00,0x2b,0x00,0x40,0x00,0xed,0xff,0xb4,0xff,0xd3,0xff,0x14,0x00,0x0c,0x00,0xe8,0xff,0x18,0x00,0x33,0x00,0xe9,0xff,0xf5,0xff,0xf8,0xff,0xdb,0xff,0xf6,0xff,0x02,0x00,0xeb,0xff,0x28,0x00,0xa5,0xff,0xd9,0xff,0xe2,0xff,0x02,0x00,0xf3,0xff,0xcd,0xff,0x01,0x00,0xf1,0xff,0x3e,0x00,0x48,0x00,0xae,0xff,0xe3,0xff,0x19,0x00,0xbc,0xff,0x02,0x00,0x10,0x00,0xf3,0xff,0xaa,0xff,0x05,0x00,0xd8,0xff,0x1c,0x00,0xe5,0xff,0xe6,0xff,0xbd,0xff,0x19,0x00,0xc1,0xff,0x31,0x00,0xe9,0xff,0x4e,0x00,0xec,0xff,0x06,0x00,0x1b,0x00,0x27,0x00,0x15,0x00,0x0f,0x00,0xfc,0xff,0xe9,0xff,0xf4,0xff,0x0d,0x00,0xff,0xff,0xfa,0xff,0xd6,0xff,0xc0,0xff,0x15,0x00,0x11,0x00,0xd2,0xff,0xc3,0xff,0x1d,0x00,0xe4,0xff,0x12,0x00,0xad,0xff,0xf5,0xff,0xe4,0xff,0xe8,0xff,0xef,0xff,0xda,0xff,0x31,0x00,0xf8,0xff,0xef,0xff,0xe7,0xff,0xd0,0xff,0x10,0x00,0xda,0xff,0x1c,0x00,0xd0,0xff,0x34,0x00,0x15,0x00,0xcf,0xff,0xa8,0xff,0x10,0x00,0xee,0xff,0xea,0xff,0xe5,0xff,0x02,0x00,0xdd,0xff,0x4d,0x00,0xf5,0xff,0x22,0x00,0x1e,0x00,0xf4,0xff,0x27,0x00,0x57,0x00,0x05,0x00,0x24,0x00,0xfc,0xff,0x36,0x00,0x09,0x00,0xe3,0xff,0x27,0x00,0x11,0x00,0xf9,0xff,0xf5,0xff,0xa0,0xff,0xcc,0xff,0x10,0x00,0x46,0x00,0xf1,0xff,0x0f,0x00,0xcf,0xff,0xff,0xff,0xf9,0xff,0xd8,0xff,0xf1,0xff,0xfa,0xff,0xf7,0xff,0x07,0x00,0x01,0x00,0x1c,0x00,0x5a,0x00,0xef,0xff,0x25,0x00,0x0f,0x00,0xcb,0xff,0x02,0x00,0x05,0x00,0xe3,0xff,0xf2,0xff,0x17,0x00,0x0c,0x00,0x16,0x00,0x2e,0x00,0xde,0xff,0x04,0x00,0x20,0x00,0x0f,0x00,0x08,0x00,0xe2,0xff,0xf3,0xff,0xf6,0xff,0xf2,0xff,0xff,0xff,0x02,0x00,0xfc,0xff,0x0c,0x00,0xfe,0xff,0xef,0xff,0xbc,0xff,0xef,0xff,0xd4,0xff,0xd5,0xff,0xcf,0xff,0x29,0x00,0x46,0x00,0xd5,0xff,0xe2,0xff,0xea,0xff,0xfe,0xff,0xc9,0xff,0xf3,0xff,0xea,0xff,0xf2,0xff,0x42,0x00,0x3d,0x00,0xbf,0xff,0xf6,0xff,0x0b,0x00,0xdb,0xff,0x19,0x00,0xe5,0xff,0xe7,0xff,0x3e,0x00,0x3c,0x00,0xee,0xff,0x0f,0x00,0x0c,0x00,0x30,0x00,0xe7,0xff,0x08,0x00,0xc1,0xff,0xc3,0xff,0x50,0x00,0x16,0x00,0xdd,0xff,0xf8,0xff,0xf9,0xff,0x00,0x00,0x3b,0x00,0x01,0x00,0xf7,0xff,0xb4,0xff,0x26,0x00,0x0f,0x00,0x01,0x00,0x25,0x00,0x54,0x00,0x10,0x00,0xe2,0xff,0xeb,0xff,0xfd,0xff,0x29,0x00,0x31,0x00,0xf9,0xff,0x11,0x00,0x00,0x00,0x31,0x00,0x28,0x00,0xa5,0xff,0xef,0xff,0xea,0xff,0xe8,0xff,0x45,0x00,0xf3,0xff,0x1b,0x00,0xcc,0xff,0x25,0x00,0x1a,0x00,0xe8,0xff,0x5b,0x00,0x40,0x00,0x03,0x00,0x13,0x00,0x28,0x00,0x4f,0x00,0xe4,0xff,0xc9,0xff,0x1a,0x00,0xd1,0xff,0xfb,0xff,0xf8,0xff,0x05,0x00,0xd5,0xff,0xde,0xff,0xde,0xff,0x71,0x00,0xd4,0xff,0x10,0x00,0x12,0x00,0xe1,0xff,0xf5,0xff,0xc3,0xff,0x4d,0x00,0x0c,0x00,0xfa,0xff,0xb1,0xff,0xfb,0xff,0x5d,0x00,0xe3,0xff,0x02,0x00,0x11,0x00,0xe3,0xff,0x0f,0x00,0x07,0x00,0xdf,0xff,0xa8,0xff,0xf2,0xff,0x29,0x00,0x0f,0x00,0xfa,0xff,0xe7,0xff,0x26,0x00,0xda,0xff,0x41,0x00,0xf6,0xff,0x2c,0x00,0xb8,0xff,0xf6,0xff,0xab,0xff,0xcf,0xff,0x49,0x00,0x09,0x00,0xca,0xff,0xe9,0xff,0xda,0xff,0xc9,0xff,0x0a,0x00,0xd9,0xff,0xe7,0xff,0xe7,0xff,0x80,0xff,0xeb,0xff,0xf8,0xff,0x07,0x00,0x1f,0x00,0x09,0x00,0xb6,0xff,0x0d,0x00,0xe8,0xff,0xea,0xff,0xd2,0xff,0xf9,0xff,0xf2,0xff,0xf5,0xff,0xe6,0xff,0xbd,0xff,0x30,0x00,0xfc,0xff,0xf0,0xff,0x1e,0x00,0x35,0x00,0x27,0x00,0x0d,0x00,0x24,0x00,0x22,0x00,0x19,0x00,0x35,0x00,0x10,0x00,0x0d,0x00,0x31,0x00,0x41,0x00,0xf7,0xff,0x1d,0x00,0xf6,0xff,0xfc,0xff,0x49,0x00,0x18,0x00,0xf6,0xff,0xea,0xff,0xf2,0xff,0xdb,0xff,0x42,0x00,0xc2,0xff,0xfc,0xff,0xee,0xff,0x00,0x00,0xd6,0xff,0xe9,0xff,0x1d,0x00,0xf6,0xff,0x0d,0x00,0x11,0x00,0xbb,0xff,0xdf,0xff,0x0e,0x00,0x1e,0x00,0xf2,0xff,0x4a,0x00,0x41,0x00,0x15,0x00,0xc6,0xff,0xdd,0xff,0xd8,0xff,0xf5,0xff,0xe3,0xff,0x14,0x00,0xc0,0xff,0xbb,0xff,0xc4,0xff,0xc5,0xff,0xdd,0xff,0xf8,0xff,0x0e,0x00,0xf2,0xff,0xdd,0xff,0xd2,0xff,0x1d,0x00,0xf4,0xff,0x40,0x00,0x17,0x00,0x99,0xff,0x0b,0x00,0x02,0x00,0xf4,0xff,0x15,0x00,0x22,0x00,0xef,0xff,0x0b,0x00,0xe3,0xff,0xf8,0xff,0xae,0xff,0xb6,0xff,0x13,0x00,0x15,0x00,0x17,0x00,0x1f,0x00,0xf1,0xff,0x27,0x00,0xc1,0xff,0xce,0xff,0x24,0x00,0x1d,0x00,0x3d,0x00,0x0b,0x00,0x1b,0x00,0x09,0x00,0xc4,0xff,0x47,0x00,0x12,0x00,0x04,0x00,0xef,0xff,0x23,0x00,0x37,0x00,0x05,0x00,0xd8,0xff,0x08,0x00,0xff,0xff,0xf8,0xff,0x00,0x00,0x09,0x00,0x0c,0x00,0x15,0x00,0xad,0xff,0xe7,0xff,0xdf,0xff,0x58,0x00,0x19,0x00,0x47,0x00,0xde,0xff,0x6c,0x00,0xdf,0xff,0xe0,0xff,0x30,0x00,0x04,0x00,0x05,0x00,0x01,0x00,0x08,0x00,0xc5,0xff,0x35,0x00,0x00,0x00,0x93,0xff,0x4b,0x00,0x0e,0x00,0xf6,0xff,0x06,0x00,0xa6,0xff,0xd4,0xff,0xff,0xff,0xf2,0xff,0x27,0x00,0x23,0x00,0x3b,0x00,0x2a,0x00,0x14,0x00,0x25,0x00,0x25,0x00,0x0c,0x00,0xfd,0xff,0x32,0x00,0x1f,0x00,0x0b,0x00,0x06,0x00,0x2f,0x00,0xd7,0xff,0x01,0x00,0xfe,0xff,0xdf,0xff,0xfc,0xff,0x59,0x00,0xe1,0xff,0x08,0x00,0x07,0x00,0x37,0x00,0xf2,0xff,0x02,0x00,0x3b,0x00,0xe9,0xff,0xdb,0xff,0xd9,0xff,0xf4,0xff,0x17,0x00,0xf5,0xff,0x71,0x00,0x24,0x00,0x17,0x00,0x08,0x00,0xe2,0xff,0x3e,0x00,0xfa,0xff,0x04,0x00,0xed,0xff,0xf2,0xff,0x38,0x00,0x3c,0x00,0x28,0x00,0xe7,0xff,0x64,0x00,0x1c,0x00,0x0c,0x00,0x0f,0x00,0xad,0xff,0xe9,0xff,0xe1,0xff,0x2a,0x00,0xc2,0xff,0x35,0x00,0x2b,0x00,0xfb,0xff,0xe2,0xff,0x0d,0x00,0x0b,0x00,0xe5,0xff,0xbf,0xff,0xdf,0xff,0x25,0x00,0xfe,0xff,0x3c,0x00,0xf8,0xff,0x1b,0x00,0x0a,0x00,0xc0,0xff,0xab,0xff,0x03,0x00,0x39,0x00,0x09,0x00,0xe0,0xff,0xed,0xff,0xf8,0xff,0x00,0x00,0xf6,0xff,0x42,0x00,0x6e,0x00,0xeb,0xff,0xfc,0xff,0xf7,0xff,0x2c,0x00,0xf2,0xff,0xfa,0xff,0xf0,0xff,0xda,0xff,0xfe,0xff,0x31,0x00,0x3a,0x00,0xc2,0xff,0x32,0x00,0xf5,0xff,0xfb,0xff,0x0e,0x00,0x05,0x00,0x15,0x00,0xe6,0xff,0xcd,0xff,0x2b,0x00,0x0b,0x00,0x23,0x00,0xf4,0xff,0x02,0x00,0x62,0x00,0x0f,0x00,0x12,0x00,0xd9,0xff,0x1a,0x00,0xec,0xff,0xd0,0xff,0x27,0x00,0x22,0x00,0x0b,0x00,0xcc,0xff,0x21,0x00,0x14,0x00,0x45,0x00,0x06,0x00,0xe3,0xff,0xf5,0xff,0xb9,0xff,0xe0,0xff,0xfe,0xff,0x31,0x00,0x0f,0x00,0xc2,0xff,0x1b,0x00,0xf0,0xff,0xf0,0xff,0x18,0x00,0x2c,0x00,0xdb,0xff,0xe7,0xff,0x07,0x00,0xf9,0xff,0x1e,0x00,0x32,0x00,0xfa,0xff,0xe5,0xff,0x15,0x00,0x1c,0x00,0x0e,0x00,0xaa,0xff,0xf1,0xff,0x23,0x00,0x3f,0x00,0xed,0xff,0x04,0x00,0x37,0x00,0x0d,0x00,0xcb,0xff,0x07,0x00,0x0a,0x00,0xe2,0xff,0xef,0xff,0x1d,0x00,0xfe,0xff,0x89,0xff,0x2b,0x00,0x1c,0x00,0x19,0x00,0x02,0x00,0x3c,0x00,0x16,0x00,0x2d,0x00,0xd2,0xff,0x1b,0x00,0xed,0xff,0x11,0x00,0x0e,0x00,0xe7,0xff,0xdd,0xff,0xf2,0xff,0x16,0x00,0xe9,0xff,0xd2,0xff,0x3d,0x00,0x6d,0x00,0xc5,0xff,0x2d,0x00,0x3d,0x00,0xc0,0xff,0xfb,0xff,0xe9,0xff,0xda,0xff,0x22,0x00,0x38,0x00,0x20,0x00,0x10,0x00,0x22,0x00,0xeb,0xff,0x1c,0x00,0x37,0x00,0xae,0xff,0x0e,0x00,0xdb,0xff,0xc9,0xff,0x4e,0x00,0xda,0xff,0x0b,0x00,0xac,0xff,0x31,0x00,0xd0,0xff,0x05,0x00,0x26,0x00,0x03,0x00,0x0b,0x00,0x23,0x00,0xf7,0xff,0x1d,0x00,0xdc,0xff,0xf8,0xff,0xd7,0xff,0xf7,0xff,0x28,0x00,0x0f,0x00,0xff,0xff,0x13,0x00,0x23,0x00,0xfe,0xff,0xd7,0xff,0x31,0x00,0xba,0xff,0x3c,0x00,0xe7,0xff,0x0b,0x00,0xde,0xff,0x17,0x00,0xae,0xff,0x0e,0x00,0xe5,0xff,0x41,0x00,0x20,0x00,0xae,0xff,0x06,0x00,0x0f,0x00,0x06,0x00,0xbc,0xff,0x4d,0x00,0xe4,0xff,0x47,0x00,0x02,0x00,0x0a,0x00,0x0b,0x00,0xdb,0xff,0x03,0x00,0xf8,0xff,0xba,0xff,0xd4,0xff,0x1f,0x00,0x12,0x00,0x40,0x00,0xed,0xff,0xb1,0xff,0xd8,0xff,0xb9,0xff,0x0c,0x00,0xe2,0xff,0xfb,0xff,0x2f,0x00,0x0c,0x00,0xe0,0xff,0x12,0x00,0xee,0xff,0x31,0x00,0xef,0xff,0x3d,0x00,0xbd,0xff,0xf0,0xff,0xe9,0xff,0xfd,0xff,0x25,0x00,0x23,0x00,0xc7,0xff,0xf6,0xff,0xed,0xff,0x3b,0x00,0x06,0x00,0xe5,0xff,0x14,0x00,0x03,0x00,0x15,0x00,0x17,0x00,0x3c,0x00,0x26,0x00,0x6c,0x00,0x04,0x00,0xf1,0xff,0x0e,0x00,0xe0,0xff,0x3c,0x00,0xd6,0xff,0xd4,0xff,0xf0,0xff,0xdb,0xff,0xdd,0xff,0x1c,0x00,0x09,0x00,0x27,0x00,0xc8,0xff,0xaa,0xff,0xff,0xff,0x1b,0x00,0x30,0x00,0x0f,0x00,0x2f,0x00,0xd6,0xff,0xc3,0xff,0xc0,0xff,0xf5,0xff,0xe2,0xff,0x2c,0x00,0xce,0xff,0x1a,0x00,0xba,0xff,0x3e,0x00,0xe0,0xff,0xeb,0xff,0x09,0x00,0xf0,0xff,0x1c,0x00,0x3d,0x00,0xf8,0xff,0x0a,0x00,0xd6,0xff,0xea,0xff,0xc7,0xff,0xd8,0xff,0x0e,0x00,0x2d,0x00,0xcb,0xff,0xdd,0xff,0x1c,0x00,0x31,0x00,0x07,0x00,0x3b,0x00,0x06,0x00,0x07,0x00,0xeb,0xff,0x33,0x00,0x2f,0x00,0xf5,0xff,0x40,0x00,0xf9,0xff,0xbe,0xff,0x5b,0x00,0x03,0x00,0x01,0x00,0xf4,0xff,0xff,0xff,0xd1,0xff,0xf9,0xff,0x02,0x00,0xfc,0xff,0xf0,0xff,0x00,0x00,0x07,0x00,0x19,0x00,0xd0,0xff,0x19,0x00,0x3d,0x00,0x0a,0x00,0xfd,0xff,0x40,0x00,0xbd,0xff,0xc0,0xff,0xc4,0xff,0xf5,0xff,0xf6,0xff,0xd2,0xff,0x0b,0x00,0x14,0x00,0xef,0xff,0x2f,0x00,0x56,0x00,0x25,0x00,0xa2,0xff,0xee,0xff,0xc9,0xff,0x10,0x00,0x9b,0xff,0xfc,0xff,0x55,0x00,0xde,0xff,0x05,0x00,0x16,0x00,0x49,0x00,0xff,0xff,0x3a,0x00,0xe4,0xff,0xf1,0xff,0x12,0x00,0x03,0x00,0x49,0x00,0xfe,0xff,0xd3,0xff,0xe1,0xff,0xc8,0xff,0xfa,0xff,0x14,0x00,0xf0,0xff,0x4d,0x00,0x23,0x00,0x02,0x00,0xd7,0xff,0x32,0x00,0xdb,0xff,0xfc,0xff,0x05,0x00,0x06,0x00,0xc3,0xff,0x3c,0x00,0x06,0x00,0x2e,0x00,0x1c,0x00,0x4b,0x00,0xa0,0xff,0x1f,0x00,0x0e,0x00,0xff,0xff,0xf8,0xff,0x2b,0x00,0x09,0x00,0x06,0x00,0x5f,0x00,0x07,0x00,0x0d,0x00,0xea,0xff,0x2c,0x00,0x07,0x00,0x3a,0x00,0x07,0x00,0x0b,0x00,0xd6,0xff,0xf9,0xff,0x33,0x00,0xf2,0xff,0x1f,0x00,0xe9,0xff,0x15,0x00,0xf7,0xff,0x0c,0x00,0xdc,0xff,0x1a,0x00,0xe6,0xff,0x00,0x00,0x04,0x00,0xef,0xff,0xf6,0xff,0x1e,0x00,0x02,0x00,0xf5,0xff,0xb6,0xff,0xf1,0xff,0x0a,0x00,0x02,0x00,0x06,0x00,0x1b,0x00,0x07,0x00,0x1b,0x00,0xf5,0xff,0xef,0xff,0x0b,0x00,0x33,0x00,0x16,0x00,0x06,0x00,0x1f,0x00,0x08,0x00,0x17,0x00,0x1f,0x00,0xf3,0xff,0x0c,0x00,0x09,0x00,0x00,0x00,0xe6,0xff,0x13,0x00,0xfc,0xff,0x07,0x00,0x07,0x00,0x0d,0x00,0x03,0x00,0xe8,0xff,0x1b,0x00,0xf4,0xff,0xf8,0xff,0x19,0x00,0xf0,0xff,0xf9,0xff,0x01,0x00,0x01,0x00,0x0c,0x00,0x02,0x00,0xeb,0xff,0x02,0x00,0x1f,0x00,0xe8,0xff,0x15,0x00,0xff,0xff,0xe8,0xff,0x17,0x00,0x00,0x00,0x0d,0x00,0xe3,0xff,0x12,0x00,0x01,0x00,0xe0,0xff,0xea,0xff,0xf4,0xff,0x29,0x00,0xe9,0xff,0xe1,0xff,0xf3,0xff,0xec,0xff,0xf3,0xff,0x0f,0x00,0xff,0xff,0xec,0xff,0xf9,0xff,0xed,0xff,0x0f,0x00,0xf0,0xff,0x1f,0x00,0x0a,0x00,0xd4,0xff,0xcc,0xff,0xe8,0xff,0xf5,0xff,0x22,0x00,0xfb,0xff,0x10,0x00,0xcf,0xff,0x11,0x00,0xef,0xff,0x29,0x00,0xf6,0xff,0xfb,0xff,0x12,0x00,0x06,0x00,0x20,0x00,0x0d,0x00,0x06,0x00,0x0d,0x00,0x02,0x00,0xf7,0xff,0xe0,0xff,0xfc,0xff,0xf9,0xff,0x02,0x00,0xf8,0xff,0x0c,0x00,0x10,0x00,0xf5,0xff,0xf7,0xff,0xfd,0xff,0x01,0x00,0xf8,0xff,0x1d,0x00,0x03,0x00,0x10,0x00,0xe5,0xff,0x1c,0x00,0x17,0x00,0xfc,0xff,0xf0,0xff,0xfa,0xff,0x05,0x00,0xf6,0xff,0x11,0x00,0xfd,0xff,0xd7,0xff,0xfc,0xff,0xf8,0xff,0x1b,0x00,0xcd,0xff,0xb0,0xff,0xfc,0xff,0xfc,0xff,0x1e,0x00,0x01,0x00,0x09,0x00,0x13,0x00,0xe7,0xff,0xfb,0xff,0x07,0x00,0x0c,0x00,0x08,0x00,0xf6,0xff,0x0b,0x00,0x1f,0x00,0xe2,0xff,0xf8,0xff,0xf5,0xff,0x18,0x00,0x10,0x00,0xc5,0xff,0xfe,0xff,0xf1,0xff,0x2c,0x00,0x05,0x00,0x0f,0x00,0x0e,0x00,0x00,0x00,0x34,0x00,0xfd,0xff,0x20,0x00,0x13,0x00,0xe4,0xff,0x1c,0x00,0xf5,0xff,0xd9,0xff,0xea,0xff,0x08,0x00,0x03,0x00,0x03,0x00,0x13,0x00,0xef,0xff,0x0d,0x00,0xff,0xff,0xf1,0xff,0xf5,0xff,0x30,0x00,0x01,0x00,0xff,0xff,0xf0,0xff,0x16,0x00,0x34,0x00,0xf4,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x29,0x00,0x0b,0x00,0x06,0x00,0xbb,0xff,0xf9,0xff,0x26,0x00,0x13,0x00,0xec,0xff,0xf5,0xff,0xee,0xff,0xef,0xff,0x15,0x00,0xf2,0xff,0x22,0x00,0x3d,0x00,0xe8,0xff,0xf0,0xff,0x10,0x00,0x21,0x00,0xf9,0xff,0x0d,0x00,0xe3,0xff,0x2a,0x00,0xee,0xff,0x08,0x00,0xed,0xff,0x12,0x00,0x16,0x00,0xe6,0xff,0xca,0xff,0xf9,0xff,0x06,0x00,0x43,0x00,0x12,0x00,0x15,0x00,0x0f,0x00,0x11,0x00,0x0a,0x00,0xcd,0xff,0x0d,0x00,0xcd,0xff,0x0c,0x00,0x18,0x00,0x1d,0x00,0xf1,0xff,0xf4,0xff,0xf6,0xff,0x01,0x00,0xe4,0xff,0xfd,0xff,0x10,0x00,0x06,0x00,0xe4,0xff,0xfd,0xff,0xe0,0xff,0xf8,0xff,0xfc,0xff,0xde,0xff,0x1e,0x00,0x14,0x00,0xe7,0xff,0xc5,0xff,0x0b,0x00,0x00,0x00,0x0e,0x00,0x08,0x00,0x09,0x00,0xf0,0xff,0xf0,0xff,0x35,0x00,0xff,0xff,0x17,0x00,0xf9,0xff,0xfc,0xff,0xf8,0xff,0x1e,0x00,0xf2,0xff,0x2e,0x00,0x24,0x00,0xe9,0xff,0x0b,0x00,0x02,0x00,0xe7,0xff,0xfc,0xff,0x00,0x00,0x0a,0x00,0x23,0x00,0xfc,0xff,0x06,0x00,0x00,0x00,0x16,0x00,0x18,0x00,0xf0,0xff,0xf6,0xff,0xfc,0xff,0xf7,0xff,0x1d,0x00,0x02,0x00,0x10,0x00,0xee,0xff,0xf6,0xff,0x05,0x00,0xda,0xff,0x0a,0x00,0xdc,0xff,0xf5,0xff,0xff,0xff,0x1c,0x00,0xee,0xff,0x02,0x00,0xf2,0xff,0xf4,0xff,0xbe,0xff,0xf7,0xff,0x05,0x00,0xf9,0xff,0xf7,0xff,0xe2,0xff,0xc0,0xff,0xed,0xff,0xf1,0xff,0xda,0xff,0xfd,0xff,0xea,0xff,0xe4,0xff,0xe3,0xff,0xf7,0xff,0x1d,0x00,0x02,0x00,0xea,0xff,0x02,0x00,0x10,0x00,0xf8,0xff,0x36,0x00,0xfd,0xff,0x26,0x00,0x16,0x00,0xf6,0xff,0xd1,0xff,0x0e,0x00,0xeb,0xff,0x15,0x00,0xc7,0xff,0xf0,0xff,0xfb,0xff,0x0c,0x00,0xc5,0xff,0xf3,0xff,0x0d,0x00,0x14,0x00,0x0b,0x00,0xf6,0xff,0xf3,0xff,0xfa,0xff,0x14,0x00,0x05,0x00,0xff,0xff,0xed,0xff,0xf4,0xff,0xf6,0xff,0xfe,0xff,0xce,0xff,0xf0,0xff,0xd3,0xff,0xfa,0xff,0xf2,0xff,0xb0,0xff,0x0c,0x00,0xe5,0xff,0x12,0x00,0x03,0x00,0x00,0x00,0xf6,0xff,0xfc,0xff,0x11,0x00,0xfc,0xff,0xf6,0xff,0x19,0x00,0x0c,0x00,0x02,0x00,0x13,0x00,0xc8,0xff,0x06,0x00,0xd5,0xff,0xf0,0xff,0x05,0x00,0xfc,0xff,0xe7,0xff,0xf3,0xff,0x34,0x00,0x05,0x00,0x04,0x00,0xd7,0xff,0x42,0x00,0x00,0x00,0x1c,0x00,0xfa,0xff,0x18,0x00,0x05,0x00,0x1c,0x00,0xfd,0xff,0xdb,0xff,0x73,0x00,0x18,0x00,0xe4,0xff,0x1b,0x00,0xf8,0xff,0x30,0x00,0xca,0xff,0x3c,0x00,0xd2,0xff,0xea,0xff,0x39,0x00,0x2f,0x00,0x15,0x00,0xdf,0xff,0xb0,0xff,0xe8,0xff,0x21,0x00,0x1b,0x00,0xe2,0xff,0xc0,0xff,0x65,0x00,0xff,0xff,0xd1,0xff,0xc7,0xff,0x41,0x00,0x7f,0x00,0xe1,0xff,0xc4,0xff,0xef,0xff,0x27,0x00,0xf5,0xff,0x1a,0x00,0x1c,0x00,0x49,0x00,0xc2,0xff,0x62,0x00,0x91,0xff,0xc4,0xff,0xf8,0xff,0x61,0x00,0xec,0xff,0x9a,0xff,0x59,0x00,0x1f,0x00,0xca,0xff,0x7f,0x00,0xef,0xff,0x26,0x00,0x28,0x00,0xde,0xff,0xd2,0xff,0xfe,0xff,0x88,0xff,0xef,0xff,0x13,0x00,0xcd,0xff,0xf8,0xff,0xee,0xff,0x01,0x00,0x12,0x00,0x44,0x00,0x3d,0x00,0xe3,0xff,0xf4,0xff,0xf0,0xff,0x0e,0x00,0xec,0xff,0x0e,0x00,0xf2,0xff,0x1e,0x00,0x43,0x00,0x0a,0x00,0x16,0x00,0x09,0x00,0x32,0x00,0xfe,0xff,0x2a,0x00,0xce,0xff,0x18,0x00,0xe5,0xff,0x07,0x00,0x02,0x00,0x16,0x00,0xbf,0xff,0xef,0xff,0x19,0x00,0xfc,0xff,0x04,0x00,0xe2,0xff,0xcb,0xff,0x32,0x00,0x0e,0x00,0x23,0x00,0x12,0x00,0xa5,0xff,0x1a,0x00,0xd6,0xff,0x37,0x00,0x40,0x00,0xd7,0xff,0xef,0xff,0x1a,0x00,0xef,0xff,0xff,0xff,0x47,0x00,0x02,0x00,0xf2,0xff,0xf2,0xff,0xdf,0xff,0x41,0x00,0xe0,0xff,0x12,0x00,0x07,0x00,0x14,0x00,0x5a,0x00,0xed,0xff,0xb1,0xff,0x18,0x00,0x29,0x00,0x3b,0x00,0xe6,0xff,0xe3,0xff,0xe5,0xff,0x1d,0x00,0xf6,0xff,0xf3,0xff,0x04,0x00,0xe0,0xff,0x33,0x00,0xe8,0xff,0x20,0x00,0xe5,0xff,0x15,0x00,0xa8,0xff,0x38,0x00,0x35,0x00,0xe3,0xff,0x1f,0x00,0x22,0x00,0x37,0x00,0x17,0x00,0xc2,0xff,0xe5,0xff,0xcd,0xff,0x35,0x00,0x09,0x00,0x1c,0x00,0x23,0x00,0xda,0xff,0xd1,0xff,0x03,0x00,0xb5,0xff,0xde,0xff,0xe7,0xff,0x12,0x00,0x34,0x00,0x3d,0x00,0xd5,0xff,0x01,0x00,0x22,0x00,0xd3,0xff,0xec,0xff,0x3f,0x00,0x44,0x00,0x19,0x00,0xdc,0xff,0x3c,0x00,0xe4,0xff,0x2a,0x00,0x1d,0x00,0x21,0x00,0xfe,0xff,0xf7,0xff,0xa1,0xff,0xd8,0xff,0x3b,0x00,0xeb,0xff,0xd9,0xff,0xea,0xff,0xe9,0xff,0x29,0x00,0x25,0x00,0xd3,0xff,0x04,0x00,0xdb,0xff,0xa6,0xff,0x15,0x00,0x34,0x00,0xdb,0xff,0xfe,0xff,0xf7,0xff,0xf6,0xff,0xa3,0xff,0x56,0x00,0x13,0x00,0xc9,0xff,0xaa,0xff,0xd7,0xff,0x3c,0x00,0x35,0x00,0x1c,0x00,0xb9,0xff,0x09,0x00,0xee,0xff,0x0e,0x00,0xea,0xff,0x1c,0x00,0xf9,0xff,0x54,0x00,0x62,0x00,0x40,0x00,0xd5,0xff,0xcc,0xff,0xd5,0xff,0x07,0x00,0x48,0x00,0xd0,0xff,0xd1,0xff,0xe1,0xff,0x2e,0x00,0x3f,0x00,0x1d,0x00,0x27,0x00,0x51,0x00,0xcd,0xff,0x1f,0x00,0xcf,0xff,0x21,0x00,0x15,0x00,0xb4,0xff,0x20,0x00,0xdb,0xff,0xd2,0xff,0x41,0x00,0xf6,0xff,0xf5,0xff,0x9b,0xff,0xc3,0xff,0xeb,0xff,0x40,0x00,0xe2,0xff,0xc7,0xff,0x19,0x00,0xa9,0xff,0xd7,0xff,0xe7,0xff,0xe4,0xff,0x2c,0x00,0x9f,0xff,0xf5,0xff,0x16,0x00,0x37,0x00,0xd1,0xff,0xec,0xff,0x00,0x00,0x00,0x00,0xc2,0xff,0x09,0x00,0x3b,0x00,0x0a,0x00,0xc4,0xff,0x1f,0x00,0x07,0x00,0x23,0x00,0x42,0x00,0x03,0x00,0x3a,0x00,0x15,0x00,0xe4,0xff,0xc2,0xff,0xef,0xff,0xc4,0xff,0xcc,0xff,0x29,0x00,0xe3,0xff,0x1a,0x00,0x47,0x00,0xdf,0xff,0x45,0x00,0xe9,0xff,0xf4,0xff,0xf9,0xff,0x34,0x00,0xfe,0xff,0x04,0x00,0xcf,0xff,0x0b,0x00,0x29,0x00,0xa1,0xff,0xfd,0xff,0xe8,0xff,0xbc,0xff,0x03,0x00,0x2e,0x00,0x3c,0x00,0xf3,0xff,0x44,0x00,0x2d,0x00,0x2c,0x00,0x1d,0x00,0xbe,0xff,0x09,0x00,0xef,0xff,0x3f,0x00,0xed,0xff,0x2a,0x00,0xe9,0xff,0x2b,0x00,0x19,0x00,0x24,0x00,0x1d,0x00,0xc7,0xff,0x15,0x00,0xf6,0xff,0xe4,0xff,0x13,0x00,0xfb,0xff,0xe1,0xff,0xd5,0xff,0x04,0x00,0xf6,0xff,0xf7,0xff,0xd4,0xff,0xda,0xff,0x15,0x00,0x04,0x00,0x3d,0x00,0x19,0x00,0x29,0x00,0x01,0x00,0x05,0x00,0xd3,0xff,0x15,0x00,0x26,0x00,0x24,0x00,0xfd,0xff,0x14,0x00,0x2e,0x00,0xf8,0xff,0x02,0x00,0x27,0x00,0xc7,0xff,0x2c,0x00,0xef,0xff,0x00,0x00,0xdb,0xff,0xee,0xff,0xca,0xff,0xd2,0xff,0x08,0x00,0xbf,0xff,0x0c,0x00,0x2e,0x00,0xba,0xff,0x47,0x00,0x45,0x00,0x4f,0x00,0x31,0x00,0xc6,0xff,0xaa,0xff,0xd7,0xff,0x0c,0x00,0x14,0x00,0xd8,0xff,0x23,0x00,0xf8,0xff,0xd5,0xff,0x07,0x00,0x13,0x00,0x23,0x00,0xf2,0xff,0x3f,0x00,0x0e,0x00,0xef,0xff,0xb2,0xff,0xbd,0xff,0x37,0x00,0xb8,0xff,0x30,0x00,0x25,0x00,0x59,0x00,0xef,0xff,0x0e,0x00,0x42,0x00,0xed,0xff,0x07,0x00,0xdc,0xff,0xae,0xff,0x39,0x00,0x55,0x00,0xc1,0xff,0xe8,0xff,0xfd,0xff,0xed,0xff,0xf6,0xff,0x00,0x00,0xea,0xff,0xf2,0xff,0xd5,0xff,0xbe,0xff,0x0a,0x00,0x09,0x00,0x2b,0x00,0x17,0x00,0x03,0x00,0xf8,0xff,0xab,0xff,0x0f,0x00,0xdc,0xff,0x1d,0x00,0xe0,0xff,0x04,0x00,0x14,0x00,0x1b,0x00,0x25,0x00,0x50,0x00,0xe7,0xff,0xea,0xff,0x1f,0x00,0xae,0xff,0x0b,0x00,0xd2,0xff,0x09,0x00,0xfe,0xff,0x21,0x00,0xd9,0xff,0xde,0xff,0xcd,0xff,0x0f,0x00,0xf4,0xff,0x1a,0x00,0x3e,0x00,0x03,0x00,0x1a,0x00,0xfa,0xff,0x18,0x00,0x16,0x00,0xe7,0xff,0xf9,0xff,0x40,0x00,0x1d,0x00,0xf6,0xff,0x26,0x00,0x45,0x00,0xd0,0xff,0xfa,0xff,0x49,0x00,0x52,0x00,0xe3,0xff,0x24,0x00,0x0c,0x00,0xd2,0xff,0xd1,0xff,0x13,0x00,0x08,0x00,0x33,0x00,0x09,0x00,0x21,0x00,0x09,0x00,0xd6,0xff,0xbe,0xff,0xd8,0xff,0x6b,0x00,0xfc,0xff,0x37,0x00,0x13,0x00,0x1f,0x00,0xfe,0xff,0xea,0xff,0x37,0x00,0x18,0x00,0x4d,0x00,0xf9,0xff,0xf1,0xff,0xe8,0xff,0x29,0x00,0x4b,0x00,0x1a,0x00,0x08,0x00,0x0b,0x00,0xd8,0xff,0x05,0x00,0xf1,0xff,0x01,0x00,0x0e,0x00,0xfa,0xff,0x01,0x00,0xb0,0xff,0x39,0x00,0x6a,0x00,0x02,0x00,0xd4,0xff,0xca,0xff,0x08,0x00,0xb1,0xff,0xfc,0xff,0xc5,0xff,0xcb,0xff,0xff,0xff,0x13,0x00,0xd6,0xff,0x0d,0x00,0xd0,0xff,0x1a,0x00,0x12,0x00,0xc4,0xff,0x3b,0x00,0x38,0x00,0x13,0x00,0x0e,0x00,0x2e,0x00,0xe9,0xff,0x05,0x00,0x40,0x00,0x2e,0x00,0xca,0xff,0xef,0xff,0xfe,0xff,0x31,0x00,0xe0,0xff,0xda,0xff,0xa9,0xff,0x7f,0x00,0x23,0x00,0xcb,0xff,0x37,0x00,0xfa,0xff,0xfc,0xff,0x45,0x00,0x1a,0x00,0x28,0x00,0xd0,0xff,0x28,0x00,0xc2,0xff,0xbf,0xff,0xef,0xff,0xea,0xff,0x07,0x00,0xc2,0xff,0x08,0x00,0x1a,0x00,0xdc,0xff,0x21,0x00,0x31,0x00,0x05,0x00,0x62,0x00,0x0c,0x00,0x0c,0x00,0xd2,0xff,0x0b,0x00,0x1f,0x00,0xe8,0xff,0xb8,0xff,0x3f,0x00,0x11,0x00,0x1a,0x00,0xf0,0xff,0xcd,0xff,0x2a,0x00,0x39,0x00,0xd5,0xff,0xe9,0xff,0x09,0x00,0xf5,0xff,0xc8,0xff,0x4b,0x00,0xe9,0xff,0xc6,0xff,0x0c,0x00,0x1a,0x00,0x20,0x00,0xde,0xff,0x4e,0x00,0x08,0x00,0x34,0x00,0x2f,0x00,0x1e,0x00,0xde,0xff,0xd0,0xff,0x30,0x00,0xf0,0xff,0xc5,0xff,0xed,0xff,0x04,0x00,0xc3,0xff,0x35,0x00,0x06,0x00,0xc7,0xff,0xcc,0xff,0x1b,0x00,0xe3,0xff,0xf2,0xff,0xea,0xff,0x06,0x00,0xc1,0xff,0x02,0x00,0x0f,0x00,0x1f,0x00,0x19,0x00,0xb0,0xff,0x41,0x00,0xf8,0xff,0x44,0x00,0xcd,0xff,0xc8,0xff,0x10,0x00,0xe9,0xff,0xf4,0xff,0x1c,0x00,0xf7,0xff,0xcf,0xff,0xff,0xff,0xca,0xff,0xf6,0xff,0xed,0xff,0xf1,0xff,0x15,0x00,0xf9,0xff,0x3a,0x00,0x0b,0x00,0x13,0x00,0xed,0xff,0xed,0xff,0xd5,0xff,0x10,0x00,0x19,0x00,0x0f,0x00,0x23,0x00,0xdd,0xff,0xa2,0xff,0xe2,0xff,0xe9,0xff,0x0d,0x00,0x02,0x00,0xf0,0xff,0x0e,0x00,0x18,0x00,0x10,0x00,0x05,0x00,0xce,0xff,0x12,0x00,0xe3,0xff,0x11,0x00,0x04,0x00,0xf4,0xff,0xfe,0xff,0x17,0x00,0xe2,0xff,0xd7,0xff,0x23,0x00,0x54,0x00,0xc4,0xff,0x60,0x00,0x07,0x00,0x34,0x00,0x1f,0x00,0x04,0x00,0xf0,0xff,0xf5,0xff,0xfc,0xff,0x6c,0x00,0xe0,0xff,0xd5,0xff,0x1a,0x00,0xe9,0xff,0x7d,0x00,0x21,0x00,0xf2,0xff,0x0b,0x00,0x10,0x00,0xfe,0xff,0xf0,0xff,0xc3,0xff,0x12,0x00,0xd6,0xff,0x1f,0x00,0x11,0x00,0x01,0x00,0x0e,0x00,0x06,0x00,0x1b,0x00,0xb3,0xff,0x0c,0x00,0x02,0x00,0xfc,0xff,0xbd,0xff,0xd8,0xff,0xfe,0xff,0xfe,0xff,0xed,0xff,0x01,0x00,0xf4,0xff,0xcd,0xff,0xe7,0xff,0xee,0xff,0x12,0x00,0x22,0x00,0x38,0x00,0x07,0x00,0x16,0x00,0xb0,0xff,0x2d,0x00,0xec,0xff,0x63,0x00,0x07,0x00,0x13,0x00,0xae,0xff,0x0f,0x00,0xd3,0xff,0x09,0x00,0x22,0x00,0x36,0x00,0xde,0xff,0xdd,0xff,0x0f,0x00,0x3b,0x00,0xf3,0xff,0x18,0x00,0xf3,0xff,0x55,0x00,0x28,0x00,0x27,0x00,0xec,0xff,0x0e,0x00,0x4d,0x00,0xdc,0xff,0x0e,0x00,0xec,0xff,0xc1,0xff,0xd8,0xff,0x09,0x00,0x03,0x00,0x1f,0x00,0x56,0x00,0x08,0x00,0xed,0xff,0xea,0xff,0xf1,0xff,0x29,0x00,0x1b,0x00,0xf9,0xff,0xf6,0xff,0x30,0x00,0xe7,0xff,0x11,0x00,0xdb,0xff,0xdd,0xff,0x4b,0x00,0xc5,0xff,0xfc,0xff,0x34,0x00,0x23,0x00,0xf2,0xff,0xc1,0xff,0x2a,0x00,0xc5,0xff,0x00,0x00,0xd7,0xff,0xde,0xff,0xfc,0xff,0x0c,0x00,0xef,0xff,0x39,0x00,0x12,0x00,0x21,0x00,0x4e,0x00,0x61,0x00,0x0d,0x00,0xce,0xff,0xf0,0xff,0xea,0xff,0xfa,0xff,0xdc,0xff,0x03,0x00,0x26,0x00,0xe5,0xff,0x4b,0x00,0xea,0xff,0xee,0xff,0xa1,0xff,0x2e,0x00,0xed,0xff,0xfd,0xff,0xd1,0xff,0x0d,0x00,0x15,0x00,0xfe,0xff,0x2b,0x00,0xf8,0xff,0x00,0x00,0xfb,0xff,0x0d,0x00,0xf2,0xff,0xd2,0xff,0xfa,0xff,0x0f,0x00,0x15,0x00,0xea,0xff,0x15,0x00,0x1d,0x00,0x36,0x00,0x00,0x00,0xd7,0xff,0x1c,0x00,0x32,0x00,0x0f,0x00,0x04,0x00,0x4f,0x00,0xd7,0xff,0xf2,0xff,0xbc,0xff,0x04,0x00,0xcf,0xff,0xd6,0xff,0x45,0x00,0x14,0x00,0x18,0x00,0x10,0x00,0xcd,0xff,0xc9,0xff,0x00,0x00,0x2e,0x00,0x01,0x00,0xe8,0xff,0x17,0x00,0x29,0x00,0x03,0x00,0x1b,0x00,0xdd,0xff,0x1c,0x00,0x4b,0x00,0xac,0xff,0xf5,0xff,0xe3,0xff,0x29,0x00,0x0b,0x00,0xe0,0xff,0x16,0x00,0x03,0x00,0x42,0x00,0xde,0xff,0xe4,0xff,0x0b,0x00,0x1b,0x00,0xd2,0xff,0x29,0x00,0xe3,0xff,0xfa,0xff,0x16,0x00,0xe4,0xff,0x07,0x00,0x12,0x00,0x2f,0x00,0xfa,0xff,0x05,0x00,0x15,0x00,0xc2,0xff,0xb2,0xff,0xe0,0xff,0x07,0x00,0x00,0x00,0xd4,0xff,0xf3,0xff,0x25,0x00,0x2d,0x00,0x38,0x00,0xdb,0xff,0xdb,0xff,0x3c,0x00,0xf8,0xff,0x0b,0x00,0xc2,0xff,0x05,0x00,0x0c,0x00,0xd4,0xff,0x23,0x00,0xe0,0xff,0x65,0x00,0xd4,0xff,0xfe,0xff,0xeb,0xff,0xce,0xff,0xc8,0xff,0xfc,0xff,0x03,0x00,0x3b,0x00,0xdd,0xff,0xe5,0xff,0x3b,0x00,0x13,0x00,0xd7,0xff,0xf1,0xff,0xf1,0xff,0x1c,0x00,0xd9,0xff,0xba,0xff,0xe0,0xff,0xf2,0xff,0xf5,0xff,0x1a,0x00,0xd8,0xff,0x0b,0x00,0xf0,0xff,0x30,0x00,0xec,0xff,0x1f,0x00,0xfe,0xff,0x25,0x00,0x33,0x00,0x15,0x00,0x21,0x00,0xf4,0xff,0xfc,0xff,0x24,0x00,0xc7,0xff,0xf4,0xff,0xfa,0xff,0x1e,0x00,0x0d,0x00,0x3c,0x00,0x08,0x00,0xf3,0xff,0x46,0x00,0x1b,0x00,0xf0,0xff,0x14,0x00,0xf6,0xff,0x4a,0x00,0x15,0x00,0x02,0x00,0x28,0x00,0x1a,0x00,0x2f,0x00,0x26,0x00,0x3b,0x00,0x32,0x00,0xfb,0xff,0xee,0xff,0x35,0x00,0xfa,0xff,0xf0,0xff,0x09,0x00,0x26,0x00,0xf1,0xff,0x00,0x00,0xed,0xff,0xca,0xff,0xbe,0xff,0x2d,0x00,0x32,0x00,0x1e,0x00,0x1e,0x00,0xd8,0xff,0xfc,0xff,0x1f,0x00,0x0a,0x00,0x2b,0x00,0xa9,0xff,0x19,0x00,0x02,0x00,0xb4,0xff,0x1f,0x00,0x13,0x00,0xfc,0xff,0xfe,0xff,0x1c,0x00,0xc6,0xff,0x24,0x00,0x0f,0x00,0xef,0xff,0x13,0x00,0xd9,0xff,0x37,0x00,0xfa,0xff,0x2f,0x00,0xf1,0xff,0xef,0xff,0x1c,0x00,0x46,0x00,0xad,0xff,0x1e,0x00,0xf7,0xff,0x28,0x00,0x12,0x00,0xd6,0xff,0xd5,0xff,0x15,0x00,0x3a,0x00,0x52,0x00,0x13,0x00,0xc2,0xff,0xcb,0xff,0xee,0xff,0x0a,0x00,0xff,0xff,0x12,0x00,0x3d,0x00,0x94,0xff,0x24,0x00,0xe6,0xff,0xd9,0xff,0x06,0x00,0x54,0x00,0x24,0x00,0xdd,0xff,0xe5,0xff,0x14,0x00,0x26,0x00,0xae,0xff,0x31,0x00,0xfb,0xff,0x07,0x00,0xfc,0xff,0xcc,0xff,0xdb,0xff,0xe5,0xff,0x04,0x00,0xbb,0xff,0x34,0x00,0x0a,0x00,0x34,0x00,0x04,0x00,0x16,0x00,0xe2,0xff,0xdf,0xff,0x0b,0x00,0x05,0x00,0x0b,0x00,0x03,0x00,0x20,0x00,0x1f,0x00,0x26,0x00,0x01,0x00,0xe9,0xff,0x24,0x00,0x22,0x00,0xfd,0xff,0xe9,0xff,0xe8,0xff,0x4c,0x00,0xe5,0xff,0xf4,0xff,0x16,0x00,0xf0,0xff,0xe3,0xff,0x27,0x00,0xd9,0xff,0xcc,0xff,0x0e,0x00,0xd8,0xff,0xfb,0xff,0x24,0x00,0xfa,0xff,0x15,0x00,0x53,0x00,0xd1,0xff,0x05,0x00,0x12,0x00,0xaf,0xff,0x1b,0x00,0x49,0x00,0x2f,0x00,0x09,0x00,0xd1,0xff,0x08,0x00,0xe2,0xff,0xf2,0xff,0x1d,0x00,0x23,0x00,0xf1,0xff,0x43,0x00,0x16,0x00,0xd2,0xff,0x20,0x00,0x14,0x00,0xf9,0xff,0x57,0x00,0x0b,0x00,0xf9,0xff,0xde,0xff,0x02,0x00,0x32,0x00,0xe0,0xff,0xe0,0xff,0x21,0x00,0x0f,0x00,0xe5,0xff,0xd2,0xff,0xf0,0xff,0x3a,0x00,0x16,0x00,0x1e,0x00,0xf6,0xff,0xfa,0xff,0xf7,0xff,0xee,0xff,0xd9,0xff,0x4c,0x00,0x14,0x00,0x0f,0x00,0x33,0x00,0xf8,0xff,0x04,0x00,0xe7,0xff,0x14,0x00,0xe5,0xff,0xc3,0xff,0xf3,0xff,0x0f,0x00,0xe2,0xff,0xe1,0xff,0x0e,0x00,0xf8,0xff,0x0a,0x00,0x13,0x00,0xad,0xff,0x36,0x00,0x0c,0x00,0x53,0x00,0xdc,0xff,0x18,0x00,0x0f,0x00,0xd8,0xff,0x2e,0x00,0xdc,0xff,0x13,0x00,0x04,0x00,0xca,0xff,0x1b,0x00,0x09,0x00,0x0b,0x00,0x1f,0x00,0xfd,0xff,0x02,0x00,0x05,0x00,0x42,0x00,0x01,0x00,0xf3,0xff,0x10,0x00,0x17,0x00,0xdf,0xff,0xd0,0xff,0x08,0x00,0x24,0x00,0x2e,0x00,0xca,0xff,0xe1,0xff,0xeb,0xff,0xde,0xff,0xb9,0xff,0xfc,0xff,0x00,0x00,0xdb,0xff,0xe2,0xff,0xf5,0xff,0xf6,0xff,0x10,0x00,0x1b,0x00,0x1c,0x00,0xdb,0xff,0x3b,0x00,0xca,0xff,0xff,0xff,0xf2,0xff,0xbb,0xff,0xeb,0xff,0x1b,0x00,0x00,0x00,0xd3,0xff,0x21,0x00,0xa9,0xff,0x22,0x00,0xe4,0xff,0x1c,0x00,0x1e,0x00,0x26,0x00,0xef,0xff,0x18,0x00,0xc1,0xff,0x15,0x00,0x1e,0x00,0x25,0x00,0x1b,0x00,0xfc,0xff,0x37,0x00,0xef,0xff,0xfa,0xff,0xe3,0xff,0x18,0x00,0x08,0x00,0xd7,0xff,0xf2,0xff,0xf1,0xff,0xf1,0xff,0x13,0x00,0x20,0x00,0xf1,0xff,0x2b,0x00,0xcf,0xff,0x35,0x00,0x07,0x00,0xc0,0xff,0xe1,0xff,0x24,0x00,0x0d,0x00,0xe4,0xff,0x19,0x00,0xd9,0xff,0x0f,0x00,0x03,0x00,0xb1,0xff,0x1c,0x00,0x0e,0x00,0xc8,0xff,0xee,0xff,0x07,0x00,0x17,0x00,0xed,0xff,0x21,0x00,0x26,0x00,0x13,0x00,0x38,0x00,0x1e,0x00,0xea,0xff,0xef,0xff,0x07,0x00,0xd5,0xff,0xf6,0xff,0x24,0x00,0xdb,0xff,0xf9,0xff,0x29,0x00,0xe5,0xff,0xf1,0xff,0x04,0x00,0x01,0x00,0x3c,0x00,0xdb,0xff,0x3d,0x00,0x08,0x00,0xbb,0xff,0x1a,0x00,0xe9,0xff,0xd5,0xff,0x12,0x00,0x20,0x00,0xfe,0xff,0xf0,0xff,0xbb,0xff,0xdd,0xff,0x03,0x00,0x3c,0x00,0xff,0xff,0xf7,0xff,0x02,0x00,0x13,0x00,0xf0,0xff,0x18,0x00,0xe6,0xff,0x37,0x00,0xf5,0xff,0xfb,0xff,0x30,0x00,0x09,0x00,0xcb,0xff,0x18,0x00,0xfc,0xff,0xd1,0xff,0x2a,0x00,0xe5,0xff,0xe3,0xff,0x03,0x00,0xf0,0xff,0xd7,0xff,0x0d,0x00,0xd9,0xff,0x23,0x00,0xde,0xff,0xde,0xff,0xde,0xff,0xc0,0xff,0x21,0x00,0x15,0x00,0x4f,0x00,0xf7,0xff,0x21,0x00,0xfc,0xff,0xbc,0xff,0x60,0x00,0x17,0x00,0x0a,0x00,0x30,0x00,0x0b,0x00,0xc8,0xff,0x30,0x00,0x0a,0x00,0x1e,0x00,0xd1,0xff,0xf3,0xff,0xd6,0xff,0x2f,0x00,0xfb,0xff,0xfb,0xff,0x05,0x00,0xed,0xff,0x2d,0x00,0xcf,0xff,0x32,0x00,0x18,0x00,0x0d,0x00,0x2d,0x00,0xf0,0xff,0x95,0xff,0x31,0x00,0x11,0x00,0x02,0x00,0xf8,0xff,0x12,0x00,0x1e,0x00,0xcf,0xff,0x0b,0x00,0xfa,0xff,0x01,0x00,0xe4,0xff,0x26,0x00,0xe2,0xff,0x22,0x00,0x23,0x00,0xfa,0xff,0xfc,0xff,0xea,0xff,0xdd,0xff,0xe0,0xff,0x31,0x00,0x28,0x00,0xf7,0xff,0x3f,0x00,0x1e,0x00,0x1f,0x00,0x07,0x00,0xe0,0xff,0x25,0x00,0x16,0x00,0xb9,0xff,0xcd,0xff,0xe4,0xff,0x0c,0x00,0x08,0x00,0x0b,0x00,0xf2,0xff,0x14,0x00,0xde,0xff,0x3e,0x00,0x1c,0x00,0xf8,0xff,0xe4,0xff,0x11,0x00,0xf6,0xff,0xe0,0xff,0x0f,0x00,0xd5,0xff,0xd9,0xff,0xdd,0xff,0x2a,0x00,0x02,0x00,0x25,0x00,0xe8,0xff,0xee,0xff,0x0a,0x00,0xdf,0xff,0xdf,0xff,0x2a,0x00,0xf1,0xff,0xe0,0xff,0x06,0x00,0xf2,0xff,0x09,0x00,0x05,0x00,0x30,0x00,0xfa,0xff,0x0c,0x00,0x30,0x00,0xfd,0xff,0x50,0x00,0xfd,0xff,0x22,0x00,0x2a,0x00,0x0f,0x00,0xdc,0xff,0x0a,0x00,0x03,0x00,0x11,0x00,0x08,0x00,0xef,0xff,0x2d,0x00,0xe7,0xff,0x13,0x00,0x1d,0x00,0x1c,0x00,0xe6,0xff,0x02,0x00,0x16,0x00,0xfc,0xff,0x0c,0x00,0xf5,0xff,0xf6,0xff,0xbd,0xff,0x25,0x00,0xfd,0xff,0x22,0x00,0x01,0x00,0xd4,0xff,0x34,0x00,0x1c,0x00,0xd1,0xff,0x17,0x00,0x24,0x00,0x06,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x12,0x00,0xe6,0xff,0xf5,0xff,0xd5,0xff,0xf2,0xff,0xd8,0xff,0xfc,0xff,0x24,0x00,0xd4,0xff,0x19,0x00,0x01,0x00,0xca,0xff,0xc2,0xff,0x14,0x00,0x17,0x00,0xdc,0xff,0x06,0x00,0x12,0x00,0x14,0x00,0x08,0x00,0x01,0x00,0xee,0xff,0xf6,0xff,0x21,0x00,0x20,0x00,0x30,0x00,0x02,0x00,0xf2,0xff,0x0b,0x00,0x3a,0x00,0xdc,0xff,0x09,0x00,0xe8,0xff,0xfe,0xff,0x17,0x00,0xd5,0xff,0xf9,0xff,0xdb,0xff,0x0c,0x00,0x29,0x00,0x01,0x00,0x13,0x00,0xf2,0xff,0xee,0xff,0x10,0x00,0xf7,0xff,0xda,0xff,0x18,0x00,0xd6,0xff,0xfa,0xff,0x14,0x00,0x31,0x00,0x05,0x00,0xfc,0xff,0x15,0x00,0xda,0xff,0x07,0x00,0x1e,0x00,0xfd,0xff,0xfd,0xff,0xc9,0xff,0x0d,0x00,0xbc,0xff,0x02,0x00,0xf5,0xff,0xea,0xff,0x13,0x00,0x37,0x00,0xf3,0xff,0xec,0xff,0xea,0xff,0xfd,0xff,0xe5,0xff,0x30,0x00,0xed,0xff,0x14,0x00,0x0e,0x00,0x30,0x00,0x3e,0x00,0xf1,0xff,0x40,0x00,0xd8,0xff,0xdc,0xff,0x0b,0x00,0x1a,0x00,0xf5,0xff,0x28,0x00,0xe4,0xff,0x02,0x00,0xf0,0xff,0x34,0x00,0xdd,0xff,0xed,0xff,0xe4,0xff,0xf3,0xff,0xcc,0xff,0x11,0x00,0x00,0x00,0x0d,0x00,0xfc,0xff,0xfa,0xff,0x80,0xff,0xe2,0xff,0xb1,0xff,0xfc,0xff,0xf7,0xff,0x11,0x00,0xea,0xff,0xed,0xff,0xe2,0xff,0x2d,0x00,0xe1,0xff,0xb2,0xff,0xf7,0xff,0xf8,0xff,0x10,0x00,0xd7,0xff,0x0b,0x00,0xda,0xff,0x27,0x00,0x12,0x00,0xe0,0xff,0x09,0x00,0xae,0xff,0xde,0xff,0xdf,0xff,0xe0,0xff,0x0c,0x00,0xd6,0xff,0xeb,0xff,0x25,0x00,0x05,0x00,0x02,0x00,0xda,0xff,0x30,0x00,0x34,0x00,0xd0,0xff,0xec,0xff,0xf0,0xff,0x0a,0x00,0x25,0x00,0x28,0x00,0x01,0x00,0x48,0x00,0xe0,0xff,0xeb,0xff,0xb5,0xff,0xd5,0xff,0xeb,0xff,0xdb,0xff,0x1d,0x00,0x01,0x00,0xd8,0xff,0xce,0xff,0xf3,0xff,0x25,0x00,0x0f,0x00,0xc3,0xff,0x14,0x00,0xe0,0xff,0x0d,0x00,0xf2,0xff,0x17,0x00,0x27,0x00,0x17,0x00,0xc6,0xff,0x1a,0x00,0xd6,0xff,0x0b,0x00,0xc9,0xff,0xf9,0xff,0x10,0x00,0x0a,0x00,0x13,0x00,0x0c,0x00,0xcb,0xff,0xdc,0xff,0x13,0x00,0xba,0xff,0x06,0x00,0xe4,0xff,0x0b,0x00,0x1a,0x00,0xe8,0xff,0x1f,0x00,0x19,0x00,0x25,0x00,0x36,0x00,0xf2,0xff,0xe0,0xff,0x24,0x00,0xba,0xff,0xf8,0xff,0xf8,0xff,0x05,0x00,0xe6,0xff,0xd8,0xff,0xd4,0xff,0x06,0x00,0x21,0x00,0x09,0x00,0x12,0x00,0xf1,0xff,0x0e,0x00,0xfc,0xff,0xd0,0xff,0xf2,0xff,0x50,0x00,0x09,0x00,0xfc,0xff,0xd1,0xff,0xfd,0xff,0x25,0x00,0xfc,0xff,0xfa,0xff,0xfd,0xff,0x01,0x00,0xf0,0xff,0xd8,0xff,0x31,0x00,0xdd,0xff,0xdc,0xff,0x33,0x00,0x0a,0x00,0x10,0x00,0xec,0xff,0x05,0x00,0xf0,0xff,0x16,0x00,0x11,0x00,0x26,0x00,0x15,0x00,0xe4,0xff,0x2a,0x00,0xfb,0xff,0x15,0x00,0xb8,0xff,0x47,0x00,0x01,0x00,0x29,0x00,0xe0,0xff,0xf3,0xff,0xc9,0xff,0x30,0x00,0x1a,0x00,0x05,0x00,0x21,0x00,0xe9,0xff,0x2e,0x00,0x0e,0x00,0xe1,0xff,0xf3,0xff,0xda,0xff,0xe0,0xff,0x24,0x00,0x2a,0x00,0xe3,0xff,0x0a,0x00,0x16,0x00,0x19,0x00,0x02,0x00,0x30,0x00,0x10,0x00,0x26,0x00,0x2b,0x00,0xef,0xff,0x20,0x00,0xc6,0xff,0x15,0x00,0xe6,0xff,0x1f,0x00,0xe1,0xff,0xf7,0xff,0x33,0x00,0xda,0xff,0x12,0x00,0xe3,0xff,0xf0,0xff,0xee,0xff,0xed,0xff,0xd6,0xff,0xea,0xff,0x01,0x00,0x20,0x00,0xb4,0xff,0xd3,0xff,0x05,0x00,0x18,0x00,0xe8,0xff,0xd9,0xff,0x0f,0x00,0x0b,0x00,0x10,0x00,0xea,0xff,0xea,0xff,0xea,0xff,0xf3,0xff,0x09,0x00,0xe9,0xff,0x0c,0x00,0x14,0x00,0x2a,0x00,0x19,0x00,0x2a,0x00,0x1b,0x00,0x0a,0x00,0xdf,0xff,0xd8,0xff,0x18,0x00,0x23,0x00,0x18,0x00,0xd7,0xff,0x25,0x00,0x22,0x00,0xe1,0xff,0xff,0xff,0x14,0x00,0x2e,0x00,0x1f,0x00,0x23,0x00,0xf4,0xff,0xef,0xff,0xd2,0xff,0xe3,0xff,0xe0,0xff,0x36,0x00,0xea,0xff,0xfd,0xff,0xed,0xff,0x05,0x00,0x01,0x00,0xfa,0xff,0x18,0x00,0x3a,0x00,0xd4,0xff,0xd8,0xff,0xfa,0xff,0xfb,0xff,0xff,0xff,0xfd,0xff,0x46,0x00,0xf3,0xff,0x15,0x00,0x3c,0x00,0xfb,0xff,0x1b,0x00,0x07,0x00,0xf6,0xff,0x20,0x00,0xdd,0xff,0xe5,0xff,0xcd,0xff,0x0f,0x00,0xff,0xff,0x1e,0x00,0x0f,0x00,0xe4,0xff,0x37,0x00,0x0e,0x00,0xec,0xff,0xf9,0xff,0xe2,0xff,0x2f,0x00,0x0d,0x00,0xed,0xff,0xef,0xff,0xf8,0xff,0xe4,0xff,0xdd,0xff,0x0a,0x00,0x2e,0x00,0x08,0x00,0x08,0x00,0x34,0x00,0xe5,0xff,0xec,0xff,0x23,0x00,0x28,0x00,0xe0,0xff,0xe0,0xff,0x1b,0x00,0xde,0xff,0x0d,0x00,0xf7,0xff,0xf8,0xff,0xed,0xff,0xd2,0xff,0x22,0x00,0xd2,0xff,0x43,0x00,0xff,0xff,0xb4,0xff,0xe7,0xff,0xff,0xff,0xe2,0xff,0xed,0xff,0xf5,0xff,0xf9,0xff,0x34,0x00,0x16,0x00,0x06,0x00,0x0b,0x00,0xee,0xff,0x07,0x00,0xa6,0xff,0x08,0x00,0x0d,0x00,0xfd,0xff,0x41,0x00,0x36,0x00,0xf0,0xff,0x1c,0x00,0xf1,0xff,0xeb,0xff,0x31,0x00,0xdc,0xff,0x27,0x00,0x16,0x00,0xc3,0xff,0x14,0x00,0xc8,0xff,0xd5,0xff,0x01,0x00,0x25,0x00,0xdd,0xff,0x2a,0x00,0xf2,0xff,0xec,0xff,0xe7,0xff,0x13,0x00,0xdf,0xff,0x17,0x00,0xed,0xff,0x75,0x00,0x49,0x00,0x1d,0x00,0xe5,0xff,0xf6,0xff,0x01,0x00,0x1d,0x00,0xf9,0xff,0x24,0x00,0xce,0xff,0x1a,0x00,0x14,0x00,0xce,0xff,0x08,0x00,0x01,0x00,0xbf,0xff,0xe6,0xff,0x0f,0x00,0x07,0x00,0xf3,0xff,0x30,0x00,0x1a,0x00,0x05,0x00,0xfa,0xff,0x06,0x00,0x17,0x00,0x25,0x00,0xe0,0xff,0x0e,0x00,0xad,0xff,0x01,0x00,0x15,0x00,0x02,0x00,0x28,0x00,0xde,0xff,0x0a,0x00,0x0e,0x00,0x0c,0x00,0xc0,0xff,0x1d,0x00,0xf1,0xff,0xd9,0xff,0xf7,0xff,0xf8,0xff,0xfa,0xff,0x08,0x00,0xec,0xff,0xd2,0xff,0x34,0x00,0x0f,0x00,0xe6,0xff,0x16,0x00,0xd3,0xff,0x16,0x00,0xd1,0xff,0x30,0x00,0x00,0x00,0x33,0x00,0xed,0xff,0xe8,0xff,0x0e,0x00,0xde,0xff,0xe1,0xff,0x2b,0x00,0x09,0x00,0xfb,0xff,0xec,0xff,0x1f,0x00,0x9b,0xff,0xc7,0xff,0xd3,0xff,0xdf,0xff,0xf2,0xff,0xf7,0xff,0x23,0x00,0xed,0xff,0x0d,0x00,0x2c,0x00,0xcf,0xff,0xf3,0xff,0x14,0x00,0x24,0x00,0xc6,0xff,0xe8,0xff,0xfa,0xff,0xe5,0xff,0xdf,0xff,0xfc,0xff,0x3b,0x00,0x07,0x00,0x11,0x00,0xd9,0xff,0x1b,0x00,0x06,0x00,0xde,0xff,0x28,0x00,0x03,0x00,0xe6,0xff,0xcc,0xff,0xe9,0xff,0xe1,0xff,0xfb,0xff,0x24,0x00,0xf6,0xff,0x1b,0x00,0x1a,0x00,0x0c,0x00,0x0f,0x00,0x03,0x00,0x20,0x00,0xc2,0xff,0xf2,0xff,0xca,0xff,0xcd,0xff,0x09,0x00,0x4d,0x00,0xf7,0xff,0xdc,0xff,0xb0,0xff,0xf1,0xff,0xc6,0xff,0x0b,0x00,0xd6,0xff,0xb1,0xff,0x02,0x00,0x0a,0x00,0x08,0x00,0x1e,0x00,0x0d,0x00,0x10,0x00,0x08,0x00,0x2e,0x00,0x01,0x00,0xe8,0xff,0x3c,0x00,0x16,0x00,0x1d,0x00,0x0c,0x00,0x11,0x00,0xfc,0xff,0xc4,0xff,0xf2,0xff,0x3a,0x00,0x09,0x00,0x22,0x00,0x3d,0x00,0xe0,0xff,0x39,0x00,0x06,0x00,0xed,0xff,0x02,0x00,0x07,0x00,0xa1,0xff,0xef,0xff,0xfb,0xff,0xee,0xff,0x2b,0x00,0x0d,0x00,0xe5,0xff,0xfd,0xff,0x01,0x00,0xfc,0xff,0xf2,0xff,0x1d,0x00,0x20,0x00,0x1e,0x00,0xc9,0xff,0x1e,0x00,0xe9,0xff,0x34,0x00,0xde,0xff,0x03,0x00,0xfd,0xff,0x44,0x00,0xc7,0xff,0xd8,0xff,0x31,0x00,0xd6,0xff,0x25,0x00,0x15,0x00,0xe3,0xff,0x10,0x00,0xf5,0xff,0x1c,0x00,0x17,0x00,0xf9,0xff,0xf8,0xff,0xe3,0xff,0xbd,0xff,0x02,0x00,0x21,0x00,0xfc,0xff,0x09,0x00,0x01,0x00,0x15,0x00,0xce,0xff,0xfa,0xff,0xd9,0xff,0xc6,0xff,0xd2,0xff,0xea,0xff,0xc2,0xff,0x0b,0x00,0x37,0x00,0xf7,0xff,0x36,0x00,0x08,0x00,0x15,0x00,0xd7,0xff,0x1d,0x00,0xe4,0xff,0x0e,0x00,0x1b,0x00,0x33,0x00,0xe9,0xff,0xef,0xff,0x07,0x00,0xe5,0xff,0x27,0x00,0xd8,0xff,0xda,0xff,0xda,0xff,0xf9,0xff,0x29,0x00,0xe4,0xff,0xf8,0xff,0xf5,0xff,0x18,0x00,0xea,0xff,0x3d,0x00,0x14,0x00,0xc3,0xff,0xce,0xff,0x1b,0x00,0xd4,0xff,0xbe,0xff,0x0f,0x00,0x26,0x00,0xf5,0xff,0x08,0x00,0xf9,0xff,0x03,0x00,0x1a,0x00,0x17,0x00,0xf4,0xff,0xde,0xff,0x26,0x00,0xd6,0xff,0xe0,0xff,0x28,0x00,0xbc,0xff,0x9c,0xff,0x02,0x00,0x01,0x00,0x9f,0xff,0x15,0x00,0x28,0x00,0xdd,0xff,0x40,0x00,0x5e,0x00,0xb6,0xff,0xe0,0xff,0xd9,0xff,0x39,0x00,0xc0,0xff,0x1f,0x00,0x19,0x00,0xee,0xff,0xcd,0xff,0xb7,0xff,0xef,0xff,0xea,0xff,0xa6,0xff,0x4a,0x00,0x3b,0x00,0xf3,0xff,0x5f,0x00,0x37,0x00,0x2d,0x00,0xf3,0xff,0xa6,0xff,0x28,0x00,0xf3,0xff,0x3c,0x00,0x08,0x00,0xec,0xff,0xda,0xff,0x1e,0x00,0x2c,0x00,0x03,0x00,0xe8,0xff,0xd5,0xff,0x22,0x00,0xfc,0xff,0xa0,0xff,0xee,0xff,0xd3,0xff,0x12,0x00,0x14,0x00,0x1a,0x00,0xe3,0xff,0xa2,0xff,0x49,0x00,0xd9,0xff,0xad,0xff,0x17,0x00,0xf5,0xff,0xef,0xff,0xef,0xff,0x41,0x00,0x04,0x00,0xf7,0xff,0x04,0x00,0x05,0x00,0xdf,0xff,0x09,0x00,0x21,0x00,0xf4,0xff,0xf9,0xff,0x07,0x00,0x13,0x00,0xe8,0xff,0x00,0x00,0x37,0x00,0xe5,0xff,0x04,0x00,0xe8,0xff,0x1c,0x00,0xdc,0xff,0x06,0x00,0xfb,0xff,0xe2,0xff,0x06,0x00,0xde,0xff,0x13,0x00,0xee,0xff,0xf2,0xff,0x12,0x00,0x0e,0x00,0xeb,0xff,0x0a,0x00,0x10,0x00,0x18,0x00,0x01,0x00,0xf7,0xff,0xef,0xff,0x01,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0xf9,0xff,0x0b,0x00,0x0e,0x00,0x09,0x00,0x17,0x00,0xc1,0xff,0xee,0xff,0x05,0x00,0x09,0x00,0xf3,0xff,0x04,0x00,0x16,0x00,0x04,0x00,0xfc,0xff,0xf8,0xff,0xf3,0xff,0xf3,0xff,0xd0,0xff,0x07,0x00,0x00,0x00,0xfd,0xff,0x05,0x00,0x05,0x00,0x06,0x00,0xfc,0xff,0xf7,0xff,0xf9,0xff,0x11,0x00,0x19,0x00,0xf3,0xff,0x14,0x00,0xf6,0xff,0x0f,0x00,0x0b,0x00,0xf8,0xff,0x06,0x00,0x18,0x00,0x13,0x00,0xfe,0xff,0xf2,0xff,0xe1,0xff,0x2d,0x00,0xd6,0xff,0x31,0x00,0xfd,0xff,0xea,0xff,0x17,0x00,0xef,0xff,0x31,0x00,0x0d,0x00,0x00,0x00,0xf4,0xff,0x0f,0x00,0xf3,0xff,0xe0,0xff,0x06,0x00,0x2a,0x00,0x02,0x00,0xf4,0xff,0xfd,0xff,0xee,0xff,0x2a,0x00,0x01,0x00,0xe3,0xff,0xf6,0xff,0x10,0x00,0xfc,0xff,0x0b,0x00,0x0e,0x00,0xf4,0xff,0xee,0xff,0x03,0x00,0xe4,0xff,0xfb,0xff,0xfa,0xff,0xfb,0xff,0x08,0x00,0x01,0x00,0xed,0xff,0xf6,0xff,0xf1,0xff,0xe8,0xff,0xee,0xff,0x0a,0x00,0xf3,0xff,0x01,0x00,0xf4,0xff,0x14,0x00,0x04,0x00,0xf7,0xff,0xf0,0xff,0x0d,0x00,0x0b,0x00,0xf7,0xff,0x12,0x00,0x0a,0x00,0xe8,0xff,0x04,0x00,0x2b,0x00,0xf1,0xff,0x0f,0x00,0xe8,0xff,0xe3,0xff,0xec,0xff,0xe7,0xff,0x1c,0x00,0xfd,0xff,0x1d,0x00,0x0c,0x00,0xd7,0xff,0x1a,0x00,0xec,0xff,0x18,0x00,0x0a,0x00,0xf9,0xff,0xf6,0xff,0x17,0x00,0xd8,0xff,0xf8,0xff,0x23,0x00,0x09,0x00,0x06,0x00,0xf4,0xff,0x04,0x00,0xea,0xff,0x13,0x00,0x03,0x00,0xda,0xff,0xfd,0xff,0x30,0x00,0xed,0xff,0x08,0x00,0x05,0x00,0xf7,0xff,0xf2,0xff,0x09,0x00,0xf4,0xff,0xdd,0xff,0x02,0x00,0x10,0x00,0x07,0x00,0x08,0x00,0xf6,0xff,0x0e,0x00,0x28,0x00,0xe0,0xff,0xf4,0xff,0xee,0xff,0xf3,0xff,0xf1,0xff,0xf0,0xff,0x01,0x00,0x11,0x00,0xf1,0xff,0xdd,0xff,0xfd,0xff,0x1e,0x00,0xf3,0xff,0x2a,0x00,0xf4,0xff,0x13,0x00,0xfe,0xff,0xd6,0xff,0xe0,0xff,0x01,0x00,0xef,0xff,0xf3,0xff,0xfd,0xff,0xf7,0xff,0x06,0x00,0xfc,0xff,0xde,0xff,0x05,0x00,0x17,0x00,0xff,0xff,0x1d,0x00,0x0b,0x00,0x1f,0x00,0xfa,0xff,0xf3,0xff,0x0b,0x00,0xeb,0xff,0x0e,0x00,0x20,0x00,0xee,0xff,0x08,0x00,0xe7,0xff,0xf6,0xff,0x09,0x00,0x0a,0x00,0xfd,0xff,0xe9,0xff,0xe8,0xff,0x06,0x00,0xd9,0xff,0xf9,0xff,0xcc,0xff,0xe7,0xff,0xe6,0xff,0xfb,0xff,0xf6,0xff,0xef,0xff,0xf9,0xff,0x1a,0x00,0x02,0x00,0x0d,0x00,0xf2,0xff,0x09,0x00,0x1f,0x00,0xf2,0xff,0xf0,0xff,0xf5,0xff,0xf2,0xff,0xe7,0xff,0xdc,0xff,0x00,0x00,0xfc,0xff,0xfa,0xff,0xd1,0xff,0xff,0xff,0x2b,0x00,0x03,0x00,0x0f,0x00,0xef,0xff,0xe6,0xff,0xe5,0xff,0xe1,0xff,0xe0,0xff,0xff,0xff,0x01,0x00,0xfa,0xff,0xf9,0xff,0xf8,0xff,0x0f,0x00,0x10,0x00,0xd0,0xff,0x07,0x00,0xdc,0xff,0xbf,0xff,0x19,0x00,0x28,0x00,0x1b,0x00,0x01,0x00,0x1c,0x00,0x07,0x00,0xe8,0xff,0x04,0x00,0x28,0x00,0x09,0x00,0x0b,0x00,0xfe,0xff,0xf5,0xff,0x18,0x00,0xf6,0xff,0x09,0x00,0xe8,0xff,0xf2,0xff,0x2e,0x00,0xdf,0xff,0xfe,0xff,0xeb,0xff,0xec,0xff,0xf5,0xff,0x06,0x00,0xfe,0xff,0xf0,0xff,0x1c,0x00,0x32,0x00,0xfe,0xff,0x0a,0x00,0xef,0xff,0x1b,0x00,0x27,0x00,0x07,0x00,0x04,0x00,0x1b,0x00,0xf6,0xff,0xdc,0xff,0x03,0x00,0xfd,0xff,0xfb,0xff,0xf3,0xff,0xdc,0xff,0xf7,0xff,0xe5,0xff,0x07,0x00,0x1c,0x00,0xbf,0xff,0x10,0x00,0xfc,0xff,0x09,0x00,0x0e,0x00,0xf9,0xff,0xf1,0xff,0xfc,0xff,0x05,0x00,0xf6,0xff,0x10,0x00,0x0a,0x00,0xe0,0xff,0x0c,0x00,0xd3,0xff,0xe8,0xff,0x1e,0x00,0x0b,0x00,0x01,0x00,0x00,0x00,0x15,0x00,0xfb,0xff,0xf7,0xff,0xf8,0xff,0xf6,0xff,0x1b,0x00,0x0a,0x00,0xf4,0xff,0xf5,0xff,0x0c,0x00,0xfe,0xff,0x04,0x00,0xfe,0xff,0xd8,0xff,0x14,0x00,0xf6,0xff,0xfd,0xff,0xca,0xff,0x10,0x00,0xee,0xff,0x01,0x00,0xfd,0xff,0xf0,0xff,0x12,0x00,0x29,0x00,0x0f,0x00,0x0c,0x00,0xfc,0xff,0x29,0x00,0xdc,0xff,0xfd,0xff,0xfb,0xff,0x0d,0x00,0x0e,0x00,0xe2,0xff,0xea,0xff,0xfb,0xff,0xe5,0xff,0xe3,0xff,0xe9,0xff,0x57,0x00,0xe2,0xff,0xfd,0xff,0x4a,0x00,0xb4,0xff,0xf2,0xff,0xb4,0xff,0xb5,0xff,0xd3,0xff,0xbe,0xff,0x15,0x00,0xd9,0xff,0xa4,0xff,0x28,0x00,0xd7,0xff,0x13,0x00,0x12,0x00,0x41,0x00,0xeb,0xff,0x30,0x00,0x09,0x00,0x2b,0x00,0x16,0x00,0xd5,0xff,0xf7,0xff,0x3c,0x00,0x46,0x00,0x22,0x00,0x0c,0x00,0x3a,0x00,0x3a,0x00,0x09,0x00,0xba,0xff,0x5f,0x00,0x03,0x00,0x63,0x00,0x43,0x00,0xeb,0xff,0x1f,0x00,0x19,0x00,0x76,0x00,0xea,0xff,0xfa,0xff,0xaf,0xff,0x7f,0x00,0xdb,0xff,0x8f,0xff,0x57,0x00,0x3c,0x00,0x1f,0x00,0x3d,0x00,0xca,0xff,0xf3,0xff,0x33,0x00,0xe8,0xff,0xd4,0xff,0x61,0x00,0xa8,0xff,0x5a,0x00,0xe5,0xff,0x14,0x00,0x96,0xff,0x5a,0x00,0xd7,0xff,0x03,0x00,0xe1,0xff,0xed,0xff,0xfc,0xff,0x25,0x00,0xfa,0xff,0xa4,0xff,0xc8,0xff,0x1a,0x00,0xfc,0xff,0x1b,0x00,0x15,0x00,0xe6,0xff,0x07,0x00,0xcb,0xff,0xdd,0xff,0xfa,0xff,0x05,0x00,0x1d,0x00,0x0d,0x00,0x1a,0x00,0xe1,0xff,0xec,0xff,0x02,0x00,0xde,0xff,0xd2,0xff,0xc6,0xff,0xf7,0xff,0x05,0x00,0xf4,0xff,0x0b,0x00,0x0e,0x00,0xfb,0xff,0xef,0xff,0x08,0x00,0x1d,0x00,0x52,0x00,0x39,0x00,0x04,0x00,0xe0,0xff,0x2a,0x00,0xee,0xff,0x29,0x00,0x20,0x00,0xdd,0xff,0xff,0xff,0x0d,0x00,0x02,0x00,0x2d,0x00,0xd8,0xff,0xfd,0xff,0xf9,0xff,0x16,0x00,0xe7,0xff,0x1f,0x00,0x42,0x00,0xd5,0xff,0xf9,0xff,0xe4,0xff,0xcb,0xff,0xe3,0xff,0xe9,0xff,0x2d,0x00,0xf0,0xff,0x00,0x00,0x1f,0x00,0x00,0x00,0x07,0x00,0xec,0xff,0xf7,0xff,0xe1,0xff,0xcc,0xff,0x1a,0x00,0x0f,0x00,0x00,0x00,0x1c,0x00,0xf6,0xff,0x1c,0x00,0xa2,0xff,0xa2,0xff,0xf3,0xff,0x0a,0x00,0x2e,0x00,0xb7,0xff,0x11,0x00,0xc3,0xff,0xe7,0xff,0x01,0x00,0x45,0x00,0x32,0x00,0x41,0x00,0x5f,0x00,0xd0,0xff,0x06,0x00,0x0d,0x00,0x01,0x00,0x27,0x00,0x4f,0x00,0x10,0x00,0x35,0x00,0xff,0xff,0xf5,0xff,0x19,0x00,0xf6,0xff,0x5e,0x00,0xfa,0xff,0x04,0x00,0xf5,0xff,0xfe,0xff,0xa7,0xff,0xb1,0xff,0x03,0x00,0xf9,0xff,0xe8,0xff,0xe2,0xff,0x22,0x00,0x01,0x00,0xe4,0xff,0x0f,0x00,0xe2,0xff,0x01,0x00,0xea,0xff,0xfd,0xff,0xe1,0xff,0xf2,0xff,0x5e,0x00,0xed,0xff,0x16,0x00,0x20,0x00,0xe9,0xff,0xdf,0xff,0x0c,0x00,0x16,0x00,0x2a,0x00,0xdd,0xff,0xdb,0xff,0x19,0x00,0xe1,0xff,0x02,0x00,0x0a,0x00,0x18,0x00,0xd4,0xff,0x00,0x00,0xeb,0xff,0xfd,0xff,0xf9,0xff,0xc8,0xff,0x1e,0x00,0xb5,0xff,0x0a,0x00,0xb1,0xff,0x54,0x00,0xf8,0xff,0x02,0x00,0xfa,0xff,0x03,0x00,0x03,0x00,0x20,0x00,0xf1,0xff,0x59,0x00,0x2c,0x00,0xde,0xff,0x0e,0x00,0x22,0x00,0xed,0xff,0xb9,0xff,0x18,0x00,0x2d,0x00,0xe9,0xff,0xef,0xff,0xfa,0xff,0x49,0x00,0xff,0xff,0xa4,0xff,0x12,0x00,0x1c,0x00,0xef,0xff,0xd8,0xff,0xd6,0xff,0x32,0x00,0x50,0x00,0x03,0x00,0x0a,0x00,0x24,0x00,0x12,0x00,0xfc,0xff,0x32,0x00,0x19,0x00,0x05,0x00,0xf2,0xff,0x08,0x00,0xee,0xff,0xf4,0xff,0x13,0x00,0xaf,0xff,0xd9,0xff,0x2b,0x00,0xfe,0xff,0x0f,0x00,0x1f,0x00,0xca,0xff,0x1c,0x00,0xd3,0xff,0x08,0x00,0x10,0x00,0xe8,0xff,0xf4,0xff,0xf7,0xff,0x0c,0x00,0xc2,0xff,0x01,0x00,0x08,0x00,0x4a,0x00,0xdd,0xff,0x29,0x00,0xf3,0xff,0x14,0x00,0x0d,0x00,0xef,0xff,0xc8,0xff,0x0a,0x00,0x0f,0x00,0x2e,0x00,0x0c,0x00,0xc8,0xff,0x45,0x00,0x00,0x00,0x72,0x00,0xdc,0xff,0xee,0xff,0x16,0x00,0xf8,0xff,0x1d,0x00,0x14,0x00,0xed,0xff,0xd0,0xff,0xb0,0xff,0xf6,0xff,0xfd,0xff,0x08,0x00,0x06,0x00,0x15,0x00,0xd4,0xff,0xfb,0xff,0xe0,0xff,0x2d,0x00,0x00,0x00,0xfc,0xff,0x50,0x00,0x12,0x00,0xe6,0xff,0x0f,0x00,0x13,0x00,0x13,0x00,0x4c,0x00,0x3a,0x00,0xec,0xff,0x59,0x00,0xbb,0xff,0xcc,0xff,0xd3,0xff,0xd8,0xff,0x08,0x00,0xfd,0xff,0x07,0x00,0x19,0x00,0x36,0x00,0x2d,0x00,0x12,0x00,0x26,0x00,0xe4,0xff,0xe9,0xff,0xff,0xff,0xcf,0xff,0x05,0x00,0xef,0xff,0x18,0x00,0xed,0xff,0xf6,0xff,0x1f,0x00,0x32,0x00,0x05,0x00,0x0a,0x00,0x1b,0x00,0xf3,0xff,0xce,0xff,0x0e,0x00,0x11,0x00,0xd7,0xff,0xfe,0xff,0x2f,0x00,0xcc,0xff,0xf6,0xff,0x01,0x00,0xd2,0xff,0xf3,0xff,0xd7,0xff,0x06,0x00,0x22,0x00,0x2d,0x00,0x28,0x00,0xc2,0xff,0x1c,0x00,0xf1,0xff,0xf5,0xff,0x14,0x00,0x3c,0x00,0xd4,0xff,0x1b,0x00,0x0c,0x00,0x1f,0x00,0x55,0x00,0xff,0xff,0xd9,0xff,0xe7,0xff,0xe9,0xff,0xd0,0xff,0x1d,0x00,0x03,0x00,0x18,0x00,0xfd,0xff,0xf7,0xff,0x20,0x00,0xfb,0xff,0xe9,0xff,0xcd,0xff,0xf4,0xff,0x06,0x00,0x53,0x00,0x29,0x00,0x7f,0x00,0x3b,0x00,0xed,0xff,0x55,0x00,0xfc,0xff,0x39,0x00,0xe5,0xff,0xf1,0xff,0x09,0x00,0xdd,0xff,0x02,0x00,0x29,0x00,0x31,0x00,0xee,0xff,0x49,0x00,0x07,0x00,0x0e,0x00,0x15,0x00,0xf0,0xff,0xb5,0xff,0x22,0x00,0xbf,0xff,0x8f,0xff,0x18,0x00,0x59,0x00,0x4a,0x00,0xfb,0xff,0x44,0x00,0xc2,0xff,0xf6,0xff,0xef,0xff,0x37,0x00,0xe0,0xff,0x47,0x00,0x08,0x00,0xff,0xff,0xdf,0xff,0xd4,0xff,0xf2,0xff,0xbf,0xff,0x23,0x00,0xf8,0xff,0xe5,0xff,0xe0,0xff,0x6a,0x00,0xe9,0xff,0x39,0x00,0xfd,0xff,0x09,0x00,0xe4,0xff,0xe1,0xff,0x63,0x00,0x18,0x00,0x2c,0x00,0x1d,0x00,0xb5,0xff,0xe6,0xff,0xe8,0xff,0xf1,0xff,0xeb,0xff,0x59,0x00,0x0d,0x00,0xf8,0xff,0xd5,0xff,0x22,0x00,0xf4,0xff,0x19,0x00,0xd0,0xff,0x2e,0x00,0x01,0x00,0xe5,0xff,0xe0,0xff,0x04,0x00,0xe2,0xff,0x38,0x00,0xdc,0xff,0x16,0x00,0x04,0x00,0x0a,0x00,0x33,0x00,0xe0,0xff,0x07,0x00,0xdb,0xff,0x22,0x00,0x1e,0x00,0x05,0x00,0x1d,0x00,0x0f,0x00,0x00,0x00,0xe2,0xff,0xe6,0xff,0xcb,0xff,0x50,0x00,0x36,0x00,0xfb,0xff,0xb4,0xff,0xf8,0xff,0x04,0x00,0x00,0x00,0xed,0xff,0xe5,0xff,0xc6,0xff,0x32,0x00,0xd8,0xff,0xdf,0xff,0x20,0x00,0xc1,0xff,0xb5,0xff,0x1f,0x00,0xff,0xff,0x24,0x00,0x14,0x00,0x42,0x00,0xf2,0xff,0x27,0x00,0xf8,0xff,0xd6,0xff,0x2e,0x00,0x0f,0x00,0x18,0x00,0xbd,0xff,0xfa,0xff,0xe7,0xff,0x3f,0x00,0xbe,0xff,0x16,0x00,0x0a,0x00,0x3d,0x00,0x0d,0x00,0x48,0x00,0xe5,0xff,0x13,0x00,0x0e,0x00,0xd2,0xff,0x08,0x00,0xe1,0xff,0x22,0x00,0xd2,0xff,0x13,0x00,0x0b,0x00,0x1e,0x00,0xfd,0xff,0x1c,0x00,0xf3,0xff,0xb3,0xff,0xfe,0xff,0x87,0xff,0xf1,0xff,0xf9,0xff,0x95,0xff,0x18,0x00,0x15,0x00,0x2d,0x00,0x1b,0x00,0x33,0x00,0x08,0x00,0xed,0xff,0xc6,0xff,0xf8,0xff,0xf7,0xff,0x24,0x00,0x2e,0x00,0x10,0x00,0xf6,0xff,0xe1,0xff,0x09,0x00,0xfe,0xff,0xe4,0xff,0x22,0x00,0xf2,0xff,0xde,0xff,0x09,0x00,0xe2,0xff,0xf1,0xff,0xfd,0xff,0x08,0x00,0x38,0x00,0x10,0x00,0x96,0xff,0xe9,0xff,0xe8,0xff,0xf9,0xff,0xd4,0xff,0x07,0x00,0x0e,0x00,0xd8,0xff,0xe6,0xff,0x10,0x00,0x16,0x00,0x03,0x00,0x0b,0x00,0xe7,0xff,0x32,0x00,0xc0,0xff,0xf9,0xff,0x34,0x00,0x4b,0x00,0x1e,0x00,0xd2,0xff,0x14,0x00,0xf8,0xff,0xfe,0xff,0xe8,0xff,0x13,0x00,0x0a,0x00,0x13,0x00,0x2e,0x00,0xf1,0xff,0xd3,0xff,0x19,0x00,0x09,0x00,0xda,0xff,0x06,0x00,0x1e,0x00,0x09,0x00,0xf0,0xff,0x0a,0x00,0xec,0xff,0xda,0xff,0x24,0x00,0xde,0xff,0xfe,0xff,0x33,0x00,0x18,0x00,0xeb,0xff,0x02,0x00,0x9c,0xff,0xce,0xff,0xcb,0xff,0x08,0x00,0xf9,0xff,0x18,0x00,0x0a,0x00,0x24,0x00,0xc5,0xff,0xf7,0xff,0x09,0x00,0x1d,0x00,0x25,0x00,0xdb,0xff,0xdf,0xff,0xe4,0xff,0xd9,0xff,0xe9,0xff,0x05,0x00,0xcf,0xff,0x4e,0x00,0xe0,0xff,0x31,0x00,0x39,0x00,0x09,0x00,0x0b,0x00,0xee,0xff,0x1c,0x00,0xf2,0xff,0xe0,0xff,0xf2,0xff,0xc6,0xff,0x11,0x00,0xe2,0xff,0xf3,0xff,0x08,0x00,0x11,0x00,0xc1,0xff,0xae,0xff,0x3c,0x00,0xab,0xff,0x36,0x00,0xe1,0xff,0x2c,0x00,0xe2,0xff,0xd6,0xff,0xc4,0xff,0xf8,0xff,0x20,0x00,0x0d,0x00,0x06,0x00,0xef,0xff,0xfe,0xff,0xc9,0xff,0xc4,0xff,0x24,0x00,0x24,0x00,0xde,0xff,0x2e,0x00,0xb0,0xff,0xf0,0xff,0xdc,0xff,0x3f,0x00,0xaa,0xff,0x3d,0x00,0x0f,0x00,0x15,0x00,0x38,0x00,0xe8,0xff,0x30,0x00,0x02,0x00,0xab,0xff,0xde,0xff,0x4b,0x00,0xce,0xff,0x3d,0x00,0x28,0x00,0x35,0x00,0x5e,0x00,0x32,0x00,0xd8,0xff,0xed,0xff,0x43,0x00,0x35,0x00,0xfe,0xff,0xf5,0xff,0x28,0x00,0x02,0x00,0xf9,0xff,0xd9,0xff,0x08,0x00,0xce,0xff,0xe9,0xff,0x0b,0x00,0xde,0xff,0xdf,0xff,0xcf,0xff,0x33,0x00,0x25,0x00,0x03,0x00,0xc7,0xff,0xfb,0xff,0xeb,0xff,0xf7,0xff,0xf6,0xff,0xc0,0xff,0x14,0x00,0xf0,0xff,0x14,0x00,0x48,0x00,0xac,0xff,0xee,0xff,0xed,0xff,0xda,0xff,0xd9,0xff,0xf6,0xff,0x01,0x00,0x12,0x00,0xf7,0xff,0x29,0x00,0x9a,0xff,0x04,0x00,0xb8,0xff,0x1e,0x00,0xcb,0xff,0x45,0x00,0x16,0x00,0x0c,0x00,0x37,0x00,0x2a,0x00,0x0c,0x00,0xfd,0xff,0xa0,0xff,0xfd,0xff,0x01,0x00,0x18,0x00,0xeb,0xff,0xdc,0xff,0x0c,0x00,0x13,0x00,0xcf,0xff,0x69,0x00,0x0b,0x00,0xe5,0xff,0x3f,0x00,0x07,0x00,0x1c,0x00,0xe1,0xff,0xda,0xff,0x10,0x00,0x22,0x00,0x38,0x00,0xd3,0xff,0x9b,0xff,0xfb,0xff,0x12,0x00,0xe8,0xff,0x1c,0x00,0x01,0x00,0xd2,0xff,0x15,0x00,0xfd,0xff,0x3e,0x00,0x0b,0x00,0x0c,0x00,0xe9,0xff,0xf1,0xff,0x11,0x00,0xf2,0xff,0x0f,0x00,0xdd,0xff,0x2e,0x00,0xe9,0xff,0xbe,0xff,0x06,0x00,0x02,0x00,0xe2,0xff,0x2c,0x00,0x05,0x00,0x12,0x00,0xbe,0xff,0x12,0x00,0xd9,0xff,0xfa,0xff,0x39,0x00,0x1f,0x00,0x11,0x00,0x39,0x00,0xfe,0xff,0xeb,0xff,0xd6,0xff,0xfc,0xff,0xd5,0xff,0xfd,0xff,0xe4,0xff,0xfb,0xff,0xec,0xff,0x0c,0x00,0xb6,0xff,0xf8,0xff,0x1b,0x00,0xe9,0xff,0xbd,0xff,0x19,0x00,0xe7,0xff,0xe0,0xff,0x17,0x00,0x1a,0x00,0x5c,0x00,0x09,0x00,0xec,0xff,0xba,0xff,0x42,0x00,0x09,0x00,0xf5,0xff,0xf0,0xff,0x9c,0xff,0xe3,0xff,0xc7,0xff,0xd6,0xff,0x1a,0x00,0xf7,0xff,0x0e,0x00,0x03,0x00,0xfc,0xff,0xff,0xff,0xe8,0xff,0xb5,0xff,0x45,0x00,0x38,0x00,0x06,0x00,0xeb,0xff,0x33,0x00,0xcc,0xff,0xc9,0xff,0x2b,0x00,0x12,0x00,0xfd,0xff,0x45,0x00,0x1b,0x00,0xf3,0xff,0xfd,0xff,0x0e,0x00,0x1f,0x00,0x09,0x00,0x3f,0x00,0x1a,0x00,0x1c,0x00,0x1a,0x00,0x01,0x00,0x02,0x00,0xfe,0xff,0xc6,0xff,0xba,0xff,0xf2,0xff,0xea,0xff,0xfb,0xff,0xdf,0xff,0x47,0x00,0x34,0x00,0xf0,0xff,0xd6,0xff,0x6c,0x00,0x15,0x00,0x06,0x00,0xd8,0xff,0xf8,0xff,0x3c,0x00,0x2a,0x00,0xe3,0xff,0x42,0x00,0x26,0x00,0xd3,0xff,0x08,0x00,0xf9,0xff,0xe2,0xff,0x15,0x00,0x2b,0x00,0x14,0x00,0xea,0xff,0xe7,0xff,0x08,0x00,0x22,0x00,0xf0,0xff,0xeb,0xff,0xf7,0xff,0x01,0x00,0xeb,0xff,0xff,0xff,0x03,0x00,0xde,0xff,0x27,0x00,0x0e,0x00,0xad,0xff,0xd1,0xff,0x34,0x00,0x18,0x00,0xfa,0xff,0xc5,0xff,0xeb,0xff,0x10,0x00,0xb2,0xff,0x08,0x00,0xe1,0xff,0x19,0x00,0x06,0x00,0x22,0x00,0xff,0xff,0x29,0x00,0xdb,0xff,0xec,0xff,0x00,0x00,0x22,0x00,0xcb,0xff,0x07,0x00,0xc4,0xff,0xf0,0xff,0xfa,0xff,0x1d,0x00,0xfc,0xff,0xe6,0xff,0xee,0xff,0x2b,0x00,0xef,0xff,0xc4,0xff,0xa0,0xff,0x11,0x00,0x26,0x00,0xf4,0xff,0x1f,0x00,0x1b,0x00,0x05,0x00,0xb6,0xff,0xfa,0xff,0xff,0xff,0xf4,0xff,0x09,0x00,0x1a,0x00,0xbb,0xff,0xfe,0xff,0x47,0x00,0x0f,0x00,0x1a,0x00,0x06,0x00,0xe8,0xff,0x1d,0x00,0xdb,0xff,0x26,0x00,0xeb,0xff,0xbe,0xff,0x11,0x00,0xf4,0xff,0x66,0x00,0xff,0xff,0xf3,0xff,0x02,0x00,0x32,0x00,0xcd,0xff,0x07,0x00,0x0f,0x00,0xf3,0xff,0xf3,0xff,0xbf,0xff,0x28,0x00,0x02,0x00,0xe3,0xff,0x07,0x00,0xec,0xff,0xf5,0xff,0x37,0x00,0x6b,0x00,0xe7,0xff,0x1a,0x00,0xdc,0xff,0xec,0xff,0xd6,0xff,0x0a,0x00,0x1f,0x00,0xff,0xff,0xf8,0xff,0x04,0x00,0x14,0x00,0x1e,0x00,0x06,0x00,0xfc,0xff,0x04,0x00,0x4f,0x00,0xbd,0xff,0x0e,0x00,0x42,0x00,0x95,0xff,0xca,0xff,0xde,0xff,0xec,0xff,0xef,0xff,0x05,0x00,0x00,0x00,0xc5,0xff,0xc6,0xff,0x42,0x00,0xf8,0xff,0xe3,0xff,0x23,0x00,0xee,0xff,0xfa,0xff,0xd9,0xff,0x47,0x00,0xb0,0xff,0xd3,0xff,0xda,0xff,0xbe,0xff,0x05,0x00,0x15,0x00,0x05,0x00,0x0e,0x00,0x07,0x00,0x12,0x00,0x05,0x00,0x03,0x00,0x29,0x00,0x3e,0x00,0xfc,0xff,0xfc,0xff,0x0d,0x00,0x05,0x00,0x1d,0x00,0xf0,0xff,0x20,0x00,0x04,0x00,0x66,0x00,0xf9,0xff,0xf7,0xff,0xe2,0xff,0xf7,0xff,0x4a,0x00,0xd2,0xff,0x12,0x00,0xfb,0xff,0xfa,0xff,0x08,0x00,0x1a,0x00,0xff,0xff,0x30,0x00,0xdb,0xff,0x3c,0x00,0x06,0x00,0x17,0x00,0x2e,0x00,0x98,0xff,0x31,0x00,0xf0,0xff,0x1d,0x00,0x12,0x00,0xf2,0xff,0xfe,0xff,0x28,0x00,0xf3,0xff,0x39,0x00,0x0c,0x00,0x0c,0x00,0x0b,0x00,0xf2,0xff,0xd9,0xff,0x22,0x00,0x16,0x00,0xcf,0xff,0xf9,0xff,0xdc,0xff,0x04,0x00,0x1b,0x00,0xd2,0xff,0xfe,0xff,0xd5,0xff,0x22,0x00,0xe2,0xff,0xbe,0xff,0xd3,0xff,0xd8,0xff,0xcd,0xff,0xf6,0xff,0x0d,0x00,0xca,0xff,0x8b,0xff,0xeb,0xff,0x2b,0x00,0x18,0x00,0xe8,0xff,0xdb,0xff,0x7c,0x00,0x17,0x00,0x33,0x00,0xfc,0xff,0xfb,0xff,0xf4,0xff,0xf2,0xff,0xe5,0xff,0x06,0x00,0xec,0xff,0xc0,0xff,0xf9,0xff,0x0d,0x00,0x25,0x00,0x07,0x00,0x19,0x00,0x39,0x00,0xe8,0xff,0x99,0xff,0xd1,0xff,0xe9,0xff,0xcb,0xff,0xd1,0xff,0xdc,0xff,0x20,0x00,0x1a,0x00,0x1d,0x00,0xda,0xff,0xdb,0xff,0x15,0x00,0xfb,0xff,0x27,0x00,0xc6,0xff,0x23,0x00,0xfe,0xff,0x19,0x00,0xfb,0xff,0xec,0xff,0xd7,0xff,0x14,0x00,0x11,0x00,0xde,0xff,0x19,0x00,0xe1,0xff,0x17,0x00,0xfa,0xff,0x2e,0x00,0xd0,0xff,0x12,0x00,0xf3,0xff,0x3e,0x00,0xda,0xff,0xff,0xff,0xcd,0xff,0xdd,0xff,0xe0,0xff,0xf7,0xff,0xfe,0xff,0x40,0x00,0xcb,0xff,0x0c,0x00,0x20,0x00,0x0e,0x00,0xc7,0xff,0x0f,0x00,0xbf,0xff,0xdb,0xff,0xe7,0xff,0x0a,0x00,0xfd,0xff,0xf6,0xff,0xd8,0xff,0x08,0x00,0xe1,0xff,0xe9,0xff,0xdf,0xff,0xe0,0xff,0x14,0x00,0x15,0x00,0xe9,0xff,0x24,0x00,0x23,0x00,0xfb,0xff,0x28,0x00,0xec,0xff,0x09,0x00,0x25,0x00,0x25,0x00,0x09,0x00,0x28,0x00,0xf2,0xff,0x11,0x00,0x3f,0x00,0x05,0x00,0x24,0x00,0xf6,0xff,0xb9,0xff,0x90,0xff,0xfe,0xff,0xeb,0xff,0xf0,0xff,0xe6,0xff,0x28,0x00,0x49,0x00,0xbf,0xff,0xe8,0xff,0xd3,0xff,0xff,0xff,0xb1,0xff,0xe4,0xff,0x17,0x00,0xdc,0xff,0xce,0xff,0xe8,0xff,0x32,0x00,0xe7,0xff,0x15,0x00,0xe7,0xff,0x29,0x00,0xdd,0xff,0x12,0x00,0xcd,0xff,0xf5,0xff,0x19,0x00,0x25,0x00,0x17,0x00,0x26,0x00,0x3e,0x00,0x09,0x00,0x08,0x00,0xec,0xff,0x22,0x00,0xfb,0xff,0xf5,0xff,0xea,0xff,0x03,0x00,0xfe,0xff,0x0e,0x00,0xaf,0xff,0xc5,0xff,0xf0,0xff,0xeb,0xff,0x0c,0x00,0x12,0x00,0xeb,0xff,0x17,0x00,0xd1,0xff,0x02,0x00,0x33,0x00,0xcf,0xff,0x71,0x00,0xec,0xff,0xe8,0xff,0xa7,0xff,0x1e,0x00,0x11,0x00,0xde,0xff,0xda,0xff,0x27,0x00,0x05,0x00,0xc2,0xff,0x2d,0x00,0x1d,0x00,0xd9,0xff,0xe0,0xff,0xeb,0xff,0xfe,0xff,0x2d,0x00,0x2e,0x00,0xfc,0xff,0x0c,0x00,0xeb,0xff,0x98,0xff,0x06,0x00,0xae,0xff,0x12,0x00,0x56,0x00,0x21,0x00,0xe3,0xff,0xfc,0xff,0xf8,0xff,0x15,0x00,0xf7,0xff,0xe6,0xff,0x29,0x00,0x10,0x00,0xf2,0xff,0x13,0x00,0xe4,0xff,0x5f,0x00,0xdf,0xff,0x0a,0x00,0x06,0x00,0x36,0x00,0x06,0x00,0xf6,0xff,0x02,0x00,0x01,0x00,0xec,0xff,0x13,0x00,0xca,0xff,0x13,0x00,0xc3,0xff,0x43,0x00,0xc2,0xff,0xfd,0xff,0xf4,0xff,0xd4,0xff,0xc4,0xff,0x15,0x00,0x37,0x00,0xf9,0xff,0x17,0x00,0xf4,0xff,0x09,0x00,0x45,0x00,0x55,0x00,0x1c,0x00,0xfb,0xff,0xf8,0xff,0xde,0xff,0xf9,0xff,0x50,0x00,0xe5,0xff,0xf7,0xff,0xdd,0xff,0x3d,0x00,0x10,0x00,0x0a,0x00,0x1b,0x00,0xfa,0xff,0xc1,0xff,0xfa,0xff,0x10,0x00,0x1a,0x00,0x33,0x00,0x2b,0x00,0x04,0x00,0x3a,0x00,0x24,0x00,0x3d,0x00,0x48,0x00,0x52,0x00,0x05,0x00,0xc8,0xff,0xad,0xff,0xf2,0xff,0x46,0x00,0x22,0x00,0xed,0xff,0xc9,0xff,0x07,0x00,0xe4,0xff,0xd2,0xff,0x14,0x00,0x34,0x00,0xd2,0xff,0x1f,0x00,0xf5,0xff,0xcc,0xff,0x0c,0x00,0x2d,0x00,0xf4,0xff,0x3e,0x00,0x39,0x00,0x0b,0x00,0xf7,0xff,0xe5,0xff,0x2f,0x00,0xf6,0xff,0x54,0x00,0x09,0x00,0xc4,0xff,0xfa,0xff,0xe9,0xff,0x18,0x00,0x8a,0xff,0x10,0x00,0xfb,0xff,0xba,0xff,0xe6,0xff,0xec,0xff,0x30,0x00,0xea,0xff,0xfe,0xff,0x20,0x00,0xf9,0xff,0x19,0x00,0xdf,0xff,0x0d,0x00,0x46,0x00,0x02,0x00,0x0d,0x00,0xc1,0xff,0x96,0xff,0xcf,0xff,0x22,0x00,0x4a,0x00,0x07,0x00,0xdb,0xff,0xeb,0xff,0xcc,0xff,0x41,0x00,0x0b,0x00,0x1e,0x00,0xdc,0xff,0x11,0x00,0x01,0x00,0x34,0x00,0x07,0x00,0x10,0x00,0xd3,0xff,0xd9,0xff,0x39,0x00,0x00,0x00,0xfc,0xff,0xe9,0xff,0x63,0x00,0xd9,0xff,0xfa,0xff,0xcf,0xff,0x02,0x00,0x12,0x00,0xc7,0xff,0xee,0xff,0x15,0x00,0x45,0x00,0x1c,0x00,0xc1,0xff,0xf5,0xff,0x48,0x00,0x1b,0x00,0x0c,0x00,0xa4,0xff,0xe2,0xff,0xff,0xff,0x0b,0x00,0x13,0x00,0xeb,0xff,0x28,0x00,0xc3,0xff,0x1b,0x00,0x53,0x00,0x0b,0x00,0x6b,0x00,0xee,0xff,0x11,0x00,0x31,0x00,0x10,0x00,0xf8,0xff,0x08,0x00,0x06,0x00,0x43,0x00,0xfd,0xff,0xb6,0xff,0xe3,0xff,0xe6,0xff,0xf3,0xff,0x04,0x00,0x23,0x00,0xde,0xff,0x4f,0x00,0x02,0x00,0x23,0x00,0x21,0x00,0x19,0x00,0x22,0x00,0x29,0x00,0x29,0x00,0xae,0xff,0xfe,0xff,0x37,0x00,0xdc,0xff,0x09,0x00,0xf7,0xff,0x1b,0x00,0xee,0xff,0xb8,0xff,0xc8,0xff,0x0e,0x00,0x0c,0x00,0xea,0xff,0x1e,0x00,0xf7,0xff,0xfc,0xff,0xe1,0xff,0x19,0x00,0xd3,0xff,0x41,0x00,0x0f,0x00,0xc1,0xff,0x05,0x00,0xd3,0xff,0x16,0x00,0xe4,0xff,0x2c,0x00,0xf1,0xff,0xad,0xff,0x02,0x00,0xd8,0xff,0xfe,0xff,0x54,0x00,0x24,0x00,0x1e,0x00,0x1b,0x00,0xff,0xff,0x0e,0x00,0xf5,0xff,0xf7,0xff,0x3c,0x00,0x31,0x00,0x1b,0x00,0x0a,0x00,0x2a,0x00,0xfb,0xff,0x0a,0x00,0xf6,0xff,0x07,0x00,0xa5,0xff,0x5e,0x00,0xee,0xff,0xec,0xff,0xe6,0xff,0xd2,0xff,0x03,0x00,0xcd,0xff,0x0f,0x00,0xd3,0xff,0xde,0xff,0xc5,0xff,0x24,0x00,0x20,0x00,0xfd,0xff,0x0b,0x00,0x00,0x00,0x27,0x00,0x21,0x00,0x24,0x00,0xbe,0xff,0xe4,0xff,0xdc,0xff,0xcf,0xff,0x2f,0x00,0x33,0x00,0xd2,0xff,0xf6,0xff,0x24,0x00,0x23,0x00,0xf1,0xff,0xf9,0xff,0xc5,0xff,0x49,0x00,0x25,0x00,0x31,0x00,0xd7,0xff,0xf7,0xff,0x0b,0x00,0x0c,0x00,0xe0,0xff,0xdf,0xff,0x00,0x00,0x42,0x00,0x18,0x00,0x07,0x00,0xf7,0xff,0xed,0xff,0x12,0x00,0xd1,0xff,0x01,0x00,0xc0,0xff,0x4c,0x00,0x2c,0x00,0x3e,0x00,0xdc,0xff,0xb6,0xff,0x08,0x00,0xf4,0xff,0x22,0x00,0xfd,0xff,0x1e,0x00,0x19,0x00,0xef,0xff,0xe9,0xff,0x23,0x00,0x3d,0x00,0xea,0xff,0xfa,0xff,0xfa,0xff,0xab,0xff,0x0d,0x00,0x00,0x00,0xde,0xff,0xbe,0xff,0x30,0x00,0xe6,0xff,0xfa,0xff,0x66,0x00,0x3c,0x00,0x19,0x00,0xeb,0xff,0x0f,0x00,0x40,0x00,0xe1,0xff,0x0d,0x00,0xeb,0xff,0xf7,0xff,0xed,0xff,0x26,0x00,0xf7,0xff,0x2b,0x00,0xd1,0xff,0xf5,0xff,0x02,0x00,0xd7,0xff,0x3b,0x00,0xe2,0xff,0xcc,0xff,0x01,0x00,0xd1,0xff,0xf1,0xff,0x22,0x00,0x19,0x00,0x51,0x00,0x09,0x00,0x42,0x00,0x27,0x00,0x36,0x00,0xdc,0xff,0x3d,0x00,0x1e,0x00,0xd4,0xff,0xe4,0xff,0x09,0x00,0x0b,0x00,0x1c,0x00,0x0e,0x00,0x0e,0x00,0x0d,0x00,0xe0,0xff,0xf7,0xff,0xdd,0xff,0x36,0x00,0x42,0x00,0x11,0x00,0xd2,0xff,0x06,0x00,0x03,0x00,0x28,0x00,0xea,0xff,0xe5,0xff,0x57,0x00,0x14,0x00,0x55,0x00,0x2f,0x00,0xd4,0xff,0xf7,0xff,0xb2,0xff,0xce,0xff,0xdf,0xff,0x13,0x00,0x06,0x00,0xfc,0xff,0xfe,0xff,0xe3,0xff,0xe0,0xff,0x20,0x00,0xcf,0xff,0xf8,0xff,0xc3,0xff,0x0e,0x00,0x0a,0x00,0x3d,0x00,0x0c,0x00,0x0f,0x00,0xfc,0xff,0x48,0x00,0xfc,0xff,0xe4,0xff,0xbd,0xff,0xac,0xff,0x26,0x00,0x16,0x00,0xf8,0xff,0x03,0x00,0x3b,0x00,0xd5,0xff,0xf5,0xff,0x01,0x00,0x19,0x00,0x18,0x00,0x00,0x00,0xbd,0xff,0xc1,0xff,0xd8,0xff,0xd5,0xff,0x18,0x00,0x1a,0x00,0xee,0xff,0xd6,0xff,0xfe,0xff,0xff,0xff,0xea,0xff,0x41,0x00,0x22,0x00,0x15,0x00,0xcb,0xff,0x43,0x00,0xf6,0xff,0xf5,0xff,0x0b,0x00,0xbf,0xff,0xe5,0xff,0xe6,0xff,0xc5,0xff,0x45,0x00,0xf6,0xff,0xe0,0xff,0x2e,0x00,0xd5,0xff,0x35,0x00,0x53,0x00,0xef,0xff,0xff,0xff,0x27,0x00,0x27,0x00,0xeb,0xff,0xd3,0xff,0x21,0x00,0xcb,0xff,0xe1,0xff,0x5a,0x00,0x14,0x00,0x05,0x00,0xe8,0xff,0x04,0x00,0x50,0x00,0xfb,0xff,0x28,0x00,0x43,0x00,0x9a,0xff,0xec,0xff,0x68,0x00,0xe2,0xff,0x13,0x00,0xe1,0xff,0xf8,0xff,0x48,0x00,0x38,0x00,0xd2,0xff,0xc6,0xff,0x44,0x00,0x32,0x00,0xde,0xff,0x21,0x00,0x08,0x00,0x1d,0x00,0xc8,0xff,0x1e,0x00,0x38,0x00,0x0f,0x00,0x16,0x00,0xf3,0xff,0x09,0x00,0x10,0x00,0xc5,0xff,0x20,0x00,0xf3,0xff,0xe8,0xff,0x28,0x00,0xf8,0xff,0xe5,0xff,0xff,0xff,0x34,0x00,0xd2,0xff,0xed,0xff,0x0d,0x00,0x03,0x00,0x26,0x00,0xac,0xff,0x14,0x00,0x4a,0x00,0xd6,0xff,0x29,0x00,0xf0,0xff,0x02,0x00,0x18,0x00,0x39,0x00,0xde,0xff,0x02,0x00,0x14,0x00,0xff,0xff,0xcb,0xff,0xc4,0xff,0x2b,0x00,0xeb,0xff,0x18,0x00,0x33,0x00,0x4e,0x00,0xd3,0xff,0xb6,0xff,0xbd,0xff,0xdd,0xff,0xed,0xff,0x2b,0x00,0xf2,0xff,0xf2,0xff,0xf4,0xff,0x13,0x00,0x19,0x00,0xf0,0xff,0xfc,0xff,0x25,0x00,0x11,0x00,0x1b,0x00,0x16,0x00,0xe1,0xff,0xdb,0xff,0xad,0xff,0xfb,0xff,0xe9,0xff,0xfa,0xff,0xfe,0xff,0x23,0x00,0xf4,0xff,0xf6,0xff,0x08,0x00,0x40,0x00,0x1c,0x00,0xcd,0xff,0xef,0xff,0x20,0x00,0x0b,0x00,0xef,0xff,0xf6,0xff,0x0f,0x00,0x04,0x00,0xc6,0xff,0xe8,0xff,0xcb,0xff,0x21,0x00,0xc9,0xff,0xc9,0xff,0x30,0x00,0x18,0x00,0xd3,0xff,0x6e,0x00,0x12,0x00,0x36,0x00,0x10,0x00,0x36,0x00,0xe8,0xff,0xea,0xff,0xe6,0xff,0x1b,0x00,0xf7,0xff,0xc9,0xff,0x39,0x00,0x3c,0x00,0xde,0xff,0x13,0x00,0x10,0x00,0xb6,0xff,0xfb,0xff,0xf2,0xff,0x18,0x00,0xc3,0xff,0xb4,0xff,0xe7,0xff,0xfe,0xff,0xf2,0xff,0xd5,0xff,0xe8,0xff,0x03,0x00,0xda,0xff,0xd0,0xff,0x21,0x00,0xe7,0xff,0x19,0x00,0xc4,0xff,0xf7,0xff,0x0c,0x00,0xf2,0xff,0x0a,0x00,0xf2,0xff,0x07,0x00,0x20,0x00,0xba,0xff,0xf7,0xff,0x48,0x00,0xba,0xff,0xc7,0xff,0xf5,0xff,0x3f,0x00,0x06,0x00,0x49,0x00,0xe2,0xff,0x2a,0x00,0xc0,0xff,0x02,0x00,0x01,0x00,0xf5,0xff,0xef,0xff,0xf6,0xff,0x19,0x00,0x0c,0x00,0x31,0x00,0xe0,0xff,0x7f,0x00,0x38,0x00,0x24,0x00,0xca,0xff,0xff,0xff,0x32,0x00,0x11,0x00,0xed,0xff,0x00,0x00,0xf8,0xff,0x44,0x00,0x24,0x00,0x02,0x00,0xd5,0xff,0xd6,0xff,0xf7,0xff,0x04,0x00,0x2d,0x00,0xc4,0xff,0x03,0x00,0xcd,0xff,0xff,0xff,0xe6,0xff,0x56,0x00,0xf4,0xff,0x4a,0x00,0xd7,0xff,0xe2,0xff,0xec,0xff,0xfb,0xff,0x13,0x00,0xe7,0xff,0x21,0x00,0x16,0x00,0xeb,0xff,0xd1,0xff,0x02,0x00,0xd3,0xff,0x4d,0x00,0x15,0x00,0xf3,0xff,0xde,0xff,0xfe,0xff,0x22,0x00,0xc1,0xff,0x16,0x00,0xf2,0xff,0xbc,0xff,0xe1,0xff,0xb0,0xff,0xfb,0xff,0xe4,0xff,0xf4,0xff,0x2d,0x00,0xde,0xff,0xff,0xff,0xde,0xff,0x18,0x00,0x13,0x00,0xdb,0xff,0xee,0xff,0xc5,0xff,0xed,0xff,0x0d,0x00,0xdb,0xff,0xcf,0xff,0x0a,0x00,0xec,0xff,0x2b,0x00,0xba,0xff,0x20,0x00,0x2d,0x00,0x09,0x00,0x08,0x00,0xde,0xff,0xc5,0xff,0xea,0xff,0x13,0x00,0xee,0xff,0xe1,0xff,0x24,0x00,0xf8,0xff,0xee,0xff,0xf6,0xff,0xfb,0xff,0x0d,0x00,0xe0,0xff,0x12,0x00,0x06,0x00,0xce,0xff,0x4a,0x00,0x05,0x00,0xff,0xff,0xeb,0xff,0x23,0x00,0xf4,0xff,0x26,0x00,0x80,0xff,0x13,0x00,0x4c,0x00,0x0e,0x00,0x33,0x00,0xb8,0xff,0xc9,0xff,0xb5,0xff,0x03,0x00,0xf6,0xff,0x19,0x00,0xbc,0xff,0x4f,0x00,0xca,0xff,0xd6,0xff,0x19,0x00,0xf7,0xff,0x1e,0x00,0x11,0x00,0xc3,0xff,0xc1,0xff,0xdf,0xff,0x44,0x00,0xfd,0xff,0x0f,0x00,0x24,0x00,0xfe,0xff,0xcc,0xff,0xfc,0xff,0xd2,0xff,0xf9,0xff,0xc8,0xff,0xe0,0xff,0xe8,0xff,0x0a,0x00,0xf5,0xff,0x04,0x00,0xf7,0xff,0xfc,0xff,0x4c,0x00,0xda,0xff,0xcb,0xff,0xca,0xff,0xed,0xff,0x1b,0x00,0x50,0x00,0x19,0x00,0xc0,0xff,0x2f,0x00,0xfa,0xff,0xec,0xff,0xd9,0xff,0x0f,0x00,0xfe,0xff,0x34,0x00,0x41,0x00,0x94,0xff,0x2a,0x00,0xfc,0xff,0x15,0x00,0x23,0x00,0xfb,0xff,0xc9,0xff,0xe0,0xff,0xcb,0xff,0x02,0x00,0xed,0xff,0xed,0xff,0x0d,0x00,0x2d,0x00,0x1b,0x00,0x53,0x00,0xf7,0xff,0xf7,0xff,0x16,0x00,0x2f,0x00,0x4e,0x00,0xd0,0xff,0x0e,0x00,0x2f,0x00,0xc3,0xff,0x06,0x00,0x12,0x00,0x09,0x00,0xcf,0xff,0xe4,0xff,0xdf,0xff,0xfc,0xff,0x0a,0x00,0x08,0x00,0x00,0x00,0xf2,0xff,0x16,0x00,0xd5,0xff,0x33,0x00,0x29,0x00,0xf2,0xff,0xca,0xff,0xac,0xff,0x40,0x00,0x9e,0xff,0x3c,0x00,0xeb,0xff,0xbc,0xff,0xee,0xff,0xad,0xff,0xd2,0xff,0x25,0x00,0xfd,0xff,0x1f,0x00,0xd3,0xff,0x0f,0x00,0x17,0x00,0x6e,0x00,0x33,0x00,0xe0,0xff,0xd9,0xff,0xdf,0xff,0xfc,0xff,0xf8,0xff,0x06,0x00,0xc8,0xff,0xb1,0xff,0xde,0xff,0xd5,0xff,0x06,0x00,0xf4,0xff,0xc2,0xff,0x48,0x00,0xcb,0xff,0x2b,0x00,0x19,0x00,0x25,0x00,0xeb,0xff,0xb7,0xff,0x0b,0x00,0xae,0xff,0x0b,0x00,0xd6,0xff,0x2c,0x00,0x0b,0x00,0x2c,0x00,0x27,0x00,0x38,0x00,0x3a,0x00,0xca,0xff,0xf7,0xff,0x03,0x00,0xef,0xff,0x1a,0x00,0x53,0x00,0x24,0x00,0xcf,0xff,0xd3,0xff,0x26,0x00,0xfc,0xff,0x38,0x00,0xd7,0xff,0xc2,0xff,0xc5,0xff,0xe4,0xff,0xe0,0xff,0x09,0x00,0x02,0x00,0xfc,0xff,0x2b,0x00,0xec,0xff,0xf9,0xff,0x1a,0x00,0x1e,0x00,0x01,0x00,0xfb,0xff,0x01,0x00,0x0d,0x00,0x00,0x00,0x0c,0x00,0xfb,0xff,0x08,0x00,0x08,0x00,0xf0,0xff,0xd7,0xff,0xfb,0xff,0xf8,0xff,0xf5,0xff,0x0d,0x00,0xf3,0xff,0xed,0xff,0xdb,0xff,0x0e,0x00,0x0a,0x00,0x10,0x00,0xf0,0xff,0x00,0x00,0xcb,0xff,0x04,0x00,0xf5,0xff,0x27,0x00,0xf4,0xff,0xe4,0xff,0xff,0xff,0xe1,0xff,0xf6,0xff,0x06,0x00,0xfe,0xff,0xf6,0xff,0x07,0x00,0x02,0x00,0x0e,0x00,0x26,0x00,0x06,0x00,0xf7,0xff,0xf0,0xff,0xf6,0xff,0xf9,0xff,0x01,0x00,0x02,0x00,0xf4,0xff,0x13,0x00,0x12,0x00,0x03,0x00,0x10,0x00,0xe9,0xff,0xf2,0xff,0xfa,0xff,0xf8,0xff,0x07,0x00,0x1e,0x00,0x07,0x00,0xf6,0xff,0x08,0x00,0x00,0x00,0xf7,0xff,0x08,0x00,0xfd,0xff,0x04,0x00,0xf7,0xff,0x08,0x00,0x05,0x00,0xf0,0xff,0xf7,0xff,0xfb,0xff,0xfe,0xff,0x03,0x00,0x0d,0x00,0x05,0x00,0xf6,0xff,0xda,0xff,0x04,0x00,0x11,0x00,0xf1,0xff,0xec,0xff,0xf6,0xff,0x2a,0x00,0xfe,0xff,0x05,0x00,0xf5,0xff,0x0e,0x00,0xe7,0xff,0x12,0x00,0x06,0x00,0x24,0x00,0xde,0xff,0xe4,0xff,0xfe,0xff,0xf1,0xff,0xf9,0xff,0xf1,0xff,0x01,0x00,0x03,0x00,0xff,0xff,0x24,0x00,0x16,0x00,0xf9,0xff,0xdd,0xff,0x02,0x00,0xfd,0xff,0xf3,0xff,0x06,0x00,0x0a,0x00,0x18,0x00,0xfd,0xff,0x0d,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0xf4,0xff,0x00,0x00,0xf8,0xff,0xf8,0xff,0xf0,0xff,0x08,0x00,0x09,0x00,0x10,0x00,0x0e,0x00,0x07,0x00,0x07,0x00,0xe3,0xff,0xea,0xff,0x2b,0x00,0x12,0x00,0x03,0x00,0x03,0x00,0xf9,0xff,0xff,0xff,0x05,0x00,0xf4,0xff,0x1c,0x00,0xf9,0xff,0xda,0xff,0xf6,0xff,0xb0,0xff,0x07,0x00,0x17,0x00,0xf8,0xff,0xf3,0xff,0xea,0xff,0x20,0x00,0x03,0x00,0x0f,0x00,0x07,0x00,0x0d,0x00,0xf1,0xff,0x05,0x00,0x14,0x00,0x11,0x00,0xe3,0xff,0x07,0x00,0x06,0x00,0xfa,0xff,0xf0,0xff,0xf7,0xff,0x07,0x00,0x0e,0x00,0xf8,0xff,0x03,0x00,0x11,0x00,0x10,0x00,0xd5,0xff,0xf8,0xff,0x0e,0x00,0xfa,0xff,0x09,0x00,0xe7,0xff,0x17,0x00,0xd6,0xff,0xec,0xff,0xf3,0xff,0xfe,0xff,0x16,0x00,0xff,0xff,0xfb,0xff,0x07,0x00,0xee,0xff,0xf7,0xff,0xef,0xff,0x04,0x00,0x0a,0x00,0x25,0x00,0x2b,0x00,0x09,0x00,0x18,0x00,0x0a,0x00,0x26,0x00,0xf0,0xff,0x03,0x00,0x02,0x00,0x0b,0x00,0x03,0x00,0x1a,0x00,0xfd,0xff,0x00,0x00,0x1b,0x00,0xea,0xff,0xf8,0xff,0xe7,0xff,0xe9,0xff,0x0e,0x00,0x09,0x00,0x05,0x00,0xe5,0xff,0x25,0x00,0x0f,0x00,0x10,0x00,0x03,0x00,0x03,0x00,0xe1,0xff,0x16,0x00,0x28,0x00,0x23,0x00,0xf0,0xff,0xfd,0xff,0x0e,0x00,0x03,0x00,0xed,0xff,0xf9,0xff,0x07,0x00,0x09,0x00,0x04,0x00,0x30,0x00,0x00,0x00,0x0b,0x00,0xd6,0xff,0xf9,0xff,0x0c,0x00,0x06,0x00,0xfc,0xff,0x02,0x00,0x1a,0x00,0xdc,0xff,0x05,0x00,0xe7,0xff,0xf4,0xff,0x02,0x00,0xea,0xff,0x05,0x00,0xff,0xff,0x01,0x00,0x11,0x00,0xed,0xff,0x0e,0x00,0x04,0x00,0x0d,0x00,0x0f,0x00,0x02,0x00,0x23,0x00,0xf1,0xff,0x2a,0x00,0x07,0x00,0x0c,0x00,0xfe,0xff,0x0c,0x00,0x08,0x00,0x10,0x00,0x02,0x00,0x01,0x00,0x17,0x00,0xe4,0xff,0xf7,0xff,0x01,0x00,0xe4,0xff,0x0d,0x00,0xfb,0xff,0x1c,0x00,0xfd,0xff,0x1d,0x00,0x03,0x00,0x01,0x00,0x05,0x00,0x08,0x00,0xee,0xff,0x1a,0x00,0x37,0x00,0xe3,0xff,0xf3,0xff,0x2b,0x00,0x07,0x00,0x16,0x00,0xea,0xff,0x13,0x00,0x03,0x00,0xfe,0xff,0x04,0x00,0x1a,0x00,0x12,0x00,0xf0,0xff,0xf3,0xff,0xef,0xff,0xf7,0xff,0x01,0x00,0x03,0x00,0xf1,0xff,0x16,0x00,0xdc,0xff,0xca,0xff,0xd6,0xff,0xed,0xff,0x0e,0x00,0xec,0xff,0xf0,0xff,0xf9,0xff,0x09,0x00,0x06,0x00,0xea,0xff,0x11,0x00,0xee,0xff,0xe9,0xff,0x2c,0x00,0x02,0x00,0xdb,0xff,0xd1,0xff,0x0b,0x00,0xf0,0xff,0x07,0x00,0x00,0x00,0x12,0x00,0x0b,0x00,0x2a,0x00,0xf7,0xff,0x13,0x00,0x1f,0x00,0xf9,0xff,0xfa,0xff,0x11,0x00,0xf8,0xff,0xf8,0xff,0x00,0x00,0x1d,0x00,0xd7,0xff,0x1d,0x00,0x06,0x00,0xfa,0xff,0xf5,0xff,0xf3,0xff,0xef,0xff,0x18,0x00,0x1b,0x00,0xd8,0xff,0x0d,0x00,0x17,0x00,0xff,0xff,0xfe,0xff,0xea,0xff,0x2a,0x00,0x11,0x00,0xdc,0xff,0x18,0x00,0x1d,0x00,0x22,0x00,0x16,0x00,0xe4,0xff,0xfd,0xff,0x2f,0x00,0x01,0x00,0x00,0x00,0x0a,0x00,0xef,0xff,0xe7,0xff,0xd8,0xff,0xe2,0xff,0xed,0xff,0x02,0x00,0xf7,0xff,0xfe,0xff,0xee,0xff,0x08,0x00,0x16,0x00,0xf4,0xff,0x11,0x00,0xe1,0xff,0xfd,0xff,0x34,0x00,0xe1,0xff,0x12,0x00,0xae,0xff,0x14,0x00,0xb0,0xff,0x99,0xff,0xad,0xff,0x59,0x00,0x50,0x00,0x3b,0x00,0x03,0x00,0x08,0x00,0x40,0x00,0xcc,0xff,0xb0,0xff,0x17,0x00,0x9f,0xff,0x7f,0x00,0xf2,0xff,0x15,0x00,0xbd,0xff,0xdd,0xff,0x4f,0x00,0x53,0x00,0xc5,0xff,0x41,0x00,0xe8,0xff,0x38,0x00,0xd8,0xff,0xbc,0xff,0x66,0x00,0x15,0x00,0x55,0x00,0x07,0x00,0xaf,0xff,0x4a,0x00,0x2c,0x00,0xa8,0xff,0x57,0x00,0x3c,0x00,0xfb,0xff,0x30,0x00,0x3b,0x00,0xca,0xff,0x35,0x00,0xb1,0xff,0x39,0x00,0xbb,0xff,0xab,0xff,0x19,0x00,0xe4,0xff,0xf9,0xff,0xb1,0xff,0x3b,0x00,0xd7,0xff,0xed,0xff,0xb0,0xff,0xc4,0xff,0x51,0x00,0xe5,0xff,0xed,0xff,0xf8,0xff,0xc4,0xff,0xf1,0xff,0x13,0x00,0x1e,0x00,0x2f,0x00,0x1e,0x00,0x0f,0x00,0x03,0x00,0xe3,0xff,0xda,0xff,0x22,0x00,0xd8,0xff,0xc2,0xff,0x31,0x00,0x27,0x00,0x07,0x00,0x1a,0x00,0xff,0xff,0xe0,0xff,0xfb,0xff,0x21,0x00,0x03,0x00,0x39,0x00,0x06,0x00,0xd9,0xff,0xf6,0xff,0x17,0x00,0xeb,0xff,0xe9,0xff,0x30,0x00,0x24,0x00,0x3e,0x00,0xfe,0xff,0xc0,0xff,0x2e,0x00,0xf0,0xff,0x1a,0x00,0xe2,0xff,0x20,0x00,0xd8,0xff,0x0d,0x00,0xa6,0xff,0x36,0x00,0x25,0x00,0x00,0x00,0xff,0xff,0x09,0x00,0x31,0x00,0xb6,0xff,0xe7,0xff,0x25,0x00,0xe0,0xff,0x1c,0x00,0xd2,0xff,0xff,0xff,0x38,0x00,0xf5,0xff,0x02,0x00,0xff,0xff,0xe4,0xff,0xf0,0xff,0xd1,0xff,0x0b,0x00,0xfd,0xff,0x04,0x00,0x27,0x00,0xce,0xff,0x22,0x00,0x41,0x00,0xd7,0xff,0xf8,0xff,0xf1,0xff,0xee,0xff,0xa6,0xff,0xdf,0xff,0xf2,0xff,0xf1,0xff,0xe9,0xff,0xca,0xff,0x4f,0x00,0x04,0x00,0x28,0x00,0xf4,0xff,0x4b,0x00,0x0b,0x00,0x5d,0x00,0xfe,0xff,0x0b,0x00,0xd6,0xff,0xf5,0xff,0x05,0x00,0x01,0x00,0x05,0x00,0x7b,0x00,0x15,0x00,0x1a,0x00,0xe0,0xff,0x33,0x00,0xd8,0xff,0xde,0xff,0x5d,0x00,0xd6,0xff,0x2c,0x00,0x1b,0x00,0x50,0x00,0xfb,0xff,0x23,0x00,0x16,0x00,0xbf,0xff,0x08,0x00,0xf9,0xff,0xf2,0xff,0x47,0x00,0xd2,0xff,0xe7,0xff,0xd2,0xff,0x1a,0x00,0x07,0x00,0x08,0x00,0x24,0x00,0x22,0x00,0xee,0xff,0xbb,0xff,0x07,0x00,0x23,0x00,0xc1,0xff,0x2a,0x00,0xc4,0xff,0xec,0xff,0x0b,0x00,0xf9,0xff,0x3e,0x00,0xe8,0xff,0x2a,0x00,0x50,0x00,0x1a,0x00,0xd3,0xff,0xe1,0xff,0xdb,0xff,0x04,0x00,0xe1,0xff,0xcd,0xff,0xaf,0xff,0x0b,0x00,0xc1,0xff,0x0c,0x00,0xef,0xff,0x1a,0x00,0x26,0x00,0x13,0x00,0xfa,0xff,0xe0,0xff,0x1a,0x00,0x02,0x00,0xe6,0xff,0xd8,0xff,0x26,0x00,0x24,0x00,0xe9,0xff,0x25,0x00,0x25,0x00,0x10,0x00,0x07,0x00,0x29,0x00,0xee,0xff,0xd8,0xff,0x33,0x00,0x21,0x00,0xc0,0xff,0x20,0x00,0xf6,0xff,0xcf,0xff,0x15,0x00,0xec,0xff,0xe6,0xff,0x46,0x00,0x07,0x00,0xd3,0xff,0xf0,0xff,0x14,0x00,0x18,0x00,0x55,0x00,0x2a,0x00,0xcb,0xff,0x15,0x00,0x2a,0x00,0xe9,0xff,0x2d,0x00,0xe2,0xff,0xfa,0xff,0xdf,0xff,0x05,0x00,0x1e,0x00,0xed,0xff,0x17,0x00,0xe0,0xff,0x44,0x00,0x10,0x00,0xe5,0xff,0x36,0x00,0x1c,0x00,0xc4,0xff,0xbc,0xff,0xf9,0xff,0xc1,0xff,0x2f,0x00,0x03,0x00,0xdb,0xff,0x06,0x00,0xcd,0xff,0x17,0x00,0x10,0x00,0x38,0x00,0x26,0x00,0x1b,0x00,0xe6,0xff,0x23,0x00,0xc6,0xff,0xff,0xff,0xf3,0xff,0xa6,0xff,0xf2,0xff,0x1f,0x00,0xdb,0xff,0xbd,0xff,0x1c,0x00,0x34,0x00,0xfd,0xff,0x1a,0x00,0xda,0xff,0x17,0x00,0xe7,0xff,0x0c,0x00,0x08,0x00,0xfe,0xff,0xff,0xff,0xcd,0xff,0xb0,0xff,0xff,0xff,0x08,0x00,0x0e,0x00,0x36,0x00,0x43,0x00,0xef,0xff,0xc3,0xff,0x0e,0x00,0xdc,0xff,0xe6,0xff,0xe4,0xff,0x57,0x00,0xcc,0xff,0xbf,0xff,0xd0,0xff,0x24,0x00,0xbb,0xff,0xd3,0xff,0xf0,0xff,0xdc,0xff,0x31,0x00,0x0d,0x00,0x38,0x00,0xfd,0xff,0x15,0x00,0x18,0x00,0x42,0x00,0xd5,0xff,0x09,0x00,0xe4,0xff,0xe2,0xff,0xff,0xff,0xfb,0xff,0x21,0x00,0x11,0x00,0xae,0xff,0x03,0x00,0x22,0x00,0x03,0x00,0x21,0x00,0x0a,0x00,0xd2,0xff,0xdf,0xff,0xb8,0xff,0x0c,0x00,0x47,0x00,0x07,0x00,0x02,0x00,0x2a,0x00,0xe8,0xff,0xd9,0xff,0xda,0xff,0x1b,0x00,0xe0,0xff,0x10,0x00,0xdf,0xff,0xee,0xff,0x29,0x00,0x30,0x00,0x0e,0x00,0xf9,0xff,0x11,0x00,0xe9,0xff,0x18,0x00,0xff,0xff,0x38,0x00,0x97,0xff,0x14,0x00,0xfa,0xff,0xbb,0xff,0xed,0xff,0x0a,0x00,0xad,0xff,0xf9,0xff,0xc7,0xff,0x0f,0x00,0xce,0xff,0xcc,0xff,0x14,0x00,0x36,0x00,0xcb,0xff,0xfa,0xff,0x27,0x00,0xe0,0xff,0x17,0x00,0xdd,0xff,0xff,0xff,0xde,0xff,0x35,0x00,0x20,0x00,0xe1,0xff,0xf5,0xff,0xd0,0xff,0x00,0x00,0x17,0x00,0x46,0x00,0x07,0x00,0xbd,0xff,0x18,0x00,0xdb,0xff,0x16,0x00,0x0a,0x00,0xc9,0xff,0xf7,0xff,0x22,0x00,0xd5,0xff,0xda,0xff,0xdd,0xff,0x19,0x00,0xf4,0xff,0x04,0x00,0x04,0x00,0x25,0x00,0xfe,0xff,0xfa,0xff,0x18,0x00,0x27,0x00,0x08,0x00,0xd9,0xff,0xd4,0xff,0xb6,0xff,0x32,0x00,0x12,0x00,0xee,0xff,0x20,0x00,0x19,0x00,0x11,0x00,0xae,0xff,0xda,0xff,0x34,0x00,0xf5,0xff,0xf6,0xff,0x13,0x00,0xe1,0xff,0x08,0x00,0x31,0x00,0x01,0x00,0xf7,0xff,0xd9,0xff,0xcb,0xff,0xfc,0xff,0x1a,0x00,0xf7,0xff,0xf0,0xff,0xbb,0xff,0x3b,0x00,0xd7,0xff,0xe3,0xff,0xfe,0xff,0x18,0x00,0x08,0x00,0xf9,0xff,0x0a,0x00,0x3d,0x00,0x17,0x00,0xff,0xff,0xe1,0xff,0xd1,0xff,0x20,0x00,0x11,0x00,0xfb,0xff,0xbb,0xff,0xde,0xff,0xd9,0xff,0xec,0xff,0xb4,0xff,0xd5,0xff,0xe4,0xff,0x15,0x00,0x05,0x00,0xe5,0xff,0x23,0x00,0xe1,0xff,0x34,0x00,0x3d,0x00,0x08,0x00,0xdf,0xff,0xe0,0xff,0xfa,0xff,0xce,0xff,0x3d,0x00,0x22,0x00,0x0b,0x00,0xfd,0xff,0x06,0x00,0xe3,0xff,0xfd,0xff,0x1e,0x00,0xc0,0xff,0xf4,0xff,0xc7,0xff,0xe3,0xff,0x05,0x00,0x1b,0x00,0xb2,0xff,0x03,0x00,0x29,0x00,0x27,0x00,0xdd,0xff,0xfb,0xff,0x26,0x00,0xf6,0xff,0xdc,0xff,0xfa,0xff,0x13,0x00,0x07,0x00,0xe9,0xff,0xfc,0xff,0xec,0xff,0x81,0xff,0x22,0x00,0x02,0x00,0x11,0x00,0x13,0x00,0x31,0x00,0xca,0xff,0xee,0xff,0x12,0x00,0x5e,0x00,0xef,0xff,0xe0,0xff,0xe7,0xff,0x1d,0x00,0x0d,0x00,0xe3,0xff,0x03,0x00,0x03,0x00,0xef,0xff,0x21,0x00,0x01,0x00,0x11,0x00,0x18,0x00,0xe0,0xff,0xd9,0xff,0x38,0x00,0xda,0xff,0xc4,0xff,0x0c,0x00,0xff,0xff,0x05,0x00,0x20,0x00,0x13,0x00,0xe1,0xff,0xfb,0xff,0x00,0x00,0xf8,0xff,0xf7,0xff,0xde,0xff,0x2e,0x00,0x10,0x00,0xee,0xff,0xee,0xff,0x0b,0x00,0x18,0x00,0xdc,0xff,0x35,0x00,0xe7,0xff,0x08,0x00,0xcb,0xff,0xf9,0xff,0x0f,0x00,0xcd,0xff,0x06,0x00,0x1d,0x00,0xf9,0xff,0x38,0x00,0xd1,0xff,0xe1,0xff,0x40,0x00,0x08,0x00,0x13,0x00,0xe5,0xff,0xd7,0xff,0x11,0x00,0xd4,0xff,0xe2,0xff,0xec,0xff,0x39,0x00,0xef,0xff,0xf4,0xff,0xfd,0xff,0xcb,0xff,0xe9,0xff,0xeb,0xff,0x0a,0x00,0xd4,0xff,0xea,0xff,0x10,0x00,0xe2,0xff,0xd6,0xff,0xf6,0xff,0x11,0x00,0x16,0x00,0xf4,0xff,0x1c,0x00,0xf9,0xff,0x07,0x00,0xe2,0xff,0xd2,0xff,0x05,0x00,0xe0,0xff,0xf5,0xff,0x32,0x00,0x2c,0x00,0xda,0xff,0xb7,0xff,0x20,0x00,0x2b,0x00,0x16,0x00,0x16,0x00,0x15,0x00,0x3d,0x00,0xa7,0xff,0x3a,0x00,0xf2,0xff,0xf8,0xff,0xf1,0xff,0x49,0x00,0x09,0x00,0xd8,0xff,0xf1,0xff,0xf2,0xff,0xe0,0xff,0x08,0x00,0xe5,0xff,0xff,0xff,0xc9,0xff,0xff,0xff,0x15,0x00,0x20,0x00,0xee,0xff,0x25,0x00,0xfe,0xff,0x31,0x00,0xe8,0xff,0xf8,0xff,0x29,0x00,0x1a,0x00,0x2b,0x00,0x28,0x00,0xb8,0xff,0xe2,0xff,0x00,0x00,0x3b,0x00,0xc0,0xff,0xe2,0xff,0xe9,0xff,0xea,0xff,0x15,0x00,0xf3,0xff,0x22,0x00,0xaa,0xff,0xe7,0xff,0x0f,0x00,0xfc,0xff,0xfa,0xff,0x11,0x00,0xd4,0xff,0x09,0x00,0x13,0x00,0x18,0x00,0xd8,0xff,0x5a,0x00,0xea,0xff,0xfd,0xff,0xd1,0xff,0x29,0x00,0x26,0x00,0x22,0x00,0x4d,0x00,0x00,0x00,0x14,0x00,0xeb,0xff,0xf0,0xff,0x26,0x00,0xd7,0xff,0xef,0xff,0xfe,0xff,0xf4,0xff,0xe8,0xff,0xfa,0xff,0x0a,0x00,0xd2,0xff,0x38,0x00,0x31,0x00,0x01,0x00,0x2b,0x00,0xea,0xff,0xc1,0xff,0x0a,0x00,0xd3,0xff,0x21,0x00,0xd7,0xff,0xf3,0xff,0x2b,0x00,0xfb,0xff,0x09,0x00,0xee,0xff,0x6e,0x00,0xf7,0xff,0x01,0x00,0xf5,0xff,0x0b,0x00,0xf8,0xff,0xb1,0xff,0x30,0x00,0x2b,0x00,0x26,0x00,0xcb,0xff,0x7a,0x00,0xdc,0xff,0x26,0x00,0xff,0xff,0x36,0x00,0xc1,0xff,0x0e,0x00,0x1f,0x00,0x16,0x00,0xdb,0xff,0x37,0x00,0xde,0xff,0xc0,0xff,0x1f,0x00,0xd8,0xff,0xef,0xff,0xed,0xff,0x11,0x00,0x12,0x00,0x4d,0x00,0xea,0xff,0xf4,0xff,0xd7,0xff,0xcb,0xff,0x22,0x00,0x37,0x00,0xeb,0xff,0xb1,0xff,0x09,0x00,0xfe,0xff,0x42,0x00,0xd3,0xff,0x30,0x00,0xe3,0xff,0xf3,0xff,0x05,0x00,0xdc,0xff,0x1c,0x00,0xdc,0xff,0x16,0x00,0x2d,0x00,0xdb,0xff,0x3e,0x00,0xce,0xff,0x28,0x00,0x24,0x00,0x37,0x00,0x3d,0x00,0xdb,0xff,0x0b,0x00,0xf1,0xff,0x17,0x00,0x37,0x00,0xd4,0xff,0xfb,0xff,0xfc,0xff,0xd2,0xff,0xcd,0xff,0xca,0xff,0xc0,0xff,0x1d,0x00,0xe6,0xff,0xc8,0xff,0xec,0xff,0x35,0x00,0x07,0x00,0x1e,0x00,0x2c,0x00,0x39,0x00,0xf3,0xff,0x4f,0x00,0x1d,0x00,0xd5,0xff,0x1d,0x00,0xbf,0xff,0xdd,0xff,0x1b,0x00,0x07,0x00,0xc1,0xff,0xef,0xff,0x5f,0x00,0xeb,0xff,0xd4,0xff,0xe6,0xff,0x0c,0x00,0xbd,0xff,0x28,0x00,0xf6,0xff,0xdb,0xff,0xeb,0xff,0xe9,0xff,0x44,0x00,0x50,0x00,0xe5,0xff,0x00,0x00,0xea,0xff,0xde,0xff,0x1c,0x00,0xcb,0xff,0xc5,0xff,0xde,0xff,0x0c,0x00,0x09,0x00,0x3d,0x00,0xff,0xff,0xf6,0xff,0xbb,0xff,0x27,0x00,0xfe,0xff,0x2f,0x00,0x18,0x00,0xf9,0xff,0xde,0xff,0xe4,0xff,0x94,0xff,0x0b,0x00,0x16,0x00,0x12,0x00,0xf2,0xff,0x0b,0x00,0x02,0x00,0xf6,0xff,0xf7,0xff,0xff,0xff,0xf0,0xff,0x07,0x00,0xe3,0xff,0xc7,0xff,0x3f,0x00,0xf8,0xff,0x16,0x00,0xf8,0xff,0x18,0x00,0x14,0x00,0x0a,0x00,0xe1,0xff,0x2d,0x00,0xc9,0xff,0x2a,0x00,0xbc,0xff,0xe8,0xff,0xd0,0xff,0xec,0xff,0xe0,0xff,0x0f,0x00,0xfc,0xff,0xe6,0xff,0x5e,0x00,0xda,0xff,0xda,0xff,0xef,0xff,0x89,0xff,0xd8,0xff,0x2c,0x00,0x1f,0x00,0xf0,0xff,0xde,0xff,0x10,0x00,0x29,0x00,0xff,0xff,0x00,0x00,0x2a,0x00,0x27,0x00,0x3a,0x00,0x06,0x00,0x37,0x00,0x23,0x00,0xc5,0xff,0x3a,0x00,0xd6,0xff,0x1f,0x00,0x20,0x00,0x31,0x00,0x24,0x00,0x0e,0x00,0x19,0x00,0x1d,0x00,0xff,0xff,0xf7,0xff,0x3f,0x00,0x0d,0x00,0x18,0x00,0x3e,0x00,0x3c,0x00,0xf4,0xff,0xd9,0xff,0xd8,0xff,0x38,0x00,0x2a,0x00,0xd4,0xff,0x24,0x00,0xf1,0xff,0x2d,0x00,0x0b,0x00,0x28,0x00,0xd2,0xff,0x37,0x00,0x2b,0x00,0xe9,0xff,0xef,0xff,0xe6,0xff,0xd4,0xff,0x0f,0x00,0xd0,0xff,0xef,0xff,0xd9,0xff,0x06,0x00,0xee,0xff,0xdc,0xff,0xc6,0xff,0xf8,0xff,0xe5,0xff,0xf8,0xff,0x1b,0x00,0xef,0xff,0xfb,0xff,0xdd,0xff,0x09,0x00,0x3a,0x00,0x1b,0x00,0x02,0x00,0xbd,0xff,0x18,0x00,0x09,0x00,0x2e,0x00,0x19,0x00,0xd5,0xff,0x1b,0x00,0x0e,0x00,0x3a,0x00,0xfa,0xff,0xe2,0xff,0xd6,0xff,0xe6,0xff,0xb9,0xff,0x17,0x00,0x28,0x00,0x2b,0x00,0xe6,0xff,0x0f,0x00,0xd1,0xff,0x1b,0x00,0xe3,0xff,0x27,0x00,0x14,0x00,0xc8,0xff,0x2a,0x00,0x10,0x00,0xfa,0xff,0x15,0x00,0x02,0x00,0x1d,0x00,0x2d,0x00,0x00,0x00,0x2b,0x00,0x5b,0x00,0x0d,0x00,0xc4,0xff,0x13,0x00,0xc6,0xff,0x1d,0x00,0x17,0x00,0xef,0xff,0xf6,0xff,0x01,0x00,0xd4,0xff,0x06,0x00,0xf2,0xff,0x0e,0x00,0xd1,0xff,0x0f,0x00,0x24,0x00,0x3b,0x00,0x12,0x00,0xc2,0xff,0xf7,0xff,0xdf,0xff,0x25,0x00,0x00,0x00,0xdf,0xff,0x38,0x00,0xe5,0xff,0xef,0xff,0xfe,0xff,0x1d,0x00,0xe0,0xff,0x05,0x00,0xd4,0xff,0x91,0xff,0x1b,0x00,0x10,0x00,0xee,0xff,0x66,0x00,0xfc,0xff,0x16,0x00,0x29,0x00,0x1b,0x00,0x06,0x00,0xbe,0xff,0x06,0x00,0xe1,0xff,0xf6,0xff,0x0d,0x00,0xe2,0xff,0xfd,0xff,0x1e,0x00,0xf1,0xff,0x08,0x00,0xe7,0xff,0xe7,0xff,0x10,0x00,0xf1,0xff,0x1e,0x00,0x01,0x00,0x25,0x00,0x11,0x00,0x2a,0x00,0x1b,0x00,0x2c,0x00,0xd6,0xff,0x08,0x00,0x26,0x00,0x0d,0x00,0x0d,0x00,0xc8,0xff,0xc5,0xff,0x12,0x00,0x20,0x00,0x31,0x00,0xf0,0xff,0xeb,0xff,0x2d,0x00,0x62,0x00,0xbb,0xff,0x16,0x00,0xdc,0xff,0xe4,0xff,0x10,0x00,0xfd,0xff,0xd8,0xff,0xf7,0xff,0x19,0x00,0x24,0x00,0x10,0x00,0xf5,0xff,0x0a,0x00,0xff,0xff,0x09,0x00,0x19,0x00,0x24,0x00,0x19,0x00,0x18,0x00,0x2a,0x00,0x41,0x00,0x33,0x00,0x34,0x00,0x18,0x00,0x1f,0x00,0xc7,0xff,0xf5,0xff,0xc5,0xff,0xe8,0xff,0xf1,0xff,0xf3,0xff,0xf5,0xff,0x31,0x00,0x3f,0x00,0xd6,0xff,0x02,0x00,0xdf,0xff,0x03,0x00,0xfd,0xff,0xcc,0xff,0xc4,0xff,0xc9,0xff,0x15,0x00,0x0f,0x00,0x4c,0x00,0xca,0xff,0x5c,0x00,0x19,0x00,0x17,0x00,0xdf,0xff,0x0b,0x00,0xda,0xff,0x09,0x00,0x30,0x00,0xb8,0xff,0x13,0x00,0xe8,0xff,0xee,0xff,0xec,0xff,0xbe,0xff,0xb0,0xff,0xca,0xff,0x0a,0x00,0xf4,0xff,0xe4,0xff,0x15,0x00,0xf8,0xff,0xae,0xff,0x07,0x00,0x25,0x00,0xec,0xff,0xe3,0xff,0xed,0xff,0xff,0xff,0xb2,0xff,0x0b,0x00,0x1f,0x00,0xf2,0xff,0xcc,0xff,0x3d,0x00,0x0e,0x00,0xf9,0xff,0xec,0xff,0xcd,0xff,0xd0,0xff,0x08,0x00,0xd8,0xff,0xee,0xff,0xa5,0xff,0x3d,0x00,0xe8,0xff,0xd9,0xff,0xf7,0xff,0xda,0xff,0x2c,0x00,0xf7,0xff,0xea,0xff,0x65,0x00,0xaf,0xff,0x2b,0x00,0x45,0x00,0xbe,0xff,0xe0,0xff,0xdc,0xff,0xc2,0xff,0x1b,0x00,0x32,0x00,0x11,0x00,0xe8,0xff,0x2d,0x00,0x22,0x00,0xf2,0xff,0x2b,0x00,0xfe,0xff,0xce,0xff,0xec,0xff,0xdb,0xff,0xe3,0xff,0xe4,0xff,0x19,0x00,0xb8,0xff,0x38,0x00,0x34,0x00,0x0a,0x00,0x52,0x00,0x4b,0x00,0x5e,0x00,0x20,0x00,0x2d,0x00,0x1d,0x00,0x5e,0x00,0xac,0xff,0xc6,0xff,0xe1,0xff,0xd5,0xff,0x01,0x00,0x28,0x00,0x2f,0x00,0x5d,0x00,0xe2,0xff,0x44,0x00,0x23,0x00,0xcc,0xff,0x30,0x00,0x53,0x00,0xbc,0xff,0x1c,0x00,0x21,0x00,0x0f,0x00,0xdf,0xff,0x1f,0x00,0xd9,0xff,0xf4,0xff,0x28,0x00,0xf8,0xff,0xf9,0xff,0x1a,0x00,0x2f,0x00,0xdf,0xff,0xd2,0xff,0x20,0x00,0x0e,0x00,0xb8,0xff,0x26,0x00,0xfd,0xff,0xd8,0xff,0xc7,0xff,0x06,0x00,0xc4,0xff,0x07,0x00,0xe0,0xff,0xb7,0xff,0xd4,0xff,0x27,0x00,0x12,0x00,0xec,0xff,0xc7,0xff,0x4f,0x00,0xff,0xff,0x2d,0x00,0xad,0xff,0x14,0x00,0x11,0x00,0x0d,0x00,0xe3,0xff,0xf0,0xff,0x20,0x00,0x4b,0x00,0xec,0xff,0xe9,0xff,0x1f,0x00,0xfa,0xff,0xe7,0xff,0x1c,0x00,0x01,0x00,0x13,0x00,0xf4,0xff,0x10,0x00,0xf2,0xff,0xc6,0xff,0x17,0x00,0x19,0x00,0x2f,0x00,0xfb,0xff,0x3e,0x00,0x10,0x00,0xda,0xff,0xe5,0xff,0x14,0x00,0xee,0xff,0x4f,0x00,0xe8,0xff,0xb8,0xff,0x34,0x00,0x15,0x00,0xbf,0xff,0xda,0xff,0x43,0x00,0x31,0x00,0x17,0x00,0x22,0x00,0x48,0x00,0x1d,0x00,0x11,0x00,0x22,0x00,0xe6,0xff,0xd8,0xff,0x11,0x00,0xdf,0xff,0x34,0x00,0x23,0x00,0x46,0x00,0xc2,0xff,0xec,0xff,0xe9,0xff,0xf6,0xff,0x04,0x00,0x04,0x00,0xf1,0xff,0x13,0x00,0xc2,0xff,0xff,0xff,0xc8,0xff,0x0f,0x00,0xea,0xff,0xe9,0xff,0xec,0xff,0xed,0xff,0xcd,0xff,0x01,0x00,0xca,0xff,0x4a,0x00,0xfd,0xff,0x0e,0x00,0x0f,0x00,0x10,0x00,0xd4,0xff,0x05,0x00,0xa6,0xff,0xd5,0xff,0xff,0xff,0xe7,0xff,0x0a,0x00,0xec,0xff,0xec,0xff,0x08,0x00,0xda,0xff,0xdc,0xff,0x3e,0x00,0x06,0x00,0x2b,0x00,0xf8,0xff,0xcd,0xff,0xfe,0xff,0x11,0x00,0x2e,0x00,0x09,0x00,0x04,0x00,0x7d,0x00,0xed,0xff,0xfd,0xff,0xca,0xff,0xec,0xff,0x30,0x00,0xc3,0xff,0xe0,0xff,0xec,0xff,0x35,0x00,0x4b,0x00,0xee,0xff,0x37,0x00,0xce,0xff,0xe2,0xff,0x14,0x00,0x04,0x00,0x0e,0x00,0xd1,0xff,0x06,0x00,0xee,0xff,0x1c,0x00,0xe4,0xff,0x22,0x00,0xe2,0xff,0xcc,0xff,0x45,0x00,0x2f,0x00,0xf9,0xff,0xee,0xff,0xfd,0xff,0x17,0x00,0xd8,0xff,0x36,0x00,0x07,0x00,0x13,0x00,0x40,0x00,0xd3,0xff,0x0e,0x00,0xf7,0xff,0x23,0x00,0x30,0x00,0xcc,0xff,0x1e,0x00,0xf2,0xff,0x14,0x00,0x52,0x00,0x13,0x00,0xda,0xff,0x25,0x00,0x70,0x00,0x55,0x00,0x0f,0x00,0xda,0xff,0x36,0x00,0x52,0x00,0xb4,0xff,0xf7,0xff,0x01,0x00,0x16,0x00,0xd9,0xff,0xf2,0xff,0xd4,0xff,0x80,0xff,0x1b,0x00,0x34,0x00,0x1b,0x00,0x48,0x00,0x1d,0x00,0xfc,0xff,0xce,0xff,0x37,0x00,0x18,0x00,0x35,0x00,0x1f,0x00,0x0e,0x00,0xf0,0xff,0xbe,0xff,0x0f,0x00,0xda,0xff,0x03,0x00,0x0d,0x00,0x1f,0x00,0x1f,0x00,0x22,0x00,0xda,0xff,0xfa,0xff,0x02,0x00,0x22,0x00,0x04,0x00,0xb1,0xff,0x05,0x00,0xdb,0xff,0x1b,0x00,0xf1,0xff,0x38,0x00,0xe7,0xff,0x34,0x00,0xf2,0xff,0x41,0x00,0xda,0xff,0xda,0xff,0x22,0x00,0x2e,0x00,0xef,0xff,0x15,0x00,0xf9,0xff,0xd7,0xff,0x2e,0x00,0xe2,0xff,0x01,0x00,0x34,0x00,0xe9,0xff,0x3f,0x00,0x1f,0x00,0xeb,0xff,0x5a,0x00,0x02,0x00,0xd3,0xff,0x37,0x00,0xf6,0xff,0x9d,0xff,0xe9,0xff,0xcc,0xff,0xe1,0xff,0xca,0xff,0xe2,0xff,0x06,0x00,0xcd,0xff,0x19,0x00,0x43,0x00,0x0a,0x00,0xeb,0xff,0xd3,0xff,0x09,0x00,0x25,0x00,0xce,0xff,0xf4,0xff,0x11,0x00,0x01,0x00,0xe0,0xff,0x0d,0x00,0xad,0xff,0xca,0xff,0x20,0x00,0xe2,0xff,0x1b,0x00,0x1f,0x00,0xf7,0xff,0x04,0x00,0xbb,0xff,0x26,0x00,0xdf,0xff,0x43,0x00,0x07,0x00,0xd6,0xff,0x02,0x00,0x24,0x00,0x1d,0x00,0x2c,0x00,0xb7,0xff,0xad,0xff,0xf3,0xff,0xf8,0xff,0xd7,0xff,0xd3,0xff,0xeb,0xff,0x15,0x00,0xf6,0xff,0xc0,0xff,0x30,0x00,0xea,0xff,0x1c,0x00,0xd7,0xff,0x59,0x00,0x29,0x00,0x0a,0x00,0xc5,0xff,0x2e,0x00,0xe5,0xff,0xa5,0xff,0x00,0x00,0x3a,0x00,0xfd,0xff,0xe3,0xff,0x1f,0x00,0x12,0x00,0xc7,0xff,0xe7,0xff,0xe3,0xff,0xed,0xff,0xd3,0xff,0x99,0xff,0x05,0x00,0xb9,0xff,0xd7,0xff,0xce,0xff,0x1a,0x00,0x4b,0x00,0x17,0x00,0x01,0x00,0x15,0x00,0xf0,0xff,0x3d,0x00,0xc7,0xff,0xe1,0xff,0xe6,0xff,0x37,0x00,0x22,0x00,0xce,0xff,0xf6,0xff,0x4b,0x00,0xc7,0xff,0x0a,0x00,0x0f,0x00,0xe1,0xff,0x1d,0x00,0xe3,0xff,0xf9,0xff,0x9e,0xff,0xb0,0xff,0xe9,0xff,0x97,0xff,0x31,0x00,0xfb,0xff,0xdd,0xff,0x21,0x00,0x0e,0x00,0x4b,0x00,0xe6,0xff,0x1d,0x00,0x5c,0x00,0xaa,0xff,0xca,0xff,0xb2,0xff,0xc5,0xff,0xc6,0xff,0xb0,0xff,0x27,0x00,0xd2,0xff,0xe8,0xff,0x28,0x00,0xc0,0xff,0xd4,0xff,0xe2,0xff,0xca,0xff,0xce,0xff,0x17,0x00,0x25,0x00,0x3b,0x00,0x08,0x00,0xdd,0xff,0x16,0x00,0xcf,0xff,0x19,0x00,0xc6,0xff,0x0e,0x00,0x62,0x00,0xd7,0xff,0xec,0xff,0xe3,0xff,0x46,0x00,0xd5,0xff,0x38,0x00,0xe2,0xff,0xe4,0xff,0x23,0x00,0x0f,0x00,0xe4,0xff,0x20,0x00,0xd9,0xff,0x31,0x00,0xf9,0xff,0xec,0xff,0xdf,0xff,0xf1,0xff,0x29,0x00,0x27,0x00,0xeb,0xff,0xea,0xff,0xf3,0xff,0xf6,0xff,0x92,0xff,0x23,0x00,0x08,0x00,0xad,0xff,0x0e,0x00,0xb9,0xff,0x0a,0x00,0xf6,0xff,0x01,0x00,0xd4,0xff,0xcd,0xff,0xb4,0xff,0x03,0x00,0xdb,0xff,0x10,0x00,0x32,0x00,0xf0,0xff,0x1b,0x00,0x12,0x00,0x30,0x00,0xe2,0xff,0x3b,0x00,0x36,0x00,0x5c,0x00,0xf1,0xff,0x10,0x00,0x06,0x00,0x07,0x00,0xe8,0xff,0xfd,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0x25,0x00,0xfd,0xff,0xde,0xff,0x08,0x00,0xff,0xff,0x2a,0x00,0xf8,0xff,0x09,0x00,0xd7,0xff,0xde,0xff,0xec,0xff,0x12,0x00,0x04,0x00,0x06,0x00,0xf7,0xff,0xf9,0xff,0x12,0x00,0x08,0x00,0x0a,0x00,0x01,0x00,0x21,0x00,0x12,0x00,0x0a,0x00,0xe3,0xff,0xf5,0xff,0x16,0x00,0x04,0x00,0xe8,0xff,0xe0,0xff,0x00,0x00,0xfc,0xff,0x01,0x00,0xf7,0xff,0xf6,0xff,0x04,0x00,0xfd,0xff,0xe8,0xff,0x03,0x00,0x03,0x00,0xe7,0xff,0xf9,0xff,0xf2,0xff,0xdd,0xff,0xf7,0xff,0xda,0xff,0x02,0x00,0xfc,0xff,0xf1,0xff,0x01,0x00,0x0b,0x00,0x11,0x00,0x02,0x00,0x20,0x00,0x0e,0x00,0x0b,0x00,0xf7,0xff,0x0e,0x00,0x11,0x00,0x12,0x00,0xfb,0xff,0x04,0x00,0x07,0x00,0xfd,0xff,0xf4,0xff,0x13,0x00,0x0a,0x00,0xe9,0xff,0x04,0x00,0xfa,0xff,0x24,0x00,0xfc,0xff,0xfa,0xff,0xf6,0xff,0xff,0xff,0xcc,0xff,0x12,0x00,0xef,0xff,0x0a,0x00,0x00,0x00,0xef,0xff,0x01,0x00,0xef,0xff,0x11,0x00,0xf9,0xff,0x04,0x00,0xfc,0xff,0x08,0x00,0x0f,0x00,0xea,0xff,0x23,0x00,0x11,0x00,0xfb,0xff,0x0b,0x00,0xf6,0xff,0xff,0xff,0xff,0xff,0x09,0x00,0x13,0x00,0xff,0xff,0x01,0x00,0xfc,0xff,0xfc,0xff,0x09,0x00,0xea,0xff,0x08,0x00,0x03,0x00,0xe7,0xff,0xf8,0xff,0x02,0x00,0x01,0x00,0x10,0x00,0x07,0x00,0xe4,0xff,0x03,0x00,0xf3,0xff,0xe5,0xff,0x14,0x00,0xfd,0xff,0x0b,0x00,0xf4,0xff,0x04,0x00,0x0a,0x00,0x0a,0x00,0xf5,0xff,0x11,0x00,0x14,0x00,0xfe,0xff,0x0d,0x00,0x0a,0x00,0xf6,0xff,0x00,0x00,0x01,0x00,0xf9,0xff,0x1c,0x00,0x04,0x00,0x04,0x00,0xdd,0xff,0xea,0xff,0xdf,0xff,0x18,0x00,0xf1,0xff,0xff,0xff,0xff,0xff,0x02,0x00,0xec,0xff,0x05,0x00,0x0c,0x00,0x00,0x00,0x1e,0x00,0x0a,0x00,0x04,0x00,0xea,0xff,0x0c,0x00,0x11,0x00,0x16,0x00,0xfd,0xff,0xef,0xff,0xf7,0xff,0x05,0x00,0xff,0xff,0x08,0x00,0xeb,0xff,0x00,0x00,0x03,0x00,0x06,0x00,0x03,0x00,0xf9,0xff,0x13,0x00,0x09,0x00,0xf9,0xff,0xf8,0xff,0xf8,0xff,0x04,0x00,0x08,0x00,0xfb,0xff,0x04,0x00,0xfb,0xff,0xfe,0xff,0x0e,0x00,0xfc,0xff,0xf1,0xff,0x0e,0x00,0x00,0x00,0x0e,0x00,0x05,0x00,0x13,0x00,0xf9,0xff,0xed,0xff,0xff,0xff,0x09,0x00,0xfe,0xff,0xfe,0xff,0x06,0x00,0x07,0x00,0xf6,0xff,0xfa,0xff,0x0b,0x00,0x05,0x00,0x06,0x00,0xe4,0xff,0xf0,0xff,0x04,0x00,0x0e,0x00,0xf9,0xff,0xf5,0xff,0x01,0x00,0x19,0x00,0xf0,0xff,0x0d,0x00,0x02,0x00,0xfd,0xff,0xf3,0xff,0xf6,0xff,0x02,0x00,0x05,0x00,0x08,0x00,0xfd,0xff,0x10,0x00,0x02,0x00,0x0a,0x00,0xf1,0xff,0x0a,0x00,0x01,0x00,0x02,0x00,0x13,0x00,0x09,0x00,0xfc,0xff,0xfe,0xff,0xed,0xff,0x18,0x00,0xe6,0xff,0xf2,0xff,0x0c,0x00,0xf5,0xff,0xff,0xff,0x12,0x00,0xf0,0xff,0x03,0x00,0x0e,0x00,0xf2,0xff,0x03,0x00,0x03,0x00,0xfe,0xff,0xeb,0xff,0xf1,0xff,0x01,0x00,0xff,0xff,0xff,0xff,0xfc,0xff,0x1b,0x00,0x23,0x00,0x0d,0x00,0xf0,0xff,0x05,0x00,0x00,0x00,0xfd,0xff,0x1a,0x00,0xe2,0xff,0xeb,0xff,0x03,0x00,0x07,0x00,0x0b,0x00,0xfc,0xff,0x01,0x00,0xeb,0xff,0xee,0xff,0x11,0x00,0xf4,0xff,0xec,0xff,0x09,0x00,0x04,0x00,0xe8,0xff,0x01,0x00,0xfc,0xff,0x10,0x00,0x06,0x00,0x04,0x00,0x0e,0x00,0x0d,0x00,0x00,0x00,0xff,0xff,0xe8,0xff,0x02,0x00,0x0d,0x00,0x12,0x00,0x11,0x00,0xfc,0xff,0xf8,0xff,0xf5,0xff,0x0d,0x00,0xfc,0xff,0x06,0x00,0xeb,0xff,0x08,0x00,0xf8,0xff,0x03,0x00,0x02,0x00,0xf1,0xff,0x06,0x00,0x10,0x00,0x09,0x00,0xfd,0xff,0x0c,0x00,0xe6,0xff,0xf7,0xff,0x02,0x00,0x15,0x00,0xfc,0xff,0x12,0x00,0x02,0x00,0x01,0x00,0xe8,0xff,0x07,0x00,0xe9,0xff,0x0f,0x00,0xed,0xff,0xee,0xff,0x03,0x00,0x03,0x00,0x03,0x00,0xf4,0xff,0x08,0x00,0x01,0x00,0xfa,0xff,0x0d,0x00,0x0b,0x00,0x16,0x00,0xec,0xff,0x0d,0x00,0x08,0x00,0xf6,0xff,0xed,0xff,0xf9,0xff,0x08,0x00,0x0c,0x00,0x00,0x00,0x09,0x00,0xf5,0xff,0x09,0x00,0xe4,0xff,0x06,0x00,0x0d,0x00,0x05,0x00,0xdd,0xff,0x01,0x00,0x0e,0x00,0x18,0x00,0x01,0x00,0x1f,0x00,0x17,0x00,0x02,0x00,0x07,0x00,0x08,0x00,0xf2,0xff,0xff,0xff,0x00,0x00,0xf7,0xff,0xeb,0xff,0x0c,0x00,0xec,0xff,0x05,0x00,0xfb,0xff,0x00,0x00,0x1d,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xee,0xff,0xe9,0xff,0x01,0x00,0x0d,0x00,0xfc,0xff,0xe7,0xff,0xfb,0xff,0x05,0x00,0xe8,0xff,0xf8,0xff,0x07,0x00,0xf7,0xff,0xef,0xff,0xe7,0xff,0x0c,0x00,0x01,0x00,0x01,0x00,0xfa,0xff,0x0e,0x00,0xf5,0xff,0xff,0xff,0xfe,0xff,0x17,0x00,0x1a,0x00,0xe8,0xff,0xed,0xff,0xfa,0xff,0xf9,0xff,0x08,0x00,0xed,0xff,0x05,0x00,0x00,0x00,0xf7,0xff,0x05,0x00,0xff,0xff,0xfe,0xff,0xe9,0xff,0x0e,0x00,0x0b,0x00,0x01,0x00,0x09,0x00,0x0c,0x00,0xf9,0xff,0x07,0x00,0x11,0x00,0x03,0x00,0x09,0x00,0x03,0x00,0xfc,0xff,0xec,0xff,0x1e,0x00,0x03,0x00,0xfc,0xff,0x03,0x00,0x08,0x00,0xf9,0xff,0xe5,0xff,0xf9,0xff,0xed,0xff,0x03,0x00,0xf8,0xff,0xf4,0xff,0x03,0x00,0xff,0xff,0xf4,0xff,0xf5,0xff,0x02,0x00,0xfd,0xff,0x0a,0x00,0xf3,0xff,0x0e,0x00,0x07,0x00,0x10,0x00,0xfd,0xff,0x1c,0x00,0x03,0x00,0x10,0x00,0xf1,0xff,0x10,0x00,0x03,0x00,0x13,0x00,0x0b,0x00,0xf2,0xff,0x00,0x00,0x03,0x00,0xf8,0xff,0xf6,0xff,0x09,0x00,0xfb,0xff,0x0c,0x00,0x04,0x00,0xfc,0xff,0x15,0x00,0x11,0x00,0x08,0x00,0x0a,0x00,0xee,0xff,0x06,0x00,0xfe,0xff,0x13,0x00,0xeb,0xff,0xe0,0xff,0x03,0x00,0x02,0x00,0x10,0x00,0xfd,0xff,0x0b,0x00,0x04,0x00,0xf7,0xff,0xf2,0xff,0x10,0x00,0x02,0x00,0xf7,0xff,0xf1,0xff,0x15,0x00,0x04,0x00,0xfe,0xff,0x02,0x00,0x11,0x00,0xff,0xff,0x05,0x00,0xf5,0xff,0x11,0x00,0x09,0x00,0x0c,0x00,0xf4,0xff,0x01,0x00,0x12,0x00,0xf5,0xff,0xec,0xff,0x04,0x00,0x0a,0x00,0x08,0x00,0xfb,0xff,0x09,0x00,0x09,0x00,0x1a,0x00,0x02,0x00,0xf7,0xff,0xee,0xff,0x26,0x00,0xf1,0xff,0x10,0x00,0x01,0x00,0x06,0x00,0x22,0x00,0x05,0x00,0xfa,0xff,0xfb,0xff,0x05,0x00,0xf7,0xff,0xf7,0xff,0xf1,0xff,0xe9,0xff,0x05,0x00,0x0b,0x00,0xff,0xff,0xf6,0xff,0x07,0x00,0x0a,0x00,0xfb,0xff,0xe9,0xff,0xfe,0xff,0x12,0x00,0x02,0x00,0xf2,0xff,0x03,0x00,0xff,0xff,0xf4,0xff,0xf7,0xff,0x02,0x00,0x07,0x00,0x06,0x00,0xe2,0xff,0x0c,0x00,0x07,0x00,0x03,0x00,0x11,0x00,0xf5,0xff,0x0e,0x00,0xfd,0xff,0xff,0xff,0x09,0x00,0x10,0x00,0xec,0xff,0x09,0x00,0x07,0x00,0x15,0x00,0x11,0x00,0xef,0xff,0xff,0xff,0x10,0x00,0xf1,0xff,0xef,0xff,0xfe,0xff,0x02,0x00,0xf7,0xff,0xe5,0xff,0x07,0x00,0x0a,0x00,0xff,0xff,0xff,0xff,0x0d,0x00,0xff,0xff,0x13,0x00,0xe6,0xff,0x1a,0x00,0x01,0x00,0x02,0x00,0xf8,0xff,0x16,0x00,0xfa,0xff,0xfc,0xff,0x05,0x00,0x06,0x00,0xeb,0xff,0xed,0xff,0x08,0x00,0x06,0x00,0x0b,0x00,0x0c,0x00,0x05,0x00,0x06,0x00,0xfc,0xff,0xee,0xff,0x01,0x00,0xf8,0xff,0xf8,0xff,0xe6,0xff,0x06,0x00,0x08,0x00,0xfa,0xff,0xf7,0xff,0xf4,0xff,0x1b,0x00,0x09,0x00,0x11,0x00,0xf5,0xff,0x0f,0x00,0x04,0x00,0xf9,0xff,0x1e,0x00,0xf7,0xff,0x07,0x00,0x01,0x00,0x0a,0x00,0xfd,0xff,0x09,0x00,0xe2,0xff,0x08,0x00,0x02,0x00,0x14,0x00,0x0f,0x00,0xee,0xff,0x08,0x00,0x0a,0x00,0xfc,0xff,0xe7,0xff,0xf8,0xff,0x19,0x00,0xfb,0xff,0xe5,0xff,0x07,0x00,0x05,0x00,0xdf,0xff,0xf6,0xff,0x19,0x00,0xf5,0xff,0x03,0x00,0xec,0xff,0x15,0x00,0xff,0xff,0x07,0x00,0x0f,0x00,0x08,0x00,0xf7,0xff,0xff,0xff,0xff,0xff,0x11,0x00,0x04,0x00,0x0a,0x00,0x05,0x00,0x14,0x00,0x10,0x00,0x18,0x00,0xf1,0xff,0x00,0x00,0x0e,0x00,0xf0,0xff,0xfc,0xff,0xf8,0xff,0x0a,0x00,0xfa,0xff,0xe6,0xff,0x10,0x00,0x04,0x00,0x03,0x00,0xf5,0xff,0x04,0x00,0xf5,0xff,0x18,0x00,0xf0,0xff,0x02,0x00,0x0a,0x00,0xff,0xff,0x10,0x00,0xed,0xff,0x0d,0x00,0xfc,0xff,0x1d,0x00,0x02,0x00,0x0a,0x00,0xf3,0xff,0x04,0x00,0x13,0x00,0x10,0x00,0x06,0x00,0xf1,0xff,0x03,0x00,0x0c,0x00,0xf0,0xff,0xf6,0xff,0xfc,0xff,0x13,0x00,0xf7,0xff,0x09,0x00,0x0d,0x00,0xfc,0xff,0x04,0x00,0xfa,0xff,0x0e,0x00,0x03,0x00,0x06,0x00,0x08,0x00,0xf4,0xff,0x04,0x00,0xfb,0xff,0x0f,0x00,0x16,0x00,0xee,0xff,0xfe,0xff,0x1c,0x00,0x06,0x00,0x06,0x00,0x0d,0x00,0xfd,0xff,0xfa,0xff,0x18,0x00,0xf1,0xff,0xed,0xff,0x00,0x00,0xff,0xff,0xf8,0xff,0xfa,0xff,0xf8,0xff,0xfe,0xff,0xe7,0xff,0xe6,0xff,0x08,0x00,0x0e,0x00,0x19,0x00,0xf9,0xff,0x08,0x00,0xf8,0xff,0x19,0x00,0xeb,0xff,0xfb,0xff,0x06,0x00,0xfd,0xff,0xf2,0xff,0xfd,0xff,0x0b,0x00,0x03,0x00,0x0d,0x00,0x08,0x00,0x12,0x00,0xfd,0xff,0xfe,0xff,0x10,0x00,0xf5,0xff,0x0c,0x00,0xf9,0xff,0x05,0x00,0x08,0x00,0xec,0xff,0x00,0x00,0xfd,0xff,0x13,0x00,0xff,0xff,0xf1,0xff,0x1f,0x00,0xf7,0xff,0x03,0x00,0xfa,0xff,0xf4,0xff,0x03,0x00,0x0a,0x00,0xf2,0xff,0xf0,0xff,0x07,0x00,0x07,0x00,0x10,0x00,0x07,0x00,0xfe,0xff,0xfd,0xff,0xfb,0xff,0x01,0x00,0x0a,0x00,0xf8,0xff,0x0a,0x00,0x09,0x00,0x11,0x00,0x07,0x00,0xdf,0xff,0x00,0x00,0x0f,0x00,0xe9,0xff,0x0d,0x00,0x03,0x00,0xfc,0xff,0xfd,0xff,0xf1,0xff,0x10,0x00,0x0b,0x00,0x05,0x00,0x0c,0x00,0xf6,0xff,0xf8,0xff,0x13,0x00,0xf5,0xff,0xf4,0xff,0x06,0x00,0xf5,0xff,0x0f,0x00,0x16,0x00,0xfa,0xff,0xf7,0xff,0x12,0x00,0x04,0x00,0x1a,0x00,0x0b,0x00,0xf2,0xff,0x09,0x00,0x0c,0x00,0xf7,0xff,0x0e,0x00,0xff,0xff,0x0b,0x00,0x01,0x00,0xe9,0xff,0xf1,0xff,0x16,0x00,0xef,0xff,0x05,0x00,0x00,0x00,0x09,0x00,0xf4,0xff,0x00,0x00,0x1e,0x00,0xf7,0xff,0x1b,0x00,0x07,0x00,0xe7,0xff,0x10,0x00,0xf4,0xff,0x16,0x00,0x28,0x00,0xfc,0xff,0xfb,0xff,0x0b,0x00,0x04,0x00,0x12,0x00,0xee,0xff,0xf7,0xff,0x0a,0x00,0xfd,0xff,0x0f,0x00,0xf3,0xff,0x0b,0x00,0x05,0x00,0xf9,0xff,0x06,0x00,0xff,0xff,0x0e,0x00,0xf7,0xff,0xeb,0xff,0xf7,0xff,0xfa,0xff,0xeb,0xff,0x00,0x00,0xf2,0xff,0xee,0xff,0x05,0x00,0x17,0x00,0xe5,0xff,0x0e,0x00,0x07,0x00,0x02,0x00,0x22,0x00,0x03,0x00,0xfb,0xff,0x06,0x00,0x09,0x00,0x1a,0x00,0x0f,0x00,0x19,0x00,0x0d,0x00,0x10,0x00,0xf0,0xff,0xf2,0xff,0x05,0x00,0x10,0x00,0xef,0xff,0xed,0xff,0xf5,0xff,0x0d,0x00,0x02,0x00,0x06,0x00,0xf0,0xff,0x0c,0x00,0xec,0xff,0xfb,0xff,0x03,0x00,0xf9,0xff,0x06,0x00,0xf3,0xff,0xe3,0xff,0x0a,0x00,0xfc,0xff,0x00,0x00,0x14,0x00,0x01,0x00,0xf7,0xff,0xf4,0xff,0x01,0x00,0x0e,0x00,0x17,0x00,0x21,0x00,0x09,0x00,0xf9,0xff,0x05,0x00,0x1b,0x00,0xf1,0xff,0xfe,0xff,0xf9,0xff,0x03,0x00,0x0a,0x00,0x14,0x00,0xf4,0xff,0x04,0x00,0xe9,0xff,0xf4,0xff,0x12,0x00,0x0b,0x00,0xec,0xff,0xf0,0xff,0x1b,0x00,0xeb,0xff,0xe8,0xff,0xff,0xff,0xfd,0xff,0x0e,0x00,0x11,0x00,0x01,0x00,0xf3,0xff,0x07,0x00,0x10,0x00,0x23,0x00,0x25,0x00,0x1b,0x00,0x1b,0x00,0x01,0x00,0x21,0x00,0x01,0x00,0xf3,0xff,0x05,0x00,0xf8,0xff,0x07,0x00,0xfb,0xff,0x13,0x00,0xfb,0xff,0xf6,0xff,0xfb,0xff,0x0f,0x00,0x09,0x00,0x6b,0x00,0x03,0x00,0xb2,0xff,0x40,0x00,0xed,0xff,0xac,0xff,0x54,0x00,0xe1,0xff,0x0d,0x00,0xfe,0xff,0x01,0x00,0x93,0xff,0x1f,0x00,0x19,0x00,0x2f,0x00,0x1f,0x00,0x17,0x00,0x37,0x00,0x16,0x00,0x13,0x00,0x13,0x00,0xac,0xff,0x2d,0x00,0xf5,0xff,0x0b,0x00,0x65,0x00,0xf5,0xff,0xe6,0xff,0xe6,0xff,0x80,0xff,0xfa,0xff,0xef,0xff,0xbc,0xff,0xe9,0xff,0xdb,0xff,0xf5,0xff,0xfe,0xff,0x0a,0x00,0x09,0x00,0xd0,0xff,0x1b,0x00,0x0d,0x00,0xff,0xff,0xdd,0xff,0x4a,0x00,0x01,0x00,0xf9,0xff,0x39,0x00,0x27,0x00,0xa6,0xff,0x24,0x00,0xf3,0xff,0x19,0x00,0x2a,0x00,0x06,0x00,0xca,0xff,0x02,0x00,0x0e,0x00,0xcb,0xff,0xf7,0xff,0x1f,0x00,0xf7,0xff,0x25,0x00,0xef,0xff,0x0e,0x00,0x0b,0x00,0x00,0x00,0x0a,0x00,0x06,0x00,0x07,0x00,0x11,0x00,0xfa,0xff,0x08,0x00,0x02,0x00,0xfd,0xff,0x12,0x00,0xc5,0xff,0xd9,0xff,0xfd,0xff,0x0d,0x00,0xe8,0xff,0xf5,0xff,0xe6,0xff,0xfb,0xff,0x0b,0x00,0x17,0x00,0x02,0x00,0xee,0xff,0xdc,0xff,0x07,0x00,0x00,0x00,0xf9,0xff,0x09,0x00,0x24,0x00,0x09,0x00,0xfa,0xff,0xf1,0xff,0xdc,0xff,0xdf,0xff,0x1e,0x00,0x24,0x00,0x1f,0x00,0xdc,0xff,0xab,0xff,0xfa,0xff,0x21,0x00,0x17,0x00,0xc1,0xff,0x33,0x00,0xb9,0xff,0xe2,0xff,0xdb,0xff,0x00,0x00,0xf1,0xff,0xf9,0xff,0x05,0x00,0xcb,0xff,0x10,0x00,0x04,0x00,0xdf,0xff,0xb6,0xff,0x2d,0x00,0xe0,0xff,0xf5,0xff,0x60,0x00,0x1c,0x00,0xf2,0xff,0x1f,0x00,0x26,0x00,0x02,0x00,0xf8,0xff,0xe8,0xff,0x12,0x00,0xf4,0xff,0xe2,0xff,0xde,0xff,0x0a,0x00,0x0a,0x00,0xfb,0xff,0xfb,0xff,0x2a,0x00,0x01,0x00,0xdd,0xff,0x20,0x00,0xda,0xff,0x23,0x00,0x39,0x00,0xf8,0xff,0xef,0xff,0xf4,0xff,0xf9,0xff,0xdb,0xff,0xe9,0xff,0x12,0x00,0xf1,0xff,0x16,0x00,0xfe,0xff,0xeb,0xff,0x33,0x00,0x20,0x00,0x06,0x00,0xe4,0xff,0xef,0xff,0x01,0x00,0x1e,0x00,0xd3,0xff,0xff,0xff,0xf3,0xff,0x0a,0x00,0xdc,0xff,0xe3,0xff,0x19,0x00,0xf5,0xff,0xd1,0xff,0x08,0x00,0x01,0x00,0xf7,0xff,0x3d,0x00,0xec,0xff,0x16,0x00,0x09,0x00,0xca,0xff,0x30,0x00,0x45,0x00,0x1a,0x00,0xd4,0xff,0x40,0x00,0xed,0xff,0xf2,0xff,0x0e,0x00,0xc8,0xff,0x1d,0x00,0x34,0x00,0x08,0x00,0x15,0x00,0x0f,0x00,0x1d,0x00,0x03,0x00,0x00,0x00,0x23,0x00,0xfd,0xff,0x41,0x00,0xcc,0xff,0x0b,0x00,0xcf,0xff,0x24,0x00,0xff,0xff,0xdd,0xff,0x5c,0x00,0x7f,0x00,0x48,0x00,0x0f,0x00,0xef,0xff,0x1d,0x00,0xec,0xff,0x7e,0x00,0x0d,0x00,0x01,0x00,0xeb,0xff,0xfc,0xff,0xfb,0xff,0x3b,0x00,0xe1,0xff,0xf1,0xff,0xf1,0xff,0x3a,0x00,0xe7,0xff,0xe9,0xff,0xf5,0xff,0xeb,0xff,0x02,0x00,0x16,0x00,0x23,0x00,0x0f,0x00,0xe2,0xff,0x02,0x00,0xff,0xff,0xf8,0xff,0x03,0x00,0xfc,0xff,0x0e,0x00,0x02,0x00,0x41,0x00,0xf8,0xff,0xf3,0xff,0xd6,0xff,0xef,0xff,0x2b,0x00,0x04,0x00,0xd7,0xff,0x0d,0x00,0x0b,0x00,0xeb,0xff,0xfe,0xff,0xed,0xff,0x09,0x00,0xc1,0xff,0xd7,0xff,0xdb,0xff,0x30,0x00,0x10,0x00,0xd5,0xff,0x13,0x00,0xfb,0xff,0x2f,0x00,0x18,0x00,0x13,0x00,0xeb,0xff,0x07,0x00,0xf3,0xff,0x12,0x00,0x12,0x00,0x04,0x00,0x23,0x00,0x42,0x00,0x15,0x00,0x03,0x00,0xf2,0xff,0x22,0x00,0x1d,0x00,0xfb,0xff,0x1f,0x00,0x35,0x00,0xd2,0xff,0xe1,0xff,0xe6,0xff,0x20,0x00,0x24,0x00,0x06,0x00,0x02,0x00,0x0e,0x00,0x07,0x00,0xe8,0xff,0xfc,0xff,0xf8,0xff,0x21,0x00,0xff,0xff,0x1c,0x00,0xf6,0xff,0x17,0x00,0x17,0x00,0xd7,0xff,0x0a,0x00,0x17,0x00,0xab,0xff,0x06,0x00,0xf7,0xff,0xf2,0xff,0x15,0x00,0x0d,0x00,0xe7,0xff,0x07,0x00,0xe1,0xff,0x11,0x00,0xd9,0xff,0x15,0x00,0x13,0x00,0xf6,0xff,0x0b,0x00,0x21,0x00,0xc2,0xff,0xe5,0xff,0xcc,0xff,0x31,0x00,0xef,0xff,0xb0,0xff,0x2a,0x00,0x01,0x00,0x18,0x00,0xe1,0xff,0x00,0x00,0x18,0x00,0xfb,0xff,0x04,0x00,0x1a,0x00,0x18,0x00,0x1d,0x00,0x3b,0x00,0x45,0x00,0x0a,0x00,0x05,0x00,0x3c,0x00,0x2d,0x00,0x1c,0x00,0xd1,0xff,0x26,0x00,0x35,0x00,0xdb,0xff,0xe4,0xff,0xaa,0xff,0x22,0x00,0x16,0x00,0x10,0x00,0xfa,0xff,0xd5,0xff,0xeb,0xff,0xf8,0xff,0x00,0x00,0xe3,0xff,0xd2,0xff,0x1e,0x00,0x07,0x00,0x08,0x00,0xd3,0xff,0xdc,0xff,0x2e,0x00,0x2c,0x00,0x0c,0x00,0xdc,0xff,0xd5,0xff,0xe0,0xff,0xe4,0xff,0x08,0x00,0xfc,0xff,0xfb,0xff,0x07,0x00,0xfd,0xff,0x00,0x00,0xfd,0xff,0x0b,0x00,0x20,0x00,0xdf,0xff,0x05,0x00,0xfa,0xff,0x32,0x00,0x21,0x00,0x07,0x00,0xee,0xff,0x02,0x00,0x14,0x00,0xe3,0xff,0xf9,0xff,0xdb,0xff,0xfe,0xff,0xdf,0xff,0xfd,0xff,0x49,0x00,0xe6,0xff,0xf4,0xff,0xee,0xff,0x0b,0x00,0x07,0x00,0xe0,0xff,0xd2,0xff,0xdd,0xff,0xeb,0xff,0xd9,0xff,0xea,0xff,0x15,0x00,0xe7,0xff,0xcb,0xff,0x31,0x00,0x22,0x00,0x1b,0x00,0xf7,0xff,0xfe,0xff,0xdb,0xff,0x35,0x00,0x1d,0x00,0xfd,0xff,0xd8,0xff,0xfc,0xff,0xf3,0xff,0xcd,0xff,0xdf,0xff,0xd1,0xff,0x3a,0x00,0x09,0x00,0x0d,0x00,0xff,0xff,0x14,0x00,0xf1,0xff,0x0a,0x00,0xf6,0xff,0xed,0xff,0xf9,0xff,0xfa,0xff,0x29,0x00,0xef,0xff,0x04,0x00,0xf2,0xff,0x21,0x00,0x04,0x00,0xff,0xff,0xf1,0xff,0xfb,0xff,0xee,0xff,0xcd,0xff,0x01,0x00,0x18,0x00,0x2c,0x00,0xf9,0xff,0xe4,0xff,0x12,0x00,0xde,0xff,0x13,0x00,0xef,0xff,0xe6,0xff,0x04,0x00,0x06,0x00,0x0b,0x00,0x18,0x00,0x04,0x00,0x16,0x00,0x2c,0x00,0xee,0xff,0xde,0xff,0xea,0xff,0xec,0xff,0xe0,0xff,0x09,0x00,0x39,0x00,0xe9,0xff,0xe3,0xff,0xf0,0xff,0xee,0xff,0x1b,0x00,0x0b,0x00,0xe0,0xff,0xf3,0xff,0xc6,0xff,0x0d,0x00,0x21,0x00,0xdf,0xff,0xe9,0xff,0x04,0x00,0x67,0x00,0x04,0x00,0xe6,0xff,0xe9,0xff,0x1e,0x00,0x44,0x00,0xea,0xff,0xfe,0xff,0xe0,0xff,0x0d,0x00,0xef,0xff,0xeb,0xff,0xe5,0xff,0xf3,0xff,0xef,0xff,0x21,0x00,0x01,0x00,0xd7,0xff,0x04,0x00,0x20,0x00,0xe4,0xff,0x0a,0x00,0x05,0x00,0xfe,0xff,0xe0,0xff,0x0d,0x00,0x15,0x00,0xf5,0xff,0x02,0x00,0x18,0x00,0xdf,0xff,0xee,0xff,0xe5,0xff,0xd5,0xff,0x05,0x00,0xd6,0xff,0x53,0x00,0x04,0x00,0xef,0xff,0xc6,0xff,0x0f,0x00,0x0f,0x00,0x16,0x00,0x23,0x00,0xaf,0xff,0x0d,0x00,0x22,0x00,0xf3,0xff,0x15,0x00,0x05,0x00,0xfb,0xff,0x13,0x00,0x22,0x00,0xff,0xff,0xf4,0xff,0xef,0xff,0xfc,0xff,0x23,0x00,0xf4,0xff,0xea,0xff,0x18,0x00,0x18,0x00,0xe9,0xff,0xde,0xff,0x52,0x00,0xfc,0xff,0xe6,0xff,0x05,0x00,0xdc,0xff,0x39,0x00,0xf9,0xff,0x27,0x00,0x0a,0x00,0x11,0x00,0xfa,0xff,0x05,0x00,0xd1,0xff,0xea,0xff,0xf7,0xff,0xe7,0xff,0x04,0x00,0x11,0x00,0xde,0xff,0xfb,0xff,0x18,0x00,0x20,0x00,0xff,0xff,0xc9,0xff,0xff,0xff,0xde,0xff,0xff,0xff,0xf5,0xff,0x09,0x00,0xed,0xff,0x1b,0x00,0xe7,0xff,0xaf,0xff,0xfb,0xff,0x15,0x00,0x35,0x00,0x17,0x00,0x99,0xff,0x4b,0x00,0x03,0x00,0x01,0x00,0x06,0x00,0xfe,0xff,0x02,0x00,0x0e,0x00,0x09,0x00,0x0b,0x00,0x72,0x00,0xe4,0xff,0x1c,0x00,0x08,0x00,0xa1,0xff,0x02,0x00,0x2a,0x00,0xe2,0xff,0xf6,0xff,0x18,0x00,0x31,0x00,0xcd,0xff,0xf7,0xff,0xf3,0xff,0x2f,0x00,0x12,0x00,0xcb,0xff,0x47,0x00,0xed,0xff,0x1e,0x00,0xe8,0xff,0x17,0x00,0x1a,0x00,0xe5,0xff,0x07,0x00,0x0d,0x00,0x0b,0x00,0x08,0x00,0x18,0x00,0xff,0xff,0x51,0x00,0x04,0x00,0x14,0x00,0x48,0x00,0x09,0x00,0xde,0xff,0x46,0x00,0x3a,0x00,0xd4,0xff,0xe1,0xff,0xcf,0xff,0xfa,0xff,0x17,0x00,0x1d,0x00,0x26,0x00,0x05,0x00,0xff,0xff,0xea,0xff,0x07,0x00,0x1e,0x00,0xf1,0xff,0x03,0x00,0x0c,0x00,0xf5,0xff,0xfc,0xff,0x0d,0x00,0xfb,0xff,0xcd,0xff,0xe8,0xff,0x1b,0x00,0x10,0x00,0xb5,0xff,0x05,0x00,0xff,0xff,0x09,0x00,0xd9,0xff,0x1d,0x00,0xf4,0xff,0x05,0x00,0x03,0x00,0x0d,0x00,0x00,0x00,0x03,0x00,0x0f,0x00,0x06,0x00,0xf8,0xff,0x18,0x00,0x09,0x00,0x25,0x00,0xe3,0xff,0x22,0x00,0xf8,0xff,0x11,0x00,0xe5,0xff,0xf0,0xff,0x18,0x00,0xf3,0xff,0x1b,0x00,0x15,0x00,0x04,0x00,0xe9,0xff,0x08,0x00,0xee,0xff,0x07,0x00,0x1c,0x00,0xf6,0xff,0x09,0x00,0x0d,0x00,0xf1,0xff,0x2a,0x00,0x26,0x00,0x0f,0x00,0x05,0x00,0x2f,0x00,0x24,0x00,0x02,0x00,0xfa,0xff,0xd6,0xff,0x35,0x00,0xee,0xff,0xf7,0xff,0xc5,0xff,0xda,0xff,0xec,0xff,0xe8,0xff,0xd0,0xff,0x31,0x00,0xcf,0xff,0x15,0x00,0x10,0x00,0xe6,0xff,0x3c,0x00,0xdf,0xff,0x1c,0x00,0x08,0x00,0xa1,0xff,0xce,0xff,0x09,0x00,0xdf,0xff,0xe9,0xff,0x15,0x00,0xf6,0xff,0xfd,0xff,0xda,0xff,0x16,0x00,0xfb,0xff,0xfb,0xff,0xfc,0xff,0x11,0x00,0x24,0x00,0xc4,0xff,0xf9,0xff,0x0b,0x00,0x27,0x00,0x02,0x00,0x20,0x00,0x04,0x00,0x31,0x00,0x0c,0x00,0x18,0x00,0xf8,0xff,0xcf,0xff,0x08,0x00,0x08,0x00,0x00,0x00,0xe0,0xff,0x0a,0x00,0x1d,0x00,0x24,0x00,0x03,0x00,0x1c,0x00,0x24,0x00,0xdb,0xff,0xbb,0xff,0x2e,0x00,0x06,0x00,0xf2,0xff,0x21,0x00,0xe8,0xff,0xf7,0xff,0xf1,0xff,0x13,0x00,0x03,0x00,0x0d,0x00,0xeb,0xff,0x05,0x00,0x0b,0x00,0x05,0x00,0x95,0xff,0x07,0x00,0x10,0x00,0xf7,0xff,0x0f,0x00,0xf2,0xff,0x1f,0x00,0xff,0xff,0x01,0x00,0xf0,0xff,0xfe,0xff,0xe2,0xff,0x09,0x00,0x11,0x00,0xf4,0xff,0x0d,0x00,0xf9,0xff,0xfc,0xff,0x07,0x00,0x09,0x00,0x01,0x00,0x32,0x00,0x01,0x00,0xa3,0xff,0x0f,0x00,0x01,0x00,0xf2,0xff,0xe5,0xff,0x1e,0x00,0x02,0x00,0x07,0x00,0x03,0x00,0xfa,0xff,0x0a,0x00,0x15,0x00,0xd9,0xff,0x06,0x00,0xef,0xff,0xf7,0xff,0x17,0x00,0xfb,0xff,0x0e,0x00,0xef,0xff,0x03,0x00,0xe0,0xff,0xd6,0xff,0x34,0x00,0xfe,0xff,0xe0,0xff,0x0e,0x00,0x05,0x00,0xea,0xff,0xc7,0xff,0xf9,0xff,0xdb,0xff,0xfe,0xff,0xff,0xff,0x04,0x00,0x24,0x00,0x1e,0x00,0x30,0x00,0xe4,0xff,0x0b,0x00,0x2c,0x00,0xfc,0xff,0x11,0x00,0xf9,0xff,0xea,0xff,0x1b,0x00,0x22,0x00,0x17,0x00,0x2b,0x00,0x01,0x00,0xc5,0xff,0x32,0x00,0xfc,0xff,0xf3,0xff,0x01,0x00,0x0b,0x00,0x0e,0x00,0xe4,0xff,0x3b,0x00,0x29,0x00,0x32,0x00,0xfa,0xff,0x44,0x00,0xfd,0xff,0xfc,0xff,0xeb,0xff,0x3b,0x00,0x12,0x00,0x07,0x00,0xd4,0xff,0xdb,0xff,0x2f,0x00,0xc3,0xff,0xd3,0xff,0xc9,0xff,0x16,0x00,0xdd,0xff,0xe2,0xff,0xfa,0xff,0xfc,0xff,0x02,0x00,0xee,0xff,0x04,0x00,0xdd,0xff,0xf8,0xff,0xdd,0xff,0x11,0x00,0xf4,0xff,0xcc,0xff,0xed,0xff,0x12,0x00,0xea,0xff,0xcb,0xff,0x28,0x00,0x28,0x00,0x37,0x00,0xef,0xff,0xd0,0xff,0x25,0x00,0x13,0x00,0x09,0x00,0x1e,0x00,0xf5,0xff,0xf7,0xff,0xbc,0xff,0xe8,0xff,0xcb,0xff,0x08,0x00,0x28,0x00,0xcc,0xff,0xff,0xff,0xb9,0xff,0x22,0x00,0x0a,0x00,0x0d,0x00,0x2b,0x00,0xcd,0xff,0x31,0x00,0x1a,0x00,0xe8,0xff,0x1e,0x00,0x05,0x00,0xfc,0xff,0x14,0x00,0xfa,0xff,0x0b,0x00,0xed,0xff,0xed,0xff,0xef,0xff,0xea,0xff,0xdd,0xff,0x02,0x00,0x34,0x00,0xd4,0xff,0xfa,0xff,0x28,0x00,0x15,0x00,0xf9,0xff,0xd9,0xff,0xec,0xff,0x36,0x00,0x0e,0x00,0xb7,0xff,0x15,0x00,0xda,0xff,0xf4,0xff,0xe1,0xff,0xc8,0xff,0xd0,0xff,0xfa,0xff,0xfb,0xff,0x75,0x00,0xf7,0xff,0xdb,0xff,0xf1,0xff,0x00,0x00,0xe8,0xff,0x09,0x00,0x01,0x00,0x18,0x00,0xcf,0xff,0xe2,0xff,0xe7,0xff,0x04,0x00,0xff,0xff,0xf8,0xff,0xf2,0xff,0xf8,0xff,0xf5,0xff,0xd4,0xff,0xda,0xff,0x0e,0x00,0x06,0x00,0xf4,0xff,0x30,0x00,0xeb,0xff,0xf3,0xff,0xed,0xff,0xdb,0xff,0xf7,0xff,0xc1,0xff,0x07,0x00,0x10,0x00,0x0f,0x00,0x00,0x00,0xf6,0xff,0xc4,0xff,0x0b,0x00,0x05,0x00,0x1b,0x00,0x1b,0x00,0xf6,0xff,0xf6,0xff,0x10,0x00,0xe1,0xff,0xfd,0xff,0xcd,0xff,0x2e,0x00,0xf1,0xff,0xdc,0xff,0xf8,0xff,0xfd,0xff,0x23,0x00,0xed,0xff,0x13,0x00,0x0d,0x00,0xfc,0xff,0x14,0x00,0x2a,0x00,0x1b,0x00,0x02,0x00,0x49,0x00,0x1c,0x00,0xfe,0xff,0xf2,0xff,0xee,0xff,0x17,0x00,0x24,0x00,0x06,0x00,0xf6,0xff,0x3d,0x00,0xc5,0xff,0xf3,0xff,0xe6,0xff,0x29,0x00,0xd6,0xff,0x00,0x00,0x02,0x00,0x03,0x00,0x06,0x00,0xdf,0xff,0xff,0xff,0xe3,0xff,0x12,0x00,0x02,0x00,0xfa,0xff,0x03,0x00,0xfc,0xff,0xed,0xff,0x12,0x00,0xeb,0xff,0xfc,0xff,0x1a,0x00,0xf2,0xff,0xf2,0xff,0x1b,0x00,0x11,0x00,0x0a,0x00,0xfc,0xff,0x36,0x00,0xc9,0xff,0xf8,0xff,0x30,0x00,0x1d,0x00,0xf7,0xff,0x38,0x00,0x0a,0x00,0x2d,0x00,0x1d,0x00,0xf3,0xff,0x25,0x00,0xec,0xff,0x32,0x00,0xe1,0xff,0x36,0x00,0x04,0x00,0xea,0xff,0x01,0x00,0xf8,0xff,0x41,0x00,0xb9,0xff,0x23,0x00,0x18,0x00,0x2d,0x00,0x0b,0x00,0xf4,0xff,0x15,0x00,0xf2,0xff,0xeb,0xff,0x24,0x00,0xce,0xff,0x81,0xff,0xd1,0xff,0xfb,0xff,0x21,0x00,0x05,0x00,0x14,0x00,0x0b,0x00,0xce,0xff,0xfa,0xff,0xff,0xff,0xfa,0xff,0x0a,0x00,0xf2,0xff,0x26,0x00,0xfb,0xff,0x25,0x00,0xf9,0xff,0xf7,0xff,0xfa,0xff,0x20,0x00,0x2c,0x00,0xf4,0xff,0x04,0x00,0xfd,0xff,0x13,0x00,0xf1,0xff,0x00,0x00,0x0b,0x00,0xdc,0xff,0xed,0xff,0x1a,0x00,0x0a,0x00,0xf0,0xff,0xd9,0xff,0xef,0xff,0x19,0x00,0x05,0x00,0x03,0x00,0xf2,0xff,0xf2,0xff,0xfd,0xff,0x10,0x00,0xd7,0xff,0x07,0x00,0x0a,0x00,0x0e,0x00,0xf1,0xff,0x26,0x00,0xeb,0xff,0xfd,0xff,0x0e,0x00,0x1c,0x00,0x19,0x00,0xfc,0xff,0xfa,0xff,0x09,0x00,0xf9,0xff,0xf2,0xff,0x04,0x00,0xff,0xff,0xfd,0xff,0x01,0x00,0x2e,0x00,0xe8,0xff,0xfe,0xff,0x03,0x00,0x09,0x00,0x1b,0x00,0x08,0x00,0x05,0x00,0x1d,0x00,0x05,0x00,0xfb,0xff,0x10,0x00,0xfd,0xff,0x01,0x00,0xf7,0xff,0xfe,0xff,0xf5,0xff,0x16,0x00,0x0e,0x00,0xff,0xff,0xea,0xff,0x10,0x00,0x1a,0x00,0x04,0x00,0xf4,0xff,0x00,0x00,0x05,0x00,0x03,0x00,0xf4,0xff,0x00,0x00,0x13,0x00,0x1a,0x00,0x2e,0x00,0x10,0x00,0x0a,0x00,0x0e,0x00,0xf5,0xff,0x1b,0x00,0x11,0x00,0x0a,0x00,0xfa,0xff,0xf4,0xff,0x0e,0x00,0xf2,0xff,0x00,0x00,0x1b,0x00,0x0b,0x00,0x06,0x00,0xef,0xff,0x00,0x00,0xf3,0xff,0x00,0x00,0xfc,0xff,0xf2,0xff,0x17,0x00,0xf6,0xff,0x1a,0x00,0xff,0xff,0x0b,0x00,0x00,0x00,0xfd,0xff,0x12,0x00,0xfc,0xff,0xf6,0xff,0x22,0x00,0xfc,0xff,0xfd,0xff,0xfb,0xff,0xfd,0xff,0x1a,0x00,0xfe,0xff,0xf6,0xff,0x17,0x00,0xf0,0xff,0xff,0xff,0x06,0x00,0xed,0xff,0x0d,0x00,0xf3,0xff,0x0c,0x00,0xfe,0xff,0xf3,0xff,0xf1,0xff,0xfc,0xff,0xff,0xff,0x1b,0x00,0x05,0x00,0xf1,0xff,0x17,0x00,0x06,0x00,0x07,0x00,0xf3,0xff,0x01,0x00,0x04,0x00,0xeb,0xff,0x0b,0x00,0x25,0x00,0x11,0x00,0xfa,0xff,0xfb,0xff,0xf9,0xff,0x2d,0x00,0xfa,0xff,0x02,0x00,0x15,0x00,0xe6,0xff,0x03,0x00,0x07,0x00,0xde,0xff,0x09,0x00,0xfd,0xff,0xff,0xff,0x0f,0x00,0x10,0x00,0x11,0x00,0x03,0x00,0xf8,0xff,0xf6,0xff,0x11,0x00,0xf8,0xff,0x08,0x00,0xff,0xff,0x08,0x00,0x0a,0x00,0xfb,0xff,0x03,0x00,0x18,0x00,0x15,0x00,0x1a,0x00,0x14,0x00,0x01,0x00,0xf6,0xff,0xf4,0xff,0x06,0x00,0x10,0x00,0x0a,0x00,0x08,0x00,0xf2,0xff,0xf7,0xff,0xf4,0xff,0x06,0x00,0x0b,0x00,0x16,0x00,0x01,0x00,0xfb,0xff,0x1f,0x00,0xf9,0xff,0xfd,0xff,0xfa,0xff,0xf8,0xff,0x06,0x00,0x05,0x00,0xf9,0xff,0xfc,0xff,0x05,0x00,0x02,0x00,0x03,0x00,0x04,0x00,0xed,0xff,0xe4,0xff,0x20,0x00,0xe7,0xff,0xfe,0xff,0xf9,0xff,0xf5,0xff,0x1e,0x00,0x0b,0x00,0x00,0x00,0x0c,0x00,0xf8,0xff,0x06,0x00,0xf5,0xff,0xef,0xff,0x1a,0x00,0xf3,0xff,0xff,0xff,0xec,0xff,0x12,0x00,0xfd,0xff,0xfd,0xff,0xed,0xff,0xf3,0xff,0x07,0x00,0xf4,0xff,0xf2,0xff,0x04,0x00,0x0d,0x00,0x09,0x00,0xfd,0xff,0x13,0x00,0xe8,0xff,0xed,0xff,0x03,0x00,0x10,0x00,0xfc,0xff,0x12,0x00,0x04,0x00,0x24,0x00,0x10,0x00,0x02,0x00,0x01,0x00,0x0e,0x00,0x00,0x00,0x0b,0x00,0xed,0xff,0x04,0x00,0x29,0x00,0xf7,0xff,0xf9,0xff,0xed,0xff,0xfc,0xff,0xfd,0xff,0xfb,0xff,0x12,0x00,0xf9,0xff,0xf5,0xff,0x11,0x00,0x00,0x00,0x03,0x00,0xfe,0xff,0xf9,0xff,0xfa,0xff,0xdf,0xff,0xee,0xff,0x15,0x00,0xed,0xff,0xff,0xff,0xf2,0xff,0xf0,0xff,0x0e,0x00,0xf7,0xff,0x07,0x00,0x03,0x00,0xf4,0xff,0xf7,0xff,0xfc,0xff,0x01,0x00,0xfa,0xff,0xf9,0xff,0x14,0x00,0x0f,0x00,0x09,0x00,0xe9,0xff,0x00,0x00,0xf4,0xff,0xf9,0xff,0xf6,0xff,0xf6,0xff,0x0c,0x00,0x0b,0x00,0x08,0x00,0xfa,0xff,0xfd,0xff,0x11,0x00,0x09,0x00,0x01,0x00,0xe8,0xff,0x0d,0x00,0x07,0x00,0x02,0x00,0xfe,0xff,0x1d,0x00,0x11,0x00,0xfe,0xff,0x12,0x00,0xe8,0xff,0xf3,0xff,0x00,0x00,0x07,0x00,0x20,0x00,0x2b,0x00,0x0e,0x00,0xf3,0xff,0xf0,0xff,0x0d,0x00,0x01,0x00,0xf0,0xff,0xe1,0xff,0x08,0x00,0xfb,0xff,0xfd,0xff,0x01,0x00,0x08,0x00,0x09,0x00,0xf8,0xff,0x05,0x00,0xeb,0xff,0xf7,0xff,0xf2,0xff,0xec,0xff,0x05,0x00,0x0c,0x00,0x01,0x00,0x02,0x00,0x0e,0x00,0x0b,0x00,0x1a,0x00,0xef,0xff,0x06,0x00,0x0c,0x00,0xeb,0xff,0x0f,0x00,0x0d,0x00,0xee,0xff,0xfa,0xff,0xfc,0xff,0xf9,0xff,0xf9,0xff,0x03,0x00,0x1a,0x00,0xf8,0xff,0xf9,0xff,0x08,0x00,0xfc,0xff,0x08,0x00,0xf2,0xff,0xfd,0xff,0x01,0x00,0xff,0xff,0xe7,0xff,0xf1,0xff,0x01,0x00,0xfe,0xff,0xf4,0xff,0xfd,0xff,0x1a,0x00,0xf8,0xff,0xfc,0xff,0x0b,0x00,0x08,0x00,0xf9,0xff,0x14,0x00,0xfa,0xff,0xfb,0xff,0x1d,0x00,0x16,0x00,0xf6,0xff,0x0b,0x00,0xf5,0xff,0xff,0xff,0xec,0xff,0x10,0x00,0x0a,0x00,0xf8,0xff,0xf5,0xff,0x08,0x00,0x10,0x00,0x0b,0x00,0xf5,0xff,0x0c,0x00,0x16,0x00,0x05,0x00,0x07,0x00,0xdc,0xff,0x03,0x00,0x01,0x00,0xff,0xff,0x1b,0x00,0x03,0x00,0x05,0x00,0x1d,0x00,0xf3,0xff,0xfc,0xff,0xf6,0xff,0xee,0xff,0x29,0x00,0x0a,0x00,0x19,0x00,0x0e,0x00,0x09,0x00,0xf5,0xff,0xfa,0xff,0xef,0xff,0x13,0x00,0x00,0x00,0xfe,0xff,0xef,0xff,0x07,0x00,0xfe,0xff,0xfc,0xff,0xfe,0xff,0x0a,0x00,0x24,0x00,0xfd,0xff,0xe2,0xff,0xfe,0xff,0x02,0x00,0xfd,0xff,0xfa,0xff,0x04,0x00,0x02,0x00,0x02,0x00,0x07,0x00,0xfd,0xff,0x06,0x00,0x02,0x00,0xf5,0xff,0x23,0x00,0x1b,0x00,0x00,0x00,0xef,0xff,0x06,0x00,0x07,0x00,0xfb,0xff,0xf4,0xff,0x16,0x00,0xf6,0xff,0xf7,0xff,0xf7,0xff,0xff,0xff,0x0f,0x00,0x02,0x00,0xf7,0xff,0xfe,0xff,0xfb,0xff,0x0f,0x00,0xf2,0xff,0xf5,0xff,0xfd,0xff,0xf6,0xff,0xf7,0xff,0x0b,0x00,0x0b,0x00,0x06,0x00,0x12,0x00,0xf5,0xff,0xf9,0xff,0xff,0xff,0xf6,0xff,0x11,0x00,0x03,0x00,0xf5,0xff,0xfd,0xff,0x0f,0x00,0xf8,0xff,0x02,0x00,0xf7,0xff,0xe8,0xff,0xff,0xff,0xf9,0xff,0xe9,0xff,0x06,0x00,0x07,0x00,0x05,0x00,0x02,0x00,0x00,0x00,0xf9,0xff,0xde,0xff,0xdb,0xff,0xe2,0xff,0xfb,0xff,0x18,0x00,0xf8,0xff,0x12,0x00,0x06,0x00,0x04,0x00,0x05,0x00,0x05,0x00,0x0b,0x00,0xf2,0xff,0xfd,0xff,0x09,0x00,0xf5,0xff,0x1a,0x00,0x06,0x00,0xf7,0xff,0xf0,0xff,0xff,0xff,0xea,0xff,0x0d,0x00,0xf9,0xff,0xf4,0xff,0xf8,0xff,0x00,0x00,0xfe,0xff,0x00,0x00,0xfa,0xff,0x09,0x00,0xec,0xff,0x0c,0x00,0xed,0xff,0xdc,0xff,0xf8,0xff,0xf4,0xff,0x06,0x00,0x19,0x00,0x0a,0x00,0x02,0x00,0x0b,0x00,0x24,0x00,0xf8,0xff,0x07,0x00,0x06,0x00,0x08,0x00,0xeb,0xff,0xf3,0xff,0xfa,0xff,0xfd,0xff,0xff,0xff,0xfe,0xff,0xf3,0xff,0x01,0x00,0xff,0xff,0xf1,0xff,0xe3,0xff,0x05,0x00,0x05,0x00,0x0d,0x00,0xfb,0xff,0xfc,0xff,0x04,0x00,0x02,0x00,0x09,0x00,0xee,0xff,0x02,0x00,0xf6,0xff,0xf1,0xff,0xf8,0xff,0x04,0x00,0xfd,0xff,0xf5,0xff,0xf9,0xff,0xfc,0xff,0xfa,0xff,0xe7,0xff,0x03,0x00,0xe6,0xff,0x09,0x00,0xf2,0xff,0xf4,0xff,0xfd,0xff,0xfc,0xff,0xf7,0xff,0xfb,0xff,0xf9,0xff,0x01,0x00,0x0d,0x00,0xff,0xff,0x0b,0x00,0x01,0x00,0xfe,0xff,0xfe,0xff,0x11,0x00,0x0e,0x00,0x10,0x00,0xf5,0xff,0xfb,0xff,0xfc,0xff,0xf5,0xff,0x09,0x00,0x08,0x00,0x08,0x00,0xef,0xff,0x08,0x00,0xf2,0xff,0x11,0x00,0x00,0x00,0x10,0x00,0xf6,0xff,0x18,0x00,0xfd,0xff,0x14,0x00,0xf9,0xff,0x01,0x00,0xeb,0xff,0xee,0xff,0x10,0x00,0x01,0x00,0xf0,0xff,0x08,0x00,0x01,0x00,0x03,0x00,0xf6,0xff,0x01,0x00,0x04,0x00,0xf0,0xff,0x1f,0x00,0x03,0x00,0x06,0x00,0xfa,0xff,0x0b,0x00,0xfb,0xff,0xff,0xff,0x05,0x00,0xff,0xff,0xf8,0xff,0xf9,0xff,0x12,0x00,0xfe,0xff,0x16,0x00,0xeb,0xff,0x0c,0x00,0x01,0x00,0xf5,0xff,0xef,0xff,0x01,0x00,0xf4,0xff,0xfc,0xff,0x00,0x00,0xf5,0xff,0xed,0xff,0x06,0x00,0x0f,0x00,0xf7,0xff,0xf8,0xff,0xf4,0xff,0x0a,0x00,0xee,0xff,0x14,0x00,0xf1,0xff,0x00,0x00,0x08,0x00,0xf2,0xff,0xfa,0xff,0x12,0x00,0xfe,0xff,0x0f,0x00,0x11,0x00,0xfa,0xff,0x05,0x00,0x04,0x00,0x14,0x00,0x06,0x00,0x07,0x00,0x04,0x00,0xf0,0xff,0xf2,0xff,0xff,0xff,0xf2,0xff,0x0f,0x00,0x07,0x00,0xf6,0xff,0xe9,0xff,0xfd,0xff,0x06,0x00,0x11,0x00,0xfb,0xff,0xff,0xff,0x09,0x00,0x0b,0x00,0xef,0xff,0xf7,0xff,0xfe,0xff,0xeb,0xff,0x04,0x00,0xe0,0xff,0xf3,0xff,0x00,0x00,0xe6,0xff,0xf0,0xff,0xf1,0xff,0x06,0x00,0xfd,0xff,0xfa,0xff,0x03,0x00,0xfd,0xff,0xf9,0xff,0x1a,0x00,0xfc,0xff,0x00,0x00,0xe9,0xff,0xe8,0xff,0xfb,0xff,0xf6,0xff,0xe4,0xff,0x04,0x00,0xf9,0xff,0x0a,0x00,0xff,0xff,0xed,0xff,0xe9,0xff,0xe9,0xff,0xeb,0xff,0x0f,0x00,0x04,0x00,0x14,0x00,0x01,0x00,0x19,0x00,0x12,0x00,0x05,0x00,0xf9,0xff,0xe3,0xff,0x0c,0x00,0xf5,0xff,0xe8,0xff,0xf8,0xff,0x00,0x00,0x08,0x00,0x01,0x00,0x04,0x00,0xf5,0xff,0x00,0x00,0xf3,0xff,0xf8,0xff,0xf3,0xff,0xfc,0xff,0x0f,0x00,0xff,0xff,0x0a,0x00,0x00,0x00,0xfd,0xff,0x04,0x00,0x12,0x00,0xe8,0xff,0x05,0x00,0xe7,0xff,0x08,0x00,0xf5,0xff,0xee,0xff,0x08,0x00,0x0c,0x00,0x05,0x00,0xee,0xff,0x08,0x00,0xf6,0xff,0xf8,0xff,0xf4,0xff,0x18,0x00,0x04,0x00,0xfc,0xff,0xfe,0xff,0xf9,0xff,0xf3,0xff,0xfe,0xff,0xe7,0xff,0x17,0x00,0xfa,0xff,0xfe,0xff,0x07,0x00,0x05,0x00,0x0c,0x00,0x13,0x00,0x01,0x00,0xf9,0xff,0xf4,0xff,0xe5,0xff,0xf2,0xff,0xf6,0xff,0xfc,0xff,0x0a,0x00,0x05,0x00,0x19,0x00,0x16,0x00,0xff,0xff,0xde,0xff,0x1e,0x00,0x00,0x00,0x0d,0x00,0xff,0xff,0x13,0x00,0x05,0x00,0xf2,0xff,0xf9,0xff,0xed,0xff,0xf4,0xff,0xfd,0xff,0xe7,0xff,0x04,0x00,0xfa,0xff,0xf9,0xff,0xfc,0xff,0xfb,0xff,0xf4,0xff,0x17,0x00,0xfc,0xff,0xed,0xff,0xf8,0xff,0x0e,0x00,0x1a,0x00,0x1d,0x00,0x0f,0x00,0x05,0x00,0xfa,0xff,0xf5,0xff,0xf7,0xff,0x06,0x00,0xf6,0xff,0x02,0x00,0x00,0x00,0xf2,0xff,0xef,0xff,0x08,0x00,0x14,0x00,0xf8,0xff,0x05,0x00,0x01,0x00,0xef,0xff,0x00,0x00,0xef,0xff,0x05,0x00,0xf3,0xff,0x07,0x00,0xdd,0xff,0x0b,0x00,0x0c,0x00,0x16,0x00,0xfa,0xff,0xff,0xff,0xfc,0xff,0xea,0xff,0x05,0x00,0x07,0x00,0x04,0x00,0xf3,0xff,0x00,0x00,0xef,0xff,0x0b,0x00,0x06,0x00,0xea,0xff,0x12,0x00,0x00,0x00,0x07,0x00,0xf2,0xff,0x21,0x00,0x0f,0x00,0x0d,0x00,0x0a,0x00,0x00,0x00,0xf4,0xff,0xfc,0xff,0xed,0xff,0x00,0x00,0x0d,0x00,0xf8,0xff,0xfd,0xff,0x00,0x00,0x07,0x00,0x17,0x00,0xf7,0xff,0xf2,0xff,0x12,0x00,0xe7,0xff,0x16,0x00,0x20,0x00,0x05,0x00,0xfb,0xff,0x08,0x00,0xf2,0xff,0x14,0x00,0x05,0x00,0x0d,0x00,0xf2,0xff,0xfd,0xff,0x07,0x00,0x14,0x00,0x19,0x00,0x14,0x00,0xfa,0xff,0xf7,0xff,0x16,0x00,0xe2,0xff,0xfe,0xff,0xfe,0xff,0xe6,0xff,0x00,0x00,0xf7,0xff,0xfa,0xff,0xfe,0xff,0xee,0xff,0x1f,0x00,0xff,0xff,0xff,0xff,0x05,0x00,0x0b,0x00,0xea,0xff,0x00,0x00,0xfa,0xff,0xe9,0xff,0xf3,0xff,0x00,0x00,0x03,0x00,0x04,0x00,0x13,0x00,0x1d,0x00,0xf4,0xff,0x1f,0x00,0xea,0xff,0x1a,0x00,0xf3,0xff,0x04,0x00,0xde,0xff,0xfa,0xff,0xdf,0xff,0xf8,0xff,0xfc,0xff,0x15,0x00,0x07,0x00,0x08,0x00,0xe0,0xff,0x02,0x00,0x03,0x00,0xf4,0xff,0x0c,0x00,0xe9,0xff,0xeb,0xff,0xeb,0xff,0x12,0x00,0x14,0x00,0x05,0x00,0xf8,0xff,0xf0,0xff,0xde,0xff,0x14,0x00,0xf9,0xff,0x04,0x00,0xee,0xff,0xed,0xff,0x47,0x00,0xf7,0xff,0x26,0x00,0x0f,0x00,0x32,0x00,0xb3,0xff,0x03,0x00,0xae,0xff,0xef,0xff,0x1e,0x00,0x0c,0x00,0xfe,0xff,0xff,0xff,0xe3,0xff,0x74,0x00,0xf4,0xff,0x96,0xff,0xa1,0xff,0x8f,0xff,0xf5,0xff,0x0e,0x00,0xf5,0xff,0xf6,0xff,0xfe,0xff,0xe0,0xff,0xea,0xff,0x14,0x00,0x2b,0x00,0x75,0x00,0xec,0xff,0x12,0x00,0xd5,0xff,0x03,0x00,0xed,0xff,0xf7,0xff,0x09,0x00,0xdd,0xff,0xf4,0xff,0xef,0xff,0xf0,0xff,0x30,0x00,0xfd,0xff,0x19,0x00,0xee,0xff,0x16,0x00,0xef,0xff,0x00,0x00,0xfa,0xff,0xf3,0xff,0x0c,0x00,0x14,0x00,0x1a,0x00,0x13,0x00,0x0e,0x00,0x08,0x00,0xf1,0xff,0x13,0x00,0xf4,0xff,0x07,0x00,0x00,0x00,0x03,0x00,0xf7,0xff,0xf3,0xff,0xcf,0xff,0xf0,0xff,0x0b,0x00,0x0e,0x00,0x09,0x00,0x0c,0x00,0xe7,0xff,0xf8,0xff,0x0b,0x00,0xf6,0xff,0x12,0x00,0x16,0x00,0xfb,0xff,0x0c,0x00,0xfb,0xff,0x0a,0x00,0x1e,0x00,0x2e,0x00,0xe9,0xff,0x1d,0x00,0xfc,0xff,0x1c,0x00,0xe4,0xff,0x0d,0x00,0x13,0x00,0xf9,0xff,0xf1,0xff,0xef,0xff,0x02,0x00,0x2c,0x00,0xee,0xff,0xe3,0xff,0x01,0x00,0xf7,0xff,0xe1,0xff,0xfd,0xff,0x0f,0x00,0x14,0x00,0xfb,0xff,0x09,0x00,0xfc,0xff,0xf4,0xff,0xf5,0xff,0x09,0x00,0x03,0x00,0x08,0x00,0x29,0x00,0x01,0x00,0xee,0xff,0x00,0x00,0x15,0x00,0xf7,0xff,0x0a,0x00,0x1b,0x00,0xf3,0xff,0xef,0xff,0xf3,0xff,0x05,0x00,0xe3,0xff,0x04,0x00,0x13,0x00,0x05,0x00,0xf0,0xff,0x0a,0x00,0xf3,0xff,0xf4,0xff,0x13,0x00,0x09,0x00,0x18,0x00,0x16,0x00,0xec,0xff,0x10,0x00,0x21,0x00,0x15,0x00,0x1a,0x00,0xe5,0xff,0x18,0x00,0xf2,0xff,0x0f,0x00,0x09,0x00,0xe5,0xff,0xf4,0xff,0x19,0x00,0x1e,0x00,0xf3,0xff,0x0c,0x00,0x03,0x00,0x12,0x00,0x18,0x00,0x18,0x00,0x1a,0x00,0x1f,0x00,0xf9,0xff,0xfa,0xff,0x16,0x00,0x0a,0x00,0xec,0xff,0xfc,0xff,0xe0,0xff,0x00,0x00,0xf9,0xff,0xe0,0xff,0xe2,0xff,0x07,0x00,0x0c,0x00,0x10,0x00,0x13,0x00,0xf2,0xff,0x0b,0x00,0x09,0x00,0xfc,0xff,0x0e,0x00,0xcd,0xff,0x05,0x00,0xec,0xff,0x04,0x00,0x14,0x00,0x0b,0x00,0x09,0x00,0x1e,0x00,0xe8,0xff,0x04,0x00,0xf6,0xff,0x10,0x00,0xf2,0xff,0xf9,0xff,0x01,0x00,0x10,0x00,0xf3,0xff,0x09,0x00,0x0c,0x00,0x12,0x00,0xfe,0xff,0xff,0xff,0x06,0x00,0x04,0x00,0xfb,0xff,0x0e,0x00,0xd7,0xff,0x12,0x00,0xce,0xff,0x06,0x00,0x00,0x00,0xea,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xfc,0xff,0x10,0x00,0xf1,0xff,0xea,0xff,0x15,0x00,0xeb,0xff,0xfa,0xff,0xe5,0xff,0xd5,0xff,0xf7,0xff,0x1f,0x00,0xdf,0xff,0xe1,0xff,0x13,0x00,0xea,0xff,0x10,0x00,0xf1,0xff,0x10,0x00,0xe0,0xff,0xdf,0xff,0xe9,0xff,0x17,0x00,0x05,0x00,0x2b,0x00,0xea,0xff,0x2a,0x00,0xf1,0xff,0xfa,0xff,0x0f,0x00,0xdc,0xff,0x10,0x00,0xe2,0xff,0x21,0x00,0xec,0xff,0x08,0x00,0xc3,0xff,0x10,0x00,0xe4,0xff,0x1b,0x00,0xf9,0xff,0x1d,0x00,0xf1,0xff,0x16,0x00,0xdd,0xff,0x1e,0x00,0x16,0x00,0xf6,0xff,0x11,0x00,0x06,0x00,0x08,0x00,0xff,0xff,0x06,0x00,0xf4,0xff,0x15,0x00,0xef,0xff,0xed,0xff,0xec,0xff,0xf6,0xff,0x0a,0x00,0xfe,0xff,0x12,0x00,0x13,0x00,0xde,0xff,0x14,0x00,0xf4,0xff,0x02,0x00,0xea,0xff,0x06,0x00,0xf5,0xff,0x06,0x00,0x09,0x00,0xf6,0xff,0xf3,0xff,0xfc,0xff,0xd7,0xff,0xf5,0xff,0xea,0xff,0x03,0x00,0x0e,0x00,0xea,0xff,0x10,0x00,0xf3,0xff,0x14,0x00,0x28,0x00,0x04,0x00,0xb1,0xff,0x11,0x00,0xf3,0xff,0xfb,0xff,0xe6,0xff,0xf0,0xff,0x00,0x00,0xfb,0xff,0x02,0x00,0xf9,0xff,0x1d,0x00,0xea,0xff,0x02,0x00,0xe3,0xff,0xf9,0xff,0xea,0xff,0x1d,0x00,0x10,0x00,0x1b,0x00,0xcc,0xff,0x1d,0x00,0xad,0xff,0xec,0xff,0xf3,0xff,0xed,0xff,0x1e,0x00,0x01,0x00,0xfc,0xff,0xce,0xff,0x17,0x00,0xf6,0xff,0x0f,0x00,0x06,0x00,0x0a,0x00,0xf4,0xff,0x1c,0x00,0xc9,0xff,0xd0,0xff,0x09,0x00,0xfc,0xff,0xfd,0xff,0xee,0xff,0x01,0x00,0xf1,0xff,0xfe,0xff,0xed,0xff,0xf6,0xff,0xf9,0xff,0xff,0xff,0x07,0x00,0x0f,0x00,0x04,0x00,0x0a,0x00,0x05,0x00,0x0e,0x00,0xf7,0xff,0x07,0x00,0xea,0xff,0xf6,0xff,0x04,0x00,0x24,0x00,0xf3,0xff,0x12,0x00,0xef,0xff,0xea,0xff,0xe5,0xff,0xf3,0xff,0xf1,0xff,0x14,0x00,0xef,0xff,0xcf,0xff,0xfc,0xff,0x16,0x00,0xf7,0xff,0x15,0x00,0x02,0x00,0x16,0x00,0x10,0x00,0xe9,0xff,0xfc,0xff,0x00,0x00,0x00,0x00,0x03,0x00,0x22,0x00,0x1b,0x00,0x12,0x00,0xfd,0xff,0x32,0x00,0xf0,0xff,0xef,0xff,0x19,0x00,0xde,0xff,0x03,0x00,0xfa,0xff,0x08,0x00,0xeb,0xff,0x15,0x00,0x23,0x00,0x1d,0x00,0x16,0x00,0xf2,0xff,0xd7,0xff,0x05,0x00,0xec,0xff,0xeb,0xff,0x19,0x00,0xde,0xff,0x28,0x00,0xdd,0xff,0x12,0x00,0x0d,0x00,0x09,0x00,0xe9,0xff,0x19,0x00,0xf8,0xff,0x08,0x00,0xf8,0xff,0xf4,0xff,0xee,0xff,0x15,0x00,0x3f,0x00,0x0b,0x00,0xea,0xff,0x29,0x00,0x18,0x00,0x05,0x00,0xf6,0xff,0x0c,0x00,0x05,0x00,0x10,0x00,0x2b,0x00,0x29,0x00,0xe5,0xff,0x03,0x00,0xf2,0xff,0x08,0x00,0x17,0x00,0x00,0x00,0xff,0xff,0x06,0x00,0xd3,0xff,0x15,0x00,0x11,0x00,0x25,0x00,0x1c,0x00,0x03,0x00,0x0f,0x00,0x07,0x00,0x19,0x00,0x09,0x00,0x0f,0x00,0x00,0x00,0x06,0x00,0xed,0xff,0xf2,0xff,0x18,0x00,0xfe,0xff,0xec,0xff,0xe0,0xff,0xe9,0xff,0x02,0x00,0xf5,0xff,0xe1,0xff,0x1a,0x00,0xef,0xff,0x0b,0x00,0xf2,0xff,0xfa,0xff,0xf9,0xff,0xe9,0xff,0xf0,0xff,0xde,0xff,0x10,0x00,0x1c,0x00,0xfe,0xff,0x0e,0x00,0x05,0x00,0x11,0x00,0xe3,0xff,0xfb,0xff,0xfd,0xff,0xf2,0xff,0xf0,0xff,0xe8,0xff,0xfe,0xff,0xe9,0xff,0xeb,0xff,0xf7,0xff,0xf0,0xff,0xf7,0xff,0xc3,0xff,0x23,0x00,0x2b,0x00,0x0d,0x00,0x1d,0x00,0xfe,0xff,0x25,0x00,0x28,0x00,0xf1,0xff,0x45,0x00,0xe6,0xff,0xf2,0xff,0xcb,0xff,0x0a,0x00,0xf8,0xff,0x05,0x00,0x0f,0x00,0x29,0x00,0x03,0x00,0xf4,0xff,0xe5,0xff,0x55,0x00,0xf2,0xff,0x7f,0x00,0xfd,0xff,0x33,0x00,0xef,0xff,0x29,0x00,0x1a,0x00,0xf5,0xff,0x19,0x00,0x08,0x00,0xf8,0xff,0xe9,0xff,0xf7,0xff,0xfe,0xff,0x0d,0x00,0x09,0x00,0x08,0x00,0x16,0x00,0x12,0x00,0x12,0x00,0xee,0xff,0x11,0x00,0x06,0x00,0x0c,0x00,0xec,0xff,0xfd,0xff,0x1f,0x00,0xf5,0xff,0xf2,0xff,0x02,0x00,0x1e,0x00,0xed,0xff,0x0b,0x00,0xf6,0xff,0x0c,0x00,0xfa,0xff,0xe5,0xff,0x00,0x00,0x0d,0x00,0x00,0x00,0x03,0x00,0x0a,0x00,0xf4,0xff,0x11,0x00,0xd6,0xff,0x2b,0x00,0xdb,0xff,0xd9,0xff,0xf9,0xff,0xec,0xff,0x06,0x00,0x02,0x00,0x05,0x00,0xe7,0xff,0x28,0x00,0xd0,0xff,0xf7,0xff,0x1f,0x00,0xfc,0xff,0xf6,0xff,0x28,0x00,0x0d,0x00,0x18,0x00,0x07,0x00,0x23,0x00,0xdd,0xff,0x0c,0x00,0xe4,0xff,0x16,0x00,0x10,0x00,0xf4,0xff,0x02,0x00,0xee,0xff,0xfe,0xff,0xfc,0xff,0x22,0x00,0xed,0xff,0x18,0x00,0x12,0x00,0x1b,0x00,0xf3,0xff,0xf8,0xff,0xff,0xff,0x0b,0x00,0xe8,0xff,0xf8,0xff,0xf9,0xff,0xf4,0xff,0x0f,0x00,0xf4,0xff,0x11,0x00,0xe6,0xff,0xee,0xff,0xe8,0xff,0x1c,0x00,0xed,0xff,0x07,0x00,0x13,0x00,0x08,0x00,0x08,0x00,0xed,0xff,0x16,0x00,0x0f,0x00,0x1e,0x00,0xf9,0xff,0x19,0x00,0x0d,0x00,0x0c,0x00,0xd8,0xff,0xfe,0xff,0xdc,0xff,0x12,0x00,0xea,0xff,0xfc,0xff,0x12,0x00,0x10,0x00,0x18,0x00,0xea,0xff,0x17,0x00,0xd6,0xff,0xf5,0xff,0xe6,0xff,0x01,0x00,0xdc,0xff,0x23,0x00,0xf1,0xff,0x1d,0x00,0xf5,0xff,0x18,0x00,0xe2,0xff,0x14,0x00,0xd4,0xff,0xed,0xff,0x0b,0x00,0x1a,0x00,0x11,0x00,0x09,0x00,0xe0,0xff,0x0d,0x00,0x14,0x00,0x0e,0x00,0x10,0x00,0x11,0x00,0x1a,0x00,0xfd,0xff,0x11,0x00,0xf0,0xff,0xf2,0xff,0xef,0xff,0x09,0x00,0xe9,0xff,0x0a,0x00,0xe2,0xff,0x07,0x00,0x0a,0x00,0xe3,0xff,0x1a,0x00,0x0b,0x00,0xf2,0xff,0xea,0xff,0x02,0x00,0x12,0x00,0x09,0x00,0x07,0x00,0x07,0x00,0x08,0x00,0xf9,0xff,0x06,0x00,0x03,0x00,0x25,0x00,0xd0,0xff,0x0c,0x00,0xf5,0xff,0xdc,0xff,0x06,0x00,0x09,0x00,0xff,0xff,0x03,0x00,0x0f,0x00,0xb5,0xff,0x0b,0x00,0x19,0x00,0xf5,0xff,0xf2,0xff,0x0d,0x00,0xfb,0xff,0xfb,0xff,0x07,0x00,0x11,0x00,0xf2,0xff,0xeb,0xff,0xfd,0xff,0x0f,0x00,0x01,0x00,0x0a,0x00,0xf7,0xff,0xe3,0xff,0x33,0x00,0x22,0x00,0x46,0x00,0x0a,0x00,0x13,0x00,0x04,0x00,0x18,0x00,0x0a,0x00,0xeb,0xff,0xf9,0xff,0xe8,0xff,0x09,0x00,0xe3,0xff,0x04,0x00,0xf1,0xff,0xea,0xff,0xd5,0xff,0xf8,0xff,0xf0,0xff,0xf5,0xff,0xea,0xff,0x0a,0x00,0x09,0x00,0x06,0x00,0xfb,0xff,0x07,0x00,0x01,0x00,0x06,0x00,0xf5,0xff,0xf6,0xff,0x0a,0x00,0x20,0x00,0x0b,0x00,0xed,0xff,0xd7,0xff,0x09,0x00,0xee,0xff,0xfa,0xff,0x03,0x00,0x17,0x00,0xec,0xff,0x0b,0x00,0x22,0x00,0xfb,0xff,0xee,0xff,0xf4,0xff,0xfc,0xff,0xf2,0xff,0x11,0x00,0xed,0xff,0x18,0x00,0x07,0x00,0x19,0x00,0x29,0x00,0xf5,0xff,0x2f,0x00,0x00,0x00,0x14,0x00,0x10,0x00,0xfa,0xff,0x11,0x00,0xe6,0xff,0x0d,0x00,0x01,0x00,0x14,0x00,0x04,0x00,0x21,0x00,0xf2,0xff,0x1f,0x00,0x28,0x00,0xe1,0xff,0x03,0x00,0xf1,0xff,0xde,0xff,0x17,0x00,0xf1,0xff,0x14,0x00,0x07,0x00,0x0b,0x00,0x03,0x00,0xd8,0xff,0x01,0x00,0xef,0xff,0xf7,0xff,0x05,0x00,0x06,0x00,0xf7,0xff,0x0c,0x00,0xf8,0xff,0xf3,0xff,0xec,0xff,0x02,0x00,0xec,0xff,0x20,0x00,0xde,0xff,0x00,0x00,0xf7,0xff,0x17,0x00,0x03,0x00,0x16,0x00,0xe8,0xff,0xfe,0xff,0xd5,0xff,0x31,0x00,0x0a,0x00,0x1a,0x00,0xd4,0xff,0x03,0x00,0x0a,0x00,0x06,0x00,0xf1,0xff,0xe7,0xff,0xfd,0xff,0xeb,0xff,0x23,0x00,0x18,0x00,0xf9,0xff,0xe8,0xff,0x0b,0x00,0xe8,0xff,0x0c,0x00,0xe2,0xff,0x14,0x00,0xeb,0xff,0x1f,0x00,0xfb,0xff,0x05,0x00,0x17,0x00,0xfb,0xff,0xe4,0xff,0xfb,0xff,0x12,0x00,0x1b,0x00,0xf8,0xff,0xeb,0xff,0x06,0x00,0x22,0x00,0x07,0x00,0x1c,0x00,0xfe,0xff,0x07,0x00,0x04,0x00,0x04,0x00,0xff,0xff,0x15,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x1d,0x00,0x0d,0x00,0x01,0x00,0xd7,0xff,0xfa,0xff,0xd1,0xff,0x0d,0x00,0x04,0x00,0x09,0x00,0x04,0x00,0xf3,0xff,0xee,0xff,0x0b,0x00,0x16,0x00,0x01,0x00,0xfc,0xff,0x1d,0x00,0xf2,0xff,0x06,0x00,0xf7,0xff,0xcb,0xff,0x02,0x00,0xfb,0xff,0xd8,0xff,0xfa,0xff,0x01,0x00,0x1a,0x00,0x21,0x00,0xf8,0xff,0x2d,0x00,0xf6,0xff,0xef,0xff,0x1c,0x00,0x05,0x00,0xe6,0xff,0x29,0x00,0xec,0xff,0x0d,0x00,0xf2,0xff,0x13,0x00,0x2c,0x00,0x12,0x00,0xeb,0xff,0xec,0xff,0xfc,0xff,0xf9,0xff,0x0e,0x00,0x0a,0x00,0xf1,0xff,0xf7,0xff,0xfc,0xff,0xfb,0xff,0x22,0x00,0xfc,0xff,0x11,0x00,0x21,0x00,0xf4,0xff,0xf4,0xff,0x12,0x00,0xff,0xff,0xf6,0xff,0x07,0x00,0xe8,0xff,0xee,0xff,0x1f,0x00,0xf3,0xff,0x29,0x00,0xf1,0xff,0x00,0x00,0xe6,0xff,0x0a,0x00,0x02,0x00,0xf5,0xff,0xf7,0xff,0x15,0x00,0xf4,0xff,0xf0,0xff,0x10,0x00,0x07,0x00,0xf0,0xff,0xf8,0xff,0x32,0x00,0x25,0x00,0x08,0x00,0xdd,0xff,0x27,0x00,0xec,0xff,0x2e,0x00,0xef,0xff,0x0f,0x00,0x1c,0x00,0xc8,0xff,0xf9,0xff,0xdc,0xff,0x19,0x00,0x30,0x00,0x1a,0x00,0x4c,0x00,0xdb,0xff,0xca,0xff,0xf6,0xff,0xfa,0xff,0x2b,0x00,0xe3,0xff,0xf8,0xff,0xf3,0xff,0x13,0x00,0xf2,0xff,0xee,0xff,0x0c,0x00,0xef,0xff,0x0b,0x00,0x0d,0x00,0xf9,0xff,0xdf,0xff,0x17,0x00,0x1d,0x00,0xe6,0xff,0x16,0x00,0xf2,0xff,0xfd,0xff,0x14,0x00,0x26,0x00,0x0b,0x00,0x05,0x00,0x1c,0x00,0xde,0xff,0xe9,0xff,0xf4,0xff,0xeb,0xff,0x15,0x00,0xe9,0xff,0x04,0x00,0xe6,0xff,0x02,0x00,0x08,0x00,0xf2,0xff,0xdf,0xff,0x03,0x00,0x00,0x00,0xe7,0xff,0xff,0xff,0xe1,0xff,0x0b,0x00,0xf5,0xff,0xe6,0xff,0xfa,0xff,0x15,0x00,0x06,0x00,0x19,0x00,0xf4,0xff,0x19,0x00,0x11,0x00,0x12,0x00,0x02,0x00,0xdb,0xff,0x0f,0x00,0xe2,0xff,0x1d,0x00,0x15,0x00,0x02,0x00,0x28,0x00,0x1a,0x00,0xd3,0xff,0xf4,0xff,0xf4,0xff,0x21,0x00,0xf1,0xff,0x39,0x00,0x03,0x00,0x18,0x00,0xf2,0xff,0x0e,0x00,0xe3,0xff,0xeb,0xff,0xfa,0xff,0x02,0x00,0x14,0x00,0xfb,0xff,0xe0,0xff,0x69,0x00,0xf0,0xff,0x1c,0x00,0xf2,0xff,0xf0,0xff,0xf1,0xff,0xe7,0xff,0xfd,0xff,0x06,0x00,0x18,0x00,0x0a,0x00,0xf9,0xff,0xdf,0xff,0x06,0x00,0x05,0x00,0xdc,0xff,0xd9,0xff,0x01,0x00,0xed,0xff,0xf8,0xff,0xf5,0xff,0xf7,0xff,0xde,0xff,0x10,0x00,0x06,0x00,0x46,0x00,0xdc,0xff,0x0d,0x00,0x2b,0x00,0xf6,0xff,0x4b,0x00,0x12,0x00,0xfc,0xff,0xd8,0xff,0x32,0x00,0x32,0x00,0xce,0xff,0x02,0x00,0xda,0xff,0x24,0x00,0xf4,0xff,0x19,0x00,0x0d,0x00,0xe8,0xff,0x14,0x00,0x13,0x00,0xe3,0xff,0xf3,0xff,0xee,0xff,0xdc,0xff,0x19,0x00,0xcf,0xff,0x3e,0x00,0x14,0x00,0xdb,0xff,0x90,0xff,0x04,0x00,0x15,0x00,0x17,0x00,0xe7,0xff,0x39,0x00,0xf6,0xff,0x20,0x00,0x00,0x00,0x01,0x00,0xe9,0xff,0x03,0x00,0x10,0x00,0xc6,0xff,0xfa,0xff,0xf7,0xff,0xe9,0xff,0xf6,0xff,0xf3,0xff,0xfe,0xff,0xdd,0xff,0xf9,0xff,0x11,0x00,0xfa,0xff,0x09,0x00,0xe9,0xff,0xd6,0xff,0x07,0x00,0x00,0x00,0x17,0x00,0x02,0x00,0xfd,0xff,0xf7,0xff,0xfd,0xff,0x09,0x00,0xf3,0xff,0x11,0x00,0x21,0x00,0x09,0x00,0x12,0x00,0x0e,0x00,0xfd,0xff,0xf2,0xff,0xf7,0xff,0x0a,0x00,0xe5,0xff,0xf9,0xff,0xfb,0xff,0xed,0xff,0x03,0x00,0x0f,0x00,0x09,0x00,0x08,0x00,0x0e,0x00,0x09,0x00,0xf7,0xff,0x0c,0x00,0xf4,0xff,0xe8,0xff,0xfb,0xff,0x06,0x00,0x10,0x00,0x13,0x00,0xf4,0xff,0xf9,0xff,0x1d,0x00,0xf9,0xff,0xeb,0xff,0x05,0x00,0x10,0x00,0x02,0x00,0x10,0x00,0x0b,0x00,0x03,0x00,0xde,0xff,0x0a,0x00,0x0a,0x00,0xdd,0xff,0x0d,0x00,0xfd,0xff,0x1c,0x00,0x03,0x00,0xff,0xff,0x0b,0x00,0xfc,0xff,0xfe,0xff,0x05,0x00,0xfe,0xff,0x00,0x00,0xf3,0xff,0xde,0xff,0xf4,0xff,0xe8,0xff,0x12,0x00,0x10,0x00,0xfa,0xff,0xfb,0xff,0xf8,0xff,0x08,0x00,0x09,0x00,0xfd,0xff,0x00,0x00,0x01,0x00,0x12,0x00,0xf2,0xff,0x04,0x00,0xf2,0xff,0xec,0xff,0x0f,0x00,0x08,0x00,0x15,0x00,0xfa,0xff,0xf7,0xff,0xef,0xff,0xdb,0xff,0xf7,0xff,0xf4,0xff,0xfc,0xff,0x07,0x00,0xdb,0xff,0x09,0x00,0xea,0xff,0xfa,0xff,0x00,0x00,0xf5,0xff,0x13,0x00,0xf9,0xff,0xf7,0xff,0xee,0xff,0xf2,0xff,0x06,0x00,0xf5,0xff,0x00,0x00,0x12,0x00,0x09,0x00,0x11,0x00,0x02,0x00,0x00,0x00,0xf5,0xff,0xec,0xff,0xfe,0xff,0xdb,0xff,0x13,0x00,0xfa,0xff,0x09,0x00,0xff,0xff,0xe3,0xff,0x05,0x00,0xf1,0xff,0x0a,0x00,0x08,0x00,0x11,0x00,0xfa,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xfe,0xff,0x0b,0x00,0x15,0x00,0xf7,0xff,0xfb,0xff,0x10,0x00,0xf5,0xff,0x1a,0x00,0xf6,0xff,0x02,0x00,0x22,0x00,0x0b,0x00,0xf7,0xff,0x0c,0x00,0x16,0x00,0xed,0xff,0x0c,0x00,0x02,0x00,0x14,0x00,0xff,0xff,0x07,0x00,0x01,0x00,0x0d,0x00,0xff,0xff,0xfc,0xff,0xf7,0xff,0x09,0x00,0xee,0xff,0xf4,0xff,0xf5,0xff,0xf8,0xff,0xfc,0xff,0xe3,0xff,0x0f,0x00,0xf1,0xff,0xf7,0xff,0xf8,0xff,0x0a,0x00,0x06,0x00,0x0a,0x00,0xf7,0xff,0x0b,0x00,0x00,0x00,0x0f,0x00,0x0d,0x00,0x05,0x00,0xf8,0xff,0x03,0x00,0xf9,0xff,0x08,0x00,0x12,0x00,0xfd,0xff,0xf3,0xff,0xfd,0xff,0xde,0xff,0xfb,0xff,0xf5,0xff,0x03,0x00,0x01,0x00,0xe4,0xff,0xef,0xff,0xf4,0xff,0xf8,0xff,0xf3,0xff,0xfd,0xff,0x0f,0x00,0x17,0x00,0x00,0x00,0xfc,0xff,0x0a,0x00,0x09,0x00,0x2d,0x00,0xfa,0xff,0xfb,0xff,0xf7,0xff,0x0e,0x00,0xff,0xff,0x02,0x00,0x05,0x00,0xee,0xff,0x05,0x00,0x05,0x00,0xeb,0xff,0xfd,0xff,0x19,0x00,0xf2,0xff,0xe7,0xff,0xfb,0xff,0x0a,0x00,0x08,0x00,0x05,0x00,0xef,0xff,0xfa,0xff,0x03,0x00,0xf2,0xff,0xf4,0xff,0x00,0x00,0x0f,0x00,0xed,0xff,0xf4,0xff,0x04,0x00,0xf5,0xff,0xf5,0xff,0x00,0x00,0x00,0x00,0xfb,0xff,0x0f,0x00,0x0e,0x00,0xe8,0xff,0x0b,0x00,0xf5,0xff,0x26,0x00,0x04,0x00,0x06,0x00,0xf9,0xff,0xf9,0xff,0xf4,0xff,0x03,0x00,0x06,0x00,0xff,0xff,0x12,0x00,0xfd,0xff,0xfe,0xff,0x11,0x00,0xfb,0xff,0xde,0xff,0x05,0x00,0xf4,0xff,0xf7,0xff,0x0b,0x00,0x05,0x00,0xff,0xff,0xf5,0xff,0xe4,0xff,0xf7,0xff,0x16,0x00,0x0c,0x00,0x10,0x00,0xfe,0xff,0xfe,0xff,0x10,0x00,0x00,0x00,0xf8,0xff,0x15,0x00,0x07,0x00,0x00,0x00,0x0a,0x00,0xfc,0xff,0x20,0x00,0xee,0xff,0xdd,0xff,0xfb,0xff,0xe8,0xff,0x0c,0x00,0xf4,0xff,0xe6,0xff,0xf1,0xff,0x06,0x00,0xf4,0xff,0xeb,0xff,0xf5,0xff,0x09,0x00,0x09,0x00,0xfe,0xff,0xf9,0xff,0xe4,0xff,0x01,0x00,0x06,0x00,0xef,0xff,0xfb,0xff,0x07,0x00,0x11,0x00,0x0b,0x00,0x0c,0x00,0x10,0x00,0x02,0x00,0x00,0x00,0xf4,0xff,0x18,0x00,0xff,0xff,0xfd,0xff,0x02,0x00,0x02,0x00,0xf6,0xff,0xef,0xff,0x03,0x00,0x15,0x00,0xf9,0xff,0xf9,0xff,0xed,0xff,0xfc,0xff,0xff,0xff,0xf7,0xff,0x0d,0x00,0xff,0xff,0xf7,0xff,0xfc,0xff,0xf1,0xff,0xff,0xff,0x14,0x00,0x10,0x00,0xe9,0xff,0xfc,0xff,0x1d,0x00,0x07,0x00,0x04,0x00,0xf4,0xff,0xff,0xff,0xfc,0xff,0x06,0x00,0xef,0xff,0xfb,0xff,0x03,0x00,0xf6,0xff,0xe8,0xff,0xfa,0xff,0x19,0x00,0x05,0x00,0xff,0xff,0x0c,0x00,0xe9,0xff,0xed,0xff,0xf4,0xff,0xf8,0xff,0x00,0x00,0x19,0x00,0xff,0xff,0xf6,0xff,0xfc,0xff,0xe7,0xff,0x08,0x00,0xfe,0xff,0xea,0xff,0x09,0x00,0x1e,0x00,0x08,0x00,0xf3,0xff,0x06,0x00,0x02,0x00,0xed,0xff,0x05,0x00,0xeb,0xff,0xeb,0xff,0xfc,0xff,0xfc,0xff,0xf5,0xff,0xf2,0xff,0xfb,0xff,0xe9,0xff,0x0b,0x00,0x04,0x00,0x0e,0x00,0xf7,0xff,0xff,0xff,0xeb,0xff,0xee,0xff,0x06,0x00,0x0c,0x00,0x09,0x00,0xfb,0xff,0xf8,0xff,0xd1,0xff,0xf8,0xff,0xfa,0xff,0xfb,0xff,0xe9,0xff,0x0c,0x00,0x07,0x00,0xf2,0xff,0x02,0x00,0xf6,0xff,0x09,0x00,0x08,0x00,0xe8,0xff,0xf7,0xff,0xfa,0xff,0x16,0x00,0xff,0xff,0xe5,0xff,0x01,0x00,0xdf,0xff,0x0b,0x00,0x12,0x00,0xfd,0xff,0xeb,0xff,0xe7,0xff,0x0a,0x00,0x03,0x00,0xf7,0xff,0xfd,0xff,0x06,0x00,0xe9,0xff,0xf8,0xff,0x03,0x00,0xfd,0xff,0xf9,0xff,0x20,0x00,0xed,0xff,0x0c,0x00,0xf9,0xff,0x20,0x00,0x08,0x00,0x10,0x00,0xf1,0xff,0x03,0x00,0xed,0xff,0xf3,0xff,0xff,0xff,0x0e,0x00,0x00,0x00,0xf7,0xff,0x01,0x00,0x0b,0x00,0x01,0x00,0xf4,0xff,0xf7,0xff,0xf2,0xff,0xef,0xff,0xf2,0xff,0xe5,0xff,0xf9,0xff,0xff,0xff,0x08,0x00,0xf3,0xff,0xff,0xff,0xf9,0xff,0xf6,0xff,0x01,0x00,0xf0,0xff,0x10,0x00,0x04,0x00,0xfa,0xff,0xf0,0xff,0x08,0x00,0xf4,0xff,0x08,0x00,0x06,0x00,0xf1,0xff,0x17,0x00,0xfd,0xff,0x1c,0x00,0xec,0xff,0xea,0xff,0xee,0xff,0x09,0x00,0x0a,0x00,0x0e,0x00,0xf1,0xff,0xf7,0xff,0xe1,0xff,0x0d,0x00,0xff,0xff,0xfd,0xff,0xfc,0xff,0x06,0x00,0xf8,0xff,0x04,0x00,0xfc,0xff,0xec,0xff,0x19,0x00,0xf3,0xff,0xfb,0xff,0x0f,0x00,0xf5,0xff,0xfa,0xff,0x05,0x00,0xfa,0xff,0xf2,0xff,0x08,0x00,0x0b,0x00,0x14,0x00,0xfb,0xff,0xf2,0xff,0x01,0x00,0xe6,0xff,0x04,0x00,0xd9,0xff,0x00,0x00,0xfe,0xff,0x08,0x00,0xe3,0xff,0x02,0x00,0xe3,0xff,0xe7,0xff,0xf9,0xff,0x02,0x00,0xff,0xff,0xf9,0xff,0x07,0x00,0x12,0x00,0x00,0x00,0x15,0x00,0xf7,0xff,0xe7,0xff,0x06,0x00,0x06,0x00,0xff,0xff,0x07,0x00,0x2e,0x00,0x10,0x00,0x05,0x00,0x03,0x00,0x12,0x00,0xfc,0xff,0x00,0x00,0xf6,0xff,0xe6,0xff,0xf9,0xff,0x05,0x00,0x09,0x00,0xf8,0xff,0xf8,0xff,0xfa,0xff,0xf7,0xff,0x07,0x00,0xf1,0xff,0xfb,0xff,0x01,0x00,0x01,0x00,0xf6,0xff,0x05,0x00,0xea,0xff,0xf6,0xff,0x19,0x00,0xe7,0xff,0x00,0x00,0x14,0x00,0xf7,0xff,0x15,0x00,0x0c,0x00,0x14,0x00,0xfa,0xff,0x04,0x00,0xfd,0xff,0x13,0x00,0xfc,0xff,0xe9,0xff,0xfd,0xff,0xf9,0xff,0xf7,0xff,0x01,0x00,0x00,0x00,0x13,0x00,0xff,0xff,0xe7,0xff,0xec,0xff,0x08,0x00,0xfd,0xff,0xfc,0xff,0x04,0x00,0x09,0x00,0xf3,0xff,0xf6,0xff,0xf0,0xff,0xfc,0xff,0x16,0x00,0xff,0xff,0xea,0xff,0x01,0x00,0xfd,0xff,0xfd,0xff,0xfb,0xff,0x01,0x00,0xfe,0xff,0x08,0x00,0x0c,0x00,0x03,0x00,0xf8,0xff,0x02,0x00,0xf1,0xff,0xf2,0xff,0xff,0xff,0xeb,0xff,0xfe,0xff,0xe5,0xff,0xe7,0xff,0xea,0xff,0xf2,0xff,0xe7,0xff,0xea,0xff,0x03,0x00,0xfb,0xff,0xff,0xff,0xf3,0xff,0x05,0x00,0xf7,0xff,0xea,0xff,0xf5,0xff,0xf2,0xff,0x0d,0x00,0x05,0x00,0xf7,0xff,0xf8,0xff,0x0f,0x00,0x23,0x00,0xf9,0xff,0x08,0x00,0x02,0x00,0x0f,0x00,0x01,0x00,0xdf,0xff,0x00,0x00,0x00,0x00,0xfb,0xff,0xf0,0xff,0x06,0x00,0x10,0x00,0x11,0x00,0xe8,0xff,0xfd,0xff,0xeb,0xff,0xf4,0xff,0xf9,0xff,0x05,0x00,0x09,0x00,0x02,0x00,0x09,0x00,0xe9,0xff,0xf8,0xff,0x06,0x00,0xf1,0xff,0xef,0xff,0x06,0x00,0xf9,0xff,0xff,0xff,0x05,0x00,0x19,0x00,0x04,0x00,0xfe,0xff,0x11,0x00,0xed,0xff,0xf8,0xff,0xe6,0xff,0xfd,0xff,0xdd,0xff,0xfc,0xff,0xe6,0xff,0xfd,0xff,0xe7,0xff,0xec,0xff,0xe8,0xff,0xef,0xff,0xfe,0xff,0xf2,0xff,0xf9,0xff,0xff,0xff,0x16,0x00,0xf4,0xff,0xfb,0xff,0xfc,0xff,0xf5,0xff,0xfe,0xff,0xf7,0xff,0x06,0x00,0x08,0x00,0xff,0xff,0x07,0x00,0x02,0x00,0x12,0x00,0x08,0x00,0x0b,0x00,0x09,0x00,0xf7,0xff,0xf9,0xff,0x17,0x00,0xf1,0xff,0xfd,0xff,0xf8,0xff,0x02,0x00,0xff,0xff,0xf4,0xff,0xf8,0xff,0xf5,0xff,0xfa,0xff,0x07,0x00,0xf8,0xff,0x02,0x00,0x01,0x00,0x08,0x00,0xf9,0xff,0x01,0x00,0x01,0x00,0xf1,0xff,0x12,0x00,0xea,0xff,0xfa,0xff,0x06,0x00,0xf4,0xff,0x12,0x00,0x04,0x00,0x1a,0x00,0xf7,0xff,0x07,0x00,0xfc,0xff,0x19,0x00,0x00,0x00,0xed,0xff,0xf9,0xff,0xe4,0xff,0xfb,0xff,0xfd,0xff,0xff,0xff,0xf7,0xff,0x06,0x00,0xe3,0xff,0xf6,0xff,0xed,0xff,0xef,0xff,0xf9,0xff,0x07,0x00,0x10,0x00,0xed,0xff,0xff,0xff,0xea,0xff,0xf6,0xff,0x0b,0x00,0xee,0xff,0x0e,0x00,0x02,0x00,0xfd,0xff,0xfc,0xff,0x0c,0x00,0x00,0x00,0x1c,0x00,0x0a,0x00,0x08,0x00,0x19,0x00,0xfc,0xff,0xed,0xff,0xf9,0xff,0x07,0x00,0xf3,0xff,0x03,0x00,0x04,0x00,0xe3,0xff,0xfe,0xff,0x06,0x00,0xef,0xff,0x0b,0x00,0xf2,0xff,0xff,0xff,0x03,0x00,0x13,0x00,0x00,0x00,0x0c,0x00,0xfc,0xff,0xef,0xff,0x0b,0x00,0xfe,0xff,0xe8,0xff,0xff,0xff,0xfc,0xff,0x0e,0x00,0x03,0x00,0x04,0x00,0x0e,0x00,0x11,0x00,0x15,0x00,0x00,0x00,0xf8,0xff,0xf4,0xff,0xf4,0xff,0x0a,0x00,0xef,0xff,0x01,0x00,0xf4,0xff,0xfa,0xff,0xf3,0xff,0xfb,0xff,0xf8,0xff,0xe7,0xff,0xe7,0xff,0x02,0x00,0x04,0x00,0x02,0x00,0xf8,0xff,0x0d,0x00,0x06,0x00,0xf7,0xff,0x0e,0x00,0x1e,0x00,0xe5,0xff,0x06,0x00,0xf4,0xff,0x19,0x00,0x0b,0x00,0x03,0x00,0xf0,0xff,0x0f,0x00,0xf9,0xff,0xfa,0xff,0xfa,0xff,0x1a,0x00,0xfa,0xff,0x01,0x00,0xf3,0xff,0xf3,0xff,0xfe,0xff,0xdc,0xff,0x0a,0x00,0xff,0xff,0xf8,0xff,0xf2,0xff,0xfa,0xff,0xf7,0xff,0x02,0x00,0x18,0x00,0xf8,0xff,0x0e,0x00,0xeb,0xff,0xf1,0xff,0x08,0x00,0x0b,0x00,0xfa,0xff,0x05,0x00,0xfe,0xff,0x0f,0x00,0x05,0x00,0x00,0x00,0xeb,0xff,0x13,0x00,0xf1,0xff,0xf9,0xff,0xf5,0xff,0xea,0xff,0xf1,0xff,0x07,0x00,0xe7,0xff,0xd0,0xff,0xf0,0xff,0xeb,0xff,0xe8,0xff,0x0b,0x00,0x07,0x00,0xff,0xff,0xf3,0xff,0x05,0x00,0xfd,0xff,0x14,0x00,0xf3,0xff,0x07,0x00,0xe9,0xff,0xec,0xff,0xef,0xff,0x06,0x00,0x08,0x00,0xf1,0xff,0xf9,0xff,0x09,0x00,0xfe,0xff,0x00,0x00,0xfd,0xff,0x0c,0x00,0x07,0x00,0xf4,0xff,0xf4,0xff,0xe8,0xff,0xe9,0xff,0xea,0xff,0xe0,0xff,0xeb,0xff,0xee,0xff,0xdb,0xff,0x00,0x00,0x0b,0x00,0x0a,0x00,0x03,0x00,0xf3,0xff,0x0b,0x00,0x00,0x00,0x25,0x00,0xf6,0xff,0x0b,0x00,0x1b,0x00,0xe4,0xff,0x08,0x00,0x1f,0x00,0xfb,0xff,0xf1,0xff,0xf9,0xff,0xef,0xff,0x04,0x00,0x18,0x00,0x0d,0x00,0x1a,0x00,0x01,0x00,0xfd,0xff,0xf9,0xff,0xfd,0xff,0xdc,0xff,0x22,0x00,0xe2,0xff,0xf9,0xff,0xec,0xff,0xee,0xff,0xe1,0xff,0x15,0x00,0xf7,0xff,0xfc,0xff,0xe6,0xff,0x05,0x00,0x00,0x00,0x27,0x00,0xf0,0xff,0x1e,0x00,0x00,0x00,0xd8,0xff,0x09,0x00,0x05,0x00,0xfb,0xff,0xeb,0xff,0xe2,0xff,0xc1,0xff,0x4c,0x00,0x1e,0x00,0xef,0xff,0x1d,0x00,0x10,0x00,0xda,0xff,0xcd,0xff,0x04,0x00,0xad,0xff,0xfc,0xff,0xbb,0xff,0x24,0x00,0x81,0xff,0xd4,0xff,0xeb,0xff,0x0b,0x00,0x48,0x00,0xd7,0xff,0xd6,0xff,0x40,0x00,0x0a,0x00,0x1a,0x00,0x1c,0x00,0x56,0x00,0xd0,0xff,0x33,0x00,0x24,0x00,0x46,0x00,0xd8,0xff,0x06,0x00,0xc2,0xff,0xe7,0xff,0x33,0x00,0xe2,0xff,0x38,0x00,0xe6,0xff,0x25,0x00,0x18,0x00,0x7f,0x00,0xc6,0xff,0x34,0x00,0xe2,0xff,0xb9,0xff,0xda,0xff,0x29,0x00,0xdc,0xff,0x43,0x00,0xc4,0xff,0xbd,0xff,0x25,0x00,0xb5,0xff,0x43,0x00,0x5b,0x00,0x30,0x00,0x0c,0x00,0x36,0x00,0x04,0x00,0xc4,0xff,0xef,0xff,0x05,0x00,0x42,0x00,0xa8,0xff,0x5a,0x00,0x49,0x00,0x99,0xff,0x43,0x00,0xbc,0xff,0x50,0x00,0xc5,0xff,0xf4,0xff,0xe1,0xff,0xfa,0xff,0xca,0xff,0x1f,0x00,0x3f,0x00,0x23,0x00,0xb0,0xff,0x2b,0x00,0x0b,0x00,0x06,0x00,0x1f,0x00,0xc8,0xff,0x18,0x00,0xd5,0xff,0xca,0xff,0xd9,0xff,0x9a,0xff,0xcf,0xff,0xc7,0x79,0x6b,0x8a \ No newline at end of file diff --git a/config/_default_cfg_src_/res/ring/SOUND_RING_16000.txt b/config/_default_cfg_src_/res/ring/SOUND_RING_16000.txt new file mode 100644 index 0000000..42879e0 --- /dev/null +++ b/config/_default_cfg_src_/res/ring/SOUND_RING_16000.txt @@ -0,0 +1,17825 @@ +0, +0, +-1, +-1, +0, +1, +1, +4, +2, +1, +1, +2, +-2, +-3, +0, +1, +-1, +-3, +0, +1, +-1, +0, +0, +0, +0, +-1, +2, +0, +0, +0, +4, +0, +2, +-2, +0, +-2, +0, +1, +-2, +0, +3, +2, +0, +1, +1, +-1, +-1, +-1, +0, +0, +2, +3, +0, +1, +-1, +0, +0, +2, +-2, +0, +-2, +-1, +-1, +0, +-4, +0, +0, +0, +0, +-4, +2, +0, +1, +1, +2, +6, +4, +-4, +0, +1, +-2, +1, +0, +-1, +0, +0, +1, +1, +2, +0, +0, +6, +0, +0, +-1, +-3, +2, +-2, +0, +0, +4, +2, +1, +2, +2, +0, +1, +-2, +0, +3, +1, +0, +0, +0, +-2, +2, +-1, +4, +0, +0, +0, +1, +-1, +0, +1, +-3, +2, +0, +0, +0, +0, +0, +0, +-1, +0, +4, +-1, +3, +4, +0, +4, +-2, +0, +-1, +0, +2, +0, +1, +0, +1, +2, +1, +-2, +1, +0, +-3, +-1, +0, +-2, +1, +0, +0, +1, +3, +0, +1, +2, +-1, +3, +0, +1, +2, +-2, +0, +-1, +-1, +0, +0, +0, +-1, +1, +4, +-1, +3, +-4, +2, +1, +0, +-3, +0, +1, +-2, +0, +1, +-1, +1, +-1, +1, +0, +0, +-1, +-3, +4, +-3, +-1, +-3, +-1, +-4, +1, +3, +0, +0, +1, +2, +-2, +1, +-1, +1, +-1, +1, +0, +0, +1, +0, +0, +2, +-1, +-1, +-1, +-3, +2, +-3, +1, +0, +0, +-1, +0, +1, +0, +0, +2, +1, +0, +-2, +1, +0, +3, +6, +0, +0, +-2, +1, +-3, +1, +-1, +2, +-1, +-2, +-2, +4, +0, +-1, +-3, +0, +0, +0, +2, +3, +1, +-2, +0, +0, +1, +0, +0, +0, +0, +-1, +2, +0, +0, +0, +-3, +2, +-1, +0, +-2, +1, +-1, +0, +2, +0, +0, +0, +0, +0, +0, +0, +3, +1, +-2, +1, +0, +-2, +-2, +2, +0, +-3, +1, +-1, +-1, +1, +-2, +-3, +3, +1, +0, +0, +0, +0, +0, +1, +2, +-1, +2, +4, +0, +1, +5, +-2, +0, +-1, +1, +-2, +0, +2, +-1, +-3, +0, +2, +0, +0, +-2, +-2, +0, +-1, +0, +-3, +0, +2, +-3, +-2, +0, +-3, +-1, +0, +2, +1, +0, +2, +0, +0, +0, +3, +2, +-1, +1, +0, +0, +3, +-1, +0, +0, +0, +-3, +1, +1, +-2, +0, +-3, +0, +0, +0, +0, +2, +0, +0, +1, +1, +0, +1, +0, +6, +0, +-2, +0, +0, +0, +-3, +-2, +0, +0, +0, +-1, +2, +-2, +1, +1, +0, +0, +1, +-3, +2, +1, +-2, +0, +0, +1, +-1, +0, +-1, +1, +0, +1, +0, +4, +1, +0, +-2, +0, +0, +0, +-3, +0, +1, +-1, +-3, +0, +4, +1, +-2, +2, +2, +-1, +-1, +2, +0, +1, +0, +0, +0, +1, +0, +0, +-3, +4, +1, +4, +0, +1, +-1, +0, +0, +0, +1, +-1, +0, +0, +4, +-2, +1, +0, +0, +1, +1, +0, +3, +-1, +-1, +4, +-2, +1, +1, +0, +-4, +0, +0, +-2, +3, +0, +3, +2, +3, +0, +1, +-2, +-2, +-3, +-2, +-4, +0, +-1, +0, +-1, +0, +0, +-1, +3, +-2, +0, +-2, +-2, +1, +0, +1, +-1, +-1, +-1, +0, +2, +1, +0, +2, +0, +0, +2, +-2, +-1, +7, +2, +-3, +-4, +0, +-7, +0, +0, +1, +0, +1, +-1, +2, +-3, +4, +-1, +0, +-4, +0, +-1, +1, +-1, +1, +-3, +-4, +-1, +1, +-4, +2, +-3, +5, +-4, +5, +-2, +3, +-5, +7, +-6, +6, +-7, +10, +-7, +9, +-6, +11, +-8, +18, +-15, +23, +-23, +30, +54, +2404, +4712, +4763, +3516, +1176, +-1251, +-3555, +-4800, +-5046, +-4376, +-2604, +-370, +1600, +3176, +4274, +4885, +4438, +2953, +574, +-2241, +-4506, +-5460, +-5067, +-3765, +-2051, +-137, +1607, +3077, +4115, +4345, +3474, +1602, +-807, +-3131, +-4789, +-5237, +-4490, +-2947, +-1075, +781, +2383, +3612, +4324, +4249, +3101, +999, +-1493, +-3630, +-4823, +-4768, +-3680, +-2004, +-187, +1554, +3055, +4148, +4575, +4076, +2525, +207, +-2228, +-4066, +-4818, +-4389, +-3032, +-1242, +570, +2218, +3581, +4459, +4563, +3668, +1766, +-700, +-3017, +-4492, +-4788, +-3957, +-2404, +-567, +1206, +2779, +3997, +4618, +4352, +3036, +852, +-1645, +-3720, +-4771, +-4618, +-3465, +-1751, +94, +1808, +3264, +4293, +4616, +3956, +2270, +-122, +-2533, +-4272, +-4867, +-4295, +-2876, +-1078, +740, +2379, +3698, +4490, +4468, +3401, +1398, +-1083, +-3309, +-4648, +-4776, +-3832, +-2220, +-387, +1377, +2903, +4053, +4569, +4163, +2714, +466, +-1997, +-3941, +-4825, +-4518, +-3273, +-1533, +293, +1974, +3380, +4323, +4511, +3718, +1917, +-483, +-2820, +-4399, +-4825, +-4119, +-2641, +-839, +948, +2537, +3789, +4477, +4316, +3126, +1042, +-1413, +-3522, +-4683, +-4657, +-3611, +-1966, +-143, +1571, +3045, +4113, +4509, +3971, +2406, +113, +-2290, +-4083, +-4792, +-4339, +-3020, +-1269, +522, +2158, +3497, +4337, +4408, +3473, +1584, +-817, +-3059, +-4474, +-4727, +-3901, +-2377, +-581, +1164, +2694, +3870, +4448, +4157, +2838, +699, +-1721, +-3701, +-4692, +-4509, +-3374, +-1701, +96, +1770, +3185, +4162, +4438, +3759, +2091, +-223, +-2549, +-4198, +-4736, +-4157, +-2766, +-1012, +749, +2337, +3605, +4343, +4286, +3220, +1250, +-1143, +-3271, +-4524, +-4618, +-3684, +-2111, +-333, +1375, +2857, +3952, +4418, +3986, +2548, +356, +-2010, +-3859, +-4679, +-4350, +-3127, +-1439, +334, +1960, +3316, +4204, +4358, +3543, +1775, +-557, +-2793, +-4287, +-4664, +-3956, +-2507, +-758, +970, +2506, +3704, +4347, +4152, +2960, +923, +-1447, +-3466, +-4549, +-4491, +-3454, +-1859, +-92, +1578, +2997, +4013, +4367, +3800, +2257, +27, +-2280, +-3990, +-4644, +-4180, +-2883, +-1184, +559, +2144, +3431, +4223, +4255, +3309, +1456, +-874, +-3018, +-4354, +-4571, +-3747, +-2254, +-513, +1182, +2666, +3789, +4328, +3995, +2686, +592, +-1741, +-3631, +-4552, +-4349, +-3230, +-1600, +145, +1770, +3138, +4062, +4298, +3604, +1952, +-303, +-2529, +-4094, +-4588, +-3996, +-2635, +-935, +779, +2320, +3537, +4233, +4133, +3065, +1139, +-1182, +-3220, +-4397, +-4458, +-3535, +-2004, +-271, +1385, +2812, +3860, +4284, +3827, +2408, +271, +-2013, +-3774, +-4537, +-4189, +-2989, +-1345, +373, +1954, +3255, +4094, +4211, +3383, +1647, +-617, +-2760, +-4177, +-4508, +-3798, +-2384, +-683, +994, +2482, +3624, +4219, +3998, +2807, +812, +-1472, +-3403, +-4419, +-4330, +-3316, +-1752, +-40, +1577, +2953, +3920, +4232, +3641, +2114, +-52, +-2273, +-3894, +-4492, +-4020, +-2753, +-1100, +597, +2130, +3369, +4114, +4107, +3151, +1338, +-919, +-2971, +-4236, +-4413, +-3602, +-2139, +-449, +1197, +2634, +3708, +4198, +3841, +2541, +496, +-1749, +-3557, +-4418, +-4188, +-3091, +-1501, +194, +1767, +3080, +3963, +4156, +3441, +1822, +-367, +-2509, +-3992, +-4431, +-3841, +-2509, +-854, +809, +2296, +3462, +4115, +3985, +2909, +1025, +-1215, +-3165, +-4273, +-4305, +-3389, +-1898, +-215, +1391, +2774, +3772, +4152, +3672, +2267, +182, +-2016, +-3691, +-4392, +-4031, +-2859, +-1261, +411, +1942, +3198, +3991, +4064, +3227, +1520, +-669, +-2730, +-4068, +-4359, +-3653, +-2271, +-614, +1012, +2454, +3548, +4101, +3843, +2659, +717, +-1495, +-3337, +-4286, +-4176, +-3172, +-1651, +18, +1584, +2906, +3826, +4095, +3488, +1983, +-124, +-2261, +-3801, +-4353, +-3866, +-2625, +-1020, +627, +2113, +3304, +4002, +3961, +3000, +1220, +-966, +-2933, +-4121, +-4263, +-3451, +-2028, +-389, +1212, +2598, +3626, +4074, +3693, +2399, +403, +-1766, +-3482, +-4283, +-4036, +-2951, +-1407, +235, +1763, +3035, +3862, +4019, +3294, +1694, +-427, +-2489, +-3896, +-4290, +-3690, +-2391, +-782, +835, +2272, +3393, +4000, +3836, +2762, +916, +-1250, +-3111, +-4154, +-4155, +-3247, +-1789, +-156, +1403, +2731, +3689, +4028, +3521, +2128, +102, +-2014, +-3610, +-4258, +-3885, +-2723, +-1176, +453, +1937, +3139, +3886, +3923, +3079, +1404, +-722, +-2700, +-3962, +-4216, +-3502, +-2156, +-548, +1033, +2425, +3476, +3984, +3693, +2516, +614, +-1518, +-3271, +-4165, +-4032, +-3032, +-1551, +64, +1587, +2860, +3731, +3959, +3343, +1851, +-193, +-2249, +-3709, +-4215, +-3722, +-2498, +-938, +658, +2097, +3242, +3895, +3816, +2853, +1106, +-1007, +-2889, +-4011, +-4113, +-3307, +-1919, +-319, +1228, +2565, +3547, +3948, +3543, +2261, +313, +-1776, +-3413, +-4152, +-3886, +-2819, +-1315, +280, +1760, +2978, +3764, +3881, +3140, +1569, +-489, +-2471, +-3796, +-4149, +-3547, +-2272, +-706, +861, +2250, +3325, +3886, +3692, +2620, +813, +-1276, +-3054, +-4033, +-4002, +-3107, +-1686, +-104, +1409, +2695, +3598, +3898, +3373, +1992, +23, +-2014, +-3530, +-4119, +-3735, +-2602, +-1089, +485, +1925, +3083, +3785, +3786, +2932, +1285, +-774, +-2667, +-3855, +-4069, +-3363, +-2045, +-482, +1053, +2396, +3403, +3859, +3553, +2377, +520, +-1535, +-3208, +-4035, +-3877, +-2898, +-1457, +113, +1583, +2816, +3638, +3828, +3192, +1718, +-263, +-2237, +-3624, +-4075, +-3573, +-2381, +-859, +687, +2080, +3174, +3784, +3674, +2711, +1000, +-1043, +-2846, +-3895, +-3972, +-3170, +-1818, +-262, +1235, +2527, +3462, +3823, +3398, +2123, +234, +-1777, +-3338, +-4023, +-3739, +-2694, +-1229, +320, +1756, +2925, +3663, +3747, +2994, +1452, +-541, +-2445, +-3697, +-4008, +-3396, +-2156, +-636, +880, +2226, +3257, +3771, +3550, +2483, +713, +-1303, +-3004, +-3912, +-3860, +-2973, +-1589, +-47, +1413, +2654, +3506, +3771, +3223, +1869, +-47, +-2001, +-3446, +-3982, +-3600, +-2383, +-783, +617, +1769, +2576, +2974, +2795, +2010, +765, +-638, +-1772, +-2368, +-2385, +-1909, +-1133, +-214, +642, +1332, +1737, +1798, +1487, +882, +109, +-658, +-1245, +-1498, +-1405, +-1034, +-495, +80, +582, +945, +1116, +1070, +791, +352, +-136, +-566, +-842, +-913, +-797, +-539, +-189, +172, +468, +651, +701, +602, +387, +102, +-188, +-423, +-549, +-553, +-441, +-249, +-28, +181, +344, +425, +420, +328, +174, +-11, +-174, +-295, +-346, +-323, +-233, +-103, +32, +156, +241, +268, +241, +167, +63, +-47, +-142, +-197, +-214, +-185, +-116, +-32, +53, +121, +159, +163, +133, +84, +13, +-53, +-104, +-125, +-127, +-102, +-53, +0, +53, +82, +101, +100, +69, +35, +-11, +-45, +-67, +-83, +-74, +-54, +-23, +11, +37, +58, +60, +51, +35, +9, +-14, +-34, +-46, +-49, +-41, +-23, +-3, +13, +30, +38, +34, +30, +18, +0, +-12, +-25, +-33, +-29, +-18, +-13, +0, +12, +24, +21, +25, +19, +6, +-1, +-14, +-20, +-17, +-15, +-9, +-4, +5, +8, +16, +16, +14, +2, +1, +-6, +-6, +-11, +-10, +-6, +-7, +-3, +7, +8, +9, +10, +6, +4, +-2, +-2, +-7, +-4, +-9, +-4, +-2, +5, +8, +2, +3, +4, +0, +2, +-1, +-2, +-4, +-3, +0, +-2, +-1, +2, +6, +2, +4, +6, +1, +2, +-2, +1, +-1, +-4, +-2, +0, +1, +0, +1, +-1, +2, +1, +0, +1, +3, +-3, +-2, +-1, +-1, +0, +0, +0, +0, +2, +1, +0, +1, +2, +0, +0, +-1, +0, +2, +-1, +-2, +0, +1, +1, +-3, +2, +1, +-1, +-2, +1, +-3, +1, +0, +2, +0, +0, +0, +1, +2, +0, +0, +0, +0, +0, +-1, +0, +0, +-1, +5, +0, +0, +0, +-2, +0, +-1, +2, +-2, +0, +0, +0, +-1, +-2, +-5, +3, +-2, +-2, +-3, +0, +0, +-3, +4, +-1, +0, +0, +2, +3, +0, +-3, +3, +0, +-1, +0, +1, +-3, +-2, +0, +-1, +0, +1, +-2, +-3, +1, +-1, +-1, +2, +0, +-1, +0, +-1, +-2, +0, +0, +1, +0, +4, +0, +1, +-1, +0, +0, +1, +5, +0, +-3, +0, +2, +1, +1, +-2, +0, +3, +-1, +0, +1, +0, +5, +-2, +1, +-2, +1, +0, +0, +-1, +4, +-2, +0, +1, +2, +0, +-3, +2, +0, +-3, +0, +-1, +-1, +-2, +-2, +0, +-1, +1, +0, +0, +-1, +-2, +4, +0, +-1, +0, +-1, +-3, +-5, +-3, +-3, +0, +0, +3, +2, +-1, +-1, +-1, +0, +2, +-3, +1, +1, +1, +-4, +0, +1, +0, +-2, +0, +0, +0, +-4, +2, +-2, +0, +-2, +1, +1, +-1, +1, +-2, +1, +-1, +-2, +0, +1, +-2, +-2, +4, +0, +0, +3, +0, +3, +0, +1, +2, +0, +0, +0, +0, +2, +0, +0, +-3, +-1, +-2, +0, +1, +-2, +0, +-1, +0, +2, +0, +-2, +0, +-1, +-1, +4, +1, +3, +0, +0, +-1, +2, +-5, +0, +0, +1, +3, +0, +0, +0, +-3, +1, +-1, +1, +-3, +1, +0, +1, +0, +5, +-1, +-1, +0, +0, +0, +0, +0, +2, +3, +1, +3, +-1, +1, +3, +0, +0, +1, +-4, +0, +3, +-2, +1, +1, +0, +1, +-2, +-3, +-3, +-1, +-2, +-1, +0, +0, +2, +-3, +0, +0, +1, +-1, +2, +1, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +-1, +0, +3, +0, +0, +1, +0, +-1, +-2, +-4, +0, +0, +-1, +0, +2, +1, +-1, +0, +-2, +3, +-1, +2, +1, +2, +2, +1, +0, +0, +1, +0, +0, +-2, +2, +0, +1, +0, +0, +0, +0, +0, +1, +-3, +1, +4, +-2, +5, +0, +2, +1, +1, +2, +1, +0, +0, +0, +4, +-2, +1, +-2, +0, +1, +0, +1, +1, +-2, +-2, +-3, +-1, +0, +0, +-1, +0, +-1, +0, +-2, +-2, +0, +3, +0, +-1, +0, +-1, +-1, +0, +1, +-2, +-2, +0, +0, +1, +0, +4, +0, +1, +-2, +0, +-3, +-1, +1, +4, +0, +0, +-1, +-2, +0, +2, +0, +1, +-1, +-1, +0, +2, +0, +-1, +2, +0, +0, +0, +2, +0, +0, +2, +0, +0, +1, +-2, +-1, +0, +0, +5, +-1, +2, +0, +0, +-3, +2, +0, +1, +-3, +-1, +-4, +-1, +-1, +2, +-2, +4, +-2, +0, +0, +2, +0, +-5, +-3, +0, +0, +0, +-6, +1, +1, +0, +2, +2, +1, +0, +0, +0, +0, +0, +0, +1, +-1, +1, +0, +0, +-3, +-1, +0, +0, +0, +1, +0, +0, +-1, +3, +0, +0, +-1, +-1, +0, +2, +0, +3, +0, +-1, +-2, +-1, +0, +4, +3, +0, +0, +0, +0, +0, +-2, +0, +0, +-1, +0, +-4, +-4, +-2, +3, +0, +0, +-8, +2, +-1, +0, +0, +0, +-3, +2, +-1, +2, +-1, +0, +-1, +1, +0, +0, +-2, +1, +-2, +2, +0, +0, +0, +0, +-1, +2, +-1, +3, +-3, +3, +-2, +3, +-7, +0, +-3, +4, +-4, +8, +-6, +7, +-6, +6, +-4, +3, +-3, +7, +-2, +8, +-2, +10, +-5, +13, +-6, +8, +-11, +11, +-12, +12, +-16, +14, +-16, +16, +-19, +23, +-28, +27, +-33, +34, +-42, +50, +-54, +50, +302, +6651, +7177, +-1303, +-8721, +-7898, +1315, +9140, +10966, +4598, +-5965, +-11125, +-6261, +3174, +8705, +7477, +1203, +-7343, +-10416, +-4836, +3313, +7422, +6165, +115, +-7762, +-10204, +-3802, +4446, +7970, +5715, +-1305, +-8879, +-9359, +-1666, +6216, +8086, +4401, +-3002, +-9191, +-7687, +460, +7017, +7611, +3178, +-4069, +-9102, +-6235, +1912, +7548, +7291, +2214, +-5257, +-9163, +-4917, +3405, +8115, +6862, +862, +-6558, +-8980, +-3276, +4810, +8375, +6016, +-621, +-7598, +-8356, +-1624, +5914, +8296, +5057, +-2070, +-8355, +-7557, +-37, +6783, +8105, +3965, +-3525, +-8929, +-6504, +1519, +7517, +7695, +2688, +-4970, +-9161, +-5203, +3019, +7978, +7075, +1278, +-6244, +-9052, +-3727, +4336, +8217, +6268, +-170, +-7346, +-8610, +-2171, +5501, +8246, +5316, +-1673, +-8204, +-7868, +-562, +6461, +8067, +4196, +-3151, +-8788, +-6827, +1010, +7201, +7679, +2956, +-4566, +-9050, +-5579, +2506, +7718, +7118, +1606, +-5851, +-9007, +-4142, +3871, +8024, +6373, +186, +-6966, +-8624, +-2608, +5070, +8093, +5468, +-1275, +-7851, +-7950, +-1021, +6065, +7965, +4407, +-2719, +-8483, +-6998, +544, +6857, +7639, +3228, +-4115, +-8818, +-5817, +2041, +7420, +7137, +1930, +-5401, +-8844, +-4455, +3417, +7773, +6452, +559, +-6535, +-8562, +-2975, +4642, +7907, +5604, +-857, +-7468, +-7979, +-1434, +5670, +7846, +4610, +-2279, +-8150, +-7121, +104, +6503, +7583, +3483, +-3663, +-8558, +-6030, +1592, +7124, +7137, +2241, +-4951, +-8672, +-4743, +2976, +7535, +6514, +920, +-6107, +-8474, +-3326, +4215, +7724, +5729, +-461, +-7074, +-7985, +-1829, +5277, +7717, +4800, +-1853, +-7811, +-7223, +-320, +6153, +7518, +3724, +-3223, +-8288, +-6212, +1154, +6817, +7123, +2538, +-4511, +-8474, +-5004, +2533, +7279, +6565, +1262, +-5679, +-8370, +-3652, +3791, +7525, +5839, +-81, +-6681, +-7971, +-2206, +4883, +7577, +4963, +-1445, +-7464, +-7296, +-728, +5798, +7434, +3947, +-2793, +-8008, +-6372, +722, +6509, +7106, +2816, +-4084, +-8264, +-5245, +2107, +7024, +6599, +1583, +-5263, +-8244, +-3953, +3376, +7325, +5934, +285, +-6289, +-7932, +-2562, +4496, +7429, +5110, +-1049, +-7114, +-7340, +-1119, +5448, +7341, +4156, +-2377, +-7710, +-6503, +314, +6200, +7070, +3071, +-3660, +-8044, +-5451, +1692, +6758, +6623, +1888, +-4851, +-8099, +-4232, +2966, +7114, +6016, +627, +-5897, +-7869, +-2894, +4107, +7272, +5245, +-667, +-6765, +-7368, +-1494, +5081, +7241, +4342, +-1974, +-7412, +-6614, +-86, +5879, +7025, +3313, +-3250, +-7812, +-5642, +1281, +6482, +6637, +2178, +-4442, +-7942, +-4488, +2566, +6893, +6080, +961, +-5510, +-7794, +-3210, +3726, +7102, +5373, +-301, +-6410, +-7375, +-1850, +4731, +7125, +4518, +-1588, +-7107, +-6703, +-467, +5563, +6970, +3538, +-2849, +-7564, +-5804, +885, +6210, +6628, +2452, +-4044, +-7770, +-4725, +2164, +6665, +6134, +1274, +-5123, +-7696, +-3505, +3337, +6927, +5472, +43, +-6057, +-7361, +-2184, +4370, +7005, +4673, +-1214, +-6798, +-6773, +-840, +5238, +6895, +3747, +-2460, +-7313, +-5952, +493, +5924, +6612, +2707, +-3652, +-7580, +-4941, +1780, +6425, +6165, +1574, +-4745, +-7586, +-3775, +2964, +6741, +5563, +377, +-5700, +-7326, +-2511, +4009, +6868, +4820, +-851, +-6484, +-6816, +-1194, +4913, +6814, +3939, +-2080, +-7049, +-6075, +121, +5639, +6585, +2950, +-3266, +-7380, +-5130, +1397, +6185, +6190, +1858, +-4374, +-7454, +-4032, +2589, +6546, +5641, +694, +-5349, +-7278, +-2816, +3660, +6723, +4947, +-504, +-6168, +-6843, +-1537, +4582, +6722, +4120, +-1716, +-6787, +-6177, +-242, +5346, +6545, +3169, +-2893, +-7174, +-5305, +1024, +5933, +6207, +2122, +-4007, +-7317, +-4267, +2222, +6345, +5708, +997, +-5003, +-7209, +-3107, +3308, +6567, +5063, +-167, +-5847, +-6856, +-1863, +4256, +6615, +4285, +-1363, +-6506, +-6265, +-594, +5057, +6491, +3379, +-2535, +-6952, +-5464, +659, +5685, +6205, +2376, +-3637, +-7167, +-4483, +1856, +6136, +5757, +1290, +-4657, +-7124, +-3375, +2956, +6411, +5159, +154, +-5530, +-6843, +-2175, +3932, +6509, +4430, +-1019, +-6226, +-6322, +-935, +4760, +6432, +3576, +-2177, +-6724, +-5596, +307, +5426, +6196, +2618, +-3285, +-7001, +-4684, +1499, +5922, +5795, +1565, +-4307, +-7029, +-3627, +2607, +6241, +5249, +458, +-5209, +-6819, +-2467, +3605, +6383, +4566, +-684, +-5946, +-6370, +-1262, +4462, +6364, +3757, +-1833, +-6491, +-5712, +-35, +5164, +6168, +2838, +-2940, +-6822, +-4860, +1148, +5699, +5825, +1828, +-3971, +-6915, +-3867, +2269, +6065, +5325, +753, +-4889, +-6776, +-2751, +3280, +6252, +4687, +-367, +-5660, +-6402, +-1573, +4158, +6278, +3925, +-1491, +-6253, +-5808, +-372, +4896, +6137, +3054, +-2596, +-6635, +-5023, +804, +5472, +5840, +2080, +-3635, +-6788, +-4081, +1930, +5878, +5393, +1037, +-4572, +-6718, +-3017, +2953, +6117, +4799, +-57, +-5370, +-6414, +-1876, +3861, +6185, +4082, +-1170, +-6006, +-5889, +-696, +4626, +6094, +3251, +-2262, +-6441, +-5172, +469, +5238, +5842, +2317, +-3304, +-6655, +-4285, +1593, +5688, +5438, +1303, +-4256, +-6642, +-3265, +2633, +5969, +4897, +243, +-5084, +-6409, +-2160, +3558, +6086, +4223, +-848, +-5751, +-5949, +-1013, +4353, +6042, +3432, +-1934, +-6235, +-5295, +147, +5003, +5833, +2540, +-2978, +-6508, +-4470, +1260, +5491, +5481, +1563, +-3941, +-6555, +-3499, +2312, +5814, +4985, +527, +-4792, +-6386, +-2435, +3256, +5976, +4359, +-541, +-5491, +-6000, +-1314, +4082, +5979, +3604, +-1612, +-6020, +-5406, +-175, +4761, +5818, +2750, +-2655, +-6348, +-4639, +940, +5286, +5510, +1806, +-3631, +-6460, +-3723, +1990, +5658, +5057, +801, +-4501, +-6354, +-2694, +2958, +5861, +4475, +-245, +-5232, +-6029, +-1605, +3799, +5903, +3764, +-1300, +-5804, +-5498, +-487, +4516, +5790, +2954, +-2340, +-6177, +-4791, +623, +5077, +5528, +2044, +-3315, +-6352, +-3922, +1673, +5487, +5120, +1068, +-4215, +-6306, +-2945, +2658, +5733, +4586, +42, +-4966, +-6044, +-1880, +3516, +5827, +3908, +-993, +-5586, +-5564, +-805, +4301, +5459, +2256, +-2171, +-4651, +-3067, +699, +3209, +2914, +691, +-1680, +-2601, +-1476, +633, +1915, +1652, +283, +-1146, +-1640, +-845, +552, +1364, +1028, +-27, +-951, +-1051, +-325, +580, +905, +474, +-238, +-651, +-524, +-34, +407, +487, +187, +-190, +-367, +-267, +-3, +247, +293, +115, +-139, +-249, +-169, +25, +190, +193, +35, +-135, +-170, +-69, +61, +129, +93, +-15, +-99, +-84, +-21, +46, +68, +46, +-13, +-52, +-50, +-7, +29, +46, +27, +-8, +-38, +-32, +0, +23, +28, +13, +-16, +-29, +-17, +7, +23, +13, +0, +-10, +-17, +-10, +5, +10, +8, +-2, +-5, +-7, +0, +3, +6, +8, +0, +-5, +-7, +-5, +0, +9, +-1, +-2, +-5, +-4, +-1, +3, +3, +0, +-1, +-2, +0, +-1, +0, +-1, +-4, +-2, +-3, +-1, +-2, +0, +2, +-1, +-1, +1, +1, +0, +-1, +0, +0, +-1, +-2, +-3, +0, +0, +2, +3, +1, +-1, +0, +-1, +0, +0, +0, +0, +0, +1, +2, +1, +-1, +0, +1, +1, +4, +-1, +2, +-2, +3, +2, +0, +-2, +-1, +1, +-2, +1, +-1, +0, +1, +0, +3, +1, +-2, +0, +5, +1, +0, +1, +2, +0, +0, +0, +0, +0, +3, +2, +0, +3, +1, +-2, +-2, +1, +0, +-1, +-1, +1, +-2, +0, +0, +-3, +-2, +0, +1, +2, +3, +-2, +-2, +-4, +4, +-1, +-1, +-1, +3, +0, +0, +-1, +0, +3, +0, +0, +0, +-1, +0, +-4, +-1, +-2, +0, +0, +0, +1, +-3, +1, +0, +1, +0, +0, +0, +0, +-2, +-1, +2, +-1, +-2, +0, +-1, +0, +1, +0, +-2, +0, +0, +3, +-2, +-2, +0, +0, +1, +0, +-2, +-2, +-2, +0, +0, +2, +0, +3, +0, +1, +0, +1, +-2, +2, +-3, +0, +-4, +-1, +0, +1, +-1, +0, +0, +-1, +1, +-4, +1, +2, +1, +-2, +0, +0, +0, +2, +1, +0, +1, +0, +0, +2, +3, +0, +0, +-3, +0, +-2, +-2, +3, +-3, +-1, +-3, +-1, +-3, +-2, +-1, +1, +0, +-3, +1, +0, +-1, +2, +1, +0, +1, +0, +3, +-3, +0, +2, +0, +1, +-1, +0, +-2, +-2, +2, +-3, +1, +0, +2, +2, +4, +0, +0, +-3, +0, +-4, +3, +3, +-2, +0, +-1, +0, +0, +-1, +-3, +0, +0, +1, +1, +-1, +-1, +0, +2, +0, +0, +0, +-1, +1, +0, +-1, +0, +0, +0, +-3, +0, +3, +0, +0, +0, +0, +-4, +-2, +1, +-2, +2, +-2, +0, +4, +-1, +1, +1, +3, +-2, +-2, +0, +-1, +5, +3, +2, +-1, +0, +2, +2, +0, +0, +0, +1, +1, +0, +-1, +-2, +2, +-1, +1, +3, +0, +0, +-3, +0, +1, +2, +-1, +-1, +0, +3, +-3, +0, +-1, +0, +-2, +-1, +0, +0, +-3, +-1, +1, +-1, +2, +-2, +0, +1, +2, +1, +-1, +-2, +0, +1, +0, +0, +0, +0, +1, +-5, +-1, +-1, +1, +0, +0, +-2, +-1, +-2, +0, +3, +1, +0, +1, +0, +1, +-1, +-1, +2, +1, +0, +-2, +-2, +0, +1, +-1, +0, +1, +0, +4, +5, +3, +2, +0, +0, +0, +-2, +0, +0, +1, +1, +3, +1, +2, +1, +1, +0, +0, +-1, +-1, +0, +-2, +1, +-2, +2, +4, +1, +3, +0, +0, +1, +0, +-1, +0, +0, +3, +0, +0, +-1, +-2, +0, +0, +1, +0, +-3, +-2, +-2, +0, +2, +0, +1, +0, +3, +3, +-2, +0, +1, +-2, +0, +0, +-2, +-2, +-1, +0, +0, +0, +0, +1, +3, +1, +0, +2, +-1, +-1, +1, +0, +-1, +3, +2, +1, +-3, +3, +4, +0, +0, +-2, +-1, +-4, +3, +-1, +-1, +2, +0, +0, +5, +-2, +-3, +0, +2, +1, +0, +1, +3, +0, +2, +0, +0, +2, +0, +0, +0, +0, +2, +0, +-1, +-2, +3, +-1, +-1, +-1, +3, +-1, +-2, +-3, +-4, +3, +1, +1, +0, +1, +0, +0, +0, +0, +-2, +2, +1, +1, +3, +0, +0, +0, +2, +-3, +0, +0, +0, +0, +0, +0, +2, +0, +-1, +4, +2, +-1, +0, +1, +0, +0, +0, +-2, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-2, +-1, +0, +0, +1, +2, +0, +1, +3, +-1, +1, +0, +1, +-2, +-1, +0, +-1, +-3, +2, +2, +4, +2, +2, +1, +0, +0, +4, +0, +1, +1, +-1, +0, +2, +0, +0, +-1, +0, +0, +0, +0, +2, +0, +0, +0, +-2, +2, +1, +0, +0, +-1, +0, +0, +2, +2, +1, +0, +0, +3, +-2, +2, +0, +2, +0, +0, +0, +2, +0, +0, +0, +1, +-3, +2, +2, +2, +1, +0, +-1, +4, +-4, +-1, +0, +0, +1, +0, +0, +3, +1, +0, +1, +1, +-1, +1, +2, +1, +-1, +2, +-2, +1, +0, +1, +-3, +0, +2, +0, +2, +0, +-4, +4, +-3, +6, +0, +3, +0, +3, +0, +4, +-3, +1, +-2, +0, +0, +-1, +-4, +5, +-1, +4, +-3, +2, +-3, +2, +-2, +7, +-2, +5, +0, +5, +-1, +2, +-5, +5, +-6, +10, +-10, +7, +-4, +7, +-12, +8, +-7, +10, +-15, +17, +-15, +25, +-26, +33, +-38, +44, +76, +3744, +7533, +7988, +6272, +2367, +-2273, +-6671, +-8943, +-8814, +-6696, +-3283, +146, +2747, +4830, +6659, +8095, +7911, +5521, +1066, +-4250, +-8407, +-9868, +-8580, +-5566, +-2245, +638, +2782, +4598, +6237, +7098, +6180, +3139, +-1371, +-5860, +-8759, +-8996, +-6893, +-3632, +-530, +1841, +3606, +5199, +6587, +7031, +5511, +1898, +-2773, +-6780, +-8670, +-7937, +-5283, +-2048, +683, +2726, +4413, +6026, +7174, +6948, +4588, +399, +-4271, +-7654, +-8607, +-7078, +-4066, +-893, +1599, +3490, +5183, +6750, +7498, +6489, +3285, +-1364, +-5819, +-8409, +-8388, +-6153, +-2930, +78, +2365, +4201, +5923, +7304, +7466, +5574, +1626, +-3208, +-7169, +-8830, +-7877, +-5094, +-1809, +984, +3096, +4901, +6583, +7627, +7053, +4280, +-224, +-4964, +-8198, +-8846, +-7061, +-3915, +-718, +1832, +3799, +5591, +7126, +7669, +6264, +2699, +-2128, +-6492, +-8822, +-8470, +-6005, +-2692, +314, +2618, +4495, +6242, +7519, +7404, +5140, +915, +-3960, +-7703, +-9026, +-7751, +-4795, +-1483, +1262, +3361, +5187, +6830, +7691, +6814, +3712, +-962, +-5618, +-8543, +-8828, +-6765, +-3521, +-359, +2117, +4074, +5857, +7314, +7612, +5885, +2043, +-2841, +-7013, +-8982, +-8282, +-5609, +-2263, +669, +2904, +4772, +6486, +7620, +7223, +4638, +218, +-4610, +-8081, +-9024, +-7436, +-4351, +-1067, +1596, +3645, +5457, +7040, +7705, +6511, +3121, +-1668, +-6176, +-8770, +-8689, +-6379, +-3073, +29, +2426, +4350, +6118, +7464, +7507, +5458, +1381, +-3514, +-7461, +-9062, +-8028, +-5175, +-1832, +1017, +3198, +5050, +6725, +7691, +7005, +4102, +-476, +-5227, +-8392, +-8960, +-7095, +-3898, +-666, +1913, +3928, +5727, +7231, +7676, +6162, +2496, +-2364, +-6692, +-8942, +-8505, +-5972, +-2627, +398, +2728, +4630, +6372, +7588, +7369, +4994, +701, +-4169, +-7858, +-9093, +-7737, +-4735, +-1404, +1365, +3488, +5323, +6948, +7733, +6741, +3538, +-1177, +-5805, +-8655, +-8859, +-6727, +-3448, +-267, +2230, +4210, +5995, +7404, +7610, +5776, +1849, +-3049, +-7176, +-9066, +-8279, +-5553, +-2180, +768, +3031, +4916, +6626, +7691, +7185, +4492, +16, +-4810, +-8217, +-9070, +-7417, +-4286, +-983, +1698, +3778, +5603, +7156, +7733, +6427, +2943, +-1875, +-6358, +-8872, +-8705, +-6331, +-2997, +121, +2547, +4497, +6258, +7555, +7505, +5347, +1187, +-3718, +-7611, +-9129, +-8015, +-5114, +-1746, +1126, +3329, +5200, +6853, +7752, +6953, +3956, +-678, +-5414, +-8515, +-9003, +-7066, +-3828, +-573, +2026, +4067, +5878, +7342, +7702, +6072, +2319, +-2570, +-6865, +-9031, +-8510, +-5920, +-2544, +503, +2855, +4778, +6513, +7670, +7346, +4867, +503, +-4367, +-7997, +-9146, +-7713, +-4670, +-1314, +1467, +3621, +5475, +7069, +7783, +6674, +3378, +-1379, +-5980, +-8761, +-8876, +-6683, +-3371, +-167, +2350, +4350, +6144, +7501, +7615, +5670, +1664, +-3249, +-7325, +-9131, +-8272, +-5489, +-2100, +869, +3155, +5061, +6751, +7752, +7145, +4349, +-182, +-4990, +-8331, +-9105, +-7379, +-4211, +-892, +1808, +3911, +5750, +7266, +7760, +6340, +2771, +-2076, +-6516, +-8948, +-8709, +-6280, +-2916, +219, +2661, +4635, +6393, +7634, +7487, +5218, +994, +-3913, +-7738, +-9175, +-7987, +-5046, +-1656, +1225, +3454, +5340, +6973, +7800, +6892, +3797, +-884, +-5584, +-8610, +-9012, +-7016, +-3752, +-479, +2140, +4198, +6011, +7438, +7703, +5962, +2135, +-2761, +-7005, +-9086, +-8489, +-5858, +-2459, +597, +2970, +4916, +6638, +7729, +7306, +4725, +308, +-4552, +-8106, +-9165, +-7668, +-4587, +-1222, +1573, +3742, +5608, +7175, +7798, +6588, +3205, +-1578, +-6139, +-8830, +-8866, +-6620, +-3290, +-73, +2456, +4478, +6266, +7577, +7598, +5537, +1476, +-3440, +-7452, +-9165, +-8234, +-5411, +-2010, +964, +3270, +5188, +6863, +7792, +7078, +4189, +-381, +-5159, +-8419, +-9104, +-7318, +-4128, +-801, +1907, +4029, +5867, +7353, +7762, +6236, +2588, +-2271, +-6659, +-9002, +-8675, +-6203, +-2826, +313, +2767, +4755, +6508, +7687, +7443, +5072, +804, +-4088, +-7848, +-9191, +-7938, +-4957, +-1568, +1327, +3561, +5457, +7067, +7815, +6804, +3624, +-1076, +-5737, +-8677, +-8992, +-6942, +-3660, +-386, +2240, +4314, +6125, +7502, +7679, +5838, +1942, +-2950, +-7130, +-9117, +-8443, +-5767, +-2366, +686, +3074, +5033, +6732, +7765, +7238, +4568, +116, +-4714, +-8191, +-9156, +-7601, +-4493, +-1133, +1670, +3853, +5724, +7254, +7792, +6476, +3024, +-1771, +-6274, +-8874, +-8826, +-6537, +-3194, +12, +2556, +4594, +6369, +7627, +7547, +5398, +1279, +-3611, +-7549, +-9168, +-8166, +-5319, +-1916, +1062, +3370, +5296, +6948, +7805, +6995, +4019, +-576, +-5305, +-8477, +-9074, +-7231, +-4026, +-709, +2006, +4133, +5970, +7412, +7729, +6106, +2398, +-2453, +-6764, +-9019, +-8619, +-6112, +-2725, +401, +2867, +4862, +6596, +7714, +7372, +4914, +607, +-4246, +-7920, +-9169, +-7853, +-4854, +-1471, +1414, +3658, +5561, +7135, +7798, +6695, +3443, +-1264, +-5864, +-8708, +-8936, +-6846, +-3558, +-298, +2328, +4411, +6217, +7542, +7623, +5690, +1749, +-3121, +-7212, +-9108, +-8365, +-5661, +-2268, +775, +3166, +5129, +6807, +7764, +7148, +4392, +-76, +-4852, +-8238, +-9116, +-7502, +-4391, +-1040, +1757, +3944, +5809, +7301, +7758, +6350, +2833, +-1949, +-6374, +-8884, +-8757, +-6428, +-3091, +101, +2645, +4684, +6440, +7645, +7476, +5235, +1090, +-3767, +-7613, +-9135, +-8072, +-5209, +-1822, +1146, +3459, +5387, +7001, +7784, +6875, +3838, +-761, +-5429, +-8498, +-9009, +-7128, +-3919, +-625, +2087, +4221, +6054, +7442, +7670, +5962, +2205, +-2618, +-6852, +-9009, +-8526, +-5995, +-2626, +486, +2948, +4945, +6661, +7712, +7275, +4738, +417, +-4386, +-7958, +-9118, +-7744, +-4743, +-1376, +1495, +3745, +5637, +7173, +7758, +6559, +3248, +-1437, +-5964, +-8705, +-8856, +-6729, +-3451, +-208, +2407, +4493, +6280, +7553, +7542, +5529, +1558, +-3270, +-7276, +-9069, +-8261, +-5544, +-2174, +865, +3242, +5209, +6851, +7746, +7026, +4212, +-266, +-4968, +-8263, +-9028, +-7412, +-4089, +-520, +1989, +3764, +5075, +5964, +5858, +4363, +1575, +-1699, +-4360, +-5592, +-5293, +-3837, +-1879, +49, +1640, +2821, +3559, +3707, +3137, +1849, +86, +-1685, +-2961, +-3392, +-2994, +-2009, +-783, +393, +1361, +2040, +2357, +2237, +1637, +674, +-418, +-1365, +-1931, +-2015, +-1662, +-1017, +-250, +493, +1067, +1415, +1479, +1259, +780, +148, +-496, +-995, +-1235, +-1194, +-904, +-462, +15, +454, +774, +924, +896, +679, +329, +-76, +-437, +-682, +-765, +-690, +-471, +-182, +116, +370, +534, +580, +512, +342, +108, +-134, +-336, +-453, +-465, +-384, +-232, +-42, +139, +275, +355, +357, +284, +160, +6, +-140, +-237, +-291, +-276, +-201, +-102, +19, +125, +196, +227, +209, +146, +63, +-34, +-108, +-166, +-179, +-159, +-106, +-35, +36, +97, +134, +140, +118, +75, +19, +-38, +-82, +-110, +-107, +-85, +-49, +-5, +39, +68, +86, +83, +65, +34, +-3, +-34, +-57, +-68, +-62, +-45, +-19, +8, +33, +51, +57, +50, +33, +12, +-9, +-27, +-39, +-43, +-35, +-21, +-3, +13, +26, +33, +36, +27, +15, +2, +-7, +-22, +-23, +-25, +-21, +-9, +0, +12, +20, +20, +19, +12, +3, +-2, +-6, +-12, +-17, +-17, +-10, +-3, +3, +11, +13, +13, +10, +5, +2, +-2, +-9, +-11, +-12, +-5, +-1, +0, +5, +4, +8, +8, +4, +2, +1, +-6, +-5, +-5, +-5, +-3, +-1, +1, +2, +1, +3, +5, +0, +1, +0, +-3, +-3, +-3, +-3, +-4, +-4, +1, +4, +2, +0, +3, +1, +0, +-1, +-2, +0, +0, +2, +4, +-1, +0, +2, +4, +2, +-1, +0, +0, +-3, +-3, +-3, +-2, +2, +0, +-1, +-1, +1, +0, +-3, +0, +6, +3, +0, +0, +-2, +2, +-2, +1, +1, +-3, +-2, +4, +0, +-2, +0, +2, +0, +0, +0, +-1, +-1, +-1, +0, +-1, +-1, +0, +6, +3, +0, +0, +1, +-2, +0, +-3, +0, +-5, +0, +-1, +-2, +0, +-4, +1, +-2, +2, +1, +0, +0, +3, +0, +-2, +0, +-1, +-3, +-2, +-1, +-1, +0, +-1, +0, +2, +1, +-1, +0, +-3, +0, +2, +1, +0, +0, +0, +1, +0, +4, +4, +2, +2, +0, +0, +-2, +3, +0, +2, +-4, +2, +-1, +0, +0, +2, +0, +0, +-3, +0, +1, +3, +0, +4, +-1, +0, +2, +2, +-3, +0, +0, +2, +-5, +0, +0, +2, +2, +1, +-1, +2, +0, +2, +0, +-2, +2, +-3, +-3, +1, +0, +1, +1, +-2, +-1, +0, +2, +0, +4, +0, +0, +0, +-1, +1, +0, +-2, +0, +1, +-1, +2, +-2, +-1, +0, +0, +0, +1, +0, +0, +0, +0, +2, +3, +-2, +0, +1, +0, +-1, +2, +-3, +-1, +4, +0, +0, +0, +0, +0, +-1, +-1, +-3, +-1, +1, +1, +1, +-1, +1, +0, +5, +0, +0, +-2, +-1, +0, +0, +4, +2, +-4, +1, +0, +0, +0, +1, +0, +0, +0, +1, +3, +-3, +-3, +0, +0, +1, +-2, +0, +-2, +0, +-1, +0, +1, +0, +-6, +0, +2, +0, +0, +0, +-3, +-2, +-1, +0, +1, +0, +0, +0, +0, +0, +1, +0, +1, +1, +0, +1, +1, +2, +0, +0, +0, +1, +-3, +-1, +-1, +3, +-3, +1, +0, +0, +0, +1, +0, +-1, +0, +0, +0, +1, +2, +-1, +0, +0, +0, +-3, +1, +0, +0, +0, +1, +0, +0, +0, +-1, +-2, +-1, +0, +0, +0, +0, +3, +2, +-1, +2, +-1, +1, +2, +1, +2, +-1, +0, +1, +1, +1, +0, +10, +56, +60, +30, +-14, +-60, +-84, +-89, +-73, +-46, +-9, +38, +77, +85, +85, +75, +51, +15, +-27, +-71, +-100, +-103, +-81, +-37, +8, +44, +71, +83, +82, +69, +36, +-1, +-43, +-78, +-93, +-85, +-55, +-11, +28, +54, +73, +79, +79, +50, +28, +-16, +-56, +-89, +-95, +-79, +-41, +-3, +36, +65, +75, +76, +68, +42, +10, +-33, +-73, +-95, +-93, +-68, +-26, +12, +52, +71, +77, +74, +59, +31, +-8, +-52, +-80, +-97, +-83, +-56, +-7, +26, +59, +71, +79, +73, +51, +18, +-18, +-66, +-86, +-94, +-72, +-41, +8, +38, +68, +76, +79, +65, +42, +2, +-39, +-78, +-92, +-92, +-58, +-23, +22, +50, +75, +71, +78, +55, +29, +-15, +-55, +-85, +-91, +-81, +-42, +-6, +38, +56, +82, +77, +73, +44, +18, +-30, +-64, +-95, +-87, +-72, +-28, +3, +45, +60, +83, +71, +63, +30, +1, +-52, +-75, +-97, +-82, +-61, +-16, +16, +58, +67, +81, +66, +57, +18, +-12, +-61, +-83, +-97, +-70, +-45, +7, +25, +66, +68, +81, +59, +49, +0, +-28, +-71, +-88, +-94, +-52, +-31, +20, +40, +75, +70, +81, +53, +35, +-15, +-42, +-90, +-88, +-89, +-41, +-16, +36, +48, +81, +68, +77, +36, +25, +-31, +-52, +-96, +-79, +-80, +-23, +-8, +44, +51, +86, +64, +72, +31, +14, +-48, +-66, +-99, +-74, +-67, +-8, +9, +58, +56, +86, +59, +65, +14, +-3, +-64, +-68, +-103, +-61, +-62, +11, +15, +73, +56, +89, +54, +64, +-2, +-9, +-86, +-70, +-108, +-46, +-44, +28, +16, +90, +53, +97, +33, +62, +-29, +-13, +-106, +-48, +-114, +-14, +-61, +68, +-1, +129, +8, +148, +-49, +145, +-195, +215, +-631, +3326, +9148, +-4817, +-10498, +3889, +15039, +4465, +-12636, +-7787, +9658, +11821, +-4476, +-14737, +-1437, +12367, +5761, +-11561, +-11119, +6296, +11683, +-2846, +-13806, +-2670, +11081, +5826, +-9938, +-10185, +5171, +10877, +-1497, +-12767, +-3358, +10600, +7286, +-8538, +-10862, +4527, +11855, +101, +-12567, +-4632, +10055, +8297, +-7061, +-11248, +3016, +11895, +2035, +-11545, +-5817, +9213, +9410, +-5628, +-11740, +1691, +11795, +3150, +-11043, +-6841, +8438, +10154, +-4217, +-11894, +449, +11789, +4600, +-10386, +-8208, +7313, +10813, +-2960, +-12283, +-1003, +11556, +5931, +-9398, +-9090, +6254, +11355, +-1507, +-12336, +-2581, +10916, +6975, +-8510, +-10094, +5036, +11768, +-39, +-12086, +-3806, +10417, +8049, +-7432, +-10926, +3582, +11801, +1247, +-11833, +-5207, +9668, +9069, +-6099, +-11401, +2352, +11911, +2637, +-11369, +-6554, +8620, +9716, +-4915, +-11865, +931, +11812, +4036, +-10560, +-7579, +7741, +10448, +-3569, +-12184, +-582, +11370, +5153, +-9821, +-8663, +6623, +11019, +-2078, +-12091, +-1851, +11040, +6362, +-8877, +-9667, +5303, +11242, +-798, +-12053, +-3233, +10474, +7496, +-7688, +-10290, +4168, +11550, +602, +-11805, +-4654, +9635, +8311, +-6618, +-10965, +2848, +11660, +2053, +-11223, +-5753, +8909, +9205, +-5385, +-11493, +1374, +11442, +3234, +-10691, +-6951, +7984, +9957, +-3974, +-11655, +151, +11311, +4522, +-9974, +-8093, +6806, +10388, +-2744, +-11837, +-1231, +10978, +5768, +-8967, +-8905, +5801, +10881, +-1381, +-11860, +-2677, +10330, +6722, +-8062, +-9757, +4596, +11216, +71, +-11511, +-3847, +9810, +7744, +-6976, +-10505, +3218, +11209, +1294, +-11218, +-5116, +9066, +8679, +-5684, +-10880, +2042, +11291, +2616, +-10728, +-6381, +8066, +9284, +-4543, +-11299, +710, +11172, +3954, +-9934, +-7315, +7202, +9959, +-3257, +-11558, +-733, +10740, +5002, +-9214, +-8332, +6143, +10495, +-1834, +-11456, +-1917, +10400, +6136, +-8319, +-9256, +4873, +10698, +-625, +-11391, +-3225, +9869, +7209, +-7174, +-9833, +3796, +10969, +703, +-11153, +-4562, +9044, +7971, +-6156, +-10451, +2540, +11067, +2076, +-10575, +-5601, +8354, +8806, +-4976, +-10942, +1141, +10845, +3198, +-10063, +-6720, +7459, +9517, +-3638, +-11069, +-24, +10708, +4406, +-9372, +-7801, +6326, +9909, +-2465, +-11224, +-1328, +10377, +5593, +-8401, +-8542, +5364, +10374, +-1172, +-11221, +-2705, +9750, +6487, +-7531, +-9340, +4219, +10675, +210, +-10881, +-3800, +9229, +7451, +-6499, +-10030, +2895, +10659, +1362, +-10586, +-4997, +8517, +8324, +-5268, +-10368, +1783, +10718, +2613, +-10111, +-6188, +7544, +8892, +-4179, +-10743, +517, +10590, +3878, +-9341, +-7064, +6718, +9522, +-2953, +-10975, +-855, +10160, +4867, +-8645, +-8002, +5708, +10014, +-1600, +-10859, +-1977, +9825, +5937, +-7787, +-8876, +4492, +10193, +-454, +-10779, +-3211, +9304, +6950, +-6693, +-9401, +3455, +10442, +803, +-10533, +-4480, +8507, +7663, +-5715, +-9966, +2259, +10516, +2107, +-9973, +-5448, +7834, +8445, +-4596, +-10417, +929, +10289, +3168, +-9476, +-6498, +6975, +9112, +-3314, +-10517, +-174, +10146, +4308, +-8806, +-7513, +5887, +9472, +-2202, +-10651, +-1417, +9815, +5426, +-7875, +-8201, +4959, +9896, +-980, +-10639, +-2721, +9199, +6263, +-7042, +-8942, +3866, +10171, +338, +-10292, +-3750, +8697, +7173, +-6058, +-9587, +2607, +10144, +1426, +-9997, +-4878, +8001, +8000, +-4875, +-9881, +1542, +10182, +2610, +-9539, +-6004, +7063, +8524, +-3842, +-10224, +336, +10045, +3808, +-8788, +-6821, +6269, +9109, +-2678, +-10435, +-965, +9623, +4738, +-8122, +-7697, +5297, +9568, +-1384, +-10303, +-2025, +9290, +5748, +-7293, +-8517, +4131, +9724, +-298, +-10208, +-3194, +8784, +6708, +-6241, +-8998, +3143, +9942, +892, +-9965, +-4397, +8006, +7377, +-5311, +-9519, +2004, +10007, +2139, +-9416, +-5305, +7358, +8110, +-4243, +-9936, +731, +9774, +3136, +-8930, +-6293, +6525, +8736, +-3016, +-10009, +-324, +9621, +4214, +-8287, +-7245, +5479, +9067, +-1964, +-10125, +-1495, +9295, +5276, +-7389, +-7887, +4589, +9456, +-800, +-10095, +-2735, +8698, +6064, +-6586, +-8569, +3544, +9702, +445, +-9755, +-3718, +8191, +6917, +-5639, +-9159, +2355, +9682, +1502, +-9446, +-4780, +7512, +7674, +-4540, +-9470, +1294, +9673, +2620, +-8976, +-5790, +6667, +8224, +-3505, +-9754, +153, +9511, +3706, +-8323, +-6630, +5835, +8728, +-2395, +-9887, +-1012, +9177, +4664, +-7619, +-7430, +4886, +9113, +-1237, +-9831, +-2109, +8779, +5588, +-6805, +-8128, +3861, +9339, +-126, +-9683, +-3202, +8253, +6434, +-5882, +-8671, +2824, +9478, +1001, +-9394, +-4255, +7608, +7162, +-4915, +-9117, +1732, +9489, +2102, +-8957, +-5217, +6889, +7803, +-3883, +-9427, +612, +9358, +3146, +-8418, +-6119, +6070, +8333, +-2805, +-9596, +-489, +9119, +4145, +-7758, +-6937, +5171, +8741, +-1712, +-9635, +-1598, +8763, +5082, +-6999, +-7643, +4215, +9041, +-605, +-9540, +-2675, +8290, +5931, +-6148, +-8251, +3207, +9220, +503, +-9307, +-3708, +7718, +6698, +-5226, +-8732, +2155, +9275, +1585, +-8945, +-4688, +7047, +7362, +-4238, +-9087, +1079, +9212, +2632, +-8466, +-5607, +6282, +7926, +-3210, +-9315, +-8, +9027, +3634, +-7866, +-6437, +5438, +8382, +-2145, +-9412, +-1096, +8728, +4572, +-7171, +-7178, +4527, +8723, +-1064, +-9370, +-2158, +8318, +5440, +-6378, +-7812, +3568, +8948, +17, +-9203, +-3189, +7798, +6225, +-5508, +-8338, +2555, +9053, +1086, +-8908, +-4179, +7181, +6922, +-4569, +-8738, +1511, +9045, +2127, +-8491, +-5100, +6473, +7518, +-3579, +-9015, +451, +8916, +3125, +-7952, +-5951, +5685, +8015, +-2551, +-9167, +-611, +8673, +4075, +-7315, +-6712, +4820, +8399, +-1501, +-9189, +-1666, +8320, +4952, +-6579, +-7378, +3900, +8666, +-443, +-9077, +-2683, +7852, +5761, +-5767, +-7934, +2925, +8823, +600, +-8846, +-3675, +7296, +6480, +-4871, +-8383, +1917, +8863, +1638, +-8486, +-4601, +6638, +7111, +-3933, +-8707, +884, +8794, +2630, +-8015, +-5469, +5905, +7635, +-2938, +-8913, +-147, +8597, +3590, +-7437, +-6246, +5081, +8068, +-1923, +-8981, +-1187, +8307, +4469, +-6752, +-6946, +4215, +8372, +-877, +-8943, +-2189, +7877, +5308, +-6007, +-7513, +3249, +8623, +4, +-7979, +-2468, +5456, +4095, +-2942, +-4347, +755, +3695, +811, +-2736, +-1588, +1667, +1769, +-767, +-1647, +192, +1336, +192, +-1001, +-420, +679, +569, +-386, +-622, +88, +601, +164, +-492, +-334, +321, +409, +-126, +-379, +-28, +269, +119, +-141, +-142, +27, +119, +34, +-74, +-62, +43, +53, +-33, +-51, +34, +40, +-32, +-46, +24, +42, +-4, +-35, +-14, +15, +27, +1, +-29, +-21, +21, +28, +-8, +-28, +-1, +10, +2, +-2, +0, +-7, +-3, +4, +8, +-5, +-3, +0, +-1, +0, +3, +2, +-1, +-8, +3, +2, +-7, +-3, +1, +0, +-1, +-2, +1, +-4, +2, +4, +-3, +-2, +1, +-5, +0, +-1, +1, +-1, +0, +0, +0, +0, +-2, +0, +-3, +-2, +-1, +1, +-2, +0, +1, +0, +-1, +-1, +1, +0, +0, +-3, +3, +-1, +1, +2, +0, +0, +3, +1, +3, +-1, +0, +-5, +1, +-1, +2, +0, +-1, +0, +-1, +-1, +0, +3, +4, +0, +-2, +0, +0, +-5, +0, +2, +0, +0, +-2, +-4, +1, +1, +1, +4, +-2, +1, +-1, +0, +1, +3, +0, +0, +4, +1, +-1, +1, +4, +-1, +2, +0, +-1, +0, +1, +2, +0, +-2, +-1, +3, +0, +3, +-3, +-1, +-1, +-2, +-5, +0, +1, +-3, +2, +1, +1, +0, +0, +-2, +-1, +4, +0, +2, +0, +-1, +0, +2, +2, +2, +0, +0, +0, +2, +1, +1, +-2, +-1, +0, +-1, +5, +-1, +1, +0, +0, +1, +-4, +-4, +-1, +1, +0, +0, +0, +1, +0, +0, +-1, +0, +0, +3, +1, +0, +-1, +0, +-1, +2, +0, +0, +2, +0, +1, +1, +2, +2, +-2, +1, +0, +-1, +0, +-1, +3, +2, +2, +0, +0, +-1, +-1, +0, +-1, +0, +0, +0, +2, +-1, +0, +1, +-2, +1, +0, +-1, +3, +0, +1, +3, +-1, +2, +0, +-3, +-1, +-2, +0, +-1, +-1, +1, +2, +0, +-1, +4, +2, +-3, +0, +0, +0, +-4, +-2, +-5, +0, +-3, +0, +1, +0, +-1, +1, +1, +-2, +1, +-4, +1, +0, +-1, +2, +2, +0, +0, +2, +-2, +-3, +3, +1, +2, +2, +1, +0, +-3, +0, +3, +-2, +-2, +0, +1, +0, +2, +-1, +0, +1, +1, +0, +-2, +0, +0, +0, +2, +0, +-1, +-1, +0, +-2, +0, +2, +0, +-1, +0, +-2, +-2, +0, +0, +4, +0, +2, +-1, +-1, +4, +3, +2, +1, +0, +2, +1, +-2, +-2, +0, +0, +-4, +1, +0, +0, +-1, +1, +0, +0, +2, +-1, +0, +0, +-2, +0, +2, +-3, +0, +1, +0, +0, +0, +-1, +-1, +-1, +0, +-2, +0, +0, +-1, +-4, +0, +0, +-2, +1, +2, +0, +2, +0, +-1, +-1, +-1, +-1, +0, +1, +0, +1, +0, +-1, +0, +0, +3, +0, +0, +0, +1, +-2, +-1, +-3, +1, +-1, +0, +0, +-2, +0, +-6, +1, +0, +1, +1, +2, +4, +-2, +0, +1, +0, +-2, +0, +0, +1, +0, +0, +0, +0, +0, +-1, +0, +2, +-2, +-3, +1, +0, +0, +0, +1, +0, +2, +0, +0, +-1, +-1, +0, +-1, +0, +2, +2, +-1, +-3, +0, +1, +-3, +-1, +0, +-1, +1, +2, +2, +1, +0, +-1, +2, +0, +1, +1, +-1, +-1, +2, +0, +2, +1, +-1, +1, +0, +0, +-1, +-1, +2, +0, +0, +-1, +2, +2, +1, +1, +-2, +-2, +-2, +-3, +0, +-1, +0, +0, +1, +3, +-2, +39, +143, +24, +-163, +-214, +-56, +159, +225, +126, +-92, +-257, +-197, +21, +191, +184, +55, +-108, +-214, +-132, +64, +180, +161, +48, +-104, +-198, +-115, +81, +194, +156, +26, +-138, +-209, +-84, +120, +199, +122, +-24, +-167, +-189, +-37, +144, +185, +93, +-53, +-177, +-170, +-9, +155, +175, +73, +-78, +-186, +-149, +28, +175, +166, +44, +-107, +-195, +-117, +67, +185, +148, +16, +-133, +-196, +-87, +99, +187, +128, +-13, +-159, +-192, +-53, +128, +190, +106, +-44, +-174, +-173, +-16, +150, +180, +84, +-76, +-192, +-158, +26, +172, +170, +53, +-100, +-200, +-126, +57, +183, +153, +21, +-127, +-202, +-101, +91, +193, +141, +-3, +-150, +-197, +-65, +120, +192, +113, +-32, +-173, +-182, +-31, +147, +184, +92, +-67, +-188, +-166, +11, +169, +174, +62, +-95, +-199, +-141, +47, +179, +164, +37, +-116, +-199, +-106, +81, +187, +140, +6, +-144, +-195, +-79, +113, +190, +121, +-26, +-165, +-186, +-37, +138, +184, +97, +-55, +-182, +-172, +-2, +159, +176, +68, +-83, +-193, +-144, +38, +174, +162, +41, +-112, +-199, +-116, +71, +185, +147, +16, +-138, +-197, +-84, +103, +187, +128, +-19, +-164, +-188, +-47, +131, +188, +104, +-47, +-176, +-170, +-13, +153, +180, +78, +-73, +-187, +-152, +27, +170, +164, +48, +-104, +-195, +-121, +62, +179, +150, +26, +-133, +-192, +-95, +94, +182, +133, +-9, +-151, +-193, +-54, +119, +183, +105, +-32, +-171, +-170, +-26, +153, +175, +87, +-70, +-183, +-158, +18, +160, +175, +53, +-91, +-201, +-126, +45, +180, +151, +36, +-124, +-187, +-98, +89, +177, +145, +-7, +-135, +-198, +-56, +106, +190, +108, +-21, +-171, +-168, +-44, +153, +166, +106, +-69, +-166, +-177, +20, +139, +191, +42, +-60, +-217, +-98, +0, +223, +98, +112, +14, +5850, +12035, +12956, +10341, +4051, +-3450, +-10639, +-14326, +-14105, +-10721, +-5265, +140, +4172, +7393, +10356, +12901, +12846, +9144, +1993, +-6651, +-13443, +-15810, +-13668, +-8828, +-3640, +815, +4114, +6975, +9737, +11359, +10074, +5261, +-2015, +-9282, +-14007, +-14390, +-10955, +-5783, +-948, +2692, +5399, +7955, +10356, +11326, +9042, +3283, +-4257, +-10748, +-13816, +-12605, +-8333, +-3261, +937, +4053, +6678, +9336, +11384, +11247, +7587, +879, +-6639, +-12105, +-13645, +-11162, +-6381, +-1456, +2340, +5217, +7891, +10528, +11970, +10549, +5498, +-1931, +-9097, +-13279, +-13227, +-9649, +-4604, +14, +3483, +6292, +9069, +11471, +11965, +9102, +2855, +-4865, +-11232, +-13908, +-12367, +-7969, +-2885, +1365, +4556, +7365, +10136, +12027, +11346, +7059, +-89, +-7655, +-12836, +-13884, +-11032, +-6123, +-1231, +2614, +5615, +8443, +11043, +12151, +10121, +4543, +-3103, +-10064, +-13784, +-13220, +-9338, +-4225, +321, +3785, +6662, +9484, +11714, +11783, +8348, +1726, +-5992, +-11943, +-14061, +-12041, +-7437, +-2399, +1725, +4887, +7721, +10450, +12054, +10883, +6103, +-1228, +-8588, +-13234, +-13692, +-10461, +-5477, +-709, +2990, +5948, +8776, +11247, +11975, +9446, +3490, +-4171, +-10760, +-13881, +-12785, +-8641, +-3570, +811, +4146, +7003, +9784, +11792, +11417, +7509, +638, +-6929, +-12400, +-13893, +-11438, +-6704, +-1780, +2170, +5235, +8056, +10688, +11988, +10330, +5139, +-2292, +-9353, +-13437, +-13326, +-9770, +-4767, +-160, +3387, +6291, +9092, +11398, +11739, +8720, +2454, +-5159, +-11326, +-13851, +-12255, +-7913, +-2904, +1299, +4515, +7339, +10068, +11823, +10991, +6632, +-423, +-7791, +-12741, +-13651, +-10792, +-5977, +-1190, +2595, +5586, +8387, +10898, +11860, +9722, +4158, +-3325, +-10039, +-13549, +-12896, +-9062, +-4079, +364, +3774, +6638, +9400, +11515, +11441, +7948, +1411, +-6093, +-11810, +-13735, +-11692, +-7186, +-2277, +1757, +4870, +7680, +10327, +11808, +10509, +5732, +-1468, +-8584, +-13000, +-13335, +-10131, +-5268, +-620, +3003, +5934, +8715, +11083, +11679, +9064, +3157, +-4314, +-10653, +-13579, +-12419, +-8347, +-3405, +865, +4150, +6980, +9698, +11583, +11076, +7133, +371, +-6972, +-12204, +-13546, +-11081, +-6457, +-1666, +2195, +5225, +8019, +10563, +11726, +9959, +4792, +-2488, +-9306, +-13169, +-12956, +-9445, +-4571, +-79, +3401, +6279, +9036, +11227, +11428, +8344, +2146, +-5263, +-11180, +-13522, +-11887, +-7628, +-2759, +1341, +4514, +7317, +9968, +11595, +10645, +6266, +-657, +-7795, +-12513, +-13286, +-10440, +-5743, +-1082, +2622, +5575, +8339, +10764, +11581, +9348, +3823, +-3476, +-9952, +-13250, +-12516, +-8741, +-3887, +433, +3784, +6618, +9327, +11318, +11114, +7571, +1126, +-6159, +-11623, +-13389, +-11314, +-6906, +-2137, +1797, +4876, +7647, +10212, +11552, +10149, +5370, +-1675, +-8551, +-12734, +-12955, +-9780, +-5039, +-527, +3027, +5919, +8657, +10921, +11372, +8682, +2838, +-4439, +-10523, +-13245, +-12032, +-8036, +-3235, +927, +4156, +6951, +9602, +11358, +10726, +6751, +113, +-7004, +-11984, +-13177, +-10707, +-6194, +-1542, +2234, +5243, +8017, +10493, +11525, +9661, +4488, +-2662, +-9272, +-12949, +-12673, +-9218, +-4463, +-70, +3389, +6277, +9016, +11123, +11199, +8044, +1897, +-5343, +-11059, +-13254, +-11610, +-7439, +-2700, +1326, +4493, +7308, +9913, +11433, +10364, +5968, +-861, +-7790, +-12314, +-12989, +-10175, +-5588, +-1044, +2610, +5567, +8336, +10674, +11378, +9056, +3554, +-3598, +-9861, +-12982, +-12208, +-8500, +-3778, +458, +3779, +6617, +9301, +11192, +10866, +7273, +910, +-6190, +-11447, +-13081, +-11017, +-6715, +-2068, +1800, +4865, +7643, +10151, +11373, +9864, +5082, +-1834, +-8495, +-12497, +-12640, +-9515, +-4902, +-493, +3017, +5912, +8628, +10811, +11144, +8379, +2587, +-4521, +-10393, +-12965, +-11716, +-7814, +-3145, +932, +4135, +6936, +9549, +11202, +10454, +6445, +-90, +-7005, +-11783, +-12866, +-10422, +-6028, +-1491, +2219, +5203, +7946, +10330, +11234, +9286, +4162, +-2800, +-9151, +-12611, +-12245, +-8853, +-4238, +6, +3376, +6257, +8951, +10917, +10812, +7580, +1558, +-5385, +-10764, +-12778, +-11183, +-7206, +-2632, +1337, +4536, +7372, +9869, +11138, +9875, +5488, +-1095, +-7668, +-11880, +-12489, +-9839, +-5474, +-1050, +2603, +5638, +8390, +10547, +10969, +8509, +3121, +-3712, +-9585, +-12484, +-11757, +-8278, +-3748, +426, +3798, +6702, +9306, +10948, +10362, +6724, +575, +-6150, +-11057, +-12564, +-10636, +-6576, +-2082, +1778, +4920, +7721, +10076, +11016, +9310, +4581, +-2038, +-8303, +-12012, +-12141, +-9224, +-4833, +-526, +3018, +5996, +8677, +10635, +10687, +7815, +2179, +-4568, +-10056, +-12437, +-11279, +-7617, +-3130, +901, +4172, +7028, +9528, +10911, +9930, +5913, +-370, +-6892, +-11337, +-12337, +-10061, +-5903, +-1506, +2207, +5271, +8015, +10219, +10837, +8719, +3693, +-2941, +-8891, +-12095, +-11758, +-8584, +-4186, +-7, +3413, +6320, +8928, +10672, +10357, +7091, +1247, +-5382, +-10463, +-12325, +-10767, +-6946, +-2520, +1364, +4535, +7334, +9716, +10823, +9440, +5083, +-1292, +-7572, +-11540, +-12050, +-9462, +-5243, +-958, +2621, +5607, +8285, +10320, +10601, +8088, +2795, +-3796, +-9401, +-12105, +-11324, +-7933, +-3561, +486, +3786, +6637, +9150, +10662, +9970, +6329, +326, +-6137, +-10786, +-12144, +-10229, +-6285, +-1942, +1801, +4883, +7623, +9866, +10676, +8902, +4230, +-2187, +-8184, +-11671, +-11710, +-8841, +-4601, +-434, +3019, +5932, +8537, +10379, +10313, +7409, +1890, +-4618, +-9841, +-12042, +-10849, +-7282, +-2949, +951, +4149, +6937, +9340, +10604, +9524, +5540, +-577, +-6835, +-11035, +-11910, +-9657, +-5628, +-1385, +2221, +5219, +7892, +9982, +10480, +8309, +3365, +-3045, +-8727, +-11724, +-11314, +-8218, +-3968, +67, +3394, +6245, +8764, +10383, +9967, +6690, +994, +-5388, +-10206, +-11910, +-10336, +-6632, +-2366, +1399, +4497, +7222, +9507, +10483, +9027, +4721, +-1457, +-7470, +-11205, +-11608, +-9071, +-4991, +-850, +2620, +5538, +8138, +10056, +10219, +7679, +2486, +-3866, +-9204, +-11701, +-10882, +-7581, +-3365, +541, +3759, +6544, +8961, +10353, +9554, +5947, +95, +-6087, +-10502, +-11694, +-9835, +-5738, +-1227, +2028, +4488, +6433, +7832, +7878, +6021, +2429, +-1885, +-5389, +-7092, +-6878, +-5184, +-2798, +-318, +1818, +3489, +4592, +4914, +4251, +2642, +374, +-1958, +-3708, +-4383, +-3979, +-2796, +-1253, +281, +1590, +2558, +3082, +3020, +2296, +1060, +-374, +-1651, +-2456, +-2648, +-2267, +-1482, +-497, +493, +1305, +1820, +1979, +1745, +1155, +335, +-527, +-1226, +-1615, +-1616, +-1279, +-727, +-98, +502, +969, +1239, +1237, +992, +543, +7, +-507, +-877, +-1039, +-974, +-720, +-343, +70, +443, +708, +812, +757, +550, +237, +-109, +-416, +-614, +-671, +-592, +-393, +-135, +125, +345, +496, +538, +459, +303, +83, +-137, +-316, +-423, +-434, +-360, +-215, +-41, +132, +272, +351, +353, +287, +165, +14, +-137, +-242, +-302, +-289, +-227, +-116, +9, +125, +214, +253, +246, +185, +92, +-16, +-118, +-188, +-221, +-204, +-145, +-65, +21, +107, +168, +190, +177, +126, +46, +-33, +-104, +-153, +-166, +-144, +-96, +-32, +33, +94, +134, +149, +135, +89, +24, +-39, +-96, +-129, +-135, +-113, +-68, +-16, +40, +91, +119, +123, +104, +65, +9, +-50, +-89, +-113, +-111, +-90, +-50, +0, +49, +87, +108, +111, +90, +43, +-3, +-57, +-90, +-104, +-95, +-74, +-30, +12, +54, +87, +105, +93, +67, +22, +-23, +-62, +-92, +-100, +-84, +-55, +-18, +25, +63, +88, +96, +83, +50, +11, +-34, +-70, +-88, +-93, +-73, +-41, +-6, +36, +71, +93, +90, +73, +37, +-2, +-45, +-79, +-91, +-84, +-63, +-28, +14, +49, +80, +91, +85, +62, +21, +-22, +-58, +-81, +-87, +-77, +-50, +-13, +25, +59, +80, +92, +79, +45, +6, +-36, +-69, +-84, +-84, +-65, +-40, +2, +33, +71, +87, +87, +67, +30, +-8, +-46, +-74, +-89, +-77, +-60, +-22, +9, +48, +76, +86, +81, +54, +15, +-28, +-57, +-81, +-85, +-70, +-46, +-7, +28, +63, +82, +85, +69, +44, +1, +-40, +-70, +-89, +-85, +-63, +-34, +1, +45, +69, +84, +84, +64, +27, +-15, +-50, +-79, +-82, +-76, +-52, +-17, +21, +55, +77, +83, +74, +48, +10, +-30, +-62, +-82, +-85, +-68, +-42, +-1, +32, +66, +82, +86, +69, +38, +-3, +-41, +-70, +-81, +-79, +-60, +-28, +10, +46, +73, +84, +75, +58, +24, +-18, +-53, +-74, +-81, +-70, +-47, +-12, +20, +55, +78, +84, +73, +43, +6, +-29, +-65, +-83, +-84, +-63, +-36, +-3, +35, +65, +82, +84, +65, +30, +-11, +-45, +-71, +-83, +-78, +-54, +-22, +15, +52, +72, +86, +78, +52, +17, +-21, +-60, +-74, +-79, +-71, +-41, +-7, +29, +62, +78, +81, +67, +39, +-1, +-37, +-67, +-79, +-78, +-57, +-28, +1, +33, +56, +70, +64, +45, +23, +-3, +-28, +-43, +-50, +-45, +-30, +-10, +5, +25, +34, +40, +32, +20, +10, +-9, +-20, +-28, +-32, +-24, +-12, +-1, +10, +20, +25, +20, +20, +11, +2, +-9, +-14, +-16, +-19, +-12, +-6, +1, +5, +14, +18, +14, +10, +3, +-1, +-7, +-13, +-12, +-13, +-5, +0, +3, +8, +7, +10, +6, +7, +4, +-3, +-4, +-7, +-5, +-8, +-1, +-1, +5, +6, +6, +5, +6, +2, +-3, +-3, +-3, +-6, +-4, +0, +0, +-1, +3, +0, +1, +0, +2, +0, +-2, +-1, +-7, +-4, +-2, +0, +0, +0, +2, +1, +0, +4, +0, +0, +-2, +-2, +0, +-4, +2, +-2, +1, +0, +1, +0, +0, +3, +0, +1, +0, +0, +-2, +-2, +-1, +-3, +0, +2, +-1, +0, +1, +1, +0, +1, +1, +-1, +2, +0, +0, +1, +1, +0, +-2, +2, +-1, +1, +-1, +24, +135, +163, +85, +-34, +-160, +-259, +-282, +-218, +-94, +45, +166, +225, +234, +217, +183, +132, +36, +-102, +-231, +-321, +-310, +-214, +-57, +84, +182, +220, +217, +194, +164, +97, +-6, +-134, +-246, +-295, +-255, +-134, +14, +129, +195, +208, +191, +161, +125, +53, +-48, +-180, +-270, +-287, +-211, +-77, +63, +155, +199, +198, +178, +149, +108, +20, +-102, +-221, +-287, +-274, +-168, +-27, +103, +180, +204, +193, +173, +149, +81, +-24, +-149, +-267, +-299, +-243, +-124, +29, +140, +201, +205, +195, +174, +125, +51, +-69, +-199, +-288, +-296, +-206, +-70, +76, +169, +210, +208, +191, +156, +104, +7, +-122, +-247, +-302, +-276, +-160, +-12, +121, +194, +216, +208, +184, +146, +71, +-42, +-174, +-280, +-304, +-241, +-100, +43, +156, +211, +216, +194, +175, +121, +36, +-96, +-224, +-299, +-289, +-197, +-47, +91, +188, +218, +212, +189, +161, +92, +-8, +-148, +-263, +-312, +-264, +-143, +12, +132, +203, +217, +210, +180, +143, +57, +-61, +-201, +-291, +-313, +-224, +-86, +66, +165, +220, +213, +202, +164, +119, +15, +-107, +-248, +-305, +-295, +-173, +-32, +113, +190, +225, +206, +193, +147, +89, +-36, +-159, +-288, +-306, +-263, +-121, +24, +153, +206, +229, +199, +187, +123, +54, +-93, +-206, +-311, +-294, +-223, +-54, +72, +190, +213, +230, +188, +174, +95, +12, +-144, +-245, +-330, +-266, +-173, +8, +114, +221, +209, +228, +171, +159, +51, +-31, +-203, +-277, +-333, +-226, +-120, +70, +146, +237, +203, +225, +153, +145, +4, +-76, +-260, +-287, +-330, +-169, +-75, +132, +160, +265, +184, +236, +120, +136, +-62, +-105, +-327, +-260, +-333, +-73, +-61, +225, +118, +333, +91, +326, +-29, +271, +-355, +204, +-925, +7150, +5453, +-11337, +-4078, +13422, +12031, +-9225, +-11808, +8047, +13282, +-3248, +-13812, +-771, +11636, +1964, +-12191, +-6047, +9031, +6849, +-9518, +-9829, +6894, +9936, +-6038, +-13154, +2731, +11699, +-1485, +-13798, +-2456, +11366, +4489, +-10956, +-6814, +8599, +8494, +-6825, +-10319, +4453, +10450, +-2664, +-12255, +-98, +11500, +2521, +-11475, +-4332, +10658, +7093, +-8890, +-8611, +7263, +9907, +-4943, +-11527, +2437, +11258, +339, +-11505, +-2001, +11179, +5293, +-9888, +-6632, +8829, +8806, +-6935, +-10534, +4692, +10923, +-2255, +-11740, +416, +11788, +3007, +-10923, +-4473, +10138, +7132, +-8564, +-8999, +6513, +9861, +-4524, +-11319, +2573, +11710, +722, +-11512, +-2211, +11099, +5222, +-10039, +-7109, +8221, +8492, +-6759, +-10390, +4629, +11134, +-1652, +-11453, +88, +11498, +3090, +-10935, +-4978, +9536, +6836, +-8609, +-9074, +6471, +10151, +-3964, +-10968, +2401, +11479, +819, +-11382, +-2641, +10455, +4936, +-10031, +-7347, +7963, +8752, +-6065, +-10000, +4523, +11039, +-1454, +-11348, +-285, +10983, +2874, +-10994, +-5335, +9153, +7015, +-7915, +-8634, +6420, +10162, +-3633, +-10825, +2017, +11056, +730, +-11450, +-3136, +9970, +5042, +-9428, +-6969, +8011, +8921, +-5642, +-9861, +4161, +10701, +-1422, +-11405, +-846, +10403, +2900, +-10528, +-5080, +9226, +7346, +-7380, +-8509, +6076, +9933, +-3508, +-10879, +1427, +10469, +685, +-11165, +-3051, +10035, +5488, +-8801, +-6832, +7704, +8793, +-5438, +-9923, +3587, +10153, +-1506, +-11309, +-963, +10427, +3415, +-9840, +-4918, +8997, +7315, +-7136, +-8578, +5544, +9469, +-3592, +-10952, +1117, +10407, +1212, +-10469, +-2866, +9916, +5582, +-8513, +-6933, +7222, +8439, +-5485, +-10121, +3110, +9989, +-1026, +-10672, +-762, +10428, +3648, +-9527, +-5047, +8566, +7094, +-7124, +-8869, +4940, +9212, +-3210, +-10434, +1291, +10521, +1592, +-10114, +-3015, +9538, +5475, +-8448, +-7267, +6568, +8112, +-5225, +-9780, +3218, +10200, +-503, +-10268, +-910, +10115, +3641, +-9405, +-5393, +7909, +6740, +-6998, +-8733, +4946, +9474, +-2577, +-9985, +1177, +10289, +1684, +-9965, +-3354, +8929, +5151, +-8418, +-7347, +6425, +8375, +-4537, +-9302, +3162, +10072, +-335, +-10119, +-1243, +9594, +3396, +-9455, +-5664, +7622, +6955, +-6306, +-8262, +4958, +9475, +-2316, +-9849, +845, +9863, +1532, +-10057, +-3779, +8511, +5279, +-7808, +-6919, +6509, +8526, +-4175, +-9180, +2836, +9740, +-376, +-10212, +-1766, +9074, +3427, +-8977, +-5346, +7741, +7252, +-5840, +-8139, +4651, +9235, +-2256, +-9933, +289, +9301, +1473, +-9750, +-3611, +8635, +5697, +-7245, +-6780, +6235, +8373, +-4041, +-9254, +2284, +9196, +-485, +-10091, +-1786, +9155, +3922, +-8336, +-5173, +7539, +7190, +-5648, +-8212, +4137, +8754, +-2385, +-9983, +69, +9295, +1990, +-9081, +-3403, +8522, +5750, +-7010, +-6867, +5772, +7988, +-4145, +-9438, +1890, +9080, +-17, +-9451, +-1546, +9157, +4100, +-8064, +-5285, +7127, +6922, +-5705, +-8486, +3606, +8533, +-2005, +-9437, +296, +9418, +2309, +-8763, +-3527, +8164, +5595, +-7002, +-7190, +5166, +7700, +-3839, +-8982, +2109, +9296, +406, +-9120, +-1663, +8916, +4122, +-7964, +-5644, +6441, +6523, +-5584, +-8265, +3717, +8798, +-1489, +-9103, +142, +9169, +2368, +-8646, +-3869, +7507, +5173, +-7043, +-7206, +5138, +7990, +-3253, +-8639, +1964, +9136, +584, +-8918, +-1954, +8316, +3704, +-8117, +-5833, +6325, +6860, +-4884, +-7828, +3671, +8755, +-1214, +-8862, +-45, +8779, +2120, +-8826, +-4254, +7233, +5449, +-6334, +-6734, +5184, +8034, +-2958, +-8445, +1781, +8860, +465, +-9126, +-2502, +7847, +3832, +-7532, +-5422, +6440, +7027, +-4553, +-7700, +3469, +8585, +-1203, +-9030, +-673, +8178, +2092, +-8413, +-3944, +7401, +5755, +-5929, +-6650, +4961, +7946, +-2819, +-8553, +1165, +8222, +302, +-8929, +-2363, +8032, +4265, +-7035, +-5331, +6228, +6998, +-4325, +-7742, +2925, +7987, +-1439, +-9055, +-730, +8313, +2610, +-7835, +-3818, +7229, +5783, +-5663, +-6652, +4526, +7467, +-3064, +-8766, +884, +8253, +844, +-8293, +-2174, +7933, +4347, +-6790, +-5372, +5859, +6668, +-4487, +-8009, +2550, +7968, +-916, +-8464, +-575, +8250, +2702, +-7649, +-3942, +6897, +5588, +-5714, +-6929, +4093, +7404, +-2580, +-8221, +1062, +8276, +994, +-8169, +-2392, +7612, +4259, +-6747, +-5631, +5414, +6558, +-4113, +-7626, +2640, +8017, +-698, +-8328, +-782, +8004, +2756, +-7501, +-4151, +6480, +5459, +-5462, +-6727, +4087, +7477, +-2318, +-8106, +826, +8075, +1134, +-7964, +-2554, +7264, +4164, +-6567, +-5571, +5331, +6654, +-3811, +-7539, +2380, +7836, +-518, +-8106, +-906, +7742, +2718, +-7378, +-4214, +6339, +5581, +-5125, +-6659, +3818, +7308, +-2143, +-7924, +713, +7908, +1187, +-7864, +-2714, +7064, +4288, +-6224, +-5507, +5084, +6522, +-3652, +-7420, +2249, +7749, +-375, +-8008, +-1129, +7507, +2841, +-7055, +-4169, +6127, +5506, +-4982, +-6623, +3648, +7281, +-1913, +-7814, +464, +7660, +1296, +-7591, +-2696, +6908, +4298, +-6077, +-5561, +4868, +6524, +-3372, +-7301, +2009, +7522, +-281, +-7810, +-1174, +7398, +2938, +-6891, +-4286, +5866, +5516, +-4686, +-6500, +3440, +7104, +-1813, +-7700, +355, +7578, +1467, +-7399, +-2850, +6627, +4306, +-5797, +-5470, +4696, +6428, +-3246, +-7265, +1827, +7450, +-48, +-7599, +-1333, +7122, +2946, +-6662, +-4247, +5726, +5510, +-4525, +-6525, +3197, +7027, +-1563, +-7488, +211, +7348, +1496, +-7240, +-2884, +6501, +4382, +-5593, +-5521, +4416, +6343, +-3002, +-7076, +1700, +7287, +7, +-7491, +-1444, +6996, +3087, +-6417, +-4309, +5443, +5427, +-4307, +-6397, +3083, +6949, +-1441, +-7418, +22, +7202, +1670, +-6975, +-2947, +6241, +4318, +-5415, +-5465, +4292, +6340, +-2823, +-7034, +1462, +7132, +189, +-7240, +-1504, +6792, +3067, +-6274, +-4346, +5293, +5474, +-4067, +-6360, +2820, +6780, +-1276, +-7215, +-40, +7062, +1719, +-6859, +-3060, +6060, +4404, +-5141, +-5430, +4035, +6194, +-2681, +-6892, +1369, +7056, +312, +-7126, +-1683, +6585, +3155, +-5995, +-4316, +5087, +5370, +-3928, +-6308, +2695, +6741, +-1067, +-7117, +-231, +6813, +1838, +-6671, +-2727, +5481, +3142, +-3572, +-3358, +2093, +2894, +-812, +-2327, +56, +1813, +342, +-1493, +-467, +1203, +660, +-1032, +-737, +829, +719, +-607, +-645, +403, +589, +-240, +-461, +36, +313, +118, +-138, +-162, +11, +112, +19, +-98, +48, +133, +-72, +-182, +41, +182, +0, +-125, +10, +69, +-37, +-61, +31, +48, +14, +-6, +-31, +-60, +0, +63, +32, +-21, +-10, +-25, +-46, +-2, +75, +38, +-33, +-35, +-4, +-13, +0, +38, +30, +-18, +-29, +-19, +-12, +6, +46, +29, +-20, +-38, +-19, +-6, +18, +44, +22, +-28, +-43, +-17, +11, +25, +33, +12, +-24, +-38, +-12, +12, +29, +30, +6, +-29, +-37, +-12, +16, +31, +26, +-1, +-33, +-37, +-6, +25, +36, +23, +-10, +-36, +-31, +0, +31, +32, +14, +-14, +-34, +-27, +3, +27, +34, +10, +-15, +-35, +-26, +5, +35, +34, +1, +-28, +-34, +-18, +13, +34, +22, +-4, +-26, +-34, +-12, +18, +37, +19, +-6, +-29, +-26, +-6, +25, +34, +19, +-13, +-34, +-24, +2, +28, +29, +11, +-18, +-35, +-25, +6, +28, +29, +8, +-24, +-33, +-12, +12, +33, +26, +0, +-27, +-32, +-8, +15, +31, +21, +-6, +-31, +-31, +-7, +21, +35, +19, +-9, +-34, +-28, +0, +25, +34, +12, +-18, +-34, +-22, +5, +30, +34, +5, +-23, +-34, +-20, +11, +34, +29, +3, +-26, +-31, +-10, +14, +34, +23, +-3, +-31, +-29, +-2, +21, +37, +20, +-9, +-33, +-25, +-3, +24, +33, +16, +-15, +-34, +-22, +0, +24, +33, +10, +-21, +-31, +-16, +7, +29, +27, +7, +-21, +-31, +-13, +13, +31, +22, +-1, +-29, +-30, +-9, +17, +31, +24, +-14, +-29, +-27, +-1, +20, +35, +18, +-10, +-33, +-19, +3, +26, +28, +8, +-17, +-32, +-24, +7, +28, +27, +6, +-21, +-31, +-13, +15, +29, +24, +-4, +-25, +-27, +-9, +16, +35, +20, +-8, +-29, +-29, +-3, +22, +32, +16, +-12, +-27, +-24, +2, +26, +30, +7, +-19, +-31, +-19, +7, +30, +30, +7, +-22, +-33, +-16, +11, +33, +27, +-1, +-22, +-31, +-11, +10, +32, +23, +-8, +-27, +-26, +-6, +22, +25, +18, +-12, +-28, +-23, +-2, +26, +30, +9, +-17, +-29, +-21, +3, +29, +27, +7, +-19, +-27, +-18, +9, +30, +27, +3, +-24, +-29, +-9, +15, +30, +18, +-4, +-24, +-30, +-7, +20, +34, +15, +-12, +-28, +-23, +-1, +26, +32, +12, +-13, +-32, +-25, +3, +26, +27, +9, +-19, +-28, +-16, +11, +29, +26, +5, +-21, +-32, +-14, +12, +25, +22, +-3, +-24, +-26, +-12, +11, +24, +16, +-4, +-16, +-15, +-3, +13, +13, +6, +-5, +-13, +-9, +-1, +9, +8, +3, +-3, +-6, +-6, +1, +6, +7, +2, +-4, +-4, +-1, +2, +4, +1, +-4, +0, +-3, +1, +3, +4, +0, +1, +-1, +-2, +-1, +3, +1, +3, +4, +1, +1, +1, +0, +2, +-1, +-4, +-3, +-1, +-1, +0, +1, +-1, +2, +2, +0, +-1, +0, +-1, +-1, +-1, +-1, +1, +0, +2, +0, +1, +1, +-3, +0, +0, +-4, +-2, +-1, +1, +0, +-1, +0, +1, +0, +4, +-1, +1, +-2, +0, +0, +1, +3, +1, +0, +0, +2, +0, +0, +-3, +0, +-4, +-5, +1, +-1, +-2, +3, +0, +0, +0, +1, +0, +-1, +-1, +-1, +1, +0, +0, +0, +-2, +-4, +1, +0, +0, +-4, +0, +-5, +-2, +0, +2, +-4, +3, +-2, +1, +-6, +1, +0, +4, +-3, +6, +-7, +14, +-9, +203, +121, +-409, +-215, +372, +396, +-247, +-546, +8, +484, +157, +-455, +-369, +305, +455, +-107, +-509, +-57, +483, +251, +-364, +-358, +256, +449, +-63, +-458, +-76, +422, +252, +-322, +-376, +197, +435, +-16, +-465, +-143, +405, +288, +-291, +-410, +151, +441, +32, +-447, +-192, +366, +324, +-234, +-430, +85, +444, +85, +-421, +-240, +329, +355, +-190, +-440, +40, +441, +133, +-395, +-281, +299, +384, +-146, +-453, +-14, +433, +185, +-368, +-326, +256, +408, +-90, +-459, +-66, +418, +230, +-333, +-364, +208, +430, +-35, +-457, +-117, +402, +268, +-301, +-391, +164, +434, +11, +-444, +-170, +376, +306, +-249, +-415, +110, +441, +66, +-428, +-221, +349, +342, +-204, +-435, +61, +439, +116, +-408, +-263, +311, +370, +-158, +-444, +8, +433, +161, +-379, +-305, +272, +394, +-112, +-449, +-42, +419, +206, +-345, +-340, +228, +408, +-58, +-445, +-95, +403, +247, +-308, +-368, +183, +423, +-7, +-433, +-144, +383, +285, +-265, +-394, +132, +433, +36, +-424, +-195, +353, +321, +-219, +-413, +83, +430, +90, +-406, +-236, +317, +347, +-172, +-425, +32, +425, +137, +-375, +-279, +280, +373, +-128, +-434, +-19, +415, +183, +-351, +-311, +238, +394, +-78, +-437, +-71, +402, +225, +-316, +-344, +197, +409, +-33, +-429, +-116, +380, +262, +-272, +-371, +149, +413, +20, +-419, +-165, +350, +298, +-234, +-394, +97, +416, +64, +-398, +-212, +324, +325, +-187, +-414, +56, +416, +117, +-381, +-251, +285, +357, +-146, +-417, +3, +411, +154, +-345, +-291, +252, +369, +-97, +-426, +-44, +393, +199, +-325, +-323, +203, +393, +-52, +-416, +-99, +379, +235, +-285, +-357, +165, +395, +0, +-417, +-136, +344, +283, +-254, +-366, +110, +411, +38, +-385, +-200, +337, +292, +-193, +-402, +86, +386, +110, +-396, +-194, +265, +369, +-205, +-349, +112, +4771, +8924, +8993, +7185, +3291, +-1749, +-7216, +-10116, +-9842, +-7512, +-4077, +-718, +2290, +5266, +7652, +9125, +8749, +6544, +2082, +-4124, +-9421, +-11218, +-9450, +-6162, +-3151, +-386, +2400, +5110, +7128, +7789, +6764, +3897, +-828, +-6182, +-9932, +-10158, +-7556, +-4233, +-1429, +1072, +3647, +5934, +7381, +7640, +6231, +2751, +-2413, +-7362, +-9776, +-8724, +-5680, +-2611, +-176, +2260, +4843, +6937, +7939, +7571, +5428, +1219, +-4152, +-8404, +-9553, +-7596, +-4418, +-1553, +832, +3362, +5865, +7641, +8161, +7162, +4200, +-703, +-6016, +-9285, +-9141, +-6502, +-3359, +-706, +1735, +4385, +6730, +8095, +8031, +6305, +2518, +-2809, +-7650, +-9706, +-8428, +-5395, +-2385, +144, +2700, +5338, +7391, +8252, +7592, +5089, +555, +-4871, +-8880, +-9608, +-7433, +-4263, +-1454, +1032, +3686, +6204, +7851, +8157, +6830, +3539, +-1538, +-6695, +-9575, +-9043, +-6262, +-3150, +-531, +1993, +4670, +6928, +8099, +7811, +5783, +1735, +-3612, +-8133, +-9725, +-8114, +-5032, +-2109, +386, +2986, +5583, +7486, +8121, +7217, +4445, +-241, +-5530, +-9105, +-9374, +-6977, +-3844, +-1125, +1339, +3981, +6389, +7855, +7925, +6352, +2831, +-2284, +-7168, +-9557, +-8636, +-5753, +-2732, +-195, +2310, +4939, +7047, +8011, +7486, +5218, +994, +-4267, +-8411, +-9507, +-7617, +-4531, +-1715, +723, +3299, +5811, +7536, +7952, +6804, +3798, +-975, +-6062, +-9183, +-9012, +-6450, +-3379, +-769, +1670, +4276, +6554, +7819, +7658, +5859, +2134, +-2972, +-7543, +-9448, +-8173, +-5233, +-2317, +139, +2634, +5189, +7143, +7890, +7138, +4638, +273, +-4870, +-8609, +-9235, +-7105, +-4044, +-1340, +1054, +3605, +6009, +7555, +7746, +6376, +3155, +-1680, +-6535, +-9189, +-8611, +-5926, +-2938, +-423, +1990, +4548, +6692, +7756, +7376, +5344, +1439, +-3625, +-7848, +-9283, +-7695, +-4730, +-1921, +469, +2942, +5426, +7213, +7749, +6770, +4046, +-430, +-5410, +-8734, +-8916, +-6596, +-3578, +-978, +1368, +3898, +6188, +7545, +7518, +5920, +2497, +-2355, +-6935, +-9130, +-8190, +-5410, +-2517, +-89, +2305, +4812, +6806, +7665, +7060, +4806, +745, +-4223, +-8090, +-9051, +-7200, +-4236, +-1540, +790, +3250, +5644, +7255, +7571, +6373, +3432, +-1122, +-5900, +-8786, +-8556, +-6076, +-3129, +-636, +1688, +4178, +6344, +7499, +7261, +5435, +1837, +-3001, +-7274, +-9010, +-7741, +-4902, +-2114, +238, +2614, +5054, +6893, +7539, +6719, +4246, +65, +-4780, +-8253, +-8782, +-6703, +-3769, +-1179, +1104, +3542, +5832, +7263, +7362, +5947, +2811, +-1785, +-6332, +-8772, +-8166, +-5570, +-2703, +-301, +1999, +4441, +6475, +7426, +6968, +4932, +1174, +-3605, +-7549, +-8831, +-7269, +-4418, +-1731, +545, +2911, +5275, +6943, +7380, +6347, +3669, +-600, +-5282, +-8351, +-8461, +-6206, +-3319, +-835, +1408, +3822, +5991, +7235, +7124, +5493, +2185, +-2418, +-6702, +-8698, +-7746, +-5069, +-2298, +12, +2300, +4690, +6568, +7322, +6645, +4405, +521, +-4165, +-7757, +-8600, +-6794, +-3949, +-1371, +863, +3226, +5522, +7053, +7289, +6040, +3142, +-1234, +-5771, +-8479, +-8223, +-5830, +-2993, +-582, +1682, +4097, +6194, +7280, +6968, +5126, +1613, +-3009, +-7055, +-8666, +-7428, +-4708, +-2018, +258, +2572, +4934, +6705, +7270, +6399, +3939, +-91, +-4700, +-7964, +-8425, +-6420, +-3588, +-1094, +1125, +3482, +5698, +7051, +7084, +5629, +2562, +-1842, +-6148, +-8430, +-7817, +-5314, +-2557, +-239, +1999, +4363, +6312, +7196, +6675, +4627, +984, +-3570, +-7288, +-8470, +-6950, +-4208, +-1620, +594, +2881, +5163, +6766, +7126, +6042, +3397, +-712, +-5156, +-8040, +-8105, +-5928, +-3152, +-753, +1423, +3757, +5856, +7021, +6841, +5189, +1959, +-2443, +-6492, +-8362, +-7417, +-4846, +-2177, +61, +2280, +4594, +6402, +7084, +6348, +4120, +354, +-4102, +-7487, +-8255, +-6505, +-3762, +-1277, +878, +3150, +5350, +6774, +6928, +5647, +2825, +-1334, +-5584, +-8081, +-7776, +-5460, +-2748, +-445, +1736, +3992, +5904, +6954, +6693, +4779, +1214, +-3129, +-6672, +-8053, +-7057, +-4593, +-1846, +580, +2685, +4628, +6266, +7047, +6269, +3571, +-522, +-4667, +-7376, +-7820, +-6228, +-3573, +-856, +1448, +3425, +5245, +6652, +6947, +5440, +2094, +-2180, +-5887, +-7754, +-7364, +-5265, +-2496, +80, +2223, +4106, +5812, +6900, +6580, +4330, +492, +-3717, +-6815, +-7808, +-6676, +-4218, +-1463, +936, +2946, +4764, +6300, +6942, +5913, +2981, +-1141, +-5059, +-7416, +-7552, +-5810, +-3144, +-494, +1729, +3635, +5370, +6656, +6735, +4977, +1480, +-2722, +-6160, +-7680, +-7032, +-4819, +-2083, +400, +2461, +4293, +5912, +6831, +6260, +3786, +-109, +-4167, +-6954, +-7627, +-6287, +-3772, +-1086, +1222, +3158, +4924, +6351, +6786, +5504, +2399, +-1705, +-5408, +-7433, +-7279, +-5380, +-2717, +-153, +1980, +3829, +5503, +6640, +6484, +4487, +881, +-3219, +-6383, +-7578, +-6678, +-4377, +-1687, +707, +2690, +4471, +5997, +6735, +5914, +3241, +-692, +-4576, +-7053, +-7416, +-5881, +-3334, +-723, +1489, +3367, +5078, +6380, +6595, +5072, +1823, +-2242, +-5707, +-7411, +-6977, +-4950, +-2301, +168, +2222, +4017, +5617, +6598, +6200, +3985, +303, +-3677, +-6563, +-7442, +-6311, +-3947, +-1311, +989, +2908, +4638, +6073, +6612, +5544, +2689, +-1250, +-4945, +-7112, +-7175, +-5473, +-2914, +-385, +1746, +3569, +5211, +6387, +6381, +4620, +1245, +-2739, +-5961, +-7341, +-6663, +-4525, +-1908, +473, +2451, +4198, +5722, +6529, +5894, +3470, +-267, +-4107, +-6700, +-7266, +-5938, +-3520, +-948, +1261, +3118, +4794, +6116, +6452, +5151, +2140, +-1781, +-5268, +-7121, +-6913, +-5071, +-2508, +-55, +1985, +3759, +5342, +6368, +6141, +4154, +684, +-3214, +-6171, +-7243, +-6326, +-4110, +-1529, +759, +2667, +4369, +5801, +6429, +5562, +2949, +-820, +-4491, +-6787, +-7068, +-5556, +-3112, +-607, +1514, +3319, +4940, +6142, +6271, +4734, +1585, +-2285, +-5547, +-7093, +-6633, +-4661, +-2120, +246, +2217, +3941, +5448, +6324, +5865, +3680, +123, +-3645, +-6351, +-7098, +-6000, +-3543, +-825, +1164, +2675, +3882, +4772, +4826, +3711, +1525, +-1096, +-3239, +-4295, +-4193, +-3188, +-1754, +-244, +1068, +2102, +2792, +3006, +2621, +1653, +274, +-1157, +-2242, +-2677, +-2447, +-1739, +-800, +138, +945, +1546, +1885, +1867, +1435, +687, +-197, +-988, +-1497, +-1632, +-1409, +-938, +-335, +273, +779, +1115, +1227, +1094, +741, +238, +-304, +-750, +-1002, +-1012, +-814, +-475, +-86, +291, +591, +768, +785, +644, +371, +27, +-298, +-543, +-663, +-628, +-470, +-236, +22, +263, +436, +519, +496, +376, +181, +-46, +-252, +-391, +-442, +-395, +-270, +-109, +64, +215, +320, +357, +321, +221, +82, +-73, +-205, +-286, +-302, +-251, +-164, +-40, +75, +175, +236, +253, +215, +142, +28, +-80, +-169, +-215, +-217, +-169, +-100, +-12, +74, +146, +185, +186, +155, +91, +2, +-77, +-141, +-167, +-158, +-121, +-59, +7, +73, +123, +150, +148, +117, +59, +-11, +-81, +-123, +-139, +-125, +-92, +-37, +17, +71, +110, +131, +125, +87, +32, +-28, +-82, +-111, +-120, +-103, +-68, +-20, +29, +75, +106, +120, +106, +69, +14, +-38, +-86, +-103, +-109, +-86, +-49, +-6, +34, +78, +102, +108, +89, +44, +-2, +-50, +-84, +-103, +-95, +-75, +-37, +7, +51, +80, +98, +100, +75, +31, +-16, +-62, +-91, +-98, +-85, +-56, +-19, +21, +58, +88, +97, +87, +58, +11, +-35, +-73, +-89, +-94, +-76, +-45, +-8, +29, +68, +93, +94, +78, +44, +-7, +-49, +-83, +-91, +-88, +-60, +-30, +7, +46, +79, +97, +90, +67, +22, +-22, +-61, +-88, +-92, +-76, +-55, +-15, +18, +56, +83, +95, +85, +50, +6, +-38, +-69, +-90, +-88, +-68, +-40, +-3, +35, +73, +91, +91, +77, +37, +-9, +-52, +-79, +-90, +-86, +-62, +-25, +8, +47, +79, +93, +88, +61, +19, +-26, +-66, +-88, +-88, +-74, +-48, +-14, +26, +61, +86, +97, +85, +47, +1, +-39, +-76, +-90, +-85, +-70, +-36, +1, +38, +71, +93, +90, +70, +30, +-14, +-56, +-86, +-92, +-80, +-54, +-21, +15, +50, +78, +93, +84, +53, +13, +-29, +-69, +-89, +-92, +-72, +-44, +-9, +36, +64, +86, +92, +75, +41, +-4, +-44, +-80, +-87, +-82, +-64, +-31, +11, +47, +73, +97, +85, +65, +23, +-23, +-59, +-85, +-92, +-78, +-50, +-18, +20, +56, +84, +93, +82, +50, +8, +-37, +-68, +-88, +-88, +-67, +-39, +-4, +35, +65, +90, +93, +70, +38, +-11, +-51, +-74, +-95, +-86, +-62, +-23, +11, +49, +78, +93, +83, +57, +15, +-25, +-60, +-79, +-86, +-74, +-47, +-7, +23, +57, +87, +90, +80, +44, +2, +-40, +-74, +-89, +-85, +-62, +-31, +3, +35, +60, +72, +68, +54, +23, +-6, +-32, +-47, +-51, +-47, +-33, +-13, +2, +26, +36, +40, +36, +24, +4, +-12, +-20, +-32, +-32, +-29, +-16, +-6, +7, +17, +27, +24, +21, +10, +-2, +-6, +-16, +-18, +-18, +-14, +-9, +0, +7, +13, +13, +15, +12, +5, +-2, +-3, +-14, +-13, +-8, +-9, +-1, +1, +7, +8, +8, +10, +4, +1, +-4, +-10, +-11, +-6, +-7, +-4, +1, +2, +4, +3, +6, +5, +1, +0, +0, +-5, +-5, +-1, +-7, +0, +0, +4, +4, +3, +0, +2, +1, +0, +0, +-4, +-5, +4, +0, +-1, +-1, +2, +3, +0, +1, +4, +-1, +0, +0, +-4, +-2, +-1, +0, +5, +0, +0, +1, +1, +-2, +1, +-1, +1, +0, +-2, +-3, +-2, +1, +0, +-2, +2, +0, +1, +0, +-1, +-2, +0, +0, +-1, +-2, +0, +0, +0, +0, +4, +-1, +1, +0, +-5, +32, +201, +238, +122, +-47, +-232, +-366, +-402, +-317, +-143, +45, +226, +315, +333, +308, +273, +199, +60, +-126, +-324, +-453, +-446, +-304, +-87, +112, +250, +306, +302, +279, +239, +143, +0, +-184, +-338, +-412, +-357, +-196, +7, +174, +268, +283, +271, +238, +187, +88, +-66, +-247, +-375, +-405, +-302, +-119, +75, +209, +271, +272, +256, +221, +158, +39, +-128, +-305, +-400, +-379, +-242, +-47, +132, +239, +276, +265, +248, +204, +124, +-26, +-200, +-355, +-406, +-340, +-169, +20, +180, +258, +283, +265, +241, +183, +81, +-93, +-270, +-394, +-402, +-289, +-94, +86, +220, +273, +283, +259, +227, +149, +18, +-161, +-325, +-414, +-367, +-222, +-20, +145, +252, +282, +281, +250, +205, +108, +-47, +-233, +-372, +-412, +-320, +-153, +47, +194, +271, +282, +275, +234, +180, +52, +-111, +-291, +-397, +-392, +-264, +-76, +115, +225, +284, +279, +264, +213, +138, +-9, +-186, +-348, +-411, +-360, +-188, +-4, +166, +253, +286, +267, +248, +194, +91, +-76, +-249, +-385, +-397, +-306, +-116, +66, +210, +267, +285, +262, +233, +158, +35, +-143, +-308, +-402, +-370, +-239, +-44, +124, +245, +278, +278, +251, +210, +117, +-23, +-213, +-354, +-407, +-333, +-169, +25, +175, +266, +279, +269, +231, +185, +69, +-97, +-270, +-384, +-389, +-275, +-91, +92, +210, +272, +277, +260, +220, +148, +8, +-162, +-325, +-402, +-356, +-211, +-21, +146, +248, +275, +270, +241, +198, +97, +-50, +-233, +-365, +-398, +-308, +-139, +49, +187, +265, +272, +266, +222, +170, +43, +-115, +-291, +-384, +-382, +-243, +-71, +120, +219, +282, +262, +263, +205, +136, +-26, +-169, +-351, +-378, +-355, +-162, +-18, +186, +223, +304, +235, +278, +146, +116, +-102, +-292, +407, +5702, +-4959, +-3001, +10366, +471, +-7761, +5304, +6877, +-8595, +-1577, +10209, +-4571, +-9138, +7803, +2993, +-11132, +959, +9291, +-7177, +-6353, +10098, +502, +-10931, +4559, +7537, +-9434, +-3922, +9909, +-3068, +-9723, +7171, +5334, +-10092, +145, +10006, +-5189, +-6974, +8983, +1910, +-10449, +2847, +7841, +-7984, +-4153, +9790, +-1033, +-8750, +6399, +5888, +-8901, +-526, +9483, +-4587, +-7221, +7834, +2178, +-9680, +2775, +8199, +-6782, +-3833, +9649, +-658, +-8536, +5874, +5669, +-9010, +-1147, +8970, +-4431, +-7108, +8138, +2889, +-9161, +2801, +8451, +-6657, +-4177, +9388, +-720, +-9210, +5199, +5645, +-8961, +-1255, +9596, +-3643, +-7039, +8163, +3368, +-9318, +2237, +8420, +-6786, +-5133, +8897, +-487, +-9291, +5150, +6547, +-8313, +-1429, +9761, +-3157, +-7449, +7639, +3473, +-9681, +1221, +8239, +-6490, +-5299, +9107, +530, +-8933, +4937, +6909, +-8026, +-2031, +9453, +-3068, +-8102, +6785, +3601, +-9488, +1072, +8790, +-5554, +-5257, +9043, +995, +-8971, +4313, +6845, +-8134, +-2900, +8937, +-2767, +-8108, +6822, +4444, +-8842, +920, +8984, +-5155, +-5626, +8568, +1080, +-9400, +3419, +6725, +-7850, +-3032, +9295, +-1830, +-7825, +6670, +4847, +-8693, +353, +8765, +-5125, +-6371, +7881, +1261, +-9282, +3328, +7423, +-7048, +-3064, +9323, +-1356, +-8014, +6113, +4858, +-8901, +-549, +8430, +-4828, +-6430, +8016, +2177, +-8793, +3160, +7694, +-6715, +-3540, +8955, +-1272, +-8556, +5276, +4879, +-8685, +-688, +8898, +-3912, +-6288, +7927, +2616, +-8755, +2578, +7576, +-6767, +-4342, +8388, +-1022, +-8514, +5257, +5654, +-7984, +-790, +9027, +-3487, +-6585, +7426, +2677, +-9087, +1689, +7379, +-6475, +-4447, +8642, +-104, +-8154, +5101, +6003, +-7758, +-1310, +8748, +-3431, +-7230, +6687, +2792, +-8923, +1582, +7963, +-5642, +-4404, +8627, +346, +-8251, +4540, +5966, +-7895, +-2156, +8324, +-3156, +-7254, +6751, +3633, +-8354, +1443, +8178, +-5273, +-4798, +8213, +422, +-8693, +3700, +5895, +-7657, +-2281, +8697, +-2260, +-7022, +6640, +4028, +-8244, +896, +7999, +-5274, +-5525, +7587, +616, +-8604, +3638, +6581, +-6915, +-2323, +8761, +-1818, +-7227, +6125, +4052, +-8487, +42, +7713, +-4998, +-5598, +7754, +1481, +-8161, +3492, +6869, +-6630, +-2781, +8434, +-1755, +-7781, +5354, +4092, +-8295, +-79, +8197, +-4145, +-5483, +7698, +1910, +-8168, +2948, +6780, +-6704, +-3568, +7935, +-1515, +-7760, +5366, +4851, +-7667, +-180, +8344, +-3758, +-5792, +7248, +1964, +-8523, +2109, +6621, +-6445, +-3668, +8208, +-646, +-7448, +5236, +5202, +-7483, +-680, +8113, +-3729, +-6432, +6571, +2093, +-8395, +2020, +7209, +-5676, +-3654, +8229, +-216, +-7569, +4718, +5174, +-7655, +-1494, +7745, +-3470, +-6469, +6667, +2901, +-7887, +1894, +7444, +-5348, +-4044, +7858, +-154, +-8033, +3934, +5139, +-7440, +-1608, +8139, +-2625, +-6282, +6581, +3296, +-7811, +1371, +7295, +-5380, +-4756, +7296, +35, +-7964, +3896, +5813, +-6762, +-1659, +8229, +-2219, +-6504, +6113, +3322, +-8078, +582, +7085, +-5111, +-4841, +7499, +899, +-7543, +3773, +6104, +-6507, +-2085, +7948, +-2200, +-7087, +5399, +3384, +-7947, +418, +7524, +-4336, +-4763, +7434, +1251, +-7626, +3257, +6026, +-6652, +-2882, +7507, +-1942, +-7077, +5419, +4123, +-7335, +360, +7700, +-3985, +-5045, +7064, +1320, +-8003, +2484, +5947, +-6391, +-2986, +7799, +-1100, +-6777, +5324, +4462, +-7199, +-98, +7529, +-3982, +-5702, +6458, +1488, +-7892, +2391, +6516, +-5660, +-2962, +7828, +-721, +-6915, +4871, +4456, +-7412, +-894, +7225, +-3720, +-5761, +6551, +2257, +-7416, +2283, +6739, +-5394, +-3340, +7523, +-677, +-7418, +4137, +4467, +-7216, +-1027, +7598, +-2927, +-5583, +6487, +2615, +-7387, +1810, +6632, +-5462, +-4054, +7025, +-457, +-7378, +4085, +5113, +-6581, +-1063, +7700, +-2570, +-5817, +6084, +2648, +-7699, +1031, +6457, +-5209, +-4157, +7207, +326, +-7019, +3989, +5398, +-6386, +-1487, +7470, +-2546, +-6398, +5426, +2749, +-7553, +916, +6935, +-4461, +-4073, +7183, +671, +-7119, +3501, +5346, +-6507, +-2160, +7196, +-2216, +-6370, +5445, +3398, +-7105, +749, +7017, +-4253, +-4462, +6823, +782, +-7373, +2964, +5474, +-6185, +-2310, +7338, +-1631, +-6300, +5241, +3646, +-7044, +301, +6942, +-4092, +-4841, +6546, +1123, +-7285, +2717, +5766, +-5794, +-2511, +7275, +-1324, +-6456, +4889, +3828, +-7008, +-124, +6960, +-3732, +-5006, +6386, +1530, +-7157, +2428, +5911, +-5568, +-2834, +7142, +-1036, +-6618, +4554, +4088, +-6805, +-443, +7008, +-3347, +-5141, +6185, +1821, +-7134, +2081, +6023, +-5350, +-3162, +7015, +-661, +-6671, +4250, +4339, +-6584, +-734, +7004, +-3048, +-5327, +5955, +2108, +-7111, +1710, +6158, +-5052, +-3429, +6878, +-313, +-6678, +3959, +4542, +-6412, +-1050, +6997, +-2738, +-5533, +5703, +2429, +-7016, +1359, +6253, +-4744, +-3651, +6737, +1, +-6727, +3660, +4752, +-6235, +-1395, +6979, +-2382, +-5675, +5440, +2715, +-6891, +1045, +6324, +-4478, +-3889, +6597, +322, +-6776, +3332, +4965, +-6009, +-1706, +6911, +-2040, +-5782, +5183, +2962, +-6797, +730, +6416, +-4201, +-4148, +6427, +667, +-6775, +2996, +5130, +-5765, +-1984, +6843, +-1737, +-5900, +4943, +3229, +-6695, +384, +6479, +-3877, +-4368, +6226, +979, +-6742, +2688, +5273, +-5556, +-2258, +6787, +-1414, +-6029, +4664, +3504, +-6544, +44, +6497, +-3570, +-4543, +6033, +1262, +-6726, +2387, +5436, +-5332, +-2561, +6709, +-1063, +-6113, +4367, +3732, +-6374, +-252, +6507, +-3281, +-4731, +5854, +1566, +-6699, +2052, +5589, +-5066, +-2829, +6577, +-737, +-6163, +4091, +3928, +-6231, +-553, +6542, +-2988, +-4922, +5638, +1877, +-6641, +1716, +5684, +-4794, +-3069, +6461, +-448, +-6221, +3821, +4159, +-6075, +-874, +6537, +-2649, +-5092, +5398, +2143, +-6542, +1412, +5776, +-4559, +-3298, +6346, +-127, +-6289, +3522, +4369, +-5870, +-1189, +6499, +-2347, +-5205, +5164, +2399, +-6477, +1127, +5868, +-4290, +-3564, +6219, +191, +-6293, +3199, +4551, +-5678, +-1442, +6438, +-2037, +-5357, +4972, +2641, +-6366, +747, +6011, +-4080, +-3456, +5404, +184, +-4329, +1728, +2764, +-2714, +-1001, +2690, +-372, +-2019, +1141, +1142, +-1323, +-427, +1249, +-164, +-938, +506, +565, +-615, +-236, +577, +28, +-506, +152, +378, +-245, +-249, +282, +137, +-271, +-51, +260, +-42, +-201, +105, +145, +-155, +-75, +184, +17, +-191, +52, +165, +-94, +-125, +122, +69, +-128, +-19, +119, +-34, +-85, +67, +50, +-98, +-10, +98, +-21, +-92, +55, +76, +-64, +-46, +62, +17, +-50, +5, +37, +-29, +-16, +43, +-1, +-50, +19, +54, +-28, +-46, +31, +33, +-30, +-21, +29, +3, +-13, +6, +3, +-18, +6, +24, +-17, +-31, +20, +24, +-18, +-23, +16, +14, +-10, +-13, +4, +0, +6, +5, +-7, +-10, +13, +14, +-14, +-19, +18, +17, +-10, +-18, +6, +10, +0, +-5, +-6, +5, +13, +3, +-17, +-5, +17, +17, +-11, +-16, +9, +16, +1, +-18, +0, +11, +8, +-6, +-12, +0, +14, +2, +-14, +-8, +12, +12, +-11, +-13, +3, +20, +2, +-11, +-8, +9, +14, +-1, +-16, +-1, +15, +3, +-10, +-9, +10, +18, +-7, +-16, +-3, +11, +2, +-11, +-12, +9, +13, +-4, +-15, +-6, +17, +10, +-12, +-11, +4, +14, +0, +-14, +-5, +11, +5, +-7, +-15, +7, +16, +1, +-15, +-6, +14, +11, +-7, +-12, +4, +14, +1, +-12, +-7, +11, +7, +-4, +-12, +0, +19, +4, +-11, +-8, +11, +15, +-4, +-16, +-1, +14, +7, +-14, +-10, +10, +13, +0, +-16, +-4, +15, +9, +-8, +-15, +3, +12, +-2, +-16, +-7, +14, +14, +-8, +-12, +7, +14, +0, +-14, +-1, +12, +9, +-6, +-13, +8, +15, +-1, +-14, +-6, +11, +9, +-12, +-16, +1, +13, +8, +-15, +-8, +12, +13, +-6, +-15, +0, +16, +6, +-7, +-11, +8, +13, +-3, +-14, +1, +12, +9, +-14, +-10, +7, +14, +-7, +-18, +-1, +15, +7, +-9, +-11, +4, +13, +0, +-14, +-4, +13, +9, +-14, +-14, +2, +11, +3, +-11, +-6, +13, +10, +-9, +-7, +2, +12, +2, +-16, +-4, +13, +9, +-9, +-14, +0, +14, +5, +-13, +-11, +10, +12, +-7, +-14, +-1, +14, +7, +-12, +-9, +7, +12, +-4, +-14, +-4, +11, +6, +-11, +-9, +7, +12, +-4, +-14, +-1, +17, +10, +-11, +-14, +7, +13, +0, +-13, +-5, +12, +7, +-9, +-12, +0, +14, +2, +-14, +-4, +10, +10, +-6, +-12, +1, +14, +2, +-17, +-8, +10, +9, +-7, +-13, +0, +13, +2, +-12, +-11, +11, +11, +-1, +-13, +0, +13, +8, +-10, +-13, +8, +11, +-2, +-15, +-4, +11, +7, +-7, +-10, +0, +9, +1, +-8, +-3, +2, +2, +-1, +-5, +-2, +0, +1, +-2, +0, +0, +5, +-1, +0, +-1, +1, +3, +-1, +0, +0, +1, +0, +0, +0, +-1, +1, +2, +0, +2, +3, +-1, +0, +-4, +0, +2, +-1, +0, +0, +-1, +1, +0, +3, +-4, +3, +0, +-1, +0, +-1, +0, +0, +1, +0, +0, +0, +0, +0, +-2, +1, +0, +-1, +-3, +2, +0, +2, +0, +1, +2, +0, +1, +-1, +0, +1, +0, +-3, +-1, +-1, +-4, +2, +-2, +0, +0, +0, +0, +-1, +-1, +0, +1, +0, +2, +0, +0, +0, +-3, +0, +2, +-2, +-1, +2, +0, +-2, +3, +-6, +1, +-1, +0, +-3, +0, +0, +0, +2, +0, +0, +0, +-2, +2, +4, +4, +1, +-3, +0, +-1, +-2, +2, +2, +2, +0, +3, +0, +2, +0, +2, +-3, +-2, +1, +-4, +15, +165, +-73, +-269, +82, +305, +17, +-358, +-102, +283, +127, +-241, +-222, +151, +222, +-96, +-236, +42, +241, +15, +-245, +-35, +255, +109, +-239, +-138, +227, +190, +-177, +-220, +134, +243, +-62, +-251, +13, +237, +49, +-230, +-95, +208, +138, +-181, +-178, +150, +203, +-107, +-240, +68, +243, +-10, +-255, +-39, +237, +87, +-216, +-135, +183, +175, +-138, +-212, +102, +223, +-49, +-247, +8, +241, +50, +-235, +-93, +212, +138, +-185, +-181, +147, +203, +-98, +-235, +54, +234, +0, +-239, +-46, +225, +99, +-208, +-142, +180, +178, +-138, +-209, +100, +225, +-47, +-242, +1, +231, +48, +-224, +-96, +201, +143, +-173, +-180, +141, +204, +-89, +-228, +53, +231, +6, +-238, +-50, +222, +95, +-202, +-140, +170, +177, +-130, +-208, +92, +216, +-45, +-233, +-2, +228, +56, +-220, +-100, +193, +137, +-164, +-178, +136, +198, +-82, +-226, +42, +225, +8, +-230, +-51, +213, +98, +-192, +-143, +162, +171, +-125, +-202, +87, +217, +-36, +-228, +-5, +219, +57, +-210, +-100, +191, +134, +-157, +-178, +128, +197, +-77, +-216, +37, +221, +14, +-218, +-57, +205, +102, +-183, +-141, +159, +166, +-114, +-198, +83, +213, +-28, +-220, +-9, +215, +61, +-204, +-98, +179, +139, +-150, +-171, +114, +192, +-70, +-213, +30, +212, +16, +-210, +-58, +199, +100, +-175, +-142, +149, +168, +-106, +-197, +73, +205, +-24, +-214, +-14, +206, +62, +-195, +-100, +174, +140, +-144, +-165, +108, +188, +-65, +-202, +25, +208, +19, +-204, +-62, +191, +101, +-163, +-141, +144, +160, +-98, +-193, +72, +195, +-13, +-213, +-16, +192, +72, +-193, +-99, +163, +141, +-143, +-160, +99, +193, +-65, +-199, +17, +210, +17, +-193, +-72, +194, +94, +-150, +-146, +151, +148, +-80, +-204, +81, +168, +12, +-229, +14, +147, +123, +-81, +4570, +9554, +10082, +7637, +2676, +-2947, +-8396, +-11460, +-11351, +-8277, +-3721, +431, +3458, +6162, +8632, +10260, +9688, +6644, +1273, +-5345, +-10775, +-12655, +-10722, +-6687, +-2603, +870, +3699, +6106, +7934, +8685, +7572, +3999, +-1708, +-7604, +-11229, +-11205, +-8374, +-4428, +-625, +2545, +4871, +6629, +8057, +8661, +6952, +2357, +-3748, +-8735, +-10800, +-9773, +-6605, +-2574, +1110, +3776, +5618, +7358, +8874, +8751, +5668, +185, +-5579, +-9522, +-10678, +-8920, +-5122, +-860, +2362, +4450, +6339, +8401, +9444, +7988, +3764, +-1909, +-7210, +-10471, +-10622, +-7742, +-3400, +437, +3047, +5167, +7442, +9217, +9173, +6607, +1846, +-3949, +-8958, +-11208, +-9888, +-6098, +-1955, +1300, +3842, +6251, +8338, +9350, +8446, +5176, +-246, +-6247, +-10432, +-11079, +-8551, +-4625, +-848, +2309, +4951, +7129, +8724, +9226, +7669, +3378, +-2759, +-8321, +-11011, +-10305, +-7274, +-3337, +462, +3531, +5792, +7630, +9072, +9107, +6380, +966, +-5185, +-9591, +-10999, +-9495, +-5978, +-1745, +1880, +4387, +6329, +8270, +9505, +8423, +4372, +-1478, +-6982, +-10410, +-10875, +-8443, +-4245, +-112, +2841, +4968, +7126, +9068, +9385, +7005, +2231, +-3531, +-8534, +-11105, +-10328, +-6796, +-2471, +1025, +3542, +5858, +8101, +9376, +8615, +5427, +247, +-5596, +-10026, +-11232, +-9035, +-5053, +-1157, +1931, +4531, +6881, +8653, +9188, +7731, +3810, +-2019, +-7721, +-10912, +-10542, +-7564, +-3653, +14, +3094, +5564, +7518, +8884, +8983, +6676, +1668, +-4496, +-9286, +-10973, +-9598, +-6268, +-2259, +1419, +4175, +6207, +7997, +9236, +8558, +4946, +-828, +-6542, +-10132, +-10769, +-8652, +-4776, +-607, +2615, +4836, +6809, +8724, +9381, +7403, +2760, +-3036, +-8053, +-10763, +-10400, +-7294, +-2971, +765, +3366, +5515, +7734, +9278, +8823, +5764, +701, +-4979, +-9475, +-11130, +-9414, +-5515, +-1442, +1694, +4163, +6527, +8514, +9233, +7860, +4148, +-1360, +-7023, +-10621, +-10743, +-7912, +-3951, +-301, +2676, +5226, +7373, +8814, +8914, +6854, +2277, +-3736, +-8835, +-10956, +-9779, +-6517, +-2638, +942, +3844, +6076, +7860, +9021, +8575, +5435, +-91, +-5990, +-9897, +-10722, +-8790, +-5185, +-1137, +2276, +4707, +6636, +8406, +9261, +7730, +3377, +-2481, +-7633, +-10472, +-10368, +-7659, +-3529, +398, +3218, +5303, +7371, +9065, +8990, +6202, +1184, +-4454, +-8967, +-10899, +-9671, +-6033, +-1830, +1498, +3907, +6146, +8266, +9264, +8082, +4483, +-821, +-6352, +-10191, +-10832, +-8332, +-4315, +-557, +2362, +4846, +7125, +8763, +8947, +7012, +2754, +-2993, +-8250, +-10854, +-10020, +-6813, +-2938, +545, +3444, +5850, +7759, +8900, +8538, +5792, +622, +-5319, +-9610, +-10735, +-8949, +-5484, +-1604, +1842, +4487, +6515, +8190, +9072, +7927, +3980, +-1815, +-7208, +-10257, +-10330, +-7901, +-4035, +-72, +2995, +5173, +7098, +8782, +9045, +6642, +1754, +-3962, +-8544, +-10646, +-9789, +-6518, +-2318, +1243, +3744, +5840, +7931, +9201, +8343, +4887, +-342, +-5782, +-9714, +-10785, +-8721, +-4783, +-847, +2151, +4547, +6887, +8778, +9207, +7378, +3252, +-2335, +-7691, +-10776, +-10462, +-7422, +-3434, +112, +3002, +5551, +7723, +9037, +8756, +6219, +1346, +-4580, +-9299, +-10946, +-9396, +-5975, +-2153, +1281, +4127, +6407, +8182, +9081, +8184, +4632, +-1021, +-6719, +-10190, +-10534, +-8270, +-4604, +-697, +2599, +5046, +7021, +8669, +9158, +7190, +2527, +-3351, +-8214, +-10557, +-9989, +-7059, +-2993, +788, +3563, +5694, +7732, +9209, +8752, +5546, +285, +-5271, +-9364, +-10767, +-9173, +-5463, +-1359, +1877, +4274, +6517, +8555, +9294, +7694, +3691, +-1744, +-7029, +-10367, +-10549, +-7805, +-3784, +-115, +2723, +5192, +7475, +8991, +8839, +6435, +1854, +-3860, +-8741, +-10854, +-9639, +-6263, +-2419, +942, +3764, +6193, +8099, +9033, +8240, +5042, +-295, +-6058, +-9934, +-10600, +-8476, +-4916, +-1144, +2173, +4811, +6887, +8482, +9038, +7437, +3151, +-2685, +-7824, +-10418, +-10032, +-7342, +-3502, +318, +3293, +5527, +7511, +8970, +8776, +5991, +959, +-4737, +-9083, +-10671, +-9284, +-5873, +-1905, +1493, +4103, +6321, +8242, +9147, +7960, +4254, +-1200, +-6604, +-10055, +-10471, +-8125, +-4329, +-532, +2538, +4979, +7116, +8743, +8961, +6834, +2316, +-3359, +-8221, +-10566, +-9829, +-6759, +-2834, +713, +3508, +5818, +7829, +9037, +8441, +5353, +203, +-5396, +-9447, +-10611, +-8854, +-5290, +-1404, +1850, +4422, +6615, +8419, +9064, +7558, +3568, +-1975, +-7197, +-10241, +-10226, +-7621, +-3785, +-76, +2885, +5277, +7368, +8848, +8773, +6301, +1552, +-4098, +-8664, +-10577, +-9464, +-6223, +-2313, +1133, +3832, +6092, +8033, +9051, +8130, +4712, +-582, +-6051, +-9737, +-10468, +-8401, +-4738, +-919, +2228, +4718, +6882, +8568, +8962, +7107, +2839, +-2745, +-7730, +-10360, +-9948, +-7105, +-3242, +363, +3223, +5564, +7598, +8916, +8538, +5731, +779, +-4807, +-9052, +-10537, +-9074, +-5676, +-1802, +1524, +4152, +6374, +8222, +9015, +7756, +4039, +-1362, +-6660, +-9966, +-10276, +-7926, +-4190, +-454, +2581, +5016, +7132, +8694, +8815, +6610, +2098, +-3493, +-8212, +-10427, +-9628, +-6581, +-2716, +782, +3552, +5853, +7818, +8952, +8265, +5119, +3, +-5481, +-9385, +-10441, +-8654, +-5135, +-1309, +1908, +4457, +6638, +8391, +8945, +7356, +3336, +-2138, +-7225, +-10133, +-10041, +-7432, +-3656, +-3, +2933, +5314, +7375, +8785, +8617, +6080, +1343, +-4213, +-8637, +-10434, +-9270, +-6051, +-2209, +1189, +3876, +6129, +8022, +8957, +7940, +4480, +-771, +-6112, +-9659, +-10295, +-8205, +-4593, +-838, +2269, +4758, +6904, +8531, +8829, +6896, +2619, +-2890, +-7738, +-10244, +-9766, +-6933, +-3122, +427, +3265, +5601, +7606, +8847, +8379, +5505, +579, +-4902, +-9013, +-10386, +-8885, +-5521, +-1709, +1578, +4186, +6402, +8203, +8911, +7566, +3808, +-1537, +-6711, +-9869, +-10105, +-7741, +-4058, +-375, +2629, +5058, +7150, +8647, +8670, +6400, +1878, +-3617, +-8205, +-10294, +-9447, +-6411, +-2613, +843, +3591, +5886, +7814, +8878, +8086, +4903, +-190, +-5551, +-9338, +-10268, +-8495, +-4775, +-745, +2131, +4204, +5766, +6837, +6769, +5090, +1927, +-1837, +-4904, +-6376, +-6100, +-4490, +-2286, +-74, +1779, +3189, +4099, +4326, +3711, +2257, +226, +-1848, +-3377, +-3941, +-3538, +-2444, +-1034, +348, +1503, +2346, +2775, +2693, +2029, +922, +-376, +-1533, +-2262, +-2421, +-2051, +-1312, +-411, +481, +1207, +1678, +1820, +1602, +1063, +299, +-501, +-1152, +-1515, +-1506, +-1197, +-685, +-88, +472, +909, +1157, +1173, +952, +539, +24, +-476, +-841, +-1010, +-954, +-707, +-346, +50, +410, +671, +797, +760, +571, +272, +-82, +-400, +-616, +-689, +-612, +-423, +-172, +99, +336, +496, +563, +508, +356, +127, +-114, +-326, +-461, +-486, +-410, +-262, +-75, +114, +276, +386, +415, +361, +236, +61, +-124, +-273, +-358, +-363, +-291, +-173, +-26, +119, +236, +308, +323, +265, +154, +11, +-131, +-237, +-291, +-281, +-218, +-111, +3, +119, +210, +266, +265, +210, +108, +-19, +-136, +-220, +-251, +-229, +-165, +-79, +28, +121, +198, +240, +230, +167, +66, +-45, +-151, +-210, +-225, +-193, +-131, +-46, +48, +132, +195, +220, +198, +129, +35, +-73, +-155, +-208, +-205, +-169, +-97, +-19, +67, +145, +198, +214, +171, +94, +-4, +-97, +-172, +-197, +-188, +-141, +-72, +10, +88, +160, +199, +195, +148, +61, +-36, +-119, +-176, +-194, +-168, +-115, +-42, +37, +119, +174, +199, +179, +118, +28, +-70, +-145, +-184, +-185, +-151, +-89, +-18, +62, +137, +179, +197, +160, +86, +-7, +-95, +-159, +-187, +-178, +-131, +-62, +18, +94, +157, +190, +183, +139, +52, +-45, +-123, +-175, +-184, +-158, +-104, +-36, +44, +113, +170, +187, +169, +104, +16, +-76, +-143, +-184, +-181, +-142, +-79, +-6, +71, +139, +181, +187, +149, +73, +-18, +-106, +-164, +-182, +-165, +-116, +-55, +24, +99, +158, +189, +178, +122, +40, +-48, +-126, +-176, +-177, +-153, +-94, +-26, +50, +119, +171, +187, +163, +93, +4, +-81, +-153, +-180, +-166, +-131, +-68, +2, +79, +146, +188, +180, +140, +62, +-31, +-108, +-166, +-180, +-164, +-112, +-42, +34, +108, +166, +186, +168, +111, +22, +-62, +-134, +-177, +-175, +-144, +-87, +-16, +60, +128, +174, +185, +152, +80, +-6, +-94, +-153, +-180, +-167, +-131, +-59, +16, +89, +152, +185, +177, +128, +48, +-43, +-116, +-166, +-179, +-153, +-98, +-33, +45, +118, +170, +188, +164, +101, +13, +-76, +-142, +-178, +-173, +-137, +-76, +-4, +69, +135, +181, +180, +145, +67, +-21, +-104, +-157, +-176, +-165, +-117, +-49, +26, +98, +157, +186, +170, +120, +39, +-55, +-127, +-171, +-174, +-147, +-95, +-22, +50, +123, +172, +184, +152, +88, +-2, +-84, +-148, +-177, +-166, +-124, +-66, +0, +63, +117, +146, +139, +107, +49, +-8, +-64, +-95, +-110, +-97, +-70, +-29, +14, +52, +76, +86, +77, +53, +15, +-18, +-47, +-64, +-68, +-54, +-32, +-5, +19, +43, +55, +50, +41, +26, +0, +-16, +-34, +-42, +-41, +-30, +-11, +5, +21, +27, +33, +28, +23, +9, +-3, +-16, +-23, +-23, +-22, +-15, +-3, +7, +16, +19, +21, +17, +11, +4, +-4, +-15, +-15, +-15, +-11, +-8, +-1, +5, +12, +13, +10, +5, +3, +0, +-6, +-4, +-8, +-4, +-6, +-2, +-3, +4, +6, +5, +10, +3, +2, +-2, +-6, +-8, +-4, +-4, +-4, +0, +0, +2, +5, +2, +3, +3, +1, +-2, +-4, +-6, +-2, +-3, +-1, +0, +2, +0, +4, +0, +1, +0, +0, +0, +-4, +-1, +0, +-2, +-1, +0, +0, +0, +-1, +2, +0, +0, +0, +0, +-5, +0, +2, +-3, +0, +0, +1, +-1, +0, +0, +1, +-1, +17, +100, +117, +64, +-24, +-110, +-172, +-196, +-155, +-83, +0, +83, +133, +157, +151, +142, +112, +49, +-43, +-141, +-209, +-209, +-154, +-57, +29, +94, +129, +142, +142, +126, +86, +12, +-80, +-156, +-197, +-172, +-106, +-12, +61, +110, +126, +132, +120, +107, +62, +-15, +-110, +-172, +-190, +-150, +-70, +15, +77, +113, +124, +130, +118, +91, +30, +-51, +-139, +-182, +-186, +-120, +-41, +47, +94, +121, +124, +130, +108, +74, +1, +-88, +-162, +-188, +-170, +-89, +-8, +72, +103, +131, +126, +129, +101, +58, +-34, +-115, +-189, +-187, +-145, +-55, +20, +91, +113, +135, +128, +127, +85, +32, +-70, +-143, +-204, +-176, +-125, +-19, +43, +107, +124, +142, +126, +123, +65, +0, +-110, +-163, +-203, +-148, +-92, +13, +67, +123, +120, +141, +117, +108, +33, +-33, +-136, +-181, +-200, +-125, +-57, +42, +85, +134, +124, +143, +109, +94, +-1, +-64, +-172, +-187, +-188, +-94, +-29, +75, +97, +140, +120, +145, +93, +71, +-35, +-98, +-190, +-176, +-168, +-57, +-1, +99, +101, +146, +113, +140, +76, +45, +-71, +-127, +-205, +-164, +-143, +-21, +24, +118, +105, +154, +111, +130, +52, +20, +-109, +-144, +-213, +-146, +-116, +17, +43, +137, +106, +157, +104, +126, +25, +-11, +-147, +-154, +-215, +-111, +-87, +53, +59, +149, +104, +161, +91, +115, +-12, +-39, +-181, +-160, +-212, +-78, +-55, +86, +69, +156, +95, +165, +72, +102, +-54, +-61, +-211, +-148, +-198, +-35, +-34, +123, +66, +177, +81, +173, +44, +91, +-103, +-74, +-245, +-122, +-190, +20, +-30, +168, +45, +210, +48, +202, +-14, +102, +-186, +-47, +-307, +-37, +-239, +143, +-106, +300, +-93, +392, +-187, +496, +-468, +731, +-1442, +5793, +2530, +-9734, +15644, +-2126, +-8150, +14718, +-7005, +-5070, +12906, +-9606, +-1656, +9542, +-11482, +1321, +7297, +-12917, +4725, +4848, +-13040, +8030, +1944, +-12052, +10251, +-1907, +-9416, +11161, +-5724, +-6279, +11076, +-8602, +-2390, +10366, +-10430, +1066, +8739, +-11441, +4330, +6051, +-11694, +7047, +2650, +-10927, +9492, +-805, +-8917, +11256, +-3988, +-6264, +11741, +-6961, +-3176, +10945, +-9385, +15, +9053, +-10970, +3521, +6761, +-11292, +6843, +3875, +-10770, +9365, +510, +-9380, +10836, +-3091, +-7232, +11309, +-6275, +-4125, +11127, +-8633, +-560, +9898, +-10374, +2843, +7644, +-11284, +5824, +4508, +-11268, +8320, +1201, +-9887, +10414, +-2026, +-7602, +11447, +-5215, +-4809, +11309, +-8070, +-1752, +9970, +-10225, +1557, +8024, +-11108, +5039, +5478, +-11024, +7876, +2297, +-10109, +9881, +-1250, +-8441, +10824, +-4653, +-5847, +11127, +-7299, +-2478, +10463, +-9353, +911, +8717, +-10712, +4080, +6005, +-11251, +6752, +2848, +-10542, +9174, +-262, +-8690, +10726, +-3444, +-6259, +11168, +-6461, +-3408, +10410, +-9011, +-322, +8854, +-10463, +3154, +6774, +-10836, +6238, +3943, +-10428, +8622, +619, +-9213, +10015, +-2856, +-7179, +10730, +-5735, +-4148, +10659, +-8033, +-890, +9477, +-9782, +2313, +7278, +-10789, +5117, +4380, +-10750, +7714, +1425, +-9418, +9736, +-1649, +-7405, +10712, +-4740, +-4853, +10547, +-7541, +-2034, +9427, +-9510, +1274, +7788, +-10332, +4521, +5392, +-10417, +7190, +2353, +-9674, +9012, +-1029, +-8184, +10077, +-4102, +-5612, +10534, +-6581, +-2551, +9931, +-8653, +579, +8276, +-10059, +3462, +5743, +-10623, +6143, +2970, +-9866, +8528, +70, +-8284, +9989, +-3009, +-6101, +10388, +-5941, +-3559, +9737, +-8333, +-510, +8513, +-9613, +2782, +6597, +-10134, +5641, +3910, +-9866, +7830, +725, +-8882, +9225, +-2446, +-6847, +10119, +-5058, +-4048, +10084, +-7359, +-1072, +8974, +-9112, +1828, +6892, +-10185, +4530, +4333, +-10030, +7144, +1675, +-8882, +9040, +-1302, +-7108, +9956, +-4279, +-4865, +9807, +-6970, +-2163, +8970, +-8688, +1052, +7542, +-9591, +4034, +5252, +-9781, +6499, +2370, +-9265, +8216, +-789, +-7810, +9442, +-3515, +-5369, +9948, +-5945, +-2600, +9377, +-7984, +244, +7809, +-9462, +2931, +5531, +-9909, +5638, +3108, +-9224, +7899, +329, +-7877, +9262, +-2612, +-5965, +9625, +-5472, +-3619, +9170, +-7593, +-624, +8203, +-8835, +2419, +6367, +-9459, +5064, +3834, +-9366, +7076, +819, +-8477, +8558, +-1979, +-6484, +9538, +-4469, +-3969, +9487, +-6721, +-1263, +8450, +-8514, +1380, +6533, +-9510, +4075, +4359, +-9317, +6608, +1843, +-8385, +8354, +-1000, +-6844, +9199, +-3896, +-4848, +9132, +-6344, +-2181, +8582, +-7908, +826, +7239, +-8902, +3564, +5089, +-9216, +5820, +2324, +-8836, +7519, +-485, +-7361, +8867, +-2984, +-5148, +9331, +-5370, +-2655, +8806, +-7396, +-88, +7329, +-8845, +2510, +5403, +-9171, +5189, +3197, +-8636, +7266, +534, +-7494, +8541, +-2306, +-5846, +8884, +-4978, +-3572, +8694, +-6855, +-702, +7844, +-8137, +2055, +6115, +-8837, +4491, +3697, +-8884, +6423, +992, +-7987, +7991, +-1481, +-6058, +8950, +-3968, +-3877, +8931, +-6153, +-1495, +7863, +-7952, +1004, +6199, +-8846, +3681, +4341, +-8702, +5989, +1916, +-7923, +7644, +-824, +-6644, +8449, +-3538, +-4800, +8534, +-5679, +-2130, +8160, +-7243, +593, +6930, +-8264, +3074, +4872, +-8675, +5177, +2282, +-8348, +6973, +-125, +-6916, +8285, +-2513, +-4922, +8716, +-4873, +-2699, +8251, +-6867, +-406, +6902, +-8148, +2230, +5287, +-8460, +4768, +3238, +-8111, +6635, +704, +-7125, +7809, +-2074, +-5695, +8272, +-4430, +-3470, +8250, +-6143, +-788, +7437, +-7517, +1729, +5856, +-8297, +3889, +3535, +-8383, +5802, +1113, +-7461, +7484, +-1139, +-5838, +8299, +-3490, +-3809, +8265, +-5703, +-1653, +7379, +-7375, +724, +6029, +-8032, +3374, +4272, +-8075, +5526, +2020, +-7508, +6977, +-590, +-6380, +7733, +-3167, +-4569, +8112, +-5051, +-2141, +7744, +-6570, +366, +6521, +-7699, +2657, +4625, +-8236, +4570, +2339, +-7755, +6447, +126, +-6475, +7732, +-2173, +-4820, +8069, +-4410, +-2785, +7607, +-6365, +-535, +6632, +-7469, +1936, +5150, +-7829, +4234, +3103, +-7663, +6022, +758, +-6869, +7145, +-1685, +-5352, +7764, +-3887, +-3305, +7775, +-5654, +-1029, +6957, +-6966, +1324, +5459, +-7754, +3505, +3552, +-7762, +5376, +1368, +-6964, +6834, +-973, +-5632, +7644, +-3192, +-3849, +7662, +-5143, +-1667, +7024, +-6644, +663, +5849, +-7463, +2889, +4088, +-7594, +4876, +1922, +-7129, +6403, +-348, +-6016, +7290, +-2568, +-4276, +7571, +-4598, +-2200, +7204, +-6151, +12, +6112, +-7146, +2270, +4465, +-7540, +4310, +2502, +-7220, +5907, +298, +-6203, +6997, +-1975, +-4690, +7472, +-4007, +-2785, +7203, +-5657, +-569, +6312, +-6840, +1672, +4912, +-7369, +3693, +3028, +-7195, +5421, +842, +-6436, +6667, +-1342, +-5095, +7252, +-3395, +-3237, +7192, +-5191, +-1139, +6541, +-6470, +1013, +5239, +-7127, +3114, +3464, +-7201, +4941, +1445, +-6605, +6247, +-709, +-5374, +7016, +-2850, +-3700, +7182, +-4662, +-1735, +6641, +-6028, +441, +5507, +-6906, +2559, +3942, +-7130, +4376, +1989, +-6666, +5828, +-164, +-5658, +6786, +-2242, +-4152, +7050, +-4096, +-2222, +6701, +-5638, +-120, +5796, +-6617, +1926, +4331, +-6969, +3845, +2452, +-6737, +5420, +430, +-5908, +6440, +-1635, +-4488, +6894, +-3596, +-2706, +6771, +-5179, +-722, +5979, +-6256, +1365, +4647, +-6827, +3326, +2959, +-6765, +4913, +990, +-6043, +6093, +-1104, +-4819, +6746, +-3033, +-3198, +6728, +-4670, +-1229, +6101, +-5930, +817, +4994, +-6633, +2735, +3399, +-6678, +4435, +1471, +-6183, +5757, +-522, +-5138, +6486, +-2453, +-3577, +6643, +-4217, +-1725, +6251, +-5550, +223, +5248, +-6347, +2198, +3753, +-6616, +3972, +1994, +-6291, +5322, +42, +-5334, +6205, +-1945, +-3948, +6575, +-3704, +-2245, +6288, +-5095, +-290, +5433, +-6088, +1677, +4142, +-6501, +3425, +2467, +-6284, +4897, +528, +-5534, +5943, +-1387, +-4324, +6404, +-3165, +-2660, +6271, +-4697, +-794, +5640, +-5785, +1104, +4459, +-6283, +2913, +2870, +-6300, +4524, +1009, +-5622, +5122, +-668, +-2966, +3301, +-1193, +-1074, +1792, +-850, +-454, +1027, +-686, +-82, +729, +-742, +152, +513, +-674, +291, +213, +-376, +230, +-49, +-75, +156, +-130, +21, +55, +-50, +21, +31, +-43, +-21, +77, +-27, +-65, +65, +1, +-16, +-16, +1, +48, +-34, +-32, +40, +-4, +-4, +-12, +-5, +7, +7, +0, +-26, +-4, +35, +-4, +-26, +-4, +34, +1, +-34, +-3, +26, +3, +-24, +-10, +21, +4, +-6, +-16, +2, +18, +0, +-23, +-5, +16, +12, +-20, +-14, +19, +18, +-22, +-20, +11, +21, +-11, +-15, +0, +20, +-1, +-13, +-5, +21, +10, +-12, +-16, +18, +19, +-8, +-21, +9, +19, +2, +-22, +2, +19, +7, +-19, +-11, +19, +18, +-17, +-15, +6, +17, +-5, +-20, +1, +21, +1, +-20, +-11, +19, +8, +-16, +-18, +14, +14, +-13, +-17, +6, +21, +-4, +-19, +-1, +19, +6, +-19, +-10, +15, +17, +-16, +-18, +11, +23, +-6, +-18, +0, +22, +1, +-19, +-8, +18, +6, +-16, +-13, +10, +19, +-11, +-20, +6, +20, +1, +-21, +-2, +20, +6, +-17, +-11, +17, +16, +-14, +-18, +7, +20, +-5, +-21, +-1, +19, +2, +-16, +-9, +17, +10, +-13, +-15, +15, +17, +-8, +-20, +1, +24, +0, +-17, +-1, +20, +4, +-19, +-8, +17, +15, +-11, +-15, +9, +18, +-7, +-17, +1, +20, +1, +-17, +-9, +15, +10, +-13, +-17, +13, +16, +-7, +-22, +6, +20, +0, +-19, +-5, +17, +8, +-16, +-10, +13, +13, +-12, +-16, +9, +16, +-5, +-18, +0, +17, +2, +-22, +-10, +20, +10, +-13, +-16, +13, +15, +-11, +-18, +3, +21, +0, +-19, +-4, +22, +7, +-17, +-13, +14, +15, +-10, +-16, +7, +20, +-4, +-19, +0, +20, +2, +-18, +-10, +12, +10, +-17, +-13, +7, +17, +-7, +-20, +2, +16, +-3, +-25, +1, +21, +12, +-18, +-12, +13, +14, +-14, +-20, +6, +20, +0, +-18, +1, +18, +2, +-19, +-6, +16, +7, +-12, +-15, +9, +17, +-4, +-19, +0, +19, +0, +-22, +-6, +17, +7, +-15, +-7, +14, +16, +-12, +-17, +6, +18, +-7, +-16, +0, +17, +5, +-19, +-7, +11, +9, +-12, +-12, +10, +18, +-8, +-17, +3, +23, +2, +-19, +-4, +19, +7, +-16, +-14, +14, +17, +-6, +-20, +8, +17, +-6, +-16, +-4, +17, +2, +-13, +-6, +17, +11, +-12, +-14, +5, +15, +-4, +-17, +2, +19, +1, +-19, +-4, +15, +7, +-16, +-6, +10, +15, +-7, +-13, +6, +13, +0, +-17, +1, +14, +7, +-19, +-9, +15, +9, +-11, +-12, +6, +14, +-2, +-5, +-3, +9, +1, +-2, +-4, +7, +6, +-1, +0, +0, +2, +-4, +3, +2, +2, +0, +-1, +-1, +4, +1, +-1, +0, +3, +1, +1, +-1, +0, +0, +2, +0, +-2, +-1, +-2, +0, +0, +0, +-1, +1, +-2, +0, +2, +0, +-1, +-4, +1, +0, +1, +2, +0, +2, +2, +0, +1, +0, +-2, +-1, +-3, +1, +0, +-3, +-3, +-4, +-2, +-1, +-1, +1, +0, +0, +0, +3, +0, +1, +3, +3, +-3, +-4, +-7, +3, +1, +4, +4, +0, +0, +1, +-2, +3, +1, +0, +3, +0, +0, +0, +0, +0, +1, +1, +-1, +-1, +-1, +0, +0, +1, +4, +5, +0, +1, +-1, +0, +-1, +0, +2, +1, +-3, +0, +0, +2, +-1, +0, +-2, +4, +0, +0, +1, +0, +-1, +0, +0, +1, +0, +-2, +0, +5, +-6, +0, +-2, +6, +-15, +77, +74, +-232, +76, +230, +-196, +-159, +242, +-13, +-291, +148, +197, +-287, +-55, +312, +-104, +-250, +236, +134, +-302, +48, +303, +-188, +-183, +295, +38, +-301, +125, +237, +-250, +-102, +313, +-57, +-276, +204, +160, +-287, +-8, +283, +-150, +-205, +258, +65, +-292, +84, +240, +-218, +-117, +281, +-32, +-263, +175, +163, +-263, +-26, +272, +-127, +-203, +241, +74, +-279, +76, +234, +-203, +-125, +273, +-25, +-260, +168, +164, +-257, +-29, +275, +-118, +-206, +235, +83, +-282, +71, +245, +-200, +-134, +273, +-18, +-266, +164, +181, +-259, +-41, +276, +-108, +-220, +227, +95, +-284, +56, +254, +-196, +-143, +276, +-3, +-273, +147, +191, +-251, +-58, +279, +-97, +-229, +223, +107, +-281, +42, +257, +-183, +-155, +269, +15, +-272, +134, +198, +-240, +-68, +280, +-83, +-234, +210, +123, +-276, +26, +257, +-172, +-166, +262, +25, +-271, +122, +207, +-233, +-75, +278, +-71, +-235, +200, +130, +-266, +18, +262, +-158, +-178, +252, +42, +-270, +110, +215, +-227, +-91, +279, +-57, +-243, +189, +140, +-265, +5, +262, +-144, +-184, +242, +51, +-272, +100, +218, +-214, +-101, +271, +-43, +-250, +180, +150, +-264, +-10, +266, +-136, +-191, +240, +61, +-267, +82, +226, +-207, +-115, +267, +-31, +-247, +167, +160, +-252, +-21, +270, +-120, +-199, +229, +76, +-271, +75, +232, +-194, +-124, +261, +-21, +-255, +153, +166, +-245, +-31, +263, +-106, +-209, +219, +84, +-271, +59, +238, +-187, +-133, +256, +-5, +-254, +143, +176, +-240, +-46, +264, +-96, +-208, +209, +96, +-266, +46, +236, +-172, +-142, +254, +8, +-258, +129, +185, +-232, +-59, +264, +-85, +-217, +203, +103, +-259, +35, +246, +-164, +-154, +249, +18, +-257, +122, +192, +-224, +-70, +259, +-71, +-223, +194, +117, +-259, +18, +246, +-153, +-163, +243, +32, +-258, +106, +199, +-215, +-78, +264, +-62, +-223, +183, +128, +-255, +8, +247, +-146, +-171, +234, +43, +-260, +96, +207, +-210, +-90, +259, +-52, +-234, +175, +135, +-251, +-2, +250, +-129, +-178, +225, +55, +-252, +86, +208, +-200, +-101, +255, +-36, +-233, +159, +145, +-240, +-17, +251, +-121, +-186, +222, +63, +-253, +72, +218, +-187, +-114, +251, +-22, +-236, +152, +157, +-236, +-27, +253, +-106, +-188, +213, +80, +-254, +57, +224, +-181, +-122, +248, +-14, +-240, +141, +165, +-233, +-38, +255, +-95, +-197, +202, +87, +-248, +47, +223, +-169, +-131, +244, +2, +-240, +129, +168, +-225, +-47, +248, +-87, +-208, +199, +91, +-253, +38, +230, +-165, +-139, +240, +11, +-245, +122, +178, +-218, +-60, +247, +-70, +-208, +189, +109, +-245, +27, +231, +-153, +-147, +232, +21, +-248, +108, +181, +-210, +-69, +251, +-60, +-212, +178, +117, +-243, +14, +235, +-144, +-159, +226, +35, +-244, +96, +191, +-203, +-82, +243, +-52, +-217, +170, +125, +-238, +2, +234, +-133, +-165, +216, +46, +-243, +87, +194, +-196, +-92, +243, +-40, +-221, +163, +135, +-234, +-12, +238, +-123, +-173, +215, +54, +-244, +78, +201, +-189, +-105, +242, +-26, +-227, +147, +143, +-226, +-22, +241, +-112, +-179, +204, +66, +-244, +62, +208, +-177, +-112, +238, +-17, +-231, +142, +156, +-220, +-32, +239, +-95, +-187, +197, +79, +-239, +49, +215, +-164, +-120, +233, +-5, +-229, +132, +158, +-213, +-41, +241, +-87, +-191, +192, +89, +-241, +41, +217, +-154, +-126, +227, +9, +-230, +120, +167, +-208, +-53, +238, +-74, +-196, +186, +97, +-237, +29, +221, +-146, +-137, +226, +20, +-234, +107, +175, +-203, +-61, +236, +-61, +-205, +176, +106, +-236, +18, +224, +-140, +-144, +217, +28, +-235, +98, +178, +-196, +-74, +236, +-55, +-208, +166, +117, +-226, +7, +219, +-125, +-158, +210, +38, +-231, +86, +185, +-189, +-82, +234, +-42, +-214, +155, +126, +-227, +-5, +226, +-118, +-160, +208, +48, +-232, +75, +187, +-183, +-92, +229, +-30, +-214, +148, +133, +-218, +-11, +229, +-110, +-168, +203, +60, +-233, +67, +196, +-173, +-103, +225, +-24, +-218, +138, +141, +-213, +-23, +228, +-100, +-175, +195, +70, +-231, +58, +200, +-165, +-112, +225, +-11, +-222, +128, +151, +-209, +-36, +228, +-94, +-183, +185, +77, +-228, +48, +204, +-153, +-119, +216, +2, +-220, +121, +158, +-202, +-46, +228, +-80, +-186, +179, +90, +-227, +32, +204, +-149, +-127, +218, +8, +-222, +107, +161, +-199, +-54, +226, +-66, +-187, +169, +99, +-226, +22, +212, +-139, +-136, +219, +63, +-131, +236, +338, +-38, +34, +244, +-129, +-349, +-37, +-108, +-410, +-119, +162, +-103, +-36, +379, +227, +-48, +198, +187, +-271, +-244, +15, +-258, +-373, +35, +75, +-177, +109, +376, +45, +-18, +261, +16, +-332, +-87, +-2, +-341, +-205, +167, +-22, +-112, +292, +305, +-32, +117, +266, +-148, +-268, +38, +-109, +-355, +-11, +167, +-111, +31, +392, +171, +-41, +244, +154, +-274, +-149, +60, +-249, +-281, +130, +75, +-139, +203, +375, +26, +43, +288, +-32, +-311, +-24, +-31, +-352, +-132, +176, +-57, +-70, +339, +260, +-48, +161, +230, +-207, +-244, +44, +-173, +-351, +32, +125, +-145, +82, +387, +103, +-24, +259, +77, +-303, +-112, +22, +-309, +-244, +143, +15, +-132, +252, +329, +-13, +78, +271, +-105, +-295, +2, +-81, +-365, +-73, +132, +-71, +19, +283, +194, +51, +139, +85, +-131, +-163, +-112, +-175, +-181, +-60, +18, +30, +115, +196, +176, +119, +82, +-1, +-105, +-159, +-162, +-157, +-129, +-50, +26, +83, +139, +184, +170, +112, +36, +-42, +-122, +-169, +-167, +-137, +-95, +-31, +51, +115, +162, +177, +157, +90, +0, +-74, +-136, +-169, +-162, +-125, +-67, +-8, +74, +131, +167, +170, +136, +61, +-29, +-104, +-148, +-168, +-147, +-104, +-47, +27, +95, +148, +172, +156, +109, +29, +-55, +-121, +-158, +-165, +-137, +-81, +-15, +52, +120, +163, +171, +145, +80, +-2, +-86, +-138, +-163, +-150, +-115, +-58, +8, +76, +134, +168, +168, +121, +46, +-37, +-109, +-152, +-167, +-142, +-91, +-34, +36, +101, +152, +168, +149, +93, +15, +-67, +-130, +-161, +-157, +-127, +-73, +-5, +56, +123, +159, +169, +131, +64, +-10, +-94, +-140, +-160, +-146, +-104, +-48, +19, +84, +136, +166, +159, +109, +38, +-44, +-113, +-153, +-158, +-128, +-85, +-23, +47, +105, +153, +169, +143, +80, +2, +-74, +-131, +-156, +-148, +-116, +-66, +3, +70, +125, +161, +162, +120, +52, +-27, +-100, +-143, +-159, +-132, +-98, +-36, +31, +89, +141, +165, +147, +100, +24, +-54, +-118, +-150, +-153, +-125, +-74, +-14, +55, +114, +154, +162, +132, +76, +-4, +-84, +-133, +-155, +-143, +-102, +-50, +10, +77, +128, +159, +151, +112, +46, +-35, +-102, +-141, +-152, +-128, +-83, +-27, +33, +98, +142, +158, +137, +82, +12, +-61, +-122, +-146, +-141, +-114, +-65, +-7, +60, +114, +150, +154, +120, +58, +-17, +-87, +-129, +-153, +-136, +-94, +-42, +20, +81, +130, +157, +141, +99, +33, +-44, +-110, +-146, +-147, +-122, +-73, +-22, +45, +106, +143, +153, +128, +75, +-1, +-73, +-124, +-145, +-138, +-105, +-57, +3, +70, +119, +151, +148, +113, +46, +-25, +-93, +-137, +-148, +-126, +-87, +-33, +28, +90, +130, +154, +136, +87, +17, +-50, +-108, +-141, +-139, +-113, +-61, +-13, +48, +108, +140, +147, +126, +62, +-7, +-78, +-125, +-142, +-136, +-96, +-45, +13, +77, +121, +145, +140, +103, +37, +-39, +-98, +-140, +-142, +-121, +-79, +-24, +35, +92, +134, +150, +129, +76, +9, +-64, +-111, +-140, +-135, +-105, +-59, +0, +58, +108, +142, +145, +109, +50, +-19, +-82, +-124, +-139, +-129, +-87, +-39, +23, +78, +128, +148, +132, +94, +24, +-44, +-98, +-133, +-134, +-111, +-72, +-14, +41, +96, +132, +147, +121, +62, +-3, +-70, +-113, +-136, +-127, +-95, +-53, +4, +67, +114, +136, +140, +104, +37, +-28, +-88, +-129, +-137, +-118, +-82, +-26, +27, +84, +125, +140, +126, +75, +14, +-51, +-102, +-128, +-132, +-107, +-61, +-7, +50, +101, +132, +136, +115, +57, +-14, +-71, +-119, +-136, +-124, +-87, +-42, +13, +71, +117, +137, +136, +92, +32, +-33, +-93, +-123, +-133, +-112, +-74, +-23, +36, +88, +127, +135, +119, +73, +9, +-55, +-107, +-127, +-124, +-94, +-57, +2, +52, +102, +129, +133, +103, +45, +-19, +-79, +-117, +-127, +-114, +-81, +-34, +23, +75, +114, +134, +124, +85, +23, +-42, +-92, +-124, +-125, +-103, +-62, +-14, +39, +89, +125, +134, +114, +60, +-1, +-65, +-109, +-126, +-118, +-89, +-47, +7, +62, +107, +133, +125, +94, +37, +-31, +-80, +-117, +-124, +-109, +-72, +-27, +28, +80, +117, +133, +113, +74, +11, +-48, +-98, +-124, +-117, +-101, +-55, +-7, +50, +96, +126, +126, +101, +51, +-12, +-69, +-108, +-126, +-116, +-82, +-39, +16, +67, +108, +128, +119, +83, +24, +-36, +-86, +-120, +-123, +-105, +-69, +-15, +36, +82, +119, +126, +109, +63, +1, +-57, +-100, +-122, +-117, +-88, +-48, +1, +51, +98, +123, +122, +95, +42, +-21, +-72, +-112, +-117, +-108, +-73, +-29, +22, +68, +111, +127, +112, +71, +19, +-40, +-91, +-118, +-119, +-96, +-58, +-9, +38, +88, +120, +122, +101, +53, +-2, +-62, +-102, +-119, +-113, +-81, +-43, +10, +55, +96, +125, +120, +86, +33, +-27, +-77, +-108, +-119, +-100, +-64, +-24, +25, +75, +111, +122, +105, +69, +10, +-48, +-90, +-117, +-110, +-91, +-48, +0, +49, +88, +120, +119, +94, +42, +-10, +-65, +-100, +-114, +-101, +-74, +-32, +14, +63, +105, +120, +113, +73, +23, +-33, +-84, +-112, +-113, +-94, +-58, +-16, +32, +80, +109, +117, +101, +58, +1, +-56, +-93, +-108, +-107, +-77, +-43, +0, +41, +75, +91, +88, +67, +37, +-5, +-42, +-61, +-68, +-64, +-44, +-19, +6, +32, +54, +56, +49, +33, +9, +-8, +-30, +-38, +-41, +-36, +-21, +-3, +10, +24, +35, +31, +26, +12, +2, +-13, +-23, +-24, +-27, +-20, +-8, +0, +10, +20, +21, +16, +17, +8, +-1, +-6, +-12, +-14, +-16, +-8, +-3, +2, +5, +14, +11, +11, +6, \ No newline at end of file diff --git a/config/_default_cfg_src_/res/ring/SOUND_RING_44100.txt b/config/_default_cfg_src_/res/ring/SOUND_RING_44100.txt new file mode 100644 index 0000000..c77f086 --- /dev/null +++ b/config/_default_cfg_src_/res/ring/SOUND_RING_44100.txt @@ -0,0 +1,4224 @@ +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +2368 , +2368 , +4736 , +4736 , +6464 , +6464 , +7744 , +7744 , +8128 , +8128 , +7872 , +7872 , +6912 , +6912 , +5184 , +5184 , +3136 , +3136 , +576 , +576 , +-1792 , +-1792 , +-4224 , +-4224 , +-6208 , +-6208 , +-7488 , +-7488 , +-8128 , +-8128 , +-8064 , +-8064 , +-7104 , +-7104 , +-5632 , +-5632 , +-3520 , +-3520 , +-1216 , +-1216 , +1408 , +1408 , +3712 , +3712 , +5824 , +5824 , +7296 , +7296 , +8064 , +8064 , +8128 , +8128 , +7424 , +7424 , +5952 , +5952 , +4032 , +4032 , +1600 , +1600 , +-832 , +-832 , +-3328 , +-3328 , +-5208 , +-5208 , +-6820 , +-6820 , +-7750 , +-7750 , +-7874 , +-7874 , +-7316 , +-7316 , +-6138 , +-6138 , +-4216 , +-4216 , +-2108 , +-2108 , +372 , +372 , +2666 , +2666 , +4898 , +4898 , +6510 , +6510 , +7564 , +7564 , +7874 , +7874 , +7564 , +7564 , +6386 , +6386 , +4712 , +4712 , +2480 , +2480 , +186 , +186 , +-2294 , +-2294 , +-4402 , +-4402 , +-6262 , +-6262 , +-7378 , +-7378 , +-7874 , +-7874 , +-7688 , +-7688 , +-6696 , +-6696 , +-5022 , +-5022 , +-3038 , +-3038 , +-558 , +-558 , +1736 , +1736 , +4092 , +4092 , +5890 , +5890 , +7137 , +7137 , +7747 , +7747 , +7686 , +7686 , +6893 , +6893 , +5368 , +5368 , +3355 , +3355 , +1159 , +1159 , +-1342 , +-1342 , +-3538 , +-3538 , +-5551 , +-5551 , +-6893 , +-6893 , +-7686 , +-7686 , +-7747 , +-7747 , +-7076 , +-7076 , +-5795 , +-5795 , +-3843 , +-3843 , +-1708 , +-1708 , +793 , +793 , +3172 , +3172 , +5124 , +5124 , +6710 , +6710 , +7564 , +7564 , +7747 , +7747 , +7259 , +7259 , +6039 , +6039 , +4331 , +4331 , +2074 , +2074 , +-183 , +-183 , +-2623 , +-2623 , +-4819 , +-4819 , +-6405 , +-6405 , +-7442 , +-7442 , +-7620 , +-7620 , +-7320 , +-7320 , +-6300 , +-6300 , +-4560 , +-4560 , +-2580 , +-2580 , +-180 , +-180 , +2040 , +2040 , +4260 , +4260 , +6060 , +6060 , +7140 , +7140 , +7620 , +7620 , +7440 , +7440 , +6480 , +6480 , +5040 , +5040 , +2940 , +2940 , +780 , +780 , +-1680 , +-1680 , +-3780 , +-3780 , +-5700 , +-5700 , +-6960 , +-6960 , +-7620 , +-7620 , +-7560 , +-7560 , +-6780 , +-6780 , +-5280 , +-5280 , +-3480 , +-3480 , +-1140 , +-1140 , +1140 , +1140 , +3480 , +3480 , +5280 , +5280 , +6780 , +6780 , +7560 , +7560 , +7620 , +7620 , +6728 , +6728 , +5510 , +5510 , +3654 , +3654 , +1624 , +1624 , +-754 , +-754 , +-2842 , +-2842 , +-4872 , +-4872 , +-6264 , +-6264 , +-7192 , +-7192 , +-7366 , +-7366 , +-6902 , +-6902 , +-5742 , +-5742 , +-4118 , +-4118 , +-1972 , +-1972 , +174 , +174 , +2494 , +2494 , +4408 , +4408 , +6090 , +6090 , +7076 , +7076 , +7366 , +7366 , +7076 , +7076 , +6090 , +6090 , +4582 , +4582 , +2494 , +2494 , +174 , +174 , +-1972 , +-1972 , +-4118 , +-4118 , +-5742 , +-5742 , +-6902 , +-6902 , +-7366 , +-7366 , +-7192 , +-7192 , +-6380 , +-6380 , +-4788 , +-4788 , +-2964 , +-2964 , +-741 , +-741 , +1596 , +1596 , +3591 , +3591 , +5415 , +5415 , +6612 , +6612 , +7239 , +7239 , +7182 , +7182 , +6441 , +6441 , +5187 , +5187 , +3306 , +3306 , +1254 , +1254 , +-1083 , +-1083 , +-3306 , +-3306 , +-5016 , +-5016 , +-6441 , +-6441 , +-7182 , +-7182 , +-7239 , +-7239 , +-6669 , +-6669 , +-5415 , +-5415 , +-3762 , +-3762 , +-1596 , +-1596 , +513 , +513 , +2793 , +2793 , +4617 , +4617 , +6156 , +6156 , +7068 , +7068 , +7239 , +7239 , +6783 , +6783 , +5757 , +5757 , +4047 , +4047 , +2072 , +2072 , +-168 , +-168 , +-2240 , +-2240 , +-4256 , +-4256 , +-5768 , +-5768 , +-6832 , +-6832 , +-7112 , +-7112 , +-6832 , +-6832 , +-5880 , +-5880 , +-4424 , +-4424 , +-2408 , +-2408 , +-336 , +-336 , +1904 , +1904 , +3808 , +3808 , +5544 , +5544 , +6608 , +6608 , +7112 , +7112 , +6944 , +6944 , +6160 , +6160 , +4704 , +4704 , +2912 , +2912 , +728 , +728 , +-1400 , +-1400 , +-3528 , +-3528 , +-5208 , +-5208 , +-6496 , +-6496 , +-7112 , +-7112 , +-7056 , +-7056 , +-6384 , +-6384 , +-5096 , +-5096 , +-3248 , +-3248 , +-1232 , +-1232 , +1045 , +1045 , +3025 , +3025 , +4840 , +4840 , +6105 , +6105 , +6930 , +6930 , +6985 , +6985 , +6435 , +6435 , +5335 , +5335 , +3630 , +3630 , +1540 , +1540 , +-495 , +-495 , +-2695 , +-2695 , +-4455 , +-4455 , +-5940 , +-5940 , +-6765 , +-6765 , +-6985 , +-6985 , +-6655 , +-6655 , +-5555 , +-5555 , +-4070 , +-4070 , +-2035 , +-2035 , +165 , +165 , +2200 , +2200 , +4180 , +4180 , +5665 , +5665 , +6710 , +6710 , +6985 , +6985 , +6710 , +6710 , +5830 , +5830 , +4345 , +4345 , +2530 , +2530 , +330 , +330 , +-1870 , +-1870 , +-3604 , +-3604 , +-5247 , +-5247 , +-6254 , +-6254 , +-6731 , +-6731 , +-6625 , +-6625 , +-5830 , +-5830 , +-4558 , +-4558 , +-2756 , +-2756 , +-848 , +-848 , +1325 , +1325 , +3180 , +3180 , +4929 , +4929 , +6148 , +6148 , +6731 , +6731 , +6678 , +6678 , +6042 , +6042 , +4823 , +4823 , +3180 , +3180 , +1166 , +1166 , +-848 , +-848 , +-2915 , +-2915 , +-4558 , +-4558 , +-5883 , +-5883 , +-6678 , +-6678 , +-6731 , +-6731 , +-6201 , +-6201 , +-5141 , +-5141 , +-3498 , +-3498 , +-1643 , +-1643 , +477 , +477 , +2438 , +2438 , +4293 , +4293 , +5512 , +5512 , +6396 , +6396 , +6604 , +6604 , +6292 , +6292 , +5252 , +5252 , +3848 , +3848 , +1924 , +1924 , +0 , +0 , +-2080 , +-2080 , +-3848 , +-3848 , +-5356 , +-5356 , +-6292 , +-6292 , +-6604 , +-6604 , +-6396 , +-6396 , +-5512 , +-5512 , +-4108 , +-4108 , +-2392 , +-2392 , +-312 , +-312 , +1612 , +1612 , +3536 , +3536 , +5044 , +5044 , +6136 , +6136 , +6604 , +6604 , +6500 , +6500 , +5772 , +5772 , +4472 , +4472 , +2704 , +2704 , +832 , +832 , +-1300 , +-1300 , +-3120 , +-3120 , +-4836 , +-4836 , +-5928 , +-5928 , +-6477 , +-6477 , +-6477 , +-6477 , +-5814 , +-5814 , +-4743 , +-4743 , +-3060 , +-3060 , +-1122 , +-1122 , +816 , +816 , +2805 , +2805 , +4386 , +4386 , +5661 , +5661 , +6375 , +6375 , +6477 , +6477 , +6018 , +6018 , +4947 , +4947 , +3468 , +3468 , +1581 , +1581 , +-306 , +-306 , +-2346 , +-2346 , +-4131 , +-4131 , +-5406 , +-5406 , +-6273 , +-6273 , +-6477 , +-6477 , +-6171 , +-6171 , +-5253 , +-5253 , +-3774 , +-3774 , +-2040 , +-2040 , +0 , +0 , +1887 , +1887 , +3774 , +3774 , +5253 , +5253 , +6171 , +6171 , +6477 , +6477 , +6027 , +6027 , +5194 , +5194 , +3969 , +3969 , +2254 , +2254 , +441 , +441 , +-1519 , +-1519 , +-3234 , +-3234 , +-4753 , +-4753 , +-5782 , +-5782 , +-6223 , +-6223 , +-6125 , +-6125 , +-5439 , +-5439 , +-4214 , +-4214 , +-2695 , +-2695 , +-784 , +-784 , +1078 , +1078 , +2940 , +2940 , +4459 , +4459 , +5586 , +5586 , +6174 , +6174 , +6223 , +6223 , +5586 , +5586 , +4557 , +4557 , +2940 , +2940 , +1225 , +1225 , +-784 , +-784 , +-2548 , +-2548 , +-4214 , +-4214 , +-5390 , +-5390 , +-6125 , +-6125 , +-6223 , +-6223 , +-5782 , +-5782 , +-4656 , +-4656 , +-3264 , +-3264 , +-1488 , +-1488 , +288 , +288 , +2208 , +2208 , +3792 , +3792 , +5088 , +5088 , +5856 , +5856 , +6096 , +6096 , +5856 , +5856 , +4944 , +4944 , +3552 , +3552 , +1920 , +1920 , +0 , +0 , +-1776 , +-1776 , +-3552 , +-3552 , +-4848 , +-4848 , +-5808 , +-5808 , +-6096 , +-6096 , +-5904 , +-5904 , +-5184 , +-5184 , +-3888 , +-3888 , +-2352 , +-2352 , +-432 , +-432 , +1488 , +1488 , +3168 , +3168 , +4656 , +4656 , +5616 , +5616 , +6096 , +6096 , +6048 , +6048 , +5328 , +5328 , +4224 , +4224 , +2585 , +2585 , +893 , +893 , +-1034 , +-1034 , +-2820 , +-2820 , +-4277 , +-4277 , +-5358 , +-5358 , +-5922 , +-5922 , +-5969 , +-5969 , +-5452 , +-5452 , +-4371 , +-4371 , +-2961 , +-2961 , +-1175 , +-1175 , +611 , +611 , +2444 , +2444 , +4042 , +4042 , +5170 , +5170 , +5875 , +5875 , +5969 , +5969 , +5546 , +5546 , +4653 , +4653 , +3196 , +3196 , +1598 , +1598 , +-282 , +-282 , +-2021 , +-2021 , +-3713 , +-3713 , +-4935 , +-4935 , +-5734 , +-5734 , +-5969 , +-5969 , +-5734 , +-5734 , +-4841 , +-4841 , +-3572 , +-3572 , +-1880 , +-1880 , +-138 , +-138 , +1702 , +1702 , +3266 , +3266 , +4646 , +4646 , +5474 , +5474 , +5842 , +5842 , +5658 , +5658 , +4968 , +4968 , +3726 , +3726 , +2254 , +2254 , +414 , +414 , +-1288 , +-1288 , +-3036 , +-3036 , +-4370 , +-4370 , +-5382 , +-5382 , +-5842 , +-5842 , +-5796 , +-5796 , +-5106 , +-5106 , +-4048 , +-4048 , +-2530 , +-2530 , +-874 , +-874 , +1012 , +1012 , +2668 , +2668 , +4186 , +4186 , +5198 , +5198 , +5796 , +5796 , +5842 , +5842 , +5336 , +5336 , +4370 , +4370 , +2898 , +2898 , +1150 , +1150 , +-598 , +-598 , +-2288 , +-2288 , +-3696 , +-3696 , +-4840 , +-4840 , +-5456 , +-5456 , +-5588 , +-5588 , +-5236 , +-5236 , +-4356 , +-4356 , +-3124 , +-3124 , +-1496 , +-1496 , +264 , +264 , +1892 , +1892 , +3476 , +3476 , +4620 , +4620 , +5368 , +5368 , +5588 , +5588 , +5368 , +5368 , +4620 , +4620 , +3344 , +3344 , +1892 , +1892 , +132 , +132 , +-1628 , +-1628 , +-3124 , +-3124 , +-4444 , +-4444 , +-5236 , +-5236 , +-5588 , +-5588 , +-5456 , +-5456 , +-4752 , +-4752 , +-3696 , +-3696 , +-2156 , +-2156 , +-572 , +-572 , +1232 , +1232 , +2904 , +2904 , +4085 , +4085 , +5031 , +5031 , +5461 , +5461 , +5418 , +5418 , +4859 , +4859 , +3784 , +3784 , +2494 , +2494 , +817 , +817 , +-817 , +-817 , +-2494 , +-2494 , +-3784 , +-3784 , +-4859 , +-4859 , +-5418 , +-5418 , +-5461 , +-5461 , +-4988 , +-4988 , +-4085 , +-4085 , +-2709 , +-2709 , +-1204 , +-1204 , +559 , +559 , +2107 , +2107 , +3612 , +3612 , +4644 , +4644 , +5332 , +5332 , +5461 , +5461 , +5117 , +5117 , +4257 , +4257 , +3053 , +3053 , +1462 , +1462 , +-129 , +-129 , +-1849 , +-1849 , +-3268 , +-3268 , +-4515 , +-4515 , +-5124 , +-5124 , +-5334 , +-5334 , +-5124 , +-5124 , +-4410 , +-4410 , +-3192 , +-3192 , +-1806 , +-1806 , +-126 , +-126 , +1428 , +1428 , +2982 , +2982 , +4158 , +4158 , +4998 , +4998 , +5334 , +5334 , +5208 , +5208 , +4620 , +4620 , +3528 , +3528 , +2058 , +2058 , +546 , +546 , +-1176 , +-1176 , +-2646 , +-2646 , +-3990 , +-3990 , +-4872 , +-4872 , +-5334 , +-5334 , +-5292 , +-5292 , +-4746 , +-4746 , +-3822 , +-3822 , +-2436 , +-2436 , +-798 , +-798 , +798 , +798 , +2436 , +2436 , +3696 , +3696 , +4746 , +4746 , +5292 , +5292 , +5080 , +5080 , +4680 , +4680 , +3800 , +3800 , +2640 , +2640 , +1120 , +1120 , +-520 , +-520 , +-1960 , +-1960 , +-3360 , +-3360 , +-4320 , +-4320 , +-4960 , +-4960 , +-5080 , +-5080 , +-4760 , +-4760 , +-4040 , +-4040 , +-2840 , +-2840 , +-1480 , +-1480 , +120 , +120 , +1600 , +1600 , +3040 , +3040 , +4200 , +4200 , +4880 , +4880 , +5080 , +5080 , +4880 , +4880 , +4200 , +4200 , +3160 , +3160 , +1720 , +1720 , +240 , +240 , +-1360 , +-1360 , +-2720 , +-2720 , +-3960 , +-3960 , +-4760 , +-4760 , +-5080 , +-5080 , +-4960 , +-4960 , +-4290 , +-4290 , +-3276 , +-3276 , +-2028 , +-2028 , +-507 , +-507 , +975 , +975 , +2457 , +2457 , +3627 , +3627 , +4524 , +4524 , +4953 , +4953 , +4914 , +4914 , +4407 , +4407 , +3549 , +3549 , +2262 , +2262 , +858 , +858 , +-741 , +-741 , +-2145 , +-2145 , +-3432 , +-3432 , +-4329 , +-4329 , +-4914 , +-4914 , +-4953 , +-4953 , +-4563 , +-4563 , +-3705 , +-3705 , +-2574 , +-2574 , +-1092 , +-1092 , +351 , +351 , +1911 , +1911 , +3159 , +3159 , +4212 , +4212 , +4797 , +4797 , +4953 , +4953 , +4719 , +4719 , +3939 , +3939 , +2698 , +2698 , +1406 , +1406 , +-114 , +-114 , +-1520 , +-1520 , +-2888 , +-2888 , +-3914 , +-3914 , +-4636 , +-4636 , +-4826 , +-4826 , +-4636 , +-4636 , +-4028 , +-4028 , +-3002 , +-3002 , +-1634 , +-1634 , +-228 , +-228 , +1292 , +1292 , +2584 , +2584 , +3762 , +3762 , +4484 , +4484 , +4826 , +4826 , +4750 , +4750 , +4180 , +4180 , +3268 , +3268 , +1976 , +1976 , +608 , +608 , +-950 , +-950 , +-2394 , +-2394 , +-3534 , +-3534 , +-4408 , +-4408 , +-4826 , +-4826 , +-4788 , +-4788 , +-4332 , +-4332 , +-3458 , +-3458 , +-2280 , +-2280 , +-814 , +-814 , +592 , +592 , +2035 , +2035 , +3256 , +3256 , +4107 , +4107 , +4662 , +4662 , +4699 , +4699 , +4329 , +4329 , +3589 , +3589 , +2442 , +2442 , +1147 , +1147 , +-333 , +-333 , +-1702 , +-1702 , +-2997 , +-2997 , +-3996 , +-3996 , +-4551 , +-4551 , +-4699 , +-4699 , +-4477 , +-4477 , +-3737 , +-3737 , +-2738 , +-2738 , +-1369 , +-1369 , +0 , +0 , +1480 , +1480 , +2738 , +2738 , +3811 , +3811 , +4477 , +4477 , +4699 , +4699 , +4514 , +4514 , +3922 , +3922 , +2923 , +2923 , +1702 , +1702 , +222 , +222 , +-1085 , +-1085 , +-2380 , +-2380 , +-3395 , +-3395 , +-4130 , +-4130 , +-4445 , +-4445 , +-4375 , +-4375 , +-3850 , +-3850 , +-3010 , +-3010 , +-1820 , +-1820 , +-560 , +-560 , +875 , +875 , +2100 , +2100 , +3255 , +3255 , +3990 , +3990 , +4445 , +4445 , +4445 , +4445 , +3990 , +3990 , +3185 , +3185 , +2100 , +2100 , +770 , +770 , +-560 , +-560 , +-1925 , +-1925 , +-3010 , +-3010 , +-3885 , +-3885 , +-4375 , +-4375 , +-4445 , +-4445 , +-4130 , +-4130 , +-3395 , +-3395 , +-2380 , +-2380 , +-1085 , +-1085 , +315 , +315 , +1610 , +1610 , +2754 , +2754 , +3604 , +3604 , +4182 , +4182 , +4318 , +4318 , +4114 , +4114 , +3502 , +3502 , +2516 , +2516 , +1360 , +1360 , +0 , +0 , +-1360 , +-1360 , +-2516 , +-2516 , +-3502 , +-3502 , +-4114 , +-4114 , +-4318 , +-4318 , +-4182 , +-4182 , +-3604 , +-3604 , +-2754 , +-2754 , +-1564 , +-1564 , +-306 , +-306 , +1054 , +1054 , +2312 , +2312 , +3298 , +3298 , +4012 , +4012 , +4318 , +4318 , +4250 , +4250 , +3774 , +3774 , +2924 , +2924 , +1870 , +1870 , +544 , +544 , +-748 , +-748 , +-2040 , +-2040 , +-3162 , +-3162 , +-3762 , +-3762 , +-4191 , +-4191 , +-4191 , +-4191 , +-3762 , +-3762 , +-3069 , +-3069 , +-1980 , +-1980 , +-825 , +-825 , +528 , +528 , +1716 , +1716 , +2838 , +2838 , +3630 , +3630 , +4125 , +4125 , +4191 , +4191 , +3894 , +3894 , +3201 , +3201 , +2244 , +2244 , +1023 , +1023 , +-198 , +-198 , +-1518 , +-1518 , +-2607 , +-2607 , +-3498 , +-3498 , +-4026 , +-4026 , +-4191 , +-4191 , +-3993 , +-3993 , +-3399 , +-3399 , +-2442 , +-2442 , +-1320 , +-1320 , +0 , +0 , +1221 , +1221 , +2442 , +2442 , +3333 , +3333 , +3993 , +3993 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +2368 , +2368 , +4736 , +4736 , +6464 , +6464 , +7744 , +7744 , +8128 , +8128 , +7872 , +7872 , +6912 , +6912 , +5184 , +5184 , +3136 , +3136 , +576 , +576 , +-1792 , +-1792 , +-4224 , +-4224 , +-6208 , +-6208 , +-7488 , +-7488 , +-8128 , +-8128 , +-8064 , +-8064 , +-7104 , +-7104 , +-5632 , +-5632 , +-3520 , +-3520 , +-1216 , +-1216 , +1408 , +1408 , +3712 , +3712 , +5824 , +5824 , +7296 , +7296 , +8064 , +8064 , +8128 , +8128 , +7424 , +7424 , +5952 , +5952 , +4032 , +4032 , +1600 , +1600 , +-832 , +-832 , +-3328 , +-3328 , +-5208 , +-5208 , +-6820 , +-6820 , +-7750 , +-7750 , +-7874 , +-7874 , +-7316 , +-7316 , +-6138 , +-6138 , +-4216 , +-4216 , +-2108 , +-2108 , +372 , +372 , +2666 , +2666 , +4898 , +4898 , +6510 , +6510 , +7564 , +7564 , +7874 , +7874 , +7564 , +7564 , +6386 , +6386 , +4712 , +4712 , +2480 , +2480 , +186 , +186 , +-2294 , +-2294 , +-4402 , +-4402 , +-6262 , +-6262 , +-7378 , +-7378 , +-7874 , +-7874 , +-7688 , +-7688 , +-6696 , +-6696 , +-5022 , +-5022 , +-3038 , +-3038 , +-558 , +-558 , +1736 , +1736 , +4092 , +4092 , +5890 , +5890 , +7137 , +7137 , +7747 , +7747 , +7686 , +7686 , +6893 , +6893 , +5368 , +5368 , +3355 , +3355 , +1159 , +1159 , +-1342 , +-1342 , +-3538 , +-3538 , +-5551 , +-5551 , +-6893 , +-6893 , +-7686 , +-7686 , +-7747 , +-7747 , +-7076 , +-7076 , +-5795 , +-5795 , +-3843 , +-3843 , +-1708 , +-1708 , +793 , +793 , +3172 , +3172 , +5124 , +5124 , +6710 , +6710 , +7564 , +7564 , +7747 , +7747 , +7259 , +7259 , +6039 , +6039 , +4331 , +4331 , +2074 , +2074 , +-183 , +-183 , +-2623 , +-2623 , +-4819 , +-4819 , +-6405 , +-6405 , +-7442 , +-7442 , +-7620 , +-7620 , +-7320 , +-7320 , +-6300 , +-6300 , +-4560 , +-4560 , +-2580 , +-2580 , +-180 , +-180 , +2040 , +2040 , +4260 , +4260 , +6060 , +6060 , +7140 , +7140 , +7620 , +7620 , +7440 , +7440 , +6480 , +6480 , +5040 , +5040 , +2940 , +2940 , +780 , +780 , +-1680 , +-1680 , +-3780 , +-3780 , +-5700 , +-5700 , +-6960 , +-6960 , +-7620 , +-7620 , +-7560 , +-7560 , +-6780 , +-6780 , +-5280 , +-5280 , +-3480 , +-3480 , +-1140 , +-1140 , +1140 , +1140 , +3480 , +3480 , +5280 , +5280 , +6780 , +6780 , +7560 , +7560 , +7620 , +7620 , +6728 , +6728 , +5510 , +5510 , +3654 , +3654 , +1624 , +1624 , +-754 , +-754 , +-2842 , +-2842 , +-4872 , +-4872 , +-6264 , +-6264 , +-7192 , +-7192 , +-7366 , +-7366 , +-6902 , +-6902 , +-5742 , +-5742 , +-4118 , +-4118 , +-1972 , +-1972 , +174 , +174 , +2494 , +2494 , +4408 , +4408 , +6090 , +6090 , +7076 , +7076 , +7366 , +7366 , +7076 , +7076 , +6090 , +6090 , +4582 , +4582 , +2494 , +2494 , +174 , +174 , +-1972 , +-1972 , +-4118 , +-4118 , +-5742 , +-5742 , +-6902 , +-6902 , +-7366 , +-7366 , +-7192 , +-7192 , +-6380 , +-6380 , +-4788 , +-4788 , +-2964 , +-2964 , +-741 , +-741 , +1596 , +1596 , +3591 , +3591 , +5415 , +5415 , +6612 , +6612 , +7239 , +7239 , +7182 , +7182 , +6441 , +6441 , +5187 , +5187 , +3306 , +3306 , +1254 , +1254 , +-1083 , +-1083 , +-3306 , +-3306 , +-5016 , +-5016 , +-6441 , +-6441 , +-7182 , +-7182 , +-7239 , +-7239 , +-6669 , +-6669 , +-5415 , +-5415 , +-3762 , +-3762 , +-1596 , +-1596 , +513 , +513 , +2793 , +2793 , +4617 , +4617 , +6156 , +6156 , +7068 , +7068 , +7239 , +7239 , +6783 , +6783 , +5757 , +5757 , +4047 , +4047 , +2072 , +2072 , +-168 , +-168 , +-2240 , +-2240 , +-4256 , +-4256 , +-5768 , +-5768 , +-6832 , +-6832 , +-7112 , +-7112 , +-6832 , +-6832 , +-5880 , +-5880 , +-4424 , +-4424 , +-2408 , +-2408 , +-336 , +-336 , +1904 , +1904 , +3808 , +3808 , +5544 , +5544 , +6608 , +6608 , +7112 , +7112 , +6944 , +6944 , +6160 , +6160 , +4704 , +4704 , +2912 , +2912 , +728 , +728 , +-1400 , +-1400 , +-3528 , +-3528 , +-5208 , +-5208 , +-6496 , +-6496 , +-7112 , +-7112 , +-7056 , +-7056 , +-6384 , +-6384 , +-5096 , +-5096 , +-3248 , +-3248 , +-1232 , +-1232 , +1045 , +1045 , +3025 , +3025 , +4840 , +4840 , +6105 , +6105 , +6930 , +6930 , +6985 , +6985 , +6435 , +6435 , +5335 , +5335 , +3630 , +3630 , +1540 , +1540 , +-495 , +-495 , +-2695 , +-2695 , +-4455 , +-4455 , +-5940 , +-5940 , +-6765 , +-6765 , +-6985 , +-6985 , +-6655 , +-6655 , +-5555 , +-5555 , +-4070 , +-4070 , +-2035 , +-2035 , +165 , +165 , +2200 , +2200 , +4180 , +4180 , +5665 , +5665 , +6710 , +6710 , +6985 , +6985 , +6710 , +6710 , +5830 , +5830 , +4345 , +4345 , +2530 , +2530 , +330 , +330 , +-1870 , +-1870 , +-3604 , +-3604 , +-5247 , +-5247 , +-6254 , +-6254 , +-6731 , +-6731 , +-6625 , +-6625 , +-5830 , +-5830 , +-4558 , +-4558 , +-2756 , +-2756 , +-848 , +-848 , +1325 , +1325 , +3180 , +3180 , +4929 , +4929 , +6148 , +6148 , +6731 , +6731 , +6678 , +6678 , +6042 , +6042 , +4823 , +4823 , +3180 , +3180 , +1166 , +1166 , +-848 , +-848 , +-2915 , +-2915 , +-4558 , +-4558 , +-5883 , +-5883 , +-6678 , +-6678 , +-6731 , +-6731 , +-6201 , +-6201 , +-5141 , +-5141 , +-3498 , +-3498 , +-1643 , +-1643 , +477 , +477 , +2438 , +2438 , +4293 , +4293 , +5512 , +5512 , +6396 , +6396 , +6604 , +6604 , +6292 , +6292 , +5252 , +5252 , +3848 , +3848 , +1924 , +1924 , +0 , +0 , +-2080 , +-2080 , +-3848 , +-3848 , +-5356 , +-5356 , +-6292 , +-6292 , +-6604 , +-6604 , +-6396 , +-6396 , +-5512 , +-5512 , +-4108 , +-4108 , +-2392 , +-2392 , +-312 , +-312 , +1612 , +1612 , +3536 , +3536 , +5044 , +5044 , +6136 , +6136 , +6604 , +6604 , +6500 , +6500 , +5772 , +5772 , +4472 , +4472 , +2704 , +2704 , +832 , +832 , +-1300 , +-1300 , +-3120 , +-3120 , +-4836 , +-4836 , +-5928 , +-5928 , +-6477 , +-6477 , +-6477 , +-6477 , +-5814 , +-5814 , +-4743 , +-4743 , +-3060 , +-3060 , +-1122 , +-1122 , +816 , +816 , +2805 , +2805 , +4386 , +4386 , +5661 , +5661 , +6375 , +6375 , +6477 , +6477 , +6018 , +6018 , +4947 , +4947 , +3468 , +3468 , +1581 , +1581 , +-306 , +-306 , +-2346 , +-2346 , +-4131 , +-4131 , +-5406 , +-5406 , +-6273 , +-6273 , +-6477 , +-6477 , +-6171 , +-6171 , +-5253 , +-5253 , +-3774 , +-3774 , +-2040 , +-2040 , +0 , +0 , +1887 , +1887 , +3774 , +3774 , +5253 , +5253 , +6171 , +6171 , +6477 , +6477 , +6027 , +6027 , +5194 , +5194 , +3969 , +3969 , +2254 , +2254 , +441 , +441 , +-1519 , +-1519 , +-3234 , +-3234 , +-4753 , +-4753 , +-5782 , +-5782 , +-6223 , +-6223 , +-6125 , +-6125 , +-5439 , +-5439 , +-4214 , +-4214 , +-2695 , +-2695 , +-784 , +-784 , +1078 , +1078 , +2940 , +2940 , +4459 , +4459 , +5586 , +5586 , +6174 , +6174 , +6223 , +6223 , +5586 , +5586 , +4557 , +4557 , +2940 , +2940 , +1225 , +1225 , +-784 , +-784 , +-2548 , +-2548 , +-4214 , +-4214 , +-5390 , +-5390 , +-6125 , +-6125 , +-6223 , +-6223 , +-5782 , +-5782 , +-4656 , +-4656 , +-3264 , +-3264 , +-1488 , +-1488 , +288 , +288 , +2208 , +2208 , +3792 , +3792 , +5088 , +5088 , +5856 , +5856 , +6096 , +6096 , +5856 , +5856 , +4944 , +4944 , +3552 , +3552 , +1920 , +1920 , +0 , +0 , +-1776 , +-1776 , +-3552 , +-3552 , +-4848 , +-4848 , +-5808 , +-5808 , +-6096 , +-6096 , +-5904 , +-5904 , +-5184 , +-5184 , +-3888 , +-3888 , +-2352 , +-2352 , +-432 , +-432 , +1488 , +1488 , +3168 , +3168 , +4656 , +4656 , +5616 , +5616 , +6096 , +6096 , +6048 , +6048 , +5328 , +5328 , +4224 , +4224 , +2585 , +2585 , +893 , +893 , +-1034 , +-1034 , +-2820 , +-2820 , +-4277 , +-4277 , +-5358 , +-5358 , +-5922 , +-5922 , +-5969 , +-5969 , +-5452 , +-5452 , +-4371 , +-4371 , +-2961 , +-2961 , +-1175 , +-1175 , +611 , +611 , +2444 , +2444 , +4042 , +4042 , +5170 , +5170 , +5875 , +5875 , +5969 , +5969 , +5546 , +5546 , +4653 , +4653 , +3196 , +3196 , +1598 , +1598 , +-282 , +-282 , +-2021 , +-2021 , +-3713 , +-3713 , +-4935 , +-4935 , +-5734 , +-5734 , +-5969 , +-5969 , +-5734 , +-5734 , +-4841 , +-4841 , +-3572 , +-3572 , +-1880 , +-1880 , +-138 , +-138 , +1702 , +1702 , +3266 , +3266 , +4646 , +4646 , +5474 , +5474 , +5842 , +5842 , +5658 , +5658 , +4968 , +4968 , +3726 , +3726 , +2254 , +2254 , +414 , +414 , +-1288 , +-1288 , +-3036 , +-3036 , +-4370 , +-4370 , +-5382 , +-5382 , +-5842 , +-5842 , +-5796 , +-5796 , +-5106 , +-5106 , +-4048 , +-4048 , +-2530 , +-2530 , +-874 , +-874 , +1012 , +1012 , +2668 , +2668 , +4186 , +4186 , +5198 , +5198 , +5796 , +5796 , +5842 , +5842 , +5336 , +5336 , +4370 , +4370 , +2898 , +2898 , +1150 , +1150 , +-598 , +-598 , +-2288 , +-2288 , +-3696 , +-3696 , +-4840 , +-4840 , +-5456 , +-5456 , +-5588 , +-5588 , +-5236 , +-5236 , +-4356 , +-4356 , +-3124 , +-3124 , +-1496 , +-1496 , +264 , +264 , +1892 , +1892 , +3476 , +3476 , +4620 , +4620 , +5368 , +5368 , +5588 , +5588 , +5368 , +5368 , +4620 , +4620 , +3344 , +3344 , +1892 , +1892 , +132 , +132 , +-1628 , +-1628 , +-3124 , +-3124 , +-4444 , +-4444 , +-5236 , +-5236 , +-5588 , +-5588 , +-5456 , +-5456 , +-4752 , +-4752 , +-3696 , +-3696 , +-2156 , +-2156 , +-572 , +-572 , +1232 , +1232 , +2904 , +2904 , +4085 , +4085 , +5031 , +5031 , +5461 , +5461 , +5418 , +5418 , +4859 , +4859 , +3784 , +3784 , +2494 , +2494 , +817 , +817 , +-817 , +-817 , +-2494 , +-2494 , +-3784 , +-3784 , +-4859 , +-4859 , +-5418 , +-5418 , +-5461 , +-5461 , +-4988 , +-4988 , +-4085 , +-4085 , +-2709 , +-2709 , +-1204 , +-1204 , +559 , +559 , +2107 , +2107 , +3612 , +3612 , +4644 , +4644 , +5332 , +5332 , +5461 , +5461 , +5117 , +5117 , +4257 , +4257 , +3053 , +3053 , +1462 , +1462 , +-129 , +-129 , +-1849 , +-1849 , +-3268 , +-3268 , +-4515 , +-4515 , +-5124 , +-5124 , +-5334 , +-5334 , +-5124 , +-5124 , +-4410 , +-4410 , +-3192 , +-3192 , +-1806 , +-1806 , +-126 , +-126 , +1428 , +1428 , +2982 , +2982 , +4158 , +4158 , +4998 , +4998 , +5334 , +5334 , +5208 , +5208 , +4620 , +4620 , +3528 , +3528 , +2058 , +2058 , +546 , +546 , +-1176 , +-1176 , +-2646 , +-2646 , +-3990 , +-3990 , +-4872 , +-4872 , +-5334 , +-5334 , +-5292 , +-5292 , +-4746 , +-4746 , +-3822 , +-3822 , +-2436 , +-2436 , +-798 , +-798 , +798 , +798 , +2436 , +2436 , +3696 , +3696 , +4746 , +4746 , +5292 , +5292 , +5080 , +5080 , +4680 , +4680 , +3800 , +3800 , +2640 , +2640 , +1120 , +1120 , +-520 , +-520 , +-1960 , +-1960 , +-3360 , +-3360 , +-4320 , +-4320 , +-4960 , +-4960 , +-5080 , +-5080 , +-4760 , +-4760 , +-4040 , +-4040 , +-2840 , +-2840 , +-1480 , +-1480 , +120 , +120 , +1600 , +1600 , +3040 , +3040 , +4200 , +4200 , +4880 , +4880 , +5080 , +5080 , +4880 , +4880 , +4200 , +4200 , +3160 , +3160 , +1720 , +1720 , +240 , +240 , +-1360 , +-1360 , +-2720 , +-2720 , +-3960 , +-3960 , +-4760 , +-4760 , +-5080 , +-5080 , +-4960 , +-4960 , +-4290 , +-4290 , +-3276 , +-3276 , +-2028 , +-2028 , +-507 , +-507 , +975 , +975 , +2457 , +2457 , +3627 , +3627 , +4524 , +4524 , +4953 , +4953 , +4914 , +4914 , +4407 , +4407 , +3549 , +3549 , +2262 , +2262 , +858 , +858 , +-741 , +-741 , +-2145 , +-2145 , +-3432 , +-3432 , +-4329 , +-4329 , +-4914 , +-4914 , +-4953 , +-4953 , +-4563 , +-4563 , +-3705 , +-3705 , +-2574 , +-2574 , +-1092 , +-1092 , +351 , +351 , +1911 , +1911 , +3159 , +3159 , +4212 , +4212 , +4797 , +4797 , +4953 , +4953 , +4719 , +4719 , +3939 , +3939 , +2698 , +2698 , +1406 , +1406 , +-114 , +-114 , +-1520 , +-1520 , +-2888 , +-2888 , +-3914 , +-3914 , +-4636 , +-4636 , +-4826 , +-4826 , +-4636 , +-4636 , +-4028 , +-4028 , +-3002 , +-3002 , +-1634 , +-1634 , +-228 , +-228 , +1292 , +1292 , +2584 , +2584 , +3762 , +3762 , +4484 , +4484 , +4826 , +4826 , +4750 , +4750 , +4180 , +4180 , +3268 , +3268 , +1976 , +1976 , +608 , +608 , +-950 , +-950 , +-2394 , +-2394 , +-3534 , +-3534 , +-4408 , +-4408 , +-4826 , +-4826 , +-4788 , +-4788 , +-4332 , +-4332 , +-3458 , +-3458 , +-2280 , +-2280 , +-814 , +-814 , +592 , +592 , +2035 , +2035 , +3256 , +3256 , +4107 , +4107 , +4662 , +4662 , +4699 , +4699 , +4329 , +4329 , +3589 , +3589 , +2442 , +2442 , +1147 , +1147 , +-333 , +-333 , +-1702 , +-1702 , +-2997 , +-2997 , +-3996 , +-3996 , +-4551 , +-4551 , +-4699 , +-4699 , +-4477 , +-4477 , +-3737 , +-3737 , +-2738 , +-2738 , +-1369 , +-1369 , +0 , +0 , +1480 , +1480 , +2738 , +2738 , +3811 , +3811 , +4477 , +4477 , +4699 , +4699 , +4514 , +4514 , +3922 , +3922 , +2923 , +2923 , +1702 , +1702 , +222 , +222 , +-1085 , +-1085 , +-2380 , +-2380 , +-3395 , +-3395 , +-4130 , +-4130 , +-4445 , +-4445 , +-4375 , +-4375 , +-3850 , +-3850 , +-3010 , +-3010 , +-1820 , +-1820 , +-560 , +-560 , +875 , +875 , +2100 , +2100 , +3255 , +3255 , +3990 , +3990 , +4445 , +4445 , +4445 , +4445 , +3990 , +3990 , +3185 , +3185 , +2100 , +2100 , +770 , +770 , +-560 , +-560 , +-1925 , +-1925 , +-3010 , +-3010 , +-3885 , +-3885 , +-4375 , +-4375 , +-4445 , +-4445 , +-4130 , +-4130 , +-3395 , +-3395 , +-2380 , +-2380 , +-1085 , +-1085 , +315 , +315 , +1610 , +1610 , +2754 , +2754 , +3604 , +3604 , +4182 , +4182 , +4318 , +4318 , +4114 , +4114 , +3502 , +3502 , +2516 , +2516 , +1360 , +1360 , +0 , +0 , +-1360 , +-1360 , +-2516 , +-2516 , +-3502 , +-3502 , +-4114 , +-4114 , +-4318 , +-4318 , +-4182 , +-4182 , +-3604 , +-3604 , +-2754 , +-2754 , +-1564 , +-1564 , +-306 , +-306 , +1054 , +1054 , +2312 , +2312 , +3298 , +3298 , +4012 , +4012 , +4318 , +4318 , +4250 , +4250 , +3774 , +3774 , +2924 , +2924 , +1870 , +1870 , +544 , +544 , +-748 , +-748 , +-2040 , +-2040 , +-3162 , +-3162 , \ No newline at end of file diff --git a/config/_default_cfg_src_/res/ring/SOUND_RING_48000.txt b/config/_default_cfg_src_/res/ring/SOUND_RING_48000.txt new file mode 100644 index 0000000..c77f086 --- /dev/null +++ b/config/_default_cfg_src_/res/ring/SOUND_RING_48000.txt @@ -0,0 +1,4224 @@ +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +2368 , +2368 , +4736 , +4736 , +6464 , +6464 , +7744 , +7744 , +8128 , +8128 , +7872 , +7872 , +6912 , +6912 , +5184 , +5184 , +3136 , +3136 , +576 , +576 , +-1792 , +-1792 , +-4224 , +-4224 , +-6208 , +-6208 , +-7488 , +-7488 , +-8128 , +-8128 , +-8064 , +-8064 , +-7104 , +-7104 , +-5632 , +-5632 , +-3520 , +-3520 , +-1216 , +-1216 , +1408 , +1408 , +3712 , +3712 , +5824 , +5824 , +7296 , +7296 , +8064 , +8064 , +8128 , +8128 , +7424 , +7424 , +5952 , +5952 , +4032 , +4032 , +1600 , +1600 , +-832 , +-832 , +-3328 , +-3328 , +-5208 , +-5208 , +-6820 , +-6820 , +-7750 , +-7750 , +-7874 , +-7874 , +-7316 , +-7316 , +-6138 , +-6138 , +-4216 , +-4216 , +-2108 , +-2108 , +372 , +372 , +2666 , +2666 , +4898 , +4898 , +6510 , +6510 , +7564 , +7564 , +7874 , +7874 , +7564 , +7564 , +6386 , +6386 , +4712 , +4712 , +2480 , +2480 , +186 , +186 , +-2294 , +-2294 , +-4402 , +-4402 , +-6262 , +-6262 , +-7378 , +-7378 , +-7874 , +-7874 , +-7688 , +-7688 , +-6696 , +-6696 , +-5022 , +-5022 , +-3038 , +-3038 , +-558 , +-558 , +1736 , +1736 , +4092 , +4092 , +5890 , +5890 , +7137 , +7137 , +7747 , +7747 , +7686 , +7686 , +6893 , +6893 , +5368 , +5368 , +3355 , +3355 , +1159 , +1159 , +-1342 , +-1342 , +-3538 , +-3538 , +-5551 , +-5551 , +-6893 , +-6893 , +-7686 , +-7686 , +-7747 , +-7747 , +-7076 , +-7076 , +-5795 , +-5795 , +-3843 , +-3843 , +-1708 , +-1708 , +793 , +793 , +3172 , +3172 , +5124 , +5124 , +6710 , +6710 , +7564 , +7564 , +7747 , +7747 , +7259 , +7259 , +6039 , +6039 , +4331 , +4331 , +2074 , +2074 , +-183 , +-183 , +-2623 , +-2623 , +-4819 , +-4819 , +-6405 , +-6405 , +-7442 , +-7442 , +-7620 , +-7620 , +-7320 , +-7320 , +-6300 , +-6300 , +-4560 , +-4560 , +-2580 , +-2580 , +-180 , +-180 , +2040 , +2040 , +4260 , +4260 , +6060 , +6060 , +7140 , +7140 , +7620 , +7620 , +7440 , +7440 , +6480 , +6480 , +5040 , +5040 , +2940 , +2940 , +780 , +780 , +-1680 , +-1680 , +-3780 , +-3780 , +-5700 , +-5700 , +-6960 , +-6960 , +-7620 , +-7620 , +-7560 , +-7560 , +-6780 , +-6780 , +-5280 , +-5280 , +-3480 , +-3480 , +-1140 , +-1140 , +1140 , +1140 , +3480 , +3480 , +5280 , +5280 , +6780 , +6780 , +7560 , +7560 , +7620 , +7620 , +6728 , +6728 , +5510 , +5510 , +3654 , +3654 , +1624 , +1624 , +-754 , +-754 , +-2842 , +-2842 , +-4872 , +-4872 , +-6264 , +-6264 , +-7192 , +-7192 , +-7366 , +-7366 , +-6902 , +-6902 , +-5742 , +-5742 , +-4118 , +-4118 , +-1972 , +-1972 , +174 , +174 , +2494 , +2494 , +4408 , +4408 , +6090 , +6090 , +7076 , +7076 , +7366 , +7366 , +7076 , +7076 , +6090 , +6090 , +4582 , +4582 , +2494 , +2494 , +174 , +174 , +-1972 , +-1972 , +-4118 , +-4118 , +-5742 , +-5742 , +-6902 , +-6902 , +-7366 , +-7366 , +-7192 , +-7192 , +-6380 , +-6380 , +-4788 , +-4788 , +-2964 , +-2964 , +-741 , +-741 , +1596 , +1596 , +3591 , +3591 , +5415 , +5415 , +6612 , +6612 , +7239 , +7239 , +7182 , +7182 , +6441 , +6441 , +5187 , +5187 , +3306 , +3306 , +1254 , +1254 , +-1083 , +-1083 , +-3306 , +-3306 , +-5016 , +-5016 , +-6441 , +-6441 , +-7182 , +-7182 , +-7239 , +-7239 , +-6669 , +-6669 , +-5415 , +-5415 , +-3762 , +-3762 , +-1596 , +-1596 , +513 , +513 , +2793 , +2793 , +4617 , +4617 , +6156 , +6156 , +7068 , +7068 , +7239 , +7239 , +6783 , +6783 , +5757 , +5757 , +4047 , +4047 , +2072 , +2072 , +-168 , +-168 , +-2240 , +-2240 , +-4256 , +-4256 , +-5768 , +-5768 , +-6832 , +-6832 , +-7112 , +-7112 , +-6832 , +-6832 , +-5880 , +-5880 , +-4424 , +-4424 , +-2408 , +-2408 , +-336 , +-336 , +1904 , +1904 , +3808 , +3808 , +5544 , +5544 , +6608 , +6608 , +7112 , +7112 , +6944 , +6944 , +6160 , +6160 , +4704 , +4704 , +2912 , +2912 , +728 , +728 , +-1400 , +-1400 , +-3528 , +-3528 , +-5208 , +-5208 , +-6496 , +-6496 , +-7112 , +-7112 , +-7056 , +-7056 , +-6384 , +-6384 , +-5096 , +-5096 , +-3248 , +-3248 , +-1232 , +-1232 , +1045 , +1045 , +3025 , +3025 , +4840 , +4840 , +6105 , +6105 , +6930 , +6930 , +6985 , +6985 , +6435 , +6435 , +5335 , +5335 , +3630 , +3630 , +1540 , +1540 , +-495 , +-495 , +-2695 , +-2695 , +-4455 , +-4455 , +-5940 , +-5940 , +-6765 , +-6765 , +-6985 , +-6985 , +-6655 , +-6655 , +-5555 , +-5555 , +-4070 , +-4070 , +-2035 , +-2035 , +165 , +165 , +2200 , +2200 , +4180 , +4180 , +5665 , +5665 , +6710 , +6710 , +6985 , +6985 , +6710 , +6710 , +5830 , +5830 , +4345 , +4345 , +2530 , +2530 , +330 , +330 , +-1870 , +-1870 , +-3604 , +-3604 , +-5247 , +-5247 , +-6254 , +-6254 , +-6731 , +-6731 , +-6625 , +-6625 , +-5830 , +-5830 , +-4558 , +-4558 , +-2756 , +-2756 , +-848 , +-848 , +1325 , +1325 , +3180 , +3180 , +4929 , +4929 , +6148 , +6148 , +6731 , +6731 , +6678 , +6678 , +6042 , +6042 , +4823 , +4823 , +3180 , +3180 , +1166 , +1166 , +-848 , +-848 , +-2915 , +-2915 , +-4558 , +-4558 , +-5883 , +-5883 , +-6678 , +-6678 , +-6731 , +-6731 , +-6201 , +-6201 , +-5141 , +-5141 , +-3498 , +-3498 , +-1643 , +-1643 , +477 , +477 , +2438 , +2438 , +4293 , +4293 , +5512 , +5512 , +6396 , +6396 , +6604 , +6604 , +6292 , +6292 , +5252 , +5252 , +3848 , +3848 , +1924 , +1924 , +0 , +0 , +-2080 , +-2080 , +-3848 , +-3848 , +-5356 , +-5356 , +-6292 , +-6292 , +-6604 , +-6604 , +-6396 , +-6396 , +-5512 , +-5512 , +-4108 , +-4108 , +-2392 , +-2392 , +-312 , +-312 , +1612 , +1612 , +3536 , +3536 , +5044 , +5044 , +6136 , +6136 , +6604 , +6604 , +6500 , +6500 , +5772 , +5772 , +4472 , +4472 , +2704 , +2704 , +832 , +832 , +-1300 , +-1300 , +-3120 , +-3120 , +-4836 , +-4836 , +-5928 , +-5928 , +-6477 , +-6477 , +-6477 , +-6477 , +-5814 , +-5814 , +-4743 , +-4743 , +-3060 , +-3060 , +-1122 , +-1122 , +816 , +816 , +2805 , +2805 , +4386 , +4386 , +5661 , +5661 , +6375 , +6375 , +6477 , +6477 , +6018 , +6018 , +4947 , +4947 , +3468 , +3468 , +1581 , +1581 , +-306 , +-306 , +-2346 , +-2346 , +-4131 , +-4131 , +-5406 , +-5406 , +-6273 , +-6273 , +-6477 , +-6477 , +-6171 , +-6171 , +-5253 , +-5253 , +-3774 , +-3774 , +-2040 , +-2040 , +0 , +0 , +1887 , +1887 , +3774 , +3774 , +5253 , +5253 , +6171 , +6171 , +6477 , +6477 , +6027 , +6027 , +5194 , +5194 , +3969 , +3969 , +2254 , +2254 , +441 , +441 , +-1519 , +-1519 , +-3234 , +-3234 , +-4753 , +-4753 , +-5782 , +-5782 , +-6223 , +-6223 , +-6125 , +-6125 , +-5439 , +-5439 , +-4214 , +-4214 , +-2695 , +-2695 , +-784 , +-784 , +1078 , +1078 , +2940 , +2940 , +4459 , +4459 , +5586 , +5586 , +6174 , +6174 , +6223 , +6223 , +5586 , +5586 , +4557 , +4557 , +2940 , +2940 , +1225 , +1225 , +-784 , +-784 , +-2548 , +-2548 , +-4214 , +-4214 , +-5390 , +-5390 , +-6125 , +-6125 , +-6223 , +-6223 , +-5782 , +-5782 , +-4656 , +-4656 , +-3264 , +-3264 , +-1488 , +-1488 , +288 , +288 , +2208 , +2208 , +3792 , +3792 , +5088 , +5088 , +5856 , +5856 , +6096 , +6096 , +5856 , +5856 , +4944 , +4944 , +3552 , +3552 , +1920 , +1920 , +0 , +0 , +-1776 , +-1776 , +-3552 , +-3552 , +-4848 , +-4848 , +-5808 , +-5808 , +-6096 , +-6096 , +-5904 , +-5904 , +-5184 , +-5184 , +-3888 , +-3888 , +-2352 , +-2352 , +-432 , +-432 , +1488 , +1488 , +3168 , +3168 , +4656 , +4656 , +5616 , +5616 , +6096 , +6096 , +6048 , +6048 , +5328 , +5328 , +4224 , +4224 , +2585 , +2585 , +893 , +893 , +-1034 , +-1034 , +-2820 , +-2820 , +-4277 , +-4277 , +-5358 , +-5358 , +-5922 , +-5922 , +-5969 , +-5969 , +-5452 , +-5452 , +-4371 , +-4371 , +-2961 , +-2961 , +-1175 , +-1175 , +611 , +611 , +2444 , +2444 , +4042 , +4042 , +5170 , +5170 , +5875 , +5875 , +5969 , +5969 , +5546 , +5546 , +4653 , +4653 , +3196 , +3196 , +1598 , +1598 , +-282 , +-282 , +-2021 , +-2021 , +-3713 , +-3713 , +-4935 , +-4935 , +-5734 , +-5734 , +-5969 , +-5969 , +-5734 , +-5734 , +-4841 , +-4841 , +-3572 , +-3572 , +-1880 , +-1880 , +-138 , +-138 , +1702 , +1702 , +3266 , +3266 , +4646 , +4646 , +5474 , +5474 , +5842 , +5842 , +5658 , +5658 , +4968 , +4968 , +3726 , +3726 , +2254 , +2254 , +414 , +414 , +-1288 , +-1288 , +-3036 , +-3036 , +-4370 , +-4370 , +-5382 , +-5382 , +-5842 , +-5842 , +-5796 , +-5796 , +-5106 , +-5106 , +-4048 , +-4048 , +-2530 , +-2530 , +-874 , +-874 , +1012 , +1012 , +2668 , +2668 , +4186 , +4186 , +5198 , +5198 , +5796 , +5796 , +5842 , +5842 , +5336 , +5336 , +4370 , +4370 , +2898 , +2898 , +1150 , +1150 , +-598 , +-598 , +-2288 , +-2288 , +-3696 , +-3696 , +-4840 , +-4840 , +-5456 , +-5456 , +-5588 , +-5588 , +-5236 , +-5236 , +-4356 , +-4356 , +-3124 , +-3124 , +-1496 , +-1496 , +264 , +264 , +1892 , +1892 , +3476 , +3476 , +4620 , +4620 , +5368 , +5368 , +5588 , +5588 , +5368 , +5368 , +4620 , +4620 , +3344 , +3344 , +1892 , +1892 , +132 , +132 , +-1628 , +-1628 , +-3124 , +-3124 , +-4444 , +-4444 , +-5236 , +-5236 , +-5588 , +-5588 , +-5456 , +-5456 , +-4752 , +-4752 , +-3696 , +-3696 , +-2156 , +-2156 , +-572 , +-572 , +1232 , +1232 , +2904 , +2904 , +4085 , +4085 , +5031 , +5031 , +5461 , +5461 , +5418 , +5418 , +4859 , +4859 , +3784 , +3784 , +2494 , +2494 , +817 , +817 , +-817 , +-817 , +-2494 , +-2494 , +-3784 , +-3784 , +-4859 , +-4859 , +-5418 , +-5418 , +-5461 , +-5461 , +-4988 , +-4988 , +-4085 , +-4085 , +-2709 , +-2709 , +-1204 , +-1204 , +559 , +559 , +2107 , +2107 , +3612 , +3612 , +4644 , +4644 , +5332 , +5332 , +5461 , +5461 , +5117 , +5117 , +4257 , +4257 , +3053 , +3053 , +1462 , +1462 , +-129 , +-129 , +-1849 , +-1849 , +-3268 , +-3268 , +-4515 , +-4515 , +-5124 , +-5124 , +-5334 , +-5334 , +-5124 , +-5124 , +-4410 , +-4410 , +-3192 , +-3192 , +-1806 , +-1806 , +-126 , +-126 , +1428 , +1428 , +2982 , +2982 , +4158 , +4158 , +4998 , +4998 , +5334 , +5334 , +5208 , +5208 , +4620 , +4620 , +3528 , +3528 , +2058 , +2058 , +546 , +546 , +-1176 , +-1176 , +-2646 , +-2646 , +-3990 , +-3990 , +-4872 , +-4872 , +-5334 , +-5334 , +-5292 , +-5292 , +-4746 , +-4746 , +-3822 , +-3822 , +-2436 , +-2436 , +-798 , +-798 , +798 , +798 , +2436 , +2436 , +3696 , +3696 , +4746 , +4746 , +5292 , +5292 , +5080 , +5080 , +4680 , +4680 , +3800 , +3800 , +2640 , +2640 , +1120 , +1120 , +-520 , +-520 , +-1960 , +-1960 , +-3360 , +-3360 , +-4320 , +-4320 , +-4960 , +-4960 , +-5080 , +-5080 , +-4760 , +-4760 , +-4040 , +-4040 , +-2840 , +-2840 , +-1480 , +-1480 , +120 , +120 , +1600 , +1600 , +3040 , +3040 , +4200 , +4200 , +4880 , +4880 , +5080 , +5080 , +4880 , +4880 , +4200 , +4200 , +3160 , +3160 , +1720 , +1720 , +240 , +240 , +-1360 , +-1360 , +-2720 , +-2720 , +-3960 , +-3960 , +-4760 , +-4760 , +-5080 , +-5080 , +-4960 , +-4960 , +-4290 , +-4290 , +-3276 , +-3276 , +-2028 , +-2028 , +-507 , +-507 , +975 , +975 , +2457 , +2457 , +3627 , +3627 , +4524 , +4524 , +4953 , +4953 , +4914 , +4914 , +4407 , +4407 , +3549 , +3549 , +2262 , +2262 , +858 , +858 , +-741 , +-741 , +-2145 , +-2145 , +-3432 , +-3432 , +-4329 , +-4329 , +-4914 , +-4914 , +-4953 , +-4953 , +-4563 , +-4563 , +-3705 , +-3705 , +-2574 , +-2574 , +-1092 , +-1092 , +351 , +351 , +1911 , +1911 , +3159 , +3159 , +4212 , +4212 , +4797 , +4797 , +4953 , +4953 , +4719 , +4719 , +3939 , +3939 , +2698 , +2698 , +1406 , +1406 , +-114 , +-114 , +-1520 , +-1520 , +-2888 , +-2888 , +-3914 , +-3914 , +-4636 , +-4636 , +-4826 , +-4826 , +-4636 , +-4636 , +-4028 , +-4028 , +-3002 , +-3002 , +-1634 , +-1634 , +-228 , +-228 , +1292 , +1292 , +2584 , +2584 , +3762 , +3762 , +4484 , +4484 , +4826 , +4826 , +4750 , +4750 , +4180 , +4180 , +3268 , +3268 , +1976 , +1976 , +608 , +608 , +-950 , +-950 , +-2394 , +-2394 , +-3534 , +-3534 , +-4408 , +-4408 , +-4826 , +-4826 , +-4788 , +-4788 , +-4332 , +-4332 , +-3458 , +-3458 , +-2280 , +-2280 , +-814 , +-814 , +592 , +592 , +2035 , +2035 , +3256 , +3256 , +4107 , +4107 , +4662 , +4662 , +4699 , +4699 , +4329 , +4329 , +3589 , +3589 , +2442 , +2442 , +1147 , +1147 , +-333 , +-333 , +-1702 , +-1702 , +-2997 , +-2997 , +-3996 , +-3996 , +-4551 , +-4551 , +-4699 , +-4699 , +-4477 , +-4477 , +-3737 , +-3737 , +-2738 , +-2738 , +-1369 , +-1369 , +0 , +0 , +1480 , +1480 , +2738 , +2738 , +3811 , +3811 , +4477 , +4477 , +4699 , +4699 , +4514 , +4514 , +3922 , +3922 , +2923 , +2923 , +1702 , +1702 , +222 , +222 , +-1085 , +-1085 , +-2380 , +-2380 , +-3395 , +-3395 , +-4130 , +-4130 , +-4445 , +-4445 , +-4375 , +-4375 , +-3850 , +-3850 , +-3010 , +-3010 , +-1820 , +-1820 , +-560 , +-560 , +875 , +875 , +2100 , +2100 , +3255 , +3255 , +3990 , +3990 , +4445 , +4445 , +4445 , +4445 , +3990 , +3990 , +3185 , +3185 , +2100 , +2100 , +770 , +770 , +-560 , +-560 , +-1925 , +-1925 , +-3010 , +-3010 , +-3885 , +-3885 , +-4375 , +-4375 , +-4445 , +-4445 , +-4130 , +-4130 , +-3395 , +-3395 , +-2380 , +-2380 , +-1085 , +-1085 , +315 , +315 , +1610 , +1610 , +2754 , +2754 , +3604 , +3604 , +4182 , +4182 , +4318 , +4318 , +4114 , +4114 , +3502 , +3502 , +2516 , +2516 , +1360 , +1360 , +0 , +0 , +-1360 , +-1360 , +-2516 , +-2516 , +-3502 , +-3502 , +-4114 , +-4114 , +-4318 , +-4318 , +-4182 , +-4182 , +-3604 , +-3604 , +-2754 , +-2754 , +-1564 , +-1564 , +-306 , +-306 , +1054 , +1054 , +2312 , +2312 , +3298 , +3298 , +4012 , +4012 , +4318 , +4318 , +4250 , +4250 , +3774 , +3774 , +2924 , +2924 , +1870 , +1870 , +544 , +544 , +-748 , +-748 , +-2040 , +-2040 , +-3162 , +-3162 , +-3762 , +-3762 , +-4191 , +-4191 , +-4191 , +-4191 , +-3762 , +-3762 , +-3069 , +-3069 , +-1980 , +-1980 , +-825 , +-825 , +528 , +528 , +1716 , +1716 , +2838 , +2838 , +3630 , +3630 , +4125 , +4125 , +4191 , +4191 , +3894 , +3894 , +3201 , +3201 , +2244 , +2244 , +1023 , +1023 , +-198 , +-198 , +-1518 , +-1518 , +-2607 , +-2607 , +-3498 , +-3498 , +-4026 , +-4026 , +-4191 , +-4191 , +-3993 , +-3993 , +-3399 , +-3399 , +-2442 , +-2442 , +-1320 , +-1320 , +0 , +0 , +1221 , +1221 , +2442 , +2442 , +3333 , +3333 , +3993 , +3993 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +2368 , +2368 , +4736 , +4736 , +6464 , +6464 , +7744 , +7744 , +8128 , +8128 , +7872 , +7872 , +6912 , +6912 , +5184 , +5184 , +3136 , +3136 , +576 , +576 , +-1792 , +-1792 , +-4224 , +-4224 , +-6208 , +-6208 , +-7488 , +-7488 , +-8128 , +-8128 , +-8064 , +-8064 , +-7104 , +-7104 , +-5632 , +-5632 , +-3520 , +-3520 , +-1216 , +-1216 , +1408 , +1408 , +3712 , +3712 , +5824 , +5824 , +7296 , +7296 , +8064 , +8064 , +8128 , +8128 , +7424 , +7424 , +5952 , +5952 , +4032 , +4032 , +1600 , +1600 , +-832 , +-832 , +-3328 , +-3328 , +-5208 , +-5208 , +-6820 , +-6820 , +-7750 , +-7750 , +-7874 , +-7874 , +-7316 , +-7316 , +-6138 , +-6138 , +-4216 , +-4216 , +-2108 , +-2108 , +372 , +372 , +2666 , +2666 , +4898 , +4898 , +6510 , +6510 , +7564 , +7564 , +7874 , +7874 , +7564 , +7564 , +6386 , +6386 , +4712 , +4712 , +2480 , +2480 , +186 , +186 , +-2294 , +-2294 , +-4402 , +-4402 , +-6262 , +-6262 , +-7378 , +-7378 , +-7874 , +-7874 , +-7688 , +-7688 , +-6696 , +-6696 , +-5022 , +-5022 , +-3038 , +-3038 , +-558 , +-558 , +1736 , +1736 , +4092 , +4092 , +5890 , +5890 , +7137 , +7137 , +7747 , +7747 , +7686 , +7686 , +6893 , +6893 , +5368 , +5368 , +3355 , +3355 , +1159 , +1159 , +-1342 , +-1342 , +-3538 , +-3538 , +-5551 , +-5551 , +-6893 , +-6893 , +-7686 , +-7686 , +-7747 , +-7747 , +-7076 , +-7076 , +-5795 , +-5795 , +-3843 , +-3843 , +-1708 , +-1708 , +793 , +793 , +3172 , +3172 , +5124 , +5124 , +6710 , +6710 , +7564 , +7564 , +7747 , +7747 , +7259 , +7259 , +6039 , +6039 , +4331 , +4331 , +2074 , +2074 , +-183 , +-183 , +-2623 , +-2623 , +-4819 , +-4819 , +-6405 , +-6405 , +-7442 , +-7442 , +-7620 , +-7620 , +-7320 , +-7320 , +-6300 , +-6300 , +-4560 , +-4560 , +-2580 , +-2580 , +-180 , +-180 , +2040 , +2040 , +4260 , +4260 , +6060 , +6060 , +7140 , +7140 , +7620 , +7620 , +7440 , +7440 , +6480 , +6480 , +5040 , +5040 , +2940 , +2940 , +780 , +780 , +-1680 , +-1680 , +-3780 , +-3780 , +-5700 , +-5700 , +-6960 , +-6960 , +-7620 , +-7620 , +-7560 , +-7560 , +-6780 , +-6780 , +-5280 , +-5280 , +-3480 , +-3480 , +-1140 , +-1140 , +1140 , +1140 , +3480 , +3480 , +5280 , +5280 , +6780 , +6780 , +7560 , +7560 , +7620 , +7620 , +6728 , +6728 , +5510 , +5510 , +3654 , +3654 , +1624 , +1624 , +-754 , +-754 , +-2842 , +-2842 , +-4872 , +-4872 , +-6264 , +-6264 , +-7192 , +-7192 , +-7366 , +-7366 , +-6902 , +-6902 , +-5742 , +-5742 , +-4118 , +-4118 , +-1972 , +-1972 , +174 , +174 , +2494 , +2494 , +4408 , +4408 , +6090 , +6090 , +7076 , +7076 , +7366 , +7366 , +7076 , +7076 , +6090 , +6090 , +4582 , +4582 , +2494 , +2494 , +174 , +174 , +-1972 , +-1972 , +-4118 , +-4118 , +-5742 , +-5742 , +-6902 , +-6902 , +-7366 , +-7366 , +-7192 , +-7192 , +-6380 , +-6380 , +-4788 , +-4788 , +-2964 , +-2964 , +-741 , +-741 , +1596 , +1596 , +3591 , +3591 , +5415 , +5415 , +6612 , +6612 , +7239 , +7239 , +7182 , +7182 , +6441 , +6441 , +5187 , +5187 , +3306 , +3306 , +1254 , +1254 , +-1083 , +-1083 , +-3306 , +-3306 , +-5016 , +-5016 , +-6441 , +-6441 , +-7182 , +-7182 , +-7239 , +-7239 , +-6669 , +-6669 , +-5415 , +-5415 , +-3762 , +-3762 , +-1596 , +-1596 , +513 , +513 , +2793 , +2793 , +4617 , +4617 , +6156 , +6156 , +7068 , +7068 , +7239 , +7239 , +6783 , +6783 , +5757 , +5757 , +4047 , +4047 , +2072 , +2072 , +-168 , +-168 , +-2240 , +-2240 , +-4256 , +-4256 , +-5768 , +-5768 , +-6832 , +-6832 , +-7112 , +-7112 , +-6832 , +-6832 , +-5880 , +-5880 , +-4424 , +-4424 , +-2408 , +-2408 , +-336 , +-336 , +1904 , +1904 , +3808 , +3808 , +5544 , +5544 , +6608 , +6608 , +7112 , +7112 , +6944 , +6944 , +6160 , +6160 , +4704 , +4704 , +2912 , +2912 , +728 , +728 , +-1400 , +-1400 , +-3528 , +-3528 , +-5208 , +-5208 , +-6496 , +-6496 , +-7112 , +-7112 , +-7056 , +-7056 , +-6384 , +-6384 , +-5096 , +-5096 , +-3248 , +-3248 , +-1232 , +-1232 , +1045 , +1045 , +3025 , +3025 , +4840 , +4840 , +6105 , +6105 , +6930 , +6930 , +6985 , +6985 , +6435 , +6435 , +5335 , +5335 , +3630 , +3630 , +1540 , +1540 , +-495 , +-495 , +-2695 , +-2695 , +-4455 , +-4455 , +-5940 , +-5940 , +-6765 , +-6765 , +-6985 , +-6985 , +-6655 , +-6655 , +-5555 , +-5555 , +-4070 , +-4070 , +-2035 , +-2035 , +165 , +165 , +2200 , +2200 , +4180 , +4180 , +5665 , +5665 , +6710 , +6710 , +6985 , +6985 , +6710 , +6710 , +5830 , +5830 , +4345 , +4345 , +2530 , +2530 , +330 , +330 , +-1870 , +-1870 , +-3604 , +-3604 , +-5247 , +-5247 , +-6254 , +-6254 , +-6731 , +-6731 , +-6625 , +-6625 , +-5830 , +-5830 , +-4558 , +-4558 , +-2756 , +-2756 , +-848 , +-848 , +1325 , +1325 , +3180 , +3180 , +4929 , +4929 , +6148 , +6148 , +6731 , +6731 , +6678 , +6678 , +6042 , +6042 , +4823 , +4823 , +3180 , +3180 , +1166 , +1166 , +-848 , +-848 , +-2915 , +-2915 , +-4558 , +-4558 , +-5883 , +-5883 , +-6678 , +-6678 , +-6731 , +-6731 , +-6201 , +-6201 , +-5141 , +-5141 , +-3498 , +-3498 , +-1643 , +-1643 , +477 , +477 , +2438 , +2438 , +4293 , +4293 , +5512 , +5512 , +6396 , +6396 , +6604 , +6604 , +6292 , +6292 , +5252 , +5252 , +3848 , +3848 , +1924 , +1924 , +0 , +0 , +-2080 , +-2080 , +-3848 , +-3848 , +-5356 , +-5356 , +-6292 , +-6292 , +-6604 , +-6604 , +-6396 , +-6396 , +-5512 , +-5512 , +-4108 , +-4108 , +-2392 , +-2392 , +-312 , +-312 , +1612 , +1612 , +3536 , +3536 , +5044 , +5044 , +6136 , +6136 , +6604 , +6604 , +6500 , +6500 , +5772 , +5772 , +4472 , +4472 , +2704 , +2704 , +832 , +832 , +-1300 , +-1300 , +-3120 , +-3120 , +-4836 , +-4836 , +-5928 , +-5928 , +-6477 , +-6477 , +-6477 , +-6477 , +-5814 , +-5814 , +-4743 , +-4743 , +-3060 , +-3060 , +-1122 , +-1122 , +816 , +816 , +2805 , +2805 , +4386 , +4386 , +5661 , +5661 , +6375 , +6375 , +6477 , +6477 , +6018 , +6018 , +4947 , +4947 , +3468 , +3468 , +1581 , +1581 , +-306 , +-306 , +-2346 , +-2346 , +-4131 , +-4131 , +-5406 , +-5406 , +-6273 , +-6273 , +-6477 , +-6477 , +-6171 , +-6171 , +-5253 , +-5253 , +-3774 , +-3774 , +-2040 , +-2040 , +0 , +0 , +1887 , +1887 , +3774 , +3774 , +5253 , +5253 , +6171 , +6171 , +6477 , +6477 , +6027 , +6027 , +5194 , +5194 , +3969 , +3969 , +2254 , +2254 , +441 , +441 , +-1519 , +-1519 , +-3234 , +-3234 , +-4753 , +-4753 , +-5782 , +-5782 , +-6223 , +-6223 , +-6125 , +-6125 , +-5439 , +-5439 , +-4214 , +-4214 , +-2695 , +-2695 , +-784 , +-784 , +1078 , +1078 , +2940 , +2940 , +4459 , +4459 , +5586 , +5586 , +6174 , +6174 , +6223 , +6223 , +5586 , +5586 , +4557 , +4557 , +2940 , +2940 , +1225 , +1225 , +-784 , +-784 , +-2548 , +-2548 , +-4214 , +-4214 , +-5390 , +-5390 , +-6125 , +-6125 , +-6223 , +-6223 , +-5782 , +-5782 , +-4656 , +-4656 , +-3264 , +-3264 , +-1488 , +-1488 , +288 , +288 , +2208 , +2208 , +3792 , +3792 , +5088 , +5088 , +5856 , +5856 , +6096 , +6096 , +5856 , +5856 , +4944 , +4944 , +3552 , +3552 , +1920 , +1920 , +0 , +0 , +-1776 , +-1776 , +-3552 , +-3552 , +-4848 , +-4848 , +-5808 , +-5808 , +-6096 , +-6096 , +-5904 , +-5904 , +-5184 , +-5184 , +-3888 , +-3888 , +-2352 , +-2352 , +-432 , +-432 , +1488 , +1488 , +3168 , +3168 , +4656 , +4656 , +5616 , +5616 , +6096 , +6096 , +6048 , +6048 , +5328 , +5328 , +4224 , +4224 , +2585 , +2585 , +893 , +893 , +-1034 , +-1034 , +-2820 , +-2820 , +-4277 , +-4277 , +-5358 , +-5358 , +-5922 , +-5922 , +-5969 , +-5969 , +-5452 , +-5452 , +-4371 , +-4371 , +-2961 , +-2961 , +-1175 , +-1175 , +611 , +611 , +2444 , +2444 , +4042 , +4042 , +5170 , +5170 , +5875 , +5875 , +5969 , +5969 , +5546 , +5546 , +4653 , +4653 , +3196 , +3196 , +1598 , +1598 , +-282 , +-282 , +-2021 , +-2021 , +-3713 , +-3713 , +-4935 , +-4935 , +-5734 , +-5734 , +-5969 , +-5969 , +-5734 , +-5734 , +-4841 , +-4841 , +-3572 , +-3572 , +-1880 , +-1880 , +-138 , +-138 , +1702 , +1702 , +3266 , +3266 , +4646 , +4646 , +5474 , +5474 , +5842 , +5842 , +5658 , +5658 , +4968 , +4968 , +3726 , +3726 , +2254 , +2254 , +414 , +414 , +-1288 , +-1288 , +-3036 , +-3036 , +-4370 , +-4370 , +-5382 , +-5382 , +-5842 , +-5842 , +-5796 , +-5796 , +-5106 , +-5106 , +-4048 , +-4048 , +-2530 , +-2530 , +-874 , +-874 , +1012 , +1012 , +2668 , +2668 , +4186 , +4186 , +5198 , +5198 , +5796 , +5796 , +5842 , +5842 , +5336 , +5336 , +4370 , +4370 , +2898 , +2898 , +1150 , +1150 , +-598 , +-598 , +-2288 , +-2288 , +-3696 , +-3696 , +-4840 , +-4840 , +-5456 , +-5456 , +-5588 , +-5588 , +-5236 , +-5236 , +-4356 , +-4356 , +-3124 , +-3124 , +-1496 , +-1496 , +264 , +264 , +1892 , +1892 , +3476 , +3476 , +4620 , +4620 , +5368 , +5368 , +5588 , +5588 , +5368 , +5368 , +4620 , +4620 , +3344 , +3344 , +1892 , +1892 , +132 , +132 , +-1628 , +-1628 , +-3124 , +-3124 , +-4444 , +-4444 , +-5236 , +-5236 , +-5588 , +-5588 , +-5456 , +-5456 , +-4752 , +-4752 , +-3696 , +-3696 , +-2156 , +-2156 , +-572 , +-572 , +1232 , +1232 , +2904 , +2904 , +4085 , +4085 , +5031 , +5031 , +5461 , +5461 , +5418 , +5418 , +4859 , +4859 , +3784 , +3784 , +2494 , +2494 , +817 , +817 , +-817 , +-817 , +-2494 , +-2494 , +-3784 , +-3784 , +-4859 , +-4859 , +-5418 , +-5418 , +-5461 , +-5461 , +-4988 , +-4988 , +-4085 , +-4085 , +-2709 , +-2709 , +-1204 , +-1204 , +559 , +559 , +2107 , +2107 , +3612 , +3612 , +4644 , +4644 , +5332 , +5332 , +5461 , +5461 , +5117 , +5117 , +4257 , +4257 , +3053 , +3053 , +1462 , +1462 , +-129 , +-129 , +-1849 , +-1849 , +-3268 , +-3268 , +-4515 , +-4515 , +-5124 , +-5124 , +-5334 , +-5334 , +-5124 , +-5124 , +-4410 , +-4410 , +-3192 , +-3192 , +-1806 , +-1806 , +-126 , +-126 , +1428 , +1428 , +2982 , +2982 , +4158 , +4158 , +4998 , +4998 , +5334 , +5334 , +5208 , +5208 , +4620 , +4620 , +3528 , +3528 , +2058 , +2058 , +546 , +546 , +-1176 , +-1176 , +-2646 , +-2646 , +-3990 , +-3990 , +-4872 , +-4872 , +-5334 , +-5334 , +-5292 , +-5292 , +-4746 , +-4746 , +-3822 , +-3822 , +-2436 , +-2436 , +-798 , +-798 , +798 , +798 , +2436 , +2436 , +3696 , +3696 , +4746 , +4746 , +5292 , +5292 , +5080 , +5080 , +4680 , +4680 , +3800 , +3800 , +2640 , +2640 , +1120 , +1120 , +-520 , +-520 , +-1960 , +-1960 , +-3360 , +-3360 , +-4320 , +-4320 , +-4960 , +-4960 , +-5080 , +-5080 , +-4760 , +-4760 , +-4040 , +-4040 , +-2840 , +-2840 , +-1480 , +-1480 , +120 , +120 , +1600 , +1600 , +3040 , +3040 , +4200 , +4200 , +4880 , +4880 , +5080 , +5080 , +4880 , +4880 , +4200 , +4200 , +3160 , +3160 , +1720 , +1720 , +240 , +240 , +-1360 , +-1360 , +-2720 , +-2720 , +-3960 , +-3960 , +-4760 , +-4760 , +-5080 , +-5080 , +-4960 , +-4960 , +-4290 , +-4290 , +-3276 , +-3276 , +-2028 , +-2028 , +-507 , +-507 , +975 , +975 , +2457 , +2457 , +3627 , +3627 , +4524 , +4524 , +4953 , +4953 , +4914 , +4914 , +4407 , +4407 , +3549 , +3549 , +2262 , +2262 , +858 , +858 , +-741 , +-741 , +-2145 , +-2145 , +-3432 , +-3432 , +-4329 , +-4329 , +-4914 , +-4914 , +-4953 , +-4953 , +-4563 , +-4563 , +-3705 , +-3705 , +-2574 , +-2574 , +-1092 , +-1092 , +351 , +351 , +1911 , +1911 , +3159 , +3159 , +4212 , +4212 , +4797 , +4797 , +4953 , +4953 , +4719 , +4719 , +3939 , +3939 , +2698 , +2698 , +1406 , +1406 , +-114 , +-114 , +-1520 , +-1520 , +-2888 , +-2888 , +-3914 , +-3914 , +-4636 , +-4636 , +-4826 , +-4826 , +-4636 , +-4636 , +-4028 , +-4028 , +-3002 , +-3002 , +-1634 , +-1634 , +-228 , +-228 , +1292 , +1292 , +2584 , +2584 , +3762 , +3762 , +4484 , +4484 , +4826 , +4826 , +4750 , +4750 , +4180 , +4180 , +3268 , +3268 , +1976 , +1976 , +608 , +608 , +-950 , +-950 , +-2394 , +-2394 , +-3534 , +-3534 , +-4408 , +-4408 , +-4826 , +-4826 , +-4788 , +-4788 , +-4332 , +-4332 , +-3458 , +-3458 , +-2280 , +-2280 , +-814 , +-814 , +592 , +592 , +2035 , +2035 , +3256 , +3256 , +4107 , +4107 , +4662 , +4662 , +4699 , +4699 , +4329 , +4329 , +3589 , +3589 , +2442 , +2442 , +1147 , +1147 , +-333 , +-333 , +-1702 , +-1702 , +-2997 , +-2997 , +-3996 , +-3996 , +-4551 , +-4551 , +-4699 , +-4699 , +-4477 , +-4477 , +-3737 , +-3737 , +-2738 , +-2738 , +-1369 , +-1369 , +0 , +0 , +1480 , +1480 , +2738 , +2738 , +3811 , +3811 , +4477 , +4477 , +4699 , +4699 , +4514 , +4514 , +3922 , +3922 , +2923 , +2923 , +1702 , +1702 , +222 , +222 , +-1085 , +-1085 , +-2380 , +-2380 , +-3395 , +-3395 , +-4130 , +-4130 , +-4445 , +-4445 , +-4375 , +-4375 , +-3850 , +-3850 , +-3010 , +-3010 , +-1820 , +-1820 , +-560 , +-560 , +875 , +875 , +2100 , +2100 , +3255 , +3255 , +3990 , +3990 , +4445 , +4445 , +4445 , +4445 , +3990 , +3990 , +3185 , +3185 , +2100 , +2100 , +770 , +770 , +-560 , +-560 , +-1925 , +-1925 , +-3010 , +-3010 , +-3885 , +-3885 , +-4375 , +-4375 , +-4445 , +-4445 , +-4130 , +-4130 , +-3395 , +-3395 , +-2380 , +-2380 , +-1085 , +-1085 , +315 , +315 , +1610 , +1610 , +2754 , +2754 , +3604 , +3604 , +4182 , +4182 , +4318 , +4318 , +4114 , +4114 , +3502 , +3502 , +2516 , +2516 , +1360 , +1360 , +0 , +0 , +-1360 , +-1360 , +-2516 , +-2516 , +-3502 , +-3502 , +-4114 , +-4114 , +-4318 , +-4318 , +-4182 , +-4182 , +-3604 , +-3604 , +-2754 , +-2754 , +-1564 , +-1564 , +-306 , +-306 , +1054 , +1054 , +2312 , +2312 , +3298 , +3298 , +4012 , +4012 , +4318 , +4318 , +4250 , +4250 , +3774 , +3774 , +2924 , +2924 , +1870 , +1870 , +544 , +544 , +-748 , +-748 , +-2040 , +-2040 , +-3162 , +-3162 , \ No newline at end of file diff --git a/config/_default_cfg_src_/res/ring/SOUND_RING_8000.txt b/config/_default_cfg_src_/res/ring/SOUND_RING_8000.txt new file mode 100644 index 0000000..c77f086 --- /dev/null +++ b/config/_default_cfg_src_/res/ring/SOUND_RING_8000.txt @@ -0,0 +1,4224 @@ +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +2368 , +2368 , +4736 , +4736 , +6464 , +6464 , +7744 , +7744 , +8128 , +8128 , +7872 , +7872 , +6912 , +6912 , +5184 , +5184 , +3136 , +3136 , +576 , +576 , +-1792 , +-1792 , +-4224 , +-4224 , +-6208 , +-6208 , +-7488 , +-7488 , +-8128 , +-8128 , +-8064 , +-8064 , +-7104 , +-7104 , +-5632 , +-5632 , +-3520 , +-3520 , +-1216 , +-1216 , +1408 , +1408 , +3712 , +3712 , +5824 , +5824 , +7296 , +7296 , +8064 , +8064 , +8128 , +8128 , +7424 , +7424 , +5952 , +5952 , +4032 , +4032 , +1600 , +1600 , +-832 , +-832 , +-3328 , +-3328 , +-5208 , +-5208 , +-6820 , +-6820 , +-7750 , +-7750 , +-7874 , +-7874 , +-7316 , +-7316 , +-6138 , +-6138 , +-4216 , +-4216 , +-2108 , +-2108 , +372 , +372 , +2666 , +2666 , +4898 , +4898 , +6510 , +6510 , +7564 , +7564 , +7874 , +7874 , +7564 , +7564 , +6386 , +6386 , +4712 , +4712 , +2480 , +2480 , +186 , +186 , +-2294 , +-2294 , +-4402 , +-4402 , +-6262 , +-6262 , +-7378 , +-7378 , +-7874 , +-7874 , +-7688 , +-7688 , +-6696 , +-6696 , +-5022 , +-5022 , +-3038 , +-3038 , +-558 , +-558 , +1736 , +1736 , +4092 , +4092 , +5890 , +5890 , +7137 , +7137 , +7747 , +7747 , +7686 , +7686 , +6893 , +6893 , +5368 , +5368 , +3355 , +3355 , +1159 , +1159 , +-1342 , +-1342 , +-3538 , +-3538 , +-5551 , +-5551 , +-6893 , +-6893 , +-7686 , +-7686 , +-7747 , +-7747 , +-7076 , +-7076 , +-5795 , +-5795 , +-3843 , +-3843 , +-1708 , +-1708 , +793 , +793 , +3172 , +3172 , +5124 , +5124 , +6710 , +6710 , +7564 , +7564 , +7747 , +7747 , +7259 , +7259 , +6039 , +6039 , +4331 , +4331 , +2074 , +2074 , +-183 , +-183 , +-2623 , +-2623 , +-4819 , +-4819 , +-6405 , +-6405 , +-7442 , +-7442 , +-7620 , +-7620 , +-7320 , +-7320 , +-6300 , +-6300 , +-4560 , +-4560 , +-2580 , +-2580 , +-180 , +-180 , +2040 , +2040 , +4260 , +4260 , +6060 , +6060 , +7140 , +7140 , +7620 , +7620 , +7440 , +7440 , +6480 , +6480 , +5040 , +5040 , +2940 , +2940 , +780 , +780 , +-1680 , +-1680 , +-3780 , +-3780 , +-5700 , +-5700 , +-6960 , +-6960 , +-7620 , +-7620 , +-7560 , +-7560 , +-6780 , +-6780 , +-5280 , +-5280 , +-3480 , +-3480 , +-1140 , +-1140 , +1140 , +1140 , +3480 , +3480 , +5280 , +5280 , +6780 , +6780 , +7560 , +7560 , +7620 , +7620 , +6728 , +6728 , +5510 , +5510 , +3654 , +3654 , +1624 , +1624 , +-754 , +-754 , +-2842 , +-2842 , +-4872 , +-4872 , +-6264 , +-6264 , +-7192 , +-7192 , +-7366 , +-7366 , +-6902 , +-6902 , +-5742 , +-5742 , +-4118 , +-4118 , +-1972 , +-1972 , +174 , +174 , +2494 , +2494 , +4408 , +4408 , +6090 , +6090 , +7076 , +7076 , +7366 , +7366 , +7076 , +7076 , +6090 , +6090 , +4582 , +4582 , +2494 , +2494 , +174 , +174 , +-1972 , +-1972 , +-4118 , +-4118 , +-5742 , +-5742 , +-6902 , +-6902 , +-7366 , +-7366 , +-7192 , +-7192 , +-6380 , +-6380 , +-4788 , +-4788 , +-2964 , +-2964 , +-741 , +-741 , +1596 , +1596 , +3591 , +3591 , +5415 , +5415 , +6612 , +6612 , +7239 , +7239 , +7182 , +7182 , +6441 , +6441 , +5187 , +5187 , +3306 , +3306 , +1254 , +1254 , +-1083 , +-1083 , +-3306 , +-3306 , +-5016 , +-5016 , +-6441 , +-6441 , +-7182 , +-7182 , +-7239 , +-7239 , +-6669 , +-6669 , +-5415 , +-5415 , +-3762 , +-3762 , +-1596 , +-1596 , +513 , +513 , +2793 , +2793 , +4617 , +4617 , +6156 , +6156 , +7068 , +7068 , +7239 , +7239 , +6783 , +6783 , +5757 , +5757 , +4047 , +4047 , +2072 , +2072 , +-168 , +-168 , +-2240 , +-2240 , +-4256 , +-4256 , +-5768 , +-5768 , +-6832 , +-6832 , +-7112 , +-7112 , +-6832 , +-6832 , +-5880 , +-5880 , +-4424 , +-4424 , +-2408 , +-2408 , +-336 , +-336 , +1904 , +1904 , +3808 , +3808 , +5544 , +5544 , +6608 , +6608 , +7112 , +7112 , +6944 , +6944 , +6160 , +6160 , +4704 , +4704 , +2912 , +2912 , +728 , +728 , +-1400 , +-1400 , +-3528 , +-3528 , +-5208 , +-5208 , +-6496 , +-6496 , +-7112 , +-7112 , +-7056 , +-7056 , +-6384 , +-6384 , +-5096 , +-5096 , +-3248 , +-3248 , +-1232 , +-1232 , +1045 , +1045 , +3025 , +3025 , +4840 , +4840 , +6105 , +6105 , +6930 , +6930 , +6985 , +6985 , +6435 , +6435 , +5335 , +5335 , +3630 , +3630 , +1540 , +1540 , +-495 , +-495 , +-2695 , +-2695 , +-4455 , +-4455 , +-5940 , +-5940 , +-6765 , +-6765 , +-6985 , +-6985 , +-6655 , +-6655 , +-5555 , +-5555 , +-4070 , +-4070 , +-2035 , +-2035 , +165 , +165 , +2200 , +2200 , +4180 , +4180 , +5665 , +5665 , +6710 , +6710 , +6985 , +6985 , +6710 , +6710 , +5830 , +5830 , +4345 , +4345 , +2530 , +2530 , +330 , +330 , +-1870 , +-1870 , +-3604 , +-3604 , +-5247 , +-5247 , +-6254 , +-6254 , +-6731 , +-6731 , +-6625 , +-6625 , +-5830 , +-5830 , +-4558 , +-4558 , +-2756 , +-2756 , +-848 , +-848 , +1325 , +1325 , +3180 , +3180 , +4929 , +4929 , +6148 , +6148 , +6731 , +6731 , +6678 , +6678 , +6042 , +6042 , +4823 , +4823 , +3180 , +3180 , +1166 , +1166 , +-848 , +-848 , +-2915 , +-2915 , +-4558 , +-4558 , +-5883 , +-5883 , +-6678 , +-6678 , +-6731 , +-6731 , +-6201 , +-6201 , +-5141 , +-5141 , +-3498 , +-3498 , +-1643 , +-1643 , +477 , +477 , +2438 , +2438 , +4293 , +4293 , +5512 , +5512 , +6396 , +6396 , +6604 , +6604 , +6292 , +6292 , +5252 , +5252 , +3848 , +3848 , +1924 , +1924 , +0 , +0 , +-2080 , +-2080 , +-3848 , +-3848 , +-5356 , +-5356 , +-6292 , +-6292 , +-6604 , +-6604 , +-6396 , +-6396 , +-5512 , +-5512 , +-4108 , +-4108 , +-2392 , +-2392 , +-312 , +-312 , +1612 , +1612 , +3536 , +3536 , +5044 , +5044 , +6136 , +6136 , +6604 , +6604 , +6500 , +6500 , +5772 , +5772 , +4472 , +4472 , +2704 , +2704 , +832 , +832 , +-1300 , +-1300 , +-3120 , +-3120 , +-4836 , +-4836 , +-5928 , +-5928 , +-6477 , +-6477 , +-6477 , +-6477 , +-5814 , +-5814 , +-4743 , +-4743 , +-3060 , +-3060 , +-1122 , +-1122 , +816 , +816 , +2805 , +2805 , +4386 , +4386 , +5661 , +5661 , +6375 , +6375 , +6477 , +6477 , +6018 , +6018 , +4947 , +4947 , +3468 , +3468 , +1581 , +1581 , +-306 , +-306 , +-2346 , +-2346 , +-4131 , +-4131 , +-5406 , +-5406 , +-6273 , +-6273 , +-6477 , +-6477 , +-6171 , +-6171 , +-5253 , +-5253 , +-3774 , +-3774 , +-2040 , +-2040 , +0 , +0 , +1887 , +1887 , +3774 , +3774 , +5253 , +5253 , +6171 , +6171 , +6477 , +6477 , +6027 , +6027 , +5194 , +5194 , +3969 , +3969 , +2254 , +2254 , +441 , +441 , +-1519 , +-1519 , +-3234 , +-3234 , +-4753 , +-4753 , +-5782 , +-5782 , +-6223 , +-6223 , +-6125 , +-6125 , +-5439 , +-5439 , +-4214 , +-4214 , +-2695 , +-2695 , +-784 , +-784 , +1078 , +1078 , +2940 , +2940 , +4459 , +4459 , +5586 , +5586 , +6174 , +6174 , +6223 , +6223 , +5586 , +5586 , +4557 , +4557 , +2940 , +2940 , +1225 , +1225 , +-784 , +-784 , +-2548 , +-2548 , +-4214 , +-4214 , +-5390 , +-5390 , +-6125 , +-6125 , +-6223 , +-6223 , +-5782 , +-5782 , +-4656 , +-4656 , +-3264 , +-3264 , +-1488 , +-1488 , +288 , +288 , +2208 , +2208 , +3792 , +3792 , +5088 , +5088 , +5856 , +5856 , +6096 , +6096 , +5856 , +5856 , +4944 , +4944 , +3552 , +3552 , +1920 , +1920 , +0 , +0 , +-1776 , +-1776 , +-3552 , +-3552 , +-4848 , +-4848 , +-5808 , +-5808 , +-6096 , +-6096 , +-5904 , +-5904 , +-5184 , +-5184 , +-3888 , +-3888 , +-2352 , +-2352 , +-432 , +-432 , +1488 , +1488 , +3168 , +3168 , +4656 , +4656 , +5616 , +5616 , +6096 , +6096 , +6048 , +6048 , +5328 , +5328 , +4224 , +4224 , +2585 , +2585 , +893 , +893 , +-1034 , +-1034 , +-2820 , +-2820 , +-4277 , +-4277 , +-5358 , +-5358 , +-5922 , +-5922 , +-5969 , +-5969 , +-5452 , +-5452 , +-4371 , +-4371 , +-2961 , +-2961 , +-1175 , +-1175 , +611 , +611 , +2444 , +2444 , +4042 , +4042 , +5170 , +5170 , +5875 , +5875 , +5969 , +5969 , +5546 , +5546 , +4653 , +4653 , +3196 , +3196 , +1598 , +1598 , +-282 , +-282 , +-2021 , +-2021 , +-3713 , +-3713 , +-4935 , +-4935 , +-5734 , +-5734 , +-5969 , +-5969 , +-5734 , +-5734 , +-4841 , +-4841 , +-3572 , +-3572 , +-1880 , +-1880 , +-138 , +-138 , +1702 , +1702 , +3266 , +3266 , +4646 , +4646 , +5474 , +5474 , +5842 , +5842 , +5658 , +5658 , +4968 , +4968 , +3726 , +3726 , +2254 , +2254 , +414 , +414 , +-1288 , +-1288 , +-3036 , +-3036 , +-4370 , +-4370 , +-5382 , +-5382 , +-5842 , +-5842 , +-5796 , +-5796 , +-5106 , +-5106 , +-4048 , +-4048 , +-2530 , +-2530 , +-874 , +-874 , +1012 , +1012 , +2668 , +2668 , +4186 , +4186 , +5198 , +5198 , +5796 , +5796 , +5842 , +5842 , +5336 , +5336 , +4370 , +4370 , +2898 , +2898 , +1150 , +1150 , +-598 , +-598 , +-2288 , +-2288 , +-3696 , +-3696 , +-4840 , +-4840 , +-5456 , +-5456 , +-5588 , +-5588 , +-5236 , +-5236 , +-4356 , +-4356 , +-3124 , +-3124 , +-1496 , +-1496 , +264 , +264 , +1892 , +1892 , +3476 , +3476 , +4620 , +4620 , +5368 , +5368 , +5588 , +5588 , +5368 , +5368 , +4620 , +4620 , +3344 , +3344 , +1892 , +1892 , +132 , +132 , +-1628 , +-1628 , +-3124 , +-3124 , +-4444 , +-4444 , +-5236 , +-5236 , +-5588 , +-5588 , +-5456 , +-5456 , +-4752 , +-4752 , +-3696 , +-3696 , +-2156 , +-2156 , +-572 , +-572 , +1232 , +1232 , +2904 , +2904 , +4085 , +4085 , +5031 , +5031 , +5461 , +5461 , +5418 , +5418 , +4859 , +4859 , +3784 , +3784 , +2494 , +2494 , +817 , +817 , +-817 , +-817 , +-2494 , +-2494 , +-3784 , +-3784 , +-4859 , +-4859 , +-5418 , +-5418 , +-5461 , +-5461 , +-4988 , +-4988 , +-4085 , +-4085 , +-2709 , +-2709 , +-1204 , +-1204 , +559 , +559 , +2107 , +2107 , +3612 , +3612 , +4644 , +4644 , +5332 , +5332 , +5461 , +5461 , +5117 , +5117 , +4257 , +4257 , +3053 , +3053 , +1462 , +1462 , +-129 , +-129 , +-1849 , +-1849 , +-3268 , +-3268 , +-4515 , +-4515 , +-5124 , +-5124 , +-5334 , +-5334 , +-5124 , +-5124 , +-4410 , +-4410 , +-3192 , +-3192 , +-1806 , +-1806 , +-126 , +-126 , +1428 , +1428 , +2982 , +2982 , +4158 , +4158 , +4998 , +4998 , +5334 , +5334 , +5208 , +5208 , +4620 , +4620 , +3528 , +3528 , +2058 , +2058 , +546 , +546 , +-1176 , +-1176 , +-2646 , +-2646 , +-3990 , +-3990 , +-4872 , +-4872 , +-5334 , +-5334 , +-5292 , +-5292 , +-4746 , +-4746 , +-3822 , +-3822 , +-2436 , +-2436 , +-798 , +-798 , +798 , +798 , +2436 , +2436 , +3696 , +3696 , +4746 , +4746 , +5292 , +5292 , +5080 , +5080 , +4680 , +4680 , +3800 , +3800 , +2640 , +2640 , +1120 , +1120 , +-520 , +-520 , +-1960 , +-1960 , +-3360 , +-3360 , +-4320 , +-4320 , +-4960 , +-4960 , +-5080 , +-5080 , +-4760 , +-4760 , +-4040 , +-4040 , +-2840 , +-2840 , +-1480 , +-1480 , +120 , +120 , +1600 , +1600 , +3040 , +3040 , +4200 , +4200 , +4880 , +4880 , +5080 , +5080 , +4880 , +4880 , +4200 , +4200 , +3160 , +3160 , +1720 , +1720 , +240 , +240 , +-1360 , +-1360 , +-2720 , +-2720 , +-3960 , +-3960 , +-4760 , +-4760 , +-5080 , +-5080 , +-4960 , +-4960 , +-4290 , +-4290 , +-3276 , +-3276 , +-2028 , +-2028 , +-507 , +-507 , +975 , +975 , +2457 , +2457 , +3627 , +3627 , +4524 , +4524 , +4953 , +4953 , +4914 , +4914 , +4407 , +4407 , +3549 , +3549 , +2262 , +2262 , +858 , +858 , +-741 , +-741 , +-2145 , +-2145 , +-3432 , +-3432 , +-4329 , +-4329 , +-4914 , +-4914 , +-4953 , +-4953 , +-4563 , +-4563 , +-3705 , +-3705 , +-2574 , +-2574 , +-1092 , +-1092 , +351 , +351 , +1911 , +1911 , +3159 , +3159 , +4212 , +4212 , +4797 , +4797 , +4953 , +4953 , +4719 , +4719 , +3939 , +3939 , +2698 , +2698 , +1406 , +1406 , +-114 , +-114 , +-1520 , +-1520 , +-2888 , +-2888 , +-3914 , +-3914 , +-4636 , +-4636 , +-4826 , +-4826 , +-4636 , +-4636 , +-4028 , +-4028 , +-3002 , +-3002 , +-1634 , +-1634 , +-228 , +-228 , +1292 , +1292 , +2584 , +2584 , +3762 , +3762 , +4484 , +4484 , +4826 , +4826 , +4750 , +4750 , +4180 , +4180 , +3268 , +3268 , +1976 , +1976 , +608 , +608 , +-950 , +-950 , +-2394 , +-2394 , +-3534 , +-3534 , +-4408 , +-4408 , +-4826 , +-4826 , +-4788 , +-4788 , +-4332 , +-4332 , +-3458 , +-3458 , +-2280 , +-2280 , +-814 , +-814 , +592 , +592 , +2035 , +2035 , +3256 , +3256 , +4107 , +4107 , +4662 , +4662 , +4699 , +4699 , +4329 , +4329 , +3589 , +3589 , +2442 , +2442 , +1147 , +1147 , +-333 , +-333 , +-1702 , +-1702 , +-2997 , +-2997 , +-3996 , +-3996 , +-4551 , +-4551 , +-4699 , +-4699 , +-4477 , +-4477 , +-3737 , +-3737 , +-2738 , +-2738 , +-1369 , +-1369 , +0 , +0 , +1480 , +1480 , +2738 , +2738 , +3811 , +3811 , +4477 , +4477 , +4699 , +4699 , +4514 , +4514 , +3922 , +3922 , +2923 , +2923 , +1702 , +1702 , +222 , +222 , +-1085 , +-1085 , +-2380 , +-2380 , +-3395 , +-3395 , +-4130 , +-4130 , +-4445 , +-4445 , +-4375 , +-4375 , +-3850 , +-3850 , +-3010 , +-3010 , +-1820 , +-1820 , +-560 , +-560 , +875 , +875 , +2100 , +2100 , +3255 , +3255 , +3990 , +3990 , +4445 , +4445 , +4445 , +4445 , +3990 , +3990 , +3185 , +3185 , +2100 , +2100 , +770 , +770 , +-560 , +-560 , +-1925 , +-1925 , +-3010 , +-3010 , +-3885 , +-3885 , +-4375 , +-4375 , +-4445 , +-4445 , +-4130 , +-4130 , +-3395 , +-3395 , +-2380 , +-2380 , +-1085 , +-1085 , +315 , +315 , +1610 , +1610 , +2754 , +2754 , +3604 , +3604 , +4182 , +4182 , +4318 , +4318 , +4114 , +4114 , +3502 , +3502 , +2516 , +2516 , +1360 , +1360 , +0 , +0 , +-1360 , +-1360 , +-2516 , +-2516 , +-3502 , +-3502 , +-4114 , +-4114 , +-4318 , +-4318 , +-4182 , +-4182 , +-3604 , +-3604 , +-2754 , +-2754 , +-1564 , +-1564 , +-306 , +-306 , +1054 , +1054 , +2312 , +2312 , +3298 , +3298 , +4012 , +4012 , +4318 , +4318 , +4250 , +4250 , +3774 , +3774 , +2924 , +2924 , +1870 , +1870 , +544 , +544 , +-748 , +-748 , +-2040 , +-2040 , +-3162 , +-3162 , +-3762 , +-3762 , +-4191 , +-4191 , +-4191 , +-4191 , +-3762 , +-3762 , +-3069 , +-3069 , +-1980 , +-1980 , +-825 , +-825 , +528 , +528 , +1716 , +1716 , +2838 , +2838 , +3630 , +3630 , +4125 , +4125 , +4191 , +4191 , +3894 , +3894 , +3201 , +3201 , +2244 , +2244 , +1023 , +1023 , +-198 , +-198 , +-1518 , +-1518 , +-2607 , +-2607 , +-3498 , +-3498 , +-4026 , +-4026 , +-4191 , +-4191 , +-3993 , +-3993 , +-3399 , +-3399 , +-2442 , +-2442 , +-1320 , +-1320 , +0 , +0 , +1221 , +1221 , +2442 , +2442 , +3333 , +3333 , +3993 , +3993 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +2368 , +2368 , +4736 , +4736 , +6464 , +6464 , +7744 , +7744 , +8128 , +8128 , +7872 , +7872 , +6912 , +6912 , +5184 , +5184 , +3136 , +3136 , +576 , +576 , +-1792 , +-1792 , +-4224 , +-4224 , +-6208 , +-6208 , +-7488 , +-7488 , +-8128 , +-8128 , +-8064 , +-8064 , +-7104 , +-7104 , +-5632 , +-5632 , +-3520 , +-3520 , +-1216 , +-1216 , +1408 , +1408 , +3712 , +3712 , +5824 , +5824 , +7296 , +7296 , +8064 , +8064 , +8128 , +8128 , +7424 , +7424 , +5952 , +5952 , +4032 , +4032 , +1600 , +1600 , +-832 , +-832 , +-3328 , +-3328 , +-5208 , +-5208 , +-6820 , +-6820 , +-7750 , +-7750 , +-7874 , +-7874 , +-7316 , +-7316 , +-6138 , +-6138 , +-4216 , +-4216 , +-2108 , +-2108 , +372 , +372 , +2666 , +2666 , +4898 , +4898 , +6510 , +6510 , +7564 , +7564 , +7874 , +7874 , +7564 , +7564 , +6386 , +6386 , +4712 , +4712 , +2480 , +2480 , +186 , +186 , +-2294 , +-2294 , +-4402 , +-4402 , +-6262 , +-6262 , +-7378 , +-7378 , +-7874 , +-7874 , +-7688 , +-7688 , +-6696 , +-6696 , +-5022 , +-5022 , +-3038 , +-3038 , +-558 , +-558 , +1736 , +1736 , +4092 , +4092 , +5890 , +5890 , +7137 , +7137 , +7747 , +7747 , +7686 , +7686 , +6893 , +6893 , +5368 , +5368 , +3355 , +3355 , +1159 , +1159 , +-1342 , +-1342 , +-3538 , +-3538 , +-5551 , +-5551 , +-6893 , +-6893 , +-7686 , +-7686 , +-7747 , +-7747 , +-7076 , +-7076 , +-5795 , +-5795 , +-3843 , +-3843 , +-1708 , +-1708 , +793 , +793 , +3172 , +3172 , +5124 , +5124 , +6710 , +6710 , +7564 , +7564 , +7747 , +7747 , +7259 , +7259 , +6039 , +6039 , +4331 , +4331 , +2074 , +2074 , +-183 , +-183 , +-2623 , +-2623 , +-4819 , +-4819 , +-6405 , +-6405 , +-7442 , +-7442 , +-7620 , +-7620 , +-7320 , +-7320 , +-6300 , +-6300 , +-4560 , +-4560 , +-2580 , +-2580 , +-180 , +-180 , +2040 , +2040 , +4260 , +4260 , +6060 , +6060 , +7140 , +7140 , +7620 , +7620 , +7440 , +7440 , +6480 , +6480 , +5040 , +5040 , +2940 , +2940 , +780 , +780 , +-1680 , +-1680 , +-3780 , +-3780 , +-5700 , +-5700 , +-6960 , +-6960 , +-7620 , +-7620 , +-7560 , +-7560 , +-6780 , +-6780 , +-5280 , +-5280 , +-3480 , +-3480 , +-1140 , +-1140 , +1140 , +1140 , +3480 , +3480 , +5280 , +5280 , +6780 , +6780 , +7560 , +7560 , +7620 , +7620 , +6728 , +6728 , +5510 , +5510 , +3654 , +3654 , +1624 , +1624 , +-754 , +-754 , +-2842 , +-2842 , +-4872 , +-4872 , +-6264 , +-6264 , +-7192 , +-7192 , +-7366 , +-7366 , +-6902 , +-6902 , +-5742 , +-5742 , +-4118 , +-4118 , +-1972 , +-1972 , +174 , +174 , +2494 , +2494 , +4408 , +4408 , +6090 , +6090 , +7076 , +7076 , +7366 , +7366 , +7076 , +7076 , +6090 , +6090 , +4582 , +4582 , +2494 , +2494 , +174 , +174 , +-1972 , +-1972 , +-4118 , +-4118 , +-5742 , +-5742 , +-6902 , +-6902 , +-7366 , +-7366 , +-7192 , +-7192 , +-6380 , +-6380 , +-4788 , +-4788 , +-2964 , +-2964 , +-741 , +-741 , +1596 , +1596 , +3591 , +3591 , +5415 , +5415 , +6612 , +6612 , +7239 , +7239 , +7182 , +7182 , +6441 , +6441 , +5187 , +5187 , +3306 , +3306 , +1254 , +1254 , +-1083 , +-1083 , +-3306 , +-3306 , +-5016 , +-5016 , +-6441 , +-6441 , +-7182 , +-7182 , +-7239 , +-7239 , +-6669 , +-6669 , +-5415 , +-5415 , +-3762 , +-3762 , +-1596 , +-1596 , +513 , +513 , +2793 , +2793 , +4617 , +4617 , +6156 , +6156 , +7068 , +7068 , +7239 , +7239 , +6783 , +6783 , +5757 , +5757 , +4047 , +4047 , +2072 , +2072 , +-168 , +-168 , +-2240 , +-2240 , +-4256 , +-4256 , +-5768 , +-5768 , +-6832 , +-6832 , +-7112 , +-7112 , +-6832 , +-6832 , +-5880 , +-5880 , +-4424 , +-4424 , +-2408 , +-2408 , +-336 , +-336 , +1904 , +1904 , +3808 , +3808 , +5544 , +5544 , +6608 , +6608 , +7112 , +7112 , +6944 , +6944 , +6160 , +6160 , +4704 , +4704 , +2912 , +2912 , +728 , +728 , +-1400 , +-1400 , +-3528 , +-3528 , +-5208 , +-5208 , +-6496 , +-6496 , +-7112 , +-7112 , +-7056 , +-7056 , +-6384 , +-6384 , +-5096 , +-5096 , +-3248 , +-3248 , +-1232 , +-1232 , +1045 , +1045 , +3025 , +3025 , +4840 , +4840 , +6105 , +6105 , +6930 , +6930 , +6985 , +6985 , +6435 , +6435 , +5335 , +5335 , +3630 , +3630 , +1540 , +1540 , +-495 , +-495 , +-2695 , +-2695 , +-4455 , +-4455 , +-5940 , +-5940 , +-6765 , +-6765 , +-6985 , +-6985 , +-6655 , +-6655 , +-5555 , +-5555 , +-4070 , +-4070 , +-2035 , +-2035 , +165 , +165 , +2200 , +2200 , +4180 , +4180 , +5665 , +5665 , +6710 , +6710 , +6985 , +6985 , +6710 , +6710 , +5830 , +5830 , +4345 , +4345 , +2530 , +2530 , +330 , +330 , +-1870 , +-1870 , +-3604 , +-3604 , +-5247 , +-5247 , +-6254 , +-6254 , +-6731 , +-6731 , +-6625 , +-6625 , +-5830 , +-5830 , +-4558 , +-4558 , +-2756 , +-2756 , +-848 , +-848 , +1325 , +1325 , +3180 , +3180 , +4929 , +4929 , +6148 , +6148 , +6731 , +6731 , +6678 , +6678 , +6042 , +6042 , +4823 , +4823 , +3180 , +3180 , +1166 , +1166 , +-848 , +-848 , +-2915 , +-2915 , +-4558 , +-4558 , +-5883 , +-5883 , +-6678 , +-6678 , +-6731 , +-6731 , +-6201 , +-6201 , +-5141 , +-5141 , +-3498 , +-3498 , +-1643 , +-1643 , +477 , +477 , +2438 , +2438 , +4293 , +4293 , +5512 , +5512 , +6396 , +6396 , +6604 , +6604 , +6292 , +6292 , +5252 , +5252 , +3848 , +3848 , +1924 , +1924 , +0 , +0 , +-2080 , +-2080 , +-3848 , +-3848 , +-5356 , +-5356 , +-6292 , +-6292 , +-6604 , +-6604 , +-6396 , +-6396 , +-5512 , +-5512 , +-4108 , +-4108 , +-2392 , +-2392 , +-312 , +-312 , +1612 , +1612 , +3536 , +3536 , +5044 , +5044 , +6136 , +6136 , +6604 , +6604 , +6500 , +6500 , +5772 , +5772 , +4472 , +4472 , +2704 , +2704 , +832 , +832 , +-1300 , +-1300 , +-3120 , +-3120 , +-4836 , +-4836 , +-5928 , +-5928 , +-6477 , +-6477 , +-6477 , +-6477 , +-5814 , +-5814 , +-4743 , +-4743 , +-3060 , +-3060 , +-1122 , +-1122 , +816 , +816 , +2805 , +2805 , +4386 , +4386 , +5661 , +5661 , +6375 , +6375 , +6477 , +6477 , +6018 , +6018 , +4947 , +4947 , +3468 , +3468 , +1581 , +1581 , +-306 , +-306 , +-2346 , +-2346 , +-4131 , +-4131 , +-5406 , +-5406 , +-6273 , +-6273 , +-6477 , +-6477 , +-6171 , +-6171 , +-5253 , +-5253 , +-3774 , +-3774 , +-2040 , +-2040 , +0 , +0 , +1887 , +1887 , +3774 , +3774 , +5253 , +5253 , +6171 , +6171 , +6477 , +6477 , +6027 , +6027 , +5194 , +5194 , +3969 , +3969 , +2254 , +2254 , +441 , +441 , +-1519 , +-1519 , +-3234 , +-3234 , +-4753 , +-4753 , +-5782 , +-5782 , +-6223 , +-6223 , +-6125 , +-6125 , +-5439 , +-5439 , +-4214 , +-4214 , +-2695 , +-2695 , +-784 , +-784 , +1078 , +1078 , +2940 , +2940 , +4459 , +4459 , +5586 , +5586 , +6174 , +6174 , +6223 , +6223 , +5586 , +5586 , +4557 , +4557 , +2940 , +2940 , +1225 , +1225 , +-784 , +-784 , +-2548 , +-2548 , +-4214 , +-4214 , +-5390 , +-5390 , +-6125 , +-6125 , +-6223 , +-6223 , +-5782 , +-5782 , +-4656 , +-4656 , +-3264 , +-3264 , +-1488 , +-1488 , +288 , +288 , +2208 , +2208 , +3792 , +3792 , +5088 , +5088 , +5856 , +5856 , +6096 , +6096 , +5856 , +5856 , +4944 , +4944 , +3552 , +3552 , +1920 , +1920 , +0 , +0 , +-1776 , +-1776 , +-3552 , +-3552 , +-4848 , +-4848 , +-5808 , +-5808 , +-6096 , +-6096 , +-5904 , +-5904 , +-5184 , +-5184 , +-3888 , +-3888 , +-2352 , +-2352 , +-432 , +-432 , +1488 , +1488 , +3168 , +3168 , +4656 , +4656 , +5616 , +5616 , +6096 , +6096 , +6048 , +6048 , +5328 , +5328 , +4224 , +4224 , +2585 , +2585 , +893 , +893 , +-1034 , +-1034 , +-2820 , +-2820 , +-4277 , +-4277 , +-5358 , +-5358 , +-5922 , +-5922 , +-5969 , +-5969 , +-5452 , +-5452 , +-4371 , +-4371 , +-2961 , +-2961 , +-1175 , +-1175 , +611 , +611 , +2444 , +2444 , +4042 , +4042 , +5170 , +5170 , +5875 , +5875 , +5969 , +5969 , +5546 , +5546 , +4653 , +4653 , +3196 , +3196 , +1598 , +1598 , +-282 , +-282 , +-2021 , +-2021 , +-3713 , +-3713 , +-4935 , +-4935 , +-5734 , +-5734 , +-5969 , +-5969 , +-5734 , +-5734 , +-4841 , +-4841 , +-3572 , +-3572 , +-1880 , +-1880 , +-138 , +-138 , +1702 , +1702 , +3266 , +3266 , +4646 , +4646 , +5474 , +5474 , +5842 , +5842 , +5658 , +5658 , +4968 , +4968 , +3726 , +3726 , +2254 , +2254 , +414 , +414 , +-1288 , +-1288 , +-3036 , +-3036 , +-4370 , +-4370 , +-5382 , +-5382 , +-5842 , +-5842 , +-5796 , +-5796 , +-5106 , +-5106 , +-4048 , +-4048 , +-2530 , +-2530 , +-874 , +-874 , +1012 , +1012 , +2668 , +2668 , +4186 , +4186 , +5198 , +5198 , +5796 , +5796 , +5842 , +5842 , +5336 , +5336 , +4370 , +4370 , +2898 , +2898 , +1150 , +1150 , +-598 , +-598 , +-2288 , +-2288 , +-3696 , +-3696 , +-4840 , +-4840 , +-5456 , +-5456 , +-5588 , +-5588 , +-5236 , +-5236 , +-4356 , +-4356 , +-3124 , +-3124 , +-1496 , +-1496 , +264 , +264 , +1892 , +1892 , +3476 , +3476 , +4620 , +4620 , +5368 , +5368 , +5588 , +5588 , +5368 , +5368 , +4620 , +4620 , +3344 , +3344 , +1892 , +1892 , +132 , +132 , +-1628 , +-1628 , +-3124 , +-3124 , +-4444 , +-4444 , +-5236 , +-5236 , +-5588 , +-5588 , +-5456 , +-5456 , +-4752 , +-4752 , +-3696 , +-3696 , +-2156 , +-2156 , +-572 , +-572 , +1232 , +1232 , +2904 , +2904 , +4085 , +4085 , +5031 , +5031 , +5461 , +5461 , +5418 , +5418 , +4859 , +4859 , +3784 , +3784 , +2494 , +2494 , +817 , +817 , +-817 , +-817 , +-2494 , +-2494 , +-3784 , +-3784 , +-4859 , +-4859 , +-5418 , +-5418 , +-5461 , +-5461 , +-4988 , +-4988 , +-4085 , +-4085 , +-2709 , +-2709 , +-1204 , +-1204 , +559 , +559 , +2107 , +2107 , +3612 , +3612 , +4644 , +4644 , +5332 , +5332 , +5461 , +5461 , +5117 , +5117 , +4257 , +4257 , +3053 , +3053 , +1462 , +1462 , +-129 , +-129 , +-1849 , +-1849 , +-3268 , +-3268 , +-4515 , +-4515 , +-5124 , +-5124 , +-5334 , +-5334 , +-5124 , +-5124 , +-4410 , +-4410 , +-3192 , +-3192 , +-1806 , +-1806 , +-126 , +-126 , +1428 , +1428 , +2982 , +2982 , +4158 , +4158 , +4998 , +4998 , +5334 , +5334 , +5208 , +5208 , +4620 , +4620 , +3528 , +3528 , +2058 , +2058 , +546 , +546 , +-1176 , +-1176 , +-2646 , +-2646 , +-3990 , +-3990 , +-4872 , +-4872 , +-5334 , +-5334 , +-5292 , +-5292 , +-4746 , +-4746 , +-3822 , +-3822 , +-2436 , +-2436 , +-798 , +-798 , +798 , +798 , +2436 , +2436 , +3696 , +3696 , +4746 , +4746 , +5292 , +5292 , +5080 , +5080 , +4680 , +4680 , +3800 , +3800 , +2640 , +2640 , +1120 , +1120 , +-520 , +-520 , +-1960 , +-1960 , +-3360 , +-3360 , +-4320 , +-4320 , +-4960 , +-4960 , +-5080 , +-5080 , +-4760 , +-4760 , +-4040 , +-4040 , +-2840 , +-2840 , +-1480 , +-1480 , +120 , +120 , +1600 , +1600 , +3040 , +3040 , +4200 , +4200 , +4880 , +4880 , +5080 , +5080 , +4880 , +4880 , +4200 , +4200 , +3160 , +3160 , +1720 , +1720 , +240 , +240 , +-1360 , +-1360 , +-2720 , +-2720 , +-3960 , +-3960 , +-4760 , +-4760 , +-5080 , +-5080 , +-4960 , +-4960 , +-4290 , +-4290 , +-3276 , +-3276 , +-2028 , +-2028 , +-507 , +-507 , +975 , +975 , +2457 , +2457 , +3627 , +3627 , +4524 , +4524 , +4953 , +4953 , +4914 , +4914 , +4407 , +4407 , +3549 , +3549 , +2262 , +2262 , +858 , +858 , +-741 , +-741 , +-2145 , +-2145 , +-3432 , +-3432 , +-4329 , +-4329 , +-4914 , +-4914 , +-4953 , +-4953 , +-4563 , +-4563 , +-3705 , +-3705 , +-2574 , +-2574 , +-1092 , +-1092 , +351 , +351 , +1911 , +1911 , +3159 , +3159 , +4212 , +4212 , +4797 , +4797 , +4953 , +4953 , +4719 , +4719 , +3939 , +3939 , +2698 , +2698 , +1406 , +1406 , +-114 , +-114 , +-1520 , +-1520 , +-2888 , +-2888 , +-3914 , +-3914 , +-4636 , +-4636 , +-4826 , +-4826 , +-4636 , +-4636 , +-4028 , +-4028 , +-3002 , +-3002 , +-1634 , +-1634 , +-228 , +-228 , +1292 , +1292 , +2584 , +2584 , +3762 , +3762 , +4484 , +4484 , +4826 , +4826 , +4750 , +4750 , +4180 , +4180 , +3268 , +3268 , +1976 , +1976 , +608 , +608 , +-950 , +-950 , +-2394 , +-2394 , +-3534 , +-3534 , +-4408 , +-4408 , +-4826 , +-4826 , +-4788 , +-4788 , +-4332 , +-4332 , +-3458 , +-3458 , +-2280 , +-2280 , +-814 , +-814 , +592 , +592 , +2035 , +2035 , +3256 , +3256 , +4107 , +4107 , +4662 , +4662 , +4699 , +4699 , +4329 , +4329 , +3589 , +3589 , +2442 , +2442 , +1147 , +1147 , +-333 , +-333 , +-1702 , +-1702 , +-2997 , +-2997 , +-3996 , +-3996 , +-4551 , +-4551 , +-4699 , +-4699 , +-4477 , +-4477 , +-3737 , +-3737 , +-2738 , +-2738 , +-1369 , +-1369 , +0 , +0 , +1480 , +1480 , +2738 , +2738 , +3811 , +3811 , +4477 , +4477 , +4699 , +4699 , +4514 , +4514 , +3922 , +3922 , +2923 , +2923 , +1702 , +1702 , +222 , +222 , +-1085 , +-1085 , +-2380 , +-2380 , +-3395 , +-3395 , +-4130 , +-4130 , +-4445 , +-4445 , +-4375 , +-4375 , +-3850 , +-3850 , +-3010 , +-3010 , +-1820 , +-1820 , +-560 , +-560 , +875 , +875 , +2100 , +2100 , +3255 , +3255 , +3990 , +3990 , +4445 , +4445 , +4445 , +4445 , +3990 , +3990 , +3185 , +3185 , +2100 , +2100 , +770 , +770 , +-560 , +-560 , +-1925 , +-1925 , +-3010 , +-3010 , +-3885 , +-3885 , +-4375 , +-4375 , +-4445 , +-4445 , +-4130 , +-4130 , +-3395 , +-3395 , +-2380 , +-2380 , +-1085 , +-1085 , +315 , +315 , +1610 , +1610 , +2754 , +2754 , +3604 , +3604 , +4182 , +4182 , +4318 , +4318 , +4114 , +4114 , +3502 , +3502 , +2516 , +2516 , +1360 , +1360 , +0 , +0 , +-1360 , +-1360 , +-2516 , +-2516 , +-3502 , +-3502 , +-4114 , +-4114 , +-4318 , +-4318 , +-4182 , +-4182 , +-3604 , +-3604 , +-2754 , +-2754 , +-1564 , +-1564 , +-306 , +-306 , +1054 , +1054 , +2312 , +2312 , +3298 , +3298 , +4012 , +4012 , +4318 , +4318 , +4250 , +4250 , +3774 , +3774 , +2924 , +2924 , +1870 , +1870 , +544 , +544 , +-748 , +-748 , +-2040 , +-2040 , +-3162 , +-3162 , \ No newline at end of file diff --git a/config/_default_cfg_src_/slave_code.S b/config/_default_cfg_src_/slave_code.S new file mode 100644 index 0000000..b0882be --- /dev/null +++ b/config/_default_cfg_src_/slave_code.S @@ -0,0 +1,27 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#define TO_STRING_A(s) # s +#define TO_STRING(s) TO_STRING_A(s) + +.globl __slave_code_start +.globl __slave_code_end +.section .slave_code_flash_rodata, "a", %progbits +.balign 4 + +__slave_code_start: + .incbin TO_STRING(SLAVE_BIN_NAME) +__slave_code_end: + diff --git a/config/_default_cfg_src_/tgt_hardware.c b/config/_default_cfg_src_/tgt_hardware.c new file mode 100644 index 0000000..d5419d1 --- /dev/null +++ b/config/_default_cfg_src_/tgt_hardware.c @@ -0,0 +1,99 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "tgt_hardware.h" + +const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_hw_pinmux_pwl[CFG_HW_PLW_NUM] = { +}; + +//adckey define +const uint16_t CFG_HW_ADCKEY_MAP_TABLE[CFG_HW_ADCKEY_NUMBER] = { + HAL_KEY_CODE_FN9,HAL_KEY_CODE_FN8,HAL_KEY_CODE_FN7, + HAL_KEY_CODE_FN6,HAL_KEY_CODE_FN5,HAL_KEY_CODE_FN4, + HAL_KEY_CODE_FN3,HAL_KEY_CODE_FN2,HAL_KEY_CODE_FN1 +}; + +//gpiokey define +const struct HAL_KEY_GPIOKEY_CFG_T cfg_hw_gpio_key_cfg[CFG_HW_GPIOKEY_NUM] = { +}; + +//bt config +const char *BT_LOCAL_NAME = TO_STRING(BT_DEV_NAME) "\0"; +const char *BLE_DEFAULT_NAME = "BES_BLE"; + +uint8_t ble_addr[6] = { +#ifdef BLE_DEV_ADDR + BLE_DEV_ADDR +#else + 0xBE,0x99,0x34,0x45,0x56,0x67 +#endif +}; +uint8_t bt_addr[6] = { +#ifdef BT_DEV_ADDR + BT_DEV_ADDR +#else + 0x1e,0x57,0x34,0x45,0x56,0x67 +#endif +}; + +//audio config +//freq bands range {[0k:2.5K], [2.5k:5K], [5k:7.5K], [7.5K:10K], [10K:12.5K], [12.5K:15K], [15K:17.5K], [17.5K:20K]} +//gain range -12~+12 +const int8_t cfg_hw_aud_eq_band_settings[CFG_HW_AUD_EQ_NUM_BANDS] = {0, 0, 0, 0, 0, 0, 0, 0}; + +#define TX_PA_GAIN CODEC_TX_PA_GAIN_DEFAULT + +const struct CODEC_DAC_VOL_T codec_dac_vol[TGT_VOLUME_LEVEL_QTY] = { + {TX_PA_GAIN,0x03,-11}, + {TX_PA_GAIN,0x03,-99}, + {TX_PA_GAIN,0x03,-45}, + {TX_PA_GAIN,0x03,-42}, + {TX_PA_GAIN,0x03,-39}, + {TX_PA_GAIN,0x03,-36}, + {TX_PA_GAIN,0x03,-33}, + {TX_PA_GAIN,0x03,-30}, + {TX_PA_GAIN,0x03,-27}, + {TX_PA_GAIN,0x03,-24}, + {TX_PA_GAIN,0x03,-21}, + {TX_PA_GAIN,0x03,-18}, + {TX_PA_GAIN,0x03,-15}, + {TX_PA_GAIN,0x03,-12}, + {TX_PA_GAIN,0x03, -9}, + {TX_PA_GAIN,0x03, -6}, + {TX_PA_GAIN,0x03, -3}, + {TX_PA_GAIN,0x03, 0}, //0dBm +}; + +#define CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV (AUD_CHANNEL_MAP_CH0 | AUD_VMIC_MAP_VMIC1) +#define CFG_HW_AUD_INPUT_PATH_LINEIN_DEV (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1) +#define CFG_HW_AUD_INPUT_PATH_VADMIC_DEV (AUD_CHANNEL_MAP_CH4 | AUD_VMIC_MAP_VMIC1) +const struct AUD_IO_PATH_CFG_T cfg_audio_input_path_cfg[CFG_HW_AUD_INPUT_PATH_NUM] = { + { AUD_INPUT_PATH_MAINMIC, CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV, }, + { AUD_INPUT_PATH_LINEIN, CFG_HW_AUD_INPUT_PATH_LINEIN_DEV, }, + { AUD_INPUT_PATH_VADMIC, CFG_HW_AUD_INPUT_PATH_VADMIC_DEV, }, +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_enable_cfg = { + HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_detecter_cfg = { + HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_indicator_cfg = { + HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; + diff --git a/config/_default_cfg_src_/tgt_hardware.h b/config/_default_cfg_src_/tgt_hardware.h new file mode 100644 index 0000000..f5d336e --- /dev/null +++ b/config/_default_cfg_src_/tgt_hardware.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __TGT_HARDWARE__ +#define __TGT_HARDWARE__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_iomux.h" +#include "hal_gpio.h" +#include "hal_key.h" +#include "hal_aud.h" + +//pwl +#define CFG_HW_PLW_NUM (0) +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_hw_pinmux_pwl[CFG_HW_PLW_NUM]; + +//adckey define +#define CFG_HW_ADCKEY_NUMBER 9 +#define CFG_HW_ADCKEY_BASE 0 +#define CFG_HW_ADCKEY_ADC_MAXVOLT 1000 +#define CFG_HW_ADCKEY_ADC_MINVOLT 0 +#define CFG_HW_ADCKEY_ADC_KEYVOLT_BASE 130 +extern const uint16_t CFG_HW_ADCKEY_MAP_TABLE[CFG_HW_ADCKEY_NUMBER]; + +#define BTA_AV_CO_SBC_MAX_BITPOOL 53 + +//gpiokey define +#define CFG_HW_GPIOKEY_NUM (0) +extern const struct HAL_KEY_GPIOKEY_CFG_T cfg_hw_gpio_key_cfg[CFG_HW_GPIOKEY_NUM]; + +// audio codec +#define CFG_HW_AUD_INPUT_PATH_NUM 3 +extern const struct AUD_IO_PATH_CFG_T cfg_audio_input_path_cfg[CFG_HW_AUD_INPUT_PATH_NUM]; + +#define CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1) + +#define CFG_HW_AUD_SIDETONE_MIC_DEV (AUD_CHANNEL_MAP_CH0) +#define CFG_HW_AUD_SIDETONE_GAIN_DBVAL (-20) + +//bt config +extern const char *BT_LOCAL_NAME; +extern const char *BLE_DEFAULT_NAME; +extern uint8_t ble_addr[6]; +extern uint8_t bt_addr[6]; + +#define CODEC_SADC_VOL (7) + +extern const struct CODEC_DAC_VOL_T codec_dac_vol[TGT_VOLUME_LEVEL_QTY]; + +//range -12~+12 +#define CFG_HW_AUD_EQ_NUM_BANDS (8) +extern const int8_t cfg_aud_eq_sbc_band_settings[CFG_HW_AUD_EQ_NUM_BANDS]; +#define CFG_AUD_EQ_IIR_NUM_BANDS (4) + +//battery info +#define APP_BATTERY_MIN_MV (3200) +#define APP_BATTERY_PD_MV (3100) + +#define APP_BATTERY_MAX_MV (4200) + +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_enable_cfg; +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_detecter_cfg; +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_indicator_cfg; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/config/best2300p_ibrt/target.mk b/config/best2300p_ibrt/target.mk new file mode 100644 index 0000000..d97c8dd --- /dev/null +++ b/config/best2300p_ibrt/target.mk @@ -0,0 +1,410 @@ +CHIP ?= best2300p + +DEBUG ?= 1 + +FPGA ?= 0 + +MBED ?= 0 + +RTOS ?= 1 + +#KERNEL ?= FREERTOS + + +LIBC_ROM ?= 1 + +export USER_SECURE_BOOT ?= 0 +# enable:1 +# disable:0 + +WATCHER_DOG ?= 1 + +DEBUG_PORT ?= 1 +# 0: usb +# 1: uart0 +# 2: uart1 + +FLASH_CHIP ?= ALL +# GD25Q80C +# GD25Q32C +# ALL + +export NO_TRACE_TIME_STAMP ?=1 + +export FORCE_SIGNALINGMODE ?= 0 + +export FORCE_NOSIGNALINGMODE ?= 0 + +export FORCE_SCO_MAX_RETX ?= 0 + +export FA_RX_GAIN_CTRL ?= 1 + +export BT_FA_ECC ?= 0 + +export CONTROLLER_DUMP_ENABLE ?= 0 + +export CONTROLLER_MEM_LOG_ENABLE ?= 0 + +export INTERSYS_DEBUG ?= 1 + +export PROFILE_DEBUG ?= 0 + +export BTDUMP_ENABLE ?= 0 + +export BT_DEBUG_TPORTS ?= 0 + +TPORTS_KEY_COEXIST ?= 0 + +export SNIFF_MODE_CHECK ?= 0 + +AUDIO_OUTPUT_MONO ?= 0 + +AUDIO_OUTPUT_DIFF ?= 0 + +HW_FIR_EQ_PROCESS ?= 0 + +SW_IIR_EQ_PROCESS ?= 0 + +HW_DAC_IIR_EQ_PROCESS ?= 1 + +HW_IIR_EQ_PROCESS ?= 0 + +HW_DC_FILTER_WITH_IIR ?= 0 + +AUDIO_DRC ?= 0 + +AUDIO_DRC2 ?= 0 + +PC_CMD_UART ?= 0 + +AUDIO_SECTION_ENABLE ?= 0 + +AUDIO_RESAMPLE ?= 1 + +RESAMPLE_ANY_SAMPLE_RATE ?= 1 + +OSC_26M_X4_AUD2BB ?= 1 + +AUDIO_OUTPUT_VOLUME_DEFAULT ?= 12 +# range:1~16 + +AUDIO_INPUT_CAPLESSMODE ?= 0 + +AUDIO_INPUT_LARGEGAIN ?= 0 + +AUDIO_CODEC_ASYNC_CLOSE ?= 0 + +AUDIO_SCO_BTPCM_CHANNEL ?= 1 + +export A2DP_CP_ACCEL ?= 1 + +export SCO_CP_ACCEL ?= 1 + +export SCO_TRACE_CP_ACCEL ?= 0 + +# For TWS SCO DMA snapshot and low delay +export PCM_FAST_MODE ?= 1 + +export CVSD_BYPASS ?= 1 + +export LOW_DELAY_SCO ?= 0 + +SPEECH_TX_DC_FILTER ?= 1 + +SPEECH_TX_AEC2FLOAT ?= 1 + +SPEECH_TX_NS3 ?= 0 + +SPEECH_TX_2MIC_NS2 ?= 0 + +SPEECH_TX_COMPEXP ?= 1 + +SPEECH_TX_EQ ?= 0 + +SPEECH_TX_POST_GAIN ?= 0 + +SPEECH_RX_NS2FLOAT ?= 0 + +SPEECH_RX_EQ ?= 0 + +SPEECH_RX_POST_GAIN ?= 0 + +LARGE_RAM ?= 1 + +HSP_ENABLE ?= 0 + +HFP_1_6_ENABLE ?= 1 + +MSBC_PLC_ENABLE ?= 1 + +MSBC_PLC_ENCODER ?= 1 + +MSBC_16K_SAMPLE_RATE ?= 1 + +SBC_FUNC_IN_ROM ?= 0 + +ROM_UTILS_ON ?= 0 + +APP_LINEIN_A2DP_SOURCE ?= 0 + +APP_I2S_A2DP_SOURCE ?= 0 + +VOICE_PROMPT ?= 1 + +export THROUGH_PUT ?= 0 + +#### Google related feature #### +# the overall google service switch +# currently, google service includes BISTO and GFPS +export GOOGLE_SERVICE_ENABLE ?= 0 + +# BISTO is a GVA service on Bluetooth audio device +# BISTO is an isolated service relative to GFPS +export BISTO_ENABLE ?= 0 + +# macro switch for reduced_guesture +export REDUCED_GUESTURE_ENABLE ?= 0 + +# GSOUND_HOTWORD is a hotword library running on Bluetooth audio device +# GSOUND_HOTWORD is a subset of BISTO +export GSOUND_HOTWORD_ENABLE ?= 0 + +# this is a subset choice for gsound hotword +export GSOUND_HOTWORD_EXTERNAL ?= 0 + +# GFPS is google fastpair service +# GFPS is an isolated service relative to BISTO +export GFPS_ENABLE ?= 0 +#### Google related feature #### + +BLE ?= 0 + +TOTA ?= 0 + +GATT_OVER_BR_EDR ?= 0 + +OTA_ENABLE ?= 1 + +TILE_DATAPATH_ENABLED ?= 0 + +CUSTOM_INFORMATION_TILE_ENABLE ?= 0 + +INTERCONNECTION ?= 0 + +INTERACTION ?= 0 + +INTERACTION_FASTPAIR ?= 0 + +BT_ONE_BRING_TWO ?= 0 + +DSD_SUPPORT ?= 0 + +A2DP_EQ_24BIT ?= 1 + +A2DP_AAC_ON ?= 1 + +A2DP_SCALABLE_ON ?= 0 + +A2DP_LHDC_ON ?= 0 +ifeq ($(A2DP_LHDC_ON),1) +A2DP_LHDC_V3 ?= 1 +A2DP_LHDC_LARC ?= 1 +export FLASH_UNIQUE_ID ?= 1 +endif + +A2DP_LDAC_ON ?= 0 + +export TX_RX_PCM_MASK ?= 0 + +A2DP_SCALABLE_ON ?= 0 + +FACTORY_MODE ?= 1 + +ENGINEER_MODE ?= 1 + +ULTRA_LOW_POWER ?= 1 + +DAC_CLASSG_ENABLE ?= 1 + +NO_SLEEP ?= 0 + +CORE_DUMP ?= 1 + +CORE_DUMP_TO_FLASH ?= 0 + +ENHANCED_STACK ?= 1 + +export SYNC_BT_CTLR_PROFILE ?= 0 + +export A2DP_AVDTP_CP ?= 0 + +export A2DP_DECODER_VER := 2 + +export IBRT ?= 1 + +export IBRT_SEARCH_UI ?= 1 + +export BES_AUD ?= 1 + +export POWER_MODE ?= DIG_DCDC + +export BT_RF_PREFER ?= 2M + +export SPEECH_CODEC ?= 1 + +export TWS_PROMPT_SYNC ?= 0 +export MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED ?= 0 +export IOS_MFI ?= 0 + +export FLASH_SIZE ?= 0x400000 +export FLASH_SUSPEND ?= 1 + +ifeq ($(DSD_SUPPORT),1) +export BTUSB_AUDIO_MODE ?= 1 +export AUDIO_INPUT_MONO ?= 1 +export USB_ISO ?= 1 +export USB_AUDIO_DYN_CFG ?= 1 +export DELAY_STREAM_OPEN ?= 0 +export KEEP_SAME_LATENCY ?= 1 +export HW_FIR_DSD_PROCESS ?= 1 +ifeq ($(HW_FIR_DSD_PROCESS),1) +ifeq ($(CHIP),best2300) +export HW_FIR_DSD_BUF_MID_ADDR ?= 0x200A0000 +export DATA_BUF_START ?= 0x20040000 +endif +endif +export USB_AUDIO_UAC2 ?= 1 +export USB_HIGH_SPEED ?= 1 +KBUILD_CPPFLAGS += \ + -DHW_FIR_DSD_BUF_MID_ADDR=$(HW_FIR_DSD_BUF_MID_ADDR) \ + -DDATA_BUF_START=$(DATA_BUF_START) +endif + +USE_THIRDPARTY ?= 0 +export USE_KNOWLES ?= 0 + +ifeq ($(CURRENT_TEST),1) +export VCODEC_VOLT ?= 1.6V +export VANA_VOLT ?= 1.35V +else +export VCODEC_VOLT ?= 1.8V +export VANA_VOLT ?= 1.35V +endif + +export LAURENT_ALGORITHM ?= 0 + +export TX_IQ_CAL ?= 0 + +export BT_XTAL_SYNC ?= 1 + +export BTADDR_FOR_DEBUG ?= 1 + +export POWERKEY_I2C_SWITCH ?=0 + +AUTO_TEST ?= 0 + +BES_AUTOMATE_TEST ?= 0 + +export DUMP_NORMAL_LOG ?= 0 + +SUPPORT_BATTERY_REPORT ?= 1 + +SUPPORT_HF_INDICATORS ?= 0 + +SUPPORT_SIRI ?= 1 + +BES_AUDIO_DEV_Main_Board_9v0 ?= 0 + +APP_USE_LED_INDICATE_IBRT_STATUS ?= 0 + +export BT_EXT_LNA_PA ?=0 +export BT_EXT_LNA ?=0 +export BT_EXT_PA ?=0 + +ifeq ($(A2DP_LHDC_ON),1) +AUDIO_BUFFER_SIZE := 140*1024 +else +AUDIO_BUFFER_SIZE := 100*1024 +endif + +export TRACE_BUF_SIZE := 16*1024 +export TRACE_BAUD_RATE := 10*115200 + +init-y := +core-y := platform/ services/ apps/ utils/cqueue/ utils/list/ services/multimedia/ utils/intersyshci/ + +KBUILD_CPPFLAGS += \ + -Iplatform/cmsis/inc \ + -Iservices/audioflinger \ + -Iplatform/hal \ + -Iservices/fs/ \ + -Iservices/fs/sd \ + -Iservices/fs/fat \ + -Iservices/fs/fat/ChaN + +KBUILD_CPPFLAGS += \ + -DAPP_AUDIO_BUFFER_SIZE=$(AUDIO_BUFFER_SIZE) \ + -DCHARGER_PLUGINOUT_RESET=0 \ + -D__POWERKEY_CTRL_ONOFF_ONLY__ +# -D__A2DP_AVDTP_CP__ \ + +ifeq ($(BES_AUDIO_DEV_Main_Board_9v0),1) +KBUILD_CPPFLAGS += -DBES_AUDIO_DEV_Main_Board_9v0 +endif + +ifeq ($(TPORTS_KEY_COEXIST),1) +KBUILD_CPPFLAGS += -DTPORTS_KEY_COEXIST +endif + +#-DIBRT_LINK_LOWLAYER_MONITOR + +#-D_AUTO_SWITCH_POWER_MODE__ +#-D__APP_KEY_FN_STYLE_A__ +#-D__APP_KEY_FN_STYLE_B__ +#-D__EARPHONE_STAY_BOTH_SCAN__ +#-D__POWERKEY_CTRL_ONOFF_ONLY__ +#-DAUDIO_LINEIN + +ifeq ($(CURRENT_TEST),1) +INTSRAM_RUN ?= 1 +endif +ifeq ($(INTSRAM_RUN),1) +LDS_FILE := best1000_intsram.lds +else +LDS_FILE := best1000.lds +endif + +ifeq ($(GATT_OVER_BR_EDR),1) +export GATT_OVER_BR_EDR ?= 1 +KBUILD_CPPFLAGS += -D__GATT_OVER_BR_EDR__ +endif + +ifeq ($(TOTA),1) +ifeq ($(BLE),1) +KBUILD_CPPFLAGS += -DBLE_TOTA_ENABLED +endif +KBUILD_CPPFLAGS += -DSHOW_RSSI +KBUILD_CPPFLAGS += -DTEST_OVER_THE_AIR_ENANBLED +export TEST_OVER_THE_AIR ?= 1 +endif + +KBUILD_CPPFLAGS += -DSHOW_RSSI +ifneq ($(A2DP_DECODER_VER), ) +KBUILD_CPPFLAGS += -DA2DP_DECODER_VER=$(A2DP_DECODER_VER) +endif + +KBUILD_CPPFLAGS += \ + # -DHAL_TRACE_RX_ENABLE + +KBUILD_CFLAGS += + +LIB_LDFLAGS += -lstdc++ -lsupc++ + +export BTIF_HID_DEVICE ?= 1 +ifeq ($(BTIF_HID_DEVICE),1) +KBUILD_CPPFLAGS += -DBTIF_HID_DEVICE +endif + +#CFLAGS_IMAGE += -u _printf_float -u _scanf_float + +#LDFLAGS_IMAGE += --wrap main diff --git a/config/best2300p_ibrt/tgt_hardware.c b/config/best2300p_ibrt/tgt_hardware.c new file mode 100644 index 0000000..eba786f --- /dev/null +++ b/config/best2300p_ibrt/tgt_hardware.c @@ -0,0 +1,339 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "tgt_hardware.h" +#include "iir_process.h" +#include "fir_process.h" +#include "drc.h" +#include "limiter.h" +#include "spectrum_fix.h" + +const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_hw_pinmux_pwl[CFG_HW_PLW_NUM] = { +#if (CFG_HW_PLW_NUM > 0) + {HAL_IOMUX_PIN_LED2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_LED1, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}, +#endif +}; + +#ifdef __APP_USE_LED_INDICATE_IBRT_STATUS__ +const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_ibrt_indication_pinmux_pwl[3] = { + {HAL_IOMUX_PIN_P1_5, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_LED1, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VBAT, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_LED2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VBAT, HAL_IOMUX_PIN_PULLUP_ENABLE}, +}; +#endif + +#ifdef __KNOWLES +const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_pinmux_uart[2] = { + {HAL_IOMUX_PIN_P2_2, HAL_IOMUX_FUNC_UART2_RX, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P2_3, HAL_IOMUX_FUNC_UART2_TX, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL}, +}; +#endif + +//adckey define +const uint16_t CFG_HW_ADCKEY_MAP_TABLE[CFG_HW_ADCKEY_NUMBER] = { +#if (CFG_HW_ADCKEY_NUMBER > 0) + HAL_KEY_CODE_FN9,HAL_KEY_CODE_FN8,HAL_KEY_CODE_FN7, + HAL_KEY_CODE_FN6,HAL_KEY_CODE_FN5,HAL_KEY_CODE_FN4, + HAL_KEY_CODE_FN3,HAL_KEY_CODE_FN2,HAL_KEY_CODE_FN1, +#endif +}; + +//gpiokey define +#define CFG_HW_GPIOKEY_DOWN_LEVEL (0) +#define CFG_HW_GPIOKEY_UP_LEVEL (1) +const struct HAL_KEY_GPIOKEY_CFG_T cfg_hw_gpio_key_cfg[CFG_HW_GPIOKEY_NUM] = { +/* +#if (CFG_HW_GPIOKEY_NUM > 0) +#ifdef BES_AUDIO_DEV_Main_Board_9v0 + {HAL_KEY_CODE_FN1,{HAL_IOMUX_PIN_P0_3, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN2,{HAL_IOMUX_PIN_P0_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN3,{HAL_IOMUX_PIN_P0_1, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN4,{HAL_IOMUX_PIN_P0_2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + //{HAL_KEY_CODE_FN5,{HAL_IOMUX_PIN_P2_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + // {HAL_KEY_CODE_FN6,{HAL_IOMUX_PIN_P2_1, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, +#else +#ifndef TPORTS_KEY_COEXIST + {HAL_KEY_CODE_FN1,{HAL_IOMUX_PIN_P1_3, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN2,{HAL_IOMUX_PIN_P1_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + // {HAL_KEY_CODE_FN3,{HAL_IOMUX_PIN_P1_2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN15,{HAL_IOMUX_PIN_P1_2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, +#else + {HAL_KEY_CODE_FN1,{HAL_IOMUX_PIN_P1_3, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN15,{HAL_IOMUX_PIN_P1_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, +#endif +#endif +#ifdef IS_MULTI_AI_ENABLED + //{HAL_KEY_CODE_FN13,{HAL_IOMUX_PIN_P1_3, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + //{HAL_KEY_CODE_FN14,{HAL_IOMUX_PIN_P1_2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, +#endif +#endif +*/ + {HAL_KEY_CODE_FN1,{HAL_IOMUX_PIN_P1_5, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, +}; + +//bt config +const char *BT_LOCAL_NAME = TO_STRING(BT_DEV_NAME) "\0"; +const char *BLE_DEFAULT_NAME = "BES_BLE"; +uint8_t ble_addr[6] = { +#ifdef BLE_DEV_ADDR + BLE_DEV_ADDR +#else + 0xBE,0x99,0x34,0x45,0x56,0x67 +#endif +}; +uint8_t bt_addr[6] = { +#ifdef BT_DEV_ADDR + BT_DEV_ADDR +#else + 0x1e,0x57,0x34,0x45,0x56,0x67 +#endif +}; + +//audio config +//freq bands range {[0k:2.5K], [2.5k:5K], [5k:7.5K], [7.5K:10K], [10K:12.5K], [12.5K:15K], [15K:17.5K], [17.5K:20K]} +//gain range -12~+12 +const int8_t cfg_aud_eq_sbc_band_settings[CFG_HW_AUD_EQ_NUM_BANDS] = {0, 0, 0, 0, 0, 0, 0, 0}; + +#define TX_PA_GAIN CODEC_TX_PA_GAIN_DEFAULT + +const struct CODEC_DAC_VOL_T codec_dac_vol[TGT_VOLUME_LEVEL_QTY] = { + {TX_PA_GAIN,0x03,-21}, + {TX_PA_GAIN,0x03,-99}, + {TX_PA_GAIN,0x03,-45}, + {TX_PA_GAIN,0x03,-42}, + {TX_PA_GAIN,0x03,-39}, + {TX_PA_GAIN,0x03,-36}, + {TX_PA_GAIN,0x03,-33}, + {TX_PA_GAIN,0x03,-30}, + {TX_PA_GAIN,0x03,-27}, + {TX_PA_GAIN,0x03,-24}, + {TX_PA_GAIN,0x03,-21}, + {TX_PA_GAIN,0x03,-18}, + {TX_PA_GAIN,0x03,-15}, + {TX_PA_GAIN,0x03,-12}, + {TX_PA_GAIN,0x03, -9}, + {TX_PA_GAIN,0x03, -6}, + {TX_PA_GAIN,0x03, -3}, + {TX_PA_GAIN,0x03, 0}, //0dBm +}; + +#if SPEECH_CODEC_CAPTURE_CHANNEL_NUM == 2 +#define CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH4 | AUD_VMIC_MAP_VMIC2|AUD_VMIC_MAP_VMIC3) +#elif SPEECH_CODEC_CAPTURE_CHANNEL_NUM == 3 +#define CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1 | AUD_CHANNEL_MAP_CH4 | AUD_VMIC_MAP_VMIC1) +#else +#define CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV (AUD_CHANNEL_MAP_CH4 | AUD_VMIC_MAP_VMIC3) +#endif + +#define CFG_HW_AUD_INPUT_PATH_LINEIN_DEV (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1) +#ifdef VOICE_DETECTOR_EN +#define CFG_HW_AUD_INPUT_PATH_VADMIC_DEV (AUD_CHANNEL_MAP_CH4 | AUD_VMIC_MAP_VMIC1) +#else +#define CFG_HW_AUD_INPUT_PATH_ASRMIC_DEV (AUD_CHANNEL_MAP_CH0 | AUD_VMIC_MAP_VMIC1) +#endif + +const struct AUD_IO_PATH_CFG_T cfg_audio_input_path_cfg[CFG_HW_AUD_INPUT_PATH_NUM] = { +#if defined(SPEECH_TX_AEC_CODEC_REF) + // NOTE: If enable Ch5 and CH6, need to add channel_num when setup audioflinger stream + { AUD_INPUT_PATH_MAINMIC, CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV | AUD_CHANNEL_MAP_CH4, }, +#else + { AUD_INPUT_PATH_MAINMIC, CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV, }, +#endif + { AUD_INPUT_PATH_LINEIN, CFG_HW_AUD_INPUT_PATH_LINEIN_DEV, }, +#ifdef VOICE_DETECTOR_EN + { AUD_INPUT_PATH_VADMIC, CFG_HW_AUD_INPUT_PATH_VADMIC_DEV, }, +#else + { AUD_INPUT_PATH_ASRMIC, CFG_HW_AUD_INPUT_PATH_ASRMIC_DEV, }, +#endif +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP MuteOutPwl ={ + HAL_IOMUX_PIN_P1_1, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_enable_cfg = { + HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_detecter_cfg = { + HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_indicator_cfg = { + HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_hw_tws_channel_cfg = { + HAL_IOMUX_PIN_P1_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE//HAL_IOMUX_PIN_P1_5 500:HAL_IOMUX_PIN_P2_5 +}; +/* +const struct HAL_IOMUX_PIN_FUNCTION_MAP TOUCH_INT ={ + HAL_IOMUX_PIN_P1_5, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; +*/ + +const struct HAL_IOMUX_PIN_FUNCTION_MAP TOUCH_I2C_SDA ={ + HAL_IOMUX_PIN_P2_1, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP TOUCH_I2C_SCL ={ + HAL_IOMUX_PIN_P2_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; +bool tgt_tws_get_channel_is_right(void) +{ +#ifdef __FIXED_TWS_EAR_SIDE__ + return TWS_EAR_SIDE_ROLE; +#else + return hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)cfg_hw_tws_channel_cfg.pin); +#endif +} + +const IIR_CFG_T audio_eq_sw_iir_cfg = { + .gain0 = 0, + .gain1 = 0, + .num = 5, + .param = { + {IIR_TYPE_PEAK, .0, 200, 2}, + {IIR_TYPE_PEAK, .0, 600, 2}, + {IIR_TYPE_PEAK, .0, 2000.0, 2}, + {IIR_TYPE_PEAK, .0, 6000.0, 2}, + {IIR_TYPE_PEAK, .0, 12000.0, 2} + } +}; + +const IIR_CFG_T * const audio_eq_sw_iir_cfg_list[EQ_SW_IIR_LIST_NUM]={ + &audio_eq_sw_iir_cfg, +}; + +const FIR_CFG_T audio_eq_hw_fir_cfg_44p1k = { + .gain = 0.0f, + .len = 384, + .coef = + { + (1<<23)-1, + } +}; + +const FIR_CFG_T audio_eq_hw_fir_cfg_48k = { + .gain = 0.0f, + .len = 384, + .coef = + { + (1<<23)-1, + } +}; + + +const FIR_CFG_T audio_eq_hw_fir_cfg_96k = { + .gain = 0.0f, + .len = 384, + .coef = + { + (1<<23)-1, + } +}; + +const FIR_CFG_T * const audio_eq_hw_fir_cfg_list[EQ_HW_FIR_LIST_NUM]={ + &audio_eq_hw_fir_cfg_44p1k, + &audio_eq_hw_fir_cfg_48k, + &audio_eq_hw_fir_cfg_96k, +}; + +//hardware dac iir eq +const IIR_CFG_T audio_eq_hw_dac_iir_cfg = { + .gain0 = 0, + .gain1 = 0, + .num = 8, + .param = { + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + } +}; + +const IIR_CFG_T * const POSSIBLY_UNUSED audio_eq_hw_dac_iir_cfg_list[EQ_HW_DAC_IIR_LIST_NUM]={ + &audio_eq_hw_dac_iir_cfg, +}; + +//hardware dac iir eq +const IIR_CFG_T audio_eq_hw_adc_iir_adc_cfg = { + .gain0 = 0, + .gain1 = 0, + .num = 1, + .param = { + {IIR_TYPE_PEAK, 0.0, 1000.0, 0.7}, + } +}; + +const IIR_CFG_T * const POSSIBLY_UNUSED audio_eq_hw_adc_iir_cfg_list[EQ_HW_ADC_IIR_LIST_NUM]={ + &audio_eq_hw_adc_iir_adc_cfg, +}; + + + +//hardware iir eq +const IIR_CFG_T audio_eq_hw_iir_cfg = { + .gain0 = 0, + .gain1 = 0, + .num = 8, + .param = { + {IIR_TYPE_PEAK, -10.1, 100.0, 7}, + {IIR_TYPE_PEAK, -10.1, 400.0, 7}, + {IIR_TYPE_PEAK, -10.1, 700.0, 7}, + {IIR_TYPE_PEAK, -10.1, 1000.0, 7}, + {IIR_TYPE_PEAK, -10.1, 3000.0, 7}, + {IIR_TYPE_PEAK, -10.1, 5000.0, 7}, + {IIR_TYPE_PEAK, -10.1, 7000.0, 7}, + {IIR_TYPE_PEAK, -10.1, 9000.0, 7}, + + } +}; + +const IIR_CFG_T * const POSSIBLY_UNUSED audio_eq_hw_iir_cfg_list[EQ_HW_IIR_LIST_NUM]={ + &audio_eq_hw_iir_cfg, +}; + +const DrcConfig audio_drc_cfg = { + .knee = 3, + .filter_type = {14, -1}, + .band_num = 2, + .look_ahead_time = 10, + .band_settings = { + {-20, 0, 2, 3, 3000, 1}, + {-20, 0, 2, 3, 3000, 1}, + } + }; + +const LimiterConfig audio_drc2_cfg = { + .knee = 2, + .look_ahead_time = 10, + .threshold = -20, + .makeup_gain = 19, + .ratio = 1000, + .attack_time = 3, + .release_time = 3000, +}; + +const SpectrumFixConfig audio_spectrum_cfg = { + .freq_num = 9, + .freq_list = {200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800}, +}; + diff --git a/config/best2300p_ibrt/tgt_hardware.h b/config/best2300p_ibrt/tgt_hardware.h new file mode 100644 index 0000000..e89a615 --- /dev/null +++ b/config/best2300p_ibrt/tgt_hardware.h @@ -0,0 +1,152 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __TGT_HARDWARE__ +#define __TGT_HARDWARE__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_iomux.h" +#include "hal_gpio.h" +#include "hal_key.h" +#include "hal_aud.h" + +//config hwardware codec iir. +#define EQ_HW_DAC_IIR_LIST_NUM 1 +#define EQ_HW_ADC_IIR_LIST_NUM 1 +#define EQ_HW_IIR_LIST_NUM 1 +#define EQ_SW_IIR_LIST_NUM 1 +#define EQ_HW_FIR_LIST_NUM 3 + +//pwl + +#ifdef __BT_DEBUG_TPORTS__ +#define CFG_HW_PLW_NUM (0) +#else +#ifdef __APP_USE_LED_INDICATE_IBRT_STATUS__ +#define CFG_HW_PLW_NUM (0) +#else +#define CFG_HW_PLW_NUM (2) +#endif +#endif + +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_hw_pinmux_pwl[CFG_HW_PLW_NUM]; +#ifdef __APP_USE_LED_INDICATE_IBRT_STATUS__ +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_ibrt_indication_pinmux_pwl[3]; +#endif + +#ifdef __KNOWLES +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_pinmux_uart[2]; +#endif + +//adckey define +#define CFG_HW_ADCKEY_NUMBER 0 +#define CFG_HW_ADCKEY_BASE 0 +#define CFG_HW_ADCKEY_ADC_MAXVOLT 1000 +#define CFG_HW_ADCKEY_ADC_MINVOLT 0 +#define CFG_HW_ADCKEY_ADC_KEYVOLT_BASE 130 +extern const uint16_t CFG_HW_ADCKEY_MAP_TABLE[CFG_HW_ADCKEY_NUMBER]; + +#define BTA_AV_CO_SBC_MAX_BITPOOL 52 + +#ifdef __BT_DEBUG_TPORTS__ +#ifdef TPORTS_KEY_COEXIST +#define CFG_HW_GPIOKEY_NUM (2) +#else +#define CFG_HW_GPIOKEY_NUM (0) +#endif +#else +//gpiokey define +#ifdef IS_MULTI_AI_ENABLED +#define CFG_HW_GPIOKEY_NUM (3) +#elif BES_AUDIO_DEV_Main_Board_9v0 +#define CFG_HW_GPIOKEY_NUM (6) +#else +#define CFG_HW_GPIOKEY_NUM (1) +#endif +#endif + +extern const struct HAL_KEY_GPIOKEY_CFG_T cfg_hw_gpio_key_cfg[CFG_HW_GPIOKEY_NUM]; + +// ANC function key +#define ANC_FUNCTION_KEY HAL_KEY_CODE_PWR + +// ANC coefficient curve number +#define ANC_COEF_NUM (1) + +//#define ANC_TALK_THROUGH + +#ifdef ANC_TALK_THROUGH +#define ANC_COEF_LIST_NUM (ANC_COEF_NUM + 1) +#else +#define ANC_COEF_LIST_NUM (ANC_COEF_NUM) +#endif + +#define ANC_FF_MIC_CH_L AUD_CHANNEL_MAP_CH0 +#define ANC_FF_MIC_CH_R AUD_CHANNEL_MAP_CH1 +#define ANC_FB_MIC_CH_L AUD_CHANNEL_MAP_CH2 +#define ANC_FB_MIC_CH_R AUD_CHANNEL_MAP_CH3 + +// audio codec +#define CFG_HW_AUD_INPUT_PATH_NUM 3 +extern const struct AUD_IO_PATH_CFG_T cfg_audio_input_path_cfg[CFG_HW_AUD_INPUT_PATH_NUM]; + +#define CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV (AUD_CHANNEL_MAP_CH0) + +#define CFG_HW_AUD_SIDETONE_MIC_DEV (AUD_CHANNEL_MAP_CH0) +#define CFG_HW_AUD_SIDETONE_GAIN_DBVAL (-20) + +//bt config +extern const char *BT_LOCAL_NAME; +extern const char *BLE_DEFAULT_NAME; +extern uint8_t ble_addr[6]; +extern uint8_t bt_addr[6]; + +#define CODEC_SADC_VOL (12) + +extern const struct CODEC_DAC_VOL_T codec_dac_vol[TGT_VOLUME_LEVEL_QTY]; + +//range -12~+12 +#define CFG_HW_AUD_EQ_NUM_BANDS (8) +extern const int8_t cfg_aud_eq_sbc_band_settings[CFG_HW_AUD_EQ_NUM_BANDS]; +#define CFG_AUD_EQ_IIR_NUM_BANDS (4) + +//battery info +#define APP_BATTERY_MIN_MV (3200) +#define APP_BATTERY_PD_MV (3100) + +#define APP_BATTERY_MAX_MV (4200) + +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_enable_cfg; +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_detecter_cfg; +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_indicator_cfg; + +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP MuteOutPwl; +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_hw_tws_channel_cfg; +//extern const struct HAL_IOMUX_PIN_FUNCTION_MAP TOUCH_INT; + +extern bool tgt_tws_get_channel_is_right(void); +extern void app_mute_ctrl(bool Status); +extern void app_mutetimer_start(); + +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP TOUCH_I2C_SDA; +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP TOUCH_I2C_SCL; +#ifdef __cplusplus +} +#endif + +#endif diff --git a/config/best2300p_ibrt_anc/target.mk b/config/best2300p_ibrt_anc/target.mk new file mode 100644 index 0000000..15bb89e --- /dev/null +++ b/config/best2300p_ibrt_anc/target.mk @@ -0,0 +1,423 @@ +CHIP ?= best2300p + +DEBUG ?= 1 + +FPGA ?= 0 + +MBED ?= 0 + +RTOS ?= 1 + +#KERNEL ?= FREERTOS + +LIBC_ROM ?= 1 + +export USER_SECURE_BOOT ?= 0 +# enable:1 +# disable:0 + +WATCHER_DOG ?= 0 + +DEBUG_PORT ?= 1 +# 0: usb +# 1: uart0 +# 2: uart1 + +FLASH_CHIP ?= ALL +# GD25Q80C +# GD25Q32C +# ALL + +export NO_TRACE_TIME_STAMP ?=1 + +export FORCE_SIGNALINGMODE ?= 0 + +export FORCE_NOSIGNALINGMODE ?= 0 + +export FORCE_SCO_MAX_RETX ?= 0 + +export FA_RX_GAIN_CTRL ?= 1 + +export BT_FA_ECC ?= 0 +export CONTROLLER_DUMP_ENABLE ?= 0 +export CONTROLLER_MEM_LOG_ENABLE ?= 0 + +export INTERSYS_DEBUG ?= 1 + +export PROFILE_DEBUG ?= 0 + +export BTDUMP_ENABLE ?= 0 + +export BT_DEBUG_TPORTS ?= 0 + +TPORTS_KEY_COEXIST ?= 0 + +export SNIFF_MODE_CHECK ?= 0 + +AUDIO_OUTPUT_MONO ?= 0 + +AUDIO_OUTPUT_DIFF ?= 0 + +#### ANC DEFINE START ###### +export ANC_APP ?= 0 +export ANC_FF_ENABLED ?= 0 +export ANC_FB_ENABLED ?= 0 +export AUDIO_ANC_FB_MC ?= 0 +export AUDIO_SECTION_SUPPT ?= 0 +export AUD_SECTION_STRUCT_VERSION ?= 2 +export AUDIO_ANC_FB_MC_HW ?=0 +export APP_ANC_KEY ?= 0 +export ANC_FB_CHECK ?= 0 +##### ANC DEFINE END ###### + +APP_ANC_TEST ?= 0 + +TEST_OVER_THE_AIR ?= 0 + +HW_FIR_EQ_PROCESS ?= 0 + +SW_IIR_EQ_PROCESS ?= 1 + +HW_DAC_IIR_EQ_PROCESS ?= 0 + +HW_IIR_EQ_PROCESS ?= 0 + +HW_DC_FILTER_WITH_IIR ?= 0 + +AUDIO_DRC ?= 0 + +AUDIO_DRC2 ?= 0 + +PC_CMD_UART ?= 0 + +AUDIO_SECTION_ENABLE ?= 0 + +AUDIO_RESAMPLE ?= 1 + +RESAMPLE_ANY_SAMPLE_RATE ?= 1 + +OSC_26M_X4_AUD2BB ?= 1 + +AUDIO_OUTPUT_VOLUME_DEFAULT ?= 17 +# range:1~16 + +AUDIO_INPUT_CAPLESSMODE ?= 0 + +AUDIO_INPUT_LARGEGAIN ?= 0 + +AUDIO_CODEC_ASYNC_CLOSE ?= 0 + +AUDIO_SCO_BTPCM_CHANNEL ?= 1 + +export A2DP_CP_ACCEL ?= 1 + +export SCO_CP_ACCEL ?= 1 + +export SCO_TRACE_CP_ACCEL ?= 0 + +# For TWS SCO DMA snapshot and low delay +export PCM_FAST_MODE ?= 1 + +export CVSD_BYPASS ?= 1 + +export LOW_DELAY_SCO ?= 0 + +SPEECH_TX_DC_FILTER ?= 1 + +SPEECH_TX_AEC2FLOAT ?= 1 + +SPEECH_TX_NS3 ?= 0 + +SPEECH_TX_2MIC_NS2 ?= 0 + +SPEECH_TX_COMPEXP ?= 1 + +SPEECH_TX_EQ ?= 0 + +SPEECH_TX_POST_GAIN ?= 0 + +SPEECH_RX_NS2FLOAT ?= 0 + +SPEECH_RX_EQ ?= 0 + +SPEECH_RX_POST_GAIN ?= 0 + +LARGE_RAM ?= 1 + +HSP_ENABLE ?= 0 + +HFP_1_6_ENABLE ?= 1 + +BTIF_HID_DEVICE ?= 1 + +MSBC_PLC_ENABLE ?= 1 + +MSBC_PLC_ENCODER ?= 1 + +MSBC_16K_SAMPLE_RATE ?= 1 + +SBC_FUNC_IN_ROM ?= 0 + +ROM_UTILS_ON ?= 0 + +APP_LINEIN_A2DP_SOURCE ?= 0 + +APP_I2S_A2DP_SOURCE ?= 0 + +VOICE_PROMPT ?= 1 + +#### Google related feature #### +# the overall google service switch +# currently, google service includes BISTO and GFPS +export GOOGLE_SERVICE_ENABLE ?= 0 + +# BISTO is a GVA service on Bluetooth audio device +# BISTO is an isolated service relative to GFPS +export BISTO_ENABLE ?= 0 + +# GSOUND_HOTWORD is a hotword library running on Bluetooth audio device +# GSOUND_HOTWORD is a subset of BISTO +export GSOUND_HOTWORD_ENABLE ?= 0 + +# GFPS is google fastpair service +# GFPS is an isolated service relative to BISTO +export GFPS_ENABLE ?= 0 +#### Google related feature #### + +export BTIF_HID_DEVICE ?= 1 +ifeq ($(BTIF_HID_DEVICE),1) +KBUILD_CPPFLAGS += -DBTIF_HID_DEVICE +endif + +BLE ?= 0 + +TOTA ?= 0 + +OTA_ENABLE ?= 1 + +TILE_DATAPATH_ENABLED ?= 0 + +CUSTOM_INFORMATION_TILE_ENABLE ?= 0 + +INTERCONNECTION ?= 0 + +INTERACTION ?= 0 + +INTERACTION_FASTPAIR ?= 0 + +BT_ONE_BRING_TWO ?= 0 + +DSD_SUPPORT ?= 0 + +A2DP_EQ_24BIT ?= 1 + +A2DP_AAC_ON ?= 1 + +A2DP_SCALABLE_ON ?= 0 + +A2DP_LHDC_ON ?= 0 +ifeq ($(A2DP_LHDC_ON),1) +A2DP_LHDC_V3 ?= 1 +A2DP_LHDC_LARC ?= 0 +export FLASH_UNIQUE_ID ?= 1 +endif + +A2DP_LDAC_ON ?= 0 + +export TX_RX_PCM_MASK ?= 0 + +A2DP_SCALABLE_ON ?= 0 + +FACTORY_MODE ?= 1 + +ENGINEER_MODE ?= 1 + +ULTRA_LOW_POWER ?= 1 + +DAC_CLASSG_ENABLE ?= 1 + +NO_SLEEP ?= 0 + +CORE_DUMP ?= 1 + +CORE_DUMP_TO_FLASH ?= 0 + +ENHANCED_STACK ?= 1 + +export SYNC_BT_CTLR_PROFILE ?= 0 + +export A2DP_DECODER_VER := 2 + +export IBRT ?= 1 + +export IBRT_SEARCH_UI ?= 1 + +export BES_AUD ?= 1 + +export POWER_MODE ?= DIG_DCDC + +export BT_RF_PREFER ?= 2M + +export SPEECH_CODEC ?= 1 + +export TWS_PROMPT_SYNC ?= 0 +export MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED ?= 0 + +export FLASH_SIZE ?= 0x400000 +export FLASH_SUSPEND ?= 1 + +ifeq ($(DSD_SUPPORT),1) +export BTUSB_AUDIO_MODE ?= 1 +export AUDIO_INPUT_MONO ?= 1 +export USB_ISO ?= 1 +export USB_AUDIO_DYN_CFG ?= 1 +export DELAY_STREAM_OPEN ?= 0 +export KEEP_SAME_LATENCY ?= 1 +export HW_FIR_DSD_PROCESS ?= 1 +ifeq ($(HW_FIR_DSD_PROCESS),1) +ifeq ($(CHIP),best2300) +export HW_FIR_DSD_BUF_MID_ADDR ?= 0x200A0000 +export DATA_BUF_START ?= 0x20040000 +endif +endif +export USB_AUDIO_UAC2 ?= 1 +export USB_HIGH_SPEED ?= 1 +KBUILD_CPPFLAGS += \ + -DHW_FIR_DSD_BUF_MID_ADDR=$(HW_FIR_DSD_BUF_MID_ADDR) \ + -DDATA_BUF_START=$(DATA_BUF_START) +endif + +USE_THIRDPARTY ?= 0 +export USE_KNOWLES ?= 0 +export USE_CYBERON ?= 0 + +ifeq ($(CURRENT_TEST),1) +export VCODEC_VOLT ?= 1.6V +export VANA_VOLT ?= 1.35V +else +endif + +export LAURENT_ALGORITHM ?= 0 + +export TX_IQ_CAL ?= 0 + +export BT_XTAL_SYNC ?= 1 + +export BTADDR_FOR_DEBUG ?= 1 + +export POWERKEY_I2C_SWITCH ?=0 + +AUTO_TEST ?= 0 + +export DUMP_NORMAL_LOG ?= 0 + +SUPPORT_BATTERY_REPORT ?= 1 + +SUPPORT_HF_INDICATORS ?= 0 + +SUPPORT_SIRI ?= 1 + +BES_AUDIO_DEV_Main_Board_9v0 ?= 0 + +APP_USE_LED_INDICATE_IBRT_STATUS ?= 0 + +export BT_EXT_LNA_PA ?=0 +export BT_EXT_LNA ?=0 +export BT_EXT_PA ?=0 + +ifeq ($(A2DP_LHDC_ON),1) +AUDIO_BUFFER_SIZE := 140*1024 +else +AUDIO_BUFFER_SIZE := 100*1024 +endif + +export TRACE_BUF_SIZE := 16*1024 +export TRACE_BAUD_RATE := 10*115200 + +init-y := +core-y := platform/ services/ apps/ utils/cqueue/ utils/list/ services/multimedia/ utils/intersyshci/ + +KBUILD_CPPFLAGS += -Iplatform/cmsis/inc \ + -Iservices/audioflinger \ + -Iplatform/hal \ + -Iservices/fs/ \ + -Iservices/fs/sd \ + -Iservices/fs/fat \ + -Iservices/fs/fat/ChaN + +KBUILD_CPPFLAGS += \ + -DAPP_AUDIO_BUFFER_SIZE=$(AUDIO_BUFFER_SIZE) \ + -DCHARGER_PLUGINOUT_RESET=0 \ + -D__APP_KEY_FN_STYLE_A__ + +ifeq ($(APP_ANC_KEY),1) +KBUILD_CPPFLAGS += -D__BT_ANC_KEY__ +endif + +ifeq ($(BES_AUDIO_DEV_Main_Board_9v0),1) +KBUILD_CPPFLAGS += -DBES_AUDIO_DEV_Main_Board_9v0 +endif + +ifeq ($(TPORTS_KEY_COEXIST),1) +KBUILD_CPPFLAGS += -DTPORTS_KEY_COEXIST +endif + +#-DIBRT_LINK_LOWLAYER_MONITOR + +#-D_AUTO_SWITCH_POWER_MODE__ +#-D__APP_KEY_FN_STYLE_A__ +#-D__APP_KEY_FN_STYLE_B__ +#-D__EARPHONE_STAY_BOTH_SCAN__ +#-D__POWERKEY_CTRL_ONOFF_ONLY__ +#-DAUDIO_LINEIN + +ifeq ($(CURRENT_TEST),1) +INTSRAM_RUN ?= 1 +endif +ifeq ($(INTSRAM_RUN),1) +LDS_FILE := best1000_intsram.lds +else +LDS_FILE := best1000.lds +endif + +ifeq ($(TOTA),1) +ifeq ($(BLE),1) +KBUILD_CPPFLAGS += -DBLE_TOTA_ENABLED +endif +KBUILD_CPPFLAGS += -DSHOW_RSSI +KBUILD_CPPFLAGS += -DTEST_OVER_THE_AIR_ENANBLED +export TEST_OVER_THE_AIR ?= 1 +endif + +ifneq ($(A2DP_DECODER_VER), ) +KBUILD_CPPFLAGS += -DA2DP_DECODER_VER=$(A2DP_DECODER_VER) +endif + +ifeq ($(ANC_APP),1) +KBUILD_CPPFLAGS += -DANC_APP +endif + +ifeq ($(USE_CYBERON),1) + +export THIRDPARTY_LIB ?= cyberon +KBUILD_CPPFLAGS += -D__CYBERON + +export KWS_IN_RAM := 1 +ifeq ($(KWS_IN_RAM),1) +CPPFLAGS_${LDS_FILE} += -DKWS_IN_RAM +endif #KWS_IN_RAM + +endif #USE_CYBERON + +KBUILD_CFLAGS += + +LIB_LDFLAGS += -lstdc++ -lsupc++ + +#CFLAGS_IMAGE += -u _printf_float -u _scanf_float + +#LDFLAGS_IMAGE += --wrap main + +export BTIF_HID_DEVICE ?= 1 +ifeq ($(BTIF_HID_DEVICE),1) +KBUILD_CPPFLAGS += -DBTIF_HID_DEVICE +endif diff --git a/config/best2300p_ibrt_anc/tgt_hardware.c b/config/best2300p_ibrt_anc/tgt_hardware.c new file mode 100644 index 0000000..1a2e752 --- /dev/null +++ b/config/best2300p_ibrt_anc/tgt_hardware.c @@ -0,0 +1,1089 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "tgt_hardware.h" +#include "aud_section.h" +#include "iir_process.h" +#include "fir_process.h" +#include "drc.h" +#include "limiter.h" +#include "spectrum_fix.h" + +const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_hw_pinmux_pwl[CFG_HW_PLW_NUM] = { +#if (CFG_HW_PLW_NUM > 0) + {HAL_IOMUX_PIN_P1_5, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_P1_4, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}, +#endif +}; + +//adckey define +const uint16_t CFG_HW_ADCKEY_MAP_TABLE[CFG_HW_ADCKEY_NUMBER] = { +#if (CFG_HW_ADCKEY_NUMBER > 0) + HAL_KEY_CODE_FN9,HAL_KEY_CODE_FN8,HAL_KEY_CODE_FN7, + HAL_KEY_CODE_FN6,HAL_KEY_CODE_FN5,HAL_KEY_CODE_FN4, + HAL_KEY_CODE_FN3,HAL_KEY_CODE_FN2,HAL_KEY_CODE_FN1, +#endif +}; + +//gpiokey define +#define CFG_HW_GPIOKEY_DOWN_LEVEL (0) +#define CFG_HW_GPIOKEY_UP_LEVEL (1) +const struct HAL_KEY_GPIOKEY_CFG_T cfg_hw_gpio_key_cfg[CFG_HW_GPIOKEY_NUM] = { +#if (CFG_HW_GPIOKEY_NUM > 0) +#ifdef BES_AUDIO_DEV_Main_Board_9v0 + {HAL_KEY_CODE_FN1,{HAL_IOMUX_PIN_P0_3, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN2,{HAL_IOMUX_PIN_P0_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN3,{HAL_IOMUX_PIN_P0_1, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN4,{HAL_IOMUX_PIN_P0_2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN5,{HAL_IOMUX_PIN_P2_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN6,{HAL_IOMUX_PIN_P2_1, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, +#else +#ifndef TPORTS_KEY_COEXIST + {HAL_KEY_CODE_FN1,{HAL_IOMUX_PIN_P1_3, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN2,{HAL_IOMUX_PIN_P1_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + // {HAL_KEY_CODE_FN3,{HAL_IOMUX_PIN_P1_2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN15,{HAL_IOMUX_PIN_P1_2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, +#else + {HAL_KEY_CODE_FN1,{HAL_IOMUX_PIN_P1_3, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + {HAL_KEY_CODE_FN15,{HAL_IOMUX_PIN_P1_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, +#endif +#endif +#ifdef IS_MULTI_AI_ENABLED + //{HAL_KEY_CODE_FN13,{HAL_IOMUX_PIN_P1_3, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, + //{HAL_KEY_CODE_FN14,{HAL_IOMUX_PIN_P1_2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}}, +#endif +#endif +}; + +//bt config +const char *BT_LOCAL_NAME = TO_STRING(BT_DEV_NAME) "\0"; +const char *BLE_DEFAULT_NAME = "BES_BLE"; +uint8_t ble_addr[6] = { +#ifdef BLE_DEV_ADDR + BLE_DEV_ADDR +#else + 0xBE,0x99,0x34,0x45,0x56,0x67 +#endif +}; +uint8_t bt_addr[6] = { +#ifdef BT_DEV_ADDR + BT_DEV_ADDR +#else + 0x1e,0x57,0x34,0x45,0x56,0x67 +#endif +}; + +//audio config +//freq bands range {[0k:2.5K], [2.5k:5K], [5k:7.5K], [7.5K:10K], [10K:12.5K], [12.5K:15K], [15K:17.5K], [17.5K:20K]} +//gain range -12~+12 +const int8_t cfg_aud_eq_sbc_band_settings[CFG_HW_AUD_EQ_NUM_BANDS] = {0, 0, 0, 0, 0, 0, 0, 0}; + +#define TX_PA_GAIN CODEC_TX_PA_GAIN_DEFAULT + +const struct CODEC_DAC_VOL_T codec_dac_vol[TGT_VOLUME_LEVEL_QTY] = { + {TX_PA_GAIN,0x03,-11}, + {TX_PA_GAIN,0x03,-99}, + {TX_PA_GAIN,0x03,-45}, + {TX_PA_GAIN,0x03,-42}, + {TX_PA_GAIN,0x03,-39}, + {TX_PA_GAIN,0x03,-36}, + {TX_PA_GAIN,0x03,-33}, + {TX_PA_GAIN,0x03,-30}, + {TX_PA_GAIN,0x03,-27}, + {TX_PA_GAIN,0x03,-24}, + {TX_PA_GAIN,0x03,-21}, + {TX_PA_GAIN,0x03,-18}, + {TX_PA_GAIN,0x03,-15}, + {TX_PA_GAIN,0x03,-12}, + {TX_PA_GAIN,0x03, -9}, + {TX_PA_GAIN,0x03, -6}, + {TX_PA_GAIN,0x03, -3}, + {TX_PA_GAIN,0x03, 0}, //0dBm +}; + +#if SPEECH_CODEC_CAPTURE_CHANNEL_NUM == 2 +#define CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1 | AUD_VMIC_MAP_VMIC1) +#elif SPEECH_CODEC_CAPTURE_CHANNEL_NUM == 3 +#define CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1 | AUD_CHANNEL_MAP_CH4 | AUD_VMIC_MAP_VMIC1) +#else +#define CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV (AUD_CHANNEL_MAP_CH0 | AUD_VMIC_MAP_VMIC1) +#endif +#define CFG_HW_AUD_INPUT_PATH_LINEIN_DEV (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1) +#define CFG_HW_AUD_INPUT_PATH_VADMIC_DEV (AUD_CHANNEL_MAP_CH4 | AUD_VMIC_MAP_VMIC1) +#define CFG_HW_AUD_INPUT_PATH_ASRMIC_DEV (AUD_CHANNEL_MAP_CH0 | AUD_VMIC_MAP_VMIC1) + +const struct AUD_IO_PATH_CFG_T cfg_audio_input_path_cfg[CFG_HW_AUD_INPUT_PATH_NUM] = { +#if defined(SPEECH_TX_AEC_CODEC_REF) + // NOTE: If enable Ch5 and CH6, need to add channel_num when setup audioflinger stream + { AUD_INPUT_PATH_MAINMIC, CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV | AUD_CHANNEL_MAP_ECMIC_CH0, }, +#else + { AUD_INPUT_PATH_MAINMIC, CFG_HW_AUD_INPUT_PATH_MAINMIC_DEV, }, +#endif + { AUD_INPUT_PATH_LINEIN, CFG_HW_AUD_INPUT_PATH_LINEIN_DEV, }, + { AUD_INPUT_PATH_VADMIC, CFG_HW_AUD_INPUT_PATH_VADMIC_DEV, }, + { AUD_INPUT_PATH_ASRMIC, CFG_HW_AUD_INPUT_PATH_ASRMIC_DEV, }, +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_enable_cfg = { + HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_detecter_cfg = { + HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; + +const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_indicator_cfg = { + HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE +}; + + +/* + +//ff + + +Filter1_B=[ 42462788, -84862242, 42399478]; +Filter1_A=[ 134217728, -268358003, 134140286]; + +Filter2_B=[ 135905569, -267224817, 131334465]; +Filter2_A=[ 134217728, -267224817, 133022306]; + +Filter3_B=[ 132936489, -263935268, 131067941]; +Filter3_A=[ 134217728, -263935268, 129786702]; + +Filter4_B=[ 131758190, -257297054, 126191415]; +Filter4_A=[ 134217728, -257297054, 123731878]; + + + +*/ + +#define IIR_COUNTER_FF_L (6) +#define IIR_COUNTER_FF_R (6) +#define IIR_COUNTER_FB_L (5) +#define IIR_COUNTER_FB_R (5) + + +static const struct_anc_cfg POSSIBLY_UNUSED AncFirCoef_50p7k_mode0 = { + .anc_cfg_ff_l = { + // .total_gain = 440, + .total_gain = 350, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FF_L, + + .iir_coef[0].coef_b={42462788, -84862242, 42399478}, + .iir_coef[0].coef_a={134217728, -268358003, 134140286}, + + .iir_coef[1].coef_b={135905569, -267224817, 131334465}, + .iir_coef[1].coef_a={134217728, -267224817, 133022306}, + + .iir_coef[2].coef_b={132936489, -263935268, 131067941}, + .iir_coef[2].coef_a={134217728, -263935268, 129786702}, + + .iir_coef[3].coef_b={131758190, -257297054, 126191415}, + .iir_coef[3].coef_a={134217728, -257297054, 123731878}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + .anc_cfg_ff_r = { + // .total_gain = 382, + .total_gain = 350, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FF_R, + + .iir_coef[0].coef_b={42462788, -84862242, 42399478}, + .iir_coef[0].coef_a={134217728, -268358003, 134140286}, + + .iir_coef[1].coef_b={135905569, -267224817, 131334465}, + .iir_coef[1].coef_a={134217728, -267224817, 133022306}, + + .iir_coef[2].coef_b={132936489, -263935268, 131067941}, + .iir_coef[2].coef_a={134217728, -263935268, 129786702}, + + .iir_coef[3].coef_b={131758190, -257297054, 126191415}, + .iir_coef[3].coef_a={134217728, -257297054, 123731878}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + + +/* + +Filter1_B=[ 27461831, -54408898, 27001841]; +Filter1_A=[ 134217728, -216605724, 82606056]; + +Filter2_B=[ 138294078, -267600712, 129323227]; +Filter2_A=[ 134217728, -267600712, 133399577]; + +Filter3_B=[ 134500015, -268177932, 133678688]; +Filter3_A=[ 134217728, -268177932, 133960975]; + +Filter4_B=[ 133629164, -264794659, 131257050]; +Filter4_A=[ 134217728, -264794659, 130668486]; + + +*/ + + .anc_cfg_fb_l = { + .total_gain = 350, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FB_L, + + .iir_coef[0].coef_b={ 27461831, -54408898, 27001841}, + .iir_coef[0].coef_a={134217728, -216605724, 82606056}, + + .iir_coef[1].coef_b={138294078, -267600712, 129323227}, + .iir_coef[1].coef_a={134217728, -267600712, 133399577}, + + .iir_coef[2].coef_b={134500015, -268177932, 133678688}, + .iir_coef[2].coef_a={134217728, -268177932, 133960975}, + + .iir_coef[3].coef_b={133629164, -264794659, 131257050}, + .iir_coef[3].coef_a={134217728, -264794659, 130668486}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + + + + + + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + .anc_cfg_fb_r = { + .total_gain = 350, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FB_R, + + .iir_coef[0].coef_b={ 27461831, -54408898, 27001841}, + .iir_coef[0].coef_a={134217728, -216605724, 82606056}, + + .iir_coef[1].coef_b={138294078, -267600712, 129323227}, + .iir_coef[1].coef_a={134217728, -267600712, 133399577}, + + .iir_coef[2].coef_b={134500015, -268177932, 133678688}, + .iir_coef[2].coef_a={134217728, -268177932, 133960975}, + + .iir_coef[3].coef_b={133629164, -264794659, 131257050}, + .iir_coef[3].coef_a={134217728, -264794659, 130668486}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + + + +}; + + +/* + +//ff + + +Filter1_B=[ 42463913, -84860822, 42396935]; +Filter1_A=[ 134217728, -268353516, 134135801]; + +Filter2_B=[ 136002894, -267154076, 131168209]; +Filter2_A=[ 134217728, -267154076, 132953376]; + +Filter3_B=[ 132863566, -263674901, 130888668]; +Filter3_A=[ 134217728, -263674901, 129534506]; + +Filter4_B=[ 131621817, -256639526, 125746382]; +Filter4_A=[ 134217728, -256639526, 123150471]; + + + +*/ + +static const struct_anc_cfg POSSIBLY_UNUSED AncFirCoef_48k_mode0 = { + .anc_cfg_ff_l = { + // .total_gain = 440, + .total_gain = 312, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FF_L, + + .iir_coef[0].coef_b={42463913, -84860822, 42396935}, + .iir_coef[0].coef_a={134217728, -268353516, 134135801}, + + .iir_coef[1].coef_b={136002894, -267154076, 131168209}, + .iir_coef[1].coef_a={134217728, -267154076, 132953376}, + + .iir_coef[2].coef_b={132863566, -263674901, 130888668}, + .iir_coef[2].coef_a={134217728, -263674901, 129534506}, + + .iir_coef[3].coef_b={131621817, -256639526, 125746382}, + .iir_coef[3].coef_a={134217728, -256639526, 123150471}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + .anc_cfg_ff_r = { + // .total_gain = 382, + .total_gain = 288, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FF_R, + + .iir_coef[0].coef_b={42463913, -84860822, 42396935}, + .iir_coef[0].coef_a={134217728, -268353516, 134135801}, + + .iir_coef[1].coef_b={136002894, -267154076, 131168209}, + .iir_coef[1].coef_a={134217728, -267154076, 132953376}, + + .iir_coef[2].coef_b={132863566, -263674901, 130888668}, + .iir_coef[2].coef_a={134217728, -263674901, 129534506}, + + .iir_coef[3].coef_b={131621817, -256639526, 125746382}, + .iir_coef[3].coef_a={134217728, -256639526, 123150471}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + + +/* + +Filter1_B=[ 27172676, -53803459, 26691412]; +Filter1_A=[ 134217728, -214195429, 80219070]; + +Filter2_B=[ 138529480, -267551490, 129040578]; +Filter2_A=[ 134217728, -267551490, 133352330]; + +Filter3_B=[ 134516353, -268162980, 133647489]; +Filter3_A=[ 134217728, -268162980, 133946114]; + +Filter4_B=[ 133595549, -264581113, 131087955]; +Filter4_A=[ 134217728, -264581113, 130465777]; + + +*/ + + .anc_cfg_fb_l = { + .total_gain = 511, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FB_L, + + .iir_coef[0].coef_b={ 27172676, -53803459, 26691412}, + .iir_coef[0].coef_a={134217728, -214195429, 80219070}, + + .iir_coef[1].coef_b={138529480, -267551490, 129040578}, + .iir_coef[1].coef_a={134217728, -267551490, 133352330}, + + .iir_coef[2].coef_b={134516353, -268162980, 133647489}, + .iir_coef[2].coef_a={134217728, -268162980, 133946114}, + + .iir_coef[3].coef_b={133595549, -264581113, 131087955}, + .iir_coef[3].coef_a={134217728, -264581113, 130465777}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + .anc_cfg_fb_r = { + .total_gain = 511, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FB_R, + + .iir_coef[0].coef_b={ 27172676, -53803459, 26691412}, + .iir_coef[0].coef_a={134217728, -214195429, 80219070}, + + .iir_coef[1].coef_b={138529480, -267551490, 129040578}, + .iir_coef[1].coef_a={134217728, -267551490, 133352330}, + + .iir_coef[2].coef_b={134516353, -268162980, 133647489}, + .iir_coef[2].coef_a={134217728, -268162980, 133946114}, + + .iir_coef[3].coef_b={133595549, -264581113, 131087955}, + .iir_coef[3].coef_a={134217728, -264581113, 130465777}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + +#if (AUD_SECTION_STRUCT_VERSION == 2) + + +/* +1.0000000000000000,-1.5858874672928407,0.6974239598044429,0.2832267077115959,-0.3117526885614825,0.1400624733614886, +Filter1_B=[ 4751756, -5230342, 2349858]; +Filter1_A=[ 16777216, -26606777, 11700832]; + + +1.0000000000000000,-1.7971697583202608,0.8159624512785459,0.9540998606028980,-1.7971697583202608,0.8618625906756480, +Filter2_B=[ 16007139, -30151505, 14459655]; +Filter2_A=[ 16777216, -30151505, 13689578]; + + +1.0000000000000000,-1.9694050640918992,0.9705681145972464,0.3200483744622364,-0.6223829329788905,0.3034976090220014, +Filter3_B=[ 5369521, -10441853, 5091845]; +Filter3_A=[ 16777216, -33041134, 16283431]; + + +1.0000000000000000,-1.9921619776276678,0.9921812243512138,0.9968660174712476,-1.9921712178765081,0.9953059666311256, +Filter4_B=[ 16724636, -33423087, 16698463]; +Filter4_A=[ 16777216, -33422932, 16646039]; +*/ + +/* + +1.0000000000000000,-1.9868580074509832,0.9869011854430232,1.1834688902733632,-2.3614075958038656,1.1779451659756268, +Filter1_B=[ 19855313, -39617845, 19762640]; +Filter1_A=[ 16777216, -33333946, 16557454]; + + +1.0000000000000000,-1.0329261527674278,0.0418392318218667,0.5812322628931170,-1.0329261527674278,0.4606069689287498, +Filter2_B=[ 9751459, -17329625, 7727703]; +Filter2_A=[ 16777216, -17329625, 701946]; + + +1.0000000000000000,-1.9576081396140492,0.9591185490154677,1.0729914166044796,-1.9576081396140492,0.8861271324109881, +Filter3_B=[ 18001809, -32843215, 14866746]; +Filter3_A=[ 16777216, -32843215, 16091339]; + + +1.0000000000000000,-1.9197071583239940,0.9219883336398085,0.7545642546264146,-1.4392920140632206,0.6870089347526202, +Filter4_B=[ 12659487, -24147313, 11526097]; +Filter4_A=[ 16777216, -32207342, 15468397]; + + +1.0000000000000000,-1.9102108535747602,0.9139876710346515,0.9829076121866517,-1.9102108535747602,0.9310800588479999, +Filter5_B=[ 16490453, -32048020, 15620931]; +Filter5_A=[ 16777216, -32048020, 15334169]; +*/ + + + + + .anc_cfg_mc_l = { + .total_gain = 1228, + + .iir_bypass_flag=0, + .iir_counter=5, + + .iir_coef[0].coef_b={19855313, -39617845, 19762640}, + .iir_coef[0].coef_a={16777216, -33333946, 16557454}, + + .iir_coef[1].coef_b={9751459, -17329625, 7727703}, + .iir_coef[1].coef_a={16777216, -17329625, 701946}, + + .iir_coef[2].coef_b={18001809, -32843215, 14866746}, + .iir_coef[2].coef_a={16777216, -32843215, 16091339}, + + .iir_coef[3].coef_b={12659487, -24147313, 11526097}, + .iir_coef[3].coef_a={16777216, -32207342, 15468397}, + + .iir_coef[4].coef_b={16490453, -32048020, 15620931}, + .iir_coef[4].coef_a={16777216, -32048020, 15334169}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + + + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + .anc_cfg_mc_r = { + .total_gain = 1331, + + .iir_bypass_flag=0, + .iir_counter=5, + + .iir_coef[0].coef_b={19855313, -39617845, 19762640}, + .iir_coef[0].coef_a={16777216, -33333946, 16557454}, + + .iir_coef[1].coef_b={9751459, -17329625, 7727703}, + .iir_coef[1].coef_a={16777216, -17329625, 701946}, + + .iir_coef[2].coef_b={18001809, -32843215, 14866746}, + .iir_coef[2].coef_a={16777216, -32843215, 16091339}, + + .iir_coef[3].coef_b={12659487, -24147313, 11526097}, + .iir_coef[3].coef_a={16777216, -32207342, 15468397}, + + .iir_coef[4].coef_b={16490453, -32048020, 15620931}, + .iir_coef[4].coef_a={16777216, -32048020, 15334169}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + + + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, +#endif +}; + +/* +//ff + + +Filter1_B=[ 42465729, -84858529, 42392831]; +Filter1_A=[ 134217728, -268346271, 134128558]; + +Filter2_B=[ 136159949, -267039705, 130899919]; +Filter2_A=[ 134217728, -267039705, 132842140]; + +Filter3_B=[ 132746107, -263254540, 130599907]; +Filter3_A=[ 134217728, -263254540, 129128286]; + +Filter4_B=[ 131402980, -255575175, 125032243]; +Filter4_A=[ 134217728, -255575175, 122217496]; + + + +*/ + + + +static const struct_anc_cfg POSSIBLY_UNUSED AncFirCoef_44p1k_mode0 = { + .anc_cfg_ff_l = { + // .total_gain = 440, + .total_gain =312, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FF_L, + + .iir_coef[0].coef_b={42465729, -84858529, 42392831}, + .iir_coef[0].coef_a={134217728, -268346271, 134128558}, + + .iir_coef[1].coef_b={136159949, -267039705, 130899919}, + .iir_coef[1].coef_a={134217728, -267039705, 132842140}, + + .iir_coef[2].coef_b={132746107, -263254540, 130599907}, + .iir_coef[2].coef_a={134217728, -263254540, 129128286}, + + .iir_coef[3].coef_b={131402980, -255575175, 125032243}, + .iir_coef[3].coef_a={ 134217728, -255575175, 122217496}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + .anc_cfg_ff_r = { + // .total_gain = 382, + .total_gain = 288, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FF_R, + + .iir_coef[0].coef_b={42465729, -84858529, 42392831}, + .iir_coef[0].coef_a={134217728, -268346271, 134128558}, + + .iir_coef[1].coef_b={136159949, -267039705, 130899919}, + .iir_coef[1].coef_a={134217728, -267039705, 132842140}, + + .iir_coef[2].coef_b={132746107, -263254540, 130599907}, + .iir_coef[2].coef_a={134217728, -263254540, 129128286}, + + .iir_coef[3].coef_b={131402980, -255575175, 125032243}, + .iir_coef[3].coef_a={ 134217728, -255575175, 122217496}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + +/* + +Filter1_B=[ 26719020, -52852829, 26204379]; +Filter1_A=[ 134217728, -210410903, 76474119]; + +Filter2_B=[ 138909433, -267471808, 128584365]; +Filter2_A=[ 134217728, -267471808, 133276071]; + +Filter3_B=[ 134542733, -268138827, 133597115]; +Filter3_A=[ 134217728, -268138827, 133922120]; + +Filter4_B=[ 133541379, -264235686, 130815458]; +Filter4_A=[ 134217728, -264235686, 130139109]; + +*/ + + + .anc_cfg_fb_l = { + .total_gain = 511, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FB_L, + + .iir_coef[0].coef_b={26719020, -52852829, 26204379}, + .iir_coef[0].coef_a={134217728, -210410903, 76474119}, + + .iir_coef[1].coef_b={138909433, -267471808, 128584365}, + .iir_coef[1].coef_a={134217728, -267471808, 133276071}, + + .iir_coef[2].coef_b={134542733, -268138827, 133597115}, + .iir_coef[2].coef_a={134217728, -268138827, 133922120}, + + .iir_coef[3].coef_b={133541379, -264235686, 130815458}, + .iir_coef[3].coef_a={134217728, -264235686, 130139109}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + .anc_cfg_fb_r = { + .total_gain = 511, + + .iir_bypass_flag=0, + .iir_counter=IIR_COUNTER_FB_R, + + .iir_coef[0].coef_b={26719020, -52852829, 26204379}, + .iir_coef[0].coef_a={134217728, -210410903, 76474119}, + + .iir_coef[1].coef_b={138909433, -267471808, 128584365}, + .iir_coef[1].coef_a={134217728, -267471808, 133276071}, + + .iir_coef[2].coef_b={134542733, -268138827, 133597115}, + .iir_coef[2].coef_a={134217728, -268138827, 133922120}, + + .iir_coef[3].coef_b={133541379, -264235686, 130815458}, + .iir_coef[3].coef_a={134217728, -264235686, 130139109}, + + .iir_coef[4].coef_b={0x8000000,0,0}, + .iir_coef[4].coef_a={0x8000000,0,0}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + + +/* .fir_bypass_flag=1, + .fir_len = AUD_COEF_LEN, + .fir_coef = + { + 32767, + }, +*/ + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, +#if (AUD_SECTION_STRUCT_VERSION == 2) + + + +/* + +Filter1_B=[ 19847881, -39594823, 19747071]; +Filter1_A=[ 16777216, -33314517, 16538159]; + +Filter2_B=[ 9442890, -16603187, 7330251]; +Filter2_A=[ 16777216, -16603187, -4075]; + +Filter3_B=[ 18107639, -32779315, 14701642]; +Filter3_A=[ 16777216, -32779315, 16032065]; + +Filter4_B=[ 12666347, -24058210, 11437046]; +Filter4_A=[ 16777216, -32089673, 15357640]; + +Filter5_B=[ 16466312, -31915122, 15523589]; +Filter5_A=[ 16777216, -31915122, 15212684]; +*/ + + + + + .anc_cfg_mc_l = { + .total_gain = 1228, + + .iir_bypass_flag=0, + .iir_counter=5, + + .iir_coef[0].coef_b={19847881, -39594823, 19747071}, + .iir_coef[0].coef_a={16777216, -33314517, 16538159}, + + .iir_coef[1].coef_b={9442890, -16603187, 7330251}, + .iir_coef[1].coef_a={16777216, -16603187, -4075}, + + .iir_coef[2].coef_b={18107639, -32779315, 14701642}, + .iir_coef[2].coef_a={16777216, -32779315, 16032065}, + + .iir_coef[3].coef_b={12666347, -24058210, 11437046}, + .iir_coef[3].coef_a={16777216, -32089673, 15357640}, + + .iir_coef[4].coef_b={16466312, -31915122, 15523589}, + .iir_coef[4].coef_a={16777216, -31915122, 15212684}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + + + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, + .anc_cfg_mc_r = { + .total_gain = 1331, + + .iir_bypass_flag=0, + .iir_counter=5, + + .iir_coef[0].coef_b={19847881, -39594823, 19747071}, + .iir_coef[0].coef_a={16777216, -33314517, 16538159}, + + .iir_coef[1].coef_b={9442890, -16603187, 7330251}, + .iir_coef[1].coef_a={16777216, -16603187, -4075}, + + .iir_coef[2].coef_b={18107639, -32779315, 14701642}, + .iir_coef[2].coef_a={16777216, -32779315, 16032065}, + + .iir_coef[3].coef_b={12666347, -24058210, 11437046}, + .iir_coef[3].coef_a={16777216, -32089673, 15357640}, + + .iir_coef[4].coef_b={16466312, -31915122, 15523589}, + .iir_coef[4].coef_a={16777216, -31915122, 15212684}, + + .iir_coef[5].coef_b={0x8000000,0,0}, + .iir_coef[5].coef_a={0x8000000,0,0}, + + + .dac_gain_offset=0, + .adc_gain_offset=(0)*4, + }, +#endif + +}; + +const struct_anc_cfg * anc_coef_list_50p7k[ANC_COEF_LIST_NUM] = { + &AncFirCoef_50p7k_mode0, +#if (ANC_COEF_LIST_NUM == 2) + &AncFirCoef_50p7k_mode0, +#endif +#if(ANC_COEF_LIST_NUM == 3) + &AncFirCoef_50p7k_mode0, + &AncFirCoef_50p7k_mode0, +#endif +#if(ANC_COEF_LIST_NUM == 4) + &AncFirCoef_50p7k_mode0, + &AncFirCoef_50p7k_mode0, + &AncFirCoef_50p7k_mode0, +#endif +}; + +const struct_anc_cfg * anc_coef_list_48k[ANC_COEF_LIST_NUM] = { + &AncFirCoef_48k_mode0, +#if (ANC_COEF_LIST_NUM == 2) + &AncFirCoef_48k_mode0, +#endif +#if(ANC_COEF_LIST_NUM == 3) + &AncFirCoef_48k_mode0, + &AncFirCoef_48k_mode0, +#endif +#if(ANC_COEF_LIST_NUM == 4) + &AncFirCoef_48k_mode0, + &AncFirCoef_48k_mode0, + &AncFirCoef_48k_mode0, +#endif +}; + +const struct_anc_cfg * anc_coef_list_44p1k[ANC_COEF_LIST_NUM] = { + &AncFirCoef_44p1k_mode0, +#if (ANC_COEF_LIST_NUM == 2) + &AncFirCoef_44p1k_mode0, +#endif +#if(ANC_COEF_LIST_NUM == 3) + &AncFirCoef_44p1k_mode0, + &AncFirCoef_44p1k_mode0, +#endif +#if(ANC_COEF_LIST_NUM == 4) + &AncFirCoef_44p1k_mode0, + &AncFirCoef_44p1k_mode0, + &AncFirCoef_44p1k_mode0, +#endif +}; + +const IIR_CFG_T audio_eq_sw_iir_cfg = { + .gain0 = 0, + .gain1 = 0, + .num = 5, + .param = { + {IIR_TYPE_PEAK, .0, 200, 2}, + {IIR_TYPE_PEAK, .0, 600, 2}, + {IIR_TYPE_PEAK, .0, 2000.0, 2}, + {IIR_TYPE_PEAK, .0, 6000.0, 2}, + {IIR_TYPE_PEAK, .0, 12000.0, 2} + } +}; + +const IIR_CFG_T * const audio_eq_sw_iir_cfg_list[EQ_SW_IIR_LIST_NUM]={ + &audio_eq_sw_iir_cfg, +}; + +const FIR_CFG_T audio_eq_hw_fir_cfg_44p1k = { + .gain = 0.0f, + .len = 384, + .coef = + { + (1<<23)-1, + } +}; + +const FIR_CFG_T audio_eq_hw_fir_cfg_48k = { + .gain = 0.0f, + .len = 384, + .coef = + { + (1<<23)-1, + } +}; + + +const FIR_CFG_T audio_eq_hw_fir_cfg_96k = { + .gain = 0.0f, + .len = 384, + .coef = + { + (1<<23)-1, + } +}; + +const FIR_CFG_T * const audio_eq_hw_fir_cfg_list[EQ_HW_FIR_LIST_NUM]={ + &audio_eq_hw_fir_cfg_44p1k, + &audio_eq_hw_fir_cfg_48k, + &audio_eq_hw_fir_cfg_96k, +}; + +//hardware dac iir eq +const IIR_CFG_T audio_eq_hw_dac_iir_cfg = { + .gain0 = 0, + .gain1 = 0, + .num = 8, + .param = { + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + {IIR_TYPE_PEAK, 0, 1000.0, 0.7}, + } +}; + +const IIR_CFG_T * const POSSIBLY_UNUSED audio_eq_hw_dac_iir_cfg_list[EQ_HW_DAC_IIR_LIST_NUM]={ + &audio_eq_hw_dac_iir_cfg, +}; + +//hardware dac iir eq +const IIR_CFG_T audio_eq_hw_adc_iir_adc_cfg = { + .gain0 = 0, + .gain1 = 0, + .num = 1, + .param = { + {IIR_TYPE_PEAK, 0.0, 1000.0, 0.7}, + } +}; + +const IIR_CFG_T * const POSSIBLY_UNUSED audio_eq_hw_adc_iir_cfg_list[EQ_HW_ADC_IIR_LIST_NUM]={ + &audio_eq_hw_adc_iir_adc_cfg, +}; + + + +//hardware iir eq +const IIR_CFG_T audio_eq_hw_iir_cfg = { + .gain0 = 0, + .gain1 = 0, + .num = 8, + .param = { + {IIR_TYPE_PEAK, -10.1, 100.0, 7}, + {IIR_TYPE_PEAK, -10.1, 400.0, 7}, + {IIR_TYPE_PEAK, -10.1, 700.0, 7}, + {IIR_TYPE_PEAK, -10.1, 1000.0, 7}, + {IIR_TYPE_PEAK, -10.1, 3000.0, 7}, + {IIR_TYPE_PEAK, -10.1, 5000.0, 7}, + {IIR_TYPE_PEAK, -10.1, 7000.0, 7}, + {IIR_TYPE_PEAK, -10.1, 9000.0, 7}, + + } +}; + +const IIR_CFG_T * const POSSIBLY_UNUSED audio_eq_hw_iir_cfg_list[EQ_HW_IIR_LIST_NUM]={ + &audio_eq_hw_iir_cfg, +}; + +const DrcConfig audio_drc_cfg = { + .knee = 3, + .filter_type = {14, -1}, + .band_num = 2, + .look_ahead_time = 10, + .band_settings = { + {-20, 0, 2, 3, 3000, 1}, + {-20, 0, 2, 3, 3000, 1}, + } + }; + +const LimiterConfig audio_drc2_cfg = { + .knee = 2, + .look_ahead_time = 10, + .threshold = -20, + .makeup_gain = 19, + .ratio = 1000, + .attack_time = 3, + .release_time = 3000, +}; + +const SpectrumFixConfig audio_spectrum_cfg = { + .freq_num = 9, + .freq_list = {200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800}, +}; + diff --git a/config/best2300p_ibrt_anc/tgt_hardware.h b/config/best2300p_ibrt_anc/tgt_hardware.h new file mode 100644 index 0000000..e9e3555 --- /dev/null +++ b/config/best2300p_ibrt_anc/tgt_hardware.h @@ -0,0 +1,120 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __TGT_HARDWARE__ +#define __TGT_HARDWARE__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_iomux.h" +#include "hal_gpio.h" +#include "hal_key.h" +#include "hal_aud.h" + +//config hwardware codec iir. +#define EQ_HW_DAC_IIR_LIST_NUM 1 +#define EQ_HW_ADC_IIR_LIST_NUM 1 +#define EQ_HW_IIR_LIST_NUM 1 +#define EQ_SW_IIR_LIST_NUM 1 +#define EQ_HW_FIR_LIST_NUM 3 + +//pwl +#define CFG_HW_PLW_NUM (2) +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_hw_pinmux_pwl[CFG_HW_PLW_NUM]; + +//adckey define +#define CFG_HW_ADCKEY_NUMBER 0 +#define CFG_HW_ADCKEY_BASE 0 +#define CFG_HW_ADCKEY_ADC_MAXVOLT 1000 +#define CFG_HW_ADCKEY_ADC_MINVOLT 0 +#define CFG_HW_ADCKEY_ADC_KEYVOLT_BASE 130 +extern const uint16_t CFG_HW_ADCKEY_MAP_TABLE[CFG_HW_ADCKEY_NUMBER]; + +#define BTA_AV_CO_SBC_MAX_BITPOOL 52 + +//gpiokey define +#ifdef IS_MULTI_AI_ENABLED +#define CFG_HW_GPIOKEY_NUM (3) +#elif BES_AUDIO_DEV_Main_Board_9v0 +#define CFG_HW_GPIOKEY_NUM (6) +#else +#define CFG_HW_GPIOKEY_NUM (3) +#endif + + +extern const struct HAL_KEY_GPIOKEY_CFG_T cfg_hw_gpio_key_cfg[CFG_HW_GPIOKEY_NUM]; + +// ANC function key +#define ANC_FUNCTION_KEY HAL_KEY_CODE_PWR + +// ANC coefficient curve number +#define ANC_COEF_NUM (1) + +//#define ANC_TALK_THROUGH + +#ifdef ANC_TALK_THROUGH +#define ANC_COEF_LIST_NUM (ANC_COEF_NUM + 1) +#else +#define ANC_COEF_LIST_NUM (ANC_COEF_NUM) +#endif + +#define ANC_FF_MIC_CH_L AUD_CHANNEL_MAP_CH0 +#define ANC_FF_MIC_CH_R 0 +#define ANC_FB_MIC_CH_L AUD_CHANNEL_MAP_CH2 +#define ANC_FB_MIC_CH_R 0 + +#define ANC_VMIC_CFG (AUD_VMIC_MAP_VMIC3) + +// audio codec +#define CFG_HW_AUD_INPUT_PATH_NUM 4 +extern const struct AUD_IO_PATH_CFG_T cfg_audio_input_path_cfg[CFG_HW_AUD_INPUT_PATH_NUM]; + +#define CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV (AUD_CHANNEL_MAP_CH0) + +#define CFG_HW_AUD_SIDETONE_MIC_DEV (AUD_CHANNEL_MAP_CH0) +#define CFG_HW_AUD_SIDETONE_GAIN_DBVAL (-20) + +//bt config +extern const char *BT_LOCAL_NAME; +extern const char *BLE_DEFAULT_NAME; +extern uint8_t ble_addr[6]; +extern uint8_t bt_addr[6]; + +#define CODEC_SADC_VOL (12) + +extern const struct CODEC_DAC_VOL_T codec_dac_vol[TGT_VOLUME_LEVEL_QTY]; + +//range -12~+12 +#define CFG_HW_AUD_EQ_NUM_BANDS (8) +extern const int8_t cfg_aud_eq_sbc_band_settings[CFG_HW_AUD_EQ_NUM_BANDS]; +#define CFG_AUD_EQ_IIR_NUM_BANDS (4) + +//battery info +#define APP_BATTERY_MIN_MV (3200) +#define APP_BATTERY_PD_MV (3100) + +#define APP_BATTERY_MAX_MV (4200) + +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_enable_cfg; +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_detecter_cfg; +extern const struct HAL_IOMUX_PIN_FUNCTION_MAP app_battery_ext_charger_indicator_cfg; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/config/common.mk b/config/common.mk new file mode 100644 index 0000000..b4c4300 --- /dev/null +++ b/config/common.mk @@ -0,0 +1,2646 @@ + +add_if_exists = $(foreach d,$(1),$(if $(wildcard $(srctree)/$(d)),$(d) ,)) + +# ------------------------------------------- +# Macro Default Value +# ------------------------------------------- +# 1 for IBRT, 0 for stereo +export IBRT ?= 0 + +# 1 to enable BLE, 0 to disable BLE +export BLE ?= 0 + +# 1 to enable BLE security feature, 0 to disable it +export BLE_SECURITY_ENABLED ?= 0 + +export CTKD_ENABLE ?= 0 + +export TILE_DATAPATH_ENABLED ?= 0 + +export OTA_ENABLE ?= 0 + +export OTA_CODE_OFFSET ?= 0 +export OTA_UPGRADE_LOG_SIZE ?= 0 +export OTA_SUPPORT_SLAVE_BIN ?= 0 +export OTA_BOOT_SIZE ?= 0 + +# is current system a tws system +# currently in our SDK, system include relay tws and IBRT +# of if relay tws or IBRT is enabled, this macro must set to 1 +export TWS_SYSTEM_ENABLED ?= 0 + +# ai voice related configuration +export VOICE_DATAPATH_ENABLED ?= 0 + +# Google related feature +export GOOGLE_SERVICE_ENABLE ?= 0 +export BISTO_ENABLE ?= 0 +export GSOUND_HOTWORD_ENABLE ?= 0 +export GSOUND_HOTWORD_EXTERNAL ?= 0 +export GFPS_ENABLE ?= 0 + +# Amazon related feature +export AMA_VOICE ?= 0 + +# HUAWEI related feature +export INTERCONNECTION ?= 0 + +# ALI related feature +export GMA_VOICE ?= 0 + +# TENCENT related feature +export TENCENT_VOICE ?= 0 + +# BAIDU related feature +export DMA_VOICE ?= 0 + +# BES AI feature +export SMART_VOICE ?= 0 + +# other AI feature +export CUSTOMIZE_VOICE ?= 0 + +# mean to manage all AI features +export AI_VOICE ?= 0 + +# Dual mic recording feature +export DUAL_MIC_RECORDING ?= 0 +export LOWER_BANDWIDTH ?= 0 + +# 1 to support mutiple AI, 0 to disable this feature +IS_MULTI_AI_ENABLE ?= 0 + +# NOTE: This size is 0 by default, used to save the hotword model file +HOTWORD_SECTION_SIZE ?= 0x0 + +# NOTE: This size cannot be changed so that audio section address is fixed. +# This rule can be removed once audio tool can set audio section address dynamically. +FACTORY_SECTION_SIZE ?= 0x1000 + +# NOTE: This size cannot be changed so that audio section address is fixed. +# This rule can be removed once audio tool can set audio section address dynamically. +RESERVED_SECTION_SIZE ?= 0x1000 + +# 1 to enable the VAD feature, 0 to disable the VAD feature +export VOICE_DETECTOR_EN ?= 0 + +# 1 to use 8K sample rate for VAD, 0 to use 16K sample rate for VAD +VAD_USE_8K_SAMPLE_RATE ?= 0 + +# ------------------------------------------- +# Root Option Dependencies +# ------------------------------------------- +# NOTE: the value of AMA_VOICE,DMA_VOICE, SMART_VOICE, TENCENT_VOICE, GMA_VOICE, CUSTOMIZE_VOICE must be confirmed above +ifneq ($(filter 1,$(AMA_VOICE) $(DMA_VOICE) $(SMART_VOICE) $(TENCENT_VOICE) $(GMA_VOICE) $(CUSTOMIZE_VOICE) $(DUAL_MIC_RECORDING)),) +export AI_VOICE := 1 +endif + +ifeq ($(BT_ANC),1) +export ANC_APP ?= 1 +endif + +export ANC_ASSIST_ENABLED ?= 0 + +ifeq ($(GOOGLE_SERVICE_ENABLE), 1) +export BISTO_ENABLE := 1 +export GFPS_ENABLE := 1 +KBUILD_CPPFLAGS += -DOS_DYNAMIC_MEM_SIZE=0x6800 +endif + +ifeq ($(BISTO_ENABLE),1) +OTA_ENABLE := 1 +export VOICE_DATAPATH_ENABLED := 1 +export CRASH_REBOOT ?= 1 + +export BLE_SECURITY_ENABLED := 1 + +ifeq ($(CHIP),best1400) +export DUMP_CRASH_LOG ?= 0 +else +export DUMP_CRASH_LOG ?= 0 +endif + +export VOICE_DATAPATH_TYPE ?= gsound +#export TRACE_DUMP2FLASH ?= 1 +export FLASH_SUSPEND := 1 +export BLE_ONLY_ENABLED ?= 0 + +ifeq ($(GSOUND_HOTWORD_ENABLE),1) +# used to store hotword model, currently 240KB +# this value is used in link file +HOTWORD_SECTION_SIZE ?= 0x3C000 +endif +endif # ifeq ($(BISTO_ENABLE),1) + +ifeq ($(MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED),1) +AUDIO_OUTPUT_SW_GAIN ?= 1 +endif # ifeq ($(MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED),1) + +# NOTE: variable value in BLE_SWITCH must already confirmed above here +BLE_SWITCH := \ + $(BISTO_ENABLE) \ + $(GFPS_ENABLE) \ + $(AMA_VOICE) \ + $(DMA_VOICE) \ + $(GMA_VOICE) \ + $(SMART_VOICE) \ + $(TENCENT_VOICE) \ + $(CUSTOMIZE_VOICE) \ + $(TILE_DATAPATH_ENABLED) \ + $(BLE_ONLY_ENABLED) + +ifneq ($(filter 1, $(BLE_SWITCH)),) +export BLE := 1 +endif + +# NOTE: value of AI_VOICE and BISTO_ENABLE must already confirmed above here +ifeq ($(filter 0,$(AI_VOICE) $(BISTO_ENABLE)),) +IS_MULTI_AI_ENABLE := 1 +endif + +ifeq ($(VOICE_PROMPT),1) +KBUILD_CPPFLAGS += -DMEDIA_PLAYER_SUPPORT +endif + +ifeq ($(INTERCONNECTION),1) +OTA_ENABLE := 1 +endif + +ifeq ($(GMA_VOICE),1) +OTA_ENABLE := 1 +endif + +ifeq ($(IBRT),1) +TWS_SYSTEM_ENABLED := 1 +endif + +MIX_MIC_DURING_MUSIC_ENABLED ?= 0 + +# make sure the value of GFPS_ENABLE and GMA_VOICE is confirmed above here +ifneq ($(filter 1,$(GFPS_ENABLE) $(GMA_VOICE) $(TOTA)),) +core-y += utils/encrypt/ +endif + +ifneq ($(filter 1,$(TOTA)),) +core-y += utils/sha256/ +endif + +ifneq ($(filter apps/ tests/speech_test/ tests/ota_boot/, $(core-y)),) +export BT_APP ?= 1 +FULL_APP_PROJECT ?= 1 +endif + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# OTA features +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(OTA_ENABLE),1) + +ifeq ($(FPGA),1) +OTA_CODE_OFFSET := 0 +else +OTA_CODE_OFFSET := 0x18000 +endif + +OTA_UPGRADE_LOG_SIZE := 0x1000 +OTA_SUPPORT_SLAVE_BIN := 0 + +KBUILD_CPPFLAGS += -DOTA_ENABLED +KBUILD_CPPFLAGS += -DBES_OTA_BASIC + +KBUILD_CPPFLAGS += -D__APP_IMAGE_FLASH_OFFSET__=$(OTA_CODE_OFFSET) +KBUILD_CPPFLAGS += -DNEW_IMAGE_FLASH_OFFSET=0x200000 +KBUILD_CPPFLAGS += -DFIRMWARE_REV + +ifeq ($(IBRT), 1) +export FORCE_SCO_MAX_RETX := 0 +KBUILD_CPPFLAGS += -DIBRT_OTA +endif +endif + +# ------------------------------------------- +# CHIP selection +# ------------------------------------------- + +export CHIP + +ifneq (,) +else ifeq ($(CHIP),best1000) +KBUILD_CPPFLAGS += -DCHIP_BEST1000 +CPU := m4 +export CHIP_HAS_FPU := 1 +export CHIP_HAS_USB := 1 +export CHIP_HAS_USBPHY := 0 +export CHIP_HAS_SDMMC := 1 +export CHIP_HAS_SDIO := 1 +export CHIP_HAS_PSRAM := 1 +export CHIP_HAS_SPI := 1 +export CHIP_HAS_SPILCD := 1 +export CHIP_HAS_SPIPHY := 0 +export CHIP_HAS_I2C := 1 +export CHIP_HAS_UART := 2 +export CHIP_HAS_DMA := 2 +export CHIP_HAS_SPDIF := 1 +export CHIP_HAS_TRANSQ := 0 +export CHIP_HAS_EXT_PMU := 0 +export CHIP_HAS_AUDIO_CONST_ROM := 1 +export CHIP_FLASH_CTRL_VER := 1 +export CHIP_PSRAM_CTRL_VER := 1 +export CHIP_SPI_VER := 1 +export CHIP_HAS_EC_CODEC_REF := 0 +export CHIP_HAS_SCO_DMA_SNAPSHOT := 0 +export CHIP_ROM_UTILS_VER := 1 +export NO_LPU_26M ?= 1 +else ifeq ($(CHIP),best1400) +ifeq ($(CHIP_SUBTYPE),best1402) +SUBTYPE_VALID := 1 +KBUILD_CPPFLAGS += -DCHIP_BEST1402 +export CHIP_FLASH_CTRL_VER := 3 +else +KBUILD_CPPFLAGS += -DCHIP_BEST1400 +export CHIP_FLASH_CTRL_VER := 2 +endif +CPU := m4 +export CHIP_HAS_FPU := 1 +export CHIP_HAS_USB := 1 +export CHIP_HAS_USBPHY := 0 +export CHIP_HAS_SDMMC := 0 +export CHIP_HAS_SDIO := 0 +export CHIP_HAS_PSRAM := 0 +export CHIP_HAS_SPI := 1 +export CHIP_HAS_SPILCD := 0 +export CHIP_HAS_SPIPHY := 0 +export CHIP_HAS_I2C := 1 +export CHIP_HAS_UART := 3 +export CHIP_HAS_DMA := 1 +export CHIP_HAS_SPDIF := 0 +export CHIP_HAS_TRANSQ := 0 +export CHIP_HAS_EXT_PMU := 0 +export CHIP_HAS_AUDIO_CONST_ROM := 0 +export CHIP_SPI_VER := 3 +export BTDUMP_ENABLE := 1 +export CHIP_HAS_EC_CODEC_REF := 1 +export CHIP_HAS_SCO_DMA_SNAPSHOT := 1 +export CHIP_ROM_UTILS_VER := 1 +export NO_LPU_26M ?= 1 +else ifeq ($(CHIP),best2000) +KBUILD_CPPFLAGS += -DCHIP_BEST2000 +CPU := m4 +export CHIP_HAS_FPU := 1 +export CHIP_HAS_USB := 1 +export CHIP_HAS_USBPHY := 1 +export CHIP_HAS_SDMMC := 1 +export CHIP_HAS_SDIO := 1 +export CHIP_HAS_PSRAM := 1 +export CHIP_HAS_SPI := 1 +export CHIP_HAS_SPILCD := 1 +export CHIP_HAS_SPIPHY := 1 +export CHIP_HAS_I2C := 1 +export CHIP_HAS_UART := 3 +export CHIP_HAS_DMA := 2 +export CHIP_HAS_SPDIF := 2 +export CHIP_HAS_TRANSQ := 1 +export CHIP_HAS_PSC := 1 +export CHIP_HAS_EXT_PMU := 0 +export CHIP_HAS_AUDIO_CONST_ROM := 0 +export CHIP_FLASH_CTRL_VER := 1 +export CHIP_PSRAM_CTRL_VER := 1 +export CHIP_SPI_VER := 1 +export CHIP_HAS_EC_CODEC_REF := 0 +export CHIP_HAS_SCO_DMA_SNAPSHOT := 0 +export CHIP_ROM_UTILS_VER := 1 +export NO_LPU_26M ?= 1 +else ifeq ($(CHIP),best2001) +KBUILD_CPPFLAGS += -DCHIP_BEST2001 +ifeq ($(CHIP_SUBSYS),dsp) +KBUILD_CPPFLAGS += -DCHIP_BEST2001_DSP +CPU := a7 +DSP_ENABLE ?= 1 +else +CPU := m33 +export CHIP_HAS_CP := 1 +endif +export CHIP_HAS_FPU := 1 +export CHIP_HAS_USB := 1 +export CHIP_HAS_USBPHY := 1 +export CHIP_HAS_SDMMC := 1 +export CHIP_HAS_SDIO := 0 +export CHIP_HAS_PSRAM := 1 +export CHIP_HAS_PSRAMUHS := 1 +export CHIP_HAS_SPI := 1 +export CHIP_HAS_SPILCD := 1 +export CHIP_HAS_SPIPHY := 1 +export CHIP_HAS_SPIDPD := 1 +export CHIP_HAS_I2C := 2 +export CHIP_HAS_UART := 3 +ifeq ($(DSP_ENABLE), 1) +export DSP_USE_AUDMA ?= 1 +ifeq ($(LARGE_RAM), 1) +$(error LARGE_RAM conflicts with DSP_ENABLE) +endif +endif +ifeq ($(DSP_USE_AUDMA), 1) +export CHIP_HAS_DMA := 1 +KBUILD_CPPFLAGS += -DDSP_USE_AUDMA +else +ifeq ($(CHIP_SUBSYS),dsp) +export CHIP_HAS_DMA := 0 +else +export CHIP_HAS_DMA := 2 +endif +endif +export CHIP_HAS_SPDIF := 1 +export CHIP_HAS_TRANSQ := 2 +export CHIP_HAS_TRNG := 1 +export CHIP_HAS_EXT_PMU := 0 +export CHIP_HAS_AUDIO_CONST_ROM := 0 +export CHIP_FLASH_CTRL_VER := 3 +export CHIP_PSRAM_CTRL_VER := 2 +export CHIP_SPI_VER := 4 +export CHIP_CACHE_VER := 2 +export CHIP_HAS_EC_CODEC_REF := 1 +export CHIP_HAS_SCO_DMA_SNAPSHOT := 1 +export CHIP_ROM_UTILS_VER := 1 +export NO_LPU_26M ?= 1 +export FLASH_SIZE ?= 0x1000000 +export OSC_26M_X4_AUD2BB := 0 +export USB_USE_USBPLL := 1 +export A7_DSP_SPEED ?= 1100 +#780:780M, 1000:1G, 1100:1.1G +else ifeq ($(CHIP),best2300) +KBUILD_CPPFLAGS += -DCHIP_BEST2300 +CPU := m4 +export CHIP_HAS_FPU := 1 +export CHIP_HAS_USB := 1 +export CHIP_HAS_USBPHY := 1 +export CHIP_HAS_SDMMC := 1 +export CHIP_HAS_SDIO := 0 +export CHIP_HAS_PSRAM := 0 +export CHIP_HAS_SPI := 1 +export CHIP_HAS_SPILCD := 1 +export CHIP_HAS_SPIPHY := 1 +export CHIP_HAS_I2C := 2 +export CHIP_HAS_UART := 3 +export CHIP_HAS_DMA := 2 +export CHIP_HAS_I2S := 1 +export CHIP_HAS_SPDIF := 1 +export CHIP_HAS_TRANSQ := 0 +export CHIP_HAS_PSC := 1 +export CHIP_HAS_EXT_PMU := 1 +export CHIP_HAS_AUDIO_CONST_ROM := 0 +export CHIP_FLASH_CTRL_VER := 2 +export CHIP_SPI_VER := 2 +export CHIP_HAS_EC_CODEC_REF := 0 +export CHIP_HAS_SCO_DMA_SNAPSHOT := 0 +export CHIP_ROM_UTILS_VER := 1 +export NO_LPU_26M ?= 1 +else ifeq ($(CHIP),best2300a) +KBUILD_CPPFLAGS += -DCHIP_BEST2300A +CPU := m33 +LIBC_ROM := 0 +CRC32_ROM := 0 +SHA256_ROM := 0 +export LIBC_OVERRIDE ?= 1 +export CHIP_HAS_FPU := 1 +export CHIP_HAS_USB := 1 +export CHIP_HAS_USBPHY := 1 +export CHIP_HAS_SDMMC := 1 +export CHIP_HAS_SDIO := 0 +export CHIP_HAS_PSRAM := 0 +export CHIP_HAS_SPI := 1 +export CHIP_HAS_SPILCD := 1 +export CHIP_HAS_SPIPHY := 1 +export CHIP_HAS_I2C := 3 +export CHIP_HAS_UART := 3 +export CHIP_HAS_DMA := 2 +export CHIP_HAS_I2S := 2 +export CHIP_HAS_TDM := 2 +export CHIP_HAS_SPDIF := 1 +export CHIP_HAS_TRANSQ := 0 +export CHIP_HAS_PSC := 1 +export CHIP_HAS_EXT_PMU := 1 +export CHIP_HAS_CP := 1 +export CHIP_HAS_AUDIO_CONST_ROM := 0 +export CHIP_FLASH_CTRL_VER := 3 +export CHIP_SPI_VER := 4 +export CHIP_CACHE_VER := 2 +export CHIP_RAM_BOOT := 1 +export CHIP_HAS_EC_CODEC_REF := 1 +export CHIP_HAS_SCO_DMA_SNAPSHOT := 1 +export CHIP_HAS_HW_SMOOTHING_GAIN := 1 +export CHIP_ROM_UTILS_VER := 1 +export NO_LPU_26M ?= 1 +else ifeq ($(CHIP),best2300p) +KBUILD_CPPFLAGS += -DCHIP_BEST2300P +CPU := m4 +export CHIP_HAS_FPU := 1 +export CHIP_HAS_USB := 1 +export CHIP_HAS_USBPHY := 1 +export CHIP_HAS_SDMMC := 1 +export CHIP_HAS_SDIO := 0 +export CHIP_HAS_PSRAM := 0 +export CHIP_HAS_SPI := 1 +export CHIP_HAS_SPILCD := 1 +export CHIP_HAS_SPIPHY := 1 +export CHIP_HAS_I2C := 2 +export CHIP_HAS_UART := 3 +export CHIP_HAS_DMA := 2 +export CHIP_HAS_I2S := 2 +export CHIP_HAS_TDM := 2 +export CHIP_HAS_SPDIF := 1 +export CHIP_HAS_TRANSQ := 0 +export CHIP_HAS_PSC := 1 +export CHIP_HAS_EXT_PMU := 1 +export CHIP_HAS_CP := 1 +export CHIP_HAS_AUDIO_CONST_ROM := 0 +export CHIP_FLASH_CTRL_VER := 2 +export CHIP_SPI_VER := 3 +export CHIP_CACHE_VER := 2 +export CHIP_HAS_EC_CODEC_REF := 1 +export CHIP_HAS_SCO_DMA_SNAPSHOT := 1 +export CHIP_ROM_UTILS_VER := 1 +export NO_LPU_26M ?= 1 +else ifeq ($(CHIP),best3001) +ifeq ($(CHIP_SUBTYPE),best3005) +SUBTYPE_VALID := 1 +KBUILD_CPPFLAGS += -DCHIP_BEST3005 +export CHIP_CACHE_VER := 2 +export CHIP_FLASH_CTRL_VER := 2 +else +KBUILD_CPPFLAGS += -DCHIP_BEST3001 +export CHIP_FLASH_CTRL_VER := 1 +endif +CPU := m4 +export CHIP_HAS_FPU := 1 +export CHIP_HAS_USB := 1 +export CHIP_HAS_USBPHY := 1 +export CHIP_HAS_SDMMC := 0 +export CHIP_HAS_SDIO := 0 +export CHIP_HAS_PSRAM := 0 +export CHIP_HAS_SPI := 1 +export CHIP_HAS_SPILCD := 0 +export CHIP_HAS_SPIPHY := 0 +export CHIP_HAS_I2C := 1 +export CHIP_HAS_UART := 2 +export CHIP_HAS_DMA := 1 +export CHIP_HAS_SPDIF := 1 +export CHIP_HAS_TRANSQ := 0 +export CHIP_HAS_EXT_PMU := 0 +export CHIP_HAS_AUDIO_CONST_ROM := 0 +export CHIP_SPI_VER := 3 +export CHIP_HAS_EC_CODEC_REF := 0 +export CHIP_HAS_SCO_DMA_SNAPSHOT := 0 +export CHIP_ROM_UTILS_VER := 1 +export NO_LPU_26M ?= 1 +else ifeq ($(CHIP),best3003) +KBUILD_CPPFLAGS += -DCHIP_BEST3003 +CPU := m33 +export CHIP_HAS_FPU := 1 +export CHIP_HAS_USB := 1 +export CHIP_HAS_USBPHY := 1 +export CHIP_HAS_SDMMC := 0 +export CHIP_HAS_SDIO := 0 +export CHIP_HAS_PSRAM := 0 +export CHIP_HAS_SPI := 1 +export CHIP_HAS_SPILCD := 0 +export CHIP_HAS_SPIPHY := 0 +export CHIP_HAS_I2C := 1 +export CHIP_HAS_UART := 2 +export CHIP_HAS_DMA := 2 +export CHIP_HAS_SPDIF := 1 +export CHIP_HAS_TRANSQ := 0 +export CHIP_HAS_EXT_PMU := 0 +export CHIP_HAS_AUDIO_CONST_ROM := 0 +export CHIP_CACHE_VER := 2 +export CHIP_FLASH_CTRL_VER := 2 +export CHIP_SPI_VER := 4 +export CHIP_HAS_DCO ?= 1 +export NO_LPU_26M ?= 1 +else ifeq ($(CHIP),fpga1000) +KBUILD_CPPFLAGS += -DCHIP_FPGA1000 +KBUILD_CPPFLAGS += -DCHIP_BEST1000 +CPU := m4 +export CHIP_HAS_FPU := 1 +export CHIP_HAS_USB := 1 +export CHIP_HAS_USBPHY := 0 +export CHIP_HAS_SDMMC := 1 +export CHIP_HAS_SDIO := 1 +export CHIP_HAS_PSRAM := 1 +export CHIP_HAS_SPI := 1 +export CHIP_HAS_SPILCD := 1 +export CHIP_HAS_SPIPHY := 0 +export CHIP_HAS_I2C := 1 +export CHIP_HAS_UART := 2 +export CHIP_HAS_DMA := 2 +export CHIP_INTERSYS_VER := 2 +export CHIP_HAS_SPDIF := 1 +export CHIP_HAS_TRANSQ := 0 +export CHIP_HAS_EXT_PMU := 0 +export CHIP_HAS_AUDIO_CONST_ROM := 1 +export CHIP_FLASH_CTRL_VER := 1 +export CHIP_PSRAM_CTRL_VER := 1 +export CHIP_SPI_VER := 1 +export CHIP_HAS_EC_CODEC_REF := 0 +export CHIP_HAS_SCO_DMA_SNAPSHOT := 0 +export CHIP_ROM_UTILS_VER := 1 +export NO_LPU_26M ?= 1 +else +$(error Invalid CHIP: $(CHIP)) +endif + +ifneq ($(CHIP_SUBTYPE),) +ifneq ($(SUBTYPE_VALID),1) +$(error Invalid CHIP_SUBTYPE=$(CHIP_SUBTYPE) for CHIP=$(CHIP)) +endif +export CHIP_SUBTYPE +endif + +ifeq ($(CPU),) +CPU := m33 +endif +export CPU + +ifneq ($(filter a%,$(CPU)),) +# Override lds file +LDS_FILE := armca.lds + +ifeq ($(GEN_BOOT_SECTION),1) +CPPFLAGS_${LDS_FILE} += -DGEN_BOOT_SECTION +endif + +ifeq ($(EXEC_IN_RAM),1) +CPPFLAGS_${LDS_FILE} += -DEXEC_IN_RAM +else ifeq ($(EXEC_IN_PSRAM),1) +CPPFLAGS_${LDS_FILE} += -DEXEC_IN_PSRAM +endif +endif + +export FLASH_SIZE ?= 0x100000 +ifeq ($(CHIP_HAS_PSRAM),1) +export PSRAM_SIZE ?= 0x400000 +export PSRAM_ENABLE ?= 0 +export PSRAM_SPEED ?= 200 +#166:166M, 200:200M +endif +ifeq ($(CHIP_HAS_PSRAMUHS),1) +export PSRAMUHS_ENABLE ?= 0 +export PSRAMUHS_SPEED ?= 1000 +#400:400M, 600:600M, 800:800M, 900:900M, 1000:1G +ifeq ($(PSRAMUHS_DUAL_8BIT), 1) +export PSRAMUHS_SIZE ?= 0x1000000 +ifeq ($(PSRAMUHS_DUAL_SWITCH), 1) +$(error PSRAMUHS_DUAL_8BIT conflicts with PSRAMUHS_DUAL_SWITCH) +endif +endif +export PSRAMUHS_SIZE ?= 0x800000 +endif + +KBUILD_CPPFLAGS += -DCHIP_HAS_UART=$(CHIP_HAS_UART) +KBUILD_CPPFLAGS += -DCHIP_HAS_I2C=$(CHIP_HAS_I2C) + +ifeq ($(CHIP_HAS_USB),1) +KBUILD_CPPFLAGS += -DCHIP_HAS_USB +endif + +ifneq ($(CHIP_HAS_TRANSQ),0) +KBUILD_CPPFLAGS += -DCHIP_HAS_TRANSQ=$(CHIP_HAS_TRANSQ) +endif + +ifeq ($(CHIP_HAS_CP),1) +KBUILD_CPPFLAGS += -DCHIP_HAS_CP +endif + +ifeq ($(CHIP_HAS_AUDIO_CONST_ROM),1) +KBUILD_CPPFLAGS += -DCHIP_HAS_AUDIO_CONST_ROM +endif + +ifeq ($(CHIP_HAS_HW_SMOOTHING_GAIN),1) +KBUILD_CPPFLAGS += -DHW_SUPPORT_SMOOOTHING_GAIN +endif + +ifeq ($(MCU_SLEEP_POWER_DOWN),1) +KBUILD_CPPFLAGS += -DMCU_SLEEP_POWER_DOWN +endif + +ifeq ($(USB_AUDIO_APP),1) +ifneq ($(BTUSB_AUDIO_MODE),1) +NO_OVERLAY ?= 1 +endif +endif +export NO_OVERLAY +ifeq ($(NO_OVERLAY),1) +KBUILD_CPPFLAGS += -DNO_OVERLAY +endif + +ifneq ($(ROM_SIZE),) +KBUILD_CPPFLAGS += -DROM_SIZE=$(ROM_SIZE) +endif + +ifneq ($(RAM_SIZE),) +KBUILD_CPPFLAGS += -DRAM_SIZE=$(RAM_SIZE) +endif + +ifeq ($(AUDIO_SECTION_ENABLE),1) +KBUILD_CPPFLAGS += -DAUDIO_SECTION_ENABLE +# depend on length of (ANC + AUDIO + SPEECH) in aud_section.c +AUD_SECTION_SIZE ?= 0x8000 +ifeq ($(ANC_APP),1) +$(error Can not enable AUDIO_SECTION_ENABLE and ANC_APP together) +endif +endif + +ifeq ($(ANC_APP),1) +ifeq ($(CHIP),best1000) +AUD_SECTION_SIZE ?= 0x8000 +else +AUD_SECTION_SIZE ?= 0x10000 +endif +ifeq ($(ANC_FB_CHECK),1) +KBUILD_CPPFLAGS += -DANC_FB_CHECK +endif +else +AUD_SECTION_SIZE ?= 0 +endif + +ifeq ($(TWS),1) +LARGE_RAM ?= 1 +endif + +USERDATA_SECTION_SIZE ?= 0x1000 + +FACTORY_SECTION_SIZE ?= 0x1000 + +LHDC_LICENSE_SECTION_SIZE ?= 0x1000 + +export DUMP_NORMAL_LOG ?= 0 +ifeq ($(DUMP_NORMAL_LOG),1) +ifeq ($(FLASH_SIZE),0x40000) # 2M bits +LOG_DUMP_SECTION_SIZE ?= 0x4000 +endif +ifeq ($(FLASH_SIZE),0x80000) # 4M bits +LOG_DUMP_SECTION_SIZE ?= 0x8000 +endif +ifeq ($(FLASH_SIZE),0x100000) # 8M bits +LOG_DUMP_SECTION_SIZE ?= 0x10000 +endif +ifeq ($(FLASH_SIZE),0x200000) # 16M bits +LOG_DUMP_SECTION_SIZE ?= 0x80000 +endif +ifeq ($(FLASH_SIZE),0x400000) # 32M bits +LOG_DUMP_SECTION_SIZE ?= 0x200000 +endif +ifeq ($(FLASH_SIZE),0x800000) # 64M bits +LOG_DUMP_SECTION_SIZE ?= 0x400000 +endif +KBUILD_CPPFLAGS += -DDUMP_LOG_ENABLE +else +LOG_DUMP_SECTION_SIZE ?= 0 +endif + +APP_USE_LED_INDICATE_IBRT_STATUS ?= 0 +ifeq ($(APP_USE_LED_INDICATE_IBRT_STATUS),1) +KBUILD_CPPFLAGS += -D__APP_USE_LED_INDICATE_IBRT_STATUS__ +endif + +ifeq ($(DUMP_CRASH_LOG),1) +CRASH_DUMP_SECTION_SIZE ?= 0x4000 +KBUILD_CPPFLAGS += -DDUMP_CRASH_ENABLE +else +CRASH_DUMP_SECTION_SIZE ?= 0 +endif + +export CORE_DUMP_TO_FLASH ?= 0 +ifeq ($(CORE_DUMP_TO_FLASH),1) +CORE_DUMP_SECTION_SIZE ?= 0x100000 +KBUILD_CPPFLAGS += -DCORE_DUMP_TO_FLASH +else +CORE_DUMP_SECTION_SIZE ?= 0 +endif + +CUSTOM_PARAMETER_SECTION_SIZE ?= 0x1000 + +export LDS_SECTION_FLAGS := \ + -DHOTWORD_SECTION_SIZE=$(HOTWORD_SECTION_SIZE) \ + -DCORE_DUMP_SECTION_SIZE=$(CORE_DUMP_SECTION_SIZE) \ + -DOTA_UPGRADE_LOG_SIZE=$(OTA_UPGRADE_LOG_SIZE) \ + -DLOG_DUMP_SECTION_SIZE=$(LOG_DUMP_SECTION_SIZE) \ + -DCRASH_DUMP_SECTION_SIZE=$(CRASH_DUMP_SECTION_SIZE) \ + -DCUSTOM_PARAMETER_SECTION_SIZE=$(CUSTOM_PARAMETER_SECTION_SIZE) \ + -DLHDC_LICENSE_SECTION_SIZE=$(LHDC_LICENSE_SECTION_SIZE) \ + -DUSERDATA_SECTION_SIZE=$(USERDATA_SECTION_SIZE) \ + -DAUD_SECTION_SIZE=$(AUD_SECTION_SIZE) \ + -DRESERVED_SECTION_SIZE=$(RESERVED_SECTION_SIZE) \ + -DFACTORY_SECTION_SIZE=$(FACTORY_SECTION_SIZE) + +CPPFLAGS_${LDS_FILE} += \ + -DLINKER_SCRIPT \ + -DFLASH_SIZE=$(FLASH_SIZE) \ + -Iplatform/hal + +CPPFLAGS_${LDS_FILE} += $(LDS_SECTION_FLAGS) + +ifneq ($(PSRAM_SIZE),) +CPPFLAGS_${LDS_FILE} +=-DPSRAM_SIZE=$(PSRAM_SIZE) +endif + +ifneq ($(PSRAMUHS_SIZE),) +CPPFLAGS_${LDS_FILE} +=-DPSRAMUHS_SIZE=$(PSRAMUHS_SIZE) +endif + +ifneq ($(OTA_BOOT_SIZE), 0) +CPPFLAGS_${LDS_FILE} += -DOTA_BOOT_SIZE=$(OTA_BOOT_SIZE) +endif + +CPPFLAGS_${LDS_FILE} += -DOTA_CODE_OFFSET=$(OTA_CODE_OFFSET) + +ifneq ($(OTA_REMAP_OFFSET),) +CPPFLAGS_${LDS_FILE} += -DOTA_REMAP_OFFSET=$(OTA_REMAP_OFFSET) +endif + +ifneq ($(FLASH_REGION_SIZE),) +CPPFLAGS_${LDS_FILE} += -DFLASH_REGION_SIZE=$(FLASH_REGION_SIZE) +endif + +ifneq ($(SLAVE_BIN_FLASH_OFFSET),) +export SLAVE_BIN_FLASH_OFFSET +CPPFLAGS_${LDS_FILE} += -DSLAVE_BIN_FLASH_OFFSET=$(SLAVE_BIN_FLASH_OFFSET) +endif + +ifeq ($(BOOT_CODE_IN_RAM),1) +CPPFLAGS_${LDS_FILE} += -DBOOT_CODE_IN_RAM +endif + +ifeq ($(GSOUND_HOTWORD_EXTERNAL),1) +CPPFLAGS_${LDS_FILE} += -DGSOUND_HOTWORD_EXTERNAL +endif + +ifeq ($(LARGE_RAM),1) +KBUILD_CPPFLAGS += -DLARGE_RAM +endif + +ifeq ($(CHIP_HAS_EXT_PMU),1) +export PMU_IRQ_UNIFIED ?= 1 +endif + +# ------------------------------------------- +# Standard C library +# ------------------------------------------- + +export NOSTD +export LIBC_ROM + +ifeq ($(NOSTD),1) + +ifeq ($(MBED),1) +$(error Invalid configuration: MBED needs standard C library support) +endif +ifeq ($(RTOS),1) +$(error Invalid configuration: RTOS needs standard C library support) +endif + +ifneq ($(NO_LIBC),1) +core-y += utils/libc/ +endif + +SPECS_CFLAGS := + +LIB_LDFLAGS := $(filter-out -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys,$(LIB_LDFLAGS)) + +KBUILD_CPPFLAGS += -ffreestanding -Iutils/libc/inc +ifeq ($(TOOLCHAIN),armclang) +# 1) Avoid -nostdinc +# CMSIS header files need arm_compat.h, which is one of toolchain's standard header files +# 2) Always -nostdlib for compiling C/C++ files +# Never convert standard API calls to non-standard library calls, but just emit standard API calls +# 3) Avoid -nostdlib for linking final image +# Some 64-bit calculations and math functions need toolchain's standard library +KBUILD_CPPFLAGS += -nostdlib +else +KBUILD_CPPFLAGS += -nostdinc +CFLAGS_IMAGE += -nostdlib +endif + +KBUILD_CPPFLAGS += -DNOSTD + +else # NOSTD != 1 + +ifeq ($(LIBC_ROM),1) +core-y += utils/libc/ +endif + +ifeq ($(TOOLCHAIN),armclang) +LIB_LDFLAGS := $(filter-out -lsupc++,$(LIB_LDFLAGS)) +else +SPECS_CFLAGS := --specs=nano.specs + +LIB_LDFLAGS += -lm -lc -lgcc -lnosys +endif + +endif # NOSTD != 1 + +# ------------------------------------------- +# RTOS library +# ------------------------------------------- + +export RTOS + +ifeq ($(RTOS),1) + +ifeq ($(CPU),m4) +KERNEL ?= RTX +else +KERNEL ?= RTX5 +ifeq ($(KERNEL),RTX) +$(error RTX doesn't support $(CPU)) +endif +endif + +export KERNEL + +VALID_KERNEL_LIST := RTX RTX5 FREERTOS + +ifeq ($(filter $(VALID_KERNEL_LIST),$(KERNEL)),) +$(error Bad KERNEL=$(KERNEL). Valid values are: $(VALID_KERNEL_LIST)) +endif + +core-y += rtos/ + +KBUILD_CPPFLAGS += -DRTOS +KBUILD_CPPFLAGS += -DKERNEL_$(KERNEL) + +ifeq ($(KERNEL),RTX) +KBUILD_CPPFLAGS += \ + -Iinclude/rtos/rtx/ +KBUILD_CPPFLAGS += -D__RTX_CPU_STATISTICS__=1 +#KBUILD_CPPFLAGS += -DTASK_HUNG_CHECK_ENABLED=1 +else ifeq ($(KERNEL),RTX5) +OS_IDLESTKSIZE ?= 1024 +KBUILD_CPPFLAGS += \ + -Iinclude/rtos/rtx5/ +KBUILD_CPPFLAGS += -D__RTX_CPU_STATISTICS__=1 +#KBUILD_CPPFLAGS += -DTASK_HUNG_CHECK_ENABLED=1 +else #!rtx +ifeq ($(KERNEL),FREERTOS) +KBUILD_CPPFLAGS += \ + -Iinclude/rtos/freertos/ +endif #freertos +endif #rtx + +ifeq ($(BLE),0) +KBUILD_CPPFLAGS += -DBESBT_STACK_SIZE=1024*5+512 +else +KBUILD_CPPFLAGS += -DBESBT_STACK_SIZE=1024*8+512 +endif + +ifeq ($(BLE_SECURITY_ENABLED), 1) +KBUILD_CPPFLAGS += -DCFG_APP_SEC +endif + +ifeq ($(TWS),1) +OS_TASKCNT ?= 12 +OS_SCHEDULERSTKSIZE ?= 768 +OS_IDLESTKSIZE ?= 512 +else +OS_TASKCNT ?= 20 +OS_SCHEDULERSTKSIZE ?= 512 +OS_IDLESTKSIZE ?= 256 +endif + +ifeq ($(CPU),m33) +OS_CLOCK_NOMINAL ?= 16000 +else +OS_CLOCK_NOMINAL ?= 32000 +endif +OS_FIFOSZ ?= 24 + +export OS_TASKCNT +export OS_SCHEDULERSTKSIZE +export OS_IDLESTKSIZE +export OS_CLOCK_NOMINAL +export OS_FIFOSZ + +endif + +# ------------------------------------------- +# MBED library +# ------------------------------------------- + +export MBED + +ifeq ($(MBED),1) + +core-y += mbed/ + +KBUILD_CPPFLAGS += -DMBED + +KBUILD_CPPFLAGS += \ + -Imbed/api \ + -Imbed/common \ + +endif + +# ------------------------------------------- +# DEBUG functions +# ------------------------------------------- + +export DEBUG + +ifeq ($(CHIP),best1400) +OPT_LEVEL ?= s +endif + +ifneq ($(OPT_LEVEL),) +KBUILD_CFLAGS += -O$(OPT_LEVEL) +else +KBUILD_CFLAGS += -O2 +endif + +ifeq ($(DEBUG),1) + +KBUILD_CPPFLAGS += -DDEBUG + +ifneq ($(NOSTD),1) +KBUILD_CFLAGS += -fstack-protector-strong +endif + +else + +KBUILD_CPPFLAGS += -DNDEBUG + +REL_TRACE_ENABLE ?= 1 +ifeq ($(REL_TRACE_ENABLE),1) +KBUILD_CPPFLAGS += -DREL_TRACE_ENABLE +endif + +endif + +ifeq ($(NO_CHK_TRC_FMT),1) +KBUILD_CPPFLAGS += -DNO_CHK_TRC_FMT +else +# Typedef int32_t to int, and typedef uint32_t to unsigned int +KBUILD_CPPFLAGS += -U__INT32_TYPE__ -D__INT32_TYPE__=int -U__UINT32_TYPE__ +endif + +ifeq ($(MERGE_CONST),1) +ifeq ($(TOOLCHAIN),armclang) +$(error MERGE_CONST is not supported in $(TOOLCHAIN)) +else +KBUILD_CPPFLAGS += -fmerge-constants -fmerge-all-constants +endif +endif + +export CORE_DUMP ?= 0 +ifeq ($(CORE_DUMP),1) +core-y += utils/crash_catcher/ utils/xyzmodem/ +endif + +# ------------------------------------------- +# SIMU functions +# ------------------------------------------- + +export SIMU + +ifeq ($(SIMU),1) + +KBUILD_CPPFLAGS += -DSIMU + +endif + +# ------------------------------------------- +# FPGA functions +# ------------------------------------------- + +export FPGA + +ifeq ($(FPGA),1) + +KBUILD_CPPFLAGS += -DFPGA + +endif + +# ------------------------------------------- +# ROM_BUILD functions +# ------------------------------------------- + +export ROM_BUILD + +ifeq ($(ROM_BUILD),1) + +KBUILD_CPPFLAGS += -DROM_BUILD + +endif + +# Limit the length of REVISION_INFO if ROM_BUILD or using rom.lds +ifneq ($(filter 1,$(ROM_BUILD))$(filter rom.lds,$(LDS_FILE)),) +ifeq ($(CHIP),best1000) +REVISION_INFO := x +else +REVISION_INFO := $(GIT_REVISION) +endif +endif + +# ------------------------------------------- +# PROGRAMMER functions +# ------------------------------------------- + +export PROGRAMMER + +ifeq ($(PROGRAMMER),1) + +KBUILD_CPPFLAGS += -DPROGRAMMER + +endif + +# ------------------------------------------- +# ROM_UTILS functions +# ------------------------------------------- + +export ROM_UTILS_ON ?= 0 +ifeq ($(ROM_UTILS_ON),1) +KBUILD_CPPFLAGS += -DROM_UTILS_ON +core-y += utils/rom_utils/ +endif + +# ------------------------------------------- +# Features +# ------------------------------------------- + +export DEBUG_PORT ?= 1 + +ifneq ($(filter best1000 best2000,$(CHIP)),) +export AUD_SECTION_STRUCT_VERSION ?= 1 +else +export AUD_SECTION_STRUCT_VERSION ?= 2 +endif + +ifneq ($(AUD_SECTION_STRUCT_VERSION),) +KBUILD_CPPFLAGS += -DAUD_SECTION_STRUCT_VERSION=$(AUD_SECTION_STRUCT_VERSION) +endif + +export FLASH_CHIP +ifneq ($(FLASH_CHIP),) +VALID_FLASH_CHIP_LIST := ALL \ + GD25LQ64C GD25LQ32C GD25LQ16C GD25Q32C GD25Q80C GD25Q40C GD25Q20C \ + P25Q64L P25Q32L P25Q16L P25Q80H P25Q21H \ + XT25Q08B \ + EN25S80B +ifneq ($(filter-out $(VALID_FLASH_CHIP_LIST),$(FLASH_CHIP)),) +$(error Invalid FLASH_CHIP: $(filter-out $(VALID_FLASH_CHIP_LIST),$(FLASH_CHIP))) +endif +endif + +NV_REC_DEV_VER ?= 2 + +export NO_SLEEP ?= 0 + +export FAULT_DUMP ?= 1 + +export USE_TRACE_ID ?= 0 +ifeq ($(USE_TRACE_ID),1) +export TRACE_STR_SECTION ?= 1 +endif + +export CRASH_BOOT ?= 0 + +export OSC_26M_X4_AUD2BB ?= 0 +ifeq ($(OSC_26M_X4_AUD2BB),1) +export ANA_26M_X4_ENABLE ?= 1 +export FLASH_LOW_SPEED ?= 0 +endif + +export AUDIO_CODEC_ASYNC_CLOSE ?= 0 + +# Enable the workaround for BEST1000 version C & earlier chips +export CODEC_PLAY_BEFORE_CAPTURE ?= 0 + +export AUDIO_INPUT_CAPLESSMODE ?= 0 + +export AUDIO_INPUT_LARGEGAIN ?= 0 + +export AUDIO_INPUT_MONO ?= 0 + +export AUDIO_OUTPUT_MONO ?= 0 + +export AUDIO_OUTPUT_VOLUME_DEFAULT ?= 10 + +export AUDIO_OUTPUT_INVERT_RIGHT_CHANNEL ?= 0 + +export AUDIO_OUTPUT_CALIB_GAIN_MISSMATCH ?= 0 + +ifeq ($(USB_AUDIO_APP),1) +export CODEC_HIGH_QUALITY ?= 1 +endif + +ifeq ($(ANC_APP),1) +export CODEC_HIGH_QUALITY ?= 1 +endif + +ifeq ($(CHIP),best1000) +AUDIO_OUTPUT_DIFF ?= 1 +AUDIO_OUTPUT_DC_CALIB ?= $(AUDIO_OUTPUT_DIFF) +AUDIO_OUTPUT_SMALL_GAIN_ATTN ?= 1 +AUDIO_OUTPUT_SW_GAIN ?= 1 +ANC_L_R_MISALIGN_WORKAROUND ?= 1 +else ifeq ($(CHIP),best2000) +ifeq ($(CODEC_HIGH_QUALITY),1) +export VCODEC_VOLT ?= 2.5V +else +export VCODEC_VOLT ?= 1.6V +endif +AUDIO_OUTPUT_DIFF ?= 0 +ifeq ($(VCODEC_VOLT),2.5V) +AUDIO_OUTPUT_DC_CALIB ?= 0 +AUDIO_OUTPUT_DC_CALIB_ANA ?= 1 +else +AUDIO_OUTPUT_DC_CALIB ?= 1 +AUDIO_OUTPUT_DC_CALIB_ANA ?= 0 +endif +ifneq ($(AUDIO_OUTPUT_DIFF),1) +# Class-G module still needs improving +#DAC_CLASSG_ENABLE ?= 1 +endif +else ifeq ($(CHIP),best2001) +export VCODEC_VOLT ?= 1.8V +AUDIO_OUTPUT_DC_CALIB ?= 0 +AUDIO_OUTPUT_DC_CALIB_ANA ?= 1 +else ifneq ($(filter best3001 best3003 best3005,$(CHIP)),) +export VCODEC_VOLT ?= 2.5V +AUDIO_OUTPUT_DC_CALIB ?= 1 +AUDIO_OUTPUT_DC_CALIB_ANA ?= 0 +else +AUDIO_OUTPUT_DC_CALIB ?= 0 +AUDIO_OUTPUT_DC_CALIB_ANA ?= 1 +endif + +ifeq ($(AUDIO_OUTPUT_DC_CALIB)-$(AUDIO_OUTPUT_DC_CALIB_ANA),1-1) +$(error AUDIO_OUTPUT_DC_CALIB and AUDIO_OUTPUT_DC_CALIB_ANA cannot be enabled at the same time) +endif + +export AUDIO_OUTPUT_DIFF + +export AUDIO_OUTPUT_DC_CALIB + +export AUDIO_OUTPUT_DC_CALIB_ANA + +export AUDIO_OUTPUT_SMALL_GAIN_ATTN + +export AUDIO_OUTPUT_SW_GAIN + +export ANC_L_R_MISALIGN_WORKAROUND + +export DAC_CLASSG_ENABLE + +export AF_DEVICE_I2S ?= 0 + +export AF_DEVICE_TDM ?= 0 + +export AF_ADC_I2S_SYNC ?= 0 +ifeq ($(AF_ADC_I2S_SYNC),1) +KBUILD_CPPFLAGS += -DAF_ADC_I2S_SYNC +export AF_DEVICE_I2S = 1 +export INT_LOCK_EXCEPTION ?= 1 +endif + +export BONE_SENSOR_TDM ?= 0 +ifeq ($(BONE_SENSOR_TDM),1) +KBUILD_CPPFLAGS += -DBONE_SENSOR_TDM +KBUILD_CPPFLAGS += -DI2C_TASK_MODE +export AF_DEVICE_I2S = 1 +export AF_DEVICE_TDM = 1 +KBUILD_CPPFLAGS += -DI2S_MCLK_FROM_SPDIF +KBUILD_CPPFLAGS += -DI2S_MCLK_IOMUX_INDEX=13 +KBUILD_CPPFLAGS += -DCLKOUT_IOMUX_INDEX=13 +endif + +export PLAYBACK_USE_I2S ?= 0 +ifeq ($(PLAYBACK_USE_I2S),1) +KBUILD_CPPFLAGS += -DPLAYBACK_USE_I2S +export AF_DEVICE_I2S = 1 +export A2DP_EQ_24BIT = 0 +endif + +ifeq ($(ANC_APP),1) +export ANC_FF_ENABLED ?= 1 +ifeq ($(ANC_FB_CHECK),1) +KBUILD_CPPFLAGS += -DANC_FB_CHECK +endif +endif + +ifeq ($(CHIP),best1400) +export AUDIO_RESAMPLE ?= 1 +export PMU_IRQ_UNIFIED ?= 1 +else ifeq ($(CHIP),best2001) +export AUDIO_RESAMPLE ?= 1 +else +export AUDIO_RESAMPLE ?= 0 +endif + +ifeq ($(AUDIO_RESAMPLE),1) +ifeq ($(CHIP),best1000) +export SW_PLAYBACK_RESAMPLE ?= 1 +export SW_CAPTURE_RESAMPLE ?= 1 +export NO_SCO_RESAMPLE ?= 1 +endif # CHIP is best1000 +ifeq ($(CHIP),best2000) +export SW_CAPTURE_RESAMPLE ?= 1 +export SW_SCO_RESAMPLE ?= 1 +export NO_SCO_RESAMPLE ?= 0 +endif # CHIP is best2000 +ifeq ($(BT_ANC),1) +ifeq ($(NO_SCO_RESAMPLE),1) +$(error BT_ANC and NO_SCO_RESAMPLE cannot be enabled at the same time) +endif +endif # BT_ANC + +KBUILD_CPPFLAGS += -D__AUDIO_RESAMPLE__ +endif # AUDIO_RESAMPLE + +export HW_FIR_DSD_PROCESS ?= 0 + +export HW_FIR_EQ_PROCESS ?= 0 + +export SW_IIR_EQ_PROCESS ?= 0 +ifeq ($(SW_IIR_EQ_PROCESS),1) +export A2DP_EQ_24BIT = 1 +endif + +export HW_IIR_EQ_PROCESS ?= 0 + +export HW_DAC_IIR_EQ_PROCESS ?= 0 + +export AUDIO_DRC ?= 0 + +export AUDIO_DRC2 ?= 0 + +export HW_DC_FILTER_WITH_IIR ?= 0 +ifeq ($(HW_DC_FILTER_WITH_IIR),1) +KBUILD_CPPFLAGS += -DHW_DC_FILTER_WITH_IIR +export HW_FILTER_CODEC_IIR ?= 1 +endif + +ifeq ($(USB_AUDIO_APP),1) +export ANDROID_ACCESSORY_SPEC ?= 1 +export FIXED_CODEC_ADC_VOL ?= 0 + +ifneq ($(BTUSB_AUDIO_MODE),1) +NO_PWRKEY ?= 1 +NO_GROUPKEY ?= 1 +endif +endif + +export NO_PWRKEY + +export NO_GROUPKEY + +ifneq ($(CHIP),best1000) +ifneq ($(CHIP)-$(TWS),best2000-1) +# For bt +export A2DP_EQ_24BIT ?= 1 +# For usb audio +export AUDIO_PLAYBACK_24BIT ?= 1 +endif +endif + +ifeq ($(CHIP),best1000) + +ifeq ($(AUD_PLL_DOUBLE),1) +KBUILD_CPPFLAGS += -DAUD_PLL_DOUBLE +endif + +ifeq ($(DUAL_AUX_MIC),1) +ifeq ($(AUDIO_INPUT_MONO),1) +$(error Invalid talk mic configuration) +endif +KBUILD_CPPFLAGS += -D_DUAL_AUX_MIC_ +endif + +endif # best1000 + +ifeq ($(CAPTURE_ANC_DATA),1) +KBUILD_CPPFLAGS += -DCAPTURE_ANC_DATA +endif + +ifeq ($(AUDIO_ANC_TT_HW),1) +KBUILD_CPPFLAGS += -DAUDIO_ANC_TT_HW +endif + +ifeq ($(AUDIO_ANC_FB_MC_HW),1) +KBUILD_CPPFLAGS += -DAUDIO_ANC_FB_MC_HW +endif + +ifeq ($(AUDIO_ANC_FB_MC),1) +ifeq ($(AUDIO_RESAMPLE),1) +$(error AUDIO_ANC_FB_MC conflicts with AUDIO_RESAMPLE) +endif +KBUILD_CPPFLAGS += -DAUDIO_ANC_FB_MC +endif + +ifeq ($(BT_ANC),1) +KBUILD_CPPFLAGS += -D__BT_ANC__ +endif + +export ANC_NOISE_TRACKER ?= 0 +ifeq ($(ANC_NOISE_TRACKER),1) +ifeq ($(IBRT),1) +KBUILD_CPPFLAGS += -DANC_NOISE_TRACKER_CHANNEL_NUM=1 +else +KBUILD_CPPFLAGS += -DANC_NOISE_TRACKER_CHANNEL_NUM=2 +endif +endif + +ifeq ($(AUDIO_ANC_FB_ADJ_MC),1) +KBUILD_CPPFLAGS += -DGLOBAL_SRAM_CMSIS_FFT +endif + +ifeq ($(ANC_WNR_ENABLED),1) +KBUILD_CPPFLAGS += -DGLOBAL_SRAM_CMSIS_FFT +endif + +ifeq ($(KWS_ALEXA),1) +KBUILD_CPPFLAGS += -DKWS_BES +KBUILD_CPPFLAGS += -DGLOBAL_SRAM_KISS_FFT +KBUILD_CPPFLAGS += -DGLOBAL_SRAM_CMSIS_FFT +endif + +export BTUSB_AUDIO_MODE ?= 0 +ifeq ($(BTUSB_AUDIO_MODE),1) +KBUILD_CPPFLAGS += -DBTUSB_AUDIO_MODE +endif + +export BT_USB_AUDIO_DUAL_MODE ?= 0 +ifeq ($(BT_USB_AUDIO_DUAL_MODE),1) +KBUILD_CPPFLAGS += -DBT_USB_AUDIO_DUAL_MODE +endif + +ifeq ($(WATCHER_DOG),1) +KBUILD_CPPFLAGS += -D__WATCHER_DOG_RESET__ +endif + +export ULTRA_LOW_POWER ?= 0 +ifeq ($(ULTRA_LOW_POWER),1) +export FLASH_LOW_SPEED ?= 1 +export PSRAM_LOW_SPEED ?= 1 +endif + +export USB_HIGH_SPEED ?= 0 +ifeq ($(CHIP),best2000) +ifeq ($(USB_HIGH_SPEED),1) +export AUDIO_USE_BBPLL ?= 1 +endif +ifeq ($(AUDIO_USE_BBPLL),1) +ifeq ($(MCU_HIGH_PERFORMANCE_MODE),1) +$(error MCU_HIGH_PERFORMANCE_MODE conflicts with AUDIO_USE_BBPLL) +endif +else # !AUDIO_USE_BBPLL +ifeq ($(USB_HIGH_SPEED),1) +$(error AUDIO_USE_BBPLL must be used with USB_HIGH_SPEED) +endif +endif # !AUDIO_USE_BBPLL +endif # best2000 + +ifeq ($(SIMPLE_TASK_SWITCH),1) +KBUILD_CPPFLAGS += -DSIMPLE_TASK_SWITCH +endif + +ifeq ($(ASSERT_SHOW_FILE_FUNC),1) +KBUILD_CPPFLAGS += -DASSERT_SHOW_FILE_FUNC +else +ifeq ($(ASSERT_SHOW_FILE),1) +KBUILD_CPPFLAGS += -DASSERT_SHOW_FILE +else +ifeq ($(ASSERT_SHOW_FUNC),1) +KBUILD_CPPFLAGS += -DASSERT_SHOW_FUNC +endif +endif +endif + +ifeq ($(CALIB_SLOW_TIMER),1) +KBUILD_CPPFLAGS += -DCALIB_SLOW_TIMER +endif + +ifeq ($(INT_LOCK_EXCEPTION),1) +KBUILD_CPPFLAGS += -DINT_LOCK_EXCEPTION +endif + +export APP_ANC_TEST ?= 0 +ifeq ($(APP_ANC_TEST),1) +KBUILD_CPPFLAGS += -DAPP_ANC_TEST +endif + +USER_REBOOT_PLAY_MUSIC_AUTO ?= 0 +ifeq ($(USER_REBOOT_PLAY_MUSIC_AUTO),1) +KBUILD_CPPFLAGS += -DUSER_REBOOT_PLAY_MUSIC_AUTO +export USER_REBOOT_PLAY_MUSIC_AUTO ?= 1 +endif + +export TEST_OVER_THE_AIR ?= 0 +ifeq ($(TEST_OVER_THE_AIR),1) +KBUILD_CPPFLAGS += -DTEST_OVER_THE_AIR_ENANBLED=1 +endif + +ifeq ($(USE_TRACE_ID),1) +KBUILD_CPPFLAGS += -DUSE_TRACE_ID +endif + +ifeq ($(TRACE_STR_SECTION),1) +KBUILD_CPPFLAGS += -DTRACE_STR_SECTION +CPPFLAGS_${LDS_FILE} += -DTRACE_STR_SECTION +endif + +USE_THIRDPARTY ?= 0 +ifeq ($(USE_THIRDPARTY),1) +KBUILD_CPPFLAGS += -D__THIRDPARTY +core-y += thirdparty/ +endif + +export PC_CMD_UART ?= 0 +ifeq ($(PC_CMD_UART),1) +KBUILD_CPPFLAGS += -D__PC_CMD_UART__ +endif + +ifeq ($(VOICE_DETECTOR_EN),1) +KBUILD_CPPFLAGS += -DVOICE_DETECTOR_EN +endif + +ifeq ($(VAD_USE_8K_SAMPLE_RATE),1) +KBUILD_CPPFLAGS += -DVAD_USE_8K_SAMPLE_RATE +endif + +ifeq ($(USB_ANC_MC_EQ_TUNING),1) +KBUILD_CPPFLAGS += -DUSB_ANC_MC_EQ_TUNING -DANC_PROD_TEST +endif + +export AUTO_TEST ?= 0 +ifeq ($(AUTO_TEST),1) +KBUILD_CFLAGS += -D_AUTO_TEST_ +endif + +export BES_AUTOMATE_TEST ?= 0 +ifeq ($(BES_AUTOMATE_TEST),1) +KBUILD_CFLAGS += -DBES_AUTOMATE_TEST +KBUILD_CFLAGS += -DHAL_TRACE_RX_ENABLE +endif + +ifeq ($(RB_CODEC),1) +CPPFLAGS_${LDS_FILE} += -DRB_CODEC +endif + +ifneq ($(DATA_BUF_START),) +CPPFLAGS_${LDS_FILE} += -DDATA_BUF_START=$(DATA_BUF_START) +endif + +ifeq ($(USER_SECURE_BOOT),1) +core-y += utils/user_secure_boot/ \ + utils/system_info/ +endif + +ifeq ($(MAX_DAC_OUTPUT),-60db) +MAX_DAC_OUTPUT_FLAGS := -DMAX_DAC_OUTPUT_M60DB +else +ifeq ($(MAX_DAC_OUTPUT),3.75mw) +MAX_DAC_OUTPUT_FLAGS := -DMAX_DAC_OUTPUT_3P75MW +else +ifeq ($(MAX_DAC_OUTPUT),5mw) +MAX_DAC_OUTPUT_FLAGS := -DMAX_DAC_OUTPUT_5MW +else +ifeq ($(MAX_DAC_OUTPUT),10mw) +MAX_DAC_OUTPUT_FLAGS := -DMAX_DAC_OUTPUT_10MW +else +ifneq ($(MAX_DAC_OUTPUT),30mw) +ifneq ($(MAX_DAC_OUTPUT),) +$(error Invalid MAX_DAC_OUTPUT value: $(MAX_DAC_OUTPUT) (MUST be one of: -60db 3.75mw 5mw 10mw 30mw)) +endif +endif +endif +endif +endif +endif +export MAX_DAC_OUTPUT_FLAGS + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# BT features +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(BT_APP),1) + +export BT_IF_INCLUDES ?= +export BT_PROFILES_INCLUDES ?= +export ENHANCED_STACK ?= 1 + +export INTERSYS_NO_THREAD ?= 0 + +export INTERSYS_DEBUG ?= 0 +ifeq ($(INTERSYS_DEBUG),1) + KBUILD_CPPFLAGS += -DINTERSYS_DEBUG=1 +endif + +export BT_DEBUG_TPORTS ?= 0 +ifneq ($(BT_DEBUG_TPORTS),0) + KBUILD_CPPFLAGS += -D__BT_DEBUG_TPORTS__ +endif + +export SNOOP_DATA_EXCHANGE_VIA_BLE ?= 0 +ifeq ($(SNOOP_DATA_EXCHANGE_VIA_BLE),1) + KBUILD_CPPFLAGS += -DSNOOP_DATA_EXCHANGE_VIA_BLE +endif + +export SYNC_BT_CTLR_PROFILE ?= 0 +ifeq ($(SYNC_BT_CTLR_PROFILE),1) + KBUILD_CPPFLAGS += -DSYNC_BT_CTLR_PROFILE +endif + +export PROFILE_DEBUG ?= 0 +ifeq ($(PROFILE_DEBUG),1) + KBUILD_CPPFLAGS += -DXA_DEBUG=1 +endif + +ifeq ($(ENHANCED_STACK),1) +BT_IF_INCLUDES += \ + -Iservices/bt_if_enhanced/inc +BT_PROFILES_INCLUDES += \ + -Iservices/bt_profiles_enhanced/inc +else +BT_IF_INCLUDES += \ + -Iservices/bt_if/inc +BT_PROFILES_INCLUDES += \ + -Iservices/bt_profiles/inc \ + -Iservices/bt_profiles/inc/sys +endif + +ifeq ($(ENHANCED_STACK),1) +KBUILD_CFLAGS += -DENHANCED_STACK +#KBUILD_CPPFLAGS += -D__A2DP_AVDTP_CP__ -D__A2DP_AVDTP_DR__ +#KBUILD_CPPFLAGS += -D__A2DP_AVDTP_DR__ +KBUILD_CPPFLAGS += -D__BLE_TX_USE_BT_TX_QUEUE__ +ifeq ($(BISTO_ENABLE),1) +ifneq ($(IBRT),1) +#disbled before IBRT MAP role switch feature is ready +KBUILD_CPPFLAGS += -D__BTMAP_ENABLE__ +endif +endif +endif + +ifeq ($(A2DP_AVDTP_CP),1) +KBUILD_CPPFLAGS += -D__A2DP_AVDTP_CP__ +endif + +ifneq ($(filter-out 2M 3M,$(BT_RF_PREFER)),) +$(error Invalid BT_RF_PREFER=$(BT_RF_PREFER)) +endif +ifneq ($(BT_RF_PREFER),) +RF_PREFER := $(subst .,P,$(BT_RF_PREFER)) +KBUILD_CPPFLAGS += -D__$(RF_PREFER)_PACK__ +endif + +export AUDIO_SCO_BTPCM_CHANNEL ?= 1 +ifeq ($(AUDIO_SCO_BTPCM_CHANNEL),1) +KBUILD_CPPFLAGS += -D_SCO_BTPCM_CHANNEL_ +endif + +export BT_ONE_BRING_TWO ?= 0 +ifeq ($(BT_ONE_BRING_TWO),1) +KBUILD_CPPFLAGS += -D__BT_ONE_BRING_TWO__ +endif + +export A2DP_PLAYER_USE_BT_TRIGGER ?= 1 +ifeq ($(A2DP_PLAYER_USE_BT_TRIGGER),1) +KBUILD_CPPFLAGS += -D__A2DP_PLAYER_USE_BT_TRIGGER__ +endif + +export BT_SELECT_PROF_DEVICE_ID ?= 0 +ifeq ($(BT_ONE_BRING_TWO),1) +ifeq ($(BT_SELECT_PROF_DEVICE_ID),1) +KBUILD_CPPFLAGS += -D__BT_SELECT_PROF_DEVICE_ID__ +endif +endif + +export SBC_FUNC_IN_ROM ?= 0 +ifeq ($(SBC_FUNC_IN_ROM),1) + +KBUILD_CPPFLAGS += -D__SBC_FUNC_IN_ROM__ + +ifeq ($(CHIP),best2000) +UNALIGNED_ACCESS ?= 1 +KBUILD_CPPFLAGS += -D__SBC_FUNC_IN_ROM_VBEST2000_ONLYSBC__ +KBUILD_CPPFLAGS += -D__SBC_FUNC_IN_ROM_VBEST2000__ +endif +endif + +export HFP_1_6_ENABLE ?= 1 +ifeq ($(HFP_1_6_ENABLE),1) +KBUILD_CPPFLAGS += -DHFP_1_6_ENABLE +ifeq ($(MSBC_16K_SAMPLE_RATE),0) +KBUILD_CPPFLAGS += -DMSBC_8K_SAMPLE_RATE +export DSP_LIB ?= 1 +endif +endif + +export A2DP_AAC_ON ?= 0 +ifeq ($(A2DP_AAC_ON),1) +KBUILD_CPPFLAGS += -DA2DP_AAC_ON +KBUILD_CPPFLAGS += -D__ACC_FRAGMENT_COMPATIBLE__ +endif + +export FDKAAC_VERSION ?= 2 + +ifneq ($(FDKAAC_VERSION),) +KBUILD_CPPFLAGS += -DFDKAAC_VERSION=$(FDKAAC_VERSION) +endif + +export A2DP_LHDC_ON ?= 0 +ifeq ($(A2DP_LHDC_ON),1) +KBUILD_CPPFLAGS += -DA2DP_LHDC_ON +export A2DP_LHDC_V3 ?= 0 +ifeq ($(A2DP_LHDC_V3),1) +KBUILD_CPPFLAGS += -DA2DP_LHDC_V3 +endif +export A2DP_LHDC_LARC ?= 0 +ifeq ($(A2DP_LHDC_LARC),1) +KBUILD_CPPFLAGS += -DA2DP_LHDC_LARC +endif + +core-y += thirdparty/audio_codec_lib/liblhdc-dec/ +endif +ifeq ($(USER_SECURE_BOOT),1) +KBUILD_CPPFLAGS += -DUSER_SECURE_BOOT +endif + +export A2DP_SCALABLE_ON ?= 0 +ifeq ($(A2DP_SCALABLE_ON),1) +KBUILD_CPPFLAGS += -DA2DP_SCALABLE_ON +KBUILD_CPPFLAGS += -DGLOBAL_SRAM_KISS_FFT +#KBUILD_CPPFLAGS += -DA2DP_SCALABLE_UHQ_SUPPORT +core-y += thirdparty/audio_codec_lib/scalable/ +endif + +export A2DP_LDAC_ON ?= 0 +ifeq ($(A2DP_LDAC_ON),1) +KBUILD_CPPFLAGS += -DA2DP_LDAC_ON +core-y += thirdparty/audio_codec_lib/ldac/ +endif + +export A2DP_CP_ACCEL ?= 0 +ifeq ($(A2DP_CP_ACCEL),1) +KBUILD_CPPFLAGS += -DA2DP_CP_ACCEL +endif + +export SCO_CP_ACCEL ?= 0 +ifeq ($(SCO_CP_ACCEL),1) +KBUILD_CPPFLAGS += -DSCO_CP_ACCEL +# spx fft will share buffer which is not fit for dual cores. +KBUILD_CPPFLAGS += -DUSE_CMSIS_F32_FFT +endif + +export SCO_TRACE_CP_ACCEL ?= 0 +ifeq ($(SCO_TRACE_CP_ACCEL),1) +KBUILD_CPPFLAGS += -DSCO_TRACE_CP_ACCEL +endif + +ifeq ($(BT_XTAL_SYNC),1) +KBUILD_CPPFLAGS += -DBT_XTAL_SYNC_NEW_METHOD +KBUILD_CPPFLAGS += -DFIXED_BIT_OFFSET_TARGET +endif + +ifeq ($(BT_XTAL_SYNC_SLOW),1) +KBUILD_CPPFLAGS += -DBT_XTAL_SYNC_SLOW +endif + +ifeq ($(BT_XTAL_SYNC_NO_RESET),1) +KBUILD_CPPFLAGS += -DBT_XTAL_SYNC_NO_RESET +endif + + +ifeq ($(APP_LINEIN_A2DP_SOURCE),1) +KBUILD_CPPFLAGS += -DAPP_LINEIN_A2DP_SOURCE +endif + +ifeq ($(HSP_ENABLE),1) +KBUILD_CPPFLAGS += -D__HSP_ENABLE__ +endif + +ifeq ($(APP_I2S_A2DP_SOURCE),1) +KBUILD_CPPFLAGS += -DAPP_I2S_A2DP_SOURCE +endif + +export TX_RX_PCM_MASK ?= 0 +ifeq ($(TX_RX_PCM_MASK),1) +KBUILD_CPPFLAGS += -DTX_RX_PCM_MASK +endif + +export PCM_FAST_MODE ?= 0 +ifeq ($(PCM_FAST_MODE),1) +KBUILD_CPPFLAGS += -DPCM_FAST_MODE +endif + +export LOW_DELAY_SCO ?= 0 +ifeq ($(LOW_DELAY_SCO),1) +KBUILD_CPPFLAGS += -DLOW_DELAY_SCO +endif + +export CVSD_BYPASS ?= 0 +ifeq ($(CVSD_BYPASS),1) +KBUILD_CPPFLAGS += -DCVSD_BYPASS +endif + +export SCO_DMA_SNAPSHOT ?= 0 +ifeq ($(CHIP_HAS_SCO_DMA_SNAPSHOT),1) +export SCO_DMA_SNAPSHOT := 1 +KBUILD_CPPFLAGS += -DSCO_DMA_SNAPSHOT +endif + +export SCO_OPTIMIZE_FOR_RAM ?= 0 +ifeq ($(SCO_OPTIMIZE_FOR_RAM),1) +KBUILD_CPPFLAGS += -DSCO_OPTIMIZE_FOR_RAM +endif + +export AAC_TEXT_PARTIAL_IN_FLASH ?= 0 +ifeq ($(AAC_TEXT_PARTIAL_IN_FLASH),1) +KBUILD_CPPFLAGS += -DAAC_TEXT_PARTIAL_IN_FLASH +endif + +ifeq ($(SUPPORT_BATTERY_REPORT),1) +KBUILD_CPPFLAGS += -DSUPPORT_BATTERY_REPORT +endif + +ifeq ($(SUPPORT_HF_INDICATORS),1) +KBUILD_CPPFLAGS += -DSUPPORT_HF_INDICATORS +endif + +ifeq ($(SUPPORT_SIRI),1) +KBUILD_CPPFLAGS += -DSUPPORT_SIRI +endif + +export BQB_PROFILE_TEST ?= 0 +ifeq ($(BQB_PROFILE_TEST),1) +KBUILD_CPPFLAGS += -D__BQB_PROFILE_TEST__ +endif + +export AUDIO_SPECTRUM ?= 0 +ifeq ($(AUDIO_SPECTRUM),1) +KBUILD_CPPFLAGS += -D__AUDIO_SPECTRUM__ +KBUILD_CPPFLAGS += -DGLOBAL_SRAM_KISS_FFT +endif + +export INTERCONNECTION ?= 0 +ifeq ($(INTERCONNECTION),1) +KBUILD_CPPFLAGS += -D__INTERCONNECTION__ +endif + +export INTERACTION ?= 0 +ifeq ($(INTERACTION),1) +KBUILD_CPPFLAGS += -D__INTERACTION__ +endif + +export INTERACTION_FASTPAIR ?= 0 +ifeq ($(INTERACTION_FASTPAIR),1) +KBUILD_CPPFLAGS += -D__INTERACTION_FASTPAIR__ +KBUILD_CPPFLAGS += -D__INTERACTION_CUSTOMER_AT_COMMAND__ +endif + +ifeq ($(SUSPEND_ANOTHER_DEV_A2DP_STREAMING_WHEN_CALL_IS_COMING),1) +KBUILD_CPPFLAGS += -DSUSPEND_ANOTHER_DEV_A2DP_STREAMING_WHEN_CALL_IS_COMING +endif + +export TWS_PROMPT_SYNC ?= 0 +ifeq ($(TWS_PROMPT_SYNC), 1) +export MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED = 1 +KBUILD_CPPFLAGS += -DTWS_PROMPT_SYNC +endif + +export MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED ?= 0 +ifeq ($(MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED), 1) +KBUILD_CPPFLAGS += -DMIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED +export RESAMPLE_ANY_SAMPLE_RATE ?= 1 +endif + +#ifeq ($(AUDIO_RESAMPLE),0) +export RESAMPLE_ANY_SAMPLE_RATE ?= 1 +KBUILD_CPPFLAGS += -DRESAMPLE_ANY_SAMPLE_RATE +#endif + +export MEDIA_PLAY_24BIT ?= 0 + +export LBRT ?= 0 +ifeq ($(LBRT),1) +KBUILD_CPPFLAGS += -DLBRT +endif + +export IBRT ?= 0 +ifeq ($(IBRT),1) +KBUILD_CPPFLAGS += -DIBRT +KBUILD_CPPFLAGS += -DIBRT_BLOCKED +KBUILD_CPPFLAGS += -DIBRT_NOT_USE +KBUILD_CPPFLAGS += -D__A2DP_AUDIO_SYNC_FIX_DIFF_NOPID__ +endif + + +export IBRT_TESTMODE ?= 0 +ifeq ($(IBRT_TESTMODE),1) +KBUILD_CPPFLAGS += -D__IBRT_IBRT_TESTMODE__ +endif + +ifeq ($(TWS_SYSTEM_ENABLED),1) +KBUILD_CPPFLAGS += -DTWS_SYSTEM_ENABLED +endif + +export BES_AUD ?= 0 +ifeq ($(BES_AUD),1) +KBUILD_CPPFLAGS += -DBES_AUD +endif + +export IBRT_SEARCH_UI ?= 0 +ifeq ($(IBRT_SEARCH_UI),1) +KBUILD_CPPFLAGS += -DIBRT_SEARCH_UI +endif + +endif # BT_APP + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# BLE features +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(BLE),1) + +KBUILD_CPPFLAGS += -DBLE_ENABLE + +KBUILD_CPPFLAGS += -D__IAG_BLE_INCLUDE__ + +IS_USE_BLE_DUAL_CONNECTION ?= 1 + +ifeq ($(IS_USE_BLE_DUAL_CONNECTION),1) +KBUILD_CPPFLAGS += -DBLE_CONNECTION_MAX=2 +else +KBUILD_CPPFLAGS += -DBLE_CONNECTION_MAX=1 +endif + +ifeq ($(IS_ENABLE_DEUGGING_MODE),1) +KBUILD_CPPFLAGS += -DIS_ENABLE_DEUGGING_MODE +endif + +endif # BLE + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# Speech features +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +export SPEECH_TX_24BIT ?= 0 +ifeq ($(SPEECH_TX_24BIT),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_24BIT +endif + +export SPEECH_TX_DC_FILTER ?= 0 +ifeq ($(SPEECH_TX_DC_FILTER),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_DC_FILTER +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_TX_MIC_CALIBRATION ?= 0 +ifeq ($(SPEECH_TX_MIC_CALIBRATION),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_MIC_CALIBRATION +endif + +export SPEECH_TX_MIC_FIR_CALIBRATION ?= 0 +ifeq ($(SPEECH_TX_MIC_FIR_CALIBRATION),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_MIC_FIR_CALIBRATION +endif + +export SPEECH_TX_AEC_CODEC_REF ?= 0 + +export SPEECH_TX_AEC ?= 0 +ifeq ($(SPEECH_TX_AEC),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_AEC +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +ifeq ($(CHIP_HAS_EC_CODEC_REF),1) +export SPEECH_TX_AEC_CODEC_REF := 1 +endif +endif + +export SPEECH_TX_AEC2 ?= 0 +ifeq ($(SPEECH_TX_AEC2),1) +$(error SPEECH_TX_AEC2 is not supported now, use SPEECH_TX_AEC2FLOAT instead) +KBUILD_CPPFLAGS += -DSPEECH_TX_AEC2 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +ifeq ($(CHIP_HAS_EC_CODEC_REF),1) +export SPEECH_TX_AEC_CODEC_REF := 1 +endif +endif + +export SPEECH_TX_AEC3 ?= 0 +ifeq ($(SPEECH_TX_AEC3),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_AEC3 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +ifeq ($(CHIP_HAS_EC_CODEC_REF),1) +export SPEECH_TX_AEC_CODEC_REF := 1 +endif +endif + +export SPEECH_TX_AEC2FLOAT ?= 0 +ifeq ($(SPEECH_TX_AEC2FLOAT),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_AEC2FLOAT +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +export DSP_LIB ?= 1 +ifeq ($(CHIP_HAS_EC_CODEC_REF),1) +export SPEECH_TX_AEC_CODEC_REF := 1 +endif +endif + +ifeq ($(SCO_DMA_SNAPSHOT),0) +export SPEECH_TX_AEC_CODEC_REF := 0 +endif + +export SPEECH_TX_NS ?= 0 +ifeq ($(SPEECH_TX_NS),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_NS +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_TX_NS2 ?= 0 +ifeq ($(SPEECH_TX_NS2),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_NS2 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +KBUILD_CPPFLAGS += -DLC_MMSE_FRAME_LENGTH=$(LC_MMSE_FRAME_LENGTH) +endif + +export SPEECH_TX_NS2FLOAT ?= 0 +ifeq ($(SPEECH_TX_NS2FLOAT),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_NS2FLOAT +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +export DSP_LIB ?= 1 +endif + +export SPEECH_TX_NS3 ?= 0 +ifeq ($(SPEECH_TX_NS3),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_NS3 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_TX_WNR ?= 0 +ifeq ($(SPEECH_TX_WNR),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_WNR +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_CS_VAD ?= 0 +ifeq ($(SPEECH_CS_VAD),1) +KBUILD_CPPFLAGS += -DSPEECH_CS_VAD +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM ?= 1 + +export SPEECH_TX_2MIC_NS ?= 0 +ifeq ($(SPEECH_TX_2MIC_NS),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_2MIC_NS +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM = 2 +endif + +export SPEECH_TX_2MIC_NS2 ?= 0 +ifeq ($(SPEECH_TX_2MIC_NS2),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_2MIC_NS2 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +KBUILD_CPPFLAGS += -DCOH_FRAME_LENGTH=$(COH_FRAME_LENGTH) +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM = 2 +endif + +export SPEECH_TX_2MIC_NS3 ?= 0 +ifeq ($(SPEECH_TX_2MIC_NS3),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_2MIC_NS3 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM = 2 +endif + +export SPEECH_TX_2MIC_NS4 ?= 0 +ifeq ($(SPEECH_TX_2MIC_NS4),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_2MIC_NS4 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC + +ifeq ($(BONE_SENSOR_TDM),1) +# Get 1 channel from sensor +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM = 1 +else +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM = 2 +endif + +endif + +export SPEECH_TX_2MIC_NS5 ?= 0 +ifeq ($(SPEECH_TX_2MIC_NS5),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_2MIC_NS5 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM = 2 +endif + +export SPEECH_TX_3MIC_NS ?= 0 +ifeq ($(SPEECH_TX_3MIC_NS),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_3MIC_NS +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +ifeq ($(BONE_SENSOR_TDM),1) +# Get 1 channel from sensor +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM = 2 +else +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM = 3 +endif +endif + +export SPEECH_TX_3MIC_NS3 ?= 0 +ifeq ($(SPEECH_TX_3MIC_NS3),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_3MIC_NS3 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +# Get 1 channel from sensor +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM = 3 +endif + +export SPEECH_TX_THIRDPARTY_ALANGO ?= 0 +ifeq ($(SPEECH_TX_THIRDPARTY_ALANGO),1) +export SPEECH_TX_THIRDPARTY := 1 +core-y += thirdparty/alango_lib/ +endif + +export SPEECH_TX_THIRDPARTY ?= 0 +ifeq ($(SPEECH_TX_THIRDPARTY),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_THIRDPARTY +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +# Get 1 channel from sensor +export SPEECH_CODEC_CAPTURE_CHANNEL_NUM = 2 +ifeq ($(CHIP_HAS_EC_CODEC_REF),1) +export SPEECH_TX_AEC_CODEC_REF := 1 +endif +endif + +export SPEECH_TX_NOISE_GATE ?= 0 +ifeq ($(SPEECH_TX_NOISE_GATE),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_NOISE_GATE +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_TX_COMPEXP ?= 0 +ifeq ($(SPEECH_TX_COMPEXP),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_COMPEXP +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_TX_AGC ?= 0 +ifeq ($(SPEECH_TX_AGC),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_AGC +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_TX_EQ ?= 0 +ifeq ($(SPEECH_TX_EQ),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_EQ +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +export DSP_LIB ?= 1 +endif + +export SPEECH_TX_POST_GAIN ?= 0 +ifeq ($(SPEECH_TX_POST_GAIN),1) +KBUILD_CPPFLAGS += -DSPEECH_TX_POST_GAIN +endif + +export SPEECH_RX_NS ?= 0 +ifeq ($(SPEECH_RX_NS),1) +KBUILD_CPPFLAGS += -DSPEECH_RX_NS +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_RX_NS2 ?= 0 +ifeq ($(SPEECH_RX_NS2),1) +KBUILD_CPPFLAGS += -DSPEECH_RX_NS2 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_RX_NS2FLOAT ?= 0 +ifeq ($(SPEECH_RX_NS2FLOAT),1) +KBUILD_CPPFLAGS += -DSPEECH_RX_NS2FLOAT +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +export DSP_LIB ?= 1 +endif + +export SPEECH_RX_NS3 ?= 0 +ifeq ($(SPEECH_RX_NS3),1) +KBUILD_CPPFLAGS += -DSPEECH_RX_NS3 +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_RX_AGC ?= 0 +ifeq ($(SPEECH_RX_AGC),1) +KBUILD_CPPFLAGS += -DSPEECH_RX_AGC +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +endif + +export SPEECH_RX_EQ ?= 0 +ifeq ($(SPEECH_RX_EQ),1) +KBUILD_CPPFLAGS += -DSPEECH_RX_EQ +KBUILD_CPPFLAGS += -DHFP_DISABLE_NREC +export DSP_LIB ?= 1 +endif + +export SPEECH_RX_POST_GAIN ?= 0 +ifeq ($(SPEECH_RX_POST_GAIN),1) +KBUILD_CPPFLAGS += -DSPEECH_RX_POST_GAIN +endif + +export SPEECH_RX_24BIT ?= 0 +ifeq ($(SPEECH_RX_EQ),1) +# enable 24bit to fix low level signal distortion +export SPEECH_RX_24BIT = 1 +endif + + +export SPEECH_PROCESS_FRAME_MS ?= 16 +ifeq ($(SPEECH_CODEC_CAPTURE_CHANNEL_NUM),1) +export SPEECH_PROCESS_FRAME_MS = 15 +endif +ifeq ($(SPEECH_TX_2MIC_NS2),1) +export SPEECH_PROCESS_FRAME_MS = 15 +endif +ifeq ($(SPEECH_TX_THIRDPARTY),1) +export SPEECH_PROCESS_FRAME_MS = 15 +endif + +export SPEECH_SCO_FRAME_MS ?= 15 + +export SPEECH_SIDETONE ?= 0 +ifeq ($(SPEECH_SIDETONE),1) +KBUILD_CPPFLAGS += -DSPEECH_SIDETONE +ifeq ($(CHIP),best2000) +# Disable SCO resample +export SW_SCO_RESAMPLE := 0 +export NO_SCO_RESAMPLE := 1 +endif +endif + +ifeq ($(THIRDPARTY_LIB),aispeech) +export DSP_LIB ?= 1 +endif + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# Features for full application projects +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(FULL_APP_PROJECT),1) + +export BESLIB_INFO := $(GIT_REVISION) + +export SPEECH_LIB ?= 1 + +export FLASH_PROTECTION ?= 1 + +export APP_TEST_AUDIO ?= 0 + +export APP_TEST_MODE ?= 0 +ifeq ($(APP_TEST_MODE),1) +KBUILD_CPPFLAGS += -DAPP_TEST_MODE +endif + +export VOICE_PROMPT ?= 1 + +export AUDIO_QUEUE_SUPPORT ?= 1 + +export VOICE_RECOGNITION ?= 0 + +export ENGINEER_MODE ?= 1 +ifeq ($(ENGINEER_MODE),1) +FACTORY_MODE := 1 +endif +ifeq ($(FACTORY_MODE),1) +KBUILD_CPPFLAGS += -D__FACTORY_MODE_SUPPORT__ +endif + +export NEW_NV_RECORD_ENABLED ?= 1 +ifeq ($(NEW_NV_RECORD_ENABLED),1) +KBUILD_CPPFLAGS += -DNEW_NV_RECORD_ENABLED +KBUILD_CPPFLAGS += -Iservices/nv_section/userdata_section +endif + +ifeq ($(HEAR_THRU_PEAK_DET),1) +KBUILD_CPPFLAGS += -D__HEAR_THRU_PEAK_DET__ +endif + +KBUILD_CPPFLAGS += -DSPEECH_PROCESS_FRAME_MS=$(SPEECH_PROCESS_FRAME_MS) +KBUILD_CPPFLAGS += -DSPEECH_SCO_FRAME_MS=$(SPEECH_SCO_FRAME_MS) + +KBUILD_CPPFLAGS += -DMULTIPOINT_DUAL_SLAVE + +endif # FULL_APP_PROJECT + +ifeq ($(SPEECH_LIB),1) + +export DSP_LIB ?= 1 + +ifeq ($(USB_AUDIO_APP),1) +ifneq ($(USB_AUDIO_SEND_CHAN),$(SPEECH_CODEC_CAPTURE_CHANNEL_NUM)) +$(info ) +$(info CAUTION: Change USB_AUDIO_SEND_CHAN($(USB_AUDIO_SEND_CHAN)) to SPEECH_CODEC_CAPTURE_CHANNEL_NUM($(SPEECH_CODEC_CAPTURE_CHANNEL_NUM))) +$(info ) +export USB_AUDIO_SEND_CHAN := $(SPEECH_CODEC_CAPTURE_CHANNEL_NUM) +ifneq ($(USB_AUDIO_SEND_CHAN),$(SPEECH_CODEC_CAPTURE_CHANNEL_NUM)) +$(error ERROR: Failed to change USB_AUDIO_SEND_CHAN($(USB_AUDIO_SEND_CHAN))) +endif +endif +endif + +KBUILD_CPPFLAGS += -DSPEECH_CODEC_CAPTURE_CHANNEL_NUM=$(SPEECH_CODEC_CAPTURE_CHANNEL_NUM) +KBUILD_CPPFLAGS += -DSPEECH_ASR_CAPTURE_CHANNEL_NUM=$(SPEECH_ASR_CAPTURE_CHANNEL_NUM) +endif # SPEECH_LIB + +export USB_AUDIO_SPEECH ?= 0 +ifeq ($(USB_AUDIO_SPEECH),1) +export USB_AUDIO_DYN_CFG := 0 +export KEEP_SAME_LATENCY := 1 +endif + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# BISTO feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(BISTO_ENABLE),1) + +KBUILD_CFLAGS += -DBISTO_ENABLED + +KBUILD_CPPFLAGS += -DCFG_SW_KEY_LPRESS_THRESH_MS=1000 + +KBUILD_CPPFLAGS += -DDEBUG_BLE_DATAPATH=0 + +KBUILD_CFLAGS += -DCRC32_OF_IMAGE + +#export OPUS_CODEC ?= 1 +#ENCODING_ALGORITHM_OPUS 2 +#ENCODING_ALGORITHM_SBC 3 +#KBUILD_CPPFLAGS += -DVOB_ENCODING_ALGORITHM=3 + +# As MIX_MIC_DURING_MUSIC uses the isolated audio stream, if define MIX_MIC_DURING_MUSIC, +# the isolated audio stream must be enabled +KBUILD_CPPFLAGS += -DISOLATED_AUDIO_STREAM_ENABLED=1 + +ASSERT_SHOW_FILE_FUNC ?= 1 + +#KBUILD_CPPFLAGS += -DSAVING_AUDIO_DATA_TO_SD_ENABLED=1 + +KBUILD_CPPFLAGS += -DIS_GSOUND_BUTTION_HANDLER_WORKAROUND_ENABLED + +ifeq ($(GSOUND_HOTWORD_ENABLE), 1) +KBUILD_CFLAGS += -DGSOUND_HOTWORD_ENABLED +ifeq ($(GSOUND_HOTWORD_EXTERNAL), 1) +KBUILD_CFLAGS += -DGSOUND_HOTWORD_EXTERNAL +endif +endif + +REDUCED_GUESTURE_ENABLE ?= 0 + +BISTO_USE_TWS_API ?= 1 +ifeq ($(BISTO_USE_TWS_API), 1) +KBUILD_CPPFLAGS += -DBISTO_USE_TWS_API +endif + +ifeq ($(REDUCED_GUESTURE_ENABLE), 1) +KBUILD_CFLAGS += -DREDUCED_GUESTURE_ENABLED +endif +endif # BISTO_ENABLE + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# GFPS feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(GFPS_ENABLE),1) + +KBUILD_CPPFLAGS += -DGFPS_ENABLED +export BLE_SECURITY_ENABLED := 1 + +# this macro is used to determain if the resolveable private address is used for BLE +KBUILD_CPPFLAGS += -DBLE_USE_RPA + +endif # GFPS + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# AMA feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(AMA_VOICE),1) + +KBUILD_CPPFLAGS += -D__AMA_VOICE__ +KBUILD_CPPFLAGS += -DBLE_USE_RPA + +ifeq ($(CHIP),best1400) +KBUILD_CPPFLAGS += -DVOB_ENCODING_ALGORITHM=3 +export OPUS_CODEC ?= 0 +else +KBUILD_CPPFLAGS += -DVOB_ENCODING_ALGORITHM=2 +export OPUS_CODEC := 1 +endif +endif # AMA_VOICE + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# DMA feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(DMA_VOICE),1) +KBUILD_CPPFLAGS += -D__DMA_VOICE__ + +KBUILD_CPPFLAGS += -D__BES__ +KBUILD_CPPFLAGS += -DVOB_ENCODING_ALGORITHM=2 +KBUILD_CPPFLAGS += -DNVREC_BAIDU_DATA_SECTION +KBUILD_CPPFLAGS += -DBAIDU_DATA_RAND_LEN=8 +KBUILD_CPPFLAGS += -DFM_MIN_FREQ=875 +KBUILD_CPPFLAGS += -DFM_MAX_FREQ=1079 +KBUILD_CPPFLAGS += -DBAIDU_DATA_DEF_FM_FREQ=893 +KBUILD_CPPFLAGS += -DBAIDU_DATA_SN_LEN=16 +export OPUS_CODEC := 1 +export SHA256_ROM ?= 1 +export LIBC_ROM := 0 +ifeq ($(LIBC_ROM),1) +$(error LIBC_ROM should be 0 when DMA_VOICE=1) +endif +endif # DMA_VOICE + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# GMA feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(GMA_VOICE),1) +export AI_VOICE ?= 1 +KBUILD_CPPFLAGS += -D__GMA_VOICE__ + +#KBUILD_CPPFLAGS += -DKEYWORD_WAKEUP_ENABLED=0 +#KBUILD_CPPFLAGS += -DPUSH_AND_HOLD_ENABLED=1 +#KBUILD_CPPFLAGS += -DAI_32KBPS_VOICE=0 +KBUILD_CPPFLAGS += -DVOB_ENCODING_ALGORITHM=2 +export OPUS_CODEC := 1 +KBUILD_CPPFLAGS += -D__GMA_OTA_TWS__ +#KBUILD_CPPFLAGS += -DMCU_HIGH_PERFORMANCE_MODE +KBUILD_CPPFLAGS += -DGMA_HOLD_ACTIVE_ENABLE +endif + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# SMART_VOICE feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(SMART_VOICE),1) +KBUILD_CPPFLAGS += -D__SMART_VOICE__ +KBUILD_CPPFLAGS += -DVOB_ENCODING_ALGORITHM=2 +export OPUS_CODEC := 1 +#SPEECH_CODEC_CAPTURE_CHANNEL_NUM ?= 2 +#KBUILD_CPPFLAGS += -DMCU_HIGH_PERFORMANCE_MODE +#KBUILD_CPPFLAGS += -DSPEECH_CAPTURE_TWO_CHANNEL +endif # SMART_VOICE + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# TENCENT_VOICE feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(TENCENT_VOICE),1) +KBUILD_CPPFLAGS += -D__TENCENT_VOICE__ +KBUILD_CPPFLAGS += -DVOB_ENCODING_ALGORITHM=2 +export OPUS_CODEC := 1 +endif # TENCENT_VOICE + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# CUSTOMIZE feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(CUSTOMIZE_VOICE),1) +KBUILD_CPPFLAGS += -D__CUSTOMIZE_VOICE__ +KBUILD_CPPFLAGS += -DVOB_ENCODING_ALGORITHM=2 +export OPUS_CODEC := 1 +#SPEECH_CODEC_CAPTURE_CHANNEL_NUM ?= 2 +#KBUILD_CPPFLAGS += -DMCU_HIGH_PERFORMANCE_MODE +#KBUILD_CPPFLAGS += -DSPEECH_CAPTURE_TWO_CHANNEL +endif # CUSTOMIZE_VOICE + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# Dual MIC recording feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(DUAL_MIC_RECORDING),1) +KBUILD_CPPFLAGS += -D__DUAL_MIC_RECORDING__ +KBUILD_CPPFLAGS += -DVOB_ENCODING_ALGORITHM=2 +ifeq ($(LOWER_BANDWIDTH),1) +KBUILD_CPPFLAGS += -D__LOWER_BANDWIDTH__ +endif # LOWER_BANDWIDTH +export OPUS_CODEC := 1 +endif # DUAL_MIC_RECORDING + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# AI_VOICE feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(AI_VOICE),1) +KBUILD_CPPFLAGS += -D__AI_VOICE__ +KBUILD_CPPFLAGS += -DNO_ENCODING=0 +KBUILD_CPPFLAGS += -DENCODING_ALGORITHM_ADPCM=1 +KBUILD_CPPFLAGS += -DENCODING_ALGORITHM_OPUS=2 +KBUILD_CPPFLAGS += -DENCODING_ALGORITHM_SBC=3 +KBUILD_CPPFLAGS += -DOS_DYNAMIC_MEM_SIZE=0x6800 +ifeq ($(OPUS_CODEC),1) +KBUILD_CPPFLAGS += -DOPUS_IN_OVERLAY +endif + +ifeq ($(filter -DISOLATED_AUDIO_STREAM_ENABLED=1,$(KBUILD_CPPFLAGS)),) +KBUILD_CPPFLAGS += -DISOLATED_AUDIO_STREAM_ENABLED=1 +endif + +ifneq ($(filter -DVOB_ENCODING_ALGORITHM=2,$(KBUILD_CPPFLAGS)),) +ifneq ($(USE_KNOWLES),1) +ifneq ($(ALEXA_WWE),1) +export AF_STACK_SIZE ?= 16384 +endif +endif +endif +endif # AI_VOICE + +ifeq ($(THROUGH_PUT),1) +KBUILD_CPPFLAGS += -D__THROUGH_PUT__ +endif # THROUGH_PUT + +ifeq ($(USE_KNOWLES),1) +KBUILD_CPPFLAGS += -D__KNOWLES +KBUILD_CPPFLAGS += -DIDLE_ALEXA_KWD +export THIRDPARTY_LIB := knowles_uart +endif + +AI_CAPTURE_CHANNEL_NUM ?= 0 +ifneq ($(AI_CAPTURE_CHANNEL_NUM),0) +KBUILD_CPPFLAGS += -DAI_CAPTURE_CHANNEL_NUM=$(AI_CAPTURE_CHANNEL_NUM) +endif + +AI_CAPTURE_DATA_AEC ?= 0 +ifeq ($(AI_CAPTURE_DATA_AEC),1) +KBUILD_CPPFLAGS += -DAI_CAPTURE_DATA_AEC +KBUILD_CPPFLAGS += -DAI_ALGORITHM_ENABLE +KBUILD_CPPFLAGS += -DAEC_STERE_ON +endif + +export AI_AEC_CP_ACCEL ?= 0 +ifeq ($(AI_AEC_CP_ACCEL),1) +KBUILD_CPPFLAGS += -DAI_AEC_CP_ACCEL +endif + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# MULTI_AI feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(IS_MULTI_AI_ENABLE),1) +export SHA256_ROM ?= 1 +KBUILD_CPPFLAGS += -DIS_MULTI_AI_ENABLED +endif # MULTI_AI + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# VOICE_DATAPATH feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(VOICE_DATAPATH_ENABLED),1) +KBUILD_CPPFLAGS += -DVOICE_DATAPATH +endif # VOICE_DATAPATH + +export SLAVE_ADV_BLE_ENABLED ?= 0 +ifeq ($(SLAVE_ADV_BLE_ENABLED),1) +KBUILD_CPPFLAGS += -DSLAVE_ADV_BLE +endif + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# TILE feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(TILE_DATAPATH_ENABLED),1) +KBUILD_CPPFLAGS += -DTILE_DATAPATH +endif + +export CUSTOM_INFORMATION_TILE_ENABLE ?= 0 +ifeq ($(CUSTOM_INFORMATION_TILE_ENABLE),1) +KBUILD_CPPFLAGS += -DCUSTOM_INFORMATION_TILE=1 +endif # TILE + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# MFI feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(IOS_MFI),1) +KBUILD_CPPFLAGS += -DIOS_IAP2_PROTOCOL +endif # IOS_MFI + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# MIX_MIC_DURING_MUSIC feature +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(MIX_MIC_DURING_MUSIC_ENABLED),1) +KBUILD_CPPFLAGS += -DMIX_MIC_DURING_MUSIC +endif + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# Put customized features above +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# Obsoleted features +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +OBSOLETED_FEATURE_LIST := EQ_PROCESS RB_CODEC AUDIO_EQ_PROCESS MEDIA_PLAYER_RBCODEC +USED_OBSOLETED_FEATURE := $(strip $(foreach f,$(OBSOLETED_FEATURE_LIST),$(if $(filter 1,$($f)),$f))) +ifneq ($(USED_OBSOLETED_FEATURE),) +$(error Obsoleted features: $(USED_OBSOLETED_FEATURE)) +endif + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# Flash suspend features +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(FLASH_SUSPEND), 1) +KBUILD_CPPFLAGS += -DFLASH_SUSPEND +endif + +# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv +# BLE only enable features +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ifeq ($(BLE_ONLY_ENABLED),1) +KBUILD_CPPFLAGS += -DBLE_ONLY_ENABLED +KBUILD_CPPFLAGS += -DBLE_POWER_LEVEL_0 +endif + +# ------------------------------------------- +# General +# ------------------------------------------- + +ifneq ($(NO_CONFIG),1) +core-y += config/ +endif + +ifneq ($(NO_BOOT_STRUCT),1) +core-y += $(call add_if_exists,utils/boot_struct/) +endif + +export DEFAULT_CFG_SRC ?= _default_cfg_src_ + +ifneq ($(wildcard $(srctree)/config/$(T)/tgt_hardware.h $(srctree)/config/$(T)/res/),) +KBUILD_CPPFLAGS += -Iconfig/$(T) +endif +KBUILD_CPPFLAGS += -Iconfig/$(DEFAULT_CFG_SRC) + +CPU_CFLAGS := -mthumb +ifeq ($(CPU),a7) +CPU_CFLAGS += -march=armv7-a +else ifeq ($(CPU),m33) +ifeq ($(CPU_NO_DSP),1) +CPU_CFLAGS += -mcpu=cortex-m33+nodsp +else +CPU_CFLAGS += -mcpu=cortex-m33 +endif +else +CPU_CFLAGS += -mcpu=cortex-m4 +endif + +export UNALIGNED_ACCESS ?= 1 +ifeq ($(UNALIGNED_ACCESS),1) +KBUILD_CPPFLAGS += -DUNALIGNED_ACCESS +else +CPU_CFLAGS += -mno-unaligned-access +endif + +ifeq ($(CHIP_HAS_FPU),1) +ifeq ($(CPU),a7) +CPU_CFLAGS += -mfpu=vfpv3-d16 +else ifeq ($(CPU),m33) +CPU_CFLAGS += -mfpu=fpv5-sp-d16 +else +CPU_CFLAGS += -mfpu=fpv4-sp-d16 +endif +ifeq ($(SOFT_FLOAT_ABI),1) +CPU_CFLAGS += -mfloat-abi=softfp +else +CPU_CFLAGS += -mfloat-abi=hard +endif +else +CPU_CFLAGS += -mfloat-abi=soft +endif + +ifneq ($(ALLOW_WARNING),1) +KBUILD_CPPFLAGS += -Werror +endif + +ifeq ($(PIE),1) +ifneq ($(TOOLCHAIN),armclang) +ifneq ($(NOSTD),1) +$(error PIE can only work when NOSTD=1) +endif +KBUILD_CPPFLAGS += -msingle-pic-base +endif +KBUILD_CPPFLAGS += -fPIE +# -pie option will generate .dynamic section +#LDFLAGS += -pie +#LDFLAGS += -z relro -z now +endif + +KBUILD_CPPFLAGS += $(CPU_CFLAGS) $(SPECS_CFLAGS) +LINK_CFLAGS += $(CPU_CFLAGS) $(SPECS_CFLAGS) +CFLAGS_IMAGE += $(CPU_CFLAGS) $(SPECS_CFLAGS) + +# Save 100+ bytes by filling less alignment holes +# TODO: Array alignment? +#LDFLAGS += --sort-common --sort-section=alignment + +ifeq ($(CTYPE_PTR_DEF),1) +ifeq ($(TOOLCHAIN),armclang) +$(error CTYPE_PTR_DEF is not supported in $(TOOLCHAIN)) +else +LDFLAGS_IMAGE += --defsym __ctype_ptr__=0 +endif +endif + +export RAND_FROM_MIC ?= 0 +ifeq ($(RAND_FROM_MIC),1) +KBUILD_CPPFLAGS += -D__RAND_FROM_MIC__ +endif + +export RSSI_GATHERING_ENABLED ?= 0 +ifeq ($(RSSI_GATHERING_ENABLED),1) +KBUILD_CPPFLAGS += -DRSSI_GATHERING_ENABLED +endif + +export TOTA ?= 0 +ifeq ($(TOTA),1) +KBUILD_CPPFLAGS += -DTOTA +KBUILD_CPPFLAGS += -DRSSI_GATHERING_ENABLED +endif + +export POWER_ON_ENTER_TWS_PAIRING_ENABLED ?= 0 +ifeq ($(POWER_ON_ENTER_TWS_PAIRING_ENABLED),1) +KBUILD_CPPFLAGS += -DPOWER_ON_ENTER_TWS_PAIRING_ENABLED +endif \ No newline at end of file diff --git a/include/rtos/freertos/FreeRTOS.h b/include/rtos/freertos/FreeRTOS.h new file mode 100644 index 0000000..c4b5c3b --- /dev/null +++ b/include/rtos/freertos/FreeRTOS.h @@ -0,0 +1,1186 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* + * If stdint.h cannot be located then: + * + If using GCC ensure the -nostdint options is *not* being used. + * + Ensure the project's include path includes the directory in which your + * compiler stores stdint.h. + * + Set any compiler options necessary for it to support C99, as technically + * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any + * other way). + * + The FreeRTOS download includes a simple stdint.h definition that can be + * used in cases where none is provided by the compiler. The files only + * contains the typedefs required to build FreeRTOS. Read the instructions + * in FreeRTOS/source/stdint.readme for more information. + */ +#include /* READ COMMENT ABOVE. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Definitions specific to the port being used. */ +#include "portable.h" + +/* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */ +#ifndef configUSE_NEWLIB_REENTRANT + #define configUSE_NEWLIB_REENTRANT 0 +#endif + +/* Required if struct _reent is used. */ +#if ( configUSE_NEWLIB_REENTRANT == 1 ) + #include +#endif +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configMINIMAL_STACK_SIZE + #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value. +#endif + +#ifndef configMAX_PRIORITIES + #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if configMAX_PRIORITIES < 1 + #error configMAX_PRIORITIES must be defined to be greater than or equal to 1. +#endif + +#ifndef configUSE_PREEMPTION + #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK + #error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK + #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_16_BIT_TICKS + #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_CO_ROUTINES + #define configUSE_CO_ROUTINES 0 +#endif + +#ifndef INCLUDE_vTaskPrioritySet + #define INCLUDE_vTaskPrioritySet 0 +#endif + +#ifndef INCLUDE_uxTaskPriorityGet + #define INCLUDE_uxTaskPriorityGet 0 +#endif + +#ifndef INCLUDE_vTaskDelete + #define INCLUDE_vTaskDelete 0 +#endif + +#ifndef INCLUDE_vTaskSuspend + #define INCLUDE_vTaskSuspend 0 +#endif + +#ifndef INCLUDE_vTaskDelayUntil + #define INCLUDE_vTaskDelayUntil 0 +#endif + +#ifndef INCLUDE_vTaskDelay + #define INCLUDE_vTaskDelay 0 +#endif + +#ifndef INCLUDE_xTaskGetIdleTaskHandle + #define INCLUDE_xTaskGetIdleTaskHandle 0 +#endif + +#ifndef INCLUDE_xTaskAbortDelay + #define INCLUDE_xTaskAbortDelay 0 +#endif + +#ifndef INCLUDE_xQueueGetMutexHolder + #define INCLUDE_xQueueGetMutexHolder 0 +#endif + +#ifndef INCLUDE_xSemaphoreGetMutexHolder + #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder +#endif + +#ifndef INCLUDE_xTaskGetHandle + #define INCLUDE_xTaskGetHandle 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef INCLUDE_eTaskGetState + #define INCLUDE_eTaskGetState 0 +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 +#endif + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 0 +#endif + +#if configUSE_CO_ROUTINES != 0 + #ifndef configMAX_CO_ROUTINE_PRIORITIES + #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. + #endif +#endif + +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS + #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API + #define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB + #define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h +#endif + +#ifndef configASSERT + #define configASSERT( x ) + #define configASSERT_DEFINED 0 +#else + #define configASSERT_DEFINED 1 +#endif + +/* The timers module relies on xTaskGetSchedulerState(). */ +#if configUSE_TIMERS == 1 + + #ifndef configTIMER_TASK_PRIORITY + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. + #endif /* configTIMER_TASK_PRIORITY */ + + #ifndef configTIMER_QUEUE_LENGTH + #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. + #endif /* configTIMER_QUEUE_LENGTH */ + + #ifndef configTIMER_TASK_STACK_DEPTH + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. + #endif /* configTIMER_TASK_STACK_DEPTH */ + +#endif /* configUSE_TIMERS */ + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#endif + +#ifndef portCLEAN_UP_TCB + #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef portPRE_TASK_DELETE_HOOK + #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending ) +#endif + +#ifndef portSETUP_TCB + #define portSETUP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 0U +#endif + +#if ( configQUEUE_REGISTRY_SIZE < 1 ) + #define vQueueAddToRegistry( xQueue, pcName ) + #define vQueueUnregisterQueue( xQueue ) + #define pcQueueGetName( xQueue ) +#endif + +#ifndef portPOINTER_SIZE_TYPE + #define portPOINTER_SIZE_TYPE uint32_t +#endif + +/* Remove any unused trace macros. */ +#ifndef traceSTART + /* Used to perform any necessary initialisation - for example, open a file + into which trace is to be written. */ + #define traceSTART() +#endif + +#ifndef traceEND + /* Use to close a trace, for example close a file into which trace has been + written. */ + #define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN + /* Called after a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the selected task. */ + #define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceINCREASE_TICK_COUNT + /* Called before stepping the tick count after waking from tickless idle + sleep. */ + #define traceINCREASE_TICK_COUNT( x ) +#endif + +#ifndef traceLOW_POWER_IDLE_BEGIN + /* Called immediately before entering tickless idle. */ + #define traceLOW_POWER_IDLE_BEGIN() +#endif + +#ifndef traceLOW_POWER_IDLE_END + /* Called when returning to the Idle task after a tickless idle. */ + #define traceLOW_POWER_IDLE_END() +#endif + +#ifndef traceTASK_SWITCHED_OUT + /* Called before a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the task being switched out. */ + #define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceTASK_PRIORITY_INHERIT + /* Called when a task attempts to take a mutex that is already held by a + lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task + that holds the mutex. uxInheritedPriority is the priority the mutex holder + will inherit (the priority of the task that is attempting to obtain the + muted. */ + #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) +#endif + +#ifndef traceTASK_PRIORITY_DISINHERIT + /* Called when a task releases a mutex, the holding of which had resulted in + the task inheriting the priority of a higher priority task. + pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the + mutex. uxOriginalPriority is the task's configured (base) priority. */ + #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_PEEK + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND + /* Task is about to block because it cannot write to a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the write was attempted. pxCurrentTCB points to the TCB of the + task that attempted the write. */ + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +#ifndef configRECORD_STACK_HIGH_ADDRESS + #define configRECORD_STACK_HIGH_ADDRESS 0 +#endif + +#ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H + #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceMOVED_TASK_TO_READY_STATE + #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef tracePOST_MOVED_TASK_TO_READY_STATE + #define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED( ucQueueType ) +#endif + +#ifndef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE + #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE + #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED + #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE + #define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FAILED + #define traceQUEUE_PEEK_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR + #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED + #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED() +#endif + +#ifndef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL + #define traceTASK_DELAY_UNTIL( x ) +#endif + +#ifndef traceTASK_DELAY + #define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK + #define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef traceTIMER_CREATE + #define traceTIMER_CREATE( pxNewTimer ) +#endif + +#ifndef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() +#endif + +#ifndef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) +#endif + +#ifndef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( pxTimer ) +#endif + +#ifndef traceTIMER_COMMAND_RECEIVED + #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) +#endif + +#ifndef traceMALLOC + #define traceMALLOC( pvAddress, uiSize ) +#endif + +#ifndef traceFREE + #define traceFREE( pvAddress, uiSize ) +#endif + +#ifndef traceEVENT_GROUP_CREATE + #define traceEVENT_GROUP_CREATE( xEventGroup ) +#endif + +#ifndef traceEVENT_GROUP_CREATE_FAILED + #define traceEVENT_GROUP_CREATE_FAILED() +#endif + +#ifndef traceEVENT_GROUP_SYNC_BLOCK + #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_SYNC_END + #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK + #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_END + #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS + #define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR + #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS + #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR + #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_DELETE + #define traceEVENT_GROUP_DELETE( xEventGroup ) +#endif + +#ifndef tracePEND_FUNC_CALL + #define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef tracePEND_FUNC_CALL_FROM_ISR + #define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef traceQUEUE_REGISTRY_ADD + #define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName) +#endif + +#ifndef traceTASK_NOTIFY_TAKE_BLOCK + #define traceTASK_NOTIFY_TAKE_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_TAKE + #define traceTASK_NOTIFY_TAKE() +#endif + +#ifndef traceTASK_NOTIFY_WAIT_BLOCK + #define traceTASK_NOTIFY_WAIT_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_WAIT + #define traceTASK_NOTIFY_WAIT() +#endif + +#ifndef traceTASK_NOTIFY + #define traceTASK_NOTIFY() +#endif + +#ifndef traceTASK_NOTIFY_FROM_ISR + #define traceTASK_NOTIFY_FROM_ISR() +#endif + +#ifndef traceTASK_NOTIFY_GIVE_FROM_ISR + #define traceTASK_NOTIFY_GIVE_FROM_ISR() +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_FAILED + #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED + #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE + #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_DELETE + #define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RESET + #define traceSTREAM_BUFFER_RESET( xStreamBuffer ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND + #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND + #define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FAILED + #define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FROM_ISR + #define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE + #define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE + #define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FAILED + #define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FROM_ISR + #define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) +#endif + +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. + #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + + #ifndef portGET_RUN_TIME_COUNTER_VALUE + #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. + #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ + #endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT + #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API + #define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef portSUPPRESS_TICKS_AND_SLEEP + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) +#endif + +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 +#endif + +#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 + #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 +#endif + +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 +#endif + +#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING + #define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPRE_SLEEP_PROCESSING + #define configPRE_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPOST_SLEEP_PROCESSING + #define configPOST_SLEEP_PROCESSING( x ) +#endif + +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif + +#ifndef portTASK_USES_FLOATING_POINT + #define portTASK_USES_FLOATING_POINT() +#endif + +#ifndef portTASK_CALLS_SECURE_FUNCTIONS + #define portTASK_CALLS_SECURE_FUNCTIONS() +#endif + +#ifndef configUSE_TIME_SLICING + #define configUSE_TIME_SLICING 1 +#endif + +#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 +#endif + +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#endif + +#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + +#ifndef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 0 +#endif + +#ifndef mtCOVERAGE_TEST_MARKER + #define mtCOVERAGE_TEST_MARKER() +#endif + +#ifndef mtCOVERAGE_TEST_DELAY + #define mtCOVERAGE_TEST_DELAY() +#endif + +#ifndef portASSERT_IF_IN_ISR + #define portASSERT_IF_IN_ISR() +#endif + +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#endif + +#ifndef configAPPLICATION_ALLOCATED_HEAP + #define configAPPLICATION_ALLOCATED_HEAP 0 +#endif + +#ifndef configUSE_TASK_NOTIFICATIONS + #define configUSE_TASK_NOTIFICATIONS 1 +#endif + +#ifndef configUSE_POSIX_ERRNO + #define configUSE_POSIX_ERRNO 0 +#endif + +#ifndef portTICK_TYPE_IS_ATOMIC + #define portTICK_TYPE_IS_ATOMIC 0 +#endif + +#ifndef configSUPPORT_STATIC_ALLOCATION + /* Defaults to 0 for backward compatibility. */ + #define configSUPPORT_STATIC_ALLOCATION 0 +#endif + +#ifndef configSUPPORT_DYNAMIC_ALLOCATION + /* Defaults to 1 for backward compatibility. */ + #define configSUPPORT_DYNAMIC_ALLOCATION 1 +#endif + +#ifndef configSTACK_DEPTH_TYPE + /* Defaults to uint16_t for backward compatibility, but can be overridden + in FreeRTOSConfig.h if uint16_t is too restrictive. */ + #define configSTACK_DEPTH_TYPE uint16_t +#endif + +#ifndef configMESSAGE_BUFFER_LENGTH_TYPE + /* Defaults to size_t for backward compatibility, but can be overridden + in FreeRTOSConfig.h if lengths will always be less than the number of bytes + in a size_t. */ + #define configMESSAGE_BUFFER_LENGTH_TYPE size_t +#endif + +/* Sanity check the configuration. */ +#if( configUSE_TICKLESS_IDLE != 0 ) + #if( INCLUDE_vTaskSuspend != 1 ) + #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0 + #endif /* INCLUDE_vTaskSuspend */ +#endif /* configUSE_TICKLESS_IDLE */ + +#if( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) + #error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. +#endif + +#if( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) ) + #error configUSE_MUTEXES must be set to 1 to use recursive mutexes +#endif + +#ifndef configINITIAL_TICK_COUNT + #define configINITIAL_TICK_COUNT 0 +#endif + +#if( portTICK_TYPE_IS_ATOMIC == 0 ) + /* Either variables of tick type cannot be read atomically, or + portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when + the tick count is returned to the standard critical section macros. */ + #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) +#else + /* The tick type can be read atomically, so critical sections used when the + tick count is returned can be defined away. */ + #define portTICK_TYPE_ENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x +#endif + +/* Definitions to allow backward compatibility with FreeRTOS versions prior to +V8 if desired. */ +#ifndef configENABLE_BACKWARD_COMPATIBILITY + #define configENABLE_BACKWARD_COMPATIBILITY 1 +#endif + +#ifndef configPRINTF + /* configPRINTF() was not defined, so define it away to nothing. To use + configPRINTF() then define it as follows (where MyPrintFunction() is + provided by the application writer): + + void MyPrintFunction(const char *pcFormat, ... ); + #define configPRINTF( X ) MyPrintFunction X + + Then call like a standard printf() function, but placing brackets around + all parameters so they are passed as a single parameter. For example: + configPRINTF( ("Value = %d", MyVariable) ); */ + #define configPRINTF( X ) +#endif + +#ifndef configMAX + /* The application writer has not provided their own MAX macro, so define + the following generic implementation. */ + #define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) +#endif + +#ifndef configMIN + /* The application writer has not provided their own MAX macro, so define + the following generic implementation. */ + #define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#endif + +#if configENABLE_BACKWARD_COMPATIBILITY == 1 + #define eTaskStateGet eTaskGetState + #define portTickType TickType_t + #define xTaskHandle TaskHandle_t + #define xQueueHandle QueueHandle_t + #define xSemaphoreHandle SemaphoreHandle_t + #define xQueueSetHandle QueueSetHandle_t + #define xQueueSetMemberHandle QueueSetMemberHandle_t + #define xTimeOutType TimeOut_t + #define xMemoryRegion MemoryRegion_t + #define xTaskParameters TaskParameters_t + #define xTaskStatusType TaskStatus_t + #define xTimerHandle TimerHandle_t + #define xCoRoutineHandle CoRoutineHandle_t + #define pdTASK_HOOK_CODE TaskHookFunction_t + #define portTICK_RATE_MS portTICK_PERIOD_MS + #define pcTaskGetTaskName pcTaskGetName + #define pcTimerGetTimerName pcTimerGetName + #define pcQueueGetQueueName pcQueueGetName + #define vTaskGetTaskInfo vTaskGetInfo + + /* Backward compatibility within the scheduler code only - these definitions + are not really required but are included for completeness. */ + #define tmrTIMER_CALLBACK TimerCallbackFunction_t + #define pdTASK_CODE TaskFunction_t + #define xListItem ListItem_t + #define xList List_t + + /* For libraries that break the list data hiding, and access list structure + members directly (which is not supposed to be done). */ + #define pxContainer pvContainer +#endif /* configENABLE_BACKWARD_COMPATIBILITY */ + +#if( configUSE_ALTERNATIVE_API != 0 ) + #error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0 +#endif + +/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even +if floating point hardware is otherwise supported by the FreeRTOS port in use. +This constant is not supported by all FreeRTOS ports that include floating +point support. */ +#ifndef configUSE_TASK_FPU_SUPPORT + #define configUSE_TASK_FPU_SUPPORT 1 +#endif + +/* + * In line with software engineering best practice, FreeRTOS implements a strict + * data hiding policy, so the real structures used by FreeRTOS to maintain the + * state of tasks, queues, semaphores, etc. are not accessible to the application + * code. However, if the application writer wants to statically allocate such + * an object then the size of the object needs to be know. Dummy structures + * that are guaranteed to have the same size and alignment requirements of the + * real objects are used for this purpose. The dummy list and list item + * structures below are used for inclusion in such a dummy structure. + */ +struct xSTATIC_LIST_ITEM +{ + TickType_t xDummy1; + void *pvDummy2[ 4 ]; +}; +typedef struct xSTATIC_LIST_ITEM StaticListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +struct xSTATIC_MINI_LIST_ITEM +{ + TickType_t xDummy1; + void *pvDummy2[ 2 ]; +}; +typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +typedef struct xSTATIC_LIST +{ + UBaseType_t uxDummy1; + void *pvDummy2; + StaticMiniListItem_t xDummy3; +} StaticList_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Task structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a task then + * the size of the task object needs to be know. The StaticTask_t structure + * below is provided for this purpose. Its sizes and alignment requirements are + * guaranteed to match those of the genuine structure, no matter which + * architecture is being used, and no matter how the values in FreeRTOSConfig.h + * are set. Its contents are somewhat obfuscated in the hope users will + * recognise that it would be unwise to make direct use of the structure members. + */ +typedef struct xSTATIC_TCB +{ + void *pxDummy1; + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xDummy2; + #endif + StaticListItem_t xDummy3[ 2 ]; + UBaseType_t uxDummy5; + void *pxDummy6; + uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + void *pxDummy8; + #endif + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxDummy9; + #endif + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy10[ 2 ]; + #endif + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxDummy12[ 2 ]; + #endif + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void *pxDummy14; + #endif + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulDummy16; + #endif + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + struct _reent xDummy17; + #endif + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t ulDummy18; + uint8_t ucDummy19; + #endif + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t uxDummy20; + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDummy21; + #endif + #if ( configUSE_POSIX_ERRNO == 1 ) + int iDummy22; + #endif +} StaticTask_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Queue structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a queue + * then the size of the queue object needs to be know. The StaticQueue_t + * structure below is provided for this purpose. Its sizes and alignment + * requirements are guaranteed to match those of the genuine structure, no + * matter which architecture is being used, and no matter how the values in + * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope + * users will recognise that it would be unwise to make direct use of the + * structure members. + */ +typedef struct xSTATIC_QUEUE +{ + void *pvDummy1[ 3 ]; + + union + { + void *pvDummy2; + UBaseType_t uxDummy2; + } u; + + StaticList_t xDummy3[ 2 ]; + UBaseType_t uxDummy4[ 3 ]; + uint8_t ucDummy5[ 2 ]; + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy6; + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + void *pvDummy7; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy8; + uint8_t ucDummy9; + #endif + +} StaticQueue_t; +typedef StaticQueue_t StaticSemaphore_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the event group structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create an event group then the size of the event group object needs to be + * know. The StaticEventGroup_t structure below is provided for this purpose. + * Its sizes and alignment requirements are guaranteed to match those of the + * genuine structure, no matter which architecture is being used, and no matter + * how the values in FreeRTOSConfig.h are set. Its contents are somewhat + * obfuscated in the hope users will recognise that it would be unwise to make + * direct use of the structure members. + */ +typedef struct xSTATIC_EVENT_GROUP +{ + TickType_t xDummy1; + StaticList_t xDummy2; + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy3; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy4; + #endif + +} StaticEventGroup_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the software timer structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create a software timer then the size of the queue object needs to be know. + * The StaticTimer_t structure below is provided for this purpose. Its sizes + * and alignment requirements are guaranteed to match those of the genuine + * structure, no matter which architecture is being used, and no matter how the + * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in + * the hope users will recognise that it would be unwise to make direct use of + * the structure members. + */ +typedef struct xSTATIC_TIMER +{ + void *pvDummy1; + StaticListItem_t xDummy2; + TickType_t xDummy3; + UBaseType_t uxDummy4; + void *pvDummy5; + TaskFunction_t pvDummy6; + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy7; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy8; + #endif + +} StaticTimer_t; + +/* +* In line with software engineering best practice, especially when supplying a +* library that is likely to change in future versions, FreeRTOS implements a +* strict data hiding policy. This means the stream buffer structure used +* internally by FreeRTOS is not accessible to application code. However, if +* the application writer wants to statically allocate the memory required to +* create a stream buffer then the size of the stream buffer object needs to be +* know. The StaticStreamBuffer_t structure below is provided for this purpose. +* Its size and alignment requirements are guaranteed to match those of the +* genuine structure, no matter which architecture is being used, and no matter +* how the values in FreeRTOSConfig.h are set. Its contents are somewhat +* obfuscated in the hope users will recognise that it would be unwise to make +* direct use of the structure members. +*/ +typedef struct xSTATIC_STREAM_BUFFER +{ + size_t uxDummy1[ 4 ]; + void * pvDummy2[ 3 ]; + uint8_t ucDummy3; + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy4; + #endif +} StaticStreamBuffer_t; + +/* Message buffers are built on stream buffers. */ +typedef StaticStreamBuffer_t StaticMessageBuffer_t; + +#ifdef __cplusplus +} +#endif + +#endif /* INC_FREERTOS_H */ + diff --git a/include/rtos/freertos/FreeRTOSConfig.h b/include/rtos/freertos/FreeRTOSConfig.h new file mode 100644 index 0000000..5e13baf --- /dev/null +++ b/include/rtos/freertos/FreeRTOSConfig.h @@ -0,0 +1,238 @@ +/* -------------------------------------------------------------------------- + * Copyright (c) 2013-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. + * + * -------------------------------------------------------------------------- + * + * $Revision: V10.1.1 + * + * Project: CMSIS-FreeRTOS + * Title: FreeRTOS configuration definitions + * + * --------------------------------------------------------------------------*/ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#include + +//#include "RTE_Components.h" +//#include CMSIS_device_header +#include "cmsis.h" +#include "hal_trace.h" + +//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- + +// Minimal stack size [words] <0-65535> +// Stack for idle task and default task stack in words. +// Default: 128 +#define configMINIMAL_STACK_SIZE ((uint16_t)(512)) + +// Total heap size [bytes] <0-0xFFFFFFFF> +// Heap memory size in bytes. +// Default: 8192 +#define configTOTAL_HEAP_SIZE ((size_t)(8192 * 4)) + +// Kernel tick frequency [Hz] <0-0xFFFFFFFF> +// Kernel tick rate in Hz. +// Default: 1000 +#define configTICK_RATE_HZ ((TickType_t)1000) + +// Timer task stack depth [words] <0-65535> +// Stack for timer task in words. +// Default: 80 +#define configTIMER_TASK_STACK_DEPTH 512 + +// Timer task priority <0-56> +// Timer task priority. +// Default: 40 (High) +#define configTIMER_TASK_PRIORITY 40 + +// Timer queue length <0-1024> +// Timer command queue length. +// Default: 5 +#define configTIMER_QUEUE_LENGTH 25 + +// Preemption interrupt priority +// Maximum priority of interrupts that are safe to call FreeRTOS API. +// Default: 16 +//#define configMAX_SYSCALL_INTERRUPT_PRIORITY 16 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 64 + +// Use time slicing +// Enable setting to use timeslicing. +// Default: 1 +#define configUSE_TIME_SLICING 1 + +// Idle should yield +// Control Yield behaviour of the idle task. +// Default: 1 +#define configIDLE_SHOULD_YIELD 1 + +#define configUSE_TICKLESS_IDLE 1 + +// Check for stack overflow +// <0=>Disable <1=>Method one <2=>Method two +// Enable or disable stack overflow checking. +// Callback function vApplicationStackOverflowHook implementation is required when stack checking is enabled. +// Default: 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 + +// Use idle hook +// Enable callback function call on each idle task iteration. +// Callback function vApplicationIdleHook implementation is required when idle hook is enabled. +// Default: 0 +#define configUSE_IDLE_HOOK 1 + +// Use tick hook +// Enable callback function call during each tick interrupt. +// Callback function vApplicationTickHook implementation is required when tick hook is enabled. +// Default: 0 +#define configUSE_TICK_HOOK 0 + +// Use deamon task startup hook +// Enable callback function call when timer service starts. +// Callback function vApplicationDaemonTaskStartupHook implementation is required when deamon task startup hook is enabled. +// Default: 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +// Use malloc failed hook +// Enable callback function call when out of dynamic memory. +// Callback function vApplicationMallocFailedHook implementation is required when malloc failed hook is enabled. +// Default: 0 +#define configUSE_MALLOC_FAILED_HOOK 1 + +// Queue registry size +// Define maximum number of queue objects registered for debug purposes. +// The queue registry is used by kernel aware debuggers to locate queue and semaphore structures and display associated text names. +// Default: 0 +#define configQUEUE_REGISTRY_SIZE 0 + +//#define configGENERATE_RUN_TIME_STATS 1 +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 + +// Used for the minist time for enter deep sleep +// Default: 4 +#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 5 + +// Event Recorder configuration +// Initialize and setup Event Recorder level filtering. +// Settings have no effect when Event Recorder is not present. + +// Initialize Event Recorder +// Initialize Event Recorder before FreeRTOS kernel start. +// Default: 1 +#define configEVR_INITIALIZE 1 + +// Setup recording level filter +// Enable configuration of FreeRTOS events recording level +// Default: 1 +#define configEVR_SETUP_LEVEL 1 + +// Tasks functions +// Define event recording level bitmask for events generated from Tasks functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_TASKS 0x05 + +// Queue functions +// Define event recording level bitmask for events generated from Queue functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_QUEUE 0x05 + +// Timer functions +// Define event recording level bitmask for events generated from Timer functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_TIMERS 0x05 + +// Event Groups functions +// Define event recording level bitmask for events generated from Event Groups functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_EVENTGROUPS 0x05 + +// Heap functions +// Define event recording level bitmask for events generated from Heap functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_HEAP 0x05 + +// Stream Buffer functions +// Define event recording level bitmask for events generated from Stream Buffer functions. +// Default: 0x05 +// <0x00=>Off <0x01=>Errors <0x05=>Errors + Operation <0x0F=>All +#define configEVR_LEVEL_STREAMBUFFER 0x05 +// +// +#define configASSERT( x ) do {ASSERT( x, "%s %s, %d\n", #x, __func__, __LINE__)} while(0) +//------------- <<< end of configuration section >>> --------------------------- + +extern uint32_t SystemCoreClock; + +/* Defines needed by FreeRTOS to implement CMSIS RTOS2 API. Do not change! */ +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configUSE_PREEMPTION 1 +#define configUSE_TIMERS 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configMAX_PRIORITIES 56 +#define configKERNEL_INTERRUPT_PRIORITY 255 + +/* Defines that include FreeRTOS functions which implement CMSIS RTOS2 API. Do not change! */ +#define INCLUDE_xEventGroupSetBitsFromISR 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xTimerPendFunctionCall 1 + +/* Map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ +#define xPortPendSVHandler PendSV_Handler +#define vPortSVCHandler SVC_Handler + +/* Include debug event definitions */ +#include "freertos_evr.h" + +#endif /* FREERTOS_CONFIG_H */ diff --git a/include/rtos/freertos/StackMacros.h b/include/rtos/freertos/StackMacros.h new file mode 100644 index 0000000..b6eaec3 --- /dev/null +++ b/include/rtos/freertos/StackMacros.h @@ -0,0 +1,133 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +#ifndef _MSC_VER /* Visual Studio doesn't support #warning. */ + #warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in future released. +#endif + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ + const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ + \ + if( ( pulStack[ 0 ] != ulCheckValue ) || \ + ( pulStack[ 1 ] != ulCheckValue ) || \ + ( pulStack[ 2 ] != ulCheckValue ) || \ + ( pulStack[ 3 ] != ulCheckValue ) ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ + static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +/* Remove stack overflow macro if not being used. */ +#ifndef taskCHECK_FOR_STACK_OVERFLOW + #define taskCHECK_FOR_STACK_OVERFLOW() +#endif + + + +#endif /* STACK_MACROS_H */ + diff --git a/include/rtos/freertos/cmsis_os.h b/include/rtos/freertos/cmsis_os.h new file mode 100644 index 0000000..b3e7922 --- /dev/null +++ b/include/rtos/freertos/cmsis_os.h @@ -0,0 +1,879 @@ +/* + * Copyright (c) 2013-2017 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 10. January 2017 + * $Revision: V2.1.0 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h FreeRTOS header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedefs + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * Version 1.02 + * Control functions for short timeouts in microsecond resolution: + * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec + * Removed: osSignalGet + * Version 2.0.0 + * OS objects creation without macros (dynamic creation and resource allocation): + * - added: osXxxxNew functions which replace osXxxxCreate + * - added: osXxxxAttr_t structures + * - deprecated: osXxxxCreate functions, osXxxxDef_t structures + * - deprecated: osXxxxDef and osXxxx macros + * osStatus codes simplified and renamed to osStatus_t + * osEvent return structure deprecated + * Kernel: + * - added: osKernelInfo_t and osKernelGetInfo + * - added: osKernelState_t and osKernelGetState (replaces osKernelRunning) + * - added: osKernelLock, osKernelUnlock + * - added: osKernelSuspend, osKernelResume + * - added: osKernelGetTickCount, osKernelGetTickFreq + * - renamed osKernelSysTick to osKernelGetSysTimerCount + * - replaced osKernelSysTickFrequency with osKernelGetSysTimerFreq + * - deprecated osKernelSysTickMicroSec + * Thread: + * - extended number of thread priorities + * - renamed osPrioriry to osPrioriry_t + * - replaced osThreadCreate with osThreadNew + * - added: osThreadGetName + * - added: osThreadState_t and osThreadGetState + * - added: osThreadGetStackSize, osThreadGetStackSpace + * - added: osThreadSuspend, osThreadResume + * - added: osThreadJoin, osThreadDetach, osThreadExit + * - added: osThreadGetCount, osThreadEnumerate + * - added: Thread Flags (moved from Signals) + * Signals: + * - renamed osSignals to osThreadFlags (moved to Thread Flags) + * - changed return value of Set/Clear/Wait functions + * - Clear function limited to current running thread + * - extended Wait function (options) + * - added: osThreadFlagsGet + * Event Flags: + * - added new independent object for handling Event Flags + * Delay and Wait functions: + * - added: osDelayUntil + * - deprecated: osWait + * Timer: + * - replaced osTimerCreate with osTimerNew + * - added: osTimerGetName, osTimerIsRunning + * Mutex: + * - extended: attributes (Recursive, Priority Inherit, Robust) + * - replaced osMutexCreate with osMutexNew + * - renamed osMutexWait to osMutexAcquire + * - added: osMutexGetName, osMutexGetOwner + * Semaphore: + * - extended: maximum and initial token count + * - replaced osSemaphoreCreate with osSemaphoreNew + * - renamed osSemaphoreWait to osSemaphoreAcquire (changed return value) + * - added: osSemaphoreGetName, osSemaphoreGetCount + * Memory Pool: + * - using osMemoryPool prefix instead of osPool + * - replaced osPoolCreate with osMemoryPoolNew + * - extended osMemoryPoolAlloc (timeout) + * - added: osMemoryPoolGetName + * - added: osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize + * - added: osMemoryPoolGetCount, osMemoryPoolGetSpace + * - added: osMemoryPoolDelete + * - deprecated: osPoolCAlloc + * Message Queue: + * - extended: fixed size message instead of a single 32-bit value + * - using osMessageQueue prefix instead of osMessage + * - replaced osMessageCreate with osMessageQueueNew + * - updated: osMessageQueuePut, osMessageQueueGet + * - added: osMessageQueueGetName + * - added: osMessageQueueGetCapacity, osMessageQueueGetMsgSize + * - added: osMessageQueueGetCount, osMessageQueueGetSpace + * - added: osMessageQueueReset, osMessageQueueDelete + * Mail Queue: + * - deprecated (superseded by extended Message Queue functionality) + * Version 2.1.0 + * Support for critical and uncritical sections (nesting safe): + * - updated: osKernelLock, osKernelUnlock + * - added: osKernelRestoreLock + * Updated Thread and Event Flags: + * - changed flags parameter and return type from int32_t to uint32_t + *---------------------------------------------------------------------------*/ + +#ifndef CMSIS_OS_H_ +#define CMSIS_OS_H_ + +#define osCMSIS 0x20001U ///< API version (main[31:16].sub[15:0]) + +#define osCMSIS_FreeRTOS 0x90000U ///< RTOS identification and version (main[31:16].sub[15:0]) + +#define osKernelSystemId "FreeRTOS V9.0.0" ///< RTOS identification string + +// The stack space occupied is mainly dependent on the underling C standard library +#if defined(__GNUC__) || defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__ICCARM__) +# define WORDS_STACK_SIZE 512 +#elif defined(TOOLCHAIN_ARM_MICRO) +# define WORDS_STACK_SIZE 128 +#endif + +#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4) + +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Signals 24U ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 65535U ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available +#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available + +#if defined(__CC_ARM) +#define os_InRegs __value_in_regs +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#define os_InRegs __attribute__((value_in_regs)) +#else +#define os_InRegs +#endif + +#include "cmsis_os2.h" +#include "FreeRTOS.h" + + +// OS_API_IN_INTLOCK can be enabled in target.mk by: +// export OS_API_IN_INTLOCK ?= 1 + +#ifdef OS_API_IN_INTLOCK +// CAUTION: +// It will be treated as in ISR when calling OS APIs in intlock(), but +// the stack might still be using PSP instead of MSP. +#define IN_ISR() (__get_IPSR() != 0 || __get_PRIMASK() != 0) +#else +#define IN_ISR() (__get_IPSR() != 0) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumerations, structures, defines ==== + +/// Priority values. +#if (osCMSIS < 0x20000U) +typedef enum { + osPriorityIdle = -3, ///< Priority: idle (lowest) + osPriorityLow = -2, ///< Priority: low + osPriorityBelowNormal = -1, ///< Priority: below normal + osPriorityNormal = 0, ///< Priority: normal (default) + osPriorityAboveNormal = +1, ///< Priority: above normal + osPriorityHigh = +2, ///< Priority: high + osPriorityRealtime = +3, ///< Priority: realtime (highest) + osPriorityError = 0x84, ///< System cannot determine priority or illegal priority. + osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osPriority; +#else +#define osPriority osPriority_t +#endif + +/// Entry point of a thread. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +typedef void (*os_ptimer) (void const *argument); + +/// Timer type. +#if (osCMSIS < 0x20000U) +typedef enum { + osTimerOnce = 0, ///< One-shot timer. + osTimerPeriodic = 1 ///< Repeating timer. +} os_timer_type; +#else +#define os_timer_type osTimerType_t +#endif + +/// Timeout value. +#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. + +/// Status code values returned by CMSIS-RTOS functions. +#if (osCMSIS < 0x20000U) +typedef enum { + osOK = 0, ///< Function completed; no error or event occurred. + osEventSignal = 0x08, ///< Function completed; signal event occurred. + osEventMessage = 0x10, ///< Function completed; message event occurred. + osEventMail = 0x20, ///< Function completed; mail event occurred. + osEventTimeout = 0x40, ///< Function completed; timeout occurred. + osErrorParameter = 0x80, ///< Parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< Resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< Resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< Function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< System cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< Value of a parameter is out of range. + osErrorOS = 0xFF, ///< Unspecified RTOS error: run-time error but no other error message fits. + osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osStatus; +#else +typedef int32_t osStatus; +#define osEventSignal (0x08) +#define osEventMessage (0x10) +#define osEventMail (0x20) +#define osEventTimeout (0x40) +#define osErrorOS osError +#define osErrorTimeoutResource osErrorTimeout +#define osErrorISRRecursive (-126) +#define osErrorValue (-127) +#define osErrorPriority (-128) +#define os_status_reserved (0x7FFFFFFF) ///< Prevents enum down-size compiler optimization. +#endif + + +// >>> the following data type definitions may be adapted towards a specific RTOS + +/// Thread ID identifies the thread. +#if (osCMSIS < 0x20000U) +typedef void *osThreadId; +#else +#define osThreadId osThreadId_t +#endif + +/// Timer ID identifies the timer. +#if (osCMSIS < 0x20000U) +typedef void *osTimerId; +#else +#define osTimerId osTimerId_t +#endif + +/// Mutex ID identifies the mutex. +#if (osCMSIS < 0x20000U) +typedef void *osMutexId; +#else +#define osMutexId osMutexId_t +#endif + +/// Semaphore ID identifies the semaphore. +#if (osCMSIS < 0x20000U) +typedef void *osSemaphoreId; +#else +#define osSemaphoreId osSemaphoreId_t +#endif + +/// Pool ID identifies the memory pool. +typedef void *osPoolId; + +/// Message ID identifies the message queue. +typedef void *osMessageQId; + +/// Mail ID identifies the mail queue. +typedef void *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +#if (osCMSIS < 0x20000U) +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t instances; ///< maximum number of instances of that thread function + uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size +} osThreadDef_t; +#else +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osThreadAttr_t attr; ///< thread attributes +} osThreadDef_t; +#endif + +/// Timer Definition structure contains timer parameters. +#if (osCMSIS < 0x20000U) +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function +} osTimerDef_t; +#else +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + osTimerAttr_t attr; ///< timer attributes +} osTimerDef_t; +#endif + +/// Mutex Definition structure contains setup information for a mutex. +#if (osCMSIS < 0x20000U) +typedef struct os_mutex_def { +// uint32_t dummy; ///< dummy value + void *mutex; ///< pointer to internal data +} osMutexDef_t; +#else +#define osMutexDef_t osMutexAttr_t +#endif + +/// Semaphore Definition structure contains setup information for a semaphore. +#if (osCMSIS < 0x20000U) +typedef struct os_semaphore_def { +// uint32_t dummy; ///< dummy value + void *semaphore; ///< pointer to internal data +} osSemaphoreDef_t; +#else +#define osSemaphoreDef_t osSemaphoreAttr_t +#endif + +/// Definition structure for memory block allocation. +//#if (osCMSIS < 0x20000U) +#if 1 +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; +#else +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + osMemoryPoolAttr_t attr; ///< memory pool attributes +} osPoolDef_t; +#endif + +/// Definition structure for message queue. +#if (osCMSIS < 0x20000U) +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + void *pool; ///< memory array for messages +} osMessageQDef_t; +#else +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + osMessageQueueAttr_t attr; ///< message queue attributes +} osMessageQDef_t; +#endif + +/// Definition structure for mail queue. +#if (osCMSIS < 0x20000U) +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; +#else +typedef struct os_mailQ_def { + // uint32_t queue_sz; ///< number of elements in the queue + // uint32_t item_sz; ///< size of an item + osPoolDef_t mq_pool; ///< memory pool attributes + void *mail; ///< pointer to mail + //osMemoryPoolAttr_t mp_attr; ///< memory pool attributes + osMessageQueueAttr_t mq_attr; ///< message queue attributes +} osMailQDef_t; +#endif + + +/// Event structure contains detailed information about an event. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Management Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osKernelInitialize (void); +#endif + +/// Start the RTOS Kernel scheduler. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osKernelStart (void); +#endif + +/// Check if the RTOS kernel is already started. +/// \return 0 RTOS is not started, 1 RTOS is started. +#if (osCMSIS < 0x20000U) +int32_t osKernelRunning(void); +#endif + +#if (defined(osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available + +/// Get the RTOS kernel system timer counter. +/// \return RTOS kernel system timer as 32-bit value +#if (osCMSIS < 0x20000U) +uint32_t osKernelSysTick (void); +#else +#define osKernelSysTick osKernelGetSysTimerCount +#endif + +/// The RTOS kernel system timer frequency in Hz. +/// \note Reflects the system timer setting and is typically defined in a configuration file. +#if (osCMSIS < 0x20000U) +#define osKernelSysTickFrequency 100000000 +#endif + +/// Convert a microseconds value to a RTOS kernel system timer value. +/// \param microsec time value in microseconds. +/// \return time value normalized to the \ref osKernelSysTickFrequency +#if (osCMSIS < 0x20000U) +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) +#else +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * osKernelGetSysTimerFreq()) / 1000000) +#endif + +#endif // System Timer available + + +// ==== Thread Management Functions ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name +#else // define the object +#define osThreadDef(name, priority, instances, stacksz, task_name) \ +static uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1]; \ +static StaticTask_t os_thread_cb_##name; \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), \ + { task_name, osThreadDetached, \ + (instances == 1) ? (&os_thread_cb_##name) : NULL,\ + (instances == 1) ? sizeof(StaticTask_t) : 0U, \ + ((stacksz) && (instances == 1)) ? (&os_thread_stack##name) : NULL, \ + 8*((stacksz+7)/8), \ + (priority), 0U, 0U } } +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +#if (osCMSIS < 0x20000U) +osThreadId osThreadGetId (void); +#endif + +//#if (osCMSIS < 0x20000U) +int osGetThreadIntId (void); +//#endif + +/// Change priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); +#endif + +/// Get current priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the specified thread. +#if (osCMSIS < 0x20000U) +osPriority osThreadGetPriority (osThreadId thread_id); +#endif + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadYield (void); +#endif + +/// Terminate execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadTerminate (osThreadId thread_id); +#endif + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flag information or error code. +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osDelay (uint32_t millisec); +#endif + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +os_InRegs osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== + +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern const osTimerDef_t os_timer_def_##name +#else // define the object +#define osTimerDef(name, function) \ +static StaticTimer_t os_timer_cb_##name; \ +const osTimerDef_t os_timer_def_##name = \ +{ (function), { NULL, 0U, (&os_timer_cb_##name), sizeof(StaticTimer_t) } } +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create and Initialize a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value of the timer. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); +#endif + +/// Stop a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerStop (osTimerId timer_id); +#endif + +/// Delete a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerDelete (osTimerId timer_id); +#endif + + +// ==== Mutex Management Functions ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern const osMutexDef_t os_mutex_def_##name +#else // define the object +#define osMutexDef(name) \ +static StaticSemaphore_t os_mutex_cb_##name; \ +const osMutexDef_t os_mutex_def_##name = \ +{ NULL, osMutexRecursive | osMutexPrioInherit, (&os_mutex_cb_##name), sizeof(StaticSemaphore_t) } +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); +#else +#define osMutexWait osMutexAcquire +#endif + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexRelease (osMutexId mutex_id); +#endif + +/// Delete a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexDelete (osMutexId mutex_id); +#endif + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0U)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ +static StaticSemaphore_t os_semaphore_cb_##name; \ +const osSemaphoreDef_t os_semaphore_def_##name = \ +{ NULL, 0U, (&os_semaphore_cb_##name), sizeof(StaticSemaphore_t) } +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count maximum and initial number of available tokens. +/// \return semaphore ID for reference by other functions or NULL in case of error. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); +#endif + +/// Delete a Semaphore object. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); +#endif + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined(osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern const osPoolDef_t os_pool_def_##name +#else // define the object +#define osPoolDef(name, no, type) \ +uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), (os_pool_m_##name) } +//const osPoolDef_t os_pool_def_##name = +//{ (no), sizeof(type), {NULL} } +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a Memory Pool object. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a Memory Pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a Memory Pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool available + + +// ==== Message Queue Management Functions ==== + +#if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queue available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern const osMessageQDef_t os_messageQ_def_##name +#else // define the object +#define osMessageQDef(name, queue_sz, type) \ +static StaticQueue_t os_mq_cb_##name; \ +static uint32_t os_mq_data_##name[(queue_sz) * sizeof(type)]; \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), \ + { NULL, 0U, (&os_mq_cb_##name), sizeof(StaticQueue_t), \ + (&os_mq_data_##name), sizeof(os_mq_data_##name) } } +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue object. +/// \param[in] queue_def message queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event information that includes status code. +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +uint32_t osMessageGetSpace (osMessageQId queue_id); +#endif // Message Queue available + + +// ==== Mail Queue Management Functions ==== + +#if (defined(osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queue available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of mails in the queue. +/// \param type data type of a single mail element. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern const osMailQDef_t os_mailQ_def_##name +#else // define the object +#define osMailQDef(name, queue_sz, type) \ +static uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \ +osMailQDef_t os_mailQ_def_##name = \ +{ {(queue_sz), sizeof(type), (os_mailQ_m_##name)}, NULL, {NULL} } +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize a Mail Queue object. +/// \param[in] queue_def mail queue definition referenced with \ref osMailQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +//osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); +osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block for mail from a mail memory pool. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block for mail from a mail memory pool and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a Mail into a Queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to memory with mail to put into a queue. +/// \return status code that indicates the execution status of the function. +osStatus osMailPut (osMailQId queue_id, const void *mail); + +/// Get a Mail from a Queue or timeout if Queue is empty. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event information that includes status code. +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block by returning it to a mail memory pool. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queue available + +void os_error_str (const char *fmt, ...); + +#ifdef __cplusplus +} +#endif + +#endif // CMSIS_OS_H_ diff --git a/include/rtos/freertos/cmsis_os2.h b/include/rtos/freertos/cmsis_os2.h new file mode 100644 index 0000000..9825f04 --- /dev/null +++ b/include/rtos/freertos/cmsis_os2.h @@ -0,0 +1,758 @@ +/* + * Copyright (c) 2013-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. + * + * ---------------------------------------------------------------------- + * + * $Date: 18. June 2018 + * $Revision: V2.1.3 + * + * Project: CMSIS-RTOS2 API + * Title: cmsis_os2.h header file + * + * Version 2.1.3 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osThreadGetId + * Version 2.1.2 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetInfo, osKernelGetState + * Version 2.1.1 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetTickCount, osKernelGetTickFreq + * Changed Kernel Tick type to uint32_t: + * - updated: osKernelGetTickCount, osDelayUntil + * Version 2.1.0 + * Support for critical and uncritical sections (nesting safe): + * - updated: osKernelLock, osKernelUnlock + * - added: osKernelRestoreLock + * Updated Thread and Event Flags: + * - changed flags parameter and return type from int32_t to uint32_t + * Version 2.0.0 + * Initial Release + *---------------------------------------------------------------------------*/ + +#ifndef CMSIS_OS2_H_ +#define CMSIS_OS2_H_ + +#ifndef __NO_RETURN +#if defined(__CC_ARM) +#define __NO_RETURN __declspec(noreturn) +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#define __NO_RETURN __attribute__((__noreturn__)) +#elif defined(__GNUC__) +#define __NO_RETURN __attribute__((__noreturn__)) +#elif defined(__ICCARM__) +#define __NO_RETURN __noreturn +#else +#define __NO_RETURN +#endif +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumerations, structures, defines ==== + +/// Version information. +typedef struct { + uint32_t api; ///< API version (major.minor.rev: mmnnnrrrr dec). + uint32_t kernel; ///< Kernel version (major.minor.rev: mmnnnrrrr dec). +} osVersion_t; + +/// Kernel state. +typedef enum { + osKernelInactive = 0, ///< Inactive. + osKernelReady = 1, ///< Ready. + osKernelRunning = 2, ///< Running. + osKernelLocked = 3, ///< Locked. + osKernelSuspended = 4, ///< Suspended. + osKernelError = -1, ///< Error. + osKernelReserved = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization. +} osKernelState_t; + +/// Thread state. +typedef enum { + osThreadInactive = 0, ///< Inactive. + osThreadReady = 1, ///< Ready. + osThreadRunning = 2, ///< Running. + osThreadBlocked = 3, ///< Blocked. + osThreadTerminated = 4, ///< Terminated. + osThreadError = -1, ///< Error. + osThreadReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osThreadState_t; + +/// Priority values. +typedef enum { + osPriorityNone = 0, ///< No priority (not initialized). + osPriorityIdle = 1, ///< Reserved for Idle thread. + osPriorityLow = 8, ///< Priority: low + osPriorityLow1 = 8+1, ///< Priority: low + 1 + osPriorityLow2 = 8+2, ///< Priority: low + 2 + osPriorityLow3 = 8+3, ///< Priority: low + 3 + osPriorityLow4 = 8+4, ///< Priority: low + 4 + osPriorityLow5 = 8+5, ///< Priority: low + 5 + osPriorityLow6 = 8+6, ///< Priority: low + 6 + osPriorityLow7 = 8+7, ///< Priority: low + 7 + osPriorityBelowNormal = 16, ///< Priority: below normal + osPriorityBelowNormal1 = 16+1, ///< Priority: below normal + 1 + osPriorityBelowNormal2 = 16+2, ///< Priority: below normal + 2 + osPriorityBelowNormal3 = 16+3, ///< Priority: below normal + 3 + osPriorityBelowNormal4 = 16+4, ///< Priority: below normal + 4 + osPriorityBelowNormal5 = 16+5, ///< Priority: below normal + 5 + osPriorityBelowNormal6 = 16+6, ///< Priority: below normal + 6 + osPriorityBelowNormal7 = 16+7, ///< Priority: below normal + 7 + osPriorityNormal = 24, ///< Priority: normal + osPriorityNormal1 = 24+1, ///< Priority: normal + 1 + osPriorityNormal2 = 24+2, ///< Priority: normal + 2 + osPriorityNormal3 = 24+3, ///< Priority: normal + 3 + osPriorityNormal4 = 24+4, ///< Priority: normal + 4 + osPriorityNormal5 = 24+5, ///< Priority: normal + 5 + osPriorityNormal6 = 24+6, ///< Priority: normal + 6 + osPriorityNormal7 = 24+7, ///< Priority: normal + 7 + osPriorityAboveNormal = 32, ///< Priority: above normal + osPriorityAboveNormal1 = 32+1, ///< Priority: above normal + 1 + osPriorityAboveNormal2 = 32+2, ///< Priority: above normal + 2 + osPriorityAboveNormal3 = 32+3, ///< Priority: above normal + 3 + osPriorityAboveNormal4 = 32+4, ///< Priority: above normal + 4 + osPriorityAboveNormal5 = 32+5, ///< Priority: above normal + 5 + osPriorityAboveNormal6 = 32+6, ///< Priority: above normal + 6 + osPriorityAboveNormal7 = 32+7, ///< Priority: above normal + 7 + osPriorityHigh = 40, ///< Priority: high + osPriorityHigh1 = 40+1, ///< Priority: high + 1 + osPriorityHigh2 = 40+2, ///< Priority: high + 2 + osPriorityHigh3 = 40+3, ///< Priority: high + 3 + osPriorityHigh4 = 40+4, ///< Priority: high + 4 + osPriorityHigh5 = 40+5, ///< Priority: high + 5 + osPriorityHigh6 = 40+6, ///< Priority: high + 6 + osPriorityHigh7 = 40+7, ///< Priority: high + 7 + osPriorityRealtime = 48, ///< Priority: realtime + osPriorityRealtime1 = 48+1, ///< Priority: realtime + 1 + osPriorityRealtime2 = 48+2, ///< Priority: realtime + 2 + osPriorityRealtime3 = 48+3, ///< Priority: realtime + 3 + osPriorityRealtime4 = 48+4, ///< Priority: realtime + 4 + osPriorityRealtime5 = 48+5, ///< Priority: realtime + 5 + osPriorityRealtime6 = 48+6, ///< Priority: realtime + 6 + osPriorityRealtime7 = 48+7, ///< Priority: realtime + 7 + osPriorityISR = 56, ///< Reserved for ISR deferred thread. + osPriorityError = -1, ///< System cannot determine priority or illegal priority. + osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osPriority_t; + +/// Entry point of a thread. +typedef void (*osThreadFunc_t) (void *argument); + +/// Timer callback function. +typedef void (*osTimerFunc_t) (void *argument); + +/// Timer type. +typedef enum { + osTimerOnce = 0, ///< One-shot timer. + osTimerPeriodic = 1 ///< Repeating timer. +} osTimerType_t; + +// Timeout value. +#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. + +// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait). +#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default). +#define osFlagsWaitAll 0x00000001U ///< Wait for all flags. +#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for. + +// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). +#define osFlagsError 0x80000000U ///< Error indicator. +#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1). +#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2). +#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3). +#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4). +#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6). + +// Thread attributes (attr_bits in \ref osThreadAttr_t). +#define osThreadDetached 0x00000000U ///< Thread created in detached mode (default) +#define osThreadJoinable 0x00000001U ///< Thread created in joinable mode + +// Mutex attributes (attr_bits in \ref osMutexAttr_t). +#define osMutexRecursive 0x00000001U ///< Recursive mutex. +#define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol. +#define osMutexRobust 0x00000008U ///< Robust mutex. + +/// Status code values returned by CMSIS-RTOS functions. +typedef enum { + osOK = 0, ///< Operation completed successfully. + osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits. + osErrorTimeout = -2, ///< Operation not completed within the timeout period. + osErrorResource = -3, ///< Resource not available. + osErrorParameter = -4, ///< Parameter error. + osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osStatus_t; + + +/// \details Thread ID identifies the thread. +typedef void *osThreadId_t; + +/// \details Timer ID identifies the timer. +typedef void *osTimerId_t; + +/// \details Event Flags ID identifies the event flags. +typedef void *osEventFlagsId_t; + +/// \details Mutex ID identifies the mutex. +typedef void *osMutexId_t; + +/// \details Semaphore ID identifies the semaphore. +typedef void *osSemaphoreId_t; + +/// \details Memory Pool ID identifies the memory pool. +typedef void *osMemoryPoolId_t; + +/// \details Message Queue ID identifies the message queue. +typedef void *osMessageQueueId_t; + + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + + +/// Attributes structure for thread. +typedef struct { + const char *name; ///< name of the thread + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *stack_mem; ///< memory for stack + uint32_t stack_size; ///< size of stack + osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) + TZ_ModuleId_t tz_module; ///< TrustZone module identifier + uint32_t reserved; ///< reserved (must be 0) +} osThreadAttr_t; + +/// Attributes structure for timer. +typedef struct { + const char *name; ///< name of the timer + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osTimerAttr_t; + +/// Attributes structure for event flags. +typedef struct { + const char *name; ///< name of the event flags + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osEventFlagsAttr_t; + +/// Attributes structure for mutex. +typedef struct { + const char *name; ///< name of the mutex + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mutex; ///< pointer to internal data +} osMutexAttr_t; + +/// Attributes structure for semaphore. +typedef struct { + const char *name; ///< name of the semaphore + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *semaphore; ///< pointer to internal data +} osSemaphoreAttr_t; + +/// Attributes structure for memory pool. +typedef struct { + const char *name; ///< name of the memory pool + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mp_mem; ///< memory for data storage + uint32_t mp_size; ///< size of provided memory for data storage +} osMemoryPoolAttr_t; + +/// Attributes structure for message queue. +typedef struct { + const char *name; ///< name of the message queue + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mq_mem; ///< memory for data storage + uint32_t mq_size; ///< size of provided memory for data storage +} osMessageQueueAttr_t; + + +// ==== Kernel Management Functions ==== + +/// Initialize the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelInitialize (void); + +/// Get RTOS Kernel Information. +/// \param[out] version pointer to buffer for retrieving version information. +/// \param[out] id_buf pointer to buffer for retrieving kernel identification string. +/// \param[in] id_size size of buffer for kernel identification string. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); + +/// Get the current RTOS Kernel state. +/// \return current RTOS Kernel state. +osKernelState_t osKernelGetState (void); + +/// Start the RTOS Kernel scheduler. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelStart (void); + +/// Lock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelLock (void); + +/// Unlock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelUnlock (void); + +/// Restore the RTOS Kernel scheduler lock state. +/// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock. +/// \return new lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelRestoreLock (int32_t lock); + +/// Suspend the RTOS Kernel scheduler. +/// \return time in ticks, for how long the system can sleep or power-down. +uint32_t osKernelSuspend (void); + +/// Resume the RTOS Kernel scheduler. +/// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode. +void osKernelResume (uint32_t sleep_ticks); + +/// Get the RTOS kernel tick count. +/// \return RTOS kernel current tick count. +uint32_t osKernelGetTickCount (void); + +/// Get the RTOS kernel tick frequency. +/// \return frequency of the kernel tick in hertz, i.e. kernel ticks per second. +uint32_t osKernelGetTickFreq (void); + +/// Get the RTOS kernel system timer count. +/// \return RTOS kernel current system timer count as 32-bit value. +uint32_t osKernelGetSysTimerCount (void); + +/// Get the RTOS kernel system timer frequency. +/// \return frequency of the system timer in hertz, i.e. timer ticks per second. +uint32_t osKernelGetSysTimerFreq (void); + + +// ==== Thread Management Functions ==== + +/// Create a thread and add it to Active Threads. +/// \param[in] func thread function. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \param[in] attr thread attributes; NULL: default values. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); + +/// Get name of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return name as null-terminated string. +const char *osThreadGetName (osThreadId_t thread_id); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadGetId (void); + +/// Get current thread state of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current thread state of the specified thread. +osThreadState_t osThreadGetState (osThreadId_t thread_id); + +/// Get stack size of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return stack size in bytes. +uint32_t osThreadGetStackSize (osThreadId_t thread_id); + +/// Get available stack space of a thread based on stack watermark recording during execution. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return remaining stack space in bytes. +uint32_t osThreadGetStackSpace (osThreadId_t thread_id); + +/// Change priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); + +/// Get current priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current priority value of the specified thread. +osPriority_t osThreadGetPriority (osThreadId_t thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadYield (void); + +/// Suspend execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSuspend (osThreadId_t thread_id); + +/// Resume execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadResume (osThreadId_t thread_id); + +/// Detach a thread (thread storage can be reclaimed when thread terminates). +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadDetach (osThreadId_t thread_id); + +/// Wait for specified thread to terminate. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadJoin (osThreadId_t thread_id); + +/// Terminate execution of current running thread. +__NO_RETURN void osThreadExit (void); + +/// Terminate execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadTerminate (osThreadId_t thread_id); + +/// Get number of active threads. +/// \return number of active threads. +uint32_t osThreadGetCount (void); + +/// Enumerate active threads. +/// \param[out] thread_array pointer to array for retrieving thread IDs. +/// \param[in] array_items maximum number of items in array for retrieving thread IDs. +/// \return number of enumerated threads. +uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items); + + +// ==== Thread Flags Functions ==== + +/// Set the specified Thread Flags of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] flags specifies the flags of the thread that shall be set. +/// \return thread flags after setting or error code if highest bit set. +uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); + +/// Clear the specified Thread Flags of current running thread. +/// \param[in] flags specifies the flags of the thread that shall be cleared. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsClear (uint32_t flags); + +/// Get the current Thread Flags of current running thread. +/// \return current thread flags. +uint32_t osThreadFlagsGet (void); + +/// Wait for one or more Thread Flags of the current running thread to become signaled. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value +/// \return status code that indicates the execution status of the function. +osStatus_t osDelay (uint32_t ticks); + +/// Wait until specified time. +/// \param[in] ticks absolute time in ticks +/// \return status code that indicates the execution status of the function. +osStatus_t osDelayUntil (uint32_t ticks); + + +// ==== Timer Management Functions ==== + +/// Create and Initialize a timer. +/// \param[in] func function pointer to callback function. +/// \param[in] type \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer callback function. +/// \param[in] attr timer attributes; NULL: default values. +/// \return timer ID for reference by other functions or NULL in case of error. +osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); + +/// Get name of a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return name as null-terminated string. +const char *osTimerGetName (osTimerId_t timer_id); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks); + +/// Stop a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStop (osTimerId_t timer_id); + +/// Check if a timer is running. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return 0 not running, 1 running. +uint32_t osTimerIsRunning (osTimerId_t timer_id); + +/// Delete a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerDelete (osTimerId_t timer_id); + + +// ==== Event Flags Management Functions ==== + +/// Create and Initialize an Event Flags object. +/// \param[in] attr event flags attributes; NULL: default values. +/// \return event flags ID for reference by other functions or NULL in case of error. +osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr); + +/// Get name of an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return name as null-terminated string. +const char *osEventFlagsGetName (osEventFlagsId_t ef_id); + +/// Set the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be set. +/// \return event flags after setting or error code if highest bit set. +uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); + +/// Clear the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be cleared. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); + +/// Get the current Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return current event flags. +uint32_t osEventFlagsGet (osEventFlagsId_t ef_id); + +/// Wait for one or more Event Flags to become signaled. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); + +/// Delete an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id); + + +// ==== Mutex Management Functions ==== + +/// Create and Initialize a Mutex object. +/// \param[in] attr mutex attributes; NULL: default values. +/// \return mutex ID for reference by other functions or NULL in case of error. +osMutexId_t osMutexNew (const osMutexAttr_t *attr); + +/// Get name of a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return name as null-terminated string. +const char *osMutexGetName (osMutexId_t mutex_id); + +/// Acquire a Mutex or timeout if it is locked. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); + +/// Release a Mutex that was acquired by \ref osMutexAcquire. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexRelease (osMutexId_t mutex_id); + +/// Get Thread which owns a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return thread ID of owner thread or NULL when mutex was not acquired. +osThreadId_t osMutexGetOwner (osMutexId_t mutex_id); + +/// Delete a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexDelete (osMutexId_t mutex_id); + + +// ==== Semaphore Management Functions ==== + +/// Create and Initialize a Semaphore object. +/// \param[in] max_count maximum number of available tokens. +/// \param[in] initial_count initial number of available tokens. +/// \param[in] attr semaphore attributes; NULL: default values. +/// \return semaphore ID for reference by other functions or NULL in case of error. +osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); + +/// Get name of a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return name as null-terminated string. +const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id); + +/// Acquire a Semaphore token or timeout if no tokens are available. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); + +/// Release a Semaphore token up to the initial maximum count. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id); + +/// Get current Semaphore token count. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return number of tokens available. +uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id); + +/// Delete a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id); + + +// ==== Memory Pool Management Functions ==== + +/// Create and Initialize a Memory Pool object. +/// \param[in] block_count maximum number of memory blocks in memory pool. +/// \param[in] block_size memory block size in bytes. +/// \param[in] attr memory pool attributes; NULL: default values. +/// \return memory pool ID for reference by other functions or NULL in case of error. +osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr); + +/// Get name of a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return name as null-terminated string. +const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id); + +/// Allocate a memory block from a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return address of the allocated memory block or NULL in case of no memory is available. +void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); + +/// Get maximum number of memory blocks in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return maximum number of memory blocks. +uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id); + +/// Get memory block size in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return memory block size in bytes. +uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks used in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks used. +uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks available in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks available. +uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id); + +/// Delete a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id); + + +// ==== Message Queue Management Functions ==== + +/// Create and Initialize a Message Queue object. +/// \param[in] msg_count maximum number of messages in queue. +/// \param[in] msg_size maximum message size in bytes. +/// \param[in] attr message queue attributes; NULL: default values. +/// \return message queue ID for reference by other functions or NULL in case of error. +osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); + +/// Get name of a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return name as null-terminated string. +const char *osMessageQueueGetName (osMessageQueueId_t mq_id); + +/// Put a Message into a Queue or timeout if Queue is full. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[in] msg_ptr pointer to buffer with message to put into a queue. +/// \param[in] msg_prio message priority. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[out] msg_ptr pointer to buffer for message to get from a queue. +/// \param[out] msg_prio pointer to buffer for message priority or NULL. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); + +/// Get maximum number of messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum number of messages. +uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id); + +/// Get maximum message size in a Memory Pool. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum message size in bytes. +uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id); + +/// Get number of queued messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of queued messages. +uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id); + +/// Get number of available slots for messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of available slots for messages. +uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id); + +/// Reset a Message Queue to initial empty state. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id); + +/// Delete a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); + + +#ifdef __cplusplus +} +#endif + +#endif // CMSIS_OS2_H_ diff --git a/include/rtos/freertos/croutine.h b/include/rtos/freertos/croutine.h new file mode 100644 index 0000000..f22142f --- /dev/null +++ b/include/rtos/freertos/croutine.h @@ -0,0 +1,719 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#include "freertos_list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to hide the implementation of the co-routine control block. The +control block structure however has to be included in the header due to +the macro implementation of the co-routine functionality. */ +typedef void * CoRoutineHandle_t; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ + ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */ + UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ + UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + uint16_t uxState; /*< Used internally by the co-routine implementation. */ +} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ + +/** + * croutine. h + *
+ BaseType_t xCoRoutineCreate(
+                                 crCOROUTINE_CODE pxCoRoutineCode,
+                                 UBaseType_t uxPriority,
+                                 UBaseType_t uxIndex
+                               );
+ * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: +
+ // Co-routine to be created.
+ void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // This co-routine just delays for a fixed period, then toggles
+         // an LED.  Two co-routines are created using this function, so
+         // the uxIndex parameter is used to tell the co-routine which
+         // LED to flash and how int32_t to delay.  This assumes xQueue has
+         // already been created.
+         vParTestToggleLED( cLedToFlash[ uxIndex ] );
+         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ uint8_t ucParameterToPass;
+ TaskHandle_t xHandle;
+
+     // Create two co-routines at priority 0.  The first is given index 0
+     // so (from the code above) toggles LED 5 every 200 ticks.  The second
+     // is given index 1 so toggles LED 6 every 400 ticks.
+     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+     {
+         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+     }
+ }
+   
+ * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); + + +/** + * croutine. h + *
+ void vCoRoutineSchedule( void );
+ * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: +
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+	vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+    for( ;; )
+    {
+        vCoRoutineSchedule();
+    }
+ }
+ 
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + *
+ crSTART( CoRoutineHandle_t xHandle );
+ * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: + +/** + * croutine. h + *
+ crEND();
+ * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): +#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): + +/** + * croutine. h + *
+ crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
+ * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+        // Delay for 200ms.
+        crDELAY( xHandle, xDelayTime );
+
+        // Do something here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + if( ( xTicksToDelay ) > 0 ) \ + { \ + vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ + } \ + crSET_STATE0( ( xHandle ) ); + +/** + *
+ crQUEUE_SEND(
+                  CoRoutineHandle_t xHandle,
+                  QueueHandle_t pxQueue,
+                  void *pvItemToQueue,
+                  TickType_t xTicksToWait,
+                  BaseType_t *pxResult
+             )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: +
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xNumberToPost = 0;
+ static BaseType_t xResult;
+
+    // Co-routines must begin with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // This assumes the queue has already been created.
+        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+        if( xResult != pdPASS )
+        {
+            // The message was not posted!
+        }
+
+        // Increment the number to be posted onto the queue.
+        xNumberToPost++;
+
+        // Delay for 100 ticks.
+        crDELAY( xHandle, 100 );
+    }
+
+    // Co-routines must end with a call to crEND().
+    crEND();
+ }
+ * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_RECEIVE(
+                     CoRoutineHandle_t xHandle,
+                     QueueHandle_t pxQueue,
+                     void *pvBuffer,
+                     TickType_t xTicksToWait,
+                     BaseType_t *pxResult
+                 )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: +
+ // A co-routine receives the number of an LED to flash from a queue.  It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xResult;
+ static UBaseType_t uxLEDToFlash;
+
+    // All co-routines must start with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // Wait for data to become available on the queue.
+        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+        if( xResult == pdPASS )
+        {
+            // We received the LED to flash - flash it!
+            vParTestToggleLED( uxLEDToFlash );
+        }
+    }
+
+    crEND();
+ }
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ + } \ + if( *( pxResult ) == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *( pxResult ) = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvItemToQueue,
+                            BaseType_t xCoRoutinePreviouslyWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: +
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ char cRxedChar;
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Wait for data to become available on the queue.  This assumes the
+         // queue xCommsRxQueue has already been created!
+         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+         // Was a character received?
+         if( xResult == pdPASS )
+         {
+             // Process the character here.
+         }
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     // We loop around reading characters until there are none left in the UART.
+     while( UART_RX_REG_NOT_EMPTY() )
+     {
+         // Obtain the character from the UART.
+         cRxedChar = UART_RX_REG;
+
+         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
+         // the first time around the loop.  If the post causes a co-routine
+         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+         // In this manner we can ensure that if more than one co-routine is
+         // blocked on the queue only one is woken by this ISR no matter how
+         // many characters are posted to the queue.
+         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+     }
+ }
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) + + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvBuffer,
+                            BaseType_t * pxCoRoutineWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: +
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period.  The character is incremented each time.
+ static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Send the next character to the queue.
+         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+         if( xResult == pdPASS )
+         {
+             // The character was successfully posted to the queue.
+         }
+		 else
+		 {
+			// Could not post the character to the queue.
+		 }
+
+         // Enable the UART Tx interrupt to cause an interrupt in this
+		 // hypothetical UART.  The interrupt will obtain the character
+		 // from the queue and send it.
+		 ENABLE_RX_INTERRUPT();
+
+		 // Increment to the next character then block for a fixed period.
+		 // cCharToTx will maintain its value across the delay as it is
+		 // declared static.
+		 cCharToTx++;
+		 if( cCharToTx > 'x' )
+		 {
+			cCharToTx = 'a';
+		 }
+		 crDELAY( 100 );
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     while( UART_TX_REG_EMPTY() )
+     {
+         // Are there any characters in the queue waiting to be sent?
+		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+		 // is woken by the post - ensuring that only a single co-routine is
+		 // woken no matter how many times we go around this loop.
+         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+		 {
+			 SEND_CHARACTER( cCharToTx );
+		 }
+     }
+ }
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ); + +#ifdef __cplusplus +} +#endif + +#endif /* CO_ROUTINE_H */ diff --git a/include/rtos/freertos/deprecated_definitions.h b/include/rtos/freertos/deprecated_definitions.h new file mode 100644 index 0000000..c747847 --- /dev/null +++ b/include/rtos/freertos/deprecated_definitions.h @@ -0,0 +1,279 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef DEPRECATED_DEFINITIONS_H +#define DEPRECATED_DEFINITIONS_H + + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. The +definitions below remain in the code for backward compatibility only. New +projects should not use them. */ + +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT + #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT + #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef GCC_MEGA_AVR + #include "../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR + #include "../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT + #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT + #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" +#endif + +#ifdef _FEDPICC + #include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL + #include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 + #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE + #include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx + #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 + #include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 + #include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 + #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS + #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC + #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR + #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR + #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR + #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR + #include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR + #include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC + #include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR + #include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S + #include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 + #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 + #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR + #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC + #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE + #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 + #include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 + #include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC + #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR + #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 + #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 + #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE + #include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef __GNUC__ + #ifdef __AVR32_AVR32A__ + #include "portmacro.h" + #endif +#endif + +#ifdef __ICCAVR32__ + #ifdef __CORE__ + #if __CORE__ == __AVR32A__ + #include "portmacro.h" + #endif + #endif +#endif + +#ifdef __91467D + #include "portmacro.h" +#endif + +#ifdef __96340 + #include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#endif /* DEPRECATED_DEFINITIONS_H */ + diff --git a/include/rtos/freertos/event_groups.h b/include/rtos/freertos/event_groups.h new file mode 100644 index 0000000..e40c544 --- /dev/null +++ b/include/rtos/freertos/event_groups.h @@ -0,0 +1,757 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef EVENT_GROUPS_H +#define EVENT_GROUPS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include event_groups.h" +#endif + +/* FreeRTOS includes. */ +#include "timers.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An event group is a collection of bits to which an application can assign a + * meaning. For example, an application may create an event group to convey + * the status of various CAN bus related events in which bit 0 might mean "A CAN + * message has been received and is ready for processing", bit 1 might mean "The + * application has queued a message that is ready for sending onto the CAN + * network", and bit 2 might mean "It is time to send a SYNC message onto the + * CAN network" etc. A task can then test the bit values to see which events + * are active, and optionally enter the Blocked state to wait for a specified + * bit or a group of specified bits to be active. To continue the CAN bus + * example, a CAN controlling task can enter the Blocked state (and therefore + * not consume any processing time) until either bit 0, bit 1 or bit 2 are + * active, at which time the bit that was actually active would inform the task + * which action it had to take (process a received message, send a message, or + * send a SYNC). + * + * The event groups implementation contains intelligence to avoid race + * conditions that would otherwise occur were an application to use a simple + * variable for the same purpose. This is particularly important with respect + * to when a bit within an event group is to be cleared, and when bits have to + * be set and then tested atomically - as is the case where event groups are + * used to create a synchronisation point between multiple tasks (a + * 'rendezvous'). + * + * \defgroup EventGroup + */ + + + +/** + * event_groups.h + * + * Type by which event groups are referenced. For example, a call to + * xEventGroupCreate() returns an EventGroupHandle_t variable that can then + * be used as a parameter to other event group functions. + * + * \defgroup EventGroupHandle_t EventGroupHandle_t + * \ingroup EventGroup + */ +struct EventGroupDef_t; +typedef struct EventGroupDef_t * EventGroupHandle_t; + +/* + * The type that holds event bits always matches TickType_t - therefore the + * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, + * 32 bits if set to 0. + * + * \defgroup EventBits_t EventBits_t + * \ingroup EventGroup + */ +typedef TickType_t EventBits_t; + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreate( void );
+ 
+ * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @return If the event group was created then a handle to the event group is + * returned. If there was insufficient FreeRTOS heap available to create the + * event group then NULL is returned. See http://www.freertos.org/a00111.html + * + * Example usage: +
+	// Declare a variable to hold the created event group.
+	EventGroupHandle_t xCreatedEventGroup;
+
+	// Attempt to create the event group.
+	xCreatedEventGroup = xEventGroupCreate();
+
+	// Was the event group created successfully?
+	if( xCreatedEventGroup == NULL )
+	{
+		// The event group was not created because there was insufficient
+		// FreeRTOS heap available.
+	}
+	else
+	{
+		// The event group was created.
+	}
+   
+ * \defgroup xEventGroupCreate xEventGroupCreate + * \ingroup EventGroup + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
+ 
+ * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type + * StaticEventGroup_t, which will be then be used to hold the event group's data + * structures, removing the need for the memory to be allocated dynamically. + * + * @return If the event group was created then a handle to the event group is + * returned. If pxEventGroupBuffer was NULL then NULL is returned. + * + * Example usage: +
+	// StaticEventGroup_t is a publicly accessible structure that has the same
+	// size and alignment requirements as the real event group structure.  It is
+	// provided as a mechanism for applications to know the size of the event
+	// group (which is dependent on the architecture and configuration file
+	// settings) without breaking the strict data hiding policy by exposing the
+	// real event group internals.  This StaticEventGroup_t variable is passed
+	// into the xSemaphoreCreateEventGroupStatic() function and is used to store
+	// the event group's data structures
+	StaticEventGroup_t xEventGroupBuffer;
+
+	// Create the event group without dynamically allocating any memory.
+	xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
+   
+ */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupWaitBits( 	EventGroupHandle_t xEventGroup,
+										const EventBits_t uxBitsToWaitFor,
+										const BaseType_t xClearOnExit,
+										const BaseType_t xWaitForAllBits,
+										const TickType_t xTicksToWait );
+ 
+ * + * [Potentially] block to wait for one or more bits to be set within a + * previously created event group. + * + * This function cannot be called from an interrupt. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and/or bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within + * uxBitsToWaitFor that are set within the event group will be cleared before + * xEventGroupWaitBits() returns if the wait condition was met (if the function + * returns for a reason other than a timeout). If xClearOnExit is set to + * pdFALSE then the bits set in the event group are not altered when the call to + * xEventGroupWaitBits() returns. + * + * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then + * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor + * are set or the specified block time expires. If xWaitForAllBits is set to + * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set + * in uxBitsToWaitFor is set or the specified block time expires. The block + * time is specified by the xTicksToWait parameter. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for one/all (depending on the xWaitForAllBits value) of the bits specified by + * uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupWaitBits() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupWaitBits() returned because the bits it was waiting for were set + * then the returned value is the event group value before any bits were + * automatically cleared in the case that xClearOnExit parameter was set to + * pdTRUE. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+   const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+		// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
+		// the event group.  Clear the bits before exiting.
+		uxBits = xEventGroupWaitBits(
+					xEventGroup,	// The event group being tested.
+					BIT_0 | BIT_4,	// The bits within the event group to wait for.
+					pdTRUE,			// BIT_0 and BIT_4 should be cleared before returning.
+					pdFALSE,		// Don't wait for both bits, either bit will do.
+					xTicksToWait );	// Wait a maximum of 100ms for either bit to be set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// xEventGroupWaitBits() returned because both bits were set.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_0 was set.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_4 was set.
+		}
+		else
+		{
+			// xEventGroupWaitBits() returned because xTicksToWait ticks passed
+			// without either BIT_0 or BIT_4 becoming set.
+		}
+   }
+   
+ * \defgroup xEventGroupWaitBits xEventGroupWaitBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
+ 
+ * + * Clear bits within an event group. This function cannot be called from an + * interrupt. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear + * in the event group. For example, to clear bit 3 only, set uxBitsToClear to + * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. + * + * @return The value of the event group before the specified bits were cleared. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Clear bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupClearBits(
+								xEventGroup,	// The event group being updated.
+								BIT_0 | BIT_4 );// The bits being cleared.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
+			// called.  Both will now be clear (not set).
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 were set in the first place.
+		}
+   }
+   
+ * \defgroup xEventGroupClearBits xEventGroupClearBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * A version of xEventGroupClearBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed + * while interrupts are disabled, so protects event groups that are accessed + * from tasks by suspending the scheduler rather than disabling interrupts. As + * a result event groups cannot be accessed directly from an interrupt service + * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the + * timer task to have the clear operation performed in the context of the timer + * task. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. + * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3 + * and bit 0 set uxBitsToClear to 0x09. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+		// Clear bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupClearBitsFromISR(
+							xEventGroup,	 // The event group being updated.
+							BIT_0 | BIT_4 ); // The bits being set.
+
+		if( xResult == pdPASS )
+		{
+			// The message was posted successfully.
+		}
+  }
+   
+ * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * Set bits within an event group. + * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() + * is a version that can be called from an interrupt. + * + * Setting bits in an event group will automatically unblock tasks that are + * blocked waiting for the bits. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @return The value of the event group at the time the call to + * xEventGroupSetBits() returns. There are two reasons why the returned value + * might have the bits specified by the uxBitsToSet parameter cleared. First, + * if setting a bit results in a task that was waiting for the bit leaving the + * blocked state then it is possible the bit will be cleared automatically + * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any + * unblocked (or otherwise Ready state) task that has a priority above that of + * the task that called xEventGroupSetBits() will execute and may change the + * event group value before the call to xEventGroupSetBits() returns. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupSetBits(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4 );// The bits being set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 remained set when the function returned.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 remained set when the function returned, but bit 4 was
+			// cleared.  It might be that bit 4 was cleared automatically as a
+			// task that was waiting for bit 4 was removed from the Blocked
+			// state.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 remained set when the function returned, but bit 0 was
+			// cleared.  It might be that bit 0 was cleared automatically as a
+			// task that was waiting for bit 0 was removed from the Blocked
+			// state.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 remained set.  It might be that a task
+			// was waiting for both of the bits to be set, and the bits were
+			// cleared as the task left the Blocked state.
+		}
+   }
+   
+ * \defgroup xEventGroupSetBits xEventGroupSetBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
+ 
+ * + * A version of xEventGroupSetBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed in + * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR() + * sends a message to the timer task to have the set operation performed in the + * context of the timer task - where a scheduler lock is used in place of a + * critical section. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task is higher than the priority of the + * currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE by + * xEventGroupSetBitsFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+   BaseType_t xHigherPriorityTaskWoken, xResult;
+
+		// xHigherPriorityTaskWoken must be initialised to pdFALSE.
+		xHigherPriorityTaskWoken = pdFALSE;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupSetBitsFromISR(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4   // The bits being set.
+							&xHigherPriorityTaskWoken );
+
+		// Was the message posted successfully?
+		if( xResult == pdPASS )
+		{
+			// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
+			// switch should be requested.  The macro used is port specific and
+			// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
+			// refer to the documentation page for the port being used.
+			portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+		}
+  }
+   
+ * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSync(	EventGroupHandle_t xEventGroup,
+									const EventBits_t uxBitsToSet,
+									const EventBits_t uxBitsToWaitFor,
+									TickType_t xTicksToWait );
+ 
+ * + * Atomically set bits within an event group, then wait for a combination of + * bits to be set within the same event group. This functionality is typically + * used to synchronise multiple tasks, where each task has to wait for the other + * tasks to reach a synchronisation point before proceeding. + * + * This function cannot be used from an interrupt. + * + * The function will return before its block time expires if the bits specified + * by the uxBitsToWait parameter are set, or become set within that time. In + * this case all the bits specified by uxBitsToWait will be automatically + * cleared before the function returns. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToSet The bits to set in the event group before determining + * if, and possibly waiting for, all the bits specified by the uxBitsToWait + * parameter are set. + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for all of the bits specified by uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupSync() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupSync() returned because all the bits it was waiting for were + * set then the returned value is the event group value before any bits were + * automatically cleared. + * + * Example usage: +
+ // Bits used by the three tasks.
+ #define TASK_0_BIT		( 1 << 0 )
+ #define TASK_1_BIT		( 1 << 1 )
+ #define TASK_2_BIT		( 1 << 2 )
+
+ #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
+
+ // Use an event group to synchronise three tasks.  It is assumed this event
+ // group has already been created elsewhere.
+ EventGroupHandle_t xEventBits;
+
+ void vTask0( void *pvParameters )
+ {
+ EventBits_t uxReturn;
+ TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 0 in the event flag to note this task has reached the
+		// sync point.  The other two tasks will set the other two bits defined
+		// by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
+		// point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
+		// for this to happen.
+		uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
+
+		if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
+		{
+			// All three tasks reached the synchronisation point before the call
+			// to xEventGroupSync() timed out.
+		}
+	}
+ }
+
+ void vTask1( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 1 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	 }
+ }
+
+ void vTask2( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 2 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	}
+ }
+
+ 
+ * \defgroup xEventGroupSync xEventGroupSync + * \ingroup EventGroup + */ +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
+ 
+ * + * Returns the current value of the bits in an event group. This function + * cannot be used from an interrupt. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBits() was called. + * + * \defgroup xEventGroupGetBits xEventGroupGetBits + * \ingroup EventGroup + */ +#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
+ 
+ * + * A version of xEventGroupGetBits() that can be called from an ISR. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. + * + * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR + * \ingroup EventGroup + */ +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	void xEventGroupDelete( EventGroupHandle_t xEventGroup );
+ 
+ * + * Delete an event group that was previously created by a call to + * xEventGroupCreate(). Tasks that are blocked on the event group will be + * unblocked and obtain 0 as the event group's value. + * + * @param xEventGroup The event group being deleted. + */ +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/* For internal use only. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; + + +#if (configUSE_TRACE_FACILITY == 1) + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION; + void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT_GROUPS_H */ + + diff --git a/include/rtos/freertos/freertos_evr.h b/include/rtos/freertos/freertos_evr.h new file mode 100644 index 0000000..a036194 --- /dev/null +++ b/include/rtos/freertos/freertos_evr.h @@ -0,0 +1,966 @@ +/* -------------------------------------------------------------------------- + * Copyright (c) 2013-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. + * + * Name: freertos_evr.h + * Purpose: FreeRTOS Event Recorder definitions + * + *---------------------------------------------------------------------------*/ + +#ifndef FREERTOS_EVR_H_ +#define FREERTOS_EVR_H_ + +#include +#include + +//#include "RTE_Components.h" + +#if !defined(RTE_Compiler_EventRecorder) + /* Disable debug events if Event Recorder is not used */ + #ifndef EVR_FREERTOS_DISABLE + #define EVR_FREERTOS_DISABLE + #endif +#endif + +/* Temporarily define FreeRTOS object types */ +#define TCB_t void* +#define Queue_t void* +#define Timer_t void* +#define PendedFunction_t void* +#define EventGroup_t void* +#define StreamBuffer_t void* + +/** + \brief Setup Event Recorder configuration + \param[in] reset reset if already configured (0:no reset, 1:reset) +*/ +extern void EvrFreeRTOSSetup (uint32_t reset); + +/** + \brief Event on successful task create (Op) + \param[in] pxNewTCB pointer to task handle. +*/ +extern void EvrFreeRTOSTasks_TaskCreate (TCB_t pxNewTCB); + +/** + \brief Event on unsuccessful task create (Error) +*/ +extern void EvrFreeRTOSTasks_TaskCreateFailed (void); + +/** + \brief Event on task delete (Op) + \param[in] pxTCB pointer to task handle. +*/ +extern void EvrFreeRTOSTasks_TaskDelete (TCB_t pxTCB); + +/** + \brief Event before current running task execution is delayed (Op) + \param[in] xTimeToWake wake time (ticks). +*/ +extern void EvrFreeRTOSTasks_TaskDelayUntil (uint32_t xTimeToWake); + +/** + \brief Event on current thread execution delay (Op) + \param[in] xTicksToDelay number of ticks to delay. +*/ +extern void EvrFreeRTOSTasks_TaskDelay (uint32_t xTicksToDelay); + +/** + \brief Event on task priority set (Op) + \param[in] pxTCB pointer to task handle. + \param[in] uxNewPriority +*/ +extern void EvrFreeRTOSTasks_TaskPrioritySet (TCB_t pxTCB, uint32_t uxNewPriority); + +/** + \brief Event on task suspend (Op) + \param[in] pxTCB pointer to task handle. +*/ +extern void EvrFreeRTOSTasks_TaskSuspend (TCB_t pxTCB); + +/** + \brief Event on task resume (Op) + \param[in] pxTCB pointer to task handle. +*/ +extern void EvrFreeRTOSTasks_TaskResume (TCB_t pxTCB); + +/** + \brief Event on task resume call from ISR (Op) + \param[in] pxTCB pointer to task handle. +*/ +extern void EvrFreeRTOSTasks_TaskResumeFromIsr (TCB_t pxTCB); + +/** + \brief Event on tick count increment (Detail) + \param[in] xTickCount tick count before increment. +*/ +extern void EvrFreeRTOSTasks_TaskIncrementTick (uint32_t xTickCount); + +/** + \brief Event on tick count increase (Op) + \param[in] xTicksToJump number of ticks by which the tick count is increased. +*/ +extern void EvrFreeRTOSTasks_IncreaseTickCount (uint32_t xTicksToJump); + +/** + \brief Event before a new task is selected to run (Op) + \param[in] pxCurrentTCB handle to the task about to leave the running state. +*/ +extern void EvrFreeRTOSTasks_TaskSwitchedOut (TCB_t pxCurrentTCB); + +/** + \brief Event after a task has been selected to run (Op) + \param[in] pxCurrentTCB handle to the task about to enter the running state. + \param[in] uxTopPriority pxCurrentTCB task priority. +*/ +extern void EvrFreeRTOSTasks_TaskSwitchedIn (TCB_t pxCurrentTCB, uint32_t uxTopPriority); + +/** + \brief Event on task priority inheritance (Op) + \param[in] pxTCBOfMutexHolder pointer to task handle. + \param[in] uxInheritedPriority new (inherited) task priority. +*/ +extern void EvrFreeRTOSTasks_TaskPriorityInherit (TCB_t pxTCBOfMutexHolder, uint32_t uxInheritedPriority); + +/** + \brief Event on task priority disinheritance (Op) + \param[in] pxTCBOfMutexHolder pointer to task handle. + \param[in] uxOriginalPriority old (original) task priority. +*/ +extern void EvrFreeRTOSTasks_TaskPriorityDisinherit (TCB_t pxTCBOfMutexHolder, uint32_t uxOriginalPriority); + +/** + \brief Event sent before transition of a task into the Ready state (Op) + \param[in] pxTCB pointer to task handle. +*/ +extern void EvrFreeRTOSTasks_MovedTaskToReadyState (TCB_t pxTCB); + +/** + \brief Event sent after transition of a task into the Ready state (Op) + \param[in] pxTCB pointer to task handle. +*/ +extern void EvrFreeRTOSTasks_PostMovedTaskToReadyState (TCB_t pxTCB); + +/** + \brief Event on enter to the low power mode (Op) + \param[in] xExpectedIdleTime expected idle time in ticks. +*/ +extern void EvrFreeRTOSTasks_LowPowerIdleBegin (uint32_t xExpectedIdleTime); + +/** + \brief Event on exit from the low power mode (Op) +*/ +extern void EvrFreeRTOSTasks_LowPowerIdleEnd (void); + +/** + \brief Event on indicating the current running task is about to block while waiting for notification to be non-zero (Op) + \param[in] xTicksToWait wait timeout in ticks. +*/ +extern void EvrFreeRTOSTasks_TaskNotifyTakeBlock (uint32_t xTicksToWait); + +/** + \brief Event on successful task notify take (Op) + \param[in] ulNotifiedValue current state of the notification value. +*/ +extern void EvrFreeRTOSTasks_TaskNotifyTake (uint32_t ulNotifiedValue); + +/** + \brief Event indicating the current running task is about to block while waiting to receive notification (Op) + \param[in] xTicksToWait wait timeout in ticks. +*/ +extern void EvrFreeRTOSTasks_TaskNotifyWaitBlock (uint32_t xTicksToWait); + +/** + \brief Event on successful task notify wait (Op) + \param[in] ulNotifiedValue current state of the notification value. +*/ +extern void EvrFreeRTOSTasks_TaskNotifyWait (uint32_t ulNotifiedValue); + +/** + \brief Event on successful task notify (Op) + \param[in] xTaskToNotify pointer to task to be notified. + \param[in] ulValue notify value. + \param[in] eAction task notification action. + \param[in] ulNotifiedValue current state of the notification value. +*/ +extern void EvrFreeRTOSTasks_TaskNotify (TCB_t xTaskToNotify, uint32_t ulValue, uint32_t eAction, uint32_t ulNotifiedValue); + +/** + \brief Event on successful task notify from ISR (Op) + \param[in] xTaskToNotify pointer to task to be notified. + \param[in] ulValue notify value. + \param[in] eAction task notification action. + \param[in] ulNotifiedValue current state of the notification value. +*/ +extern void EvrFreeRTOSTasks_TaskNotifyFromIsr (TCB_t xTaskToNotify, uint32_t ulValue, uint32_t eAction, uint32_t ulNotifiedValue); + +/** + \brief Event on successful task notify give from ISR (Op) + \param[in] xTaskToNotify pointer to task to be notified. + \param[in] ulNotifiedValue current state of the notification value. +*/ +extern void EvrFreeRTOSTasks_TaskNotifyGiveFromIsr (TCB_t xTaskToNotify, uint32_t ulNotifiedValue); + +/** + \brief Event on successful queue create (Op) + \param[in] pxQueue pointer to mutex object handle. +*/ +extern void EvrFreeRTOSQueue_QueueCreate (Queue_t pxQueue); + +/** + \brief Event on unsuccessful queue create (Error) + \param[in] ucQueueType queue type +*/ +extern void EvrFreeRTOSQueue_QueueCreateFailed (uint32_t ucQueueType); + +/** + \brief Event on successful mutex create (Op) + \param[in] pxNewQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_CreateMutex (Queue_t pxNewQueue); + +/** + \brief Event on unsuccessful mutex create (Error) +*/ +extern void EvrFreeRTOSQueue_CreateMutexFailed (void); + +/** + \brief Event on successful recursive mutex give (Op) + \param[in] pxMutex pointer to mutex object handle. +*/ +extern void EvrFreeRTOSQueue_GiveMutexRecursive (Queue_t pxMutex); + +/** + \brief Event on unsuccessful recursive mutex give (Error) + \param[in] pxMutex pointer to mutex object handle. +*/ +extern void EvrFreeRTOSQueue_GiveMutexRecursiveFailed (Queue_t pxMutex); + +/** + \brief Event on successful recursive mutex take (Op) + \param[in] pxMutex pointer to mutex object handle. +*/ +extern void EvrFreeRTOSQueue_TakeMutexRecursive (Queue_t pxMutex); + +/** + \brief Event on unsuccessful recursive mutex take (Error) + \param[in] pxMutex pointer to mutex object handle. +*/ +extern void EvrFreeRTOSQueue_TakeMutexRecursiveFailed (Queue_t pxMutex); + +/** + \brief Event on successful counting semaphore create (Op) + \param[in] xHandle pointer to semaphore object handle. +*/ +extern void EvrFreeRTOSQueue_CreateCountingSemaphore (Queue_t xHandle); + +/** + \brief Event on unsuccessful counting semaphore create (Error) +*/ +extern void EvrFreeRTOSQueue_CreateCountingSemaphoreFailed (void); + +/** + \brief Event on queue write (Op) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueueSend (Queue_t pxQueue); + +/** + \brief Event on write to the full queue (Error) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueueSendFailed (Queue_t pxQueue); + +/** + \brief Event on queue read (Op) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueueReceive (Queue_t pxQueue); + +/** + \brief Event on queue peek (Op) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueuePeek (Queue_t pxQueue); + +/** + \brief Event on queue peek when queue is empty and no block time was specified (Error) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueuePeekFailed (Queue_t pxQueue); + +/** + \brief Event on queue peek from ISR (Op) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueuePeekFromIsr (Queue_t pxQueue); + +/** + \brief Event on read from the empty queue (Error) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueueReceiveFailed (Queue_t pxQueue); + +/** + \brief Event on write to the queue from ISR (Op) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueueSendFromIsr (Queue_t pxQueue); + +/** + \brief Event on write to the full queue from ISR (Error) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueueSendFromIsrFailed (Queue_t pxQueue); + +/** + \brief Event on queue read from ISR (Op) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueueReceiveFromIsr (Queue_t pxQueue); + +/** + \brief Event on empty queue read from ISR (Error) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueueReceiveFromIsrFailed (Queue_t pxQueue); + +/** + \brief Event on empty queue peek from ISR (Error) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueuePeekFromIsrFailed (Queue_t pxQueue); + +/** + \brief Event on queue delete (Op) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_QueueDelete (Queue_t pxQueue); + +/** + \brief Event on assignment of a human readable name to a queue (Op) + \param[in] pxQueue pointer to queue object handle. + \param[in] pcQueueName pointer to queue object name. +*/ +extern void EvrFreeRTOSQueue_QueueRegistryAdd (Queue_t pxQueue, const char *pcQueueName); + +/** + \brief Event indicating the current running task is about to block while reading from an empty queue (Op) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_BlockingOnQueueReceive (Queue_t pxQueue); + +/** + \brief Event indicating the current running task is about to block while writting to a full queue (Op) + \param[in] pxQueue pointer to queue object handle. +*/ +extern void EvrFreeRTOSQueue_BlockingOnQueueSend (Queue_t pxQueue); + +/** + \brief Event on successful timer object create (Op) + \param[in] pxNewTimer pointer to timer object handle. +*/ +extern void EvrFreeRTOSTimers_TimerCreate (Timer_t pxNewTimer); + +/** + \brief Event on unsuccessful timer object create (Error) +*/ +extern void EvrFreeRTOSTimers_TimerCreateFailed (void); + +/** + \brief Event on timer queue command send (Op) + \param[in] pxTimer pointer to timer object handle. + \param[in] xCommandID timer command ID. + \param[in] xOptionalValue optional command value. + \param[in] xReturn return value. +*/ +extern void EvrFreeRTOSTimers_TimerCommandSend (Timer_t pxTimer, uint32_t xCommandID, uint32_t xOptionalValue, uint32_t xReturn); + +/** + \brief Event on timer queue command receive (Op) + \param[in] pxTimer pointer to timer object handle. + \param[in] xCommandID timer command ID. + \param[in] xOptionalValue optional command value. +*/ +extern void EvrFreeRTOSTimers_TimerCommandReceived (Timer_t pxTimer, uint32_t xCommandID, uint32_t xOptionalValue); + +/** + \brief Event on timer expire (Op) + \param[in] pxTimer pointer to timer object handle. +*/ +extern void EvrFreeRTOSTimers_TimerExpired (Timer_t pxTimer); + +/** + \brief Event on pass of the function execution to the timer service task (Op) + \param[in] pxFunctionToPend pointer to callback function + \param[in] pvParameter1 function parameter 1. + \param[in] ulParameter2 function parameter 2. + \param[in] xReturn return value. +*/ +extern void EvrFreeRTOSTimers_PendFuncCall (PendedFunction_t pxFunctionToPend, void *pvParameter1, uint32_t ulParameter2, uint32_t xReturn); + +/** + \brief Event on pass of the function execution to the timer service task from the ISR (Op) + \param[in] pxFunctionToPend pointer to callback function + \param[in] pvParameter1 function parameter 1. + \param[in] ulParameter2 function parameter 2. + \param[in] xReturn return value. +*/ +extern void EvrFreeRTOSTimers_PendFuncCallFromIsr (PendedFunction_t pxFunctionToPend, void *pvParameter1, uint32_t ulParameter2, uint32_t xReturn); + +/** + \brief Event on successful event groups object create (Op) + \param[in] pxEventGroup pointer to Event Groups object handle. +*/ +extern void EvrFreeRTOSEventGroups_EventGroupCreate (EventGroup_t pxEventGroup); + +/** + \brief Event on unsuccessful event groups object create (Error) +*/ +extern void EvrFreeRTOSEventGroups_EventGroupCreateFailed (void); + +/** + \brief Event on event groups sync wait start (Op) + \param[in] pxEventGroup pointer to Event Groups object handle. + \param[in] uxBitsToSet event bits that shall be set. + \param[in] uxBitsToWaitFor event bits to wait for. +*/ +extern void EvrFreeRTOSEventGroups_EventGroupSyncBlock (EventGroup_t pxEventGroup, uint32_t uxBitsToSet, uint32_t uxBitsToWaitFor); + +/** + \brief Event on event groups sync completed (Op) + \param[in] pxEventGroup pointer to Event Groups object handle. + \param[in] uxBitsToSet event bits that shall be set. + \param[in] uxBitsToWaitFor event bits to wait for. + \param[in] xTimeoutOccurred timeout value. +*/ +extern void EvrFreeRTOSEventGroups_EventGroupSyncEnd (EventGroup_t pxEventGroup, uint32_t uxBitsToSet, uint32_t uxBitsToWaitFor, uint32_t xTimeoutOccurred); + +/** + \brief Event on event groups bit wait start (Op) + \param[in] pxEventGroup pointer to Event Groups object handle. + \param[in] uxBitsToWaitFor event bits to wait for. +*/ +extern void EvrFreeRTOSEventGroups_EventGroupWaitBitsBlock (EventGroup_t pxEventGroup, uint32_t uxBitsToWaitFor); + +/** + \brief Event on event groups bit wait completed (Op) + \param[in] pxEventGroup pointer to Event Groups object handle. + \param[in] uxBitsToWaitFor event bits to wait for. + \param[in] xTimeoutOccurred timeout value. +*/ +extern void EvrFreeRTOSEventGroups_EventGroupWaitBitsEnd (EventGroup_t pxEventGroup, uint32_t uxBitsToWaitFor, uint32_t xTimeoutOccurred); + +/** + \brief Event on event groups bit clear (Op) + \param[in] pxEventGroup pointer to Event Groups object handle. + \param[in] uxBitsToClear event bits that shall be cleared. +*/ +extern void EvrFreeRTOSEventGroups_EventGroupClearBits (EventGroup_t pxEventGroup, uint32_t uxBitsToClear); + +/** + \brief Event on event groups bit clear call from ISR (Op) + \param[in] pxEventGroup pointer to Event Groups object handle. + \param[in] uxBitsToClear event bits that shall be cleared. +*/ +extern void EvrFreeRTOSEventGroups_EventGroupClearBitsFromIsr (EventGroup_t pxEventGroup, uint32_t uxBitsToClear); + +/** + \brief Event on event groups bit set (Op) + \param[in] pxEventGroup pointer to Event Groups object handle. + \param[in] uxBitsToSet event bits that shall be set. +*/ +extern void EvrFreeRTOSEventGroups_EventGroupSetBits (EventGroup_t pxEventGroup, uint32_t uxBitsToSet); + +/** + \brief Event on event groups bit set call from ISR (Op) + \param[in] pxEventGroup pointer to Event Groups object handle. + \param[in] uxBitsToSet event bits that shall be set. +*/ +extern void EvrFreeRTOSEventGroups_EventGroupSetBitsFromIsr (EventGroup_t pxEventGroup, uint32_t uxBitsToSet); + +/** + \brief Event on event groups object delete (Op) + \param[in] pxEventGroup pointer to Event Groups object handle. +*/ +extern void EvrFreeRTOSEventGroups_EventGroupDelete (EventGroup_t pxEventGroup); + +/** + \brief Event on unsuccessful stream buffer object create (Error) + \param[in] uxIsMessageBuffer buffer type designator (0:stream, 1:message). +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferCreateFailed (uint32_t uxIsMessageBuffer); + +/** + \brief Event on unsuccessful stream buffer object create (Error) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. + \param[in] uxIsMessageBuffer buffer type designator (0:stream, 1:message). +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferCreateStaticFailed (StreamBuffer_t pxStreamBuffer, uint32_t uxIsMessageBuffer); + +/** + \brief Event on successful stream buffer object create (Op) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. + \param[in] uxIsMessageBuffer buffer type designator (0:stream, 1:message). +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferCreate (StreamBuffer_t pxStreamBuffer, uint32_t uxIsMessageBuffer); + +/** + \brief Event on stream buffer object delete (Op) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferDelete (StreamBuffer_t pxStreamBuffer); + +/** + \brief Event on stream buffer object reset (Op) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferReset (StreamBuffer_t pxStreamBuffer); + +/** + \brief Event on stream buffer send when buffer is full and sending task is blocked (Op) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferBlockingOnSend (StreamBuffer_t pxStreamBuffer); + +/** + \brief Event on stream buffer send when data is successfully copied into the buffer (Op) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. + \param[in] xBytesSent number of bytes copied into the buffer +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferSend (StreamBuffer_t pxStreamBuffer, uint32_t xBytesSent); + +/** + \brief Event on stream buffer send when data is not copied into the buffer (Error) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferSendFailed (StreamBuffer_t pxStreamBuffer); + +/** + \brief Event on stream buffer send from ISR when data is successfully copied into the buffer (Op) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. + \param[in] xBytesSent number of bytes copied into the buffer +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferSendFromIsr (StreamBuffer_t pxStreamBuffer, uint32_t xBytesSent); + +/** + \brief Event on stream buffer receive when buffer is empty and receiving task is blocked (Op) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferBlockingOnReceive (StreamBuffer_t pxStreamBuffer); + +/** + \brief Event on stream buffer receive when data is successfully copied from the buffer (Op) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. + \param[in] xReceivedLength number of bytes copied from the buffer +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferReceive (StreamBuffer_t pxStreamBuffer, uint32_t xReceivedLength); + +/** + \brief Event on stream buffer receive when data is not copied from the buffer (Error) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferReceiveFailed (StreamBuffer_t pxStreamBuffer); + +/** + \brief Event on stream buffer receive from ISR when data is successfully copied from the buffer (Op) + \param[in] pxStreamBuffer pointer to Stream Buffer object handle. + \param[in] xReceivedLength number of bytes copied from the buffer +*/ +extern void EvrFreeRTOSStreamBuf_StreamBufferReceiveFromIsr (StreamBuffer_t pxStreamBuffer, uint32_t xReceivedLength); + +/** + \brief Event on heap memory block allocation (Op) + \param[in] pvAddress pointer to memory block. + \param[in] uiSize memory block size. +*/ +extern void EvrFreeRTOSHeap_Malloc (void *pvAddress, uint32_t uiSize); + +/** + \brief Event on heap memory block free (Op) + \param[in] pvAddress pointer to memory block. + \param[in] uiSize memory block size. +*/ +extern void EvrFreeRTOSHeap_Free (void *pvAddress, uint32_t uiSize); + + +/* Tasks */ + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_CREATE_DISABLE)) + #define traceTASK_CREATE(px) EvrFreeRTOSTasks_TaskCreate(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_CREATE_FAILED_DISABLE)) + #define traceTASK_CREATE_FAILED() EvrFreeRTOSTasks_TaskCreateFailed() +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_DELETE_DISABLE)) + #define traceTASK_DELETE(px) EvrFreeRTOSTasks_TaskDelete(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_DELAY_UNTIL_DISABLE)) + #define traceTASK_DELAY_UNTIL(x) EvrFreeRTOSTasks_TaskDelayUntil(x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_DELAY_DISABLE)) + #define traceTASK_DELAY() EvrFreeRTOSTasks_TaskDelay(xTicksToDelay) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_PRIORITY_SET_DISABLE)) + #define traceTASK_PRIORITY_SET(px,ux) EvrFreeRTOSTasks_TaskPrioritySet(px,ux) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_SUSPEND_DISABLE)) + #define traceTASK_SUSPEND(px) EvrFreeRTOSTasks_TaskSuspend(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_RESUME_DISABLE)) + #define traceTASK_RESUME(px) EvrFreeRTOSTasks_TaskResume(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_RESUME_FROM_ISR_DISABLE)) + #define traceTASK_RESUME_FROM_ISR(px) EvrFreeRTOSTasks_TaskResumeFromIsr(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_INCREMENT_TICK_DISABLE)) + #define traceTASK_INCREMENT_TICK(x) EvrFreeRTOSTasks_TaskIncrementTick(x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceINCREASE_TICK_COUNT_DISABLE)) + #define traceINCREASE_TICK_COUNT(x) EvrFreeRTOSTasks_IncreaseTickCount(x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_SWITCHED_OUT_DISABLE)) + #define traceTASK_SWITCHED_OUT() EvrFreeRTOSTasks_TaskSwitchedOut(pxCurrentTCB) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_SWITCHED_IN_DISABLE)) + #define traceTASK_SWITCHED_IN() EvrFreeRTOSTasks_TaskSwitchedIn(pxCurrentTCB, uxTopReadyPriority) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_PRIORITY_INHERIT_DISABLE)) + #define traceTASK_PRIORITY_INHERIT(px,ux) EvrFreeRTOSTasks_TaskPriorityInherit(px,ux) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_PRIORITY_DISINHERIT_DISABLE)) + #define traceTASK_PRIORITY_DISINHERIT(px,ux) EvrFreeRTOSTasks_TaskPriorityDisinherit(px,ux) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceMOVED_TASK_TO_READY_STATE_DISABLE)) + #define traceMOVED_TASK_TO_READY_STATE(px) EvrFreeRTOSTasks_MovedTaskToReadyState(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(tracePOST_MOVED_TASK_TO_READY_STATE_DISABLE)) + #define tracePOST_MOVED_TASK_TO_READY_STATE(px) EvrFreeRTOSTasks_PostMovedTaskToReadyState(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceLOW_POWER_IDLE_BEGIN_DISABLE)) + #define traceLOW_POWER_IDLE_BEGIN() EvrFreeRTOSTasks_LowPowerIdleBegin(xExpectedIdleTime) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceLOW_POWER_IDLE_END_DISABLE)) + #define traceLOW_POWER_IDLE_END() EvrFreeRTOSTasks_LowPowerIdleEnd() +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_NOTIFY_TAKE_BLOCK_DISABLE)) + #define traceTASK_NOTIFY_TAKE_BLOCK() EvrFreeRTOSTasks_TaskNotifyTakeBlock(xTicksToWait) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_NOTIFY_TAKE_DISABLE)) + #define traceTASK_NOTIFY_TAKE() EvrFreeRTOSTasks_TaskNotifyTake(pxCurrentTCB->ulNotifiedValue) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_NOTIFY_WAIT_BLOCK_DISABLE)) + #define traceTASK_NOTIFY_WAIT_BLOCK() EvrFreeRTOSTasks_TaskNotifyWaitBlock(xTicksToWait) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_NOTIFY_WAIT_DISABLE)) + #define traceTASK_NOTIFY_WAIT() EvrFreeRTOSTasks_TaskNotifyWait(pxCurrentTCB->ulNotifiedValue) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_NOTIFY_DISABLE)) + #define traceTASK_NOTIFY() EvrFreeRTOSTasks_TaskNotify(pxTCB, ulValue, eAction, pxTCB->ulNotifiedValue) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_NOTIFY_FROM_ISR_DISABLE)) + #define traceTASK_NOTIFY_FROM_ISR() EvrFreeRTOSTasks_TaskNotifyFromIsr(pxTCB, ulValue, eAction, pxTCB->ulNotifiedValue) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTASK_NOTIFY_GIVE_FROM_ISR_DISABLE)) + #define traceTASK_NOTIFY_GIVE_FROM_ISR() EvrFreeRTOSTasks_TaskNotifyGiveFromIsr(pxTCB, pxTCB->ulNotifiedValue) +#endif + + +/* Queue */ + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_CREATE_DISABLE)) + #define traceQUEUE_CREATE(px) EvrFreeRTOSQueue_QueueCreate(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_CREATE_FAILED_DISABLE)) + #define traceQUEUE_CREATE_FAILED(uc) EvrFreeRTOSQueue_QueueCreateFailed(uc) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceCREATE_MUTEX_DISABLE)) + #define traceCREATE_MUTEX(px) EvrFreeRTOSQueue_CreateMutex(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceCREATE_MUTEX_FAILED_DISABLE)) + #define traceCREATE_MUTEX_FAILED() EvrFreeRTOSQueue_CreateMutexFailed() +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceGIVE_MUTEX_RECURSIVE_DISABLE)) + #define traceGIVE_MUTEX_RECURSIVE(px) EvrFreeRTOSQueue_GiveMutexRecursive(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceGIVE_MUTEX_RECURSIVE_FAILED_DISABLE)) + #define traceGIVE_MUTEX_RECURSIVE_FAILED(px) EvrFreeRTOSQueue_GiveMutexRecursiveFailed(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTAKE_MUTEX_RECURSIVE_DISABLE)) + #define traceTAKE_MUTEX_RECURSIVE(px) EvrFreeRTOSQueue_TakeMutexRecursive(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTAKE_MUTEX_RECURSIVE_FAILED_DISABLE)) + #define traceTAKE_MUTEX_RECURSIVE_FAILED(px) EvrFreeRTOSQueue_TakeMutexRecursiveFailed(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceCREATE_COUNTING_SEMAPHORE_DISABLE)) + #define traceCREATE_COUNTING_SEMAPHORE() EvrFreeRTOSQueue_CreateCountingSemaphore(xHandle) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceCREATE_COUNTING_SEMAPHORE_FAILED_DISABLE)) + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() EvrFreeRTOSQueue_CreateCountingSemaphoreFailed() +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_SEND_DISABLE)) + #define traceQUEUE_SEND(px) EvrFreeRTOSQueue_QueueSend(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_SEND_FAILED_DISABLE)) + #define traceQUEUE_SEND_FAILED(px) EvrFreeRTOSQueue_QueueSendFailed(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_RECEIVE_DISABLE)) + #define traceQUEUE_RECEIVE(px) EvrFreeRTOSQueue_QueueReceive(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_PEEK_DISABLE)) + #define traceQUEUE_PEEK(px) EvrFreeRTOSQueue_QueuePeek(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_PEEK_DISABLE)) + #define traceQUEUE_PEEK_FAILED(px) EvrFreeRTOSQueue_QueuePeekFailed(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_PEEK_FROM_ISR_DISABLE)) + #define traceQUEUE_PEEK_FROM_ISR(px) EvrFreeRTOSQueue_QueuePeekFromIsr(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_RECEIVE_FAILED_DISABLE)) + #define traceQUEUE_RECEIVE_FAILED(px) EvrFreeRTOSQueue_QueueReceiveFailed(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_SEND_FROM_ISR_DISABLE)) + #define traceQUEUE_SEND_FROM_ISR(px) EvrFreeRTOSQueue_QueueSendFromIsr(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_SEND_FROM_ISR_FAILED_DISABLE)) + #define traceQUEUE_SEND_FROM_ISR_FAILED(px) EvrFreeRTOSQueue_QueueSendFromIsrFailed(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_RECEIVE_FROM_ISR_DISABLE)) + #define traceQUEUE_RECEIVE_FROM_ISR(px) EvrFreeRTOSQueue_QueueReceiveFromIsr(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_RECEIVE_FROM_ISR_FAILED_DISABLE)) + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED(px) EvrFreeRTOSQueue_QueueReceiveFromIsrFailed(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_PEEK_FROM_ISR_FAILED_DISABLE)) + #define traceQUEUE_PEEK_FROM_ISR_FAILED(px) EvrFreeRTOSQueue_QueuePeekFromIsrFailed(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_DELETE_DISABLE)) + #define traceQUEUE_DELETE(px) EvrFreeRTOSQueue_QueueDelete(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceQUEUE_REGISTRY_ADD_DISABLE)) + #define traceQUEUE_REGISTRY_ADD(px,pc) EvrFreeRTOSQueue_QueueRegistryAdd(px,pc) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceBLOCKING_ON_QUEUE_RECEIVE_DISABLE)) + #define traceBLOCKING_ON_QUEUE_RECEIVE(px) EvrFreeRTOSQueue_BlockingOnQueueReceive(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceBLOCKING_ON_QUEUE_SEND_DISABLE)) + #define traceBLOCKING_ON_QUEUE_SEND(px) EvrFreeRTOSQueue_BlockingOnQueueSend(px) +#endif + + +/* Timers */ + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTIMER_CREATE_DISABLE)) + #define traceTIMER_CREATE(px) EvrFreeRTOSTimers_TimerCreate(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTIMER_CREATE_FAILED_DISABLE)) + #define traceTIMER_CREATE_FAILED() EvrFreeRTOSTimers_TimerCreateFailed() +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTIMER_COMMAND_SEND_DISABLE)) + #define traceTIMER_COMMAND_SEND(pxT,xC,xO,xR) EvrFreeRTOSTimers_TimerCommandSend(pxT,xC,xO,xR) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTIMER_COMMAND_RECEIVED_DISABLE)) + #define traceTIMER_COMMAND_RECEIVED(px,xC,xO) EvrFreeRTOSTimers_TimerCommandReceived(px,xC,xO) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceTIMER_EXPIRED_DISABLE)) + #define traceTIMER_EXPIRED(px) EvrFreeRTOSTimers_TimerExpired(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(tracePEND_FUNC_CALL_DISABLE)) + #define tracePEND_FUNC_CALL(px,pv,ul,x) EvrFreeRTOSTimers_PendFuncCall(px,pv,ul,x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(tracePEND_FUNC_CALL_FROM_ISR_DISABLE)) + #define tracePEND_FUNC_CALL_FROM_ISR(px,pv,ul,x) EvrFreeRTOSTimers_PendFuncCallFromIsr(px,pv,ul,x) +#endif + + +/* Event Groups */ + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_CREATE_DISABLE)) + #define traceEVENT_GROUP_CREATE(px) EvrFreeRTOSEventGroups_EventGroupCreate(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_CREATE_FAILED_DISABLE)) + #define traceEVENT_GROUP_CREATE_FAILED() EvrFreeRTOSEventGroups_EventGroupCreateFailed() +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_SYNC_BLOCK_DISABLE)) + #define traceEVENT_GROUP_SYNC_BLOCK(px,uxS,uxW) EvrFreeRTOSEventGroups_EventGroupSyncBlock(px,uxS,uxW) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_SYNC_END_DISABLE)) + #define traceEVENT_GROUP_SYNC_END(px,uxS,uxW,x) EvrFreeRTOSEventGroups_EventGroupSyncEnd(px,uxS,uxW,x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_WAIT_BITS_BLOCK_DISABLE)) + #define traceEVENT_GROUP_WAIT_BITS_BLOCK(px,ux) EvrFreeRTOSEventGroups_EventGroupWaitBitsBlock(px,ux) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_WAIT_BITS_END_DISABLE)) + #define traceEVENT_GROUP_WAIT_BITS_END(px,ux,x) EvrFreeRTOSEventGroups_EventGroupWaitBitsEnd(px,ux,x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_CLEAR_BITS_DISABLE)) + #define traceEVENT_GROUP_CLEAR_BITS(px,ux) EvrFreeRTOSEventGroups_EventGroupClearBits(px,ux) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_CLEAR_BITS_FROM_ISR_DISABLE)) + #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(px,ux) EvrFreeRTOSEventGroups_EventGroupClearBitsFromIsr(px,ux) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_SET_BITS_DISABLE)) + #define traceEVENT_GROUP_SET_BITS(px,ux) EvrFreeRTOSEventGroups_EventGroupSetBits(px,ux) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_SET_BITS_FROM_ISR_DISABLE)) + #define traceEVENT_GROUP_SET_BITS_FROM_ISR(px,ux) EvrFreeRTOSEventGroups_EventGroupSetBitsFromIsr(px,ux) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceEVENT_GROUP_DELETE_DISABLE)) + #define traceEVENT_GROUP_DELETE(px) EvrFreeRTOSEventGroups_EventGroupDelete(px) +#endif + + +/* Stream Buffer */ + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_CREATE_FAILED_DISABLE)) + #define traceSTREAM_BUFFER_CREATE_FAILED(ux) EvrFreeRTOSStreamBuf_StreamBufferCreateFailed(ux) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_CREATE_STATIC_FAILED_DISABLE)) + #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED(x,ux) EvrFreeRTOSStreamBuf_StreamBufferCreateStaticFailed(x,ux) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_CREATE_DISABLE)) + #define traceSTREAM_BUFFER_CREATE(px,x) EvrFreeRTOSStreamBuf_StreamBufferCreate(px,x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_DELETE_DISABLE)) + #define traceSTREAM_BUFFER_DELETE(px) EvrFreeRTOSStreamBuf_StreamBufferDelete(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_RESET_DISABLE)) + #define traceSTREAM_BUFFER_RESET(px) EvrFreeRTOSStreamBuf_StreamBufferReset(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceBLOCKING_ON_STREAM_BUFFER_SEND_DISABLE)) + #define traceBLOCKING_ON_STREAM_BUFFER_SEND(px) EvrFreeRTOSStreamBuf_StreamBufferBlockingOnSend(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_SEND_DISABLE)) + #define traceSTREAM_BUFFER_SEND(px,x) EvrFreeRTOSStreamBuf_StreamBufferSend(px,x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_SEND_FAILED_DISABLE)) + #define traceSTREAM_BUFFER_SEND_FAILED(px) EvrFreeRTOSStreamBuf_StreamBufferSendFailed(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_SEND_FROM_ISR_DISABLE)) + #define traceSTREAM_BUFFER_SEND_FROM_ISR(px,x) EvrFreeRTOSStreamBuf_StreamBufferSendFromIsr(px,x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceBLOCKING_ON_STREAM_BUFFER_RECEIVE_DISABLE)) + #define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE(px) EvrFreeRTOSStreamBuf_StreamBufferBlockingOnReceive(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_RECEIVE_DISABLE)) + #define traceSTREAM_BUFFER_RECEIVE(px,x) EvrFreeRTOSStreamBuf_StreamBufferReceive(px,x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_RECEIVE_FAILED_DISABLE)) + #define traceSTREAM_BUFFER_RECEIVE_FAILED(px) EvrFreeRTOSStreamBuf_StreamBufferReceiveFailed(px) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceSTREAM_BUFFER_RECEIVE_FROM_ISR_DISABLE)) + #define traceSTREAM_BUFFER_RECEIVE_FROM_ISR(px,x) EvrFreeRTOSStreamBuf_StreamBufferReceiveFromIsr(px,x) +#endif + + +/* Heap */ + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceMALLOC_DISABLE)) + #define traceMALLOC(pv,x) EvrFreeRTOSHeap_Malloc(pv,x) +#endif + +#if (!defined(EVR_FREERTOS_DISABLE) && !defined(traceFREE_DISABLE)) + #define traceFREE(pv,x) EvrFreeRTOSHeap_Free(pv,x) +#endif + + +/* Undefine FreeRTOS object types */ +#undef TCB_t +#undef Queue_t +#undef Timer_t +#undef PendedFunction_t +#undef EventGroup_t +#undef StreamBuffer_t + +#endif /* FREERTOS_EVR_H_ */ diff --git a/include/rtos/freertos/freertos_list.h b/include/rtos/freertos/freertos_list.h new file mode 100644 index 0000000..43e0fff --- /dev/null +++ b/include/rtos/freertos/freertos_list.h @@ -0,0 +1,412 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * descending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + +#ifndef INC_FREERTOS_H + #error FreeRTOS.h must be included before list.h +#endif + +#ifndef LIST_H +#define LIST_H + +/* + * The list structure members are modified from within interrupts, and therefore + * by rights should be declared volatile. However, they are only modified in a + * functionally atomic way (within critical sections of with the scheduler + * suspended) and are either passed by reference into a function or indexed via + * a volatile variable. Therefore, in all use cases tested so far, the volatile + * qualifier can be omitted in order to provide a moderate performance + * improvement without adversely affecting functional behaviour. The assembly + * instructions generated by the IAR, ARM and GCC compilers when the respective + * compiler's options were set for maximum optimisation has been inspected and + * deemed to be as intended. That said, as compiler technology advances, and + * especially if aggressive cross module optimisation is used (a use case that + * has not been exercised to any great extend) then it is feasible that the + * volatile qualifier will be needed for correct optimisation. It is expected + * that a compiler removing essential code because, without the volatile + * qualifier on the list structure members and with aggressive cross module + * optimisation, the compiler deemed the code unnecessary will result in + * complete and obvious failure of the scheduler. If this is ever experienced + * then the volatile qualifier can be inserted in the relevant places within the + * list structures by simply defining configLIST_VOLATILE to volatile in + * FreeRTOSConfig.h (as per the example at the bottom of this comment block). + * If configLIST_VOLATILE is not defined then the preprocessor directives below + * will simply #define configLIST_VOLATILE away completely. + * + * To use volatile list structure members then add the following line to + * FreeRTOSConfig.h (without the quotes): + * "#define configLIST_VOLATILE volatile" + */ +#ifndef configLIST_VOLATILE + #define configLIST_VOLATILE +#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macros that can be used to place known values within the list structures, +then check that the known values do not get corrupted during the execution of +the application. These may catch the list data structures being overwritten in +memory. They will not catch data errors caused by incorrect configuration or +use of FreeRTOS.*/ +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) + /* Define the macros to do nothing. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) + #define listTEST_LIST_INTEGRITY( pxList ) +#else + /* Define macros that add new members into the list structures. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; + + /* Define macros that set the new structure members to known values. */ + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + + /* Define macros that will assert if one of the structure members does not + contain its expected value. */ + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) + #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) +#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ + + +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST; +struct xLIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ + struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ + void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */ + listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +}; +typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ + +struct xMINI_LIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; + struct xLIST_ITEM * configLIST_VOLATILE pxNext; + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; +}; +typedef struct xMINI_LIST_ITEM MiniListItem_t; + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + volatile UBaseType_t uxNumberOfItems; + ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ + MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ + listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +} List_t; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) + +/* + * Access macro to get the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in descending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) + +/* + * Access macro to retrieve the value of the list item. The value can + * represent anything - for example the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro to retrieve the value of the list item at the head of a given + * list. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_NEXT listGET_NEXT + * \ingroup LinkedList + */ +#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) + +/* + * Return the list item that marks the end of the list + * + * \page listGET_END_MARKER listGET_END_MARKER + * \ingroup LinkedList + */ +#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entry's pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxTCB pxTCB is set to the address of the owner of the next list item. + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ +{ \ +List_t * const pxConstList = ( pxList ); \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + } \ + ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ +} + + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE if the list item is in the list, otherwise pdFALSE. + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) + +/* + * Return the list a list item is contained within (referenced from). + * + * @param pxListItem The list item being queried. + * @return A pointer to the List_t object that references the pxListItem + */ +#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) + +/* + * This provides a crude means of knowing if a list has been initialised, as + * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() + * function. + */ +#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (descending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pxIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pxIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page uxListRemove uxListRemove + * \ingroup LinkedList + */ +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/rtos/freertos/message_buffer.h b/include/rtos/freertos/message_buffer.h new file mode 100644 index 0000000..e62e42d --- /dev/null +++ b/include/rtos/freertos/message_buffer.h @@ -0,0 +1,798 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * Message buffers build functionality on top of FreeRTOS stream buffers. + * Whereas stream buffers are used to send a continuous stream of data from one + * task or interrupt to another, message buffers are used to send variable + * length discrete messages from one task or interrupt to another. Their + * implementation is light weight, making them particularly suited for interrupt + * to task and core to core communication scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * timeout to 0. + * + * Message buffers hold variable length messages. To enable that, when a + * message is written to the message buffer an additional sizeof( size_t ) bytes + * are also written to store the message's length (that happens internally, with + * the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so writing a 10 byte message to a message buffer on a 32-bit + * architecture will actually reduce the available space in the message buffer + * by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length + * of the message). + */ + +#ifndef FREERTOS_MESSAGE_BUFFER_H +#define FREERTOS_MESSAGE_BUFFER_H + +/* Message buffers are built onto of stream buffers. */ +#include "stream_buffer.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +/** + * Type by which message buffers are referenced. For example, a call to + * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can + * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(), + * etc. + */ +typedef void * MessageBufferHandle_t; + +/*-----------------------------------------------------------*/ + +/** + * message_buffer.h + * +
+MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
+
+ * + * Creates a new message buffer using dynamically allocated memory. See + * xMessageBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xMessageBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes (not messages) the message + * buffer will be able to hold at any one time. When a message is written to + * the message buffer an additional sizeof( size_t ) bytes are also written to + * store the message's length. sizeof( size_t ) is typically 4 bytes on a + * 32-bit architecture, so on most 32-bit architectures a 10 byte message will + * take up 14 bytes of message buffer space. + * + * @return If NULL is returned, then the message buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the message buffer data structures and storage area. A non-NULL value being + * returned indicates that the message buffer has been created successfully - + * the returned value should be stored as the handle to the created message + * buffer. + * + * Example use: +
+
+void vAFunction( void )
+{
+MessageBufferHandle_t xMessageBuffer;
+const size_t xMessageBufferSizeBytes = 100;
+
+    // Create a message buffer that can hold 100 bytes.  The memory used to hold
+    // both the message buffer structure and the messages themselves is allocated
+    // dynamically.  Each message added to the buffer consumes an additional 4
+    // bytes which are used to hold the lengh of the message.
+    xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
+
+    if( xMessageBuffer == NULL )
+    {
+        // There was not enough heap memory space available to create the
+        // message buffer.
+    }
+    else
+    {
+        // The message buffer was created successfully and can now be used.
+    }
+
+
+ * \defgroup xMessageBufferCreate xMessageBufferCreate + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE ) + +/** + * message_buffer.h + * +
+MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
+                                                  uint8_t *pucMessageBufferStorageArea,
+                                                  StaticMessageBuffer_t *pxStaticMessageBuffer );
+
+ * Creates a new message buffer using statically allocated memory. See + * xMessageBufferCreate() for a version that uses dynamically allocated memory. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucMessageBufferStorageArea parameter. When a message is written to the + * message buffer an additional sizeof( size_t ) bytes are also written to store + * the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so on most 32-bit architecture a 10 byte message will take up + * 14 bytes of message buffer space. The maximum number of bytes that can be + * stored in the message buffer is actually (xBufferSizeBytes - 1). + * + * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes + 1 big. This is the array to which messages are + * copied when they are written to the message buffer. + * + * @param pxStaticMessageBuffer Must point to a variable of type + * StaticMessageBuffer_t, which will be used to hold the message buffer's data + * structure. + * + * @return If the message buffer is created successfully then a handle to the + * created message buffer is returned. If either pucMessageBufferStorageArea or + * pxStaticmessageBuffer are NULL then NULL is returned. + * + * Example use: +
+
+// Used to dimension the array used to hold the messages.  The available space
+// will actually be one less than this, so 999.
+#define STORAGE_SIZE_BYTES 1000
+
+// Defines the memory that will actually hold the messages within the message
+// buffer.
+static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
+
+// The variable used to hold the message buffer structure.
+StaticMessageBuffer_t xMessageBufferStruct;
+
+void MyFunction( void )
+{
+MessageBufferHandle_t xMessageBuffer;
+
+    xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
+                                                 ucBufferStorage,
+                                                 &xMessageBufferStruct );
+
+    // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
+    // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
+    // reference the created message buffer in other message buffer API calls.
+
+    // Other code that uses the message buffer can go here.
+}
+
+
+ * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
+                           const void *pvTxData,
+                           size_t xDataLengthBytes,
+                           TickType_t xTicksToWait );
+
+ *
+ * Sends a discrete message to the message buffer.  The message can be any
+ * length that fits within the buffer's free space, and is copied into the
+ * buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferSend() to write to a message buffer from a task.  Use
+ * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer to which a message is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the message that is to be copied into the
+ * message buffer.
+ *
+ * @param xDataLengthBytes The length of the message.  That is, the number of
+ * bytes to copy from pvTxData into the message buffer.  When a message is
+ * written to the message buffer an additional sizeof( size_t ) bytes are also
+ * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
+ * on a 32-bit architecture, so on most 32-bit architecture setting
+ * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
+ * bytes (20 bytes of message data and 4 bytes to hold the message length).
+ *
+ * @param xTicksToWait The maximum amount of time the calling task should remain
+ * in the Blocked state to wait for enough space to become available in the
+ * message buffer, should the message buffer have insufficient space when
+ * xMessageBufferSend() is called.  The calling task will never block if
+ * xTicksToWait is zero.  The block time is specified in tick periods, so the
+ * absolute time it represents is dependent on the tick frequency.  The macro
+ * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
+ * a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will cause
+ * the task to wait indefinitely (without timing out), provided
+ * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any
+ * CPU time when they are in the Blocked state.
+ *
+ * @return The number of bytes written to the message buffer.  If the call to
+ * xMessageBufferSend() times out before there was enough space to write the
+ * message into the message buffer then zero is returned.  If the call did not
+ * time out then xDataLengthBytes is returned.
+ *
+ * Example use:
+
+void vAFunction( MessageBufferHandle_t xMessageBuffer )
+{
+size_t xBytesSent;
+uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
+char *pcStringToSend = "String to send";
+const TickType_t x100ms = pdMS_TO_TICKS( 100 );
+
+    // Send an array to the message buffer, blocking for a maximum of 100ms to
+    // wait for enough space to be available in the message buffer.
+    xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
+
+    if( xBytesSent != sizeof( ucArrayToSend ) )
+    {
+        // The call to xMessageBufferSend() times out before there was enough
+        // space in the buffer for the data to be written.
+    }
+
+    // Send the string to the message buffer.  Return immediately if there is
+    // not enough space in the buffer.
+    xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The string could not be added to the message buffer because there was
+        // not enough free space in the buffer.
+    }
+}
+
+ * \defgroup xMessageBufferSend xMessageBufferSend + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
+                                  const void *pvTxData,
+                                  size_t xDataLengthBytes,
+                                  BaseType_t *pxHigherPriorityTaskWoken );
+
+ *
+ * Interrupt safe version of the API function that sends a discrete message to
+ * the message buffer.  The message can be any length that fits within the
+ * buffer's free space, and is copied into the buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferSend() to write to a message buffer from a task.  Use
+ * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer to which a message is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the message that is to be copied into the
+ * message buffer.
+ *
+ * @param xDataLengthBytes The length of the message.  That is, the number of
+ * bytes to copy from pvTxData into the message buffer.  When a message is
+ * written to the message buffer an additional sizeof( size_t ) bytes are also
+ * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
+ * on a 32-bit architecture, so on most 32-bit architecture setting
+ * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
+ * bytes (20 bytes of message data and 4 bytes to hold the message length).
+ *
+ * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will
+ * have a task blocked on it waiting for data.  Calling
+ * xMessageBufferSendFromISR() can make data available, and so cause a task that
+ * was waiting for data to leave the Blocked state.  If calling
+ * xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently executing task (the
+ * task that was interrupted), then, internally, xMessageBufferSendFromISR()
+ * will set *pxHigherPriorityTaskWoken to pdTRUE.  If
+ * xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
+ * context switch should be performed before the interrupt is exited.  This will
+ * ensure that the interrupt returns directly to the highest priority Ready
+ * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it
+ * is passed into the function.  See the code example below for an example.
+ *
+ * @return The number of bytes actually written to the message buffer.  If the
+ * message buffer didn't have enough free space for the message to be stored
+ * then 0 is returned, otherwise xDataLengthBytes is returned.
+ *
+ * Example use:
+
+// A message buffer that has already been created.
+MessageBufferHandle_t xMessageBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+size_t xBytesSent;
+char *pcStringToSend = "String to send";
+BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
+
+    // Attempt to send the string to the message buffer.
+    xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
+                                            ( void * ) pcStringToSend,
+                                            strlen( pcStringToSend ),
+                                            &xHigherPriorityTaskWoken );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The string could not be added to the message buffer because there was
+        // not enough free space in the buffer.
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xMessageBufferSendFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
+                              void *pvRxData,
+                              size_t xBufferLengthBytes,
+                              TickType_t xTicksToWait );
+
+ * + * Receives a discrete message from a message buffer. Messages can be of + * variable length and are copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for a message, should the message buffer be empty. + * xMessageBufferReceive() will return immediately if xTicksToWait is zero and + * the message buffer is empty. The block time is specified in tick periods, so + * the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any + * CPU time when they are in the Blocked state. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. If xMessageBufferReceive() times out before a message became available + * then zero is returned. If the length of the message is greater than + * xBufferLengthBytes then the message will be left in the message buffer and + * zero is returned. + * + * Example use: +
+void vAFunction( MessageBuffer_t xMessageBuffer )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
+
+    // Receive the next message from the message buffer.  Wait in the Blocked
+    // state (so not using any CPU processing time) for a maximum of 100ms for
+    // a message to become available.
+    xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
+                                            ( void * ) ucRxData,
+                                            sizeof( ucRxData ),
+                                            xBlockTime );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains a message that is xReceivedBytes long.  Process
+        // the message here....
+    }
+}
+
+ * \defgroup xMessageBufferReceive xMessageBufferReceive + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) + + +/** + * message_buffer.h + * +
+size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
+                                     void *pvRxData,
+                                     size_t xBufferLengthBytes,
+                                     BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * An interrupt safe version of the API function that receives a discrete + * message from a message buffer. Messages can be of variable length and are + * copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param pxHigherPriorityTaskWoken It is possible that a message buffer will + * have a task blocked on it waiting for space to become available. Calling + * xMessageBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. + * + * Example use: +
+// A message buffer that has already been created.
+MessageBuffer_t xMessageBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
+
+    // Receive the next message from the message buffer.
+    xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
+                                                  ( void * ) ucRxData,
+                                                  sizeof( ucRxData ),
+                                                  &xHigherPriorityTaskWoken );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains a message that is xReceivedBytes long.  Process
+        // the message here....
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xMessageBufferReceiveFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
+
+ * + * Deletes a message buffer that was previously created using a call to + * xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message + * buffer was created using dynamic memory (that is, by xMessageBufferCreate()), + * then the allocated memory is freed. + * + * A message buffer handle must not be used after the message buffer has been + * deleted. + * + * @param xMessageBuffer The handle of the message buffer to be deleted. + * + */ +#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
+
+ * + * Tests to see if a message buffer is full. A message buffer is full if it + * cannot accept any more messages, of any size, until space is made available + * by a message being removed from the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is full then + * pdTRUE is returned. Otherwise pdFALSE is returned. + */ +#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
+
+ * + * Tests to see if a message buffer is empty (does not contain any messages). + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is empty then + * pdTRUE is returned. Otherwise pdFALSE is returned. + * + */ +#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
+
+ * + * Resets a message buffer to its initial empty state, discarding any message it + * contained. + * + * A message buffer can only be reset if there are no tasks blocked on it. + * + * @param xMessageBuffer The handle of the message buffer being reset. + * + * @return If the message buffer was reset then pdPASS is returned. If the + * message buffer could not be reset because either there was a task blocked on + * the message queue to wait for space to become available, or to wait for a + * a message to be available, then pdFAIL is returned. + * + * \defgroup xMessageBufferReset xMessageBufferReset + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer ) + + +/** + * message_buffer.h +
+size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
+
+ * Returns the number of bytes of free space in the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The number of bytes that can be written to the message buffer before + * the message buffer would be full. When a message is written to the message + * buffer an additional sizeof( size_t ) bytes are also written to store the + * message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size + * of the largest message that can be written to the message buffer is 6 bytes. + * + * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+ size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
+ 
+ * Returns the length (in bytes) of the next message in a message buffer. + * Useful if xMessageBufferReceive() returned 0 because the size of the buffer + * passed into xMessageBufferReceive() was too small to hold the next message. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The length (in bytes) of the next message in the message buffer, or 0 + * if the message buffer is empty. + * + * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes + * \ingroup MessageBufferManagement + */ +#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION; + +/** + * message_buffer.h + * +
+BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xMessageBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferSendCompletedFromISR(). If calling + * xMessageBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferReceiveCompletedFromISR(). If calling + * xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) + +#if defined( __cplusplus ) +} /* extern "C" */ +#endif + +#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */ diff --git a/include/rtos/freertos/mpu_prototypes.h b/include/rtos/freertos/mpu_prototypes.h new file mode 100644 index 0000000..8510d40 --- /dev/null +++ b/include/rtos/freertos/mpu_prototypes.h @@ -0,0 +1,156 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * When the MPU is used the standard (non MPU) API functions are mapped to + * equivalents that start "MPU_", the prototypes for which are defined in this + * header files. This will cause the application code to call the MPU_ version + * which wraps the non-MPU version with privilege promoting then demoting code, + * so the kernel code always runs will full privileges. + */ + + +#ifndef MPU_PROTOTYPES_H +#define MPU_PROTOTYPES_H + +/* MPU versions of tasks.h API functions. */ +BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ); +TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ); +BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ); +BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ); +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ); +void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ); +void MPU_vTaskDelay( const TickType_t xTicksToDelay ); +void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ); +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ); +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ); +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ); +void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ); +void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ); +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ); +void MPU_vTaskResume( TaskHandle_t xTaskToResume ); +void MPU_vTaskStartScheduler( void ); +void MPU_vTaskSuspendAll( void ); +BaseType_t MPU_xTaskResumeAll( void ); +TickType_t MPU_xTaskGetTickCount( void ); +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ); +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ); +TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ); +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ); +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ); +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ); +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ); +BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ); +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ); +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ); +void MPU_vTaskList( char * pcWriteBuffer ); +void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ); +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ); +BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); +uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); +BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ); +BaseType_t MPU_xTaskIncrementTick( void ); +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ); +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ); +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ); +void MPU_vTaskMissedYield( void ); +BaseType_t MPU_xTaskGetSchedulerState( void ); + +/* MPU versions of queue.h API functions. */ +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ); +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ); +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ); +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ); +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ); +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ); +void MPU_vQueueDelete( QueueHandle_t xQueue ); +QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ); +QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ); +QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ); +QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ); +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ); +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ); +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ); +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ); +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ); +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ); +QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ); +QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ); +QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ); +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ); +BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ); +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ); +BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ); +void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ); +UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ); +uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ); + +/* MPU versions of timers.h API functions. */ +TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ); +TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ); +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ); +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ); +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ); +BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ); +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ); +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ); +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ); +BaseType_t MPU_xTimerCreateTimerTask( void ); +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ); + +/* MPU versions of event_group.h API functions. */ +EventGroupHandle_t MPU_xEventGroupCreate( void ); +EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ); +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ); +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ); +void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ); +UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ); + +/* MPU versions of message/stream_buffer.h API functions. */ +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ); +size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken ); +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ); +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ); +size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken ); +void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ); +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ); +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ); +BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ); +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ); +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ); +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ); +StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ); +StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ); + + + +#endif /* MPU_PROTOTYPES_H */ + diff --git a/include/rtos/freertos/mpu_wrappers.h b/include/rtos/freertos/mpu_wrappers.h new file mode 100644 index 0000000..f7a53c5 --- /dev/null +++ b/include/rtos/freertos/mpu_wrappers.h @@ -0,0 +1,182 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but +only for ports that are using the MPU. */ +#ifdef portUSING_MPU_WRAPPERS + + /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is + included from queue.c or task.c to prevent it from having an effect within + those files. */ + #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + + /* + * Map standard (non MPU) API functions to equivalents that start + * "MPU_". This will cause the application code to call the MPU_ + * version, which wraps the non-MPU version with privilege promoting + * then demoting code, so the kernel code always runs will full + * privileges. + */ + + /* Map standard tasks.h API functions to the MPU equivalents. */ + #define xTaskCreate MPU_xTaskCreate + #define xTaskCreateStatic MPU_xTaskCreateStatic + #define xTaskCreateRestricted MPU_xTaskCreateRestricted + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define vTaskDelete MPU_vTaskDelete + #define vTaskDelay MPU_vTaskDelay + #define vTaskDelayUntil MPU_vTaskDelayUntil + #define xTaskAbortDelay MPU_xTaskAbortDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define eTaskGetState MPU_eTaskGetState + #define vTaskGetInfo MPU_vTaskGetInfo + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define vTaskSuspend MPU_vTaskSuspend + #define vTaskResume MPU_vTaskResume + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskResumeAll MPU_xTaskResumeAll + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define pcTaskGetName MPU_pcTaskGetName + #define xTaskGetHandle MPU_xTaskGetHandle + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer + #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle + #define uxTaskGetSystemState MPU_uxTaskGetSystemState + #define vTaskList MPU_vTaskList + #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats + #define xTaskGenericNotify MPU_xTaskGenericNotify + #define xTaskNotifyWait MPU_xTaskNotifyWait + #define ulTaskNotifyTake MPU_ulTaskNotifyTake + #define xTaskNotifyStateClear MPU_xTaskNotifyStateClear + + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState + #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + + /* Map standard queue.h API functions to the MPU equivalents. */ + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueReceive MPU_xQueueReceive + #define xQueuePeek MPU_xQueuePeek + #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable + #define vQueueDelete MPU_vQueueDelete + #define xQueueCreateMutex MPU_xQueueCreateMutex + #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic + #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore + #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic + #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueGenericCreate MPU_xQueueGenericCreate + #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic + #define xQueueCreateSet MPU_xQueueCreateSet + #define xQueueAddToSet MPU_xQueueAddToSet + #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet + #define xQueueSelectFromSet MPU_xQueueSelectFromSet + #define xQueueGenericReset MPU_xQueueGenericReset + + #if( configQUEUE_REGISTRY_SIZE > 0 ) + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #define pcQueueGetName MPU_pcQueueGetName + #endif + + /* Map standard timer.h API functions to the MPU equivalents. */ + #define xTimerCreate MPU_xTimerCreate + #define xTimerCreateStatic MPU_xTimerCreateStatic + #define pvTimerGetTimerID MPU_pvTimerGetTimerID + #define vTimerSetTimerID MPU_vTimerSetTimerID + #define xTimerIsTimerActive MPU_xTimerIsTimerActive + #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle + #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall + #define pcTimerGetName MPU_pcTimerGetName + #define xTimerGetPeriod MPU_xTimerGetPeriod + #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime + #define xTimerGenericCommand MPU_xTimerGenericCommand + + /* Map standard event_group.h API functions to the MPU equivalents. */ + #define xEventGroupCreate MPU_xEventGroupCreate + #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic + #define xEventGroupWaitBits MPU_xEventGroupWaitBits + #define xEventGroupClearBits MPU_xEventGroupClearBits + #define xEventGroupSetBits MPU_xEventGroupSetBits + #define xEventGroupSync MPU_xEventGroupSync + #define vEventGroupDelete MPU_vEventGroupDelete + + /* Map standard message/stream_buffer.h API functions to the MPU + equivalents. */ + #define xStreamBufferSend MPU_xStreamBufferSend + #define xStreamBufferSendFromISR MPU_xStreamBufferSendFromISR + #define xStreamBufferReceive MPU_xStreamBufferReceive + #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes + #define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR + #define vStreamBufferDelete MPU_vStreamBufferDelete + #define xStreamBufferIsFull MPU_xStreamBufferIsFull + #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty + #define xStreamBufferReset MPU_xStreamBufferReset + #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable + #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable + #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel + #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate + #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic + + + /* Remove the privileged function macro, but keep the PRIVILEGED_DATA + macro so applications can place data in privileged access sections + (useful when using statically allocated objects). */ + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + + /* Ensure API functions go in the privileged execution section. */ + #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + + #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA + #define portUSING_MPU_WRAPPERS 0 + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ + diff --git a/include/rtos/freertos/portable.h b/include/rtos/freertos/portable.h new file mode 100644 index 0000000..15f0e65 --- /dev/null +++ b/include/rtos/freertos/portable.h @@ -0,0 +1,165 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/*----------------------------------------------------------- + * Portable layer API. Each function must be defined for each port. + *----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. +Purely for reasons of backward compatibility the old method is still valid, but +to make it clear that new projects should not use it, support for the port +specific constants has been moved into the deprecated_definitions.h header +file. */ +#include "deprecated_definitions.h" + +/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h +did not result in a portmacro.h header file being included - and it should be +included here. In this case the path to the correct portmacro.h header file +must be set in the compiler's include path. */ +#ifndef portENTER_CRITICAL + #include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 32 + #define portBYTE_ALIGNMENT_MASK ( 0x001f ) +#endif + +#if portBYTE_ALIGNMENT == 16 + #define portBYTE_ALIGNMENT_MASK ( 0x000f ) +#endif + +#if portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#endif + +#if portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#endif + +#if portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#endif + +#if portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#endif + +#ifndef portBYTE_ALIGNMENT_MASK + #error "Invalid portBYTE_ALIGNMENT definition" +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS + #define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mpu_wrappers.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; +#else + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; +#endif + +/* Used by heap_5.c. */ +typedef struct HeapRegion +{ + uint8_t *pucStartAddress; + size_t xSizeInBytes; +} HeapRegion_t; + +/* + * Used to define multiple heap regions for use by heap_5.c. This function + * must be called before any calls to pvPortMalloc() - not creating a task, + * queue, semaphore, mutex, software timer, event group, etc. will result in + * pvPortMalloc being called. + * + * pxHeapRegions passes in an array of HeapRegion_t structures - each of which + * defines a region of memory that can be used as the heap. The array is + * terminated by a HeapRegions_t structure that has a size of 0. The region + * with the lowest start address must appear first in the array. + */ +void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; + + +/* + * Map to the memory management routines required for the port. + */ +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void vPortFree( void *pv ) PRIVILEGED_FUNCTION; +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; +size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABLE_H */ + diff --git a/include/rtos/freertos/portmacro.h b/include/rtos/freertos/portmacro.h new file mode 100644 index 0000000..4da9166 --- /dev/null +++ b/include/rtos/freertos/portmacro.h @@ -0,0 +1,256 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 + +/* The max restore time for the hardware jump out from deep sleep */ +#define portMAX_RESTORE_TIME 6 +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +#define portYIELD() \ +{ \ + /* Set a PendSV to request a context switch. */ \ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ + \ + /* Barriers are normally not required but do ensure the code is completely \ + within the specified behaviour for the architecture. */ \ + __asm volatile( "dsb" ::: "memory" ); \ + __asm volatile( "isb" ); \ +} + +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) +#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() +#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) +//#define portDISABLE_INTERRUPTS() __disable_irq() +//#define portENABLE_INTERRUPTS() __enable_irq() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif + +#ifndef portTASK_IDLE_INIT + extern void vPortTaskIdleInit(void); +#define portTASK_IDLE_INIT vPortTaskIdleInit +#endif + +#ifndef portLIGHT_SLEEP +extern void vPortLightSleep( TickType_t ulExpectedIdleTime ); +#define portLIGHT_SLEEP(xExpectedIdleTime) vPortLightSleep(xExpectedIdleTime) +#endif + +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Generic helper function. */ + __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); + return ucReturn; + } + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) +#endif + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ +uint32_t ulCurrentInterrupt; +BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortRaiseBASEPRI( void ) +{ + + __asm volatile + ( + " msr basepri, %0 \n" \ + " isb \n" \ + " dsb \n" \ + : : "r" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" + ); +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) +{ +uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n" \ + " mov %1, %2 \n" \ + " msr basepri, %1 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return ulOriginalBASEPRI; +} +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) +{ + __asm volatile + ( + " msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/include/rtos/freertos/projdefs.h b/include/rtos/freertos/projdefs.h new file mode 100644 index 0000000..c862173 --- /dev/null +++ b/include/rtos/freertos/projdefs.h @@ -0,0 +1,124 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* + * Defines the prototype to which task functions must conform. Defined in this + * file to ensure the type is known before portable.h is included. + */ +typedef void (*TaskFunction_t)( void * ); + +/* Converts a time in milliseconds to a time in ticks. This macro can be +overridden by a macro of the same name defined in FreeRTOSConfig.h in case the +definition here is not suitable for your application. */ +#ifndef pdMS_TO_TICKS + #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) +#endif + +#define pdFALSE ( ( BaseType_t ) 0 ) +#define pdTRUE ( ( BaseType_t ) 1 ) + +#define pdPASS ( pdTRUE ) +#define pdFAIL ( pdFALSE ) +#define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) +#define errQUEUE_FULL ( ( BaseType_t ) 0 ) + +/* FreeRTOS error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +/* Macros used for basic data corruption checks. */ +#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES + #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 +#endif + +#if( configUSE_16_BIT_TICKS == 1 ) + #define pdINTEGRITY_CHECK_VALUE 0x5a5a +#else + #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL +#endif + +/* The following errno values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_ERRNO_NONE 0 /* No errors */ +#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ +#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ +#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ +#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ +#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ +#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ +#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ +#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ +#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ +#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ +#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ +#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ +#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ +#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ +#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ +#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ +#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ +#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ +#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ +#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ +#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ +#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ +#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ +#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ +#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ +#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ +#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ +#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ +#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ +#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ +#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ +#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ +#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ +#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ +#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ +#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ +#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ +#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ + +/* The following endian values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_LITTLE_ENDIAN 0 +#define pdFREERTOS_BIG_ENDIAN 1 + +/* Re-defining endian values for generic naming. */ +#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN +#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN + + +#endif /* PROJDEFS_H */ + + + diff --git a/include/rtos/freertos/queue.h b/include/rtos/freertos/queue.h new file mode 100644 index 0000000..1967cca --- /dev/null +++ b/include/rtos/freertos/queue.h @@ -0,0 +1,1655 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include queue.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "task.h" + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate() + * returns an QueueHandle_t variable that can then be used as a parameter to + * xQueueSend(), xQueueReceive(), etc. + */ +struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */ +typedef struct QueueDefinition * QueueHandle_t; + +/** + * Type by which queue sets are referenced. For example, a call to + * xQueueCreateSet() returns an xQueueSet variable that can then be used as a + * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. + */ +typedef struct QueueDefinition * QueueSetHandle_t; + +/** + * Queue sets can contain both queues and semaphores, so the + * QueueSetMemberHandle_t is defined as a type to be used where a parameter or + * return value can be either an QueueHandle_t or an SemaphoreHandle_t. + */ +typedef struct QueueDefinition * QueueSetMemberHandle_t; + +/* For internal use only. */ +#define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) +#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 ) +#define queueOVERWRITE ( ( BaseType_t ) 2 ) + +/* For internal use only. These definitions *must* match those in queue.c. */ +#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) + +/** + * queue. h + *
+ QueueHandle_t xQueueCreate(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+	if( xQueue1 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue2 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) ) +#endif + +/** + * queue. h + *
+ QueueHandle_t xQueueCreateStatic(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize,
+							  uint8_t *pucQueueStorageBuffer,
+							  StaticQueue_t *pxQueueBuffer
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @param pucQueueStorageBuffer If uxItemSize is not zero then + * pucQueueStorageBuffer must point to a uint8_t array that is at least large + * enough to hold the maximum number of items that can be in the queue at any + * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is + * zero then pucQueueStorageBuffer can be NULL. + * + * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which + * will be used to hold the queue's data structure. + * + * @return If the queue is created then a handle to the created queue is + * returned. If pxQueueBuffer is NULL then NULL is returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ #define QUEUE_LENGTH 10
+ #define ITEM_SIZE sizeof( uint32_t )
+
+ // xQueueBuffer will hold the queue structure.
+ StaticQueue_t xQueueBuffer;
+
+ // ucQueueStorage will hold the items posted to the queue.  Must be at least
+ // [(queue length) * ( queue item size)] bytes long.
+ uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold.
+							ITEM_SIZE	  // The size of each item in the queue
+							&( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
+							&xQueueBuffer ); // The buffer that will hold the queue structure.
+
+	// The queue is guaranteed to be created successfully as no dynamic memory
+	// allocation is used.  Therefore xQueue1 is now a handle to a valid queue.
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreateStatic xQueueCreateStatic + * \ingroup QueueManagement + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * queue. h + *
+ BaseType_t xQueueSendToToFront(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) + +/** + * queue. h + *
+ BaseType_t xQueueSendToBack(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueSend(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  TickType_t xTicksToWait
+						 );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwrite(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue
+						 );
+ * 
+ * + * Only for use with queues that have a length of one - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * This function must not be called from an interrupt service routine. + * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle of the queue to which the data is being sent. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and + * therefore has the same return values as xQueueSendToFront(). However, pdPASS + * is the only value that can be returned because xQueueOverwrite() will write + * to the queue even when the queue is already full. + * + * Example usage: +
+
+ void vFunction( void *pvParameters )
+ {
+ QueueHandle_t xQueue;
+ uint32_t ulVarToSend, ulValReceived;
+
+	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwrite() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+
+	// Write the value 10 to the queue using xQueueOverwrite().
+	ulVarToSend = 10;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// Peeking the queue should now return 10, but leave the value 10 in
+	// the queue.  A block time of zero is used as it is known that the
+	// queue holds a value.
+	ulValReceived = 0;
+	xQueuePeek( xQueue, &ulValReceived, 0 );
+
+	if( ulValReceived != 10 )
+	{
+		// Error unless the item was removed by a different task.
+	}
+
+	// The queue is still full.  Use xQueueOverwrite() to overwrite the
+	// value held in the queue with 100.
+	ulVarToSend = 100;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// This time read from the queue, leaving the queue empty once more.
+	// A block time of 0 is used again.
+	xQueueReceive( xQueue, &ulValReceived, 0 );
+
+	// The value read should be the last value written, even though the
+	// queue was already full when the value was written.
+	if( ulValReceived != 100 )
+	{
+		// Error!
+	}
+
+	// ...
+}
+ 
+ * \defgroup xQueueOverwrite xQueueOverwrite + * \ingroup QueueManagement + */ +#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) + + +/** + * queue. h + *
+ BaseType_t xQueueGenericSend(
+									QueueHandle_t xQueue,
+									const void * pvItemToQueue,
+									TickType_t xTicksToWait
+									BaseType_t xCopyPosition
+								);
+ * 
+ * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueuePeek(
+							 QueueHandle_t xQueue,
+							 void * const pvBuffer,
+							 TickType_t xTicksToWait
+						 );
+ * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. See + * xQueuePeekFromISR() for an alternative that can be called from an interrupt + * service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Peek a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask, but the item still remains on the queue.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueuePeek xQueuePeek + * \ingroup QueueManagement + */ +BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueuePeekFromISR(
+									QueueHandle_t xQueue,
+									void *pvBuffer,
+								);
+ * + * A version of xQueuePeek() that can be called from an interrupt service + * routine (ISR). + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * \defgroup xQueuePeekFromISR xQueuePeekFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceive(
+								 QueueHandle_t xQueue,
+								 void *pvBuffer,
+								 TickType_t xTicksToWait
+							);
+ * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_PERIOD_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
+ * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
+ * + * Return the number of free spaces available in a queue. This is equal to the + * number of items that can be sent to the queue before the queue becomes full + * if no items are removed. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of spaces available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
void vQueueDelete( QueueHandle_t xQueue );
+ * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \defgroup vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueSendToFrontFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPrioritTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) + + +/** + * queue. h + *
+ BaseType_t xQueueSendToBackFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwriteFromISR(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  BaseType_t *pxHigherPriorityTaskWoken
+						 );
+ * 
+ * + * A version of xQueueOverwrite() that can be used in an interrupt service + * routine (ISR). + * + * Only for use with queues that can hold a single item - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return xQueueOverwriteFromISR() is a macro that calls + * xQueueGenericSendFromISR(), and therefore has the same return values as + * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be + * returned because xQueueOverwriteFromISR() will write to the queue even when + * the queue is already full. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ void vFunction( void *pvParameters )
+ {
+ 	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwriteFromISR() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+}
+
+void vAnInterruptHandler( void )
+{
+// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+uint32_t ulVarToSend, ulValReceived;
+
+	// Write the value 10 to the queue using xQueueOverwriteFromISR().
+	ulVarToSend = 10;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// The queue is full, but calling xQueueOverwriteFromISR() again will still
+	// pass because the value held in the queue will be overwritten with the
+	// new value.
+	ulVarToSend = 100;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// Reading from the queue will now return 100.
+
+	// ...
+
+	if( xHigherPrioritytaskWoken == pdTRUE )
+	{
+		// Writing to the queue caused a task to unblock and the unblocked task
+		// has a priority higher than or equal to the priority of the currently
+		// executing task (the task this interrupt interrupted).  Perform a context
+		// switch so this interrupt returns directly to the unblocked task.
+		portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
+	}
+}
+ 
+ * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR + * \ingroup QueueManagement + */ +#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) + +/** + * queue. h + *
+ BaseType_t xQueueSendFromISR(
+									 QueueHandle_t xQueue,
+									 const void *pvItemToQueue,
+									 BaseType_t *pxHigherPriorityTaskWoken
+								);
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		// Actual macro used here is port specific.
+		portYIELD_FROM_ISR ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueGenericSendFromISR(
+										   QueueHandle_t		xQueue,
+										   const	void	*pvItemToQueue,
+										   BaseType_t	*pxHigherPriorityTaskWoken,
+										   BaseType_t	xCopyPosition
+									   );
+ 
+ * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. xQueueGiveFromISR() is an + * equivalent for use by semaphores that don't actually copy any data. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWokenByPost;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWokenByPost = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post each byte.
+		xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.  Note that the
+	// name of the yield function required is port specific.
+	if( xHigherPriorityTaskWokenByPost )
+	{
+		taskYIELD_YIELD_FROM_ISR();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceiveFromISR(
+									   QueueHandle_t	xQueue,
+									   void	*pvBuffer,
+									   BaseType_t *pxTaskWoken
+								   );
+ * 
+ * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxTaskWoken A task may be blocked waiting for space to become + * available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const TickType_t xTicksToWait = ( TickType_t )0xff;
+
+	// Create a queue capable of containing 10 characters.
+	xQueue = xQueueCreate( 10, sizeof( char ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Post some characters that will be used within an ISR.  If the queue
+	// is full then this task will block for xTicksToWait ticks.
+	cValueToPost = 'a';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+	cValueToPost = 'b';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+
+	// ... keep posting characters ... this task may block when the queue
+	// becomes full.
+
+	cValueToPost = 'c';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ BaseType_t xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+	while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+	{
+		// A character was received.  Output the character now.
+		vOutputCharacter( cRxedChar );
+
+		// If removing the character from the queue woke the task that was
+		// posting onto the queue cTaskWokenByReceive will have been set to
+		// pdTRUE.  No matter how many times this loop iterates only one
+		// task will be woken.
+	}
+
+	if( cTaskWokenByPost != ( char ) pdFALSE;
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* + * Utilities to query queues that are safe to use from an ISR. These utilities + * should be used only from witin an ISR, or within a critical section. + */ +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ); +BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken ); +BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ); +BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ); + +/* + * For internal use only. Use xSemaphoreCreateMutex(), + * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling + * these functions directly. + */ +QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; + +/* + * Reset a queue back to its original empty state. The return value is now + * obsolete and is always set to pdPASS. + */ +#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE ) + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not effect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. The queue registry only + * stores a pointer to the string - so the string must be persistent (global or + * preferably in ROM/Flash), not on the stack. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to + * remove the queue, semaphore or mutex from the register. If you are not using + * a kernel aware debugger then this function can be ignored. + * + * @param xQueue The handle of the queue being removed from the registry. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +#endif + +/* + * The queue registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call pcQueueGetName() to look + * up and return the name of a queue in the queue registry from the queue's + * handle. + * + * @param xQueue The handle of the queue the name of which will be returned. + * @return If the queue is in the registry then a pointer to the name of the + * queue is returned. If the queue is not in the registry then NULL is + * returned. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + const char *pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * before it can be used. Once created, standard FreeRTOS queues and semaphores + * can be added to the set using calls to xQueueAddToSet(). + * xQueueSelectFromSet() is then used to determine which, if any, of the queues + * or semaphores contained in the set is in a state where a queue read or + * semaphore take operation would be successful. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. Otherwise NULL is returned. + */ +QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; + +/* + * Adds a queue or semaphore to a queue set that was previously created by a + * call to xQueueCreateSet(). + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being added to + * the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set to which the queue or semaphore + * is being added. + * + * @return If the queue or semaphore was successfully added to the queue set + * then pdPASS is returned. If the queue could not be successfully added to the + * queue set because it is already a member of a different queue set then pdFAIL + * is returned. + */ +BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * Removes a queue or semaphore from a queue set. A queue or semaphore can only + * be removed from a set if the queue or semaphore is empty. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being removed + * from the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set in which the queue or semaphore + * is included. + * + * @return If the queue or semaphore was successfully removed from the queue set + * then pdPASS is returned. If the queue was not in the queue set, or the + * queue (or semaphore) was not empty, then pdFAIL is returned. + */ +BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * xQueueSelectFromSet() selects from the members of a queue set a queue or + * semaphore that either contains data (in the case of a queue) or is available + * to take (in the case of a semaphore). xQueueSelectFromSet() effectively + * allows a task to block (pend) on a read operation on all the queues and + * semaphores in a queue set simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueSet The queue set on which the task will (potentially) block. + * + * @param xTicksToWait The maximum time, in ticks, that the calling task will + * remain in the Blocked state (with other tasks executing) to wait for a member + * of the queue set to be ready for a successful queue read or semaphore take + * operation. + * + * @return xQueueSelectFromSet() will return the handle of a queue (cast to + * a QueueSetMemberHandle_t type) contained in the queue set that contains data, + * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained + * in the queue set that is available, or NULL if no such queue or semaphore + * exists before before the specified block time expires. + */ +QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * A version of xQueueSelectFromSet() that can be used from an ISR. + */ +QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* Not public API functions. */ +void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; +void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + diff --git a/include/rtos/freertos/semphr.h b/include/rtos/freertos/semphr.h new file mode 100644 index 0000000..53b158a --- /dev/null +++ b/include/rtos/freertos/semphr.h @@ -0,0 +1,1140 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include semphr.h" +#endif + +#include "queue.h" + +typedef QueueHandle_t SemaphoreHandle_t; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) +#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + + +/** + * semphr. h + *
vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
+ * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define vSemaphoreCreateBinary( xSemaphore ) \ + { \ + ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + ( void ) xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinary( void )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @return Handle to the created semaphore, or NULL if the memory required to + * hold the semaphore's data structures could not be allocated. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * NOTE: In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the semaphore is created then a handle to the created semaphore is + * returned. If pxSemaphoreBuffer is NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // The semaphore's data structures will be placed in the xSemaphoreBuffer
+    // variable, the address of which is passed into the function.  The
+    // function's parameter is not NULL, so the function will not attempt any
+    // dynamic memory allocation, and therefore the function will not return
+    // return NULL.
+    xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
+
+    // Rest of task code goes here.
+ }
+ 
+ * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
xSemaphoreTake(
+ *                   SemaphoreHandle_t xSemaphore,
+ *                   TickType_t xBlockTime
+ *               )
+ * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    xSemaphore = xSemaphoreCreateBinary();
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xSemaphore != NULL )
+    {
+        // See if we can obtain the semaphore.  If the semaphore is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the semaphore and can now access the
+            // shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource.  Release the
+            // semaphore.
+            xSemaphoreGive( xSemaphore );
+        }
+        else
+        {
+            // We could not obtain the semaphore and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) + +/** + * semphr. h + * xSemaphoreTakeRecursive( + * SemaphoreHandle_t xMutex, + * TickType_t xBlockTime + * ) + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+            // xSemaphoreTakeRecursive() are made on the same mutex.  In real
+            // code these would not be just sequential calls as this would make
+            // no sense.  Instead the calls are likely to be buried inside
+            // a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+            // available to another task until it has also been given back
+            // three times.  Again it is unlikely that real code would have
+            // these calls sequentially, but instead buried in a more complex
+            // call structure.  This is just for illustrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+
+            // Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) +#endif + +/** + * semphr. h + *
xSemaphoreGive( SemaphoreHandle_t xSemaphore )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    xSemaphore = vSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+        {
+            // We would expect this call to fail because we cannot give
+            // a semaphore without first "taking" it!
+        }
+
+        // Obtain the semaphore - don't block if the semaphore is not
+        // immediately available.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
+        {
+            // We now have the semaphore and can access the shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource so can free the
+            // semaphore.
+            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+            {
+                // We would not expect this call to fail because we must have
+                // obtained the semaphore to get here.
+            }
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )
+ * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, it would be more likely that the calls
+			// to xSemaphoreGiveRecursive() would be called as a call stack
+			// unwound.  This is just for demonstrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) +#endif + +/** + * semphr. h + *
+ xSemaphoreGiveFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: +
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT	10
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+    for( ;; )
+    {
+        // We want this task to run every 10 ticks of a timer.  The semaphore
+        // was created before this task was started.
+
+        // Block waiting for the semaphore to become available.
+        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+        {
+            // It is time to execute.
+
+            // ...
+
+            // We have finished our task.  Return to the top of the loop where
+            // we will block on the semaphore until it is time to execute
+            // again.  Note when using the semaphore for synchronisation with an
+			// ISR in this manner there is no need to 'give' the semaphore back.
+        }
+    }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static uint8_t ucLocalTickCount = 0;
+ static BaseType_t xHigherPriorityTaskWoken;
+
+    // A timer tick has occurred.
+
+    // ... Do other time functions.
+
+    // Is it time for vATask () to run?
+	xHigherPriorityTaskWoken = pdFALSE;
+    ucLocalTickCount++;
+    if( ucLocalTickCount >= TICKS_TO_WAIT )
+    {
+        // Unblock the task by releasing the semaphore.
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+        // Reset the count so we release the semaphore again in 10 ticks time.
+        ucLocalTickCount = 0;
+    }
+
+    if( xHigherPriorityTaskWoken != pdFALSE )
+    {
+        // We can force a context switch here.  Context switching from an
+        // ISR uses port specific syntax.  Check the demo task for your port
+        // to find the syntax required.
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
+ xSemaphoreTakeFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to take a semaphore from an ISR. The semaphore must have + * previously been created with a call to xSemaphoreCreateBinary() or + * xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR, however taking a semaphore from an ISR + * is not a common operation. It is likely to only be useful when taking a + * counting semaphore when an interrupt is obtaining an object from a resource + * pool (when the semaphore count indicates the number of resources available). + * + * @param xSemaphore A handle to the semaphore being taken. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully taken, otherwise + * pdFALSE + */ +#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutex( void )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return If the mutex was successfully created then a handle to the created + * semaphore is returned. If there was not enough heap to allocate the mutex + * data structures then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will be used to hold the mutex's data structure, removing the need for + * the memory to be allocated dynamically. + * + * @return If the mutex was successfully created then a handle to the created + * mutex is returned. If pxMutexBuffer was NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A mutex cannot be used before it has been created.  xMutexBuffer is
+    // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
+    // attempted.
+    xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic + * \ingroup Semaphores + */ + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex + * \ingroup Semaphores + */ +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the recursive mutex's data structure, + * removing the need for the memory to be allocated dynamically. + * + * @return If the recursive mutex was successfully created then a handle to the + * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is + * returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A recursive semaphore cannot be used before it is created.  Here a
+    // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
+    // The address of xMutexBuffer is passed into the function, and will hold
+    // the mutexes data structures - so no dynamic memory allocation will be
+    // attempted.
+    xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic + * \ingroup Semaphores + */ +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer can + * instead optionally provide the memory that will get used by the counting + * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting + * semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+    // The max value to which the semaphore can count should be 10, and the
+    // initial value assigned to the count should be 0.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer must + * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a + * counting semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the counting semaphore was successfully created then a handle to + * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL + * then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Counting semaphore cannot be used before they have been created.  Create
+    // a counting semaphore using xSemaphoreCreateCountingStatic().  The max
+    // value to which the semaphore can count is 10, and the initial value
+    // assigned to the count will be 0.  The address of xSemaphoreBuffer is
+    // passed in and will be used to hold the semaphore structure, so no dynamic
+    // memory allocation will be used.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
+
+    // No memory allocation was attempted so xSemaphore cannot be NULL, so there
+    // is no need to check its value.
+ }
+ 
+ * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
+ * + * Delete a semaphore. This function must be used with care. For example, + * do not delete a mutex type semaphore if the mutex is held by a task. + * + * @param xSemaphore A handle to the semaphore to be deleted. + * + * \defgroup vSemaphoreDelete vSemaphoreDelete + * \ingroup Semaphores + */ +#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) + +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + * Note: This is a good way of determining if the calling task is the mutex + * holder, but not a good way of determining the identity of the mutex holder as + * the holder may change between the function exiting and the returned value + * being tested. + */ +#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) + +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + */ +#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) + +/** + * semphr.h + *
UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
+ * + * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns + * its current count value. If the semaphore is a binary semaphore then + * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the + * semaphore is not available. + * + */ +#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) ) + +#endif /* SEMAPHORE_H */ + + diff --git a/include/rtos/freertos/stack_macros.h b/include/rtos/freertos/stack_macros.h new file mode 100644 index 0000000..673ef6d --- /dev/null +++ b/include/rtos/freertos/stack_macros.h @@ -0,0 +1,129 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ + const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ + \ + if( ( pulStack[ 0 ] != ulCheckValue ) || \ + ( pulStack[ 1 ] != ulCheckValue ) || \ + ( pulStack[ 2 ] != ulCheckValue ) || \ + ( pulStack[ 3 ] != ulCheckValue ) ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ + static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +/* Remove stack overflow macro if not being used. */ +#ifndef taskCHECK_FOR_STACK_OVERFLOW + #define taskCHECK_FOR_STACK_OVERFLOW() +#endif + + + +#endif /* STACK_MACROS_H */ + diff --git a/include/rtos/freertos/stdint.readme b/include/rtos/freertos/stdint.readme new file mode 100644 index 0000000..4414c29 --- /dev/null +++ b/include/rtos/freertos/stdint.readme @@ -0,0 +1,27 @@ + +#ifndef FREERTOS_STDINT +#define FREERTOS_STDINT + +/******************************************************************************* + * THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions + * necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be + * built using compilers that do not provide their own stdint.h definition. + * + * To use this file: + * + * 1) Copy this file into the directory that contains your FreeRTOSConfig.h + * header file, as that directory will already be in the compilers include + * path. + * + * 2) Rename the copied file stdint.h. + * + */ + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef long int32_t; +typedef unsigned long uint32_t; + +#endif /* FREERTOS_STDINT */ diff --git a/include/rtos/freertos/stream_buffer.h b/include/rtos/freertos/stream_buffer.h new file mode 100644 index 0000000..6619fe0 --- /dev/null +++ b/include/rtos/freertos/stream_buffer.h @@ -0,0 +1,855 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * Stream buffers are used to send a continuous stream of data from one task or + * interrupt to another. Their implementation is light weight, making them + * particularly suited for interrupt to task and core to core communication + * scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section section and set the + * receive block time to 0. + * + */ + +#ifndef STREAM_BUFFER_H +#define STREAM_BUFFER_H + +#if defined( __cplusplus ) +extern "C" { +#endif + +/** + * Type by which stream buffers are referenced. For example, a call to + * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can + * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(), + * etc. + */ +struct StreamBufferDef_t; +typedef struct StreamBufferDef_t * StreamBufferHandle_t; + + +/** + * message_buffer.h + * +
+StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
+
+ * + * Creates a new stream buffer using dynamically allocated memory. See + * xStreamBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xStreamBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes the stream buffer will be + * able to hold at any one time. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @return If NULL is returned, then the stream buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the stream buffer data structures and storage area. A non-NULL value being + * returned indicates that the stream buffer has been created successfully - + * the returned value should be stored as the handle to the created stream + * buffer. + * + * Example use: +
+
+void vAFunction( void )
+{
+StreamBufferHandle_t xStreamBuffer;
+const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
+
+    // Create a stream buffer that can hold 100 bytes.  The memory used to hold
+    // both the stream buffer structure and the data in the stream buffer is
+    // allocated dynamically.
+    xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
+
+    if( xStreamBuffer == NULL )
+    {
+        // There was not enough heap memory space available to create the
+        // stream buffer.
+    }
+    else
+    {
+        // The stream buffer was created successfully and can now be used.
+    }
+}
+
+ * \defgroup xStreamBufferCreate xStreamBufferCreate + * \ingroup StreamBufferManagement + */ +#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE ) + +/** + * stream_buffer.h + * +
+StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
+                                                size_t xTriggerLevelBytes,
+                                                uint8_t *pucStreamBufferStorageArea,
+                                                StaticStreamBuffer_t *pxStaticStreamBuffer );
+
+ * Creates a new stream buffer using statically allocated memory. See + * xStreamBufferCreate() for a version that uses dynamically allocated memory. + * + * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for + * xStreamBufferCreateStatic() to be available. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucStreamBufferStorageArea parameter. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes + 1 big. This is the array to which streams are + * copied when they are written to the stream buffer. + * + * @param pxStaticStreamBuffer Must point to a variable of type + * StaticStreamBuffer_t, which will be used to hold the stream buffer's data + * structure. + * + * @return If the stream buffer is created successfully then a handle to the + * created stream buffer is returned. If either pucStreamBufferStorageArea or + * pxStaticstreamBuffer are NULL then NULL is returned. + * + * Example use: +
+
+// Used to dimension the array used to hold the streams.  The available space
+// will actually be one less than this, so 999.
+#define STORAGE_SIZE_BYTES 1000
+
+// Defines the memory that will actually hold the streams within the stream
+// buffer.
+static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
+
+// The variable used to hold the stream buffer structure.
+StaticStreamBuffer_t xStreamBufferStruct;
+
+void MyFunction( void )
+{
+StreamBufferHandle_t xStreamBuffer;
+const size_t xTriggerLevel = 1;
+
+    xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
+                                               xTriggerLevel,
+                                               ucBufferStorage,
+                                               &xStreamBufferStruct );
+
+    // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
+    // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
+    // reference the created stream buffer in other stream buffer API calls.
+
+    // Other code that uses the stream buffer can go here.
+}
+
+
+ * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic + * \ingroup StreamBufferManagement + */ +#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer ) + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
+                          const void *pvTxData,
+                          size_t xDataLengthBytes,
+                          TickType_t xTicksToWait );
+
+ * + * Sends bytes to a stream buffer. The bytes are copied into the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the buffer that holds the bytes to be copied + * into the stream buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for enough space to become available in the stream + * buffer, should the stream buffer contain too little space to hold the + * another xDataLengthBytes bytes. The block time is specified in tick periods, + * so the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out + * before it can write all xDataLengthBytes into the buffer it will still write + * as many bytes as possible. A task does not use any CPU time when it is in + * the blocked state. + * + * @return The number of bytes written to the stream buffer. If a task times + * out before it can write all xDataLengthBytes into the buffer it will still + * write as many bytes as possible. + * + * Example use: +
+void vAFunction( StreamBufferHandle_t xStreamBuffer )
+{
+size_t xBytesSent;
+uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
+char *pcStringToSend = "String to send";
+const TickType_t x100ms = pdMS_TO_TICKS( 100 );
+
+    // Send an array to the stream buffer, blocking for a maximum of 100ms to
+    // wait for enough space to be available in the stream buffer.
+    xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
+
+    if( xBytesSent != sizeof( ucArrayToSend ) )
+    {
+        // The call to xStreamBufferSend() times out before there was enough
+        // space in the buffer for the data to be written, but it did
+        // successfully write xBytesSent bytes.
+    }
+
+    // Send the string to the stream buffer.  Return immediately if there is not
+    // enough space in the buffer.
+    xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The entire string could not be added to the stream buffer because
+        // there was not enough free space in the buffer, but xBytesSent bytes
+        // were sent.  Could try again to send the remaining bytes.
+    }
+}
+
+ * \defgroup xStreamBufferSend xStreamBufferSend + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
+                                 const void *pvTxData,
+                                 size_t xDataLengthBytes,
+                                 BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * Interrupt safe version of the API function that sends a stream of bytes to + * the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the data that is to be copied into the stream + * buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for data. Calling + * xStreamBufferSendFromISR() can make data available, and so cause a task that + * was waiting for data to leave the Blocked state. If calling + * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the + * unblocked task has a priority higher than the currently executing task (the + * task that was interrupted), then, internally, xStreamBufferSendFromISR() + * will set *pxHigherPriorityTaskWoken to pdTRUE. If + * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. This will + * ensure that the interrupt returns directly to the highest priority Ready + * state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it + * is passed into the function. See the example code below for an example. + * + * @return The number of bytes actually written to the stream buffer, which will + * be less than xDataLengthBytes if the stream buffer didn't have enough free + * space for all the bytes to be written. + * + * Example use: +
+// A stream buffer that has already been created.
+StreamBufferHandle_t xStreamBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+size_t xBytesSent;
+char *pcStringToSend = "String to send";
+BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
+
+    // Attempt to send the string to the stream buffer.
+    xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
+                                           ( void * ) pcStringToSend,
+                                           strlen( pcStringToSend ),
+                                           &xHigherPriorityTaskWoken );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // There was not enough free space in the stream buffer for the entire
+        // string to be written, ut xBytesSent bytes were written.
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xStreamBufferSendFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
+                             void *pvRxData,
+                             size_t xBufferLengthBytes,
+                             TickType_t xTicksToWait );
+
+ * + * Receives bytes from a stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferReceive() to read from a stream buffer from a task. Use + * xStreamBufferReceiveFromISR() to read from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which bytes are to + * be received. + * + * @param pvRxData A pointer to the buffer into which the received bytes will be + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for data to become available if the stream buffer is + * empty. xStreamBufferReceive() will return immediately if xTicksToWait is + * zero. The block time is specified in tick periods, so the absolute time it + * represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can + * be used to convert a time specified in milliseconds into a time specified in + * ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait + * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 + * in FreeRTOSConfig.h. A task does not use any CPU time when it is in the + * Blocked state. + * + * @return The number of bytes actually read from the stream buffer, which will + * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed + * out before xBufferLengthBytes were available. + * + * Example use: +
+void vAFunction( StreamBuffer_t xStreamBuffer )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
+
+    // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
+    // Wait in the Blocked state (so not using any CPU processing time) for a
+    // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
+    // available.
+    xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
+                                           ( void * ) ucRxData,
+                                           sizeof( ucRxData ),
+                                           xBlockTime );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains another xRecievedBytes bytes of data, which can
+        // be processed here....
+    }
+}
+
+ * \defgroup xStreamBufferReceive xStreamBufferReceive + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
+                                    void *pvRxData,
+                                    size_t xBufferLengthBytes,
+                                    BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * An interrupt safe version of the API function that receives bytes from a + * stream buffer. + * + * Use xStreamBufferReceive() to read bytes from a stream buffer from a task. + * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which a stream + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received bytes are + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for space to become available. Calling + * xStreamBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The number of bytes read from the stream buffer, if any. + * + * Example use: +
+// A stream buffer that has already been created.
+StreamBuffer_t xStreamBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
+
+    // Receive the next stream from the stream buffer.
+    xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
+                                                  ( void * ) ucRxData,
+                                                  sizeof( ucRxData ),
+                                                  &xHigherPriorityTaskWoken );
+
+    if( xReceivedBytes > 0 )
+    {
+        // ucRxData contains xReceivedBytes read from the stream buffer.
+        // Process the stream here....
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xStreamBufferReceiveFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Deletes a stream buffer that was previously created using a call to + * xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream + * buffer was created using dynamic memory (that is, by xStreamBufferCreate()), + * then the allocated memory is freed. + * + * A stream buffer handle must not be used after the stream buffer has been + * deleted. + * + * @param xStreamBuffer The handle of the stream buffer to be deleted. + * + * \defgroup vStreamBufferDelete vStreamBufferDelete + * \ingroup StreamBufferManagement + */ +void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see if it is full. A stream buffer is full if it + * does not have any free space, and therefore cannot accept any more data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is full then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsFull xStreamBufferIsFull + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see if it is empty. A stream buffer is empty if + * it does not contain any data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is empty then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Resets a stream buffer to its initial, empty, state. Any data that was in + * the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream + * buffer. + * + * @param xStreamBuffer The handle of the stream buffer being reset. + * + * @return If the stream buffer is reset then pdPASS is returned. If there was + * a task blocked waiting to send to or read from the stream buffer then the + * stream buffer is not reset and pdFAIL is returned. + * + * \defgroup xStreamBufferReset xStreamBufferReset + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see how much free space it contains, which is + * equal to the amount of data that can be sent to the stream buffer before it + * is full. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be written to the stream buffer before + * the stream buffer would be full. + * + * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see how much data it contains, which is equal to + * the number of bytes that can be read from the stream buffer before the stream + * buffer would be empty. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be read from the stream buffer before + * the stream buffer would be empty. + * + * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
+
+ * + * A stream buffer's trigger level is the number of bytes that must be in the + * stream buffer before a task that is blocked on the stream buffer to + * wait for data is moved out of the blocked state. For example, if a task is + * blocked on a read of an empty stream buffer that has a trigger level of 1 + * then the task will be unblocked when a single byte is written to the buffer + * or the task's block time expires. As another example, if a task is blocked + * on a read of an empty stream buffer that has a trigger level of 10 then the + * task will not be unblocked until the stream buffer contains at least 10 bytes + * or the task's block time expires. If a reading task's block time expires + * before the trigger level is reached then the task will still receive however + * many bytes are actually available. Setting a trigger level of 0 will result + * in a trigger level of 1 being used. It is not valid to specify a trigger + * level that is greater than the buffer size. + * + * A trigger level is set when the stream buffer is created, and can be modified + * using xStreamBufferSetTriggerLevel(). + * + * @param xStreamBuffer The handle of the stream buffer being updated. + * + * @param xTriggerLevel The new trigger level for the stream buffer. + * + * @return If xTriggerLevel was less than or equal to the stream buffer's length + * then the trigger level will be updated and pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xStreamBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferSendCompletedFromISR(). If calling + * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferReceiveCompletedFromISR(). If calling + * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* Functions below here are not part of the public API. */ +StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION; + +StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION; + +size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +#if( configUSE_TRACE_FACILITY == 1 ) + void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION; + UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; +#endif + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( STREAM_BUFFER_H ) */ diff --git a/include/rtos/freertos/task.h b/include/rtos/freertos/task.h new file mode 100644 index 0000000..9b43e0b --- /dev/null +++ b/include/rtos/freertos/task.h @@ -0,0 +1,2340 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef INC_TASK_H +#define INC_TASK_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include task.h" +#endif + +#include "freertos_list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V10.1.1" +#define tskKERNEL_VERSION_MAJOR 10 +#define tskKERNEL_VERSION_MINOR 1 +#define tskKERNEL_VERSION_BUILD 1 + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an TaskHandle_t variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \defgroup TaskHandle_t TaskHandle_t + * \ingroup Tasks + */ +struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tskTaskControlBlock* TaskHandle_t; + +/* + * Defines the prototype to which the application task hook function must + * conform. + */ +typedef BaseType_t (*TaskHookFunction_t)( void * ); + +/* Task states returned by eTaskGetState. */ +typedef enum +{ + eRunning = 0, /* A task is querying the state of itself, so must be running. */ + eReady, /* The task being queried is in a read or pending ready list. */ + eBlocked, /* The task being queried is in the Blocked state. */ + eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ + eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */ + eInvalid /* Used as an 'invalid state' value. */ +} eTaskState; + +/* Actions that can be performed when vTaskNotify() is called. */ +typedef enum +{ + eNoAction = 0, /* Notify the task without updating its notify value. */ + eSetBits, /* Set bits in the task's notification value. */ + eIncrement, /* Increment the task's notification value. */ + eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */ + eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ +} eNotifyAction; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + BaseType_t xOverflowCount; + TickType_t xTimeOnEntering; +} TimeOut_t; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + uint32_t ulLengthInBytes; + uint32_t ulParameters; +} MemoryRegion_t; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMETERS +{ + TaskFunction_t pvTaskCode; + const char * const pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + uint16_t usStackDepth; + void *pvParameters; + UBaseType_t uxPriority; + StackType_t *puxStackBuffer; + MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; + #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + StaticTask_t * const pxTaskBuffer; + #endif +} TaskParameters_t; + +/* Used with the uxTaskGetSystemState() function to return the state of each task +in the system. */ +typedef struct xTASK_STATUS +{ + TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ + const char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + UBaseType_t xTaskNumber; /* A number unique to the task. */ + eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ + UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ + UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ + uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ + StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */ + configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ +} TaskStatus_t; + +/* Possible return values for eTaskConfirmSleepModeStatus(). */ +typedef enum +{ + eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ + eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ + eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ +} eSleepModeStatus; + +/** + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \defgroup taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() +#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() +#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is +0 to generate more optimal code when configASSERT() is defined as the constant +is used in assert() statements. */ +#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 ) +#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 ) +#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) + + +/*----------------------------------------------------------- + * TASK CREATION API + *----------------------------------------------------------*/ + +/** + * task. h + *
+ BaseType_t xTaskCreate(
+							  TaskFunction_t pvTaskCode,
+							  const char * const pcName,
+							  configSTACK_DEPTH_TYPE usStackDepth,
+							  void *pvParameters,
+							  UBaseType_t uxPriority,
+							  TaskHandle_t *pvCreatedTask
+						  );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * See xTaskCreateStatic() for a version that does not use any dynamic memory + * allocation. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pvCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+	 }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static uint8_t ucParameterToPass;
+ TaskHandle_t xHandle = NULL;
+
+	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+	 // the new task attempts to access it.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+     configASSERT( xHandle );
+
+	 // Use the handle to delete the task.
+     if( xHandle != NULL )
+     {
+	     vTaskDelete( xHandle );
+     }
+ }
+   
+ * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ TaskHandle_t xTaskCreateStatic( TaskFunction_t pvTaskCode,
+								 const char * const pcName,
+								 uint32_t ulStackDepth,
+								 void *pvParameters,
+								 UBaseType_t uxPriority,
+								 StackType_t *pxStackBuffer,
+								 StaticTask_t *pxTaskBuffer );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. The maximum length of the string is defined by + * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. + * + * @param ulStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task will run. + * + * @param pxStackBuffer Must point to a StackType_t array that has at least + * ulStackDepth indexes - the array will then be used as the task's stack, + * removing the need for the stack to be allocated dynamically. + * + * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will + * then be used to hold the task's data structures, removing the need for the + * memory to be allocated dynamically. + * + * @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will + * be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer + * are NULL then the task will not be created and + * errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned. + * + * Example usage: +
+
+    // Dimensions the buffer that the task being created will use as its stack.
+    // NOTE:  This is the number of words the stack will hold, not the number of
+    // bytes.  For example, if each stack item is 32-bits, and this is set to 100,
+    // then 400 bytes (100 * 32-bits) will be allocated.
+    #define STACK_SIZE 200
+
+    // Structure that will hold the TCB of the task being created.
+    StaticTask_t xTaskBuffer;
+
+    // Buffer that the task being created will use as its stack.  Note this is
+    // an array of StackType_t variables.  The size of StackType_t is dependent on
+    // the RTOS port.
+    StackType_t xStack[ STACK_SIZE ];
+
+    // Function that implements the task being created.
+    void vTaskCode( void * pvParameters )
+    {
+        // The parameter value is expected to be 1 as 1 is passed in the
+        // pvParameters value in the call to xTaskCreateStatic().
+        configASSERT( ( uint32_t ) pvParameters == 1UL );
+
+        for( ;; )
+        {
+            // Task code goes here.
+        }
+    }
+
+    // Function that creates a task.
+    void vOtherFunction( void )
+    {
+        TaskHandle_t xHandle = NULL;
+
+        // Create the task without using any dynamic memory allocation.
+        xHandle = xTaskCreateStatic(
+                      vTaskCode,       // Function that implements the task.
+                      "NAME",          // Text name for the task.
+                      STACK_SIZE,      // Stack size in words, not bytes.
+                      ( void * ) 1,    // Parameter passed into the task.
+                      tskIDLE_PRIORITY,// Priority at which the task is created.
+                      xStack,          // Array to use as the task's stack.
+                      &xTaskBuffer );  // Variable to hold the task's data structure.
+
+        // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
+        // been created, and xHandle will be the task's handle.  Use the handle
+        // to suspend the task.
+        vTaskSuspend( xHandle );
+    }
+   
+ * \defgroup xTaskCreateStatic xTaskCreateStatic + * \ingroup Tasks + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * task. h + *
+ BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ * + * Only available when configSUPPORT_DYNAMIC_ALLOCATION is set to 1. + * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * See xTaskCreateRestrictedStatic() for a version that does not use any + * dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+// Create an TaskParameters_t structure that defines the task to be created.
+static const TaskParameters_t xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// and/or timer task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ * + * Only available when configSUPPORT_STATIC_ALLOCATION is set to 1. + * + * xTaskCreateRestrictedStatic() should only be used in systems that include an + * MPU implementation. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreateRestricted() then the stack is provided by the application writer, + * and the memory used to hold the task's data structure is automatically + * dynamically allocated inside the xTaskCreateRestricted() function. If a task + * is created using xTaskCreateRestrictedStatic() then the application writer + * must provide the memory used to hold the task's data structures too. + * xTaskCreateRestrictedStatic() therefore allows a memory protected task to be + * created without using any dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. If configSUPPORT_STATIC_ALLOCATION is set to 1 the structure + * contains an additional member, which is used to point to a variable of type + * StaticTask_t - which is then used to hold the task's data structure. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+// Create an TaskParameters_t structure that defines the task to be created.
+// The StaticTask_t variable is only included in the structure when
+// configSUPPORT_STATIC_ALLOCATION is set to 1.  The PRIVILEGED_DATA macro can
+// be used to force the variable into the RTOS kernel's privileged data area.
+static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
+static const TaskParameters_t xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+
+	&xTaskBuffer; // Holds the task's data structure.
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// and/or timer task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic + * \ingroup Tasks + */ +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
+ * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an MemoryRegion_t structure that contains the + * new memory region definitions. + * + * Example usage: +
+// Define an array of MemoryRegion_t structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{
+	// Base address		Length		Parameters
+	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
+	{ 0,				0,			0 },
+	{ 0,				0,			0 }
+};
+
+void vATask( void *pvParameters )
+{
+	// This task was created such that it has access to certain regions of
+	// memory as defined by the MPU configuration.  At some point it is
+	// desired that these MPU regions are replaced with that defined in the
+	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+	// for this purpose.  NULL is used as the task handle to indicate that this
+	// function should modify the MPU regions of the calling task.
+	vTaskAllocateMPURegions( NULL, xAltRegions );
+
+	// Now the task can continue its function, but from this point on can only
+	// access its stack and the ucOneKByte array (unless any other statically
+	// defined or shared regions have been declared elsewhere).
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelete( TaskHandle_t xTask );
+ * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param xTask The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: +
+ void vOtherFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create the task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK CONTROL API + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskDelay( const TickType_t xTicksToDelay );
+ * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a periodic task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + + void vTaskFunction( void * pvParameters ) + { + // Block for 500ms. + const TickType_t xDelay = 500 / portTICK_PERIOD_MS; + + for( ;; ) + { + // Simply toggle the LED every 500ms, blocking between each toggle. + vToggleLED(); + vTaskDelay( xDelay ); + } + } + + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );
+ * + * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by periodic + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The constant portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within vTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * Example usage: +
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ TickType_t xLastWakeTime;
+ const TickType_t xFrequency = 10;
+
+	 // Initialise the xLastWakeTime variable with the current time.
+	 xLastWakeTime = xTaskGetTickCount ();
+	 for( ;; )
+	 {
+		 // Wait for the next cycle.
+		 vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+		 // Perform action here.
+	 }
+ }
+   
+ * \defgroup vTaskDelayUntil vTaskDelayUntil + * \ingroup TaskCtrl + */ +void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskAbortDelay( TaskHandle_t xTask );
+ * + * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this + * function to be available. + * + * A task will enter the Blocked state when it is waiting for an event. The + * event it is waiting for can be a temporal event (waiting for a time), such + * as when vTaskDelay() is called, or an event on an object, such as when + * xQueueReceive() or ulTaskNotifyTake() is called. If the handle of a task + * that is in the Blocked state is used in a call to xTaskAbortDelay() then the + * task will leave the Blocked state, and return from whichever function call + * placed the task into the Blocked state. + * + * @param xTask The handle of the task to remove from the Blocked state. + * + * @return If the task referenced by xTask was not in the Blocked state then + * pdFAIL is returned. Otherwise pdPASS is returned. + * + * \defgroup xTaskAbortDelay xTaskAbortDelay + * \ingroup TaskCtrl + */ +BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param xTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of xTask. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to obtain the priority of the created task.
+	 // It was created with tskIDLE_PRIORITY, but may have changed
+	 // it itself.
+	 if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+	 {
+		 // The task has changed it's priority.
+	 }
+
+	 // ...
+
+	 // Is our priority higher than the created task?
+	 if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+	 {
+		 // Our priority (obtained using NULL handle) is higher.
+	 }
+ }
+   
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask );
+ * + * A version of uxTaskPriorityGet() that can be used from an ISR. + */ +UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
eTaskState eTaskGetState( TaskHandle_t xTask );
+ * + * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the state of any task. States are encoded by the eTaskState + * enumerated type. + * + * @param xTask Handle of the task to be queried. + * + * @return The state of xTask at the time the function was called. Note the + * state of the task might change between the function being called, and the + * functions return value being tested by the calling task. + */ +eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
+ * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * Populates a TaskStatus_t structure with information about a task. + * + * @param xTask Handle of the task being queried. If xTask is NULL then + * information will be returned about the calling task. + * + * @param pxTaskStatus A pointer to the TaskStatus_t structure that will be + * filled with information about the task referenced by the handle passed using + * the xTask parameter. + * + * @xGetFreeStackSpace The TaskStatus_t structure contains a member to report + * the stack high water mark of the task being queried. Calculating the stack + * high water mark takes a relatively long time, and can make the system + * temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to + * allow the high water mark checking to be skipped. The high watermark value + * will only be written to the TaskStatus_t structure if xGetFreeStackSpace is + * not set to pdFALSE; + * + * @param eState The TaskStatus_t structure contains a member to report the + * state of the task being queried. Obtaining the task state is not as fast as + * a simple assignment - so the eState parameter is provided to allow the state + * information to be omitted from the TaskStatus_t structure. To obtain state + * information then set eState to eInvalid - otherwise the value passed in + * eState will be reported as the task state in the TaskStatus_t structure. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+ TaskStatus_t xTaskDetails;
+
+    // Obtain the handle of a task from its name.
+    xHandle = xTaskGetHandle( "Task_Name" );
+
+    // Check the handle is not NULL.
+    configASSERT( xHandle );
+
+    // Use the handle to obtain further information about the task.
+    vTaskGetInfo( xHandle,
+                  &xTaskDetails,
+                  pdTRUE, // Include the high water mark in xTaskDetails.
+                  eInvalid ); // Include the task state in xTaskDetails.
+ }
+   
+ * \defgroup vTaskGetInfo vTaskGetInfo + * \ingroup TaskCtrl + */ +void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
+ * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param xTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to raise the priority of the created task.
+	 vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+	 // ...
+
+	 // Use a NULL handle to raise our priority to the same value.
+	 vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+   
+ * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Suspend ourselves.
+	 vTaskSuspend( NULL );
+
+	 // We cannot get here unless another task calls vTaskResume
+	 // with our handle as the parameter.
+ }
+   
+ * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskResume( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param xTaskToResume Handle to the task being readied. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Resume the suspended task ourselves.
+	 vTaskResume( xHandle );
+
+	 // The created task will once again get microcontroller processing
+	 // time in accordance with its priority within the system.
+ }
+   
+ * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void xTaskResumeFromISR( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * xTaskResumeFromISR() should not be used to synchronise a task with an + * interrupt if there is a chance that the interrupt could arrive prior to the + * task being suspended - as this can lead to interrupts being missed. Use of a + * semaphore as a synchronisation mechanism would avoid this eventuality. + * + * @param xTaskToResume Handle to the task being readied. + * + * @return pdTRUE if resuming the task should result in a context switch, + * otherwise pdFALSE. This is used by the ISR to determine if a context switch + * may be required following the ISR. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER CONTROL + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskStartScheduler( void );
+ * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: +
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+   
+ * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskEndScheduler( void );
+ * + * NOTE: At the time of writing only the x86 real mode port, which runs on a PC + * in place of DOS, implements this function. + * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: +
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // At some point we want to end the real time kernel processing
+		 // so call ...
+		 vTaskEndScheduler ();
+	 }
+ }
+
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will only get here when the vTaskCode () task has called
+	 // vTaskEndScheduler ().  When we get here we are back to single task
+	 // execution.
+ }
+   
+ * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspendAll( void );
+ * + * Suspends the scheduler without disabling interrupts. Context switches will + * not occur while the scheduler is suspended. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the kernel
+		 // tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.
+		 xTaskResumeAll ();
+	 }
+ }
+   
+ * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskResumeAll( void );
+ * + * Resumes scheduler activity after it was suspended by a call to + * vTaskSuspendAll(). + * + * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks + * that were previously suspended by a call to vTaskSuspend(). + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the real
+		 // time kernel tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.  We want to force
+		 // a context switch - but there is no point if resuming the scheduler
+		 // caused a context switch already.
+		 if( !xTaskResumeAll () )
+		 {
+			  taskYIELD ();
+		 }
+	 }
+ }
+   
+ * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK UTILITIES + *----------------------------------------------------------*/ + +/** + * task. h + *
TickType_t xTaskGetTickCount( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
TickType_t xTaskGetTickCountFromISR( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that TickType_t is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
uint16_t uxTaskGetNumberOfTasks( void );
+ * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
char *pcTaskGetName( TaskHandle_t xTaskToQuery );
+ * + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQuery. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. + * + * \defgroup pcTaskGetName pcTaskGetName + * \ingroup TaskUtils + */ +char *pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
TaskHandle_t xTaskGetHandle( const char *pcNameToQuery );
+ * + * NOTE: This function takes a relatively long time to complete and should be + * used sparingly. + * + * @return The handle of the task that has the human readable name pcNameToQuery. + * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle + * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. + * + * \defgroup pcTaskGetHandle pcTaskGetHandle + * \ingroup TaskUtils + */ +TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task.h + *
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* When using trace macros it is sometimes necessary to include task.h before +FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined, +so the following two prototypes will cause a compilation error. This can be +fixed by simply guarding against the inclusion of these two prototypes unless +they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration +constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG + #if configUSE_APPLICATION_TASK_TAG == 1 + /** + * task.h + *
void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTag( TaskHandle_t xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. + */ + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + + /* Each task contains an array of pointers that is dimensioned by the + configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The + kernel does not use the pointers itself, so the application writer can use + the pointers for any purpose they wish. The following two functions are + used to set and query a pointer respectively. */ + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) PRIVILEGED_FUNCTION; + void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION; + +#endif + +/** + * task.h + *
BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. The return value is the value returned by the task hook function + * registered by the user. + */ +BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) PRIVILEGED_FUNCTION; + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task. It is not valid to call + * xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for + * uxTaskGetSystemState() to be available. + * + * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in + * the system. TaskStatus_t structures contain, among other things, members + * for the task handle, task name, task priority, task state, and total amount + * of run time consumed by the task. See the TaskStatus_t structure + * definition in this file for the full member list. + * + * NOTE: This function is intended for debugging use only as its use results in + * the scheduler remaining suspended for an extended period. + * + * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures. + * The array must contain at least one TaskStatus_t structure for each task + * that is under the control of the RTOS. The number of tasks under the control + * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. + * + * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray + * parameter. The size is specified as the number of indexes in the array, or + * the number of TaskStatus_t structures contained in the array, not by the + * number of bytes in the array. + * + * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in + * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the + * total run time (as defined by the run time stats clock, see + * http://www.freertos.org/rtos-run-time-stats.html) since the target booted. + * pulTotalRunTime can be set to NULL to omit the total run time information. + * + * @return The number of TaskStatus_t structures that were populated by + * uxTaskGetSystemState(). This should equal the number returned by the + * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed + * in the uxArraySize parameter was too small. + * + * Example usage: +
+    // This example demonstrates how a human readable table of run time stats
+	// information is generated from raw data provided by uxTaskGetSystemState().
+	// The human readable table is written to pcWriteBuffer
+	void vTaskGetRunTimeStats( char *pcWriteBuffer )
+	{
+	TaskStatus_t *pxTaskStatusArray;
+	volatile UBaseType_t uxArraySize, x;
+	uint32_t ulTotalRunTime, ulStatsAsPercentage;
+
+		// Make sure the write buffer does not contain a string.
+		*pcWriteBuffer = 0x00;
+
+		// Take a snapshot of the number of tasks in case it changes while this
+		// function is executing.
+		uxArraySize = uxTaskGetNumberOfTasks();
+
+		// Allocate a TaskStatus_t structure for each task.  An array could be
+		// allocated statically at compile time.
+		pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );
+
+		if( pxTaskStatusArray != NULL )
+		{
+			// Generate raw status information about each task.
+			uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
+
+			// For percentage calculations.
+			ulTotalRunTime /= 100UL;
+
+			// Avoid divide by zero errors.
+			if( ulTotalRunTime > 0 )
+			{
+				// For each populated position in the pxTaskStatusArray array,
+				// format the raw data as human readable ASCII data
+				for( x = 0; x < uxArraySize; x++ )
+				{
+					// What percentage of the total run time has the task used?
+					// This will always be rounded down to the nearest integer.
+					// ulTotalRunTimeDiv100 has already been divided by 100.
+					ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
+
+					if( ulStatsAsPercentage > 0UL )
+					{
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
+					}
+					else
+					{
+						// If the percentage is zero here then the task has
+						// consumed less than 1% of the total run time.
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
+					}
+
+					pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
+				}
+			}
+
+			// The array is no longer needed, free the memory it consumes.
+			vPortFree( pxTaskStatusArray );
+		}
+	}
+	
+ */ +UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskList( char *pcWriteBuffer );
+ * + * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must + * both be defined as 1 for this function to be available. See the + * configuration section of the FreeRTOS.org website for more information. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays task + * names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that might + * bloat the code size, use a lot of stack, and provide different results on + * different platforms. An alternative, tiny, third party, and limited + * functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly through a + * call to vTaskList(). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ASCII form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \defgroup vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
void vTaskGetRunTimeStats( char *pcWriteBuffer );
+ * + * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS + * must both be defined as 1 for this function to be available. The application + * must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * NOTE 2: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays the + * amount of time each task has spent in the Running state in both absolute and + * percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function + * that might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, and + * limited functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() directly + * to get access to raw stats data, rather than indirectly through a call to + * vTaskGetRunTimeStats(). + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ASCII form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * pulPreviousNotificationValue - + * Can be used to pass out the subject task's notification value before any + * bits are modified by the notify function. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION; +#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL ) +#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) + +/** + * task. h + *
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * A version of xTaskNotify() that can be used from an interrupt service routine + * (ISR). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the + * task to which the notification was sent to leave the Blocked state, and the + * unblocked task has a priority higher than the currently running task. If + * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should + * be requested before the interrupt is exited. How a context switch is + * requested from an ISR is dependent on the port - see the documentation page + * for the port in use. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) +#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) + +/** + * task. h + *
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value + * will be cleared in the calling task's notification value before the task + * checks to see if any notifications are pending, and optionally blocks if no + * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if + * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have + * the effect of resetting the task's notification value to 0. Setting + * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged. + * + * @param ulBitsToClearOnExit If a notification is pending or received before + * the calling task exits the xTaskNotifyWait() function then the task's + * notification value (see the xTaskNotify() API function) is passed out using + * the pulNotificationValue parameter. Then any bits that are set in + * ulBitsToClearOnExit will be cleared in the task's notification value (note + * *pulNotificationValue is set before any bits are cleared). Setting + * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL + * (if limits.h is not included) will have the effect of resetting the task's + * notification value to 0 before the function exits. Setting + * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged + * when the function exits (in which case the value passed out in + * pulNotificationValue will match the task's notification value). + * + * @param pulNotificationValue Used to pass the task's notification value out + * of the function. Note the value passed out will not be effected by the + * clearing of any bits caused by ulBitsToClearOnExit being non-zero. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for a notification to be received, should a notification + * not already be pending when xTaskNotifyWait() was called. The task + * will not consume any processing time while it is in the Blocked state. This + * is specified in kernel ticks, the macro pdMS_TO_TICSK( value_in_ms ) can be + * used to convert a time specified in milliseconds to a time specified in + * ticks. + * + * @return If a notification was received (including notifications that were + * already pending when xTaskNotifyWait was called) then pdPASS is + * returned. Otherwise pdFAIL is returned. + * + * \defgroup xTaskNotifyWait xTaskNotifyWait + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro + * to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * xTaskNotifyGive() is a helper macro intended for use when task notifications + * are used as light weight and faster binary or counting semaphore equivalents. + * Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function, + * the equivalent action that instead uses a task notification is + * xTaskNotifyGive(). + * + * When task notifications are being used as a binary or counting semaphore + * equivalent then the task being notified should wait for the notification + * using the ulTaskNotificationTake() API function rather than the + * xTaskNotifyWait() API function. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the + * eAction parameter set to eIncrement - so pdPASS is always returned. + * + * \defgroup xTaskNotifyGive xTaskNotifyGive + * \ingroup TaskNotifications + */ +#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL ) + +/** + * task. h + *
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro
+ * to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * A version of xTaskNotifyGive() that can be called from an interrupt service
+ * routine (ISR).
+ *
+ * Events can be sent to a task using an intermediary object.  Examples of such
+ * objects are queues, semaphores, mutexes and event groups.  Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value.  In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * vTaskNotifyGiveFromISR() is intended for use when task notifications are
+ * used as light weight and faster binary or counting semaphore equivalents.
+ * Actual FreeRTOS semaphores are given from an ISR using the
+ * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses
+ * a task notification is vTaskNotifyGiveFromISR().
+ *
+ * When task notifications are being used as a binary or counting semaphore
+ * equivalent then the task being notified should wait for the notification
+ * using the ulTaskNotificationTake() API function rather than the
+ * xTaskNotifyWait() API function.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.
+ *
+ * @param xTaskToNotify The handle of the task being notified.  The handle to a
+ * task can be returned from the xTaskCreate() API function used to create the
+ * task, and the handle of the currently running task can be obtained by calling
+ * xTaskGetCurrentTaskHandle().
+ *
+ * @param pxHigherPriorityTaskWoken  vTaskNotifyGiveFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
+ * task to which the notification was sent to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently running task.  If
+ * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch
+ * should be requested before the interrupt is exited.  How a context switch is
+ * requested from an ISR is dependent on the port - see the documentation page
+ * for the port in use.
+ *
+ * \defgroup xTaskNotifyWait xTaskNotifyWait
+ * \ingroup TaskNotifications
+ */
+void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * 
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * ulTaskNotifyTake() is intended for use when a task notification is used as a + * faster and lighter weight binary or counting semaphore alternative. Actual + * FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the + * equivalent action that instead uses a task notification is + * ulTaskNotifyTake(). + * + * When a task is using its notification value as a binary or counting semaphore + * other tasks should send notifications to it using the xTaskNotifyGive() + * macro, or xTaskNotify() function with the eAction parameter set to + * eIncrement. + * + * ulTaskNotifyTake() can either clear the task's notification value to + * zero on exit, in which case the notification value acts like a binary + * semaphore, or decrement the task's notification value on exit, in which case + * the notification value acts like a counting semaphore. + * + * A task can use ulTaskNotifyTake() to [optionally] block to wait for a + * the task's notification value to be non-zero. The task does not consume any + * CPU time while it is in the Blocked state. + * + * Where as xTaskNotifyWait() will return when a notification is pending, + * ulTaskNotifyTake() will return when the task's notification value is + * not zero. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's + * notification value is decremented when the function exits. In this way the + * notification value acts like a counting semaphore. If xClearCountOnExit is + * not pdFALSE then the task's notification value is cleared to zero when the + * function exits. In this way the notification value acts like a binary + * semaphore. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for the task's notification value to be greater than zero, + * should the count not already be greater than zero when + * ulTaskNotifyTake() was called. The task will not consume any processing + * time while it is in the Blocked state. This is specified in kernel ticks, + * the macro pdMS_TO_TICSK( value_in_ms ) can be used to convert a time + * specified in milliseconds to a time specified in ticks. + * + * @return The task's notification count before it is either cleared to zero or + * decremented (see the xClearCountOnExit parameter). + * + * \defgroup ulTaskNotifyTake ulTaskNotifyTake + * \ingroup TaskNotifications + */ +uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );
+ * + * If the notification state of the task referenced by the handle xTask is + * eNotified, then set the task's notification state to eNotWaitingNotification. + * The task's notification value is not altered. Set xTask to NULL to clear the + * notification state of the calling task. + * + * @return pdTRUE if the task's notification state was set to + * eNotWaitingNotification, otherwise pdFALSE. + * \defgroup xTaskNotifyStateClear xTaskNotifyStateClear + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + *----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. If a non-zero value is returned then a context switch is + * required because either: + * + A task was removed from a blocked list because its timeout had expired, + * or + * + Time slicing is in use and there is a task of equal priority to the + * currently running task. + */ +BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * The 'unordered' version replaces the event list item value with the + * xItemValue value, and inserts the list item at the end of the list. + * + * The 'ordered' version uses the existing event list item value (which is the + * owning tasks priority) to insert the list item into the event list is task + * priority order. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xItemValue The item value to use for the event list item when the + * event list is not ordered by task priority. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks,the constant + * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + */ +void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called + * if either an event occurs to unblock a task, or the block timeout period + * expires. + * + * xTaskRemoveFromEventList() is used when the event list is in task priority + * order. It removes the list item from the head of the event list as that will + * have the highest priority owning task of all the tasks on the event list. + * vTaskRemoveFromUnorderedEventList() is used when the event list is not + * ordered and the event list items hold something other than the owning tasks + * priority. In this case the event list item value is updated to the value + * passed in the xItemValue parameter. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; + +/* + * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY + * THE EVENT BITS MODULE. + */ +TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +/* + * Capture the current time status for future reference. + */ +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + +/* + * Compare the time status now with that previously captured to see if the + * timeout has expired. + */ +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * If a higher priority task attempting to obtain a mutex caused a lower + * priority task to inherit the higher priority task's priority - but the higher + * priority task then timed out without obtaining the mutex, then the lower + * priority task will disinherit the priority again - but only down as far as + * the highest priority task that is still waiting for the mutex (if there were + * more than one task waiting for the mutex). + */ +void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) PRIVILEGED_FUNCTION; + +/* + * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. + */ +UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +UBaseType_t uxTaskGetTCBNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; +/* + * Set the uxTaskNumber of the task referenced by the xTask parameter to + * uxHandle. + */ +void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * If tickless mode is being used, or a low power mode is implemented, then + * the tick interrupt will not execute during idle periods. When this is the + * case, the tick count value maintained by the scheduler needs to be kept up + * to date with the actual execution time by being skipped forward by a time + * equal to the idle period. + */ +void vTaskStepTick( const TickType_t xTicksToJump ) PRIVILEGED_FUNCTION; + +/* + * Only avilable when configUSE_TICKLESS_IDLE is set to 1. + * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port + * specific sleep function to determine if it is ok to proceed with the sleep, + * and if it is ok to proceed, if it is ok to sleep indefinitely. + * + * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only + * called with the scheduler suspended, not from within a critical section. It + * is therefore possible for an interrupt to request a context switch between + * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being + * entered. eTaskConfirmSleepModeStatus() should be called from a short + * critical section between the timer being stopped and the sleep mode being + * entered to ensure it is ok to proceed into the sleep mode. + */ +eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Increment the mutex held count when a mutex is + * taken and return the handle of the task that has taken the mutex. + */ +TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Same as vTaskSetTimeOutState(), but without a critial + * section. + */ +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + + +#ifdef __cplusplus +} +#endif +#endif /* INC_TASK_H */ + + + diff --git a/include/rtos/freertos/timers.h b/include/rtos/freertos/timers.h new file mode 100644 index 0000000..ae8bc71 --- /dev/null +++ b/include/rtos/freertos/timers.h @@ -0,0 +1,1278 @@ +/* + * FreeRTOS Kernel V10.1.1 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef TIMERS_H +#define TIMERS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include timers.h" +#endif + +/*lint -save -e537 This headers are only multiply included if the application code +happens to also be including task.h. */ +#include "task.h" +/*lint -restore */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +/* IDs for commands that can be sent/received on the timer queue. These are to +be used solely through the macros that make up the public software timer API, +as defined below. The commands that are sent from interrupts must use the +highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task +or interrupt version of the queue send function should be used. */ +#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) +#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) +#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) +#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) +#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) +#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) +#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) + +#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) +#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) +#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) + + +/** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an TimerHandle_t variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ +struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tmrTimerControl * TimerHandle_t; + +/* + * Defines the prototype to which timer callback functions must conform. + */ +typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer ); + +/* + * Defines the prototype to which functions used with the + * xTimerPendFunctionCallFromISR() function must conform. + */ +typedef void (*PendedFunction_t)( void *, uint32_t ); + +/** + * TimerHandle_t xTimerCreate( const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @return If the timer is successfully created then a handle to the newly + * created timer is returned. If the timer cannot be created (because either + * there is insufficient FreeRTOS heap remaining to allocate the timer + * structures, or the timer period was set to 0) then NULL is returned. + * + * Example usage: + * @verbatim + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * TimerHandle_t xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( TimerHandle_t pxTimer ) + * { + * int32_t lArrayIndex; + * const int32_t xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * x ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; +#endif + +/** + * TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction, + * StaticTimer_t *pxTimerBuffer ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @param pxTimerBuffer Must point to a variable of type StaticTimer_t, which + * will be then be used to hold the software timer's data structures, removing + * the need for the memory to be allocated dynamically. + * + * @return If the timer is created then a handle to the created timer is + * returned. If pxTimerBuffer was NULL then NULL is returned. + * + * Example usage: + * @verbatim + * + * // The buffer used to hold the software timer's data structure. + * static StaticTimer_t xTimerBuffer; + * + * // A variable that will be incremented by the software timer's callback + * // function. + * UBaseType_t uxVariableToIncrement = 0; + * + * // A software timer callback function that increments a variable passed to + * // it when the software timer was created. After the 5th increment the + * // callback function stops the software timer. + * static void prvTimerCallback( TimerHandle_t xExpiredTimer ) + * { + * UBaseType_t *puxVariableToIncrement; + * BaseType_t xReturned; + * + * // Obtain the address of the variable to increment from the timer ID. + * puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); + * + * // Increment the variable to show the timer callback has executed. + * ( *puxVariableToIncrement )++; + * + * // If this callback has executed the required number of times, stop the + * // timer. + * if( *puxVariableToIncrement == 5 ) + * { + * // This is called from a timer callback so must not block. + * xTimerStop( xExpiredTimer, staticDONT_BLOCK ); + * } + * } + * + * + * void main( void ) + * { + * // Create the software time. xTimerCreateStatic() has an extra parameter + * // than the normal xTimerCreate() API function. The parameter is a pointer + * // to the StaticTimer_t structure that will hold the software timer + * // structure. If the parameter is passed as NULL then the structure will be + * // allocated dynamically, just as if xTimerCreate() had been called. + * xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS. + * xTimerPeriod, // The period of the timer in ticks. + * pdTRUE, // This is an auto-reload timer. + * ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function + * prvTimerCallback, // The function to execute when the timer expires. + * &xTimerBuffer ); // The buffer that will hold the software timer structure. + * + * // The scheduler has not started yet so a block time is not used. + * xReturned = xTimerStart( xTimer, 0 ); + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * void *pvTimerGetTimerID( TimerHandle_t xTimer ); + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer, and by calling the + * vTimerSetTimerID() API function. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); + * + * Sets the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being updated. + * + * @param pvNewID The ID to assign to the timer. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); + * + * Queries a timer to see if it is active or dormant. + * + * A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + * @endverbatim + */ +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); + * + * Simply returns the handle of the timer service/daemon task. It it not valid + * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStart() starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerStart() has equivalent functionality + * to the xTimerReset() API function. + * + * Starting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerStart() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerStart() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerStart() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() + * to be available. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the start command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStop() stops a timer that was previously started using either of the + * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), + * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. + * + * Stopping a timer ensures the timer is not in the active state. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() + * to be available. + * + * @param xTimer The handle of the timer being stopped. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerChangePeriod() changes the period of a timer that was previously + * created using the xTimerCreate() API function. + * + * xTimerChangePeriod() can be called to change the period of an active or + * dormant state timer. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerChangePeriod() to be available. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerChangePeriod() was called. xTicksToWait is ignored if + * xTimerChangePeriod() is called before the scheduler is started. + * + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xTicksToWait ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. The timer service/daemon task priority is set by the + * configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. If the timer + * // referenced by xTimer is already active when it is called, then the timer + * // is deleted. If the timer referenced by xTimer is not active when it is + * // called, then the period of the timer is set to 500ms and the timer is + * // started. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is already active - delete it. + * xTimerDelete( xTimer ); + * } + * else + * { + * // xTimer is not active, change its period to 500ms. This will also + * // cause the timer to start. Block for a maximum of 100 ticks if the + * // change period command cannot immediately be sent to the timer + * // command queue. + * if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS ) + * { + * // The command was successfully sent. + * } + * else + * { + * // The command could not be sent, even after waiting for 100 ticks + * // to pass. Take appropriate action here. + * } + * } + * } + * @endverbatim + */ + #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerDelete() deletes a timer that was previously created using the + * xTimerCreate() API function. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerDelete() to be available. + * + * @param xTimer The handle of the timer being deleted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the delete command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete() + * is called before the scheduler is started. + * + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerChangePeriod() API function example usage scenario. + */ +#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerReset() re-starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerReset() will cause the timer to + * re-evaluate its expiry time so that it is relative to when xTimerReset() was + * called. If the timer was in the dormant state then xTimerReset() has + * equivalent functionality to the xTimerStart() API function. + * + * Resetting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerReset() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerReset() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerReset() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() + * to be available. + * + * @param xTimer The handle of the timer being reset/started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the reset command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer. + * + * TimerHandle_t xBacklightTimer = NULL; + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press event handler. + * void vKeyPressEventHandler( char cKey ) + * { + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. Wait 10 ticks for the command to be successfully sent + * // if it cannot be sent immediately. + * vSetBacklightState( BACKLIGHT_ON ); + * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start the one-shot timer that is responsible for turning + * // the back-light off if no keys are pressed within a 5 second period. + * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. + * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks. + * pdFALSE, // The timer is a one-shot timer. + * 0, // The id is not used by the callback so can take any value. + * vBacklightTimerCallback // The callback function that switches the LCD back-light off. + * ); + * + * if( xBacklightTimer == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timer running as it has already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStart() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStartFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStartFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStartFromISR() function. If + * xTimerStartFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerStartFromISR() is actually called. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then restart the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The start command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStop() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being stopped. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStopFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStopFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStopFromISR() function. If + * xTimerStopFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the timer should be simply stopped. + * + * // The interrupt service routine that stops the timer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - simply stop the timer. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The stop command was not executed successfully. Take appropriate + * // action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerChangePeriod() that can be called from an interrupt + * service routine. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerChangePeriodFromISR() writes a message to the + * timer command queue, so has the potential to transition the timer service/ + * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() + * causes the timer service/daemon task to leave the Blocked state, and the + * timer service/daemon task has a priority equal to or greater than the + * currently executing task (the task that was interrupted), then + * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the + * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets + * this value to pdTRUE then a context switch should be performed before the + * interrupt exits. + * + * @return pdFAIL will be returned if the command to change the timers period + * could not be sent to the timer command queue. pdPASS will be returned if the + * command was successfully sent to the timer command queue. When the command + * is actually processed will depend on the priority of the timer service/daemon + * task relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the period of xTimer should be changed to 500ms. + * + * // The interrupt service routine that changes the period of xTimer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - change the period of xTimer to 500ms. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The command to change the timers period was not executed + * // successfully. Take appropriate action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerReset() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer that is to be started, reset, or + * restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerResetFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerResetFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerResetFromISR() function. If + * xTimerResetFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerResetFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + + +/** + * BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * + * Used from application interrupt service routines to defer the execution of a + * function to the RTOS daemon task (the timer service task, hence this function + * is implemented in timers.c and is prefixed with 'Timer'). + * + * Ideally an interrupt service routine (ISR) is kept as short as possible, but + * sometimes an ISR either has a lot of processing to do, or needs to perform + * processing that is not deterministic. In these cases + * xTimerPendFunctionCallFromISR() can be used to defer processing of a function + * to the RTOS daemon task. + * + * A mechanism is provided that allows the interrupt to return directly to the + * task that will subsequently execute the pended callback function. This + * allows the callback function to execute contiguously in time with the + * interrupt - just as if the callback had executed in the interrupt itself. + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task (which is set using + * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of + * the currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE within + * xTimerPendFunctionCallFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + * Example usage: + * @verbatim + * + * // The callback function that will execute in the context of the daemon task. + * // Note callback functions must all use this same prototype. + * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) + * { + * BaseType_t xInterfaceToService; + * + * // The interface that requires servicing is passed in the second + * // parameter. The first parameter is not used in this case. + * xInterfaceToService = ( BaseType_t ) ulParameter2; + * + * // ...Perform the processing here... + * } + * + * // An ISR that receives data packets from multiple interfaces + * void vAnISR( void ) + * { + * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; + * + * // Query the hardware to determine which interface needs processing. + * xInterfaceToService = prvCheckInterfaces(); + * + * // The actual processing is to be deferred to a task. Request the + * // vProcessInterface() callback function is executed, passing in the + * // number of the interface that needs processing. The interface to + * // service is passed in the second parameter. The first parameter is + * // not used in this case. + * xHigherPriorityTaskWoken = pdFALSE; + * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); + * + * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context + * // switch should be requested. The macro used is port specific and will + * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to + * // the documentation page for the port being used. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * + * } + * @endverbatim + */ +BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + + /** + * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * TickType_t xTicksToWait ); + * + * + * Used to defer the execution of a function to the RTOS daemon task (the timer + * service task, hence this function is implemented in timers.c and is prefixed + * with 'Timer'). + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param xTicksToWait Calling this function will result in a message being + * sent to the timer daemon task on a queue. xTicksToWait is the amount of + * time the calling task should remain in the Blocked state (so not using any + * processing time) for space to become available on the timer queue if the + * queue is found to be full. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + */ +BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * const char * const pcTimerGetName( TimerHandle_t xTimer ); + * + * Returns the name that was assigned to a timer when the timer was created. + * + * @param xTimer The handle of the timer being queried. + * + * @return The name assigned to the timer specified by the xTimer parameter. + */ +const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * TickType_t xTimerGetPeriod( TimerHandle_t xTimer ); + * + * Returns the period of a timer. + * + * @param xTimer The handle of the timer being queried. + * + * @return The period of the timer in ticks. + */ +TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** +* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); +* +* Returns the time in ticks at which the timer will expire. If this is less +* than the current tick count then the expiry time has overflowed from the +* current time. +* +* @param xTimer The handle of the timer being queried. +* +* @return If the timer is running then the time in ticks at which the timer +* will next expire is returned. If the timer is not running then the return +* value is undefined. +*/ +TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +#if( configUSE_TRACE_FACILITY == 1 ) + void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION; + UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* TIMERS_H */ + + + diff --git a/include/rtos/rtx/cmsis_os.h b/include/rtos/rtx/cmsis_os.h new file mode 100644 index 0000000..d8b3d96 --- /dev/null +++ b/include/rtos/rtx/cmsis_os.h @@ -0,0 +1,813 @@ +/* ---------------------------------------------------------------------- + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * $Date: 5. June 2012 + * $Revision: V1.01 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h RTX header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedef's + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * -------------------------------------------------------------------- */ + +/** +\page cmsis_os_h Header File Template: cmsis_os.h + +The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). +Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents +its implementation. + +The file cmsis_os.h contains: + - CMSIS-RTOS API function definitions + - struct definitions for parameters and return types + - status and priority values used by CMSIS-RTOS API functions + - macros for defining threads and other kernel objects + + +Name conventions and header file modifications + +All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. +Definitions that are prefixed \b os_ are not used in the application code but local to this header file. +All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. + +Definitions that are marked with CAN BE CHANGED can be adapted towards the needs of the actual CMSIS-RTOS implementation. +These definitions can be specific to the underlying RTOS kernel. + +Definitions that are marked with MUST REMAIN UNCHANGED cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer +compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. + + +Function calls from interrupt service routines + +The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): + - \ref osSignalSet + - \ref osSemaphoreRelease + - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree + - \ref osMessagePut, \ref osMessageGet + - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree + +Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called +from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. + +Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. +If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. + + +Define and reference object definitions + +With \#define osObjectsExternal objects are defined as external symbols. This allows to create a consistent header file +that is used throughout a project as shown below: + +Header File +\code +#include // CMSIS RTOS header file + +// Thread definition +extern void thread_sample (void const *argument); // function prototype +osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); + +// Pool definition +osPoolDef(MyPool, 10, long); +\endcode + + +This header file defines all objects when included in a C/C++ source file. When \#define osObjectsExternal is +present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be +used throughout the whole project. + +Example +\code +#include "osObjects.h" // Definition of the CMSIS-RTOS objects +\endcode + +\code +#define osObjectExternal // Objects will be defined as external symbols +#include "osObjects.h" // Reference to the CMSIS-RTOS objects +\endcode + +*/ + +#ifndef _CMSIS_OS_H +#define _CMSIS_OS_H + +/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x10001 ///< API version (main [31:16] .sub [15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_RTX ((4<<16)|61) ///< RTOS identification and version (main [31:16] .sub [15:0]) + +/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. +#define osKernelSystemId "RTX V4.61" ///< RTOS identification string + + +#define CMSIS_OS_RTX + +// The stack space occupied is mainly dependent on the underling C standard library +#if defined(__GNUC__) || defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__ICCARM__) +# define WORDS_STACK_SIZE 512 +#elif defined(TOOLCHAIN_ARM_MICRO) +# define WORDS_STACK_SIZE 128 +#endif + +#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4) + + +/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_Signals 16 ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 65535 ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available + +#if defined (__CC_ARM) +#define os_InRegs __value_in_regs // Compiler specific: force struct in registers +#elif defined (__ICCARM__) +#define os_InRegs __value_in_regs // Compiler specific: force struct in registers +#else +#define os_InRegs +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "os_tcb.h" + +// ==== Enumeration, structures, defines ==== + +/// Priority used for thread control. +/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. +typedef enum { + osPriorityIdle = -3, ///< priority: idle (lowest) + osPriorityLow = -2, ///< priority: low + osPriorityBelowNormal = -1, ///< priority: below normal + osPriorityNormal = 0, ///< priority: normal (default) + osPriorityAboveNormal = +1, ///< priority: above normal + osPriorityHigh = +2, ///< priority: high + osPriorityRealtime = +3, ///< priority: realtime (highest) + osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority +} osPriority; + +/// Timeout value. +/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value + +/// Status code values returned by CMSIS-RTOS functions. +/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osEventMessage = 0x10, ///< function completed; message event occurred. + osEventMail = 0x20, ///< function completed; mail event occurred. + osEventTimeout = 0x40, ///< function completed; timeout occurred. + osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< value of a parameter is out of range. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; + + +/// Timer type value for the timer definition. +/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. +typedef enum { + osTimerOnce = 0, ///< one-shot timer + osTimerPeriodic = 1 ///< repeating timer +} os_timer_type; + +/// Entry point of a thread. +/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. +typedef void (*os_ptimer) (void const *argument); + +// >>> the following data type definitions may shall adapted towards a specific RTOS + +/// Thread ID identifies the thread (pointer to a thread control block). +/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_cb *osThreadId; + +/// Timer ID identifies the timer (pointer to a timer control block). +/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_cb *osTimerId; + +/// Mutex ID identifies the mutex (pointer to a mutex control block). +/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_cb *osMutexId; + +/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). +/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_cb *osSemaphoreId; + +/// Pool ID identifies the memory pool (pointer to a memory pool control block). +/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_cb *osPoolId; + +/// Message ID identifies the message queue (pointer to a message queue control block). +/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_cb *osMessageQId; + +/// Mail ID identifies the mail queue (pointer to a mail queue control block). +/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_cb *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t stacksize; ///< stack size requirements in bytes + uint32_t *stack_pointer; ///< pointer to the stack memory block + struct OS_TCB tcb; +#if __RTX_CPU_STATISTICS__ + const char * name_str; +#endif +} osThreadDef_t; + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + void *timer; ///< pointer to internal data +} osTimerDef_t; + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_def { + void *mutex; ///< pointer to internal data +} osMutexDef_t; + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_def { + void *semaphore; ///< pointer to internal data +} osSemaphoreDef_t; + +/// Definition structure for memory block allocation. +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + void *pool; ///< memory array for messages +} osMessageQDef_t; + +/// Definition structure for mail queue. +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; + +/// Event structure contains detailed information about an event. +/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. +/// However the struct may be extended at the end. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Control Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. +osStatus osKernelInitialize (void); + +/// Start the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. +osStatus osKernelStart (void); + +/// Check if the RTOS kernel is already started. +/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. +/// \return 0 RTOS is not started, 1 RTOS is started. +int32_t osKernelRunning(void); + + +// ==== Thread Management ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, stacksz) \ +extern osThreadDef_t os_thread_def_##name +#else // define the object +#if __RTX_CPU_STATISTICS__ +#define osThreadDef(name, priority, instances, stacksz, task_name) \ +uint32_t os_thread_def_stack_##name [stacksz / sizeof(uint32_t)]; \ +osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (stacksz), (os_thread_def_stack_##name) , {0,}, (task_name)} +#else +#define osThreadDef(name, priority, instance, stacksz, task_name) \ +uint32_t os_thread_def_stack_##name [stacksz / sizeof(uint32_t)]; \ +osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (stacksz), (os_thread_def_stack_##name)} +#endif +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. +osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. +osThreadId osThreadGetId (void); + +int osGetThreadIntId (void); + +/// Terminate execution of a thread and remove it from Active Threads. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. +osStatus osThreadTerminate (osThreadId thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. +osStatus osThreadYield (void); + +/// Change priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); + +/// Get current priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the thread function. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. +osPriority osThreadGetPriority (osThreadId thread_id); + +/// Show a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadShow (osThreadId thread_id); +#endif + +/// set the hung check of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] enable enable/disable the hung check feature of the task +/// \param[in] timeout hung check timeout in millisecond +/// \return status code that indicates the execution status of the function. +#if TASK_HUNG_CHECK_ENABLED +osStatus osThreadSetHungCheck (osThreadId thread_id, int32_t enable, uint32_t timeout); +#endif + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec time delay value +/// \return status code that indicates the execution status of the function. +osStatus osDelay (uint32_t millisec); + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern osTimerDef_t os_timer_def_##name +#else // define the object +#define osTimerDef(name, function) \ +uint32_t os_timer_cb_##name[5]; \ +osTimerDef_t os_timer_def_##name = \ +{ (function), (os_timer_cb_##name) } +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec time delay value of the timer. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); + +/// Stop the timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. +osStatus osTimerStop (osTimerId timer_id); + +/// Delete a timer that was created by \ref osTimerCreate. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. +osStatus osTimerDelete (osTimerId timer_id); + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Get Signal Flags status of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalGet shall be consistent in every CMSIS-RTOS. +int32_t osSignalGet (osThreadId thread_id); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event flag information or error code. +/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Mutex Management ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern osMutexDef_t os_mutex_def_##name +#else // define the object +#define osMutexDef(name) \ +uint32_t os_mutex_cb_##name[3]; \ +osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) } +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. +osStatus osMutexRelease (osMutexId mutex_id); + +/// Delete a Mutex that was created by \ref osMutexCreate. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. +osStatus osMutexDelete (osMutexId mutex_id); + +/// Get owner thread of a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return thread id or NULL +#if (osCMSIS < 0x20000U) +osThreadId osMutexGetOwner (osMutexId mutex_id); +#endif + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ +uint32_t os_semaphore_cb_##name[2]; \ +osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) } +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object used for managing resources. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count number of available resources. +/// \return semaphore ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); + +/// Delete a Semaphore that was created by \ref osSemaphoreCreate. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern osPoolDef_t os_pool_def_##name +#else // define the object +#define osPoolDef(name, no, type) \ +uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \ +osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), (os_pool_m_##name) } +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a memory pool. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a memory pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a specific memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block that is returned to the memory pool. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool Management available + + +// ==== Message Queue Management Functions ==== + +#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern osMessageQDef_t os_messageQ_def_##name +#else // define the object +#define osMessageQDef(name, queue_sz, type) \ +uint32_t os_messageQ_q_##name[4+(queue_sz)]; \ +osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), (os_messageQ_q_##name) } +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue. +/// \param[in] queue_def queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message or Wait for a Message from a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event information that includes status code. +/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +/// Get space in the Message Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \return the size of the space. +uint32_t osMessageGetSpace (osMessageQId queue_id); +#endif // Message Queues available + + +// ==== Mail Queue Management Functions ==== + +#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue +/// \param queue_sz maximum number of messages in queue +/// \param type data type of a single message element +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern osMailQDef_t os_mailQ_def_##name +#else // define the object +#define osMailQDef(name, queue_sz, type) \ +uint32_t os_mailQ_q_##name[4+(queue_sz)]; \ +uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \ +void * os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \ +osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize mail queue. +/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block from a mail and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a mail to a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. +osStatus osMailPut (osMailQId queue_id, void *mail); + +/// Get a mail from a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queues available + +void os_error_str (const char *fmt, ...); + +#ifdef __cplusplus +} +#endif + +#endif // _CMSIS_OS_H diff --git a/include/rtos/rtx/os_tcb.h b/include/rtos/rtx/os_tcb.h new file mode 100644 index 0000000..894aa19 --- /dev/null +++ b/include/rtos/rtx/os_tcb.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef OS_TCB_H +#define OS_TCB_H + +/* Types */ +typedef char S8; +typedef unsigned char U8; +typedef short S16; +typedef unsigned short U16; +typedef int S32; +typedef unsigned int U32; +typedef long long S64; +typedef unsigned long long U64; +typedef unsigned char BIT; +typedef unsigned int BOOL; +typedef void (*FUNCP)(void); + +typedef struct OS_TCB { + /* General part: identical for all implementations. */ + U8 cb_type; /* Control Block Type */ + U8 state; /* Task state */ + U8 prio; /* Execution priority */ + U8 task_id; /* Task ID value for optimized TCB access */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ + U16 interval_time; /* Time interval for periodic waits */ + U16 events; /* Event flags */ + U16 waits; /* Wait flags */ + void **msg; /* Direct message passing when task waits */ + + /* Hardware dependant part: specific for CM processor */ + U8 stack_frame; /* Stack frame: 0=Basic, 1=Extended */ + U8 reserved1; + U16 reserved2; + U32 priv_stack; /* Private stack size in bytes */ + U32 tsk_stack; /* Current task Stack pointer (R13) */ + U32 *stack; /* Pointer to Task Stack memory block */ + + /* Library dependant part */ +#if defined (__CC_ARM) && !defined (__MICROLIB) + /* A memory space for arm standard library. */ + U32 std_libspace[96/4]; +#endif +#if __RTX_CPU_STATISTICS__ + U32 swap_in_time; /* the task schedule in time */ + U32 swap_out_time; /* the task schedule out time */ + U32 rtime; /* the task runing time after startup */ + U8 *name; +#if TASK_HUNG_CHECK_ENABLED + U8 hung_check; + U32 hung_check_timeout; +#endif +#endif /* __RTX_CPU_STATISTICS__*/ + + /* Task entry point used for uVision debugger */ + FUNCP ptask; /* Task entry address */ +} *P_TCB; + +#endif diff --git a/include/rtos/rtx5/cmsis_os.h b/include/rtos/rtx5/cmsis_os.h new file mode 100644 index 0000000..541f094 --- /dev/null +++ b/include/rtos/rtx5/cmsis_os.h @@ -0,0 +1,928 @@ +/* + * Copyright (c) 2013-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. + * + * ---------------------------------------------------------------------- + * + * $Date: 18. June 2018 + * $Revision: V2.1.3 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h template header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedefs + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * Version 1.02 + * Control functions for short timeouts in microsecond resolution: + * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec + * Removed: osSignalGet + * Version 2.0.0 + * OS objects creation without macros (dynamic creation and resource allocation): + * - added: osXxxxNew functions which replace osXxxxCreate + * - added: osXxxxAttr_t structures + * - deprecated: osXxxxCreate functions, osXxxxDef_t structures + * - deprecated: osXxxxDef and osXxxx macros + * osStatus codes simplified and renamed to osStatus_t + * osEvent return structure deprecated + * Kernel: + * - added: osKernelInfo_t and osKernelGetInfo + * - added: osKernelState_t and osKernelGetState (replaces osKernelRunning) + * - added: osKernelLock, osKernelUnlock + * - added: osKernelSuspend, osKernelResume + * - added: osKernelGetTickCount, osKernelGetTickFreq + * - renamed osKernelSysTick to osKernelGetSysTimerCount + * - replaced osKernelSysTickFrequency with osKernelGetSysTimerFreq + * - deprecated osKernelSysTickMicroSec + * Thread: + * - extended number of thread priorities + * - renamed osPrioriry to osPrioriry_t + * - replaced osThreadCreate with osThreadNew + * - added: osThreadGetName + * - added: osThreadState_t and osThreadGetState + * - added: osThreadGetStackSize, osThreadGetStackSpace + * - added: osThreadSuspend, osThreadResume + * - added: osThreadJoin, osThreadDetach, osThreadExit + * - added: osThreadGetCount, osThreadEnumerate + * - added: Thread Flags (moved from Signals) + * Signals: + * - renamed osSignals to osThreadFlags (moved to Thread Flags) + * - changed return value of Set/Clear/Wait functions + * - Clear function limited to current running thread + * - extended Wait function (options) + * - added: osThreadFlagsGet + * Event Flags: + * - added new independent object for handling Event Flags + * Delay and Wait functions: + * - added: osDelayUntil + * - deprecated: osWait + * Timer: + * - replaced osTimerCreate with osTimerNew + * - added: osTimerGetName, osTimerIsRunning + * Mutex: + * - extended: attributes (Recursive, Priority Inherit, Robust) + * - replaced osMutexCreate with osMutexNew + * - renamed osMutexWait to osMutexAcquire + * - added: osMutexGetName, osMutexGetOwner + * Semaphore: + * - extended: maximum and initial token count + * - replaced osSemaphoreCreate with osSemaphoreNew + * - renamed osSemaphoreWait to osSemaphoreAcquire (changed return value) + * - added: osSemaphoreGetName, osSemaphoreGetCount + * Memory Pool: + * - using osMemoryPool prefix instead of osPool + * - replaced osPoolCreate with osMemoryPoolNew + * - extended osMemoryPoolAlloc (timeout) + * - added: osMemoryPoolGetName + * - added: osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize + * - added: osMemoryPoolGetCount, osMemoryPoolGetSpace + * - added: osMemoryPoolDelete + * - deprecated: osPoolCAlloc + * Message Queue: + * - extended: fixed size message instead of a single 32-bit value + * - using osMessageQueue prefix instead of osMessage + * - replaced osMessageCreate with osMessageQueueNew + * - updated: osMessageQueuePut, osMessageQueueGet + * - added: osMessageQueueGetName + * - added: osMessageQueueGetCapacity, osMessageQueueGetMsgSize + * - added: osMessageQueueGetCount, osMessageQueueGetSpace + * - added: osMessageQueueReset, osMessageQueueDelete + * Mail Queue: + * - deprecated (superseded by extended Message Queue functionality) + * Version 2.1.0 + * Support for critical and uncritical sections (nesting safe): + * - updated: osKernelLock, osKernelUnlock + * - added: osKernelRestoreLock + * Updated Thread and Event Flags: + * - changed flags parameter and return type from int32_t to uint32_t + * Version 2.1.1 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetTickCount, osKernelGetTickFreq + * Changed Kernel Tick type to uint32_t: + * - updated: osKernelGetTickCount, osDelayUntil + * Version 2.1.2 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetInfo, osKernelGetState + * Version 2.1.3 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osThreadGetId + *---------------------------------------------------------------------------*/ + +#ifndef CMSIS_OS_H_ +#define CMSIS_OS_H_ + +/// \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x20001U ///< API version (main[31:16].sub[15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_KERNEL 0x10000U ///< RTOS identification and version (main[31:16].sub[15:0]) + +/// \note CAN BE CHANGED: \b osKernelSystemId identifies the underlying RTOS kernel. +#define osKernelSystemId "KERNEL V1.0" ///< RTOS identification string + +/// \note CAN BE CHANGED: \b osFeature_xxx identifies RTOS features. +#define osFeature_MainThread 0 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Signals 16U ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 65535U ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available +#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available + +#if (osCMSIS >= 0x20000U) +#include "cmsis_os2.h" +#else +#include +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumerations, structures, defines ==== + +/// Priority values. +#if (osCMSIS < 0x20000U) +typedef enum { + osPriorityIdle = -3, ///< Priority: idle (lowest) + osPriorityLow = -2, ///< Priority: low + osPriorityBelowNormal = -1, ///< Priority: below normal + osPriorityNormal = 0, ///< Priority: normal (default) + osPriorityAboveNormal = +1, ///< Priority: above normal + osPriorityHigh = +2, ///< Priority: high + osPriorityRealtime = +3, ///< Priority: realtime (highest) + osPriorityError = 0x84, ///< System cannot determine priority or illegal priority. + osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osPriority; +#else +#define osPriority osPriority_t +#endif + +/// Entry point of a thread. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +typedef void (*os_ptimer) (void const *argument); + +/// Timer type. +#if (osCMSIS < 0x20000U) +typedef enum { + osTimerOnce = 0, ///< One-shot timer. + osTimerPeriodic = 1 ///< Repeating timer. +} os_timer_type; +#else +#define os_timer_type osTimerType_t +#endif + +/// Timeout value. +#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. + +/// Status code values returned by CMSIS-RTOS functions. +#if (osCMSIS < 0x20000U) +typedef enum { + osOK = 0, ///< Function completed; no error or event occurred. + osEventSignal = 0x08, ///< Function completed; signal event occurred. + osEventMessage = 0x10, ///< Function completed; message event occurred. + osEventMail = 0x20, ///< Function completed; mail event occurred. + osEventTimeout = 0x40, ///< Function completed; timeout occurred. + osErrorParameter = 0x80, ///< Parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< Resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< Resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< Function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< System cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< Value of a parameter is out of range. + osErrorOS = 0xFF, ///< Unspecified RTOS error: run-time error but no other error message fits. + osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osStatus; +#else +typedef osStatus_t osStatus; +#define osEventSignal (0x08) +#define osEventMessage (0x10) +#define osEventMail (0x20) +#define osEventTimeout (0x40) +#define osErrorOS osError +#define osErrorTimeoutResource osErrorTimeout +#define osErrorISRRecursive (-126) +#define osErrorValue (-127) +#define osErrorPriority (-128) +#define os_status_reserved osStatusReserved +#endif + + +// >>> the following data type definitions may be adapted towards a specific RTOS + +/// Thread ID identifies the thread. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef void *osThreadId; +#else +#define osThreadId osThreadId_t +#endif + +/// Timer ID identifies the timer. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef void *osTimerId; +#else +#define osTimerId osTimerId_t +#endif + +/// Mutex ID identifies the mutex. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef void *osMutexId; +#else +#define osMutexId osMutexId_t +#endif + +/// Semaphore ID identifies the semaphore. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef void *osSemaphoreId; +#else +#define osSemaphoreId osSemaphoreId_t +#endif + +/// Pool ID identifies the memory pool. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +typedef void *osPoolId; + +/// Message ID identifies the message queue. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +typedef void *osMessageQId; + +/// Mail ID identifies the mail queue. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +typedef void *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t instances; ///< maximum number of instances of that thread function + uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size +} osThreadDef_t; +#else +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osThreadAttr_t attr; ///< thread attributes +} osThreadDef_t; +#endif + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function +} osTimerDef_t; +#else +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + osTimerAttr_t attr; ///< timer attributes +} osTimerDef_t; +#endif + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_mutex_def { + uint32_t dummy; ///< dummy value +} osMutexDef_t; +#else +#define osMutexDef_t osMutexAttr_t +#endif + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_semaphore_def { + uint32_t dummy; ///< dummy value +} osSemaphoreDef_t; +#else +#define osSemaphoreDef_t osSemaphoreAttr_t +#endif + +/// Definition structure for memory block allocation. +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; +#else +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + osMemoryPoolAttr_t attr; ///< memory pool attributes +} osPoolDef_t; +#endif + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + void *pool; ///< memory array for messages +} osMessageQDef_t; +#else +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + osMessageQueueAttr_t attr; ///< message queue attributes +} osMessageQDef_t; +#endif + +/// Definition structure for mail queue. +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; +#else +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *mail; ///< pointer to mail + osMemoryPoolAttr_t mp_attr; ///< memory pool attributes + osMessageQueueAttr_t mq_attr; ///< message queue attributes +} osMailQDef_t; +#endif + + +/// Event structure contains detailed information about an event. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Management Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osKernelInitialize (void); +#endif + +/// Start the RTOS Kernel scheduler. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osKernelStart (void); +#endif + +/// Check if the RTOS kernel is already started. +/// \return 0 RTOS is not started, 1 RTOS is started. +#if (osCMSIS < 0x20000U) +int32_t osKernelRunning(void); +#endif + +#if (defined(osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available + +/// Get the RTOS kernel system timer counter. +/// \return RTOS kernel system timer as 32-bit value +#if (osCMSIS < 0x20000U) +uint32_t osKernelSysTick (void); +#else +#define osKernelSysTick osKernelGetSysTimerCount +#endif + +/// The RTOS kernel system timer frequency in Hz. +/// \note Reflects the system timer setting and is typically defined in a configuration file. +#if (osCMSIS < 0x20000U) +#define osKernelSysTickFrequency 100000000 +#endif + +/// Convert a microseconds value to a RTOS kernel system timer value. +/// \param microsec time value in microseconds. +/// \return time value normalized to the \ref osKernelSysTickFrequency +#if (osCMSIS < 0x20000U) +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) +#else +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * osKernelGetSysTimerFreq()) / 1000000) +#endif + +#endif // System Timer available + + +// ==== Thread Management Functions ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (instances), (stacksz) } +#else +#define osThreadDef(name, priority, instances, stacksz, task_name) \ +uint64_t os_thread_def_stack_##name [(8*((stacksz+7)/8)) / sizeof(uint64_t)]; \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), \ + { task_name, osThreadDetached, NULL, 0U, os_thread_def_stack_##name, 8*((stacksz+7)/8), (priority), 0U, 0U } } +#endif +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +#if (osCMSIS < 0x20000U) +osThreadId osThreadGetId (void); +#endif + +/// Change priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); +#endif + +/// Get current priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the specified thread. +#if (osCMSIS < 0x20000U) +osPriority osThreadGetPriority (osThreadId thread_id); +#endif + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadYield (void); +#endif + +/// Terminate execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadTerminate (osThreadId thread_id); +#endif + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flag information or error code. +osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osDelay (uint32_t millisec); +#endif + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== + +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern const osTimerDef_t os_timer_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osTimerDef(name, function) \ +const osTimerDef_t os_timer_def_##name = { (function) } +#else +#define osTimerDef(name, function) \ +const osTimerDef_t os_timer_def_##name = \ +{ (function), { NULL, 0U, NULL, 0U } } +#endif +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create and Initialize a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value of the timer. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); +#endif + +/// Stop a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerStop (osTimerId timer_id); +#endif + +/// Delete a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerDelete (osTimerId timer_id); +#endif + + +// ==== Mutex Management Functions ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern const osMutexDef_t os_mutex_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osMutexDef(name) \ +const osMutexDef_t os_mutex_def_##name = { 0 } +#else +#define osMutexDef(name) \ +const osMutexDef_t os_mutex_def_##name = \ +{ NULL, osMutexRecursive | osMutexPrioInherit | osMutexRobust, NULL, 0U } +#endif +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); +#else +#define osMutexWait osMutexAcquire +#endif + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexRelease (osMutexId mutex_id); +#endif + +/// Delete a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexDelete (osMutexId mutex_id); +#endif + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0U)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osSemaphoreDef(name) \ +const osSemaphoreDef_t os_semaphore_def_##name = { 0 } +#else +#define osSemaphoreDef(name) \ +const osSemaphoreDef_t os_semaphore_def_##name = \ +{ NULL, 0U, NULL, 0U } +#endif +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count maximum and initial number of available tokens. +/// \return semaphore ID for reference by other functions or NULL in case of error. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); +#endif + +/// Delete a Semaphore object. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); +#endif + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined(osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern const osPoolDef_t os_pool_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osPoolDef(name, no, type) \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), NULL } +#else +#define osPoolDef(name, no, type) \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), { NULL, 0U, NULL, 0U, NULL, 0U } } +#endif +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a Memory Pool object. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a Memory Pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a Memory Pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool available + + +// ==== Message Queue Management Functions ==== + +#if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queue available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern const osMessageQDef_t os_messageQ_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osMessageQDef(name, queue_sz, type) \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), NULL } +#else +#define osMessageQDef(name, queue_sz, type) \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), { NULL, 0U, NULL, 0U, NULL, 0U } } +#endif +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue object. +/// \param[in] queue_def message queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event information that includes status code. +osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +uint32_t osMessageGetSpace (osMessageQId queue_id); +#endif // Message Queue available + + +// ==== Mail Queue Management Functions ==== + +#if (defined(osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queue available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of mails in the queue. +/// \param type data type of a single mail element. +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern const osMailQDef_t os_mailQ_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osMailQDef(name, queue_sz, type) \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), NULL } +#else +#define osMailQDef(name, queue_sz, type) \ +static void *os_mail_p_##name[2]; \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), (&os_mail_p_##name), \ + { NULL, 0U, NULL, 0U, NULL, 0U }, \ + { NULL, 0U, NULL, 0U, NULL, 0U } } +#endif +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize a Mail Queue object. +/// \param[in] queue_def mail queue definition referenced with \ref osMailQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block for mail from a mail memory pool. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block for mail from a mail memory pool and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a Mail into a Queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to memory with mail to put into a queue. +/// \return status code that indicates the execution status of the function. +osStatus osMailPut (osMailQId queue_id, const void *mail); + +/// Get a Mail from a Queue or timeout if Queue is empty. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event information that includes status code. +osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block by returning it to a mail memory pool. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queue available + +#if !(osCMSIS < 0x20000U) +const char *osGetThreadName (void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // CMSIS_OS_H_ diff --git a/include/rtos/rtx5/cmsis_os2.h b/include/rtos/rtx5/cmsis_os2.h new file mode 100644 index 0000000..555496b --- /dev/null +++ b/include/rtos/rtx5/cmsis_os2.h @@ -0,0 +1,760 @@ +/* + * Copyright (c) 2013-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. + * + * ---------------------------------------------------------------------- + * + * $Date: 18. June 2018 + * $Revision: V2.1.3 + * + * Project: CMSIS-RTOS2 API + * Title: cmsis_os2.h header file + * + * Version 2.1.3 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osThreadGetId + * Version 2.1.2 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetInfo, osKernelGetState + * Version 2.1.1 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetTickCount, osKernelGetTickFreq + * Changed Kernel Tick type to uint32_t: + * - updated: osKernelGetTickCount, osDelayUntil + * Version 2.1.0 + * Support for critical and uncritical sections (nesting safe): + * - updated: osKernelLock, osKernelUnlock + * - added: osKernelRestoreLock + * Updated Thread and Event Flags: + * - changed flags parameter and return type from int32_t to uint32_t + * Version 2.0.0 + * Initial Release + *---------------------------------------------------------------------------*/ + +#ifndef CMSIS_OS2_H_ +#define CMSIS_OS2_H_ + +#ifndef __NO_RETURN +#if defined(__CC_ARM) +#define __NO_RETURN __declspec(noreturn) +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#define __NO_RETURN __attribute__((__noreturn__)) +#elif defined(__GNUC__) +#define __NO_RETURN __attribute__((__noreturn__)) +#elif defined(__ICCARM__) +#define __NO_RETURN __noreturn +#else +#define __NO_RETURN +#endif +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumerations, structures, defines ==== + +/// Version information. +typedef struct { + uint32_t api; ///< API version (major.minor.rev: mmnnnrrrr dec). + uint32_t kernel; ///< Kernel version (major.minor.rev: mmnnnrrrr dec). +} osVersion_t; + +/// Kernel state. +typedef enum { + osKernelInactive = 0, ///< Inactive. + osKernelReady = 1, ///< Ready. + osKernelRunning = 2, ///< Running. + osKernelLocked = 3, ///< Locked. + osKernelSuspended = 4, ///< Suspended. + osKernelError = -1, ///< Error. + osKernelReserved = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization. +} osKernelState_t; + +/// Thread state. +typedef enum { + osThreadInactive = 0, ///< Inactive. + osThreadReady = 1, ///< Ready. + osThreadRunning = 2, ///< Running. + osThreadBlocked = 3, ///< Blocked. + osThreadTerminated = 4, ///< Terminated. + osThreadError = -1, ///< Error. + osThreadReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osThreadState_t; + +/// Priority values. +typedef enum { + osPriorityNone = 0, ///< No priority (not initialized). + osPriorityIdle = 1, ///< Reserved for Idle thread. + osPriorityLow = 8, ///< Priority: low + osPriorityLow1 = 8+1, ///< Priority: low + 1 + osPriorityLow2 = 8+2, ///< Priority: low + 2 + osPriorityLow3 = 8+3, ///< Priority: low + 3 + osPriorityLow4 = 8+4, ///< Priority: low + 4 + osPriorityLow5 = 8+5, ///< Priority: low + 5 + osPriorityLow6 = 8+6, ///< Priority: low + 6 + osPriorityLow7 = 8+7, ///< Priority: low + 7 + osPriorityBelowNormal = 16, ///< Priority: below normal + osPriorityBelowNormal1 = 16+1, ///< Priority: below normal + 1 + osPriorityBelowNormal2 = 16+2, ///< Priority: below normal + 2 + osPriorityBelowNormal3 = 16+3, ///< Priority: below normal + 3 + osPriorityBelowNormal4 = 16+4, ///< Priority: below normal + 4 + osPriorityBelowNormal5 = 16+5, ///< Priority: below normal + 5 + osPriorityBelowNormal6 = 16+6, ///< Priority: below normal + 6 + osPriorityBelowNormal7 = 16+7, ///< Priority: below normal + 7 + osPriorityNormal = 24, ///< Priority: normal + osPriorityNormal1 = 24+1, ///< Priority: normal + 1 + osPriorityNormal2 = 24+2, ///< Priority: normal + 2 + osPriorityNormal3 = 24+3, ///< Priority: normal + 3 + osPriorityNormal4 = 24+4, ///< Priority: normal + 4 + osPriorityNormal5 = 24+5, ///< Priority: normal + 5 + osPriorityNormal6 = 24+6, ///< Priority: normal + 6 + osPriorityNormal7 = 24+7, ///< Priority: normal + 7 + osPriorityAboveNormal = 32, ///< Priority: above normal + osPriorityAboveNormal1 = 32+1, ///< Priority: above normal + 1 + osPriorityAboveNormal2 = 32+2, ///< Priority: above normal + 2 + osPriorityAboveNormal3 = 32+3, ///< Priority: above normal + 3 + osPriorityAboveNormal4 = 32+4, ///< Priority: above normal + 4 + osPriorityAboveNormal5 = 32+5, ///< Priority: above normal + 5 + osPriorityAboveNormal6 = 32+6, ///< Priority: above normal + 6 + osPriorityAboveNormal7 = 32+7, ///< Priority: above normal + 7 + osPriorityHigh = 40, ///< Priority: high + osPriorityHigh1 = 40+1, ///< Priority: high + 1 + osPriorityHigh2 = 40+2, ///< Priority: high + 2 + osPriorityHigh3 = 40+3, ///< Priority: high + 3 + osPriorityHigh4 = 40+4, ///< Priority: high + 4 + osPriorityHigh5 = 40+5, ///< Priority: high + 5 + osPriorityHigh6 = 40+6, ///< Priority: high + 6 + osPriorityHigh7 = 40+7, ///< Priority: high + 7 + osPriorityRealtime = 48, ///< Priority: realtime + osPriorityRealtime1 = 48+1, ///< Priority: realtime + 1 + osPriorityRealtime2 = 48+2, ///< Priority: realtime + 2 + osPriorityRealtime3 = 48+3, ///< Priority: realtime + 3 + osPriorityRealtime4 = 48+4, ///< Priority: realtime + 4 + osPriorityRealtime5 = 48+5, ///< Priority: realtime + 5 + osPriorityRealtime6 = 48+6, ///< Priority: realtime + 6 + osPriorityRealtime7 = 48+7, ///< Priority: realtime + 7 + osPriorityISR = 56, ///< Reserved for ISR deferred thread. + osPriorityError = -1, ///< System cannot determine priority or illegal priority. + osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osPriority_t; + +/// Entry point of a thread. +typedef void (*osThreadFunc_t) (void *argument); + +/// Timer callback function. +typedef void (*osTimerFunc_t) (void *argument); + +/// Timer type. +typedef enum { + osTimerOnce = 0, ///< One-shot timer. + osTimerPeriodic = 1 ///< Repeating timer. +} osTimerType_t; + +// Timeout value. +#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. + +// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait). +#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default). +#define osFlagsWaitAll 0x00000001U ///< Wait for all flags. +#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for. + +// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). +#define osFlagsError 0x80000000U ///< Error indicator. +#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1). +#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2). +#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3). +#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4). +#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6). + +// Thread attributes (attr_bits in \ref osThreadAttr_t). +#define osThreadDetached 0x00000000U ///< Thread created in detached mode (default) +#define osThreadJoinable 0x00000001U ///< Thread created in joinable mode + +// Mutex attributes (attr_bits in \ref osMutexAttr_t). +#define osMutexRecursive 0x00000001U ///< Recursive mutex. +#define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol. +#define osMutexRobust 0x00000008U ///< Robust mutex. + +/// Status code values returned by CMSIS-RTOS functions. +typedef enum { + osOK = 0, ///< Operation completed successfully. + osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits. + osErrorTimeout = -2, ///< Operation not completed within the timeout period. + osErrorResource = -3, ///< Resource not available. + osErrorParameter = -4, ///< Parameter error. + osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osStatus_t; + + +/// \details Thread ID identifies the thread. +typedef void *osThreadId_t; + +/// \details Timer ID identifies the timer. +typedef void *osTimerId_t; + +/// \details Event Flags ID identifies the event flags. +typedef void *osEventFlagsId_t; + +/// \details Mutex ID identifies the mutex. +typedef void *osMutexId_t; + +/// \details Semaphore ID identifies the semaphore. +typedef void *osSemaphoreId_t; + +/// \details Memory Pool ID identifies the memory pool. +typedef void *osMemoryPoolId_t; + +/// \details Message Queue ID identifies the message queue. +typedef void *osMessageQueueId_t; + + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + + +/// Attributes structure for thread. +typedef struct { + const char *name; ///< name of the thread + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *stack_mem; ///< memory for stack + uint32_t stack_size; ///< size of stack + osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) + TZ_ModuleId_t tz_module; ///< TrustZone module identifier + uint32_t reserved; ///< reserved (must be 0) +} osThreadAttr_t; + +/// Attributes structure for timer. +typedef struct { + const char *name; ///< name of the timer + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osTimerAttr_t; + +/// Attributes structure for event flags. +typedef struct { + const char *name; ///< name of the event flags + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osEventFlagsAttr_t; + +/// Attributes structure for mutex. +typedef struct { + const char *name; ///< name of the mutex + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osMutexAttr_t; + +/// Attributes structure for semaphore. +typedef struct { + const char *name; ///< name of the semaphore + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osSemaphoreAttr_t; + +/// Attributes structure for memory pool. +typedef struct { + const char *name; ///< name of the memory pool + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mp_mem; ///< memory for data storage + uint32_t mp_size; ///< size of provided memory for data storage +} osMemoryPoolAttr_t; + +/// Attributes structure for message queue. +typedef struct { + const char *name; ///< name of the message queue + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mq_mem; ///< memory for data storage + uint32_t mq_size; ///< size of provided memory for data storage +} osMessageQueueAttr_t; + + +// ==== Kernel Management Functions ==== + +/// Initialize the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelInitialize (void); + +/// Get RTOS Kernel Information. +/// \param[out] version pointer to buffer for retrieving version information. +/// \param[out] id_buf pointer to buffer for retrieving kernel identification string. +/// \param[in] id_size size of buffer for kernel identification string. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); + +/// Get the current RTOS Kernel state. +/// \return current RTOS Kernel state. +osKernelState_t osKernelGetState (void); + +/// Start the RTOS Kernel scheduler. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelStart (void); + +/// Lock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelLock (void); + +/// Unlock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelUnlock (void); + +/// Restore the RTOS Kernel scheduler lock state. +/// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock. +/// \return new lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelRestoreLock (int32_t lock); + +/// Suspend the RTOS Kernel scheduler. +/// \return time in ticks, for how long the system can sleep or power-down. +uint32_t osKernelSuspend (void); + +/// Resume the RTOS Kernel scheduler. +/// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode. +void osKernelResume (uint32_t sleep_ticks); + +/// Get the RTOS kernel tick count. +/// \return RTOS kernel current tick count. +uint32_t osKernelGetTickCount (void); + +/// Get the RTOS kernel tick frequency. +/// \return frequency of the kernel tick in hertz, i.e. kernel ticks per second. +uint32_t osKernelGetTickFreq (void); + +/// Get the RTOS kernel system timer count. +/// \return RTOS kernel current system timer count as 32-bit value. +uint32_t osKernelGetSysTimerCount (void); + +/// Get the RTOS kernel system timer frequency. +/// \return frequency of the system timer in hertz, i.e. timer ticks per second. +uint32_t osKernelGetSysTimerFreq (void); + + +// ==== Thread Management Functions ==== + +/// Create a thread and add it to Active Threads. +/// \param[in] func thread function. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \param[in] attr thread attributes; NULL: default values. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); + +/// Get name of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return name as null-terminated string. +const char *osThreadGetName (osThreadId_t thread_id); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadGetId (void); + +/// Get current thread state of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current thread state of the specified thread. +osThreadState_t osThreadGetState (osThreadId_t thread_id); + +/// Get stack size of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return stack size in bytes. +uint32_t osThreadGetStackSize (osThreadId_t thread_id); + +/// Get available stack space of a thread based on stack watermark recording during execution. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return remaining stack space in bytes. +uint32_t osThreadGetStackSpace (osThreadId_t thread_id); + +/// Change priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); + +/// Get current priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current priority value of the specified thread. +osPriority_t osThreadGetPriority (osThreadId_t thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadYield (void); + +/// Suspend execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSuspend (osThreadId_t thread_id); + +/// Resume execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadResume (osThreadId_t thread_id); + +/// Detach a thread (thread storage can be reclaimed when thread terminates). +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadDetach (osThreadId_t thread_id); + +/// Wait for specified thread to terminate. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadJoin (osThreadId_t thread_id); + +/// Terminate execution of current running thread. +__NO_RETURN void osThreadExit (void); + +/// Terminate execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadTerminate (osThreadId_t thread_id); + +/// Get number of active threads. +/// \return number of active threads. +uint32_t osThreadGetCount (void); + +/// Enumerate active threads. +/// \param[out] thread_array pointer to array for retrieving thread IDs. +/// \param[in] array_items maximum number of items in array for retrieving thread IDs. +/// \return number of enumerated threads. +uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items); + + +// ==== Thread Flags Functions ==== + +/// Set the specified Thread Flags of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] flags specifies the flags of the thread that shall be set. +/// \return thread flags after setting or error code if highest bit set. +uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); + +/// Clear the specified Thread Flags of current running thread. +/// \param[in] flags specifies the flags of the thread that shall be cleared. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsClear (uint32_t flags); + +/// Get the current Thread Flags of current running thread. +/// \return current thread flags. +uint32_t osThreadFlagsGet (void); + +/// Wait for one or more Thread Flags of the current running thread to become signaled. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); + +#if TASK_HUNG_CHECK_ENABLED +/// enable/disable the hung check feature of an active thread +osStatus_t osThreadSetHungCheck (osThreadId_t thread_id, int32_t enable, uint32_t timeout); +#endif + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value +/// \return status code that indicates the execution status of the function. +osStatus_t osDelay (uint32_t ticks); + +/// Wait until specified time. +/// \param[in] ticks absolute time in ticks +/// \return status code that indicates the execution status of the function. +osStatus_t osDelayUntil (uint32_t ticks); + + +// ==== Timer Management Functions ==== + +/// Create and Initialize a timer. +/// \param[in] func function pointer to callback function. +/// \param[in] type \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer callback function. +/// \param[in] attr timer attributes; NULL: default values. +/// \return timer ID for reference by other functions or NULL in case of error. +osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); + +/// Get name of a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return name as null-terminated string. +const char *osTimerGetName (osTimerId_t timer_id); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks); + +/// Stop a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStop (osTimerId_t timer_id); + +/// Check if a timer is running. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return 0 not running, 1 running. +uint32_t osTimerIsRunning (osTimerId_t timer_id); + +/// Delete a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerDelete (osTimerId_t timer_id); + + +// ==== Event Flags Management Functions ==== + +/// Create and Initialize an Event Flags object. +/// \param[in] attr event flags attributes; NULL: default values. +/// \return event flags ID for reference by other functions or NULL in case of error. +osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr); + +/// Get name of an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return name as null-terminated string. +const char *osEventFlagsGetName (osEventFlagsId_t ef_id); + +/// Set the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be set. +/// \return event flags after setting or error code if highest bit set. +uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); + +/// Clear the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be cleared. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); + +/// Get the current Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return current event flags. +uint32_t osEventFlagsGet (osEventFlagsId_t ef_id); + +/// Wait for one or more Event Flags to become signaled. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); + +/// Delete an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id); + + +// ==== Mutex Management Functions ==== + +/// Create and Initialize a Mutex object. +/// \param[in] attr mutex attributes; NULL: default values. +/// \return mutex ID for reference by other functions or NULL in case of error. +osMutexId_t osMutexNew (const osMutexAttr_t *attr); + +/// Get name of a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return name as null-terminated string. +const char *osMutexGetName (osMutexId_t mutex_id); + +/// Acquire a Mutex or timeout if it is locked. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); + +/// Release a Mutex that was acquired by \ref osMutexAcquire. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexRelease (osMutexId_t mutex_id); + +/// Get Thread which owns a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return thread ID of owner thread or NULL when mutex was not acquired. +osThreadId_t osMutexGetOwner (osMutexId_t mutex_id); + +/// Delete a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexDelete (osMutexId_t mutex_id); + + +// ==== Semaphore Management Functions ==== + +/// Create and Initialize a Semaphore object. +/// \param[in] max_count maximum number of available tokens. +/// \param[in] initial_count initial number of available tokens. +/// \param[in] attr semaphore attributes; NULL: default values. +/// \return semaphore ID for reference by other functions or NULL in case of error. +osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); + +/// Get name of a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return name as null-terminated string. +const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id); + +/// Acquire a Semaphore token or timeout if no tokens are available. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); + +/// Release a Semaphore token up to the initial maximum count. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id); + +/// Get current Semaphore token count. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return number of tokens available. +uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id); + +/// Delete a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id); + + +// ==== Memory Pool Management Functions ==== + +/// Create and Initialize a Memory Pool object. +/// \param[in] block_count maximum number of memory blocks in memory pool. +/// \param[in] block_size memory block size in bytes. +/// \param[in] attr memory pool attributes; NULL: default values. +/// \return memory pool ID for reference by other functions or NULL in case of error. +osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr); + +/// Get name of a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return name as null-terminated string. +const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id); + +/// Allocate a memory block from a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return address of the allocated memory block or NULL in case of no memory is available. +void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); + +/// Get maximum number of memory blocks in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return maximum number of memory blocks. +uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id); + +/// Get memory block size in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return memory block size in bytes. +uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks used in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks used. +uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks available in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks available. +uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id); + +/// Delete a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id); + + +// ==== Message Queue Management Functions ==== + +/// Create and Initialize a Message Queue object. +/// \param[in] msg_count maximum number of messages in queue. +/// \param[in] msg_size maximum message size in bytes. +/// \param[in] attr message queue attributes; NULL: default values. +/// \return message queue ID for reference by other functions or NULL in case of error. +osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); + +/// Get name of a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return name as null-terminated string. +const char *osMessageQueueGetName (osMessageQueueId_t mq_id); + +/// Put a Message into a Queue or timeout if Queue is full. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[in] msg_ptr pointer to buffer with message to put into a queue. +/// \param[in] msg_prio message priority. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[out] msg_ptr pointer to buffer for message to get from a queue. +/// \param[out] msg_prio pointer to buffer for message priority or NULL. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); + +/// Get maximum number of messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum number of messages. +uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id); + +/// Get maximum message size in a Memory Pool. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum message size in bytes. +uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id); + +/// Get number of queued messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of queued messages. +uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id); + +/// Get number of available slots for messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of available slots for messages. +uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id); + +/// Reset a Message Queue to initial empty state. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id); + +/// Delete a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); + + +#ifdef __cplusplus +} +#endif + +#endif // CMSIS_OS2_H_ diff --git a/include/rtos/rtx5/os_tick.h b/include/rtos/rtx5/os_tick.h new file mode 100644 index 0000000..8f7cdf6 --- /dev/null +++ b/include/rtos/rtx5/os_tick.h @@ -0,0 +1,71 @@ +/**************************************************************************//** + * @file os_tick.h + * @brief CMSIS OS Tick header file + * @version V1.0.1 + * @date 24. November 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017-2017 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 OS_TICK_H +#define OS_TICK_H + +#include + +/// IRQ Handler. +#ifndef IRQHANDLER_T +#define IRQHANDLER_T +typedef void (*IRQHandler_t) (void); +#endif + +/// Setup OS Tick timer to generate periodic RTOS Kernel Ticks +/// \param[in] freq tick frequency in Hz +/// \param[in] handler tick IRQ handler +/// \return 0 on success, -1 on error. +int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler); + +/// Enable OS Tick timer interrupt +void OS_Tick_Enable (void); + +/// Disable OS Tick timer interrupt +void OS_Tick_Disable (void); + +/// Acknowledge execution of OS Tick timer interrupt +void OS_Tick_AcknowledgeIRQ (void); + +/// Get OS Tick timer IRQ number +/// \return OS Tick IRQ number +int32_t OS_Tick_GetIRQn (void); + +/// Get OS Tick timer clock frequency +/// \return OS Tick timer clock frequency in Hz +uint32_t OS_Tick_GetClock (void); + +/// Get OS Tick timer interval reload value +/// \return OS Tick timer interval reload value +uint32_t OS_Tick_GetInterval (void); + +/// Get OS Tick timer counter value +/// \return OS Tick timer counter value +uint32_t OS_Tick_GetCount (void); + +/// Get OS Tick timer overflow status +/// \return OS Tick overflow status (1 - overflow, 0 - no overflow). +uint32_t OS_Tick_GetOverflow (void); + +#endif /* OS_TICK_H */ diff --git a/include/rtos/rtx5/rtx_evr.h b/include/rtos/rtx5/rtx_evr.h new file mode 100644 index 0000000..fa80853 --- /dev/null +++ b/include/rtos/rtx5/rtx_evr.h @@ -0,0 +1,1974 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: RTX Event Recorder definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_EVR_H_ +#define RTX_EVR_H_ + +#include "cmsis_os2.h" // CMSIS RTOS API +#include "rtx_config.h" // RTX Configuration +#include "rtx_os.h" // RTX OS definitions + +// Initial Thread configuration covered also Thread Flags and Generic Wait +#ifndef OS_EVR_THFLAGS +#define OS_EVR_THFLAGS OS_EVR_THREAD +#endif +#ifndef OS_EVR_WAIT +#define OS_EVR_WAIT OS_EVR_THREAD +#endif + +#ifdef _RTE_ +#include "RTE_Components.h" +#endif + +#ifdef RTE_Compiler_EventRecorder + +//lint -emacro((835,845),EventID) [MISRA Note 13] + +#include "EventRecorder.h" +#include "EventRecorderConf.h" + +#if ((defined(OS_EVR_INIT) && (OS_EVR_INIT != 0)) || (EVENT_TIMESTAMP_SOURCE == 2)) +#ifndef EVR_RTX_KERNEL_GET_STATE_DISABLE +#define EVR_RTX_KERNEL_GET_STATE_DISABLE +#endif +#endif + +#if (EVENT_TIMESTAMP_SOURCE == 2) +#ifndef EVR_RTX_KERNEL_GET_SYS_TIMER_COUNT_DISABLE +#define EVR_RTX_KERNEL_GET_SYS_TIMER_COUNT_DISABLE +#endif +#ifndef EVR_RTX_KERNEL_GET_SYS_TIMER_FREQ_DISABLE +#define EVR_RTX_KERNEL_GET_SYS_TIMER_FREQ_DISABLE +#endif +#endif + +/// RTOS component number +#define EvtRtxMemoryNo (0xF0U) +#define EvtRtxKernelNo (0xF1U) +#define EvtRtxThreadNo (0xF2U) +#define EvtRtxThreadFlagsNo (0xF4U) +#define EvtRtxWaitNo (0xF3U) +#define EvtRtxTimerNo (0xF6U) +#define EvtRtxEventFlagsNo (0xF5U) +#define EvtRtxMutexNo (0xF7U) +#define EvtRtxSemaphoreNo (0xF8U) +#define EvtRtxMemoryPoolNo (0xF9U) +#define EvtRtxMessageQueueNo (0xFAU) + +#endif // RTE_Compiler_EventRecorder + + +/// Extended Status codes +#define osRtxErrorKernelNotReady (-7) +#define osRtxErrorKernelNotRunning (-8) +#define osRtxErrorInvalidControlBlock (-9) +#define osRtxErrorInvalidDataMemory (-10) +#define osRtxErrorInvalidThreadStack (-11) +#define osRtxErrorInvalidPriority (-12) +#define osRtxErrorThreadNotJoinable (-13) +#define osRtxErrorMutexNotOwned (-14) +#define osRtxErrorMutexNotLocked (-15) +#define osRtxErrorMutexLockLimit (-16) +#define osRtxErrorSemaphoreCountLimit (-17) +#define osRtxErrorTZ_InitContext_S (-18) +#define osRtxErrorTZ_AllocContext_S (-19) +#define osRtxErrorTZ_FreeContext_S (-20) +#define osRtxErrorTZ_LoadContext_S (-21) +#define osRtxErrorTZ_SaveContext_S (-22) + + +// ==== Memory Events ==== + +/** + \brief Event on memory initialization (Op) + \param[in] mem pointer to memory pool. + \param[in] size size of a memory pool in bytes. + \param[in] result execution status: 1 - success, 0 - failure. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_INIT_DISABLE)) +extern void EvrRtxMemoryInit (void *mem, uint32_t size, uint32_t result); +#else +#define EvrRtxMemoryInit(mem, size, result) +#endif + +/** + \brief Event on memory allocate (Op) + \param[in] mem pointer to memory pool. + \param[in] size size of a memory block in bytes. + \param[in] type memory block type: 0 - generic, 1 - control block. + \param[in] block pointer to allocated memory block or NULL in case of no memory is available. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_ALLOC_DISABLE)) +extern void EvrRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type, void *block); +#else +#define EvrRtxMemoryAlloc(mem, size, type, block) +#endif + +/** + \brief Event on memory free (Op) + \param[in] mem pointer to memory pool. + \param[in] block memory block to be returned to the memory pool. + \param[in] result execution status: 1 - success, 0 - failure. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_FREE_DISABLE)) +extern void EvrRtxMemoryFree (void *mem, void *block, uint32_t result); +#else +#define EvrRtxMemoryFree(mem, block, result) +#endif + +/** + \brief Event on memory block initialization (Op) + \param[in] mp_info memory pool info. + \param[in] block_count maximum number of memory blocks in memory pool. + \param[in] block_size size of a memory block in bytes. + \param[in] block_mem pointer to memory for block storage. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_INIT_DISABLE)) +extern void EvrRtxMemoryBlockInit (osRtxMpInfo_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem); +#else +#define EvrRtxMemoryBlockInit(mp_info, block_count, block_size, block_mem) +#endif + +/** + \brief Event on memory block alloc (Op) + \param[in] mp_info memory pool info. + \param[in] block address of the allocated memory block or NULL in case of no memory is available. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_ALLOC_DISABLE)) +extern void EvrRtxMemoryBlockAlloc (osRtxMpInfo_t *mp_info, void *block); +#else +#define EvrRtxMemoryBlockAlloc(mp_info, block) +#endif + +/** + \brief Event on memory block free (Op) + \param[in] mp_info memory pool info. + \param[in] block address of the allocated memory block to be returned to the memory pool. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_FREE_DISABLE)) +extern void EvrRtxMemoryBlockFree (osRtxMpInfo_t *mp_info, void *block, int32_t status); +#else +#define EvrRtxMemoryBlockFree(mp_info, block, status) +#endif + + +// ==== Kernel Events ==== + +/** + \brief Event on RTOS kernel error (Error) + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_ERROR_DISABLE)) +extern void EvrRtxKernelError (int32_t status); +#else +#define EvrRtxKernelError(status) +#endif + +/** + \brief Event on RTOS kernel initialize (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INITIALIZE_DISABLE)) +extern void EvrRtxKernelInitialize (void); +#else +#define EvrRtxKernelInitialize() +#endif + +/** + \brief Event on successful RTOS kernel initialize (Op) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INITIALIZED_DISABLE)) +extern void EvrRtxKernelInitialized (void); +#else +#define EvrRtxKernelInitialized() +#endif + +/** + \brief Event on RTOS kernel information retrieve (API) + \param[in] version pointer to buffer for retrieving version information. + \param[in] id_buf pointer to buffer for retrieving kernel identification string. + \param[in] id_size size of buffer for kernel identification string. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_INFO_DISABLE)) +extern void EvrRtxKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); +#else +#define EvrRtxKernelGetInfo(version, id_buf, id_size) +#endif + +/** + \brief Event on successful RTOS kernel information retrieve (Op) + \param[in] version pointer to buffer for retrieving version information. + \param[in] id_buf pointer to buffer for retrieving kernel identification string. + \param[in] id_size size of buffer for kernel identification string. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INFO_RETRIEVED_DISABLE)) +extern void EvrRtxKernelInfoRetrieved (const osVersion_t *version, const char *id_buf, uint32_t id_size); +#else +#define EvrRtxKernelInfoRetrieved(version, id_buf, id_size) +#endif + +/** + \brief Event on current RTOS Kernel state retrieve (API) + \param[in] state current RTOS Kernel state. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_STATE_DISABLE)) +extern void EvrRtxKernelGetState (osKernelState_t state); +#else +#define EvrRtxKernelGetState(state) +#endif + +/** + \brief Event on RTOS Kernel scheduler start (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_START_DISABLE)) +extern void EvrRtxKernelStart (void); +#else +#define EvrRtxKernelStart() +#endif + +/** + \brief Event on successful RTOS Kernel scheduler start (Op) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_STARTED_DISABLE)) +extern void EvrRtxKernelStarted (void); +#else +#define EvrRtxKernelStarted() +#endif + +/** + \brief Event on RTOS Kernel scheduler lock (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCK_DISABLE)) +extern void EvrRtxKernelLock (void); +#else +#define EvrRtxKernelLock() +#endif + +/** + \brief Event on successful RTOS Kernel scheduler lock (Op) + \param[in] lock previous lock state (1 - locked, 0 - not locked). +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCKED_DISABLE)) +extern void EvrRtxKernelLocked (int32_t lock); +#else +#define EvrRtxKernelLocked(lock) +#endif + +/** + \brief Event on RTOS Kernel scheduler unlock (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_UNLOCK_DISABLE)) +extern void EvrRtxKernelUnlock (void); +#else +#define EvrRtxKernelUnlock() +#endif + +/** + \brief Event on successful RTOS Kernel scheduler unlock (Op) + \param[in] lock previous lock state (1 - locked, 0 - not locked). +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_UNLOCKED_DISABLE)) +extern void EvrRtxKernelUnlocked (int32_t lock); +#else +#define EvrRtxKernelUnlocked(lock) +#endif + +/** + \brief Event on RTOS Kernel scheduler lock state restore (API) + \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESTORE_LOCK_DISABLE)) +extern void EvrRtxKernelRestoreLock (int32_t lock); +#else +#define EvrRtxKernelRestoreLock(lock) +#endif + +/** + \brief Event on successful RTOS Kernel scheduler lock state restore (Op) + \param[in] lock new lock state (1 - locked, 0 - not locked). +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCK_RESTORED_DISABLE)) +extern void EvrRtxKernelLockRestored (int32_t lock); +#else +#define EvrRtxKernelLockRestored(lock) +#endif + +/** + \brief Event on RTOS Kernel scheduler suspend (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_SUSPEND_DISABLE)) +extern void EvrRtxKernelSuspend (void); +#else +#define EvrRtxKernelSuspend() +#endif + +/** + \brief Event on successful RTOS Kernel scheduler suspend (Op) + \param[in] sleep_ticks time in ticks, for how long the system can sleep or power-down. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_SUSPENDED_DISABLE)) +extern void EvrRtxKernelSuspended (uint32_t sleep_ticks); +#else +#define EvrRtxKernelSuspended(sleep_ticks) +#endif + +/** + \brief Event on RTOS Kernel scheduler resume (API) + \param[in] sleep_ticks time in ticks, for how long the system was in sleep or power-down mode. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESUME_DISABLE)) +extern void EvrRtxKernelResume (uint32_t sleep_ticks); +#else +#define EvrRtxKernelResume(sleep_ticks) +#endif + +/** + \brief Event on successful RTOS Kernel scheduler resume (Op) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESUMED_DISABLE)) +extern void EvrRtxKernelResumed (void); +#else +#define EvrRtxKernelResumed() +#endif + +/** + \brief Event on RTOS kernel tick count retrieve (API) + \param[in] count RTOS kernel current tick count. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE)) +extern void EvrRtxKernelGetTickCount (uint32_t count); +#else +#define EvrRtxKernelGetTickCount(count) +#endif + +/** + \brief Event on RTOS kernel tick frequency retrieve (API) + \param[in] freq frequency of the kernel tick. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_FREQ_DISABLE)) +extern void EvrRtxKernelGetTickFreq (uint32_t freq); +#else +#define EvrRtxKernelGetTickFreq(freq) +#endif + +/** + \brief Event on RTOS kernel system timer count retrieve (API) + \param[in] count RTOS kernel current system timer count as 32-bit value. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_SYS_TIMER_COUNT_DISABLE)) +extern void EvrRtxKernelGetSysTimerCount (uint32_t count); +#else +#define EvrRtxKernelGetSysTimerCount(count) +#endif + +/** + \brief Event on RTOS kernel system timer frequency retrieve (API) + \param[in] freq frequency of the system timer. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_SYS_TIMER_FREQ_DISABLE)) +extern void EvrRtxKernelGetSysTimerFreq (uint32_t freq); +#else +#define EvrRtxKernelGetSysTimerFreq(freq) +#endif + + +// ==== Thread Events ==== + +/** + \brief Event on thread error (Error) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_ERROR_DISABLE)) +extern void EvrRtxThreadError (osThreadId_t thread_id, int32_t status); +#else +#define EvrRtxThreadError(thread_id, status) +#endif + +/** + \brief Event on thread create and intialize (API) + \param[in] func thread function. + \param[in] argument pointer that is passed to the thread function as start argument. + \param[in] attr thread attributes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_NEW_DISABLE)) +extern void EvrRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); +#else +#define EvrRtxThreadNew(func, argument, attr) +#endif + +/** + \brief Event on successful thread create (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] thread_addr thread entry address. + \param[in] name pointer to thread object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_CREATED_DISABLE)) +extern void EvrRtxThreadCreated (osThreadId_t thread_id, uint32_t thread_addr, const char *name); +#else +#define EvrRtxThreadCreated(thread_id, thread_addr, name) +#endif + +/** + \brief Event on thread name retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] name pointer to thread object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_NAME_DISABLE)) +extern void EvrRtxThreadGetName (osThreadId_t thread_id, const char *name); +#else +#define EvrRtxThreadGetName(thread_id, name) +#endif + +/** + \brief Event on current running thread ID retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_ID_DISABLE)) +extern void EvrRtxThreadGetId (osThreadId_t thread_id); +#else +#define EvrRtxThreadGetId(thread_id) +#endif + +/** + \brief Event on thread state retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] state current thread state of the specified thread. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STATE_DISABLE)) +extern void EvrRtxThreadGetState (osThreadId_t thread_id, osThreadState_t state); +#else +#define EvrRtxThreadGetState(thread_id, state) +#endif + +/** + \brief Event on thread stack size retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] stack_size stack size in bytes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STACK_SIZE_DISABLE)) +extern void EvrRtxThreadGetStackSize (osThreadId_t thread_id, uint32_t stack_size); +#else +#define EvrRtxThreadGetStackSize(thread_id, stack_size) +#endif + +/** + \brief Event on available stack space retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] stack_space remaining stack space in bytes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STACK_SPACE_DISABLE)) +extern void EvrRtxThreadGetStackSpace (osThreadId_t thread_id, uint32_t stack_space); +#else +#define EvrRtxThreadGetStackSpace(thread_id, stack_space) +#endif + +/** + \brief Event on thread priority set (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] priority new priority value for the thread function. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SET_PRIORITY_DISABLE)) +extern void EvrRtxThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); +#else +#define EvrRtxThreadSetPriority(thread_id, priority) +#endif + +/** + \brief Event on thread priority updated (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] priority new priority value for the thread function. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_PRIORITY_UPDATED_DISABLE)) +extern void EvrRtxThreadPriorityUpdated (osThreadId_t thread_id, osPriority_t priority); +#else +#define EvrRtxThreadPriorityUpdated(thread_id, priority) +#endif + +/** + \brief Event on thread priority retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] priority current priority value of the specified thread. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_PRIORITY_DISABLE)) +extern void EvrRtxThreadGetPriority (osThreadId_t thread_id, osPriority_t priority); +#else +#define EvrRtxThreadGetPriority(thread_id, priority) +#endif + +/** + \brief Event on thread yield (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_YIELD_DISABLE)) +extern void EvrRtxThreadYield (void); +#else +#define EvrRtxThreadYield() +#endif + +/** + \brief Event on thread suspend (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SUSPEND_DISABLE)) +extern void EvrRtxThreadSuspend (osThreadId_t thread_id); +#else +#define EvrRtxThreadSuspend(thread_id) +#endif + +/** + \brief Event on successful thread suspend (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SUSPENDED_DISABLE)) +extern void EvrRtxThreadSuspended (osThreadId_t thread_id); +#else +#define EvrRtxThreadSuspended(thread_id) +#endif + +/** + \brief Event on thread resume (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_RESUME_DISABLE)) +extern void EvrRtxThreadResume (osThreadId_t thread_id); +#else +#define EvrRtxThreadResume(thread_id) +#endif + +/** + \brief Event on successful thread resume (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_RESUMED_DISABLE)) +extern void EvrRtxThreadResumed (osThreadId_t thread_id); +#else +#define EvrRtxThreadResumed(thread_id) +#endif + +/** + \brief Event on thread detach (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DETACH_DISABLE)) +extern void EvrRtxThreadDetach (osThreadId_t thread_id); +#else +#define EvrRtxThreadDetach(thread_id) +#endif + +/** + \brief Event on successful thread detach (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DETACHED_DISABLE)) +extern void EvrRtxThreadDetached (osThreadId_t thread_id); +#else +#define EvrRtxThreadDetached(thread_id) +#endif + +/** + \brief Event on thread join (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOIN_DISABLE)) +extern void EvrRtxThreadJoin (osThreadId_t thread_id); +#else +#define EvrRtxThreadJoin(thread_id) +#endif + +/** + \brief Event on pending thread join (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOIN_PENDING_DISABLE)) +extern void EvrRtxThreadJoinPending (osThreadId_t thread_id); +#else +#define EvrRtxThreadJoinPending(thread_id) +#endif + +/** + \brief Event on successful thread join (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOINED_DISABLE)) +extern void EvrRtxThreadJoined (osThreadId_t thread_id); +#else +#define EvrRtxThreadJoined(thread_id) +#endif + +/** + \brief Event on thread execution block (Detail) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_BLOCKED_DISABLE)) +extern void EvrRtxThreadBlocked (osThreadId_t thread_id, uint32_t timeout); +#else +#define EvrRtxThreadBlocked(thread_id, timeout) +#endif + +/** + \brief Event on thread execution unblock (Detail) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] ret_val extended execution status of the thread. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_UNBLOCKED_DISABLE)) +extern void EvrRtxThreadUnblocked (osThreadId_t thread_id, uint32_t ret_val); +#else +#define EvrRtxThreadUnblocked(thread_id, ret_val) +#endif + +/** + \brief Event on running thread pre-emption (Detail) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_PREEMPTED_DISABLE)) +extern void EvrRtxThreadPreempted (osThreadId_t thread_id); +#else +#define EvrRtxThreadPreempted(thread_id) +#endif + +/** + \brief Event on running thread switch (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SWITCHED_DISABLE)) +extern void EvrRtxThreadSwitched (osThreadId_t thread_id); +#else +#define EvrRtxThreadSwitched(thread_id) +#endif + +/** + \brief Event on thread exit (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_EXIT_DISABLE)) +extern void EvrRtxThreadExit (void); +#else +#define EvrRtxThreadExit() +#endif + +/** + \brief Event on thread terminate (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_TERMINATE_DISABLE)) +extern void EvrRtxThreadTerminate (osThreadId_t thread_id); +#else +#define EvrRtxThreadTerminate(thread_id) +#endif + +/** + \brief Event on successful thread terminate (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DESTROYED_DISABLE)) +extern void EvrRtxThreadDestroyed (osThreadId_t thread_id); +#else +#define EvrRtxThreadDestroyed(thread_id) +#endif + +/** + \brief Event on active thread count retrieve (API) + \param[in] count number of active threads. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_COUNT_DISABLE)) +extern void EvrRtxThreadGetCount (uint32_t count); +#else +#define EvrRtxThreadGetCount(count) +#endif + +/** + \brief Event on active threads enumerate (API) + \param[in] thread_array pointer to array for retrieving thread IDs. + \param[in] array_items maximum number of items in array for retrieving thread IDs. + \param[in] count number of enumerated threads. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_ENUMERATE_DISABLE)) +extern void EvrRtxThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items, uint32_t count); +#else +#define EvrRtxThreadEnumerate(thread_array, array_items, count) +#endif + + +// ==== Thread Flags Events ==== + +/** + \brief Event on thread flags error (Error) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_ERROR_DISABLE)) +extern void EvrRtxThreadFlagsError (osThreadId_t thread_id, int32_t status); +#else +#define EvrRtxThreadFlagsError(thread_id, status) +#endif + +/** + \brief Event on thread flags set (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] flags flags of the thread that shall be set. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_SET_DISABLE)) +extern void EvrRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); +#else +#define EvrRtxThreadFlagsSet(thread_id, flags) +#endif + +/** + \brief Event on successful thread flags set (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] thread_flags thread flags after setting. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_SET_DONE_DISABLE)) +extern void EvrRtxThreadFlagsSetDone (osThreadId_t thread_id, uint32_t thread_flags); +#else +#define EvrRtxThreadFlagsSetDone(thread_id, thread_flags) +#endif + +/** + \brief Event on thread flags clear (API) + \param[in] flags flags of the thread that shall be cleared. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_CLEAR_DISABLE)) +extern void EvrRtxThreadFlagsClear (uint32_t flags); +#else +#define EvrRtxThreadFlagsClear(flags) +#endif + +/** + \brief Event on successful thread flags clear (Op) + \param[in] thread_flags thread flags before clearing. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_CLEAR_DONE_DISABLE)) +extern void EvrRtxThreadFlagsClearDone (uint32_t thread_flags); +#else +#define EvrRtxThreadFlagsClearDone(thread_flags) +#endif + +/** + \brief Event on thread flags retrieve (API) + \param[in] thread_flags current thread flags. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_GET_DISABLE)) +extern void EvrRtxThreadFlagsGet (uint32_t thread_flags); +#else +#define EvrRtxThreadFlagsGet(thread_flags) +#endif + +/** + \brief Event on wait for thread flags (API) + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_DISABLE)) +extern void EvrRtxThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); +#else +#define EvrRtxThreadFlagsWait(flags, options, timeout) +#endif + +/** + \brief Event on pending wait for thread flags (Op) + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_PENDING_DISABLE)) +extern void EvrRtxThreadFlagsWaitPending (uint32_t flags, uint32_t options, uint32_t timeout); +#else +#define EvrRtxThreadFlagsWaitPending(flags, options, timeout) +#endif + +/** + \brief Event on wait timeout for thread flags (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_TIMEOUT_DISABLE)) +extern void EvrRtxThreadFlagsWaitTimeout (osThreadId_t thread_id); +#else +#define EvrRtxThreadFlagsWaitTimeout(thread_id) +#endif + +/** + \brief Event on successful wait for thread flags (Op) + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] thread_flags thread flags before clearing. + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_COMPLETED_DISABLE)) +extern void EvrRtxThreadFlagsWaitCompleted (uint32_t flags, uint32_t options, uint32_t thread_flags, osThreadId_t thread_id); +#else +#define EvrRtxThreadFlagsWaitCompleted(flags, options, thread_flags, thread_id) +#endif + +/** + \brief Event on unsuccessful wait for thread flags (Op) + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_NOT_COMPLETED_DISABLE)) +extern void EvrRtxThreadFlagsWaitNotCompleted (uint32_t flags, uint32_t options); +#else +#define EvrRtxThreadFlagsWaitNotCompleted(flags, options) +#endif + + +// ==== Generic Wait Events ==== + +/** + \brief Event on delay error (Error) + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_ERROR_DISABLE)) +extern void EvrRtxDelayError (int32_t status); +#else +#define EvrRtxDelayError(status) +#endif + +/** + \brief Event on delay for specified time (API) + \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_DISABLE)) +extern void EvrRtxDelay (uint32_t ticks); +#else +#define EvrRtxDelay(ticks) +#endif + +/** + \brief Event on delay until specified time (API) + \param[in] ticks absolute time in ticks. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_UNTIL_DISABLE)) +extern void EvrRtxDelayUntil (uint32_t ticks); +#else +#define EvrRtxDelayUntil(ticks) +#endif + +/** + \brief Event on delay started (Op) + \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_STARTED_DISABLE)) +extern void EvrRtxDelayStarted (uint32_t ticks); +#else +#define EvrRtxDelayStarted(ticks) +#endif + +/** + \brief Event on delay until specified time started (Op) + \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_UNTIL_STARTED_DISABLE)) +extern void EvrRtxDelayUntilStarted (uint32_t ticks); +#else +#define EvrRtxDelayUntilStarted(ticks) +#endif + +/** + \brief Event on delay completed (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_COMPLETED_DISABLE)) +extern void EvrRtxDelayCompleted (osThreadId_t thread_id); +#else +#define EvrRtxDelayCompleted(thread_id) +#endif + + +// ==== Timer Events ==== + +/** + \brief Event on timer error (Error) + \param[in] timer_id timer ID obtained by \ref osTimerNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_ERROR_DISABLE)) +extern void EvrRtxTimerError (osTimerId_t timer_id, int32_t status); +#else +#define EvrRtxTimerError(timer_id, status) +#endif + +/** + \brief Event on timer callback call (Op) + \param[in] func start address of a timer call back function. + \param[in] argument argument to the timer call back function. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_CALLBACK_DISABLE)) +extern void EvrRtxTimerCallback (osTimerFunc_t func, void *argument); +#else +#define EvrRtxTimerCallback(func, argument) +#endif + +/** + \brief Event on timer create and initialize (API) + \param[in] func start address of a timer call back function. + \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. + \param[in] argument argument to the timer call back function. + \param[in] attr timer attributes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_NEW_DISABLE)) +extern void EvrRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); +#else +#define EvrRtxTimerNew(func, type, argument, attr) +#endif + +/** + \brief Event on successful timer create (Op) + \param[in] timer_id timer ID obtained by \ref osTimerNew. + \param[in] name pointer to timer object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_CREATED_DISABLE)) +extern void EvrRtxTimerCreated (osTimerId_t timer_id, const char *name); +#else +#define EvrRtxTimerCreated(timer_id, name) +#endif + +/** + \brief Event on timer name retrieve (API) + \param[in] timer_id timer ID obtained by \ref osTimerNew. + \param[in] name pointer to timer object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_GET_NAME_DISABLE)) +extern void EvrRtxTimerGetName (osTimerId_t timer_id, const char *name); +#else +#define EvrRtxTimerGetName(timer_id, name) +#endif + +/** + \brief Event on timer start (API) + \param[in] timer_id timer ID obtained by \ref osTimerNew. + \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_START_DISABLE)) +extern void EvrRtxTimerStart (osTimerId_t timer_id, uint32_t ticks); +#else +#define EvrRtxTimerStart(timer_id, ticks) +#endif + +/** + \brief Event on successful timer start (Op) + \param[in] timer_id timer ID obtained by \ref osTimerNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STARTED_DISABLE)) +extern void EvrRtxTimerStarted (osTimerId_t timer_id); +#else +#define EvrRtxTimerStarted(timer_id) +#endif + +/** + \brief Event on timer stop (API) + \param[in] timer_id timer ID obtained by \ref osTimerNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STOP_DISABLE)) +extern void EvrRtxTimerStop (osTimerId_t timer_id); +#else +#define EvrRtxTimerStop(timer_id) +#endif + +/** + \brief Event on successful timer stop (Op) + \param[in] timer_id timer ID obtained by \ref osTimerNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STOPPED_DISABLE)) +extern void EvrRtxTimerStopped (osTimerId_t timer_id); +#else +#define EvrRtxTimerStopped(timer_id) +#endif + +/** + \brief Event on timer running state check (API) + \param[in] timer_id timer ID obtained by \ref osTimerNew. + \param[in] running running state: 0 not running, 1 running. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_IS_RUNNING_DISABLE)) +extern void EvrRtxTimerIsRunning (osTimerId_t timer_id, uint32_t running); +#else +#define EvrRtxTimerIsRunning(timer_id, running) +#endif + +/** + \brief Event on timer delete (API) + \param[in] timer_id timer ID obtained by \ref osTimerNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_DELETE_DISABLE)) +extern void EvrRtxTimerDelete (osTimerId_t timer_id); +#else +#define EvrRtxTimerDelete(timer_id) +#endif + +/** + \brief Event on successful timer delete (Op) + \param[in] timer_id timer ID obtained by \ref osTimerNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_DESTROYED_DISABLE)) +extern void EvrRtxTimerDestroyed (osTimerId_t timer_id); +#else +#define EvrRtxTimerDestroyed(timer_id) +#endif + + +// ==== Event Flags Events ==== + +/** + \brief Event on event flags error (Error) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_ERROR_DISABLE)) +extern void EvrRtxEventFlagsError (osEventFlagsId_t ef_id, int32_t status); +#else +#define EvrRtxEventFlagsError(ef_id, status) +#endif + +/** + \brief Event on event flags create and initialize (API) + \param[in] attr event flags attributes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_NEW_DISABLE)) +extern void EvrRtxEventFlagsNew (const osEventFlagsAttr_t *attr); +#else +#define EvrRtxEventFlagsNew(attr) +#endif + +/** + \brief Event on successful event flags create (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] name pointer to event flags object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CREATED_DISABLE)) +extern void EvrRtxEventFlagsCreated (osEventFlagsId_t ef_id, const char *name); +#else +#define EvrRtxEventFlagsCreated(ef_id, name) +#endif + +/** + \brief Event on event flags name retrieve (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] name pointer to event flags object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_GET_NAME_DISABLE)) +extern void EvrRtxEventFlagsGetName (osEventFlagsId_t ef_id, const char *name); +#else +#define EvrRtxEventFlagsGetName(ef_id, name) +#endif + +/** + \brief Event on event flags set (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags that shall be set. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_SET_DISABLE)) +extern void EvrRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); +#else +#define EvrRtxEventFlagsSet(ef_id, flags) +#endif + +/** + \brief Event on successful event flags set (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] event_flags event flags after setting. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_SET_DONE_DISABLE)) +extern void EvrRtxEventFlagsSetDone (osEventFlagsId_t ef_id, uint32_t event_flags); +#else +#define EvrRtxEventFlagsSetDone(ef_id, event_flags) +#endif + +/** + \brief Event on event flags clear (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags that shall be cleared. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CLEAR_DISABLE)) +extern void EvrRtxEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); +#else +#define EvrRtxEventFlagsClear(ef_id, flags) +#endif + +/** + \brief Event on successful event flags clear (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] event_flags event flags before clearing. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CLEAR_DONE_DISABLE)) +extern void EvrRtxEventFlagsClearDone (osEventFlagsId_t ef_id, uint32_t event_flags); +#else +#define EvrRtxEventFlagsClearDone(ef_id, event_flags) +#endif + +/** + \brief Event on event flags retrieve (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] event_flags current event flags. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_GET_DISABLE)) +extern void EvrRtxEventFlagsGet (osEventFlagsId_t ef_id, uint32_t event_flags); +#else +#define EvrRtxEventFlagsGet(ef_id, event_flags) +#endif + +/** + \brief Event on wait for event flags (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_DISABLE)) +extern void EvrRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); +#else +#define EvrRtxEventFlagsWait(ef_id, flags, options, timeout) +#endif + +/** + \brief Event on pending wait for event flags (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_PENDING_DISABLE)) +extern void EvrRtxEventFlagsWaitPending (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); +#else +#define EvrRtxEventFlagsWaitPending(ef_id, flags, options, timeout) +#endif + +/** + \brief Event on wait timeout for event flags (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_TIMEOUT_DISABLE)) +extern void EvrRtxEventFlagsWaitTimeout (osEventFlagsId_t ef_id); +#else +#define EvrRtxEventFlagsWaitTimeout(ef_id) +#endif + +/** + \brief Event on successful wait for event flags (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] event_flags event flags before clearing or 0 if specified flags have not been set. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_COMPLETED_DISABLE)) +extern void EvrRtxEventFlagsWaitCompleted (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t event_flags); +#else +#define EvrRtxEventFlagsWaitCompleted(ef_id, flags, options, event_flags) +#endif + +/** + \brief Event on unsuccessful wait for event flags (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_NOT_COMPLETED_DISABLE)) +extern void EvrRtxEventFlagsWaitNotCompleted (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options); +#else +#define EvrRtxEventFlagsWaitNotCompleted(ef_id, flags, options) +#endif + +/** + \brief Event on event flags delete (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_DELETE_DISABLE)) +extern void EvrRtxEventFlagsDelete (osEventFlagsId_t ef_id); +#else +#define EvrRtxEventFlagsDelete(ef_id) +#endif + +/** + \brief Event on successful event flags delete (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_DESTROYED_DISABLE)) +extern void EvrRtxEventFlagsDestroyed (osEventFlagsId_t ef_id); +#else +#define EvrRtxEventFlagsDestroyed(ef_id) +#endif + + +// ==== Mutex Events ==== + +/** + \brief Event on mutex error (Error) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ERROR_DISABLE)) +extern void EvrRtxMutexError (osMutexId_t mutex_id, int32_t status); +#else +#define EvrRtxMutexError(mutex_id, status) +#endif + +/** + \brief Event on mutex create and initialize (API) + \param[in] attr mutex attributes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_NEW_DISABLE)) +extern void EvrRtxMutexNew (const osMutexAttr_t *attr); +#else +#define EvrRtxMutexNew(attr) +#endif + +/** + \brief Event on successful mutex create (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] name pointer to mutex object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_CREATED_DISABLE)) +extern void EvrRtxMutexCreated (osMutexId_t mutex_id, const char *name); +#else +#define EvrRtxMutexCreated(mutex_id, name) +#endif + +/** + \brief Event on mutex name retrieve (API) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] name pointer to mutex object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_GET_NAME_DISABLE)) +extern void EvrRtxMutexGetName (osMutexId_t mutex_id, const char *name); +#else +#define EvrRtxMutexGetName(mutex_id, name) +#endif + +/** + \brief Event on mutex acquire (API) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_DISABLE)) +extern void EvrRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); +#else +#define EvrRtxMutexAcquire(mutex_id, timeout) +#endif + +/** + \brief Event on pending mutex acquire (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_PENDING_DISABLE)) +extern void EvrRtxMutexAcquirePending (osMutexId_t mutex_id, uint32_t timeout); +#else +#define EvrRtxMutexAcquirePending(mutex_id, timeout) +#endif + +/** + \brief Event on mutex acquire timeout (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_TIMEOUT_DISABLE)) +extern void EvrRtxMutexAcquireTimeout (osMutexId_t mutex_id); +#else +#define EvrRtxMutexAcquireTimeout(mutex_id) +#endif + +/** + \brief Event on successful mutex acquire (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] lock current number of times mutex object is locked. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRED_DISABLE)) +extern void EvrRtxMutexAcquired (osMutexId_t mutex_id, uint32_t lock); +#else +#define EvrRtxMutexAcquired(mutex_id, lock) +#endif + +/** + \brief Event on unsuccessful mutex acquire (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_NOT_ACQUIRED_DISABLE)) +extern void EvrRtxMutexNotAcquired (osMutexId_t mutex_id); +#else +#define EvrRtxMutexNotAcquired(mutex_id) +#endif + +/** + \brief Event on mutex release (API) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_RELEASE_DISABLE)) +extern void EvrRtxMutexRelease (osMutexId_t mutex_id); +#else +#define EvrRtxMutexRelease(mutex_id) +#endif + +/** + \brief Event on successful mutex release (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] lock current number of times mutex object is locked. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_RELEASED_DISABLE)) +extern void EvrRtxMutexReleased (osMutexId_t mutex_id, uint32_t lock); +#else +#define EvrRtxMutexReleased(mutex_id, lock) +#endif + +/** + \brief Event on mutex owner retrieve (API) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_GET_OWNER_DISABLE)) +extern void EvrRtxMutexGetOwner (osMutexId_t mutex_id, osThreadId_t thread_id); +#else +#define EvrRtxMutexGetOwner(mutex_id, thread_id) +#endif + +/** + \brief Event on mutex delete (API) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_DELETE_DISABLE)) +extern void EvrRtxMutexDelete (osMutexId_t mutex_id); +#else +#define EvrRtxMutexDelete(mutex_id) +#endif + +/** + \brief Event on successful mutex delete (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_DESTROYED_DISABLE)) +extern void EvrRtxMutexDestroyed (osMutexId_t mutex_id); +#else +#define EvrRtxMutexDestroyed(mutex_id) +#endif + + +// ==== Semaphore Events ==== + +/** + \brief Event on semaphore error (Error) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ERROR_DISABLE)) +extern void EvrRtxSemaphoreError (osSemaphoreId_t semaphore_id, int32_t status); +#else +#define EvrRtxSemaphoreError(semaphore_id, status) +#endif + +/** + \brief Event on semaphore create and initialize (API) + \param[in] max_count maximum number of available tokens. + \param[in] initial_count initial number of available tokens. + \param[in] attr semaphore attributes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_NEW_DISABLE)) +extern void EvrRtxSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); +#else +#define EvrRtxSemaphoreNew(max_count, initial_count, attr) +#endif + +/** + \brief Event on successful semaphore create (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] name pointer to semaphore object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_CREATED_DISABLE)) +extern void EvrRtxSemaphoreCreated (osSemaphoreId_t semaphore_id, const char *name); +#else +#define EvrRtxSemaphoreCreated(semaphore_id, name) +#endif + +/** + \brief Event on semaphore name retrieve (API) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] name pointer to semaphore object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_GET_NAME_DISABLE)) +extern void EvrRtxSemaphoreGetName (osSemaphoreId_t semaphore_id, const char *name); +#else +#define EvrRtxSemaphoreGetName(semaphore_id, name) +#endif + +/** + \brief Event on semaphore acquire (API) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_DISABLE)) +extern void EvrRtxSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); +#else +#define EvrRtxSemaphoreAcquire(semaphore_id, timeout) +#endif + +/** + \brief Event on pending semaphore acquire (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_PENDING_DISABLE)) +extern void EvrRtxSemaphoreAcquirePending (osSemaphoreId_t semaphore_id, uint32_t timeout); +#else +#define EvrRtxSemaphoreAcquirePending(semaphore_id, timeout) +#endif + +/** + \brief Event on semaphore acquire timeout (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_TIMEOUT_DISABLE)) +extern void EvrRtxSemaphoreAcquireTimeout (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreAcquireTimeout(semaphore_id) +#endif + +/** + \brief Event on successful semaphore acquire (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] tokens number of available tokens. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRED_DISABLE)) +extern void EvrRtxSemaphoreAcquired (osSemaphoreId_t semaphore_id, uint32_t tokens); +#else +#define EvrRtxSemaphoreAcquired(semaphore_id, tokens) +#endif + +/** + \brief Event on unsuccessful semaphore acquire (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_NOT_ACQUIRED_DISABLE)) +extern void EvrRtxSemaphoreNotAcquired (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreNotAcquired(semaphore_id) +#endif + +/** + \brief Event on semaphore release (API) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_RELEASE_DISABLE)) +extern void EvrRtxSemaphoreRelease (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreRelease(semaphore_id) +#endif + +/** + \brief Event on successful semaphore release (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] tokens number of available tokens. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_RELEASED_DISABLE)) +extern void EvrRtxSemaphoreReleased (osSemaphoreId_t semaphore_id, uint32_t tokens); +#else +#define EvrRtxSemaphoreReleased(semaphore_id, tokens) +#endif + +/** + \brief Event on semaphore token count retrieval (API) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] count current number of available tokens. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_GET_COUNT_DISABLE)) +extern void EvrRtxSemaphoreGetCount (osSemaphoreId_t semaphore_id, uint32_t count); +#else +#define EvrRtxSemaphoreGetCount(semaphore_id, count) +#endif + +/** + \brief Event on semaphore delete (API) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_DELETE_DISABLE)) +extern void EvrRtxSemaphoreDelete (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreDelete(semaphore_id) +#endif + +/** + \brief Event on successful semaphore delete (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_DESTROYED_DISABLE)) +extern void EvrRtxSemaphoreDestroyed (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreDestroyed(semaphore_id) +#endif + + +// ==== Memory Pool Events ==== + +/** + \brief Event on memory pool error (Error) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ERROR_DISABLE)) +extern void EvrRtxMemoryPoolError (osMemoryPoolId_t mp_id, int32_t status); +#else +#define EvrRtxMemoryPoolError(mp_id, status) +#endif + +/** + \brief Event on memory pool create and initialize (API) + \param[in] block_count maximum number of memory blocks in memory pool. + \param[in] block_size memory block size in bytes. + \param[in] attr memory pool attributes; NULL: default values. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_NEW_DISABLE)) +extern void EvrRtxMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr); +#else +#define EvrRtxMemoryPoolNew(block_count, block_size, attr) +#endif + +/** + \brief Event on successful memory pool create (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] name pointer to memory pool object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_CREATED_DISABLE)) +extern void EvrRtxMemoryPoolCreated (osMemoryPoolId_t mp_id, const char *name); +#else +#define EvrRtxMemoryPoolCreated(mp_id, name) +#endif + +/** + \brief Event on memory pool name retrieve (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] name pointer to memory pool object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_NAME_DISABLE)) +extern void EvrRtxMemoryPoolGetName (osMemoryPoolId_t mp_id, const char *name); +#else +#define EvrRtxMemoryPoolGetName(mp_id, name) +#endif + +/** + \brief Event on memory pool allocation (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_DISABLE)) +extern void EvrRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); +#else +#define EvrRtxMemoryPoolAlloc(mp_id, timeout) +#endif + +/** + \brief Event on pending memory pool allocation (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_PENDING_DISABLE)) +extern void EvrRtxMemoryPoolAllocPending (osMemoryPoolId_t mp_id, uint32_t timeout); +#else +#define EvrRtxMemoryPoolAllocPending(mp_id, timeout) +#endif + +/** + \brief Event on memory pool allocation timeout (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_TIMEOUT_DISABLE)) +extern void EvrRtxMemoryPoolAllocTimeout (osMemoryPoolId_t mp_id); +#else +#define EvrRtxMemoryPoolAllocTimeout(mp_id) +#endif + +/** + \brief Event on successful memory pool allocation (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] block address of the allocated memory block. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOCATED_DISABLE)) +extern void EvrRtxMemoryPoolAllocated (osMemoryPoolId_t mp_id, void *block); +#else +#define EvrRtxMemoryPoolAllocated(mp_id, block) +#endif + +/** + \brief Event on unsuccessful memory pool allocation (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_FAILED_DISABLE)) +extern void EvrRtxMemoryPoolAllocFailed (osMemoryPoolId_t mp_id); +#else +#define EvrRtxMemoryPoolAllocFailed(mp_id) +#endif + +/** + \brief Event on memory pool free (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] block address of the allocated memory block to be returned to the memory pool. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_FREE_DISABLE)) +extern void EvrRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); +#else +#define EvrRtxMemoryPoolFree(mp_id, block) +#endif + +/** + \brief Event on successful memory pool free (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] block address of the allocated memory block to be returned to the memory pool. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DEALLOCATED_DISABLE)) +extern void EvrRtxMemoryPoolDeallocated (osMemoryPoolId_t mp_id, void *block); +#else +#define EvrRtxMemoryPoolDeallocated(mp_id, block) +#endif + +/** + \brief Event on unsuccessful memory pool free (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] block address of the allocated memory block to be returned to the memory pool. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_FREE_FAILED_DISABLE)) +extern void EvrRtxMemoryPoolFreeFailed (osMemoryPoolId_t mp_id, void *block); +#else +#define EvrRtxMemoryPoolFreeFailed(mp_id, block) +#endif + +/** + \brief Event on memory pool capacity retrieve (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] capacity maximum number of memory blocks. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_CAPACITY_DISABLE)) +extern void EvrRtxMemoryPoolGetCapacity (osMemoryPoolId_t mp_id, uint32_t capacity); +#else +#define EvrRtxMemoryPoolGetCapacity(mp_id, capacity) +#endif + +/** + \brief Event on memory pool block size retrieve (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] block_size memory block size in bytes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_BLOCK_SZIE_DISABLE)) +extern void EvrRtxMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id, uint32_t block_size); +#else +#define EvrRtxMemoryPoolGetBlockSize(mp_id, block_size) +#endif + +/** + \brief Event on used memory pool blocks retrieve (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] count number of memory blocks used. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_COUNT_DISABLE)) +extern void EvrRtxMemoryPoolGetCount (osMemoryPoolId_t mp_id, uint32_t count); +#else +#define EvrRtxMemoryPoolGetCount(mp_id, count) +#endif + +/** + \brief Event on available memory pool blocks retrieve (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] space number of memory blocks available. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_SPACE_DISABLE)) +extern void EvrRtxMemoryPoolGetSpace (osMemoryPoolId_t mp_id, uint32_t space); +#else +#define EvrRtxMemoryPoolGetSpace(mp_id, space) +#endif + +/** + \brief Event on memory pool delete (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DELETE_DISABLE)) +extern void EvrRtxMemoryPoolDelete (osMemoryPoolId_t mp_id); +#else +#define EvrRtxMemoryPoolDelete(mp_id) +#endif + +/** + \brief Event on successful memory pool delete (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DESTROYED_DISABLE)) +extern void EvrRtxMemoryPoolDestroyed (osMemoryPoolId_t mp_id); +#else +#define EvrRtxMemoryPoolDestroyed(mp_id) +#endif + + +// ==== Message Queue Events ==== + +/** + \brief Event on message queue error (Error) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_ERROR_DISABLE)) +extern void EvrRtxMessageQueueError (osMessageQueueId_t mq_id, int32_t status); +#else +#define EvrRtxMessageQueueError(mq_id, status) +#endif + +/** + \brief Event on message queue create and initialization (API) + \param[in] msg_count maximum number of messages in queue. + \param[in] msg_size maximum message size in bytes. + \param[in] attr message queue attributes; NULL: default values. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NEW_DISABLE)) +extern void EvrRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); +#else +#define EvrRtxMessageQueueNew(msg_count, msg_size, attr) +#endif + +/** + \brief Event on successful message queue create (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] name pointer to message queue object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_CREATED_DISABLE)) +extern void EvrRtxMessageQueueCreated (osMessageQueueId_t mq_id, const char *name); +#else +#define EvrRtxMessageQueueCreated(mq_id, name) +#endif + +/** + \brief Event on message queue name retrieve(API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] name pointer to message queue object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_NAME_DISABLE)) +extern void EvrRtxMessageQueueGetName (osMessageQueueId_t mq_id, const char *name); +#else +#define EvrRtxMessageQueueGetName(mq_id, name) +#endif + +/** + \brief Event on message put (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer with message to put into a queue. + \param[in] msg_prio message priority. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_DISABLE)) +extern void EvrRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); +#else +#define EvrRtxMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout) +#endif + +/** + \brief Event on pending message put (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer with message to put into a queue. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_PENDING_DISABLE)) +extern void EvrRtxMessageQueuePutPending (osMessageQueueId_t mq_id, const void *msg_ptr, uint32_t timeout); +#else +#define EvrRtxMessageQueuePutPending(mq_id, msg_ptr, timeout) +#endif + +/** + \brief Event on message put timeout (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_TIMEOUT_DISABLE)) +extern void EvrRtxMessageQueuePutTimeout (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueuePutTimeout(mq_id) +#endif + +/** + \brief Event on pending message insert (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer with message to put into a queue. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_INSERT_PENDING_DISABLE)) +extern void EvrRtxMessageQueueInsertPending (osMessageQueueId_t mq_id, const void *msg_ptr); +#else +#define EvrRtxMessageQueueInsertPending(mq_id, msg_ptr) +#endif + +/** + \brief Event on successful message insert (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer with message to put into a queue. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_INSERTED_DISABLE)) +extern void EvrRtxMessageQueueInserted (osMessageQueueId_t mq_id, const void *msg_ptr); +#else +#define EvrRtxMessageQueueInserted(mq_id, msg_ptr) +#endif + +/** + \brief Event on unsuccessful message insert (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer with message to put into a queue. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NOT_INSERTED_DISABLE)) +extern void EvrRtxMessageQueueNotInserted (osMessageQueueId_t mq_id, const void *msg_ptr); +#else +#define EvrRtxMessageQueueNotInserted(mq_id, msg_ptr) +#endif + +/** + \brief Event on message get (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer for message to get from a queue. + \param[in] msg_prio message priority. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_DISABLE)) +extern void EvrRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); +#else +#define EvrRtxMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout) +#endif + +/** + \brief Event on pending message get (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer for message to get from a queue. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_PENDING_DISABLE)) +extern void EvrRtxMessageQueueGetPending (osMessageQueueId_t mq_id, void *msg_ptr, uint32_t timeout); +#else +#define EvrRtxMessageQueueGetPending(mq_id, msg_ptr, timeout) +#endif + +/** + \brief Event on message get timeout (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_TIMEOUT_DISABLE)) +extern void EvrRtxMessageQueueGetTimeout (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueGetTimeout(mq_id) +#endif + +/** + \brief Event on successful message get (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer for message to get from a queue. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RETRIEVED_DISABLE)) +extern void EvrRtxMessageQueueRetrieved (osMessageQueueId_t mq_id, void *msg_ptr); +#else +#define EvrRtxMessageQueueRetrieved(mq_id, msg_ptr) +#endif + +/** + \brief Event on unsuccessful message get (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer for message to get from a queue. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NOT_RETRIEVED_DISABLE)) +extern void EvrRtxMessageQueueNotRetrieved (osMessageQueueId_t mq_id, void *msg_ptr); +#else +#define EvrRtxMessageQueueNotRetrieved(mq_id, msg_ptr) +#endif + +/** + \brief Event on message queue capacity retrieve (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] capacity maximum number of messages. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_CAPACITY_DISABLE)) +extern void EvrRtxMessageQueueGetCapacity (osMessageQueueId_t mq_id, uint32_t capacity); +#else +#define EvrRtxMessageQueueGetCapacity(mq_id, capacity) +#endif + +/** + \brief Event on message queue message size retrieve (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_size maximum message size in bytes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_MSG_SIZE_DISABLE)) +extern void EvrRtxMessageQueueGetMsgSize (osMessageQueueId_t mq_id, uint32_t msg_size); +#else +#define EvrRtxMessageQueueGetMsgSize(mq_id, msg_size) +#endif + +/** + \brief Event on message queue message count retrieve (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] count number of queued messages. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_COUNT_DISABLE)) +extern void EvrRtxMessageQueueGetCount (osMessageQueueId_t mq_id, uint32_t count); +#else +#define EvrRtxMessageQueueGetCount(mq_id, count) +#endif + +/** + \brief Event on message queue message slots retrieve (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] space number of available slots for messages. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_SPACE_DISABLE)) +extern void EvrRtxMessageQueueGetSpace (osMessageQueueId_t mq_id, uint32_t space); +#else +#define EvrRtxMessageQueueGetSpace(mq_id, space) +#endif + +/** + \brief Event on message queue reset (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RESET_DISABLE)) +extern void EvrRtxMessageQueueReset (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueReset(mq_id) +#endif + +/** + \brief Event on successful message queue reset (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RESET_DONE_DISABLE)) +extern void EvrRtxMessageQueueResetDone (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueResetDone(mq_id) +#endif + +/** + \brief Event on message queue delete (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_DELETE_DISABLE)) +extern void EvrRtxMessageQueueDelete (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueDelete(mq_id) +#endif + +/** + \brief Event on successful message queue delete (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_DESTROYED_DISABLE)) +extern void EvrRtxMessageQueueDestroyed (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueDestroyed(mq_id) +#endif + + +#endif // RTX_EVR_H_ diff --git a/include/rtos/rtx5/rtx_os.h b/include/rtos/rtx5/rtx_os.h new file mode 100644 index 0000000..eaaa7da --- /dev/null +++ b/include/rtos/rtx5/rtx_os.h @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: RTX OS definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_OS_H_ +#define RTX_OS_H_ + +#include +#include +#include "cmsis_os2.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/// Kernel Information +#define osRtxVersionAPI 20010003 ///< API version (2.1.3) +#define osRtxVersionKernel 50050001 ///< Kernel version (5.5.1) +#define osRtxKernelId "RTX V5.5.1" ///< Kernel identification string + + +// ==== Common definitions ==== + +/// Object Identifier definitions +#define osRtxIdInvalid 0x00U +#define osRtxIdThread 0xF1U +#define osRtxIdTimer 0xF2U +#define osRtxIdEventFlags 0xF3U +#define osRtxIdMutex 0xF5U +#define osRtxIdSemaphore 0xF6U +#define osRtxIdMemoryPool 0xF7U +#define osRtxIdMessage 0xF9U +#define osRtxIdMessageQueue 0xFAU + +/// Object Flags definitions +#define osRtxFlagSystemObject 0x01U +#define osRtxFlagSystemMemory 0x02U + + +// ==== Kernel definitions ==== + +/// Kernel State definitions +#define osRtxKernelInactive ((uint8_t)osKernelInactive) +#define osRtxKernelReady ((uint8_t)osKernelReady) +#define osRtxKernelRunning ((uint8_t)osKernelRunning) +#define osRtxKernelLocked ((uint8_t)osKernelLocked) +#define osRtxKernelSuspended ((uint8_t)osKernelSuspended) + + +// ==== Thread definitions ==== + +/// Thread State definitions (extending osThreadState) +#define osRtxThreadStateMask 0x0FU + +#define osRtxThreadInactive ((uint8_t)osThreadInactive) +#define osRtxThreadReady ((uint8_t)osThreadReady) +#define osRtxThreadRunning ((uint8_t)osThreadRunning) +#define osRtxThreadBlocked ((uint8_t)osThreadBlocked) +#define osRtxThreadTerminated ((uint8_t)osThreadTerminated) + +#define osRtxThreadWaitingDelay ((uint8_t)(osRtxThreadBlocked | 0x10U)) +#define osRtxThreadWaitingJoin ((uint8_t)(osRtxThreadBlocked | 0x20U)) +#define osRtxThreadWaitingThreadFlags ((uint8_t)(osRtxThreadBlocked | 0x30U)) +#define osRtxThreadWaitingEventFlags ((uint8_t)(osRtxThreadBlocked | 0x40U)) +#define osRtxThreadWaitingMutex ((uint8_t)(osRtxThreadBlocked | 0x50U)) +#define osRtxThreadWaitingSemaphore ((uint8_t)(osRtxThreadBlocked | 0x60U)) +#define osRtxThreadWaitingMemoryPool ((uint8_t)(osRtxThreadBlocked | 0x70U)) +#define osRtxThreadWaitingMessageGet ((uint8_t)(osRtxThreadBlocked | 0x80U)) +#define osRtxThreadWaitingMessagePut ((uint8_t)(osRtxThreadBlocked | 0x90U)) + +/// Thread Flags definitions +#define osRtxThreadFlagDefStack 0x10U ///< Default Stack flag + +/// Stack Marker definitions +#define osRtxStackMagicWord 0xE25A2EA5U ///< Stack Magic Word (Stack Base) +#define osRtxStackFillPattern 0xCCCCCCCCU ///< Stack Fill Pattern + +/// Thread Control Block +typedef struct osRtxThread_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t attr; ///< Object Attributes + const char *name; ///< Object Name + struct osRtxThread_s *thread_next; ///< Link pointer to next Thread in Object list + struct osRtxThread_s *thread_prev; ///< Link pointer to previous Thread in Object list + struct osRtxThread_s *delay_next; ///< Link pointer to next Thread in Delay list + struct osRtxThread_s *delay_prev; ///< Link pointer to previous Thread in Delay list + struct osRtxThread_s *thread_join; ///< Thread waiting to Join + uint32_t delay; ///< Delay Time + int8_t priority; ///< Thread Priority + int8_t priority_base; ///< Base Priority + uint8_t stack_frame; ///< Stack Frame (EXC_RETURN[7..0]) + uint8_t flags_options; ///< Thread/Event Flags Options + uint32_t wait_flags; ///< Waiting Thread/Event Flags + uint32_t thread_flags; ///< Thread Flags + struct osRtxMutex_s *mutex_list; ///< Link pointer to list of owned Mutexes + void *stack_mem; ///< Stack Memory + uint32_t stack_size; ///< Stack Size + uint32_t sp; ///< Current Stack Pointer + uint32_t thread_addr; ///< Thread entry address + uint32_t tz_memory; ///< TrustZone Memory Identifier +#ifdef RTX_TF_M_EXTENSION + uint32_t tz_module; ///< TrustZone Module Identifier +#endif +#if __RTX_CPU_STATISTICS__ + uint32_t swap_in_time; ///< the task schedule in time + uint32_t swap_out_time; ///< the task schedule out time + uint32_t rtime; ///< the task runing time after startup + uint32_t step_rtime; ///< the task runing time tile last show +#if TASK_HUNG_CHECK_ENABLED + uint32_t hung_check; + uint32_t hung_check_timeout; +#endif +#endif /* __RTX_CPU_STATISTICS__*/ +} osRtxThread_t; + + +// ==== Timer definitions ==== + +/// Timer State definitions +#define osRtxTimerInactive 0x00U ///< Timer Inactive +#define osRtxTimerStopped 0x01U ///< Timer Stopped +#define osRtxTimerRunning 0x02U ///< Timer Running + +/// Timer Type definitions +#define osRtxTimerPeriodic ((uint8_t)osTimerPeriodic) + +/// Timer Function Information +typedef struct { + osTimerFunc_t func; ///< Function Pointer + void *arg; ///< Function Argument +} osRtxTimerFinfo_t; + +/// Timer Control Block +typedef struct osRtxTimer_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t type; ///< Timer Type (Periodic/One-shot) + const char *name; ///< Object Name + struct osRtxTimer_s *prev; ///< Pointer to previous active Timer + struct osRtxTimer_s *next; ///< Pointer to next active Timer + uint32_t tick; ///< Timer current Tick + uint32_t load; ///< Timer Load value + osRtxTimerFinfo_t finfo; ///< Timer Function Info +} osRtxTimer_t; + + +// ==== Event Flags definitions ==== + +/// Event Flags Control Block +typedef struct { + uint8_t id; ///< Object Identifier + uint8_t reserved_state; ///< Object State (not used) + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Waiting Threads List + uint32_t event_flags; ///< Event Flags +} osRtxEventFlags_t; + + +// ==== Mutex definitions ==== + +/// Mutex Control Block +typedef struct osRtxMutex_s { + uint8_t id; ///< Object Identifier + uint8_t reserved_state; ///< Object State (not used) + uint8_t flags; ///< Object Flags + uint8_t attr; ///< Object Attributes + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Waiting Threads List + osRtxThread_t *owner_thread; ///< Owner Thread + struct osRtxMutex_s *owner_prev; ///< Pointer to previous owned Mutex + struct osRtxMutex_s *owner_next; ///< Pointer to next owned Mutex + uint8_t lock; ///< Lock counter + uint8_t padding[3]; +} osRtxMutex_t; + + +// ==== Semaphore definitions ==== + +/// Semaphore Control Block +typedef struct { + uint8_t id; ///< Object Identifier + uint8_t reserved_state; ///< Object State (not used) + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Waiting Threads List + uint16_t tokens; ///< Current number of tokens + uint16_t max_tokens; ///< Maximum number of tokens +} osRtxSemaphore_t; + + +// ==== Memory Pool definitions ==== + +/// Memory Pool Information +typedef struct { + uint32_t max_blocks; ///< Maximum number of Blocks + uint32_t used_blocks; ///< Number of used Blocks + uint32_t block_size; ///< Block Size + void *block_base; ///< Block Memory Base Address + void *block_lim; ///< Block Memory Limit Address + void *block_free; ///< First free Block Address +} osRtxMpInfo_t; + +/// Memory Pool Control Block +typedef struct { + uint8_t id; ///< Object Identifier + uint8_t reserved_state; ///< Object State (not used) + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Waiting Threads List + osRtxMpInfo_t mp_info; ///< Memory Pool Info +} osRtxMemoryPool_t; + + +// ==== Message Queue definitions ==== + +/// Message Control Block +typedef struct osRtxMessage_s { + uint8_t id; ///< Object Identifier + uint8_t reserved_state; ///< Object State (not used) + uint8_t flags; ///< Object Flags + uint8_t priority; ///< Message Priority + struct osRtxMessage_s *prev; ///< Pointer to previous Message + struct osRtxMessage_s *next; ///< Pointer to next Message +} osRtxMessage_t; + +/// Message Queue Control Block +typedef struct { + uint8_t id; ///< Object Identifier + uint8_t reserved_state; ///< Object State (not used) + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Waiting Threads List + osRtxMpInfo_t mp_info; ///< Memory Pool Info + uint32_t msg_size; ///< Message Size + uint32_t msg_count; ///< Number of queued Messages + osRtxMessage_t *msg_first; ///< Pointer to first Message + osRtxMessage_t *msg_last; ///< Pointer to last Message +} osRtxMessageQueue_t; + + +// ==== Generic Object definitions ==== + +/// Generic Object Control Block +typedef struct { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Threads List +} osRtxObject_t; + + +// ==== OS Runtime Information definitions ==== + +/// OS Runtime Information structure +typedef struct { + const char *os_id; ///< OS Identification + uint32_t version; ///< OS Version + struct { ///< Kernel Info + uint8_t state; ///< State + volatile uint8_t blocked; ///< Blocked + uint8_t pendSV; ///< Pending SV + uint8_t reserved; + uint32_t tick; ///< Tick counter + } kernel; + int32_t tick_irqn; ///< Tick Timer IRQ Number + struct { ///< Thread Info + struct { ///< Thread Run Info + osRtxThread_t *curr; ///< Current running Thread + osRtxThread_t *next; ///< Next Thread to Run + } run; + osRtxObject_t ready; ///< Ready List Object + osRtxThread_t *idle; ///< Idle Thread + osRtxThread_t *delay_list; ///< Delay List + osRtxThread_t *wait_list; ///< Wait List (no Timeout) + osRtxThread_t *terminate_list; ///< Terminate Thread List + struct { ///< Thread Round Robin Info + osRtxThread_t *thread; ///< Round Robin Thread + uint32_t tick; ///< Round Robin Time Tick + uint32_t timeout; ///< Round Robin Timeout + } robin; + } thread; + struct { ///< Timer Info + osRtxTimer_t *list; ///< Active Timer List + osRtxThread_t *thread; ///< Timer Thread + osRtxMessageQueue_t *mq; ///< Timer Message Queue + void (*tick)(void); ///< Timer Tick Function + } timer; + struct { ///< ISR Post Processing Queue + uint16_t max; ///< Maximum Items + uint16_t cnt; ///< Item Count + uint16_t in; ///< Incoming Item Index + uint16_t out; ///< Outgoing Item Index + void **data; ///< Queue Data + } isr_queue; + struct { ///< ISR Post Processing functions + void (*thread)(osRtxThread_t*); ///< Thread Post Processing function + void (*event_flags)(osRtxEventFlags_t*); ///< Event Flags Post Processing function + void (*semaphore)(osRtxSemaphore_t*); ///< Semaphore Post Processing function + void (*memory_pool)(osRtxMemoryPool_t*); ///< Memory Pool Post Processing function + void (*message)(osRtxMessage_t*); ///< Message Post Processing function + } post_process; + struct { ///< Memory Pools (Variable Block Size) + void *stack; ///< Stack Memory + void *mp_data; ///< Memory Pool Data Memory + void *mq_data; ///< Message Queue Data Memory + void *common; ///< Common Memory + } mem; + struct { ///< Memory Pools (Fixed Block Size) + osRtxMpInfo_t *stack; ///< Stack for Threads + osRtxMpInfo_t *thread; ///< Thread Control Blocks + osRtxMpInfo_t *timer; ///< Timer Control Blocks + osRtxMpInfo_t *event_flags; ///< Event Flags Control Blocks + osRtxMpInfo_t *mutex; ///< Mutex Control Blocks + osRtxMpInfo_t *semaphore; ///< Semaphore Control Blocks + osRtxMpInfo_t *memory_pool; ///< Memory Pool Control Blocks + osRtxMpInfo_t *message_queue; ///< Message Queue Control Blocks + } mpi; +} osRtxInfo_t; + +extern osRtxInfo_t osRtxInfo; ///< OS Runtime Information + +/// OS Runtime Object Memory Usage structure +typedef struct { + uint32_t cnt_alloc; ///< Counter for alloc + uint32_t cnt_free; ///< Counter for free + uint32_t max_used; ///< Maximum used +} osRtxObjectMemUsage_t; + +/// OS Runtime Object Memory Usage variables +extern osRtxObjectMemUsage_t osRtxThreadMemUsage; +extern osRtxObjectMemUsage_t osRtxTimerMemUsage; +extern osRtxObjectMemUsage_t osRtxEventFlagsMemUsage; +extern osRtxObjectMemUsage_t osRtxMutexMemUsage; +extern osRtxObjectMemUsage_t osRtxSemaphoreMemUsage; +extern osRtxObjectMemUsage_t osRtxMemoryPoolMemUsage; +extern osRtxObjectMemUsage_t osRtxMessageQueueMemUsage; + + +// ==== OS API definitions ==== + +// Object Limits definitions +#define osRtxThreadFlagsLimit 31U ///< number of Thread Flags available per thread +#define osRtxEventFlagsLimit 31U ///< number of Event Flags available per object +#define osRtxMutexLockLimit 255U ///< maximum number of recursive mutex locks +#define osRtxSemaphoreTokenLimit 65535U ///< maximum number of tokens per semaphore + +// Control Block sizes +#define osRtxThreadCbSize sizeof(osRtxThread_t) +#define osRtxTimerCbSize sizeof(osRtxTimer_t) +#define osRtxEventFlagsCbSize sizeof(osRtxEventFlags_t) +#define osRtxMutexCbSize sizeof(osRtxMutex_t) +#define osRtxSemaphoreCbSize sizeof(osRtxSemaphore_t) +#define osRtxMemoryPoolCbSize sizeof(osRtxMemoryPool_t) +#define osRtxMessageQueueCbSize sizeof(osRtxMessageQueue_t) + +/// Memory size in bytes for Memory Pool storage. +/// \param block_count maximum number of memory blocks in memory pool. +/// \param block_size memory block size in bytes. +#define osRtxMemoryPoolMemSize(block_count, block_size) \ + (4*(block_count)*(((block_size)+3)/4)) + +/// Memory size in bytes for Message Queue storage. +/// \param msg_count maximum number of messages in queue. +/// \param msg_size maximum message size in bytes. +#define osRtxMessageQueueMemSize(msg_count, msg_size) \ + (4*(msg_count)*(3+(((msg_size)+3)/4))) + + +// ==== OS External Functions ==== + +// OS Error Codes +#define osRtxErrorStackUnderflow 1U ///< Stack overflow, i.e. stack pointer below its lower memory limit for descending stacks. +#define osRtxErrorISRQueueOverflow 2U ///< ISR Queue overflow detected when inserting object. +#define osRtxErrorTimerQueueOverflow 3U ///< User Timer Callback Queue overflow detected for timer. +#define osRtxErrorClibSpace 4U ///< Standard C/C++ library libspace not available: increase \c OS_THREAD_LIBSPACE_NUM. +#define osRtxErrorClibMutex 5U ///< Standard C/C++ library mutex initialization failed. + +/// OS Error Callback function +extern uint32_t osRtxErrorNotify (uint32_t code, void *object_id); + +/// OS Idle Thread +extern void osRtxIdleThread (void *argument); + +/// OS Exception handlers +extern void SVC_Handler (void); +extern void PendSV_Handler (void); +extern void SysTick_Handler (void); + +/// OS Trusted Firmware M Extension +#ifdef RTX_TF_M_EXTENSION +extern uint32_t osRtxTzGetModuleId (void); +#endif + + +// ==== OS External Configuration ==== + +/// OS Configuration flags +#define osRtxConfigPrivilegedMode (1UL<<0) ///< Threads in Privileged mode +#define osRtxConfigStackCheck (1UL<<1) ///< Stack overrun checking +#define osRtxConfigStackWatermark (1UL<<2) ///< Stack usage Watermark + +/// OS Configuration structure +typedef struct { + uint32_t flags; ///< OS Configuration Flags + uint32_t tick_freq; ///< Kernel Tick Frequency + uint32_t robin_timeout; ///< Round Robin Timeout Tick + struct { ///< ISR Post Processing Queue + void **data; ///< Queue Data + uint16_t max; ///< Maximum Items + uint16_t padding; + } isr_queue; + struct { ///< Memory Pools (Variable Block Size) + void *stack_addr; ///< Stack Memory Address + uint32_t stack_size; ///< Stack Memory Size + void *mp_data_addr; ///< Memory Pool Memory Address + uint32_t mp_data_size; ///< Memory Pool Memory Size + void *mq_data_addr; ///< Message Queue Data Memory Address + uint32_t mq_data_size; ///< Message Queue Data Memory Size + void *common_addr; ///< Common Memory Address + uint32_t common_size; ///< Common Memory Size + } mem; + struct { ///< Memory Pools (Fixed Block Size) + osRtxMpInfo_t *stack; ///< Stack for Threads + osRtxMpInfo_t *thread; ///< Thread Control Blocks + osRtxMpInfo_t *timer; ///< Timer Control Blocks + osRtxMpInfo_t *event_flags; ///< Event Flags Control Blocks + osRtxMpInfo_t *mutex; ///< Mutex Control Blocks + osRtxMpInfo_t *semaphore; ///< Semaphore Control Blocks + osRtxMpInfo_t *memory_pool; ///< Memory Pool Control Blocks + osRtxMpInfo_t *message_queue; ///< Message Queue Control Blocks + } mpi; + uint32_t thread_stack_size; ///< Default Thread Stack Size + const + osThreadAttr_t *idle_thread_attr; ///< Idle Thread Attributes + const + osThreadAttr_t *timer_thread_attr; ///< Timer Thread Attributes + const + osMessageQueueAttr_t *timer_mq_attr; ///< Timer Message Queue Attributes + uint32_t timer_mq_mcnt; ///< Timer Message Queue maximum Messages +} osRtxConfig_t; + +extern const osRtxConfig_t osRtxConfig; ///< OS Configuration + + +#ifdef __cplusplus +} +#endif + +#endif // RTX_OS_H_ diff --git a/platform/Makefile b/platform/Makefile new file mode 100644 index 0000000..274e9c9 --- /dev/null +++ b/platform/Makefile @@ -0,0 +1,7 @@ +obj-y := cmsis/ drivers/ hal/ + +ifneq ($(DUAL_BOOT),1) +obj-y += main/ +endif + +subdir-ccflags-y += -Iplatform/cmsis/inc -Iplatform/hal -Iutils/hwtimer_list \ No newline at end of file diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/BasicMathFunctions.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/BasicMathFunctions.c new file mode 100644 index 0000000..b444c11 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/BasicMathFunctions.c @@ -0,0 +1,63 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: BasicMathFunctions.c + * Description: Combination of all basic math function source files. + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_abs_f32.c" +#include "arm_abs_q15.c" +#include "arm_abs_q31.c" +#include "arm_abs_q7.c" +#include "arm_add_f32.c" +#include "arm_add_q15.c" +#include "arm_add_q31.c" +#include "arm_add_q7.c" +#include "arm_dot_prod_f32.c" +#include "arm_dot_prod_q15.c" +#include "arm_dot_prod_q31.c" +#include "arm_dot_prod_q7.c" +#include "arm_mult_f32.c" +#include "arm_mult_q15.c" +#include "arm_mult_q31.c" +#include "arm_mult_q7.c" +#include "arm_negate_f32.c" +#include "arm_negate_q15.c" +#include "arm_negate_q31.c" +#include "arm_negate_q7.c" +#include "arm_offset_f32.c" +#include "arm_offset_q15.c" +#include "arm_offset_q31.c" +#include "arm_offset_q7.c" +#include "arm_scale_f32.c" +#include "arm_scale_q15.c" +#include "arm_scale_q31.c" +#include "arm_scale_q7.c" +#include "arm_shift_q15.c" +#include "arm_shift_q31.c" +#include "arm_shift_q7.c" +#include "arm_sub_f32.c" +#include "arm_sub_q15.c" +#include "arm_sub_q31.c" +#include "arm_sub_q7.c" diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/Makefile b/platform/cmsis/DSP_Lib/BasicMathFunctions/Makefile new file mode 100644 index 0000000..88c2e8b --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/Makefile @@ -0,0 +1,6 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out %Functions.c,$(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_f32.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_f32.c new file mode 100644 index 0000000..295939a --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_f32.c @@ -0,0 +1,117 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_abs_f32.c + * Description: Floating-point vector absolute value + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include + +/** + @ingroup groupMath + */ + +/** + @defgroup BasicAbs Vector Absolute Value + + Computes the absolute value of a vector on an element-by-element basis. + +
+      pDst[n] = abs(pSrc[n]),   0 <= n < blockSize.
+  
+ + The functions support in-place computation allowing the source and + destination pointers to reference the same memory buffer. + There are separate functions for floating-point, Q7, Q15, and Q31 data types. + */ + +/** + @addtogroup BasicAbs + @{ + */ + +/** + @brief Floating-point vector absolute value. + @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_abs_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = |A| */ + + /* Calculate absolute and store result in destination buffer. */ + *pDst++ = fabsf(*pSrc++); + + *pDst++ = fabsf(*pSrc++); + + *pDst++ = fabsf(*pSrc++); + + *pDst++ = fabsf(*pSrc++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = |A| */ + + /* Calculate absolute and store result in destination buffer. */ + *pDst++ = fabsf(*pSrc++); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicAbs group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q15.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q15.c new file mode 100644 index 0000000..eb944ce --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q15.c @@ -0,0 +1,132 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_abs_q15.c + * Description: Q15 vector absolute value + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicAbs + @{ + */ + +/** + @brief Q15 vector absolute value. + @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 + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + The Q15 value -1 (0x8000) will be saturated to the maximum allowable positive value 0x7FFF. + */ + +void arm_abs_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + q15_t in; /* Temporary input variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = |A| */ + + /* Calculate absolute of input (if -1 then saturated to 0x7fff) and store result in destination buffer. */ + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in); +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in); +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in); +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = |A| */ + + /* Calculate absolute of input (if -1 then saturated to 0x7fff) and store result in destination buffer. */ + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q15_t)__QSUB16(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicAbs group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q31.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q31.c new file mode 100644 index 0000000..bf7608b --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q31.c @@ -0,0 +1,132 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_abs_q31.c + * Description: Q31 vector absolute value + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicAbs + @{ + */ + +/** + @brief Q31 vector absolute value. + @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 + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + The Q31 value -1 (0x80000000) will be saturated to the maximum allowable positive value 0x7FFFFFFF. + */ + +void arm_abs_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t in; /* Temporary variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = |A| */ + + /* Calculate absolute of input (if -1 then saturated to 0x7fffffff) and store result in destination buffer. */ + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in); +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in); +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in); +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = |A| */ + + /* Calculate absolute of input (if -1 then saturated to 0x7fffffff) and store result in destination buffer. */ + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q31_t)__QSUB(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicAbs group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q7.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q7.c new file mode 100644 index 0000000..a6c4a6c --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_abs_q7.c @@ -0,0 +1,134 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_abs_q7.c + * Description: Q7 vector absolute value + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicAbs + @{ + */ + +/** + @brief Q7 vector absolute value. + @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 + + @par Conditions for optimum performance + Input and output buffers should be aligned by 32-bit + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + The Q7 value -1 (0x80) will be saturated to the maximum allowable positive value 0x7F. + */ + +void arm_abs_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + q7_t in; /* Temporary input variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = |A| */ + + /* Calculate absolute of input (if -1 then saturated to 0x7f) and store result in destination buffer. */ + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q7_t)__QSUB(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in); +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q7_t)__QSUB(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in); +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q7_t)__QSUB(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in); +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q7_t)__QSUB(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = |A| */ + + /* Calculate absolute of input (if -1 then saturated to 0x7f) and store result in destination buffer. */ + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = (in > 0) ? in : (q7_t) __QSUB(0, in); +#else + *pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? (q7_t) 0x7f : -in); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicAbs group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_f32.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_f32.c new file mode 100644 index 0000000..e48e1d5 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_f32.c @@ -0,0 +1,113 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_add_f32.c + * Description: Floating-point vector addition + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @defgroup BasicAdd Vector Addition + + Element-by-element addition of two vectors. + +
+      pDst[n] = pSrcA[n] + pSrcB[n],   0 <= n < blockSize.
+  
+ + There are separate functions for floating-point, Q7, Q15, and Q31 data types. + */ + +/** + @addtogroup BasicAdd + @{ + */ + +/** + @brief Floating-point vector addition. + @param[in] pSrcA points to first input vector + @param[in] pSrcB points to second input vector + @param[out] pDst points to output vector + @param[in] blockSize number of samples in each vector + @return none + */ + +void arm_add_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A + B */ + + /* Add and store result in destination buffer. */ + *pDst++ = (*pSrcA++) + (*pSrcB++); + *pDst++ = (*pSrcA++) + (*pSrcB++); + *pDst++ = (*pSrcA++) + (*pSrcB++); + *pDst++ = (*pSrcA++) + (*pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A + B */ + + /* Add and store result in destination buffer. */ + *pDst++ = (*pSrcA++) + (*pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicAdd group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q15.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q15.c new file mode 100644 index 0000000..bc62937 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q15.c @@ -0,0 +1,126 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_add_q15.c + * Description: Q15 vector addition + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicAdd + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated. + */ + +void arm_add_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q31_t inA1, inA2; + q31_t inB1, inB2; +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A + B */ + +#if defined (ARM_MATH_DSP) + /* read 2 times 2 samples at a time from sourceA */ + inA1 = read_q15x2_ia ((q15_t **) &pSrcA); + inA2 = read_q15x2_ia ((q15_t **) &pSrcA); + /* read 2 times 2 samples at a time from sourceB */ + inB1 = read_q15x2_ia ((q15_t **) &pSrcB); + inB2 = read_q15x2_ia ((q15_t **) &pSrcB); + + /* Add and store 2 times 2 samples at a time */ + write_q15x2_ia (&pDst, __QADD16(inA1, inB1)); + write_q15x2_ia (&pDst, __QADD16(inA2, inB2)); +#else + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16); + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16); + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16); + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A + B */ + + /* Add and store result in destination buffer. */ +#if defined (ARM_MATH_DSP) + *pDst++ = (q15_t) __QADD16(*pSrcA++, *pSrcB++); +#else + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ + *pSrcB++), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicAdd group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q31.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q31.c new file mode 100644 index 0000000..3c1cbc2 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q31.c @@ -0,0 +1,108 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_add_q31.c + * Description: Q31 vector addition + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicAdd + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated. + */ + +void arm_add_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A + B */ + + /* Add and store result in destination buffer. */ + *pDst++ = __QADD(*pSrcA++, *pSrcB++); + + *pDst++ = __QADD(*pSrcA++, *pSrcB++); + + *pDst++ = __QADD(*pSrcA++, *pSrcB++); + + *pDst++ = __QADD(*pSrcA++, *pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A + B */ + + /* Add and store result in destination buffer. */ + *pDst++ = __QADD(*pSrcA++, *pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicAdd group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q7.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q7.c new file mode 100644 index 0000000..f9c4a95 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_add_q7.c @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_add_q7.c + * Description: Q7 vector addition + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicAdd + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q7 range [0x80 0x7F] are saturated. + */ + +void arm_add_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A + B */ + +#if defined (ARM_MATH_DSP) + /* Add and store result in destination buffer (4 samples at a time). */ + write_q7x4_ia (&pDst, __QADD8 (read_q7x4_ia ((q7_t **) &pSrcA), read_q7x4_ia ((q7_t **) &pSrcB))); +#else + *pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8); + *pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8); + *pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8); + *pDst++ = (q7_t) __SSAT ((q15_t) *pSrcA++ + *pSrcB++, 8); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A + B */ + + /* Add and store result in destination buffer. */ + *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ + *pSrcB++, 8); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicAdd group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_f32.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_f32.c new file mode 100644 index 0000000..d7f2464 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_f32.c @@ -0,0 +1,120 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_dot_prod_f32.c + * Description: Floating-point dot product + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @defgroup BasicDotProd Vector Dot Product + + Computes the dot product of two vectors. + The vectors are multiplied element-by-element and then summed. + +
+      sum = pSrcA[0]*pSrcB[0] + pSrcA[1]*pSrcB[1] + ... + pSrcA[blockSize-1]*pSrcB[blockSize-1]
+  
+ + There are separate functions for floating-point, Q7, Q15, and Q31 data types. + */ + +/** + @addtogroup BasicDotProd + @{ + */ + +/** + @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. + @return none + */ + +void arm_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t blockSize, + float32_t * result) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t sum = 0.0f; /* Temporary return variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */ + + /* Calculate dot product and store result in a temporary buffer. */ + sum += (*pSrcA++) * (*pSrcB++); + + sum += (*pSrcA++) * (*pSrcB++); + + sum += (*pSrcA++) * (*pSrcB++); + + sum += (*pSrcA++) * (*pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */ + + /* Calculate dot product and store result in a temporary buffer. */ + sum += (*pSrcA++) * (*pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store result in destination buffer */ + *result = sum; +} + +/** + @} end of BasicDotProd group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q15.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q15.c new file mode 100644 index 0000000..e303b09 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q15.c @@ -0,0 +1,120 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_dot_prod_q15.c + * Description: Q15 dot product + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicDotProd + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The intermediate multiplications are in 1.15 x 1.15 = 2.30 format and these + results are added to a 64-bit accumulator in 34.30 format. + Nonsaturating additions are used and given that there are 33 guard bits in the accumulator + there is no risk of overflow. + The return result is in 34.30 format. + */ + +void arm_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t blockSize, + q63_t * result) +{ + uint32_t blkCnt; /* Loop counter */ + q63_t sum = 0; /* Temporary return variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */ + +#if defined (ARM_MATH_DSP) + /* Calculate dot product and store result in a temporary buffer. */ + sum = __SMLALD(read_q15x2_ia ((q15_t **) &pSrcA), read_q15x2_ia ((q15_t **) &pSrcB), sum); + sum = __SMLALD(read_q15x2_ia ((q15_t **) &pSrcA), read_q15x2_ia ((q15_t **) &pSrcB), sum); +#else + sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++); + sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++); + sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++); + sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */ + + /* Calculate dot product and store result in a temporary buffer. */ +//#if defined (ARM_MATH_DSP) +// sum = __SMLALD(*pSrcA++, *pSrcB++, sum); +//#else + sum += (q63_t)((q31_t) *pSrcA++ * *pSrcB++); +//#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store result in destination buffer in 34.30 format */ + *result = sum; +} + +/** + @} end of BasicDotProd group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q31.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q31.c new file mode 100644 index 0000000..76cd577 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q31.c @@ -0,0 +1,115 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_dot_prod_q31.c + * Description: Q31 dot product + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicDotProd + @{ + */ + +/** + @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. + @return none + + @par Scaling and Overflow Behavior + The intermediate multiplications are in 1.31 x 1.31 = 2.62 format and these + are truncated to 2.48 format by discarding the lower 14 bits. + The 2.48 result is then added without saturation to a 64-bit accumulator in 16.48 format. + There are 15 guard bits in the accumulator and there is no risk of overflow as long as + the length of the vectors is less than 2^16 elements. + The return result is in 16.48 format. + */ + +void arm_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t blockSize, + q63_t * result) +{ + uint32_t blkCnt; /* Loop counter */ + q63_t sum = 0; /* Temporary return variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */ + + /* Calculate dot product and store result in a temporary buffer. */ + sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U; + + sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U; + + sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U; + + sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */ + + /* Calculate dot product and store result in a temporary buffer. */ + sum += ((q63_t) *pSrcA++ * *pSrcB++) >> 14U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store result in destination buffer in 16.48 format */ + *result = sum; +} + +/** + @} end of BasicDotProd group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q7.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q7.c new file mode 100644 index 0000000..8e18a73 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_dot_prod_q7.c @@ -0,0 +1,139 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_dot_prod_q7.c + * Description: Q7 dot product + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicDotProd + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The intermediate multiplications are in 1.7 x 1.7 = 2.14 format and these + results are added to an accumulator in 18.14 format. + Nonsaturating additions are used and there is no danger of wrap around as long as + the vectors are less than 2^18 elements long. + The return result is in 18.14 format. + */ + +void arm_dot_prod_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + uint32_t blockSize, + q31_t * result) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t sum = 0; /* Temporary return variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q31_t input1, input2; /* Temporary variables */ + q31_t inA1, inA2, inB1, inB2; /* Temporary variables */ +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */ + +#if defined (ARM_MATH_DSP) + /* read 4 samples at a time from sourceA */ + input1 = read_q7x4_ia ((q7_t **) &pSrcA); + /* read 4 samples at a time from sourceB */ + input2 = read_q7x4_ia ((q7_t **) &pSrcB); + + /* extract two q7_t samples to q15_t samples */ + inA1 = __SXTB16(__ROR(input1, 8)); + /* extract reminaing two samples */ + inA2 = __SXTB16(input1); + /* extract two q7_t samples to q15_t samples */ + inB1 = __SXTB16(__ROR(input2, 8)); + /* extract reminaing two samples */ + inB2 = __SXTB16(input2); + + /* multiply and accumulate two samples at a time */ + sum = __SMLAD(inA1, inB1, sum); + sum = __SMLAD(inA2, inB2, sum); +#else + sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++); + sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++); + sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++); + sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */ + + /* Calculate dot product and store result in a temporary buffer. */ +//#if defined (ARM_MATH_DSP) +// sum = __SMLAD(*pSrcA++, *pSrcB++, sum); +//#else + sum += (q31_t) ((q15_t) *pSrcA++ * *pSrcB++); +//#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store result in destination buffer in 18.14 format */ + *result = sum; +} + +/** + @} end of BasicDotProd group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_f32.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_f32.c new file mode 100644 index 0000000..24f74f0 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_f32.c @@ -0,0 +1,116 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mult_f32.c + * Description: Floating-point vector multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @defgroup BasicMult Vector Multiplication + + Element-by-element multiplication of two vectors. + +
+      pDst[n] = pSrcA[n] * pSrcB[n],   0 <= n < blockSize.
+  
+ + There are separate functions for floating-point, Q7, Q15, and Q31 data types. + */ + +/** + @addtogroup BasicMult + @{ + */ + +/** + @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. + @return none + */ + +void arm_mult_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A * B */ + + /* Multiply inputs and store result in destination buffer. */ + *pDst++ = (*pSrcA++) * (*pSrcB++); + + *pDst++ = (*pSrcA++) * (*pSrcB++); + + *pDst++ = (*pSrcA++) * (*pSrcB++); + + *pDst++ = (*pSrcA++) * (*pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A * B */ + + /* Multiply input and store result in destination buffer. */ + *pDst++ = (*pSrcA++) * (*pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicMult group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q15.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q15.c new file mode 100644 index 0000000..37aa924 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q15.c @@ -0,0 +1,143 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mult_q15.c + * Description: Q15 vector multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicMult + @{ + */ + +/** + @brief Q15 vector multiplication + @param[in] pSrcA points to first input vector + @param[in] pSrcB points to second input vector + @param[out] pDst points to output vector + @param[in] blockSize number of samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated. + */ + +void arm_mult_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q31_t inA1, inA2, inB1, inB2; /* Temporary input variables */ + q15_t out1, out2, out3, out4; /* Temporary output variables */ + q31_t mul1, mul2, mul3, mul4; /* Temporary variables */ +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A * B */ + +#if defined (ARM_MATH_DSP) + /* read 2 samples at a time from sourceA */ + inA1 = read_q15x2_ia ((q15_t **) &pSrcA); + /* read 2 samples at a time from sourceB */ + inB1 = read_q15x2_ia ((q15_t **) &pSrcB); + /* read 2 samples at a time from sourceA */ + inA2 = read_q15x2_ia ((q15_t **) &pSrcA); + /* read 2 samples at a time from sourceB */ + inB2 = read_q15x2_ia ((q15_t **) &pSrcB); + + /* multiply mul = sourceA * sourceB */ + mul1 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16)); + mul2 = (q31_t) ((q15_t) (inA1 ) * (q15_t) (inB1 )); + mul3 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB2 >> 16)); + mul4 = (q31_t) ((q15_t) (inA2 ) * (q15_t) (inB2 )); + + /* saturate result to 16 bit */ + out1 = (q15_t) __SSAT(mul1 >> 15, 16); + out2 = (q15_t) __SSAT(mul2 >> 15, 16); + out3 = (q15_t) __SSAT(mul3 >> 15, 16); + out4 = (q15_t) __SSAT(mul4 >> 15, 16); + + /* store result to destination */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pDst, __PKHBT(out2, out1, 16)); + write_q15x2_ia (&pDst, __PKHBT(out4, out3, 16)); +#else + write_q15x2_ia (&pDst, __PKHBT(out1, out2, 16)); + write_q15x2_ia (&pDst, __PKHBT(out3, out4, 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + +#else + *pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16); + *pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16); + *pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16); + *pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A * B */ + + /* Multiply inputs and store result in destination buffer. */ + *pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicMult group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q31.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q31.c new file mode 100644 index 0000000..9592684 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q31.c @@ -0,0 +1,119 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mult_q31.c + * Description: Q31 vector multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicMult + @{ + */ + +/** + @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. + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] are saturated. + */ + +void arm_mult_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t out; /* Temporary output variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A * B */ + + /* Multiply inputs and store result in destination buffer. */ + out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32; + out = __SSAT(out, 31); + *pDst++ = out << 1U; + + out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32; + out = __SSAT(out, 31); + *pDst++ = out << 1U; + + out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32; + out = __SSAT(out, 31); + *pDst++ = out << 1U; + + out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32; + out = __SSAT(out, 31); + *pDst++ = out << 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A * B */ + + /* Multiply inputs and store result in destination buffer. */ + out = ((q63_t) *pSrcA++ * *pSrcB++) >> 32; + out = __SSAT(out, 31); + *pDst++ = out << 1U; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicMult group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q7.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q7.c new file mode 100644 index 0000000..5587ce5 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_mult_q7.c @@ -0,0 +1,119 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mult_q7.c + * Description: Q7 vector multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicMult + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q7 range [0x80 0x7F] are saturated. + */ + +void arm_mult_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q7_t out1, out2, out3, out4; /* Temporary output variables */ +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A * B */ + +#if defined (ARM_MATH_DSP) + /* Multiply inputs and store results in temporary variables */ + out1 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8); + out2 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8); + out3 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8); + out4 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8); + + /* Pack and store result in destination buffer (in single write) */ + write_q7x4_ia (&pDst, __PACKq7(out1, out2, out3, out4)); +#else + *pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8); + *pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8); + *pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8); + *pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A * B */ + + /* Multiply input and store result in destination buffer. */ + *pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicMult group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_f32.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_f32.c new file mode 100644 index 0000000..fc020df --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_f32.c @@ -0,0 +1,116 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_negate_f32.c + * Description: Negates floating-point vectors + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @defgroup BasicNegate Vector Negate + + Negates the elements of a vector. + +
+      pDst[n] = -pSrc[n],   0 <= n < blockSize.
+  
+ + The functions support in-place computation allowing the source and + destination pointers to reference the same memory buffer. + There are separate functions for floating-point, Q7, Q15, and Q31 data types. + */ + +/** + @addtogroup BasicNegate + @{ + */ + +/** + @brief Negates the elements of a floating-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_negate_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = -A */ + + /* Negate and store result in destination buffer. */ + *pDst++ = -*pSrc++; + + *pDst++ = -*pSrc++; + + *pDst++ = -*pSrc++; + + *pDst++ = -*pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = -A */ + + /* Negate and store result in destination buffer. */ + *pDst++ = -*pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicNegate group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q15.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q15.c new file mode 100644 index 0000000..267e4cc --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q15.c @@ -0,0 +1,126 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_negate_q15.c + * Description: Negates Q15 vectors + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicNegate + @{ + */ + +/** + @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 each vector. + @return none + + @par Conditions for optimum performance + Input and output buffers should be aligned by 32-bit + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + The Q15 value -1 (0x8000) is saturated to the maximum allowable positive value 0x7FFF. + */ + +void arm_negate_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + q15_t in; /* Temporary input variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q31_t in1; /* Temporary input variables */ +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = -A */ + +#if defined (ARM_MATH_DSP) + /* Negate and store result in destination buffer (2 samples at a time). */ + in1 = read_q15x2_ia ((q15_t **) &pSrc); + write_q15x2_ia (&pDst, __QSUB16(0, in1)); + + in1 = read_q15x2_ia ((q15_t **) &pSrc); + write_q15x2_ia (&pDst, __QSUB16(0, in1)); +#else + in = *pSrc++; + *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in; + + in = *pSrc++; + *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in; + + in = *pSrc++; + *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in; + + in = *pSrc++; + *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in; +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = -A */ + + /* Negate and store result in destination buffer. */ + in = *pSrc++; + *pDst++ = (in == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicNegate group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q31.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q31.c new file mode 100644 index 0000000..645fb0a --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q31.c @@ -0,0 +1,132 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_negate_q31.c + * Description: Negates Q31 vectors + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicNegate + @{ + */ + +/** + @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 each vector. + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + The Q31 value -1 (0x80000000) is saturated to the maximum allowable positive value 0x7FFFFFFF. + */ + +void arm_negate_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t in; /* Temporary input variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = -A */ + + /* Negate and store result in destination buffer. */ + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __QSUB(0, in); +#else + *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in; +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __QSUB(0, in); +#else + *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in; +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __QSUB(0, in); +#else + *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in; +#endif + + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __QSUB(0, in); +#else + *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in; +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = -A */ + + /* Negate and store result in destination buffer. */ + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __QSUB(0, in); +#else + *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in; +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicNegate group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q7.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q7.c new file mode 100644 index 0000000..40a373e --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_negate_q7.c @@ -0,0 +1,126 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_negate_q7.c + * Description: Negates Q7 vectors + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicNegate + @{ + */ + +/** + @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 each vector. + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + The Q7 value -1 (0x80) is saturated to the maximum allowable positive value 0x7F. + */ + +void arm_negate_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + q7_t in; /* Temporary input variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q31_t in1; /* Temporary input variable */ +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = -A */ + +#if defined (ARM_MATH_DSP) + /* Negate and store result in destination buffer (4 samples at a time). */ + in1 = read_q7x4_ia ((q7_t **) &pSrc); + write_q7x4_ia (&pDst, __QSUB8(0, in1)); +#else + in = *pSrc++; + *pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in; + + in = *pSrc++; + *pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in; + + in = *pSrc++; + *pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in; + + in = *pSrc++; + *pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in; +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = -A */ + + /* Negate and store result in destination buffer. */ + in = *pSrc++; + +#if defined (ARM_MATH_DSP) + *pDst++ = (q7_t) __QSUB(0, in); +#else + *pDst++ = (in == (q7_t) 0x80) ? (q7_t) 0x7f : -in; +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicNegate group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_f32.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_f32.c new file mode 100644 index 0000000..43c894f --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_f32.c @@ -0,0 +1,118 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_offset_f32.c + * Description: Floating-point vector offset + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @defgroup BasicOffset Vector Offset + + Adds a constant offset to each element of a vector. + +
+      pDst[n] = pSrc[n] + offset,   0 <= n < blockSize.
+  
+ + The functions support in-place computation allowing the source and + destination pointers to reference the same memory buffer. + There are separate functions for floating-point, Q7, Q15, and Q31 data types. + */ + +/** + @addtogroup BasicOffset + @{ + */ + +/** + @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 each vector + @return none + */ + +void arm_offset_f32( + const float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A + offset */ + + /* Add offset and store result in destination buffer. */ + *pDst++ = (*pSrc++) + offset; + + *pDst++ = (*pSrc++) + offset; + + *pDst++ = (*pSrc++) + offset; + + *pDst++ = (*pSrc++) + offset; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A + offset */ + + /* Add offset and store result in destination buffer. */ + *pDst++ = (*pSrc++) + offset; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicOffset group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q15.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q15.c new file mode 100644 index 0000000..cd2f22b --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q15.c @@ -0,0 +1,121 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_offset_q15.c + * Description: Q15 vector offset + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicOffset + @{ + */ + +/** + @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 each vector + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated. + */ + +void arm_offset_q15( + const q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q31_t offset_packed; /* Offset packed to 32 bit */ + + /* Offset is packed to 32 bit in order to use SIMD32 for addition */ + offset_packed = __PKHBT(offset, offset, 16); +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A + offset */ + +#if defined (ARM_MATH_DSP) + /* Add offset and store result in destination buffer (2 samples at a time). */ + write_q15x2_ia (&pDst, __QADD16(read_q15x2_ia ((q15_t **) &pSrc), offset_packed)); + write_q15x2_ia (&pDst, __QADD16(read_q15x2_ia ((q15_t **) &pSrc), offset_packed)); +#else + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16); + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16); + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16); + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A + offset */ + + /* Add offset and store result in destination buffer. */ +#if defined (ARM_MATH_DSP) + *pDst++ = (q15_t) __QADD16(*pSrc++, offset); +#else + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrc++ + offset), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicOffset group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q31.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q31.c new file mode 100644 index 0000000..5de36b4 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q31.c @@ -0,0 +1,128 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_offset_q31.c + * Description: Q31 vector offset + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicOffset + @{ + */ + +/** + @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 each vector + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated. + */ + +void arm_offset_q31( + const q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A + offset */ + + /* Add offset and store result in destination buffer. */ +#if defined (ARM_MATH_DSP) + *pDst++ = __QADD(*pSrc++, offset); +#else + *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset); +#endif + +#if defined (ARM_MATH_DSP) + *pDst++ = __QADD(*pSrc++, offset); +#else + *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset); +#endif + +#if defined (ARM_MATH_DSP) + *pDst++ = __QADD(*pSrc++, offset); +#else + *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset); +#endif + +#if defined (ARM_MATH_DSP) + *pDst++ = __QADD(*pSrc++, offset); +#else + *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A + offset */ + + /* Add offset and store result in destination buffer. */ +#if defined (ARM_MATH_DSP) + *pDst++ = __QADD(*pSrc++, offset); +#else + *pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicOffset group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q7.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q7.c new file mode 100644 index 0000000..f67db45 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_offset_q7.c @@ -0,0 +1,116 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_offset_q7.c + * Description: Q7 vector offset + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicOffset + @{ + */ + +/** + @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 each vector + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q7 range [0x80 0x7F] are saturated. + */ + +void arm_offset_q7( + const q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q31_t offset_packed; /* Offset packed to 32 bit */ + + /* Offset is packed to 32 bit in order to use SIMD32 for addition */ + offset_packed = __PACKq7(offset, offset, offset, offset); +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A + offset */ + +#if defined (ARM_MATH_DSP) + /* Add offset and store result in destination buffer (4 samples at a time). */ + write_q7x4_ia (&pDst, __QADD8(read_q7x4_ia ((q7_t **) &pSrc), offset_packed)); +#else + *pDst++ = (q7_t) __SSAT(*pSrc++ + offset, 8); + *pDst++ = (q7_t) __SSAT(*pSrc++ + offset, 8); + *pDst++ = (q7_t) __SSAT(*pSrc++ + offset, 8); + *pDst++ = (q7_t) __SSAT(*pSrc++ + offset, 8); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A + offset */ + + /* Add offset and store result in destination buffer. */ + *pDst++ = (q7_t) __SSAT((q15_t) *pSrc++ + offset, 8); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicOffset group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_f32.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_f32.c new file mode 100644 index 0000000..675f396 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_f32.c @@ -0,0 +1,131 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_scale_f32.c + * Description: Multiplies a floating-point vector by a scalar + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @defgroup BasicScale Vector Scale + + Multiply a vector by a scalar value. For floating-point data, the algorithm used is: + +
+      pDst[n] = pSrc[n] * scale,   0 <= n < blockSize.
+  
+ + In the fixed-point Q7, Q15, and Q31 functions, scale is represented by + a fractional multiplication scaleFract and an arithmetic shift shift. + The shift allows the gain of the scaling operation to exceed 1.0. + The algorithm used with fixed-point data is: + +
+      pDst[n] = (pSrc[n] * scaleFract) << shift,   0 <= n < blockSize.
+  
+ + The overall scale factor applied to the fixed-point data is +
+      scale = scaleFract * 2^shift.
+  
+ + The functions support in-place computation allowing the source and destination + pointers to reference the same memory buffer. + */ + +/** + @addtogroup BasicScale + @{ + */ + +/** + @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 each vector + @return none + */ + +void arm_scale_f32( + const float32_t *pSrc, + float32_t scale, + float32_t *pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A * scale */ + + /* Scale input and store result in destination buffer. */ + *pDst++ = (*pSrc++) * scale; + + *pDst++ = (*pSrc++) * scale; + + *pDst++ = (*pSrc++) * scale; + + *pDst++ = (*pSrc++) * scale; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A * scale */ + + /* Scale input and store result in destination buffer. */ + *pDst++ = (*pSrc++) * scale; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicScale group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q15.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q15.c new file mode 100644 index 0000000..039b93d --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q15.c @@ -0,0 +1,144 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_scale_q15.c + * Description: Multiplies a Q15 vector by a scalar + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicScale + @{ + */ + +/** + @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 each vector + @return none + + @par Scaling and Overflow Behavior + The input data *pSrc and scaleFract are in 1.15 format. + These are multiplied to yield a 2.30 intermediate result and this is shifted with saturation to 1.15 format. + */ + +void arm_scale_q15( + const q15_t *pSrc, + q15_t scaleFract, + int8_t shift, + q15_t *pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + int8_t kShift = 15 - shift; /* Shift to apply after scaling */ + +#if defined (ARM_MATH_LOOPUNROLL) +#if defined (ARM_MATH_DSP) + q31_t inA1, inA2; + q31_t out1, out2, out3, out4; /* Temporary output variables */ + q15_t in1, in2, in3, in4; /* Temporary input variables */ +#endif +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A * scale */ + +#if defined (ARM_MATH_DSP) + /* read 2 times 2 samples at a time from source */ + inA1 = read_q15x2_ia ((q15_t **) &pSrc); + inA2 = read_q15x2_ia ((q15_t **) &pSrc); + + /* Scale inputs and store result in temporary variables + * in single cycle by packing the outputs */ + out1 = (q31_t) ((q15_t) (inA1 >> 16) * scaleFract); + out2 = (q31_t) ((q15_t) (inA1 ) * scaleFract); + out3 = (q31_t) ((q15_t) (inA2 >> 16) * scaleFract); + out4 = (q31_t) ((q15_t) (inA2 ) * scaleFract); + + /* apply shifting */ + out1 = out1 >> kShift; + out2 = out2 >> kShift; + out3 = out3 >> kShift; + out4 = out4 >> kShift; + + /* saturate the output */ + in1 = (q15_t) (__SSAT(out1, 16)); + in2 = (q15_t) (__SSAT(out2, 16)); + in3 = (q15_t) (__SSAT(out3, 16)); + in4 = (q15_t) (__SSAT(out4, 16)); + + /* store result to destination */ + write_q15x2_ia (&pDst, __PKHBT(in2, in1, 16)); + write_q15x2_ia (&pDst, __PKHBT(in4, in3, 16)); +#else + *pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16)); + *pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16)); + *pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16)); + *pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16)); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A * scale */ + + /* Scale input and store result in destination buffer. */ + *pDst++ = (q15_t) (__SSAT(((q31_t) *pSrc++ * scaleFract) >> kShift, 16)); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicScale group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q31.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q31.c new file mode 100644 index 0000000..d762ca7 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q31.c @@ -0,0 +1,191 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_scale_q31.c + * Description: Multiplies a Q31 vector by a scalar + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicScale + @{ + */ + +/** + @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 each vector + @return none + + @par Scaling and Overflow Behavior + The input data *pSrc and scaleFract are in 1.31 format. + These are multiplied to yield a 2.62 intermediate result and this is shifted with saturation to 1.31 format. + */ + +void arm_scale_q31( + const q31_t *pSrc, + q31_t scaleFract, + int8_t shift, + q31_t *pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t in, out; /* Temporary variables */ + int8_t kShift = shift + 1; /* Shift to apply after scaling */ + int8_t sign = (kShift & 0x80); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + if (sign == 0U) + { + while (blkCnt > 0U) + { + /* C = A * scale */ + + /* Scale input and store result in destination buffer. */ + in = *pSrc++; /* read input from source */ + in = ((q63_t) in * scaleFract) >> 32; /* multiply input with scaler value */ + out = in << kShift; /* apply shifting */ + if (in != (out >> kShift)) /* saturate the result */ + out = 0x7FFFFFFF ^ (in >> 31); + *pDst++ = out; /* Store result destination */ + + in = *pSrc++; + in = ((q63_t) in * scaleFract) >> 32; + out = in << kShift; + if (in != (out >> kShift)) + out = 0x7FFFFFFF ^ (in >> 31); + *pDst++ = out; + + in = *pSrc++; + in = ((q63_t) in * scaleFract) >> 32; + out = in << kShift; + if (in != (out >> kShift)) + out = 0x7FFFFFFF ^ (in >> 31); + *pDst++ = out; + + in = *pSrc++; + in = ((q63_t) in * scaleFract) >> 32; + out = in << kShift; + if (in != (out >> kShift)) + out = 0x7FFFFFFF ^ (in >> 31); + *pDst++ = out; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + while (blkCnt > 0U) + { + /* C = A * scale */ + + /* Scale input and store result in destination buffer. */ + in = *pSrc++; /* read four inputs from source */ + in = ((q63_t) in * scaleFract) >> 32; /* multiply input with scaler value */ + out = in >> -kShift; /* apply shifting */ + *pDst++ = out; /* Store result destination */ + + in = *pSrc++; + in = ((q63_t) in * scaleFract) >> 32; + out = in >> -kShift; + *pDst++ = out; + + in = *pSrc++; + in = ((q63_t) in * scaleFract) >> 32; + out = in >> -kShift; + *pDst++ = out; + + in = *pSrc++; + in = ((q63_t) in * scaleFract) >> 32; + out = in >> -kShift; + *pDst++ = out; + + /* Decrement loop counter */ + blkCnt--; + } + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + if (sign == 0U) + { + while (blkCnt > 0U) + { + /* C = A * scale */ + + /* Scale input and store result in destination buffer. */ + in = *pSrc++; + in = ((q63_t) in * scaleFract) >> 32; + out = in << kShift; + if (in != (out >> kShift)) + out = 0x7FFFFFFF ^ (in >> 31); + *pDst++ = out; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + while (blkCnt > 0U) + { + /* C = A * scale */ + + /* Scale input and store result in destination buffer. */ + in = *pSrc++; + in = ((q63_t) in * scaleFract) >> 32; + out = in >> -kShift; + *pDst++ = out; + + /* Decrement loop counter */ + blkCnt--; + } + } + +} + +/** + @} end of BasicScale group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q7.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q7.c new file mode 100644 index 0000000..cb967d2 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_scale_q7.c @@ -0,0 +1,129 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_scale_q7.c + * Description: Multiplies a Q7 vector by a scalar + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicScale + @{ + */ + +/** + @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 each vector + @return none + + @par Scaling and Overflow Behavior + The input data *pSrc and scaleFract are in 1.7 format. + These are multiplied to yield a 2.14 intermediate result and this is shifted with saturation to 1.7 format. + */ + +void arm_scale_q7( + const q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + int8_t kShift = 7 - shift; /* Shift to apply after scaling */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q7_t in1, in2, in3, in4; /* Temporary input variables */ + q7_t out1, out2, out3, out4; /* Temporary output variables */ +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A * scale */ + +#if defined (ARM_MATH_DSP) + /* Reading 4 inputs from memory */ + in1 = *pSrc++; + in2 = *pSrc++; + in3 = *pSrc++; + in4 = *pSrc++; + + /* Scale inputs and store result in the temporary variable. */ + out1 = (q7_t) (__SSAT(((in1) * scaleFract) >> kShift, 8)); + out2 = (q7_t) (__SSAT(((in2) * scaleFract) >> kShift, 8)); + out3 = (q7_t) (__SSAT(((in3) * scaleFract) >> kShift, 8)); + out4 = (q7_t) (__SSAT(((in4) * scaleFract) >> kShift, 8)); + + /* Pack and store result in destination buffer (in single write) */ + write_q7x4_ia (&pDst, __PACKq7(out1, out2, out3, out4)); +#else + *pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8)); + *pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8)); + *pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8)); + *pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8)); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A * scale */ + + /* Scale input and store result in destination buffer. */ + *pDst++ = (q7_t) (__SSAT((((q15_t) *pSrc++ * scaleFract) >> kShift), 8)); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicScale group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q15.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q15.c new file mode 100644 index 0000000..8a15155 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q15.c @@ -0,0 +1,201 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_shift_q15.c + * Description: Shifts the elements of a Q15 vector by a specified number of bits + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicShift + @{ + */ + +/** + @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 each vector + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated. + */ + +void arm_shift_q15( + const q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q15_t in1, in2; /* Temporary input variables */ +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + /* If the shift value is positive then do right shift else left shift */ + if (sign == 0U) + { + while (blkCnt > 0U) + { + /* C = A << shiftBits */ + +#if defined (ARM_MATH_DSP) + /* read 2 samples from source */ + in1 = *pSrc++; + in2 = *pSrc++; + + /* Shift the inputs and then store the results in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pDst, __PKHBT(__SSAT((in1 << shiftBits), 16), + __SSAT((in2 << shiftBits), 16), 16)); +#else + write_q15x2_ia (&pDst, __PKHBT(__SSAT((in2 << shiftBits), 16), + __SSAT((in1 << shiftBits), 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* read 2 samples from source */ + in1 = *pSrc++; + in2 = *pSrc++; + +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pDst, __PKHBT(__SSAT((in1 << shiftBits), 16), + __SSAT((in2 << shiftBits), 16), 16)); +#else + write_q15x2_ia (&pDst, __PKHBT(__SSAT((in2 << shiftBits), 16), + __SSAT((in1 << shiftBits), 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + +#else + *pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16); + *pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16); + *pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16); + *pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + while (blkCnt > 0U) + { + /* C = A >> shiftBits */ + +#if defined (ARM_MATH_DSP) + /* read 2 samples from source */ + in1 = *pSrc++; + in2 = *pSrc++; + + /* Shift the inputs and then store the results in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pDst, __PKHBT((in1 >> -shiftBits), + (in2 >> -shiftBits), 16)); +#else + write_q15x2_ia (&pDst, __PKHBT((in2 >> -shiftBits), + (in1 >> -shiftBits), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* read 2 samples from source */ + in1 = *pSrc++; + in2 = *pSrc++; + +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pDst, __PKHBT((in1 >> -shiftBits), + (in2 >> -shiftBits), 16)); +#else + write_q15x2_ia (&pDst, __PKHBT((in2 >> -shiftBits), + (in1 >> -shiftBits), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + +#else + *pDst++ = (*pSrc++ >> -shiftBits); + *pDst++ = (*pSrc++ >> -shiftBits); + *pDst++ = (*pSrc++ >> -shiftBits); + *pDst++ = (*pSrc++ >> -shiftBits); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* If the shift value is positive then do right shift else left shift */ + if (sign == 0U) + { + while (blkCnt > 0U) + { + /* C = A << shiftBits */ + + /* Shift input and store result in destination buffer. */ + *pDst++ = __SSAT(((q31_t) *pSrc++ << shiftBits), 16); + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + while (blkCnt > 0U) + { + /* C = A >> shiftBits */ + + /* Shift input and store result in destination buffer. */ + *pDst++ = (*pSrc++ >> -shiftBits); + + /* Decrement loop counter */ + blkCnt--; + } + } + +} + +/** + @} end of BasicShift group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q31.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q31.c new file mode 100644 index 0000000..db6060a --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q31.c @@ -0,0 +1,181 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_shift_q31.c + * Description: Shifts the elements of a Q31 vector by a specified number of bits + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ +/** + @defgroup BasicShift Vector Shift + + Shifts the elements of a fixed-point vector by a specified number of bits. + There are separate functions for Q7, Q15, and Q31 data types. + The underlying algorithm used is: + +
+      pDst[n] = pSrc[n] << shift,   0 <= n < blockSize.
+  
+ + If shift is positive then the elements of the vector are shifted to the left. + If shift is negative then the elements of the vector are shifted to the right. + + The functions support in-place computation allowing the source and destination + pointers to reference the same memory buffer. + */ + +/** + @addtogroup BasicShift + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated. + */ + +void arm_shift_q31( + const q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */ + +#if defined (ARM_MATH_LOOPUNROLL) + + q31_t in, out; /* Temporary variables */ + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + /* If the shift value is positive then do right shift else left shift */ + if (sign == 0U) + { + while (blkCnt > 0U) + { + /* C = A << shiftBits */ + + /* Shift input and store result in destination buffer. */ + in = *pSrc++; + out = in << shiftBits; + if (in != (out >> shiftBits)) + out = 0x7FFFFFFF ^ (in >> 31); + *pDst++ = out; + + in = *pSrc++; + out = in << shiftBits; + if (in != (out >> shiftBits)) + out = 0x7FFFFFFF ^ (in >> 31); + *pDst++ = out; + + in = *pSrc++; + out = in << shiftBits; + if (in != (out >> shiftBits)) + out = 0x7FFFFFFF ^ (in >> 31); + *pDst++ = out; + + in = *pSrc++; + out = in << shiftBits; + if (in != (out >> shiftBits)) + out = 0x7FFFFFFF ^ (in >> 31); + *pDst++ = out; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + while (blkCnt > 0U) + { + /* C = A >> shiftBits */ + + /* Shift input and store results in destination buffer. */ + *pDst++ = (*pSrc++ >> -shiftBits); + *pDst++ = (*pSrc++ >> -shiftBits); + *pDst++ = (*pSrc++ >> -shiftBits); + *pDst++ = (*pSrc++ >> -shiftBits); + + /* Decrement loop counter */ + blkCnt--; + } + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* If the shift value is positive then do right shift else left shift */ + if (sign == 0U) + { + while (blkCnt > 0U) + { + /* C = A << shiftBits */ + + /* Shift input and store result in destination buffer. */ + *pDst++ = clip_q63_to_q31((q63_t) *pSrc++ << shiftBits); + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + while (blkCnt > 0U) + { + /* C = A >> shiftBits */ + + /* Shift input and store result in destination buffer. */ + *pDst++ = (*pSrc++ >> -shiftBits); + + /* Decrement loop counter */ + blkCnt--; + } + } + +} + +/** + @} end of BasicShift group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q7.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q7.c new file mode 100644 index 0000000..c4163fc --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_shift_q7.c @@ -0,0 +1,175 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_shift_q7.c + * Description: Processing function for the Q7 Shifting + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicShift + @{ + */ + +/** + @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 each vector + @return none + + @par onditions for optimum performance + Input and output buffers should be aligned by 32-bit + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q7 range [0x80 0x7F] are saturated. + */ + +void arm_shift_q7( + const q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q7_t in1, in2, in3, in4; /* Temporary input variables */ +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + /* If the shift value is positive then do right shift else left shift */ + if (sign == 0U) + { + while (blkCnt > 0U) + { + /* C = A << shiftBits */ + +#if defined (ARM_MATH_DSP) + /* Read 4 inputs */ + in1 = *pSrc++; + in2 = *pSrc++; + in3 = *pSrc++; + in4 = *pSrc++; + + /* Pack and store result in destination buffer (in single write) */ + write_q7x4_ia (&pDst, __PACKq7(__SSAT((in1 << shiftBits), 8), + __SSAT((in2 << shiftBits), 8), + __SSAT((in3 << shiftBits), 8), + __SSAT((in4 << shiftBits), 8) )); +#else + *pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8); + *pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8); + *pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8); + *pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + while (blkCnt > 0U) + { + /* C = A >> shiftBits */ + +#if defined (ARM_MATH_DSP) + /* Read 4 inputs */ + in1 = *pSrc++; + in2 = *pSrc++; + in3 = *pSrc++; + in4 = *pSrc++; + + /* Pack and store result in destination buffer (in single write) */ + write_q7x4_ia (&pDst, __PACKq7((in1 >> -shiftBits), + (in2 >> -shiftBits), + (in3 >> -shiftBits), + (in4 >> -shiftBits) )); +#else + *pDst++ = (*pSrc++ >> -shiftBits); + *pDst++ = (*pSrc++ >> -shiftBits); + *pDst++ = (*pSrc++ >> -shiftBits); + *pDst++ = (*pSrc++ >> -shiftBits); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* If the shift value is positive then do right shift else left shift */ + if (sign == 0U) + { + while (blkCnt > 0U) + { + /* C = A << shiftBits */ + + /* Shift input and store result in destination buffer. */ + *pDst++ = (q7_t) __SSAT(((q15_t) *pSrc++ << shiftBits), 8); + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + while (blkCnt > 0U) + { + /* C = A >> shiftBits */ + + /* Shift input and store result in destination buffer. */ + *pDst++ = (*pSrc++ >> -shiftBits); + + /* Decrement loop counter */ + blkCnt--; + } + } + +} + +/** + @} end of BasicShift group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_f32.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_f32.c new file mode 100644 index 0000000..2ebacb9 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_f32.c @@ -0,0 +1,116 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sub_f32.c + * Description: Floating-point vector subtraction + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @defgroup BasicSub Vector Subtraction + + Element-by-element subtraction of two vectors. + +
+      pDst[n] = pSrcA[n] - pSrcB[n],   0 <= n < blockSize.
+  
+ + There are separate functions for floating-point, Q7, Q15, and Q31 data types. + */ + +/** + @addtogroup BasicSub + @{ + */ + +/** + @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 + @return none + */ + +void arm_sub_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A - B */ + + /* Subtract and store result in destination buffer. */ + *pDst++ = (*pSrcA++) - (*pSrcB++); + + *pDst++ = (*pSrcA++) - (*pSrcB++); + + *pDst++ = (*pSrcA++) - (*pSrcB++); + + *pDst++ = (*pSrcA++) - (*pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A - B */ + + /* Subtract and store result in destination buffer. */ + *pDst++ = (*pSrcA++) - (*pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicSub group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q15.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q15.c new file mode 100644 index 0000000..835917e --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q15.c @@ -0,0 +1,126 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sub_q15.c + * Description: Q15 vector subtraction + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicSub + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated. + */ + +void arm_sub_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q31_t inA1, inA2; + q31_t inB1, inB2; +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A - B */ + +#if defined (ARM_MATH_DSP) + /* read 2 times 2 samples at a time from sourceA */ + inA1 = read_q15x2_ia ((q15_t **) &pSrcA); + inA2 = read_q15x2_ia ((q15_t **) &pSrcA); + /* read 2 times 2 samples at a time from sourceB */ + inB1 = read_q15x2_ia ((q15_t **) &pSrcB); + inB2 = read_q15x2_ia ((q15_t **) &pSrcB); + + /* Subtract and store 2 times 2 samples at a time */ + write_q15x2_ia (&pDst, __QSUB16(inA1, inB1)); + write_q15x2_ia (&pDst, __QSUB16(inA2, inB2)); +#else + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16); + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16); + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16); + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A - B */ + + /* Subtract and store result in destination buffer. */ +#if defined (ARM_MATH_DSP) + *pDst++ = (q15_t) __QSUB16(*pSrcA++, *pSrcB++); +#else + *pDst++ = (q15_t) __SSAT(((q31_t) *pSrcA++ - *pSrcB++), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicSub group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q31.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q31.c new file mode 100644 index 0000000..bac1927 --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q31.c @@ -0,0 +1,108 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sub_q31.c + * Description: Q31 vector subtraction + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicSub + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated. + */ + +void arm_sub_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A - B */ + + /* Subtract and store result in destination buffer. */ + *pDst++ = __QSUB(*pSrcA++, *pSrcB++); + + *pDst++ = __QSUB(*pSrcA++, *pSrcB++); + + *pDst++ = __QSUB(*pSrcA++, *pSrcB++); + + *pDst++ = __QSUB(*pSrcA++, *pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A - B */ + + /* Subtract and store result in destination buffer. */ + *pDst++ = __QSUB(*pSrcA++, *pSrcB++); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicSub group + */ diff --git a/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q7.c b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q7.c new file mode 100644 index 0000000..a55a8fd --- /dev/null +++ b/platform/cmsis/DSP_Lib/BasicMathFunctions/arm_sub_q7.c @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sub_q7.c + * Description: Q7 vector subtraction + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMath + */ + +/** + @addtogroup BasicSub + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q7 range [0x80 0x7F] will be saturated. + */ + +void arm_sub_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A - B */ + +#if defined (ARM_MATH_DSP) + /* Subtract and store result in destination buffer (4 samples at a time). */ + write_q7x4_ia (&pDst, __QSUB8(read_q7x4_ia ((q7_t **) &pSrcA), read_q7x4_ia ((q7_t **) &pSrcB))); +#else + *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8); + *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8); + *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8); + *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A - B */ + + /* Subtract and store result in destination buffer. */ + *pDst++ = (q7_t) __SSAT((q15_t) *pSrcA++ - *pSrcB++, 8); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of BasicSub group + */ diff --git a/platform/cmsis/DSP_Lib/CommonTables/CommonTables.c b/platform/cmsis/DSP_Lib/CommonTables/CommonTables.c new file mode 100644 index 0000000..acda9f8 --- /dev/null +++ b/platform/cmsis/DSP_Lib/CommonTables/CommonTables.c @@ -0,0 +1,31 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: CommonTables.c + * Description: Combination of all common table source files. + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_common_tables.c" +#include "arm_const_structs.c" + diff --git a/platform/cmsis/DSP_Lib/CommonTables/Makefile b/platform/cmsis/DSP_Lib/CommonTables/Makefile new file mode 100644 index 0000000..b951b3c --- /dev/null +++ b/platform/cmsis/DSP_Lib/CommonTables/Makefile @@ -0,0 +1,6 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out CommonTables.c,$(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/cmsis/DSP_Lib/CommonTables/arm_common_tables.c b/platform/cmsis/DSP_Lib/CommonTables/arm_common_tables.c new file mode 100644 index 0000000..ea396a9 --- /dev/null +++ b/platform/cmsis/DSP_Lib/CommonTables/arm_common_tables.c @@ -0,0 +1,22151 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_common_tables.c + * Description: common tables like fft twiddle factors, Bitreverse, reciprocal etc + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup ComplexFFT + */ + +/** + @addtogroup CFFT_CIFFT Complex FFT Tables + @{ + */ + +/** + @par + Pseudo code for Generation of Bit reversal Table is + @par +
for (l = 1; l <= N/4; l++)
+  {
+    for (i = 0; i< logN2; i++)
+    {
+      a[i] = l & (1 << i);
+    }
+    for (j = 0; j < logN2; j++)
+    {
+      if (a[j] != 0)
+      y[l] += (1 << ((logN2 - 1) - j));
+    }
+    y[l] = y[l] >> 1;
+   } 
+ @par + where N = 4096, logN2 = 12 + @par + N is the maximum FFT Size supported +*/ + +/** + @brief Table for bit reversal process +*/ +const uint16_t armBitRevTable[1024] = { + 0x400, 0x200, 0x600, 0x100, 0x500, 0x300, 0x700, 0x080, 0x480, 0x280, + 0x680, 0x180, 0x580, 0x380, 0x780, 0x040, 0x440, 0x240, 0x640, 0x140, + 0x540, 0x340, 0x740, 0x0c0, 0x4c0, 0x2c0, 0x6c0, 0x1c0, 0x5c0, 0x3c0, + 0x7c0, 0x020, 0x420, 0x220, 0x620, 0x120, 0x520, 0x320, 0x720, 0x0a0, + 0x4a0, 0x2a0, 0x6a0, 0x1a0, 0x5a0, 0x3a0, 0x7a0, 0x060, 0x460, 0x260, + 0x660, 0x160, 0x560, 0x360, 0x760, 0x0e0, 0x4e0, 0x2e0, 0x6e0, 0x1e0, + 0x5e0, 0x3e0, 0x7e0, 0x010, 0x410, 0x210, 0x610, 0x110, 0x510, 0x310, + 0x710, 0x090, 0x490, 0x290, 0x690, 0x190, 0x590, 0x390, 0x790, 0x050, + 0x450, 0x250, 0x650, 0x150, 0x550, 0x350, 0x750, 0x0d0, 0x4d0, 0x2d0, + 0x6d0, 0x1d0, 0x5d0, 0x3d0, 0x7d0, 0x030, 0x430, 0x230, 0x630, 0x130, + 0x530, 0x330, 0x730, 0x0b0, 0x4b0, 0x2b0, 0x6b0, 0x1b0, 0x5b0, 0x3b0, + 0x7b0, 0x070, 0x470, 0x270, 0x670, 0x170, 0x570, 0x370, 0x770, 0x0f0, + 0x4f0, 0x2f0, 0x6f0, 0x1f0, 0x5f0, 0x3f0, 0x7f0, 0x008, 0x408, 0x208, + 0x608, 0x108, 0x508, 0x308, 0x708, 0x088, 0x488, 0x288, 0x688, 0x188, + 0x588, 0x388, 0x788, 0x048, 0x448, 0x248, 0x648, 0x148, 0x548, 0x348, + 0x748, 0x0c8, 0x4c8, 0x2c8, 0x6c8, 0x1c8, 0x5c8, 0x3c8, 0x7c8, 0x028, + 0x428, 0x228, 0x628, 0x128, 0x528, 0x328, 0x728, 0x0a8, 0x4a8, 0x2a8, + 0x6a8, 0x1a8, 0x5a8, 0x3a8, 0x7a8, 0x068, 0x468, 0x268, 0x668, 0x168, + 0x568, 0x368, 0x768, 0x0e8, 0x4e8, 0x2e8, 0x6e8, 0x1e8, 0x5e8, 0x3e8, + 0x7e8, 0x018, 0x418, 0x218, 0x618, 0x118, 0x518, 0x318, 0x718, 0x098, + 0x498, 0x298, 0x698, 0x198, 0x598, 0x398, 0x798, 0x058, 0x458, 0x258, + 0x658, 0x158, 0x558, 0x358, 0x758, 0x0d8, 0x4d8, 0x2d8, 0x6d8, 0x1d8, + 0x5d8, 0x3d8, 0x7d8, 0x038, 0x438, 0x238, 0x638, 0x138, 0x538, 0x338, + 0x738, 0x0b8, 0x4b8, 0x2b8, 0x6b8, 0x1b8, 0x5b8, 0x3b8, 0x7b8, 0x078, + 0x478, 0x278, 0x678, 0x178, 0x578, 0x378, 0x778, 0x0f8, 0x4f8, 0x2f8, + 0x6f8, 0x1f8, 0x5f8, 0x3f8, 0x7f8, 0x004, 0x404, 0x204, 0x604, 0x104, + 0x504, 0x304, 0x704, 0x084, 0x484, 0x284, 0x684, 0x184, 0x584, 0x384, + 0x784, 0x044, 0x444, 0x244, 0x644, 0x144, 0x544, 0x344, 0x744, 0x0c4, + 0x4c4, 0x2c4, 0x6c4, 0x1c4, 0x5c4, 0x3c4, 0x7c4, 0x024, 0x424, 0x224, + 0x624, 0x124, 0x524, 0x324, 0x724, 0x0a4, 0x4a4, 0x2a4, 0x6a4, 0x1a4, + 0x5a4, 0x3a4, 0x7a4, 0x064, 0x464, 0x264, 0x664, 0x164, 0x564, 0x364, + 0x764, 0x0e4, 0x4e4, 0x2e4, 0x6e4, 0x1e4, 0x5e4, 0x3e4, 0x7e4, 0x014, + 0x414, 0x214, 0x614, 0x114, 0x514, 0x314, 0x714, 0x094, 0x494, 0x294, + 0x694, 0x194, 0x594, 0x394, 0x794, 0x054, 0x454, 0x254, 0x654, 0x154, + 0x554, 0x354, 0x754, 0x0d4, 0x4d4, 0x2d4, 0x6d4, 0x1d4, 0x5d4, 0x3d4, + 0x7d4, 0x034, 0x434, 0x234, 0x634, 0x134, 0x534, 0x334, 0x734, 0x0b4, + 0x4b4, 0x2b4, 0x6b4, 0x1b4, 0x5b4, 0x3b4, 0x7b4, 0x074, 0x474, 0x274, + 0x674, 0x174, 0x574, 0x374, 0x774, 0x0f4, 0x4f4, 0x2f4, 0x6f4, 0x1f4, + 0x5f4, 0x3f4, 0x7f4, 0x00c, 0x40c, 0x20c, 0x60c, 0x10c, 0x50c, 0x30c, + 0x70c, 0x08c, 0x48c, 0x28c, 0x68c, 0x18c, 0x58c, 0x38c, 0x78c, 0x04c, + 0x44c, 0x24c, 0x64c, 0x14c, 0x54c, 0x34c, 0x74c, 0x0cc, 0x4cc, 0x2cc, + 0x6cc, 0x1cc, 0x5cc, 0x3cc, 0x7cc, 0x02c, 0x42c, 0x22c, 0x62c, 0x12c, + 0x52c, 0x32c, 0x72c, 0x0ac, 0x4ac, 0x2ac, 0x6ac, 0x1ac, 0x5ac, 0x3ac, + 0x7ac, 0x06c, 0x46c, 0x26c, 0x66c, 0x16c, 0x56c, 0x36c, 0x76c, 0x0ec, + 0x4ec, 0x2ec, 0x6ec, 0x1ec, 0x5ec, 0x3ec, 0x7ec, 0x01c, 0x41c, 0x21c, + 0x61c, 0x11c, 0x51c, 0x31c, 0x71c, 0x09c, 0x49c, 0x29c, 0x69c, 0x19c, + 0x59c, 0x39c, 0x79c, 0x05c, 0x45c, 0x25c, 0x65c, 0x15c, 0x55c, 0x35c, + 0x75c, 0x0dc, 0x4dc, 0x2dc, 0x6dc, 0x1dc, 0x5dc, 0x3dc, 0x7dc, 0x03c, + 0x43c, 0x23c, 0x63c, 0x13c, 0x53c, 0x33c, 0x73c, 0x0bc, 0x4bc, 0x2bc, + 0x6bc, 0x1bc, 0x5bc, 0x3bc, 0x7bc, 0x07c, 0x47c, 0x27c, 0x67c, 0x17c, + 0x57c, 0x37c, 0x77c, 0x0fc, 0x4fc, 0x2fc, 0x6fc, 0x1fc, 0x5fc, 0x3fc, + 0x7fc, 0x002, 0x402, 0x202, 0x602, 0x102, 0x502, 0x302, 0x702, 0x082, + 0x482, 0x282, 0x682, 0x182, 0x582, 0x382, 0x782, 0x042, 0x442, 0x242, + 0x642, 0x142, 0x542, 0x342, 0x742, 0x0c2, 0x4c2, 0x2c2, 0x6c2, 0x1c2, + 0x5c2, 0x3c2, 0x7c2, 0x022, 0x422, 0x222, 0x622, 0x122, 0x522, 0x322, + 0x722, 0x0a2, 0x4a2, 0x2a2, 0x6a2, 0x1a2, 0x5a2, 0x3a2, 0x7a2, 0x062, + 0x462, 0x262, 0x662, 0x162, 0x562, 0x362, 0x762, 0x0e2, 0x4e2, 0x2e2, + 0x6e2, 0x1e2, 0x5e2, 0x3e2, 0x7e2, 0x012, 0x412, 0x212, 0x612, 0x112, + 0x512, 0x312, 0x712, 0x092, 0x492, 0x292, 0x692, 0x192, 0x592, 0x392, + 0x792, 0x052, 0x452, 0x252, 0x652, 0x152, 0x552, 0x352, 0x752, 0x0d2, + 0x4d2, 0x2d2, 0x6d2, 0x1d2, 0x5d2, 0x3d2, 0x7d2, 0x032, 0x432, 0x232, + 0x632, 0x132, 0x532, 0x332, 0x732, 0x0b2, 0x4b2, 0x2b2, 0x6b2, 0x1b2, + 0x5b2, 0x3b2, 0x7b2, 0x072, 0x472, 0x272, 0x672, 0x172, 0x572, 0x372, + 0x772, 0x0f2, 0x4f2, 0x2f2, 0x6f2, 0x1f2, 0x5f2, 0x3f2, 0x7f2, 0x00a, + 0x40a, 0x20a, 0x60a, 0x10a, 0x50a, 0x30a, 0x70a, 0x08a, 0x48a, 0x28a, + 0x68a, 0x18a, 0x58a, 0x38a, 0x78a, 0x04a, 0x44a, 0x24a, 0x64a, 0x14a, + 0x54a, 0x34a, 0x74a, 0x0ca, 0x4ca, 0x2ca, 0x6ca, 0x1ca, 0x5ca, 0x3ca, + 0x7ca, 0x02a, 0x42a, 0x22a, 0x62a, 0x12a, 0x52a, 0x32a, 0x72a, 0x0aa, + 0x4aa, 0x2aa, 0x6aa, 0x1aa, 0x5aa, 0x3aa, 0x7aa, 0x06a, 0x46a, 0x26a, + 0x66a, 0x16a, 0x56a, 0x36a, 0x76a, 0x0ea, 0x4ea, 0x2ea, 0x6ea, 0x1ea, + 0x5ea, 0x3ea, 0x7ea, 0x01a, 0x41a, 0x21a, 0x61a, 0x11a, 0x51a, 0x31a, + 0x71a, 0x09a, 0x49a, 0x29a, 0x69a, 0x19a, 0x59a, 0x39a, 0x79a, 0x5a, + 0x45a, 0x25a, 0x65a, 0x15a, 0x55a, 0x35a, 0x75a, 0x0da, 0x4da, 0x2da, + 0x6da, 0x1da, 0x5da, 0x3da, 0x7da, 0x03a, 0x43a, 0x23a, 0x63a, 0x13a, + 0x53a, 0x33a, 0x73a, 0x0ba, 0x4ba, 0x2ba, 0x6ba, 0x1ba, 0x5ba, 0x3ba, + 0x7ba, 0x07a, 0x47a, 0x27a, 0x67a, 0x17a, 0x57a, 0x37a, 0x77a, 0x0fa, + 0x4fa, 0x2fa, 0x6fa, 0x1fa, 0x5fa, 0x3fa, 0x7fa, 0x006, 0x406, 0x206, + 0x606, 0x106, 0x506, 0x306, 0x706, 0x086, 0x486, 0x286, 0x686, 0x186, + 0x586, 0x386, 0x786, 0x046, 0x446, 0x246, 0x646, 0x146, 0x546, 0x346, + 0x746, 0x0c6, 0x4c6, 0x2c6, 0x6c6, 0x1c6, 0x5c6, 0x3c6, 0x7c6, 0x026, + 0x426, 0x226, 0x626, 0x126, 0x526, 0x326, 0x726, 0x0a6, 0x4a6, 0x2a6, + 0x6a6, 0x1a6, 0x5a6, 0x3a6, 0x7a6, 0x066, 0x466, 0x266, 0x666, 0x166, + 0x566, 0x366, 0x766, 0x0e6, 0x4e6, 0x2e6, 0x6e6, 0x1e6, 0x5e6, 0x3e6, + 0x7e6, 0x016, 0x416, 0x216, 0x616, 0x116, 0x516, 0x316, 0x716, 0x096, + 0x496, 0x296, 0x696, 0x196, 0x596, 0x396, 0x796, 0x056, 0x456, 0x256, + 0x656, 0x156, 0x556, 0x356, 0x756, 0x0d6, 0x4d6, 0x2d6, 0x6d6, 0x1d6, + 0x5d6, 0x3d6, 0x7d6, 0x036, 0x436, 0x236, 0x636, 0x136, 0x536, 0x336, + 0x736, 0x0b6, 0x4b6, 0x2b6, 0x6b6, 0x1b6, 0x5b6, 0x3b6, 0x7b6, 0x076, + 0x476, 0x276, 0x676, 0x176, 0x576, 0x376, 0x776, 0x0f6, 0x4f6, 0x2f6, + 0x6f6, 0x1f6, 0x5f6, 0x3f6, 0x7f6, 0x00e, 0x40e, 0x20e, 0x60e, 0x10e, + 0x50e, 0x30e, 0x70e, 0x08e, 0x48e, 0x28e, 0x68e, 0x18e, 0x58e, 0x38e, + 0x78e, 0x04e, 0x44e, 0x24e, 0x64e, 0x14e, 0x54e, 0x34e, 0x74e, 0x0ce, + 0x4ce, 0x2ce, 0x6ce, 0x1ce, 0x5ce, 0x3ce, 0x7ce, 0x02e, 0x42e, 0x22e, + 0x62e, 0x12e, 0x52e, 0x32e, 0x72e, 0x0ae, 0x4ae, 0x2ae, 0x6ae, 0x1ae, + 0x5ae, 0x3ae, 0x7ae, 0x06e, 0x46e, 0x26e, 0x66e, 0x16e, 0x56e, 0x36e, + 0x76e, 0x0ee, 0x4ee, 0x2ee, 0x6ee, 0x1ee, 0x5ee, 0x3ee, 0x7ee, 0x01e, + 0x41e, 0x21e, 0x61e, 0x11e, 0x51e, 0x31e, 0x71e, 0x09e, 0x49e, 0x29e, + 0x69e, 0x19e, 0x59e, 0x39e, 0x79e, 0x05e, 0x45e, 0x25e, 0x65e, 0x15e, + 0x55e, 0x35e, 0x75e, 0x0de, 0x4de, 0x2de, 0x6de, 0x1de, 0x5de, 0x3de, + 0x7de, 0x03e, 0x43e, 0x23e, 0x63e, 0x13e, 0x53e, 0x33e, 0x73e, 0x0be, + 0x4be, 0x2be, 0x6be, 0x1be, 0x5be, 0x3be, 0x7be, 0x07e, 0x47e, 0x27e, + 0x67e, 0x17e, 0x57e, 0x37e, 0x77e, 0x0fe, 0x4fe, 0x2fe, 0x6fe, 0x1fe, + 0x5fe, 0x3fe, 0x7fe, 0x001 +}; + + +/** + @brief Floating-point Twiddle factors Table Generation +*/ + +/** + @par + Example code for Floating-point Twiddle factors Generation: + @par +
for (i = 0; i < N/; i++)
+  {
+ 	twiddleCoef[2*i]   = cos(i * 2*PI/(float)N);
+ 	twiddleCoef[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 16, PI = 3.14159265358979 + @par + Cos and Sin values are in interleaved fashion +*/ +const float32_t twiddleCoef_16[32] = { + 1.000000000f, 0.000000000f, + 0.923879533f, 0.382683432f, + 0.707106781f, 0.707106781f, + 0.382683432f, 0.923879533f, + 0.000000000f, 1.000000000f, + -0.382683432f, 0.923879533f, + -0.707106781f, 0.707106781f, + -0.923879533f, 0.382683432f, + -1.000000000f, 0.000000000f, + -0.923879533f, -0.382683432f, + -0.707106781f, -0.707106781f, + -0.382683432f, -0.923879533f, + -0.000000000f, -1.000000000f, + 0.382683432f, -0.923879533f, + 0.707106781f, -0.707106781f, + 0.923879533f, -0.382683432f +}; + +/** + @par + Example code for Floating-point Twiddle factors Generation: + @par +
for (i = 0; i< N/; i++)
+  {
+ 	twiddleCoef[2*i]   = cos(i * 2*PI/(float)N);
+ 	twiddleCoef[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 32, PI = 3.14159265358979 + @par + Cos and Sin values are in interleaved fashion +*/ +const float32_t twiddleCoef_32[64] = { + 1.000000000f, 0.000000000f, + 0.980785280f, 0.195090322f, + 0.923879533f, 0.382683432f, + 0.831469612f, 0.555570233f, + 0.707106781f, 0.707106781f, + 0.555570233f, 0.831469612f, + 0.382683432f, 0.923879533f, + 0.195090322f, 0.980785280f, + 0.000000000f, 1.000000000f, + -0.195090322f, 0.980785280f, + -0.382683432f, 0.923879533f, + -0.555570233f, 0.831469612f, + -0.707106781f, 0.707106781f, + -0.831469612f, 0.555570233f, + -0.923879533f, 0.382683432f, + -0.980785280f, 0.195090322f, + -1.000000000f, 0.000000000f, + -0.980785280f, -0.195090322f, + -0.923879533f, -0.382683432f, + -0.831469612f, -0.555570233f, + -0.707106781f, -0.707106781f, + -0.555570233f, -0.831469612f, + -0.382683432f, -0.923879533f, + -0.195090322f, -0.980785280f, + -0.000000000f, -1.000000000f, + 0.195090322f, -0.980785280f, + 0.382683432f, -0.923879533f, + 0.555570233f, -0.831469612f, + 0.707106781f, -0.707106781f, + 0.831469612f, -0.555570233f, + 0.923879533f, -0.382683432f, + 0.980785280f, -0.195090322f +}; + +/** + @par + Example code for Floating-point Twiddle factors Generation: + @par +
for(i = 0; i < N/; i++)
+  {
+ 	twiddleCoef[2*i]   = cos(i * 2*PI/(float)N);
+ 	twiddleCoef[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 64, PI = 3.14159265358979 + @par + Cos and Sin values are in interleaved fashion +*/ +const float32_t twiddleCoef_64[128] = { + 1.000000000f, 0.000000000f, + 0.995184727f, 0.098017140f, + 0.980785280f, 0.195090322f, + 0.956940336f, 0.290284677f, + 0.923879533f, 0.382683432f, + 0.881921264f, 0.471396737f, + 0.831469612f, 0.555570233f, + 0.773010453f, 0.634393284f, + 0.707106781f, 0.707106781f, + 0.634393284f, 0.773010453f, + 0.555570233f, 0.831469612f, + 0.471396737f, 0.881921264f, + 0.382683432f, 0.923879533f, + 0.290284677f, 0.956940336f, + 0.195090322f, 0.980785280f, + 0.098017140f, 0.995184727f, + 0.000000000f, 1.000000000f, + -0.098017140f, 0.995184727f, + -0.195090322f, 0.980785280f, + -0.290284677f, 0.956940336f, + -0.382683432f, 0.923879533f, + -0.471396737f, 0.881921264f, + -0.555570233f, 0.831469612f, + -0.634393284f, 0.773010453f, + -0.707106781f, 0.707106781f, + -0.773010453f, 0.634393284f, + -0.831469612f, 0.555570233f, + -0.881921264f, 0.471396737f, + -0.923879533f, 0.382683432f, + -0.956940336f, 0.290284677f, + -0.980785280f, 0.195090322f, + -0.995184727f, 0.098017140f, + -1.000000000f, 0.000000000f, + -0.995184727f, -0.098017140f, + -0.980785280f, -0.195090322f, + -0.956940336f, -0.290284677f, + -0.923879533f, -0.382683432f, + -0.881921264f, -0.471396737f, + -0.831469612f, -0.555570233f, + -0.773010453f, -0.634393284f, + -0.707106781f, -0.707106781f, + -0.634393284f, -0.773010453f, + -0.555570233f, -0.831469612f, + -0.471396737f, -0.881921264f, + -0.382683432f, -0.923879533f, + -0.290284677f, -0.956940336f, + -0.195090322f, -0.980785280f, + -0.098017140f, -0.995184727f, + -0.000000000f, -1.000000000f, + 0.098017140f, -0.995184727f, + 0.195090322f, -0.980785280f, + 0.290284677f, -0.956940336f, + 0.382683432f, -0.923879533f, + 0.471396737f, -0.881921264f, + 0.555570233f, -0.831469612f, + 0.634393284f, -0.773010453f, + 0.707106781f, -0.707106781f, + 0.773010453f, -0.634393284f, + 0.831469612f, -0.555570233f, + 0.881921264f, -0.471396737f, + 0.923879533f, -0.382683432f, + 0.956940336f, -0.290284677f, + 0.980785280f, -0.195090322f, + 0.995184727f, -0.098017140f +}; + +/** + @par + Example code for Floating-point Twiddle factors Generation: + @par +
for (i = 0; i< N/; i++)
+  {
+ 	twiddleCoef[2*i]   = cos(i * 2*PI/(float)N);
+ 	twiddleCoef[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 128, PI = 3.14159265358979 + @par + Cos and Sin values are in interleaved fashion +*/ +const float32_t twiddleCoef_128[256] = { + 1.000000000f, 0.000000000f, + 0.998795456f, 0.049067674f, + 0.995184727f, 0.098017140f, + 0.989176510f, 0.146730474f, + 0.980785280f, 0.195090322f, + 0.970031253f, 0.242980180f, + 0.956940336f, 0.290284677f, + 0.941544065f, 0.336889853f, + 0.923879533f, 0.382683432f, + 0.903989293f, 0.427555093f, + 0.881921264f, 0.471396737f, + 0.857728610f, 0.514102744f, + 0.831469612f, 0.555570233f, + 0.803207531f, 0.595699304f, + 0.773010453f, 0.634393284f, + 0.740951125f, 0.671558955f, + 0.707106781f, 0.707106781f, + 0.671558955f, 0.740951125f, + 0.634393284f, 0.773010453f, + 0.595699304f, 0.803207531f, + 0.555570233f, 0.831469612f, + 0.514102744f, 0.857728610f, + 0.471396737f, 0.881921264f, + 0.427555093f, 0.903989293f, + 0.382683432f, 0.923879533f, + 0.336889853f, 0.941544065f, + 0.290284677f, 0.956940336f, + 0.242980180f, 0.970031253f, + 0.195090322f, 0.980785280f, + 0.146730474f, 0.989176510f, + 0.098017140f, 0.995184727f, + 0.049067674f, 0.998795456f, + 0.000000000f, 1.000000000f, + -0.049067674f, 0.998795456f, + -0.098017140f, 0.995184727f, + -0.146730474f, 0.989176510f, + -0.195090322f, 0.980785280f, + -0.242980180f, 0.970031253f, + -0.290284677f, 0.956940336f, + -0.336889853f, 0.941544065f, + -0.382683432f, 0.923879533f, + -0.427555093f, 0.903989293f, + -0.471396737f, 0.881921264f, + -0.514102744f, 0.857728610f, + -0.555570233f, 0.831469612f, + -0.595699304f, 0.803207531f, + -0.634393284f, 0.773010453f, + -0.671558955f, 0.740951125f, + -0.707106781f, 0.707106781f, + -0.740951125f, 0.671558955f, + -0.773010453f, 0.634393284f, + -0.803207531f, 0.595699304f, + -0.831469612f, 0.555570233f, + -0.857728610f, 0.514102744f, + -0.881921264f, 0.471396737f, + -0.903989293f, 0.427555093f, + -0.923879533f, 0.382683432f, + -0.941544065f, 0.336889853f, + -0.956940336f, 0.290284677f, + -0.970031253f, 0.242980180f, + -0.980785280f, 0.195090322f, + -0.989176510f, 0.146730474f, + -0.995184727f, 0.098017140f, + -0.998795456f, 0.049067674f, + -1.000000000f, 0.000000000f, + -0.998795456f, -0.049067674f, + -0.995184727f, -0.098017140f, + -0.989176510f, -0.146730474f, + -0.980785280f, -0.195090322f, + -0.970031253f, -0.242980180f, + -0.956940336f, -0.290284677f, + -0.941544065f, -0.336889853f, + -0.923879533f, -0.382683432f, + -0.903989293f, -0.427555093f, + -0.881921264f, -0.471396737f, + -0.857728610f, -0.514102744f, + -0.831469612f, -0.555570233f, + -0.803207531f, -0.595699304f, + -0.773010453f, -0.634393284f, + -0.740951125f, -0.671558955f, + -0.707106781f, -0.707106781f, + -0.671558955f, -0.740951125f, + -0.634393284f, -0.773010453f, + -0.595699304f, -0.803207531f, + -0.555570233f, -0.831469612f, + -0.514102744f, -0.857728610f, + -0.471396737f, -0.881921264f, + -0.427555093f, -0.903989293f, + -0.382683432f, -0.923879533f, + -0.336889853f, -0.941544065f, + -0.290284677f, -0.956940336f, + -0.242980180f, -0.970031253f, + -0.195090322f, -0.980785280f, + -0.146730474f, -0.989176510f, + -0.098017140f, -0.995184727f, + -0.049067674f, -0.998795456f, + -0.000000000f, -1.000000000f, + 0.049067674f, -0.998795456f, + 0.098017140f, -0.995184727f, + 0.146730474f, -0.989176510f, + 0.195090322f, -0.980785280f, + 0.242980180f, -0.970031253f, + 0.290284677f, -0.956940336f, + 0.336889853f, -0.941544065f, + 0.382683432f, -0.923879533f, + 0.427555093f, -0.903989293f, + 0.471396737f, -0.881921264f, + 0.514102744f, -0.857728610f, + 0.555570233f, -0.831469612f, + 0.595699304f, -0.803207531f, + 0.634393284f, -0.773010453f, + 0.671558955f, -0.740951125f, + 0.707106781f, -0.707106781f, + 0.740951125f, -0.671558955f, + 0.773010453f, -0.634393284f, + 0.803207531f, -0.595699304f, + 0.831469612f, -0.555570233f, + 0.857728610f, -0.514102744f, + 0.881921264f, -0.471396737f, + 0.903989293f, -0.427555093f, + 0.923879533f, -0.382683432f, + 0.941544065f, -0.336889853f, + 0.956940336f, -0.290284677f, + 0.970031253f, -0.242980180f, + 0.980785280f, -0.195090322f, + 0.989176510f, -0.146730474f, + 0.995184727f, -0.098017140f, + 0.998795456f, -0.049067674f +}; + +/** + @par + Example code for Floating-point Twiddle factors Generation: + @par +
for(i = 0; i< N/; i++)
+  {
+ 	twiddleCoef[2*i]   = cos(i * 2*PI/(float)N);
+ 	twiddleCoef[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 256, PI = 3.14159265358979 + @par + Cos and Sin values are in interleaved fashion +*/ +const float32_t twiddleCoef_256[512] = { + 1.000000000f, 0.000000000f, + 0.999698819f, 0.024541229f, + 0.998795456f, 0.049067674f, + 0.997290457f, 0.073564564f, + 0.995184727f, 0.098017140f, + 0.992479535f, 0.122410675f, + 0.989176510f, 0.146730474f, + 0.985277642f, 0.170961889f, + 0.980785280f, 0.195090322f, + 0.975702130f, 0.219101240f, + 0.970031253f, 0.242980180f, + 0.963776066f, 0.266712757f, + 0.956940336f, 0.290284677f, + 0.949528181f, 0.313681740f, + 0.941544065f, 0.336889853f, + 0.932992799f, 0.359895037f, + 0.923879533f, 0.382683432f, + 0.914209756f, 0.405241314f, + 0.903989293f, 0.427555093f, + 0.893224301f, 0.449611330f, + 0.881921264f, 0.471396737f, + 0.870086991f, 0.492898192f, + 0.857728610f, 0.514102744f, + 0.844853565f, 0.534997620f, + 0.831469612f, 0.555570233f, + 0.817584813f, 0.575808191f, + 0.803207531f, 0.595699304f, + 0.788346428f, 0.615231591f, + 0.773010453f, 0.634393284f, + 0.757208847f, 0.653172843f, + 0.740951125f, 0.671558955f, + 0.724247083f, 0.689540545f, + 0.707106781f, 0.707106781f, + 0.689540545f, 0.724247083f, + 0.671558955f, 0.740951125f, + 0.653172843f, 0.757208847f, + 0.634393284f, 0.773010453f, + 0.615231591f, 0.788346428f, + 0.595699304f, 0.803207531f, + 0.575808191f, 0.817584813f, + 0.555570233f, 0.831469612f, + 0.534997620f, 0.844853565f, + 0.514102744f, 0.857728610f, + 0.492898192f, 0.870086991f, + 0.471396737f, 0.881921264f, + 0.449611330f, 0.893224301f, + 0.427555093f, 0.903989293f, + 0.405241314f, 0.914209756f, + 0.382683432f, 0.923879533f, + 0.359895037f, 0.932992799f, + 0.336889853f, 0.941544065f, + 0.313681740f, 0.949528181f, + 0.290284677f, 0.956940336f, + 0.266712757f, 0.963776066f, + 0.242980180f, 0.970031253f, + 0.219101240f, 0.975702130f, + 0.195090322f, 0.980785280f, + 0.170961889f, 0.985277642f, + 0.146730474f, 0.989176510f, + 0.122410675f, 0.992479535f, + 0.098017140f, 0.995184727f, + 0.073564564f, 0.997290457f, + 0.049067674f, 0.998795456f, + 0.024541229f, 0.999698819f, + 0.000000000f, 1.000000000f, + -0.024541229f, 0.999698819f, + -0.049067674f, 0.998795456f, + -0.073564564f, 0.997290457f, + -0.098017140f, 0.995184727f, + -0.122410675f, 0.992479535f, + -0.146730474f, 0.989176510f, + -0.170961889f, 0.985277642f, + -0.195090322f, 0.980785280f, + -0.219101240f, 0.975702130f, + -0.242980180f, 0.970031253f, + -0.266712757f, 0.963776066f, + -0.290284677f, 0.956940336f, + -0.313681740f, 0.949528181f, + -0.336889853f, 0.941544065f, + -0.359895037f, 0.932992799f, + -0.382683432f, 0.923879533f, + -0.405241314f, 0.914209756f, + -0.427555093f, 0.903989293f, + -0.449611330f, 0.893224301f, + -0.471396737f, 0.881921264f, + -0.492898192f, 0.870086991f, + -0.514102744f, 0.857728610f, + -0.534997620f, 0.844853565f, + -0.555570233f, 0.831469612f, + -0.575808191f, 0.817584813f, + -0.595699304f, 0.803207531f, + -0.615231591f, 0.788346428f, + -0.634393284f, 0.773010453f, + -0.653172843f, 0.757208847f, + -0.671558955f, 0.740951125f, + -0.689540545f, 0.724247083f, + -0.707106781f, 0.707106781f, + -0.724247083f, 0.689540545f, + -0.740951125f, 0.671558955f, + -0.757208847f, 0.653172843f, + -0.773010453f, 0.634393284f, + -0.788346428f, 0.615231591f, + -0.803207531f, 0.595699304f, + -0.817584813f, 0.575808191f, + -0.831469612f, 0.555570233f, + -0.844853565f, 0.534997620f, + -0.857728610f, 0.514102744f, + -0.870086991f, 0.492898192f, + -0.881921264f, 0.471396737f, + -0.893224301f, 0.449611330f, + -0.903989293f, 0.427555093f, + -0.914209756f, 0.405241314f, + -0.923879533f, 0.382683432f, + -0.932992799f, 0.359895037f, + -0.941544065f, 0.336889853f, + -0.949528181f, 0.313681740f, + -0.956940336f, 0.290284677f, + -0.963776066f, 0.266712757f, + -0.970031253f, 0.242980180f, + -0.975702130f, 0.219101240f, + -0.980785280f, 0.195090322f, + -0.985277642f, 0.170961889f, + -0.989176510f, 0.146730474f, + -0.992479535f, 0.122410675f, + -0.995184727f, 0.098017140f, + -0.997290457f, 0.073564564f, + -0.998795456f, 0.049067674f, + -0.999698819f, 0.024541229f, + -1.000000000f, 0.000000000f, + -0.999698819f, -0.024541229f, + -0.998795456f, -0.049067674f, + -0.997290457f, -0.073564564f, + -0.995184727f, -0.098017140f, + -0.992479535f, -0.122410675f, + -0.989176510f, -0.146730474f, + -0.985277642f, -0.170961889f, + -0.980785280f, -0.195090322f, + -0.975702130f, -0.219101240f, + -0.970031253f, -0.242980180f, + -0.963776066f, -0.266712757f, + -0.956940336f, -0.290284677f, + -0.949528181f, -0.313681740f, + -0.941544065f, -0.336889853f, + -0.932992799f, -0.359895037f, + -0.923879533f, -0.382683432f, + -0.914209756f, -0.405241314f, + -0.903989293f, -0.427555093f, + -0.893224301f, -0.449611330f, + -0.881921264f, -0.471396737f, + -0.870086991f, -0.492898192f, + -0.857728610f, -0.514102744f, + -0.844853565f, -0.534997620f, + -0.831469612f, -0.555570233f, + -0.817584813f, -0.575808191f, + -0.803207531f, -0.595699304f, + -0.788346428f, -0.615231591f, + -0.773010453f, -0.634393284f, + -0.757208847f, -0.653172843f, + -0.740951125f, -0.671558955f, + -0.724247083f, -0.689540545f, + -0.707106781f, -0.707106781f, + -0.689540545f, -0.724247083f, + -0.671558955f, -0.740951125f, + -0.653172843f, -0.757208847f, + -0.634393284f, -0.773010453f, + -0.615231591f, -0.788346428f, + -0.595699304f, -0.803207531f, + -0.575808191f, -0.817584813f, + -0.555570233f, -0.831469612f, + -0.534997620f, -0.844853565f, + -0.514102744f, -0.857728610f, + -0.492898192f, -0.870086991f, + -0.471396737f, -0.881921264f, + -0.449611330f, -0.893224301f, + -0.427555093f, -0.903989293f, + -0.405241314f, -0.914209756f, + -0.382683432f, -0.923879533f, + -0.359895037f, -0.932992799f, + -0.336889853f, -0.941544065f, + -0.313681740f, -0.949528181f, + -0.290284677f, -0.956940336f, + -0.266712757f, -0.963776066f, + -0.242980180f, -0.970031253f, + -0.219101240f, -0.975702130f, + -0.195090322f, -0.980785280f, + -0.170961889f, -0.985277642f, + -0.146730474f, -0.989176510f, + -0.122410675f, -0.992479535f, + -0.098017140f, -0.995184727f, + -0.073564564f, -0.997290457f, + -0.049067674f, -0.998795456f, + -0.024541229f, -0.999698819f, + -0.000000000f, -1.000000000f, + 0.024541229f, -0.999698819f, + 0.049067674f, -0.998795456f, + 0.073564564f, -0.997290457f, + 0.098017140f, -0.995184727f, + 0.122410675f, -0.992479535f, + 0.146730474f, -0.989176510f, + 0.170961889f, -0.985277642f, + 0.195090322f, -0.980785280f, + 0.219101240f, -0.975702130f, + 0.242980180f, -0.970031253f, + 0.266712757f, -0.963776066f, + 0.290284677f, -0.956940336f, + 0.313681740f, -0.949528181f, + 0.336889853f, -0.941544065f, + 0.359895037f, -0.932992799f, + 0.382683432f, -0.923879533f, + 0.405241314f, -0.914209756f, + 0.427555093f, -0.903989293f, + 0.449611330f, -0.893224301f, + 0.471396737f, -0.881921264f, + 0.492898192f, -0.870086991f, + 0.514102744f, -0.857728610f, + 0.534997620f, -0.844853565f, + 0.555570233f, -0.831469612f, + 0.575808191f, -0.817584813f, + 0.595699304f, -0.803207531f, + 0.615231591f, -0.788346428f, + 0.634393284f, -0.773010453f, + 0.653172843f, -0.757208847f, + 0.671558955f, -0.740951125f, + 0.689540545f, -0.724247083f, + 0.707106781f, -0.707106781f, + 0.724247083f, -0.689540545f, + 0.740951125f, -0.671558955f, + 0.757208847f, -0.653172843f, + 0.773010453f, -0.634393284f, + 0.788346428f, -0.615231591f, + 0.803207531f, -0.595699304f, + 0.817584813f, -0.575808191f, + 0.831469612f, -0.555570233f, + 0.844853565f, -0.534997620f, + 0.857728610f, -0.514102744f, + 0.870086991f, -0.492898192f, + 0.881921264f, -0.471396737f, + 0.893224301f, -0.449611330f, + 0.903989293f, -0.427555093f, + 0.914209756f, -0.405241314f, + 0.923879533f, -0.382683432f, + 0.932992799f, -0.359895037f, + 0.941544065f, -0.336889853f, + 0.949528181f, -0.313681740f, + 0.956940336f, -0.290284677f, + 0.963776066f, -0.266712757f, + 0.970031253f, -0.242980180f, + 0.975702130f, -0.219101240f, + 0.980785280f, -0.195090322f, + 0.985277642f, -0.170961889f, + 0.989176510f, -0.146730474f, + 0.992479535f, -0.122410675f, + 0.995184727f, -0.098017140f, + 0.997290457f, -0.073564564f, + 0.998795456f, -0.049067674f, + 0.999698819f, -0.024541229f +}; + +/** + @par + Example code for Floating-point Twiddle factors Generation: + @par +
for (i = 0; i< N/; i++)
+  {
+ 	twiddleCoef[2*i]   = cos(i * 2*PI/(float)N);
+ 	twiddleCoef[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 512, PI = 3.14159265358979 + @par + Cos and Sin values are in interleaved fashion +*/ +const float32_t twiddleCoef_512[1024] = { + 1.000000000f, 0.000000000f, + 0.999924702f, 0.012271538f, + 0.999698819f, 0.024541229f, + 0.999322385f, 0.036807223f, + 0.998795456f, 0.049067674f, + 0.998118113f, 0.061320736f, + 0.997290457f, 0.073564564f, + 0.996312612f, 0.085797312f, + 0.995184727f, 0.098017140f, + 0.993906970f, 0.110222207f, + 0.992479535f, 0.122410675f, + 0.990902635f, 0.134580709f, + 0.989176510f, 0.146730474f, + 0.987301418f, 0.158858143f, + 0.985277642f, 0.170961889f, + 0.983105487f, 0.183039888f, + 0.980785280f, 0.195090322f, + 0.978317371f, 0.207111376f, + 0.975702130f, 0.219101240f, + 0.972939952f, 0.231058108f, + 0.970031253f, 0.242980180f, + 0.966976471f, 0.254865660f, + 0.963776066f, 0.266712757f, + 0.960430519f, 0.278519689f, + 0.956940336f, 0.290284677f, + 0.953306040f, 0.302005949f, + 0.949528181f, 0.313681740f, + 0.945607325f, 0.325310292f, + 0.941544065f, 0.336889853f, + 0.937339012f, 0.348418680f, + 0.932992799f, 0.359895037f, + 0.928506080f, 0.371317194f, + 0.923879533f, 0.382683432f, + 0.919113852f, 0.393992040f, + 0.914209756f, 0.405241314f, + 0.909167983f, 0.416429560f, + 0.903989293f, 0.427555093f, + 0.898674466f, 0.438616239f, + 0.893224301f, 0.449611330f, + 0.887639620f, 0.460538711f, + 0.881921264f, 0.471396737f, + 0.876070094f, 0.482183772f, + 0.870086991f, 0.492898192f, + 0.863972856f, 0.503538384f, + 0.857728610f, 0.514102744f, + 0.851355193f, 0.524589683f, + 0.844853565f, 0.534997620f, + 0.838224706f, 0.545324988f, + 0.831469612f, 0.555570233f, + 0.824589303f, 0.565731811f, + 0.817584813f, 0.575808191f, + 0.810457198f, 0.585797857f, + 0.803207531f, 0.595699304f, + 0.795836905f, 0.605511041f, + 0.788346428f, 0.615231591f, + 0.780737229f, 0.624859488f, + 0.773010453f, 0.634393284f, + 0.765167266f, 0.643831543f, + 0.757208847f, 0.653172843f, + 0.749136395f, 0.662415778f, + 0.740951125f, 0.671558955f, + 0.732654272f, 0.680600998f, + 0.724247083f, 0.689540545f, + 0.715730825f, 0.698376249f, + 0.707106781f, 0.707106781f, + 0.698376249f, 0.715730825f, + 0.689540545f, 0.724247083f, + 0.680600998f, 0.732654272f, + 0.671558955f, 0.740951125f, + 0.662415778f, 0.749136395f, + 0.653172843f, 0.757208847f, + 0.643831543f, 0.765167266f, + 0.634393284f, 0.773010453f, + 0.624859488f, 0.780737229f, + 0.615231591f, 0.788346428f, + 0.605511041f, 0.795836905f, + 0.595699304f, 0.803207531f, + 0.585797857f, 0.810457198f, + 0.575808191f, 0.817584813f, + 0.565731811f, 0.824589303f, + 0.555570233f, 0.831469612f, + 0.545324988f, 0.838224706f, + 0.534997620f, 0.844853565f, + 0.524589683f, 0.851355193f, + 0.514102744f, 0.857728610f, + 0.503538384f, 0.863972856f, + 0.492898192f, 0.870086991f, + 0.482183772f, 0.876070094f, + 0.471396737f, 0.881921264f, + 0.460538711f, 0.887639620f, + 0.449611330f, 0.893224301f, + 0.438616239f, 0.898674466f, + 0.427555093f, 0.903989293f, + 0.416429560f, 0.909167983f, + 0.405241314f, 0.914209756f, + 0.393992040f, 0.919113852f, + 0.382683432f, 0.923879533f, + 0.371317194f, 0.928506080f, + 0.359895037f, 0.932992799f, + 0.348418680f, 0.937339012f, + 0.336889853f, 0.941544065f, + 0.325310292f, 0.945607325f, + 0.313681740f, 0.949528181f, + 0.302005949f, 0.953306040f, + 0.290284677f, 0.956940336f, + 0.278519689f, 0.960430519f, + 0.266712757f, 0.963776066f, + 0.254865660f, 0.966976471f, + 0.242980180f, 0.970031253f, + 0.231058108f, 0.972939952f, + 0.219101240f, 0.975702130f, + 0.207111376f, 0.978317371f, + 0.195090322f, 0.980785280f, + 0.183039888f, 0.983105487f, + 0.170961889f, 0.985277642f, + 0.158858143f, 0.987301418f, + 0.146730474f, 0.989176510f, + 0.134580709f, 0.990902635f, + 0.122410675f, 0.992479535f, + 0.110222207f, 0.993906970f, + 0.098017140f, 0.995184727f, + 0.085797312f, 0.996312612f, + 0.073564564f, 0.997290457f, + 0.061320736f, 0.998118113f, + 0.049067674f, 0.998795456f, + 0.036807223f, 0.999322385f, + 0.024541229f, 0.999698819f, + 0.012271538f, 0.999924702f, + 0.000000000f, 1.000000000f, + -0.012271538f, 0.999924702f, + -0.024541229f, 0.999698819f, + -0.036807223f, 0.999322385f, + -0.049067674f, 0.998795456f, + -0.061320736f, 0.998118113f, + -0.073564564f, 0.997290457f, + -0.085797312f, 0.996312612f, + -0.098017140f, 0.995184727f, + -0.110222207f, 0.993906970f, + -0.122410675f, 0.992479535f, + -0.134580709f, 0.990902635f, + -0.146730474f, 0.989176510f, + -0.158858143f, 0.987301418f, + -0.170961889f, 0.985277642f, + -0.183039888f, 0.983105487f, + -0.195090322f, 0.980785280f, + -0.207111376f, 0.978317371f, + -0.219101240f, 0.975702130f, + -0.231058108f, 0.972939952f, + -0.242980180f, 0.970031253f, + -0.254865660f, 0.966976471f, + -0.266712757f, 0.963776066f, + -0.278519689f, 0.960430519f, + -0.290284677f, 0.956940336f, + -0.302005949f, 0.953306040f, + -0.313681740f, 0.949528181f, + -0.325310292f, 0.945607325f, + -0.336889853f, 0.941544065f, + -0.348418680f, 0.937339012f, + -0.359895037f, 0.932992799f, + -0.371317194f, 0.928506080f, + -0.382683432f, 0.923879533f, + -0.393992040f, 0.919113852f, + -0.405241314f, 0.914209756f, + -0.416429560f, 0.909167983f, + -0.427555093f, 0.903989293f, + -0.438616239f, 0.898674466f, + -0.449611330f, 0.893224301f, + -0.460538711f, 0.887639620f, + -0.471396737f, 0.881921264f, + -0.482183772f, 0.876070094f, + -0.492898192f, 0.870086991f, + -0.503538384f, 0.863972856f, + -0.514102744f, 0.857728610f, + -0.524589683f, 0.851355193f, + -0.534997620f, 0.844853565f, + -0.545324988f, 0.838224706f, + -0.555570233f, 0.831469612f, + -0.565731811f, 0.824589303f, + -0.575808191f, 0.817584813f, + -0.585797857f, 0.810457198f, + -0.595699304f, 0.803207531f, + -0.605511041f, 0.795836905f, + -0.615231591f, 0.788346428f, + -0.624859488f, 0.780737229f, + -0.634393284f, 0.773010453f, + -0.643831543f, 0.765167266f, + -0.653172843f, 0.757208847f, + -0.662415778f, 0.749136395f, + -0.671558955f, 0.740951125f, + -0.680600998f, 0.732654272f, + -0.689540545f, 0.724247083f, + -0.698376249f, 0.715730825f, + -0.707106781f, 0.707106781f, + -0.715730825f, 0.698376249f, + -0.724247083f, 0.689540545f, + -0.732654272f, 0.680600998f, + -0.740951125f, 0.671558955f, + -0.749136395f, 0.662415778f, + -0.757208847f, 0.653172843f, + -0.765167266f, 0.643831543f, + -0.773010453f, 0.634393284f, + -0.780737229f, 0.624859488f, + -0.788346428f, 0.615231591f, + -0.795836905f, 0.605511041f, + -0.803207531f, 0.595699304f, + -0.810457198f, 0.585797857f, + -0.817584813f, 0.575808191f, + -0.824589303f, 0.565731811f, + -0.831469612f, 0.555570233f, + -0.838224706f, 0.545324988f, + -0.844853565f, 0.534997620f, + -0.851355193f, 0.524589683f, + -0.857728610f, 0.514102744f, + -0.863972856f, 0.503538384f, + -0.870086991f, 0.492898192f, + -0.876070094f, 0.482183772f, + -0.881921264f, 0.471396737f, + -0.887639620f, 0.460538711f, + -0.893224301f, 0.449611330f, + -0.898674466f, 0.438616239f, + -0.903989293f, 0.427555093f, + -0.909167983f, 0.416429560f, + -0.914209756f, 0.405241314f, + -0.919113852f, 0.393992040f, + -0.923879533f, 0.382683432f, + -0.928506080f, 0.371317194f, + -0.932992799f, 0.359895037f, + -0.937339012f, 0.348418680f, + -0.941544065f, 0.336889853f, + -0.945607325f, 0.325310292f, + -0.949528181f, 0.313681740f, + -0.953306040f, 0.302005949f, + -0.956940336f, 0.290284677f, + -0.960430519f, 0.278519689f, + -0.963776066f, 0.266712757f, + -0.966976471f, 0.254865660f, + -0.970031253f, 0.242980180f, + -0.972939952f, 0.231058108f, + -0.975702130f, 0.219101240f, + -0.978317371f, 0.207111376f, + -0.980785280f, 0.195090322f, + -0.983105487f, 0.183039888f, + -0.985277642f, 0.170961889f, + -0.987301418f, 0.158858143f, + -0.989176510f, 0.146730474f, + -0.990902635f, 0.134580709f, + -0.992479535f, 0.122410675f, + -0.993906970f, 0.110222207f, + -0.995184727f, 0.098017140f, + -0.996312612f, 0.085797312f, + -0.997290457f, 0.073564564f, + -0.998118113f, 0.061320736f, + -0.998795456f, 0.049067674f, + -0.999322385f, 0.036807223f, + -0.999698819f, 0.024541229f, + -0.999924702f, 0.012271538f, + -1.000000000f, 0.000000000f, + -0.999924702f, -0.012271538f, + -0.999698819f, -0.024541229f, + -0.999322385f, -0.036807223f, + -0.998795456f, -0.049067674f, + -0.998118113f, -0.061320736f, + -0.997290457f, -0.073564564f, + -0.996312612f, -0.085797312f, + -0.995184727f, -0.098017140f, + -0.993906970f, -0.110222207f, + -0.992479535f, -0.122410675f, + -0.990902635f, -0.134580709f, + -0.989176510f, -0.146730474f, + -0.987301418f, -0.158858143f, + -0.985277642f, -0.170961889f, + -0.983105487f, -0.183039888f, + -0.980785280f, -0.195090322f, + -0.978317371f, -0.207111376f, + -0.975702130f, -0.219101240f, + -0.972939952f, -0.231058108f, + -0.970031253f, -0.242980180f, + -0.966976471f, -0.254865660f, + -0.963776066f, -0.266712757f, + -0.960430519f, -0.278519689f, + -0.956940336f, -0.290284677f, + -0.953306040f, -0.302005949f, + -0.949528181f, -0.313681740f, + -0.945607325f, -0.325310292f, + -0.941544065f, -0.336889853f, + -0.937339012f, -0.348418680f, + -0.932992799f, -0.359895037f, + -0.928506080f, -0.371317194f, + -0.923879533f, -0.382683432f, + -0.919113852f, -0.393992040f, + -0.914209756f, -0.405241314f, + -0.909167983f, -0.416429560f, + -0.903989293f, -0.427555093f, + -0.898674466f, -0.438616239f, + -0.893224301f, -0.449611330f, + -0.887639620f, -0.460538711f, + -0.881921264f, -0.471396737f, + -0.876070094f, -0.482183772f, + -0.870086991f, -0.492898192f, + -0.863972856f, -0.503538384f, + -0.857728610f, -0.514102744f, + -0.851355193f, -0.524589683f, + -0.844853565f, -0.534997620f, + -0.838224706f, -0.545324988f, + -0.831469612f, -0.555570233f, + -0.824589303f, -0.565731811f, + -0.817584813f, -0.575808191f, + -0.810457198f, -0.585797857f, + -0.803207531f, -0.595699304f, + -0.795836905f, -0.605511041f, + -0.788346428f, -0.615231591f, + -0.780737229f, -0.624859488f, + -0.773010453f, -0.634393284f, + -0.765167266f, -0.643831543f, + -0.757208847f, -0.653172843f, + -0.749136395f, -0.662415778f, + -0.740951125f, -0.671558955f, + -0.732654272f, -0.680600998f, + -0.724247083f, -0.689540545f, + -0.715730825f, -0.698376249f, + -0.707106781f, -0.707106781f, + -0.698376249f, -0.715730825f, + -0.689540545f, -0.724247083f, + -0.680600998f, -0.732654272f, + -0.671558955f, -0.740951125f, + -0.662415778f, -0.749136395f, + -0.653172843f, -0.757208847f, + -0.643831543f, -0.765167266f, + -0.634393284f, -0.773010453f, + -0.624859488f, -0.780737229f, + -0.615231591f, -0.788346428f, + -0.605511041f, -0.795836905f, + -0.595699304f, -0.803207531f, + -0.585797857f, -0.810457198f, + -0.575808191f, -0.817584813f, + -0.565731811f, -0.824589303f, + -0.555570233f, -0.831469612f, + -0.545324988f, -0.838224706f, + -0.534997620f, -0.844853565f, + -0.524589683f, -0.851355193f, + -0.514102744f, -0.857728610f, + -0.503538384f, -0.863972856f, + -0.492898192f, -0.870086991f, + -0.482183772f, -0.876070094f, + -0.471396737f, -0.881921264f, + -0.460538711f, -0.887639620f, + -0.449611330f, -0.893224301f, + -0.438616239f, -0.898674466f, + -0.427555093f, -0.903989293f, + -0.416429560f, -0.909167983f, + -0.405241314f, -0.914209756f, + -0.393992040f, -0.919113852f, + -0.382683432f, -0.923879533f, + -0.371317194f, -0.928506080f, + -0.359895037f, -0.932992799f, + -0.348418680f, -0.937339012f, + -0.336889853f, -0.941544065f, + -0.325310292f, -0.945607325f, + -0.313681740f, -0.949528181f, + -0.302005949f, -0.953306040f, + -0.290284677f, -0.956940336f, + -0.278519689f, -0.960430519f, + -0.266712757f, -0.963776066f, + -0.254865660f, -0.966976471f, + -0.242980180f, -0.970031253f, + -0.231058108f, -0.972939952f, + -0.219101240f, -0.975702130f, + -0.207111376f, -0.978317371f, + -0.195090322f, -0.980785280f, + -0.183039888f, -0.983105487f, + -0.170961889f, -0.985277642f, + -0.158858143f, -0.987301418f, + -0.146730474f, -0.989176510f, + -0.134580709f, -0.990902635f, + -0.122410675f, -0.992479535f, + -0.110222207f, -0.993906970f, + -0.098017140f, -0.995184727f, + -0.085797312f, -0.996312612f, + -0.073564564f, -0.997290457f, + -0.061320736f, -0.998118113f, + -0.049067674f, -0.998795456f, + -0.036807223f, -0.999322385f, + -0.024541229f, -0.999698819f, + -0.012271538f, -0.999924702f, + -0.000000000f, -1.000000000f, + 0.012271538f, -0.999924702f, + 0.024541229f, -0.999698819f, + 0.036807223f, -0.999322385f, + 0.049067674f, -0.998795456f, + 0.061320736f, -0.998118113f, + 0.073564564f, -0.997290457f, + 0.085797312f, -0.996312612f, + 0.098017140f, -0.995184727f, + 0.110222207f, -0.993906970f, + 0.122410675f, -0.992479535f, + 0.134580709f, -0.990902635f, + 0.146730474f, -0.989176510f, + 0.158858143f, -0.987301418f, + 0.170961889f, -0.985277642f, + 0.183039888f, -0.983105487f, + 0.195090322f, -0.980785280f, + 0.207111376f, -0.978317371f, + 0.219101240f, -0.975702130f, + 0.231058108f, -0.972939952f, + 0.242980180f, -0.970031253f, + 0.254865660f, -0.966976471f, + 0.266712757f, -0.963776066f, + 0.278519689f, -0.960430519f, + 0.290284677f, -0.956940336f, + 0.302005949f, -0.953306040f, + 0.313681740f, -0.949528181f, + 0.325310292f, -0.945607325f, + 0.336889853f, -0.941544065f, + 0.348418680f, -0.937339012f, + 0.359895037f, -0.932992799f, + 0.371317194f, -0.928506080f, + 0.382683432f, -0.923879533f, + 0.393992040f, -0.919113852f, + 0.405241314f, -0.914209756f, + 0.416429560f, -0.909167983f, + 0.427555093f, -0.903989293f, + 0.438616239f, -0.898674466f, + 0.449611330f, -0.893224301f, + 0.460538711f, -0.887639620f, + 0.471396737f, -0.881921264f, + 0.482183772f, -0.876070094f, + 0.492898192f, -0.870086991f, + 0.503538384f, -0.863972856f, + 0.514102744f, -0.857728610f, + 0.524589683f, -0.851355193f, + 0.534997620f, -0.844853565f, + 0.545324988f, -0.838224706f, + 0.555570233f, -0.831469612f, + 0.565731811f, -0.824589303f, + 0.575808191f, -0.817584813f, + 0.585797857f, -0.810457198f, + 0.595699304f, -0.803207531f, + 0.605511041f, -0.795836905f, + 0.615231591f, -0.788346428f, + 0.624859488f, -0.780737229f, + 0.634393284f, -0.773010453f, + 0.643831543f, -0.765167266f, + 0.653172843f, -0.757208847f, + 0.662415778f, -0.749136395f, + 0.671558955f, -0.740951125f, + 0.680600998f, -0.732654272f, + 0.689540545f, -0.724247083f, + 0.698376249f, -0.715730825f, + 0.707106781f, -0.707106781f, + 0.715730825f, -0.698376249f, + 0.724247083f, -0.689540545f, + 0.732654272f, -0.680600998f, + 0.740951125f, -0.671558955f, + 0.749136395f, -0.662415778f, + 0.757208847f, -0.653172843f, + 0.765167266f, -0.643831543f, + 0.773010453f, -0.634393284f, + 0.780737229f, -0.624859488f, + 0.788346428f, -0.615231591f, + 0.795836905f, -0.605511041f, + 0.803207531f, -0.595699304f, + 0.810457198f, -0.585797857f, + 0.817584813f, -0.575808191f, + 0.824589303f, -0.565731811f, + 0.831469612f, -0.555570233f, + 0.838224706f, -0.545324988f, + 0.844853565f, -0.534997620f, + 0.851355193f, -0.524589683f, + 0.857728610f, -0.514102744f, + 0.863972856f, -0.503538384f, + 0.870086991f, -0.492898192f, + 0.876070094f, -0.482183772f, + 0.881921264f, -0.471396737f, + 0.887639620f, -0.460538711f, + 0.893224301f, -0.449611330f, + 0.898674466f, -0.438616239f, + 0.903989293f, -0.427555093f, + 0.909167983f, -0.416429560f, + 0.914209756f, -0.405241314f, + 0.919113852f, -0.393992040f, + 0.923879533f, -0.382683432f, + 0.928506080f, -0.371317194f, + 0.932992799f, -0.359895037f, + 0.937339012f, -0.348418680f, + 0.941544065f, -0.336889853f, + 0.945607325f, -0.325310292f, + 0.949528181f, -0.313681740f, + 0.953306040f, -0.302005949f, + 0.956940336f, -0.290284677f, + 0.960430519f, -0.278519689f, + 0.963776066f, -0.266712757f, + 0.966976471f, -0.254865660f, + 0.970031253f, -0.242980180f, + 0.972939952f, -0.231058108f, + 0.975702130f, -0.219101240f, + 0.978317371f, -0.207111376f, + 0.980785280f, -0.195090322f, + 0.983105487f, -0.183039888f, + 0.985277642f, -0.170961889f, + 0.987301418f, -0.158858143f, + 0.989176510f, -0.146730474f, + 0.990902635f, -0.134580709f, + 0.992479535f, -0.122410675f, + 0.993906970f, -0.110222207f, + 0.995184727f, -0.098017140f, + 0.996312612f, -0.085797312f, + 0.997290457f, -0.073564564f, + 0.998118113f, -0.061320736f, + 0.998795456f, -0.049067674f, + 0.999322385f, -0.036807223f, + 0.999698819f, -0.024541229f, + 0.999924702f, -0.012271538f +}; +/** + @par + Example code for Floating-point Twiddle factors Generation: + @par +
for (i = 0; i< N/; i++)
+  {
+ 	twiddleCoef[2*i]   = cos(i * 2*PI/(float)N);
+ 	twiddleCoef[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 1024, PI = 3.14159265358979 + @par + Cos and Sin values are in interleaved fashion +*/ +const float32_t twiddleCoef_1024[2048] = { + 1.000000000f, 0.000000000f, + 0.999981175f, 0.006135885f, + 0.999924702f, 0.012271538f, + 0.999830582f, 0.018406730f, + 0.999698819f, 0.024541229f, + 0.999529418f, 0.030674803f, + 0.999322385f, 0.036807223f, + 0.999077728f, 0.042938257f, + 0.998795456f, 0.049067674f, + 0.998475581f, 0.055195244f, + 0.998118113f, 0.061320736f, + 0.997723067f, 0.067443920f, + 0.997290457f, 0.073564564f, + 0.996820299f, 0.079682438f, + 0.996312612f, 0.085797312f, + 0.995767414f, 0.091908956f, + 0.995184727f, 0.098017140f, + 0.994564571f, 0.104121634f, + 0.993906970f, 0.110222207f, + 0.993211949f, 0.116318631f, + 0.992479535f, 0.122410675f, + 0.991709754f, 0.128498111f, + 0.990902635f, 0.134580709f, + 0.990058210f, 0.140658239f, + 0.989176510f, 0.146730474f, + 0.988257568f, 0.152797185f, + 0.987301418f, 0.158858143f, + 0.986308097f, 0.164913120f, + 0.985277642f, 0.170961889f, + 0.984210092f, 0.177004220f, + 0.983105487f, 0.183039888f, + 0.981963869f, 0.189068664f, + 0.980785280f, 0.195090322f, + 0.979569766f, 0.201104635f, + 0.978317371f, 0.207111376f, + 0.977028143f, 0.213110320f, + 0.975702130f, 0.219101240f, + 0.974339383f, 0.225083911f, + 0.972939952f, 0.231058108f, + 0.971503891f, 0.237023606f, + 0.970031253f, 0.242980180f, + 0.968522094f, 0.248927606f, + 0.966976471f, 0.254865660f, + 0.965394442f, 0.260794118f, + 0.963776066f, 0.266712757f, + 0.962121404f, 0.272621355f, + 0.960430519f, 0.278519689f, + 0.958703475f, 0.284407537f, + 0.956940336f, 0.290284677f, + 0.955141168f, 0.296150888f, + 0.953306040f, 0.302005949f, + 0.951435021f, 0.307849640f, + 0.949528181f, 0.313681740f, + 0.947585591f, 0.319502031f, + 0.945607325f, 0.325310292f, + 0.943593458f, 0.331106306f, + 0.941544065f, 0.336889853f, + 0.939459224f, 0.342660717f, + 0.937339012f, 0.348418680f, + 0.935183510f, 0.354163525f, + 0.932992799f, 0.359895037f, + 0.930766961f, 0.365612998f, + 0.928506080f, 0.371317194f, + 0.926210242f, 0.377007410f, + 0.923879533f, 0.382683432f, + 0.921514039f, 0.388345047f, + 0.919113852f, 0.393992040f, + 0.916679060f, 0.399624200f, + 0.914209756f, 0.405241314f, + 0.911706032f, 0.410843171f, + 0.909167983f, 0.416429560f, + 0.906595705f, 0.422000271f, + 0.903989293f, 0.427555093f, + 0.901348847f, 0.433093819f, + 0.898674466f, 0.438616239f, + 0.895966250f, 0.444122145f, + 0.893224301f, 0.449611330f, + 0.890448723f, 0.455083587f, + 0.887639620f, 0.460538711f, + 0.884797098f, 0.465976496f, + 0.881921264f, 0.471396737f, + 0.879012226f, 0.476799230f, + 0.876070094f, 0.482183772f, + 0.873094978f, 0.487550160f, + 0.870086991f, 0.492898192f, + 0.867046246f, 0.498227667f, + 0.863972856f, 0.503538384f, + 0.860866939f, 0.508830143f, + 0.857728610f, 0.514102744f, + 0.854557988f, 0.519355990f, + 0.851355193f, 0.524589683f, + 0.848120345f, 0.529803625f, + 0.844853565f, 0.534997620f, + 0.841554977f, 0.540171473f, + 0.838224706f, 0.545324988f, + 0.834862875f, 0.550457973f, + 0.831469612f, 0.555570233f, + 0.828045045f, 0.560661576f, + 0.824589303f, 0.565731811f, + 0.821102515f, 0.570780746f, + 0.817584813f, 0.575808191f, + 0.814036330f, 0.580813958f, + 0.810457198f, 0.585797857f, + 0.806847554f, 0.590759702f, + 0.803207531f, 0.595699304f, + 0.799537269f, 0.600616479f, + 0.795836905f, 0.605511041f, + 0.792106577f, 0.610382806f, + 0.788346428f, 0.615231591f, + 0.784556597f, 0.620057212f, + 0.780737229f, 0.624859488f, + 0.776888466f, 0.629638239f, + 0.773010453f, 0.634393284f, + 0.769103338f, 0.639124445f, + 0.765167266f, 0.643831543f, + 0.761202385f, 0.648514401f, + 0.757208847f, 0.653172843f, + 0.753186799f, 0.657806693f, + 0.749136395f, 0.662415778f, + 0.745057785f, 0.666999922f, + 0.740951125f, 0.671558955f, + 0.736816569f, 0.676092704f, + 0.732654272f, 0.680600998f, + 0.728464390f, 0.685083668f, + 0.724247083f, 0.689540545f, + 0.720002508f, 0.693971461f, + 0.715730825f, 0.698376249f, + 0.711432196f, 0.702754744f, + 0.707106781f, 0.707106781f, + 0.702754744f, 0.711432196f, + 0.698376249f, 0.715730825f, + 0.693971461f, 0.720002508f, + 0.689540545f, 0.724247083f, + 0.685083668f, 0.728464390f, + 0.680600998f, 0.732654272f, + 0.676092704f, 0.736816569f, + 0.671558955f, 0.740951125f, + 0.666999922f, 0.745057785f, + 0.662415778f, 0.749136395f, + 0.657806693f, 0.753186799f, + 0.653172843f, 0.757208847f, + 0.648514401f, 0.761202385f, + 0.643831543f, 0.765167266f, + 0.639124445f, 0.769103338f, + 0.634393284f, 0.773010453f, + 0.629638239f, 0.776888466f, + 0.624859488f, 0.780737229f, + 0.620057212f, 0.784556597f, + 0.615231591f, 0.788346428f, + 0.610382806f, 0.792106577f, + 0.605511041f, 0.795836905f, + 0.600616479f, 0.799537269f, + 0.595699304f, 0.803207531f, + 0.590759702f, 0.806847554f, + 0.585797857f, 0.810457198f, + 0.580813958f, 0.814036330f, + 0.575808191f, 0.817584813f, + 0.570780746f, 0.821102515f, + 0.565731811f, 0.824589303f, + 0.560661576f, 0.828045045f, + 0.555570233f, 0.831469612f, + 0.550457973f, 0.834862875f, + 0.545324988f, 0.838224706f, + 0.540171473f, 0.841554977f, + 0.534997620f, 0.844853565f, + 0.529803625f, 0.848120345f, + 0.524589683f, 0.851355193f, + 0.519355990f, 0.854557988f, + 0.514102744f, 0.857728610f, + 0.508830143f, 0.860866939f, + 0.503538384f, 0.863972856f, + 0.498227667f, 0.867046246f, + 0.492898192f, 0.870086991f, + 0.487550160f, 0.873094978f, + 0.482183772f, 0.876070094f, + 0.476799230f, 0.879012226f, + 0.471396737f, 0.881921264f, + 0.465976496f, 0.884797098f, + 0.460538711f, 0.887639620f, + 0.455083587f, 0.890448723f, + 0.449611330f, 0.893224301f, + 0.444122145f, 0.895966250f, + 0.438616239f, 0.898674466f, + 0.433093819f, 0.901348847f, + 0.427555093f, 0.903989293f, + 0.422000271f, 0.906595705f, + 0.416429560f, 0.909167983f, + 0.410843171f, 0.911706032f, + 0.405241314f, 0.914209756f, + 0.399624200f, 0.916679060f, + 0.393992040f, 0.919113852f, + 0.388345047f, 0.921514039f, + 0.382683432f, 0.923879533f, + 0.377007410f, 0.926210242f, + 0.371317194f, 0.928506080f, + 0.365612998f, 0.930766961f, + 0.359895037f, 0.932992799f, + 0.354163525f, 0.935183510f, + 0.348418680f, 0.937339012f, + 0.342660717f, 0.939459224f, + 0.336889853f, 0.941544065f, + 0.331106306f, 0.943593458f, + 0.325310292f, 0.945607325f, + 0.319502031f, 0.947585591f, + 0.313681740f, 0.949528181f, + 0.307849640f, 0.951435021f, + 0.302005949f, 0.953306040f, + 0.296150888f, 0.955141168f, + 0.290284677f, 0.956940336f, + 0.284407537f, 0.958703475f, + 0.278519689f, 0.960430519f, + 0.272621355f, 0.962121404f, + 0.266712757f, 0.963776066f, + 0.260794118f, 0.965394442f, + 0.254865660f, 0.966976471f, + 0.248927606f, 0.968522094f, + 0.242980180f, 0.970031253f, + 0.237023606f, 0.971503891f, + 0.231058108f, 0.972939952f, + 0.225083911f, 0.974339383f, + 0.219101240f, 0.975702130f, + 0.213110320f, 0.977028143f, + 0.207111376f, 0.978317371f, + 0.201104635f, 0.979569766f, + 0.195090322f, 0.980785280f, + 0.189068664f, 0.981963869f, + 0.183039888f, 0.983105487f, + 0.177004220f, 0.984210092f, + 0.170961889f, 0.985277642f, + 0.164913120f, 0.986308097f, + 0.158858143f, 0.987301418f, + 0.152797185f, 0.988257568f, + 0.146730474f, 0.989176510f, + 0.140658239f, 0.990058210f, + 0.134580709f, 0.990902635f, + 0.128498111f, 0.991709754f, + 0.122410675f, 0.992479535f, + 0.116318631f, 0.993211949f, + 0.110222207f, 0.993906970f, + 0.104121634f, 0.994564571f, + 0.098017140f, 0.995184727f, + 0.091908956f, 0.995767414f, + 0.085797312f, 0.996312612f, + 0.079682438f, 0.996820299f, + 0.073564564f, 0.997290457f, + 0.067443920f, 0.997723067f, + 0.061320736f, 0.998118113f, + 0.055195244f, 0.998475581f, + 0.049067674f, 0.998795456f, + 0.042938257f, 0.999077728f, + 0.036807223f, 0.999322385f, + 0.030674803f, 0.999529418f, + 0.024541229f, 0.999698819f, + 0.018406730f, 0.999830582f, + 0.012271538f, 0.999924702f, + 0.006135885f, 0.999981175f, + 0.000000000f, 1.000000000f, + -0.006135885f, 0.999981175f, + -0.012271538f, 0.999924702f, + -0.018406730f, 0.999830582f, + -0.024541229f, 0.999698819f, + -0.030674803f, 0.999529418f, + -0.036807223f, 0.999322385f, + -0.042938257f, 0.999077728f, + -0.049067674f, 0.998795456f, + -0.055195244f, 0.998475581f, + -0.061320736f, 0.998118113f, + -0.067443920f, 0.997723067f, + -0.073564564f, 0.997290457f, + -0.079682438f, 0.996820299f, + -0.085797312f, 0.996312612f, + -0.091908956f, 0.995767414f, + -0.098017140f, 0.995184727f, + -0.104121634f, 0.994564571f, + -0.110222207f, 0.993906970f, + -0.116318631f, 0.993211949f, + -0.122410675f, 0.992479535f, + -0.128498111f, 0.991709754f, + -0.134580709f, 0.990902635f, + -0.140658239f, 0.990058210f, + -0.146730474f, 0.989176510f, + -0.152797185f, 0.988257568f, + -0.158858143f, 0.987301418f, + -0.164913120f, 0.986308097f, + -0.170961889f, 0.985277642f, + -0.177004220f, 0.984210092f, + -0.183039888f, 0.983105487f, + -0.189068664f, 0.981963869f, + -0.195090322f, 0.980785280f, + -0.201104635f, 0.979569766f, + -0.207111376f, 0.978317371f, + -0.213110320f, 0.977028143f, + -0.219101240f, 0.975702130f, + -0.225083911f, 0.974339383f, + -0.231058108f, 0.972939952f, + -0.237023606f, 0.971503891f, + -0.242980180f, 0.970031253f, + -0.248927606f, 0.968522094f, + -0.254865660f, 0.966976471f, + -0.260794118f, 0.965394442f, + -0.266712757f, 0.963776066f, + -0.272621355f, 0.962121404f, + -0.278519689f, 0.960430519f, + -0.284407537f, 0.958703475f, + -0.290284677f, 0.956940336f, + -0.296150888f, 0.955141168f, + -0.302005949f, 0.953306040f, + -0.307849640f, 0.951435021f, + -0.313681740f, 0.949528181f, + -0.319502031f, 0.947585591f, + -0.325310292f, 0.945607325f, + -0.331106306f, 0.943593458f, + -0.336889853f, 0.941544065f, + -0.342660717f, 0.939459224f, + -0.348418680f, 0.937339012f, + -0.354163525f, 0.935183510f, + -0.359895037f, 0.932992799f, + -0.365612998f, 0.930766961f, + -0.371317194f, 0.928506080f, + -0.377007410f, 0.926210242f, + -0.382683432f, 0.923879533f, + -0.388345047f, 0.921514039f, + -0.393992040f, 0.919113852f, + -0.399624200f, 0.916679060f, + -0.405241314f, 0.914209756f, + -0.410843171f, 0.911706032f, + -0.416429560f, 0.909167983f, + -0.422000271f, 0.906595705f, + -0.427555093f, 0.903989293f, + -0.433093819f, 0.901348847f, + -0.438616239f, 0.898674466f, + -0.444122145f, 0.895966250f, + -0.449611330f, 0.893224301f, + -0.455083587f, 0.890448723f, + -0.460538711f, 0.887639620f, + -0.465976496f, 0.884797098f, + -0.471396737f, 0.881921264f, + -0.476799230f, 0.879012226f, + -0.482183772f, 0.876070094f, + -0.487550160f, 0.873094978f, + -0.492898192f, 0.870086991f, + -0.498227667f, 0.867046246f, + -0.503538384f, 0.863972856f, + -0.508830143f, 0.860866939f, + -0.514102744f, 0.857728610f, + -0.519355990f, 0.854557988f, + -0.524589683f, 0.851355193f, + -0.529803625f, 0.848120345f, + -0.534997620f, 0.844853565f, + -0.540171473f, 0.841554977f, + -0.545324988f, 0.838224706f, + -0.550457973f, 0.834862875f, + -0.555570233f, 0.831469612f, + -0.560661576f, 0.828045045f, + -0.565731811f, 0.824589303f, + -0.570780746f, 0.821102515f, + -0.575808191f, 0.817584813f, + -0.580813958f, 0.814036330f, + -0.585797857f, 0.810457198f, + -0.590759702f, 0.806847554f, + -0.595699304f, 0.803207531f, + -0.600616479f, 0.799537269f, + -0.605511041f, 0.795836905f, + -0.610382806f, 0.792106577f, + -0.615231591f, 0.788346428f, + -0.620057212f, 0.784556597f, + -0.624859488f, 0.780737229f, + -0.629638239f, 0.776888466f, + -0.634393284f, 0.773010453f, + -0.639124445f, 0.769103338f, + -0.643831543f, 0.765167266f, + -0.648514401f, 0.761202385f, + -0.653172843f, 0.757208847f, + -0.657806693f, 0.753186799f, + -0.662415778f, 0.749136395f, + -0.666999922f, 0.745057785f, + -0.671558955f, 0.740951125f, + -0.676092704f, 0.736816569f, + -0.680600998f, 0.732654272f, + -0.685083668f, 0.728464390f, + -0.689540545f, 0.724247083f, + -0.693971461f, 0.720002508f, + -0.698376249f, 0.715730825f, + -0.702754744f, 0.711432196f, + -0.707106781f, 0.707106781f, + -0.711432196f, 0.702754744f, + -0.715730825f, 0.698376249f, + -0.720002508f, 0.693971461f, + -0.724247083f, 0.689540545f, + -0.728464390f, 0.685083668f, + -0.732654272f, 0.680600998f, + -0.736816569f, 0.676092704f, + -0.740951125f, 0.671558955f, + -0.745057785f, 0.666999922f, + -0.749136395f, 0.662415778f, + -0.753186799f, 0.657806693f, + -0.757208847f, 0.653172843f, + -0.761202385f, 0.648514401f, + -0.765167266f, 0.643831543f, + -0.769103338f, 0.639124445f, + -0.773010453f, 0.634393284f, + -0.776888466f, 0.629638239f, + -0.780737229f, 0.624859488f, + -0.784556597f, 0.620057212f, + -0.788346428f, 0.615231591f, + -0.792106577f, 0.610382806f, + -0.795836905f, 0.605511041f, + -0.799537269f, 0.600616479f, + -0.803207531f, 0.595699304f, + -0.806847554f, 0.590759702f, + -0.810457198f, 0.585797857f, + -0.814036330f, 0.580813958f, + -0.817584813f, 0.575808191f, + -0.821102515f, 0.570780746f, + -0.824589303f, 0.565731811f, + -0.828045045f, 0.560661576f, + -0.831469612f, 0.555570233f, + -0.834862875f, 0.550457973f, + -0.838224706f, 0.545324988f, + -0.841554977f, 0.540171473f, + -0.844853565f, 0.534997620f, + -0.848120345f, 0.529803625f, + -0.851355193f, 0.524589683f, + -0.854557988f, 0.519355990f, + -0.857728610f, 0.514102744f, + -0.860866939f, 0.508830143f, + -0.863972856f, 0.503538384f, + -0.867046246f, 0.498227667f, + -0.870086991f, 0.492898192f, + -0.873094978f, 0.487550160f, + -0.876070094f, 0.482183772f, + -0.879012226f, 0.476799230f, + -0.881921264f, 0.471396737f, + -0.884797098f, 0.465976496f, + -0.887639620f, 0.460538711f, + -0.890448723f, 0.455083587f, + -0.893224301f, 0.449611330f, + -0.895966250f, 0.444122145f, + -0.898674466f, 0.438616239f, + -0.901348847f, 0.433093819f, + -0.903989293f, 0.427555093f, + -0.906595705f, 0.422000271f, + -0.909167983f, 0.416429560f, + -0.911706032f, 0.410843171f, + -0.914209756f, 0.405241314f, + -0.916679060f, 0.399624200f, + -0.919113852f, 0.393992040f, + -0.921514039f, 0.388345047f, + -0.923879533f, 0.382683432f, + -0.926210242f, 0.377007410f, + -0.928506080f, 0.371317194f, + -0.930766961f, 0.365612998f, + -0.932992799f, 0.359895037f, + -0.935183510f, 0.354163525f, + -0.937339012f, 0.348418680f, + -0.939459224f, 0.342660717f, + -0.941544065f, 0.336889853f, + -0.943593458f, 0.331106306f, + -0.945607325f, 0.325310292f, + -0.947585591f, 0.319502031f, + -0.949528181f, 0.313681740f, + -0.951435021f, 0.307849640f, + -0.953306040f, 0.302005949f, + -0.955141168f, 0.296150888f, + -0.956940336f, 0.290284677f, + -0.958703475f, 0.284407537f, + -0.960430519f, 0.278519689f, + -0.962121404f, 0.272621355f, + -0.963776066f, 0.266712757f, + -0.965394442f, 0.260794118f, + -0.966976471f, 0.254865660f, + -0.968522094f, 0.248927606f, + -0.970031253f, 0.242980180f, + -0.971503891f, 0.237023606f, + -0.972939952f, 0.231058108f, + -0.974339383f, 0.225083911f, + -0.975702130f, 0.219101240f, + -0.977028143f, 0.213110320f, + -0.978317371f, 0.207111376f, + -0.979569766f, 0.201104635f, + -0.980785280f, 0.195090322f, + -0.981963869f, 0.189068664f, + -0.983105487f, 0.183039888f, + -0.984210092f, 0.177004220f, + -0.985277642f, 0.170961889f, + -0.986308097f, 0.164913120f, + -0.987301418f, 0.158858143f, + -0.988257568f, 0.152797185f, + -0.989176510f, 0.146730474f, + -0.990058210f, 0.140658239f, + -0.990902635f, 0.134580709f, + -0.991709754f, 0.128498111f, + -0.992479535f, 0.122410675f, + -0.993211949f, 0.116318631f, + -0.993906970f, 0.110222207f, + -0.994564571f, 0.104121634f, + -0.995184727f, 0.098017140f, + -0.995767414f, 0.091908956f, + -0.996312612f, 0.085797312f, + -0.996820299f, 0.079682438f, + -0.997290457f, 0.073564564f, + -0.997723067f, 0.067443920f, + -0.998118113f, 0.061320736f, + -0.998475581f, 0.055195244f, + -0.998795456f, 0.049067674f, + -0.999077728f, 0.042938257f, + -0.999322385f, 0.036807223f, + -0.999529418f, 0.030674803f, + -0.999698819f, 0.024541229f, + -0.999830582f, 0.018406730f, + -0.999924702f, 0.012271538f, + -0.999981175f, 0.006135885f, + -1.000000000f, 0.000000000f, + -0.999981175f, -0.006135885f, + -0.999924702f, -0.012271538f, + -0.999830582f, -0.018406730f, + -0.999698819f, -0.024541229f, + -0.999529418f, -0.030674803f, + -0.999322385f, -0.036807223f, + -0.999077728f, -0.042938257f, + -0.998795456f, -0.049067674f, + -0.998475581f, -0.055195244f, + -0.998118113f, -0.061320736f, + -0.997723067f, -0.067443920f, + -0.997290457f, -0.073564564f, + -0.996820299f, -0.079682438f, + -0.996312612f, -0.085797312f, + -0.995767414f, -0.091908956f, + -0.995184727f, -0.098017140f, + -0.994564571f, -0.104121634f, + -0.993906970f, -0.110222207f, + -0.993211949f, -0.116318631f, + -0.992479535f, -0.122410675f, + -0.991709754f, -0.128498111f, + -0.990902635f, -0.134580709f, + -0.990058210f, -0.140658239f, + -0.989176510f, -0.146730474f, + -0.988257568f, -0.152797185f, + -0.987301418f, -0.158858143f, + -0.986308097f, -0.164913120f, + -0.985277642f, -0.170961889f, + -0.984210092f, -0.177004220f, + -0.983105487f, -0.183039888f, + -0.981963869f, -0.189068664f, + -0.980785280f, -0.195090322f, + -0.979569766f, -0.201104635f, + -0.978317371f, -0.207111376f, + -0.977028143f, -0.213110320f, + -0.975702130f, -0.219101240f, + -0.974339383f, -0.225083911f, + -0.972939952f, -0.231058108f, + -0.971503891f, -0.237023606f, + -0.970031253f, -0.242980180f, + -0.968522094f, -0.248927606f, + -0.966976471f, -0.254865660f, + -0.965394442f, -0.260794118f, + -0.963776066f, -0.266712757f, + -0.962121404f, -0.272621355f, + -0.960430519f, -0.278519689f, + -0.958703475f, -0.284407537f, + -0.956940336f, -0.290284677f, + -0.955141168f, -0.296150888f, + -0.953306040f, -0.302005949f, + -0.951435021f, -0.307849640f, + -0.949528181f, -0.313681740f, + -0.947585591f, -0.319502031f, + -0.945607325f, -0.325310292f, + -0.943593458f, -0.331106306f, + -0.941544065f, -0.336889853f, + -0.939459224f, -0.342660717f, + -0.937339012f, -0.348418680f, + -0.935183510f, -0.354163525f, + -0.932992799f, -0.359895037f, + -0.930766961f, -0.365612998f, + -0.928506080f, -0.371317194f, + -0.926210242f, -0.377007410f, + -0.923879533f, -0.382683432f, + -0.921514039f, -0.388345047f, + -0.919113852f, -0.393992040f, + -0.916679060f, -0.399624200f, + -0.914209756f, -0.405241314f, + -0.911706032f, -0.410843171f, + -0.909167983f, -0.416429560f, + -0.906595705f, -0.422000271f, + -0.903989293f, -0.427555093f, + -0.901348847f, -0.433093819f, + -0.898674466f, -0.438616239f, + -0.895966250f, -0.444122145f, + -0.893224301f, -0.449611330f, + -0.890448723f, -0.455083587f, + -0.887639620f, -0.460538711f, + -0.884797098f, -0.465976496f, + -0.881921264f, -0.471396737f, + -0.879012226f, -0.476799230f, + -0.876070094f, -0.482183772f, + -0.873094978f, -0.487550160f, + -0.870086991f, -0.492898192f, + -0.867046246f, -0.498227667f, + -0.863972856f, -0.503538384f, + -0.860866939f, -0.508830143f, + -0.857728610f, -0.514102744f, + -0.854557988f, -0.519355990f, + -0.851355193f, -0.524589683f, + -0.848120345f, -0.529803625f, + -0.844853565f, -0.534997620f, + -0.841554977f, -0.540171473f, + -0.838224706f, -0.545324988f, + -0.834862875f, -0.550457973f, + -0.831469612f, -0.555570233f, + -0.828045045f, -0.560661576f, + -0.824589303f, -0.565731811f, + -0.821102515f, -0.570780746f, + -0.817584813f, -0.575808191f, + -0.814036330f, -0.580813958f, + -0.810457198f, -0.585797857f, + -0.806847554f, -0.590759702f, + -0.803207531f, -0.595699304f, + -0.799537269f, -0.600616479f, + -0.795836905f, -0.605511041f, + -0.792106577f, -0.610382806f, + -0.788346428f, -0.615231591f, + -0.784556597f, -0.620057212f, + -0.780737229f, -0.624859488f, + -0.776888466f, -0.629638239f, + -0.773010453f, -0.634393284f, + -0.769103338f, -0.639124445f, + -0.765167266f, -0.643831543f, + -0.761202385f, -0.648514401f, + -0.757208847f, -0.653172843f, + -0.753186799f, -0.657806693f, + -0.749136395f, -0.662415778f, + -0.745057785f, -0.666999922f, + -0.740951125f, -0.671558955f, + -0.736816569f, -0.676092704f, + -0.732654272f, -0.680600998f, + -0.728464390f, -0.685083668f, + -0.724247083f, -0.689540545f, + -0.720002508f, -0.693971461f, + -0.715730825f, -0.698376249f, + -0.711432196f, -0.702754744f, + -0.707106781f, -0.707106781f, + -0.702754744f, -0.711432196f, + -0.698376249f, -0.715730825f, + -0.693971461f, -0.720002508f, + -0.689540545f, -0.724247083f, + -0.685083668f, -0.728464390f, + -0.680600998f, -0.732654272f, + -0.676092704f, -0.736816569f, + -0.671558955f, -0.740951125f, + -0.666999922f, -0.745057785f, + -0.662415778f, -0.749136395f, + -0.657806693f, -0.753186799f, + -0.653172843f, -0.757208847f, + -0.648514401f, -0.761202385f, + -0.643831543f, -0.765167266f, + -0.639124445f, -0.769103338f, + -0.634393284f, -0.773010453f, + -0.629638239f, -0.776888466f, + -0.624859488f, -0.780737229f, + -0.620057212f, -0.784556597f, + -0.615231591f, -0.788346428f, + -0.610382806f, -0.792106577f, + -0.605511041f, -0.795836905f, + -0.600616479f, -0.799537269f, + -0.595699304f, -0.803207531f, + -0.590759702f, -0.806847554f, + -0.585797857f, -0.810457198f, + -0.580813958f, -0.814036330f, + -0.575808191f, -0.817584813f, + -0.570780746f, -0.821102515f, + -0.565731811f, -0.824589303f, + -0.560661576f, -0.828045045f, + -0.555570233f, -0.831469612f, + -0.550457973f, -0.834862875f, + -0.545324988f, -0.838224706f, + -0.540171473f, -0.841554977f, + -0.534997620f, -0.844853565f, + -0.529803625f, -0.848120345f, + -0.524589683f, -0.851355193f, + -0.519355990f, -0.854557988f, + -0.514102744f, -0.857728610f, + -0.508830143f, -0.860866939f, + -0.503538384f, -0.863972856f, + -0.498227667f, -0.867046246f, + -0.492898192f, -0.870086991f, + -0.487550160f, -0.873094978f, + -0.482183772f, -0.876070094f, + -0.476799230f, -0.879012226f, + -0.471396737f, -0.881921264f, + -0.465976496f, -0.884797098f, + -0.460538711f, -0.887639620f, + -0.455083587f, -0.890448723f, + -0.449611330f, -0.893224301f, + -0.444122145f, -0.895966250f, + -0.438616239f, -0.898674466f, + -0.433093819f, -0.901348847f, + -0.427555093f, -0.903989293f, + -0.422000271f, -0.906595705f, + -0.416429560f, -0.909167983f, + -0.410843171f, -0.911706032f, + -0.405241314f, -0.914209756f, + -0.399624200f, -0.916679060f, + -0.393992040f, -0.919113852f, + -0.388345047f, -0.921514039f, + -0.382683432f, -0.923879533f, + -0.377007410f, -0.926210242f, + -0.371317194f, -0.928506080f, + -0.365612998f, -0.930766961f, + -0.359895037f, -0.932992799f, + -0.354163525f, -0.935183510f, + -0.348418680f, -0.937339012f, + -0.342660717f, -0.939459224f, + -0.336889853f, -0.941544065f, + -0.331106306f, -0.943593458f, + -0.325310292f, -0.945607325f, + -0.319502031f, -0.947585591f, + -0.313681740f, -0.949528181f, + -0.307849640f, -0.951435021f, + -0.302005949f, -0.953306040f, + -0.296150888f, -0.955141168f, + -0.290284677f, -0.956940336f, + -0.284407537f, -0.958703475f, + -0.278519689f, -0.960430519f, + -0.272621355f, -0.962121404f, + -0.266712757f, -0.963776066f, + -0.260794118f, -0.965394442f, + -0.254865660f, -0.966976471f, + -0.248927606f, -0.968522094f, + -0.242980180f, -0.970031253f, + -0.237023606f, -0.971503891f, + -0.231058108f, -0.972939952f, + -0.225083911f, -0.974339383f, + -0.219101240f, -0.975702130f, + -0.213110320f, -0.977028143f, + -0.207111376f, -0.978317371f, + -0.201104635f, -0.979569766f, + -0.195090322f, -0.980785280f, + -0.189068664f, -0.981963869f, + -0.183039888f, -0.983105487f, + -0.177004220f, -0.984210092f, + -0.170961889f, -0.985277642f, + -0.164913120f, -0.986308097f, + -0.158858143f, -0.987301418f, + -0.152797185f, -0.988257568f, + -0.146730474f, -0.989176510f, + -0.140658239f, -0.990058210f, + -0.134580709f, -0.990902635f, + -0.128498111f, -0.991709754f, + -0.122410675f, -0.992479535f, + -0.116318631f, -0.993211949f, + -0.110222207f, -0.993906970f, + -0.104121634f, -0.994564571f, + -0.098017140f, -0.995184727f, + -0.091908956f, -0.995767414f, + -0.085797312f, -0.996312612f, + -0.079682438f, -0.996820299f, + -0.073564564f, -0.997290457f, + -0.067443920f, -0.997723067f, + -0.061320736f, -0.998118113f, + -0.055195244f, -0.998475581f, + -0.049067674f, -0.998795456f, + -0.042938257f, -0.999077728f, + -0.036807223f, -0.999322385f, + -0.030674803f, -0.999529418f, + -0.024541229f, -0.999698819f, + -0.018406730f, -0.999830582f, + -0.012271538f, -0.999924702f, + -0.006135885f, -0.999981175f, + -0.000000000f, -1.000000000f, + 0.006135885f, -0.999981175f, + 0.012271538f, -0.999924702f, + 0.018406730f, -0.999830582f, + 0.024541229f, -0.999698819f, + 0.030674803f, -0.999529418f, + 0.036807223f, -0.999322385f, + 0.042938257f, -0.999077728f, + 0.049067674f, -0.998795456f, + 0.055195244f, -0.998475581f, + 0.061320736f, -0.998118113f, + 0.067443920f, -0.997723067f, + 0.073564564f, -0.997290457f, + 0.079682438f, -0.996820299f, + 0.085797312f, -0.996312612f, + 0.091908956f, -0.995767414f, + 0.098017140f, -0.995184727f, + 0.104121634f, -0.994564571f, + 0.110222207f, -0.993906970f, + 0.116318631f, -0.993211949f, + 0.122410675f, -0.992479535f, + 0.128498111f, -0.991709754f, + 0.134580709f, -0.990902635f, + 0.140658239f, -0.990058210f, + 0.146730474f, -0.989176510f, + 0.152797185f, -0.988257568f, + 0.158858143f, -0.987301418f, + 0.164913120f, -0.986308097f, + 0.170961889f, -0.985277642f, + 0.177004220f, -0.984210092f, + 0.183039888f, -0.983105487f, + 0.189068664f, -0.981963869f, + 0.195090322f, -0.980785280f, + 0.201104635f, -0.979569766f, + 0.207111376f, -0.978317371f, + 0.213110320f, -0.977028143f, + 0.219101240f, -0.975702130f, + 0.225083911f, -0.974339383f, + 0.231058108f, -0.972939952f, + 0.237023606f, -0.971503891f, + 0.242980180f, -0.970031253f, + 0.248927606f, -0.968522094f, + 0.254865660f, -0.966976471f, + 0.260794118f, -0.965394442f, + 0.266712757f, -0.963776066f, + 0.272621355f, -0.962121404f, + 0.278519689f, -0.960430519f, + 0.284407537f, -0.958703475f, + 0.290284677f, -0.956940336f, + 0.296150888f, -0.955141168f, + 0.302005949f, -0.953306040f, + 0.307849640f, -0.951435021f, + 0.313681740f, -0.949528181f, + 0.319502031f, -0.947585591f, + 0.325310292f, -0.945607325f, + 0.331106306f, -0.943593458f, + 0.336889853f, -0.941544065f, + 0.342660717f, -0.939459224f, + 0.348418680f, -0.937339012f, + 0.354163525f, -0.935183510f, + 0.359895037f, -0.932992799f, + 0.365612998f, -0.930766961f, + 0.371317194f, -0.928506080f, + 0.377007410f, -0.926210242f, + 0.382683432f, -0.923879533f, + 0.388345047f, -0.921514039f, + 0.393992040f, -0.919113852f, + 0.399624200f, -0.916679060f, + 0.405241314f, -0.914209756f, + 0.410843171f, -0.911706032f, + 0.416429560f, -0.909167983f, + 0.422000271f, -0.906595705f, + 0.427555093f, -0.903989293f, + 0.433093819f, -0.901348847f, + 0.438616239f, -0.898674466f, + 0.444122145f, -0.895966250f, + 0.449611330f, -0.893224301f, + 0.455083587f, -0.890448723f, + 0.460538711f, -0.887639620f, + 0.465976496f, -0.884797098f, + 0.471396737f, -0.881921264f, + 0.476799230f, -0.879012226f, + 0.482183772f, -0.876070094f, + 0.487550160f, -0.873094978f, + 0.492898192f, -0.870086991f, + 0.498227667f, -0.867046246f, + 0.503538384f, -0.863972856f, + 0.508830143f, -0.860866939f, + 0.514102744f, -0.857728610f, + 0.519355990f, -0.854557988f, + 0.524589683f, -0.851355193f, + 0.529803625f, -0.848120345f, + 0.534997620f, -0.844853565f, + 0.540171473f, -0.841554977f, + 0.545324988f, -0.838224706f, + 0.550457973f, -0.834862875f, + 0.555570233f, -0.831469612f, + 0.560661576f, -0.828045045f, + 0.565731811f, -0.824589303f, + 0.570780746f, -0.821102515f, + 0.575808191f, -0.817584813f, + 0.580813958f, -0.814036330f, + 0.585797857f, -0.810457198f, + 0.590759702f, -0.806847554f, + 0.595699304f, -0.803207531f, + 0.600616479f, -0.799537269f, + 0.605511041f, -0.795836905f, + 0.610382806f, -0.792106577f, + 0.615231591f, -0.788346428f, + 0.620057212f, -0.784556597f, + 0.624859488f, -0.780737229f, + 0.629638239f, -0.776888466f, + 0.634393284f, -0.773010453f, + 0.639124445f, -0.769103338f, + 0.643831543f, -0.765167266f, + 0.648514401f, -0.761202385f, + 0.653172843f, -0.757208847f, + 0.657806693f, -0.753186799f, + 0.662415778f, -0.749136395f, + 0.666999922f, -0.745057785f, + 0.671558955f, -0.740951125f, + 0.676092704f, -0.736816569f, + 0.680600998f, -0.732654272f, + 0.685083668f, -0.728464390f, + 0.689540545f, -0.724247083f, + 0.693971461f, -0.720002508f, + 0.698376249f, -0.715730825f, + 0.702754744f, -0.711432196f, + 0.707106781f, -0.707106781f, + 0.711432196f, -0.702754744f, + 0.715730825f, -0.698376249f, + 0.720002508f, -0.693971461f, + 0.724247083f, -0.689540545f, + 0.728464390f, -0.685083668f, + 0.732654272f, -0.680600998f, + 0.736816569f, -0.676092704f, + 0.740951125f, -0.671558955f, + 0.745057785f, -0.666999922f, + 0.749136395f, -0.662415778f, + 0.753186799f, -0.657806693f, + 0.757208847f, -0.653172843f, + 0.761202385f, -0.648514401f, + 0.765167266f, -0.643831543f, + 0.769103338f, -0.639124445f, + 0.773010453f, -0.634393284f, + 0.776888466f, -0.629638239f, + 0.780737229f, -0.624859488f, + 0.784556597f, -0.620057212f, + 0.788346428f, -0.615231591f, + 0.792106577f, -0.610382806f, + 0.795836905f, -0.605511041f, + 0.799537269f, -0.600616479f, + 0.803207531f, -0.595699304f, + 0.806847554f, -0.590759702f, + 0.810457198f, -0.585797857f, + 0.814036330f, -0.580813958f, + 0.817584813f, -0.575808191f, + 0.821102515f, -0.570780746f, + 0.824589303f, -0.565731811f, + 0.828045045f, -0.560661576f, + 0.831469612f, -0.555570233f, + 0.834862875f, -0.550457973f, + 0.838224706f, -0.545324988f, + 0.841554977f, -0.540171473f, + 0.844853565f, -0.534997620f, + 0.848120345f, -0.529803625f, + 0.851355193f, -0.524589683f, + 0.854557988f, -0.519355990f, + 0.857728610f, -0.514102744f, + 0.860866939f, -0.508830143f, + 0.863972856f, -0.503538384f, + 0.867046246f, -0.498227667f, + 0.870086991f, -0.492898192f, + 0.873094978f, -0.487550160f, + 0.876070094f, -0.482183772f, + 0.879012226f, -0.476799230f, + 0.881921264f, -0.471396737f, + 0.884797098f, -0.465976496f, + 0.887639620f, -0.460538711f, + 0.890448723f, -0.455083587f, + 0.893224301f, -0.449611330f, + 0.895966250f, -0.444122145f, + 0.898674466f, -0.438616239f, + 0.901348847f, -0.433093819f, + 0.903989293f, -0.427555093f, + 0.906595705f, -0.422000271f, + 0.909167983f, -0.416429560f, + 0.911706032f, -0.410843171f, + 0.914209756f, -0.405241314f, + 0.916679060f, -0.399624200f, + 0.919113852f, -0.393992040f, + 0.921514039f, -0.388345047f, + 0.923879533f, -0.382683432f, + 0.926210242f, -0.377007410f, + 0.928506080f, -0.371317194f, + 0.930766961f, -0.365612998f, + 0.932992799f, -0.359895037f, + 0.935183510f, -0.354163525f, + 0.937339012f, -0.348418680f, + 0.939459224f, -0.342660717f, + 0.941544065f, -0.336889853f, + 0.943593458f, -0.331106306f, + 0.945607325f, -0.325310292f, + 0.947585591f, -0.319502031f, + 0.949528181f, -0.313681740f, + 0.951435021f, -0.307849640f, + 0.953306040f, -0.302005949f, + 0.955141168f, -0.296150888f, + 0.956940336f, -0.290284677f, + 0.958703475f, -0.284407537f, + 0.960430519f, -0.278519689f, + 0.962121404f, -0.272621355f, + 0.963776066f, -0.266712757f, + 0.965394442f, -0.260794118f, + 0.966976471f, -0.254865660f, + 0.968522094f, -0.248927606f, + 0.970031253f, -0.242980180f, + 0.971503891f, -0.237023606f, + 0.972939952f, -0.231058108f, + 0.974339383f, -0.225083911f, + 0.975702130f, -0.219101240f, + 0.977028143f, -0.213110320f, + 0.978317371f, -0.207111376f, + 0.979569766f, -0.201104635f, + 0.980785280f, -0.195090322f, + 0.981963869f, -0.189068664f, + 0.983105487f, -0.183039888f, + 0.984210092f, -0.177004220f, + 0.985277642f, -0.170961889f, + 0.986308097f, -0.164913120f, + 0.987301418f, -0.158858143f, + 0.988257568f, -0.152797185f, + 0.989176510f, -0.146730474f, + 0.990058210f, -0.140658239f, + 0.990902635f, -0.134580709f, + 0.991709754f, -0.128498111f, + 0.992479535f, -0.122410675f, + 0.993211949f, -0.116318631f, + 0.993906970f, -0.110222207f, + 0.994564571f, -0.104121634f, + 0.995184727f, -0.098017140f, + 0.995767414f, -0.091908956f, + 0.996312612f, -0.085797312f, + 0.996820299f, -0.079682438f, + 0.997290457f, -0.073564564f, + 0.997723067f, -0.067443920f, + 0.998118113f, -0.061320736f, + 0.998475581f, -0.055195244f, + 0.998795456f, -0.049067674f, + 0.999077728f, -0.042938257f, + 0.999322385f, -0.036807223f, + 0.999529418f, -0.030674803f, + 0.999698819f, -0.024541229f, + 0.999830582f, -0.018406730f, + 0.999924702f, -0.012271538f, + 0.999981175f, -0.006135885f +}; + +/** + @par + Example code for Floating-point Twiddle factors Generation: + @par +
for (i = 0; i< N/; i++)
+  {
+ 	twiddleCoef[2*i]   = cos(i * 2*PI/(float)N);
+ 	twiddleCoef[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 2048, PI = 3.14159265358979 + @par + Cos and Sin values are in interleaved fashion +*/ +const float32_t twiddleCoef_2048[4096] = { + 1.000000000f, 0.000000000f, + 0.999995294f, 0.003067957f, + 0.999981175f, 0.006135885f, + 0.999957645f, 0.009203755f, + 0.999924702f, 0.012271538f, + 0.999882347f, 0.015339206f, + 0.999830582f, 0.018406730f, + 0.999769405f, 0.021474080f, + 0.999698819f, 0.024541229f, + 0.999618822f, 0.027608146f, + 0.999529418f, 0.030674803f, + 0.999430605f, 0.033741172f, + 0.999322385f, 0.036807223f, + 0.999204759f, 0.039872928f, + 0.999077728f, 0.042938257f, + 0.998941293f, 0.046003182f, + 0.998795456f, 0.049067674f, + 0.998640218f, 0.052131705f, + 0.998475581f, 0.055195244f, + 0.998301545f, 0.058258265f, + 0.998118113f, 0.061320736f, + 0.997925286f, 0.064382631f, + 0.997723067f, 0.067443920f, + 0.997511456f, 0.070504573f, + 0.997290457f, 0.073564564f, + 0.997060070f, 0.076623861f, + 0.996820299f, 0.079682438f, + 0.996571146f, 0.082740265f, + 0.996312612f, 0.085797312f, + 0.996044701f, 0.088853553f, + 0.995767414f, 0.091908956f, + 0.995480755f, 0.094963495f, + 0.995184727f, 0.098017140f, + 0.994879331f, 0.101069863f, + 0.994564571f, 0.104121634f, + 0.994240449f, 0.107172425f, + 0.993906970f, 0.110222207f, + 0.993564136f, 0.113270952f, + 0.993211949f, 0.116318631f, + 0.992850414f, 0.119365215f, + 0.992479535f, 0.122410675f, + 0.992099313f, 0.125454983f, + 0.991709754f, 0.128498111f, + 0.991310860f, 0.131540029f, + 0.990902635f, 0.134580709f, + 0.990485084f, 0.137620122f, + 0.990058210f, 0.140658239f, + 0.989622017f, 0.143695033f, + 0.989176510f, 0.146730474f, + 0.988721692f, 0.149764535f, + 0.988257568f, 0.152797185f, + 0.987784142f, 0.155828398f, + 0.987301418f, 0.158858143f, + 0.986809402f, 0.161886394f, + 0.986308097f, 0.164913120f, + 0.985797509f, 0.167938295f, + 0.985277642f, 0.170961889f, + 0.984748502f, 0.173983873f, + 0.984210092f, 0.177004220f, + 0.983662419f, 0.180022901f, + 0.983105487f, 0.183039888f, + 0.982539302f, 0.186055152f, + 0.981963869f, 0.189068664f, + 0.981379193f, 0.192080397f, + 0.980785280f, 0.195090322f, + 0.980182136f, 0.198098411f, + 0.979569766f, 0.201104635f, + 0.978948175f, 0.204108966f, + 0.978317371f, 0.207111376f, + 0.977677358f, 0.210111837f, + 0.977028143f, 0.213110320f, + 0.976369731f, 0.216106797f, + 0.975702130f, 0.219101240f, + 0.975025345f, 0.222093621f, + 0.974339383f, 0.225083911f, + 0.973644250f, 0.228072083f, + 0.972939952f, 0.231058108f, + 0.972226497f, 0.234041959f, + 0.971503891f, 0.237023606f, + 0.970772141f, 0.240003022f, + 0.970031253f, 0.242980180f, + 0.969281235f, 0.245955050f, + 0.968522094f, 0.248927606f, + 0.967753837f, 0.251897818f, + 0.966976471f, 0.254865660f, + 0.966190003f, 0.257831102f, + 0.965394442f, 0.260794118f, + 0.964589793f, 0.263754679f, + 0.963776066f, 0.266712757f, + 0.962953267f, 0.269668326f, + 0.962121404f, 0.272621355f, + 0.961280486f, 0.275571819f, + 0.960430519f, 0.278519689f, + 0.959571513f, 0.281464938f, + 0.958703475f, 0.284407537f, + 0.957826413f, 0.287347460f, + 0.956940336f, 0.290284677f, + 0.956045251f, 0.293219163f, + 0.955141168f, 0.296150888f, + 0.954228095f, 0.299079826f, + 0.953306040f, 0.302005949f, + 0.952375013f, 0.304929230f, + 0.951435021f, 0.307849640f, + 0.950486074f, 0.310767153f, + 0.949528181f, 0.313681740f, + 0.948561350f, 0.316593376f, + 0.947585591f, 0.319502031f, + 0.946600913f, 0.322407679f, + 0.945607325f, 0.325310292f, + 0.944604837f, 0.328209844f, + 0.943593458f, 0.331106306f, + 0.942573198f, 0.333999651f, + 0.941544065f, 0.336889853f, + 0.940506071f, 0.339776884f, + 0.939459224f, 0.342660717f, + 0.938403534f, 0.345541325f, + 0.937339012f, 0.348418680f, + 0.936265667f, 0.351292756f, + 0.935183510f, 0.354163525f, + 0.934092550f, 0.357030961f, + 0.932992799f, 0.359895037f, + 0.931884266f, 0.362755724f, + 0.930766961f, 0.365612998f, + 0.929640896f, 0.368466830f, + 0.928506080f, 0.371317194f, + 0.927362526f, 0.374164063f, + 0.926210242f, 0.377007410f, + 0.925049241f, 0.379847209f, + 0.923879533f, 0.382683432f, + 0.922701128f, 0.385516054f, + 0.921514039f, 0.388345047f, + 0.920318277f, 0.391170384f, + 0.919113852f, 0.393992040f, + 0.917900776f, 0.396809987f, + 0.916679060f, 0.399624200f, + 0.915448716f, 0.402434651f, + 0.914209756f, 0.405241314f, + 0.912962190f, 0.408044163f, + 0.911706032f, 0.410843171f, + 0.910441292f, 0.413638312f, + 0.909167983f, 0.416429560f, + 0.907886116f, 0.419216888f, + 0.906595705f, 0.422000271f, + 0.905296759f, 0.424779681f, + 0.903989293f, 0.427555093f, + 0.902673318f, 0.430326481f, + 0.901348847f, 0.433093819f, + 0.900015892f, 0.435857080f, + 0.898674466f, 0.438616239f, + 0.897324581f, 0.441371269f, + 0.895966250f, 0.444122145f, + 0.894599486f, 0.446868840f, + 0.893224301f, 0.449611330f, + 0.891840709f, 0.452349587f, + 0.890448723f, 0.455083587f, + 0.889048356f, 0.457813304f, + 0.887639620f, 0.460538711f, + 0.886222530f, 0.463259784f, + 0.884797098f, 0.465976496f, + 0.883363339f, 0.468688822f, + 0.881921264f, 0.471396737f, + 0.880470889f, 0.474100215f, + 0.879012226f, 0.476799230f, + 0.877545290f, 0.479493758f, + 0.876070094f, 0.482183772f, + 0.874586652f, 0.484869248f, + 0.873094978f, 0.487550160f, + 0.871595087f, 0.490226483f, + 0.870086991f, 0.492898192f, + 0.868570706f, 0.495565262f, + 0.867046246f, 0.498227667f, + 0.865513624f, 0.500885383f, + 0.863972856f, 0.503538384f, + 0.862423956f, 0.506186645f, + 0.860866939f, 0.508830143f, + 0.859301818f, 0.511468850f, + 0.857728610f, 0.514102744f, + 0.856147328f, 0.516731799f, + 0.854557988f, 0.519355990f, + 0.852960605f, 0.521975293f, + 0.851355193f, 0.524589683f, + 0.849741768f, 0.527199135f, + 0.848120345f, 0.529803625f, + 0.846490939f, 0.532403128f, + 0.844853565f, 0.534997620f, + 0.843208240f, 0.537587076f, + 0.841554977f, 0.540171473f, + 0.839893794f, 0.542750785f, + 0.838224706f, 0.545324988f, + 0.836547727f, 0.547894059f, + 0.834862875f, 0.550457973f, + 0.833170165f, 0.553016706f, + 0.831469612f, 0.555570233f, + 0.829761234f, 0.558118531f, + 0.828045045f, 0.560661576f, + 0.826321063f, 0.563199344f, + 0.824589303f, 0.565731811f, + 0.822849781f, 0.568258953f, + 0.821102515f, 0.570780746f, + 0.819347520f, 0.573297167f, + 0.817584813f, 0.575808191f, + 0.815814411f, 0.578313796f, + 0.814036330f, 0.580813958f, + 0.812250587f, 0.583308653f, + 0.810457198f, 0.585797857f, + 0.808656182f, 0.588281548f, + 0.806847554f, 0.590759702f, + 0.805031331f, 0.593232295f, + 0.803207531f, 0.595699304f, + 0.801376172f, 0.598160707f, + 0.799537269f, 0.600616479f, + 0.797690841f, 0.603066599f, + 0.795836905f, 0.605511041f, + 0.793975478f, 0.607949785f, + 0.792106577f, 0.610382806f, + 0.790230221f, 0.612810082f, + 0.788346428f, 0.615231591f, + 0.786455214f, 0.617647308f, + 0.784556597f, 0.620057212f, + 0.782650596f, 0.622461279f, + 0.780737229f, 0.624859488f, + 0.778816512f, 0.627251815f, + 0.776888466f, 0.629638239f, + 0.774953107f, 0.632018736f, + 0.773010453f, 0.634393284f, + 0.771060524f, 0.636761861f, + 0.769103338f, 0.639124445f, + 0.767138912f, 0.641481013f, + 0.765167266f, 0.643831543f, + 0.763188417f, 0.646176013f, + 0.761202385f, 0.648514401f, + 0.759209189f, 0.650846685f, + 0.757208847f, 0.653172843f, + 0.755201377f, 0.655492853f, + 0.753186799f, 0.657806693f, + 0.751165132f, 0.660114342f, + 0.749136395f, 0.662415778f, + 0.747100606f, 0.664710978f, + 0.745057785f, 0.666999922f, + 0.743007952f, 0.669282588f, + 0.740951125f, 0.671558955f, + 0.738887324f, 0.673829000f, + 0.736816569f, 0.676092704f, + 0.734738878f, 0.678350043f, + 0.732654272f, 0.680600998f, + 0.730562769f, 0.682845546f, + 0.728464390f, 0.685083668f, + 0.726359155f, 0.687315341f, + 0.724247083f, 0.689540545f, + 0.722128194f, 0.691759258f, + 0.720002508f, 0.693971461f, + 0.717870045f, 0.696177131f, + 0.715730825f, 0.698376249f, + 0.713584869f, 0.700568794f, + 0.711432196f, 0.702754744f, + 0.709272826f, 0.704934080f, + 0.707106781f, 0.707106781f, + 0.704934080f, 0.709272826f, + 0.702754744f, 0.711432196f, + 0.700568794f, 0.713584869f, + 0.698376249f, 0.715730825f, + 0.696177131f, 0.717870045f, + 0.693971461f, 0.720002508f, + 0.691759258f, 0.722128194f, + 0.689540545f, 0.724247083f, + 0.687315341f, 0.726359155f, + 0.685083668f, 0.728464390f, + 0.682845546f, 0.730562769f, + 0.680600998f, 0.732654272f, + 0.678350043f, 0.734738878f, + 0.676092704f, 0.736816569f, + 0.673829000f, 0.738887324f, + 0.671558955f, 0.740951125f, + 0.669282588f, 0.743007952f, + 0.666999922f, 0.745057785f, + 0.664710978f, 0.747100606f, + 0.662415778f, 0.749136395f, + 0.660114342f, 0.751165132f, + 0.657806693f, 0.753186799f, + 0.655492853f, 0.755201377f, + 0.653172843f, 0.757208847f, + 0.650846685f, 0.759209189f, + 0.648514401f, 0.761202385f, + 0.646176013f, 0.763188417f, + 0.643831543f, 0.765167266f, + 0.641481013f, 0.767138912f, + 0.639124445f, 0.769103338f, + 0.636761861f, 0.771060524f, + 0.634393284f, 0.773010453f, + 0.632018736f, 0.774953107f, + 0.629638239f, 0.776888466f, + 0.627251815f, 0.778816512f, + 0.624859488f, 0.780737229f, + 0.622461279f, 0.782650596f, + 0.620057212f, 0.784556597f, + 0.617647308f, 0.786455214f, + 0.615231591f, 0.788346428f, + 0.612810082f, 0.790230221f, + 0.610382806f, 0.792106577f, + 0.607949785f, 0.793975478f, + 0.605511041f, 0.795836905f, + 0.603066599f, 0.797690841f, + 0.600616479f, 0.799537269f, + 0.598160707f, 0.801376172f, + 0.595699304f, 0.803207531f, + 0.593232295f, 0.805031331f, + 0.590759702f, 0.806847554f, + 0.588281548f, 0.808656182f, + 0.585797857f, 0.810457198f, + 0.583308653f, 0.812250587f, + 0.580813958f, 0.814036330f, + 0.578313796f, 0.815814411f, + 0.575808191f, 0.817584813f, + 0.573297167f, 0.819347520f, + 0.570780746f, 0.821102515f, + 0.568258953f, 0.822849781f, + 0.565731811f, 0.824589303f, + 0.563199344f, 0.826321063f, + 0.560661576f, 0.828045045f, + 0.558118531f, 0.829761234f, + 0.555570233f, 0.831469612f, + 0.553016706f, 0.833170165f, + 0.550457973f, 0.834862875f, + 0.547894059f, 0.836547727f, + 0.545324988f, 0.838224706f, + 0.542750785f, 0.839893794f, + 0.540171473f, 0.841554977f, + 0.537587076f, 0.843208240f, + 0.534997620f, 0.844853565f, + 0.532403128f, 0.846490939f, + 0.529803625f, 0.848120345f, + 0.527199135f, 0.849741768f, + 0.524589683f, 0.851355193f, + 0.521975293f, 0.852960605f, + 0.519355990f, 0.854557988f, + 0.516731799f, 0.856147328f, + 0.514102744f, 0.857728610f, + 0.511468850f, 0.859301818f, + 0.508830143f, 0.860866939f, + 0.506186645f, 0.862423956f, + 0.503538384f, 0.863972856f, + 0.500885383f, 0.865513624f, + 0.498227667f, 0.867046246f, + 0.495565262f, 0.868570706f, + 0.492898192f, 0.870086991f, + 0.490226483f, 0.871595087f, + 0.487550160f, 0.873094978f, + 0.484869248f, 0.874586652f, + 0.482183772f, 0.876070094f, + 0.479493758f, 0.877545290f, + 0.476799230f, 0.879012226f, + 0.474100215f, 0.880470889f, + 0.471396737f, 0.881921264f, + 0.468688822f, 0.883363339f, + 0.465976496f, 0.884797098f, + 0.463259784f, 0.886222530f, + 0.460538711f, 0.887639620f, + 0.457813304f, 0.889048356f, + 0.455083587f, 0.890448723f, + 0.452349587f, 0.891840709f, + 0.449611330f, 0.893224301f, + 0.446868840f, 0.894599486f, + 0.444122145f, 0.895966250f, + 0.441371269f, 0.897324581f, + 0.438616239f, 0.898674466f, + 0.435857080f, 0.900015892f, + 0.433093819f, 0.901348847f, + 0.430326481f, 0.902673318f, + 0.427555093f, 0.903989293f, + 0.424779681f, 0.905296759f, + 0.422000271f, 0.906595705f, + 0.419216888f, 0.907886116f, + 0.416429560f, 0.909167983f, + 0.413638312f, 0.910441292f, + 0.410843171f, 0.911706032f, + 0.408044163f, 0.912962190f, + 0.405241314f, 0.914209756f, + 0.402434651f, 0.915448716f, + 0.399624200f, 0.916679060f, + 0.396809987f, 0.917900776f, + 0.393992040f, 0.919113852f, + 0.391170384f, 0.920318277f, + 0.388345047f, 0.921514039f, + 0.385516054f, 0.922701128f, + 0.382683432f, 0.923879533f, + 0.379847209f, 0.925049241f, + 0.377007410f, 0.926210242f, + 0.374164063f, 0.927362526f, + 0.371317194f, 0.928506080f, + 0.368466830f, 0.929640896f, + 0.365612998f, 0.930766961f, + 0.362755724f, 0.931884266f, + 0.359895037f, 0.932992799f, + 0.357030961f, 0.934092550f, + 0.354163525f, 0.935183510f, + 0.351292756f, 0.936265667f, + 0.348418680f, 0.937339012f, + 0.345541325f, 0.938403534f, + 0.342660717f, 0.939459224f, + 0.339776884f, 0.940506071f, + 0.336889853f, 0.941544065f, + 0.333999651f, 0.942573198f, + 0.331106306f, 0.943593458f, + 0.328209844f, 0.944604837f, + 0.325310292f, 0.945607325f, + 0.322407679f, 0.946600913f, + 0.319502031f, 0.947585591f, + 0.316593376f, 0.948561350f, + 0.313681740f, 0.949528181f, + 0.310767153f, 0.950486074f, + 0.307849640f, 0.951435021f, + 0.304929230f, 0.952375013f, + 0.302005949f, 0.953306040f, + 0.299079826f, 0.954228095f, + 0.296150888f, 0.955141168f, + 0.293219163f, 0.956045251f, + 0.290284677f, 0.956940336f, + 0.287347460f, 0.957826413f, + 0.284407537f, 0.958703475f, + 0.281464938f, 0.959571513f, + 0.278519689f, 0.960430519f, + 0.275571819f, 0.961280486f, + 0.272621355f, 0.962121404f, + 0.269668326f, 0.962953267f, + 0.266712757f, 0.963776066f, + 0.263754679f, 0.964589793f, + 0.260794118f, 0.965394442f, + 0.257831102f, 0.966190003f, + 0.254865660f, 0.966976471f, + 0.251897818f, 0.967753837f, + 0.248927606f, 0.968522094f, + 0.245955050f, 0.969281235f, + 0.242980180f, 0.970031253f, + 0.240003022f, 0.970772141f, + 0.237023606f, 0.971503891f, + 0.234041959f, 0.972226497f, + 0.231058108f, 0.972939952f, + 0.228072083f, 0.973644250f, + 0.225083911f, 0.974339383f, + 0.222093621f, 0.975025345f, + 0.219101240f, 0.975702130f, + 0.216106797f, 0.976369731f, + 0.213110320f, 0.977028143f, + 0.210111837f, 0.977677358f, + 0.207111376f, 0.978317371f, + 0.204108966f, 0.978948175f, + 0.201104635f, 0.979569766f, + 0.198098411f, 0.980182136f, + 0.195090322f, 0.980785280f, + 0.192080397f, 0.981379193f, + 0.189068664f, 0.981963869f, + 0.186055152f, 0.982539302f, + 0.183039888f, 0.983105487f, + 0.180022901f, 0.983662419f, + 0.177004220f, 0.984210092f, + 0.173983873f, 0.984748502f, + 0.170961889f, 0.985277642f, + 0.167938295f, 0.985797509f, + 0.164913120f, 0.986308097f, + 0.161886394f, 0.986809402f, + 0.158858143f, 0.987301418f, + 0.155828398f, 0.987784142f, + 0.152797185f, 0.988257568f, + 0.149764535f, 0.988721692f, + 0.146730474f, 0.989176510f, + 0.143695033f, 0.989622017f, + 0.140658239f, 0.990058210f, + 0.137620122f, 0.990485084f, + 0.134580709f, 0.990902635f, + 0.131540029f, 0.991310860f, + 0.128498111f, 0.991709754f, + 0.125454983f, 0.992099313f, + 0.122410675f, 0.992479535f, + 0.119365215f, 0.992850414f, + 0.116318631f, 0.993211949f, + 0.113270952f, 0.993564136f, + 0.110222207f, 0.993906970f, + 0.107172425f, 0.994240449f, + 0.104121634f, 0.994564571f, + 0.101069863f, 0.994879331f, + 0.098017140f, 0.995184727f, + 0.094963495f, 0.995480755f, + 0.091908956f, 0.995767414f, + 0.088853553f, 0.996044701f, + 0.085797312f, 0.996312612f, + 0.082740265f, 0.996571146f, + 0.079682438f, 0.996820299f, + 0.076623861f, 0.997060070f, + 0.073564564f, 0.997290457f, + 0.070504573f, 0.997511456f, + 0.067443920f, 0.997723067f, + 0.064382631f, 0.997925286f, + 0.061320736f, 0.998118113f, + 0.058258265f, 0.998301545f, + 0.055195244f, 0.998475581f, + 0.052131705f, 0.998640218f, + 0.049067674f, 0.998795456f, + 0.046003182f, 0.998941293f, + 0.042938257f, 0.999077728f, + 0.039872928f, 0.999204759f, + 0.036807223f, 0.999322385f, + 0.033741172f, 0.999430605f, + 0.030674803f, 0.999529418f, + 0.027608146f, 0.999618822f, + 0.024541229f, 0.999698819f, + 0.021474080f, 0.999769405f, + 0.018406730f, 0.999830582f, + 0.015339206f, 0.999882347f, + 0.012271538f, 0.999924702f, + 0.009203755f, 0.999957645f, + 0.006135885f, 0.999981175f, + 0.003067957f, 0.999995294f, + 0.000000000f, 1.000000000f, + -0.003067957f, 0.999995294f, + -0.006135885f, 0.999981175f, + -0.009203755f, 0.999957645f, + -0.012271538f, 0.999924702f, + -0.015339206f, 0.999882347f, + -0.018406730f, 0.999830582f, + -0.021474080f, 0.999769405f, + -0.024541229f, 0.999698819f, + -0.027608146f, 0.999618822f, + -0.030674803f, 0.999529418f, + -0.033741172f, 0.999430605f, + -0.036807223f, 0.999322385f, + -0.039872928f, 0.999204759f, + -0.042938257f, 0.999077728f, + -0.046003182f, 0.998941293f, + -0.049067674f, 0.998795456f, + -0.052131705f, 0.998640218f, + -0.055195244f, 0.998475581f, + -0.058258265f, 0.998301545f, + -0.061320736f, 0.998118113f, + -0.064382631f, 0.997925286f, + -0.067443920f, 0.997723067f, + -0.070504573f, 0.997511456f, + -0.073564564f, 0.997290457f, + -0.076623861f, 0.997060070f, + -0.079682438f, 0.996820299f, + -0.082740265f, 0.996571146f, + -0.085797312f, 0.996312612f, + -0.088853553f, 0.996044701f, + -0.091908956f, 0.995767414f, + -0.094963495f, 0.995480755f, + -0.098017140f, 0.995184727f, + -0.101069863f, 0.994879331f, + -0.104121634f, 0.994564571f, + -0.107172425f, 0.994240449f, + -0.110222207f, 0.993906970f, + -0.113270952f, 0.993564136f, + -0.116318631f, 0.993211949f, + -0.119365215f, 0.992850414f, + -0.122410675f, 0.992479535f, + -0.125454983f, 0.992099313f, + -0.128498111f, 0.991709754f, + -0.131540029f, 0.991310860f, + -0.134580709f, 0.990902635f, + -0.137620122f, 0.990485084f, + -0.140658239f, 0.990058210f, + -0.143695033f, 0.989622017f, + -0.146730474f, 0.989176510f, + -0.149764535f, 0.988721692f, + -0.152797185f, 0.988257568f, + -0.155828398f, 0.987784142f, + -0.158858143f, 0.987301418f, + -0.161886394f, 0.986809402f, + -0.164913120f, 0.986308097f, + -0.167938295f, 0.985797509f, + -0.170961889f, 0.985277642f, + -0.173983873f, 0.984748502f, + -0.177004220f, 0.984210092f, + -0.180022901f, 0.983662419f, + -0.183039888f, 0.983105487f, + -0.186055152f, 0.982539302f, + -0.189068664f, 0.981963869f, + -0.192080397f, 0.981379193f, + -0.195090322f, 0.980785280f, + -0.198098411f, 0.980182136f, + -0.201104635f, 0.979569766f, + -0.204108966f, 0.978948175f, + -0.207111376f, 0.978317371f, + -0.210111837f, 0.977677358f, + -0.213110320f, 0.977028143f, + -0.216106797f, 0.976369731f, + -0.219101240f, 0.975702130f, + -0.222093621f, 0.975025345f, + -0.225083911f, 0.974339383f, + -0.228072083f, 0.973644250f, + -0.231058108f, 0.972939952f, + -0.234041959f, 0.972226497f, + -0.237023606f, 0.971503891f, + -0.240003022f, 0.970772141f, + -0.242980180f, 0.970031253f, + -0.245955050f, 0.969281235f, + -0.248927606f, 0.968522094f, + -0.251897818f, 0.967753837f, + -0.254865660f, 0.966976471f, + -0.257831102f, 0.966190003f, + -0.260794118f, 0.965394442f, + -0.263754679f, 0.964589793f, + -0.266712757f, 0.963776066f, + -0.269668326f, 0.962953267f, + -0.272621355f, 0.962121404f, + -0.275571819f, 0.961280486f, + -0.278519689f, 0.960430519f, + -0.281464938f, 0.959571513f, + -0.284407537f, 0.958703475f, + -0.287347460f, 0.957826413f, + -0.290284677f, 0.956940336f, + -0.293219163f, 0.956045251f, + -0.296150888f, 0.955141168f, + -0.299079826f, 0.954228095f, + -0.302005949f, 0.953306040f, + -0.304929230f, 0.952375013f, + -0.307849640f, 0.951435021f, + -0.310767153f, 0.950486074f, + -0.313681740f, 0.949528181f, + -0.316593376f, 0.948561350f, + -0.319502031f, 0.947585591f, + -0.322407679f, 0.946600913f, + -0.325310292f, 0.945607325f, + -0.328209844f, 0.944604837f, + -0.331106306f, 0.943593458f, + -0.333999651f, 0.942573198f, + -0.336889853f, 0.941544065f, + -0.339776884f, 0.940506071f, + -0.342660717f, 0.939459224f, + -0.345541325f, 0.938403534f, + -0.348418680f, 0.937339012f, + -0.351292756f, 0.936265667f, + -0.354163525f, 0.935183510f, + -0.357030961f, 0.934092550f, + -0.359895037f, 0.932992799f, + -0.362755724f, 0.931884266f, + -0.365612998f, 0.930766961f, + -0.368466830f, 0.929640896f, + -0.371317194f, 0.928506080f, + -0.374164063f, 0.927362526f, + -0.377007410f, 0.926210242f, + -0.379847209f, 0.925049241f, + -0.382683432f, 0.923879533f, + -0.385516054f, 0.922701128f, + -0.388345047f, 0.921514039f, + -0.391170384f, 0.920318277f, + -0.393992040f, 0.919113852f, + -0.396809987f, 0.917900776f, + -0.399624200f, 0.916679060f, + -0.402434651f, 0.915448716f, + -0.405241314f, 0.914209756f, + -0.408044163f, 0.912962190f, + -0.410843171f, 0.911706032f, + -0.413638312f, 0.910441292f, + -0.416429560f, 0.909167983f, + -0.419216888f, 0.907886116f, + -0.422000271f, 0.906595705f, + -0.424779681f, 0.905296759f, + -0.427555093f, 0.903989293f, + -0.430326481f, 0.902673318f, + -0.433093819f, 0.901348847f, + -0.435857080f, 0.900015892f, + -0.438616239f, 0.898674466f, + -0.441371269f, 0.897324581f, + -0.444122145f, 0.895966250f, + -0.446868840f, 0.894599486f, + -0.449611330f, 0.893224301f, + -0.452349587f, 0.891840709f, + -0.455083587f, 0.890448723f, + -0.457813304f, 0.889048356f, + -0.460538711f, 0.887639620f, + -0.463259784f, 0.886222530f, + -0.465976496f, 0.884797098f, + -0.468688822f, 0.883363339f, + -0.471396737f, 0.881921264f, + -0.474100215f, 0.880470889f, + -0.476799230f, 0.879012226f, + -0.479493758f, 0.877545290f, + -0.482183772f, 0.876070094f, + -0.484869248f, 0.874586652f, + -0.487550160f, 0.873094978f, + -0.490226483f, 0.871595087f, + -0.492898192f, 0.870086991f, + -0.495565262f, 0.868570706f, + -0.498227667f, 0.867046246f, + -0.500885383f, 0.865513624f, + -0.503538384f, 0.863972856f, + -0.506186645f, 0.862423956f, + -0.508830143f, 0.860866939f, + -0.511468850f, 0.859301818f, + -0.514102744f, 0.857728610f, + -0.516731799f, 0.856147328f, + -0.519355990f, 0.854557988f, + -0.521975293f, 0.852960605f, + -0.524589683f, 0.851355193f, + -0.527199135f, 0.849741768f, + -0.529803625f, 0.848120345f, + -0.532403128f, 0.846490939f, + -0.534997620f, 0.844853565f, + -0.537587076f, 0.843208240f, + -0.540171473f, 0.841554977f, + -0.542750785f, 0.839893794f, + -0.545324988f, 0.838224706f, + -0.547894059f, 0.836547727f, + -0.550457973f, 0.834862875f, + -0.553016706f, 0.833170165f, + -0.555570233f, 0.831469612f, + -0.558118531f, 0.829761234f, + -0.560661576f, 0.828045045f, + -0.563199344f, 0.826321063f, + -0.565731811f, 0.824589303f, + -0.568258953f, 0.822849781f, + -0.570780746f, 0.821102515f, + -0.573297167f, 0.819347520f, + -0.575808191f, 0.817584813f, + -0.578313796f, 0.815814411f, + -0.580813958f, 0.814036330f, + -0.583308653f, 0.812250587f, + -0.585797857f, 0.810457198f, + -0.588281548f, 0.808656182f, + -0.590759702f, 0.806847554f, + -0.593232295f, 0.805031331f, + -0.595699304f, 0.803207531f, + -0.598160707f, 0.801376172f, + -0.600616479f, 0.799537269f, + -0.603066599f, 0.797690841f, + -0.605511041f, 0.795836905f, + -0.607949785f, 0.793975478f, + -0.610382806f, 0.792106577f, + -0.612810082f, 0.790230221f, + -0.615231591f, 0.788346428f, + -0.617647308f, 0.786455214f, + -0.620057212f, 0.784556597f, + -0.622461279f, 0.782650596f, + -0.624859488f, 0.780737229f, + -0.627251815f, 0.778816512f, + -0.629638239f, 0.776888466f, + -0.632018736f, 0.774953107f, + -0.634393284f, 0.773010453f, + -0.636761861f, 0.771060524f, + -0.639124445f, 0.769103338f, + -0.641481013f, 0.767138912f, + -0.643831543f, 0.765167266f, + -0.646176013f, 0.763188417f, + -0.648514401f, 0.761202385f, + -0.650846685f, 0.759209189f, + -0.653172843f, 0.757208847f, + -0.655492853f, 0.755201377f, + -0.657806693f, 0.753186799f, + -0.660114342f, 0.751165132f, + -0.662415778f, 0.749136395f, + -0.664710978f, 0.747100606f, + -0.666999922f, 0.745057785f, + -0.669282588f, 0.743007952f, + -0.671558955f, 0.740951125f, + -0.673829000f, 0.738887324f, + -0.676092704f, 0.736816569f, + -0.678350043f, 0.734738878f, + -0.680600998f, 0.732654272f, + -0.682845546f, 0.730562769f, + -0.685083668f, 0.728464390f, + -0.687315341f, 0.726359155f, + -0.689540545f, 0.724247083f, + -0.691759258f, 0.722128194f, + -0.693971461f, 0.720002508f, + -0.696177131f, 0.717870045f, + -0.698376249f, 0.715730825f, + -0.700568794f, 0.713584869f, + -0.702754744f, 0.711432196f, + -0.704934080f, 0.709272826f, + -0.707106781f, 0.707106781f, + -0.709272826f, 0.704934080f, + -0.711432196f, 0.702754744f, + -0.713584869f, 0.700568794f, + -0.715730825f, 0.698376249f, + -0.717870045f, 0.696177131f, + -0.720002508f, 0.693971461f, + -0.722128194f, 0.691759258f, + -0.724247083f, 0.689540545f, + -0.726359155f, 0.687315341f, + -0.728464390f, 0.685083668f, + -0.730562769f, 0.682845546f, + -0.732654272f, 0.680600998f, + -0.734738878f, 0.678350043f, + -0.736816569f, 0.676092704f, + -0.738887324f, 0.673829000f, + -0.740951125f, 0.671558955f, + -0.743007952f, 0.669282588f, + -0.745057785f, 0.666999922f, + -0.747100606f, 0.664710978f, + -0.749136395f, 0.662415778f, + -0.751165132f, 0.660114342f, + -0.753186799f, 0.657806693f, + -0.755201377f, 0.655492853f, + -0.757208847f, 0.653172843f, + -0.759209189f, 0.650846685f, + -0.761202385f, 0.648514401f, + -0.763188417f, 0.646176013f, + -0.765167266f, 0.643831543f, + -0.767138912f, 0.641481013f, + -0.769103338f, 0.639124445f, + -0.771060524f, 0.636761861f, + -0.773010453f, 0.634393284f, + -0.774953107f, 0.632018736f, + -0.776888466f, 0.629638239f, + -0.778816512f, 0.627251815f, + -0.780737229f, 0.624859488f, + -0.782650596f, 0.622461279f, + -0.784556597f, 0.620057212f, + -0.786455214f, 0.617647308f, + -0.788346428f, 0.615231591f, + -0.790230221f, 0.612810082f, + -0.792106577f, 0.610382806f, + -0.793975478f, 0.607949785f, + -0.795836905f, 0.605511041f, + -0.797690841f, 0.603066599f, + -0.799537269f, 0.600616479f, + -0.801376172f, 0.598160707f, + -0.803207531f, 0.595699304f, + -0.805031331f, 0.593232295f, + -0.806847554f, 0.590759702f, + -0.808656182f, 0.588281548f, + -0.810457198f, 0.585797857f, + -0.812250587f, 0.583308653f, + -0.814036330f, 0.580813958f, + -0.815814411f, 0.578313796f, + -0.817584813f, 0.575808191f, + -0.819347520f, 0.573297167f, + -0.821102515f, 0.570780746f, + -0.822849781f, 0.568258953f, + -0.824589303f, 0.565731811f, + -0.826321063f, 0.563199344f, + -0.828045045f, 0.560661576f, + -0.829761234f, 0.558118531f, + -0.831469612f, 0.555570233f, + -0.833170165f, 0.553016706f, + -0.834862875f, 0.550457973f, + -0.836547727f, 0.547894059f, + -0.838224706f, 0.545324988f, + -0.839893794f, 0.542750785f, + -0.841554977f, 0.540171473f, + -0.843208240f, 0.537587076f, + -0.844853565f, 0.534997620f, + -0.846490939f, 0.532403128f, + -0.848120345f, 0.529803625f, + -0.849741768f, 0.527199135f, + -0.851355193f, 0.524589683f, + -0.852960605f, 0.521975293f, + -0.854557988f, 0.519355990f, + -0.856147328f, 0.516731799f, + -0.857728610f, 0.514102744f, + -0.859301818f, 0.511468850f, + -0.860866939f, 0.508830143f, + -0.862423956f, 0.506186645f, + -0.863972856f, 0.503538384f, + -0.865513624f, 0.500885383f, + -0.867046246f, 0.498227667f, + -0.868570706f, 0.495565262f, + -0.870086991f, 0.492898192f, + -0.871595087f, 0.490226483f, + -0.873094978f, 0.487550160f, + -0.874586652f, 0.484869248f, + -0.876070094f, 0.482183772f, + -0.877545290f, 0.479493758f, + -0.879012226f, 0.476799230f, + -0.880470889f, 0.474100215f, + -0.881921264f, 0.471396737f, + -0.883363339f, 0.468688822f, + -0.884797098f, 0.465976496f, + -0.886222530f, 0.463259784f, + -0.887639620f, 0.460538711f, + -0.889048356f, 0.457813304f, + -0.890448723f, 0.455083587f, + -0.891840709f, 0.452349587f, + -0.893224301f, 0.449611330f, + -0.894599486f, 0.446868840f, + -0.895966250f, 0.444122145f, + -0.897324581f, 0.441371269f, + -0.898674466f, 0.438616239f, + -0.900015892f, 0.435857080f, + -0.901348847f, 0.433093819f, + -0.902673318f, 0.430326481f, + -0.903989293f, 0.427555093f, + -0.905296759f, 0.424779681f, + -0.906595705f, 0.422000271f, + -0.907886116f, 0.419216888f, + -0.909167983f, 0.416429560f, + -0.910441292f, 0.413638312f, + -0.911706032f, 0.410843171f, + -0.912962190f, 0.408044163f, + -0.914209756f, 0.405241314f, + -0.915448716f, 0.402434651f, + -0.916679060f, 0.399624200f, + -0.917900776f, 0.396809987f, + -0.919113852f, 0.393992040f, + -0.920318277f, 0.391170384f, + -0.921514039f, 0.388345047f, + -0.922701128f, 0.385516054f, + -0.923879533f, 0.382683432f, + -0.925049241f, 0.379847209f, + -0.926210242f, 0.377007410f, + -0.927362526f, 0.374164063f, + -0.928506080f, 0.371317194f, + -0.929640896f, 0.368466830f, + -0.930766961f, 0.365612998f, + -0.931884266f, 0.362755724f, + -0.932992799f, 0.359895037f, + -0.934092550f, 0.357030961f, + -0.935183510f, 0.354163525f, + -0.936265667f, 0.351292756f, + -0.937339012f, 0.348418680f, + -0.938403534f, 0.345541325f, + -0.939459224f, 0.342660717f, + -0.940506071f, 0.339776884f, + -0.941544065f, 0.336889853f, + -0.942573198f, 0.333999651f, + -0.943593458f, 0.331106306f, + -0.944604837f, 0.328209844f, + -0.945607325f, 0.325310292f, + -0.946600913f, 0.322407679f, + -0.947585591f, 0.319502031f, + -0.948561350f, 0.316593376f, + -0.949528181f, 0.313681740f, + -0.950486074f, 0.310767153f, + -0.951435021f, 0.307849640f, + -0.952375013f, 0.304929230f, + -0.953306040f, 0.302005949f, + -0.954228095f, 0.299079826f, + -0.955141168f, 0.296150888f, + -0.956045251f, 0.293219163f, + -0.956940336f, 0.290284677f, + -0.957826413f, 0.287347460f, + -0.958703475f, 0.284407537f, + -0.959571513f, 0.281464938f, + -0.960430519f, 0.278519689f, + -0.961280486f, 0.275571819f, + -0.962121404f, 0.272621355f, + -0.962953267f, 0.269668326f, + -0.963776066f, 0.266712757f, + -0.964589793f, 0.263754679f, + -0.965394442f, 0.260794118f, + -0.966190003f, 0.257831102f, + -0.966976471f, 0.254865660f, + -0.967753837f, 0.251897818f, + -0.968522094f, 0.248927606f, + -0.969281235f, 0.245955050f, + -0.970031253f, 0.242980180f, + -0.970772141f, 0.240003022f, + -0.971503891f, 0.237023606f, + -0.972226497f, 0.234041959f, + -0.972939952f, 0.231058108f, + -0.973644250f, 0.228072083f, + -0.974339383f, 0.225083911f, + -0.975025345f, 0.222093621f, + -0.975702130f, 0.219101240f, + -0.976369731f, 0.216106797f, + -0.977028143f, 0.213110320f, + -0.977677358f, 0.210111837f, + -0.978317371f, 0.207111376f, + -0.978948175f, 0.204108966f, + -0.979569766f, 0.201104635f, + -0.980182136f, 0.198098411f, + -0.980785280f, 0.195090322f, + -0.981379193f, 0.192080397f, + -0.981963869f, 0.189068664f, + -0.982539302f, 0.186055152f, + -0.983105487f, 0.183039888f, + -0.983662419f, 0.180022901f, + -0.984210092f, 0.177004220f, + -0.984748502f, 0.173983873f, + -0.985277642f, 0.170961889f, + -0.985797509f, 0.167938295f, + -0.986308097f, 0.164913120f, + -0.986809402f, 0.161886394f, + -0.987301418f, 0.158858143f, + -0.987784142f, 0.155828398f, + -0.988257568f, 0.152797185f, + -0.988721692f, 0.149764535f, + -0.989176510f, 0.146730474f, + -0.989622017f, 0.143695033f, + -0.990058210f, 0.140658239f, + -0.990485084f, 0.137620122f, + -0.990902635f, 0.134580709f, + -0.991310860f, 0.131540029f, + -0.991709754f, 0.128498111f, + -0.992099313f, 0.125454983f, + -0.992479535f, 0.122410675f, + -0.992850414f, 0.119365215f, + -0.993211949f, 0.116318631f, + -0.993564136f, 0.113270952f, + -0.993906970f, 0.110222207f, + -0.994240449f, 0.107172425f, + -0.994564571f, 0.104121634f, + -0.994879331f, 0.101069863f, + -0.995184727f, 0.098017140f, + -0.995480755f, 0.094963495f, + -0.995767414f, 0.091908956f, + -0.996044701f, 0.088853553f, + -0.996312612f, 0.085797312f, + -0.996571146f, 0.082740265f, + -0.996820299f, 0.079682438f, + -0.997060070f, 0.076623861f, + -0.997290457f, 0.073564564f, + -0.997511456f, 0.070504573f, + -0.997723067f, 0.067443920f, + -0.997925286f, 0.064382631f, + -0.998118113f, 0.061320736f, + -0.998301545f, 0.058258265f, + -0.998475581f, 0.055195244f, + -0.998640218f, 0.052131705f, + -0.998795456f, 0.049067674f, + -0.998941293f, 0.046003182f, + -0.999077728f, 0.042938257f, + -0.999204759f, 0.039872928f, + -0.999322385f, 0.036807223f, + -0.999430605f, 0.033741172f, + -0.999529418f, 0.030674803f, + -0.999618822f, 0.027608146f, + -0.999698819f, 0.024541229f, + -0.999769405f, 0.021474080f, + -0.999830582f, 0.018406730f, + -0.999882347f, 0.015339206f, + -0.999924702f, 0.012271538f, + -0.999957645f, 0.009203755f, + -0.999981175f, 0.006135885f, + -0.999995294f, 0.003067957f, + -1.000000000f, 0.000000000f, + -0.999995294f, -0.003067957f, + -0.999981175f, -0.006135885f, + -0.999957645f, -0.009203755f, + -0.999924702f, -0.012271538f, + -0.999882347f, -0.015339206f, + -0.999830582f, -0.018406730f, + -0.999769405f, -0.021474080f, + -0.999698819f, -0.024541229f, + -0.999618822f, -0.027608146f, + -0.999529418f, -0.030674803f, + -0.999430605f, -0.033741172f, + -0.999322385f, -0.036807223f, + -0.999204759f, -0.039872928f, + -0.999077728f, -0.042938257f, + -0.998941293f, -0.046003182f, + -0.998795456f, -0.049067674f, + -0.998640218f, -0.052131705f, + -0.998475581f, -0.055195244f, + -0.998301545f, -0.058258265f, + -0.998118113f, -0.061320736f, + -0.997925286f, -0.064382631f, + -0.997723067f, -0.067443920f, + -0.997511456f, -0.070504573f, + -0.997290457f, -0.073564564f, + -0.997060070f, -0.076623861f, + -0.996820299f, -0.079682438f, + -0.996571146f, -0.082740265f, + -0.996312612f, -0.085797312f, + -0.996044701f, -0.088853553f, + -0.995767414f, -0.091908956f, + -0.995480755f, -0.094963495f, + -0.995184727f, -0.098017140f, + -0.994879331f, -0.101069863f, + -0.994564571f, -0.104121634f, + -0.994240449f, -0.107172425f, + -0.993906970f, -0.110222207f, + -0.993564136f, -0.113270952f, + -0.993211949f, -0.116318631f, + -0.992850414f, -0.119365215f, + -0.992479535f, -0.122410675f, + -0.992099313f, -0.125454983f, + -0.991709754f, -0.128498111f, + -0.991310860f, -0.131540029f, + -0.990902635f, -0.134580709f, + -0.990485084f, -0.137620122f, + -0.990058210f, -0.140658239f, + -0.989622017f, -0.143695033f, + -0.989176510f, -0.146730474f, + -0.988721692f, -0.149764535f, + -0.988257568f, -0.152797185f, + -0.987784142f, -0.155828398f, + -0.987301418f, -0.158858143f, + -0.986809402f, -0.161886394f, + -0.986308097f, -0.164913120f, + -0.985797509f, -0.167938295f, + -0.985277642f, -0.170961889f, + -0.984748502f, -0.173983873f, + -0.984210092f, -0.177004220f, + -0.983662419f, -0.180022901f, + -0.983105487f, -0.183039888f, + -0.982539302f, -0.186055152f, + -0.981963869f, -0.189068664f, + -0.981379193f, -0.192080397f, + -0.980785280f, -0.195090322f, + -0.980182136f, -0.198098411f, + -0.979569766f, -0.201104635f, + -0.978948175f, -0.204108966f, + -0.978317371f, -0.207111376f, + -0.977677358f, -0.210111837f, + -0.977028143f, -0.213110320f, + -0.976369731f, -0.216106797f, + -0.975702130f, -0.219101240f, + -0.975025345f, -0.222093621f, + -0.974339383f, -0.225083911f, + -0.973644250f, -0.228072083f, + -0.972939952f, -0.231058108f, + -0.972226497f, -0.234041959f, + -0.971503891f, -0.237023606f, + -0.970772141f, -0.240003022f, + -0.970031253f, -0.242980180f, + -0.969281235f, -0.245955050f, + -0.968522094f, -0.248927606f, + -0.967753837f, -0.251897818f, + -0.966976471f, -0.254865660f, + -0.966190003f, -0.257831102f, + -0.965394442f, -0.260794118f, + -0.964589793f, -0.263754679f, + -0.963776066f, -0.266712757f, + -0.962953267f, -0.269668326f, + -0.962121404f, -0.272621355f, + -0.961280486f, -0.275571819f, + -0.960430519f, -0.278519689f, + -0.959571513f, -0.281464938f, + -0.958703475f, -0.284407537f, + -0.957826413f, -0.287347460f, + -0.956940336f, -0.290284677f, + -0.956045251f, -0.293219163f, + -0.955141168f, -0.296150888f, + -0.954228095f, -0.299079826f, + -0.953306040f, -0.302005949f, + -0.952375013f, -0.304929230f, + -0.951435021f, -0.307849640f, + -0.950486074f, -0.310767153f, + -0.949528181f, -0.313681740f, + -0.948561350f, -0.316593376f, + -0.947585591f, -0.319502031f, + -0.946600913f, -0.322407679f, + -0.945607325f, -0.325310292f, + -0.944604837f, -0.328209844f, + -0.943593458f, -0.331106306f, + -0.942573198f, -0.333999651f, + -0.941544065f, -0.336889853f, + -0.940506071f, -0.339776884f, + -0.939459224f, -0.342660717f, + -0.938403534f, -0.345541325f, + -0.937339012f, -0.348418680f, + -0.936265667f, -0.351292756f, + -0.935183510f, -0.354163525f, + -0.934092550f, -0.357030961f, + -0.932992799f, -0.359895037f, + -0.931884266f, -0.362755724f, + -0.930766961f, -0.365612998f, + -0.929640896f, -0.368466830f, + -0.928506080f, -0.371317194f, + -0.927362526f, -0.374164063f, + -0.926210242f, -0.377007410f, + -0.925049241f, -0.379847209f, + -0.923879533f, -0.382683432f, + -0.922701128f, -0.385516054f, + -0.921514039f, -0.388345047f, + -0.920318277f, -0.391170384f, + -0.919113852f, -0.393992040f, + -0.917900776f, -0.396809987f, + -0.916679060f, -0.399624200f, + -0.915448716f, -0.402434651f, + -0.914209756f, -0.405241314f, + -0.912962190f, -0.408044163f, + -0.911706032f, -0.410843171f, + -0.910441292f, -0.413638312f, + -0.909167983f, -0.416429560f, + -0.907886116f, -0.419216888f, + -0.906595705f, -0.422000271f, + -0.905296759f, -0.424779681f, + -0.903989293f, -0.427555093f, + -0.902673318f, -0.430326481f, + -0.901348847f, -0.433093819f, + -0.900015892f, -0.435857080f, + -0.898674466f, -0.438616239f, + -0.897324581f, -0.441371269f, + -0.895966250f, -0.444122145f, + -0.894599486f, -0.446868840f, + -0.893224301f, -0.449611330f, + -0.891840709f, -0.452349587f, + -0.890448723f, -0.455083587f, + -0.889048356f, -0.457813304f, + -0.887639620f, -0.460538711f, + -0.886222530f, -0.463259784f, + -0.884797098f, -0.465976496f, + -0.883363339f, -0.468688822f, + -0.881921264f, -0.471396737f, + -0.880470889f, -0.474100215f, + -0.879012226f, -0.476799230f, + -0.877545290f, -0.479493758f, + -0.876070094f, -0.482183772f, + -0.874586652f, -0.484869248f, + -0.873094978f, -0.487550160f, + -0.871595087f, -0.490226483f, + -0.870086991f, -0.492898192f, + -0.868570706f, -0.495565262f, + -0.867046246f, -0.498227667f, + -0.865513624f, -0.500885383f, + -0.863972856f, -0.503538384f, + -0.862423956f, -0.506186645f, + -0.860866939f, -0.508830143f, + -0.859301818f, -0.511468850f, + -0.857728610f, -0.514102744f, + -0.856147328f, -0.516731799f, + -0.854557988f, -0.519355990f, + -0.852960605f, -0.521975293f, + -0.851355193f, -0.524589683f, + -0.849741768f, -0.527199135f, + -0.848120345f, -0.529803625f, + -0.846490939f, -0.532403128f, + -0.844853565f, -0.534997620f, + -0.843208240f, -0.537587076f, + -0.841554977f, -0.540171473f, + -0.839893794f, -0.542750785f, + -0.838224706f, -0.545324988f, + -0.836547727f, -0.547894059f, + -0.834862875f, -0.550457973f, + -0.833170165f, -0.553016706f, + -0.831469612f, -0.555570233f, + -0.829761234f, -0.558118531f, + -0.828045045f, -0.560661576f, + -0.826321063f, -0.563199344f, + -0.824589303f, -0.565731811f, + -0.822849781f, -0.568258953f, + -0.821102515f, -0.570780746f, + -0.819347520f, -0.573297167f, + -0.817584813f, -0.575808191f, + -0.815814411f, -0.578313796f, + -0.814036330f, -0.580813958f, + -0.812250587f, -0.583308653f, + -0.810457198f, -0.585797857f, + -0.808656182f, -0.588281548f, + -0.806847554f, -0.590759702f, + -0.805031331f, -0.593232295f, + -0.803207531f, -0.595699304f, + -0.801376172f, -0.598160707f, + -0.799537269f, -0.600616479f, + -0.797690841f, -0.603066599f, + -0.795836905f, -0.605511041f, + -0.793975478f, -0.607949785f, + -0.792106577f, -0.610382806f, + -0.790230221f, -0.612810082f, + -0.788346428f, -0.615231591f, + -0.786455214f, -0.617647308f, + -0.784556597f, -0.620057212f, + -0.782650596f, -0.622461279f, + -0.780737229f, -0.624859488f, + -0.778816512f, -0.627251815f, + -0.776888466f, -0.629638239f, + -0.774953107f, -0.632018736f, + -0.773010453f, -0.634393284f, + -0.771060524f, -0.636761861f, + -0.769103338f, -0.639124445f, + -0.767138912f, -0.641481013f, + -0.765167266f, -0.643831543f, + -0.763188417f, -0.646176013f, + -0.761202385f, -0.648514401f, + -0.759209189f, -0.650846685f, + -0.757208847f, -0.653172843f, + -0.755201377f, -0.655492853f, + -0.753186799f, -0.657806693f, + -0.751165132f, -0.660114342f, + -0.749136395f, -0.662415778f, + -0.747100606f, -0.664710978f, + -0.745057785f, -0.666999922f, + -0.743007952f, -0.669282588f, + -0.740951125f, -0.671558955f, + -0.738887324f, -0.673829000f, + -0.736816569f, -0.676092704f, + -0.734738878f, -0.678350043f, + -0.732654272f, -0.680600998f, + -0.730562769f, -0.682845546f, + -0.728464390f, -0.685083668f, + -0.726359155f, -0.687315341f, + -0.724247083f, -0.689540545f, + -0.722128194f, -0.691759258f, + -0.720002508f, -0.693971461f, + -0.717870045f, -0.696177131f, + -0.715730825f, -0.698376249f, + -0.713584869f, -0.700568794f, + -0.711432196f, -0.702754744f, + -0.709272826f, -0.704934080f, + -0.707106781f, -0.707106781f, + -0.704934080f, -0.709272826f, + -0.702754744f, -0.711432196f, + -0.700568794f, -0.713584869f, + -0.698376249f, -0.715730825f, + -0.696177131f, -0.717870045f, + -0.693971461f, -0.720002508f, + -0.691759258f, -0.722128194f, + -0.689540545f, -0.724247083f, + -0.687315341f, -0.726359155f, + -0.685083668f, -0.728464390f, + -0.682845546f, -0.730562769f, + -0.680600998f, -0.732654272f, + -0.678350043f, -0.734738878f, + -0.676092704f, -0.736816569f, + -0.673829000f, -0.738887324f, + -0.671558955f, -0.740951125f, + -0.669282588f, -0.743007952f, + -0.666999922f, -0.745057785f, + -0.664710978f, -0.747100606f, + -0.662415778f, -0.749136395f, + -0.660114342f, -0.751165132f, + -0.657806693f, -0.753186799f, + -0.655492853f, -0.755201377f, + -0.653172843f, -0.757208847f, + -0.650846685f, -0.759209189f, + -0.648514401f, -0.761202385f, + -0.646176013f, -0.763188417f, + -0.643831543f, -0.765167266f, + -0.641481013f, -0.767138912f, + -0.639124445f, -0.769103338f, + -0.636761861f, -0.771060524f, + -0.634393284f, -0.773010453f, + -0.632018736f, -0.774953107f, + -0.629638239f, -0.776888466f, + -0.627251815f, -0.778816512f, + -0.624859488f, -0.780737229f, + -0.622461279f, -0.782650596f, + -0.620057212f, -0.784556597f, + -0.617647308f, -0.786455214f, + -0.615231591f, -0.788346428f, + -0.612810082f, -0.790230221f, + -0.610382806f, -0.792106577f, + -0.607949785f, -0.793975478f, + -0.605511041f, -0.795836905f, + -0.603066599f, -0.797690841f, + -0.600616479f, -0.799537269f, + -0.598160707f, -0.801376172f, + -0.595699304f, -0.803207531f, + -0.593232295f, -0.805031331f, + -0.590759702f, -0.806847554f, + -0.588281548f, -0.808656182f, + -0.585797857f, -0.810457198f, + -0.583308653f, -0.812250587f, + -0.580813958f, -0.814036330f, + -0.578313796f, -0.815814411f, + -0.575808191f, -0.817584813f, + -0.573297167f, -0.819347520f, + -0.570780746f, -0.821102515f, + -0.568258953f, -0.822849781f, + -0.565731811f, -0.824589303f, + -0.563199344f, -0.826321063f, + -0.560661576f, -0.828045045f, + -0.558118531f, -0.829761234f, + -0.555570233f, -0.831469612f, + -0.553016706f, -0.833170165f, + -0.550457973f, -0.834862875f, + -0.547894059f, -0.836547727f, + -0.545324988f, -0.838224706f, + -0.542750785f, -0.839893794f, + -0.540171473f, -0.841554977f, + -0.537587076f, -0.843208240f, + -0.534997620f, -0.844853565f, + -0.532403128f, -0.846490939f, + -0.529803625f, -0.848120345f, + -0.527199135f, -0.849741768f, + -0.524589683f, -0.851355193f, + -0.521975293f, -0.852960605f, + -0.519355990f, -0.854557988f, + -0.516731799f, -0.856147328f, + -0.514102744f, -0.857728610f, + -0.511468850f, -0.859301818f, + -0.508830143f, -0.860866939f, + -0.506186645f, -0.862423956f, + -0.503538384f, -0.863972856f, + -0.500885383f, -0.865513624f, + -0.498227667f, -0.867046246f, + -0.495565262f, -0.868570706f, + -0.492898192f, -0.870086991f, + -0.490226483f, -0.871595087f, + -0.487550160f, -0.873094978f, + -0.484869248f, -0.874586652f, + -0.482183772f, -0.876070094f, + -0.479493758f, -0.877545290f, + -0.476799230f, -0.879012226f, + -0.474100215f, -0.880470889f, + -0.471396737f, -0.881921264f, + -0.468688822f, -0.883363339f, + -0.465976496f, -0.884797098f, + -0.463259784f, -0.886222530f, + -0.460538711f, -0.887639620f, + -0.457813304f, -0.889048356f, + -0.455083587f, -0.890448723f, + -0.452349587f, -0.891840709f, + -0.449611330f, -0.893224301f, + -0.446868840f, -0.894599486f, + -0.444122145f, -0.895966250f, + -0.441371269f, -0.897324581f, + -0.438616239f, -0.898674466f, + -0.435857080f, -0.900015892f, + -0.433093819f, -0.901348847f, + -0.430326481f, -0.902673318f, + -0.427555093f, -0.903989293f, + -0.424779681f, -0.905296759f, + -0.422000271f, -0.906595705f, + -0.419216888f, -0.907886116f, + -0.416429560f, -0.909167983f, + -0.413638312f, -0.910441292f, + -0.410843171f, -0.911706032f, + -0.408044163f, -0.912962190f, + -0.405241314f, -0.914209756f, + -0.402434651f, -0.915448716f, + -0.399624200f, -0.916679060f, + -0.396809987f, -0.917900776f, + -0.393992040f, -0.919113852f, + -0.391170384f, -0.920318277f, + -0.388345047f, -0.921514039f, + -0.385516054f, -0.922701128f, + -0.382683432f, -0.923879533f, + -0.379847209f, -0.925049241f, + -0.377007410f, -0.926210242f, + -0.374164063f, -0.927362526f, + -0.371317194f, -0.928506080f, + -0.368466830f, -0.929640896f, + -0.365612998f, -0.930766961f, + -0.362755724f, -0.931884266f, + -0.359895037f, -0.932992799f, + -0.357030961f, -0.934092550f, + -0.354163525f, -0.935183510f, + -0.351292756f, -0.936265667f, + -0.348418680f, -0.937339012f, + -0.345541325f, -0.938403534f, + -0.342660717f, -0.939459224f, + -0.339776884f, -0.940506071f, + -0.336889853f, -0.941544065f, + -0.333999651f, -0.942573198f, + -0.331106306f, -0.943593458f, + -0.328209844f, -0.944604837f, + -0.325310292f, -0.945607325f, + -0.322407679f, -0.946600913f, + -0.319502031f, -0.947585591f, + -0.316593376f, -0.948561350f, + -0.313681740f, -0.949528181f, + -0.310767153f, -0.950486074f, + -0.307849640f, -0.951435021f, + -0.304929230f, -0.952375013f, + -0.302005949f, -0.953306040f, + -0.299079826f, -0.954228095f, + -0.296150888f, -0.955141168f, + -0.293219163f, -0.956045251f, + -0.290284677f, -0.956940336f, + -0.287347460f, -0.957826413f, + -0.284407537f, -0.958703475f, + -0.281464938f, -0.959571513f, + -0.278519689f, -0.960430519f, + -0.275571819f, -0.961280486f, + -0.272621355f, -0.962121404f, + -0.269668326f, -0.962953267f, + -0.266712757f, -0.963776066f, + -0.263754679f, -0.964589793f, + -0.260794118f, -0.965394442f, + -0.257831102f, -0.966190003f, + -0.254865660f, -0.966976471f, + -0.251897818f, -0.967753837f, + -0.248927606f, -0.968522094f, + -0.245955050f, -0.969281235f, + -0.242980180f, -0.970031253f, + -0.240003022f, -0.970772141f, + -0.237023606f, -0.971503891f, + -0.234041959f, -0.972226497f, + -0.231058108f, -0.972939952f, + -0.228072083f, -0.973644250f, + -0.225083911f, -0.974339383f, + -0.222093621f, -0.975025345f, + -0.219101240f, -0.975702130f, + -0.216106797f, -0.976369731f, + -0.213110320f, -0.977028143f, + -0.210111837f, -0.977677358f, + -0.207111376f, -0.978317371f, + -0.204108966f, -0.978948175f, + -0.201104635f, -0.979569766f, + -0.198098411f, -0.980182136f, + -0.195090322f, -0.980785280f, + -0.192080397f, -0.981379193f, + -0.189068664f, -0.981963869f, + -0.186055152f, -0.982539302f, + -0.183039888f, -0.983105487f, + -0.180022901f, -0.983662419f, + -0.177004220f, -0.984210092f, + -0.173983873f, -0.984748502f, + -0.170961889f, -0.985277642f, + -0.167938295f, -0.985797509f, + -0.164913120f, -0.986308097f, + -0.161886394f, -0.986809402f, + -0.158858143f, -0.987301418f, + -0.155828398f, -0.987784142f, + -0.152797185f, -0.988257568f, + -0.149764535f, -0.988721692f, + -0.146730474f, -0.989176510f, + -0.143695033f, -0.989622017f, + -0.140658239f, -0.990058210f, + -0.137620122f, -0.990485084f, + -0.134580709f, -0.990902635f, + -0.131540029f, -0.991310860f, + -0.128498111f, -0.991709754f, + -0.125454983f, -0.992099313f, + -0.122410675f, -0.992479535f, + -0.119365215f, -0.992850414f, + -0.116318631f, -0.993211949f, + -0.113270952f, -0.993564136f, + -0.110222207f, -0.993906970f, + -0.107172425f, -0.994240449f, + -0.104121634f, -0.994564571f, + -0.101069863f, -0.994879331f, + -0.098017140f, -0.995184727f, + -0.094963495f, -0.995480755f, + -0.091908956f, -0.995767414f, + -0.088853553f, -0.996044701f, + -0.085797312f, -0.996312612f, + -0.082740265f, -0.996571146f, + -0.079682438f, -0.996820299f, + -0.076623861f, -0.997060070f, + -0.073564564f, -0.997290457f, + -0.070504573f, -0.997511456f, + -0.067443920f, -0.997723067f, + -0.064382631f, -0.997925286f, + -0.061320736f, -0.998118113f, + -0.058258265f, -0.998301545f, + -0.055195244f, -0.998475581f, + -0.052131705f, -0.998640218f, + -0.049067674f, -0.998795456f, + -0.046003182f, -0.998941293f, + -0.042938257f, -0.999077728f, + -0.039872928f, -0.999204759f, + -0.036807223f, -0.999322385f, + -0.033741172f, -0.999430605f, + -0.030674803f, -0.999529418f, + -0.027608146f, -0.999618822f, + -0.024541229f, -0.999698819f, + -0.021474080f, -0.999769405f, + -0.018406730f, -0.999830582f, + -0.015339206f, -0.999882347f, + -0.012271538f, -0.999924702f, + -0.009203755f, -0.999957645f, + -0.006135885f, -0.999981175f, + -0.003067957f, -0.999995294f, + -0.000000000f, -1.000000000f, + 0.003067957f, -0.999995294f, + 0.006135885f, -0.999981175f, + 0.009203755f, -0.999957645f, + 0.012271538f, -0.999924702f, + 0.015339206f, -0.999882347f, + 0.018406730f, -0.999830582f, + 0.021474080f, -0.999769405f, + 0.024541229f, -0.999698819f, + 0.027608146f, -0.999618822f, + 0.030674803f, -0.999529418f, + 0.033741172f, -0.999430605f, + 0.036807223f, -0.999322385f, + 0.039872928f, -0.999204759f, + 0.042938257f, -0.999077728f, + 0.046003182f, -0.998941293f, + 0.049067674f, -0.998795456f, + 0.052131705f, -0.998640218f, + 0.055195244f, -0.998475581f, + 0.058258265f, -0.998301545f, + 0.061320736f, -0.998118113f, + 0.064382631f, -0.997925286f, + 0.067443920f, -0.997723067f, + 0.070504573f, -0.997511456f, + 0.073564564f, -0.997290457f, + 0.076623861f, -0.997060070f, + 0.079682438f, -0.996820299f, + 0.082740265f, -0.996571146f, + 0.085797312f, -0.996312612f, + 0.088853553f, -0.996044701f, + 0.091908956f, -0.995767414f, + 0.094963495f, -0.995480755f, + 0.098017140f, -0.995184727f, + 0.101069863f, -0.994879331f, + 0.104121634f, -0.994564571f, + 0.107172425f, -0.994240449f, + 0.110222207f, -0.993906970f, + 0.113270952f, -0.993564136f, + 0.116318631f, -0.993211949f, + 0.119365215f, -0.992850414f, + 0.122410675f, -0.992479535f, + 0.125454983f, -0.992099313f, + 0.128498111f, -0.991709754f, + 0.131540029f, -0.991310860f, + 0.134580709f, -0.990902635f, + 0.137620122f, -0.990485084f, + 0.140658239f, -0.990058210f, + 0.143695033f, -0.989622017f, + 0.146730474f, -0.989176510f, + 0.149764535f, -0.988721692f, + 0.152797185f, -0.988257568f, + 0.155828398f, -0.987784142f, + 0.158858143f, -0.987301418f, + 0.161886394f, -0.986809402f, + 0.164913120f, -0.986308097f, + 0.167938295f, -0.985797509f, + 0.170961889f, -0.985277642f, + 0.173983873f, -0.984748502f, + 0.177004220f, -0.984210092f, + 0.180022901f, -0.983662419f, + 0.183039888f, -0.983105487f, + 0.186055152f, -0.982539302f, + 0.189068664f, -0.981963869f, + 0.192080397f, -0.981379193f, + 0.195090322f, -0.980785280f, + 0.198098411f, -0.980182136f, + 0.201104635f, -0.979569766f, + 0.204108966f, -0.978948175f, + 0.207111376f, -0.978317371f, + 0.210111837f, -0.977677358f, + 0.213110320f, -0.977028143f, + 0.216106797f, -0.976369731f, + 0.219101240f, -0.975702130f, + 0.222093621f, -0.975025345f, + 0.225083911f, -0.974339383f, + 0.228072083f, -0.973644250f, + 0.231058108f, -0.972939952f, + 0.234041959f, -0.972226497f, + 0.237023606f, -0.971503891f, + 0.240003022f, -0.970772141f, + 0.242980180f, -0.970031253f, + 0.245955050f, -0.969281235f, + 0.248927606f, -0.968522094f, + 0.251897818f, -0.967753837f, + 0.254865660f, -0.966976471f, + 0.257831102f, -0.966190003f, + 0.260794118f, -0.965394442f, + 0.263754679f, -0.964589793f, + 0.266712757f, -0.963776066f, + 0.269668326f, -0.962953267f, + 0.272621355f, -0.962121404f, + 0.275571819f, -0.961280486f, + 0.278519689f, -0.960430519f, + 0.281464938f, -0.959571513f, + 0.284407537f, -0.958703475f, + 0.287347460f, -0.957826413f, + 0.290284677f, -0.956940336f, + 0.293219163f, -0.956045251f, + 0.296150888f, -0.955141168f, + 0.299079826f, -0.954228095f, + 0.302005949f, -0.953306040f, + 0.304929230f, -0.952375013f, + 0.307849640f, -0.951435021f, + 0.310767153f, -0.950486074f, + 0.313681740f, -0.949528181f, + 0.316593376f, -0.948561350f, + 0.319502031f, -0.947585591f, + 0.322407679f, -0.946600913f, + 0.325310292f, -0.945607325f, + 0.328209844f, -0.944604837f, + 0.331106306f, -0.943593458f, + 0.333999651f, -0.942573198f, + 0.336889853f, -0.941544065f, + 0.339776884f, -0.940506071f, + 0.342660717f, -0.939459224f, + 0.345541325f, -0.938403534f, + 0.348418680f, -0.937339012f, + 0.351292756f, -0.936265667f, + 0.354163525f, -0.935183510f, + 0.357030961f, -0.934092550f, + 0.359895037f, -0.932992799f, + 0.362755724f, -0.931884266f, + 0.365612998f, -0.930766961f, + 0.368466830f, -0.929640896f, + 0.371317194f, -0.928506080f, + 0.374164063f, -0.927362526f, + 0.377007410f, -0.926210242f, + 0.379847209f, -0.925049241f, + 0.382683432f, -0.923879533f, + 0.385516054f, -0.922701128f, + 0.388345047f, -0.921514039f, + 0.391170384f, -0.920318277f, + 0.393992040f, -0.919113852f, + 0.396809987f, -0.917900776f, + 0.399624200f, -0.916679060f, + 0.402434651f, -0.915448716f, + 0.405241314f, -0.914209756f, + 0.408044163f, -0.912962190f, + 0.410843171f, -0.911706032f, + 0.413638312f, -0.910441292f, + 0.416429560f, -0.909167983f, + 0.419216888f, -0.907886116f, + 0.422000271f, -0.906595705f, + 0.424779681f, -0.905296759f, + 0.427555093f, -0.903989293f, + 0.430326481f, -0.902673318f, + 0.433093819f, -0.901348847f, + 0.435857080f, -0.900015892f, + 0.438616239f, -0.898674466f, + 0.441371269f, -0.897324581f, + 0.444122145f, -0.895966250f, + 0.446868840f, -0.894599486f, + 0.449611330f, -0.893224301f, + 0.452349587f, -0.891840709f, + 0.455083587f, -0.890448723f, + 0.457813304f, -0.889048356f, + 0.460538711f, -0.887639620f, + 0.463259784f, -0.886222530f, + 0.465976496f, -0.884797098f, + 0.468688822f, -0.883363339f, + 0.471396737f, -0.881921264f, + 0.474100215f, -0.880470889f, + 0.476799230f, -0.879012226f, + 0.479493758f, -0.877545290f, + 0.482183772f, -0.876070094f, + 0.484869248f, -0.874586652f, + 0.487550160f, -0.873094978f, + 0.490226483f, -0.871595087f, + 0.492898192f, -0.870086991f, + 0.495565262f, -0.868570706f, + 0.498227667f, -0.867046246f, + 0.500885383f, -0.865513624f, + 0.503538384f, -0.863972856f, + 0.506186645f, -0.862423956f, + 0.508830143f, -0.860866939f, + 0.511468850f, -0.859301818f, + 0.514102744f, -0.857728610f, + 0.516731799f, -0.856147328f, + 0.519355990f, -0.854557988f, + 0.521975293f, -0.852960605f, + 0.524589683f, -0.851355193f, + 0.527199135f, -0.849741768f, + 0.529803625f, -0.848120345f, + 0.532403128f, -0.846490939f, + 0.534997620f, -0.844853565f, + 0.537587076f, -0.843208240f, + 0.540171473f, -0.841554977f, + 0.542750785f, -0.839893794f, + 0.545324988f, -0.838224706f, + 0.547894059f, -0.836547727f, + 0.550457973f, -0.834862875f, + 0.553016706f, -0.833170165f, + 0.555570233f, -0.831469612f, + 0.558118531f, -0.829761234f, + 0.560661576f, -0.828045045f, + 0.563199344f, -0.826321063f, + 0.565731811f, -0.824589303f, + 0.568258953f, -0.822849781f, + 0.570780746f, -0.821102515f, + 0.573297167f, -0.819347520f, + 0.575808191f, -0.817584813f, + 0.578313796f, -0.815814411f, + 0.580813958f, -0.814036330f, + 0.583308653f, -0.812250587f, + 0.585797857f, -0.810457198f, + 0.588281548f, -0.808656182f, + 0.590759702f, -0.806847554f, + 0.593232295f, -0.805031331f, + 0.595699304f, -0.803207531f, + 0.598160707f, -0.801376172f, + 0.600616479f, -0.799537269f, + 0.603066599f, -0.797690841f, + 0.605511041f, -0.795836905f, + 0.607949785f, -0.793975478f, + 0.610382806f, -0.792106577f, + 0.612810082f, -0.790230221f, + 0.615231591f, -0.788346428f, + 0.617647308f, -0.786455214f, + 0.620057212f, -0.784556597f, + 0.622461279f, -0.782650596f, + 0.624859488f, -0.780737229f, + 0.627251815f, -0.778816512f, + 0.629638239f, -0.776888466f, + 0.632018736f, -0.774953107f, + 0.634393284f, -0.773010453f, + 0.636761861f, -0.771060524f, + 0.639124445f, -0.769103338f, + 0.641481013f, -0.767138912f, + 0.643831543f, -0.765167266f, + 0.646176013f, -0.763188417f, + 0.648514401f, -0.761202385f, + 0.650846685f, -0.759209189f, + 0.653172843f, -0.757208847f, + 0.655492853f, -0.755201377f, + 0.657806693f, -0.753186799f, + 0.660114342f, -0.751165132f, + 0.662415778f, -0.749136395f, + 0.664710978f, -0.747100606f, + 0.666999922f, -0.745057785f, + 0.669282588f, -0.743007952f, + 0.671558955f, -0.740951125f, + 0.673829000f, -0.738887324f, + 0.676092704f, -0.736816569f, + 0.678350043f, -0.734738878f, + 0.680600998f, -0.732654272f, + 0.682845546f, -0.730562769f, + 0.685083668f, -0.728464390f, + 0.687315341f, -0.726359155f, + 0.689540545f, -0.724247083f, + 0.691759258f, -0.722128194f, + 0.693971461f, -0.720002508f, + 0.696177131f, -0.717870045f, + 0.698376249f, -0.715730825f, + 0.700568794f, -0.713584869f, + 0.702754744f, -0.711432196f, + 0.704934080f, -0.709272826f, + 0.707106781f, -0.707106781f, + 0.709272826f, -0.704934080f, + 0.711432196f, -0.702754744f, + 0.713584869f, -0.700568794f, + 0.715730825f, -0.698376249f, + 0.717870045f, -0.696177131f, + 0.720002508f, -0.693971461f, + 0.722128194f, -0.691759258f, + 0.724247083f, -0.689540545f, + 0.726359155f, -0.687315341f, + 0.728464390f, -0.685083668f, + 0.730562769f, -0.682845546f, + 0.732654272f, -0.680600998f, + 0.734738878f, -0.678350043f, + 0.736816569f, -0.676092704f, + 0.738887324f, -0.673829000f, + 0.740951125f, -0.671558955f, + 0.743007952f, -0.669282588f, + 0.745057785f, -0.666999922f, + 0.747100606f, -0.664710978f, + 0.749136395f, -0.662415778f, + 0.751165132f, -0.660114342f, + 0.753186799f, -0.657806693f, + 0.755201377f, -0.655492853f, + 0.757208847f, -0.653172843f, + 0.759209189f, -0.650846685f, + 0.761202385f, -0.648514401f, + 0.763188417f, -0.646176013f, + 0.765167266f, -0.643831543f, + 0.767138912f, -0.641481013f, + 0.769103338f, -0.639124445f, + 0.771060524f, -0.636761861f, + 0.773010453f, -0.634393284f, + 0.774953107f, -0.632018736f, + 0.776888466f, -0.629638239f, + 0.778816512f, -0.627251815f, + 0.780737229f, -0.624859488f, + 0.782650596f, -0.622461279f, + 0.784556597f, -0.620057212f, + 0.786455214f, -0.617647308f, + 0.788346428f, -0.615231591f, + 0.790230221f, -0.612810082f, + 0.792106577f, -0.610382806f, + 0.793975478f, -0.607949785f, + 0.795836905f, -0.605511041f, + 0.797690841f, -0.603066599f, + 0.799537269f, -0.600616479f, + 0.801376172f, -0.598160707f, + 0.803207531f, -0.595699304f, + 0.805031331f, -0.593232295f, + 0.806847554f, -0.590759702f, + 0.808656182f, -0.588281548f, + 0.810457198f, -0.585797857f, + 0.812250587f, -0.583308653f, + 0.814036330f, -0.580813958f, + 0.815814411f, -0.578313796f, + 0.817584813f, -0.575808191f, + 0.819347520f, -0.573297167f, + 0.821102515f, -0.570780746f, + 0.822849781f, -0.568258953f, + 0.824589303f, -0.565731811f, + 0.826321063f, -0.563199344f, + 0.828045045f, -0.560661576f, + 0.829761234f, -0.558118531f, + 0.831469612f, -0.555570233f, + 0.833170165f, -0.553016706f, + 0.834862875f, -0.550457973f, + 0.836547727f, -0.547894059f, + 0.838224706f, -0.545324988f, + 0.839893794f, -0.542750785f, + 0.841554977f, -0.540171473f, + 0.843208240f, -0.537587076f, + 0.844853565f, -0.534997620f, + 0.846490939f, -0.532403128f, + 0.848120345f, -0.529803625f, + 0.849741768f, -0.527199135f, + 0.851355193f, -0.524589683f, + 0.852960605f, -0.521975293f, + 0.854557988f, -0.519355990f, + 0.856147328f, -0.516731799f, + 0.857728610f, -0.514102744f, + 0.859301818f, -0.511468850f, + 0.860866939f, -0.508830143f, + 0.862423956f, -0.506186645f, + 0.863972856f, -0.503538384f, + 0.865513624f, -0.500885383f, + 0.867046246f, -0.498227667f, + 0.868570706f, -0.495565262f, + 0.870086991f, -0.492898192f, + 0.871595087f, -0.490226483f, + 0.873094978f, -0.487550160f, + 0.874586652f, -0.484869248f, + 0.876070094f, -0.482183772f, + 0.877545290f, -0.479493758f, + 0.879012226f, -0.476799230f, + 0.880470889f, -0.474100215f, + 0.881921264f, -0.471396737f, + 0.883363339f, -0.468688822f, + 0.884797098f, -0.465976496f, + 0.886222530f, -0.463259784f, + 0.887639620f, -0.460538711f, + 0.889048356f, -0.457813304f, + 0.890448723f, -0.455083587f, + 0.891840709f, -0.452349587f, + 0.893224301f, -0.449611330f, + 0.894599486f, -0.446868840f, + 0.895966250f, -0.444122145f, + 0.897324581f, -0.441371269f, + 0.898674466f, -0.438616239f, + 0.900015892f, -0.435857080f, + 0.901348847f, -0.433093819f, + 0.902673318f, -0.430326481f, + 0.903989293f, -0.427555093f, + 0.905296759f, -0.424779681f, + 0.906595705f, -0.422000271f, + 0.907886116f, -0.419216888f, + 0.909167983f, -0.416429560f, + 0.910441292f, -0.413638312f, + 0.911706032f, -0.410843171f, + 0.912962190f, -0.408044163f, + 0.914209756f, -0.405241314f, + 0.915448716f, -0.402434651f, + 0.916679060f, -0.399624200f, + 0.917900776f, -0.396809987f, + 0.919113852f, -0.393992040f, + 0.920318277f, -0.391170384f, + 0.921514039f, -0.388345047f, + 0.922701128f, -0.385516054f, + 0.923879533f, -0.382683432f, + 0.925049241f, -0.379847209f, + 0.926210242f, -0.377007410f, + 0.927362526f, -0.374164063f, + 0.928506080f, -0.371317194f, + 0.929640896f, -0.368466830f, + 0.930766961f, -0.365612998f, + 0.931884266f, -0.362755724f, + 0.932992799f, -0.359895037f, + 0.934092550f, -0.357030961f, + 0.935183510f, -0.354163525f, + 0.936265667f, -0.351292756f, + 0.937339012f, -0.348418680f, + 0.938403534f, -0.345541325f, + 0.939459224f, -0.342660717f, + 0.940506071f, -0.339776884f, + 0.941544065f, -0.336889853f, + 0.942573198f, -0.333999651f, + 0.943593458f, -0.331106306f, + 0.944604837f, -0.328209844f, + 0.945607325f, -0.325310292f, + 0.946600913f, -0.322407679f, + 0.947585591f, -0.319502031f, + 0.948561350f, -0.316593376f, + 0.949528181f, -0.313681740f, + 0.950486074f, -0.310767153f, + 0.951435021f, -0.307849640f, + 0.952375013f, -0.304929230f, + 0.953306040f, -0.302005949f, + 0.954228095f, -0.299079826f, + 0.955141168f, -0.296150888f, + 0.956045251f, -0.293219163f, + 0.956940336f, -0.290284677f, + 0.957826413f, -0.287347460f, + 0.958703475f, -0.284407537f, + 0.959571513f, -0.281464938f, + 0.960430519f, -0.278519689f, + 0.961280486f, -0.275571819f, + 0.962121404f, -0.272621355f, + 0.962953267f, -0.269668326f, + 0.963776066f, -0.266712757f, + 0.964589793f, -0.263754679f, + 0.965394442f, -0.260794118f, + 0.966190003f, -0.257831102f, + 0.966976471f, -0.254865660f, + 0.967753837f, -0.251897818f, + 0.968522094f, -0.248927606f, + 0.969281235f, -0.245955050f, + 0.970031253f, -0.242980180f, + 0.970772141f, -0.240003022f, + 0.971503891f, -0.237023606f, + 0.972226497f, -0.234041959f, + 0.972939952f, -0.231058108f, + 0.973644250f, -0.228072083f, + 0.974339383f, -0.225083911f, + 0.975025345f, -0.222093621f, + 0.975702130f, -0.219101240f, + 0.976369731f, -0.216106797f, + 0.977028143f, -0.213110320f, + 0.977677358f, -0.210111837f, + 0.978317371f, -0.207111376f, + 0.978948175f, -0.204108966f, + 0.979569766f, -0.201104635f, + 0.980182136f, -0.198098411f, + 0.980785280f, -0.195090322f, + 0.981379193f, -0.192080397f, + 0.981963869f, -0.189068664f, + 0.982539302f, -0.186055152f, + 0.983105487f, -0.183039888f, + 0.983662419f, -0.180022901f, + 0.984210092f, -0.177004220f, + 0.984748502f, -0.173983873f, + 0.985277642f, -0.170961889f, + 0.985797509f, -0.167938295f, + 0.986308097f, -0.164913120f, + 0.986809402f, -0.161886394f, + 0.987301418f, -0.158858143f, + 0.987784142f, -0.155828398f, + 0.988257568f, -0.152797185f, + 0.988721692f, -0.149764535f, + 0.989176510f, -0.146730474f, + 0.989622017f, -0.143695033f, + 0.990058210f, -0.140658239f, + 0.990485084f, -0.137620122f, + 0.990902635f, -0.134580709f, + 0.991310860f, -0.131540029f, + 0.991709754f, -0.128498111f, + 0.992099313f, -0.125454983f, + 0.992479535f, -0.122410675f, + 0.992850414f, -0.119365215f, + 0.993211949f, -0.116318631f, + 0.993564136f, -0.113270952f, + 0.993906970f, -0.110222207f, + 0.994240449f, -0.107172425f, + 0.994564571f, -0.104121634f, + 0.994879331f, -0.101069863f, + 0.995184727f, -0.098017140f, + 0.995480755f, -0.094963495f, + 0.995767414f, -0.091908956f, + 0.996044701f, -0.088853553f, + 0.996312612f, -0.085797312f, + 0.996571146f, -0.082740265f, + 0.996820299f, -0.079682438f, + 0.997060070f, -0.076623861f, + 0.997290457f, -0.073564564f, + 0.997511456f, -0.070504573f, + 0.997723067f, -0.067443920f, + 0.997925286f, -0.064382631f, + 0.998118113f, -0.061320736f, + 0.998301545f, -0.058258265f, + 0.998475581f, -0.055195244f, + 0.998640218f, -0.052131705f, + 0.998795456f, -0.049067674f, + 0.998941293f, -0.046003182f, + 0.999077728f, -0.042938257f, + 0.999204759f, -0.039872928f, + 0.999322385f, -0.036807223f, + 0.999430605f, -0.033741172f, + 0.999529418f, -0.030674803f, + 0.999618822f, -0.027608146f, + 0.999698819f, -0.024541229f, + 0.999769405f, -0.021474080f, + 0.999830582f, -0.018406730f, + 0.999882347f, -0.015339206f, + 0.999924702f, -0.012271538f, + 0.999957645f, -0.009203755f, + 0.999981175f, -0.006135885f, + 0.999995294f, -0.003067957f +}; + +/** + @par + Example code for Floating-point Twiddle factors Generation: + @par +
for (i = 0; i< N/; i++)
+  {
+ 	twiddleCoef[2*i]   = cos(i * 2*PI/(float)N);
+ 	twiddleCoef[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 4096, PI = 3.14159265358979 + @par + Cos and Sin values are in interleaved fashion +*/ +const float32_t twiddleCoef_4096[8192] = { + 1.000000000f, 0.000000000f, + 0.999998823f, 0.001533980f, + 0.999995294f, 0.003067957f, + 0.999989411f, 0.004601926f, + 0.999981175f, 0.006135885f, + 0.999970586f, 0.007669829f, + 0.999957645f, 0.009203755f, + 0.999942350f, 0.010737659f, + 0.999924702f, 0.012271538f, + 0.999904701f, 0.013805389f, + 0.999882347f, 0.015339206f, + 0.999857641f, 0.016872988f, + 0.999830582f, 0.018406730f, + 0.999801170f, 0.019940429f, + 0.999769405f, 0.021474080f, + 0.999735288f, 0.023007681f, + 0.999698819f, 0.024541229f, + 0.999659997f, 0.026074718f, + 0.999618822f, 0.027608146f, + 0.999575296f, 0.029141509f, + 0.999529418f, 0.030674803f, + 0.999481187f, 0.032208025f, + 0.999430605f, 0.033741172f, + 0.999377670f, 0.035274239f, + 0.999322385f, 0.036807223f, + 0.999264747f, 0.038340120f, + 0.999204759f, 0.039872928f, + 0.999142419f, 0.041405641f, + 0.999077728f, 0.042938257f, + 0.999010686f, 0.044470772f, + 0.998941293f, 0.046003182f, + 0.998869550f, 0.047535484f, + 0.998795456f, 0.049067674f, + 0.998719012f, 0.050599749f, + 0.998640218f, 0.052131705f, + 0.998559074f, 0.053663538f, + 0.998475581f, 0.055195244f, + 0.998389737f, 0.056726821f, + 0.998301545f, 0.058258265f, + 0.998211003f, 0.059789571f, + 0.998118113f, 0.061320736f, + 0.998022874f, 0.062851758f, + 0.997925286f, 0.064382631f, + 0.997825350f, 0.065913353f, + 0.997723067f, 0.067443920f, + 0.997618435f, 0.068974328f, + 0.997511456f, 0.070504573f, + 0.997402130f, 0.072034653f, + 0.997290457f, 0.073564564f, + 0.997176437f, 0.075094301f, + 0.997060070f, 0.076623861f, + 0.996941358f, 0.078153242f, + 0.996820299f, 0.079682438f, + 0.996696895f, 0.081211447f, + 0.996571146f, 0.082740265f, + 0.996443051f, 0.084268888f, + 0.996312612f, 0.085797312f, + 0.996179829f, 0.087325535f, + 0.996044701f, 0.088853553f, + 0.995907229f, 0.090381361f, + 0.995767414f, 0.091908956f, + 0.995625256f, 0.093436336f, + 0.995480755f, 0.094963495f, + 0.995333912f, 0.096490431f, + 0.995184727f, 0.098017140f, + 0.995033199f, 0.099543619f, + 0.994879331f, 0.101069863f, + 0.994723121f, 0.102595869f, + 0.994564571f, 0.104121634f, + 0.994403680f, 0.105647154f, + 0.994240449f, 0.107172425f, + 0.994074879f, 0.108697444f, + 0.993906970f, 0.110222207f, + 0.993736722f, 0.111746711f, + 0.993564136f, 0.113270952f, + 0.993389211f, 0.114794927f, + 0.993211949f, 0.116318631f, + 0.993032350f, 0.117842062f, + 0.992850414f, 0.119365215f, + 0.992666142f, 0.120888087f, + 0.992479535f, 0.122410675f, + 0.992290591f, 0.123932975f, + 0.992099313f, 0.125454983f, + 0.991905700f, 0.126976696f, + 0.991709754f, 0.128498111f, + 0.991511473f, 0.130019223f, + 0.991310860f, 0.131540029f, + 0.991107914f, 0.133060525f, + 0.990902635f, 0.134580709f, + 0.990695025f, 0.136100575f, + 0.990485084f, 0.137620122f, + 0.990272812f, 0.139139344f, + 0.990058210f, 0.140658239f, + 0.989841278f, 0.142176804f, + 0.989622017f, 0.143695033f, + 0.989400428f, 0.145212925f, + 0.989176510f, 0.146730474f, + 0.988950265f, 0.148247679f, + 0.988721692f, 0.149764535f, + 0.988490793f, 0.151281038f, + 0.988257568f, 0.152797185f, + 0.988022017f, 0.154312973f, + 0.987784142f, 0.155828398f, + 0.987543942f, 0.157343456f, + 0.987301418f, 0.158858143f, + 0.987056571f, 0.160372457f, + 0.986809402f, 0.161886394f, + 0.986559910f, 0.163399949f, + 0.986308097f, 0.164913120f, + 0.986053963f, 0.166425904f, + 0.985797509f, 0.167938295f, + 0.985538735f, 0.169450291f, + 0.985277642f, 0.170961889f, + 0.985014231f, 0.172473084f, + 0.984748502f, 0.173983873f, + 0.984480455f, 0.175494253f, + 0.984210092f, 0.177004220f, + 0.983937413f, 0.178513771f, + 0.983662419f, 0.180022901f, + 0.983385110f, 0.181531608f, + 0.983105487f, 0.183039888f, + 0.982823551f, 0.184547737f, + 0.982539302f, 0.186055152f, + 0.982252741f, 0.187562129f, + 0.981963869f, 0.189068664f, + 0.981672686f, 0.190574755f, + 0.981379193f, 0.192080397f, + 0.981083391f, 0.193585587f, + 0.980785280f, 0.195090322f, + 0.980484862f, 0.196594598f, + 0.980182136f, 0.198098411f, + 0.979877104f, 0.199601758f, + 0.979569766f, 0.201104635f, + 0.979260123f, 0.202607039f, + 0.978948175f, 0.204108966f, + 0.978633924f, 0.205610413f, + 0.978317371f, 0.207111376f, + 0.977998515f, 0.208611852f, + 0.977677358f, 0.210111837f, + 0.977353900f, 0.211611327f, + 0.977028143f, 0.213110320f, + 0.976700086f, 0.214608811f, + 0.976369731f, 0.216106797f, + 0.976037079f, 0.217604275f, + 0.975702130f, 0.219101240f, + 0.975364885f, 0.220597690f, + 0.975025345f, 0.222093621f, + 0.974683511f, 0.223589029f, + 0.974339383f, 0.225083911f, + 0.973992962f, 0.226578264f, + 0.973644250f, 0.228072083f, + 0.973293246f, 0.229565366f, + 0.972939952f, 0.231058108f, + 0.972584369f, 0.232550307f, + 0.972226497f, 0.234041959f, + 0.971866337f, 0.235533059f, + 0.971503891f, 0.237023606f, + 0.971139158f, 0.238513595f, + 0.970772141f, 0.240003022f, + 0.970402839f, 0.241491885f, + 0.970031253f, 0.242980180f, + 0.969657385f, 0.244467903f, + 0.969281235f, 0.245955050f, + 0.968902805f, 0.247441619f, + 0.968522094f, 0.248927606f, + 0.968139105f, 0.250413007f, + 0.967753837f, 0.251897818f, + 0.967366292f, 0.253382037f, + 0.966976471f, 0.254865660f, + 0.966584374f, 0.256348682f, + 0.966190003f, 0.257831102f, + 0.965793359f, 0.259312915f, + 0.965394442f, 0.260794118f, + 0.964993253f, 0.262274707f, + 0.964589793f, 0.263754679f, + 0.964184064f, 0.265234030f, + 0.963776066f, 0.266712757f, + 0.963365800f, 0.268190857f, + 0.962953267f, 0.269668326f, + 0.962538468f, 0.271145160f, + 0.962121404f, 0.272621355f, + 0.961702077f, 0.274096910f, + 0.961280486f, 0.275571819f, + 0.960856633f, 0.277046080f, + 0.960430519f, 0.278519689f, + 0.960002146f, 0.279992643f, + 0.959571513f, 0.281464938f, + 0.959138622f, 0.282936570f, + 0.958703475f, 0.284407537f, + 0.958266071f, 0.285877835f, + 0.957826413f, 0.287347460f, + 0.957384501f, 0.288816408f, + 0.956940336f, 0.290284677f, + 0.956493919f, 0.291752263f, + 0.956045251f, 0.293219163f, + 0.955594334f, 0.294685372f, + 0.955141168f, 0.296150888f, + 0.954685755f, 0.297615707f, + 0.954228095f, 0.299079826f, + 0.953768190f, 0.300543241f, + 0.953306040f, 0.302005949f, + 0.952841648f, 0.303467947f, + 0.952375013f, 0.304929230f, + 0.951906137f, 0.306389795f, + 0.951435021f, 0.307849640f, + 0.950961666f, 0.309308760f, + 0.950486074f, 0.310767153f, + 0.950008245f, 0.312224814f, + 0.949528181f, 0.313681740f, + 0.949045882f, 0.315137929f, + 0.948561350f, 0.316593376f, + 0.948074586f, 0.318048077f, + 0.947585591f, 0.319502031f, + 0.947094366f, 0.320955232f, + 0.946600913f, 0.322407679f, + 0.946105232f, 0.323859367f, + 0.945607325f, 0.325310292f, + 0.945107193f, 0.326760452f, + 0.944604837f, 0.328209844f, + 0.944100258f, 0.329658463f, + 0.943593458f, 0.331106306f, + 0.943084437f, 0.332553370f, + 0.942573198f, 0.333999651f, + 0.942059740f, 0.335445147f, + 0.941544065f, 0.336889853f, + 0.941026175f, 0.338333767f, + 0.940506071f, 0.339776884f, + 0.939983753f, 0.341219202f, + 0.939459224f, 0.342660717f, + 0.938932484f, 0.344101426f, + 0.938403534f, 0.345541325f, + 0.937872376f, 0.346980411f, + 0.937339012f, 0.348418680f, + 0.936803442f, 0.349856130f, + 0.936265667f, 0.351292756f, + 0.935725689f, 0.352728556f, + 0.935183510f, 0.354163525f, + 0.934639130f, 0.355597662f, + 0.934092550f, 0.357030961f, + 0.933543773f, 0.358463421f, + 0.932992799f, 0.359895037f, + 0.932439629f, 0.361325806f, + 0.931884266f, 0.362755724f, + 0.931326709f, 0.364184790f, + 0.930766961f, 0.365612998f, + 0.930205023f, 0.367040346f, + 0.929640896f, 0.368466830f, + 0.929074581f, 0.369892447f, + 0.928506080f, 0.371317194f, + 0.927935395f, 0.372741067f, + 0.927362526f, 0.374164063f, + 0.926787474f, 0.375586178f, + 0.926210242f, 0.377007410f, + 0.925630831f, 0.378427755f, + 0.925049241f, 0.379847209f, + 0.924465474f, 0.381265769f, + 0.923879533f, 0.382683432f, + 0.923291417f, 0.384100195f, + 0.922701128f, 0.385516054f, + 0.922108669f, 0.386931006f, + 0.921514039f, 0.388345047f, + 0.920917242f, 0.389758174f, + 0.920318277f, 0.391170384f, + 0.919717146f, 0.392581674f, + 0.919113852f, 0.393992040f, + 0.918508394f, 0.395401479f, + 0.917900776f, 0.396809987f, + 0.917290997f, 0.398217562f, + 0.916679060f, 0.399624200f, + 0.916064966f, 0.401029897f, + 0.915448716f, 0.402434651f, + 0.914830312f, 0.403838458f, + 0.914209756f, 0.405241314f, + 0.913587048f, 0.406643217f, + 0.912962190f, 0.408044163f, + 0.912335185f, 0.409444149f, + 0.911706032f, 0.410843171f, + 0.911074734f, 0.412241227f, + 0.910441292f, 0.413638312f, + 0.909805708f, 0.415034424f, + 0.909167983f, 0.416429560f, + 0.908528119f, 0.417823716f, + 0.907886116f, 0.419216888f, + 0.907241978f, 0.420609074f, + 0.906595705f, 0.422000271f, + 0.905947298f, 0.423390474f, + 0.905296759f, 0.424779681f, + 0.904644091f, 0.426167889f, + 0.903989293f, 0.427555093f, + 0.903332368f, 0.428941292f, + 0.902673318f, 0.430326481f, + 0.902012144f, 0.431710658f, + 0.901348847f, 0.433093819f, + 0.900683429f, 0.434475961f, + 0.900015892f, 0.435857080f, + 0.899346237f, 0.437237174f, + 0.898674466f, 0.438616239f, + 0.898000580f, 0.439994271f, + 0.897324581f, 0.441371269f, + 0.896646470f, 0.442747228f, + 0.895966250f, 0.444122145f, + 0.895283921f, 0.445496017f, + 0.894599486f, 0.446868840f, + 0.893912945f, 0.448240612f, + 0.893224301f, 0.449611330f, + 0.892533555f, 0.450980989f, + 0.891840709f, 0.452349587f, + 0.891145765f, 0.453717121f, + 0.890448723f, 0.455083587f, + 0.889749586f, 0.456448982f, + 0.889048356f, 0.457813304f, + 0.888345033f, 0.459176548f, + 0.887639620f, 0.460538711f, + 0.886932119f, 0.461899791f, + 0.886222530f, 0.463259784f, + 0.885510856f, 0.464618686f, + 0.884797098f, 0.465976496f, + 0.884081259f, 0.467333209f, + 0.883363339f, 0.468688822f, + 0.882643340f, 0.470043332f, + 0.881921264f, 0.471396737f, + 0.881197113f, 0.472749032f, + 0.880470889f, 0.474100215f, + 0.879742593f, 0.475450282f, + 0.879012226f, 0.476799230f, + 0.878279792f, 0.478147056f, + 0.877545290f, 0.479493758f, + 0.876808724f, 0.480839331f, + 0.876070094f, 0.482183772f, + 0.875329403f, 0.483527079f, + 0.874586652f, 0.484869248f, + 0.873841843f, 0.486210276f, + 0.873094978f, 0.487550160f, + 0.872346059f, 0.488888897f, + 0.871595087f, 0.490226483f, + 0.870842063f, 0.491562916f, + 0.870086991f, 0.492898192f, + 0.869329871f, 0.494232309f, + 0.868570706f, 0.495565262f, + 0.867809497f, 0.496897049f, + 0.867046246f, 0.498227667f, + 0.866280954f, 0.499557113f, + 0.865513624f, 0.500885383f, + 0.864744258f, 0.502212474f, + 0.863972856f, 0.503538384f, + 0.863199422f, 0.504863109f, + 0.862423956f, 0.506186645f, + 0.861646461f, 0.507508991f, + 0.860866939f, 0.508830143f, + 0.860085390f, 0.510150097f, + 0.859301818f, 0.511468850f, + 0.858516224f, 0.512786401f, + 0.857728610f, 0.514102744f, + 0.856938977f, 0.515417878f, + 0.856147328f, 0.516731799f, + 0.855353665f, 0.518044504f, + 0.854557988f, 0.519355990f, + 0.853760301f, 0.520666254f, + 0.852960605f, 0.521975293f, + 0.852158902f, 0.523283103f, + 0.851355193f, 0.524589683f, + 0.850549481f, 0.525895027f, + 0.849741768f, 0.527199135f, + 0.848932055f, 0.528502002f, + 0.848120345f, 0.529803625f, + 0.847306639f, 0.531104001f, + 0.846490939f, 0.532403128f, + 0.845673247f, 0.533701002f, + 0.844853565f, 0.534997620f, + 0.844031895f, 0.536292979f, + 0.843208240f, 0.537587076f, + 0.842382600f, 0.538879909f, + 0.841554977f, 0.540171473f, + 0.840725375f, 0.541461766f, + 0.839893794f, 0.542750785f, + 0.839060237f, 0.544038527f, + 0.838224706f, 0.545324988f, + 0.837387202f, 0.546610167f, + 0.836547727f, 0.547894059f, + 0.835706284f, 0.549176662f, + 0.834862875f, 0.550457973f, + 0.834017501f, 0.551737988f, + 0.833170165f, 0.553016706f, + 0.832320868f, 0.554294121f, + 0.831469612f, 0.555570233f, + 0.830616400f, 0.556845037f, + 0.829761234f, 0.558118531f, + 0.828904115f, 0.559390712f, + 0.828045045f, 0.560661576f, + 0.827184027f, 0.561931121f, + 0.826321063f, 0.563199344f, + 0.825456154f, 0.564466242f, + 0.824589303f, 0.565731811f, + 0.823720511f, 0.566996049f, + 0.822849781f, 0.568258953f, + 0.821977115f, 0.569520519f, + 0.821102515f, 0.570780746f, + 0.820225983f, 0.572039629f, + 0.819347520f, 0.573297167f, + 0.818467130f, 0.574553355f, + 0.817584813f, 0.575808191f, + 0.816700573f, 0.577061673f, + 0.815814411f, 0.578313796f, + 0.814926329f, 0.579564559f, + 0.814036330f, 0.580813958f, + 0.813144415f, 0.582061990f, + 0.812250587f, 0.583308653f, + 0.811354847f, 0.584553943f, + 0.810457198f, 0.585797857f, + 0.809557642f, 0.587040394f, + 0.808656182f, 0.588281548f, + 0.807752818f, 0.589521319f, + 0.806847554f, 0.590759702f, + 0.805940391f, 0.591996695f, + 0.805031331f, 0.593232295f, + 0.804120377f, 0.594466499f, + 0.803207531f, 0.595699304f, + 0.802292796f, 0.596930708f, + 0.801376172f, 0.598160707f, + 0.800457662f, 0.599389298f, + 0.799537269f, 0.600616479f, + 0.798614995f, 0.601842247f, + 0.797690841f, 0.603066599f, + 0.796764810f, 0.604289531f, + 0.795836905f, 0.605511041f, + 0.794907126f, 0.606731127f, + 0.793975478f, 0.607949785f, + 0.793041960f, 0.609167012f, + 0.792106577f, 0.610382806f, + 0.791169330f, 0.611597164f, + 0.790230221f, 0.612810082f, + 0.789289253f, 0.614021559f, + 0.788346428f, 0.615231591f, + 0.787401747f, 0.616440175f, + 0.786455214f, 0.617647308f, + 0.785506830f, 0.618852988f, + 0.784556597f, 0.620057212f, + 0.783604519f, 0.621259977f, + 0.782650596f, 0.622461279f, + 0.781694832f, 0.623661118f, + 0.780737229f, 0.624859488f, + 0.779777788f, 0.626056388f, + 0.778816512f, 0.627251815f, + 0.777853404f, 0.628445767f, + 0.776888466f, 0.629638239f, + 0.775921699f, 0.630829230f, + 0.774953107f, 0.632018736f, + 0.773982691f, 0.633206755f, + 0.773010453f, 0.634393284f, + 0.772036397f, 0.635578320f, + 0.771060524f, 0.636761861f, + 0.770082837f, 0.637943904f, + 0.769103338f, 0.639124445f, + 0.768122029f, 0.640303482f, + 0.767138912f, 0.641481013f, + 0.766153990f, 0.642657034f, + 0.765167266f, 0.643831543f, + 0.764178741f, 0.645004537f, + 0.763188417f, 0.646176013f, + 0.762196298f, 0.647345969f, + 0.761202385f, 0.648514401f, + 0.760206682f, 0.649681307f, + 0.759209189f, 0.650846685f, + 0.758209910f, 0.652010531f, + 0.757208847f, 0.653172843f, + 0.756206001f, 0.654333618f, + 0.755201377f, 0.655492853f, + 0.754194975f, 0.656650546f, + 0.753186799f, 0.657806693f, + 0.752176850f, 0.658961293f, + 0.751165132f, 0.660114342f, + 0.750151646f, 0.661265838f, + 0.749136395f, 0.662415778f, + 0.748119380f, 0.663564159f, + 0.747100606f, 0.664710978f, + 0.746080074f, 0.665856234f, + 0.745057785f, 0.666999922f, + 0.744033744f, 0.668142041f, + 0.743007952f, 0.669282588f, + 0.741980412f, 0.670421560f, + 0.740951125f, 0.671558955f, + 0.739920095f, 0.672694769f, + 0.738887324f, 0.673829000f, + 0.737852815f, 0.674961646f, + 0.736816569f, 0.676092704f, + 0.735778589f, 0.677222170f, + 0.734738878f, 0.678350043f, + 0.733697438f, 0.679476320f, + 0.732654272f, 0.680600998f, + 0.731609381f, 0.681724074f, + 0.730562769f, 0.682845546f, + 0.729514438f, 0.683965412f, + 0.728464390f, 0.685083668f, + 0.727412629f, 0.686200312f, + 0.726359155f, 0.687315341f, + 0.725303972f, 0.688428753f, + 0.724247083f, 0.689540545f, + 0.723188489f, 0.690650714f, + 0.722128194f, 0.691759258f, + 0.721066199f, 0.692866175f, + 0.720002508f, 0.693971461f, + 0.718937122f, 0.695075114f, + 0.717870045f, 0.696177131f, + 0.716801279f, 0.697277511f, + 0.715730825f, 0.698376249f, + 0.714658688f, 0.699473345f, + 0.713584869f, 0.700568794f, + 0.712509371f, 0.701662595f, + 0.711432196f, 0.702754744f, + 0.710353347f, 0.703845241f, + 0.709272826f, 0.704934080f, + 0.708190637f, 0.706021261f, + 0.707106781f, 0.707106781f, + 0.706021261f, 0.708190637f, + 0.704934080f, 0.709272826f, + 0.703845241f, 0.710353347f, + 0.702754744f, 0.711432196f, + 0.701662595f, 0.712509371f, + 0.700568794f, 0.713584869f, + 0.699473345f, 0.714658688f, + 0.698376249f, 0.715730825f, + 0.697277511f, 0.716801279f, + 0.696177131f, 0.717870045f, + 0.695075114f, 0.718937122f, + 0.693971461f, 0.720002508f, + 0.692866175f, 0.721066199f, + 0.691759258f, 0.722128194f, + 0.690650714f, 0.723188489f, + 0.689540545f, 0.724247083f, + 0.688428753f, 0.725303972f, + 0.687315341f, 0.726359155f, + 0.686200312f, 0.727412629f, + 0.685083668f, 0.728464390f, + 0.683965412f, 0.729514438f, + 0.682845546f, 0.730562769f, + 0.681724074f, 0.731609381f, + 0.680600998f, 0.732654272f, + 0.679476320f, 0.733697438f, + 0.678350043f, 0.734738878f, + 0.677222170f, 0.735778589f, + 0.676092704f, 0.736816569f, + 0.674961646f, 0.737852815f, + 0.673829000f, 0.738887324f, + 0.672694769f, 0.739920095f, + 0.671558955f, 0.740951125f, + 0.670421560f, 0.741980412f, + 0.669282588f, 0.743007952f, + 0.668142041f, 0.744033744f, + 0.666999922f, 0.745057785f, + 0.665856234f, 0.746080074f, + 0.664710978f, 0.747100606f, + 0.663564159f, 0.748119380f, + 0.662415778f, 0.749136395f, + 0.661265838f, 0.750151646f, + 0.660114342f, 0.751165132f, + 0.658961293f, 0.752176850f, + 0.657806693f, 0.753186799f, + 0.656650546f, 0.754194975f, + 0.655492853f, 0.755201377f, + 0.654333618f, 0.756206001f, + 0.653172843f, 0.757208847f, + 0.652010531f, 0.758209910f, + 0.650846685f, 0.759209189f, + 0.649681307f, 0.760206682f, + 0.648514401f, 0.761202385f, + 0.647345969f, 0.762196298f, + 0.646176013f, 0.763188417f, + 0.645004537f, 0.764178741f, + 0.643831543f, 0.765167266f, + 0.642657034f, 0.766153990f, + 0.641481013f, 0.767138912f, + 0.640303482f, 0.768122029f, + 0.639124445f, 0.769103338f, + 0.637943904f, 0.770082837f, + 0.636761861f, 0.771060524f, + 0.635578320f, 0.772036397f, + 0.634393284f, 0.773010453f, + 0.633206755f, 0.773982691f, + 0.632018736f, 0.774953107f, + 0.630829230f, 0.775921699f, + 0.629638239f, 0.776888466f, + 0.628445767f, 0.777853404f, + 0.627251815f, 0.778816512f, + 0.626056388f, 0.779777788f, + 0.624859488f, 0.780737229f, + 0.623661118f, 0.781694832f, + 0.622461279f, 0.782650596f, + 0.621259977f, 0.783604519f, + 0.620057212f, 0.784556597f, + 0.618852988f, 0.785506830f, + 0.617647308f, 0.786455214f, + 0.616440175f, 0.787401747f, + 0.615231591f, 0.788346428f, + 0.614021559f, 0.789289253f, + 0.612810082f, 0.790230221f, + 0.611597164f, 0.791169330f, + 0.610382806f, 0.792106577f, + 0.609167012f, 0.793041960f, + 0.607949785f, 0.793975478f, + 0.606731127f, 0.794907126f, + 0.605511041f, 0.795836905f, + 0.604289531f, 0.796764810f, + 0.603066599f, 0.797690841f, + 0.601842247f, 0.798614995f, + 0.600616479f, 0.799537269f, + 0.599389298f, 0.800457662f, + 0.598160707f, 0.801376172f, + 0.596930708f, 0.802292796f, + 0.595699304f, 0.803207531f, + 0.594466499f, 0.804120377f, + 0.593232295f, 0.805031331f, + 0.591996695f, 0.805940391f, + 0.590759702f, 0.806847554f, + 0.589521319f, 0.807752818f, + 0.588281548f, 0.808656182f, + 0.587040394f, 0.809557642f, + 0.585797857f, 0.810457198f, + 0.584553943f, 0.811354847f, + 0.583308653f, 0.812250587f, + 0.582061990f, 0.813144415f, + 0.580813958f, 0.814036330f, + 0.579564559f, 0.814926329f, + 0.578313796f, 0.815814411f, + 0.577061673f, 0.816700573f, + 0.575808191f, 0.817584813f, + 0.574553355f, 0.818467130f, + 0.573297167f, 0.819347520f, + 0.572039629f, 0.820225983f, + 0.570780746f, 0.821102515f, + 0.569520519f, 0.821977115f, + 0.568258953f, 0.822849781f, + 0.566996049f, 0.823720511f, + 0.565731811f, 0.824589303f, + 0.564466242f, 0.825456154f, + 0.563199344f, 0.826321063f, + 0.561931121f, 0.827184027f, + 0.560661576f, 0.828045045f, + 0.559390712f, 0.828904115f, + 0.558118531f, 0.829761234f, + 0.556845037f, 0.830616400f, + 0.555570233f, 0.831469612f, + 0.554294121f, 0.832320868f, + 0.553016706f, 0.833170165f, + 0.551737988f, 0.834017501f, + 0.550457973f, 0.834862875f, + 0.549176662f, 0.835706284f, + 0.547894059f, 0.836547727f, + 0.546610167f, 0.837387202f, + 0.545324988f, 0.838224706f, + 0.544038527f, 0.839060237f, + 0.542750785f, 0.839893794f, + 0.541461766f, 0.840725375f, + 0.540171473f, 0.841554977f, + 0.538879909f, 0.842382600f, + 0.537587076f, 0.843208240f, + 0.536292979f, 0.844031895f, + 0.534997620f, 0.844853565f, + 0.533701002f, 0.845673247f, + 0.532403128f, 0.846490939f, + 0.531104001f, 0.847306639f, + 0.529803625f, 0.848120345f, + 0.528502002f, 0.848932055f, + 0.527199135f, 0.849741768f, + 0.525895027f, 0.850549481f, + 0.524589683f, 0.851355193f, + 0.523283103f, 0.852158902f, + 0.521975293f, 0.852960605f, + 0.520666254f, 0.853760301f, + 0.519355990f, 0.854557988f, + 0.518044504f, 0.855353665f, + 0.516731799f, 0.856147328f, + 0.515417878f, 0.856938977f, + 0.514102744f, 0.857728610f, + 0.512786401f, 0.858516224f, + 0.511468850f, 0.859301818f, + 0.510150097f, 0.860085390f, + 0.508830143f, 0.860866939f, + 0.507508991f, 0.861646461f, + 0.506186645f, 0.862423956f, + 0.504863109f, 0.863199422f, + 0.503538384f, 0.863972856f, + 0.502212474f, 0.864744258f, + 0.500885383f, 0.865513624f, + 0.499557113f, 0.866280954f, + 0.498227667f, 0.867046246f, + 0.496897049f, 0.867809497f, + 0.495565262f, 0.868570706f, + 0.494232309f, 0.869329871f, + 0.492898192f, 0.870086991f, + 0.491562916f, 0.870842063f, + 0.490226483f, 0.871595087f, + 0.488888897f, 0.872346059f, + 0.487550160f, 0.873094978f, + 0.486210276f, 0.873841843f, + 0.484869248f, 0.874586652f, + 0.483527079f, 0.875329403f, + 0.482183772f, 0.876070094f, + 0.480839331f, 0.876808724f, + 0.479493758f, 0.877545290f, + 0.478147056f, 0.878279792f, + 0.476799230f, 0.879012226f, + 0.475450282f, 0.879742593f, + 0.474100215f, 0.880470889f, + 0.472749032f, 0.881197113f, + 0.471396737f, 0.881921264f, + 0.470043332f, 0.882643340f, + 0.468688822f, 0.883363339f, + 0.467333209f, 0.884081259f, + 0.465976496f, 0.884797098f, + 0.464618686f, 0.885510856f, + 0.463259784f, 0.886222530f, + 0.461899791f, 0.886932119f, + 0.460538711f, 0.887639620f, + 0.459176548f, 0.888345033f, + 0.457813304f, 0.889048356f, + 0.456448982f, 0.889749586f, + 0.455083587f, 0.890448723f, + 0.453717121f, 0.891145765f, + 0.452349587f, 0.891840709f, + 0.450980989f, 0.892533555f, + 0.449611330f, 0.893224301f, + 0.448240612f, 0.893912945f, + 0.446868840f, 0.894599486f, + 0.445496017f, 0.895283921f, + 0.444122145f, 0.895966250f, + 0.442747228f, 0.896646470f, + 0.441371269f, 0.897324581f, + 0.439994271f, 0.898000580f, + 0.438616239f, 0.898674466f, + 0.437237174f, 0.899346237f, + 0.435857080f, 0.900015892f, + 0.434475961f, 0.900683429f, + 0.433093819f, 0.901348847f, + 0.431710658f, 0.902012144f, + 0.430326481f, 0.902673318f, + 0.428941292f, 0.903332368f, + 0.427555093f, 0.903989293f, + 0.426167889f, 0.904644091f, + 0.424779681f, 0.905296759f, + 0.423390474f, 0.905947298f, + 0.422000271f, 0.906595705f, + 0.420609074f, 0.907241978f, + 0.419216888f, 0.907886116f, + 0.417823716f, 0.908528119f, + 0.416429560f, 0.909167983f, + 0.415034424f, 0.909805708f, + 0.413638312f, 0.910441292f, + 0.412241227f, 0.911074734f, + 0.410843171f, 0.911706032f, + 0.409444149f, 0.912335185f, + 0.408044163f, 0.912962190f, + 0.406643217f, 0.913587048f, + 0.405241314f, 0.914209756f, + 0.403838458f, 0.914830312f, + 0.402434651f, 0.915448716f, + 0.401029897f, 0.916064966f, + 0.399624200f, 0.916679060f, + 0.398217562f, 0.917290997f, + 0.396809987f, 0.917900776f, + 0.395401479f, 0.918508394f, + 0.393992040f, 0.919113852f, + 0.392581674f, 0.919717146f, + 0.391170384f, 0.920318277f, + 0.389758174f, 0.920917242f, + 0.388345047f, 0.921514039f, + 0.386931006f, 0.922108669f, + 0.385516054f, 0.922701128f, + 0.384100195f, 0.923291417f, + 0.382683432f, 0.923879533f, + 0.381265769f, 0.924465474f, + 0.379847209f, 0.925049241f, + 0.378427755f, 0.925630831f, + 0.377007410f, 0.926210242f, + 0.375586178f, 0.926787474f, + 0.374164063f, 0.927362526f, + 0.372741067f, 0.927935395f, + 0.371317194f, 0.928506080f, + 0.369892447f, 0.929074581f, + 0.368466830f, 0.929640896f, + 0.367040346f, 0.930205023f, + 0.365612998f, 0.930766961f, + 0.364184790f, 0.931326709f, + 0.362755724f, 0.931884266f, + 0.361325806f, 0.932439629f, + 0.359895037f, 0.932992799f, + 0.358463421f, 0.933543773f, + 0.357030961f, 0.934092550f, + 0.355597662f, 0.934639130f, + 0.354163525f, 0.935183510f, + 0.352728556f, 0.935725689f, + 0.351292756f, 0.936265667f, + 0.349856130f, 0.936803442f, + 0.348418680f, 0.937339012f, + 0.346980411f, 0.937872376f, + 0.345541325f, 0.938403534f, + 0.344101426f, 0.938932484f, + 0.342660717f, 0.939459224f, + 0.341219202f, 0.939983753f, + 0.339776884f, 0.940506071f, + 0.338333767f, 0.941026175f, + 0.336889853f, 0.941544065f, + 0.335445147f, 0.942059740f, + 0.333999651f, 0.942573198f, + 0.332553370f, 0.943084437f, + 0.331106306f, 0.943593458f, + 0.329658463f, 0.944100258f, + 0.328209844f, 0.944604837f, + 0.326760452f, 0.945107193f, + 0.325310292f, 0.945607325f, + 0.323859367f, 0.946105232f, + 0.322407679f, 0.946600913f, + 0.320955232f, 0.947094366f, + 0.319502031f, 0.947585591f, + 0.318048077f, 0.948074586f, + 0.316593376f, 0.948561350f, + 0.315137929f, 0.949045882f, + 0.313681740f, 0.949528181f, + 0.312224814f, 0.950008245f, + 0.310767153f, 0.950486074f, + 0.309308760f, 0.950961666f, + 0.307849640f, 0.951435021f, + 0.306389795f, 0.951906137f, + 0.304929230f, 0.952375013f, + 0.303467947f, 0.952841648f, + 0.302005949f, 0.953306040f, + 0.300543241f, 0.953768190f, + 0.299079826f, 0.954228095f, + 0.297615707f, 0.954685755f, + 0.296150888f, 0.955141168f, + 0.294685372f, 0.955594334f, + 0.293219163f, 0.956045251f, + 0.291752263f, 0.956493919f, + 0.290284677f, 0.956940336f, + 0.288816408f, 0.957384501f, + 0.287347460f, 0.957826413f, + 0.285877835f, 0.958266071f, + 0.284407537f, 0.958703475f, + 0.282936570f, 0.959138622f, + 0.281464938f, 0.959571513f, + 0.279992643f, 0.960002146f, + 0.278519689f, 0.960430519f, + 0.277046080f, 0.960856633f, + 0.275571819f, 0.961280486f, + 0.274096910f, 0.961702077f, + 0.272621355f, 0.962121404f, + 0.271145160f, 0.962538468f, + 0.269668326f, 0.962953267f, + 0.268190857f, 0.963365800f, + 0.266712757f, 0.963776066f, + 0.265234030f, 0.964184064f, + 0.263754679f, 0.964589793f, + 0.262274707f, 0.964993253f, + 0.260794118f, 0.965394442f, + 0.259312915f, 0.965793359f, + 0.257831102f, 0.966190003f, + 0.256348682f, 0.966584374f, + 0.254865660f, 0.966976471f, + 0.253382037f, 0.967366292f, + 0.251897818f, 0.967753837f, + 0.250413007f, 0.968139105f, + 0.248927606f, 0.968522094f, + 0.247441619f, 0.968902805f, + 0.245955050f, 0.969281235f, + 0.244467903f, 0.969657385f, + 0.242980180f, 0.970031253f, + 0.241491885f, 0.970402839f, + 0.240003022f, 0.970772141f, + 0.238513595f, 0.971139158f, + 0.237023606f, 0.971503891f, + 0.235533059f, 0.971866337f, + 0.234041959f, 0.972226497f, + 0.232550307f, 0.972584369f, + 0.231058108f, 0.972939952f, + 0.229565366f, 0.973293246f, + 0.228072083f, 0.973644250f, + 0.226578264f, 0.973992962f, + 0.225083911f, 0.974339383f, + 0.223589029f, 0.974683511f, + 0.222093621f, 0.975025345f, + 0.220597690f, 0.975364885f, + 0.219101240f, 0.975702130f, + 0.217604275f, 0.976037079f, + 0.216106797f, 0.976369731f, + 0.214608811f, 0.976700086f, + 0.213110320f, 0.977028143f, + 0.211611327f, 0.977353900f, + 0.210111837f, 0.977677358f, + 0.208611852f, 0.977998515f, + 0.207111376f, 0.978317371f, + 0.205610413f, 0.978633924f, + 0.204108966f, 0.978948175f, + 0.202607039f, 0.979260123f, + 0.201104635f, 0.979569766f, + 0.199601758f, 0.979877104f, + 0.198098411f, 0.980182136f, + 0.196594598f, 0.980484862f, + 0.195090322f, 0.980785280f, + 0.193585587f, 0.981083391f, + 0.192080397f, 0.981379193f, + 0.190574755f, 0.981672686f, + 0.189068664f, 0.981963869f, + 0.187562129f, 0.982252741f, + 0.186055152f, 0.982539302f, + 0.184547737f, 0.982823551f, + 0.183039888f, 0.983105487f, + 0.181531608f, 0.983385110f, + 0.180022901f, 0.983662419f, + 0.178513771f, 0.983937413f, + 0.177004220f, 0.984210092f, + 0.175494253f, 0.984480455f, + 0.173983873f, 0.984748502f, + 0.172473084f, 0.985014231f, + 0.170961889f, 0.985277642f, + 0.169450291f, 0.985538735f, + 0.167938295f, 0.985797509f, + 0.166425904f, 0.986053963f, + 0.164913120f, 0.986308097f, + 0.163399949f, 0.986559910f, + 0.161886394f, 0.986809402f, + 0.160372457f, 0.987056571f, + 0.158858143f, 0.987301418f, + 0.157343456f, 0.987543942f, + 0.155828398f, 0.987784142f, + 0.154312973f, 0.988022017f, + 0.152797185f, 0.988257568f, + 0.151281038f, 0.988490793f, + 0.149764535f, 0.988721692f, + 0.148247679f, 0.988950265f, + 0.146730474f, 0.989176510f, + 0.145212925f, 0.989400428f, + 0.143695033f, 0.989622017f, + 0.142176804f, 0.989841278f, + 0.140658239f, 0.990058210f, + 0.139139344f, 0.990272812f, + 0.137620122f, 0.990485084f, + 0.136100575f, 0.990695025f, + 0.134580709f, 0.990902635f, + 0.133060525f, 0.991107914f, + 0.131540029f, 0.991310860f, + 0.130019223f, 0.991511473f, + 0.128498111f, 0.991709754f, + 0.126976696f, 0.991905700f, + 0.125454983f, 0.992099313f, + 0.123932975f, 0.992290591f, + 0.122410675f, 0.992479535f, + 0.120888087f, 0.992666142f, + 0.119365215f, 0.992850414f, + 0.117842062f, 0.993032350f, + 0.116318631f, 0.993211949f, + 0.114794927f, 0.993389211f, + 0.113270952f, 0.993564136f, + 0.111746711f, 0.993736722f, + 0.110222207f, 0.993906970f, + 0.108697444f, 0.994074879f, + 0.107172425f, 0.994240449f, + 0.105647154f, 0.994403680f, + 0.104121634f, 0.994564571f, + 0.102595869f, 0.994723121f, + 0.101069863f, 0.994879331f, + 0.099543619f, 0.995033199f, + 0.098017140f, 0.995184727f, + 0.096490431f, 0.995333912f, + 0.094963495f, 0.995480755f, + 0.093436336f, 0.995625256f, + 0.091908956f, 0.995767414f, + 0.090381361f, 0.995907229f, + 0.088853553f, 0.996044701f, + 0.087325535f, 0.996179829f, + 0.085797312f, 0.996312612f, + 0.084268888f, 0.996443051f, + 0.082740265f, 0.996571146f, + 0.081211447f, 0.996696895f, + 0.079682438f, 0.996820299f, + 0.078153242f, 0.996941358f, + 0.076623861f, 0.997060070f, + 0.075094301f, 0.997176437f, + 0.073564564f, 0.997290457f, + 0.072034653f, 0.997402130f, + 0.070504573f, 0.997511456f, + 0.068974328f, 0.997618435f, + 0.067443920f, 0.997723067f, + 0.065913353f, 0.997825350f, + 0.064382631f, 0.997925286f, + 0.062851758f, 0.998022874f, + 0.061320736f, 0.998118113f, + 0.059789571f, 0.998211003f, + 0.058258265f, 0.998301545f, + 0.056726821f, 0.998389737f, + 0.055195244f, 0.998475581f, + 0.053663538f, 0.998559074f, + 0.052131705f, 0.998640218f, + 0.050599749f, 0.998719012f, + 0.049067674f, 0.998795456f, + 0.047535484f, 0.998869550f, + 0.046003182f, 0.998941293f, + 0.044470772f, 0.999010686f, + 0.042938257f, 0.999077728f, + 0.041405641f, 0.999142419f, + 0.039872928f, 0.999204759f, + 0.038340120f, 0.999264747f, + 0.036807223f, 0.999322385f, + 0.035274239f, 0.999377670f, + 0.033741172f, 0.999430605f, + 0.032208025f, 0.999481187f, + 0.030674803f, 0.999529418f, + 0.029141509f, 0.999575296f, + 0.027608146f, 0.999618822f, + 0.026074718f, 0.999659997f, + 0.024541229f, 0.999698819f, + 0.023007681f, 0.999735288f, + 0.021474080f, 0.999769405f, + 0.019940429f, 0.999801170f, + 0.018406730f, 0.999830582f, + 0.016872988f, 0.999857641f, + 0.015339206f, 0.999882347f, + 0.013805389f, 0.999904701f, + 0.012271538f, 0.999924702f, + 0.010737659f, 0.999942350f, + 0.009203755f, 0.999957645f, + 0.007669829f, 0.999970586f, + 0.006135885f, 0.999981175f, + 0.004601926f, 0.999989411f, + 0.003067957f, 0.999995294f, + 0.001533980f, 0.999998823f, + 0.000000000f, 1.000000000f, + -0.001533980f, 0.999998823f, + -0.003067957f, 0.999995294f, + -0.004601926f, 0.999989411f, + -0.006135885f, 0.999981175f, + -0.007669829f, 0.999970586f, + -0.009203755f, 0.999957645f, + -0.010737659f, 0.999942350f, + -0.012271538f, 0.999924702f, + -0.013805389f, 0.999904701f, + -0.015339206f, 0.999882347f, + -0.016872988f, 0.999857641f, + -0.018406730f, 0.999830582f, + -0.019940429f, 0.999801170f, + -0.021474080f, 0.999769405f, + -0.023007681f, 0.999735288f, + -0.024541229f, 0.999698819f, + -0.026074718f, 0.999659997f, + -0.027608146f, 0.999618822f, + -0.029141509f, 0.999575296f, + -0.030674803f, 0.999529418f, + -0.032208025f, 0.999481187f, + -0.033741172f, 0.999430605f, + -0.035274239f, 0.999377670f, + -0.036807223f, 0.999322385f, + -0.038340120f, 0.999264747f, + -0.039872928f, 0.999204759f, + -0.041405641f, 0.999142419f, + -0.042938257f, 0.999077728f, + -0.044470772f, 0.999010686f, + -0.046003182f, 0.998941293f, + -0.047535484f, 0.998869550f, + -0.049067674f, 0.998795456f, + -0.050599749f, 0.998719012f, + -0.052131705f, 0.998640218f, + -0.053663538f, 0.998559074f, + -0.055195244f, 0.998475581f, + -0.056726821f, 0.998389737f, + -0.058258265f, 0.998301545f, + -0.059789571f, 0.998211003f, + -0.061320736f, 0.998118113f, + -0.062851758f, 0.998022874f, + -0.064382631f, 0.997925286f, + -0.065913353f, 0.997825350f, + -0.067443920f, 0.997723067f, + -0.068974328f, 0.997618435f, + -0.070504573f, 0.997511456f, + -0.072034653f, 0.997402130f, + -0.073564564f, 0.997290457f, + -0.075094301f, 0.997176437f, + -0.076623861f, 0.997060070f, + -0.078153242f, 0.996941358f, + -0.079682438f, 0.996820299f, + -0.081211447f, 0.996696895f, + -0.082740265f, 0.996571146f, + -0.084268888f, 0.996443051f, + -0.085797312f, 0.996312612f, + -0.087325535f, 0.996179829f, + -0.088853553f, 0.996044701f, + -0.090381361f, 0.995907229f, + -0.091908956f, 0.995767414f, + -0.093436336f, 0.995625256f, + -0.094963495f, 0.995480755f, + -0.096490431f, 0.995333912f, + -0.098017140f, 0.995184727f, + -0.099543619f, 0.995033199f, + -0.101069863f, 0.994879331f, + -0.102595869f, 0.994723121f, + -0.104121634f, 0.994564571f, + -0.105647154f, 0.994403680f, + -0.107172425f, 0.994240449f, + -0.108697444f, 0.994074879f, + -0.110222207f, 0.993906970f, + -0.111746711f, 0.993736722f, + -0.113270952f, 0.993564136f, + -0.114794927f, 0.993389211f, + -0.116318631f, 0.993211949f, + -0.117842062f, 0.993032350f, + -0.119365215f, 0.992850414f, + -0.120888087f, 0.992666142f, + -0.122410675f, 0.992479535f, + -0.123932975f, 0.992290591f, + -0.125454983f, 0.992099313f, + -0.126976696f, 0.991905700f, + -0.128498111f, 0.991709754f, + -0.130019223f, 0.991511473f, + -0.131540029f, 0.991310860f, + -0.133060525f, 0.991107914f, + -0.134580709f, 0.990902635f, + -0.136100575f, 0.990695025f, + -0.137620122f, 0.990485084f, + -0.139139344f, 0.990272812f, + -0.140658239f, 0.990058210f, + -0.142176804f, 0.989841278f, + -0.143695033f, 0.989622017f, + -0.145212925f, 0.989400428f, + -0.146730474f, 0.989176510f, + -0.148247679f, 0.988950265f, + -0.149764535f, 0.988721692f, + -0.151281038f, 0.988490793f, + -0.152797185f, 0.988257568f, + -0.154312973f, 0.988022017f, + -0.155828398f, 0.987784142f, + -0.157343456f, 0.987543942f, + -0.158858143f, 0.987301418f, + -0.160372457f, 0.987056571f, + -0.161886394f, 0.986809402f, + -0.163399949f, 0.986559910f, + -0.164913120f, 0.986308097f, + -0.166425904f, 0.986053963f, + -0.167938295f, 0.985797509f, + -0.169450291f, 0.985538735f, + -0.170961889f, 0.985277642f, + -0.172473084f, 0.985014231f, + -0.173983873f, 0.984748502f, + -0.175494253f, 0.984480455f, + -0.177004220f, 0.984210092f, + -0.178513771f, 0.983937413f, + -0.180022901f, 0.983662419f, + -0.181531608f, 0.983385110f, + -0.183039888f, 0.983105487f, + -0.184547737f, 0.982823551f, + -0.186055152f, 0.982539302f, + -0.187562129f, 0.982252741f, + -0.189068664f, 0.981963869f, + -0.190574755f, 0.981672686f, + -0.192080397f, 0.981379193f, + -0.193585587f, 0.981083391f, + -0.195090322f, 0.980785280f, + -0.196594598f, 0.980484862f, + -0.198098411f, 0.980182136f, + -0.199601758f, 0.979877104f, + -0.201104635f, 0.979569766f, + -0.202607039f, 0.979260123f, + -0.204108966f, 0.978948175f, + -0.205610413f, 0.978633924f, + -0.207111376f, 0.978317371f, + -0.208611852f, 0.977998515f, + -0.210111837f, 0.977677358f, + -0.211611327f, 0.977353900f, + -0.213110320f, 0.977028143f, + -0.214608811f, 0.976700086f, + -0.216106797f, 0.976369731f, + -0.217604275f, 0.976037079f, + -0.219101240f, 0.975702130f, + -0.220597690f, 0.975364885f, + -0.222093621f, 0.975025345f, + -0.223589029f, 0.974683511f, + -0.225083911f, 0.974339383f, + -0.226578264f, 0.973992962f, + -0.228072083f, 0.973644250f, + -0.229565366f, 0.973293246f, + -0.231058108f, 0.972939952f, + -0.232550307f, 0.972584369f, + -0.234041959f, 0.972226497f, + -0.235533059f, 0.971866337f, + -0.237023606f, 0.971503891f, + -0.238513595f, 0.971139158f, + -0.240003022f, 0.970772141f, + -0.241491885f, 0.970402839f, + -0.242980180f, 0.970031253f, + -0.244467903f, 0.969657385f, + -0.245955050f, 0.969281235f, + -0.247441619f, 0.968902805f, + -0.248927606f, 0.968522094f, + -0.250413007f, 0.968139105f, + -0.251897818f, 0.967753837f, + -0.253382037f, 0.967366292f, + -0.254865660f, 0.966976471f, + -0.256348682f, 0.966584374f, + -0.257831102f, 0.966190003f, + -0.259312915f, 0.965793359f, + -0.260794118f, 0.965394442f, + -0.262274707f, 0.964993253f, + -0.263754679f, 0.964589793f, + -0.265234030f, 0.964184064f, + -0.266712757f, 0.963776066f, + -0.268190857f, 0.963365800f, + -0.269668326f, 0.962953267f, + -0.271145160f, 0.962538468f, + -0.272621355f, 0.962121404f, + -0.274096910f, 0.961702077f, + -0.275571819f, 0.961280486f, + -0.277046080f, 0.960856633f, + -0.278519689f, 0.960430519f, + -0.279992643f, 0.960002146f, + -0.281464938f, 0.959571513f, + -0.282936570f, 0.959138622f, + -0.284407537f, 0.958703475f, + -0.285877835f, 0.958266071f, + -0.287347460f, 0.957826413f, + -0.288816408f, 0.957384501f, + -0.290284677f, 0.956940336f, + -0.291752263f, 0.956493919f, + -0.293219163f, 0.956045251f, + -0.294685372f, 0.955594334f, + -0.296150888f, 0.955141168f, + -0.297615707f, 0.954685755f, + -0.299079826f, 0.954228095f, + -0.300543241f, 0.953768190f, + -0.302005949f, 0.953306040f, + -0.303467947f, 0.952841648f, + -0.304929230f, 0.952375013f, + -0.306389795f, 0.951906137f, + -0.307849640f, 0.951435021f, + -0.309308760f, 0.950961666f, + -0.310767153f, 0.950486074f, + -0.312224814f, 0.950008245f, + -0.313681740f, 0.949528181f, + -0.315137929f, 0.949045882f, + -0.316593376f, 0.948561350f, + -0.318048077f, 0.948074586f, + -0.319502031f, 0.947585591f, + -0.320955232f, 0.947094366f, + -0.322407679f, 0.946600913f, + -0.323859367f, 0.946105232f, + -0.325310292f, 0.945607325f, + -0.326760452f, 0.945107193f, + -0.328209844f, 0.944604837f, + -0.329658463f, 0.944100258f, + -0.331106306f, 0.943593458f, + -0.332553370f, 0.943084437f, + -0.333999651f, 0.942573198f, + -0.335445147f, 0.942059740f, + -0.336889853f, 0.941544065f, + -0.338333767f, 0.941026175f, + -0.339776884f, 0.940506071f, + -0.341219202f, 0.939983753f, + -0.342660717f, 0.939459224f, + -0.344101426f, 0.938932484f, + -0.345541325f, 0.938403534f, + -0.346980411f, 0.937872376f, + -0.348418680f, 0.937339012f, + -0.349856130f, 0.936803442f, + -0.351292756f, 0.936265667f, + -0.352728556f, 0.935725689f, + -0.354163525f, 0.935183510f, + -0.355597662f, 0.934639130f, + -0.357030961f, 0.934092550f, + -0.358463421f, 0.933543773f, + -0.359895037f, 0.932992799f, + -0.361325806f, 0.932439629f, + -0.362755724f, 0.931884266f, + -0.364184790f, 0.931326709f, + -0.365612998f, 0.930766961f, + -0.367040346f, 0.930205023f, + -0.368466830f, 0.929640896f, + -0.369892447f, 0.929074581f, + -0.371317194f, 0.928506080f, + -0.372741067f, 0.927935395f, + -0.374164063f, 0.927362526f, + -0.375586178f, 0.926787474f, + -0.377007410f, 0.926210242f, + -0.378427755f, 0.925630831f, + -0.379847209f, 0.925049241f, + -0.381265769f, 0.924465474f, + -0.382683432f, 0.923879533f, + -0.384100195f, 0.923291417f, + -0.385516054f, 0.922701128f, + -0.386931006f, 0.922108669f, + -0.388345047f, 0.921514039f, + -0.389758174f, 0.920917242f, + -0.391170384f, 0.920318277f, + -0.392581674f, 0.919717146f, + -0.393992040f, 0.919113852f, + -0.395401479f, 0.918508394f, + -0.396809987f, 0.917900776f, + -0.398217562f, 0.917290997f, + -0.399624200f, 0.916679060f, + -0.401029897f, 0.916064966f, + -0.402434651f, 0.915448716f, + -0.403838458f, 0.914830312f, + -0.405241314f, 0.914209756f, + -0.406643217f, 0.913587048f, + -0.408044163f, 0.912962190f, + -0.409444149f, 0.912335185f, + -0.410843171f, 0.911706032f, + -0.412241227f, 0.911074734f, + -0.413638312f, 0.910441292f, + -0.415034424f, 0.909805708f, + -0.416429560f, 0.909167983f, + -0.417823716f, 0.908528119f, + -0.419216888f, 0.907886116f, + -0.420609074f, 0.907241978f, + -0.422000271f, 0.906595705f, + -0.423390474f, 0.905947298f, + -0.424779681f, 0.905296759f, + -0.426167889f, 0.904644091f, + -0.427555093f, 0.903989293f, + -0.428941292f, 0.903332368f, + -0.430326481f, 0.902673318f, + -0.431710658f, 0.902012144f, + -0.433093819f, 0.901348847f, + -0.434475961f, 0.900683429f, + -0.435857080f, 0.900015892f, + -0.437237174f, 0.899346237f, + -0.438616239f, 0.898674466f, + -0.439994271f, 0.898000580f, + -0.441371269f, 0.897324581f, + -0.442747228f, 0.896646470f, + -0.444122145f, 0.895966250f, + -0.445496017f, 0.895283921f, + -0.446868840f, 0.894599486f, + -0.448240612f, 0.893912945f, + -0.449611330f, 0.893224301f, + -0.450980989f, 0.892533555f, + -0.452349587f, 0.891840709f, + -0.453717121f, 0.891145765f, + -0.455083587f, 0.890448723f, + -0.456448982f, 0.889749586f, + -0.457813304f, 0.889048356f, + -0.459176548f, 0.888345033f, + -0.460538711f, 0.887639620f, + -0.461899791f, 0.886932119f, + -0.463259784f, 0.886222530f, + -0.464618686f, 0.885510856f, + -0.465976496f, 0.884797098f, + -0.467333209f, 0.884081259f, + -0.468688822f, 0.883363339f, + -0.470043332f, 0.882643340f, + -0.471396737f, 0.881921264f, + -0.472749032f, 0.881197113f, + -0.474100215f, 0.880470889f, + -0.475450282f, 0.879742593f, + -0.476799230f, 0.879012226f, + -0.478147056f, 0.878279792f, + -0.479493758f, 0.877545290f, + -0.480839331f, 0.876808724f, + -0.482183772f, 0.876070094f, + -0.483527079f, 0.875329403f, + -0.484869248f, 0.874586652f, + -0.486210276f, 0.873841843f, + -0.487550160f, 0.873094978f, + -0.488888897f, 0.872346059f, + -0.490226483f, 0.871595087f, + -0.491562916f, 0.870842063f, + -0.492898192f, 0.870086991f, + -0.494232309f, 0.869329871f, + -0.495565262f, 0.868570706f, + -0.496897049f, 0.867809497f, + -0.498227667f, 0.867046246f, + -0.499557113f, 0.866280954f, + -0.500885383f, 0.865513624f, + -0.502212474f, 0.864744258f, + -0.503538384f, 0.863972856f, + -0.504863109f, 0.863199422f, + -0.506186645f, 0.862423956f, + -0.507508991f, 0.861646461f, + -0.508830143f, 0.860866939f, + -0.510150097f, 0.860085390f, + -0.511468850f, 0.859301818f, + -0.512786401f, 0.858516224f, + -0.514102744f, 0.857728610f, + -0.515417878f, 0.856938977f, + -0.516731799f, 0.856147328f, + -0.518044504f, 0.855353665f, + -0.519355990f, 0.854557988f, + -0.520666254f, 0.853760301f, + -0.521975293f, 0.852960605f, + -0.523283103f, 0.852158902f, + -0.524589683f, 0.851355193f, + -0.525895027f, 0.850549481f, + -0.527199135f, 0.849741768f, + -0.528502002f, 0.848932055f, + -0.529803625f, 0.848120345f, + -0.531104001f, 0.847306639f, + -0.532403128f, 0.846490939f, + -0.533701002f, 0.845673247f, + -0.534997620f, 0.844853565f, + -0.536292979f, 0.844031895f, + -0.537587076f, 0.843208240f, + -0.538879909f, 0.842382600f, + -0.540171473f, 0.841554977f, + -0.541461766f, 0.840725375f, + -0.542750785f, 0.839893794f, + -0.544038527f, 0.839060237f, + -0.545324988f, 0.838224706f, + -0.546610167f, 0.837387202f, + -0.547894059f, 0.836547727f, + -0.549176662f, 0.835706284f, + -0.550457973f, 0.834862875f, + -0.551737988f, 0.834017501f, + -0.553016706f, 0.833170165f, + -0.554294121f, 0.832320868f, + -0.555570233f, 0.831469612f, + -0.556845037f, 0.830616400f, + -0.558118531f, 0.829761234f, + -0.559390712f, 0.828904115f, + -0.560661576f, 0.828045045f, + -0.561931121f, 0.827184027f, + -0.563199344f, 0.826321063f, + -0.564466242f, 0.825456154f, + -0.565731811f, 0.824589303f, + -0.566996049f, 0.823720511f, + -0.568258953f, 0.822849781f, + -0.569520519f, 0.821977115f, + -0.570780746f, 0.821102515f, + -0.572039629f, 0.820225983f, + -0.573297167f, 0.819347520f, + -0.574553355f, 0.818467130f, + -0.575808191f, 0.817584813f, + -0.577061673f, 0.816700573f, + -0.578313796f, 0.815814411f, + -0.579564559f, 0.814926329f, + -0.580813958f, 0.814036330f, + -0.582061990f, 0.813144415f, + -0.583308653f, 0.812250587f, + -0.584553943f, 0.811354847f, + -0.585797857f, 0.810457198f, + -0.587040394f, 0.809557642f, + -0.588281548f, 0.808656182f, + -0.589521319f, 0.807752818f, + -0.590759702f, 0.806847554f, + -0.591996695f, 0.805940391f, + -0.593232295f, 0.805031331f, + -0.594466499f, 0.804120377f, + -0.595699304f, 0.803207531f, + -0.596930708f, 0.802292796f, + -0.598160707f, 0.801376172f, + -0.599389298f, 0.800457662f, + -0.600616479f, 0.799537269f, + -0.601842247f, 0.798614995f, + -0.603066599f, 0.797690841f, + -0.604289531f, 0.796764810f, + -0.605511041f, 0.795836905f, + -0.606731127f, 0.794907126f, + -0.607949785f, 0.793975478f, + -0.609167012f, 0.793041960f, + -0.610382806f, 0.792106577f, + -0.611597164f, 0.791169330f, + -0.612810082f, 0.790230221f, + -0.614021559f, 0.789289253f, + -0.615231591f, 0.788346428f, + -0.616440175f, 0.787401747f, + -0.617647308f, 0.786455214f, + -0.618852988f, 0.785506830f, + -0.620057212f, 0.784556597f, + -0.621259977f, 0.783604519f, + -0.622461279f, 0.782650596f, + -0.623661118f, 0.781694832f, + -0.624859488f, 0.780737229f, + -0.626056388f, 0.779777788f, + -0.627251815f, 0.778816512f, + -0.628445767f, 0.777853404f, + -0.629638239f, 0.776888466f, + -0.630829230f, 0.775921699f, + -0.632018736f, 0.774953107f, + -0.633206755f, 0.773982691f, + -0.634393284f, 0.773010453f, + -0.635578320f, 0.772036397f, + -0.636761861f, 0.771060524f, + -0.637943904f, 0.770082837f, + -0.639124445f, 0.769103338f, + -0.640303482f, 0.768122029f, + -0.641481013f, 0.767138912f, + -0.642657034f, 0.766153990f, + -0.643831543f, 0.765167266f, + -0.645004537f, 0.764178741f, + -0.646176013f, 0.763188417f, + -0.647345969f, 0.762196298f, + -0.648514401f, 0.761202385f, + -0.649681307f, 0.760206682f, + -0.650846685f, 0.759209189f, + -0.652010531f, 0.758209910f, + -0.653172843f, 0.757208847f, + -0.654333618f, 0.756206001f, + -0.655492853f, 0.755201377f, + -0.656650546f, 0.754194975f, + -0.657806693f, 0.753186799f, + -0.658961293f, 0.752176850f, + -0.660114342f, 0.751165132f, + -0.661265838f, 0.750151646f, + -0.662415778f, 0.749136395f, + -0.663564159f, 0.748119380f, + -0.664710978f, 0.747100606f, + -0.665856234f, 0.746080074f, + -0.666999922f, 0.745057785f, + -0.668142041f, 0.744033744f, + -0.669282588f, 0.743007952f, + -0.670421560f, 0.741980412f, + -0.671558955f, 0.740951125f, + -0.672694769f, 0.739920095f, + -0.673829000f, 0.738887324f, + -0.674961646f, 0.737852815f, + -0.676092704f, 0.736816569f, + -0.677222170f, 0.735778589f, + -0.678350043f, 0.734738878f, + -0.679476320f, 0.733697438f, + -0.680600998f, 0.732654272f, + -0.681724074f, 0.731609381f, + -0.682845546f, 0.730562769f, + -0.683965412f, 0.729514438f, + -0.685083668f, 0.728464390f, + -0.686200312f, 0.727412629f, + -0.687315341f, 0.726359155f, + -0.688428753f, 0.725303972f, + -0.689540545f, 0.724247083f, + -0.690650714f, 0.723188489f, + -0.691759258f, 0.722128194f, + -0.692866175f, 0.721066199f, + -0.693971461f, 0.720002508f, + -0.695075114f, 0.718937122f, + -0.696177131f, 0.717870045f, + -0.697277511f, 0.716801279f, + -0.698376249f, 0.715730825f, + -0.699473345f, 0.714658688f, + -0.700568794f, 0.713584869f, + -0.701662595f, 0.712509371f, + -0.702754744f, 0.711432196f, + -0.703845241f, 0.710353347f, + -0.704934080f, 0.709272826f, + -0.706021261f, 0.708190637f, + -0.707106781f, 0.707106781f, + -0.708190637f, 0.706021261f, + -0.709272826f, 0.704934080f, + -0.710353347f, 0.703845241f, + -0.711432196f, 0.702754744f, + -0.712509371f, 0.701662595f, + -0.713584869f, 0.700568794f, + -0.714658688f, 0.699473345f, + -0.715730825f, 0.698376249f, + -0.716801279f, 0.697277511f, + -0.717870045f, 0.696177131f, + -0.718937122f, 0.695075114f, + -0.720002508f, 0.693971461f, + -0.721066199f, 0.692866175f, + -0.722128194f, 0.691759258f, + -0.723188489f, 0.690650714f, + -0.724247083f, 0.689540545f, + -0.725303972f, 0.688428753f, + -0.726359155f, 0.687315341f, + -0.727412629f, 0.686200312f, + -0.728464390f, 0.685083668f, + -0.729514438f, 0.683965412f, + -0.730562769f, 0.682845546f, + -0.731609381f, 0.681724074f, + -0.732654272f, 0.680600998f, + -0.733697438f, 0.679476320f, + -0.734738878f, 0.678350043f, + -0.735778589f, 0.677222170f, + -0.736816569f, 0.676092704f, + -0.737852815f, 0.674961646f, + -0.738887324f, 0.673829000f, + -0.739920095f, 0.672694769f, + -0.740951125f, 0.671558955f, + -0.741980412f, 0.670421560f, + -0.743007952f, 0.669282588f, + -0.744033744f, 0.668142041f, + -0.745057785f, 0.666999922f, + -0.746080074f, 0.665856234f, + -0.747100606f, 0.664710978f, + -0.748119380f, 0.663564159f, + -0.749136395f, 0.662415778f, + -0.750151646f, 0.661265838f, + -0.751165132f, 0.660114342f, + -0.752176850f, 0.658961293f, + -0.753186799f, 0.657806693f, + -0.754194975f, 0.656650546f, + -0.755201377f, 0.655492853f, + -0.756206001f, 0.654333618f, + -0.757208847f, 0.653172843f, + -0.758209910f, 0.652010531f, + -0.759209189f, 0.650846685f, + -0.760206682f, 0.649681307f, + -0.761202385f, 0.648514401f, + -0.762196298f, 0.647345969f, + -0.763188417f, 0.646176013f, + -0.764178741f, 0.645004537f, + -0.765167266f, 0.643831543f, + -0.766153990f, 0.642657034f, + -0.767138912f, 0.641481013f, + -0.768122029f, 0.640303482f, + -0.769103338f, 0.639124445f, + -0.770082837f, 0.637943904f, + -0.771060524f, 0.636761861f, + -0.772036397f, 0.635578320f, + -0.773010453f, 0.634393284f, + -0.773982691f, 0.633206755f, + -0.774953107f, 0.632018736f, + -0.775921699f, 0.630829230f, + -0.776888466f, 0.629638239f, + -0.777853404f, 0.628445767f, + -0.778816512f, 0.627251815f, + -0.779777788f, 0.626056388f, + -0.780737229f, 0.624859488f, + -0.781694832f, 0.623661118f, + -0.782650596f, 0.622461279f, + -0.783604519f, 0.621259977f, + -0.784556597f, 0.620057212f, + -0.785506830f, 0.618852988f, + -0.786455214f, 0.617647308f, + -0.787401747f, 0.616440175f, + -0.788346428f, 0.615231591f, + -0.789289253f, 0.614021559f, + -0.790230221f, 0.612810082f, + -0.791169330f, 0.611597164f, + -0.792106577f, 0.610382806f, + -0.793041960f, 0.609167012f, + -0.793975478f, 0.607949785f, + -0.794907126f, 0.606731127f, + -0.795836905f, 0.605511041f, + -0.796764810f, 0.604289531f, + -0.797690841f, 0.603066599f, + -0.798614995f, 0.601842247f, + -0.799537269f, 0.600616479f, + -0.800457662f, 0.599389298f, + -0.801376172f, 0.598160707f, + -0.802292796f, 0.596930708f, + -0.803207531f, 0.595699304f, + -0.804120377f, 0.594466499f, + -0.805031331f, 0.593232295f, + -0.805940391f, 0.591996695f, + -0.806847554f, 0.590759702f, + -0.807752818f, 0.589521319f, + -0.808656182f, 0.588281548f, + -0.809557642f, 0.587040394f, + -0.810457198f, 0.585797857f, + -0.811354847f, 0.584553943f, + -0.812250587f, 0.583308653f, + -0.813144415f, 0.582061990f, + -0.814036330f, 0.580813958f, + -0.814926329f, 0.579564559f, + -0.815814411f, 0.578313796f, + -0.816700573f, 0.577061673f, + -0.817584813f, 0.575808191f, + -0.818467130f, 0.574553355f, + -0.819347520f, 0.573297167f, + -0.820225983f, 0.572039629f, + -0.821102515f, 0.570780746f, + -0.821977115f, 0.569520519f, + -0.822849781f, 0.568258953f, + -0.823720511f, 0.566996049f, + -0.824589303f, 0.565731811f, + -0.825456154f, 0.564466242f, + -0.826321063f, 0.563199344f, + -0.827184027f, 0.561931121f, + -0.828045045f, 0.560661576f, + -0.828904115f, 0.559390712f, + -0.829761234f, 0.558118531f, + -0.830616400f, 0.556845037f, + -0.831469612f, 0.555570233f, + -0.832320868f, 0.554294121f, + -0.833170165f, 0.553016706f, + -0.834017501f, 0.551737988f, + -0.834862875f, 0.550457973f, + -0.835706284f, 0.549176662f, + -0.836547727f, 0.547894059f, + -0.837387202f, 0.546610167f, + -0.838224706f, 0.545324988f, + -0.839060237f, 0.544038527f, + -0.839893794f, 0.542750785f, + -0.840725375f, 0.541461766f, + -0.841554977f, 0.540171473f, + -0.842382600f, 0.538879909f, + -0.843208240f, 0.537587076f, + -0.844031895f, 0.536292979f, + -0.844853565f, 0.534997620f, + -0.845673247f, 0.533701002f, + -0.846490939f, 0.532403128f, + -0.847306639f, 0.531104001f, + -0.848120345f, 0.529803625f, + -0.848932055f, 0.528502002f, + -0.849741768f, 0.527199135f, + -0.850549481f, 0.525895027f, + -0.851355193f, 0.524589683f, + -0.852158902f, 0.523283103f, + -0.852960605f, 0.521975293f, + -0.853760301f, 0.520666254f, + -0.854557988f, 0.519355990f, + -0.855353665f, 0.518044504f, + -0.856147328f, 0.516731799f, + -0.856938977f, 0.515417878f, + -0.857728610f, 0.514102744f, + -0.858516224f, 0.512786401f, + -0.859301818f, 0.511468850f, + -0.860085390f, 0.510150097f, + -0.860866939f, 0.508830143f, + -0.861646461f, 0.507508991f, + -0.862423956f, 0.506186645f, + -0.863199422f, 0.504863109f, + -0.863972856f, 0.503538384f, + -0.864744258f, 0.502212474f, + -0.865513624f, 0.500885383f, + -0.866280954f, 0.499557113f, + -0.867046246f, 0.498227667f, + -0.867809497f, 0.496897049f, + -0.868570706f, 0.495565262f, + -0.869329871f, 0.494232309f, + -0.870086991f, 0.492898192f, + -0.870842063f, 0.491562916f, + -0.871595087f, 0.490226483f, + -0.872346059f, 0.488888897f, + -0.873094978f, 0.487550160f, + -0.873841843f, 0.486210276f, + -0.874586652f, 0.484869248f, + -0.875329403f, 0.483527079f, + -0.876070094f, 0.482183772f, + -0.876808724f, 0.480839331f, + -0.877545290f, 0.479493758f, + -0.878279792f, 0.478147056f, + -0.879012226f, 0.476799230f, + -0.879742593f, 0.475450282f, + -0.880470889f, 0.474100215f, + -0.881197113f, 0.472749032f, + -0.881921264f, 0.471396737f, + -0.882643340f, 0.470043332f, + -0.883363339f, 0.468688822f, + -0.884081259f, 0.467333209f, + -0.884797098f, 0.465976496f, + -0.885510856f, 0.464618686f, + -0.886222530f, 0.463259784f, + -0.886932119f, 0.461899791f, + -0.887639620f, 0.460538711f, + -0.888345033f, 0.459176548f, + -0.889048356f, 0.457813304f, + -0.889749586f, 0.456448982f, + -0.890448723f, 0.455083587f, + -0.891145765f, 0.453717121f, + -0.891840709f, 0.452349587f, + -0.892533555f, 0.450980989f, + -0.893224301f, 0.449611330f, + -0.893912945f, 0.448240612f, + -0.894599486f, 0.446868840f, + -0.895283921f, 0.445496017f, + -0.895966250f, 0.444122145f, + -0.896646470f, 0.442747228f, + -0.897324581f, 0.441371269f, + -0.898000580f, 0.439994271f, + -0.898674466f, 0.438616239f, + -0.899346237f, 0.437237174f, + -0.900015892f, 0.435857080f, + -0.900683429f, 0.434475961f, + -0.901348847f, 0.433093819f, + -0.902012144f, 0.431710658f, + -0.902673318f, 0.430326481f, + -0.903332368f, 0.428941292f, + -0.903989293f, 0.427555093f, + -0.904644091f, 0.426167889f, + -0.905296759f, 0.424779681f, + -0.905947298f, 0.423390474f, + -0.906595705f, 0.422000271f, + -0.907241978f, 0.420609074f, + -0.907886116f, 0.419216888f, + -0.908528119f, 0.417823716f, + -0.909167983f, 0.416429560f, + -0.909805708f, 0.415034424f, + -0.910441292f, 0.413638312f, + -0.911074734f, 0.412241227f, + -0.911706032f, 0.410843171f, + -0.912335185f, 0.409444149f, + -0.912962190f, 0.408044163f, + -0.913587048f, 0.406643217f, + -0.914209756f, 0.405241314f, + -0.914830312f, 0.403838458f, + -0.915448716f, 0.402434651f, + -0.916064966f, 0.401029897f, + -0.916679060f, 0.399624200f, + -0.917290997f, 0.398217562f, + -0.917900776f, 0.396809987f, + -0.918508394f, 0.395401479f, + -0.919113852f, 0.393992040f, + -0.919717146f, 0.392581674f, + -0.920318277f, 0.391170384f, + -0.920917242f, 0.389758174f, + -0.921514039f, 0.388345047f, + -0.922108669f, 0.386931006f, + -0.922701128f, 0.385516054f, + -0.923291417f, 0.384100195f, + -0.923879533f, 0.382683432f, + -0.924465474f, 0.381265769f, + -0.925049241f, 0.379847209f, + -0.925630831f, 0.378427755f, + -0.926210242f, 0.377007410f, + -0.926787474f, 0.375586178f, + -0.927362526f, 0.374164063f, + -0.927935395f, 0.372741067f, + -0.928506080f, 0.371317194f, + -0.929074581f, 0.369892447f, + -0.929640896f, 0.368466830f, + -0.930205023f, 0.367040346f, + -0.930766961f, 0.365612998f, + -0.931326709f, 0.364184790f, + -0.931884266f, 0.362755724f, + -0.932439629f, 0.361325806f, + -0.932992799f, 0.359895037f, + -0.933543773f, 0.358463421f, + -0.934092550f, 0.357030961f, + -0.934639130f, 0.355597662f, + -0.935183510f, 0.354163525f, + -0.935725689f, 0.352728556f, + -0.936265667f, 0.351292756f, + -0.936803442f, 0.349856130f, + -0.937339012f, 0.348418680f, + -0.937872376f, 0.346980411f, + -0.938403534f, 0.345541325f, + -0.938932484f, 0.344101426f, + -0.939459224f, 0.342660717f, + -0.939983753f, 0.341219202f, + -0.940506071f, 0.339776884f, + -0.941026175f, 0.338333767f, + -0.941544065f, 0.336889853f, + -0.942059740f, 0.335445147f, + -0.942573198f, 0.333999651f, + -0.943084437f, 0.332553370f, + -0.943593458f, 0.331106306f, + -0.944100258f, 0.329658463f, + -0.944604837f, 0.328209844f, + -0.945107193f, 0.326760452f, + -0.945607325f, 0.325310292f, + -0.946105232f, 0.323859367f, + -0.946600913f, 0.322407679f, + -0.947094366f, 0.320955232f, + -0.947585591f, 0.319502031f, + -0.948074586f, 0.318048077f, + -0.948561350f, 0.316593376f, + -0.949045882f, 0.315137929f, + -0.949528181f, 0.313681740f, + -0.950008245f, 0.312224814f, + -0.950486074f, 0.310767153f, + -0.950961666f, 0.309308760f, + -0.951435021f, 0.307849640f, + -0.951906137f, 0.306389795f, + -0.952375013f, 0.304929230f, + -0.952841648f, 0.303467947f, + -0.953306040f, 0.302005949f, + -0.953768190f, 0.300543241f, + -0.954228095f, 0.299079826f, + -0.954685755f, 0.297615707f, + -0.955141168f, 0.296150888f, + -0.955594334f, 0.294685372f, + -0.956045251f, 0.293219163f, + -0.956493919f, 0.291752263f, + -0.956940336f, 0.290284677f, + -0.957384501f, 0.288816408f, + -0.957826413f, 0.287347460f, + -0.958266071f, 0.285877835f, + -0.958703475f, 0.284407537f, + -0.959138622f, 0.282936570f, + -0.959571513f, 0.281464938f, + -0.960002146f, 0.279992643f, + -0.960430519f, 0.278519689f, + -0.960856633f, 0.277046080f, + -0.961280486f, 0.275571819f, + -0.961702077f, 0.274096910f, + -0.962121404f, 0.272621355f, + -0.962538468f, 0.271145160f, + -0.962953267f, 0.269668326f, + -0.963365800f, 0.268190857f, + -0.963776066f, 0.266712757f, + -0.964184064f, 0.265234030f, + -0.964589793f, 0.263754679f, + -0.964993253f, 0.262274707f, + -0.965394442f, 0.260794118f, + -0.965793359f, 0.259312915f, + -0.966190003f, 0.257831102f, + -0.966584374f, 0.256348682f, + -0.966976471f, 0.254865660f, + -0.967366292f, 0.253382037f, + -0.967753837f, 0.251897818f, + -0.968139105f, 0.250413007f, + -0.968522094f, 0.248927606f, + -0.968902805f, 0.247441619f, + -0.969281235f, 0.245955050f, + -0.969657385f, 0.244467903f, + -0.970031253f, 0.242980180f, + -0.970402839f, 0.241491885f, + -0.970772141f, 0.240003022f, + -0.971139158f, 0.238513595f, + -0.971503891f, 0.237023606f, + -0.971866337f, 0.235533059f, + -0.972226497f, 0.234041959f, + -0.972584369f, 0.232550307f, + -0.972939952f, 0.231058108f, + -0.973293246f, 0.229565366f, + -0.973644250f, 0.228072083f, + -0.973992962f, 0.226578264f, + -0.974339383f, 0.225083911f, + -0.974683511f, 0.223589029f, + -0.975025345f, 0.222093621f, + -0.975364885f, 0.220597690f, + -0.975702130f, 0.219101240f, + -0.976037079f, 0.217604275f, + -0.976369731f, 0.216106797f, + -0.976700086f, 0.214608811f, + -0.977028143f, 0.213110320f, + -0.977353900f, 0.211611327f, + -0.977677358f, 0.210111837f, + -0.977998515f, 0.208611852f, + -0.978317371f, 0.207111376f, + -0.978633924f, 0.205610413f, + -0.978948175f, 0.204108966f, + -0.979260123f, 0.202607039f, + -0.979569766f, 0.201104635f, + -0.979877104f, 0.199601758f, + -0.980182136f, 0.198098411f, + -0.980484862f, 0.196594598f, + -0.980785280f, 0.195090322f, + -0.981083391f, 0.193585587f, + -0.981379193f, 0.192080397f, + -0.981672686f, 0.190574755f, + -0.981963869f, 0.189068664f, + -0.982252741f, 0.187562129f, + -0.982539302f, 0.186055152f, + -0.982823551f, 0.184547737f, + -0.983105487f, 0.183039888f, + -0.983385110f, 0.181531608f, + -0.983662419f, 0.180022901f, + -0.983937413f, 0.178513771f, + -0.984210092f, 0.177004220f, + -0.984480455f, 0.175494253f, + -0.984748502f, 0.173983873f, + -0.985014231f, 0.172473084f, + -0.985277642f, 0.170961889f, + -0.985538735f, 0.169450291f, + -0.985797509f, 0.167938295f, + -0.986053963f, 0.166425904f, + -0.986308097f, 0.164913120f, + -0.986559910f, 0.163399949f, + -0.986809402f, 0.161886394f, + -0.987056571f, 0.160372457f, + -0.987301418f, 0.158858143f, + -0.987543942f, 0.157343456f, + -0.987784142f, 0.155828398f, + -0.988022017f, 0.154312973f, + -0.988257568f, 0.152797185f, + -0.988490793f, 0.151281038f, + -0.988721692f, 0.149764535f, + -0.988950265f, 0.148247679f, + -0.989176510f, 0.146730474f, + -0.989400428f, 0.145212925f, + -0.989622017f, 0.143695033f, + -0.989841278f, 0.142176804f, + -0.990058210f, 0.140658239f, + -0.990272812f, 0.139139344f, + -0.990485084f, 0.137620122f, + -0.990695025f, 0.136100575f, + -0.990902635f, 0.134580709f, + -0.991107914f, 0.133060525f, + -0.991310860f, 0.131540029f, + -0.991511473f, 0.130019223f, + -0.991709754f, 0.128498111f, + -0.991905700f, 0.126976696f, + -0.992099313f, 0.125454983f, + -0.992290591f, 0.123932975f, + -0.992479535f, 0.122410675f, + -0.992666142f, 0.120888087f, + -0.992850414f, 0.119365215f, + -0.993032350f, 0.117842062f, + -0.993211949f, 0.116318631f, + -0.993389211f, 0.114794927f, + -0.993564136f, 0.113270952f, + -0.993736722f, 0.111746711f, + -0.993906970f, 0.110222207f, + -0.994074879f, 0.108697444f, + -0.994240449f, 0.107172425f, + -0.994403680f, 0.105647154f, + -0.994564571f, 0.104121634f, + -0.994723121f, 0.102595869f, + -0.994879331f, 0.101069863f, + -0.995033199f, 0.099543619f, + -0.995184727f, 0.098017140f, + -0.995333912f, 0.096490431f, + -0.995480755f, 0.094963495f, + -0.995625256f, 0.093436336f, + -0.995767414f, 0.091908956f, + -0.995907229f, 0.090381361f, + -0.996044701f, 0.088853553f, + -0.996179829f, 0.087325535f, + -0.996312612f, 0.085797312f, + -0.996443051f, 0.084268888f, + -0.996571146f, 0.082740265f, + -0.996696895f, 0.081211447f, + -0.996820299f, 0.079682438f, + -0.996941358f, 0.078153242f, + -0.997060070f, 0.076623861f, + -0.997176437f, 0.075094301f, + -0.997290457f, 0.073564564f, + -0.997402130f, 0.072034653f, + -0.997511456f, 0.070504573f, + -0.997618435f, 0.068974328f, + -0.997723067f, 0.067443920f, + -0.997825350f, 0.065913353f, + -0.997925286f, 0.064382631f, + -0.998022874f, 0.062851758f, + -0.998118113f, 0.061320736f, + -0.998211003f, 0.059789571f, + -0.998301545f, 0.058258265f, + -0.998389737f, 0.056726821f, + -0.998475581f, 0.055195244f, + -0.998559074f, 0.053663538f, + -0.998640218f, 0.052131705f, + -0.998719012f, 0.050599749f, + -0.998795456f, 0.049067674f, + -0.998869550f, 0.047535484f, + -0.998941293f, 0.046003182f, + -0.999010686f, 0.044470772f, + -0.999077728f, 0.042938257f, + -0.999142419f, 0.041405641f, + -0.999204759f, 0.039872928f, + -0.999264747f, 0.038340120f, + -0.999322385f, 0.036807223f, + -0.999377670f, 0.035274239f, + -0.999430605f, 0.033741172f, + -0.999481187f, 0.032208025f, + -0.999529418f, 0.030674803f, + -0.999575296f, 0.029141509f, + -0.999618822f, 0.027608146f, + -0.999659997f, 0.026074718f, + -0.999698819f, 0.024541229f, + -0.999735288f, 0.023007681f, + -0.999769405f, 0.021474080f, + -0.999801170f, 0.019940429f, + -0.999830582f, 0.018406730f, + -0.999857641f, 0.016872988f, + -0.999882347f, 0.015339206f, + -0.999904701f, 0.013805389f, + -0.999924702f, 0.012271538f, + -0.999942350f, 0.010737659f, + -0.999957645f, 0.009203755f, + -0.999970586f, 0.007669829f, + -0.999981175f, 0.006135885f, + -0.999989411f, 0.004601926f, + -0.999995294f, 0.003067957f, + -0.999998823f, 0.001533980f, + -1.000000000f, 0.000000000f, + -0.999998823f, -0.001533980f, + -0.999995294f, -0.003067957f, + -0.999989411f, -0.004601926f, + -0.999981175f, -0.006135885f, + -0.999970586f, -0.007669829f, + -0.999957645f, -0.009203755f, + -0.999942350f, -0.010737659f, + -0.999924702f, -0.012271538f, + -0.999904701f, -0.013805389f, + -0.999882347f, -0.015339206f, + -0.999857641f, -0.016872988f, + -0.999830582f, -0.018406730f, + -0.999801170f, -0.019940429f, + -0.999769405f, -0.021474080f, + -0.999735288f, -0.023007681f, + -0.999698819f, -0.024541229f, + -0.999659997f, -0.026074718f, + -0.999618822f, -0.027608146f, + -0.999575296f, -0.029141509f, + -0.999529418f, -0.030674803f, + -0.999481187f, -0.032208025f, + -0.999430605f, -0.033741172f, + -0.999377670f, -0.035274239f, + -0.999322385f, -0.036807223f, + -0.999264747f, -0.038340120f, + -0.999204759f, -0.039872928f, + -0.999142419f, -0.041405641f, + -0.999077728f, -0.042938257f, + -0.999010686f, -0.044470772f, + -0.998941293f, -0.046003182f, + -0.998869550f, -0.047535484f, + -0.998795456f, -0.049067674f, + -0.998719012f, -0.050599749f, + -0.998640218f, -0.052131705f, + -0.998559074f, -0.053663538f, + -0.998475581f, -0.055195244f, + -0.998389737f, -0.056726821f, + -0.998301545f, -0.058258265f, + -0.998211003f, -0.059789571f, + -0.998118113f, -0.061320736f, + -0.998022874f, -0.062851758f, + -0.997925286f, -0.064382631f, + -0.997825350f, -0.065913353f, + -0.997723067f, -0.067443920f, + -0.997618435f, -0.068974328f, + -0.997511456f, -0.070504573f, + -0.997402130f, -0.072034653f, + -0.997290457f, -0.073564564f, + -0.997176437f, -0.075094301f, + -0.997060070f, -0.076623861f, + -0.996941358f, -0.078153242f, + -0.996820299f, -0.079682438f, + -0.996696895f, -0.081211447f, + -0.996571146f, -0.082740265f, + -0.996443051f, -0.084268888f, + -0.996312612f, -0.085797312f, + -0.996179829f, -0.087325535f, + -0.996044701f, -0.088853553f, + -0.995907229f, -0.090381361f, + -0.995767414f, -0.091908956f, + -0.995625256f, -0.093436336f, + -0.995480755f, -0.094963495f, + -0.995333912f, -0.096490431f, + -0.995184727f, -0.098017140f, + -0.995033199f, -0.099543619f, + -0.994879331f, -0.101069863f, + -0.994723121f, -0.102595869f, + -0.994564571f, -0.104121634f, + -0.994403680f, -0.105647154f, + -0.994240449f, -0.107172425f, + -0.994074879f, -0.108697444f, + -0.993906970f, -0.110222207f, + -0.993736722f, -0.111746711f, + -0.993564136f, -0.113270952f, + -0.993389211f, -0.114794927f, + -0.993211949f, -0.116318631f, + -0.993032350f, -0.117842062f, + -0.992850414f, -0.119365215f, + -0.992666142f, -0.120888087f, + -0.992479535f, -0.122410675f, + -0.992290591f, -0.123932975f, + -0.992099313f, -0.125454983f, + -0.991905700f, -0.126976696f, + -0.991709754f, -0.128498111f, + -0.991511473f, -0.130019223f, + -0.991310860f, -0.131540029f, + -0.991107914f, -0.133060525f, + -0.990902635f, -0.134580709f, + -0.990695025f, -0.136100575f, + -0.990485084f, -0.137620122f, + -0.990272812f, -0.139139344f, + -0.990058210f, -0.140658239f, + -0.989841278f, -0.142176804f, + -0.989622017f, -0.143695033f, + -0.989400428f, -0.145212925f, + -0.989176510f, -0.146730474f, + -0.988950265f, -0.148247679f, + -0.988721692f, -0.149764535f, + -0.988490793f, -0.151281038f, + -0.988257568f, -0.152797185f, + -0.988022017f, -0.154312973f, + -0.987784142f, -0.155828398f, + -0.987543942f, -0.157343456f, + -0.987301418f, -0.158858143f, + -0.987056571f, -0.160372457f, + -0.986809402f, -0.161886394f, + -0.986559910f, -0.163399949f, + -0.986308097f, -0.164913120f, + -0.986053963f, -0.166425904f, + -0.985797509f, -0.167938295f, + -0.985538735f, -0.169450291f, + -0.985277642f, -0.170961889f, + -0.985014231f, -0.172473084f, + -0.984748502f, -0.173983873f, + -0.984480455f, -0.175494253f, + -0.984210092f, -0.177004220f, + -0.983937413f, -0.178513771f, + -0.983662419f, -0.180022901f, + -0.983385110f, -0.181531608f, + -0.983105487f, -0.183039888f, + -0.982823551f, -0.184547737f, + -0.982539302f, -0.186055152f, + -0.982252741f, -0.187562129f, + -0.981963869f, -0.189068664f, + -0.981672686f, -0.190574755f, + -0.981379193f, -0.192080397f, + -0.981083391f, -0.193585587f, + -0.980785280f, -0.195090322f, + -0.980484862f, -0.196594598f, + -0.980182136f, -0.198098411f, + -0.979877104f, -0.199601758f, + -0.979569766f, -0.201104635f, + -0.979260123f, -0.202607039f, + -0.978948175f, -0.204108966f, + -0.978633924f, -0.205610413f, + -0.978317371f, -0.207111376f, + -0.977998515f, -0.208611852f, + -0.977677358f, -0.210111837f, + -0.977353900f, -0.211611327f, + -0.977028143f, -0.213110320f, + -0.976700086f, -0.214608811f, + -0.976369731f, -0.216106797f, + -0.976037079f, -0.217604275f, + -0.975702130f, -0.219101240f, + -0.975364885f, -0.220597690f, + -0.975025345f, -0.222093621f, + -0.974683511f, -0.223589029f, + -0.974339383f, -0.225083911f, + -0.973992962f, -0.226578264f, + -0.973644250f, -0.228072083f, + -0.973293246f, -0.229565366f, + -0.972939952f, -0.231058108f, + -0.972584369f, -0.232550307f, + -0.972226497f, -0.234041959f, + -0.971866337f, -0.235533059f, + -0.971503891f, -0.237023606f, + -0.971139158f, -0.238513595f, + -0.970772141f, -0.240003022f, + -0.970402839f, -0.241491885f, + -0.970031253f, -0.242980180f, + -0.969657385f, -0.244467903f, + -0.969281235f, -0.245955050f, + -0.968902805f, -0.247441619f, + -0.968522094f, -0.248927606f, + -0.968139105f, -0.250413007f, + -0.967753837f, -0.251897818f, + -0.967366292f, -0.253382037f, + -0.966976471f, -0.254865660f, + -0.966584374f, -0.256348682f, + -0.966190003f, -0.257831102f, + -0.965793359f, -0.259312915f, + -0.965394442f, -0.260794118f, + -0.964993253f, -0.262274707f, + -0.964589793f, -0.263754679f, + -0.964184064f, -0.265234030f, + -0.963776066f, -0.266712757f, + -0.963365800f, -0.268190857f, + -0.962953267f, -0.269668326f, + -0.962538468f, -0.271145160f, + -0.962121404f, -0.272621355f, + -0.961702077f, -0.274096910f, + -0.961280486f, -0.275571819f, + -0.960856633f, -0.277046080f, + -0.960430519f, -0.278519689f, + -0.960002146f, -0.279992643f, + -0.959571513f, -0.281464938f, + -0.959138622f, -0.282936570f, + -0.958703475f, -0.284407537f, + -0.958266071f, -0.285877835f, + -0.957826413f, -0.287347460f, + -0.957384501f, -0.288816408f, + -0.956940336f, -0.290284677f, + -0.956493919f, -0.291752263f, + -0.956045251f, -0.293219163f, + -0.955594334f, -0.294685372f, + -0.955141168f, -0.296150888f, + -0.954685755f, -0.297615707f, + -0.954228095f, -0.299079826f, + -0.953768190f, -0.300543241f, + -0.953306040f, -0.302005949f, + -0.952841648f, -0.303467947f, + -0.952375013f, -0.304929230f, + -0.951906137f, -0.306389795f, + -0.951435021f, -0.307849640f, + -0.950961666f, -0.309308760f, + -0.950486074f, -0.310767153f, + -0.950008245f, -0.312224814f, + -0.949528181f, -0.313681740f, + -0.949045882f, -0.315137929f, + -0.948561350f, -0.316593376f, + -0.948074586f, -0.318048077f, + -0.947585591f, -0.319502031f, + -0.947094366f, -0.320955232f, + -0.946600913f, -0.322407679f, + -0.946105232f, -0.323859367f, + -0.945607325f, -0.325310292f, + -0.945107193f, -0.326760452f, + -0.944604837f, -0.328209844f, + -0.944100258f, -0.329658463f, + -0.943593458f, -0.331106306f, + -0.943084437f, -0.332553370f, + -0.942573198f, -0.333999651f, + -0.942059740f, -0.335445147f, + -0.941544065f, -0.336889853f, + -0.941026175f, -0.338333767f, + -0.940506071f, -0.339776884f, + -0.939983753f, -0.341219202f, + -0.939459224f, -0.342660717f, + -0.938932484f, -0.344101426f, + -0.938403534f, -0.345541325f, + -0.937872376f, -0.346980411f, + -0.937339012f, -0.348418680f, + -0.936803442f, -0.349856130f, + -0.936265667f, -0.351292756f, + -0.935725689f, -0.352728556f, + -0.935183510f, -0.354163525f, + -0.934639130f, -0.355597662f, + -0.934092550f, -0.357030961f, + -0.933543773f, -0.358463421f, + -0.932992799f, -0.359895037f, + -0.932439629f, -0.361325806f, + -0.931884266f, -0.362755724f, + -0.931326709f, -0.364184790f, + -0.930766961f, -0.365612998f, + -0.930205023f, -0.367040346f, + -0.929640896f, -0.368466830f, + -0.929074581f, -0.369892447f, + -0.928506080f, -0.371317194f, + -0.927935395f, -0.372741067f, + -0.927362526f, -0.374164063f, + -0.926787474f, -0.375586178f, + -0.926210242f, -0.377007410f, + -0.925630831f, -0.378427755f, + -0.925049241f, -0.379847209f, + -0.924465474f, -0.381265769f, + -0.923879533f, -0.382683432f, + -0.923291417f, -0.384100195f, + -0.922701128f, -0.385516054f, + -0.922108669f, -0.386931006f, + -0.921514039f, -0.388345047f, + -0.920917242f, -0.389758174f, + -0.920318277f, -0.391170384f, + -0.919717146f, -0.392581674f, + -0.919113852f, -0.393992040f, + -0.918508394f, -0.395401479f, + -0.917900776f, -0.396809987f, + -0.917290997f, -0.398217562f, + -0.916679060f, -0.399624200f, + -0.916064966f, -0.401029897f, + -0.915448716f, -0.402434651f, + -0.914830312f, -0.403838458f, + -0.914209756f, -0.405241314f, + -0.913587048f, -0.406643217f, + -0.912962190f, -0.408044163f, + -0.912335185f, -0.409444149f, + -0.911706032f, -0.410843171f, + -0.911074734f, -0.412241227f, + -0.910441292f, -0.413638312f, + -0.909805708f, -0.415034424f, + -0.909167983f, -0.416429560f, + -0.908528119f, -0.417823716f, + -0.907886116f, -0.419216888f, + -0.907241978f, -0.420609074f, + -0.906595705f, -0.422000271f, + -0.905947298f, -0.423390474f, + -0.905296759f, -0.424779681f, + -0.904644091f, -0.426167889f, + -0.903989293f, -0.427555093f, + -0.903332368f, -0.428941292f, + -0.902673318f, -0.430326481f, + -0.902012144f, -0.431710658f, + -0.901348847f, -0.433093819f, + -0.900683429f, -0.434475961f, + -0.900015892f, -0.435857080f, + -0.899346237f, -0.437237174f, + -0.898674466f, -0.438616239f, + -0.898000580f, -0.439994271f, + -0.897324581f, -0.441371269f, + -0.896646470f, -0.442747228f, + -0.895966250f, -0.444122145f, + -0.895283921f, -0.445496017f, + -0.894599486f, -0.446868840f, + -0.893912945f, -0.448240612f, + -0.893224301f, -0.449611330f, + -0.892533555f, -0.450980989f, + -0.891840709f, -0.452349587f, + -0.891145765f, -0.453717121f, + -0.890448723f, -0.455083587f, + -0.889749586f, -0.456448982f, + -0.889048356f, -0.457813304f, + -0.888345033f, -0.459176548f, + -0.887639620f, -0.460538711f, + -0.886932119f, -0.461899791f, + -0.886222530f, -0.463259784f, + -0.885510856f, -0.464618686f, + -0.884797098f, -0.465976496f, + -0.884081259f, -0.467333209f, + -0.883363339f, -0.468688822f, + -0.882643340f, -0.470043332f, + -0.881921264f, -0.471396737f, + -0.881197113f, -0.472749032f, + -0.880470889f, -0.474100215f, + -0.879742593f, -0.475450282f, + -0.879012226f, -0.476799230f, + -0.878279792f, -0.478147056f, + -0.877545290f, -0.479493758f, + -0.876808724f, -0.480839331f, + -0.876070094f, -0.482183772f, + -0.875329403f, -0.483527079f, + -0.874586652f, -0.484869248f, + -0.873841843f, -0.486210276f, + -0.873094978f, -0.487550160f, + -0.872346059f, -0.488888897f, + -0.871595087f, -0.490226483f, + -0.870842063f, -0.491562916f, + -0.870086991f, -0.492898192f, + -0.869329871f, -0.494232309f, + -0.868570706f, -0.495565262f, + -0.867809497f, -0.496897049f, + -0.867046246f, -0.498227667f, + -0.866280954f, -0.499557113f, + -0.865513624f, -0.500885383f, + -0.864744258f, -0.502212474f, + -0.863972856f, -0.503538384f, + -0.863199422f, -0.504863109f, + -0.862423956f, -0.506186645f, + -0.861646461f, -0.507508991f, + -0.860866939f, -0.508830143f, + -0.860085390f, -0.510150097f, + -0.859301818f, -0.511468850f, + -0.858516224f, -0.512786401f, + -0.857728610f, -0.514102744f, + -0.856938977f, -0.515417878f, + -0.856147328f, -0.516731799f, + -0.855353665f, -0.518044504f, + -0.854557988f, -0.519355990f, + -0.853760301f, -0.520666254f, + -0.852960605f, -0.521975293f, + -0.852158902f, -0.523283103f, + -0.851355193f, -0.524589683f, + -0.850549481f, -0.525895027f, + -0.849741768f, -0.527199135f, + -0.848932055f, -0.528502002f, + -0.848120345f, -0.529803625f, + -0.847306639f, -0.531104001f, + -0.846490939f, -0.532403128f, + -0.845673247f, -0.533701002f, + -0.844853565f, -0.534997620f, + -0.844031895f, -0.536292979f, + -0.843208240f, -0.537587076f, + -0.842382600f, -0.538879909f, + -0.841554977f, -0.540171473f, + -0.840725375f, -0.541461766f, + -0.839893794f, -0.542750785f, + -0.839060237f, -0.544038527f, + -0.838224706f, -0.545324988f, + -0.837387202f, -0.546610167f, + -0.836547727f, -0.547894059f, + -0.835706284f, -0.549176662f, + -0.834862875f, -0.550457973f, + -0.834017501f, -0.551737988f, + -0.833170165f, -0.553016706f, + -0.832320868f, -0.554294121f, + -0.831469612f, -0.555570233f, + -0.830616400f, -0.556845037f, + -0.829761234f, -0.558118531f, + -0.828904115f, -0.559390712f, + -0.828045045f, -0.560661576f, + -0.827184027f, -0.561931121f, + -0.826321063f, -0.563199344f, + -0.825456154f, -0.564466242f, + -0.824589303f, -0.565731811f, + -0.823720511f, -0.566996049f, + -0.822849781f, -0.568258953f, + -0.821977115f, -0.569520519f, + -0.821102515f, -0.570780746f, + -0.820225983f, -0.572039629f, + -0.819347520f, -0.573297167f, + -0.818467130f, -0.574553355f, + -0.817584813f, -0.575808191f, + -0.816700573f, -0.577061673f, + -0.815814411f, -0.578313796f, + -0.814926329f, -0.579564559f, + -0.814036330f, -0.580813958f, + -0.813144415f, -0.582061990f, + -0.812250587f, -0.583308653f, + -0.811354847f, -0.584553943f, + -0.810457198f, -0.585797857f, + -0.809557642f, -0.587040394f, + -0.808656182f, -0.588281548f, + -0.807752818f, -0.589521319f, + -0.806847554f, -0.590759702f, + -0.805940391f, -0.591996695f, + -0.805031331f, -0.593232295f, + -0.804120377f, -0.594466499f, + -0.803207531f, -0.595699304f, + -0.802292796f, -0.596930708f, + -0.801376172f, -0.598160707f, + -0.800457662f, -0.599389298f, + -0.799537269f, -0.600616479f, + -0.798614995f, -0.601842247f, + -0.797690841f, -0.603066599f, + -0.796764810f, -0.604289531f, + -0.795836905f, -0.605511041f, + -0.794907126f, -0.606731127f, + -0.793975478f, -0.607949785f, + -0.793041960f, -0.609167012f, + -0.792106577f, -0.610382806f, + -0.791169330f, -0.611597164f, + -0.790230221f, -0.612810082f, + -0.789289253f, -0.614021559f, + -0.788346428f, -0.615231591f, + -0.787401747f, -0.616440175f, + -0.786455214f, -0.617647308f, + -0.785506830f, -0.618852988f, + -0.784556597f, -0.620057212f, + -0.783604519f, -0.621259977f, + -0.782650596f, -0.622461279f, + -0.781694832f, -0.623661118f, + -0.780737229f, -0.624859488f, + -0.779777788f, -0.626056388f, + -0.778816512f, -0.627251815f, + -0.777853404f, -0.628445767f, + -0.776888466f, -0.629638239f, + -0.775921699f, -0.630829230f, + -0.774953107f, -0.632018736f, + -0.773982691f, -0.633206755f, + -0.773010453f, -0.634393284f, + -0.772036397f, -0.635578320f, + -0.771060524f, -0.636761861f, + -0.770082837f, -0.637943904f, + -0.769103338f, -0.639124445f, + -0.768122029f, -0.640303482f, + -0.767138912f, -0.641481013f, + -0.766153990f, -0.642657034f, + -0.765167266f, -0.643831543f, + -0.764178741f, -0.645004537f, + -0.763188417f, -0.646176013f, + -0.762196298f, -0.647345969f, + -0.761202385f, -0.648514401f, + -0.760206682f, -0.649681307f, + -0.759209189f, -0.650846685f, + -0.758209910f, -0.652010531f, + -0.757208847f, -0.653172843f, + -0.756206001f, -0.654333618f, + -0.755201377f, -0.655492853f, + -0.754194975f, -0.656650546f, + -0.753186799f, -0.657806693f, + -0.752176850f, -0.658961293f, + -0.751165132f, -0.660114342f, + -0.750151646f, -0.661265838f, + -0.749136395f, -0.662415778f, + -0.748119380f, -0.663564159f, + -0.747100606f, -0.664710978f, + -0.746080074f, -0.665856234f, + -0.745057785f, -0.666999922f, + -0.744033744f, -0.668142041f, + -0.743007952f, -0.669282588f, + -0.741980412f, -0.670421560f, + -0.740951125f, -0.671558955f, + -0.739920095f, -0.672694769f, + -0.738887324f, -0.673829000f, + -0.737852815f, -0.674961646f, + -0.736816569f, -0.676092704f, + -0.735778589f, -0.677222170f, + -0.734738878f, -0.678350043f, + -0.733697438f, -0.679476320f, + -0.732654272f, -0.680600998f, + -0.731609381f, -0.681724074f, + -0.730562769f, -0.682845546f, + -0.729514438f, -0.683965412f, + -0.728464390f, -0.685083668f, + -0.727412629f, -0.686200312f, + -0.726359155f, -0.687315341f, + -0.725303972f, -0.688428753f, + -0.724247083f, -0.689540545f, + -0.723188489f, -0.690650714f, + -0.722128194f, -0.691759258f, + -0.721066199f, -0.692866175f, + -0.720002508f, -0.693971461f, + -0.718937122f, -0.695075114f, + -0.717870045f, -0.696177131f, + -0.716801279f, -0.697277511f, + -0.715730825f, -0.698376249f, + -0.714658688f, -0.699473345f, + -0.713584869f, -0.700568794f, + -0.712509371f, -0.701662595f, + -0.711432196f, -0.702754744f, + -0.710353347f, -0.703845241f, + -0.709272826f, -0.704934080f, + -0.708190637f, -0.706021261f, + -0.707106781f, -0.707106781f, + -0.706021261f, -0.708190637f, + -0.704934080f, -0.709272826f, + -0.703845241f, -0.710353347f, + -0.702754744f, -0.711432196f, + -0.701662595f, -0.712509371f, + -0.700568794f, -0.713584869f, + -0.699473345f, -0.714658688f, + -0.698376249f, -0.715730825f, + -0.697277511f, -0.716801279f, + -0.696177131f, -0.717870045f, + -0.695075114f, -0.718937122f, + -0.693971461f, -0.720002508f, + -0.692866175f, -0.721066199f, + -0.691759258f, -0.722128194f, + -0.690650714f, -0.723188489f, + -0.689540545f, -0.724247083f, + -0.688428753f, -0.725303972f, + -0.687315341f, -0.726359155f, + -0.686200312f, -0.727412629f, + -0.685083668f, -0.728464390f, + -0.683965412f, -0.729514438f, + -0.682845546f, -0.730562769f, + -0.681724074f, -0.731609381f, + -0.680600998f, -0.732654272f, + -0.679476320f, -0.733697438f, + -0.678350043f, -0.734738878f, + -0.677222170f, -0.735778589f, + -0.676092704f, -0.736816569f, + -0.674961646f, -0.737852815f, + -0.673829000f, -0.738887324f, + -0.672694769f, -0.739920095f, + -0.671558955f, -0.740951125f, + -0.670421560f, -0.741980412f, + -0.669282588f, -0.743007952f, + -0.668142041f, -0.744033744f, + -0.666999922f, -0.745057785f, + -0.665856234f, -0.746080074f, + -0.664710978f, -0.747100606f, + -0.663564159f, -0.748119380f, + -0.662415778f, -0.749136395f, + -0.661265838f, -0.750151646f, + -0.660114342f, -0.751165132f, + -0.658961293f, -0.752176850f, + -0.657806693f, -0.753186799f, + -0.656650546f, -0.754194975f, + -0.655492853f, -0.755201377f, + -0.654333618f, -0.756206001f, + -0.653172843f, -0.757208847f, + -0.652010531f, -0.758209910f, + -0.650846685f, -0.759209189f, + -0.649681307f, -0.760206682f, + -0.648514401f, -0.761202385f, + -0.647345969f, -0.762196298f, + -0.646176013f, -0.763188417f, + -0.645004537f, -0.764178741f, + -0.643831543f, -0.765167266f, + -0.642657034f, -0.766153990f, + -0.641481013f, -0.767138912f, + -0.640303482f, -0.768122029f, + -0.639124445f, -0.769103338f, + -0.637943904f, -0.770082837f, + -0.636761861f, -0.771060524f, + -0.635578320f, -0.772036397f, + -0.634393284f, -0.773010453f, + -0.633206755f, -0.773982691f, + -0.632018736f, -0.774953107f, + -0.630829230f, -0.775921699f, + -0.629638239f, -0.776888466f, + -0.628445767f, -0.777853404f, + -0.627251815f, -0.778816512f, + -0.626056388f, -0.779777788f, + -0.624859488f, -0.780737229f, + -0.623661118f, -0.781694832f, + -0.622461279f, -0.782650596f, + -0.621259977f, -0.783604519f, + -0.620057212f, -0.784556597f, + -0.618852988f, -0.785506830f, + -0.617647308f, -0.786455214f, + -0.616440175f, -0.787401747f, + -0.615231591f, -0.788346428f, + -0.614021559f, -0.789289253f, + -0.612810082f, -0.790230221f, + -0.611597164f, -0.791169330f, + -0.610382806f, -0.792106577f, + -0.609167012f, -0.793041960f, + -0.607949785f, -0.793975478f, + -0.606731127f, -0.794907126f, + -0.605511041f, -0.795836905f, + -0.604289531f, -0.796764810f, + -0.603066599f, -0.797690841f, + -0.601842247f, -0.798614995f, + -0.600616479f, -0.799537269f, + -0.599389298f, -0.800457662f, + -0.598160707f, -0.801376172f, + -0.596930708f, -0.802292796f, + -0.595699304f, -0.803207531f, + -0.594466499f, -0.804120377f, + -0.593232295f, -0.805031331f, + -0.591996695f, -0.805940391f, + -0.590759702f, -0.806847554f, + -0.589521319f, -0.807752818f, + -0.588281548f, -0.808656182f, + -0.587040394f, -0.809557642f, + -0.585797857f, -0.810457198f, + -0.584553943f, -0.811354847f, + -0.583308653f, -0.812250587f, + -0.582061990f, -0.813144415f, + -0.580813958f, -0.814036330f, + -0.579564559f, -0.814926329f, + -0.578313796f, -0.815814411f, + -0.577061673f, -0.816700573f, + -0.575808191f, -0.817584813f, + -0.574553355f, -0.818467130f, + -0.573297167f, -0.819347520f, + -0.572039629f, -0.820225983f, + -0.570780746f, -0.821102515f, + -0.569520519f, -0.821977115f, + -0.568258953f, -0.822849781f, + -0.566996049f, -0.823720511f, + -0.565731811f, -0.824589303f, + -0.564466242f, -0.825456154f, + -0.563199344f, -0.826321063f, + -0.561931121f, -0.827184027f, + -0.560661576f, -0.828045045f, + -0.559390712f, -0.828904115f, + -0.558118531f, -0.829761234f, + -0.556845037f, -0.830616400f, + -0.555570233f, -0.831469612f, + -0.554294121f, -0.832320868f, + -0.553016706f, -0.833170165f, + -0.551737988f, -0.834017501f, + -0.550457973f, -0.834862875f, + -0.549176662f, -0.835706284f, + -0.547894059f, -0.836547727f, + -0.546610167f, -0.837387202f, + -0.545324988f, -0.838224706f, + -0.544038527f, -0.839060237f, + -0.542750785f, -0.839893794f, + -0.541461766f, -0.840725375f, + -0.540171473f, -0.841554977f, + -0.538879909f, -0.842382600f, + -0.537587076f, -0.843208240f, + -0.536292979f, -0.844031895f, + -0.534997620f, -0.844853565f, + -0.533701002f, -0.845673247f, + -0.532403128f, -0.846490939f, + -0.531104001f, -0.847306639f, + -0.529803625f, -0.848120345f, + -0.528502002f, -0.848932055f, + -0.527199135f, -0.849741768f, + -0.525895027f, -0.850549481f, + -0.524589683f, -0.851355193f, + -0.523283103f, -0.852158902f, + -0.521975293f, -0.852960605f, + -0.520666254f, -0.853760301f, + -0.519355990f, -0.854557988f, + -0.518044504f, -0.855353665f, + -0.516731799f, -0.856147328f, + -0.515417878f, -0.856938977f, + -0.514102744f, -0.857728610f, + -0.512786401f, -0.858516224f, + -0.511468850f, -0.859301818f, + -0.510150097f, -0.860085390f, + -0.508830143f, -0.860866939f, + -0.507508991f, -0.861646461f, + -0.506186645f, -0.862423956f, + -0.504863109f, -0.863199422f, + -0.503538384f, -0.863972856f, + -0.502212474f, -0.864744258f, + -0.500885383f, -0.865513624f, + -0.499557113f, -0.866280954f, + -0.498227667f, -0.867046246f, + -0.496897049f, -0.867809497f, + -0.495565262f, -0.868570706f, + -0.494232309f, -0.869329871f, + -0.492898192f, -0.870086991f, + -0.491562916f, -0.870842063f, + -0.490226483f, -0.871595087f, + -0.488888897f, -0.872346059f, + -0.487550160f, -0.873094978f, + -0.486210276f, -0.873841843f, + -0.484869248f, -0.874586652f, + -0.483527079f, -0.875329403f, + -0.482183772f, -0.876070094f, + -0.480839331f, -0.876808724f, + -0.479493758f, -0.877545290f, + -0.478147056f, -0.878279792f, + -0.476799230f, -0.879012226f, + -0.475450282f, -0.879742593f, + -0.474100215f, -0.880470889f, + -0.472749032f, -0.881197113f, + -0.471396737f, -0.881921264f, + -0.470043332f, -0.882643340f, + -0.468688822f, -0.883363339f, + -0.467333209f, -0.884081259f, + -0.465976496f, -0.884797098f, + -0.464618686f, -0.885510856f, + -0.463259784f, -0.886222530f, + -0.461899791f, -0.886932119f, + -0.460538711f, -0.887639620f, + -0.459176548f, -0.888345033f, + -0.457813304f, -0.889048356f, + -0.456448982f, -0.889749586f, + -0.455083587f, -0.890448723f, + -0.453717121f, -0.891145765f, + -0.452349587f, -0.891840709f, + -0.450980989f, -0.892533555f, + -0.449611330f, -0.893224301f, + -0.448240612f, -0.893912945f, + -0.446868840f, -0.894599486f, + -0.445496017f, -0.895283921f, + -0.444122145f, -0.895966250f, + -0.442747228f, -0.896646470f, + -0.441371269f, -0.897324581f, + -0.439994271f, -0.898000580f, + -0.438616239f, -0.898674466f, + -0.437237174f, -0.899346237f, + -0.435857080f, -0.900015892f, + -0.434475961f, -0.900683429f, + -0.433093819f, -0.901348847f, + -0.431710658f, -0.902012144f, + -0.430326481f, -0.902673318f, + -0.428941292f, -0.903332368f, + -0.427555093f, -0.903989293f, + -0.426167889f, -0.904644091f, + -0.424779681f, -0.905296759f, + -0.423390474f, -0.905947298f, + -0.422000271f, -0.906595705f, + -0.420609074f, -0.907241978f, + -0.419216888f, -0.907886116f, + -0.417823716f, -0.908528119f, + -0.416429560f, -0.909167983f, + -0.415034424f, -0.909805708f, + -0.413638312f, -0.910441292f, + -0.412241227f, -0.911074734f, + -0.410843171f, -0.911706032f, + -0.409444149f, -0.912335185f, + -0.408044163f, -0.912962190f, + -0.406643217f, -0.913587048f, + -0.405241314f, -0.914209756f, + -0.403838458f, -0.914830312f, + -0.402434651f, -0.915448716f, + -0.401029897f, -0.916064966f, + -0.399624200f, -0.916679060f, + -0.398217562f, -0.917290997f, + -0.396809987f, -0.917900776f, + -0.395401479f, -0.918508394f, + -0.393992040f, -0.919113852f, + -0.392581674f, -0.919717146f, + -0.391170384f, -0.920318277f, + -0.389758174f, -0.920917242f, + -0.388345047f, -0.921514039f, + -0.386931006f, -0.922108669f, + -0.385516054f, -0.922701128f, + -0.384100195f, -0.923291417f, + -0.382683432f, -0.923879533f, + -0.381265769f, -0.924465474f, + -0.379847209f, -0.925049241f, + -0.378427755f, -0.925630831f, + -0.377007410f, -0.926210242f, + -0.375586178f, -0.926787474f, + -0.374164063f, -0.927362526f, + -0.372741067f, -0.927935395f, + -0.371317194f, -0.928506080f, + -0.369892447f, -0.929074581f, + -0.368466830f, -0.929640896f, + -0.367040346f, -0.930205023f, + -0.365612998f, -0.930766961f, + -0.364184790f, -0.931326709f, + -0.362755724f, -0.931884266f, + -0.361325806f, -0.932439629f, + -0.359895037f, -0.932992799f, + -0.358463421f, -0.933543773f, + -0.357030961f, -0.934092550f, + -0.355597662f, -0.934639130f, + -0.354163525f, -0.935183510f, + -0.352728556f, -0.935725689f, + -0.351292756f, -0.936265667f, + -0.349856130f, -0.936803442f, + -0.348418680f, -0.937339012f, + -0.346980411f, -0.937872376f, + -0.345541325f, -0.938403534f, + -0.344101426f, -0.938932484f, + -0.342660717f, -0.939459224f, + -0.341219202f, -0.939983753f, + -0.339776884f, -0.940506071f, + -0.338333767f, -0.941026175f, + -0.336889853f, -0.941544065f, + -0.335445147f, -0.942059740f, + -0.333999651f, -0.942573198f, + -0.332553370f, -0.943084437f, + -0.331106306f, -0.943593458f, + -0.329658463f, -0.944100258f, + -0.328209844f, -0.944604837f, + -0.326760452f, -0.945107193f, + -0.325310292f, -0.945607325f, + -0.323859367f, -0.946105232f, + -0.322407679f, -0.946600913f, + -0.320955232f, -0.947094366f, + -0.319502031f, -0.947585591f, + -0.318048077f, -0.948074586f, + -0.316593376f, -0.948561350f, + -0.315137929f, -0.949045882f, + -0.313681740f, -0.949528181f, + -0.312224814f, -0.950008245f, + -0.310767153f, -0.950486074f, + -0.309308760f, -0.950961666f, + -0.307849640f, -0.951435021f, + -0.306389795f, -0.951906137f, + -0.304929230f, -0.952375013f, + -0.303467947f, -0.952841648f, + -0.302005949f, -0.953306040f, + -0.300543241f, -0.953768190f, + -0.299079826f, -0.954228095f, + -0.297615707f, -0.954685755f, + -0.296150888f, -0.955141168f, + -0.294685372f, -0.955594334f, + -0.293219163f, -0.956045251f, + -0.291752263f, -0.956493919f, + -0.290284677f, -0.956940336f, + -0.288816408f, -0.957384501f, + -0.287347460f, -0.957826413f, + -0.285877835f, -0.958266071f, + -0.284407537f, -0.958703475f, + -0.282936570f, -0.959138622f, + -0.281464938f, -0.959571513f, + -0.279992643f, -0.960002146f, + -0.278519689f, -0.960430519f, + -0.277046080f, -0.960856633f, + -0.275571819f, -0.961280486f, + -0.274096910f, -0.961702077f, + -0.272621355f, -0.962121404f, + -0.271145160f, -0.962538468f, + -0.269668326f, -0.962953267f, + -0.268190857f, -0.963365800f, + -0.266712757f, -0.963776066f, + -0.265234030f, -0.964184064f, + -0.263754679f, -0.964589793f, + -0.262274707f, -0.964993253f, + -0.260794118f, -0.965394442f, + -0.259312915f, -0.965793359f, + -0.257831102f, -0.966190003f, + -0.256348682f, -0.966584374f, + -0.254865660f, -0.966976471f, + -0.253382037f, -0.967366292f, + -0.251897818f, -0.967753837f, + -0.250413007f, -0.968139105f, + -0.248927606f, -0.968522094f, + -0.247441619f, -0.968902805f, + -0.245955050f, -0.969281235f, + -0.244467903f, -0.969657385f, + -0.242980180f, -0.970031253f, + -0.241491885f, -0.970402839f, + -0.240003022f, -0.970772141f, + -0.238513595f, -0.971139158f, + -0.237023606f, -0.971503891f, + -0.235533059f, -0.971866337f, + -0.234041959f, -0.972226497f, + -0.232550307f, -0.972584369f, + -0.231058108f, -0.972939952f, + -0.229565366f, -0.973293246f, + -0.228072083f, -0.973644250f, + -0.226578264f, -0.973992962f, + -0.225083911f, -0.974339383f, + -0.223589029f, -0.974683511f, + -0.222093621f, -0.975025345f, + -0.220597690f, -0.975364885f, + -0.219101240f, -0.975702130f, + -0.217604275f, -0.976037079f, + -0.216106797f, -0.976369731f, + -0.214608811f, -0.976700086f, + -0.213110320f, -0.977028143f, + -0.211611327f, -0.977353900f, + -0.210111837f, -0.977677358f, + -0.208611852f, -0.977998515f, + -0.207111376f, -0.978317371f, + -0.205610413f, -0.978633924f, + -0.204108966f, -0.978948175f, + -0.202607039f, -0.979260123f, + -0.201104635f, -0.979569766f, + -0.199601758f, -0.979877104f, + -0.198098411f, -0.980182136f, + -0.196594598f, -0.980484862f, + -0.195090322f, -0.980785280f, + -0.193585587f, -0.981083391f, + -0.192080397f, -0.981379193f, + -0.190574755f, -0.981672686f, + -0.189068664f, -0.981963869f, + -0.187562129f, -0.982252741f, + -0.186055152f, -0.982539302f, + -0.184547737f, -0.982823551f, + -0.183039888f, -0.983105487f, + -0.181531608f, -0.983385110f, + -0.180022901f, -0.983662419f, + -0.178513771f, -0.983937413f, + -0.177004220f, -0.984210092f, + -0.175494253f, -0.984480455f, + -0.173983873f, -0.984748502f, + -0.172473084f, -0.985014231f, + -0.170961889f, -0.985277642f, + -0.169450291f, -0.985538735f, + -0.167938295f, -0.985797509f, + -0.166425904f, -0.986053963f, + -0.164913120f, -0.986308097f, + -0.163399949f, -0.986559910f, + -0.161886394f, -0.986809402f, + -0.160372457f, -0.987056571f, + -0.158858143f, -0.987301418f, + -0.157343456f, -0.987543942f, + -0.155828398f, -0.987784142f, + -0.154312973f, -0.988022017f, + -0.152797185f, -0.988257568f, + -0.151281038f, -0.988490793f, + -0.149764535f, -0.988721692f, + -0.148247679f, -0.988950265f, + -0.146730474f, -0.989176510f, + -0.145212925f, -0.989400428f, + -0.143695033f, -0.989622017f, + -0.142176804f, -0.989841278f, + -0.140658239f, -0.990058210f, + -0.139139344f, -0.990272812f, + -0.137620122f, -0.990485084f, + -0.136100575f, -0.990695025f, + -0.134580709f, -0.990902635f, + -0.133060525f, -0.991107914f, + -0.131540029f, -0.991310860f, + -0.130019223f, -0.991511473f, + -0.128498111f, -0.991709754f, + -0.126976696f, -0.991905700f, + -0.125454983f, -0.992099313f, + -0.123932975f, -0.992290591f, + -0.122410675f, -0.992479535f, + -0.120888087f, -0.992666142f, + -0.119365215f, -0.992850414f, + -0.117842062f, -0.993032350f, + -0.116318631f, -0.993211949f, + -0.114794927f, -0.993389211f, + -0.113270952f, -0.993564136f, + -0.111746711f, -0.993736722f, + -0.110222207f, -0.993906970f, + -0.108697444f, -0.994074879f, + -0.107172425f, -0.994240449f, + -0.105647154f, -0.994403680f, + -0.104121634f, -0.994564571f, + -0.102595869f, -0.994723121f, + -0.101069863f, -0.994879331f, + -0.099543619f, -0.995033199f, + -0.098017140f, -0.995184727f, + -0.096490431f, -0.995333912f, + -0.094963495f, -0.995480755f, + -0.093436336f, -0.995625256f, + -0.091908956f, -0.995767414f, + -0.090381361f, -0.995907229f, + -0.088853553f, -0.996044701f, + -0.087325535f, -0.996179829f, + -0.085797312f, -0.996312612f, + -0.084268888f, -0.996443051f, + -0.082740265f, -0.996571146f, + -0.081211447f, -0.996696895f, + -0.079682438f, -0.996820299f, + -0.078153242f, -0.996941358f, + -0.076623861f, -0.997060070f, + -0.075094301f, -0.997176437f, + -0.073564564f, -0.997290457f, + -0.072034653f, -0.997402130f, + -0.070504573f, -0.997511456f, + -0.068974328f, -0.997618435f, + -0.067443920f, -0.997723067f, + -0.065913353f, -0.997825350f, + -0.064382631f, -0.997925286f, + -0.062851758f, -0.998022874f, + -0.061320736f, -0.998118113f, + -0.059789571f, -0.998211003f, + -0.058258265f, -0.998301545f, + -0.056726821f, -0.998389737f, + -0.055195244f, -0.998475581f, + -0.053663538f, -0.998559074f, + -0.052131705f, -0.998640218f, + -0.050599749f, -0.998719012f, + -0.049067674f, -0.998795456f, + -0.047535484f, -0.998869550f, + -0.046003182f, -0.998941293f, + -0.044470772f, -0.999010686f, + -0.042938257f, -0.999077728f, + -0.041405641f, -0.999142419f, + -0.039872928f, -0.999204759f, + -0.038340120f, -0.999264747f, + -0.036807223f, -0.999322385f, + -0.035274239f, -0.999377670f, + -0.033741172f, -0.999430605f, + -0.032208025f, -0.999481187f, + -0.030674803f, -0.999529418f, + -0.029141509f, -0.999575296f, + -0.027608146f, -0.999618822f, + -0.026074718f, -0.999659997f, + -0.024541229f, -0.999698819f, + -0.023007681f, -0.999735288f, + -0.021474080f, -0.999769405f, + -0.019940429f, -0.999801170f, + -0.018406730f, -0.999830582f, + -0.016872988f, -0.999857641f, + -0.015339206f, -0.999882347f, + -0.013805389f, -0.999904701f, + -0.012271538f, -0.999924702f, + -0.010737659f, -0.999942350f, + -0.009203755f, -0.999957645f, + -0.007669829f, -0.999970586f, + -0.006135885f, -0.999981175f, + -0.004601926f, -0.999989411f, + -0.003067957f, -0.999995294f, + -0.001533980f, -0.999998823f, + -0.000000000f, -1.000000000f, + 0.001533980f, -0.999998823f, + 0.003067957f, -0.999995294f, + 0.004601926f, -0.999989411f, + 0.006135885f, -0.999981175f, + 0.007669829f, -0.999970586f, + 0.009203755f, -0.999957645f, + 0.010737659f, -0.999942350f, + 0.012271538f, -0.999924702f, + 0.013805389f, -0.999904701f, + 0.015339206f, -0.999882347f, + 0.016872988f, -0.999857641f, + 0.018406730f, -0.999830582f, + 0.019940429f, -0.999801170f, + 0.021474080f, -0.999769405f, + 0.023007681f, -0.999735288f, + 0.024541229f, -0.999698819f, + 0.026074718f, -0.999659997f, + 0.027608146f, -0.999618822f, + 0.029141509f, -0.999575296f, + 0.030674803f, -0.999529418f, + 0.032208025f, -0.999481187f, + 0.033741172f, -0.999430605f, + 0.035274239f, -0.999377670f, + 0.036807223f, -0.999322385f, + 0.038340120f, -0.999264747f, + 0.039872928f, -0.999204759f, + 0.041405641f, -0.999142419f, + 0.042938257f, -0.999077728f, + 0.044470772f, -0.999010686f, + 0.046003182f, -0.998941293f, + 0.047535484f, -0.998869550f, + 0.049067674f, -0.998795456f, + 0.050599749f, -0.998719012f, + 0.052131705f, -0.998640218f, + 0.053663538f, -0.998559074f, + 0.055195244f, -0.998475581f, + 0.056726821f, -0.998389737f, + 0.058258265f, -0.998301545f, + 0.059789571f, -0.998211003f, + 0.061320736f, -0.998118113f, + 0.062851758f, -0.998022874f, + 0.064382631f, -0.997925286f, + 0.065913353f, -0.997825350f, + 0.067443920f, -0.997723067f, + 0.068974328f, -0.997618435f, + 0.070504573f, -0.997511456f, + 0.072034653f, -0.997402130f, + 0.073564564f, -0.997290457f, + 0.075094301f, -0.997176437f, + 0.076623861f, -0.997060070f, + 0.078153242f, -0.996941358f, + 0.079682438f, -0.996820299f, + 0.081211447f, -0.996696895f, + 0.082740265f, -0.996571146f, + 0.084268888f, -0.996443051f, + 0.085797312f, -0.996312612f, + 0.087325535f, -0.996179829f, + 0.088853553f, -0.996044701f, + 0.090381361f, -0.995907229f, + 0.091908956f, -0.995767414f, + 0.093436336f, -0.995625256f, + 0.094963495f, -0.995480755f, + 0.096490431f, -0.995333912f, + 0.098017140f, -0.995184727f, + 0.099543619f, -0.995033199f, + 0.101069863f, -0.994879331f, + 0.102595869f, -0.994723121f, + 0.104121634f, -0.994564571f, + 0.105647154f, -0.994403680f, + 0.107172425f, -0.994240449f, + 0.108697444f, -0.994074879f, + 0.110222207f, -0.993906970f, + 0.111746711f, -0.993736722f, + 0.113270952f, -0.993564136f, + 0.114794927f, -0.993389211f, + 0.116318631f, -0.993211949f, + 0.117842062f, -0.993032350f, + 0.119365215f, -0.992850414f, + 0.120888087f, -0.992666142f, + 0.122410675f, -0.992479535f, + 0.123932975f, -0.992290591f, + 0.125454983f, -0.992099313f, + 0.126976696f, -0.991905700f, + 0.128498111f, -0.991709754f, + 0.130019223f, -0.991511473f, + 0.131540029f, -0.991310860f, + 0.133060525f, -0.991107914f, + 0.134580709f, -0.990902635f, + 0.136100575f, -0.990695025f, + 0.137620122f, -0.990485084f, + 0.139139344f, -0.990272812f, + 0.140658239f, -0.990058210f, + 0.142176804f, -0.989841278f, + 0.143695033f, -0.989622017f, + 0.145212925f, -0.989400428f, + 0.146730474f, -0.989176510f, + 0.148247679f, -0.988950265f, + 0.149764535f, -0.988721692f, + 0.151281038f, -0.988490793f, + 0.152797185f, -0.988257568f, + 0.154312973f, -0.988022017f, + 0.155828398f, -0.987784142f, + 0.157343456f, -0.987543942f, + 0.158858143f, -0.987301418f, + 0.160372457f, -0.987056571f, + 0.161886394f, -0.986809402f, + 0.163399949f, -0.986559910f, + 0.164913120f, -0.986308097f, + 0.166425904f, -0.986053963f, + 0.167938295f, -0.985797509f, + 0.169450291f, -0.985538735f, + 0.170961889f, -0.985277642f, + 0.172473084f, -0.985014231f, + 0.173983873f, -0.984748502f, + 0.175494253f, -0.984480455f, + 0.177004220f, -0.984210092f, + 0.178513771f, -0.983937413f, + 0.180022901f, -0.983662419f, + 0.181531608f, -0.983385110f, + 0.183039888f, -0.983105487f, + 0.184547737f, -0.982823551f, + 0.186055152f, -0.982539302f, + 0.187562129f, -0.982252741f, + 0.189068664f, -0.981963869f, + 0.190574755f, -0.981672686f, + 0.192080397f, -0.981379193f, + 0.193585587f, -0.981083391f, + 0.195090322f, -0.980785280f, + 0.196594598f, -0.980484862f, + 0.198098411f, -0.980182136f, + 0.199601758f, -0.979877104f, + 0.201104635f, -0.979569766f, + 0.202607039f, -0.979260123f, + 0.204108966f, -0.978948175f, + 0.205610413f, -0.978633924f, + 0.207111376f, -0.978317371f, + 0.208611852f, -0.977998515f, + 0.210111837f, -0.977677358f, + 0.211611327f, -0.977353900f, + 0.213110320f, -0.977028143f, + 0.214608811f, -0.976700086f, + 0.216106797f, -0.976369731f, + 0.217604275f, -0.976037079f, + 0.219101240f, -0.975702130f, + 0.220597690f, -0.975364885f, + 0.222093621f, -0.975025345f, + 0.223589029f, -0.974683511f, + 0.225083911f, -0.974339383f, + 0.226578264f, -0.973992962f, + 0.228072083f, -0.973644250f, + 0.229565366f, -0.973293246f, + 0.231058108f, -0.972939952f, + 0.232550307f, -0.972584369f, + 0.234041959f, -0.972226497f, + 0.235533059f, -0.971866337f, + 0.237023606f, -0.971503891f, + 0.238513595f, -0.971139158f, + 0.240003022f, -0.970772141f, + 0.241491885f, -0.970402839f, + 0.242980180f, -0.970031253f, + 0.244467903f, -0.969657385f, + 0.245955050f, -0.969281235f, + 0.247441619f, -0.968902805f, + 0.248927606f, -0.968522094f, + 0.250413007f, -0.968139105f, + 0.251897818f, -0.967753837f, + 0.253382037f, -0.967366292f, + 0.254865660f, -0.966976471f, + 0.256348682f, -0.966584374f, + 0.257831102f, -0.966190003f, + 0.259312915f, -0.965793359f, + 0.260794118f, -0.965394442f, + 0.262274707f, -0.964993253f, + 0.263754679f, -0.964589793f, + 0.265234030f, -0.964184064f, + 0.266712757f, -0.963776066f, + 0.268190857f, -0.963365800f, + 0.269668326f, -0.962953267f, + 0.271145160f, -0.962538468f, + 0.272621355f, -0.962121404f, + 0.274096910f, -0.961702077f, + 0.275571819f, -0.961280486f, + 0.277046080f, -0.960856633f, + 0.278519689f, -0.960430519f, + 0.279992643f, -0.960002146f, + 0.281464938f, -0.959571513f, + 0.282936570f, -0.959138622f, + 0.284407537f, -0.958703475f, + 0.285877835f, -0.958266071f, + 0.287347460f, -0.957826413f, + 0.288816408f, -0.957384501f, + 0.290284677f, -0.956940336f, + 0.291752263f, -0.956493919f, + 0.293219163f, -0.956045251f, + 0.294685372f, -0.955594334f, + 0.296150888f, -0.955141168f, + 0.297615707f, -0.954685755f, + 0.299079826f, -0.954228095f, + 0.300543241f, -0.953768190f, + 0.302005949f, -0.953306040f, + 0.303467947f, -0.952841648f, + 0.304929230f, -0.952375013f, + 0.306389795f, -0.951906137f, + 0.307849640f, -0.951435021f, + 0.309308760f, -0.950961666f, + 0.310767153f, -0.950486074f, + 0.312224814f, -0.950008245f, + 0.313681740f, -0.949528181f, + 0.315137929f, -0.949045882f, + 0.316593376f, -0.948561350f, + 0.318048077f, -0.948074586f, + 0.319502031f, -0.947585591f, + 0.320955232f, -0.947094366f, + 0.322407679f, -0.946600913f, + 0.323859367f, -0.946105232f, + 0.325310292f, -0.945607325f, + 0.326760452f, -0.945107193f, + 0.328209844f, -0.944604837f, + 0.329658463f, -0.944100258f, + 0.331106306f, -0.943593458f, + 0.332553370f, -0.943084437f, + 0.333999651f, -0.942573198f, + 0.335445147f, -0.942059740f, + 0.336889853f, -0.941544065f, + 0.338333767f, -0.941026175f, + 0.339776884f, -0.940506071f, + 0.341219202f, -0.939983753f, + 0.342660717f, -0.939459224f, + 0.344101426f, -0.938932484f, + 0.345541325f, -0.938403534f, + 0.346980411f, -0.937872376f, + 0.348418680f, -0.937339012f, + 0.349856130f, -0.936803442f, + 0.351292756f, -0.936265667f, + 0.352728556f, -0.935725689f, + 0.354163525f, -0.935183510f, + 0.355597662f, -0.934639130f, + 0.357030961f, -0.934092550f, + 0.358463421f, -0.933543773f, + 0.359895037f, -0.932992799f, + 0.361325806f, -0.932439629f, + 0.362755724f, -0.931884266f, + 0.364184790f, -0.931326709f, + 0.365612998f, -0.930766961f, + 0.367040346f, -0.930205023f, + 0.368466830f, -0.929640896f, + 0.369892447f, -0.929074581f, + 0.371317194f, -0.928506080f, + 0.372741067f, -0.927935395f, + 0.374164063f, -0.927362526f, + 0.375586178f, -0.926787474f, + 0.377007410f, -0.926210242f, + 0.378427755f, -0.925630831f, + 0.379847209f, -0.925049241f, + 0.381265769f, -0.924465474f, + 0.382683432f, -0.923879533f, + 0.384100195f, -0.923291417f, + 0.385516054f, -0.922701128f, + 0.386931006f, -0.922108669f, + 0.388345047f, -0.921514039f, + 0.389758174f, -0.920917242f, + 0.391170384f, -0.920318277f, + 0.392581674f, -0.919717146f, + 0.393992040f, -0.919113852f, + 0.395401479f, -0.918508394f, + 0.396809987f, -0.917900776f, + 0.398217562f, -0.917290997f, + 0.399624200f, -0.916679060f, + 0.401029897f, -0.916064966f, + 0.402434651f, -0.915448716f, + 0.403838458f, -0.914830312f, + 0.405241314f, -0.914209756f, + 0.406643217f, -0.913587048f, + 0.408044163f, -0.912962190f, + 0.409444149f, -0.912335185f, + 0.410843171f, -0.911706032f, + 0.412241227f, -0.911074734f, + 0.413638312f, -0.910441292f, + 0.415034424f, -0.909805708f, + 0.416429560f, -0.909167983f, + 0.417823716f, -0.908528119f, + 0.419216888f, -0.907886116f, + 0.420609074f, -0.907241978f, + 0.422000271f, -0.906595705f, + 0.423390474f, -0.905947298f, + 0.424779681f, -0.905296759f, + 0.426167889f, -0.904644091f, + 0.427555093f, -0.903989293f, + 0.428941292f, -0.903332368f, + 0.430326481f, -0.902673318f, + 0.431710658f, -0.902012144f, + 0.433093819f, -0.901348847f, + 0.434475961f, -0.900683429f, + 0.435857080f, -0.900015892f, + 0.437237174f, -0.899346237f, + 0.438616239f, -0.898674466f, + 0.439994271f, -0.898000580f, + 0.441371269f, -0.897324581f, + 0.442747228f, -0.896646470f, + 0.444122145f, -0.895966250f, + 0.445496017f, -0.895283921f, + 0.446868840f, -0.894599486f, + 0.448240612f, -0.893912945f, + 0.449611330f, -0.893224301f, + 0.450980989f, -0.892533555f, + 0.452349587f, -0.891840709f, + 0.453717121f, -0.891145765f, + 0.455083587f, -0.890448723f, + 0.456448982f, -0.889749586f, + 0.457813304f, -0.889048356f, + 0.459176548f, -0.888345033f, + 0.460538711f, -0.887639620f, + 0.461899791f, -0.886932119f, + 0.463259784f, -0.886222530f, + 0.464618686f, -0.885510856f, + 0.465976496f, -0.884797098f, + 0.467333209f, -0.884081259f, + 0.468688822f, -0.883363339f, + 0.470043332f, -0.882643340f, + 0.471396737f, -0.881921264f, + 0.472749032f, -0.881197113f, + 0.474100215f, -0.880470889f, + 0.475450282f, -0.879742593f, + 0.476799230f, -0.879012226f, + 0.478147056f, -0.878279792f, + 0.479493758f, -0.877545290f, + 0.480839331f, -0.876808724f, + 0.482183772f, -0.876070094f, + 0.483527079f, -0.875329403f, + 0.484869248f, -0.874586652f, + 0.486210276f, -0.873841843f, + 0.487550160f, -0.873094978f, + 0.488888897f, -0.872346059f, + 0.490226483f, -0.871595087f, + 0.491562916f, -0.870842063f, + 0.492898192f, -0.870086991f, + 0.494232309f, -0.869329871f, + 0.495565262f, -0.868570706f, + 0.496897049f, -0.867809497f, + 0.498227667f, -0.867046246f, + 0.499557113f, -0.866280954f, + 0.500885383f, -0.865513624f, + 0.502212474f, -0.864744258f, + 0.503538384f, -0.863972856f, + 0.504863109f, -0.863199422f, + 0.506186645f, -0.862423956f, + 0.507508991f, -0.861646461f, + 0.508830143f, -0.860866939f, + 0.510150097f, -0.860085390f, + 0.511468850f, -0.859301818f, + 0.512786401f, -0.858516224f, + 0.514102744f, -0.857728610f, + 0.515417878f, -0.856938977f, + 0.516731799f, -0.856147328f, + 0.518044504f, -0.855353665f, + 0.519355990f, -0.854557988f, + 0.520666254f, -0.853760301f, + 0.521975293f, -0.852960605f, + 0.523283103f, -0.852158902f, + 0.524589683f, -0.851355193f, + 0.525895027f, -0.850549481f, + 0.527199135f, -0.849741768f, + 0.528502002f, -0.848932055f, + 0.529803625f, -0.848120345f, + 0.531104001f, -0.847306639f, + 0.532403128f, -0.846490939f, + 0.533701002f, -0.845673247f, + 0.534997620f, -0.844853565f, + 0.536292979f, -0.844031895f, + 0.537587076f, -0.843208240f, + 0.538879909f, -0.842382600f, + 0.540171473f, -0.841554977f, + 0.541461766f, -0.840725375f, + 0.542750785f, -0.839893794f, + 0.544038527f, -0.839060237f, + 0.545324988f, -0.838224706f, + 0.546610167f, -0.837387202f, + 0.547894059f, -0.836547727f, + 0.549176662f, -0.835706284f, + 0.550457973f, -0.834862875f, + 0.551737988f, -0.834017501f, + 0.553016706f, -0.833170165f, + 0.554294121f, -0.832320868f, + 0.555570233f, -0.831469612f, + 0.556845037f, -0.830616400f, + 0.558118531f, -0.829761234f, + 0.559390712f, -0.828904115f, + 0.560661576f, -0.828045045f, + 0.561931121f, -0.827184027f, + 0.563199344f, -0.826321063f, + 0.564466242f, -0.825456154f, + 0.565731811f, -0.824589303f, + 0.566996049f, -0.823720511f, + 0.568258953f, -0.822849781f, + 0.569520519f, -0.821977115f, + 0.570780746f, -0.821102515f, + 0.572039629f, -0.820225983f, + 0.573297167f, -0.819347520f, + 0.574553355f, -0.818467130f, + 0.575808191f, -0.817584813f, + 0.577061673f, -0.816700573f, + 0.578313796f, -0.815814411f, + 0.579564559f, -0.814926329f, + 0.580813958f, -0.814036330f, + 0.582061990f, -0.813144415f, + 0.583308653f, -0.812250587f, + 0.584553943f, -0.811354847f, + 0.585797857f, -0.810457198f, + 0.587040394f, -0.809557642f, + 0.588281548f, -0.808656182f, + 0.589521319f, -0.807752818f, + 0.590759702f, -0.806847554f, + 0.591996695f, -0.805940391f, + 0.593232295f, -0.805031331f, + 0.594466499f, -0.804120377f, + 0.595699304f, -0.803207531f, + 0.596930708f, -0.802292796f, + 0.598160707f, -0.801376172f, + 0.599389298f, -0.800457662f, + 0.600616479f, -0.799537269f, + 0.601842247f, -0.798614995f, + 0.603066599f, -0.797690841f, + 0.604289531f, -0.796764810f, + 0.605511041f, -0.795836905f, + 0.606731127f, -0.794907126f, + 0.607949785f, -0.793975478f, + 0.609167012f, -0.793041960f, + 0.610382806f, -0.792106577f, + 0.611597164f, -0.791169330f, + 0.612810082f, -0.790230221f, + 0.614021559f, -0.789289253f, + 0.615231591f, -0.788346428f, + 0.616440175f, -0.787401747f, + 0.617647308f, -0.786455214f, + 0.618852988f, -0.785506830f, + 0.620057212f, -0.784556597f, + 0.621259977f, -0.783604519f, + 0.622461279f, -0.782650596f, + 0.623661118f, -0.781694832f, + 0.624859488f, -0.780737229f, + 0.626056388f, -0.779777788f, + 0.627251815f, -0.778816512f, + 0.628445767f, -0.777853404f, + 0.629638239f, -0.776888466f, + 0.630829230f, -0.775921699f, + 0.632018736f, -0.774953107f, + 0.633206755f, -0.773982691f, + 0.634393284f, -0.773010453f, + 0.635578320f, -0.772036397f, + 0.636761861f, -0.771060524f, + 0.637943904f, -0.770082837f, + 0.639124445f, -0.769103338f, + 0.640303482f, -0.768122029f, + 0.641481013f, -0.767138912f, + 0.642657034f, -0.766153990f, + 0.643831543f, -0.765167266f, + 0.645004537f, -0.764178741f, + 0.646176013f, -0.763188417f, + 0.647345969f, -0.762196298f, + 0.648514401f, -0.761202385f, + 0.649681307f, -0.760206682f, + 0.650846685f, -0.759209189f, + 0.652010531f, -0.758209910f, + 0.653172843f, -0.757208847f, + 0.654333618f, -0.756206001f, + 0.655492853f, -0.755201377f, + 0.656650546f, -0.754194975f, + 0.657806693f, -0.753186799f, + 0.658961293f, -0.752176850f, + 0.660114342f, -0.751165132f, + 0.661265838f, -0.750151646f, + 0.662415778f, -0.749136395f, + 0.663564159f, -0.748119380f, + 0.664710978f, -0.747100606f, + 0.665856234f, -0.746080074f, + 0.666999922f, -0.745057785f, + 0.668142041f, -0.744033744f, + 0.669282588f, -0.743007952f, + 0.670421560f, -0.741980412f, + 0.671558955f, -0.740951125f, + 0.672694769f, -0.739920095f, + 0.673829000f, -0.738887324f, + 0.674961646f, -0.737852815f, + 0.676092704f, -0.736816569f, + 0.677222170f, -0.735778589f, + 0.678350043f, -0.734738878f, + 0.679476320f, -0.733697438f, + 0.680600998f, -0.732654272f, + 0.681724074f, -0.731609381f, + 0.682845546f, -0.730562769f, + 0.683965412f, -0.729514438f, + 0.685083668f, -0.728464390f, + 0.686200312f, -0.727412629f, + 0.687315341f, -0.726359155f, + 0.688428753f, -0.725303972f, + 0.689540545f, -0.724247083f, + 0.690650714f, -0.723188489f, + 0.691759258f, -0.722128194f, + 0.692866175f, -0.721066199f, + 0.693971461f, -0.720002508f, + 0.695075114f, -0.718937122f, + 0.696177131f, -0.717870045f, + 0.697277511f, -0.716801279f, + 0.698376249f, -0.715730825f, + 0.699473345f, -0.714658688f, + 0.700568794f, -0.713584869f, + 0.701662595f, -0.712509371f, + 0.702754744f, -0.711432196f, + 0.703845241f, -0.710353347f, + 0.704934080f, -0.709272826f, + 0.706021261f, -0.708190637f, + 0.707106781f, -0.707106781f, + 0.708190637f, -0.706021261f, + 0.709272826f, -0.704934080f, + 0.710353347f, -0.703845241f, + 0.711432196f, -0.702754744f, + 0.712509371f, -0.701662595f, + 0.713584869f, -0.700568794f, + 0.714658688f, -0.699473345f, + 0.715730825f, -0.698376249f, + 0.716801279f, -0.697277511f, + 0.717870045f, -0.696177131f, + 0.718937122f, -0.695075114f, + 0.720002508f, -0.693971461f, + 0.721066199f, -0.692866175f, + 0.722128194f, -0.691759258f, + 0.723188489f, -0.690650714f, + 0.724247083f, -0.689540545f, + 0.725303972f, -0.688428753f, + 0.726359155f, -0.687315341f, + 0.727412629f, -0.686200312f, + 0.728464390f, -0.685083668f, + 0.729514438f, -0.683965412f, + 0.730562769f, -0.682845546f, + 0.731609381f, -0.681724074f, + 0.732654272f, -0.680600998f, + 0.733697438f, -0.679476320f, + 0.734738878f, -0.678350043f, + 0.735778589f, -0.677222170f, + 0.736816569f, -0.676092704f, + 0.737852815f, -0.674961646f, + 0.738887324f, -0.673829000f, + 0.739920095f, -0.672694769f, + 0.740951125f, -0.671558955f, + 0.741980412f, -0.670421560f, + 0.743007952f, -0.669282588f, + 0.744033744f, -0.668142041f, + 0.745057785f, -0.666999922f, + 0.746080074f, -0.665856234f, + 0.747100606f, -0.664710978f, + 0.748119380f, -0.663564159f, + 0.749136395f, -0.662415778f, + 0.750151646f, -0.661265838f, + 0.751165132f, -0.660114342f, + 0.752176850f, -0.658961293f, + 0.753186799f, -0.657806693f, + 0.754194975f, -0.656650546f, + 0.755201377f, -0.655492853f, + 0.756206001f, -0.654333618f, + 0.757208847f, -0.653172843f, + 0.758209910f, -0.652010531f, + 0.759209189f, -0.650846685f, + 0.760206682f, -0.649681307f, + 0.761202385f, -0.648514401f, + 0.762196298f, -0.647345969f, + 0.763188417f, -0.646176013f, + 0.764178741f, -0.645004537f, + 0.765167266f, -0.643831543f, + 0.766153990f, -0.642657034f, + 0.767138912f, -0.641481013f, + 0.768122029f, -0.640303482f, + 0.769103338f, -0.639124445f, + 0.770082837f, -0.637943904f, + 0.771060524f, -0.636761861f, + 0.772036397f, -0.635578320f, + 0.773010453f, -0.634393284f, + 0.773982691f, -0.633206755f, + 0.774953107f, -0.632018736f, + 0.775921699f, -0.630829230f, + 0.776888466f, -0.629638239f, + 0.777853404f, -0.628445767f, + 0.778816512f, -0.627251815f, + 0.779777788f, -0.626056388f, + 0.780737229f, -0.624859488f, + 0.781694832f, -0.623661118f, + 0.782650596f, -0.622461279f, + 0.783604519f, -0.621259977f, + 0.784556597f, -0.620057212f, + 0.785506830f, -0.618852988f, + 0.786455214f, -0.617647308f, + 0.787401747f, -0.616440175f, + 0.788346428f, -0.615231591f, + 0.789289253f, -0.614021559f, + 0.790230221f, -0.612810082f, + 0.791169330f, -0.611597164f, + 0.792106577f, -0.610382806f, + 0.793041960f, -0.609167012f, + 0.793975478f, -0.607949785f, + 0.794907126f, -0.606731127f, + 0.795836905f, -0.605511041f, + 0.796764810f, -0.604289531f, + 0.797690841f, -0.603066599f, + 0.798614995f, -0.601842247f, + 0.799537269f, -0.600616479f, + 0.800457662f, -0.599389298f, + 0.801376172f, -0.598160707f, + 0.802292796f, -0.596930708f, + 0.803207531f, -0.595699304f, + 0.804120377f, -0.594466499f, + 0.805031331f, -0.593232295f, + 0.805940391f, -0.591996695f, + 0.806847554f, -0.590759702f, + 0.807752818f, -0.589521319f, + 0.808656182f, -0.588281548f, + 0.809557642f, -0.587040394f, + 0.810457198f, -0.585797857f, + 0.811354847f, -0.584553943f, + 0.812250587f, -0.583308653f, + 0.813144415f, -0.582061990f, + 0.814036330f, -0.580813958f, + 0.814926329f, -0.579564559f, + 0.815814411f, -0.578313796f, + 0.816700573f, -0.577061673f, + 0.817584813f, -0.575808191f, + 0.818467130f, -0.574553355f, + 0.819347520f, -0.573297167f, + 0.820225983f, -0.572039629f, + 0.821102515f, -0.570780746f, + 0.821977115f, -0.569520519f, + 0.822849781f, -0.568258953f, + 0.823720511f, -0.566996049f, + 0.824589303f, -0.565731811f, + 0.825456154f, -0.564466242f, + 0.826321063f, -0.563199344f, + 0.827184027f, -0.561931121f, + 0.828045045f, -0.560661576f, + 0.828904115f, -0.559390712f, + 0.829761234f, -0.558118531f, + 0.830616400f, -0.556845037f, + 0.831469612f, -0.555570233f, + 0.832320868f, -0.554294121f, + 0.833170165f, -0.553016706f, + 0.834017501f, -0.551737988f, + 0.834862875f, -0.550457973f, + 0.835706284f, -0.549176662f, + 0.836547727f, -0.547894059f, + 0.837387202f, -0.546610167f, + 0.838224706f, -0.545324988f, + 0.839060237f, -0.544038527f, + 0.839893794f, -0.542750785f, + 0.840725375f, -0.541461766f, + 0.841554977f, -0.540171473f, + 0.842382600f, -0.538879909f, + 0.843208240f, -0.537587076f, + 0.844031895f, -0.536292979f, + 0.844853565f, -0.534997620f, + 0.845673247f, -0.533701002f, + 0.846490939f, -0.532403128f, + 0.847306639f, -0.531104001f, + 0.848120345f, -0.529803625f, + 0.848932055f, -0.528502002f, + 0.849741768f, -0.527199135f, + 0.850549481f, -0.525895027f, + 0.851355193f, -0.524589683f, + 0.852158902f, -0.523283103f, + 0.852960605f, -0.521975293f, + 0.853760301f, -0.520666254f, + 0.854557988f, -0.519355990f, + 0.855353665f, -0.518044504f, + 0.856147328f, -0.516731799f, + 0.856938977f, -0.515417878f, + 0.857728610f, -0.514102744f, + 0.858516224f, -0.512786401f, + 0.859301818f, -0.511468850f, + 0.860085390f, -0.510150097f, + 0.860866939f, -0.508830143f, + 0.861646461f, -0.507508991f, + 0.862423956f, -0.506186645f, + 0.863199422f, -0.504863109f, + 0.863972856f, -0.503538384f, + 0.864744258f, -0.502212474f, + 0.865513624f, -0.500885383f, + 0.866280954f, -0.499557113f, + 0.867046246f, -0.498227667f, + 0.867809497f, -0.496897049f, + 0.868570706f, -0.495565262f, + 0.869329871f, -0.494232309f, + 0.870086991f, -0.492898192f, + 0.870842063f, -0.491562916f, + 0.871595087f, -0.490226483f, + 0.872346059f, -0.488888897f, + 0.873094978f, -0.487550160f, + 0.873841843f, -0.486210276f, + 0.874586652f, -0.484869248f, + 0.875329403f, -0.483527079f, + 0.876070094f, -0.482183772f, + 0.876808724f, -0.480839331f, + 0.877545290f, -0.479493758f, + 0.878279792f, -0.478147056f, + 0.879012226f, -0.476799230f, + 0.879742593f, -0.475450282f, + 0.880470889f, -0.474100215f, + 0.881197113f, -0.472749032f, + 0.881921264f, -0.471396737f, + 0.882643340f, -0.470043332f, + 0.883363339f, -0.468688822f, + 0.884081259f, -0.467333209f, + 0.884797098f, -0.465976496f, + 0.885510856f, -0.464618686f, + 0.886222530f, -0.463259784f, + 0.886932119f, -0.461899791f, + 0.887639620f, -0.460538711f, + 0.888345033f, -0.459176548f, + 0.889048356f, -0.457813304f, + 0.889749586f, -0.456448982f, + 0.890448723f, -0.455083587f, + 0.891145765f, -0.453717121f, + 0.891840709f, -0.452349587f, + 0.892533555f, -0.450980989f, + 0.893224301f, -0.449611330f, + 0.893912945f, -0.448240612f, + 0.894599486f, -0.446868840f, + 0.895283921f, -0.445496017f, + 0.895966250f, -0.444122145f, + 0.896646470f, -0.442747228f, + 0.897324581f, -0.441371269f, + 0.898000580f, -0.439994271f, + 0.898674466f, -0.438616239f, + 0.899346237f, -0.437237174f, + 0.900015892f, -0.435857080f, + 0.900683429f, -0.434475961f, + 0.901348847f, -0.433093819f, + 0.902012144f, -0.431710658f, + 0.902673318f, -0.430326481f, + 0.903332368f, -0.428941292f, + 0.903989293f, -0.427555093f, + 0.904644091f, -0.426167889f, + 0.905296759f, -0.424779681f, + 0.905947298f, -0.423390474f, + 0.906595705f, -0.422000271f, + 0.907241978f, -0.420609074f, + 0.907886116f, -0.419216888f, + 0.908528119f, -0.417823716f, + 0.909167983f, -0.416429560f, + 0.909805708f, -0.415034424f, + 0.910441292f, -0.413638312f, + 0.911074734f, -0.412241227f, + 0.911706032f, -0.410843171f, + 0.912335185f, -0.409444149f, + 0.912962190f, -0.408044163f, + 0.913587048f, -0.406643217f, + 0.914209756f, -0.405241314f, + 0.914830312f, -0.403838458f, + 0.915448716f, -0.402434651f, + 0.916064966f, -0.401029897f, + 0.916679060f, -0.399624200f, + 0.917290997f, -0.398217562f, + 0.917900776f, -0.396809987f, + 0.918508394f, -0.395401479f, + 0.919113852f, -0.393992040f, + 0.919717146f, -0.392581674f, + 0.920318277f, -0.391170384f, + 0.920917242f, -0.389758174f, + 0.921514039f, -0.388345047f, + 0.922108669f, -0.386931006f, + 0.922701128f, -0.385516054f, + 0.923291417f, -0.384100195f, + 0.923879533f, -0.382683432f, + 0.924465474f, -0.381265769f, + 0.925049241f, -0.379847209f, + 0.925630831f, -0.378427755f, + 0.926210242f, -0.377007410f, + 0.926787474f, -0.375586178f, + 0.927362526f, -0.374164063f, + 0.927935395f, -0.372741067f, + 0.928506080f, -0.371317194f, + 0.929074581f, -0.369892447f, + 0.929640896f, -0.368466830f, + 0.930205023f, -0.367040346f, + 0.930766961f, -0.365612998f, + 0.931326709f, -0.364184790f, + 0.931884266f, -0.362755724f, + 0.932439629f, -0.361325806f, + 0.932992799f, -0.359895037f, + 0.933543773f, -0.358463421f, + 0.934092550f, -0.357030961f, + 0.934639130f, -0.355597662f, + 0.935183510f, -0.354163525f, + 0.935725689f, -0.352728556f, + 0.936265667f, -0.351292756f, + 0.936803442f, -0.349856130f, + 0.937339012f, -0.348418680f, + 0.937872376f, -0.346980411f, + 0.938403534f, -0.345541325f, + 0.938932484f, -0.344101426f, + 0.939459224f, -0.342660717f, + 0.939983753f, -0.341219202f, + 0.940506071f, -0.339776884f, + 0.941026175f, -0.338333767f, + 0.941544065f, -0.336889853f, + 0.942059740f, -0.335445147f, + 0.942573198f, -0.333999651f, + 0.943084437f, -0.332553370f, + 0.943593458f, -0.331106306f, + 0.944100258f, -0.329658463f, + 0.944604837f, -0.328209844f, + 0.945107193f, -0.326760452f, + 0.945607325f, -0.325310292f, + 0.946105232f, -0.323859367f, + 0.946600913f, -0.322407679f, + 0.947094366f, -0.320955232f, + 0.947585591f, -0.319502031f, + 0.948074586f, -0.318048077f, + 0.948561350f, -0.316593376f, + 0.949045882f, -0.315137929f, + 0.949528181f, -0.313681740f, + 0.950008245f, -0.312224814f, + 0.950486074f, -0.310767153f, + 0.950961666f, -0.309308760f, + 0.951435021f, -0.307849640f, + 0.951906137f, -0.306389795f, + 0.952375013f, -0.304929230f, + 0.952841648f, -0.303467947f, + 0.953306040f, -0.302005949f, + 0.953768190f, -0.300543241f, + 0.954228095f, -0.299079826f, + 0.954685755f, -0.297615707f, + 0.955141168f, -0.296150888f, + 0.955594334f, -0.294685372f, + 0.956045251f, -0.293219163f, + 0.956493919f, -0.291752263f, + 0.956940336f, -0.290284677f, + 0.957384501f, -0.288816408f, + 0.957826413f, -0.287347460f, + 0.958266071f, -0.285877835f, + 0.958703475f, -0.284407537f, + 0.959138622f, -0.282936570f, + 0.959571513f, -0.281464938f, + 0.960002146f, -0.279992643f, + 0.960430519f, -0.278519689f, + 0.960856633f, -0.277046080f, + 0.961280486f, -0.275571819f, + 0.961702077f, -0.274096910f, + 0.962121404f, -0.272621355f, + 0.962538468f, -0.271145160f, + 0.962953267f, -0.269668326f, + 0.963365800f, -0.268190857f, + 0.963776066f, -0.266712757f, + 0.964184064f, -0.265234030f, + 0.964589793f, -0.263754679f, + 0.964993253f, -0.262274707f, + 0.965394442f, -0.260794118f, + 0.965793359f, -0.259312915f, + 0.966190003f, -0.257831102f, + 0.966584374f, -0.256348682f, + 0.966976471f, -0.254865660f, + 0.967366292f, -0.253382037f, + 0.967753837f, -0.251897818f, + 0.968139105f, -0.250413007f, + 0.968522094f, -0.248927606f, + 0.968902805f, -0.247441619f, + 0.969281235f, -0.245955050f, + 0.969657385f, -0.244467903f, + 0.970031253f, -0.242980180f, + 0.970402839f, -0.241491885f, + 0.970772141f, -0.240003022f, + 0.971139158f, -0.238513595f, + 0.971503891f, -0.237023606f, + 0.971866337f, -0.235533059f, + 0.972226497f, -0.234041959f, + 0.972584369f, -0.232550307f, + 0.972939952f, -0.231058108f, + 0.973293246f, -0.229565366f, + 0.973644250f, -0.228072083f, + 0.973992962f, -0.226578264f, + 0.974339383f, -0.225083911f, + 0.974683511f, -0.223589029f, + 0.975025345f, -0.222093621f, + 0.975364885f, -0.220597690f, + 0.975702130f, -0.219101240f, + 0.976037079f, -0.217604275f, + 0.976369731f, -0.216106797f, + 0.976700086f, -0.214608811f, + 0.977028143f, -0.213110320f, + 0.977353900f, -0.211611327f, + 0.977677358f, -0.210111837f, + 0.977998515f, -0.208611852f, + 0.978317371f, -0.207111376f, + 0.978633924f, -0.205610413f, + 0.978948175f, -0.204108966f, + 0.979260123f, -0.202607039f, + 0.979569766f, -0.201104635f, + 0.979877104f, -0.199601758f, + 0.980182136f, -0.198098411f, + 0.980484862f, -0.196594598f, + 0.980785280f, -0.195090322f, + 0.981083391f, -0.193585587f, + 0.981379193f, -0.192080397f, + 0.981672686f, -0.190574755f, + 0.981963869f, -0.189068664f, + 0.982252741f, -0.187562129f, + 0.982539302f, -0.186055152f, + 0.982823551f, -0.184547737f, + 0.983105487f, -0.183039888f, + 0.983385110f, -0.181531608f, + 0.983662419f, -0.180022901f, + 0.983937413f, -0.178513771f, + 0.984210092f, -0.177004220f, + 0.984480455f, -0.175494253f, + 0.984748502f, -0.173983873f, + 0.985014231f, -0.172473084f, + 0.985277642f, -0.170961889f, + 0.985538735f, -0.169450291f, + 0.985797509f, -0.167938295f, + 0.986053963f, -0.166425904f, + 0.986308097f, -0.164913120f, + 0.986559910f, -0.163399949f, + 0.986809402f, -0.161886394f, + 0.987056571f, -0.160372457f, + 0.987301418f, -0.158858143f, + 0.987543942f, -0.157343456f, + 0.987784142f, -0.155828398f, + 0.988022017f, -0.154312973f, + 0.988257568f, -0.152797185f, + 0.988490793f, -0.151281038f, + 0.988721692f, -0.149764535f, + 0.988950265f, -0.148247679f, + 0.989176510f, -0.146730474f, + 0.989400428f, -0.145212925f, + 0.989622017f, -0.143695033f, + 0.989841278f, -0.142176804f, + 0.990058210f, -0.140658239f, + 0.990272812f, -0.139139344f, + 0.990485084f, -0.137620122f, + 0.990695025f, -0.136100575f, + 0.990902635f, -0.134580709f, + 0.991107914f, -0.133060525f, + 0.991310860f, -0.131540029f, + 0.991511473f, -0.130019223f, + 0.991709754f, -0.128498111f, + 0.991905700f, -0.126976696f, + 0.992099313f, -0.125454983f, + 0.992290591f, -0.123932975f, + 0.992479535f, -0.122410675f, + 0.992666142f, -0.120888087f, + 0.992850414f, -0.119365215f, + 0.993032350f, -0.117842062f, + 0.993211949f, -0.116318631f, + 0.993389211f, -0.114794927f, + 0.993564136f, -0.113270952f, + 0.993736722f, -0.111746711f, + 0.993906970f, -0.110222207f, + 0.994074879f, -0.108697444f, + 0.994240449f, -0.107172425f, + 0.994403680f, -0.105647154f, + 0.994564571f, -0.104121634f, + 0.994723121f, -0.102595869f, + 0.994879331f, -0.101069863f, + 0.995033199f, -0.099543619f, + 0.995184727f, -0.098017140f, + 0.995333912f, -0.096490431f, + 0.995480755f, -0.094963495f, + 0.995625256f, -0.093436336f, + 0.995767414f, -0.091908956f, + 0.995907229f, -0.090381361f, + 0.996044701f, -0.088853553f, + 0.996179829f, -0.087325535f, + 0.996312612f, -0.085797312f, + 0.996443051f, -0.084268888f, + 0.996571146f, -0.082740265f, + 0.996696895f, -0.081211447f, + 0.996820299f, -0.079682438f, + 0.996941358f, -0.078153242f, + 0.997060070f, -0.076623861f, + 0.997176437f, -0.075094301f, + 0.997290457f, -0.073564564f, + 0.997402130f, -0.072034653f, + 0.997511456f, -0.070504573f, + 0.997618435f, -0.068974328f, + 0.997723067f, -0.067443920f, + 0.997825350f, -0.065913353f, + 0.997925286f, -0.064382631f, + 0.998022874f, -0.062851758f, + 0.998118113f, -0.061320736f, + 0.998211003f, -0.059789571f, + 0.998301545f, -0.058258265f, + 0.998389737f, -0.056726821f, + 0.998475581f, -0.055195244f, + 0.998559074f, -0.053663538f, + 0.998640218f, -0.052131705f, + 0.998719012f, -0.050599749f, + 0.998795456f, -0.049067674f, + 0.998869550f, -0.047535484f, + 0.998941293f, -0.046003182f, + 0.999010686f, -0.044470772f, + 0.999077728f, -0.042938257f, + 0.999142419f, -0.041405641f, + 0.999204759f, -0.039872928f, + 0.999264747f, -0.038340120f, + 0.999322385f, -0.036807223f, + 0.999377670f, -0.035274239f, + 0.999430605f, -0.033741172f, + 0.999481187f, -0.032208025f, + 0.999529418f, -0.030674803f, + 0.999575296f, -0.029141509f, + 0.999618822f, -0.027608146f, + 0.999659997f, -0.026074718f, + 0.999698819f, -0.024541229f, + 0.999735288f, -0.023007681f, + 0.999769405f, -0.021474080f, + 0.999801170f, -0.019940429f, + 0.999830582f, -0.018406730f, + 0.999857641f, -0.016872988f, + 0.999882347f, -0.015339206f, + 0.999904701f, -0.013805389f, + 0.999924702f, -0.012271538f, + 0.999942350f, -0.010737659f, + 0.999957645f, -0.009203755f, + 0.999970586f, -0.007669829f, + 0.999981175f, -0.006135885f, + 0.999989411f, -0.004601926f, + 0.999995294f, -0.003067957f, + 0.999998823f, -0.001533980f +}; + +/** + @brief Q31 Twiddle factors Table +*/ + + +/** + @par + Example code for Q31 Twiddle factors Generation:: + @par +
 for(i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefQ31[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefQ31[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 16, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to Q31(Fixed point 1.31): + round(twiddleCoefQ31(i) * pow(2, 31)) + */ +const q31_t twiddleCoef_16_q31[24] = { + (q31_t)0x7FFFFFFF, (q31_t)0x00000000, + (q31_t)0x7641AF3C, (q31_t)0x30FBC54D, + (q31_t)0x5A82799A, (q31_t)0x5A82799A, + (q31_t)0x30FBC54D, (q31_t)0x7641AF3C, + (q31_t)0x00000000, (q31_t)0x7FFFFFFF, + (q31_t)0xCF043AB2, (q31_t)0x7641AF3C, + (q31_t)0xA57D8666, (q31_t)0x5A82799A, + (q31_t)0x89BE50C3, (q31_t)0x30FBC54D, + (q31_t)0x80000000, (q31_t)0x00000000, + (q31_t)0x89BE50C3, (q31_t)0xCF043AB2, + (q31_t)0xA57D8666, (q31_t)0xA57D8666, + (q31_t)0xCF043AB2, (q31_t)0x89BE50C3 +}; + +/** + @par + Example code for Q31 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefQ31[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefQ31[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 32, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to Q31(Fixed point 1.31): + round(twiddleCoefQ31(i) * pow(2, 31)) + */ +const q31_t twiddleCoef_32_q31[48] = { + (q31_t)0x7FFFFFFF, (q31_t)0x00000000, + (q31_t)0x7D8A5F3F, (q31_t)0x18F8B83C, + (q31_t)0x7641AF3C, (q31_t)0x30FBC54D, + (q31_t)0x6A6D98A4, (q31_t)0x471CECE6, + (q31_t)0x5A82799A, (q31_t)0x5A82799A, + (q31_t)0x471CECE6, (q31_t)0x6A6D98A4, + (q31_t)0x30FBC54D, (q31_t)0x7641AF3C, + (q31_t)0x18F8B83C, (q31_t)0x7D8A5F3F, + (q31_t)0x00000000, (q31_t)0x7FFFFFFF, + (q31_t)0xE70747C3, (q31_t)0x7D8A5F3F, + (q31_t)0xCF043AB2, (q31_t)0x7641AF3C, + (q31_t)0xB8E31319, (q31_t)0x6A6D98A4, + (q31_t)0xA57D8666, (q31_t)0x5A82799A, + (q31_t)0x9592675B, (q31_t)0x471CECE6, + (q31_t)0x89BE50C3, (q31_t)0x30FBC54D, + (q31_t)0x8275A0C0, (q31_t)0x18F8B83C, + (q31_t)0x80000000, (q31_t)0x00000000, + (q31_t)0x8275A0C0, (q31_t)0xE70747C3, + (q31_t)0x89BE50C3, (q31_t)0xCF043AB2, + (q31_t)0x9592675B, (q31_t)0xB8E31319, + (q31_t)0xA57D8666, (q31_t)0xA57D8666, + (q31_t)0xB8E31319, (q31_t)0x9592675B, + (q31_t)0xCF043AB2, (q31_t)0x89BE50C3, + (q31_t)0xE70747C3, (q31_t)0x8275A0C0 +}; + +/** + @par + Example code for Q31 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefQ31[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefQ31[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 64, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to Q31(Fixed point 1.31): + round(twiddleCoefQ31(i) * pow(2, 31)) + */ +const q31_t twiddleCoef_64_q31[96] = { + (q31_t)0x7FFFFFFF, (q31_t)0x00000000, (q31_t)0x7F62368F, + (q31_t)0x0C8BD35E, (q31_t)0x7D8A5F3F, (q31_t)0x18F8B83C, + (q31_t)0x7A7D055B, (q31_t)0x25280C5D, (q31_t)0x7641AF3C, + (q31_t)0x30FBC54D, (q31_t)0x70E2CBC6, (q31_t)0x3C56BA70, + (q31_t)0x6A6D98A4, (q31_t)0x471CECE6, (q31_t)0x62F201AC, + (q31_t)0x5133CC94, (q31_t)0x5A82799A, (q31_t)0x5A82799A, + (q31_t)0x5133CC94, (q31_t)0x62F201AC, (q31_t)0x471CECE6, + (q31_t)0x6A6D98A4, (q31_t)0x3C56BA70, (q31_t)0x70E2CBC6, + (q31_t)0x30FBC54D, (q31_t)0x7641AF3C, (q31_t)0x25280C5D, + (q31_t)0x7A7D055B, (q31_t)0x18F8B83C, (q31_t)0x7D8A5F3F, + (q31_t)0x0C8BD35E, (q31_t)0x7F62368F, (q31_t)0x00000000, + (q31_t)0x7FFFFFFF, (q31_t)0xF3742CA1, (q31_t)0x7F62368F, + (q31_t)0xE70747C3, (q31_t)0x7D8A5F3F, (q31_t)0xDAD7F3A2, + (q31_t)0x7A7D055B, (q31_t)0xCF043AB2, (q31_t)0x7641AF3C, + (q31_t)0xC3A9458F, (q31_t)0x70E2CBC6, (q31_t)0xB8E31319, + (q31_t)0x6A6D98A4, (q31_t)0xAECC336B, (q31_t)0x62F201AC, + (q31_t)0xA57D8666, (q31_t)0x5A82799A, (q31_t)0x9D0DFE53, + (q31_t)0x5133CC94, (q31_t)0x9592675B, (q31_t)0x471CECE6, + (q31_t)0x8F1D343A, (q31_t)0x3C56BA70, (q31_t)0x89BE50C3, + (q31_t)0x30FBC54D, (q31_t)0x8582FAA4, (q31_t)0x25280C5D, + (q31_t)0x8275A0C0, (q31_t)0x18F8B83C, (q31_t)0x809DC970, + (q31_t)0x0C8BD35E, (q31_t)0x80000000, (q31_t)0x00000000, + (q31_t)0x809DC970, (q31_t)0xF3742CA1, (q31_t)0x8275A0C0, + (q31_t)0xE70747C3, (q31_t)0x8582FAA4, (q31_t)0xDAD7F3A2, + (q31_t)0x89BE50C3, (q31_t)0xCF043AB2, (q31_t)0x8F1D343A, + (q31_t)0xC3A9458F, (q31_t)0x9592675B, (q31_t)0xB8E31319, + (q31_t)0x9D0DFE53, (q31_t)0xAECC336B, (q31_t)0xA57D8666, + (q31_t)0xA57D8666, (q31_t)0xAECC336B, (q31_t)0x9D0DFE53, + (q31_t)0xB8E31319, (q31_t)0x9592675B, (q31_t)0xC3A9458F, + (q31_t)0x8F1D343A, (q31_t)0xCF043AB2, (q31_t)0x89BE50C3, + (q31_t)0xDAD7F3A2, (q31_t)0x8582FAA4, (q31_t)0xE70747C3, + (q31_t)0x8275A0C0, (q31_t)0xF3742CA1, (q31_t)0x809DC970 +}; + +/** + @par + Example code for Q31 Twiddle factors Generation:: + @par +
for (i = 0; i < 3N/4; i++)
+  {
+     twiddleCoefQ31[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefQ31[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 128, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to Q31(Fixed point 1.31): + round(twiddleCoefQ31(i) * pow(2, 31)) + */ +const q31_t twiddleCoef_128_q31[192] = { + (q31_t)0x7FFFFFFF, (q31_t)0x00000000, (q31_t)0x7FD8878D, + (q31_t)0x0647D97C, (q31_t)0x7F62368F, (q31_t)0x0C8BD35E, + (q31_t)0x7E9D55FC, (q31_t)0x12C8106E, (q31_t)0x7D8A5F3F, + (q31_t)0x18F8B83C, (q31_t)0x7C29FBEE, (q31_t)0x1F19F97B, + (q31_t)0x7A7D055B, (q31_t)0x25280C5D, (q31_t)0x78848413, + (q31_t)0x2B1F34EB, (q31_t)0x7641AF3C, (q31_t)0x30FBC54D, + (q31_t)0x73B5EBD0, (q31_t)0x36BA2013, (q31_t)0x70E2CBC6, + (q31_t)0x3C56BA70, (q31_t)0x6DCA0D14, (q31_t)0x41CE1E64, + (q31_t)0x6A6D98A4, (q31_t)0x471CECE6, (q31_t)0x66CF811F, + (q31_t)0x4C3FDFF3, (q31_t)0x62F201AC, (q31_t)0x5133CC94, + (q31_t)0x5ED77C89, (q31_t)0x55F5A4D2, (q31_t)0x5A82799A, + (q31_t)0x5A82799A, (q31_t)0x55F5A4D2, (q31_t)0x5ED77C89, + (q31_t)0x5133CC94, (q31_t)0x62F201AC, (q31_t)0x4C3FDFF3, + (q31_t)0x66CF811F, (q31_t)0x471CECE6, (q31_t)0x6A6D98A4, + (q31_t)0x41CE1E64, (q31_t)0x6DCA0D14, (q31_t)0x3C56BA70, + (q31_t)0x70E2CBC6, (q31_t)0x36BA2013, (q31_t)0x73B5EBD0, + (q31_t)0x30FBC54D, (q31_t)0x7641AF3C, (q31_t)0x2B1F34EB, + (q31_t)0x78848413, (q31_t)0x25280C5D, (q31_t)0x7A7D055B, + (q31_t)0x1F19F97B, (q31_t)0x7C29FBEE, (q31_t)0x18F8B83C, + (q31_t)0x7D8A5F3F, (q31_t)0x12C8106E, (q31_t)0x7E9D55FC, + (q31_t)0x0C8BD35E, (q31_t)0x7F62368F, (q31_t)0x0647D97C, + (q31_t)0x7FD8878D, (q31_t)0x00000000, (q31_t)0x7FFFFFFF, + (q31_t)0xF9B82683, (q31_t)0x7FD8878D, (q31_t)0xF3742CA1, + (q31_t)0x7F62368F, (q31_t)0xED37EF91, (q31_t)0x7E9D55FC, + (q31_t)0xE70747C3, (q31_t)0x7D8A5F3F, (q31_t)0xE0E60684, + (q31_t)0x7C29FBEE, (q31_t)0xDAD7F3A2, (q31_t)0x7A7D055B, + (q31_t)0xD4E0CB14, (q31_t)0x78848413, (q31_t)0xCF043AB2, + (q31_t)0x7641AF3C, (q31_t)0xC945DFEC, (q31_t)0x73B5EBD0, + (q31_t)0xC3A9458F, (q31_t)0x70E2CBC6, (q31_t)0xBE31E19B, + (q31_t)0x6DCA0D14, (q31_t)0xB8E31319, (q31_t)0x6A6D98A4, + (q31_t)0xB3C0200C, (q31_t)0x66CF811F, (q31_t)0xAECC336B, + (q31_t)0x62F201AC, (q31_t)0xAA0A5B2D, (q31_t)0x5ED77C89, + (q31_t)0xA57D8666, (q31_t)0x5A82799A, (q31_t)0xA1288376, + (q31_t)0x55F5A4D2, (q31_t)0x9D0DFE53, (q31_t)0x5133CC94, + (q31_t)0x99307EE0, (q31_t)0x4C3FDFF3, (q31_t)0x9592675B, + (q31_t)0x471CECE6, (q31_t)0x9235F2EB, (q31_t)0x41CE1E64, + (q31_t)0x8F1D343A, (q31_t)0x3C56BA70, (q31_t)0x8C4A142F, + (q31_t)0x36BA2013, (q31_t)0x89BE50C3, (q31_t)0x30FBC54D, + (q31_t)0x877B7BEC, (q31_t)0x2B1F34EB, (q31_t)0x8582FAA4, + (q31_t)0x25280C5D, (q31_t)0x83D60411, (q31_t)0x1F19F97B, + (q31_t)0x8275A0C0, (q31_t)0x18F8B83C, (q31_t)0x8162AA03, + (q31_t)0x12C8106E, (q31_t)0x809DC970, (q31_t)0x0C8BD35E, + (q31_t)0x80277872, (q31_t)0x0647D97C, (q31_t)0x80000000, + (q31_t)0x00000000, (q31_t)0x80277872, (q31_t)0xF9B82683, + (q31_t)0x809DC970, (q31_t)0xF3742CA1, (q31_t)0x8162AA03, + (q31_t)0xED37EF91, (q31_t)0x8275A0C0, (q31_t)0xE70747C3, + (q31_t)0x83D60411, (q31_t)0xE0E60684, (q31_t)0x8582FAA4, + (q31_t)0xDAD7F3A2, (q31_t)0x877B7BEC, (q31_t)0xD4E0CB14, + (q31_t)0x89BE50C3, (q31_t)0xCF043AB2, (q31_t)0x8C4A142F, + (q31_t)0xC945DFEC, (q31_t)0x8F1D343A, (q31_t)0xC3A9458F, + (q31_t)0x9235F2EB, (q31_t)0xBE31E19B, (q31_t)0x9592675B, + (q31_t)0xB8E31319, (q31_t)0x99307EE0, (q31_t)0xB3C0200C, + (q31_t)0x9D0DFE53, (q31_t)0xAECC336B, (q31_t)0xA1288376, + (q31_t)0xAA0A5B2D, (q31_t)0xA57D8666, (q31_t)0xA57D8666, + (q31_t)0xAA0A5B2D, (q31_t)0xA1288376, (q31_t)0xAECC336B, + (q31_t)0x9D0DFE53, (q31_t)0xB3C0200C, (q31_t)0x99307EE0, + (q31_t)0xB8E31319, (q31_t)0x9592675B, (q31_t)0xBE31E19B, + (q31_t)0x9235F2EB, (q31_t)0xC3A9458F, (q31_t)0x8F1D343A, + (q31_t)0xC945DFEC, (q31_t)0x8C4A142F, (q31_t)0xCF043AB2, + (q31_t)0x89BE50C3, (q31_t)0xD4E0CB14, (q31_t)0x877B7BEC, + (q31_t)0xDAD7F3A2, (q31_t)0x8582FAA4, (q31_t)0xE0E60684, + (q31_t)0x83D60411, (q31_t)0xE70747C3, (q31_t)0x8275A0C0, + (q31_t)0xED37EF91, (q31_t)0x8162AA03, (q31_t)0xF3742CA1, + (q31_t)0x809DC970, (q31_t)0xF9B82683, (q31_t)0x80277872 +}; + +/** + @par + Example code for Q31 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefQ31[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefQ31[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 256, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to Q31(Fixed point 1.31): + round(twiddleCoefQ31(i) * pow(2, 31)) + + */ +const q31_t twiddleCoef_256_q31[384] = { + (q31_t)0x7FFFFFFF, (q31_t)0x00000000, (q31_t)0x7FF62182, + (q31_t)0x03242ABF, (q31_t)0x7FD8878D, (q31_t)0x0647D97C, + (q31_t)0x7FA736B4, (q31_t)0x096A9049, (q31_t)0x7F62368F, + (q31_t)0x0C8BD35E, (q31_t)0x7F0991C3, (q31_t)0x0FAB272B, + (q31_t)0x7E9D55FC, (q31_t)0x12C8106E, (q31_t)0x7E1D93E9, + (q31_t)0x15E21444, (q31_t)0x7D8A5F3F, (q31_t)0x18F8B83C, + (q31_t)0x7CE3CEB1, (q31_t)0x1C0B826A, (q31_t)0x7C29FBEE, + (q31_t)0x1F19F97B, (q31_t)0x7B5D039D, (q31_t)0x2223A4C5, + (q31_t)0x7A7D055B, (q31_t)0x25280C5D, (q31_t)0x798A23B1, + (q31_t)0x2826B928, (q31_t)0x78848413, (q31_t)0x2B1F34EB, + (q31_t)0x776C4EDB, (q31_t)0x2E110A62, (q31_t)0x7641AF3C, + (q31_t)0x30FBC54D, (q31_t)0x7504D345, (q31_t)0x33DEF287, + (q31_t)0x73B5EBD0, (q31_t)0x36BA2013, (q31_t)0x72552C84, + (q31_t)0x398CDD32, (q31_t)0x70E2CBC6, (q31_t)0x3C56BA70, + (q31_t)0x6F5F02B1, (q31_t)0x3F1749B7, (q31_t)0x6DCA0D14, + (q31_t)0x41CE1E64, (q31_t)0x6C242960, (q31_t)0x447ACD50, + (q31_t)0x6A6D98A4, (q31_t)0x471CECE6, (q31_t)0x68A69E81, + (q31_t)0x49B41533, (q31_t)0x66CF811F, (q31_t)0x4C3FDFF3, + (q31_t)0x64E88926, (q31_t)0x4EBFE8A4, (q31_t)0x62F201AC, + (q31_t)0x5133CC94, (q31_t)0x60EC3830, (q31_t)0x539B2AEF, + (q31_t)0x5ED77C89, (q31_t)0x55F5A4D2, (q31_t)0x5CB420DF, + (q31_t)0x5842DD54, (q31_t)0x5A82799A, (q31_t)0x5A82799A, + (q31_t)0x5842DD54, (q31_t)0x5CB420DF, (q31_t)0x55F5A4D2, + (q31_t)0x5ED77C89, (q31_t)0x539B2AEF, (q31_t)0x60EC3830, + (q31_t)0x5133CC94, (q31_t)0x62F201AC, (q31_t)0x4EBFE8A4, + (q31_t)0x64E88926, (q31_t)0x4C3FDFF3, (q31_t)0x66CF811F, + (q31_t)0x49B41533, (q31_t)0x68A69E81, (q31_t)0x471CECE6, + (q31_t)0x6A6D98A4, (q31_t)0x447ACD50, (q31_t)0x6C242960, + (q31_t)0x41CE1E64, (q31_t)0x6DCA0D14, (q31_t)0x3F1749B7, + (q31_t)0x6F5F02B1, (q31_t)0x3C56BA70, (q31_t)0x70E2CBC6, + (q31_t)0x398CDD32, (q31_t)0x72552C84, (q31_t)0x36BA2013, + (q31_t)0x73B5EBD0, (q31_t)0x33DEF287, (q31_t)0x7504D345, + (q31_t)0x30FBC54D, (q31_t)0x7641AF3C, (q31_t)0x2E110A62, + (q31_t)0x776C4EDB, (q31_t)0x2B1F34EB, (q31_t)0x78848413, + (q31_t)0x2826B928, (q31_t)0x798A23B1, (q31_t)0x25280C5D, + (q31_t)0x7A7D055B, (q31_t)0x2223A4C5, (q31_t)0x7B5D039D, + (q31_t)0x1F19F97B, (q31_t)0x7C29FBEE, (q31_t)0x1C0B826A, + (q31_t)0x7CE3CEB1, (q31_t)0x18F8B83C, (q31_t)0x7D8A5F3F, + (q31_t)0x15E21444, (q31_t)0x7E1D93E9, (q31_t)0x12C8106E, + (q31_t)0x7E9D55FC, (q31_t)0x0FAB272B, (q31_t)0x7F0991C3, + (q31_t)0x0C8BD35E, (q31_t)0x7F62368F, (q31_t)0x096A9049, + (q31_t)0x7FA736B4, (q31_t)0x0647D97C, (q31_t)0x7FD8878D, + (q31_t)0x03242ABF, (q31_t)0x7FF62182, (q31_t)0x00000000, + (q31_t)0x7FFFFFFF, (q31_t)0xFCDBD541, (q31_t)0x7FF62182, + (q31_t)0xF9B82683, (q31_t)0x7FD8878D, (q31_t)0xF6956FB6, + (q31_t)0x7FA736B4, (q31_t)0xF3742CA1, (q31_t)0x7F62368F, + (q31_t)0xF054D8D4, (q31_t)0x7F0991C3, (q31_t)0xED37EF91, + (q31_t)0x7E9D55FC, (q31_t)0xEA1DEBBB, (q31_t)0x7E1D93E9, + (q31_t)0xE70747C3, (q31_t)0x7D8A5F3F, (q31_t)0xE3F47D95, + (q31_t)0x7CE3CEB1, (q31_t)0xE0E60684, (q31_t)0x7C29FBEE, + (q31_t)0xDDDC5B3A, (q31_t)0x7B5D039D, (q31_t)0xDAD7F3A2, + (q31_t)0x7A7D055B, (q31_t)0xD7D946D7, (q31_t)0x798A23B1, + (q31_t)0xD4E0CB14, (q31_t)0x78848413, (q31_t)0xD1EEF59E, + (q31_t)0x776C4EDB, (q31_t)0xCF043AB2, (q31_t)0x7641AF3C, + (q31_t)0xCC210D78, (q31_t)0x7504D345, (q31_t)0xC945DFEC, + (q31_t)0x73B5EBD0, (q31_t)0xC67322CD, (q31_t)0x72552C84, + (q31_t)0xC3A9458F, (q31_t)0x70E2CBC6, (q31_t)0xC0E8B648, + (q31_t)0x6F5F02B1, (q31_t)0xBE31E19B, (q31_t)0x6DCA0D14, + (q31_t)0xBB8532AF, (q31_t)0x6C242960, (q31_t)0xB8E31319, + (q31_t)0x6A6D98A4, (q31_t)0xB64BEACC, (q31_t)0x68A69E81, + (q31_t)0xB3C0200C, (q31_t)0x66CF811F, (q31_t)0xB140175B, + (q31_t)0x64E88926, (q31_t)0xAECC336B, (q31_t)0x62F201AC, + (q31_t)0xAC64D510, (q31_t)0x60EC3830, (q31_t)0xAA0A5B2D, + (q31_t)0x5ED77C89, (q31_t)0xA7BD22AB, (q31_t)0x5CB420DF, + (q31_t)0xA57D8666, (q31_t)0x5A82799A, (q31_t)0xA34BDF20, + (q31_t)0x5842DD54, (q31_t)0xA1288376, (q31_t)0x55F5A4D2, + (q31_t)0x9F13C7D0, (q31_t)0x539B2AEF, (q31_t)0x9D0DFE53, + (q31_t)0x5133CC94, (q31_t)0x9B1776D9, (q31_t)0x4EBFE8A4, + (q31_t)0x99307EE0, (q31_t)0x4C3FDFF3, (q31_t)0x9759617E, + (q31_t)0x49B41533, (q31_t)0x9592675B, (q31_t)0x471CECE6, + (q31_t)0x93DBD69F, (q31_t)0x447ACD50, (q31_t)0x9235F2EB, + (q31_t)0x41CE1E64, (q31_t)0x90A0FD4E, (q31_t)0x3F1749B7, + (q31_t)0x8F1D343A, (q31_t)0x3C56BA70, (q31_t)0x8DAAD37B, + (q31_t)0x398CDD32, (q31_t)0x8C4A142F, (q31_t)0x36BA2013, + (q31_t)0x8AFB2CBA, (q31_t)0x33DEF287, (q31_t)0x89BE50C3, + (q31_t)0x30FBC54D, (q31_t)0x8893B124, (q31_t)0x2E110A62, + (q31_t)0x877B7BEC, (q31_t)0x2B1F34EB, (q31_t)0x8675DC4E, + (q31_t)0x2826B928, (q31_t)0x8582FAA4, (q31_t)0x25280C5D, + (q31_t)0x84A2FC62, (q31_t)0x2223A4C5, (q31_t)0x83D60411, + (q31_t)0x1F19F97B, (q31_t)0x831C314E, (q31_t)0x1C0B826A, + (q31_t)0x8275A0C0, (q31_t)0x18F8B83C, (q31_t)0x81E26C16, + (q31_t)0x15E21444, (q31_t)0x8162AA03, (q31_t)0x12C8106E, + (q31_t)0x80F66E3C, (q31_t)0x0FAB272B, (q31_t)0x809DC970, + (q31_t)0x0C8BD35E, (q31_t)0x8058C94C, (q31_t)0x096A9049, + (q31_t)0x80277872, (q31_t)0x0647D97C, (q31_t)0x8009DE7D, + (q31_t)0x03242ABF, (q31_t)0x80000000, (q31_t)0x00000000, + (q31_t)0x8009DE7D, (q31_t)0xFCDBD541, (q31_t)0x80277872, + (q31_t)0xF9B82683, (q31_t)0x8058C94C, (q31_t)0xF6956FB6, + (q31_t)0x809DC970, (q31_t)0xF3742CA1, (q31_t)0x80F66E3C, + (q31_t)0xF054D8D4, (q31_t)0x8162AA03, (q31_t)0xED37EF91, + (q31_t)0x81E26C16, (q31_t)0xEA1DEBBB, (q31_t)0x8275A0C0, + (q31_t)0xE70747C3, (q31_t)0x831C314E, (q31_t)0xE3F47D95, + (q31_t)0x83D60411, (q31_t)0xE0E60684, (q31_t)0x84A2FC62, + (q31_t)0xDDDC5B3A, (q31_t)0x8582FAA4, (q31_t)0xDAD7F3A2, + (q31_t)0x8675DC4E, (q31_t)0xD7D946D7, (q31_t)0x877B7BEC, + (q31_t)0xD4E0CB14, (q31_t)0x8893B124, (q31_t)0xD1EEF59E, + (q31_t)0x89BE50C3, (q31_t)0xCF043AB2, (q31_t)0x8AFB2CBA, + (q31_t)0xCC210D78, (q31_t)0x8C4A142F, (q31_t)0xC945DFEC, + (q31_t)0x8DAAD37B, (q31_t)0xC67322CD, (q31_t)0x8F1D343A, + (q31_t)0xC3A9458F, (q31_t)0x90A0FD4E, (q31_t)0xC0E8B648, + (q31_t)0x9235F2EB, (q31_t)0xBE31E19B, (q31_t)0x93DBD69F, + (q31_t)0xBB8532AF, (q31_t)0x9592675B, (q31_t)0xB8E31319, + (q31_t)0x9759617E, (q31_t)0xB64BEACC, (q31_t)0x99307EE0, + (q31_t)0xB3C0200C, (q31_t)0x9B1776D9, (q31_t)0xB140175B, + (q31_t)0x9D0DFE53, (q31_t)0xAECC336B, (q31_t)0x9F13C7D0, + (q31_t)0xAC64D510, (q31_t)0xA1288376, (q31_t)0xAA0A5B2D, + (q31_t)0xA34BDF20, (q31_t)0xA7BD22AB, (q31_t)0xA57D8666, + (q31_t)0xA57D8666, (q31_t)0xA7BD22AB, (q31_t)0xA34BDF20, + (q31_t)0xAA0A5B2D, (q31_t)0xA1288376, (q31_t)0xAC64D510, + (q31_t)0x9F13C7D0, (q31_t)0xAECC336B, (q31_t)0x9D0DFE53, + (q31_t)0xB140175B, (q31_t)0x9B1776D9, (q31_t)0xB3C0200C, + (q31_t)0x99307EE0, (q31_t)0xB64BEACC, (q31_t)0x9759617E, + (q31_t)0xB8E31319, (q31_t)0x9592675B, (q31_t)0xBB8532AF, + (q31_t)0x93DBD69F, (q31_t)0xBE31E19B, (q31_t)0x9235F2EB, + (q31_t)0xC0E8B648, (q31_t)0x90A0FD4E, (q31_t)0xC3A9458F, + (q31_t)0x8F1D343A, (q31_t)0xC67322CD, (q31_t)0x8DAAD37B, + (q31_t)0xC945DFEC, (q31_t)0x8C4A142F, (q31_t)0xCC210D78, + (q31_t)0x8AFB2CBA, (q31_t)0xCF043AB2, (q31_t)0x89BE50C3, + (q31_t)0xD1EEF59E, (q31_t)0x8893B124, (q31_t)0xD4E0CB14, + (q31_t)0x877B7BEC, (q31_t)0xD7D946D7, (q31_t)0x8675DC4E, + (q31_t)0xDAD7F3A2, (q31_t)0x8582FAA4, (q31_t)0xDDDC5B3A, + (q31_t)0x84A2FC62, (q31_t)0xE0E60684, (q31_t)0x83D60411, + (q31_t)0xE3F47D95, (q31_t)0x831C314E, (q31_t)0xE70747C3, + (q31_t)0x8275A0C0, (q31_t)0xEA1DEBBB, (q31_t)0x81E26C16, + (q31_t)0xED37EF91, (q31_t)0x8162AA03, (q31_t)0xF054D8D4, + (q31_t)0x80F66E3C, (q31_t)0xF3742CA1, (q31_t)0x809DC970, + (q31_t)0xF6956FB6, (q31_t)0x8058C94C, (q31_t)0xF9B82683, + (q31_t)0x80277872, (q31_t)0xFCDBD541, (q31_t)0x8009DE7D +}; + +/** + @par + Example code for Q31 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefQ31[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefQ31[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 512, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to Q31(Fixed point 1.31): + round(twiddleCoefQ31(i) * pow(2, 31)) + + */ +const q31_t twiddleCoef_512_q31[768] = { + (q31_t)0x7FFFFFFF, (q31_t)0x00000000, (q31_t)0x7FFD885A, + (q31_t)0x01921D1F, (q31_t)0x7FF62182, (q31_t)0x03242ABF, + (q31_t)0x7FE9CBC0, (q31_t)0x04B6195D, (q31_t)0x7FD8878D, + (q31_t)0x0647D97C, (q31_t)0x7FC25596, (q31_t)0x07D95B9E, + (q31_t)0x7FA736B4, (q31_t)0x096A9049, (q31_t)0x7F872BF3, + (q31_t)0x0AFB6805, (q31_t)0x7F62368F, (q31_t)0x0C8BD35E, + (q31_t)0x7F3857F5, (q31_t)0x0E1BC2E3, (q31_t)0x7F0991C3, + (q31_t)0x0FAB272B, (q31_t)0x7ED5E5C6, (q31_t)0x1139F0CE, + (q31_t)0x7E9D55FC, (q31_t)0x12C8106E, (q31_t)0x7E5FE493, + (q31_t)0x145576B1, (q31_t)0x7E1D93E9, (q31_t)0x15E21444, + (q31_t)0x7DD6668E, (q31_t)0x176DD9DE, (q31_t)0x7D8A5F3F, + (q31_t)0x18F8B83C, (q31_t)0x7D3980EC, (q31_t)0x1A82A025, + (q31_t)0x7CE3CEB1, (q31_t)0x1C0B826A, (q31_t)0x7C894BDD, + (q31_t)0x1D934FE5, (q31_t)0x7C29FBEE, (q31_t)0x1F19F97B, + (q31_t)0x7BC5E28F, (q31_t)0x209F701C, (q31_t)0x7B5D039D, + (q31_t)0x2223A4C5, (q31_t)0x7AEF6323, (q31_t)0x23A6887E, + (q31_t)0x7A7D055B, (q31_t)0x25280C5D, (q31_t)0x7A05EEAD, + (q31_t)0x26A82185, (q31_t)0x798A23B1, (q31_t)0x2826B928, + (q31_t)0x7909A92C, (q31_t)0x29A3C484, (q31_t)0x78848413, + (q31_t)0x2B1F34EB, (q31_t)0x77FAB988, (q31_t)0x2C98FBBA, + (q31_t)0x776C4EDB, (q31_t)0x2E110A62, (q31_t)0x76D94988, + (q31_t)0x2F875262, (q31_t)0x7641AF3C, (q31_t)0x30FBC54D, + (q31_t)0x75A585CF, (q31_t)0x326E54C7, (q31_t)0x7504D345, + (q31_t)0x33DEF287, (q31_t)0x745F9DD1, (q31_t)0x354D9056, + (q31_t)0x73B5EBD0, (q31_t)0x36BA2013, (q31_t)0x7307C3D0, + (q31_t)0x382493B0, (q31_t)0x72552C84, (q31_t)0x398CDD32, + (q31_t)0x719E2CD2, (q31_t)0x3AF2EEB7, (q31_t)0x70E2CBC6, + (q31_t)0x3C56BA70, (q31_t)0x70231099, (q31_t)0x3DB832A5, + (q31_t)0x6F5F02B1, (q31_t)0x3F1749B7, (q31_t)0x6E96A99C, + (q31_t)0x4073F21D, (q31_t)0x6DCA0D14, (q31_t)0x41CE1E64, + (q31_t)0x6CF934FB, (q31_t)0x4325C135, (q31_t)0x6C242960, + (q31_t)0x447ACD50, (q31_t)0x6B4AF278, (q31_t)0x45CD358F, + (q31_t)0x6A6D98A4, (q31_t)0x471CECE6, (q31_t)0x698C246C, + (q31_t)0x4869E664, (q31_t)0x68A69E81, (q31_t)0x49B41533, + (q31_t)0x67BD0FBC, (q31_t)0x4AFB6C97, (q31_t)0x66CF811F, + (q31_t)0x4C3FDFF3, (q31_t)0x65DDFBD3, (q31_t)0x4D8162C4, + (q31_t)0x64E88926, (q31_t)0x4EBFE8A4, (q31_t)0x63EF328F, + (q31_t)0x4FFB654D, (q31_t)0x62F201AC, (q31_t)0x5133CC94, + (q31_t)0x61F1003E, (q31_t)0x5269126E, (q31_t)0x60EC3830, + (q31_t)0x539B2AEF, (q31_t)0x5FE3B38D, (q31_t)0x54CA0A4A, + (q31_t)0x5ED77C89, (q31_t)0x55F5A4D2, (q31_t)0x5DC79D7C, + (q31_t)0x571DEEF9, (q31_t)0x5CB420DF, (q31_t)0x5842DD54, + (q31_t)0x5B9D1153, (q31_t)0x59646497, (q31_t)0x5A82799A, + (q31_t)0x5A82799A, (q31_t)0x59646497, (q31_t)0x5B9D1153, + (q31_t)0x5842DD54, (q31_t)0x5CB420DF, (q31_t)0x571DEEF9, + (q31_t)0x5DC79D7C, (q31_t)0x55F5A4D2, (q31_t)0x5ED77C89, + (q31_t)0x54CA0A4A, (q31_t)0x5FE3B38D, (q31_t)0x539B2AEF, + (q31_t)0x60EC3830, (q31_t)0x5269126E, (q31_t)0x61F1003E, + (q31_t)0x5133CC94, (q31_t)0x62F201AC, (q31_t)0x4FFB654D, + (q31_t)0x63EF328F, (q31_t)0x4EBFE8A4, (q31_t)0x64E88926, + (q31_t)0x4D8162C4, (q31_t)0x65DDFBD3, (q31_t)0x4C3FDFF3, + (q31_t)0x66CF811F, (q31_t)0x4AFB6C97, (q31_t)0x67BD0FBC, + (q31_t)0x49B41533, (q31_t)0x68A69E81, (q31_t)0x4869E664, + (q31_t)0x698C246C, (q31_t)0x471CECE6, (q31_t)0x6A6D98A4, + (q31_t)0x45CD358F, (q31_t)0x6B4AF278, (q31_t)0x447ACD50, + (q31_t)0x6C242960, (q31_t)0x4325C135, (q31_t)0x6CF934FB, + (q31_t)0x41CE1E64, (q31_t)0x6DCA0D14, (q31_t)0x4073F21D, + (q31_t)0x6E96A99C, (q31_t)0x3F1749B7, (q31_t)0x6F5F02B1, + (q31_t)0x3DB832A5, (q31_t)0x70231099, (q31_t)0x3C56BA70, + (q31_t)0x70E2CBC6, (q31_t)0x3AF2EEB7, (q31_t)0x719E2CD2, + (q31_t)0x398CDD32, (q31_t)0x72552C84, (q31_t)0x382493B0, + (q31_t)0x7307C3D0, (q31_t)0x36BA2013, (q31_t)0x73B5EBD0, + (q31_t)0x354D9056, (q31_t)0x745F9DD1, (q31_t)0x33DEF287, + (q31_t)0x7504D345, (q31_t)0x326E54C7, (q31_t)0x75A585CF, + (q31_t)0x30FBC54D, (q31_t)0x7641AF3C, (q31_t)0x2F875262, + (q31_t)0x76D94988, (q31_t)0x2E110A62, (q31_t)0x776C4EDB, + (q31_t)0x2C98FBBA, (q31_t)0x77FAB988, (q31_t)0x2B1F34EB, + (q31_t)0x78848413, (q31_t)0x29A3C484, (q31_t)0x7909A92C, + (q31_t)0x2826B928, (q31_t)0x798A23B1, (q31_t)0x26A82185, + (q31_t)0x7A05EEAD, (q31_t)0x25280C5D, (q31_t)0x7A7D055B, + (q31_t)0x23A6887E, (q31_t)0x7AEF6323, (q31_t)0x2223A4C5, + (q31_t)0x7B5D039D, (q31_t)0x209F701C, (q31_t)0x7BC5E28F, + (q31_t)0x1F19F97B, (q31_t)0x7C29FBEE, (q31_t)0x1D934FE5, + (q31_t)0x7C894BDD, (q31_t)0x1C0B826A, (q31_t)0x7CE3CEB1, + (q31_t)0x1A82A025, (q31_t)0x7D3980EC, (q31_t)0x18F8B83C, + (q31_t)0x7D8A5F3F, (q31_t)0x176DD9DE, (q31_t)0x7DD6668E, + (q31_t)0x15E21444, (q31_t)0x7E1D93E9, (q31_t)0x145576B1, + (q31_t)0x7E5FE493, (q31_t)0x12C8106E, (q31_t)0x7E9D55FC, + (q31_t)0x1139F0CE, (q31_t)0x7ED5E5C6, (q31_t)0x0FAB272B, + (q31_t)0x7F0991C3, (q31_t)0x0E1BC2E3, (q31_t)0x7F3857F5, + (q31_t)0x0C8BD35E, (q31_t)0x7F62368F, (q31_t)0x0AFB6805, + (q31_t)0x7F872BF3, (q31_t)0x096A9049, (q31_t)0x7FA736B4, + (q31_t)0x07D95B9E, (q31_t)0x7FC25596, (q31_t)0x0647D97C, + (q31_t)0x7FD8878D, (q31_t)0x04B6195D, (q31_t)0x7FE9CBC0, + (q31_t)0x03242ABF, (q31_t)0x7FF62182, (q31_t)0x01921D1F, + (q31_t)0x7FFD885A, (q31_t)0x00000000, (q31_t)0x7FFFFFFF, + (q31_t)0xFE6DE2E0, (q31_t)0x7FFD885A, (q31_t)0xFCDBD541, + (q31_t)0x7FF62182, (q31_t)0xFB49E6A2, (q31_t)0x7FE9CBC0, + (q31_t)0xF9B82683, (q31_t)0x7FD8878D, (q31_t)0xF826A461, + (q31_t)0x7FC25596, (q31_t)0xF6956FB6, (q31_t)0x7FA736B4, + (q31_t)0xF50497FA, (q31_t)0x7F872BF3, (q31_t)0xF3742CA1, + (q31_t)0x7F62368F, (q31_t)0xF1E43D1C, (q31_t)0x7F3857F5, + (q31_t)0xF054D8D4, (q31_t)0x7F0991C3, (q31_t)0xEEC60F31, + (q31_t)0x7ED5E5C6, (q31_t)0xED37EF91, (q31_t)0x7E9D55FC, + (q31_t)0xEBAA894E, (q31_t)0x7E5FE493, (q31_t)0xEA1DEBBB, + (q31_t)0x7E1D93E9, (q31_t)0xE8922621, (q31_t)0x7DD6668E, + (q31_t)0xE70747C3, (q31_t)0x7D8A5F3F, (q31_t)0xE57D5FDA, + (q31_t)0x7D3980EC, (q31_t)0xE3F47D95, (q31_t)0x7CE3CEB1, + (q31_t)0xE26CB01A, (q31_t)0x7C894BDD, (q31_t)0xE0E60684, + (q31_t)0x7C29FBEE, (q31_t)0xDF608FE3, (q31_t)0x7BC5E28F, + (q31_t)0xDDDC5B3A, (q31_t)0x7B5D039D, (q31_t)0xDC597781, + (q31_t)0x7AEF6323, (q31_t)0xDAD7F3A2, (q31_t)0x7A7D055B, + (q31_t)0xD957DE7A, (q31_t)0x7A05EEAD, (q31_t)0xD7D946D7, + (q31_t)0x798A23B1, (q31_t)0xD65C3B7B, (q31_t)0x7909A92C, + (q31_t)0xD4E0CB14, (q31_t)0x78848413, (q31_t)0xD3670445, + (q31_t)0x77FAB988, (q31_t)0xD1EEF59E, (q31_t)0x776C4EDB, + (q31_t)0xD078AD9D, (q31_t)0x76D94988, (q31_t)0xCF043AB2, + (q31_t)0x7641AF3C, (q31_t)0xCD91AB38, (q31_t)0x75A585CF, + (q31_t)0xCC210D78, (q31_t)0x7504D345, (q31_t)0xCAB26FA9, + (q31_t)0x745F9DD1, (q31_t)0xC945DFEC, (q31_t)0x73B5EBD0, + (q31_t)0xC7DB6C50, (q31_t)0x7307C3D0, (q31_t)0xC67322CD, + (q31_t)0x72552C84, (q31_t)0xC50D1148, (q31_t)0x719E2CD2, + (q31_t)0xC3A9458F, (q31_t)0x70E2CBC6, (q31_t)0xC247CD5A, + (q31_t)0x70231099, (q31_t)0xC0E8B648, (q31_t)0x6F5F02B1, + (q31_t)0xBF8C0DE2, (q31_t)0x6E96A99C, (q31_t)0xBE31E19B, + (q31_t)0x6DCA0D14, (q31_t)0xBCDA3ECA, (q31_t)0x6CF934FB, + (q31_t)0xBB8532AF, (q31_t)0x6C242960, (q31_t)0xBA32CA70, + (q31_t)0x6B4AF278, (q31_t)0xB8E31319, (q31_t)0x6A6D98A4, + (q31_t)0xB796199B, (q31_t)0x698C246C, (q31_t)0xB64BEACC, + (q31_t)0x68A69E81, (q31_t)0xB5049368, (q31_t)0x67BD0FBC, + (q31_t)0xB3C0200C, (q31_t)0x66CF811F, (q31_t)0xB27E9D3B, + (q31_t)0x65DDFBD3, (q31_t)0xB140175B, (q31_t)0x64E88926, + (q31_t)0xB0049AB2, (q31_t)0x63EF328F, (q31_t)0xAECC336B, + (q31_t)0x62F201AC, (q31_t)0xAD96ED91, (q31_t)0x61F1003E, + (q31_t)0xAC64D510, (q31_t)0x60EC3830, (q31_t)0xAB35F5B5, + (q31_t)0x5FE3B38D, (q31_t)0xAA0A5B2D, (q31_t)0x5ED77C89, + (q31_t)0xA8E21106, (q31_t)0x5DC79D7C, (q31_t)0xA7BD22AB, + (q31_t)0x5CB420DF, (q31_t)0xA69B9B68, (q31_t)0x5B9D1153, + (q31_t)0xA57D8666, (q31_t)0x5A82799A, (q31_t)0xA462EEAC, + (q31_t)0x59646497, (q31_t)0xA34BDF20, (q31_t)0x5842DD54, + (q31_t)0xA2386283, (q31_t)0x571DEEF9, (q31_t)0xA1288376, + (q31_t)0x55F5A4D2, (q31_t)0xA01C4C72, (q31_t)0x54CA0A4A, + (q31_t)0x9F13C7D0, (q31_t)0x539B2AEF, (q31_t)0x9E0EFFC1, + (q31_t)0x5269126E, (q31_t)0x9D0DFE53, (q31_t)0x5133CC94, + (q31_t)0x9C10CD70, (q31_t)0x4FFB654D, (q31_t)0x9B1776D9, + (q31_t)0x4EBFE8A4, (q31_t)0x9A22042C, (q31_t)0x4D8162C4, + (q31_t)0x99307EE0, (q31_t)0x4C3FDFF3, (q31_t)0x9842F043, + (q31_t)0x4AFB6C97, (q31_t)0x9759617E, (q31_t)0x49B41533, + (q31_t)0x9673DB94, (q31_t)0x4869E664, (q31_t)0x9592675B, + (q31_t)0x471CECE6, (q31_t)0x94B50D87, (q31_t)0x45CD358F, + (q31_t)0x93DBD69F, (q31_t)0x447ACD50, (q31_t)0x9306CB04, + (q31_t)0x4325C135, (q31_t)0x9235F2EB, (q31_t)0x41CE1E64, + (q31_t)0x91695663, (q31_t)0x4073F21D, (q31_t)0x90A0FD4E, + (q31_t)0x3F1749B7, (q31_t)0x8FDCEF66, (q31_t)0x3DB832A5, + (q31_t)0x8F1D343A, (q31_t)0x3C56BA70, (q31_t)0x8E61D32D, + (q31_t)0x3AF2EEB7, (q31_t)0x8DAAD37B, (q31_t)0x398CDD32, + (q31_t)0x8CF83C30, (q31_t)0x382493B0, (q31_t)0x8C4A142F, + (q31_t)0x36BA2013, (q31_t)0x8BA0622F, (q31_t)0x354D9056, + (q31_t)0x8AFB2CBA, (q31_t)0x33DEF287, (q31_t)0x8A5A7A30, + (q31_t)0x326E54C7, (q31_t)0x89BE50C3, (q31_t)0x30FBC54D, + (q31_t)0x8926B677, (q31_t)0x2F875262, (q31_t)0x8893B124, + (q31_t)0x2E110A62, (q31_t)0x88054677, (q31_t)0x2C98FBBA, + (q31_t)0x877B7BEC, (q31_t)0x2B1F34EB, (q31_t)0x86F656D3, + (q31_t)0x29A3C484, (q31_t)0x8675DC4E, (q31_t)0x2826B928, + (q31_t)0x85FA1152, (q31_t)0x26A82185, (q31_t)0x8582FAA4, + (q31_t)0x25280C5D, (q31_t)0x85109CDC, (q31_t)0x23A6887E, + (q31_t)0x84A2FC62, (q31_t)0x2223A4C5, (q31_t)0x843A1D70, + (q31_t)0x209F701C, (q31_t)0x83D60411, (q31_t)0x1F19F97B, + (q31_t)0x8376B422, (q31_t)0x1D934FE5, (q31_t)0x831C314E, + (q31_t)0x1C0B826A, (q31_t)0x82C67F13, (q31_t)0x1A82A025, + (q31_t)0x8275A0C0, (q31_t)0x18F8B83C, (q31_t)0x82299971, + (q31_t)0x176DD9DE, (q31_t)0x81E26C16, (q31_t)0x15E21444, + (q31_t)0x81A01B6C, (q31_t)0x145576B1, (q31_t)0x8162AA03, + (q31_t)0x12C8106E, (q31_t)0x812A1A39, (q31_t)0x1139F0CE, + (q31_t)0x80F66E3C, (q31_t)0x0FAB272B, (q31_t)0x80C7A80A, + (q31_t)0x0E1BC2E3, (q31_t)0x809DC970, (q31_t)0x0C8BD35E, + (q31_t)0x8078D40D, (q31_t)0x0AFB6805, (q31_t)0x8058C94C, + (q31_t)0x096A9049, (q31_t)0x803DAA69, (q31_t)0x07D95B9E, + (q31_t)0x80277872, (q31_t)0x0647D97C, (q31_t)0x80163440, + (q31_t)0x04B6195D, (q31_t)0x8009DE7D, (q31_t)0x03242ABF, + (q31_t)0x800277A5, (q31_t)0x01921D1F, (q31_t)0x80000000, + (q31_t)0x00000000, (q31_t)0x800277A5, (q31_t)0xFE6DE2E0, + (q31_t)0x8009DE7D, (q31_t)0xFCDBD541, (q31_t)0x80163440, + (q31_t)0xFB49E6A2, (q31_t)0x80277872, (q31_t)0xF9B82683, + (q31_t)0x803DAA69, (q31_t)0xF826A461, (q31_t)0x8058C94C, + (q31_t)0xF6956FB6, (q31_t)0x8078D40D, (q31_t)0xF50497FA, + (q31_t)0x809DC970, (q31_t)0xF3742CA1, (q31_t)0x80C7A80A, + (q31_t)0xF1E43D1C, (q31_t)0x80F66E3C, (q31_t)0xF054D8D4, + (q31_t)0x812A1A39, (q31_t)0xEEC60F31, (q31_t)0x8162AA03, + (q31_t)0xED37EF91, (q31_t)0x81A01B6C, (q31_t)0xEBAA894E, + (q31_t)0x81E26C16, (q31_t)0xEA1DEBBB, (q31_t)0x82299971, + (q31_t)0xE8922621, (q31_t)0x8275A0C0, (q31_t)0xE70747C3, + (q31_t)0x82C67F13, (q31_t)0xE57D5FDA, (q31_t)0x831C314E, + (q31_t)0xE3F47D95, (q31_t)0x8376B422, (q31_t)0xE26CB01A, + (q31_t)0x83D60411, (q31_t)0xE0E60684, (q31_t)0x843A1D70, + (q31_t)0xDF608FE3, (q31_t)0x84A2FC62, (q31_t)0xDDDC5B3A, + (q31_t)0x85109CDC, (q31_t)0xDC597781, (q31_t)0x8582FAA4, + (q31_t)0xDAD7F3A2, (q31_t)0x85FA1152, (q31_t)0xD957DE7A, + (q31_t)0x8675DC4E, (q31_t)0xD7D946D7, (q31_t)0x86F656D3, + (q31_t)0xD65C3B7B, (q31_t)0x877B7BEC, (q31_t)0xD4E0CB14, + (q31_t)0x88054677, (q31_t)0xD3670445, (q31_t)0x8893B124, + (q31_t)0xD1EEF59E, (q31_t)0x8926B677, (q31_t)0xD078AD9D, + (q31_t)0x89BE50C3, (q31_t)0xCF043AB2, (q31_t)0x8A5A7A30, + (q31_t)0xCD91AB38, (q31_t)0x8AFB2CBA, (q31_t)0xCC210D78, + (q31_t)0x8BA0622F, (q31_t)0xCAB26FA9, (q31_t)0x8C4A142F, + (q31_t)0xC945DFEC, (q31_t)0x8CF83C30, (q31_t)0xC7DB6C50, + (q31_t)0x8DAAD37B, (q31_t)0xC67322CD, (q31_t)0x8E61D32D, + (q31_t)0xC50D1148, (q31_t)0x8F1D343A, (q31_t)0xC3A9458F, + (q31_t)0x8FDCEF66, (q31_t)0xC247CD5A, (q31_t)0x90A0FD4E, + (q31_t)0xC0E8B648, (q31_t)0x91695663, (q31_t)0xBF8C0DE2, + (q31_t)0x9235F2EB, (q31_t)0xBE31E19B, (q31_t)0x9306CB04, + (q31_t)0xBCDA3ECA, (q31_t)0x93DBD69F, (q31_t)0xBB8532AF, + (q31_t)0x94B50D87, (q31_t)0xBA32CA70, (q31_t)0x9592675B, + (q31_t)0xB8E31319, (q31_t)0x9673DB94, (q31_t)0xB796199B, + (q31_t)0x9759617E, (q31_t)0xB64BEACC, (q31_t)0x9842F043, + (q31_t)0xB5049368, (q31_t)0x99307EE0, (q31_t)0xB3C0200C, + (q31_t)0x9A22042C, (q31_t)0xB27E9D3B, (q31_t)0x9B1776D9, + (q31_t)0xB140175B, (q31_t)0x9C10CD70, (q31_t)0xB0049AB2, + (q31_t)0x9D0DFE53, (q31_t)0xAECC336B, (q31_t)0x9E0EFFC1, + (q31_t)0xAD96ED91, (q31_t)0x9F13C7D0, (q31_t)0xAC64D510, + (q31_t)0xA01C4C72, (q31_t)0xAB35F5B5, (q31_t)0xA1288376, + (q31_t)0xAA0A5B2D, (q31_t)0xA2386283, (q31_t)0xA8E21106, + (q31_t)0xA34BDF20, (q31_t)0xA7BD22AB, (q31_t)0xA462EEAC, + (q31_t)0xA69B9B68, (q31_t)0xA57D8666, (q31_t)0xA57D8666, + (q31_t)0xA69B9B68, (q31_t)0xA462EEAC, (q31_t)0xA7BD22AB, + (q31_t)0xA34BDF20, (q31_t)0xA8E21106, (q31_t)0xA2386283, + (q31_t)0xAA0A5B2D, (q31_t)0xA1288376, (q31_t)0xAB35F5B5, + (q31_t)0xA01C4C72, (q31_t)0xAC64D510, (q31_t)0x9F13C7D0, + (q31_t)0xAD96ED91, (q31_t)0x9E0EFFC1, (q31_t)0xAECC336B, + (q31_t)0x9D0DFE53, (q31_t)0xB0049AB2, (q31_t)0x9C10CD70, + (q31_t)0xB140175B, (q31_t)0x9B1776D9, (q31_t)0xB27E9D3B, + (q31_t)0x9A22042C, (q31_t)0xB3C0200C, (q31_t)0x99307EE0, + (q31_t)0xB5049368, (q31_t)0x9842F043, (q31_t)0xB64BEACC, + (q31_t)0x9759617E, (q31_t)0xB796199B, (q31_t)0x9673DB94, + (q31_t)0xB8E31319, (q31_t)0x9592675B, (q31_t)0xBA32CA70, + (q31_t)0x94B50D87, (q31_t)0xBB8532AF, (q31_t)0x93DBD69F, + (q31_t)0xBCDA3ECA, (q31_t)0x9306CB04, (q31_t)0xBE31E19B, + (q31_t)0x9235F2EB, (q31_t)0xBF8C0DE2, (q31_t)0x91695663, + (q31_t)0xC0E8B648, (q31_t)0x90A0FD4E, (q31_t)0xC247CD5A, + (q31_t)0x8FDCEF66, (q31_t)0xC3A9458F, (q31_t)0x8F1D343A, + (q31_t)0xC50D1148, (q31_t)0x8E61D32D, (q31_t)0xC67322CD, + (q31_t)0x8DAAD37B, (q31_t)0xC7DB6C50, (q31_t)0x8CF83C30, + (q31_t)0xC945DFEC, (q31_t)0x8C4A142F, (q31_t)0xCAB26FA9, + (q31_t)0x8BA0622F, (q31_t)0xCC210D78, (q31_t)0x8AFB2CBA, + (q31_t)0xCD91AB38, (q31_t)0x8A5A7A30, (q31_t)0xCF043AB2, + (q31_t)0x89BE50C3, (q31_t)0xD078AD9D, (q31_t)0x8926B677, + (q31_t)0xD1EEF59E, (q31_t)0x8893B124, (q31_t)0xD3670445, + (q31_t)0x88054677, (q31_t)0xD4E0CB14, (q31_t)0x877B7BEC, + (q31_t)0xD65C3B7B, (q31_t)0x86F656D3, (q31_t)0xD7D946D7, + (q31_t)0x8675DC4E, (q31_t)0xD957DE7A, (q31_t)0x85FA1152, + (q31_t)0xDAD7F3A2, (q31_t)0x8582FAA4, (q31_t)0xDC597781, + (q31_t)0x85109CDC, (q31_t)0xDDDC5B3A, (q31_t)0x84A2FC62, + (q31_t)0xDF608FE3, (q31_t)0x843A1D70, (q31_t)0xE0E60684, + (q31_t)0x83D60411, (q31_t)0xE26CB01A, (q31_t)0x8376B422, + (q31_t)0xE3F47D95, (q31_t)0x831C314E, (q31_t)0xE57D5FDA, + (q31_t)0x82C67F13, (q31_t)0xE70747C3, (q31_t)0x8275A0C0, + (q31_t)0xE8922621, (q31_t)0x82299971, (q31_t)0xEA1DEBBB, + (q31_t)0x81E26C16, (q31_t)0xEBAA894E, (q31_t)0x81A01B6C, + (q31_t)0xED37EF91, (q31_t)0x8162AA03, (q31_t)0xEEC60F31, + (q31_t)0x812A1A39, (q31_t)0xF054D8D4, (q31_t)0x80F66E3C, + (q31_t)0xF1E43D1C, (q31_t)0x80C7A80A, (q31_t)0xF3742CA1, + (q31_t)0x809DC970, (q31_t)0xF50497FA, (q31_t)0x8078D40D, + (q31_t)0xF6956FB6, (q31_t)0x8058C94C, (q31_t)0xF826A461, + (q31_t)0x803DAA69, (q31_t)0xF9B82683, (q31_t)0x80277872, + (q31_t)0xFB49E6A2, (q31_t)0x80163440, (q31_t)0xFCDBD541, + (q31_t)0x8009DE7D, (q31_t)0xFE6DE2E0, (q31_t)0x800277A5 +}; + +/** + @par + Example code for Q31 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefQ31[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefQ31[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 1024, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to Q31(Fixed point 1.31): + round(twiddleCoefQ31(i) * pow(2, 31)) + + */ +const q31_t twiddleCoef_1024_q31[1536] = { + (q31_t)0x7FFFFFFF, (q31_t)0x00000000, (q31_t)0x7FFF6216, + (q31_t)0x00C90F88, (q31_t)0x7FFD885A, (q31_t)0x01921D1F, + (q31_t)0x7FFA72D1, (q31_t)0x025B26D7, (q31_t)0x7FF62182, + (q31_t)0x03242ABF, (q31_t)0x7FF09477, (q31_t)0x03ED26E6, + (q31_t)0x7FE9CBC0, (q31_t)0x04B6195D, (q31_t)0x7FE1C76B, + (q31_t)0x057F0034, (q31_t)0x7FD8878D, (q31_t)0x0647D97C, + (q31_t)0x7FCE0C3E, (q31_t)0x0710A344, (q31_t)0x7FC25596, + (q31_t)0x07D95B9E, (q31_t)0x7FB563B2, (q31_t)0x08A2009A, + (q31_t)0x7FA736B4, (q31_t)0x096A9049, (q31_t)0x7F97CEBC, + (q31_t)0x0A3308BC, (q31_t)0x7F872BF3, (q31_t)0x0AFB6805, + (q31_t)0x7F754E7F, (q31_t)0x0BC3AC35, (q31_t)0x7F62368F, + (q31_t)0x0C8BD35E, (q31_t)0x7F4DE450, (q31_t)0x0D53DB92, + (q31_t)0x7F3857F5, (q31_t)0x0E1BC2E3, (q31_t)0x7F2191B4, + (q31_t)0x0EE38765, (q31_t)0x7F0991C3, (q31_t)0x0FAB272B, + (q31_t)0x7EF0585F, (q31_t)0x1072A047, (q31_t)0x7ED5E5C6, + (q31_t)0x1139F0CE, (q31_t)0x7EBA3A39, (q31_t)0x120116D4, + (q31_t)0x7E9D55FC, (q31_t)0x12C8106E, (q31_t)0x7E7F3956, + (q31_t)0x138EDBB0, (q31_t)0x7E5FE493, (q31_t)0x145576B1, + (q31_t)0x7E3F57FE, (q31_t)0x151BDF85, (q31_t)0x7E1D93E9, + (q31_t)0x15E21444, (q31_t)0x7DFA98A7, (q31_t)0x16A81305, + (q31_t)0x7DD6668E, (q31_t)0x176DD9DE, (q31_t)0x7DB0FDF7, + (q31_t)0x183366E8, (q31_t)0x7D8A5F3F, (q31_t)0x18F8B83C, + (q31_t)0x7D628AC5, (q31_t)0x19BDCBF2, (q31_t)0x7D3980EC, + (q31_t)0x1A82A025, (q31_t)0x7D0F4218, (q31_t)0x1B4732EF, + (q31_t)0x7CE3CEB1, (q31_t)0x1C0B826A, (q31_t)0x7CB72724, + (q31_t)0x1CCF8CB3, (q31_t)0x7C894BDD, (q31_t)0x1D934FE5, + (q31_t)0x7C5A3D4F, (q31_t)0x1E56CA1E, (q31_t)0x7C29FBEE, + (q31_t)0x1F19F97B, (q31_t)0x7BF88830, (q31_t)0x1FDCDC1A, + (q31_t)0x7BC5E28F, (q31_t)0x209F701C, (q31_t)0x7B920B89, + (q31_t)0x2161B39F, (q31_t)0x7B5D039D, (q31_t)0x2223A4C5, + (q31_t)0x7B26CB4F, (q31_t)0x22E541AE, (q31_t)0x7AEF6323, + (q31_t)0x23A6887E, (q31_t)0x7AB6CBA3, (q31_t)0x24677757, + (q31_t)0x7A7D055B, (q31_t)0x25280C5D, (q31_t)0x7A4210D8, + (q31_t)0x25E845B5, (q31_t)0x7A05EEAD, (q31_t)0x26A82185, + (q31_t)0x79C89F6D, (q31_t)0x27679DF4, (q31_t)0x798A23B1, + (q31_t)0x2826B928, (q31_t)0x794A7C11, (q31_t)0x28E5714A, + (q31_t)0x7909A92C, (q31_t)0x29A3C484, (q31_t)0x78C7ABA1, + (q31_t)0x2A61B101, (q31_t)0x78848413, (q31_t)0x2B1F34EB, + (q31_t)0x78403328, (q31_t)0x2BDC4E6F, (q31_t)0x77FAB988, + (q31_t)0x2C98FBBA, (q31_t)0x77B417DF, (q31_t)0x2D553AFB, + (q31_t)0x776C4EDB, (q31_t)0x2E110A62, (q31_t)0x77235F2D, + (q31_t)0x2ECC681E, (q31_t)0x76D94988, (q31_t)0x2F875262, + (q31_t)0x768E0EA5, (q31_t)0x3041C760, (q31_t)0x7641AF3C, + (q31_t)0x30FBC54D, (q31_t)0x75F42C0A, (q31_t)0x31B54A5D, + (q31_t)0x75A585CF, (q31_t)0x326E54C7, (q31_t)0x7555BD4B, + (q31_t)0x3326E2C2, (q31_t)0x7504D345, (q31_t)0x33DEF287, + (q31_t)0x74B2C883, (q31_t)0x3496824F, (q31_t)0x745F9DD1, + (q31_t)0x354D9056, (q31_t)0x740B53FA, (q31_t)0x36041AD9, + (q31_t)0x73B5EBD0, (q31_t)0x36BA2013, (q31_t)0x735F6626, + (q31_t)0x376F9E46, (q31_t)0x7307C3D0, (q31_t)0x382493B0, + (q31_t)0x72AF05A6, (q31_t)0x38D8FE93, (q31_t)0x72552C84, + (q31_t)0x398CDD32, (q31_t)0x71FA3948, (q31_t)0x3A402DD1, + (q31_t)0x719E2CD2, (q31_t)0x3AF2EEB7, (q31_t)0x71410804, + (q31_t)0x3BA51E29, (q31_t)0x70E2CBC6, (q31_t)0x3C56BA70, + (q31_t)0x708378FE, (q31_t)0x3D07C1D5, (q31_t)0x70231099, + (q31_t)0x3DB832A5, (q31_t)0x6FC19385, (q31_t)0x3E680B2C, + (q31_t)0x6F5F02B1, (q31_t)0x3F1749B7, (q31_t)0x6EFB5F12, + (q31_t)0x3FC5EC97, (q31_t)0x6E96A99C, (q31_t)0x4073F21D, + (q31_t)0x6E30E349, (q31_t)0x4121589A, (q31_t)0x6DCA0D14, + (q31_t)0x41CE1E64, (q31_t)0x6D6227FA, (q31_t)0x427A41D0, + (q31_t)0x6CF934FB, (q31_t)0x4325C135, (q31_t)0x6C8F351C, + (q31_t)0x43D09AEC, (q31_t)0x6C242960, (q31_t)0x447ACD50, + (q31_t)0x6BB812D0, (q31_t)0x452456BC, (q31_t)0x6B4AF278, + (q31_t)0x45CD358F, (q31_t)0x6ADCC964, (q31_t)0x46756827, + (q31_t)0x6A6D98A4, (q31_t)0x471CECE6, (q31_t)0x69FD614A, + (q31_t)0x47C3C22E, (q31_t)0x698C246C, (q31_t)0x4869E664, + (q31_t)0x6919E320, (q31_t)0x490F57EE, (q31_t)0x68A69E81, + (q31_t)0x49B41533, (q31_t)0x683257AA, (q31_t)0x4A581C9D, + (q31_t)0x67BD0FBC, (q31_t)0x4AFB6C97, (q31_t)0x6746C7D7, + (q31_t)0x4B9E038F, (q31_t)0x66CF811F, (q31_t)0x4C3FDFF3, + (q31_t)0x66573CBB, (q31_t)0x4CE10034, (q31_t)0x65DDFBD3, + (q31_t)0x4D8162C4, (q31_t)0x6563BF92, (q31_t)0x4E210617, + (q31_t)0x64E88926, (q31_t)0x4EBFE8A4, (q31_t)0x646C59BF, + (q31_t)0x4F5E08E3, (q31_t)0x63EF328F, (q31_t)0x4FFB654D, + (q31_t)0x637114CC, (q31_t)0x5097FC5E, (q31_t)0x62F201AC, + (q31_t)0x5133CC94, (q31_t)0x6271FA69, (q31_t)0x51CED46E, + (q31_t)0x61F1003E, (q31_t)0x5269126E, (q31_t)0x616F146B, + (q31_t)0x53028517, (q31_t)0x60EC3830, (q31_t)0x539B2AEF, + (q31_t)0x60686CCE, (q31_t)0x5433027D, (q31_t)0x5FE3B38D, + (q31_t)0x54CA0A4A, (q31_t)0x5F5E0DB3, (q31_t)0x556040E2, + (q31_t)0x5ED77C89, (q31_t)0x55F5A4D2, (q31_t)0x5E50015D, + (q31_t)0x568A34A9, (q31_t)0x5DC79D7C, (q31_t)0x571DEEF9, + (q31_t)0x5D3E5236, (q31_t)0x57B0D256, (q31_t)0x5CB420DF, + (q31_t)0x5842DD54, (q31_t)0x5C290ACC, (q31_t)0x58D40E8C, + (q31_t)0x5B9D1153, (q31_t)0x59646497, (q31_t)0x5B1035CF, + (q31_t)0x59F3DE12, (q31_t)0x5A82799A, (q31_t)0x5A82799A, + (q31_t)0x59F3DE12, (q31_t)0x5B1035CF, (q31_t)0x59646497, + (q31_t)0x5B9D1153, (q31_t)0x58D40E8C, (q31_t)0x5C290ACC, + (q31_t)0x5842DD54, (q31_t)0x5CB420DF, (q31_t)0x57B0D256, + (q31_t)0x5D3E5236, (q31_t)0x571DEEF9, (q31_t)0x5DC79D7C, + (q31_t)0x568A34A9, (q31_t)0x5E50015D, (q31_t)0x55F5A4D2, + (q31_t)0x5ED77C89, (q31_t)0x556040E2, (q31_t)0x5F5E0DB3, + (q31_t)0x54CA0A4A, (q31_t)0x5FE3B38D, (q31_t)0x5433027D, + (q31_t)0x60686CCE, (q31_t)0x539B2AEF, (q31_t)0x60EC3830, + (q31_t)0x53028517, (q31_t)0x616F146B, (q31_t)0x5269126E, + (q31_t)0x61F1003E, (q31_t)0x51CED46E, (q31_t)0x6271FA69, + (q31_t)0x5133CC94, (q31_t)0x62F201AC, (q31_t)0x5097FC5E, + (q31_t)0x637114CC, (q31_t)0x4FFB654D, (q31_t)0x63EF328F, + (q31_t)0x4F5E08E3, (q31_t)0x646C59BF, (q31_t)0x4EBFE8A4, + (q31_t)0x64E88926, (q31_t)0x4E210617, (q31_t)0x6563BF92, + (q31_t)0x4D8162C4, (q31_t)0x65DDFBD3, (q31_t)0x4CE10034, + (q31_t)0x66573CBB, (q31_t)0x4C3FDFF3, (q31_t)0x66CF811F, + (q31_t)0x4B9E038F, (q31_t)0x6746C7D7, (q31_t)0x4AFB6C97, + (q31_t)0x67BD0FBC, (q31_t)0x4A581C9D, (q31_t)0x683257AA, + (q31_t)0x49B41533, (q31_t)0x68A69E81, (q31_t)0x490F57EE, + (q31_t)0x6919E320, (q31_t)0x4869E664, (q31_t)0x698C246C, + (q31_t)0x47C3C22E, (q31_t)0x69FD614A, (q31_t)0x471CECE6, + (q31_t)0x6A6D98A4, (q31_t)0x46756827, (q31_t)0x6ADCC964, + (q31_t)0x45CD358F, (q31_t)0x6B4AF278, (q31_t)0x452456BC, + (q31_t)0x6BB812D0, (q31_t)0x447ACD50, (q31_t)0x6C242960, + (q31_t)0x43D09AEC, (q31_t)0x6C8F351C, (q31_t)0x4325C135, + (q31_t)0x6CF934FB, (q31_t)0x427A41D0, (q31_t)0x6D6227FA, + (q31_t)0x41CE1E64, (q31_t)0x6DCA0D14, (q31_t)0x4121589A, + (q31_t)0x6E30E349, (q31_t)0x4073F21D, (q31_t)0x6E96A99C, + (q31_t)0x3FC5EC97, (q31_t)0x6EFB5F12, (q31_t)0x3F1749B7, + (q31_t)0x6F5F02B1, (q31_t)0x3E680B2C, (q31_t)0x6FC19385, + (q31_t)0x3DB832A5, (q31_t)0x70231099, (q31_t)0x3D07C1D5, + (q31_t)0x708378FE, (q31_t)0x3C56BA70, (q31_t)0x70E2CBC6, + (q31_t)0x3BA51E29, (q31_t)0x71410804, (q31_t)0x3AF2EEB7, + (q31_t)0x719E2CD2, (q31_t)0x3A402DD1, (q31_t)0x71FA3948, + (q31_t)0x398CDD32, (q31_t)0x72552C84, (q31_t)0x38D8FE93, + (q31_t)0x72AF05A6, (q31_t)0x382493B0, (q31_t)0x7307C3D0, + (q31_t)0x376F9E46, (q31_t)0x735F6626, (q31_t)0x36BA2013, + (q31_t)0x73B5EBD0, (q31_t)0x36041AD9, (q31_t)0x740B53FA, + (q31_t)0x354D9056, (q31_t)0x745F9DD1, (q31_t)0x3496824F, + (q31_t)0x74B2C883, (q31_t)0x33DEF287, (q31_t)0x7504D345, + (q31_t)0x3326E2C2, (q31_t)0x7555BD4B, (q31_t)0x326E54C7, + (q31_t)0x75A585CF, (q31_t)0x31B54A5D, (q31_t)0x75F42C0A, + (q31_t)0x30FBC54D, (q31_t)0x7641AF3C, (q31_t)0x3041C760, + (q31_t)0x768E0EA5, (q31_t)0x2F875262, (q31_t)0x76D94988, + (q31_t)0x2ECC681E, (q31_t)0x77235F2D, (q31_t)0x2E110A62, + (q31_t)0x776C4EDB, (q31_t)0x2D553AFB, (q31_t)0x77B417DF, + (q31_t)0x2C98FBBA, (q31_t)0x77FAB988, (q31_t)0x2BDC4E6F, + (q31_t)0x78403328, (q31_t)0x2B1F34EB, (q31_t)0x78848413, + (q31_t)0x2A61B101, (q31_t)0x78C7ABA1, (q31_t)0x29A3C484, + (q31_t)0x7909A92C, (q31_t)0x28E5714A, (q31_t)0x794A7C11, + (q31_t)0x2826B928, (q31_t)0x798A23B1, (q31_t)0x27679DF4, + (q31_t)0x79C89F6D, (q31_t)0x26A82185, (q31_t)0x7A05EEAD, + (q31_t)0x25E845B5, (q31_t)0x7A4210D8, (q31_t)0x25280C5D, + (q31_t)0x7A7D055B, (q31_t)0x24677757, (q31_t)0x7AB6CBA3, + (q31_t)0x23A6887E, (q31_t)0x7AEF6323, (q31_t)0x22E541AE, + (q31_t)0x7B26CB4F, (q31_t)0x2223A4C5, (q31_t)0x7B5D039D, + (q31_t)0x2161B39F, (q31_t)0x7B920B89, (q31_t)0x209F701C, + (q31_t)0x7BC5E28F, (q31_t)0x1FDCDC1A, (q31_t)0x7BF88830, + (q31_t)0x1F19F97B, (q31_t)0x7C29FBEE, (q31_t)0x1E56CA1E, + (q31_t)0x7C5A3D4F, (q31_t)0x1D934FE5, (q31_t)0x7C894BDD, + (q31_t)0x1CCF8CB3, (q31_t)0x7CB72724, (q31_t)0x1C0B826A, + (q31_t)0x7CE3CEB1, (q31_t)0x1B4732EF, (q31_t)0x7D0F4218, + (q31_t)0x1A82A025, (q31_t)0x7D3980EC, (q31_t)0x19BDCBF2, + (q31_t)0x7D628AC5, (q31_t)0x18F8B83C, (q31_t)0x7D8A5F3F, + (q31_t)0x183366E8, (q31_t)0x7DB0FDF7, (q31_t)0x176DD9DE, + (q31_t)0x7DD6668E, (q31_t)0x16A81305, (q31_t)0x7DFA98A7, + (q31_t)0x15E21444, (q31_t)0x7E1D93E9, (q31_t)0x151BDF85, + (q31_t)0x7E3F57FE, (q31_t)0x145576B1, (q31_t)0x7E5FE493, + (q31_t)0x138EDBB0, (q31_t)0x7E7F3956, (q31_t)0x12C8106E, + (q31_t)0x7E9D55FC, (q31_t)0x120116D4, (q31_t)0x7EBA3A39, + (q31_t)0x1139F0CE, (q31_t)0x7ED5E5C6, (q31_t)0x1072A047, + (q31_t)0x7EF0585F, (q31_t)0x0FAB272B, (q31_t)0x7F0991C3, + (q31_t)0x0EE38765, (q31_t)0x7F2191B4, (q31_t)0x0E1BC2E3, + (q31_t)0x7F3857F5, (q31_t)0x0D53DB92, (q31_t)0x7F4DE450, + (q31_t)0x0C8BD35E, (q31_t)0x7F62368F, (q31_t)0x0BC3AC35, + (q31_t)0x7F754E7F, (q31_t)0x0AFB6805, (q31_t)0x7F872BF3, + (q31_t)0x0A3308BC, (q31_t)0x7F97CEBC, (q31_t)0x096A9049, + (q31_t)0x7FA736B4, (q31_t)0x08A2009A, (q31_t)0x7FB563B2, + (q31_t)0x07D95B9E, (q31_t)0x7FC25596, (q31_t)0x0710A344, + (q31_t)0x7FCE0C3E, (q31_t)0x0647D97C, (q31_t)0x7FD8878D, + (q31_t)0x057F0034, (q31_t)0x7FE1C76B, (q31_t)0x04B6195D, + (q31_t)0x7FE9CBC0, (q31_t)0x03ED26E6, (q31_t)0x7FF09477, + (q31_t)0x03242ABF, (q31_t)0x7FF62182, (q31_t)0x025B26D7, + (q31_t)0x7FFA72D1, (q31_t)0x01921D1F, (q31_t)0x7FFD885A, + (q31_t)0x00C90F88, (q31_t)0x7FFF6216, (q31_t)0x00000000, + (q31_t)0x7FFFFFFF, (q31_t)0xFF36F078, (q31_t)0x7FFF6216, + (q31_t)0xFE6DE2E0, (q31_t)0x7FFD885A, (q31_t)0xFDA4D928, + (q31_t)0x7FFA72D1, (q31_t)0xFCDBD541, (q31_t)0x7FF62182, + (q31_t)0xFC12D919, (q31_t)0x7FF09477, (q31_t)0xFB49E6A2, + (q31_t)0x7FE9CBC0, (q31_t)0xFA80FFCB, (q31_t)0x7FE1C76B, + (q31_t)0xF9B82683, (q31_t)0x7FD8878D, (q31_t)0xF8EF5CBB, + (q31_t)0x7FCE0C3E, (q31_t)0xF826A461, (q31_t)0x7FC25596, + (q31_t)0xF75DFF65, (q31_t)0x7FB563B2, (q31_t)0xF6956FB6, + (q31_t)0x7FA736B4, (q31_t)0xF5CCF743, (q31_t)0x7F97CEBC, + (q31_t)0xF50497FA, (q31_t)0x7F872BF3, (q31_t)0xF43C53CA, + (q31_t)0x7F754E7F, (q31_t)0xF3742CA1, (q31_t)0x7F62368F, + (q31_t)0xF2AC246D, (q31_t)0x7F4DE450, (q31_t)0xF1E43D1C, + (q31_t)0x7F3857F5, (q31_t)0xF11C789A, (q31_t)0x7F2191B4, + (q31_t)0xF054D8D4, (q31_t)0x7F0991C3, (q31_t)0xEF8D5FB8, + (q31_t)0x7EF0585F, (q31_t)0xEEC60F31, (q31_t)0x7ED5E5C6, + (q31_t)0xEDFEE92B, (q31_t)0x7EBA3A39, (q31_t)0xED37EF91, + (q31_t)0x7E9D55FC, (q31_t)0xEC71244F, (q31_t)0x7E7F3956, + (q31_t)0xEBAA894E, (q31_t)0x7E5FE493, (q31_t)0xEAE4207A, + (q31_t)0x7E3F57FE, (q31_t)0xEA1DEBBB, (q31_t)0x7E1D93E9, + (q31_t)0xE957ECFB, (q31_t)0x7DFA98A7, (q31_t)0xE8922621, + (q31_t)0x7DD6668E, (q31_t)0xE7CC9917, (q31_t)0x7DB0FDF7, + (q31_t)0xE70747C3, (q31_t)0x7D8A5F3F, (q31_t)0xE642340D, + (q31_t)0x7D628AC5, (q31_t)0xE57D5FDA, (q31_t)0x7D3980EC, + (q31_t)0xE4B8CD10, (q31_t)0x7D0F4218, (q31_t)0xE3F47D95, + (q31_t)0x7CE3CEB1, (q31_t)0xE330734C, (q31_t)0x7CB72724, + (q31_t)0xE26CB01A, (q31_t)0x7C894BDD, (q31_t)0xE1A935E1, + (q31_t)0x7C5A3D4F, (q31_t)0xE0E60684, (q31_t)0x7C29FBEE, + (q31_t)0xE02323E5, (q31_t)0x7BF88830, (q31_t)0xDF608FE3, + (q31_t)0x7BC5E28F, (q31_t)0xDE9E4C60, (q31_t)0x7B920B89, + (q31_t)0xDDDC5B3A, (q31_t)0x7B5D039D, (q31_t)0xDD1ABE51, + (q31_t)0x7B26CB4F, (q31_t)0xDC597781, (q31_t)0x7AEF6323, + (q31_t)0xDB9888A8, (q31_t)0x7AB6CBA3, (q31_t)0xDAD7F3A2, + (q31_t)0x7A7D055B, (q31_t)0xDA17BA4A, (q31_t)0x7A4210D8, + (q31_t)0xD957DE7A, (q31_t)0x7A05EEAD, (q31_t)0xD898620C, + (q31_t)0x79C89F6D, (q31_t)0xD7D946D7, (q31_t)0x798A23B1, + (q31_t)0xD71A8EB5, (q31_t)0x794A7C11, (q31_t)0xD65C3B7B, + (q31_t)0x7909A92C, (q31_t)0xD59E4EFE, (q31_t)0x78C7ABA1, + (q31_t)0xD4E0CB14, (q31_t)0x78848413, (q31_t)0xD423B190, + (q31_t)0x78403328, (q31_t)0xD3670445, (q31_t)0x77FAB988, + (q31_t)0xD2AAC504, (q31_t)0x77B417DF, (q31_t)0xD1EEF59E, + (q31_t)0x776C4EDB, (q31_t)0xD13397E1, (q31_t)0x77235F2D, + (q31_t)0xD078AD9D, (q31_t)0x76D94988, (q31_t)0xCFBE389F, + (q31_t)0x768E0EA5, (q31_t)0xCF043AB2, (q31_t)0x7641AF3C, + (q31_t)0xCE4AB5A2, (q31_t)0x75F42C0A, (q31_t)0xCD91AB38, + (q31_t)0x75A585CF, (q31_t)0xCCD91D3D, (q31_t)0x7555BD4B, + (q31_t)0xCC210D78, (q31_t)0x7504D345, (q31_t)0xCB697DB0, + (q31_t)0x74B2C883, (q31_t)0xCAB26FA9, (q31_t)0x745F9DD1, + (q31_t)0xC9FBE527, (q31_t)0x740B53FA, (q31_t)0xC945DFEC, + (q31_t)0x73B5EBD0, (q31_t)0xC89061BA, (q31_t)0x735F6626, + (q31_t)0xC7DB6C50, (q31_t)0x7307C3D0, (q31_t)0xC727016C, + (q31_t)0x72AF05A6, (q31_t)0xC67322CD, (q31_t)0x72552C84, + (q31_t)0xC5BFD22E, (q31_t)0x71FA3948, (q31_t)0xC50D1148, + (q31_t)0x719E2CD2, (q31_t)0xC45AE1D7, (q31_t)0x71410804, + (q31_t)0xC3A9458F, (q31_t)0x70E2CBC6, (q31_t)0xC2F83E2A, + (q31_t)0x708378FE, (q31_t)0xC247CD5A, (q31_t)0x70231099, + (q31_t)0xC197F4D3, (q31_t)0x6FC19385, (q31_t)0xC0E8B648, + (q31_t)0x6F5F02B1, (q31_t)0xC03A1368, (q31_t)0x6EFB5F12, + (q31_t)0xBF8C0DE2, (q31_t)0x6E96A99C, (q31_t)0xBEDEA765, + (q31_t)0x6E30E349, (q31_t)0xBE31E19B, (q31_t)0x6DCA0D14, + (q31_t)0xBD85BE2F, (q31_t)0x6D6227FA, (q31_t)0xBCDA3ECA, + (q31_t)0x6CF934FB, (q31_t)0xBC2F6513, (q31_t)0x6C8F351C, + (q31_t)0xBB8532AF, (q31_t)0x6C242960, (q31_t)0xBADBA943, + (q31_t)0x6BB812D0, (q31_t)0xBA32CA70, (q31_t)0x6B4AF278, + (q31_t)0xB98A97D8, (q31_t)0x6ADCC964, (q31_t)0xB8E31319, + (q31_t)0x6A6D98A4, (q31_t)0xB83C3DD1, (q31_t)0x69FD614A, + (q31_t)0xB796199B, (q31_t)0x698C246C, (q31_t)0xB6F0A811, + (q31_t)0x6919E320, (q31_t)0xB64BEACC, (q31_t)0x68A69E81, + (q31_t)0xB5A7E362, (q31_t)0x683257AA, (q31_t)0xB5049368, + (q31_t)0x67BD0FBC, (q31_t)0xB461FC70, (q31_t)0x6746C7D7, + (q31_t)0xB3C0200C, (q31_t)0x66CF811F, (q31_t)0xB31EFFCB, + (q31_t)0x66573CBB, (q31_t)0xB27E9D3B, (q31_t)0x65DDFBD3, + (q31_t)0xB1DEF9E8, (q31_t)0x6563BF92, (q31_t)0xB140175B, + (q31_t)0x64E88926, (q31_t)0xB0A1F71C, (q31_t)0x646C59BF, + (q31_t)0xB0049AB2, (q31_t)0x63EF328F, (q31_t)0xAF6803A1, + (q31_t)0x637114CC, (q31_t)0xAECC336B, (q31_t)0x62F201AC, + (q31_t)0xAE312B91, (q31_t)0x6271FA69, (q31_t)0xAD96ED91, + (q31_t)0x61F1003E, (q31_t)0xACFD7AE8, (q31_t)0x616F146B, + (q31_t)0xAC64D510, (q31_t)0x60EC3830, (q31_t)0xABCCFD82, + (q31_t)0x60686CCE, (q31_t)0xAB35F5B5, (q31_t)0x5FE3B38D, + (q31_t)0xAA9FBF1D, (q31_t)0x5F5E0DB3, (q31_t)0xAA0A5B2D, + (q31_t)0x5ED77C89, (q31_t)0xA975CB56, (q31_t)0x5E50015D, + (q31_t)0xA8E21106, (q31_t)0x5DC79D7C, (q31_t)0xA84F2DA9, + (q31_t)0x5D3E5236, (q31_t)0xA7BD22AB, (q31_t)0x5CB420DF, + (q31_t)0xA72BF173, (q31_t)0x5C290ACC, (q31_t)0xA69B9B68, + (q31_t)0x5B9D1153, (q31_t)0xA60C21ED, (q31_t)0x5B1035CF, + (q31_t)0xA57D8666, (q31_t)0x5A82799A, (q31_t)0xA4EFCA31, + (q31_t)0x59F3DE12, (q31_t)0xA462EEAC, (q31_t)0x59646497, + (q31_t)0xA3D6F533, (q31_t)0x58D40E8C, (q31_t)0xA34BDF20, + (q31_t)0x5842DD54, (q31_t)0xA2C1ADC9, (q31_t)0x57B0D256, + (q31_t)0xA2386283, (q31_t)0x571DEEF9, (q31_t)0xA1AFFEA2, + (q31_t)0x568A34A9, (q31_t)0xA1288376, (q31_t)0x55F5A4D2, + (q31_t)0xA0A1F24C, (q31_t)0x556040E2, (q31_t)0xA01C4C72, + (q31_t)0x54CA0A4A, (q31_t)0x9F979331, (q31_t)0x5433027D, + (q31_t)0x9F13C7D0, (q31_t)0x539B2AEF, (q31_t)0x9E90EB94, + (q31_t)0x53028517, (q31_t)0x9E0EFFC1, (q31_t)0x5269126E, + (q31_t)0x9D8E0596, (q31_t)0x51CED46E, (q31_t)0x9D0DFE53, + (q31_t)0x5133CC94, (q31_t)0x9C8EEB33, (q31_t)0x5097FC5E, + (q31_t)0x9C10CD70, (q31_t)0x4FFB654D, (q31_t)0x9B93A640, + (q31_t)0x4F5E08E3, (q31_t)0x9B1776D9, (q31_t)0x4EBFE8A4, + (q31_t)0x9A9C406D, (q31_t)0x4E210617, (q31_t)0x9A22042C, + (q31_t)0x4D8162C4, (q31_t)0x99A8C344, (q31_t)0x4CE10034, + (q31_t)0x99307EE0, (q31_t)0x4C3FDFF3, (q31_t)0x98B93828, + (q31_t)0x4B9E038F, (q31_t)0x9842F043, (q31_t)0x4AFB6C97, + (q31_t)0x97CDA855, (q31_t)0x4A581C9D, (q31_t)0x9759617E, + (q31_t)0x49B41533, (q31_t)0x96E61CDF, (q31_t)0x490F57EE, + (q31_t)0x9673DB94, (q31_t)0x4869E664, (q31_t)0x96029EB5, + (q31_t)0x47C3C22E, (q31_t)0x9592675B, (q31_t)0x471CECE6, + (q31_t)0x9523369B, (q31_t)0x46756827, (q31_t)0x94B50D87, + (q31_t)0x45CD358F, (q31_t)0x9447ED2F, (q31_t)0x452456BC, + (q31_t)0x93DBD69F, (q31_t)0x447ACD50, (q31_t)0x9370CAE4, + (q31_t)0x43D09AEC, (q31_t)0x9306CB04, (q31_t)0x4325C135, + (q31_t)0x929DD805, (q31_t)0x427A41D0, (q31_t)0x9235F2EB, + (q31_t)0x41CE1E64, (q31_t)0x91CF1CB6, (q31_t)0x4121589A, + (q31_t)0x91695663, (q31_t)0x4073F21D, (q31_t)0x9104A0ED, + (q31_t)0x3FC5EC97, (q31_t)0x90A0FD4E, (q31_t)0x3F1749B7, + (q31_t)0x903E6C7A, (q31_t)0x3E680B2C, (q31_t)0x8FDCEF66, + (q31_t)0x3DB832A5, (q31_t)0x8F7C8701, (q31_t)0x3D07C1D5, + (q31_t)0x8F1D343A, (q31_t)0x3C56BA70, (q31_t)0x8EBEF7FB, + (q31_t)0x3BA51E29, (q31_t)0x8E61D32D, (q31_t)0x3AF2EEB7, + (q31_t)0x8E05C6B7, (q31_t)0x3A402DD1, (q31_t)0x8DAAD37B, + (q31_t)0x398CDD32, (q31_t)0x8D50FA59, (q31_t)0x38D8FE93, + (q31_t)0x8CF83C30, (q31_t)0x382493B0, (q31_t)0x8CA099D9, + (q31_t)0x376F9E46, (q31_t)0x8C4A142F, (q31_t)0x36BA2013, + (q31_t)0x8BF4AC05, (q31_t)0x36041AD9, (q31_t)0x8BA0622F, + (q31_t)0x354D9056, (q31_t)0x8B4D377C, (q31_t)0x3496824F, + (q31_t)0x8AFB2CBA, (q31_t)0x33DEF287, (q31_t)0x8AAA42B4, + (q31_t)0x3326E2C2, (q31_t)0x8A5A7A30, (q31_t)0x326E54C7, + (q31_t)0x8A0BD3F5, (q31_t)0x31B54A5D, (q31_t)0x89BE50C3, + (q31_t)0x30FBC54D, (q31_t)0x8971F15A, (q31_t)0x3041C760, + (q31_t)0x8926B677, (q31_t)0x2F875262, (q31_t)0x88DCA0D3, + (q31_t)0x2ECC681E, (q31_t)0x8893B124, (q31_t)0x2E110A62, + (q31_t)0x884BE820, (q31_t)0x2D553AFB, (q31_t)0x88054677, + (q31_t)0x2C98FBBA, (q31_t)0x87BFCCD7, (q31_t)0x2BDC4E6F, + (q31_t)0x877B7BEC, (q31_t)0x2B1F34EB, (q31_t)0x8738545E, + (q31_t)0x2A61B101, (q31_t)0x86F656D3, (q31_t)0x29A3C484, + (q31_t)0x86B583EE, (q31_t)0x28E5714A, (q31_t)0x8675DC4E, + (q31_t)0x2826B928, (q31_t)0x86376092, (q31_t)0x27679DF4, + (q31_t)0x85FA1152, (q31_t)0x26A82185, (q31_t)0x85BDEF27, + (q31_t)0x25E845B5, (q31_t)0x8582FAA4, (q31_t)0x25280C5D, + (q31_t)0x8549345C, (q31_t)0x24677757, (q31_t)0x85109CDC, + (q31_t)0x23A6887E, (q31_t)0x84D934B0, (q31_t)0x22E541AE, + (q31_t)0x84A2FC62, (q31_t)0x2223A4C5, (q31_t)0x846DF476, + (q31_t)0x2161B39F, (q31_t)0x843A1D70, (q31_t)0x209F701C, + (q31_t)0x840777CF, (q31_t)0x1FDCDC1A, (q31_t)0x83D60411, + (q31_t)0x1F19F97B, (q31_t)0x83A5C2B0, (q31_t)0x1E56CA1E, + (q31_t)0x8376B422, (q31_t)0x1D934FE5, (q31_t)0x8348D8DB, + (q31_t)0x1CCF8CB3, (q31_t)0x831C314E, (q31_t)0x1C0B826A, + (q31_t)0x82F0BDE8, (q31_t)0x1B4732EF, (q31_t)0x82C67F13, + (q31_t)0x1A82A025, (q31_t)0x829D753A, (q31_t)0x19BDCBF2, + (q31_t)0x8275A0C0, (q31_t)0x18F8B83C, (q31_t)0x824F0208, + (q31_t)0x183366E8, (q31_t)0x82299971, (q31_t)0x176DD9DE, + (q31_t)0x82056758, (q31_t)0x16A81305, (q31_t)0x81E26C16, + (q31_t)0x15E21444, (q31_t)0x81C0A801, (q31_t)0x151BDF85, + (q31_t)0x81A01B6C, (q31_t)0x145576B1, (q31_t)0x8180C6A9, + (q31_t)0x138EDBB0, (q31_t)0x8162AA03, (q31_t)0x12C8106E, + (q31_t)0x8145C5C6, (q31_t)0x120116D4, (q31_t)0x812A1A39, + (q31_t)0x1139F0CE, (q31_t)0x810FA7A0, (q31_t)0x1072A047, + (q31_t)0x80F66E3C, (q31_t)0x0FAB272B, (q31_t)0x80DE6E4C, + (q31_t)0x0EE38765, (q31_t)0x80C7A80A, (q31_t)0x0E1BC2E3, + (q31_t)0x80B21BAF, (q31_t)0x0D53DB92, (q31_t)0x809DC970, + (q31_t)0x0C8BD35E, (q31_t)0x808AB180, (q31_t)0x0BC3AC35, + (q31_t)0x8078D40D, (q31_t)0x0AFB6805, (q31_t)0x80683143, + (q31_t)0x0A3308BC, (q31_t)0x8058C94C, (q31_t)0x096A9049, + (q31_t)0x804A9C4D, (q31_t)0x08A2009A, (q31_t)0x803DAA69, + (q31_t)0x07D95B9E, (q31_t)0x8031F3C1, (q31_t)0x0710A344, + (q31_t)0x80277872, (q31_t)0x0647D97C, (q31_t)0x801E3894, + (q31_t)0x057F0034, (q31_t)0x80163440, (q31_t)0x04B6195D, + (q31_t)0x800F6B88, (q31_t)0x03ED26E6, (q31_t)0x8009DE7D, + (q31_t)0x03242ABF, (q31_t)0x80058D2E, (q31_t)0x025B26D7, + (q31_t)0x800277A5, (q31_t)0x01921D1F, (q31_t)0x80009DE9, + (q31_t)0x00C90F88, (q31_t)0x80000000, (q31_t)0x00000000, + (q31_t)0x80009DE9, (q31_t)0xFF36F078, (q31_t)0x800277A5, + (q31_t)0xFE6DE2E0, (q31_t)0x80058D2E, (q31_t)0xFDA4D928, + (q31_t)0x8009DE7D, (q31_t)0xFCDBD541, (q31_t)0x800F6B88, + (q31_t)0xFC12D919, (q31_t)0x80163440, (q31_t)0xFB49E6A2, + (q31_t)0x801E3894, (q31_t)0xFA80FFCB, (q31_t)0x80277872, + (q31_t)0xF9B82683, (q31_t)0x8031F3C1, (q31_t)0xF8EF5CBB, + (q31_t)0x803DAA69, (q31_t)0xF826A461, (q31_t)0x804A9C4D, + (q31_t)0xF75DFF65, (q31_t)0x8058C94C, (q31_t)0xF6956FB6, + (q31_t)0x80683143, (q31_t)0xF5CCF743, (q31_t)0x8078D40D, + (q31_t)0xF50497FA, (q31_t)0x808AB180, (q31_t)0xF43C53CA, + (q31_t)0x809DC970, (q31_t)0xF3742CA1, (q31_t)0x80B21BAF, + (q31_t)0xF2AC246D, (q31_t)0x80C7A80A, (q31_t)0xF1E43D1C, + (q31_t)0x80DE6E4C, (q31_t)0xF11C789A, (q31_t)0x80F66E3C, + (q31_t)0xF054D8D4, (q31_t)0x810FA7A0, (q31_t)0xEF8D5FB8, + (q31_t)0x812A1A39, (q31_t)0xEEC60F31, (q31_t)0x8145C5C6, + (q31_t)0xEDFEE92B, (q31_t)0x8162AA03, (q31_t)0xED37EF91, + (q31_t)0x8180C6A9, (q31_t)0xEC71244F, (q31_t)0x81A01B6C, + (q31_t)0xEBAA894E, (q31_t)0x81C0A801, (q31_t)0xEAE4207A, + (q31_t)0x81E26C16, (q31_t)0xEA1DEBBB, (q31_t)0x82056758, + (q31_t)0xE957ECFB, (q31_t)0x82299971, (q31_t)0xE8922621, + (q31_t)0x824F0208, (q31_t)0xE7CC9917, (q31_t)0x8275A0C0, + (q31_t)0xE70747C3, (q31_t)0x829D753A, (q31_t)0xE642340D, + (q31_t)0x82C67F13, (q31_t)0xE57D5FDA, (q31_t)0x82F0BDE8, + (q31_t)0xE4B8CD10, (q31_t)0x831C314E, (q31_t)0xE3F47D95, + (q31_t)0x8348D8DB, (q31_t)0xE330734C, (q31_t)0x8376B422, + (q31_t)0xE26CB01A, (q31_t)0x83A5C2B0, (q31_t)0xE1A935E1, + (q31_t)0x83D60411, (q31_t)0xE0E60684, (q31_t)0x840777CF, + (q31_t)0xE02323E5, (q31_t)0x843A1D70, (q31_t)0xDF608FE3, + (q31_t)0x846DF476, (q31_t)0xDE9E4C60, (q31_t)0x84A2FC62, + (q31_t)0xDDDC5B3A, (q31_t)0x84D934B0, (q31_t)0xDD1ABE51, + (q31_t)0x85109CDC, (q31_t)0xDC597781, (q31_t)0x8549345C, + (q31_t)0xDB9888A8, (q31_t)0x8582FAA4, (q31_t)0xDAD7F3A2, + (q31_t)0x85BDEF27, (q31_t)0xDA17BA4A, (q31_t)0x85FA1152, + (q31_t)0xD957DE7A, (q31_t)0x86376092, (q31_t)0xD898620C, + (q31_t)0x8675DC4E, (q31_t)0xD7D946D7, (q31_t)0x86B583EE, + (q31_t)0xD71A8EB5, (q31_t)0x86F656D3, (q31_t)0xD65C3B7B, + (q31_t)0x8738545E, (q31_t)0xD59E4EFE, (q31_t)0x877B7BEC, + (q31_t)0xD4E0CB14, (q31_t)0x87BFCCD7, (q31_t)0xD423B190, + (q31_t)0x88054677, (q31_t)0xD3670445, (q31_t)0x884BE820, + (q31_t)0xD2AAC504, (q31_t)0x8893B124, (q31_t)0xD1EEF59E, + (q31_t)0x88DCA0D3, (q31_t)0xD13397E1, (q31_t)0x8926B677, + (q31_t)0xD078AD9D, (q31_t)0x8971F15A, (q31_t)0xCFBE389F, + (q31_t)0x89BE50C3, (q31_t)0xCF043AB2, (q31_t)0x8A0BD3F5, + (q31_t)0xCE4AB5A2, (q31_t)0x8A5A7A30, (q31_t)0xCD91AB38, + (q31_t)0x8AAA42B4, (q31_t)0xCCD91D3D, (q31_t)0x8AFB2CBA, + (q31_t)0xCC210D78, (q31_t)0x8B4D377C, (q31_t)0xCB697DB0, + (q31_t)0x8BA0622F, (q31_t)0xCAB26FA9, (q31_t)0x8BF4AC05, + (q31_t)0xC9FBE527, (q31_t)0x8C4A142F, (q31_t)0xC945DFEC, + (q31_t)0x8CA099D9, (q31_t)0xC89061BA, (q31_t)0x8CF83C30, + (q31_t)0xC7DB6C50, (q31_t)0x8D50FA59, (q31_t)0xC727016C, + (q31_t)0x8DAAD37B, (q31_t)0xC67322CD, (q31_t)0x8E05C6B7, + (q31_t)0xC5BFD22E, (q31_t)0x8E61D32D, (q31_t)0xC50D1148, + (q31_t)0x8EBEF7FB, (q31_t)0xC45AE1D7, (q31_t)0x8F1D343A, + (q31_t)0xC3A9458F, (q31_t)0x8F7C8701, (q31_t)0xC2F83E2A, + (q31_t)0x8FDCEF66, (q31_t)0xC247CD5A, (q31_t)0x903E6C7A, + (q31_t)0xC197F4D3, (q31_t)0x90A0FD4E, (q31_t)0xC0E8B648, + (q31_t)0x9104A0ED, (q31_t)0xC03A1368, (q31_t)0x91695663, + (q31_t)0xBF8C0DE2, (q31_t)0x91CF1CB6, (q31_t)0xBEDEA765, + (q31_t)0x9235F2EB, (q31_t)0xBE31E19B, (q31_t)0x929DD805, + (q31_t)0xBD85BE2F, (q31_t)0x9306CB04, (q31_t)0xBCDA3ECA, + (q31_t)0x9370CAE4, (q31_t)0xBC2F6513, (q31_t)0x93DBD69F, + (q31_t)0xBB8532AF, (q31_t)0x9447ED2F, (q31_t)0xBADBA943, + (q31_t)0x94B50D87, (q31_t)0xBA32CA70, (q31_t)0x9523369B, + (q31_t)0xB98A97D8, (q31_t)0x9592675B, (q31_t)0xB8E31319, + (q31_t)0x96029EB5, (q31_t)0xB83C3DD1, (q31_t)0x9673DB94, + (q31_t)0xB796199B, (q31_t)0x96E61CDF, (q31_t)0xB6F0A811, + (q31_t)0x9759617E, (q31_t)0xB64BEACC, (q31_t)0x97CDA855, + (q31_t)0xB5A7E362, (q31_t)0x9842F043, (q31_t)0xB5049368, + (q31_t)0x98B93828, (q31_t)0xB461FC70, (q31_t)0x99307EE0, + (q31_t)0xB3C0200C, (q31_t)0x99A8C344, (q31_t)0xB31EFFCB, + (q31_t)0x9A22042C, (q31_t)0xB27E9D3B, (q31_t)0x9A9C406D, + (q31_t)0xB1DEF9E8, (q31_t)0x9B1776D9, (q31_t)0xB140175B, + (q31_t)0x9B93A640, (q31_t)0xB0A1F71C, (q31_t)0x9C10CD70, + (q31_t)0xB0049AB2, (q31_t)0x9C8EEB33, (q31_t)0xAF6803A1, + (q31_t)0x9D0DFE53, (q31_t)0xAECC336B, (q31_t)0x9D8E0596, + (q31_t)0xAE312B91, (q31_t)0x9E0EFFC1, (q31_t)0xAD96ED91, + (q31_t)0x9E90EB94, (q31_t)0xACFD7AE8, (q31_t)0x9F13C7D0, + (q31_t)0xAC64D510, (q31_t)0x9F979331, (q31_t)0xABCCFD82, + (q31_t)0xA01C4C72, (q31_t)0xAB35F5B5, (q31_t)0xA0A1F24C, + (q31_t)0xAA9FBF1D, (q31_t)0xA1288376, (q31_t)0xAA0A5B2D, + (q31_t)0xA1AFFEA2, (q31_t)0xA975CB56, (q31_t)0xA2386283, + (q31_t)0xA8E21106, (q31_t)0xA2C1ADC9, (q31_t)0xA84F2DA9, + (q31_t)0xA34BDF20, (q31_t)0xA7BD22AB, (q31_t)0xA3D6F533, + (q31_t)0xA72BF173, (q31_t)0xA462EEAC, (q31_t)0xA69B9B68, + (q31_t)0xA4EFCA31, (q31_t)0xA60C21ED, (q31_t)0xA57D8666, + (q31_t)0xA57D8666, (q31_t)0xA60C21ED, (q31_t)0xA4EFCA31, + (q31_t)0xA69B9B68, (q31_t)0xA462EEAC, (q31_t)0xA72BF173, + (q31_t)0xA3D6F533, (q31_t)0xA7BD22AB, (q31_t)0xA34BDF20, + (q31_t)0xA84F2DA9, (q31_t)0xA2C1ADC9, (q31_t)0xA8E21106, + (q31_t)0xA2386283, (q31_t)0xA975CB56, (q31_t)0xA1AFFEA2, + (q31_t)0xAA0A5B2D, (q31_t)0xA1288376, (q31_t)0xAA9FBF1D, + (q31_t)0xA0A1F24C, (q31_t)0xAB35F5B5, (q31_t)0xA01C4C72, + (q31_t)0xABCCFD82, (q31_t)0x9F979331, (q31_t)0xAC64D510, + (q31_t)0x9F13C7D0, (q31_t)0xACFD7AE8, (q31_t)0x9E90EB94, + (q31_t)0xAD96ED91, (q31_t)0x9E0EFFC1, (q31_t)0xAE312B91, + (q31_t)0x9D8E0596, (q31_t)0xAECC336B, (q31_t)0x9D0DFE53, + (q31_t)0xAF6803A1, (q31_t)0x9C8EEB33, (q31_t)0xB0049AB2, + (q31_t)0x9C10CD70, (q31_t)0xB0A1F71C, (q31_t)0x9B93A640, + (q31_t)0xB140175B, (q31_t)0x9B1776D9, (q31_t)0xB1DEF9E8, + (q31_t)0x9A9C406D, (q31_t)0xB27E9D3B, (q31_t)0x9A22042C, + (q31_t)0xB31EFFCB, (q31_t)0x99A8C344, (q31_t)0xB3C0200C, + (q31_t)0x99307EE0, (q31_t)0xB461FC70, (q31_t)0x98B93828, + (q31_t)0xB5049368, (q31_t)0x9842F043, (q31_t)0xB5A7E362, + (q31_t)0x97CDA855, (q31_t)0xB64BEACC, (q31_t)0x9759617E, + (q31_t)0xB6F0A811, (q31_t)0x96E61CDF, (q31_t)0xB796199B, + (q31_t)0x9673DB94, (q31_t)0xB83C3DD1, (q31_t)0x96029EB5, + (q31_t)0xB8E31319, (q31_t)0x9592675B, (q31_t)0xB98A97D8, + (q31_t)0x9523369B, (q31_t)0xBA32CA70, (q31_t)0x94B50D87, + (q31_t)0xBADBA943, (q31_t)0x9447ED2F, (q31_t)0xBB8532AF, + (q31_t)0x93DBD69F, (q31_t)0xBC2F6513, (q31_t)0x9370CAE4, + (q31_t)0xBCDA3ECA, (q31_t)0x9306CB04, (q31_t)0xBD85BE2F, + (q31_t)0x929DD805, (q31_t)0xBE31E19B, (q31_t)0x9235F2EB, + (q31_t)0xBEDEA765, (q31_t)0x91CF1CB6, (q31_t)0xBF8C0DE2, + (q31_t)0x91695663, (q31_t)0xC03A1368, (q31_t)0x9104A0ED, + (q31_t)0xC0E8B648, (q31_t)0x90A0FD4E, (q31_t)0xC197F4D3, + (q31_t)0x903E6C7A, (q31_t)0xC247CD5A, (q31_t)0x8FDCEF66, + (q31_t)0xC2F83E2A, (q31_t)0x8F7C8701, (q31_t)0xC3A9458F, + (q31_t)0x8F1D343A, (q31_t)0xC45AE1D7, (q31_t)0x8EBEF7FB, + (q31_t)0xC50D1148, (q31_t)0x8E61D32D, (q31_t)0xC5BFD22E, + (q31_t)0x8E05C6B7, (q31_t)0xC67322CD, (q31_t)0x8DAAD37B, + (q31_t)0xC727016C, (q31_t)0x8D50FA59, (q31_t)0xC7DB6C50, + (q31_t)0x8CF83C30, (q31_t)0xC89061BA, (q31_t)0x8CA099D9, + (q31_t)0xC945DFEC, (q31_t)0x8C4A142F, (q31_t)0xC9FBE527, + (q31_t)0x8BF4AC05, (q31_t)0xCAB26FA9, (q31_t)0x8BA0622F, + (q31_t)0xCB697DB0, (q31_t)0x8B4D377C, (q31_t)0xCC210D78, + (q31_t)0x8AFB2CBA, (q31_t)0xCCD91D3D, (q31_t)0x8AAA42B4, + (q31_t)0xCD91AB38, (q31_t)0x8A5A7A30, (q31_t)0xCE4AB5A2, + (q31_t)0x8A0BD3F5, (q31_t)0xCF043AB2, (q31_t)0x89BE50C3, + (q31_t)0xCFBE389F, (q31_t)0x8971F15A, (q31_t)0xD078AD9D, + (q31_t)0x8926B677, (q31_t)0xD13397E1, (q31_t)0x88DCA0D3, + (q31_t)0xD1EEF59E, (q31_t)0x8893B124, (q31_t)0xD2AAC504, + (q31_t)0x884BE820, (q31_t)0xD3670445, (q31_t)0x88054677, + (q31_t)0xD423B190, (q31_t)0x87BFCCD7, (q31_t)0xD4E0CB14, + (q31_t)0x877B7BEC, (q31_t)0xD59E4EFE, (q31_t)0x8738545E, + (q31_t)0xD65C3B7B, (q31_t)0x86F656D3, (q31_t)0xD71A8EB5, + (q31_t)0x86B583EE, (q31_t)0xD7D946D7, (q31_t)0x8675DC4E, + (q31_t)0xD898620C, (q31_t)0x86376092, (q31_t)0xD957DE7A, + (q31_t)0x85FA1152, (q31_t)0xDA17BA4A, (q31_t)0x85BDEF27, + (q31_t)0xDAD7F3A2, (q31_t)0x8582FAA4, (q31_t)0xDB9888A8, + (q31_t)0x8549345C, (q31_t)0xDC597781, (q31_t)0x85109CDC, + (q31_t)0xDD1ABE51, (q31_t)0x84D934B0, (q31_t)0xDDDC5B3A, + (q31_t)0x84A2FC62, (q31_t)0xDE9E4C60, (q31_t)0x846DF476, + (q31_t)0xDF608FE3, (q31_t)0x843A1D70, (q31_t)0xE02323E5, + (q31_t)0x840777CF, (q31_t)0xE0E60684, (q31_t)0x83D60411, + (q31_t)0xE1A935E1, (q31_t)0x83A5C2B0, (q31_t)0xE26CB01A, + (q31_t)0x8376B422, (q31_t)0xE330734C, (q31_t)0x8348D8DB, + (q31_t)0xE3F47D95, (q31_t)0x831C314E, (q31_t)0xE4B8CD10, + (q31_t)0x82F0BDE8, (q31_t)0xE57D5FDA, (q31_t)0x82C67F13, + (q31_t)0xE642340D, (q31_t)0x829D753A, (q31_t)0xE70747C3, + (q31_t)0x8275A0C0, (q31_t)0xE7CC9917, (q31_t)0x824F0208, + (q31_t)0xE8922621, (q31_t)0x82299971, (q31_t)0xE957ECFB, + (q31_t)0x82056758, (q31_t)0xEA1DEBBB, (q31_t)0x81E26C16, + (q31_t)0xEAE4207A, (q31_t)0x81C0A801, (q31_t)0xEBAA894E, + (q31_t)0x81A01B6C, (q31_t)0xEC71244F, (q31_t)0x8180C6A9, + (q31_t)0xED37EF91, (q31_t)0x8162AA03, (q31_t)0xEDFEE92B, + (q31_t)0x8145C5C6, (q31_t)0xEEC60F31, (q31_t)0x812A1A39, + (q31_t)0xEF8D5FB8, (q31_t)0x810FA7A0, (q31_t)0xF054D8D4, + (q31_t)0x80F66E3C, (q31_t)0xF11C789A, (q31_t)0x80DE6E4C, + (q31_t)0xF1E43D1C, (q31_t)0x80C7A80A, (q31_t)0xF2AC246D, + (q31_t)0x80B21BAF, (q31_t)0xF3742CA1, (q31_t)0x809DC970, + (q31_t)0xF43C53CA, (q31_t)0x808AB180, (q31_t)0xF50497FA, + (q31_t)0x8078D40D, (q31_t)0xF5CCF743, (q31_t)0x80683143, + (q31_t)0xF6956FB6, (q31_t)0x8058C94C, (q31_t)0xF75DFF65, + (q31_t)0x804A9C4D, (q31_t)0xF826A461, (q31_t)0x803DAA69, + (q31_t)0xF8EF5CBB, (q31_t)0x8031F3C1, (q31_t)0xF9B82683, + (q31_t)0x80277872, (q31_t)0xFA80FFCB, (q31_t)0x801E3894, + (q31_t)0xFB49E6A2, (q31_t)0x80163440, (q31_t)0xFC12D919, + (q31_t)0x800F6B88, (q31_t)0xFCDBD541, (q31_t)0x8009DE7D, + (q31_t)0xFDA4D928, (q31_t)0x80058D2E, (q31_t)0xFE6DE2E0, + (q31_t)0x800277A5, (q31_t)0xFF36F078, (q31_t)0x80009DE9 +}; + +/** + @par + Example code for Q31 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefQ31[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefQ31[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 2048, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to Q31(Fixed point 1.31): + round(twiddleCoefQ31(i) * pow(2, 31)) + */ +const q31_t twiddleCoef_2048_q31[3072] = { + (q31_t)0x7FFFFFFF, (q31_t)0x00000000, (q31_t)0x7FFFD885, + (q31_t)0x006487E3, (q31_t)0x7FFF6216, (q31_t)0x00C90F88, + (q31_t)0x7FFE9CB2, (q31_t)0x012D96B0, (q31_t)0x7FFD885A, + (q31_t)0x01921D1F, (q31_t)0x7FFC250F, (q31_t)0x01F6A296, + (q31_t)0x7FFA72D1, (q31_t)0x025B26D7, (q31_t)0x7FF871A1, + (q31_t)0x02BFA9A4, (q31_t)0x7FF62182, (q31_t)0x03242ABF, + (q31_t)0x7FF38273, (q31_t)0x0388A9E9, (q31_t)0x7FF09477, + (q31_t)0x03ED26E6, (q31_t)0x7FED5790, (q31_t)0x0451A176, + (q31_t)0x7FE9CBC0, (q31_t)0x04B6195D, (q31_t)0x7FE5F108, + (q31_t)0x051A8E5C, (q31_t)0x7FE1C76B, (q31_t)0x057F0034, + (q31_t)0x7FDD4EEC, (q31_t)0x05E36EA9, (q31_t)0x7FD8878D, + (q31_t)0x0647D97C, (q31_t)0x7FD37152, (q31_t)0x06AC406F, + (q31_t)0x7FCE0C3E, (q31_t)0x0710A344, (q31_t)0x7FC85853, + (q31_t)0x077501BE, (q31_t)0x7FC25596, (q31_t)0x07D95B9E, + (q31_t)0x7FBC040A, (q31_t)0x083DB0A7, (q31_t)0x7FB563B2, + (q31_t)0x08A2009A, (q31_t)0x7FAE7494, (q31_t)0x09064B3A, + (q31_t)0x7FA736B4, (q31_t)0x096A9049, (q31_t)0x7F9FAA15, + (q31_t)0x09CECF89, (q31_t)0x7F97CEBC, (q31_t)0x0A3308BC, + (q31_t)0x7F8FA4AF, (q31_t)0x0A973BA5, (q31_t)0x7F872BF3, + (q31_t)0x0AFB6805, (q31_t)0x7F7E648B, (q31_t)0x0B5F8D9F, + (q31_t)0x7F754E7F, (q31_t)0x0BC3AC35, (q31_t)0x7F6BE9D4, + (q31_t)0x0C27C389, (q31_t)0x7F62368F, (q31_t)0x0C8BD35E, + (q31_t)0x7F5834B6, (q31_t)0x0CEFDB75, (q31_t)0x7F4DE450, + (q31_t)0x0D53DB92, (q31_t)0x7F434563, (q31_t)0x0DB7D376, + (q31_t)0x7F3857F5, (q31_t)0x0E1BC2E3, (q31_t)0x7F2D1C0E, + (q31_t)0x0E7FA99D, (q31_t)0x7F2191B4, (q31_t)0x0EE38765, + (q31_t)0x7F15B8EE, (q31_t)0x0F475BFE, (q31_t)0x7F0991C3, + (q31_t)0x0FAB272B, (q31_t)0x7EFD1C3C, (q31_t)0x100EE8AD, + (q31_t)0x7EF0585F, (q31_t)0x1072A047, (q31_t)0x7EE34635, + (q31_t)0x10D64DBC, (q31_t)0x7ED5E5C6, (q31_t)0x1139F0CE, + (q31_t)0x7EC8371A, (q31_t)0x119D8940, (q31_t)0x7EBA3A39, + (q31_t)0x120116D4, (q31_t)0x7EABEF2C, (q31_t)0x1264994E, + (q31_t)0x7E9D55FC, (q31_t)0x12C8106E, (q31_t)0x7E8E6EB1, + (q31_t)0x132B7BF9, (q31_t)0x7E7F3956, (q31_t)0x138EDBB0, + (q31_t)0x7E6FB5F3, (q31_t)0x13F22F57, (q31_t)0x7E5FE493, + (q31_t)0x145576B1, (q31_t)0x7E4FC53E, (q31_t)0x14B8B17F, + (q31_t)0x7E3F57FE, (q31_t)0x151BDF85, (q31_t)0x7E2E9CDF, + (q31_t)0x157F0086, (q31_t)0x7E1D93E9, (q31_t)0x15E21444, + (q31_t)0x7E0C3D29, (q31_t)0x16451A83, (q31_t)0x7DFA98A7, + (q31_t)0x16A81305, (q31_t)0x7DE8A670, (q31_t)0x170AFD8D, + (q31_t)0x7DD6668E, (q31_t)0x176DD9DE, (q31_t)0x7DC3D90D, + (q31_t)0x17D0A7BB, (q31_t)0x7DB0FDF7, (q31_t)0x183366E8, + (q31_t)0x7D9DD55A, (q31_t)0x18961727, (q31_t)0x7D8A5F3F, + (q31_t)0x18F8B83C, (q31_t)0x7D769BB5, (q31_t)0x195B49E9, + (q31_t)0x7D628AC5, (q31_t)0x19BDCBF2, (q31_t)0x7D4E2C7E, + (q31_t)0x1A203E1B, (q31_t)0x7D3980EC, (q31_t)0x1A82A025, + (q31_t)0x7D24881A, (q31_t)0x1AE4F1D6, (q31_t)0x7D0F4218, + (q31_t)0x1B4732EF, (q31_t)0x7CF9AEF0, (q31_t)0x1BA96334, + (q31_t)0x7CE3CEB1, (q31_t)0x1C0B826A, (q31_t)0x7CCDA168, + (q31_t)0x1C6D9053, (q31_t)0x7CB72724, (q31_t)0x1CCF8CB3, + (q31_t)0x7CA05FF1, (q31_t)0x1D31774D, (q31_t)0x7C894BDD, + (q31_t)0x1D934FE5, (q31_t)0x7C71EAF8, (q31_t)0x1DF5163F, + (q31_t)0x7C5A3D4F, (q31_t)0x1E56CA1E, (q31_t)0x7C4242F2, + (q31_t)0x1EB86B46, (q31_t)0x7C29FBEE, (q31_t)0x1F19F97B, + (q31_t)0x7C116853, (q31_t)0x1F7B7480, (q31_t)0x7BF88830, + (q31_t)0x1FDCDC1A, (q31_t)0x7BDF5B94, (q31_t)0x203E300D, + (q31_t)0x7BC5E28F, (q31_t)0x209F701C, (q31_t)0x7BAC1D31, + (q31_t)0x21009C0B, (q31_t)0x7B920B89, (q31_t)0x2161B39F, + (q31_t)0x7B77ADA8, (q31_t)0x21C2B69C, (q31_t)0x7B5D039D, + (q31_t)0x2223A4C5, (q31_t)0x7B420D7A, (q31_t)0x22847DDF, + (q31_t)0x7B26CB4F, (q31_t)0x22E541AE, (q31_t)0x7B0B3D2C, + (q31_t)0x2345EFF7, (q31_t)0x7AEF6323, (q31_t)0x23A6887E, + (q31_t)0x7AD33D45, (q31_t)0x24070B07, (q31_t)0x7AB6CBA3, + (q31_t)0x24677757, (q31_t)0x7A9A0E4F, (q31_t)0x24C7CD32, + (q31_t)0x7A7D055B, (q31_t)0x25280C5D, (q31_t)0x7A5FB0D8, + (q31_t)0x2588349D, (q31_t)0x7A4210D8, (q31_t)0x25E845B5, + (q31_t)0x7A24256E, (q31_t)0x26483F6C, (q31_t)0x7A05EEAD, + (q31_t)0x26A82185, (q31_t)0x79E76CA6, (q31_t)0x2707EBC6, + (q31_t)0x79C89F6D, (q31_t)0x27679DF4, (q31_t)0x79A98715, + (q31_t)0x27C737D2, (q31_t)0x798A23B1, (q31_t)0x2826B928, + (q31_t)0x796A7554, (q31_t)0x288621B9, (q31_t)0x794A7C11, + (q31_t)0x28E5714A, (q31_t)0x792A37FE, (q31_t)0x2944A7A2, + (q31_t)0x7909A92C, (q31_t)0x29A3C484, (q31_t)0x78E8CFB1, + (q31_t)0x2A02C7B8, (q31_t)0x78C7ABA1, (q31_t)0x2A61B101, + (q31_t)0x78A63D10, (q31_t)0x2AC08025, (q31_t)0x78848413, + (q31_t)0x2B1F34EB, (q31_t)0x786280BF, (q31_t)0x2B7DCF17, + (q31_t)0x78403328, (q31_t)0x2BDC4E6F, (q31_t)0x781D9B64, + (q31_t)0x2C3AB2B9, (q31_t)0x77FAB988, (q31_t)0x2C98FBBA, + (q31_t)0x77D78DAA, (q31_t)0x2CF72939, (q31_t)0x77B417DF, + (q31_t)0x2D553AFB, (q31_t)0x7790583D, (q31_t)0x2DB330C7, + (q31_t)0x776C4EDB, (q31_t)0x2E110A62, (q31_t)0x7747FBCE, + (q31_t)0x2E6EC792, (q31_t)0x77235F2D, (q31_t)0x2ECC681E, + (q31_t)0x76FE790E, (q31_t)0x2F29EBCC, (q31_t)0x76D94988, + (q31_t)0x2F875262, (q31_t)0x76B3D0B3, (q31_t)0x2FE49BA6, + (q31_t)0x768E0EA5, (q31_t)0x3041C760, (q31_t)0x76680376, + (q31_t)0x309ED555, (q31_t)0x7641AF3C, (q31_t)0x30FBC54D, + (q31_t)0x761B1211, (q31_t)0x3158970D, (q31_t)0x75F42C0A, + (q31_t)0x31B54A5D, (q31_t)0x75CCFD42, (q31_t)0x3211DF03, + (q31_t)0x75A585CF, (q31_t)0x326E54C7, (q31_t)0x757DC5CA, + (q31_t)0x32CAAB6F, (q31_t)0x7555BD4B, (q31_t)0x3326E2C2, + (q31_t)0x752D6C6C, (q31_t)0x3382FA88, (q31_t)0x7504D345, + (q31_t)0x33DEF287, (q31_t)0x74DBF1EF, (q31_t)0x343ACA87, + (q31_t)0x74B2C883, (q31_t)0x3496824F, (q31_t)0x7489571B, + (q31_t)0x34F219A7, (q31_t)0x745F9DD1, (q31_t)0x354D9056, + (q31_t)0x74359CBD, (q31_t)0x35A8E624, (q31_t)0x740B53FA, + (q31_t)0x36041AD9, (q31_t)0x73E0C3A3, (q31_t)0x365F2E3B, + (q31_t)0x73B5EBD0, (q31_t)0x36BA2013, (q31_t)0x738ACC9E, + (q31_t)0x3714F02A, (q31_t)0x735F6626, (q31_t)0x376F9E46, + (q31_t)0x7333B883, (q31_t)0x37CA2A30, (q31_t)0x7307C3D0, + (q31_t)0x382493B0, (q31_t)0x72DB8828, (q31_t)0x387EDA8E, + (q31_t)0x72AF05A6, (q31_t)0x38D8FE93, (q31_t)0x72823C66, + (q31_t)0x3932FF87, (q31_t)0x72552C84, (q31_t)0x398CDD32, + (q31_t)0x7227D61C, (q31_t)0x39E6975D, (q31_t)0x71FA3948, + (q31_t)0x3A402DD1, (q31_t)0x71CC5626, (q31_t)0x3A99A057, + (q31_t)0x719E2CD2, (q31_t)0x3AF2EEB7, (q31_t)0x716FBD68, + (q31_t)0x3B4C18BA, (q31_t)0x71410804, (q31_t)0x3BA51E29, + (q31_t)0x71120CC5, (q31_t)0x3BFDFECD, (q31_t)0x70E2CBC6, + (q31_t)0x3C56BA70, (q31_t)0x70B34524, (q31_t)0x3CAF50DA, + (q31_t)0x708378FE, (q31_t)0x3D07C1D5, (q31_t)0x70536771, + (q31_t)0x3D600D2B, (q31_t)0x70231099, (q31_t)0x3DB832A5, + (q31_t)0x6FF27496, (q31_t)0x3E10320D, (q31_t)0x6FC19385, + (q31_t)0x3E680B2C, (q31_t)0x6F906D84, (q31_t)0x3EBFBDCC, + (q31_t)0x6F5F02B1, (q31_t)0x3F1749B7, (q31_t)0x6F2D532C, + (q31_t)0x3F6EAEB8, (q31_t)0x6EFB5F12, (q31_t)0x3FC5EC97, + (q31_t)0x6EC92682, (q31_t)0x401D0320, (q31_t)0x6E96A99C, + (q31_t)0x4073F21D, (q31_t)0x6E63E87F, (q31_t)0x40CAB957, + (q31_t)0x6E30E349, (q31_t)0x4121589A, (q31_t)0x6DFD9A1B, + (q31_t)0x4177CFB0, (q31_t)0x6DCA0D14, (q31_t)0x41CE1E64, + (q31_t)0x6D963C54, (q31_t)0x42244480, (q31_t)0x6D6227FA, + (q31_t)0x427A41D0, (q31_t)0x6D2DD027, (q31_t)0x42D0161E, + (q31_t)0x6CF934FB, (q31_t)0x4325C135, (q31_t)0x6CC45697, + (q31_t)0x437B42E1, (q31_t)0x6C8F351C, (q31_t)0x43D09AEC, + (q31_t)0x6C59D0A9, (q31_t)0x4425C923, (q31_t)0x6C242960, + (q31_t)0x447ACD50, (q31_t)0x6BEE3F62, (q31_t)0x44CFA73F, + (q31_t)0x6BB812D0, (q31_t)0x452456BC, (q31_t)0x6B81A3CD, + (q31_t)0x4578DB93, (q31_t)0x6B4AF278, (q31_t)0x45CD358F, + (q31_t)0x6B13FEF5, (q31_t)0x4621647C, (q31_t)0x6ADCC964, + (q31_t)0x46756827, (q31_t)0x6AA551E8, (q31_t)0x46C9405C, + (q31_t)0x6A6D98A4, (q31_t)0x471CECE6, (q31_t)0x6A359DB9, + (q31_t)0x47706D93, (q31_t)0x69FD614A, (q31_t)0x47C3C22E, + (q31_t)0x69C4E37A, (q31_t)0x4816EA85, (q31_t)0x698C246C, + (q31_t)0x4869E664, (q31_t)0x69532442, (q31_t)0x48BCB598, + (q31_t)0x6919E320, (q31_t)0x490F57EE, (q31_t)0x68E06129, + (q31_t)0x4961CD32, (q31_t)0x68A69E81, (q31_t)0x49B41533, + (q31_t)0x686C9B4B, (q31_t)0x4A062FBD, (q31_t)0x683257AA, + (q31_t)0x4A581C9D, (q31_t)0x67F7D3C4, (q31_t)0x4AA9DBA1, + (q31_t)0x67BD0FBC, (q31_t)0x4AFB6C97, (q31_t)0x67820BB6, + (q31_t)0x4B4CCF4D, (q31_t)0x6746C7D7, (q31_t)0x4B9E038F, + (q31_t)0x670B4443, (q31_t)0x4BEF092D, (q31_t)0x66CF811F, + (q31_t)0x4C3FDFF3, (q31_t)0x66937E90, (q31_t)0x4C9087B1, + (q31_t)0x66573CBB, (q31_t)0x4CE10034, (q31_t)0x661ABBC5, + (q31_t)0x4D31494B, (q31_t)0x65DDFBD3, (q31_t)0x4D8162C4, + (q31_t)0x65A0FD0B, (q31_t)0x4DD14C6E, (q31_t)0x6563BF92, + (q31_t)0x4E210617, (q31_t)0x6526438E, (q31_t)0x4E708F8F, + (q31_t)0x64E88926, (q31_t)0x4EBFE8A4, (q31_t)0x64AA907F, + (q31_t)0x4F0F1126, (q31_t)0x646C59BF, (q31_t)0x4F5E08E3, + (q31_t)0x642DE50D, (q31_t)0x4FACCFAB, (q31_t)0x63EF328F, + (q31_t)0x4FFB654D, (q31_t)0x63B0426D, (q31_t)0x5049C999, + (q31_t)0x637114CC, (q31_t)0x5097FC5E, (q31_t)0x6331A9D4, + (q31_t)0x50E5FD6C, (q31_t)0x62F201AC, (q31_t)0x5133CC94, + (q31_t)0x62B21C7B, (q31_t)0x518169A4, (q31_t)0x6271FA69, + (q31_t)0x51CED46E, (q31_t)0x62319B9D, (q31_t)0x521C0CC1, + (q31_t)0x61F1003E, (q31_t)0x5269126E, (q31_t)0x61B02876, + (q31_t)0x52B5E545, (q31_t)0x616F146B, (q31_t)0x53028517, + (q31_t)0x612DC446, (q31_t)0x534EF1B5, (q31_t)0x60EC3830, + (q31_t)0x539B2AEF, (q31_t)0x60AA704F, (q31_t)0x53E73097, + (q31_t)0x60686CCE, (q31_t)0x5433027D, (q31_t)0x60262DD5, + (q31_t)0x547EA073, (q31_t)0x5FE3B38D, (q31_t)0x54CA0A4A, + (q31_t)0x5FA0FE1E, (q31_t)0x55153FD4, (q31_t)0x5F5E0DB3, + (q31_t)0x556040E2, (q31_t)0x5F1AE273, (q31_t)0x55AB0D46, + (q31_t)0x5ED77C89, (q31_t)0x55F5A4D2, (q31_t)0x5E93DC1F, + (q31_t)0x56400757, (q31_t)0x5E50015D, (q31_t)0x568A34A9, + (q31_t)0x5E0BEC6E, (q31_t)0x56D42C99, (q31_t)0x5DC79D7C, + (q31_t)0x571DEEF9, (q31_t)0x5D8314B0, (q31_t)0x57677B9D, + (q31_t)0x5D3E5236, (q31_t)0x57B0D256, (q31_t)0x5CF95638, + (q31_t)0x57F9F2F7, (q31_t)0x5CB420DF, (q31_t)0x5842DD54, + (q31_t)0x5C6EB258, (q31_t)0x588B913F, (q31_t)0x5C290ACC, + (q31_t)0x58D40E8C, (q31_t)0x5BE32A67, (q31_t)0x591C550E, + (q31_t)0x5B9D1153, (q31_t)0x59646497, (q31_t)0x5B56BFBD, + (q31_t)0x59AC3CFD, (q31_t)0x5B1035CF, (q31_t)0x59F3DE12, + (q31_t)0x5AC973B4, (q31_t)0x5A3B47AA, (q31_t)0x5A82799A, + (q31_t)0x5A82799A, (q31_t)0x5A3B47AA, (q31_t)0x5AC973B4, + (q31_t)0x59F3DE12, (q31_t)0x5B1035CF, (q31_t)0x59AC3CFD, + (q31_t)0x5B56BFBD, (q31_t)0x59646497, (q31_t)0x5B9D1153, + (q31_t)0x591C550E, (q31_t)0x5BE32A67, (q31_t)0x58D40E8C, + (q31_t)0x5C290ACC, (q31_t)0x588B913F, (q31_t)0x5C6EB258, + (q31_t)0x5842DD54, (q31_t)0x5CB420DF, (q31_t)0x57F9F2F7, + (q31_t)0x5CF95638, (q31_t)0x57B0D256, (q31_t)0x5D3E5236, + (q31_t)0x57677B9D, (q31_t)0x5D8314B0, (q31_t)0x571DEEF9, + (q31_t)0x5DC79D7C, (q31_t)0x56D42C99, (q31_t)0x5E0BEC6E, + (q31_t)0x568A34A9, (q31_t)0x5E50015D, (q31_t)0x56400757, + (q31_t)0x5E93DC1F, (q31_t)0x55F5A4D2, (q31_t)0x5ED77C89, + (q31_t)0x55AB0D46, (q31_t)0x5F1AE273, (q31_t)0x556040E2, + (q31_t)0x5F5E0DB3, (q31_t)0x55153FD4, (q31_t)0x5FA0FE1E, + (q31_t)0x54CA0A4A, (q31_t)0x5FE3B38D, (q31_t)0x547EA073, + (q31_t)0x60262DD5, (q31_t)0x5433027D, (q31_t)0x60686CCE, + (q31_t)0x53E73097, (q31_t)0x60AA704F, (q31_t)0x539B2AEF, + (q31_t)0x60EC3830, (q31_t)0x534EF1B5, (q31_t)0x612DC446, + (q31_t)0x53028517, (q31_t)0x616F146B, (q31_t)0x52B5E545, + (q31_t)0x61B02876, (q31_t)0x5269126E, (q31_t)0x61F1003E, + (q31_t)0x521C0CC1, (q31_t)0x62319B9D, (q31_t)0x51CED46E, + (q31_t)0x6271FA69, (q31_t)0x518169A4, (q31_t)0x62B21C7B, + (q31_t)0x5133CC94, (q31_t)0x62F201AC, (q31_t)0x50E5FD6C, + (q31_t)0x6331A9D4, (q31_t)0x5097FC5E, (q31_t)0x637114CC, + (q31_t)0x5049C999, (q31_t)0x63B0426D, (q31_t)0x4FFB654D, + (q31_t)0x63EF328F, (q31_t)0x4FACCFAB, (q31_t)0x642DE50D, + (q31_t)0x4F5E08E3, (q31_t)0x646C59BF, (q31_t)0x4F0F1126, + (q31_t)0x64AA907F, (q31_t)0x4EBFE8A4, (q31_t)0x64E88926, + (q31_t)0x4E708F8F, (q31_t)0x6526438E, (q31_t)0x4E210617, + (q31_t)0x6563BF92, (q31_t)0x4DD14C6E, (q31_t)0x65A0FD0B, + (q31_t)0x4D8162C4, (q31_t)0x65DDFBD3, (q31_t)0x4D31494B, + (q31_t)0x661ABBC5, (q31_t)0x4CE10034, (q31_t)0x66573CBB, + (q31_t)0x4C9087B1, (q31_t)0x66937E90, (q31_t)0x4C3FDFF3, + (q31_t)0x66CF811F, (q31_t)0x4BEF092D, (q31_t)0x670B4443, + (q31_t)0x4B9E038F, (q31_t)0x6746C7D7, (q31_t)0x4B4CCF4D, + (q31_t)0x67820BB6, (q31_t)0x4AFB6C97, (q31_t)0x67BD0FBC, + (q31_t)0x4AA9DBA1, (q31_t)0x67F7D3C4, (q31_t)0x4A581C9D, + (q31_t)0x683257AA, (q31_t)0x4A062FBD, (q31_t)0x686C9B4B, + (q31_t)0x49B41533, (q31_t)0x68A69E81, (q31_t)0x4961CD32, + (q31_t)0x68E06129, (q31_t)0x490F57EE, (q31_t)0x6919E320, + (q31_t)0x48BCB598, (q31_t)0x69532442, (q31_t)0x4869E664, + (q31_t)0x698C246C, (q31_t)0x4816EA85, (q31_t)0x69C4E37A, + (q31_t)0x47C3C22E, (q31_t)0x69FD614A, (q31_t)0x47706D93, + (q31_t)0x6A359DB9, (q31_t)0x471CECE6, (q31_t)0x6A6D98A4, + (q31_t)0x46C9405C, (q31_t)0x6AA551E8, (q31_t)0x46756827, + (q31_t)0x6ADCC964, (q31_t)0x4621647C, (q31_t)0x6B13FEF5, + (q31_t)0x45CD358F, (q31_t)0x6B4AF278, (q31_t)0x4578DB93, + (q31_t)0x6B81A3CD, (q31_t)0x452456BC, (q31_t)0x6BB812D0, + (q31_t)0x44CFA73F, (q31_t)0x6BEE3F62, (q31_t)0x447ACD50, + (q31_t)0x6C242960, (q31_t)0x4425C923, (q31_t)0x6C59D0A9, + (q31_t)0x43D09AEC, (q31_t)0x6C8F351C, (q31_t)0x437B42E1, + (q31_t)0x6CC45697, (q31_t)0x4325C135, (q31_t)0x6CF934FB, + (q31_t)0x42D0161E, (q31_t)0x6D2DD027, (q31_t)0x427A41D0, + (q31_t)0x6D6227FA, (q31_t)0x42244480, (q31_t)0x6D963C54, + (q31_t)0x41CE1E64, (q31_t)0x6DCA0D14, (q31_t)0x4177CFB0, + (q31_t)0x6DFD9A1B, (q31_t)0x4121589A, (q31_t)0x6E30E349, + (q31_t)0x40CAB957, (q31_t)0x6E63E87F, (q31_t)0x4073F21D, + (q31_t)0x6E96A99C, (q31_t)0x401D0320, (q31_t)0x6EC92682, + (q31_t)0x3FC5EC97, (q31_t)0x6EFB5F12, (q31_t)0x3F6EAEB8, + (q31_t)0x6F2D532C, (q31_t)0x3F1749B7, (q31_t)0x6F5F02B1, + (q31_t)0x3EBFBDCC, (q31_t)0x6F906D84, (q31_t)0x3E680B2C, + (q31_t)0x6FC19385, (q31_t)0x3E10320D, (q31_t)0x6FF27496, + (q31_t)0x3DB832A5, (q31_t)0x70231099, (q31_t)0x3D600D2B, + (q31_t)0x70536771, (q31_t)0x3D07C1D5, (q31_t)0x708378FE, + (q31_t)0x3CAF50DA, (q31_t)0x70B34524, (q31_t)0x3C56BA70, + (q31_t)0x70E2CBC6, (q31_t)0x3BFDFECD, (q31_t)0x71120CC5, + (q31_t)0x3BA51E29, (q31_t)0x71410804, (q31_t)0x3B4C18BA, + (q31_t)0x716FBD68, (q31_t)0x3AF2EEB7, (q31_t)0x719E2CD2, + (q31_t)0x3A99A057, (q31_t)0x71CC5626, (q31_t)0x3A402DD1, + (q31_t)0x71FA3948, (q31_t)0x39E6975D, (q31_t)0x7227D61C, + (q31_t)0x398CDD32, (q31_t)0x72552C84, (q31_t)0x3932FF87, + (q31_t)0x72823C66, (q31_t)0x38D8FE93, (q31_t)0x72AF05A6, + (q31_t)0x387EDA8E, (q31_t)0x72DB8828, (q31_t)0x382493B0, + (q31_t)0x7307C3D0, (q31_t)0x37CA2A30, (q31_t)0x7333B883, + (q31_t)0x376F9E46, (q31_t)0x735F6626, (q31_t)0x3714F02A, + (q31_t)0x738ACC9E, (q31_t)0x36BA2013, (q31_t)0x73B5EBD0, + (q31_t)0x365F2E3B, (q31_t)0x73E0C3A3, (q31_t)0x36041AD9, + (q31_t)0x740B53FA, (q31_t)0x35A8E624, (q31_t)0x74359CBD, + (q31_t)0x354D9056, (q31_t)0x745F9DD1, (q31_t)0x34F219A7, + (q31_t)0x7489571B, (q31_t)0x3496824F, (q31_t)0x74B2C883, + (q31_t)0x343ACA87, (q31_t)0x74DBF1EF, (q31_t)0x33DEF287, + (q31_t)0x7504D345, (q31_t)0x3382FA88, (q31_t)0x752D6C6C, + (q31_t)0x3326E2C2, (q31_t)0x7555BD4B, (q31_t)0x32CAAB6F, + (q31_t)0x757DC5CA, (q31_t)0x326E54C7, (q31_t)0x75A585CF, + (q31_t)0x3211DF03, (q31_t)0x75CCFD42, (q31_t)0x31B54A5D, + (q31_t)0x75F42C0A, (q31_t)0x3158970D, (q31_t)0x761B1211, + (q31_t)0x30FBC54D, (q31_t)0x7641AF3C, (q31_t)0x309ED555, + (q31_t)0x76680376, (q31_t)0x3041C760, (q31_t)0x768E0EA5, + (q31_t)0x2FE49BA6, (q31_t)0x76B3D0B3, (q31_t)0x2F875262, + (q31_t)0x76D94988, (q31_t)0x2F29EBCC, (q31_t)0x76FE790E, + (q31_t)0x2ECC681E, (q31_t)0x77235F2D, (q31_t)0x2E6EC792, + (q31_t)0x7747FBCE, (q31_t)0x2E110A62, (q31_t)0x776C4EDB, + (q31_t)0x2DB330C7, (q31_t)0x7790583D, (q31_t)0x2D553AFB, + (q31_t)0x77B417DF, (q31_t)0x2CF72939, (q31_t)0x77D78DAA, + (q31_t)0x2C98FBBA, (q31_t)0x77FAB988, (q31_t)0x2C3AB2B9, + (q31_t)0x781D9B64, (q31_t)0x2BDC4E6F, (q31_t)0x78403328, + (q31_t)0x2B7DCF17, (q31_t)0x786280BF, (q31_t)0x2B1F34EB, + (q31_t)0x78848413, (q31_t)0x2AC08025, (q31_t)0x78A63D10, + (q31_t)0x2A61B101, (q31_t)0x78C7ABA1, (q31_t)0x2A02C7B8, + (q31_t)0x78E8CFB1, (q31_t)0x29A3C484, (q31_t)0x7909A92C, + (q31_t)0x2944A7A2, (q31_t)0x792A37FE, (q31_t)0x28E5714A, + (q31_t)0x794A7C11, (q31_t)0x288621B9, (q31_t)0x796A7554, + (q31_t)0x2826B928, (q31_t)0x798A23B1, (q31_t)0x27C737D2, + (q31_t)0x79A98715, (q31_t)0x27679DF4, (q31_t)0x79C89F6D, + (q31_t)0x2707EBC6, (q31_t)0x79E76CA6, (q31_t)0x26A82185, + (q31_t)0x7A05EEAD, (q31_t)0x26483F6C, (q31_t)0x7A24256E, + (q31_t)0x25E845B5, (q31_t)0x7A4210D8, (q31_t)0x2588349D, + (q31_t)0x7A5FB0D8, (q31_t)0x25280C5D, (q31_t)0x7A7D055B, + (q31_t)0x24C7CD32, (q31_t)0x7A9A0E4F, (q31_t)0x24677757, + (q31_t)0x7AB6CBA3, (q31_t)0x24070B07, (q31_t)0x7AD33D45, + (q31_t)0x23A6887E, (q31_t)0x7AEF6323, (q31_t)0x2345EFF7, + (q31_t)0x7B0B3D2C, (q31_t)0x22E541AE, (q31_t)0x7B26CB4F, + (q31_t)0x22847DDF, (q31_t)0x7B420D7A, (q31_t)0x2223A4C5, + (q31_t)0x7B5D039D, (q31_t)0x21C2B69C, (q31_t)0x7B77ADA8, + (q31_t)0x2161B39F, (q31_t)0x7B920B89, (q31_t)0x21009C0B, + (q31_t)0x7BAC1D31, (q31_t)0x209F701C, (q31_t)0x7BC5E28F, + (q31_t)0x203E300D, (q31_t)0x7BDF5B94, (q31_t)0x1FDCDC1A, + (q31_t)0x7BF88830, (q31_t)0x1F7B7480, (q31_t)0x7C116853, + (q31_t)0x1F19F97B, (q31_t)0x7C29FBEE, (q31_t)0x1EB86B46, + (q31_t)0x7C4242F2, (q31_t)0x1E56CA1E, (q31_t)0x7C5A3D4F, + (q31_t)0x1DF5163F, (q31_t)0x7C71EAF8, (q31_t)0x1D934FE5, + (q31_t)0x7C894BDD, (q31_t)0x1D31774D, (q31_t)0x7CA05FF1, + (q31_t)0x1CCF8CB3, (q31_t)0x7CB72724, (q31_t)0x1C6D9053, + (q31_t)0x7CCDA168, (q31_t)0x1C0B826A, (q31_t)0x7CE3CEB1, + (q31_t)0x1BA96334, (q31_t)0x7CF9AEF0, (q31_t)0x1B4732EF, + (q31_t)0x7D0F4218, (q31_t)0x1AE4F1D6, (q31_t)0x7D24881A, + (q31_t)0x1A82A025, (q31_t)0x7D3980EC, (q31_t)0x1A203E1B, + (q31_t)0x7D4E2C7E, (q31_t)0x19BDCBF2, (q31_t)0x7D628AC5, + (q31_t)0x195B49E9, (q31_t)0x7D769BB5, (q31_t)0x18F8B83C, + (q31_t)0x7D8A5F3F, (q31_t)0x18961727, (q31_t)0x7D9DD55A, + (q31_t)0x183366E8, (q31_t)0x7DB0FDF7, (q31_t)0x17D0A7BB, + (q31_t)0x7DC3D90D, (q31_t)0x176DD9DE, (q31_t)0x7DD6668E, + (q31_t)0x170AFD8D, (q31_t)0x7DE8A670, (q31_t)0x16A81305, + (q31_t)0x7DFA98A7, (q31_t)0x16451A83, (q31_t)0x7E0C3D29, + (q31_t)0x15E21444, (q31_t)0x7E1D93E9, (q31_t)0x157F0086, + (q31_t)0x7E2E9CDF, (q31_t)0x151BDF85, (q31_t)0x7E3F57FE, + (q31_t)0x14B8B17F, (q31_t)0x7E4FC53E, (q31_t)0x145576B1, + (q31_t)0x7E5FE493, (q31_t)0x13F22F57, (q31_t)0x7E6FB5F3, + (q31_t)0x138EDBB0, (q31_t)0x7E7F3956, (q31_t)0x132B7BF9, + (q31_t)0x7E8E6EB1, (q31_t)0x12C8106E, (q31_t)0x7E9D55FC, + (q31_t)0x1264994E, (q31_t)0x7EABEF2C, (q31_t)0x120116D4, + (q31_t)0x7EBA3A39, (q31_t)0x119D8940, (q31_t)0x7EC8371A, + (q31_t)0x1139F0CE, (q31_t)0x7ED5E5C6, (q31_t)0x10D64DBC, + (q31_t)0x7EE34635, (q31_t)0x1072A047, (q31_t)0x7EF0585F, + (q31_t)0x100EE8AD, (q31_t)0x7EFD1C3C, (q31_t)0x0FAB272B, + (q31_t)0x7F0991C3, (q31_t)0x0F475BFE, (q31_t)0x7F15B8EE, + (q31_t)0x0EE38765, (q31_t)0x7F2191B4, (q31_t)0x0E7FA99D, + (q31_t)0x7F2D1C0E, (q31_t)0x0E1BC2E3, (q31_t)0x7F3857F5, + (q31_t)0x0DB7D376, (q31_t)0x7F434563, (q31_t)0x0D53DB92, + (q31_t)0x7F4DE450, (q31_t)0x0CEFDB75, (q31_t)0x7F5834B6, + (q31_t)0x0C8BD35E, (q31_t)0x7F62368F, (q31_t)0x0C27C389, + (q31_t)0x7F6BE9D4, (q31_t)0x0BC3AC35, (q31_t)0x7F754E7F, + (q31_t)0x0B5F8D9F, (q31_t)0x7F7E648B, (q31_t)0x0AFB6805, + (q31_t)0x7F872BF3, (q31_t)0x0A973BA5, (q31_t)0x7F8FA4AF, + (q31_t)0x0A3308BC, (q31_t)0x7F97CEBC, (q31_t)0x09CECF89, + (q31_t)0x7F9FAA15, (q31_t)0x096A9049, (q31_t)0x7FA736B4, + (q31_t)0x09064B3A, (q31_t)0x7FAE7494, (q31_t)0x08A2009A, + (q31_t)0x7FB563B2, (q31_t)0x083DB0A7, (q31_t)0x7FBC040A, + (q31_t)0x07D95B9E, (q31_t)0x7FC25596, (q31_t)0x077501BE, + (q31_t)0x7FC85853, (q31_t)0x0710A344, (q31_t)0x7FCE0C3E, + (q31_t)0x06AC406F, (q31_t)0x7FD37152, (q31_t)0x0647D97C, + (q31_t)0x7FD8878D, (q31_t)0x05E36EA9, (q31_t)0x7FDD4EEC, + (q31_t)0x057F0034, (q31_t)0x7FE1C76B, (q31_t)0x051A8E5C, + (q31_t)0x7FE5F108, (q31_t)0x04B6195D, (q31_t)0x7FE9CBC0, + (q31_t)0x0451A176, (q31_t)0x7FED5790, (q31_t)0x03ED26E6, + (q31_t)0x7FF09477, (q31_t)0x0388A9E9, (q31_t)0x7FF38273, + (q31_t)0x03242ABF, (q31_t)0x7FF62182, (q31_t)0x02BFA9A4, + (q31_t)0x7FF871A1, (q31_t)0x025B26D7, (q31_t)0x7FFA72D1, + (q31_t)0x01F6A296, (q31_t)0x7FFC250F, (q31_t)0x01921D1F, + (q31_t)0x7FFD885A, (q31_t)0x012D96B0, (q31_t)0x7FFE9CB2, + (q31_t)0x00C90F88, (q31_t)0x7FFF6216, (q31_t)0x006487E3, + (q31_t)0x7FFFD885, (q31_t)0x00000000, (q31_t)0x7FFFFFFF, + (q31_t)0xFF9B781D, (q31_t)0x7FFFD885, (q31_t)0xFF36F078, + (q31_t)0x7FFF6216, (q31_t)0xFED2694F, (q31_t)0x7FFE9CB2, + (q31_t)0xFE6DE2E0, (q31_t)0x7FFD885A, (q31_t)0xFE095D69, + (q31_t)0x7FFC250F, (q31_t)0xFDA4D928, (q31_t)0x7FFA72D1, + (q31_t)0xFD40565B, (q31_t)0x7FF871A1, (q31_t)0xFCDBD541, + (q31_t)0x7FF62182, (q31_t)0xFC775616, (q31_t)0x7FF38273, + (q31_t)0xFC12D919, (q31_t)0x7FF09477, (q31_t)0xFBAE5E89, + (q31_t)0x7FED5790, (q31_t)0xFB49E6A2, (q31_t)0x7FE9CBC0, + (q31_t)0xFAE571A4, (q31_t)0x7FE5F108, (q31_t)0xFA80FFCB, + (q31_t)0x7FE1C76B, (q31_t)0xFA1C9156, (q31_t)0x7FDD4EEC, + (q31_t)0xF9B82683, (q31_t)0x7FD8878D, (q31_t)0xF953BF90, + (q31_t)0x7FD37152, (q31_t)0xF8EF5CBB, (q31_t)0x7FCE0C3E, + (q31_t)0xF88AFE41, (q31_t)0x7FC85853, (q31_t)0xF826A461, + (q31_t)0x7FC25596, (q31_t)0xF7C24F58, (q31_t)0x7FBC040A, + (q31_t)0xF75DFF65, (q31_t)0x7FB563B2, (q31_t)0xF6F9B4C5, + (q31_t)0x7FAE7494, (q31_t)0xF6956FB6, (q31_t)0x7FA736B4, + (q31_t)0xF6313076, (q31_t)0x7F9FAA15, (q31_t)0xF5CCF743, + (q31_t)0x7F97CEBC, (q31_t)0xF568C45A, (q31_t)0x7F8FA4AF, + (q31_t)0xF50497FA, (q31_t)0x7F872BF3, (q31_t)0xF4A07260, + (q31_t)0x7F7E648B, (q31_t)0xF43C53CA, (q31_t)0x7F754E7F, + (q31_t)0xF3D83C76, (q31_t)0x7F6BE9D4, (q31_t)0xF3742CA1, + (q31_t)0x7F62368F, (q31_t)0xF310248A, (q31_t)0x7F5834B6, + (q31_t)0xF2AC246D, (q31_t)0x7F4DE450, (q31_t)0xF2482C89, + (q31_t)0x7F434563, (q31_t)0xF1E43D1C, (q31_t)0x7F3857F5, + (q31_t)0xF1805662, (q31_t)0x7F2D1C0E, (q31_t)0xF11C789A, + (q31_t)0x7F2191B4, (q31_t)0xF0B8A401, (q31_t)0x7F15B8EE, + (q31_t)0xF054D8D4, (q31_t)0x7F0991C3, (q31_t)0xEFF11752, + (q31_t)0x7EFD1C3C, (q31_t)0xEF8D5FB8, (q31_t)0x7EF0585F, + (q31_t)0xEF29B243, (q31_t)0x7EE34635, (q31_t)0xEEC60F31, + (q31_t)0x7ED5E5C6, (q31_t)0xEE6276BF, (q31_t)0x7EC8371A, + (q31_t)0xEDFEE92B, (q31_t)0x7EBA3A39, (q31_t)0xED9B66B2, + (q31_t)0x7EABEF2C, (q31_t)0xED37EF91, (q31_t)0x7E9D55FC, + (q31_t)0xECD48406, (q31_t)0x7E8E6EB1, (q31_t)0xEC71244F, + (q31_t)0x7E7F3956, (q31_t)0xEC0DD0A8, (q31_t)0x7E6FB5F3, + (q31_t)0xEBAA894E, (q31_t)0x7E5FE493, (q31_t)0xEB474E80, + (q31_t)0x7E4FC53E, (q31_t)0xEAE4207A, (q31_t)0x7E3F57FE, + (q31_t)0xEA80FF79, (q31_t)0x7E2E9CDF, (q31_t)0xEA1DEBBB, + (q31_t)0x7E1D93E9, (q31_t)0xE9BAE57C, (q31_t)0x7E0C3D29, + (q31_t)0xE957ECFB, (q31_t)0x7DFA98A7, (q31_t)0xE8F50273, + (q31_t)0x7DE8A670, (q31_t)0xE8922621, (q31_t)0x7DD6668E, + (q31_t)0xE82F5844, (q31_t)0x7DC3D90D, (q31_t)0xE7CC9917, + (q31_t)0x7DB0FDF7, (q31_t)0xE769E8D8, (q31_t)0x7D9DD55A, + (q31_t)0xE70747C3, (q31_t)0x7D8A5F3F, (q31_t)0xE6A4B616, + (q31_t)0x7D769BB5, (q31_t)0xE642340D, (q31_t)0x7D628AC5, + (q31_t)0xE5DFC1E4, (q31_t)0x7D4E2C7E, (q31_t)0xE57D5FDA, + (q31_t)0x7D3980EC, (q31_t)0xE51B0E2A, (q31_t)0x7D24881A, + (q31_t)0xE4B8CD10, (q31_t)0x7D0F4218, (q31_t)0xE4569CCB, + (q31_t)0x7CF9AEF0, (q31_t)0xE3F47D95, (q31_t)0x7CE3CEB1, + (q31_t)0xE3926FAC, (q31_t)0x7CCDA168, (q31_t)0xE330734C, + (q31_t)0x7CB72724, (q31_t)0xE2CE88B2, (q31_t)0x7CA05FF1, + (q31_t)0xE26CB01A, (q31_t)0x7C894BDD, (q31_t)0xE20AE9C1, + (q31_t)0x7C71EAF8, (q31_t)0xE1A935E1, (q31_t)0x7C5A3D4F, + (q31_t)0xE14794B9, (q31_t)0x7C4242F2, (q31_t)0xE0E60684, + (q31_t)0x7C29FBEE, (q31_t)0xE0848B7F, (q31_t)0x7C116853, + (q31_t)0xE02323E5, (q31_t)0x7BF88830, (q31_t)0xDFC1CFF2, + (q31_t)0x7BDF5B94, (q31_t)0xDF608FE3, (q31_t)0x7BC5E28F, + (q31_t)0xDEFF63F4, (q31_t)0x7BAC1D31, (q31_t)0xDE9E4C60, + (q31_t)0x7B920B89, (q31_t)0xDE3D4963, (q31_t)0x7B77ADA8, + (q31_t)0xDDDC5B3A, (q31_t)0x7B5D039D, (q31_t)0xDD7B8220, + (q31_t)0x7B420D7A, (q31_t)0xDD1ABE51, (q31_t)0x7B26CB4F, + (q31_t)0xDCBA1008, (q31_t)0x7B0B3D2C, (q31_t)0xDC597781, + (q31_t)0x7AEF6323, (q31_t)0xDBF8F4F8, (q31_t)0x7AD33D45, + (q31_t)0xDB9888A8, (q31_t)0x7AB6CBA3, (q31_t)0xDB3832CD, + (q31_t)0x7A9A0E4F, (q31_t)0xDAD7F3A2, (q31_t)0x7A7D055B, + (q31_t)0xDA77CB62, (q31_t)0x7A5FB0D8, (q31_t)0xDA17BA4A, + (q31_t)0x7A4210D8, (q31_t)0xD9B7C093, (q31_t)0x7A24256E, + (q31_t)0xD957DE7A, (q31_t)0x7A05EEAD, (q31_t)0xD8F81439, + (q31_t)0x79E76CA6, (q31_t)0xD898620C, (q31_t)0x79C89F6D, + (q31_t)0xD838C82D, (q31_t)0x79A98715, (q31_t)0xD7D946D7, + (q31_t)0x798A23B1, (q31_t)0xD779DE46, (q31_t)0x796A7554, + (q31_t)0xD71A8EB5, (q31_t)0x794A7C11, (q31_t)0xD6BB585D, + (q31_t)0x792A37FE, (q31_t)0xD65C3B7B, (q31_t)0x7909A92C, + (q31_t)0xD5FD3847, (q31_t)0x78E8CFB1, (q31_t)0xD59E4EFE, + (q31_t)0x78C7ABA1, (q31_t)0xD53F7FDA, (q31_t)0x78A63D10, + (q31_t)0xD4E0CB14, (q31_t)0x78848413, (q31_t)0xD48230E8, + (q31_t)0x786280BF, (q31_t)0xD423B190, (q31_t)0x78403328, + (q31_t)0xD3C54D46, (q31_t)0x781D9B64, (q31_t)0xD3670445, + (q31_t)0x77FAB988, (q31_t)0xD308D6C6, (q31_t)0x77D78DAA, + (q31_t)0xD2AAC504, (q31_t)0x77B417DF, (q31_t)0xD24CCF38, + (q31_t)0x7790583D, (q31_t)0xD1EEF59E, (q31_t)0x776C4EDB, + (q31_t)0xD191386D, (q31_t)0x7747FBCE, (q31_t)0xD13397E1, + (q31_t)0x77235F2D, (q31_t)0xD0D61433, (q31_t)0x76FE790E, + (q31_t)0xD078AD9D, (q31_t)0x76D94988, (q31_t)0xD01B6459, + (q31_t)0x76B3D0B3, (q31_t)0xCFBE389F, (q31_t)0x768E0EA5, + (q31_t)0xCF612AAA, (q31_t)0x76680376, (q31_t)0xCF043AB2, + (q31_t)0x7641AF3C, (q31_t)0xCEA768F2, (q31_t)0x761B1211, + (q31_t)0xCE4AB5A2, (q31_t)0x75F42C0A, (q31_t)0xCDEE20FC, + (q31_t)0x75CCFD42, (q31_t)0xCD91AB38, (q31_t)0x75A585CF, + (q31_t)0xCD355490, (q31_t)0x757DC5CA, (q31_t)0xCCD91D3D, + (q31_t)0x7555BD4B, (q31_t)0xCC7D0577, (q31_t)0x752D6C6C, + (q31_t)0xCC210D78, (q31_t)0x7504D345, (q31_t)0xCBC53578, + (q31_t)0x74DBF1EF, (q31_t)0xCB697DB0, (q31_t)0x74B2C883, + (q31_t)0xCB0DE658, (q31_t)0x7489571B, (q31_t)0xCAB26FA9, + (q31_t)0x745F9DD1, (q31_t)0xCA5719DB, (q31_t)0x74359CBD, + (q31_t)0xC9FBE527, (q31_t)0x740B53FA, (q31_t)0xC9A0D1C4, + (q31_t)0x73E0C3A3, (q31_t)0xC945DFEC, (q31_t)0x73B5EBD0, + (q31_t)0xC8EB0FD6, (q31_t)0x738ACC9E, (q31_t)0xC89061BA, + (q31_t)0x735F6626, (q31_t)0xC835D5D0, (q31_t)0x7333B883, + (q31_t)0xC7DB6C50, (q31_t)0x7307C3D0, (q31_t)0xC7812571, + (q31_t)0x72DB8828, (q31_t)0xC727016C, (q31_t)0x72AF05A6, + (q31_t)0xC6CD0079, (q31_t)0x72823C66, (q31_t)0xC67322CD, + (q31_t)0x72552C84, (q31_t)0xC61968A2, (q31_t)0x7227D61C, + (q31_t)0xC5BFD22E, (q31_t)0x71FA3948, (q31_t)0xC5665FA8, + (q31_t)0x71CC5626, (q31_t)0xC50D1148, (q31_t)0x719E2CD2, + (q31_t)0xC4B3E746, (q31_t)0x716FBD68, (q31_t)0xC45AE1D7, + (q31_t)0x71410804, (q31_t)0xC4020132, (q31_t)0x71120CC5, + (q31_t)0xC3A9458F, (q31_t)0x70E2CBC6, (q31_t)0xC350AF25, + (q31_t)0x70B34524, (q31_t)0xC2F83E2A, (q31_t)0x708378FE, + (q31_t)0xC29FF2D4, (q31_t)0x70536771, (q31_t)0xC247CD5A, + (q31_t)0x70231099, (q31_t)0xC1EFCDF2, (q31_t)0x6FF27496, + (q31_t)0xC197F4D3, (q31_t)0x6FC19385, (q31_t)0xC1404233, + (q31_t)0x6F906D84, (q31_t)0xC0E8B648, (q31_t)0x6F5F02B1, + (q31_t)0xC0915147, (q31_t)0x6F2D532C, (q31_t)0xC03A1368, + (q31_t)0x6EFB5F12, (q31_t)0xBFE2FCDF, (q31_t)0x6EC92682, + (q31_t)0xBF8C0DE2, (q31_t)0x6E96A99C, (q31_t)0xBF3546A8, + (q31_t)0x6E63E87F, (q31_t)0xBEDEA765, (q31_t)0x6E30E349, + (q31_t)0xBE88304F, (q31_t)0x6DFD9A1B, (q31_t)0xBE31E19B, + (q31_t)0x6DCA0D14, (q31_t)0xBDDBBB7F, (q31_t)0x6D963C54, + (q31_t)0xBD85BE2F, (q31_t)0x6D6227FA, (q31_t)0xBD2FE9E1, + (q31_t)0x6D2DD027, (q31_t)0xBCDA3ECA, (q31_t)0x6CF934FB, + (q31_t)0xBC84BD1E, (q31_t)0x6CC45697, (q31_t)0xBC2F6513, + (q31_t)0x6C8F351C, (q31_t)0xBBDA36DC, (q31_t)0x6C59D0A9, + (q31_t)0xBB8532AF, (q31_t)0x6C242960, (q31_t)0xBB3058C0, + (q31_t)0x6BEE3F62, (q31_t)0xBADBA943, (q31_t)0x6BB812D0, + (q31_t)0xBA87246C, (q31_t)0x6B81A3CD, (q31_t)0xBA32CA70, + (q31_t)0x6B4AF278, (q31_t)0xB9DE9B83, (q31_t)0x6B13FEF5, + (q31_t)0xB98A97D8, (q31_t)0x6ADCC964, (q31_t)0xB936BFA3, + (q31_t)0x6AA551E8, (q31_t)0xB8E31319, (q31_t)0x6A6D98A4, + (q31_t)0xB88F926C, (q31_t)0x6A359DB9, (q31_t)0xB83C3DD1, + (q31_t)0x69FD614A, (q31_t)0xB7E9157A, (q31_t)0x69C4E37A, + (q31_t)0xB796199B, (q31_t)0x698C246C, (q31_t)0xB7434A67, + (q31_t)0x69532442, (q31_t)0xB6F0A811, (q31_t)0x6919E320, + (q31_t)0xB69E32CD, (q31_t)0x68E06129, (q31_t)0xB64BEACC, + (q31_t)0x68A69E81, (q31_t)0xB5F9D042, (q31_t)0x686C9B4B, + (q31_t)0xB5A7E362, (q31_t)0x683257AA, (q31_t)0xB556245E, + (q31_t)0x67F7D3C4, (q31_t)0xB5049368, (q31_t)0x67BD0FBC, + (q31_t)0xB4B330B2, (q31_t)0x67820BB6, (q31_t)0xB461FC70, + (q31_t)0x6746C7D7, (q31_t)0xB410F6D2, (q31_t)0x670B4443, + (q31_t)0xB3C0200C, (q31_t)0x66CF811F, (q31_t)0xB36F784E, + (q31_t)0x66937E90, (q31_t)0xB31EFFCB, (q31_t)0x66573CBB, + (q31_t)0xB2CEB6B5, (q31_t)0x661ABBC5, (q31_t)0xB27E9D3B, + (q31_t)0x65DDFBD3, (q31_t)0xB22EB392, (q31_t)0x65A0FD0B, + (q31_t)0xB1DEF9E8, (q31_t)0x6563BF92, (q31_t)0xB18F7070, + (q31_t)0x6526438E, (q31_t)0xB140175B, (q31_t)0x64E88926, + (q31_t)0xB0F0EEDA, (q31_t)0x64AA907F, (q31_t)0xB0A1F71C, + (q31_t)0x646C59BF, (q31_t)0xB0533055, (q31_t)0x642DE50D, + (q31_t)0xB0049AB2, (q31_t)0x63EF328F, (q31_t)0xAFB63667, + (q31_t)0x63B0426D, (q31_t)0xAF6803A1, (q31_t)0x637114CC, + (q31_t)0xAF1A0293, (q31_t)0x6331A9D4, (q31_t)0xAECC336B, + (q31_t)0x62F201AC, (q31_t)0xAE7E965B, (q31_t)0x62B21C7B, + (q31_t)0xAE312B91, (q31_t)0x6271FA69, (q31_t)0xADE3F33E, + (q31_t)0x62319B9D, (q31_t)0xAD96ED91, (q31_t)0x61F1003E, + (q31_t)0xAD4A1ABA, (q31_t)0x61B02876, (q31_t)0xACFD7AE8, + (q31_t)0x616F146B, (q31_t)0xACB10E4A, (q31_t)0x612DC446, + (q31_t)0xAC64D510, (q31_t)0x60EC3830, (q31_t)0xAC18CF68, + (q31_t)0x60AA704F, (q31_t)0xABCCFD82, (q31_t)0x60686CCE, + (q31_t)0xAB815F8C, (q31_t)0x60262DD5, (q31_t)0xAB35F5B5, + (q31_t)0x5FE3B38D, (q31_t)0xAAEAC02B, (q31_t)0x5FA0FE1E, + (q31_t)0xAA9FBF1D, (q31_t)0x5F5E0DB3, (q31_t)0xAA54F2B9, + (q31_t)0x5F1AE273, (q31_t)0xAA0A5B2D, (q31_t)0x5ED77C89, + (q31_t)0xA9BFF8A8, (q31_t)0x5E93DC1F, (q31_t)0xA975CB56, + (q31_t)0x5E50015D, (q31_t)0xA92BD366, (q31_t)0x5E0BEC6E, + (q31_t)0xA8E21106, (q31_t)0x5DC79D7C, (q31_t)0xA8988463, + (q31_t)0x5D8314B0, (q31_t)0xA84F2DA9, (q31_t)0x5D3E5236, + (q31_t)0xA8060D08, (q31_t)0x5CF95638, (q31_t)0xA7BD22AB, + (q31_t)0x5CB420DF, (q31_t)0xA7746EC0, (q31_t)0x5C6EB258, + (q31_t)0xA72BF173, (q31_t)0x5C290ACC, (q31_t)0xA6E3AAF2, + (q31_t)0x5BE32A67, (q31_t)0xA69B9B68, (q31_t)0x5B9D1153, + (q31_t)0xA653C302, (q31_t)0x5B56BFBD, (q31_t)0xA60C21ED, + (q31_t)0x5B1035CF, (q31_t)0xA5C4B855, (q31_t)0x5AC973B4, + (q31_t)0xA57D8666, (q31_t)0x5A82799A, (q31_t)0xA5368C4B, + (q31_t)0x5A3B47AA, (q31_t)0xA4EFCA31, (q31_t)0x59F3DE12, + (q31_t)0xA4A94042, (q31_t)0x59AC3CFD, (q31_t)0xA462EEAC, + (q31_t)0x59646497, (q31_t)0xA41CD598, (q31_t)0x591C550E, + (q31_t)0xA3D6F533, (q31_t)0x58D40E8C, (q31_t)0xA3914DA7, + (q31_t)0x588B913F, (q31_t)0xA34BDF20, (q31_t)0x5842DD54, + (q31_t)0xA306A9C7, (q31_t)0x57F9F2F7, (q31_t)0xA2C1ADC9, + (q31_t)0x57B0D256, (q31_t)0xA27CEB4F, (q31_t)0x57677B9D, + (q31_t)0xA2386283, (q31_t)0x571DEEF9, (q31_t)0xA1F41391, + (q31_t)0x56D42C99, (q31_t)0xA1AFFEA2, (q31_t)0x568A34A9, + (q31_t)0xA16C23E1, (q31_t)0x56400757, (q31_t)0xA1288376, + (q31_t)0x55F5A4D2, (q31_t)0xA0E51D8C, (q31_t)0x55AB0D46, + (q31_t)0xA0A1F24C, (q31_t)0x556040E2, (q31_t)0xA05F01E1, + (q31_t)0x55153FD4, (q31_t)0xA01C4C72, (q31_t)0x54CA0A4A, + (q31_t)0x9FD9D22A, (q31_t)0x547EA073, (q31_t)0x9F979331, + (q31_t)0x5433027D, (q31_t)0x9F558FB0, (q31_t)0x53E73097, + (q31_t)0x9F13C7D0, (q31_t)0x539B2AEF, (q31_t)0x9ED23BB9, + (q31_t)0x534EF1B5, (q31_t)0x9E90EB94, (q31_t)0x53028517, + (q31_t)0x9E4FD789, (q31_t)0x52B5E545, (q31_t)0x9E0EFFC1, + (q31_t)0x5269126E, (q31_t)0x9DCE6462, (q31_t)0x521C0CC1, + (q31_t)0x9D8E0596, (q31_t)0x51CED46E, (q31_t)0x9D4DE384, + (q31_t)0x518169A4, (q31_t)0x9D0DFE53, (q31_t)0x5133CC94, + (q31_t)0x9CCE562B, (q31_t)0x50E5FD6C, (q31_t)0x9C8EEB33, + (q31_t)0x5097FC5E, (q31_t)0x9C4FBD92, (q31_t)0x5049C999, + (q31_t)0x9C10CD70, (q31_t)0x4FFB654D, (q31_t)0x9BD21AF2, + (q31_t)0x4FACCFAB, (q31_t)0x9B93A640, (q31_t)0x4F5E08E3, + (q31_t)0x9B556F80, (q31_t)0x4F0F1126, (q31_t)0x9B1776D9, + (q31_t)0x4EBFE8A4, (q31_t)0x9AD9BC71, (q31_t)0x4E708F8F, + (q31_t)0x9A9C406D, (q31_t)0x4E210617, (q31_t)0x9A5F02F5, + (q31_t)0x4DD14C6E, (q31_t)0x9A22042C, (q31_t)0x4D8162C4, + (q31_t)0x99E5443A, (q31_t)0x4D31494B, (q31_t)0x99A8C344, + (q31_t)0x4CE10034, (q31_t)0x996C816F, (q31_t)0x4C9087B1, + (q31_t)0x99307EE0, (q31_t)0x4C3FDFF3, (q31_t)0x98F4BBBC, + (q31_t)0x4BEF092D, (q31_t)0x98B93828, (q31_t)0x4B9E038F, + (q31_t)0x987DF449, (q31_t)0x4B4CCF4D, (q31_t)0x9842F043, + (q31_t)0x4AFB6C97, (q31_t)0x98082C3B, (q31_t)0x4AA9DBA1, + (q31_t)0x97CDA855, (q31_t)0x4A581C9D, (q31_t)0x979364B5, + (q31_t)0x4A062FBD, (q31_t)0x9759617E, (q31_t)0x49B41533, + (q31_t)0x971F9ED6, (q31_t)0x4961CD32, (q31_t)0x96E61CDF, + (q31_t)0x490F57EE, (q31_t)0x96ACDBBD, (q31_t)0x48BCB598, + (q31_t)0x9673DB94, (q31_t)0x4869E664, (q31_t)0x963B1C85, + (q31_t)0x4816EA85, (q31_t)0x96029EB5, (q31_t)0x47C3C22E, + (q31_t)0x95CA6246, (q31_t)0x47706D93, (q31_t)0x9592675B, + (q31_t)0x471CECE6, (q31_t)0x955AAE17, (q31_t)0x46C9405C, + (q31_t)0x9523369B, (q31_t)0x46756827, (q31_t)0x94EC010B, + (q31_t)0x4621647C, (q31_t)0x94B50D87, (q31_t)0x45CD358F, + (q31_t)0x947E5C32, (q31_t)0x4578DB93, (q31_t)0x9447ED2F, + (q31_t)0x452456BC, (q31_t)0x9411C09D, (q31_t)0x44CFA73F, + (q31_t)0x93DBD69F, (q31_t)0x447ACD50, (q31_t)0x93A62F56, + (q31_t)0x4425C923, (q31_t)0x9370CAE4, (q31_t)0x43D09AEC, + (q31_t)0x933BA968, (q31_t)0x437B42E1, (q31_t)0x9306CB04, + (q31_t)0x4325C135, (q31_t)0x92D22FD8, (q31_t)0x42D0161E, + (q31_t)0x929DD805, (q31_t)0x427A41D0, (q31_t)0x9269C3AC, + (q31_t)0x42244480, (q31_t)0x9235F2EB, (q31_t)0x41CE1E64, + (q31_t)0x920265E4, (q31_t)0x4177CFB0, (q31_t)0x91CF1CB6, + (q31_t)0x4121589A, (q31_t)0x919C1780, (q31_t)0x40CAB957, + (q31_t)0x91695663, (q31_t)0x4073F21D, (q31_t)0x9136D97D, + (q31_t)0x401D0320, (q31_t)0x9104A0ED, (q31_t)0x3FC5EC97, + (q31_t)0x90D2ACD3, (q31_t)0x3F6EAEB8, (q31_t)0x90A0FD4E, + (q31_t)0x3F1749B7, (q31_t)0x906F927B, (q31_t)0x3EBFBDCC, + (q31_t)0x903E6C7A, (q31_t)0x3E680B2C, (q31_t)0x900D8B69, + (q31_t)0x3E10320D, (q31_t)0x8FDCEF66, (q31_t)0x3DB832A5, + (q31_t)0x8FAC988E, (q31_t)0x3D600D2B, (q31_t)0x8F7C8701, + (q31_t)0x3D07C1D5, (q31_t)0x8F4CBADB, (q31_t)0x3CAF50DA, + (q31_t)0x8F1D343A, (q31_t)0x3C56BA70, (q31_t)0x8EEDF33B, + (q31_t)0x3BFDFECD, (q31_t)0x8EBEF7FB, (q31_t)0x3BA51E29, + (q31_t)0x8E904298, (q31_t)0x3B4C18BA, (q31_t)0x8E61D32D, + (q31_t)0x3AF2EEB7, (q31_t)0x8E33A9D9, (q31_t)0x3A99A057, + (q31_t)0x8E05C6B7, (q31_t)0x3A402DD1, (q31_t)0x8DD829E4, + (q31_t)0x39E6975D, (q31_t)0x8DAAD37B, (q31_t)0x398CDD32, + (q31_t)0x8D7DC399, (q31_t)0x3932FF87, (q31_t)0x8D50FA59, + (q31_t)0x38D8FE93, (q31_t)0x8D2477D8, (q31_t)0x387EDA8E, + (q31_t)0x8CF83C30, (q31_t)0x382493B0, (q31_t)0x8CCC477D, + (q31_t)0x37CA2A30, (q31_t)0x8CA099D9, (q31_t)0x376F9E46, + (q31_t)0x8C753361, (q31_t)0x3714F02A, (q31_t)0x8C4A142F, + (q31_t)0x36BA2013, (q31_t)0x8C1F3C5C, (q31_t)0x365F2E3B, + (q31_t)0x8BF4AC05, (q31_t)0x36041AD9, (q31_t)0x8BCA6342, + (q31_t)0x35A8E624, (q31_t)0x8BA0622F, (q31_t)0x354D9056, + (q31_t)0x8B76A8E4, (q31_t)0x34F219A7, (q31_t)0x8B4D377C, + (q31_t)0x3496824F, (q31_t)0x8B240E10, (q31_t)0x343ACA87, + (q31_t)0x8AFB2CBA, (q31_t)0x33DEF287, (q31_t)0x8AD29393, + (q31_t)0x3382FA88, (q31_t)0x8AAA42B4, (q31_t)0x3326E2C2, + (q31_t)0x8A823A35, (q31_t)0x32CAAB6F, (q31_t)0x8A5A7A30, + (q31_t)0x326E54C7, (q31_t)0x8A3302BD, (q31_t)0x3211DF03, + (q31_t)0x8A0BD3F5, (q31_t)0x31B54A5D, (q31_t)0x89E4EDEE, + (q31_t)0x3158970D, (q31_t)0x89BE50C3, (q31_t)0x30FBC54D, + (q31_t)0x8997FC89, (q31_t)0x309ED555, (q31_t)0x8971F15A, + (q31_t)0x3041C760, (q31_t)0x894C2F4C, (q31_t)0x2FE49BA6, + (q31_t)0x8926B677, (q31_t)0x2F875262, (q31_t)0x890186F1, + (q31_t)0x2F29EBCC, (q31_t)0x88DCA0D3, (q31_t)0x2ECC681E, + (q31_t)0x88B80431, (q31_t)0x2E6EC792, (q31_t)0x8893B124, + (q31_t)0x2E110A62, (q31_t)0x886FA7C2, (q31_t)0x2DB330C7, + (q31_t)0x884BE820, (q31_t)0x2D553AFB, (q31_t)0x88287255, + (q31_t)0x2CF72939, (q31_t)0x88054677, (q31_t)0x2C98FBBA, + (q31_t)0x87E2649B, (q31_t)0x2C3AB2B9, (q31_t)0x87BFCCD7, + (q31_t)0x2BDC4E6F, (q31_t)0x879D7F40, (q31_t)0x2B7DCF17, + (q31_t)0x877B7BEC, (q31_t)0x2B1F34EB, (q31_t)0x8759C2EF, + (q31_t)0x2AC08025, (q31_t)0x8738545E, (q31_t)0x2A61B101, + (q31_t)0x8717304E, (q31_t)0x2A02C7B8, (q31_t)0x86F656D3, + (q31_t)0x29A3C484, (q31_t)0x86D5C802, (q31_t)0x2944A7A2, + (q31_t)0x86B583EE, (q31_t)0x28E5714A, (q31_t)0x86958AAB, + (q31_t)0x288621B9, (q31_t)0x8675DC4E, (q31_t)0x2826B928, + (q31_t)0x865678EA, (q31_t)0x27C737D2, (q31_t)0x86376092, + (q31_t)0x27679DF4, (q31_t)0x86189359, (q31_t)0x2707EBC6, + (q31_t)0x85FA1152, (q31_t)0x26A82185, (q31_t)0x85DBDA91, + (q31_t)0x26483F6C, (q31_t)0x85BDEF27, (q31_t)0x25E845B5, + (q31_t)0x85A04F28, (q31_t)0x2588349D, (q31_t)0x8582FAA4, + (q31_t)0x25280C5D, (q31_t)0x8565F1B0, (q31_t)0x24C7CD32, + (q31_t)0x8549345C, (q31_t)0x24677757, (q31_t)0x852CC2BA, + (q31_t)0x24070B07, (q31_t)0x85109CDC, (q31_t)0x23A6887E, + (q31_t)0x84F4C2D3, (q31_t)0x2345EFF7, (q31_t)0x84D934B0, + (q31_t)0x22E541AE, (q31_t)0x84BDF285, (q31_t)0x22847DDF, + (q31_t)0x84A2FC62, (q31_t)0x2223A4C5, (q31_t)0x84885257, + (q31_t)0x21C2B69C, (q31_t)0x846DF476, (q31_t)0x2161B39F, + (q31_t)0x8453E2CE, (q31_t)0x21009C0B, (q31_t)0x843A1D70, + (q31_t)0x209F701C, (q31_t)0x8420A46B, (q31_t)0x203E300D, + (q31_t)0x840777CF, (q31_t)0x1FDCDC1A, (q31_t)0x83EE97AC, + (q31_t)0x1F7B7480, (q31_t)0x83D60411, (q31_t)0x1F19F97B, + (q31_t)0x83BDBD0D, (q31_t)0x1EB86B46, (q31_t)0x83A5C2B0, + (q31_t)0x1E56CA1E, (q31_t)0x838E1507, (q31_t)0x1DF5163F, + (q31_t)0x8376B422, (q31_t)0x1D934FE5, (q31_t)0x835FA00E, + (q31_t)0x1D31774D, (q31_t)0x8348D8DB, (q31_t)0x1CCF8CB3, + (q31_t)0x83325E97, (q31_t)0x1C6D9053, (q31_t)0x831C314E, + (q31_t)0x1C0B826A, (q31_t)0x8306510F, (q31_t)0x1BA96334, + (q31_t)0x82F0BDE8, (q31_t)0x1B4732EF, (q31_t)0x82DB77E5, + (q31_t)0x1AE4F1D6, (q31_t)0x82C67F13, (q31_t)0x1A82A025, + (q31_t)0x82B1D381, (q31_t)0x1A203E1B, (q31_t)0x829D753A, + (q31_t)0x19BDCBF2, (q31_t)0x8289644A, (q31_t)0x195B49E9, + (q31_t)0x8275A0C0, (q31_t)0x18F8B83C, (q31_t)0x82622AA5, + (q31_t)0x18961727, (q31_t)0x824F0208, (q31_t)0x183366E8, + (q31_t)0x823C26F2, (q31_t)0x17D0A7BB, (q31_t)0x82299971, + (q31_t)0x176DD9DE, (q31_t)0x8217598F, (q31_t)0x170AFD8D, + (q31_t)0x82056758, (q31_t)0x16A81305, (q31_t)0x81F3C2D7, + (q31_t)0x16451A83, (q31_t)0x81E26C16, (q31_t)0x15E21444, + (q31_t)0x81D16320, (q31_t)0x157F0086, (q31_t)0x81C0A801, + (q31_t)0x151BDF85, (q31_t)0x81B03AC1, (q31_t)0x14B8B17F, + (q31_t)0x81A01B6C, (q31_t)0x145576B1, (q31_t)0x81904A0C, + (q31_t)0x13F22F57, (q31_t)0x8180C6A9, (q31_t)0x138EDBB0, + (q31_t)0x8171914E, (q31_t)0x132B7BF9, (q31_t)0x8162AA03, + (q31_t)0x12C8106E, (q31_t)0x815410D3, (q31_t)0x1264994E, + (q31_t)0x8145C5C6, (q31_t)0x120116D4, (q31_t)0x8137C8E6, + (q31_t)0x119D8940, (q31_t)0x812A1A39, (q31_t)0x1139F0CE, + (q31_t)0x811CB9CA, (q31_t)0x10D64DBC, (q31_t)0x810FA7A0, + (q31_t)0x1072A047, (q31_t)0x8102E3C3, (q31_t)0x100EE8AD, + (q31_t)0x80F66E3C, (q31_t)0x0FAB272B, (q31_t)0x80EA4712, + (q31_t)0x0F475BFE, (q31_t)0x80DE6E4C, (q31_t)0x0EE38765, + (q31_t)0x80D2E3F1, (q31_t)0x0E7FA99D, (q31_t)0x80C7A80A, + (q31_t)0x0E1BC2E3, (q31_t)0x80BCBA9C, (q31_t)0x0DB7D376, + (q31_t)0x80B21BAF, (q31_t)0x0D53DB92, (q31_t)0x80A7CB49, + (q31_t)0x0CEFDB75, (q31_t)0x809DC970, (q31_t)0x0C8BD35E, + (q31_t)0x8094162B, (q31_t)0x0C27C389, (q31_t)0x808AB180, + (q31_t)0x0BC3AC35, (q31_t)0x80819B74, (q31_t)0x0B5F8D9F, + (q31_t)0x8078D40D, (q31_t)0x0AFB6805, (q31_t)0x80705B50, + (q31_t)0x0A973BA5, (q31_t)0x80683143, (q31_t)0x0A3308BC, + (q31_t)0x806055EA, (q31_t)0x09CECF89, (q31_t)0x8058C94C, + (q31_t)0x096A9049, (q31_t)0x80518B6B, (q31_t)0x09064B3A, + (q31_t)0x804A9C4D, (q31_t)0x08A2009A, (q31_t)0x8043FBF6, + (q31_t)0x083DB0A7, (q31_t)0x803DAA69, (q31_t)0x07D95B9E, + (q31_t)0x8037A7AC, (q31_t)0x077501BE, (q31_t)0x8031F3C1, + (q31_t)0x0710A344, (q31_t)0x802C8EAD, (q31_t)0x06AC406F, + (q31_t)0x80277872, (q31_t)0x0647D97C, (q31_t)0x8022B113, + (q31_t)0x05E36EA9, (q31_t)0x801E3894, (q31_t)0x057F0034, + (q31_t)0x801A0EF7, (q31_t)0x051A8E5C, (q31_t)0x80163440, + (q31_t)0x04B6195D, (q31_t)0x8012A86F, (q31_t)0x0451A176, + (q31_t)0x800F6B88, (q31_t)0x03ED26E6, (q31_t)0x800C7D8C, + (q31_t)0x0388A9E9, (q31_t)0x8009DE7D, (q31_t)0x03242ABF, + (q31_t)0x80078E5E, (q31_t)0x02BFA9A4, (q31_t)0x80058D2E, + (q31_t)0x025B26D7, (q31_t)0x8003DAF0, (q31_t)0x01F6A296, + (q31_t)0x800277A5, (q31_t)0x01921D1F, (q31_t)0x8001634D, + (q31_t)0x012D96B0, (q31_t)0x80009DE9, (q31_t)0x00C90F88, + (q31_t)0x8000277A, (q31_t)0x006487E3, (q31_t)0x80000000, + (q31_t)0x00000000, (q31_t)0x8000277A, (q31_t)0xFF9B781D, + (q31_t)0x80009DE9, (q31_t)0xFF36F078, (q31_t)0x8001634D, + (q31_t)0xFED2694F, (q31_t)0x800277A5, (q31_t)0xFE6DE2E0, + (q31_t)0x8003DAF0, (q31_t)0xFE095D69, (q31_t)0x80058D2E, + (q31_t)0xFDA4D928, (q31_t)0x80078E5E, (q31_t)0xFD40565B, + (q31_t)0x8009DE7D, (q31_t)0xFCDBD541, (q31_t)0x800C7D8C, + (q31_t)0xFC775616, (q31_t)0x800F6B88, (q31_t)0xFC12D919, + (q31_t)0x8012A86F, (q31_t)0xFBAE5E89, (q31_t)0x80163440, + (q31_t)0xFB49E6A2, (q31_t)0x801A0EF7, (q31_t)0xFAE571A4, + (q31_t)0x801E3894, (q31_t)0xFA80FFCB, (q31_t)0x8022B113, + (q31_t)0xFA1C9156, (q31_t)0x80277872, (q31_t)0xF9B82683, + (q31_t)0x802C8EAD, (q31_t)0xF953BF90, (q31_t)0x8031F3C1, + (q31_t)0xF8EF5CBB, (q31_t)0x8037A7AC, (q31_t)0xF88AFE41, + (q31_t)0x803DAA69, (q31_t)0xF826A461, (q31_t)0x8043FBF6, + (q31_t)0xF7C24F58, (q31_t)0x804A9C4D, (q31_t)0xF75DFF65, + (q31_t)0x80518B6B, (q31_t)0xF6F9B4C5, (q31_t)0x8058C94C, + (q31_t)0xF6956FB6, (q31_t)0x806055EA, (q31_t)0xF6313076, + (q31_t)0x80683143, (q31_t)0xF5CCF743, (q31_t)0x80705B50, + (q31_t)0xF568C45A, (q31_t)0x8078D40D, (q31_t)0xF50497FA, + (q31_t)0x80819B74, (q31_t)0xF4A07260, (q31_t)0x808AB180, + (q31_t)0xF43C53CA, (q31_t)0x8094162B, (q31_t)0xF3D83C76, + (q31_t)0x809DC970, (q31_t)0xF3742CA1, (q31_t)0x80A7CB49, + (q31_t)0xF310248A, (q31_t)0x80B21BAF, (q31_t)0xF2AC246D, + (q31_t)0x80BCBA9C, (q31_t)0xF2482C89, (q31_t)0x80C7A80A, + (q31_t)0xF1E43D1C, (q31_t)0x80D2E3F1, (q31_t)0xF1805662, + (q31_t)0x80DE6E4C, (q31_t)0xF11C789A, (q31_t)0x80EA4712, + (q31_t)0xF0B8A401, (q31_t)0x80F66E3C, (q31_t)0xF054D8D4, + (q31_t)0x8102E3C3, (q31_t)0xEFF11752, (q31_t)0x810FA7A0, + (q31_t)0xEF8D5FB8, (q31_t)0x811CB9CA, (q31_t)0xEF29B243, + (q31_t)0x812A1A39, (q31_t)0xEEC60F31, (q31_t)0x8137C8E6, + (q31_t)0xEE6276BF, (q31_t)0x8145C5C6, (q31_t)0xEDFEE92B, + (q31_t)0x815410D3, (q31_t)0xED9B66B2, (q31_t)0x8162AA03, + (q31_t)0xED37EF91, (q31_t)0x8171914E, (q31_t)0xECD48406, + (q31_t)0x8180C6A9, (q31_t)0xEC71244F, (q31_t)0x81904A0C, + (q31_t)0xEC0DD0A8, (q31_t)0x81A01B6C, (q31_t)0xEBAA894E, + (q31_t)0x81B03AC1, (q31_t)0xEB474E80, (q31_t)0x81C0A801, + (q31_t)0xEAE4207A, (q31_t)0x81D16320, (q31_t)0xEA80FF79, + (q31_t)0x81E26C16, (q31_t)0xEA1DEBBB, (q31_t)0x81F3C2D7, + (q31_t)0xE9BAE57C, (q31_t)0x82056758, (q31_t)0xE957ECFB, + (q31_t)0x8217598F, (q31_t)0xE8F50273, (q31_t)0x82299971, + (q31_t)0xE8922621, (q31_t)0x823C26F2, (q31_t)0xE82F5844, + (q31_t)0x824F0208, (q31_t)0xE7CC9917, (q31_t)0x82622AA5, + (q31_t)0xE769E8D8, (q31_t)0x8275A0C0, (q31_t)0xE70747C3, + (q31_t)0x8289644A, (q31_t)0xE6A4B616, (q31_t)0x829D753A, + (q31_t)0xE642340D, (q31_t)0x82B1D381, (q31_t)0xE5DFC1E4, + (q31_t)0x82C67F13, (q31_t)0xE57D5FDA, (q31_t)0x82DB77E5, + (q31_t)0xE51B0E2A, (q31_t)0x82F0BDE8, (q31_t)0xE4B8CD10, + (q31_t)0x8306510F, (q31_t)0xE4569CCB, (q31_t)0x831C314E, + (q31_t)0xE3F47D95, (q31_t)0x83325E97, (q31_t)0xE3926FAC, + (q31_t)0x8348D8DB, (q31_t)0xE330734C, (q31_t)0x835FA00E, + (q31_t)0xE2CE88B2, (q31_t)0x8376B422, (q31_t)0xE26CB01A, + (q31_t)0x838E1507, (q31_t)0xE20AE9C1, (q31_t)0x83A5C2B0, + (q31_t)0xE1A935E1, (q31_t)0x83BDBD0D, (q31_t)0xE14794B9, + (q31_t)0x83D60411, (q31_t)0xE0E60684, (q31_t)0x83EE97AC, + (q31_t)0xE0848B7F, (q31_t)0x840777CF, (q31_t)0xE02323E5, + (q31_t)0x8420A46B, (q31_t)0xDFC1CFF2, (q31_t)0x843A1D70, + (q31_t)0xDF608FE3, (q31_t)0x8453E2CE, (q31_t)0xDEFF63F4, + (q31_t)0x846DF476, (q31_t)0xDE9E4C60, (q31_t)0x84885257, + (q31_t)0xDE3D4963, (q31_t)0x84A2FC62, (q31_t)0xDDDC5B3A, + (q31_t)0x84BDF285, (q31_t)0xDD7B8220, (q31_t)0x84D934B0, + (q31_t)0xDD1ABE51, (q31_t)0x84F4C2D3, (q31_t)0xDCBA1008, + (q31_t)0x85109CDC, (q31_t)0xDC597781, (q31_t)0x852CC2BA, + (q31_t)0xDBF8F4F8, (q31_t)0x8549345C, (q31_t)0xDB9888A8, + (q31_t)0x8565F1B0, (q31_t)0xDB3832CD, (q31_t)0x8582FAA4, + (q31_t)0xDAD7F3A2, (q31_t)0x85A04F28, (q31_t)0xDA77CB62, + (q31_t)0x85BDEF27, (q31_t)0xDA17BA4A, (q31_t)0x85DBDA91, + (q31_t)0xD9B7C093, (q31_t)0x85FA1152, (q31_t)0xD957DE7A, + (q31_t)0x86189359, (q31_t)0xD8F81439, (q31_t)0x86376092, + (q31_t)0xD898620C, (q31_t)0x865678EA, (q31_t)0xD838C82D, + (q31_t)0x8675DC4E, (q31_t)0xD7D946D7, (q31_t)0x86958AAB, + (q31_t)0xD779DE46, (q31_t)0x86B583EE, (q31_t)0xD71A8EB5, + (q31_t)0x86D5C802, (q31_t)0xD6BB585D, (q31_t)0x86F656D3, + (q31_t)0xD65C3B7B, (q31_t)0x8717304E, (q31_t)0xD5FD3847, + (q31_t)0x8738545E, (q31_t)0xD59E4EFE, (q31_t)0x8759C2EF, + (q31_t)0xD53F7FDA, (q31_t)0x877B7BEC, (q31_t)0xD4E0CB14, + (q31_t)0x879D7F40, (q31_t)0xD48230E8, (q31_t)0x87BFCCD7, + (q31_t)0xD423B190, (q31_t)0x87E2649B, (q31_t)0xD3C54D46, + (q31_t)0x88054677, (q31_t)0xD3670445, (q31_t)0x88287255, + (q31_t)0xD308D6C6, (q31_t)0x884BE820, (q31_t)0xD2AAC504, + (q31_t)0x886FA7C2, (q31_t)0xD24CCF38, (q31_t)0x8893B124, + (q31_t)0xD1EEF59E, (q31_t)0x88B80431, (q31_t)0xD191386D, + (q31_t)0x88DCA0D3, (q31_t)0xD13397E1, (q31_t)0x890186F1, + (q31_t)0xD0D61433, (q31_t)0x8926B677, (q31_t)0xD078AD9D, + (q31_t)0x894C2F4C, (q31_t)0xD01B6459, (q31_t)0x8971F15A, + (q31_t)0xCFBE389F, (q31_t)0x8997FC89, (q31_t)0xCF612AAA, + (q31_t)0x89BE50C3, (q31_t)0xCF043AB2, (q31_t)0x89E4EDEE, + (q31_t)0xCEA768F2, (q31_t)0x8A0BD3F5, (q31_t)0xCE4AB5A2, + (q31_t)0x8A3302BD, (q31_t)0xCDEE20FC, (q31_t)0x8A5A7A30, + (q31_t)0xCD91AB38, (q31_t)0x8A823A35, (q31_t)0xCD355490, + (q31_t)0x8AAA42B4, (q31_t)0xCCD91D3D, (q31_t)0x8AD29393, + (q31_t)0xCC7D0577, (q31_t)0x8AFB2CBA, (q31_t)0xCC210D78, + (q31_t)0x8B240E10, (q31_t)0xCBC53578, (q31_t)0x8B4D377C, + (q31_t)0xCB697DB0, (q31_t)0x8B76A8E4, (q31_t)0xCB0DE658, + (q31_t)0x8BA0622F, (q31_t)0xCAB26FA9, (q31_t)0x8BCA6342, + (q31_t)0xCA5719DB, (q31_t)0x8BF4AC05, (q31_t)0xC9FBE527, + (q31_t)0x8C1F3C5C, (q31_t)0xC9A0D1C4, (q31_t)0x8C4A142F, + (q31_t)0xC945DFEC, (q31_t)0x8C753361, (q31_t)0xC8EB0FD6, + (q31_t)0x8CA099D9, (q31_t)0xC89061BA, (q31_t)0x8CCC477D, + (q31_t)0xC835D5D0, (q31_t)0x8CF83C30, (q31_t)0xC7DB6C50, + (q31_t)0x8D2477D8, (q31_t)0xC7812571, (q31_t)0x8D50FA59, + (q31_t)0xC727016C, (q31_t)0x8D7DC399, (q31_t)0xC6CD0079, + (q31_t)0x8DAAD37B, (q31_t)0xC67322CD, (q31_t)0x8DD829E4, + (q31_t)0xC61968A2, (q31_t)0x8E05C6B7, (q31_t)0xC5BFD22E, + (q31_t)0x8E33A9D9, (q31_t)0xC5665FA8, (q31_t)0x8E61D32D, + (q31_t)0xC50D1148, (q31_t)0x8E904298, (q31_t)0xC4B3E746, + (q31_t)0x8EBEF7FB, (q31_t)0xC45AE1D7, (q31_t)0x8EEDF33B, + (q31_t)0xC4020132, (q31_t)0x8F1D343A, (q31_t)0xC3A9458F, + (q31_t)0x8F4CBADB, (q31_t)0xC350AF25, (q31_t)0x8F7C8701, + (q31_t)0xC2F83E2A, (q31_t)0x8FAC988E, (q31_t)0xC29FF2D4, + (q31_t)0x8FDCEF66, (q31_t)0xC247CD5A, (q31_t)0x900D8B69, + (q31_t)0xC1EFCDF2, (q31_t)0x903E6C7A, (q31_t)0xC197F4D3, + (q31_t)0x906F927B, (q31_t)0xC1404233, (q31_t)0x90A0FD4E, + (q31_t)0xC0E8B648, (q31_t)0x90D2ACD3, (q31_t)0xC0915147, + (q31_t)0x9104A0ED, (q31_t)0xC03A1368, (q31_t)0x9136D97D, + (q31_t)0xBFE2FCDF, (q31_t)0x91695663, (q31_t)0xBF8C0DE2, + (q31_t)0x919C1780, (q31_t)0xBF3546A8, (q31_t)0x91CF1CB6, + (q31_t)0xBEDEA765, (q31_t)0x920265E4, (q31_t)0xBE88304F, + (q31_t)0x9235F2EB, (q31_t)0xBE31E19B, (q31_t)0x9269C3AC, + (q31_t)0xBDDBBB7F, (q31_t)0x929DD805, (q31_t)0xBD85BE2F, + (q31_t)0x92D22FD8, (q31_t)0xBD2FE9E1, (q31_t)0x9306CB04, + (q31_t)0xBCDA3ECA, (q31_t)0x933BA968, (q31_t)0xBC84BD1E, + (q31_t)0x9370CAE4, (q31_t)0xBC2F6513, (q31_t)0x93A62F56, + (q31_t)0xBBDA36DC, (q31_t)0x93DBD69F, (q31_t)0xBB8532AF, + (q31_t)0x9411C09D, (q31_t)0xBB3058C0, (q31_t)0x9447ED2F, + (q31_t)0xBADBA943, (q31_t)0x947E5C32, (q31_t)0xBA87246C, + (q31_t)0x94B50D87, (q31_t)0xBA32CA70, (q31_t)0x94EC010B, + (q31_t)0xB9DE9B83, (q31_t)0x9523369B, (q31_t)0xB98A97D8, + (q31_t)0x955AAE17, (q31_t)0xB936BFA3, (q31_t)0x9592675B, + (q31_t)0xB8E31319, (q31_t)0x95CA6246, (q31_t)0xB88F926C, + (q31_t)0x96029EB5, (q31_t)0xB83C3DD1, (q31_t)0x963B1C85, + (q31_t)0xB7E9157A, (q31_t)0x9673DB94, (q31_t)0xB796199B, + (q31_t)0x96ACDBBD, (q31_t)0xB7434A67, (q31_t)0x96E61CDF, + (q31_t)0xB6F0A811, (q31_t)0x971F9ED6, (q31_t)0xB69E32CD, + (q31_t)0x9759617E, (q31_t)0xB64BEACC, (q31_t)0x979364B5, + (q31_t)0xB5F9D042, (q31_t)0x97CDA855, (q31_t)0xB5A7E362, + (q31_t)0x98082C3B, (q31_t)0xB556245E, (q31_t)0x9842F043, + (q31_t)0xB5049368, (q31_t)0x987DF449, (q31_t)0xB4B330B2, + (q31_t)0x98B93828, (q31_t)0xB461FC70, (q31_t)0x98F4BBBC, + (q31_t)0xB410F6D2, (q31_t)0x99307EE0, (q31_t)0xB3C0200C, + (q31_t)0x996C816F, (q31_t)0xB36F784E, (q31_t)0x99A8C344, + (q31_t)0xB31EFFCB, (q31_t)0x99E5443A, (q31_t)0xB2CEB6B5, + (q31_t)0x9A22042C, (q31_t)0xB27E9D3B, (q31_t)0x9A5F02F5, + (q31_t)0xB22EB392, (q31_t)0x9A9C406D, (q31_t)0xB1DEF9E8, + (q31_t)0x9AD9BC71, (q31_t)0xB18F7070, (q31_t)0x9B1776D9, + (q31_t)0xB140175B, (q31_t)0x9B556F80, (q31_t)0xB0F0EEDA, + (q31_t)0x9B93A640, (q31_t)0xB0A1F71C, (q31_t)0x9BD21AF2, + (q31_t)0xB0533055, (q31_t)0x9C10CD70, (q31_t)0xB0049AB2, + (q31_t)0x9C4FBD92, (q31_t)0xAFB63667, (q31_t)0x9C8EEB33, + (q31_t)0xAF6803A1, (q31_t)0x9CCE562B, (q31_t)0xAF1A0293, + (q31_t)0x9D0DFE53, (q31_t)0xAECC336B, (q31_t)0x9D4DE384, + (q31_t)0xAE7E965B, (q31_t)0x9D8E0596, (q31_t)0xAE312B91, + (q31_t)0x9DCE6462, (q31_t)0xADE3F33E, (q31_t)0x9E0EFFC1, + (q31_t)0xAD96ED91, (q31_t)0x9E4FD789, (q31_t)0xAD4A1ABA, + (q31_t)0x9E90EB94, (q31_t)0xACFD7AE8, (q31_t)0x9ED23BB9, + (q31_t)0xACB10E4A, (q31_t)0x9F13C7D0, (q31_t)0xAC64D510, + (q31_t)0x9F558FB0, (q31_t)0xAC18CF68, (q31_t)0x9F979331, + (q31_t)0xABCCFD82, (q31_t)0x9FD9D22A, (q31_t)0xAB815F8C, + (q31_t)0xA01C4C72, (q31_t)0xAB35F5B5, (q31_t)0xA05F01E1, + (q31_t)0xAAEAC02B, (q31_t)0xA0A1F24C, (q31_t)0xAA9FBF1D, + (q31_t)0xA0E51D8C, (q31_t)0xAA54F2B9, (q31_t)0xA1288376, + (q31_t)0xAA0A5B2D, (q31_t)0xA16C23E1, (q31_t)0xA9BFF8A8, + (q31_t)0xA1AFFEA2, (q31_t)0xA975CB56, (q31_t)0xA1F41391, + (q31_t)0xA92BD366, (q31_t)0xA2386283, (q31_t)0xA8E21106, + (q31_t)0xA27CEB4F, (q31_t)0xA8988463, (q31_t)0xA2C1ADC9, + (q31_t)0xA84F2DA9, (q31_t)0xA306A9C7, (q31_t)0xA8060D08, + (q31_t)0xA34BDF20, (q31_t)0xA7BD22AB, (q31_t)0xA3914DA7, + (q31_t)0xA7746EC0, (q31_t)0xA3D6F533, (q31_t)0xA72BF173, + (q31_t)0xA41CD598, (q31_t)0xA6E3AAF2, (q31_t)0xA462EEAC, + (q31_t)0xA69B9B68, (q31_t)0xA4A94042, (q31_t)0xA653C302, + (q31_t)0xA4EFCA31, (q31_t)0xA60C21ED, (q31_t)0xA5368C4B, + (q31_t)0xA5C4B855, (q31_t)0xA57D8666, (q31_t)0xA57D8666, + (q31_t)0xA5C4B855, (q31_t)0xA5368C4B, (q31_t)0xA60C21ED, + (q31_t)0xA4EFCA31, (q31_t)0xA653C302, (q31_t)0xA4A94042, + (q31_t)0xA69B9B68, (q31_t)0xA462EEAC, (q31_t)0xA6E3AAF2, + (q31_t)0xA41CD598, (q31_t)0xA72BF173, (q31_t)0xA3D6F533, + (q31_t)0xA7746EC0, (q31_t)0xA3914DA7, (q31_t)0xA7BD22AB, + (q31_t)0xA34BDF20, (q31_t)0xA8060D08, (q31_t)0xA306A9C7, + (q31_t)0xA84F2DA9, (q31_t)0xA2C1ADC9, (q31_t)0xA8988463, + (q31_t)0xA27CEB4F, (q31_t)0xA8E21106, (q31_t)0xA2386283, + (q31_t)0xA92BD366, (q31_t)0xA1F41391, (q31_t)0xA975CB56, + (q31_t)0xA1AFFEA2, (q31_t)0xA9BFF8A8, (q31_t)0xA16C23E1, + (q31_t)0xAA0A5B2D, (q31_t)0xA1288376, (q31_t)0xAA54F2B9, + (q31_t)0xA0E51D8C, (q31_t)0xAA9FBF1D, (q31_t)0xA0A1F24C, + (q31_t)0xAAEAC02B, (q31_t)0xA05F01E1, (q31_t)0xAB35F5B5, + (q31_t)0xA01C4C72, (q31_t)0xAB815F8C, (q31_t)0x9FD9D22A, + (q31_t)0xABCCFD82, (q31_t)0x9F979331, (q31_t)0xAC18CF68, + (q31_t)0x9F558FB0, (q31_t)0xAC64D510, (q31_t)0x9F13C7D0, + (q31_t)0xACB10E4A, (q31_t)0x9ED23BB9, (q31_t)0xACFD7AE8, + (q31_t)0x9E90EB94, (q31_t)0xAD4A1ABA, (q31_t)0x9E4FD789, + (q31_t)0xAD96ED91, (q31_t)0x9E0EFFC1, (q31_t)0xADE3F33E, + (q31_t)0x9DCE6462, (q31_t)0xAE312B91, (q31_t)0x9D8E0596, + (q31_t)0xAE7E965B, (q31_t)0x9D4DE384, (q31_t)0xAECC336B, + (q31_t)0x9D0DFE53, (q31_t)0xAF1A0293, (q31_t)0x9CCE562B, + (q31_t)0xAF6803A1, (q31_t)0x9C8EEB33, (q31_t)0xAFB63667, + (q31_t)0x9C4FBD92, (q31_t)0xB0049AB2, (q31_t)0x9C10CD70, + (q31_t)0xB0533055, (q31_t)0x9BD21AF2, (q31_t)0xB0A1F71C, + (q31_t)0x9B93A640, (q31_t)0xB0F0EEDA, (q31_t)0x9B556F80, + (q31_t)0xB140175B, (q31_t)0x9B1776D9, (q31_t)0xB18F7070, + (q31_t)0x9AD9BC71, (q31_t)0xB1DEF9E8, (q31_t)0x9A9C406D, + (q31_t)0xB22EB392, (q31_t)0x9A5F02F5, (q31_t)0xB27E9D3B, + (q31_t)0x9A22042C, (q31_t)0xB2CEB6B5, (q31_t)0x99E5443A, + (q31_t)0xB31EFFCB, (q31_t)0x99A8C344, (q31_t)0xB36F784E, + (q31_t)0x996C816F, (q31_t)0xB3C0200C, (q31_t)0x99307EE0, + (q31_t)0xB410F6D2, (q31_t)0x98F4BBBC, (q31_t)0xB461FC70, + (q31_t)0x98B93828, (q31_t)0xB4B330B2, (q31_t)0x987DF449, + (q31_t)0xB5049368, (q31_t)0x9842F043, (q31_t)0xB556245E, + (q31_t)0x98082C3B, (q31_t)0xB5A7E362, (q31_t)0x97CDA855, + (q31_t)0xB5F9D042, (q31_t)0x979364B5, (q31_t)0xB64BEACC, + (q31_t)0x9759617E, (q31_t)0xB69E32CD, (q31_t)0x971F9ED6, + (q31_t)0xB6F0A811, (q31_t)0x96E61CDF, (q31_t)0xB7434A67, + (q31_t)0x96ACDBBD, (q31_t)0xB796199B, (q31_t)0x9673DB94, + (q31_t)0xB7E9157A, (q31_t)0x963B1C85, (q31_t)0xB83C3DD1, + (q31_t)0x96029EB5, (q31_t)0xB88F926C, (q31_t)0x95CA6246, + (q31_t)0xB8E31319, (q31_t)0x9592675B, (q31_t)0xB936BFA3, + (q31_t)0x955AAE17, (q31_t)0xB98A97D8, (q31_t)0x9523369B, + (q31_t)0xB9DE9B83, (q31_t)0x94EC010B, (q31_t)0xBA32CA70, + (q31_t)0x94B50D87, (q31_t)0xBA87246C, (q31_t)0x947E5C32, + (q31_t)0xBADBA943, (q31_t)0x9447ED2F, (q31_t)0xBB3058C0, + (q31_t)0x9411C09D, (q31_t)0xBB8532AF, (q31_t)0x93DBD69F, + (q31_t)0xBBDA36DC, (q31_t)0x93A62F56, (q31_t)0xBC2F6513, + (q31_t)0x9370CAE4, (q31_t)0xBC84BD1E, (q31_t)0x933BA968, + (q31_t)0xBCDA3ECA, (q31_t)0x9306CB04, (q31_t)0xBD2FE9E1, + (q31_t)0x92D22FD8, (q31_t)0xBD85BE2F, (q31_t)0x929DD805, + (q31_t)0xBDDBBB7F, (q31_t)0x9269C3AC, (q31_t)0xBE31E19B, + (q31_t)0x9235F2EB, (q31_t)0xBE88304F, (q31_t)0x920265E4, + (q31_t)0xBEDEA765, (q31_t)0x91CF1CB6, (q31_t)0xBF3546A8, + (q31_t)0x919C1780, (q31_t)0xBF8C0DE2, (q31_t)0x91695663, + (q31_t)0xBFE2FCDF, (q31_t)0x9136D97D, (q31_t)0xC03A1368, + (q31_t)0x9104A0ED, (q31_t)0xC0915147, (q31_t)0x90D2ACD3, + (q31_t)0xC0E8B648, (q31_t)0x90A0FD4E, (q31_t)0xC1404233, + (q31_t)0x906F927B, (q31_t)0xC197F4D3, (q31_t)0x903E6C7A, + (q31_t)0xC1EFCDF2, (q31_t)0x900D8B69, (q31_t)0xC247CD5A, + (q31_t)0x8FDCEF66, (q31_t)0xC29FF2D4, (q31_t)0x8FAC988E, + (q31_t)0xC2F83E2A, (q31_t)0x8F7C8701, (q31_t)0xC350AF25, + (q31_t)0x8F4CBADB, (q31_t)0xC3A9458F, (q31_t)0x8F1D343A, + (q31_t)0xC4020132, (q31_t)0x8EEDF33B, (q31_t)0xC45AE1D7, + (q31_t)0x8EBEF7FB, (q31_t)0xC4B3E746, (q31_t)0x8E904298, + (q31_t)0xC50D1148, (q31_t)0x8E61D32D, (q31_t)0xC5665FA8, + (q31_t)0x8E33A9D9, (q31_t)0xC5BFD22E, (q31_t)0x8E05C6B7, + (q31_t)0xC61968A2, (q31_t)0x8DD829E4, (q31_t)0xC67322CD, + (q31_t)0x8DAAD37B, (q31_t)0xC6CD0079, (q31_t)0x8D7DC399, + (q31_t)0xC727016C, (q31_t)0x8D50FA59, (q31_t)0xC7812571, + (q31_t)0x8D2477D8, (q31_t)0xC7DB6C50, (q31_t)0x8CF83C30, + (q31_t)0xC835D5D0, (q31_t)0x8CCC477D, (q31_t)0xC89061BA, + (q31_t)0x8CA099D9, (q31_t)0xC8EB0FD6, (q31_t)0x8C753361, + (q31_t)0xC945DFEC, (q31_t)0x8C4A142F, (q31_t)0xC9A0D1C4, + (q31_t)0x8C1F3C5C, (q31_t)0xC9FBE527, (q31_t)0x8BF4AC05, + (q31_t)0xCA5719DB, (q31_t)0x8BCA6342, (q31_t)0xCAB26FA9, + (q31_t)0x8BA0622F, (q31_t)0xCB0DE658, (q31_t)0x8B76A8E4, + (q31_t)0xCB697DB0, (q31_t)0x8B4D377C, (q31_t)0xCBC53578, + (q31_t)0x8B240E10, (q31_t)0xCC210D78, (q31_t)0x8AFB2CBA, + (q31_t)0xCC7D0577, (q31_t)0x8AD29393, (q31_t)0xCCD91D3D, + (q31_t)0x8AAA42B4, (q31_t)0xCD355490, (q31_t)0x8A823A35, + (q31_t)0xCD91AB38, (q31_t)0x8A5A7A30, (q31_t)0xCDEE20FC, + (q31_t)0x8A3302BD, (q31_t)0xCE4AB5A2, (q31_t)0x8A0BD3F5, + (q31_t)0xCEA768F2, (q31_t)0x89E4EDEE, (q31_t)0xCF043AB2, + (q31_t)0x89BE50C3, (q31_t)0xCF612AAA, (q31_t)0x8997FC89, + (q31_t)0xCFBE389F, (q31_t)0x8971F15A, (q31_t)0xD01B6459, + (q31_t)0x894C2F4C, (q31_t)0xD078AD9D, (q31_t)0x8926B677, + (q31_t)0xD0D61433, (q31_t)0x890186F1, (q31_t)0xD13397E1, + (q31_t)0x88DCA0D3, (q31_t)0xD191386D, (q31_t)0x88B80431, + (q31_t)0xD1EEF59E, (q31_t)0x8893B124, (q31_t)0xD24CCF38, + (q31_t)0x886FA7C2, (q31_t)0xD2AAC504, (q31_t)0x884BE820, + (q31_t)0xD308D6C6, (q31_t)0x88287255, (q31_t)0xD3670445, + (q31_t)0x88054677, (q31_t)0xD3C54D46, (q31_t)0x87E2649B, + (q31_t)0xD423B190, (q31_t)0x87BFCCD7, (q31_t)0xD48230E8, + (q31_t)0x879D7F40, (q31_t)0xD4E0CB14, (q31_t)0x877B7BEC, + (q31_t)0xD53F7FDA, (q31_t)0x8759C2EF, (q31_t)0xD59E4EFE, + (q31_t)0x8738545E, (q31_t)0xD5FD3847, (q31_t)0x8717304E, + (q31_t)0xD65C3B7B, (q31_t)0x86F656D3, (q31_t)0xD6BB585D, + (q31_t)0x86D5C802, (q31_t)0xD71A8EB5, (q31_t)0x86B583EE, + (q31_t)0xD779DE46, (q31_t)0x86958AAB, (q31_t)0xD7D946D7, + (q31_t)0x8675DC4E, (q31_t)0xD838C82D, (q31_t)0x865678EA, + (q31_t)0xD898620C, (q31_t)0x86376092, (q31_t)0xD8F81439, + (q31_t)0x86189359, (q31_t)0xD957DE7A, (q31_t)0x85FA1152, + (q31_t)0xD9B7C093, (q31_t)0x85DBDA91, (q31_t)0xDA17BA4A, + (q31_t)0x85BDEF27, (q31_t)0xDA77CB62, (q31_t)0x85A04F28, + (q31_t)0xDAD7F3A2, (q31_t)0x8582FAA4, (q31_t)0xDB3832CD, + (q31_t)0x8565F1B0, (q31_t)0xDB9888A8, (q31_t)0x8549345C, + (q31_t)0xDBF8F4F8, (q31_t)0x852CC2BA, (q31_t)0xDC597781, + (q31_t)0x85109CDC, (q31_t)0xDCBA1008, (q31_t)0x84F4C2D3, + (q31_t)0xDD1ABE51, (q31_t)0x84D934B0, (q31_t)0xDD7B8220, + (q31_t)0x84BDF285, (q31_t)0xDDDC5B3A, (q31_t)0x84A2FC62, + (q31_t)0xDE3D4963, (q31_t)0x84885257, (q31_t)0xDE9E4C60, + (q31_t)0x846DF476, (q31_t)0xDEFF63F4, (q31_t)0x8453E2CE, + (q31_t)0xDF608FE3, (q31_t)0x843A1D70, (q31_t)0xDFC1CFF2, + (q31_t)0x8420A46B, (q31_t)0xE02323E5, (q31_t)0x840777CF, + (q31_t)0xE0848B7F, (q31_t)0x83EE97AC, (q31_t)0xE0E60684, + (q31_t)0x83D60411, (q31_t)0xE14794B9, (q31_t)0x83BDBD0D, + (q31_t)0xE1A935E1, (q31_t)0x83A5C2B0, (q31_t)0xE20AE9C1, + (q31_t)0x838E1507, (q31_t)0xE26CB01A, (q31_t)0x8376B422, + (q31_t)0xE2CE88B2, (q31_t)0x835FA00E, (q31_t)0xE330734C, + (q31_t)0x8348D8DB, (q31_t)0xE3926FAC, (q31_t)0x83325E97, + (q31_t)0xE3F47D95, (q31_t)0x831C314E, (q31_t)0xE4569CCB, + (q31_t)0x8306510F, (q31_t)0xE4B8CD10, (q31_t)0x82F0BDE8, + (q31_t)0xE51B0E2A, (q31_t)0x82DB77E5, (q31_t)0xE57D5FDA, + (q31_t)0x82C67F13, (q31_t)0xE5DFC1E4, (q31_t)0x82B1D381, + (q31_t)0xE642340D, (q31_t)0x829D753A, (q31_t)0xE6A4B616, + (q31_t)0x8289644A, (q31_t)0xE70747C3, (q31_t)0x8275A0C0, + (q31_t)0xE769E8D8, (q31_t)0x82622AA5, (q31_t)0xE7CC9917, + (q31_t)0x824F0208, (q31_t)0xE82F5844, (q31_t)0x823C26F2, + (q31_t)0xE8922621, (q31_t)0x82299971, (q31_t)0xE8F50273, + (q31_t)0x8217598F, (q31_t)0xE957ECFB, (q31_t)0x82056758, + (q31_t)0xE9BAE57C, (q31_t)0x81F3C2D7, (q31_t)0xEA1DEBBB, + (q31_t)0x81E26C16, (q31_t)0xEA80FF79, (q31_t)0x81D16320, + (q31_t)0xEAE4207A, (q31_t)0x81C0A801, (q31_t)0xEB474E80, + (q31_t)0x81B03AC1, (q31_t)0xEBAA894E, (q31_t)0x81A01B6C, + (q31_t)0xEC0DD0A8, (q31_t)0x81904A0C, (q31_t)0xEC71244F, + (q31_t)0x8180C6A9, (q31_t)0xECD48406, (q31_t)0x8171914E, + (q31_t)0xED37EF91, (q31_t)0x8162AA03, (q31_t)0xED9B66B2, + (q31_t)0x815410D3, (q31_t)0xEDFEE92B, (q31_t)0x8145C5C6, + (q31_t)0xEE6276BF, (q31_t)0x8137C8E6, (q31_t)0xEEC60F31, + (q31_t)0x812A1A39, (q31_t)0xEF29B243, (q31_t)0x811CB9CA, + (q31_t)0xEF8D5FB8, (q31_t)0x810FA7A0, (q31_t)0xEFF11752, + (q31_t)0x8102E3C3, (q31_t)0xF054D8D4, (q31_t)0x80F66E3C, + (q31_t)0xF0B8A401, (q31_t)0x80EA4712, (q31_t)0xF11C789A, + (q31_t)0x80DE6E4C, (q31_t)0xF1805662, (q31_t)0x80D2E3F1, + (q31_t)0xF1E43D1C, (q31_t)0x80C7A80A, (q31_t)0xF2482C89, + (q31_t)0x80BCBA9C, (q31_t)0xF2AC246D, (q31_t)0x80B21BAF, + (q31_t)0xF310248A, (q31_t)0x80A7CB49, (q31_t)0xF3742CA1, + (q31_t)0x809DC970, (q31_t)0xF3D83C76, (q31_t)0x8094162B, + (q31_t)0xF43C53CA, (q31_t)0x808AB180, (q31_t)0xF4A07260, + (q31_t)0x80819B74, (q31_t)0xF50497FA, (q31_t)0x8078D40D, + (q31_t)0xF568C45A, (q31_t)0x80705B50, (q31_t)0xF5CCF743, + (q31_t)0x80683143, (q31_t)0xF6313076, (q31_t)0x806055EA, + (q31_t)0xF6956FB6, (q31_t)0x8058C94C, (q31_t)0xF6F9B4C5, + (q31_t)0x80518B6B, (q31_t)0xF75DFF65, (q31_t)0x804A9C4D, + (q31_t)0xF7C24F58, (q31_t)0x8043FBF6, (q31_t)0xF826A461, + (q31_t)0x803DAA69, (q31_t)0xF88AFE41, (q31_t)0x8037A7AC, + (q31_t)0xF8EF5CBB, (q31_t)0x8031F3C1, (q31_t)0xF953BF90, + (q31_t)0x802C8EAD, (q31_t)0xF9B82683, (q31_t)0x80277872, + (q31_t)0xFA1C9156, (q31_t)0x8022B113, (q31_t)0xFA80FFCB, + (q31_t)0x801E3894, (q31_t)0xFAE571A4, (q31_t)0x801A0EF7, + (q31_t)0xFB49E6A2, (q31_t)0x80163440, (q31_t)0xFBAE5E89, + (q31_t)0x8012A86F, (q31_t)0xFC12D919, (q31_t)0x800F6B88, + (q31_t)0xFC775616, (q31_t)0x800C7D8C, (q31_t)0xFCDBD541, + (q31_t)0x8009DE7D, (q31_t)0xFD40565B, (q31_t)0x80078E5E, + (q31_t)0xFDA4D928, (q31_t)0x80058D2E, (q31_t)0xFE095D69, + (q31_t)0x8003DAF0, (q31_t)0xFE6DE2E0, (q31_t)0x800277A5, + (q31_t)0xFED2694F, (q31_t)0x8001634D, (q31_t)0xFF36F078, + (q31_t)0x80009DE9, (q31_t)0xFF9B781D, (q31_t)0x8000277A +}; + +/** + @par + Example code for Q31 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefQ31[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefQ31[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 4096, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to Q31(Fixed point 1.31): + round(twiddleCoefQ31(i) * pow(2, 31)) + */ +const q31_t twiddleCoef_4096_q31[6144] = +{ + (q31_t)0x7FFFFFFF, (q31_t)0x00000000, (q31_t)0x7FFFF621, + (q31_t)0x003243F5, (q31_t)0x7FFFD885, (q31_t)0x006487E3, + (q31_t)0x7FFFA72C, (q31_t)0x0096CBC1, (q31_t)0x7FFF6216, + (q31_t)0x00C90F88, (q31_t)0x7FFF0942, (q31_t)0x00FB532F, + (q31_t)0x7FFE9CB2, (q31_t)0x012D96B0, (q31_t)0x7FFE1C64, + (q31_t)0x015FDA03, (q31_t)0x7FFD885A, (q31_t)0x01921D1F, + (q31_t)0x7FFCE093, (q31_t)0x01C45FFE, (q31_t)0x7FFC250F, + (q31_t)0x01F6A296, (q31_t)0x7FFB55CE, (q31_t)0x0228E4E1, + (q31_t)0x7FFA72D1, (q31_t)0x025B26D7, (q31_t)0x7FF97C17, + (q31_t)0x028D6870, (q31_t)0x7FF871A1, (q31_t)0x02BFA9A4, + (q31_t)0x7FF7536F, (q31_t)0x02F1EA6B, (q31_t)0x7FF62182, + (q31_t)0x03242ABF, (q31_t)0x7FF4DBD8, (q31_t)0x03566A96, + (q31_t)0x7FF38273, (q31_t)0x0388A9E9, (q31_t)0x7FF21553, + (q31_t)0x03BAE8B1, (q31_t)0x7FF09477, (q31_t)0x03ED26E6, + (q31_t)0x7FEEFFE1, (q31_t)0x041F647F, (q31_t)0x7FED5790, + (q31_t)0x0451A176, (q31_t)0x7FEB9B85, (q31_t)0x0483DDC3, + (q31_t)0x7FE9CBC0, (q31_t)0x04B6195D, (q31_t)0x7FE7E840, + (q31_t)0x04E8543D, (q31_t)0x7FE5F108, (q31_t)0x051A8E5C, + (q31_t)0x7FE3E616, (q31_t)0x054CC7B0, (q31_t)0x7FE1C76B, + (q31_t)0x057F0034, (q31_t)0x7FDF9508, (q31_t)0x05B137DF, + (q31_t)0x7FDD4EEC, (q31_t)0x05E36EA9, (q31_t)0x7FDAF518, + (q31_t)0x0615A48A, (q31_t)0x7FD8878D, (q31_t)0x0647D97C, + (q31_t)0x7FD6064B, (q31_t)0x067A0D75, (q31_t)0x7FD37152, + (q31_t)0x06AC406F, (q31_t)0x7FD0C8A3, (q31_t)0x06DE7261, + (q31_t)0x7FCE0C3E, (q31_t)0x0710A344, (q31_t)0x7FCB3C23, + (q31_t)0x0742D310, (q31_t)0x7FC85853, (q31_t)0x077501BE, + (q31_t)0x7FC560CF, (q31_t)0x07A72F45, (q31_t)0x7FC25596, + (q31_t)0x07D95B9E, (q31_t)0x7FBF36A9, (q31_t)0x080B86C1, + (q31_t)0x7FBC040A, (q31_t)0x083DB0A7, (q31_t)0x7FB8BDB7, + (q31_t)0x086FD947, (q31_t)0x7FB563B2, (q31_t)0x08A2009A, + (q31_t)0x7FB1F5FC, (q31_t)0x08D42698, (q31_t)0x7FAE7494, + (q31_t)0x09064B3A, (q31_t)0x7FAADF7C, (q31_t)0x09386E77, + (q31_t)0x7FA736B4, (q31_t)0x096A9049, (q31_t)0x7FA37A3C, + (q31_t)0x099CB0A7, (q31_t)0x7F9FAA15, (q31_t)0x09CECF89, + (q31_t)0x7F9BC63F, (q31_t)0x0A00ECE8, (q31_t)0x7F97CEBC, + (q31_t)0x0A3308BC, (q31_t)0x7F93C38C, (q31_t)0x0A6522FE, + (q31_t)0x7F8FA4AF, (q31_t)0x0A973BA5, (q31_t)0x7F8B7226, + (q31_t)0x0AC952AA, (q31_t)0x7F872BF3, (q31_t)0x0AFB6805, + (q31_t)0x7F82D214, (q31_t)0x0B2D7BAE, (q31_t)0x7F7E648B, + (q31_t)0x0B5F8D9F, (q31_t)0x7F79E35A, (q31_t)0x0B919DCE, + (q31_t)0x7F754E7F, (q31_t)0x0BC3AC35, (q31_t)0x7F70A5FD, + (q31_t)0x0BF5B8CB, (q31_t)0x7F6BE9D4, (q31_t)0x0C27C389, + (q31_t)0x7F671A04, (q31_t)0x0C59CC67, (q31_t)0x7F62368F, + (q31_t)0x0C8BD35E, (q31_t)0x7F5D3F75, (q31_t)0x0CBDD865, + (q31_t)0x7F5834B6, (q31_t)0x0CEFDB75, (q31_t)0x7F531654, + (q31_t)0x0D21DC87, (q31_t)0x7F4DE450, (q31_t)0x0D53DB92, + (q31_t)0x7F489EAA, (q31_t)0x0D85D88F, (q31_t)0x7F434563, + (q31_t)0x0DB7D376, (q31_t)0x7F3DD87C, (q31_t)0x0DE9CC3F, + (q31_t)0x7F3857F5, (q31_t)0x0E1BC2E3, (q31_t)0x7F32C3D0, + (q31_t)0x0E4DB75B, (q31_t)0x7F2D1C0E, (q31_t)0x0E7FA99D, + (q31_t)0x7F2760AF, (q31_t)0x0EB199A3, (q31_t)0x7F2191B4, + (q31_t)0x0EE38765, (q31_t)0x7F1BAF1E, (q31_t)0x0F1572DC, + (q31_t)0x7F15B8EE, (q31_t)0x0F475BFE, (q31_t)0x7F0FAF24, + (q31_t)0x0F7942C6, (q31_t)0x7F0991C3, (q31_t)0x0FAB272B, + (q31_t)0x7F0360CB, (q31_t)0x0FDD0925, (q31_t)0x7EFD1C3C, + (q31_t)0x100EE8AD, (q31_t)0x7EF6C418, (q31_t)0x1040C5BB, + (q31_t)0x7EF0585F, (q31_t)0x1072A047, (q31_t)0x7EE9D913, + (q31_t)0x10A4784A, (q31_t)0x7EE34635, (q31_t)0x10D64DBC, + (q31_t)0x7EDC9FC6, (q31_t)0x11082096, (q31_t)0x7ED5E5C6, + (q31_t)0x1139F0CE, (q31_t)0x7ECF1837, (q31_t)0x116BBE5F, + (q31_t)0x7EC8371A, (q31_t)0x119D8940, (q31_t)0x7EC1426F, + (q31_t)0x11CF516A, (q31_t)0x7EBA3A39, (q31_t)0x120116D4, + (q31_t)0x7EB31E77, (q31_t)0x1232D978, (q31_t)0x7EABEF2C, + (q31_t)0x1264994E, (q31_t)0x7EA4AC58, (q31_t)0x1296564D, + (q31_t)0x7E9D55FC, (q31_t)0x12C8106E, (q31_t)0x7E95EC19, + (q31_t)0x12F9C7AA, (q31_t)0x7E8E6EB1, (q31_t)0x132B7BF9, + (q31_t)0x7E86DDC5, (q31_t)0x135D2D53, (q31_t)0x7E7F3956, + (q31_t)0x138EDBB0, (q31_t)0x7E778165, (q31_t)0x13C0870A, + (q31_t)0x7E6FB5F3, (q31_t)0x13F22F57, (q31_t)0x7E67D702, + (q31_t)0x1423D492, (q31_t)0x7E5FE493, (q31_t)0x145576B1, + (q31_t)0x7E57DEA6, (q31_t)0x148715AD, (q31_t)0x7E4FC53E, + (q31_t)0x14B8B17F, (q31_t)0x7E47985B, (q31_t)0x14EA4A1F, + (q31_t)0x7E3F57FE, (q31_t)0x151BDF85, (q31_t)0x7E37042A, + (q31_t)0x154D71AA, (q31_t)0x7E2E9CDF, (q31_t)0x157F0086, + (q31_t)0x7E26221E, (q31_t)0x15B08C11, (q31_t)0x7E1D93E9, + (q31_t)0x15E21444, (q31_t)0x7E14F242, (q31_t)0x16139917, + (q31_t)0x7E0C3D29, (q31_t)0x16451A83, (q31_t)0x7E03749F, + (q31_t)0x1676987F, (q31_t)0x7DFA98A7, (q31_t)0x16A81305, + (q31_t)0x7DF1A942, (q31_t)0x16D98A0C, (q31_t)0x7DE8A670, + (q31_t)0x170AFD8D, (q31_t)0x7DDF9034, (q31_t)0x173C6D80, + (q31_t)0x7DD6668E, (q31_t)0x176DD9DE, (q31_t)0x7DCD2981, + (q31_t)0x179F429F, (q31_t)0x7DC3D90D, (q31_t)0x17D0A7BB, + (q31_t)0x7DBA7534, (q31_t)0x1802092C, (q31_t)0x7DB0FDF7, + (q31_t)0x183366E8, (q31_t)0x7DA77359, (q31_t)0x1864C0E9, + (q31_t)0x7D9DD55A, (q31_t)0x18961727, (q31_t)0x7D9423FB, + (q31_t)0x18C7699B, (q31_t)0x7D8A5F3F, (q31_t)0x18F8B83C, + (q31_t)0x7D808727, (q31_t)0x192A0303, (q31_t)0x7D769BB5, + (q31_t)0x195B49E9, (q31_t)0x7D6C9CE9, (q31_t)0x198C8CE6, + (q31_t)0x7D628AC5, (q31_t)0x19BDCBF2, (q31_t)0x7D58654C, + (q31_t)0x19EF0706, (q31_t)0x7D4E2C7E, (q31_t)0x1A203E1B, + (q31_t)0x7D43E05E, (q31_t)0x1A517127, (q31_t)0x7D3980EC, + (q31_t)0x1A82A025, (q31_t)0x7D2F0E2A, (q31_t)0x1AB3CB0C, + (q31_t)0x7D24881A, (q31_t)0x1AE4F1D6, (q31_t)0x7D19EEBE, + (q31_t)0x1B161479, (q31_t)0x7D0F4218, (q31_t)0x1B4732EF, + (q31_t)0x7D048228, (q31_t)0x1B784D30, (q31_t)0x7CF9AEF0, + (q31_t)0x1BA96334, (q31_t)0x7CEEC873, (q31_t)0x1BDA74F5, + (q31_t)0x7CE3CEB1, (q31_t)0x1C0B826A, (q31_t)0x7CD8C1AD, + (q31_t)0x1C3C8B8C, (q31_t)0x7CCDA168, (q31_t)0x1C6D9053, + (q31_t)0x7CC26DE5, (q31_t)0x1C9E90B8, (q31_t)0x7CB72724, + (q31_t)0x1CCF8CB3, (q31_t)0x7CABCD27, (q31_t)0x1D00843C, + (q31_t)0x7CA05FF1, (q31_t)0x1D31774D, (q31_t)0x7C94DF82, + (q31_t)0x1D6265DD, (q31_t)0x7C894BDD, (q31_t)0x1D934FE5, + (q31_t)0x7C7DA504, (q31_t)0x1DC4355D, (q31_t)0x7C71EAF8, + (q31_t)0x1DF5163F, (q31_t)0x7C661DBB, (q31_t)0x1E25F281, + (q31_t)0x7C5A3D4F, (q31_t)0x1E56CA1E, (q31_t)0x7C4E49B6, + (q31_t)0x1E879D0C, (q31_t)0x7C4242F2, (q31_t)0x1EB86B46, + (q31_t)0x7C362904, (q31_t)0x1EE934C2, (q31_t)0x7C29FBEE, + (q31_t)0x1F19F97B, (q31_t)0x7C1DBBB2, (q31_t)0x1F4AB967, + (q31_t)0x7C116853, (q31_t)0x1F7B7480, (q31_t)0x7C0501D1, + (q31_t)0x1FAC2ABF, (q31_t)0x7BF88830, (q31_t)0x1FDCDC1A, + (q31_t)0x7BEBFB70, (q31_t)0x200D888C, (q31_t)0x7BDF5B94, + (q31_t)0x203E300D, (q31_t)0x7BD2A89E, (q31_t)0x206ED295, + (q31_t)0x7BC5E28F, (q31_t)0x209F701C, (q31_t)0x7BB9096A, + (q31_t)0x20D0089B, (q31_t)0x7BAC1D31, (q31_t)0x21009C0B, + (q31_t)0x7B9F1DE5, (q31_t)0x21312A65, (q31_t)0x7B920B89, + (q31_t)0x2161B39F, (q31_t)0x7B84E61E, (q31_t)0x219237B4, + (q31_t)0x7B77ADA8, (q31_t)0x21C2B69C, (q31_t)0x7B6A6227, + (q31_t)0x21F3304E, (q31_t)0x7B5D039D, (q31_t)0x2223A4C5, + (q31_t)0x7B4F920E, (q31_t)0x225413F8, (q31_t)0x7B420D7A, + (q31_t)0x22847DDF, (q31_t)0x7B3475E4, (q31_t)0x22B4E274, + (q31_t)0x7B26CB4F, (q31_t)0x22E541AE, (q31_t)0x7B190DBB, + (q31_t)0x23159B87, (q31_t)0x7B0B3D2C, (q31_t)0x2345EFF7, + (q31_t)0x7AFD59A3, (q31_t)0x23763EF7, (q31_t)0x7AEF6323, + (q31_t)0x23A6887E, (q31_t)0x7AE159AE, (q31_t)0x23D6CC86, + (q31_t)0x7AD33D45, (q31_t)0x24070B07, (q31_t)0x7AC50DEB, + (q31_t)0x243743FA, (q31_t)0x7AB6CBA3, (q31_t)0x24677757, + (q31_t)0x7AA8766E, (q31_t)0x2497A517, (q31_t)0x7A9A0E4F, + (q31_t)0x24C7CD32, (q31_t)0x7A8B9348, (q31_t)0x24F7EFA1, + (q31_t)0x7A7D055B, (q31_t)0x25280C5D, (q31_t)0x7A6E648A, + (q31_t)0x2558235E, (q31_t)0x7A5FB0D8, (q31_t)0x2588349D, + (q31_t)0x7A50EA46, (q31_t)0x25B84012, (q31_t)0x7A4210D8, + (q31_t)0x25E845B5, (q31_t)0x7A33248F, (q31_t)0x26184581, + (q31_t)0x7A24256E, (q31_t)0x26483F6C, (q31_t)0x7A151377, + (q31_t)0x26783370, (q31_t)0x7A05EEAD, (q31_t)0x26A82185, + (q31_t)0x79F6B711, (q31_t)0x26D809A5, (q31_t)0x79E76CA6, + (q31_t)0x2707EBC6, (q31_t)0x79D80F6F, (q31_t)0x2737C7E3, + (q31_t)0x79C89F6D, (q31_t)0x27679DF4, (q31_t)0x79B91CA4, + (q31_t)0x27976DF1, (q31_t)0x79A98715, (q31_t)0x27C737D2, + (q31_t)0x7999DEC3, (q31_t)0x27F6FB92, (q31_t)0x798A23B1, + (q31_t)0x2826B928, (q31_t)0x797A55E0, (q31_t)0x2856708C, + (q31_t)0x796A7554, (q31_t)0x288621B9, (q31_t)0x795A820E, + (q31_t)0x28B5CCA5, (q31_t)0x794A7C11, (q31_t)0x28E5714A, + (q31_t)0x793A6360, (q31_t)0x29150FA1, (q31_t)0x792A37FE, + (q31_t)0x2944A7A2, (q31_t)0x7919F9EB, (q31_t)0x29743945, + (q31_t)0x7909A92C, (q31_t)0x29A3C484, (q31_t)0x78F945C3, + (q31_t)0x29D34958, (q31_t)0x78E8CFB1, (q31_t)0x2A02C7B8, + (q31_t)0x78D846FB, (q31_t)0x2A323F9D, (q31_t)0x78C7ABA1, + (q31_t)0x2A61B101, (q31_t)0x78B6FDA8, (q31_t)0x2A911BDB, + (q31_t)0x78A63D10, (q31_t)0x2AC08025, (q31_t)0x789569DE, + (q31_t)0x2AEFDDD8, (q31_t)0x78848413, (q31_t)0x2B1F34EB, + (q31_t)0x78738BB3, (q31_t)0x2B4E8558, (q31_t)0x786280BF, + (q31_t)0x2B7DCF17, (q31_t)0x7851633B, (q31_t)0x2BAD1221, + (q31_t)0x78403328, (q31_t)0x2BDC4E6F, (q31_t)0x782EF08B, + (q31_t)0x2C0B83F9, (q31_t)0x781D9B64, (q31_t)0x2C3AB2B9, + (q31_t)0x780C33B8, (q31_t)0x2C69DAA6, (q31_t)0x77FAB988, + (q31_t)0x2C98FBBA, (q31_t)0x77E92CD8, (q31_t)0x2CC815ED, + (q31_t)0x77D78DAA, (q31_t)0x2CF72939, (q31_t)0x77C5DC01, + (q31_t)0x2D263595, (q31_t)0x77B417DF, (q31_t)0x2D553AFB, + (q31_t)0x77A24148, (q31_t)0x2D843963, (q31_t)0x7790583D, + (q31_t)0x2DB330C7, (q31_t)0x777E5CC3, (q31_t)0x2DE2211E, + (q31_t)0x776C4EDB, (q31_t)0x2E110A62, (q31_t)0x775A2E88, + (q31_t)0x2E3FEC8B, (q31_t)0x7747FBCE, (q31_t)0x2E6EC792, + (q31_t)0x7735B6AE, (q31_t)0x2E9D9B70, (q31_t)0x77235F2D, + (q31_t)0x2ECC681E, (q31_t)0x7710F54B, (q31_t)0x2EFB2D94, + (q31_t)0x76FE790E, (q31_t)0x2F29EBCC, (q31_t)0x76EBEA77, + (q31_t)0x2F58A2BD, (q31_t)0x76D94988, (q31_t)0x2F875262, + (q31_t)0x76C69646, (q31_t)0x2FB5FAB2, (q31_t)0x76B3D0B3, + (q31_t)0x2FE49BA6, (q31_t)0x76A0F8D2, (q31_t)0x30133538, + (q31_t)0x768E0EA5, (q31_t)0x3041C760, (q31_t)0x767B1230, + (q31_t)0x30705217, (q31_t)0x76680376, (q31_t)0x309ED555, + (q31_t)0x7654E279, (q31_t)0x30CD5114, (q31_t)0x7641AF3C, + (q31_t)0x30FBC54D, (q31_t)0x762E69C3, (q31_t)0x312A31F8, + (q31_t)0x761B1211, (q31_t)0x3158970D, (q31_t)0x7607A827, + (q31_t)0x3186F487, (q31_t)0x75F42C0A, (q31_t)0x31B54A5D, + (q31_t)0x75E09DBD, (q31_t)0x31E39889, (q31_t)0x75CCFD42, + (q31_t)0x3211DF03, (q31_t)0x75B94A9C, (q31_t)0x32401DC5, + (q31_t)0x75A585CF, (q31_t)0x326E54C7, (q31_t)0x7591AEDD, + (q31_t)0x329C8402, (q31_t)0x757DC5CA, (q31_t)0x32CAAB6F, + (q31_t)0x7569CA98, (q31_t)0x32F8CB07, (q31_t)0x7555BD4B, + (q31_t)0x3326E2C2, (q31_t)0x75419DE6, (q31_t)0x3354F29A, + (q31_t)0x752D6C6C, (q31_t)0x3382FA88, (q31_t)0x751928E0, + (q31_t)0x33B0FA84, (q31_t)0x7504D345, (q31_t)0x33DEF287, + (q31_t)0x74F06B9E, (q31_t)0x340CE28A, (q31_t)0x74DBF1EF, + (q31_t)0x343ACA87, (q31_t)0x74C7663A, (q31_t)0x3468AA76, + (q31_t)0x74B2C883, (q31_t)0x3496824F, (q31_t)0x749E18CD, + (q31_t)0x34C4520D, (q31_t)0x7489571B, (q31_t)0x34F219A7, + (q31_t)0x74748371, (q31_t)0x351FD917, (q31_t)0x745F9DD1, + (q31_t)0x354D9056, (q31_t)0x744AA63E, (q31_t)0x357B3F5D, + (q31_t)0x74359CBD, (q31_t)0x35A8E624, (q31_t)0x74208150, + (q31_t)0x35D684A5, (q31_t)0x740B53FA, (q31_t)0x36041AD9, + (q31_t)0x73F614C0, (q31_t)0x3631A8B7, (q31_t)0x73E0C3A3, + (q31_t)0x365F2E3B, (q31_t)0x73CB60A7, (q31_t)0x368CAB5C, + (q31_t)0x73B5EBD0, (q31_t)0x36BA2013, (q31_t)0x73A06522, + (q31_t)0x36E78C5A, (q31_t)0x738ACC9E, (q31_t)0x3714F02A, + (q31_t)0x73752249, (q31_t)0x37424B7A, (q31_t)0x735F6626, + (q31_t)0x376F9E46, (q31_t)0x73499838, (q31_t)0x379CE884, + (q31_t)0x7333B883, (q31_t)0x37CA2A30, (q31_t)0x731DC709, + (q31_t)0x37F76340, (q31_t)0x7307C3D0, (q31_t)0x382493B0, + (q31_t)0x72F1AED8, (q31_t)0x3851BB76, (q31_t)0x72DB8828, + (q31_t)0x387EDA8E, (q31_t)0x72C54FC0, (q31_t)0x38ABF0EF, + (q31_t)0x72AF05A6, (q31_t)0x38D8FE93, (q31_t)0x7298A9DC, + (q31_t)0x39060372, (q31_t)0x72823C66, (q31_t)0x3932FF87, + (q31_t)0x726BBD48, (q31_t)0x395FF2C9, (q31_t)0x72552C84, + (q31_t)0x398CDD32, (q31_t)0x723E8A1F, (q31_t)0x39B9BEBB, + (q31_t)0x7227D61C, (q31_t)0x39E6975D, (q31_t)0x7211107D, + (q31_t)0x3A136712, (q31_t)0x71FA3948, (q31_t)0x3A402DD1, + (q31_t)0x71E3507F, (q31_t)0x3A6CEB95, (q31_t)0x71CC5626, + (q31_t)0x3A99A057, (q31_t)0x71B54A40, (q31_t)0x3AC64C0F, + (q31_t)0x719E2CD2, (q31_t)0x3AF2EEB7, (q31_t)0x7186FDDE, + (q31_t)0x3B1F8847, (q31_t)0x716FBD68, (q31_t)0x3B4C18BA, + (q31_t)0x71586B73, (q31_t)0x3B78A007, (q31_t)0x71410804, + (q31_t)0x3BA51E29, (q31_t)0x7129931E, (q31_t)0x3BD19317, + (q31_t)0x71120CC5, (q31_t)0x3BFDFECD, (q31_t)0x70FA74FB, + (q31_t)0x3C2A6142, (q31_t)0x70E2CBC6, (q31_t)0x3C56BA70, + (q31_t)0x70CB1127, (q31_t)0x3C830A4F, (q31_t)0x70B34524, + (q31_t)0x3CAF50DA, (q31_t)0x709B67C0, (q31_t)0x3CDB8E09, + (q31_t)0x708378FE, (q31_t)0x3D07C1D5, (q31_t)0x706B78E3, + (q31_t)0x3D33EC39, (q31_t)0x70536771, (q31_t)0x3D600D2B, + (q31_t)0x703B44AC, (q31_t)0x3D8C24A7, (q31_t)0x70231099, + (q31_t)0x3DB832A5, (q31_t)0x700ACB3B, (q31_t)0x3DE4371F, + (q31_t)0x6FF27496, (q31_t)0x3E10320D, (q31_t)0x6FDA0CAD, + (q31_t)0x3E3C2369, (q31_t)0x6FC19385, (q31_t)0x3E680B2C, + (q31_t)0x6FA90920, (q31_t)0x3E93E94F, (q31_t)0x6F906D84, + (q31_t)0x3EBFBDCC, (q31_t)0x6F77C0B3, (q31_t)0x3EEB889C, + (q31_t)0x6F5F02B1, (q31_t)0x3F1749B7, (q31_t)0x6F463383, + (q31_t)0x3F430118, (q31_t)0x6F2D532C, (q31_t)0x3F6EAEB8, + (q31_t)0x6F1461AF, (q31_t)0x3F9A528F, (q31_t)0x6EFB5F12, + (q31_t)0x3FC5EC97, (q31_t)0x6EE24B57, (q31_t)0x3FF17CCA, + (q31_t)0x6EC92682, (q31_t)0x401D0320, (q31_t)0x6EAFF098, + (q31_t)0x40487F93, (q31_t)0x6E96A99C, (q31_t)0x4073F21D, + (q31_t)0x6E7D5193, (q31_t)0x409F5AB6, (q31_t)0x6E63E87F, + (q31_t)0x40CAB957, (q31_t)0x6E4A6E65, (q31_t)0x40F60DFB, + (q31_t)0x6E30E349, (q31_t)0x4121589A, (q31_t)0x6E17472F, + (q31_t)0x414C992E, (q31_t)0x6DFD9A1B, (q31_t)0x4177CFB0, + (q31_t)0x6DE3DC11, (q31_t)0x41A2FC1A, (q31_t)0x6DCA0D14, + (q31_t)0x41CE1E64, (q31_t)0x6DB02D29, (q31_t)0x41F93688, + (q31_t)0x6D963C54, (q31_t)0x42244480, (q31_t)0x6D7C3A98, + (q31_t)0x424F4845, (q31_t)0x6D6227FA, (q31_t)0x427A41D0, + (q31_t)0x6D48047E, (q31_t)0x42A5311A, (q31_t)0x6D2DD027, + (q31_t)0x42D0161E, (q31_t)0x6D138AFA, (q31_t)0x42FAF0D4, + (q31_t)0x6CF934FB, (q31_t)0x4325C135, (q31_t)0x6CDECE2E, + (q31_t)0x4350873C, (q31_t)0x6CC45697, (q31_t)0x437B42E1, + (q31_t)0x6CA9CE3A, (q31_t)0x43A5F41E, (q31_t)0x6C8F351C, + (q31_t)0x43D09AEC, (q31_t)0x6C748B3F, (q31_t)0x43FB3745, + (q31_t)0x6C59D0A9, (q31_t)0x4425C923, (q31_t)0x6C3F055D, + (q31_t)0x4450507E, (q31_t)0x6C242960, (q31_t)0x447ACD50, + (q31_t)0x6C093CB6, (q31_t)0x44A53F93, (q31_t)0x6BEE3F62, + (q31_t)0x44CFA73F, (q31_t)0x6BD3316A, (q31_t)0x44FA044F, + (q31_t)0x6BB812D0, (q31_t)0x452456BC, (q31_t)0x6B9CE39B, + (q31_t)0x454E9E80, (q31_t)0x6B81A3CD, (q31_t)0x4578DB93, + (q31_t)0x6B66536A, (q31_t)0x45A30DF0, (q31_t)0x6B4AF278, + (q31_t)0x45CD358F, (q31_t)0x6B2F80FA, (q31_t)0x45F7526B, + (q31_t)0x6B13FEF5, (q31_t)0x4621647C, (q31_t)0x6AF86C6C, + (q31_t)0x464B6BBD, (q31_t)0x6ADCC964, (q31_t)0x46756827, + (q31_t)0x6AC115E1, (q31_t)0x469F59B4, (q31_t)0x6AA551E8, + (q31_t)0x46C9405C, (q31_t)0x6A897D7D, (q31_t)0x46F31C1A, + (q31_t)0x6A6D98A4, (q31_t)0x471CECE6, (q31_t)0x6A51A361, + (q31_t)0x4746B2BC, (q31_t)0x6A359DB9, (q31_t)0x47706D93, + (q31_t)0x6A1987B0, (q31_t)0x479A1D66, (q31_t)0x69FD614A, + (q31_t)0x47C3C22E, (q31_t)0x69E12A8C, (q31_t)0x47ED5BE6, + (q31_t)0x69C4E37A, (q31_t)0x4816EA85, (q31_t)0x69A88C18, + (q31_t)0x48406E07, (q31_t)0x698C246C, (q31_t)0x4869E664, + (q31_t)0x696FAC78, (q31_t)0x48935397, (q31_t)0x69532442, + (q31_t)0x48BCB598, (q31_t)0x69368BCE, (q31_t)0x48E60C62, + (q31_t)0x6919E320, (q31_t)0x490F57EE, (q31_t)0x68FD2A3D, + (q31_t)0x49389836, (q31_t)0x68E06129, (q31_t)0x4961CD32, + (q31_t)0x68C387E9, (q31_t)0x498AF6DE, (q31_t)0x68A69E81, + (q31_t)0x49B41533, (q31_t)0x6889A4F5, (q31_t)0x49DD282A, + (q31_t)0x686C9B4B, (q31_t)0x4A062FBD, (q31_t)0x684F8186, + (q31_t)0x4A2F2BE5, (q31_t)0x683257AA, (q31_t)0x4A581C9D, + (q31_t)0x68151DBE, (q31_t)0x4A8101DE, (q31_t)0x67F7D3C4, + (q31_t)0x4AA9DBA1, (q31_t)0x67DA79C2, (q31_t)0x4AD2A9E1, + (q31_t)0x67BD0FBC, (q31_t)0x4AFB6C97, (q31_t)0x679F95B7, + (q31_t)0x4B2423BD, (q31_t)0x67820BB6, (q31_t)0x4B4CCF4D, + (q31_t)0x676471C0, (q31_t)0x4B756F3F, (q31_t)0x6746C7D7, + (q31_t)0x4B9E038F, (q31_t)0x67290E02, (q31_t)0x4BC68C36, + (q31_t)0x670B4443, (q31_t)0x4BEF092D, (q31_t)0x66ED6AA1, + (q31_t)0x4C177A6E, (q31_t)0x66CF811F, (q31_t)0x4C3FDFF3, + (q31_t)0x66B187C3, (q31_t)0x4C6839B6, (q31_t)0x66937E90, + (q31_t)0x4C9087B1, (q31_t)0x6675658C, (q31_t)0x4CB8C9DD, + (q31_t)0x66573CBB, (q31_t)0x4CE10034, (q31_t)0x66390422, + (q31_t)0x4D092AB0, (q31_t)0x661ABBC5, (q31_t)0x4D31494B, + (q31_t)0x65FC63A9, (q31_t)0x4D595BFE, (q31_t)0x65DDFBD3, + (q31_t)0x4D8162C4, (q31_t)0x65BF8447, (q31_t)0x4DA95D96, + (q31_t)0x65A0FD0B, (q31_t)0x4DD14C6E, (q31_t)0x65826622, + (q31_t)0x4DF92F45, (q31_t)0x6563BF92, (q31_t)0x4E210617, + (q31_t)0x6545095F, (q31_t)0x4E48D0DC, (q31_t)0x6526438E, + (q31_t)0x4E708F8F, (q31_t)0x65076E24, (q31_t)0x4E984229, + (q31_t)0x64E88926, (q31_t)0x4EBFE8A4, (q31_t)0x64C99498, + (q31_t)0x4EE782FA, (q31_t)0x64AA907F, (q31_t)0x4F0F1126, + (q31_t)0x648B7CDF, (q31_t)0x4F369320, (q31_t)0x646C59BF, + (q31_t)0x4F5E08E3, (q31_t)0x644D2722, (q31_t)0x4F857268, + (q31_t)0x642DE50D, (q31_t)0x4FACCFAB, (q31_t)0x640E9385, + (q31_t)0x4FD420A3, (q31_t)0x63EF328F, (q31_t)0x4FFB654D, + (q31_t)0x63CFC230, (q31_t)0x50229DA0, (q31_t)0x63B0426D, + (q31_t)0x5049C999, (q31_t)0x6390B34A, (q31_t)0x5070E92F, + (q31_t)0x637114CC, (q31_t)0x5097FC5E, (q31_t)0x635166F8, + (q31_t)0x50BF031F, (q31_t)0x6331A9D4, (q31_t)0x50E5FD6C, + (q31_t)0x6311DD63, (q31_t)0x510CEB40, (q31_t)0x62F201AC, + (q31_t)0x5133CC94, (q31_t)0x62D216B2, (q31_t)0x515AA162, + (q31_t)0x62B21C7B, (q31_t)0x518169A4, (q31_t)0x6292130C, + (q31_t)0x51A82555, (q31_t)0x6271FA69, (q31_t)0x51CED46E, + (q31_t)0x6251D297, (q31_t)0x51F576E9, (q31_t)0x62319B9D, + (q31_t)0x521C0CC1, (q31_t)0x6211557D, (q31_t)0x524295EF, + (q31_t)0x61F1003E, (q31_t)0x5269126E, (q31_t)0x61D09BE5, + (q31_t)0x528F8237, (q31_t)0x61B02876, (q31_t)0x52B5E545, + (q31_t)0x618FA5F6, (q31_t)0x52DC3B92, (q31_t)0x616F146B, + (q31_t)0x53028517, (q31_t)0x614E73D9, (q31_t)0x5328C1D0, + (q31_t)0x612DC446, (q31_t)0x534EF1B5, (q31_t)0x610D05B7, + (q31_t)0x537514C1, (q31_t)0x60EC3830, (q31_t)0x539B2AEF, + (q31_t)0x60CB5BB6, (q31_t)0x53C13438, (q31_t)0x60AA704F, + (q31_t)0x53E73097, (q31_t)0x60897600, (q31_t)0x540D2005, + (q31_t)0x60686CCE, (q31_t)0x5433027D, (q31_t)0x604754BE, + (q31_t)0x5458D7F9, (q31_t)0x60262DD5, (q31_t)0x547EA073, + (q31_t)0x6004F818, (q31_t)0x54A45BE5, (q31_t)0x5FE3B38D, + (q31_t)0x54CA0A4A, (q31_t)0x5FC26038, (q31_t)0x54EFAB9C, + (q31_t)0x5FA0FE1E, (q31_t)0x55153FD4, (q31_t)0x5F7F8D46, + (q31_t)0x553AC6ED, (q31_t)0x5F5E0DB3, (q31_t)0x556040E2, + (q31_t)0x5F3C7F6B, (q31_t)0x5585ADAC, (q31_t)0x5F1AE273, + (q31_t)0x55AB0D46, (q31_t)0x5EF936D1, (q31_t)0x55D05FAA, + (q31_t)0x5ED77C89, (q31_t)0x55F5A4D2, (q31_t)0x5EB5B3A1, + (q31_t)0x561ADCB8, (q31_t)0x5E93DC1F, (q31_t)0x56400757, + (q31_t)0x5E71F606, (q31_t)0x566524AA, (q31_t)0x5E50015D, + (q31_t)0x568A34A9, (q31_t)0x5E2DFE28, (q31_t)0x56AF3750, + (q31_t)0x5E0BEC6E, (q31_t)0x56D42C99, (q31_t)0x5DE9CC32, + (q31_t)0x56F9147E, (q31_t)0x5DC79D7C, (q31_t)0x571DEEF9, + (q31_t)0x5DA5604E, (q31_t)0x5742BC05, (q31_t)0x5D8314B0, + (q31_t)0x57677B9D, (q31_t)0x5D60BAA6, (q31_t)0x578C2DB9, + (q31_t)0x5D3E5236, (q31_t)0x57B0D256, (q31_t)0x5D1BDB65, + (q31_t)0x57D5696C, (q31_t)0x5CF95638, (q31_t)0x57F9F2F7, + (q31_t)0x5CD6C2B4, (q31_t)0x581E6EF1, (q31_t)0x5CB420DF, + (q31_t)0x5842DD54, (q31_t)0x5C9170BF, (q31_t)0x58673E1B, + (q31_t)0x5C6EB258, (q31_t)0x588B913F, (q31_t)0x5C4BE5B0, + (q31_t)0x58AFD6BC, (q31_t)0x5C290ACC, (q31_t)0x58D40E8C, + (q31_t)0x5C0621B2, (q31_t)0x58F838A9, (q31_t)0x5BE32A67, + (q31_t)0x591C550E, (q31_t)0x5BC024F0, (q31_t)0x594063B4, + (q31_t)0x5B9D1153, (q31_t)0x59646497, (q31_t)0x5B79EF96, + (q31_t)0x598857B1, (q31_t)0x5B56BFBD, (q31_t)0x59AC3CFD, + (q31_t)0x5B3381CE, (q31_t)0x59D01474, (q31_t)0x5B1035CF, + (q31_t)0x59F3DE12, (q31_t)0x5AECDBC4, (q31_t)0x5A1799D0, + (q31_t)0x5AC973B4, (q31_t)0x5A3B47AA, (q31_t)0x5AA5FDA4, + (q31_t)0x5A5EE79A, (q31_t)0x5A82799A, (q31_t)0x5A82799A, + (q31_t)0x5A5EE79A, (q31_t)0x5AA5FDA4, (q31_t)0x5A3B47AA, + (q31_t)0x5AC973B4, (q31_t)0x5A1799D0, (q31_t)0x5AECDBC4, + (q31_t)0x59F3DE12, (q31_t)0x5B1035CF, (q31_t)0x59D01474, + (q31_t)0x5B3381CE, (q31_t)0x59AC3CFD, (q31_t)0x5B56BFBD, + (q31_t)0x598857B1, (q31_t)0x5B79EF96, (q31_t)0x59646497, + (q31_t)0x5B9D1153, (q31_t)0x594063B4, (q31_t)0x5BC024F0, + (q31_t)0x591C550E, (q31_t)0x5BE32A67, (q31_t)0x58F838A9, + (q31_t)0x5C0621B2, (q31_t)0x58D40E8C, (q31_t)0x5C290ACC, + (q31_t)0x58AFD6BC, (q31_t)0x5C4BE5B0, (q31_t)0x588B913F, + (q31_t)0x5C6EB258, (q31_t)0x58673E1B, (q31_t)0x5C9170BF, + (q31_t)0x5842DD54, (q31_t)0x5CB420DF, (q31_t)0x581E6EF1, + (q31_t)0x5CD6C2B4, (q31_t)0x57F9F2F7, (q31_t)0x5CF95638, + (q31_t)0x57D5696C, (q31_t)0x5D1BDB65, (q31_t)0x57B0D256, + (q31_t)0x5D3E5236, (q31_t)0x578C2DB9, (q31_t)0x5D60BAA6, + (q31_t)0x57677B9D, (q31_t)0x5D8314B0, (q31_t)0x5742BC05, + (q31_t)0x5DA5604E, (q31_t)0x571DEEF9, (q31_t)0x5DC79D7C, + (q31_t)0x56F9147E, (q31_t)0x5DE9CC32, (q31_t)0x56D42C99, + (q31_t)0x5E0BEC6E, (q31_t)0x56AF3750, (q31_t)0x5E2DFE28, + (q31_t)0x568A34A9, (q31_t)0x5E50015D, (q31_t)0x566524AA, + (q31_t)0x5E71F606, (q31_t)0x56400757, (q31_t)0x5E93DC1F, + (q31_t)0x561ADCB8, (q31_t)0x5EB5B3A1, (q31_t)0x55F5A4D2, + (q31_t)0x5ED77C89, (q31_t)0x55D05FAA, (q31_t)0x5EF936D1, + (q31_t)0x55AB0D46, (q31_t)0x5F1AE273, (q31_t)0x5585ADAC, + (q31_t)0x5F3C7F6B, (q31_t)0x556040E2, (q31_t)0x5F5E0DB3, + (q31_t)0x553AC6ED, (q31_t)0x5F7F8D46, (q31_t)0x55153FD4, + (q31_t)0x5FA0FE1E, (q31_t)0x54EFAB9C, (q31_t)0x5FC26038, + (q31_t)0x54CA0A4A, (q31_t)0x5FE3B38D, (q31_t)0x54A45BE5, + (q31_t)0x6004F818, (q31_t)0x547EA073, (q31_t)0x60262DD5, + (q31_t)0x5458D7F9, (q31_t)0x604754BE, (q31_t)0x5433027D, + (q31_t)0x60686CCE, (q31_t)0x540D2005, (q31_t)0x60897600, + (q31_t)0x53E73097, (q31_t)0x60AA704F, (q31_t)0x53C13438, + (q31_t)0x60CB5BB6, (q31_t)0x539B2AEF, (q31_t)0x60EC3830, + (q31_t)0x537514C1, (q31_t)0x610D05B7, (q31_t)0x534EF1B5, + (q31_t)0x612DC446, (q31_t)0x5328C1D0, (q31_t)0x614E73D9, + (q31_t)0x53028517, (q31_t)0x616F146B, (q31_t)0x52DC3B92, + (q31_t)0x618FA5F6, (q31_t)0x52B5E545, (q31_t)0x61B02876, + (q31_t)0x528F8237, (q31_t)0x61D09BE5, (q31_t)0x5269126E, + (q31_t)0x61F1003E, (q31_t)0x524295EF, (q31_t)0x6211557D, + (q31_t)0x521C0CC1, (q31_t)0x62319B9D, (q31_t)0x51F576E9, + (q31_t)0x6251D297, (q31_t)0x51CED46E, (q31_t)0x6271FA69, + (q31_t)0x51A82555, (q31_t)0x6292130C, (q31_t)0x518169A4, + (q31_t)0x62B21C7B, (q31_t)0x515AA162, (q31_t)0x62D216B2, + (q31_t)0x5133CC94, (q31_t)0x62F201AC, (q31_t)0x510CEB40, + (q31_t)0x6311DD63, (q31_t)0x50E5FD6C, (q31_t)0x6331A9D4, + (q31_t)0x50BF031F, (q31_t)0x635166F8, (q31_t)0x5097FC5E, + (q31_t)0x637114CC, (q31_t)0x5070E92F, (q31_t)0x6390B34A, + (q31_t)0x5049C999, (q31_t)0x63B0426D, (q31_t)0x50229DA0, + (q31_t)0x63CFC230, (q31_t)0x4FFB654D, (q31_t)0x63EF328F, + (q31_t)0x4FD420A3, (q31_t)0x640E9385, (q31_t)0x4FACCFAB, + (q31_t)0x642DE50D, (q31_t)0x4F857268, (q31_t)0x644D2722, + (q31_t)0x4F5E08E3, (q31_t)0x646C59BF, (q31_t)0x4F369320, + (q31_t)0x648B7CDF, (q31_t)0x4F0F1126, (q31_t)0x64AA907F, + (q31_t)0x4EE782FA, (q31_t)0x64C99498, (q31_t)0x4EBFE8A4, + (q31_t)0x64E88926, (q31_t)0x4E984229, (q31_t)0x65076E24, + (q31_t)0x4E708F8F, (q31_t)0x6526438E, (q31_t)0x4E48D0DC, + (q31_t)0x6545095F, (q31_t)0x4E210617, (q31_t)0x6563BF92, + (q31_t)0x4DF92F45, (q31_t)0x65826622, (q31_t)0x4DD14C6E, + (q31_t)0x65A0FD0B, (q31_t)0x4DA95D96, (q31_t)0x65BF8447, + (q31_t)0x4D8162C4, (q31_t)0x65DDFBD3, (q31_t)0x4D595BFE, + (q31_t)0x65FC63A9, (q31_t)0x4D31494B, (q31_t)0x661ABBC5, + (q31_t)0x4D092AB0, (q31_t)0x66390422, (q31_t)0x4CE10034, + (q31_t)0x66573CBB, (q31_t)0x4CB8C9DD, (q31_t)0x6675658C, + (q31_t)0x4C9087B1, (q31_t)0x66937E90, (q31_t)0x4C6839B6, + (q31_t)0x66B187C3, (q31_t)0x4C3FDFF3, (q31_t)0x66CF811F, + (q31_t)0x4C177A6E, (q31_t)0x66ED6AA1, (q31_t)0x4BEF092D, + (q31_t)0x670B4443, (q31_t)0x4BC68C36, (q31_t)0x67290E02, + (q31_t)0x4B9E038F, (q31_t)0x6746C7D7, (q31_t)0x4B756F3F, + (q31_t)0x676471C0, (q31_t)0x4B4CCF4D, (q31_t)0x67820BB6, + (q31_t)0x4B2423BD, (q31_t)0x679F95B7, (q31_t)0x4AFB6C97, + (q31_t)0x67BD0FBC, (q31_t)0x4AD2A9E1, (q31_t)0x67DA79C2, + (q31_t)0x4AA9DBA1, (q31_t)0x67F7D3C4, (q31_t)0x4A8101DE, + (q31_t)0x68151DBE, (q31_t)0x4A581C9D, (q31_t)0x683257AA, + (q31_t)0x4A2F2BE5, (q31_t)0x684F8186, (q31_t)0x4A062FBD, + (q31_t)0x686C9B4B, (q31_t)0x49DD282A, (q31_t)0x6889A4F5, + (q31_t)0x49B41533, (q31_t)0x68A69E81, (q31_t)0x498AF6DE, + (q31_t)0x68C387E9, (q31_t)0x4961CD32, (q31_t)0x68E06129, + (q31_t)0x49389836, (q31_t)0x68FD2A3D, (q31_t)0x490F57EE, + (q31_t)0x6919E320, (q31_t)0x48E60C62, (q31_t)0x69368BCE, + (q31_t)0x48BCB598, (q31_t)0x69532442, (q31_t)0x48935397, + (q31_t)0x696FAC78, (q31_t)0x4869E664, (q31_t)0x698C246C, + (q31_t)0x48406E07, (q31_t)0x69A88C18, (q31_t)0x4816EA85, + (q31_t)0x69C4E37A, (q31_t)0x47ED5BE6, (q31_t)0x69E12A8C, + (q31_t)0x47C3C22E, (q31_t)0x69FD614A, (q31_t)0x479A1D66, + (q31_t)0x6A1987B0, (q31_t)0x47706D93, (q31_t)0x6A359DB9, + (q31_t)0x4746B2BC, (q31_t)0x6A51A361, (q31_t)0x471CECE6, + (q31_t)0x6A6D98A4, (q31_t)0x46F31C1A, (q31_t)0x6A897D7D, + (q31_t)0x46C9405C, (q31_t)0x6AA551E8, (q31_t)0x469F59B4, + (q31_t)0x6AC115E1, (q31_t)0x46756827, (q31_t)0x6ADCC964, + (q31_t)0x464B6BBD, (q31_t)0x6AF86C6C, (q31_t)0x4621647C, + (q31_t)0x6B13FEF5, (q31_t)0x45F7526B, (q31_t)0x6B2F80FA, + (q31_t)0x45CD358F, (q31_t)0x6B4AF278, (q31_t)0x45A30DF0, + (q31_t)0x6B66536A, (q31_t)0x4578DB93, (q31_t)0x6B81A3CD, + (q31_t)0x454E9E80, (q31_t)0x6B9CE39B, (q31_t)0x452456BC, + (q31_t)0x6BB812D0, (q31_t)0x44FA044F, (q31_t)0x6BD3316A, + (q31_t)0x44CFA73F, (q31_t)0x6BEE3F62, (q31_t)0x44A53F93, + (q31_t)0x6C093CB6, (q31_t)0x447ACD50, (q31_t)0x6C242960, + (q31_t)0x4450507E, (q31_t)0x6C3F055D, (q31_t)0x4425C923, + (q31_t)0x6C59D0A9, (q31_t)0x43FB3745, (q31_t)0x6C748B3F, + (q31_t)0x43D09AEC, (q31_t)0x6C8F351C, (q31_t)0x43A5F41E, + (q31_t)0x6CA9CE3A, (q31_t)0x437B42E1, (q31_t)0x6CC45697, + (q31_t)0x4350873C, (q31_t)0x6CDECE2E, (q31_t)0x4325C135, + (q31_t)0x6CF934FB, (q31_t)0x42FAF0D4, (q31_t)0x6D138AFA, + (q31_t)0x42D0161E, (q31_t)0x6D2DD027, (q31_t)0x42A5311A, + (q31_t)0x6D48047E, (q31_t)0x427A41D0, (q31_t)0x6D6227FA, + (q31_t)0x424F4845, (q31_t)0x6D7C3A98, (q31_t)0x42244480, + (q31_t)0x6D963C54, (q31_t)0x41F93688, (q31_t)0x6DB02D29, + (q31_t)0x41CE1E64, (q31_t)0x6DCA0D14, (q31_t)0x41A2FC1A, + (q31_t)0x6DE3DC11, (q31_t)0x4177CFB0, (q31_t)0x6DFD9A1B, + (q31_t)0x414C992E, (q31_t)0x6E17472F, (q31_t)0x4121589A, + (q31_t)0x6E30E349, (q31_t)0x40F60DFB, (q31_t)0x6E4A6E65, + (q31_t)0x40CAB957, (q31_t)0x6E63E87F, (q31_t)0x409F5AB6, + (q31_t)0x6E7D5193, (q31_t)0x4073F21D, (q31_t)0x6E96A99C, + (q31_t)0x40487F93, (q31_t)0x6EAFF098, (q31_t)0x401D0320, + (q31_t)0x6EC92682, (q31_t)0x3FF17CCA, (q31_t)0x6EE24B57, + (q31_t)0x3FC5EC97, (q31_t)0x6EFB5F12, (q31_t)0x3F9A528F, + (q31_t)0x6F1461AF, (q31_t)0x3F6EAEB8, (q31_t)0x6F2D532C, + (q31_t)0x3F430118, (q31_t)0x6F463383, (q31_t)0x3F1749B7, + (q31_t)0x6F5F02B1, (q31_t)0x3EEB889C, (q31_t)0x6F77C0B3, + (q31_t)0x3EBFBDCC, (q31_t)0x6F906D84, (q31_t)0x3E93E94F, + (q31_t)0x6FA90920, (q31_t)0x3E680B2C, (q31_t)0x6FC19385, + (q31_t)0x3E3C2369, (q31_t)0x6FDA0CAD, (q31_t)0x3E10320D, + (q31_t)0x6FF27496, (q31_t)0x3DE4371F, (q31_t)0x700ACB3B, + (q31_t)0x3DB832A5, (q31_t)0x70231099, (q31_t)0x3D8C24A7, + (q31_t)0x703B44AC, (q31_t)0x3D600D2B, (q31_t)0x70536771, + (q31_t)0x3D33EC39, (q31_t)0x706B78E3, (q31_t)0x3D07C1D5, + (q31_t)0x708378FE, (q31_t)0x3CDB8E09, (q31_t)0x709B67C0, + (q31_t)0x3CAF50DA, (q31_t)0x70B34524, (q31_t)0x3C830A4F, + (q31_t)0x70CB1127, (q31_t)0x3C56BA70, (q31_t)0x70E2CBC6, + (q31_t)0x3C2A6142, (q31_t)0x70FA74FB, (q31_t)0x3BFDFECD, + (q31_t)0x71120CC5, (q31_t)0x3BD19317, (q31_t)0x7129931E, + (q31_t)0x3BA51E29, (q31_t)0x71410804, (q31_t)0x3B78A007, + (q31_t)0x71586B73, (q31_t)0x3B4C18BA, (q31_t)0x716FBD68, + (q31_t)0x3B1F8847, (q31_t)0x7186FDDE, (q31_t)0x3AF2EEB7, + (q31_t)0x719E2CD2, (q31_t)0x3AC64C0F, (q31_t)0x71B54A40, + (q31_t)0x3A99A057, (q31_t)0x71CC5626, (q31_t)0x3A6CEB95, + (q31_t)0x71E3507F, (q31_t)0x3A402DD1, (q31_t)0x71FA3948, + (q31_t)0x3A136712, (q31_t)0x7211107D, (q31_t)0x39E6975D, + (q31_t)0x7227D61C, (q31_t)0x39B9BEBB, (q31_t)0x723E8A1F, + (q31_t)0x398CDD32, (q31_t)0x72552C84, (q31_t)0x395FF2C9, + (q31_t)0x726BBD48, (q31_t)0x3932FF87, (q31_t)0x72823C66, + (q31_t)0x39060372, (q31_t)0x7298A9DC, (q31_t)0x38D8FE93, + (q31_t)0x72AF05A6, (q31_t)0x38ABF0EF, (q31_t)0x72C54FC0, + (q31_t)0x387EDA8E, (q31_t)0x72DB8828, (q31_t)0x3851BB76, + (q31_t)0x72F1AED8, (q31_t)0x382493B0, (q31_t)0x7307C3D0, + (q31_t)0x37F76340, (q31_t)0x731DC709, (q31_t)0x37CA2A30, + (q31_t)0x7333B883, (q31_t)0x379CE884, (q31_t)0x73499838, + (q31_t)0x376F9E46, (q31_t)0x735F6626, (q31_t)0x37424B7A, + (q31_t)0x73752249, (q31_t)0x3714F02A, (q31_t)0x738ACC9E, + (q31_t)0x36E78C5A, (q31_t)0x73A06522, (q31_t)0x36BA2013, + (q31_t)0x73B5EBD0, (q31_t)0x368CAB5C, (q31_t)0x73CB60A7, + (q31_t)0x365F2E3B, (q31_t)0x73E0C3A3, (q31_t)0x3631A8B7, + (q31_t)0x73F614C0, (q31_t)0x36041AD9, (q31_t)0x740B53FA, + (q31_t)0x35D684A5, (q31_t)0x74208150, (q31_t)0x35A8E624, + (q31_t)0x74359CBD, (q31_t)0x357B3F5D, (q31_t)0x744AA63E, + (q31_t)0x354D9056, (q31_t)0x745F9DD1, (q31_t)0x351FD917, + (q31_t)0x74748371, (q31_t)0x34F219A7, (q31_t)0x7489571B, + (q31_t)0x34C4520D, (q31_t)0x749E18CD, (q31_t)0x3496824F, + (q31_t)0x74B2C883, (q31_t)0x3468AA76, (q31_t)0x74C7663A, + (q31_t)0x343ACA87, (q31_t)0x74DBF1EF, (q31_t)0x340CE28A, + (q31_t)0x74F06B9E, (q31_t)0x33DEF287, (q31_t)0x7504D345, + (q31_t)0x33B0FA84, (q31_t)0x751928E0, (q31_t)0x3382FA88, + (q31_t)0x752D6C6C, (q31_t)0x3354F29A, (q31_t)0x75419DE6, + (q31_t)0x3326E2C2, (q31_t)0x7555BD4B, (q31_t)0x32F8CB07, + (q31_t)0x7569CA98, (q31_t)0x32CAAB6F, (q31_t)0x757DC5CA, + (q31_t)0x329C8402, (q31_t)0x7591AEDD, (q31_t)0x326E54C7, + (q31_t)0x75A585CF, (q31_t)0x32401DC5, (q31_t)0x75B94A9C, + (q31_t)0x3211DF03, (q31_t)0x75CCFD42, (q31_t)0x31E39889, + (q31_t)0x75E09DBD, (q31_t)0x31B54A5D, (q31_t)0x75F42C0A, + (q31_t)0x3186F487, (q31_t)0x7607A827, (q31_t)0x3158970D, + (q31_t)0x761B1211, (q31_t)0x312A31F8, (q31_t)0x762E69C3, + (q31_t)0x30FBC54D, (q31_t)0x7641AF3C, (q31_t)0x30CD5114, + (q31_t)0x7654E279, (q31_t)0x309ED555, (q31_t)0x76680376, + (q31_t)0x30705217, (q31_t)0x767B1230, (q31_t)0x3041C760, + (q31_t)0x768E0EA5, (q31_t)0x30133538, (q31_t)0x76A0F8D2, + (q31_t)0x2FE49BA6, (q31_t)0x76B3D0B3, (q31_t)0x2FB5FAB2, + (q31_t)0x76C69646, (q31_t)0x2F875262, (q31_t)0x76D94988, + (q31_t)0x2F58A2BD, (q31_t)0x76EBEA77, (q31_t)0x2F29EBCC, + (q31_t)0x76FE790E, (q31_t)0x2EFB2D94, (q31_t)0x7710F54B, + (q31_t)0x2ECC681E, (q31_t)0x77235F2D, (q31_t)0x2E9D9B70, + (q31_t)0x7735B6AE, (q31_t)0x2E6EC792, (q31_t)0x7747FBCE, + (q31_t)0x2E3FEC8B, (q31_t)0x775A2E88, (q31_t)0x2E110A62, + (q31_t)0x776C4EDB, (q31_t)0x2DE2211E, (q31_t)0x777E5CC3, + (q31_t)0x2DB330C7, (q31_t)0x7790583D, (q31_t)0x2D843963, + (q31_t)0x77A24148, (q31_t)0x2D553AFB, (q31_t)0x77B417DF, + (q31_t)0x2D263595, (q31_t)0x77C5DC01, (q31_t)0x2CF72939, + (q31_t)0x77D78DAA, (q31_t)0x2CC815ED, (q31_t)0x77E92CD8, + (q31_t)0x2C98FBBA, (q31_t)0x77FAB988, (q31_t)0x2C69DAA6, + (q31_t)0x780C33B8, (q31_t)0x2C3AB2B9, (q31_t)0x781D9B64, + (q31_t)0x2C0B83F9, (q31_t)0x782EF08B, (q31_t)0x2BDC4E6F, + (q31_t)0x78403328, (q31_t)0x2BAD1221, (q31_t)0x7851633B, + (q31_t)0x2B7DCF17, (q31_t)0x786280BF, (q31_t)0x2B4E8558, + (q31_t)0x78738BB3, (q31_t)0x2B1F34EB, (q31_t)0x78848413, + (q31_t)0x2AEFDDD8, (q31_t)0x789569DE, (q31_t)0x2AC08025, + (q31_t)0x78A63D10, (q31_t)0x2A911BDB, (q31_t)0x78B6FDA8, + (q31_t)0x2A61B101, (q31_t)0x78C7ABA1, (q31_t)0x2A323F9D, + (q31_t)0x78D846FB, (q31_t)0x2A02C7B8, (q31_t)0x78E8CFB1, + (q31_t)0x29D34958, (q31_t)0x78F945C3, (q31_t)0x29A3C484, + (q31_t)0x7909A92C, (q31_t)0x29743945, (q31_t)0x7919F9EB, + (q31_t)0x2944A7A2, (q31_t)0x792A37FE, (q31_t)0x29150FA1, + (q31_t)0x793A6360, (q31_t)0x28E5714A, (q31_t)0x794A7C11, + (q31_t)0x28B5CCA5, (q31_t)0x795A820E, (q31_t)0x288621B9, + (q31_t)0x796A7554, (q31_t)0x2856708C, (q31_t)0x797A55E0, + (q31_t)0x2826B928, (q31_t)0x798A23B1, (q31_t)0x27F6FB92, + (q31_t)0x7999DEC3, (q31_t)0x27C737D2, (q31_t)0x79A98715, + (q31_t)0x27976DF1, (q31_t)0x79B91CA4, (q31_t)0x27679DF4, + (q31_t)0x79C89F6D, (q31_t)0x2737C7E3, (q31_t)0x79D80F6F, + (q31_t)0x2707EBC6, (q31_t)0x79E76CA6, (q31_t)0x26D809A5, + (q31_t)0x79F6B711, (q31_t)0x26A82185, (q31_t)0x7A05EEAD, + (q31_t)0x26783370, (q31_t)0x7A151377, (q31_t)0x26483F6C, + (q31_t)0x7A24256E, (q31_t)0x26184581, (q31_t)0x7A33248F, + (q31_t)0x25E845B5, (q31_t)0x7A4210D8, (q31_t)0x25B84012, + (q31_t)0x7A50EA46, (q31_t)0x2588349D, (q31_t)0x7A5FB0D8, + (q31_t)0x2558235E, (q31_t)0x7A6E648A, (q31_t)0x25280C5D, + (q31_t)0x7A7D055B, (q31_t)0x24F7EFA1, (q31_t)0x7A8B9348, + (q31_t)0x24C7CD32, (q31_t)0x7A9A0E4F, (q31_t)0x2497A517, + (q31_t)0x7AA8766E, (q31_t)0x24677757, (q31_t)0x7AB6CBA3, + (q31_t)0x243743FA, (q31_t)0x7AC50DEB, (q31_t)0x24070B07, + (q31_t)0x7AD33D45, (q31_t)0x23D6CC86, (q31_t)0x7AE159AE, + (q31_t)0x23A6887E, (q31_t)0x7AEF6323, (q31_t)0x23763EF7, + (q31_t)0x7AFD59A3, (q31_t)0x2345EFF7, (q31_t)0x7B0B3D2C, + (q31_t)0x23159B87, (q31_t)0x7B190DBB, (q31_t)0x22E541AE, + (q31_t)0x7B26CB4F, (q31_t)0x22B4E274, (q31_t)0x7B3475E4, + (q31_t)0x22847DDF, (q31_t)0x7B420D7A, (q31_t)0x225413F8, + (q31_t)0x7B4F920E, (q31_t)0x2223A4C5, (q31_t)0x7B5D039D, + (q31_t)0x21F3304E, (q31_t)0x7B6A6227, (q31_t)0x21C2B69C, + (q31_t)0x7B77ADA8, (q31_t)0x219237B4, (q31_t)0x7B84E61E, + (q31_t)0x2161B39F, (q31_t)0x7B920B89, (q31_t)0x21312A65, + (q31_t)0x7B9F1DE5, (q31_t)0x21009C0B, (q31_t)0x7BAC1D31, + (q31_t)0x20D0089B, (q31_t)0x7BB9096A, (q31_t)0x209F701C, + (q31_t)0x7BC5E28F, (q31_t)0x206ED295, (q31_t)0x7BD2A89E, + (q31_t)0x203E300D, (q31_t)0x7BDF5B94, (q31_t)0x200D888C, + (q31_t)0x7BEBFB70, (q31_t)0x1FDCDC1A, (q31_t)0x7BF88830, + (q31_t)0x1FAC2ABF, (q31_t)0x7C0501D1, (q31_t)0x1F7B7480, + (q31_t)0x7C116853, (q31_t)0x1F4AB967, (q31_t)0x7C1DBBB2, + (q31_t)0x1F19F97B, (q31_t)0x7C29FBEE, (q31_t)0x1EE934C2, + (q31_t)0x7C362904, (q31_t)0x1EB86B46, (q31_t)0x7C4242F2, + (q31_t)0x1E879D0C, (q31_t)0x7C4E49B6, (q31_t)0x1E56CA1E, + (q31_t)0x7C5A3D4F, (q31_t)0x1E25F281, (q31_t)0x7C661DBB, + (q31_t)0x1DF5163F, (q31_t)0x7C71EAF8, (q31_t)0x1DC4355D, + (q31_t)0x7C7DA504, (q31_t)0x1D934FE5, (q31_t)0x7C894BDD, + (q31_t)0x1D6265DD, (q31_t)0x7C94DF82, (q31_t)0x1D31774D, + (q31_t)0x7CA05FF1, (q31_t)0x1D00843C, (q31_t)0x7CABCD27, + (q31_t)0x1CCF8CB3, (q31_t)0x7CB72724, (q31_t)0x1C9E90B8, + (q31_t)0x7CC26DE5, (q31_t)0x1C6D9053, (q31_t)0x7CCDA168, + (q31_t)0x1C3C8B8C, (q31_t)0x7CD8C1AD, (q31_t)0x1C0B826A, + (q31_t)0x7CE3CEB1, (q31_t)0x1BDA74F5, (q31_t)0x7CEEC873, + (q31_t)0x1BA96334, (q31_t)0x7CF9AEF0, (q31_t)0x1B784D30, + (q31_t)0x7D048228, (q31_t)0x1B4732EF, (q31_t)0x7D0F4218, + (q31_t)0x1B161479, (q31_t)0x7D19EEBE, (q31_t)0x1AE4F1D6, + (q31_t)0x7D24881A, (q31_t)0x1AB3CB0C, (q31_t)0x7D2F0E2A, + (q31_t)0x1A82A025, (q31_t)0x7D3980EC, (q31_t)0x1A517127, + (q31_t)0x7D43E05E, (q31_t)0x1A203E1B, (q31_t)0x7D4E2C7E, + (q31_t)0x19EF0706, (q31_t)0x7D58654C, (q31_t)0x19BDCBF2, + (q31_t)0x7D628AC5, (q31_t)0x198C8CE6, (q31_t)0x7D6C9CE9, + (q31_t)0x195B49E9, (q31_t)0x7D769BB5, (q31_t)0x192A0303, + (q31_t)0x7D808727, (q31_t)0x18F8B83C, (q31_t)0x7D8A5F3F, + (q31_t)0x18C7699B, (q31_t)0x7D9423FB, (q31_t)0x18961727, + (q31_t)0x7D9DD55A, (q31_t)0x1864C0E9, (q31_t)0x7DA77359, + (q31_t)0x183366E8, (q31_t)0x7DB0FDF7, (q31_t)0x1802092C, + (q31_t)0x7DBA7534, (q31_t)0x17D0A7BB, (q31_t)0x7DC3D90D, + (q31_t)0x179F429F, (q31_t)0x7DCD2981, (q31_t)0x176DD9DE, + (q31_t)0x7DD6668E, (q31_t)0x173C6D80, (q31_t)0x7DDF9034, + (q31_t)0x170AFD8D, (q31_t)0x7DE8A670, (q31_t)0x16D98A0C, + (q31_t)0x7DF1A942, (q31_t)0x16A81305, (q31_t)0x7DFA98A7, + (q31_t)0x1676987F, (q31_t)0x7E03749F, (q31_t)0x16451A83, + (q31_t)0x7E0C3D29, (q31_t)0x16139917, (q31_t)0x7E14F242, + (q31_t)0x15E21444, (q31_t)0x7E1D93E9, (q31_t)0x15B08C11, + (q31_t)0x7E26221E, (q31_t)0x157F0086, (q31_t)0x7E2E9CDF, + (q31_t)0x154D71AA, (q31_t)0x7E37042A, (q31_t)0x151BDF85, + (q31_t)0x7E3F57FE, (q31_t)0x14EA4A1F, (q31_t)0x7E47985B, + (q31_t)0x14B8B17F, (q31_t)0x7E4FC53E, (q31_t)0x148715AD, + (q31_t)0x7E57DEA6, (q31_t)0x145576B1, (q31_t)0x7E5FE493, + (q31_t)0x1423D492, (q31_t)0x7E67D702, (q31_t)0x13F22F57, + (q31_t)0x7E6FB5F3, (q31_t)0x13C0870A, (q31_t)0x7E778165, + (q31_t)0x138EDBB0, (q31_t)0x7E7F3956, (q31_t)0x135D2D53, + (q31_t)0x7E86DDC5, (q31_t)0x132B7BF9, (q31_t)0x7E8E6EB1, + (q31_t)0x12F9C7AA, (q31_t)0x7E95EC19, (q31_t)0x12C8106E, + (q31_t)0x7E9D55FC, (q31_t)0x1296564D, (q31_t)0x7EA4AC58, + (q31_t)0x1264994E, (q31_t)0x7EABEF2C, (q31_t)0x1232D978, + (q31_t)0x7EB31E77, (q31_t)0x120116D4, (q31_t)0x7EBA3A39, + (q31_t)0x11CF516A, (q31_t)0x7EC1426F, (q31_t)0x119D8940, + (q31_t)0x7EC8371A, (q31_t)0x116BBE5F, (q31_t)0x7ECF1837, + (q31_t)0x1139F0CE, (q31_t)0x7ED5E5C6, (q31_t)0x11082096, + (q31_t)0x7EDC9FC6, (q31_t)0x10D64DBC, (q31_t)0x7EE34635, + (q31_t)0x10A4784A, (q31_t)0x7EE9D913, (q31_t)0x1072A047, + (q31_t)0x7EF0585F, (q31_t)0x1040C5BB, (q31_t)0x7EF6C418, + (q31_t)0x100EE8AD, (q31_t)0x7EFD1C3C, (q31_t)0x0FDD0925, + (q31_t)0x7F0360CB, (q31_t)0x0FAB272B, (q31_t)0x7F0991C3, + (q31_t)0x0F7942C6, (q31_t)0x7F0FAF24, (q31_t)0x0F475BFE, + (q31_t)0x7F15B8EE, (q31_t)0x0F1572DC, (q31_t)0x7F1BAF1E, + (q31_t)0x0EE38765, (q31_t)0x7F2191B4, (q31_t)0x0EB199A3, + (q31_t)0x7F2760AF, (q31_t)0x0E7FA99D, (q31_t)0x7F2D1C0E, + (q31_t)0x0E4DB75B, (q31_t)0x7F32C3D0, (q31_t)0x0E1BC2E3, + (q31_t)0x7F3857F5, (q31_t)0x0DE9CC3F, (q31_t)0x7F3DD87C, + (q31_t)0x0DB7D376, (q31_t)0x7F434563, (q31_t)0x0D85D88F, + (q31_t)0x7F489EAA, (q31_t)0x0D53DB92, (q31_t)0x7F4DE450, + (q31_t)0x0D21DC87, (q31_t)0x7F531654, (q31_t)0x0CEFDB75, + (q31_t)0x7F5834B6, (q31_t)0x0CBDD865, (q31_t)0x7F5D3F75, + (q31_t)0x0C8BD35E, (q31_t)0x7F62368F, (q31_t)0x0C59CC67, + (q31_t)0x7F671A04, (q31_t)0x0C27C389, (q31_t)0x7F6BE9D4, + (q31_t)0x0BF5B8CB, (q31_t)0x7F70A5FD, (q31_t)0x0BC3AC35, + (q31_t)0x7F754E7F, (q31_t)0x0B919DCE, (q31_t)0x7F79E35A, + (q31_t)0x0B5F8D9F, (q31_t)0x7F7E648B, (q31_t)0x0B2D7BAE, + (q31_t)0x7F82D214, (q31_t)0x0AFB6805, (q31_t)0x7F872BF3, + (q31_t)0x0AC952AA, (q31_t)0x7F8B7226, (q31_t)0x0A973BA5, + (q31_t)0x7F8FA4AF, (q31_t)0x0A6522FE, (q31_t)0x7F93C38C, + (q31_t)0x0A3308BC, (q31_t)0x7F97CEBC, (q31_t)0x0A00ECE8, + (q31_t)0x7F9BC63F, (q31_t)0x09CECF89, (q31_t)0x7F9FAA15, + (q31_t)0x099CB0A7, (q31_t)0x7FA37A3C, (q31_t)0x096A9049, + (q31_t)0x7FA736B4, (q31_t)0x09386E77, (q31_t)0x7FAADF7C, + (q31_t)0x09064B3A, (q31_t)0x7FAE7494, (q31_t)0x08D42698, + (q31_t)0x7FB1F5FC, (q31_t)0x08A2009A, (q31_t)0x7FB563B2, + (q31_t)0x086FD947, (q31_t)0x7FB8BDB7, (q31_t)0x083DB0A7, + (q31_t)0x7FBC040A, (q31_t)0x080B86C1, (q31_t)0x7FBF36A9, + (q31_t)0x07D95B9E, (q31_t)0x7FC25596, (q31_t)0x07A72F45, + (q31_t)0x7FC560CF, (q31_t)0x077501BE, (q31_t)0x7FC85853, + (q31_t)0x0742D310, (q31_t)0x7FCB3C23, (q31_t)0x0710A344, + (q31_t)0x7FCE0C3E, (q31_t)0x06DE7261, (q31_t)0x7FD0C8A3, + (q31_t)0x06AC406F, (q31_t)0x7FD37152, (q31_t)0x067A0D75, + (q31_t)0x7FD6064B, (q31_t)0x0647D97C, (q31_t)0x7FD8878D, + (q31_t)0x0615A48A, (q31_t)0x7FDAF518, (q31_t)0x05E36EA9, + (q31_t)0x7FDD4EEC, (q31_t)0x05B137DF, (q31_t)0x7FDF9508, + (q31_t)0x057F0034, (q31_t)0x7FE1C76B, (q31_t)0x054CC7B0, + (q31_t)0x7FE3E616, (q31_t)0x051A8E5C, (q31_t)0x7FE5F108, + (q31_t)0x04E8543D, (q31_t)0x7FE7E840, (q31_t)0x04B6195D, + (q31_t)0x7FE9CBC0, (q31_t)0x0483DDC3, (q31_t)0x7FEB9B85, + (q31_t)0x0451A176, (q31_t)0x7FED5790, (q31_t)0x041F647F, + (q31_t)0x7FEEFFE1, (q31_t)0x03ED26E6, (q31_t)0x7FF09477, + (q31_t)0x03BAE8B1, (q31_t)0x7FF21553, (q31_t)0x0388A9E9, + (q31_t)0x7FF38273, (q31_t)0x03566A96, (q31_t)0x7FF4DBD8, + (q31_t)0x03242ABF, (q31_t)0x7FF62182, (q31_t)0x02F1EA6B, + (q31_t)0x7FF7536F, (q31_t)0x02BFA9A4, (q31_t)0x7FF871A1, + (q31_t)0x028D6870, (q31_t)0x7FF97C17, (q31_t)0x025B26D7, + (q31_t)0x7FFA72D1, (q31_t)0x0228E4E1, (q31_t)0x7FFB55CE, + (q31_t)0x01F6A296, (q31_t)0x7FFC250F, (q31_t)0x01C45FFE, + (q31_t)0x7FFCE093, (q31_t)0x01921D1F, (q31_t)0x7FFD885A, + (q31_t)0x015FDA03, (q31_t)0x7FFE1C64, (q31_t)0x012D96B0, + (q31_t)0x7FFE9CB2, (q31_t)0x00FB532F, (q31_t)0x7FFF0942, + (q31_t)0x00C90F88, (q31_t)0x7FFF6216, (q31_t)0x0096CBC1, + (q31_t)0x7FFFA72C, (q31_t)0x006487E3, (q31_t)0x7FFFD885, + (q31_t)0x003243F5, (q31_t)0x7FFFF621, (q31_t)0x00000000, + (q31_t)0x7FFFFFFF, (q31_t)0xFFCDBC0A, (q31_t)0x7FFFF621, + (q31_t)0xFF9B781D, (q31_t)0x7FFFD885, (q31_t)0xFF69343E, + (q31_t)0x7FFFA72C, (q31_t)0xFF36F078, (q31_t)0x7FFF6216, + (q31_t)0xFF04ACD0, (q31_t)0x7FFF0942, (q31_t)0xFED2694F, + (q31_t)0x7FFE9CB2, (q31_t)0xFEA025FC, (q31_t)0x7FFE1C64, + (q31_t)0xFE6DE2E0, (q31_t)0x7FFD885A, (q31_t)0xFE3BA001, + (q31_t)0x7FFCE093, (q31_t)0xFE095D69, (q31_t)0x7FFC250F, + (q31_t)0xFDD71B1E, (q31_t)0x7FFB55CE, (q31_t)0xFDA4D928, + (q31_t)0x7FFA72D1, (q31_t)0xFD72978F, (q31_t)0x7FF97C17, + (q31_t)0xFD40565B, (q31_t)0x7FF871A1, (q31_t)0xFD0E1594, + (q31_t)0x7FF7536F, (q31_t)0xFCDBD541, (q31_t)0x7FF62182, + (q31_t)0xFCA99569, (q31_t)0x7FF4DBD8, (q31_t)0xFC775616, + (q31_t)0x7FF38273, (q31_t)0xFC45174E, (q31_t)0x7FF21553, + (q31_t)0xFC12D919, (q31_t)0x7FF09477, (q31_t)0xFBE09B80, + (q31_t)0x7FEEFFE1, (q31_t)0xFBAE5E89, (q31_t)0x7FED5790, + (q31_t)0xFB7C223C, (q31_t)0x7FEB9B85, (q31_t)0xFB49E6A2, + (q31_t)0x7FE9CBC0, (q31_t)0xFB17ABC2, (q31_t)0x7FE7E840, + (q31_t)0xFAE571A4, (q31_t)0x7FE5F108, (q31_t)0xFAB3384F, + (q31_t)0x7FE3E616, (q31_t)0xFA80FFCB, (q31_t)0x7FE1C76B, + (q31_t)0xFA4EC820, (q31_t)0x7FDF9508, (q31_t)0xFA1C9156, + (q31_t)0x7FDD4EEC, (q31_t)0xF9EA5B75, (q31_t)0x7FDAF518, + (q31_t)0xF9B82683, (q31_t)0x7FD8878D, (q31_t)0xF985F28A, + (q31_t)0x7FD6064B, (q31_t)0xF953BF90, (q31_t)0x7FD37152, + (q31_t)0xF9218D9E, (q31_t)0x7FD0C8A3, (q31_t)0xF8EF5CBB, + (q31_t)0x7FCE0C3E, (q31_t)0xF8BD2CEF, (q31_t)0x7FCB3C23, + (q31_t)0xF88AFE41, (q31_t)0x7FC85853, (q31_t)0xF858D0BA, + (q31_t)0x7FC560CF, (q31_t)0xF826A461, (q31_t)0x7FC25596, + (q31_t)0xF7F4793E, (q31_t)0x7FBF36A9, (q31_t)0xF7C24F58, + (q31_t)0x7FBC040A, (q31_t)0xF79026B8, (q31_t)0x7FB8BDB7, + (q31_t)0xF75DFF65, (q31_t)0x7FB563B2, (q31_t)0xF72BD967, + (q31_t)0x7FB1F5FC, (q31_t)0xF6F9B4C5, (q31_t)0x7FAE7494, + (q31_t)0xF6C79188, (q31_t)0x7FAADF7C, (q31_t)0xF6956FB6, + (q31_t)0x7FA736B4, (q31_t)0xF6634F58, (q31_t)0x7FA37A3C, + (q31_t)0xF6313076, (q31_t)0x7F9FAA15, (q31_t)0xF5FF1317, + (q31_t)0x7F9BC63F, (q31_t)0xF5CCF743, (q31_t)0x7F97CEBC, + (q31_t)0xF59ADD01, (q31_t)0x7F93C38C, (q31_t)0xF568C45A, + (q31_t)0x7F8FA4AF, (q31_t)0xF536AD55, (q31_t)0x7F8B7226, + (q31_t)0xF50497FA, (q31_t)0x7F872BF3, (q31_t)0xF4D28451, + (q31_t)0x7F82D214, (q31_t)0xF4A07260, (q31_t)0x7F7E648B, + (q31_t)0xF46E6231, (q31_t)0x7F79E35A, (q31_t)0xF43C53CA, + (q31_t)0x7F754E7F, (q31_t)0xF40A4734, (q31_t)0x7F70A5FD, + (q31_t)0xF3D83C76, (q31_t)0x7F6BE9D4, (q31_t)0xF3A63398, + (q31_t)0x7F671A04, (q31_t)0xF3742CA1, (q31_t)0x7F62368F, + (q31_t)0xF342279A, (q31_t)0x7F5D3F75, (q31_t)0xF310248A, + (q31_t)0x7F5834B6, (q31_t)0xF2DE2378, (q31_t)0x7F531654, + (q31_t)0xF2AC246D, (q31_t)0x7F4DE450, (q31_t)0xF27A2770, + (q31_t)0x7F489EAA, (q31_t)0xF2482C89, (q31_t)0x7F434563, + (q31_t)0xF21633C0, (q31_t)0x7F3DD87C, (q31_t)0xF1E43D1C, + (q31_t)0x7F3857F5, (q31_t)0xF1B248A5, (q31_t)0x7F32C3D0, + (q31_t)0xF1805662, (q31_t)0x7F2D1C0E, (q31_t)0xF14E665C, + (q31_t)0x7F2760AF, (q31_t)0xF11C789A, (q31_t)0x7F2191B4, + (q31_t)0xF0EA8D23, (q31_t)0x7F1BAF1E, (q31_t)0xF0B8A401, + (q31_t)0x7F15B8EE, (q31_t)0xF086BD39, (q31_t)0x7F0FAF24, + (q31_t)0xF054D8D4, (q31_t)0x7F0991C3, (q31_t)0xF022F6DA, + (q31_t)0x7F0360CB, (q31_t)0xEFF11752, (q31_t)0x7EFD1C3C, + (q31_t)0xEFBF3A44, (q31_t)0x7EF6C418, (q31_t)0xEF8D5FB8, + (q31_t)0x7EF0585F, (q31_t)0xEF5B87B5, (q31_t)0x7EE9D913, + (q31_t)0xEF29B243, (q31_t)0x7EE34635, (q31_t)0xEEF7DF6A, + (q31_t)0x7EDC9FC6, (q31_t)0xEEC60F31, (q31_t)0x7ED5E5C6, + (q31_t)0xEE9441A0, (q31_t)0x7ECF1837, (q31_t)0xEE6276BF, + (q31_t)0x7EC8371A, (q31_t)0xEE30AE95, (q31_t)0x7EC1426F, + (q31_t)0xEDFEE92B, (q31_t)0x7EBA3A39, (q31_t)0xEDCD2687, + (q31_t)0x7EB31E77, (q31_t)0xED9B66B2, (q31_t)0x7EABEF2C, + (q31_t)0xED69A9B2, (q31_t)0x7EA4AC58, (q31_t)0xED37EF91, + (q31_t)0x7E9D55FC, (q31_t)0xED063855, (q31_t)0x7E95EC19, + (q31_t)0xECD48406, (q31_t)0x7E8E6EB1, (q31_t)0xECA2D2AC, + (q31_t)0x7E86DDC5, (q31_t)0xEC71244F, (q31_t)0x7E7F3956, + (q31_t)0xEC3F78F5, (q31_t)0x7E778165, (q31_t)0xEC0DD0A8, + (q31_t)0x7E6FB5F3, (q31_t)0xEBDC2B6D, (q31_t)0x7E67D702, + (q31_t)0xEBAA894E, (q31_t)0x7E5FE493, (q31_t)0xEB78EA52, + (q31_t)0x7E57DEA6, (q31_t)0xEB474E80, (q31_t)0x7E4FC53E, + (q31_t)0xEB15B5E0, (q31_t)0x7E47985B, (q31_t)0xEAE4207A, + (q31_t)0x7E3F57FE, (q31_t)0xEAB28E55, (q31_t)0x7E37042A, + (q31_t)0xEA80FF79, (q31_t)0x7E2E9CDF, (q31_t)0xEA4F73EE, + (q31_t)0x7E26221E, (q31_t)0xEA1DEBBB, (q31_t)0x7E1D93E9, + (q31_t)0xE9EC66E8, (q31_t)0x7E14F242, (q31_t)0xE9BAE57C, + (q31_t)0x7E0C3D29, (q31_t)0xE9896780, (q31_t)0x7E03749F, + (q31_t)0xE957ECFB, (q31_t)0x7DFA98A7, (q31_t)0xE92675F4, + (q31_t)0x7DF1A942, (q31_t)0xE8F50273, (q31_t)0x7DE8A670, + (q31_t)0xE8C3927F, (q31_t)0x7DDF9034, (q31_t)0xE8922621, + (q31_t)0x7DD6668E, (q31_t)0xE860BD60, (q31_t)0x7DCD2981, + (q31_t)0xE82F5844, (q31_t)0x7DC3D90D, (q31_t)0xE7FDF6D3, + (q31_t)0x7DBA7534, (q31_t)0xE7CC9917, (q31_t)0x7DB0FDF7, + (q31_t)0xE79B3F16, (q31_t)0x7DA77359, (q31_t)0xE769E8D8, + (q31_t)0x7D9DD55A, (q31_t)0xE7389664, (q31_t)0x7D9423FB, + (q31_t)0xE70747C3, (q31_t)0x7D8A5F3F, (q31_t)0xE6D5FCFC, + (q31_t)0x7D808727, (q31_t)0xE6A4B616, (q31_t)0x7D769BB5, + (q31_t)0xE6737319, (q31_t)0x7D6C9CE9, (q31_t)0xE642340D, + (q31_t)0x7D628AC5, (q31_t)0xE610F8F9, (q31_t)0x7D58654C, + (q31_t)0xE5DFC1E4, (q31_t)0x7D4E2C7E, (q31_t)0xE5AE8ED8, + (q31_t)0x7D43E05E, (q31_t)0xE57D5FDA, (q31_t)0x7D3980EC, + (q31_t)0xE54C34F3, (q31_t)0x7D2F0E2A, (q31_t)0xE51B0E2A, + (q31_t)0x7D24881A, (q31_t)0xE4E9EB86, (q31_t)0x7D19EEBE, + (q31_t)0xE4B8CD10, (q31_t)0x7D0F4218, (q31_t)0xE487B2CF, + (q31_t)0x7D048228, (q31_t)0xE4569CCB, (q31_t)0x7CF9AEF0, + (q31_t)0xE4258B0A, (q31_t)0x7CEEC873, (q31_t)0xE3F47D95, + (q31_t)0x7CE3CEB1, (q31_t)0xE3C37473, (q31_t)0x7CD8C1AD, + (q31_t)0xE3926FAC, (q31_t)0x7CCDA168, (q31_t)0xE3616F47, + (q31_t)0x7CC26DE5, (q31_t)0xE330734C, (q31_t)0x7CB72724, + (q31_t)0xE2FF7BC3, (q31_t)0x7CABCD27, (q31_t)0xE2CE88B2, + (q31_t)0x7CA05FF1, (q31_t)0xE29D9A22, (q31_t)0x7C94DF82, + (q31_t)0xE26CB01A, (q31_t)0x7C894BDD, (q31_t)0xE23BCAA2, + (q31_t)0x7C7DA504, (q31_t)0xE20AE9C1, (q31_t)0x7C71EAF8, + (q31_t)0xE1DA0D7E, (q31_t)0x7C661DBB, (q31_t)0xE1A935E1, + (q31_t)0x7C5A3D4F, (q31_t)0xE17862F3, (q31_t)0x7C4E49B6, + (q31_t)0xE14794B9, (q31_t)0x7C4242F2, (q31_t)0xE116CB3D, + (q31_t)0x7C362904, (q31_t)0xE0E60684, (q31_t)0x7C29FBEE, + (q31_t)0xE0B54698, (q31_t)0x7C1DBBB2, (q31_t)0xE0848B7F, + (q31_t)0x7C116853, (q31_t)0xE053D541, (q31_t)0x7C0501D1, + (q31_t)0xE02323E5, (q31_t)0x7BF88830, (q31_t)0xDFF27773, + (q31_t)0x7BEBFB70, (q31_t)0xDFC1CFF2, (q31_t)0x7BDF5B94, + (q31_t)0xDF912D6A, (q31_t)0x7BD2A89E, (q31_t)0xDF608FE3, + (q31_t)0x7BC5E28F, (q31_t)0xDF2FF764, (q31_t)0x7BB9096A, + (q31_t)0xDEFF63F4, (q31_t)0x7BAC1D31, (q31_t)0xDECED59B, + (q31_t)0x7B9F1DE5, (q31_t)0xDE9E4C60, (q31_t)0x7B920B89, + (q31_t)0xDE6DC84B, (q31_t)0x7B84E61E, (q31_t)0xDE3D4963, + (q31_t)0x7B77ADA8, (q31_t)0xDE0CCFB1, (q31_t)0x7B6A6227, + (q31_t)0xDDDC5B3A, (q31_t)0x7B5D039D, (q31_t)0xDDABEC07, + (q31_t)0x7B4F920E, (q31_t)0xDD7B8220, (q31_t)0x7B420D7A, + (q31_t)0xDD4B1D8B, (q31_t)0x7B3475E4, (q31_t)0xDD1ABE51, + (q31_t)0x7B26CB4F, (q31_t)0xDCEA6478, (q31_t)0x7B190DBB, + (q31_t)0xDCBA1008, (q31_t)0x7B0B3D2C, (q31_t)0xDC89C108, + (q31_t)0x7AFD59A3, (q31_t)0xDC597781, (q31_t)0x7AEF6323, + (q31_t)0xDC293379, (q31_t)0x7AE159AE, (q31_t)0xDBF8F4F8, + (q31_t)0x7AD33D45, (q31_t)0xDBC8BC05, (q31_t)0x7AC50DEB, + (q31_t)0xDB9888A8, (q31_t)0x7AB6CBA3, (q31_t)0xDB685AE8, + (q31_t)0x7AA8766E, (q31_t)0xDB3832CD, (q31_t)0x7A9A0E4F, + (q31_t)0xDB08105E, (q31_t)0x7A8B9348, (q31_t)0xDAD7F3A2, + (q31_t)0x7A7D055B, (q31_t)0xDAA7DCA1, (q31_t)0x7A6E648A, + (q31_t)0xDA77CB62, (q31_t)0x7A5FB0D8, (q31_t)0xDA47BFED, + (q31_t)0x7A50EA46, (q31_t)0xDA17BA4A, (q31_t)0x7A4210D8, + (q31_t)0xD9E7BA7E, (q31_t)0x7A33248F, (q31_t)0xD9B7C093, + (q31_t)0x7A24256E, (q31_t)0xD987CC8F, (q31_t)0x7A151377, + (q31_t)0xD957DE7A, (q31_t)0x7A05EEAD, (q31_t)0xD927F65B, + (q31_t)0x79F6B711, (q31_t)0xD8F81439, (q31_t)0x79E76CA6, + (q31_t)0xD8C8381C, (q31_t)0x79D80F6F, (q31_t)0xD898620C, + (q31_t)0x79C89F6D, (q31_t)0xD868920F, (q31_t)0x79B91CA4, + (q31_t)0xD838C82D, (q31_t)0x79A98715, (q31_t)0xD809046D, + (q31_t)0x7999DEC3, (q31_t)0xD7D946D7, (q31_t)0x798A23B1, + (q31_t)0xD7A98F73, (q31_t)0x797A55E0, (q31_t)0xD779DE46, + (q31_t)0x796A7554, (q31_t)0xD74A335A, (q31_t)0x795A820E, + (q31_t)0xD71A8EB5, (q31_t)0x794A7C11, (q31_t)0xD6EAF05E, + (q31_t)0x793A6360, (q31_t)0xD6BB585D, (q31_t)0x792A37FE, + (q31_t)0xD68BC6BA, (q31_t)0x7919F9EB, (q31_t)0xD65C3B7B, + (q31_t)0x7909A92C, (q31_t)0xD62CB6A7, (q31_t)0x78F945C3, + (q31_t)0xD5FD3847, (q31_t)0x78E8CFB1, (q31_t)0xD5CDC062, + (q31_t)0x78D846FB, (q31_t)0xD59E4EFE, (q31_t)0x78C7ABA1, + (q31_t)0xD56EE424, (q31_t)0x78B6FDA8, (q31_t)0xD53F7FDA, + (q31_t)0x78A63D10, (q31_t)0xD5102227, (q31_t)0x789569DE, + (q31_t)0xD4E0CB14, (q31_t)0x78848413, (q31_t)0xD4B17AA7, + (q31_t)0x78738BB3, (q31_t)0xD48230E8, (q31_t)0x786280BF, + (q31_t)0xD452EDDE, (q31_t)0x7851633B, (q31_t)0xD423B190, + (q31_t)0x78403328, (q31_t)0xD3F47C06, (q31_t)0x782EF08B, + (q31_t)0xD3C54D46, (q31_t)0x781D9B64, (q31_t)0xD3962559, + (q31_t)0x780C33B8, (q31_t)0xD3670445, (q31_t)0x77FAB988, + (q31_t)0xD337EA12, (q31_t)0x77E92CD8, (q31_t)0xD308D6C6, + (q31_t)0x77D78DAA, (q31_t)0xD2D9CA6A, (q31_t)0x77C5DC01, + (q31_t)0xD2AAC504, (q31_t)0x77B417DF, (q31_t)0xD27BC69C, + (q31_t)0x77A24148, (q31_t)0xD24CCF38, (q31_t)0x7790583D, + (q31_t)0xD21DDEE1, (q31_t)0x777E5CC3, (q31_t)0xD1EEF59E, + (q31_t)0x776C4EDB, (q31_t)0xD1C01374, (q31_t)0x775A2E88, + (q31_t)0xD191386D, (q31_t)0x7747FBCE, (q31_t)0xD162648F, + (q31_t)0x7735B6AE, (q31_t)0xD13397E1, (q31_t)0x77235F2D, + (q31_t)0xD104D26B, (q31_t)0x7710F54B, (q31_t)0xD0D61433, + (q31_t)0x76FE790E, (q31_t)0xD0A75D42, (q31_t)0x76EBEA77, + (q31_t)0xD078AD9D, (q31_t)0x76D94988, (q31_t)0xD04A054D, + (q31_t)0x76C69646, (q31_t)0xD01B6459, (q31_t)0x76B3D0B3, + (q31_t)0xCFECCAC7, (q31_t)0x76A0F8D2, (q31_t)0xCFBE389F, + (q31_t)0x768E0EA5, (q31_t)0xCF8FADE8, (q31_t)0x767B1230, + (q31_t)0xCF612AAA, (q31_t)0x76680376, (q31_t)0xCF32AEEB, + (q31_t)0x7654E279, (q31_t)0xCF043AB2, (q31_t)0x7641AF3C, + (q31_t)0xCED5CE08, (q31_t)0x762E69C3, (q31_t)0xCEA768F2, + (q31_t)0x761B1211, (q31_t)0xCE790B78, (q31_t)0x7607A827, + (q31_t)0xCE4AB5A2, (q31_t)0x75F42C0A, (q31_t)0xCE1C6776, + (q31_t)0x75E09DBD, (q31_t)0xCDEE20FC, (q31_t)0x75CCFD42, + (q31_t)0xCDBFE23A, (q31_t)0x75B94A9C, (q31_t)0xCD91AB38, + (q31_t)0x75A585CF, (q31_t)0xCD637BFD, (q31_t)0x7591AEDD, + (q31_t)0xCD355490, (q31_t)0x757DC5CA, (q31_t)0xCD0734F8, + (q31_t)0x7569CA98, (q31_t)0xCCD91D3D, (q31_t)0x7555BD4B, + (q31_t)0xCCAB0D65, (q31_t)0x75419DE6, (q31_t)0xCC7D0577, + (q31_t)0x752D6C6C, (q31_t)0xCC4F057B, (q31_t)0x751928E0, + (q31_t)0xCC210D78, (q31_t)0x7504D345, (q31_t)0xCBF31D75, + (q31_t)0x74F06B9E, (q31_t)0xCBC53578, (q31_t)0x74DBF1EF, + (q31_t)0xCB975589, (q31_t)0x74C7663A, (q31_t)0xCB697DB0, + (q31_t)0x74B2C883, (q31_t)0xCB3BADF2, (q31_t)0x749E18CD, + (q31_t)0xCB0DE658, (q31_t)0x7489571B, (q31_t)0xCAE026E8, + (q31_t)0x74748371, (q31_t)0xCAB26FA9, (q31_t)0x745F9DD1, + (q31_t)0xCA84C0A2, (q31_t)0x744AA63E, (q31_t)0xCA5719DB, + (q31_t)0x74359CBD, (q31_t)0xCA297B5A, (q31_t)0x74208150, + (q31_t)0xC9FBE527, (q31_t)0x740B53FA, (q31_t)0xC9CE5748, + (q31_t)0x73F614C0, (q31_t)0xC9A0D1C4, (q31_t)0x73E0C3A3, + (q31_t)0xC97354A3, (q31_t)0x73CB60A7, (q31_t)0xC945DFEC, + (q31_t)0x73B5EBD0, (q31_t)0xC91873A5, (q31_t)0x73A06522, + (q31_t)0xC8EB0FD6, (q31_t)0x738ACC9E, (q31_t)0xC8BDB485, + (q31_t)0x73752249, (q31_t)0xC89061BA, (q31_t)0x735F6626, + (q31_t)0xC863177B, (q31_t)0x73499838, (q31_t)0xC835D5D0, + (q31_t)0x7333B883, (q31_t)0xC8089CBF, (q31_t)0x731DC709, + (q31_t)0xC7DB6C50, (q31_t)0x7307C3D0, (q31_t)0xC7AE4489, + (q31_t)0x72F1AED8, (q31_t)0xC7812571, (q31_t)0x72DB8828, + (q31_t)0xC7540F10, (q31_t)0x72C54FC0, (q31_t)0xC727016C, + (q31_t)0x72AF05A6, (q31_t)0xC6F9FC8D, (q31_t)0x7298A9DC, + (q31_t)0xC6CD0079, (q31_t)0x72823C66, (q31_t)0xC6A00D36, + (q31_t)0x726BBD48, (q31_t)0xC67322CD, (q31_t)0x72552C84, + (q31_t)0xC6464144, (q31_t)0x723E8A1F, (q31_t)0xC61968A2, + (q31_t)0x7227D61C, (q31_t)0xC5EC98ED, (q31_t)0x7211107D, + (q31_t)0xC5BFD22E, (q31_t)0x71FA3948, (q31_t)0xC593146A, + (q31_t)0x71E3507F, (q31_t)0xC5665FA8, (q31_t)0x71CC5626, + (q31_t)0xC539B3F0, (q31_t)0x71B54A40, (q31_t)0xC50D1148, + (q31_t)0x719E2CD2, (q31_t)0xC4E077B8, (q31_t)0x7186FDDE, + (q31_t)0xC4B3E746, (q31_t)0x716FBD68, (q31_t)0xC4875FF8, + (q31_t)0x71586B73, (q31_t)0xC45AE1D7, (q31_t)0x71410804, + (q31_t)0xC42E6CE8, (q31_t)0x7129931E, (q31_t)0xC4020132, + (q31_t)0x71120CC5, (q31_t)0xC3D59EBD, (q31_t)0x70FA74FB, + (q31_t)0xC3A9458F, (q31_t)0x70E2CBC6, (q31_t)0xC37CF5B0, + (q31_t)0x70CB1127, (q31_t)0xC350AF25, (q31_t)0x70B34524, + (q31_t)0xC32471F6, (q31_t)0x709B67C0, (q31_t)0xC2F83E2A, + (q31_t)0x708378FE, (q31_t)0xC2CC13C7, (q31_t)0x706B78E3, + (q31_t)0xC29FF2D4, (q31_t)0x70536771, (q31_t)0xC273DB58, + (q31_t)0x703B44AC, (q31_t)0xC247CD5A, (q31_t)0x70231099, + (q31_t)0xC21BC8E0, (q31_t)0x700ACB3B, (q31_t)0xC1EFCDF2, + (q31_t)0x6FF27496, (q31_t)0xC1C3DC96, (q31_t)0x6FDA0CAD, + (q31_t)0xC197F4D3, (q31_t)0x6FC19385, (q31_t)0xC16C16B0, + (q31_t)0x6FA90920, (q31_t)0xC1404233, (q31_t)0x6F906D84, + (q31_t)0xC1147763, (q31_t)0x6F77C0B3, (q31_t)0xC0E8B648, + (q31_t)0x6F5F02B1, (q31_t)0xC0BCFEE7, (q31_t)0x6F463383, + (q31_t)0xC0915147, (q31_t)0x6F2D532C, (q31_t)0xC065AD70, + (q31_t)0x6F1461AF, (q31_t)0xC03A1368, (q31_t)0x6EFB5F12, + (q31_t)0xC00E8335, (q31_t)0x6EE24B57, (q31_t)0xBFE2FCDF, + (q31_t)0x6EC92682, (q31_t)0xBFB7806C, (q31_t)0x6EAFF098, + (q31_t)0xBF8C0DE2, (q31_t)0x6E96A99C, (q31_t)0xBF60A54A, + (q31_t)0x6E7D5193, (q31_t)0xBF3546A8, (q31_t)0x6E63E87F, + (q31_t)0xBF09F204, (q31_t)0x6E4A6E65, (q31_t)0xBEDEA765, + (q31_t)0x6E30E349, (q31_t)0xBEB366D1, (q31_t)0x6E17472F, + (q31_t)0xBE88304F, (q31_t)0x6DFD9A1B, (q31_t)0xBE5D03E5, + (q31_t)0x6DE3DC11, (q31_t)0xBE31E19B, (q31_t)0x6DCA0D14, + (q31_t)0xBE06C977, (q31_t)0x6DB02D29, (q31_t)0xBDDBBB7F, + (q31_t)0x6D963C54, (q31_t)0xBDB0B7BA, (q31_t)0x6D7C3A98, + (q31_t)0xBD85BE2F, (q31_t)0x6D6227FA, (q31_t)0xBD5ACEE5, + (q31_t)0x6D48047E, (q31_t)0xBD2FE9E1, (q31_t)0x6D2DD027, + (q31_t)0xBD050F2C, (q31_t)0x6D138AFA, (q31_t)0xBCDA3ECA, + (q31_t)0x6CF934FB, (q31_t)0xBCAF78C3, (q31_t)0x6CDECE2E, + (q31_t)0xBC84BD1E, (q31_t)0x6CC45697, (q31_t)0xBC5A0BE1, + (q31_t)0x6CA9CE3A, (q31_t)0xBC2F6513, (q31_t)0x6C8F351C, + (q31_t)0xBC04C8BA, (q31_t)0x6C748B3F, (q31_t)0xBBDA36DC, + (q31_t)0x6C59D0A9, (q31_t)0xBBAFAF81, (q31_t)0x6C3F055D, + (q31_t)0xBB8532AF, (q31_t)0x6C242960, (q31_t)0xBB5AC06C, + (q31_t)0x6C093CB6, (q31_t)0xBB3058C0, (q31_t)0x6BEE3F62, + (q31_t)0xBB05FBB0, (q31_t)0x6BD3316A, (q31_t)0xBADBA943, + (q31_t)0x6BB812D0, (q31_t)0xBAB1617F, (q31_t)0x6B9CE39B, + (q31_t)0xBA87246C, (q31_t)0x6B81A3CD, (q31_t)0xBA5CF210, + (q31_t)0x6B66536A, (q31_t)0xBA32CA70, (q31_t)0x6B4AF278, + (q31_t)0xBA08AD94, (q31_t)0x6B2F80FA, (q31_t)0xB9DE9B83, + (q31_t)0x6B13FEF5, (q31_t)0xB9B49442, (q31_t)0x6AF86C6C, + (q31_t)0xB98A97D8, (q31_t)0x6ADCC964, (q31_t)0xB960A64B, + (q31_t)0x6AC115E1, (q31_t)0xB936BFA3, (q31_t)0x6AA551E8, + (q31_t)0xB90CE3E6, (q31_t)0x6A897D7D, (q31_t)0xB8E31319, + (q31_t)0x6A6D98A4, (q31_t)0xB8B94D44, (q31_t)0x6A51A361, + (q31_t)0xB88F926C, (q31_t)0x6A359DB9, (q31_t)0xB865E299, + (q31_t)0x6A1987B0, (q31_t)0xB83C3DD1, (q31_t)0x69FD614A, + (q31_t)0xB812A419, (q31_t)0x69E12A8C, (q31_t)0xB7E9157A, + (q31_t)0x69C4E37A, (q31_t)0xB7BF91F8, (q31_t)0x69A88C18, + (q31_t)0xB796199B, (q31_t)0x698C246C, (q31_t)0xB76CAC68, + (q31_t)0x696FAC78, (q31_t)0xB7434A67, (q31_t)0x69532442, + (q31_t)0xB719F39D, (q31_t)0x69368BCE, (q31_t)0xB6F0A811, + (q31_t)0x6919E320, (q31_t)0xB6C767CA, (q31_t)0x68FD2A3D, + (q31_t)0xB69E32CD, (q31_t)0x68E06129, (q31_t)0xB6750921, + (q31_t)0x68C387E9, (q31_t)0xB64BEACC, (q31_t)0x68A69E81, + (q31_t)0xB622D7D5, (q31_t)0x6889A4F5, (q31_t)0xB5F9D042, + (q31_t)0x686C9B4B, (q31_t)0xB5D0D41A, (q31_t)0x684F8186, + (q31_t)0xB5A7E362, (q31_t)0x683257AA, (q31_t)0xB57EFE21, + (q31_t)0x68151DBE, (q31_t)0xB556245E, (q31_t)0x67F7D3C4, + (q31_t)0xB52D561E, (q31_t)0x67DA79C2, (q31_t)0xB5049368, + (q31_t)0x67BD0FBC, (q31_t)0xB4DBDC42, (q31_t)0x679F95B7, + (q31_t)0xB4B330B2, (q31_t)0x67820BB6, (q31_t)0xB48A90C0, + (q31_t)0x676471C0, (q31_t)0xB461FC70, (q31_t)0x6746C7D7, + (q31_t)0xB43973C9, (q31_t)0x67290E02, (q31_t)0xB410F6D2, + (q31_t)0x670B4443, (q31_t)0xB3E88591, (q31_t)0x66ED6AA1, + (q31_t)0xB3C0200C, (q31_t)0x66CF811F, (q31_t)0xB397C649, + (q31_t)0x66B187C3, (q31_t)0xB36F784E, (q31_t)0x66937E90, + (q31_t)0xB3473622, (q31_t)0x6675658C, (q31_t)0xB31EFFCB, + (q31_t)0x66573CBB, (q31_t)0xB2F6D54F, (q31_t)0x66390422, + (q31_t)0xB2CEB6B5, (q31_t)0x661ABBC5, (q31_t)0xB2A6A401, + (q31_t)0x65FC63A9, (q31_t)0xB27E9D3B, (q31_t)0x65DDFBD3, + (q31_t)0xB256A26A, (q31_t)0x65BF8447, (q31_t)0xB22EB392, + (q31_t)0x65A0FD0B, (q31_t)0xB206D0BA, (q31_t)0x65826622, + (q31_t)0xB1DEF9E8, (q31_t)0x6563BF92, (q31_t)0xB1B72F23, + (q31_t)0x6545095F, (q31_t)0xB18F7070, (q31_t)0x6526438E, + (q31_t)0xB167BDD6, (q31_t)0x65076E24, (q31_t)0xB140175B, + (q31_t)0x64E88926, (q31_t)0xB1187D05, (q31_t)0x64C99498, + (q31_t)0xB0F0EEDA, (q31_t)0x64AA907F, (q31_t)0xB0C96CDF, + (q31_t)0x648B7CDF, (q31_t)0xB0A1F71C, (q31_t)0x646C59BF, + (q31_t)0xB07A8D97, (q31_t)0x644D2722, (q31_t)0xB0533055, + (q31_t)0x642DE50D, (q31_t)0xB02BDF5C, (q31_t)0x640E9385, + (q31_t)0xB0049AB2, (q31_t)0x63EF328F, (q31_t)0xAFDD625F, + (q31_t)0x63CFC230, (q31_t)0xAFB63667, (q31_t)0x63B0426D, + (q31_t)0xAF8F16D0, (q31_t)0x6390B34A, (q31_t)0xAF6803A1, + (q31_t)0x637114CC, (q31_t)0xAF40FCE0, (q31_t)0x635166F8, + (q31_t)0xAF1A0293, (q31_t)0x6331A9D4, (q31_t)0xAEF314BF, + (q31_t)0x6311DD63, (q31_t)0xAECC336B, (q31_t)0x62F201AC, + (q31_t)0xAEA55E9D, (q31_t)0x62D216B2, (q31_t)0xAE7E965B, + (q31_t)0x62B21C7B, (q31_t)0xAE57DAAA, (q31_t)0x6292130C, + (q31_t)0xAE312B91, (q31_t)0x6271FA69, (q31_t)0xAE0A8916, + (q31_t)0x6251D297, (q31_t)0xADE3F33E, (q31_t)0x62319B9D, + (q31_t)0xADBD6A10, (q31_t)0x6211557D, (q31_t)0xAD96ED91, + (q31_t)0x61F1003E, (q31_t)0xAD707DC8, (q31_t)0x61D09BE5, + (q31_t)0xAD4A1ABA, (q31_t)0x61B02876, (q31_t)0xAD23C46D, + (q31_t)0x618FA5F6, (q31_t)0xACFD7AE8, (q31_t)0x616F146B, + (q31_t)0xACD73E30, (q31_t)0x614E73D9, (q31_t)0xACB10E4A, + (q31_t)0x612DC446, (q31_t)0xAC8AEB3E, (q31_t)0x610D05B7, + (q31_t)0xAC64D510, (q31_t)0x60EC3830, (q31_t)0xAC3ECBC7, + (q31_t)0x60CB5BB6, (q31_t)0xAC18CF68, (q31_t)0x60AA704F, + (q31_t)0xABF2DFFA, (q31_t)0x60897600, (q31_t)0xABCCFD82, + (q31_t)0x60686CCE, (q31_t)0xABA72806, (q31_t)0x604754BE, + (q31_t)0xAB815F8C, (q31_t)0x60262DD5, (q31_t)0xAB5BA41A, + (q31_t)0x6004F818, (q31_t)0xAB35F5B5, (q31_t)0x5FE3B38D, + (q31_t)0xAB105464, (q31_t)0x5FC26038, (q31_t)0xAAEAC02B, + (q31_t)0x5FA0FE1E, (q31_t)0xAAC53912, (q31_t)0x5F7F8D46, + (q31_t)0xAA9FBF1D, (q31_t)0x5F5E0DB3, (q31_t)0xAA7A5253, + (q31_t)0x5F3C7F6B, (q31_t)0xAA54F2B9, (q31_t)0x5F1AE273, + (q31_t)0xAA2FA055, (q31_t)0x5EF936D1, (q31_t)0xAA0A5B2D, + (q31_t)0x5ED77C89, (q31_t)0xA9E52347, (q31_t)0x5EB5B3A1, + (q31_t)0xA9BFF8A8, (q31_t)0x5E93DC1F, (q31_t)0xA99ADB56, + (q31_t)0x5E71F606, (q31_t)0xA975CB56, (q31_t)0x5E50015D, + (q31_t)0xA950C8AF, (q31_t)0x5E2DFE28, (q31_t)0xA92BD366, + (q31_t)0x5E0BEC6E, (q31_t)0xA906EB81, (q31_t)0x5DE9CC32, + (q31_t)0xA8E21106, (q31_t)0x5DC79D7C, (q31_t)0xA8BD43FA, + (q31_t)0x5DA5604E, (q31_t)0xA8988463, (q31_t)0x5D8314B0, + (q31_t)0xA873D246, (q31_t)0x5D60BAA6, (q31_t)0xA84F2DA9, + (q31_t)0x5D3E5236, (q31_t)0xA82A9693, (q31_t)0x5D1BDB65, + (q31_t)0xA8060D08, (q31_t)0x5CF95638, (q31_t)0xA7E1910E, + (q31_t)0x5CD6C2B4, (q31_t)0xA7BD22AB, (q31_t)0x5CB420DF, + (q31_t)0xA798C1E4, (q31_t)0x5C9170BF, (q31_t)0xA7746EC0, + (q31_t)0x5C6EB258, (q31_t)0xA7502943, (q31_t)0x5C4BE5B0, + (q31_t)0xA72BF173, (q31_t)0x5C290ACC, (q31_t)0xA707C756, + (q31_t)0x5C0621B2, (q31_t)0xA6E3AAF2, (q31_t)0x5BE32A67, + (q31_t)0xA6BF9C4B, (q31_t)0x5BC024F0, (q31_t)0xA69B9B68, + (q31_t)0x5B9D1153, (q31_t)0xA677A84E, (q31_t)0x5B79EF96, + (q31_t)0xA653C302, (q31_t)0x5B56BFBD, (q31_t)0xA62FEB8B, + (q31_t)0x5B3381CE, (q31_t)0xA60C21ED, (q31_t)0x5B1035CF, + (q31_t)0xA5E8662F, (q31_t)0x5AECDBC4, (q31_t)0xA5C4B855, + (q31_t)0x5AC973B4, (q31_t)0xA5A11865, (q31_t)0x5AA5FDA4, + (q31_t)0xA57D8666, (q31_t)0x5A82799A, (q31_t)0xA55A025B, + (q31_t)0x5A5EE79A, (q31_t)0xA5368C4B, (q31_t)0x5A3B47AA, + (q31_t)0xA513243B, (q31_t)0x5A1799D0, (q31_t)0xA4EFCA31, + (q31_t)0x59F3DE12, (q31_t)0xA4CC7E31, (q31_t)0x59D01474, + (q31_t)0xA4A94042, (q31_t)0x59AC3CFD, (q31_t)0xA4861069, + (q31_t)0x598857B1, (q31_t)0xA462EEAC, (q31_t)0x59646497, + (q31_t)0xA43FDB0F, (q31_t)0x594063B4, (q31_t)0xA41CD598, + (q31_t)0x591C550E, (q31_t)0xA3F9DE4D, (q31_t)0x58F838A9, + (q31_t)0xA3D6F533, (q31_t)0x58D40E8C, (q31_t)0xA3B41A4F, + (q31_t)0x58AFD6BC, (q31_t)0xA3914DA7, (q31_t)0x588B913F, + (q31_t)0xA36E8F40, (q31_t)0x58673E1B, (q31_t)0xA34BDF20, + (q31_t)0x5842DD54, (q31_t)0xA3293D4B, (q31_t)0x581E6EF1, + (q31_t)0xA306A9C7, (q31_t)0x57F9F2F7, (q31_t)0xA2E4249A, + (q31_t)0x57D5696C, (q31_t)0xA2C1ADC9, (q31_t)0x57B0D256, + (q31_t)0xA29F4559, (q31_t)0x578C2DB9, (q31_t)0xA27CEB4F, + (q31_t)0x57677B9D, (q31_t)0xA25A9FB1, (q31_t)0x5742BC05, + (q31_t)0xA2386283, (q31_t)0x571DEEF9, (q31_t)0xA21633CD, + (q31_t)0x56F9147E, (q31_t)0xA1F41391, (q31_t)0x56D42C99, + (q31_t)0xA1D201D7, (q31_t)0x56AF3750, (q31_t)0xA1AFFEA2, + (q31_t)0x568A34A9, (q31_t)0xA18E09F9, (q31_t)0x566524AA, + (q31_t)0xA16C23E1, (q31_t)0x56400757, (q31_t)0xA14A4C5E, + (q31_t)0x561ADCB8, (q31_t)0xA1288376, (q31_t)0x55F5A4D2, + (q31_t)0xA106C92E, (q31_t)0x55D05FAA, (q31_t)0xA0E51D8C, + (q31_t)0x55AB0D46, (q31_t)0xA0C38094, (q31_t)0x5585ADAC, + (q31_t)0xA0A1F24C, (q31_t)0x556040E2, (q31_t)0xA08072BA, + (q31_t)0x553AC6ED, (q31_t)0xA05F01E1, (q31_t)0x55153FD4, + (q31_t)0xA03D9FC7, (q31_t)0x54EFAB9C, (q31_t)0xA01C4C72, + (q31_t)0x54CA0A4A, (q31_t)0x9FFB07E7, (q31_t)0x54A45BE5, + (q31_t)0x9FD9D22A, (q31_t)0x547EA073, (q31_t)0x9FB8AB41, + (q31_t)0x5458D7F9, (q31_t)0x9F979331, (q31_t)0x5433027D, + (q31_t)0x9F7689FF, (q31_t)0x540D2005, (q31_t)0x9F558FB0, + (q31_t)0x53E73097, (q31_t)0x9F34A449, (q31_t)0x53C13438, + (q31_t)0x9F13C7D0, (q31_t)0x539B2AEF, (q31_t)0x9EF2FA48, + (q31_t)0x537514C1, (q31_t)0x9ED23BB9, (q31_t)0x534EF1B5, + (q31_t)0x9EB18C26, (q31_t)0x5328C1D0, (q31_t)0x9E90EB94, + (q31_t)0x53028517, (q31_t)0x9E705A09, (q31_t)0x52DC3B92, + (q31_t)0x9E4FD789, (q31_t)0x52B5E545, (q31_t)0x9E2F641A, + (q31_t)0x528F8237, (q31_t)0x9E0EFFC1, (q31_t)0x5269126E, + (q31_t)0x9DEEAA82, (q31_t)0x524295EF, (q31_t)0x9DCE6462, + (q31_t)0x521C0CC1, (q31_t)0x9DAE2D68, (q31_t)0x51F576E9, + (q31_t)0x9D8E0596, (q31_t)0x51CED46E, (q31_t)0x9D6DECF4, + (q31_t)0x51A82555, (q31_t)0x9D4DE384, (q31_t)0x518169A4, + (q31_t)0x9D2DE94D, (q31_t)0x515AA162, (q31_t)0x9D0DFE53, + (q31_t)0x5133CC94, (q31_t)0x9CEE229C, (q31_t)0x510CEB40, + (q31_t)0x9CCE562B, (q31_t)0x50E5FD6C, (q31_t)0x9CAE9907, + (q31_t)0x50BF031F, (q31_t)0x9C8EEB33, (q31_t)0x5097FC5E, + (q31_t)0x9C6F4CB5, (q31_t)0x5070E92F, (q31_t)0x9C4FBD92, + (q31_t)0x5049C999, (q31_t)0x9C303DCF, (q31_t)0x50229DA0, + (q31_t)0x9C10CD70, (q31_t)0x4FFB654D, (q31_t)0x9BF16C7A, + (q31_t)0x4FD420A3, (q31_t)0x9BD21AF2, (q31_t)0x4FACCFAB, + (q31_t)0x9BB2D8DD, (q31_t)0x4F857268, (q31_t)0x9B93A640, + (q31_t)0x4F5E08E3, (q31_t)0x9B748320, (q31_t)0x4F369320, + (q31_t)0x9B556F80, (q31_t)0x4F0F1126, (q31_t)0x9B366B67, + (q31_t)0x4EE782FA, (q31_t)0x9B1776D9, (q31_t)0x4EBFE8A4, + (q31_t)0x9AF891DB, (q31_t)0x4E984229, (q31_t)0x9AD9BC71, + (q31_t)0x4E708F8F, (q31_t)0x9ABAF6A0, (q31_t)0x4E48D0DC, + (q31_t)0x9A9C406D, (q31_t)0x4E210617, (q31_t)0x9A7D99DD, + (q31_t)0x4DF92F45, (q31_t)0x9A5F02F5, (q31_t)0x4DD14C6E, + (q31_t)0x9A407BB8, (q31_t)0x4DA95D96, (q31_t)0x9A22042C, + (q31_t)0x4D8162C4, (q31_t)0x9A039C56, (q31_t)0x4D595BFE, + (q31_t)0x99E5443A, (q31_t)0x4D31494B, (q31_t)0x99C6FBDE, + (q31_t)0x4D092AB0, (q31_t)0x99A8C344, (q31_t)0x4CE10034, + (q31_t)0x998A9A73, (q31_t)0x4CB8C9DD, (q31_t)0x996C816F, + (q31_t)0x4C9087B1, (q31_t)0x994E783C, (q31_t)0x4C6839B6, + (q31_t)0x99307EE0, (q31_t)0x4C3FDFF3, (q31_t)0x9912955E, + (q31_t)0x4C177A6E, (q31_t)0x98F4BBBC, (q31_t)0x4BEF092D, + (q31_t)0x98D6F1FE, (q31_t)0x4BC68C36, (q31_t)0x98B93828, + (q31_t)0x4B9E038F, (q31_t)0x989B8E3F, (q31_t)0x4B756F3F, + (q31_t)0x987DF449, (q31_t)0x4B4CCF4D, (q31_t)0x98606A48, + (q31_t)0x4B2423BD, (q31_t)0x9842F043, (q31_t)0x4AFB6C97, + (q31_t)0x9825863D, (q31_t)0x4AD2A9E1, (q31_t)0x98082C3B, + (q31_t)0x4AA9DBA1, (q31_t)0x97EAE241, (q31_t)0x4A8101DE, + (q31_t)0x97CDA855, (q31_t)0x4A581C9D, (q31_t)0x97B07E7A, + (q31_t)0x4A2F2BE5, (q31_t)0x979364B5, (q31_t)0x4A062FBD, + (q31_t)0x97765B0A, (q31_t)0x49DD282A, (q31_t)0x9759617E, + (q31_t)0x49B41533, (q31_t)0x973C7816, (q31_t)0x498AF6DE, + (q31_t)0x971F9ED6, (q31_t)0x4961CD32, (q31_t)0x9702D5C2, + (q31_t)0x49389836, (q31_t)0x96E61CDF, (q31_t)0x490F57EE, + (q31_t)0x96C97431, (q31_t)0x48E60C62, (q31_t)0x96ACDBBD, + (q31_t)0x48BCB598, (q31_t)0x96905387, (q31_t)0x48935397, + (q31_t)0x9673DB94, (q31_t)0x4869E664, (q31_t)0x965773E7, + (q31_t)0x48406E07, (q31_t)0x963B1C85, (q31_t)0x4816EA85, + (q31_t)0x961ED573, (q31_t)0x47ED5BE6, (q31_t)0x96029EB5, + (q31_t)0x47C3C22E, (q31_t)0x95E6784F, (q31_t)0x479A1D66, + (q31_t)0x95CA6246, (q31_t)0x47706D93, (q31_t)0x95AE5C9E, + (q31_t)0x4746B2BC, (q31_t)0x9592675B, (q31_t)0x471CECE6, + (q31_t)0x95768282, (q31_t)0x46F31C1A, (q31_t)0x955AAE17, + (q31_t)0x46C9405C, (q31_t)0x953EEA1E, (q31_t)0x469F59B4, + (q31_t)0x9523369B, (q31_t)0x46756827, (q31_t)0x95079393, + (q31_t)0x464B6BBD, (q31_t)0x94EC010B, (q31_t)0x4621647C, + (q31_t)0x94D07F05, (q31_t)0x45F7526B, (q31_t)0x94B50D87, + (q31_t)0x45CD358F, (q31_t)0x9499AC95, (q31_t)0x45A30DF0, + (q31_t)0x947E5C32, (q31_t)0x4578DB93, (q31_t)0x94631C64, + (q31_t)0x454E9E80, (q31_t)0x9447ED2F, (q31_t)0x452456BC, + (q31_t)0x942CCE95, (q31_t)0x44FA044F, (q31_t)0x9411C09D, + (q31_t)0x44CFA73F, (q31_t)0x93F6C34A, (q31_t)0x44A53F93, + (q31_t)0x93DBD69F, (q31_t)0x447ACD50, (q31_t)0x93C0FAA2, + (q31_t)0x4450507E, (q31_t)0x93A62F56, (q31_t)0x4425C923, + (q31_t)0x938B74C0, (q31_t)0x43FB3745, (q31_t)0x9370CAE4, + (q31_t)0x43D09AEC, (q31_t)0x935631C5, (q31_t)0x43A5F41E, + (q31_t)0x933BA968, (q31_t)0x437B42E1, (q31_t)0x932131D1, + (q31_t)0x4350873C, (q31_t)0x9306CB04, (q31_t)0x4325C135, + (q31_t)0x92EC7505, (q31_t)0x42FAF0D4, (q31_t)0x92D22FD8, + (q31_t)0x42D0161E, (q31_t)0x92B7FB82, (q31_t)0x42A5311A, + (q31_t)0x929DD805, (q31_t)0x427A41D0, (q31_t)0x9283C567, + (q31_t)0x424F4845, (q31_t)0x9269C3AC, (q31_t)0x42244480, + (q31_t)0x924FD2D6, (q31_t)0x41F93688, (q31_t)0x9235F2EB, + (q31_t)0x41CE1E64, (q31_t)0x921C23EE, (q31_t)0x41A2FC1A, + (q31_t)0x920265E4, (q31_t)0x4177CFB0, (q31_t)0x91E8B8D0, + (q31_t)0x414C992E, (q31_t)0x91CF1CB6, (q31_t)0x4121589A, + (q31_t)0x91B5919A, (q31_t)0x40F60DFB, (q31_t)0x919C1780, + (q31_t)0x40CAB957, (q31_t)0x9182AE6C, (q31_t)0x409F5AB6, + (q31_t)0x91695663, (q31_t)0x4073F21D, (q31_t)0x91500F67, + (q31_t)0x40487F93, (q31_t)0x9136D97D, (q31_t)0x401D0320, + (q31_t)0x911DB4A8, (q31_t)0x3FF17CCA, (q31_t)0x9104A0ED, + (q31_t)0x3FC5EC97, (q31_t)0x90EB9E50, (q31_t)0x3F9A528F, + (q31_t)0x90D2ACD3, (q31_t)0x3F6EAEB8, (q31_t)0x90B9CC7C, + (q31_t)0x3F430118, (q31_t)0x90A0FD4E, (q31_t)0x3F1749B7, + (q31_t)0x90883F4C, (q31_t)0x3EEB889C, (q31_t)0x906F927B, + (q31_t)0x3EBFBDCC, (q31_t)0x9056F6DF, (q31_t)0x3E93E94F, + (q31_t)0x903E6C7A, (q31_t)0x3E680B2C, (q31_t)0x9025F352, + (q31_t)0x3E3C2369, (q31_t)0x900D8B69, (q31_t)0x3E10320D, + (q31_t)0x8FF534C4, (q31_t)0x3DE4371F, (q31_t)0x8FDCEF66, + (q31_t)0x3DB832A5, (q31_t)0x8FC4BB53, (q31_t)0x3D8C24A7, + (q31_t)0x8FAC988E, (q31_t)0x3D600D2B, (q31_t)0x8F94871D, + (q31_t)0x3D33EC39, (q31_t)0x8F7C8701, (q31_t)0x3D07C1D5, + (q31_t)0x8F64983F, (q31_t)0x3CDB8E09, (q31_t)0x8F4CBADB, + (q31_t)0x3CAF50DA, (q31_t)0x8F34EED8, (q31_t)0x3C830A4F, + (q31_t)0x8F1D343A, (q31_t)0x3C56BA70, (q31_t)0x8F058B04, + (q31_t)0x3C2A6142, (q31_t)0x8EEDF33B, (q31_t)0x3BFDFECD, + (q31_t)0x8ED66CE1, (q31_t)0x3BD19317, (q31_t)0x8EBEF7FB, + (q31_t)0x3BA51E29, (q31_t)0x8EA7948C, (q31_t)0x3B78A007, + (q31_t)0x8E904298, (q31_t)0x3B4C18BA, (q31_t)0x8E790222, + (q31_t)0x3B1F8847, (q31_t)0x8E61D32D, (q31_t)0x3AF2EEB7, + (q31_t)0x8E4AB5BF, (q31_t)0x3AC64C0F, (q31_t)0x8E33A9D9, + (q31_t)0x3A99A057, (q31_t)0x8E1CAF80, (q31_t)0x3A6CEB95, + (q31_t)0x8E05C6B7, (q31_t)0x3A402DD1, (q31_t)0x8DEEEF82, + (q31_t)0x3A136712, (q31_t)0x8DD829E4, (q31_t)0x39E6975D, + (q31_t)0x8DC175E0, (q31_t)0x39B9BEBB, (q31_t)0x8DAAD37B, + (q31_t)0x398CDD32, (q31_t)0x8D9442B7, (q31_t)0x395FF2C9, + (q31_t)0x8D7DC399, (q31_t)0x3932FF87, (q31_t)0x8D675623, + (q31_t)0x39060372, (q31_t)0x8D50FA59, (q31_t)0x38D8FE93, + (q31_t)0x8D3AB03F, (q31_t)0x38ABF0EF, (q31_t)0x8D2477D8, + (q31_t)0x387EDA8E, (q31_t)0x8D0E5127, (q31_t)0x3851BB76, + (q31_t)0x8CF83C30, (q31_t)0x382493B0, (q31_t)0x8CE238F6, + (q31_t)0x37F76340, (q31_t)0x8CCC477D, (q31_t)0x37CA2A30, + (q31_t)0x8CB667C7, (q31_t)0x379CE884, (q31_t)0x8CA099D9, + (q31_t)0x376F9E46, (q31_t)0x8C8ADDB6, (q31_t)0x37424B7A, + (q31_t)0x8C753361, (q31_t)0x3714F02A, (q31_t)0x8C5F9ADD, + (q31_t)0x36E78C5A, (q31_t)0x8C4A142F, (q31_t)0x36BA2013, + (q31_t)0x8C349F58, (q31_t)0x368CAB5C, (q31_t)0x8C1F3C5C, + (q31_t)0x365F2E3B, (q31_t)0x8C09EB40, (q31_t)0x3631A8B7, + (q31_t)0x8BF4AC05, (q31_t)0x36041AD9, (q31_t)0x8BDF7EAF, + (q31_t)0x35D684A5, (q31_t)0x8BCA6342, (q31_t)0x35A8E624, + (q31_t)0x8BB559C1, (q31_t)0x357B3F5D, (q31_t)0x8BA0622F, + (q31_t)0x354D9056, (q31_t)0x8B8B7C8F, (q31_t)0x351FD917, + (q31_t)0x8B76A8E4, (q31_t)0x34F219A7, (q31_t)0x8B61E732, + (q31_t)0x34C4520D, (q31_t)0x8B4D377C, (q31_t)0x3496824F, + (q31_t)0x8B3899C5, (q31_t)0x3468AA76, (q31_t)0x8B240E10, + (q31_t)0x343ACA87, (q31_t)0x8B0F9461, (q31_t)0x340CE28A, + (q31_t)0x8AFB2CBA, (q31_t)0x33DEF287, (q31_t)0x8AE6D71F, + (q31_t)0x33B0FA84, (q31_t)0x8AD29393, (q31_t)0x3382FA88, + (q31_t)0x8ABE6219, (q31_t)0x3354F29A, (q31_t)0x8AAA42B4, + (q31_t)0x3326E2C2, (q31_t)0x8A963567, (q31_t)0x32F8CB07, + (q31_t)0x8A823A35, (q31_t)0x32CAAB6F, (q31_t)0x8A6E5122, + (q31_t)0x329C8402, (q31_t)0x8A5A7A30, (q31_t)0x326E54C7, + (q31_t)0x8A46B563, (q31_t)0x32401DC5, (q31_t)0x8A3302BD, + (q31_t)0x3211DF03, (q31_t)0x8A1F6242, (q31_t)0x31E39889, + (q31_t)0x8A0BD3F5, (q31_t)0x31B54A5D, (q31_t)0x89F857D8, + (q31_t)0x3186F487, (q31_t)0x89E4EDEE, (q31_t)0x3158970D, + (q31_t)0x89D1963C, (q31_t)0x312A31F8, (q31_t)0x89BE50C3, + (q31_t)0x30FBC54D, (q31_t)0x89AB1D86, (q31_t)0x30CD5114, + (q31_t)0x8997FC89, (q31_t)0x309ED555, (q31_t)0x8984EDCF, + (q31_t)0x30705217, (q31_t)0x8971F15A, (q31_t)0x3041C760, + (q31_t)0x895F072D, (q31_t)0x30133538, (q31_t)0x894C2F4C, + (q31_t)0x2FE49BA6, (q31_t)0x893969B9, (q31_t)0x2FB5FAB2, + (q31_t)0x8926B677, (q31_t)0x2F875262, (q31_t)0x89141589, + (q31_t)0x2F58A2BD, (q31_t)0x890186F1, (q31_t)0x2F29EBCC, + (q31_t)0x88EF0AB4, (q31_t)0x2EFB2D94, (q31_t)0x88DCA0D3, + (q31_t)0x2ECC681E, (q31_t)0x88CA4951, (q31_t)0x2E9D9B70, + (q31_t)0x88B80431, (q31_t)0x2E6EC792, (q31_t)0x88A5D177, + (q31_t)0x2E3FEC8B, (q31_t)0x8893B124, (q31_t)0x2E110A62, + (q31_t)0x8881A33C, (q31_t)0x2DE2211E, (q31_t)0x886FA7C2, + (q31_t)0x2DB330C7, (q31_t)0x885DBEB7, (q31_t)0x2D843963, + (q31_t)0x884BE820, (q31_t)0x2D553AFB, (q31_t)0x883A23FE, + (q31_t)0x2D263595, (q31_t)0x88287255, (q31_t)0x2CF72939, + (q31_t)0x8816D327, (q31_t)0x2CC815ED, (q31_t)0x88054677, + (q31_t)0x2C98FBBA, (q31_t)0x87F3CC47, (q31_t)0x2C69DAA6, + (q31_t)0x87E2649B, (q31_t)0x2C3AB2B9, (q31_t)0x87D10F75, + (q31_t)0x2C0B83F9, (q31_t)0x87BFCCD7, (q31_t)0x2BDC4E6F, + (q31_t)0x87AE9CC5, (q31_t)0x2BAD1221, (q31_t)0x879D7F40, + (q31_t)0x2B7DCF17, (q31_t)0x878C744C, (q31_t)0x2B4E8558, + (q31_t)0x877B7BEC, (q31_t)0x2B1F34EB, (q31_t)0x876A9621, + (q31_t)0x2AEFDDD8, (q31_t)0x8759C2EF, (q31_t)0x2AC08025, + (q31_t)0x87490257, (q31_t)0x2A911BDB, (q31_t)0x8738545E, + (q31_t)0x2A61B101, (q31_t)0x8727B904, (q31_t)0x2A323F9D, + (q31_t)0x8717304E, (q31_t)0x2A02C7B8, (q31_t)0x8706BA3C, + (q31_t)0x29D34958, (q31_t)0x86F656D3, (q31_t)0x29A3C484, + (q31_t)0x86E60614, (q31_t)0x29743945, (q31_t)0x86D5C802, + (q31_t)0x2944A7A2, (q31_t)0x86C59C9F, (q31_t)0x29150FA1, + (q31_t)0x86B583EE, (q31_t)0x28E5714A, (q31_t)0x86A57DF1, + (q31_t)0x28B5CCA5, (q31_t)0x86958AAB, (q31_t)0x288621B9, + (q31_t)0x8685AA1F, (q31_t)0x2856708C, (q31_t)0x8675DC4E, + (q31_t)0x2826B928, (q31_t)0x8666213C, (q31_t)0x27F6FB92, + (q31_t)0x865678EA, (q31_t)0x27C737D2, (q31_t)0x8646E35B, + (q31_t)0x27976DF1, (q31_t)0x86376092, (q31_t)0x27679DF4, + (q31_t)0x8627F090, (q31_t)0x2737C7E3, (q31_t)0x86189359, + (q31_t)0x2707EBC6, (q31_t)0x860948EE, (q31_t)0x26D809A5, + (q31_t)0x85FA1152, (q31_t)0x26A82185, (q31_t)0x85EAEC88, + (q31_t)0x26783370, (q31_t)0x85DBDA91, (q31_t)0x26483F6C, + (q31_t)0x85CCDB70, (q31_t)0x26184581, (q31_t)0x85BDEF27, + (q31_t)0x25E845B5, (q31_t)0x85AF15B9, (q31_t)0x25B84012, + (q31_t)0x85A04F28, (q31_t)0x2588349D, (q31_t)0x85919B75, + (q31_t)0x2558235E, (q31_t)0x8582FAA4, (q31_t)0x25280C5D, + (q31_t)0x85746CB7, (q31_t)0x24F7EFA1, (q31_t)0x8565F1B0, + (q31_t)0x24C7CD32, (q31_t)0x85578991, (q31_t)0x2497A517, + (q31_t)0x8549345C, (q31_t)0x24677757, (q31_t)0x853AF214, + (q31_t)0x243743FA, (q31_t)0x852CC2BA, (q31_t)0x24070B07, + (q31_t)0x851EA652, (q31_t)0x23D6CC86, (q31_t)0x85109CDC, + (q31_t)0x23A6887E, (q31_t)0x8502A65C, (q31_t)0x23763EF7, + (q31_t)0x84F4C2D3, (q31_t)0x2345EFF7, (q31_t)0x84E6F244, + (q31_t)0x23159B87, (q31_t)0x84D934B0, (q31_t)0x22E541AE, + (q31_t)0x84CB8A1B, (q31_t)0x22B4E274, (q31_t)0x84BDF285, + (q31_t)0x22847DDF, (q31_t)0x84B06DF1, (q31_t)0x225413F8, + (q31_t)0x84A2FC62, (q31_t)0x2223A4C5, (q31_t)0x84959DD9, + (q31_t)0x21F3304E, (q31_t)0x84885257, (q31_t)0x21C2B69C, + (q31_t)0x847B19E1, (q31_t)0x219237B4, (q31_t)0x846DF476, + (q31_t)0x2161B39F, (q31_t)0x8460E21A, (q31_t)0x21312A65, + (q31_t)0x8453E2CE, (q31_t)0x21009C0B, (q31_t)0x8446F695, + (q31_t)0x20D0089B, (q31_t)0x843A1D70, (q31_t)0x209F701C, + (q31_t)0x842D5761, (q31_t)0x206ED295, (q31_t)0x8420A46B, + (q31_t)0x203E300D, (q31_t)0x8414048F, (q31_t)0x200D888C, + (q31_t)0x840777CF, (q31_t)0x1FDCDC1A, (q31_t)0x83FAFE2E, + (q31_t)0x1FAC2ABF, (q31_t)0x83EE97AC, (q31_t)0x1F7B7480, + (q31_t)0x83E2444D, (q31_t)0x1F4AB967, (q31_t)0x83D60411, + (q31_t)0x1F19F97B, (q31_t)0x83C9D6FB, (q31_t)0x1EE934C2, + (q31_t)0x83BDBD0D, (q31_t)0x1EB86B46, (q31_t)0x83B1B649, + (q31_t)0x1E879D0C, (q31_t)0x83A5C2B0, (q31_t)0x1E56CA1E, + (q31_t)0x8399E244, (q31_t)0x1E25F281, (q31_t)0x838E1507, + (q31_t)0x1DF5163F, (q31_t)0x83825AFB, (q31_t)0x1DC4355D, + (q31_t)0x8376B422, (q31_t)0x1D934FE5, (q31_t)0x836B207D, + (q31_t)0x1D6265DD, (q31_t)0x835FA00E, (q31_t)0x1D31774D, + (q31_t)0x835432D8, (q31_t)0x1D00843C, (q31_t)0x8348D8DB, + (q31_t)0x1CCF8CB3, (q31_t)0x833D921A, (q31_t)0x1C9E90B8, + (q31_t)0x83325E97, (q31_t)0x1C6D9053, (q31_t)0x83273E52, + (q31_t)0x1C3C8B8C, (q31_t)0x831C314E, (q31_t)0x1C0B826A, + (q31_t)0x8311378C, (q31_t)0x1BDA74F5, (q31_t)0x8306510F, + (q31_t)0x1BA96334, (q31_t)0x82FB7DD8, (q31_t)0x1B784D30, + (q31_t)0x82F0BDE8, (q31_t)0x1B4732EF, (q31_t)0x82E61141, + (q31_t)0x1B161479, (q31_t)0x82DB77E5, (q31_t)0x1AE4F1D6, + (q31_t)0x82D0F1D5, (q31_t)0x1AB3CB0C, (q31_t)0x82C67F13, + (q31_t)0x1A82A025, (q31_t)0x82BC1FA1, (q31_t)0x1A517127, + (q31_t)0x82B1D381, (q31_t)0x1A203E1B, (q31_t)0x82A79AB3, + (q31_t)0x19EF0706, (q31_t)0x829D753A, (q31_t)0x19BDCBF2, + (q31_t)0x82936316, (q31_t)0x198C8CE6, (q31_t)0x8289644A, + (q31_t)0x195B49E9, (q31_t)0x827F78D8, (q31_t)0x192A0303, + (q31_t)0x8275A0C0, (q31_t)0x18F8B83C, (q31_t)0x826BDC04, + (q31_t)0x18C7699B, (q31_t)0x82622AA5, (q31_t)0x18961727, + (q31_t)0x82588CA6, (q31_t)0x1864C0E9, (q31_t)0x824F0208, + (q31_t)0x183366E8, (q31_t)0x82458ACB, (q31_t)0x1802092C, + (q31_t)0x823C26F2, (q31_t)0x17D0A7BB, (q31_t)0x8232D67E, + (q31_t)0x179F429F, (q31_t)0x82299971, (q31_t)0x176DD9DE, + (q31_t)0x82206FCB, (q31_t)0x173C6D80, (q31_t)0x8217598F, + (q31_t)0x170AFD8D, (q31_t)0x820E56BE, (q31_t)0x16D98A0C, + (q31_t)0x82056758, (q31_t)0x16A81305, (q31_t)0x81FC8B60, + (q31_t)0x1676987F, (q31_t)0x81F3C2D7, (q31_t)0x16451A83, + (q31_t)0x81EB0DBD, (q31_t)0x16139917, (q31_t)0x81E26C16, + (q31_t)0x15E21444, (q31_t)0x81D9DDE1, (q31_t)0x15B08C11, + (q31_t)0x81D16320, (q31_t)0x157F0086, (q31_t)0x81C8FBD5, + (q31_t)0x154D71AA, (q31_t)0x81C0A801, (q31_t)0x151BDF85, + (q31_t)0x81B867A4, (q31_t)0x14EA4A1F, (q31_t)0x81B03AC1, + (q31_t)0x14B8B17F, (q31_t)0x81A82159, (q31_t)0x148715AD, + (q31_t)0x81A01B6C, (q31_t)0x145576B1, (q31_t)0x819828FD, + (q31_t)0x1423D492, (q31_t)0x81904A0C, (q31_t)0x13F22F57, + (q31_t)0x81887E9A, (q31_t)0x13C0870A, (q31_t)0x8180C6A9, + (q31_t)0x138EDBB0, (q31_t)0x8179223A, (q31_t)0x135D2D53, + (q31_t)0x8171914E, (q31_t)0x132B7BF9, (q31_t)0x816A13E6, + (q31_t)0x12F9C7AA, (q31_t)0x8162AA03, (q31_t)0x12C8106E, + (q31_t)0x815B53A8, (q31_t)0x1296564D, (q31_t)0x815410D3, + (q31_t)0x1264994E, (q31_t)0x814CE188, (q31_t)0x1232D978, + (q31_t)0x8145C5C6, (q31_t)0x120116D4, (q31_t)0x813EBD90, + (q31_t)0x11CF516A, (q31_t)0x8137C8E6, (q31_t)0x119D8940, + (q31_t)0x8130E7C8, (q31_t)0x116BBE5F, (q31_t)0x812A1A39, + (q31_t)0x1139F0CE, (q31_t)0x81236039, (q31_t)0x11082096, + (q31_t)0x811CB9CA, (q31_t)0x10D64DBC, (q31_t)0x811626EC, + (q31_t)0x10A4784A, (q31_t)0x810FA7A0, (q31_t)0x1072A047, + (q31_t)0x81093BE8, (q31_t)0x1040C5BB, (q31_t)0x8102E3C3, + (q31_t)0x100EE8AD, (q31_t)0x80FC9F35, (q31_t)0x0FDD0925, + (q31_t)0x80F66E3C, (q31_t)0x0FAB272B, (q31_t)0x80F050DB, + (q31_t)0x0F7942C6, (q31_t)0x80EA4712, (q31_t)0x0F475BFE, + (q31_t)0x80E450E2, (q31_t)0x0F1572DC, (q31_t)0x80DE6E4C, + (q31_t)0x0EE38765, (q31_t)0x80D89F51, (q31_t)0x0EB199A3, + (q31_t)0x80D2E3F1, (q31_t)0x0E7FA99D, (q31_t)0x80CD3C2F, + (q31_t)0x0E4DB75B, (q31_t)0x80C7A80A, (q31_t)0x0E1BC2E3, + (q31_t)0x80C22783, (q31_t)0x0DE9CC3F, (q31_t)0x80BCBA9C, + (q31_t)0x0DB7D376, (q31_t)0x80B76155, (q31_t)0x0D85D88F, + (q31_t)0x80B21BAF, (q31_t)0x0D53DB92, (q31_t)0x80ACE9AB, + (q31_t)0x0D21DC87, (q31_t)0x80A7CB49, (q31_t)0x0CEFDB75, + (q31_t)0x80A2C08B, (q31_t)0x0CBDD865, (q31_t)0x809DC970, + (q31_t)0x0C8BD35E, (q31_t)0x8098E5FB, (q31_t)0x0C59CC67, + (q31_t)0x8094162B, (q31_t)0x0C27C389, (q31_t)0x808F5A02, + (q31_t)0x0BF5B8CB, (q31_t)0x808AB180, (q31_t)0x0BC3AC35, + (q31_t)0x80861CA5, (q31_t)0x0B919DCE, (q31_t)0x80819B74, + (q31_t)0x0B5F8D9F, (q31_t)0x807D2DEB, (q31_t)0x0B2D7BAE, + (q31_t)0x8078D40D, (q31_t)0x0AFB6805, (q31_t)0x80748DD9, + (q31_t)0x0AC952AA, (q31_t)0x80705B50, (q31_t)0x0A973BA5, + (q31_t)0x806C3C73, (q31_t)0x0A6522FE, (q31_t)0x80683143, + (q31_t)0x0A3308BC, (q31_t)0x806439C0, (q31_t)0x0A00ECE8, + (q31_t)0x806055EA, (q31_t)0x09CECF89, (q31_t)0x805C85C3, + (q31_t)0x099CB0A7, (q31_t)0x8058C94C, (q31_t)0x096A9049, + (q31_t)0x80552083, (q31_t)0x09386E77, (q31_t)0x80518B6B, + (q31_t)0x09064B3A, (q31_t)0x804E0A03, (q31_t)0x08D42698, + (q31_t)0x804A9C4D, (q31_t)0x08A2009A, (q31_t)0x80474248, + (q31_t)0x086FD947, (q31_t)0x8043FBF6, (q31_t)0x083DB0A7, + (q31_t)0x8040C956, (q31_t)0x080B86C1, (q31_t)0x803DAA69, + (q31_t)0x07D95B9E, (q31_t)0x803A9F31, (q31_t)0x07A72F45, + (q31_t)0x8037A7AC, (q31_t)0x077501BE, (q31_t)0x8034C3DC, + (q31_t)0x0742D310, (q31_t)0x8031F3C1, (q31_t)0x0710A344, + (q31_t)0x802F375C, (q31_t)0x06DE7261, (q31_t)0x802C8EAD, + (q31_t)0x06AC406F, (q31_t)0x8029F9B4, (q31_t)0x067A0D75, + (q31_t)0x80277872, (q31_t)0x0647D97C, (q31_t)0x80250AE7, + (q31_t)0x0615A48A, (q31_t)0x8022B113, (q31_t)0x05E36EA9, + (q31_t)0x80206AF8, (q31_t)0x05B137DF, (q31_t)0x801E3894, + (q31_t)0x057F0034, (q31_t)0x801C19E9, (q31_t)0x054CC7B0, + (q31_t)0x801A0EF7, (q31_t)0x051A8E5C, (q31_t)0x801817BF, + (q31_t)0x04E8543D, (q31_t)0x80163440, (q31_t)0x04B6195D, + (q31_t)0x8014647A, (q31_t)0x0483DDC3, (q31_t)0x8012A86F, + (q31_t)0x0451A176, (q31_t)0x8011001E, (q31_t)0x041F647F, + (q31_t)0x800F6B88, (q31_t)0x03ED26E6, (q31_t)0x800DEAAC, + (q31_t)0x03BAE8B1, (q31_t)0x800C7D8C, (q31_t)0x0388A9E9, + (q31_t)0x800B2427, (q31_t)0x03566A96, (q31_t)0x8009DE7D, + (q31_t)0x03242ABF, (q31_t)0x8008AC90, (q31_t)0x02F1EA6B, + (q31_t)0x80078E5E, (q31_t)0x02BFA9A4, (q31_t)0x800683E8, + (q31_t)0x028D6870, (q31_t)0x80058D2E, (q31_t)0x025B26D7, + (q31_t)0x8004AA31, (q31_t)0x0228E4E1, (q31_t)0x8003DAF0, + (q31_t)0x01F6A296, (q31_t)0x80031F6C, (q31_t)0x01C45FFE, + (q31_t)0x800277A5, (q31_t)0x01921D1F, (q31_t)0x8001E39B, + (q31_t)0x015FDA03, (q31_t)0x8001634D, (q31_t)0x012D96B0, + (q31_t)0x8000F6BD, (q31_t)0x00FB532F, (q31_t)0x80009DE9, + (q31_t)0x00C90F88, (q31_t)0x800058D3, (q31_t)0x0096CBC1, + (q31_t)0x8000277A, (q31_t)0x006487E3, (q31_t)0x800009DE, + (q31_t)0x003243F5, (q31_t)0x80000000, (q31_t)0x00000000, + (q31_t)0x800009DE, (q31_t)0xFFCDBC0A, (q31_t)0x8000277A, + (q31_t)0xFF9B781D, (q31_t)0x800058D3, (q31_t)0xFF69343E, + (q31_t)0x80009DE9, (q31_t)0xFF36F078, (q31_t)0x8000F6BD, + (q31_t)0xFF04ACD0, (q31_t)0x8001634D, (q31_t)0xFED2694F, + (q31_t)0x8001E39B, (q31_t)0xFEA025FC, (q31_t)0x800277A5, + (q31_t)0xFE6DE2E0, (q31_t)0x80031F6C, (q31_t)0xFE3BA001, + (q31_t)0x8003DAF0, (q31_t)0xFE095D69, (q31_t)0x8004AA31, + (q31_t)0xFDD71B1E, (q31_t)0x80058D2E, (q31_t)0xFDA4D928, + (q31_t)0x800683E8, (q31_t)0xFD72978F, (q31_t)0x80078E5E, + (q31_t)0xFD40565B, (q31_t)0x8008AC90, (q31_t)0xFD0E1594, + (q31_t)0x8009DE7D, (q31_t)0xFCDBD541, (q31_t)0x800B2427, + (q31_t)0xFCA99569, (q31_t)0x800C7D8C, (q31_t)0xFC775616, + (q31_t)0x800DEAAC, (q31_t)0xFC45174E, (q31_t)0x800F6B88, + (q31_t)0xFC12D919, (q31_t)0x8011001E, (q31_t)0xFBE09B80, + (q31_t)0x8012A86F, (q31_t)0xFBAE5E89, (q31_t)0x8014647A, + (q31_t)0xFB7C223C, (q31_t)0x80163440, (q31_t)0xFB49E6A2, + (q31_t)0x801817BF, (q31_t)0xFB17ABC2, (q31_t)0x801A0EF7, + (q31_t)0xFAE571A4, (q31_t)0x801C19E9, (q31_t)0xFAB3384F, + (q31_t)0x801E3894, (q31_t)0xFA80FFCB, (q31_t)0x80206AF8, + (q31_t)0xFA4EC820, (q31_t)0x8022B113, (q31_t)0xFA1C9156, + (q31_t)0x80250AE7, (q31_t)0xF9EA5B75, (q31_t)0x80277872, + (q31_t)0xF9B82683, (q31_t)0x8029F9B4, (q31_t)0xF985F28A, + (q31_t)0x802C8EAD, (q31_t)0xF953BF90, (q31_t)0x802F375C, + (q31_t)0xF9218D9E, (q31_t)0x8031F3C1, (q31_t)0xF8EF5CBB, + (q31_t)0x8034C3DC, (q31_t)0xF8BD2CEF, (q31_t)0x8037A7AC, + (q31_t)0xF88AFE41, (q31_t)0x803A9F31, (q31_t)0xF858D0BA, + (q31_t)0x803DAA69, (q31_t)0xF826A461, (q31_t)0x8040C956, + (q31_t)0xF7F4793E, (q31_t)0x8043FBF6, (q31_t)0xF7C24F58, + (q31_t)0x80474248, (q31_t)0xF79026B8, (q31_t)0x804A9C4D, + (q31_t)0xF75DFF65, (q31_t)0x804E0A03, (q31_t)0xF72BD967, + (q31_t)0x80518B6B, (q31_t)0xF6F9B4C5, (q31_t)0x80552083, + (q31_t)0xF6C79188, (q31_t)0x8058C94C, (q31_t)0xF6956FB6, + (q31_t)0x805C85C3, (q31_t)0xF6634F58, (q31_t)0x806055EA, + (q31_t)0xF6313076, (q31_t)0x806439C0, (q31_t)0xF5FF1317, + (q31_t)0x80683143, (q31_t)0xF5CCF743, (q31_t)0x806C3C73, + (q31_t)0xF59ADD01, (q31_t)0x80705B50, (q31_t)0xF568C45A, + (q31_t)0x80748DD9, (q31_t)0xF536AD55, (q31_t)0x8078D40D, + (q31_t)0xF50497FA, (q31_t)0x807D2DEB, (q31_t)0xF4D28451, + (q31_t)0x80819B74, (q31_t)0xF4A07260, (q31_t)0x80861CA5, + (q31_t)0xF46E6231, (q31_t)0x808AB180, (q31_t)0xF43C53CA, + (q31_t)0x808F5A02, (q31_t)0xF40A4734, (q31_t)0x8094162B, + (q31_t)0xF3D83C76, (q31_t)0x8098E5FB, (q31_t)0xF3A63398, + (q31_t)0x809DC970, (q31_t)0xF3742CA1, (q31_t)0x80A2C08B, + (q31_t)0xF342279A, (q31_t)0x80A7CB49, (q31_t)0xF310248A, + (q31_t)0x80ACE9AB, (q31_t)0xF2DE2378, (q31_t)0x80B21BAF, + (q31_t)0xF2AC246D, (q31_t)0x80B76155, (q31_t)0xF27A2770, + (q31_t)0x80BCBA9C, (q31_t)0xF2482C89, (q31_t)0x80C22783, + (q31_t)0xF21633C0, (q31_t)0x80C7A80A, (q31_t)0xF1E43D1C, + (q31_t)0x80CD3C2F, (q31_t)0xF1B248A5, (q31_t)0x80D2E3F1, + (q31_t)0xF1805662, (q31_t)0x80D89F51, (q31_t)0xF14E665C, + (q31_t)0x80DE6E4C, (q31_t)0xF11C789A, (q31_t)0x80E450E2, + (q31_t)0xF0EA8D23, (q31_t)0x80EA4712, (q31_t)0xF0B8A401, + (q31_t)0x80F050DB, (q31_t)0xF086BD39, (q31_t)0x80F66E3C, + (q31_t)0xF054D8D4, (q31_t)0x80FC9F35, (q31_t)0xF022F6DA, + (q31_t)0x8102E3C3, (q31_t)0xEFF11752, (q31_t)0x81093BE8, + (q31_t)0xEFBF3A44, (q31_t)0x810FA7A0, (q31_t)0xEF8D5FB8, + (q31_t)0x811626EC, (q31_t)0xEF5B87B5, (q31_t)0x811CB9CA, + (q31_t)0xEF29B243, (q31_t)0x81236039, (q31_t)0xEEF7DF6A, + (q31_t)0x812A1A39, (q31_t)0xEEC60F31, (q31_t)0x8130E7C8, + (q31_t)0xEE9441A0, (q31_t)0x8137C8E6, (q31_t)0xEE6276BF, + (q31_t)0x813EBD90, (q31_t)0xEE30AE95, (q31_t)0x8145C5C6, + (q31_t)0xEDFEE92B, (q31_t)0x814CE188, (q31_t)0xEDCD2687, + (q31_t)0x815410D3, (q31_t)0xED9B66B2, (q31_t)0x815B53A8, + (q31_t)0xED69A9B2, (q31_t)0x8162AA03, (q31_t)0xED37EF91, + (q31_t)0x816A13E6, (q31_t)0xED063855, (q31_t)0x8171914E, + (q31_t)0xECD48406, (q31_t)0x8179223A, (q31_t)0xECA2D2AC, + (q31_t)0x8180C6A9, (q31_t)0xEC71244F, (q31_t)0x81887E9A, + (q31_t)0xEC3F78F5, (q31_t)0x81904A0C, (q31_t)0xEC0DD0A8, + (q31_t)0x819828FD, (q31_t)0xEBDC2B6D, (q31_t)0x81A01B6C, + (q31_t)0xEBAA894E, (q31_t)0x81A82159, (q31_t)0xEB78EA52, + (q31_t)0x81B03AC1, (q31_t)0xEB474E80, (q31_t)0x81B867A4, + (q31_t)0xEB15B5E0, (q31_t)0x81C0A801, (q31_t)0xEAE4207A, + (q31_t)0x81C8FBD5, (q31_t)0xEAB28E55, (q31_t)0x81D16320, + (q31_t)0xEA80FF79, (q31_t)0x81D9DDE1, (q31_t)0xEA4F73EE, + (q31_t)0x81E26C16, (q31_t)0xEA1DEBBB, (q31_t)0x81EB0DBD, + (q31_t)0xE9EC66E8, (q31_t)0x81F3C2D7, (q31_t)0xE9BAE57C, + (q31_t)0x81FC8B60, (q31_t)0xE9896780, (q31_t)0x82056758, + (q31_t)0xE957ECFB, (q31_t)0x820E56BE, (q31_t)0xE92675F4, + (q31_t)0x8217598F, (q31_t)0xE8F50273, (q31_t)0x82206FCB, + (q31_t)0xE8C3927F, (q31_t)0x82299971, (q31_t)0xE8922621, + (q31_t)0x8232D67E, (q31_t)0xE860BD60, (q31_t)0x823C26F2, + (q31_t)0xE82F5844, (q31_t)0x82458ACB, (q31_t)0xE7FDF6D3, + (q31_t)0x824F0208, (q31_t)0xE7CC9917, (q31_t)0x82588CA6, + (q31_t)0xE79B3F16, (q31_t)0x82622AA5, (q31_t)0xE769E8D8, + (q31_t)0x826BDC04, (q31_t)0xE7389664, (q31_t)0x8275A0C0, + (q31_t)0xE70747C3, (q31_t)0x827F78D8, (q31_t)0xE6D5FCFC, + (q31_t)0x8289644A, (q31_t)0xE6A4B616, (q31_t)0x82936316, + (q31_t)0xE6737319, (q31_t)0x829D753A, (q31_t)0xE642340D, + (q31_t)0x82A79AB3, (q31_t)0xE610F8F9, (q31_t)0x82B1D381, + (q31_t)0xE5DFC1E4, (q31_t)0x82BC1FA1, (q31_t)0xE5AE8ED8, + (q31_t)0x82C67F13, (q31_t)0xE57D5FDA, (q31_t)0x82D0F1D5, + (q31_t)0xE54C34F3, (q31_t)0x82DB77E5, (q31_t)0xE51B0E2A, + (q31_t)0x82E61141, (q31_t)0xE4E9EB86, (q31_t)0x82F0BDE8, + (q31_t)0xE4B8CD10, (q31_t)0x82FB7DD8, (q31_t)0xE487B2CF, + (q31_t)0x8306510F, (q31_t)0xE4569CCB, (q31_t)0x8311378C, + (q31_t)0xE4258B0A, (q31_t)0x831C314E, (q31_t)0xE3F47D95, + (q31_t)0x83273E52, (q31_t)0xE3C37473, (q31_t)0x83325E97, + (q31_t)0xE3926FAC, (q31_t)0x833D921A, (q31_t)0xE3616F47, + (q31_t)0x8348D8DB, (q31_t)0xE330734C, (q31_t)0x835432D8, + (q31_t)0xE2FF7BC3, (q31_t)0x835FA00E, (q31_t)0xE2CE88B2, + (q31_t)0x836B207D, (q31_t)0xE29D9A22, (q31_t)0x8376B422, + (q31_t)0xE26CB01A, (q31_t)0x83825AFB, (q31_t)0xE23BCAA2, + (q31_t)0x838E1507, (q31_t)0xE20AE9C1, (q31_t)0x8399E244, + (q31_t)0xE1DA0D7E, (q31_t)0x83A5C2B0, (q31_t)0xE1A935E1, + (q31_t)0x83B1B649, (q31_t)0xE17862F3, (q31_t)0x83BDBD0D, + (q31_t)0xE14794B9, (q31_t)0x83C9D6FB, (q31_t)0xE116CB3D, + (q31_t)0x83D60411, (q31_t)0xE0E60684, (q31_t)0x83E2444D, + (q31_t)0xE0B54698, (q31_t)0x83EE97AC, (q31_t)0xE0848B7F, + (q31_t)0x83FAFE2E, (q31_t)0xE053D541, (q31_t)0x840777CF, + (q31_t)0xE02323E5, (q31_t)0x8414048F, (q31_t)0xDFF27773, + (q31_t)0x8420A46B, (q31_t)0xDFC1CFF2, (q31_t)0x842D5761, + (q31_t)0xDF912D6A, (q31_t)0x843A1D70, (q31_t)0xDF608FE3, + (q31_t)0x8446F695, (q31_t)0xDF2FF764, (q31_t)0x8453E2CE, + (q31_t)0xDEFF63F4, (q31_t)0x8460E21A, (q31_t)0xDECED59B, + (q31_t)0x846DF476, (q31_t)0xDE9E4C60, (q31_t)0x847B19E1, + (q31_t)0xDE6DC84B, (q31_t)0x84885257, (q31_t)0xDE3D4963, + (q31_t)0x84959DD9, (q31_t)0xDE0CCFB1, (q31_t)0x84A2FC62, + (q31_t)0xDDDC5B3A, (q31_t)0x84B06DF1, (q31_t)0xDDABEC07, + (q31_t)0x84BDF285, (q31_t)0xDD7B8220, (q31_t)0x84CB8A1B, + (q31_t)0xDD4B1D8B, (q31_t)0x84D934B0, (q31_t)0xDD1ABE51, + (q31_t)0x84E6F244, (q31_t)0xDCEA6478, (q31_t)0x84F4C2D3, + (q31_t)0xDCBA1008, (q31_t)0x8502A65C, (q31_t)0xDC89C108, + (q31_t)0x85109CDC, (q31_t)0xDC597781, (q31_t)0x851EA652, + (q31_t)0xDC293379, (q31_t)0x852CC2BA, (q31_t)0xDBF8F4F8, + (q31_t)0x853AF214, (q31_t)0xDBC8BC05, (q31_t)0x8549345C, + (q31_t)0xDB9888A8, (q31_t)0x85578991, (q31_t)0xDB685AE8, + (q31_t)0x8565F1B0, (q31_t)0xDB3832CD, (q31_t)0x85746CB7, + (q31_t)0xDB08105E, (q31_t)0x8582FAA4, (q31_t)0xDAD7F3A2, + (q31_t)0x85919B75, (q31_t)0xDAA7DCA1, (q31_t)0x85A04F28, + (q31_t)0xDA77CB62, (q31_t)0x85AF15B9, (q31_t)0xDA47BFED, + (q31_t)0x85BDEF27, (q31_t)0xDA17BA4A, (q31_t)0x85CCDB70, + (q31_t)0xD9E7BA7E, (q31_t)0x85DBDA91, (q31_t)0xD9B7C093, + (q31_t)0x85EAEC88, (q31_t)0xD987CC8F, (q31_t)0x85FA1152, + (q31_t)0xD957DE7A, (q31_t)0x860948EE, (q31_t)0xD927F65B, + (q31_t)0x86189359, (q31_t)0xD8F81439, (q31_t)0x8627F090, + (q31_t)0xD8C8381C, (q31_t)0x86376092, (q31_t)0xD898620C, + (q31_t)0x8646E35B, (q31_t)0xD868920F, (q31_t)0x865678EA, + (q31_t)0xD838C82D, (q31_t)0x8666213C, (q31_t)0xD809046D, + (q31_t)0x8675DC4E, (q31_t)0xD7D946D7, (q31_t)0x8685AA1F, + (q31_t)0xD7A98F73, (q31_t)0x86958AAB, (q31_t)0xD779DE46, + (q31_t)0x86A57DF1, (q31_t)0xD74A335A, (q31_t)0x86B583EE, + (q31_t)0xD71A8EB5, (q31_t)0x86C59C9F, (q31_t)0xD6EAF05E, + (q31_t)0x86D5C802, (q31_t)0xD6BB585D, (q31_t)0x86E60614, + (q31_t)0xD68BC6BA, (q31_t)0x86F656D3, (q31_t)0xD65C3B7B, + (q31_t)0x8706BA3C, (q31_t)0xD62CB6A7, (q31_t)0x8717304E, + (q31_t)0xD5FD3847, (q31_t)0x8727B904, (q31_t)0xD5CDC062, + (q31_t)0x8738545E, (q31_t)0xD59E4EFE, (q31_t)0x87490257, + (q31_t)0xD56EE424, (q31_t)0x8759C2EF, (q31_t)0xD53F7FDA, + (q31_t)0x876A9621, (q31_t)0xD5102227, (q31_t)0x877B7BEC, + (q31_t)0xD4E0CB14, (q31_t)0x878C744C, (q31_t)0xD4B17AA7, + (q31_t)0x879D7F40, (q31_t)0xD48230E8, (q31_t)0x87AE9CC5, + (q31_t)0xD452EDDE, (q31_t)0x87BFCCD7, (q31_t)0xD423B190, + (q31_t)0x87D10F75, (q31_t)0xD3F47C06, (q31_t)0x87E2649B, + (q31_t)0xD3C54D46, (q31_t)0x87F3CC47, (q31_t)0xD3962559, + (q31_t)0x88054677, (q31_t)0xD3670445, (q31_t)0x8816D327, + (q31_t)0xD337EA12, (q31_t)0x88287255, (q31_t)0xD308D6C6, + (q31_t)0x883A23FE, (q31_t)0xD2D9CA6A, (q31_t)0x884BE820, + (q31_t)0xD2AAC504, (q31_t)0x885DBEB7, (q31_t)0xD27BC69C, + (q31_t)0x886FA7C2, (q31_t)0xD24CCF38, (q31_t)0x8881A33C, + (q31_t)0xD21DDEE1, (q31_t)0x8893B124, (q31_t)0xD1EEF59E, + (q31_t)0x88A5D177, (q31_t)0xD1C01374, (q31_t)0x88B80431, + (q31_t)0xD191386D, (q31_t)0x88CA4951, (q31_t)0xD162648F, + (q31_t)0x88DCA0D3, (q31_t)0xD13397E1, (q31_t)0x88EF0AB4, + (q31_t)0xD104D26B, (q31_t)0x890186F1, (q31_t)0xD0D61433, + (q31_t)0x89141589, (q31_t)0xD0A75D42, (q31_t)0x8926B677, + (q31_t)0xD078AD9D, (q31_t)0x893969B9, (q31_t)0xD04A054D, + (q31_t)0x894C2F4C, (q31_t)0xD01B6459, (q31_t)0x895F072D, + (q31_t)0xCFECCAC7, (q31_t)0x8971F15A, (q31_t)0xCFBE389F, + (q31_t)0x8984EDCF, (q31_t)0xCF8FADE8, (q31_t)0x8997FC89, + (q31_t)0xCF612AAA, (q31_t)0x89AB1D86, (q31_t)0xCF32AEEB, + (q31_t)0x89BE50C3, (q31_t)0xCF043AB2, (q31_t)0x89D1963C, + (q31_t)0xCED5CE08, (q31_t)0x89E4EDEE, (q31_t)0xCEA768F2, + (q31_t)0x89F857D8, (q31_t)0xCE790B78, (q31_t)0x8A0BD3F5, + (q31_t)0xCE4AB5A2, (q31_t)0x8A1F6242, (q31_t)0xCE1C6776, + (q31_t)0x8A3302BD, (q31_t)0xCDEE20FC, (q31_t)0x8A46B563, + (q31_t)0xCDBFE23A, (q31_t)0x8A5A7A30, (q31_t)0xCD91AB38, + (q31_t)0x8A6E5122, (q31_t)0xCD637BFD, (q31_t)0x8A823A35, + (q31_t)0xCD355490, (q31_t)0x8A963567, (q31_t)0xCD0734F8, + (q31_t)0x8AAA42B4, (q31_t)0xCCD91D3D, (q31_t)0x8ABE6219, + (q31_t)0xCCAB0D65, (q31_t)0x8AD29393, (q31_t)0xCC7D0577, + (q31_t)0x8AE6D71F, (q31_t)0xCC4F057B, (q31_t)0x8AFB2CBA, + (q31_t)0xCC210D78, (q31_t)0x8B0F9461, (q31_t)0xCBF31D75, + (q31_t)0x8B240E10, (q31_t)0xCBC53578, (q31_t)0x8B3899C5, + (q31_t)0xCB975589, (q31_t)0x8B4D377C, (q31_t)0xCB697DB0, + (q31_t)0x8B61E732, (q31_t)0xCB3BADF2, (q31_t)0x8B76A8E4, + (q31_t)0xCB0DE658, (q31_t)0x8B8B7C8F, (q31_t)0xCAE026E8, + (q31_t)0x8BA0622F, (q31_t)0xCAB26FA9, (q31_t)0x8BB559C1, + (q31_t)0xCA84C0A2, (q31_t)0x8BCA6342, (q31_t)0xCA5719DB, + (q31_t)0x8BDF7EAF, (q31_t)0xCA297B5A, (q31_t)0x8BF4AC05, + (q31_t)0xC9FBE527, (q31_t)0x8C09EB40, (q31_t)0xC9CE5748, + (q31_t)0x8C1F3C5C, (q31_t)0xC9A0D1C4, (q31_t)0x8C349F58, + (q31_t)0xC97354A3, (q31_t)0x8C4A142F, (q31_t)0xC945DFEC, + (q31_t)0x8C5F9ADD, (q31_t)0xC91873A5, (q31_t)0x8C753361, + (q31_t)0xC8EB0FD6, (q31_t)0x8C8ADDB6, (q31_t)0xC8BDB485, + (q31_t)0x8CA099D9, (q31_t)0xC89061BA, (q31_t)0x8CB667C7, + (q31_t)0xC863177B, (q31_t)0x8CCC477D, (q31_t)0xC835D5D0, + (q31_t)0x8CE238F6, (q31_t)0xC8089CBF, (q31_t)0x8CF83C30, + (q31_t)0xC7DB6C50, (q31_t)0x8D0E5127, (q31_t)0xC7AE4489, + (q31_t)0x8D2477D8, (q31_t)0xC7812571, (q31_t)0x8D3AB03F, + (q31_t)0xC7540F10, (q31_t)0x8D50FA59, (q31_t)0xC727016C, + (q31_t)0x8D675623, (q31_t)0xC6F9FC8D, (q31_t)0x8D7DC399, + (q31_t)0xC6CD0079, (q31_t)0x8D9442B7, (q31_t)0xC6A00D36, + (q31_t)0x8DAAD37B, (q31_t)0xC67322CD, (q31_t)0x8DC175E0, + (q31_t)0xC6464144, (q31_t)0x8DD829E4, (q31_t)0xC61968A2, + (q31_t)0x8DEEEF82, (q31_t)0xC5EC98ED, (q31_t)0x8E05C6B7, + (q31_t)0xC5BFD22E, (q31_t)0x8E1CAF80, (q31_t)0xC593146A, + (q31_t)0x8E33A9D9, (q31_t)0xC5665FA8, (q31_t)0x8E4AB5BF, + (q31_t)0xC539B3F0, (q31_t)0x8E61D32D, (q31_t)0xC50D1148, + (q31_t)0x8E790222, (q31_t)0xC4E077B8, (q31_t)0x8E904298, + (q31_t)0xC4B3E746, (q31_t)0x8EA7948C, (q31_t)0xC4875FF8, + (q31_t)0x8EBEF7FB, (q31_t)0xC45AE1D7, (q31_t)0x8ED66CE1, + (q31_t)0xC42E6CE8, (q31_t)0x8EEDF33B, (q31_t)0xC4020132, + (q31_t)0x8F058B04, (q31_t)0xC3D59EBD, (q31_t)0x8F1D343A, + (q31_t)0xC3A9458F, (q31_t)0x8F34EED8, (q31_t)0xC37CF5B0, + (q31_t)0x8F4CBADB, (q31_t)0xC350AF25, (q31_t)0x8F64983F, + (q31_t)0xC32471F6, (q31_t)0x8F7C8701, (q31_t)0xC2F83E2A, + (q31_t)0x8F94871D, (q31_t)0xC2CC13C7, (q31_t)0x8FAC988E, + (q31_t)0xC29FF2D4, (q31_t)0x8FC4BB53, (q31_t)0xC273DB58, + (q31_t)0x8FDCEF66, (q31_t)0xC247CD5A, (q31_t)0x8FF534C4, + (q31_t)0xC21BC8E0, (q31_t)0x900D8B69, (q31_t)0xC1EFCDF2, + (q31_t)0x9025F352, (q31_t)0xC1C3DC96, (q31_t)0x903E6C7A, + (q31_t)0xC197F4D3, (q31_t)0x9056F6DF, (q31_t)0xC16C16B0, + (q31_t)0x906F927B, (q31_t)0xC1404233, (q31_t)0x90883F4C, + (q31_t)0xC1147763, (q31_t)0x90A0FD4E, (q31_t)0xC0E8B648, + (q31_t)0x90B9CC7C, (q31_t)0xC0BCFEE7, (q31_t)0x90D2ACD3, + (q31_t)0xC0915147, (q31_t)0x90EB9E50, (q31_t)0xC065AD70, + (q31_t)0x9104A0ED, (q31_t)0xC03A1368, (q31_t)0x911DB4A8, + (q31_t)0xC00E8335, (q31_t)0x9136D97D, (q31_t)0xBFE2FCDF, + (q31_t)0x91500F67, (q31_t)0xBFB7806C, (q31_t)0x91695663, + (q31_t)0xBF8C0DE2, (q31_t)0x9182AE6C, (q31_t)0xBF60A54A, + (q31_t)0x919C1780, (q31_t)0xBF3546A8, (q31_t)0x91B5919A, + (q31_t)0xBF09F204, (q31_t)0x91CF1CB6, (q31_t)0xBEDEA765, + (q31_t)0x91E8B8D0, (q31_t)0xBEB366D1, (q31_t)0x920265E4, + (q31_t)0xBE88304F, (q31_t)0x921C23EE, (q31_t)0xBE5D03E5, + (q31_t)0x9235F2EB, (q31_t)0xBE31E19B, (q31_t)0x924FD2D6, + (q31_t)0xBE06C977, (q31_t)0x9269C3AC, (q31_t)0xBDDBBB7F, + (q31_t)0x9283C567, (q31_t)0xBDB0B7BA, (q31_t)0x929DD805, + (q31_t)0xBD85BE2F, (q31_t)0x92B7FB82, (q31_t)0xBD5ACEE5, + (q31_t)0x92D22FD8, (q31_t)0xBD2FE9E1, (q31_t)0x92EC7505, + (q31_t)0xBD050F2C, (q31_t)0x9306CB04, (q31_t)0xBCDA3ECA, + (q31_t)0x932131D1, (q31_t)0xBCAF78C3, (q31_t)0x933BA968, + (q31_t)0xBC84BD1E, (q31_t)0x935631C5, (q31_t)0xBC5A0BE1, + (q31_t)0x9370CAE4, (q31_t)0xBC2F6513, (q31_t)0x938B74C0, + (q31_t)0xBC04C8BA, (q31_t)0x93A62F56, (q31_t)0xBBDA36DC, + (q31_t)0x93C0FAA2, (q31_t)0xBBAFAF81, (q31_t)0x93DBD69F, + (q31_t)0xBB8532AF, (q31_t)0x93F6C34A, (q31_t)0xBB5AC06C, + (q31_t)0x9411C09D, (q31_t)0xBB3058C0, (q31_t)0x942CCE95, + (q31_t)0xBB05FBB0, (q31_t)0x9447ED2F, (q31_t)0xBADBA943, + (q31_t)0x94631C64, (q31_t)0xBAB1617F, (q31_t)0x947E5C32, + (q31_t)0xBA87246C, (q31_t)0x9499AC95, (q31_t)0xBA5CF210, + (q31_t)0x94B50D87, (q31_t)0xBA32CA70, (q31_t)0x94D07F05, + (q31_t)0xBA08AD94, (q31_t)0x94EC010B, (q31_t)0xB9DE9B83, + (q31_t)0x95079393, (q31_t)0xB9B49442, (q31_t)0x9523369B, + (q31_t)0xB98A97D8, (q31_t)0x953EEA1E, (q31_t)0xB960A64B, + (q31_t)0x955AAE17, (q31_t)0xB936BFA3, (q31_t)0x95768282, + (q31_t)0xB90CE3E6, (q31_t)0x9592675B, (q31_t)0xB8E31319, + (q31_t)0x95AE5C9E, (q31_t)0xB8B94D44, (q31_t)0x95CA6246, + (q31_t)0xB88F926C, (q31_t)0x95E6784F, (q31_t)0xB865E299, + (q31_t)0x96029EB5, (q31_t)0xB83C3DD1, (q31_t)0x961ED573, + (q31_t)0xB812A419, (q31_t)0x963B1C85, (q31_t)0xB7E9157A, + (q31_t)0x965773E7, (q31_t)0xB7BF91F8, (q31_t)0x9673DB94, + (q31_t)0xB796199B, (q31_t)0x96905387, (q31_t)0xB76CAC68, + (q31_t)0x96ACDBBD, (q31_t)0xB7434A67, (q31_t)0x96C97431, + (q31_t)0xB719F39D, (q31_t)0x96E61CDF, (q31_t)0xB6F0A811, + (q31_t)0x9702D5C2, (q31_t)0xB6C767CA, (q31_t)0x971F9ED6, + (q31_t)0xB69E32CD, (q31_t)0x973C7816, (q31_t)0xB6750921, + (q31_t)0x9759617E, (q31_t)0xB64BEACC, (q31_t)0x97765B0A, + (q31_t)0xB622D7D5, (q31_t)0x979364B5, (q31_t)0xB5F9D042, + (q31_t)0x97B07E7A, (q31_t)0xB5D0D41A, (q31_t)0x97CDA855, + (q31_t)0xB5A7E362, (q31_t)0x97EAE241, (q31_t)0xB57EFE21, + (q31_t)0x98082C3B, (q31_t)0xB556245E, (q31_t)0x9825863D, + (q31_t)0xB52D561E, (q31_t)0x9842F043, (q31_t)0xB5049368, + (q31_t)0x98606A48, (q31_t)0xB4DBDC42, (q31_t)0x987DF449, + (q31_t)0xB4B330B2, (q31_t)0x989B8E3F, (q31_t)0xB48A90C0, + (q31_t)0x98B93828, (q31_t)0xB461FC70, (q31_t)0x98D6F1FE, + (q31_t)0xB43973C9, (q31_t)0x98F4BBBC, (q31_t)0xB410F6D2, + (q31_t)0x9912955E, (q31_t)0xB3E88591, (q31_t)0x99307EE0, + (q31_t)0xB3C0200C, (q31_t)0x994E783C, (q31_t)0xB397C649, + (q31_t)0x996C816F, (q31_t)0xB36F784E, (q31_t)0x998A9A73, + (q31_t)0xB3473622, (q31_t)0x99A8C344, (q31_t)0xB31EFFCB, + (q31_t)0x99C6FBDE, (q31_t)0xB2F6D54F, (q31_t)0x99E5443A, + (q31_t)0xB2CEB6B5, (q31_t)0x9A039C56, (q31_t)0xB2A6A401, + (q31_t)0x9A22042C, (q31_t)0xB27E9D3B, (q31_t)0x9A407BB8, + (q31_t)0xB256A26A, (q31_t)0x9A5F02F5, (q31_t)0xB22EB392, + (q31_t)0x9A7D99DD, (q31_t)0xB206D0BA, (q31_t)0x9A9C406D, + (q31_t)0xB1DEF9E8, (q31_t)0x9ABAF6A0, (q31_t)0xB1B72F23, + (q31_t)0x9AD9BC71, (q31_t)0xB18F7070, (q31_t)0x9AF891DB, + (q31_t)0xB167BDD6, (q31_t)0x9B1776D9, (q31_t)0xB140175B, + (q31_t)0x9B366B67, (q31_t)0xB1187D05, (q31_t)0x9B556F80, + (q31_t)0xB0F0EEDA, (q31_t)0x9B748320, (q31_t)0xB0C96CDF, + (q31_t)0x9B93A640, (q31_t)0xB0A1F71C, (q31_t)0x9BB2D8DD, + (q31_t)0xB07A8D97, (q31_t)0x9BD21AF2, (q31_t)0xB0533055, + (q31_t)0x9BF16C7A, (q31_t)0xB02BDF5C, (q31_t)0x9C10CD70, + (q31_t)0xB0049AB2, (q31_t)0x9C303DCF, (q31_t)0xAFDD625F, + (q31_t)0x9C4FBD92, (q31_t)0xAFB63667, (q31_t)0x9C6F4CB5, + (q31_t)0xAF8F16D0, (q31_t)0x9C8EEB33, (q31_t)0xAF6803A1, + (q31_t)0x9CAE9907, (q31_t)0xAF40FCE0, (q31_t)0x9CCE562B, + (q31_t)0xAF1A0293, (q31_t)0x9CEE229C, (q31_t)0xAEF314BF, + (q31_t)0x9D0DFE53, (q31_t)0xAECC336B, (q31_t)0x9D2DE94D, + (q31_t)0xAEA55E9D, (q31_t)0x9D4DE384, (q31_t)0xAE7E965B, + (q31_t)0x9D6DECF4, (q31_t)0xAE57DAAA, (q31_t)0x9D8E0596, + (q31_t)0xAE312B91, (q31_t)0x9DAE2D68, (q31_t)0xAE0A8916, + (q31_t)0x9DCE6462, (q31_t)0xADE3F33E, (q31_t)0x9DEEAA82, + (q31_t)0xADBD6A10, (q31_t)0x9E0EFFC1, (q31_t)0xAD96ED91, + (q31_t)0x9E2F641A, (q31_t)0xAD707DC8, (q31_t)0x9E4FD789, + (q31_t)0xAD4A1ABA, (q31_t)0x9E705A09, (q31_t)0xAD23C46D, + (q31_t)0x9E90EB94, (q31_t)0xACFD7AE8, (q31_t)0x9EB18C26, + (q31_t)0xACD73E30, (q31_t)0x9ED23BB9, (q31_t)0xACB10E4A, + (q31_t)0x9EF2FA48, (q31_t)0xAC8AEB3E, (q31_t)0x9F13C7D0, + (q31_t)0xAC64D510, (q31_t)0x9F34A449, (q31_t)0xAC3ECBC7, + (q31_t)0x9F558FB0, (q31_t)0xAC18CF68, (q31_t)0x9F7689FF, + (q31_t)0xABF2DFFA, (q31_t)0x9F979331, (q31_t)0xABCCFD82, + (q31_t)0x9FB8AB41, (q31_t)0xABA72806, (q31_t)0x9FD9D22A, + (q31_t)0xAB815F8C, (q31_t)0x9FFB07E7, (q31_t)0xAB5BA41A, + (q31_t)0xA01C4C72, (q31_t)0xAB35F5B5, (q31_t)0xA03D9FC7, + (q31_t)0xAB105464, (q31_t)0xA05F01E1, (q31_t)0xAAEAC02B, + (q31_t)0xA08072BA, (q31_t)0xAAC53912, (q31_t)0xA0A1F24C, + (q31_t)0xAA9FBF1D, (q31_t)0xA0C38094, (q31_t)0xAA7A5253, + (q31_t)0xA0E51D8C, (q31_t)0xAA54F2B9, (q31_t)0xA106C92E, + (q31_t)0xAA2FA055, (q31_t)0xA1288376, (q31_t)0xAA0A5B2D, + (q31_t)0xA14A4C5E, (q31_t)0xA9E52347, (q31_t)0xA16C23E1, + (q31_t)0xA9BFF8A8, (q31_t)0xA18E09F9, (q31_t)0xA99ADB56, + (q31_t)0xA1AFFEA2, (q31_t)0xA975CB56, (q31_t)0xA1D201D7, + (q31_t)0xA950C8AF, (q31_t)0xA1F41391, (q31_t)0xA92BD366, + (q31_t)0xA21633CD, (q31_t)0xA906EB81, (q31_t)0xA2386283, + (q31_t)0xA8E21106, (q31_t)0xA25A9FB1, (q31_t)0xA8BD43FA, + (q31_t)0xA27CEB4F, (q31_t)0xA8988463, (q31_t)0xA29F4559, + (q31_t)0xA873D246, (q31_t)0xA2C1ADC9, (q31_t)0xA84F2DA9, + (q31_t)0xA2E4249A, (q31_t)0xA82A9693, (q31_t)0xA306A9C7, + (q31_t)0xA8060D08, (q31_t)0xA3293D4B, (q31_t)0xA7E1910E, + (q31_t)0xA34BDF20, (q31_t)0xA7BD22AB, (q31_t)0xA36E8F40, + (q31_t)0xA798C1E4, (q31_t)0xA3914DA7, (q31_t)0xA7746EC0, + (q31_t)0xA3B41A4F, (q31_t)0xA7502943, (q31_t)0xA3D6F533, + (q31_t)0xA72BF173, (q31_t)0xA3F9DE4D, (q31_t)0xA707C756, + (q31_t)0xA41CD598, (q31_t)0xA6E3AAF2, (q31_t)0xA43FDB0F, + (q31_t)0xA6BF9C4B, (q31_t)0xA462EEAC, (q31_t)0xA69B9B68, + (q31_t)0xA4861069, (q31_t)0xA677A84E, (q31_t)0xA4A94042, + (q31_t)0xA653C302, (q31_t)0xA4CC7E31, (q31_t)0xA62FEB8B, + (q31_t)0xA4EFCA31, (q31_t)0xA60C21ED, (q31_t)0xA513243B, + (q31_t)0xA5E8662F, (q31_t)0xA5368C4B, (q31_t)0xA5C4B855, + (q31_t)0xA55A025B, (q31_t)0xA5A11865, (q31_t)0xA57D8666, + (q31_t)0xA57D8666, (q31_t)0xA5A11865, (q31_t)0xA55A025B, + (q31_t)0xA5C4B855, (q31_t)0xA5368C4B, (q31_t)0xA5E8662F, + (q31_t)0xA513243B, (q31_t)0xA60C21ED, (q31_t)0xA4EFCA31, + (q31_t)0xA62FEB8B, (q31_t)0xA4CC7E31, (q31_t)0xA653C302, + (q31_t)0xA4A94042, (q31_t)0xA677A84E, (q31_t)0xA4861069, + (q31_t)0xA69B9B68, (q31_t)0xA462EEAC, (q31_t)0xA6BF9C4B, + (q31_t)0xA43FDB0F, (q31_t)0xA6E3AAF2, (q31_t)0xA41CD598, + (q31_t)0xA707C756, (q31_t)0xA3F9DE4D, (q31_t)0xA72BF173, + (q31_t)0xA3D6F533, (q31_t)0xA7502943, (q31_t)0xA3B41A4F, + (q31_t)0xA7746EC0, (q31_t)0xA3914DA7, (q31_t)0xA798C1E4, + (q31_t)0xA36E8F40, (q31_t)0xA7BD22AB, (q31_t)0xA34BDF20, + (q31_t)0xA7E1910E, (q31_t)0xA3293D4B, (q31_t)0xA8060D08, + (q31_t)0xA306A9C7, (q31_t)0xA82A9693, (q31_t)0xA2E4249A, + (q31_t)0xA84F2DA9, (q31_t)0xA2C1ADC9, (q31_t)0xA873D246, + (q31_t)0xA29F4559, (q31_t)0xA8988463, (q31_t)0xA27CEB4F, + (q31_t)0xA8BD43FA, (q31_t)0xA25A9FB1, (q31_t)0xA8E21106, + (q31_t)0xA2386283, (q31_t)0xA906EB81, (q31_t)0xA21633CD, + (q31_t)0xA92BD366, (q31_t)0xA1F41391, (q31_t)0xA950C8AF, + (q31_t)0xA1D201D7, (q31_t)0xA975CB56, (q31_t)0xA1AFFEA2, + (q31_t)0xA99ADB56, (q31_t)0xA18E09F9, (q31_t)0xA9BFF8A8, + (q31_t)0xA16C23E1, (q31_t)0xA9E52347, (q31_t)0xA14A4C5E, + (q31_t)0xAA0A5B2D, (q31_t)0xA1288376, (q31_t)0xAA2FA055, + (q31_t)0xA106C92E, (q31_t)0xAA54F2B9, (q31_t)0xA0E51D8C, + (q31_t)0xAA7A5253, (q31_t)0xA0C38094, (q31_t)0xAA9FBF1D, + (q31_t)0xA0A1F24C, (q31_t)0xAAC53912, (q31_t)0xA08072BA, + (q31_t)0xAAEAC02B, (q31_t)0xA05F01E1, (q31_t)0xAB105464, + (q31_t)0xA03D9FC7, (q31_t)0xAB35F5B5, (q31_t)0xA01C4C72, + (q31_t)0xAB5BA41A, (q31_t)0x9FFB07E7, (q31_t)0xAB815F8C, + (q31_t)0x9FD9D22A, (q31_t)0xABA72806, (q31_t)0x9FB8AB41, + (q31_t)0xABCCFD82, (q31_t)0x9F979331, (q31_t)0xABF2DFFA, + (q31_t)0x9F7689FF, (q31_t)0xAC18CF68, (q31_t)0x9F558FB0, + (q31_t)0xAC3ECBC7, (q31_t)0x9F34A449, (q31_t)0xAC64D510, + (q31_t)0x9F13C7D0, (q31_t)0xAC8AEB3E, (q31_t)0x9EF2FA48, + (q31_t)0xACB10E4A, (q31_t)0x9ED23BB9, (q31_t)0xACD73E30, + (q31_t)0x9EB18C26, (q31_t)0xACFD7AE8, (q31_t)0x9E90EB94, + (q31_t)0xAD23C46D, (q31_t)0x9E705A09, (q31_t)0xAD4A1ABA, + (q31_t)0x9E4FD789, (q31_t)0xAD707DC8, (q31_t)0x9E2F641A, + (q31_t)0xAD96ED91, (q31_t)0x9E0EFFC1, (q31_t)0xADBD6A10, + (q31_t)0x9DEEAA82, (q31_t)0xADE3F33E, (q31_t)0x9DCE6462, + (q31_t)0xAE0A8916, (q31_t)0x9DAE2D68, (q31_t)0xAE312B91, + (q31_t)0x9D8E0596, (q31_t)0xAE57DAAA, (q31_t)0x9D6DECF4, + (q31_t)0xAE7E965B, (q31_t)0x9D4DE384, (q31_t)0xAEA55E9D, + (q31_t)0x9D2DE94D, (q31_t)0xAECC336B, (q31_t)0x9D0DFE53, + (q31_t)0xAEF314BF, (q31_t)0x9CEE229C, (q31_t)0xAF1A0293, + (q31_t)0x9CCE562B, (q31_t)0xAF40FCE0, (q31_t)0x9CAE9907, + (q31_t)0xAF6803A1, (q31_t)0x9C8EEB33, (q31_t)0xAF8F16D0, + (q31_t)0x9C6F4CB5, (q31_t)0xAFB63667, (q31_t)0x9C4FBD92, + (q31_t)0xAFDD625F, (q31_t)0x9C303DCF, (q31_t)0xB0049AB2, + (q31_t)0x9C10CD70, (q31_t)0xB02BDF5C, (q31_t)0x9BF16C7A, + (q31_t)0xB0533055, (q31_t)0x9BD21AF2, (q31_t)0xB07A8D97, + (q31_t)0x9BB2D8DD, (q31_t)0xB0A1F71C, (q31_t)0x9B93A640, + (q31_t)0xB0C96CDF, (q31_t)0x9B748320, (q31_t)0xB0F0EEDA, + (q31_t)0x9B556F80, (q31_t)0xB1187D05, (q31_t)0x9B366B67, + (q31_t)0xB140175B, (q31_t)0x9B1776D9, (q31_t)0xB167BDD6, + (q31_t)0x9AF891DB, (q31_t)0xB18F7070, (q31_t)0x9AD9BC71, + (q31_t)0xB1B72F23, (q31_t)0x9ABAF6A0, (q31_t)0xB1DEF9E8, + (q31_t)0x9A9C406D, (q31_t)0xB206D0BA, (q31_t)0x9A7D99DD, + (q31_t)0xB22EB392, (q31_t)0x9A5F02F5, (q31_t)0xB256A26A, + (q31_t)0x9A407BB8, (q31_t)0xB27E9D3B, (q31_t)0x9A22042C, + (q31_t)0xB2A6A401, (q31_t)0x9A039C56, (q31_t)0xB2CEB6B5, + (q31_t)0x99E5443A, (q31_t)0xB2F6D54F, (q31_t)0x99C6FBDE, + (q31_t)0xB31EFFCB, (q31_t)0x99A8C344, (q31_t)0xB3473622, + (q31_t)0x998A9A73, (q31_t)0xB36F784E, (q31_t)0x996C816F, + (q31_t)0xB397C649, (q31_t)0x994E783C, (q31_t)0xB3C0200C, + (q31_t)0x99307EE0, (q31_t)0xB3E88591, (q31_t)0x9912955E, + (q31_t)0xB410F6D2, (q31_t)0x98F4BBBC, (q31_t)0xB43973C9, + (q31_t)0x98D6F1FE, (q31_t)0xB461FC70, (q31_t)0x98B93828, + (q31_t)0xB48A90C0, (q31_t)0x989B8E3F, (q31_t)0xB4B330B2, + (q31_t)0x987DF449, (q31_t)0xB4DBDC42, (q31_t)0x98606A48, + (q31_t)0xB5049368, (q31_t)0x9842F043, (q31_t)0xB52D561E, + (q31_t)0x9825863D, (q31_t)0xB556245E, (q31_t)0x98082C3B, + (q31_t)0xB57EFE21, (q31_t)0x97EAE241, (q31_t)0xB5A7E362, + (q31_t)0x97CDA855, (q31_t)0xB5D0D41A, (q31_t)0x97B07E7A, + (q31_t)0xB5F9D042, (q31_t)0x979364B5, (q31_t)0xB622D7D5, + (q31_t)0x97765B0A, (q31_t)0xB64BEACC, (q31_t)0x9759617E, + (q31_t)0xB6750921, (q31_t)0x973C7816, (q31_t)0xB69E32CD, + (q31_t)0x971F9ED6, (q31_t)0xB6C767CA, (q31_t)0x9702D5C2, + (q31_t)0xB6F0A811, (q31_t)0x96E61CDF, (q31_t)0xB719F39D, + (q31_t)0x96C97431, (q31_t)0xB7434A67, (q31_t)0x96ACDBBD, + (q31_t)0xB76CAC68, (q31_t)0x96905387, (q31_t)0xB796199B, + (q31_t)0x9673DB94, (q31_t)0xB7BF91F8, (q31_t)0x965773E7, + (q31_t)0xB7E9157A, (q31_t)0x963B1C85, (q31_t)0xB812A419, + (q31_t)0x961ED573, (q31_t)0xB83C3DD1, (q31_t)0x96029EB5, + (q31_t)0xB865E299, (q31_t)0x95E6784F, (q31_t)0xB88F926C, + (q31_t)0x95CA6246, (q31_t)0xB8B94D44, (q31_t)0x95AE5C9E, + (q31_t)0xB8E31319, (q31_t)0x9592675B, (q31_t)0xB90CE3E6, + (q31_t)0x95768282, (q31_t)0xB936BFA3, (q31_t)0x955AAE17, + (q31_t)0xB960A64B, (q31_t)0x953EEA1E, (q31_t)0xB98A97D8, + (q31_t)0x9523369B, (q31_t)0xB9B49442, (q31_t)0x95079393, + (q31_t)0xB9DE9B83, (q31_t)0x94EC010B, (q31_t)0xBA08AD94, + (q31_t)0x94D07F05, (q31_t)0xBA32CA70, (q31_t)0x94B50D87, + (q31_t)0xBA5CF210, (q31_t)0x9499AC95, (q31_t)0xBA87246C, + (q31_t)0x947E5C32, (q31_t)0xBAB1617F, (q31_t)0x94631C64, + (q31_t)0xBADBA943, (q31_t)0x9447ED2F, (q31_t)0xBB05FBB0, + (q31_t)0x942CCE95, (q31_t)0xBB3058C0, (q31_t)0x9411C09D, + (q31_t)0xBB5AC06C, (q31_t)0x93F6C34A, (q31_t)0xBB8532AF, + (q31_t)0x93DBD69F, (q31_t)0xBBAFAF81, (q31_t)0x93C0FAA2, + (q31_t)0xBBDA36DC, (q31_t)0x93A62F56, (q31_t)0xBC04C8BA, + (q31_t)0x938B74C0, (q31_t)0xBC2F6513, (q31_t)0x9370CAE4, + (q31_t)0xBC5A0BE1, (q31_t)0x935631C5, (q31_t)0xBC84BD1E, + (q31_t)0x933BA968, (q31_t)0xBCAF78C3, (q31_t)0x932131D1, + (q31_t)0xBCDA3ECA, (q31_t)0x9306CB04, (q31_t)0xBD050F2C, + (q31_t)0x92EC7505, (q31_t)0xBD2FE9E1, (q31_t)0x92D22FD8, + (q31_t)0xBD5ACEE5, (q31_t)0x92B7FB82, (q31_t)0xBD85BE2F, + (q31_t)0x929DD805, (q31_t)0xBDB0B7BA, (q31_t)0x9283C567, + (q31_t)0xBDDBBB7F, (q31_t)0x9269C3AC, (q31_t)0xBE06C977, + (q31_t)0x924FD2D6, (q31_t)0xBE31E19B, (q31_t)0x9235F2EB, + (q31_t)0xBE5D03E5, (q31_t)0x921C23EE, (q31_t)0xBE88304F, + (q31_t)0x920265E4, (q31_t)0xBEB366D1, (q31_t)0x91E8B8D0, + (q31_t)0xBEDEA765, (q31_t)0x91CF1CB6, (q31_t)0xBF09F204, + (q31_t)0x91B5919A, (q31_t)0xBF3546A8, (q31_t)0x919C1780, + (q31_t)0xBF60A54A, (q31_t)0x9182AE6C, (q31_t)0xBF8C0DE2, + (q31_t)0x91695663, (q31_t)0xBFB7806C, (q31_t)0x91500F67, + (q31_t)0xBFE2FCDF, (q31_t)0x9136D97D, (q31_t)0xC00E8335, + (q31_t)0x911DB4A8, (q31_t)0xC03A1368, (q31_t)0x9104A0ED, + (q31_t)0xC065AD70, (q31_t)0x90EB9E50, (q31_t)0xC0915147, + (q31_t)0x90D2ACD3, (q31_t)0xC0BCFEE7, (q31_t)0x90B9CC7C, + (q31_t)0xC0E8B648, (q31_t)0x90A0FD4E, (q31_t)0xC1147763, + (q31_t)0x90883F4C, (q31_t)0xC1404233, (q31_t)0x906F927B, + (q31_t)0xC16C16B0, (q31_t)0x9056F6DF, (q31_t)0xC197F4D3, + (q31_t)0x903E6C7A, (q31_t)0xC1C3DC96, (q31_t)0x9025F352, + (q31_t)0xC1EFCDF2, (q31_t)0x900D8B69, (q31_t)0xC21BC8E0, + (q31_t)0x8FF534C4, (q31_t)0xC247CD5A, (q31_t)0x8FDCEF66, + (q31_t)0xC273DB58, (q31_t)0x8FC4BB53, (q31_t)0xC29FF2D4, + (q31_t)0x8FAC988E, (q31_t)0xC2CC13C7, (q31_t)0x8F94871D, + (q31_t)0xC2F83E2A, (q31_t)0x8F7C8701, (q31_t)0xC32471F6, + (q31_t)0x8F64983F, (q31_t)0xC350AF25, (q31_t)0x8F4CBADB, + (q31_t)0xC37CF5B0, (q31_t)0x8F34EED8, (q31_t)0xC3A9458F, + (q31_t)0x8F1D343A, (q31_t)0xC3D59EBD, (q31_t)0x8F058B04, + (q31_t)0xC4020132, (q31_t)0x8EEDF33B, (q31_t)0xC42E6CE8, + (q31_t)0x8ED66CE1, (q31_t)0xC45AE1D7, (q31_t)0x8EBEF7FB, + (q31_t)0xC4875FF8, (q31_t)0x8EA7948C, (q31_t)0xC4B3E746, + (q31_t)0x8E904298, (q31_t)0xC4E077B8, (q31_t)0x8E790222, + (q31_t)0xC50D1148, (q31_t)0x8E61D32D, (q31_t)0xC539B3F0, + (q31_t)0x8E4AB5BF, (q31_t)0xC5665FA8, (q31_t)0x8E33A9D9, + (q31_t)0xC593146A, (q31_t)0x8E1CAF80, (q31_t)0xC5BFD22E, + (q31_t)0x8E05C6B7, (q31_t)0xC5EC98ED, (q31_t)0x8DEEEF82, + (q31_t)0xC61968A2, (q31_t)0x8DD829E4, (q31_t)0xC6464144, + (q31_t)0x8DC175E0, (q31_t)0xC67322CD, (q31_t)0x8DAAD37B, + (q31_t)0xC6A00D36, (q31_t)0x8D9442B7, (q31_t)0xC6CD0079, + (q31_t)0x8D7DC399, (q31_t)0xC6F9FC8D, (q31_t)0x8D675623, + (q31_t)0xC727016C, (q31_t)0x8D50FA59, (q31_t)0xC7540F10, + (q31_t)0x8D3AB03F, (q31_t)0xC7812571, (q31_t)0x8D2477D8, + (q31_t)0xC7AE4489, (q31_t)0x8D0E5127, (q31_t)0xC7DB6C50, + (q31_t)0x8CF83C30, (q31_t)0xC8089CBF, (q31_t)0x8CE238F6, + (q31_t)0xC835D5D0, (q31_t)0x8CCC477D, (q31_t)0xC863177B, + (q31_t)0x8CB667C7, (q31_t)0xC89061BA, (q31_t)0x8CA099D9, + (q31_t)0xC8BDB485, (q31_t)0x8C8ADDB6, (q31_t)0xC8EB0FD6, + (q31_t)0x8C753361, (q31_t)0xC91873A5, (q31_t)0x8C5F9ADD, + (q31_t)0xC945DFEC, (q31_t)0x8C4A142F, (q31_t)0xC97354A3, + (q31_t)0x8C349F58, (q31_t)0xC9A0D1C4, (q31_t)0x8C1F3C5C, + (q31_t)0xC9CE5748, (q31_t)0x8C09EB40, (q31_t)0xC9FBE527, + (q31_t)0x8BF4AC05, (q31_t)0xCA297B5A, (q31_t)0x8BDF7EAF, + (q31_t)0xCA5719DB, (q31_t)0x8BCA6342, (q31_t)0xCA84C0A2, + (q31_t)0x8BB559C1, (q31_t)0xCAB26FA9, (q31_t)0x8BA0622F, + (q31_t)0xCAE026E8, (q31_t)0x8B8B7C8F, (q31_t)0xCB0DE658, + (q31_t)0x8B76A8E4, (q31_t)0xCB3BADF2, (q31_t)0x8B61E732, + (q31_t)0xCB697DB0, (q31_t)0x8B4D377C, (q31_t)0xCB975589, + (q31_t)0x8B3899C5, (q31_t)0xCBC53578, (q31_t)0x8B240E10, + (q31_t)0xCBF31D75, (q31_t)0x8B0F9461, (q31_t)0xCC210D78, + (q31_t)0x8AFB2CBA, (q31_t)0xCC4F057B, (q31_t)0x8AE6D71F, + (q31_t)0xCC7D0577, (q31_t)0x8AD29393, (q31_t)0xCCAB0D65, + (q31_t)0x8ABE6219, (q31_t)0xCCD91D3D, (q31_t)0x8AAA42B4, + (q31_t)0xCD0734F8, (q31_t)0x8A963567, (q31_t)0xCD355490, + (q31_t)0x8A823A35, (q31_t)0xCD637BFD, (q31_t)0x8A6E5122, + (q31_t)0xCD91AB38, (q31_t)0x8A5A7A30, (q31_t)0xCDBFE23A, + (q31_t)0x8A46B563, (q31_t)0xCDEE20FC, (q31_t)0x8A3302BD, + (q31_t)0xCE1C6776, (q31_t)0x8A1F6242, (q31_t)0xCE4AB5A2, + (q31_t)0x8A0BD3F5, (q31_t)0xCE790B78, (q31_t)0x89F857D8, + (q31_t)0xCEA768F2, (q31_t)0x89E4EDEE, (q31_t)0xCED5CE08, + (q31_t)0x89D1963C, (q31_t)0xCF043AB2, (q31_t)0x89BE50C3, + (q31_t)0xCF32AEEB, (q31_t)0x89AB1D86, (q31_t)0xCF612AAA, + (q31_t)0x8997FC89, (q31_t)0xCF8FADE8, (q31_t)0x8984EDCF, + (q31_t)0xCFBE389F, (q31_t)0x8971F15A, (q31_t)0xCFECCAC7, + (q31_t)0x895F072D, (q31_t)0xD01B6459, (q31_t)0x894C2F4C, + (q31_t)0xD04A054D, (q31_t)0x893969B9, (q31_t)0xD078AD9D, + (q31_t)0x8926B677, (q31_t)0xD0A75D42, (q31_t)0x89141589, + (q31_t)0xD0D61433, (q31_t)0x890186F1, (q31_t)0xD104D26B, + (q31_t)0x88EF0AB4, (q31_t)0xD13397E1, (q31_t)0x88DCA0D3, + (q31_t)0xD162648F, (q31_t)0x88CA4951, (q31_t)0xD191386D, + (q31_t)0x88B80431, (q31_t)0xD1C01374, (q31_t)0x88A5D177, + (q31_t)0xD1EEF59E, (q31_t)0x8893B124, (q31_t)0xD21DDEE1, + (q31_t)0x8881A33C, (q31_t)0xD24CCF38, (q31_t)0x886FA7C2, + (q31_t)0xD27BC69C, (q31_t)0x885DBEB7, (q31_t)0xD2AAC504, + (q31_t)0x884BE820, (q31_t)0xD2D9CA6A, (q31_t)0x883A23FE, + (q31_t)0xD308D6C6, (q31_t)0x88287255, (q31_t)0xD337EA12, + (q31_t)0x8816D327, (q31_t)0xD3670445, (q31_t)0x88054677, + (q31_t)0xD3962559, (q31_t)0x87F3CC47, (q31_t)0xD3C54D46, + (q31_t)0x87E2649B, (q31_t)0xD3F47C06, (q31_t)0x87D10F75, + (q31_t)0xD423B190, (q31_t)0x87BFCCD7, (q31_t)0xD452EDDE, + (q31_t)0x87AE9CC5, (q31_t)0xD48230E8, (q31_t)0x879D7F40, + (q31_t)0xD4B17AA7, (q31_t)0x878C744C, (q31_t)0xD4E0CB14, + (q31_t)0x877B7BEC, (q31_t)0xD5102227, (q31_t)0x876A9621, + (q31_t)0xD53F7FDA, (q31_t)0x8759C2EF, (q31_t)0xD56EE424, + (q31_t)0x87490257, (q31_t)0xD59E4EFE, (q31_t)0x8738545E, + (q31_t)0xD5CDC062, (q31_t)0x8727B904, (q31_t)0xD5FD3847, + (q31_t)0x8717304E, (q31_t)0xD62CB6A7, (q31_t)0x8706BA3C, + (q31_t)0xD65C3B7B, (q31_t)0x86F656D3, (q31_t)0xD68BC6BA, + (q31_t)0x86E60614, (q31_t)0xD6BB585D, (q31_t)0x86D5C802, + (q31_t)0xD6EAF05E, (q31_t)0x86C59C9F, (q31_t)0xD71A8EB5, + (q31_t)0x86B583EE, (q31_t)0xD74A335A, (q31_t)0x86A57DF1, + (q31_t)0xD779DE46, (q31_t)0x86958AAB, (q31_t)0xD7A98F73, + (q31_t)0x8685AA1F, (q31_t)0xD7D946D7, (q31_t)0x8675DC4E, + (q31_t)0xD809046D, (q31_t)0x8666213C, (q31_t)0xD838C82D, + (q31_t)0x865678EA, (q31_t)0xD868920F, (q31_t)0x8646E35B, + (q31_t)0xD898620C, (q31_t)0x86376092, (q31_t)0xD8C8381C, + (q31_t)0x8627F090, (q31_t)0xD8F81439, (q31_t)0x86189359, + (q31_t)0xD927F65B, (q31_t)0x860948EE, (q31_t)0xD957DE7A, + (q31_t)0x85FA1152, (q31_t)0xD987CC8F, (q31_t)0x85EAEC88, + (q31_t)0xD9B7C093, (q31_t)0x85DBDA91, (q31_t)0xD9E7BA7E, + (q31_t)0x85CCDB70, (q31_t)0xDA17BA4A, (q31_t)0x85BDEF27, + (q31_t)0xDA47BFED, (q31_t)0x85AF15B9, (q31_t)0xDA77CB62, + (q31_t)0x85A04F28, (q31_t)0xDAA7DCA1, (q31_t)0x85919B75, + (q31_t)0xDAD7F3A2, (q31_t)0x8582FAA4, (q31_t)0xDB08105E, + (q31_t)0x85746CB7, (q31_t)0xDB3832CD, (q31_t)0x8565F1B0, + (q31_t)0xDB685AE8, (q31_t)0x85578991, (q31_t)0xDB9888A8, + (q31_t)0x8549345C, (q31_t)0xDBC8BC05, (q31_t)0x853AF214, + (q31_t)0xDBF8F4F8, (q31_t)0x852CC2BA, (q31_t)0xDC293379, + (q31_t)0x851EA652, (q31_t)0xDC597781, (q31_t)0x85109CDC, + (q31_t)0xDC89C108, (q31_t)0x8502A65C, (q31_t)0xDCBA1008, + (q31_t)0x84F4C2D3, (q31_t)0xDCEA6478, (q31_t)0x84E6F244, + (q31_t)0xDD1ABE51, (q31_t)0x84D934B0, (q31_t)0xDD4B1D8B, + (q31_t)0x84CB8A1B, (q31_t)0xDD7B8220, (q31_t)0x84BDF285, + (q31_t)0xDDABEC07, (q31_t)0x84B06DF1, (q31_t)0xDDDC5B3A, + (q31_t)0x84A2FC62, (q31_t)0xDE0CCFB1, (q31_t)0x84959DD9, + (q31_t)0xDE3D4963, (q31_t)0x84885257, (q31_t)0xDE6DC84B, + (q31_t)0x847B19E1, (q31_t)0xDE9E4C60, (q31_t)0x846DF476, + (q31_t)0xDECED59B, (q31_t)0x8460E21A, (q31_t)0xDEFF63F4, + (q31_t)0x8453E2CE, (q31_t)0xDF2FF764, (q31_t)0x8446F695, + (q31_t)0xDF608FE3, (q31_t)0x843A1D70, (q31_t)0xDF912D6A, + (q31_t)0x842D5761, (q31_t)0xDFC1CFF2, (q31_t)0x8420A46B, + (q31_t)0xDFF27773, (q31_t)0x8414048F, (q31_t)0xE02323E5, + (q31_t)0x840777CF, (q31_t)0xE053D541, (q31_t)0x83FAFE2E, + (q31_t)0xE0848B7F, (q31_t)0x83EE97AC, (q31_t)0xE0B54698, + (q31_t)0x83E2444D, (q31_t)0xE0E60684, (q31_t)0x83D60411, + (q31_t)0xE116CB3D, (q31_t)0x83C9D6FB, (q31_t)0xE14794B9, + (q31_t)0x83BDBD0D, (q31_t)0xE17862F3, (q31_t)0x83B1B649, + (q31_t)0xE1A935E1, (q31_t)0x83A5C2B0, (q31_t)0xE1DA0D7E, + (q31_t)0x8399E244, (q31_t)0xE20AE9C1, (q31_t)0x838E1507, + (q31_t)0xE23BCAA2, (q31_t)0x83825AFB, (q31_t)0xE26CB01A, + (q31_t)0x8376B422, (q31_t)0xE29D9A22, (q31_t)0x836B207D, + (q31_t)0xE2CE88B2, (q31_t)0x835FA00E, (q31_t)0xE2FF7BC3, + (q31_t)0x835432D8, (q31_t)0xE330734C, (q31_t)0x8348D8DB, + (q31_t)0xE3616F47, (q31_t)0x833D921A, (q31_t)0xE3926FAC, + (q31_t)0x83325E97, (q31_t)0xE3C37473, (q31_t)0x83273E52, + (q31_t)0xE3F47D95, (q31_t)0x831C314E, (q31_t)0xE4258B0A, + (q31_t)0x8311378C, (q31_t)0xE4569CCB, (q31_t)0x8306510F, + (q31_t)0xE487B2CF, (q31_t)0x82FB7DD8, (q31_t)0xE4B8CD10, + (q31_t)0x82F0BDE8, (q31_t)0xE4E9EB86, (q31_t)0x82E61141, + (q31_t)0xE51B0E2A, (q31_t)0x82DB77E5, (q31_t)0xE54C34F3, + (q31_t)0x82D0F1D5, (q31_t)0xE57D5FDA, (q31_t)0x82C67F13, + (q31_t)0xE5AE8ED8, (q31_t)0x82BC1FA1, (q31_t)0xE5DFC1E4, + (q31_t)0x82B1D381, (q31_t)0xE610F8F9, (q31_t)0x82A79AB3, + (q31_t)0xE642340D, (q31_t)0x829D753A, (q31_t)0xE6737319, + (q31_t)0x82936316, (q31_t)0xE6A4B616, (q31_t)0x8289644A, + (q31_t)0xE6D5FCFC, (q31_t)0x827F78D8, (q31_t)0xE70747C3, + (q31_t)0x8275A0C0, (q31_t)0xE7389664, (q31_t)0x826BDC04, + (q31_t)0xE769E8D8, (q31_t)0x82622AA5, (q31_t)0xE79B3F16, + (q31_t)0x82588CA6, (q31_t)0xE7CC9917, (q31_t)0x824F0208, + (q31_t)0xE7FDF6D3, (q31_t)0x82458ACB, (q31_t)0xE82F5844, + (q31_t)0x823C26F2, (q31_t)0xE860BD60, (q31_t)0x8232D67E, + (q31_t)0xE8922621, (q31_t)0x82299971, (q31_t)0xE8C3927F, + (q31_t)0x82206FCB, (q31_t)0xE8F50273, (q31_t)0x8217598F, + (q31_t)0xE92675F4, (q31_t)0x820E56BE, (q31_t)0xE957ECFB, + (q31_t)0x82056758, (q31_t)0xE9896780, (q31_t)0x81FC8B60, + (q31_t)0xE9BAE57C, (q31_t)0x81F3C2D7, (q31_t)0xE9EC66E8, + (q31_t)0x81EB0DBD, (q31_t)0xEA1DEBBB, (q31_t)0x81E26C16, + (q31_t)0xEA4F73EE, (q31_t)0x81D9DDE1, (q31_t)0xEA80FF79, + (q31_t)0x81D16320, (q31_t)0xEAB28E55, (q31_t)0x81C8FBD5, + (q31_t)0xEAE4207A, (q31_t)0x81C0A801, (q31_t)0xEB15B5E0, + (q31_t)0x81B867A4, (q31_t)0xEB474E80, (q31_t)0x81B03AC1, + (q31_t)0xEB78EA52, (q31_t)0x81A82159, (q31_t)0xEBAA894E, + (q31_t)0x81A01B6C, (q31_t)0xEBDC2B6D, (q31_t)0x819828FD, + (q31_t)0xEC0DD0A8, (q31_t)0x81904A0C, (q31_t)0xEC3F78F5, + (q31_t)0x81887E9A, (q31_t)0xEC71244F, (q31_t)0x8180C6A9, + (q31_t)0xECA2D2AC, (q31_t)0x8179223A, (q31_t)0xECD48406, + (q31_t)0x8171914E, (q31_t)0xED063855, (q31_t)0x816A13E6, + (q31_t)0xED37EF91, (q31_t)0x8162AA03, (q31_t)0xED69A9B2, + (q31_t)0x815B53A8, (q31_t)0xED9B66B2, (q31_t)0x815410D3, + (q31_t)0xEDCD2687, (q31_t)0x814CE188, (q31_t)0xEDFEE92B, + (q31_t)0x8145C5C6, (q31_t)0xEE30AE95, (q31_t)0x813EBD90, + (q31_t)0xEE6276BF, (q31_t)0x8137C8E6, (q31_t)0xEE9441A0, + (q31_t)0x8130E7C8, (q31_t)0xEEC60F31, (q31_t)0x812A1A39, + (q31_t)0xEEF7DF6A, (q31_t)0x81236039, (q31_t)0xEF29B243, + (q31_t)0x811CB9CA, (q31_t)0xEF5B87B5, (q31_t)0x811626EC, + (q31_t)0xEF8D5FB8, (q31_t)0x810FA7A0, (q31_t)0xEFBF3A44, + (q31_t)0x81093BE8, (q31_t)0xEFF11752, (q31_t)0x8102E3C3, + (q31_t)0xF022F6DA, (q31_t)0x80FC9F35, (q31_t)0xF054D8D4, + (q31_t)0x80F66E3C, (q31_t)0xF086BD39, (q31_t)0x80F050DB, + (q31_t)0xF0B8A401, (q31_t)0x80EA4712, (q31_t)0xF0EA8D23, + (q31_t)0x80E450E2, (q31_t)0xF11C789A, (q31_t)0x80DE6E4C, + (q31_t)0xF14E665C, (q31_t)0x80D89F51, (q31_t)0xF1805662, + (q31_t)0x80D2E3F1, (q31_t)0xF1B248A5, (q31_t)0x80CD3C2F, + (q31_t)0xF1E43D1C, (q31_t)0x80C7A80A, (q31_t)0xF21633C0, + (q31_t)0x80C22783, (q31_t)0xF2482C89, (q31_t)0x80BCBA9C, + (q31_t)0xF27A2770, (q31_t)0x80B76155, (q31_t)0xF2AC246D, + (q31_t)0x80B21BAF, (q31_t)0xF2DE2378, (q31_t)0x80ACE9AB, + (q31_t)0xF310248A, (q31_t)0x80A7CB49, (q31_t)0xF342279A, + (q31_t)0x80A2C08B, (q31_t)0xF3742CA1, (q31_t)0x809DC970, + (q31_t)0xF3A63398, (q31_t)0x8098E5FB, (q31_t)0xF3D83C76, + (q31_t)0x8094162B, (q31_t)0xF40A4734, (q31_t)0x808F5A02, + (q31_t)0xF43C53CA, (q31_t)0x808AB180, (q31_t)0xF46E6231, + (q31_t)0x80861CA5, (q31_t)0xF4A07260, (q31_t)0x80819B74, + (q31_t)0xF4D28451, (q31_t)0x807D2DEB, (q31_t)0xF50497FA, + (q31_t)0x8078D40D, (q31_t)0xF536AD55, (q31_t)0x80748DD9, + (q31_t)0xF568C45A, (q31_t)0x80705B50, (q31_t)0xF59ADD01, + (q31_t)0x806C3C73, (q31_t)0xF5CCF743, (q31_t)0x80683143, + (q31_t)0xF5FF1317, (q31_t)0x806439C0, (q31_t)0xF6313076, + (q31_t)0x806055EA, (q31_t)0xF6634F58, (q31_t)0x805C85C3, + (q31_t)0xF6956FB6, (q31_t)0x8058C94C, (q31_t)0xF6C79188, + (q31_t)0x80552083, (q31_t)0xF6F9B4C5, (q31_t)0x80518B6B, + (q31_t)0xF72BD967, (q31_t)0x804E0A03, (q31_t)0xF75DFF65, + (q31_t)0x804A9C4D, (q31_t)0xF79026B8, (q31_t)0x80474248, + (q31_t)0xF7C24F58, (q31_t)0x8043FBF6, (q31_t)0xF7F4793E, + (q31_t)0x8040C956, (q31_t)0xF826A461, (q31_t)0x803DAA69, + (q31_t)0xF858D0BA, (q31_t)0x803A9F31, (q31_t)0xF88AFE41, + (q31_t)0x8037A7AC, (q31_t)0xF8BD2CEF, (q31_t)0x8034C3DC, + (q31_t)0xF8EF5CBB, (q31_t)0x8031F3C1, (q31_t)0xF9218D9E, + (q31_t)0x802F375C, (q31_t)0xF953BF90, (q31_t)0x802C8EAD, + (q31_t)0xF985F28A, (q31_t)0x8029F9B4, (q31_t)0xF9B82683, + (q31_t)0x80277872, (q31_t)0xF9EA5B75, (q31_t)0x80250AE7, + (q31_t)0xFA1C9156, (q31_t)0x8022B113, (q31_t)0xFA4EC820, + (q31_t)0x80206AF8, (q31_t)0xFA80FFCB, (q31_t)0x801E3894, + (q31_t)0xFAB3384F, (q31_t)0x801C19E9, (q31_t)0xFAE571A4, + (q31_t)0x801A0EF7, (q31_t)0xFB17ABC2, (q31_t)0x801817BF, + (q31_t)0xFB49E6A2, (q31_t)0x80163440, (q31_t)0xFB7C223C, + (q31_t)0x8014647A, (q31_t)0xFBAE5E89, (q31_t)0x8012A86F, + (q31_t)0xFBE09B80, (q31_t)0x8011001E, (q31_t)0xFC12D919, + (q31_t)0x800F6B88, (q31_t)0xFC45174E, (q31_t)0x800DEAAC, + (q31_t)0xFC775616, (q31_t)0x800C7D8C, (q31_t)0xFCA99569, + (q31_t)0x800B2427, (q31_t)0xFCDBD541, (q31_t)0x8009DE7D, + (q31_t)0xFD0E1594, (q31_t)0x8008AC90, (q31_t)0xFD40565B, + (q31_t)0x80078E5E, (q31_t)0xFD72978F, (q31_t)0x800683E8, + (q31_t)0xFDA4D928, (q31_t)0x80058D2E, (q31_t)0xFDD71B1E, + (q31_t)0x8004AA31, (q31_t)0xFE095D69, (q31_t)0x8003DAF0, + (q31_t)0xFE3BA001, (q31_t)0x80031F6C, (q31_t)0xFE6DE2E0, + (q31_t)0x800277A5, (q31_t)0xFEA025FC, (q31_t)0x8001E39B, + (q31_t)0xFED2694F, (q31_t)0x8001634D, (q31_t)0xFF04ACD0, + (q31_t)0x8000F6BD, (q31_t)0xFF36F078, (q31_t)0x80009DE9, + (q31_t)0xFF69343E, (q31_t)0x800058D3, (q31_t)0xFF9B781D, + (q31_t)0x8000277A, (q31_t)0xFFCDBC0A, (q31_t)0x800009DE +}; + + + +/** + @brief q15 Twiddle factors Table +*/ + + +/** + @par + Example code for q15 Twiddle factors Generation:: + @par +
fori = 0; i< 3N/4; i++)
+  {
+     twiddleCoefq15[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefq15[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 16, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to q15(Fixed point 1.15): + round(twiddleCoefq15(i) * pow(2, 15)) + */ +const q15_t twiddleCoef_16_q15[24] = { + (q15_t)0x7FFF, (q15_t)0x0000, + (q15_t)0x7641, (q15_t)0x30FB, + (q15_t)0x5A82, (q15_t)0x5A82, + (q15_t)0x30FB, (q15_t)0x7641, + (q15_t)0x0000, (q15_t)0x7FFF, + (q15_t)0xCF04, (q15_t)0x7641, + (q15_t)0xA57D, (q15_t)0x5A82, + (q15_t)0x89BE, (q15_t)0x30FB, + (q15_t)0x8000, (q15_t)0x0000, + (q15_t)0x89BE, (q15_t)0xCF04, + (q15_t)0xA57D, (q15_t)0xA57D, + (q15_t)0xCF04, (q15_t)0x89BE +}; + +/** + @par + Example code for q15 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefq15[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefq15[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 32, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to q15(Fixed point 1.15): + round(twiddleCoefq15(i) * pow(2, 15)) + */ +const q15_t twiddleCoef_32_q15[48] = { + (q15_t)0x7FFF, (q15_t)0x0000, + (q15_t)0x7D8A, (q15_t)0x18F8, + (q15_t)0x7641, (q15_t)0x30FB, + (q15_t)0x6A6D, (q15_t)0x471C, + (q15_t)0x5A82, (q15_t)0x5A82, + (q15_t)0x471C, (q15_t)0x6A6D, + (q15_t)0x30FB, (q15_t)0x7641, + (q15_t)0x18F8, (q15_t)0x7D8A, + (q15_t)0x0000, (q15_t)0x7FFF, + (q15_t)0xE707, (q15_t)0x7D8A, + (q15_t)0xCF04, (q15_t)0x7641, + (q15_t)0xB8E3, (q15_t)0x6A6D, + (q15_t)0xA57D, (q15_t)0x5A82, + (q15_t)0x9592, (q15_t)0x471C, + (q15_t)0x89BE, (q15_t)0x30FB, + (q15_t)0x8275, (q15_t)0x18F8, + (q15_t)0x8000, (q15_t)0x0000, + (q15_t)0x8275, (q15_t)0xE707, + (q15_t)0x89BE, (q15_t)0xCF04, + (q15_t)0x9592, (q15_t)0xB8E3, + (q15_t)0xA57D, (q15_t)0xA57D, + (q15_t)0xB8E3, (q15_t)0x9592, + (q15_t)0xCF04, (q15_t)0x89BE, + (q15_t)0xE707, (q15_t)0x8275 +}; + +/** + @par + Example code for q15 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefq15[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefq15[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 64, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to q15(Fixed point 1.15): + round(twiddleCoefq15(i) * pow(2, 15)) + */ +const q15_t twiddleCoef_64_q15[96] = { + (q15_t)0x7FFF, (q15_t)0x0000, (q15_t)0x7F62, (q15_t)0x0C8B, + (q15_t)0x7D8A, (q15_t)0x18F8, (q15_t)0x7A7D, (q15_t)0x2528, + (q15_t)0x7641, (q15_t)0x30FB, (q15_t)0x70E2, (q15_t)0x3C56, + (q15_t)0x6A6D, (q15_t)0x471C, (q15_t)0x62F2, (q15_t)0x5133, + (q15_t)0x5A82, (q15_t)0x5A82, (q15_t)0x5133, (q15_t)0x62F2, + (q15_t)0x471C, (q15_t)0x6A6D, (q15_t)0x3C56, (q15_t)0x70E2, + (q15_t)0x30FB, (q15_t)0x7641, (q15_t)0x2528, (q15_t)0x7A7D, + (q15_t)0x18F8, (q15_t)0x7D8A, (q15_t)0x0C8B, (q15_t)0x7F62, + (q15_t)0x0000, (q15_t)0x7FFF, (q15_t)0xF374, (q15_t)0x7F62, + (q15_t)0xE707, (q15_t)0x7D8A, (q15_t)0xDAD7, (q15_t)0x7A7D, + (q15_t)0xCF04, (q15_t)0x7641, (q15_t)0xC3A9, (q15_t)0x70E2, + (q15_t)0xB8E3, (q15_t)0x6A6D, (q15_t)0xAECC, (q15_t)0x62F2, + (q15_t)0xA57D, (q15_t)0x5A82, (q15_t)0x9D0D, (q15_t)0x5133, + (q15_t)0x9592, (q15_t)0x471C, (q15_t)0x8F1D, (q15_t)0x3C56, + (q15_t)0x89BE, (q15_t)0x30FB, (q15_t)0x8582, (q15_t)0x2528, + (q15_t)0x8275, (q15_t)0x18F8, (q15_t)0x809D, (q15_t)0x0C8B, + (q15_t)0x8000, (q15_t)0x0000, (q15_t)0x809D, (q15_t)0xF374, + (q15_t)0x8275, (q15_t)0xE707, (q15_t)0x8582, (q15_t)0xDAD7, + (q15_t)0x89BE, (q15_t)0xCF04, (q15_t)0x8F1D, (q15_t)0xC3A9, + (q15_t)0x9592, (q15_t)0xB8E3, (q15_t)0x9D0D, (q15_t)0xAECC, + (q15_t)0xA57D, (q15_t)0xA57D, (q15_t)0xAECC, (q15_t)0x9D0D, + (q15_t)0xB8E3, (q15_t)0x9592, (q15_t)0xC3A9, (q15_t)0x8F1D, + (q15_t)0xCF04, (q15_t)0x89BE, (q15_t)0xDAD7, (q15_t)0x8582, + (q15_t)0xE707, (q15_t)0x8275, (q15_t)0xF374, (q15_t)0x809D +}; + +/** + @par + Example code for q15 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefq15[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefq15[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 128, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to q15(Fixed point 1.15): + round(twiddleCoefq15(i) * pow(2, 15)) + */ +const q15_t twiddleCoef_128_q15[192] = { + (q15_t)0x7FFF, (q15_t)0x0000, (q15_t)0x7FD8, (q15_t)0x0647, + (q15_t)0x7F62, (q15_t)0x0C8B, (q15_t)0x7E9D, (q15_t)0x12C8, + (q15_t)0x7D8A, (q15_t)0x18F8, (q15_t)0x7C29, (q15_t)0x1F19, + (q15_t)0x7A7D, (q15_t)0x2528, (q15_t)0x7884, (q15_t)0x2B1F, + (q15_t)0x7641, (q15_t)0x30FB, (q15_t)0x73B5, (q15_t)0x36BA, + (q15_t)0x70E2, (q15_t)0x3C56, (q15_t)0x6DCA, (q15_t)0x41CE, + (q15_t)0x6A6D, (q15_t)0x471C, (q15_t)0x66CF, (q15_t)0x4C3F, + (q15_t)0x62F2, (q15_t)0x5133, (q15_t)0x5ED7, (q15_t)0x55F5, + (q15_t)0x5A82, (q15_t)0x5A82, (q15_t)0x55F5, (q15_t)0x5ED7, + (q15_t)0x5133, (q15_t)0x62F2, (q15_t)0x4C3F, (q15_t)0x66CF, + (q15_t)0x471C, (q15_t)0x6A6D, (q15_t)0x41CE, (q15_t)0x6DCA, + (q15_t)0x3C56, (q15_t)0x70E2, (q15_t)0x36BA, (q15_t)0x73B5, + (q15_t)0x30FB, (q15_t)0x7641, (q15_t)0x2B1F, (q15_t)0x7884, + (q15_t)0x2528, (q15_t)0x7A7D, (q15_t)0x1F19, (q15_t)0x7C29, + (q15_t)0x18F8, (q15_t)0x7D8A, (q15_t)0x12C8, (q15_t)0x7E9D, + (q15_t)0x0C8B, (q15_t)0x7F62, (q15_t)0x0647, (q15_t)0x7FD8, + (q15_t)0x0000, (q15_t)0x7FFF, (q15_t)0xF9B8, (q15_t)0x7FD8, + (q15_t)0xF374, (q15_t)0x7F62, (q15_t)0xED37, (q15_t)0x7E9D, + (q15_t)0xE707, (q15_t)0x7D8A, (q15_t)0xE0E6, (q15_t)0x7C29, + (q15_t)0xDAD7, (q15_t)0x7A7D, (q15_t)0xD4E0, (q15_t)0x7884, + (q15_t)0xCF04, (q15_t)0x7641, (q15_t)0xC945, (q15_t)0x73B5, + (q15_t)0xC3A9, (q15_t)0x70E2, (q15_t)0xBE31, (q15_t)0x6DCA, + (q15_t)0xB8E3, (q15_t)0x6A6D, (q15_t)0xB3C0, (q15_t)0x66CF, + (q15_t)0xAECC, (q15_t)0x62F2, (q15_t)0xAA0A, (q15_t)0x5ED7, + (q15_t)0xA57D, (q15_t)0x5A82, (q15_t)0xA128, (q15_t)0x55F5, + (q15_t)0x9D0D, (q15_t)0x5133, (q15_t)0x9930, (q15_t)0x4C3F, + (q15_t)0x9592, (q15_t)0x471C, (q15_t)0x9235, (q15_t)0x41CE, + (q15_t)0x8F1D, (q15_t)0x3C56, (q15_t)0x8C4A, (q15_t)0x36BA, + (q15_t)0x89BE, (q15_t)0x30FB, (q15_t)0x877B, (q15_t)0x2B1F, + (q15_t)0x8582, (q15_t)0x2528, (q15_t)0x83D6, (q15_t)0x1F19, + (q15_t)0x8275, (q15_t)0x18F8, (q15_t)0x8162, (q15_t)0x12C8, + (q15_t)0x809D, (q15_t)0x0C8B, (q15_t)0x8027, (q15_t)0x0647, + (q15_t)0x8000, (q15_t)0x0000, (q15_t)0x8027, (q15_t)0xF9B8, + (q15_t)0x809D, (q15_t)0xF374, (q15_t)0x8162, (q15_t)0xED37, + (q15_t)0x8275, (q15_t)0xE707, (q15_t)0x83D6, (q15_t)0xE0E6, + (q15_t)0x8582, (q15_t)0xDAD7, (q15_t)0x877B, (q15_t)0xD4E0, + (q15_t)0x89BE, (q15_t)0xCF04, (q15_t)0x8C4A, (q15_t)0xC945, + (q15_t)0x8F1D, (q15_t)0xC3A9, (q15_t)0x9235, (q15_t)0xBE31, + (q15_t)0x9592, (q15_t)0xB8E3, (q15_t)0x9930, (q15_t)0xB3C0, + (q15_t)0x9D0D, (q15_t)0xAECC, (q15_t)0xA128, (q15_t)0xAA0A, + (q15_t)0xA57D, (q15_t)0xA57D, (q15_t)0xAA0A, (q15_t)0xA128, + (q15_t)0xAECC, (q15_t)0x9D0D, (q15_t)0xB3C0, (q15_t)0x9930, + (q15_t)0xB8E3, (q15_t)0x9592, (q15_t)0xBE31, (q15_t)0x9235, + (q15_t)0xC3A9, (q15_t)0x8F1D, (q15_t)0xC945, (q15_t)0x8C4A, + (q15_t)0xCF04, (q15_t)0x89BE, (q15_t)0xD4E0, (q15_t)0x877B, + (q15_t)0xDAD7, (q15_t)0x8582, (q15_t)0xE0E6, (q15_t)0x83D6, + (q15_t)0xE707, (q15_t)0x8275, (q15_t)0xED37, (q15_t)0x8162, + (q15_t)0xF374, (q15_t)0x809D, (q15_t)0xF9B8, (q15_t)0x8027 +}; + +/** + @par + Example code for q15 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefq15[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefq15[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 256, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to q15(Fixed point 1.15): + round(twiddleCoefq15(i) * pow(2, 15)) + */ +const q15_t twiddleCoef_256_q15[384] = { + (q15_t)0x7FFF, (q15_t)0x0000, (q15_t)0x7FF6, (q15_t)0x0324, + (q15_t)0x7FD8, (q15_t)0x0647, (q15_t)0x7FA7, (q15_t)0x096A, + (q15_t)0x7F62, (q15_t)0x0C8B, (q15_t)0x7F09, (q15_t)0x0FAB, + (q15_t)0x7E9D, (q15_t)0x12C8, (q15_t)0x7E1D, (q15_t)0x15E2, + (q15_t)0x7D8A, (q15_t)0x18F8, (q15_t)0x7CE3, (q15_t)0x1C0B, + (q15_t)0x7C29, (q15_t)0x1F19, (q15_t)0x7B5D, (q15_t)0x2223, + (q15_t)0x7A7D, (q15_t)0x2528, (q15_t)0x798A, (q15_t)0x2826, + (q15_t)0x7884, (q15_t)0x2B1F, (q15_t)0x776C, (q15_t)0x2E11, + (q15_t)0x7641, (q15_t)0x30FB, (q15_t)0x7504, (q15_t)0x33DE, + (q15_t)0x73B5, (q15_t)0x36BA, (q15_t)0x7255, (q15_t)0x398C, + (q15_t)0x70E2, (q15_t)0x3C56, (q15_t)0x6F5F, (q15_t)0x3F17, + (q15_t)0x6DCA, (q15_t)0x41CE, (q15_t)0x6C24, (q15_t)0x447A, + (q15_t)0x6A6D, (q15_t)0x471C, (q15_t)0x68A6, (q15_t)0x49B4, + (q15_t)0x66CF, (q15_t)0x4C3F, (q15_t)0x64E8, (q15_t)0x4EBF, + (q15_t)0x62F2, (q15_t)0x5133, (q15_t)0x60EC, (q15_t)0x539B, + (q15_t)0x5ED7, (q15_t)0x55F5, (q15_t)0x5CB4, (q15_t)0x5842, + (q15_t)0x5A82, (q15_t)0x5A82, (q15_t)0x5842, (q15_t)0x5CB4, + (q15_t)0x55F5, (q15_t)0x5ED7, (q15_t)0x539B, (q15_t)0x60EC, + (q15_t)0x5133, (q15_t)0x62F2, (q15_t)0x4EBF, (q15_t)0x64E8, + (q15_t)0x4C3F, (q15_t)0x66CF, (q15_t)0x49B4, (q15_t)0x68A6, + (q15_t)0x471C, (q15_t)0x6A6D, (q15_t)0x447A, (q15_t)0x6C24, + (q15_t)0x41CE, (q15_t)0x6DCA, (q15_t)0x3F17, (q15_t)0x6F5F, + (q15_t)0x3C56, (q15_t)0x70E2, (q15_t)0x398C, (q15_t)0x7255, + (q15_t)0x36BA, (q15_t)0x73B5, (q15_t)0x33DE, (q15_t)0x7504, + (q15_t)0x30FB, (q15_t)0x7641, (q15_t)0x2E11, (q15_t)0x776C, + (q15_t)0x2B1F, (q15_t)0x7884, (q15_t)0x2826, (q15_t)0x798A, + (q15_t)0x2528, (q15_t)0x7A7D, (q15_t)0x2223, (q15_t)0x7B5D, + (q15_t)0x1F19, (q15_t)0x7C29, (q15_t)0x1C0B, (q15_t)0x7CE3, + (q15_t)0x18F8, (q15_t)0x7D8A, (q15_t)0x15E2, (q15_t)0x7E1D, + (q15_t)0x12C8, (q15_t)0x7E9D, (q15_t)0x0FAB, (q15_t)0x7F09, + (q15_t)0x0C8B, (q15_t)0x7F62, (q15_t)0x096A, (q15_t)0x7FA7, + (q15_t)0x0647, (q15_t)0x7FD8, (q15_t)0x0324, (q15_t)0x7FF6, + (q15_t)0x0000, (q15_t)0x7FFF, (q15_t)0xFCDB, (q15_t)0x7FF6, + (q15_t)0xF9B8, (q15_t)0x7FD8, (q15_t)0xF695, (q15_t)0x7FA7, + (q15_t)0xF374, (q15_t)0x7F62, (q15_t)0xF054, (q15_t)0x7F09, + (q15_t)0xED37, (q15_t)0x7E9D, (q15_t)0xEA1D, (q15_t)0x7E1D, + (q15_t)0xE707, (q15_t)0x7D8A, (q15_t)0xE3F4, (q15_t)0x7CE3, + (q15_t)0xE0E6, (q15_t)0x7C29, (q15_t)0xDDDC, (q15_t)0x7B5D, + (q15_t)0xDAD7, (q15_t)0x7A7D, (q15_t)0xD7D9, (q15_t)0x798A, + (q15_t)0xD4E0, (q15_t)0x7884, (q15_t)0xD1EE, (q15_t)0x776C, + (q15_t)0xCF04, (q15_t)0x7641, (q15_t)0xCC21, (q15_t)0x7504, + (q15_t)0xC945, (q15_t)0x73B5, (q15_t)0xC673, (q15_t)0x7255, + (q15_t)0xC3A9, (q15_t)0x70E2, (q15_t)0xC0E8, (q15_t)0x6F5F, + (q15_t)0xBE31, (q15_t)0x6DCA, (q15_t)0xBB85, (q15_t)0x6C24, + (q15_t)0xB8E3, (q15_t)0x6A6D, (q15_t)0xB64B, (q15_t)0x68A6, + (q15_t)0xB3C0, (q15_t)0x66CF, (q15_t)0xB140, (q15_t)0x64E8, + (q15_t)0xAECC, (q15_t)0x62F2, (q15_t)0xAC64, (q15_t)0x60EC, + (q15_t)0xAA0A, (q15_t)0x5ED7, (q15_t)0xA7BD, (q15_t)0x5CB4, + (q15_t)0xA57D, (q15_t)0x5A82, (q15_t)0xA34B, (q15_t)0x5842, + (q15_t)0xA128, (q15_t)0x55F5, (q15_t)0x9F13, (q15_t)0x539B, + (q15_t)0x9D0D, (q15_t)0x5133, (q15_t)0x9B17, (q15_t)0x4EBF, + (q15_t)0x9930, (q15_t)0x4C3F, (q15_t)0x9759, (q15_t)0x49B4, + (q15_t)0x9592, (q15_t)0x471C, (q15_t)0x93DB, (q15_t)0x447A, + (q15_t)0x9235, (q15_t)0x41CE, (q15_t)0x90A0, (q15_t)0x3F17, + (q15_t)0x8F1D, (q15_t)0x3C56, (q15_t)0x8DAA, (q15_t)0x398C, + (q15_t)0x8C4A, (q15_t)0x36BA, (q15_t)0x8AFB, (q15_t)0x33DE, + (q15_t)0x89BE, (q15_t)0x30FB, (q15_t)0x8893, (q15_t)0x2E11, + (q15_t)0x877B, (q15_t)0x2B1F, (q15_t)0x8675, (q15_t)0x2826, + (q15_t)0x8582, (q15_t)0x2528, (q15_t)0x84A2, (q15_t)0x2223, + (q15_t)0x83D6, (q15_t)0x1F19, (q15_t)0x831C, (q15_t)0x1C0B, + (q15_t)0x8275, (q15_t)0x18F8, (q15_t)0x81E2, (q15_t)0x15E2, + (q15_t)0x8162, (q15_t)0x12C8, (q15_t)0x80F6, (q15_t)0x0FAB, + (q15_t)0x809D, (q15_t)0x0C8B, (q15_t)0x8058, (q15_t)0x096A, + (q15_t)0x8027, (q15_t)0x0647, (q15_t)0x8009, (q15_t)0x0324, + (q15_t)0x8000, (q15_t)0x0000, (q15_t)0x8009, (q15_t)0xFCDB, + (q15_t)0x8027, (q15_t)0xF9B8, (q15_t)0x8058, (q15_t)0xF695, + (q15_t)0x809D, (q15_t)0xF374, (q15_t)0x80F6, (q15_t)0xF054, + (q15_t)0x8162, (q15_t)0xED37, (q15_t)0x81E2, (q15_t)0xEA1D, + (q15_t)0x8275, (q15_t)0xE707, (q15_t)0x831C, (q15_t)0xE3F4, + (q15_t)0x83D6, (q15_t)0xE0E6, (q15_t)0x84A2, (q15_t)0xDDDC, + (q15_t)0x8582, (q15_t)0xDAD7, (q15_t)0x8675, (q15_t)0xD7D9, + (q15_t)0x877B, (q15_t)0xD4E0, (q15_t)0x8893, (q15_t)0xD1EE, + (q15_t)0x89BE, (q15_t)0xCF04, (q15_t)0x8AFB, (q15_t)0xCC21, + (q15_t)0x8C4A, (q15_t)0xC945, (q15_t)0x8DAA, (q15_t)0xC673, + (q15_t)0x8F1D, (q15_t)0xC3A9, (q15_t)0x90A0, (q15_t)0xC0E8, + (q15_t)0x9235, (q15_t)0xBE31, (q15_t)0x93DB, (q15_t)0xBB85, + (q15_t)0x9592, (q15_t)0xB8E3, (q15_t)0x9759, (q15_t)0xB64B, + (q15_t)0x9930, (q15_t)0xB3C0, (q15_t)0x9B17, (q15_t)0xB140, + (q15_t)0x9D0D, (q15_t)0xAECC, (q15_t)0x9F13, (q15_t)0xAC64, + (q15_t)0xA128, (q15_t)0xAA0A, (q15_t)0xA34B, (q15_t)0xA7BD, + (q15_t)0xA57D, (q15_t)0xA57D, (q15_t)0xA7BD, (q15_t)0xA34B, + (q15_t)0xAA0A, (q15_t)0xA128, (q15_t)0xAC64, (q15_t)0x9F13, + (q15_t)0xAECC, (q15_t)0x9D0D, (q15_t)0xB140, (q15_t)0x9B17, + (q15_t)0xB3C0, (q15_t)0x9930, (q15_t)0xB64B, (q15_t)0x9759, + (q15_t)0xB8E3, (q15_t)0x9592, (q15_t)0xBB85, (q15_t)0x93DB, + (q15_t)0xBE31, (q15_t)0x9235, (q15_t)0xC0E8, (q15_t)0x90A0, + (q15_t)0xC3A9, (q15_t)0x8F1D, (q15_t)0xC673, (q15_t)0x8DAA, + (q15_t)0xC945, (q15_t)0x8C4A, (q15_t)0xCC21, (q15_t)0x8AFB, + (q15_t)0xCF04, (q15_t)0x89BE, (q15_t)0xD1EE, (q15_t)0x8893, + (q15_t)0xD4E0, (q15_t)0x877B, (q15_t)0xD7D9, (q15_t)0x8675, + (q15_t)0xDAD7, (q15_t)0x8582, (q15_t)0xDDDC, (q15_t)0x84A2, + (q15_t)0xE0E6, (q15_t)0x83D6, (q15_t)0xE3F4, (q15_t)0x831C, + (q15_t)0xE707, (q15_t)0x8275, (q15_t)0xEA1D, (q15_t)0x81E2, + (q15_t)0xED37, (q15_t)0x8162, (q15_t)0xF054, (q15_t)0x80F6, + (q15_t)0xF374, (q15_t)0x809D, (q15_t)0xF695, (q15_t)0x8058, + (q15_t)0xF9B8, (q15_t)0x8027, (q15_t)0xFCDB, (q15_t)0x8009 +}; + +/** + @par + Example code for q15 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefq15[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefq15[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 512, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to q15(Fixed point 1.15): + round(twiddleCoefq15(i) * pow(2, 15)) + */ +const q15_t twiddleCoef_512_q15[768] = { + (q15_t)0x7FFF, (q15_t)0x0000, (q15_t)0x7FFD, (q15_t)0x0192, + (q15_t)0x7FF6, (q15_t)0x0324, (q15_t)0x7FE9, (q15_t)0x04B6, + (q15_t)0x7FD8, (q15_t)0x0647, (q15_t)0x7FC2, (q15_t)0x07D9, + (q15_t)0x7FA7, (q15_t)0x096A, (q15_t)0x7F87, (q15_t)0x0AFB, + (q15_t)0x7F62, (q15_t)0x0C8B, (q15_t)0x7F38, (q15_t)0x0E1B, + (q15_t)0x7F09, (q15_t)0x0FAB, (q15_t)0x7ED5, (q15_t)0x1139, + (q15_t)0x7E9D, (q15_t)0x12C8, (q15_t)0x7E5F, (q15_t)0x1455, + (q15_t)0x7E1D, (q15_t)0x15E2, (q15_t)0x7DD6, (q15_t)0x176D, + (q15_t)0x7D8A, (q15_t)0x18F8, (q15_t)0x7D39, (q15_t)0x1A82, + (q15_t)0x7CE3, (q15_t)0x1C0B, (q15_t)0x7C89, (q15_t)0x1D93, + (q15_t)0x7C29, (q15_t)0x1F19, (q15_t)0x7BC5, (q15_t)0x209F, + (q15_t)0x7B5D, (q15_t)0x2223, (q15_t)0x7AEF, (q15_t)0x23A6, + (q15_t)0x7A7D, (q15_t)0x2528, (q15_t)0x7A05, (q15_t)0x26A8, + (q15_t)0x798A, (q15_t)0x2826, (q15_t)0x7909, (q15_t)0x29A3, + (q15_t)0x7884, (q15_t)0x2B1F, (q15_t)0x77FA, (q15_t)0x2C98, + (q15_t)0x776C, (q15_t)0x2E11, (q15_t)0x76D9, (q15_t)0x2F87, + (q15_t)0x7641, (q15_t)0x30FB, (q15_t)0x75A5, (q15_t)0x326E, + (q15_t)0x7504, (q15_t)0x33DE, (q15_t)0x745F, (q15_t)0x354D, + (q15_t)0x73B5, (q15_t)0x36BA, (q15_t)0x7307, (q15_t)0x3824, + (q15_t)0x7255, (q15_t)0x398C, (q15_t)0x719E, (q15_t)0x3AF2, + (q15_t)0x70E2, (q15_t)0x3C56, (q15_t)0x7023, (q15_t)0x3DB8, + (q15_t)0x6F5F, (q15_t)0x3F17, (q15_t)0x6E96, (q15_t)0x4073, + (q15_t)0x6DCA, (q15_t)0x41CE, (q15_t)0x6CF9, (q15_t)0x4325, + (q15_t)0x6C24, (q15_t)0x447A, (q15_t)0x6B4A, (q15_t)0x45CD, + (q15_t)0x6A6D, (q15_t)0x471C, (q15_t)0x698C, (q15_t)0x4869, + (q15_t)0x68A6, (q15_t)0x49B4, (q15_t)0x67BD, (q15_t)0x4AFB, + (q15_t)0x66CF, (q15_t)0x4C3F, (q15_t)0x65DD, (q15_t)0x4D81, + (q15_t)0x64E8, (q15_t)0x4EBF, (q15_t)0x63EF, (q15_t)0x4FFB, + (q15_t)0x62F2, (q15_t)0x5133, (q15_t)0x61F1, (q15_t)0x5269, + (q15_t)0x60EC, (q15_t)0x539B, (q15_t)0x5FE3, (q15_t)0x54CA, + (q15_t)0x5ED7, (q15_t)0x55F5, (q15_t)0x5DC7, (q15_t)0x571D, + (q15_t)0x5CB4, (q15_t)0x5842, (q15_t)0x5B9D, (q15_t)0x5964, + (q15_t)0x5A82, (q15_t)0x5A82, (q15_t)0x5964, (q15_t)0x5B9D, + (q15_t)0x5842, (q15_t)0x5CB4, (q15_t)0x571D, (q15_t)0x5DC7, + (q15_t)0x55F5, (q15_t)0x5ED7, (q15_t)0x54CA, (q15_t)0x5FE3, + (q15_t)0x539B, (q15_t)0x60EC, (q15_t)0x5269, (q15_t)0x61F1, + (q15_t)0x5133, (q15_t)0x62F2, (q15_t)0x4FFB, (q15_t)0x63EF, + (q15_t)0x4EBF, (q15_t)0x64E8, (q15_t)0x4D81, (q15_t)0x65DD, + (q15_t)0x4C3F, (q15_t)0x66CF, (q15_t)0x4AFB, (q15_t)0x67BD, + (q15_t)0x49B4, (q15_t)0x68A6, (q15_t)0x4869, (q15_t)0x698C, + (q15_t)0x471C, (q15_t)0x6A6D, (q15_t)0x45CD, (q15_t)0x6B4A, + (q15_t)0x447A, (q15_t)0x6C24, (q15_t)0x4325, (q15_t)0x6CF9, + (q15_t)0x41CE, (q15_t)0x6DCA, (q15_t)0x4073, (q15_t)0x6E96, + (q15_t)0x3F17, (q15_t)0x6F5F, (q15_t)0x3DB8, (q15_t)0x7023, + (q15_t)0x3C56, (q15_t)0x70E2, (q15_t)0x3AF2, (q15_t)0x719E, + (q15_t)0x398C, (q15_t)0x7255, (q15_t)0x3824, (q15_t)0x7307, + (q15_t)0x36BA, (q15_t)0x73B5, (q15_t)0x354D, (q15_t)0x745F, + (q15_t)0x33DE, (q15_t)0x7504, (q15_t)0x326E, (q15_t)0x75A5, + (q15_t)0x30FB, (q15_t)0x7641, (q15_t)0x2F87, (q15_t)0x76D9, + (q15_t)0x2E11, (q15_t)0x776C, (q15_t)0x2C98, (q15_t)0x77FA, + (q15_t)0x2B1F, (q15_t)0x7884, (q15_t)0x29A3, (q15_t)0x7909, + (q15_t)0x2826, (q15_t)0x798A, (q15_t)0x26A8, (q15_t)0x7A05, + (q15_t)0x2528, (q15_t)0x7A7D, (q15_t)0x23A6, (q15_t)0x7AEF, + (q15_t)0x2223, (q15_t)0x7B5D, (q15_t)0x209F, (q15_t)0x7BC5, + (q15_t)0x1F19, (q15_t)0x7C29, (q15_t)0x1D93, (q15_t)0x7C89, + (q15_t)0x1C0B, (q15_t)0x7CE3, (q15_t)0x1A82, (q15_t)0x7D39, + (q15_t)0x18F8, (q15_t)0x7D8A, (q15_t)0x176D, (q15_t)0x7DD6, + (q15_t)0x15E2, (q15_t)0x7E1D, (q15_t)0x1455, (q15_t)0x7E5F, + (q15_t)0x12C8, (q15_t)0x7E9D, (q15_t)0x1139, (q15_t)0x7ED5, + (q15_t)0x0FAB, (q15_t)0x7F09, (q15_t)0x0E1B, (q15_t)0x7F38, + (q15_t)0x0C8B, (q15_t)0x7F62, (q15_t)0x0AFB, (q15_t)0x7F87, + (q15_t)0x096A, (q15_t)0x7FA7, (q15_t)0x07D9, (q15_t)0x7FC2, + (q15_t)0x0647, (q15_t)0x7FD8, (q15_t)0x04B6, (q15_t)0x7FE9, + (q15_t)0x0324, (q15_t)0x7FF6, (q15_t)0x0192, (q15_t)0x7FFD, + (q15_t)0x0000, (q15_t)0x7FFF, (q15_t)0xFE6D, (q15_t)0x7FFD, + (q15_t)0xFCDB, (q15_t)0x7FF6, (q15_t)0xFB49, (q15_t)0x7FE9, + (q15_t)0xF9B8, (q15_t)0x7FD8, (q15_t)0xF826, (q15_t)0x7FC2, + (q15_t)0xF695, (q15_t)0x7FA7, (q15_t)0xF504, (q15_t)0x7F87, + (q15_t)0xF374, (q15_t)0x7F62, (q15_t)0xF1E4, (q15_t)0x7F38, + (q15_t)0xF054, (q15_t)0x7F09, (q15_t)0xEEC6, (q15_t)0x7ED5, + (q15_t)0xED37, (q15_t)0x7E9D, (q15_t)0xEBAA, (q15_t)0x7E5F, + (q15_t)0xEA1D, (q15_t)0x7E1D, (q15_t)0xE892, (q15_t)0x7DD6, + (q15_t)0xE707, (q15_t)0x7D8A, (q15_t)0xE57D, (q15_t)0x7D39, + (q15_t)0xE3F4, (q15_t)0x7CE3, (q15_t)0xE26C, (q15_t)0x7C89, + (q15_t)0xE0E6, (q15_t)0x7C29, (q15_t)0xDF60, (q15_t)0x7BC5, + (q15_t)0xDDDC, (q15_t)0x7B5D, (q15_t)0xDC59, (q15_t)0x7AEF, + (q15_t)0xDAD7, (q15_t)0x7A7D, (q15_t)0xD957, (q15_t)0x7A05, + (q15_t)0xD7D9, (q15_t)0x798A, (q15_t)0xD65C, (q15_t)0x7909, + (q15_t)0xD4E0, (q15_t)0x7884, (q15_t)0xD367, (q15_t)0x77FA, + (q15_t)0xD1EE, (q15_t)0x776C, (q15_t)0xD078, (q15_t)0x76D9, + (q15_t)0xCF04, (q15_t)0x7641, (q15_t)0xCD91, (q15_t)0x75A5, + (q15_t)0xCC21, (q15_t)0x7504, (q15_t)0xCAB2, (q15_t)0x745F, + (q15_t)0xC945, (q15_t)0x73B5, (q15_t)0xC7DB, (q15_t)0x7307, + (q15_t)0xC673, (q15_t)0x7255, (q15_t)0xC50D, (q15_t)0x719E, + (q15_t)0xC3A9, (q15_t)0x70E2, (q15_t)0xC247, (q15_t)0x7023, + (q15_t)0xC0E8, (q15_t)0x6F5F, (q15_t)0xBF8C, (q15_t)0x6E96, + (q15_t)0xBE31, (q15_t)0x6DCA, (q15_t)0xBCDA, (q15_t)0x6CF9, + (q15_t)0xBB85, (q15_t)0x6C24, (q15_t)0xBA32, (q15_t)0x6B4A, + (q15_t)0xB8E3, (q15_t)0x6A6D, (q15_t)0xB796, (q15_t)0x698C, + (q15_t)0xB64B, (q15_t)0x68A6, (q15_t)0xB504, (q15_t)0x67BD, + (q15_t)0xB3C0, (q15_t)0x66CF, (q15_t)0xB27E, (q15_t)0x65DD, + (q15_t)0xB140, (q15_t)0x64E8, (q15_t)0xB004, (q15_t)0x63EF, + (q15_t)0xAECC, (q15_t)0x62F2, (q15_t)0xAD96, (q15_t)0x61F1, + (q15_t)0xAC64, (q15_t)0x60EC, (q15_t)0xAB35, (q15_t)0x5FE3, + (q15_t)0xAA0A, (q15_t)0x5ED7, (q15_t)0xA8E2, (q15_t)0x5DC7, + (q15_t)0xA7BD, (q15_t)0x5CB4, (q15_t)0xA69B, (q15_t)0x5B9D, + (q15_t)0xA57D, (q15_t)0x5A82, (q15_t)0xA462, (q15_t)0x5964, + (q15_t)0xA34B, (q15_t)0x5842, (q15_t)0xA238, (q15_t)0x571D, + (q15_t)0xA128, (q15_t)0x55F5, (q15_t)0xA01C, (q15_t)0x54CA, + (q15_t)0x9F13, (q15_t)0x539B, (q15_t)0x9E0E, (q15_t)0x5269, + (q15_t)0x9D0D, (q15_t)0x5133, (q15_t)0x9C10, (q15_t)0x4FFB, + (q15_t)0x9B17, (q15_t)0x4EBF, (q15_t)0x9A22, (q15_t)0x4D81, + (q15_t)0x9930, (q15_t)0x4C3F, (q15_t)0x9842, (q15_t)0x4AFB, + (q15_t)0x9759, (q15_t)0x49B4, (q15_t)0x9673, (q15_t)0x4869, + (q15_t)0x9592, (q15_t)0x471C, (q15_t)0x94B5, (q15_t)0x45CD, + (q15_t)0x93DB, (q15_t)0x447A, (q15_t)0x9306, (q15_t)0x4325, + (q15_t)0x9235, (q15_t)0x41CE, (q15_t)0x9169, (q15_t)0x4073, + (q15_t)0x90A0, (q15_t)0x3F17, (q15_t)0x8FDC, (q15_t)0x3DB8, + (q15_t)0x8F1D, (q15_t)0x3C56, (q15_t)0x8E61, (q15_t)0x3AF2, + (q15_t)0x8DAA, (q15_t)0x398C, (q15_t)0x8CF8, (q15_t)0x3824, + (q15_t)0x8C4A, (q15_t)0x36BA, (q15_t)0x8BA0, (q15_t)0x354D, + (q15_t)0x8AFB, (q15_t)0x33DE, (q15_t)0x8A5A, (q15_t)0x326E, + (q15_t)0x89BE, (q15_t)0x30FB, (q15_t)0x8926, (q15_t)0x2F87, + (q15_t)0x8893, (q15_t)0x2E11, (q15_t)0x8805, (q15_t)0x2C98, + (q15_t)0x877B, (q15_t)0x2B1F, (q15_t)0x86F6, (q15_t)0x29A3, + (q15_t)0x8675, (q15_t)0x2826, (q15_t)0x85FA, (q15_t)0x26A8, + (q15_t)0x8582, (q15_t)0x2528, (q15_t)0x8510, (q15_t)0x23A6, + (q15_t)0x84A2, (q15_t)0x2223, (q15_t)0x843A, (q15_t)0x209F, + (q15_t)0x83D6, (q15_t)0x1F19, (q15_t)0x8376, (q15_t)0x1D93, + (q15_t)0x831C, (q15_t)0x1C0B, (q15_t)0x82C6, (q15_t)0x1A82, + (q15_t)0x8275, (q15_t)0x18F8, (q15_t)0x8229, (q15_t)0x176D, + (q15_t)0x81E2, (q15_t)0x15E2, (q15_t)0x81A0, (q15_t)0x1455, + (q15_t)0x8162, (q15_t)0x12C8, (q15_t)0x812A, (q15_t)0x1139, + (q15_t)0x80F6, (q15_t)0x0FAB, (q15_t)0x80C7, (q15_t)0x0E1B, + (q15_t)0x809D, (q15_t)0x0C8B, (q15_t)0x8078, (q15_t)0x0AFB, + (q15_t)0x8058, (q15_t)0x096A, (q15_t)0x803D, (q15_t)0x07D9, + (q15_t)0x8027, (q15_t)0x0647, (q15_t)0x8016, (q15_t)0x04B6, + (q15_t)0x8009, (q15_t)0x0324, (q15_t)0x8002, (q15_t)0x0192, + (q15_t)0x8000, (q15_t)0x0000, (q15_t)0x8002, (q15_t)0xFE6D, + (q15_t)0x8009, (q15_t)0xFCDB, (q15_t)0x8016, (q15_t)0xFB49, + (q15_t)0x8027, (q15_t)0xF9B8, (q15_t)0x803D, (q15_t)0xF826, + (q15_t)0x8058, (q15_t)0xF695, (q15_t)0x8078, (q15_t)0xF504, + (q15_t)0x809D, (q15_t)0xF374, (q15_t)0x80C7, (q15_t)0xF1E4, + (q15_t)0x80F6, (q15_t)0xF054, (q15_t)0x812A, (q15_t)0xEEC6, + (q15_t)0x8162, (q15_t)0xED37, (q15_t)0x81A0, (q15_t)0xEBAA, + (q15_t)0x81E2, (q15_t)0xEA1D, (q15_t)0x8229, (q15_t)0xE892, + (q15_t)0x8275, (q15_t)0xE707, (q15_t)0x82C6, (q15_t)0xE57D, + (q15_t)0x831C, (q15_t)0xE3F4, (q15_t)0x8376, (q15_t)0xE26C, + (q15_t)0x83D6, (q15_t)0xE0E6, (q15_t)0x843A, (q15_t)0xDF60, + (q15_t)0x84A2, (q15_t)0xDDDC, (q15_t)0x8510, (q15_t)0xDC59, + (q15_t)0x8582, (q15_t)0xDAD7, (q15_t)0x85FA, (q15_t)0xD957, + (q15_t)0x8675, (q15_t)0xD7D9, (q15_t)0x86F6, (q15_t)0xD65C, + (q15_t)0x877B, (q15_t)0xD4E0, (q15_t)0x8805, (q15_t)0xD367, + (q15_t)0x8893, (q15_t)0xD1EE, (q15_t)0x8926, (q15_t)0xD078, + (q15_t)0x89BE, (q15_t)0xCF04, (q15_t)0x8A5A, (q15_t)0xCD91, + (q15_t)0x8AFB, (q15_t)0xCC21, (q15_t)0x8BA0, (q15_t)0xCAB2, + (q15_t)0x8C4A, (q15_t)0xC945, (q15_t)0x8CF8, (q15_t)0xC7DB, + (q15_t)0x8DAA, (q15_t)0xC673, (q15_t)0x8E61, (q15_t)0xC50D, + (q15_t)0x8F1D, (q15_t)0xC3A9, (q15_t)0x8FDC, (q15_t)0xC247, + (q15_t)0x90A0, (q15_t)0xC0E8, (q15_t)0x9169, (q15_t)0xBF8C, + (q15_t)0x9235, (q15_t)0xBE31, (q15_t)0x9306, (q15_t)0xBCDA, + (q15_t)0x93DB, (q15_t)0xBB85, (q15_t)0x94B5, (q15_t)0xBA32, + (q15_t)0x9592, (q15_t)0xB8E3, (q15_t)0x9673, (q15_t)0xB796, + (q15_t)0x9759, (q15_t)0xB64B, (q15_t)0x9842, (q15_t)0xB504, + (q15_t)0x9930, (q15_t)0xB3C0, (q15_t)0x9A22, (q15_t)0xB27E, + (q15_t)0x9B17, (q15_t)0xB140, (q15_t)0x9C10, (q15_t)0xB004, + (q15_t)0x9D0D, (q15_t)0xAECC, (q15_t)0x9E0E, (q15_t)0xAD96, + (q15_t)0x9F13, (q15_t)0xAC64, (q15_t)0xA01C, (q15_t)0xAB35, + (q15_t)0xA128, (q15_t)0xAA0A, (q15_t)0xA238, (q15_t)0xA8E2, + (q15_t)0xA34B, (q15_t)0xA7BD, (q15_t)0xA462, (q15_t)0xA69B, + (q15_t)0xA57D, (q15_t)0xA57D, (q15_t)0xA69B, (q15_t)0xA462, + (q15_t)0xA7BD, (q15_t)0xA34B, (q15_t)0xA8E2, (q15_t)0xA238, + (q15_t)0xAA0A, (q15_t)0xA128, (q15_t)0xAB35, (q15_t)0xA01C, + (q15_t)0xAC64, (q15_t)0x9F13, (q15_t)0xAD96, (q15_t)0x9E0E, + (q15_t)0xAECC, (q15_t)0x9D0D, (q15_t)0xB004, (q15_t)0x9C10, + (q15_t)0xB140, (q15_t)0x9B17, (q15_t)0xB27E, (q15_t)0x9A22, + (q15_t)0xB3C0, (q15_t)0x9930, (q15_t)0xB504, (q15_t)0x9842, + (q15_t)0xB64B, (q15_t)0x9759, (q15_t)0xB796, (q15_t)0x9673, + (q15_t)0xB8E3, (q15_t)0x9592, (q15_t)0xBA32, (q15_t)0x94B5, + (q15_t)0xBB85, (q15_t)0x93DB, (q15_t)0xBCDA, (q15_t)0x9306, + (q15_t)0xBE31, (q15_t)0x9235, (q15_t)0xBF8C, (q15_t)0x9169, + (q15_t)0xC0E8, (q15_t)0x90A0, (q15_t)0xC247, (q15_t)0x8FDC, + (q15_t)0xC3A9, (q15_t)0x8F1D, (q15_t)0xC50D, (q15_t)0x8E61, + (q15_t)0xC673, (q15_t)0x8DAA, (q15_t)0xC7DB, (q15_t)0x8CF8, + (q15_t)0xC945, (q15_t)0x8C4A, (q15_t)0xCAB2, (q15_t)0x8BA0, + (q15_t)0xCC21, (q15_t)0x8AFB, (q15_t)0xCD91, (q15_t)0x8A5A, + (q15_t)0xCF04, (q15_t)0x89BE, (q15_t)0xD078, (q15_t)0x8926, + (q15_t)0xD1EE, (q15_t)0x8893, (q15_t)0xD367, (q15_t)0x8805, + (q15_t)0xD4E0, (q15_t)0x877B, (q15_t)0xD65C, (q15_t)0x86F6, + (q15_t)0xD7D9, (q15_t)0x8675, (q15_t)0xD957, (q15_t)0x85FA, + (q15_t)0xDAD7, (q15_t)0x8582, (q15_t)0xDC59, (q15_t)0x8510, + (q15_t)0xDDDC, (q15_t)0x84A2, (q15_t)0xDF60, (q15_t)0x843A, + (q15_t)0xE0E6, (q15_t)0x83D6, (q15_t)0xE26C, (q15_t)0x8376, + (q15_t)0xE3F4, (q15_t)0x831C, (q15_t)0xE57D, (q15_t)0x82C6, + (q15_t)0xE707, (q15_t)0x8275, (q15_t)0xE892, (q15_t)0x8229, + (q15_t)0xEA1D, (q15_t)0x81E2, (q15_t)0xEBAA, (q15_t)0x81A0, + (q15_t)0xED37, (q15_t)0x8162, (q15_t)0xEEC6, (q15_t)0x812A, + (q15_t)0xF054, (q15_t)0x80F6, (q15_t)0xF1E4, (q15_t)0x80C7, + (q15_t)0xF374, (q15_t)0x809D, (q15_t)0xF504, (q15_t)0x8078, + (q15_t)0xF695, (q15_t)0x8058, (q15_t)0xF826, (q15_t)0x803D, + (q15_t)0xF9B8, (q15_t)0x8027, (q15_t)0xFB49, (q15_t)0x8016, + (q15_t)0xFCDB, (q15_t)0x8009, (q15_t)0xFE6D, (q15_t)0x8002 +}; + +/** + @par + Example code for q15 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefq15[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefq15[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 1024, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to q15(Fixed point 1.15): + round(twiddleCoefq15(i) * pow(2, 15)) + + */ +const q15_t twiddleCoef_1024_q15[1536] = { + (q15_t)0x7FFF, (q15_t)0x0000, (q15_t)0x7FFF, (q15_t)0x00C9, + (q15_t)0x7FFD, (q15_t)0x0192, (q15_t)0x7FFA, (q15_t)0x025B, + (q15_t)0x7FF6, (q15_t)0x0324, (q15_t)0x7FF0, (q15_t)0x03ED, + (q15_t)0x7FE9, (q15_t)0x04B6, (q15_t)0x7FE1, (q15_t)0x057F, + (q15_t)0x7FD8, (q15_t)0x0647, (q15_t)0x7FCE, (q15_t)0x0710, + (q15_t)0x7FC2, (q15_t)0x07D9, (q15_t)0x7FB5, (q15_t)0x08A2, + (q15_t)0x7FA7, (q15_t)0x096A, (q15_t)0x7F97, (q15_t)0x0A33, + (q15_t)0x7F87, (q15_t)0x0AFB, (q15_t)0x7F75, (q15_t)0x0BC3, + (q15_t)0x7F62, (q15_t)0x0C8B, (q15_t)0x7F4D, (q15_t)0x0D53, + (q15_t)0x7F38, (q15_t)0x0E1B, (q15_t)0x7F21, (q15_t)0x0EE3, + (q15_t)0x7F09, (q15_t)0x0FAB, (q15_t)0x7EF0, (q15_t)0x1072, + (q15_t)0x7ED5, (q15_t)0x1139, (q15_t)0x7EBA, (q15_t)0x1201, + (q15_t)0x7E9D, (q15_t)0x12C8, (q15_t)0x7E7F, (q15_t)0x138E, + (q15_t)0x7E5F, (q15_t)0x1455, (q15_t)0x7E3F, (q15_t)0x151B, + (q15_t)0x7E1D, (q15_t)0x15E2, (q15_t)0x7DFA, (q15_t)0x16A8, + (q15_t)0x7DD6, (q15_t)0x176D, (q15_t)0x7DB0, (q15_t)0x1833, + (q15_t)0x7D8A, (q15_t)0x18F8, (q15_t)0x7D62, (q15_t)0x19BD, + (q15_t)0x7D39, (q15_t)0x1A82, (q15_t)0x7D0F, (q15_t)0x1B47, + (q15_t)0x7CE3, (q15_t)0x1C0B, (q15_t)0x7CB7, (q15_t)0x1CCF, + (q15_t)0x7C89, (q15_t)0x1D93, (q15_t)0x7C5A, (q15_t)0x1E56, + (q15_t)0x7C29, (q15_t)0x1F19, (q15_t)0x7BF8, (q15_t)0x1FDC, + (q15_t)0x7BC5, (q15_t)0x209F, (q15_t)0x7B92, (q15_t)0x2161, + (q15_t)0x7B5D, (q15_t)0x2223, (q15_t)0x7B26, (q15_t)0x22E5, + (q15_t)0x7AEF, (q15_t)0x23A6, (q15_t)0x7AB6, (q15_t)0x2467, + (q15_t)0x7A7D, (q15_t)0x2528, (q15_t)0x7A42, (q15_t)0x25E8, + (q15_t)0x7A05, (q15_t)0x26A8, (q15_t)0x79C8, (q15_t)0x2767, + (q15_t)0x798A, (q15_t)0x2826, (q15_t)0x794A, (q15_t)0x28E5, + (q15_t)0x7909, (q15_t)0x29A3, (q15_t)0x78C7, (q15_t)0x2A61, + (q15_t)0x7884, (q15_t)0x2B1F, (q15_t)0x7840, (q15_t)0x2BDC, + (q15_t)0x77FA, (q15_t)0x2C98, (q15_t)0x77B4, (q15_t)0x2D55, + (q15_t)0x776C, (q15_t)0x2E11, (q15_t)0x7723, (q15_t)0x2ECC, + (q15_t)0x76D9, (q15_t)0x2F87, (q15_t)0x768E, (q15_t)0x3041, + (q15_t)0x7641, (q15_t)0x30FB, (q15_t)0x75F4, (q15_t)0x31B5, + (q15_t)0x75A5, (q15_t)0x326E, (q15_t)0x7555, (q15_t)0x3326, + (q15_t)0x7504, (q15_t)0x33DE, (q15_t)0x74B2, (q15_t)0x3496, + (q15_t)0x745F, (q15_t)0x354D, (q15_t)0x740B, (q15_t)0x3604, + (q15_t)0x73B5, (q15_t)0x36BA, (q15_t)0x735F, (q15_t)0x376F, + (q15_t)0x7307, (q15_t)0x3824, (q15_t)0x72AF, (q15_t)0x38D8, + (q15_t)0x7255, (q15_t)0x398C, (q15_t)0x71FA, (q15_t)0x3A40, + (q15_t)0x719E, (q15_t)0x3AF2, (q15_t)0x7141, (q15_t)0x3BA5, + (q15_t)0x70E2, (q15_t)0x3C56, (q15_t)0x7083, (q15_t)0x3D07, + (q15_t)0x7023, (q15_t)0x3DB8, (q15_t)0x6FC1, (q15_t)0x3E68, + (q15_t)0x6F5F, (q15_t)0x3F17, (q15_t)0x6EFB, (q15_t)0x3FC5, + (q15_t)0x6E96, (q15_t)0x4073, (q15_t)0x6E30, (q15_t)0x4121, + (q15_t)0x6DCA, (q15_t)0x41CE, (q15_t)0x6D62, (q15_t)0x427A, + (q15_t)0x6CF9, (q15_t)0x4325, (q15_t)0x6C8F, (q15_t)0x43D0, + (q15_t)0x6C24, (q15_t)0x447A, (q15_t)0x6BB8, (q15_t)0x4524, + (q15_t)0x6B4A, (q15_t)0x45CD, (q15_t)0x6ADC, (q15_t)0x4675, + (q15_t)0x6A6D, (q15_t)0x471C, (q15_t)0x69FD, (q15_t)0x47C3, + (q15_t)0x698C, (q15_t)0x4869, (q15_t)0x6919, (q15_t)0x490F, + (q15_t)0x68A6, (q15_t)0x49B4, (q15_t)0x6832, (q15_t)0x4A58, + (q15_t)0x67BD, (q15_t)0x4AFB, (q15_t)0x6746, (q15_t)0x4B9E, + (q15_t)0x66CF, (q15_t)0x4C3F, (q15_t)0x6657, (q15_t)0x4CE1, + (q15_t)0x65DD, (q15_t)0x4D81, (q15_t)0x6563, (q15_t)0x4E21, + (q15_t)0x64E8, (q15_t)0x4EBF, (q15_t)0x646C, (q15_t)0x4F5E, + (q15_t)0x63EF, (q15_t)0x4FFB, (q15_t)0x6371, (q15_t)0x5097, + (q15_t)0x62F2, (q15_t)0x5133, (q15_t)0x6271, (q15_t)0x51CE, + (q15_t)0x61F1, (q15_t)0x5269, (q15_t)0x616F, (q15_t)0x5302, + (q15_t)0x60EC, (q15_t)0x539B, (q15_t)0x6068, (q15_t)0x5433, + (q15_t)0x5FE3, (q15_t)0x54CA, (q15_t)0x5F5E, (q15_t)0x5560, + (q15_t)0x5ED7, (q15_t)0x55F5, (q15_t)0x5E50, (q15_t)0x568A, + (q15_t)0x5DC7, (q15_t)0x571D, (q15_t)0x5D3E, (q15_t)0x57B0, + (q15_t)0x5CB4, (q15_t)0x5842, (q15_t)0x5C29, (q15_t)0x58D4, + (q15_t)0x5B9D, (q15_t)0x5964, (q15_t)0x5B10, (q15_t)0x59F3, + (q15_t)0x5A82, (q15_t)0x5A82, (q15_t)0x59F3, (q15_t)0x5B10, + (q15_t)0x5964, (q15_t)0x5B9D, (q15_t)0x58D4, (q15_t)0x5C29, + (q15_t)0x5842, (q15_t)0x5CB4, (q15_t)0x57B0, (q15_t)0x5D3E, + (q15_t)0x571D, (q15_t)0x5DC7, (q15_t)0x568A, (q15_t)0x5E50, + (q15_t)0x55F5, (q15_t)0x5ED7, (q15_t)0x5560, (q15_t)0x5F5E, + (q15_t)0x54CA, (q15_t)0x5FE3, (q15_t)0x5433, (q15_t)0x6068, + (q15_t)0x539B, (q15_t)0x60EC, (q15_t)0x5302, (q15_t)0x616F, + (q15_t)0x5269, (q15_t)0x61F1, (q15_t)0x51CE, (q15_t)0x6271, + (q15_t)0x5133, (q15_t)0x62F2, (q15_t)0x5097, (q15_t)0x6371, + (q15_t)0x4FFB, (q15_t)0x63EF, (q15_t)0x4F5E, (q15_t)0x646C, + (q15_t)0x4EBF, (q15_t)0x64E8, (q15_t)0x4E21, (q15_t)0x6563, + (q15_t)0x4D81, (q15_t)0x65DD, (q15_t)0x4CE1, (q15_t)0x6657, + (q15_t)0x4C3F, (q15_t)0x66CF, (q15_t)0x4B9E, (q15_t)0x6746, + (q15_t)0x4AFB, (q15_t)0x67BD, (q15_t)0x4A58, (q15_t)0x6832, + (q15_t)0x49B4, (q15_t)0x68A6, (q15_t)0x490F, (q15_t)0x6919, + (q15_t)0x4869, (q15_t)0x698C, (q15_t)0x47C3, (q15_t)0x69FD, + (q15_t)0x471C, (q15_t)0x6A6D, (q15_t)0x4675, (q15_t)0x6ADC, + (q15_t)0x45CD, (q15_t)0x6B4A, (q15_t)0x4524, (q15_t)0x6BB8, + (q15_t)0x447A, (q15_t)0x6C24, (q15_t)0x43D0, (q15_t)0x6C8F, + (q15_t)0x4325, (q15_t)0x6CF9, (q15_t)0x427A, (q15_t)0x6D62, + (q15_t)0x41CE, (q15_t)0x6DCA, (q15_t)0x4121, (q15_t)0x6E30, + (q15_t)0x4073, (q15_t)0x6E96, (q15_t)0x3FC5, (q15_t)0x6EFB, + (q15_t)0x3F17, (q15_t)0x6F5F, (q15_t)0x3E68, (q15_t)0x6FC1, + (q15_t)0x3DB8, (q15_t)0x7023, (q15_t)0x3D07, (q15_t)0x7083, + (q15_t)0x3C56, (q15_t)0x70E2, (q15_t)0x3BA5, (q15_t)0x7141, + (q15_t)0x3AF2, (q15_t)0x719E, (q15_t)0x3A40, (q15_t)0x71FA, + (q15_t)0x398C, (q15_t)0x7255, (q15_t)0x38D8, (q15_t)0x72AF, + (q15_t)0x3824, (q15_t)0x7307, (q15_t)0x376F, (q15_t)0x735F, + (q15_t)0x36BA, (q15_t)0x73B5, (q15_t)0x3604, (q15_t)0x740B, + (q15_t)0x354D, (q15_t)0x745F, (q15_t)0x3496, (q15_t)0x74B2, + (q15_t)0x33DE, (q15_t)0x7504, (q15_t)0x3326, (q15_t)0x7555, + (q15_t)0x326E, (q15_t)0x75A5, (q15_t)0x31B5, (q15_t)0x75F4, + (q15_t)0x30FB, (q15_t)0x7641, (q15_t)0x3041, (q15_t)0x768E, + (q15_t)0x2F87, (q15_t)0x76D9, (q15_t)0x2ECC, (q15_t)0x7723, + (q15_t)0x2E11, (q15_t)0x776C, (q15_t)0x2D55, (q15_t)0x77B4, + (q15_t)0x2C98, (q15_t)0x77FA, (q15_t)0x2BDC, (q15_t)0x7840, + (q15_t)0x2B1F, (q15_t)0x7884, (q15_t)0x2A61, (q15_t)0x78C7, + (q15_t)0x29A3, (q15_t)0x7909, (q15_t)0x28E5, (q15_t)0x794A, + (q15_t)0x2826, (q15_t)0x798A, (q15_t)0x2767, (q15_t)0x79C8, + (q15_t)0x26A8, (q15_t)0x7A05, (q15_t)0x25E8, (q15_t)0x7A42, + (q15_t)0x2528, (q15_t)0x7A7D, (q15_t)0x2467, (q15_t)0x7AB6, + (q15_t)0x23A6, (q15_t)0x7AEF, (q15_t)0x22E5, (q15_t)0x7B26, + (q15_t)0x2223, (q15_t)0x7B5D, (q15_t)0x2161, (q15_t)0x7B92, + (q15_t)0x209F, (q15_t)0x7BC5, (q15_t)0x1FDC, (q15_t)0x7BF8, + (q15_t)0x1F19, (q15_t)0x7C29, (q15_t)0x1E56, (q15_t)0x7C5A, + (q15_t)0x1D93, (q15_t)0x7C89, (q15_t)0x1CCF, (q15_t)0x7CB7, + (q15_t)0x1C0B, (q15_t)0x7CE3, (q15_t)0x1B47, (q15_t)0x7D0F, + (q15_t)0x1A82, (q15_t)0x7D39, (q15_t)0x19BD, (q15_t)0x7D62, + (q15_t)0x18F8, (q15_t)0x7D8A, (q15_t)0x1833, (q15_t)0x7DB0, + (q15_t)0x176D, (q15_t)0x7DD6, (q15_t)0x16A8, (q15_t)0x7DFA, + (q15_t)0x15E2, (q15_t)0x7E1D, (q15_t)0x151B, (q15_t)0x7E3F, + (q15_t)0x1455, (q15_t)0x7E5F, (q15_t)0x138E, (q15_t)0x7E7F, + (q15_t)0x12C8, (q15_t)0x7E9D, (q15_t)0x1201, (q15_t)0x7EBA, + (q15_t)0x1139, (q15_t)0x7ED5, (q15_t)0x1072, (q15_t)0x7EF0, + (q15_t)0x0FAB, (q15_t)0x7F09, (q15_t)0x0EE3, (q15_t)0x7F21, + (q15_t)0x0E1B, (q15_t)0x7F38, (q15_t)0x0D53, (q15_t)0x7F4D, + (q15_t)0x0C8B, (q15_t)0x7F62, (q15_t)0x0BC3, (q15_t)0x7F75, + (q15_t)0x0AFB, (q15_t)0x7F87, (q15_t)0x0A33, (q15_t)0x7F97, + (q15_t)0x096A, (q15_t)0x7FA7, (q15_t)0x08A2, (q15_t)0x7FB5, + (q15_t)0x07D9, (q15_t)0x7FC2, (q15_t)0x0710, (q15_t)0x7FCE, + (q15_t)0x0647, (q15_t)0x7FD8, (q15_t)0x057F, (q15_t)0x7FE1, + (q15_t)0x04B6, (q15_t)0x7FE9, (q15_t)0x03ED, (q15_t)0x7FF0, + (q15_t)0x0324, (q15_t)0x7FF6, (q15_t)0x025B, (q15_t)0x7FFA, + (q15_t)0x0192, (q15_t)0x7FFD, (q15_t)0x00C9, (q15_t)0x7FFF, + (q15_t)0x0000, (q15_t)0x7FFF, (q15_t)0xFF36, (q15_t)0x7FFF, + (q15_t)0xFE6D, (q15_t)0x7FFD, (q15_t)0xFDA4, (q15_t)0x7FFA, + (q15_t)0xFCDB, (q15_t)0x7FF6, (q15_t)0xFC12, (q15_t)0x7FF0, + (q15_t)0xFB49, (q15_t)0x7FE9, (q15_t)0xFA80, (q15_t)0x7FE1, + (q15_t)0xF9B8, (q15_t)0x7FD8, (q15_t)0xF8EF, (q15_t)0x7FCE, + (q15_t)0xF826, (q15_t)0x7FC2, (q15_t)0xF75D, (q15_t)0x7FB5, + (q15_t)0xF695, (q15_t)0x7FA7, (q15_t)0xF5CC, (q15_t)0x7F97, + (q15_t)0xF504, (q15_t)0x7F87, (q15_t)0xF43C, (q15_t)0x7F75, + (q15_t)0xF374, (q15_t)0x7F62, (q15_t)0xF2AC, (q15_t)0x7F4D, + (q15_t)0xF1E4, (q15_t)0x7F38, (q15_t)0xF11C, (q15_t)0x7F21, + (q15_t)0xF054, (q15_t)0x7F09, (q15_t)0xEF8D, (q15_t)0x7EF0, + (q15_t)0xEEC6, (q15_t)0x7ED5, (q15_t)0xEDFE, (q15_t)0x7EBA, + (q15_t)0xED37, (q15_t)0x7E9D, (q15_t)0xEC71, (q15_t)0x7E7F, + (q15_t)0xEBAA, (q15_t)0x7E5F, (q15_t)0xEAE4, (q15_t)0x7E3F, + (q15_t)0xEA1D, (q15_t)0x7E1D, (q15_t)0xE957, (q15_t)0x7DFA, + (q15_t)0xE892, (q15_t)0x7DD6, (q15_t)0xE7CC, (q15_t)0x7DB0, + (q15_t)0xE707, (q15_t)0x7D8A, (q15_t)0xE642, (q15_t)0x7D62, + (q15_t)0xE57D, (q15_t)0x7D39, (q15_t)0xE4B8, (q15_t)0x7D0F, + (q15_t)0xE3F4, (q15_t)0x7CE3, (q15_t)0xE330, (q15_t)0x7CB7, + (q15_t)0xE26C, (q15_t)0x7C89, (q15_t)0xE1A9, (q15_t)0x7C5A, + (q15_t)0xE0E6, (q15_t)0x7C29, (q15_t)0xE023, (q15_t)0x7BF8, + (q15_t)0xDF60, (q15_t)0x7BC5, (q15_t)0xDE9E, (q15_t)0x7B92, + (q15_t)0xDDDC, (q15_t)0x7B5D, (q15_t)0xDD1A, (q15_t)0x7B26, + (q15_t)0xDC59, (q15_t)0x7AEF, (q15_t)0xDB98, (q15_t)0x7AB6, + (q15_t)0xDAD7, (q15_t)0x7A7D, (q15_t)0xDA17, (q15_t)0x7A42, + (q15_t)0xD957, (q15_t)0x7A05, (q15_t)0xD898, (q15_t)0x79C8, + (q15_t)0xD7D9, (q15_t)0x798A, (q15_t)0xD71A, (q15_t)0x794A, + (q15_t)0xD65C, (q15_t)0x7909, (q15_t)0xD59E, (q15_t)0x78C7, + (q15_t)0xD4E0, (q15_t)0x7884, (q15_t)0xD423, (q15_t)0x7840, + (q15_t)0xD367, (q15_t)0x77FA, (q15_t)0xD2AA, (q15_t)0x77B4, + (q15_t)0xD1EE, (q15_t)0x776C, (q15_t)0xD133, (q15_t)0x7723, + (q15_t)0xD078, (q15_t)0x76D9, (q15_t)0xCFBE, (q15_t)0x768E, + (q15_t)0xCF04, (q15_t)0x7641, (q15_t)0xCE4A, (q15_t)0x75F4, + (q15_t)0xCD91, (q15_t)0x75A5, (q15_t)0xCCD9, (q15_t)0x7555, + (q15_t)0xCC21, (q15_t)0x7504, (q15_t)0xCB69, (q15_t)0x74B2, + (q15_t)0xCAB2, (q15_t)0x745F, (q15_t)0xC9FB, (q15_t)0x740B, + (q15_t)0xC945, (q15_t)0x73B5, (q15_t)0xC890, (q15_t)0x735F, + (q15_t)0xC7DB, (q15_t)0x7307, (q15_t)0xC727, (q15_t)0x72AF, + (q15_t)0xC673, (q15_t)0x7255, (q15_t)0xC5BF, (q15_t)0x71FA, + (q15_t)0xC50D, (q15_t)0x719E, (q15_t)0xC45A, (q15_t)0x7141, + (q15_t)0xC3A9, (q15_t)0x70E2, (q15_t)0xC2F8, (q15_t)0x7083, + (q15_t)0xC247, (q15_t)0x7023, (q15_t)0xC197, (q15_t)0x6FC1, + (q15_t)0xC0E8, (q15_t)0x6F5F, (q15_t)0xC03A, (q15_t)0x6EFB, + (q15_t)0xBF8C, (q15_t)0x6E96, (q15_t)0xBEDE, (q15_t)0x6E30, + (q15_t)0xBE31, (q15_t)0x6DCA, (q15_t)0xBD85, (q15_t)0x6D62, + (q15_t)0xBCDA, (q15_t)0x6CF9, (q15_t)0xBC2F, (q15_t)0x6C8F, + (q15_t)0xBB85, (q15_t)0x6C24, (q15_t)0xBADB, (q15_t)0x6BB8, + (q15_t)0xBA32, (q15_t)0x6B4A, (q15_t)0xB98A, (q15_t)0x6ADC, + (q15_t)0xB8E3, (q15_t)0x6A6D, (q15_t)0xB83C, (q15_t)0x69FD, + (q15_t)0xB796, (q15_t)0x698C, (q15_t)0xB6F0, (q15_t)0x6919, + (q15_t)0xB64B, (q15_t)0x68A6, (q15_t)0xB5A7, (q15_t)0x6832, + (q15_t)0xB504, (q15_t)0x67BD, (q15_t)0xB461, (q15_t)0x6746, + (q15_t)0xB3C0, (q15_t)0x66CF, (q15_t)0xB31E, (q15_t)0x6657, + (q15_t)0xB27E, (q15_t)0x65DD, (q15_t)0xB1DE, (q15_t)0x6563, + (q15_t)0xB140, (q15_t)0x64E8, (q15_t)0xB0A1, (q15_t)0x646C, + (q15_t)0xB004, (q15_t)0x63EF, (q15_t)0xAF68, (q15_t)0x6371, + (q15_t)0xAECC, (q15_t)0x62F2, (q15_t)0xAE31, (q15_t)0x6271, + (q15_t)0xAD96, (q15_t)0x61F1, (q15_t)0xACFD, (q15_t)0x616F, + (q15_t)0xAC64, (q15_t)0x60EC, (q15_t)0xABCC, (q15_t)0x6068, + (q15_t)0xAB35, (q15_t)0x5FE3, (q15_t)0xAA9F, (q15_t)0x5F5E, + (q15_t)0xAA0A, (q15_t)0x5ED7, (q15_t)0xA975, (q15_t)0x5E50, + (q15_t)0xA8E2, (q15_t)0x5DC7, (q15_t)0xA84F, (q15_t)0x5D3E, + (q15_t)0xA7BD, (q15_t)0x5CB4, (q15_t)0xA72B, (q15_t)0x5C29, + (q15_t)0xA69B, (q15_t)0x5B9D, (q15_t)0xA60C, (q15_t)0x5B10, + (q15_t)0xA57D, (q15_t)0x5A82, (q15_t)0xA4EF, (q15_t)0x59F3, + (q15_t)0xA462, (q15_t)0x5964, (q15_t)0xA3D6, (q15_t)0x58D4, + (q15_t)0xA34B, (q15_t)0x5842, (q15_t)0xA2C1, (q15_t)0x57B0, + (q15_t)0xA238, (q15_t)0x571D, (q15_t)0xA1AF, (q15_t)0x568A, + (q15_t)0xA128, (q15_t)0x55F5, (q15_t)0xA0A1, (q15_t)0x5560, + (q15_t)0xA01C, (q15_t)0x54CA, (q15_t)0x9F97, (q15_t)0x5433, + (q15_t)0x9F13, (q15_t)0x539B, (q15_t)0x9E90, (q15_t)0x5302, + (q15_t)0x9E0E, (q15_t)0x5269, (q15_t)0x9D8E, (q15_t)0x51CE, + (q15_t)0x9D0D, (q15_t)0x5133, (q15_t)0x9C8E, (q15_t)0x5097, + (q15_t)0x9C10, (q15_t)0x4FFB, (q15_t)0x9B93, (q15_t)0x4F5E, + (q15_t)0x9B17, (q15_t)0x4EBF, (q15_t)0x9A9C, (q15_t)0x4E21, + (q15_t)0x9A22, (q15_t)0x4D81, (q15_t)0x99A8, (q15_t)0x4CE1, + (q15_t)0x9930, (q15_t)0x4C3F, (q15_t)0x98B9, (q15_t)0x4B9E, + (q15_t)0x9842, (q15_t)0x4AFB, (q15_t)0x97CD, (q15_t)0x4A58, + (q15_t)0x9759, (q15_t)0x49B4, (q15_t)0x96E6, (q15_t)0x490F, + (q15_t)0x9673, (q15_t)0x4869, (q15_t)0x9602, (q15_t)0x47C3, + (q15_t)0x9592, (q15_t)0x471C, (q15_t)0x9523, (q15_t)0x4675, + (q15_t)0x94B5, (q15_t)0x45CD, (q15_t)0x9447, (q15_t)0x4524, + (q15_t)0x93DB, (q15_t)0x447A, (q15_t)0x9370, (q15_t)0x43D0, + (q15_t)0x9306, (q15_t)0x4325, (q15_t)0x929D, (q15_t)0x427A, + (q15_t)0x9235, (q15_t)0x41CE, (q15_t)0x91CF, (q15_t)0x4121, + (q15_t)0x9169, (q15_t)0x4073, (q15_t)0x9104, (q15_t)0x3FC5, + (q15_t)0x90A0, (q15_t)0x3F17, (q15_t)0x903E, (q15_t)0x3E68, + (q15_t)0x8FDC, (q15_t)0x3DB8, (q15_t)0x8F7C, (q15_t)0x3D07, + (q15_t)0x8F1D, (q15_t)0x3C56, (q15_t)0x8EBE, (q15_t)0x3BA5, + (q15_t)0x8E61, (q15_t)0x3AF2, (q15_t)0x8E05, (q15_t)0x3A40, + (q15_t)0x8DAA, (q15_t)0x398C, (q15_t)0x8D50, (q15_t)0x38D8, + (q15_t)0x8CF8, (q15_t)0x3824, (q15_t)0x8CA0, (q15_t)0x376F, + (q15_t)0x8C4A, (q15_t)0x36BA, (q15_t)0x8BF4, (q15_t)0x3604, + (q15_t)0x8BA0, (q15_t)0x354D, (q15_t)0x8B4D, (q15_t)0x3496, + (q15_t)0x8AFB, (q15_t)0x33DE, (q15_t)0x8AAA, (q15_t)0x3326, + (q15_t)0x8A5A, (q15_t)0x326E, (q15_t)0x8A0B, (q15_t)0x31B5, + (q15_t)0x89BE, (q15_t)0x30FB, (q15_t)0x8971, (q15_t)0x3041, + (q15_t)0x8926, (q15_t)0x2F87, (q15_t)0x88DC, (q15_t)0x2ECC, + (q15_t)0x8893, (q15_t)0x2E11, (q15_t)0x884B, (q15_t)0x2D55, + (q15_t)0x8805, (q15_t)0x2C98, (q15_t)0x87BF, (q15_t)0x2BDC, + (q15_t)0x877B, (q15_t)0x2B1F, (q15_t)0x8738, (q15_t)0x2A61, + (q15_t)0x86F6, (q15_t)0x29A3, (q15_t)0x86B5, (q15_t)0x28E5, + (q15_t)0x8675, (q15_t)0x2826, (q15_t)0x8637, (q15_t)0x2767, + (q15_t)0x85FA, (q15_t)0x26A8, (q15_t)0x85BD, (q15_t)0x25E8, + (q15_t)0x8582, (q15_t)0x2528, (q15_t)0x8549, (q15_t)0x2467, + (q15_t)0x8510, (q15_t)0x23A6, (q15_t)0x84D9, (q15_t)0x22E5, + (q15_t)0x84A2, (q15_t)0x2223, (q15_t)0x846D, (q15_t)0x2161, + (q15_t)0x843A, (q15_t)0x209F, (q15_t)0x8407, (q15_t)0x1FDC, + (q15_t)0x83D6, (q15_t)0x1F19, (q15_t)0x83A5, (q15_t)0x1E56, + (q15_t)0x8376, (q15_t)0x1D93, (q15_t)0x8348, (q15_t)0x1CCF, + (q15_t)0x831C, (q15_t)0x1C0B, (q15_t)0x82F0, (q15_t)0x1B47, + (q15_t)0x82C6, (q15_t)0x1A82, (q15_t)0x829D, (q15_t)0x19BD, + (q15_t)0x8275, (q15_t)0x18F8, (q15_t)0x824F, (q15_t)0x1833, + (q15_t)0x8229, (q15_t)0x176D, (q15_t)0x8205, (q15_t)0x16A8, + (q15_t)0x81E2, (q15_t)0x15E2, (q15_t)0x81C0, (q15_t)0x151B, + (q15_t)0x81A0, (q15_t)0x1455, (q15_t)0x8180, (q15_t)0x138E, + (q15_t)0x8162, (q15_t)0x12C8, (q15_t)0x8145, (q15_t)0x1201, + (q15_t)0x812A, (q15_t)0x1139, (q15_t)0x810F, (q15_t)0x1072, + (q15_t)0x80F6, (q15_t)0x0FAB, (q15_t)0x80DE, (q15_t)0x0EE3, + (q15_t)0x80C7, (q15_t)0x0E1B, (q15_t)0x80B2, (q15_t)0x0D53, + (q15_t)0x809D, (q15_t)0x0C8B, (q15_t)0x808A, (q15_t)0x0BC3, + (q15_t)0x8078, (q15_t)0x0AFB, (q15_t)0x8068, (q15_t)0x0A33, + (q15_t)0x8058, (q15_t)0x096A, (q15_t)0x804A, (q15_t)0x08A2, + (q15_t)0x803D, (q15_t)0x07D9, (q15_t)0x8031, (q15_t)0x0710, + (q15_t)0x8027, (q15_t)0x0647, (q15_t)0x801E, (q15_t)0x057F, + (q15_t)0x8016, (q15_t)0x04B6, (q15_t)0x800F, (q15_t)0x03ED, + (q15_t)0x8009, (q15_t)0x0324, (q15_t)0x8005, (q15_t)0x025B, + (q15_t)0x8002, (q15_t)0x0192, (q15_t)0x8000, (q15_t)0x00C9, + (q15_t)0x8000, (q15_t)0x0000, (q15_t)0x8000, (q15_t)0xFF36, + (q15_t)0x8002, (q15_t)0xFE6D, (q15_t)0x8005, (q15_t)0xFDA4, + (q15_t)0x8009, (q15_t)0xFCDB, (q15_t)0x800F, (q15_t)0xFC12, + (q15_t)0x8016, (q15_t)0xFB49, (q15_t)0x801E, (q15_t)0xFA80, + (q15_t)0x8027, (q15_t)0xF9B8, (q15_t)0x8031, (q15_t)0xF8EF, + (q15_t)0x803D, (q15_t)0xF826, (q15_t)0x804A, (q15_t)0xF75D, + (q15_t)0x8058, (q15_t)0xF695, (q15_t)0x8068, (q15_t)0xF5CC, + (q15_t)0x8078, (q15_t)0xF504, (q15_t)0x808A, (q15_t)0xF43C, + (q15_t)0x809D, (q15_t)0xF374, (q15_t)0x80B2, (q15_t)0xF2AC, + (q15_t)0x80C7, (q15_t)0xF1E4, (q15_t)0x80DE, (q15_t)0xF11C, + (q15_t)0x80F6, (q15_t)0xF054, (q15_t)0x810F, (q15_t)0xEF8D, + (q15_t)0x812A, (q15_t)0xEEC6, (q15_t)0x8145, (q15_t)0xEDFE, + (q15_t)0x8162, (q15_t)0xED37, (q15_t)0x8180, (q15_t)0xEC71, + (q15_t)0x81A0, (q15_t)0xEBAA, (q15_t)0x81C0, (q15_t)0xEAE4, + (q15_t)0x81E2, (q15_t)0xEA1D, (q15_t)0x8205, (q15_t)0xE957, + (q15_t)0x8229, (q15_t)0xE892, (q15_t)0x824F, (q15_t)0xE7CC, + (q15_t)0x8275, (q15_t)0xE707, (q15_t)0x829D, (q15_t)0xE642, + (q15_t)0x82C6, (q15_t)0xE57D, (q15_t)0x82F0, (q15_t)0xE4B8, + (q15_t)0x831C, (q15_t)0xE3F4, (q15_t)0x8348, (q15_t)0xE330, + (q15_t)0x8376, (q15_t)0xE26C, (q15_t)0x83A5, (q15_t)0xE1A9, + (q15_t)0x83D6, (q15_t)0xE0E6, (q15_t)0x8407, (q15_t)0xE023, + (q15_t)0x843A, (q15_t)0xDF60, (q15_t)0x846D, (q15_t)0xDE9E, + (q15_t)0x84A2, (q15_t)0xDDDC, (q15_t)0x84D9, (q15_t)0xDD1A, + (q15_t)0x8510, (q15_t)0xDC59, (q15_t)0x8549, (q15_t)0xDB98, + (q15_t)0x8582, (q15_t)0xDAD7, (q15_t)0x85BD, (q15_t)0xDA17, + (q15_t)0x85FA, (q15_t)0xD957, (q15_t)0x8637, (q15_t)0xD898, + (q15_t)0x8675, (q15_t)0xD7D9, (q15_t)0x86B5, (q15_t)0xD71A, + (q15_t)0x86F6, (q15_t)0xD65C, (q15_t)0x8738, (q15_t)0xD59E, + (q15_t)0x877B, (q15_t)0xD4E0, (q15_t)0x87BF, (q15_t)0xD423, + (q15_t)0x8805, (q15_t)0xD367, (q15_t)0x884B, (q15_t)0xD2AA, + (q15_t)0x8893, (q15_t)0xD1EE, (q15_t)0x88DC, (q15_t)0xD133, + (q15_t)0x8926, (q15_t)0xD078, (q15_t)0x8971, (q15_t)0xCFBE, + (q15_t)0x89BE, (q15_t)0xCF04, (q15_t)0x8A0B, (q15_t)0xCE4A, + (q15_t)0x8A5A, (q15_t)0xCD91, (q15_t)0x8AAA, (q15_t)0xCCD9, + (q15_t)0x8AFB, (q15_t)0xCC21, (q15_t)0x8B4D, (q15_t)0xCB69, + (q15_t)0x8BA0, (q15_t)0xCAB2, (q15_t)0x8BF4, (q15_t)0xC9FB, + (q15_t)0x8C4A, (q15_t)0xC945, (q15_t)0x8CA0, (q15_t)0xC890, + (q15_t)0x8CF8, (q15_t)0xC7DB, (q15_t)0x8D50, (q15_t)0xC727, + (q15_t)0x8DAA, (q15_t)0xC673, (q15_t)0x8E05, (q15_t)0xC5BF, + (q15_t)0x8E61, (q15_t)0xC50D, (q15_t)0x8EBE, (q15_t)0xC45A, + (q15_t)0x8F1D, (q15_t)0xC3A9, (q15_t)0x8F7C, (q15_t)0xC2F8, + (q15_t)0x8FDC, (q15_t)0xC247, (q15_t)0x903E, (q15_t)0xC197, + (q15_t)0x90A0, (q15_t)0xC0E8, (q15_t)0x9104, (q15_t)0xC03A, + (q15_t)0x9169, (q15_t)0xBF8C, (q15_t)0x91CF, (q15_t)0xBEDE, + (q15_t)0x9235, (q15_t)0xBE31, (q15_t)0x929D, (q15_t)0xBD85, + (q15_t)0x9306, (q15_t)0xBCDA, (q15_t)0x9370, (q15_t)0xBC2F, + (q15_t)0x93DB, (q15_t)0xBB85, (q15_t)0x9447, (q15_t)0xBADB, + (q15_t)0x94B5, (q15_t)0xBA32, (q15_t)0x9523, (q15_t)0xB98A, + (q15_t)0x9592, (q15_t)0xB8E3, (q15_t)0x9602, (q15_t)0xB83C, + (q15_t)0x9673, (q15_t)0xB796, (q15_t)0x96E6, (q15_t)0xB6F0, + (q15_t)0x9759, (q15_t)0xB64B, (q15_t)0x97CD, (q15_t)0xB5A7, + (q15_t)0x9842, (q15_t)0xB504, (q15_t)0x98B9, (q15_t)0xB461, + (q15_t)0x9930, (q15_t)0xB3C0, (q15_t)0x99A8, (q15_t)0xB31E, + (q15_t)0x9A22, (q15_t)0xB27E, (q15_t)0x9A9C, (q15_t)0xB1DE, + (q15_t)0x9B17, (q15_t)0xB140, (q15_t)0x9B93, (q15_t)0xB0A1, + (q15_t)0x9C10, (q15_t)0xB004, (q15_t)0x9C8E, (q15_t)0xAF68, + (q15_t)0x9D0D, (q15_t)0xAECC, (q15_t)0x9D8E, (q15_t)0xAE31, + (q15_t)0x9E0E, (q15_t)0xAD96, (q15_t)0x9E90, (q15_t)0xACFD, + (q15_t)0x9F13, (q15_t)0xAC64, (q15_t)0x9F97, (q15_t)0xABCC, + (q15_t)0xA01C, (q15_t)0xAB35, (q15_t)0xA0A1, (q15_t)0xAA9F, + (q15_t)0xA128, (q15_t)0xAA0A, (q15_t)0xA1AF, (q15_t)0xA975, + (q15_t)0xA238, (q15_t)0xA8E2, (q15_t)0xA2C1, (q15_t)0xA84F, + (q15_t)0xA34B, (q15_t)0xA7BD, (q15_t)0xA3D6, (q15_t)0xA72B, + (q15_t)0xA462, (q15_t)0xA69B, (q15_t)0xA4EF, (q15_t)0xA60C, + (q15_t)0xA57D, (q15_t)0xA57D, (q15_t)0xA60C, (q15_t)0xA4EF, + (q15_t)0xA69B, (q15_t)0xA462, (q15_t)0xA72B, (q15_t)0xA3D6, + (q15_t)0xA7BD, (q15_t)0xA34B, (q15_t)0xA84F, (q15_t)0xA2C1, + (q15_t)0xA8E2, (q15_t)0xA238, (q15_t)0xA975, (q15_t)0xA1AF, + (q15_t)0xAA0A, (q15_t)0xA128, (q15_t)0xAA9F, (q15_t)0xA0A1, + (q15_t)0xAB35, (q15_t)0xA01C, (q15_t)0xABCC, (q15_t)0x9F97, + (q15_t)0xAC64, (q15_t)0x9F13, (q15_t)0xACFD, (q15_t)0x9E90, + (q15_t)0xAD96, (q15_t)0x9E0E, (q15_t)0xAE31, (q15_t)0x9D8E, + (q15_t)0xAECC, (q15_t)0x9D0D, (q15_t)0xAF68, (q15_t)0x9C8E, + (q15_t)0xB004, (q15_t)0x9C10, (q15_t)0xB0A1, (q15_t)0x9B93, + (q15_t)0xB140, (q15_t)0x9B17, (q15_t)0xB1DE, (q15_t)0x9A9C, + (q15_t)0xB27E, (q15_t)0x9A22, (q15_t)0xB31E, (q15_t)0x99A8, + (q15_t)0xB3C0, (q15_t)0x9930, (q15_t)0xB461, (q15_t)0x98B9, + (q15_t)0xB504, (q15_t)0x9842, (q15_t)0xB5A7, (q15_t)0x97CD, + (q15_t)0xB64B, (q15_t)0x9759, (q15_t)0xB6F0, (q15_t)0x96E6, + (q15_t)0xB796, (q15_t)0x9673, (q15_t)0xB83C, (q15_t)0x9602, + (q15_t)0xB8E3, (q15_t)0x9592, (q15_t)0xB98A, (q15_t)0x9523, + (q15_t)0xBA32, (q15_t)0x94B5, (q15_t)0xBADB, (q15_t)0x9447, + (q15_t)0xBB85, (q15_t)0x93DB, (q15_t)0xBC2F, (q15_t)0x9370, + (q15_t)0xBCDA, (q15_t)0x9306, (q15_t)0xBD85, (q15_t)0x929D, + (q15_t)0xBE31, (q15_t)0x9235, (q15_t)0xBEDE, (q15_t)0x91CF, + (q15_t)0xBF8C, (q15_t)0x9169, (q15_t)0xC03A, (q15_t)0x9104, + (q15_t)0xC0E8, (q15_t)0x90A0, (q15_t)0xC197, (q15_t)0x903E, + (q15_t)0xC247, (q15_t)0x8FDC, (q15_t)0xC2F8, (q15_t)0x8F7C, + (q15_t)0xC3A9, (q15_t)0x8F1D, (q15_t)0xC45A, (q15_t)0x8EBE, + (q15_t)0xC50D, (q15_t)0x8E61, (q15_t)0xC5BF, (q15_t)0x8E05, + (q15_t)0xC673, (q15_t)0x8DAA, (q15_t)0xC727, (q15_t)0x8D50, + (q15_t)0xC7DB, (q15_t)0x8CF8, (q15_t)0xC890, (q15_t)0x8CA0, + (q15_t)0xC945, (q15_t)0x8C4A, (q15_t)0xC9FB, (q15_t)0x8BF4, + (q15_t)0xCAB2, (q15_t)0x8BA0, (q15_t)0xCB69, (q15_t)0x8B4D, + (q15_t)0xCC21, (q15_t)0x8AFB, (q15_t)0xCCD9, (q15_t)0x8AAA, + (q15_t)0xCD91, (q15_t)0x8A5A, (q15_t)0xCE4A, (q15_t)0x8A0B, + (q15_t)0xCF04, (q15_t)0x89BE, (q15_t)0xCFBE, (q15_t)0x8971, + (q15_t)0xD078, (q15_t)0x8926, (q15_t)0xD133, (q15_t)0x88DC, + (q15_t)0xD1EE, (q15_t)0x8893, (q15_t)0xD2AA, (q15_t)0x884B, + (q15_t)0xD367, (q15_t)0x8805, (q15_t)0xD423, (q15_t)0x87BF, + (q15_t)0xD4E0, (q15_t)0x877B, (q15_t)0xD59E, (q15_t)0x8738, + (q15_t)0xD65C, (q15_t)0x86F6, (q15_t)0xD71A, (q15_t)0x86B5, + (q15_t)0xD7D9, (q15_t)0x8675, (q15_t)0xD898, (q15_t)0x8637, + (q15_t)0xD957, (q15_t)0x85FA, (q15_t)0xDA17, (q15_t)0x85BD, + (q15_t)0xDAD7, (q15_t)0x8582, (q15_t)0xDB98, (q15_t)0x8549, + (q15_t)0xDC59, (q15_t)0x8510, (q15_t)0xDD1A, (q15_t)0x84D9, + (q15_t)0xDDDC, (q15_t)0x84A2, (q15_t)0xDE9E, (q15_t)0x846D, + (q15_t)0xDF60, (q15_t)0x843A, (q15_t)0xE023, (q15_t)0x8407, + (q15_t)0xE0E6, (q15_t)0x83D6, (q15_t)0xE1A9, (q15_t)0x83A5, + (q15_t)0xE26C, (q15_t)0x8376, (q15_t)0xE330, (q15_t)0x8348, + (q15_t)0xE3F4, (q15_t)0x831C, (q15_t)0xE4B8, (q15_t)0x82F0, + (q15_t)0xE57D, (q15_t)0x82C6, (q15_t)0xE642, (q15_t)0x829D, + (q15_t)0xE707, (q15_t)0x8275, (q15_t)0xE7CC, (q15_t)0x824F, + (q15_t)0xE892, (q15_t)0x8229, (q15_t)0xE957, (q15_t)0x8205, + (q15_t)0xEA1D, (q15_t)0x81E2, (q15_t)0xEAE4, (q15_t)0x81C0, + (q15_t)0xEBAA, (q15_t)0x81A0, (q15_t)0xEC71, (q15_t)0x8180, + (q15_t)0xED37, (q15_t)0x8162, (q15_t)0xEDFE, (q15_t)0x8145, + (q15_t)0xEEC6, (q15_t)0x812A, (q15_t)0xEF8D, (q15_t)0x810F, + (q15_t)0xF054, (q15_t)0x80F6, (q15_t)0xF11C, (q15_t)0x80DE, + (q15_t)0xF1E4, (q15_t)0x80C7, (q15_t)0xF2AC, (q15_t)0x80B2, + (q15_t)0xF374, (q15_t)0x809D, (q15_t)0xF43C, (q15_t)0x808A, + (q15_t)0xF504, (q15_t)0x8078, (q15_t)0xF5CC, (q15_t)0x8068, + (q15_t)0xF695, (q15_t)0x8058, (q15_t)0xF75D, (q15_t)0x804A, + (q15_t)0xF826, (q15_t)0x803D, (q15_t)0xF8EF, (q15_t)0x8031, + (q15_t)0xF9B8, (q15_t)0x8027, (q15_t)0xFA80, (q15_t)0x801E, + (q15_t)0xFB49, (q15_t)0x8016, (q15_t)0xFC12, (q15_t)0x800F, + (q15_t)0xFCDB, (q15_t)0x8009, (q15_t)0xFDA4, (q15_t)0x8005, + (q15_t)0xFE6D, (q15_t)0x8002, (q15_t)0xFF36, (q15_t)0x8000 +}; + +/** + @par + Example code for q15 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefq15[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefq15[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 2048, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to q15(Fixed point 1.15): + round(twiddleCoefq15(i) * pow(2, 15)) + */ +const q15_t twiddleCoef_2048_q15[3072] = { + (q15_t)0x7FFF, (q15_t)0x0000, (q15_t)0x7FFF, (q15_t)0x0064, + (q15_t)0x7FFF, (q15_t)0x00C9, (q15_t)0x7FFE, (q15_t)0x012D, + (q15_t)0x7FFD, (q15_t)0x0192, (q15_t)0x7FFC, (q15_t)0x01F6, + (q15_t)0x7FFA, (q15_t)0x025B, (q15_t)0x7FF8, (q15_t)0x02BF, + (q15_t)0x7FF6, (q15_t)0x0324, (q15_t)0x7FF3, (q15_t)0x0388, + (q15_t)0x7FF0, (q15_t)0x03ED, (q15_t)0x7FED, (q15_t)0x0451, + (q15_t)0x7FE9, (q15_t)0x04B6, (q15_t)0x7FE5, (q15_t)0x051A, + (q15_t)0x7FE1, (q15_t)0x057F, (q15_t)0x7FDD, (q15_t)0x05E3, + (q15_t)0x7FD8, (q15_t)0x0647, (q15_t)0x7FD3, (q15_t)0x06AC, + (q15_t)0x7FCE, (q15_t)0x0710, (q15_t)0x7FC8, (q15_t)0x0775, + (q15_t)0x7FC2, (q15_t)0x07D9, (q15_t)0x7FBC, (q15_t)0x083D, + (q15_t)0x7FB5, (q15_t)0x08A2, (q15_t)0x7FAE, (q15_t)0x0906, + (q15_t)0x7FA7, (q15_t)0x096A, (q15_t)0x7F9F, (q15_t)0x09CE, + (q15_t)0x7F97, (q15_t)0x0A33, (q15_t)0x7F8F, (q15_t)0x0A97, + (q15_t)0x7F87, (q15_t)0x0AFB, (q15_t)0x7F7E, (q15_t)0x0B5F, + (q15_t)0x7F75, (q15_t)0x0BC3, (q15_t)0x7F6B, (q15_t)0x0C27, + (q15_t)0x7F62, (q15_t)0x0C8B, (q15_t)0x7F58, (q15_t)0x0CEF, + (q15_t)0x7F4D, (q15_t)0x0D53, (q15_t)0x7F43, (q15_t)0x0DB7, + (q15_t)0x7F38, (q15_t)0x0E1B, (q15_t)0x7F2D, (q15_t)0x0E7F, + (q15_t)0x7F21, (q15_t)0x0EE3, (q15_t)0x7F15, (q15_t)0x0F47, + (q15_t)0x7F09, (q15_t)0x0FAB, (q15_t)0x7EFD, (q15_t)0x100E, + (q15_t)0x7EF0, (q15_t)0x1072, (q15_t)0x7EE3, (q15_t)0x10D6, + (q15_t)0x7ED5, (q15_t)0x1139, (q15_t)0x7EC8, (q15_t)0x119D, + (q15_t)0x7EBA, (q15_t)0x1201, (q15_t)0x7EAB, (q15_t)0x1264, + (q15_t)0x7E9D, (q15_t)0x12C8, (q15_t)0x7E8E, (q15_t)0x132B, + (q15_t)0x7E7F, (q15_t)0x138E, (q15_t)0x7E6F, (q15_t)0x13F2, + (q15_t)0x7E5F, (q15_t)0x1455, (q15_t)0x7E4F, (q15_t)0x14B8, + (q15_t)0x7E3F, (q15_t)0x151B, (q15_t)0x7E2E, (q15_t)0x157F, + (q15_t)0x7E1D, (q15_t)0x15E2, (q15_t)0x7E0C, (q15_t)0x1645, + (q15_t)0x7DFA, (q15_t)0x16A8, (q15_t)0x7DE8, (q15_t)0x170A, + (q15_t)0x7DD6, (q15_t)0x176D, (q15_t)0x7DC3, (q15_t)0x17D0, + (q15_t)0x7DB0, (q15_t)0x1833, (q15_t)0x7D9D, (q15_t)0x1896, + (q15_t)0x7D8A, (q15_t)0x18F8, (q15_t)0x7D76, (q15_t)0x195B, + (q15_t)0x7D62, (q15_t)0x19BD, (q15_t)0x7D4E, (q15_t)0x1A20, + (q15_t)0x7D39, (q15_t)0x1A82, (q15_t)0x7D24, (q15_t)0x1AE4, + (q15_t)0x7D0F, (q15_t)0x1B47, (q15_t)0x7CF9, (q15_t)0x1BA9, + (q15_t)0x7CE3, (q15_t)0x1C0B, (q15_t)0x7CCD, (q15_t)0x1C6D, + (q15_t)0x7CB7, (q15_t)0x1CCF, (q15_t)0x7CA0, (q15_t)0x1D31, + (q15_t)0x7C89, (q15_t)0x1D93, (q15_t)0x7C71, (q15_t)0x1DF5, + (q15_t)0x7C5A, (q15_t)0x1E56, (q15_t)0x7C42, (q15_t)0x1EB8, + (q15_t)0x7C29, (q15_t)0x1F19, (q15_t)0x7C11, (q15_t)0x1F7B, + (q15_t)0x7BF8, (q15_t)0x1FDC, (q15_t)0x7BDF, (q15_t)0x203E, + (q15_t)0x7BC5, (q15_t)0x209F, (q15_t)0x7BAC, (q15_t)0x2100, + (q15_t)0x7B92, (q15_t)0x2161, (q15_t)0x7B77, (q15_t)0x21C2, + (q15_t)0x7B5D, (q15_t)0x2223, (q15_t)0x7B42, (q15_t)0x2284, + (q15_t)0x7B26, (q15_t)0x22E5, (q15_t)0x7B0B, (q15_t)0x2345, + (q15_t)0x7AEF, (q15_t)0x23A6, (q15_t)0x7AD3, (q15_t)0x2407, + (q15_t)0x7AB6, (q15_t)0x2467, (q15_t)0x7A9A, (q15_t)0x24C7, + (q15_t)0x7A7D, (q15_t)0x2528, (q15_t)0x7A5F, (q15_t)0x2588, + (q15_t)0x7A42, (q15_t)0x25E8, (q15_t)0x7A24, (q15_t)0x2648, + (q15_t)0x7A05, (q15_t)0x26A8, (q15_t)0x79E7, (q15_t)0x2707, + (q15_t)0x79C8, (q15_t)0x2767, (q15_t)0x79A9, (q15_t)0x27C7, + (q15_t)0x798A, (q15_t)0x2826, (q15_t)0x796A, (q15_t)0x2886, + (q15_t)0x794A, (q15_t)0x28E5, (q15_t)0x792A, (q15_t)0x2944, + (q15_t)0x7909, (q15_t)0x29A3, (q15_t)0x78E8, (q15_t)0x2A02, + (q15_t)0x78C7, (q15_t)0x2A61, (q15_t)0x78A6, (q15_t)0x2AC0, + (q15_t)0x7884, (q15_t)0x2B1F, (q15_t)0x7862, (q15_t)0x2B7D, + (q15_t)0x7840, (q15_t)0x2BDC, (q15_t)0x781D, (q15_t)0x2C3A, + (q15_t)0x77FA, (q15_t)0x2C98, (q15_t)0x77D7, (q15_t)0x2CF7, + (q15_t)0x77B4, (q15_t)0x2D55, (q15_t)0x7790, (q15_t)0x2DB3, + (q15_t)0x776C, (q15_t)0x2E11, (q15_t)0x7747, (q15_t)0x2E6E, + (q15_t)0x7723, (q15_t)0x2ECC, (q15_t)0x76FE, (q15_t)0x2F29, + (q15_t)0x76D9, (q15_t)0x2F87, (q15_t)0x76B3, (q15_t)0x2FE4, + (q15_t)0x768E, (q15_t)0x3041, (q15_t)0x7668, (q15_t)0x309E, + (q15_t)0x7641, (q15_t)0x30FB, (q15_t)0x761B, (q15_t)0x3158, + (q15_t)0x75F4, (q15_t)0x31B5, (q15_t)0x75CC, (q15_t)0x3211, + (q15_t)0x75A5, (q15_t)0x326E, (q15_t)0x757D, (q15_t)0x32CA, + (q15_t)0x7555, (q15_t)0x3326, (q15_t)0x752D, (q15_t)0x3382, + (q15_t)0x7504, (q15_t)0x33DE, (q15_t)0x74DB, (q15_t)0x343A, + (q15_t)0x74B2, (q15_t)0x3496, (q15_t)0x7489, (q15_t)0x34F2, + (q15_t)0x745F, (q15_t)0x354D, (q15_t)0x7435, (q15_t)0x35A8, + (q15_t)0x740B, (q15_t)0x3604, (q15_t)0x73E0, (q15_t)0x365F, + (q15_t)0x73B5, (q15_t)0x36BA, (q15_t)0x738A, (q15_t)0x3714, + (q15_t)0x735F, (q15_t)0x376F, (q15_t)0x7333, (q15_t)0x37CA, + (q15_t)0x7307, (q15_t)0x3824, (q15_t)0x72DB, (q15_t)0x387E, + (q15_t)0x72AF, (q15_t)0x38D8, (q15_t)0x7282, (q15_t)0x3932, + (q15_t)0x7255, (q15_t)0x398C, (q15_t)0x7227, (q15_t)0x39E6, + (q15_t)0x71FA, (q15_t)0x3A40, (q15_t)0x71CC, (q15_t)0x3A99, + (q15_t)0x719E, (q15_t)0x3AF2, (q15_t)0x716F, (q15_t)0x3B4C, + (q15_t)0x7141, (q15_t)0x3BA5, (q15_t)0x7112, (q15_t)0x3BFD, + (q15_t)0x70E2, (q15_t)0x3C56, (q15_t)0x70B3, (q15_t)0x3CAF, + (q15_t)0x7083, (q15_t)0x3D07, (q15_t)0x7053, (q15_t)0x3D60, + (q15_t)0x7023, (q15_t)0x3DB8, (q15_t)0x6FF2, (q15_t)0x3E10, + (q15_t)0x6FC1, (q15_t)0x3E68, (q15_t)0x6F90, (q15_t)0x3EBF, + (q15_t)0x6F5F, (q15_t)0x3F17, (q15_t)0x6F2D, (q15_t)0x3F6E, + (q15_t)0x6EFB, (q15_t)0x3FC5, (q15_t)0x6EC9, (q15_t)0x401D, + (q15_t)0x6E96, (q15_t)0x4073, (q15_t)0x6E63, (q15_t)0x40CA, + (q15_t)0x6E30, (q15_t)0x4121, (q15_t)0x6DFD, (q15_t)0x4177, + (q15_t)0x6DCA, (q15_t)0x41CE, (q15_t)0x6D96, (q15_t)0x4224, + (q15_t)0x6D62, (q15_t)0x427A, (q15_t)0x6D2D, (q15_t)0x42D0, + (q15_t)0x6CF9, (q15_t)0x4325, (q15_t)0x6CC4, (q15_t)0x437B, + (q15_t)0x6C8F, (q15_t)0x43D0, (q15_t)0x6C59, (q15_t)0x4425, + (q15_t)0x6C24, (q15_t)0x447A, (q15_t)0x6BEE, (q15_t)0x44CF, + (q15_t)0x6BB8, (q15_t)0x4524, (q15_t)0x6B81, (q15_t)0x4578, + (q15_t)0x6B4A, (q15_t)0x45CD, (q15_t)0x6B13, (q15_t)0x4621, + (q15_t)0x6ADC, (q15_t)0x4675, (q15_t)0x6AA5, (q15_t)0x46C9, + (q15_t)0x6A6D, (q15_t)0x471C, (q15_t)0x6A35, (q15_t)0x4770, + (q15_t)0x69FD, (q15_t)0x47C3, (q15_t)0x69C4, (q15_t)0x4816, + (q15_t)0x698C, (q15_t)0x4869, (q15_t)0x6953, (q15_t)0x48BC, + (q15_t)0x6919, (q15_t)0x490F, (q15_t)0x68E0, (q15_t)0x4961, + (q15_t)0x68A6, (q15_t)0x49B4, (q15_t)0x686C, (q15_t)0x4A06, + (q15_t)0x6832, (q15_t)0x4A58, (q15_t)0x67F7, (q15_t)0x4AA9, + (q15_t)0x67BD, (q15_t)0x4AFB, (q15_t)0x6782, (q15_t)0x4B4C, + (q15_t)0x6746, (q15_t)0x4B9E, (q15_t)0x670B, (q15_t)0x4BEF, + (q15_t)0x66CF, (q15_t)0x4C3F, (q15_t)0x6693, (q15_t)0x4C90, + (q15_t)0x6657, (q15_t)0x4CE1, (q15_t)0x661A, (q15_t)0x4D31, + (q15_t)0x65DD, (q15_t)0x4D81, (q15_t)0x65A0, (q15_t)0x4DD1, + (q15_t)0x6563, (q15_t)0x4E21, (q15_t)0x6526, (q15_t)0x4E70, + (q15_t)0x64E8, (q15_t)0x4EBF, (q15_t)0x64AA, (q15_t)0x4F0F, + (q15_t)0x646C, (q15_t)0x4F5E, (q15_t)0x642D, (q15_t)0x4FAC, + (q15_t)0x63EF, (q15_t)0x4FFB, (q15_t)0x63B0, (q15_t)0x5049, + (q15_t)0x6371, (q15_t)0x5097, (q15_t)0x6331, (q15_t)0x50E5, + (q15_t)0x62F2, (q15_t)0x5133, (q15_t)0x62B2, (q15_t)0x5181, + (q15_t)0x6271, (q15_t)0x51CE, (q15_t)0x6231, (q15_t)0x521C, + (q15_t)0x61F1, (q15_t)0x5269, (q15_t)0x61B0, (q15_t)0x52B5, + (q15_t)0x616F, (q15_t)0x5302, (q15_t)0x612D, (q15_t)0x534E, + (q15_t)0x60EC, (q15_t)0x539B, (q15_t)0x60AA, (q15_t)0x53E7, + (q15_t)0x6068, (q15_t)0x5433, (q15_t)0x6026, (q15_t)0x547E, + (q15_t)0x5FE3, (q15_t)0x54CA, (q15_t)0x5FA0, (q15_t)0x5515, + (q15_t)0x5F5E, (q15_t)0x5560, (q15_t)0x5F1A, (q15_t)0x55AB, + (q15_t)0x5ED7, (q15_t)0x55F5, (q15_t)0x5E93, (q15_t)0x5640, + (q15_t)0x5E50, (q15_t)0x568A, (q15_t)0x5E0B, (q15_t)0x56D4, + (q15_t)0x5DC7, (q15_t)0x571D, (q15_t)0x5D83, (q15_t)0x5767, + (q15_t)0x5D3E, (q15_t)0x57B0, (q15_t)0x5CF9, (q15_t)0x57F9, + (q15_t)0x5CB4, (q15_t)0x5842, (q15_t)0x5C6E, (q15_t)0x588B, + (q15_t)0x5C29, (q15_t)0x58D4, (q15_t)0x5BE3, (q15_t)0x591C, + (q15_t)0x5B9D, (q15_t)0x5964, (q15_t)0x5B56, (q15_t)0x59AC, + (q15_t)0x5B10, (q15_t)0x59F3, (q15_t)0x5AC9, (q15_t)0x5A3B, + (q15_t)0x5A82, (q15_t)0x5A82, (q15_t)0x5A3B, (q15_t)0x5AC9, + (q15_t)0x59F3, (q15_t)0x5B10, (q15_t)0x59AC, (q15_t)0x5B56, + (q15_t)0x5964, (q15_t)0x5B9D, (q15_t)0x591C, (q15_t)0x5BE3, + (q15_t)0x58D4, (q15_t)0x5C29, (q15_t)0x588B, (q15_t)0x5C6E, + (q15_t)0x5842, (q15_t)0x5CB4, (q15_t)0x57F9, (q15_t)0x5CF9, + (q15_t)0x57B0, (q15_t)0x5D3E, (q15_t)0x5767, (q15_t)0x5D83, + (q15_t)0x571D, (q15_t)0x5DC7, (q15_t)0x56D4, (q15_t)0x5E0B, + (q15_t)0x568A, (q15_t)0x5E50, (q15_t)0x5640, (q15_t)0x5E93, + (q15_t)0x55F5, (q15_t)0x5ED7, (q15_t)0x55AB, (q15_t)0x5F1A, + (q15_t)0x5560, (q15_t)0x5F5E, (q15_t)0x5515, (q15_t)0x5FA0, + (q15_t)0x54CA, (q15_t)0x5FE3, (q15_t)0x547E, (q15_t)0x6026, + (q15_t)0x5433, (q15_t)0x6068, (q15_t)0x53E7, (q15_t)0x60AA, + (q15_t)0x539B, (q15_t)0x60EC, (q15_t)0x534E, (q15_t)0x612D, + (q15_t)0x5302, (q15_t)0x616F, (q15_t)0x52B5, (q15_t)0x61B0, + (q15_t)0x5269, (q15_t)0x61F1, (q15_t)0x521C, (q15_t)0x6231, + (q15_t)0x51CE, (q15_t)0x6271, (q15_t)0x5181, (q15_t)0x62B2, + (q15_t)0x5133, (q15_t)0x62F2, (q15_t)0x50E5, (q15_t)0x6331, + (q15_t)0x5097, (q15_t)0x6371, (q15_t)0x5049, (q15_t)0x63B0, + (q15_t)0x4FFB, (q15_t)0x63EF, (q15_t)0x4FAC, (q15_t)0x642D, + (q15_t)0x4F5E, (q15_t)0x646C, (q15_t)0x4F0F, (q15_t)0x64AA, + (q15_t)0x4EBF, (q15_t)0x64E8, (q15_t)0x4E70, (q15_t)0x6526, + (q15_t)0x4E21, (q15_t)0x6563, (q15_t)0x4DD1, (q15_t)0x65A0, + (q15_t)0x4D81, (q15_t)0x65DD, (q15_t)0x4D31, (q15_t)0x661A, + (q15_t)0x4CE1, (q15_t)0x6657, (q15_t)0x4C90, (q15_t)0x6693, + (q15_t)0x4C3F, (q15_t)0x66CF, (q15_t)0x4BEF, (q15_t)0x670B, + (q15_t)0x4B9E, (q15_t)0x6746, (q15_t)0x4B4C, (q15_t)0x6782, + (q15_t)0x4AFB, (q15_t)0x67BD, (q15_t)0x4AA9, (q15_t)0x67F7, + (q15_t)0x4A58, (q15_t)0x6832, (q15_t)0x4A06, (q15_t)0x686C, + (q15_t)0x49B4, (q15_t)0x68A6, (q15_t)0x4961, (q15_t)0x68E0, + (q15_t)0x490F, (q15_t)0x6919, (q15_t)0x48BC, (q15_t)0x6953, + (q15_t)0x4869, (q15_t)0x698C, (q15_t)0x4816, (q15_t)0x69C4, + (q15_t)0x47C3, (q15_t)0x69FD, (q15_t)0x4770, (q15_t)0x6A35, + (q15_t)0x471C, (q15_t)0x6A6D, (q15_t)0x46C9, (q15_t)0x6AA5, + (q15_t)0x4675, (q15_t)0x6ADC, (q15_t)0x4621, (q15_t)0x6B13, + (q15_t)0x45CD, (q15_t)0x6B4A, (q15_t)0x4578, (q15_t)0x6B81, + (q15_t)0x4524, (q15_t)0x6BB8, (q15_t)0x44CF, (q15_t)0x6BEE, + (q15_t)0x447A, (q15_t)0x6C24, (q15_t)0x4425, (q15_t)0x6C59, + (q15_t)0x43D0, (q15_t)0x6C8F, (q15_t)0x437B, (q15_t)0x6CC4, + (q15_t)0x4325, (q15_t)0x6CF9, (q15_t)0x42D0, (q15_t)0x6D2D, + (q15_t)0x427A, (q15_t)0x6D62, (q15_t)0x4224, (q15_t)0x6D96, + (q15_t)0x41CE, (q15_t)0x6DCA, (q15_t)0x4177, (q15_t)0x6DFD, + (q15_t)0x4121, (q15_t)0x6E30, (q15_t)0x40CA, (q15_t)0x6E63, + (q15_t)0x4073, (q15_t)0x6E96, (q15_t)0x401D, (q15_t)0x6EC9, + (q15_t)0x3FC5, (q15_t)0x6EFB, (q15_t)0x3F6E, (q15_t)0x6F2D, + (q15_t)0x3F17, (q15_t)0x6F5F, (q15_t)0x3EBF, (q15_t)0x6F90, + (q15_t)0x3E68, (q15_t)0x6FC1, (q15_t)0x3E10, (q15_t)0x6FF2, + (q15_t)0x3DB8, (q15_t)0x7023, (q15_t)0x3D60, (q15_t)0x7053, + (q15_t)0x3D07, (q15_t)0x7083, (q15_t)0x3CAF, (q15_t)0x70B3, + (q15_t)0x3C56, (q15_t)0x70E2, (q15_t)0x3BFD, (q15_t)0x7112, + (q15_t)0x3BA5, (q15_t)0x7141, (q15_t)0x3B4C, (q15_t)0x716F, + (q15_t)0x3AF2, (q15_t)0x719E, (q15_t)0x3A99, (q15_t)0x71CC, + (q15_t)0x3A40, (q15_t)0x71FA, (q15_t)0x39E6, (q15_t)0x7227, + (q15_t)0x398C, (q15_t)0x7255, (q15_t)0x3932, (q15_t)0x7282, + (q15_t)0x38D8, (q15_t)0x72AF, (q15_t)0x387E, (q15_t)0x72DB, + (q15_t)0x3824, (q15_t)0x7307, (q15_t)0x37CA, (q15_t)0x7333, + (q15_t)0x376F, (q15_t)0x735F, (q15_t)0x3714, (q15_t)0x738A, + (q15_t)0x36BA, (q15_t)0x73B5, (q15_t)0x365F, (q15_t)0x73E0, + (q15_t)0x3604, (q15_t)0x740B, (q15_t)0x35A8, (q15_t)0x7435, + (q15_t)0x354D, (q15_t)0x745F, (q15_t)0x34F2, (q15_t)0x7489, + (q15_t)0x3496, (q15_t)0x74B2, (q15_t)0x343A, (q15_t)0x74DB, + (q15_t)0x33DE, (q15_t)0x7504, (q15_t)0x3382, (q15_t)0x752D, + (q15_t)0x3326, (q15_t)0x7555, (q15_t)0x32CA, (q15_t)0x757D, + (q15_t)0x326E, (q15_t)0x75A5, (q15_t)0x3211, (q15_t)0x75CC, + (q15_t)0x31B5, (q15_t)0x75F4, (q15_t)0x3158, (q15_t)0x761B, + (q15_t)0x30FB, (q15_t)0x7641, (q15_t)0x309E, (q15_t)0x7668, + (q15_t)0x3041, (q15_t)0x768E, (q15_t)0x2FE4, (q15_t)0x76B3, + (q15_t)0x2F87, (q15_t)0x76D9, (q15_t)0x2F29, (q15_t)0x76FE, + (q15_t)0x2ECC, (q15_t)0x7723, (q15_t)0x2E6E, (q15_t)0x7747, + (q15_t)0x2E11, (q15_t)0x776C, (q15_t)0x2DB3, (q15_t)0x7790, + (q15_t)0x2D55, (q15_t)0x77B4, (q15_t)0x2CF7, (q15_t)0x77D7, + (q15_t)0x2C98, (q15_t)0x77FA, (q15_t)0x2C3A, (q15_t)0x781D, + (q15_t)0x2BDC, (q15_t)0x7840, (q15_t)0x2B7D, (q15_t)0x7862, + (q15_t)0x2B1F, (q15_t)0x7884, (q15_t)0x2AC0, (q15_t)0x78A6, + (q15_t)0x2A61, (q15_t)0x78C7, (q15_t)0x2A02, (q15_t)0x78E8, + (q15_t)0x29A3, (q15_t)0x7909, (q15_t)0x2944, (q15_t)0x792A, + (q15_t)0x28E5, (q15_t)0x794A, (q15_t)0x2886, (q15_t)0x796A, + (q15_t)0x2826, (q15_t)0x798A, (q15_t)0x27C7, (q15_t)0x79A9, + (q15_t)0x2767, (q15_t)0x79C8, (q15_t)0x2707, (q15_t)0x79E7, + (q15_t)0x26A8, (q15_t)0x7A05, (q15_t)0x2648, (q15_t)0x7A24, + (q15_t)0x25E8, (q15_t)0x7A42, (q15_t)0x2588, (q15_t)0x7A5F, + (q15_t)0x2528, (q15_t)0x7A7D, (q15_t)0x24C7, (q15_t)0x7A9A, + (q15_t)0x2467, (q15_t)0x7AB6, (q15_t)0x2407, (q15_t)0x7AD3, + (q15_t)0x23A6, (q15_t)0x7AEF, (q15_t)0x2345, (q15_t)0x7B0B, + (q15_t)0x22E5, (q15_t)0x7B26, (q15_t)0x2284, (q15_t)0x7B42, + (q15_t)0x2223, (q15_t)0x7B5D, (q15_t)0x21C2, (q15_t)0x7B77, + (q15_t)0x2161, (q15_t)0x7B92, (q15_t)0x2100, (q15_t)0x7BAC, + (q15_t)0x209F, (q15_t)0x7BC5, (q15_t)0x203E, (q15_t)0x7BDF, + (q15_t)0x1FDC, (q15_t)0x7BF8, (q15_t)0x1F7B, (q15_t)0x7C11, + (q15_t)0x1F19, (q15_t)0x7C29, (q15_t)0x1EB8, (q15_t)0x7C42, + (q15_t)0x1E56, (q15_t)0x7C5A, (q15_t)0x1DF5, (q15_t)0x7C71, + (q15_t)0x1D93, (q15_t)0x7C89, (q15_t)0x1D31, (q15_t)0x7CA0, + (q15_t)0x1CCF, (q15_t)0x7CB7, (q15_t)0x1C6D, (q15_t)0x7CCD, + (q15_t)0x1C0B, (q15_t)0x7CE3, (q15_t)0x1BA9, (q15_t)0x7CF9, + (q15_t)0x1B47, (q15_t)0x7D0F, (q15_t)0x1AE4, (q15_t)0x7D24, + (q15_t)0x1A82, (q15_t)0x7D39, (q15_t)0x1A20, (q15_t)0x7D4E, + (q15_t)0x19BD, (q15_t)0x7D62, (q15_t)0x195B, (q15_t)0x7D76, + (q15_t)0x18F8, (q15_t)0x7D8A, (q15_t)0x1896, (q15_t)0x7D9D, + (q15_t)0x1833, (q15_t)0x7DB0, (q15_t)0x17D0, (q15_t)0x7DC3, + (q15_t)0x176D, (q15_t)0x7DD6, (q15_t)0x170A, (q15_t)0x7DE8, + (q15_t)0x16A8, (q15_t)0x7DFA, (q15_t)0x1645, (q15_t)0x7E0C, + (q15_t)0x15E2, (q15_t)0x7E1D, (q15_t)0x157F, (q15_t)0x7E2E, + (q15_t)0x151B, (q15_t)0x7E3F, (q15_t)0x14B8, (q15_t)0x7E4F, + (q15_t)0x1455, (q15_t)0x7E5F, (q15_t)0x13F2, (q15_t)0x7E6F, + (q15_t)0x138E, (q15_t)0x7E7F, (q15_t)0x132B, (q15_t)0x7E8E, + (q15_t)0x12C8, (q15_t)0x7E9D, (q15_t)0x1264, (q15_t)0x7EAB, + (q15_t)0x1201, (q15_t)0x7EBA, (q15_t)0x119D, (q15_t)0x7EC8, + (q15_t)0x1139, (q15_t)0x7ED5, (q15_t)0x10D6, (q15_t)0x7EE3, + (q15_t)0x1072, (q15_t)0x7EF0, (q15_t)0x100E, (q15_t)0x7EFD, + (q15_t)0x0FAB, (q15_t)0x7F09, (q15_t)0x0F47, (q15_t)0x7F15, + (q15_t)0x0EE3, (q15_t)0x7F21, (q15_t)0x0E7F, (q15_t)0x7F2D, + (q15_t)0x0E1B, (q15_t)0x7F38, (q15_t)0x0DB7, (q15_t)0x7F43, + (q15_t)0x0D53, (q15_t)0x7F4D, (q15_t)0x0CEF, (q15_t)0x7F58, + (q15_t)0x0C8B, (q15_t)0x7F62, (q15_t)0x0C27, (q15_t)0x7F6B, + (q15_t)0x0BC3, (q15_t)0x7F75, (q15_t)0x0B5F, (q15_t)0x7F7E, + (q15_t)0x0AFB, (q15_t)0x7F87, (q15_t)0x0A97, (q15_t)0x7F8F, + (q15_t)0x0A33, (q15_t)0x7F97, (q15_t)0x09CE, (q15_t)0x7F9F, + (q15_t)0x096A, (q15_t)0x7FA7, (q15_t)0x0906, (q15_t)0x7FAE, + (q15_t)0x08A2, (q15_t)0x7FB5, (q15_t)0x083D, (q15_t)0x7FBC, + (q15_t)0x07D9, (q15_t)0x7FC2, (q15_t)0x0775, (q15_t)0x7FC8, + (q15_t)0x0710, (q15_t)0x7FCE, (q15_t)0x06AC, (q15_t)0x7FD3, + (q15_t)0x0647, (q15_t)0x7FD8, (q15_t)0x05E3, (q15_t)0x7FDD, + (q15_t)0x057F, (q15_t)0x7FE1, (q15_t)0x051A, (q15_t)0x7FE5, + (q15_t)0x04B6, (q15_t)0x7FE9, (q15_t)0x0451, (q15_t)0x7FED, + (q15_t)0x03ED, (q15_t)0x7FF0, (q15_t)0x0388, (q15_t)0x7FF3, + (q15_t)0x0324, (q15_t)0x7FF6, (q15_t)0x02BF, (q15_t)0x7FF8, + (q15_t)0x025B, (q15_t)0x7FFA, (q15_t)0x01F6, (q15_t)0x7FFC, + (q15_t)0x0192, (q15_t)0x7FFD, (q15_t)0x012D, (q15_t)0x7FFE, + (q15_t)0x00C9, (q15_t)0x7FFF, (q15_t)0x0064, (q15_t)0x7FFF, + (q15_t)0x0000, (q15_t)0x7FFF, (q15_t)0xFF9B, (q15_t)0x7FFF, + (q15_t)0xFF36, (q15_t)0x7FFF, (q15_t)0xFED2, (q15_t)0x7FFE, + (q15_t)0xFE6D, (q15_t)0x7FFD, (q15_t)0xFE09, (q15_t)0x7FFC, + (q15_t)0xFDA4, (q15_t)0x7FFA, (q15_t)0xFD40, (q15_t)0x7FF8, + (q15_t)0xFCDB, (q15_t)0x7FF6, (q15_t)0xFC77, (q15_t)0x7FF3, + (q15_t)0xFC12, (q15_t)0x7FF0, (q15_t)0xFBAE, (q15_t)0x7FED, + (q15_t)0xFB49, (q15_t)0x7FE9, (q15_t)0xFAE5, (q15_t)0x7FE5, + (q15_t)0xFA80, (q15_t)0x7FE1, (q15_t)0xFA1C, (q15_t)0x7FDD, + (q15_t)0xF9B8, (q15_t)0x7FD8, (q15_t)0xF953, (q15_t)0x7FD3, + (q15_t)0xF8EF, (q15_t)0x7FCE, (q15_t)0xF88A, (q15_t)0x7FC8, + (q15_t)0xF826, (q15_t)0x7FC2, (q15_t)0xF7C2, (q15_t)0x7FBC, + (q15_t)0xF75D, (q15_t)0x7FB5, (q15_t)0xF6F9, (q15_t)0x7FAE, + (q15_t)0xF695, (q15_t)0x7FA7, (q15_t)0xF631, (q15_t)0x7F9F, + (q15_t)0xF5CC, (q15_t)0x7F97, (q15_t)0xF568, (q15_t)0x7F8F, + (q15_t)0xF504, (q15_t)0x7F87, (q15_t)0xF4A0, (q15_t)0x7F7E, + (q15_t)0xF43C, (q15_t)0x7F75, (q15_t)0xF3D8, (q15_t)0x7F6B, + (q15_t)0xF374, (q15_t)0x7F62, (q15_t)0xF310, (q15_t)0x7F58, + (q15_t)0xF2AC, (q15_t)0x7F4D, (q15_t)0xF248, (q15_t)0x7F43, + (q15_t)0xF1E4, (q15_t)0x7F38, (q15_t)0xF180, (q15_t)0x7F2D, + (q15_t)0xF11C, (q15_t)0x7F21, (q15_t)0xF0B8, (q15_t)0x7F15, + (q15_t)0xF054, (q15_t)0x7F09, (q15_t)0xEFF1, (q15_t)0x7EFD, + (q15_t)0xEF8D, (q15_t)0x7EF0, (q15_t)0xEF29, (q15_t)0x7EE3, + (q15_t)0xEEC6, (q15_t)0x7ED5, (q15_t)0xEE62, (q15_t)0x7EC8, + (q15_t)0xEDFE, (q15_t)0x7EBA, (q15_t)0xED9B, (q15_t)0x7EAB, + (q15_t)0xED37, (q15_t)0x7E9D, (q15_t)0xECD4, (q15_t)0x7E8E, + (q15_t)0xEC71, (q15_t)0x7E7F, (q15_t)0xEC0D, (q15_t)0x7E6F, + (q15_t)0xEBAA, (q15_t)0x7E5F, (q15_t)0xEB47, (q15_t)0x7E4F, + (q15_t)0xEAE4, (q15_t)0x7E3F, (q15_t)0xEA80, (q15_t)0x7E2E, + (q15_t)0xEA1D, (q15_t)0x7E1D, (q15_t)0xE9BA, (q15_t)0x7E0C, + (q15_t)0xE957, (q15_t)0x7DFA, (q15_t)0xE8F5, (q15_t)0x7DE8, + (q15_t)0xE892, (q15_t)0x7DD6, (q15_t)0xE82F, (q15_t)0x7DC3, + (q15_t)0xE7CC, (q15_t)0x7DB0, (q15_t)0xE769, (q15_t)0x7D9D, + (q15_t)0xE707, (q15_t)0x7D8A, (q15_t)0xE6A4, (q15_t)0x7D76, + (q15_t)0xE642, (q15_t)0x7D62, (q15_t)0xE5DF, (q15_t)0x7D4E, + (q15_t)0xE57D, (q15_t)0x7D39, (q15_t)0xE51B, (q15_t)0x7D24, + (q15_t)0xE4B8, (q15_t)0x7D0F, (q15_t)0xE456, (q15_t)0x7CF9, + (q15_t)0xE3F4, (q15_t)0x7CE3, (q15_t)0xE392, (q15_t)0x7CCD, + (q15_t)0xE330, (q15_t)0x7CB7, (q15_t)0xE2CE, (q15_t)0x7CA0, + (q15_t)0xE26C, (q15_t)0x7C89, (q15_t)0xE20A, (q15_t)0x7C71, + (q15_t)0xE1A9, (q15_t)0x7C5A, (q15_t)0xE147, (q15_t)0x7C42, + (q15_t)0xE0E6, (q15_t)0x7C29, (q15_t)0xE084, (q15_t)0x7C11, + (q15_t)0xE023, (q15_t)0x7BF8, (q15_t)0xDFC1, (q15_t)0x7BDF, + (q15_t)0xDF60, (q15_t)0x7BC5, (q15_t)0xDEFF, (q15_t)0x7BAC, + (q15_t)0xDE9E, (q15_t)0x7B92, (q15_t)0xDE3D, (q15_t)0x7B77, + (q15_t)0xDDDC, (q15_t)0x7B5D, (q15_t)0xDD7B, (q15_t)0x7B42, + (q15_t)0xDD1A, (q15_t)0x7B26, (q15_t)0xDCBA, (q15_t)0x7B0B, + (q15_t)0xDC59, (q15_t)0x7AEF, (q15_t)0xDBF8, (q15_t)0x7AD3, + (q15_t)0xDB98, (q15_t)0x7AB6, (q15_t)0xDB38, (q15_t)0x7A9A, + (q15_t)0xDAD7, (q15_t)0x7A7D, (q15_t)0xDA77, (q15_t)0x7A5F, + (q15_t)0xDA17, (q15_t)0x7A42, (q15_t)0xD9B7, (q15_t)0x7A24, + (q15_t)0xD957, (q15_t)0x7A05, (q15_t)0xD8F8, (q15_t)0x79E7, + (q15_t)0xD898, (q15_t)0x79C8, (q15_t)0xD838, (q15_t)0x79A9, + (q15_t)0xD7D9, (q15_t)0x798A, (q15_t)0xD779, (q15_t)0x796A, + (q15_t)0xD71A, (q15_t)0x794A, (q15_t)0xD6BB, (q15_t)0x792A, + (q15_t)0xD65C, (q15_t)0x7909, (q15_t)0xD5FD, (q15_t)0x78E8, + (q15_t)0xD59E, (q15_t)0x78C7, (q15_t)0xD53F, (q15_t)0x78A6, + (q15_t)0xD4E0, (q15_t)0x7884, (q15_t)0xD482, (q15_t)0x7862, + (q15_t)0xD423, (q15_t)0x7840, (q15_t)0xD3C5, (q15_t)0x781D, + (q15_t)0xD367, (q15_t)0x77FA, (q15_t)0xD308, (q15_t)0x77D7, + (q15_t)0xD2AA, (q15_t)0x77B4, (q15_t)0xD24C, (q15_t)0x7790, + (q15_t)0xD1EE, (q15_t)0x776C, (q15_t)0xD191, (q15_t)0x7747, + (q15_t)0xD133, (q15_t)0x7723, (q15_t)0xD0D6, (q15_t)0x76FE, + (q15_t)0xD078, (q15_t)0x76D9, (q15_t)0xD01B, (q15_t)0x76B3, + (q15_t)0xCFBE, (q15_t)0x768E, (q15_t)0xCF61, (q15_t)0x7668, + (q15_t)0xCF04, (q15_t)0x7641, (q15_t)0xCEA7, (q15_t)0x761B, + (q15_t)0xCE4A, (q15_t)0x75F4, (q15_t)0xCDEE, (q15_t)0x75CC, + (q15_t)0xCD91, (q15_t)0x75A5, (q15_t)0xCD35, (q15_t)0x757D, + (q15_t)0xCCD9, (q15_t)0x7555, (q15_t)0xCC7D, (q15_t)0x752D, + (q15_t)0xCC21, (q15_t)0x7504, (q15_t)0xCBC5, (q15_t)0x74DB, + (q15_t)0xCB69, (q15_t)0x74B2, (q15_t)0xCB0D, (q15_t)0x7489, + (q15_t)0xCAB2, (q15_t)0x745F, (q15_t)0xCA57, (q15_t)0x7435, + (q15_t)0xC9FB, (q15_t)0x740B, (q15_t)0xC9A0, (q15_t)0x73E0, + (q15_t)0xC945, (q15_t)0x73B5, (q15_t)0xC8EB, (q15_t)0x738A, + (q15_t)0xC890, (q15_t)0x735F, (q15_t)0xC835, (q15_t)0x7333, + (q15_t)0xC7DB, (q15_t)0x7307, (q15_t)0xC781, (q15_t)0x72DB, + (q15_t)0xC727, (q15_t)0x72AF, (q15_t)0xC6CD, (q15_t)0x7282, + (q15_t)0xC673, (q15_t)0x7255, (q15_t)0xC619, (q15_t)0x7227, + (q15_t)0xC5BF, (q15_t)0x71FA, (q15_t)0xC566, (q15_t)0x71CC, + (q15_t)0xC50D, (q15_t)0x719E, (q15_t)0xC4B3, (q15_t)0x716F, + (q15_t)0xC45A, (q15_t)0x7141, (q15_t)0xC402, (q15_t)0x7112, + (q15_t)0xC3A9, (q15_t)0x70E2, (q15_t)0xC350, (q15_t)0x70B3, + (q15_t)0xC2F8, (q15_t)0x7083, (q15_t)0xC29F, (q15_t)0x7053, + (q15_t)0xC247, (q15_t)0x7023, (q15_t)0xC1EF, (q15_t)0x6FF2, + (q15_t)0xC197, (q15_t)0x6FC1, (q15_t)0xC140, (q15_t)0x6F90, + (q15_t)0xC0E8, (q15_t)0x6F5F, (q15_t)0xC091, (q15_t)0x6F2D, + (q15_t)0xC03A, (q15_t)0x6EFB, (q15_t)0xBFE2, (q15_t)0x6EC9, + (q15_t)0xBF8C, (q15_t)0x6E96, (q15_t)0xBF35, (q15_t)0x6E63, + (q15_t)0xBEDE, (q15_t)0x6E30, (q15_t)0xBE88, (q15_t)0x6DFD, + (q15_t)0xBE31, (q15_t)0x6DCA, (q15_t)0xBDDB, (q15_t)0x6D96, + (q15_t)0xBD85, (q15_t)0x6D62, (q15_t)0xBD2F, (q15_t)0x6D2D, + (q15_t)0xBCDA, (q15_t)0x6CF9, (q15_t)0xBC84, (q15_t)0x6CC4, + (q15_t)0xBC2F, (q15_t)0x6C8F, (q15_t)0xBBDA, (q15_t)0x6C59, + (q15_t)0xBB85, (q15_t)0x6C24, (q15_t)0xBB30, (q15_t)0x6BEE, + (q15_t)0xBADB, (q15_t)0x6BB8, (q15_t)0xBA87, (q15_t)0x6B81, + (q15_t)0xBA32, (q15_t)0x6B4A, (q15_t)0xB9DE, (q15_t)0x6B13, + (q15_t)0xB98A, (q15_t)0x6ADC, (q15_t)0xB936, (q15_t)0x6AA5, + (q15_t)0xB8E3, (q15_t)0x6A6D, (q15_t)0xB88F, (q15_t)0x6A35, + (q15_t)0xB83C, (q15_t)0x69FD, (q15_t)0xB7E9, (q15_t)0x69C4, + (q15_t)0xB796, (q15_t)0x698C, (q15_t)0xB743, (q15_t)0x6953, + (q15_t)0xB6F0, (q15_t)0x6919, (q15_t)0xB69E, (q15_t)0x68E0, + (q15_t)0xB64B, (q15_t)0x68A6, (q15_t)0xB5F9, (q15_t)0x686C, + (q15_t)0xB5A7, (q15_t)0x6832, (q15_t)0xB556, (q15_t)0x67F7, + (q15_t)0xB504, (q15_t)0x67BD, (q15_t)0xB4B3, (q15_t)0x6782, + (q15_t)0xB461, (q15_t)0x6746, (q15_t)0xB410, (q15_t)0x670B, + (q15_t)0xB3C0, (q15_t)0x66CF, (q15_t)0xB36F, (q15_t)0x6693, + (q15_t)0xB31E, (q15_t)0x6657, (q15_t)0xB2CE, (q15_t)0x661A, + (q15_t)0xB27E, (q15_t)0x65DD, (q15_t)0xB22E, (q15_t)0x65A0, + (q15_t)0xB1DE, (q15_t)0x6563, (q15_t)0xB18F, (q15_t)0x6526, + (q15_t)0xB140, (q15_t)0x64E8, (q15_t)0xB0F0, (q15_t)0x64AA, + (q15_t)0xB0A1, (q15_t)0x646C, (q15_t)0xB053, (q15_t)0x642D, + (q15_t)0xB004, (q15_t)0x63EF, (q15_t)0xAFB6, (q15_t)0x63B0, + (q15_t)0xAF68, (q15_t)0x6371, (q15_t)0xAF1A, (q15_t)0x6331, + (q15_t)0xAECC, (q15_t)0x62F2, (q15_t)0xAE7E, (q15_t)0x62B2, + (q15_t)0xAE31, (q15_t)0x6271, (q15_t)0xADE3, (q15_t)0x6231, + (q15_t)0xAD96, (q15_t)0x61F1, (q15_t)0xAD4A, (q15_t)0x61B0, + (q15_t)0xACFD, (q15_t)0x616F, (q15_t)0xACB1, (q15_t)0x612D, + (q15_t)0xAC64, (q15_t)0x60EC, (q15_t)0xAC18, (q15_t)0x60AA, + (q15_t)0xABCC, (q15_t)0x6068, (q15_t)0xAB81, (q15_t)0x6026, + (q15_t)0xAB35, (q15_t)0x5FE3, (q15_t)0xAAEA, (q15_t)0x5FA0, + (q15_t)0xAA9F, (q15_t)0x5F5E, (q15_t)0xAA54, (q15_t)0x5F1A, + (q15_t)0xAA0A, (q15_t)0x5ED7, (q15_t)0xA9BF, (q15_t)0x5E93, + (q15_t)0xA975, (q15_t)0x5E50, (q15_t)0xA92B, (q15_t)0x5E0B, + (q15_t)0xA8E2, (q15_t)0x5DC7, (q15_t)0xA898, (q15_t)0x5D83, + (q15_t)0xA84F, (q15_t)0x5D3E, (q15_t)0xA806, (q15_t)0x5CF9, + (q15_t)0xA7BD, (q15_t)0x5CB4, (q15_t)0xA774, (q15_t)0x5C6E, + (q15_t)0xA72B, (q15_t)0x5C29, (q15_t)0xA6E3, (q15_t)0x5BE3, + (q15_t)0xA69B, (q15_t)0x5B9D, (q15_t)0xA653, (q15_t)0x5B56, + (q15_t)0xA60C, (q15_t)0x5B10, (q15_t)0xA5C4, (q15_t)0x5AC9, + (q15_t)0xA57D, (q15_t)0x5A82, (q15_t)0xA536, (q15_t)0x5A3B, + (q15_t)0xA4EF, (q15_t)0x59F3, (q15_t)0xA4A9, (q15_t)0x59AC, + (q15_t)0xA462, (q15_t)0x5964, (q15_t)0xA41C, (q15_t)0x591C, + (q15_t)0xA3D6, (q15_t)0x58D4, (q15_t)0xA391, (q15_t)0x588B, + (q15_t)0xA34B, (q15_t)0x5842, (q15_t)0xA306, (q15_t)0x57F9, + (q15_t)0xA2C1, (q15_t)0x57B0, (q15_t)0xA27C, (q15_t)0x5767, + (q15_t)0xA238, (q15_t)0x571D, (q15_t)0xA1F4, (q15_t)0x56D4, + (q15_t)0xA1AF, (q15_t)0x568A, (q15_t)0xA16C, (q15_t)0x5640, + (q15_t)0xA128, (q15_t)0x55F5, (q15_t)0xA0E5, (q15_t)0x55AB, + (q15_t)0xA0A1, (q15_t)0x5560, (q15_t)0xA05F, (q15_t)0x5515, + (q15_t)0xA01C, (q15_t)0x54CA, (q15_t)0x9FD9, (q15_t)0x547E, + (q15_t)0x9F97, (q15_t)0x5433, (q15_t)0x9F55, (q15_t)0x53E7, + (q15_t)0x9F13, (q15_t)0x539B, (q15_t)0x9ED2, (q15_t)0x534E, + (q15_t)0x9E90, (q15_t)0x5302, (q15_t)0x9E4F, (q15_t)0x52B5, + (q15_t)0x9E0E, (q15_t)0x5269, (q15_t)0x9DCE, (q15_t)0x521C, + (q15_t)0x9D8E, (q15_t)0x51CE, (q15_t)0x9D4D, (q15_t)0x5181, + (q15_t)0x9D0D, (q15_t)0x5133, (q15_t)0x9CCE, (q15_t)0x50E5, + (q15_t)0x9C8E, (q15_t)0x5097, (q15_t)0x9C4F, (q15_t)0x5049, + (q15_t)0x9C10, (q15_t)0x4FFB, (q15_t)0x9BD2, (q15_t)0x4FAC, + (q15_t)0x9B93, (q15_t)0x4F5E, (q15_t)0x9B55, (q15_t)0x4F0F, + (q15_t)0x9B17, (q15_t)0x4EBF, (q15_t)0x9AD9, (q15_t)0x4E70, + (q15_t)0x9A9C, (q15_t)0x4E21, (q15_t)0x9A5F, (q15_t)0x4DD1, + (q15_t)0x9A22, (q15_t)0x4D81, (q15_t)0x99E5, (q15_t)0x4D31, + (q15_t)0x99A8, (q15_t)0x4CE1, (q15_t)0x996C, (q15_t)0x4C90, + (q15_t)0x9930, (q15_t)0x4C3F, (q15_t)0x98F4, (q15_t)0x4BEF, + (q15_t)0x98B9, (q15_t)0x4B9E, (q15_t)0x987D, (q15_t)0x4B4C, + (q15_t)0x9842, (q15_t)0x4AFB, (q15_t)0x9808, (q15_t)0x4AA9, + (q15_t)0x97CD, (q15_t)0x4A58, (q15_t)0x9793, (q15_t)0x4A06, + (q15_t)0x9759, (q15_t)0x49B4, (q15_t)0x971F, (q15_t)0x4961, + (q15_t)0x96E6, (q15_t)0x490F, (q15_t)0x96AC, (q15_t)0x48BC, + (q15_t)0x9673, (q15_t)0x4869, (q15_t)0x963B, (q15_t)0x4816, + (q15_t)0x9602, (q15_t)0x47C3, (q15_t)0x95CA, (q15_t)0x4770, + (q15_t)0x9592, (q15_t)0x471C, (q15_t)0x955A, (q15_t)0x46C9, + (q15_t)0x9523, (q15_t)0x4675, (q15_t)0x94EC, (q15_t)0x4621, + (q15_t)0x94B5, (q15_t)0x45CD, (q15_t)0x947E, (q15_t)0x4578, + (q15_t)0x9447, (q15_t)0x4524, (q15_t)0x9411, (q15_t)0x44CF, + (q15_t)0x93DB, (q15_t)0x447A, (q15_t)0x93A6, (q15_t)0x4425, + (q15_t)0x9370, (q15_t)0x43D0, (q15_t)0x933B, (q15_t)0x437B, + (q15_t)0x9306, (q15_t)0x4325, (q15_t)0x92D2, (q15_t)0x42D0, + (q15_t)0x929D, (q15_t)0x427A, (q15_t)0x9269, (q15_t)0x4224, + (q15_t)0x9235, (q15_t)0x41CE, (q15_t)0x9202, (q15_t)0x4177, + (q15_t)0x91CF, (q15_t)0x4121, (q15_t)0x919C, (q15_t)0x40CA, + (q15_t)0x9169, (q15_t)0x4073, (q15_t)0x9136, (q15_t)0x401D, + (q15_t)0x9104, (q15_t)0x3FC5, (q15_t)0x90D2, (q15_t)0x3F6E, + (q15_t)0x90A0, (q15_t)0x3F17, (q15_t)0x906F, (q15_t)0x3EBF, + (q15_t)0x903E, (q15_t)0x3E68, (q15_t)0x900D, (q15_t)0x3E10, + (q15_t)0x8FDC, (q15_t)0x3DB8, (q15_t)0x8FAC, (q15_t)0x3D60, + (q15_t)0x8F7C, (q15_t)0x3D07, (q15_t)0x8F4C, (q15_t)0x3CAF, + (q15_t)0x8F1D, (q15_t)0x3C56, (q15_t)0x8EED, (q15_t)0x3BFD, + (q15_t)0x8EBE, (q15_t)0x3BA5, (q15_t)0x8E90, (q15_t)0x3B4C, + (q15_t)0x8E61, (q15_t)0x3AF2, (q15_t)0x8E33, (q15_t)0x3A99, + (q15_t)0x8E05, (q15_t)0x3A40, (q15_t)0x8DD8, (q15_t)0x39E6, + (q15_t)0x8DAA, (q15_t)0x398C, (q15_t)0x8D7D, (q15_t)0x3932, + (q15_t)0x8D50, (q15_t)0x38D8, (q15_t)0x8D24, (q15_t)0x387E, + (q15_t)0x8CF8, (q15_t)0x3824, (q15_t)0x8CCC, (q15_t)0x37CA, + (q15_t)0x8CA0, (q15_t)0x376F, (q15_t)0x8C75, (q15_t)0x3714, + (q15_t)0x8C4A, (q15_t)0x36BA, (q15_t)0x8C1F, (q15_t)0x365F, + (q15_t)0x8BF4, (q15_t)0x3604, (q15_t)0x8BCA, (q15_t)0x35A8, + (q15_t)0x8BA0, (q15_t)0x354D, (q15_t)0x8B76, (q15_t)0x34F2, + (q15_t)0x8B4D, (q15_t)0x3496, (q15_t)0x8B24, (q15_t)0x343A, + (q15_t)0x8AFB, (q15_t)0x33DE, (q15_t)0x8AD2, (q15_t)0x3382, + (q15_t)0x8AAA, (q15_t)0x3326, (q15_t)0x8A82, (q15_t)0x32CA, + (q15_t)0x8A5A, (q15_t)0x326E, (q15_t)0x8A33, (q15_t)0x3211, + (q15_t)0x8A0B, (q15_t)0x31B5, (q15_t)0x89E4, (q15_t)0x3158, + (q15_t)0x89BE, (q15_t)0x30FB, (q15_t)0x8997, (q15_t)0x309E, + (q15_t)0x8971, (q15_t)0x3041, (q15_t)0x894C, (q15_t)0x2FE4, + (q15_t)0x8926, (q15_t)0x2F87, (q15_t)0x8901, (q15_t)0x2F29, + (q15_t)0x88DC, (q15_t)0x2ECC, (q15_t)0x88B8, (q15_t)0x2E6E, + (q15_t)0x8893, (q15_t)0x2E11, (q15_t)0x886F, (q15_t)0x2DB3, + (q15_t)0x884B, (q15_t)0x2D55, (q15_t)0x8828, (q15_t)0x2CF7, + (q15_t)0x8805, (q15_t)0x2C98, (q15_t)0x87E2, (q15_t)0x2C3A, + (q15_t)0x87BF, (q15_t)0x2BDC, (q15_t)0x879D, (q15_t)0x2B7D, + (q15_t)0x877B, (q15_t)0x2B1F, (q15_t)0x8759, (q15_t)0x2AC0, + (q15_t)0x8738, (q15_t)0x2A61, (q15_t)0x8717, (q15_t)0x2A02, + (q15_t)0x86F6, (q15_t)0x29A3, (q15_t)0x86D5, (q15_t)0x2944, + (q15_t)0x86B5, (q15_t)0x28E5, (q15_t)0x8695, (q15_t)0x2886, + (q15_t)0x8675, (q15_t)0x2826, (q15_t)0x8656, (q15_t)0x27C7, + (q15_t)0x8637, (q15_t)0x2767, (q15_t)0x8618, (q15_t)0x2707, + (q15_t)0x85FA, (q15_t)0x26A8, (q15_t)0x85DB, (q15_t)0x2648, + (q15_t)0x85BD, (q15_t)0x25E8, (q15_t)0x85A0, (q15_t)0x2588, + (q15_t)0x8582, (q15_t)0x2528, (q15_t)0x8565, (q15_t)0x24C7, + (q15_t)0x8549, (q15_t)0x2467, (q15_t)0x852C, (q15_t)0x2407, + (q15_t)0x8510, (q15_t)0x23A6, (q15_t)0x84F4, (q15_t)0x2345, + (q15_t)0x84D9, (q15_t)0x22E5, (q15_t)0x84BD, (q15_t)0x2284, + (q15_t)0x84A2, (q15_t)0x2223, (q15_t)0x8488, (q15_t)0x21C2, + (q15_t)0x846D, (q15_t)0x2161, (q15_t)0x8453, (q15_t)0x2100, + (q15_t)0x843A, (q15_t)0x209F, (q15_t)0x8420, (q15_t)0x203E, + (q15_t)0x8407, (q15_t)0x1FDC, (q15_t)0x83EE, (q15_t)0x1F7B, + (q15_t)0x83D6, (q15_t)0x1F19, (q15_t)0x83BD, (q15_t)0x1EB8, + (q15_t)0x83A5, (q15_t)0x1E56, (q15_t)0x838E, (q15_t)0x1DF5, + (q15_t)0x8376, (q15_t)0x1D93, (q15_t)0x835F, (q15_t)0x1D31, + (q15_t)0x8348, (q15_t)0x1CCF, (q15_t)0x8332, (q15_t)0x1C6D, + (q15_t)0x831C, (q15_t)0x1C0B, (q15_t)0x8306, (q15_t)0x1BA9, + (q15_t)0x82F0, (q15_t)0x1B47, (q15_t)0x82DB, (q15_t)0x1AE4, + (q15_t)0x82C6, (q15_t)0x1A82, (q15_t)0x82B1, (q15_t)0x1A20, + (q15_t)0x829D, (q15_t)0x19BD, (q15_t)0x8289, (q15_t)0x195B, + (q15_t)0x8275, (q15_t)0x18F8, (q15_t)0x8262, (q15_t)0x1896, + (q15_t)0x824F, (q15_t)0x1833, (q15_t)0x823C, (q15_t)0x17D0, + (q15_t)0x8229, (q15_t)0x176D, (q15_t)0x8217, (q15_t)0x170A, + (q15_t)0x8205, (q15_t)0x16A8, (q15_t)0x81F3, (q15_t)0x1645, + (q15_t)0x81E2, (q15_t)0x15E2, (q15_t)0x81D1, (q15_t)0x157F, + (q15_t)0x81C0, (q15_t)0x151B, (q15_t)0x81B0, (q15_t)0x14B8, + (q15_t)0x81A0, (q15_t)0x1455, (q15_t)0x8190, (q15_t)0x13F2, + (q15_t)0x8180, (q15_t)0x138E, (q15_t)0x8171, (q15_t)0x132B, + (q15_t)0x8162, (q15_t)0x12C8, (q15_t)0x8154, (q15_t)0x1264, + (q15_t)0x8145, (q15_t)0x1201, (q15_t)0x8137, (q15_t)0x119D, + (q15_t)0x812A, (q15_t)0x1139, (q15_t)0x811C, (q15_t)0x10D6, + (q15_t)0x810F, (q15_t)0x1072, (q15_t)0x8102, (q15_t)0x100E, + (q15_t)0x80F6, (q15_t)0x0FAB, (q15_t)0x80EA, (q15_t)0x0F47, + (q15_t)0x80DE, (q15_t)0x0EE3, (q15_t)0x80D2, (q15_t)0x0E7F, + (q15_t)0x80C7, (q15_t)0x0E1B, (q15_t)0x80BC, (q15_t)0x0DB7, + (q15_t)0x80B2, (q15_t)0x0D53, (q15_t)0x80A7, (q15_t)0x0CEF, + (q15_t)0x809D, (q15_t)0x0C8B, (q15_t)0x8094, (q15_t)0x0C27, + (q15_t)0x808A, (q15_t)0x0BC3, (q15_t)0x8081, (q15_t)0x0B5F, + (q15_t)0x8078, (q15_t)0x0AFB, (q15_t)0x8070, (q15_t)0x0A97, + (q15_t)0x8068, (q15_t)0x0A33, (q15_t)0x8060, (q15_t)0x09CE, + (q15_t)0x8058, (q15_t)0x096A, (q15_t)0x8051, (q15_t)0x0906, + (q15_t)0x804A, (q15_t)0x08A2, (q15_t)0x8043, (q15_t)0x083D, + (q15_t)0x803D, (q15_t)0x07D9, (q15_t)0x8037, (q15_t)0x0775, + (q15_t)0x8031, (q15_t)0x0710, (q15_t)0x802C, (q15_t)0x06AC, + (q15_t)0x8027, (q15_t)0x0647, (q15_t)0x8022, (q15_t)0x05E3, + (q15_t)0x801E, (q15_t)0x057F, (q15_t)0x801A, (q15_t)0x051A, + (q15_t)0x8016, (q15_t)0x04B6, (q15_t)0x8012, (q15_t)0x0451, + (q15_t)0x800F, (q15_t)0x03ED, (q15_t)0x800C, (q15_t)0x0388, + (q15_t)0x8009, (q15_t)0x0324, (q15_t)0x8007, (q15_t)0x02BF, + (q15_t)0x8005, (q15_t)0x025B, (q15_t)0x8003, (q15_t)0x01F6, + (q15_t)0x8002, (q15_t)0x0192, (q15_t)0x8001, (q15_t)0x012D, + (q15_t)0x8000, (q15_t)0x00C9, (q15_t)0x8000, (q15_t)0x0064, + (q15_t)0x8000, (q15_t)0x0000, (q15_t)0x8000, (q15_t)0xFF9B, + (q15_t)0x8000, (q15_t)0xFF36, (q15_t)0x8001, (q15_t)0xFED2, + (q15_t)0x8002, (q15_t)0xFE6D, (q15_t)0x8003, (q15_t)0xFE09, + (q15_t)0x8005, (q15_t)0xFDA4, (q15_t)0x8007, (q15_t)0xFD40, + (q15_t)0x8009, (q15_t)0xFCDB, (q15_t)0x800C, (q15_t)0xFC77, + (q15_t)0x800F, (q15_t)0xFC12, (q15_t)0x8012, (q15_t)0xFBAE, + (q15_t)0x8016, (q15_t)0xFB49, (q15_t)0x801A, (q15_t)0xFAE5, + (q15_t)0x801E, (q15_t)0xFA80, (q15_t)0x8022, (q15_t)0xFA1C, + (q15_t)0x8027, (q15_t)0xF9B8, (q15_t)0x802C, (q15_t)0xF953, + (q15_t)0x8031, (q15_t)0xF8EF, (q15_t)0x8037, (q15_t)0xF88A, + (q15_t)0x803D, (q15_t)0xF826, (q15_t)0x8043, (q15_t)0xF7C2, + (q15_t)0x804A, (q15_t)0xF75D, (q15_t)0x8051, (q15_t)0xF6F9, + (q15_t)0x8058, (q15_t)0xF695, (q15_t)0x8060, (q15_t)0xF631, + (q15_t)0x8068, (q15_t)0xF5CC, (q15_t)0x8070, (q15_t)0xF568, + (q15_t)0x8078, (q15_t)0xF504, (q15_t)0x8081, (q15_t)0xF4A0, + (q15_t)0x808A, (q15_t)0xF43C, (q15_t)0x8094, (q15_t)0xF3D8, + (q15_t)0x809D, (q15_t)0xF374, (q15_t)0x80A7, (q15_t)0xF310, + (q15_t)0x80B2, (q15_t)0xF2AC, (q15_t)0x80BC, (q15_t)0xF248, + (q15_t)0x80C7, (q15_t)0xF1E4, (q15_t)0x80D2, (q15_t)0xF180, + (q15_t)0x80DE, (q15_t)0xF11C, (q15_t)0x80EA, (q15_t)0xF0B8, + (q15_t)0x80F6, (q15_t)0xF054, (q15_t)0x8102, (q15_t)0xEFF1, + (q15_t)0x810F, (q15_t)0xEF8D, (q15_t)0x811C, (q15_t)0xEF29, + (q15_t)0x812A, (q15_t)0xEEC6, (q15_t)0x8137, (q15_t)0xEE62, + (q15_t)0x8145, (q15_t)0xEDFE, (q15_t)0x8154, (q15_t)0xED9B, + (q15_t)0x8162, (q15_t)0xED37, (q15_t)0x8171, (q15_t)0xECD4, + (q15_t)0x8180, (q15_t)0xEC71, (q15_t)0x8190, (q15_t)0xEC0D, + (q15_t)0x81A0, (q15_t)0xEBAA, (q15_t)0x81B0, (q15_t)0xEB47, + (q15_t)0x81C0, (q15_t)0xEAE4, (q15_t)0x81D1, (q15_t)0xEA80, + (q15_t)0x81E2, (q15_t)0xEA1D, (q15_t)0x81F3, (q15_t)0xE9BA, + (q15_t)0x8205, (q15_t)0xE957, (q15_t)0x8217, (q15_t)0xE8F5, + (q15_t)0x8229, (q15_t)0xE892, (q15_t)0x823C, (q15_t)0xE82F, + (q15_t)0x824F, (q15_t)0xE7CC, (q15_t)0x8262, (q15_t)0xE769, + (q15_t)0x8275, (q15_t)0xE707, (q15_t)0x8289, (q15_t)0xE6A4, + (q15_t)0x829D, (q15_t)0xE642, (q15_t)0x82B1, (q15_t)0xE5DF, + (q15_t)0x82C6, (q15_t)0xE57D, (q15_t)0x82DB, (q15_t)0xE51B, + (q15_t)0x82F0, (q15_t)0xE4B8, (q15_t)0x8306, (q15_t)0xE456, + (q15_t)0x831C, (q15_t)0xE3F4, (q15_t)0x8332, (q15_t)0xE392, + (q15_t)0x8348, (q15_t)0xE330, (q15_t)0x835F, (q15_t)0xE2CE, + (q15_t)0x8376, (q15_t)0xE26C, (q15_t)0x838E, (q15_t)0xE20A, + (q15_t)0x83A5, (q15_t)0xE1A9, (q15_t)0x83BD, (q15_t)0xE147, + (q15_t)0x83D6, (q15_t)0xE0E6, (q15_t)0x83EE, (q15_t)0xE084, + (q15_t)0x8407, (q15_t)0xE023, (q15_t)0x8420, (q15_t)0xDFC1, + (q15_t)0x843A, (q15_t)0xDF60, (q15_t)0x8453, (q15_t)0xDEFF, + (q15_t)0x846D, (q15_t)0xDE9E, (q15_t)0x8488, (q15_t)0xDE3D, + (q15_t)0x84A2, (q15_t)0xDDDC, (q15_t)0x84BD, (q15_t)0xDD7B, + (q15_t)0x84D9, (q15_t)0xDD1A, (q15_t)0x84F4, (q15_t)0xDCBA, + (q15_t)0x8510, (q15_t)0xDC59, (q15_t)0x852C, (q15_t)0xDBF8, + (q15_t)0x8549, (q15_t)0xDB98, (q15_t)0x8565, (q15_t)0xDB38, + (q15_t)0x8582, (q15_t)0xDAD7, (q15_t)0x85A0, (q15_t)0xDA77, + (q15_t)0x85BD, (q15_t)0xDA17, (q15_t)0x85DB, (q15_t)0xD9B7, + (q15_t)0x85FA, (q15_t)0xD957, (q15_t)0x8618, (q15_t)0xD8F8, + (q15_t)0x8637, (q15_t)0xD898, (q15_t)0x8656, (q15_t)0xD838, + (q15_t)0x8675, (q15_t)0xD7D9, (q15_t)0x8695, (q15_t)0xD779, + (q15_t)0x86B5, (q15_t)0xD71A, (q15_t)0x86D5, (q15_t)0xD6BB, + (q15_t)0x86F6, (q15_t)0xD65C, (q15_t)0x8717, (q15_t)0xD5FD, + (q15_t)0x8738, (q15_t)0xD59E, (q15_t)0x8759, (q15_t)0xD53F, + (q15_t)0x877B, (q15_t)0xD4E0, (q15_t)0x879D, (q15_t)0xD482, + (q15_t)0x87BF, (q15_t)0xD423, (q15_t)0x87E2, (q15_t)0xD3C5, + (q15_t)0x8805, (q15_t)0xD367, (q15_t)0x8828, (q15_t)0xD308, + (q15_t)0x884B, (q15_t)0xD2AA, (q15_t)0x886F, (q15_t)0xD24C, + (q15_t)0x8893, (q15_t)0xD1EE, (q15_t)0x88B8, (q15_t)0xD191, + (q15_t)0x88DC, (q15_t)0xD133, (q15_t)0x8901, (q15_t)0xD0D6, + (q15_t)0x8926, (q15_t)0xD078, (q15_t)0x894C, (q15_t)0xD01B, + (q15_t)0x8971, (q15_t)0xCFBE, (q15_t)0x8997, (q15_t)0xCF61, + (q15_t)0x89BE, (q15_t)0xCF04, (q15_t)0x89E4, (q15_t)0xCEA7, + (q15_t)0x8A0B, (q15_t)0xCE4A, (q15_t)0x8A33, (q15_t)0xCDEE, + (q15_t)0x8A5A, (q15_t)0xCD91, (q15_t)0x8A82, (q15_t)0xCD35, + (q15_t)0x8AAA, (q15_t)0xCCD9, (q15_t)0x8AD2, (q15_t)0xCC7D, + (q15_t)0x8AFB, (q15_t)0xCC21, (q15_t)0x8B24, (q15_t)0xCBC5, + (q15_t)0x8B4D, (q15_t)0xCB69, (q15_t)0x8B76, (q15_t)0xCB0D, + (q15_t)0x8BA0, (q15_t)0xCAB2, (q15_t)0x8BCA, (q15_t)0xCA57, + (q15_t)0x8BF4, (q15_t)0xC9FB, (q15_t)0x8C1F, (q15_t)0xC9A0, + (q15_t)0x8C4A, (q15_t)0xC945, (q15_t)0x8C75, (q15_t)0xC8EB, + (q15_t)0x8CA0, (q15_t)0xC890, (q15_t)0x8CCC, (q15_t)0xC835, + (q15_t)0x8CF8, (q15_t)0xC7DB, (q15_t)0x8D24, (q15_t)0xC781, + (q15_t)0x8D50, (q15_t)0xC727, (q15_t)0x8D7D, (q15_t)0xC6CD, + (q15_t)0x8DAA, (q15_t)0xC673, (q15_t)0x8DD8, (q15_t)0xC619, + (q15_t)0x8E05, (q15_t)0xC5BF, (q15_t)0x8E33, (q15_t)0xC566, + (q15_t)0x8E61, (q15_t)0xC50D, (q15_t)0x8E90, (q15_t)0xC4B3, + (q15_t)0x8EBE, (q15_t)0xC45A, (q15_t)0x8EED, (q15_t)0xC402, + (q15_t)0x8F1D, (q15_t)0xC3A9, (q15_t)0x8F4C, (q15_t)0xC350, + (q15_t)0x8F7C, (q15_t)0xC2F8, (q15_t)0x8FAC, (q15_t)0xC29F, + (q15_t)0x8FDC, (q15_t)0xC247, (q15_t)0x900D, (q15_t)0xC1EF, + (q15_t)0x903E, (q15_t)0xC197, (q15_t)0x906F, (q15_t)0xC140, + (q15_t)0x90A0, (q15_t)0xC0E8, (q15_t)0x90D2, (q15_t)0xC091, + (q15_t)0x9104, (q15_t)0xC03A, (q15_t)0x9136, (q15_t)0xBFE2, + (q15_t)0x9169, (q15_t)0xBF8C, (q15_t)0x919C, (q15_t)0xBF35, + (q15_t)0x91CF, (q15_t)0xBEDE, (q15_t)0x9202, (q15_t)0xBE88, + (q15_t)0x9235, (q15_t)0xBE31, (q15_t)0x9269, (q15_t)0xBDDB, + (q15_t)0x929D, (q15_t)0xBD85, (q15_t)0x92D2, (q15_t)0xBD2F, + (q15_t)0x9306, (q15_t)0xBCDA, (q15_t)0x933B, (q15_t)0xBC84, + (q15_t)0x9370, (q15_t)0xBC2F, (q15_t)0x93A6, (q15_t)0xBBDA, + (q15_t)0x93DB, (q15_t)0xBB85, (q15_t)0x9411, (q15_t)0xBB30, + (q15_t)0x9447, (q15_t)0xBADB, (q15_t)0x947E, (q15_t)0xBA87, + (q15_t)0x94B5, (q15_t)0xBA32, (q15_t)0x94EC, (q15_t)0xB9DE, + (q15_t)0x9523, (q15_t)0xB98A, (q15_t)0x955A, (q15_t)0xB936, + (q15_t)0x9592, (q15_t)0xB8E3, (q15_t)0x95CA, (q15_t)0xB88F, + (q15_t)0x9602, (q15_t)0xB83C, (q15_t)0x963B, (q15_t)0xB7E9, + (q15_t)0x9673, (q15_t)0xB796, (q15_t)0x96AC, (q15_t)0xB743, + (q15_t)0x96E6, (q15_t)0xB6F0, (q15_t)0x971F, (q15_t)0xB69E, + (q15_t)0x9759, (q15_t)0xB64B, (q15_t)0x9793, (q15_t)0xB5F9, + (q15_t)0x97CD, (q15_t)0xB5A7, (q15_t)0x9808, (q15_t)0xB556, + (q15_t)0x9842, (q15_t)0xB504, (q15_t)0x987D, (q15_t)0xB4B3, + (q15_t)0x98B9, (q15_t)0xB461, (q15_t)0x98F4, (q15_t)0xB410, + (q15_t)0x9930, (q15_t)0xB3C0, (q15_t)0x996C, (q15_t)0xB36F, + (q15_t)0x99A8, (q15_t)0xB31E, (q15_t)0x99E5, (q15_t)0xB2CE, + (q15_t)0x9A22, (q15_t)0xB27E, (q15_t)0x9A5F, (q15_t)0xB22E, + (q15_t)0x9A9C, (q15_t)0xB1DE, (q15_t)0x9AD9, (q15_t)0xB18F, + (q15_t)0x9B17, (q15_t)0xB140, (q15_t)0x9B55, (q15_t)0xB0F0, + (q15_t)0x9B93, (q15_t)0xB0A1, (q15_t)0x9BD2, (q15_t)0xB053, + (q15_t)0x9C10, (q15_t)0xB004, (q15_t)0x9C4F, (q15_t)0xAFB6, + (q15_t)0x9C8E, (q15_t)0xAF68, (q15_t)0x9CCE, (q15_t)0xAF1A, + (q15_t)0x9D0D, (q15_t)0xAECC, (q15_t)0x9D4D, (q15_t)0xAE7E, + (q15_t)0x9D8E, (q15_t)0xAE31, (q15_t)0x9DCE, (q15_t)0xADE3, + (q15_t)0x9E0E, (q15_t)0xAD96, (q15_t)0x9E4F, (q15_t)0xAD4A, + (q15_t)0x9E90, (q15_t)0xACFD, (q15_t)0x9ED2, (q15_t)0xACB1, + (q15_t)0x9F13, (q15_t)0xAC64, (q15_t)0x9F55, (q15_t)0xAC18, + (q15_t)0x9F97, (q15_t)0xABCC, (q15_t)0x9FD9, (q15_t)0xAB81, + (q15_t)0xA01C, (q15_t)0xAB35, (q15_t)0xA05F, (q15_t)0xAAEA, + (q15_t)0xA0A1, (q15_t)0xAA9F, (q15_t)0xA0E5, (q15_t)0xAA54, + (q15_t)0xA128, (q15_t)0xAA0A, (q15_t)0xA16C, (q15_t)0xA9BF, + (q15_t)0xA1AF, (q15_t)0xA975, (q15_t)0xA1F4, (q15_t)0xA92B, + (q15_t)0xA238, (q15_t)0xA8E2, (q15_t)0xA27C, (q15_t)0xA898, + (q15_t)0xA2C1, (q15_t)0xA84F, (q15_t)0xA306, (q15_t)0xA806, + (q15_t)0xA34B, (q15_t)0xA7BD, (q15_t)0xA391, (q15_t)0xA774, + (q15_t)0xA3D6, (q15_t)0xA72B, (q15_t)0xA41C, (q15_t)0xA6E3, + (q15_t)0xA462, (q15_t)0xA69B, (q15_t)0xA4A9, (q15_t)0xA653, + (q15_t)0xA4EF, (q15_t)0xA60C, (q15_t)0xA536, (q15_t)0xA5C4, + (q15_t)0xA57D, (q15_t)0xA57D, (q15_t)0xA5C4, (q15_t)0xA536, + (q15_t)0xA60C, (q15_t)0xA4EF, (q15_t)0xA653, (q15_t)0xA4A9, + (q15_t)0xA69B, (q15_t)0xA462, (q15_t)0xA6E3, (q15_t)0xA41C, + (q15_t)0xA72B, (q15_t)0xA3D6, (q15_t)0xA774, (q15_t)0xA391, + (q15_t)0xA7BD, (q15_t)0xA34B, (q15_t)0xA806, (q15_t)0xA306, + (q15_t)0xA84F, (q15_t)0xA2C1, (q15_t)0xA898, (q15_t)0xA27C, + (q15_t)0xA8E2, (q15_t)0xA238, (q15_t)0xA92B, (q15_t)0xA1F4, + (q15_t)0xA975, (q15_t)0xA1AF, (q15_t)0xA9BF, (q15_t)0xA16C, + (q15_t)0xAA0A, (q15_t)0xA128, (q15_t)0xAA54, (q15_t)0xA0E5, + (q15_t)0xAA9F, (q15_t)0xA0A1, (q15_t)0xAAEA, (q15_t)0xA05F, + (q15_t)0xAB35, (q15_t)0xA01C, (q15_t)0xAB81, (q15_t)0x9FD9, + (q15_t)0xABCC, (q15_t)0x9F97, (q15_t)0xAC18, (q15_t)0x9F55, + (q15_t)0xAC64, (q15_t)0x9F13, (q15_t)0xACB1, (q15_t)0x9ED2, + (q15_t)0xACFD, (q15_t)0x9E90, (q15_t)0xAD4A, (q15_t)0x9E4F, + (q15_t)0xAD96, (q15_t)0x9E0E, (q15_t)0xADE3, (q15_t)0x9DCE, + (q15_t)0xAE31, (q15_t)0x9D8E, (q15_t)0xAE7E, (q15_t)0x9D4D, + (q15_t)0xAECC, (q15_t)0x9D0D, (q15_t)0xAF1A, (q15_t)0x9CCE, + (q15_t)0xAF68, (q15_t)0x9C8E, (q15_t)0xAFB6, (q15_t)0x9C4F, + (q15_t)0xB004, (q15_t)0x9C10, (q15_t)0xB053, (q15_t)0x9BD2, + (q15_t)0xB0A1, (q15_t)0x9B93, (q15_t)0xB0F0, (q15_t)0x9B55, + (q15_t)0xB140, (q15_t)0x9B17, (q15_t)0xB18F, (q15_t)0x9AD9, + (q15_t)0xB1DE, (q15_t)0x9A9C, (q15_t)0xB22E, (q15_t)0x9A5F, + (q15_t)0xB27E, (q15_t)0x9A22, (q15_t)0xB2CE, (q15_t)0x99E5, + (q15_t)0xB31E, (q15_t)0x99A8, (q15_t)0xB36F, (q15_t)0x996C, + (q15_t)0xB3C0, (q15_t)0x9930, (q15_t)0xB410, (q15_t)0x98F4, + (q15_t)0xB461, (q15_t)0x98B9, (q15_t)0xB4B3, (q15_t)0x987D, + (q15_t)0xB504, (q15_t)0x9842, (q15_t)0xB556, (q15_t)0x9808, + (q15_t)0xB5A7, (q15_t)0x97CD, (q15_t)0xB5F9, (q15_t)0x9793, + (q15_t)0xB64B, (q15_t)0x9759, (q15_t)0xB69E, (q15_t)0x971F, + (q15_t)0xB6F0, (q15_t)0x96E6, (q15_t)0xB743, (q15_t)0x96AC, + (q15_t)0xB796, (q15_t)0x9673, (q15_t)0xB7E9, (q15_t)0x963B, + (q15_t)0xB83C, (q15_t)0x9602, (q15_t)0xB88F, (q15_t)0x95CA, + (q15_t)0xB8E3, (q15_t)0x9592, (q15_t)0xB936, (q15_t)0x955A, + (q15_t)0xB98A, (q15_t)0x9523, (q15_t)0xB9DE, (q15_t)0x94EC, + (q15_t)0xBA32, (q15_t)0x94B5, (q15_t)0xBA87, (q15_t)0x947E, + (q15_t)0xBADB, (q15_t)0x9447, (q15_t)0xBB30, (q15_t)0x9411, + (q15_t)0xBB85, (q15_t)0x93DB, (q15_t)0xBBDA, (q15_t)0x93A6, + (q15_t)0xBC2F, (q15_t)0x9370, (q15_t)0xBC84, (q15_t)0x933B, + (q15_t)0xBCDA, (q15_t)0x9306, (q15_t)0xBD2F, (q15_t)0x92D2, + (q15_t)0xBD85, (q15_t)0x929D, (q15_t)0xBDDB, (q15_t)0x9269, + (q15_t)0xBE31, (q15_t)0x9235, (q15_t)0xBE88, (q15_t)0x9202, + (q15_t)0xBEDE, (q15_t)0x91CF, (q15_t)0xBF35, (q15_t)0x919C, + (q15_t)0xBF8C, (q15_t)0x9169, (q15_t)0xBFE2, (q15_t)0x9136, + (q15_t)0xC03A, (q15_t)0x9104, (q15_t)0xC091, (q15_t)0x90D2, + (q15_t)0xC0E8, (q15_t)0x90A0, (q15_t)0xC140, (q15_t)0x906F, + (q15_t)0xC197, (q15_t)0x903E, (q15_t)0xC1EF, (q15_t)0x900D, + (q15_t)0xC247, (q15_t)0x8FDC, (q15_t)0xC29F, (q15_t)0x8FAC, + (q15_t)0xC2F8, (q15_t)0x8F7C, (q15_t)0xC350, (q15_t)0x8F4C, + (q15_t)0xC3A9, (q15_t)0x8F1D, (q15_t)0xC402, (q15_t)0x8EED, + (q15_t)0xC45A, (q15_t)0x8EBE, (q15_t)0xC4B3, (q15_t)0x8E90, + (q15_t)0xC50D, (q15_t)0x8E61, (q15_t)0xC566, (q15_t)0x8E33, + (q15_t)0xC5BF, (q15_t)0x8E05, (q15_t)0xC619, (q15_t)0x8DD8, + (q15_t)0xC673, (q15_t)0x8DAA, (q15_t)0xC6CD, (q15_t)0x8D7D, + (q15_t)0xC727, (q15_t)0x8D50, (q15_t)0xC781, (q15_t)0x8D24, + (q15_t)0xC7DB, (q15_t)0x8CF8, (q15_t)0xC835, (q15_t)0x8CCC, + (q15_t)0xC890, (q15_t)0x8CA0, (q15_t)0xC8EB, (q15_t)0x8C75, + (q15_t)0xC945, (q15_t)0x8C4A, (q15_t)0xC9A0, (q15_t)0x8C1F, + (q15_t)0xC9FB, (q15_t)0x8BF4, (q15_t)0xCA57, (q15_t)0x8BCA, + (q15_t)0xCAB2, (q15_t)0x8BA0, (q15_t)0xCB0D, (q15_t)0x8B76, + (q15_t)0xCB69, (q15_t)0x8B4D, (q15_t)0xCBC5, (q15_t)0x8B24, + (q15_t)0xCC21, (q15_t)0x8AFB, (q15_t)0xCC7D, (q15_t)0x8AD2, + (q15_t)0xCCD9, (q15_t)0x8AAA, (q15_t)0xCD35, (q15_t)0x8A82, + (q15_t)0xCD91, (q15_t)0x8A5A, (q15_t)0xCDEE, (q15_t)0x8A33, + (q15_t)0xCE4A, (q15_t)0x8A0B, (q15_t)0xCEA7, (q15_t)0x89E4, + (q15_t)0xCF04, (q15_t)0x89BE, (q15_t)0xCF61, (q15_t)0x8997, + (q15_t)0xCFBE, (q15_t)0x8971, (q15_t)0xD01B, (q15_t)0x894C, + (q15_t)0xD078, (q15_t)0x8926, (q15_t)0xD0D6, (q15_t)0x8901, + (q15_t)0xD133, (q15_t)0x88DC, (q15_t)0xD191, (q15_t)0x88B8, + (q15_t)0xD1EE, (q15_t)0x8893, (q15_t)0xD24C, (q15_t)0x886F, + (q15_t)0xD2AA, (q15_t)0x884B, (q15_t)0xD308, (q15_t)0x8828, + (q15_t)0xD367, (q15_t)0x8805, (q15_t)0xD3C5, (q15_t)0x87E2, + (q15_t)0xD423, (q15_t)0x87BF, (q15_t)0xD482, (q15_t)0x879D, + (q15_t)0xD4E0, (q15_t)0x877B, (q15_t)0xD53F, (q15_t)0x8759, + (q15_t)0xD59E, (q15_t)0x8738, (q15_t)0xD5FD, (q15_t)0x8717, + (q15_t)0xD65C, (q15_t)0x86F6, (q15_t)0xD6BB, (q15_t)0x86D5, + (q15_t)0xD71A, (q15_t)0x86B5, (q15_t)0xD779, (q15_t)0x8695, + (q15_t)0xD7D9, (q15_t)0x8675, (q15_t)0xD838, (q15_t)0x8656, + (q15_t)0xD898, (q15_t)0x8637, (q15_t)0xD8F8, (q15_t)0x8618, + (q15_t)0xD957, (q15_t)0x85FA, (q15_t)0xD9B7, (q15_t)0x85DB, + (q15_t)0xDA17, (q15_t)0x85BD, (q15_t)0xDA77, (q15_t)0x85A0, + (q15_t)0xDAD7, (q15_t)0x8582, (q15_t)0xDB38, (q15_t)0x8565, + (q15_t)0xDB98, (q15_t)0x8549, (q15_t)0xDBF8, (q15_t)0x852C, + (q15_t)0xDC59, (q15_t)0x8510, (q15_t)0xDCBA, (q15_t)0x84F4, + (q15_t)0xDD1A, (q15_t)0x84D9, (q15_t)0xDD7B, (q15_t)0x84BD, + (q15_t)0xDDDC, (q15_t)0x84A2, (q15_t)0xDE3D, (q15_t)0x8488, + (q15_t)0xDE9E, (q15_t)0x846D, (q15_t)0xDEFF, (q15_t)0x8453, + (q15_t)0xDF60, (q15_t)0x843A, (q15_t)0xDFC1, (q15_t)0x8420, + (q15_t)0xE023, (q15_t)0x8407, (q15_t)0xE084, (q15_t)0x83EE, + (q15_t)0xE0E6, (q15_t)0x83D6, (q15_t)0xE147, (q15_t)0x83BD, + (q15_t)0xE1A9, (q15_t)0x83A5, (q15_t)0xE20A, (q15_t)0x838E, + (q15_t)0xE26C, (q15_t)0x8376, (q15_t)0xE2CE, (q15_t)0x835F, + (q15_t)0xE330, (q15_t)0x8348, (q15_t)0xE392, (q15_t)0x8332, + (q15_t)0xE3F4, (q15_t)0x831C, (q15_t)0xE456, (q15_t)0x8306, + (q15_t)0xE4B8, (q15_t)0x82F0, (q15_t)0xE51B, (q15_t)0x82DB, + (q15_t)0xE57D, (q15_t)0x82C6, (q15_t)0xE5DF, (q15_t)0x82B1, + (q15_t)0xE642, (q15_t)0x829D, (q15_t)0xE6A4, (q15_t)0x8289, + (q15_t)0xE707, (q15_t)0x8275, (q15_t)0xE769, (q15_t)0x8262, + (q15_t)0xE7CC, (q15_t)0x824F, (q15_t)0xE82F, (q15_t)0x823C, + (q15_t)0xE892, (q15_t)0x8229, (q15_t)0xE8F5, (q15_t)0x8217, + (q15_t)0xE957, (q15_t)0x8205, (q15_t)0xE9BA, (q15_t)0x81F3, + (q15_t)0xEA1D, (q15_t)0x81E2, (q15_t)0xEA80, (q15_t)0x81D1, + (q15_t)0xEAE4, (q15_t)0x81C0, (q15_t)0xEB47, (q15_t)0x81B0, + (q15_t)0xEBAA, (q15_t)0x81A0, (q15_t)0xEC0D, (q15_t)0x8190, + (q15_t)0xEC71, (q15_t)0x8180, (q15_t)0xECD4, (q15_t)0x8171, + (q15_t)0xED37, (q15_t)0x8162, (q15_t)0xED9B, (q15_t)0x8154, + (q15_t)0xEDFE, (q15_t)0x8145, (q15_t)0xEE62, (q15_t)0x8137, + (q15_t)0xEEC6, (q15_t)0x812A, (q15_t)0xEF29, (q15_t)0x811C, + (q15_t)0xEF8D, (q15_t)0x810F, (q15_t)0xEFF1, (q15_t)0x8102, + (q15_t)0xF054, (q15_t)0x80F6, (q15_t)0xF0B8, (q15_t)0x80EA, + (q15_t)0xF11C, (q15_t)0x80DE, (q15_t)0xF180, (q15_t)0x80D2, + (q15_t)0xF1E4, (q15_t)0x80C7, (q15_t)0xF248, (q15_t)0x80BC, + (q15_t)0xF2AC, (q15_t)0x80B2, (q15_t)0xF310, (q15_t)0x80A7, + (q15_t)0xF374, (q15_t)0x809D, (q15_t)0xF3D8, (q15_t)0x8094, + (q15_t)0xF43C, (q15_t)0x808A, (q15_t)0xF4A0, (q15_t)0x8081, + (q15_t)0xF504, (q15_t)0x8078, (q15_t)0xF568, (q15_t)0x8070, + (q15_t)0xF5CC, (q15_t)0x8068, (q15_t)0xF631, (q15_t)0x8060, + (q15_t)0xF695, (q15_t)0x8058, (q15_t)0xF6F9, (q15_t)0x8051, + (q15_t)0xF75D, (q15_t)0x804A, (q15_t)0xF7C2, (q15_t)0x8043, + (q15_t)0xF826, (q15_t)0x803D, (q15_t)0xF88A, (q15_t)0x8037, + (q15_t)0xF8EF, (q15_t)0x8031, (q15_t)0xF953, (q15_t)0x802C, + (q15_t)0xF9B8, (q15_t)0x8027, (q15_t)0xFA1C, (q15_t)0x8022, + (q15_t)0xFA80, (q15_t)0x801E, (q15_t)0xFAE5, (q15_t)0x801A, + (q15_t)0xFB49, (q15_t)0x8016, (q15_t)0xFBAE, (q15_t)0x8012, + (q15_t)0xFC12, (q15_t)0x800F, (q15_t)0xFC77, (q15_t)0x800C, + (q15_t)0xFCDB, (q15_t)0x8009, (q15_t)0xFD40, (q15_t)0x8007, + (q15_t)0xFDA4, (q15_t)0x8005, (q15_t)0xFE09, (q15_t)0x8003, + (q15_t)0xFE6D, (q15_t)0x8002, (q15_t)0xFED2, (q15_t)0x8001, + (q15_t)0xFF36, (q15_t)0x8000, (q15_t)0xFF9B, (q15_t)0x8000 +}; + +/** + @par + Example code for q15 Twiddle factors Generation:: + @par +
for (i = 0; i< 3N/4; i++)
+  {
+     twiddleCoefq15[2*i]   = cos(i * 2*PI/(float)N);
+     twiddleCoefq15[2*i+1] = sin(i * 2*PI/(float)N);
+  } 
+ @par + where N = 4096, PI = 3.14159265358979 + @par + Cos and Sin values are interleaved fashion + @par + Convert Floating point to q15(Fixed point 1.15): + round(twiddleCoefq15(i) * pow(2, 15)) + */ +const q15_t twiddleCoef_4096_q15[6144] = +{ + (q15_t)0x7FFF, (q15_t)0x0000, (q15_t)0x7FFF, (q15_t)0x0032, + (q15_t)0x7FFF, (q15_t)0x0064, (q15_t)0x7FFF, (q15_t)0x0096, + (q15_t)0x7FFF, (q15_t)0x00C9, (q15_t)0x7FFF, (q15_t)0x00FB, + (q15_t)0x7FFE, (q15_t)0x012D, (q15_t)0x7FFE, (q15_t)0x015F, + (q15_t)0x7FFD, (q15_t)0x0192, (q15_t)0x7FFC, (q15_t)0x01C4, + (q15_t)0x7FFC, (q15_t)0x01F6, (q15_t)0x7FFB, (q15_t)0x0228, + (q15_t)0x7FFA, (q15_t)0x025B, (q15_t)0x7FF9, (q15_t)0x028D, + (q15_t)0x7FF8, (q15_t)0x02BF, (q15_t)0x7FF7, (q15_t)0x02F1, + (q15_t)0x7FF6, (q15_t)0x0324, (q15_t)0x7FF4, (q15_t)0x0356, + (q15_t)0x7FF3, (q15_t)0x0388, (q15_t)0x7FF2, (q15_t)0x03BA, + (q15_t)0x7FF0, (q15_t)0x03ED, (q15_t)0x7FEE, (q15_t)0x041F, + (q15_t)0x7FED, (q15_t)0x0451, (q15_t)0x7FEB, (q15_t)0x0483, + (q15_t)0x7FE9, (q15_t)0x04B6, (q15_t)0x7FE7, (q15_t)0x04E8, + (q15_t)0x7FE5, (q15_t)0x051A, (q15_t)0x7FE3, (q15_t)0x054C, + (q15_t)0x7FE1, (q15_t)0x057F, (q15_t)0x7FDF, (q15_t)0x05B1, + (q15_t)0x7FDD, (q15_t)0x05E3, (q15_t)0x7FDA, (q15_t)0x0615, + (q15_t)0x7FD8, (q15_t)0x0647, (q15_t)0x7FD6, (q15_t)0x067A, + (q15_t)0x7FD3, (q15_t)0x06AC, (q15_t)0x7FD0, (q15_t)0x06DE, + (q15_t)0x7FCE, (q15_t)0x0710, (q15_t)0x7FCB, (q15_t)0x0742, + (q15_t)0x7FC8, (q15_t)0x0775, (q15_t)0x7FC5, (q15_t)0x07A7, + (q15_t)0x7FC2, (q15_t)0x07D9, (q15_t)0x7FBF, (q15_t)0x080B, + (q15_t)0x7FBC, (q15_t)0x083D, (q15_t)0x7FB8, (q15_t)0x086F, + (q15_t)0x7FB5, (q15_t)0x08A2, (q15_t)0x7FB1, (q15_t)0x08D4, + (q15_t)0x7FAE, (q15_t)0x0906, (q15_t)0x7FAA, (q15_t)0x0938, + (q15_t)0x7FA7, (q15_t)0x096A, (q15_t)0x7FA3, (q15_t)0x099C, + (q15_t)0x7F9F, (q15_t)0x09CE, (q15_t)0x7F9B, (q15_t)0x0A00, + (q15_t)0x7F97, (q15_t)0x0A33, (q15_t)0x7F93, (q15_t)0x0A65, + (q15_t)0x7F8F, (q15_t)0x0A97, (q15_t)0x7F8B, (q15_t)0x0AC9, + (q15_t)0x7F87, (q15_t)0x0AFB, (q15_t)0x7F82, (q15_t)0x0B2D, + (q15_t)0x7F7E, (q15_t)0x0B5F, (q15_t)0x7F79, (q15_t)0x0B91, + (q15_t)0x7F75, (q15_t)0x0BC3, (q15_t)0x7F70, (q15_t)0x0BF5, + (q15_t)0x7F6B, (q15_t)0x0C27, (q15_t)0x7F67, (q15_t)0x0C59, + (q15_t)0x7F62, (q15_t)0x0C8B, (q15_t)0x7F5D, (q15_t)0x0CBD, + (q15_t)0x7F58, (q15_t)0x0CEF, (q15_t)0x7F53, (q15_t)0x0D21, + (q15_t)0x7F4D, (q15_t)0x0D53, (q15_t)0x7F48, (q15_t)0x0D85, + (q15_t)0x7F43, (q15_t)0x0DB7, (q15_t)0x7F3D, (q15_t)0x0DE9, + (q15_t)0x7F38, (q15_t)0x0E1B, (q15_t)0x7F32, (q15_t)0x0E4D, + (q15_t)0x7F2D, (q15_t)0x0E7F, (q15_t)0x7F27, (q15_t)0x0EB1, + (q15_t)0x7F21, (q15_t)0x0EE3, (q15_t)0x7F1B, (q15_t)0x0F15, + (q15_t)0x7F15, (q15_t)0x0F47, (q15_t)0x7F0F, (q15_t)0x0F79, + (q15_t)0x7F09, (q15_t)0x0FAB, (q15_t)0x7F03, (q15_t)0x0FDD, + (q15_t)0x7EFD, (q15_t)0x100E, (q15_t)0x7EF6, (q15_t)0x1040, + (q15_t)0x7EF0, (q15_t)0x1072, (q15_t)0x7EE9, (q15_t)0x10A4, + (q15_t)0x7EE3, (q15_t)0x10D6, (q15_t)0x7EDC, (q15_t)0x1108, + (q15_t)0x7ED5, (q15_t)0x1139, (q15_t)0x7ECF, (q15_t)0x116B, + (q15_t)0x7EC8, (q15_t)0x119D, (q15_t)0x7EC1, (q15_t)0x11CF, + (q15_t)0x7EBA, (q15_t)0x1201, (q15_t)0x7EB3, (q15_t)0x1232, + (q15_t)0x7EAB, (q15_t)0x1264, (q15_t)0x7EA4, (q15_t)0x1296, + (q15_t)0x7E9D, (q15_t)0x12C8, (q15_t)0x7E95, (q15_t)0x12F9, + (q15_t)0x7E8E, (q15_t)0x132B, (q15_t)0x7E86, (q15_t)0x135D, + (q15_t)0x7E7F, (q15_t)0x138E, (q15_t)0x7E77, (q15_t)0x13C0, + (q15_t)0x7E6F, (q15_t)0x13F2, (q15_t)0x7E67, (q15_t)0x1423, + (q15_t)0x7E5F, (q15_t)0x1455, (q15_t)0x7E57, (q15_t)0x1487, + (q15_t)0x7E4F, (q15_t)0x14B8, (q15_t)0x7E47, (q15_t)0x14EA, + (q15_t)0x7E3F, (q15_t)0x151B, (q15_t)0x7E37, (q15_t)0x154D, + (q15_t)0x7E2E, (q15_t)0x157F, (q15_t)0x7E26, (q15_t)0x15B0, + (q15_t)0x7E1D, (q15_t)0x15E2, (q15_t)0x7E14, (q15_t)0x1613, + (q15_t)0x7E0C, (q15_t)0x1645, (q15_t)0x7E03, (q15_t)0x1676, + (q15_t)0x7DFA, (q15_t)0x16A8, (q15_t)0x7DF1, (q15_t)0x16D9, + (q15_t)0x7DE8, (q15_t)0x170A, (q15_t)0x7DDF, (q15_t)0x173C, + (q15_t)0x7DD6, (q15_t)0x176D, (q15_t)0x7DCD, (q15_t)0x179F, + (q15_t)0x7DC3, (q15_t)0x17D0, (q15_t)0x7DBA, (q15_t)0x1802, + (q15_t)0x7DB0, (q15_t)0x1833, (q15_t)0x7DA7, (q15_t)0x1864, + (q15_t)0x7D9D, (q15_t)0x1896, (q15_t)0x7D94, (q15_t)0x18C7, + (q15_t)0x7D8A, (q15_t)0x18F8, (q15_t)0x7D80, (q15_t)0x192A, + (q15_t)0x7D76, (q15_t)0x195B, (q15_t)0x7D6C, (q15_t)0x198C, + (q15_t)0x7D62, (q15_t)0x19BD, (q15_t)0x7D58, (q15_t)0x19EF, + (q15_t)0x7D4E, (q15_t)0x1A20, (q15_t)0x7D43, (q15_t)0x1A51, + (q15_t)0x7D39, (q15_t)0x1A82, (q15_t)0x7D2F, (q15_t)0x1AB3, + (q15_t)0x7D24, (q15_t)0x1AE4, (q15_t)0x7D19, (q15_t)0x1B16, + (q15_t)0x7D0F, (q15_t)0x1B47, (q15_t)0x7D04, (q15_t)0x1B78, + (q15_t)0x7CF9, (q15_t)0x1BA9, (q15_t)0x7CEE, (q15_t)0x1BDA, + (q15_t)0x7CE3, (q15_t)0x1C0B, (q15_t)0x7CD8, (q15_t)0x1C3C, + (q15_t)0x7CCD, (q15_t)0x1C6D, (q15_t)0x7CC2, (q15_t)0x1C9E, + (q15_t)0x7CB7, (q15_t)0x1CCF, (q15_t)0x7CAB, (q15_t)0x1D00, + (q15_t)0x7CA0, (q15_t)0x1D31, (q15_t)0x7C94, (q15_t)0x1D62, + (q15_t)0x7C89, (q15_t)0x1D93, (q15_t)0x7C7D, (q15_t)0x1DC4, + (q15_t)0x7C71, (q15_t)0x1DF5, (q15_t)0x7C66, (q15_t)0x1E25, + (q15_t)0x7C5A, (q15_t)0x1E56, (q15_t)0x7C4E, (q15_t)0x1E87, + (q15_t)0x7C42, (q15_t)0x1EB8, (q15_t)0x7C36, (q15_t)0x1EE9, + (q15_t)0x7C29, (q15_t)0x1F19, (q15_t)0x7C1D, (q15_t)0x1F4A, + (q15_t)0x7C11, (q15_t)0x1F7B, (q15_t)0x7C05, (q15_t)0x1FAC, + (q15_t)0x7BF8, (q15_t)0x1FDC, (q15_t)0x7BEB, (q15_t)0x200D, + (q15_t)0x7BDF, (q15_t)0x203E, (q15_t)0x7BD2, (q15_t)0x206E, + (q15_t)0x7BC5, (q15_t)0x209F, (q15_t)0x7BB9, (q15_t)0x20D0, + (q15_t)0x7BAC, (q15_t)0x2100, (q15_t)0x7B9F, (q15_t)0x2131, + (q15_t)0x7B92, (q15_t)0x2161, (q15_t)0x7B84, (q15_t)0x2192, + (q15_t)0x7B77, (q15_t)0x21C2, (q15_t)0x7B6A, (q15_t)0x21F3, + (q15_t)0x7B5D, (q15_t)0x2223, (q15_t)0x7B4F, (q15_t)0x2254, + (q15_t)0x7B42, (q15_t)0x2284, (q15_t)0x7B34, (q15_t)0x22B4, + (q15_t)0x7B26, (q15_t)0x22E5, (q15_t)0x7B19, (q15_t)0x2315, + (q15_t)0x7B0B, (q15_t)0x2345, (q15_t)0x7AFD, (q15_t)0x2376, + (q15_t)0x7AEF, (q15_t)0x23A6, (q15_t)0x7AE1, (q15_t)0x23D6, + (q15_t)0x7AD3, (q15_t)0x2407, (q15_t)0x7AC5, (q15_t)0x2437, + (q15_t)0x7AB6, (q15_t)0x2467, (q15_t)0x7AA8, (q15_t)0x2497, + (q15_t)0x7A9A, (q15_t)0x24C7, (q15_t)0x7A8B, (q15_t)0x24F7, + (q15_t)0x7A7D, (q15_t)0x2528, (q15_t)0x7A6E, (q15_t)0x2558, + (q15_t)0x7A5F, (q15_t)0x2588, (q15_t)0x7A50, (q15_t)0x25B8, + (q15_t)0x7A42, (q15_t)0x25E8, (q15_t)0x7A33, (q15_t)0x2618, + (q15_t)0x7A24, (q15_t)0x2648, (q15_t)0x7A15, (q15_t)0x2678, + (q15_t)0x7A05, (q15_t)0x26A8, (q15_t)0x79F6, (q15_t)0x26D8, + (q15_t)0x79E7, (q15_t)0x2707, (q15_t)0x79D8, (q15_t)0x2737, + (q15_t)0x79C8, (q15_t)0x2767, (q15_t)0x79B9, (q15_t)0x2797, + (q15_t)0x79A9, (q15_t)0x27C7, (q15_t)0x7999, (q15_t)0x27F6, + (q15_t)0x798A, (q15_t)0x2826, (q15_t)0x797A, (q15_t)0x2856, + (q15_t)0x796A, (q15_t)0x2886, (q15_t)0x795A, (q15_t)0x28B5, + (q15_t)0x794A, (q15_t)0x28E5, (q15_t)0x793A, (q15_t)0x2915, + (q15_t)0x792A, (q15_t)0x2944, (q15_t)0x7919, (q15_t)0x2974, + (q15_t)0x7909, (q15_t)0x29A3, (q15_t)0x78F9, (q15_t)0x29D3, + (q15_t)0x78E8, (q15_t)0x2A02, (q15_t)0x78D8, (q15_t)0x2A32, + (q15_t)0x78C7, (q15_t)0x2A61, (q15_t)0x78B6, (q15_t)0x2A91, + (q15_t)0x78A6, (q15_t)0x2AC0, (q15_t)0x7895, (q15_t)0x2AEF, + (q15_t)0x7884, (q15_t)0x2B1F, (q15_t)0x7873, (q15_t)0x2B4E, + (q15_t)0x7862, (q15_t)0x2B7D, (q15_t)0x7851, (q15_t)0x2BAD, + (q15_t)0x7840, (q15_t)0x2BDC, (q15_t)0x782E, (q15_t)0x2C0B, + (q15_t)0x781D, (q15_t)0x2C3A, (q15_t)0x780C, (q15_t)0x2C69, + (q15_t)0x77FA, (q15_t)0x2C98, (q15_t)0x77E9, (q15_t)0x2CC8, + (q15_t)0x77D7, (q15_t)0x2CF7, (q15_t)0x77C5, (q15_t)0x2D26, + (q15_t)0x77B4, (q15_t)0x2D55, (q15_t)0x77A2, (q15_t)0x2D84, + (q15_t)0x7790, (q15_t)0x2DB3, (q15_t)0x777E, (q15_t)0x2DE2, + (q15_t)0x776C, (q15_t)0x2E11, (q15_t)0x775A, (q15_t)0x2E3F, + (q15_t)0x7747, (q15_t)0x2E6E, (q15_t)0x7735, (q15_t)0x2E9D, + (q15_t)0x7723, (q15_t)0x2ECC, (q15_t)0x7710, (q15_t)0x2EFB, + (q15_t)0x76FE, (q15_t)0x2F29, (q15_t)0x76EB, (q15_t)0x2F58, + (q15_t)0x76D9, (q15_t)0x2F87, (q15_t)0x76C6, (q15_t)0x2FB5, + (q15_t)0x76B3, (q15_t)0x2FE4, (q15_t)0x76A0, (q15_t)0x3013, + (q15_t)0x768E, (q15_t)0x3041, (q15_t)0x767B, (q15_t)0x3070, + (q15_t)0x7668, (q15_t)0x309E, (q15_t)0x7654, (q15_t)0x30CD, + (q15_t)0x7641, (q15_t)0x30FB, (q15_t)0x762E, (q15_t)0x312A, + (q15_t)0x761B, (q15_t)0x3158, (q15_t)0x7607, (q15_t)0x3186, + (q15_t)0x75F4, (q15_t)0x31B5, (q15_t)0x75E0, (q15_t)0x31E3, + (q15_t)0x75CC, (q15_t)0x3211, (q15_t)0x75B9, (q15_t)0x3240, + (q15_t)0x75A5, (q15_t)0x326E, (q15_t)0x7591, (q15_t)0x329C, + (q15_t)0x757D, (q15_t)0x32CA, (q15_t)0x7569, (q15_t)0x32F8, + (q15_t)0x7555, (q15_t)0x3326, (q15_t)0x7541, (q15_t)0x3354, + (q15_t)0x752D, (q15_t)0x3382, (q15_t)0x7519, (q15_t)0x33B0, + (q15_t)0x7504, (q15_t)0x33DE, (q15_t)0x74F0, (q15_t)0x340C, + (q15_t)0x74DB, (q15_t)0x343A, (q15_t)0x74C7, (q15_t)0x3468, + (q15_t)0x74B2, (q15_t)0x3496, (q15_t)0x749E, (q15_t)0x34C4, + (q15_t)0x7489, (q15_t)0x34F2, (q15_t)0x7474, (q15_t)0x351F, + (q15_t)0x745F, (q15_t)0x354D, (q15_t)0x744A, (q15_t)0x357B, + (q15_t)0x7435, (q15_t)0x35A8, (q15_t)0x7420, (q15_t)0x35D6, + (q15_t)0x740B, (q15_t)0x3604, (q15_t)0x73F6, (q15_t)0x3631, + (q15_t)0x73E0, (q15_t)0x365F, (q15_t)0x73CB, (q15_t)0x368C, + (q15_t)0x73B5, (q15_t)0x36BA, (q15_t)0x73A0, (q15_t)0x36E7, + (q15_t)0x738A, (q15_t)0x3714, (q15_t)0x7375, (q15_t)0x3742, + (q15_t)0x735F, (q15_t)0x376F, (q15_t)0x7349, (q15_t)0x379C, + (q15_t)0x7333, (q15_t)0x37CA, (q15_t)0x731D, (q15_t)0x37F7, + (q15_t)0x7307, (q15_t)0x3824, (q15_t)0x72F1, (q15_t)0x3851, + (q15_t)0x72DB, (q15_t)0x387E, (q15_t)0x72C5, (q15_t)0x38AB, + (q15_t)0x72AF, (q15_t)0x38D8, (q15_t)0x7298, (q15_t)0x3906, + (q15_t)0x7282, (q15_t)0x3932, (q15_t)0x726B, (q15_t)0x395F, + (q15_t)0x7255, (q15_t)0x398C, (q15_t)0x723E, (q15_t)0x39B9, + (q15_t)0x7227, (q15_t)0x39E6, (q15_t)0x7211, (q15_t)0x3A13, + (q15_t)0x71FA, (q15_t)0x3A40, (q15_t)0x71E3, (q15_t)0x3A6C, + (q15_t)0x71CC, (q15_t)0x3A99, (q15_t)0x71B5, (q15_t)0x3AC6, + (q15_t)0x719E, (q15_t)0x3AF2, (q15_t)0x7186, (q15_t)0x3B1F, + (q15_t)0x716F, (q15_t)0x3B4C, (q15_t)0x7158, (q15_t)0x3B78, + (q15_t)0x7141, (q15_t)0x3BA5, (q15_t)0x7129, (q15_t)0x3BD1, + (q15_t)0x7112, (q15_t)0x3BFD, (q15_t)0x70FA, (q15_t)0x3C2A, + (q15_t)0x70E2, (q15_t)0x3C56, (q15_t)0x70CB, (q15_t)0x3C83, + (q15_t)0x70B3, (q15_t)0x3CAF, (q15_t)0x709B, (q15_t)0x3CDB, + (q15_t)0x7083, (q15_t)0x3D07, (q15_t)0x706B, (q15_t)0x3D33, + (q15_t)0x7053, (q15_t)0x3D60, (q15_t)0x703B, (q15_t)0x3D8C, + (q15_t)0x7023, (q15_t)0x3DB8, (q15_t)0x700A, (q15_t)0x3DE4, + (q15_t)0x6FF2, (q15_t)0x3E10, (q15_t)0x6FDA, (q15_t)0x3E3C, + (q15_t)0x6FC1, (q15_t)0x3E68, (q15_t)0x6FA9, (q15_t)0x3E93, + (q15_t)0x6F90, (q15_t)0x3EBF, (q15_t)0x6F77, (q15_t)0x3EEB, + (q15_t)0x6F5F, (q15_t)0x3F17, (q15_t)0x6F46, (q15_t)0x3F43, + (q15_t)0x6F2D, (q15_t)0x3F6E, (q15_t)0x6F14, (q15_t)0x3F9A, + (q15_t)0x6EFB, (q15_t)0x3FC5, (q15_t)0x6EE2, (q15_t)0x3FF1, + (q15_t)0x6EC9, (q15_t)0x401D, (q15_t)0x6EAF, (q15_t)0x4048, + (q15_t)0x6E96, (q15_t)0x4073, (q15_t)0x6E7D, (q15_t)0x409F, + (q15_t)0x6E63, (q15_t)0x40CA, (q15_t)0x6E4A, (q15_t)0x40F6, + (q15_t)0x6E30, (q15_t)0x4121, (q15_t)0x6E17, (q15_t)0x414C, + (q15_t)0x6DFD, (q15_t)0x4177, (q15_t)0x6DE3, (q15_t)0x41A2, + (q15_t)0x6DCA, (q15_t)0x41CE, (q15_t)0x6DB0, (q15_t)0x41F9, + (q15_t)0x6D96, (q15_t)0x4224, (q15_t)0x6D7C, (q15_t)0x424F, + (q15_t)0x6D62, (q15_t)0x427A, (q15_t)0x6D48, (q15_t)0x42A5, + (q15_t)0x6D2D, (q15_t)0x42D0, (q15_t)0x6D13, (q15_t)0x42FA, + (q15_t)0x6CF9, (q15_t)0x4325, (q15_t)0x6CDE, (q15_t)0x4350, + (q15_t)0x6CC4, (q15_t)0x437B, (q15_t)0x6CA9, (q15_t)0x43A5, + (q15_t)0x6C8F, (q15_t)0x43D0, (q15_t)0x6C74, (q15_t)0x43FB, + (q15_t)0x6C59, (q15_t)0x4425, (q15_t)0x6C3F, (q15_t)0x4450, + (q15_t)0x6C24, (q15_t)0x447A, (q15_t)0x6C09, (q15_t)0x44A5, + (q15_t)0x6BEE, (q15_t)0x44CF, (q15_t)0x6BD3, (q15_t)0x44FA, + (q15_t)0x6BB8, (q15_t)0x4524, (q15_t)0x6B9C, (q15_t)0x454E, + (q15_t)0x6B81, (q15_t)0x4578, (q15_t)0x6B66, (q15_t)0x45A3, + (q15_t)0x6B4A, (q15_t)0x45CD, (q15_t)0x6B2F, (q15_t)0x45F7, + (q15_t)0x6B13, (q15_t)0x4621, (q15_t)0x6AF8, (q15_t)0x464B, + (q15_t)0x6ADC, (q15_t)0x4675, (q15_t)0x6AC1, (q15_t)0x469F, + (q15_t)0x6AA5, (q15_t)0x46C9, (q15_t)0x6A89, (q15_t)0x46F3, + (q15_t)0x6A6D, (q15_t)0x471C, (q15_t)0x6A51, (q15_t)0x4746, + (q15_t)0x6A35, (q15_t)0x4770, (q15_t)0x6A19, (q15_t)0x479A, + (q15_t)0x69FD, (q15_t)0x47C3, (q15_t)0x69E1, (q15_t)0x47ED, + (q15_t)0x69C4, (q15_t)0x4816, (q15_t)0x69A8, (q15_t)0x4840, + (q15_t)0x698C, (q15_t)0x4869, (q15_t)0x696F, (q15_t)0x4893, + (q15_t)0x6953, (q15_t)0x48BC, (q15_t)0x6936, (q15_t)0x48E6, + (q15_t)0x6919, (q15_t)0x490F, (q15_t)0x68FD, (q15_t)0x4938, + (q15_t)0x68E0, (q15_t)0x4961, (q15_t)0x68C3, (q15_t)0x498A, + (q15_t)0x68A6, (q15_t)0x49B4, (q15_t)0x6889, (q15_t)0x49DD, + (q15_t)0x686C, (q15_t)0x4A06, (q15_t)0x684F, (q15_t)0x4A2F, + (q15_t)0x6832, (q15_t)0x4A58, (q15_t)0x6815, (q15_t)0x4A81, + (q15_t)0x67F7, (q15_t)0x4AA9, (q15_t)0x67DA, (q15_t)0x4AD2, + (q15_t)0x67BD, (q15_t)0x4AFB, (q15_t)0x679F, (q15_t)0x4B24, + (q15_t)0x6782, (q15_t)0x4B4C, (q15_t)0x6764, (q15_t)0x4B75, + (q15_t)0x6746, (q15_t)0x4B9E, (q15_t)0x6729, (q15_t)0x4BC6, + (q15_t)0x670B, (q15_t)0x4BEF, (q15_t)0x66ED, (q15_t)0x4C17, + (q15_t)0x66CF, (q15_t)0x4C3F, (q15_t)0x66B1, (q15_t)0x4C68, + (q15_t)0x6693, (q15_t)0x4C90, (q15_t)0x6675, (q15_t)0x4CB8, + (q15_t)0x6657, (q15_t)0x4CE1, (q15_t)0x6639, (q15_t)0x4D09, + (q15_t)0x661A, (q15_t)0x4D31, (q15_t)0x65FC, (q15_t)0x4D59, + (q15_t)0x65DD, (q15_t)0x4D81, (q15_t)0x65BF, (q15_t)0x4DA9, + (q15_t)0x65A0, (q15_t)0x4DD1, (q15_t)0x6582, (q15_t)0x4DF9, + (q15_t)0x6563, (q15_t)0x4E21, (q15_t)0x6545, (q15_t)0x4E48, + (q15_t)0x6526, (q15_t)0x4E70, (q15_t)0x6507, (q15_t)0x4E98, + (q15_t)0x64E8, (q15_t)0x4EBF, (q15_t)0x64C9, (q15_t)0x4EE7, + (q15_t)0x64AA, (q15_t)0x4F0F, (q15_t)0x648B, (q15_t)0x4F36, + (q15_t)0x646C, (q15_t)0x4F5E, (q15_t)0x644D, (q15_t)0x4F85, + (q15_t)0x642D, (q15_t)0x4FAC, (q15_t)0x640E, (q15_t)0x4FD4, + (q15_t)0x63EF, (q15_t)0x4FFB, (q15_t)0x63CF, (q15_t)0x5022, + (q15_t)0x63B0, (q15_t)0x5049, (q15_t)0x6390, (q15_t)0x5070, + (q15_t)0x6371, (q15_t)0x5097, (q15_t)0x6351, (q15_t)0x50BF, + (q15_t)0x6331, (q15_t)0x50E5, (q15_t)0x6311, (q15_t)0x510C, + (q15_t)0x62F2, (q15_t)0x5133, (q15_t)0x62D2, (q15_t)0x515A, + (q15_t)0x62B2, (q15_t)0x5181, (q15_t)0x6292, (q15_t)0x51A8, + (q15_t)0x6271, (q15_t)0x51CE, (q15_t)0x6251, (q15_t)0x51F5, + (q15_t)0x6231, (q15_t)0x521C, (q15_t)0x6211, (q15_t)0x5242, + (q15_t)0x61F1, (q15_t)0x5269, (q15_t)0x61D0, (q15_t)0x528F, + (q15_t)0x61B0, (q15_t)0x52B5, (q15_t)0x618F, (q15_t)0x52DC, + (q15_t)0x616F, (q15_t)0x5302, (q15_t)0x614E, (q15_t)0x5328, + (q15_t)0x612D, (q15_t)0x534E, (q15_t)0x610D, (q15_t)0x5375, + (q15_t)0x60EC, (q15_t)0x539B, (q15_t)0x60CB, (q15_t)0x53C1, + (q15_t)0x60AA, (q15_t)0x53E7, (q15_t)0x6089, (q15_t)0x540D, + (q15_t)0x6068, (q15_t)0x5433, (q15_t)0x6047, (q15_t)0x5458, + (q15_t)0x6026, (q15_t)0x547E, (q15_t)0x6004, (q15_t)0x54A4, + (q15_t)0x5FE3, (q15_t)0x54CA, (q15_t)0x5FC2, (q15_t)0x54EF, + (q15_t)0x5FA0, (q15_t)0x5515, (q15_t)0x5F7F, (q15_t)0x553A, + (q15_t)0x5F5E, (q15_t)0x5560, (q15_t)0x5F3C, (q15_t)0x5585, + (q15_t)0x5F1A, (q15_t)0x55AB, (q15_t)0x5EF9, (q15_t)0x55D0, + (q15_t)0x5ED7, (q15_t)0x55F5, (q15_t)0x5EB5, (q15_t)0x561A, + (q15_t)0x5E93, (q15_t)0x5640, (q15_t)0x5E71, (q15_t)0x5665, + (q15_t)0x5E50, (q15_t)0x568A, (q15_t)0x5E2D, (q15_t)0x56AF, + (q15_t)0x5E0B, (q15_t)0x56D4, (q15_t)0x5DE9, (q15_t)0x56F9, + (q15_t)0x5DC7, (q15_t)0x571D, (q15_t)0x5DA5, (q15_t)0x5742, + (q15_t)0x5D83, (q15_t)0x5767, (q15_t)0x5D60, (q15_t)0x578C, + (q15_t)0x5D3E, (q15_t)0x57B0, (q15_t)0x5D1B, (q15_t)0x57D5, + (q15_t)0x5CF9, (q15_t)0x57F9, (q15_t)0x5CD6, (q15_t)0x581E, + (q15_t)0x5CB4, (q15_t)0x5842, (q15_t)0x5C91, (q15_t)0x5867, + (q15_t)0x5C6E, (q15_t)0x588B, (q15_t)0x5C4B, (q15_t)0x58AF, + (q15_t)0x5C29, (q15_t)0x58D4, (q15_t)0x5C06, (q15_t)0x58F8, + (q15_t)0x5BE3, (q15_t)0x591C, (q15_t)0x5BC0, (q15_t)0x5940, + (q15_t)0x5B9D, (q15_t)0x5964, (q15_t)0x5B79, (q15_t)0x5988, + (q15_t)0x5B56, (q15_t)0x59AC, (q15_t)0x5B33, (q15_t)0x59D0, + (q15_t)0x5B10, (q15_t)0x59F3, (q15_t)0x5AEC, (q15_t)0x5A17, + (q15_t)0x5AC9, (q15_t)0x5A3B, (q15_t)0x5AA5, (q15_t)0x5A5E, + (q15_t)0x5A82, (q15_t)0x5A82, (q15_t)0x5A5E, (q15_t)0x5AA5, + (q15_t)0x5A3B, (q15_t)0x5AC9, (q15_t)0x5A17, (q15_t)0x5AEC, + (q15_t)0x59F3, (q15_t)0x5B10, (q15_t)0x59D0, (q15_t)0x5B33, + (q15_t)0x59AC, (q15_t)0x5B56, (q15_t)0x5988, (q15_t)0x5B79, + (q15_t)0x5964, (q15_t)0x5B9D, (q15_t)0x5940, (q15_t)0x5BC0, + (q15_t)0x591C, (q15_t)0x5BE3, (q15_t)0x58F8, (q15_t)0x5C06, + (q15_t)0x58D4, (q15_t)0x5C29, (q15_t)0x58AF, (q15_t)0x5C4B, + (q15_t)0x588B, (q15_t)0x5C6E, (q15_t)0x5867, (q15_t)0x5C91, + (q15_t)0x5842, (q15_t)0x5CB4, (q15_t)0x581E, (q15_t)0x5CD6, + (q15_t)0x57F9, (q15_t)0x5CF9, (q15_t)0x57D5, (q15_t)0x5D1B, + (q15_t)0x57B0, (q15_t)0x5D3E, (q15_t)0x578C, (q15_t)0x5D60, + (q15_t)0x5767, (q15_t)0x5D83, (q15_t)0x5742, (q15_t)0x5DA5, + (q15_t)0x571D, (q15_t)0x5DC7, (q15_t)0x56F9, (q15_t)0x5DE9, + (q15_t)0x56D4, (q15_t)0x5E0B, (q15_t)0x56AF, (q15_t)0x5E2D, + (q15_t)0x568A, (q15_t)0x5E50, (q15_t)0x5665, (q15_t)0x5E71, + (q15_t)0x5640, (q15_t)0x5E93, (q15_t)0x561A, (q15_t)0x5EB5, + (q15_t)0x55F5, (q15_t)0x5ED7, (q15_t)0x55D0, (q15_t)0x5EF9, + (q15_t)0x55AB, (q15_t)0x5F1A, (q15_t)0x5585, (q15_t)0x5F3C, + (q15_t)0x5560, (q15_t)0x5F5E, (q15_t)0x553A, (q15_t)0x5F7F, + (q15_t)0x5515, (q15_t)0x5FA0, (q15_t)0x54EF, (q15_t)0x5FC2, + (q15_t)0x54CA, (q15_t)0x5FE3, (q15_t)0x54A4, (q15_t)0x6004, + (q15_t)0x547E, (q15_t)0x6026, (q15_t)0x5458, (q15_t)0x6047, + (q15_t)0x5433, (q15_t)0x6068, (q15_t)0x540D, (q15_t)0x6089, + (q15_t)0x53E7, (q15_t)0x60AA, (q15_t)0x53C1, (q15_t)0x60CB, + (q15_t)0x539B, (q15_t)0x60EC, (q15_t)0x5375, (q15_t)0x610D, + (q15_t)0x534E, (q15_t)0x612D, (q15_t)0x5328, (q15_t)0x614E, + (q15_t)0x5302, (q15_t)0x616F, (q15_t)0x52DC, (q15_t)0x618F, + (q15_t)0x52B5, (q15_t)0x61B0, (q15_t)0x528F, (q15_t)0x61D0, + (q15_t)0x5269, (q15_t)0x61F1, (q15_t)0x5242, (q15_t)0x6211, + (q15_t)0x521C, (q15_t)0x6231, (q15_t)0x51F5, (q15_t)0x6251, + (q15_t)0x51CE, (q15_t)0x6271, (q15_t)0x51A8, (q15_t)0x6292, + (q15_t)0x5181, (q15_t)0x62B2, (q15_t)0x515A, (q15_t)0x62D2, + (q15_t)0x5133, (q15_t)0x62F2, (q15_t)0x510C, (q15_t)0x6311, + (q15_t)0x50E5, (q15_t)0x6331, (q15_t)0x50BF, (q15_t)0x6351, + (q15_t)0x5097, (q15_t)0x6371, (q15_t)0x5070, (q15_t)0x6390, + (q15_t)0x5049, (q15_t)0x63B0, (q15_t)0x5022, (q15_t)0x63CF, + (q15_t)0x4FFB, (q15_t)0x63EF, (q15_t)0x4FD4, (q15_t)0x640E, + (q15_t)0x4FAC, (q15_t)0x642D, (q15_t)0x4F85, (q15_t)0x644D, + (q15_t)0x4F5E, (q15_t)0x646C, (q15_t)0x4F36, (q15_t)0x648B, + (q15_t)0x4F0F, (q15_t)0x64AA, (q15_t)0x4EE7, (q15_t)0x64C9, + (q15_t)0x4EBF, (q15_t)0x64E8, (q15_t)0x4E98, (q15_t)0x6507, + (q15_t)0x4E70, (q15_t)0x6526, (q15_t)0x4E48, (q15_t)0x6545, + (q15_t)0x4E21, (q15_t)0x6563, (q15_t)0x4DF9, (q15_t)0x6582, + (q15_t)0x4DD1, (q15_t)0x65A0, (q15_t)0x4DA9, (q15_t)0x65BF, + (q15_t)0x4D81, (q15_t)0x65DD, (q15_t)0x4D59, (q15_t)0x65FC, + (q15_t)0x4D31, (q15_t)0x661A, (q15_t)0x4D09, (q15_t)0x6639, + (q15_t)0x4CE1, (q15_t)0x6657, (q15_t)0x4CB8, (q15_t)0x6675, + (q15_t)0x4C90, (q15_t)0x6693, (q15_t)0x4C68, (q15_t)0x66B1, + (q15_t)0x4C3F, (q15_t)0x66CF, (q15_t)0x4C17, (q15_t)0x66ED, + (q15_t)0x4BEF, (q15_t)0x670B, (q15_t)0x4BC6, (q15_t)0x6729, + (q15_t)0x4B9E, (q15_t)0x6746, (q15_t)0x4B75, (q15_t)0x6764, + (q15_t)0x4B4C, (q15_t)0x6782, (q15_t)0x4B24, (q15_t)0x679F, + (q15_t)0x4AFB, (q15_t)0x67BD, (q15_t)0x4AD2, (q15_t)0x67DA, + (q15_t)0x4AA9, (q15_t)0x67F7, (q15_t)0x4A81, (q15_t)0x6815, + (q15_t)0x4A58, (q15_t)0x6832, (q15_t)0x4A2F, (q15_t)0x684F, + (q15_t)0x4A06, (q15_t)0x686C, (q15_t)0x49DD, (q15_t)0x6889, + (q15_t)0x49B4, (q15_t)0x68A6, (q15_t)0x498A, (q15_t)0x68C3, + (q15_t)0x4961, (q15_t)0x68E0, (q15_t)0x4938, (q15_t)0x68FD, + (q15_t)0x490F, (q15_t)0x6919, (q15_t)0x48E6, (q15_t)0x6936, + (q15_t)0x48BC, (q15_t)0x6953, (q15_t)0x4893, (q15_t)0x696F, + (q15_t)0x4869, (q15_t)0x698C, (q15_t)0x4840, (q15_t)0x69A8, + (q15_t)0x4816, (q15_t)0x69C4, (q15_t)0x47ED, (q15_t)0x69E1, + (q15_t)0x47C3, (q15_t)0x69FD, (q15_t)0x479A, (q15_t)0x6A19, + (q15_t)0x4770, (q15_t)0x6A35, (q15_t)0x4746, (q15_t)0x6A51, + (q15_t)0x471C, (q15_t)0x6A6D, (q15_t)0x46F3, (q15_t)0x6A89, + (q15_t)0x46C9, (q15_t)0x6AA5, (q15_t)0x469F, (q15_t)0x6AC1, + (q15_t)0x4675, (q15_t)0x6ADC, (q15_t)0x464B, (q15_t)0x6AF8, + (q15_t)0x4621, (q15_t)0x6B13, (q15_t)0x45F7, (q15_t)0x6B2F, + (q15_t)0x45CD, (q15_t)0x6B4A, (q15_t)0x45A3, (q15_t)0x6B66, + (q15_t)0x4578, (q15_t)0x6B81, (q15_t)0x454E, (q15_t)0x6B9C, + (q15_t)0x4524, (q15_t)0x6BB8, (q15_t)0x44FA, (q15_t)0x6BD3, + (q15_t)0x44CF, (q15_t)0x6BEE, (q15_t)0x44A5, (q15_t)0x6C09, + (q15_t)0x447A, (q15_t)0x6C24, (q15_t)0x4450, (q15_t)0x6C3F, + (q15_t)0x4425, (q15_t)0x6C59, (q15_t)0x43FB, (q15_t)0x6C74, + (q15_t)0x43D0, (q15_t)0x6C8F, (q15_t)0x43A5, (q15_t)0x6CA9, + (q15_t)0x437B, (q15_t)0x6CC4, (q15_t)0x4350, (q15_t)0x6CDE, + (q15_t)0x4325, (q15_t)0x6CF9, (q15_t)0x42FA, (q15_t)0x6D13, + (q15_t)0x42D0, (q15_t)0x6D2D, (q15_t)0x42A5, (q15_t)0x6D48, + (q15_t)0x427A, (q15_t)0x6D62, (q15_t)0x424F, (q15_t)0x6D7C, + (q15_t)0x4224, (q15_t)0x6D96, (q15_t)0x41F9, (q15_t)0x6DB0, + (q15_t)0x41CE, (q15_t)0x6DCA, (q15_t)0x41A2, (q15_t)0x6DE3, + (q15_t)0x4177, (q15_t)0x6DFD, (q15_t)0x414C, (q15_t)0x6E17, + (q15_t)0x4121, (q15_t)0x6E30, (q15_t)0x40F6, (q15_t)0x6E4A, + (q15_t)0x40CA, (q15_t)0x6E63, (q15_t)0x409F, (q15_t)0x6E7D, + (q15_t)0x4073, (q15_t)0x6E96, (q15_t)0x4048, (q15_t)0x6EAF, + (q15_t)0x401D, (q15_t)0x6EC9, (q15_t)0x3FF1, (q15_t)0x6EE2, + (q15_t)0x3FC5, (q15_t)0x6EFB, (q15_t)0x3F9A, (q15_t)0x6F14, + (q15_t)0x3F6E, (q15_t)0x6F2D, (q15_t)0x3F43, (q15_t)0x6F46, + (q15_t)0x3F17, (q15_t)0x6F5F, (q15_t)0x3EEB, (q15_t)0x6F77, + (q15_t)0x3EBF, (q15_t)0x6F90, (q15_t)0x3E93, (q15_t)0x6FA9, + (q15_t)0x3E68, (q15_t)0x6FC1, (q15_t)0x3E3C, (q15_t)0x6FDA, + (q15_t)0x3E10, (q15_t)0x6FF2, (q15_t)0x3DE4, (q15_t)0x700A, + (q15_t)0x3DB8, (q15_t)0x7023, (q15_t)0x3D8C, (q15_t)0x703B, + (q15_t)0x3D60, (q15_t)0x7053, (q15_t)0x3D33, (q15_t)0x706B, + (q15_t)0x3D07, (q15_t)0x7083, (q15_t)0x3CDB, (q15_t)0x709B, + (q15_t)0x3CAF, (q15_t)0x70B3, (q15_t)0x3C83, (q15_t)0x70CB, + (q15_t)0x3C56, (q15_t)0x70E2, (q15_t)0x3C2A, (q15_t)0x70FA, + (q15_t)0x3BFD, (q15_t)0x7112, (q15_t)0x3BD1, (q15_t)0x7129, + (q15_t)0x3BA5, (q15_t)0x7141, (q15_t)0x3B78, (q15_t)0x7158, + (q15_t)0x3B4C, (q15_t)0x716F, (q15_t)0x3B1F, (q15_t)0x7186, + (q15_t)0x3AF2, (q15_t)0x719E, (q15_t)0x3AC6, (q15_t)0x71B5, + (q15_t)0x3A99, (q15_t)0x71CC, (q15_t)0x3A6C, (q15_t)0x71E3, + (q15_t)0x3A40, (q15_t)0x71FA, (q15_t)0x3A13, (q15_t)0x7211, + (q15_t)0x39E6, (q15_t)0x7227, (q15_t)0x39B9, (q15_t)0x723E, + (q15_t)0x398C, (q15_t)0x7255, (q15_t)0x395F, (q15_t)0x726B, + (q15_t)0x3932, (q15_t)0x7282, (q15_t)0x3906, (q15_t)0x7298, + (q15_t)0x38D8, (q15_t)0x72AF, (q15_t)0x38AB, (q15_t)0x72C5, + (q15_t)0x387E, (q15_t)0x72DB, (q15_t)0x3851, (q15_t)0x72F1, + (q15_t)0x3824, (q15_t)0x7307, (q15_t)0x37F7, (q15_t)0x731D, + (q15_t)0x37CA, (q15_t)0x7333, (q15_t)0x379C, (q15_t)0x7349, + (q15_t)0x376F, (q15_t)0x735F, (q15_t)0x3742, (q15_t)0x7375, + (q15_t)0x3714, (q15_t)0x738A, (q15_t)0x36E7, (q15_t)0x73A0, + (q15_t)0x36BA, (q15_t)0x73B5, (q15_t)0x368C, (q15_t)0x73CB, + (q15_t)0x365F, (q15_t)0x73E0, (q15_t)0x3631, (q15_t)0x73F6, + (q15_t)0x3604, (q15_t)0x740B, (q15_t)0x35D6, (q15_t)0x7420, + (q15_t)0x35A8, (q15_t)0x7435, (q15_t)0x357B, (q15_t)0x744A, + (q15_t)0x354D, (q15_t)0x745F, (q15_t)0x351F, (q15_t)0x7474, + (q15_t)0x34F2, (q15_t)0x7489, (q15_t)0x34C4, (q15_t)0x749E, + (q15_t)0x3496, (q15_t)0x74B2, (q15_t)0x3468, (q15_t)0x74C7, + (q15_t)0x343A, (q15_t)0x74DB, (q15_t)0x340C, (q15_t)0x74F0, + (q15_t)0x33DE, (q15_t)0x7504, (q15_t)0x33B0, (q15_t)0x7519, + (q15_t)0x3382, (q15_t)0x752D, (q15_t)0x3354, (q15_t)0x7541, + (q15_t)0x3326, (q15_t)0x7555, (q15_t)0x32F8, (q15_t)0x7569, + (q15_t)0x32CA, (q15_t)0x757D, (q15_t)0x329C, (q15_t)0x7591, + (q15_t)0x326E, (q15_t)0x75A5, (q15_t)0x3240, (q15_t)0x75B9, + (q15_t)0x3211, (q15_t)0x75CC, (q15_t)0x31E3, (q15_t)0x75E0, + (q15_t)0x31B5, (q15_t)0x75F4, (q15_t)0x3186, (q15_t)0x7607, + (q15_t)0x3158, (q15_t)0x761B, (q15_t)0x312A, (q15_t)0x762E, + (q15_t)0x30FB, (q15_t)0x7641, (q15_t)0x30CD, (q15_t)0x7654, + (q15_t)0x309E, (q15_t)0x7668, (q15_t)0x3070, (q15_t)0x767B, + (q15_t)0x3041, (q15_t)0x768E, (q15_t)0x3013, (q15_t)0x76A0, + (q15_t)0x2FE4, (q15_t)0x76B3, (q15_t)0x2FB5, (q15_t)0x76C6, + (q15_t)0x2F87, (q15_t)0x76D9, (q15_t)0x2F58, (q15_t)0x76EB, + (q15_t)0x2F29, (q15_t)0x76FE, (q15_t)0x2EFB, (q15_t)0x7710, + (q15_t)0x2ECC, (q15_t)0x7723, (q15_t)0x2E9D, (q15_t)0x7735, + (q15_t)0x2E6E, (q15_t)0x7747, (q15_t)0x2E3F, (q15_t)0x775A, + (q15_t)0x2E11, (q15_t)0x776C, (q15_t)0x2DE2, (q15_t)0x777E, + (q15_t)0x2DB3, (q15_t)0x7790, (q15_t)0x2D84, (q15_t)0x77A2, + (q15_t)0x2D55, (q15_t)0x77B4, (q15_t)0x2D26, (q15_t)0x77C5, + (q15_t)0x2CF7, (q15_t)0x77D7, (q15_t)0x2CC8, (q15_t)0x77E9, + (q15_t)0x2C98, (q15_t)0x77FA, (q15_t)0x2C69, (q15_t)0x780C, + (q15_t)0x2C3A, (q15_t)0x781D, (q15_t)0x2C0B, (q15_t)0x782E, + (q15_t)0x2BDC, (q15_t)0x7840, (q15_t)0x2BAD, (q15_t)0x7851, + (q15_t)0x2B7D, (q15_t)0x7862, (q15_t)0x2B4E, (q15_t)0x7873, + (q15_t)0x2B1F, (q15_t)0x7884, (q15_t)0x2AEF, (q15_t)0x7895, + (q15_t)0x2AC0, (q15_t)0x78A6, (q15_t)0x2A91, (q15_t)0x78B6, + (q15_t)0x2A61, (q15_t)0x78C7, (q15_t)0x2A32, (q15_t)0x78D8, + (q15_t)0x2A02, (q15_t)0x78E8, (q15_t)0x29D3, (q15_t)0x78F9, + (q15_t)0x29A3, (q15_t)0x7909, (q15_t)0x2974, (q15_t)0x7919, + (q15_t)0x2944, (q15_t)0x792A, (q15_t)0x2915, (q15_t)0x793A, + (q15_t)0x28E5, (q15_t)0x794A, (q15_t)0x28B5, (q15_t)0x795A, + (q15_t)0x2886, (q15_t)0x796A, (q15_t)0x2856, (q15_t)0x797A, + (q15_t)0x2826, (q15_t)0x798A, (q15_t)0x27F6, (q15_t)0x7999, + (q15_t)0x27C7, (q15_t)0x79A9, (q15_t)0x2797, (q15_t)0x79B9, + (q15_t)0x2767, (q15_t)0x79C8, (q15_t)0x2737, (q15_t)0x79D8, + (q15_t)0x2707, (q15_t)0x79E7, (q15_t)0x26D8, (q15_t)0x79F6, + (q15_t)0x26A8, (q15_t)0x7A05, (q15_t)0x2678, (q15_t)0x7A15, + (q15_t)0x2648, (q15_t)0x7A24, (q15_t)0x2618, (q15_t)0x7A33, + (q15_t)0x25E8, (q15_t)0x7A42, (q15_t)0x25B8, (q15_t)0x7A50, + (q15_t)0x2588, (q15_t)0x7A5F, (q15_t)0x2558, (q15_t)0x7A6E, + (q15_t)0x2528, (q15_t)0x7A7D, (q15_t)0x24F7, (q15_t)0x7A8B, + (q15_t)0x24C7, (q15_t)0x7A9A, (q15_t)0x2497, (q15_t)0x7AA8, + (q15_t)0x2467, (q15_t)0x7AB6, (q15_t)0x2437, (q15_t)0x7AC5, + (q15_t)0x2407, (q15_t)0x7AD3, (q15_t)0x23D6, (q15_t)0x7AE1, + (q15_t)0x23A6, (q15_t)0x7AEF, (q15_t)0x2376, (q15_t)0x7AFD, + (q15_t)0x2345, (q15_t)0x7B0B, (q15_t)0x2315, (q15_t)0x7B19, + (q15_t)0x22E5, (q15_t)0x7B26, (q15_t)0x22B4, (q15_t)0x7B34, + (q15_t)0x2284, (q15_t)0x7B42, (q15_t)0x2254, (q15_t)0x7B4F, + (q15_t)0x2223, (q15_t)0x7B5D, (q15_t)0x21F3, (q15_t)0x7B6A, + (q15_t)0x21C2, (q15_t)0x7B77, (q15_t)0x2192, (q15_t)0x7B84, + (q15_t)0x2161, (q15_t)0x7B92, (q15_t)0x2131, (q15_t)0x7B9F, + (q15_t)0x2100, (q15_t)0x7BAC, (q15_t)0x20D0, (q15_t)0x7BB9, + (q15_t)0x209F, (q15_t)0x7BC5, (q15_t)0x206E, (q15_t)0x7BD2, + (q15_t)0x203E, (q15_t)0x7BDF, (q15_t)0x200D, (q15_t)0x7BEB, + (q15_t)0x1FDC, (q15_t)0x7BF8, (q15_t)0x1FAC, (q15_t)0x7C05, + (q15_t)0x1F7B, (q15_t)0x7C11, (q15_t)0x1F4A, (q15_t)0x7C1D, + (q15_t)0x1F19, (q15_t)0x7C29, (q15_t)0x1EE9, (q15_t)0x7C36, + (q15_t)0x1EB8, (q15_t)0x7C42, (q15_t)0x1E87, (q15_t)0x7C4E, + (q15_t)0x1E56, (q15_t)0x7C5A, (q15_t)0x1E25, (q15_t)0x7C66, + (q15_t)0x1DF5, (q15_t)0x7C71, (q15_t)0x1DC4, (q15_t)0x7C7D, + (q15_t)0x1D93, (q15_t)0x7C89, (q15_t)0x1D62, (q15_t)0x7C94, + (q15_t)0x1D31, (q15_t)0x7CA0, (q15_t)0x1D00, (q15_t)0x7CAB, + (q15_t)0x1CCF, (q15_t)0x7CB7, (q15_t)0x1C9E, (q15_t)0x7CC2, + (q15_t)0x1C6D, (q15_t)0x7CCD, (q15_t)0x1C3C, (q15_t)0x7CD8, + (q15_t)0x1C0B, (q15_t)0x7CE3, (q15_t)0x1BDA, (q15_t)0x7CEE, + (q15_t)0x1BA9, (q15_t)0x7CF9, (q15_t)0x1B78, (q15_t)0x7D04, + (q15_t)0x1B47, (q15_t)0x7D0F, (q15_t)0x1B16, (q15_t)0x7D19, + (q15_t)0x1AE4, (q15_t)0x7D24, (q15_t)0x1AB3, (q15_t)0x7D2F, + (q15_t)0x1A82, (q15_t)0x7D39, (q15_t)0x1A51, (q15_t)0x7D43, + (q15_t)0x1A20, (q15_t)0x7D4E, (q15_t)0x19EF, (q15_t)0x7D58, + (q15_t)0x19BD, (q15_t)0x7D62, (q15_t)0x198C, (q15_t)0x7D6C, + (q15_t)0x195B, (q15_t)0x7D76, (q15_t)0x192A, (q15_t)0x7D80, + (q15_t)0x18F8, (q15_t)0x7D8A, (q15_t)0x18C7, (q15_t)0x7D94, + (q15_t)0x1896, (q15_t)0x7D9D, (q15_t)0x1864, (q15_t)0x7DA7, + (q15_t)0x1833, (q15_t)0x7DB0, (q15_t)0x1802, (q15_t)0x7DBA, + (q15_t)0x17D0, (q15_t)0x7DC3, (q15_t)0x179F, (q15_t)0x7DCD, + (q15_t)0x176D, (q15_t)0x7DD6, (q15_t)0x173C, (q15_t)0x7DDF, + (q15_t)0x170A, (q15_t)0x7DE8, (q15_t)0x16D9, (q15_t)0x7DF1, + (q15_t)0x16A8, (q15_t)0x7DFA, (q15_t)0x1676, (q15_t)0x7E03, + (q15_t)0x1645, (q15_t)0x7E0C, (q15_t)0x1613, (q15_t)0x7E14, + (q15_t)0x15E2, (q15_t)0x7E1D, (q15_t)0x15B0, (q15_t)0x7E26, + (q15_t)0x157F, (q15_t)0x7E2E, (q15_t)0x154D, (q15_t)0x7E37, + (q15_t)0x151B, (q15_t)0x7E3F, (q15_t)0x14EA, (q15_t)0x7E47, + (q15_t)0x14B8, (q15_t)0x7E4F, (q15_t)0x1487, (q15_t)0x7E57, + (q15_t)0x1455, (q15_t)0x7E5F, (q15_t)0x1423, (q15_t)0x7E67, + (q15_t)0x13F2, (q15_t)0x7E6F, (q15_t)0x13C0, (q15_t)0x7E77, + (q15_t)0x138E, (q15_t)0x7E7F, (q15_t)0x135D, (q15_t)0x7E86, + (q15_t)0x132B, (q15_t)0x7E8E, (q15_t)0x12F9, (q15_t)0x7E95, + (q15_t)0x12C8, (q15_t)0x7E9D, (q15_t)0x1296, (q15_t)0x7EA4, + (q15_t)0x1264, (q15_t)0x7EAB, (q15_t)0x1232, (q15_t)0x7EB3, + (q15_t)0x1201, (q15_t)0x7EBA, (q15_t)0x11CF, (q15_t)0x7EC1, + (q15_t)0x119D, (q15_t)0x7EC8, (q15_t)0x116B, (q15_t)0x7ECF, + (q15_t)0x1139, (q15_t)0x7ED5, (q15_t)0x1108, (q15_t)0x7EDC, + (q15_t)0x10D6, (q15_t)0x7EE3, (q15_t)0x10A4, (q15_t)0x7EE9, + (q15_t)0x1072, (q15_t)0x7EF0, (q15_t)0x1040, (q15_t)0x7EF6, + (q15_t)0x100E, (q15_t)0x7EFD, (q15_t)0x0FDD, (q15_t)0x7F03, + (q15_t)0x0FAB, (q15_t)0x7F09, (q15_t)0x0F79, (q15_t)0x7F0F, + (q15_t)0x0F47, (q15_t)0x7F15, (q15_t)0x0F15, (q15_t)0x7F1B, + (q15_t)0x0EE3, (q15_t)0x7F21, (q15_t)0x0EB1, (q15_t)0x7F27, + (q15_t)0x0E7F, (q15_t)0x7F2D, (q15_t)0x0E4D, (q15_t)0x7F32, + (q15_t)0x0E1B, (q15_t)0x7F38, (q15_t)0x0DE9, (q15_t)0x7F3D, + (q15_t)0x0DB7, (q15_t)0x7F43, (q15_t)0x0D85, (q15_t)0x7F48, + (q15_t)0x0D53, (q15_t)0x7F4D, (q15_t)0x0D21, (q15_t)0x7F53, + (q15_t)0x0CEF, (q15_t)0x7F58, (q15_t)0x0CBD, (q15_t)0x7F5D, + (q15_t)0x0C8B, (q15_t)0x7F62, (q15_t)0x0C59, (q15_t)0x7F67, + (q15_t)0x0C27, (q15_t)0x7F6B, (q15_t)0x0BF5, (q15_t)0x7F70, + (q15_t)0x0BC3, (q15_t)0x7F75, (q15_t)0x0B91, (q15_t)0x7F79, + (q15_t)0x0B5F, (q15_t)0x7F7E, (q15_t)0x0B2D, (q15_t)0x7F82, + (q15_t)0x0AFB, (q15_t)0x7F87, (q15_t)0x0AC9, (q15_t)0x7F8B, + (q15_t)0x0A97, (q15_t)0x7F8F, (q15_t)0x0A65, (q15_t)0x7F93, + (q15_t)0x0A33, (q15_t)0x7F97, (q15_t)0x0A00, (q15_t)0x7F9B, + (q15_t)0x09CE, (q15_t)0x7F9F, (q15_t)0x099C, (q15_t)0x7FA3, + (q15_t)0x096A, (q15_t)0x7FA7, (q15_t)0x0938, (q15_t)0x7FAA, + (q15_t)0x0906, (q15_t)0x7FAE, (q15_t)0x08D4, (q15_t)0x7FB1, + (q15_t)0x08A2, (q15_t)0x7FB5, (q15_t)0x086F, (q15_t)0x7FB8, + (q15_t)0x083D, (q15_t)0x7FBC, (q15_t)0x080B, (q15_t)0x7FBF, + (q15_t)0x07D9, (q15_t)0x7FC2, (q15_t)0x07A7, (q15_t)0x7FC5, + (q15_t)0x0775, (q15_t)0x7FC8, (q15_t)0x0742, (q15_t)0x7FCB, + (q15_t)0x0710, (q15_t)0x7FCE, (q15_t)0x06DE, (q15_t)0x7FD0, + (q15_t)0x06AC, (q15_t)0x7FD3, (q15_t)0x067A, (q15_t)0x7FD6, + (q15_t)0x0647, (q15_t)0x7FD8, (q15_t)0x0615, (q15_t)0x7FDA, + (q15_t)0x05E3, (q15_t)0x7FDD, (q15_t)0x05B1, (q15_t)0x7FDF, + (q15_t)0x057F, (q15_t)0x7FE1, (q15_t)0x054C, (q15_t)0x7FE3, + (q15_t)0x051A, (q15_t)0x7FE5, (q15_t)0x04E8, (q15_t)0x7FE7, + (q15_t)0x04B6, (q15_t)0x7FE9, (q15_t)0x0483, (q15_t)0x7FEB, + (q15_t)0x0451, (q15_t)0x7FED, (q15_t)0x041F, (q15_t)0x7FEE, + (q15_t)0x03ED, (q15_t)0x7FF0, (q15_t)0x03BA, (q15_t)0x7FF2, + (q15_t)0x0388, (q15_t)0x7FF3, (q15_t)0x0356, (q15_t)0x7FF4, + (q15_t)0x0324, (q15_t)0x7FF6, (q15_t)0x02F1, (q15_t)0x7FF7, + (q15_t)0x02BF, (q15_t)0x7FF8, (q15_t)0x028D, (q15_t)0x7FF9, + (q15_t)0x025B, (q15_t)0x7FFA, (q15_t)0x0228, (q15_t)0x7FFB, + (q15_t)0x01F6, (q15_t)0x7FFC, (q15_t)0x01C4, (q15_t)0x7FFC, + (q15_t)0x0192, (q15_t)0x7FFD, (q15_t)0x015F, (q15_t)0x7FFE, + (q15_t)0x012D, (q15_t)0x7FFE, (q15_t)0x00FB, (q15_t)0x7FFF, + (q15_t)0x00C9, (q15_t)0x7FFF, (q15_t)0x0096, (q15_t)0x7FFF, + (q15_t)0x0064, (q15_t)0x7FFF, (q15_t)0x0032, (q15_t)0x7FFF, + (q15_t)0x0000, (q15_t)0x7FFF, (q15_t)0xFFCD, (q15_t)0x7FFF, + (q15_t)0xFF9B, (q15_t)0x7FFF, (q15_t)0xFF69, (q15_t)0x7FFF, + (q15_t)0xFF36, (q15_t)0x7FFF, (q15_t)0xFF04, (q15_t)0x7FFF, + (q15_t)0xFED2, (q15_t)0x7FFE, (q15_t)0xFEA0, (q15_t)0x7FFE, + (q15_t)0xFE6D, (q15_t)0x7FFD, (q15_t)0xFE3B, (q15_t)0x7FFC, + (q15_t)0xFE09, (q15_t)0x7FFC, (q15_t)0xFDD7, (q15_t)0x7FFB, + (q15_t)0xFDA4, (q15_t)0x7FFA, (q15_t)0xFD72, (q15_t)0x7FF9, + (q15_t)0xFD40, (q15_t)0x7FF8, (q15_t)0xFD0E, (q15_t)0x7FF7, + (q15_t)0xFCDB, (q15_t)0x7FF6, (q15_t)0xFCA9, (q15_t)0x7FF4, + (q15_t)0xFC77, (q15_t)0x7FF3, (q15_t)0xFC45, (q15_t)0x7FF2, + (q15_t)0xFC12, (q15_t)0x7FF0, (q15_t)0xFBE0, (q15_t)0x7FEE, + (q15_t)0xFBAE, (q15_t)0x7FED, (q15_t)0xFB7C, (q15_t)0x7FEB, + (q15_t)0xFB49, (q15_t)0x7FE9, (q15_t)0xFB17, (q15_t)0x7FE7, + (q15_t)0xFAE5, (q15_t)0x7FE5, (q15_t)0xFAB3, (q15_t)0x7FE3, + (q15_t)0xFA80, (q15_t)0x7FE1, (q15_t)0xFA4E, (q15_t)0x7FDF, + (q15_t)0xFA1C, (q15_t)0x7FDD, (q15_t)0xF9EA, (q15_t)0x7FDA, + (q15_t)0xF9B8, (q15_t)0x7FD8, (q15_t)0xF985, (q15_t)0x7FD6, + (q15_t)0xF953, (q15_t)0x7FD3, (q15_t)0xF921, (q15_t)0x7FD0, + (q15_t)0xF8EF, (q15_t)0x7FCE, (q15_t)0xF8BD, (q15_t)0x7FCB, + (q15_t)0xF88A, (q15_t)0x7FC8, (q15_t)0xF858, (q15_t)0x7FC5, + (q15_t)0xF826, (q15_t)0x7FC2, (q15_t)0xF7F4, (q15_t)0x7FBF, + (q15_t)0xF7C2, (q15_t)0x7FBC, (q15_t)0xF790, (q15_t)0x7FB8, + (q15_t)0xF75D, (q15_t)0x7FB5, (q15_t)0xF72B, (q15_t)0x7FB1, + (q15_t)0xF6F9, (q15_t)0x7FAE, (q15_t)0xF6C7, (q15_t)0x7FAA, + (q15_t)0xF695, (q15_t)0x7FA7, (q15_t)0xF663, (q15_t)0x7FA3, + (q15_t)0xF631, (q15_t)0x7F9F, (q15_t)0xF5FF, (q15_t)0x7F9B, + (q15_t)0xF5CC, (q15_t)0x7F97, (q15_t)0xF59A, (q15_t)0x7F93, + (q15_t)0xF568, (q15_t)0x7F8F, (q15_t)0xF536, (q15_t)0x7F8B, + (q15_t)0xF504, (q15_t)0x7F87, (q15_t)0xF4D2, (q15_t)0x7F82, + (q15_t)0xF4A0, (q15_t)0x7F7E, (q15_t)0xF46E, (q15_t)0x7F79, + (q15_t)0xF43C, (q15_t)0x7F75, (q15_t)0xF40A, (q15_t)0x7F70, + (q15_t)0xF3D8, (q15_t)0x7F6B, (q15_t)0xF3A6, (q15_t)0x7F67, + (q15_t)0xF374, (q15_t)0x7F62, (q15_t)0xF342, (q15_t)0x7F5D, + (q15_t)0xF310, (q15_t)0x7F58, (q15_t)0xF2DE, (q15_t)0x7F53, + (q15_t)0xF2AC, (q15_t)0x7F4D, (q15_t)0xF27A, (q15_t)0x7F48, + (q15_t)0xF248, (q15_t)0x7F43, (q15_t)0xF216, (q15_t)0x7F3D, + (q15_t)0xF1E4, (q15_t)0x7F38, (q15_t)0xF1B2, (q15_t)0x7F32, + (q15_t)0xF180, (q15_t)0x7F2D, (q15_t)0xF14E, (q15_t)0x7F27, + (q15_t)0xF11C, (q15_t)0x7F21, (q15_t)0xF0EA, (q15_t)0x7F1B, + (q15_t)0xF0B8, (q15_t)0x7F15, (q15_t)0xF086, (q15_t)0x7F0F, + (q15_t)0xF054, (q15_t)0x7F09, (q15_t)0xF022, (q15_t)0x7F03, + (q15_t)0xEFF1, (q15_t)0x7EFD, (q15_t)0xEFBF, (q15_t)0x7EF6, + (q15_t)0xEF8D, (q15_t)0x7EF0, (q15_t)0xEF5B, (q15_t)0x7EE9, + (q15_t)0xEF29, (q15_t)0x7EE3, (q15_t)0xEEF7, (q15_t)0x7EDC, + (q15_t)0xEEC6, (q15_t)0x7ED5, (q15_t)0xEE94, (q15_t)0x7ECF, + (q15_t)0xEE62, (q15_t)0x7EC8, (q15_t)0xEE30, (q15_t)0x7EC1, + (q15_t)0xEDFE, (q15_t)0x7EBA, (q15_t)0xEDCD, (q15_t)0x7EB3, + (q15_t)0xED9B, (q15_t)0x7EAB, (q15_t)0xED69, (q15_t)0x7EA4, + (q15_t)0xED37, (q15_t)0x7E9D, (q15_t)0xED06, (q15_t)0x7E95, + (q15_t)0xECD4, (q15_t)0x7E8E, (q15_t)0xECA2, (q15_t)0x7E86, + (q15_t)0xEC71, (q15_t)0x7E7F, (q15_t)0xEC3F, (q15_t)0x7E77, + (q15_t)0xEC0D, (q15_t)0x7E6F, (q15_t)0xEBDC, (q15_t)0x7E67, + (q15_t)0xEBAA, (q15_t)0x7E5F, (q15_t)0xEB78, (q15_t)0x7E57, + (q15_t)0xEB47, (q15_t)0x7E4F, (q15_t)0xEB15, (q15_t)0x7E47, + (q15_t)0xEAE4, (q15_t)0x7E3F, (q15_t)0xEAB2, (q15_t)0x7E37, + (q15_t)0xEA80, (q15_t)0x7E2E, (q15_t)0xEA4F, (q15_t)0x7E26, + (q15_t)0xEA1D, (q15_t)0x7E1D, (q15_t)0xE9EC, (q15_t)0x7E14, + (q15_t)0xE9BA, (q15_t)0x7E0C, (q15_t)0xE989, (q15_t)0x7E03, + (q15_t)0xE957, (q15_t)0x7DFA, (q15_t)0xE926, (q15_t)0x7DF1, + (q15_t)0xE8F5, (q15_t)0x7DE8, (q15_t)0xE8C3, (q15_t)0x7DDF, + (q15_t)0xE892, (q15_t)0x7DD6, (q15_t)0xE860, (q15_t)0x7DCD, + (q15_t)0xE82F, (q15_t)0x7DC3, (q15_t)0xE7FD, (q15_t)0x7DBA, + (q15_t)0xE7CC, (q15_t)0x7DB0, (q15_t)0xE79B, (q15_t)0x7DA7, + (q15_t)0xE769, (q15_t)0x7D9D, (q15_t)0xE738, (q15_t)0x7D94, + (q15_t)0xE707, (q15_t)0x7D8A, (q15_t)0xE6D5, (q15_t)0x7D80, + (q15_t)0xE6A4, (q15_t)0x7D76, (q15_t)0xE673, (q15_t)0x7D6C, + (q15_t)0xE642, (q15_t)0x7D62, (q15_t)0xE610, (q15_t)0x7D58, + (q15_t)0xE5DF, (q15_t)0x7D4E, (q15_t)0xE5AE, (q15_t)0x7D43, + (q15_t)0xE57D, (q15_t)0x7D39, (q15_t)0xE54C, (q15_t)0x7D2F, + (q15_t)0xE51B, (q15_t)0x7D24, (q15_t)0xE4E9, (q15_t)0x7D19, + (q15_t)0xE4B8, (q15_t)0x7D0F, (q15_t)0xE487, (q15_t)0x7D04, + (q15_t)0xE456, (q15_t)0x7CF9, (q15_t)0xE425, (q15_t)0x7CEE, + (q15_t)0xE3F4, (q15_t)0x7CE3, (q15_t)0xE3C3, (q15_t)0x7CD8, + (q15_t)0xE392, (q15_t)0x7CCD, (q15_t)0xE361, (q15_t)0x7CC2, + (q15_t)0xE330, (q15_t)0x7CB7, (q15_t)0xE2FF, (q15_t)0x7CAB, + (q15_t)0xE2CE, (q15_t)0x7CA0, (q15_t)0xE29D, (q15_t)0x7C94, + (q15_t)0xE26C, (q15_t)0x7C89, (q15_t)0xE23B, (q15_t)0x7C7D, + (q15_t)0xE20A, (q15_t)0x7C71, (q15_t)0xE1DA, (q15_t)0x7C66, + (q15_t)0xE1A9, (q15_t)0x7C5A, (q15_t)0xE178, (q15_t)0x7C4E, + (q15_t)0xE147, (q15_t)0x7C42, (q15_t)0xE116, (q15_t)0x7C36, + (q15_t)0xE0E6, (q15_t)0x7C29, (q15_t)0xE0B5, (q15_t)0x7C1D, + (q15_t)0xE084, (q15_t)0x7C11, (q15_t)0xE053, (q15_t)0x7C05, + (q15_t)0xE023, (q15_t)0x7BF8, (q15_t)0xDFF2, (q15_t)0x7BEB, + (q15_t)0xDFC1, (q15_t)0x7BDF, (q15_t)0xDF91, (q15_t)0x7BD2, + (q15_t)0xDF60, (q15_t)0x7BC5, (q15_t)0xDF2F, (q15_t)0x7BB9, + (q15_t)0xDEFF, (q15_t)0x7BAC, (q15_t)0xDECE, (q15_t)0x7B9F, + (q15_t)0xDE9E, (q15_t)0x7B92, (q15_t)0xDE6D, (q15_t)0x7B84, + (q15_t)0xDE3D, (q15_t)0x7B77, (q15_t)0xDE0C, (q15_t)0x7B6A, + (q15_t)0xDDDC, (q15_t)0x7B5D, (q15_t)0xDDAB, (q15_t)0x7B4F, + (q15_t)0xDD7B, (q15_t)0x7B42, (q15_t)0xDD4B, (q15_t)0x7B34, + (q15_t)0xDD1A, (q15_t)0x7B26, (q15_t)0xDCEA, (q15_t)0x7B19, + (q15_t)0xDCBA, (q15_t)0x7B0B, (q15_t)0xDC89, (q15_t)0x7AFD, + (q15_t)0xDC59, (q15_t)0x7AEF, (q15_t)0xDC29, (q15_t)0x7AE1, + (q15_t)0xDBF8, (q15_t)0x7AD3, (q15_t)0xDBC8, (q15_t)0x7AC5, + (q15_t)0xDB98, (q15_t)0x7AB6, (q15_t)0xDB68, (q15_t)0x7AA8, + (q15_t)0xDB38, (q15_t)0x7A9A, (q15_t)0xDB08, (q15_t)0x7A8B, + (q15_t)0xDAD7, (q15_t)0x7A7D, (q15_t)0xDAA7, (q15_t)0x7A6E, + (q15_t)0xDA77, (q15_t)0x7A5F, (q15_t)0xDA47, (q15_t)0x7A50, + (q15_t)0xDA17, (q15_t)0x7A42, (q15_t)0xD9E7, (q15_t)0x7A33, + (q15_t)0xD9B7, (q15_t)0x7A24, (q15_t)0xD987, (q15_t)0x7A15, + (q15_t)0xD957, (q15_t)0x7A05, (q15_t)0xD927, (q15_t)0x79F6, + (q15_t)0xD8F8, (q15_t)0x79E7, (q15_t)0xD8C8, (q15_t)0x79D8, + (q15_t)0xD898, (q15_t)0x79C8, (q15_t)0xD868, (q15_t)0x79B9, + (q15_t)0xD838, (q15_t)0x79A9, (q15_t)0xD809, (q15_t)0x7999, + (q15_t)0xD7D9, (q15_t)0x798A, (q15_t)0xD7A9, (q15_t)0x797A, + (q15_t)0xD779, (q15_t)0x796A, (q15_t)0xD74A, (q15_t)0x795A, + (q15_t)0xD71A, (q15_t)0x794A, (q15_t)0xD6EA, (q15_t)0x793A, + (q15_t)0xD6BB, (q15_t)0x792A, (q15_t)0xD68B, (q15_t)0x7919, + (q15_t)0xD65C, (q15_t)0x7909, (q15_t)0xD62C, (q15_t)0x78F9, + (q15_t)0xD5FD, (q15_t)0x78E8, (q15_t)0xD5CD, (q15_t)0x78D8, + (q15_t)0xD59E, (q15_t)0x78C7, (q15_t)0xD56E, (q15_t)0x78B6, + (q15_t)0xD53F, (q15_t)0x78A6, (q15_t)0xD510, (q15_t)0x7895, + (q15_t)0xD4E0, (q15_t)0x7884, (q15_t)0xD4B1, (q15_t)0x7873, + (q15_t)0xD482, (q15_t)0x7862, (q15_t)0xD452, (q15_t)0x7851, + (q15_t)0xD423, (q15_t)0x7840, (q15_t)0xD3F4, (q15_t)0x782E, + (q15_t)0xD3C5, (q15_t)0x781D, (q15_t)0xD396, (q15_t)0x780C, + (q15_t)0xD367, (q15_t)0x77FA, (q15_t)0xD337, (q15_t)0x77E9, + (q15_t)0xD308, (q15_t)0x77D7, (q15_t)0xD2D9, (q15_t)0x77C5, + (q15_t)0xD2AA, (q15_t)0x77B4, (q15_t)0xD27B, (q15_t)0x77A2, + (q15_t)0xD24C, (q15_t)0x7790, (q15_t)0xD21D, (q15_t)0x777E, + (q15_t)0xD1EE, (q15_t)0x776C, (q15_t)0xD1C0, (q15_t)0x775A, + (q15_t)0xD191, (q15_t)0x7747, (q15_t)0xD162, (q15_t)0x7735, + (q15_t)0xD133, (q15_t)0x7723, (q15_t)0xD104, (q15_t)0x7710, + (q15_t)0xD0D6, (q15_t)0x76FE, (q15_t)0xD0A7, (q15_t)0x76EB, + (q15_t)0xD078, (q15_t)0x76D9, (q15_t)0xD04A, (q15_t)0x76C6, + (q15_t)0xD01B, (q15_t)0x76B3, (q15_t)0xCFEC, (q15_t)0x76A0, + (q15_t)0xCFBE, (q15_t)0x768E, (q15_t)0xCF8F, (q15_t)0x767B, + (q15_t)0xCF61, (q15_t)0x7668, (q15_t)0xCF32, (q15_t)0x7654, + (q15_t)0xCF04, (q15_t)0x7641, (q15_t)0xCED5, (q15_t)0x762E, + (q15_t)0xCEA7, (q15_t)0x761B, (q15_t)0xCE79, (q15_t)0x7607, + (q15_t)0xCE4A, (q15_t)0x75F4, (q15_t)0xCE1C, (q15_t)0x75E0, + (q15_t)0xCDEE, (q15_t)0x75CC, (q15_t)0xCDBF, (q15_t)0x75B9, + (q15_t)0xCD91, (q15_t)0x75A5, (q15_t)0xCD63, (q15_t)0x7591, + (q15_t)0xCD35, (q15_t)0x757D, (q15_t)0xCD07, (q15_t)0x7569, + (q15_t)0xCCD9, (q15_t)0x7555, (q15_t)0xCCAB, (q15_t)0x7541, + (q15_t)0xCC7D, (q15_t)0x752D, (q15_t)0xCC4F, (q15_t)0x7519, + (q15_t)0xCC21, (q15_t)0x7504, (q15_t)0xCBF3, (q15_t)0x74F0, + (q15_t)0xCBC5, (q15_t)0x74DB, (q15_t)0xCB97, (q15_t)0x74C7, + (q15_t)0xCB69, (q15_t)0x74B2, (q15_t)0xCB3B, (q15_t)0x749E, + (q15_t)0xCB0D, (q15_t)0x7489, (q15_t)0xCAE0, (q15_t)0x7474, + (q15_t)0xCAB2, (q15_t)0x745F, (q15_t)0xCA84, (q15_t)0x744A, + (q15_t)0xCA57, (q15_t)0x7435, (q15_t)0xCA29, (q15_t)0x7420, + (q15_t)0xC9FB, (q15_t)0x740B, (q15_t)0xC9CE, (q15_t)0x73F6, + (q15_t)0xC9A0, (q15_t)0x73E0, (q15_t)0xC973, (q15_t)0x73CB, + (q15_t)0xC945, (q15_t)0x73B5, (q15_t)0xC918, (q15_t)0x73A0, + (q15_t)0xC8EB, (q15_t)0x738A, (q15_t)0xC8BD, (q15_t)0x7375, + (q15_t)0xC890, (q15_t)0x735F, (q15_t)0xC863, (q15_t)0x7349, + (q15_t)0xC835, (q15_t)0x7333, (q15_t)0xC808, (q15_t)0x731D, + (q15_t)0xC7DB, (q15_t)0x7307, (q15_t)0xC7AE, (q15_t)0x72F1, + (q15_t)0xC781, (q15_t)0x72DB, (q15_t)0xC754, (q15_t)0x72C5, + (q15_t)0xC727, (q15_t)0x72AF, (q15_t)0xC6F9, (q15_t)0x7298, + (q15_t)0xC6CD, (q15_t)0x7282, (q15_t)0xC6A0, (q15_t)0x726B, + (q15_t)0xC673, (q15_t)0x7255, (q15_t)0xC646, (q15_t)0x723E, + (q15_t)0xC619, (q15_t)0x7227, (q15_t)0xC5EC, (q15_t)0x7211, + (q15_t)0xC5BF, (q15_t)0x71FA, (q15_t)0xC593, (q15_t)0x71E3, + (q15_t)0xC566, (q15_t)0x71CC, (q15_t)0xC539, (q15_t)0x71B5, + (q15_t)0xC50D, (q15_t)0x719E, (q15_t)0xC4E0, (q15_t)0x7186, + (q15_t)0xC4B3, (q15_t)0x716F, (q15_t)0xC487, (q15_t)0x7158, + (q15_t)0xC45A, (q15_t)0x7141, (q15_t)0xC42E, (q15_t)0x7129, + (q15_t)0xC402, (q15_t)0x7112, (q15_t)0xC3D5, (q15_t)0x70FA, + (q15_t)0xC3A9, (q15_t)0x70E2, (q15_t)0xC37C, (q15_t)0x70CB, + (q15_t)0xC350, (q15_t)0x70B3, (q15_t)0xC324, (q15_t)0x709B, + (q15_t)0xC2F8, (q15_t)0x7083, (q15_t)0xC2CC, (q15_t)0x706B, + (q15_t)0xC29F, (q15_t)0x7053, (q15_t)0xC273, (q15_t)0x703B, + (q15_t)0xC247, (q15_t)0x7023, (q15_t)0xC21B, (q15_t)0x700A, + (q15_t)0xC1EF, (q15_t)0x6FF2, (q15_t)0xC1C3, (q15_t)0x6FDA, + (q15_t)0xC197, (q15_t)0x6FC1, (q15_t)0xC16C, (q15_t)0x6FA9, + (q15_t)0xC140, (q15_t)0x6F90, (q15_t)0xC114, (q15_t)0x6F77, + (q15_t)0xC0E8, (q15_t)0x6F5F, (q15_t)0xC0BC, (q15_t)0x6F46, + (q15_t)0xC091, (q15_t)0x6F2D, (q15_t)0xC065, (q15_t)0x6F14, + (q15_t)0xC03A, (q15_t)0x6EFB, (q15_t)0xC00E, (q15_t)0x6EE2, + (q15_t)0xBFE2, (q15_t)0x6EC9, (q15_t)0xBFB7, (q15_t)0x6EAF, + (q15_t)0xBF8C, (q15_t)0x6E96, (q15_t)0xBF60, (q15_t)0x6E7D, + (q15_t)0xBF35, (q15_t)0x6E63, (q15_t)0xBF09, (q15_t)0x6E4A, + (q15_t)0xBEDE, (q15_t)0x6E30, (q15_t)0xBEB3, (q15_t)0x6E17, + (q15_t)0xBE88, (q15_t)0x6DFD, (q15_t)0xBE5D, (q15_t)0x6DE3, + (q15_t)0xBE31, (q15_t)0x6DCA, (q15_t)0xBE06, (q15_t)0x6DB0, + (q15_t)0xBDDB, (q15_t)0x6D96, (q15_t)0xBDB0, (q15_t)0x6D7C, + (q15_t)0xBD85, (q15_t)0x6D62, (q15_t)0xBD5A, (q15_t)0x6D48, + (q15_t)0xBD2F, (q15_t)0x6D2D, (q15_t)0xBD05, (q15_t)0x6D13, + (q15_t)0xBCDA, (q15_t)0x6CF9, (q15_t)0xBCAF, (q15_t)0x6CDE, + (q15_t)0xBC84, (q15_t)0x6CC4, (q15_t)0xBC5A, (q15_t)0x6CA9, + (q15_t)0xBC2F, (q15_t)0x6C8F, (q15_t)0xBC04, (q15_t)0x6C74, + (q15_t)0xBBDA, (q15_t)0x6C59, (q15_t)0xBBAF, (q15_t)0x6C3F, + (q15_t)0xBB85, (q15_t)0x6C24, (q15_t)0xBB5A, (q15_t)0x6C09, + (q15_t)0xBB30, (q15_t)0x6BEE, (q15_t)0xBB05, (q15_t)0x6BD3, + (q15_t)0xBADB, (q15_t)0x6BB8, (q15_t)0xBAB1, (q15_t)0x6B9C, + (q15_t)0xBA87, (q15_t)0x6B81, (q15_t)0xBA5C, (q15_t)0x6B66, + (q15_t)0xBA32, (q15_t)0x6B4A, (q15_t)0xBA08, (q15_t)0x6B2F, + (q15_t)0xB9DE, (q15_t)0x6B13, (q15_t)0xB9B4, (q15_t)0x6AF8, + (q15_t)0xB98A, (q15_t)0x6ADC, (q15_t)0xB960, (q15_t)0x6AC1, + (q15_t)0xB936, (q15_t)0x6AA5, (q15_t)0xB90C, (q15_t)0x6A89, + (q15_t)0xB8E3, (q15_t)0x6A6D, (q15_t)0xB8B9, (q15_t)0x6A51, + (q15_t)0xB88F, (q15_t)0x6A35, (q15_t)0xB865, (q15_t)0x6A19, + (q15_t)0xB83C, (q15_t)0x69FD, (q15_t)0xB812, (q15_t)0x69E1, + (q15_t)0xB7E9, (q15_t)0x69C4, (q15_t)0xB7BF, (q15_t)0x69A8, + (q15_t)0xB796, (q15_t)0x698C, (q15_t)0xB76C, (q15_t)0x696F, + (q15_t)0xB743, (q15_t)0x6953, (q15_t)0xB719, (q15_t)0x6936, + (q15_t)0xB6F0, (q15_t)0x6919, (q15_t)0xB6C7, (q15_t)0x68FD, + (q15_t)0xB69E, (q15_t)0x68E0, (q15_t)0xB675, (q15_t)0x68C3, + (q15_t)0xB64B, (q15_t)0x68A6, (q15_t)0xB622, (q15_t)0x6889, + (q15_t)0xB5F9, (q15_t)0x686C, (q15_t)0xB5D0, (q15_t)0x684F, + (q15_t)0xB5A7, (q15_t)0x6832, (q15_t)0xB57E, (q15_t)0x6815, + (q15_t)0xB556, (q15_t)0x67F7, (q15_t)0xB52D, (q15_t)0x67DA, + (q15_t)0xB504, (q15_t)0x67BD, (q15_t)0xB4DB, (q15_t)0x679F, + (q15_t)0xB4B3, (q15_t)0x6782, (q15_t)0xB48A, (q15_t)0x6764, + (q15_t)0xB461, (q15_t)0x6746, (q15_t)0xB439, (q15_t)0x6729, + (q15_t)0xB410, (q15_t)0x670B, (q15_t)0xB3E8, (q15_t)0x66ED, + (q15_t)0xB3C0, (q15_t)0x66CF, (q15_t)0xB397, (q15_t)0x66B1, + (q15_t)0xB36F, (q15_t)0x6693, (q15_t)0xB347, (q15_t)0x6675, + (q15_t)0xB31E, (q15_t)0x6657, (q15_t)0xB2F6, (q15_t)0x6639, + (q15_t)0xB2CE, (q15_t)0x661A, (q15_t)0xB2A6, (q15_t)0x65FC, + (q15_t)0xB27E, (q15_t)0x65DD, (q15_t)0xB256, (q15_t)0x65BF, + (q15_t)0xB22E, (q15_t)0x65A0, (q15_t)0xB206, (q15_t)0x6582, + (q15_t)0xB1DE, (q15_t)0x6563, (q15_t)0xB1B7, (q15_t)0x6545, + (q15_t)0xB18F, (q15_t)0x6526, (q15_t)0xB167, (q15_t)0x6507, + (q15_t)0xB140, (q15_t)0x64E8, (q15_t)0xB118, (q15_t)0x64C9, + (q15_t)0xB0F0, (q15_t)0x64AA, (q15_t)0xB0C9, (q15_t)0x648B, + (q15_t)0xB0A1, (q15_t)0x646C, (q15_t)0xB07A, (q15_t)0x644D, + (q15_t)0xB053, (q15_t)0x642D, (q15_t)0xB02B, (q15_t)0x640E, + (q15_t)0xB004, (q15_t)0x63EF, (q15_t)0xAFDD, (q15_t)0x63CF, + (q15_t)0xAFB6, (q15_t)0x63B0, (q15_t)0xAF8F, (q15_t)0x6390, + (q15_t)0xAF68, (q15_t)0x6371, (q15_t)0xAF40, (q15_t)0x6351, + (q15_t)0xAF1A, (q15_t)0x6331, (q15_t)0xAEF3, (q15_t)0x6311, + (q15_t)0xAECC, (q15_t)0x62F2, (q15_t)0xAEA5, (q15_t)0x62D2, + (q15_t)0xAE7E, (q15_t)0x62B2, (q15_t)0xAE57, (q15_t)0x6292, + (q15_t)0xAE31, (q15_t)0x6271, (q15_t)0xAE0A, (q15_t)0x6251, + (q15_t)0xADE3, (q15_t)0x6231, (q15_t)0xADBD, (q15_t)0x6211, + (q15_t)0xAD96, (q15_t)0x61F1, (q15_t)0xAD70, (q15_t)0x61D0, + (q15_t)0xAD4A, (q15_t)0x61B0, (q15_t)0xAD23, (q15_t)0x618F, + (q15_t)0xACFD, (q15_t)0x616F, (q15_t)0xACD7, (q15_t)0x614E, + (q15_t)0xACB1, (q15_t)0x612D, (q15_t)0xAC8A, (q15_t)0x610D, + (q15_t)0xAC64, (q15_t)0x60EC, (q15_t)0xAC3E, (q15_t)0x60CB, + (q15_t)0xAC18, (q15_t)0x60AA, (q15_t)0xABF2, (q15_t)0x6089, + (q15_t)0xABCC, (q15_t)0x6068, (q15_t)0xABA7, (q15_t)0x6047, + (q15_t)0xAB81, (q15_t)0x6026, (q15_t)0xAB5B, (q15_t)0x6004, + (q15_t)0xAB35, (q15_t)0x5FE3, (q15_t)0xAB10, (q15_t)0x5FC2, + (q15_t)0xAAEA, (q15_t)0x5FA0, (q15_t)0xAAC5, (q15_t)0x5F7F, + (q15_t)0xAA9F, (q15_t)0x5F5E, (q15_t)0xAA7A, (q15_t)0x5F3C, + (q15_t)0xAA54, (q15_t)0x5F1A, (q15_t)0xAA2F, (q15_t)0x5EF9, + (q15_t)0xAA0A, (q15_t)0x5ED7, (q15_t)0xA9E5, (q15_t)0x5EB5, + (q15_t)0xA9BF, (q15_t)0x5E93, (q15_t)0xA99A, (q15_t)0x5E71, + (q15_t)0xA975, (q15_t)0x5E50, (q15_t)0xA950, (q15_t)0x5E2D, + (q15_t)0xA92B, (q15_t)0x5E0B, (q15_t)0xA906, (q15_t)0x5DE9, + (q15_t)0xA8E2, (q15_t)0x5DC7, (q15_t)0xA8BD, (q15_t)0x5DA5, + (q15_t)0xA898, (q15_t)0x5D83, (q15_t)0xA873, (q15_t)0x5D60, + (q15_t)0xA84F, (q15_t)0x5D3E, (q15_t)0xA82A, (q15_t)0x5D1B, + (q15_t)0xA806, (q15_t)0x5CF9, (q15_t)0xA7E1, (q15_t)0x5CD6, + (q15_t)0xA7BD, (q15_t)0x5CB4, (q15_t)0xA798, (q15_t)0x5C91, + (q15_t)0xA774, (q15_t)0x5C6E, (q15_t)0xA750, (q15_t)0x5C4B, + (q15_t)0xA72B, (q15_t)0x5C29, (q15_t)0xA707, (q15_t)0x5C06, + (q15_t)0xA6E3, (q15_t)0x5BE3, (q15_t)0xA6BF, (q15_t)0x5BC0, + (q15_t)0xA69B, (q15_t)0x5B9D, (q15_t)0xA677, (q15_t)0x5B79, + (q15_t)0xA653, (q15_t)0x5B56, (q15_t)0xA62F, (q15_t)0x5B33, + (q15_t)0xA60C, (q15_t)0x5B10, (q15_t)0xA5E8, (q15_t)0x5AEC, + (q15_t)0xA5C4, (q15_t)0x5AC9, (q15_t)0xA5A1, (q15_t)0x5AA5, + (q15_t)0xA57D, (q15_t)0x5A82, (q15_t)0xA55A, (q15_t)0x5A5E, + (q15_t)0xA536, (q15_t)0x5A3B, (q15_t)0xA513, (q15_t)0x5A17, + (q15_t)0xA4EF, (q15_t)0x59F3, (q15_t)0xA4CC, (q15_t)0x59D0, + (q15_t)0xA4A9, (q15_t)0x59AC, (q15_t)0xA486, (q15_t)0x5988, + (q15_t)0xA462, (q15_t)0x5964, (q15_t)0xA43F, (q15_t)0x5940, + (q15_t)0xA41C, (q15_t)0x591C, (q15_t)0xA3F9, (q15_t)0x58F8, + (q15_t)0xA3D6, (q15_t)0x58D4, (q15_t)0xA3B4, (q15_t)0x58AF, + (q15_t)0xA391, (q15_t)0x588B, (q15_t)0xA36E, (q15_t)0x5867, + (q15_t)0xA34B, (q15_t)0x5842, (q15_t)0xA329, (q15_t)0x581E, + (q15_t)0xA306, (q15_t)0x57F9, (q15_t)0xA2E4, (q15_t)0x57D5, + (q15_t)0xA2C1, (q15_t)0x57B0, (q15_t)0xA29F, (q15_t)0x578C, + (q15_t)0xA27C, (q15_t)0x5767, (q15_t)0xA25A, (q15_t)0x5742, + (q15_t)0xA238, (q15_t)0x571D, (q15_t)0xA216, (q15_t)0x56F9, + (q15_t)0xA1F4, (q15_t)0x56D4, (q15_t)0xA1D2, (q15_t)0x56AF, + (q15_t)0xA1AF, (q15_t)0x568A, (q15_t)0xA18E, (q15_t)0x5665, + (q15_t)0xA16C, (q15_t)0x5640, (q15_t)0xA14A, (q15_t)0x561A, + (q15_t)0xA128, (q15_t)0x55F5, (q15_t)0xA106, (q15_t)0x55D0, + (q15_t)0xA0E5, (q15_t)0x55AB, (q15_t)0xA0C3, (q15_t)0x5585, + (q15_t)0xA0A1, (q15_t)0x5560, (q15_t)0xA080, (q15_t)0x553A, + (q15_t)0xA05F, (q15_t)0x5515, (q15_t)0xA03D, (q15_t)0x54EF, + (q15_t)0xA01C, (q15_t)0x54CA, (q15_t)0x9FFB, (q15_t)0x54A4, + (q15_t)0x9FD9, (q15_t)0x547E, (q15_t)0x9FB8, (q15_t)0x5458, + (q15_t)0x9F97, (q15_t)0x5433, (q15_t)0x9F76, (q15_t)0x540D, + (q15_t)0x9F55, (q15_t)0x53E7, (q15_t)0x9F34, (q15_t)0x53C1, + (q15_t)0x9F13, (q15_t)0x539B, (q15_t)0x9EF2, (q15_t)0x5375, + (q15_t)0x9ED2, (q15_t)0x534E, (q15_t)0x9EB1, (q15_t)0x5328, + (q15_t)0x9E90, (q15_t)0x5302, (q15_t)0x9E70, (q15_t)0x52DC, + (q15_t)0x9E4F, (q15_t)0x52B5, (q15_t)0x9E2F, (q15_t)0x528F, + (q15_t)0x9E0E, (q15_t)0x5269, (q15_t)0x9DEE, (q15_t)0x5242, + (q15_t)0x9DCE, (q15_t)0x521C, (q15_t)0x9DAE, (q15_t)0x51F5, + (q15_t)0x9D8E, (q15_t)0x51CE, (q15_t)0x9D6D, (q15_t)0x51A8, + (q15_t)0x9D4D, (q15_t)0x5181, (q15_t)0x9D2D, (q15_t)0x515A, + (q15_t)0x9D0D, (q15_t)0x5133, (q15_t)0x9CEE, (q15_t)0x510C, + (q15_t)0x9CCE, (q15_t)0x50E5, (q15_t)0x9CAE, (q15_t)0x50BF, + (q15_t)0x9C8E, (q15_t)0x5097, (q15_t)0x9C6F, (q15_t)0x5070, + (q15_t)0x9C4F, (q15_t)0x5049, (q15_t)0x9C30, (q15_t)0x5022, + (q15_t)0x9C10, (q15_t)0x4FFB, (q15_t)0x9BF1, (q15_t)0x4FD4, + (q15_t)0x9BD2, (q15_t)0x4FAC, (q15_t)0x9BB2, (q15_t)0x4F85, + (q15_t)0x9B93, (q15_t)0x4F5E, (q15_t)0x9B74, (q15_t)0x4F36, + (q15_t)0x9B55, (q15_t)0x4F0F, (q15_t)0x9B36, (q15_t)0x4EE7, + (q15_t)0x9B17, (q15_t)0x4EBF, (q15_t)0x9AF8, (q15_t)0x4E98, + (q15_t)0x9AD9, (q15_t)0x4E70, (q15_t)0x9ABA, (q15_t)0x4E48, + (q15_t)0x9A9C, (q15_t)0x4E21, (q15_t)0x9A7D, (q15_t)0x4DF9, + (q15_t)0x9A5F, (q15_t)0x4DD1, (q15_t)0x9A40, (q15_t)0x4DA9, + (q15_t)0x9A22, (q15_t)0x4D81, (q15_t)0x9A03, (q15_t)0x4D59, + (q15_t)0x99E5, (q15_t)0x4D31, (q15_t)0x99C6, (q15_t)0x4D09, + (q15_t)0x99A8, (q15_t)0x4CE1, (q15_t)0x998A, (q15_t)0x4CB8, + (q15_t)0x996C, (q15_t)0x4C90, (q15_t)0x994E, (q15_t)0x4C68, + (q15_t)0x9930, (q15_t)0x4C3F, (q15_t)0x9912, (q15_t)0x4C17, + (q15_t)0x98F4, (q15_t)0x4BEF, (q15_t)0x98D6, (q15_t)0x4BC6, + (q15_t)0x98B9, (q15_t)0x4B9E, (q15_t)0x989B, (q15_t)0x4B75, + (q15_t)0x987D, (q15_t)0x4B4C, (q15_t)0x9860, (q15_t)0x4B24, + (q15_t)0x9842, (q15_t)0x4AFB, (q15_t)0x9825, (q15_t)0x4AD2, + (q15_t)0x9808, (q15_t)0x4AA9, (q15_t)0x97EA, (q15_t)0x4A81, + (q15_t)0x97CD, (q15_t)0x4A58, (q15_t)0x97B0, (q15_t)0x4A2F, + (q15_t)0x9793, (q15_t)0x4A06, (q15_t)0x9776, (q15_t)0x49DD, + (q15_t)0x9759, (q15_t)0x49B4, (q15_t)0x973C, (q15_t)0x498A, + (q15_t)0x971F, (q15_t)0x4961, (q15_t)0x9702, (q15_t)0x4938, + (q15_t)0x96E6, (q15_t)0x490F, (q15_t)0x96C9, (q15_t)0x48E6, + (q15_t)0x96AC, (q15_t)0x48BC, (q15_t)0x9690, (q15_t)0x4893, + (q15_t)0x9673, (q15_t)0x4869, (q15_t)0x9657, (q15_t)0x4840, + (q15_t)0x963B, (q15_t)0x4816, (q15_t)0x961E, (q15_t)0x47ED, + (q15_t)0x9602, (q15_t)0x47C3, (q15_t)0x95E6, (q15_t)0x479A, + (q15_t)0x95CA, (q15_t)0x4770, (q15_t)0x95AE, (q15_t)0x4746, + (q15_t)0x9592, (q15_t)0x471C, (q15_t)0x9576, (q15_t)0x46F3, + (q15_t)0x955A, (q15_t)0x46C9, (q15_t)0x953E, (q15_t)0x469F, + (q15_t)0x9523, (q15_t)0x4675, (q15_t)0x9507, (q15_t)0x464B, + (q15_t)0x94EC, (q15_t)0x4621, (q15_t)0x94D0, (q15_t)0x45F7, + (q15_t)0x94B5, (q15_t)0x45CD, (q15_t)0x9499, (q15_t)0x45A3, + (q15_t)0x947E, (q15_t)0x4578, (q15_t)0x9463, (q15_t)0x454E, + (q15_t)0x9447, (q15_t)0x4524, (q15_t)0x942C, (q15_t)0x44FA, + (q15_t)0x9411, (q15_t)0x44CF, (q15_t)0x93F6, (q15_t)0x44A5, + (q15_t)0x93DB, (q15_t)0x447A, (q15_t)0x93C0, (q15_t)0x4450, + (q15_t)0x93A6, (q15_t)0x4425, (q15_t)0x938B, (q15_t)0x43FB, + (q15_t)0x9370, (q15_t)0x43D0, (q15_t)0x9356, (q15_t)0x43A5, + (q15_t)0x933B, (q15_t)0x437B, (q15_t)0x9321, (q15_t)0x4350, + (q15_t)0x9306, (q15_t)0x4325, (q15_t)0x92EC, (q15_t)0x42FA, + (q15_t)0x92D2, (q15_t)0x42D0, (q15_t)0x92B7, (q15_t)0x42A5, + (q15_t)0x929D, (q15_t)0x427A, (q15_t)0x9283, (q15_t)0x424F, + (q15_t)0x9269, (q15_t)0x4224, (q15_t)0x924F, (q15_t)0x41F9, + (q15_t)0x9235, (q15_t)0x41CE, (q15_t)0x921C, (q15_t)0x41A2, + (q15_t)0x9202, (q15_t)0x4177, (q15_t)0x91E8, (q15_t)0x414C, + (q15_t)0x91CF, (q15_t)0x4121, (q15_t)0x91B5, (q15_t)0x40F6, + (q15_t)0x919C, (q15_t)0x40CA, (q15_t)0x9182, (q15_t)0x409F, + (q15_t)0x9169, (q15_t)0x4073, (q15_t)0x9150, (q15_t)0x4048, + (q15_t)0x9136, (q15_t)0x401D, (q15_t)0x911D, (q15_t)0x3FF1, + (q15_t)0x9104, (q15_t)0x3FC5, (q15_t)0x90EB, (q15_t)0x3F9A, + (q15_t)0x90D2, (q15_t)0x3F6E, (q15_t)0x90B9, (q15_t)0x3F43, + (q15_t)0x90A0, (q15_t)0x3F17, (q15_t)0x9088, (q15_t)0x3EEB, + (q15_t)0x906F, (q15_t)0x3EBF, (q15_t)0x9056, (q15_t)0x3E93, + (q15_t)0x903E, (q15_t)0x3E68, (q15_t)0x9025, (q15_t)0x3E3C, + (q15_t)0x900D, (q15_t)0x3E10, (q15_t)0x8FF5, (q15_t)0x3DE4, + (q15_t)0x8FDC, (q15_t)0x3DB8, (q15_t)0x8FC4, (q15_t)0x3D8C, + (q15_t)0x8FAC, (q15_t)0x3D60, (q15_t)0x8F94, (q15_t)0x3D33, + (q15_t)0x8F7C, (q15_t)0x3D07, (q15_t)0x8F64, (q15_t)0x3CDB, + (q15_t)0x8F4C, (q15_t)0x3CAF, (q15_t)0x8F34, (q15_t)0x3C83, + (q15_t)0x8F1D, (q15_t)0x3C56, (q15_t)0x8F05, (q15_t)0x3C2A, + (q15_t)0x8EED, (q15_t)0x3BFD, (q15_t)0x8ED6, (q15_t)0x3BD1, + (q15_t)0x8EBE, (q15_t)0x3BA5, (q15_t)0x8EA7, (q15_t)0x3B78, + (q15_t)0x8E90, (q15_t)0x3B4C, (q15_t)0x8E79, (q15_t)0x3B1F, + (q15_t)0x8E61, (q15_t)0x3AF2, (q15_t)0x8E4A, (q15_t)0x3AC6, + (q15_t)0x8E33, (q15_t)0x3A99, (q15_t)0x8E1C, (q15_t)0x3A6C, + (q15_t)0x8E05, (q15_t)0x3A40, (q15_t)0x8DEE, (q15_t)0x3A13, + (q15_t)0x8DD8, (q15_t)0x39E6, (q15_t)0x8DC1, (q15_t)0x39B9, + (q15_t)0x8DAA, (q15_t)0x398C, (q15_t)0x8D94, (q15_t)0x395F, + (q15_t)0x8D7D, (q15_t)0x3932, (q15_t)0x8D67, (q15_t)0x3906, + (q15_t)0x8D50, (q15_t)0x38D8, (q15_t)0x8D3A, (q15_t)0x38AB, + (q15_t)0x8D24, (q15_t)0x387E, (q15_t)0x8D0E, (q15_t)0x3851, + (q15_t)0x8CF8, (q15_t)0x3824, (q15_t)0x8CE2, (q15_t)0x37F7, + (q15_t)0x8CCC, (q15_t)0x37CA, (q15_t)0x8CB6, (q15_t)0x379C, + (q15_t)0x8CA0, (q15_t)0x376F, (q15_t)0x8C8A, (q15_t)0x3742, + (q15_t)0x8C75, (q15_t)0x3714, (q15_t)0x8C5F, (q15_t)0x36E7, + (q15_t)0x8C4A, (q15_t)0x36BA, (q15_t)0x8C34, (q15_t)0x368C, + (q15_t)0x8C1F, (q15_t)0x365F, (q15_t)0x8C09, (q15_t)0x3631, + (q15_t)0x8BF4, (q15_t)0x3604, (q15_t)0x8BDF, (q15_t)0x35D6, + (q15_t)0x8BCA, (q15_t)0x35A8, (q15_t)0x8BB5, (q15_t)0x357B, + (q15_t)0x8BA0, (q15_t)0x354D, (q15_t)0x8B8B, (q15_t)0x351F, + (q15_t)0x8B76, (q15_t)0x34F2, (q15_t)0x8B61, (q15_t)0x34C4, + (q15_t)0x8B4D, (q15_t)0x3496, (q15_t)0x8B38, (q15_t)0x3468, + (q15_t)0x8B24, (q15_t)0x343A, (q15_t)0x8B0F, (q15_t)0x340C, + (q15_t)0x8AFB, (q15_t)0x33DE, (q15_t)0x8AE6, (q15_t)0x33B0, + (q15_t)0x8AD2, (q15_t)0x3382, (q15_t)0x8ABE, (q15_t)0x3354, + (q15_t)0x8AAA, (q15_t)0x3326, (q15_t)0x8A96, (q15_t)0x32F8, + (q15_t)0x8A82, (q15_t)0x32CA, (q15_t)0x8A6E, (q15_t)0x329C, + (q15_t)0x8A5A, (q15_t)0x326E, (q15_t)0x8A46, (q15_t)0x3240, + (q15_t)0x8A33, (q15_t)0x3211, (q15_t)0x8A1F, (q15_t)0x31E3, + (q15_t)0x8A0B, (q15_t)0x31B5, (q15_t)0x89F8, (q15_t)0x3186, + (q15_t)0x89E4, (q15_t)0x3158, (q15_t)0x89D1, (q15_t)0x312A, + (q15_t)0x89BE, (q15_t)0x30FB, (q15_t)0x89AB, (q15_t)0x30CD, + (q15_t)0x8997, (q15_t)0x309E, (q15_t)0x8984, (q15_t)0x3070, + (q15_t)0x8971, (q15_t)0x3041, (q15_t)0x895F, (q15_t)0x3013, + (q15_t)0x894C, (q15_t)0x2FE4, (q15_t)0x8939, (q15_t)0x2FB5, + (q15_t)0x8926, (q15_t)0x2F87, (q15_t)0x8914, (q15_t)0x2F58, + (q15_t)0x8901, (q15_t)0x2F29, (q15_t)0x88EF, (q15_t)0x2EFB, + (q15_t)0x88DC, (q15_t)0x2ECC, (q15_t)0x88CA, (q15_t)0x2E9D, + (q15_t)0x88B8, (q15_t)0x2E6E, (q15_t)0x88A5, (q15_t)0x2E3F, + (q15_t)0x8893, (q15_t)0x2E11, (q15_t)0x8881, (q15_t)0x2DE2, + (q15_t)0x886F, (q15_t)0x2DB3, (q15_t)0x885D, (q15_t)0x2D84, + (q15_t)0x884B, (q15_t)0x2D55, (q15_t)0x883A, (q15_t)0x2D26, + (q15_t)0x8828, (q15_t)0x2CF7, (q15_t)0x8816, (q15_t)0x2CC8, + (q15_t)0x8805, (q15_t)0x2C98, (q15_t)0x87F3, (q15_t)0x2C69, + (q15_t)0x87E2, (q15_t)0x2C3A, (q15_t)0x87D1, (q15_t)0x2C0B, + (q15_t)0x87BF, (q15_t)0x2BDC, (q15_t)0x87AE, (q15_t)0x2BAD, + (q15_t)0x879D, (q15_t)0x2B7D, (q15_t)0x878C, (q15_t)0x2B4E, + (q15_t)0x877B, (q15_t)0x2B1F, (q15_t)0x876A, (q15_t)0x2AEF, + (q15_t)0x8759, (q15_t)0x2AC0, (q15_t)0x8749, (q15_t)0x2A91, + (q15_t)0x8738, (q15_t)0x2A61, (q15_t)0x8727, (q15_t)0x2A32, + (q15_t)0x8717, (q15_t)0x2A02, (q15_t)0x8706, (q15_t)0x29D3, + (q15_t)0x86F6, (q15_t)0x29A3, (q15_t)0x86E6, (q15_t)0x2974, + (q15_t)0x86D5, (q15_t)0x2944, (q15_t)0x86C5, (q15_t)0x2915, + (q15_t)0x86B5, (q15_t)0x28E5, (q15_t)0x86A5, (q15_t)0x28B5, + (q15_t)0x8695, (q15_t)0x2886, (q15_t)0x8685, (q15_t)0x2856, + (q15_t)0x8675, (q15_t)0x2826, (q15_t)0x8666, (q15_t)0x27F6, + (q15_t)0x8656, (q15_t)0x27C7, (q15_t)0x8646, (q15_t)0x2797, + (q15_t)0x8637, (q15_t)0x2767, (q15_t)0x8627, (q15_t)0x2737, + (q15_t)0x8618, (q15_t)0x2707, (q15_t)0x8609, (q15_t)0x26D8, + (q15_t)0x85FA, (q15_t)0x26A8, (q15_t)0x85EA, (q15_t)0x2678, + (q15_t)0x85DB, (q15_t)0x2648, (q15_t)0x85CC, (q15_t)0x2618, + (q15_t)0x85BD, (q15_t)0x25E8, (q15_t)0x85AF, (q15_t)0x25B8, + (q15_t)0x85A0, (q15_t)0x2588, (q15_t)0x8591, (q15_t)0x2558, + (q15_t)0x8582, (q15_t)0x2528, (q15_t)0x8574, (q15_t)0x24F7, + (q15_t)0x8565, (q15_t)0x24C7, (q15_t)0x8557, (q15_t)0x2497, + (q15_t)0x8549, (q15_t)0x2467, (q15_t)0x853A, (q15_t)0x2437, + (q15_t)0x852C, (q15_t)0x2407, (q15_t)0x851E, (q15_t)0x23D6, + (q15_t)0x8510, (q15_t)0x23A6, (q15_t)0x8502, (q15_t)0x2376, + (q15_t)0x84F4, (q15_t)0x2345, (q15_t)0x84E6, (q15_t)0x2315, + (q15_t)0x84D9, (q15_t)0x22E5, (q15_t)0x84CB, (q15_t)0x22B4, + (q15_t)0x84BD, (q15_t)0x2284, (q15_t)0x84B0, (q15_t)0x2254, + (q15_t)0x84A2, (q15_t)0x2223, (q15_t)0x8495, (q15_t)0x21F3, + (q15_t)0x8488, (q15_t)0x21C2, (q15_t)0x847B, (q15_t)0x2192, + (q15_t)0x846D, (q15_t)0x2161, (q15_t)0x8460, (q15_t)0x2131, + (q15_t)0x8453, (q15_t)0x2100, (q15_t)0x8446, (q15_t)0x20D0, + (q15_t)0x843A, (q15_t)0x209F, (q15_t)0x842D, (q15_t)0x206E, + (q15_t)0x8420, (q15_t)0x203E, (q15_t)0x8414, (q15_t)0x200D, + (q15_t)0x8407, (q15_t)0x1FDC, (q15_t)0x83FA, (q15_t)0x1FAC, + (q15_t)0x83EE, (q15_t)0x1F7B, (q15_t)0x83E2, (q15_t)0x1F4A, + (q15_t)0x83D6, (q15_t)0x1F19, (q15_t)0x83C9, (q15_t)0x1EE9, + (q15_t)0x83BD, (q15_t)0x1EB8, (q15_t)0x83B1, (q15_t)0x1E87, + (q15_t)0x83A5, (q15_t)0x1E56, (q15_t)0x8399, (q15_t)0x1E25, + (q15_t)0x838E, (q15_t)0x1DF5, (q15_t)0x8382, (q15_t)0x1DC4, + (q15_t)0x8376, (q15_t)0x1D93, (q15_t)0x836B, (q15_t)0x1D62, + (q15_t)0x835F, (q15_t)0x1D31, (q15_t)0x8354, (q15_t)0x1D00, + (q15_t)0x8348, (q15_t)0x1CCF, (q15_t)0x833D, (q15_t)0x1C9E, + (q15_t)0x8332, (q15_t)0x1C6D, (q15_t)0x8327, (q15_t)0x1C3C, + (q15_t)0x831C, (q15_t)0x1C0B, (q15_t)0x8311, (q15_t)0x1BDA, + (q15_t)0x8306, (q15_t)0x1BA9, (q15_t)0x82FB, (q15_t)0x1B78, + (q15_t)0x82F0, (q15_t)0x1B47, (q15_t)0x82E6, (q15_t)0x1B16, + (q15_t)0x82DB, (q15_t)0x1AE4, (q15_t)0x82D0, (q15_t)0x1AB3, + (q15_t)0x82C6, (q15_t)0x1A82, (q15_t)0x82BC, (q15_t)0x1A51, + (q15_t)0x82B1, (q15_t)0x1A20, (q15_t)0x82A7, (q15_t)0x19EF, + (q15_t)0x829D, (q15_t)0x19BD, (q15_t)0x8293, (q15_t)0x198C, + (q15_t)0x8289, (q15_t)0x195B, (q15_t)0x827F, (q15_t)0x192A, + (q15_t)0x8275, (q15_t)0x18F8, (q15_t)0x826B, (q15_t)0x18C7, + (q15_t)0x8262, (q15_t)0x1896, (q15_t)0x8258, (q15_t)0x1864, + (q15_t)0x824F, (q15_t)0x1833, (q15_t)0x8245, (q15_t)0x1802, + (q15_t)0x823C, (q15_t)0x17D0, (q15_t)0x8232, (q15_t)0x179F, + (q15_t)0x8229, (q15_t)0x176D, (q15_t)0x8220, (q15_t)0x173C, + (q15_t)0x8217, (q15_t)0x170A, (q15_t)0x820E, (q15_t)0x16D9, + (q15_t)0x8205, (q15_t)0x16A8, (q15_t)0x81FC, (q15_t)0x1676, + (q15_t)0x81F3, (q15_t)0x1645, (q15_t)0x81EB, (q15_t)0x1613, + (q15_t)0x81E2, (q15_t)0x15E2, (q15_t)0x81D9, (q15_t)0x15B0, + (q15_t)0x81D1, (q15_t)0x157F, (q15_t)0x81C8, (q15_t)0x154D, + (q15_t)0x81C0, (q15_t)0x151B, (q15_t)0x81B8, (q15_t)0x14EA, + (q15_t)0x81B0, (q15_t)0x14B8, (q15_t)0x81A8, (q15_t)0x1487, + (q15_t)0x81A0, (q15_t)0x1455, (q15_t)0x8198, (q15_t)0x1423, + (q15_t)0x8190, (q15_t)0x13F2, (q15_t)0x8188, (q15_t)0x13C0, + (q15_t)0x8180, (q15_t)0x138E, (q15_t)0x8179, (q15_t)0x135D, + (q15_t)0x8171, (q15_t)0x132B, (q15_t)0x816A, (q15_t)0x12F9, + (q15_t)0x8162, (q15_t)0x12C8, (q15_t)0x815B, (q15_t)0x1296, + (q15_t)0x8154, (q15_t)0x1264, (q15_t)0x814C, (q15_t)0x1232, + (q15_t)0x8145, (q15_t)0x1201, (q15_t)0x813E, (q15_t)0x11CF, + (q15_t)0x8137, (q15_t)0x119D, (q15_t)0x8130, (q15_t)0x116B, + (q15_t)0x812A, (q15_t)0x1139, (q15_t)0x8123, (q15_t)0x1108, + (q15_t)0x811C, (q15_t)0x10D6, (q15_t)0x8116, (q15_t)0x10A4, + (q15_t)0x810F, (q15_t)0x1072, (q15_t)0x8109, (q15_t)0x1040, + (q15_t)0x8102, (q15_t)0x100E, (q15_t)0x80FC, (q15_t)0x0FDD, + (q15_t)0x80F6, (q15_t)0x0FAB, (q15_t)0x80F0, (q15_t)0x0F79, + (q15_t)0x80EA, (q15_t)0x0F47, (q15_t)0x80E4, (q15_t)0x0F15, + (q15_t)0x80DE, (q15_t)0x0EE3, (q15_t)0x80D8, (q15_t)0x0EB1, + (q15_t)0x80D2, (q15_t)0x0E7F, (q15_t)0x80CD, (q15_t)0x0E4D, + (q15_t)0x80C7, (q15_t)0x0E1B, (q15_t)0x80C2, (q15_t)0x0DE9, + (q15_t)0x80BC, (q15_t)0x0DB7, (q15_t)0x80B7, (q15_t)0x0D85, + (q15_t)0x80B2, (q15_t)0x0D53, (q15_t)0x80AC, (q15_t)0x0D21, + (q15_t)0x80A7, (q15_t)0x0CEF, (q15_t)0x80A2, (q15_t)0x0CBD, + (q15_t)0x809D, (q15_t)0x0C8B, (q15_t)0x8098, (q15_t)0x0C59, + (q15_t)0x8094, (q15_t)0x0C27, (q15_t)0x808F, (q15_t)0x0BF5, + (q15_t)0x808A, (q15_t)0x0BC3, (q15_t)0x8086, (q15_t)0x0B91, + (q15_t)0x8081, (q15_t)0x0B5F, (q15_t)0x807D, (q15_t)0x0B2D, + (q15_t)0x8078, (q15_t)0x0AFB, (q15_t)0x8074, (q15_t)0x0AC9, + (q15_t)0x8070, (q15_t)0x0A97, (q15_t)0x806C, (q15_t)0x0A65, + (q15_t)0x8068, (q15_t)0x0A33, (q15_t)0x8064, (q15_t)0x0A00, + (q15_t)0x8060, (q15_t)0x09CE, (q15_t)0x805C, (q15_t)0x099C, + (q15_t)0x8058, (q15_t)0x096A, (q15_t)0x8055, (q15_t)0x0938, + (q15_t)0x8051, (q15_t)0x0906, (q15_t)0x804E, (q15_t)0x08D4, + (q15_t)0x804A, (q15_t)0x08A2, (q15_t)0x8047, (q15_t)0x086F, + (q15_t)0x8043, (q15_t)0x083D, (q15_t)0x8040, (q15_t)0x080B, + (q15_t)0x803D, (q15_t)0x07D9, (q15_t)0x803A, (q15_t)0x07A7, + (q15_t)0x8037, (q15_t)0x0775, (q15_t)0x8034, (q15_t)0x0742, + (q15_t)0x8031, (q15_t)0x0710, (q15_t)0x802F, (q15_t)0x06DE, + (q15_t)0x802C, (q15_t)0x06AC, (q15_t)0x8029, (q15_t)0x067A, + (q15_t)0x8027, (q15_t)0x0647, (q15_t)0x8025, (q15_t)0x0615, + (q15_t)0x8022, (q15_t)0x05E3, (q15_t)0x8020, (q15_t)0x05B1, + (q15_t)0x801E, (q15_t)0x057F, (q15_t)0x801C, (q15_t)0x054C, + (q15_t)0x801A, (q15_t)0x051A, (q15_t)0x8018, (q15_t)0x04E8, + (q15_t)0x8016, (q15_t)0x04B6, (q15_t)0x8014, (q15_t)0x0483, + (q15_t)0x8012, (q15_t)0x0451, (q15_t)0x8011, (q15_t)0x041F, + (q15_t)0x800F, (q15_t)0x03ED, (q15_t)0x800D, (q15_t)0x03BA, + (q15_t)0x800C, (q15_t)0x0388, (q15_t)0x800B, (q15_t)0x0356, + (q15_t)0x8009, (q15_t)0x0324, (q15_t)0x8008, (q15_t)0x02F1, + (q15_t)0x8007, (q15_t)0x02BF, (q15_t)0x8006, (q15_t)0x028D, + (q15_t)0x8005, (q15_t)0x025B, (q15_t)0x8004, (q15_t)0x0228, + (q15_t)0x8003, (q15_t)0x01F6, (q15_t)0x8003, (q15_t)0x01C4, + (q15_t)0x8002, (q15_t)0x0192, (q15_t)0x8001, (q15_t)0x015F, + (q15_t)0x8001, (q15_t)0x012D, (q15_t)0x8000, (q15_t)0x00FB, + (q15_t)0x8000, (q15_t)0x00C9, (q15_t)0x8000, (q15_t)0x0096, + (q15_t)0x8000, (q15_t)0x0064, (q15_t)0x8000, (q15_t)0x0032, + (q15_t)0x8000, (q15_t)0x0000, (q15_t)0x8000, (q15_t)0xFFCD, + (q15_t)0x8000, (q15_t)0xFF9B, (q15_t)0x8000, (q15_t)0xFF69, + (q15_t)0x8000, (q15_t)0xFF36, (q15_t)0x8000, (q15_t)0xFF04, + (q15_t)0x8001, (q15_t)0xFED2, (q15_t)0x8001, (q15_t)0xFEA0, + (q15_t)0x8002, (q15_t)0xFE6D, (q15_t)0x8003, (q15_t)0xFE3B, + (q15_t)0x8003, (q15_t)0xFE09, (q15_t)0x8004, (q15_t)0xFDD7, + (q15_t)0x8005, (q15_t)0xFDA4, (q15_t)0x8006, (q15_t)0xFD72, + (q15_t)0x8007, (q15_t)0xFD40, (q15_t)0x8008, (q15_t)0xFD0E, + (q15_t)0x8009, (q15_t)0xFCDB, (q15_t)0x800B, (q15_t)0xFCA9, + (q15_t)0x800C, (q15_t)0xFC77, (q15_t)0x800D, (q15_t)0xFC45, + (q15_t)0x800F, (q15_t)0xFC12, (q15_t)0x8011, (q15_t)0xFBE0, + (q15_t)0x8012, (q15_t)0xFBAE, (q15_t)0x8014, (q15_t)0xFB7C, + (q15_t)0x8016, (q15_t)0xFB49, (q15_t)0x8018, (q15_t)0xFB17, + (q15_t)0x801A, (q15_t)0xFAE5, (q15_t)0x801C, (q15_t)0xFAB3, + (q15_t)0x801E, (q15_t)0xFA80, (q15_t)0x8020, (q15_t)0xFA4E, + (q15_t)0x8022, (q15_t)0xFA1C, (q15_t)0x8025, (q15_t)0xF9EA, + (q15_t)0x8027, (q15_t)0xF9B8, (q15_t)0x8029, (q15_t)0xF985, + (q15_t)0x802C, (q15_t)0xF953, (q15_t)0x802F, (q15_t)0xF921, + (q15_t)0x8031, (q15_t)0xF8EF, (q15_t)0x8034, (q15_t)0xF8BD, + (q15_t)0x8037, (q15_t)0xF88A, (q15_t)0x803A, (q15_t)0xF858, + (q15_t)0x803D, (q15_t)0xF826, (q15_t)0x8040, (q15_t)0xF7F4, + (q15_t)0x8043, (q15_t)0xF7C2, (q15_t)0x8047, (q15_t)0xF790, + (q15_t)0x804A, (q15_t)0xF75D, (q15_t)0x804E, (q15_t)0xF72B, + (q15_t)0x8051, (q15_t)0xF6F9, (q15_t)0x8055, (q15_t)0xF6C7, + (q15_t)0x8058, (q15_t)0xF695, (q15_t)0x805C, (q15_t)0xF663, + (q15_t)0x8060, (q15_t)0xF631, (q15_t)0x8064, (q15_t)0xF5FF, + (q15_t)0x8068, (q15_t)0xF5CC, (q15_t)0x806C, (q15_t)0xF59A, + (q15_t)0x8070, (q15_t)0xF568, (q15_t)0x8074, (q15_t)0xF536, + (q15_t)0x8078, (q15_t)0xF504, (q15_t)0x807D, (q15_t)0xF4D2, + (q15_t)0x8081, (q15_t)0xF4A0, (q15_t)0x8086, (q15_t)0xF46E, + (q15_t)0x808A, (q15_t)0xF43C, (q15_t)0x808F, (q15_t)0xF40A, + (q15_t)0x8094, (q15_t)0xF3D8, (q15_t)0x8098, (q15_t)0xF3A6, + (q15_t)0x809D, (q15_t)0xF374, (q15_t)0x80A2, (q15_t)0xF342, + (q15_t)0x80A7, (q15_t)0xF310, (q15_t)0x80AC, (q15_t)0xF2DE, + (q15_t)0x80B2, (q15_t)0xF2AC, (q15_t)0x80B7, (q15_t)0xF27A, + (q15_t)0x80BC, (q15_t)0xF248, (q15_t)0x80C2, (q15_t)0xF216, + (q15_t)0x80C7, (q15_t)0xF1E4, (q15_t)0x80CD, (q15_t)0xF1B2, + (q15_t)0x80D2, (q15_t)0xF180, (q15_t)0x80D8, (q15_t)0xF14E, + (q15_t)0x80DE, (q15_t)0xF11C, (q15_t)0x80E4, (q15_t)0xF0EA, + (q15_t)0x80EA, (q15_t)0xF0B8, (q15_t)0x80F0, (q15_t)0xF086, + (q15_t)0x80F6, (q15_t)0xF054, (q15_t)0x80FC, (q15_t)0xF022, + (q15_t)0x8102, (q15_t)0xEFF1, (q15_t)0x8109, (q15_t)0xEFBF, + (q15_t)0x810F, (q15_t)0xEF8D, (q15_t)0x8116, (q15_t)0xEF5B, + (q15_t)0x811C, (q15_t)0xEF29, (q15_t)0x8123, (q15_t)0xEEF7, + (q15_t)0x812A, (q15_t)0xEEC6, (q15_t)0x8130, (q15_t)0xEE94, + (q15_t)0x8137, (q15_t)0xEE62, (q15_t)0x813E, (q15_t)0xEE30, + (q15_t)0x8145, (q15_t)0xEDFE, (q15_t)0x814C, (q15_t)0xEDCD, + (q15_t)0x8154, (q15_t)0xED9B, (q15_t)0x815B, (q15_t)0xED69, + (q15_t)0x8162, (q15_t)0xED37, (q15_t)0x816A, (q15_t)0xED06, + (q15_t)0x8171, (q15_t)0xECD4, (q15_t)0x8179, (q15_t)0xECA2, + (q15_t)0x8180, (q15_t)0xEC71, (q15_t)0x8188, (q15_t)0xEC3F, + (q15_t)0x8190, (q15_t)0xEC0D, (q15_t)0x8198, (q15_t)0xEBDC, + (q15_t)0x81A0, (q15_t)0xEBAA, (q15_t)0x81A8, (q15_t)0xEB78, + (q15_t)0x81B0, (q15_t)0xEB47, (q15_t)0x81B8, (q15_t)0xEB15, + (q15_t)0x81C0, (q15_t)0xEAE4, (q15_t)0x81C8, (q15_t)0xEAB2, + (q15_t)0x81D1, (q15_t)0xEA80, (q15_t)0x81D9, (q15_t)0xEA4F, + (q15_t)0x81E2, (q15_t)0xEA1D, (q15_t)0x81EB, (q15_t)0xE9EC, + (q15_t)0x81F3, (q15_t)0xE9BA, (q15_t)0x81FC, (q15_t)0xE989, + (q15_t)0x8205, (q15_t)0xE957, (q15_t)0x820E, (q15_t)0xE926, + (q15_t)0x8217, (q15_t)0xE8F5, (q15_t)0x8220, (q15_t)0xE8C3, + (q15_t)0x8229, (q15_t)0xE892, (q15_t)0x8232, (q15_t)0xE860, + (q15_t)0x823C, (q15_t)0xE82F, (q15_t)0x8245, (q15_t)0xE7FD, + (q15_t)0x824F, (q15_t)0xE7CC, (q15_t)0x8258, (q15_t)0xE79B, + (q15_t)0x8262, (q15_t)0xE769, (q15_t)0x826B, (q15_t)0xE738, + (q15_t)0x8275, (q15_t)0xE707, (q15_t)0x827F, (q15_t)0xE6D5, + (q15_t)0x8289, (q15_t)0xE6A4, (q15_t)0x8293, (q15_t)0xE673, + (q15_t)0x829D, (q15_t)0xE642, (q15_t)0x82A7, (q15_t)0xE610, + (q15_t)0x82B1, (q15_t)0xE5DF, (q15_t)0x82BC, (q15_t)0xE5AE, + (q15_t)0x82C6, (q15_t)0xE57D, (q15_t)0x82D0, (q15_t)0xE54C, + (q15_t)0x82DB, (q15_t)0xE51B, (q15_t)0x82E6, (q15_t)0xE4E9, + (q15_t)0x82F0, (q15_t)0xE4B8, (q15_t)0x82FB, (q15_t)0xE487, + (q15_t)0x8306, (q15_t)0xE456, (q15_t)0x8311, (q15_t)0xE425, + (q15_t)0x831C, (q15_t)0xE3F4, (q15_t)0x8327, (q15_t)0xE3C3, + (q15_t)0x8332, (q15_t)0xE392, (q15_t)0x833D, (q15_t)0xE361, + (q15_t)0x8348, (q15_t)0xE330, (q15_t)0x8354, (q15_t)0xE2FF, + (q15_t)0x835F, (q15_t)0xE2CE, (q15_t)0x836B, (q15_t)0xE29D, + (q15_t)0x8376, (q15_t)0xE26C, (q15_t)0x8382, (q15_t)0xE23B, + (q15_t)0x838E, (q15_t)0xE20A, (q15_t)0x8399, (q15_t)0xE1DA, + (q15_t)0x83A5, (q15_t)0xE1A9, (q15_t)0x83B1, (q15_t)0xE178, + (q15_t)0x83BD, (q15_t)0xE147, (q15_t)0x83C9, (q15_t)0xE116, + (q15_t)0x83D6, (q15_t)0xE0E6, (q15_t)0x83E2, (q15_t)0xE0B5, + (q15_t)0x83EE, (q15_t)0xE084, (q15_t)0x83FA, (q15_t)0xE053, + (q15_t)0x8407, (q15_t)0xE023, (q15_t)0x8414, (q15_t)0xDFF2, + (q15_t)0x8420, (q15_t)0xDFC1, (q15_t)0x842D, (q15_t)0xDF91, + (q15_t)0x843A, (q15_t)0xDF60, (q15_t)0x8446, (q15_t)0xDF2F, + (q15_t)0x8453, (q15_t)0xDEFF, (q15_t)0x8460, (q15_t)0xDECE, + (q15_t)0x846D, (q15_t)0xDE9E, (q15_t)0x847B, (q15_t)0xDE6D, + (q15_t)0x8488, (q15_t)0xDE3D, (q15_t)0x8495, (q15_t)0xDE0C, + (q15_t)0x84A2, (q15_t)0xDDDC, (q15_t)0x84B0, (q15_t)0xDDAB, + (q15_t)0x84BD, (q15_t)0xDD7B, (q15_t)0x84CB, (q15_t)0xDD4B, + (q15_t)0x84D9, (q15_t)0xDD1A, (q15_t)0x84E6, (q15_t)0xDCEA, + (q15_t)0x84F4, (q15_t)0xDCBA, (q15_t)0x8502, (q15_t)0xDC89, + (q15_t)0x8510, (q15_t)0xDC59, (q15_t)0x851E, (q15_t)0xDC29, + (q15_t)0x852C, (q15_t)0xDBF8, (q15_t)0x853A, (q15_t)0xDBC8, + (q15_t)0x8549, (q15_t)0xDB98, (q15_t)0x8557, (q15_t)0xDB68, + (q15_t)0x8565, (q15_t)0xDB38, (q15_t)0x8574, (q15_t)0xDB08, + (q15_t)0x8582, (q15_t)0xDAD7, (q15_t)0x8591, (q15_t)0xDAA7, + (q15_t)0x85A0, (q15_t)0xDA77, (q15_t)0x85AF, (q15_t)0xDA47, + (q15_t)0x85BD, (q15_t)0xDA17, (q15_t)0x85CC, (q15_t)0xD9E7, + (q15_t)0x85DB, (q15_t)0xD9B7, (q15_t)0x85EA, (q15_t)0xD987, + (q15_t)0x85FA, (q15_t)0xD957, (q15_t)0x8609, (q15_t)0xD927, + (q15_t)0x8618, (q15_t)0xD8F8, (q15_t)0x8627, (q15_t)0xD8C8, + (q15_t)0x8637, (q15_t)0xD898, (q15_t)0x8646, (q15_t)0xD868, + (q15_t)0x8656, (q15_t)0xD838, (q15_t)0x8666, (q15_t)0xD809, + (q15_t)0x8675, (q15_t)0xD7D9, (q15_t)0x8685, (q15_t)0xD7A9, + (q15_t)0x8695, (q15_t)0xD779, (q15_t)0x86A5, (q15_t)0xD74A, + (q15_t)0x86B5, (q15_t)0xD71A, (q15_t)0x86C5, (q15_t)0xD6EA, + (q15_t)0x86D5, (q15_t)0xD6BB, (q15_t)0x86E6, (q15_t)0xD68B, + (q15_t)0x86F6, (q15_t)0xD65C, (q15_t)0x8706, (q15_t)0xD62C, + (q15_t)0x8717, (q15_t)0xD5FD, (q15_t)0x8727, (q15_t)0xD5CD, + (q15_t)0x8738, (q15_t)0xD59E, (q15_t)0x8749, (q15_t)0xD56E, + (q15_t)0x8759, (q15_t)0xD53F, (q15_t)0x876A, (q15_t)0xD510, + (q15_t)0x877B, (q15_t)0xD4E0, (q15_t)0x878C, (q15_t)0xD4B1, + (q15_t)0x879D, (q15_t)0xD482, (q15_t)0x87AE, (q15_t)0xD452, + (q15_t)0x87BF, (q15_t)0xD423, (q15_t)0x87D1, (q15_t)0xD3F4, + (q15_t)0x87E2, (q15_t)0xD3C5, (q15_t)0x87F3, (q15_t)0xD396, + (q15_t)0x8805, (q15_t)0xD367, (q15_t)0x8816, (q15_t)0xD337, + (q15_t)0x8828, (q15_t)0xD308, (q15_t)0x883A, (q15_t)0xD2D9, + (q15_t)0x884B, (q15_t)0xD2AA, (q15_t)0x885D, (q15_t)0xD27B, + (q15_t)0x886F, (q15_t)0xD24C, (q15_t)0x8881, (q15_t)0xD21D, + (q15_t)0x8893, (q15_t)0xD1EE, (q15_t)0x88A5, (q15_t)0xD1C0, + (q15_t)0x88B8, (q15_t)0xD191, (q15_t)0x88CA, (q15_t)0xD162, + (q15_t)0x88DC, (q15_t)0xD133, (q15_t)0x88EF, (q15_t)0xD104, + (q15_t)0x8901, (q15_t)0xD0D6, (q15_t)0x8914, (q15_t)0xD0A7, + (q15_t)0x8926, (q15_t)0xD078, (q15_t)0x8939, (q15_t)0xD04A, + (q15_t)0x894C, (q15_t)0xD01B, (q15_t)0x895F, (q15_t)0xCFEC, + (q15_t)0x8971, (q15_t)0xCFBE, (q15_t)0x8984, (q15_t)0xCF8F, + (q15_t)0x8997, (q15_t)0xCF61, (q15_t)0x89AB, (q15_t)0xCF32, + (q15_t)0x89BE, (q15_t)0xCF04, (q15_t)0x89D1, (q15_t)0xCED5, + (q15_t)0x89E4, (q15_t)0xCEA7, (q15_t)0x89F8, (q15_t)0xCE79, + (q15_t)0x8A0B, (q15_t)0xCE4A, (q15_t)0x8A1F, (q15_t)0xCE1C, + (q15_t)0x8A33, (q15_t)0xCDEE, (q15_t)0x8A46, (q15_t)0xCDBF, + (q15_t)0x8A5A, (q15_t)0xCD91, (q15_t)0x8A6E, (q15_t)0xCD63, + (q15_t)0x8A82, (q15_t)0xCD35, (q15_t)0x8A96, (q15_t)0xCD07, + (q15_t)0x8AAA, (q15_t)0xCCD9, (q15_t)0x8ABE, (q15_t)0xCCAB, + (q15_t)0x8AD2, (q15_t)0xCC7D, (q15_t)0x8AE6, (q15_t)0xCC4F, + (q15_t)0x8AFB, (q15_t)0xCC21, (q15_t)0x8B0F, (q15_t)0xCBF3, + (q15_t)0x8B24, (q15_t)0xCBC5, (q15_t)0x8B38, (q15_t)0xCB97, + (q15_t)0x8B4D, (q15_t)0xCB69, (q15_t)0x8B61, (q15_t)0xCB3B, + (q15_t)0x8B76, (q15_t)0xCB0D, (q15_t)0x8B8B, (q15_t)0xCAE0, + (q15_t)0x8BA0, (q15_t)0xCAB2, (q15_t)0x8BB5, (q15_t)0xCA84, + (q15_t)0x8BCA, (q15_t)0xCA57, (q15_t)0x8BDF, (q15_t)0xCA29, + (q15_t)0x8BF4, (q15_t)0xC9FB, (q15_t)0x8C09, (q15_t)0xC9CE, + (q15_t)0x8C1F, (q15_t)0xC9A0, (q15_t)0x8C34, (q15_t)0xC973, + (q15_t)0x8C4A, (q15_t)0xC945, (q15_t)0x8C5F, (q15_t)0xC918, + (q15_t)0x8C75, (q15_t)0xC8EB, (q15_t)0x8C8A, (q15_t)0xC8BD, + (q15_t)0x8CA0, (q15_t)0xC890, (q15_t)0x8CB6, (q15_t)0xC863, + (q15_t)0x8CCC, (q15_t)0xC835, (q15_t)0x8CE2, (q15_t)0xC808, + (q15_t)0x8CF8, (q15_t)0xC7DB, (q15_t)0x8D0E, (q15_t)0xC7AE, + (q15_t)0x8D24, (q15_t)0xC781, (q15_t)0x8D3A, (q15_t)0xC754, + (q15_t)0x8D50, (q15_t)0xC727, (q15_t)0x8D67, (q15_t)0xC6F9, + (q15_t)0x8D7D, (q15_t)0xC6CD, (q15_t)0x8D94, (q15_t)0xC6A0, + (q15_t)0x8DAA, (q15_t)0xC673, (q15_t)0x8DC1, (q15_t)0xC646, + (q15_t)0x8DD8, (q15_t)0xC619, (q15_t)0x8DEE, (q15_t)0xC5EC, + (q15_t)0x8E05, (q15_t)0xC5BF, (q15_t)0x8E1C, (q15_t)0xC593, + (q15_t)0x8E33, (q15_t)0xC566, (q15_t)0x8E4A, (q15_t)0xC539, + (q15_t)0x8E61, (q15_t)0xC50D, (q15_t)0x8E79, (q15_t)0xC4E0, + (q15_t)0x8E90, (q15_t)0xC4B3, (q15_t)0x8EA7, (q15_t)0xC487, + (q15_t)0x8EBE, (q15_t)0xC45A, (q15_t)0x8ED6, (q15_t)0xC42E, + (q15_t)0x8EED, (q15_t)0xC402, (q15_t)0x8F05, (q15_t)0xC3D5, + (q15_t)0x8F1D, (q15_t)0xC3A9, (q15_t)0x8F34, (q15_t)0xC37C, + (q15_t)0x8F4C, (q15_t)0xC350, (q15_t)0x8F64, (q15_t)0xC324, + (q15_t)0x8F7C, (q15_t)0xC2F8, (q15_t)0x8F94, (q15_t)0xC2CC, + (q15_t)0x8FAC, (q15_t)0xC29F, (q15_t)0x8FC4, (q15_t)0xC273, + (q15_t)0x8FDC, (q15_t)0xC247, (q15_t)0x8FF5, (q15_t)0xC21B, + (q15_t)0x900D, (q15_t)0xC1EF, (q15_t)0x9025, (q15_t)0xC1C3, + (q15_t)0x903E, (q15_t)0xC197, (q15_t)0x9056, (q15_t)0xC16C, + (q15_t)0x906F, (q15_t)0xC140, (q15_t)0x9088, (q15_t)0xC114, + (q15_t)0x90A0, (q15_t)0xC0E8, (q15_t)0x90B9, (q15_t)0xC0BC, + (q15_t)0x90D2, (q15_t)0xC091, (q15_t)0x90EB, (q15_t)0xC065, + (q15_t)0x9104, (q15_t)0xC03A, (q15_t)0x911D, (q15_t)0xC00E, + (q15_t)0x9136, (q15_t)0xBFE2, (q15_t)0x9150, (q15_t)0xBFB7, + (q15_t)0x9169, (q15_t)0xBF8C, (q15_t)0x9182, (q15_t)0xBF60, + (q15_t)0x919C, (q15_t)0xBF35, (q15_t)0x91B5, (q15_t)0xBF09, + (q15_t)0x91CF, (q15_t)0xBEDE, (q15_t)0x91E8, (q15_t)0xBEB3, + (q15_t)0x9202, (q15_t)0xBE88, (q15_t)0x921C, (q15_t)0xBE5D, + (q15_t)0x9235, (q15_t)0xBE31, (q15_t)0x924F, (q15_t)0xBE06, + (q15_t)0x9269, (q15_t)0xBDDB, (q15_t)0x9283, (q15_t)0xBDB0, + (q15_t)0x929D, (q15_t)0xBD85, (q15_t)0x92B7, (q15_t)0xBD5A, + (q15_t)0x92D2, (q15_t)0xBD2F, (q15_t)0x92EC, (q15_t)0xBD05, + (q15_t)0x9306, (q15_t)0xBCDA, (q15_t)0x9321, (q15_t)0xBCAF, + (q15_t)0x933B, (q15_t)0xBC84, (q15_t)0x9356, (q15_t)0xBC5A, + (q15_t)0x9370, (q15_t)0xBC2F, (q15_t)0x938B, (q15_t)0xBC04, + (q15_t)0x93A6, (q15_t)0xBBDA, (q15_t)0x93C0, (q15_t)0xBBAF, + (q15_t)0x93DB, (q15_t)0xBB85, (q15_t)0x93F6, (q15_t)0xBB5A, + (q15_t)0x9411, (q15_t)0xBB30, (q15_t)0x942C, (q15_t)0xBB05, + (q15_t)0x9447, (q15_t)0xBADB, (q15_t)0x9463, (q15_t)0xBAB1, + (q15_t)0x947E, (q15_t)0xBA87, (q15_t)0x9499, (q15_t)0xBA5C, + (q15_t)0x94B5, (q15_t)0xBA32, (q15_t)0x94D0, (q15_t)0xBA08, + (q15_t)0x94EC, (q15_t)0xB9DE, (q15_t)0x9507, (q15_t)0xB9B4, + (q15_t)0x9523, (q15_t)0xB98A, (q15_t)0x953E, (q15_t)0xB960, + (q15_t)0x955A, (q15_t)0xB936, (q15_t)0x9576, (q15_t)0xB90C, + (q15_t)0x9592, (q15_t)0xB8E3, (q15_t)0x95AE, (q15_t)0xB8B9, + (q15_t)0x95CA, (q15_t)0xB88F, (q15_t)0x95E6, (q15_t)0xB865, + (q15_t)0x9602, (q15_t)0xB83C, (q15_t)0x961E, (q15_t)0xB812, + (q15_t)0x963B, (q15_t)0xB7E9, (q15_t)0x9657, (q15_t)0xB7BF, + (q15_t)0x9673, (q15_t)0xB796, (q15_t)0x9690, (q15_t)0xB76C, + (q15_t)0x96AC, (q15_t)0xB743, (q15_t)0x96C9, (q15_t)0xB719, + (q15_t)0x96E6, (q15_t)0xB6F0, (q15_t)0x9702, (q15_t)0xB6C7, + (q15_t)0x971F, (q15_t)0xB69E, (q15_t)0x973C, (q15_t)0xB675, + (q15_t)0x9759, (q15_t)0xB64B, (q15_t)0x9776, (q15_t)0xB622, + (q15_t)0x9793, (q15_t)0xB5F9, (q15_t)0x97B0, (q15_t)0xB5D0, + (q15_t)0x97CD, (q15_t)0xB5A7, (q15_t)0x97EA, (q15_t)0xB57E, + (q15_t)0x9808, (q15_t)0xB556, (q15_t)0x9825, (q15_t)0xB52D, + (q15_t)0x9842, (q15_t)0xB504, (q15_t)0x9860, (q15_t)0xB4DB, + (q15_t)0x987D, (q15_t)0xB4B3, (q15_t)0x989B, (q15_t)0xB48A, + (q15_t)0x98B9, (q15_t)0xB461, (q15_t)0x98D6, (q15_t)0xB439, + (q15_t)0x98F4, (q15_t)0xB410, (q15_t)0x9912, (q15_t)0xB3E8, + (q15_t)0x9930, (q15_t)0xB3C0, (q15_t)0x994E, (q15_t)0xB397, + (q15_t)0x996C, (q15_t)0xB36F, (q15_t)0x998A, (q15_t)0xB347, + (q15_t)0x99A8, (q15_t)0xB31E, (q15_t)0x99C6, (q15_t)0xB2F6, + (q15_t)0x99E5, (q15_t)0xB2CE, (q15_t)0x9A03, (q15_t)0xB2A6, + (q15_t)0x9A22, (q15_t)0xB27E, (q15_t)0x9A40, (q15_t)0xB256, + (q15_t)0x9A5F, (q15_t)0xB22E, (q15_t)0x9A7D, (q15_t)0xB206, + (q15_t)0x9A9C, (q15_t)0xB1DE, (q15_t)0x9ABA, (q15_t)0xB1B7, + (q15_t)0x9AD9, (q15_t)0xB18F, (q15_t)0x9AF8, (q15_t)0xB167, + (q15_t)0x9B17, (q15_t)0xB140, (q15_t)0x9B36, (q15_t)0xB118, + (q15_t)0x9B55, (q15_t)0xB0F0, (q15_t)0x9B74, (q15_t)0xB0C9, + (q15_t)0x9B93, (q15_t)0xB0A1, (q15_t)0x9BB2, (q15_t)0xB07A, + (q15_t)0x9BD2, (q15_t)0xB053, (q15_t)0x9BF1, (q15_t)0xB02B, + (q15_t)0x9C10, (q15_t)0xB004, (q15_t)0x9C30, (q15_t)0xAFDD, + (q15_t)0x9C4F, (q15_t)0xAFB6, (q15_t)0x9C6F, (q15_t)0xAF8F, + (q15_t)0x9C8E, (q15_t)0xAF68, (q15_t)0x9CAE, (q15_t)0xAF40, + (q15_t)0x9CCE, (q15_t)0xAF1A, (q15_t)0x9CEE, (q15_t)0xAEF3, + (q15_t)0x9D0D, (q15_t)0xAECC, (q15_t)0x9D2D, (q15_t)0xAEA5, + (q15_t)0x9D4D, (q15_t)0xAE7E, (q15_t)0x9D6D, (q15_t)0xAE57, + (q15_t)0x9D8E, (q15_t)0xAE31, (q15_t)0x9DAE, (q15_t)0xAE0A, + (q15_t)0x9DCE, (q15_t)0xADE3, (q15_t)0x9DEE, (q15_t)0xADBD, + (q15_t)0x9E0E, (q15_t)0xAD96, (q15_t)0x9E2F, (q15_t)0xAD70, + (q15_t)0x9E4F, (q15_t)0xAD4A, (q15_t)0x9E70, (q15_t)0xAD23, + (q15_t)0x9E90, (q15_t)0xACFD, (q15_t)0x9EB1, (q15_t)0xACD7, + (q15_t)0x9ED2, (q15_t)0xACB1, (q15_t)0x9EF2, (q15_t)0xAC8A, + (q15_t)0x9F13, (q15_t)0xAC64, (q15_t)0x9F34, (q15_t)0xAC3E, + (q15_t)0x9F55, (q15_t)0xAC18, (q15_t)0x9F76, (q15_t)0xABF2, + (q15_t)0x9F97, (q15_t)0xABCC, (q15_t)0x9FB8, (q15_t)0xABA7, + (q15_t)0x9FD9, (q15_t)0xAB81, (q15_t)0x9FFB, (q15_t)0xAB5B, + (q15_t)0xA01C, (q15_t)0xAB35, (q15_t)0xA03D, (q15_t)0xAB10, + (q15_t)0xA05F, (q15_t)0xAAEA, (q15_t)0xA080, (q15_t)0xAAC5, + (q15_t)0xA0A1, (q15_t)0xAA9F, (q15_t)0xA0C3, (q15_t)0xAA7A, + (q15_t)0xA0E5, (q15_t)0xAA54, (q15_t)0xA106, (q15_t)0xAA2F, + (q15_t)0xA128, (q15_t)0xAA0A, (q15_t)0xA14A, (q15_t)0xA9E5, + (q15_t)0xA16C, (q15_t)0xA9BF, (q15_t)0xA18E, (q15_t)0xA99A, + (q15_t)0xA1AF, (q15_t)0xA975, (q15_t)0xA1D2, (q15_t)0xA950, + (q15_t)0xA1F4, (q15_t)0xA92B, (q15_t)0xA216, (q15_t)0xA906, + (q15_t)0xA238, (q15_t)0xA8E2, (q15_t)0xA25A, (q15_t)0xA8BD, + (q15_t)0xA27C, (q15_t)0xA898, (q15_t)0xA29F, (q15_t)0xA873, + (q15_t)0xA2C1, (q15_t)0xA84F, (q15_t)0xA2E4, (q15_t)0xA82A, + (q15_t)0xA306, (q15_t)0xA806, (q15_t)0xA329, (q15_t)0xA7E1, + (q15_t)0xA34B, (q15_t)0xA7BD, (q15_t)0xA36E, (q15_t)0xA798, + (q15_t)0xA391, (q15_t)0xA774, (q15_t)0xA3B4, (q15_t)0xA750, + (q15_t)0xA3D6, (q15_t)0xA72B, (q15_t)0xA3F9, (q15_t)0xA707, + (q15_t)0xA41C, (q15_t)0xA6E3, (q15_t)0xA43F, (q15_t)0xA6BF, + (q15_t)0xA462, (q15_t)0xA69B, (q15_t)0xA486, (q15_t)0xA677, + (q15_t)0xA4A9, (q15_t)0xA653, (q15_t)0xA4CC, (q15_t)0xA62F, + (q15_t)0xA4EF, (q15_t)0xA60C, (q15_t)0xA513, (q15_t)0xA5E8, + (q15_t)0xA536, (q15_t)0xA5C4, (q15_t)0xA55A, (q15_t)0xA5A1, + (q15_t)0xA57D, (q15_t)0xA57D, (q15_t)0xA5A1, (q15_t)0xA55A, + (q15_t)0xA5C4, (q15_t)0xA536, (q15_t)0xA5E8, (q15_t)0xA513, + (q15_t)0xA60C, (q15_t)0xA4EF, (q15_t)0xA62F, (q15_t)0xA4CC, + (q15_t)0xA653, (q15_t)0xA4A9, (q15_t)0xA677, (q15_t)0xA486, + (q15_t)0xA69B, (q15_t)0xA462, (q15_t)0xA6BF, (q15_t)0xA43F, + (q15_t)0xA6E3, (q15_t)0xA41C, (q15_t)0xA707, (q15_t)0xA3F9, + (q15_t)0xA72B, (q15_t)0xA3D6, (q15_t)0xA750, (q15_t)0xA3B4, + (q15_t)0xA774, (q15_t)0xA391, (q15_t)0xA798, (q15_t)0xA36E, + (q15_t)0xA7BD, (q15_t)0xA34B, (q15_t)0xA7E1, (q15_t)0xA329, + (q15_t)0xA806, (q15_t)0xA306, (q15_t)0xA82A, (q15_t)0xA2E4, + (q15_t)0xA84F, (q15_t)0xA2C1, (q15_t)0xA873, (q15_t)0xA29F, + (q15_t)0xA898, (q15_t)0xA27C, (q15_t)0xA8BD, (q15_t)0xA25A, + (q15_t)0xA8E2, (q15_t)0xA238, (q15_t)0xA906, (q15_t)0xA216, + (q15_t)0xA92B, (q15_t)0xA1F4, (q15_t)0xA950, (q15_t)0xA1D2, + (q15_t)0xA975, (q15_t)0xA1AF, (q15_t)0xA99A, (q15_t)0xA18E, + (q15_t)0xA9BF, (q15_t)0xA16C, (q15_t)0xA9E5, (q15_t)0xA14A, + (q15_t)0xAA0A, (q15_t)0xA128, (q15_t)0xAA2F, (q15_t)0xA106, + (q15_t)0xAA54, (q15_t)0xA0E5, (q15_t)0xAA7A, (q15_t)0xA0C3, + (q15_t)0xAA9F, (q15_t)0xA0A1, (q15_t)0xAAC5, (q15_t)0xA080, + (q15_t)0xAAEA, (q15_t)0xA05F, (q15_t)0xAB10, (q15_t)0xA03D, + (q15_t)0xAB35, (q15_t)0xA01C, (q15_t)0xAB5B, (q15_t)0x9FFB, + (q15_t)0xAB81, (q15_t)0x9FD9, (q15_t)0xABA7, (q15_t)0x9FB8, + (q15_t)0xABCC, (q15_t)0x9F97, (q15_t)0xABF2, (q15_t)0x9F76, + (q15_t)0xAC18, (q15_t)0x9F55, (q15_t)0xAC3E, (q15_t)0x9F34, + (q15_t)0xAC64, (q15_t)0x9F13, (q15_t)0xAC8A, (q15_t)0x9EF2, + (q15_t)0xACB1, (q15_t)0x9ED2, (q15_t)0xACD7, (q15_t)0x9EB1, + (q15_t)0xACFD, (q15_t)0x9E90, (q15_t)0xAD23, (q15_t)0x9E70, + (q15_t)0xAD4A, (q15_t)0x9E4F, (q15_t)0xAD70, (q15_t)0x9E2F, + (q15_t)0xAD96, (q15_t)0x9E0E, (q15_t)0xADBD, (q15_t)0x9DEE, + (q15_t)0xADE3, (q15_t)0x9DCE, (q15_t)0xAE0A, (q15_t)0x9DAE, + (q15_t)0xAE31, (q15_t)0x9D8E, (q15_t)0xAE57, (q15_t)0x9D6D, + (q15_t)0xAE7E, (q15_t)0x9D4D, (q15_t)0xAEA5, (q15_t)0x9D2D, + (q15_t)0xAECC, (q15_t)0x9D0D, (q15_t)0xAEF3, (q15_t)0x9CEE, + (q15_t)0xAF1A, (q15_t)0x9CCE, (q15_t)0xAF40, (q15_t)0x9CAE, + (q15_t)0xAF68, (q15_t)0x9C8E, (q15_t)0xAF8F, (q15_t)0x9C6F, + (q15_t)0xAFB6, (q15_t)0x9C4F, (q15_t)0xAFDD, (q15_t)0x9C30, + (q15_t)0xB004, (q15_t)0x9C10, (q15_t)0xB02B, (q15_t)0x9BF1, + (q15_t)0xB053, (q15_t)0x9BD2, (q15_t)0xB07A, (q15_t)0x9BB2, + (q15_t)0xB0A1, (q15_t)0x9B93, (q15_t)0xB0C9, (q15_t)0x9B74, + (q15_t)0xB0F0, (q15_t)0x9B55, (q15_t)0xB118, (q15_t)0x9B36, + (q15_t)0xB140, (q15_t)0x9B17, (q15_t)0xB167, (q15_t)0x9AF8, + (q15_t)0xB18F, (q15_t)0x9AD9, (q15_t)0xB1B7, (q15_t)0x9ABA, + (q15_t)0xB1DE, (q15_t)0x9A9C, (q15_t)0xB206, (q15_t)0x9A7D, + (q15_t)0xB22E, (q15_t)0x9A5F, (q15_t)0xB256, (q15_t)0x9A40, + (q15_t)0xB27E, (q15_t)0x9A22, (q15_t)0xB2A6, (q15_t)0x9A03, + (q15_t)0xB2CE, (q15_t)0x99E5, (q15_t)0xB2F6, (q15_t)0x99C6, + (q15_t)0xB31E, (q15_t)0x99A8, (q15_t)0xB347, (q15_t)0x998A, + (q15_t)0xB36F, (q15_t)0x996C, (q15_t)0xB397, (q15_t)0x994E, + (q15_t)0xB3C0, (q15_t)0x9930, (q15_t)0xB3E8, (q15_t)0x9912, + (q15_t)0xB410, (q15_t)0x98F4, (q15_t)0xB439, (q15_t)0x98D6, + (q15_t)0xB461, (q15_t)0x98B9, (q15_t)0xB48A, (q15_t)0x989B, + (q15_t)0xB4B3, (q15_t)0x987D, (q15_t)0xB4DB, (q15_t)0x9860, + (q15_t)0xB504, (q15_t)0x9842, (q15_t)0xB52D, (q15_t)0x9825, + (q15_t)0xB556, (q15_t)0x9808, (q15_t)0xB57E, (q15_t)0x97EA, + (q15_t)0xB5A7, (q15_t)0x97CD, (q15_t)0xB5D0, (q15_t)0x97B0, + (q15_t)0xB5F9, (q15_t)0x9793, (q15_t)0xB622, (q15_t)0x9776, + (q15_t)0xB64B, (q15_t)0x9759, (q15_t)0xB675, (q15_t)0x973C, + (q15_t)0xB69E, (q15_t)0x971F, (q15_t)0xB6C7, (q15_t)0x9702, + (q15_t)0xB6F0, (q15_t)0x96E6, (q15_t)0xB719, (q15_t)0x96C9, + (q15_t)0xB743, (q15_t)0x96AC, (q15_t)0xB76C, (q15_t)0x9690, + (q15_t)0xB796, (q15_t)0x9673, (q15_t)0xB7BF, (q15_t)0x9657, + (q15_t)0xB7E9, (q15_t)0x963B, (q15_t)0xB812, (q15_t)0x961E, + (q15_t)0xB83C, (q15_t)0x9602, (q15_t)0xB865, (q15_t)0x95E6, + (q15_t)0xB88F, (q15_t)0x95CA, (q15_t)0xB8B9, (q15_t)0x95AE, + (q15_t)0xB8E3, (q15_t)0x9592, (q15_t)0xB90C, (q15_t)0x9576, + (q15_t)0xB936, (q15_t)0x955A, (q15_t)0xB960, (q15_t)0x953E, + (q15_t)0xB98A, (q15_t)0x9523, (q15_t)0xB9B4, (q15_t)0x9507, + (q15_t)0xB9DE, (q15_t)0x94EC, (q15_t)0xBA08, (q15_t)0x94D0, + (q15_t)0xBA32, (q15_t)0x94B5, (q15_t)0xBA5C, (q15_t)0x9499, + (q15_t)0xBA87, (q15_t)0x947E, (q15_t)0xBAB1, (q15_t)0x9463, + (q15_t)0xBADB, (q15_t)0x9447, (q15_t)0xBB05, (q15_t)0x942C, + (q15_t)0xBB30, (q15_t)0x9411, (q15_t)0xBB5A, (q15_t)0x93F6, + (q15_t)0xBB85, (q15_t)0x93DB, (q15_t)0xBBAF, (q15_t)0x93C0, + (q15_t)0xBBDA, (q15_t)0x93A6, (q15_t)0xBC04, (q15_t)0x938B, + (q15_t)0xBC2F, (q15_t)0x9370, (q15_t)0xBC5A, (q15_t)0x9356, + (q15_t)0xBC84, (q15_t)0x933B, (q15_t)0xBCAF, (q15_t)0x9321, + (q15_t)0xBCDA, (q15_t)0x9306, (q15_t)0xBD05, (q15_t)0x92EC, + (q15_t)0xBD2F, (q15_t)0x92D2, (q15_t)0xBD5A, (q15_t)0x92B7, + (q15_t)0xBD85, (q15_t)0x929D, (q15_t)0xBDB0, (q15_t)0x9283, + (q15_t)0xBDDB, (q15_t)0x9269, (q15_t)0xBE06, (q15_t)0x924F, + (q15_t)0xBE31, (q15_t)0x9235, (q15_t)0xBE5D, (q15_t)0x921C, + (q15_t)0xBE88, (q15_t)0x9202, (q15_t)0xBEB3, (q15_t)0x91E8, + (q15_t)0xBEDE, (q15_t)0x91CF, (q15_t)0xBF09, (q15_t)0x91B5, + (q15_t)0xBF35, (q15_t)0x919C, (q15_t)0xBF60, (q15_t)0x9182, + (q15_t)0xBF8C, (q15_t)0x9169, (q15_t)0xBFB7, (q15_t)0x9150, + (q15_t)0xBFE2, (q15_t)0x9136, (q15_t)0xC00E, (q15_t)0x911D, + (q15_t)0xC03A, (q15_t)0x9104, (q15_t)0xC065, (q15_t)0x90EB, + (q15_t)0xC091, (q15_t)0x90D2, (q15_t)0xC0BC, (q15_t)0x90B9, + (q15_t)0xC0E8, (q15_t)0x90A0, (q15_t)0xC114, (q15_t)0x9088, + (q15_t)0xC140, (q15_t)0x906F, (q15_t)0xC16C, (q15_t)0x9056, + (q15_t)0xC197, (q15_t)0x903E, (q15_t)0xC1C3, (q15_t)0x9025, + (q15_t)0xC1EF, (q15_t)0x900D, (q15_t)0xC21B, (q15_t)0x8FF5, + (q15_t)0xC247, (q15_t)0x8FDC, (q15_t)0xC273, (q15_t)0x8FC4, + (q15_t)0xC29F, (q15_t)0x8FAC, (q15_t)0xC2CC, (q15_t)0x8F94, + (q15_t)0xC2F8, (q15_t)0x8F7C, (q15_t)0xC324, (q15_t)0x8F64, + (q15_t)0xC350, (q15_t)0x8F4C, (q15_t)0xC37C, (q15_t)0x8F34, + (q15_t)0xC3A9, (q15_t)0x8F1D, (q15_t)0xC3D5, (q15_t)0x8F05, + (q15_t)0xC402, (q15_t)0x8EED, (q15_t)0xC42E, (q15_t)0x8ED6, + (q15_t)0xC45A, (q15_t)0x8EBE, (q15_t)0xC487, (q15_t)0x8EA7, + (q15_t)0xC4B3, (q15_t)0x8E90, (q15_t)0xC4E0, (q15_t)0x8E79, + (q15_t)0xC50D, (q15_t)0x8E61, (q15_t)0xC539, (q15_t)0x8E4A, + (q15_t)0xC566, (q15_t)0x8E33, (q15_t)0xC593, (q15_t)0x8E1C, + (q15_t)0xC5BF, (q15_t)0x8E05, (q15_t)0xC5EC, (q15_t)0x8DEE, + (q15_t)0xC619, (q15_t)0x8DD8, (q15_t)0xC646, (q15_t)0x8DC1, + (q15_t)0xC673, (q15_t)0x8DAA, (q15_t)0xC6A0, (q15_t)0x8D94, + (q15_t)0xC6CD, (q15_t)0x8D7D, (q15_t)0xC6F9, (q15_t)0x8D67, + (q15_t)0xC727, (q15_t)0x8D50, (q15_t)0xC754, (q15_t)0x8D3A, + (q15_t)0xC781, (q15_t)0x8D24, (q15_t)0xC7AE, (q15_t)0x8D0E, + (q15_t)0xC7DB, (q15_t)0x8CF8, (q15_t)0xC808, (q15_t)0x8CE2, + (q15_t)0xC835, (q15_t)0x8CCC, (q15_t)0xC863, (q15_t)0x8CB6, + (q15_t)0xC890, (q15_t)0x8CA0, (q15_t)0xC8BD, (q15_t)0x8C8A, + (q15_t)0xC8EB, (q15_t)0x8C75, (q15_t)0xC918, (q15_t)0x8C5F, + (q15_t)0xC945, (q15_t)0x8C4A, (q15_t)0xC973, (q15_t)0x8C34, + (q15_t)0xC9A0, (q15_t)0x8C1F, (q15_t)0xC9CE, (q15_t)0x8C09, + (q15_t)0xC9FB, (q15_t)0x8BF4, (q15_t)0xCA29, (q15_t)0x8BDF, + (q15_t)0xCA57, (q15_t)0x8BCA, (q15_t)0xCA84, (q15_t)0x8BB5, + (q15_t)0xCAB2, (q15_t)0x8BA0, (q15_t)0xCAE0, (q15_t)0x8B8B, + (q15_t)0xCB0D, (q15_t)0x8B76, (q15_t)0xCB3B, (q15_t)0x8B61, + (q15_t)0xCB69, (q15_t)0x8B4D, (q15_t)0xCB97, (q15_t)0x8B38, + (q15_t)0xCBC5, (q15_t)0x8B24, (q15_t)0xCBF3, (q15_t)0x8B0F, + (q15_t)0xCC21, (q15_t)0x8AFB, (q15_t)0xCC4F, (q15_t)0x8AE6, + (q15_t)0xCC7D, (q15_t)0x8AD2, (q15_t)0xCCAB, (q15_t)0x8ABE, + (q15_t)0xCCD9, (q15_t)0x8AAA, (q15_t)0xCD07, (q15_t)0x8A96, + (q15_t)0xCD35, (q15_t)0x8A82, (q15_t)0xCD63, (q15_t)0x8A6E, + (q15_t)0xCD91, (q15_t)0x8A5A, (q15_t)0xCDBF, (q15_t)0x8A46, + (q15_t)0xCDEE, (q15_t)0x8A33, (q15_t)0xCE1C, (q15_t)0x8A1F, + (q15_t)0xCE4A, (q15_t)0x8A0B, (q15_t)0xCE79, (q15_t)0x89F8, + (q15_t)0xCEA7, (q15_t)0x89E4, (q15_t)0xCED5, (q15_t)0x89D1, + (q15_t)0xCF04, (q15_t)0x89BE, (q15_t)0xCF32, (q15_t)0x89AB, + (q15_t)0xCF61, (q15_t)0x8997, (q15_t)0xCF8F, (q15_t)0x8984, + (q15_t)0xCFBE, (q15_t)0x8971, (q15_t)0xCFEC, (q15_t)0x895F, + (q15_t)0xD01B, (q15_t)0x894C, (q15_t)0xD04A, (q15_t)0x8939, + (q15_t)0xD078, (q15_t)0x8926, (q15_t)0xD0A7, (q15_t)0x8914, + (q15_t)0xD0D6, (q15_t)0x8901, (q15_t)0xD104, (q15_t)0x88EF, + (q15_t)0xD133, (q15_t)0x88DC, (q15_t)0xD162, (q15_t)0x88CA, + (q15_t)0xD191, (q15_t)0x88B8, (q15_t)0xD1C0, (q15_t)0x88A5, + (q15_t)0xD1EE, (q15_t)0x8893, (q15_t)0xD21D, (q15_t)0x8881, + (q15_t)0xD24C, (q15_t)0x886F, (q15_t)0xD27B, (q15_t)0x885D, + (q15_t)0xD2AA, (q15_t)0x884B, (q15_t)0xD2D9, (q15_t)0x883A, + (q15_t)0xD308, (q15_t)0x8828, (q15_t)0xD337, (q15_t)0x8816, + (q15_t)0xD367, (q15_t)0x8805, (q15_t)0xD396, (q15_t)0x87F3, + (q15_t)0xD3C5, (q15_t)0x87E2, (q15_t)0xD3F4, (q15_t)0x87D1, + (q15_t)0xD423, (q15_t)0x87BF, (q15_t)0xD452, (q15_t)0x87AE, + (q15_t)0xD482, (q15_t)0x879D, (q15_t)0xD4B1, (q15_t)0x878C, + (q15_t)0xD4E0, (q15_t)0x877B, (q15_t)0xD510, (q15_t)0x876A, + (q15_t)0xD53F, (q15_t)0x8759, (q15_t)0xD56E, (q15_t)0x8749, + (q15_t)0xD59E, (q15_t)0x8738, (q15_t)0xD5CD, (q15_t)0x8727, + (q15_t)0xD5FD, (q15_t)0x8717, (q15_t)0xD62C, (q15_t)0x8706, + (q15_t)0xD65C, (q15_t)0x86F6, (q15_t)0xD68B, (q15_t)0x86E6, + (q15_t)0xD6BB, (q15_t)0x86D5, (q15_t)0xD6EA, (q15_t)0x86C5, + (q15_t)0xD71A, (q15_t)0x86B5, (q15_t)0xD74A, (q15_t)0x86A5, + (q15_t)0xD779, (q15_t)0x8695, (q15_t)0xD7A9, (q15_t)0x8685, + (q15_t)0xD7D9, (q15_t)0x8675, (q15_t)0xD809, (q15_t)0x8666, + (q15_t)0xD838, (q15_t)0x8656, (q15_t)0xD868, (q15_t)0x8646, + (q15_t)0xD898, (q15_t)0x8637, (q15_t)0xD8C8, (q15_t)0x8627, + (q15_t)0xD8F8, (q15_t)0x8618, (q15_t)0xD927, (q15_t)0x8609, + (q15_t)0xD957, (q15_t)0x85FA, (q15_t)0xD987, (q15_t)0x85EA, + (q15_t)0xD9B7, (q15_t)0x85DB, (q15_t)0xD9E7, (q15_t)0x85CC, + (q15_t)0xDA17, (q15_t)0x85BD, (q15_t)0xDA47, (q15_t)0x85AF, + (q15_t)0xDA77, (q15_t)0x85A0, (q15_t)0xDAA7, (q15_t)0x8591, + (q15_t)0xDAD7, (q15_t)0x8582, (q15_t)0xDB08, (q15_t)0x8574, + (q15_t)0xDB38, (q15_t)0x8565, (q15_t)0xDB68, (q15_t)0x8557, + (q15_t)0xDB98, (q15_t)0x8549, (q15_t)0xDBC8, (q15_t)0x853A, + (q15_t)0xDBF8, (q15_t)0x852C, (q15_t)0xDC29, (q15_t)0x851E, + (q15_t)0xDC59, (q15_t)0x8510, (q15_t)0xDC89, (q15_t)0x8502, + (q15_t)0xDCBA, (q15_t)0x84F4, (q15_t)0xDCEA, (q15_t)0x84E6, + (q15_t)0xDD1A, (q15_t)0x84D9, (q15_t)0xDD4B, (q15_t)0x84CB, + (q15_t)0xDD7B, (q15_t)0x84BD, (q15_t)0xDDAB, (q15_t)0x84B0, + (q15_t)0xDDDC, (q15_t)0x84A2, (q15_t)0xDE0C, (q15_t)0x8495, + (q15_t)0xDE3D, (q15_t)0x8488, (q15_t)0xDE6D, (q15_t)0x847B, + (q15_t)0xDE9E, (q15_t)0x846D, (q15_t)0xDECE, (q15_t)0x8460, + (q15_t)0xDEFF, (q15_t)0x8453, (q15_t)0xDF2F, (q15_t)0x8446, + (q15_t)0xDF60, (q15_t)0x843A, (q15_t)0xDF91, (q15_t)0x842D, + (q15_t)0xDFC1, (q15_t)0x8420, (q15_t)0xDFF2, (q15_t)0x8414, + (q15_t)0xE023, (q15_t)0x8407, (q15_t)0xE053, (q15_t)0x83FA, + (q15_t)0xE084, (q15_t)0x83EE, (q15_t)0xE0B5, (q15_t)0x83E2, + (q15_t)0xE0E6, (q15_t)0x83D6, (q15_t)0xE116, (q15_t)0x83C9, + (q15_t)0xE147, (q15_t)0x83BD, (q15_t)0xE178, (q15_t)0x83B1, + (q15_t)0xE1A9, (q15_t)0x83A5, (q15_t)0xE1DA, (q15_t)0x8399, + (q15_t)0xE20A, (q15_t)0x838E, (q15_t)0xE23B, (q15_t)0x8382, + (q15_t)0xE26C, (q15_t)0x8376, (q15_t)0xE29D, (q15_t)0x836B, + (q15_t)0xE2CE, (q15_t)0x835F, (q15_t)0xE2FF, (q15_t)0x8354, + (q15_t)0xE330, (q15_t)0x8348, (q15_t)0xE361, (q15_t)0x833D, + (q15_t)0xE392, (q15_t)0x8332, (q15_t)0xE3C3, (q15_t)0x8327, + (q15_t)0xE3F4, (q15_t)0x831C, (q15_t)0xE425, (q15_t)0x8311, + (q15_t)0xE456, (q15_t)0x8306, (q15_t)0xE487, (q15_t)0x82FB, + (q15_t)0xE4B8, (q15_t)0x82F0, (q15_t)0xE4E9, (q15_t)0x82E6, + (q15_t)0xE51B, (q15_t)0x82DB, (q15_t)0xE54C, (q15_t)0x82D0, + (q15_t)0xE57D, (q15_t)0x82C6, (q15_t)0xE5AE, (q15_t)0x82BC, + (q15_t)0xE5DF, (q15_t)0x82B1, (q15_t)0xE610, (q15_t)0x82A7, + (q15_t)0xE642, (q15_t)0x829D, (q15_t)0xE673, (q15_t)0x8293, + (q15_t)0xE6A4, (q15_t)0x8289, (q15_t)0xE6D5, (q15_t)0x827F, + (q15_t)0xE707, (q15_t)0x8275, (q15_t)0xE738, (q15_t)0x826B, + (q15_t)0xE769, (q15_t)0x8262, (q15_t)0xE79B, (q15_t)0x8258, + (q15_t)0xE7CC, (q15_t)0x824F, (q15_t)0xE7FD, (q15_t)0x8245, + (q15_t)0xE82F, (q15_t)0x823C, (q15_t)0xE860, (q15_t)0x8232, + (q15_t)0xE892, (q15_t)0x8229, (q15_t)0xE8C3, (q15_t)0x8220, + (q15_t)0xE8F5, (q15_t)0x8217, (q15_t)0xE926, (q15_t)0x820E, + (q15_t)0xE957, (q15_t)0x8205, (q15_t)0xE989, (q15_t)0x81FC, + (q15_t)0xE9BA, (q15_t)0x81F3, (q15_t)0xE9EC, (q15_t)0x81EB, + (q15_t)0xEA1D, (q15_t)0x81E2, (q15_t)0xEA4F, (q15_t)0x81D9, + (q15_t)0xEA80, (q15_t)0x81D1, (q15_t)0xEAB2, (q15_t)0x81C8, + (q15_t)0xEAE4, (q15_t)0x81C0, (q15_t)0xEB15, (q15_t)0x81B8, + (q15_t)0xEB47, (q15_t)0x81B0, (q15_t)0xEB78, (q15_t)0x81A8, + (q15_t)0xEBAA, (q15_t)0x81A0, (q15_t)0xEBDC, (q15_t)0x8198, + (q15_t)0xEC0D, (q15_t)0x8190, (q15_t)0xEC3F, (q15_t)0x8188, + (q15_t)0xEC71, (q15_t)0x8180, (q15_t)0xECA2, (q15_t)0x8179, + (q15_t)0xECD4, (q15_t)0x8171, (q15_t)0xED06, (q15_t)0x816A, + (q15_t)0xED37, (q15_t)0x8162, (q15_t)0xED69, (q15_t)0x815B, + (q15_t)0xED9B, (q15_t)0x8154, (q15_t)0xEDCD, (q15_t)0x814C, + (q15_t)0xEDFE, (q15_t)0x8145, (q15_t)0xEE30, (q15_t)0x813E, + (q15_t)0xEE62, (q15_t)0x8137, (q15_t)0xEE94, (q15_t)0x8130, + (q15_t)0xEEC6, (q15_t)0x812A, (q15_t)0xEEF7, (q15_t)0x8123, + (q15_t)0xEF29, (q15_t)0x811C, (q15_t)0xEF5B, (q15_t)0x8116, + (q15_t)0xEF8D, (q15_t)0x810F, (q15_t)0xEFBF, (q15_t)0x8109, + (q15_t)0xEFF1, (q15_t)0x8102, (q15_t)0xF022, (q15_t)0x80FC, + (q15_t)0xF054, (q15_t)0x80F6, (q15_t)0xF086, (q15_t)0x80F0, + (q15_t)0xF0B8, (q15_t)0x80EA, (q15_t)0xF0EA, (q15_t)0x80E4, + (q15_t)0xF11C, (q15_t)0x80DE, (q15_t)0xF14E, (q15_t)0x80D8, + (q15_t)0xF180, (q15_t)0x80D2, (q15_t)0xF1B2, (q15_t)0x80CD, + (q15_t)0xF1E4, (q15_t)0x80C7, (q15_t)0xF216, (q15_t)0x80C2, + (q15_t)0xF248, (q15_t)0x80BC, (q15_t)0xF27A, (q15_t)0x80B7, + (q15_t)0xF2AC, (q15_t)0x80B2, (q15_t)0xF2DE, (q15_t)0x80AC, + (q15_t)0xF310, (q15_t)0x80A7, (q15_t)0xF342, (q15_t)0x80A2, + (q15_t)0xF374, (q15_t)0x809D, (q15_t)0xF3A6, (q15_t)0x8098, + (q15_t)0xF3D8, (q15_t)0x8094, (q15_t)0xF40A, (q15_t)0x808F, + (q15_t)0xF43C, (q15_t)0x808A, (q15_t)0xF46E, (q15_t)0x8086, + (q15_t)0xF4A0, (q15_t)0x8081, (q15_t)0xF4D2, (q15_t)0x807D, + (q15_t)0xF504, (q15_t)0x8078, (q15_t)0xF536, (q15_t)0x8074, + (q15_t)0xF568, (q15_t)0x8070, (q15_t)0xF59A, (q15_t)0x806C, + (q15_t)0xF5CC, (q15_t)0x8068, (q15_t)0xF5FF, (q15_t)0x8064, + (q15_t)0xF631, (q15_t)0x8060, (q15_t)0xF663, (q15_t)0x805C, + (q15_t)0xF695, (q15_t)0x8058, (q15_t)0xF6C7, (q15_t)0x8055, + (q15_t)0xF6F9, (q15_t)0x8051, (q15_t)0xF72B, (q15_t)0x804E, + (q15_t)0xF75D, (q15_t)0x804A, (q15_t)0xF790, (q15_t)0x8047, + (q15_t)0xF7C2, (q15_t)0x8043, (q15_t)0xF7F4, (q15_t)0x8040, + (q15_t)0xF826, (q15_t)0x803D, (q15_t)0xF858, (q15_t)0x803A, + (q15_t)0xF88A, (q15_t)0x8037, (q15_t)0xF8BD, (q15_t)0x8034, + (q15_t)0xF8EF, (q15_t)0x8031, (q15_t)0xF921, (q15_t)0x802F, + (q15_t)0xF953, (q15_t)0x802C, (q15_t)0xF985, (q15_t)0x8029, + (q15_t)0xF9B8, (q15_t)0x8027, (q15_t)0xF9EA, (q15_t)0x8025, + (q15_t)0xFA1C, (q15_t)0x8022, (q15_t)0xFA4E, (q15_t)0x8020, + (q15_t)0xFA80, (q15_t)0x801E, (q15_t)0xFAB3, (q15_t)0x801C, + (q15_t)0xFAE5, (q15_t)0x801A, (q15_t)0xFB17, (q15_t)0x8018, + (q15_t)0xFB49, (q15_t)0x8016, (q15_t)0xFB7C, (q15_t)0x8014, + (q15_t)0xFBAE, (q15_t)0x8012, (q15_t)0xFBE0, (q15_t)0x8011, + (q15_t)0xFC12, (q15_t)0x800F, (q15_t)0xFC45, (q15_t)0x800D, + (q15_t)0xFC77, (q15_t)0x800C, (q15_t)0xFCA9, (q15_t)0x800B, + (q15_t)0xFCDB, (q15_t)0x8009, (q15_t)0xFD0E, (q15_t)0x8008, + (q15_t)0xFD40, (q15_t)0x8007, (q15_t)0xFD72, (q15_t)0x8006, + (q15_t)0xFDA4, (q15_t)0x8005, (q15_t)0xFDD7, (q15_t)0x8004, + (q15_t)0xFE09, (q15_t)0x8003, (q15_t)0xFE3B, (q15_t)0x8003, + (q15_t)0xFE6D, (q15_t)0x8002, (q15_t)0xFEA0, (q15_t)0x8001, + (q15_t)0xFED2, (q15_t)0x8001, (q15_t)0xFF04, (q15_t)0x8000, + (q15_t)0xFF36, (q15_t)0x8000, (q15_t)0xFF69, (q15_t)0x8000, + (q15_t)0xFF9B, (q15_t)0x8000, (q15_t)0xFFCD, (q15_t)0x8000 +}; + + +/** + @} end of CFFT_CIFFT group +*/ + +/** + @brief Q15 table for reciprocal +*/ +const q15_t __ALIGNED(4) armRecipTableQ15[64] = { + 0x7F03, 0x7D13, 0x7B31, 0x795E, 0x7798, 0x75E0, + 0x7434, 0x7294, 0x70FF, 0x6F76, 0x6DF6, 0x6C82, + 0x6B16, 0x69B5, 0x685C, 0x670C, 0x65C4, 0x6484, + 0x634C, 0x621C, 0x60F3, 0x5FD0, 0x5EB5, 0x5DA0, + 0x5C91, 0x5B88, 0x5A85, 0x5988, 0x5890, 0x579E, + 0x56B0, 0x55C8, 0x54E4, 0x5405, 0x532B, 0x5255, + 0x5183, 0x50B6, 0x4FEC, 0x4F26, 0x4E64, 0x4DA6, + 0x4CEC, 0x4C34, 0x4B81, 0x4AD0, 0x4A23, 0x4978, + 0x48D1, 0x482D, 0x478C, 0x46ED, 0x4651, 0x45B8, + 0x4521, 0x448D, 0x43FC, 0x436C, 0x42DF, 0x4255, + 0x41CC, 0x4146, 0x40C2, 0x4040 +}; + +/** + @brief Q31 table for reciprocal +*/ +const q31_t armRecipTableQ31[64] = { + 0x7F03F03F, 0x7D137420, 0x7B31E739, 0x795E9F94, 0x7798FD29, 0x75E06928, + 0x7434554D, 0x72943B4B, 0x70FF9C40, 0x6F760031, 0x6DF6F593, 0x6C8210E3, + 0x6B16EC3A, 0x69B526F6, 0x685C655F, 0x670C505D, 0x65C4952D, 0x6484E519, + 0x634CF53E, 0x621C7E4F, 0x60F33C61, 0x5FD0EEB3, 0x5EB55785, 0x5DA03BEB, + 0x5C9163A1, 0x5B8898E6, 0x5A85A85A, 0x598860DF, 0x58909373, 0x579E1318, + 0x56B0B4B8, 0x55C84F0B, 0x54E4BA80, 0x5405D124, 0x532B6E8F, 0x52556FD0, + 0x5183B35A, 0x50B618F3, 0x4FEC81A2, 0x4F26CFA2, 0x4E64E64E, 0x4DA6AA1D, + 0x4CEC008B, 0x4C34D010, 0x4B810016, 0x4AD078EF, 0x4A2323C4, 0x4978EA96, + 0x48D1B827, 0x482D77FE, 0x478C1657, 0x46ED801D, 0x4651A2E5, 0x45B86CE2, + 0x4521CCE1, 0x448DB244, 0x43FC0CFA, 0x436CCD78, 0x42DFE4B4, 0x42554426, + 0x41CCDDB6, 0x4146A3C6, 0x40C28923, 0x40408102 +}; + +const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH] = +{ + /* 8x2, size 20 */ + 8,64, 24,72, 16,64, 40,80, 32,64, 56,88, 48,72, 88,104, 72,96, 104,112 +}; + +const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH] = +{ + /* 8x4, size 48 */ + 8,64, 16,128, 24,192, 32,64, 40,72, 48,136, 56,200, 64,128, 72,80, 88,208, + 80,144, 96,192, 104,208, 112,152, 120,216, 136,192, 144,160, 168,208, + 152,224, 176,208, 184,232, 216,240, 200,224, 232,240 +}; + +const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH] = +{ + /* radix 8, size 56 */ + 8,64, 16,128, 24,192, 32,256, 40,320, 48,384, 56,448, 80,136, 88,200, + 96,264, 104,328, 112,392, 120,456, 152,208, 160,272, 168,336, 176,400, + 184,464, 224,280, 232,344, 240,408, 248,472, 296,352, 304,416, 312,480, + 368,424, 376,488, 440,496 +}; + +const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH] = +{ + /* 8x2, size 208 */ + 8,512, 16,64, 24,576, 32,128, 40,640, 48,192, 56,704, 64,256, 72,768, + 80,320, 88,832, 96,384, 104,896, 112,448, 120,960, 128,512, 136,520, + 144,768, 152,584, 160,520, 168,648, 176,200, 184,712, 192,264, 200,776, + 208,328, 216,840, 224,392, 232,904, 240,456, 248,968, 264,528, 272,320, + 280,592, 288,768, 296,656, 304,328, 312,720, 328,784, 344,848, 352,400, + 360,912, 368,464, 376,976, 384,576, 392,536, 400,832, 408,600, 416,584, + 424,664, 432,840, 440,728, 448,592, 456,792, 464,848, 472,856, 480,600, + 488,920, 496,856, 504,984, 520,544, 528,576, 536,608, 552,672, 560,608, + 568,736, 576,768, 584,800, 592,832, 600,864, 608,800, 616,928, 624,864, + 632,992, 648,672, 656,896, 664,928, 688,904, 696,744, 704,896, 712,808, + 720,912, 728,872, 736,928, 744,936, 752,920, 760,1000, 776,800, 784,832, + 792,864, 808,904, 816,864, 824,920, 840,864, 856,880, 872,944, 888,1008, + 904,928, 912,960, 920,992, 944,968, 952,1000, 968,992, 984,1008 +}; + +const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH] = +{ + /* 8x4, size 440 */ + 8,512, 16,1024, 24,1536, 32,64, 40,576, 48,1088, 56,1600, 64,128, 72,640, + 80,1152, 88,1664, 96,192, 104,704, 112,1216, 120,1728, 128,256, 136,768, + 144,1280, 152,1792, 160,320, 168,832, 176,1344, 184,1856, 192,384, + 200,896, 208,1408, 216,1920, 224,448, 232,960, 240,1472, 248,1984, + 256,512, 264,520, 272,1032, 280,1544, 288,640, 296,584, 304,1096, 312,1608, + 320,768, 328,648, 336,1160, 344,1672, 352,896, 360,712, 368,1224, 376,1736, + 384,520, 392,776, 400,1288, 408,1800, 416,648, 424,840, 432,1352, 440,1864, + 448,776, 456,904, 464,1416, 472,1928, 480,904, 488,968, 496,1480, 504,1992, + 520,528, 512,1024, 528,1040, 536,1552, 544,1152, 552,592, 560,1104, + 568,1616, 576,1280, 584,656, 592,1168, 600,1680, 608,1408, 616,720, + 624,1232, 632,1744, 640,1032, 648,784, 656,1296, 664,1808, 672,1160, + 680,848, 688,1360, 696,1872, 704,1288, 712,912, 720,1424, 728,1936, + 736,1416, 744,976, 752,1488, 760,2000, 768,1536, 776,1552, 784,1048, + 792,1560, 800,1664, 808,1680, 816,1112, 824,1624, 832,1792, 840,1808, + 848,1176, 856,1688, 864,1920, 872,1936, 880,1240, 888,1752, 896,1544, + 904,1560, 912,1304, 920,1816, 928,1672, 936,1688, 944,1368, 952,1880, + 960,1800, 968,1816, 976,1432, 984,1944, 992,1928, 1000,1944, 1008,1496, + 1016,2008, 1032,1152, 1040,1056, 1048,1568, 1064,1408, 1072,1120, + 1080,1632, 1088,1536, 1096,1160, 1104,1184, 1112,1696, 1120,1552, + 1128,1416, 1136,1248, 1144,1760, 1160,1664, 1168,1312, 1176,1824, + 1184,1544, 1192,1920, 1200,1376, 1208,1888, 1216,1568, 1224,1672, + 1232,1440, 1240,1952, 1248,1560, 1256,1928, 1264,1504, 1272,2016, + 1288,1312, 1296,1408, 1304,1576, 1320,1424, 1328,1416, 1336,1640, + 1344,1792, 1352,1824, 1360,1920, 1368,1704, 1376,1800, 1384,1432, + 1392,1928, 1400,1768, 1416,1680, 1432,1832, 1440,1576, 1448,1936, + 1456,1832, 1464,1896, 1472,1808, 1480,1688, 1488,1936, 1496,1960, + 1504,1816, 1512,1944, 1520,1944, 1528,2024, 1560,1584, 1592,1648, + 1600,1792, 1608,1920, 1616,1800, 1624,1712, 1632,1808, 1640,1936, + 1648,1816, 1656,1776, 1672,1696, 1688,1840, 1704,1952, 1712,1928, + 1720,1904, 1728,1824, 1736,1952, 1744,1832, 1752,1968, 1760,1840, + 1768,1960, 1776,1944, 1784,2032, 1864,1872, 1848,1944, 1872,1888, + 1880,1904, 1888,1984, 1896,2000, 1912,2032, 1904,2016, 1976,2032, + 1960,1968, 2008,2032, 1992,2016, 2024,2032 +}; + +const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH] = +{ + /* radix 8, size 448 */ + 8,512, 16,1024, 24,1536, 32,2048, 40,2560, 48,3072, 56,3584, 72,576, + 80,1088, 88,1600, 96,2112, 104,2624, 112,3136, 120,3648, 136,640, 144,1152, + 152,1664, 160,2176, 168,2688, 176,3200, 184,3712, 200,704, 208,1216, + 216,1728, 224,2240, 232,2752, 240,3264, 248,3776, 264,768, 272,1280, + 280,1792, 288,2304, 296,2816, 304,3328, 312,3840, 328,832, 336,1344, + 344,1856, 352,2368, 360,2880, 368,3392, 376,3904, 392,896, 400,1408, + 408,1920, 416,2432, 424,2944, 432,3456, 440,3968, 456,960, 464,1472, + 472,1984, 480,2496, 488,3008, 496,3520, 504,4032, 528,1032, 536,1544, + 544,2056, 552,2568, 560,3080, 568,3592, 592,1096, 600,1608, 608,2120, + 616,2632, 624,3144, 632,3656, 656,1160, 664,1672, 672,2184, 680,2696, + 688,3208, 696,3720, 720,1224, 728,1736, 736,2248, 744,2760, 752,3272, + 760,3784, 784,1288, 792,1800, 800,2312, 808,2824, 816,3336, 824,3848, + 848,1352, 856,1864, 864,2376, 872,2888, 880,3400, 888,3912, 912,1416, + 920,1928, 928,2440, 936,2952, 944,3464, 952,3976, 976,1480, 984,1992, + 992,2504, 1000,3016, 1008,3528, 1016,4040, 1048,1552, 1056,2064, 1064,2576, + 1072,3088, 1080,3600, 1112,1616, 1120,2128, 1128,2640, 1136,3152, + 1144,3664, 1176,1680, 1184,2192, 1192,2704, 1200,3216, 1208,3728, + 1240,1744, 1248,2256, 1256,2768, 1264,3280, 1272,3792, 1304,1808, + 1312,2320, 1320,2832, 1328,3344, 1336,3856, 1368,1872, 1376,2384, + 1384,2896, 1392,3408, 1400,3920, 1432,1936, 1440,2448, 1448,2960, + 1456,3472, 1464,3984, 1496,2000, 1504,2512, 1512,3024, 1520,3536, + 1528,4048, 1568,2072, 1576,2584, 1584,3096, 1592,3608, 1632,2136, + 1640,2648, 1648,3160, 1656,3672, 1696,2200, 1704,2712, 1712,3224, + 1720,3736, 1760,2264, 1768,2776, 1776,3288, 1784,3800, 1824,2328, + 1832,2840, 1840,3352, 1848,3864, 1888,2392, 1896,2904, 1904,3416, + 1912,3928, 1952,2456, 1960,2968, 1968,3480, 1976,3992, 2016,2520, + 2024,3032, 2032,3544, 2040,4056, 2088,2592, 2096,3104, 2104,3616, + 2152,2656, 2160,3168, 2168,3680, 2216,2720, 2224,3232, 2232,3744, + 2280,2784, 2288,3296, 2296,3808, 2344,2848, 2352,3360, 2360,3872, + 2408,2912, 2416,3424, 2424,3936, 2472,2976, 2480,3488, 2488,4000, + 2536,3040, 2544,3552, 2552,4064, 2608,3112, 2616,3624, 2672,3176, + 2680,3688, 2736,3240, 2744,3752, 2800,3304, 2808,3816, 2864,3368, + 2872,3880, 2928,3432, 2936,3944, 2992,3496, 3000,4008, 3056,3560, + 3064,4072, 3128,3632, 3192,3696, 3256,3760, 3320,3824, 3384,3888, + 3448,3952, 3512,4016, 3576,4080 +}; + +const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH] = +{ + /* 8x2, size 1800 */ + 8,4096, 16,512, 24,4608, 32,1024, 40,5120, 48,1536, 56,5632, 64,2048, + 72,6144, 80,2560, 88,6656, 96,3072, 104,7168, 112,3584, 120,7680, 128,2048, + 136,4160, 144,576, 152,4672, 160,1088, 168,5184, 176,1600, 184,5696, + 192,2112, 200,6208, 208,2624, 216,6720, 224,3136, 232,7232, 240,3648, + 248,7744, 256,2048, 264,4224, 272,640, 280,4736, 288,1152, 296,5248, + 304,1664, 312,5760, 320,2176, 328,6272, 336,2688, 344,6784, 352,3200, + 360,7296, 368,3712, 376,7808, 384,2112, 392,4288, 400,704, 408,4800, + 416,1216, 424,5312, 432,1728, 440,5824, 448,2240, 456,6336, 464,2752, + 472,6848, 480,3264, 488,7360, 496,3776, 504,7872, 512,2048, 520,4352, + 528,768, 536,4864, 544,1280, 552,5376, 560,1792, 568,5888, 576,2304, + 584,6400, 592,2816, 600,6912, 608,3328, 616,7424, 624,3840, 632,7936, + 640,2176, 648,4416, 656,832, 664,4928, 672,1344, 680,5440, 688,1856, + 696,5952, 704,2368, 712,6464, 720,2880, 728,6976, 736,3392, 744,7488, + 752,3904, 760,8000, 768,2112, 776,4480, 784,896, 792,4992, 800,1408, + 808,5504, 816,1920, 824,6016, 832,2432, 840,6528, 848,2944, 856,7040, + 864,3456, 872,7552, 880,3968, 888,8064, 896,2240, 904,4544, 912,960, + 920,5056, 928,1472, 936,5568, 944,1984, 952,6080, 960,2496, 968,6592, + 976,3008, 984,7104, 992,3520, 1000,7616, 1008,4032, 1016,8128, 1024,4096, + 1032,4104, 1040,4352, 1048,4616, 1056,4104, 1064,5128, 1072,1544, + 1080,5640, 1088,2056, 1096,6152, 1104,2568, 1112,6664, 1120,3080, + 1128,7176, 1136,3592, 1144,7688, 1152,6144, 1160,4168, 1168,6400, + 1176,4680, 1184,6152, 1192,5192, 1200,1608, 1208,5704, 1216,2120, + 1224,6216, 1232,2632, 1240,6728, 1248,3144, 1256,7240, 1264,3656, + 1272,7752, 1280,4160, 1288,4232, 1296,4416, 1304,4744, 1312,4168, + 1320,5256, 1328,1672, 1336,5768, 1344,2184, 1352,6280, 1360,2696, + 1368,6792, 1376,3208, 1384,7304, 1392,3720, 1400,7816, 1408,6208, + 1416,4296, 1424,6464, 1432,4808, 1440,6216, 1448,5320, 1456,1736, + 1464,5832, 1472,2248, 1480,6344, 1488,2760, 1496,6856, 1504,3272, + 1512,7368, 1520,3784, 1528,7880, 1536,4224, 1544,4360, 1552,4480, + 1560,4872, 1568,4232, 1576,5384, 1584,1800, 1592,5896, 1600,2312, + 1608,6408, 1616,2824, 1624,6920, 1632,3336, 1640,7432, 1648,3848, + 1656,7944, 1664,6272, 1672,4424, 1680,6528, 1688,4936, 1696,6280, + 1704,5448, 1712,1864, 1720,5960, 1728,2376, 1736,6472, 1744,2888, + 1752,6984, 1760,3400, 1768,7496, 1776,3912, 1784,8008, 1792,4288, + 1800,4488, 1808,4544, 1816,5000, 1824,4296, 1832,5512, 1840,1928, + 1848,6024, 1856,2440, 1864,6536, 1872,2952, 1880,7048, 1888,3464, + 1896,7560, 1904,3976, 1912,8072, 1920,6336, 1928,4552, 1936,6592, + 1944,5064, 1952,6344, 1960,5576, 1968,1992, 1976,6088, 1984,2504, + 1992,6600, 2000,3016, 2008,7112, 2016,3528, 2024,7624, 2032,4040, + 2040,8136, 2056,4112, 2064,2112, 2072,4624, 2080,4352, 2088,5136, + 2096,4480, 2104,5648, 2120,6160, 2128,2576, 2136,6672, 2144,3088, + 2152,7184, 2160,3600, 2168,7696, 2176,2560, 2184,4176, 2192,2816, + 2200,4688, 2208,2568, 2216,5200, 2224,2824, 2232,5712, 2240,2576, + 2248,6224, 2256,2640, 2264,6736, 2272,3152, 2280,7248, 2288,3664, + 2296,7760, 2312,4240, 2320,2432, 2328,4752, 2336,6400, 2344,5264, + 2352,6528, 2360,5776, 2368,2816, 2376,6288, 2384,2704, 2392,6800, + 2400,3216, 2408,7312, 2416,3728, 2424,7824, 2432,2624, 2440,4304, + 2448,2880, 2456,4816, 2464,2632, 2472,5328, 2480,2888, 2488,5840, + 2496,2640, 2504,6352, 2512,2768, 2520,6864, 2528,3280, 2536,7376, + 2544,3792, 2552,7888, 2568,4368, 2584,4880, 2592,4416, 2600,5392, + 2608,4544, 2616,5904, 2632,6416, 2640,2832, 2648,6928, 2656,3344, + 2664,7440, 2672,3856, 2680,7952, 2696,4432, 2704,2944, 2712,4944, + 2720,4432, 2728,5456, 2736,2952, 2744,5968, 2752,2944, 2760,6480, + 2768,2896, 2776,6992, 2784,3408, 2792,7504, 2800,3920, 2808,8016, + 2824,4496, 2840,5008, 2848,6464, 2856,5520, 2864,6592, 2872,6032, + 2888,6544, 2896,2960, 2904,7056, 2912,3472, 2920,7568, 2928,3984, + 2936,8080, 2952,4560, 2960,3008, 2968,5072, 2976,6480, 2984,5584, + 2992,3016, 3000,6096, 3016,6608, 3032,7120, 3040,3536, 3048,7632, + 3056,4048, 3064,8144, 3072,4608, 3080,4120, 3088,4864, 3096,4632, + 3104,4616, 3112,5144, 3120,4872, 3128,5656, 3136,4624, 3144,6168, + 3152,4880, 3160,6680, 3168,4632, 3176,7192, 3184,3608, 3192,7704, + 3200,6656, 3208,4184, 3216,6912, 3224,4696, 3232,6664, 3240,5208, + 3248,6920, 3256,5720, 3264,6672, 3272,6232, 3280,6928, 3288,6744, + 3296,6680, 3304,7256, 3312,3672, 3320,7768, 3328,4672, 3336,4248, + 3344,4928, 3352,4760, 3360,4680, 3368,5272, 3376,4936, 3384,5784, + 3392,4688, 3400,6296, 3408,4944, 3416,6808, 3424,4696, 3432,7320, + 3440,3736, 3448,7832, 3456,6720, 3464,4312, 3472,6976, 3480,4824, + 3488,6728, 3496,5336, 3504,6984, 3512,5848, 3520,6736, 3528,6360, + 3536,6992, 3544,6872, 3552,6744, 3560,7384, 3568,3800, 3576,7896, + 3584,4736, 3592,4376, 3600,4992, 3608,4888, 3616,4744, 3624,5400, + 3632,5000, 3640,5912, 3648,4752, 3656,6424, 3664,5008, 3672,6936, + 3680,4760, 3688,7448, 3696,3864, 3704,7960, 3712,6784, 3720,4440, + 3728,7040, 3736,4952, 3744,6792, 3752,5464, 3760,7048, 3768,5976, + 3776,6800, 3784,6488, 3792,7056, 3800,7000, 3808,6808, 3816,7512, + 3824,3928, 3832,8024, 3840,4800, 3848,4504, 3856,5056, 3864,5016, + 3872,4808, 3880,5528, 3888,5064, 3896,6040, 3904,4816, 3912,6552, + 3920,5072, 3928,7064, 3936,4824, 3944,7576, 3952,3992, 3960,8088, + 3968,6848, 3976,4568, 3984,7104, 3992,5080, 4000,6856, 4008,5592, + 4016,7112, 4024,6104, 4032,6864, 4040,6616, 4048,7120, 4056,7128, + 4064,6872, 4072,7640, 4080,7128, 4088,8152, 4104,4128, 4112,4160, + 4120,4640, 4136,5152, 4144,4232, 4152,5664, 4160,4352, 4168,6176, + 4176,4416, 4184,6688, 4192,4616, 4200,7200, 4208,4744, 4216,7712, + 4224,4608, 4232,4616, 4240,4672, 4248,4704, 4256,4640, 4264,5216, + 4272,4704, 4280,5728, 4288,4864, 4296,6240, 4304,4928, 4312,6752, + 4320,4632, 4328,7264, 4336,4760, 4344,7776, 4360,4640, 4368,4416, + 4376,4768, 4384,6152, 4392,5280, 4400,6280, 4408,5792, 4424,6304, + 4440,6816, 4448,6664, 4456,7328, 4464,6792, 4472,7840, 4480,4624, + 4488,4632, 4496,4688, 4504,4832, 4512,6168, 4520,5344, 4528,6296, + 4536,5856, 4544,4880, 4552,6368, 4560,4944, 4568,6880, 4576,6680, + 4584,7392, 4592,6808, 4600,7904, 4608,6144, 4616,6152, 4624,6208, + 4632,4896, 4640,6176, 4648,5408, 4656,6240, 4664,5920, 4672,6400, + 4680,6432, 4688,6464, 4696,6944, 4704,6432, 4712,7456, 4720,4808, + 4728,7968, 4736,6656, 4744,6664, 4752,6720, 4760,4960, 4768,6688, + 4776,5472, 4784,6752, 4792,5984, 4800,6912, 4808,6496, 4816,6976, + 4824,7008, 4832,6944, 4840,7520, 4848,7008, 4856,8032, 4864,6160, + 4872,6168, 4880,6224, 4888,5024, 4896,6216, 4904,5536, 4912,6344, + 4920,6048, 4928,6416, 4936,6560, 4944,6480, 4952,7072, 4960,6728, + 4968,7584, 4976,6856, 4984,8096, 4992,6672, 5000,6680, 5008,6736, + 5016,5088, 5024,6232, 5032,5600, 5040,6360, 5048,6112, 5056,6928, + 5064,6624, 5072,6992, 5080,7136, 5088,6744, 5096,7648, 5104,6872, + 5112,8160, 5128,5152, 5136,5376, 5144,5408, 5168,5384, 5176,5672, + 5184,5376, 5192,6184, 5200,5392, 5208,6696, 5216,5408, 5224,7208, + 5232,5400, 5240,7720, 5248,7168, 5256,7200, 5264,7424, 5272,7456, + 5280,7176, 5288,7208, 5296,7432, 5304,5736, 5312,7184, 5320,6248, + 5328,7440, 5336,6760, 5344,7192, 5352,7272, 5360,7448, 5368,7784, + 5384,5408, 5392,5440, 5400,5472, 5408,6184, 5416,7208, 5424,5448, + 5432,5800, 5448,6312, 5464,6824, 5472,6696, 5480,7336, 5488,6824, + 5496,7848, 5504,7232, 5512,7264, 5520,7488, 5528,7520, 5536,7240, + 5544,7272, 5552,7496, 5560,5864, 5568,7248, 5576,6376, 5584,7504, + 5592,6888, 5600,7256, 5608,7400, 5616,7512, 5624,7912, 5632,7168, + 5640,7176, 5648,7232, 5656,7240, 5664,7200, 5672,7208, 5680,7264, + 5688,5928, 5696,7424, 5704,6440, 5712,7488, 5720,6952, 5728,7456, + 5736,7464, 5744,7520, 5752,7976, 5760,7296, 5768,7328, 5776,7552, + 5784,7584, 5792,7304, 5800,7336, 5808,7560, 5816,5992, 5824,7312, + 5832,6504, 5840,7568, 5848,7016, 5856,7320, 5864,7528, 5872,7576, + 5880,8040, 5888,7184, 5896,7192, 5904,7248, 5912,7256, 5920,6248, + 5928,7272, 5936,6376, 5944,6056, 5952,7440, 5960,6568, 5968,7504, + 5976,7080, 5984,6760, 5992,7592, 6000,6888, 6008,8104, 6016,7360, + 6024,7392, 6032,7616, 6040,7648, 6048,7368, 6056,7400, 6064,7624, + 6072,6120, 6080,7376, 6088,6632, 6096,7632, 6104,7144, 6112,7384, + 6120,7656, 6128,7640, 6136,8168, 6168,6240, 6192,6216, 6200,7264, + 6232,6704, 6248,7216, 6256,6680, 6264,7728, 6272,6656, 6280,6664, + 6288,6912, 6296,6496, 6304,6688, 6312,6696, 6320,6944, 6328,7520, + 6336,6672, 6344,6680, 6352,6928, 6360,6768, 6368,6704, 6376,7280, + 6384,6744, 6392,7792, 6408,6432, 6424,6752, 6440,7432, 6448,6536, + 6456,7560, 6472,6944, 6488,6832, 6496,6920, 6504,7344, 6512,7048, + 6520,7856, 6528,6720, 6536,6728, 6544,6976, 6552,7008, 6560,6752, + 6568,7448, 6576,7008, 6584,7576, 6592,6736, 6600,6744, 6608,6992, + 6616,6896, 6624,6936, 6632,7408, 6640,7064, 6648,7920, 6712,7280, + 6744,6960, 6760,7472, 6768,6936, 6776,7984, 6800,6848, 6808,6856, + 6832,6880, 6840,6888, 6848,7040, 6856,7048, 6864,7104, 6872,7024, + 6880,7072, 6888,7536, 6896,7136, 6904,8048, 6952,7496, 6968,7624, + 6984,7008, 7000,7088, 7016,7600, 7024,7112, 7032,8112, 7056,7104, + 7064,7112, 7080,7512, 7088,7136, 7096,7640, 7128,7152, 7144,7664, + 7160,8176, 7176,7200, 7192,7216, 7224,7272, 7240,7264, 7256,7280, + 7288,7736, 7296,7680, 7304,7712, 7312,7936, 7320,7968, 7328,7688, + 7336,7720, 7344,7944, 7352,7976, 7360,7696, 7368,7728, 7376,7952, + 7384,7984, 7392,7704, 7400,7736, 7408,7960, 7416,7800, 7432,7456, + 7448,7472, 7480,7592, 7496,7520, 7512,7536, 7528,7976, 7544,7864, + 7552,7744, 7560,7776, 7568,8000, 7576,8032, 7584,7752, 7592,7784, + 7600,8008, 7608,8040, 7616,7760, 7624,7792, 7632,8016, 7640,8048, + 7648,7768, 7656,7800, 7664,8024, 7672,7928, 7688,7712, 7704,7728, + 7752,7776, 7768,7792, 7800,7992, 7816,7840, 7824,8064, 7832,8096, + 7856,8072, 7864,8104, 7872,8064, 7880,8072, 7888,8080, 7896,8112, + 7904,8096, 7912,8104, 7920,8088, 7928,8056, 7944,7968, 7960,7984, + 8008,8032, 8024,8048, 8056,8120, 8072,8096, 8080,8128, 8088,8160, + 8112,8136, 8120,8168, 8136,8160, 8152,8176 +}; + +const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH] = +{ + /* 8x2, size 3808 */ + 8,4096, 16,8192, 24,12288, 32,512, 40,4608, 48,8704, 56,12800, 64,1024, + 72,5120, 80,9216, 88,13312, 96,1536, 104,5632, 112,9728, 120,13824, + 128,2048, 136,6144, 144,10240, 152,14336, 160,2560, 168,6656, 176,10752, + 184,14848, 192,3072, 200,7168, 208,11264, 216,15360, 224,3584, 232,7680, + 240,11776, 248,15872, 256,1024, 264,4160, 272,8256, 280,12352, 288,576, + 296,4672, 304,8768, 312,12864, 320,1088, 328,5184, 336,9280, 344,13376, + 352,1600, 360,5696, 368,9792, 376,13888, 384,2112, 392,6208, 400,10304, + 408,14400, 416,2624, 424,6720, 432,10816, 440,14912, 448,3136, 456,7232, + 464,11328, 472,15424, 480,3648, 488,7744, 496,11840, 504,15936, 512,2048, + 520,4224, 528,8320, 536,12416, 544,640, 552,4736, 560,8832, 568,12928, + 576,1152, 584,5248, 592,9344, 600,13440, 608,1664, 616,5760, 624,9856, + 632,13952, 640,2176, 648,6272, 656,10368, 664,14464, 672,2688, 680,6784, + 688,10880, 696,14976, 704,3200, 712,7296, 720,11392, 728,15488, 736,3712, + 744,7808, 752,11904, 760,16000, 768,3072, 776,4288, 784,8384, 792,12480, + 800,3200, 808,4800, 816,8896, 824,12992, 832,1216, 840,5312, 848,9408, + 856,13504, 864,1728, 872,5824, 880,9920, 888,14016, 896,2240, 904,6336, + 912,10432, 920,14528, 928,2752, 936,6848, 944,10944, 952,15040, 960,3264, + 968,7360, 976,11456, 984,15552, 992,3776, 1000,7872, 1008,11968, 1016,16064, + 1032,4352, 1040,8448, 1048,12544, 1056,3072, 1064,4864, 1072,8960, + 1080,13056, 1088,1280, 1096,5376, 1104,9472, 1112,13568, 1120,1792, + 1128,5888, 1136,9984, 1144,14080, 1152,2304, 1160,6400, 1168,10496, + 1176,14592, 1184,2816, 1192,6912, 1200,11008, 1208,15104, 1216,3328, + 1224,7424, 1232,11520, 1240,15616, 1248,3840, 1256,7936, 1264,12032, + 1272,16128, 1288,4416, 1296,8512, 1304,12608, 1312,3328, 1320,4928, + 1328,9024, 1336,13120, 1352,5440, 1360,9536, 1368,13632, 1376,1856, + 1384,5952, 1392,10048, 1400,14144, 1408,2368, 1416,6464, 1424,10560, + 1432,14656, 1440,2880, 1448,6976, 1456,11072, 1464,15168, 1472,3392, + 1480,7488, 1488,11584, 1496,15680, 1504,3904, 1512,8000, 1520,12096, + 1528,16192, 1536,2112, 1544,4480, 1552,8576, 1560,12672, 1568,2240, + 1576,4992, 1584,9088, 1592,13184, 1600,2368, 1608,5504, 1616,9600, + 1624,13696, 1632,1920, 1640,6016, 1648,10112, 1656,14208, 1664,2432, + 1672,6528, 1680,10624, 1688,14720, 1696,2944, 1704,7040, 1712,11136, + 1720,15232, 1728,3456, 1736,7552, 1744,11648, 1752,15744, 1760,3968, + 1768,8064, 1776,12160, 1784,16256, 1792,3136, 1800,4544, 1808,8640, + 1816,12736, 1824,3264, 1832,5056, 1840,9152, 1848,13248, 1856,3392, + 1864,5568, 1872,9664, 1880,13760, 1888,1984, 1896,6080, 1904,10176, + 1912,14272, 1920,2496, 1928,6592, 1936,10688, 1944,14784, 1952,3008, + 1960,7104, 1968,11200, 1976,15296, 1984,3520, 1992,7616, 2000,11712, + 2008,15808, 2016,4032, 2024,8128, 2032,12224, 2040,16320, 2048,4096, + 2056,4104, 2064,8200, 2072,12296, 2080,4224, 2088,4616, 2096,8712, + 2104,12808, 2112,4352, 2120,5128, 2128,9224, 2136,13320, 2144,4480, + 2152,5640, 2160,9736, 2168,13832, 2176,4104, 2184,6152, 2192,10248, + 2200,14344, 2208,2568, 2216,6664, 2224,10760, 2232,14856, 2240,3080, + 2248,7176, 2256,11272, 2264,15368, 2272,3592, 2280,7688, 2288,11784, + 2296,15880, 2304,5120, 2312,4168, 2320,8264, 2328,12360, 2336,5248, + 2344,4680, 2352,8776, 2360,12872, 2368,5376, 2376,5192, 2384,9288, + 2392,13384, 2400,5504, 2408,5704, 2416,9800, 2424,13896, 2432,5128, + 2440,6216, 2448,10312, 2456,14408, 2464,2632, 2472,6728, 2480,10824, + 2488,14920, 2496,3144, 2504,7240, 2512,11336, 2520,15432, 2528,3656, + 2536,7752, 2544,11848, 2552,15944, 2560,6144, 2568,4232, 2576,8328, + 2584,12424, 2592,6272, 2600,4744, 2608,8840, 2616,12936, 2624,6400, + 2632,5256, 2640,9352, 2648,13448, 2656,6528, 2664,5768, 2672,9864, + 2680,13960, 2688,6152, 2696,6280, 2704,10376, 2712,14472, 2720,6280, + 2728,6792, 2736,10888, 2744,14984, 2752,3208, 2760,7304, 2768,11400, + 2776,15496, 2784,3720, 2792,7816, 2800,11912, 2808,16008, 2816,7168, + 2824,4296, 2832,8392, 2840,12488, 2848,7296, 2856,4808, 2864,8904, + 2872,13000, 2880,7424, 2888,5320, 2896,9416, 2904,13512, 2912,7552, + 2920,5832, 2928,9928, 2936,14024, 2944,7176, 2952,6344, 2960,10440, + 2968,14536, 2976,7304, 2984,6856, 2992,10952, 3000,15048, 3008,3272, + 3016,7368, 3024,11464, 3032,15560, 3040,3784, 3048,7880, 3056,11976, + 3064,16072, 3072,4160, 3080,4360, 3088,8456, 3096,12552, 3104,4288, + 3112,4872, 3120,8968, 3128,13064, 3136,4416, 3144,5384, 3152,9480, + 3160,13576, 3168,4544, 3176,5896, 3184,9992, 3192,14088, 3200,4168, + 3208,6408, 3216,10504, 3224,14600, 3232,4296, 3240,6920, 3248,11016, + 3256,15112, 3264,3336, 3272,7432, 3280,11528, 3288,15624, 3296,3848, + 3304,7944, 3312,12040, 3320,16136, 3328,5184, 3336,4424, 3344,8520, + 3352,12616, 3360,5312, 3368,4936, 3376,9032, 3384,13128, 3392,5440, + 3400,5448, 3408,9544, 3416,13640, 3424,5568, 3432,5960, 3440,10056, + 3448,14152, 3456,5192, 3464,6472, 3472,10568, 3480,14664, 3488,5320, + 3496,6984, 3504,11080, 3512,15176, 3520,5448, 3528,7496, 3536,11592, + 3544,15688, 3552,3912, 3560,8008, 3568,12104, 3576,16200, 3584,6208, + 3592,4488, 3600,8584, 3608,12680, 3616,6336, 3624,5000, 3632,9096, + 3640,13192, 3648,6464, 3656,5512, 3664,9608, 3672,13704, 3680,6592, + 3688,6024, 3696,10120, 3704,14216, 3712,6216, 3720,6536, 3728,10632, + 3736,14728, 3744,6344, 3752,7048, 3760,11144, 3768,15240, 3776,6472, + 3784,7560, 3792,11656, 3800,15752, 3808,3976, 3816,8072, 3824,12168, + 3832,16264, 3840,7232, 3848,4552, 3856,8648, 3864,12744, 3872,7360, + 3880,5064, 3888,9160, 3896,13256, 3904,7488, 3912,5576, 3920,9672, + 3928,13768, 3936,7616, 3944,6088, 3952,10184, 3960,14280, 3968,7240, + 3976,6600, 3984,10696, 3992,14792, 4000,7368, 4008,7112, 4016,11208, + 4024,15304, 4032,7496, 4040,7624, 4048,11720, 4056,15816, 4064,7624, + 4072,8136, 4080,12232, 4088,16328, 4096,8192, 4104,4112, 4112,8208, + 4120,12304, 4128,8320, 4136,4624, 4144,8720, 4152,12816, 4160,8448, + 4168,5136, 4176,9232, 4184,13328, 4192,8576, 4200,5648, 4208,9744, + 4216,13840, 4224,8200, 4232,6160, 4240,10256, 4248,14352, 4256,8328, + 4264,6672, 4272,10768, 4280,14864, 4288,8456, 4296,7184, 4304,11280, + 4312,15376, 4320,8584, 4328,7696, 4336,11792, 4344,15888, 4352,9216, + 4360,9232, 4368,8272, 4376,12368, 4384,9344, 4392,4688, 4400,8784, + 4408,12880, 4416,9472, 4424,5200, 4432,9296, 4440,13392, 4448,9600, + 4456,5712, 4464,9808, 4472,13904, 4480,9224, 4488,6224, 4496,10320, + 4504,14416, 4512,9352, 4520,6736, 4528,10832, 4536,14928, 4544,9480, + 4552,7248, 4560,11344, 4568,15440, 4576,9608, 4584,7760, 4592,11856, + 4600,15952, 4608,10240, 4616,10256, 4624,8336, 4632,12432, 4640,10368, + 4648,4752, 4656,8848, 4664,12944, 4672,10496, 4680,5264, 4688,9360, + 4696,13456, 4704,10624, 4712,5776, 4720,9872, 4728,13968, 4736,10248, + 4744,6288, 4752,10384, 4760,14480, 4768,10376, 4776,6800, 4784,10896, + 4792,14992, 4800,10504, 4808,7312, 4816,11408, 4824,15504, 4832,10632, + 4840,7824, 4848,11920, 4856,16016, 4864,11264, 4872,11280, 4880,8400, + 4888,12496, 4896,11392, 4904,11408, 4912,8912, 4920,13008, 4928,11520, + 4936,5328, 4944,9424, 4952,13520, 4960,11648, 4968,5840, 4976,9936, + 4984,14032, 4992,11272, 5000,6352, 5008,10448, 5016,14544, 5024,11400, + 5032,6864, 5040,10960, 5048,15056, 5056,11528, 5064,7376, 5072,11472, + 5080,15568, 5088,11656, 5096,7888, 5104,11984, 5112,16080, 5120,8256, + 5128,8272, 5136,8464, 5144,12560, 5152,8384, 5160,8400, 5168,8976, + 5176,13072, 5184,8512, 5192,5392, 5200,9488, 5208,13584, 5216,8640, + 5224,5904, 5232,10000, 5240,14096, 5248,8264, 5256,6416, 5264,10512, + 5272,14608, 5280,8392, 5288,6928, 5296,11024, 5304,15120, 5312,8520, + 5320,7440, 5328,11536, 5336,15632, 5344,8648, 5352,7952, 5360,12048, + 5368,16144, 5376,9280, 5384,9296, 5392,8528, 5400,12624, 5408,9408, + 5416,9424, 5424,9040, 5432,13136, 5440,9536, 5448,5456, 5456,9552, + 5464,13648, 5472,9664, 5480,5968, 5488,10064, 5496,14160, 5504,9288, + 5512,6480, 5520,10576, 5528,14672, 5536,9416, 5544,6992, 5552,11088, + 5560,15184, 5568,9544, 5576,7504, 5584,11600, 5592,15696, 5600,9672, + 5608,8016, 5616,12112, 5624,16208, 5632,10304, 5640,10320, 5648,8592, + 5656,12688, 5664,10432, 5672,10448, 5680,9104, 5688,13200, 5696,10560, + 5704,10576, 5712,9616, 5720,13712, 5728,10688, 5736,6032, 5744,10128, + 5752,14224, 5760,10312, 5768,6544, 5776,10640, 5784,14736, 5792,10440, + 5800,7056, 5808,11152, 5816,15248, 5824,10568, 5832,7568, 5840,11664, + 5848,15760, 5856,10696, 5864,8080, 5872,12176, 5880,16272, 5888,11328, + 5896,11344, 5904,8656, 5912,12752, 5920,11456, 5928,11472, 5936,9168, + 5944,13264, 5952,11584, 5960,11600, 5968,9680, 5976,13776, 5984,11712, + 5992,6096, 6000,10192, 6008,14288, 6016,11336, 6024,6608, 6032,10704, + 6040,14800, 6048,11464, 6056,7120, 6064,11216, 6072,15312, 6080,11592, + 6088,7632, 6096,11728, 6104,15824, 6112,11720, 6120,8144, 6128,12240, + 6136,16336, 6144,12288, 6152,12304, 6160,8216, 6168,12312, 6176,12416, + 6184,12432, 6192,8728, 6200,12824, 6208,12544, 6216,12560, 6224,9240, + 6232,13336, 6240,12672, 6248,12688, 6256,9752, 6264,13848, 6272,12296, + 6280,12312, 6288,10264, 6296,14360, 6304,12424, 6312,6680, 6320,10776, + 6328,14872, 6336,12552, 6344,7192, 6352,11288, 6360,15384, 6368,12680, + 6376,7704, 6384,11800, 6392,15896, 6400,13312, 6408,13328, 6416,8280, + 6424,12376, 6432,13440, 6440,13456, 6448,8792, 6456,12888, 6464,13568, + 6472,13584, 6480,9304, 6488,13400, 6496,13696, 6504,13712, 6512,9816, + 6520,13912, 6528,13320, 6536,13336, 6544,10328, 6552,14424, 6560,13448, + 6568,6744, 6576,10840, 6584,14936, 6592,13576, 6600,7256, 6608,11352, + 6616,15448, 6624,13704, 6632,7768, 6640,11864, 6648,15960, 6656,14336, + 6664,14352, 6672,8344, 6680,12440, 6688,14464, 6696,14480, 6704,8856, + 6712,12952, 6720,14592, 6728,14608, 6736,9368, 6744,13464, 6752,14720, + 6760,14736, 6768,9880, 6776,13976, 6784,14344, 6792,14360, 6800,10392, + 6808,14488, 6816,14472, 6824,14488, 6832,10904, 6840,15000, 6848,14600, + 6856,7320, 6864,11416, 6872,15512, 6880,14728, 6888,7832, 6896,11928, + 6904,16024, 6912,15360, 6920,15376, 6928,8408, 6936,12504, 6944,15488, + 6952,15504, 6960,8920, 6968,13016, 6976,15616, 6984,15632, 6992,9432, + 7000,13528, 7008,15744, 7016,15760, 7024,9944, 7032,14040, 7040,15368, + 7048,15384, 7056,10456, 7064,14552, 7072,15496, 7080,15512, 7088,10968, + 7096,15064, 7104,15624, 7112,7384, 7120,11480, 7128,15576, 7136,15752, + 7144,7896, 7152,11992, 7160,16088, 7168,12352, 7176,12368, 7184,8472, + 7192,12568, 7200,12480, 7208,12496, 7216,8984, 7224,13080, 7232,12608, + 7240,12624, 7248,9496, 7256,13592, 7264,12736, 7272,12752, 7280,10008, + 7288,14104, 7296,12360, 7304,12376, 7312,10520, 7320,14616, 7328,12488, + 7336,12504, 7344,11032, 7352,15128, 7360,12616, 7368,7448, 7376,11544, + 7384,15640, 7392,12744, 7400,7960, 7408,12056, 7416,16152, 7424,13376, + 7432,13392, 7440,8536, 7448,12632, 7456,13504, 7464,13520, 7472,9048, + 7480,13144, 7488,13632, 7496,13648, 7504,9560, 7512,13656, 7520,13760, + 7528,13776, 7536,10072, 7544,14168, 7552,13384, 7560,13400, 7568,10584, + 7576,14680, 7584,13512, 7592,13528, 7600,11096, 7608,15192, 7616,13640, + 7624,13656, 7632,11608, 7640,15704, 7648,13768, 7656,8024, 7664,12120, + 7672,16216, 7680,14400, 7688,14416, 7696,8600, 7704,12696, 7712,14528, + 7720,14544, 7728,9112, 7736,13208, 7744,14656, 7752,14672, 7760,9624, + 7768,13720, 7776,14784, 7784,14800, 7792,10136, 7800,14232, 7808,14408, + 7816,14424, 7824,10648, 7832,14744, 7840,14536, 7848,14552, 7856,11160, + 7864,15256, 7872,14664, 7880,14680, 7888,11672, 7896,15768, 7904,14792, + 7912,8088, 7920,12184, 7928,16280, 7936,15424, 7944,15440, 7952,8664, + 7960,12760, 7968,15552, 7976,15568, 7984,9176, 7992,13272, 8000,15680, + 8008,15696, 8016,9688, 8024,13784, 8032,15808, 8040,15824, 8048,10200, + 8056,14296, 8064,15432, 8072,15448, 8080,10712, 8088,14808, 8096,15560, + 8104,15576, 8112,11224, 8120,15320, 8128,15688, 8136,15704, 8144,11736, + 8152,15832, 8160,15816, 8168,15832, 8176,12248, 8184,16344, 8200,8320, + 8208,8224, 8216,12320, 8232,10368, 8240,8736, 8248,12832, 8256,8448, + 8264,8384, 8272,9248, 8280,13344, 8288,9232, 8296,10432, 8304,9760, + 8312,13856, 8328,12416, 8336,10272, 8344,14368, 8352,12296, 8360,14464, + 8368,10784, 8376,14880, 8384,8456, 8392,12480, 8400,11296, 8408,15392, + 8416,12552, 8424,14528, 8432,11808, 8440,15904, 8448,9216, 8456,8576, + 8464,9232, 8472,12384, 8480,9248, 8488,10624, 8496,8800, 8504,12896, + 8512,9472, 8520,8640, 8528,9312, 8536,13408, 8544,9296, 8552,10688, + 8560,9824, 8568,13920, 8576,9224, 8584,12672, 8592,10336, 8600,14432, + 8608,13320, 8616,14720, 8624,10848, 8632,14944, 8640,9480, 8648,12736, + 8656,11360, 8664,15456, 8672,13576, 8680,14784, 8688,11872, 8696,15968, + 8704,12288, 8712,12416, 8720,12296, 8728,12448, 8736,12304, 8744,10376, + 8752,8864, 8760,12960, 8768,12352, 8776,12480, 8784,9376, 8792,13472, + 8800,12368, 8808,10440, 8816,9888, 8824,13984, 8832,12320, 8840,12424, + 8848,10400, 8856,14496, 8864,12312, 8872,14472, 8880,10912, 8888,15008, + 8896,12384, 8904,12488, 8912,11424, 8920,15520, 8928,12568, 8936,14536, + 8944,11936, 8952,16032, 8960,12544, 8968,12672, 8976,12552, 8984,12512, + 8992,12560, 9000,10632, 9008,12568, 9016,13024, 9024,12608, 9032,12736, + 9040,9440, 9048,13536, 9056,12624, 9064,10696, 9072,9952, 9080,14048, + 9088,9240, 9096,12680, 9104,10464, 9112,14560, 9120,13336, 9128,14728, + 9136,10976, 9144,15072, 9152,9496, 9160,12744, 9168,11488, 9176,15584, + 9184,13592, 9192,14792, 9200,12000, 9208,16096, 9224,9344, 9232,9248, + 9240,12576, 9256,11392, 9264,12560, 9272,13088, 9280,9472, 9288,9408, + 9296,9504, 9304,13600, 9312,9488, 9320,11456, 9328,10016, 9336,14112, + 9352,13440, 9360,10528, 9368,14624, 9376,12360, 9384,15488, 9392,11040, + 9400,15136, 9408,9480, 9416,13504, 9424,11552, 9432,15648, 9440,12616, + 9448,15552, 9456,12064, 9464,16160, 9480,9600, 9488,9504, 9496,12640, + 9512,11648, 9520,12624, 9528,13152, 9544,9664, 9552,9568, 9560,13664, + 9576,11712, 9584,10080, 9592,14176, 9608,13696, 9616,10592, 9624,14688, + 9632,13384, 9640,15744, 9648,11104, 9656,15200, 9672,13760, 9680,11616, + 9688,15712, 9696,13640, 9704,15808, 9712,12128, 9720,16224, 9728,13312, + 9736,13440, 9744,13320, 9752,12704, 9760,13328, 9768,11400, 9776,13336, + 9784,13216, 9792,13376, 9800,13504, 9808,13384, 9816,13728, 9824,13392, + 9832,11464, 9840,10144, 9848,14240, 9856,13344, 9864,13448, 9872,10656, + 9880,14752, 9888,12376, 9896,15496, 9904,11168, 9912,15264, 9920,13408, + 9928,13512, 9936,11680, 9944,15776, 9952,12632, 9960,15560, 9968,12192, + 9976,16288, 9984,13568, 9992,13696, 10000,13576, 10008,12768, 10016,13584, + 10024,11656, 10032,13592, 10040,13280, 10048,13632, 10056,13760, + 10064,13640, 10072,13792, 10080,13648, 10088,11720, 10096,10208, + 10104,14304, 10112,13600, 10120,13704, 10128,10720, 10136,14816, + 10144,13400, 10152,15752, 10160,11232, 10168,15328, 10176,13664, + 10184,13768, 10192,11744, 10200,15840, 10208,13656, 10216,15816, + 10224,12256, 10232,16352, 10248,10272, 10256,10368, 10264,12328, + 10280,10384, 10288,10376, 10296,12840, 10304,11264, 10312,11296, + 10320,11392, 10328,13352, 10336,11272, 10344,10448, 10352,11400, + 10360,13864, 10376,12432, 10392,14376, 10400,12328, 10408,14480, + 10416,10792, 10424,14888, 10432,11280, 10440,12496, 10448,11304, + 10456,15400, 10464,11288, 10472,14544, 10480,11816, 10488,15912, + 10496,11264, 10504,11272, 10512,11280, 10520,12392, 10528,11296, + 10536,10640, 10544,12496, 10552,12904, 10560,11328, 10568,11360, + 10576,11456, 10584,13416, 10592,11336, 10600,10704, 10608,11464, + 10616,13928, 10624,11392, 10632,12688, 10640,11304, 10648,14440, + 10656,13352, 10664,14736, 10672,10856, 10680,14952, 10688,11344, + 10696,12752, 10704,11368, 10712,15464, 10720,11352, 10728,14800, + 10736,11880, 10744,15976, 10752,14336, 10760,14368, 10768,14464, + 10776,12456, 10784,14344, 10792,14376, 10800,14472, 10808,12968, + 10816,15360, 10824,15392, 10832,15488, 10840,13480, 10848,15368, + 10856,15400, 10864,15496, 10872,13992, 10880,14352, 10888,12440, + 10896,14480, 10904,14504, 10912,14360, 10920,14488, 10928,14488, + 10936,15016, 10944,15376, 10952,12504, 10960,11432, 10968,15528, + 10976,15384, 10984,14552, 10992,11944, 11000,16040, 11008,14400, + 11016,14432, 11024,14528, 11032,12520, 11040,14408, 11048,14440, + 11056,14536, 11064,13032, 11072,15424, 11080,15456, 11088,15552, + 11096,13544, 11104,15432, 11112,15464, 11120,15560, 11128,14056, + 11136,14416, 11144,12696, 11152,14544, 11160,14568, 11168,14424, + 11176,14744, 11184,14552, 11192,15080, 11200,15440, 11208,12760, + 11216,11496, 11224,15592, 11232,15448, 11240,14808, 11248,12008, + 11256,16104, 11272,11296, 11280,11392, 11288,12584, 11304,11408, + 11312,12688, 11320,13096, 11328,11520, 11336,11552, 11344,11648, + 11352,13608, 11360,11528, 11368,11472, 11376,11656, 11384,14120, + 11400,13456, 11416,14632, 11424,12392, 11432,15504, 11440,14440, + 11448,15144, 11456,11536, 11464,13520, 11472,11560, 11480,15656, + 11488,11544, 11496,15568, 11504,12072, 11512,16168, 11528,11552, + 11536,11648, 11544,12648, 11560,11664, 11568,12752, 11576,13160, + 11592,11616, 11600,11712, 11608,13672, 11624,11728, 11632,11720, + 11640,14184, 11656,13712, 11672,14696, 11680,13416, 11688,15760, + 11696,15464, 11704,15208, 11720,13776, 11736,15720, 11744,13672, + 11752,15824, 11760,12136, 11768,16232, 11776,14592, 11784,14624, + 11792,14720, 11800,12712, 11808,14600, 11816,14632, 11824,14728, + 11832,13224, 11840,15616, 11848,15648, 11856,15744, 11864,13736, + 11872,15624, 11880,15656, 11888,15752, 11896,14248, 11904,14608, + 11912,13464, 11920,14736, 11928,14760, 11936,14616, 11944,15512, + 11952,14744, 11960,15272, 11968,15632, 11976,13528, 11984,15760, + 11992,15784, 12000,15640, 12008,15576, 12016,12200, 12024,16296, + 12032,14656, 12040,14688, 12048,14784, 12056,12776, 12064,14664, + 12072,14696, 12080,14792, 12088,13288, 12096,15680, 12104,15712, + 12112,15808, 12120,13800, 12128,15688, 12136,15720, 12144,15816, + 12152,14312, 12160,14672, 12168,13720, 12176,14800, 12184,14824, + 12192,14680, 12200,15768, 12208,14808, 12216,15336, 12224,15696, + 12232,13784, 12240,15824, 12248,15848, 12256,15704, 12264,15832, + 12272,15832, 12280,16360, 12312,12336, 12344,12848, 12352,12544, + 12360,12552, 12368,12560, 12376,13360, 12384,12576, 12392,12584, + 12400,13336, 12408,13872, 12424,12448, 12440,14384, 12456,14496, + 12464,14472, 12472,14896, 12480,12672, 12488,12512, 12496,12688, + 12504,15408, 12512,12680, 12520,14560, 12528,14728, 12536,15920, + 12544,13312, 12552,13320, 12560,13328, 12568,13336, 12576,13344, + 12584,13352, 12592,13360, 12600,12912, 12608,13568, 12616,13576, + 12624,13584, 12632,13424, 12640,13600, 12648,13608, 12656,13400, + 12664,13936, 12672,13440, 12680,12704, 12688,13456, 12696,14448, + 12704,13448, 12712,14752, 12720,15496, 12728,14960, 12736,13696, + 12744,12768, 12752,13712, 12760,15472, 12768,13704, 12776,14816, + 12784,15752, 12792,15984, 12800,14336, 12808,14464, 12816,14344, + 12824,14472, 12832,14352, 12840,14480, 12848,14360, 12856,12976, + 12864,14400, 12872,14528, 12880,14408, 12888,13488, 12896,14416, + 12904,14544, 12912,14424, 12920,14000, 12928,14368, 12936,14496, + 12944,14376, 12952,14512, 12960,14384, 12968,14504, 12976,14488, + 12984,15024, 12992,14432, 13000,14560, 13008,14440, 13016,15536, + 13024,14448, 13032,14568, 13040,14744, 13048,16048, 13056,14592, + 13064,14720, 13072,14600, 13080,14728, 13088,14608, 13096,14736, + 13104,14616, 13112,14744, 13120,14656, 13128,14784, 13136,14664, + 13144,13552, 13152,14672, 13160,14800, 13168,14680, 13176,14064, + 13184,14624, 13192,14752, 13200,14632, 13208,14576, 13216,13464, + 13224,14760, 13232,15512, 13240,15088, 13248,14688, 13256,14816, + 13264,14696, 13272,15600, 13280,13720, 13288,14824, 13296,15768, + 13304,16112, 13336,13360, 13368,14616, 13376,13568, 13384,13576, + 13392,13584, 13400,13616, 13408,13600, 13416,13608, 13424,13592, + 13432,14128, 13448,13472, 13464,14640, 13480,15520, 13488,14536, + 13496,15152, 13504,13696, 13512,13536, 13520,13712, 13528,15664, + 13536,13704, 13544,15584, 13552,14792, 13560,16176, 13592,13616, + 13624,14680, 13656,13680, 13688,14192, 13704,13728, 13720,14704, + 13736,15776, 13744,15560, 13752,15216, 13768,13792, 13784,15728, + 13800,15840, 13808,15816, 13816,16240, 13824,15360, 13832,15488, + 13840,15368, 13848,15496, 13856,15376, 13864,15504, 13872,15384, + 13880,15512, 13888,15424, 13896,15552, 13904,15432, 13912,15560, + 13920,15440, 13928,15568, 13936,15448, 13944,14256, 13952,15392, + 13960,15520, 13968,15400, 13976,14768, 13984,15408, 13992,15528, + 14000,14552, 14008,15280, 14016,15456, 14024,15584, 14032,15464, + 14040,15792, 14048,15472, 14056,15592, 14064,14808, 14072,16304, + 14080,15616, 14088,15744, 14096,15624, 14104,15752, 14112,15632, + 14120,15760, 14128,15640, 14136,15768, 14144,15680, 14152,15808, + 14160,15688, 14168,15816, 14176,15696, 14184,15824, 14192,15704, + 14200,14320, 14208,15648, 14216,15776, 14224,15656, 14232,14832, + 14240,15664, 14248,15784, 14256,15576, 14264,15344, 14272,15712, + 14280,15840, 14288,15720, 14296,15856, 14304,15728, 14312,15848, + 14320,15832, 14328,16368, 14392,14488, 14400,14592, 14408,14600, + 14416,14608, 14424,14616, 14432,14624, 14440,14632, 14448,14640, + 14456,15512, 14504,14512, 14520,14904, 14528,14720, 14536,14728, + 14544,14736, 14552,15416, 14560,14752, 14568,14576, 14584,15928, + 14576,14760, 14592,15360, 14600,15368, 14608,15376, 14616,15384, + 14624,15392, 14632,15400, 14640,15408, 14648,15416, 14656,15616, + 14664,15624, 14672,15632, 14680,15640, 14688,15648, 14696,15656, + 14704,15664, 14712,15576, 14720,15488, 14728,15496, 14736,15504, + 14744,15512, 14752,15520, 14760,14768, 14776,14968, 14768,15528, + 14784,15744, 14792,15752, 14800,15760, 14808,15480, 14816,15776, + 14824,14832, 14840,15992, 14832,15784, 14856,14864, 14864,14880, + 14872,14896, 14880,14976, 14888,14992, 14896,15008, 14904,15024, + 14912,15104, 14920,15120, 14928,15136, 14936,15152, 14944,15232, + 14952,15248, 14960,15264, 14968,15280, 14984,15008, 15000,15024, + 15016,15024, 15040,15112, 15048,15128, 15056,15144, 15064,15544, + 15072,15240, 15080,15256, 15088,15272, 15096,16056, 15104,15872, + 15112,15888, 15120,15904, 15128,15920, 15136,16000, 15144,16016, + 15152,16032, 15160,16048, 15168,16128, 15176,16144, 15184,16160, + 15192,16176, 15200,16256, 15208,16272, 15216,16288, 15224,16304, + 15232,15880, 15240,15896, 15248,15912, 15256,15928, 15264,16008, + 15272,16024, 15280,16040, 15288,16056, 15296,16136, 15304,16152, + 15312,16168, 15320,15608, 15328,16264, 15336,16280, 15344,16296, + 15352,16120, 15416,15512, 15424,15616, 15432,15624, 15440,15632, + 15448,15640, 15456,15648, 15464,15656, 15472,15664, 15480,15768, + 15528,15536, 15544,16048, 15552,15744, 15560,15752, 15568,15760, + 15576,15672, 15584,15776, 15592,15600, 15600,15784, 15608,16184, + 15672,15768, 15736,15832, 15784,15792, 15800,16304, 15848,15856, + 15880,16000, 15864,16248, 15888,16000, 15896,16008, 15904,16000, + 15912,16016, 15920,16008, 15928,16024, 15936,16128, 15944,16160, + 15952,16256, 15960,16288, 15968,16136, 15976,16168, 15984,16264, + 15992,16296, 16008,16032, 16024,16040, 16064,16144, 16040,16048, + 16072,16176, 16080,16272, 16088,16304, 16096,16152, 16104,16184, + 16112,16280, 16136,16256, 16120,16312, 16144,16256, 16152,16264, + 16160,16256, 16168,16272, 16176,16264, 16184,16280, 16200,16208, + 16208,16224, 16216,16240, 16224,16320, 16232,16336, 16240,16352, + 16248,16368, 16264,16288, 16280,16296, 16296,16304, 16344,16368, + 16328,16352, 16360,16368 +}; + +const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH] = +{ + /* radix 8, size 4032 */ + 8,4096, 16,8192, 24,12288, 32,16384, 40,20480, 48,24576, 56,28672, 64,512, + 72,4608, 80,8704, 88,12800, 96,16896, 104,20992, 112,25088, 120,29184, + 128,1024, 136,5120, 144,9216, 152,13312, 160,17408, 168,21504, 176,25600, + 184,29696, 192,1536, 200,5632, 208,9728, 216,13824, 224,17920, 232,22016, + 240,26112, 248,30208, 256,2048, 264,6144, 272,10240, 280,14336, 288,18432, + 296,22528, 304,26624, 312,30720, 320,2560, 328,6656, 336,10752, 344,14848, + 352,18944, 360,23040, 368,27136, 376,31232, 384,3072, 392,7168, 400,11264, + 408,15360, 416,19456, 424,23552, 432,27648, 440,31744, 448,3584, 456,7680, + 464,11776, 472,15872, 480,19968, 488,24064, 496,28160, 504,32256, 520,4160, + 528,8256, 536,12352, 544,16448, 552,20544, 560,24640, 568,28736, 584,4672, + 592,8768, 600,12864, 608,16960, 616,21056, 624,25152, 632,29248, 640,1088, + 648,5184, 656,9280, 664,13376, 672,17472, 680,21568, 688,25664, 696,29760, + 704,1600, 712,5696, 720,9792, 728,13888, 736,17984, 744,22080, 752,26176, + 760,30272, 768,2112, 776,6208, 784,10304, 792,14400, 800,18496, 808,22592, + 816,26688, 824,30784, 832,2624, 840,6720, 848,10816, 856,14912, 864,19008, + 872,23104, 880,27200, 888,31296, 896,3136, 904,7232, 912,11328, 920,15424, + 928,19520, 936,23616, 944,27712, 952,31808, 960,3648, 968,7744, 976,11840, + 984,15936, 992,20032, 1000,24128, 1008,28224, 1016,32320, 1032,4224, + 1040,8320, 1048,12416, 1056,16512, 1064,20608, 1072,24704, 1080,28800, + 1096,4736, 1104,8832, 1112,12928, 1120,17024, 1128,21120, 1136,25216, + 1144,29312, 1160,5248, 1168,9344, 1176,13440, 1184,17536, 1192,21632, + 1200,25728, 1208,29824, 1216,1664, 1224,5760, 1232,9856, 1240,13952, + 1248,18048, 1256,22144, 1264,26240, 1272,30336, 1280,2176, 1288,6272, + 1296,10368, 1304,14464, 1312,18560, 1320,22656, 1328,26752, 1336,30848, + 1344,2688, 1352,6784, 1360,10880, 1368,14976, 1376,19072, 1384,23168, + 1392,27264, 1400,31360, 1408,3200, 1416,7296, 1424,11392, 1432,15488, + 1440,19584, 1448,23680, 1456,27776, 1464,31872, 1472,3712, 1480,7808, + 1488,11904, 1496,16000, 1504,20096, 1512,24192, 1520,28288, 1528,32384, + 1544,4288, 1552,8384, 1560,12480, 1568,16576, 1576,20672, 1584,24768, + 1592,28864, 1608,4800, 1616,8896, 1624,12992, 1632,17088, 1640,21184, + 1648,25280, 1656,29376, 1672,5312, 1680,9408, 1688,13504, 1696,17600, + 1704,21696, 1712,25792, 1720,29888, 1736,5824, 1744,9920, 1752,14016, + 1760,18112, 1768,22208, 1776,26304, 1784,30400, 1792,2240, 1800,6336, + 1808,10432, 1816,14528, 1824,18624, 1832,22720, 1840,26816, 1848,30912, + 1856,2752, 1864,6848, 1872,10944, 1880,15040, 1888,19136, 1896,23232, + 1904,27328, 1912,31424, 1920,3264, 1928,7360, 1936,11456, 1944,15552, + 1952,19648, 1960,23744, 1968,27840, 1976,31936, 1984,3776, 1992,7872, + 2000,11968, 2008,16064, 2016,20160, 2024,24256, 2032,28352, 2040,32448, + 2056,4352, 2064,8448, 2072,12544, 2080,16640, 2088,20736, 2096,24832, + 2104,28928, 2120,4864, 2128,8960, 2136,13056, 2144,17152, 2152,21248, + 2160,25344, 2168,29440, 2184,5376, 2192,9472, 2200,13568, 2208,17664, + 2216,21760, 2224,25856, 2232,29952, 2248,5888, 2256,9984, 2264,14080, + 2272,18176, 2280,22272, 2288,26368, 2296,30464, 2312,6400, 2320,10496, + 2328,14592, 2336,18688, 2344,22784, 2352,26880, 2360,30976, 2368,2816, + 2376,6912, 2384,11008, 2392,15104, 2400,19200, 2408,23296, 2416,27392, + 2424,31488, 2432,3328, 2440,7424, 2448,11520, 2456,15616, 2464,19712, + 2472,23808, 2480,27904, 2488,32000, 2496,3840, 2504,7936, 2512,12032, + 2520,16128, 2528,20224, 2536,24320, 2544,28416, 2552,32512, 2568,4416, + 2576,8512, 2584,12608, 2592,16704, 2600,20800, 2608,24896, 2616,28992, + 2632,4928, 2640,9024, 2648,13120, 2656,17216, 2664,21312, 2672,25408, + 2680,29504, 2696,5440, 2704,9536, 2712,13632, 2720,17728, 2728,21824, + 2736,25920, 2744,30016, 2760,5952, 2768,10048, 2776,14144, 2784,18240, + 2792,22336, 2800,26432, 2808,30528, 2824,6464, 2832,10560, 2840,14656, + 2848,18752, 2856,22848, 2864,26944, 2872,31040, 2888,6976, 2896,11072, + 2904,15168, 2912,19264, 2920,23360, 2928,27456, 2936,31552, 2944,3392, + 2952,7488, 2960,11584, 2968,15680, 2976,19776, 2984,23872, 2992,27968, + 3000,32064, 3008,3904, 3016,8000, 3024,12096, 3032,16192, 3040,20288, + 3048,24384, 3056,28480, 3064,32576, 3080,4480, 3088,8576, 3096,12672, + 3104,16768, 3112,20864, 3120,24960, 3128,29056, 3144,4992, 3152,9088, + 3160,13184, 3168,17280, 3176,21376, 3184,25472, 3192,29568, 3208,5504, + 3216,9600, 3224,13696, 3232,17792, 3240,21888, 3248,25984, 3256,30080, + 3272,6016, 3280,10112, 3288,14208, 3296,18304, 3304,22400, 3312,26496, + 3320,30592, 3336,6528, 3344,10624, 3352,14720, 3360,18816, 3368,22912, + 3376,27008, 3384,31104, 3400,7040, 3408,11136, 3416,15232, 3424,19328, + 3432,23424, 3440,27520, 3448,31616, 3464,7552, 3472,11648, 3480,15744, + 3488,19840, 3496,23936, 3504,28032, 3512,32128, 3520,3968, 3528,8064, + 3536,12160, 3544,16256, 3552,20352, 3560,24448, 3568,28544, 3576,32640, + 3592,4544, 3600,8640, 3608,12736, 3616,16832, 3624,20928, 3632,25024, + 3640,29120, 3656,5056, 3664,9152, 3672,13248, 3680,17344, 3688,21440, + 3696,25536, 3704,29632, 3720,5568, 3728,9664, 3736,13760, 3744,17856, + 3752,21952, 3760,26048, 3768,30144, 3784,6080, 3792,10176, 3800,14272, + 3808,18368, 3816,22464, 3824,26560, 3832,30656, 3848,6592, 3856,10688, + 3864,14784, 3872,18880, 3880,22976, 3888,27072, 3896,31168, 3912,7104, + 3920,11200, 3928,15296, 3936,19392, 3944,23488, 3952,27584, 3960,31680, + 3976,7616, 3984,11712, 3992,15808, 4000,19904, 4008,24000, 4016,28096, + 4024,32192, 4040,8128, 4048,12224, 4056,16320, 4064,20416, 4072,24512, + 4080,28608, 4088,32704, 4112,8200, 4120,12296, 4128,16392, 4136,20488, + 4144,24584, 4152,28680, 4168,4616, 4176,8712, 4184,12808, 4192,16904, + 4200,21000, 4208,25096, 4216,29192, 4232,5128, 4240,9224, 4248,13320, + 4256,17416, 4264,21512, 4272,25608, 4280,29704, 4296,5640, 4304,9736, + 4312,13832, 4320,17928, 4328,22024, 4336,26120, 4344,30216, 4360,6152, + 4368,10248, 4376,14344, 4384,18440, 4392,22536, 4400,26632, 4408,30728, + 4424,6664, 4432,10760, 4440,14856, 4448,18952, 4456,23048, 4464,27144, + 4472,31240, 4488,7176, 4496,11272, 4504,15368, 4512,19464, 4520,23560, + 4528,27656, 4536,31752, 4552,7688, 4560,11784, 4568,15880, 4576,19976, + 4584,24072, 4592,28168, 4600,32264, 4624,8264, 4632,12360, 4640,16456, + 4648,20552, 4656,24648, 4664,28744, 4688,8776, 4696,12872, 4704,16968, + 4712,21064, 4720,25160, 4728,29256, 4744,5192, 4752,9288, 4760,13384, + 4768,17480, 4776,21576, 4784,25672, 4792,29768, 4808,5704, 4816,9800, + 4824,13896, 4832,17992, 4840,22088, 4848,26184, 4856,30280, 4872,6216, + 4880,10312, 4888,14408, 4896,18504, 4904,22600, 4912,26696, 4920,30792, + 4936,6728, 4944,10824, 4952,14920, 4960,19016, 4968,23112, 4976,27208, + 4984,31304, 5000,7240, 5008,11336, 5016,15432, 5024,19528, 5032,23624, + 5040,27720, 5048,31816, 5064,7752, 5072,11848, 5080,15944, 5088,20040, + 5096,24136, 5104,28232, 5112,32328, 5136,8328, 5144,12424, 5152,16520, + 5160,20616, 5168,24712, 5176,28808, 5200,8840, 5208,12936, 5216,17032, + 5224,21128, 5232,25224, 5240,29320, 5264,9352, 5272,13448, 5280,17544, + 5288,21640, 5296,25736, 5304,29832, 5320,5768, 5328,9864, 5336,13960, + 5344,18056, 5352,22152, 5360,26248, 5368,30344, 5384,6280, 5392,10376, + 5400,14472, 5408,18568, 5416,22664, 5424,26760, 5432,30856, 5448,6792, + 5456,10888, 5464,14984, 5472,19080, 5480,23176, 5488,27272, 5496,31368, + 5512,7304, 5520,11400, 5528,15496, 5536,19592, 5544,23688, 5552,27784, + 5560,31880, 5576,7816, 5584,11912, 5592,16008, 5600,20104, 5608,24200, + 5616,28296, 5624,32392, 5648,8392, 5656,12488, 5664,16584, 5672,20680, + 5680,24776, 5688,28872, 5712,8904, 5720,13000, 5728,17096, 5736,21192, + 5744,25288, 5752,29384, 5776,9416, 5784,13512, 5792,17608, 5800,21704, + 5808,25800, 5816,29896, 5840,9928, 5848,14024, 5856,18120, 5864,22216, + 5872,26312, 5880,30408, 5896,6344, 5904,10440, 5912,14536, 5920,18632, + 5928,22728, 5936,26824, 5944,30920, 5960,6856, 5968,10952, 5976,15048, + 5984,19144, 5992,23240, 6000,27336, 6008,31432, 6024,7368, 6032,11464, + 6040,15560, 6048,19656, 6056,23752, 6064,27848, 6072,31944, 6088,7880, + 6096,11976, 6104,16072, 6112,20168, 6120,24264, 6128,28360, 6136,32456, + 6160,8456, 6168,12552, 6176,16648, 6184,20744, 6192,24840, 6200,28936, + 6224,8968, 6232,13064, 6240,17160, 6248,21256, 6256,25352, 6264,29448, + 6288,9480, 6296,13576, 6304,17672, 6312,21768, 6320,25864, 6328,29960, + 6352,9992, 6360,14088, 6368,18184, 6376,22280, 6384,26376, 6392,30472, + 6416,10504, 6424,14600, 6432,18696, 6440,22792, 6448,26888, 6456,30984, + 6472,6920, 6480,11016, 6488,15112, 6496,19208, 6504,23304, 6512,27400, + 6520,31496, 6536,7432, 6544,11528, 6552,15624, 6560,19720, 6568,23816, + 6576,27912, 6584,32008, 6600,7944, 6608,12040, 6616,16136, 6624,20232, + 6632,24328, 6640,28424, 6648,32520, 6672,8520, 6680,12616, 6688,16712, + 6696,20808, 6704,24904, 6712,29000, 6736,9032, 6744,13128, 6752,17224, + 6760,21320, 6768,25416, 6776,29512, 6800,9544, 6808,13640, 6816,17736, + 6824,21832, 6832,25928, 6840,30024, 6864,10056, 6872,14152, 6880,18248, + 6888,22344, 6896,26440, 6904,30536, 6928,10568, 6936,14664, 6944,18760, + 6952,22856, 6960,26952, 6968,31048, 6992,11080, 7000,15176, 7008,19272, + 7016,23368, 7024,27464, 7032,31560, 7048,7496, 7056,11592, 7064,15688, + 7072,19784, 7080,23880, 7088,27976, 7096,32072, 7112,8008, 7120,12104, + 7128,16200, 7136,20296, 7144,24392, 7152,28488, 7160,32584, 7184,8584, + 7192,12680, 7200,16776, 7208,20872, 7216,24968, 7224,29064, 7248,9096, + 7256,13192, 7264,17288, 7272,21384, 7280,25480, 7288,29576, 7312,9608, + 7320,13704, 7328,17800, 7336,21896, 7344,25992, 7352,30088, 7376,10120, + 7384,14216, 7392,18312, 7400,22408, 7408,26504, 7416,30600, 7440,10632, + 7448,14728, 7456,18824, 7464,22920, 7472,27016, 7480,31112, 7504,11144, + 7512,15240, 7520,19336, 7528,23432, 7536,27528, 7544,31624, 7568,11656, + 7576,15752, 7584,19848, 7592,23944, 7600,28040, 7608,32136, 7624,8072, + 7632,12168, 7640,16264, 7648,20360, 7656,24456, 7664,28552, 7672,32648, + 7696,8648, 7704,12744, 7712,16840, 7720,20936, 7728,25032, 7736,29128, + 7760,9160, 7768,13256, 7776,17352, 7784,21448, 7792,25544, 7800,29640, + 7824,9672, 7832,13768, 7840,17864, 7848,21960, 7856,26056, 7864,30152, + 7888,10184, 7896,14280, 7904,18376, 7912,22472, 7920,26568, 7928,30664, + 7952,10696, 7960,14792, 7968,18888, 7976,22984, 7984,27080, 7992,31176, + 8016,11208, 8024,15304, 8032,19400, 8040,23496, 8048,27592, 8056,31688, + 8080,11720, 8088,15816, 8096,19912, 8104,24008, 8112,28104, 8120,32200, + 8144,12232, 8152,16328, 8160,20424, 8168,24520, 8176,28616, 8184,32712, + 8216,12304, 8224,16400, 8232,20496, 8240,24592, 8248,28688, 8272,8720, + 8280,12816, 8288,16912, 8296,21008, 8304,25104, 8312,29200, 8336,9232, + 8344,13328, 8352,17424, 8360,21520, 8368,25616, 8376,29712, 8400,9744, + 8408,13840, 8416,17936, 8424,22032, 8432,26128, 8440,30224, 8464,10256, + 8472,14352, 8480,18448, 8488,22544, 8496,26640, 8504,30736, 8528,10768, + 8536,14864, 8544,18960, 8552,23056, 8560,27152, 8568,31248, 8592,11280, + 8600,15376, 8608,19472, 8616,23568, 8624,27664, 8632,31760, 8656,11792, + 8664,15888, 8672,19984, 8680,24080, 8688,28176, 8696,32272, 8728,12368, + 8736,16464, 8744,20560, 8752,24656, 8760,28752, 8792,12880, 8800,16976, + 8808,21072, 8816,25168, 8824,29264, 8848,9296, 8856,13392, 8864,17488, + 8872,21584, 8880,25680, 8888,29776, 8912,9808, 8920,13904, 8928,18000, + 8936,22096, 8944,26192, 8952,30288, 8976,10320, 8984,14416, 8992,18512, + 9000,22608, 9008,26704, 9016,30800, 9040,10832, 9048,14928, 9056,19024, + 9064,23120, 9072,27216, 9080,31312, 9104,11344, 9112,15440, 9120,19536, + 9128,23632, 9136,27728, 9144,31824, 9168,11856, 9176,15952, 9184,20048, + 9192,24144, 9200,28240, 9208,32336, 9240,12432, 9248,16528, 9256,20624, + 9264,24720, 9272,28816, 9304,12944, 9312,17040, 9320,21136, 9328,25232, + 9336,29328, 9368,13456, 9376,17552, 9384,21648, 9392,25744, 9400,29840, + 9424,9872, 9432,13968, 9440,18064, 9448,22160, 9456,26256, 9464,30352, + 9488,10384, 9496,14480, 9504,18576, 9512,22672, 9520,26768, 9528,30864, + 9552,10896, 9560,14992, 9568,19088, 9576,23184, 9584,27280, 9592,31376, + 9616,11408, 9624,15504, 9632,19600, 9640,23696, 9648,27792, 9656,31888, + 9680,11920, 9688,16016, 9696,20112, 9704,24208, 9712,28304, 9720,32400, + 9752,12496, 9760,16592, 9768,20688, 9776,24784, 9784,28880, 9816,13008, + 9824,17104, 9832,21200, 9840,25296, 9848,29392, 9880,13520, 9888,17616, + 9896,21712, 9904,25808, 9912,29904, 9944,14032, 9952,18128, 9960,22224, + 9968,26320, 9976,30416, 10000,10448, 10008,14544, 10016,18640, 10024,22736, + 10032,26832, 10040,30928, 10064,10960, 10072,15056, 10080,19152, + 10088,23248, 10096,27344, 10104,31440, 10128,11472, 10136,15568, + 10144,19664, 10152,23760, 10160,27856, 10168,31952, 10192,11984, + 10200,16080, 10208,20176, 10216,24272, 10224,28368, 10232,32464, + 10264,12560, 10272,16656, 10280,20752, 10288,24848, 10296,28944, + 10328,13072, 10336,17168, 10344,21264, 10352,25360, 10360,29456, + 10392,13584, 10400,17680, 10408,21776, 10416,25872, 10424,29968, + 10456,14096, 10464,18192, 10472,22288, 10480,26384, 10488,30480, + 10520,14608, 10528,18704, 10536,22800, 10544,26896, 10552,30992, + 10576,11024, 10584,15120, 10592,19216, 10600,23312, 10608,27408, + 10616,31504, 10640,11536, 10648,15632, 10656,19728, 10664,23824, + 10672,27920, 10680,32016, 10704,12048, 10712,16144, 10720,20240, + 10728,24336, 10736,28432, 10744,32528, 10776,12624, 10784,16720, + 10792,20816, 10800,24912, 10808,29008, 10840,13136, 10848,17232, + 10856,21328, 10864,25424, 10872,29520, 10904,13648, 10912,17744, + 10920,21840, 10928,25936, 10936,30032, 10968,14160, 10976,18256, + 10984,22352, 10992,26448, 11000,30544, 11032,14672, 11040,18768, + 11048,22864, 11056,26960, 11064,31056, 11096,15184, 11104,19280, + 11112,23376, 11120,27472, 11128,31568, 11152,11600, 11160,15696, + 11168,19792, 11176,23888, 11184,27984, 11192,32080, 11216,12112, + 11224,16208, 11232,20304, 11240,24400, 11248,28496, 11256,32592, + 11288,12688, 11296,16784, 11304,20880, 11312,24976, 11320,29072, + 11352,13200, 11360,17296, 11368,21392, 11376,25488, 11384,29584, + 11416,13712, 11424,17808, 11432,21904, 11440,26000, 11448,30096, + 11480,14224, 11488,18320, 11496,22416, 11504,26512, 11512,30608, + 11544,14736, 11552,18832, 11560,22928, 11568,27024, 11576,31120, + 11608,15248, 11616,19344, 11624,23440, 11632,27536, 11640,31632, + 11672,15760, 11680,19856, 11688,23952, 11696,28048, 11704,32144, + 11728,12176, 11736,16272, 11744,20368, 11752,24464, 11760,28560, + 11768,32656, 11800,12752, 11808,16848, 11816,20944, 11824,25040, + 11832,29136, 11864,13264, 11872,17360, 11880,21456, 11888,25552, + 11896,29648, 11928,13776, 11936,17872, 11944,21968, 11952,26064, + 11960,30160, 11992,14288, 12000,18384, 12008,22480, 12016,26576, + 12024,30672, 12056,14800, 12064,18896, 12072,22992, 12080,27088, + 12088,31184, 12120,15312, 12128,19408, 12136,23504, 12144,27600, + 12152,31696, 12184,15824, 12192,19920, 12200,24016, 12208,28112, + 12216,32208, 12248,16336, 12256,20432, 12264,24528, 12272,28624, + 12280,32720, 12320,16408, 12328,20504, 12336,24600, 12344,28696, + 12376,12824, 12384,16920, 12392,21016, 12400,25112, 12408,29208, + 12440,13336, 12448,17432, 12456,21528, 12464,25624, 12472,29720, + 12504,13848, 12512,17944, 12520,22040, 12528,26136, 12536,30232, + 12568,14360, 12576,18456, 12584,22552, 12592,26648, 12600,30744, + 12632,14872, 12640,18968, 12648,23064, 12656,27160, 12664,31256, + 12696,15384, 12704,19480, 12712,23576, 12720,27672, 12728,31768, + 12760,15896, 12768,19992, 12776,24088, 12784,28184, 12792,32280, + 12832,16472, 12840,20568, 12848,24664, 12856,28760, 12896,16984, + 12904,21080, 12912,25176, 12920,29272, 12952,13400, 12960,17496, + 12968,21592, 12976,25688, 12984,29784, 13016,13912, 13024,18008, + 13032,22104, 13040,26200, 13048,30296, 13080,14424, 13088,18520, + 13096,22616, 13104,26712, 13112,30808, 13144,14936, 13152,19032, + 13160,23128, 13168,27224, 13176,31320, 13208,15448, 13216,19544, + 13224,23640, 13232,27736, 13240,31832, 13272,15960, 13280,20056, + 13288,24152, 13296,28248, 13304,32344, 13344,16536, 13352,20632, + 13360,24728, 13368,28824, 13408,17048, 13416,21144, 13424,25240, + 13432,29336, 13472,17560, 13480,21656, 13488,25752, 13496,29848, + 13528,13976, 13536,18072, 13544,22168, 13552,26264, 13560,30360, + 13592,14488, 13600,18584, 13608,22680, 13616,26776, 13624,30872, + 13656,15000, 13664,19096, 13672,23192, 13680,27288, 13688,31384, + 13720,15512, 13728,19608, 13736,23704, 13744,27800, 13752,31896, + 13784,16024, 13792,20120, 13800,24216, 13808,28312, 13816,32408, + 13856,16600, 13864,20696, 13872,24792, 13880,28888, 13920,17112, + 13928,21208, 13936,25304, 13944,29400, 13984,17624, 13992,21720, + 14000,25816, 14008,29912, 14048,18136, 14056,22232, 14064,26328, + 14072,30424, 14104,14552, 14112,18648, 14120,22744, 14128,26840, + 14136,30936, 14168,15064, 14176,19160, 14184,23256, 14192,27352, + 14200,31448, 14232,15576, 14240,19672, 14248,23768, 14256,27864, + 14264,31960, 14296,16088, 14304,20184, 14312,24280, 14320,28376, + 14328,32472, 14368,16664, 14376,20760, 14384,24856, 14392,28952, + 14432,17176, 14440,21272, 14448,25368, 14456,29464, 14496,17688, + 14504,21784, 14512,25880, 14520,29976, 14560,18200, 14568,22296, + 14576,26392, 14584,30488, 14624,18712, 14632,22808, 14640,26904, + 14648,31000, 14680,15128, 14688,19224, 14696,23320, 14704,27416, + 14712,31512, 14744,15640, 14752,19736, 14760,23832, 14768,27928, + 14776,32024, 14808,16152, 14816,20248, 14824,24344, 14832,28440, + 14840,32536, 14880,16728, 14888,20824, 14896,24920, 14904,29016, + 14944,17240, 14952,21336, 14960,25432, 14968,29528, 15008,17752, + 15016,21848, 15024,25944, 15032,30040, 15072,18264, 15080,22360, + 15088,26456, 15096,30552, 15136,18776, 15144,22872, 15152,26968, + 15160,31064, 15200,19288, 15208,23384, 15216,27480, 15224,31576, + 15256,15704, 15264,19800, 15272,23896, 15280,27992, 15288,32088, + 15320,16216, 15328,20312, 15336,24408, 15344,28504, 15352,32600, + 15392,16792, 15400,20888, 15408,24984, 15416,29080, 15456,17304, + 15464,21400, 15472,25496, 15480,29592, 15520,17816, 15528,21912, + 15536,26008, 15544,30104, 15584,18328, 15592,22424, 15600,26520, + 15608,30616, 15648,18840, 15656,22936, 15664,27032, 15672,31128, + 15712,19352, 15720,23448, 15728,27544, 15736,31640, 15776,19864, + 15784,23960, 15792,28056, 15800,32152, 15832,16280, 15840,20376, + 15848,24472, 15856,28568, 15864,32664, 15904,16856, 15912,20952, + 15920,25048, 15928,29144, 15968,17368, 15976,21464, 15984,25560, + 15992,29656, 16032,17880, 16040,21976, 16048,26072, 16056,30168, + 16096,18392, 16104,22488, 16112,26584, 16120,30680, 16160,18904, + 16168,23000, 16176,27096, 16184,31192, 16224,19416, 16232,23512, + 16240,27608, 16248,31704, 16288,19928, 16296,24024, 16304,28120, + 16312,32216, 16352,20440, 16360,24536, 16368,28632, 16376,32728, + 16424,20512, 16432,24608, 16440,28704, 16480,16928, 16488,21024, + 16496,25120, 16504,29216, 16544,17440, 16552,21536, 16560,25632, + 16568,29728, 16608,17952, 16616,22048, 16624,26144, 16632,30240, + 16672,18464, 16680,22560, 16688,26656, 16696,30752, 16736,18976, + 16744,23072, 16752,27168, 16760,31264, 16800,19488, 16808,23584, + 16816,27680, 16824,31776, 16864,20000, 16872,24096, 16880,28192, + 16888,32288, 16936,20576, 16944,24672, 16952,28768, 17000,21088, + 17008,25184, 17016,29280, 17056,17504, 17064,21600, 17072,25696, + 17080,29792, 17120,18016, 17128,22112, 17136,26208, 17144,30304, + 17184,18528, 17192,22624, 17200,26720, 17208,30816, 17248,19040, + 17256,23136, 17264,27232, 17272,31328, 17312,19552, 17320,23648, + 17328,27744, 17336,31840, 17376,20064, 17384,24160, 17392,28256, + 17400,32352, 17448,20640, 17456,24736, 17464,28832, 17512,21152, + 17520,25248, 17528,29344, 17576,21664, 17584,25760, 17592,29856, + 17632,18080, 17640,22176, 17648,26272, 17656,30368, 17696,18592, + 17704,22688, 17712,26784, 17720,30880, 17760,19104, 17768,23200, + 17776,27296, 17784,31392, 17824,19616, 17832,23712, 17840,27808, + 17848,31904, 17888,20128, 17896,24224, 17904,28320, 17912,32416, + 17960,20704, 17968,24800, 17976,28896, 18024,21216, 18032,25312, + 18040,29408, 18088,21728, 18096,25824, 18104,29920, 18152,22240, + 18160,26336, 18168,30432, 18208,18656, 18216,22752, 18224,26848, + 18232,30944, 18272,19168, 18280,23264, 18288,27360, 18296,31456, + 18336,19680, 18344,23776, 18352,27872, 18360,31968, 18400,20192, + 18408,24288, 18416,28384, 18424,32480, 18472,20768, 18480,24864, + 18488,28960, 18536,21280, 18544,25376, 18552,29472, 18600,21792, + 18608,25888, 18616,29984, 18664,22304, 18672,26400, 18680,30496, + 18728,22816, 18736,26912, 18744,31008, 18784,19232, 18792,23328, + 18800,27424, 18808,31520, 18848,19744, 18856,23840, 18864,27936, + 18872,32032, 18912,20256, 18920,24352, 18928,28448, 18936,32544, + 18984,20832, 18992,24928, 19000,29024, 19048,21344, 19056,25440, + 19064,29536, 19112,21856, 19120,25952, 19128,30048, 19176,22368, + 19184,26464, 19192,30560, 19240,22880, 19248,26976, 19256,31072, + 19304,23392, 19312,27488, 19320,31584, 19360,19808, 19368,23904, + 19376,28000, 19384,32096, 19424,20320, 19432,24416, 19440,28512, + 19448,32608, 19496,20896, 19504,24992, 19512,29088, 19560,21408, + 19568,25504, 19576,29600, 19624,21920, 19632,26016, 19640,30112, + 19688,22432, 19696,26528, 19704,30624, 19752,22944, 19760,27040, + 19768,31136, 19816,23456, 19824,27552, 19832,31648, 19880,23968, + 19888,28064, 19896,32160, 19936,20384, 19944,24480, 19952,28576, + 19960,32672, 20008,20960, 20016,25056, 20024,29152, 20072,21472, + 20080,25568, 20088,29664, 20136,21984, 20144,26080, 20152,30176, + 20200,22496, 20208,26592, 20216,30688, 20264,23008, 20272,27104, + 20280,31200, 20328,23520, 20336,27616, 20344,31712, 20392,24032, + 20400,28128, 20408,32224, 20456,24544, 20464,28640, 20472,32736, + 20528,24616, 20536,28712, 20584,21032, 20592,25128, 20600,29224, + 20648,21544, 20656,25640, 20664,29736, 20712,22056, 20720,26152, + 20728,30248, 20776,22568, 20784,26664, 20792,30760, 20840,23080, + 20848,27176, 20856,31272, 20904,23592, 20912,27688, 20920,31784, + 20968,24104, 20976,28200, 20984,32296, 21040,24680, 21048,28776, + 21104,25192, 21112,29288, 21160,21608, 21168,25704, 21176,29800, + 21224,22120, 21232,26216, 21240,30312, 21288,22632, 21296,26728, + 21304,30824, 21352,23144, 21360,27240, 21368,31336, 21416,23656, + 21424,27752, 21432,31848, 21480,24168, 21488,28264, 21496,32360, + 21552,24744, 21560,28840, 21616,25256, 21624,29352, 21680,25768, + 21688,29864, 21736,22184, 21744,26280, 21752,30376, 21800,22696, + 21808,26792, 21816,30888, 21864,23208, 21872,27304, 21880,31400, + 21928,23720, 21936,27816, 21944,31912, 21992,24232, 22000,28328, + 22008,32424, 22064,24808, 22072,28904, 22128,25320, 22136,29416, + 22192,25832, 22200,29928, 22256,26344, 22264,30440, 22312,22760, + 22320,26856, 22328,30952, 22376,23272, 22384,27368, 22392,31464, + 22440,23784, 22448,27880, 22456,31976, 22504,24296, 22512,28392, + 22520,32488, 22576,24872, 22584,28968, 22640,25384, 22648,29480, + 22704,25896, 22712,29992, 22768,26408, 22776,30504, 22832,26920, + 22840,31016, 22888,23336, 22896,27432, 22904,31528, 22952,23848, + 22960,27944, 22968,32040, 23016,24360, 23024,28456, 23032,32552, + 23088,24936, 23096,29032, 23152,25448, 23160,29544, 23216,25960, + 23224,30056, 23280,26472, 23288,30568, 23344,26984, 23352,31080, + 23408,27496, 23416,31592, 23464,23912, 23472,28008, 23480,32104, + 23528,24424, 23536,28520, 23544,32616, 23600,25000, 23608,29096, + 23664,25512, 23672,29608, 23728,26024, 23736,30120, 23792,26536, + 23800,30632, 23856,27048, 23864,31144, 23920,27560, 23928,31656, + 23984,28072, 23992,32168, 24040,24488, 24048,28584, 24056,32680, + 24112,25064, 24120,29160, 24176,25576, 24184,29672, 24240,26088, + 24248,30184, 24304,26600, 24312,30696, 24368,27112, 24376,31208, + 24432,27624, 24440,31720, 24496,28136, 24504,32232, 24560,28648, + 24568,32744, 24632,28720, 24688,25136, 24696,29232, 24752,25648, + 24760,29744, 24816,26160, 24824,30256, 24880,26672, 24888,30768, + 24944,27184, 24952,31280, 25008,27696, 25016,31792, 25072,28208, + 25080,32304, 25144,28784, 25208,29296, 25264,25712, 25272,29808, + 25328,26224, 25336,30320, 25392,26736, 25400,30832, 25456,27248, + 25464,31344, 25520,27760, 25528,31856, 25584,28272, 25592,32368, + 25656,28848, 25720,29360, 25784,29872, 25840,26288, 25848,30384, + 25904,26800, 25912,30896, 25968,27312, 25976,31408, 26032,27824, + 26040,31920, 26096,28336, 26104,32432, 26168,28912, 26232,29424, + 26296,29936, 26360,30448, 26416,26864, 26424,30960, 26480,27376, + 26488,31472, 26544,27888, 26552,31984, 26608,28400, 26616,32496, + 26680,28976, 26744,29488, 26808,30000, 26872,30512, 26936,31024, + 26992,27440, 27000,31536, 27056,27952, 27064,32048, 27120,28464, + 27128,32560, 27192,29040, 27256,29552, 27320,30064, 27384,30576, + 27448,31088, 27512,31600, 27568,28016, 27576,32112, 27632,28528, + 27640,32624, 27704,29104, 27768,29616, 27832,30128, 27896,30640, + 27960,31152, 28024,31664, 28088,32176, 28144,28592, 28152,32688, + 28216,29168, 28280,29680, 28344,30192, 28408,30704, 28472,31216, + 28536,31728, 28600,32240, 28664,32752, 28792,29240, 28856,29752, + 28920,30264, 28984,30776, 29048,31288, 29112,31800, 29176,32312, + 29368,29816, 29432,30328, 29496,30840, 29560,31352, 29624,31864, + 29688,32376, 29944,30392, 30008,30904, 30072,31416, 30136,31928, + 30200,32440, 30520,30968, 30584,31480, 30648,31992, 30712,32504, + 31096,31544, 31160,32056, 31224,32568, 31672,32120, 31736,32632, + 32248,32696 +}; + + +const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH] = +{ + /* radix 4, size 12 */ + 8,64, 16,32, 24,96, 40,80, 56,112, 88,104 +}; + +const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH] = +{ + /* 4x2, size 24 */ + 8,128, 16,64, 24,192, 40,160, 48,96, 56,224, 72,144, + 88,208, 104,176, 120,240, 152,200, 184,232 +}; + +const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH] = +{ + /* radix 4, size 56 */ + 8,256, 16,128, 24,384, 32,64, 40,320, 48,192, 56,448, 72,288, 80,160, 88,416, 104,352, + 112,224, 120,480, 136,272, 152,400, 168,336, 176,208, 184,464, 200,304, 216,432, + 232,368, 248,496, 280,392, 296,328, 312,456, 344,424, 376,488, 440,472 +}; + +const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH] = +{ + /* 4x2, size 112 */ + 8,512, 16,256, 24,768, 32,128, 40,640, 48,384, 56,896, 72,576, 80,320, 88,832, 96,192, + 104,704, 112,448, 120,960, 136,544, 144,288, 152,800, 168,672, 176,416, 184,928, 200,608, + 208,352, 216,864, 232,736, 240,480, 248,992, 264,528, 280,784, 296,656, 304,400, 312,912, + 328,592, 344,848, 360,720, 368,464, 376,976, 392,560, 408,816, 424,688, 440,944, 456,624, + 472,880, 488,752, 504,1008, 536,776, 552,648, 568,904, 600,840, 616,712, 632,968, + 664,808, 696,936, 728,872, 760,1000, 824,920, 888,984 +}; + +const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH] = +{ + /* radix 4, size 240 */ + 8,1024, 16,512, 24,1536, 32,256, 40,1280, 48,768, 56,1792, 64,128, 72,1152, 80,640, + 88,1664, 96,384, 104,1408, 112,896, 120,1920, 136,1088, 144,576, 152,1600, 160,320, + 168,1344, 176,832, 184,1856, 200,1216, 208,704, 216,1728, 224,448, 232,1472, 240,960, + 248,1984, 264,1056, 272,544, 280,1568, 296,1312, 304,800, 312,1824, 328,1184, 336,672, + 344,1696, 352,416, 360,1440, 368,928, 376,1952, 392,1120, 400,608, 408,1632, 424,1376, + 432,864, 440,1888, 456,1248, 464,736, 472,1760, 488,1504, 496,992, 504,2016, 520,1040, + 536,1552, 552,1296, 560,784, 568,1808, 584,1168, 592,656, 600,1680, 616,1424, 624,912, + 632,1936, 648,1104, 664,1616, 680,1360, 688,848, 696,1872, 712,1232, 728,1744, 744,1488, + 752,976, 760,2000, 776,1072, 792,1584, 808,1328, 824,1840, 840,1200, 856,1712, 872,1456, + 880,944, 888,1968, 904,1136, 920,1648, 936,1392, 952,1904, 968,1264, 984,1776, 1000,1520, + 1016,2032, 1048,1544, 1064,1288, 1080,1800, 1096,1160, 1112,1672, 1128,1416, 1144,1928, + 1176,1608, 1192,1352, 1208,1864, 1240,1736, 1256,1480, 1272,1992, 1304,1576, 1336,1832, + 1368,1704, 1384,1448, 1400,1960, 1432,1640, 1464,1896, 1496,1768, 1528,2024, 1592,1816, + 1624,1688, 1656,1944, 1720,1880, 1784,2008, 1912,1976 +}; + +const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH] = +{ + /* 4x2, size 480 */ + 8,2048, 16,1024, 24,3072, 32,512, 40,2560, 48,1536, 56,3584, 64,256, 72,2304, 80,1280, + 88,3328, 96,768, 104,2816, 112,1792, 120,3840, 136,2176, 144,1152, 152,3200, 160,640, + 168,2688, 176,1664, 184,3712, 192,384, 200,2432, 208,1408, 216,3456, 224,896, 232,2944, + 240,1920, 248,3968, 264,2112, 272,1088, 280,3136, 288,576, 296,2624, 304,1600, 312,3648, + 328,2368, 336,1344, 344,3392, 352,832, 360,2880, 368,1856, 376,3904, 392,2240, 400,1216, + 408,3264, 416,704, 424,2752, 432,1728, 440,3776, 456,2496, 464,1472, 472,3520, 480,960, + 488,3008, 496,1984, 504,4032, 520,2080, 528,1056, 536,3104, 552,2592, 560,1568, 568,3616, + 584,2336, 592,1312, 600,3360, 608,800, 616,2848, 624,1824, 632,3872, 648,2208, 656,1184, + 664,3232, 680,2720, 688,1696, 696,3744, 712,2464, 720,1440, 728,3488, 736,928, 744,2976, + 752,1952, 760,4000, 776,2144, 784,1120, 792,3168, 808,2656, 816,1632, 824,3680, 840,2400, + 848,1376, 856,3424, 872,2912, 880,1888, 888,3936, 904,2272, 912,1248, 920,3296, 936,2784, + 944,1760, 952,3808, 968,2528, 976,1504, 984,3552, 1000,3040, 1008,2016, 1016,4064, + 1032,2064, 1048,3088, 1064,2576, 1072,1552, 1080,3600, 1096,2320, 1104,1296, 1112,3344, + 1128,2832, 1136,1808, 1144,3856, 1160,2192, 1176,3216, 1192,2704, 1200,1680, 1208,3728, + 1224,2448, 1232,1424, 1240,3472, 1256,2960, 1264,1936, 1272,3984, 1288,2128, 1304,3152, + 1320,2640, 1328,1616, 1336,3664, 1352,2384, 1368,3408, 1384,2896, 1392,1872, 1400,3920, + 1416,2256, 1432,3280, 1448,2768, 1456,1744, 1464,3792, 1480,2512, 1496,3536, 1512,3024, + 1520,2000, 1528,4048, 1544,2096, 1560,3120, 1576,2608, 1592,3632, 1608,2352, 1624,3376, + 1640,2864, 1648,1840, 1656,3888, 1672,2224, 1688,3248, 1704,2736, 1720,3760, 1736,2480, + 1752,3504, 1768,2992, 1776,1968, 1784,4016, 1800,2160, 1816,3184, 1832,2672, 1848,3696, + 1864,2416, 1880,3440, 1896,2928, 1912,3952, 1928,2288, 1944,3312, 1960,2800, 1976,3824, + 1992,2544, 2008,3568, 2024,3056, 2040,4080, 2072,3080, 2088,2568, 2104,3592, 2120,2312, + 2136,3336, 2152,2824, 2168,3848, 2200,3208, 2216,2696, 2232,3720, 2248,2440, 2264,3464, + 2280,2952, 2296,3976, 2328,3144, 2344,2632, 2360,3656, 2392,3400, 2408,2888, 2424,3912, + 2456,3272, 2472,2760, 2488,3784, 2520,3528, 2536,3016, 2552,4040, 2584,3112, 2616,3624, + 2648,3368, 2664,2856, 2680,3880, 2712,3240, 2744,3752, 2776,3496, 2792,2984, 2808,4008, + 2840,3176, 2872,3688, 2904,3432, 2936,3944, 2968,3304, 3000,3816, 3032,3560, 3064,4072, + 3128,3608, 3160,3352, 3192,3864, 3256,3736, 3288,3480, 3320,3992, 3384,3672, 3448,3928, + 3512,3800, 3576,4056, 3704,3896, 3832,4024 +}; + +const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH] = +{ + /* radix 4, size 992 */ + 8,4096, 16,2048, 24,6144, 32,1024, 40,5120, 48,3072, 56,7168, 64,512, 72,4608, + 80,2560, 88,6656, 96,1536, 104,5632, 112,3584, 120,7680, 128,256, 136,4352, + 144,2304, 152,6400, 160,1280, 168,5376, 176,3328, 184,7424, 192,768, 200,4864, + 208,2816, 216,6912, 224,1792, 232,5888, 240,3840, 248,7936, 264,4224, 272,2176, + 280,6272, 288,1152, 296,5248, 304,3200, 312,7296, 320,640, 328,4736, 336,2688, + 344,6784, 352,1664, 360,5760, 368,3712, 376,7808, 392,4480, 400,2432, 408,6528, + 416,1408, 424,5504, 432,3456, 440,7552, 448,896, 456,4992, 464,2944, 472,7040, + 480,1920, 488,6016, 496,3968, 504,8064, 520,4160, 528,2112, 536,6208, 544,1088, + 552,5184, 560,3136, 568,7232, 584,4672, 592,2624, 600,6720, 608,1600, 616,5696, + 624,3648, 632,7744, 648,4416, 656,2368, 664,6464, 672,1344, 680,5440, 688,3392, + 696,7488, 704,832, 712,4928, 720,2880, 728,6976, 736,1856, 744,5952, 752,3904, + 760,8000, 776,4288, 784,2240, 792,6336, 800,1216, 808,5312, 816,3264, 824,7360, + 840,4800, 848,2752, 856,6848, 864,1728, 872,5824, 880,3776, 888,7872, 904,4544, + 912,2496, 920,6592, 928,1472, 936,5568, 944,3520, 952,7616, 968,5056, 976,3008, + 984,7104, 992,1984, 1000,6080, 1008,4032, 1016,8128, 1032,4128, 1040,2080, + 1048,6176, 1064,5152, 1072,3104, 1080,7200, 1096,4640, 1104,2592, 1112,6688, + 1120,1568, 1128,5664, 1136,3616, 1144,7712, 1160,4384, 1168,2336, 1176,6432, + 1184,1312, 1192,5408, 1200,3360, 1208,7456, 1224,4896, 1232,2848, 1240,6944, + 1248,1824, 1256,5920, 1264,3872, 1272,7968, 1288,4256, 1296,2208, 1304,6304, + 1320,5280, 1328,3232, 1336,7328, 1352,4768, 1360,2720, 1368,6816, 1376,1696, + 1384,5792, 1392,3744, 1400,7840, 1416,4512, 1424,2464, 1432,6560, 1448,5536, + 1456,3488, 1464,7584, 1480,5024, 1488,2976, 1496,7072, 1504,1952, 1512,6048, + 1520,4000, 1528,8096, 1544,4192, 1552,2144, 1560,6240, 1576,5216, 1584,3168, + 1592,7264, 1608,4704, 1616,2656, 1624,6752, 1640,5728, 1648,3680, 1656,7776, + 1672,4448, 1680,2400, 1688,6496, 1704,5472, 1712,3424, 1720,7520, 1736,4960, + 1744,2912, 1752,7008, 1760,1888, 1768,5984, 1776,3936, 1784,8032, 1800,4320, + 1808,2272, 1816,6368, 1832,5344, 1840,3296, 1848,7392, 1864,4832, 1872,2784, + 1880,6880, 1896,5856, 1904,3808, 1912,7904, 1928,4576, 1936,2528, 1944,6624, + 1960,5600, 1968,3552, 1976,7648, 1992,5088, 2000,3040, 2008,7136, 2024,6112, + 2032,4064, 2040,8160, 2056,4112, 2072,6160, 2088,5136, 2096,3088, 2104,7184, + 2120,4624, 2128,2576, 2136,6672, 2152,5648, 2160,3600, 2168,7696, 2184,4368, + 2192,2320, 2200,6416, 2216,5392, 2224,3344, 2232,7440, 2248,4880, 2256,2832, + 2264,6928, 2280,5904, 2288,3856, 2296,7952, 2312,4240, 2328,6288, 2344,5264, + 2352,3216, 2360,7312, 2376,4752, 2384,2704, 2392,6800, 2408,5776, 2416,3728, + 2424,7824, 2440,4496, 2456,6544, 2472,5520, 2480,3472, 2488,7568, 2504,5008, + 2512,2960, 2520,7056, 2536,6032, 2544,3984, 2552,8080, 2568,4176, 2584,6224, + 2600,5200, 2608,3152, 2616,7248, 2632,4688, 2648,6736, 2664,5712, 2672,3664, + 2680,7760, 2696,4432, 2712,6480, 2728,5456, 2736,3408, 2744,7504, 2760,4944, + 2768,2896, 2776,6992, 2792,5968, 2800,3920, 2808,8016, 2824,4304, 2840,6352, + 2856,5328, 2864,3280, 2872,7376, 2888,4816, 2904,6864, 2920,5840, 2928,3792, + 2936,7888, 2952,4560, 2968,6608, 2984,5584, 2992,3536, 3000,7632, 3016,5072, + 3032,7120, 3048,6096, 3056,4048, 3064,8144, 3080,4144, 3096,6192, 3112,5168, + 3128,7216, 3144,4656, 3160,6704, 3176,5680, 3184,3632, 3192,7728, 3208,4400, + 3224,6448, 3240,5424, 3248,3376, 3256,7472, 3272,4912, 3288,6960, 3304,5936, + 3312,3888, 3320,7984, 3336,4272, 3352,6320, 3368,5296, 3384,7344, 3400,4784, + 3416,6832, 3432,5808, 3440,3760, 3448,7856, 3464,4528, 3480,6576, 3496,5552, + 3512,7600, 3528,5040, 3544,7088, 3560,6064, 3568,4016, 3576,8112, 3592,4208, + 3608,6256, 3624,5232, 3640,7280, 3656,4720, 3672,6768, 3688,5744, 3704,7792, + 3720,4464, 3736,6512, 3752,5488, 3768,7536, 3784,4976, 3800,7024, 3816,6000, + 3824,3952, 3832,8048, 3848,4336, 3864,6384, 3880,5360, 3896,7408, 3912,4848, + 3928,6896, 3944,5872, 3960,7920, 3976,4592, 3992,6640, 4008,5616, 4024,7664, + 4040,5104, 4056,7152, 4072,6128, 4088,8176, 4120,6152, 4136,5128, 4152,7176, + 4168,4616, 4184,6664, 4200,5640, 4216,7688, 4232,4360, 4248,6408, 4264,5384, + 4280,7432, 4296,4872, 4312,6920, 4328,5896, 4344,7944, 4376,6280, 4392,5256, + 4408,7304, 4424,4744, 4440,6792, 4456,5768, 4472,7816, 4504,6536, 4520,5512, + 4536,7560, 4552,5000, 4568,7048, 4584,6024, 4600,8072, 4632,6216, 4648,5192, + 4664,7240, 4696,6728, 4712,5704, 4728,7752, 4760,6472, 4776,5448, 4792,7496, + 4808,4936, 4824,6984, 4840,5960, 4856,8008, 4888,6344, 4904,5320, 4920,7368, + 4952,6856, 4968,5832, 4984,7880, 5016,6600, 5032,5576, 5048,7624, 5080,7112, + 5096,6088, 5112,8136, 5144,6184, 5176,7208, 5208,6696, 5224,5672, 5240,7720, + 5272,6440, 5288,5416, 5304,7464, 5336,6952, 5352,5928, 5368,7976, 5400,6312, + 5432,7336, 5464,6824, 5480,5800, 5496,7848, 5528,6568, 5560,7592, 5592,7080, + 5608,6056, 5624,8104, 5656,6248, 5688,7272, 5720,6760, 5752,7784, 5784,6504, + 5816,7528, 5848,7016, 5864,5992, 5880,8040, 5912,6376, 5944,7400, 5976,6888, + 6008,7912, 6040,6632, 6072,7656, 6104,7144, 6136,8168, 6200,7192, 6232,6680, + 6264,7704, 6296,6424, 6328,7448, 6360,6936, 6392,7960, 6456,7320, 6488,6808, + 6520,7832, 6584,7576, 6616,7064, 6648,8088, 6712,7256, 6776,7768, 6840,7512, + 6872,7000, 6904,8024, 6968,7384, 7032,7896, 7096,7640, 7160,8152, 7288,7736, + 7352,7480, 7416,7992, 7544,7864, 7672,8120, 7928,8056 +}; + +const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH] = +{ + /* 4x2, size 1984 */ + 8,8192, 16,4096, 24,12288, 32,2048, 40,10240, 48,6144, 56,14336, 64,1024, + 72,9216, 80,5120, 88,13312, 96,3072, 104,11264, 112,7168, 120,15360, 128,512, + 136,8704, 144,4608, 152,12800, 160,2560, 168,10752, 176,6656, 184,14848, + 192,1536, 200,9728, 208,5632, 216,13824, 224,3584, 232,11776, 240,7680, + 248,15872, 264,8448, 272,4352, 280,12544, 288,2304, 296,10496, 304,6400, + 312,14592, 320,1280, 328,9472, 336,5376, 344,13568, 352,3328, 360,11520, + 368,7424, 376,15616, 384,768, 392,8960, 400,4864, 408,13056, 416,2816, + 424,11008, 432,6912, 440,15104, 448,1792, 456,9984, 464,5888, 472,14080, + 480,3840, 488,12032, 496,7936, 504,16128, 520,8320, 528,4224, 536,12416, + 544,2176, 552,10368, 560,6272, 568,14464, 576,1152, 584,9344, 592,5248, + 600,13440, 608,3200, 616,11392, 624,7296, 632,15488, 648,8832, 656,4736, + 664,12928, 672,2688, 680,10880, 688,6784, 696,14976, 704,1664, 712,9856, + 720,5760, 728,13952, 736,3712, 744,11904, 752,7808, 760,16000, 776,8576, + 784,4480, 792,12672, 800,2432, 808,10624, 816,6528, 824,14720, 832,1408, + 840,9600, 848,5504, 856,13696, 864,3456, 872,11648, 880,7552, 888,15744, + 904,9088, 912,4992, 920,13184, 928,2944, 936,11136, 944,7040, 952,15232, + 960,1920, 968,10112, 976,6016, 984,14208, 992,3968, 1000,12160, 1008,8064, + 1016,16256, 1032,8256, 1040,4160, 1048,12352, 1056,2112, 1064,10304, 1072,6208, + 1080,14400, 1096,9280, 1104,5184, 1112,13376, 1120,3136, 1128,11328, 1136,7232, + 1144,15424, 1160,8768, 1168,4672, 1176,12864, 1184,2624, 1192,10816, 1200,6720, + 1208,14912, 1216,1600, 1224,9792, 1232,5696, 1240,13888, 1248,3648, 1256,11840, + 1264,7744, 1272,15936, 1288,8512, 1296,4416, 1304,12608, 1312,2368, 1320,10560, + 1328,6464, 1336,14656, 1352,9536, 1360,5440, 1368,13632, 1376,3392, 1384,11584, + 1392,7488, 1400,15680, 1416,9024, 1424,4928, 1432,13120, 1440,2880, 1448,11072, + 1456,6976, 1464,15168, 1472,1856, 1480,10048, 1488,5952, 1496,14144, 1504,3904, + 1512,12096, 1520,8000, 1528,16192, 1544,8384, 1552,4288, 1560,12480, 1568,2240, + 1576,10432, 1584,6336, 1592,14528, 1608,9408, 1616,5312, 1624,13504, 1632,3264, + 1640,11456, 1648,7360, 1656,15552, 1672,8896, 1680,4800, 1688,12992, 1696,2752, + 1704,10944, 1712,6848, 1720,15040, 1736,9920, 1744,5824, 1752,14016, 1760,3776, + 1768,11968, 1776,7872, 1784,16064, 1800,8640, 1808,4544, 1816,12736, 1824,2496, + 1832,10688, 1840,6592, 1848,14784, 1864,9664, 1872,5568, 1880,13760, 1888,3520, + 1896,11712, 1904,7616, 1912,15808, 1928,9152, 1936,5056, 1944,13248, 1952,3008, + 1960,11200, 1968,7104, 1976,15296, 1992,10176, 2000,6080, 2008,14272, 2016,4032, + 2024,12224, 2032,8128, 2040,16320, 2056,8224, 2064,4128, 2072,12320, 2088,10272, + 2096,6176, 2104,14368, 2120,9248, 2128,5152, 2136,13344, 2144,3104, 2152,11296, + 2160,7200, 2168,15392, 2184,8736, 2192,4640, 2200,12832, 2208,2592, 2216,10784, + 2224,6688, 2232,14880, 2248,9760, 2256,5664, 2264,13856, 2272,3616, 2280,11808, + 2288,7712, 2296,15904, 2312,8480, 2320,4384, 2328,12576, 2344,10528, 2352,6432, + 2360,14624, 2376,9504, 2384,5408, 2392,13600, 2400,3360, 2408,11552, 2416,7456, + 2424,15648, 2440,8992, 2448,4896, 2456,13088, 2464,2848, 2472,11040, 2480,6944, + 2488,15136, 2504,10016, 2512,5920, 2520,14112, 2528,3872, 2536,12064, 2544,7968, + 2552,16160, 2568,8352, 2576,4256, 2584,12448, 2600,10400, 2608,6304, 2616,14496, + 2632,9376, 2640,5280, 2648,13472, 2656,3232, 2664,11424, 2672,7328, 2680,15520, + 2696,8864, 2704,4768, 2712,12960, 2728,10912, 2736,6816, 2744,15008, 2760,9888, + 2768,5792, 2776,13984, 2784,3744, 2792,11936, 2800,7840, 2808,16032, 2824,8608, + 2832,4512, 2840,12704, 2856,10656, 2864,6560, 2872,14752, 2888,9632, 2896,5536, + 2904,13728, 2912,3488, 2920,11680, 2928,7584, 2936,15776, 2952,9120, 2960,5024, + 2968,13216, 2984,11168, 2992,7072, 3000,15264, 3016,10144, 3024,6048, + 3032,14240, 3040,4000, 3048,12192, 3056,8096, 3064,16288, 3080,8288, 3088,4192, + 3096,12384, 3112,10336, 3120,6240, 3128,14432, 3144,9312, 3152,5216, 3160,13408, + 3176,11360, 3184,7264, 3192,15456, 3208,8800, 3216,4704, 3224,12896, 3240,10848, + 3248,6752, 3256,14944, 3272,9824, 3280,5728, 3288,13920, 3296,3680, 3304,11872, + 3312,7776, 3320,15968, 3336,8544, 3344,4448, 3352,12640, 3368,10592, 3376,6496, + 3384,14688, 3400,9568, 3408,5472, 3416,13664, 3432,11616, 3440,7520, 3448,15712, + 3464,9056, 3472,4960, 3480,13152, 3496,11104, 3504,7008, 3512,15200, 3528,10080, + 3536,5984, 3544,14176, 3552,3936, 3560,12128, 3568,8032, 3576,16224, 3592,8416, + 3600,4320, 3608,12512, 3624,10464, 3632,6368, 3640,14560, 3656,9440, 3664,5344, + 3672,13536, 3688,11488, 3696,7392, 3704,15584, 3720,8928, 3728,4832, 3736,13024, + 3752,10976, 3760,6880, 3768,15072, 3784,9952, 3792,5856, 3800,14048, 3816,12000, + 3824,7904, 3832,16096, 3848,8672, 3856,4576, 3864,12768, 3880,10720, 3888,6624, + 3896,14816, 3912,9696, 3920,5600, 3928,13792, 3944,11744, 3952,7648, 3960,15840, + 3976,9184, 3984,5088, 3992,13280, 4008,11232, 4016,7136, 4024,15328, 4040,10208, + 4048,6112, 4056,14304, 4072,12256, 4080,8160, 4088,16352, 4104,8208, 4120,12304, + 4136,10256, 4144,6160, 4152,14352, 4168,9232, 4176,5136, 4184,13328, 4200,11280, + 4208,7184, 4216,15376, 4232,8720, 4240,4624, 4248,12816, 4264,10768, 4272,6672, + 4280,14864, 4296,9744, 4304,5648, 4312,13840, 4328,11792, 4336,7696, 4344,15888, + 4360,8464, 4376,12560, 4392,10512, 4400,6416, 4408,14608, 4424,9488, 4432,5392, + 4440,13584, 4456,11536, 4464,7440, 4472,15632, 4488,8976, 4496,4880, 4504,13072, + 4520,11024, 4528,6928, 4536,15120, 4552,10000, 4560,5904, 4568,14096, + 4584,12048, 4592,7952, 4600,16144, 4616,8336, 4632,12432, 4648,10384, 4656,6288, + 4664,14480, 4680,9360, 4688,5264, 4696,13456, 4712,11408, 4720,7312, 4728,15504, + 4744,8848, 4760,12944, 4776,10896, 4784,6800, 4792,14992, 4808,9872, 4816,5776, + 4824,13968, 4840,11920, 4848,7824, 4856,16016, 4872,8592, 4888,12688, + 4904,10640, 4912,6544, 4920,14736, 4936,9616, 4944,5520, 4952,13712, 4968,11664, + 4976,7568, 4984,15760, 5000,9104, 5016,13200, 5032,11152, 5040,7056, 5048,15248, + 5064,10128, 5072,6032, 5080,14224, 5096,12176, 5104,8080, 5112,16272, 5128,8272, + 5144,12368, 5160,10320, 5168,6224, 5176,14416, 5192,9296, 5208,13392, + 5224,11344, 5232,7248, 5240,15440, 5256,8784, 5272,12880, 5288,10832, 5296,6736, + 5304,14928, 5320,9808, 5328,5712, 5336,13904, 5352,11856, 5360,7760, 5368,15952, + 5384,8528, 5400,12624, 5416,10576, 5424,6480, 5432,14672, 5448,9552, 5464,13648, + 5480,11600, 5488,7504, 5496,15696, 5512,9040, 5528,13136, 5544,11088, 5552,6992, + 5560,15184, 5576,10064, 5584,5968, 5592,14160, 5608,12112, 5616,8016, + 5624,16208, 5640,8400, 5656,12496, 5672,10448, 5680,6352, 5688,14544, 5704,9424, + 5720,13520, 5736,11472, 5744,7376, 5752,15568, 5768,8912, 5784,13008, + 5800,10960, 5808,6864, 5816,15056, 5832,9936, 5848,14032, 5864,11984, 5872,7888, + 5880,16080, 5896,8656, 5912,12752, 5928,10704, 5936,6608, 5944,14800, 5960,9680, + 5976,13776, 5992,11728, 6000,7632, 6008,15824, 6024,9168, 6040,13264, + 6056,11216, 6064,7120, 6072,15312, 6088,10192, 6104,14288, 6120,12240, + 6128,8144, 6136,16336, 6152,8240, 6168,12336, 6184,10288, 6200,14384, 6216,9264, + 6232,13360, 6248,11312, 6256,7216, 6264,15408, 6280,8752, 6296,12848, + 6312,10800, 6320,6704, 6328,14896, 6344,9776, 6360,13872, 6376,11824, 6384,7728, + 6392,15920, 6408,8496, 6424,12592, 6440,10544, 6456,14640, 6472,9520, + 6488,13616, 6504,11568, 6512,7472, 6520,15664, 6536,9008, 6552,13104, + 6568,11056, 6576,6960, 6584,15152, 6600,10032, 6616,14128, 6632,12080, + 6640,7984, 6648,16176, 6664,8368, 6680,12464, 6696,10416, 6712,14512, 6728,9392, + 6744,13488, 6760,11440, 6768,7344, 6776,15536, 6792,8880, 6808,12976, + 6824,10928, 6840,15024, 6856,9904, 6872,14000, 6888,11952, 6896,7856, + 6904,16048, 6920,8624, 6936,12720, 6952,10672, 6968,14768, 6984,9648, + 7000,13744, 7016,11696, 7024,7600, 7032,15792, 7048,9136, 7064,13232, + 7080,11184, 7096,15280, 7112,10160, 7128,14256, 7144,12208, 7152,8112, + 7160,16304, 7176,8304, 7192,12400, 7208,10352, 7224,14448, 7240,9328, + 7256,13424, 7272,11376, 7288,15472, 7304,8816, 7320,12912, 7336,10864, + 7352,14960, 7368,9840, 7384,13936, 7400,11888, 7408,7792, 7416,15984, 7432,8560, + 7448,12656, 7464,10608, 7480,14704, 7496,9584, 7512,13680, 7528,11632, + 7544,15728, 7560,9072, 7576,13168, 7592,11120, 7608,15216, 7624,10096, + 7640,14192, 7656,12144, 7664,8048, 7672,16240, 7688,8432, 7704,12528, + 7720,10480, 7736,14576, 7752,9456, 7768,13552, 7784,11504, 7800,15600, + 7816,8944, 7832,13040, 7848,10992, 7864,15088, 7880,9968, 7896,14064, + 7912,12016, 7928,16112, 7944,8688, 7960,12784, 7976,10736, 7992,14832, + 8008,9712, 8024,13808, 8040,11760, 8056,15856, 8072,9200, 8088,13296, + 8104,11248, 8120,15344, 8136,10224, 8152,14320, 8168,12272, 8184,16368, + 8216,12296, 8232,10248, 8248,14344, 8264,9224, 8280,13320, 8296,11272, + 8312,15368, 8328,8712, 8344,12808, 8360,10760, 8376,14856, 8392,9736, + 8408,13832, 8424,11784, 8440,15880, 8472,12552, 8488,10504, 8504,14600, + 8520,9480, 8536,13576, 8552,11528, 8568,15624, 8584,8968, 8600,13064, + 8616,11016, 8632,15112, 8648,9992, 8664,14088, 8680,12040, 8696,16136, + 8728,12424, 8744,10376, 8760,14472, 8776,9352, 8792,13448, 8808,11400, + 8824,15496, 8856,12936, 8872,10888, 8888,14984, 8904,9864, 8920,13960, + 8936,11912, 8952,16008, 8984,12680, 9000,10632, 9016,14728, 9032,9608, + 9048,13704, 9064,11656, 9080,15752, 9112,13192, 9128,11144, 9144,15240, + 9160,10120, 9176,14216, 9192,12168, 9208,16264, 9240,12360, 9256,10312, + 9272,14408, 9304,13384, 9320,11336, 9336,15432, 9368,12872, 9384,10824, + 9400,14920, 9416,9800, 9432,13896, 9448,11848, 9464,15944, 9496,12616, + 9512,10568, 9528,14664, 9560,13640, 9576,11592, 9592,15688, 9624,13128, + 9640,11080, 9656,15176, 9672,10056, 9688,14152, 9704,12104, 9720,16200, + 9752,12488, 9768,10440, 9784,14536, 9816,13512, 9832,11464, 9848,15560, + 9880,13000, 9896,10952, 9912,15048, 9944,14024, 9960,11976, 9976,16072, + 10008,12744, 10024,10696, 10040,14792, 10072,13768, 10088,11720, 10104,15816, + 10136,13256, 10152,11208, 10168,15304, 10200,14280, 10216,12232, 10232,16328, + 10264,12328, 10296,14376, 10328,13352, 10344,11304, 10360,15400, 10392,12840, + 10408,10792, 10424,14888, 10456,13864, 10472,11816, 10488,15912, 10520,12584, + 10552,14632, 10584,13608, 10600,11560, 10616,15656, 10648,13096, 10664,11048, + 10680,15144, 10712,14120, 10728,12072, 10744,16168, 10776,12456, 10808,14504, + 10840,13480, 10856,11432, 10872,15528, 10904,12968, 10936,15016, 10968,13992, + 10984,11944, 11000,16040, 11032,12712, 11064,14760, 11096,13736, 11112,11688, + 11128,15784, 11160,13224, 11192,15272, 11224,14248, 11240,12200, 11256,16296, + 11288,12392, 11320,14440, 11352,13416, 11384,15464, 11416,12904, 11448,14952, + 11480,13928, 11496,11880, 11512,15976, 11544,12648, 11576,14696, 11608,13672, + 11640,15720, 11672,13160, 11704,15208, 11736,14184, 11752,12136, 11768,16232, + 11800,12520, 11832,14568, 11864,13544, 11896,15592, 11928,13032, 11960,15080, + 11992,14056, 12024,16104, 12056,12776, 12088,14824, 12120,13800, 12152,15848, + 12184,13288, 12216,15336, 12248,14312, 12280,16360, 12344,14360, 12376,13336, + 12408,15384, 12440,12824, 12472,14872, 12504,13848, 12536,15896, 12600,14616, + 12632,13592, 12664,15640, 12696,13080, 12728,15128, 12760,14104, 12792,16152, + 12856,14488, 12888,13464, 12920,15512, 12984,15000, 13016,13976, 13048,16024, + 13112,14744, 13144,13720, 13176,15768, 13240,15256, 13272,14232, 13304,16280, + 13368,14424, 13432,15448, 13496,14936, 13528,13912, 13560,15960, 13624,14680, + 13688,15704, 13752,15192, 13784,14168, 13816,16216, 13880,14552, 13944,15576, + 14008,15064, 14072,16088, 14136,14808, 14200,15832, 14264,15320, 14328,16344, + 14456,15416, 14520,14904, 14584,15928, 14712,15672, 14776,15160, 14840,16184, + 14968,15544, 15096,16056, 15224,15800, 15352,16312, 15608,15992, 15864,16248 +}; + +const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH] = +{ + /* radix 4, size 4032 */ + 8,16384, 16,8192, 24,24576, 32,4096, 40,20480, 48,12288, 56,28672, 64,2048, + 72,18432, 80,10240, 88,26624, 96,6144, 104,22528, 112,14336, 120,30720, + 128,1024, 136,17408, 144,9216, 152,25600, 160,5120, 168,21504, 176,13312, + 184,29696, 192,3072, 200,19456, 208,11264, 216,27648, 224,7168, 232,23552, + 240,15360, 248,31744, 256,512, 264,16896, 272,8704, 280,25088, 288,4608, + 296,20992, 304,12800, 312,29184, 320,2560, 328,18944, 336,10752, 344,27136, + 352,6656, 360,23040, 368,14848, 376,31232, 384,1536, 392,17920, 400,9728, + 408,26112, 416,5632, 424,22016, 432,13824, 440,30208, 448,3584, 456,19968, + 464,11776, 472,28160, 480,7680, 488,24064, 496,15872, 504,32256, 520,16640, + 528,8448, 536,24832, 544,4352, 552,20736, 560,12544, 568,28928, 576,2304, + 584,18688, 592,10496, 600,26880, 608,6400, 616,22784, 624,14592, 632,30976, + 640,1280, 648,17664, 656,9472, 664,25856, 672,5376, 680,21760, 688,13568, + 696,29952, 704,3328, 712,19712, 720,11520, 728,27904, 736,7424, 744,23808, + 752,15616, 760,32000, 776,17152, 784,8960, 792,25344, 800,4864, 808,21248, + 816,13056, 824,29440, 832,2816, 840,19200, 848,11008, 856,27392, 864,6912, + 872,23296, 880,15104, 888,31488, 896,1792, 904,18176, 912,9984, 920,26368, + 928,5888, 936,22272, 944,14080, 952,30464, 960,3840, 968,20224, 976,12032, + 984,28416, 992,7936, 1000,24320, 1008,16128, 1016,32512, 1032,16512, 1040,8320, + 1048,24704, 1056,4224, 1064,20608, 1072,12416, 1080,28800, 1088,2176, + 1096,18560, 1104,10368, 1112,26752, 1120,6272, 1128,22656, 1136,14464, + 1144,30848, 1160,17536, 1168,9344, 1176,25728, 1184,5248, 1192,21632, + 1200,13440, 1208,29824, 1216,3200, 1224,19584, 1232,11392, 1240,27776, + 1248,7296, 1256,23680, 1264,15488, 1272,31872, 1288,17024, 1296,8832, + 1304,25216, 1312,4736, 1320,21120, 1328,12928, 1336,29312, 1344,2688, + 1352,19072, 1360,10880, 1368,27264, 1376,6784, 1384,23168, 1392,14976, + 1400,31360, 1408,1664, 1416,18048, 1424,9856, 1432,26240, 1440,5760, 1448,22144, + 1456,13952, 1464,30336, 1472,3712, 1480,20096, 1488,11904, 1496,28288, + 1504,7808, 1512,24192, 1520,16000, 1528,32384, 1544,16768, 1552,8576, + 1560,24960, 1568,4480, 1576,20864, 1584,12672, 1592,29056, 1600,2432, + 1608,18816, 1616,10624, 1624,27008, 1632,6528, 1640,22912, 1648,14720, + 1656,31104, 1672,17792, 1680,9600, 1688,25984, 1696,5504, 1704,21888, + 1712,13696, 1720,30080, 1728,3456, 1736,19840, 1744,11648, 1752,28032, + 1760,7552, 1768,23936, 1776,15744, 1784,32128, 1800,17280, 1808,9088, + 1816,25472, 1824,4992, 1832,21376, 1840,13184, 1848,29568, 1856,2944, + 1864,19328, 1872,11136, 1880,27520, 1888,7040, 1896,23424, 1904,15232, + 1912,31616, 1928,18304, 1936,10112, 1944,26496, 1952,6016, 1960,22400, + 1968,14208, 1976,30592, 1984,3968, 1992,20352, 2000,12160, 2008,28544, + 2016,8064, 2024,24448, 2032,16256, 2040,32640, 2056,16448, 2064,8256, + 2072,24640, 2080,4160, 2088,20544, 2096,12352, 2104,28736, 2120,18496, + 2128,10304, 2136,26688, 2144,6208, 2152,22592, 2160,14400, 2168,30784, + 2184,17472, 2192,9280, 2200,25664, 2208,5184, 2216,21568, 2224,13376, + 2232,29760, 2240,3136, 2248,19520, 2256,11328, 2264,27712, 2272,7232, + 2280,23616, 2288,15424, 2296,31808, 2312,16960, 2320,8768, 2328,25152, + 2336,4672, 2344,21056, 2352,12864, 2360,29248, 2368,2624, 2376,19008, + 2384,10816, 2392,27200, 2400,6720, 2408,23104, 2416,14912, 2424,31296, + 2440,17984, 2448,9792, 2456,26176, 2464,5696, 2472,22080, 2480,13888, + 2488,30272, 2496,3648, 2504,20032, 2512,11840, 2520,28224, 2528,7744, + 2536,24128, 2544,15936, 2552,32320, 2568,16704, 2576,8512, 2584,24896, + 2592,4416, 2600,20800, 2608,12608, 2616,28992, 2632,18752, 2640,10560, + 2648,26944, 2656,6464, 2664,22848, 2672,14656, 2680,31040, 2696,17728, + 2704,9536, 2712,25920, 2720,5440, 2728,21824, 2736,13632, 2744,30016, 2752,3392, + 2760,19776, 2768,11584, 2776,27968, 2784,7488, 2792,23872, 2800,15680, + 2808,32064, 2824,17216, 2832,9024, 2840,25408, 2848,4928, 2856,21312, + 2864,13120, 2872,29504, 2888,19264, 2896,11072, 2904,27456, 2912,6976, + 2920,23360, 2928,15168, 2936,31552, 2952,18240, 2960,10048, 2968,26432, + 2976,5952, 2984,22336, 2992,14144, 3000,30528, 3008,3904, 3016,20288, + 3024,12096, 3032,28480, 3040,8000, 3048,24384, 3056,16192, 3064,32576, + 3080,16576, 3088,8384, 3096,24768, 3104,4288, 3112,20672, 3120,12480, + 3128,28864, 3144,18624, 3152,10432, 3160,26816, 3168,6336, 3176,22720, + 3184,14528, 3192,30912, 3208,17600, 3216,9408, 3224,25792, 3232,5312, + 3240,21696, 3248,13504, 3256,29888, 3272,19648, 3280,11456, 3288,27840, + 3296,7360, 3304,23744, 3312,15552, 3320,31936, 3336,17088, 3344,8896, + 3352,25280, 3360,4800, 3368,21184, 3376,12992, 3384,29376, 3400,19136, + 3408,10944, 3416,27328, 3424,6848, 3432,23232, 3440,15040, 3448,31424, + 3464,18112, 3472,9920, 3480,26304, 3488,5824, 3496,22208, 3504,14016, + 3512,30400, 3520,3776, 3528,20160, 3536,11968, 3544,28352, 3552,7872, + 3560,24256, 3568,16064, 3576,32448, 3592,16832, 3600,8640, 3608,25024, + 3616,4544, 3624,20928, 3632,12736, 3640,29120, 3656,18880, 3664,10688, + 3672,27072, 3680,6592, 3688,22976, 3696,14784, 3704,31168, 3720,17856, + 3728,9664, 3736,26048, 3744,5568, 3752,21952, 3760,13760, 3768,30144, + 3784,19904, 3792,11712, 3800,28096, 3808,7616, 3816,24000, 3824,15808, + 3832,32192, 3848,17344, 3856,9152, 3864,25536, 3872,5056, 3880,21440, + 3888,13248, 3896,29632, 3912,19392, 3920,11200, 3928,27584, 3936,7104, + 3944,23488, 3952,15296, 3960,31680, 3976,18368, 3984,10176, 3992,26560, + 4000,6080, 4008,22464, 4016,14272, 4024,30656, 4040,20416, 4048,12224, + 4056,28608, 4064,8128, 4072,24512, 4080,16320, 4088,32704, 4104,16416, + 4112,8224, 4120,24608, 4136,20512, 4144,12320, 4152,28704, 4168,18464, + 4176,10272, 4184,26656, 4192,6176, 4200,22560, 4208,14368, 4216,30752, + 4232,17440, 4240,9248, 4248,25632, 4256,5152, 4264,21536, 4272,13344, + 4280,29728, 4296,19488, 4304,11296, 4312,27680, 4320,7200, 4328,23584, + 4336,15392, 4344,31776, 4360,16928, 4368,8736, 4376,25120, 4384,4640, + 4392,21024, 4400,12832, 4408,29216, 4424,18976, 4432,10784, 4440,27168, + 4448,6688, 4456,23072, 4464,14880, 4472,31264, 4488,17952, 4496,9760, + 4504,26144, 4512,5664, 4520,22048, 4528,13856, 4536,30240, 4552,20000, + 4560,11808, 4568,28192, 4576,7712, 4584,24096, 4592,15904, 4600,32288, + 4616,16672, 4624,8480, 4632,24864, 4648,20768, 4656,12576, 4664,28960, + 4680,18720, 4688,10528, 4696,26912, 4704,6432, 4712,22816, 4720,14624, + 4728,31008, 4744,17696, 4752,9504, 4760,25888, 4768,5408, 4776,21792, + 4784,13600, 4792,29984, 4808,19744, 4816,11552, 4824,27936, 4832,7456, + 4840,23840, 4848,15648, 4856,32032, 4872,17184, 4880,8992, 4888,25376, + 4904,21280, 4912,13088, 4920,29472, 4936,19232, 4944,11040, 4952,27424, + 4960,6944, 4968,23328, 4976,15136, 4984,31520, 5000,18208, 5008,10016, + 5016,26400, 5024,5920, 5032,22304, 5040,14112, 5048,30496, 5064,20256, + 5072,12064, 5080,28448, 5088,7968, 5096,24352, 5104,16160, 5112,32544, + 5128,16544, 5136,8352, 5144,24736, 5160,20640, 5168,12448, 5176,28832, + 5192,18592, 5200,10400, 5208,26784, 5216,6304, 5224,22688, 5232,14496, + 5240,30880, 5256,17568, 5264,9376, 5272,25760, 5288,21664, 5296,13472, + 5304,29856, 5320,19616, 5328,11424, 5336,27808, 5344,7328, 5352,23712, + 5360,15520, 5368,31904, 5384,17056, 5392,8864, 5400,25248, 5416,21152, + 5424,12960, 5432,29344, 5448,19104, 5456,10912, 5464,27296, 5472,6816, + 5480,23200, 5488,15008, 5496,31392, 5512,18080, 5520,9888, 5528,26272, + 5536,5792, 5544,22176, 5552,13984, 5560,30368, 5576,20128, 5584,11936, + 5592,28320, 5600,7840, 5608,24224, 5616,16032, 5624,32416, 5640,16800, + 5648,8608, 5656,24992, 5672,20896, 5680,12704, 5688,29088, 5704,18848, + 5712,10656, 5720,27040, 5728,6560, 5736,22944, 5744,14752, 5752,31136, + 5768,17824, 5776,9632, 5784,26016, 5800,21920, 5808,13728, 5816,30112, + 5832,19872, 5840,11680, 5848,28064, 5856,7584, 5864,23968, 5872,15776, + 5880,32160, 5896,17312, 5904,9120, 5912,25504, 5928,21408, 5936,13216, + 5944,29600, 5960,19360, 5968,11168, 5976,27552, 5984,7072, 5992,23456, + 6000,15264, 6008,31648, 6024,18336, 6032,10144, 6040,26528, 6056,22432, + 6064,14240, 6072,30624, 6088,20384, 6096,12192, 6104,28576, 6112,8096, + 6120,24480, 6128,16288, 6136,32672, 6152,16480, 6160,8288, 6168,24672, + 6184,20576, 6192,12384, 6200,28768, 6216,18528, 6224,10336, 6232,26720, + 6248,22624, 6256,14432, 6264,30816, 6280,17504, 6288,9312, 6296,25696, + 6312,21600, 6320,13408, 6328,29792, 6344,19552, 6352,11360, 6360,27744, + 6368,7264, 6376,23648, 6384,15456, 6392,31840, 6408,16992, 6416,8800, + 6424,25184, 6440,21088, 6448,12896, 6456,29280, 6472,19040, 6480,10848, + 6488,27232, 6496,6752, 6504,23136, 6512,14944, 6520,31328, 6536,18016, + 6544,9824, 6552,26208, 6568,22112, 6576,13920, 6584,30304, 6600,20064, + 6608,11872, 6616,28256, 6624,7776, 6632,24160, 6640,15968, 6648,32352, + 6664,16736, 6672,8544, 6680,24928, 6696,20832, 6704,12640, 6712,29024, + 6728,18784, 6736,10592, 6744,26976, 6760,22880, 6768,14688, 6776,31072, + 6792,17760, 6800,9568, 6808,25952, 6824,21856, 6832,13664, 6840,30048, + 6856,19808, 6864,11616, 6872,28000, 6880,7520, 6888,23904, 6896,15712, + 6904,32096, 6920,17248, 6928,9056, 6936,25440, 6952,21344, 6960,13152, + 6968,29536, 6984,19296, 6992,11104, 7000,27488, 7016,23392, 7024,15200, + 7032,31584, 7048,18272, 7056,10080, 7064,26464, 7080,22368, 7088,14176, + 7096,30560, 7112,20320, 7120,12128, 7128,28512, 7136,8032, 7144,24416, + 7152,16224, 7160,32608, 7176,16608, 7184,8416, 7192,24800, 7208,20704, + 7216,12512, 7224,28896, 7240,18656, 7248,10464, 7256,26848, 7272,22752, + 7280,14560, 7288,30944, 7304,17632, 7312,9440, 7320,25824, 7336,21728, + 7344,13536, 7352,29920, 7368,19680, 7376,11488, 7384,27872, 7400,23776, + 7408,15584, 7416,31968, 7432,17120, 7440,8928, 7448,25312, 7464,21216, + 7472,13024, 7480,29408, 7496,19168, 7504,10976, 7512,27360, 7528,23264, + 7536,15072, 7544,31456, 7560,18144, 7568,9952, 7576,26336, 7592,22240, + 7600,14048, 7608,30432, 7624,20192, 7632,12000, 7640,28384, 7648,7904, + 7656,24288, 7664,16096, 7672,32480, 7688,16864, 7696,8672, 7704,25056, + 7720,20960, 7728,12768, 7736,29152, 7752,18912, 7760,10720, 7768,27104, + 7784,23008, 7792,14816, 7800,31200, 7816,17888, 7824,9696, 7832,26080, + 7848,21984, 7856,13792, 7864,30176, 7880,19936, 7888,11744, 7896,28128, + 7912,24032, 7920,15840, 7928,32224, 7944,17376, 7952,9184, 7960,25568, + 7976,21472, 7984,13280, 7992,29664, 8008,19424, 8016,11232, 8024,27616, + 8040,23520, 8048,15328, 8056,31712, 8072,18400, 8080,10208, 8088,26592, + 8104,22496, 8112,14304, 8120,30688, 8136,20448, 8144,12256, 8152,28640, + 8168,24544, 8176,16352, 8184,32736, 8200,16400, 8216,24592, 8232,20496, + 8240,12304, 8248,28688, 8264,18448, 8272,10256, 8280,26640, 8296,22544, + 8304,14352, 8312,30736, 8328,17424, 8336,9232, 8344,25616, 8360,21520, + 8368,13328, 8376,29712, 8392,19472, 8400,11280, 8408,27664, 8424,23568, + 8432,15376, 8440,31760, 8456,16912, 8464,8720, 8472,25104, 8488,21008, + 8496,12816, 8504,29200, 8520,18960, 8528,10768, 8536,27152, 8552,23056, + 8560,14864, 8568,31248, 8584,17936, 8592,9744, 8600,26128, 8616,22032, + 8624,13840, 8632,30224, 8648,19984, 8656,11792, 8664,28176, 8680,24080, + 8688,15888, 8696,32272, 8712,16656, 8728,24848, 8744,20752, 8752,12560, + 8760,28944, 8776,18704, 8784,10512, 8792,26896, 8808,22800, 8816,14608, + 8824,30992, 8840,17680, 8848,9488, 8856,25872, 8872,21776, 8880,13584, + 8888,29968, 8904,19728, 8912,11536, 8920,27920, 8936,23824, 8944,15632, + 8952,32016, 8968,17168, 8984,25360, 9000,21264, 9008,13072, 9016,29456, + 9032,19216, 9040,11024, 9048,27408, 9064,23312, 9072,15120, 9080,31504, + 9096,18192, 9104,10000, 9112,26384, 9128,22288, 9136,14096, 9144,30480, + 9160,20240, 9168,12048, 9176,28432, 9192,24336, 9200,16144, 9208,32528, + 9224,16528, 9240,24720, 9256,20624, 9264,12432, 9272,28816, 9288,18576, + 9296,10384, 9304,26768, 9320,22672, 9328,14480, 9336,30864, 9352,17552, + 9368,25744, 9384,21648, 9392,13456, 9400,29840, 9416,19600, 9424,11408, + 9432,27792, 9448,23696, 9456,15504, 9464,31888, 9480,17040, 9496,25232, + 9512,21136, 9520,12944, 9528,29328, 9544,19088, 9552,10896, 9560,27280, + 9576,23184, 9584,14992, 9592,31376, 9608,18064, 9616,9872, 9624,26256, + 9640,22160, 9648,13968, 9656,30352, 9672,20112, 9680,11920, 9688,28304, + 9704,24208, 9712,16016, 9720,32400, 9736,16784, 9752,24976, 9768,20880, + 9776,12688, 9784,29072, 9800,18832, 9808,10640, 9816,27024, 9832,22928, + 9840,14736, 9848,31120, 9864,17808, 9880,26000, 9896,21904, 9904,13712, + 9912,30096, 9928,19856, 9936,11664, 9944,28048, 9960,23952, 9968,15760, + 9976,32144, 9992,17296, 10008,25488, 10024,21392, 10032,13200, 10040,29584, + 10056,19344, 10064,11152, 10072,27536, 10088,23440, 10096,15248, 10104,31632, + 10120,18320, 10136,26512, 10152,22416, 10160,14224, 10168,30608, 10184,20368, + 10192,12176, 10200,28560, 10216,24464, 10224,16272, 10232,32656, 10248,16464, + 10264,24656, 10280,20560, 10288,12368, 10296,28752, 10312,18512, 10328,26704, + 10344,22608, 10352,14416, 10360,30800, 10376,17488, 10392,25680, 10408,21584, + 10416,13392, 10424,29776, 10440,19536, 10448,11344, 10456,27728, 10472,23632, + 10480,15440, 10488,31824, 10504,16976, 10520,25168, 10536,21072, 10544,12880, + 10552,29264, 10568,19024, 10576,10832, 10584,27216, 10600,23120, 10608,14928, + 10616,31312, 10632,18000, 10648,26192, 10664,22096, 10672,13904, 10680,30288, + 10696,20048, 10704,11856, 10712,28240, 10728,24144, 10736,15952, 10744,32336, + 10760,16720, 10776,24912, 10792,20816, 10800,12624, 10808,29008, 10824,18768, + 10840,26960, 10856,22864, 10864,14672, 10872,31056, 10888,17744, 10904,25936, + 10920,21840, 10928,13648, 10936,30032, 10952,19792, 10960,11600, 10968,27984, + 10984,23888, 10992,15696, 11000,32080, 11016,17232, 11032,25424, 11048,21328, + 11056,13136, 11064,29520, 11080,19280, 11096,27472, 11112,23376, 11120,15184, + 11128,31568, 11144,18256, 11160,26448, 11176,22352, 11184,14160, 11192,30544, + 11208,20304, 11216,12112, 11224,28496, 11240,24400, 11248,16208, 11256,32592, + 11272,16592, 11288,24784, 11304,20688, 11312,12496, 11320,28880, 11336,18640, + 11352,26832, 11368,22736, 11376,14544, 11384,30928, 11400,17616, 11416,25808, + 11432,21712, 11440,13520, 11448,29904, 11464,19664, 11480,27856, 11496,23760, + 11504,15568, 11512,31952, 11528,17104, 11544,25296, 11560,21200, 11568,13008, + 11576,29392, 11592,19152, 11608,27344, 11624,23248, 11632,15056, 11640,31440, + 11656,18128, 11672,26320, 11688,22224, 11696,14032, 11704,30416, 11720,20176, + 11728,11984, 11736,28368, 11752,24272, 11760,16080, 11768,32464, 11784,16848, + 11800,25040, 11816,20944, 11824,12752, 11832,29136, 11848,18896, 11864,27088, + 11880,22992, 11888,14800, 11896,31184, 11912,17872, 11928,26064, 11944,21968, + 11952,13776, 11960,30160, 11976,19920, 11992,28112, 12008,24016, 12016,15824, + 12024,32208, 12040,17360, 12056,25552, 12072,21456, 12080,13264, 12088,29648, + 12104,19408, 12120,27600, 12136,23504, 12144,15312, 12152,31696, 12168,18384, + 12184,26576, 12200,22480, 12208,14288, 12216,30672, 12232,20432, 12248,28624, + 12264,24528, 12272,16336, 12280,32720, 12296,16432, 12312,24624, 12328,20528, + 12344,28720, 12360,18480, 12376,26672, 12392,22576, 12400,14384, 12408,30768, + 12424,17456, 12440,25648, 12456,21552, 12464,13360, 12472,29744, 12488,19504, + 12504,27696, 12520,23600, 12528,15408, 12536,31792, 12552,16944, 12568,25136, + 12584,21040, 12592,12848, 12600,29232, 12616,18992, 12632,27184, 12648,23088, + 12656,14896, 12664,31280, 12680,17968, 12696,26160, 12712,22064, 12720,13872, + 12728,30256, 12744,20016, 12760,28208, 12776,24112, 12784,15920, 12792,32304, + 12808,16688, 12824,24880, 12840,20784, 12856,28976, 12872,18736, 12888,26928, + 12904,22832, 12912,14640, 12920,31024, 12936,17712, 12952,25904, 12968,21808, + 12976,13616, 12984,30000, 13000,19760, 13016,27952, 13032,23856, 13040,15664, + 13048,32048, 13064,17200, 13080,25392, 13096,21296, 13112,29488, 13128,19248, + 13144,27440, 13160,23344, 13168,15152, 13176,31536, 13192,18224, 13208,26416, + 13224,22320, 13232,14128, 13240,30512, 13256,20272, 13272,28464, 13288,24368, + 13296,16176, 13304,32560, 13320,16560, 13336,24752, 13352,20656, 13368,28848, + 13384,18608, 13400,26800, 13416,22704, 13424,14512, 13432,30896, 13448,17584, + 13464,25776, 13480,21680, 13496,29872, 13512,19632, 13528,27824, 13544,23728, + 13552,15536, 13560,31920, 13576,17072, 13592,25264, 13608,21168, 13624,29360, + 13640,19120, 13656,27312, 13672,23216, 13680,15024, 13688,31408, 13704,18096, + 13720,26288, 13736,22192, 13744,14000, 13752,30384, 13768,20144, 13784,28336, + 13800,24240, 13808,16048, 13816,32432, 13832,16816, 13848,25008, 13864,20912, + 13880,29104, 13896,18864, 13912,27056, 13928,22960, 13936,14768, 13944,31152, + 13960,17840, 13976,26032, 13992,21936, 14008,30128, 14024,19888, 14040,28080, + 14056,23984, 14064,15792, 14072,32176, 14088,17328, 14104,25520, 14120,21424, + 14136,29616, 14152,19376, 14168,27568, 14184,23472, 14192,15280, 14200,31664, + 14216,18352, 14232,26544, 14248,22448, 14264,30640, 14280,20400, 14296,28592, + 14312,24496, 14320,16304, 14328,32688, 14344,16496, 14360,24688, 14376,20592, + 14392,28784, 14408,18544, 14424,26736, 14440,22640, 14456,30832, 14472,17520, + 14488,25712, 14504,21616, 14520,29808, 14536,19568, 14552,27760, 14568,23664, + 14576,15472, 14584,31856, 14600,17008, 14616,25200, 14632,21104, 14648,29296, + 14664,19056, 14680,27248, 14696,23152, 14704,14960, 14712,31344, 14728,18032, + 14744,26224, 14760,22128, 14776,30320, 14792,20080, 14808,28272, 14824,24176, + 14832,15984, 14840,32368, 14856,16752, 14872,24944, 14888,20848, 14904,29040, + 14920,18800, 14936,26992, 14952,22896, 14968,31088, 14984,17776, 15000,25968, + 15016,21872, 15032,30064, 15048,19824, 15064,28016, 15080,23920, 15088,15728, + 15096,32112, 15112,17264, 15128,25456, 15144,21360, 15160,29552, 15176,19312, + 15192,27504, 15208,23408, 15224,31600, 15240,18288, 15256,26480, 15272,22384, + 15288,30576, 15304,20336, 15320,28528, 15336,24432, 15344,16240, 15352,32624, + 15368,16624, 15384,24816, 15400,20720, 15416,28912, 15432,18672, 15448,26864, + 15464,22768, 15480,30960, 15496,17648, 15512,25840, 15528,21744, 15544,29936, + 15560,19696, 15576,27888, 15592,23792, 15608,31984, 15624,17136, 15640,25328, + 15656,21232, 15672,29424, 15688,19184, 15704,27376, 15720,23280, 15736,31472, + 15752,18160, 15768,26352, 15784,22256, 15800,30448, 15816,20208, 15832,28400, + 15848,24304, 15856,16112, 15864,32496, 15880,16880, 15896,25072, 15912,20976, + 15928,29168, 15944,18928, 15960,27120, 15976,23024, 15992,31216, 16008,17904, + 16024,26096, 16040,22000, 16056,30192, 16072,19952, 16088,28144, 16104,24048, + 16120,32240, 16136,17392, 16152,25584, 16168,21488, 16184,29680, 16200,19440, + 16216,27632, 16232,23536, 16248,31728, 16264,18416, 16280,26608, 16296,22512, + 16312,30704, 16328,20464, 16344,28656, 16360,24560, 16376,32752, 16408,24584, + 16424,20488, 16440,28680, 16456,18440, 16472,26632, 16488,22536, 16504,30728, + 16520,17416, 16536,25608, 16552,21512, 16568,29704, 16584,19464, 16600,27656, + 16616,23560, 16632,31752, 16648,16904, 16664,25096, 16680,21000, 16696,29192, + 16712,18952, 16728,27144, 16744,23048, 16760,31240, 16776,17928, 16792,26120, + 16808,22024, 16824,30216, 16840,19976, 16856,28168, 16872,24072, 16888,32264, + 16920,24840, 16936,20744, 16952,28936, 16968,18696, 16984,26888, 17000,22792, + 17016,30984, 17032,17672, 17048,25864, 17064,21768, 17080,29960, 17096,19720, + 17112,27912, 17128,23816, 17144,32008, 17176,25352, 17192,21256, 17208,29448, + 17224,19208, 17240,27400, 17256,23304, 17272,31496, 17288,18184, 17304,26376, + 17320,22280, 17336,30472, 17352,20232, 17368,28424, 17384,24328, 17400,32520, + 17432,24712, 17448,20616, 17464,28808, 17480,18568, 17496,26760, 17512,22664, + 17528,30856, 17560,25736, 17576,21640, 17592,29832, 17608,19592, 17624,27784, + 17640,23688, 17656,31880, 17688,25224, 17704,21128, 17720,29320, 17736,19080, + 17752,27272, 17768,23176, 17784,31368, 17800,18056, 17816,26248, 17832,22152, + 17848,30344, 17864,20104, 17880,28296, 17896,24200, 17912,32392, 17944,24968, + 17960,20872, 17976,29064, 17992,18824, 18008,27016, 18024,22920, 18040,31112, + 18072,25992, 18088,21896, 18104,30088, 18120,19848, 18136,28040, 18152,23944, + 18168,32136, 18200,25480, 18216,21384, 18232,29576, 18248,19336, 18264,27528, + 18280,23432, 18296,31624, 18328,26504, 18344,22408, 18360,30600, 18376,20360, + 18392,28552, 18408,24456, 18424,32648, 18456,24648, 18472,20552, 18488,28744, + 18520,26696, 18536,22600, 18552,30792, 18584,25672, 18600,21576, 18616,29768, + 18632,19528, 18648,27720, 18664,23624, 18680,31816, 18712,25160, 18728,21064, + 18744,29256, 18760,19016, 18776,27208, 18792,23112, 18808,31304, 18840,26184, + 18856,22088, 18872,30280, 18888,20040, 18904,28232, 18920,24136, 18936,32328, + 18968,24904, 18984,20808, 19000,29000, 19032,26952, 19048,22856, 19064,31048, + 19096,25928, 19112,21832, 19128,30024, 19144,19784, 19160,27976, 19176,23880, + 19192,32072, 19224,25416, 19240,21320, 19256,29512, 19288,27464, 19304,23368, + 19320,31560, 19352,26440, 19368,22344, 19384,30536, 19400,20296, 19416,28488, + 19432,24392, 19448,32584, 19480,24776, 19496,20680, 19512,28872, 19544,26824, + 19560,22728, 19576,30920, 19608,25800, 19624,21704, 19640,29896, 19672,27848, + 19688,23752, 19704,31944, 19736,25288, 19752,21192, 19768,29384, 19800,27336, + 19816,23240, 19832,31432, 19864,26312, 19880,22216, 19896,30408, 19912,20168, + 19928,28360, 19944,24264, 19960,32456, 19992,25032, 20008,20936, 20024,29128, + 20056,27080, 20072,22984, 20088,31176, 20120,26056, 20136,21960, 20152,30152, + 20184,28104, 20200,24008, 20216,32200, 20248,25544, 20264,21448, 20280,29640, + 20312,27592, 20328,23496, 20344,31688, 20376,26568, 20392,22472, 20408,30664, + 20440,28616, 20456,24520, 20472,32712, 20504,24616, 20536,28712, 20568,26664, + 20584,22568, 20600,30760, 20632,25640, 20648,21544, 20664,29736, 20696,27688, + 20712,23592, 20728,31784, 20760,25128, 20776,21032, 20792,29224, 20824,27176, + 20840,23080, 20856,31272, 20888,26152, 20904,22056, 20920,30248, 20952,28200, + 20968,24104, 20984,32296, 21016,24872, 21048,28968, 21080,26920, 21096,22824, + 21112,31016, 21144,25896, 21160,21800, 21176,29992, 21208,27944, 21224,23848, + 21240,32040, 21272,25384, 21304,29480, 21336,27432, 21352,23336, 21368,31528, + 21400,26408, 21416,22312, 21432,30504, 21464,28456, 21480,24360, 21496,32552, + 21528,24744, 21560,28840, 21592,26792, 21608,22696, 21624,30888, 21656,25768, + 21688,29864, 21720,27816, 21736,23720, 21752,31912, 21784,25256, 21816,29352, + 21848,27304, 21864,23208, 21880,31400, 21912,26280, 21928,22184, 21944,30376, + 21976,28328, 21992,24232, 22008,32424, 22040,25000, 22072,29096, 22104,27048, + 22120,22952, 22136,31144, 22168,26024, 22200,30120, 22232,28072, 22248,23976, + 22264,32168, 22296,25512, 22328,29608, 22360,27560, 22376,23464, 22392,31656, + 22424,26536, 22456,30632, 22488,28584, 22504,24488, 22520,32680, 22552,24680, + 22584,28776, 22616,26728, 22648,30824, 22680,25704, 22712,29800, 22744,27752, + 22760,23656, 22776,31848, 22808,25192, 22840,29288, 22872,27240, 22888,23144, + 22904,31336, 22936,26216, 22968,30312, 23000,28264, 23016,24168, 23032,32360, + 23064,24936, 23096,29032, 23128,26984, 23160,31080, 23192,25960, 23224,30056, + 23256,28008, 23272,23912, 23288,32104, 23320,25448, 23352,29544, 23384,27496, + 23416,31592, 23448,26472, 23480,30568, 23512,28520, 23528,24424, 23544,32616, + 23576,24808, 23608,28904, 23640,26856, 23672,30952, 23704,25832, 23736,29928, + 23768,27880, 23800,31976, 23832,25320, 23864,29416, 23896,27368, 23928,31464, + 23960,26344, 23992,30440, 24024,28392, 24040,24296, 24056,32488, 24088,25064, + 24120,29160, 24152,27112, 24184,31208, 24216,26088, 24248,30184, 24280,28136, + 24312,32232, 24344,25576, 24376,29672, 24408,27624, 24440,31720, 24472,26600, + 24504,30696, 24536,28648, 24568,32744, 24632,28696, 24664,26648, 24696,30744, + 24728,25624, 24760,29720, 24792,27672, 24824,31768, 24856,25112, 24888,29208, + 24920,27160, 24952,31256, 24984,26136, 25016,30232, 25048,28184, 25080,32280, + 25144,28952, 25176,26904, 25208,31000, 25240,25880, 25272,29976, 25304,27928, + 25336,32024, 25400,29464, 25432,27416, 25464,31512, 25496,26392, 25528,30488, + 25560,28440, 25592,32536, 25656,28824, 25688,26776, 25720,30872, 25784,29848, + 25816,27800, 25848,31896, 25912,29336, 25944,27288, 25976,31384, 26008,26264, + 26040,30360, 26072,28312, 26104,32408, 26168,29080, 26200,27032, 26232,31128, + 26296,30104, 26328,28056, 26360,32152, 26424,29592, 26456,27544, 26488,31640, + 26552,30616, 26584,28568, 26616,32664, 26680,28760, 26744,30808, 26808,29784, + 26840,27736, 26872,31832, 26936,29272, 26968,27224, 27000,31320, 27064,30296, + 27096,28248, 27128,32344, 27192,29016, 27256,31064, 27320,30040, 27352,27992, + 27384,32088, 27448,29528, 27512,31576, 27576,30552, 27608,28504, 27640,32600, + 27704,28888, 27768,30936, 27832,29912, 27896,31960, 27960,29400, 28024,31448, + 28088,30424, 28120,28376, 28152,32472, 28216,29144, 28280,31192, 28344,30168, + 28408,32216, 28472,29656, 28536,31704, 28600,30680, 28664,32728, 28792,30776, + 28856,29752, 28920,31800, 28984,29240, 29048,31288, 29112,30264, 29176,32312, + 29304,31032, 29368,30008, 29432,32056, 29560,31544, 29624,30520, 29688,32568, + 29816,30904, 29944,31928, 30072,31416, 30136,30392, 30200,32440, 30328,31160, + 30456,32184, 30584,31672, 30712,32696, 30968,31864, 31096,31352, 31224,32376, + 31480,32120, 31736,32632, 32248,32504 +}; + +/** + @par + Example code for Floating-point RFFT Twiddle factors Generation: + @par +
TW = exp(2*pi*i*[0:L/2-1]/L - pi/2*i).' 
+ @par + Real and Imag values are in interleaved fashion +*/ +const float32_t twiddleCoef_rfft_32[32] = { + 0.000000000f, 1.000000000f, + 0.195090322f, 0.980785280f, + 0.382683432f, 0.923879533f, + 0.555570233f, 0.831469612f, + 0.707106781f, 0.707106781f, + 0.831469612f, 0.555570233f, + 0.923879533f, 0.382683432f, + 0.980785280f, 0.195090322f, + 1.000000000f, 0.000000000f, + 0.980785280f, -0.195090322f, + 0.923879533f, -0.382683432f, + 0.831469612f, -0.555570233f, + 0.707106781f, -0.707106781f, + 0.555570233f, -0.831469612f, + 0.382683432f, -0.923879533f, + 0.195090322f, -0.980785280f +}; + +const float32_t twiddleCoef_rfft_64[64] = { + 0.000000000000000f, 1.000000000000000f, + 0.098017140329561f, 0.995184726672197f, + 0.195090322016128f, 0.980785280403230f, + 0.290284677254462f, 0.956940335732209f, + 0.382683432365090f, 0.923879532511287f, + 0.471396736825998f, 0.881921264348355f, + 0.555570233019602f, 0.831469612302545f, + 0.634393284163645f, 0.773010453362737f, + 0.707106781186547f, 0.707106781186548f, + 0.773010453362737f, 0.634393284163645f, + 0.831469612302545f, 0.555570233019602f, + 0.881921264348355f, 0.471396736825998f, + 0.923879532511287f, 0.382683432365090f, + 0.956940335732209f, 0.290284677254462f, + 0.980785280403230f, 0.195090322016128f, + 0.995184726672197f, 0.098017140329561f, + 1.000000000000000f, 0.000000000000000f, + 0.995184726672197f, -0.098017140329561f, + 0.980785280403230f, -0.195090322016128f, + 0.956940335732209f, -0.290284677254462f, + 0.923879532511287f, -0.382683432365090f, + 0.881921264348355f, -0.471396736825998f, + 0.831469612302545f, -0.555570233019602f, + 0.773010453362737f, -0.634393284163645f, + 0.707106781186548f, -0.707106781186547f, + 0.634393284163645f, -0.773010453362737f, + 0.555570233019602f, -0.831469612302545f, + 0.471396736825998f, -0.881921264348355f, + 0.382683432365090f, -0.923879532511287f, + 0.290284677254462f, -0.956940335732209f, + 0.195090322016129f, -0.980785280403230f, + 0.098017140329561f, -0.995184726672197f +}; + +const float32_t twiddleCoef_rfft_128[128] = { + 0.000000000f, 1.000000000f, + 0.049067674f, 0.998795456f, + 0.098017140f, 0.995184727f, + 0.146730474f, 0.989176510f, + 0.195090322f, 0.980785280f, + 0.242980180f, 0.970031253f, + 0.290284677f, 0.956940336f, + 0.336889853f, 0.941544065f, + 0.382683432f, 0.923879533f, + 0.427555093f, 0.903989293f, + 0.471396737f, 0.881921264f, + 0.514102744f, 0.857728610f, + 0.555570233f, 0.831469612f, + 0.595699304f, 0.803207531f, + 0.634393284f, 0.773010453f, + 0.671558955f, 0.740951125f, + 0.707106781f, 0.707106781f, + 0.740951125f, 0.671558955f, + 0.773010453f, 0.634393284f, + 0.803207531f, 0.595699304f, + 0.831469612f, 0.555570233f, + 0.857728610f, 0.514102744f, + 0.881921264f, 0.471396737f, + 0.903989293f, 0.427555093f, + 0.923879533f, 0.382683432f, + 0.941544065f, 0.336889853f, + 0.956940336f, 0.290284677f, + 0.970031253f, 0.242980180f, + 0.980785280f, 0.195090322f, + 0.989176510f, 0.146730474f, + 0.995184727f, 0.098017140f, + 0.998795456f, 0.049067674f, + 1.000000000f, 0.000000000f, + 0.998795456f, -0.049067674f, + 0.995184727f, -0.098017140f, + 0.989176510f, -0.146730474f, + 0.980785280f, -0.195090322f, + 0.970031253f, -0.242980180f, + 0.956940336f, -0.290284677f, + 0.941544065f, -0.336889853f, + 0.923879533f, -0.382683432f, + 0.903989293f, -0.427555093f, + 0.881921264f, -0.471396737f, + 0.857728610f, -0.514102744f, + 0.831469612f, -0.555570233f, + 0.803207531f, -0.595699304f, + 0.773010453f, -0.634393284f, + 0.740951125f, -0.671558955f, + 0.707106781f, -0.707106781f, + 0.671558955f, -0.740951125f, + 0.634393284f, -0.773010453f, + 0.595699304f, -0.803207531f, + 0.555570233f, -0.831469612f, + 0.514102744f, -0.857728610f, + 0.471396737f, -0.881921264f, + 0.427555093f, -0.903989293f, + 0.382683432f, -0.923879533f, + 0.336889853f, -0.941544065f, + 0.290284677f, -0.956940336f, + 0.242980180f, -0.970031253f, + 0.195090322f, -0.980785280f, + 0.146730474f, -0.989176510f, + 0.098017140f, -0.995184727f, + 0.049067674f, -0.998795456f +}; + +const float32_t twiddleCoef_rfft_256[256] = { + 0.000000000f, 1.000000000f, + 0.024541229f, 0.999698819f, + 0.049067674f, 0.998795456f, + 0.073564564f, 0.997290457f, + 0.098017140f, 0.995184727f, + 0.122410675f, 0.992479535f, + 0.146730474f, 0.989176510f, + 0.170961889f, 0.985277642f, + 0.195090322f, 0.980785280f, + 0.219101240f, 0.975702130f, + 0.242980180f, 0.970031253f, + 0.266712757f, 0.963776066f, + 0.290284677f, 0.956940336f, + 0.313681740f, 0.949528181f, + 0.336889853f, 0.941544065f, + 0.359895037f, 0.932992799f, + 0.382683432f, 0.923879533f, + 0.405241314f, 0.914209756f, + 0.427555093f, 0.903989293f, + 0.449611330f, 0.893224301f, + 0.471396737f, 0.881921264f, + 0.492898192f, 0.870086991f, + 0.514102744f, 0.857728610f, + 0.534997620f, 0.844853565f, + 0.555570233f, 0.831469612f, + 0.575808191f, 0.817584813f, + 0.595699304f, 0.803207531f, + 0.615231591f, 0.788346428f, + 0.634393284f, 0.773010453f, + 0.653172843f, 0.757208847f, + 0.671558955f, 0.740951125f, + 0.689540545f, 0.724247083f, + 0.707106781f, 0.707106781f, + 0.724247083f, 0.689540545f, + 0.740951125f, 0.671558955f, + 0.757208847f, 0.653172843f, + 0.773010453f, 0.634393284f, + 0.788346428f, 0.615231591f, + 0.803207531f, 0.595699304f, + 0.817584813f, 0.575808191f, + 0.831469612f, 0.555570233f, + 0.844853565f, 0.534997620f, + 0.857728610f, 0.514102744f, + 0.870086991f, 0.492898192f, + 0.881921264f, 0.471396737f, + 0.893224301f, 0.449611330f, + 0.903989293f, 0.427555093f, + 0.914209756f, 0.405241314f, + 0.923879533f, 0.382683432f, + 0.932992799f, 0.359895037f, + 0.941544065f, 0.336889853f, + 0.949528181f, 0.313681740f, + 0.956940336f, 0.290284677f, + 0.963776066f, 0.266712757f, + 0.970031253f, 0.242980180f, + 0.975702130f, 0.219101240f, + 0.980785280f, 0.195090322f, + 0.985277642f, 0.170961889f, + 0.989176510f, 0.146730474f, + 0.992479535f, 0.122410675f, + 0.995184727f, 0.098017140f, + 0.997290457f, 0.073564564f, + 0.998795456f, 0.049067674f, + 0.999698819f, 0.024541229f, + 1.000000000f, 0.000000000f, + 0.999698819f, -0.024541229f, + 0.998795456f, -0.049067674f, + 0.997290457f, -0.073564564f, + 0.995184727f, -0.098017140f, + 0.992479535f, -0.122410675f, + 0.989176510f, -0.146730474f, + 0.985277642f, -0.170961889f, + 0.980785280f, -0.195090322f, + 0.975702130f, -0.219101240f, + 0.970031253f, -0.242980180f, + 0.963776066f, -0.266712757f, + 0.956940336f, -0.290284677f, + 0.949528181f, -0.313681740f, + 0.941544065f, -0.336889853f, + 0.932992799f, -0.359895037f, + 0.923879533f, -0.382683432f, + 0.914209756f, -0.405241314f, + 0.903989293f, -0.427555093f, + 0.893224301f, -0.449611330f, + 0.881921264f, -0.471396737f, + 0.870086991f, -0.492898192f, + 0.857728610f, -0.514102744f, + 0.844853565f, -0.534997620f, + 0.831469612f, -0.555570233f, + 0.817584813f, -0.575808191f, + 0.803207531f, -0.595699304f, + 0.788346428f, -0.615231591f, + 0.773010453f, -0.634393284f, + 0.757208847f, -0.653172843f, + 0.740951125f, -0.671558955f, + 0.724247083f, -0.689540545f, + 0.707106781f, -0.707106781f, + 0.689540545f, -0.724247083f, + 0.671558955f, -0.740951125f, + 0.653172843f, -0.757208847f, + 0.634393284f, -0.773010453f, + 0.615231591f, -0.788346428f, + 0.595699304f, -0.803207531f, + 0.575808191f, -0.817584813f, + 0.555570233f, -0.831469612f, + 0.534997620f, -0.844853565f, + 0.514102744f, -0.857728610f, + 0.492898192f, -0.870086991f, + 0.471396737f, -0.881921264f, + 0.449611330f, -0.893224301f, + 0.427555093f, -0.903989293f, + 0.405241314f, -0.914209756f, + 0.382683432f, -0.923879533f, + 0.359895037f, -0.932992799f, + 0.336889853f, -0.941544065f, + 0.313681740f, -0.949528181f, + 0.290284677f, -0.956940336f, + 0.266712757f, -0.963776066f, + 0.242980180f, -0.970031253f, + 0.219101240f, -0.975702130f, + 0.195090322f, -0.980785280f, + 0.170961889f, -0.985277642f, + 0.146730474f, -0.989176510f, + 0.122410675f, -0.992479535f, + 0.098017140f, -0.995184727f, + 0.073564564f, -0.997290457f, + 0.049067674f, -0.998795456f, + 0.024541229f, -0.999698819f +}; + +const float32_t twiddleCoef_rfft_512[512] = { + 0.000000000f, 1.000000000f, + 0.012271538f, 0.999924702f, + 0.024541229f, 0.999698819f, + 0.036807223f, 0.999322385f, + 0.049067674f, 0.998795456f, + 0.061320736f, 0.998118113f, + 0.073564564f, 0.997290457f, + 0.085797312f, 0.996312612f, + 0.098017140f, 0.995184727f, + 0.110222207f, 0.993906970f, + 0.122410675f, 0.992479535f, + 0.134580709f, 0.990902635f, + 0.146730474f, 0.989176510f, + 0.158858143f, 0.987301418f, + 0.170961889f, 0.985277642f, + 0.183039888f, 0.983105487f, + 0.195090322f, 0.980785280f, + 0.207111376f, 0.978317371f, + 0.219101240f, 0.975702130f, + 0.231058108f, 0.972939952f, + 0.242980180f, 0.970031253f, + 0.254865660f, 0.966976471f, + 0.266712757f, 0.963776066f, + 0.278519689f, 0.960430519f, + 0.290284677f, 0.956940336f, + 0.302005949f, 0.953306040f, + 0.313681740f, 0.949528181f, + 0.325310292f, 0.945607325f, + 0.336889853f, 0.941544065f, + 0.348418680f, 0.937339012f, + 0.359895037f, 0.932992799f, + 0.371317194f, 0.928506080f, + 0.382683432f, 0.923879533f, + 0.393992040f, 0.919113852f, + 0.405241314f, 0.914209756f, + 0.416429560f, 0.909167983f, + 0.427555093f, 0.903989293f, + 0.438616239f, 0.898674466f, + 0.449611330f, 0.893224301f, + 0.460538711f, 0.887639620f, + 0.471396737f, 0.881921264f, + 0.482183772f, 0.876070094f, + 0.492898192f, 0.870086991f, + 0.503538384f, 0.863972856f, + 0.514102744f, 0.857728610f, + 0.524589683f, 0.851355193f, + 0.534997620f, 0.844853565f, + 0.545324988f, 0.838224706f, + 0.555570233f, 0.831469612f, + 0.565731811f, 0.824589303f, + 0.575808191f, 0.817584813f, + 0.585797857f, 0.810457198f, + 0.595699304f, 0.803207531f, + 0.605511041f, 0.795836905f, + 0.615231591f, 0.788346428f, + 0.624859488f, 0.780737229f, + 0.634393284f, 0.773010453f, + 0.643831543f, 0.765167266f, + 0.653172843f, 0.757208847f, + 0.662415778f, 0.749136395f, + 0.671558955f, 0.740951125f, + 0.680600998f, 0.732654272f, + 0.689540545f, 0.724247083f, + 0.698376249f, 0.715730825f, + 0.707106781f, 0.707106781f, + 0.715730825f, 0.698376249f, + 0.724247083f, 0.689540545f, + 0.732654272f, 0.680600998f, + 0.740951125f, 0.671558955f, + 0.749136395f, 0.662415778f, + 0.757208847f, 0.653172843f, + 0.765167266f, 0.643831543f, + 0.773010453f, 0.634393284f, + 0.780737229f, 0.624859488f, + 0.788346428f, 0.615231591f, + 0.795836905f, 0.605511041f, + 0.803207531f, 0.595699304f, + 0.810457198f, 0.585797857f, + 0.817584813f, 0.575808191f, + 0.824589303f, 0.565731811f, + 0.831469612f, 0.555570233f, + 0.838224706f, 0.545324988f, + 0.844853565f, 0.534997620f, + 0.851355193f, 0.524589683f, + 0.857728610f, 0.514102744f, + 0.863972856f, 0.503538384f, + 0.870086991f, 0.492898192f, + 0.876070094f, 0.482183772f, + 0.881921264f, 0.471396737f, + 0.887639620f, 0.460538711f, + 0.893224301f, 0.449611330f, + 0.898674466f, 0.438616239f, + 0.903989293f, 0.427555093f, + 0.909167983f, 0.416429560f, + 0.914209756f, 0.405241314f, + 0.919113852f, 0.393992040f, + 0.923879533f, 0.382683432f, + 0.928506080f, 0.371317194f, + 0.932992799f, 0.359895037f, + 0.937339012f, 0.348418680f, + 0.941544065f, 0.336889853f, + 0.945607325f, 0.325310292f, + 0.949528181f, 0.313681740f, + 0.953306040f, 0.302005949f, + 0.956940336f, 0.290284677f, + 0.960430519f, 0.278519689f, + 0.963776066f, 0.266712757f, + 0.966976471f, 0.254865660f, + 0.970031253f, 0.242980180f, + 0.972939952f, 0.231058108f, + 0.975702130f, 0.219101240f, + 0.978317371f, 0.207111376f, + 0.980785280f, 0.195090322f, + 0.983105487f, 0.183039888f, + 0.985277642f, 0.170961889f, + 0.987301418f, 0.158858143f, + 0.989176510f, 0.146730474f, + 0.990902635f, 0.134580709f, + 0.992479535f, 0.122410675f, + 0.993906970f, 0.110222207f, + 0.995184727f, 0.098017140f, + 0.996312612f, 0.085797312f, + 0.997290457f, 0.073564564f, + 0.998118113f, 0.061320736f, + 0.998795456f, 0.049067674f, + 0.999322385f, 0.036807223f, + 0.999698819f, 0.024541229f, + 0.999924702f, 0.012271538f, + 1.000000000f, 0.000000000f, + 0.999924702f, -0.012271538f, + 0.999698819f, -0.024541229f, + 0.999322385f, -0.036807223f, + 0.998795456f, -0.049067674f, + 0.998118113f, -0.061320736f, + 0.997290457f, -0.073564564f, + 0.996312612f, -0.085797312f, + 0.995184727f, -0.098017140f, + 0.993906970f, -0.110222207f, + 0.992479535f, -0.122410675f, + 0.990902635f, -0.134580709f, + 0.989176510f, -0.146730474f, + 0.987301418f, -0.158858143f, + 0.985277642f, -0.170961889f, + 0.983105487f, -0.183039888f, + 0.980785280f, -0.195090322f, + 0.978317371f, -0.207111376f, + 0.975702130f, -0.219101240f, + 0.972939952f, -0.231058108f, + 0.970031253f, -0.242980180f, + 0.966976471f, -0.254865660f, + 0.963776066f, -0.266712757f, + 0.960430519f, -0.278519689f, + 0.956940336f, -0.290284677f, + 0.953306040f, -0.302005949f, + 0.949528181f, -0.313681740f, + 0.945607325f, -0.325310292f, + 0.941544065f, -0.336889853f, + 0.937339012f, -0.348418680f, + 0.932992799f, -0.359895037f, + 0.928506080f, -0.371317194f, + 0.923879533f, -0.382683432f, + 0.919113852f, -0.393992040f, + 0.914209756f, -0.405241314f, + 0.909167983f, -0.416429560f, + 0.903989293f, -0.427555093f, + 0.898674466f, -0.438616239f, + 0.893224301f, -0.449611330f, + 0.887639620f, -0.460538711f, + 0.881921264f, -0.471396737f, + 0.876070094f, -0.482183772f, + 0.870086991f, -0.492898192f, + 0.863972856f, -0.503538384f, + 0.857728610f, -0.514102744f, + 0.851355193f, -0.524589683f, + 0.844853565f, -0.534997620f, + 0.838224706f, -0.545324988f, + 0.831469612f, -0.555570233f, + 0.824589303f, -0.565731811f, + 0.817584813f, -0.575808191f, + 0.810457198f, -0.585797857f, + 0.803207531f, -0.595699304f, + 0.795836905f, -0.605511041f, + 0.788346428f, -0.615231591f, + 0.780737229f, -0.624859488f, + 0.773010453f, -0.634393284f, + 0.765167266f, -0.643831543f, + 0.757208847f, -0.653172843f, + 0.749136395f, -0.662415778f, + 0.740951125f, -0.671558955f, + 0.732654272f, -0.680600998f, + 0.724247083f, -0.689540545f, + 0.715730825f, -0.698376249f, + 0.707106781f, -0.707106781f, + 0.698376249f, -0.715730825f, + 0.689540545f, -0.724247083f, + 0.680600998f, -0.732654272f, + 0.671558955f, -0.740951125f, + 0.662415778f, -0.749136395f, + 0.653172843f, -0.757208847f, + 0.643831543f, -0.765167266f, + 0.634393284f, -0.773010453f, + 0.624859488f, -0.780737229f, + 0.615231591f, -0.788346428f, + 0.605511041f, -0.795836905f, + 0.595699304f, -0.803207531f, + 0.585797857f, -0.810457198f, + 0.575808191f, -0.817584813f, + 0.565731811f, -0.824589303f, + 0.555570233f, -0.831469612f, + 0.545324988f, -0.838224706f, + 0.534997620f, -0.844853565f, + 0.524589683f, -0.851355193f, + 0.514102744f, -0.857728610f, + 0.503538384f, -0.863972856f, + 0.492898192f, -0.870086991f, + 0.482183772f, -0.876070094f, + 0.471396737f, -0.881921264f, + 0.460538711f, -0.887639620f, + 0.449611330f, -0.893224301f, + 0.438616239f, -0.898674466f, + 0.427555093f, -0.903989293f, + 0.416429560f, -0.909167983f, + 0.405241314f, -0.914209756f, + 0.393992040f, -0.919113852f, + 0.382683432f, -0.923879533f, + 0.371317194f, -0.928506080f, + 0.359895037f, -0.932992799f, + 0.348418680f, -0.937339012f, + 0.336889853f, -0.941544065f, + 0.325310292f, -0.945607325f, + 0.313681740f, -0.949528181f, + 0.302005949f, -0.953306040f, + 0.290284677f, -0.956940336f, + 0.278519689f, -0.960430519f, + 0.266712757f, -0.963776066f, + 0.254865660f, -0.966976471f, + 0.242980180f, -0.970031253f, + 0.231058108f, -0.972939952f, + 0.219101240f, -0.975702130f, + 0.207111376f, -0.978317371f, + 0.195090322f, -0.980785280f, + 0.183039888f, -0.983105487f, + 0.170961889f, -0.985277642f, + 0.158858143f, -0.987301418f, + 0.146730474f, -0.989176510f, + 0.134580709f, -0.990902635f, + 0.122410675f, -0.992479535f, + 0.110222207f, -0.993906970f, + 0.098017140f, -0.995184727f, + 0.085797312f, -0.996312612f, + 0.073564564f, -0.997290457f, + 0.061320736f, -0.998118113f, + 0.049067674f, -0.998795456f, + 0.036807223f, -0.999322385f, + 0.024541229f, -0.999698819f, + 0.012271538f, -0.999924702f +}; + +const float32_t twiddleCoef_rfft_1024[1024] = { + 0.000000000f, 1.000000000f, + 0.006135885f, 0.999981175f, + 0.012271538f, 0.999924702f, + 0.018406730f, 0.999830582f, + 0.024541229f, 0.999698819f, + 0.030674803f, 0.999529418f, + 0.036807223f, 0.999322385f, + 0.042938257f, 0.999077728f, + 0.049067674f, 0.998795456f, + 0.055195244f, 0.998475581f, + 0.061320736f, 0.998118113f, + 0.067443920f, 0.997723067f, + 0.073564564f, 0.997290457f, + 0.079682438f, 0.996820299f, + 0.085797312f, 0.996312612f, + 0.091908956f, 0.995767414f, + 0.098017140f, 0.995184727f, + 0.104121634f, 0.994564571f, + 0.110222207f, 0.993906970f, + 0.116318631f, 0.993211949f, + 0.122410675f, 0.992479535f, + 0.128498111f, 0.991709754f, + 0.134580709f, 0.990902635f, + 0.140658239f, 0.990058210f, + 0.146730474f, 0.989176510f, + 0.152797185f, 0.988257568f, + 0.158858143f, 0.987301418f, + 0.164913120f, 0.986308097f, + 0.170961889f, 0.985277642f, + 0.177004220f, 0.984210092f, + 0.183039888f, 0.983105487f, + 0.189068664f, 0.981963869f, + 0.195090322f, 0.980785280f, + 0.201104635f, 0.979569766f, + 0.207111376f, 0.978317371f, + 0.213110320f, 0.977028143f, + 0.219101240f, 0.975702130f, + 0.225083911f, 0.974339383f, + 0.231058108f, 0.972939952f, + 0.237023606f, 0.971503891f, + 0.242980180f, 0.970031253f, + 0.248927606f, 0.968522094f, + 0.254865660f, 0.966976471f, + 0.260794118f, 0.965394442f, + 0.266712757f, 0.963776066f, + 0.272621355f, 0.962121404f, + 0.278519689f, 0.960430519f, + 0.284407537f, 0.958703475f, + 0.290284677f, 0.956940336f, + 0.296150888f, 0.955141168f, + 0.302005949f, 0.953306040f, + 0.307849640f, 0.951435021f, + 0.313681740f, 0.949528181f, + 0.319502031f, 0.947585591f, + 0.325310292f, 0.945607325f, + 0.331106306f, 0.943593458f, + 0.336889853f, 0.941544065f, + 0.342660717f, 0.939459224f, + 0.348418680f, 0.937339012f, + 0.354163525f, 0.935183510f, + 0.359895037f, 0.932992799f, + 0.365612998f, 0.930766961f, + 0.371317194f, 0.928506080f, + 0.377007410f, 0.926210242f, + 0.382683432f, 0.923879533f, + 0.388345047f, 0.921514039f, + 0.393992040f, 0.919113852f, + 0.399624200f, 0.916679060f, + 0.405241314f, 0.914209756f, + 0.410843171f, 0.911706032f, + 0.416429560f, 0.909167983f, + 0.422000271f, 0.906595705f, + 0.427555093f, 0.903989293f, + 0.433093819f, 0.901348847f, + 0.438616239f, 0.898674466f, + 0.444122145f, 0.895966250f, + 0.449611330f, 0.893224301f, + 0.455083587f, 0.890448723f, + 0.460538711f, 0.887639620f, + 0.465976496f, 0.884797098f, + 0.471396737f, 0.881921264f, + 0.476799230f, 0.879012226f, + 0.482183772f, 0.876070094f, + 0.487550160f, 0.873094978f, + 0.492898192f, 0.870086991f, + 0.498227667f, 0.867046246f, + 0.503538384f, 0.863972856f, + 0.508830143f, 0.860866939f, + 0.514102744f, 0.857728610f, + 0.519355990f, 0.854557988f, + 0.524589683f, 0.851355193f, + 0.529803625f, 0.848120345f, + 0.534997620f, 0.844853565f, + 0.540171473f, 0.841554977f, + 0.545324988f, 0.838224706f, + 0.550457973f, 0.834862875f, + 0.555570233f, 0.831469612f, + 0.560661576f, 0.828045045f, + 0.565731811f, 0.824589303f, + 0.570780746f, 0.821102515f, + 0.575808191f, 0.817584813f, + 0.580813958f, 0.814036330f, + 0.585797857f, 0.810457198f, + 0.590759702f, 0.806847554f, + 0.595699304f, 0.803207531f, + 0.600616479f, 0.799537269f, + 0.605511041f, 0.795836905f, + 0.610382806f, 0.792106577f, + 0.615231591f, 0.788346428f, + 0.620057212f, 0.784556597f, + 0.624859488f, 0.780737229f, + 0.629638239f, 0.776888466f, + 0.634393284f, 0.773010453f, + 0.639124445f, 0.769103338f, + 0.643831543f, 0.765167266f, + 0.648514401f, 0.761202385f, + 0.653172843f, 0.757208847f, + 0.657806693f, 0.753186799f, + 0.662415778f, 0.749136395f, + 0.666999922f, 0.745057785f, + 0.671558955f, 0.740951125f, + 0.676092704f, 0.736816569f, + 0.680600998f, 0.732654272f, + 0.685083668f, 0.728464390f, + 0.689540545f, 0.724247083f, + 0.693971461f, 0.720002508f, + 0.698376249f, 0.715730825f, + 0.702754744f, 0.711432196f, + 0.707106781f, 0.707106781f, + 0.711432196f, 0.702754744f, + 0.715730825f, 0.698376249f, + 0.720002508f, 0.693971461f, + 0.724247083f, 0.689540545f, + 0.728464390f, 0.685083668f, + 0.732654272f, 0.680600998f, + 0.736816569f, 0.676092704f, + 0.740951125f, 0.671558955f, + 0.745057785f, 0.666999922f, + 0.749136395f, 0.662415778f, + 0.753186799f, 0.657806693f, + 0.757208847f, 0.653172843f, + 0.761202385f, 0.648514401f, + 0.765167266f, 0.643831543f, + 0.769103338f, 0.639124445f, + 0.773010453f, 0.634393284f, + 0.776888466f, 0.629638239f, + 0.780737229f, 0.624859488f, + 0.784556597f, 0.620057212f, + 0.788346428f, 0.615231591f, + 0.792106577f, 0.610382806f, + 0.795836905f, 0.605511041f, + 0.799537269f, 0.600616479f, + 0.803207531f, 0.595699304f, + 0.806847554f, 0.590759702f, + 0.810457198f, 0.585797857f, + 0.814036330f, 0.580813958f, + 0.817584813f, 0.575808191f, + 0.821102515f, 0.570780746f, + 0.824589303f, 0.565731811f, + 0.828045045f, 0.560661576f, + 0.831469612f, 0.555570233f, + 0.834862875f, 0.550457973f, + 0.838224706f, 0.545324988f, + 0.841554977f, 0.540171473f, + 0.844853565f, 0.534997620f, + 0.848120345f, 0.529803625f, + 0.851355193f, 0.524589683f, + 0.854557988f, 0.519355990f, + 0.857728610f, 0.514102744f, + 0.860866939f, 0.508830143f, + 0.863972856f, 0.503538384f, + 0.867046246f, 0.498227667f, + 0.870086991f, 0.492898192f, + 0.873094978f, 0.487550160f, + 0.876070094f, 0.482183772f, + 0.879012226f, 0.476799230f, + 0.881921264f, 0.471396737f, + 0.884797098f, 0.465976496f, + 0.887639620f, 0.460538711f, + 0.890448723f, 0.455083587f, + 0.893224301f, 0.449611330f, + 0.895966250f, 0.444122145f, + 0.898674466f, 0.438616239f, + 0.901348847f, 0.433093819f, + 0.903989293f, 0.427555093f, + 0.906595705f, 0.422000271f, + 0.909167983f, 0.416429560f, + 0.911706032f, 0.410843171f, + 0.914209756f, 0.405241314f, + 0.916679060f, 0.399624200f, + 0.919113852f, 0.393992040f, + 0.921514039f, 0.388345047f, + 0.923879533f, 0.382683432f, + 0.926210242f, 0.377007410f, + 0.928506080f, 0.371317194f, + 0.930766961f, 0.365612998f, + 0.932992799f, 0.359895037f, + 0.935183510f, 0.354163525f, + 0.937339012f, 0.348418680f, + 0.939459224f, 0.342660717f, + 0.941544065f, 0.336889853f, + 0.943593458f, 0.331106306f, + 0.945607325f, 0.325310292f, + 0.947585591f, 0.319502031f, + 0.949528181f, 0.313681740f, + 0.951435021f, 0.307849640f, + 0.953306040f, 0.302005949f, + 0.955141168f, 0.296150888f, + 0.956940336f, 0.290284677f, + 0.958703475f, 0.284407537f, + 0.960430519f, 0.278519689f, + 0.962121404f, 0.272621355f, + 0.963776066f, 0.266712757f, + 0.965394442f, 0.260794118f, + 0.966976471f, 0.254865660f, + 0.968522094f, 0.248927606f, + 0.970031253f, 0.242980180f, + 0.971503891f, 0.237023606f, + 0.972939952f, 0.231058108f, + 0.974339383f, 0.225083911f, + 0.975702130f, 0.219101240f, + 0.977028143f, 0.213110320f, + 0.978317371f, 0.207111376f, + 0.979569766f, 0.201104635f, + 0.980785280f, 0.195090322f, + 0.981963869f, 0.189068664f, + 0.983105487f, 0.183039888f, + 0.984210092f, 0.177004220f, + 0.985277642f, 0.170961889f, + 0.986308097f, 0.164913120f, + 0.987301418f, 0.158858143f, + 0.988257568f, 0.152797185f, + 0.989176510f, 0.146730474f, + 0.990058210f, 0.140658239f, + 0.990902635f, 0.134580709f, + 0.991709754f, 0.128498111f, + 0.992479535f, 0.122410675f, + 0.993211949f, 0.116318631f, + 0.993906970f, 0.110222207f, + 0.994564571f, 0.104121634f, + 0.995184727f, 0.098017140f, + 0.995767414f, 0.091908956f, + 0.996312612f, 0.085797312f, + 0.996820299f, 0.079682438f, + 0.997290457f, 0.073564564f, + 0.997723067f, 0.067443920f, + 0.998118113f, 0.061320736f, + 0.998475581f, 0.055195244f, + 0.998795456f, 0.049067674f, + 0.999077728f, 0.042938257f, + 0.999322385f, 0.036807223f, + 0.999529418f, 0.030674803f, + 0.999698819f, 0.024541229f, + 0.999830582f, 0.018406730f, + 0.999924702f, 0.012271538f, + 0.999981175f, 0.006135885f, + 1.000000000f, 0.000000000f, + 0.999981175f, -0.006135885f, + 0.999924702f, -0.012271538f, + 0.999830582f, -0.018406730f, + 0.999698819f, -0.024541229f, + 0.999529418f, -0.030674803f, + 0.999322385f, -0.036807223f, + 0.999077728f, -0.042938257f, + 0.998795456f, -0.049067674f, + 0.998475581f, -0.055195244f, + 0.998118113f, -0.061320736f, + 0.997723067f, -0.067443920f, + 0.997290457f, -0.073564564f, + 0.996820299f, -0.079682438f, + 0.996312612f, -0.085797312f, + 0.995767414f, -0.091908956f, + 0.995184727f, -0.098017140f, + 0.994564571f, -0.104121634f, + 0.993906970f, -0.110222207f, + 0.993211949f, -0.116318631f, + 0.992479535f, -0.122410675f, + 0.991709754f, -0.128498111f, + 0.990902635f, -0.134580709f, + 0.990058210f, -0.140658239f, + 0.989176510f, -0.146730474f, + 0.988257568f, -0.152797185f, + 0.987301418f, -0.158858143f, + 0.986308097f, -0.164913120f, + 0.985277642f, -0.170961889f, + 0.984210092f, -0.177004220f, + 0.983105487f, -0.183039888f, + 0.981963869f, -0.189068664f, + 0.980785280f, -0.195090322f, + 0.979569766f, -0.201104635f, + 0.978317371f, -0.207111376f, + 0.977028143f, -0.213110320f, + 0.975702130f, -0.219101240f, + 0.974339383f, -0.225083911f, + 0.972939952f, -0.231058108f, + 0.971503891f, -0.237023606f, + 0.970031253f, -0.242980180f, + 0.968522094f, -0.248927606f, + 0.966976471f, -0.254865660f, + 0.965394442f, -0.260794118f, + 0.963776066f, -0.266712757f, + 0.962121404f, -0.272621355f, + 0.960430519f, -0.278519689f, + 0.958703475f, -0.284407537f, + 0.956940336f, -0.290284677f, + 0.955141168f, -0.296150888f, + 0.953306040f, -0.302005949f, + 0.951435021f, -0.307849640f, + 0.949528181f, -0.313681740f, + 0.947585591f, -0.319502031f, + 0.945607325f, -0.325310292f, + 0.943593458f, -0.331106306f, + 0.941544065f, -0.336889853f, + 0.939459224f, -0.342660717f, + 0.937339012f, -0.348418680f, + 0.935183510f, -0.354163525f, + 0.932992799f, -0.359895037f, + 0.930766961f, -0.365612998f, + 0.928506080f, -0.371317194f, + 0.926210242f, -0.377007410f, + 0.923879533f, -0.382683432f, + 0.921514039f, -0.388345047f, + 0.919113852f, -0.393992040f, + 0.916679060f, -0.399624200f, + 0.914209756f, -0.405241314f, + 0.911706032f, -0.410843171f, + 0.909167983f, -0.416429560f, + 0.906595705f, -0.422000271f, + 0.903989293f, -0.427555093f, + 0.901348847f, -0.433093819f, + 0.898674466f, -0.438616239f, + 0.895966250f, -0.444122145f, + 0.893224301f, -0.449611330f, + 0.890448723f, -0.455083587f, + 0.887639620f, -0.460538711f, + 0.884797098f, -0.465976496f, + 0.881921264f, -0.471396737f, + 0.879012226f, -0.476799230f, + 0.876070094f, -0.482183772f, + 0.873094978f, -0.487550160f, + 0.870086991f, -0.492898192f, + 0.867046246f, -0.498227667f, + 0.863972856f, -0.503538384f, + 0.860866939f, -0.508830143f, + 0.857728610f, -0.514102744f, + 0.854557988f, -0.519355990f, + 0.851355193f, -0.524589683f, + 0.848120345f, -0.529803625f, + 0.844853565f, -0.534997620f, + 0.841554977f, -0.540171473f, + 0.838224706f, -0.545324988f, + 0.834862875f, -0.550457973f, + 0.831469612f, -0.555570233f, + 0.828045045f, -0.560661576f, + 0.824589303f, -0.565731811f, + 0.821102515f, -0.570780746f, + 0.817584813f, -0.575808191f, + 0.814036330f, -0.580813958f, + 0.810457198f, -0.585797857f, + 0.806847554f, -0.590759702f, + 0.803207531f, -0.595699304f, + 0.799537269f, -0.600616479f, + 0.795836905f, -0.605511041f, + 0.792106577f, -0.610382806f, + 0.788346428f, -0.615231591f, + 0.784556597f, -0.620057212f, + 0.780737229f, -0.624859488f, + 0.776888466f, -0.629638239f, + 0.773010453f, -0.634393284f, + 0.769103338f, -0.639124445f, + 0.765167266f, -0.643831543f, + 0.761202385f, -0.648514401f, + 0.757208847f, -0.653172843f, + 0.753186799f, -0.657806693f, + 0.749136395f, -0.662415778f, + 0.745057785f, -0.666999922f, + 0.740951125f, -0.671558955f, + 0.736816569f, -0.676092704f, + 0.732654272f, -0.680600998f, + 0.728464390f, -0.685083668f, + 0.724247083f, -0.689540545f, + 0.720002508f, -0.693971461f, + 0.715730825f, -0.698376249f, + 0.711432196f, -0.702754744f, + 0.707106781f, -0.707106781f, + 0.702754744f, -0.711432196f, + 0.698376249f, -0.715730825f, + 0.693971461f, -0.720002508f, + 0.689540545f, -0.724247083f, + 0.685083668f, -0.728464390f, + 0.680600998f, -0.732654272f, + 0.676092704f, -0.736816569f, + 0.671558955f, -0.740951125f, + 0.666999922f, -0.745057785f, + 0.662415778f, -0.749136395f, + 0.657806693f, -0.753186799f, + 0.653172843f, -0.757208847f, + 0.648514401f, -0.761202385f, + 0.643831543f, -0.765167266f, + 0.639124445f, -0.769103338f, + 0.634393284f, -0.773010453f, + 0.629638239f, -0.776888466f, + 0.624859488f, -0.780737229f, + 0.620057212f, -0.784556597f, + 0.615231591f, -0.788346428f, + 0.610382806f, -0.792106577f, + 0.605511041f, -0.795836905f, + 0.600616479f, -0.799537269f, + 0.595699304f, -0.803207531f, + 0.590759702f, -0.806847554f, + 0.585797857f, -0.810457198f, + 0.580813958f, -0.814036330f, + 0.575808191f, -0.817584813f, + 0.570780746f, -0.821102515f, + 0.565731811f, -0.824589303f, + 0.560661576f, -0.828045045f, + 0.555570233f, -0.831469612f, + 0.550457973f, -0.834862875f, + 0.545324988f, -0.838224706f, + 0.540171473f, -0.841554977f, + 0.534997620f, -0.844853565f, + 0.529803625f, -0.848120345f, + 0.524589683f, -0.851355193f, + 0.519355990f, -0.854557988f, + 0.514102744f, -0.857728610f, + 0.508830143f, -0.860866939f, + 0.503538384f, -0.863972856f, + 0.498227667f, -0.867046246f, + 0.492898192f, -0.870086991f, + 0.487550160f, -0.873094978f, + 0.482183772f, -0.876070094f, + 0.476799230f, -0.879012226f, + 0.471396737f, -0.881921264f, + 0.465976496f, -0.884797098f, + 0.460538711f, -0.887639620f, + 0.455083587f, -0.890448723f, + 0.449611330f, -0.893224301f, + 0.444122145f, -0.895966250f, + 0.438616239f, -0.898674466f, + 0.433093819f, -0.901348847f, + 0.427555093f, -0.903989293f, + 0.422000271f, -0.906595705f, + 0.416429560f, -0.909167983f, + 0.410843171f, -0.911706032f, + 0.405241314f, -0.914209756f, + 0.399624200f, -0.916679060f, + 0.393992040f, -0.919113852f, + 0.388345047f, -0.921514039f, + 0.382683432f, -0.923879533f, + 0.377007410f, -0.926210242f, + 0.371317194f, -0.928506080f, + 0.365612998f, -0.930766961f, + 0.359895037f, -0.932992799f, + 0.354163525f, -0.935183510f, + 0.348418680f, -0.937339012f, + 0.342660717f, -0.939459224f, + 0.336889853f, -0.941544065f, + 0.331106306f, -0.943593458f, + 0.325310292f, -0.945607325f, + 0.319502031f, -0.947585591f, + 0.313681740f, -0.949528181f, + 0.307849640f, -0.951435021f, + 0.302005949f, -0.953306040f, + 0.296150888f, -0.955141168f, + 0.290284677f, -0.956940336f, + 0.284407537f, -0.958703475f, + 0.278519689f, -0.960430519f, + 0.272621355f, -0.962121404f, + 0.266712757f, -0.963776066f, + 0.260794118f, -0.965394442f, + 0.254865660f, -0.966976471f, + 0.248927606f, -0.968522094f, + 0.242980180f, -0.970031253f, + 0.237023606f, -0.971503891f, + 0.231058108f, -0.972939952f, + 0.225083911f, -0.974339383f, + 0.219101240f, -0.975702130f, + 0.213110320f, -0.977028143f, + 0.207111376f, -0.978317371f, + 0.201104635f, -0.979569766f, + 0.195090322f, -0.980785280f, + 0.189068664f, -0.981963869f, + 0.183039888f, -0.983105487f, + 0.177004220f, -0.984210092f, + 0.170961889f, -0.985277642f, + 0.164913120f, -0.986308097f, + 0.158858143f, -0.987301418f, + 0.152797185f, -0.988257568f, + 0.146730474f, -0.989176510f, + 0.140658239f, -0.990058210f, + 0.134580709f, -0.990902635f, + 0.128498111f, -0.991709754f, + 0.122410675f, -0.992479535f, + 0.116318631f, -0.993211949f, + 0.110222207f, -0.993906970f, + 0.104121634f, -0.994564571f, + 0.098017140f, -0.995184727f, + 0.091908956f, -0.995767414f, + 0.085797312f, -0.996312612f, + 0.079682438f, -0.996820299f, + 0.073564564f, -0.997290457f, + 0.067443920f, -0.997723067f, + 0.061320736f, -0.998118113f, + 0.055195244f, -0.998475581f, + 0.049067674f, -0.998795456f, + 0.042938257f, -0.999077728f, + 0.036807223f, -0.999322385f, + 0.030674803f, -0.999529418f, + 0.024541229f, -0.999698819f, + 0.018406730f, -0.999830582f, + 0.012271538f, -0.999924702f, + 0.006135885f, -0.999981175f +}; + +const float32_t twiddleCoef_rfft_2048[2048] = { + 0.000000000f, 1.000000000f, + 0.003067957f, 0.999995294f, + 0.006135885f, 0.999981175f, + 0.009203755f, 0.999957645f, + 0.012271538f, 0.999924702f, + 0.015339206f, 0.999882347f, + 0.018406730f, 0.999830582f, + 0.021474080f, 0.999769405f, + 0.024541229f, 0.999698819f, + 0.027608146f, 0.999618822f, + 0.030674803f, 0.999529418f, + 0.033741172f, 0.999430605f, + 0.036807223f, 0.999322385f, + 0.039872928f, 0.999204759f, + 0.042938257f, 0.999077728f, + 0.046003182f, 0.998941293f, + 0.049067674f, 0.998795456f, + 0.052131705f, 0.998640218f, + 0.055195244f, 0.998475581f, + 0.058258265f, 0.998301545f, + 0.061320736f, 0.998118113f, + 0.064382631f, 0.997925286f, + 0.067443920f, 0.997723067f, + 0.070504573f, 0.997511456f, + 0.073564564f, 0.997290457f, + 0.076623861f, 0.997060070f, + 0.079682438f, 0.996820299f, + 0.082740265f, 0.996571146f, + 0.085797312f, 0.996312612f, + 0.088853553f, 0.996044701f, + 0.091908956f, 0.995767414f, + 0.094963495f, 0.995480755f, + 0.098017140f, 0.995184727f, + 0.101069863f, 0.994879331f, + 0.104121634f, 0.994564571f, + 0.107172425f, 0.994240449f, + 0.110222207f, 0.993906970f, + 0.113270952f, 0.993564136f, + 0.116318631f, 0.993211949f, + 0.119365215f, 0.992850414f, + 0.122410675f, 0.992479535f, + 0.125454983f, 0.992099313f, + 0.128498111f, 0.991709754f, + 0.131540029f, 0.991310860f, + 0.134580709f, 0.990902635f, + 0.137620122f, 0.990485084f, + 0.140658239f, 0.990058210f, + 0.143695033f, 0.989622017f, + 0.146730474f, 0.989176510f, + 0.149764535f, 0.988721692f, + 0.152797185f, 0.988257568f, + 0.155828398f, 0.987784142f, + 0.158858143f, 0.987301418f, + 0.161886394f, 0.986809402f, + 0.164913120f, 0.986308097f, + 0.167938295f, 0.985797509f, + 0.170961889f, 0.985277642f, + 0.173983873f, 0.984748502f, + 0.177004220f, 0.984210092f, + 0.180022901f, 0.983662419f, + 0.183039888f, 0.983105487f, + 0.186055152f, 0.982539302f, + 0.189068664f, 0.981963869f, + 0.192080397f, 0.981379193f, + 0.195090322f, 0.980785280f, + 0.198098411f, 0.980182136f, + 0.201104635f, 0.979569766f, + 0.204108966f, 0.978948175f, + 0.207111376f, 0.978317371f, + 0.210111837f, 0.977677358f, + 0.213110320f, 0.977028143f, + 0.216106797f, 0.976369731f, + 0.219101240f, 0.975702130f, + 0.222093621f, 0.975025345f, + 0.225083911f, 0.974339383f, + 0.228072083f, 0.973644250f, + 0.231058108f, 0.972939952f, + 0.234041959f, 0.972226497f, + 0.237023606f, 0.971503891f, + 0.240003022f, 0.970772141f, + 0.242980180f, 0.970031253f, + 0.245955050f, 0.969281235f, + 0.248927606f, 0.968522094f, + 0.251897818f, 0.967753837f, + 0.254865660f, 0.966976471f, + 0.257831102f, 0.966190003f, + 0.260794118f, 0.965394442f, + 0.263754679f, 0.964589793f, + 0.266712757f, 0.963776066f, + 0.269668326f, 0.962953267f, + 0.272621355f, 0.962121404f, + 0.275571819f, 0.961280486f, + 0.278519689f, 0.960430519f, + 0.281464938f, 0.959571513f, + 0.284407537f, 0.958703475f, + 0.287347460f, 0.957826413f, + 0.290284677f, 0.956940336f, + 0.293219163f, 0.956045251f, + 0.296150888f, 0.955141168f, + 0.299079826f, 0.954228095f, + 0.302005949f, 0.953306040f, + 0.304929230f, 0.952375013f, + 0.307849640f, 0.951435021f, + 0.310767153f, 0.950486074f, + 0.313681740f, 0.949528181f, + 0.316593376f, 0.948561350f, + 0.319502031f, 0.947585591f, + 0.322407679f, 0.946600913f, + 0.325310292f, 0.945607325f, + 0.328209844f, 0.944604837f, + 0.331106306f, 0.943593458f, + 0.333999651f, 0.942573198f, + 0.336889853f, 0.941544065f, + 0.339776884f, 0.940506071f, + 0.342660717f, 0.939459224f, + 0.345541325f, 0.938403534f, + 0.348418680f, 0.937339012f, + 0.351292756f, 0.936265667f, + 0.354163525f, 0.935183510f, + 0.357030961f, 0.934092550f, + 0.359895037f, 0.932992799f, + 0.362755724f, 0.931884266f, + 0.365612998f, 0.930766961f, + 0.368466830f, 0.929640896f, + 0.371317194f, 0.928506080f, + 0.374164063f, 0.927362526f, + 0.377007410f, 0.926210242f, + 0.379847209f, 0.925049241f, + 0.382683432f, 0.923879533f, + 0.385516054f, 0.922701128f, + 0.388345047f, 0.921514039f, + 0.391170384f, 0.920318277f, + 0.393992040f, 0.919113852f, + 0.396809987f, 0.917900776f, + 0.399624200f, 0.916679060f, + 0.402434651f, 0.915448716f, + 0.405241314f, 0.914209756f, + 0.408044163f, 0.912962190f, + 0.410843171f, 0.911706032f, + 0.413638312f, 0.910441292f, + 0.416429560f, 0.909167983f, + 0.419216888f, 0.907886116f, + 0.422000271f, 0.906595705f, + 0.424779681f, 0.905296759f, + 0.427555093f, 0.903989293f, + 0.430326481f, 0.902673318f, + 0.433093819f, 0.901348847f, + 0.435857080f, 0.900015892f, + 0.438616239f, 0.898674466f, + 0.441371269f, 0.897324581f, + 0.444122145f, 0.895966250f, + 0.446868840f, 0.894599486f, + 0.449611330f, 0.893224301f, + 0.452349587f, 0.891840709f, + 0.455083587f, 0.890448723f, + 0.457813304f, 0.889048356f, + 0.460538711f, 0.887639620f, + 0.463259784f, 0.886222530f, + 0.465976496f, 0.884797098f, + 0.468688822f, 0.883363339f, + 0.471396737f, 0.881921264f, + 0.474100215f, 0.880470889f, + 0.476799230f, 0.879012226f, + 0.479493758f, 0.877545290f, + 0.482183772f, 0.876070094f, + 0.484869248f, 0.874586652f, + 0.487550160f, 0.873094978f, + 0.490226483f, 0.871595087f, + 0.492898192f, 0.870086991f, + 0.495565262f, 0.868570706f, + 0.498227667f, 0.867046246f, + 0.500885383f, 0.865513624f, + 0.503538384f, 0.863972856f, + 0.506186645f, 0.862423956f, + 0.508830143f, 0.860866939f, + 0.511468850f, 0.859301818f, + 0.514102744f, 0.857728610f, + 0.516731799f, 0.856147328f, + 0.519355990f, 0.854557988f, + 0.521975293f, 0.852960605f, + 0.524589683f, 0.851355193f, + 0.527199135f, 0.849741768f, + 0.529803625f, 0.848120345f, + 0.532403128f, 0.846490939f, + 0.534997620f, 0.844853565f, + 0.537587076f, 0.843208240f, + 0.540171473f, 0.841554977f, + 0.542750785f, 0.839893794f, + 0.545324988f, 0.838224706f, + 0.547894059f, 0.836547727f, + 0.550457973f, 0.834862875f, + 0.553016706f, 0.833170165f, + 0.555570233f, 0.831469612f, + 0.558118531f, 0.829761234f, + 0.560661576f, 0.828045045f, + 0.563199344f, 0.826321063f, + 0.565731811f, 0.824589303f, + 0.568258953f, 0.822849781f, + 0.570780746f, 0.821102515f, + 0.573297167f, 0.819347520f, + 0.575808191f, 0.817584813f, + 0.578313796f, 0.815814411f, + 0.580813958f, 0.814036330f, + 0.583308653f, 0.812250587f, + 0.585797857f, 0.810457198f, + 0.588281548f, 0.808656182f, + 0.590759702f, 0.806847554f, + 0.593232295f, 0.805031331f, + 0.595699304f, 0.803207531f, + 0.598160707f, 0.801376172f, + 0.600616479f, 0.799537269f, + 0.603066599f, 0.797690841f, + 0.605511041f, 0.795836905f, + 0.607949785f, 0.793975478f, + 0.610382806f, 0.792106577f, + 0.612810082f, 0.790230221f, + 0.615231591f, 0.788346428f, + 0.617647308f, 0.786455214f, + 0.620057212f, 0.784556597f, + 0.622461279f, 0.782650596f, + 0.624859488f, 0.780737229f, + 0.627251815f, 0.778816512f, + 0.629638239f, 0.776888466f, + 0.632018736f, 0.774953107f, + 0.634393284f, 0.773010453f, + 0.636761861f, 0.771060524f, + 0.639124445f, 0.769103338f, + 0.641481013f, 0.767138912f, + 0.643831543f, 0.765167266f, + 0.646176013f, 0.763188417f, + 0.648514401f, 0.761202385f, + 0.650846685f, 0.759209189f, + 0.653172843f, 0.757208847f, + 0.655492853f, 0.755201377f, + 0.657806693f, 0.753186799f, + 0.660114342f, 0.751165132f, + 0.662415778f, 0.749136395f, + 0.664710978f, 0.747100606f, + 0.666999922f, 0.745057785f, + 0.669282588f, 0.743007952f, + 0.671558955f, 0.740951125f, + 0.673829000f, 0.738887324f, + 0.676092704f, 0.736816569f, + 0.678350043f, 0.734738878f, + 0.680600998f, 0.732654272f, + 0.682845546f, 0.730562769f, + 0.685083668f, 0.728464390f, + 0.687315341f, 0.726359155f, + 0.689540545f, 0.724247083f, + 0.691759258f, 0.722128194f, + 0.693971461f, 0.720002508f, + 0.696177131f, 0.717870045f, + 0.698376249f, 0.715730825f, + 0.700568794f, 0.713584869f, + 0.702754744f, 0.711432196f, + 0.704934080f, 0.709272826f, + 0.707106781f, 0.707106781f, + 0.709272826f, 0.704934080f, + 0.711432196f, 0.702754744f, + 0.713584869f, 0.700568794f, + 0.715730825f, 0.698376249f, + 0.717870045f, 0.696177131f, + 0.720002508f, 0.693971461f, + 0.722128194f, 0.691759258f, + 0.724247083f, 0.689540545f, + 0.726359155f, 0.687315341f, + 0.728464390f, 0.685083668f, + 0.730562769f, 0.682845546f, + 0.732654272f, 0.680600998f, + 0.734738878f, 0.678350043f, + 0.736816569f, 0.676092704f, + 0.738887324f, 0.673829000f, + 0.740951125f, 0.671558955f, + 0.743007952f, 0.669282588f, + 0.745057785f, 0.666999922f, + 0.747100606f, 0.664710978f, + 0.749136395f, 0.662415778f, + 0.751165132f, 0.660114342f, + 0.753186799f, 0.657806693f, + 0.755201377f, 0.655492853f, + 0.757208847f, 0.653172843f, + 0.759209189f, 0.650846685f, + 0.761202385f, 0.648514401f, + 0.763188417f, 0.646176013f, + 0.765167266f, 0.643831543f, + 0.767138912f, 0.641481013f, + 0.769103338f, 0.639124445f, + 0.771060524f, 0.636761861f, + 0.773010453f, 0.634393284f, + 0.774953107f, 0.632018736f, + 0.776888466f, 0.629638239f, + 0.778816512f, 0.627251815f, + 0.780737229f, 0.624859488f, + 0.782650596f, 0.622461279f, + 0.784556597f, 0.620057212f, + 0.786455214f, 0.617647308f, + 0.788346428f, 0.615231591f, + 0.790230221f, 0.612810082f, + 0.792106577f, 0.610382806f, + 0.793975478f, 0.607949785f, + 0.795836905f, 0.605511041f, + 0.797690841f, 0.603066599f, + 0.799537269f, 0.600616479f, + 0.801376172f, 0.598160707f, + 0.803207531f, 0.595699304f, + 0.805031331f, 0.593232295f, + 0.806847554f, 0.590759702f, + 0.808656182f, 0.588281548f, + 0.810457198f, 0.585797857f, + 0.812250587f, 0.583308653f, + 0.814036330f, 0.580813958f, + 0.815814411f, 0.578313796f, + 0.817584813f, 0.575808191f, + 0.819347520f, 0.573297167f, + 0.821102515f, 0.570780746f, + 0.822849781f, 0.568258953f, + 0.824589303f, 0.565731811f, + 0.826321063f, 0.563199344f, + 0.828045045f, 0.560661576f, + 0.829761234f, 0.558118531f, + 0.831469612f, 0.555570233f, + 0.833170165f, 0.553016706f, + 0.834862875f, 0.550457973f, + 0.836547727f, 0.547894059f, + 0.838224706f, 0.545324988f, + 0.839893794f, 0.542750785f, + 0.841554977f, 0.540171473f, + 0.843208240f, 0.537587076f, + 0.844853565f, 0.534997620f, + 0.846490939f, 0.532403128f, + 0.848120345f, 0.529803625f, + 0.849741768f, 0.527199135f, + 0.851355193f, 0.524589683f, + 0.852960605f, 0.521975293f, + 0.854557988f, 0.519355990f, + 0.856147328f, 0.516731799f, + 0.857728610f, 0.514102744f, + 0.859301818f, 0.511468850f, + 0.860866939f, 0.508830143f, + 0.862423956f, 0.506186645f, + 0.863972856f, 0.503538384f, + 0.865513624f, 0.500885383f, + 0.867046246f, 0.498227667f, + 0.868570706f, 0.495565262f, + 0.870086991f, 0.492898192f, + 0.871595087f, 0.490226483f, + 0.873094978f, 0.487550160f, + 0.874586652f, 0.484869248f, + 0.876070094f, 0.482183772f, + 0.877545290f, 0.479493758f, + 0.879012226f, 0.476799230f, + 0.880470889f, 0.474100215f, + 0.881921264f, 0.471396737f, + 0.883363339f, 0.468688822f, + 0.884797098f, 0.465976496f, + 0.886222530f, 0.463259784f, + 0.887639620f, 0.460538711f, + 0.889048356f, 0.457813304f, + 0.890448723f, 0.455083587f, + 0.891840709f, 0.452349587f, + 0.893224301f, 0.449611330f, + 0.894599486f, 0.446868840f, + 0.895966250f, 0.444122145f, + 0.897324581f, 0.441371269f, + 0.898674466f, 0.438616239f, + 0.900015892f, 0.435857080f, + 0.901348847f, 0.433093819f, + 0.902673318f, 0.430326481f, + 0.903989293f, 0.427555093f, + 0.905296759f, 0.424779681f, + 0.906595705f, 0.422000271f, + 0.907886116f, 0.419216888f, + 0.909167983f, 0.416429560f, + 0.910441292f, 0.413638312f, + 0.911706032f, 0.410843171f, + 0.912962190f, 0.408044163f, + 0.914209756f, 0.405241314f, + 0.915448716f, 0.402434651f, + 0.916679060f, 0.399624200f, + 0.917900776f, 0.396809987f, + 0.919113852f, 0.393992040f, + 0.920318277f, 0.391170384f, + 0.921514039f, 0.388345047f, + 0.922701128f, 0.385516054f, + 0.923879533f, 0.382683432f, + 0.925049241f, 0.379847209f, + 0.926210242f, 0.377007410f, + 0.927362526f, 0.374164063f, + 0.928506080f, 0.371317194f, + 0.929640896f, 0.368466830f, + 0.930766961f, 0.365612998f, + 0.931884266f, 0.362755724f, + 0.932992799f, 0.359895037f, + 0.934092550f, 0.357030961f, + 0.935183510f, 0.354163525f, + 0.936265667f, 0.351292756f, + 0.937339012f, 0.348418680f, + 0.938403534f, 0.345541325f, + 0.939459224f, 0.342660717f, + 0.940506071f, 0.339776884f, + 0.941544065f, 0.336889853f, + 0.942573198f, 0.333999651f, + 0.943593458f, 0.331106306f, + 0.944604837f, 0.328209844f, + 0.945607325f, 0.325310292f, + 0.946600913f, 0.322407679f, + 0.947585591f, 0.319502031f, + 0.948561350f, 0.316593376f, + 0.949528181f, 0.313681740f, + 0.950486074f, 0.310767153f, + 0.951435021f, 0.307849640f, + 0.952375013f, 0.304929230f, + 0.953306040f, 0.302005949f, + 0.954228095f, 0.299079826f, + 0.955141168f, 0.296150888f, + 0.956045251f, 0.293219163f, + 0.956940336f, 0.290284677f, + 0.957826413f, 0.287347460f, + 0.958703475f, 0.284407537f, + 0.959571513f, 0.281464938f, + 0.960430519f, 0.278519689f, + 0.961280486f, 0.275571819f, + 0.962121404f, 0.272621355f, + 0.962953267f, 0.269668326f, + 0.963776066f, 0.266712757f, + 0.964589793f, 0.263754679f, + 0.965394442f, 0.260794118f, + 0.966190003f, 0.257831102f, + 0.966976471f, 0.254865660f, + 0.967753837f, 0.251897818f, + 0.968522094f, 0.248927606f, + 0.969281235f, 0.245955050f, + 0.970031253f, 0.242980180f, + 0.970772141f, 0.240003022f, + 0.971503891f, 0.237023606f, + 0.972226497f, 0.234041959f, + 0.972939952f, 0.231058108f, + 0.973644250f, 0.228072083f, + 0.974339383f, 0.225083911f, + 0.975025345f, 0.222093621f, + 0.975702130f, 0.219101240f, + 0.976369731f, 0.216106797f, + 0.977028143f, 0.213110320f, + 0.977677358f, 0.210111837f, + 0.978317371f, 0.207111376f, + 0.978948175f, 0.204108966f, + 0.979569766f, 0.201104635f, + 0.980182136f, 0.198098411f, + 0.980785280f, 0.195090322f, + 0.981379193f, 0.192080397f, + 0.981963869f, 0.189068664f, + 0.982539302f, 0.186055152f, + 0.983105487f, 0.183039888f, + 0.983662419f, 0.180022901f, + 0.984210092f, 0.177004220f, + 0.984748502f, 0.173983873f, + 0.985277642f, 0.170961889f, + 0.985797509f, 0.167938295f, + 0.986308097f, 0.164913120f, + 0.986809402f, 0.161886394f, + 0.987301418f, 0.158858143f, + 0.987784142f, 0.155828398f, + 0.988257568f, 0.152797185f, + 0.988721692f, 0.149764535f, + 0.989176510f, 0.146730474f, + 0.989622017f, 0.143695033f, + 0.990058210f, 0.140658239f, + 0.990485084f, 0.137620122f, + 0.990902635f, 0.134580709f, + 0.991310860f, 0.131540029f, + 0.991709754f, 0.128498111f, + 0.992099313f, 0.125454983f, + 0.992479535f, 0.122410675f, + 0.992850414f, 0.119365215f, + 0.993211949f, 0.116318631f, + 0.993564136f, 0.113270952f, + 0.993906970f, 0.110222207f, + 0.994240449f, 0.107172425f, + 0.994564571f, 0.104121634f, + 0.994879331f, 0.101069863f, + 0.995184727f, 0.098017140f, + 0.995480755f, 0.094963495f, + 0.995767414f, 0.091908956f, + 0.996044701f, 0.088853553f, + 0.996312612f, 0.085797312f, + 0.996571146f, 0.082740265f, + 0.996820299f, 0.079682438f, + 0.997060070f, 0.076623861f, + 0.997290457f, 0.073564564f, + 0.997511456f, 0.070504573f, + 0.997723067f, 0.067443920f, + 0.997925286f, 0.064382631f, + 0.998118113f, 0.061320736f, + 0.998301545f, 0.058258265f, + 0.998475581f, 0.055195244f, + 0.998640218f, 0.052131705f, + 0.998795456f, 0.049067674f, + 0.998941293f, 0.046003182f, + 0.999077728f, 0.042938257f, + 0.999204759f, 0.039872928f, + 0.999322385f, 0.036807223f, + 0.999430605f, 0.033741172f, + 0.999529418f, 0.030674803f, + 0.999618822f, 0.027608146f, + 0.999698819f, 0.024541229f, + 0.999769405f, 0.021474080f, + 0.999830582f, 0.018406730f, + 0.999882347f, 0.015339206f, + 0.999924702f, 0.012271538f, + 0.999957645f, 0.009203755f, + 0.999981175f, 0.006135885f, + 0.999995294f, 0.003067957f, + 1.000000000f, 0.000000000f, + 0.999995294f, -0.003067957f, + 0.999981175f, -0.006135885f, + 0.999957645f, -0.009203755f, + 0.999924702f, -0.012271538f, + 0.999882347f, -0.015339206f, + 0.999830582f, -0.018406730f, + 0.999769405f, -0.021474080f, + 0.999698819f, -0.024541229f, + 0.999618822f, -0.027608146f, + 0.999529418f, -0.030674803f, + 0.999430605f, -0.033741172f, + 0.999322385f, -0.036807223f, + 0.999204759f, -0.039872928f, + 0.999077728f, -0.042938257f, + 0.998941293f, -0.046003182f, + 0.998795456f, -0.049067674f, + 0.998640218f, -0.052131705f, + 0.998475581f, -0.055195244f, + 0.998301545f, -0.058258265f, + 0.998118113f, -0.061320736f, + 0.997925286f, -0.064382631f, + 0.997723067f, -0.067443920f, + 0.997511456f, -0.070504573f, + 0.997290457f, -0.073564564f, + 0.997060070f, -0.076623861f, + 0.996820299f, -0.079682438f, + 0.996571146f, -0.082740265f, + 0.996312612f, -0.085797312f, + 0.996044701f, -0.088853553f, + 0.995767414f, -0.091908956f, + 0.995480755f, -0.094963495f, + 0.995184727f, -0.098017140f, + 0.994879331f, -0.101069863f, + 0.994564571f, -0.104121634f, + 0.994240449f, -0.107172425f, + 0.993906970f, -0.110222207f, + 0.993564136f, -0.113270952f, + 0.993211949f, -0.116318631f, + 0.992850414f, -0.119365215f, + 0.992479535f, -0.122410675f, + 0.992099313f, -0.125454983f, + 0.991709754f, -0.128498111f, + 0.991310860f, -0.131540029f, + 0.990902635f, -0.134580709f, + 0.990485084f, -0.137620122f, + 0.990058210f, -0.140658239f, + 0.989622017f, -0.143695033f, + 0.989176510f, -0.146730474f, + 0.988721692f, -0.149764535f, + 0.988257568f, -0.152797185f, + 0.987784142f, -0.155828398f, + 0.987301418f, -0.158858143f, + 0.986809402f, -0.161886394f, + 0.986308097f, -0.164913120f, + 0.985797509f, -0.167938295f, + 0.985277642f, -0.170961889f, + 0.984748502f, -0.173983873f, + 0.984210092f, -0.177004220f, + 0.983662419f, -0.180022901f, + 0.983105487f, -0.183039888f, + 0.982539302f, -0.186055152f, + 0.981963869f, -0.189068664f, + 0.981379193f, -0.192080397f, + 0.980785280f, -0.195090322f, + 0.980182136f, -0.198098411f, + 0.979569766f, -0.201104635f, + 0.978948175f, -0.204108966f, + 0.978317371f, -0.207111376f, + 0.977677358f, -0.210111837f, + 0.977028143f, -0.213110320f, + 0.976369731f, -0.216106797f, + 0.975702130f, -0.219101240f, + 0.975025345f, -0.222093621f, + 0.974339383f, -0.225083911f, + 0.973644250f, -0.228072083f, + 0.972939952f, -0.231058108f, + 0.972226497f, -0.234041959f, + 0.971503891f, -0.237023606f, + 0.970772141f, -0.240003022f, + 0.970031253f, -0.242980180f, + 0.969281235f, -0.245955050f, + 0.968522094f, -0.248927606f, + 0.967753837f, -0.251897818f, + 0.966976471f, -0.254865660f, + 0.966190003f, -0.257831102f, + 0.965394442f, -0.260794118f, + 0.964589793f, -0.263754679f, + 0.963776066f, -0.266712757f, + 0.962953267f, -0.269668326f, + 0.962121404f, -0.272621355f, + 0.961280486f, -0.275571819f, + 0.960430519f, -0.278519689f, + 0.959571513f, -0.281464938f, + 0.958703475f, -0.284407537f, + 0.957826413f, -0.287347460f, + 0.956940336f, -0.290284677f, + 0.956045251f, -0.293219163f, + 0.955141168f, -0.296150888f, + 0.954228095f, -0.299079826f, + 0.953306040f, -0.302005949f, + 0.952375013f, -0.304929230f, + 0.951435021f, -0.307849640f, + 0.950486074f, -0.310767153f, + 0.949528181f, -0.313681740f, + 0.948561350f, -0.316593376f, + 0.947585591f, -0.319502031f, + 0.946600913f, -0.322407679f, + 0.945607325f, -0.325310292f, + 0.944604837f, -0.328209844f, + 0.943593458f, -0.331106306f, + 0.942573198f, -0.333999651f, + 0.941544065f, -0.336889853f, + 0.940506071f, -0.339776884f, + 0.939459224f, -0.342660717f, + 0.938403534f, -0.345541325f, + 0.937339012f, -0.348418680f, + 0.936265667f, -0.351292756f, + 0.935183510f, -0.354163525f, + 0.934092550f, -0.357030961f, + 0.932992799f, -0.359895037f, + 0.931884266f, -0.362755724f, + 0.930766961f, -0.365612998f, + 0.929640896f, -0.368466830f, + 0.928506080f, -0.371317194f, + 0.927362526f, -0.374164063f, + 0.926210242f, -0.377007410f, + 0.925049241f, -0.379847209f, + 0.923879533f, -0.382683432f, + 0.922701128f, -0.385516054f, + 0.921514039f, -0.388345047f, + 0.920318277f, -0.391170384f, + 0.919113852f, -0.393992040f, + 0.917900776f, -0.396809987f, + 0.916679060f, -0.399624200f, + 0.915448716f, -0.402434651f, + 0.914209756f, -0.405241314f, + 0.912962190f, -0.408044163f, + 0.911706032f, -0.410843171f, + 0.910441292f, -0.413638312f, + 0.909167983f, -0.416429560f, + 0.907886116f, -0.419216888f, + 0.906595705f, -0.422000271f, + 0.905296759f, -0.424779681f, + 0.903989293f, -0.427555093f, + 0.902673318f, -0.430326481f, + 0.901348847f, -0.433093819f, + 0.900015892f, -0.435857080f, + 0.898674466f, -0.438616239f, + 0.897324581f, -0.441371269f, + 0.895966250f, -0.444122145f, + 0.894599486f, -0.446868840f, + 0.893224301f, -0.449611330f, + 0.891840709f, -0.452349587f, + 0.890448723f, -0.455083587f, + 0.889048356f, -0.457813304f, + 0.887639620f, -0.460538711f, + 0.886222530f, -0.463259784f, + 0.884797098f, -0.465976496f, + 0.883363339f, -0.468688822f, + 0.881921264f, -0.471396737f, + 0.880470889f, -0.474100215f, + 0.879012226f, -0.476799230f, + 0.877545290f, -0.479493758f, + 0.876070094f, -0.482183772f, + 0.874586652f, -0.484869248f, + 0.873094978f, -0.487550160f, + 0.871595087f, -0.490226483f, + 0.870086991f, -0.492898192f, + 0.868570706f, -0.495565262f, + 0.867046246f, -0.498227667f, + 0.865513624f, -0.500885383f, + 0.863972856f, -0.503538384f, + 0.862423956f, -0.506186645f, + 0.860866939f, -0.508830143f, + 0.859301818f, -0.511468850f, + 0.857728610f, -0.514102744f, + 0.856147328f, -0.516731799f, + 0.854557988f, -0.519355990f, + 0.852960605f, -0.521975293f, + 0.851355193f, -0.524589683f, + 0.849741768f, -0.527199135f, + 0.848120345f, -0.529803625f, + 0.846490939f, -0.532403128f, + 0.844853565f, -0.534997620f, + 0.843208240f, -0.537587076f, + 0.841554977f, -0.540171473f, + 0.839893794f, -0.542750785f, + 0.838224706f, -0.545324988f, + 0.836547727f, -0.547894059f, + 0.834862875f, -0.550457973f, + 0.833170165f, -0.553016706f, + 0.831469612f, -0.555570233f, + 0.829761234f, -0.558118531f, + 0.828045045f, -0.560661576f, + 0.826321063f, -0.563199344f, + 0.824589303f, -0.565731811f, + 0.822849781f, -0.568258953f, + 0.821102515f, -0.570780746f, + 0.819347520f, -0.573297167f, + 0.817584813f, -0.575808191f, + 0.815814411f, -0.578313796f, + 0.814036330f, -0.580813958f, + 0.812250587f, -0.583308653f, + 0.810457198f, -0.585797857f, + 0.808656182f, -0.588281548f, + 0.806847554f, -0.590759702f, + 0.805031331f, -0.593232295f, + 0.803207531f, -0.595699304f, + 0.801376172f, -0.598160707f, + 0.799537269f, -0.600616479f, + 0.797690841f, -0.603066599f, + 0.795836905f, -0.605511041f, + 0.793975478f, -0.607949785f, + 0.792106577f, -0.610382806f, + 0.790230221f, -0.612810082f, + 0.788346428f, -0.615231591f, + 0.786455214f, -0.617647308f, + 0.784556597f, -0.620057212f, + 0.782650596f, -0.622461279f, + 0.780737229f, -0.624859488f, + 0.778816512f, -0.627251815f, + 0.776888466f, -0.629638239f, + 0.774953107f, -0.632018736f, + 0.773010453f, -0.634393284f, + 0.771060524f, -0.636761861f, + 0.769103338f, -0.639124445f, + 0.767138912f, -0.641481013f, + 0.765167266f, -0.643831543f, + 0.763188417f, -0.646176013f, + 0.761202385f, -0.648514401f, + 0.759209189f, -0.650846685f, + 0.757208847f, -0.653172843f, + 0.755201377f, -0.655492853f, + 0.753186799f, -0.657806693f, + 0.751165132f, -0.660114342f, + 0.749136395f, -0.662415778f, + 0.747100606f, -0.664710978f, + 0.745057785f, -0.666999922f, + 0.743007952f, -0.669282588f, + 0.740951125f, -0.671558955f, + 0.738887324f, -0.673829000f, + 0.736816569f, -0.676092704f, + 0.734738878f, -0.678350043f, + 0.732654272f, -0.680600998f, + 0.730562769f, -0.682845546f, + 0.728464390f, -0.685083668f, + 0.726359155f, -0.687315341f, + 0.724247083f, -0.689540545f, + 0.722128194f, -0.691759258f, + 0.720002508f, -0.693971461f, + 0.717870045f, -0.696177131f, + 0.715730825f, -0.698376249f, + 0.713584869f, -0.700568794f, + 0.711432196f, -0.702754744f, + 0.709272826f, -0.704934080f, + 0.707106781f, -0.707106781f, + 0.704934080f, -0.709272826f, + 0.702754744f, -0.711432196f, + 0.700568794f, -0.713584869f, + 0.698376249f, -0.715730825f, + 0.696177131f, -0.717870045f, + 0.693971461f, -0.720002508f, + 0.691759258f, -0.722128194f, + 0.689540545f, -0.724247083f, + 0.687315341f, -0.726359155f, + 0.685083668f, -0.728464390f, + 0.682845546f, -0.730562769f, + 0.680600998f, -0.732654272f, + 0.678350043f, -0.734738878f, + 0.676092704f, -0.736816569f, + 0.673829000f, -0.738887324f, + 0.671558955f, -0.740951125f, + 0.669282588f, -0.743007952f, + 0.666999922f, -0.745057785f, + 0.664710978f, -0.747100606f, + 0.662415778f, -0.749136395f, + 0.660114342f, -0.751165132f, + 0.657806693f, -0.753186799f, + 0.655492853f, -0.755201377f, + 0.653172843f, -0.757208847f, + 0.650846685f, -0.759209189f, + 0.648514401f, -0.761202385f, + 0.646176013f, -0.763188417f, + 0.643831543f, -0.765167266f, + 0.641481013f, -0.767138912f, + 0.639124445f, -0.769103338f, + 0.636761861f, -0.771060524f, + 0.634393284f, -0.773010453f, + 0.632018736f, -0.774953107f, + 0.629638239f, -0.776888466f, + 0.627251815f, -0.778816512f, + 0.624859488f, -0.780737229f, + 0.622461279f, -0.782650596f, + 0.620057212f, -0.784556597f, + 0.617647308f, -0.786455214f, + 0.615231591f, -0.788346428f, + 0.612810082f, -0.790230221f, + 0.610382806f, -0.792106577f, + 0.607949785f, -0.793975478f, + 0.605511041f, -0.795836905f, + 0.603066599f, -0.797690841f, + 0.600616479f, -0.799537269f, + 0.598160707f, -0.801376172f, + 0.595699304f, -0.803207531f, + 0.593232295f, -0.805031331f, + 0.590759702f, -0.806847554f, + 0.588281548f, -0.808656182f, + 0.585797857f, -0.810457198f, + 0.583308653f, -0.812250587f, + 0.580813958f, -0.814036330f, + 0.578313796f, -0.815814411f, + 0.575808191f, -0.817584813f, + 0.573297167f, -0.819347520f, + 0.570780746f, -0.821102515f, + 0.568258953f, -0.822849781f, + 0.565731811f, -0.824589303f, + 0.563199344f, -0.826321063f, + 0.560661576f, -0.828045045f, + 0.558118531f, -0.829761234f, + 0.555570233f, -0.831469612f, + 0.553016706f, -0.833170165f, + 0.550457973f, -0.834862875f, + 0.547894059f, -0.836547727f, + 0.545324988f, -0.838224706f, + 0.542750785f, -0.839893794f, + 0.540171473f, -0.841554977f, + 0.537587076f, -0.843208240f, + 0.534997620f, -0.844853565f, + 0.532403128f, -0.846490939f, + 0.529803625f, -0.848120345f, + 0.527199135f, -0.849741768f, + 0.524589683f, -0.851355193f, + 0.521975293f, -0.852960605f, + 0.519355990f, -0.854557988f, + 0.516731799f, -0.856147328f, + 0.514102744f, -0.857728610f, + 0.511468850f, -0.859301818f, + 0.508830143f, -0.860866939f, + 0.506186645f, -0.862423956f, + 0.503538384f, -0.863972856f, + 0.500885383f, -0.865513624f, + 0.498227667f, -0.867046246f, + 0.495565262f, -0.868570706f, + 0.492898192f, -0.870086991f, + 0.490226483f, -0.871595087f, + 0.487550160f, -0.873094978f, + 0.484869248f, -0.874586652f, + 0.482183772f, -0.876070094f, + 0.479493758f, -0.877545290f, + 0.476799230f, -0.879012226f, + 0.474100215f, -0.880470889f, + 0.471396737f, -0.881921264f, + 0.468688822f, -0.883363339f, + 0.465976496f, -0.884797098f, + 0.463259784f, -0.886222530f, + 0.460538711f, -0.887639620f, + 0.457813304f, -0.889048356f, + 0.455083587f, -0.890448723f, + 0.452349587f, -0.891840709f, + 0.449611330f, -0.893224301f, + 0.446868840f, -0.894599486f, + 0.444122145f, -0.895966250f, + 0.441371269f, -0.897324581f, + 0.438616239f, -0.898674466f, + 0.435857080f, -0.900015892f, + 0.433093819f, -0.901348847f, + 0.430326481f, -0.902673318f, + 0.427555093f, -0.903989293f, + 0.424779681f, -0.905296759f, + 0.422000271f, -0.906595705f, + 0.419216888f, -0.907886116f, + 0.416429560f, -0.909167983f, + 0.413638312f, -0.910441292f, + 0.410843171f, -0.911706032f, + 0.408044163f, -0.912962190f, + 0.405241314f, -0.914209756f, + 0.402434651f, -0.915448716f, + 0.399624200f, -0.916679060f, + 0.396809987f, -0.917900776f, + 0.393992040f, -0.919113852f, + 0.391170384f, -0.920318277f, + 0.388345047f, -0.921514039f, + 0.385516054f, -0.922701128f, + 0.382683432f, -0.923879533f, + 0.379847209f, -0.925049241f, + 0.377007410f, -0.926210242f, + 0.374164063f, -0.927362526f, + 0.371317194f, -0.928506080f, + 0.368466830f, -0.929640896f, + 0.365612998f, -0.930766961f, + 0.362755724f, -0.931884266f, + 0.359895037f, -0.932992799f, + 0.357030961f, -0.934092550f, + 0.354163525f, -0.935183510f, + 0.351292756f, -0.936265667f, + 0.348418680f, -0.937339012f, + 0.345541325f, -0.938403534f, + 0.342660717f, -0.939459224f, + 0.339776884f, -0.940506071f, + 0.336889853f, -0.941544065f, + 0.333999651f, -0.942573198f, + 0.331106306f, -0.943593458f, + 0.328209844f, -0.944604837f, + 0.325310292f, -0.945607325f, + 0.322407679f, -0.946600913f, + 0.319502031f, -0.947585591f, + 0.316593376f, -0.948561350f, + 0.313681740f, -0.949528181f, + 0.310767153f, -0.950486074f, + 0.307849640f, -0.951435021f, + 0.304929230f, -0.952375013f, + 0.302005949f, -0.953306040f, + 0.299079826f, -0.954228095f, + 0.296150888f, -0.955141168f, + 0.293219163f, -0.956045251f, + 0.290284677f, -0.956940336f, + 0.287347460f, -0.957826413f, + 0.284407537f, -0.958703475f, + 0.281464938f, -0.959571513f, + 0.278519689f, -0.960430519f, + 0.275571819f, -0.961280486f, + 0.272621355f, -0.962121404f, + 0.269668326f, -0.962953267f, + 0.266712757f, -0.963776066f, + 0.263754679f, -0.964589793f, + 0.260794118f, -0.965394442f, + 0.257831102f, -0.966190003f, + 0.254865660f, -0.966976471f, + 0.251897818f, -0.967753837f, + 0.248927606f, -0.968522094f, + 0.245955050f, -0.969281235f, + 0.242980180f, -0.970031253f, + 0.240003022f, -0.970772141f, + 0.237023606f, -0.971503891f, + 0.234041959f, -0.972226497f, + 0.231058108f, -0.972939952f, + 0.228072083f, -0.973644250f, + 0.225083911f, -0.974339383f, + 0.222093621f, -0.975025345f, + 0.219101240f, -0.975702130f, + 0.216106797f, -0.976369731f, + 0.213110320f, -0.977028143f, + 0.210111837f, -0.977677358f, + 0.207111376f, -0.978317371f, + 0.204108966f, -0.978948175f, + 0.201104635f, -0.979569766f, + 0.198098411f, -0.980182136f, + 0.195090322f, -0.980785280f, + 0.192080397f, -0.981379193f, + 0.189068664f, -0.981963869f, + 0.186055152f, -0.982539302f, + 0.183039888f, -0.983105487f, + 0.180022901f, -0.983662419f, + 0.177004220f, -0.984210092f, + 0.173983873f, -0.984748502f, + 0.170961889f, -0.985277642f, + 0.167938295f, -0.985797509f, + 0.164913120f, -0.986308097f, + 0.161886394f, -0.986809402f, + 0.158858143f, -0.987301418f, + 0.155828398f, -0.987784142f, + 0.152797185f, -0.988257568f, + 0.149764535f, -0.988721692f, + 0.146730474f, -0.989176510f, + 0.143695033f, -0.989622017f, + 0.140658239f, -0.990058210f, + 0.137620122f, -0.990485084f, + 0.134580709f, -0.990902635f, + 0.131540029f, -0.991310860f, + 0.128498111f, -0.991709754f, + 0.125454983f, -0.992099313f, + 0.122410675f, -0.992479535f, + 0.119365215f, -0.992850414f, + 0.116318631f, -0.993211949f, + 0.113270952f, -0.993564136f, + 0.110222207f, -0.993906970f, + 0.107172425f, -0.994240449f, + 0.104121634f, -0.994564571f, + 0.101069863f, -0.994879331f, + 0.098017140f, -0.995184727f, + 0.094963495f, -0.995480755f, + 0.091908956f, -0.995767414f, + 0.088853553f, -0.996044701f, + 0.085797312f, -0.996312612f, + 0.082740265f, -0.996571146f, + 0.079682438f, -0.996820299f, + 0.076623861f, -0.997060070f, + 0.073564564f, -0.997290457f, + 0.070504573f, -0.997511456f, + 0.067443920f, -0.997723067f, + 0.064382631f, -0.997925286f, + 0.061320736f, -0.998118113f, + 0.058258265f, -0.998301545f, + 0.055195244f, -0.998475581f, + 0.052131705f, -0.998640218f, + 0.049067674f, -0.998795456f, + 0.046003182f, -0.998941293f, + 0.042938257f, -0.999077728f, + 0.039872928f, -0.999204759f, + 0.036807223f, -0.999322385f, + 0.033741172f, -0.999430605f, + 0.030674803f, -0.999529418f, + 0.027608146f, -0.999618822f, + 0.024541229f, -0.999698819f, + 0.021474080f, -0.999769405f, + 0.018406730f, -0.999830582f, + 0.015339206f, -0.999882347f, + 0.012271538f, -0.999924702f, + 0.009203755f, -0.999957645f, + 0.006135885f, -0.999981175f, + 0.003067957f, -0.999995294f +}; + +const float32_t twiddleCoef_rfft_4096[4096] = { + 0.000000000f, 1.000000000f, + 0.001533980f, 0.999998823f, + 0.003067957f, 0.999995294f, + 0.004601926f, 0.999989411f, + 0.006135885f, 0.999981175f, + 0.007669829f, 0.999970586f, + 0.009203755f, 0.999957645f, + 0.010737659f, 0.999942350f, + 0.012271538f, 0.999924702f, + 0.013805389f, 0.999904701f, + 0.015339206f, 0.999882347f, + 0.016872988f, 0.999857641f, + 0.018406730f, 0.999830582f, + 0.019940429f, 0.999801170f, + 0.021474080f, 0.999769405f, + 0.023007681f, 0.999735288f, + 0.024541229f, 0.999698819f, + 0.026074718f, 0.999659997f, + 0.027608146f, 0.999618822f, + 0.029141509f, 0.999575296f, + 0.030674803f, 0.999529418f, + 0.032208025f, 0.999481187f, + 0.033741172f, 0.999430605f, + 0.035274239f, 0.999377670f, + 0.036807223f, 0.999322385f, + 0.038340120f, 0.999264747f, + 0.039872928f, 0.999204759f, + 0.041405641f, 0.999142419f, + 0.042938257f, 0.999077728f, + 0.044470772f, 0.999010686f, + 0.046003182f, 0.998941293f, + 0.047535484f, 0.998869550f, + 0.049067674f, 0.998795456f, + 0.050599749f, 0.998719012f, + 0.052131705f, 0.998640218f, + 0.053663538f, 0.998559074f, + 0.055195244f, 0.998475581f, + 0.056726821f, 0.998389737f, + 0.058258265f, 0.998301545f, + 0.059789571f, 0.998211003f, + 0.061320736f, 0.998118113f, + 0.062851758f, 0.998022874f, + 0.064382631f, 0.997925286f, + 0.065913353f, 0.997825350f, + 0.067443920f, 0.997723067f, + 0.068974328f, 0.997618435f, + 0.070504573f, 0.997511456f, + 0.072034653f, 0.997402130f, + 0.073564564f, 0.997290457f, + 0.075094301f, 0.997176437f, + 0.076623861f, 0.997060070f, + 0.078153242f, 0.996941358f, + 0.079682438f, 0.996820299f, + 0.081211447f, 0.996696895f, + 0.082740265f, 0.996571146f, + 0.084268888f, 0.996443051f, + 0.085797312f, 0.996312612f, + 0.087325535f, 0.996179829f, + 0.088853553f, 0.996044701f, + 0.090381361f, 0.995907229f, + 0.091908956f, 0.995767414f, + 0.093436336f, 0.995625256f, + 0.094963495f, 0.995480755f, + 0.096490431f, 0.995333912f, + 0.098017140f, 0.995184727f, + 0.099543619f, 0.995033199f, + 0.101069863f, 0.994879331f, + 0.102595869f, 0.994723121f, + 0.104121634f, 0.994564571f, + 0.105647154f, 0.994403680f, + 0.107172425f, 0.994240449f, + 0.108697444f, 0.994074879f, + 0.110222207f, 0.993906970f, + 0.111746711f, 0.993736722f, + 0.113270952f, 0.993564136f, + 0.114794927f, 0.993389211f, + 0.116318631f, 0.993211949f, + 0.117842062f, 0.993032350f, + 0.119365215f, 0.992850414f, + 0.120888087f, 0.992666142f, + 0.122410675f, 0.992479535f, + 0.123932975f, 0.992290591f, + 0.125454983f, 0.992099313f, + 0.126976696f, 0.991905700f, + 0.128498111f, 0.991709754f, + 0.130019223f, 0.991511473f, + 0.131540029f, 0.991310860f, + 0.133060525f, 0.991107914f, + 0.134580709f, 0.990902635f, + 0.136100575f, 0.990695025f, + 0.137620122f, 0.990485084f, + 0.139139344f, 0.990272812f, + 0.140658239f, 0.990058210f, + 0.142176804f, 0.989841278f, + 0.143695033f, 0.989622017f, + 0.145212925f, 0.989400428f, + 0.146730474f, 0.989176510f, + 0.148247679f, 0.988950265f, + 0.149764535f, 0.988721692f, + 0.151281038f, 0.988490793f, + 0.152797185f, 0.988257568f, + 0.154312973f, 0.988022017f, + 0.155828398f, 0.987784142f, + 0.157343456f, 0.987543942f, + 0.158858143f, 0.987301418f, + 0.160372457f, 0.987056571f, + 0.161886394f, 0.986809402f, + 0.163399949f, 0.986559910f, + 0.164913120f, 0.986308097f, + 0.166425904f, 0.986053963f, + 0.167938295f, 0.985797509f, + 0.169450291f, 0.985538735f, + 0.170961889f, 0.985277642f, + 0.172473084f, 0.985014231f, + 0.173983873f, 0.984748502f, + 0.175494253f, 0.984480455f, + 0.177004220f, 0.984210092f, + 0.178513771f, 0.983937413f, + 0.180022901f, 0.983662419f, + 0.181531608f, 0.983385110f, + 0.183039888f, 0.983105487f, + 0.184547737f, 0.982823551f, + 0.186055152f, 0.982539302f, + 0.187562129f, 0.982252741f, + 0.189068664f, 0.981963869f, + 0.190574755f, 0.981672686f, + 0.192080397f, 0.981379193f, + 0.193585587f, 0.981083391f, + 0.195090322f, 0.980785280f, + 0.196594598f, 0.980484862f, + 0.198098411f, 0.980182136f, + 0.199601758f, 0.979877104f, + 0.201104635f, 0.979569766f, + 0.202607039f, 0.979260123f, + 0.204108966f, 0.978948175f, + 0.205610413f, 0.978633924f, + 0.207111376f, 0.978317371f, + 0.208611852f, 0.977998515f, + 0.210111837f, 0.977677358f, + 0.211611327f, 0.977353900f, + 0.213110320f, 0.977028143f, + 0.214608811f, 0.976700086f, + 0.216106797f, 0.976369731f, + 0.217604275f, 0.976037079f, + 0.219101240f, 0.975702130f, + 0.220597690f, 0.975364885f, + 0.222093621f, 0.975025345f, + 0.223589029f, 0.974683511f, + 0.225083911f, 0.974339383f, + 0.226578264f, 0.973992962f, + 0.228072083f, 0.973644250f, + 0.229565366f, 0.973293246f, + 0.231058108f, 0.972939952f, + 0.232550307f, 0.972584369f, + 0.234041959f, 0.972226497f, + 0.235533059f, 0.971866337f, + 0.237023606f, 0.971503891f, + 0.238513595f, 0.971139158f, + 0.240003022f, 0.970772141f, + 0.241491885f, 0.970402839f, + 0.242980180f, 0.970031253f, + 0.244467903f, 0.969657385f, + 0.245955050f, 0.969281235f, + 0.247441619f, 0.968902805f, + 0.248927606f, 0.968522094f, + 0.250413007f, 0.968139105f, + 0.251897818f, 0.967753837f, + 0.253382037f, 0.967366292f, + 0.254865660f, 0.966976471f, + 0.256348682f, 0.966584374f, + 0.257831102f, 0.966190003f, + 0.259312915f, 0.965793359f, + 0.260794118f, 0.965394442f, + 0.262274707f, 0.964993253f, + 0.263754679f, 0.964589793f, + 0.265234030f, 0.964184064f, + 0.266712757f, 0.963776066f, + 0.268190857f, 0.963365800f, + 0.269668326f, 0.962953267f, + 0.271145160f, 0.962538468f, + 0.272621355f, 0.962121404f, + 0.274096910f, 0.961702077f, + 0.275571819f, 0.961280486f, + 0.277046080f, 0.960856633f, + 0.278519689f, 0.960430519f, + 0.279992643f, 0.960002146f, + 0.281464938f, 0.959571513f, + 0.282936570f, 0.959138622f, + 0.284407537f, 0.958703475f, + 0.285877835f, 0.958266071f, + 0.287347460f, 0.957826413f, + 0.288816408f, 0.957384501f, + 0.290284677f, 0.956940336f, + 0.291752263f, 0.956493919f, + 0.293219163f, 0.956045251f, + 0.294685372f, 0.955594334f, + 0.296150888f, 0.955141168f, + 0.297615707f, 0.954685755f, + 0.299079826f, 0.954228095f, + 0.300543241f, 0.953768190f, + 0.302005949f, 0.953306040f, + 0.303467947f, 0.952841648f, + 0.304929230f, 0.952375013f, + 0.306389795f, 0.951906137f, + 0.307849640f, 0.951435021f, + 0.309308760f, 0.950961666f, + 0.310767153f, 0.950486074f, + 0.312224814f, 0.950008245f, + 0.313681740f, 0.949528181f, + 0.315137929f, 0.949045882f, + 0.316593376f, 0.948561350f, + 0.318048077f, 0.948074586f, + 0.319502031f, 0.947585591f, + 0.320955232f, 0.947094366f, + 0.322407679f, 0.946600913f, + 0.323859367f, 0.946105232f, + 0.325310292f, 0.945607325f, + 0.326760452f, 0.945107193f, + 0.328209844f, 0.944604837f, + 0.329658463f, 0.944100258f, + 0.331106306f, 0.943593458f, + 0.332553370f, 0.943084437f, + 0.333999651f, 0.942573198f, + 0.335445147f, 0.942059740f, + 0.336889853f, 0.941544065f, + 0.338333767f, 0.941026175f, + 0.339776884f, 0.940506071f, + 0.341219202f, 0.939983753f, + 0.342660717f, 0.939459224f, + 0.344101426f, 0.938932484f, + 0.345541325f, 0.938403534f, + 0.346980411f, 0.937872376f, + 0.348418680f, 0.937339012f, + 0.349856130f, 0.936803442f, + 0.351292756f, 0.936265667f, + 0.352728556f, 0.935725689f, + 0.354163525f, 0.935183510f, + 0.355597662f, 0.934639130f, + 0.357030961f, 0.934092550f, + 0.358463421f, 0.933543773f, + 0.359895037f, 0.932992799f, + 0.361325806f, 0.932439629f, + 0.362755724f, 0.931884266f, + 0.364184790f, 0.931326709f, + 0.365612998f, 0.930766961f, + 0.367040346f, 0.930205023f, + 0.368466830f, 0.929640896f, + 0.369892447f, 0.929074581f, + 0.371317194f, 0.928506080f, + 0.372741067f, 0.927935395f, + 0.374164063f, 0.927362526f, + 0.375586178f, 0.926787474f, + 0.377007410f, 0.926210242f, + 0.378427755f, 0.925630831f, + 0.379847209f, 0.925049241f, + 0.381265769f, 0.924465474f, + 0.382683432f, 0.923879533f, + 0.384100195f, 0.923291417f, + 0.385516054f, 0.922701128f, + 0.386931006f, 0.922108669f, + 0.388345047f, 0.921514039f, + 0.389758174f, 0.920917242f, + 0.391170384f, 0.920318277f, + 0.392581674f, 0.919717146f, + 0.393992040f, 0.919113852f, + 0.395401479f, 0.918508394f, + 0.396809987f, 0.917900776f, + 0.398217562f, 0.917290997f, + 0.399624200f, 0.916679060f, + 0.401029897f, 0.916064966f, + 0.402434651f, 0.915448716f, + 0.403838458f, 0.914830312f, + 0.405241314f, 0.914209756f, + 0.406643217f, 0.913587048f, + 0.408044163f, 0.912962190f, + 0.409444149f, 0.912335185f, + 0.410843171f, 0.911706032f, + 0.412241227f, 0.911074734f, + 0.413638312f, 0.910441292f, + 0.415034424f, 0.909805708f, + 0.416429560f, 0.909167983f, + 0.417823716f, 0.908528119f, + 0.419216888f, 0.907886116f, + 0.420609074f, 0.907241978f, + 0.422000271f, 0.906595705f, + 0.423390474f, 0.905947298f, + 0.424779681f, 0.905296759f, + 0.426167889f, 0.904644091f, + 0.427555093f, 0.903989293f, + 0.428941292f, 0.903332368f, + 0.430326481f, 0.902673318f, + 0.431710658f, 0.902012144f, + 0.433093819f, 0.901348847f, + 0.434475961f, 0.900683429f, + 0.435857080f, 0.900015892f, + 0.437237174f, 0.899346237f, + 0.438616239f, 0.898674466f, + 0.439994271f, 0.898000580f, + 0.441371269f, 0.897324581f, + 0.442747228f, 0.896646470f, + 0.444122145f, 0.895966250f, + 0.445496017f, 0.895283921f, + 0.446868840f, 0.894599486f, + 0.448240612f, 0.893912945f, + 0.449611330f, 0.893224301f, + 0.450980989f, 0.892533555f, + 0.452349587f, 0.891840709f, + 0.453717121f, 0.891145765f, + 0.455083587f, 0.890448723f, + 0.456448982f, 0.889749586f, + 0.457813304f, 0.889048356f, + 0.459176548f, 0.888345033f, + 0.460538711f, 0.887639620f, + 0.461899791f, 0.886932119f, + 0.463259784f, 0.886222530f, + 0.464618686f, 0.885510856f, + 0.465976496f, 0.884797098f, + 0.467333209f, 0.884081259f, + 0.468688822f, 0.883363339f, + 0.470043332f, 0.882643340f, + 0.471396737f, 0.881921264f, + 0.472749032f, 0.881197113f, + 0.474100215f, 0.880470889f, + 0.475450282f, 0.879742593f, + 0.476799230f, 0.879012226f, + 0.478147056f, 0.878279792f, + 0.479493758f, 0.877545290f, + 0.480839331f, 0.876808724f, + 0.482183772f, 0.876070094f, + 0.483527079f, 0.875329403f, + 0.484869248f, 0.874586652f, + 0.486210276f, 0.873841843f, + 0.487550160f, 0.873094978f, + 0.488888897f, 0.872346059f, + 0.490226483f, 0.871595087f, + 0.491562916f, 0.870842063f, + 0.492898192f, 0.870086991f, + 0.494232309f, 0.869329871f, + 0.495565262f, 0.868570706f, + 0.496897049f, 0.867809497f, + 0.498227667f, 0.867046246f, + 0.499557113f, 0.866280954f, + 0.500885383f, 0.865513624f, + 0.502212474f, 0.864744258f, + 0.503538384f, 0.863972856f, + 0.504863109f, 0.863199422f, + 0.506186645f, 0.862423956f, + 0.507508991f, 0.861646461f, + 0.508830143f, 0.860866939f, + 0.510150097f, 0.860085390f, + 0.511468850f, 0.859301818f, + 0.512786401f, 0.858516224f, + 0.514102744f, 0.857728610f, + 0.515417878f, 0.856938977f, + 0.516731799f, 0.856147328f, + 0.518044504f, 0.855353665f, + 0.519355990f, 0.854557988f, + 0.520666254f, 0.853760301f, + 0.521975293f, 0.852960605f, + 0.523283103f, 0.852158902f, + 0.524589683f, 0.851355193f, + 0.525895027f, 0.850549481f, + 0.527199135f, 0.849741768f, + 0.528502002f, 0.848932055f, + 0.529803625f, 0.848120345f, + 0.531104001f, 0.847306639f, + 0.532403128f, 0.846490939f, + 0.533701002f, 0.845673247f, + 0.534997620f, 0.844853565f, + 0.536292979f, 0.844031895f, + 0.537587076f, 0.843208240f, + 0.538879909f, 0.842382600f, + 0.540171473f, 0.841554977f, + 0.541461766f, 0.840725375f, + 0.542750785f, 0.839893794f, + 0.544038527f, 0.839060237f, + 0.545324988f, 0.838224706f, + 0.546610167f, 0.837387202f, + 0.547894059f, 0.836547727f, + 0.549176662f, 0.835706284f, + 0.550457973f, 0.834862875f, + 0.551737988f, 0.834017501f, + 0.553016706f, 0.833170165f, + 0.554294121f, 0.832320868f, + 0.555570233f, 0.831469612f, + 0.556845037f, 0.830616400f, + 0.558118531f, 0.829761234f, + 0.559390712f, 0.828904115f, + 0.560661576f, 0.828045045f, + 0.561931121f, 0.827184027f, + 0.563199344f, 0.826321063f, + 0.564466242f, 0.825456154f, + 0.565731811f, 0.824589303f, + 0.566996049f, 0.823720511f, + 0.568258953f, 0.822849781f, + 0.569520519f, 0.821977115f, + 0.570780746f, 0.821102515f, + 0.572039629f, 0.820225983f, + 0.573297167f, 0.819347520f, + 0.574553355f, 0.818467130f, + 0.575808191f, 0.817584813f, + 0.577061673f, 0.816700573f, + 0.578313796f, 0.815814411f, + 0.579564559f, 0.814926329f, + 0.580813958f, 0.814036330f, + 0.582061990f, 0.813144415f, + 0.583308653f, 0.812250587f, + 0.584553943f, 0.811354847f, + 0.585797857f, 0.810457198f, + 0.587040394f, 0.809557642f, + 0.588281548f, 0.808656182f, + 0.589521319f, 0.807752818f, + 0.590759702f, 0.806847554f, + 0.591996695f, 0.805940391f, + 0.593232295f, 0.805031331f, + 0.594466499f, 0.804120377f, + 0.595699304f, 0.803207531f, + 0.596930708f, 0.802292796f, + 0.598160707f, 0.801376172f, + 0.599389298f, 0.800457662f, + 0.600616479f, 0.799537269f, + 0.601842247f, 0.798614995f, + 0.603066599f, 0.797690841f, + 0.604289531f, 0.796764810f, + 0.605511041f, 0.795836905f, + 0.606731127f, 0.794907126f, + 0.607949785f, 0.793975478f, + 0.609167012f, 0.793041960f, + 0.610382806f, 0.792106577f, + 0.611597164f, 0.791169330f, + 0.612810082f, 0.790230221f, + 0.614021559f, 0.789289253f, + 0.615231591f, 0.788346428f, + 0.616440175f, 0.787401747f, + 0.617647308f, 0.786455214f, + 0.618852988f, 0.785506830f, + 0.620057212f, 0.784556597f, + 0.621259977f, 0.783604519f, + 0.622461279f, 0.782650596f, + 0.623661118f, 0.781694832f, + 0.624859488f, 0.780737229f, + 0.626056388f, 0.779777788f, + 0.627251815f, 0.778816512f, + 0.628445767f, 0.777853404f, + 0.629638239f, 0.776888466f, + 0.630829230f, 0.775921699f, + 0.632018736f, 0.774953107f, + 0.633206755f, 0.773982691f, + 0.634393284f, 0.773010453f, + 0.635578320f, 0.772036397f, + 0.636761861f, 0.771060524f, + 0.637943904f, 0.770082837f, + 0.639124445f, 0.769103338f, + 0.640303482f, 0.768122029f, + 0.641481013f, 0.767138912f, + 0.642657034f, 0.766153990f, + 0.643831543f, 0.765167266f, + 0.645004537f, 0.764178741f, + 0.646176013f, 0.763188417f, + 0.647345969f, 0.762196298f, + 0.648514401f, 0.761202385f, + 0.649681307f, 0.760206682f, + 0.650846685f, 0.759209189f, + 0.652010531f, 0.758209910f, + 0.653172843f, 0.757208847f, + 0.654333618f, 0.756206001f, + 0.655492853f, 0.755201377f, + 0.656650546f, 0.754194975f, + 0.657806693f, 0.753186799f, + 0.658961293f, 0.752176850f, + 0.660114342f, 0.751165132f, + 0.661265838f, 0.750151646f, + 0.662415778f, 0.749136395f, + 0.663564159f, 0.748119380f, + 0.664710978f, 0.747100606f, + 0.665856234f, 0.746080074f, + 0.666999922f, 0.745057785f, + 0.668142041f, 0.744033744f, + 0.669282588f, 0.743007952f, + 0.670421560f, 0.741980412f, + 0.671558955f, 0.740951125f, + 0.672694769f, 0.739920095f, + 0.673829000f, 0.738887324f, + 0.674961646f, 0.737852815f, + 0.676092704f, 0.736816569f, + 0.677222170f, 0.735778589f, + 0.678350043f, 0.734738878f, + 0.679476320f, 0.733697438f, + 0.680600998f, 0.732654272f, + 0.681724074f, 0.731609381f, + 0.682845546f, 0.730562769f, + 0.683965412f, 0.729514438f, + 0.685083668f, 0.728464390f, + 0.686200312f, 0.727412629f, + 0.687315341f, 0.726359155f, + 0.688428753f, 0.725303972f, + 0.689540545f, 0.724247083f, + 0.690650714f, 0.723188489f, + 0.691759258f, 0.722128194f, + 0.692866175f, 0.721066199f, + 0.693971461f, 0.720002508f, + 0.695075114f, 0.718937122f, + 0.696177131f, 0.717870045f, + 0.697277511f, 0.716801279f, + 0.698376249f, 0.715730825f, + 0.699473345f, 0.714658688f, + 0.700568794f, 0.713584869f, + 0.701662595f, 0.712509371f, + 0.702754744f, 0.711432196f, + 0.703845241f, 0.710353347f, + 0.704934080f, 0.709272826f, + 0.706021261f, 0.708190637f, + 0.707106781f, 0.707106781f, + 0.708190637f, 0.706021261f, + 0.709272826f, 0.704934080f, + 0.710353347f, 0.703845241f, + 0.711432196f, 0.702754744f, + 0.712509371f, 0.701662595f, + 0.713584869f, 0.700568794f, + 0.714658688f, 0.699473345f, + 0.715730825f, 0.698376249f, + 0.716801279f, 0.697277511f, + 0.717870045f, 0.696177131f, + 0.718937122f, 0.695075114f, + 0.720002508f, 0.693971461f, + 0.721066199f, 0.692866175f, + 0.722128194f, 0.691759258f, + 0.723188489f, 0.690650714f, + 0.724247083f, 0.689540545f, + 0.725303972f, 0.688428753f, + 0.726359155f, 0.687315341f, + 0.727412629f, 0.686200312f, + 0.728464390f, 0.685083668f, + 0.729514438f, 0.683965412f, + 0.730562769f, 0.682845546f, + 0.731609381f, 0.681724074f, + 0.732654272f, 0.680600998f, + 0.733697438f, 0.679476320f, + 0.734738878f, 0.678350043f, + 0.735778589f, 0.677222170f, + 0.736816569f, 0.676092704f, + 0.737852815f, 0.674961646f, + 0.738887324f, 0.673829000f, + 0.739920095f, 0.672694769f, + 0.740951125f, 0.671558955f, + 0.741980412f, 0.670421560f, + 0.743007952f, 0.669282588f, + 0.744033744f, 0.668142041f, + 0.745057785f, 0.666999922f, + 0.746080074f, 0.665856234f, + 0.747100606f, 0.664710978f, + 0.748119380f, 0.663564159f, + 0.749136395f, 0.662415778f, + 0.750151646f, 0.661265838f, + 0.751165132f, 0.660114342f, + 0.752176850f, 0.658961293f, + 0.753186799f, 0.657806693f, + 0.754194975f, 0.656650546f, + 0.755201377f, 0.655492853f, + 0.756206001f, 0.654333618f, + 0.757208847f, 0.653172843f, + 0.758209910f, 0.652010531f, + 0.759209189f, 0.650846685f, + 0.760206682f, 0.649681307f, + 0.761202385f, 0.648514401f, + 0.762196298f, 0.647345969f, + 0.763188417f, 0.646176013f, + 0.764178741f, 0.645004537f, + 0.765167266f, 0.643831543f, + 0.766153990f, 0.642657034f, + 0.767138912f, 0.641481013f, + 0.768122029f, 0.640303482f, + 0.769103338f, 0.639124445f, + 0.770082837f, 0.637943904f, + 0.771060524f, 0.636761861f, + 0.772036397f, 0.635578320f, + 0.773010453f, 0.634393284f, + 0.773982691f, 0.633206755f, + 0.774953107f, 0.632018736f, + 0.775921699f, 0.630829230f, + 0.776888466f, 0.629638239f, + 0.777853404f, 0.628445767f, + 0.778816512f, 0.627251815f, + 0.779777788f, 0.626056388f, + 0.780737229f, 0.624859488f, + 0.781694832f, 0.623661118f, + 0.782650596f, 0.622461279f, + 0.783604519f, 0.621259977f, + 0.784556597f, 0.620057212f, + 0.785506830f, 0.618852988f, + 0.786455214f, 0.617647308f, + 0.787401747f, 0.616440175f, + 0.788346428f, 0.615231591f, + 0.789289253f, 0.614021559f, + 0.790230221f, 0.612810082f, + 0.791169330f, 0.611597164f, + 0.792106577f, 0.610382806f, + 0.793041960f, 0.609167012f, + 0.793975478f, 0.607949785f, + 0.794907126f, 0.606731127f, + 0.795836905f, 0.605511041f, + 0.796764810f, 0.604289531f, + 0.797690841f, 0.603066599f, + 0.798614995f, 0.601842247f, + 0.799537269f, 0.600616479f, + 0.800457662f, 0.599389298f, + 0.801376172f, 0.598160707f, + 0.802292796f, 0.596930708f, + 0.803207531f, 0.595699304f, + 0.804120377f, 0.594466499f, + 0.805031331f, 0.593232295f, + 0.805940391f, 0.591996695f, + 0.806847554f, 0.590759702f, + 0.807752818f, 0.589521319f, + 0.808656182f, 0.588281548f, + 0.809557642f, 0.587040394f, + 0.810457198f, 0.585797857f, + 0.811354847f, 0.584553943f, + 0.812250587f, 0.583308653f, + 0.813144415f, 0.582061990f, + 0.814036330f, 0.580813958f, + 0.814926329f, 0.579564559f, + 0.815814411f, 0.578313796f, + 0.816700573f, 0.577061673f, + 0.817584813f, 0.575808191f, + 0.818467130f, 0.574553355f, + 0.819347520f, 0.573297167f, + 0.820225983f, 0.572039629f, + 0.821102515f, 0.570780746f, + 0.821977115f, 0.569520519f, + 0.822849781f, 0.568258953f, + 0.823720511f, 0.566996049f, + 0.824589303f, 0.565731811f, + 0.825456154f, 0.564466242f, + 0.826321063f, 0.563199344f, + 0.827184027f, 0.561931121f, + 0.828045045f, 0.560661576f, + 0.828904115f, 0.559390712f, + 0.829761234f, 0.558118531f, + 0.830616400f, 0.556845037f, + 0.831469612f, 0.555570233f, + 0.832320868f, 0.554294121f, + 0.833170165f, 0.553016706f, + 0.834017501f, 0.551737988f, + 0.834862875f, 0.550457973f, + 0.835706284f, 0.549176662f, + 0.836547727f, 0.547894059f, + 0.837387202f, 0.546610167f, + 0.838224706f, 0.545324988f, + 0.839060237f, 0.544038527f, + 0.839893794f, 0.542750785f, + 0.840725375f, 0.541461766f, + 0.841554977f, 0.540171473f, + 0.842382600f, 0.538879909f, + 0.843208240f, 0.537587076f, + 0.844031895f, 0.536292979f, + 0.844853565f, 0.534997620f, + 0.845673247f, 0.533701002f, + 0.846490939f, 0.532403128f, + 0.847306639f, 0.531104001f, + 0.848120345f, 0.529803625f, + 0.848932055f, 0.528502002f, + 0.849741768f, 0.527199135f, + 0.850549481f, 0.525895027f, + 0.851355193f, 0.524589683f, + 0.852158902f, 0.523283103f, + 0.852960605f, 0.521975293f, + 0.853760301f, 0.520666254f, + 0.854557988f, 0.519355990f, + 0.855353665f, 0.518044504f, + 0.856147328f, 0.516731799f, + 0.856938977f, 0.515417878f, + 0.857728610f, 0.514102744f, + 0.858516224f, 0.512786401f, + 0.859301818f, 0.511468850f, + 0.860085390f, 0.510150097f, + 0.860866939f, 0.508830143f, + 0.861646461f, 0.507508991f, + 0.862423956f, 0.506186645f, + 0.863199422f, 0.504863109f, + 0.863972856f, 0.503538384f, + 0.864744258f, 0.502212474f, + 0.865513624f, 0.500885383f, + 0.866280954f, 0.499557113f, + 0.867046246f, 0.498227667f, + 0.867809497f, 0.496897049f, + 0.868570706f, 0.495565262f, + 0.869329871f, 0.494232309f, + 0.870086991f, 0.492898192f, + 0.870842063f, 0.491562916f, + 0.871595087f, 0.490226483f, + 0.872346059f, 0.488888897f, + 0.873094978f, 0.487550160f, + 0.873841843f, 0.486210276f, + 0.874586652f, 0.484869248f, + 0.875329403f, 0.483527079f, + 0.876070094f, 0.482183772f, + 0.876808724f, 0.480839331f, + 0.877545290f, 0.479493758f, + 0.878279792f, 0.478147056f, + 0.879012226f, 0.476799230f, + 0.879742593f, 0.475450282f, + 0.880470889f, 0.474100215f, + 0.881197113f, 0.472749032f, + 0.881921264f, 0.471396737f, + 0.882643340f, 0.470043332f, + 0.883363339f, 0.468688822f, + 0.884081259f, 0.467333209f, + 0.884797098f, 0.465976496f, + 0.885510856f, 0.464618686f, + 0.886222530f, 0.463259784f, + 0.886932119f, 0.461899791f, + 0.887639620f, 0.460538711f, + 0.888345033f, 0.459176548f, + 0.889048356f, 0.457813304f, + 0.889749586f, 0.456448982f, + 0.890448723f, 0.455083587f, + 0.891145765f, 0.453717121f, + 0.891840709f, 0.452349587f, + 0.892533555f, 0.450980989f, + 0.893224301f, 0.449611330f, + 0.893912945f, 0.448240612f, + 0.894599486f, 0.446868840f, + 0.895283921f, 0.445496017f, + 0.895966250f, 0.444122145f, + 0.896646470f, 0.442747228f, + 0.897324581f, 0.441371269f, + 0.898000580f, 0.439994271f, + 0.898674466f, 0.438616239f, + 0.899346237f, 0.437237174f, + 0.900015892f, 0.435857080f, + 0.900683429f, 0.434475961f, + 0.901348847f, 0.433093819f, + 0.902012144f, 0.431710658f, + 0.902673318f, 0.430326481f, + 0.903332368f, 0.428941292f, + 0.903989293f, 0.427555093f, + 0.904644091f, 0.426167889f, + 0.905296759f, 0.424779681f, + 0.905947298f, 0.423390474f, + 0.906595705f, 0.422000271f, + 0.907241978f, 0.420609074f, + 0.907886116f, 0.419216888f, + 0.908528119f, 0.417823716f, + 0.909167983f, 0.416429560f, + 0.909805708f, 0.415034424f, + 0.910441292f, 0.413638312f, + 0.911074734f, 0.412241227f, + 0.911706032f, 0.410843171f, + 0.912335185f, 0.409444149f, + 0.912962190f, 0.408044163f, + 0.913587048f, 0.406643217f, + 0.914209756f, 0.405241314f, + 0.914830312f, 0.403838458f, + 0.915448716f, 0.402434651f, + 0.916064966f, 0.401029897f, + 0.916679060f, 0.399624200f, + 0.917290997f, 0.398217562f, + 0.917900776f, 0.396809987f, + 0.918508394f, 0.395401479f, + 0.919113852f, 0.393992040f, + 0.919717146f, 0.392581674f, + 0.920318277f, 0.391170384f, + 0.920917242f, 0.389758174f, + 0.921514039f, 0.388345047f, + 0.922108669f, 0.386931006f, + 0.922701128f, 0.385516054f, + 0.923291417f, 0.384100195f, + 0.923879533f, 0.382683432f, + 0.924465474f, 0.381265769f, + 0.925049241f, 0.379847209f, + 0.925630831f, 0.378427755f, + 0.926210242f, 0.377007410f, + 0.926787474f, 0.375586178f, + 0.927362526f, 0.374164063f, + 0.927935395f, 0.372741067f, + 0.928506080f, 0.371317194f, + 0.929074581f, 0.369892447f, + 0.929640896f, 0.368466830f, + 0.930205023f, 0.367040346f, + 0.930766961f, 0.365612998f, + 0.931326709f, 0.364184790f, + 0.931884266f, 0.362755724f, + 0.932439629f, 0.361325806f, + 0.932992799f, 0.359895037f, + 0.933543773f, 0.358463421f, + 0.934092550f, 0.357030961f, + 0.934639130f, 0.355597662f, + 0.935183510f, 0.354163525f, + 0.935725689f, 0.352728556f, + 0.936265667f, 0.351292756f, + 0.936803442f, 0.349856130f, + 0.937339012f, 0.348418680f, + 0.937872376f, 0.346980411f, + 0.938403534f, 0.345541325f, + 0.938932484f, 0.344101426f, + 0.939459224f, 0.342660717f, + 0.939983753f, 0.341219202f, + 0.940506071f, 0.339776884f, + 0.941026175f, 0.338333767f, + 0.941544065f, 0.336889853f, + 0.942059740f, 0.335445147f, + 0.942573198f, 0.333999651f, + 0.943084437f, 0.332553370f, + 0.943593458f, 0.331106306f, + 0.944100258f, 0.329658463f, + 0.944604837f, 0.328209844f, + 0.945107193f, 0.326760452f, + 0.945607325f, 0.325310292f, + 0.946105232f, 0.323859367f, + 0.946600913f, 0.322407679f, + 0.947094366f, 0.320955232f, + 0.947585591f, 0.319502031f, + 0.948074586f, 0.318048077f, + 0.948561350f, 0.316593376f, + 0.949045882f, 0.315137929f, + 0.949528181f, 0.313681740f, + 0.950008245f, 0.312224814f, + 0.950486074f, 0.310767153f, + 0.950961666f, 0.309308760f, + 0.951435021f, 0.307849640f, + 0.951906137f, 0.306389795f, + 0.952375013f, 0.304929230f, + 0.952841648f, 0.303467947f, + 0.953306040f, 0.302005949f, + 0.953768190f, 0.300543241f, + 0.954228095f, 0.299079826f, + 0.954685755f, 0.297615707f, + 0.955141168f, 0.296150888f, + 0.955594334f, 0.294685372f, + 0.956045251f, 0.293219163f, + 0.956493919f, 0.291752263f, + 0.956940336f, 0.290284677f, + 0.957384501f, 0.288816408f, + 0.957826413f, 0.287347460f, + 0.958266071f, 0.285877835f, + 0.958703475f, 0.284407537f, + 0.959138622f, 0.282936570f, + 0.959571513f, 0.281464938f, + 0.960002146f, 0.279992643f, + 0.960430519f, 0.278519689f, + 0.960856633f, 0.277046080f, + 0.961280486f, 0.275571819f, + 0.961702077f, 0.274096910f, + 0.962121404f, 0.272621355f, + 0.962538468f, 0.271145160f, + 0.962953267f, 0.269668326f, + 0.963365800f, 0.268190857f, + 0.963776066f, 0.266712757f, + 0.964184064f, 0.265234030f, + 0.964589793f, 0.263754679f, + 0.964993253f, 0.262274707f, + 0.965394442f, 0.260794118f, + 0.965793359f, 0.259312915f, + 0.966190003f, 0.257831102f, + 0.966584374f, 0.256348682f, + 0.966976471f, 0.254865660f, + 0.967366292f, 0.253382037f, + 0.967753837f, 0.251897818f, + 0.968139105f, 0.250413007f, + 0.968522094f, 0.248927606f, + 0.968902805f, 0.247441619f, + 0.969281235f, 0.245955050f, + 0.969657385f, 0.244467903f, + 0.970031253f, 0.242980180f, + 0.970402839f, 0.241491885f, + 0.970772141f, 0.240003022f, + 0.971139158f, 0.238513595f, + 0.971503891f, 0.237023606f, + 0.971866337f, 0.235533059f, + 0.972226497f, 0.234041959f, + 0.972584369f, 0.232550307f, + 0.972939952f, 0.231058108f, + 0.973293246f, 0.229565366f, + 0.973644250f, 0.228072083f, + 0.973992962f, 0.226578264f, + 0.974339383f, 0.225083911f, + 0.974683511f, 0.223589029f, + 0.975025345f, 0.222093621f, + 0.975364885f, 0.220597690f, + 0.975702130f, 0.219101240f, + 0.976037079f, 0.217604275f, + 0.976369731f, 0.216106797f, + 0.976700086f, 0.214608811f, + 0.977028143f, 0.213110320f, + 0.977353900f, 0.211611327f, + 0.977677358f, 0.210111837f, + 0.977998515f, 0.208611852f, + 0.978317371f, 0.207111376f, + 0.978633924f, 0.205610413f, + 0.978948175f, 0.204108966f, + 0.979260123f, 0.202607039f, + 0.979569766f, 0.201104635f, + 0.979877104f, 0.199601758f, + 0.980182136f, 0.198098411f, + 0.980484862f, 0.196594598f, + 0.980785280f, 0.195090322f, + 0.981083391f, 0.193585587f, + 0.981379193f, 0.192080397f, + 0.981672686f, 0.190574755f, + 0.981963869f, 0.189068664f, + 0.982252741f, 0.187562129f, + 0.982539302f, 0.186055152f, + 0.982823551f, 0.184547737f, + 0.983105487f, 0.183039888f, + 0.983385110f, 0.181531608f, + 0.983662419f, 0.180022901f, + 0.983937413f, 0.178513771f, + 0.984210092f, 0.177004220f, + 0.984480455f, 0.175494253f, + 0.984748502f, 0.173983873f, + 0.985014231f, 0.172473084f, + 0.985277642f, 0.170961889f, + 0.985538735f, 0.169450291f, + 0.985797509f, 0.167938295f, + 0.986053963f, 0.166425904f, + 0.986308097f, 0.164913120f, + 0.986559910f, 0.163399949f, + 0.986809402f, 0.161886394f, + 0.987056571f, 0.160372457f, + 0.987301418f, 0.158858143f, + 0.987543942f, 0.157343456f, + 0.987784142f, 0.155828398f, + 0.988022017f, 0.154312973f, + 0.988257568f, 0.152797185f, + 0.988490793f, 0.151281038f, + 0.988721692f, 0.149764535f, + 0.988950265f, 0.148247679f, + 0.989176510f, 0.146730474f, + 0.989400428f, 0.145212925f, + 0.989622017f, 0.143695033f, + 0.989841278f, 0.142176804f, + 0.990058210f, 0.140658239f, + 0.990272812f, 0.139139344f, + 0.990485084f, 0.137620122f, + 0.990695025f, 0.136100575f, + 0.990902635f, 0.134580709f, + 0.991107914f, 0.133060525f, + 0.991310860f, 0.131540029f, + 0.991511473f, 0.130019223f, + 0.991709754f, 0.128498111f, + 0.991905700f, 0.126976696f, + 0.992099313f, 0.125454983f, + 0.992290591f, 0.123932975f, + 0.992479535f, 0.122410675f, + 0.992666142f, 0.120888087f, + 0.992850414f, 0.119365215f, + 0.993032350f, 0.117842062f, + 0.993211949f, 0.116318631f, + 0.993389211f, 0.114794927f, + 0.993564136f, 0.113270952f, + 0.993736722f, 0.111746711f, + 0.993906970f, 0.110222207f, + 0.994074879f, 0.108697444f, + 0.994240449f, 0.107172425f, + 0.994403680f, 0.105647154f, + 0.994564571f, 0.104121634f, + 0.994723121f, 0.102595869f, + 0.994879331f, 0.101069863f, + 0.995033199f, 0.099543619f, + 0.995184727f, 0.098017140f, + 0.995333912f, 0.096490431f, + 0.995480755f, 0.094963495f, + 0.995625256f, 0.093436336f, + 0.995767414f, 0.091908956f, + 0.995907229f, 0.090381361f, + 0.996044701f, 0.088853553f, + 0.996179829f, 0.087325535f, + 0.996312612f, 0.085797312f, + 0.996443051f, 0.084268888f, + 0.996571146f, 0.082740265f, + 0.996696895f, 0.081211447f, + 0.996820299f, 0.079682438f, + 0.996941358f, 0.078153242f, + 0.997060070f, 0.076623861f, + 0.997176437f, 0.075094301f, + 0.997290457f, 0.073564564f, + 0.997402130f, 0.072034653f, + 0.997511456f, 0.070504573f, + 0.997618435f, 0.068974328f, + 0.997723067f, 0.067443920f, + 0.997825350f, 0.065913353f, + 0.997925286f, 0.064382631f, + 0.998022874f, 0.062851758f, + 0.998118113f, 0.061320736f, + 0.998211003f, 0.059789571f, + 0.998301545f, 0.058258265f, + 0.998389737f, 0.056726821f, + 0.998475581f, 0.055195244f, + 0.998559074f, 0.053663538f, + 0.998640218f, 0.052131705f, + 0.998719012f, 0.050599749f, + 0.998795456f, 0.049067674f, + 0.998869550f, 0.047535484f, + 0.998941293f, 0.046003182f, + 0.999010686f, 0.044470772f, + 0.999077728f, 0.042938257f, + 0.999142419f, 0.041405641f, + 0.999204759f, 0.039872928f, + 0.999264747f, 0.038340120f, + 0.999322385f, 0.036807223f, + 0.999377670f, 0.035274239f, + 0.999430605f, 0.033741172f, + 0.999481187f, 0.032208025f, + 0.999529418f, 0.030674803f, + 0.999575296f, 0.029141509f, + 0.999618822f, 0.027608146f, + 0.999659997f, 0.026074718f, + 0.999698819f, 0.024541229f, + 0.999735288f, 0.023007681f, + 0.999769405f, 0.021474080f, + 0.999801170f, 0.019940429f, + 0.999830582f, 0.018406730f, + 0.999857641f, 0.016872988f, + 0.999882347f, 0.015339206f, + 0.999904701f, 0.013805389f, + 0.999924702f, 0.012271538f, + 0.999942350f, 0.010737659f, + 0.999957645f, 0.009203755f, + 0.999970586f, 0.007669829f, + 0.999981175f, 0.006135885f, + 0.999989411f, 0.004601926f, + 0.999995294f, 0.003067957f, + 0.999998823f, 0.001533980f, + 1.000000000f, 0.000000000f, + 0.999998823f, -0.001533980f, + 0.999995294f, -0.003067957f, + 0.999989411f, -0.004601926f, + 0.999981175f, -0.006135885f, + 0.999970586f, -0.007669829f, + 0.999957645f, -0.009203755f, + 0.999942350f, -0.010737659f, + 0.999924702f, -0.012271538f, + 0.999904701f, -0.013805389f, + 0.999882347f, -0.015339206f, + 0.999857641f, -0.016872988f, + 0.999830582f, -0.018406730f, + 0.999801170f, -0.019940429f, + 0.999769405f, -0.021474080f, + 0.999735288f, -0.023007681f, + 0.999698819f, -0.024541229f, + 0.999659997f, -0.026074718f, + 0.999618822f, -0.027608146f, + 0.999575296f, -0.029141509f, + 0.999529418f, -0.030674803f, + 0.999481187f, -0.032208025f, + 0.999430605f, -0.033741172f, + 0.999377670f, -0.035274239f, + 0.999322385f, -0.036807223f, + 0.999264747f, -0.038340120f, + 0.999204759f, -0.039872928f, + 0.999142419f, -0.041405641f, + 0.999077728f, -0.042938257f, + 0.999010686f, -0.044470772f, + 0.998941293f, -0.046003182f, + 0.998869550f, -0.047535484f, + 0.998795456f, -0.049067674f, + 0.998719012f, -0.050599749f, + 0.998640218f, -0.052131705f, + 0.998559074f, -0.053663538f, + 0.998475581f, -0.055195244f, + 0.998389737f, -0.056726821f, + 0.998301545f, -0.058258265f, + 0.998211003f, -0.059789571f, + 0.998118113f, -0.061320736f, + 0.998022874f, -0.062851758f, + 0.997925286f, -0.064382631f, + 0.997825350f, -0.065913353f, + 0.997723067f, -0.067443920f, + 0.997618435f, -0.068974328f, + 0.997511456f, -0.070504573f, + 0.997402130f, -0.072034653f, + 0.997290457f, -0.073564564f, + 0.997176437f, -0.075094301f, + 0.997060070f, -0.076623861f, + 0.996941358f, -0.078153242f, + 0.996820299f, -0.079682438f, + 0.996696895f, -0.081211447f, + 0.996571146f, -0.082740265f, + 0.996443051f, -0.084268888f, + 0.996312612f, -0.085797312f, + 0.996179829f, -0.087325535f, + 0.996044701f, -0.088853553f, + 0.995907229f, -0.090381361f, + 0.995767414f, -0.091908956f, + 0.995625256f, -0.093436336f, + 0.995480755f, -0.094963495f, + 0.995333912f, -0.096490431f, + 0.995184727f, -0.098017140f, + 0.995033199f, -0.099543619f, + 0.994879331f, -0.101069863f, + 0.994723121f, -0.102595869f, + 0.994564571f, -0.104121634f, + 0.994403680f, -0.105647154f, + 0.994240449f, -0.107172425f, + 0.994074879f, -0.108697444f, + 0.993906970f, -0.110222207f, + 0.993736722f, -0.111746711f, + 0.993564136f, -0.113270952f, + 0.993389211f, -0.114794927f, + 0.993211949f, -0.116318631f, + 0.993032350f, -0.117842062f, + 0.992850414f, -0.119365215f, + 0.992666142f, -0.120888087f, + 0.992479535f, -0.122410675f, + 0.992290591f, -0.123932975f, + 0.992099313f, -0.125454983f, + 0.991905700f, -0.126976696f, + 0.991709754f, -0.128498111f, + 0.991511473f, -0.130019223f, + 0.991310860f, -0.131540029f, + 0.991107914f, -0.133060525f, + 0.990902635f, -0.134580709f, + 0.990695025f, -0.136100575f, + 0.990485084f, -0.137620122f, + 0.990272812f, -0.139139344f, + 0.990058210f, -0.140658239f, + 0.989841278f, -0.142176804f, + 0.989622017f, -0.143695033f, + 0.989400428f, -0.145212925f, + 0.989176510f, -0.146730474f, + 0.988950265f, -0.148247679f, + 0.988721692f, -0.149764535f, + 0.988490793f, -0.151281038f, + 0.988257568f, -0.152797185f, + 0.988022017f, -0.154312973f, + 0.987784142f, -0.155828398f, + 0.987543942f, -0.157343456f, + 0.987301418f, -0.158858143f, + 0.987056571f, -0.160372457f, + 0.986809402f, -0.161886394f, + 0.986559910f, -0.163399949f, + 0.986308097f, -0.164913120f, + 0.986053963f, -0.166425904f, + 0.985797509f, -0.167938295f, + 0.985538735f, -0.169450291f, + 0.985277642f, -0.170961889f, + 0.985014231f, -0.172473084f, + 0.984748502f, -0.173983873f, + 0.984480455f, -0.175494253f, + 0.984210092f, -0.177004220f, + 0.983937413f, -0.178513771f, + 0.983662419f, -0.180022901f, + 0.983385110f, -0.181531608f, + 0.983105487f, -0.183039888f, + 0.982823551f, -0.184547737f, + 0.982539302f, -0.186055152f, + 0.982252741f, -0.187562129f, + 0.981963869f, -0.189068664f, + 0.981672686f, -0.190574755f, + 0.981379193f, -0.192080397f, + 0.981083391f, -0.193585587f, + 0.980785280f, -0.195090322f, + 0.980484862f, -0.196594598f, + 0.980182136f, -0.198098411f, + 0.979877104f, -0.199601758f, + 0.979569766f, -0.201104635f, + 0.979260123f, -0.202607039f, + 0.978948175f, -0.204108966f, + 0.978633924f, -0.205610413f, + 0.978317371f, -0.207111376f, + 0.977998515f, -0.208611852f, + 0.977677358f, -0.210111837f, + 0.977353900f, -0.211611327f, + 0.977028143f, -0.213110320f, + 0.976700086f, -0.214608811f, + 0.976369731f, -0.216106797f, + 0.976037079f, -0.217604275f, + 0.975702130f, -0.219101240f, + 0.975364885f, -0.220597690f, + 0.975025345f, -0.222093621f, + 0.974683511f, -0.223589029f, + 0.974339383f, -0.225083911f, + 0.973992962f, -0.226578264f, + 0.973644250f, -0.228072083f, + 0.973293246f, -0.229565366f, + 0.972939952f, -0.231058108f, + 0.972584369f, -0.232550307f, + 0.972226497f, -0.234041959f, + 0.971866337f, -0.235533059f, + 0.971503891f, -0.237023606f, + 0.971139158f, -0.238513595f, + 0.970772141f, -0.240003022f, + 0.970402839f, -0.241491885f, + 0.970031253f, -0.242980180f, + 0.969657385f, -0.244467903f, + 0.969281235f, -0.245955050f, + 0.968902805f, -0.247441619f, + 0.968522094f, -0.248927606f, + 0.968139105f, -0.250413007f, + 0.967753837f, -0.251897818f, + 0.967366292f, -0.253382037f, + 0.966976471f, -0.254865660f, + 0.966584374f, -0.256348682f, + 0.966190003f, -0.257831102f, + 0.965793359f, -0.259312915f, + 0.965394442f, -0.260794118f, + 0.964993253f, -0.262274707f, + 0.964589793f, -0.263754679f, + 0.964184064f, -0.265234030f, + 0.963776066f, -0.266712757f, + 0.963365800f, -0.268190857f, + 0.962953267f, -0.269668326f, + 0.962538468f, -0.271145160f, + 0.962121404f, -0.272621355f, + 0.961702077f, -0.274096910f, + 0.961280486f, -0.275571819f, + 0.960856633f, -0.277046080f, + 0.960430519f, -0.278519689f, + 0.960002146f, -0.279992643f, + 0.959571513f, -0.281464938f, + 0.959138622f, -0.282936570f, + 0.958703475f, -0.284407537f, + 0.958266071f, -0.285877835f, + 0.957826413f, -0.287347460f, + 0.957384501f, -0.288816408f, + 0.956940336f, -0.290284677f, + 0.956493919f, -0.291752263f, + 0.956045251f, -0.293219163f, + 0.955594334f, -0.294685372f, + 0.955141168f, -0.296150888f, + 0.954685755f, -0.297615707f, + 0.954228095f, -0.299079826f, + 0.953768190f, -0.300543241f, + 0.953306040f, -0.302005949f, + 0.952841648f, -0.303467947f, + 0.952375013f, -0.304929230f, + 0.951906137f, -0.306389795f, + 0.951435021f, -0.307849640f, + 0.950961666f, -0.309308760f, + 0.950486074f, -0.310767153f, + 0.950008245f, -0.312224814f, + 0.949528181f, -0.313681740f, + 0.949045882f, -0.315137929f, + 0.948561350f, -0.316593376f, + 0.948074586f, -0.318048077f, + 0.947585591f, -0.319502031f, + 0.947094366f, -0.320955232f, + 0.946600913f, -0.322407679f, + 0.946105232f, -0.323859367f, + 0.945607325f, -0.325310292f, + 0.945107193f, -0.326760452f, + 0.944604837f, -0.328209844f, + 0.944100258f, -0.329658463f, + 0.943593458f, -0.331106306f, + 0.943084437f, -0.332553370f, + 0.942573198f, -0.333999651f, + 0.942059740f, -0.335445147f, + 0.941544065f, -0.336889853f, + 0.941026175f, -0.338333767f, + 0.940506071f, -0.339776884f, + 0.939983753f, -0.341219202f, + 0.939459224f, -0.342660717f, + 0.938932484f, -0.344101426f, + 0.938403534f, -0.345541325f, + 0.937872376f, -0.346980411f, + 0.937339012f, -0.348418680f, + 0.936803442f, -0.349856130f, + 0.936265667f, -0.351292756f, + 0.935725689f, -0.352728556f, + 0.935183510f, -0.354163525f, + 0.934639130f, -0.355597662f, + 0.934092550f, -0.357030961f, + 0.933543773f, -0.358463421f, + 0.932992799f, -0.359895037f, + 0.932439629f, -0.361325806f, + 0.931884266f, -0.362755724f, + 0.931326709f, -0.364184790f, + 0.930766961f, -0.365612998f, + 0.930205023f, -0.367040346f, + 0.929640896f, -0.368466830f, + 0.929074581f, -0.369892447f, + 0.928506080f, -0.371317194f, + 0.927935395f, -0.372741067f, + 0.927362526f, -0.374164063f, + 0.926787474f, -0.375586178f, + 0.926210242f, -0.377007410f, + 0.925630831f, -0.378427755f, + 0.925049241f, -0.379847209f, + 0.924465474f, -0.381265769f, + 0.923879533f, -0.382683432f, + 0.923291417f, -0.384100195f, + 0.922701128f, -0.385516054f, + 0.922108669f, -0.386931006f, + 0.921514039f, -0.388345047f, + 0.920917242f, -0.389758174f, + 0.920318277f, -0.391170384f, + 0.919717146f, -0.392581674f, + 0.919113852f, -0.393992040f, + 0.918508394f, -0.395401479f, + 0.917900776f, -0.396809987f, + 0.917290997f, -0.398217562f, + 0.916679060f, -0.399624200f, + 0.916064966f, -0.401029897f, + 0.915448716f, -0.402434651f, + 0.914830312f, -0.403838458f, + 0.914209756f, -0.405241314f, + 0.913587048f, -0.406643217f, + 0.912962190f, -0.408044163f, + 0.912335185f, -0.409444149f, + 0.911706032f, -0.410843171f, + 0.911074734f, -0.412241227f, + 0.910441292f, -0.413638312f, + 0.909805708f, -0.415034424f, + 0.909167983f, -0.416429560f, + 0.908528119f, -0.417823716f, + 0.907886116f, -0.419216888f, + 0.907241978f, -0.420609074f, + 0.906595705f, -0.422000271f, + 0.905947298f, -0.423390474f, + 0.905296759f, -0.424779681f, + 0.904644091f, -0.426167889f, + 0.903989293f, -0.427555093f, + 0.903332368f, -0.428941292f, + 0.902673318f, -0.430326481f, + 0.902012144f, -0.431710658f, + 0.901348847f, -0.433093819f, + 0.900683429f, -0.434475961f, + 0.900015892f, -0.435857080f, + 0.899346237f, -0.437237174f, + 0.898674466f, -0.438616239f, + 0.898000580f, -0.439994271f, + 0.897324581f, -0.441371269f, + 0.896646470f, -0.442747228f, + 0.895966250f, -0.444122145f, + 0.895283921f, -0.445496017f, + 0.894599486f, -0.446868840f, + 0.893912945f, -0.448240612f, + 0.893224301f, -0.449611330f, + 0.892533555f, -0.450980989f, + 0.891840709f, -0.452349587f, + 0.891145765f, -0.453717121f, + 0.890448723f, -0.455083587f, + 0.889749586f, -0.456448982f, + 0.889048356f, -0.457813304f, + 0.888345033f, -0.459176548f, + 0.887639620f, -0.460538711f, + 0.886932119f, -0.461899791f, + 0.886222530f, -0.463259784f, + 0.885510856f, -0.464618686f, + 0.884797098f, -0.465976496f, + 0.884081259f, -0.467333209f, + 0.883363339f, -0.468688822f, + 0.882643340f, -0.470043332f, + 0.881921264f, -0.471396737f, + 0.881197113f, -0.472749032f, + 0.880470889f, -0.474100215f, + 0.879742593f, -0.475450282f, + 0.879012226f, -0.476799230f, + 0.878279792f, -0.478147056f, + 0.877545290f, -0.479493758f, + 0.876808724f, -0.480839331f, + 0.876070094f, -0.482183772f, + 0.875329403f, -0.483527079f, + 0.874586652f, -0.484869248f, + 0.873841843f, -0.486210276f, + 0.873094978f, -0.487550160f, + 0.872346059f, -0.488888897f, + 0.871595087f, -0.490226483f, + 0.870842063f, -0.491562916f, + 0.870086991f, -0.492898192f, + 0.869329871f, -0.494232309f, + 0.868570706f, -0.495565262f, + 0.867809497f, -0.496897049f, + 0.867046246f, -0.498227667f, + 0.866280954f, -0.499557113f, + 0.865513624f, -0.500885383f, + 0.864744258f, -0.502212474f, + 0.863972856f, -0.503538384f, + 0.863199422f, -0.504863109f, + 0.862423956f, -0.506186645f, + 0.861646461f, -0.507508991f, + 0.860866939f, -0.508830143f, + 0.860085390f, -0.510150097f, + 0.859301818f, -0.511468850f, + 0.858516224f, -0.512786401f, + 0.857728610f, -0.514102744f, + 0.856938977f, -0.515417878f, + 0.856147328f, -0.516731799f, + 0.855353665f, -0.518044504f, + 0.854557988f, -0.519355990f, + 0.853760301f, -0.520666254f, + 0.852960605f, -0.521975293f, + 0.852158902f, -0.523283103f, + 0.851355193f, -0.524589683f, + 0.850549481f, -0.525895027f, + 0.849741768f, -0.527199135f, + 0.848932055f, -0.528502002f, + 0.848120345f, -0.529803625f, + 0.847306639f, -0.531104001f, + 0.846490939f, -0.532403128f, + 0.845673247f, -0.533701002f, + 0.844853565f, -0.534997620f, + 0.844031895f, -0.536292979f, + 0.843208240f, -0.537587076f, + 0.842382600f, -0.538879909f, + 0.841554977f, -0.540171473f, + 0.840725375f, -0.541461766f, + 0.839893794f, -0.542750785f, + 0.839060237f, -0.544038527f, + 0.838224706f, -0.545324988f, + 0.837387202f, -0.546610167f, + 0.836547727f, -0.547894059f, + 0.835706284f, -0.549176662f, + 0.834862875f, -0.550457973f, + 0.834017501f, -0.551737988f, + 0.833170165f, -0.553016706f, + 0.832320868f, -0.554294121f, + 0.831469612f, -0.555570233f, + 0.830616400f, -0.556845037f, + 0.829761234f, -0.558118531f, + 0.828904115f, -0.559390712f, + 0.828045045f, -0.560661576f, + 0.827184027f, -0.561931121f, + 0.826321063f, -0.563199344f, + 0.825456154f, -0.564466242f, + 0.824589303f, -0.565731811f, + 0.823720511f, -0.566996049f, + 0.822849781f, -0.568258953f, + 0.821977115f, -0.569520519f, + 0.821102515f, -0.570780746f, + 0.820225983f, -0.572039629f, + 0.819347520f, -0.573297167f, + 0.818467130f, -0.574553355f, + 0.817584813f, -0.575808191f, + 0.816700573f, -0.577061673f, + 0.815814411f, -0.578313796f, + 0.814926329f, -0.579564559f, + 0.814036330f, -0.580813958f, + 0.813144415f, -0.582061990f, + 0.812250587f, -0.583308653f, + 0.811354847f, -0.584553943f, + 0.810457198f, -0.585797857f, + 0.809557642f, -0.587040394f, + 0.808656182f, -0.588281548f, + 0.807752818f, -0.589521319f, + 0.806847554f, -0.590759702f, + 0.805940391f, -0.591996695f, + 0.805031331f, -0.593232295f, + 0.804120377f, -0.594466499f, + 0.803207531f, -0.595699304f, + 0.802292796f, -0.596930708f, + 0.801376172f, -0.598160707f, + 0.800457662f, -0.599389298f, + 0.799537269f, -0.600616479f, + 0.798614995f, -0.601842247f, + 0.797690841f, -0.603066599f, + 0.796764810f, -0.604289531f, + 0.795836905f, -0.605511041f, + 0.794907126f, -0.606731127f, + 0.793975478f, -0.607949785f, + 0.793041960f, -0.609167012f, + 0.792106577f, -0.610382806f, + 0.791169330f, -0.611597164f, + 0.790230221f, -0.612810082f, + 0.789289253f, -0.614021559f, + 0.788346428f, -0.615231591f, + 0.787401747f, -0.616440175f, + 0.786455214f, -0.617647308f, + 0.785506830f, -0.618852988f, + 0.784556597f, -0.620057212f, + 0.783604519f, -0.621259977f, + 0.782650596f, -0.622461279f, + 0.781694832f, -0.623661118f, + 0.780737229f, -0.624859488f, + 0.779777788f, -0.626056388f, + 0.778816512f, -0.627251815f, + 0.777853404f, -0.628445767f, + 0.776888466f, -0.629638239f, + 0.775921699f, -0.630829230f, + 0.774953107f, -0.632018736f, + 0.773982691f, -0.633206755f, + 0.773010453f, -0.634393284f, + 0.772036397f, -0.635578320f, + 0.771060524f, -0.636761861f, + 0.770082837f, -0.637943904f, + 0.769103338f, -0.639124445f, + 0.768122029f, -0.640303482f, + 0.767138912f, -0.641481013f, + 0.766153990f, -0.642657034f, + 0.765167266f, -0.643831543f, + 0.764178741f, -0.645004537f, + 0.763188417f, -0.646176013f, + 0.762196298f, -0.647345969f, + 0.761202385f, -0.648514401f, + 0.760206682f, -0.649681307f, + 0.759209189f, -0.650846685f, + 0.758209910f, -0.652010531f, + 0.757208847f, -0.653172843f, + 0.756206001f, -0.654333618f, + 0.755201377f, -0.655492853f, + 0.754194975f, -0.656650546f, + 0.753186799f, -0.657806693f, + 0.752176850f, -0.658961293f, + 0.751165132f, -0.660114342f, + 0.750151646f, -0.661265838f, + 0.749136395f, -0.662415778f, + 0.748119380f, -0.663564159f, + 0.747100606f, -0.664710978f, + 0.746080074f, -0.665856234f, + 0.745057785f, -0.666999922f, + 0.744033744f, -0.668142041f, + 0.743007952f, -0.669282588f, + 0.741980412f, -0.670421560f, + 0.740951125f, -0.671558955f, + 0.739920095f, -0.672694769f, + 0.738887324f, -0.673829000f, + 0.737852815f, -0.674961646f, + 0.736816569f, -0.676092704f, + 0.735778589f, -0.677222170f, + 0.734738878f, -0.678350043f, + 0.733697438f, -0.679476320f, + 0.732654272f, -0.680600998f, + 0.731609381f, -0.681724074f, + 0.730562769f, -0.682845546f, + 0.729514438f, -0.683965412f, + 0.728464390f, -0.685083668f, + 0.727412629f, -0.686200312f, + 0.726359155f, -0.687315341f, + 0.725303972f, -0.688428753f, + 0.724247083f, -0.689540545f, + 0.723188489f, -0.690650714f, + 0.722128194f, -0.691759258f, + 0.721066199f, -0.692866175f, + 0.720002508f, -0.693971461f, + 0.718937122f, -0.695075114f, + 0.717870045f, -0.696177131f, + 0.716801279f, -0.697277511f, + 0.715730825f, -0.698376249f, + 0.714658688f, -0.699473345f, + 0.713584869f, -0.700568794f, + 0.712509371f, -0.701662595f, + 0.711432196f, -0.702754744f, + 0.710353347f, -0.703845241f, + 0.709272826f, -0.704934080f, + 0.708190637f, -0.706021261f, + 0.707106781f, -0.707106781f, + 0.706021261f, -0.708190637f, + 0.704934080f, -0.709272826f, + 0.703845241f, -0.710353347f, + 0.702754744f, -0.711432196f, + 0.701662595f, -0.712509371f, + 0.700568794f, -0.713584869f, + 0.699473345f, -0.714658688f, + 0.698376249f, -0.715730825f, + 0.697277511f, -0.716801279f, + 0.696177131f, -0.717870045f, + 0.695075114f, -0.718937122f, + 0.693971461f, -0.720002508f, + 0.692866175f, -0.721066199f, + 0.691759258f, -0.722128194f, + 0.690650714f, -0.723188489f, + 0.689540545f, -0.724247083f, + 0.688428753f, -0.725303972f, + 0.687315341f, -0.726359155f, + 0.686200312f, -0.727412629f, + 0.685083668f, -0.728464390f, + 0.683965412f, -0.729514438f, + 0.682845546f, -0.730562769f, + 0.681724074f, -0.731609381f, + 0.680600998f, -0.732654272f, + 0.679476320f, -0.733697438f, + 0.678350043f, -0.734738878f, + 0.677222170f, -0.735778589f, + 0.676092704f, -0.736816569f, + 0.674961646f, -0.737852815f, + 0.673829000f, -0.738887324f, + 0.672694769f, -0.739920095f, + 0.671558955f, -0.740951125f, + 0.670421560f, -0.741980412f, + 0.669282588f, -0.743007952f, + 0.668142041f, -0.744033744f, + 0.666999922f, -0.745057785f, + 0.665856234f, -0.746080074f, + 0.664710978f, -0.747100606f, + 0.663564159f, -0.748119380f, + 0.662415778f, -0.749136395f, + 0.661265838f, -0.750151646f, + 0.660114342f, -0.751165132f, + 0.658961293f, -0.752176850f, + 0.657806693f, -0.753186799f, + 0.656650546f, -0.754194975f, + 0.655492853f, -0.755201377f, + 0.654333618f, -0.756206001f, + 0.653172843f, -0.757208847f, + 0.652010531f, -0.758209910f, + 0.650846685f, -0.759209189f, + 0.649681307f, -0.760206682f, + 0.648514401f, -0.761202385f, + 0.647345969f, -0.762196298f, + 0.646176013f, -0.763188417f, + 0.645004537f, -0.764178741f, + 0.643831543f, -0.765167266f, + 0.642657034f, -0.766153990f, + 0.641481013f, -0.767138912f, + 0.640303482f, -0.768122029f, + 0.639124445f, -0.769103338f, + 0.637943904f, -0.770082837f, + 0.636761861f, -0.771060524f, + 0.635578320f, -0.772036397f, + 0.634393284f, -0.773010453f, + 0.633206755f, -0.773982691f, + 0.632018736f, -0.774953107f, + 0.630829230f, -0.775921699f, + 0.629638239f, -0.776888466f, + 0.628445767f, -0.777853404f, + 0.627251815f, -0.778816512f, + 0.626056388f, -0.779777788f, + 0.624859488f, -0.780737229f, + 0.623661118f, -0.781694832f, + 0.622461279f, -0.782650596f, + 0.621259977f, -0.783604519f, + 0.620057212f, -0.784556597f, + 0.618852988f, -0.785506830f, + 0.617647308f, -0.786455214f, + 0.616440175f, -0.787401747f, + 0.615231591f, -0.788346428f, + 0.614021559f, -0.789289253f, + 0.612810082f, -0.790230221f, + 0.611597164f, -0.791169330f, + 0.610382806f, -0.792106577f, + 0.609167012f, -0.793041960f, + 0.607949785f, -0.793975478f, + 0.606731127f, -0.794907126f, + 0.605511041f, -0.795836905f, + 0.604289531f, -0.796764810f, + 0.603066599f, -0.797690841f, + 0.601842247f, -0.798614995f, + 0.600616479f, -0.799537269f, + 0.599389298f, -0.800457662f, + 0.598160707f, -0.801376172f, + 0.596930708f, -0.802292796f, + 0.595699304f, -0.803207531f, + 0.594466499f, -0.804120377f, + 0.593232295f, -0.805031331f, + 0.591996695f, -0.805940391f, + 0.590759702f, -0.806847554f, + 0.589521319f, -0.807752818f, + 0.588281548f, -0.808656182f, + 0.587040394f, -0.809557642f, + 0.585797857f, -0.810457198f, + 0.584553943f, -0.811354847f, + 0.583308653f, -0.812250587f, + 0.582061990f, -0.813144415f, + 0.580813958f, -0.814036330f, + 0.579564559f, -0.814926329f, + 0.578313796f, -0.815814411f, + 0.577061673f, -0.816700573f, + 0.575808191f, -0.817584813f, + 0.574553355f, -0.818467130f, + 0.573297167f, -0.819347520f, + 0.572039629f, -0.820225983f, + 0.570780746f, -0.821102515f, + 0.569520519f, -0.821977115f, + 0.568258953f, -0.822849781f, + 0.566996049f, -0.823720511f, + 0.565731811f, -0.824589303f, + 0.564466242f, -0.825456154f, + 0.563199344f, -0.826321063f, + 0.561931121f, -0.827184027f, + 0.560661576f, -0.828045045f, + 0.559390712f, -0.828904115f, + 0.558118531f, -0.829761234f, + 0.556845037f, -0.830616400f, + 0.555570233f, -0.831469612f, + 0.554294121f, -0.832320868f, + 0.553016706f, -0.833170165f, + 0.551737988f, -0.834017501f, + 0.550457973f, -0.834862875f, + 0.549176662f, -0.835706284f, + 0.547894059f, -0.836547727f, + 0.546610167f, -0.837387202f, + 0.545324988f, -0.838224706f, + 0.544038527f, -0.839060237f, + 0.542750785f, -0.839893794f, + 0.541461766f, -0.840725375f, + 0.540171473f, -0.841554977f, + 0.538879909f, -0.842382600f, + 0.537587076f, -0.843208240f, + 0.536292979f, -0.844031895f, + 0.534997620f, -0.844853565f, + 0.533701002f, -0.845673247f, + 0.532403128f, -0.846490939f, + 0.531104001f, -0.847306639f, + 0.529803625f, -0.848120345f, + 0.528502002f, -0.848932055f, + 0.527199135f, -0.849741768f, + 0.525895027f, -0.850549481f, + 0.524589683f, -0.851355193f, + 0.523283103f, -0.852158902f, + 0.521975293f, -0.852960605f, + 0.520666254f, -0.853760301f, + 0.519355990f, -0.854557988f, + 0.518044504f, -0.855353665f, + 0.516731799f, -0.856147328f, + 0.515417878f, -0.856938977f, + 0.514102744f, -0.857728610f, + 0.512786401f, -0.858516224f, + 0.511468850f, -0.859301818f, + 0.510150097f, -0.860085390f, + 0.508830143f, -0.860866939f, + 0.507508991f, -0.861646461f, + 0.506186645f, -0.862423956f, + 0.504863109f, -0.863199422f, + 0.503538384f, -0.863972856f, + 0.502212474f, -0.864744258f, + 0.500885383f, -0.865513624f, + 0.499557113f, -0.866280954f, + 0.498227667f, -0.867046246f, + 0.496897049f, -0.867809497f, + 0.495565262f, -0.868570706f, + 0.494232309f, -0.869329871f, + 0.492898192f, -0.870086991f, + 0.491562916f, -0.870842063f, + 0.490226483f, -0.871595087f, + 0.488888897f, -0.872346059f, + 0.487550160f, -0.873094978f, + 0.486210276f, -0.873841843f, + 0.484869248f, -0.874586652f, + 0.483527079f, -0.875329403f, + 0.482183772f, -0.876070094f, + 0.480839331f, -0.876808724f, + 0.479493758f, -0.877545290f, + 0.478147056f, -0.878279792f, + 0.476799230f, -0.879012226f, + 0.475450282f, -0.879742593f, + 0.474100215f, -0.880470889f, + 0.472749032f, -0.881197113f, + 0.471396737f, -0.881921264f, + 0.470043332f, -0.882643340f, + 0.468688822f, -0.883363339f, + 0.467333209f, -0.884081259f, + 0.465976496f, -0.884797098f, + 0.464618686f, -0.885510856f, + 0.463259784f, -0.886222530f, + 0.461899791f, -0.886932119f, + 0.460538711f, -0.887639620f, + 0.459176548f, -0.888345033f, + 0.457813304f, -0.889048356f, + 0.456448982f, -0.889749586f, + 0.455083587f, -0.890448723f, + 0.453717121f, -0.891145765f, + 0.452349587f, -0.891840709f, + 0.450980989f, -0.892533555f, + 0.449611330f, -0.893224301f, + 0.448240612f, -0.893912945f, + 0.446868840f, -0.894599486f, + 0.445496017f, -0.895283921f, + 0.444122145f, -0.895966250f, + 0.442747228f, -0.896646470f, + 0.441371269f, -0.897324581f, + 0.439994271f, -0.898000580f, + 0.438616239f, -0.898674466f, + 0.437237174f, -0.899346237f, + 0.435857080f, -0.900015892f, + 0.434475961f, -0.900683429f, + 0.433093819f, -0.901348847f, + 0.431710658f, -0.902012144f, + 0.430326481f, -0.902673318f, + 0.428941292f, -0.903332368f, + 0.427555093f, -0.903989293f, + 0.426167889f, -0.904644091f, + 0.424779681f, -0.905296759f, + 0.423390474f, -0.905947298f, + 0.422000271f, -0.906595705f, + 0.420609074f, -0.907241978f, + 0.419216888f, -0.907886116f, + 0.417823716f, -0.908528119f, + 0.416429560f, -0.909167983f, + 0.415034424f, -0.909805708f, + 0.413638312f, -0.910441292f, + 0.412241227f, -0.911074734f, + 0.410843171f, -0.911706032f, + 0.409444149f, -0.912335185f, + 0.408044163f, -0.912962190f, + 0.406643217f, -0.913587048f, + 0.405241314f, -0.914209756f, + 0.403838458f, -0.914830312f, + 0.402434651f, -0.915448716f, + 0.401029897f, -0.916064966f, + 0.399624200f, -0.916679060f, + 0.398217562f, -0.917290997f, + 0.396809987f, -0.917900776f, + 0.395401479f, -0.918508394f, + 0.393992040f, -0.919113852f, + 0.392581674f, -0.919717146f, + 0.391170384f, -0.920318277f, + 0.389758174f, -0.920917242f, + 0.388345047f, -0.921514039f, + 0.386931006f, -0.922108669f, + 0.385516054f, -0.922701128f, + 0.384100195f, -0.923291417f, + 0.382683432f, -0.923879533f, + 0.381265769f, -0.924465474f, + 0.379847209f, -0.925049241f, + 0.378427755f, -0.925630831f, + 0.377007410f, -0.926210242f, + 0.375586178f, -0.926787474f, + 0.374164063f, -0.927362526f, + 0.372741067f, -0.927935395f, + 0.371317194f, -0.928506080f, + 0.369892447f, -0.929074581f, + 0.368466830f, -0.929640896f, + 0.367040346f, -0.930205023f, + 0.365612998f, -0.930766961f, + 0.364184790f, -0.931326709f, + 0.362755724f, -0.931884266f, + 0.361325806f, -0.932439629f, + 0.359895037f, -0.932992799f, + 0.358463421f, -0.933543773f, + 0.357030961f, -0.934092550f, + 0.355597662f, -0.934639130f, + 0.354163525f, -0.935183510f, + 0.352728556f, -0.935725689f, + 0.351292756f, -0.936265667f, + 0.349856130f, -0.936803442f, + 0.348418680f, -0.937339012f, + 0.346980411f, -0.937872376f, + 0.345541325f, -0.938403534f, + 0.344101426f, -0.938932484f, + 0.342660717f, -0.939459224f, + 0.341219202f, -0.939983753f, + 0.339776884f, -0.940506071f, + 0.338333767f, -0.941026175f, + 0.336889853f, -0.941544065f, + 0.335445147f, -0.942059740f, + 0.333999651f, -0.942573198f, + 0.332553370f, -0.943084437f, + 0.331106306f, -0.943593458f, + 0.329658463f, -0.944100258f, + 0.328209844f, -0.944604837f, + 0.326760452f, -0.945107193f, + 0.325310292f, -0.945607325f, + 0.323859367f, -0.946105232f, + 0.322407679f, -0.946600913f, + 0.320955232f, -0.947094366f, + 0.319502031f, -0.947585591f, + 0.318048077f, -0.948074586f, + 0.316593376f, -0.948561350f, + 0.315137929f, -0.949045882f, + 0.313681740f, -0.949528181f, + 0.312224814f, -0.950008245f, + 0.310767153f, -0.950486074f, + 0.309308760f, -0.950961666f, + 0.307849640f, -0.951435021f, + 0.306389795f, -0.951906137f, + 0.304929230f, -0.952375013f, + 0.303467947f, -0.952841648f, + 0.302005949f, -0.953306040f, + 0.300543241f, -0.953768190f, + 0.299079826f, -0.954228095f, + 0.297615707f, -0.954685755f, + 0.296150888f, -0.955141168f, + 0.294685372f, -0.955594334f, + 0.293219163f, -0.956045251f, + 0.291752263f, -0.956493919f, + 0.290284677f, -0.956940336f, + 0.288816408f, -0.957384501f, + 0.287347460f, -0.957826413f, + 0.285877835f, -0.958266071f, + 0.284407537f, -0.958703475f, + 0.282936570f, -0.959138622f, + 0.281464938f, -0.959571513f, + 0.279992643f, -0.960002146f, + 0.278519689f, -0.960430519f, + 0.277046080f, -0.960856633f, + 0.275571819f, -0.961280486f, + 0.274096910f, -0.961702077f, + 0.272621355f, -0.962121404f, + 0.271145160f, -0.962538468f, + 0.269668326f, -0.962953267f, + 0.268190857f, -0.963365800f, + 0.266712757f, -0.963776066f, + 0.265234030f, -0.964184064f, + 0.263754679f, -0.964589793f, + 0.262274707f, -0.964993253f, + 0.260794118f, -0.965394442f, + 0.259312915f, -0.965793359f, + 0.257831102f, -0.966190003f, + 0.256348682f, -0.966584374f, + 0.254865660f, -0.966976471f, + 0.253382037f, -0.967366292f, + 0.251897818f, -0.967753837f, + 0.250413007f, -0.968139105f, + 0.248927606f, -0.968522094f, + 0.247441619f, -0.968902805f, + 0.245955050f, -0.969281235f, + 0.244467903f, -0.969657385f, + 0.242980180f, -0.970031253f, + 0.241491885f, -0.970402839f, + 0.240003022f, -0.970772141f, + 0.238513595f, -0.971139158f, + 0.237023606f, -0.971503891f, + 0.235533059f, -0.971866337f, + 0.234041959f, -0.972226497f, + 0.232550307f, -0.972584369f, + 0.231058108f, -0.972939952f, + 0.229565366f, -0.973293246f, + 0.228072083f, -0.973644250f, + 0.226578264f, -0.973992962f, + 0.225083911f, -0.974339383f, + 0.223589029f, -0.974683511f, + 0.222093621f, -0.975025345f, + 0.220597690f, -0.975364885f, + 0.219101240f, -0.975702130f, + 0.217604275f, -0.976037079f, + 0.216106797f, -0.976369731f, + 0.214608811f, -0.976700086f, + 0.213110320f, -0.977028143f, + 0.211611327f, -0.977353900f, + 0.210111837f, -0.977677358f, + 0.208611852f, -0.977998515f, + 0.207111376f, -0.978317371f, + 0.205610413f, -0.978633924f, + 0.204108966f, -0.978948175f, + 0.202607039f, -0.979260123f, + 0.201104635f, -0.979569766f, + 0.199601758f, -0.979877104f, + 0.198098411f, -0.980182136f, + 0.196594598f, -0.980484862f, + 0.195090322f, -0.980785280f, + 0.193585587f, -0.981083391f, + 0.192080397f, -0.981379193f, + 0.190574755f, -0.981672686f, + 0.189068664f, -0.981963869f, + 0.187562129f, -0.982252741f, + 0.186055152f, -0.982539302f, + 0.184547737f, -0.982823551f, + 0.183039888f, -0.983105487f, + 0.181531608f, -0.983385110f, + 0.180022901f, -0.983662419f, + 0.178513771f, -0.983937413f, + 0.177004220f, -0.984210092f, + 0.175494253f, -0.984480455f, + 0.173983873f, -0.984748502f, + 0.172473084f, -0.985014231f, + 0.170961889f, -0.985277642f, + 0.169450291f, -0.985538735f, + 0.167938295f, -0.985797509f, + 0.166425904f, -0.986053963f, + 0.164913120f, -0.986308097f, + 0.163399949f, -0.986559910f, + 0.161886394f, -0.986809402f, + 0.160372457f, -0.987056571f, + 0.158858143f, -0.987301418f, + 0.157343456f, -0.987543942f, + 0.155828398f, -0.987784142f, + 0.154312973f, -0.988022017f, + 0.152797185f, -0.988257568f, + 0.151281038f, -0.988490793f, + 0.149764535f, -0.988721692f, + 0.148247679f, -0.988950265f, + 0.146730474f, -0.989176510f, + 0.145212925f, -0.989400428f, + 0.143695033f, -0.989622017f, + 0.142176804f, -0.989841278f, + 0.140658239f, -0.990058210f, + 0.139139344f, -0.990272812f, + 0.137620122f, -0.990485084f, + 0.136100575f, -0.990695025f, + 0.134580709f, -0.990902635f, + 0.133060525f, -0.991107914f, + 0.131540029f, -0.991310860f, + 0.130019223f, -0.991511473f, + 0.128498111f, -0.991709754f, + 0.126976696f, -0.991905700f, + 0.125454983f, -0.992099313f, + 0.123932975f, -0.992290591f, + 0.122410675f, -0.992479535f, + 0.120888087f, -0.992666142f, + 0.119365215f, -0.992850414f, + 0.117842062f, -0.993032350f, + 0.116318631f, -0.993211949f, + 0.114794927f, -0.993389211f, + 0.113270952f, -0.993564136f, + 0.111746711f, -0.993736722f, + 0.110222207f, -0.993906970f, + 0.108697444f, -0.994074879f, + 0.107172425f, -0.994240449f, + 0.105647154f, -0.994403680f, + 0.104121634f, -0.994564571f, + 0.102595869f, -0.994723121f, + 0.101069863f, -0.994879331f, + 0.099543619f, -0.995033199f, + 0.098017140f, -0.995184727f, + 0.096490431f, -0.995333912f, + 0.094963495f, -0.995480755f, + 0.093436336f, -0.995625256f, + 0.091908956f, -0.995767414f, + 0.090381361f, -0.995907229f, + 0.088853553f, -0.996044701f, + 0.087325535f, -0.996179829f, + 0.085797312f, -0.996312612f, + 0.084268888f, -0.996443051f, + 0.082740265f, -0.996571146f, + 0.081211447f, -0.996696895f, + 0.079682438f, -0.996820299f, + 0.078153242f, -0.996941358f, + 0.076623861f, -0.997060070f, + 0.075094301f, -0.997176437f, + 0.073564564f, -0.997290457f, + 0.072034653f, -0.997402130f, + 0.070504573f, -0.997511456f, + 0.068974328f, -0.997618435f, + 0.067443920f, -0.997723067f, + 0.065913353f, -0.997825350f, + 0.064382631f, -0.997925286f, + 0.062851758f, -0.998022874f, + 0.061320736f, -0.998118113f, + 0.059789571f, -0.998211003f, + 0.058258265f, -0.998301545f, + 0.056726821f, -0.998389737f, + 0.055195244f, -0.998475581f, + 0.053663538f, -0.998559074f, + 0.052131705f, -0.998640218f, + 0.050599749f, -0.998719012f, + 0.049067674f, -0.998795456f, + 0.047535484f, -0.998869550f, + 0.046003182f, -0.998941293f, + 0.044470772f, -0.999010686f, + 0.042938257f, -0.999077728f, + 0.041405641f, -0.999142419f, + 0.039872928f, -0.999204759f, + 0.038340120f, -0.999264747f, + 0.036807223f, -0.999322385f, + 0.035274239f, -0.999377670f, + 0.033741172f, -0.999430605f, + 0.032208025f, -0.999481187f, + 0.030674803f, -0.999529418f, + 0.029141509f, -0.999575296f, + 0.027608146f, -0.999618822f, + 0.026074718f, -0.999659997f, + 0.024541229f, -0.999698819f, + 0.023007681f, -0.999735288f, + 0.021474080f, -0.999769405f, + 0.019940429f, -0.999801170f, + 0.018406730f, -0.999830582f, + 0.016872988f, -0.999857641f, + 0.015339206f, -0.999882347f, + 0.013805389f, -0.999904701f, + 0.012271538f, -0.999924702f, + 0.010737659f, -0.999942350f, + 0.009203755f, -0.999957645f, + 0.007669829f, -0.999970586f, + 0.006135885f, -0.999981175f, + 0.004601926f, -0.999989411f, + 0.003067957f, -0.999995294f, + 0.001533980f, -0.999998823f +}; + + +/** + @par + Example code for the generation of the floating-point sine table: +
+  tableSize = 512;
+  for (n = 0; n < (tableSize + 1); n++)
+  {
+ 	sinTable[n] = sin(2*PI*n/tableSize);
+  }
+ @par + where PI value is 3.14159265358979 + */ +const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1] = { + 0.00000000f, 0.01227154f, 0.02454123f, 0.03680722f, 0.04906767f, 0.06132074f, + 0.07356456f, 0.08579731f, 0.09801714f, 0.11022221f, 0.12241068f, 0.13458071f, + 0.14673047f, 0.15885814f, 0.17096189f, 0.18303989f, 0.19509032f, 0.20711138f, + 0.21910124f, 0.23105811f, 0.24298018f, 0.25486566f, 0.26671276f, 0.27851969f, + 0.29028468f, 0.30200595f, 0.31368174f, 0.32531029f, 0.33688985f, 0.34841868f, + 0.35989504f, 0.37131719f, 0.38268343f, 0.39399204f, 0.40524131f, 0.41642956f, + 0.42755509f, 0.43861624f, 0.44961133f, 0.46053871f, 0.47139674f, 0.48218377f, + 0.49289819f, 0.50353838f, 0.51410274f, 0.52458968f, 0.53499762f, 0.54532499f, + 0.55557023f, 0.56573181f, 0.57580819f, 0.58579786f, 0.59569930f, 0.60551104f, + 0.61523159f, 0.62485949f, 0.63439328f, 0.64383154f, 0.65317284f, 0.66241578f, + 0.67155895f, 0.68060100f, 0.68954054f, 0.69837625f, 0.70710678f, 0.71573083f, + 0.72424708f, 0.73265427f, 0.74095113f, 0.74913639f, 0.75720885f, 0.76516727f, + 0.77301045f, 0.78073723f, 0.78834643f, 0.79583690f, 0.80320753f, 0.81045720f, + 0.81758481f, 0.82458930f, 0.83146961f, 0.83822471f, 0.84485357f, 0.85135519f, + 0.85772861f, 0.86397286f, 0.87008699f, 0.87607009f, 0.88192126f, 0.88763962f, + 0.89322430f, 0.89867447f, 0.90398929f, 0.90916798f, 0.91420976f, 0.91911385f, + 0.92387953f, 0.92850608f, 0.93299280f, 0.93733901f, 0.94154407f, 0.94560733f, + 0.94952818f, 0.95330604f, 0.95694034f, 0.96043052f, 0.96377607f, 0.96697647f, + 0.97003125f, 0.97293995f, 0.97570213f, 0.97831737f, 0.98078528f, 0.98310549f, + 0.98527764f, 0.98730142f, 0.98917651f, 0.99090264f, 0.99247953f, 0.99390697f, + 0.99518473f, 0.99631261f, 0.99729046f, 0.99811811f, 0.99879546f, 0.99932238f, + 0.99969882f, 0.99992470f, 1.00000000f, 0.99992470f, 0.99969882f, 0.99932238f, + 0.99879546f, 0.99811811f, 0.99729046f, 0.99631261f, 0.99518473f, 0.99390697f, + 0.99247953f, 0.99090264f, 0.98917651f, 0.98730142f, 0.98527764f, 0.98310549f, + 0.98078528f, 0.97831737f, 0.97570213f, 0.97293995f, 0.97003125f, 0.96697647f, + 0.96377607f, 0.96043052f, 0.95694034f, 0.95330604f, 0.94952818f, 0.94560733f, + 0.94154407f, 0.93733901f, 0.93299280f, 0.92850608f, 0.92387953f, 0.91911385f, + 0.91420976f, 0.90916798f, 0.90398929f, 0.89867447f, 0.89322430f, 0.88763962f, + 0.88192126f, 0.87607009f, 0.87008699f, 0.86397286f, 0.85772861f, 0.85135519f, + 0.84485357f, 0.83822471f, 0.83146961f, 0.82458930f, 0.81758481f, 0.81045720f, + 0.80320753f, 0.79583690f, 0.78834643f, 0.78073723f, 0.77301045f, 0.76516727f, + 0.75720885f, 0.74913639f, 0.74095113f, 0.73265427f, 0.72424708f, 0.71573083f, + 0.70710678f, 0.69837625f, 0.68954054f, 0.68060100f, 0.67155895f, 0.66241578f, + 0.65317284f, 0.64383154f, 0.63439328f, 0.62485949f, 0.61523159f, 0.60551104f, + 0.59569930f, 0.58579786f, 0.57580819f, 0.56573181f, 0.55557023f, 0.54532499f, + 0.53499762f, 0.52458968f, 0.51410274f, 0.50353838f, 0.49289819f, 0.48218377f, + 0.47139674f, 0.46053871f, 0.44961133f, 0.43861624f, 0.42755509f, 0.41642956f, + 0.40524131f, 0.39399204f, 0.38268343f, 0.37131719f, 0.35989504f, 0.34841868f, + 0.33688985f, 0.32531029f, 0.31368174f, 0.30200595f, 0.29028468f, 0.27851969f, + 0.26671276f, 0.25486566f, 0.24298018f, 0.23105811f, 0.21910124f, 0.20711138f, + 0.19509032f, 0.18303989f, 0.17096189f, 0.15885814f, 0.14673047f, 0.13458071f, + 0.12241068f, 0.11022221f, 0.09801714f, 0.08579731f, 0.07356456f, 0.06132074f, + 0.04906767f, 0.03680722f, 0.02454123f, 0.01227154f, 0.00000000f, -0.01227154f, + -0.02454123f, -0.03680722f, -0.04906767f, -0.06132074f, -0.07356456f, + -0.08579731f, -0.09801714f, -0.11022221f, -0.12241068f, -0.13458071f, + -0.14673047f, -0.15885814f, -0.17096189f, -0.18303989f, -0.19509032f, + -0.20711138f, -0.21910124f, -0.23105811f, -0.24298018f, -0.25486566f, + -0.26671276f, -0.27851969f, -0.29028468f, -0.30200595f, -0.31368174f, + -0.32531029f, -0.33688985f, -0.34841868f, -0.35989504f, -0.37131719f, + -0.38268343f, -0.39399204f, -0.40524131f, -0.41642956f, -0.42755509f, + -0.43861624f, -0.44961133f, -0.46053871f, -0.47139674f, -0.48218377f, + -0.49289819f, -0.50353838f, -0.51410274f, -0.52458968f, -0.53499762f, + -0.54532499f, -0.55557023f, -0.56573181f, -0.57580819f, -0.58579786f, + -0.59569930f, -0.60551104f, -0.61523159f, -0.62485949f, -0.63439328f, + -0.64383154f, -0.65317284f, -0.66241578f, -0.67155895f, -0.68060100f, + -0.68954054f, -0.69837625f, -0.70710678f, -0.71573083f, -0.72424708f, + -0.73265427f, -0.74095113f, -0.74913639f, -0.75720885f, -0.76516727f, + -0.77301045f, -0.78073723f, -0.78834643f, -0.79583690f, -0.80320753f, + -0.81045720f, -0.81758481f, -0.82458930f, -0.83146961f, -0.83822471f, + -0.84485357f, -0.85135519f, -0.85772861f, -0.86397286f, -0.87008699f, + -0.87607009f, -0.88192126f, -0.88763962f, -0.89322430f, -0.89867447f, + -0.90398929f, -0.90916798f, -0.91420976f, -0.91911385f, -0.92387953f, + -0.92850608f, -0.93299280f, -0.93733901f, -0.94154407f, -0.94560733f, + -0.94952818f, -0.95330604f, -0.95694034f, -0.96043052f, -0.96377607f, + -0.96697647f, -0.97003125f, -0.97293995f, -0.97570213f, -0.97831737f, + -0.98078528f, -0.98310549f, -0.98527764f, -0.98730142f, -0.98917651f, + -0.99090264f, -0.99247953f, -0.99390697f, -0.99518473f, -0.99631261f, + -0.99729046f, -0.99811811f, -0.99879546f, -0.99932238f, -0.99969882f, + -0.99992470f, -1.00000000f, -0.99992470f, -0.99969882f, -0.99932238f, + -0.99879546f, -0.99811811f, -0.99729046f, -0.99631261f, -0.99518473f, + -0.99390697f, -0.99247953f, -0.99090264f, -0.98917651f, -0.98730142f, + -0.98527764f, -0.98310549f, -0.98078528f, -0.97831737f, -0.97570213f, + -0.97293995f, -0.97003125f, -0.96697647f, -0.96377607f, -0.96043052f, + -0.95694034f, -0.95330604f, -0.94952818f, -0.94560733f, -0.94154407f, + -0.93733901f, -0.93299280f, -0.92850608f, -0.92387953f, -0.91911385f, + -0.91420976f, -0.90916798f, -0.90398929f, -0.89867447f, -0.89322430f, + -0.88763962f, -0.88192126f, -0.87607009f, -0.87008699f, -0.86397286f, + -0.85772861f, -0.85135519f, -0.84485357f, -0.83822471f, -0.83146961f, + -0.82458930f, -0.81758481f, -0.81045720f, -0.80320753f, -0.79583690f, + -0.78834643f, -0.78073723f, -0.77301045f, -0.76516727f, -0.75720885f, + -0.74913639f, -0.74095113f, -0.73265427f, -0.72424708f, -0.71573083f, + -0.70710678f, -0.69837625f, -0.68954054f, -0.68060100f, -0.67155895f, + -0.66241578f, -0.65317284f, -0.64383154f, -0.63439328f, -0.62485949f, + -0.61523159f, -0.60551104f, -0.59569930f, -0.58579786f, -0.57580819f, + -0.56573181f, -0.55557023f, -0.54532499f, -0.53499762f, -0.52458968f, + -0.51410274f, -0.50353838f, -0.49289819f, -0.48218377f, -0.47139674f, + -0.46053871f, -0.44961133f, -0.43861624f, -0.42755509f, -0.41642956f, + -0.40524131f, -0.39399204f, -0.38268343f, -0.37131719f, -0.35989504f, + -0.34841868f, -0.33688985f, -0.32531029f, -0.31368174f, -0.30200595f, + -0.29028468f, -0.27851969f, -0.26671276f, -0.25486566f, -0.24298018f, + -0.23105811f, -0.21910124f, -0.20711138f, -0.19509032f, -0.18303989f, + -0.17096189f, -0.15885814f, -0.14673047f, -0.13458071f, -0.12241068f, + -0.11022221f, -0.09801714f, -0.08579731f, -0.07356456f, -0.06132074f, + -0.04906767f, -0.03680722f, -0.02454123f, -0.01227154f, -0.00000000f +}; + +/** + @par + Table values are in Q31 (1.31 fixed-point format) and generation is done in + three steps. First, generate sin values in floating point: +
+  tableSize = 512;
+  for (n = 0; n < (tableSize + 1); n++)
+  {
+ 	sinTable[n] = sin(2*PI*n/tableSize);
+  } 
+ where PI value is 3.14159265358979 + @par + Second, convert floating-point to Q31 (Fixed point): + (sinTable[i] * pow(2, 31)) + @par + Finally, round to the nearest integer value: + sinTable[i] += (sinTable[i] > 0 ? 0.5 : -0.5); + */ +const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1] = { + 0L, 26352928L, 52701887L, 79042909L, 105372028L, 131685278L, 157978697L, + 184248325L, 210490206L, 236700388L, 262874923L, 289009871L, 315101295L, + 341145265L, 367137861L, 393075166L, 418953276L, 444768294L, 470516330L, + 496193509L, 521795963L, 547319836L, 572761285L, 598116479L, 623381598L, + 648552838L, 673626408L, 698598533L, 723465451L, 748223418L, 772868706L, + 797397602L, 821806413L, 846091463L, 870249095L, 894275671L, 918167572L, + 941921200L, 965532978L, 988999351L, 1012316784L, 1035481766L, 1058490808L, + 1081340445L, 1104027237L, 1126547765L, 1148898640L, 1171076495L, 1193077991L, + 1214899813L, 1236538675L, 1257991320L, 1279254516L, 1300325060L, 1321199781L, + 1341875533L, 1362349204L, 1382617710L, 1402678000L, 1422527051L, 1442161874L, + 1461579514L, 1480777044L, 1499751576L, 1518500250L, 1537020244L, 1555308768L, + 1573363068L, 1591180426L, 1608758157L, 1626093616L, 1643184191L, 1660027308L, + 1676620432L, 1692961062L, 1709046739L, 1724875040L, 1740443581L, 1755750017L, + 1770792044L, 1785567396L, 1800073849L, 1814309216L, 1828271356L, 1841958164L, + 1855367581L, 1868497586L, 1881346202L, 1893911494L, 1906191570L, 1918184581L, + 1929888720L, 1941302225L, 1952423377L, 1963250501L, 1973781967L, 1984016189L, + 1993951625L, 2003586779L, 2012920201L, 2021950484L, 2030676269L, 2039096241L, + 2047209133L, 2055013723L, 2062508835L, 2069693342L, 2076566160L, 2083126254L, + 2089372638L, 2095304370L, 2100920556L, 2106220352L, 2111202959L, 2115867626L, + 2120213651L, 2124240380L, 2127947206L, 2131333572L, 2134398966L, 2137142927L, + 2139565043L, 2141664948L, 2143442326L, 2144896910L, 2146028480L, 2146836866L, + 2147321946L, 2147483647L, 2147321946L, 2146836866L, 2146028480L, 2144896910L, + 2143442326L, 2141664948L, 2139565043L, 2137142927L, 2134398966L, 2131333572L, + 2127947206L, 2124240380L, 2120213651L, 2115867626L, 2111202959L, 2106220352L, + 2100920556L, 2095304370L, 2089372638L, 2083126254L, 2076566160L, 2069693342L, + 2062508835L, 2055013723L, 2047209133L, 2039096241L, 2030676269L, 2021950484L, + 2012920201L, 2003586779L, 1993951625L, 1984016189L, 1973781967L, 1963250501L, + 1952423377L, 1941302225L, 1929888720L, 1918184581L, 1906191570L, 1893911494L, + 1881346202L, 1868497586L, 1855367581L, 1841958164L, 1828271356L, 1814309216L, + 1800073849L, 1785567396L, 1770792044L, 1755750017L, 1740443581L, 1724875040L, + 1709046739L, 1692961062L, 1676620432L, 1660027308L, 1643184191L, 1626093616L, + 1608758157L, 1591180426L, 1573363068L, 1555308768L, 1537020244L, 1518500250L, + 1499751576L, 1480777044L, 1461579514L, 1442161874L, 1422527051L, 1402678000L, + 1382617710L, 1362349204L, 1341875533L, 1321199781L, 1300325060L, 1279254516L, + 1257991320L, 1236538675L, 1214899813L, 1193077991L, 1171076495L, 1148898640L, + 1126547765L, 1104027237L, 1081340445L, 1058490808L, 1035481766L, 1012316784L, + 988999351L, 965532978L, 941921200L, 918167572L, 894275671L, 870249095L, + 846091463L, 821806413L, 797397602L, 772868706L, 748223418L, 723465451L, + 698598533L, 673626408L, 648552838L, 623381598L, 598116479L, 572761285L, + 547319836L, 521795963L, 496193509L, 470516330L, 444768294L, 418953276L, + 393075166L, 367137861L, 341145265L, 315101295L, 289009871L, 262874923L, + 236700388L, 210490206L, 184248325L, 157978697L, 131685278L, 105372028L, + 79042909L, 52701887L, 26352928L, 0L, -26352928L, -52701887L, -79042909L, + -105372028L, -131685278L, -157978697L, -184248325L, -210490206L, -236700388L, + -262874923L, -289009871L, -315101295L, -341145265L, -367137861L, -393075166L, + -418953276L, -444768294L, -470516330L, -496193509L, -521795963L, -547319836L, + -572761285L, -598116479L, -623381598L, -648552838L, -673626408L, -698598533L, + -723465451L, -748223418L, -772868706L, -797397602L, -821806413L, -846091463L, + -870249095L, -894275671L, -918167572L, -941921200L, -965532978L, -988999351L, + -1012316784L, -1035481766L, -1058490808L, -1081340445L, -1104027237L, + -1126547765L, -1148898640L, -1171076495L, -1193077991L, -1214899813L, + -1236538675L, -1257991320L, -1279254516L, -1300325060L, -1321199781L, + -1341875533L, -1362349204L, -1382617710L, -1402678000L, -1422527051L, + -1442161874L, -1461579514L, -1480777044L, -1499751576L, -1518500250L, + -1537020244L, -1555308768L, -1573363068L, -1591180426L, -1608758157L, + -1626093616L, -1643184191L, -1660027308L, -1676620432L, -1692961062L, + -1709046739L, -1724875040L, -1740443581L, -1755750017L, -1770792044L, + -1785567396L, -1800073849L, -1814309216L, -1828271356L, -1841958164L, + -1855367581L, -1868497586L, -1881346202L, -1893911494L, -1906191570L, + -1918184581L, -1929888720L, -1941302225L, -1952423377L, -1963250501L, + -1973781967L, -1984016189L, -1993951625L, -2003586779L, -2012920201L, + -2021950484L, -2030676269L, -2039096241L, -2047209133L, -2055013723L, + -2062508835L, -2069693342L, -2076566160L, -2083126254L, -2089372638L, + -2095304370L, -2100920556L, -2106220352L, -2111202959L, -2115867626L, + -2120213651L, -2124240380L, -2127947206L, -2131333572L, -2134398966L, + -2137142927L, -2139565043L, -2141664948L, -2143442326L, -2144896910L, + -2146028480L, -2146836866L, -2147321946L, (q31_t)0x80000000, -2147321946L, + -2146836866L, -2146028480L, -2144896910L, -2143442326L, -2141664948L, + -2139565043L, -2137142927L, -2134398966L, -2131333572L, -2127947206L, + -2124240380L, -2120213651L, -2115867626L, -2111202959L, -2106220352L, + -2100920556L, -2095304370L, -2089372638L, -2083126254L, -2076566160L, + -2069693342L, -2062508835L, -2055013723L, -2047209133L, -2039096241L, + -2030676269L, -2021950484L, -2012920201L, -2003586779L, -1993951625L, + -1984016189L, -1973781967L, -1963250501L, -1952423377L, -1941302225L, + -1929888720L, -1918184581L, -1906191570L, -1893911494L, -1881346202L, + -1868497586L, -1855367581L, -1841958164L, -1828271356L, -1814309216L, + -1800073849L, -1785567396L, -1770792044L, -1755750017L, -1740443581L, + -1724875040L, -1709046739L, -1692961062L, -1676620432L, -1660027308L, + -1643184191L, -1626093616L, -1608758157L, -1591180426L, -1573363068L, + -1555308768L, -1537020244L, -1518500250L, -1499751576L, -1480777044L, + -1461579514L, -1442161874L, -1422527051L, -1402678000L, -1382617710L, + -1362349204L, -1341875533L, -1321199781L, -1300325060L, -1279254516L, + -1257991320L, -1236538675L, -1214899813L, -1193077991L, -1171076495L, + -1148898640L, -1126547765L, -1104027237L, -1081340445L, -1058490808L, + -1035481766L, -1012316784L, -988999351L, -965532978L, -941921200L, + -918167572L, -894275671L, -870249095L, -846091463L, -821806413L, -797397602L, + -772868706L, -748223418L, -723465451L, -698598533L, -673626408L, -648552838L, + -623381598L, -598116479L, -572761285L, -547319836L, -521795963L, -496193509L, + -470516330L, -444768294L, -418953276L, -393075166L, -367137861L, -341145265L, + -315101295L, -289009871L, -262874923L, -236700388L, -210490206L, -184248325L, + -157978697L, -131685278L, -105372028L, -79042909L, -52701887L, -26352928L, 0 +}; + +/** + @par + Table values are in Q15 (1.15 fixed-point format) and generation is done in + three steps. First, generate sin values in floating point: +
+  tableSize = 512;
+  for (n = 0; n < (tableSize + 1); n++)
+  {
+ 	sinTable[n] = sin(2*PI*n/tableSize);
+  } 
+ where PI value is 3.14159265358979 + @par + Second, convert floating-point to Q15 (Fixed point): + (sinTable[i] * pow(2, 15)) + @par + Finally, round to the nearest integer value: + sinTable[i] += (sinTable[i] > 0 ? 0.5 :-0.5); + */ +const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1] = { + 0, 402, 804, 1206, 1608, 2009, 2411, 2811, 3212, 3612, 4011, 4410, 4808, + 5205, 5602, 5998, 6393, 6787, 7180, 7571, 7962, 8351, 8740, 9127, 9512, + 9896, 10279, 10660, 11039, 11417, 11793, 12167, 12540, 12910, 13279, + 13646, 14010, 14373, 14733, 15091, 15447, 15800, 16151, 16500, 16846, + 17190, 17531, 17869, 18205, 18538, 18868, 19195, 19520, 19841, 20160, + 20475, 20788, 21097, 21403, 21706, 22006, 22302, 22595, 22884, 23170, + 23453, 23732, 24008, 24279, 24548, 24812, 25073, 25330, 25583, 25833, + 26078, 26320, 26557, 26791, 27020, 27246, 27467, 27684, 27897, 28106, + 28311, 28511, 28707, 28899, 29086, 29269, 29448, 29622, 29792, 29957, + 30118, 30274, 30425, 30572, 30715, 30853, 30986, 31114, 31238, 31357, + 31471, 31581, 31686, 31786, 31881, 31972, 32058, 32138, 32214, 32286, + 32352, 32413, 32470, 32522, 32568, 32610, 32647, 32679, 32706, 32729, + 32746, 32758, 32766, 32767, 32766, 32758, 32746, 32729, 32706, 32679, + 32647, 32610, 32568, 32522, 32470, 32413, 32352, 32286, 32214, 32138, + 32058, 31972, 31881, 31786, 31686, 31581, 31471, 31357, 31238, 31114, + 30986, 30853, 30715, 30572, 30425, 30274, 30118, 29957, 29792, 29622, + 29448, 29269, 29086, 28899, 28707, 28511, 28311, 28106, 27897, 27684, + 27467, 27246, 27020, 26791, 26557, 26320, 26078, 25833, 25583, 25330, + 25073, 24812, 24548, 24279, 24008, 23732, 23453, 23170, 22884, 22595, + 22302, 22006, 21706, 21403, 21097, 20788, 20475, 20160, 19841, 19520, + 19195, 18868, 18538, 18205, 17869, 17531, 17190, 16846, 16500, 16151, + 15800, 15447, 15091, 14733, 14373, 14010, 13646, 13279, 12910, 12540, + 12167, 11793, 11417, 11039, 10660, 10279, 9896, 9512, 9127, 8740, 8351, + 7962, 7571, 7180, 6787, 6393, 5998, 5602, 5205, 4808, 4410, 4011, 3612, + 3212, 2811, 2411, 2009, 1608, 1206, 804, 402, 0, -402, -804, -1206, + -1608, -2009, -2411, -2811, -3212, -3612, -4011, -4410, -4808, -5205, + -5602, -5998, -6393, -6787, -7180, -7571, -7962, -8351, -8740, -9127, + -9512, -9896, -10279, -10660, -11039, -11417, -11793, -12167, -12540, + -12910, -13279, -13646, -14010, -14373, -14733, -15091, -15447, -15800, + -16151, -16500, -16846, -17190, -17531, -17869, -18205, -18538, -18868, + -19195, -19520, -19841, -20160, -20475, -20788, -21097, -21403, -21706, + -22006, -22302, -22595, -22884, -23170, -23453, -23732, -24008, -24279, + -24548, -24812, -25073, -25330, -25583, -25833, -26078, -26320, -26557, + -26791, -27020, -27246, -27467, -27684, -27897, -28106, -28311, -28511, + -28707, -28899, -29086, -29269, -29448, -29622, -29792, -29957, -30118, + -30274, -30425, -30572, -30715, -30853, -30986, -31114, -31238, -31357, + -31471, -31581, -31686, -31786, -31881, -31972, -32058, -32138, -32214, + -32286, -32352, -32413, -32470, -32522, -32568, -32610, -32647, -32679, + -32706, -32729, -32746, -32758, -32766, -32768, -32766, -32758, -32746, + -32729, -32706, -32679, -32647, -32610, -32568, -32522, -32470, -32413, + -32352, -32286, -32214, -32138, -32058, -31972, -31881, -31786, -31686, + -31581, -31471, -31357, -31238, -31114, -30986, -30853, -30715, -30572, + -30425, -30274, -30118, -29957, -29792, -29622, -29448, -29269, -29086, + -28899, -28707, -28511, -28311, -28106, -27897, -27684, -27467, -27246, + -27020, -26791, -26557, -26320, -26078, -25833, -25583, -25330, -25073, + -24812, -24548, -24279, -24008, -23732, -23453, -23170, -22884, -22595, + -22302, -22006, -21706, -21403, -21097, -20788, -20475, -20160, -19841, + -19520, -19195, -18868, -18538, -18205, -17869, -17531, -17190, -16846, + -16500, -16151, -15800, -15447, -15091, -14733, -14373, -14010, -13646, + -13279, -12910, -12540, -12167, -11793, -11417, -11039, -10660, -10279, + -9896, -9512, -9127, -8740, -8351, -7962, -7571, -7180, -6787, -6393, + -5998, -5602, -5205, -4808, -4410, -4011, -3612, -3212, -2811, -2411, + -2009, -1608, -1206, -804, -402, 0 +}; diff --git a/platform/cmsis/DSP_Lib/CommonTables/arm_const_structs.c b/platform/cmsis/DSP_Lib/CommonTables/arm_const_structs.c new file mode 100644 index 0000000..f0c114c --- /dev/null +++ b/platform/cmsis/DSP_Lib/CommonTables/arm_const_structs.c @@ -0,0 +1,379 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_const_structs.c + * Description: Constant structs that are initialized for user convenience. + * For example, some can be given as arguments to the arm_cfft_f32() or arm_rfft_f32() functions. + * + * $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. + */ + +#include "arm_const_structs.h" + +/* Floating-point structs */ +const arm_cfft_instance_f32 arm_cfft_sR_f32_len16 = { + 16, twiddleCoef_16, armBitRevIndexTable16, ARMBITREVINDEXTABLE_16_TABLE_LENGTH +}; + +const arm_cfft_instance_f32 arm_cfft_sR_f32_len32 = { + 32, twiddleCoef_32, armBitRevIndexTable32, ARMBITREVINDEXTABLE_32_TABLE_LENGTH +}; + +const arm_cfft_instance_f32 arm_cfft_sR_f32_len64 = { + 64, twiddleCoef_64, armBitRevIndexTable64, ARMBITREVINDEXTABLE_64_TABLE_LENGTH +}; + +const arm_cfft_instance_f32 arm_cfft_sR_f32_len128 = { + 128, twiddleCoef_128, armBitRevIndexTable128, ARMBITREVINDEXTABLE_128_TABLE_LENGTH +}; + +const arm_cfft_instance_f32 arm_cfft_sR_f32_len256 = { + 256, twiddleCoef_256, armBitRevIndexTable256, ARMBITREVINDEXTABLE_256_TABLE_LENGTH +}; + +const arm_cfft_instance_f32 arm_cfft_sR_f32_len512 = { + 512, twiddleCoef_512, armBitRevIndexTable512, ARMBITREVINDEXTABLE_512_TABLE_LENGTH +}; + +const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024 = { + 1024, twiddleCoef_1024, armBitRevIndexTable1024, ARMBITREVINDEXTABLE_1024_TABLE_LENGTH +}; + +const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048 = { + 2048, twiddleCoef_2048, armBitRevIndexTable2048, ARMBITREVINDEXTABLE_2048_TABLE_LENGTH +}; + +const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096 = { + 4096, twiddleCoef_4096, armBitRevIndexTable4096, ARMBITREVINDEXTABLE_4096_TABLE_LENGTH +}; + +/* Fixed-point structs */ +const arm_cfft_instance_q31 arm_cfft_sR_q31_len16 = { + 16, twiddleCoef_16_q31, armBitRevIndexTable_fixed_16, ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH +}; + +const arm_cfft_instance_q31 arm_cfft_sR_q31_len32 = { + 32, twiddleCoef_32_q31, armBitRevIndexTable_fixed_32, ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH +}; + +const arm_cfft_instance_q31 arm_cfft_sR_q31_len64 = { + 64, twiddleCoef_64_q31, armBitRevIndexTable_fixed_64, ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH +}; + +const arm_cfft_instance_q31 arm_cfft_sR_q31_len128 = { + 128, twiddleCoef_128_q31, armBitRevIndexTable_fixed_128, ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH +}; + +const arm_cfft_instance_q31 arm_cfft_sR_q31_len256 = { + 256, twiddleCoef_256_q31, armBitRevIndexTable_fixed_256, ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH +}; + +const arm_cfft_instance_q31 arm_cfft_sR_q31_len512 = { + 512, twiddleCoef_512_q31, armBitRevIndexTable_fixed_512, ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH +}; + +const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024 = { + 1024, twiddleCoef_1024_q31, armBitRevIndexTable_fixed_1024, ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH +}; + +const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048 = { + 2048, twiddleCoef_2048_q31, armBitRevIndexTable_fixed_2048, ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH +}; + +const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096 = { + 4096, twiddleCoef_4096_q31, armBitRevIndexTable_fixed_4096, ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH +}; + +const arm_cfft_instance_q15 arm_cfft_sR_q15_len16 = { + 16, twiddleCoef_16_q15, armBitRevIndexTable_fixed_16, ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH +}; + +const arm_cfft_instance_q15 arm_cfft_sR_q15_len32 = { + 32, twiddleCoef_32_q15, armBitRevIndexTable_fixed_32, ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH +}; + +const arm_cfft_instance_q15 arm_cfft_sR_q15_len64 = { + 64, twiddleCoef_64_q15, armBitRevIndexTable_fixed_64, ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH +}; + +const arm_cfft_instance_q15 arm_cfft_sR_q15_len128 = { + 128, twiddleCoef_128_q15, armBitRevIndexTable_fixed_128, ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH +}; + +const arm_cfft_instance_q15 arm_cfft_sR_q15_len256 = { + 256, twiddleCoef_256_q15, armBitRevIndexTable_fixed_256, ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH +}; + +const arm_cfft_instance_q15 arm_cfft_sR_q15_len512 = { + 512, twiddleCoef_512_q15, armBitRevIndexTable_fixed_512, ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH +}; + +const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024 = { + 1024, twiddleCoef_1024_q15, armBitRevIndexTable_fixed_1024, ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH +}; + +const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048 = { + 2048, twiddleCoef_2048_q15, armBitRevIndexTable_fixed_2048, ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH +}; + +const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096 = { + 4096, twiddleCoef_4096_q15, armBitRevIndexTable_fixed_4096, ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH +}; + +/* Structure for real-value inputs */ +/* Floating-point structs */ +const arm_rfft_fast_instance_f32 arm_rfft_fast_sR_f32_len32 = { + { 16, twiddleCoef_32, armBitRevIndexTable32, ARMBITREVINDEXTABLE_16_TABLE_LENGTH }, + 32U, + (float32_t *)twiddleCoef_rfft_32 +}; + +const arm_rfft_fast_instance_f32 arm_rfft_fast_sR_f32_len64 = { + { 32, twiddleCoef_32, armBitRevIndexTable32, ARMBITREVINDEXTABLE_32_TABLE_LENGTH }, + 64U, + (float32_t *)twiddleCoef_rfft_64 +}; + +const arm_rfft_fast_instance_f32 arm_rfft_fast_sR_f32_len128 = { + { 64, twiddleCoef_64, armBitRevIndexTable64, ARMBITREVINDEXTABLE_64_TABLE_LENGTH }, + 128U, + (float32_t *)twiddleCoef_rfft_128 +}; + +const arm_rfft_fast_instance_f32 arm_rfft_fast_sR_f32_len256 = { + { 128, twiddleCoef_128, armBitRevIndexTable128, ARMBITREVINDEXTABLE_128_TABLE_LENGTH }, + 256U, + (float32_t *)twiddleCoef_rfft_256 +}; + +const arm_rfft_fast_instance_f32 arm_rfft_fast_sR_f32_len512 = { + { 256, twiddleCoef_256, armBitRevIndexTable256, ARMBITREVINDEXTABLE_256_TABLE_LENGTH }, + 512U, + (float32_t *)twiddleCoef_rfft_512 +}; + +const arm_rfft_fast_instance_f32 arm_rfft_fast_sR_f32_len1024 = { + { 512, twiddleCoef_512, armBitRevIndexTable512, ARMBITREVINDEXTABLE_512_TABLE_LENGTH }, + 1024U, + (float32_t *)twiddleCoef_rfft_1024 +}; + +const arm_rfft_fast_instance_f32 arm_rfft_fast_sR_f32_len2048 = { + { 1024, twiddleCoef_1024, armBitRevIndexTable1024, ARMBITREVINDEXTABLE_1024_TABLE_LENGTH }, + 2048U, + (float32_t *)twiddleCoef_rfft_2048 +}; + +const arm_rfft_fast_instance_f32 arm_rfft_fast_sR_f32_len4096 = { + { 2048, twiddleCoef_2048, armBitRevIndexTable2048, ARMBITREVINDEXTABLE_2048_TABLE_LENGTH }, + 4096U, + (float32_t *)twiddleCoef_rfft_4096 +}; + +/* Fixed-point structs */ +/* q31_t */ +extern const q31_t realCoefAQ31[8192]; +extern const q31_t realCoefBQ31[8192]; + +const arm_rfft_instance_q31 arm_rfft_sR_q31_len32 = { + 32U, + 0, + 1, + 256U, + (q31_t*)realCoefAQ31, + (q31_t*)realCoefBQ31, + &arm_cfft_sR_q31_len16 +}; + +const arm_rfft_instance_q31 arm_rfft_sR_q31_len64 = { + 64U, + 0, + 1, + 128U, + (q31_t*)realCoefAQ31, + (q31_t*)realCoefBQ31, + &arm_cfft_sR_q31_len32 +}; + +const arm_rfft_instance_q31 arm_rfft_sR_q31_len128 = { + 128U, + 0, + 1, + 64U, + (q31_t*)realCoefAQ31, + (q31_t*)realCoefBQ31, + &arm_cfft_sR_q31_len64 +}; + +const arm_rfft_instance_q31 arm_rfft_sR_q31_len256 = { + 256U, + 0, + 1, + 32U, + (q31_t*)realCoefAQ31, + (q31_t*)realCoefBQ31, + &arm_cfft_sR_q31_len128 +}; + +const arm_rfft_instance_q31 arm_rfft_sR_q31_len512 = { + 512U, + 0, + 1, + 16U, + (q31_t*)realCoefAQ31, + (q31_t*)realCoefBQ31, + &arm_cfft_sR_q31_len256 +}; + +const arm_rfft_instance_q31 arm_rfft_sR_q31_len1024 = { + 1024U, + 0, + 1, + 8U, + (q31_t*)realCoefAQ31, + (q31_t*)realCoefBQ31, + &arm_cfft_sR_q31_len512 +}; + +const arm_rfft_instance_q31 arm_rfft_sR_q31_len2048 = { + 2048U, + 0, + 1, + 4U, + (q31_t*)realCoefAQ31, + (q31_t*)realCoefBQ31, + &arm_cfft_sR_q31_len1024 +}; + +const arm_rfft_instance_q31 arm_rfft_sR_q31_len4096 = { + 4096U, + 0, + 1, + 2U, + (q31_t*)realCoefAQ31, + (q31_t*)realCoefBQ31, + &arm_cfft_sR_q31_len2048 +}; + +const arm_rfft_instance_q31 arm_rfft_sR_q31_len8192 = { + 8192U, + 0, + 1, + 1U, + (q31_t*)realCoefAQ31, + (q31_t*)realCoefBQ31, + &arm_cfft_sR_q31_len4096 +}; + +/* q15_t */ +extern const q15_t realCoefAQ15[8192]; +extern const q15_t realCoefBQ15[8192]; + +const arm_rfft_instance_q15 arm_rfft_sR_q15_len32 = { + 32U, + 0, + 1, + 256U, + (q15_t*)realCoefAQ15, + (q15_t*)realCoefBQ15, + &arm_cfft_sR_q15_len16 +}; + +const arm_rfft_instance_q15 arm_rfft_sR_q15_len64 = { + 64U, + 0, + 1, + 128U, + (q15_t*)realCoefAQ15, + (q15_t*)realCoefBQ15, + &arm_cfft_sR_q15_len32 +}; + +const arm_rfft_instance_q15 arm_rfft_sR_q15_len128 = { + 128U, + 0, + 1, + 64U, + (q15_t*)realCoefAQ15, + (q15_t*)realCoefBQ15, + &arm_cfft_sR_q15_len64 +}; + +const arm_rfft_instance_q15 arm_rfft_sR_q15_len256 = { + 256U, + 0, + 1, + 32U, + (q15_t*)realCoefAQ15, + (q15_t*)realCoefBQ15, + &arm_cfft_sR_q15_len128 +}; + +const arm_rfft_instance_q15 arm_rfft_sR_q15_len512 = { + 512U, + 0, + 1, + 16U, + (q15_t*)realCoefAQ15, + (q15_t*)realCoefBQ15, + &arm_cfft_sR_q15_len256 +}; + +const arm_rfft_instance_q15 arm_rfft_sR_q15_len1024 = { + 1024U, + 0, + 1, + 8U, + (q15_t*)realCoefAQ15, + (q15_t*)realCoefBQ15, + &arm_cfft_sR_q15_len512 +}; + +const arm_rfft_instance_q15 arm_rfft_sR_q15_len2048 = { + 2048U, + 0, + 1, + 4U, + (q15_t*)realCoefAQ15, + (q15_t*)realCoefBQ15, + &arm_cfft_sR_q15_len1024 +}; + +const arm_rfft_instance_q15 arm_rfft_sR_q15_len4096 = { + 4096U, + 0, + 1, + 2U, + (q15_t*)realCoefAQ15, + (q15_t*)realCoefBQ15, + &arm_cfft_sR_q15_len2048 +}; + +const arm_rfft_instance_q15 arm_rfft_sR_q15_len8192 = { + 8192U, + 0, + 1, + 1U, + (q15_t*)realCoefAQ15, + (q15_t*)realCoefBQ15, + &arm_cfft_sR_q15_len4096 +}; diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/ComplexMathFunctions.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/ComplexMathFunctions.c new file mode 100644 index 0000000..2210533 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/ComplexMathFunctions.c @@ -0,0 +1,46 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: CompexMathFunctions.c + * Description: Combination of all comlex math function source files. + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_cmplx_conj_f32.c" +#include "arm_cmplx_conj_q15.c" +#include "arm_cmplx_conj_q31.c" +#include "arm_cmplx_dot_prod_f32.c" +#include "arm_cmplx_dot_prod_q15.c" +#include "arm_cmplx_dot_prod_q31.c" +#include "arm_cmplx_mag_f32.c" +#include "arm_cmplx_mag_q15.c" +#include "arm_cmplx_mag_q31.c" +#include "arm_cmplx_mag_squared_f32.c" +#include "arm_cmplx_mag_squared_q15.c" +#include "arm_cmplx_mag_squared_q31.c" +#include "arm_cmplx_mult_cmplx_f32.c" +#include "arm_cmplx_mult_cmplx_q15.c" +#include "arm_cmplx_mult_cmplx_q31.c" +#include "arm_cmplx_mult_real_f32.c" +#include "arm_cmplx_mult_real_q15.c" +#include "arm_cmplx_mult_real_q31.c" diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/Makefile b/platform/cmsis/DSP_Lib/ComplexMathFunctions/Makefile new file mode 100644 index 0000000..88c2e8b --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/Makefile @@ -0,0 +1,6 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out %Functions.c,$(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_f32.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_f32.c new file mode 100644 index 0000000..6387de5 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_f32.c @@ -0,0 +1,130 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_conj_f32.c + * Description: Floating-point complex conjugate + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @defgroup cmplx_conj Complex Conjugate + + Conjugates the elements of a complex data vector. + + The pSrc points to the source data and + pDst points to the destination data where the result should be written. + numSamples specifies the number of complex samples + and the data in each array is stored in an interleaved fashion + (real, imag, real, imag, ...). + Each array has a total of 2*numSamples values. + + The underlying algorithm is used: +
+  for (n = 0; n < numSamples; n++) {
+      pDst[(2*n)  ] =  pSrc[(2*n)  ];    // real part
+      pDst[(2*n)+1] = -pSrc[(2*n)+1];    // imag part
+  }
+  
+ + There are separate functions for floating-point, Q15, and Q31 data types. + */ + +/** + @addtogroup cmplx_conj + @{ + */ + +/** + @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 samples in each vector + @return none + */ + +void arm_cmplx_conj_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[0] + jC[1] = A[0]+ j(-1)A[1] */ + + /* Calculate Complex Conjugate and store result in destination buffer. */ + *pDst++ = *pSrc++; + *pDst++ = -*pSrc++; + + *pDst++ = *pSrc++; + *pDst++ = -*pSrc++; + + *pDst++ = *pSrc++; + *pDst++ = -*pSrc++; + + *pDst++ = *pSrc++; + *pDst++ = -*pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[0] + jC[1] = A[0]+ j(-1)A[1] */ + + /* Calculate Complex Conjugate and store result in destination buffer. */ + *pDst++ = *pSrc++; + *pDst++ = -*pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of cmplx_conj group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_q15.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_q15.c new file mode 100644 index 0000000..073a337 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_q15.c @@ -0,0 +1,157 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_conj_q15.c + * Description: Q15 complex conjugate + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup cmplx_conj + @{ + */ + +/** + @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 samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + The Q15 value -1 (0x8000) is saturated to the maximum allowable positive value 0x7FFF. + */ + +void arm_cmplx_conj_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t in1; /* Temporary input variable */ + +#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP) + q31_t in2, in3, in4; /* Temporary input variables */ +#endif + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[0] + jC[1] = A[0]+ j(-1)A[1] */ + + /* Calculate Complex Conjugate and store result in destination buffer. */ + + #if defined (ARM_MATH_DSP) + in1 = read_q15x2_ia ((q15_t **) &pSrc); + in2 = read_q15x2_ia ((q15_t **) &pSrc); + in3 = read_q15x2_ia ((q15_t **) &pSrc); + in4 = read_q15x2_ia ((q15_t **) &pSrc); + +#ifndef ARM_MATH_BIG_ENDIAN + in1 = __QASX(0, in1); + in2 = __QASX(0, in2); + in3 = __QASX(0, in3); + in4 = __QASX(0, in4); +#else + in1 = __QSAX(0, in1); + in2 = __QSAX(0, in2); + in3 = __QSAX(0, in3); + in4 = __QSAX(0, in4); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + in1 = ((uint32_t) in1 >> 16) | ((uint32_t) in1 << 16); + in2 = ((uint32_t) in2 >> 16) | ((uint32_t) in2 << 16); + in3 = ((uint32_t) in3 >> 16) | ((uint32_t) in3 << 16); + in4 = ((uint32_t) in4 >> 16) | ((uint32_t) in4 << 16); + + write_q15x2_ia (&pDst, in1); + write_q15x2_ia (&pDst, in2); + write_q15x2_ia (&pDst, in3); + write_q15x2_ia (&pDst, in4); +#else + *pDst++ = *pSrc++; + in1 = *pSrc++; + *pDst++ = (in1 == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in1; + + *pDst++ = *pSrc++; + in1 = *pSrc++; + *pDst++ = (in1 == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in1; + + *pDst++ = *pSrc++; + in1 = *pSrc++; + *pDst++ = (in1 == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in1; + + *pDst++ = *pSrc++; + in1 = *pSrc++; + *pDst++ = (in1 == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in1; + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[0] + jC[1] = A[0]+ j(-1)A[1] */ + + /* Calculate Complex Conjugate and store result in destination buffer. */ + *pDst++ = *pSrc++; + in1 = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __SSAT(-in1, 16); +#else + *pDst++ = (in1 == (q15_t) 0x8000) ? (q15_t) 0x7fff : -in1; +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of cmplx_conj group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_q31.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_q31.c new file mode 100644 index 0000000..6ef1ddb --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_conj_q31.c @@ -0,0 +1,137 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_conj_q31.c + * Description: Q31 complex conjugate + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup cmplx_conj + @{ + */ + +/** + @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 samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + The Q31 value -1 (0x80000000) is saturated to the maximum allowable positive value 0x7FFFFFFF. + */ + +void arm_cmplx_conj_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t in; /* Temporary input variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[0] + jC[1] = A[0]+ j(-1)A[1] */ + + /* Calculate Complex Conjugate and store result in destination buffer. */ + *pDst++ = *pSrc++; + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __QSUB(0, in); +#else + *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in; +#endif + + *pDst++ = *pSrc++; + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __QSUB(0, in); +#else + *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in; +#endif + + *pDst++ = *pSrc++; + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __QSUB(0, in); +#else + *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in; +#endif + + *pDst++ = *pSrc++; + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __QSUB(0, in); +#else + *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in; +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[0] + jC[1] = A[0]+ j(-1)A[1] */ + + /* Calculate Complex Conjugate and store result in destination buffer. */ + *pDst++ = *pSrc++; + in = *pSrc++; +#if defined (ARM_MATH_DSP) + *pDst++ = __QSUB(0, in); +#else + *pDst++ = (in == INT32_MIN) ? INT32_MAX : -in; +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of cmplx_conj group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c new file mode 100644 index 0000000..9c8ef2d --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c @@ -0,0 +1,172 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_dot_prod_f32.c + * Description: Floating-point complex dot product + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @defgroup cmplx_dot_prod Complex Dot Product + + Computes the dot product of two complex vectors. + The vectors are multiplied element-by-element and then summed. + + The pSrcA points to the first complex input vector and + pSrcB points to the second complex input vector. + numSamples specifies the number of complex samples + and the data in each array is stored in an interleaved fashion + (real, imag, real, imag, ...). + Each array has a total of 2*numSamples values. + + The underlying algorithm is used: + +
+  realResult = 0;
+  imagResult = 0;
+  for (n = 0; n < numSamples; n++) {
+      realResult += pSrcA[(2*n)+0] * pSrcB[(2*n)+0] - pSrcA[(2*n)+1] * pSrcB[(2*n)+1];
+      imagResult += pSrcA[(2*n)+0] * pSrcB[(2*n)+1] + pSrcA[(2*n)+1] * pSrcB[(2*n)+0];
+  }
+  
+ + There are separate functions for floating-point, Q15, and Q31 data types. + */ + +/** + @addtogroup cmplx_dot_prod + @{ + */ + +/** + @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 samples in each vector + @param[out] realResult real part of the result returned here + @param[out] imagResult imaginary part of the result returned here + @return none + */ + +void arm_cmplx_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t real_sum = 0.0f, imag_sum = 0.0f; /* Temporary result variables */ + float32_t a0,b0,c0,d0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += a0 * c0; + imag_sum += a0 * d0; + real_sum -= b0 * d0; + imag_sum += b0 * c0; + + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += a0 * c0; + imag_sum += a0 * d0; + real_sum -= b0 * d0; + imag_sum += b0 * c0; + + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += a0 * c0; + imag_sum += a0 * d0; + real_sum -= b0 * d0; + imag_sum += b0 * c0; + + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += a0 * c0; + imag_sum += a0 * d0; + real_sum -= b0 * d0; + imag_sum += b0 * c0; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += a0 * c0; + imag_sum += a0 * d0; + real_sum -= b0 * d0; + imag_sum += b0 * c0; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store real and imaginary result in destination buffer. */ + *realResult = real_sum; + *imagResult = imag_sum; +} + +/** + @} end of cmplx_dot_prod group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c new file mode 100644 index 0000000..2ecd801 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c @@ -0,0 +1,154 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_dot_prod_q15.c + * Description: Processing function for the Q15 Complex Dot product + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup cmplx_dot_prod + @{ + */ + +/** + @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 samples in each vector + @param[out] realResult real part of the result returned here + @param[out] imagResult imaginary part of the result returned her + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + The intermediate 1.15 by 1.15 multiplications are performed with full precision and yield a 2.30 result. + These are accumulated in a 64-bit accumulator with 34.30 precision. + As a final step, the accumulators are converted to 8.24 format. + The return results realResult and imagResult are in 8.24 format. + */ + +void arm_cmplx_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult) +{ + uint32_t blkCnt; /* Loop counter */ + q63_t real_sum = 0, imag_sum = 0; /* Temporary result variables */ + q15_t a0,b0,c0,d0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += (q31_t)a0 * c0; + imag_sum += (q31_t)a0 * d0; + real_sum -= (q31_t)b0 * d0; + imag_sum += (q31_t)b0 * c0; + + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += (q31_t)a0 * c0; + imag_sum += (q31_t)a0 * d0; + real_sum -= (q31_t)b0 * d0; + imag_sum += (q31_t)b0 * c0; + + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += (q31_t)a0 * c0; + imag_sum += (q31_t)a0 * d0; + real_sum -= (q31_t)b0 * d0; + imag_sum += (q31_t)b0 * c0; + + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += (q31_t)a0 * c0; + imag_sum += (q31_t)a0 * d0; + real_sum -= (q31_t)b0 * d0; + imag_sum += (q31_t)b0 * c0; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += (q31_t)a0 * c0; + imag_sum += (q31_t)a0 * d0; + real_sum -= (q31_t)b0 * d0; + imag_sum += (q31_t)b0 * c0; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store real and imaginary result in 8.24 format */ + /* Convert real data in 34.30 to 8.24 by 6 right shifts */ + *realResult = (q31_t) (real_sum >> 6); + /* Convert imaginary data in 34.30 to 8.24 by 6 right shifts */ + *imagResult = (q31_t) (imag_sum >> 6); +} + +/** + @} end of cmplx_dot_prod group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c new file mode 100644 index 0000000..d715d98 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c @@ -0,0 +1,153 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_dot_prod_q31.c + * Description: Q31 complex dot product + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup cmplx_dot_prod + @{ + */ + +/** + @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 samples in each vector + @param[out] realResult real part of the result returned here + @param[out] imagResult imaginary part of the result returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + The intermediate 1.31 by 1.31 multiplications are performed with 64-bit precision and then shifted to 16.48 format. + The internal real and imaginary accumulators are in 16.48 format and provide 15 guard bits. + Additions are nonsaturating and no overflow will occur as long as numSamples is less than 32768. + The return results realResult and imagResult are in 16.48 format. + Input down scaling is not required. + */ + +void arm_cmplx_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult) +{ + uint32_t blkCnt; /* Loop counter */ + q63_t real_sum = 0, imag_sum = 0; /* Temporary result variables */ + q31_t a0,b0,c0,d0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += ((q63_t)a0 * c0) >> 14; + imag_sum += ((q63_t)a0 * d0) >> 14; + real_sum -= ((q63_t)b0 * d0) >> 14; + imag_sum += ((q63_t)b0 * c0) >> 14; + + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += ((q63_t)a0 * c0) >> 14; + imag_sum += ((q63_t)a0 * d0) >> 14; + real_sum -= ((q63_t)b0 * d0) >> 14; + imag_sum += ((q63_t)b0 * c0) >> 14; + + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += ((q63_t)a0 * c0) >> 14; + imag_sum += ((q63_t)a0 * d0) >> 14; + real_sum -= ((q63_t)b0 * d0) >> 14; + imag_sum += ((q63_t)b0 * c0) >> 14; + + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += ((q63_t)a0 * c0) >> 14; + imag_sum += ((q63_t)a0 * d0) >> 14; + real_sum -= ((q63_t)b0 * d0) >> 14; + imag_sum += ((q63_t)b0 * c0) >> 14; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + a0 = *pSrcA++; + b0 = *pSrcA++; + c0 = *pSrcB++; + d0 = *pSrcB++; + + real_sum += ((q63_t)a0 * c0) >> 14; + imag_sum += ((q63_t)a0 * d0) >> 14; + real_sum -= ((q63_t)b0 * d0) >> 14; + imag_sum += ((q63_t)b0 * c0) >> 14; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store real and imaginary result in 16.48 format */ + *realResult = real_sum; + *imagResult = imag_sum; +} + +/** + @} end of cmplx_dot_prod group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_f32.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_f32.c new file mode 100644 index 0000000..39431c1 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_f32.c @@ -0,0 +1,139 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mag_f32.c + * Description: Floating-point complex magnitude + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @defgroup cmplx_mag Complex Magnitude + + Computes the magnitude of the elements of a complex data vector. + + The pSrc points to the source data and + pDst points to the where the result should be written. + numSamples specifies the number of complex samples + in the input array and the data is stored in an interleaved fashion + (real, imag, real, imag, ...). + The input array has a total of 2*numSamples values; + the output array has a total of numSamples values. + + The underlying algorithm is used: + +
+  for (n = 0; n < numSamples; n++) {
+      pDst[n] = sqrt(pSrc[(2*n)+0]^2 + pSrc[(2*n)+1]^2);
+  }
+  
+ + There are separate functions for floating-point, Q15, and Q31 data types. + */ + +/** + @addtogroup cmplx_mag + @{ + */ + +/** + @brief Floating-point complex magnitude. + @param[in] pSrc points to input vector + @param[out] pDst points to output vector + @param[in] numSamples number of samples in each vector + @return none + */ + +void arm_cmplx_mag_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t real, imag; /* Temporary input variables */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */ + + real = *pSrc++; + imag = *pSrc++; + + /* store result in destination buffer. */ + arm_sqrt_f32((real * real) + (imag * imag), pDst++); + + real = *pSrc++; + imag = *pSrc++; + arm_sqrt_f32((real * real) + (imag * imag), pDst++); + + real = *pSrc++; + imag = *pSrc++; + arm_sqrt_f32((real * real) + (imag * imag), pDst++); + + real = *pSrc++; + imag = *pSrc++; + arm_sqrt_f32((real * real) + (imag * imag), pDst++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */ + + real = *pSrc++; + imag = *pSrc++; + + /* store result in destination buffer. */ + arm_sqrt_f32((real * real) + (imag * imag), pDst++); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of cmplx_mag group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_q15.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_q15.c new file mode 100644 index 0000000..a493274 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_q15.c @@ -0,0 +1,162 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mag_q15.c + * Description: Q15 complex magnitude + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup cmplx_mag + @{ + */ + +/** + @brief Q15 complex magnitude. + @param[in] pSrc points to input vector + @param[out] pDst points to output vector + @param[in] numSamples number of samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function implements 1.15 by 1.15 multiplications and finally output is converted into 2.14 format. + */ + +void arm_cmplx_mag_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_DSP) + q31_t in; + q31_t acc0; /* Accumulators */ +#else + q15_t real, imag; /* Temporary input variables */ + q31_t acc0, acc1; /* Accumulators */ +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */ + +#if defined (ARM_MATH_DSP) + in = read_q15x2_ia ((q15_t **) &pSrc); + acc0 = __SMUAD(in, in); + /* store result in 2.14 format in destination buffer. */ + arm_sqrt_q15((q15_t) (acc0 >> 17), pDst++); + + in = read_q15x2_ia ((q15_t **) &pSrc); + acc0 = __SMUAD(in, in); + arm_sqrt_q15((q15_t) (acc0 >> 17), pDst++); + + in = read_q15x2_ia ((q15_t **) &pSrc); + acc0 = __SMUAD(in, in); + arm_sqrt_q15((q15_t) (acc0 >> 17), pDst++); + + in = read_q15x2_ia ((q15_t **) &pSrc); + acc0 = __SMUAD(in, in); + arm_sqrt_q15((q15_t) (acc0 >> 17), pDst++); +#else + real = *pSrc++; + imag = *pSrc++; + acc0 = ((q31_t) real * real); + acc1 = ((q31_t) imag * imag); + + /* store result in 2.14 format in destination buffer. */ + arm_sqrt_q15((q15_t) (((q63_t) acc0 + acc1) >> 17), pDst++); + + real = *pSrc++; + imag = *pSrc++; + acc0 = ((q31_t) real * real); + acc1 = ((q31_t) imag * imag); + arm_sqrt_q15((q15_t) (((q63_t) acc0 + acc1) >> 17), pDst++); + + real = *pSrc++; + imag = *pSrc++; + acc0 = ((q31_t) real * real); + acc1 = ((q31_t) imag * imag); + arm_sqrt_q15((q15_t) (((q63_t) acc0 + acc1) >> 17), pDst++); + + real = *pSrc++; + imag = *pSrc++; + acc0 = ((q31_t) real * real); + acc1 = ((q31_t) imag * imag); + arm_sqrt_q15((q15_t) (((q63_t) acc0 + acc1) >> 17), pDst++); +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */ + +#if defined (ARM_MATH_DSP) + in = read_q15x2_ia ((q15_t **) &pSrc); + acc0 = __SMUAD(in, in); + + /* store result in 2.14 format in destination buffer. */ + arm_sqrt_q15((q15_t) (acc0 >> 17), pDst++); +#else + real = *pSrc++; + imag = *pSrc++; + acc0 = ((q31_t) real * real); + acc1 = ((q31_t) imag * imag); + + /* store result in 2.14 format in destination buffer. */ + arm_sqrt_q15((q15_t) (((q63_t) acc0 + acc1) >> 17), pDst++); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of cmplx_mag group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_q31.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_q31.c new file mode 100644 index 0000000..873e566 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_q31.c @@ -0,0 +1,130 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mag_q31.c + * Description: Q31 complex magnitude + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup cmplx_mag + @{ + */ + +/** + @brief Q31 complex magnitude. + @param[in] pSrc points to input vector + @param[out] pDst points to output vector + @param[in] numSamples number of samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function implements 1.31 by 1.31 multiplications and finally output is converted into 2.30 format. + Input down scaling is not required. + */ + +void arm_cmplx_mag_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t real, imag; /* Temporary input variables */ + q31_t acc0, acc1; /* Accumulators */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */ + + real = *pSrc++; + imag = *pSrc++; + acc0 = (q31_t) (((q63_t) real * real) >> 33); + acc1 = (q31_t) (((q63_t) imag * imag) >> 33); + + /* store result in 2.30 format in destination buffer. */ + arm_sqrt_q31(acc0 + acc1, pDst++); + + real = *pSrc++; + imag = *pSrc++; + acc0 = (q31_t) (((q63_t) real * real) >> 33); + acc1 = (q31_t) (((q63_t) imag * imag) >> 33); + arm_sqrt_q31(acc0 + acc1, pDst++); + + real = *pSrc++; + imag = *pSrc++; + acc0 = (q31_t) (((q63_t) real * real) >> 33); + acc1 = (q31_t) (((q63_t) imag * imag) >> 33); + arm_sqrt_q31(acc0 + acc1, pDst++); + + real = *pSrc++; + imag = *pSrc++; + acc0 = (q31_t) (((q63_t) real * real) >> 33); + acc1 = (q31_t) (((q63_t) imag * imag) >> 33); + arm_sqrt_q31(acc0 + acc1, pDst++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */ + + real = *pSrc++; + imag = *pSrc++; + acc0 = (q31_t) (((q63_t) real * real) >> 33); + acc1 = (q31_t) (((q63_t) imag * imag) >> 33); + + /* store result in 2.30 format in destination buffer. */ + arm_sqrt_q31(acc0 + acc1, pDst++); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of cmplx_mag group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c new file mode 100644 index 0000000..ad2e577 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c @@ -0,0 +1,137 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mag_squared_f32.c + * Description: Floating-point complex magnitude squared + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @defgroup cmplx_mag_squared Complex Magnitude Squared + + Computes the magnitude squared of the elements of a complex data vector. + + The pSrc points to the source data and + pDst points to the where the result should be written. + numSamples specifies the number of complex samples + in the input array and the data is stored in an interleaved fashion + (real, imag, real, imag, ...). + The input array has a total of 2*numSamples values; + the output array has a total of numSamples values. + + The underlying algorithm is used: + +
+  for (n = 0; n < numSamples; n++) {
+      pDst[n] = pSrc[(2*n)+0]^2 + pSrc[(2*n)+1]^2;
+  }
+  
+ + There are separate functions for floating-point, Q15, and Q31 data types. + */ + +/** + @addtogroup cmplx_mag_squared + @{ + */ + +/** + @brief Floating-point complex magnitude squared. + @param[in] pSrc points to input vector + @param[out] pDst points to output vector + @param[in] numSamples number of samples in each vector + @return none + */ + +void arm_cmplx_mag_squared_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t real, imag; /* Temporary input variables */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[0] = (A[0] * A[0] + A[1] * A[1]) */ + + real = *pSrc++; + imag = *pSrc++; + *pDst++ = (real * real) + (imag * imag); + + real = *pSrc++; + imag = *pSrc++; + *pDst++ = (real * real) + (imag * imag); + + real = *pSrc++; + imag = *pSrc++; + *pDst++ = (real * real) + (imag * imag); + + real = *pSrc++; + imag = *pSrc++; + *pDst++ = (real * real) + (imag * imag); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[0] = (A[0] * A[0] + A[1] * A[1]) */ + + real = *pSrc++; + imag = *pSrc++; + + /* store result in destination buffer. */ + *pDst++ = (real * real) + (imag * imag); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of cmplx_mag_squared group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c new file mode 100644 index 0000000..fa5f4e6 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c @@ -0,0 +1,161 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mag_squared_q15.c + * Description: Q15 complex magnitude squared + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup cmplx_mag_squared + @{ + */ + +/** + @brief Q15 complex magnitude squared. + @param[in] pSrc points to input vector + @param[out] pDst points to output vector + @param[in] numSamples number of samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function implements 1.15 by 1.15 multiplications and finally output is converted into 3.13 format. + */ + +void arm_cmplx_mag_squared_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_DSP) + q31_t in; + q31_t acc0; /* Accumulators */ +#else + q15_t real, imag; /* Temporary input variables */ + q31_t acc0, acc1; /* Accumulators */ +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[0] = (A[0] * A[0] + A[1] * A[1]) */ + +#if defined (ARM_MATH_DSP) + in = read_q15x2_ia ((q15_t **) &pSrc); + acc0 = __SMUAD(in, in); + /* store result in 3.13 format in destination buffer. */ + *pDst++ = (q15_t) (acc0 >> 17); + + in = read_q15x2_ia ((q15_t **) &pSrc); + acc0 = __SMUAD(in, in); + *pDst++ = (q15_t) (acc0 >> 17); + + in = read_q15x2_ia ((q15_t **) &pSrc); + acc0 = __SMUAD(in, in); + *pDst++ = (q15_t) (acc0 >> 17); + + in = read_q15x2_ia ((q15_t **) &pSrc); + acc0 = __SMUAD(in, in); + *pDst++ = (q15_t) (acc0 >> 17); +#else + real = *pSrc++; + imag = *pSrc++; + acc0 = ((q31_t) real * real); + acc1 = ((q31_t) imag * imag); + /* store result in 3.13 format in destination buffer. */ + *pDst++ = (q15_t) (((q63_t) acc0 + acc1) >> 17); + + real = *pSrc++; + imag = *pSrc++; + acc0 = ((q31_t) real * real); + acc1 = ((q31_t) imag * imag); + *pDst++ = (q15_t) (((q63_t) acc0 + acc1) >> 17); + + real = *pSrc++; + imag = *pSrc++; + acc0 = ((q31_t) real * real); + acc1 = ((q31_t) imag * imag); + *pDst++ = (q15_t) (((q63_t) acc0 + acc1) >> 17); + + real = *pSrc++; + imag = *pSrc++; + acc0 = ((q31_t) real * real); + acc1 = ((q31_t) imag * imag); + *pDst++ = (q15_t) (((q63_t) acc0 + acc1) >> 17); +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[0] = (A[0] * A[0] + A[1] * A[1]) */ + +#if defined (ARM_MATH_DSP) + in = read_q15x2_ia ((q15_t **) &pSrc); + acc0 = __SMUAD(in, in); + + /* store result in 3.13 format in destination buffer. */ + *pDst++ = (q15_t) (acc0 >> 17); +#else + real = *pSrc++; + imag = *pSrc++; + acc0 = ((q31_t) real * real); + acc1 = ((q31_t) imag * imag); + + /* store result in 3.13 format in destination buffer. */ + *pDst++ = (q15_t) (((q63_t) acc0 + acc1) >> 17); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of cmplx_mag_squared group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c new file mode 100644 index 0000000..54863ef --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c @@ -0,0 +1,129 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mag_squared_q31.c + * Description: Q31 complex magnitude squared + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup cmplx_mag_squared + @{ + */ + +/** + @brief Q31 complex magnitude squared. + @param[in] pSrc points to input vector + @param[out] pDst points to output vector + @param[in] numSamples number of samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function implements 1.31 by 1.31 multiplications and finally output is converted into 3.29 format. + Input down scaling is not required. + */ + +void arm_cmplx_mag_squared_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t real, imag; /* Temporary input variables */ + q31_t acc0, acc1; /* Accumulators */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[0] = (A[0] * A[0] + A[1] * A[1]) */ + + real = *pSrc++; + imag = *pSrc++; + acc0 = (q31_t) (((q63_t) real * real) >> 33); + acc1 = (q31_t) (((q63_t) imag * imag) >> 33); + /* store the result in 3.29 format in the destination buffer. */ + *pDst++ = acc0 + acc1; + + real = *pSrc++; + imag = *pSrc++; + acc0 = (q31_t) (((q63_t) real * real) >> 33); + acc1 = (q31_t) (((q63_t) imag * imag) >> 33); + *pDst++ = acc0 + acc1; + + real = *pSrc++; + imag = *pSrc++; + acc0 = (q31_t) (((q63_t) real * real) >> 33); + acc1 = (q31_t) (((q63_t) imag * imag) >> 33); + *pDst++ = acc0 + acc1; + + real = *pSrc++; + imag = *pSrc++; + acc0 = (q31_t) (((q63_t) real * real) >> 33); + acc1 = (q31_t) (((q63_t) imag * imag) >> 33); + *pDst++ = acc0 + acc1; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[0] = (A[0] * A[0] + A[1] * A[1]) */ + + real = *pSrc++; + imag = *pSrc++; + acc0 = (q31_t) (((q63_t) real * real) >> 33); + acc1 = (q31_t) (((q63_t) imag * imag) >> 33); + + /* store result in 3.29 format in destination buffer. */ + *pDst++ = acc0 + acc1; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of cmplx_mag_squared group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c new file mode 100644 index 0000000..766cd81 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c @@ -0,0 +1,155 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mult_cmplx_f32.c + * Description: Floating-point complex-by-complex multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @defgroup CmplxByCmplxMult Complex-by-Complex Multiplication + + Multiplies a complex vector by another complex vector and generates a complex result. + The data in the complex arrays is stored in an interleaved fashion + (real, imag, real, imag, ...). + The parameter numSamples represents the number of complex + samples processed. The complex arrays have a total of 2*numSamples + real values. + + The underlying algorithm is used: + +
+  for (n = 0; n < numSamples; n++) {
+      pDst[(2*n)+0] = pSrcA[(2*n)+0] * pSrcB[(2*n)+0] - pSrcA[(2*n)+1] * pSrcB[(2*n)+1];
+      pDst[(2*n)+1] = pSrcA[(2*n)+0] * pSrcB[(2*n)+1] + pSrcA[(2*n)+1] * pSrcB[(2*n)+0];
+  }
+  
+ + There are separate functions for floating-point, Q15, and Q31 data types. + */ + +/** + @addtogroup CmplxByCmplxMult + @{ + */ + +/** + @brief Floating-point complex-by-complex multiplication. + @param[in] pSrcA points to first input vector + @param[in] pSrcB points to second input vector + @param[out] pDst points to output vector + @param[in] numSamples number of samples in each vector + @return none + */ + +void arm_cmplx_mult_cmplx_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t a, b, c, d; /* Temporary variables */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i] * B[2 * i ] - A[2 * i + 1] * B[2 * i + 1]. */ + /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i ]. */ + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + /* store result in destination buffer. */ + *pDst++ = (a * c) - (b * d); + *pDst++ = (a * d) + (b * c); + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + *pDst++ = (a * c) - (b * d); + *pDst++ = (a * d) + (b * c); + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + *pDst++ = (a * c) - (b * d); + *pDst++ = (a * d) + (b * c); + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + *pDst++ = (a * c) - (b * d); + *pDst++ = (a * d) + (b * c); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i] * B[2 * i ] - A[2 * i + 1] * B[2 * i + 1]. */ + /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i ]. */ + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + + /* store result in destination buffer. */ + *pDst++ = (a * c) - (b * d); + *pDst++ = (a * d) + (b * c); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of CmplxByCmplxMult group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c new file mode 100644 index 0000000..6659427 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c @@ -0,0 +1,136 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mult_cmplx_q15.c + * Description: Q15 complex-by-complex multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup CmplxByCmplxMult + @{ + */ + +/** + @brief Q15 complex-by-complex multiplication. + @param[in] pSrcA points to first input vector + @param[in] pSrcB points to second input vector + @param[out] pDst points to output vector + @param[in] numSamples number of samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function implements 1.15 by 1.15 multiplications and finally output is converted into 3.13 format. + */ + +void arm_cmplx_mult_cmplx_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + q15_t a, b, c, d; /* Temporary variables */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i] * B[2 * i ] - A[2 * i + 1] * B[2 * i + 1]. */ + /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i ]. */ + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + /* store result in 3.13 format in destination buffer. */ + *pDst++ = (q15_t) ( (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17) ); + *pDst++ = (q15_t) ( (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17) ); + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + *pDst++ = (q15_t) ( (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17) ); + *pDst++ = (q15_t) ( (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17) ); + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + *pDst++ = (q15_t) ( (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17) ); + *pDst++ = (q15_t) ( (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17) ); + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + *pDst++ = (q15_t) ( (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17) ); + *pDst++ = (q15_t) ( (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17) ); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i] * B[2 * i ] - A[2 * i + 1] * B[2 * i + 1]. */ + /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i ]. */ + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + + /* store result in 3.13 format in destination buffer. */ + *pDst++ = (q15_t) ( (((q31_t) a * c) >> 17) - (((q31_t) b * d) >> 17) ); + *pDst++ = (q15_t) ( (((q31_t) a * d) >> 17) + (((q31_t) b * c) >> 17) ); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of CmplxByCmplxMult group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c new file mode 100644 index 0000000..f6d6dc6 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c @@ -0,0 +1,137 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mult_cmplx_q31.c + * Description: Q31 complex-by-complex multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup CmplxByCmplxMult + @{ + */ + +/** + @brief Q31 complex-by-complex multiplication. + @param[in] pSrcA points to first input vector + @param[in] pSrcB points to second input vector + @param[out] pDst points to output vector + @param[in] numSamples number of samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function implements 1.31 by 1.31 multiplications and finally output is converted into 3.29 format. + Input down scaling is not required. + */ + +void arm_cmplx_mult_cmplx_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t a, b, c, d; /* Temporary variables */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i] * B[2 * i ] - A[2 * i + 1] * B[2 * i + 1]. */ + /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i ]. */ + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + /* store result in 3.29 format in destination buffer. */ + *pDst++ = (q31_t) ( (((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33) ); + *pDst++ = (q31_t) ( (((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33) ); + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + *pDst++ = (q31_t) ( (((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33) ); + *pDst++ = (q31_t) ( (((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33) ); + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + *pDst++ = (q31_t) ( (((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33) ); + *pDst++ = (q31_t) ( (((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33) ); + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + *pDst++ = (q31_t) ( (((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33) ); + *pDst++ = (q31_t) ( (((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33) ); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i] * B[2 * i ] - A[2 * i + 1] * B[2 * i + 1]. */ + /* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i ]. */ + + a = *pSrcA++; + b = *pSrcA++; + c = *pSrcB++; + d = *pSrcB++; + + /* store result in 3.29 format in destination buffer. */ + *pDst++ = (q31_t) ( (((q63_t) a * c) >> 33) - (((q63_t) b * d) >> 33) ); + *pDst++ = (q31_t) ( (((q63_t) a * d) >> 33) + (((q63_t) b * c) >> 33) ); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of CmplxByCmplxMult group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_f32.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_f32.c new file mode 100644 index 0000000..25409d7 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_f32.c @@ -0,0 +1,140 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mult_real_f32.c + * Description: Floating-point complex by real multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @defgroup CmplxByRealMult Complex-by-Real Multiplication + + Multiplies a complex vector by a real vector and generates a complex result. + The data in the complex arrays is stored in an interleaved fashion + (real, imag, real, imag, ...). + The parameter numSamples represents the number of complex + samples processed. The complex arrays have a total of 2*numSamples + real values while the real array has a total of numSamples + real values. + + The underlying algorithm is used: + +
+  for (n = 0; n < numSamples; n++) {
+      pCmplxDst[(2*n)+0] = pSrcCmplx[(2*n)+0] * pSrcReal[n];
+      pCmplxDst[(2*n)+1] = pSrcCmplx[(2*n)+1] * pSrcReal[n];
+  }
+  
+ + There are separate functions for floating-point, Q15, and Q31 data types. + */ + +/** + @addtogroup CmplxByRealMult + @{ + */ + +/** + @brief Floating-point complex-by-real multiplication. + @param[in] pSrcCmplx points to complex input vector + @param[in] pSrcReal points to real input vector + @param[out] pCmplxDst points to complex output vector + @param[in] numSamples number of samples in each vector + @return none + */ + +void arm_cmplx_mult_real_f32( + const float32_t * pSrcCmplx, + const float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t in; /* Temporary variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i ] * B[i]. */ + /* C[2 * i + 1] = A[2 * i + 1] * B[i]. */ + + in = *pSrcReal++; + /* store result in destination buffer. */ + *pCmplxDst++ = *pSrcCmplx++ * in; + *pCmplxDst++ = *pSrcCmplx++ * in; + + in = *pSrcReal++; + *pCmplxDst++ = *pSrcCmplx++ * in; + *pCmplxDst++ = *pSrcCmplx++ * in; + + in = *pSrcReal++; + *pCmplxDst++ = *pSrcCmplx++ * in; + *pCmplxDst++ = *pSrcCmplx++ * in; + + in = *pSrcReal++; + *pCmplxDst++ = *pSrcCmplx++* in; + *pCmplxDst++ = *pSrcCmplx++ * in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i ] * B[i]. */ + /* C[2 * i + 1] = A[2 * i + 1] * B[i]. */ + + in = *pSrcReal++; + /* store result in destination buffer. */ + *pCmplxDst++ = *pSrcCmplx++ * in; + *pCmplxDst++ = *pSrcCmplx++ * in; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of CmplxByRealMult group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_q15.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_q15.c new file mode 100644 index 0000000..4877d20 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_q15.c @@ -0,0 +1,182 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mult_real_q15.c + * Description: Q15 complex by real multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup CmplxByRealMult + @{ + */ + +/** + @brief Q15 complex-by-real multiplication. + @param[in] pSrcCmplx points to complex input vector + @param[in] pSrcReal points to real input vector + @param[out] pCmplxDst points to complex output vector + @param[in] numSamples number of samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated. + */ + +void arm_cmplx_mult_real_q15( + const q15_t * pSrcCmplx, + const q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + q15_t in; /* Temporary variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + +#if defined (ARM_MATH_DSP) + q31_t inA1, inA2; /* Temporary variables to hold input data */ + q31_t inB1; /* Temporary variables to hold input data */ + q15_t out1, out2, out3, out4; /* Temporary variables to hold output data */ + q31_t mul1, mul2, mul3, mul4; /* Temporary variables to hold intermediate data */ +#endif + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i ] * B[i]. */ + /* C[2 * i + 1] = A[2 * i + 1] * B[i]. */ + +#if defined (ARM_MATH_DSP) + /* read 2 complex numbers both real and imaginary from complex input buffer */ + inA1 = read_q15x2_ia ((q15_t **) &pSrcCmplx); + inA2 = read_q15x2_ia ((q15_t **) &pSrcCmplx); + /* read 2 real values at a time from real input buffer */ + inB1 = read_q15x2_ia ((q15_t **) &pSrcReal); + + /* multiply complex number with real numbers */ +#ifndef ARM_MATH_BIG_ENDIAN + mul1 = (q31_t) ((q15_t) (inA1) * (q15_t) (inB1)); + mul2 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1)); + mul3 = (q31_t) ((q15_t) (inA2) * (q15_t) (inB1 >> 16)); + mul4 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB1 >> 16)); +#else + mul2 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16)); + mul1 = (q31_t) ((q15_t) inA1 * (q15_t) (inB1 >> 16)); + mul4 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) inB1); + mul3 = (q31_t) ((q15_t) inA2 * (q15_t) inB1); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* saturate the result */ + out1 = (q15_t) __SSAT(mul1 >> 15U, 16); + out2 = (q15_t) __SSAT(mul2 >> 15U, 16); + out3 = (q15_t) __SSAT(mul3 >> 15U, 16); + out4 = (q15_t) __SSAT(mul4 >> 15U, 16); + + /* pack real and imaginary outputs and store them to destination */ + write_q15x2_ia (&pCmplxDst, __PKHBT(out1, out2, 16)); + write_q15x2_ia (&pCmplxDst, __PKHBT(out3, out4, 16)); + + inA1 = read_q15x2_ia ((q15_t **) &pSrcCmplx); + inA2 = read_q15x2_ia ((q15_t **) &pSrcCmplx); + inB1 = read_q15x2_ia ((q15_t **) &pSrcReal); + +#ifndef ARM_MATH_BIG_ENDIAN + mul1 = (q31_t) ((q15_t) (inA1) * (q15_t) (inB1)); + mul2 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1)); + mul3 = (q31_t) ((q15_t) (inA2) * (q15_t) (inB1 >> 16)); + mul4 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB1 >> 16)); +#else + mul2 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16)); + mul1 = (q31_t) ((q15_t) inA1 * (q15_t) (inB1 >> 16)); + mul4 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) inB1); + mul3 = (q31_t) ((q15_t) inA2 * (q15_t) inB1); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + out1 = (q15_t) __SSAT(mul1 >> 15U, 16); + out2 = (q15_t) __SSAT(mul2 >> 15U, 16); + out3 = (q15_t) __SSAT(mul3 >> 15U, 16); + out4 = (q15_t) __SSAT(mul4 >> 15U, 16); + + write_q15x2_ia (&pCmplxDst, __PKHBT(out1, out2, 16)); + write_q15x2_ia (&pCmplxDst, __PKHBT(out3, out4, 16)); +#else + in = *pSrcReal++; + *pCmplxDst++ = (q15_t) __SSAT((((q31_t) *pSrcCmplx++ * in) >> 15), 16); + *pCmplxDst++ = (q15_t) __SSAT((((q31_t) *pSrcCmplx++ * in) >> 15), 16); + + in = *pSrcReal++; + *pCmplxDst++ = (q15_t) __SSAT((((q31_t) *pSrcCmplx++ * in) >> 15), 16); + *pCmplxDst++ = (q15_t) __SSAT((((q31_t) *pSrcCmplx++ * in) >> 15), 16); + + in = *pSrcReal++; + *pCmplxDst++ = (q15_t) __SSAT((((q31_t) *pSrcCmplx++ * in) >> 15), 16); + *pCmplxDst++ = (q15_t) __SSAT((((q31_t) *pSrcCmplx++ * in) >> 15), 16); + + in = *pSrcReal++; + *pCmplxDst++ = (q15_t) __SSAT((((q31_t) *pSrcCmplx++ * in) >> 15), 16); + *pCmplxDst++ = (q15_t) __SSAT((((q31_t) *pSrcCmplx++ * in) >> 15), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i ] * B[i]. */ + /* C[2 * i + 1] = A[2 * i + 1] * B[i]. */ + + in = *pSrcReal++; + /* store the result in the destination buffer. */ + *pCmplxDst++ = (q15_t) __SSAT((((q31_t) *pSrcCmplx++ * in) >> 15), 16); + *pCmplxDst++ = (q15_t) __SSAT((((q31_t) *pSrcCmplx++ * in) >> 15), 16); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of CmplxByRealMult group + */ diff --git a/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_q31.c b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_q31.c new file mode 100644 index 0000000..906410f --- /dev/null +++ b/platform/cmsis/DSP_Lib/ComplexMathFunctions/arm_cmplx_mult_real_q31.c @@ -0,0 +1,148 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mult_real_q31.c + * Description: Q31 complex by real multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupCmplxMath + */ + +/** + @addtogroup CmplxByRealMult + @{ + */ + +/** + @brief Q31 complex-by-real multiplication. + @param[in] pSrcCmplx points to complex input vector + @param[in] pSrcReal points to real input vector + @param[out] pCmplxDst points to complex output vector + @param[in] numSamples number of samples in each vector + @return none + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] are saturated. + */ + +void arm_cmplx_mult_real_q31( + const q31_t * pSrcCmplx, + const q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t in; /* Temporary variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i ] * B[i]. */ + /* C[2 * i + 1] = A[2 * i + 1] * B[i]. */ + + in = *pSrcReal++; +#if defined (ARM_MATH_DSP) + /* store saturated result in 1.31 format to destination buffer */ + *pCmplxDst++ = (__SSAT((q31_t) (((q63_t) *pSrcCmplx++ * in) >> 32), 31) << 1); + *pCmplxDst++ = (__SSAT((q31_t) (((q63_t) *pSrcCmplx++ * in) >> 32), 31) << 1); +#else + /* store result in destination buffer. */ + *pCmplxDst++ = (q31_t) clip_q63_to_q31(((q63_t) *pSrcCmplx++ * in) >> 31); + *pCmplxDst++ = (q31_t) clip_q63_to_q31(((q63_t) *pSrcCmplx++ * in) >> 31); +#endif + + in = *pSrcReal++; +#if defined (ARM_MATH_DSP) + *pCmplxDst++ = (__SSAT((q31_t) (((q63_t) *pSrcCmplx++ * in) >> 32), 31) << 1); + *pCmplxDst++ = (__SSAT((q31_t) (((q63_t) *pSrcCmplx++ * in) >> 32), 31) << 1); +#else + *pCmplxDst++ = (q31_t) clip_q63_to_q31(((q63_t) *pSrcCmplx++ * in) >> 31); + *pCmplxDst++ = (q31_t) clip_q63_to_q31(((q63_t) *pSrcCmplx++ * in) >> 31); +#endif + + in = *pSrcReal++; +#if defined (ARM_MATH_DSP) + *pCmplxDst++ = (__SSAT((q31_t) (((q63_t) *pSrcCmplx++ * in) >> 32), 31) << 1); + *pCmplxDst++ = (__SSAT((q31_t) (((q63_t) *pSrcCmplx++ * in) >> 32), 31) << 1); +#else + *pCmplxDst++ = (q31_t) clip_q63_to_q31(((q63_t) *pSrcCmplx++ * in) >> 31); + *pCmplxDst++ = (q31_t) clip_q63_to_q31(((q63_t) *pSrcCmplx++ * in) >> 31); +#endif + + in = *pSrcReal++; +#if defined (ARM_MATH_DSP) + *pCmplxDst++ = (__SSAT((q31_t) (((q63_t) *pSrcCmplx++ * in) >> 32), 31) << 1); + *pCmplxDst++ = (__SSAT((q31_t) (((q63_t) *pSrcCmplx++ * in) >> 32), 31) << 1); +#else + *pCmplxDst++ = (q31_t) clip_q63_to_q31(((q63_t) *pSrcCmplx++ * in) >> 31); + *pCmplxDst++ = (q31_t) clip_q63_to_q31(((q63_t) *pSrcCmplx++ * in) >> 31); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C[2 * i ] = A[2 * i ] * B[i]. */ + /* C[2 * i + 1] = A[2 * i + 1] * B[i]. */ + + in = *pSrcReal++; +#if defined (ARM_MATH_DSP) + /* store saturated result in 1.31 format to destination buffer */ + *pCmplxDst++ = (__SSAT((q31_t) (((q63_t) *pSrcCmplx++ * in) >> 32), 31) << 1); + *pCmplxDst++ = (__SSAT((q31_t) (((q63_t) *pSrcCmplx++ * in) >> 32), 31) << 1); +#else + /* store result in destination buffer. */ + *pCmplxDst++ = (q31_t) clip_q63_to_q31(((q63_t) *pSrcCmplx++ * in) >> 31); + *pCmplxDst++ = (q31_t) clip_q63_to_q31(((q63_t) *pSrcCmplx++ * in) >> 31); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of CmplxByRealMult group + */ diff --git a/platform/cmsis/DSP_Lib/ControllerFunctions/ControllerFunctions.c b/platform/cmsis/DSP_Lib/ControllerFunctions/ControllerFunctions.c new file mode 100644 index 0000000..51720bc --- /dev/null +++ b/platform/cmsis/DSP_Lib/ControllerFunctions/ControllerFunctions.c @@ -0,0 +1,37 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: ControllerFunctions.c + * Description: Combination of all controller function source files. + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_pid_init_f32.c" +#include "arm_pid_init_q15.c" +#include "arm_pid_init_q31.c" +#include "arm_pid_reset_f32.c" +#include "arm_pid_reset_q15.c" +#include "arm_pid_reset_q31.c" +#include "arm_sin_cos_f32.c" +#include "arm_sin_cos_q31.c" + diff --git a/platform/cmsis/DSP_Lib/ControllerFunctions/Makefile b/platform/cmsis/DSP_Lib/ControllerFunctions/Makefile new file mode 100644 index 0000000..88c2e8b --- /dev/null +++ b/platform/cmsis/DSP_Lib/ControllerFunctions/Makefile @@ -0,0 +1,6 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out %Functions.c,$(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_f32.c b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_f32.c new file mode 100644 index 0000000..433a65a --- /dev/null +++ b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_f32.c @@ -0,0 +1,75 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_pid_init_f32.c + * Description: Floating-point PID Control initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @addtogroup PID + @{ + */ + +/** + @brief Initialization function for the floating-point PID Control. + @param[in,out] S points to an instance of the PID structure + @param[in] resetStateFlag + - value = 0: no change in state + - value = 1: reset state + @return none + + @par Details + The resetStateFlag specifies whether to set state to zero or not. \n + The function computes the structure fields: A0, A1 A2 + using the proportional gain( \c Kp), integral gain( \c Ki) and derivative gain( \c Kd) + also sets the state variables to all zeros. + */ + +void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag) +{ + /* Derived coefficient A0 */ + S->A0 = S->Kp + S->Ki + S->Kd; + + /* Derived coefficient A1 */ + S->A1 = (-S->Kp) - ((float32_t) 2.0 * S->Kd); + + /* Derived coefficient A2 */ + S->A2 = S->Kd; + + /* Check whether state needs reset or not */ + if (resetStateFlag) + { + /* Reset state to zero, The size will be always 3 samples */ + memset(S->state, 0, 3U * sizeof(float32_t)); + } + +} + +/** + @} end of PID group + */ diff --git a/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_q15.c b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_q15.c new file mode 100644 index 0000000..c88a3d9 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_q15.c @@ -0,0 +1,95 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_pid_init_q15.c + * Description: Q15 PID Control initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @addtogroup PID + @{ + */ + +/** + @brief Initialization function for the Q15 PID Control. + @param[in,out] S points to an instance of the Q15 PID structure + @param[in] resetStateFlag + - value = 0: no change in state + - value = 1: reset state + @return none + + @par Details + The resetStateFlag specifies whether to set state to zero or not. \n + The function computes the structure fields: A0, A1 A2 + using the proportional gain( \c Kp), integral gain( \c Ki) and derivative gain( \c Kd) + also sets the state variables to all zeros. + */ + +void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag) +{ + +#if defined (ARM_MATH_DSP) + + /* Derived coefficient A0 */ + S->A0 = __QADD16(__QADD16(S->Kp, S->Ki), S->Kd); + + /* Derived coefficients and pack into A1 */ + +#ifndef ARM_MATH_BIG_ENDIAN + S->A1 = __PKHBT(-__QADD16(__QADD16(S->Kd, S->Kd), S->Kp), S->Kd, 16); +#else + S->A1 = __PKHBT(S->Kd, -__QADD16(__QADD16(S->Kd, S->Kd), S->Kp), 16); +#endif + +#else + + q31_t temp; /* to store the sum */ + + /* Derived coefficient A0 */ + temp = S->Kp + S->Ki + S->Kd; + S->A0 = (q15_t) __SSAT(temp, 16); + + /* Derived coefficients and pack into A1 */ + temp = -(S->Kd + S->Kd + S->Kp); + S->A1 = (q15_t) __SSAT(temp, 16); + S->A2 = S->Kd; + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Check whether state needs reset or not */ + if (resetStateFlag) + { + /* Reset state to zero, The size will be always 3 samples */ + memset(S->state, 0, 3U * sizeof(q15_t)); + } + +} + +/** + @} end of PID group + */ diff --git a/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_q31.c b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_q31.c new file mode 100644 index 0000000..1625a5f --- /dev/null +++ b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_init_q31.c @@ -0,0 +1,92 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_pid_init_q31.c + * Description: Q31 PID Control initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @addtogroup PID + @{ + */ + +/** + @brief Initialization function for the Q31 PID Control. + @param[in,out] S points to an instance of the Q31 PID structure + @param[in] resetStateFlag + - value = 0: no change in state + - value = 1: reset state + @return none + + @par Details + The resetStateFlag specifies whether to set state to zero or not. \n + The function computes the structure fields: A0, A1 A2 + using the proportional gain( \c Kp), integral gain( \c Ki) and derivative gain( \c Kd) + also sets the state variables to all zeros. + */ + +void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag) +{ + +#if defined (ARM_MATH_DSP) + + /* Derived coefficient A0 */ + S->A0 = __QADD(__QADD(S->Kp, S->Ki), S->Kd); + + /* Derived coefficient A1 */ + S->A1 = -__QADD(__QADD(S->Kd, S->Kd), S->Kp); + +#else + + q31_t temp; /* to store the sum */ + + /* Derived coefficient A0 */ + temp = clip_q63_to_q31((q63_t) S->Kp + S->Ki); + S->A0 = clip_q63_to_q31((q63_t) temp + S->Kd); + + /* Derived coefficient A1 */ + temp = clip_q63_to_q31((q63_t) S->Kd + S->Kd); + S->A1 = -clip_q63_to_q31((q63_t) temp + S->Kp); + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Derived coefficient A2 */ + S->A2 = S->Kd; + + /* Check whether state needs reset or not */ + if (resetStateFlag) + { + /* Reset state to zero, The size will be always 3 samples */ + memset(S->state, 0, 3U * sizeof(q31_t)); + } + +} + +/** + @} end of PID group + */ diff --git a/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_f32.c b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_f32.c new file mode 100644 index 0000000..d839e55 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_f32.c @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_pid_reset_f32.c + * Description: Floating-point PID Control reset function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @addtogroup PID + @{ + */ + +/** + @brief Reset function for the floating-point PID Control. + @param[in,out] S points to an instance of the floating-point PID structure + @return none + + @par Details + The function resets the state buffer to zeros. + */ + +void arm_pid_reset_f32( + arm_pid_instance_f32 * S) +{ + /* Reset state to zero, The size will be always 3 samples */ + memset(S->state, 0, 3U * sizeof(float32_t)); +} + +/** + @} end of PID group + */ diff --git a/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_q15.c b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_q15.c new file mode 100644 index 0000000..256fd8c --- /dev/null +++ b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_q15.c @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_pid_reset_q15.c + * Description: Q15 PID Control reset function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @addtogroup PID + @{ + */ + +/** + @brief Reset function for the Q15 PID Control. + @param[in,out] S points to an instance of the Q15 PID structure + @return none + + @par Details + The function resets the state buffer to zeros. + */ + +void arm_pid_reset_q15( + arm_pid_instance_q15 * S) +{ + /* Reset state to zero, The size will be always 3 samples */ + memset(S->state, 0, 3U * sizeof(q15_t)); +} + +/** + @} end of PID group + */ diff --git a/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_q31.c b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_q31.c new file mode 100644 index 0000000..2aa391c --- /dev/null +++ b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_pid_reset_q31.c @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_pid_reset_q31.c + * Description: Q31 PID Control reset function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @addtogroup PID + @{ + */ + +/** + @brief Reset function for the Q31 PID Control. + @param[in,out] S points to an instance of the Q31 PID structure + @return none + + @par Details + The function resets the state buffer to zeros. + */ + +void arm_pid_reset_q31( + arm_pid_instance_q31 * S) +{ + /* Reset state to zero, The size will be always 3 samples */ + memset(S->state, 0, 3U * sizeof(q31_t)); +} + +/** + @} end of PID group + */ diff --git a/platform/cmsis/DSP_Lib/ControllerFunctions/arm_sin_cos_f32.c b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_sin_cos_f32.c new file mode 100644 index 0000000..12a1c83 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_sin_cos_f32.c @@ -0,0 +1,146 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sin_cos_f32.c + * Description: Sine and Cosine calculation for floating-point values + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupController + */ + +/** + @defgroup SinCos Sine Cosine + + Computes the trigonometric sine and cosine values using a combination of table lookup + and linear interpolation. + There are separate functions for Q31 and floating-point data types. + The input to the floating-point version is in degrees while the + fixed-point Q31 have a scaled input with the range + [-1 0.9999] mapping to [-180 +180] degrees. + + The floating point function also allows values that are out of the usual range. When this happens, the function will + take extra time to adjust the input value to the range of [-180 180]. + + The result is accurate to 5 digits after the decimal point. + + The implementation is based on table lookup using 360 values together with linear interpolation. + The steps used are: + -# Calculation of the nearest integer table index. + -# Compute the fractional portion (fract) of the input. + -# Fetch the value corresponding to \c index from sine table to \c y0 and also value from \c index+1 to \c y1. + -# Sine value is computed as *psinVal = y0 + (fract * (y1 - y0)). + -# Fetch the value corresponding to \c index from cosine table to \c y0 and also value from \c index+1 to \c y1. + -# Cosine value is computed as *pcosVal = y0 + (fract * (y1 - y0)). + */ + +/** + @addtogroup SinCos + @{ + */ + +/** + @brief Floating-point sin_cos function. + @param[in] theta input value in degrees + @param[out] pSinVal points to processed sine output + @param[out] pCosVal points to processed cosine output + @return none + */ + +void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal) +{ + float32_t fract, in; /* Temporary input, output variables */ + uint16_t indexS, indexC; /* Index variable */ + float32_t f1, f2, d1, d2; /* Two nearest output values */ + float32_t Dn, Df; + float32_t temp, findex; + + /* input x is in degrees */ + /* Scale input, divide input by 360, for cosine add 0.25 (pi/2) to read sine table */ + in = theta * 0.00277777777778f; + + if (in < 0.0f) + { + in = -in; + } + + in = in - (int32_t)in; + + /* Calculate the nearest index */ + findex = (float32_t)FAST_MATH_TABLE_SIZE * in; + indexS = ((uint16_t)findex) & 0x1ff; + indexC = (indexS + (FAST_MATH_TABLE_SIZE / 4)) & 0x1ff; + + /* Calculation of fractional value */ + fract = findex - (float32_t) indexS; + + /* Read two nearest values of input value from the cos & sin tables */ + f1 = sinTable_f32[indexC ]; + f2 = sinTable_f32[indexC+1]; + d1 = -sinTable_f32[indexS ]; + d2 = -sinTable_f32[indexS+1]; + + temp = (1.0f - fract) * f1 + fract * f2; + + Dn = 0.0122718463030f; /* delta between the two points (fixed), in this case 2*pi/FAST_MATH_TABLE_SIZE */ + Df = f2 - f1; /* delta between the values of the functions */ + + temp = Dn * (d1 + d2) - 2 * Df; + temp = fract * temp + (3 * Df - (d2 + 2 * d1) * Dn); + temp = fract * temp + d1 * Dn; + + /* Calculation of cosine value */ + *pCosVal = fract * temp + f1; + + /* Read two nearest values of input value from the cos & sin tables */ + f1 = sinTable_f32[indexS ]; + f2 = sinTable_f32[indexS+1]; + d1 = sinTable_f32[indexC ]; + d2 = sinTable_f32[indexC+1]; + + temp = (1.0f - fract) * f1 + fract * f2; + + Df = f2 - f1; // delta between the values of the functions + temp = Dn * (d1 + d2) - 2 * Df; + temp = fract * temp + (3 * Df - (d2 + 2 * d1) * Dn); + temp = fract * temp + d1 * Dn; + + /* Calculation of sine value */ + *pSinVal = fract * temp + f1; + + if (theta < 0.0f) + { + *pSinVal = -*pSinVal; + } +} + +/** + @} end of SinCos group + */ diff --git a/platform/cmsis/DSP_Lib/ControllerFunctions/arm_sin_cos_q31.c b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_sin_cos_q31.c new file mode 100644 index 0000000..84ee3d2 --- /dev/null +++ b/platform/cmsis/DSP_Lib/ControllerFunctions/arm_sin_cos_q31.c @@ -0,0 +1,110 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sin_cos_q31.c + * Description: Cosine & Sine calculation for Q31 values + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupController + */ + +/** + @addtogroup SinCos + @{ + */ + +/** + @brief Q31 sin_cos function. + @param[in] theta scaled input value in degrees + @param[out] pSinVal points to processed sine output + @param[out] pCosVal points to processed cosine output + @return none + + The Q31 input value is in the range [-1 0.999999] and is mapped to a degree value in the range [-180 179]. + */ + +void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal) +{ + q31_t fract; /* Temporary input, output variables */ + uint16_t indexS, indexC; /* Index variable */ + q31_t f1, f2, d1, d2; /* Two nearest output values */ + q31_t Dn, Df; + q63_t temp; + + /* Calculate the nearest index */ + indexS = (uint32_t)theta >> CONTROLLER_Q31_SHIFT; + indexC = (indexS + 128) & 0x1ff; + + /* Calculation of fractional value */ + fract = (theta - (indexS << CONTROLLER_Q31_SHIFT)) << 8; + + /* Read two nearest values of input value from the cos & sin tables */ + f1 = sinTable_q31[indexC ]; + f2 = sinTable_q31[indexC+1]; + d1 = -sinTable_q31[indexS ]; + d2 = -sinTable_q31[indexS+1]; + + Dn = 0x1921FB5; /* delta between the two points (fixed), in this case 2*pi/FAST_MATH_TABLE_SIZE */ + Df = f2 - f1; /* delta between the values of the functions */ + + temp = Dn * ((q63_t)d1 + d2); + temp = temp - ((q63_t)Df << 32); + temp = (q63_t)fract * (temp >> 31); + temp = temp + ((3 * (q63_t)Df << 31) - (d2 + ((q63_t)d1 << 1)) * Dn); + temp = (q63_t)fract * (temp >> 31); + temp = temp + (q63_t)d1 * Dn; + temp = (q63_t)fract * (temp >> 31); + + /* Calculation of cosine value */ + *pCosVal = clip_q63_to_q31((temp >> 31) + (q63_t)f1); + + /* Read two nearest values of input value from the cos & sin tables */ + f1 = sinTable_q31[indexS ]; + f2 = sinTable_q31[indexS+1]; + d1 = sinTable_q31[indexC ]; + d2 = sinTable_q31[indexC+1]; + + Df = f2 - f1; // delta between the values of the functions + temp = Dn * ((q63_t)d1 + d2); + temp = temp - ((q63_t)Df << 32); + temp = (q63_t)fract * (temp >> 31); + temp = temp + ((3 * (q63_t)Df << 31) - (d2 + ((q63_t)d1 << 1)) * Dn); + temp = (q63_t)fract * (temp >> 31); + temp = temp + (q63_t)d1 * Dn; + temp = (q63_t)fract * (temp >> 31); + + /* Calculation of sine value */ + *pSinVal = clip_q63_to_q31((temp >> 31) + (q63_t)f1); +} + +/** + @} end of SinCos group + */ diff --git a/platform/cmsis/DSP_Lib/FastMathFunctions/FastMathFunctions.c b/platform/cmsis/DSP_Lib/FastMathFunctions/FastMathFunctions.c new file mode 100644 index 0000000..abd919e --- /dev/null +++ b/platform/cmsis/DSP_Lib/FastMathFunctions/FastMathFunctions.c @@ -0,0 +1,37 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: FastMathFunctions.c + * Description: Combination of all fast math function source files. + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_cos_f32.c" +#include "arm_cos_q15.c" +#include "arm_cos_q31.c" +#include "arm_sin_f32.c" +#include "arm_sin_q15.c" +#include "arm_sin_q31.c" +#include "arm_sqrt_q15.c" +#include "arm_sqrt_q31.c" + diff --git a/platform/cmsis/DSP_Lib/FastMathFunctions/Makefile b/platform/cmsis/DSP_Lib/FastMathFunctions/Makefile new file mode 100644 index 0000000..88c2e8b --- /dev/null +++ b/platform/cmsis/DSP_Lib/FastMathFunctions/Makefile @@ -0,0 +1,6 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out %Functions.c,$(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_f32.c b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_f32.c new file mode 100644 index 0000000..26bd66e --- /dev/null +++ b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_f32.c @@ -0,0 +1,122 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cos_f32.c + * Description: Fast cosine calculation for floating-point values + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupFastMath + */ + +/** + @defgroup cos Cosine + + Computes the trigonometric cosine function using a combination of table lookup + and linear interpolation. There are separate functions for + Q15, Q31, and floating-point data types. + The input to the floating-point version is in radians while the + fixed-point Q15 and Q31 have a scaled input with the range + [0 +0.9999] mapping to [0 2*pi). The fixed-point range is chosen so that a + value of 2*pi wraps around to 0. + + The implementation is based on table lookup using 256 values together with linear interpolation. + The steps used are: + -# Calculation of the nearest integer table index + -# Compute the fractional portion (fract) of the table index. + -# The final result equals (1.0f-fract)*a + fract*b; + + where +
+     b = Table[index];
+     c = Table[index+1];
+  
+ */ + +/** + @addtogroup cos + @{ + */ + +/** + @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) +{ + float32_t cosVal, fract, in; /* Temporary input, output variables */ + uint16_t index; /* Index variable */ + float32_t a, b; /* Two nearest output values */ + int32_t n; + float32_t findex; + + /* input x is in radians */ + /* Scale input to [0 1] range from [0 2*PI] , divide input by 2*pi, add 0.25 (pi/2) to read sine table */ + in = x * 0.159154943092f + 0.25f; + + /* Calculation of floor value of input */ + n = (int32_t) in; + + /* Make negative values towards -infinity */ + if (in < 0.0f) + { + n--; + } + + /* Map input value to [0 1] */ + in = in - (float32_t) n; + + /* Calculation of index of the table */ + findex = (float32_t)FAST_MATH_TABLE_SIZE * in; + index = (uint16_t)findex; + + /* when "in" is exactly 1, we need to rotate the index down to 0 */ + if (index >= FAST_MATH_TABLE_SIZE) { + index = 0; + findex -= (float32_t)FAST_MATH_TABLE_SIZE; + } + + /* fractional value calculation */ + fract = findex - (float32_t) index; + + /* Read two nearest values of input value from the cos table */ + a = sinTable_f32[index]; + b = sinTable_f32[index+1]; + + /* Linear interpolation process */ + cosVal = (1.0f - fract) * a + fract * b; + + /* Return output value */ + return (cosVal); +} + +/** + @} end of cos group + */ diff --git a/platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_q15.c b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_q15.c new file mode 100644 index 0000000..3bb829c --- /dev/null +++ b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_q15.c @@ -0,0 +1,84 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cos_q15.c + * Description: Fast cosine calculation for Q15 values + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupFastMath + */ + +/** + @addtogroup cos + @{ + */ + +/** + @brief Fast approximation to the trigonometric cosine function for Q15 data. + @param[in] x Scaled input value in radians + @return cos(x) + + The Q15 input value is in the range [0 +0.9999] and is mapped to a radian value in the range [0 2*PI). + */ + +q15_t arm_cos_q15( + q15_t x) +{ + q15_t cosVal; /* Temporary input, output variables */ + int32_t index; /* Index variable */ + q15_t a, b; /* Two nearest output values */ + q15_t fract; /* Temporary values for fractional values */ + + /* add 0.25 (pi/2) to read sine table */ + x = (uint16_t)x + 0x2000; + if (x < 0) + { /* convert negative numbers to corresponding positive ones */ + x = (uint16_t)x + 0x8000; + } + + /* Calculate the nearest index */ + index = (uint32_t)x >> FAST_MATH_Q15_SHIFT; + + /* Calculation of fractional value */ + fract = (x - (index << FAST_MATH_Q15_SHIFT)) << 9; + + /* Read two nearest values of input value from the sin table */ + a = sinTable_q15[index]; + b = sinTable_q15[index+1]; + + /* Linear interpolation process */ + cosVal = (q31_t) (0x8000 - fract) * a >> 16; + cosVal = (q15_t) ((((q31_t) cosVal << 16) + ((q31_t) fract * b)) >> 16); + + /* Return output value */ + return (cosVal << 1); +} + +/** + @} end of cos group + */ diff --git a/platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_q31.c b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_q31.c new file mode 100644 index 0000000..8b7ff78 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_cos_q31.c @@ -0,0 +1,84 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cos_q31.c + * Description: Fast cosine calculation for Q31 values + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupFastMath + */ + +/** + @addtogroup cos + @{ + */ + +/** + @brief Fast approximation to the trigonometric cosine function for Q31 data. + @param[in] x Scaled input value in radians + @return cos(x) + + The Q31 input value is in the range [0 +0.9999] and is mapped to a radian value in the range [0 2*PI). + */ + +q31_t arm_cos_q31( + q31_t x) +{ + q31_t cosVal; /* Temporary input, output variables */ + int32_t index; /* Index variable */ + q31_t a, b; /* Two nearest output values */ + q31_t fract; /* Temporary values for fractional values */ + + /* add 0.25 (pi/2) to read sine table */ + x = (uint32_t)x + 0x20000000; + if (x < 0) + { /* convert negative numbers to corresponding positive ones */ + x = (uint32_t)x + 0x80000000; + } + + /* Calculate the nearest index */ + index = (uint32_t)x >> FAST_MATH_Q31_SHIFT; + + /* Calculation of fractional value */ + fract = (x - (index << FAST_MATH_Q31_SHIFT)) << 9; + + /* Read two nearest values of input value from the sin table */ + a = sinTable_q31[index]; + b = sinTable_q31[index+1]; + + /* Linear interpolation process */ + cosVal = (q63_t) (0x80000000 - fract) * a >> 32; + cosVal = (q31_t) ((((q63_t) cosVal << 32) + ((q63_t) fract * b)) >> 32); + + /* Return output value */ + return (cosVal << 1); +} + +/** + @} end of cos group + */ diff --git a/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_f32.c b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_f32.c new file mode 100644 index 0000000..97c6902 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_f32.c @@ -0,0 +1,122 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sin_f32.c + * Description: Fast sine calculation for floating-point values + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupFastMath + */ + +/** + @defgroup sin Sine + + Computes the trigonometric sine function using a combination of table lookup + and linear interpolation. There are separate functions for + Q15, Q31, and floating-point data types. + The input to the floating-point version is in radians while the + fixed-point Q15 and Q31 have a scaled input with the range + [0 +0.9999] mapping to [0 2*pi). The fixed-point range is chosen so that a + value of 2*pi wraps around to 0. + + The implementation is based on table lookup using 256 values together with linear interpolation. + The steps used are: + -# Calculation of the nearest integer table index + -# Compute the fractional portion (fract) of the table index. + -# The final result equals (1.0f-fract)*a + fract*b; + + where +
+     b = Table[index];
+     c = Table[index+1];
+  
+ */ + +/** + @addtogroup sin + @{ + */ + +/** + @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) +{ + float32_t sinVal, fract, in; /* Temporary input, output variables */ + uint16_t index; /* Index variable */ + float32_t a, b; /* Two nearest output values */ + int32_t n; + float32_t findex; + + /* input x is in radians */ + /* Scale input to [0 1] range from [0 2*PI] , divide input by 2*pi */ + in = x * 0.159154943092f; + + /* Calculation of floor value of input */ + n = (int32_t) in; + + /* Make negative values towards -infinity */ + if (in < 0.0f) + { + n--; + } + + /* Map input value to [0 1] */ + in = in - (float32_t) n; + + /* Calculation of index of the table */ + findex = (float32_t)FAST_MATH_TABLE_SIZE * in; + index = (uint16_t)findex; + + /* when "in" is exactly 1, we need to rotate the index down to 0 */ + if (index >= FAST_MATH_TABLE_SIZE) { + index = 0; + findex -= (float32_t)FAST_MATH_TABLE_SIZE; + } + + /* fractional value calculation */ + fract = findex - (float32_t) index; + + /* Read two nearest values of input value from the sin table */ + a = sinTable_f32[index]; + b = sinTable_f32[index+1]; + + /* Linear interpolation process */ + sinVal = (1.0f - fract) * a + fract * b; + + /* Return output value */ + return (sinVal); +} + +/** + @} end of sin group + */ diff --git a/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_q15.c b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_q15.c new file mode 100644 index 0000000..1f0c2bf --- /dev/null +++ b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_q15.c @@ -0,0 +1,77 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sin_q15.c + * Description: Fast sine calculation for Q15 values + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupFastMath + */ + +/** + @addtogroup sin + @{ + */ + +/** + @brief Fast approximation to the trigonometric sine function for Q15 data. + @param[in] x Scaled input value in radians + @return sin(x) + + The Q15 input value is in the range [0 +0.9999] and is mapped to a radian value in the range [0 2*PI). + */ + +q15_t arm_sin_q15( + q15_t x) +{ + q15_t sinVal; /* Temporary input, output variables */ + int32_t index; /* Index variable */ + q15_t a, b; /* Two nearest output values */ + q15_t fract; /* Temporary values for fractional values */ + + /* Calculate the nearest index */ + index = (uint32_t)x >> FAST_MATH_Q15_SHIFT; + + /* Calculation of fractional value */ + fract = (x - (index << FAST_MATH_Q15_SHIFT)) << 9; + + /* Read two nearest values of input value from the sin table */ + a = sinTable_q15[index]; + b = sinTable_q15[index+1]; + + /* Linear interpolation process */ + sinVal = (q31_t) (0x8000 - fract) * a >> 16; + sinVal = (q15_t) ((((q31_t) sinVal << 16) + ((q31_t) fract * b)) >> 16); + + /* Return output value */ + return (sinVal << 1); +} + +/** + @} end of sin group + */ diff --git a/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_q31.c b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_q31.c new file mode 100644 index 0000000..8cefabb --- /dev/null +++ b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sin_q31.c @@ -0,0 +1,77 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sin_q31.c + * Description: Fast sine calculation for Q31 values + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupFastMath + */ + +/** + @addtogroup sin + @{ + */ + +/** + @brief Fast approximation to the trigonometric sine function for Q31 data. + @param[in] x Scaled input value in radians + @return sin(x) + + The Q31 input value is in the range [0 +0.9999] and is mapped to a radian value in the range [0 2*PI). + */ + +q31_t arm_sin_q31( + q31_t x) +{ + q31_t sinVal; /* Temporary variables for input, output */ + int32_t index; /* Index variable */ + q31_t a, b; /* Two nearest output values */ + q31_t fract; /* Temporary values for fractional values */ + + /* Calculate the nearest index */ + index = (uint32_t)x >> FAST_MATH_Q31_SHIFT; + + /* Calculation of fractional value */ + fract = (x - (index << FAST_MATH_Q31_SHIFT)) << 9; + + /* Read two nearest values of input value from the sin table */ + a = sinTable_q31[index]; + b = sinTable_q31[index+1]; + + /* Linear interpolation process */ + sinVal = (q63_t) (0x80000000 - fract) * a >> 32; + sinVal = (q31_t) ((((q63_t) sinVal << 32) + ((q63_t) fract * b)) >> 32); + + /* Return output value */ + return (sinVal << 1); +} + +/** + @} end of sin group + */ diff --git a/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sqrt_q15.c b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sqrt_q15.c new file mode 100644 index 0000000..fab0a32 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sqrt_q15.c @@ -0,0 +1,144 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sqrt_q15.c + * Description: Q15 square root function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupFastMath + */ + +/** + @addtogroup SQRT + @{ + */ + +/** + @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) +{ + q31_t bits_val1; + q15_t number, temp1, var1, signBits1, half; + float32_t temp_float1; + union + { + q31_t fracval; + float32_t floatval; + } tempconv; + + number = in; + + /* If the input is a positive number then compute the signBits. */ + if (number > 0) + { + signBits1 = __CLZ(number) - 17; + + /* Shift by the number of signBits1 */ + if ((signBits1 % 2) == 0) + { + number = number << signBits1; + } + else + { + number = number << (signBits1 - 1); + } + + /* Calculate half value of the number */ + half = number >> 1; + /* Store the number for later use */ + temp1 = number; + + /* Convert to float */ + temp_float1 = number * 3.051757812500000e-005f; + /* Store as integer */ + tempconv.floatval = temp_float1; + bits_val1 = tempconv.fracval; + /* Subtract the shifted value from the magic number to give intial guess */ + bits_val1 = 0x5f3759df - (bits_val1 >> 1); /* gives initial guess */ + /* Store as float */ + tempconv.fracval = bits_val1; + temp_float1 = tempconv.floatval; + /* Convert to integer format */ + var1 = (q31_t) (temp_float1 * 16384); + + /* 1st iteration */ + var1 = ((q15_t) ((q31_t) var1 * (0x3000 - + ((q15_t) + ((((q15_t) + (((q31_t) var1 * var1) >> 15)) * + (q31_t) half) >> 15))) >> 15)) << 2; + /* 2nd iteration */ + var1 = ((q15_t) ((q31_t) var1 * (0x3000 - + ((q15_t) + ((((q15_t) + (((q31_t) var1 * var1) >> 15)) * + (q31_t) half) >> 15))) >> 15)) << 2; + /* 3rd iteration */ + var1 = ((q15_t) ((q31_t) var1 * (0x3000 - + ((q15_t) + ((((q15_t) + (((q31_t) var1 * var1) >> 15)) * + (q31_t) half) >> 15))) >> 15)) << 2; + + /* Multiply the inverse square root with the original value */ + var1 = ((q15_t) (((q31_t) temp1 * var1) >> 15)) << 1; + + /* Shift the output down accordingly */ + if ((signBits1 % 2) == 0) + { + var1 = var1 >> (signBits1 / 2); + } + else + { + var1 = var1 >> ((signBits1 - 1) / 2); + } + *pOut = var1; + + return (ARM_MATH_SUCCESS); + } + /* If the number is a negative number then store zero as its square root value */ + else + { + *pOut = 0; + + return (ARM_MATH_ARGUMENT_ERROR); + } +} + +/** + @} end of SQRT group + */ diff --git a/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sqrt_q31.c b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sqrt_q31.c new file mode 100644 index 0000000..9889b13 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FastMathFunctions/arm_sqrt_q31.c @@ -0,0 +1,144 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_sqrt_q31.c + * Description: Q31 square root function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupFastMath + */ + +/** + @addtogroup SQRT + @{ + */ + +/** + @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) +{ + q31_t bits_val1; + q31_t number, temp1, var1, signBits1, half; + float32_t temp_float1; + union + { + q31_t fracval; + float32_t floatval; + } tempconv; + + number = in; + + /* If the input is a positive number then compute the signBits. */ + if (number > 0) + { + signBits1 = __CLZ(number) - 1; + + /* Shift by the number of signBits1 */ + if ((signBits1 % 2) == 0) + { + number = number << signBits1; + } + else + { + number = number << (signBits1 - 1); + } + + /* Calculate half value of the number */ + half = number >> 1; + /* Store the number for later use */ + temp1 = number; + + /* Convert to float */ + temp_float1 = number * 4.6566128731e-010f; + /* Store as integer */ + tempconv.floatval = temp_float1; + bits_val1 = tempconv.fracval; + /* Subtract the shifted value from the magic number to give intial guess */ + bits_val1 = 0x5f3759df - (bits_val1 >> 1); /* gives initial guess */ + /* Store as float */ + tempconv.fracval = bits_val1; + temp_float1 = tempconv.floatval; + /* Convert to integer format */ + var1 = (q31_t) (temp_float1 * 1073741824); + + /* 1st iteration */ + var1 = ((q31_t) ((q63_t) var1 * (0x30000000 - + ((q31_t) + ((((q31_t) + (((q63_t) var1 * var1) >> 31)) * + (q63_t) half) >> 31))) >> 31)) << 2; + /* 2nd iteration */ + var1 = ((q31_t) ((q63_t) var1 * (0x30000000 - + ((q31_t) + ((((q31_t) + (((q63_t) var1 * var1) >> 31)) * + (q63_t) half) >> 31))) >> 31)) << 2; + /* 3rd iteration */ + var1 = ((q31_t) ((q63_t) var1 * (0x30000000 - + ((q31_t) + ((((q31_t) + (((q63_t) var1 * var1) >> 31)) * + (q63_t) half) >> 31))) >> 31)) << 2; + + /* Multiply the inverse square root with the original value */ + var1 = ((q31_t) (((q63_t) temp1 * var1) >> 31)) << 1; + + /* Shift the output down accordingly */ + if ((signBits1 % 2) == 0) + { + var1 = var1 >> (signBits1 / 2); + } + else + { + var1 = var1 >> ((signBits1 - 1) / 2); + } + *pOut = var1; + + return (ARM_MATH_SUCCESS); + } + /* If the number is a negative number then store zero as its square root value */ + else + { + *pOut = 0; + + return (ARM_MATH_ARGUMENT_ERROR); + } +} + +/** + @} end of SQRT group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/FilteringFunctions.c b/platform/cmsis/DSP_Lib/FilteringFunctions/FilteringFunctions.c new file mode 100644 index 0000000..7ce0cdb --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/FilteringFunctions.c @@ -0,0 +1,127 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: FilteringFunctions.c + * Description: Combination of all filtering function source files. + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_biquad_cascade_df1_32x64_init_q31.c" +#include "arm_biquad_cascade_df1_32x64_q31.c" +#include "arm_biquad_cascade_df1_f32.c" +#include "arm_biquad_cascade_df1_fast_q15.c" +#include "arm_biquad_cascade_df1_fast_q31.c" +#include "arm_biquad_cascade_df1_init_f32.c" +#include "arm_biquad_cascade_df1_init_q15.c" +#include "arm_biquad_cascade_df1_init_q31.c" +#include "arm_biquad_cascade_df1_q15.c" +#include "arm_biquad_cascade_df1_q31.c" +#include "arm_biquad_cascade_df2T_f32.c" +#include "arm_biquad_cascade_df2T_f64.c" +#include "arm_biquad_cascade_df2T_init_f32.c" +#include "arm_biquad_cascade_df2T_init_f64.c" +#include "arm_biquad_cascade_stereo_df2T_f32.c" +#include "arm_biquad_cascade_stereo_df2T_init_f32.c" +#include "arm_conv_f32.c" +#include "arm_conv_fast_opt_q15.c" +#include "arm_conv_fast_q15.c" +#include "arm_conv_fast_q31.c" +#include "arm_conv_opt_q15.c" +#include "arm_conv_opt_q7.c" +#include "arm_conv_partial_f32.c" +#include "arm_conv_partial_fast_opt_q15.c" +#include "arm_conv_partial_fast_q15.c" +#include "arm_conv_partial_fast_q31.c" +#include "arm_conv_partial_opt_q15.c" +#include "arm_conv_partial_opt_q7.c" +#include "arm_conv_partial_q15.c" +#include "arm_conv_partial_q31.c" +#include "arm_conv_partial_q7.c" +#include "arm_conv_q15.c" +#include "arm_conv_q31.c" +#include "arm_conv_q7.c" +#include "arm_correlate_f32.c" +#include "arm_correlate_fast_opt_q15.c" +#include "arm_correlate_fast_q15.c" +#include "arm_correlate_fast_q31.c" +#include "arm_correlate_opt_q15.c" +#include "arm_correlate_opt_q7.c" +#include "arm_correlate_q15.c" +#include "arm_correlate_q31.c" +#include "arm_correlate_q7.c" +#include "arm_fir_decimate_f32.c" +#include "arm_fir_decimate_fast_q15.c" +#include "arm_fir_decimate_fast_q31.c" +#include "arm_fir_decimate_init_f32.c" +#include "arm_fir_decimate_init_q15.c" +#include "arm_fir_decimate_init_q31.c" +#include "arm_fir_decimate_q15.c" +#include "arm_fir_decimate_q31.c" +#include "arm_fir_f32.c" +#include "arm_fir_fast_q15.c" +#include "arm_fir_fast_q31.c" +#include "arm_fir_init_f32.c" +#include "arm_fir_init_q15.c" +#include "arm_fir_init_q31.c" +#include "arm_fir_init_q7.c" +#include "arm_fir_interpolate_f32.c" +#include "arm_fir_interpolate_init_f32.c" +#include "arm_fir_interpolate_init_q15.c" +#include "arm_fir_interpolate_init_q31.c" +#include "arm_fir_interpolate_q15.c" +#include "arm_fir_interpolate_q31.c" +#include "arm_fir_lattice_f32.c" +#include "arm_fir_lattice_init_f32.c" +#include "arm_fir_lattice_init_q15.c" +#include "arm_fir_lattice_init_q31.c" +#include "arm_fir_lattice_q15.c" +#include "arm_fir_lattice_q31.c" +#include "arm_fir_q15.c" +#include "arm_fir_q31.c" +#include "arm_fir_q7.c" +#include "arm_fir_sparse_f32.c" +#include "arm_fir_sparse_init_f32.c" +#include "arm_fir_sparse_init_q15.c" +#include "arm_fir_sparse_init_q31.c" +#include "arm_fir_sparse_init_q7.c" +#include "arm_fir_sparse_q15.c" +#include "arm_fir_sparse_q31.c" +#include "arm_fir_sparse_q7.c" +#include "arm_iir_lattice_f32.c" +#include "arm_iir_lattice_init_f32.c" +#include "arm_iir_lattice_init_q15.c" +#include "arm_iir_lattice_init_q31.c" +#include "arm_iir_lattice_q15.c" +#include "arm_iir_lattice_q31.c" +#include "arm_lms_f32.c" +#include "arm_lms_init_f32.c" +#include "arm_lms_init_q15.c" +#include "arm_lms_init_q31.c" +#include "arm_lms_norm_f32.c" +#include "arm_lms_norm_init_f32.c" +#include "arm_lms_norm_init_q15.c" +#include "arm_lms_norm_init_q31.c" +#include "arm_lms_norm_q15.c" +#include "arm_lms_norm_q31.c" +#include "arm_lms_q15.c" +#include "arm_lms_q31.c" diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/Makefile b/platform/cmsis/DSP_Lib/FilteringFunctions/Makefile new file mode 100644 index 0000000..88c2e8b --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/Makefile @@ -0,0 +1,6 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out %Functions.c,$(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c new file mode 100644 index 0000000..ac2313f --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c @@ -0,0 +1,94 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df1_32x64_init_q31.c + * Description: High precision Q31 Biquad cascade filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF1_32x64 + @{ + */ + +/** + @brief Initialization function for the Q31 Biquad cascade 32x64 filter. + @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 after the accumulator. Varies according to the coefficients format + @return none + + @par Coefficient and State Ordering + The coefficients are stored in the array pCoeffs in the following order: +
+      {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
+  
+ where b1x and a1x are the coefficients for the first stage, + b2x and a2x are the coefficients for the second stage, + and so on. The pCoeffs array contains a total of 5*numStages values. + @par + The pState points to state variables array and size of each state variable is 1.63 format. + Each Biquad stage has 4 state variables x[n-1], x[n-2], y[n-1], and y[n-2]. + The state variables are arranged in the state array as: +
+      {x[n-1], x[n-2], y[n-1], y[n-2]}
+  
+ The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on. + The state array has a total length of 4*numStages values. + The state variables are updated after each block of data is processed; the coefficients are untouched. + */ + +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) +{ + /* Assign filter stages */ + S->numStages = numStages; + + /* Assign postShift to be applied to the output */ + S->postShift = postShift; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always 4 * numStages */ + memset(pState, 0, (4U * (uint32_t) numStages) * sizeof(q63_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of BiquadCascadeDF1_32x64 group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c new file mode 100644 index 0000000..9a284b8 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c @@ -0,0 +1,458 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df1_32x64_q31.c + * Description: High precision Q31 Biquad cascade filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup BiquadCascadeDF1_32x64 High Precision Q31 Biquad Cascade Filter + + This function implements a high precision Biquad cascade filter which operates on + Q31 data values. The filter coefficients are in 1.31 format and the state variables + are in 1.63 format. The double precision state variables reduce quantization noise + in the filter and provide a cleaner output. + These filters are particularly useful when implementing filters in which the + singularities are close to the unit circle. This is common for low pass or high + pass filters with very low cutoff frequencies. + + The function operates on blocks of input and output data + and each call to the function processes blockSize samples through + the filter. pSrc and pDst points to input and output arrays + containing blockSize Q31 values. + + @par Algorithm + Each Biquad stage implements a second order filter using the difference equation: +
+      y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
+  
+ A Direct Form I algorithm is used with 5 coefficients and 4 state variables per stage. + \image html Biquad.gif "Single Biquad filter stage" + Coefficients b0, b1 and b2 multiply the input signal x[n] and are referred to as the feedforward coefficients. + Coefficients a1 and a2 multiply the output signal y[n] and are referred to as the feedback coefficients. + Pay careful attention to the sign of the feedback coefficients. + Some design tools use the difference equation +
+      y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2]
+  
+ In this case the feedback coefficients a1 and a2 must be negated when used with the CMSIS DSP Library. + @par + Higher order filters are realized as a cascade of second order sections. + numStages refers to the number of second order stages used. + For example, an 8th order filter would be realized with numStages=4 second order stages. + \image html BiquadCascade.gif "8th order filter using a cascade of Biquad stages" + A 9th order filter would be realized with numStages=5 second order stages + with the coefficients for one of the stages configured as a first order filter + (b2=0 and a2=0). + @par + The pState points to state variables array. + Each Biquad stage has 4 state variables x[n-1], x[n-2], y[n-1], and y[n-2] and each state variable in 1.63 format to improve precision. + The state variables are arranged in the array as: +
+      {x[n-1], x[n-2], y[n-1], y[n-2]}
+  
+ @par + The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on. + The state array has a total length of 4*numStages values of data in 1.63 format. + The state variables are updated after each block of data is processed, the coefficients are untouched. + + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter. + Coefficient arrays may be shared among several instances while state variable arrays cannot be shared. + + @par Init Function + There is also an associated initialization function which performs the following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + numStages, pCoeffs, postShift, pState. Also set all of the values in pState to zero. + + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + Set the values in the state buffer to zeros before static initialization. + For example, to statically initialize the filter instance structure use +
+      arm_biquad_cas_df1_32x64_ins_q31 S1 = {numStages, pState, pCoeffs, postShift};
+  
+ where numStages is the number of Biquad stages in the filter; + pState is the address of the state buffer; + pCoeffs is the address of the coefficient buffer; + postShift shift to be applied which is described in detail below. + @par Fixed-Point Behavior + Care must be taken while using Biquad Cascade 32x64 filter function. + Following issues must be considered: + - Scaling of coefficients + - Filter gain + - Overflow and saturation + + @par + Filter coefficients are represented as fractional values and + restricted to lie in the range [-1 +1). + The processing function has an additional scaling parameter postShift + which allows the filter coefficients to exceed the range [+1 -1). + At the output of the filter's accumulator is a shift register which shifts the result by postShift bits. + \image html BiquadPostshift.gif "Fixed-point Biquad with shift by postShift bits after accumulator" + This essentially scales the filter coefficients by 2^postShift. + For example, to realize the coefficients +
+     {1.5, -0.8, 1.2, 1.6, -0.9}
+  
+ set the Coefficient array to: +
+     {0.75, -0.4, 0.6, 0.8, -0.45}
+  
+ and set postShift=1 + @par + The second thing to keep in mind is the gain through the filter. + The frequency response of a Biquad filter is a function of its coefficients. + It is possible for the gain through the filter to exceed 1.0 meaning that the + filter increases the amplitude of certain frequencies. + This means that an input signal with amplitude < 1.0 may result in an output > 1.0 + and these are saturated or overflowed based on the implementation of the filter. + To avoid this behavior the filter needs to be scaled down such that its peak gain < 1.0 + or the input signal must be scaled down so that the combination of input and filter are never overflowed. + @par + The third item to consider is the overflow and saturation behavior of the fixed-point Q31 version. + This is described in the function specific documentation below. + */ + +/** + @addtogroup BiquadCascadeDF1_32x64 + @{ + */ + +/** + @brief Processing function for the Q31 Biquad cascade 32x64 filter. + @param[in] S points to an instance of the high precision Q31 Biquad cascade filter + @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 + @return none + + @par Details + 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 and lie in the range [-0.25 +0.25). + After all 5 multiply-accumulates are performed, the 2.62 accumulator is shifted by postShift bits and the result truncated to + 1.31 format by discarding the low 32 bits. + @par + Two related functions are provided in the CMSIS DSP library. + - \ref arm_biquad_cascade_df1_q31() implements a Biquad cascade with 32-bit coefficients and state variables with a Q63 accumulator. + - \ref arm_biquad_cascade_df1_fast_q31() implements a Biquad cascade with 32-bit coefficients and state variables with a Q31 accumulator. + */ + +void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + q31_t *pIn = pSrc; /* input pointer initialization */ + q31_t *pOut = pDst; /* output pointer initialization */ + q63_t *pState = S->pState; /* state pointer initialization */ + const q31_t *pCoeffs = S->pCoeffs; /* coeff pointer initialization */ + q63_t acc; /* accumulator */ + q31_t Xn1, Xn2; /* Input Filter state variables */ + q63_t Yn1, Yn2; /* Output Filter state variables */ + q31_t b0, b1, b2, a1, a2; /* Filter coefficients */ + q31_t Xn; /* temporary input */ + int32_t shift = (int32_t) S->postShift + 1; /* Shift to be applied to the output */ + uint32_t sample, stage = S->numStages; /* loop counters */ + q31_t acc_l, acc_h; /* temporary output */ + uint32_t uShift = ((uint32_t) S->postShift + 1U); + uint32_t lShift = 32U - uShift; /* Shift to be applied to the output */ + + do + { + /* Reading the coefficients */ + b0 = *pCoeffs++; + b1 = *pCoeffs++; + b2 = *pCoeffs++; + a1 = *pCoeffs++; + a2 = *pCoeffs++; + + /* Reading the state values */ + Xn1 = (q31_t) (pState[0]); + Xn2 = (q31_t) (pState[1]); + Yn1 = pState[2]; + Yn2 = pState[3]; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Apply loop unrolling and compute 4 output values simultaneously. */ + /* Variable acc hold output value that is being computed and stored in destination buffer + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + */ + + /* Loop unrolling: Compute 4 outputs at a time */ + sample = blockSize >> 2U; + + while (sample > 0U) + { + /* Read the input */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + + /* acc = b0 * x[n] */ + acc = (q63_t) Xn * b0; + + /* acc += b1 * x[n-1] */ + acc += (q63_t) Xn1 * b1; + + /* acc += b[2] * x[n-2] */ + acc += (q63_t) Xn2 * b2; + + /* acc += a1 * y[n-1] */ + acc += mult32x64(Yn1, a1); + + /* acc += a2 * y[n-2] */ + acc += mult32x64(Yn2, a2); + + /* The result is converted to 1.63 , Yn2 variable is reused */ + Yn2 = acc << shift; + + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + /* Apply shift for lower part of acc and upper part of acc */ + acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Store the output in the destination buffer in 1.31 format. */ + *pOut = acc_h; + + /* Read the second input into Xn2, to reuse the value */ + Xn2 = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + + /* acc += b1 * x[n-1] */ + acc = (q63_t) Xn * b1; + + /* acc = b0 * x[n] */ + acc += (q63_t) Xn2 * b0; + + /* acc += b[2] * x[n-2] */ + acc += (q63_t) Xn1 * b2; + + /* acc += a1 * y[n-1] */ + acc += mult32x64(Yn2, a1); + + /* acc += a2 * y[n-2] */ + acc += mult32x64(Yn1, a2); + + /* The result is converted to 1.63, Yn1 variable is reused */ + Yn1 = acc << shift; + + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + /* Apply shift for lower part of acc and upper part of acc */ + acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Read the third input into Xn1, to reuse the value */ + Xn1 = *pIn++; + + /* The result is converted to 1.31 */ + /* Store the output in the destination buffer. */ + *(pOut + 1U) = acc_h; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + + /* acc = b0 * x[n] */ + acc = (q63_t) Xn1 * b0; + + /* acc += b1 * x[n-1] */ + acc += (q63_t) Xn2 * b1; + + /* acc += b[2] * x[n-2] */ + acc += (q63_t) Xn * b2; + + /* acc += a1 * y[n-1] */ + acc += mult32x64(Yn1, a1); + + /* acc += a2 * y[n-2] */ + acc += mult32x64(Yn2, a2); + + /* The result is converted to 1.63, Yn2 variable is reused */ + Yn2 = acc << shift; + + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + /* Apply shift for lower part of acc and upper part of acc */ + acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Store the output in the destination buffer in 1.31 format. */ + *(pOut + 2U) = acc_h; + + /* Read the fourth input into Xn, to reuse the value */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + /* acc = b0 * x[n] */ + acc = (q63_t) Xn * b0; + + /* acc += b1 * x[n-1] */ + acc += (q63_t) Xn1 * b1; + + /* acc += b[2] * x[n-2] */ + acc += (q63_t) Xn2 * b2; + + /* acc += a1 * y[n-1] */ + acc += mult32x64(Yn2, a1); + + /* acc += a2 * y[n-2] */ + acc += mult32x64(Yn1, a2); + + /* The result is converted to 1.63, Yn1 variable is reused */ + Yn1 = acc << shift; + + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + /* Apply shift for lower part of acc and upper part of acc */ + acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Store the output in the destination buffer in 1.31 format. */ + *(pOut + 3U) = acc_h; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + Xn2 = Xn1; + Xn1 = Xn; + + /* update output pointer */ + pOut += 4U; + + /* decrement loop counter */ + sample--; + } + + /* Loop unrolling: Compute remaining outputs */ + sample = blockSize & 0x3U; + +#else + + /* Initialize blkCnt with number of samples */ + sample = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (sample > 0U) + { + /* Read the input */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + + /* acc = b0 * x[n] */ + acc = (q63_t) Xn * b0; + /* acc += b1 * x[n-1] */ + acc += (q63_t) Xn1 * b1; + /* acc += b[2] * x[n-2] */ + acc += (q63_t) Xn2 * b2; + /* acc += a1 * y[n-1] */ + acc += mult32x64(Yn1, a1); + /* acc += a2 * y[n-2] */ + acc += mult32x64(Yn2, a2); + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + Xn2 = Xn1; + Xn1 = Xn; + Yn2 = Yn1; + + /* The result is converted to 1.63, Yn1 variable is reused */ + Yn1 = acc << shift; + + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + /* Apply shift for lower part of acc and upper part of acc */ + acc_h = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Store the output in the destination buffer in 1.31 format. */ + *pOut++ = acc_h; + /* Yn1 = acc << shift; */ + + /* Store the output in the destination buffer in 1.31 format. */ +/* *pOut++ = (q31_t) (acc >> (32 - shift)); */ + + /* decrement loop counter */ + sample--; + } + + /* The first stage output is given as input to the second stage. */ + pIn = pDst; + + /* Reset to destination buffer working pointer */ + pOut = pDst; + + /* Store the updated state variables back into the pState array */ + *pState++ = (q63_t) Xn1; + *pState++ = (q63_t) Xn2; + *pState++ = Yn1; + *pState++ = Yn2; + + } while (--stage); + +} + +/** + @} end of BiquadCascadeDF1_32x64 group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_f32.c new file mode 100644 index 0000000..79571a1 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_f32.c @@ -0,0 +1,340 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df1_f32.c + * Description: Processing function for the floating-point Biquad cascade DirectFormI(DF1) filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup BiquadCascadeDF1 Biquad Cascade IIR Filters Using Direct Form I Structure + + This set of functions implements arbitrary order recursive (IIR) filters. + The filters are implemented as a cascade of second order Biquad sections. + The functions support Q15, Q31 and floating-point data types. + Fast version of Q15 and Q31 also available. + + The functions operate on blocks of input and output data and each call to the function + processes blockSize samples through the filter. + pSrc points to the array of input data and + pDst points to the array of output data. + Both arrays contain blockSize values. + + @par Algorithm + Each Biquad stage implements a second order filter using the difference equation: +
+      y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
+  
+ A Direct Form I algorithm is used with 5 coefficients and 4 state variables per stage. + \image html Biquad.gif "Single Biquad filter stage" + Coefficients b0, b1 and b2 multiply the input signal x[n] and are referred to as the feedforward coefficients. + Coefficients a1 and a2 multiply the output signal y[n] and are referred to as the feedback coefficients. + Pay careful attention to the sign of the feedback coefficients. + Some design tools use the difference equation +
+      y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2]
+  
+ In this case the feedback coefficients a1 and a2 + must be negated when used with the CMSIS DSP Library. + + @par + Higher order filters are realized as a cascade of second order sections. + numStages refers to the number of second order stages used. + For example, an 8th order filter would be realized with numStages=4 second order stages. + \image html BiquadCascade.gif "8th order filter using a cascade of Biquad stages" + A 9th order filter would be realized with numStages=5 second order stages with the coefficients for one of the stages configured as a first order filter (b2=0 and a2=0). + + @par + The pState points to state variables array. + Each Biquad stage has 4 state variables x[n-1], x[n-2], y[n-1], and y[n-2]. + The state variables are arranged in the pState array as: +
+      {x[n-1], x[n-2], y[n-1], y[n-2]}
+  
+ + @par + The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on. + The state array has a total length of 4*numStages values. + The state variables are updated after each block of data is processed, the coefficients are untouched. + + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter. + Coefficient arrays may be shared among several instances while state variable arrays cannot be shared. + There are separate instance structure declarations for each of the 3 supported data types. + + @par Init Function + There is also an associated initialization function for each data type. + The initialization function performs following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + numStages, pCoeffs, pState. Also set all of the values in pState to zero. + + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + Set the values in the state buffer to zeros before static initialization. + The code below statically initializes each of the 3 different data type filter instance structures +
+      arm_biquad_casd_df1_inst_f32 S1 = {numStages, pState, pCoeffs};
+      arm_biquad_casd_df1_inst_q15 S2 = {numStages, pState, pCoeffs, postShift};
+      arm_biquad_casd_df1_inst_q31 S3 = {numStages, pState, pCoeffs, postShift};
+  
+ where numStages is the number of Biquad stages in the filter; + pState is the address of the state buffer; + pCoeffs is the address of the coefficient buffer; + postShift shift to be applied. + + @par Fixed-Point Behavior + Care must be taken when using the Q15 and Q31 versions of the Biquad Cascade filter functions. + Following issues must be considered: + - Scaling of coefficients + - Filter gain + - Overflow and saturation + + @par Scaling of coefficients + Filter coefficients are represented as fractional values and + coefficients are restricted to lie in the range [-1 +1). + The fixed-point functions have an additional scaling parameter postShift + which allow the filter coefficients to exceed the range [+1 -1). + At the output of the filter's accumulator is a shift register which shifts the result by postShift bits. + \image html BiquadPostshift.gif "Fixed-point Biquad with shift by postShift bits after accumulator" + This essentially scales the filter coefficients by 2^postShift. + For example, to realize the coefficients +
+     {1.5, -0.8, 1.2, 1.6, -0.9}
+  
+ set the pCoeffs array to: +
+     {0.75, -0.4, 0.6, 0.8, -0.45}
+  
+ and set postShift=1 + + @par Filter gain + The frequency response of a Biquad filter is a function of its coefficients. + It is possible for the gain through the filter to exceed 1.0 meaning that the filter increases the amplitude of certain frequencies. + This means that an input signal with amplitude < 1.0 may result in an output > 1.0 and these are saturated or overflowed based on the implementation of the filter. + To avoid this behavior the filter needs to be scaled down such that its peak gain < 1.0 or the input signal must be scaled down so that the combination of input and filter are never overflowed. + + @par Overflow and saturation + For Q15 and Q31 versions, it is described separately as part of the function specific documentation below. + */ + +/** + @addtogroup BiquadCascadeDF1 + @{ + */ + +/** + @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 + @return none + */ + +void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + const float32_t *pIn = pSrc; /* Source pointer */ + float32_t *pOut = pDst; /* Destination pointer */ + float32_t *pState = S->pState; /* pState pointer */ + const float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t acc; /* Accumulator */ + float32_t b0, b1, b2, a1, a2; /* Filter coefficients */ + float32_t Xn1, Xn2, Yn1, Yn2; /* Filter pState variables */ + float32_t Xn; /* Temporary input */ + uint32_t sample, stage = S->numStages; /* Loop counters */ + + do + { + /* Reading the coefficients */ + b0 = *pCoeffs++; + b1 = *pCoeffs++; + b2 = *pCoeffs++; + a1 = *pCoeffs++; + a2 = *pCoeffs++; + + /* Reading the pState values */ + Xn1 = pState[0]; + Xn2 = pState[1]; + Yn1 = pState[2]; + Yn2 = pState[3]; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Apply loop unrolling and compute 4 output values simultaneously. */ + /* Variable acc hold output values that are being computed: + * + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + */ + + /* Loop unrolling: Compute 4 outputs at a time */ + sample = blockSize >> 2U; + + while (sample > 0U) + { + /* Read the first input */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + Yn2 = (b0 * Xn) + (b1 * Xn1) + (b2 * Xn2) + (a1 * Yn1) + (a2 * Yn2); + + /* Store output in destination buffer. */ + *pOut++ = Yn2; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + + /* Read the second input */ + Xn2 = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + Yn1 = (b0 * Xn2) + (b1 * Xn) + (b2 * Xn1) + (a1 * Yn2) + (a2 * Yn1); + + /* Store output in destination buffer. */ + *pOut++ = Yn1; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + + /* Read the third input */ + Xn1 = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + Yn2 = (b0 * Xn1) + (b1 * Xn2) + (b2 * Xn) + (a1 * Yn1) + (a2 * Yn2); + + /* Store output in destination buffer. */ + *pOut++ = Yn2; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + + /* Read the forth input */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + Yn1 = (b0 * Xn) + (b1 * Xn1) + (b2 * Xn2) + (a1 * Yn2) + (a2 * Yn1); + + /* Store output in destination buffer. */ + *pOut++ = Yn1; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + Xn2 = Xn1; + Xn1 = Xn; + + /* decrement loop counter */ + sample--; + } + + /* Loop unrolling: Compute remaining outputs */ + sample = blockSize & 0x3U; + +#else + + /* Initialize blkCnt with number of samples */ + sample = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (sample > 0U) + { + /* Read the input */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + acc = (b0 * Xn) + (b1 * Xn1) + (b2 * Xn2) + (a1 * Yn1) + (a2 * Yn2); + + /* Store output in destination buffer. */ + *pOut++ = acc; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + Xn2 = Xn1; + Xn1 = Xn; + Yn2 = Yn1; + Yn1 = acc; + + /* decrement loop counter */ + sample--; + } + + /* Store the updated state variables back into the pState array */ + *pState++ = Xn1; + *pState++ = Xn2; + *pState++ = Yn1; + *pState++ = Yn2; + + /* The first stage goes from the input buffer to the output buffer. */ + /* Subsequent numStages occur in-place in the output buffer */ + pIn = pDst; + + /* Reset output pointer */ + pOut = pDst; + + /* decrement loop counter */ + stage--; + + } while (stage > 0U); + +} + +/** + @} end of BiquadCascadeDF1 group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c new file mode 100644 index 0000000..1a568d7 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c @@ -0,0 +1,250 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df1_fast_q15.c + * Description: Fast processing function for the Q15 Biquad cascade filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF1 + @{ + */ + +/** + @brief Processing function for the Q15 Biquad cascade filter (fast variant). + @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 per call + @return none + + @par Scaling and Overflow Behavior + This fast version uses a 32-bit accumulator with 2.30 format. + The accumulator maintains full precision of the intermediate multiplication results but provides only a single guard bit. + Thus, if the accumulator result overflows it wraps around and distorts the result. + In order to avoid overflows completely the input signal must be scaled down by two bits and lie in the range [-0.25 +0.25). + The 2.30 accumulator is then shifted by postShift bits and the result truncated to 1.15 format by discarding the low 16 bits. + @remark + Refer to \ref arm_biquad_cascade_df1_q15() for a slower implementation of this function + which uses 64-bit accumulation to avoid wrap around distortion. Both the slow and the fast versions use the same instance structure. + Use the function \ref arm_biquad_cascade_df1_init_q15() to initialize the filter structure. + */ + +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) +{ + const q15_t *pIn = pSrc; /* Source pointer */ + q15_t *pOut = pDst; /* Destination pointer */ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t acc; /* Accumulator */ + q31_t in; /* Temporary variable to hold input value */ + q31_t out; /* Temporary variable to hold output value */ + q31_t b0; /* Temporary variable to hold bo value */ + q31_t b1, a1; /* Filter coefficients */ + q31_t state_in, state_out; /* Filter state variables */ + int32_t shift = (int32_t) (15 - S->postShift); /* Post shift */ + uint32_t sample, stage = S->numStages; /* Loop counters */ + + do + { + /* Read the b0 and 0 coefficients using SIMD */ + b0 = read_q15x2_ia ((q15_t **) &pCoeffs); + + /* Read the b1 and b2 coefficients using SIMD */ + b1 = read_q15x2_ia ((q15_t **) &pCoeffs); + + /* Read the a1 and a2 coefficients using SIMD */ + a1 = read_q15x2_ia ((q15_t **) &pCoeffs); + + /* Read the input state values from the state buffer: x[n-1], x[n-2] */ + state_in = read_q15x2_ia (&pState); + + /* Read the output state values from the state buffer: y[n-1], y[n-2] */ + state_out = read_q15x2_da (&pState); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Apply loop unrolling and compute 2 output values simultaneously. */ + /* Variable acc hold output values that are being computed: + * + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + */ + + /* Loop unrolling: Compute 2 outputs at a time */ + sample = blockSize >> 1U; + + while (sample > 0U) + { + + /* Read the input */ + in = read_q15x2_ia ((q15_t **) &pIn); + + /* out = b0 * x[n] + 0 * 0 */ + out = __SMUAD(b0, in); + /* acc = b1 * x[n-1] + acc += b2 * x[n-2] + out */ + acc = __SMLAD(b1, state_in, out); + /* acc += a1 * y[n-1] + acc += a2 * y[n-2] */ + acc = __SMLAD(a1, state_out, acc); + + /* The result is converted from 3.29 to 1.31 and then saturation is applied */ + out = __SSAT((acc >> shift), 16); + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + /* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */ + /* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */ + +#ifndef ARM_MATH_BIG_ENDIAN + state_in = __PKHBT(in, state_in, 16); + state_out = __PKHBT(out, state_out, 16); +#else + state_in = __PKHBT(state_in >> 16, (in >> 16), 16); + state_out = __PKHBT(state_out >> 16, (out), 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* out = b0 * x[n] + 0 * 0 */ + out = __SMUADX(b0, in); + /* acc0 = b1 * x[n-1] , acc0 += b2 * x[n-2] + out */ + acc = __SMLAD(b1, state_in, out); + /* acc += a1 * y[n-1] + acc += a2 * y[n-2] */ + acc = __SMLAD(a1, state_out, acc); + + /* The result is converted from 3.29 to 1.31 and then saturation is applied */ + out = __SSAT((acc >> shift), 16); + + /* Store the output in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT(state_out, out, 16)); +#else + write_q15x2_ia (&pOut, __PKHBT(out, state_out >> 16, 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + /* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */ + /* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */ +#ifndef ARM_MATH_BIG_ENDIAN + state_in = __PKHBT(in >> 16, state_in, 16); + state_out = __PKHBT(out, state_out, 16); +#else + state_in = __PKHBT(state_in >> 16, in, 16); + state_out = __PKHBT(state_out >> 16, out, 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Decrement loop counter */ + sample--; + } + + /* Loop unrolling: Compute remaining outputs */ + sample = (blockSize & 0x1U); + +#else + + /* Initialize blkCnt with number of samples */ + sample = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (sample > 0U) + { + /* Read the input */ + in = *pIn++; + + /* out = b0 * x[n] + 0 * 0 */ +#ifndef ARM_MATH_BIG_ENDIAN + out = __SMUAD(b0, in); +#else + out = __SMUADX(b0, in); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* acc = b1 * x[n-1], acc += b2 * x[n-2] + out */ + acc = __SMLAD(b1, state_in, out); + /* acc += a1 * y[n-1] + acc += a2 * y[n-2] */ + acc = __SMLAD(a1, state_out, acc); + + /* The result is converted from 3.29 to 1.31 and then saturation is applied */ + out = __SSAT((acc >> shift), 16); + + /* Store the output in the destination buffer. */ + *pOut++ = (q15_t) out; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + /* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */ + /* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */ +#ifndef ARM_MATH_BIG_ENDIAN + state_in = __PKHBT(in, state_in, 16); + state_out = __PKHBT(out, state_out, 16); +#else + state_in = __PKHBT(state_in >> 16, in, 16); + state_out = __PKHBT(state_out >> 16, out, 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* decrement loop counter */ + sample--; + } + + /* The first stage goes from the input buffer to the output buffer. */ + /* Subsequent (numStages - 1) occur in-place in the output buffer */ + pIn = pDst; + + /* Reset the output pointer */ + pOut = pDst; + + /* Store the updated state variables back into the state array */ + write_q15x2_ia(&pState, state_in); + write_q15x2_ia(&pState, state_out); + + /* Decrement loop counter */ + stage--; + + } while (stage > 0U); +} + +/** + @} end of BiquadCascadeDF1 group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c new file mode 100644 index 0000000..586296b --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c @@ -0,0 +1,296 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df1_fast_q31.c + * Description: Processing function for the Q31 Fast Biquad cascade DirectFormI(DF1) filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF1 + @{ + */ + +/** + @brief Processing function for the Q31 Biquad cascade filter (fast variant). + @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 per call + @return none + + @par Scaling and Overflow Behavior + This function is optimized for speed at the expense of fixed-point precision and overflow protection. + The result of each 1.31 x 1.31 multiplication is truncated to 2.30 format. + These intermediate results are added to a 2.30 accumulator. + Finally, the accumulator is saturated and converted to a 1.31 result. + The fast version has the same overflow behavior as the standard version and provides less precision since it discards the low 32 bits of each multiplication result. + In order to avoid overflows completely the input signal must be scaled down by two bits and lie in the range [-0.25 +0.25). Use the intialization function + arm_biquad_cascade_df1_init_q31() to initialize filter structure. + @remark + Refer to \ref arm_biquad_cascade_df1_q31() for a slower implementation of this function + which uses 64-bit accumulation to provide higher precision. Both the slow and the fast versions use the same instance structure. + Use the function \ref arm_biquad_cascade_df1_init_q31() to initialize the filter structure. + */ + +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) +{ + const q31_t *pIn = pSrc; /* Source pointer */ + q31_t *pOut = pDst; /* Destination pointer */ + q31_t *pState = S->pState; /* pState pointer */ + const q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t acc = 0; /* Accumulator */ + q31_t b0, b1, b2, a1, a2; /* Filter coefficients */ + q31_t Xn1, Xn2, Yn1, Yn2; /* Filter pState variables */ + q31_t Xn; /* Temporary input */ + int32_t shift = (int32_t) S->postShift + 1; /* Shift to be applied to the output */ + uint32_t sample, stage = S->numStages; /* Loop counters */ + + do + { + /* Reading the coefficients */ + b0 = *pCoeffs++; + b1 = *pCoeffs++; + b2 = *pCoeffs++; + a1 = *pCoeffs++; + a2 = *pCoeffs++; + + /* Reading the pState values */ + Xn1 = pState[0]; + Xn2 = pState[1]; + Yn1 = pState[2]; + Yn2 = pState[3]; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Apply loop unrolling and compute 4 output values simultaneously. */ + /* Variables acc ... acc3 hold output values that are being computed: + * + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + */ + + /* Loop unrolling: Compute 4 outputs at a time */ + sample = blockSize >> 2U; + + while (sample > 0U) + { + /* Read the input */ + Xn = *pIn; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + /* acc = b0 * x[n] */ + /* acc = (q31_t) (((q63_t) b1 * Xn1) >> 32);*/ + mult_32x32_keep32_R(acc, b1, Xn1); + /* acc += b1 * x[n-1] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b0 * (Xn))) >> 32);*/ + multAcc_32x32_keep32_R(acc, b0, Xn); + /* acc += b[2] * x[n-2] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b2 * (Xn2))) >> 32);*/ + multAcc_32x32_keep32_R(acc, b2, Xn2); + /* acc += a1 * y[n-1] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a1 * (Yn1))) >> 32);*/ + multAcc_32x32_keep32_R(acc, a1, Yn1); + /* acc += a2 * y[n-2] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a2 * (Yn2))) >> 32);*/ + multAcc_32x32_keep32_R(acc, a2, Yn2); + + /* The result is converted to 1.31 , Yn2 variable is reused */ + Yn2 = acc << shift; + + /* Read the second input */ + Xn2 = *(pIn + 1U); + + /* Store the output in the destination buffer. */ + *pOut = Yn2; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + /* acc = b0 * x[n] */ + /* acc = (q31_t) (((q63_t) b0 * (Xn2)) >> 32);*/ + mult_32x32_keep32_R(acc, b0, Xn2); + /* acc += b1 * x[n-1] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b1 * (Xn))) >> 32);*/ + multAcc_32x32_keep32_R(acc, b1, Xn); + /* acc += b[2] * x[n-2] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b2 * (Xn1))) >> 32);*/ + multAcc_32x32_keep32_R(acc, b2, Xn1); + /* acc += a1 * y[n-1] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a1 * (Yn2))) >> 32);*/ + multAcc_32x32_keep32_R(acc, a1, Yn2); + /* acc += a2 * y[n-2] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a2 * (Yn1))) >> 32);*/ + multAcc_32x32_keep32_R(acc, a2, Yn1); + + /* The result is converted to 1.31, Yn1 variable is reused */ + Yn1 = acc << shift; + + /* Read the third input */ + Xn1 = *(pIn + 2U); + + /* Store the output in the destination buffer. */ + *(pOut + 1U) = Yn1; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + /* acc = b0 * x[n] */ + /* acc = (q31_t) (((q63_t) b0 * (Xn1)) >> 32);*/ + mult_32x32_keep32_R(acc, b0, Xn1); + /* acc += b1 * x[n-1] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b1 * (Xn2))) >> 32);*/ + multAcc_32x32_keep32_R(acc, b1, Xn2); + /* acc += b[2] * x[n-2] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b2 * (Xn))) >> 32);*/ + multAcc_32x32_keep32_R(acc, b2, Xn); + /* acc += a1 * y[n-1] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a1 * (Yn1))) >> 32);*/ + multAcc_32x32_keep32_R(acc, a1, Yn1); + /* acc += a2 * y[n-2] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a2 * (Yn2))) >> 32);*/ + multAcc_32x32_keep32_R(acc, a2, Yn2); + + /* The result is converted to 1.31, Yn2 variable is reused */ + Yn2 = acc << shift; + + /* Read the forth input */ + Xn = *(pIn + 3U); + + /* Store the output in the destination buffer. */ + *(pOut + 2U) = Yn2; + pIn += 4U; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + /* acc = b0 * x[n] */ + /* acc = (q31_t) (((q63_t) b0 * (Xn)) >> 32);*/ + mult_32x32_keep32_R(acc, b0, Xn); + /* acc += b1 * x[n-1] */ + /*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b1 * (Xn1))) >> 32);*/ + multAcc_32x32_keep32_R(acc, b1, Xn1); + /* acc += b[2] * x[n-2] */ + /*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b2 * (Xn2))) >> 32);*/ + multAcc_32x32_keep32_R(acc, b2, Xn2); + /* acc += a1 * y[n-1] */ + /*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a1 * (Yn2))) >> 32);*/ + multAcc_32x32_keep32_R(acc, a1, Yn2); + /* acc += a2 * y[n-2] */ + /*acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a2 * (Yn1))) >> 32);*/ + multAcc_32x32_keep32_R(acc, a2, Yn1); + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + Xn2 = Xn1; + + /* The result is converted to 1.31, Yn1 variable is reused */ + Yn1 = acc << shift; + + /* Xn1 = Xn */ + Xn1 = Xn; + + /* Store the output in the destination buffer. */ + *(pOut + 3U) = Yn1; + pOut += 4U; + + /* decrement loop counter */ + sample--; + } + + /* Loop unrolling: Compute remaining outputs */ + sample = (blockSize & 0x3U); + +#else + + /* Initialize blkCnt with number of samples */ + sample = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (sample > 0U) + { + /* Read the input */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + /* acc = b0 * x[n] */ + /* acc = (q31_t) (((q63_t) b0 * (Xn)) >> 32);*/ + mult_32x32_keep32_R(acc, b0, Xn); + /* acc += b1 * x[n-1] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b1 * (Xn1))) >> 32);*/ + multAcc_32x32_keep32_R(acc, b1, Xn1); + /* acc += b[2] * x[n-2] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) b2 * (Xn2))) >> 32);*/ + multAcc_32x32_keep32_R(acc, b2, Xn2); + /* acc += a1 * y[n-1] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a1 * (Yn1))) >> 32);*/ + multAcc_32x32_keep32_R(acc, a1, Yn1); + /* acc += a2 * y[n-2] */ + /* acc = (q31_t) ((((q63_t) acc << 32) + ((q63_t) a2 * (Yn2))) >> 32);*/ + multAcc_32x32_keep32_R(acc, a2, Yn2); + + /* The result is converted to 1.31 */ + acc = acc << shift; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + Xn2 = Xn1; + Xn1 = Xn; + Yn2 = Yn1; + Yn1 = acc; + + /* Store the output in the destination buffer. */ + *pOut++ = acc; + + /* decrement loop counter */ + sample--; + } + + /* The first stage goes from the input buffer to the output buffer. */ + /* Subsequent stages occur in-place in the output buffer */ + pIn = pDst; + + /* Reset to destination pointer */ + pOut = pDst; + + /* Store the updated state variables back into the pState array */ + *pState++ = Xn1; + *pState++ = Xn2; + *pState++ = Yn1; + *pState++ = Yn2; + + } while (--stage); +} + +/** + @} end of BiquadCascadeDF1 group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c new file mode 100644 index 0000000..f51c262 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c @@ -0,0 +1,91 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df1_init_f32.c + * Description: Floating-point Biquad cascade DirectFormI(DF1) filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF1 + @{ + */ + +/** + @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] pState points to the state buffer. + @return none + + @par Coefficient and State Ordering + The coefficients are stored in the array pCoeffs in the following order: +
+      {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
+  
+ + @par + where b1x and a1x are the coefficients for the first stage, + b2x and a2x are the coefficients for the second stage, + and so on. The pCoeffs array contains a total of 5*numStages values. + @par + The pState is a pointer to state array. + Each Biquad stage has 4 state variables x[n-1], x[n-2], y[n-1], and y[n-2]. + The state variables are arranged in the pState array as: +
+      {x[n-1], x[n-2], y[n-1], y[n-2]}
+  
+ The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on. + The state array has a total length of 4*numStages values. + The state variables are updated after each block of data is processed; the coefficients are untouched. + */ + +void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState) +{ + /* Assign filter stages */ + S->numStages = numStages; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always 4 * numStages */ + memset(pState, 0, (4U * (uint32_t) numStages) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of BiquadCascadeDF1 group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c new file mode 100644 index 0000000..c2e542c --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c @@ -0,0 +1,96 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df1_init_q15.c + * Description: Q15 Biquad cascade DirectFormI(DF1) filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF1 + @{ + */ + +/** + @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 accumulator result. Varies according to the coefficients format + @return none + + @par Coefficient and State Ordering + The coefficients are stored in the array pCoeffs in the following order: +
+      {b10, 0, b11, b12, a11, a12, b20, 0, b21, b22, a21, a22, ...}
+  
+ @par + where b1x and a1x are the coefficients for the first stage, + b2x and a2x are the coefficients for the second stage, + and so on. The pCoeffs array contains a total of 6*numStages values. + The zero coefficient between b1 and b2 facilities use of 16-bit SIMD instructions on the Cortex-M4. + @par + The state variables are stored in the array pState. + Each Biquad stage has 4 state variables x[n-1], x[n-2], y[n-1], and y[n-2]. + The state variables are arranged in the pState array as: +
+      {x[n-1], x[n-2], y[n-1], y[n-2]}
+  
+ The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on. + The state array has a total length of 4*numStages values. + The state variables are updated after each block of data is processed; the coefficients are untouched. + */ + +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) +{ + /* Assign filter stages */ + S->numStages = numStages; + + /* Assign postShift to be applied to the output */ + S->postShift = postShift; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always 4 * numStages */ + memset(pState, 0, (4U * (uint32_t) numStages) * sizeof(q15_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of BiquadCascadeDF1 group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c new file mode 100644 index 0000000..8637889 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c @@ -0,0 +1,95 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df1_init_q31.c + * Description: Q31 Biquad cascade DirectFormI(DF1) filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF1 + @{ + */ + +/** + @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 after the accumulator. Varies according to the coefficients format + @return none + + @par Coefficient and State Ordering + The coefficients are stored in the array pCoeffs in the following order: +
+      {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
+  
+ @par + where b1x and a1x are the coefficients for the first stage, + b2x and a2x are the coefficients for the second stage, + and so on. The pCoeffs array contains a total of 5*numStages values. + @par + The pState points to state variables array. + Each Biquad stage has 4 state variables x[n-1], x[n-2], y[n-1], and y[n-2]. + The state variables are arranged in the pState array as: +
+      {x[n-1], x[n-2], y[n-1], y[n-2]}
+  
+ The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on. + The state array has a total length of 4*numStages values. + The state variables are updated after each block of data is processed; the coefficients are untouched. + */ + +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) +{ + /* Assign filter stages */ + S->numStages = numStages; + + /* Assign postShift to be applied to the output */ + S->postShift = postShift; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always 4 * numStages */ + memset(pState, 0, (4U * (uint32_t) numStages) * sizeof(q31_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of BiquadCascadeDF1 group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_q15.c new file mode 100644 index 0000000..9e23897 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_q15.c @@ -0,0 +1,363 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df1_q15.c + * Description: Processing function for the Q15 Biquad cascade DirectFormI(DF1) filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF1 + @{ + */ + +/** + @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 location where the output result is written + @param[in] blockSize number of samples to process + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both coefficients 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. + The accumulator is then shifted by postShift bits to truncate the result to 1.15 format by discarding the low 16 bits. + Finally, the result is saturated to 1.15 format. + @remark + Refer to \ref arm_biquad_cascade_df1_fast_q15() for a faster but less precise implementation of this filter. + */ + +void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + + +#if defined (ARM_MATH_DSP) + + const q15_t *pIn = pSrc; /* Source pointer */ + q15_t *pOut = pDst; /* Destination pointer */ + q31_t in; /* Temporary variable to hold input value */ + q31_t out; /* Temporary variable to hold output value */ + q31_t b0; /* Temporary variable to hold bo value */ + q31_t b1, a1; /* Filter coefficients */ + q31_t state_in, state_out; /* Filter state variables */ + q31_t acc_l, acc_h; + q63_t acc; /* Accumulator */ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + int32_t lShift = (15 - (int32_t) S->postShift); /* Post shift */ + uint32_t sample, stage = (uint32_t) S->numStages; /* Stage loop counter */ + int32_t uShift = (32 - lShift); + + do + { + /* Read the b0 and 0 coefficients using SIMD */ + b0 = read_q15x2_ia ((q15_t **) &pCoeffs); + + /* Read the b1 and b2 coefficients using SIMD */ + b1 = read_q15x2_ia ((q15_t **) &pCoeffs); + + /* Read the a1 and a2 coefficients using SIMD */ + a1 = read_q15x2_ia ((q15_t **) &pCoeffs); + + /* Read the input state values from the state buffer: x[n-1], x[n-2] */ + state_in = read_q15x2_ia (&pState); + + /* Read the output state values from the state buffer: y[n-1], y[n-2] */ + state_out = read_q15x2_da (&pState); + + /* Apply loop unrolling and compute 2 output values simultaneously. */ + /* The variable acc hold output values that are being computed: + * + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + */ + sample = blockSize >> 1U; + + /* First part of the processing with loop unrolling. Compute 2 outputs at a time. + ** a second loop below computes the remaining 1 sample. */ + while (sample > 0U) + { + + /* Read the input */ + in = read_q15x2_ia ((q15_t **) &pIn); + + /* out = b0 * x[n] + 0 * 0 */ + out = __SMUAD(b0, in); + + /* acc += b1 * x[n-1] + b2 * x[n-2] + out */ + acc = __SMLALD(b1, state_in, out); + /* acc += a1 * y[n-1] + a2 * y[n-2] */ + acc = __SMLALD(a1, state_out, acc); + + /* The result is converted from 3.29 to 1.31 if postShift = 1, and then saturation is applied */ + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + /* Apply shift for lower part of acc and upper part of acc */ + out = (uint32_t) acc_l >> lShift | acc_h << uShift; + + out = __SSAT(out, 16); + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + /* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */ + /* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */ + +#ifndef ARM_MATH_BIG_ENDIAN + state_in = __PKHBT(in, state_in, 16); + state_out = __PKHBT(out, state_out, 16); +#else + state_in = __PKHBT(state_in >> 16, (in >> 16), 16); + state_out = __PKHBT(state_out >> 16, (out), 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* out = b0 * x[n] + 0 * 0 */ + out = __SMUADX(b0, in); + /* acc += b1 * x[n-1] + b2 * x[n-2] + out */ + acc = __SMLALD(b1, state_in, out); + /* acc += a1 * y[n-1] + a2 * y[n-2] */ + acc = __SMLALD(a1, state_out, acc); + + /* The result is converted from 3.29 to 1.31 if postShift = 1, and then saturation is applied */ + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + /* Apply shift for lower part of acc and upper part of acc */ + out = (uint32_t) acc_l >> lShift | acc_h << uShift; + + out = __SSAT(out, 16); + + /* Store the output in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT(state_out, out, 16)); +#else + write_q15x2_ia (&pOut, __PKHBT(out, state_out >> 16, 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + /* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */ + /* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */ +#ifndef ARM_MATH_BIG_ENDIAN + state_in = __PKHBT(in >> 16, state_in, 16); + state_out = __PKHBT(out, state_out, 16); +#else + state_in = __PKHBT(state_in >> 16, in, 16); + state_out = __PKHBT(state_out >> 16, out, 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Decrement loop counter */ + sample--; + } + + /* If the blockSize is not a multiple of 2, compute any remaining output samples here. + ** No loop unrolling is used. */ + + if ((blockSize & 0x1U) != 0U) + { + /* Read the input */ + in = *pIn++; + + /* out = b0 * x[n] + 0 * 0 */ +#ifndef ARM_MATH_BIG_ENDIAN + out = __SMUAD(b0, in); +#else + out = __SMUADX(b0, in); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* acc = b1 * x[n-1] + b2 * x[n-2] + out */ + acc = __SMLALD(b1, state_in, out); + /* acc += a1 * y[n-1] + a2 * y[n-2] */ + acc = __SMLALD(a1, state_out, acc); + + /* The result is converted from 3.29 to 1.31 if postShift = 1, and then saturation is applied */ + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + /* Apply shift for lower part of acc and upper part of acc */ + out = (uint32_t) acc_l >> lShift | acc_h << uShift; + + out = __SSAT(out, 16); + + /* Store the output in the destination buffer. */ + *pOut++ = (q15_t) out; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + /* x[n-N], x[n-N-1] are packed together to make state_in of type q31 */ + /* y[n-N], y[n-N-1] are packed together to make state_out of type q31 */ +#ifndef ARM_MATH_BIG_ENDIAN + state_in = __PKHBT(in, state_in, 16); + state_out = __PKHBT(out, state_out, 16); +#else + state_in = __PKHBT(state_in >> 16, in, 16); + state_out = __PKHBT(state_out >> 16, out, 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + } + + /* The first stage goes from the input wire to the output wire. */ + /* Subsequent numStages occur in-place in the output wire */ + pIn = pDst; + + /* Reset the output pointer */ + pOut = pDst; + + /* Store the updated state variables back into the state array */ + write_q15x2_ia (&pState, state_in); + write_q15x2_ia (&pState, state_out); + + /* Decrement loop counter */ + stage--; + + } while (stage > 0U); + +#else + + const q15_t *pIn = pSrc; /* Source pointer */ + q15_t *pOut = pDst; /* Destination pointer */ + q15_t b0, b1, b2, a1, a2; /* Filter coefficients */ + q15_t Xn1, Xn2, Yn1, Yn2; /* Filter state variables */ + q15_t Xn; /* temporary input */ + q63_t acc; /* Accumulator */ + int32_t shift = (15 - (int32_t) S->postShift); /* Post shift */ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + uint32_t sample, stage = (uint32_t) S->numStages; /* Stage loop counter */ + + do + { + /* Reading the coefficients */ + b0 = *pCoeffs++; + pCoeffs++; // skip the 0 coefficient + b1 = *pCoeffs++; + b2 = *pCoeffs++; + a1 = *pCoeffs++; + a2 = *pCoeffs++; + + /* Reading the state values */ + Xn1 = pState[0]; + Xn2 = pState[1]; + Yn1 = pState[2]; + Yn2 = pState[3]; + + /* The variables acc holds the output value that is computed: + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + */ + + sample = blockSize; + + while (sample > 0U) + { + /* Read the input */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + /* acc = b0 * x[n] */ + acc = (q31_t) b0 *Xn; + + /* acc += b1 * x[n-1] */ + acc += (q31_t) b1 *Xn1; + /* acc += b[2] * x[n-2] */ + acc += (q31_t) b2 *Xn2; + /* acc += a1 * y[n-1] */ + acc += (q31_t) a1 *Yn1; + /* acc += a2 * y[n-2] */ + acc += (q31_t) a2 *Yn2; + + /* The result is converted to 1.31 */ + acc = __SSAT((acc >> shift), 16); + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + Xn2 = Xn1; + Xn1 = Xn; + Yn2 = Yn1; + Yn1 = (q15_t) acc; + + /* Store the output in the destination buffer. */ + *pOut++ = (q15_t) acc; + + /* decrement the loop counter */ + sample--; + } + + /* The first stage goes from the input buffer to the output buffer. */ + /* Subsequent stages occur in-place in the output buffer */ + pIn = pDst; + + /* Reset to destination pointer */ + pOut = pDst; + + /* Store the updated state variables back into the pState array */ + *pState++ = Xn1; + *pState++ = Xn2; + *pState++ = Yn1; + *pState++ = Yn2; + + } while (--stage); + +#endif /* #if defined (ARM_MATH_DSP) */ + +} + +/** + @} end of BiquadCascadeDF1 group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_q31.c new file mode 100644 index 0000000..011e21d --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df1_q31.c @@ -0,0 +1,247 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df1_q31.c + * Description: Processing function for the Q31 Biquad cascade filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF1 + @{ + */ + +/** + @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 + @return none + + @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 and lie in the range [-0.25 +0.25). + After all 5 multiply-accumulates are performed, the 2.62 accumulator is shifted by postShift bits and the result truncated to + 1.31 format by discarding the low 32 bits. + @remark + Refer to \ref arm_biquad_cascade_df1_fast_q31() for a faster but less precise implementation of this filter. + */ + +void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + const q31_t *pIn = pSrc; /* Source pointer */ + q31_t *pOut = pDst; /* Destination pointer */ + q31_t *pState = S->pState; /* pState pointer */ + const q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q63_t acc; /* Accumulator */ + q31_t b0, b1, b2, a1, a2; /* Filter coefficients */ + q31_t Xn1, Xn2, Yn1, Yn2; /* Filter pState variables */ + q31_t Xn; /* Temporary input */ + uint32_t uShift = ((uint32_t) S->postShift + 1U); + uint32_t lShift = 32U - uShift; /* Shift to be applied to the output */ + uint32_t sample, stage = S->numStages; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc_l, acc_h; /* temporary output variables */ +#endif + + do + { + /* Reading the coefficients */ + b0 = *pCoeffs++; + b1 = *pCoeffs++; + b2 = *pCoeffs++; + a1 = *pCoeffs++; + a2 = *pCoeffs++; + + /* Reading the pState values */ + Xn1 = pState[0]; + Xn2 = pState[1]; + Yn1 = pState[2]; + Yn2 = pState[3]; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Apply loop unrolling and compute 4 output values simultaneously. */ + /* Variable acc hold output values that are being computed: + * + * acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] + */ + + /* Loop unrolling: Compute 4 outputs at a time */ + sample = blockSize >> 2U; + + while (sample > 0U) + { + /* Read the first input */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + acc = ((q63_t) b0 * Xn) + ((q63_t) b1 * Xn1) + ((q63_t) b2 * Xn2) + ((q63_t) a1 * Yn1) + ((q63_t) a2 * Yn2); + + /* The result is converted to 1.31 , Yn2 variable is reused */ + acc_l = (acc ) & 0xffffffff; /* Calc lower part of acc */ + acc_h = (acc >> 32) & 0xffffffff; /* Calc upper part of acc */ + + /* Apply shift for lower part of acc and upper part of acc */ + Yn2 = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Store output in destination buffer. */ + *pOut++ = Yn2; + + /* Read the second input */ + Xn2 = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + acc = ((q63_t) b0 * Xn2) + ((q63_t) b1 * Xn) + ((q63_t) b2 * Xn1) + ((q63_t) a1 * Yn2) + ((q63_t) a2 * Yn1); + + /* The result is converted to 1.31, Yn1 variable is reused */ + acc_l = (acc ) & 0xffffffff; /* Calc lower part of acc */ + acc_h = (acc >> 32) & 0xffffffff; /* Calc upper part of acc */ + + /* Apply shift for lower part of acc and upper part of acc */ + Yn1 = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Store output in destination buffer. */ + *pOut++ = Yn1; + + /* Read the third input */ + Xn1 = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + acc = ((q63_t) b0 * Xn1) + ((q63_t) b1 * Xn2) + ((q63_t) b2 * Xn) + ((q63_t) a1 * Yn1) + ((q63_t) a2 * Yn2); + + /* The result is converted to 1.31, Yn2 variable is reused */ + acc_l = (acc ) & 0xffffffff; /* Calc lower part of acc */ + acc_h = (acc >> 32) & 0xffffffff; /* Calc upper part of acc */ + + /* Apply shift for lower part of acc and upper part of acc */ + Yn2 = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Store output in destination buffer. */ + *pOut++ = Yn2; + + /* Read the forth input */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + acc = ((q63_t) b0 * Xn) + ((q63_t) b1 * Xn1) + ((q63_t) b2 * Xn2) + ((q63_t) a1 * Yn2) + ((q63_t) a2 * Yn1); + + /* The result is converted to 1.31, Yn1 variable is reused */ + acc_l = (acc ) & 0xffffffff; /* Calc lower part of acc */ + acc_h = (acc >> 32) & 0xffffffff; /* Calc upper part of acc */ + + /* Apply shift for lower part of acc and upper part of acc */ + Yn1 = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Store output in destination buffer. */ + *pOut++ = Yn1; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + Xn2 = Xn1; + Xn1 = Xn; + + /* decrement loop counter */ + sample--; + } + + /* Loop unrolling: Compute remaining outputs */ + sample = blockSize & 0x3U; + +#else + + /* Initialize blkCnt with number of samples */ + sample = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (sample > 0U) + { + /* Read the input */ + Xn = *pIn++; + + /* acc = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] */ + acc = ((q63_t) b0 * Xn) + ((q63_t) b1 * Xn1) + ((q63_t) b2 * Xn2) + ((q63_t) a1 * Yn1) + ((q63_t) a2 * Yn2); + + /* The result is converted to 1.31 */ + acc = acc >> lShift; + + /* Store output in destination buffer. */ + *pOut++ = (q31_t) acc; + + /* Every time after the output is computed state should be updated. */ + /* The states should be updated as: */ + /* Xn2 = Xn1 */ + /* Xn1 = Xn */ + /* Yn2 = Yn1 */ + /* Yn1 = acc */ + Xn2 = Xn1; + Xn1 = Xn; + Yn2 = Yn1; + Yn1 = (q31_t) acc; + + /* decrement loop counter */ + sample--; + } + + /* Store the updated state variables back into the pState array */ + *pState++ = Xn1; + *pState++ = Xn2; + *pState++ = Yn1; + *pState++ = Yn2; + + /* The first stage goes from the input buffer to the output buffer. */ + /* Subsequent numStages occur in-place in the output buffer */ + pIn = pDst; + + /* Reset output pointer */ + pOut = pDst; + + /* decrement loop counter */ + stage--; + + } while (stage > 0U); + +} + +/** + @} end of BiquadCascadeDF1 group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_f32.c new file mode 100644 index 0000000..112d75a --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_f32.c @@ -0,0 +1,354 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df2T_f32.c + * Description: Processing function for floating-point transposed direct form II Biquad cascade filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters +*/ + +/** + @addtogroup BiquadCascadeDF2T + @{ + */ + +/** + @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 + @return none + */ + +LOW_OPTIMIZATION_ENTER +void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + const float32_t *pIn = pSrc; /* Source pointer */ + float32_t *pOut = pDst; /* Destination pointer */ + float32_t *pState = S->pState; /* State pointer */ + const float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t acc1; /* Accumulator */ + float32_t b0, b1, b2, a1, a2; /* Filter coefficients */ + float32_t Xn1; /* Temporary input */ + float32_t d1, d2; /* State variables */ + uint32_t sample, stage = S->numStages; /* Loop counters */ + + + do + { + /* Reading the coefficients */ + b0 = pCoeffs[0]; + b1 = pCoeffs[1]; + b2 = pCoeffs[2]; + a1 = pCoeffs[3]; + a2 = pCoeffs[4]; + + /* Reading the state values */ + d1 = pState[0]; + d2 = pState[1]; + + pCoeffs += 5U; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 16 outputs at a time */ + sample = blockSize >> 4U; + + while (sample > 0U) { + + /* y[n] = b0 * x[n] + d1 */ + /* d1 = b1 * x[n] + a1 * y[n] + d2 */ + /* d2 = b2 * x[n] + a2 * y[n] */ + +/* 1 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 2 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 3 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 4 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 5 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 6 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 7 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 8 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 9 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 10 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 11 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 12 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 13 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 14 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 15 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 16 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + + /* decrement loop counter */ + sample--; + } + + /* Loop unrolling: Compute remaining outputs */ + sample = blockSize & 0xFU; + +#else + + /* Initialize blkCnt with number of samples */ + sample = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (sample > 0U) { + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + + /* decrement loop counter */ + sample--; + } + + /* Store the updated state variables back into the state array */ + pState[0] = d1; + pState[1] = d2; + + pState += 2U; + + /* The current stage input is given as the output to the next stage */ + pIn = pDst; + + /* Reset the output working pointer */ + pOut = pDst; + + /* decrement loop counter */ + stage--; + + } while (stage > 0U); + +} +LOW_OPTIMIZATION_EXIT + +/** + @} end of BiquadCascadeDF2T group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_f64.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_f64.c new file mode 100644 index 0000000..a8af8ce --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_f64.c @@ -0,0 +1,443 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df2T_f64.c + * Description: Processing function for floating-point transposed direct form II Biquad cascade filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters +*/ + +/** + @defgroup BiquadCascadeDF2T Biquad Cascade IIR Filters Using a Direct Form II Transposed Structure + + This set of functions implements arbitrary order recursive (IIR) filters using a transposed direct form II structure. + The filters are implemented as a cascade of second order Biquad sections. + These functions provide a slight memory savings as compared to the direct form I Biquad filter functions. + Only floating-point data is supported. + + This function operate on blocks of input and output data and each call to the function + processes blockSize samples through the filter. + pSrc points to the array of input data and + pDst points to the array of output data. + Both arrays contain blockSize values. + + @par Algorithm + Each Biquad stage implements a second order filter using the difference equation: +
+     y[n] = b0 * x[n] + d1
+     d1 = b1 * x[n] + a1 * y[n] + d2
+     d2 = b2 * x[n] + a2 * y[n]
+  
+ where d1 and d2 represent the two state values. + @par + A Biquad filter using a transposed Direct Form II structure is shown below. + \image html BiquadDF2Transposed.gif "Single transposed Direct Form II Biquad" + Coefficients b0, b1, and b2 multiply the input signal x[n] and are referred to as the feedforward coefficients. + Coefficients a1 and a2 multiply the output signal y[n] and are referred to as the feedback coefficients. + Pay careful attention to the sign of the feedback coefficients. + Some design tools flip the sign of the feedback coefficients: +
+     y[n] = b0 * x[n] + d1;
+     d1 = b1 * x[n] - a1 * y[n] + d2;
+     d2 = b2 * x[n] - a2 * y[n];
+  
+ In this case the feedback coefficients a1 and a2 must be negated when used with the CMSIS DSP Library. + @par + Higher order filters are realized as a cascade of second order sections. + numStages refers to the number of second order stages used. + For example, an 8th order filter would be realized with numStages=4 second order stages. + A 9th order filter would be realized with numStages=5 second order stages with the + coefficients for one of the stages configured as a first order filter (b2=0 and a2=0). + @par + pState points to the state variable array. + Each Biquad stage has 2 state variables d1 and d2. + The state variables are arranged in the pState array as: +
+      {d11, d12, d21, d22, ...}
+  
+ where d1x refers to the state variables for the first Biquad and + d2x refers to the state variables for the second Biquad. + The state array has a total length of 2*numStages values. + The state variables are updated after each block of data is processed; the coefficients are untouched. + @par + The CMSIS library contains Biquad filters in both Direct Form I and transposed Direct Form II. + The advantage of the Direct Form I structure is that it is numerically more robust for fixed-point data types. + That is why the Direct Form I structure supports Q15 and Q31 data types. + The transposed Direct Form II structure, on the other hand, requires a wide dynamic range for the state variables d1 and d2. + Because of this, the CMSIS library only has a floating-point version of the Direct Form II Biquad. + The advantage of the Direct Form II Biquad is that it requires half the number of state variables, 2 rather than 4, per Biquad stage. + + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter. + Coefficient arrays may be shared among several instances while state variable arrays cannot be shared. + + @par Init Functions + There is also an associated initialization function. + The initialization function performs following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + numStages, pCoeffs, pState. Also set all of the values in pState to zero. + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + Set the values in the state buffer to zeros before static initialization. + For example, to statically initialize the instance structure use +
+      arm_biquad_cascade_df2T_instance_f64 S1 = {numStages, pState, pCoeffs};
+      arm_biquad_cascade_df2T_instance_f32 S1 = {numStages, pState, pCoeffs};
+  
+ where numStages is the number of Biquad stages in the filter; + pState is the address of the state buffer. + pCoeffs is the address of the coefficient buffer; +*/ + +/** + @addtogroup BiquadCascadeDF2T + @{ + */ + +/** + @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 + @return none + */ + +LOW_OPTIMIZATION_ENTER +void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize) +{ + + float64_t *pIn = pSrc; /* Source pointer */ + float64_t *pOut = pDst; /* Destination pointer */ + float64_t *pState = S->pState; /* State pointer */ + float64_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float64_t acc1; /* Accumulator */ + float64_t b0, b1, b2, a1, a2; /* Filter coefficients */ + float64_t Xn1; /* Temporary input */ + float64_t d1, d2; /* State variables */ + uint32_t sample, stage = S->numStages; /* Loop counters */ + + + do + { + /* Reading the coefficients */ + b0 = pCoeffs[0]; + b1 = pCoeffs[1]; + b2 = pCoeffs[2]; + a1 = pCoeffs[3]; + a2 = pCoeffs[4]; + + /* Reading the state values */ + d1 = pState[0]; + d2 = pState[1]; + + pCoeffs += 5U; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 16 outputs at a time */ + sample = blockSize >> 4U; + + while (sample > 0U) { + + /* y[n] = b0 * x[n] + d1 */ + /* d1 = b1 * x[n] + a1 * y[n] + d2 */ + /* d2 = b2 * x[n] + a2 * y[n] */ + +/* 1 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + + +/* 2 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 3 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 4 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 5 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 6 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 7 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 8 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 9 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 10 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 11 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 12 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 13 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 14 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 15 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + +/* 16 */ + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + + /* decrement loop counter */ + sample--; + } + + /* Loop unrolling: Compute remaining outputs */ + sample = blockSize & 0xFU; + +#else + + /* Initialize blkCnt with number of samples */ + sample = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (sample > 0U) { + Xn1 = *pIn++; + + acc1 = b0 * Xn1 + d1; + + d1 = b1 * Xn1 + d2; + d1 += a1 * acc1; + + d2 = b2 * Xn1; + d2 += a2 * acc1; + + *pOut++ = acc1; + + /* decrement loop counter */ + sample--; + } + + /* Store the updated state variables back into the state array */ + pState[0] = d1; + pState[1] = d2; + + pState += 2U; + + /* The current stage input is given as the output to the next stage */ + pIn = pDst; + + /* Reset the output working pointer */ + pOut = pDst; + + /* decrement loop counter */ + stage--; + + } while (stage > 0U); + +} +LOW_OPTIMIZATION_EXIT + +/** + @} end of BiquadCascadeDF2T group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c new file mode 100644 index 0000000..33b7f18 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df2T_init_f32.c + * Description: Initialization function for floating-point transposed direct form II Biquad cascade filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF2T + @{ + */ + +/** + @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. + @return none + + @par Coefficient and State Ordering + The coefficients are stored in the array pCoeffs in the following order: +
+      {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
+  
+ @par + where b1x and a1x are the coefficients for the first stage, + b2x and a2x are the coefficients for the second stage, + and so on. The pCoeffs array contains a total of 5*numStages values. + @par + The pState is a pointer to state array. + Each Biquad stage has 2 state variables d1, and d2. + The 2 state variables for stage 1 are first, then the 2 state variables for stage 2, and so on. + The state array has a total length of 2*numStages values. + The state variables are updated after each block of data is processed; the coefficients are untouched. + */ + +void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState) +{ + /* Assign filter stages */ + S->numStages = numStages; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always 2 * numStages */ + memset(pState, 0, (2U * (uint32_t) numStages) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of BiquadCascadeDF2T group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c new file mode 100644 index 0000000..fe6901e --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_df2T_init_f64.c + * Description: Initialization function for floating-point transposed direct form II Biquad cascade filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF2T + @{ + */ + +/** + @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 + @return none + + @par Coefficient and State Ordering + The coefficients are stored in the array pCoeffs in the following order: +
+      {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
+  
+ @par + where b1x and a1x are the coefficients for the first stage, + b2x and a2x are the coefficients for the second stage, + and so on. The pCoeffs array contains a total of 5*numStages values. + @par + The pState is a pointer to state array. + Each Biquad stage has 2 state variables d1, and d2. + The 2 state variables for stage 1 are first, then the 2 state variables for stage 2, and so on. + The state array has a total length of 2*numStages values. + The state variables are updated after each block of data is processed; the coefficients are untouched. + */ + +void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState) +{ + /* Assign filter stages */ + S->numStages = numStages; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always 2 * numStages */ + memset(pState, 0, (2U * (uint32_t) numStages) * sizeof(float64_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of BiquadCascadeDF2T group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c new file mode 100644 index 0000000..d6be426 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c @@ -0,0 +1,286 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_stereo_df2T_f32.c + * Description: Processing function for floating-point transposed direct form II Biquad cascade filter. 2 channels + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters +*/ + +/** + @addtogroup BiquadCascadeDF2T + @{ + */ + +/** + @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 + @return none + */ + +LOW_OPTIMIZATION_ENTER +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) +{ + const float32_t *pIn = pSrc; /* Source pointer */ + float32_t *pOut = pDst; /* Destination pointer */ + float32_t *pState = S->pState; /* State pointer */ + const float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t acc1a, acc1b; /* Accumulator */ + float32_t b0, b1, b2, a1, a2; /* Filter coefficients */ + float32_t Xn1a, Xn1b; /* Temporary input */ + float32_t d1a, d2a, d1b, d2b; /* State variables */ + uint32_t sample, stage = S->numStages; /* Loop counters */ + + do + { + /* Reading the coefficients */ + b0 = pCoeffs[0]; + b1 = pCoeffs[1]; + b2 = pCoeffs[2]; + a1 = pCoeffs[3]; + a2 = pCoeffs[4]; + + /* Reading the state values */ + d1a = pState[0]; + d2a = pState[1]; + d1b = pState[2]; + d2b = pState[3]; + + pCoeffs += 5U; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 8 outputs at a time */ + sample = blockSize >> 3U; + + while (sample > 0U) { + /* y[n] = b0 * x[n] + d1 */ + /* d1 = b1 * x[n] + a1 * y[n] + d2 */ + /* d2 = b2 * x[n] + a2 * y[n] */ + +/* 1 */ + Xn1a = *pIn++; /* Channel a */ + Xn1b = *pIn++; /* Channel b */ + + acc1a = (b0 * Xn1a) + d1a; + acc1b = (b0 * Xn1b) + d1b; + + *pOut++ = acc1a; + *pOut++ = acc1b; + + d1a = ((b1 * Xn1a) + (a1 * acc1a)) + d2a; + d1b = ((b1 * Xn1b) + (a1 * acc1b)) + d2b; + + d2a = (b2 * Xn1a) + (a2 * acc1a); + d2b = (b2 * Xn1b) + (a2 * acc1b); + +/* 2 */ + Xn1a = *pIn++; /* Channel a */ + Xn1b = *pIn++; /* Channel b */ + + acc1a = (b0 * Xn1a) + d1a; + acc1b = (b0 * Xn1b) + d1b; + + *pOut++ = acc1a; + *pOut++ = acc1b; + + d1a = ((b1 * Xn1a) + (a1 * acc1a)) + d2a; + d1b = ((b1 * Xn1b) + (a1 * acc1b)) + d2b; + + d2a = (b2 * Xn1a) + (a2 * acc1a); + d2b = (b2 * Xn1b) + (a2 * acc1b); + +/* 3 */ + Xn1a = *pIn++; /* Channel a */ + Xn1b = *pIn++; /* Channel b */ + + acc1a = (b0 * Xn1a) + d1a; + acc1b = (b0 * Xn1b) + d1b; + + *pOut++ = acc1a; + *pOut++ = acc1b; + + d1a = ((b1 * Xn1a) + (a1 * acc1a)) + d2a; + d1b = ((b1 * Xn1b) + (a1 * acc1b)) + d2b; + + d2a = (b2 * Xn1a) + (a2 * acc1a); + d2b = (b2 * Xn1b) + (a2 * acc1b); + +/* 4 */ + Xn1a = *pIn++; /* Channel a */ + Xn1b = *pIn++; /* Channel b */ + + acc1a = (b0 * Xn1a) + d1a; + acc1b = (b0 * Xn1b) + d1b; + + *pOut++ = acc1a; + *pOut++ = acc1b; + + d1a = ((b1 * Xn1a) + (a1 * acc1a)) + d2a; + d1b = ((b1 * Xn1b) + (a1 * acc1b)) + d2b; + + d2a = (b2 * Xn1a) + (a2 * acc1a); + d2b = (b2 * Xn1b) + (a2 * acc1b); + +/* 5 */ + Xn1a = *pIn++; /* Channel a */ + Xn1b = *pIn++; /* Channel b */ + + acc1a = (b0 * Xn1a) + d1a; + acc1b = (b0 * Xn1b) + d1b; + + *pOut++ = acc1a; + *pOut++ = acc1b; + + d1a = ((b1 * Xn1a) + (a1 * acc1a)) + d2a; + d1b = ((b1 * Xn1b) + (a1 * acc1b)) + d2b; + + d2a = (b2 * Xn1a) + (a2 * acc1a); + d2b = (b2 * Xn1b) + (a2 * acc1b); + +/* 6 */ + Xn1a = *pIn++; /* Channel a */ + Xn1b = *pIn++; /* Channel b */ + + acc1a = (b0 * Xn1a) + d1a; + acc1b = (b0 * Xn1b) + d1b; + + *pOut++ = acc1a; + *pOut++ = acc1b; + + d1a = ((b1 * Xn1a) + (a1 * acc1a)) + d2a; + d1b = ((b1 * Xn1b) + (a1 * acc1b)) + d2b; + + d2a = (b2 * Xn1a) + (a2 * acc1a); + d2b = (b2 * Xn1b) + (a2 * acc1b); + +/* 7 */ + Xn1a = *pIn++; /* Channel a */ + Xn1b = *pIn++; /* Channel b */ + + acc1a = (b0 * Xn1a) + d1a; + acc1b = (b0 * Xn1b) + d1b; + + *pOut++ = acc1a; + *pOut++ = acc1b; + + d1a = ((b1 * Xn1a) + (a1 * acc1a)) + d2a; + d1b = ((b1 * Xn1b) + (a1 * acc1b)) + d2b; + + d2a = (b2 * Xn1a) + (a2 * acc1a); + d2b = (b2 * Xn1b) + (a2 * acc1b); + +/* 8 */ + Xn1a = *pIn++; /* Channel a */ + Xn1b = *pIn++; /* Channel b */ + + acc1a = (b0 * Xn1a) + d1a; + acc1b = (b0 * Xn1b) + d1b; + + *pOut++ = acc1a; + *pOut++ = acc1b; + + d1a = ((b1 * Xn1a) + (a1 * acc1a)) + d2a; + d1b = ((b1 * Xn1b) + (a1 * acc1b)) + d2b; + + d2a = (b2 * Xn1a) + (a2 * acc1a); + d2b = (b2 * Xn1b) + (a2 * acc1b); + + /* decrement loop counter */ + sample--; + } + + /* Loop unrolling: Compute remaining outputs */ + sample = blockSize & 0x7U; + +#else + + /* Initialize blkCnt with number of samples */ + sample = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (sample > 0U) { + /* Read the input */ + Xn1a = *pIn++; /* Channel a */ + Xn1b = *pIn++; /* Channel b */ + + /* y[n] = b0 * x[n] + d1 */ + acc1a = (b0 * Xn1a) + d1a; + acc1b = (b0 * Xn1b) + d1b; + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = acc1a; + *pOut++ = acc1b; + + /* Every time after the output is computed state should be updated. */ + /* d1 = b1 * x[n] + a1 * y[n] + d2 */ + d1a = ((b1 * Xn1a) + (a1 * acc1a)) + d2a; + d1b = ((b1 * Xn1b) + (a1 * acc1b)) + d2b; + + /* d2 = b2 * x[n] + a2 * y[n] */ + d2a = (b2 * Xn1a) + (a2 * acc1a); + d2b = (b2 * Xn1b) + (a2 * acc1b); + + /* decrement loop counter */ + sample--; + } + + /* Store the updated state variables back into the state array */ + pState[0] = d1a; + pState[1] = d2a; + + pState[2] = d1b; + pState[3] = d2b; + + pState += 4U; + + /* The current stage input is given as the output to the next stage */ + pIn = pDst; + + /* Reset the output working pointer */ + pOut = pDst; + + /* decrement the loop counter */ + stage--; + + } while (stage > 0U); + +} +LOW_OPTIMIZATION_EXIT + +/** + @} end of BiquadCascadeDF2T group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c new file mode 100644 index 0000000..d398f18 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_biquad_cascade_stereo_df2T_init_f32.c + * Description: Initialization function for floating-point transposed direct form II Biquad cascade filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup BiquadCascadeDF2T + @{ + */ + +/** + @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. + @return none + + @par Coefficient and State Ordering + The coefficients are stored in the array pCoeffs in the following order: +
+      {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
+  
+ @par + where b1x and a1x are the coefficients for the first stage, + b2x and a2x are the coefficients for the second stage, + and so on. The pCoeffs array contains a total of 5*numStages values. + @par + The pState is a pointer to state array. + Each Biquad stage has 2 state variables d1, and d2 for each channel. + The 2 state variables for stage 1 are first, then the 2 state variables for stage 2, and so on. + The state array has a total length of 2*numStages values. + The state variables are updated after each block of data is processed; the coefficients are untouched. + */ + +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) +{ + /* Assign filter stages */ + S->numStages = numStages; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always 4 * numStages */ + memset(pState, 0, (4U * (uint32_t) numStages) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of BiquadCascadeDF2T group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_f32.c new file mode 100644 index 0000000..4786b5b --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_f32.c @@ -0,0 +1,640 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_f32.c + * Description: Convolution of floating-point sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup Conv Convolution + + Convolution is a mathematical operation that operates on two finite length vectors to generate a finite length output vector. + Convolution is similar to correlation and is frequently used in filtering and data analysis. + The CMSIS DSP library contains functions for convolving Q7, Q15, Q31, and floating-point data types. + The library also provides fast versions of the Q15 and Q31 functions. + + @par Algorithm + Let a[n] and b[n] be sequences of length srcALen and + srcBLen samples respectively. Then the convolution +
+     c[n] = a[n] * b[n]
+  
+ @par + is defined as + \image html ConvolutionEquation.gif + @par + Note that c[n] is of length srcALen + srcBLen - 1 and is defined over the interval n=0, 1, 2, ..., srcALen + srcBLen - 2. + pSrcA points to the first input vector of length srcALen and + pSrcB points to the second input vector of length srcBLen. + The output result is written to pDst and the calling function must allocate srcALen+srcBLen-1 words for the result. + @par + Conceptually, when two signals a[n] and b[n] are convolved, + the signal b[n] slides over a[n]. + For each offset \c n, the overlapping portions of a[n] and b[n] are multiplied and summed together. + @par + Note that convolution is a commutative operation: +
+     a[n] * b[n] = b[n] * a[n].
+  
+ @par + This means that switching the A and B arguments to the convolution functions has no effect. + + @par Fixed-Point Behavior + Convolution requires summing up a large number of intermediate products. + As such, the Q7, Q15, and Q31 functions run a risk of overflow and saturation. + Refer to the function specific documentation below for further details of the particular algorithm used. + + @par Fast Versions + Fast versions are supported for Q31 and Q15. Cycles for Fast versions are less compared to Q31 and Q15 of conv and the design requires + the input signals should be scaled down to avoid intermediate overflows. + + @par Opt Versions + Opt versions are supported for Q15 and Q7. Design uses internal scratch buffer for getting good optimisation. + These versions are optimised in cycles and consumes more memory (Scratch memory) compared to Q15 and Q7 versions + */ + +/** + @addtogroup Conv + @{ + */ + +/** + @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. + @return none + */ + +void arm_conv_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst) +{ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + const float32_t *pIn1; /* InputA pointer */ + const float32_t *pIn2; /* InputB pointer */ + float32_t *pOut = pDst; /* Output pointer */ + const float32_t *px; /* Intermediate inputA pointer */ + const float32_t *py; /* Intermediate inputB pointer */ + const float32_t *pSrc1, *pSrc2; /* Intermediate pointers */ + float32_t sum; /* Accumulators */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + float32_t acc0, acc1, acc2, acc3; /* Accumulators */ + float32_t x0, x1, x2, x3, c0; /* Temporary variables to hold state and coefficient values */ +#endif + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[0] * y[srcBLen - 1] */ + sum += *px++ * *py--; + + /* x[1] * y[srcBLen - 2] */ + sum += *px++ * *py--; + + /* x[2] * y[srcBLen - 3] */ + sum += *px++ * *py--; + + /* x[3] * y[srcBLen - 4] */ + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum; + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pIn2 + count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize2 >> 2U; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0.0f; + acc1 = 0.0f; + acc2 = 0.0f; + acc3 = 0.0f; + + /* read x[0], x[1], x[2] samples */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read y[srcBLen - 1] sample */ + c0 = *py--; + /* Read x[3] sample */ + x3 = *(px); + + /* Perform the multiply-accumulate */ + /* acc0 += x[0] * y[srcBLen - 1] */ + acc0 += x0 * c0; + /* acc1 += x[1] * y[srcBLen - 1] */ + acc1 += x1 * c0; + /* acc2 += x[2] * y[srcBLen - 1] */ + acc2 += x2 * c0; + /* acc3 += x[3] * y[srcBLen - 1] */ + acc3 += x3 * c0; + + /* Read y[srcBLen - 2] sample */ + c0 = *py--; + /* Read x[4] sample */ + x0 = *(px + 1U); + + /* Perform the multiply-accumulate */ + /* acc0 += x[1] * y[srcBLen - 2] */ + acc0 += x1 * c0; + /* acc1 += x[2] * y[srcBLen - 2] */ + acc1 += x2 * c0; + /* acc2 += x[3] * y[srcBLen - 2] */ + acc2 += x3 * c0; + /* acc3 += x[4] * y[srcBLen - 2] */ + acc3 += x0 * c0; + + /* Read y[srcBLen - 3] sample */ + c0 = *py--; + /* Read x[5] sample */ + x1 = *(px + 2U); + + /* Perform the multiply-accumulate */ + /* acc0 += x[2] * y[srcBLen - 3] */ + acc0 += x2 * c0; + /* acc1 += x[3] * y[srcBLen - 2] */ + acc1 += x3 * c0; + /* acc2 += x[4] * y[srcBLen - 2] */ + acc2 += x0 * c0; + /* acc3 += x[5] * y[srcBLen - 2] */ + acc3 += x1 * c0; + + /* Read y[srcBLen - 4] sample */ + c0 = *py--; + /* Read x[6] sample */ + x2 = *(px + 3U); + px += 4U; + + /* Perform the multiply-accumulate */ + /* acc0 += x[3] * y[srcBLen - 4] */ + acc0 += x3 * c0; + /* acc1 += x[4] * y[srcBLen - 4] */ + acc1 += x0 * c0; + /* acc2 += x[5] * y[srcBLen - 4] */ + acc2 += x1 * c0; + /* acc3 += x[6] * y[srcBLen - 4] */ + acc3 += x2 * c0; + + } while (--k); + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Read y[srcBLen - 5] sample */ + c0 = *py--; + /* Read x[7] sample */ + x3 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[4] * y[srcBLen - 5] */ + acc0 += x0 * c0; + /* acc1 += x[5] * y[srcBLen - 5] */ + acc1 += x1 * c0; + /* acc2 += x[6] * y[srcBLen - 5] */ + acc2 += x2 * c0; + /* acc3 += x[7] * y[srcBLen - 5] */ + acc3 += x3 * c0; + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = acc0; + *pOut++ = acc1; + *pOut++ = acc2; + *pOut++ = acc3; + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize2 % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py--; + sum += *px++ * *py--; + sum += *px++ * *py--; + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py--; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum; + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py--; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum; + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The blockSize3 variable holds the number of MAC operations performed */ + + /* Working pointer of inputA */ + pSrc1 = pIn1 + (srcALen - (srcBLen - 1U)); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = blockSize3 >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */ + sum += *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */ + sum += *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */ + sum += *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */ + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = blockSize3 % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = blockSize3; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement the loop counter */ + blockSize3--; + } + +#else +/* alternate version for CM0_FAMILY */ + + const float32_t *pIn1 = pSrcA; /* InputA pointer */ + const float32_t *pIn2 = pSrcB; /* InputB pointer */ + float32_t sum; /* Accumulator */ + uint32_t i, j; /* Loop counters */ + + /* Loop to calculate convolution for output length number of times */ + for (i = 0U; i < (srcALen + srcBLen - 1U); i++) + { + /* Initialize sum with zero to carry out MAC operations */ + sum = 0.0f; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ( pIn1[j] * pIn2[i - j]); + } + } + + /* Store the output in the destination buffer */ + pDst[i] = sum; + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of Conv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_opt_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_opt_q15.c new file mode 100644 index 0000000..ed2aea9 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_opt_q15.c @@ -0,0 +1,366 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_fast_opt_q15.c + * Description: Fast Q15 Convolution + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Conv + @{ + */ + +/** + @brief Convolution 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 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 + @return none + + @par Scaling and Overflow Behavior + This fast version uses a 32-bit accumulator with 2.30 format. + The accumulator maintains full precision of the intermediate multiplication results + but provides only a single guard bit. There is no saturation on intermediate additions. + Thus, if the accumulator overflows it wraps around and distorts the result. + The input signals should be scaled down to avoid intermediate overflows. + Scale down the inputs by log2(min(srcALen, srcBLen)) (log2 is read as log to the base 2) times to avoid overflows, + as maximum of min(srcALen, srcBLen) number of additions are carried internally. + The 2.30 accumulator is right shifted by 15 bits and then saturated to 1.15 format to yield the final result. + + @remark + Refer to \ref arm_conv_q15() for a slower implementation of this function which uses 64-bit accumulation to avoid wrap around distortion. + */ + +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) +{ + q31_t acc0; /* Accumulators */ + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + q15_t *pOut = pDst; /* Output pointer */ + q15_t *pScr1 = pScratch1; /* Temporary pointer for scratch1 */ + q15_t *pScr2 = pScratch2; /* Temporary pointer for scratch1 */ + const q15_t *px; /* Intermediate inputA pointer */ + q15_t *py; /* Intermediate inputB pointer */ + uint32_t j, k, blkCnt; /* Loop counter */ + uint32_t tapCnt; /* Loop count */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc1, acc2, acc3; /* Accumulators */ + q31_t x1, x2, x3; /* Temporary variables to hold state and coefficient values */ + q31_t y1, y2; /* State variables */ +#endif + + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* Pointer to take end of scratch2 buffer */ + pScr2 = pScratch2 + srcBLen - 1; + + /* points to smaller length sequence */ + px = pIn2; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + /* Copy smaller length input sequence in reverse order into second scratch buffer */ + while (k > 0U) + { + /* copy second buffer in reversal manner */ + *pScr2-- = *px++; + *pScr2-- = *px++; + *pScr2-- = *px++; + *pScr2-- = *px++; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* copy second buffer in reversal manner for remaining samples */ + *pScr2-- = *px++; + + /* Decrement loop counter */ + k--; + } + + /* Initialze temporary scratch pointer */ + pScr1 = pScratch1; + + /* Assuming scratch1 buffer is aligned by 32-bit */ + /* Fill (srcBLen - 1U) zeros in scratch1 buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update temporary scratch pointer */ + pScr1 += (srcBLen - 1U); + + /* Copy bigger length sequence(srcALen) samples in scratch1 buffer */ + + /* Copy (srcALen) samples in scratch buffer */ + arm_copy_q15(pIn1, pScr1, srcALen); + + /* Update pointers */ + pScr1 += srcALen; + + + /* Fill (srcBLen - 1U) zeros at end of scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update pointer */ + pScr1 += (srcBLen - 1U); + + /* Temporary pointer for scratch2 */ + py = pScratch2; + + + /* Initialization of pIn2 pointer */ + pIn2 = py; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (srcALen + srcBLen - 1U) >> 2; + + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Read two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read next two samples from scratch1 buffer */ + x2 = read_q15x2_ia (&pScr1); + + tapCnt = (srcBLen) >> 2U; + + while (tapCnt > 0U) + { + + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia ((q15_t **) &pIn2); + y2 = read_q15x2_ia ((q15_t **) &pIn2); + + /* multiply and accumlate */ + acc0 = __SMLAD(x1, y1, acc0); + acc2 = __SMLAD(x2, y1, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + /* multiply and accumlate */ + acc1 = __SMLADX(x3, y1, acc1); + + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* multiply and accumlate */ + acc0 = __SMLAD(x2, y2, acc0); + acc2 = __SMLAD(x1, y2, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x1, x2, 0); +#else + x3 = __PKHBT(x2, x1, 0); +#endif + + acc3 = __SMLADX(x3, y1, acc3); + acc1 = __SMLADX(x3, y2, acc1); + + x2 = read_q15x2_ia (&pScr1); + +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + acc3 = __SMLADX(x3, y2, acc3); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Update scratch pointer for remaining samples of smaller length sequence */ + pScr1 -= 4U; + + /* apply same above for remaining samples of smaller length sequence */ + tapCnt = (srcBLen) & 3U; + + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2); + acc1 += (*pScr1++ * *pIn2); + acc2 += (*pScr1++ * *pIn2); + acc3 += (*pScr1++ * *pIn2++); + + pScr1 -= 3U; + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the results in the accumulators in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc0 >> 15), 16), __SSAT((acc1 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc2 >> 15), 16), __SSAT((acc3 >> 15), 16), 16)); +#else + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc1 >> 15), 16), __SSAT((acc0 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc3 >> 15), 16), __SSAT((acc2 >> 15), 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch1 += 4U; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (srcALen + srcBLen - 1U) & 0x3; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (srcALen + srcBLen - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Calculate convolution for remaining samples of Bigger length sequence */ + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + + tapCnt = (srcBLen) >> 1U; + + while (tapCnt > 0U) + { + + /* Read next two samples from scratch1 buffer */ + acc0 += (*pScr1++ * *pIn2++); + acc0 += (*pScr1++ * *pIn2++); + + /* Decrement loop counter */ + tapCnt--; + } + + tapCnt = (srcBLen) & 1U; + + /* apply same above for remaining samples of smaller length sequence */ + while (tapCnt > 0U) + { + + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2++); + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* The result is in 2.30 format. Convert to 1.15 with saturation. + Then store the output in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((acc0 >> 15), 16)); + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch1 += 1U; + } + +} + +/** + @} end of Conv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_q15.c new file mode 100644 index 0000000..3102a05 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_q15.c @@ -0,0 +1,663 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_fast_q15.c + * Description: Fast Q15 Convolution + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Conv + @{ + */ + +/** + @brief Convolution 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 srcALen+srcBLen-1 + @return none + + @par Scaling and Overflow Behavior + This fast version uses a 32-bit accumulator with 2.30 format. + The accumulator maintains full precision of the intermediate multiplication results + but provides only a single guard bit. There is no saturation on intermediate additions. + Thus, if the accumulator overflows it wraps around and distorts the result. + The input signals should be scaled down to avoid intermediate overflows. + Scale down the inputs by log2(min(srcALen, srcBLen)) (log2 is read as log to the base 2) times to avoid overflows, + as maximum of min(srcALen, srcBLen) number of additions are carried internally. + The 2.30 accumulator is right shifted by 15 bits and then saturated to 1.15 format to yield the final result. + + @remark + Refer to \ref arm_conv_q15() for a slower implementation of this function which uses 64-bit accumulation to avoid wrap around distortion. + */ + +void arm_conv_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst) +{ + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + q15_t *pOut = pDst; /* Output pointer */ + q31_t sum, acc0, acc1, acc2, acc3; /* Accumulators */ + const q15_t *px; /* Intermediate inputA pointer */ + const q15_t *py; /* Intermediate inputB pointer */ + const q15_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q31_t x0, x1, x2, x3, c0; /* Temporary variables to hold state and coefficient values */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* For loop unrolling by 4, this stage is divided into two. */ + /* First part of this stage computes the MAC operations less than 4 */ + /* Second part of this stage computes the MAC operations greater than or equal to 4 */ + + /* The first part of the stage starts here */ + while ((count < 4U) && (blockSize1 > 0U)) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Loop over number of MAC operations between + * inputA samples and inputB samples */ + k = count; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = __SMLAD(*px++, *py--, sum); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pIn2 + count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* The second part of the stage starts here */ + /* The internal loop, over count, is unrolled by 4 */ + /* To, read the last two inputB samples using SIMD: + * y[srcBLen] and y[srcBLen-1] coefficients, py is decremented by 1 */ + py = py - 1; + + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulates */ + /* x[0], x[1] are multiplied with y[srcBLen - 1], y[srcBLen - 2] respectively */ + sum = __SMLADX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + /* x[2], x[3] are multiplied with y[srcBLen - 3], y[srcBLen - 4] respectively */ + sum = __SMLADX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* For the next MAC operations, the pointer py is used without SIMD + * So, py is incremented by 1 */ + py = py + 1U; + + /* If the count is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = __SMLAD(*px++, *py--, sum); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pIn2 + (count - 1U); + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is the index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* -------------------- + * Stage2 process + * -------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { + /* Loop unroll over blockSize2, by 4 */ + blkCnt = blockSize2 >> 2U; + + while (blkCnt > 0U) + { + py = py - 1U; + + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* read x[0], x[1] samples */ + x0 = read_q15x2 ((q15_t *) px); + /* read x[1], x[2] samples */ + x1 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read the last two inputB samples using SIMD: + * y[srcBLen - 1] and y[srcBLen - 2] */ + c0 = read_q15x2_da ((q15_t **) &py); + + /* acc0 += x[0] * y[srcBLen - 1] + x[1] * y[srcBLen - 2] */ + acc0 = __SMLADX(x0, c0, acc0); + + /* acc1 += x[1] * y[srcBLen - 1] + x[2] * y[srcBLen - 2] */ + acc1 = __SMLADX(x1, c0, acc1); + + /* Read x[2], x[3] */ + x2 = read_q15x2 ((q15_t *) px); + + /* Read x[3], x[4] */ + x3 = read_q15x2 ((q15_t *) px + 1); + + /* acc2 += x[2] * y[srcBLen - 1] + x[3] * y[srcBLen - 2] */ + acc2 = __SMLADX(x2, c0, acc2); + + /* acc3 += x[3] * y[srcBLen - 1] + x[4] * y[srcBLen - 2] */ + acc3 = __SMLADX(x3, c0, acc3); + + /* Read y[srcBLen - 3] and y[srcBLen - 4] */ + c0 = read_q15x2_da ((q15_t **) &py); + + /* acc0 += x[2] * y[srcBLen - 3] + x[3] * y[srcBLen - 4] */ + acc0 = __SMLADX(x2, c0, acc0); + + /* acc1 += x[3] * y[srcBLen - 3] + x[4] * y[srcBLen - 4] */ + acc1 = __SMLADX(x3, c0, acc1); + + /* Read x[4], x[5] */ + x0 = read_q15x2 ((q15_t *) px + 2); + + /* Read x[5], x[6] */ + x1 = read_q15x2 ((q15_t *) px + 3); + px += 4U; + + /* acc2 += x[4] * y[srcBLen - 3] + x[5] * y[srcBLen - 4] */ + acc2 = __SMLADX(x0, c0, acc2); + + /* acc3 += x[5] * y[srcBLen - 3] + x[6] * y[srcBLen - 4] */ + acc3 = __SMLADX(x1, c0, acc3); + + } while (--k); + + /* For the next MAC operations, SIMD is not used + * So, the 16 bit pointer if inputB, py is updated */ + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + if (k == 1U) + { + /* Read y[srcBLen - 5] */ + c0 = *(py+1); + +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[7] */ + x3 = read_q15x2 ((q15_t *) px); + px++; + + /* Perform the multiply-accumulates */ + acc0 = __SMLAD(x0, c0, acc0); + acc1 = __SMLAD(x1, c0, acc1); + acc2 = __SMLADX(x1, c0, acc2); + acc3 = __SMLADX(x3, c0, acc3); + } + + if (k == 2U) + { + /* Read y[srcBLen - 5], y[srcBLen - 6] */ + c0 = read_q15x2 ((q15_t *) py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + /* Perform the multiply-accumulates */ + acc0 = __SMLADX(x0, c0, acc0); + acc1 = __SMLADX(x1, c0, acc1); + acc2 = __SMLADX(x3, c0, acc2); + acc3 = __SMLADX(x2, c0, acc3); + } + + if (k == 3U) + { + /* Read y[srcBLen - 5], y[srcBLen - 6] */ + c0 = read_q15x2 ((q15_t *) py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + + /* Perform the multiply-accumulates */ + acc0 = __SMLADX(x0, c0, acc0); + acc1 = __SMLADX(x1, c0, acc1); + acc2 = __SMLADX(x3, c0, acc2); + acc3 = __SMLADX(x2, c0, acc3); + + /* Read y[srcBLen - 7] */ + c0 = *(py-1); +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[10] */ + x3 = read_q15x2 ((q15_t *) px + 2); + px += 3U; + + /* Perform the multiply-accumulates */ + acc0 = __SMLADX(x1, c0, acc0); + acc1 = __SMLAD(x2, c0, acc1); + acc2 = __SMLADX(x2, c0, acc2); + acc3 = __SMLADX(x3, c0, acc3); + } + + /* Store the result in the accumulator in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT((acc0 >> 15), (acc1 >> 15), 16)); + write_q15x2_ia (&pOut, __PKHBT((acc2 >> 15), (acc3 >> 15), 16)); +#else + write_q15x2_ia (&pOut, __PKHBT((acc1 >> 15), (acc0 >> 15), 16)); + write_q15x2_ia (&pOut, __PKHBT((acc3 >> 15), (acc2 >> 15), 16)); +#endif /*#ifndef ARM_MATH_BIG_ENDIAN*/ + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize2 % 0x4U; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += ((q31_t) *px++ * *py--); + sum += ((q31_t) *px++ * *py--); + sum += ((q31_t) *px++ * *py--); + sum += ((q31_t) *px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += ((q31_t) *px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Increment the pointer pIn1 index, count by 1 */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q31_t) *px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The blockSize3 variable holds the number of MAC operations performed */ + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + pIn2 = pSrc2 - 1U; + py = pIn2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + /* For loop unrolling by 4, this stage is divided into two. */ + /* First part of this stage computes the MAC operations greater than 4 */ + /* Second part of this stage computes the MAC operations less than or equal to 4 */ + + /* The first part of the stage starts here */ + j = blockSize3 >> 2U; + + while ((j > 0U) && (blockSize3 > 0U)) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = blockSize3 >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* x[srcALen - srcBLen + 1], x[srcALen - srcBLen + 2] are multiplied + * with y[srcBLen - 1], y[srcBLen - 2] respectively */ + sum = __SMLADX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + /* x[srcALen - srcBLen + 3], x[srcALen - srcBLen + 4] are multiplied + * with y[srcBLen - 3], y[srcBLen - 4] respectively */ + sum = __SMLADX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* For the next MAC operations, the pointer py is used without SIMD + * So, py is incremented by 1 */ + py = py + 1U; + + /* If the blockSize3 is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = blockSize3 % 0x4U; + + while (k > 0U) + { + /* sum += x[srcALen - srcBLen + 5] * y[srcBLen - 5] */ + sum = __SMLAD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pIn2; + + /* Decrement loop counter */ + blockSize3--; + + j--; + } + + /* The second part of the stage starts here */ + /* SIMD is not used for the next MAC operations, + * so pointer py is updated to read only one sample at a time */ + py = py + 1U; + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = blockSize3; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum = __SMLAD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement the loop counter */ + blockSize3--; + } + +} + +/** + @} end of Conv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_q31.c new file mode 100644 index 0000000..e87eddc --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_fast_q31.c @@ -0,0 +1,558 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_fast_q31.c + * Description: Fast Q31 Convolution + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Conv + @{ + */ + +/** + @brief Convolution 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 location where the output result is written. Length srcALen+srcBLen-1. + @return none + + @par Scaling and Overflow Behavior + This function is optimized for speed at the expense of fixed-point precision and overflow protection. + The result of each 1.31 x 1.31 multiplication is truncated to 2.30 format. + These intermediate results are accumulated in a 32-bit register in 2.30 format. + Finally, the accumulator is saturated and converted to a 1.31 result. + @par + The fast version has the same overflow behavior as the standard version but provides less precision since it discards the low 32 bits of each multiplication result. + In order to avoid overflows completely the input signals must be scaled down. + Scale down the inputs by log2(min(srcALen, srcBLen)) (log2 is read as log to the base 2) times to avoid overflows, + as maximum of min(srcALen, srcBLen) number of additions are carried internally. + @remark + Refer to \ref arm_conv_q31() for a slower implementation of this function which uses 64-bit accumulation to provide higher precision. + */ + +void arm_conv_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst) +{ + const q31_t *pIn1; /* InputA pointer */ + const q31_t *pIn2; /* InputB pointer */ + q31_t *pOut = pDst; /* Output pointer */ + const q31_t *px; /* Intermediate inputA pointer */ + const q31_t *py; /* Intermediate inputB pointer */ + const q31_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q31_t sum, acc0, acc1, acc2, acc3; /* Accumulators */ + q31_t x0, x1, x2, x3, c0; /* Temporary variables to hold state and coefficient values */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* x[0] * y[srcBLen - 1] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* x[1] * y[srcBLen - 2] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* x[2] * y[srcBLen - 3] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* x[3] * y[srcBLen - 4] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum << 1; + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pIn2 + count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { + /* Loop unroll over blockSize2, by 4 */ + blkCnt = blockSize2 >> 2U; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* read x[0], x[1], x[2] samples */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read y[srcBLen - 1] sample */ + c0 = *py--; + /* Read x[3] sample */ + x3 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[0] * y[srcBLen - 1] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc1 += x[1] * y[srcBLen - 1] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc2 += x[2] * y[srcBLen - 1] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc3 += x[3] * y[srcBLen - 1] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + + /* Read y[srcBLen - 2] sample */ + c0 = *py--; + /* Read x[4] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[1] * y[srcBLen - 2] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc1 += x[2] * y[srcBLen - 2] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc2 += x[3] * y[srcBLen - 2] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x3 * c0)) >> 32); + /* acc3 += x[4] * y[srcBLen - 2] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x0 * c0)) >> 32); + + + /* Read y[srcBLen - 3] sample */ + c0 = *py--; + /* Read x[5] sample */ + x1 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[2] * y[srcBLen - 3] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc1 += x[3] * y[srcBLen - 3] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x3 * c0)) >> 32); + /* acc2 += x[4] * y[srcBLen - 3] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc3 += x[5] * y[srcBLen - 3] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x1 * c0)) >> 32); + + + /* Read y[srcBLen - 4] sample */ + c0 = *py--; + /* Read x[6] sample */ + x2 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[3] * y[srcBLen - 4] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x3 * c0)) >> 32); + /* acc1 += x[4] * y[srcBLen - 4] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc2 += x[5] * y[srcBLen - 4] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc3 += x[6] * y[srcBLen - 4] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x2 * c0)) >> 32); + + + } while (--k); + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Read y[srcBLen - 5] sample */ + c0 = *py--; + /* Read x[7] sample */ + x3 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[4] * y[srcBLen - 5] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc1 += x[5] * y[srcBLen - 5] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc2 += x[6] * y[srcBLen - 5] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc3 += x[7] * y[srcBLen - 5] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (acc0 << 1); + *pOut++ = (q31_t) (acc1 << 1); + *pOut++ = (q31_t) (acc2 << 1); + *pOut++ = (q31_t) (acc3 << 1); + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize2 % 0x4U; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum << 1; + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum << 1; + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The blockSize3 variable holds the number of MAC operations performed */ + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = blockSize3 >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* If the blockSize3 is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = blockSize3 % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum << 1; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement loop counter */ + blockSize3--; + } + +} + +/** + @} end of Conv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_opt_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_opt_q15.c new file mode 100644 index 0000000..6ad34cd --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_opt_q15.c @@ -0,0 +1,362 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_opt_q15.c + * Description: Convolution of Q15 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Conv + @{ + */ + +/** + @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. + @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 none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both inputs are 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. + This approach provides 33 guard bits and there is no risk of overflow. + The 34.30 result is then truncated to 34.15 format by discarding the low 15 bits and then saturated to 1.15 format. + @remark + Refer to \ref arm_conv_fast_q15() for a faster but less precise version of this function. + */ + +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) +{ + q63_t acc0; /* Accumulators */ + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + q15_t *pOut = pDst; /* Output pointer */ + q15_t *pScr1 = pScratch1; /* Temporary pointer for scratch1 */ + q15_t *pScr2 = pScratch2; /* Temporary pointer for scratch1 */ + const q15_t *px; /* Intermediate inputA pointer */ + q15_t *py; /* Intermediate inputB pointer */ + uint32_t j, k, blkCnt; /* Loop counter */ + uint32_t tapCnt; /* Loop count */ + +#if defined (ARM_MATH_LOOPUNROLL) + q63_t acc1, acc2, acc3; /* Accumulators */ + q31_t x1, x2, x3; /* Temporary variables to hold state and coefficient values */ + q31_t y1, y2; /* State variables */ +#endif + + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* Pointer to take end of scratch2 buffer */ + pScr2 = pScratch2 + srcBLen - 1; + + /* points to smaller length sequence */ + px = pIn2; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + /* Copy smaller length input sequence in reverse order into second scratch buffer */ + while (k > 0U) + { + /* copy second buffer in reversal manner */ + *pScr2-- = *px++; + *pScr2-- = *px++; + *pScr2-- = *px++; + *pScr2-- = *px++; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* copy second buffer in reversal manner for remaining samples */ + *pScr2-- = *px++; + + /* Decrement loop counter */ + k--; + } + + /* Initialze temporary scratch pointer */ + pScr1 = pScratch1; + + /* Assuming scratch1 buffer is aligned by 32-bit */ + /* Fill (srcBLen - 1U) zeros in scratch1 buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update temporary scratch pointer */ + pScr1 += (srcBLen - 1U); + + /* Copy bigger length sequence(srcALen) samples in scratch1 buffer */ + + /* Copy (srcALen) samples in scratch buffer */ + arm_copy_q15(pIn1, pScr1, srcALen); + + /* Update pointers */ + pScr1 += srcALen; + + + /* Fill (srcBLen - 1U) zeros at end of scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update pointer */ + pScr1 += (srcBLen - 1U); + + /* Temporary pointer for scratch2 */ + py = pScratch2; + + + /* Initialization of pIn2 pointer */ + pIn2 = py; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (srcALen + srcBLen - 1U) >> 2; + + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Read two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read next two samples from scratch1 buffer */ + x2 = read_q15x2_ia (&pScr1); + + tapCnt = (srcBLen) >> 2U; + + while (tapCnt > 0U) + { + + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia ((q15_t **) &pIn2); + y2 = read_q15x2_ia ((q15_t **) &pIn2); + + /* multiply and accumlate */ + acc0 = __SMLALD(x1, y1, acc0); + acc2 = __SMLALD(x2, y1, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + /* multiply and accumlate */ + acc1 = __SMLALDX(x3, y1, acc1); + + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* multiply and accumlate */ + acc0 = __SMLALD(x2, y2, acc0); + acc2 = __SMLALD(x1, y2, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x1, x2, 0); +#else + x3 = __PKHBT(x2, x1, 0); +#endif + + acc3 = __SMLALDX(x3, y1, acc3); + acc1 = __SMLALDX(x3, y2, acc1); + + x2 = read_q15x2_ia (&pScr1); + +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + acc3 = __SMLALDX(x3, y2, acc3); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Update scratch pointer for remaining samples of smaller length sequence */ + pScr1 -= 4U; + + /* apply same above for remaining samples of smaller length sequence */ + tapCnt = (srcBLen) & 3U; + + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2); + acc1 += (*pScr1++ * *pIn2); + acc2 += (*pScr1++ * *pIn2); + acc3 += (*pScr1++ * *pIn2++); + + pScr1 -= 3U; + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the results in the accumulators in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc0 >> 15), 16), __SSAT((acc1 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc2 >> 15), 16), __SSAT((acc3 >> 15), 16), 16)); +#else + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc1 >> 15), 16), __SSAT((acc0 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc3 >> 15), 16), __SSAT((acc2 >> 15), 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch1 += 4U; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (srcALen + srcBLen - 1U) & 0x3; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (srcALen + srcBLen - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Calculate convolution for remaining samples of Bigger length sequence */ + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + + tapCnt = (srcBLen) >> 1U; + + while (tapCnt > 0U) + { + + /* Read next two samples from scratch1 buffer */ + acc0 += (*pScr1++ * *pIn2++); + acc0 += (*pScr1++ * *pIn2++); + + /* Decrement loop counter */ + tapCnt--; + } + + tapCnt = (srcBLen) & 1U; + + /* apply same above for remaining samples of smaller length sequence */ + while (tapCnt > 0U) + { + + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2++); + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* The result is in 2.30 format. Convert to 1.15 with saturation. + Then store the output in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((acc0 >> 15), 16)); + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch1 += 1U; + } + +} + +/** + @} end of Conv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_opt_q7.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_opt_q7.c new file mode 100644 index 0000000..fb9e2ec --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_opt_q7.c @@ -0,0 +1,360 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_opt_q7.c + * Description: Convolution of Q7 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Conv + @{ + */ + +/** + @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 location where the output result is written. 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). + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 32-bit internal accumulator. + Both the inputs are represented in 1.7 format and multiplications yield a 2.14 result. + The 2.14 intermediate results are accumulated in a 32-bit accumulator in 18.14 format. + This approach provides 17 guard bits and there is no risk of overflow as long as max(srcALen, srcBLen)<131072. + The 18.14 result is then truncated to 18.7 format by discarding the low 7 bits and then saturated to 1.7 format. + */ + +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) +{ + q15_t *pScr1 = pScratch1; /* Temporary pointer for scratch */ + q15_t *pScr2 = pScratch2; /* Temporary pointer for scratch */ + q15_t x4; /* Temporary input variable */ + q15_t *py; /* Temporary input2 pointer */ + q31_t acc0, acc1, acc2, acc3; /* Accumulators */ + const q7_t *pIn1, *pIn2; /* InputA and inputB pointer */ + uint32_t j, k, blkCnt, tapCnt; /* Loop counter */ + q31_t x1, x2, x3, y1; /* Temporary input variables */ + const q7_t *px; /* Temporary input1 pointer */ + q7_t *pOut = pDst; /* Output pointer */ + q7_t out0, out1, out2, out3; /* Temporary variables */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* points to smaller length sequence */ + px = pIn2 + srcBLen - 1; + + /* Apply loop unrolling and do 4 Copies simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling copies 4 data points at a time. + ** a second loop below copies for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* copy second buffer in reversal manner */ + x4 = (q15_t) *px--; + *pScr2++ = x4; + x4 = (q15_t) *px--; + *pScr2++ = x4; + x4 = (q15_t) *px--; + *pScr2++ = x4; + x4 = (q15_t) *px--; + *pScr2++ = x4; + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, copy remaining samples here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* copy second buffer in reversal manner for remaining samples */ + x4 = (q15_t) *px--; + *pScr2++ = x4; + + /* Decrement loop counter */ + k--; + } + + /* Fill (srcBLen - 1U) zeros in scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update temporary scratch pointer */ + pScr1 += (srcBLen - 1U); + + /* Copy (srcALen) samples in scratch buffer */ + /* Apply loop unrolling and do 4 Copies simultaneously. */ + k = srcALen >> 2U; + + /* First part of the processing with loop unrolling copies 4 data points at a time. + ** a second loop below copies for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* copy second buffer in reversal manner */ + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, copy remaining samples here. + ** No loop unrolling is used. */ + k = srcALen % 0x4U; + + while (k > 0U) + { + /* copy second buffer in reversal manner for remaining samples */ + x4 = (q15_t) * pIn1++; + *pScr1++ = x4; + + /* Decrement the loop counter */ + k--; + } + + /* Fill (srcBLen - 1U) zeros at end of scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update pointer */ + pScr1 += (srcBLen - 1U); + + /* Temporary pointer for scratch2 */ + py = pScratch2; + + /* Initialization of pIn2 pointer */ + pIn2 = (q7_t *) py; + + pScr2 = py; + + /* Actual convolution process starts here */ + blkCnt = (srcALen + srcBLen - 1U) >> 2U; + + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Read two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read next two samples from scratch1 buffer */ + x2 = read_q15x2_ia (&pScr1); + + tapCnt = (srcBLen) >> 2U; + + while (tapCnt > 0U) + { + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia (&pScr2); + + /* multiply and accumlate */ + acc0 = __SMLAD(x1, y1, acc0); + acc2 = __SMLAD(x2, y1, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + /* multiply and accumlate */ + acc1 = __SMLADX(x3, y1, acc1); + + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x1, x2, 0); +#else + x3 = __PKHBT(x2, x1, 0); +#endif + + acc3 = __SMLADX(x3, y1, acc3); + + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia (&pScr2); + + acc0 = __SMLAD(x2, y1, acc0); + + acc2 = __SMLAD(x1, y1, acc2); + + acc1 = __SMLADX(x3, y1, acc1); + + x2 = read_q15x2_ia (&pScr1); + +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + acc3 = __SMLADX(x3, y1, acc3); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Update scratch pointer for remaining samples of smaller length sequence */ + pScr1 -= 4U; + + /* apply same above for remaining samples of smaller length sequence */ + tapCnt = (srcBLen) & 3U; + + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pScr2); + acc1 += (*pScr1++ * *pScr2); + acc2 += (*pScr1++ * *pScr2); + acc3 += (*pScr1++ * *pScr2++); + + pScr1 -= 3U; + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the result in the accumulator in the destination buffer. */ + out0 = (q7_t) (__SSAT(acc0 >> 7U, 8)); + out1 = (q7_t) (__SSAT(acc1 >> 7U, 8)); + out2 = (q7_t) (__SSAT(acc2 >> 7U, 8)); + out3 = (q7_t) (__SSAT(acc3 >> 7U, 8)); + + write_q7x4_ia (&pOut, __PACKq7(out0, out1, out2, out3)); + + /* Initialization of inputB pointer */ + pScr2 = py; + + pScratch1 += 4U; + } + + blkCnt = (srcALen + srcBLen - 1U) & 0x3; + + /* Calculate convolution for remaining samples of Bigger length sequence */ + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + + tapCnt = (srcBLen) >> 1U; + + while (tapCnt > 0U) + { + acc0 += (*pScr1++ * *pScr2++); + acc0 += (*pScr1++ * *pScr2++); + + /* Decrement loop counter */ + tapCnt--; + } + + tapCnt = (srcBLen) & 1U; + + /* apply same above for remaining samples of smaller length sequence */ + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pScr2++); + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(acc0 >> 7U, 8)); + + /* Initialization of inputB pointer */ + pScr2 = py; + + pScratch1 += 1U; + } + +} + +/** + @} end of Conv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_f32.c new file mode 100644 index 0000000..e25f9ab --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_f32.c @@ -0,0 +1,676 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_partial_f32.c + * Description: Partial convolution of floating-point sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup PartialConv Partial Convolution + + Partial Convolution is equivalent to Convolution except that a subset of the output samples is generated. + Each function has two additional arguments. + firstIndex specifies the starting index of the subset of output samples. + numPoints is the number of output samples to compute. + The function computes the output in the range + [firstIndex, ..., firstIndex+numPoints-1]. + The output array pDst contains numPoints values. + + The allowable range of output indices is [0 srcALen+srcBLen-2]. + If the requested subset does not fall in this range then the functions return ARM_MATH_ARGUMENT_ERROR. + Otherwise the functions return ARM_MATH_SUCCESS. + \note Refer to \ref arm_conv_f32() for details on fixed point behavior. + + @par Fast Versions + Fast versions are supported for Q31 and Q15 of partial convolution. + Cycles for Fast versions are less compared to Q31 and Q15 of partial conv and the design requires + the input signals should be scaled down to avoid intermediate overflows. + + @par Opt Versions + Opt versions are supported for Q15 and Q7. Design uses internal scratch buffer for getting good optimisation. + These versions are optimised in cycles and consumes more memory (Scratch memory) compared to Q15 and Q7 versions of partial convolution + */ + +/** + @addtogroup PartialConv + @{ + */ + +/** + @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 location where the output result is written + @param[in] firstIndex is the first output sample to start with + @param[in] numPoints is the number of output points to be computed + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : 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) +{ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + const float32_t *pIn1 = pSrcA; /* InputA pointer */ + const float32_t *pIn2 = pSrcB; /* InputB pointer */ + float32_t *pOut = pDst; /* Output pointer */ + const float32_t *px; /* Intermediate inputA pointer */ + const float32_t *py; /* Intermediate inputB pointer */ + const float32_t *pSrc1, *pSrc2; /* Intermediate pointers */ + float32_t sum; /* Accumulator */ + uint32_t j, k, count, blkCnt, check; + int32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + arm_status status; /* Status of Partial convolution */ + +#if defined (ARM_MATH_LOOPUNROLL) + float32_t acc0, acc1, acc2, acc3; /* Accumulator */ + float32_t x0, x1, x2, x3, c0; /* Temporary variables */ +#endif + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* Conditions to check which loopCounter holds + * the first and last indices of the output samples to be calculated. */ + check = firstIndex + numPoints; + blockSize3 = ((int32_t)check > (int32_t)srcALen) ? (int32_t)check - (int32_t)srcALen : 0; + blockSize3 = ((int32_t)firstIndex > (int32_t)srcALen - 1) ? blockSize3 - (int32_t)firstIndex + (int32_t)srcALen : blockSize3; + blockSize1 = ((int32_t) srcBLen - 1) - (int32_t) firstIndex; + blockSize1 = (blockSize1 > 0) ? ((check > (srcBLen - 1U)) ? blockSize1 : (int32_t) numPoints) : 0; + blockSize2 = ((int32_t) check - blockSize3) - (blockSize1 + (int32_t) firstIndex); + blockSize2 = (blockSize2 > 0) ? blockSize2 : 0; + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* Set the output pointer to point to the firstIndex + * of the output sample to be calculated. */ + pOut = pDst + firstIndex; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed. + Since the partial convolution starts from firstIndex + Number of Macs to be performed is firstIndex + 1 */ + count = 1U + firstIndex; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc1 = pIn2 + firstIndex; + py = pSrc1; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[0] * y[srcBLen - 1] */ + sum += *px++ * *py--; + + /* x[1] * y[srcBLen - 2] */ + sum += *px++ * *py--; + + /* x[2] * y[srcBLen - 3] */ + sum += *px++ * *py--; + + /* x[3] * y[srcBLen - 4] */ + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum; + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = ++pSrc1; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0) + { + pSrc1 = pIn1 + firstIndex - srcBLen + 1; + } + else + { + pSrc1 = pIn1; + } + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = ((uint32_t) blockSize2 >> 2U); + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0.0f; + acc1 = 0.0f; + acc2 = 0.0f; + acc3 = 0.0f; + + /* read x[0], x[1], x[2] samples */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read y[srcBLen - 1] sample */ + c0 = *py--; + /* Read x[3] sample */ + x3 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[0] * y[srcBLen - 1] */ + acc0 += x0 * c0; + /* acc1 += x[1] * y[srcBLen - 1] */ + acc1 += x1 * c0; + /* acc2 += x[2] * y[srcBLen - 1] */ + acc2 += x2 * c0; + /* acc3 += x[3] * y[srcBLen - 1] */ + acc3 += x3 * c0; + + /* Read y[srcBLen - 2] sample */ + c0 = *py--; + /* Read x[4] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[1] * y[srcBLen - 2] */ + acc0 += x1 * c0; + /* acc1 += x[2] * y[srcBLen - 2] */ + acc1 += x2 * c0; + /* acc2 += x[3] * y[srcBLen - 2] */ + acc2 += x3 * c0; + /* acc3 += x[4] * y[srcBLen - 2] */ + acc3 += x0 * c0; + + /* Read y[srcBLen - 3] sample */ + c0 = *py--; + /* Read x[5] sample */ + x1 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[2] * y[srcBLen - 3] */ + acc0 += x2 * c0; + /* acc1 += x[3] * y[srcBLen - 2] */ + acc1 += x3 * c0; + /* acc2 += x[4] * y[srcBLen - 2] */ + acc2 += x0 * c0; + /* acc3 += x[5] * y[srcBLen - 2] */ + acc3 += x1 * c0; + + /* Read y[srcBLen - 4] sample */ + c0 = *py--; + /* Read x[6] sample */ + x2 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[3] * y[srcBLen - 4] */ + acc0 += x3 * c0; + /* acc1 += x[4] * y[srcBLen - 4] */ + acc1 += x0 * c0; + /* acc2 += x[5] * y[srcBLen - 4] */ + acc2 += x1 * c0; + /* acc3 += x[6] * y[srcBLen - 4] */ + acc3 += x2 * c0; + + } while (--k); + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Read y[srcBLen - 5] sample */ + c0 = *py--; + /* Read x[7] sample */ + x3 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[4] * y[srcBLen - 5] */ + acc0 += x0 * c0; + /* acc1 += x[5] * y[srcBLen - 5] */ + acc1 += x1 * c0; + /* acc2 += x[6] * y[srcBLen - 5] */ + acc2 += x2 * c0; + /* acc3 += x[7] * y[srcBLen - 5] */ + acc3 += x3 * c0; + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = acc0; + *pOut++ = acc1; + *pOut++ = acc2; + *pOut++ = acc3; + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (uint32_t) blockSize2 % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += *px++ * *py--; + sum += *px++ * *py--; + sum += *px++ * *py--; + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum; + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = (uint32_t) blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum; + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The blockSize3 variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */ + sum += *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */ + sum += *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */ + sum += *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */ + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum += *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement MAC count */ + count--; + + /* Decrement the loop counter */ + blockSize3--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); + +#else +/* alternate version for CM0_FAMILY */ + + const float32_t *pIn1 = pSrcA; /* InputA pointer */ + const float32_t *pIn2 = pSrcB; /* InputB pointer */ + float32_t sum; /* Accumulator */ + uint32_t i, j; /* Loop counters */ + arm_status status; /* Status of Partial convolution */ + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* Loop to calculate convolution for output length number of values */ + for (i = firstIndex; i <= (firstIndex + numPoints - 1); i++) + { + /* Initialize sum with zero to carry on MAC operations */ + sum = 0.0f; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ( pIn1[j] * pIn2[i - j]); + } + } + + /* Store the output in the destination buffer */ + pDst[i] = sum; + } + + /* Set status as ARM_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of PartialConv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_opt_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_opt_q15.c new file mode 100644 index 0000000..7166b57 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_opt_q15.c @@ -0,0 +1,387 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_partial_fast_opt_q15.c + * Description: Fast Q15 Partial convolution + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup PartialConv + @{ + */ + +/** + @brief Partial convolution 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 + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : requested subset is not in the range [0 srcALen+srcBLen-2] + + @remark + Refer to \ref arm_conv_partial_q15() for a slower implementation of this function which uses a 64-bit accumulator to avoid wrap around distortion. + */ + +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) +{ + q15_t *pOut = pDst; /* Output pointer */ + q15_t *pScr1 = pScratch1; /* Temporary pointer for scratch1 */ + q15_t *pScr2 = pScratch2; /* Temporary pointer for scratch1 */ + q31_t acc0; /* Accumulator */ + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + const q15_t *px; /* Intermediate inputA pointer */ + q15_t *py; /* Intermediate inputB pointer */ + uint32_t j, k, blkCnt; /* Loop counter */ + uint32_t tapCnt; /* Loop count */ + arm_status status; /* Status variable */ + q31_t x1; /* Temporary variables to hold state and coefficient values */ + q31_t y1; /* State variables */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc1, acc2, acc3; /* Accumulator */ + q31_t x2, x3; /* Temporary variables to hold state and coefficient values */ + q31_t y2; /* State variables */ +#endif + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* Temporary pointer for scratch2 */ + py = pScratch2; + + /* pointer to take end of scratch2 buffer */ + pScr2 = pScratch2 + srcBLen - 1; + + /* points to smaller length sequence */ + px = pIn2; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + /* Copy smaller length input sequence in reverse order into second scratch buffer */ + while (k > 0U) + { + /* copy second buffer in reversal manner */ + *pScr2-- = *px++; + *pScr2-- = *px++; + *pScr2-- = *px++; + *pScr2-- = *px++; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* copy second buffer in reversal manner for remaining samples */ + *pScr2-- = *px++; + + /* Decrement loop counter */ + k--; + } + + /* Initialze temporary scratch pointer */ + pScr1 = pScratch1; + + /* Assuming scratch1 buffer is aligned by 32-bit */ + /* Fill (srcBLen - 1U) zeros in scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update temporary scratch pointer */ + pScr1 += (srcBLen - 1U); + + /* Copy bigger length sequence(srcALen) samples in scratch1 buffer */ + + /* Copy (srcALen) samples in scratch buffer */ + arm_copy_q15(pIn1, pScr1, srcALen); + + /* Update pointers */ + pScr1 += srcALen; + + /* Fill (srcBLen - 1U) zeros at end of scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update pointer */ + pScr1 += (srcBLen - 1U); + + /* Initialization of pIn2 pointer */ + pIn2 = py; + + pScratch1 += firstIndex; + + pOut = pDst + firstIndex; + + /* Actual convolution process starts here */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (numPoints) >> 2; + + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Read two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read next two samples from scratch1 buffer */ + x2 = read_q15x2_ia (&pScr1); + + tapCnt = (srcBLen) >> 2U; + + while (tapCnt > 0U) + { + + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia ((q15_t **) &pIn2); + y2 = read_q15x2_ia ((q15_t **) &pIn2); + + /* multiply and accumlate */ + acc0 = __SMLAD(x1, y1, acc0); + acc2 = __SMLAD(x2, y1, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + /* multiply and accumlate */ + acc1 = __SMLADX(x3, y1, acc1); + + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* multiply and accumlate */ + acc0 = __SMLAD(x2, y2, acc0); + acc2 = __SMLAD(x1, y2, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x1, x2, 0); +#else + x3 = __PKHBT(x2, x1, 0); +#endif + + acc3 = __SMLADX(x3, y1, acc3); + acc1 = __SMLADX(x3, y2, acc1); + + x2 = read_q15x2_ia (&pScr1); + +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + /* multiply and accumlate */ + acc3 = __SMLADX(x3, y2, acc3); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Update scratch pointer for remaining samples of smaller length sequence */ + pScr1 -= 4U; + + /* apply same above for remaining samples of smaller length sequence */ + tapCnt = (srcBLen) & 3U; + + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2); + acc1 += (*pScr1++ * *pIn2); + acc2 += (*pScr1++ * *pIn2); + acc3 += (*pScr1++ * *pIn2++); + + pScr1 -= 3U; + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the results in the accumulators in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc0 >> 15), 16), __SSAT((acc1 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc2 >> 15), 16), __SSAT((acc3 >> 15), 16), 16)); +#else + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc1 >> 15), 16), __SSAT((acc0 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc3 >> 15), 16), __SSAT((acc2 >> 15), 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch1 += 4U; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numPoints & 0x3; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numPoints; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Calculate convolution for remaining samples of Bigger length sequence */ + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + + tapCnt = (srcBLen) >> 1U; + + while (tapCnt > 0U) + { + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read two samples from smaller buffer */ + y1 = read_q15x2_ia ((q15_t **) &pIn2); + + /* multiply and accumlate */ + acc0 = __SMLAD(x1, y1, acc0); + + /* Decrement loop counter */ + tapCnt--; + } + + tapCnt = (srcBLen) & 1U; + + /* apply same above for remaining samples of smaller length sequence */ + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2++); + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* The result is in 2.30 format. Convert to 1.15 with saturation. + ** Then store the output in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((acc0 >> 15), 16)); + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch1 += 1U; + + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of PartialConv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_q15.c new file mode 100644 index 0000000..535fbc7 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_q15.c @@ -0,0 +1,700 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_partial_fast_q15.c + * Description: Fast Q15 Partial convolution + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup PartialConv + @{ + */ + +/** + @brief Partial convolution 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 + @param[in] firstIndex is the first output sample to start with + @param[in] numPoints is the number of output points to be computed + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : requested subset is not in the range [0 srcALen+srcBLen-2] + @remark + Refer to \ref arm_conv_partial_q15() for a slower implementation of this function which uses a 64-bit accumulator to avoid wrap around distortion. + */ + +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) +{ + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + q15_t *pOut = pDst; /* Output pointer */ + q31_t sum, acc0, acc1, acc2, acc3; /* Accumulator */ + const q15_t *px; /* Intermediate inputA pointer */ + const q15_t *py; /* Intermediate inputB pointer */ + const q15_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q31_t x0, x1, x2, x3, c0; /* Temporary input variables */ + uint32_t j, k, count, blkCnt, check; + int32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + arm_status status; /* Status of Partial convolution */ + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* Conditions to check which loopCounter holds + * the first and last indices of the output samples to be calculated. */ + check = firstIndex + numPoints; + blockSize3 = ((int32_t)check > (int32_t)srcALen) ? (int32_t)check - (int32_t)srcALen : 0; + blockSize3 = ((int32_t)firstIndex > (int32_t)srcALen - 1) ? blockSize3 - (int32_t)firstIndex + (int32_t)srcALen : blockSize3; + blockSize1 = ((int32_t) srcBLen - 1) - (int32_t) firstIndex; + blockSize1 = (blockSize1 > 0) ? ((check > (srcBLen - 1U)) ? blockSize1 : (int32_t) numPoints) : 0; + blockSize2 = (int32_t) check - ((blockSize3 + blockSize1) + (int32_t) firstIndex); + blockSize2 = (blockSize2 > 0) ? blockSize2 : 0; + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* Set the output pointer to point to the firstIndex + * of the output sample to be calculated. */ + pOut = pDst + firstIndex; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed. + Since the partial convolution starts from firstIndex + Number of Macs to be performed is firstIndex + 1 */ + count = 1U + firstIndex; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + firstIndex; + py = pSrc2; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* For loop unrolling by 4, this stage is divided into two. */ + /* First part of this stage computes the MAC operations less than 4 */ + /* Second part of this stage computes the MAC operations greater than or equal to 4 */ + + /* The first part of the stage starts here */ + while ((count < 4U) && (blockSize1 > 0)) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Loop over number of MAC operations between + * inputA samples and inputB samples */ + k = count; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = __SMLAD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = ++pSrc2; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* The second part of the stage starts here */ + /* The internal loop, over count, is unrolled by 4 */ + /* To, read the last two inputB samples using SIMD: + * y[srcBLen] and y[srcBLen-1] coefficients, py is decremented by 1 */ + py = py - 1; + + while (blockSize1 > 0) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* x[0], x[1] are multiplied with y[srcBLen - 1], y[srcBLen - 2] respectively */ + sum = __SMLADX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + /* x[2], x[3] are multiplied with y[srcBLen - 3], y[srcBLen - 4] respectively */ + sum = __SMLADX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* For the next MAC operations, the pointer py is used without SIMD + So, py is incremented by 1 */ + py = py + 1U; + + /* If the count is not a multiple of 4, compute any remaining MACs here. + No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = __SMLAD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = ++pSrc2 - 1U; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0) + { + pSrc1 = pIn1 + firstIndex - srcBLen + 1; + } + else + { + pSrc1 = pIn1; + } + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is the index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = ((uint32_t) blockSize2 >> 2U); + + while (blkCnt > 0U) + { + py = py - 1U; + + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + + /* read x[0], x[1] samples */ + x0 = read_q15x2 ((q15_t *) px); + /* read x[1], x[2] samples */ + x1 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read the last two inputB samples using SIMD: + * y[srcBLen - 1] and y[srcBLen - 2] */ + c0 = read_q15x2_da ((q15_t **) &py); + + /* acc0 += x[0] * y[srcBLen - 1] + x[1] * y[srcBLen - 2] */ + acc0 = __SMLADX(x0, c0, acc0); + + /* acc1 += x[1] * y[srcBLen - 1] + x[2] * y[srcBLen - 2] */ + acc1 = __SMLADX(x1, c0, acc1); + + /* Read x[2], x[3] */ + x2 = read_q15x2 ((q15_t *) px); + + /* Read x[3], x[4] */ + x3 = read_q15x2 ((q15_t *) px + 1); + + /* acc2 += x[2] * y[srcBLen - 1] + x[3] * y[srcBLen - 2] */ + acc2 = __SMLADX(x2, c0, acc2); + + /* acc3 += x[3] * y[srcBLen - 1] + x[4] * y[srcBLen - 2] */ + acc3 = __SMLADX(x3, c0, acc3); + + /* Read y[srcBLen - 3] and y[srcBLen - 4] */ + c0 = read_q15x2_da ((q15_t **) &py); + + /* acc0 += x[2] * y[srcBLen - 3] + x[3] * y[srcBLen - 4] */ + acc0 = __SMLADX(x2, c0, acc0); + + /* acc1 += x[3] * y[srcBLen - 3] + x[4] * y[srcBLen - 4] */ + acc1 = __SMLADX(x3, c0, acc1); + + /* Read x[4], x[5] */ + x0 = read_q15x2 ((q15_t *) px + 2); + + /* Read x[5], x[6] */ + x1 = read_q15x2 ((q15_t *) px + 3); + px += 4U; + + /* acc2 += x[4] * y[srcBLen - 3] + x[5] * y[srcBLen - 4] */ + acc2 = __SMLADX(x0, c0, acc2); + + /* acc3 += x[5] * y[srcBLen - 3] + x[6] * y[srcBLen - 4] */ + acc3 = __SMLADX(x1, c0, acc3); + + } while (--k); + + /* For the next MAC operations, SIMD is not used + So, the 16 bit pointer if inputB, py is updated */ + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + No loop unrolling is used. */ + k = srcBLen % 0x4U; + + if (k == 1U) + { + /* Read y[srcBLen - 5] */ + c0 = *(py + 1); +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[7] */ + x3 = read_q15x2 ((q15_t *) px); + px++; + + /* Perform the multiply-accumulate */ + acc0 = __SMLAD (x0, c0, acc0); + acc1 = __SMLAD (x1, c0, acc1); + acc2 = __SMLADX(x1, c0, acc2); + acc3 = __SMLADX(x3, c0, acc3); + } + + if (k == 2U) + { + /* Read y[srcBLen - 5], y[srcBLen - 6] */ + c0 = read_q15x2 ((q15_t *) py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + /* Perform the multiply-accumulate */ + acc0 = __SMLADX(x0, c0, acc0); + acc1 = __SMLADX(x1, c0, acc1); + acc2 = __SMLADX(x3, c0, acc2); + acc3 = __SMLADX(x2, c0, acc3); + } + + if (k == 3U) + { + /* Read y[srcBLen - 5], y[srcBLen - 6] */ + c0 = read_q15x2 ((q15_t *) py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + + /* Perform the multiply-accumulate */ + acc0 = __SMLADX(x0, c0, acc0); + acc1 = __SMLADX(x1, c0, acc1); + acc2 = __SMLADX(x3, c0, acc2); + acc3 = __SMLADX(x2, c0, acc3); + + c0 = *(py-1); +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[10] */ + x3 = read_q15x2 ((q15_t *) px + 2); + px += 3U; + + /* Perform the multiply-accumulates */ + acc0 = __SMLADX(x1, c0, acc0); + acc1 = __SMLAD (x2, c0, acc1); + acc2 = __SMLADX(x2, c0, acc2); + acc3 = __SMLADX(x3, c0, acc3); + } + + /* Store the results in the accumulators in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT(acc0 >> 15, acc1 >> 15, 16)); + write_q15x2_ia (&pOut, __PKHBT(acc2 >> 15, acc3 >> 15, 16)); +#else + write_q15x2_ia (&pOut, __PKHBT(acc1 >> 15, acc0 >> 15, 16)); + write_q15x2_ia (&pOut, __PKHBT(acc3 >> 15, acc2 >> 15, 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + + /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here. + No loop unrolling is used. */ + blkCnt = (uint32_t) blockSize2 % 0x4U; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += ((q31_t) *px++ * *py--); + sum += ((q31_t) *px++ * *py--); + sum += ((q31_t) *px++ * *py--); + sum += ((q31_t) *px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += ((q31_t) *px++ * *py--); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Increment the pointer pIn1 index, count by 1 */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = (uint32_t) blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q31_t) *px++ * *py--); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + pIn2 = pSrc2 - 1U; + py = pIn2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + /* For loop unrolling by 4, this stage is divided into two. */ + /* First part of this stage computes the MAC operations greater than 4 */ + /* Second part of this stage computes the MAC operations less than or equal to 4 */ + + /* The first part of the stage starts here */ + j = count >> 2U; + + while ((j > 0U) && (blockSize3 > 0)) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* x[srcALen - srcBLen + 1], x[srcALen - srcBLen + 2] are multiplied + * with y[srcBLen - 1], y[srcBLen - 2] respectively */ + sum = __SMLADX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + /* x[srcALen - srcBLen + 3], x[srcALen - srcBLen + 4] are multiplied + * with y[srcBLen - 3], y[srcBLen - 4] respectively */ + sum = __SMLADX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* For the next MAC operations, the pointer py is used without SIMD + So, py is incremented by 1 */ + py = py + 1U; + + /* If the count is not a multiple of 4, compute any remaining MACs here. + No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* sum += x[srcALen - srcBLen + 5] * y[srcBLen - 5] */ + sum = __SMLAD(*px++, *py--, sum); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pIn2; + + /* Decrement the MAC count */ + count--; + + /* Decrement the loop counter */ + blockSize3--; + + j--; + } + + /* The second part of the stage starts here */ + /* SIMD is not used for the next MAC operations, + * so pointer py is updated to read only one sample at a time */ + py = py + 1U; + + while (blockSize3 > 0) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum = __SMLAD(*px++, *py--, sum); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (sum >> 15); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement the MAC count */ + count--; + + /* Decrement the loop counter */ + blockSize3--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); + +} + +/** + @} end of PartialConv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_q31.c new file mode 100644 index 0000000..f232d51 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_fast_q31.c @@ -0,0 +1,618 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_partial_fast_q31.c + * Description: Fast Q31 Partial convolution + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup PartialConv + @{ + */ + +/** + @brief Partial convolution 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 location where the output result is written + @param[in] firstIndex is the first output sample to start with + @param[in] numPoints is the number of output points to be computed + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : requested subset is not in the range [0 srcALen+srcBLen-2] + + @remark + Refer to \ref arm_conv_partial_q31() for a slower implementation of this function which uses a 64-bit accumulator to provide higher precision. + */ + +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) +{ + const q31_t *pIn1; /* InputA pointer */ + const q31_t *pIn2; /* InputB pointer */ + q31_t *pOut = pDst; /* Output pointer */ + const q31_t *px; /* Intermediate inputA pointer */ + const q31_t *py; /* Intermediate inputB pointer */ + const q31_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q31_t sum; /* Accumulators */ + uint32_t j, k, count, check, blkCnt; + int32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + arm_status status; /* Status of Partial convolution */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc0, acc1, acc2, acc3; /* Accumulators */ + q31_t x0, x1, x2, x3, c0; +#endif + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* Conditions to check which loopCounter holds + * the first and last indices of the output samples to be calculated. */ + check = firstIndex + numPoints; + blockSize3 = ((int32_t)check > (int32_t)srcALen) ? (int32_t)check - (int32_t)srcALen : 0; + blockSize3 = ((int32_t)firstIndex > (int32_t)srcALen - 1) ? blockSize3 - (int32_t)firstIndex + (int32_t)srcALen : blockSize3; + blockSize1 = ((int32_t) srcBLen - 1) - (int32_t) firstIndex; + blockSize1 = (blockSize1 > 0) ? ((check > (srcBLen - 1U)) ? blockSize1 : (int32_t) numPoints) : 0; + blockSize2 = (int32_t) check - ((blockSize3 + blockSize1) + (int32_t) firstIndex); + blockSize2 = (blockSize2 > 0) ? blockSize2 : 0; + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* Set the output pointer to point to the firstIndex + * of the output sample to be calculated. */ + pOut = pDst + firstIndex; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed. + Since the partial convolution starts from firstIndex + Number of Macs to be performed is firstIndex + 1 */ + count = 1U + firstIndex; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + firstIndex; + py = pSrc2; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[0] * y[srcBLen - 1] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* x[1] * y[srcBLen - 2] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* x[2] * y[srcBLen - 3] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* x[3] * y[srcBLen - 4] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum << 1; + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = ++pSrc2; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0) + { + pSrc1 = pIn1 + firstIndex - srcBLen + 1; + } + else + { + pSrc1 = pIn1; + } + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = ((uint32_t) blockSize2 >> 2U); + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* read x[0], x[1], x[2] samples */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read y[srcBLen - 1] sample */ + c0 = *py--; + /* Read x[3] sample */ + x3 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[0] * y[srcBLen - 1] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc1 += x[1] * y[srcBLen - 1] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc2 += x[2] * y[srcBLen - 1] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc3 += x[3] * y[srcBLen - 1] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + /* Read y[srcBLen - 2] sample */ + c0 = *py--; + /* Read x[4] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[1] * y[srcBLen - 2] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc1 += x[2] * y[srcBLen - 2] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc2 += x[3] * y[srcBLen - 2] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x3 * c0)) >> 32); + /* acc3 += x[4] * y[srcBLen - 2] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x0 * c0)) >> 32); + + /* Read y[srcBLen - 3] sample */ + c0 = *py--; + /* Read x[5] sample */ + x1 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[2] * y[srcBLen - 3] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc1 += x[3] * y[srcBLen - 2] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x3 * c0)) >> 32); + /* acc2 += x[4] * y[srcBLen - 2] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc3 += x[5] * y[srcBLen - 2] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x1 * c0)) >> 32); + + /* Read y[srcBLen - 4] sample */ + c0 = *py--; + /* Read x[6] sample */ + x2 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[3] * y[srcBLen - 4] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x3 * c0)) >> 32); + /* acc1 += x[4] * y[srcBLen - 4] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc2 += x[5] * y[srcBLen - 4] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc3 += x[6] * y[srcBLen - 4] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x2 * c0)) >> 32); + + } while (--k); + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Read y[srcBLen - 5] sample */ + c0 = *py--; + /* Read x[7] sample */ + x3 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[4] * y[srcBLen - 5] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc1 += x[5] * y[srcBLen - 5] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc2 += x[6] * y[srcBLen - 5] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc3 += x[7] * y[srcBLen - 5] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (acc0 << 1); + *pOut++ = (q31_t) (acc1 << 1); + *pOut++ = (q31_t) (acc2 << 1); + *pOut++ = (q31_t) (acc3 << 1); + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (uint32_t) blockSize2 % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) * px++ * (*py--))) >> 32); + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) * px++ * (*py--))) >> 32); + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) * px++ * (*py--))) >> 32); + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) * px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum << 1; + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = (uint32_t) blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum << 1; + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py--))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = sum << 1; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement MAC count */ + count--; + + /* Decrement the loop counter */ + blockSize3--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); + +} + +/** + @} end of PartialConv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_opt_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_opt_q15.c new file mode 100644 index 0000000..21999d2 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_opt_q15.c @@ -0,0 +1,386 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_partial_opt_q15.c + * Description: Partial convolution of Q15 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup PartialConv + @{ + */ + +/** + @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 location where the output result is written + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : requested subset is not in the range [0 srcALen+srcBLen-2] + + @remark + Refer to \ref arm_conv_partial_fast_q15() for a faster but less precise version of this function. + */ + +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) +{ + + q15_t *pOut = pDst; /* Output pointer */ + q15_t *pScr1 = pScratch1; /* Temporary pointer for scratch1 */ + q15_t *pScr2 = pScratch2; /* Temporary pointer for scratch1 */ + q63_t acc0; /* Accumulator */ + q31_t x1; /* Temporary variables to hold state and coefficient values */ + q31_t y1; /* State variables */ + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + const q15_t *px; /* Intermediate inputA pointer */ + q15_t *py; /* Intermediate inputB pointer */ + uint32_t j, k, blkCnt; /* Loop counter */ + uint32_t tapCnt; /* Loop count */ + arm_status status; /* Status variable */ + +#if defined (ARM_MATH_LOOPUNROLL) + q63_t acc1, acc2, acc3; /* Accumulator */ + q31_t x2, x3; /* Temporary variables to hold state and coefficient values */ + q31_t y2; /* State variables */ +#endif + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* Temporary pointer for scratch2 */ + py = pScratch2; + + /* pointer to take end of scratch2 buffer */ + pScr2 = pScratch2 + srcBLen - 1; + + /* points to smaller length sequence */ + px = pIn2; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + /* Copy smaller length input sequence in reverse order into second scratch buffer */ + while (k > 0U) + { + /* copy second buffer in reversal manner */ + *pScr2-- = *px++; + *pScr2-- = *px++; + *pScr2-- = *px++; + *pScr2-- = *px++; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* copy second buffer in reversal manner for remaining samples */ + *pScr2-- = *px++; + + /* Decrement loop counter */ + k--; + } + + /* Initialze temporary scratch pointer */ + pScr1 = pScratch1; + + /* Assuming scratch1 buffer is aligned by 32-bit */ + /* Fill (srcBLen - 1U) zeros in scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update temporary scratch pointer */ + pScr1 += (srcBLen - 1U); + + /* Copy bigger length sequence(srcALen) samples in scratch1 buffer */ + + /* Copy (srcALen) samples in scratch buffer */ + arm_copy_q15(pIn1, pScr1, srcALen); + + /* Update pointers */ + pScr1 += srcALen; + + /* Fill (srcBLen - 1U) zeros at end of scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update pointer */ + pScr1 += (srcBLen - 1U); + + /* Initialization of pIn2 pointer */ + pIn2 = py; + + pScratch1 += firstIndex; + + pOut = pDst + firstIndex; + + /* Actual convolution process starts here */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (numPoints) >> 2; + + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Read two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read next two samples from scratch1 buffer */ + x2 = read_q15x2_ia (&pScr1); + + tapCnt = (srcBLen) >> 2U; + + while (tapCnt > 0U) + { + + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia ((q15_t **) &pIn2); + y2 = read_q15x2_ia ((q15_t **) &pIn2); + + /* multiply and accumlate */ + acc0 = __SMLALD(x1, y1, acc0); + acc2 = __SMLALD(x2, y1, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + /* multiply and accumlate */ + acc1 = __SMLALDX(x3, y1, acc1); + + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* multiply and accumlate */ + acc0 = __SMLALD(x2, y2, acc0); + acc2 = __SMLALD(x1, y2, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x1, x2, 0); +#else + x3 = __PKHBT(x2, x1, 0); +#endif + + acc3 = __SMLALDX(x3, y1, acc3); + acc1 = __SMLALDX(x3, y2, acc1); + + x2 = read_q15x2_ia (&pScr1); + +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + acc3 = __SMLALDX(x3, y2, acc3); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Update scratch pointer for remaining samples of smaller length sequence */ + pScr1 -= 4U; + + /* apply same above for remaining samples of smaller length sequence */ + tapCnt = (srcBLen) & 3U; + + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2); + acc1 += (*pScr1++ * *pIn2); + acc2 += (*pScr1++ * *pIn2); + acc3 += (*pScr1++ * *pIn2++); + + pScr1 -= 3U; + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the results in the accumulators in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc0 >> 15), 16), __SSAT((acc1 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc2 >> 15), 16), __SSAT((acc3 >> 15), 16), 16)); +#else + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc1 >> 15), 16), __SSAT((acc0 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc3 >> 15), 16), __SSAT((acc2 >> 15), 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch1 += 4U; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numPoints & 0x3; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numPoints; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Calculate convolution for remaining samples of Bigger length sequence */ + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + + tapCnt = (srcBLen) >> 1U; + + while (tapCnt > 0U) + { + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read two samples from smaller buffer */ + y1 = read_q15x2_ia ((q15_t **) &pIn2); + + acc0 = __SMLALD(x1, y1, acc0); + + /* Decrement the loop counter */ + tapCnt--; + } + + tapCnt = (srcBLen) & 1U; + + /* apply same above for remaining samples of smaller length sequence */ + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2++); + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* The result is in 2.30 format. Convert to 1.15 with saturation. + ** Then store the output in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((acc0 >> 15), 16)); + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch1 += 1U; + + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of PartialConv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_opt_q7.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_opt_q7.c new file mode 100644 index 0000000..811f386 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_opt_q7.c @@ -0,0 +1,390 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_partial_opt_q7.c + * Description: Partial convolution of Q7 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup PartialConv + @{ + */ + +/** + @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 location where the output result is written + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : 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) +{ + q15_t *pScr2, *pScr1; /* Intermediate pointers for scratch pointers */ + q15_t x4; /* Temporary input variable */ + const q7_t *pIn1, *pIn2; /* InputA and inputB pointer */ + uint32_t j, k, blkCnt, tapCnt; /* Loop counter */ + const q7_t *px; /* Temporary input1 pointer */ + q15_t *py; /* Temporary input2 pointer */ + q31_t acc0, acc1, acc2, acc3; /* Accumulator */ + q31_t x1, x2, x3, y1; /* Temporary input variables */ + arm_status status; + q7_t *pOut = pDst; /* Output pointer */ + q7_t out0, out1, out2, out3; /* Temporary variables */ + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* pointer to take end of scratch2 buffer */ + pScr2 = pScratch2; + + /* points to smaller length sequence */ + px = pIn2 + srcBLen - 1; + + /* Apply loop unrolling and do 4 Copies simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling copies 4 data points at a time. + ** a second loop below copies for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* copy second buffer in reversal manner */ + x4 = (q15_t) *px--; + *pScr2++ = x4; + x4 = (q15_t) *px--; + *pScr2++ = x4; + x4 = (q15_t) *px--; + *pScr2++ = x4; + x4 = (q15_t) *px--; + *pScr2++ = x4; + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, copy remaining samples here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* copy second buffer in reversal manner for remaining samples */ + x4 = (q15_t) *px--; + *pScr2++ = x4; + + /* Decrement loop counter */ + k--; + } + + /* Initialze temporary scratch pointer */ + pScr1 = pScratch1; + + /* Fill (srcBLen - 1U) zeros in scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update temporary scratch pointer */ + pScr1 += (srcBLen - 1U); + + /* Copy (srcALen) samples in scratch buffer */ + /* Apply loop unrolling and do 4 Copies simultaneously. */ + k = srcALen >> 2U; + + /* First part of the processing with loop unrolling copies 4 data points at a time. + ** a second loop below copies for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* copy second buffer in reversal manner */ + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, copy remaining samples here. + ** No loop unrolling is used. */ + k = srcALen % 0x4U; + + while (k > 0U) + { + /* copy second buffer in reversal manner for remaining samples */ + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + + /* Decrement the loop counter */ + k--; + } + + /* Fill (srcBLen - 1U) zeros at end of scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update pointer */ + pScr1 += (srcBLen - 1U); + + + /* Temporary pointer for scratch2 */ + py = pScratch2; + + /* Initialization of pIn2 pointer */ + pIn2 = (q7_t *) py; + + pScr2 = py; + + pOut = pDst + firstIndex; + + pScratch1 += firstIndex; + + /* Actual convolution process starts here */ + blkCnt = (numPoints) >> 2; + + while (blkCnt > 0) + { + /* Initialize temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumulators */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Read two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read next two samples from scratch1 buffer */ + x2 = read_q15x2_ia (&pScr1); + + tapCnt = (srcBLen) >> 2U; + + while (tapCnt > 0U) + { + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia (&pScr2); + + /* multiply and accumlate */ + acc0 = __SMLAD(x1, y1, acc0); + acc2 = __SMLAD(x2, y1, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + /* multiply and accumlate */ + acc1 = __SMLADX(x3, y1, acc1); + + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x1, x2, 0); +#else + x3 = __PKHBT(x2, x1, 0); +#endif + + acc3 = __SMLADX(x3, y1, acc3); + + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia (&pScr2); + + acc0 = __SMLAD(x2, y1, acc0); + + acc2 = __SMLAD(x1, y1, acc2); + + acc1 = __SMLADX(x3, y1, acc1); + + x2 = read_q15x2_ia (&pScr1); + +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + acc3 = __SMLADX(x3, y1, acc3); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Update scratch pointer for remaining samples of smaller length sequence */ + pScr1 -= 4U; + + /* apply same above for remaining samples of smaller length sequence */ + tapCnt = (srcBLen) & 3U; + + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pScr2); + acc1 += (*pScr1++ * *pScr2); + acc2 += (*pScr1++ * *pScr2); + acc3 += (*pScr1++ * *pScr2++); + + pScr1 -= 3U; + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the result in the accumulator in the destination buffer. */ + out0 = (q7_t) (__SSAT(acc0 >> 7U, 8)); + out1 = (q7_t) (__SSAT(acc1 >> 7U, 8)); + out2 = (q7_t) (__SSAT(acc2 >> 7U, 8)); + out3 = (q7_t) (__SSAT(acc3 >> 7U, 8)); + + write_q7x4_ia (&pOut, __PACKq7(out0, out1, out2, out3)); + + /* Initialization of inputB pointer */ + pScr2 = py; + + pScratch1 += 4U; + } + + blkCnt = (numPoints) & 0x3; + + /* Calculate convolution for remaining samples of Bigger length sequence */ + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + + tapCnt = (srcBLen) >> 1U; + + while (tapCnt > 0U) + { + + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read two samples from smaller buffer */ + y1 = read_q15x2_ia (&pScr2); + + acc0 = __SMLAD(x1, y1, acc0); + + /* Decrement the loop counter */ + tapCnt--; + } + + tapCnt = (srcBLen) & 1U; + + /* apply same above for remaining samples of smaller length sequence */ + while (tapCnt > 0U) + { + + /* accumlate the results */ + acc0 += (*pScr1++ * *pScr2++); + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(acc0 >> 7U, 8)); + + /* Initialization of inputB pointer */ + pScr2 = py; + + pScratch1 += 1U; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + return (status); +} + +/** + @} end of PartialConv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q15.c new file mode 100644 index 0000000..55272ea --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q15.c @@ -0,0 +1,752 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_partial_q15.c + * Description: Partial convolution of Q15 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup PartialConv + @{ + */ + +/** + @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 location where the output result is written + @param[in] firstIndex is the first output sample to start with + @param[in] numPoints is the number of output points to be computed + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : requested subset is not in the range [0 srcALen+srcBLen-2] + + @remark + Refer to \ref arm_conv_partial_fast_q15() for a faster but less precise version of this function. + @remark + Refer to \ref arm_conv_partial_opt_q15() for a faster implementation of this function using scratch buffers. + */ + +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) +{ + +#if defined (ARM_MATH_DSP) + + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + q15_t *pOut = pDst; /* Output pointer */ + q63_t sum, acc0, acc1, acc2, acc3; /* Accumulator */ + const q15_t *px; /* Intermediate inputA pointer */ + const q15_t *py; /* Intermediate inputB pointer */ + const q15_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q31_t x0, x1, x2, x3, c0; /* Temporary input variables to hold state and coefficient values */ + int32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt, check; + arm_status status; /* Status of Partial convolution */ + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* Conditions to check which loopCounter holds + * the first and last indices of the output samples to be calculated. */ + check = firstIndex + numPoints; + blockSize3 = ((int32_t)check > (int32_t)srcALen) ? (int32_t)check - (int32_t)srcALen : 0; + blockSize3 = ((int32_t)firstIndex > (int32_t)srcALen - 1) ? blockSize3 - (int32_t)firstIndex + (int32_t)srcALen : blockSize3; + blockSize1 = ((int32_t) srcBLen - 1) - (int32_t) firstIndex; + blockSize1 = (blockSize1 > 0) ? ((check > (srcBLen - 1U)) ? blockSize1 : (int32_t) numPoints) : 0; + blockSize2 = (int32_t) check - ((blockSize3 + blockSize1) + (int32_t) firstIndex); + blockSize2 = (blockSize2 > 0) ? blockSize2 : 0; + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* Set the output pointer to point to the firstIndex + * of the output sample to be calculated. */ + pOut = pDst + firstIndex; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed. + Since the partial convolution starts from firstIndex + Number of Macs to be performed is firstIndex + 1 */ + count = 1U + firstIndex; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + firstIndex; + py = pSrc2; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* For loop unrolling by 4, this stage is divided into two. */ + /* First part of this stage computes the MAC operations less than 4 */ + /* Second part of this stage computes the MAC operations greater than or equal to 4 */ + + /* The first part of the stage starts here */ + while ((count < 4U) && (blockSize1 > 0U)) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Loop over number of MAC operations between + * inputA samples and inputB samples */ + k = count; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = __SMLALD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((sum >> 15), 16)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = ++pSrc2; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* The second part of the stage starts here */ + /* The internal loop, over count, is unrolled by 4 */ + /* To, read the last two inputB samples using SIMD: + * y[srcBLen] and y[srcBLen-1] coefficients, py is decremented by 1 */ + py = py - 1; + + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* x[0], x[1] are multiplied with y[srcBLen - 1], y[srcBLen - 2] respectively */ + sum = __SMLALDX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + /* x[2], x[3] are multiplied with y[srcBLen - 3], y[srcBLen - 4] respectively */ + sum = __SMLALDX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* For the next MAC operations, the pointer py is used without SIMD + * So, py is incremented by 1 */ + py = py + 1U; + + /* If the count is not a multiple of 4, compute any remaining MACs here. + No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = __SMLALD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((sum >> 15), 16)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = ++pSrc2 - 1U; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0) + { + pSrc1 = pIn1 + firstIndex - srcBLen + 1; + } + else + { + pSrc1 = pIn1; + } + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is the index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = ((uint32_t) blockSize2 >> 2U); + + while (blkCnt > 0U) + { + py = py - 1U; + + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + + /* read x[0], x[1] samples */ + x0 = read_q15x2 ((q15_t *) px); + /* read x[1], x[2] samples */ + x1 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read the last two inputB samples using SIMD: + * y[srcBLen - 1] and y[srcBLen - 2] */ + c0 = read_q15x2_da ((q15_t **) &py); + + /* acc0 += x[0] * y[srcBLen - 1] + x[1] * y[srcBLen - 2] */ + acc0 = __SMLALDX(x0, c0, acc0); + + /* acc1 += x[1] * y[srcBLen - 1] + x[2] * y[srcBLen - 2] */ + acc1 = __SMLALDX(x1, c0, acc1); + + /* Read x[2], x[3] */ + x2 = read_q15x2 ((q15_t *) px); + + /* Read x[3], x[4] */ + x3 = read_q15x2 ((q15_t *) px + 1); + + /* acc2 += x[2] * y[srcBLen - 1] + x[3] * y[srcBLen - 2] */ + acc2 = __SMLALDX(x2, c0, acc2); + + /* acc3 += x[3] * y[srcBLen - 1] + x[4] * y[srcBLen - 2] */ + acc3 = __SMLALDX(x3, c0, acc3); + + /* Read y[srcBLen - 3] and y[srcBLen - 4] */ + c0 = read_q15x2_da ((q15_t **) &py); + + /* acc0 += x[2] * y[srcBLen - 3] + x[3] * y[srcBLen - 4] */ + acc0 = __SMLALDX(x2, c0, acc0); + + /* acc1 += x[3] * y[srcBLen - 3] + x[4] * y[srcBLen - 4] */ + acc1 = __SMLALDX(x3, c0, acc1); + + /* Read x[4], x[5] */ + x0 = read_q15x2 ((q15_t *) px + 2); + + /* Read x[5], x[6] */ + x1 = read_q15x2 ((q15_t *) px + 3); + px += 4U; + + /* acc2 += x[4] * y[srcBLen - 3] + x[5] * y[srcBLen - 4] */ + acc2 = __SMLALDX(x0, c0, acc2); + + /* acc3 += x[5] * y[srcBLen - 3] + x[6] * y[srcBLen - 4] */ + acc3 = __SMLALDX(x1, c0, acc3); + + } while (--k); + + /* For the next MAC operations, SIMD is not used + * So, the 16 bit pointer if inputB, py is updated */ + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + if (k == 1U) + { + /* Read y[srcBLen - 5] */ + c0 = *(py+1); +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[7] */ + x3 = read_q15x2 ((q15_t *) px); + px++; + + /* Perform the multiply-accumulate */ + acc0 = __SMLALD (x0, c0, acc0); + acc1 = __SMLALD (x1, c0, acc1); + acc2 = __SMLALDX(x1, c0, acc2); + acc3 = __SMLALDX(x3, c0, acc3); + } + + if (k == 2U) + { + /* Read y[srcBLen - 5], y[srcBLen - 6] */ + c0 = read_q15x2 ((q15_t *) py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + /* Perform the multiply-accumulate */ + acc0 = __SMLALDX(x0, c0, acc0); + acc1 = __SMLALDX(x1, c0, acc1); + acc2 = __SMLALDX(x3, c0, acc2); + acc3 = __SMLALDX(x2, c0, acc3); + } + + if (k == 3U) + { + /* Read y[srcBLen - 5], y[srcBLen - 6] */ + c0 = read_q15x2 ((q15_t *) py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + + /* Perform the multiply-accumulate */ + acc0 = __SMLALDX(x0, c0, acc0); + acc1 = __SMLALDX(x1, c0, acc1); + acc2 = __SMLALDX(x3, c0, acc2); + acc3 = __SMLALDX(x2, c0, acc3); + + c0 = *(py-1); +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[10] */ + x3 = read_q15x2 ((q15_t *) px + 2); + px += 3U; + + /* Perform the multiply-accumulates */ + acc0 = __SMLALDX(x1, c0, acc0); + acc1 = __SMLALD (x2, c0, acc1); + acc2 = __SMLALDX(x2, c0, acc2); + acc3 = __SMLALDX(x3, c0, acc3); + } + + /* Store the results in the accumulators in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc0 >> 15), 16), __SSAT((acc1 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc2 >> 15), 16), __SSAT((acc3 >> 15), 16), 16)); +#else + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc1 >> 15), 16), __SSAT((acc0 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc3 >> 15), 16), __SSAT((acc2 >> 15), 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here. + No loop unrolling is used. */ + blkCnt = (uint32_t) blockSize2 % 0x4U; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += (q63_t) ((q31_t) *px++ * *py--); + sum += (q63_t) ((q31_t) *px++ * *py--); + sum += (q63_t) ((q31_t) *px++ * *py--); + sum += (q63_t) ((q31_t) *px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) ((q31_t) *px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT(sum >> 15, 16)); + + /* Increment the pointer pIn1 index, count by 1 */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = (uint32_t) blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) ((q31_t) *px++ * *py--); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT(sum >> 15, 16)); + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + pIn2 = pSrc2 - 1U; + py = pIn2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + /* For loop unrolling by 4, this stage is divided into two. */ + /* First part of this stage computes the MAC operations greater than 4 */ + /* Second part of this stage computes the MAC operations less than or equal to 4 */ + + /* The first part of the stage starts here */ + j = count >> 2U; + + while ((j > 0U) && (blockSize3 > 0U)) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* x[srcALen - srcBLen + 1], x[srcALen - srcBLen + 2] are multiplied + * with y[srcBLen - 1], y[srcBLen - 2] respectively */ + sum = __SMLALDX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + /* x[srcALen - srcBLen + 3], x[srcALen - srcBLen + 4] are multiplied + * with y[srcBLen - 3], y[srcBLen - 4] respectively */ + sum = __SMLALDX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* For the next MAC operations, the pointer py is used without SIMD + * So, py is incremented by 1 */ + py = py + 1U; + + /* If the count is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* sum += x[srcALen - srcBLen + 5] * y[srcBLen - 5] */ + sum = __SMLALD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((sum >> 15), 16)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pIn2; + + /* Decrement MAC count */ + count--; + + /* Decrement loop counter */ + blockSize3--; + + j--; + } + + /* The second part of the stage starts here */ + /* SIMD is not used for the next MAC operations, + * so pointer py is updated to read only one sample at a time */ + py = py + 1U; + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum = __SMLALD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((sum >> 15), 16)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement MAC count */ + count--; + + /* Decrement the loop counter */ + blockSize3--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); + +#else /* #if defined (ARM_MATH_DSP) */ + + const q15_t *pIn1 = pSrcA; /* InputA pointer */ + const q15_t *pIn2 = pSrcB; /* InputB pointer */ + q63_t sum; /* Accumulator */ + uint32_t i, j; /* Loop counters */ + arm_status status; /* Status of Partial convolution */ + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* Loop to calculate convolution for output length number of values */ + for (i = firstIndex; i <= (firstIndex + numPoints - 1); i++) + { + /* Initialize sum with zero to carry on MAC operations */ + sum = 0; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ((q31_t) pIn1[j] * pIn2[i - j]); + } + } + + /* Store the output in the destination buffer */ + pDst[i] = (q15_t) __SSAT((sum >> 15U), 16U); + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); + +#endif /* #if defined (ARM_MATH_DSP) */ + +} + +/** + @} end of PartialConv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q31.c new file mode 100644 index 0000000..d0f0122 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q31.c @@ -0,0 +1,634 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_partial_q31.c + * Description: Partial convolution of Q31 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup PartialConv + @{ + */ + +/** + @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 location where the output result is written + @param[in] firstIndex is the first output sample to start with + @param[in] numPoints is the number of output points to be computed + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : requested subset is not in the range [0 srcALen+srcBLen-2] + + @remark + Refer to \ref arm_conv_partial_fast_q31() for a faster but less precise implementation of this function. + */ + +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) +{ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + const q31_t *pIn1; /* InputA pointer */ + const q31_t *pIn2; /* InputB pointer */ + q31_t *pOut = pDst; /* Output pointer */ + const q31_t *px; /* Intermediate inputA pointer */ + const q31_t *py; /* Intermediate inputB pointer */ + const q31_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q63_t sum; /* Accumulator */ + uint32_t j, k, count, blkCnt, check; + int32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + arm_status status; /* Status of Partial convolution */ + +#if defined (ARM_MATH_LOOPUNROLL) + q63_t acc0, acc1, acc2; /* Accumulator */ + q31_t x0, x1, x2, c0; /* Temporary variables */ +#endif + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* Conditions to check which loopCounter holds + * the first and last indices of the output samples to be calculated. */ + check = firstIndex + numPoints; + blockSize3 = ((int32_t)check > (int32_t)srcALen) ? (int32_t)check - (int32_t)srcALen : 0; + blockSize3 = ((int32_t)firstIndex > (int32_t)srcALen - 1) ? blockSize3 - (int32_t)firstIndex + (int32_t)srcALen : blockSize3; + blockSize1 = ((int32_t) srcBLen - 1) - (int32_t) firstIndex; + blockSize1 = (blockSize1 > 0) ? ((check > (srcBLen - 1U)) ? blockSize1 : (int32_t) numPoints) : 0; + blockSize2 = (int32_t) check - ((blockSize3 + blockSize1) + (int32_t) firstIndex); + blockSize2 = (blockSize2 > 0) ? blockSize2 : 0; + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* Set the output pointer to point to the firstIndex + * of the output sample to be calculated. */ + pOut = pDst + firstIndex; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed. + Since the partial convolution starts from firstIndex + Number of Macs to be performed is firstIndex + 1 */ + count = 1U + firstIndex; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + firstIndex; + py = pSrc2; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[0] * y[srcBLen - 1] */ + sum += (q63_t) *px++ * (*py--); + + /* x[1] * y[srcBLen - 2] */ + sum += (q63_t) *px++ * (*py--); + + /* x[2] * y[srcBLen - 3] */ + sum += (q63_t) *px++ * (*py--); + + /* x[3] * y[srcBLen - 4] */ + sum += (q63_t) *px++ * (*py--); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) *px++ * (*py--); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (sum >> 31); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = ++pSrc2; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0) + { + pSrc1 = pIn1 + firstIndex - srcBLen + 1; + } + else + { + pSrc1 = pIn1; + } + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unroll over blkCnt */ + blkCnt = blockSize2 / 3; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + + /* read x[0], x[1] samples */ + x0 = *px++; + x1 = *px++; + + /* Apply loop unrolling and compute 3 MACs simultaneously. */ + k = srcBLen / 3; + + /* First part of the processing with loop unrolling. Compute 3 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 2 samples. */ + do + { + /* Read y[srcBLen - 1] sample */ + c0 = *(py); + + /* Read x[2] sample */ + x2 = *(px); + + /* Perform the multiply-accumulate */ + /* acc0 += x[0] * y[srcBLen - 1] */ + acc0 += (q63_t) x0 * c0; + /* acc1 += x[1] * y[srcBLen - 1] */ + acc1 += (q63_t) x1 * c0; + /* acc2 += x[2] * y[srcBLen - 1] */ + acc2 += (q63_t) x2 * c0; + + /* Read y[srcBLen - 2] sample */ + c0 = *(py - 1U); + + /* Read x[3] sample */ + x0 = *(px + 1U); + + /* Perform the multiply-accumulate */ + /* acc0 += x[1] * y[srcBLen - 2] */ + acc0 += (q63_t) x1 * c0; + /* acc1 += x[2] * y[srcBLen - 2] */ + acc1 += (q63_t) x2 * c0; + /* acc2 += x[3] * y[srcBLen - 2] */ + acc2 += (q63_t) x0 * c0; + + /* Read y[srcBLen - 3] sample */ + c0 = *(py - 2U); + + /* Read x[4] sample */ + x1 = *(px + 2U); + + /* Perform the multiply-accumulate */ + /* acc0 += x[2] * y[srcBLen - 3] */ + acc0 += (q63_t) x2 * c0; + /* acc1 += x[3] * y[srcBLen - 2] */ + acc1 += (q63_t) x0 * c0; + /* acc2 += x[4] * y[srcBLen - 2] */ + acc2 += (q63_t) x1 * c0; + + + px += 3U; + + py -= 3U; + + } while (--k); + + /* If the srcBLen is not a multiple of 3, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen - (3 * (srcBLen / 3)); + + while (k > 0U) + { + /* Read y[srcBLen - 5] sample */ + c0 = *py--; + /* Read x[7] sample */ + x2 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[4] * y[srcBLen - 5] */ + acc0 += (q63_t) x0 * c0; + /* acc1 += x[5] * y[srcBLen - 5] */ + acc1 += (q63_t) x1 * c0; + /* acc2 += x[6] * y[srcBLen - 5] */ + acc2 += (q63_t) x2 * c0; + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (acc0 >> 31); + *pOut++ = (q31_t) (acc1 >> 31); + *pOut++ = (q31_t) (acc2 >> 31); + + /* Increment the pointer pIn1 index, count by 3 */ + count += 3U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize2 - 3 * (blockSize2 / 3); + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += (q63_t) *px++ * (*py--); + sum += (q63_t) *px++ * (*py--); + sum += (q63_t) *px++ * (*py--); + sum += (q63_t) *px++ * (*py--); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (sum >> 31); + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = (uint32_t) blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (sum >> 31); + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The blockSize3 variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */ + sum += (q63_t) *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */ + sum += (q63_t) *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */ + sum += (q63_t) *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */ + sum += (q63_t) *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum += (q63_t) *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (sum >> 31); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement MAC count */ + count--; + + /* Decrement the loop counter */ + blockSize3--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); + +#else +/* alternate version for CM0_FAMILY */ + + const q31_t *pIn1 = pSrcA; /* InputA pointer */ + const q31_t *pIn2 = pSrcB; /* InputB pointer */ + q63_t sum; /* Accumulator */ + uint32_t i, j; /* Loop counters */ + arm_status status; /* Status of Partial convolution */ + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* Loop to calculate convolution for output length number of values */ + for (i = firstIndex; i <= (firstIndex + numPoints - 1); i++) + { + /* Initialize sum with zero to carry on MAC operations */ + sum = 0; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ((q63_t) pIn1[j] * pIn2[i - j]); + } + } + + /* Store the output in the destination buffer */ + pDst[i] = (q31_t) (sum >> 31U); + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of PartialConv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q7.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q7.c new file mode 100644 index 0000000..9b0228c --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_partial_q7.c @@ -0,0 +1,753 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_partial_q7.c + * Description: Partial convolution of Q7 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup PartialConv + @{ + */ + +/** + @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 location where the output result is written + @param[in] firstIndex is the first output sample to start with + @param[in] numPoints is the number of output points to be computed + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : requested subset is not in the range [0 srcALen+srcBLen-2] + + @remark + Refer to \ref arm_conv_partial_opt_q7() for a faster implementation of this function. + */ + +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) +{ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + const q7_t *pIn1; /* InputA pointer */ + const q7_t *pIn2; /* InputB pointer */ + q7_t *pOut = pDst; /* Output pointer */ + const q7_t *px; /* Intermediate inputA pointer */ + const q7_t *py; /* Intermediate inputB pointer */ + const q7_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q31_t sum; /* Accumulator */ + uint32_t j, k, count, blkCnt, check; /* Loop counters */ + int32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + arm_status status; /* Status of Partial convolution */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc0, acc1, acc2, acc3; /* Accumulator */ + q31_t input1, input2; /* Temporary input variables */ + q15_t in1, in2; /* Temporary input variables */ + q7_t x0, x1, x2, x3, c0, c1; /* Temporary variables to hold state and coefficient values */ +#endif + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* Conditions to check which loopCounter holds + * the first and last indices of the output samples to be calculated. */ + check = firstIndex + numPoints; + blockSize3 = ((int32_t)check > (int32_t)srcALen) ? (int32_t)check - (int32_t)srcALen : 0; + blockSize3 = ((int32_t)firstIndex > (int32_t)srcALen - 1) ? blockSize3 - (int32_t)firstIndex + (int32_t)srcALen : blockSize3; + blockSize1 = ((int32_t) srcBLen - 1) - (int32_t) firstIndex; + blockSize1 = (blockSize1 > 0) ? ((check > (srcBLen - 1U)) ? blockSize1 : (int32_t) numPoints) : 0; + blockSize2 = (int32_t) check - ((blockSize3 + blockSize1) + (int32_t) firstIndex); + blockSize2 = (blockSize2 > 0) ? blockSize2 : 0; + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* Set the output pointer to point to the firstIndex + * of the output sample to be calculated. */ + pOut = pDst + firstIndex; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed. + Since the partial convolution starts from firstIndex + Number of Macs to be performed is firstIndex + 1 */ + count = 1U + firstIndex; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + firstIndex; + py = pSrc2; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[0] , x[1] */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* y[srcBLen - 1] , y[srcBLen - 2] */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* x[0] * y[srcBLen - 1] */ + /* x[1] * y[srcBLen - 2] */ + sum = __SMLAD(input1, input2, sum); + + /* x[2] , x[3] */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* y[srcBLen - 3] , y[srcBLen - 4] */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* x[2] * y[srcBLen - 3] */ + /* x[3] * y[srcBLen - 4] */ + sum = __SMLAD(input1, input2, sum); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q31_t) * px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(sum >> 7, 8)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = ++pSrc2; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + if ((int32_t)firstIndex - (int32_t)srcBLen + 1 > 0) + { + pSrc1 = pIn1 + firstIndex - srcBLen + 1; + } + else + { + pSrc1 = pIn1; + } + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is the index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = ((uint32_t) blockSize2 >> 2U); + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* read x[0], x[1], x[2] samples */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read y[srcBLen - 1] sample */ + c0 = *py--; + /* Read y[srcBLen - 2] sample */ + c1 = *py--; + + /* Read x[3] sample */ + x3 = *px++; + + /* x[0] and x[1] are packed */ + in1 = (q15_t) x0; + in2 = (q15_t) x1; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* y[srcBLen - 1] and y[srcBLen - 2] are packed */ + in1 = (q15_t) c0; + in2 = (q15_t) c1; + + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* acc0 += x[0] * y[srcBLen - 1] + x[1] * y[srcBLen - 2] */ + acc0 = __SMLAD(input1, input2, acc0); + + /* x[1] and x[2] are packed */ + in1 = (q15_t) x1; + in2 = (q15_t) x2; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* acc1 += x[1] * y[srcBLen - 1] + x[2] * y[srcBLen - 2] */ + acc1 = __SMLAD(input1, input2, acc1); + + /* x[2] and x[3] are packed */ + in1 = (q15_t) x2; + in2 = (q15_t) x3; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* acc2 += x[2] * y[srcBLen - 1] + x[3] * y[srcBLen - 2] */ + acc2 = __SMLAD(input1, input2, acc2); + + /* Read x[4] sample */ + x0 = *px++; + + /* x[3] and x[4] are packed */ + in1 = (q15_t) x3; + in2 = (q15_t) x0; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* acc3 += x[3] * y[srcBLen - 1] + x[4] * y[srcBLen - 2] */ + acc3 = __SMLAD(input1, input2, acc3); + + /* Read y[srcBLen - 3] sample */ + c0 = *py--; + /* Read y[srcBLen - 4] sample */ + c1 = *py--; + + /* Read x[5] sample */ + x1 = *px++; + + /* x[2] and x[3] are packed */ + in1 = (q15_t) x2; + in2 = (q15_t) x3; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* y[srcBLen - 3] and y[srcBLen - 4] are packed */ + in1 = (q15_t) c0; + in2 = (q15_t) c1; + + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* acc0 += x[2] * y[srcBLen - 3] + x[3] * y[srcBLen - 4] */ + acc0 = __SMLAD(input1, input2, acc0); + + /* x[3] and x[4] are packed */ + in1 = (q15_t) x3; + in2 = (q15_t) x0; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* acc1 += x[3] * y[srcBLen - 3] + x[4] * y[srcBLen - 4] */ + acc1 = __SMLAD(input1, input2, acc1); + + /* x[4] and x[5] are packed */ + in1 = (q15_t) x0; + in2 = (q15_t) x1; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* acc2 += x[4] * y[srcBLen - 3] + x[5] * y[srcBLen - 4] */ + acc2 = __SMLAD(input1, input2, acc2); + + /* Read x[6] sample */ + x2 = *px++; + + /* x[5] and x[6] are packed */ + in1 = (q15_t) x1; + in2 = (q15_t) x2; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* acc3 += x[5] * y[srcBLen - 3] + x[6] * y[srcBLen - 4] */ + acc3 = __SMLAD(input1, input2, acc3); + + } while (--k); + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Read y[srcBLen - 5] sample */ + c0 = *py--; + /* Read x[7] sample */ + x3 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[4] * y[srcBLen - 5] */ + acc0 += ((q31_t) x0 * c0); + /* acc1 += x[5] * y[srcBLen - 5] */ + acc1 += ((q31_t) x1 * c0); + /* acc2 += x[6] * y[srcBLen - 5] */ + acc2 += ((q31_t) x2 * c0); + /* acc3 += x[7] * y[srcBLen - 5] */ + acc3 += ((q31_t) x3 * c0); + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(acc0 >> 7, 8)); + *pOut++ = (q7_t) (__SSAT(acc1 >> 7, 8)); + *pOut++ = (q7_t) (__SSAT(acc2 >> 7, 8)); + *pOut++ = (q7_t) (__SSAT(acc3 >> 7, 8)); + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (uint32_t) blockSize2 % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + while (k > 0U) + { + /* Reading two inputs of SrcA buffer and packing */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* Reading two inputs of SrcB buffer and packing */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* Perform the multiply-accumulate */ + sum = __SMLAD(input1, input2, sum); + + /* Reading two inputs of SrcA buffer and packing */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* Reading two inputs of SrcB buffer and packing */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* Perform the multiply-accumulate */ + sum = __SMLAD(input1, input2, sum); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q31_t) * px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(sum >> 7, 8)); + + /* Increment the pointer pIn1 index, count by 1 */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = (uint32_t) blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q31_t) * px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(sum >> 7, 8)); + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pSrc1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* Reading two inputs, x[srcALen - srcBLen + 1] and x[srcALen - srcBLen + 2] of SrcA buffer and packing */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* Reading two inputs, y[srcBLen - 1] and y[srcBLen - 2] of SrcB buffer and packing */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */ + /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */ + sum = __SMLAD(input1, input2, sum); + + /* Reading two inputs, x[srcALen - srcBLen + 3] and x[srcALen - srcBLen + 4] of SrcA buffer and packing */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* Reading two inputs, y[srcBLen - 3] and y[srcBLen - 4] of SrcB buffer and packing */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */ + /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */ + sum = __SMLAD(input1, input2, sum); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum += ((q31_t) * px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(sum >> 7, 8)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement MAC count */ + count--; + + /* Decrement the loop counter */ + blockSize3--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); + +#else +/* alternate version for CM0_FAMILY */ + + const q7_t *pIn1 = pSrcA; /* InputA pointer */ + const q7_t *pIn2 = pSrcB; /* InputB pointer */ + q31_t sum; /* Accumulator */ + uint32_t i, j; /* Loop counters */ + arm_status status; /* Status of Partial convolution */ + + /* Check for range of output samples to be calculated */ + if ((firstIndex + numPoints) > ((srcALen + (srcBLen - 1U)))) + { + /* Set status as ARM_MATH_ARGUMENT_ERROR */ + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* Loop to calculate convolution for output length number of values */ + for (i = firstIndex; i <= (firstIndex + numPoints - 1); i++) + { + /* Initialize sum with zero to carry on MAC operations */ + sum = 0; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ((q15_t) pIn1[j] * (pIn2[i - j])); + } + } + + /* Store the output in the destination buffer */ + pDst[i] = (q7_t) __SSAT((sum >> 7U), 8U); + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of PartialConv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q15.c new file mode 100644 index 0000000..ad2b629 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q15.c @@ -0,0 +1,696 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_q15.c + * Description: Convolution of Q15 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Conv + @{ + */ + +/** + @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. + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both inputs are 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. + This approach provides 33 guard bits and there is no risk of overflow. + The 34.30 result is then truncated to 34.15 format by discarding the low 15 bits and then saturated to 1.15 format. + + @remark + Refer to \ref arm_conv_fast_q15() for a faster but less precise version of this function. + @remark + Refer to \ref arm_conv_opt_q15() for a faster implementation of this function using scratch buffers. + */ + +void arm_conv_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst) +{ + +#if defined (ARM_MATH_DSP) + + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + q15_t *pOut = pDst; /* Output pointer */ + q63_t sum, acc0, acc1, acc2, acc3; /* Accumulators */ + const q15_t *px; /* Intermediate inputA pointer */ + const q15_t *py; /* Intermediate inputB pointer */ + const q15_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q31_t x0, x1, x2, x3, c0; /* Temporary input variables to hold state and coefficient values */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* For loop unrolling by 4, this stage is divided into two. */ + /* First part of this stage computes the MAC operations less than 4 */ + /* Second part of this stage computes the MAC operations greater than or equal to 4 */ + + /* The first part of the stage starts here */ + while ((count < 4U) && (blockSize1 > 0U)) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Loop over number of MAC operations between + * inputA samples and inputB samples */ + k = count; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = __SMLALD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((sum >> 15), 16)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pIn2 + count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* The second part of the stage starts here */ + /* The internal loop, over count, is unrolled by 4 */ + /* To, read the last two inputB samples using SIMD: + * y[srcBLen] and y[srcBLen-1] coefficients, py is decremented by 1 */ + py = py - 1; + + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* x[0], x[1] are multiplied with y[srcBLen - 1], y[srcBLen - 2] respectively */ + sum = __SMLALDX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + /* x[2], x[3] are multiplied with y[srcBLen - 3], y[srcBLen - 4] respectively */ + sum = __SMLALDX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* For the next MAC operations, the pointer py is used without SIMD + * So, py is incremented by 1 */ + py = py + 1U; + + /* If the count is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = __SMLALD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((sum >> 15), 16)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pIn2 + (count - 1U); + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is the index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize2 >> 2U; + + while (blkCnt > 0U) + { + py = py - 1U; + + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* read x[0], x[1] samples */ + x0 = read_q15x2 ((q15_t *) px); + + /* read x[1], x[2] samples */ + x1 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read the last two inputB samples using SIMD: + * y[srcBLen - 1] and y[srcBLen - 2] */ + c0 = read_q15x2_da ((q15_t **) &py); + + /* acc0 += x[0] * y[srcBLen - 1] + x[1] * y[srcBLen - 2] */ + acc0 = __SMLALDX(x0, c0, acc0); + + /* acc1 += x[1] * y[srcBLen - 1] + x[2] * y[srcBLen - 2] */ + acc1 = __SMLALDX(x1, c0, acc1); + + /* Read x[2], x[3] */ + x2 = read_q15x2 ((q15_t *) px); + + /* Read x[3], x[4] */ + x3 = read_q15x2 ((q15_t *) px + 1); + + /* acc2 += x[2] * y[srcBLen - 1] + x[3] * y[srcBLen - 2] */ + acc2 = __SMLALDX(x2, c0, acc2); + + /* acc3 += x[3] * y[srcBLen - 1] + x[4] * y[srcBLen - 2] */ + acc3 = __SMLALDX(x3, c0, acc3); + + /* Read y[srcBLen - 3] and y[srcBLen - 4] */ + c0 = read_q15x2_da ((q15_t **) &py); + + /* acc0 += x[2] * y[srcBLen - 3] + x[3] * y[srcBLen - 4] */ + acc0 = __SMLALDX(x2, c0, acc0); + + /* acc1 += x[3] * y[srcBLen - 3] + x[4] * y[srcBLen - 4] */ + acc1 = __SMLALDX(x3, c0, acc1); + + /* Read x[4], x[5] */ + x0 = read_q15x2 ((q15_t *) px + 2); + + /* Read x[5], x[6] */ + x1 = read_q15x2 ((q15_t *) px + 3); + + px += 4U; + + /* acc2 += x[4] * y[srcBLen - 3] + x[5] * y[srcBLen - 4] */ + acc2 = __SMLALDX(x0, c0, acc2); + + /* acc3 += x[5] * y[srcBLen - 3] + x[6] * y[srcBLen - 4] */ + acc3 = __SMLALDX(x1, c0, acc3); + + } while (--k); + + /* For the next MAC operations, SIMD is not used + * So, the 16 bit pointer if inputB, py is updated */ + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + if (k == 1U) + { + /* Read y[srcBLen - 5] */ + c0 = *(py + 1); +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[7] */ + x3 = read_q15x2 ((q15_t *) px); + px++; + + /* Perform the multiply-accumulate */ + acc0 = __SMLALD(x0, c0, acc0); + acc1 = __SMLALD(x1, c0, acc1); + acc2 = __SMLALDX(x1, c0, acc2); + acc3 = __SMLALDX(x3, c0, acc3); + } + + if (k == 2U) + { + /* Read y[srcBLen - 5], y[srcBLen - 6] */ + c0 = read_q15x2 ((q15_t *) py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + /* Perform the multiply-accumulate */ + acc0 = __SMLALDX(x0, c0, acc0); + acc1 = __SMLALDX(x1, c0, acc1); + acc2 = __SMLALDX(x3, c0, acc2); + acc3 = __SMLALDX(x2, c0, acc3); + } + + if (k == 3U) + { + /* Read y[srcBLen - 5], y[srcBLen - 6] */ + c0 = read_q15x2 ((q15_t *) py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + + /* Perform the multiply-accumulate */ + acc0 = __SMLALDX(x0, c0, acc0); + acc1 = __SMLALDX(x1, c0, acc1); + acc2 = __SMLALDX(x3, c0, acc2); + acc3 = __SMLALDX(x2, c0, acc3); + + c0 = *(py-1); +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[10] */ + x3 = read_q15x2 ((q15_t *) px + 2); + px += 3U; + + /* Perform the multiply-accumulates */ + acc0 = __SMLALDX(x1, c0, acc0); + acc1 = __SMLALD(x2, c0, acc1); + acc2 = __SMLALDX(x2, c0, acc2); + acc3 = __SMLALDX(x3, c0, acc3); + } + + /* Store the result in the accumulator in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc0 >> 15), 16), __SSAT((acc1 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc2 >> 15), 16), __SSAT((acc3 >> 15), 16), 16)); +#else + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc1 >> 15), 16), __SSAT((acc0 >> 15), 16), 16)); + write_q15x2_ia (&pOut, __PKHBT(__SSAT((acc3 >> 15), 16), __SSAT((acc2 >> 15), 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize2 % 0x4U; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += (q63_t) ((q31_t) *px++ * *py--); + sum += (q63_t) ((q31_t) *px++ * *py--); + sum += (q63_t) ((q31_t) *px++ * *py--); + sum += (q63_t) ((q31_t) *px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += (q63_t) ((q31_t) *px++ * *py--); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT(sum >> 15, 16)); + + /* Increment the pointer pIn1 index, count by 1 */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) ((q31_t) *px++ * *py--); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT(sum >> 15, 16)); + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The blockSize3 variable holds the number of MAC operations performed */ + blockSize3 = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + pIn2 = pSrc2 - 1U; + py = pIn2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + /* For loop unrolling by 4, this stage is divided into two. */ + /* First part of this stage computes the MAC operations greater than 4 */ + /* Second part of this stage computes the MAC operations less than or equal to 4 */ + + /* The first part of the stage starts here */ + j = blockSize3 >> 2U; + + while ((j > 0U) && (blockSize3 > 0U)) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = blockSize3 >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* x[srcALen - srcBLen + 1], x[srcALen - srcBLen + 2] are multiplied + * with y[srcBLen - 1], y[srcBLen - 2] respectively */ + sum = __SMLALDX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + /* x[srcALen - srcBLen + 3], x[srcALen - srcBLen + 4] are multiplied + * with y[srcBLen - 3], y[srcBLen - 4] respectively */ + sum = __SMLALDX(read_q15x2_ia ((q15_t **) &px), read_q15x2_da ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* For the next MAC operations, the pointer py is used without SIMD + * So, py is incremented by 1 */ + py = py + 1U; + + /* If the blockSize3 is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = blockSize3 % 0x4U; + + while (k > 0U) + { + /* sum += x[srcALen - srcBLen + 5] * y[srcBLen - 5] */ + sum = __SMLALD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((sum >> 15), 16)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pIn2; + + /* Decrement loop counter */ + blockSize3--; + + j--; + } + + /* The second part of the stage starts here */ + /* SIMD is not used for the next MAC operations, + * so pointer py is updated to read only one sample at a time */ + py = py + 1U; + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = blockSize3; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum = __SMLALD(*px++, *py--, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q15_t) (__SSAT((sum >> 15), 16)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement loop counter */ + blockSize3--; + } + +#else /* #if defined (ARM_MATH_DSP) */ + + const q15_t *pIn1 = pSrcA; /* InputA pointer */ + const q15_t *pIn2 = pSrcB; /* InputB pointer */ + q63_t sum; /* Accumulator */ + uint32_t i, j; /* Loop counters */ + + /* Loop to calculate convolution for output length number of values */ + for (i = 0; i < (srcALen + srcBLen - 1); i++) + { + /* Initialize sum with zero to carry on MAC operations */ + sum = 0; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ((q31_t) pIn1[j] * pIn2[i - j]); + } + } + + /* Store the output in the destination buffer */ + pDst[i] = (q15_t) __SSAT((sum >> 15U), 16U); + } + +#endif /* #if defined (ARM_MATH_DSP) */ + +} + +/** + @} end of Conv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q31.c new file mode 100644 index 0000000..39550ec --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q31.c @@ -0,0 +1,581 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_q31.c + * Description: Convolution of Q31 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Conv + @{ + */ + +/** + @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 location where the output result is written. Length srcALen+srcBLen-1. + @return none + + @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. + There is no saturation on intermediate additions. + Thus, if the accumulator overflows it wraps around and distorts the result. + The input signals should be scaled down to avoid intermediate overflows. + Scale down the inputs by log2(min(srcALen, srcBLen)) (log2 is read as log to the base 2) times to avoid overflows, + as maximum of min(srcALen, srcBLen) number of additions are carried internally. + The 2.62 accumulator is right shifted by 31 bits and saturated to 1.31 format to yield the final result. + + @remark + Refer to \ref arm_conv_fast_q31() for a faster but less precise implementation of this function. + */ + +void arm_conv_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst) +{ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + const q31_t *pIn1; /* InputA pointer */ + const q31_t *pIn2; /* InputB pointer */ + q31_t *pOut = pDst; /* Output pointer */ + const q31_t *px; /* Intermediate inputA pointer */ + const q31_t *py; /* Intermediate inputB pointer */ + const q31_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q63_t sum; /* Accumulators */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q63_t acc0, acc1, acc2; /* Accumulators */ + q31_t x0, x1, x2, c0; /* Temporary variables to hold state and coefficient values */ +#endif + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[0] * y[srcBLen - 1] */ + sum += (q63_t) *px++ * (*py--); + + /* x[1] * y[srcBLen - 2] */ + sum += (q63_t) *px++ * (*py--); + + /* x[2] * y[srcBLen - 3] */ + sum += (q63_t) *px++ * (*py--); + + /* x[3] * y[srcBLen - 4] */ + sum += (q63_t) *px++ * (*py--); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (sum >> 31); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pIn2 + count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unroll by 3 */ + blkCnt = blockSize2 / 3; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + + /* read x[0], x[1], x[2] samples */ + x0 = *px++; + x1 = *px++; + + /* Apply loop unrolling and compute 3 MACs simultaneously. */ + k = srcBLen / 3; + + /* First part of the processing with loop unrolling. Compute 3 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 2 samples. */ + do + { + /* Read y[srcBLen - 1] sample */ + c0 = *(py); + /* Read x[3] sample */ + x2 = *(px); + + /* Perform the multiply-accumulate */ + /* acc0 += x[0] * y[srcBLen - 1] */ + acc0 += ((q63_t) x0 * c0); + /* acc1 += x[1] * y[srcBLen - 1] */ + acc1 += ((q63_t) x1 * c0); + /* acc2 += x[2] * y[srcBLen - 1] */ + acc2 += ((q63_t) x2 * c0); + + /* Read y[srcBLen - 2] sample */ + c0 = *(py - 1U); + /* Read x[4] sample */ + x0 = *(px + 1U); + + /* Perform the multiply-accumulate */ + /* acc0 += x[1] * y[srcBLen - 2] */ + acc0 += ((q63_t) x1 * c0); + /* acc1 += x[2] * y[srcBLen - 2] */ + acc1 += ((q63_t) x2 * c0); + /* acc2 += x[3] * y[srcBLen - 2] */ + acc2 += ((q63_t) x0 * c0); + + /* Read y[srcBLen - 3] sample */ + c0 = *(py - 2U); + /* Read x[5] sample */ + x1 = *(px + 2U); + + /* Perform the multiply-accumulate */ + /* acc0 += x[2] * y[srcBLen - 3] */ + acc0 += ((q63_t) x2 * c0); + /* acc1 += x[3] * y[srcBLen - 2] */ + acc1 += ((q63_t) x0 * c0); + /* acc2 += x[4] * y[srcBLen - 2] */ + acc2 += ((q63_t) x1 * c0); + + /* update scratch pointers */ + px += 3U; + py -= 3U; + + } while (--k); + + /* If the srcBLen is not a multiple of 3, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen - (3 * (srcBLen / 3)); + + while (k > 0U) + { + /* Read y[srcBLen - 5] sample */ + c0 = *py--; + /* Read x[7] sample */ + x2 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[4] * y[srcBLen - 5] */ + acc0 += ((q63_t) x0 * c0); + /* acc1 += x[5] * y[srcBLen - 5] */ + acc1 += ((q63_t) x1 * c0); + /* acc2 += x[6] * y[srcBLen - 5] */ + acc2 += ((q63_t) x2 * c0); + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (acc0 >> 31); + *pOut++ = (q31_t) (acc1 >> 31); + *pOut++ = (q31_t) (acc2 >> 31); + + /* Increment the pointer pIn1 index, count by 3 */ + count += 3U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize2 - 3 * (blockSize2 / 3); + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += (q63_t) *px++ * *py--; + sum += (q63_t) *px++ * *py--; + sum += (q63_t) *px++ * *py--; + sum += (q63_t) *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) *px++ * *py--; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (sum >> 31); + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) *px++ * *py--; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (sum >> 31); + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The blockSize3 variable holds the number of MAC operations performed */ + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = blockSize3 >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */ + sum += (q63_t) *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */ + sum += (q63_t) *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */ + sum += (q63_t) *px++ * *py--; + + /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */ + sum += (q63_t) *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = blockSize3 % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = blockSize3; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum += (q63_t) *px++ * *py--; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q31_t) (sum >> 31); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement loop counter */ + blockSize3--; + } + +#else +/* alternate version for CM0_FAMILY */ + + const q31_t *pIn1 = pSrcA; /* InputA pointer */ + const q31_t *pIn2 = pSrcB; /* InputB pointer */ + q63_t sum; /* Accumulators */ + uint32_t i, j; /* Loop counters */ + + /* Loop to calculate convolution for output length number of times */ + for (i = 0U; i < (srcALen + srcBLen - 1U); i++) + { + /* Initialize sum with zero to carry out MAC operations */ + sum = 0; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ((q63_t) pIn1[j] * pIn2[i - j]); + } + } + + /* Store the output in the destination buffer */ + pDst[i] = (q31_t) (sum >> 31U); + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of Conv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q7.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q7.c new file mode 100644 index 0000000..bdd1cab --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_conv_q7.c @@ -0,0 +1,700 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_conv_q7.c + * Description: Convolution of Q7 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Conv + @{ + */ + +/** + @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 location where the output result is written. Length srcALen+srcBLen-1. + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 32-bit internal accumulator. + Both the inputs are represented in 1.7 format and multiplications yield a 2.14 result. + The 2.14 intermediate results are accumulated in a 32-bit accumulator in 18.14 format. + This approach provides 17 guard bits and there is no risk of overflow as long as max(srcALen, srcBLen)<131072. + The 18.14 result is then truncated to 18.7 format by discarding the low 7 bits and then saturated to 1.7 format. + @remark + Refer to \ref arm_conv_opt_q7() for a faster implementation of this function. + */ + +void arm_conv_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst) +{ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + const q7_t *pIn1; /* InputA pointer */ + const q7_t *pIn2; /* InputB pointer */ + q7_t *pOut = pDst; /* Output pointer */ + const q7_t *px; /* Intermediate inputA pointer */ + const q7_t *py; /* Intermediate inputB pointer */ + const q7_t *pSrc1, *pSrc2; /* Intermediate pointers */ + q31_t sum; /* Accumulators */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc0, acc1, acc2, acc3; /* Accumulators */ + q31_t input1, input2; /* Temporary input variables */ + q15_t in1, in2; /* Temporary input variables */ + q7_t x0, x1, x2, x3, c0, c1; /* Temporary variables to hold state and coefficient values */ +#endif + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + } + + /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */ + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[0] + * sum = x[0] * y[1] + x[1] * y[0] + * .... + * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[0] , x[1] */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* y[srcBLen - 1] , y[srcBLen - 2] */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* x[0] * y[srcBLen - 1] */ + /* x[1] * y[srcBLen - 2] */ + sum = __SMLAD(input1, input2, sum); + + /* x[2] , x[3] */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* y[srcBLen - 3] , y[srcBLen - 4] */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* x[2] * y[srcBLen - 3] */ + /* x[3] * y[srcBLen - 4] */ + sum = __SMLAD(input1, input2, sum); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q15_t) *px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(sum >> 7U, 8)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pIn2 + count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0] + * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0] + * .... + * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize2 >> 2U; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* read x[0], x[1], x[2] samples */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read y[srcBLen - 1] sample */ + c0 = *py--; + /* Read y[srcBLen - 2] sample */ + c1 = *py--; + + /* Read x[3] sample */ + x3 = *px++; + + /* x[0] and x[1] are packed */ + in1 = (q15_t) x0; + in2 = (q15_t) x1; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* y[srcBLen - 1] and y[srcBLen - 2] are packed */ + in1 = (q15_t) c0; + in2 = (q15_t) c1; + + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc0 += x[0] * y[srcBLen - 1] + x[1] * y[srcBLen - 2] */ + acc0 = __SMLAD(input1, input2, acc0); + + /* x[1] and x[2] are packed */ + in1 = (q15_t) x1; + in2 = (q15_t) x2; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc1 += x[1] * y[srcBLen - 1] + x[2] * y[srcBLen - 2] */ + acc1 = __SMLAD(input1, input2, acc1); + + /* x[2] and x[3] are packed */ + in1 = (q15_t) x2; + in2 = (q15_t) x3; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc2 += x[2] * y[srcBLen - 1] + x[3] * y[srcBLen - 2] */ + acc2 = __SMLAD(input1, input2, acc2); + + /* Read x[4] sample */ + x0 = *px++; + + /* x[3] and x[4] are packed */ + in1 = (q15_t) x3; + in2 = (q15_t) x0; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc3 += x[3] * y[srcBLen - 1] + x[4] * y[srcBLen - 2] */ + acc3 = __SMLAD(input1, input2, acc3); + + /* Read y[srcBLen - 3] sample */ + c0 = *py--; + /* Read y[srcBLen - 4] sample */ + c1 = *py--; + + /* Read x[5] sample */ + x1 = *px++; + + /* x[2] and x[3] are packed */ + in1 = (q15_t) x2; + in2 = (q15_t) x3; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* y[srcBLen - 3] and y[srcBLen - 4] are packed */ + in1 = (q15_t) c0; + in2 = (q15_t) c1; + + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc0 += x[2] * y[srcBLen - 3] + x[3] * y[srcBLen - 4] */ + acc0 = __SMLAD(input1, input2, acc0); + + /* x[3] and x[4] are packed */ + in1 = (q15_t) x3; + in2 = (q15_t) x0; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc1 += x[3] * y[srcBLen - 3] + x[4] * y[srcBLen - 4] */ + acc1 = __SMLAD(input1, input2, acc1); + + /* x[4] and x[5] are packed */ + in1 = (q15_t) x0; + in2 = (q15_t) x1; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc2 += x[4] * y[srcBLen - 3] + x[5] * y[srcBLen - 4] */ + acc2 = __SMLAD(input1, input2, acc2); + + /* Read x[6] sample */ + x2 = *px++; + + /* x[5] and x[6] are packed */ + in1 = (q15_t) x1; + in2 = (q15_t) x2; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc3 += x[5] * y[srcBLen - 3] + x[6] * y[srcBLen - 4] */ + acc3 = __SMLAD(input1, input2, acc3); + + } while (--k); + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Read y[srcBLen - 5] sample */ + c0 = *py--; + /* Read x[7] sample */ + x3 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[4] * y[srcBLen - 5] */ + acc0 += ((q15_t) x0 * c0); + /* acc1 += x[5] * y[srcBLen - 5] */ + acc1 += ((q15_t) x1 * c0); + /* acc2 += x[6] * y[srcBLen - 5] */ + acc2 += ((q15_t) x2 * c0); + /* acc3 += x[7] * y[srcBLen - 5] */ + acc3 += ((q15_t) x3 * c0); + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(acc0 >> 7U, 8)); + *pOut++ = (q7_t) (__SSAT(acc1 >> 7U, 8)); + *pOut++ = (q7_t) (__SSAT(acc2 >> 7U, 8)); + *pOut++ = (q7_t) (__SSAT(acc3 >> 7U, 8)); + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize2 % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + while (k > 0U) + { + + /* Reading two inputs of SrcA buffer and packing */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* Reading two inputs of SrcB buffer and packing */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* Perform the multiply-accumulate */ + sum = __SMLAD(input1, input2, sum); + + /* Reading two inputs of SrcA buffer and packing */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* Reading two inputs of SrcB buffer and packing */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* Perform the multiply-accumulate */ + sum = __SMLAD(input1, input2, sum); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q15_t) *px++ * *py--); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(sum >> 7U, 8)); + + /* Increment the pointer pIn1 index, count by 1 */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q15_t) *px++ * *py--); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(sum >> 7U, 8)); + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pSrc2; + + /* Decrement loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1] + * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2] + * .... + * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2] + * sum += x[srcALen-1] * y[srcBLen-1] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The blockSize3 variable holds the number of MAC operations performed */ + + /* Working pointer of inputA */ + pSrc1 = pIn1 + (srcALen - (srcBLen - 1U)); + px = pSrc1; + + /* Working pointer of inputB */ + pSrc2 = pIn2 + (srcBLen - 1U); + py = pSrc2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = blockSize3 >> 2U; + + while (k > 0U) + { + /* Reading two inputs, x[srcALen - srcBLen + 1] and x[srcALen - srcBLen + 2] of SrcA buffer and packing */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* Reading two inputs, y[srcBLen - 1] and y[srcBLen - 2] of SrcB buffer and packing */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */ + /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */ + sum = __SMLAD(input1, input2, sum); + + /* Reading two inputs, x[srcALen - srcBLen + 3] and x[srcALen - srcBLen + 4] of SrcA buffer and packing */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* Reading two inputs, y[srcBLen - 3] and y[srcBLen - 4] of SrcB buffer and packing */ + in1 = (q15_t) *py--; + in2 = (q15_t) *py--; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */ + /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */ + sum = __SMLAD(input1, input2, sum); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = blockSize3 % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = blockSize3; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen-1] * y[srcBLen-1] */ + sum += ((q15_t) *px++ * *py--); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut++ = (q7_t) (__SSAT(sum >> 7U, 8)); + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pSrc2; + + /* Decrement loop counter */ + blockSize3--; + } + +#else +/* alternate version for CM0_FAMILY */ + + const q7_t *pIn1 = pSrcA; /* InputA pointer */ + const q7_t *pIn2 = pSrcB; /* InputB pointer */ + q31_t sum; /* Accumulator */ + uint32_t i, j; /* Loop counters */ + + /* Loop to calculate convolution for output length number of times */ + for (i = 0U; i < (srcALen + srcBLen - 1U); i++) + { + /* Initialize sum with zero to carry out MAC operations */ + sum = 0; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ((q15_t) pIn1[j] * pIn2[i - j]); + } + } + + /* Store the output in the destination buffer */ + pDst[i] = (q7_t) __SSAT((sum >> 7U), 8U); + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of Conv group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_f32.c new file mode 100644 index 0000000..4438c77 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_f32.c @@ -0,0 +1,750 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_correlate_f32.c + * Description: Correlation of floating-point sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup Corr Correlation + + Correlation is a mathematical operation that is similar to convolution. + As with convolution, correlation uses two signals to produce a third signal. + The underlying algorithms in correlation and convolution are identical except that one of the inputs is flipped in convolution. + Correlation is commonly used to measure the similarity between two signals. + It has applications in pattern recognition, cryptanalysis, and searching. + The CMSIS library provides correlation functions for Q7, Q15, Q31 and floating-point data types. + Fast versions of the Q15 and Q31 functions are also provided. + + @par Algorithm + Let a[n] and b[n] be sequences of length srcALen and srcBLen samples respectively. + The convolution of the two signals is denoted by +
+      c[n] = a[n] * b[n]
+  
+ In correlation, one of the signals is flipped in time +
+       c[n] = a[n] * b[-n]
+  
+ @par + and this is mathematically defined as + \image html CorrelateEquation.gif + @par + The pSrcA points to the first input vector of length srcALen and pSrcB points to the second input vector of length srcBLen. + The result c[n] is of length 2 * max(srcALen, srcBLen) - 1 and is defined over the interval n=0, 1, 2, ..., (2 * max(srcALen, srcBLen) - 2). + The output result is written to pDst and the calling function must allocate 2 * max(srcALen, srcBLen) - 1 words for the result. + + @note + The pDst should be initialized to all zeros before being used. + + @par Fixed-Point Behavior + Correlation requires summing up a large number of intermediate products. + As such, the Q7, Q15, and Q31 functions run a risk of overflow and saturation. + Refer to the function specific documentation below for further details of the particular algorithm used. + + @par Fast Versions + Fast versions are supported for Q31 and Q15. Cycles for Fast versions are less compared to Q31 and Q15 of correlate and the design requires + the input signals should be scaled down to avoid intermediate overflows. + + @par Opt Versions + Opt versions are supported for Q15 and Q7. Design uses internal scratch buffer for getting good optimisation. + These versions are optimised in cycles and consumes more memory (Scratch memory) compared to Q15 and Q7 versions of correlate + */ + +/** + @addtogroup Corr + @{ + */ + +/** + @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 location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + */ + +void arm_correlate_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst) +{ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + const float32_t *pIn1; /* InputA pointer */ + const float32_t *pIn2; /* InputB pointer */ + float32_t *pOut = pDst; /* Output pointer */ + const float32_t *px; /* Intermediate inputA pointer */ + const float32_t *py; /* Intermediate inputB pointer */ + const float32_t *pSrc1; /* Intermediate pointers */ + float32_t sum; /* Accumulators */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + uint32_t outBlockSize; /* Loop counter */ + int32_t inc = 1; /* Destination address modifier */ + +#if defined (ARM_MATH_LOOPUNROLL) + float32_t acc0, acc1, acc2, acc3; /* Accumulators */ + float32_t x0, x1, x2, x3, c0; /* Temporary variables for holding input and coefficient values */ +#endif + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and the destination pointer modifier, inc is set to -1 */ + /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */ + /* But to improve the performance, + * we assume zeroes in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, + * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */ + /* If srcALen < srcBLen, + * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + + /* Number of output samples is calculated */ + outBlockSize = (2U * srcALen) - 1U; + + /* When srcALen > srcBLen, zero padding has to be done to srcB + * to make their lengths equal. + * Instead, (outBlockSize - (srcALen + srcBLen - 1)) + * number of output samples are made zero */ + j = outBlockSize - (srcALen + (srcBLen - 1U)); + + /* Updating the pointer position to non zero value */ + pOut += j; + + //while (j > 0U) + //{ + // /* Zero is stored in the destination buffer */ + // *pOut++ = 0.0f; + + // /* Decrement the loop counter */ + // j--; + //} + + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + + /* CORR(x, y) = Reverse order(CORR(y, x)) */ + /* Hence set the destination pointer to point to the last output sample */ + pOut = pDst + ((srcALen + srcBLen) - 2U); + + /* Destination address modifier is set to -1 */ + inc = -1; + + } + + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[srcBlen - 1] + * sum = x[0] * y[srcBlen-2] + x[1] * y[srcBlen - 1] + * .... + * sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen - 1] * y[srcBLen - 1] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc1 = pIn2 + (srcBLen - 1U); + py = pSrc1; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[0] * y[srcBLen - 4] */ + sum += *px++ * *py++; + + /* x[1] * y[srcBLen - 3] */ + sum += *px++ * *py++; + + /* x[2] * y[srcBLen - 2] */ + sum += *px++ * *py++; + + /* x[3] * y[srcBLen - 1] */ + sum += *px++ * *py++; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* x[0] * y[srcBLen - 1] */ + sum += *px++ * *py++; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = sum; + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pSrc1 - count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen-1] * y[srcBLen-1] + * sum = x[1] * y[0] + x[2] * y[1] +...+ x[srcBLen] * y[srcBLen-1] + * .... + * sum = x[srcALen-srcBLen-2] * y[0] + x[srcALen-srcBLen-1] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize2 >> 2U; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0.0f; + acc1 = 0.0f; + acc2 = 0.0f; + acc3 = 0.0f; + + /* read x[0], x[1], x[2] samples */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read y[0] sample */ + c0 = *(py++); + /* Read x[3] sample */ + x3 = *(px++); + + /* Perform the multiply-accumulate */ + /* acc0 += x[0] * y[0] */ + acc0 += x0 * c0; + /* acc1 += x[1] * y[0] */ + acc1 += x1 * c0; + /* acc2 += x[2] * y[0] */ + acc2 += x2 * c0; + /* acc3 += x[3] * y[0] */ + acc3 += x3 * c0; + + /* Read y[1] sample */ + c0 = *(py++); + /* Read x[4] sample */ + x0 = *(px++); + + /* Perform the multiply-accumulate */ + /* acc0 += x[1] * y[1] */ + acc0 += x1 * c0; + /* acc1 += x[2] * y[1] */ + acc1 += x2 * c0; + /* acc2 += x[3] * y[1] */ + acc2 += x3 * c0; + /* acc3 += x[4] * y[1] */ + acc3 += x0 * c0; + + /* Read y[2] sample */ + c0 = *(py++); + /* Read x[5] sample */ + x1 = *(px++); + + /* Perform the multiply-accumulate */ + /* acc0 += x[2] * y[2] */ + acc0 += x2 * c0; + /* acc1 += x[3] * y[2] */ + acc1 += x3 * c0; + /* acc2 += x[4] * y[2] */ + acc2 += x0 * c0; + /* acc3 += x[5] * y[2] */ + acc3 += x1 * c0; + + /* Read y[3] sample */ + c0 = *(py++); + /* Read x[6] sample */ + x2 = *(px++); + + /* Perform the multiply-accumulate */ + /* acc0 += x[3] * y[3] */ + acc0 += x3 * c0; + /* acc1 += x[4] * y[3] */ + acc1 += x0 * c0; + /* acc2 += x[5] * y[3] */ + acc2 += x1 * c0; + /* acc3 += x[6] * y[3] */ + acc3 += x2 * c0; + + } while (--k); + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Read y[4] sample */ + c0 = *(py++); + /* Read x[7] sample */ + x3 = *(px++); + + /* Perform the multiply-accumulate */ + /* acc0 += x[4] * y[4] */ + acc0 += x0 * c0; + /* acc1 += x[5] * y[4] */ + acc1 += x1 * c0; + /* acc2 += x[6] * y[4] */ + acc2 += x2 * c0; + /* acc3 += x[7] * y[4] */ + acc3 += x3 * c0; + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = acc0; + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + *pOut = acc1; + pOut += inc; + + *pOut = acc2; + pOut += inc; + + *pOut = acc3; + pOut += inc; + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize2 % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py++; + sum += *px++ * *py++; + sum += *px++ * *py++; + sum += *px++ * *py++; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py++; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = sum; + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment the pointer pIn1 index, count by 1 */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + + /* Loop over srcBLen */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py++; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = sum; + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment the pointer pIn1 index, count by 1 */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[0] + x[srcALen-srcBLen+2] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * sum += x[srcALen-srcBLen+2] * y[0] + x[srcALen-srcBLen+3] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * .... + * sum += x[srcALen-2] * y[0] + x[srcALen-1] * y[1] + * sum += x[srcALen-1] * y[0] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = pIn1 + (srcALen - (srcBLen - 1U)); + px = pSrc1; + + /* Working pointer of inputB */ + py = pIn2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen - srcBLen + 4] * y[3] */ + sum += *px++ * *py++; + + /* sum += x[srcALen - srcBLen + 3] * y[2] */ + sum += *px++ * *py++; + + /* sum += x[srcALen - srcBLen + 2] * y[1] */ + sum += *px++ * *py++; + + /* sum += x[srcALen - srcBLen + 1] * y[0] */ + sum += *px++ * *py++; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += *px++ * *py++; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = sum; + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pIn2; + + /* Decrement MAC count */ + count--; + + /* Decrement the loop counter */ + blockSize3--; + } + +#else +/* alternate version for CM0_FAMILY */ + + const float32_t *pIn1 = pSrcA; /* inputA pointer */ + const float32_t *pIn2 = pSrcB + (srcBLen - 1U); /* inputB pointer */ + float32_t sum; /* Accumulator */ + uint32_t i = 0U, j; /* Loop counters */ + uint32_t inv = 0U; /* Reverse order flag */ + uint32_t tot = 0U; /* Length */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and a varaible, inv is set to 1 */ + /* If lengths are not equal then zero pad has to be done to make the two + * inputs of same length. But to improve the performance, we assume zeroes + * in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, (srcALen - srcBLen) zeroes has to included in the + * starting of the output buffer */ + /* If srcALen < srcBLen, (srcALen - srcBLen) zeroes has to included in the + * ending of the output buffer */ + /* Once the zero padding is done the remaining of the output is calcualted + * using convolution but with the shorter signal time shifted. */ + + /* Calculate the length of the remaining sequence */ + tot = ((srcALen + srcBLen) - 2U); + + if (srcALen > srcBLen) + { + /* Calculating the number of zeros to be padded to the output */ + j = srcALen - srcBLen; + + /* Initialise the pointer after zero padding */ + pDst += j; + } + + else if (srcALen < srcBLen) + { + /* Initialization to inputB pointer */ + pIn1 = pSrcB; + + /* Initialization to the end of inputA pointer */ + pIn2 = pSrcA + (srcALen - 1U); + + /* Initialisation of the pointer after zero padding */ + pDst = pDst + tot; + + /* Swapping the lengths */ + j = srcALen; + srcALen = srcBLen; + srcBLen = j; + + /* Setting the reverse flag */ + inv = 1; + + } + + /* Loop to calculate convolution for output length number of times */ + for (i = 0U; i <= tot; i++) + { + /* Initialize sum with zero to carry out MAC operations */ + sum = 0.0f; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if ((((i - j) < srcBLen) && (j < srcALen))) + { + /* z[i] += x[i-j] * y[j] */ + sum += pIn1[j] * pIn2[-((int32_t) i - j)]; + } + } + + /* Store the output in the destination buffer */ + if (inv == 1) + *pDst-- = sum; + else + *pDst++ = sum; + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of Corr group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_opt_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_opt_q15.c new file mode 100644 index 0000000..13661cb --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_opt_q15.c @@ -0,0 +1,345 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_correlate_fast_opt_q15.c + * Description: Fast Q15 Correlation + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Corr + @{ + */ + +/** + @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. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + @return none + + @par Scaling and Overflow Behavior + This fast version uses a 32-bit accumulator with 2.30 format. + The accumulator maintains full precision of the intermediate multiplication results but provides only a single guard bit. + There is no saturation on intermediate additions. + Thus, if the accumulator overflows it wraps around and distorts the result. + The input signals should be scaled down to avoid intermediate overflows. + Scale down one of the inputs by 1/min(srcALen, srcBLen) to avoid overflow since a + maximum of min(srcALen, srcBLen) number of additions is carried internally. + The 2.30 accumulator is right shifted by 15 bits and then saturated to 1.15 format to yield the final result. + + @remark + Refer to \ref arm_correlate_q15() for a slower implementation of this function which uses a 64-bit accumulator to avoid wrap around distortion. + */ + +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) +{ + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + q31_t acc0; /* Accumulators */ + q15_t *pOut = pDst; /* Output pointer */ + q15_t *pScr1 = pScratch; /* Temporary pointer for scratch */ + const q15_t *py; /* Intermediate inputB pointer */ + uint32_t j, blkCnt, outBlockSize; /* Loop counter */ + int32_t inc = 1; /* Destination address modifier */ + uint32_t tapCnt; /* Loop count */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc1, acc2, acc3; /* Accumulators */ + q31_t x1, x2, x3; /* Temporary variables for holding input and coefficient values */ + q31_t y1, y2; /* State variables */ +#endif + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and the destination pointer modifier, inc is set to -1 */ + /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */ + /* But to improve the performance, + * we include zeroes in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, + * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */ + /* If srcALen < srcBLen, + * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + + /* Number of output samples is calculated */ + outBlockSize = (2U * srcALen) - 1U; + + /* When srcALen > srcBLen, zero padding is done to srcB + * to make their lengths equal. + * Instead, (outBlockSize - (srcALen + srcBLen - 1)) + * number of output samples are made zero */ + j = outBlockSize - (srcALen + (srcBLen - 1U)); + + /* Updating the pointer position to non zero value */ + pOut += j; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + + /* CORR(x, y) = Reverse order(CORR(y, x)) */ + /* Hence set the destination pointer to point to the last output sample */ + pOut = pDst + ((srcALen + srcBLen) - 2U); + + /* Destination address modifier is set to -1 */ + inc = -1; + } + + pScr1 = pScratch; + + /* Fill (srcBLen - 1U) zeros in scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update temporary scratch pointer */ + pScr1 += (srcBLen - 1U); + + + /* Copy (srcALen) samples in scratch buffer */ + arm_copy_q15(pIn1, pScr1, srcALen); + + /* Update pointers */ + pScr1 += srcALen; + + + /* Fill (srcBLen - 1U) zeros at end of scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update pointer */ + pScr1 += (srcBLen - 1U); + + /* Temporary pointer for scratch2 */ + py = pIn2; + + + /* Actual correlation process starts here */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (srcALen + srcBLen - 1U) >> 2; + + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch; + + /* Clear Accumlators */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Read two samples from scratch buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read next two samples from scratch buffer */ + x2 = read_q15x2_ia (&pScr1); + + tapCnt = (srcBLen) >> 2U; + + while (tapCnt > 0U) + { + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia ((q15_t **) &pIn2); + y2 = read_q15x2_ia ((q15_t **) &pIn2); + + /* multiply and accumlate */ + acc0 = __SMLAD(x1, y1, acc0); + acc2 = __SMLAD(x2, y1, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + /* multiply and accumlate */ + acc1 = __SMLADX(x3, y1, acc1); + + /* Read next two samples from scratch buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* multiply and accumlate */ + acc0 = __SMLAD(x2, y2, acc0); + acc2 = __SMLAD(x1, y2, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x1, x2, 0); +#else + x3 = __PKHBT(x2, x1, 0); +#endif + + acc3 = __SMLADX(x3, y1, acc3); + acc1 = __SMLADX(x3, y2, acc1); + + x2 = read_q15x2_ia (&pScr1); + +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + acc3 = __SMLADX(x3, y2, acc3); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Update scratch pointer for remaining samples of smaller length sequence */ + pScr1 -= 4U; + + /* apply same above for remaining samples of smaller length sequence */ + tapCnt = (srcBLen) & 3U; + + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2); + acc1 += (*pScr1++ * *pIn2); + acc2 += (*pScr1++ * *pIn2); + acc3 += (*pScr1++ * *pIn2++); + + pScr1 -= 3U; + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the results in the accumulators in the destination buffer. */ + *pOut = (__SSAT(acc0 >> 15U, 16)); + pOut += inc; + *pOut = (__SSAT(acc1 >> 15U, 16)); + pOut += inc; + *pOut = (__SSAT(acc2 >> 15U, 16)); + pOut += inc; + *pOut = (__SSAT(acc3 >> 15U, 16)); + pOut += inc; + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch += 4U; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (srcALen + srcBLen - 1U) & 0x3; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (srcALen + srcBLen - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Calculate correlation for remaining samples of Bigger length sequence */ + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch; + + /* Clear Accumlators */ + acc0 = 0; + + tapCnt = (srcBLen) >> 1U; + + while (tapCnt > 0U) + { + + /* Read next two samples from scratch buffer */ + acc0 += (*pScr1++ * *pIn2++); + acc0 += (*pScr1++ * *pIn2++); + + /* Decrement loop counter */ + tapCnt--; + } + + tapCnt = (srcBLen) & 1U; + + /* apply same above for remaining samples of smaller length sequence */ + while (tapCnt > 0U) + { + + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2++); + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* The result is in 2.30 format. Convert to 1.15 with saturation. + ** Then store the output in the destination buffer. */ + *pOut = (q15_t) (__SSAT((acc0 >> 15), 16)); + pOut += inc; + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch += 1U; + } + +} + +/** + @} end of Corr group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_q15.c new file mode 100644 index 0000000..6898618 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_q15.c @@ -0,0 +1,614 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_correlate_fast_q15.c + * Description: Fast Q15 Correlation + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Corr + @{ + */ + +/** + @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 + + @par Scaling and Overflow Behavior + This fast version uses a 32-bit accumulator with 2.30 format. + The accumulator maintains full precision of the intermediate multiplication results but provides only a single guard bit. + There is no saturation on intermediate additions. + Thus, if the accumulator overflows it wraps around and distorts the result. + The input signals should be scaled down to avoid intermediate overflows. + Scale down one of the inputs by 1/min(srcALen, srcBLen) to avoid overflow since a + maximum of min(srcALen, srcBLen) number of additions is carried internally. + The 2.30 accumulator is right shifted by 15 bits and then saturated to 1.15 format to yield the final result. + + @remark + Refer to \ref arm_correlate_q15() for a slower implementation of this function which uses a 64-bit accumulator to avoid wrap around distortion. + */ + +void arm_correlate_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst) +{ + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + q15_t *pOut = pDst; /* Output pointer */ + q31_t sum, acc0, acc1, acc2, acc3; /* Accumulators */ + const q15_t *px; /* Intermediate inputA pointer */ + const q15_t *py; /* Intermediate inputB pointer */ + const q15_t *pSrc1; /* Intermediate pointers */ + q31_t x0, x1, x2, x3, c0; /* Temporary variables for holding input and coefficient values */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + uint32_t outBlockSize; + int32_t inc = 1; /* Destination address modifier */ + + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and the destination pointer modifier, inc is set to -1 */ + /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */ + /* But to improve the performance, + * we include zeroes in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, + * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */ + /* If srcALen < srcBLen, + * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + + /* Number of output samples is calculated */ + outBlockSize = (2U * srcALen) - 1U; + + /* When srcALen > srcBLen, zero padding is done to srcB + * to make their lengths equal. + * Instead, (outBlockSize - (srcALen + srcBLen - 1)) + * number of output samples are made zero */ + j = outBlockSize - (srcALen + (srcBLen - 1U)); + + /* Updating the pointer position to non zero value */ + pOut += j; + + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + + /* CORR(x, y) = Reverse order(CORR(y, x)) */ + /* Hence set the destination pointer to point to the last output sample */ + pOut = pDst + ((srcALen + srcBLen) - 2U); + + /* Destination address modifier is set to -1 */ + inc = -1; + + } + + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[srcBlen - 1] + * sum = x[0] * y[srcBlen - 2] + x[1] * y[srcBlen - 1] + * .... + * sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen - 1] * y[srcBLen - 1] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc1 = pIn2 + (srcBLen - 1U); + py = pSrc1; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first loop starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* x[0] * y[srcBLen - 4] , x[1] * y[srcBLen - 3] */ + sum = __SMLAD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); + /* x[3] * y[srcBLen - 1] , x[2] * y[srcBLen - 2] */ + sum = __SMLAD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, compute any remaining MACs here. + No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + /* x[0] * y[srcBLen - 1] */ + sum = __SMLAD(*px++, *py++, sum); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q15_t) (sum >> 15); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pSrc1 - count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen-1] * y[srcBLen-1] + * sum = x[1] * y[0] + x[2] * y[1] +...+ x[srcBLen] * y[srcBLen-1] + * .... + * sum = x[srcALen-srcBLen-2] * y[0] + x[srcALen-srcBLen-1] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + /* count is the index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* -------------------- + * Stage2 process + * -------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { + /* Loop unroll over blockSize2, by 4 */ + blkCnt = blockSize2 >> 2U; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* read x[0], x[1] samples */ + x0 = read_q15x2 ((q15_t *) px); + /* read x[1], x[2] samples */ + x1 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read the first two inputB samples using SIMD: + * y[0] and y[1] */ + c0 = read_q15x2_ia ((q15_t **) &py); + + /* acc0 += x[0] * y[0] + x[1] * y[1] */ + acc0 = __SMLAD(x0, c0, acc0); + + /* acc1 += x[1] * y[0] + x[2] * y[1] */ + acc1 = __SMLAD(x1, c0, acc1); + + /* Read x[2], x[3] */ + x2 = read_q15x2 ((q15_t *) px); + + /* Read x[3], x[4] */ + x3 = read_q15x2 ((q15_t *) px + 1); + + /* acc2 += x[2] * y[0] + x[3] * y[1] */ + acc2 = __SMLAD(x2, c0, acc2); + + /* acc3 += x[3] * y[0] + x[4] * y[1] */ + acc3 = __SMLAD(x3, c0, acc3); + + /* Read y[2] and y[3] */ + c0 = read_q15x2_ia ((q15_t **) &py); + + /* acc0 += x[2] * y[2] + x[3] * y[3] */ + acc0 = __SMLAD(x2, c0, acc0); + + /* acc1 += x[3] * y[2] + x[4] * y[3] */ + acc1 = __SMLAD(x3, c0, acc1); + + /* Read x[4], x[5] */ + x0 = read_q15x2 ((q15_t *) px + 2); + + /* Read x[5], x[6] */ + x1 = read_q15x2 ((q15_t *) px + 3); + px += 4U; + + /* acc2 += x[4] * y[2] + x[5] * y[3] */ + acc2 = __SMLAD(x0, c0, acc2); + + /* acc3 += x[5] * y[2] + x[6] * y[3] */ + acc3 = __SMLAD(x1, c0, acc3); + + } while (--k); + + /* For the next MAC operations, SIMD is not used + * So, the 16 bit pointer if inputB, py is updated */ + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + if (k == 1U) + { + /* Read y[4] */ + c0 = *py; + +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[7] */ + x3 = read_q15x2 ((q15_t *) px); + px++; + + /* Perform the multiply-accumulates */ + acc0 = __SMLAD (x0, c0, acc0); + acc1 = __SMLAD (x1, c0, acc1); + acc2 = __SMLADX(x1, c0, acc2); + acc3 = __SMLADX(x3, c0, acc3); + } + + if (k == 2U) + { + /* Read y[4], y[5] */ + c0 = read_q15x2 ((q15_t *) py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + /* Perform the multiply-accumulates */ + acc0 = __SMLAD(x0, c0, acc0); + acc1 = __SMLAD(x1, c0, acc1); + acc2 = __SMLAD(x3, c0, acc2); + acc3 = __SMLAD(x2, c0, acc3); + } + + if (k == 3U) + { + /* Read y[4], y[5] */ + c0 = read_q15x2_ia ((q15_t **) &py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + + /* Perform the multiply-accumulates */ + acc0 = __SMLAD(x0, c0, acc0); + acc1 = __SMLAD(x1, c0, acc1); + acc2 = __SMLAD(x3, c0, acc2); + acc3 = __SMLAD(x2, c0, acc3); + + c0 = (*py); + /* Read y[6] */ +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[10] */ + x3 = read_q15x2 ((q15_t *) px + 2); + px += 3U; + + /* Perform the multiply-accumulates */ + acc0 = __SMLADX(x1, c0, acc0); + acc1 = __SMLAD (x2, c0, acc1); + acc2 = __SMLADX(x2, c0, acc2); + acc3 = __SMLADX(x3, c0, acc3); + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q15_t) (acc0 >> 15); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + *pOut = (q15_t) (acc1 >> 15); + pOut += inc; + + *pOut = (q15_t) (acc2 >> 15); + pOut += inc; + + *pOut = (q15_t) (acc3 >> 15); + pOut += inc; + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize2 % 0x4U; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += ((q31_t) *px++ * *py++); + sum += ((q31_t) *px++ * *py++); + sum += ((q31_t) *px++ * *py++); + sum += ((q31_t) *px++ * *py++); + + /* Decrement loop counter */ + k--; + } + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += ((q31_t) * px++ * *py++); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q15_t) (sum >> 15); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment the pointer pIn1 index, count by 1 */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q31_t) *px++ * *py++); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q15_t) (sum >> 15); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + } + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[0] + x[srcALen-srcBLen+2] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * sum += x[srcALen-srcBLen+2] * y[0] + x[srcALen-srcBLen+3] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * .... + * sum += x[srcALen-2] * y[0] + x[srcALen-1] * y[1] + * sum += x[srcALen-1] * y[0] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + py = pIn2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulates */ + /* sum += x[srcALen - srcBLen + 4] * y[3] , sum += x[srcALen - srcBLen + 3] * y[2] */ + sum = __SMLAD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); + /* sum += x[srcALen - srcBLen + 2] * y[1] , sum += x[srcALen - srcBLen + 1] * y[0] */ + sum = __SMLAD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = __SMLAD(*px++, *py++, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q15_t) (sum >> 15); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pIn2; + + /* Decrement the MAC count */ + count--; + + /* Decrement the loop counter */ + blockSize3--; + } + +} + +/** + @} end of Corr group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_q31.c new file mode 100644 index 0000000..a5840b7 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_fast_q31.c @@ -0,0 +1,601 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_correlate_fast_q31.c + * Description: Fast Q31 Correlation + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Corr + @{ + */ + +/** + @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 location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + + @par Scaling and Overflow Behavior + This function is optimized for speed at the expense of fixed-point precision and overflow protection. + The result of each 1.31 x 1.31 multiplication is truncated to 2.30 format. + These intermediate results are accumulated in a 32-bit register in 2.30 format. + Finally, the accumulator is saturated and converted to a 1.31 result. + @par + The fast version has the same overflow behavior as the standard version but provides less precision since it discards the low 32 bits of each multiplication result. + In order to avoid overflows completely the input signals must be scaled down. + The input signals should be scaled down to avoid intermediate overflows. + Scale down one of the inputs by 1/min(srcALen, srcBLen)to avoid overflows since a + maximum of min(srcALen, srcBLen) number of additions is carried internally. + + @remark + Refer to \ref arm_correlate_q31() for a slower implementation of this function which uses 64-bit accumulation to provide higher precision. + */ + +void arm_correlate_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst) +{ + const q31_t *pIn1; /* InputA pointer */ + const q31_t *pIn2; /* InputB pointer */ + q31_t *pOut = pDst; /* Output pointer */ + const q31_t *px; /* Intermediate inputA pointer */ + const q31_t *py; /* Intermediate inputB pointer */ + const q31_t *pSrc1; /* Intermediate pointers */ + q31_t sum, acc0, acc1, acc2, acc3; /* Accumulators */ + q31_t x0, x1, x2, x3, c0; /* Temporary variables for holding input and coefficient values */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + uint32_t outBlockSize; + int32_t inc = 1; /* Destination address modifier */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + + /* Number of output samples is calculated */ + outBlockSize = (2U * srcALen) - 1U; + + /* When srcALen > srcBLen, zero padding is done to srcB + * to make their lengths equal. + * Instead, (outBlockSize - (srcALen + srcBLen - 1)) + * number of output samples are made zero */ + j = outBlockSize - (srcALen + (srcBLen - 1U)); + + /* Updating the pointer position to non zero value */ + pOut += j; + + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + + /* CORR(x, y) = Reverse order(CORR(y, x)) */ + /* Hence set the destination pointer to point to the last output sample */ + pOut = pDst + ((srcALen + srcBLen) - 2U); + + /* Destination address modifier is set to -1 */ + inc = -1; + + } + + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[srcBlen - 1] + * sum = x[0] * y[srcBlen - 2] + x[1] * y[srcBlen - 1] + * .... + * sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen - 1] * y[srcBLen - 1] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc1 = pIn2 + (srcBLen - 1U); + py = pSrc1; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* x[0] * y[srcBLen - 4] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* x[1] * y[srcBLen - 3] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* x[2] * y[srcBLen - 2] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* x[3] * y[srcBLen - 1] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* x[0] * y[srcBLen - 1] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = sum << 1; + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pSrc1 - count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen-1] * y[srcBLen-1] + * sum = x[1] * y[0] + x[2] * y[1] +...+ x[srcBLen] * y[srcBLen-1] + * .... + * sum = x[srcALen-srcBLen-2] * y[0] + x[srcALen-srcBLen-1] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { + /* Loop unroll over blockSize2, by 4 */ + blkCnt = blockSize2 >> 2U; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* read x[0], x[1], x[2] samples */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read y[0] sample */ + c0 = *py++; + /* Read x[3] sample */ + x3 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[0] * y[0] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc1 += x[1] * y[0] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc2 += x[2] * y[0] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc3 += x[3] * y[0] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + + /* Read y[1] sample */ + c0 = *py++; + /* Read x[4] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + /* acc0 += x[1] * y[1] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc1 += x[2] * y[1] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc2 += x[3] * y[1] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x3 * c0)) >> 32); + /* acc3 += x[4] * y[1] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x0 * c0)) >> 32); + + + /* Read y[2] sample */ + c0 = *py++; + /* Read x[5] sample */ + x1 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[2] * y[2] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc1 += x[3] * y[2] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x3 * c0)) >> 32); + /* acc2 += x[4] * y[2] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc3 += x[5] * y[2] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x1 * c0)) >> 32); + + + /* Read y[3] sample */ + c0 = *py++; + /* Read x[6] sample */ + x2 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[3] * y[3] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x3 * c0)) >> 32); + /* acc1 += x[4] * y[3] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc2 += x[5] * y[3] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc3 += x[6] * y[3] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x2 * c0)) >> 32); + + + } while (--k); + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Read y[4] sample */ + c0 = *py++; + /* Read x[7] sample */ + x3 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[4] * y[4] */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + /* acc1 += x[5] * y[4] */ + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + /* acc2 += x[6] * y[4] */ + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + /* acc3 += x[7] * y[4] */ + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q31_t) (acc0 << 1); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + *pOut = (q31_t) (acc1 << 1); + pOut += inc; + + *pOut = (q31_t) (acc2 << 1); + pOut += inc; + + *pOut = (q31_t) (acc3 << 1); + pOut += inc; + + /* Increment the pointer pIn1 index, count by 4 */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize2 % 0x4U; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = sum << 1; + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = sum << 1; + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[0] + x[srcALen-srcBLen+2] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * sum += x[srcALen-srcBLen+2] * y[0] + x[srcALen-srcBLen+3] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * .... + * sum += x[srcALen-2] * y[0] + x[srcALen-1] * y[1] + * sum += x[srcALen-1] * y[0] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = ((pIn1 + srcALen) - srcBLen) + 1U; + px = pSrc1; + + /* Working pointer of inputB */ + py = pIn2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen - srcBLen + 4] * y[3] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* sum += x[srcALen - srcBLen + 3] * y[2] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* sum += x[srcALen - srcBLen + 2] * y[1] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* sum += x[srcALen - srcBLen + 1] * y[0] */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = (q31_t) ((((q63_t) sum << 32) + + ((q63_t) *px++ * (*py++))) >> 32); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = sum << 1; + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pIn2; + + /* Decrement MAC count */ + count--; + + /* Decrement loop counter */ + blockSize3--; + } + +} + +/** + @} end of Corr group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_opt_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_opt_q15.c new file mode 100644 index 0000000..d46d9a0 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_opt_q15.c @@ -0,0 +1,341 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_correlate_opt_q15.c + * Description: Correlation of Q15 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Corr + @{ + */ + +/** + @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 location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both inputs are 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. + This approach provides 33 guard bits and there is no risk of overflow. + The 34.30 result is then truncated to 34.15 format by discarding the low 15 bits and then saturated to 1.15 format. + + @remark + Refer to \ref arm_correlate_fast_q15() for a faster but less precise version of this function. + */ + +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) +{ + q63_t acc0; /* Accumulators */ + q15_t *pOut = pDst; /* Output pointer */ + q15_t *pScr1; /* Temporary pointer for scratch1 */ + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + const q15_t *py; /* Intermediate inputB pointer */ + uint32_t j, blkCnt, outBlockSize; /* Loop counter */ + int32_t inc = 1; /* Output pointer increment */ + uint32_t tapCnt; + +#if defined (ARM_MATH_LOOPUNROLL) + q63_t acc1, acc2, acc3; /* Accumulators */ + q31_t x1, x2, x3; /* Temporary variables for holding input1 and input2 values */ + q31_t y1, y2; /* State variables */ +#endif + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and the destination pointer modifier, inc is set to -1 */ + /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */ + /* But to improve the performance, + * we include zeroes in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, + * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */ + /* If srcALen < srcBLen, + * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + + /* Number of output samples is calculated */ + outBlockSize = (srcALen * 2U) - 1U; + + /* When srcALen > srcBLen, zero padding is done to srcB + * to make their lengths equal. + * Instead, (outBlockSize - (srcALen + srcBLen - 1)) + * number of output samples are made zero */ + j = outBlockSize - (srcALen + (srcBLen - 1U)); + + /* Updating the pointer position to non zero value */ + pOut += j; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + + /* CORR(x, y) = Reverse order(CORR(y, x)) */ + /* Hence set the destination pointer to point to the last output sample */ + pOut = pDst + ((srcALen + srcBLen) - 2U); + + /* Destination address modifier is set to -1 */ + inc = -1; + } + + pScr1 = pScratch; + + /* Fill (srcBLen - 1U) zeros in scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update temporary scratch pointer */ + pScr1 += (srcBLen - 1U); + + /* Copy (srcALen) samples in scratch buffer */ + arm_copy_q15(pIn1, pScr1, srcALen); + + /* Update pointers */ + pScr1 += srcALen; + + + /* Fill (srcBLen - 1U) zeros at end of scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update pointer */ + pScr1 += (srcBLen - 1U); + + /* Temporary pointer for scratch2 */ + py = pIn2; + + + /* Actual correlation process starts here */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (srcALen + srcBLen - 1U) >> 2; + + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch; + + /* Clear Accumlators */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Read two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read next two samples from scratch1 buffer */ + x2 = read_q15x2_ia (&pScr1); + + tapCnt = (srcBLen) >> 2U; + + while (tapCnt > 0U) + { + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia ((q15_t **) &pIn2); + y2 = read_q15x2_ia ((q15_t **) &pIn2); + + /* multiply and accumlate */ + acc0 = __SMLALD(x1, y1, acc0); + acc2 = __SMLALD(x2, y1, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + /* multiply and accumlate */ + acc1 = __SMLALDX(x3, y1, acc1); + + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* multiply and accumlate */ + acc0 = __SMLALD(x2, y2, acc0); + acc2 = __SMLALD(x1, y2, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x1, x2, 0); +#else + x3 = __PKHBT(x2, x1, 0); +#endif + + acc3 = __SMLALDX(x3, y1, acc3); + acc1 = __SMLALDX(x3, y2, acc1); + + x2 = read_q15x2_ia (&pScr1); + +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + acc3 = __SMLALDX(x3, y2, acc3); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Update scratch pointer for remaining samples of smaller length sequence */ + pScr1 -= 4U; + + /* apply same above for remaining samples of smaller length sequence */ + tapCnt = (srcBLen) & 3U; + + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2); + acc1 += (*pScr1++ * *pIn2); + acc2 += (*pScr1++ * *pIn2); + acc3 += (*pScr1++ * *pIn2++); + + pScr1 -= 3U; + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + + /* Store the results in the accumulators in the destination buffer. */ + *pOut = (__SSAT(acc0 >> 15U, 16)); + pOut += inc; + *pOut = (__SSAT(acc1 >> 15U, 16)); + pOut += inc; + *pOut = (__SSAT(acc2 >> 15U, 16)); + pOut += inc; + *pOut = (__SSAT(acc3 >> 15U, 16)); + pOut += inc; + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch += 4U; + } + + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (srcALen + srcBLen - 1U) & 0x3; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (srcALen + srcBLen - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Calculate correlation for remaining samples of Bigger length sequence */ + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch; + + /* Clear Accumlators */ + acc0 = 0; + + tapCnt = (srcBLen) >> 1U; + + while (tapCnt > 0U) + { + + /* Read next two samples from scratch1 buffer */ + acc0 += (*pScr1++ * *pIn2++); + acc0 += (*pScr1++ * *pIn2++); + + /* Decrement loop counter */ + tapCnt--; + } + + tapCnt = (srcBLen) & 1U; + + /* apply same above for remaining samples of smaller length sequence */ + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pIn2++); + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* The result is in 2.30 format. Convert to 1.15 with saturation. + Then store the output in the destination buffer. */ + *pOut = (q15_t) (__SSAT((acc0 >> 15), 16)); + pOut += inc; + + /* Initialization of inputB pointer */ + pIn2 = py; + + pScratch += 1U; + } + +} + +/** + @} end of Corr group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_opt_q7.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_opt_q7.c new file mode 100644 index 0000000..035bfba --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_opt_q7.c @@ -0,0 +1,388 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_correlate_opt_q7.c + * Description: Correlation of Q7 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Corr + @{ + */ + +/** + @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 location where the output result is written. 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). + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 32-bit internal accumulator. + Both the inputs are represented in 1.7 format and multiplications yield a 2.14 result. + The 2.14 intermediate results are accumulated in a 32-bit accumulator in 18.14 format. + This approach provides 17 guard bits and there is no risk of overflow as long as max(srcALen, srcBLen)<131072. + The 18.14 result is then truncated to 18.7 format by discarding the low 7 bits and then saturated to 1.7 format. + */ + +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) +{ + q15_t *pScr1 = pScratch1; /* Temporary pointer for scratch */ + q15_t *pScr2 = pScratch2; /* Temporary pointer for scratch */ + q15_t x4; /* Temporary input variable */ + q15_t *py; /* Temporary input2 pointer */ + q31_t acc0, acc1, acc2, acc3; /* Accumulators */ + const q7_t *pIn1, *pIn2; /* InputA and inputB pointer */ + uint32_t j, k, blkCnt, tapCnt; /* Loop counter */ + int32_t inc = 1; /* Output pointer increment */ + uint32_t outBlockSize; /* Loop counter */ + q31_t x1, x2, x3, y1; /* Temporary input variables */ + q7_t *pOut = pDst; /* Output pointer */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and the destination pointer modifier, inc is set to -1 */ + /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */ + /* But to improve the performance, + * we include zeroes in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, + * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */ + /* If srcALen < srcBLen, + * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + + /* Number of output samples is calculated */ + outBlockSize = (srcALen * 2U) - 1U; + + /* When srcALen > srcBLen, zero padding is done to srcB + * to make their lengths equal. + * Instead, (outBlockSize - (srcALen + srcBLen - 1)) + * number of output samples are made zero */ + j = outBlockSize - (srcALen + (srcBLen - 1U)); + + /* Updating the pointer position to non zero value */ + pOut += j; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + + /* CORR(x, y) = Reverse order(CORR(y, x)) */ + /* Hence set the destination pointer to point to the last output sample */ + pOut = pDst + ((srcALen + srcBLen) - 2U); + + /* Destination address modifier is set to -1 */ + inc = -1; + } + + + /* Copy (srcBLen) samples in scratch buffer */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling copies 4 data points at a time. + a second loop below copies for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* copy second buffer in reversal manner */ + x4 = (q15_t) *pIn2++; + *pScr2++ = x4; + x4 = (q15_t) *pIn2++; + *pScr2++ = x4; + x4 = (q15_t) *pIn2++; + *pScr2++ = x4; + x4 = (q15_t) *pIn2++; + *pScr2++ = x4; + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, copy remaining samples here. + No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* copy second buffer in reversal manner for remaining samples */ + x4 = (q15_t) *pIn2++; + *pScr2++ = x4; + + /* Decrement loop counter */ + k--; + } + + /* Fill (srcBLen - 1U) zeros in scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update temporary scratch pointer */ + pScr1 += (srcBLen - 1U); + + /* Copy (srcALen) samples in scratch buffer */ + /* Apply loop unrolling and do 4 Copies simultaneously. */ + k = srcALen >> 2U; + + /* First part of the processing with loop unrolling copies 4 data points at a time. + a second loop below copies for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* copy second buffer in reversal manner */ + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + x4 = (q15_t) *pIn1++; + *pScr1++ = x4; + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, copy remaining samples here. + No loop unrolling is used. */ + k = srcALen % 0x4U; + + while (k > 0U) + { + /* copy second buffer in reversal manner for remaining samples */ + x4 = (q15_t) * pIn1++; + *pScr1++ = x4; + + /* Decrement the loop counter */ + k--; + } + + /* Fill (srcBLen - 1U) zeros at end of scratch buffer */ + arm_fill_q15(0, pScr1, (srcBLen - 1U)); + + /* Update pointer */ + pScr1 += (srcBLen - 1U); + + /* Temporary pointer for scratch2 */ + py = pScratch2; + + /* Initialization of pScr2 pointer */ + pScr2 = pScratch2; + + /* Actual correlation process starts here */ + blkCnt = (srcALen + srcBLen - 1U) >> 2; + + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Read two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* Read next two samples from scratch1 buffer */ + x2 = read_q15x2_ia (&pScr1); + + tapCnt = (srcBLen) >> 2U; + + while (tapCnt > 0U) + { + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia (&pScr2); + + /* multiply and accumlate */ + acc0 = __SMLAD(x1, y1, acc0); + acc2 = __SMLAD(x2, y1, acc2); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + /* multiply and accumlate */ + acc1 = __SMLADX(x3, y1, acc1); + + /* Read next two samples from scratch1 buffer */ + x1 = read_q15x2_ia (&pScr1); + + /* pack input data */ +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x1, x2, 0); +#else + x3 = __PKHBT(x2, x1, 0); +#endif + + acc3 = __SMLADX(x3, y1, acc3); + + /* Read four samples from smaller buffer */ + y1 = read_q15x2_ia (&pScr2); + + acc0 = __SMLAD(x2, y1, acc0); + + acc2 = __SMLAD(x1, y1, acc2); + + acc1 = __SMLADX(x3, y1, acc1); + + x2 = read_q15x2_ia (&pScr1); + +#ifndef ARM_MATH_BIG_ENDIAN + x3 = __PKHBT(x2, x1, 0); +#else + x3 = __PKHBT(x1, x2, 0); +#endif + + acc3 = __SMLADX(x3, y1, acc3); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Update scratch pointer for remaining samples of smaller length sequence */ + pScr1 -= 4U; + + /* apply same above for remaining samples of smaller length sequence */ + tapCnt = (srcBLen) & 3U; + + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pScr2); + acc1 += (*pScr1++ * *pScr2); + acc2 += (*pScr1++ * *pScr2); + acc3 += (*pScr1++ * *pScr2++); + + pScr1 -= 3U; + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q7_t) (__SSAT(acc0 >> 7U, 8)); + pOut += inc; + *pOut = (q7_t) (__SSAT(acc1 >> 7U, 8)); + pOut += inc; + *pOut = (q7_t) (__SSAT(acc2 >> 7U, 8)); + pOut += inc; + *pOut = (q7_t) (__SSAT(acc3 >> 7U, 8)); + pOut += inc; + + /* Initialization of inputB pointer */ + pScr2 = py; + + pScratch1 += 4U; + } + + blkCnt = (srcALen + srcBLen - 1U) & 0x3; + + /* Calculate correlation for remaining samples of Bigger length sequence */ + while (blkCnt > 0) + { + /* Initialze temporary scratch pointer as scratch1 */ + pScr1 = pScratch1; + + /* Clear Accumlators */ + acc0 = 0; + + tapCnt = (srcBLen) >> 1U; + + while (tapCnt > 0U) + { + acc0 += (*pScr1++ * *pScr2++); + acc0 += (*pScr1++ * *pScr2++); + + /* Decrement loop counter */ + tapCnt--; + } + + tapCnt = (srcBLen) & 1U; + + /* apply same above for remaining samples of smaller length sequence */ + while (tapCnt > 0U) + { + /* accumlate the results */ + acc0 += (*pScr1++ * *pScr2++); + + /* Decrement loop counter */ + tapCnt--; + } + + blkCnt--; + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q7_t) (__SSAT(acc0 >> 7U, 8)); + pOut += inc; + + /* Initialization of inputB pointer */ + pScr2 = py; + + pScratch1 += 1U; + } + +} + +/** + @} end of Corr group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q15.c new file mode 100644 index 0000000..9837875 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q15.c @@ -0,0 +1,696 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_correlate_q15.c + * Description: Correlation of Q15 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Corr + @{ + */ + +/** + @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 location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both inputs are 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. + This approach provides 33 guard bits and there is no risk of overflow. + The 34.30 result is then truncated to 34.15 format by discarding the low 15 bits and then saturated to 1.15 format. + + @remark + Refer to \ref arm_correlate_fast_q15() for a faster but less precise version of this function. + @remark + Refer to \ref arm_correlate_opt_q15() for a faster implementation of this function using scratch buffers. + */ + +void arm_correlate_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst) +{ + +#if defined (ARM_MATH_DSP) + + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + q15_t *pOut = pDst; /* Output pointer */ + q63_t sum, acc0, acc1, acc2, acc3; /* Accumulators */ + const q15_t *px; /* Intermediate inputA pointer */ + const q15_t *py; /* Intermediate inputB pointer */ + const q15_t *pSrc1; /* Intermediate pointers */ + q31_t x0, x1, x2, x3, c0; /* Temporary input variables for holding input and coefficient values */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + uint32_t outBlockSize; + int32_t inc = 1; /* Destination address modifier */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and the destination pointer modifier, inc is set to -1 */ + /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */ + /* But to improve the performance, + * we include zeroes in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, + * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */ + /* If srcALen < srcBLen, + * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + + /* Number of output samples is calculated */ + outBlockSize = (srcALen * 2U) - 1U; + + /* When srcALen > srcBLen, zero padding is done to srcB + * to make their lengths equal. + * Instead, (outBlockSize - (srcALen + srcBLen - 1)) + * number of output samples are made zero */ + j = outBlockSize - (srcALen + (srcBLen - 1U)); + + /* Updating the pointer position to non zero value */ + pOut += j; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + + /* CORR(x, y) = Reverse order(CORR(y, x)) */ + /* Hence set the destination pointer to point to the last output sample */ + pOut = pDst + ((srcALen + srcBLen) - 2U); + + /* Destination address modifier is set to -1 */ + inc = -1; + } + + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[srcBlen - 1] + * sum = x[0] * y[srcBlen - 2] + x[1] * y[srcBlen - 1] + * .... + * sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen - 1] * y[srcBLen - 1] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc1 = pIn2 + (srcBLen - 1U); + py = pSrc1; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first loop starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* x[0] * y[srcBLen - 4] , x[1] * y[srcBLen - 3] */ + sum = __SMLALD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); + /* x[3] * y[srcBLen - 1] , x[2] * y[srcBLen - 2] */ + sum = __SMLALD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* x[0] * y[srcBLen - 1] */ + sum = __SMLALD(*px++, *py++, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q15_t) (__SSAT((sum >> 15), 16)); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pSrc1 - count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen-1] * y[srcBLen-1] + * sum = x[1] * y[0] + x[2] * y[1] +...+ x[srcBLen] * y[srcBLen-1] + * .... + * sum = x[srcALen-srcBLen-2] * y[0] + x[srcALen-srcBLen-1] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + /* count is the index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize2 >> 2U; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* read x[0], x[1] samples */ + x0 = read_q15x2 ((q15_t *) px); + + /* read x[1], x[2] samples */ + x1 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read the first two inputB samples using SIMD: + * y[0] and y[1] */ + c0 = read_q15x2_ia ((q15_t **) &py); + + /* acc0 += x[0] * y[0] + x[1] * y[1] */ + acc0 = __SMLALD(x0, c0, acc0); + + /* acc1 += x[1] * y[0] + x[2] * y[1] */ + acc1 = __SMLALD(x1, c0, acc1); + + /* Read x[2], x[3] */ + x2 = read_q15x2 ((q15_t *) px); + + /* Read x[3], x[4] */ + x3 = read_q15x2 ((q15_t *) px + 1); + + /* acc2 += x[2] * y[0] + x[3] * y[1] */ + acc2 = __SMLALD(x2, c0, acc2); + + /* acc3 += x[3] * y[0] + x[4] * y[1] */ + acc3 = __SMLALD(x3, c0, acc3); + + /* Read y[2] and y[3] */ + c0 = read_q15x2_ia ((q15_t **) &py); + + /* acc0 += x[2] * y[2] + x[3] * y[3] */ + acc0 = __SMLALD(x2, c0, acc0); + + /* acc1 += x[3] * y[2] + x[4] * y[3] */ + acc1 = __SMLALD(x3, c0, acc1); + + /* Read x[4], x[5] */ + x0 = read_q15x2 ((q15_t *) px + 2); + + /* Read x[5], x[6] */ + x1 = read_q15x2 ((q15_t *) px + 3); + px += 4U; + + /* acc2 += x[4] * y[2] + x[5] * y[3] */ + acc2 = __SMLALD(x0, c0, acc2); + + /* acc3 += x[5] * y[2] + x[6] * y[3] */ + acc3 = __SMLALD(x1, c0, acc3); + + } while (--k); + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + if (k == 1U) + { + /* Read y[4] */ + c0 = *py; +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[7] */ + x3 = read_q15x2 ((q15_t *) px); + px++; + + /* Perform the multiply-accumulate */ + acc0 = __SMLALD (x0, c0, acc0); + acc1 = __SMLALD (x1, c0, acc1); + acc2 = __SMLALDX(x1, c0, acc2); + acc3 = __SMLALDX(x3, c0, acc3); + } + + if (k == 2U) + { + /* Read y[4], y[5] */ + c0 = read_q15x2 ((q15_t *) py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + px += 2U; + + /* Perform the multiply-accumulate */ + acc0 = __SMLALD(x0, c0, acc0); + acc1 = __SMLALD(x1, c0, acc1); + acc2 = __SMLALD(x3, c0, acc2); + acc3 = __SMLALD(x2, c0, acc3); + } + + if (k == 3U) + { + /* Read y[4], y[5] */ + c0 = read_q15x2_ia ((q15_t **) &py); + + /* Read x[7], x[8] */ + x3 = read_q15x2 ((q15_t *) px); + + /* Read x[9] */ + x2 = read_q15x2 ((q15_t *) px + 1); + + /* Perform the multiply-accumulate */ + acc0 = __SMLALD(x0, c0, acc0); + acc1 = __SMLALD(x1, c0, acc1); + acc2 = __SMLALD(x3, c0, acc2); + acc3 = __SMLALD(x2, c0, acc3); + + c0 = (*py); + + /* Read y[6] */ +#ifdef ARM_MATH_BIG_ENDIAN + c0 = c0 << 16U; +#else + c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + /* Read x[10] */ + x3 = read_q15x2 ((q15_t *) px + 2); + px += 3U; + + /* Perform the multiply-accumulates */ + acc0 = __SMLALDX(x1, c0, acc0); + acc1 = __SMLALD (x2, c0, acc1); + acc2 = __SMLALDX(x2, c0, acc2); + acc3 = __SMLALDX(x3, c0, acc3); + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q15_t) (__SSAT(acc0 >> 15, 16)); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + *pOut = (q15_t) (__SSAT(acc1 >> 15, 16)); + pOut += inc; + + *pOut = (q15_t) (__SSAT(acc2 >> 15, 16)); + pOut += inc; + + *pOut = (q15_t) (__SSAT(acc3 >> 15, 16)); + pOut += inc; + + /* Increment the count by 4 as 4 output values are computed */ + count += 4U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize2 % 0x4U; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += ((q63_t) *px++ * *py++); + sum += ((q63_t) *px++ * *py++); + sum += ((q63_t) *px++ * *py++); + sum += ((q63_t) *px++ * *py++); + + /* Decrement loop counter */ + k--; + } + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += ((q63_t) *px++ * *py++); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q15_t) (__SSAT(sum >> 15, 16)); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment count by 1, as one output value is computed */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q63_t) *px++ * *py++); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q15_t) (__SSAT(sum >> 15, 16)); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[0] + x[srcALen-srcBLen+2] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * sum += x[srcALen-srcBLen+2] * y[0] + x[srcALen-srcBLen+3] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * .... + * sum += x[srcALen-2] * y[0] + x[srcALen-1] * y[1] + * sum += x[srcALen-1] * y[0] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U); + px = pSrc1; + + /* Working pointer of inputB */ + py = pIn2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = count >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen - srcBLen + 4] * y[3] , sum += x[srcALen - srcBLen + 3] * y[2] */ + sum = __SMLALD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); + /* sum += x[srcALen - srcBLen + 2] * y[1] , sum += x[srcALen - srcBLen + 1] * y[0] */ + sum = __SMLALD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); + + /* Decrement loop counter */ + k--; + } + + /* If the count is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = count % 0x4U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum = __SMLALD(*px++, *py++, sum); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q15_t) (__SSAT((sum >> 15), 16)); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pIn2; + + /* Decrement MAC count */ + count--; + + /* Decrement loop counter */ + blockSize3--; + } + +#else /* #if defined (ARM_MATH_DSP) */ + + const q15_t *pIn1 = pSrcA; /* InputA pointer */ + const q15_t *pIn2 = pSrcB + (srcBLen - 1U); /* InputB pointer */ + q63_t sum; /* Accumulators */ + uint32_t i = 0U, j; /* Loop counters */ + uint32_t inv = 0U; /* Reverse order flag */ + uint32_t tot = 0U; /* Length */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and a varaible, inv is set to 1 */ + /* If lengths are not equal then zero pad has to be done to make the two + * inputs of same length. But to improve the performance, we include zeroes + * in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, (srcALen - srcBLen) zeroes has to included in the + * starting of the output buffer */ + /* If srcALen < srcBLen, (srcALen - srcBLen) zeroes has to included in the + * ending of the output buffer */ + /* Once the zero padding is done the remaining of the output is calcualted + * using convolution but with the shorter signal time shifted. */ + + /* Calculate the length of the remaining sequence */ + tot = ((srcALen + srcBLen) - 2U); + + if (srcALen > srcBLen) + { + /* Calculating the number of zeros to be padded to the output */ + j = srcALen - srcBLen; + + /* Initialise the pointer after zero padding */ + pDst += j; + } + + else if (srcALen < srcBLen) + { + /* Initialization to inputB pointer */ + pIn1 = pSrcB; + + /* Initialization to the end of inputA pointer */ + pIn2 = pSrcA + (srcALen - 1U); + + /* Initialisation of the pointer after zero padding */ + pDst = pDst + tot; + + /* Swapping the lengths */ + j = srcALen; + srcALen = srcBLen; + srcBLen = j; + + /* Setting the reverse flag */ + inv = 1; + } + + /* Loop to calculate convolution for output length number of values */ + for (i = 0U; i <= tot; i++) + { + /* Initialize sum with zero to carry on MAC operations */ + sum = 0; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ((q31_t) pIn1[j] * pIn2[-((int32_t) i - j)]); + } + } + + /* Store the output in the destination buffer */ + if (inv == 1) + *pDst-- = (q15_t) __SSAT((sum >> 15U), 16U); + else + *pDst++ = (q15_t) __SSAT((sum >> 15U), 16U); + } + +#endif /* #if defined (ARM_MATH_DSP) */ + +} + +/** + @} end of Corr group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q31.c new file mode 100644 index 0000000..caa2f51 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q31.c @@ -0,0 +1,682 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_correlate_q31.c + * Description: Correlation of Q31 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Corr + @{ + */ + +/** + @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 location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + + @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. + There is no saturation on intermediate additions. + Thus, if the accumulator overflows it wraps around and distorts the result. + The input signals should be scaled down to avoid intermediate overflows. + Scale down one of the inputs by 1/min(srcALen, srcBLen)to avoid overflows since a + maximum of min(srcALen, srcBLen) number of additions is carried internally. + The 2.62 accumulator is right shifted by 31 bits and saturated to 1.31 format to yield the final result. + + @remark + Refer to \ref arm_correlate_fast_q31() for a faster but less precise implementation of this function. + */ + +void arm_correlate_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst) +{ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + const q31_t *pIn1; /* InputA pointer */ + const q31_t *pIn2; /* InputB pointer */ + q31_t *pOut = pDst; /* Output pointer */ + const q31_t *px; /* Intermediate inputA pointer */ + const q31_t *py; /* Intermediate inputB pointer */ + const q31_t *pSrc1; /* Intermediate pointers */ + q63_t sum; /* Accumulators */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + uint32_t outBlockSize; + int32_t inc = 1; /* Destination address modifier */ + +#if defined (ARM_MATH_LOOPUNROLL) + q63_t acc0, acc1, acc2; /* Accumulators */ + q31_t x0, x1, x2, c0; /* Temporary variables for holding input and coefficient values */ +#endif + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and the destination pointer modifier, inc is set to -1 */ + /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */ + /* But to improve the performance, + * we include zeroes in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, + * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */ + /* If srcALen < srcBLen, + * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + + /* Number of output samples is calculated */ + outBlockSize = (2U * srcALen) - 1U; + + /* When srcALen > srcBLen, zero padding is done to srcB + * to make their lengths equal. + * Instead, (outBlockSize - (srcALen + srcBLen - 1)) + * number of output samples are made zero */ + j = outBlockSize - (srcALen + (srcBLen - 1U)); + + /* Updating the pointer position to non zero value */ + pOut += j; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + + /* CORR(x, y) = Reverse order(CORR(y, x)) */ + /* Hence set the destination pointer to point to the last output sample */ + pOut = pDst + ((srcALen + srcBLen) - 2U); + + /* Destination address modifier is set to -1 */ + inc = -1; + } + + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[srcBlen - 1] + * sum = x[0] * y[srcBlen - 2] + x[1] * y[srcBlen - 1] + * .... + * sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen - 1] * y[srcBLen - 1] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc1 = pIn2 + (srcBLen - 1U); + py = pSrc1; + + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[0] * y[srcBLen - 4] */ + sum += (q63_t) *px++ * (*py++); + + /* x[1] * y[srcBLen - 3] */ + sum += (q63_t) *px++ * (*py++); + + /* x[2] * y[srcBLen - 2] */ + sum += (q63_t) *px++ * (*py++); + + /* x[3] * y[srcBLen - 1] */ + sum += (q63_t) *px++ * (*py++); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* x[0] * y[srcBLen - 1] */ + sum += (q63_t) *px++ * (*py++); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q31_t) (sum >> 31); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pSrc1 - count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen-1] * y[srcBLen-1] + * sum = x[1] * y[0] + x[2] * y[1] +...+ x[srcBLen] * y[srcBLen-1] + * .... + * sum = x[srcALen-srcBLen-2] * y[0] + x[srcALen-srcBLen-1] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unroll by 3 */ + blkCnt = blockSize2 / 3; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + + /* read x[0], x[1] samples */ + x0 = *px++; + x1 = *px++; + + /* Apply loop unrolling and compute 3 MACs simultaneously. */ + k = srcBLen / 3; + + /* First part of the processing with loop unrolling. Compute 3 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 2 samples. */ + do + { + /* Read y[0] sample */ + c0 = *(py); + /* Read x[2] sample */ + x2 = *(px); + + /* Perform the multiply-accumulate */ + /* acc0 += x[0] * y[0] */ + acc0 += ((q63_t) x0 * c0); + /* acc1 += x[1] * y[0] */ + acc1 += ((q63_t) x1 * c0); + /* acc2 += x[2] * y[0] */ + acc2 += ((q63_t) x2 * c0); + + /* Read y[1] sample */ + c0 = *(py + 1U); + /* Read x[3] sample */ + x0 = *(px + 1U); + + /* Perform the multiply-accumulate */ + /* acc0 += x[1] * y[1] */ + acc0 += ((q63_t) x1 * c0); + /* acc1 += x[2] * y[1] */ + acc1 += ((q63_t) x2 * c0); + /* acc2 += x[3] * y[1] */ + acc2 += ((q63_t) x0 * c0); + + /* Read y[2] sample */ + c0 = *(py + 2U); + /* Read x[4] sample */ + x1 = *(px + 2U); + + /* Perform the multiply-accumulate */ + /* acc0 += x[2] * y[2] */ + acc0 += ((q63_t) x2 * c0); + /* acc1 += x[3] * y[2] */ + acc1 += ((q63_t) x0 * c0); + /* acc2 += x[4] * y[2] */ + acc2 += ((q63_t) x1 * c0); + + /* update scratch pointers */ + px += 3U; + py += 3U; + + } while (--k); + + /* If the srcBLen is not a multiple of 3, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen - (3 * (srcBLen / 3)); + + while (k > 0U) + { + /* Read y[4] sample */ + c0 = *(py++); + + /* Read x[7] sample */ + x2 = *(px++); + + /* Perform the multiply-accumulates */ + /* acc0 += x[4] * y[4] */ + acc0 += ((q63_t) x0 * c0); + /* acc1 += x[5] * y[4] */ + acc1 += ((q63_t) x1 * c0); + /* acc2 += x[6] * y[4] */ + acc2 += ((q63_t) x2 * c0); + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q31_t) (acc0 >> 31); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + *pOut = (q31_t) (acc1 >> 31); + pOut += inc; + + *pOut = (q31_t) (acc2 >> 31); + pOut += inc; + + /* Increment the pointer pIn1 index, count by 3 */ + count += 3U; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize2 - 3 * (blockSize2 / 3); + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulates */ + sum += (q63_t) *px++ * *py++; + sum += (q63_t) *px++ * *py++; + sum += (q63_t) *px++ * *py++; + sum += (q63_t) *px++ * *py++; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) *px++ * *py++; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q31_t) (sum >> 31); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) *px++ * *py++; + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q31_t) (sum >> 31); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[0] + x[srcALen-srcBLen+2] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * sum += x[srcALen-srcBLen+2] * y[0] + x[srcALen-srcBLen+3] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * .... + * sum += x[srcALen-2] * y[0] + x[srcALen-1] * y[1] + * sum += x[srcALen-1] * y[0] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = pIn1 + (srcALen - (srcBLen - 1U)); + px = pSrc1; + + /* Working pointer of inputB */ + py = pIn2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* sum += x[srcALen - srcBLen + 4] * y[3] */ + sum += (q63_t) *px++ * *py++; + + /* sum += x[srcALen - srcBLen + 3] * y[2] */ + sum += (q63_t) *px++ * *py++; + + /* sum += x[srcALen - srcBLen + 2] * y[1] */ + sum += (q63_t) *px++ * *py++; + + /* sum += x[srcALen - srcBLen + 1] * y[0] */ + sum += (q63_t) *px++ * *py++; + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += (q63_t) *px++ * *py++; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q31_t) (sum >> 31); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pIn2; + + /* Decrement MAC count */ + count--; + + /* Decrement loop counter */ + blockSize3--; + } + +#else +/* alternate version for CM0_FAMILY */ + + const q31_t *pIn1 = pSrcA; /* InputA pointer */ + const q31_t *pIn2 = pSrcB + (srcBLen - 1U); /* InputB pointer */ + q63_t sum; /* Accumulators */ + uint32_t i = 0U, j; /* Loop counters */ + uint32_t inv = 0U; /* Reverse order flag */ + uint32_t tot = 0U; /* Length */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and a varaible, inv is set to 1 */ + /* If lengths are not equal then zero pad has to be done to make the two + * inputs of same length. But to improve the performance, we include zeroes + * in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, (srcALen - srcBLen) zeroes has to included in the + * starting of the output buffer */ + /* If srcALen < srcBLen, (srcALen - srcBLen) zeroes has to included in the + * ending of the output buffer */ + /* Once the zero padding is done the remaining of the output is calcualted + * using correlation but with the shorter signal time shifted. */ + + /* Calculate the length of the remaining sequence */ + tot = ((srcALen + srcBLen) - 2U); + + if (srcALen > srcBLen) + { + /* Calculating the number of zeros to be padded to the output */ + j = srcALen - srcBLen; + + /* Initialise the pointer after zero padding */ + pDst += j; + } + + else if (srcALen < srcBLen) + { + /* Initialization to inputB pointer */ + pIn1 = pSrcB; + + /* Initialization to the end of inputA pointer */ + pIn2 = pSrcA + (srcALen - 1U); + + /* Initialisation of the pointer after zero padding */ + pDst = pDst + tot; + + /* Swapping the lengths */ + j = srcALen; + srcALen = srcBLen; + srcBLen = j; + + /* Setting the reverse flag */ + inv = 1; + } + + /* Loop to calculate correlation for output length number of times */ + for (i = 0U; i <= tot; i++) + { + /* Initialize sum with zero to carry out MAC operations */ + sum = 0; + + /* Loop to perform MAC operations according to correlation equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ((q63_t) pIn1[j] * pIn2[-((int32_t) i - j)]); + } + } + + /* Store the output in the destination buffer */ + if (inv == 1) + *pDst-- = (q31_t) (sum >> 31U); + else + *pDst++ = (q31_t) (sum >> 31U); + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of Corr group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q7.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q7.c new file mode 100644 index 0000000..e5881ac --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_correlate_q7.c @@ -0,0 +1,800 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_correlate_q7.c + * Description: Correlation of Q7 sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup Corr + @{ + */ + +/** + @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 location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 32-bit internal accumulator. + Both the inputs are represented in 1.7 format and multiplications yield a 2.14 result. + The 2.14 intermediate results are accumulated in a 32-bit accumulator in 18.14 format. + This approach provides 17 guard bits and there is no risk of overflow as long as max(srcALen, srcBLen)<131072. + The 18.14 result is then truncated to 18.7 format by discarding the low 7 bits and saturated to 1.7 format. + + @remark + Refer to \ref arm_correlate_opt_q7() for a faster implementation of this function. + */ + +void arm_correlate_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst) +{ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + const q7_t *pIn1; /* InputA pointer */ + const q7_t *pIn2; /* InputB pointer */ + q7_t *pOut = pDst; /* Output pointer */ + const q7_t *px; /* Intermediate inputA pointer */ + const q7_t *py; /* Intermediate inputB pointer */ + const q7_t *pSrc1; /* Intermediate pointers */ + q31_t sum; /* Accumulators */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + uint32_t outBlockSize; + int32_t inc = 1; + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc0, acc1, acc2, acc3; /* Accumulators */ + q31_t input1, input2; /* Temporary input variables */ + q15_t in1, in2; /* Temporary input variables */ + q7_t x0, x1, x2, x3, c0, c1; /* Temporary variables for holding input and coefficient values */ +#endif + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and the destination pointer modifier, inc is set to -1 */ + /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */ + /* But to improve the performance, + * we include zeroes in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, + * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */ + /* If srcALen < srcBLen, + * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */ + if (srcALen >= srcBLen) + { + /* Initialization of inputA pointer */ + pIn1 = pSrcA; + + /* Initialization of inputB pointer */ + pIn2 = pSrcB; + + /* Number of output samples is calculated */ + outBlockSize = (2U * srcALen) - 1U; + + /* When srcALen > srcBLen, zero padding is done to srcB + * to make their lengths equal. + * Instead, (outBlockSize - (srcALen + srcBLen - 1)) + * number of output samples are made zero */ + j = outBlockSize - (srcALen + (srcBLen - 1U)); + + /* Updating the pointer position to non zero value */ + pOut += j; + } + else + { + /* Initialization of inputA pointer */ + pIn1 = pSrcB; + + /* Initialization of inputB pointer */ + pIn2 = pSrcA; + + /* srcBLen is always considered as shorter or equal to srcALen */ + j = srcBLen; + srcBLen = srcALen; + srcALen = j; + + /* CORR(x, y) = Reverse order(CORR(y, x)) */ + /* Hence set the destination pointer to point to the last output sample */ + pOut = pDst + ((srcALen + srcBLen) - 2U); + + /* Destination address modifier is set to -1 */ + inc = -1; + } + + /* The function is internally + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the + * algorithm, the multiplications increase by one for every iteration. + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + + /* The algorithm is implemented in three stages. + The loop counters of each stage is initiated here. */ + blockSize1 = srcBLen - 1U; + blockSize2 = srcALen - (srcBLen - 1U); + blockSize3 = blockSize1; + + /* -------------------------- + * Initializations of stage1 + * -------------------------*/ + + /* sum = x[0] * y[srcBlen - 1] + * sum = x[0] * y[srcBlen - 2] + x[1] * y[srcBlen - 1] + * .... + * sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen - 1] * y[srcBLen - 1] + */ + + /* In this stage the MAC operations are increased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = 1U; + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + pSrc1 = pIn2 + (srcBLen - 1U); + py = pSrc1; + + /* ------------------------ + * Stage1 process + * ----------------------*/ + + /* The first stage starts here */ + while (blockSize1 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[0] , x[1] */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* y[srcBLen - 4] , y[srcBLen - 3] */ + in1 = (q15_t) *py++; + in2 = (q15_t) *py++; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* x[0] * y[srcBLen - 4] */ + /* x[1] * y[srcBLen - 3] */ + sum = __SMLAD(input1, input2, sum); + + /* x[2] , x[3] */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* y[srcBLen - 2] , y[srcBLen - 1] */ + in1 = (q15_t) *py++; + in2 = (q15_t) *py++; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16); + + /* x[2] * y[srcBLen - 2] */ + /* x[3] * y[srcBLen - 1] */ + sum = __SMLAD(input1, input2, sum); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize k with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + /* x[0] * y[srcBLen - 1] */ + sum += (q31_t) ((q15_t) *px++ * *py++); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q7_t) (__SSAT(sum >> 7U, 8)); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + py = pSrc1 - count; + px = pIn1; + + /* Increment MAC count */ + count++; + + /* Decrement loop counter */ + blockSize1--; + } + + /* -------------------------- + * Initializations of stage2 + * ------------------------*/ + + /* sum = x[0] * y[0] + x[1] * y[1] +...+ x[srcBLen-1] * y[srcBLen-1] + * sum = x[1] * y[0] + x[2] * y[1] +...+ x[srcBLen] * y[srcBLen-1] + * .... + * sum = x[srcALen-srcBLen-2] * y[0] + x[srcALen-srcBLen-1] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + */ + + /* Working pointer of inputA */ + px = pIn1; + + /* Working pointer of inputB */ + py = pIn2; + + /* count is index by which the pointer pIn1 to be incremented */ + count = 0U; + + /* ------------------- + * Stage2 process + * ------------------*/ + + /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. + * So, to loop unroll over blockSize2, + * srcBLen should be greater than or equal to 4 */ + if (srcBLen >= 4U) + { +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize2 >> 2U; + + while (blkCnt > 0U) + { + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* read x[0], x[1], x[2] samples */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + k = srcBLen >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 MACs at a time. + ** a second loop below computes MACs for the remaining 1 to 3 samples. */ + do + { + /* Read y[0] sample */ + c0 = *py++; + /* Read y[1] sample */ + c1 = *py++; + + /* Read x[3] sample */ + x3 = *px++; + + /* x[0] and x[1] are packed */ + in1 = (q15_t) x0; + in2 = (q15_t) x1; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* y[0] and y[1] are packed */ + in1 = (q15_t) c0; + in2 = (q15_t) c1; + + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc0 += x[0] * y[0] + x[1] * y[1] */ + acc0 = __SMLAD(input1, input2, acc0); + + /* x[1] and x[2] are packed */ + in1 = (q15_t) x1; + in2 = (q15_t) x2; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc1 += x[1] * y[0] + x[2] * y[1] */ + acc1 = __SMLAD(input1, input2, acc1); + + /* x[2] and x[3] are packed */ + in1 = (q15_t) x2; + in2 = (q15_t) x3; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc2 += x[2] * y[0] + x[3] * y[1] */ + acc2 = __SMLAD(input1, input2, acc2); + + /* Read x[4] sample */ + x0 = *px++; + + /* x[3] and x[4] are packed */ + in1 = (q15_t) x3; + in2 = (q15_t) x0; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc3 += x[3] * y[0] + x[4] * y[1] */ + acc3 = __SMLAD(input1, input2, acc3); + + /* Read y[2] sample */ + c0 = *py++; + /* Read y[3] sample */ + c1 = *py++; + + /* Read x[5] sample */ + x1 = *px++; + + /* x[2] and x[3] are packed */ + in1 = (q15_t) x2; + in2 = (q15_t) x3; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* y[2] and y[3] are packed */ + in1 = (q15_t) c0; + in2 = (q15_t) c1; + + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc0 += x[2] * y[2] + x[3] * y[3] */ + acc0 = __SMLAD(input1, input2, acc0); + + /* x[3] and x[4] are packed */ + in1 = (q15_t) x3; + in2 = (q15_t) x0; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc1 += x[3] * y[2] + x[4] * y[3] */ + acc1 = __SMLAD(input1, input2, acc1); + + /* x[4] and x[5] are packed */ + in1 = (q15_t) x0; + in2 = (q15_t) x1; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc2 += x[4] * y[2] + x[5] * y[3] */ + acc2 = __SMLAD(input1, input2, acc2); + + /* Read x[6] sample */ + x2 = *px++; + + /* x[5] and x[6] are packed */ + in1 = (q15_t) x1; + in2 = (q15_t) x2; + + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* acc3 += x[5] * y[2] + x[6] * y[3] */ + acc3 = __SMLAD(input1, input2, acc3); + + } while (--k); + + /* If the srcBLen is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + k = srcBLen % 0x4U; + + while (k > 0U) + { + /* Read y[4] sample */ + c0 = *py++; + /* Read x[7] sample */ + x3 = *px++; + + /* Perform the multiply-accumulates */ + /* acc0 += x[4] * y[4] */ + acc0 += ((q15_t) x0 * c0); + /* acc1 += x[5] * y[4] */ + acc1 += ((q15_t) x1 * c0); + /* acc2 += x[6] * y[4] */ + acc2 += ((q15_t) x2 * c0); + /* acc3 += x[7] * y[4] */ + acc3 += ((q15_t) x3 * c0); + + /* Reuse the present samples for the next MAC */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q7_t) (__SSAT(acc0 >> 7, 8)); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + *pOut = (q7_t) (__SSAT(acc1 >> 7, 8)); + pOut += inc; + + *pOut = (q7_t) (__SSAT(acc2 >> 7, 8)); + pOut += inc; + + *pOut = (q7_t) (__SSAT(acc3 >> 7, 8)); + pOut += inc; + + count += 4U; + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize2 % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize2; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = srcBLen >> 2U; + + while (k > 0U) + { + + /* Reading two inputs of SrcA buffer and packing */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* Reading two inputs of SrcB buffer and packing */ + in1 = (q15_t) *py++; + in2 = (q15_t) *py++; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* Perform the multiply-accumulate */ + sum = __SMLAD(input1, input2, sum); + + /* Reading two inputs of SrcA buffer and packing */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* Reading two inputs of SrcB buffer and packing */ + in1 = (q15_t) *py++; + in2 = (q15_t) *py++; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* Perform the multiply-accumulate */ + sum = __SMLAD(input1, input2, sum); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = srcBLen % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = srcBLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q15_t) *px++ * *py++); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q7_t) (__SSAT(sum >> 7U, 8)); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment the pointer pIn1 index, count by 1 */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement the loop counter */ + blkCnt--; + } + } + else + { + /* If the srcBLen is not a multiple of 4, + * the blockSize2 loop cannot be unrolled by 4 */ + blkCnt = blockSize2; + + while (blkCnt > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + + /* srcBLen number of MACS should be performed */ + k = srcBLen; + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q15_t) *px++ * *py++); + + /* Decrement the loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q7_t) (__SSAT(sum >> 7U, 8)); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Increment the MAC count */ + count++; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = pIn1 + count; + py = pIn2; + + /* Decrement loop counter */ + blkCnt--; + } + } + + + /* -------------------------- + * Initializations of stage3 + * -------------------------*/ + + /* sum += x[srcALen-srcBLen+1] * y[0] + x[srcALen-srcBLen+2] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * sum += x[srcALen-srcBLen+2] * y[0] + x[srcALen-srcBLen+3] * y[1] +...+ x[srcALen-1] * y[srcBLen-1] + * .... + * sum += x[srcALen-2] * y[0] + x[srcALen-1] * y[1] + * sum += x[srcALen-1] * y[0] + */ + + /* In this stage the MAC operations are decreased by 1 for every iteration. + The count variable holds the number of MAC operations performed */ + count = srcBLen - 1U; + + /* Working pointer of inputA */ + pSrc1 = pIn1 + (srcALen - (srcBLen - 1U)); + px = pSrc1; + + /* Working pointer of inputB */ + py = pIn2; + + /* ------------------- + * Stage3 process + * ------------------*/ + + while (blockSize3 > 0U) + { + /* Accumulator is made zero for every iteration */ + sum = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + k = count >> 2U; + + while (k > 0U) + { + /* x[srcALen - srcBLen + 1] , x[srcALen - srcBLen + 2] */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* y[0] , y[1] */ + in1 = (q15_t) *py++; + in2 = (q15_t) *py++; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* sum += x[srcALen - srcBLen + 1] * y[0] */ + /* sum += x[srcALen - srcBLen + 2] * y[1] */ + sum = __SMLAD(input1, input2, sum); + + /* x[srcALen - srcBLen + 3] , x[srcALen - srcBLen + 4] */ + in1 = (q15_t) *px++; + in2 = (q15_t) *px++; + input1 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* y[2] , y[3] */ + in1 = (q15_t) *py++; + in2 = (q15_t) *py++; + input2 = ((q31_t) in1 & 0x0000FFFF) | ((q31_t) in2 << 16U); + + /* sum += x[srcALen - srcBLen + 3] * y[2] */ + /* sum += x[srcALen - srcBLen + 4] * y[3] */ + sum = __SMLAD(input1, input2, sum); + + /* Decrement loop counter */ + k--; + } + + /* Loop unrolling: Compute remaining outputs */ + k = count % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + k = count; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (k > 0U) + { + /* Perform the multiply-accumulate */ + sum += ((q15_t) *px++ * *py++); + + /* Decrement loop counter */ + k--; + } + + /* Store the result in the accumulator in the destination buffer. */ + *pOut = (q7_t) (__SSAT(sum >> 7U, 8)); + /* Destination pointer is updated according to the address modifier, inc */ + pOut += inc; + + /* Update the inputA and inputB pointers for next MAC calculation */ + px = ++pSrc1; + py = pIn2; + + /* Decrement MAC count */ + count--; + + /* Decrement loop counter */ + blockSize3--; + } + +#else +/* alternate version for CM0_FAMILY */ + + const q7_t *pIn1 = pSrcA; /* InputA pointer */ + const q7_t *pIn2 = pSrcB + (srcBLen - 1U); /* InputB pointer */ + q31_t sum; /* Accumulator */ + uint32_t i = 0U, j; /* Loop counters */ + uint32_t inv = 0U; /* Reverse order flag */ + uint32_t tot = 0U; /* Length */ + + /* The algorithm implementation is based on the lengths of the inputs. */ + /* srcB is always made to slide across srcA. */ + /* So srcBLen is always considered as shorter or equal to srcALen */ + /* But CORR(x, y) is reverse of CORR(y, x) */ + /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ + /* and a varaible, inv is set to 1 */ + /* If lengths are not equal then zero pad has to be done to make the two + * inputs of same length. But to improve the performance, we include zeroes + * in the output instead of zero padding either of the the inputs*/ + /* If srcALen > srcBLen, (srcALen - srcBLen) zeroes has to included in the + * starting of the output buffer */ + /* If srcALen < srcBLen, (srcALen - srcBLen) zeroes has to included in the + * ending of the output buffer */ + /* Once the zero padding is done the remaining of the output is calcualted + * using convolution but with the shorter signal time shifted. */ + + /* Calculate the length of the remaining sequence */ + tot = ((srcALen + srcBLen) - 2U); + + if (srcALen > srcBLen) + { + /* Calculating the number of zeros to be padded to the output */ + j = srcALen - srcBLen; + + /* Initialise the pointer after zero padding */ + pDst += j; + } + + else if (srcALen < srcBLen) + { + /* Initialization to inputB pointer */ + pIn1 = pSrcB; + + /* Initialization to the end of inputA pointer */ + pIn2 = pSrcA + (srcALen - 1U); + + /* Initialisation of the pointer after zero padding */ + pDst = pDst + tot; + + /* Swapping the lengths */ + j = srcALen; + srcALen = srcBLen; + srcBLen = j; + + /* Setting the reverse flag */ + inv = 1; + } + + /* Loop to calculate convolution for output length number of times */ + for (i = 0U; i <= tot; i++) + { + /* Initialize sum with zero to carry out MAC operations */ + sum = 0; + + /* Loop to perform MAC operations according to convolution equation */ + for (j = 0U; j <= i; j++) + { + /* Check the array limitations */ + if (((i - j) < srcBLen) && (j < srcALen)) + { + /* z[i] += x[i-j] * y[j] */ + sum += ((q15_t) pIn1[j] * pIn2[-((int32_t) i - j)]); + } + } + + /* Store the output in the destination buffer */ + if (inv == 1) + *pDst-- = (q7_t) __SSAT((sum >> 7U), 8U); + else + *pDst++ = (q7_t) __SSAT((sum >> 7U), 8U); + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of Corr group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_f32.c new file mode 100644 index 0000000..3287116 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_f32.c @@ -0,0 +1,456 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_decimate_f32.c + * Description: FIR decimation for floating-point sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup FIR_decimate Finite Impulse Response (FIR) Decimator + + These functions combine an FIR filter together with a decimator. + They are used in multirate systems for reducing the sample rate of a signal without introducing aliasing distortion. + Conceptually, the functions are equivalent to the block diagram below: + \image html FIRDecimator.gif "Components included in the FIR Decimator functions" + When decimating by a factor of M, the signal should be prefiltered by a lowpass filter with a normalized + cutoff frequency of 1/M in order to prevent aliasing distortion. + The user of the function is responsible for providing the filter coefficients. + + The FIR decimator functions provided in the CMSIS DSP Library combine the FIR filter and the decimator in an efficient manner. + Instead of calculating all of the FIR filter outputs and discarding M-1 out of every M, only the + samples output by the decimator are computed. + The functions operate on blocks of input and output data. + pSrc points to an array of blockSize input values and + pDst points to an array of blockSize/M output values. + In order to have an integer number of output samples blockSize + must always be a multiple of the decimation factor M. + + The library provides separate functions for Q15, Q31 and floating-point data types. + + @par Algorithm: + The FIR portion of the algorithm uses the standard form filter: +
+      y[n] = b[0] * x[n] + b[1] * x[n-1] + b[2] * x[n-2] + ...+ b[numTaps-1] * x[n-numTaps+1]
+  
+ where, b[n] are the filter coefficients. + @par + The pCoeffs points to a coefficient array of size numTaps. + Coefficients are stored in time reversed order. + @par +
+      {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ @par + pState points to a state array of size numTaps + blockSize - 1. + Samples in the state buffer are stored in the order: + @par +
+      {x[n-numTaps+1], x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2]....x[0], x[1], ..., x[blockSize-1]}
+  
+ The state variables are updated after each block of data is processed, the coefficients are untouched. + + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter. + Coefficient arrays may be shared among several instances while state variable array should be allocated separately. + There are separate instance structure declarations for each of the 3 supported data types. + + @par Initialization Functions + There is also an associated initialization function for each data type. + The initialization function performs the following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + - Checks to make sure that the size of the input is a multiple of the decimation factor. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + numTaps, pCoeffs, M (decimation factor), pState. Also set all of the values in pState to zero. + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + The code below statically initializes each of the 3 different data type filter instance structures +
+      arm_fir_decimate_instance_f32 S = {M, numTaps, pCoeffs, pState};
+      arm_fir_decimate_instance_q31 S = {M, numTaps, pCoeffs, pState};
+      arm_fir_decimate_instance_q15 S = {M, numTaps, pCoeffs, pState};
+  
+ where M is the decimation factor; numTaps is the number of filter coefficients in the filter; + pCoeffs is the address of the coefficient buffer; + pState is the address of the state buffer. + Be sure to set the values in the state buffer to zeros when doing static initialization. + + @par Fixed-Point Behavior + Care must be taken when using the fixed-point versions of the FIR decimate filter 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 FIR_decimate + @{ + */ + +/** + @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 + @return none + */ + +void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + float32_t *pState = S->pState; /* State pointer */ + const float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t *pStateCur; /* Points to the current sample of the state */ + float32_t *px0; /* Temporary pointer for state buffer */ + const float32_t *pb; /* Temporary pointer for coefficient buffer */ + float32_t x0, c0; /* Temporary variables to hold state and coefficient values */ + float32_t acc0; /* Accumulator */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t i, tapCnt, blkCnt, outBlockSize = blockSize / S->M; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + float32_t *px1, *px2, *px3; + float32_t x1, x2, x3; + float32_t acc1, acc2, acc3; +#endif + + /* S->pState buffer contains previous frame (numTaps - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (numTaps - 1U); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 samples at a time */ + blkCnt = outBlockSize >> 2U; + + /* Samples loop unrolled by 4 */ + while (blkCnt > 0U) + { + /* Copy 4 * decimation factor number of new input samples into the state buffer */ + i = S->M * 4; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulators to zero */ + acc0 = 0.0f; + acc1 = 0.0f; + acc2 = 0.0f; + acc3 = 0.0f; + + /* Initialize state pointer for all the samples */ + px0 = pState; + px1 = pState + S->M; + px2 = pState + 2 * S->M; + px3 = pState + 3 * S->M; + + /* Initialize coeff pointer */ + pb = pCoeffs; + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-1] sample for acc0 */ + x0 = *(px0++); + /* Read x[n-numTaps-1] sample for acc1 */ + x1 = *(px1++); + /* Read x[n-numTaps-1] sample for acc2 */ + x2 = *(px2++); + /* Read x[n-numTaps-1] sample for acc3 */ + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + acc2 += x2 * c0; + acc3 += x3 * c0; + + /* Read the b[numTaps-2] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-2] sample for acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + acc2 += x2 * c0; + acc3 += x3 * c0; + + /* Read the b[numTaps-3] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-3] sample acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + acc2 += x2 * c0; + acc3 += x3 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-4] sample acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + acc2 += x2 * c0; + acc3 += x3 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *(pb++); + + /* Fetch state variables for acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + acc2 += x2 * c0; + acc3 += x3 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M * 4; + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = acc0; + *pDst++ = acc1; + *pDst++ = acc2; + *pDst++ = acc3; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining samples */ + blkCnt = outBlockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = outBlockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy decimation factor number of new input samples into the state buffer */ + i = S->M; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + acc0 = 0.0f; + + /* Initialize state pointer */ + px0 = pState; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-1] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + + /* Read the b[numTaps-2] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-2] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + + /* Read the b[numTaps-3] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-3] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-4] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch 1 state variable */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M; + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = acc0; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the satrt of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = (numTaps - 1U) >> 2U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numTaps - 1U) % 0x04U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of FIR_decimate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_fast_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_fast_q15.c new file mode 100644 index 0000000..948b15c --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_fast_q15.c @@ -0,0 +1,595 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_decimate_fast_q15.c + * Description: Fast Q15 FIR Decimator + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_decimate + @{ + */ + +/** + @brief Processing function for the Q15 FIR decimator (fast variant). + @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 + @return none + + @par Scaling and Overflow Behavior + This fast version uses a 32-bit accumulator with 2.30 format. + The accumulator maintains full precision of the intermediate multiplication results but provides only a single guard bit. + Thus, if the accumulator result overflows it wraps around and distorts the result. + In order to avoid overflows completely the input signal must be scaled down by log2(numTaps) bits (log2 is read as log to the base 2). + The 2.30 accumulator is then truncated to 2.15 format and saturated to yield the 1.15 result. + @remark + Refer to \ref arm_fir_decimate_q15() for a slower implementation of this function which uses 64-bit accumulation to avoid wrap around distortion. + Both the slow and the fast versions use the same instance structure. + Use function \ref arm_fir_decimate_init_q15() to initialize the filter structure. + */ + +#if defined (ARM_MATH_DSP) + +void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *pStateCur; /* Points to the current sample of the state */ + q15_t *px; /* Temporary pointer for state buffer */ + const q15_t *pb; /* Temporary pointer for coefficient buffer */ + q31_t x0, x1, c0; /* Temporary variables to hold state and coefficient values */ + q31_t sum0; /* Accumulators */ + q31_t acc0, acc1; + q15_t *px0, *px1; + uint32_t blkCntN3; + uint32_t numTaps = S->numTaps; /* Number of taps */ + uint32_t i, blkCnt, tapCnt, outBlockSize = blockSize / S->M; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t c1; /* Temporary variables to hold state and coefficient values */ +#endif + + /* S->pState buffer contains previous frame (numTaps - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (numTaps - 1U); + + /* Total number of output samples to be computed */ + blkCnt = outBlockSize / 2; + blkCntN3 = outBlockSize - (2 * blkCnt); + + while (blkCnt > 0U) + { + /* Copy 2 * decimation factor number of new input samples into the state buffer */ + i = S->M * 2; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + acc0 = 0; + acc1 = 0; + + /* Initialize state pointer for all the samples */ + px0 = pState; + px1 = pState + S->M; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] and b[numTaps-2] coefficients */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* Read x[n-numTaps-1] and x[n-numTaps-2]sample */ + x0 = read_q15x2_ia (&px0); + x1 = read_q15x2_ia (&px1); + + /* Perform the multiply-accumulate */ + acc0 = __SMLAD(x0, c0, acc0); + acc1 = __SMLAD(x1, c0, acc1); + + /* Read the b[numTaps-3] and b[numTaps-4] coefficient */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* Read x[n-numTaps-2] and x[n-numTaps-3] sample */ + x0 = read_q15x2_ia (&px0); + x1 = read_q15x2_ia (&px1); + + /* Perform the multiply-accumulate */ + acc0 = __SMLAD(x0, c0, acc0); + acc1 = __SMLAD(x1, c0, acc1); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch state variables for acc0, acc1 */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 = __SMLAD(x0, c0, acc0); + acc1 = __SMLAD(x1, c0, acc1); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M * 2; + + /* Store filter output, smlad returns the values in 2.14 format */ + /* so downsacle by 15 to get output in 1.15 */ + *pDst++ = (q15_t) (__SSAT((acc0 >> 15), 16)); + *pDst++ = (q15_t) (__SSAT((acc1 >> 15), 16)); + + /* Decrement loop counter */ + blkCnt--; + } + + while (blkCntN3 > 0U) + { + /* Copy decimation factor number of new input samples into the state buffer */ + i = S->M; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + sum0 = 0; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] and b[numTaps-2] coefficients */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* Read x[n-numTaps-1] and x[n-numTaps-2] sample */ + x0 = read_q15x2_ia (&px); + + /* Read the b[numTaps-3] and b[numTaps-4] coefficients */ + c1 = read_q15x2_ia ((q15_t **) &pb); + + /* Perform the multiply-accumulate */ + sum0 = __SMLAD(x0, c0, sum0); + + /* Read x[n-numTaps-2] and x[n-numTaps-3] sample */ + x0 = read_q15x2_ia (&px); + + /* Perform the multiply-accumulate */ + sum0 = __SMLAD(x0, c1, sum0); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch 1 state variable */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 = __SMLAD(x0, c0, sum0); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M; + + /* Store filter output, smlad returns the values in 2.14 format */ + /* so downsacle by 15 to get output in 1.15 */ + *pDst++ = (q15_t) (__SSAT((sum0 >> 15), 16)); + + /* Decrement loop counter */ + blkCntN3--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the satrt of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + + i = (numTaps - 1U) >> 2U; + + /* copy data */ + while (i > 0U) + { + write_q15x2_ia (&pStateCur, read_q15x2_ia (&pState)); + write_q15x2_ia (&pStateCur, read_q15x2_ia (&pState)); + + /* Decrement loop counter */ + i--; + } + + i = (numTaps - 1U) % 0x04U; + + /* Copy data */ + while (i > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + i--; + } + +} + +#else /* #if defined (ARM_MATH_DSP) */ + +void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *pStateCur; /* Points to the current sample of the state */ + q15_t *px; /* Temporary pointer for state buffer */ + const q15_t *pb; /* Temporary pointer for coefficient buffer */ + q15_t x0, x1, c0; /* Temporary variables to hold state and coefficient values */ + q31_t sum0; /* Accumulators */ + q31_t acc0, acc1; + q15_t *px0, *px1; + uint32_t blkCntN3; + uint32_t numTaps = S->numTaps; /* Number of taps */ + uint32_t i, blkCnt, tapCnt, outBlockSize = blockSize / S->M; /* Loop counters */ + + + /* S->pState buffer contains previous frame (numTaps - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (numTaps - 1U); + + /* Total number of output samples to be computed */ + blkCnt = outBlockSize / 2; + blkCntN3 = outBlockSize - (2 * blkCnt); + + while (blkCnt > 0U) + { + /* Copy 2 * decimation factor number of new input samples into the state buffer */ + i = S->M * 2; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + acc0 = 0; + acc1 = 0; + + /* Initialize state pointer */ + px0 = pState; + px1 = pState + S->M; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the Read b[numTaps-1] coefficients */ + c0 = *pb++; + + /* Read x[n-numTaps-1] for sample 0 and for sample 1 */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + + /* Read the b[numTaps-2] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-2] for sample 0 and sample 1 */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + + /* Read the b[numTaps-3] coefficients */ + c0 = *pb++; + + /* Read x[n-numTaps-3] for sample 0 and sample 1 */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-4] for sample 0 and sample 1 */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch 1 state variable */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M * 2; + + /* Store filter output, smlad returns the values in 2.14 format */ + /* so downsacle by 15 to get output in 1.15 */ + + *pDst++ = (q15_t) (__SSAT((acc0 >> 15), 16)); + *pDst++ = (q15_t) (__SSAT((acc1 >> 15), 16)); + + /* Decrement loop counter */ + blkCnt--; + } + + while (blkCntN3 > 0U) + { + /* Copy decimation factor number of new input samples into the state buffer */ + i = S->M; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + sum0 = 0; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-1] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 += x0 * c0; + + /* Read the b[numTaps-2] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-2] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 += x0 * c0; + + /* Read the b[numTaps-3] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-3] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 += x0 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-4] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 += x0 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch 1 state variable */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 += x0 * c0; + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M; + + /* Store filter output, smlad returns the values in 2.14 format */ + /* so downsacle by 15 to get output in 1.15 */ + *pDst++ = (q15_t) (__SSAT((sum0 >> 15), 16)); + + /* Decrement loop counter */ + blkCntN3--; + } + + /* Processing is complete. + ** Now copy the last numTaps - 1 samples to the satrt of the state buffer. + ** This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + + i = (numTaps - 1U) >> 2U; + + /* copy data */ + while (i > 0U) + { + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + i--; + } + + i = (numTaps - 1U) % 0x04U; + + /* copy data */ + while (i > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + i--; + } +} + +#endif /* #if defined (ARM_MATH_DSP) */ + +/** + @} end of FIR_decimate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_fast_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_fast_q31.c new file mode 100644 index 0000000..2c3a28a --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_fast_q31.c @@ -0,0 +1,390 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_decimate_fast_q31.c + * Description: Fast Q31 FIR Decimator + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_decimate + @{ + */ + +/** + @brief Processing function for the Q31 FIR decimator (fast variant). + @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 samples to process + @return none + + @par Scaling and Overflow Behavior + This function is optimized for speed at the expense of fixed-point precision and overflow protection. + The result of each 1.31 x 1.31 multiplication is truncated to 2.30 format. + These intermediate results are added to a 2.30 accumulator. + Finally, the accumulator is saturated and converted to a 1.31 result. + The fast version has the same overflow behavior as the standard version and provides less precision since it discards the low 32 bits of each multiplication result. + In order to avoid overflows completely the input signal must be scaled down by log2(numTaps) bits (where log2 is read as log to the base 2). + + @remark + Refer to \ref arm_fir_decimate_q31() for a slower implementation of this function which uses a 64-bit accumulator to provide higher precision. + Both the slow and the fast versions use the same instance structure. + Use function \ref arm_fir_decimate_init_q31() to initialize the filter structure. + */ + +void arm_fir_decimate_fast_q31( + const arm_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + q31_t *pState = S->pState; /* State pointer */ + const q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t *pStateCur; /* Points to the current sample of the state */ + q31_t *px0; /* Temporary pointer for state buffer */ + const q31_t *pb; /* Temporary pointer for coefficient buffer */ + q31_t x0, c0; /* Temporary variables to hold state and coefficient values */ + q63_t acc0; /* Accumulator */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t i, tapCnt, blkCnt, outBlockSize = blockSize / S->M; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t *px1, *px2, *px3; + q31_t x1, x2, x3; + q63_t acc1, acc2, acc3; +#endif + + /* S->pState buffer contains previous frame (numTaps - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (numTaps - 1U); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 samples at a time */ + blkCnt = outBlockSize >> 2U; + + /* Samples loop unrolled by 4 */ + while (blkCnt > 0U) + { + /* Copy 4 * decimation factor number of new input samples into the state buffer */ + i = S->M * 4; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Initialize state pointer for all the samples */ + px0 = pState; + px1 = pState + S->M; + px2 = pState + 2 * S->M; + px3 = pState + 3 * S->M; + + /* Initialize coeff pointer */ + pb = pCoeffs; + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-1] sample for acc0 */ + x0 = *(px0++); + /* Read x[n-numTaps-1] sample for acc1 */ + x1 = *(px1++); + /* Read x[n-numTaps-1] sample for acc2 */ + x2 = *(px2++); + /* Read x[n-numTaps-1] sample for acc3 */ + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + /* Read the b[numTaps-2] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-2] sample for acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + /* Read the b[numTaps-3] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-3] sample acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + /* Read the b[numTaps-4] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-4] sample acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *(pb++); + + /* Fetch state variables for acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + acc1 = (q31_t) ((((q63_t) acc1 << 32) + ((q63_t) x1 * c0)) >> 32); + acc2 = (q31_t) ((((q63_t) acc2 << 32) + ((q63_t) x2 * c0)) >> 32); + acc3 = (q31_t) ((((q63_t) acc3 << 32) + ((q63_t) x3 * c0)) >> 32); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M * 4; + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = (q31_t) (acc0 << 1); + *pDst++ = (q31_t) (acc1 << 1); + *pDst++ = (q31_t) (acc2 << 1); + *pDst++ = (q31_t) (acc3 << 1); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining samples */ + blkCnt = outBlockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = outBlockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy decimation factor number of new input samples into the state buffer */ + i = S->M; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + acc0 = 0; + + /* Initialize state pointer */ + px0 = pState; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-1] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + + /* Read the b[numTaps-2] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-2] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + + /* Read the b[numTaps-3] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-3] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + + /* Read the b[numTaps-4] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-4] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch 1 state variable */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 = (q31_t) ((((q63_t) acc0 << 32) + ((q63_t) x0 * c0)) >> 32); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M; + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = (q31_t) (acc0 << 1); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the satrt of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = (numTaps - 1U) >> 2U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numTaps - 1U) % 0x04U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of FIR_decimate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_f32.c new file mode 100644 index 0000000..9382f09 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_f32.c @@ -0,0 +1,105 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_decimate_init_f32.c + * Description: Floating-point FIR Decimator initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_decimate + @{ + */ + +/** + @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 + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+      {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ @par + pState points to the array of state variables. + pState is of length numTaps+blockSize-1 words where blockSize is the number of input samples passed to arm_fir_decimate_f32(). + M is the decimation factor. + */ + +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) +{ + arm_status status; + + /* The size of the input block must be a multiple of the decimation factor */ + if ((blockSize % M) != 0U) + { + /* Set status as ARM_MATH_LENGTH_ERROR */ + status = ARM_MATH_LENGTH_ERROR; + } + else + { + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear the state buffer. The size is always (blockSize + numTaps - 1) */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; + + /* Assign Decimation Factor */ + S->M = M; + + status = ARM_MATH_SUCCESS; + } + + return (status); + +} + +/** + @} end of FIR_decimate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_q15.c new file mode 100644 index 0000000..f583a03 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_q15.c @@ -0,0 +1,106 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_decimate_init_q15.c + * Description: Initialization function for the Q15 FIR Decimator + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_decimate + @{ + */ + +/** + @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 + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_LENGTH_ERROR : blockSize is not a multiple of M + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+      {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ @par + pState points to the array of state variables. + pState is of length numTaps+blockSize-1 words where blockSize is the number of input samples + to the call arm_fir_decimate_q15(). + M is the decimation factor. + */ + +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) +{ + arm_status status; + + /* The size of the input block must be a multiple of the decimation factor */ + if ((blockSize % M) != 0U) + { + /* Set status as ARM_MATH_LENGTH_ERROR */ + status = ARM_MATH_LENGTH_ERROR; + } + else + { + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear the state buffer. The size is always (blockSize + numTaps - 1) */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(q15_t)); + + /* Assign state pointer */ + S->pState = pState; + + /* Assign Decimation Factor */ + S->M = M; + + status = ARM_MATH_SUCCESS; + } + + return (status); + +} + +/** + @} end of FIR_decimate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_q31.c new file mode 100644 index 0000000..5ee69c6 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_init_q31.c @@ -0,0 +1,105 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_decimate_init_q31.c + * Description: Initialization function for Q31 FIR Decimation filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_decimate + @{ + */ + +/** + @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 + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_LENGTH_ERROR : blockSize is not a multiple of M + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+      {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ @par + pState points to the array of state variables. + pState is of length numTaps+blockSize-1 words where blockSize is the number of input samples passed to arm_fir_decimate_q31(). + M is the decimation factor. + */ + +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) +{ + arm_status status; + + /* The size of the input block must be a multiple of the decimation factor */ + if ((blockSize % M) != 0U) + { + /* Set status as ARM_MATH_LENGTH_ERROR */ + status = ARM_MATH_LENGTH_ERROR; + } + else + { + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear the state buffer. The size is always (blockSize + numTaps - 1) */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(q31_t)); + + /* Assign state pointer */ + S->pState = pState; + + /* Assign Decimation Factor */ + S->M = M; + + status = ARM_MATH_SUCCESS; + } + + return (status); + +} + +/** + @} end of FIR_decimate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_q15.c new file mode 100644 index 0000000..f9d92c0 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_q15.c @@ -0,0 +1,595 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_decimate_q15.c + * Description: Q15 FIR Decimator + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_decimate + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both coefficients 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. + + @remark + Refer to \ref arm_fir_decimate_fast_q15() for a faster but less precise implementation of this function. + */ + +#if defined (ARM_MATH_DSP) + +void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *pStateCur; /* Points to the current sample of the state */ + q15_t *px; /* Temporary pointer for state buffer */ + const q15_t *pb; /* Temporary pointer for coefficient buffer */ + q31_t x0, x1, c0; /* Temporary variables to hold state and coefficient values */ + q63_t sum0; /* Accumulators */ + q63_t acc0, acc1; + q15_t *px0, *px1; + uint32_t blkCntN3; + uint32_t numTaps = S->numTaps; /* Number of taps */ + uint32_t i, blkCnt, tapCnt, outBlockSize = blockSize / S->M; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t c1; /* Temporary variables to hold state and coefficient values */ +#endif + + /* S->pState buffer contains previous frame (numTaps - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (numTaps - 1U); + + /* Total number of output samples to be computed */ + blkCnt = outBlockSize / 2; + blkCntN3 = outBlockSize - (2 * blkCnt); + + while (blkCnt > 0U) + { + /* Copy 2 * decimation factor number of new input samples into the state buffer */ + i = S->M * 2; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + acc0 = 0; + acc1 = 0; + + /* Initialize state pointer for all the samples */ + px0 = pState; + px1 = pState + S->M; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] and b[numTaps-2] coefficients */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* Read x[n-numTaps-1] and x[n-numTaps-2]sample */ + x0 = read_q15x2_ia (&px0); + x1 = read_q15x2_ia (&px1); + + /* Perform the multiply-accumulate */ + acc0 = __SMLALD(x0, c0, acc0); + acc1 = __SMLALD(x1, c0, acc1); + + /* Read the b[numTaps-3] and b[numTaps-4] coefficient */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* Read x[n-numTaps-2] and x[n-numTaps-3] sample */ + x0 = read_q15x2_ia (&px0); + x1 = read_q15x2_ia (&px1); + + /* Perform the multiply-accumulate */ + acc0 = __SMLALD(x0, c0, acc0); + acc1 = __SMLALD(x1, c0, acc1); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch state variables for acc0, acc1 */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 = __SMLALD(x0, c0, acc0); + acc1 = __SMLALD(x1, c0, acc1); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M * 2; + + /* Store filter output, smlad returns the values in 2.14 format */ + /* so downsacle by 15 to get output in 1.15 */ + *pDst++ = (q15_t) (__SSAT((acc0 >> 15), 16)); + *pDst++ = (q15_t) (__SSAT((acc1 >> 15), 16)); + + /* Decrement loop counter */ + blkCnt--; + } + + while (blkCntN3 > 0U) + { + /* Copy decimation factor number of new input samples into the state buffer */ + i = S->M; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + sum0 = 0; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] and b[numTaps-2] coefficients */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* Read x[n-numTaps-1] and x[n-numTaps-2] sample */ + x0 = read_q15x2_ia (&px); + + /* Read the b[numTaps-3] and b[numTaps-4] coefficients */ + c1 = read_q15x2_ia ((q15_t **) &pb); + + /* Perform the multiply-accumulate */ + sum0 = __SMLALD(x0, c0, sum0); + + /* Read x[n-numTaps-2] and x[n-numTaps-3] sample */ + x0 = read_q15x2_ia (&px); + + /* Perform the multiply-accumulate */ + sum0 = __SMLALD(x0, c1, sum0); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch 1 state variable */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 = __SMLALD(x0, c0, sum0); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M; + + /* Store filter output, smlad returns the values in 2.14 format */ + /* so downsacle by 15 to get output in 1.15 */ + *pDst++ = (q15_t) (__SSAT((sum0 >> 15), 16)); + + /* Decrement loop counter */ + blkCntN3--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the satrt of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + + i = (numTaps - 1U) >> 2U; + + /* copy data */ + while (i > 0U) + { + write_q15x2_ia (&pStateCur, read_q15x2_ia (&pState)); + write_q15x2_ia (&pStateCur, read_q15x2_ia (&pState)); + + /* Decrement loop counter */ + i--; + } + + i = (numTaps - 1U) % 0x04U; + + /* Copy data */ + while (i > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + i--; + } + +} + +#else /* #if defined (ARM_MATH_DSP) */ + +void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *pStateCur; /* Points to the current sample of the state */ + q15_t *px; /* Temporary pointer for state buffer */ + const q15_t *pb; /* Temporary pointer for coefficient buffer */ + q15_t x0, x1, c0; /* Temporary variables to hold state and coefficient values */ + q63_t sum0; /* Accumulators */ + q63_t acc0, acc1; + q15_t *px0, *px1; + uint32_t blkCntN3; + uint32_t numTaps = S->numTaps; /* Number of taps */ + uint32_t i, blkCnt, tapCnt, outBlockSize = blockSize / S->M; /* Loop counters */ + + + /* S->pState buffer contains previous frame (numTaps - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (numTaps - 1U); + + /* Total number of output samples to be computed */ + blkCnt = outBlockSize / 2; + blkCntN3 = outBlockSize - (2 * blkCnt); + + while (blkCnt > 0U) + { + /* Copy 2 * decimation factor number of new input samples into the state buffer */ + i = S->M * 2; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + acc0 = 0; + acc1 = 0; + + /* Initialize state pointer */ + px0 = pState; + px1 = pState + S->M; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the Read b[numTaps-1] coefficients */ + c0 = *pb++; + + /* Read x[n-numTaps-1] for sample 0 and for sample 1 */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + + /* Read the b[numTaps-2] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-2] for sample 0 and sample 1 */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + + /* Read the b[numTaps-3] coefficients */ + c0 = *pb++; + + /* Read x[n-numTaps-3] for sample 0 and sample 1 */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-4] for sample 0 and sample 1 */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch 1 state variable */ + x0 = *px0++; + x1 = *px1++; + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M * 2; + + /* Store filter output, smlad returns the values in 2.14 format */ + /* so downsacle by 15 to get output in 1.15 */ + + *pDst++ = (q15_t) (__SSAT((acc0 >> 15), 16)); + *pDst++ = (q15_t) (__SSAT((acc1 >> 15), 16)); + + /* Decrement loop counter */ + blkCnt--; + } + + while (blkCntN3 > 0U) + { + /* Copy decimation factor number of new input samples into the state buffer */ + i = S->M; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + sum0 = 0; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-1] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 += x0 * c0; + + /* Read the b[numTaps-2] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-2] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 += x0 * c0; + + /* Read the b[numTaps-3] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-3] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 += x0 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-4] sample */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 += x0 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch 1 state variable */ + x0 = *px++; + + /* Perform the multiply-accumulate */ + sum0 += x0 * c0; + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M; + + /* Store filter output, smlad returns the values in 2.14 format */ + /* so downsacle by 15 to get output in 1.15 */ + *pDst++ = (q15_t) (__SSAT((sum0 >> 15), 16)); + + /* Decrement loop counter */ + blkCntN3--; + } + + /* Processing is complete. + ** Now copy the last numTaps - 1 samples to the satrt of the state buffer. + ** This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + + i = (numTaps - 1U) >> 2U; + + /* copy data */ + while (i > 0U) + { + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + i--; + } + + i = (numTaps - 1U) % 0x04U; + + /* copy data */ + while (i > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + i--; + } +} + +#endif /* #if defined (ARM_MATH_DSP) */ + +/** + @} end of FIR_decimate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_q31.c new file mode 100644 index 0000000..7af8a44 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_decimate_q31.c @@ -0,0 +1,387 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_decimate_q31.c + * Description: Q31 FIR Decimator + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_decimate + @{ + */ + +/** + @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 samples to process + @return none + + @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 log2(numTaps) bits (where log2 is read as log to the base 2). + After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + + @remark + Refer to \ref arm_fir_decimate_fast_q31() for a faster but less precise implementation of this function. + */ + +void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + q31_t *pState = S->pState; /* State pointer */ + const q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t *pStateCur; /* Points to the current sample of the state */ + q31_t *px0; /* Temporary pointer for state buffer */ + const q31_t *pb; /* Temporary pointer for coefficient buffer */ + q31_t x0, c0; /* Temporary variables to hold state and coefficient values */ + q63_t acc0; /* Accumulator */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t i, tapCnt, blkCnt, outBlockSize = blockSize / S->M; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t *px1, *px2, *px3; + q31_t x1, x2, x3; + q63_t acc1, acc2, acc3; +#endif + + /* S->pState buffer contains previous frame (numTaps - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (numTaps - 1U); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 samples at a time */ + blkCnt = outBlockSize >> 2U; + + /* Samples loop unrolled by 4 */ + while (blkCnt > 0U) + { + /* Copy 4 * decimation factor number of new input samples into the state buffer */ + i = S->M * 4; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Initialize state pointer for all the samples */ + px0 = pState; + px1 = pState + S->M; + px2 = pState + 2 * S->M; + px3 = pState + 3 * S->M; + + /* Initialize coeff pointer */ + pb = pCoeffs; + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-1] sample for acc0 */ + x0 = *(px0++); + /* Read x[n-numTaps-1] sample for acc1 */ + x1 = *(px1++); + /* Read x[n-numTaps-1] sample for acc2 */ + x2 = *(px2++); + /* Read x[n-numTaps-1] sample for acc3 */ + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + acc1 += (q63_t) x1 * c0; + acc2 += (q63_t) x2 * c0; + acc3 += (q63_t) x3 * c0; + + /* Read the b[numTaps-2] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-2] sample for acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + acc1 += (q63_t) x1 * c0; + acc2 += (q63_t) x2 * c0; + acc3 += (q63_t) x3 * c0; + + /* Read the b[numTaps-3] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-3] sample acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + acc1 += (q63_t) x1 * c0; + acc2 += (q63_t) x2 * c0; + acc3 += (q63_t) x3 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-4] sample acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + acc1 += (q63_t) x1 * c0; + acc2 += (q63_t) x2 * c0; + acc3 += (q63_t) x3 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *(pb++); + + /* Fetch state variables for acc0, acc1, acc2, acc3 */ + x0 = *(px0++); + x1 = *(px1++); + x2 = *(px2++); + x3 = *(px3++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + acc1 += (q63_t) x1 * c0; + acc2 += (q63_t) x2 * c0; + acc3 += (q63_t) x3 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M * 4; + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = (q31_t) (acc0 >> 31); + *pDst++ = (q31_t) (acc1 >> 31); + *pDst++ = (q31_t) (acc2 >> 31); + *pDst++ = (q31_t) (acc3 >> 31); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining samples */ + blkCnt = outBlockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = outBlockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy decimation factor number of new input samples into the state buffer */ + i = S->M; + + do + { + *pStateCur++ = *pSrc++; + + } while (--i); + + /* Set accumulator to zero */ + acc0 = 0; + + /* Initialize state pointer */ + px0 = pState; + + /* Initialize coeff pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-1] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + + /* Read the b[numTaps-2] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-2] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + + /* Read the b[numTaps-3] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-3] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *pb++; + + /* Read x[n-numTaps-4] sample */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *pb++; + + /* Fetch 1 state variable */ + x0 = *px0++; + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by the decimation factor + * to process the next group of decimation factor number samples */ + pState = pState + S->M; + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = (q31_t) (acc0 >> 31); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the satrt of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = (numTaps - 1U) >> 2U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numTaps - 1U) % 0x04U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of FIR_decimate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_f32.c new file mode 100644 index 0000000..b368b04 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_f32.c @@ -0,0 +1,493 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_f32.c + * Description: Floating-point FIR filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup FIR Finite Impulse Response (FIR) Filters + + This set of functions implements Finite Impulse Response (FIR) filters + for Q7, Q15, Q31, and floating-point data types. Fast versions of Q15 and Q31 are also provided. + The functions operate on blocks of input and output data and each call to the function processes + blockSize samples through the filter. pSrc and + pDst points to input and output arrays containing blockSize values. + + @par Algorithm + The FIR filter algorithm is based upon a sequence of multiply-accumulate (MAC) operations. + Each filter coefficient b[n] is multiplied by a state variable which equals a previous input sample x[n]. +
+      y[n] = b[0] * x[n] + b[1] * x[n-1] + b[2] * x[n-2] + ...+ b[numTaps-1] * x[n-numTaps+1]
+  
+ @par + \image html FIR.GIF "Finite Impulse Response filter" + @par + pCoeffs points to a coefficient array of size numTaps. + Coefficients are stored in time reversed order. + @par +
+      {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ @par + pState points to a state array of size numTaps + blockSize - 1. + Samples in the state buffer are stored in the following order. + @par +
+      {x[n-numTaps+1], x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2]....x[0], x[1], ..., x[blockSize-1]}
+  
+ @par + Note that the length of the state buffer exceeds the length of the coefficient array by blockSize-1. + The increased state buffer length allows circular addressing, which is traditionally used in the FIR filters, + to be avoided and yields a significant speed improvement. + The state variables are updated after each block of data is processed; the coefficients are untouched. + + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter. + Coefficient arrays may be shared among several instances while state variable arrays cannot be shared. + There are separate instance structure declarations for each of the 4 supported data types. + + @par Initialization Functions + There is also an associated initialization function for each data type. + The initialization function performs the following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + numTaps, pCoeffs, pState. Also set all of the values in pState to zero. + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + Set the values in the state buffer to zeros before static initialization. + The code below statically initializes each of the 4 different data type filter instance structures +
+      arm_fir_instance_f32 S = {numTaps, pState, pCoeffs};
+      arm_fir_instance_q31 S = {numTaps, pState, pCoeffs};
+      arm_fir_instance_q15 S = {numTaps, pState, pCoeffs};
+      arm_fir_instance_q7 S =  {numTaps, pState, pCoeffs};
+  
+ where numTaps is the number of filter coefficients in the filter; pState is the address of the state buffer; + pCoeffs is the address of the coefficient buffer. + + @par Fixed-Point Behavior + Care must be taken when using the fixed-point versions of the FIR filter 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 FIR + @{ + */ + +/** + @brief Processing function for floating-point FIR filter. + @param[in] S points to an instance of the floating-point 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 + @return none + */ + +void arm_fir_f32( + const arm_fir_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + float32_t *pState = S->pState; /* State pointer */ + const float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t *pStateCurnt; /* Points to the current sample of the state */ + float32_t *px; /* Temporary pointer for state buffer */ + const float32_t *pb; /* Temporary pointer for coefficient buffer */ + float32_t acc0; /* Accumulator */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t i, tapCnt, blkCnt; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + float32_t acc1, acc2, acc3, acc4, acc5, acc6, acc7; /* Accumulators */ + float32_t x0, x1, x2, x3, x4, x5, x6, x7; /* Temporary variables to hold state values */ + float32_t c0; /* Temporary variable to hold coefficient value */ +#endif + + /* S->pState points to state array which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 8 output values simultaneously. + * The variables acc0 ... acc7 hold output values that are being computed: + * + * acc0 = b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0] + * acc1 = b[numTaps-1] * x[n-numTaps] + b[numTaps-2] * x[n-numTaps-1] + b[numTaps-3] * x[n-numTaps-2] +...+ b[0] * x[1] + * acc2 = b[numTaps-1] * x[n-numTaps+1] + b[numTaps-2] * x[n-numTaps] + b[numTaps-3] * x[n-numTaps-1] +...+ b[0] * x[2] + * acc3 = b[numTaps-1] * x[n-numTaps+2] + b[numTaps-2] * x[n-numTaps+1] + b[numTaps-3] * x[n-numTaps] +...+ b[0] * x[3] + */ + + blkCnt = blockSize >> 3U; + + while (blkCnt > 0U) + { + /* Copy 4 new input samples into the state buffer. */ + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + + /* Set all accumulators to zero */ + acc0 = 0.0f; + acc1 = 0.0f; + acc2 = 0.0f; + acc3 = 0.0f; + acc4 = 0.0f; + acc5 = 0.0f; + acc6 = 0.0f; + acc7 = 0.0f; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + + /* This is separated from the others to avoid + * a call to __aeabi_memmove which would be slower + */ + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + + /* Read the first 7 samples from the state buffer: x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2] */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + x3 = *px++; + x4 = *px++; + x5 = *px++; + x6 = *px++; + + /* Loop unrolling: process 8 taps at a time. */ + tapCnt = numTaps >> 3U; + + while (tapCnt > 0U) + { + /* Read the b[numTaps-1] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-3] sample */ + x7 = *(px++); + + /* acc0 += b[numTaps-1] * x[n-numTaps] */ + acc0 += x0 * c0; + + /* acc1 += b[numTaps-1] * x[n-numTaps-1] */ + acc1 += x1 * c0; + + /* acc2 += b[numTaps-1] * x[n-numTaps-2] */ + acc2 += x2 * c0; + + /* acc3 += b[numTaps-1] * x[n-numTaps-3] */ + acc3 += x3 * c0; + + /* acc4 += b[numTaps-1] * x[n-numTaps-4] */ + acc4 += x4 * c0; + + /* acc1 += b[numTaps-1] * x[n-numTaps-5] */ + acc5 += x5 * c0; + + /* acc2 += b[numTaps-1] * x[n-numTaps-6] */ + acc6 += x6 * c0; + + /* acc3 += b[numTaps-1] * x[n-numTaps-7] */ + acc7 += x7 * c0; + + /* Read the b[numTaps-2] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-4] sample */ + x0 = *(px++); + + /* Perform the multiply-accumulate */ + acc0 += x1 * c0; + acc1 += x2 * c0; + acc2 += x3 * c0; + acc3 += x4 * c0; + acc4 += x5 * c0; + acc5 += x6 * c0; + acc6 += x7 * c0; + acc7 += x0 * c0; + + /* Read the b[numTaps-3] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-5] sample */ + x1 = *(px++); + + /* Perform the multiply-accumulates */ + acc0 += x2 * c0; + acc1 += x3 * c0; + acc2 += x4 * c0; + acc3 += x5 * c0; + acc4 += x6 * c0; + acc5 += x7 * c0; + acc6 += x0 * c0; + acc7 += x1 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-6] sample */ + x2 = *(px++); + + /* Perform the multiply-accumulates */ + acc0 += x3 * c0; + acc1 += x4 * c0; + acc2 += x5 * c0; + acc3 += x6 * c0; + acc4 += x7 * c0; + acc5 += x0 * c0; + acc6 += x1 * c0; + acc7 += x2 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-6] sample */ + x3 = *(px++); + /* Perform the multiply-accumulates */ + acc0 += x4 * c0; + acc1 += x5 * c0; + acc2 += x6 * c0; + acc3 += x7 * c0; + acc4 += x0 * c0; + acc5 += x1 * c0; + acc6 += x2 * c0; + acc7 += x3 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-6] sample */ + x4 = *(px++); + + /* Perform the multiply-accumulates */ + acc0 += x5 * c0; + acc1 += x6 * c0; + acc2 += x7 * c0; + acc3 += x0 * c0; + acc4 += x1 * c0; + acc5 += x2 * c0; + acc6 += x3 * c0; + acc7 += x4 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-6] sample */ + x5 = *(px++); + + /* Perform the multiply-accumulates */ + acc0 += x6 * c0; + acc1 += x7 * c0; + acc2 += x0 * c0; + acc3 += x1 * c0; + acc4 += x2 * c0; + acc5 += x3 * c0; + acc6 += x4 * c0; + acc7 += x5 * c0; + + /* Read the b[numTaps-4] coefficient */ + c0 = *(pb++); + + /* Read x[n-numTaps-6] sample */ + x6 = *(px++); + + /* Perform the multiply-accumulates */ + acc0 += x7 * c0; + acc1 += x0 * c0; + acc2 += x1 * c0; + acc3 += x2 * c0; + acc4 += x3 * c0; + acc5 += x4 * c0; + acc6 += x5 * c0; + acc7 += x6 * c0; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + tapCnt = numTaps % 0x8U; + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *(pb++); + + /* Fetch 1 state variable */ + x7 = *(px++); + + /* Perform the multiply-accumulates */ + acc0 += x0 * c0; + acc1 += x1 * c0; + acc2 += x2 * c0; + acc3 += x3 * c0; + acc4 += x4 * c0; + acc5 += x5 * c0; + acc6 += x6 * c0; + acc7 += x7 * c0; + + /* Reuse the present sample states for next sample */ + x0 = x1; + x1 = x2; + x2 = x3; + x3 = x4; + x4 = x5; + x5 = x6; + x6 = x7; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by 8 to process the next group of 8 samples */ + pState = pState + 8; + + /* The results in the 8 accumulators, store in the destination buffer. */ + *pDst++ = acc0; + *pDst++ = acc1; + *pDst++ = acc2; + *pDst++ = acc3; + *pDst++ = acc4; + *pDst++ = acc5; + *pDst++ = acc6; + *pDst++ = acc7; + + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining output samples */ + blkCnt = blockSize % 0x8U; + +#else + + /* Initialize blkCnt with number of taps */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy one sample at a time into state buffer */ + *pStateCurnt++ = *pSrc++; + + /* Set the accumulator to zero */ + acc0 = 0.0f; + + /* Initialize state pointer */ + px = pState; + + /* Initialize Coefficient pointer */ + pb = pCoeffs; + + i = numTaps; + + /* Perform the multiply-accumulates */ + do + { + /* acc = b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0] */ + acc0 += *px++ * *pb++; + + i--; + } while (i > 0U); + + /* Store result in destination buffer. */ + *pDst++ = acc0; + + /* Advance state pointer by 1 for the next sample */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCurnt = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = (numTaps - 1U) >> 2U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Calculate remaining number of copies */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy remaining data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of FIR group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_fast_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_fast_q15.c new file mode 100644 index 0000000..5f8df95 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_fast_q15.c @@ -0,0 +1,332 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_fast_q15.c + * Description: Q15 Fast FIR filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR + @{ + */ + +/** + @brief Processing function for the 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 + @return none + + @par Scaling and Overflow Behavior + This fast version uses a 32-bit accumulator with 2.30 format. + The accumulator maintains full precision of the intermediate multiplication results but provides only a single guard bit. + Thus, if the accumulator result overflows it wraps around and distorts the result. + In order to avoid overflows completely the input signal must be scaled down by log2(numTaps) bits. + The 2.30 accumulator is then truncated to 2.15 format and saturated to yield the 1.15 result. + + @remark + Refer to \ref arm_fir_q15() for a slower implementation of this function which uses 64-bit accumulation to avoid wrap around distortion. Both the slow and the fast versions use the same instance structure. + Use function \ref arm_fir_init_q15() to initialize the filter structure. + */ + +void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *pStateCurnt; /* Points to the current sample of the state */ + q15_t *px; /* Temporary pointer for state buffer */ + const q15_t *pb; /* Temporary pointer for coefficient buffer */ + q31_t acc0; /* Accumulators */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t tapCnt, blkCnt; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc1, acc2, acc3; /* Accumulators */ + q31_t x0, x1, x2, c0; /* Temporary variables to hold state and coefficient values */ +#endif + + /* S->pState points to state array which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 output values simultaneously. + * The variables acc0 ... acc3 hold output values that are being computed: + * + * acc0 = b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0] + * acc1 = b[numTaps-1] * x[n-numTaps] + b[numTaps-2] * x[n-numTaps-1] + b[numTaps-3] * x[n-numTaps-2] +...+ b[0] * x[1] + * acc2 = b[numTaps-1] * x[n-numTaps+1] + b[numTaps-2] * x[n-numTaps] + b[numTaps-3] * x[n-numTaps-1] +...+ b[0] * x[2] + * acc3 = b[numTaps-1] * x[n-numTaps+2] + b[numTaps-2] * x[n-numTaps+1] + b[numTaps-3] * x[n-numTaps] +...+ b[0] * x[3] + */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Copy 4 new input samples into the state buffer. */ + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Typecast q15_t pointer to q31_t pointer for state reading in q31_t */ + px = pState; + + /* Typecast q15_t pointer to q31_t pointer for coefficient reading in q31_t */ + pb = pCoeffs; + + /* Read the first two samples from the state buffer: x[n-N], x[n-N-1] */ + x0 = read_q15x2_ia (&px); + + /* Read the third and forth samples from the state buffer: x[n-N-2], x[n-N-3] */ + x2 = read_q15x2_ia (&px); + + /* Loop over the number of taps. Unroll by a factor of 4. + Repeat until we've computed numTaps-(numTaps%4) coefficients. */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the first two coefficients using SIMD: b[N] and b[N-1] coefficients */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* acc0 += b[N] * x[n-N] + b[N-1] * x[n-N-1] */ + acc0 = __SMLAD(x0, c0, acc0); + + /* acc2 += b[N] * x[n-N-2] + b[N-1] * x[n-N-3] */ + acc2 = __SMLAD(x2, c0, acc2); + + /* pack x[n-N-1] and x[n-N-2] */ +#ifndef ARM_MATH_BIG_ENDIAN + x1 = __PKHBT(x2, x0, 0); +#else + x1 = __PKHBT(x0, x2, 0); +#endif + + /* Read state x[n-N-4], x[n-N-5] */ + x0 = read_q15x2_ia (&px); + + /* acc1 += b[N] * x[n-N-1] + b[N-1] * x[n-N-2] */ + acc1 = __SMLADX(x1, c0, acc1); + + /* pack x[n-N-3] and x[n-N-4] */ +#ifndef ARM_MATH_BIG_ENDIAN + x1 = __PKHBT(x0, x2, 0); +#else + x1 = __PKHBT(x2, x0, 0); +#endif + + /* acc3 += b[N] * x[n-N-3] + b[N-1] * x[n-N-4] */ + acc3 = __SMLADX(x1, c0, acc3); + + /* Read coefficients b[N-2], b[N-3] */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* acc0 += b[N-2] * x[n-N-2] + b[N-3] * x[n-N-3] */ + acc0 = __SMLAD(x2, c0, acc0); + + /* Read state x[n-N-6], x[n-N-7] with offset */ + x2 = read_q15x2_ia (&px); + + /* acc2 += b[N-2] * x[n-N-4] + b[N-3] * x[n-N-5] */ + acc2 = __SMLAD(x0, c0, acc2); + + /* acc1 += b[N-2] * x[n-N-3] + b[N-3] * x[n-N-4] */ + acc1 = __SMLADX(x1, c0, acc1); + + /* pack x[n-N-5] and x[n-N-6] */ +#ifndef ARM_MATH_BIG_ENDIAN + x1 = __PKHBT(x2, x0, 0); +#else + x1 = __PKHBT(x0, x2, 0); +#endif + + /* acc3 += b[N-2] * x[n-N-5] + b[N-3] * x[n-N-6] */ + acc3 = __SMLADX(x1, c0, acc3); + + /* Decrement tap count */ + tapCnt--; + } + + /* If the filter length is not a multiple of 4, compute the remaining filter taps. + This is always be 2 taps since the filter length is even. */ + if ((numTaps & 0x3U) != 0U) + { + /* Read last two coefficients */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* Perform the multiply-accumulates */ + acc0 = __SMLAD(x0, c0, acc0); + acc2 = __SMLAD(x2, c0, acc2); + + /* pack state variables */ +#ifndef ARM_MATH_BIG_ENDIAN + x1 = __PKHBT(x2, x0, 0); +#else + x1 = __PKHBT(x0, x2, 0); +#endif + + /* Read last state variables */ + x0 = read_q15x2 (px); + + /* Perform the multiply-accumulates */ + acc1 = __SMLADX(x1, c0, acc1); + + /* pack state variables */ +#ifndef ARM_MATH_BIG_ENDIAN + x1 = __PKHBT(x0, x2, 0); +#else + x1 = __PKHBT(x2, x0, 0); +#endif + + /* Perform the multiply-accumulates */ + acc3 = __SMLADX(x1, c0, acc3); + } + + /* The results in the 4 accumulators are in 2.30 format. Convert to 1.15 with saturation. + Then store the 4 outputs in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pDst, __PKHBT(__SSAT((acc0 >> 15), 16), __SSAT((acc1 >> 15), 16), 16)); + write_q15x2_ia (&pDst, __PKHBT(__SSAT((acc2 >> 15), 16), __SSAT((acc3 >> 15), 16), 16)); +#else + write_q15x2_ia (&pDst, __PKHBT(__SSAT((acc1 >> 15), 16), __SSAT((acc0 >> 15), 16), 16)); + write_q15x2_ia (&pDst, __PKHBT(__SSAT((acc3 >> 15), 16), __SSAT((acc2 >> 15), 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Advance the state pointer by 4 to process the next group of 4 samples */ + pState = pState + 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining output samples */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of taps */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy two samples into state buffer */ + *pStateCurnt++ = *pSrc++; + + /* Set the accumulator to zero */ + acc0 = 0; + + /* Use SIMD to hold states and coefficients */ + px = pState; + pb = pCoeffs; + + tapCnt = numTaps >> 1U; + + do + { + acc0 += (q31_t) *px++ * *pb++; + acc0 += (q31_t) *px++ * *pb++; + + tapCnt--; + } + while (tapCnt > 0U); + + /* The result is in 2.30 format. Convert to 1.15 with saturation. + Then store the output in the destination buffer. */ + *pDst++ = (q15_t) (__SSAT((acc0 >> 15), 16)); + + /* Advance state pointer by 1 for the next sample */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCurnt = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = (numTaps - 1U) >> 2U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Calculate remaining number of copies */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy remaining data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of FIR group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_fast_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_fast_q31.c new file mode 100644 index 0000000..513cb72 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_fast_q31.c @@ -0,0 +1,324 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_fast_q31.c + * Description: Processing function for the Q31 Fast FIR filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR + @{ + */ + +/** + @brief Processing function for the Q31 FIR filter (fast version). + @param[in] S points to an instance of the Q31 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 + @return none + + @par Scaling and Overflow Behavior + This function is optimized for speed at the expense of fixed-point precision and overflow protection. + The result of each 1.31 x 1.31 multiplication is truncated to 2.30 format. + These intermediate results are added to a 2.30 accumulator. + Finally, the accumulator is saturated and converted to a 1.31 result. + The fast version has the same overflow behavior as the standard version and provides less precision since it discards the low 32 bits of each multiplication result. + In order to avoid overflows completely the input signal must be scaled down by log2(numTaps) bits. + + @remark + Refer to \ref arm_fir_q31() for a slower implementation of this function which uses a 64-bit accumulator to provide higher precision. Both the slow and the fast versions use the same instance structure. + Use function \ref arm_fir_init_q31() to initialize the filter structure. + */ + +IAR_ONLY_LOW_OPTIMIZATION_ENTER +void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + q31_t *pState = S->pState; /* State pointer */ + const q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t *pStateCurnt; /* Points to the current sample of the state */ + q31_t *px; /* Temporary pointer for state buffer */ + const q31_t *pb; /* Temporary pointer for coefficient buffer */ + q31_t acc0; /* Accumulators */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t i, tapCnt, blkCnt; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc1, acc2, acc3; /* Accumulators */ + q31_t x0, x1, x2, x3, c0; /* Temporary variables to hold state and coefficient values */ +#endif + + /* S->pState points to state array which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 output values simultaneously. + * The variables acc0 ... acc3 hold output values that are being computed: + * + * acc0 = b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0] + * acc1 = b[numTaps-1] * x[n-numTaps] + b[numTaps-2] * x[n-numTaps-1] + b[numTaps-3] * x[n-numTaps-2] +...+ b[0] * x[1] + * acc2 = b[numTaps-1] * x[n-numTaps+1] + b[numTaps-2] * x[n-numTaps] + b[numTaps-3] * x[n-numTaps-1] +...+ b[0] * x[2] + * acc3 = b[numTaps-1] * x[n-numTaps+2] + b[numTaps-2] * x[n-numTaps+1] + b[numTaps-3] * x[n-numTaps] +...+ b[0] * x[3] + */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Copy 4 new input samples into the state buffer. */ + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + + /* Read the first 3 samples from the state buffer: + * x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2] */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Loop unrolling. Process 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + /* Loop over the number of taps. Unroll by a factor of 4. + Repeat until we've computed numTaps-4 coefficients. */ + while (tapCnt > 0U) + { + /* Read the b[numTaps] coefficient */ + c0 = *pb; + + /* Read x[n-numTaps-3] sample */ + x3 = *px; + + /* acc0 += b[numTaps] * x[n-numTaps] */ + multAcc_32x32_keep32_R(acc0, x0, c0); + + /* acc1 += b[numTaps] * x[n-numTaps-1] */ + multAcc_32x32_keep32_R(acc1, x1, c0); + + /* acc2 += b[numTaps] * x[n-numTaps-2] */ + multAcc_32x32_keep32_R(acc2, x2, c0); + + /* acc3 += b[numTaps] * x[n-numTaps-3] */ + multAcc_32x32_keep32_R(acc3, x3, c0); + + /* Read the b[numTaps-1] coefficient */ + c0 = *(pb + 1U); + + /* Read x[n-numTaps-4] sample */ + x0 = *(px + 1U); + + /* Perform the multiply-accumulates */ + multAcc_32x32_keep32_R(acc0, x1, c0); + multAcc_32x32_keep32_R(acc1, x2, c0); + multAcc_32x32_keep32_R(acc2, x3, c0); + multAcc_32x32_keep32_R(acc3, x0, c0); + + /* Read the b[numTaps-2] coefficient */ + c0 = *(pb + 2U); + + /* Read x[n-numTaps-5] sample */ + x1 = *(px + 2U); + + /* Perform the multiply-accumulates */ + multAcc_32x32_keep32_R(acc0, x2, c0); + multAcc_32x32_keep32_R(acc1, x3, c0); + multAcc_32x32_keep32_R(acc2, x0, c0); + multAcc_32x32_keep32_R(acc3, x1, c0); + + /* Read the b[numTaps-3] coefficients */ + c0 = *(pb + 3U); + + /* Read x[n-numTaps-6] sample */ + x2 = *(px + 3U); + + /* Perform the multiply-accumulates */ + multAcc_32x32_keep32_R(acc0, x3, c0); + multAcc_32x32_keep32_R(acc1, x0, c0); + multAcc_32x32_keep32_R(acc2, x1, c0); + multAcc_32x32_keep32_R(acc3, x2, c0); + + /* update coefficient pointer */ + pb += 4U; + px += 4U; + + /* Decrement loop counter */ + tapCnt--; + } + + /* If the filter length is not a multiple of 4, compute the remaining filter taps */ + tapCnt = numTaps % 0x4U; + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *(pb++); + + /* Fetch 1 state variable */ + x3 = *(px++); + + /* Perform the multiply-accumulates */ + multAcc_32x32_keep32_R(acc0, x0, c0); + multAcc_32x32_keep32_R(acc1, x1, c0); + multAcc_32x32_keep32_R(acc2, x2, c0); + multAcc_32x32_keep32_R(acc3, x3, c0); + + /* Reuse the present sample states for next sample */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement loop counter */ + tapCnt--; + } + + /* The results in the 4 accumulators are in 2.30 format. Convert to 1.31 + Then store the 4 outputs in the destination buffer. */ + *pDst++ = (q31_t) (acc0 << 1); + *pDst++ = (q31_t) (acc1 << 1); + *pDst++ = (q31_t) (acc2 << 1); + *pDst++ = (q31_t) (acc3 << 1); + + /* Advance the state pointer by 4 to process the next group of 4 samples */ + pState = pState + 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining output samples */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of taps */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy one sample at a time into state buffer */ + *pStateCurnt++ = *pSrc++; + + /* Set the accumulator to zero */ + acc0 = 0; + + /* Initialize state pointer */ + px = pState; + + /* Initialize Coefficient pointer */ + pb = pCoeffs; + + i = numTaps; + + /* Perform the multiply-accumulates */ + do + { + multAcc_32x32_keep32_R(acc0, (*px++), (*pb++)); + i--; + } while (i > 0U); + + /* The result is in 2.30 format. Convert to 1.31 + Then store the output in the destination buffer. */ + *pDst++ = (q31_t) (acc0 << 1); + + /* Advance state pointer by 1 for the next sample */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCurnt = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = (numTaps - 1U) >> 2U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Calculate remaining number of copies */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy remaining data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement the loop counter */ + tapCnt--; + } + +} +IAR_ONLY_LOW_OPTIMIZATION_EXIT +/** + @} end of FIR group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_f32.c new file mode 100644 index 0000000..02e82ad --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_f32.c @@ -0,0 +1,81 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_init_f32.c + * Description: Floating-point FIR filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR + @{ + */ + +/** + @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 buffer + @param[in] pState points to the state buffer + @param[in] blockSize number of samples processed per call + @return none + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+      {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ @par + pState points to the array of state variables. + pState is of length numTaps+blockSize-1 samples, where blockSize is the number of input samples processed by each call to arm_fir_f32(). + */ + +void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer. The size is always (blockSize + numTaps - 1) */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of FIR group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q15.c new file mode 100644 index 0000000..a5b2d06 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q15.c @@ -0,0 +1,137 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_init_q15.c + * Description: Q15 FIR filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR + @{ + */ + +/** + @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 buffer. + @param[in] pState points to the state buffer. + @param[in] blockSize number of samples processed per call. + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : numTaps is not greater than or equal to 4 and even + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+      {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ Note that numTaps must be even and greater than or equal to 4. + To implement an odd length filter simply increase numTaps by 1 and set the last coefficient to zero. + For example, to implement a filter with numTaps=3 and coefficients +
+      {0.3, -0.8, 0.3}
+  
+ set numTaps=4 and use the coefficients: +
+      {0.3, -0.8, 0.3, 0}.
+  
+ Similarly, to implement a two point filter +
+      {0.3, -0.3}
+  
+ set numTaps=4 and use the coefficients: +
+      {0.3, -0.3, 0, 0}.
+  
+ pState points to the array of state variables. + pState is of length numTaps+blockSize, when running on Cortex-M4 and Cortex-M3 and is of length numTaps+blockSize-1, when running on Cortex-M0 where blockSize is the number of input samples processed by each call to arm_fir_q15(). + */ + +arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize) +{ + arm_status status; + +#if defined (ARM_MATH_DSP) + + /* The Number of filter coefficients in the filter must be even and at least 4 */ + if (numTaps & 0x1U) + { + status = ARM_MATH_ARGUMENT_ERROR; + } + else + { + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear the state buffer. The size is always (blockSize + numTaps ) */ + memset(pState, 0, (numTaps + (blockSize)) * sizeof(q15_t)); + + /* Assign state pointer */ + S->pState = pState; + + status = ARM_MATH_SUCCESS; + } + + return (status); + +#else + + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer. The size is always (blockSize + numTaps - 1) */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(q15_t)); + + /* Assign state pointer */ + S->pState = pState; + + status = ARM_MATH_SUCCESS; + + return (status); + +#endif /* #if defined (ARM_MATH_DSP) */ + +} + +/** + @} end of FIR group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q31.c new file mode 100644 index 0000000..7d8376f --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q31.c @@ -0,0 +1,80 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_init_q31.c + * Description: Q31 FIR filter initialization function. + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR + @{ + */ + +/** + @brief Initialization function for the Q31 FIR filter. + @param[in,out] S points to an instance of the Q31 FIR filter structure + @param[in] numTaps number of filter coefficients in the filter + @param[in] pCoeffs points to the filter coefficients buffer + @param[in] pState points to the state buffer + @param[in] blockSize number of samples processed + @return none + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+      {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ pState points to the array of state variables. + pState is of length numTaps+blockSize-1 samples, where blockSize is the number of input samples processed by each call to arm_fir_q31(). + */ + +void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer. The size is always (blockSize + numTaps - 1) */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(q31_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of FIR group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q7.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q7.c new file mode 100644 index 0000000..f96d250 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_init_q7.c @@ -0,0 +1,81 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_init_q7.c + * Description: Q7 FIR filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR + @{ + */ + +/** + @brief Initialization function for the Q7 FIR filter. + @param[in,out] S points to an instance of the Q7 FIR filter structure + @param[in] numTaps number of filter coefficients in the filter + @param[in] pCoeffs points to the filter coefficients buffer + @param[in] pState points to the state buffer + @param[in] blockSize number of samples processed + @return none + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+      {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ @par + pState points to the array of state variables. + pState is of length numTaps+blockSize-1 samples, where blockSize is the number of input samples processed by each call to arm_fir_q7(). + */ + +void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer. The size is always (blockSize + numTaps - 1) */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(q7_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of FIR group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_f32.c new file mode 100644 index 0000000..91ef699 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_f32.c @@ -0,0 +1,556 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_interpolate_f32.c + * Description: Floating-point FIR interpolation sequences + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @defgroup FIR_Interpolate Finite Impulse Response (FIR) Interpolator + + These functions combine an upsampler (zero stuffer) and an FIR filter. + They are used in multirate systems for increasing the sample rate of a signal without introducing high frequency images. + Conceptually, the functions are equivalent to the block diagram below: + \image html FIRInterpolator.gif "Components included in the FIR Interpolator functions" + After upsampling by a factor of L, the signal should be filtered by a lowpass filter with a normalized + cutoff frequency of 1/L in order to eliminate high frequency copies of the spectrum. + The user of the function is responsible for providing the filter coefficients. + + The FIR interpolator functions provided in the CMSIS DSP Library combine the upsampler and FIR filter in an efficient manner. + The upsampler inserts L-1 zeros between each sample. + Instead of multiplying by these zero values, the FIR filter is designed to skip them. + This leads to an efficient implementation without any wasted effort. + The functions operate on blocks of input and output data. + pSrc points to an array of blockSize input values and + pDst points to an array of blockSize*L output values. + + The library provides separate functions for Q15, Q31, and floating-point data types. + + @par Algorithm + The functions use a polyphase filter structure: +
+      y[n] = b[0] * x[n] + b[L]   * x[n-1] + ... + b[L*(phaseLength-1)] * x[n-phaseLength+1]
+      y[n+1] = b[1] * x[n] + b[L+1] * x[n-1] + ... + b[L*(phaseLength-1)+1] * x[n-phaseLength+1]
+      ...
+      y[n+(L-1)] = b[L-1] * x[n] + b[2*L-1] * x[n-1] + ....+ b[L*(phaseLength-1)+(L-1)] * x[n-phaseLength+1]
+  
+ This approach is more efficient than straightforward upsample-then-filter algorithms. + With this method the computation is reduced by a factor of 1/L when compared to using a standard FIR filter. + @par + pCoeffs points to a coefficient array of size numTaps. + numTaps must be a multiple of the interpolation factor L and this is checked by the + initialization functions. + Internally, the function divides the FIR filter's impulse response into shorter filters of length + phaseLength=numTaps/L. + Coefficients are stored in time reversed order. +
+      {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ @par + pState points to a state array of size blockSize + phaseLength - 1. + Samples in the state buffer are stored in the order: +
+     {x[n-phaseLength+1], x[n-phaseLength], x[n-phaseLength-1], x[n-phaseLength-2]....x[0], x[1], ..., x[blockSize-1]}
+  
+ @par + The state variables are updated after each block of data is processed, the coefficients are untouched. + + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter. + Coefficient arrays may be shared among several instances while state variable array should be allocated separately. + There are separate instance structure declarations for each of the 3 supported data types. + + @par Initialization Functions + There is also an associated initialization function for each data type. + The initialization function performs the following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + - Checks to make sure that the length of the filter is a multiple of the interpolation factor. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + L (interpolation factor), pCoeffs, phaseLength (numTaps / L), pState. Also set all of the values in pState to zero. + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + The code below statically initializes each of the 3 different data type filter instance structures +
+      arm_fir_interpolate_instance_f32 S = {L, phaseLength, pCoeffs, pState};
+      arm_fir_interpolate_instance_q31 S = {L, phaseLength, pCoeffs, pState};
+      arm_fir_interpolate_instance_q15 S = {L, phaseLength, pCoeffs, pState};
+  
+ @par + where L is the interpolation factor; phaseLength=numTaps/L is the + length of each of the shorter FIR filters used internally, + pCoeffs is the address of the coefficient buffer; + pState is the address of the state buffer. + Be sure to set the values in the state buffer to zeros when doing static initialization. + + @par Fixed-Point Behavior + Care must be taken when using the fixed-point versions of the FIR interpolate filter 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 FIR_Interpolate + @{ + */ + +/** + @brief Processing function for 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 samples to process + @return none + */ + +void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + float32_t *pState = S->pState; /* State pointer */ + const float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t *pStateCur; /* Points to the current sample of the state */ + float32_t *ptr1; /* Temporary pointer for state buffer */ + const float32_t *ptr2; /* Temporary pointer for coefficient buffer */ + float32_t sum0; /* Accumulators */ + uint32_t i, blkCnt, tapCnt; /* Loop counters */ + uint32_t phaseLen = S->phaseLength; /* Length of each polyphase filter component */ + uint32_t j; + +#if defined (ARM_MATH_LOOPUNROLL) + float32_t acc0, acc1, acc2, acc3; + float32_t x0, x1, x2, x3; + float32_t c0, c1, c2, c3; +#endif + + /* S->pState buffer contains previous frame (phaseLen - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (phaseLen - 1U); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Copy new input sample into the state buffer */ + *pStateCur++ = *pSrc++; + *pStateCur++ = *pSrc++; + *pStateCur++ = *pSrc++; + *pStateCur++ = *pSrc++; + + /* Address modifier index of coefficient buffer */ + j = 1U; + + /* Loop over the Interpolation factor. */ + i = (S->L); + + while (i > 0U) + { + /* Set accumulator to zero */ + acc0 = 0.0f; + acc1 = 0.0f; + acc2 = 0.0f; + acc3 = 0.0f; + + /* Initialize state pointer */ + ptr1 = pState; + + /* Initialize coefficient pointer */ + ptr2 = pCoeffs + (S->L - j); + + /* Loop over the polyPhase length. Unroll by a factor of 4. + Repeat until we've computed numTaps-(4*S->L) coefficients. */ + tapCnt = phaseLen >> 2U; + + x0 = *(ptr1++); + x1 = *(ptr1++); + x2 = *(ptr1++); + + while (tapCnt > 0U) + { + /* Read the input sample */ + x3 = *(ptr1++); + + /* Read the coefficient */ + c0 = *(ptr2); + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + acc2 += x2 * c0; + acc3 += x3 * c0; + + /* Read the coefficient */ + c1 = *(ptr2 + S->L); + + /* Read the input sample */ + x0 = *(ptr1++); + + /* Perform the multiply-accumulate */ + acc0 += x1 * c1; + acc1 += x2 * c1; + acc2 += x3 * c1; + acc3 += x0 * c1; + + /* Read the coefficient */ + c2 = *(ptr2 + S->L * 2); + + /* Read the input sample */ + x1 = *(ptr1++); + + /* Perform the multiply-accumulate */ + acc0 += x2 * c2; + acc1 += x3 * c2; + acc2 += x0 * c2; + acc3 += x1 * c2; + + /* Read the coefficient */ + c3 = *(ptr2 + S->L * 3); + + /* Read the input sample */ + x2 = *(ptr1++); + + /* Perform the multiply-accumulate */ + acc0 += x3 * c3; + acc1 += x0 * c3; + acc2 += x1 * c3; + acc3 += x2 * c3; + + + /* Upsampling is done by stuffing L-1 zeros between each sample. + * So instead of multiplying zeros with coefficients, + * Increment the coefficient pointer by interpolation factor times. */ + ptr2 += 4 * S->L; + + /* Decrement loop counter */ + tapCnt--; + } + + /* If the polyPhase length is not a multiple of 4, compute the remaining filter taps */ + tapCnt = phaseLen % 0x4U; + + while (tapCnt > 0U) + { + /* Read the input sample */ + x3 = *(ptr1++); + + /* Read the coefficient */ + c0 = *(ptr2); + + /* Perform the multiply-accumulate */ + acc0 += x0 * c0; + acc1 += x1 * c0; + acc2 += x2 * c0; + acc3 += x3 * c0; + + /* Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + /* update states for next sample processing */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement loop counter */ + tapCnt--; + } + + /* The result is in the accumulator, store in the destination buffer. */ + *(pDst ) = acc0; + *(pDst + S->L) = acc1; + *(pDst + 2 * S->L) = acc2; + *(pDst + 3 * S->L) = acc3; + + pDst++; + + /* Increment the address modifier index of coefficient buffer */ + j++; + + /* Decrement loop counter */ + i--; + } + + /* Advance the state pointer by 1 + * to process the next group of interpolation factor number samples */ + pState = pState + 4; + + pDst += S->L * 3; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy new input sample into the state buffer */ + *pStateCur++ = *pSrc++; + + /* Address modifier index of coefficient buffer */ + j = 1U; + + /* Loop over the Interpolation factor. */ + i = S->L; + while (i > 0U) + { + /* Set accumulator to zero */ + sum0 = 0.0f; + + /* Initialize state pointer */ + ptr1 = pState; + + /* Initialize coefficient pointer */ + ptr2 = pCoeffs + (S->L - j); + + /* Loop over the polyPhase length. + Repeat until we've computed numTaps-(4*S->L) coefficients. */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + tapCnt = phaseLen >> 2U; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + sum0 += *ptr1++ * *ptr2; + + /* Upsampling is done by stuffing L-1 zeros between each sample. + * So instead of multiplying zeros with coefficients, + * Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + sum0 += *ptr1++ * *ptr2; + ptr2 += S->L; + + sum0 += *ptr1++ * *ptr2; + ptr2 += S->L; + + sum0 += *ptr1++ * *ptr2; + ptr2 += S->L; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + tapCnt = phaseLen % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = phaseLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + sum0 += *ptr1++ * *ptr2; + + /* Upsampling is done by stuffing L-1 zeros between each sample. + * So instead of multiplying zeros with coefficients, + * Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + /* Decrement loop counter */ + tapCnt--; + } + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = sum0; + + /* Increment the address modifier index of coefficient buffer */ + j++; + + /* Decrement the loop counter */ + i--; + } + + /* Advance the state pointer by 1 + * to process the next group of interpolation factor number samples */ + pState = pState + 1; + + /* Decrement the loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last phaseLen - 1 samples to the satrt of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + tapCnt = (phaseLen - 1U) >> 2U; + + /* copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + tapCnt = (phaseLen - 1U) % 0x04U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = (phaseLen - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +#else +/* alternate version for CM0_FAMILY */ + + float32_t *pState = S->pState; /* State pointer */ + const float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t *pStateCur; /* Points to the current sample of the state */ + float32_t *ptr1; /* Temporary pointer for state buffer */ + const float32_t *ptr2; /* Temporary pointer for coefficient buffer */ + float32_t sum0; /* Accumulators */ + uint32_t i, blkCnt, tapCnt; /* Loop counters */ + uint32_t phaseLen = S->phaseLength; /* Length of each polyphase filter component */ + + /* S->pState buffer contains previous frame (phaseLen - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (phaseLen - 1U); + + /* Total number of intput samples */ + blkCnt = blockSize; + + /* Loop over the blockSize. */ + while (blkCnt > 0U) + { + /* Copy new input sample into the state buffer */ + *pStateCur++ = *pSrc++; + + /* Loop over the Interpolation factor. */ + i = S->L; + + while (i > 0U) + { + /* Set accumulator to zero */ + sum0 = 0.0f; + + /* Initialize state pointer */ + ptr1 = pState; + + /* Initialize coefficient pointer */ + ptr2 = pCoeffs + (i - 1U); + + /* Loop over the polyPhase length */ + tapCnt = phaseLen; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + sum0 += *ptr1++ * *ptr2; + + /* Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + /* Decrement the loop counter */ + tapCnt--; + } + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = sum0; + + /* Decrement loop counter */ + i--; + } + + /* Advance the state pointer by 1 + * to process the next group of interpolation factor number samples */ + pState = pState + 1; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + ** Now copy the last phaseLen - 1 samples to the start of the state buffer. + ** This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + + tapCnt = phaseLen - 1U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of FIR_Interpolate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_f32.c new file mode 100644 index 0000000..287d347 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_f32.c @@ -0,0 +1,106 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_interpolate_init_f32.c + * Description: Floating-point FIR interpolator initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Interpolate + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : filter length numTaps is not a multiple of the interpolation factor L + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+      {b[numTaps-1], b[numTaps-2], b[numTaps-2], ..., b[1], b[0]}
+  
+ @par + The length of the filter numTaps must be a multiple of the interpolation factor L. + @par + pState points to the array of state variables. + pState is of length (numTaps/L)+blockSize-1 words + where blockSize is the number of input samples processed by each call to arm_fir_interpolate_f32(). + */ + +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) +{ + arm_status status; + + /* The filter length must be a multiple of the interpolation factor */ + if ((numTaps % L) != 0U) + { + /* Set status as ARM_MATH_LENGTH_ERROR */ + status = ARM_MATH_LENGTH_ERROR; + } + else + { + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Assign Interpolation factor */ + S->L = L; + + /* Assign polyPhaseLength */ + S->phaseLength = numTaps / L; + + /* Clear state buffer and size of buffer is always phaseLength + blockSize - 1 */ + memset(pState, 0, (blockSize + ((uint32_t) S->phaseLength - 1U)) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; + + status = ARM_MATH_SUCCESS; + } + + return (status); +} + +/** + @} end of FIR_Interpolate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_q15.c new file mode 100644 index 0000000..7f43bbf --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_q15.c @@ -0,0 +1,106 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_interpolate_init_q15.c + * Description: Q15 FIR interpolator initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Interpolate + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : filter length numTaps is not a multiple of the interpolation factor L + + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+      {b[numTaps-1], b[numTaps-2], b[numTaps-2], ..., b[1], b[0]}
+  
+ The length of the filter numTaps must be a multiple of the interpolation factor L. + @par + pState points to the array of state variables. + pState is of length (numTaps/L)+blockSize-1 words + where blockSize is the number of input samples processed by each call to arm_fir_interpolate_q15(). + */ + +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) +{ + arm_status status; + + /* The filter length must be a multiple of the interpolation factor */ + if ((numTaps % L) != 0U) + { + /* Set status as ARM_MATH_LENGTH_ERROR */ + status = ARM_MATH_LENGTH_ERROR; + } + else + { + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Assign Interpolation factor */ + S->L = L; + + /* Assign polyPhaseLength */ + S->phaseLength = numTaps / L; + + /* Clear state buffer and size of buffer is always phaseLength + blockSize - 1 */ + memset(pState, 0, (blockSize + ((uint32_t) S->phaseLength - 1U)) * sizeof(q15_t)); + + /* Assign state pointer */ + S->pState = pState; + + status = ARM_MATH_SUCCESS; + } + + return (status); +} + +/** + @} end of FIR_Interpolate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_q31.c new file mode 100644 index 0000000..973e715 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_init_q31.c @@ -0,0 +1,105 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_interpolate_init_q31.c + * Description: Q31 FIR interpolator initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Interpolate + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : filter length numTaps is not a multiple of the interpolation factor L + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+      {b[numTaps-1], b[numTaps-2], b[numTaps-2], ..., b[1], b[0]}
+  
+ The length of the filter numTaps must be a multiple of the interpolation factor L. + @par + pState points to the array of state variables. + pState is of length (numTaps/L)+blockSize-1 words + where blockSize is the number of input samples processed by each call to arm_fir_interpolate_q31(). + */ + +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) +{ + arm_status status; + + /* The filter length must be a multiple of the interpolation factor */ + if ((numTaps % L) != 0U) + { + /* Set status as ARM_MATH_LENGTH_ERROR */ + status = ARM_MATH_LENGTH_ERROR; + } + else + { + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Assign Interpolation factor */ + S->L = L; + + /* Assign polyPhaseLength */ + S->phaseLength = numTaps / L; + + /* Clear state buffer and size of buffer is always phaseLength + blockSize - 1 */ + memset(pState, 0, (blockSize + ((uint32_t) S->phaseLength - 1U)) * sizeof(q31_t)); + + /* Assign state pointer */ + S->pState = pState; + + status = ARM_MATH_SUCCESS; + } + + return (status); +} + +/** + @} end of FIR_Interpolate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_q15.c new file mode 100644 index 0000000..7efec94 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_q15.c @@ -0,0 +1,479 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_interpolate_q15.c + * Description: Q15 FIR interpolation + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Interpolate + @{ + */ + +/** + @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 samples to process + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both coefficients 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. + */ + +void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *pStateCur; /* Points to the current sample of the state */ + q15_t *ptr1; /* Temporary pointer for state buffer */ + const q15_t *ptr2; /* Temporary pointer for coefficient buffer */ + q63_t sum0; /* Accumulators */ + uint32_t i, blkCnt, tapCnt; /* Loop counters */ + uint32_t phaseLen = S->phaseLength; /* Length of each polyphase filter component */ + uint32_t j; + +#if defined (ARM_MATH_LOOPUNROLL) + q63_t acc0, acc1, acc2, acc3; + q15_t x0, x1, x2, x3; + q15_t c0, c1, c2, c3; +#endif + + /* S->pState buffer contains previous frame (phaseLen - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (phaseLen - 1U); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Copy new input sample into the state buffer */ + *pStateCur++ = *pSrc++; + *pStateCur++ = *pSrc++; + *pStateCur++ = *pSrc++; + *pStateCur++ = *pSrc++; + + /* Address modifier index of coefficient buffer */ + j = 1U; + + /* Loop over the Interpolation factor. */ + i = (S->L); + + while (i > 0U) + { + /* Set accumulator to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Initialize state pointer */ + ptr1 = pState; + + /* Initialize coefficient pointer */ + ptr2 = pCoeffs + (S->L - j); + + /* Loop over the polyPhase length. Unroll by a factor of 4. + Repeat until we've computed numTaps-(4*S->L) coefficients. */ + tapCnt = phaseLen >> 2U; + + x0 = *(ptr1++); + x1 = *(ptr1++); + x2 = *(ptr1++); + + while (tapCnt > 0U) + { + /* Read the input sample */ + x3 = *(ptr1++); + + /* Read the coefficient */ + c0 = *(ptr2); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + acc1 += (q63_t) x1 * c0; + acc2 += (q63_t) x2 * c0; + acc3 += (q63_t) x3 * c0; + + /* Read the coefficient */ + c1 = *(ptr2 + S->L); + + /* Read the input sample */ + x0 = *(ptr1++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x1 * c1; + acc1 += (q63_t) x2 * c1; + acc2 += (q63_t) x3 * c1; + acc3 += (q63_t) x0 * c1; + + /* Read the coefficient */ + c2 = *(ptr2 + S->L * 2); + + /* Read the input sample */ + x1 = *(ptr1++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x2 * c2; + acc1 += (q63_t) x3 * c2; + acc2 += (q63_t) x0 * c2; + acc3 += (q63_t) x1 * c2; + + /* Read the coefficient */ + c3 = *(ptr2 + S->L * 3); + + /* Read the input sample */ + x2 = *(ptr1++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x3 * c3; + acc1 += (q63_t) x0 * c3; + acc2 += (q63_t) x1 * c3; + acc3 += (q63_t) x2 * c3; + + + /* Upsampling is done by stuffing L-1 zeros between each sample. + * So instead of multiplying zeros with coefficients, + * Increment the coefficient pointer by interpolation factor times. */ + ptr2 += 4 * S->L; + + /* Decrement loop counter */ + tapCnt--; + } + + /* If the polyPhase length is not a multiple of 4, compute the remaining filter taps */ + tapCnt = phaseLen % 0x4U; + + while (tapCnt > 0U) + { + /* Read the input sample */ + x3 = *(ptr1++); + + /* Read the coefficient */ + c0 = *(ptr2); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + acc1 += (q63_t) x1 * c0; + acc2 += (q63_t) x2 * c0; + acc3 += (q63_t) x3 * c0; + + /* Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + /* update states for next sample processing */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement loop counter */ + tapCnt--; + } + + /* The result is in the accumulator, store in the destination buffer. */ + *(pDst ) = (q15_t) (__SSAT((acc0 >> 15), 16)); + *(pDst + S->L) = (q15_t) (__SSAT((acc1 >> 15), 16)); + *(pDst + 2 * S->L) = (q15_t) (__SSAT((acc2 >> 15), 16)); + *(pDst + 3 * S->L) = (q15_t) (__SSAT((acc3 >> 15), 16)); + + pDst++; + + /* Increment the address modifier index of coefficient buffer */ + j++; + + /* Decrement loop counter */ + i--; + } + + /* Advance the state pointer by 1 + * to process the next group of interpolation factor number samples */ + pState = pState + 4; + + pDst += S->L * 3; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy new input sample into the state buffer */ + *pStateCur++ = *pSrc++; + + /* Address modifier index of coefficient buffer */ + j = 1U; + + /* Loop over the Interpolation factor. */ + i = S->L; + while (i > 0U) + { + /* Set accumulator to zero */ + sum0 = 0; + + /* Initialize state pointer */ + ptr1 = pState; + + /* Initialize coefficient pointer */ + ptr2 = pCoeffs + (S->L - j); + + /* Loop over the polyPhase length. + Repeat until we've computed numTaps-(4*S->L) coefficients. */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + tapCnt = phaseLen >> 2U; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + sum0 += (q63_t) *ptr1++ * *ptr2; + + /* Upsampling is done by stuffing L-1 zeros between each sample. + * So instead of multiplying zeros with coefficients, + * Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + sum0 += (q63_t) *ptr1++ * *ptr2; + ptr2 += S->L; + + sum0 += (q63_t) *ptr1++ * *ptr2; + ptr2 += S->L; + + sum0 += (q63_t) *ptr1++ * *ptr2; + ptr2 += S->L; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + tapCnt = phaseLen % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = phaseLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + sum0 += (q63_t) *ptr1++ * *ptr2; + + /* Upsampling is done by stuffing L-1 zeros between each sample. + * So instead of multiplying zeros with coefficients, + * Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + /* Decrement loop counter */ + tapCnt--; + } + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = (q15_t) (__SSAT((sum0 >> 15), 16)); + + /* Increment the address modifier index of coefficient buffer */ + j++; + + /* Decrement the loop counter */ + i--; + } + + /* Advance the state pointer by 1 + * to process the next group of interpolation factor number samples */ + pState = pState + 1; + + /* Decrement the loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last phaseLen - 1 samples to the satrt of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + tapCnt = (phaseLen - 1U) >> 2U; + + /* copy data */ + while (tapCnt > 0U) + { + write_q15x2_ia (&pStateCur, read_q15x2_ia (&pState)); + write_q15x2_ia (&pStateCur, read_q15x2_ia (&pState)); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + tapCnt = (phaseLen - 1U) % 0x04U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = (phaseLen - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +#else +/* alternate version for CM0_FAMILY */ + + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *pStateCur; /* Points to the current sample of the state */ + q15_t *ptr1; /* Temporary pointer for state buffer */ + const q15_t *ptr2; /* Temporary pointer for coefficient buffer */ + q63_t sum0; /* Accumulators */ + uint32_t i, blkCnt, tapCnt; /* Loop counters */ + uint32_t phaseLen = S->phaseLength; /* Length of each polyphase filter component */ + + /* S->pState buffer contains previous frame (phaseLen - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (phaseLen - 1U); + + /* Total number of intput samples */ + blkCnt = blockSize; + + /* Loop over the blockSize. */ + while (blkCnt > 0U) + { + /* Copy new input sample into the state buffer */ + *pStateCur++ = *pSrc++; + + /* Loop over the Interpolation factor. */ + i = S->L; + + while (i > 0U) + { + /* Set accumulator to zero */ + sum0 = 0; + + /* Initialize state pointer */ + ptr1 = pState; + + /* Initialize coefficient pointer */ + ptr2 = pCoeffs + (i - 1U); + + /* Loop over the polyPhase length */ + tapCnt = phaseLen; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + sum0 += ((q63_t) *ptr1++ * *ptr2); + + /* Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Store the result after converting to 1.15 format in the destination buffer. */ + *pDst++ = (q15_t) (__SSAT((sum0 >> 15), 16)); + + /* Decrement loop counter */ + i--; + } + + /* Advance the state pointer by 1 + * to process the next group of interpolation factor number samples */ + pState = pState + 1; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + ** Now copy the last phaseLen - 1 samples to the start of the state buffer. + ** This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + + tapCnt = phaseLen - 1U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of FIR_Interpolate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_q31.c new file mode 100644 index 0000000..d6a8ca3 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_interpolate_q31.c @@ -0,0 +1,481 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_interpolate_q31.c + * Description: Q31 FIR interpolation + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Interpolate + @{ + */ + +/** + @brief Processing function for the Q31 FIR interpolator. + @param[in] S points to an instance of the Q31 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 samples to process + @return none + + @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 1/(numTaps/L). + since numTaps/L additions occur per output sample. + After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + +void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + + q31_t *pState = S->pState; /* State pointer */ + const q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t *pStateCur; /* Points to the current sample of the state */ + q31_t *ptr1; /* Temporary pointer for state buffer */ + const q31_t *ptr2; /* Temporary pointer for coefficient buffer */ + q63_t sum0; /* Accumulators */ + uint32_t i, blkCnt, tapCnt; /* Loop counters */ + uint32_t phaseLen = S->phaseLength; /* Length of each polyphase filter component */ + uint32_t j; + +#if defined (ARM_MATH_LOOPUNROLL) + q63_t acc0, acc1, acc2, acc3; + q31_t x0, x1, x2, x3; + q31_t c0, c1, c2, c3; +#endif + + /* S->pState buffer contains previous frame (phaseLen - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (phaseLen - 1U); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Copy new input sample into the state buffer */ + *pStateCur++ = *pSrc++; + *pStateCur++ = *pSrc++; + *pStateCur++ = *pSrc++; + *pStateCur++ = *pSrc++; + + /* Address modifier index of coefficient buffer */ + j = 1U; + + /* Loop over the Interpolation factor. */ + i = (S->L); + + while (i > 0U) + { + /* Set accumulator to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Initialize state pointer */ + ptr1 = pState; + + /* Initialize coefficient pointer */ + ptr2 = pCoeffs + (S->L - j); + + /* Loop over the polyPhase length. Unroll by a factor of 4. + Repeat until we've computed numTaps-(4*S->L) coefficients. */ + tapCnt = phaseLen >> 2U; + + x0 = *(ptr1++); + x1 = *(ptr1++); + x2 = *(ptr1++); + + while (tapCnt > 0U) + { + /* Read the input sample */ + x3 = *(ptr1++); + + /* Read the coefficient */ + c0 = *(ptr2); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + acc1 += (q63_t) x1 * c0; + acc2 += (q63_t) x2 * c0; + acc3 += (q63_t) x3 * c0; + + /* Read the coefficient */ + c1 = *(ptr2 + S->L); + + /* Read the input sample */ + x0 = *(ptr1++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x1 * c1; + acc1 += (q63_t) x2 * c1; + acc2 += (q63_t) x3 * c1; + acc3 += (q63_t) x0 * c1; + + /* Read the coefficient */ + c2 = *(ptr2 + S->L * 2); + + /* Read the input sample */ + x1 = *(ptr1++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x2 * c2; + acc1 += (q63_t) x3 * c2; + acc2 += (q63_t) x0 * c2; + acc3 += (q63_t) x1 * c2; + + /* Read the coefficient */ + c3 = *(ptr2 + S->L * 3); + + /* Read the input sample */ + x2 = *(ptr1++); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x3 * c3; + acc1 += (q63_t) x0 * c3; + acc2 += (q63_t) x1 * c3; + acc3 += (q63_t) x2 * c3; + + + /* Upsampling is done by stuffing L-1 zeros between each sample. + * So instead of multiplying zeros with coefficients, + * Increment the coefficient pointer by interpolation factor times. */ + ptr2 += 4 * S->L; + + /* Decrement loop counter */ + tapCnt--; + } + + /* If the polyPhase length is not a multiple of 4, compute the remaining filter taps */ + tapCnt = phaseLen % 0x4U; + + while (tapCnt > 0U) + { + /* Read the input sample */ + x3 = *(ptr1++); + + /* Read the coefficient */ + c0 = *(ptr2); + + /* Perform the multiply-accumulate */ + acc0 += (q63_t) x0 * c0; + acc1 += (q63_t) x1 * c0; + acc2 += (q63_t) x2 * c0; + acc3 += (q63_t) x3 * c0; + + /* Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + /* update states for next sample processing */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement loop counter */ + tapCnt--; + } + + /* The result is in the accumulator, store in the destination buffer. */ + *(pDst ) = (q31_t) (acc0 >> 31); + *(pDst + S->L) = (q31_t) (acc1 >> 31); + *(pDst + 2 * S->L) = (q31_t) (acc2 >> 31); + *(pDst + 3 * S->L) = (q31_t) (acc3 >> 31); + + pDst++; + + /* Increment the address modifier index of coefficient buffer */ + j++; + + /* Decrement loop counter */ + i--; + } + + /* Advance the state pointer by 1 + * to process the next group of interpolation factor number samples */ + pState = pState + 4; + + pDst += S->L * 3; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy new input sample into the state buffer */ + *pStateCur++ = *pSrc++; + + /* Address modifier index of coefficient buffer */ + j = 1U; + + /* Loop over the Interpolation factor. */ + i = S->L; + while (i > 0U) + { + /* Set accumulator to zero */ + sum0 = 0; + + /* Initialize state pointer */ + ptr1 = pState; + + /* Initialize coefficient pointer */ + ptr2 = pCoeffs + (S->L - j); + + /* Loop over the polyPhase length. + Repeat until we've computed numTaps-(4*S->L) coefficients. */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + tapCnt = phaseLen >> 2U; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + sum0 += (q63_t) *ptr1++ * *ptr2; + + /* Upsampling is done by stuffing L-1 zeros between each sample. + * So instead of multiplying zeros with coefficients, + * Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + sum0 += (q63_t) *ptr1++ * *ptr2; + ptr2 += S->L; + + sum0 += (q63_t) *ptr1++ * *ptr2; + ptr2 += S->L; + + sum0 += (q63_t) *ptr1++ * *ptr2; + ptr2 += S->L; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + tapCnt = phaseLen % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = phaseLen; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + sum0 += (q63_t) *ptr1++ * *ptr2; + + /* Upsampling is done by stuffing L-1 zeros between each sample. + * So instead of multiplying zeros with coefficients, + * Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + /* Decrement loop counter */ + tapCnt--; + } + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = (q31_t) (sum0 >> 31); + + /* Increment the address modifier index of coefficient buffer */ + j++; + + /* Decrement the loop counter */ + i--; + } + + /* Advance the state pointer by 1 + * to process the next group of interpolation factor number samples */ + pState = pState + 1; + + /* Decrement the loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last phaseLen - 1 samples to the satrt of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + tapCnt = (phaseLen - 1U) >> 2U; + + /* copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + tapCnt = (phaseLen - 1U) % 0x04U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = (phaseLen - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +#else +/* alternate version for CM0_FAMILY */ + + q31_t *pState = S->pState; /* State pointer */ + const q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t *pStateCur; /* Points to the current sample of the state */ + q31_t *ptr1; /* Temporary pointer for state buffer */ + const q31_t *ptr2; /* Temporary pointer for coefficient buffer */ + q63_t sum0; /* Accumulators */ + uint32_t i, blkCnt, tapCnt; /* Loop counters */ + uint32_t phaseLen = S->phaseLength; /* Length of each polyphase filter component */ + + /* S->pState buffer contains previous frame (phaseLen - 1) samples */ + /* pStateCur points to the location where the new input data should be written */ + pStateCur = S->pState + (phaseLen - 1U); + + /* Total number of intput samples */ + blkCnt = blockSize; + + /* Loop over the blockSize. */ + while (blkCnt > 0U) + { + /* Copy new input sample into the state buffer */ + *pStateCur++ = *pSrc++; + + /* Loop over the Interpolation factor. */ + i = S->L; + + while (i > 0U) + { + /* Set accumulator to zero */ + sum0 = 0; + + /* Initialize state pointer */ + ptr1 = pState; + + /* Initialize coefficient pointer */ + ptr2 = pCoeffs + (i - 1U); + + /* Loop over the polyPhase length */ + tapCnt = phaseLen; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + sum0 += ((q63_t) *ptr1++ * *ptr2); + + /* Increment the coefficient pointer by interpolation factor times. */ + ptr2 += S->L; + + /* Decrement the loop counter */ + tapCnt--; + } + + /* The result is in the accumulator, store in the destination buffer. */ + *pDst++ = (q31_t) (sum0 >> 31); + + /* Decrement loop counter */ + i--; + } + + /* Advance the state pointer by 1 + * to process the next group of interpolation factor number samples */ + pState = pState + 1; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + ** Now copy the last phaseLen - 1 samples to the start of the state buffer. + ** This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCur = S->pState; + + tapCnt = phaseLen - 1U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of FIR_Interpolate group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_f32.c new file mode 100644 index 0000000..a3d95c1 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_f32.c @@ -0,0 +1,453 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_lattice_f32.c + * Description: Processing function for floating-point FIR Lattice filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup FIR_Lattice Finite Impulse Response (FIR) Lattice Filters + + This set of functions implements Finite Impulse Response (FIR) lattice filters + for Q15, Q31 and floating-point data types. Lattice filters are used in a + variety of adaptive filter applications. The filter structure is feedforward and + the net impulse response is finite length. + The functions operate on blocks + of input and output data and each call to the function processes + blockSize samples through the filter. pSrc and + pDst point to input and output arrays containing blockSize values. + + @par Algorithm + \image html FIRLattice.gif "Finite Impulse Response Lattice filter" + The following difference equation is implemented: + @par +
+      f0[n] = g0[n] = x[n]
+      fm[n] = fm-1[n] + km * gm-1[n-1] for m = 1, 2, ...M
+      gm[n] = km * fm-1[n] + gm-1[n-1] for m = 1, 2, ...M
+      y[n] = fM[n]
+  
+ @par + pCoeffs points to tha array of reflection coefficients of size numStages. + Reflection Coefficients are stored in the following order. + @par +
+      {k1, k2, ..., kM}
+  
+ where M is number of stages + @par + pState points to a state array of size numStages. + The state variables (g values) hold previous inputs and are stored in the following order. +
+    {g0[n], g1[n], g2[n] ...gM-1[n]}
+  
+ The state variables are updated after each block of data is processed; the coefficients are untouched. + + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter. + Coefficient arrays may be shared among several instances while state variable arrays cannot be shared. + There are separate instance structure declarations for each of the 3 supported data types. + + @par Initialization Functions + There is also an associated initialization function for each data type. + The initialization function performs the following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + numStages, pCoeffs, pState. Also set all of the values in pState to zero. + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + Set the values in the state buffer to zeros and then manually initialize the instance structure as follows: +
+      arm_fir_lattice_instance_f32 S = {numStages, pState, pCoeffs};
+      arm_fir_lattice_instance_q31 S = {numStages, pState, pCoeffs};
+      arm_fir_lattice_instance_q15 S = {numStages, pState, pCoeffs};
+  
+ @par + where numStages is the number of stages in the filter; + pState is the address of the state buffer; + pCoeffs is the address of the coefficient buffer. + + @par Fixed-Point Behavior + Care must be taken when using the fixed-point versions of the FIR Lattice filter 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 FIR_Lattice + @{ + */ + +/** + @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 + @return none + */ + +void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + float32_t *pState = S->pState; /* State pointer */ + const float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t *px; /* Temporary state pointer */ + const float32_t *pk; /* Temporary coefficient pointer */ + uint32_t numStages = S->numStages; /* Number of stages in the filter */ + uint32_t blkCnt, stageCnt; /* Loop counters */ + float32_t fcurr0, fnext0, gnext0, gcurr0; /* Temporary variables */ + +#if defined (ARM_MATH_LOOPUNROLL) + float32_t fcurr1, fnext1, gnext1; /* Temporary variables for second sample in loop unrolling */ + float32_t fcurr2, fnext2, gnext2; /* Temporary variables for third sample in loop unrolling */ + float32_t fcurr3, fnext3, gnext3; /* Temporary variables for fourth sample in loop unrolling */ +#endif + + gcurr0 = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Read two samples from input buffer */ + /* f0(n) = x(n) */ + fcurr0 = *pSrc++; + fcurr1 = *pSrc++; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pk = pCoeffs; + + /* Read g0(n-1) from state buffer */ + gcurr0 = *px; + + /* Process first sample for first tap */ + /* f1(n) = f0(n) + K1 * g0(n-1) */ + fnext0 = (gcurr0 * (*pk)) + fcurr0; + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext0 = (fcurr0 * (*pk)) + gcurr0; + + /* Process second sample for first tap */ + fnext1 = (fcurr0 * (*pk)) + fcurr1; + gnext1 = (fcurr1 * (*pk)) + fcurr0; + + /* Read next two samples from input buffer */ + /* f0(n+2) = x(n+2) */ + fcurr2 = *pSrc++; + fcurr3 = *pSrc++; + + /* Process third sample for first tap */ + fnext2 = (fcurr1 * (*pk)) + fcurr2; + gnext2 = (fcurr2 * (*pk)) + fcurr1; + + /* Process fourth sample for first tap */ + fnext3 = (fcurr2 * (*pk )) + fcurr3; + gnext3 = (fcurr3 * (*pk++)) + fcurr2; + + /* Copy only last input sample into the state buffer + which will be used for next samples processing */ + *px++ = fcurr3; + + /* Update of f values for next coefficient set processing */ + fcurr0 = fnext0; + fcurr1 = fnext1; + fcurr2 = fnext2; + fcurr3 = fnext3; + + /* Loop unrolling. Process 4 taps at a time . */ + stageCnt = (numStages - 1U) >> 2U; + + /* Loop over the number of taps. Unroll by a factor of 4. + Repeat until we've computed numStages-3 coefficients. */ + + /* Process 2nd, 3rd, 4th and 5th taps ... here */ + while (stageCnt > 0U) + { + /* Read g1(n-1), g3(n-1) .... from state */ + gcurr0 = *px; + + /* save g1(n) in state buffer */ + *px++ = gnext3; + + /* Process first sample for 2nd, 6th .. tap */ + /* Sample processing for K2, K6.... */ + /* f2(n) = f1(n) + K2 * g1(n-1) */ + fnext0 = (gcurr0 * (*pk)) + fcurr0; + + /* Process second sample for 2nd, 6th .. tap */ + /* for sample 2 processing */ + fnext1 = (gnext0 * (*pk)) + fcurr1; + + /* Process third sample for 2nd, 6th .. tap */ + fnext2 = (gnext1 * (*pk)) + fcurr2; + + /* Process fourth sample for 2nd, 6th .. tap */ + fnext3 = (gnext2 * (*pk)) + fcurr3; + + /* g2(n) = f1(n) * K2 + g1(n-1) */ + /* Calculation of state values for next stage */ + gnext3 = (fcurr3 * (*pk)) + gnext2; + + gnext2 = (fcurr2 * (*pk)) + gnext1; + + gnext1 = (fcurr1 * (*pk)) + gnext0; + + gnext0 = (fcurr0 * (*pk++)) + gcurr0; + + + /* Read g2(n-1), g4(n-1) .... from state */ + gcurr0 = *px; + + /* save g2(n) in state buffer */ + *px++ = gnext3; + + /* Sample processing for K3, K7.... */ + /* Process first sample for 3rd, 7th .. tap */ + /* f3(n) = f2(n) + K3 * g2(n-1) */ + fcurr0 = (gcurr0 * (*pk)) + fnext0; + + /* Process second sample for 3rd, 7th .. tap */ + fcurr1 = (gnext0 * (*pk)) + fnext1; + + /* Process third sample for 3rd, 7th .. tap */ + fcurr2 = (gnext1 * (*pk)) + fnext2; + + /* Process fourth sample for 3rd, 7th .. tap */ + fcurr3 = (gnext2 * (*pk)) + fnext3; + + /* Calculation of state values for next stage */ + /* g3(n) = f2(n) * K3 + g2(n-1) */ + gnext3 = (fnext3 * (*pk)) + gnext2; + + gnext2 = (fnext2 * (*pk)) + gnext1; + + gnext1 = (fnext1 * (*pk)) + gnext0; + + gnext0 = (fnext0 * (*pk++)) + gcurr0; + + + /* Read g1(n-1), g3(n-1) .... from state */ + gcurr0 = *px; + + /* save g3(n) in state buffer */ + *px++ = gnext3; + + /* Sample processing for K4, K8.... */ + /* Process first sample for 4th, 8th .. tap */ + /* f4(n) = f3(n) + K4 * g3(n-1) */ + fnext0 = (gcurr0 * (*pk)) + fcurr0; + + /* Process second sample for 4th, 8th .. tap */ + /* for sample 2 processing */ + fnext1 = (gnext0 * (*pk)) + fcurr1; + + /* Process third sample for 4th, 8th .. tap */ + fnext2 = (gnext1 * (*pk)) + fcurr2; + + /* Process fourth sample for 4th, 8th .. tap */ + fnext3 = (gnext2 * (*pk)) + fcurr3; + + /* g4(n) = f3(n) * K4 + g3(n-1) */ + /* Calculation of state values for next stage */ + gnext3 = (fcurr3 * (*pk)) + gnext2; + + gnext2 = (fcurr2 * (*pk)) + gnext1; + + gnext1 = (fcurr1 * (*pk)) + gnext0; + + gnext0 = (fcurr0 * (*pk++)) + gcurr0; + + + /* Read g2(n-1), g4(n-1) .... from state */ + gcurr0 = *px; + + /* save g4(n) in state buffer */ + *px++ = gnext3; + + /* Sample processing for K5, K9.... */ + /* Process first sample for 5th, 9th .. tap */ + /* f5(n) = f4(n) + K5 * g4(n-1) */ + fcurr0 = (gcurr0 * (*pk)) + fnext0; + + /* Process second sample for 5th, 9th .. tap */ + fcurr1 = (gnext0 * (*pk)) + fnext1; + + /* Process third sample for 5th, 9th .. tap */ + fcurr2 = (gnext1 * (*pk)) + fnext2; + + /* Process fourth sample for 5th, 9th .. tap */ + fcurr3 = (gnext2 * (*pk)) + fnext3; + + /* Calculation of state values for next stage */ + /* g5(n) = f4(n) * K5 + g4(n-1) */ + gnext3 = (fnext3 * (*pk)) + gnext2; + + gnext2 = (fnext2 * (*pk)) + gnext1; + + gnext1 = (fnext1 * (*pk)) + gnext0; + + gnext0 = (fnext0 * (*pk++)) + gcurr0; + + stageCnt--; + } + + /* If the (filter length -1) is not a multiple of 4, compute the remaining filter taps */ + stageCnt = (numStages - 1U) % 0x4U; + + while (stageCnt > 0U) + { + gcurr0 = *px; + + /* save g value in state buffer */ + *px++ = gnext3; + + /* Process four samples for last three taps here */ + fnext0 = (gcurr0 * (*pk)) + fcurr0; + + fnext1 = (gnext0 * (*pk)) + fcurr1; + + fnext2 = (gnext1 * (*pk)) + fcurr2; + + fnext3 = (gnext2 * (*pk)) + fcurr3; + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext3 = (fcurr3 * (*pk)) + gnext2; + + gnext2 = (fcurr2 * (*pk)) + gnext1; + + gnext1 = (fcurr1 * (*pk)) + gnext0; + + gnext0 = (fcurr0 * (*pk++)) + gcurr0; + + /* Update of f values for next coefficient set processing */ + fcurr0 = fnext0; + fcurr1 = fnext1; + fcurr2 = fnext2; + fcurr3 = fnext3; + + stageCnt--; + } + + /* The results in the 4 accumulators, store in the destination buffer. */ + /* y(n) = fN(n) */ + *pDst++ = fcurr0; + *pDst++ = fcurr1; + *pDst++ = fcurr2; + *pDst++ = fcurr3; + + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* f0(n) = x(n) */ + fcurr0 = *pSrc++; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pk = pCoeffs; + + /* read g2(n) from state buffer */ + gcurr0 = *px; + + /* for sample 1 processing */ + /* f1(n) = f0(n) + K1 * g0(n-1) */ + fnext0 = (gcurr0 * (*pk)) + fcurr0; + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext0 = (fcurr0 * (*pk++)) + gcurr0; + + /* save g1(n) in state buffer */ + *px++ = fcurr0; + + /* f1(n) is saved in fcurr0 for next stage processing */ + fcurr0 = fnext0; + + stageCnt = (numStages - 1U); + + /* stage loop */ + while (stageCnt > 0U) + { + /* read g2(n) from state buffer */ + gcurr0 = *px; + + /* save g1(n) in state buffer */ + *px++ = gnext0; + + /* Sample processing for K2, K3.... */ + /* f2(n) = f1(n) + K2 * g1(n-1) */ + fnext0 = (gcurr0 * (*pk)) + fcurr0; + + /* g2(n) = f1(n) * K2 + g1(n-1) */ + gnext0 = (fcurr0 * (*pk++)) + gcurr0; + + /* f1(n) is saved in fcurr0 for next stage processing */ + fcurr0 = fnext0; + + stageCnt--; + } + + /* y(n) = fN(n) */ + *pDst++ = fcurr0; + + blkCnt--; + } + +} + +/** + @} end of FIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_f32.c new file mode 100644 index 0000000..7929629 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_f32.c @@ -0,0 +1,70 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_lattice_init_f32.c + * Description: Floating-point FIR Lattice filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Lattice + @{ + */ + +/** + @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 + @return none + */ + +void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + const float32_t * pCoeffs, + float32_t * pState) +{ + /* Assign filter taps */ + S->numStages = numStages; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always numStages */ + memset(pState, 0, (numStages) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of FIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_q15.c new file mode 100644 index 0000000..5c80dff --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_q15.c @@ -0,0 +1,70 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_lattice_init_q15.c + * Description: Q15 FIR Lattice filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Lattice + @{ + */ + +/** + @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 + @return none + */ + +void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + const q15_t * pCoeffs, + q15_t * pState) +{ + /* Assign filter taps */ + S->numStages = numStages; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always numStages */ + memset(pState, 0, (numStages) * sizeof(q15_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of FIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_q31.c new file mode 100644 index 0000000..476296d --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_init_q31.c @@ -0,0 +1,70 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_lattice_init_q31.c + * Description: Q31 FIR lattice filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Lattice + @{ + */ + +/** + @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 + @return none + */ + +void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + const q31_t * pCoeffs, + q31_t * pState) +{ + /* Assign filter taps */ + S->numStages = numStages; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always numStages */ + memset(pState, 0, (numStages) * sizeof(q31_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of FIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_q15.c new file mode 100644 index 0000000..42e7c0d --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_q15.c @@ -0,0 +1,506 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_lattice_q15.c + * Description: Q15 FIR lattice filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Lattice + @{ + */ + +/** + @brief Processing function for 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 + @return none + */ + +void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *px; /* Temporary state pointer */ + const q15_t *pk; /* Temporary coefficient pointer */ + uint32_t numStages = S->numStages; /* Number of stages in the filter */ + uint32_t blkCnt, stageCnt; /* Loop counters */ + q31_t fcurr0, fnext0, gnext0, gcurr0; /* Temporary variables */ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t fcurr1, fnext1, gnext1; /* Temporary variables for second sample in loop unrolling */ + q31_t fcurr2, fnext2, gnext2; /* Temporary variables for third sample in loop unrolling */ + q31_t fcurr3, fnext3, gnext3; /* Temporary variables for fourth sample in loop unrolling */ +#endif + + gcurr0 = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Read two samples from input buffer */ + /* f0(n) = x(n) */ + fcurr0 = *pSrc++; + fcurr1 = *pSrc++; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pk = pCoeffs; + + /* Read g0(n-1) from state buffer */ + gcurr0 = *px; + + /* Process first sample for first tap */ + /* f1(n) = f0(n) + K1 * g0(n-1) */ + fnext0 = (q31_t) ((gcurr0 * (*pk)) >> 15U) + fcurr0; + fnext0 = __SSAT(fnext0, 16); + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext0 = (q31_t) ((fcurr0 * (*pk)) >> 15U) + gcurr0; + gnext0 = __SSAT(gnext0, 16); + + /* Process second sample for first tap */ + fnext1 = (q31_t) ((fcurr0 * (*pk)) >> 15U) + fcurr1; + fnext1 = __SSAT(fnext1, 16); + gnext1 = (q31_t) ((fcurr1 * (*pk)) >> 15U) + fcurr0; + gnext1 = __SSAT(gnext1, 16); + + /* Read next two samples from input buffer */ + /* f0(n+2) = x(n+2) */ + fcurr2 = *pSrc++; + fcurr3 = *pSrc++; + + /* Process third sample for first tap */ + fnext2 = (q31_t) ((fcurr1 * (*pk)) >> 15U) + fcurr2; + fnext2 = __SSAT(fnext2, 16); + gnext2 = (q31_t) ((fcurr2 * (*pk)) >> 15U) + fcurr1; + gnext2 = __SSAT(gnext2, 16); + + /* Process fourth sample for first tap */ + fnext3 = (q31_t) ((fcurr2 * (*pk )) >> 15U) + fcurr3; + fnext3 = __SSAT(fnext3, 16); + gnext3 = (q31_t) ((fcurr3 * (*pk++)) >> 15U) + fcurr2; + gnext3 = __SSAT(gnext3, 16); + + /* Copy only last input sample into the state buffer + which will be used for next samples processing */ + *px++ = (q15_t) fcurr3; + + /* Update of f values for next coefficient set processing */ + fcurr0 = fnext0; + fcurr1 = fnext1; + fcurr2 = fnext2; + fcurr3 = fnext3; + + /* Loop unrolling. Process 4 taps at a time . */ + stageCnt = (numStages - 1U) >> 2U; + + /* Loop over the number of taps. Unroll by a factor of 4. + Repeat until we've computed numStages-3 coefficients. */ + + /* Process 2nd, 3rd, 4th and 5th taps ... here */ + while (stageCnt > 0U) + { + /* Read g1(n-1), g3(n-1) .... from state */ + gcurr0 = *px; + + /* save g1(n) in state buffer */ + *px++ = (q15_t) gnext3; + + /* Process first sample for 2nd, 6th .. tap */ + /* Sample processing for K2, K6.... */ + /* f1(n) = f0(n) + K1 * g0(n-1) */ + fnext0 = (q31_t) ((gcurr0 * (*pk)) >> 15U) + fcurr0; + fnext0 = __SSAT(fnext0, 16); + + /* Process second sample for 2nd, 6th .. tap */ + /* for sample 2 processing */ + fnext1 = (q31_t) ((gnext0 * (*pk)) >> 15U) + fcurr1; + fnext1 = __SSAT(fnext1, 16); + + /* Process third sample for 2nd, 6th .. tap */ + fnext2 = (q31_t) ((gnext1 * (*pk)) >> 15U) + fcurr2; + fnext2 = __SSAT(fnext2, 16); + + /* Process fourth sample for 2nd, 6th .. tap */ + fnext3 = (q31_t) ((gnext2 * (*pk)) >> 15U) + fcurr3; + fnext3 = __SSAT(fnext3, 16); + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + /* Calculation of state values for next stage */ + gnext3 = (q31_t) ((fcurr3 * (*pk)) >> 15U) + gnext2; + gnext3 = __SSAT(gnext3, 16); + + gnext2 = (q31_t) ((fcurr2 * (*pk)) >> 15U) + gnext1; + gnext2 = __SSAT(gnext2, 16); + + gnext1 = (q31_t) ((fcurr1 * (*pk)) >> 15U) + gnext0; + gnext1 = __SSAT(gnext1, 16); + + gnext0 = (q31_t) ((fcurr0 * (*pk++)) >> 15U) + gcurr0; + gnext0 = __SSAT(gnext0, 16); + + + /* Read g2(n-1), g4(n-1) .... from state */ + gcurr0 = *px; + + /* save g1(n) in state buffer */ + *px++ = (q15_t) gnext3; + + /* Sample processing for K3, K7.... */ + /* Process first sample for 3rd, 7th .. tap */ + /* f3(n) = f2(n) + K3 * g2(n-1) */ + fcurr0 = (q31_t) ((gcurr0 * (*pk)) >> 15U) + fnext0; + fcurr0 = __SSAT(fcurr0, 16); + + /* Process second sample for 3rd, 7th .. tap */ + fcurr1 = (q31_t) ((gnext0 * (*pk)) >> 15U) + fnext1; + fcurr1 = __SSAT(fcurr1, 16); + + /* Process third sample for 3rd, 7th .. tap */ + fcurr2 = (q31_t) ((gnext1 * (*pk)) >> 15U) + fnext2; + fcurr2 = __SSAT(fcurr2, 16); + + /* Process fourth sample for 3rd, 7th .. tap */ + fcurr3 = (q31_t) ((gnext2 * (*pk)) >> 15U) + fnext3; + fcurr3 = __SSAT(fcurr3, 16); + + /* Calculation of state values for next stage */ + /* g3(n) = f2(n) * K3 + g2(n-1) */ + gnext3 = (q31_t) ((fnext3 * (*pk)) >> 15U) + gnext2; + gnext3 = __SSAT(gnext3, 16); + + gnext2 = (q31_t) ((fnext2 * (*pk)) >> 15U) + gnext1; + gnext2 = __SSAT(gnext2, 16); + + gnext1 = (q31_t) ((fnext1 * (*pk)) >> 15U) + gnext0; + gnext1 = __SSAT(gnext1, 16); + + gnext0 = (q31_t) ((fnext0 * (*pk++)) >> 15U) + gcurr0; + gnext0 = __SSAT(gnext0, 16); + + /* Read g1(n-1), g3(n-1) .... from state */ + gcurr0 = *px; + + /* save g1(n) in state buffer */ + *px++ = (q15_t) gnext3; + + /* Sample processing for K4, K8.... */ + /* Process first sample for 4th, 8th .. tap */ + /* f4(n) = f3(n) + K4 * g3(n-1) */ + fnext0 = (q31_t) ((gcurr0 * (*pk)) >> 15U) + fcurr0; + fnext0 = __SSAT(fnext0, 16); + + /* Process second sample for 4th, 8th .. tap */ + /* for sample 2 processing */ + fnext1 = (q31_t) ((gnext0 * (*pk)) >> 15U) + fcurr1; + fnext1 = __SSAT(fnext1, 16); + + /* Process third sample for 4th, 8th .. tap */ + fnext2 = (q31_t) ((gnext1 * (*pk)) >> 15U) + fcurr2; + fnext2 = __SSAT(fnext2, 16); + + /* Process fourth sample for 4th, 8th .. tap */ + fnext3 = (q31_t) ((gnext2 * (*pk)) >> 15U) + fcurr3; + fnext3 = __SSAT(fnext3, 16); + + /* g4(n) = f3(n) * K4 + g3(n-1) */ + /* Calculation of state values for next stage */ + gnext3 = (q31_t) ((fcurr3 * (*pk)) >> 15U) + gnext2; + gnext3 = __SSAT(gnext3, 16); + + gnext2 = (q31_t) ((fcurr2 * (*pk)) >> 15U) + gnext1; + gnext2 = __SSAT(gnext2, 16); + + gnext1 = (q31_t) ((fcurr1 * (*pk)) >> 15U) + gnext0; + gnext1 = __SSAT(gnext1, 16); + + gnext0 = (q31_t) ((fcurr0 * (*pk++)) >> 15U) + gcurr0; + gnext0 = __SSAT(gnext0, 16); + + /* Read g2(n-1), g4(n-1) .... from state */ + gcurr0 = *px; + + /* save g4(n) in state buffer */ + *px++ = (q15_t) gnext3; + + /* Sample processing for K5, K9.... */ + /* Process first sample for 5th, 9th .. tap */ + /* f5(n) = f4(n) + K5 * g4(n-1) */ + fcurr0 = (q31_t) ((gcurr0 * (*pk)) >> 15U) + fnext0; + fcurr0 = __SSAT(fcurr0, 16); + + /* Process second sample for 5th, 9th .. tap */ + fcurr1 = (q31_t) ((gnext0 * (*pk)) >> 15U) + fnext1; + fcurr1 = __SSAT(fcurr1, 16); + + /* Process third sample for 5th, 9th .. tap */ + fcurr2 = (q31_t) ((gnext1 * (*pk)) >> 15U) + fnext2; + fcurr2 = __SSAT(fcurr2, 16); + + /* Process fourth sample for 5th, 9th .. tap */ + fcurr3 = (q31_t) ((gnext2 * (*pk)) >> 15U) + fnext3; + fcurr3 = __SSAT(fcurr3, 16); + + /* Calculation of state values for next stage */ + /* g5(n) = f4(n) * K5 + g4(n-1) */ + gnext3 = (q31_t) ((fnext3 * (*pk)) >> 15U) + gnext2; + gnext3 = __SSAT(gnext3, 16); + + gnext2 = (q31_t) ((fnext2 * (*pk)) >> 15U) + gnext1; + gnext2 = __SSAT(gnext2, 16); + + gnext1 = (q31_t) ((fnext1 * (*pk)) >> 15U) + gnext0; + gnext1 = __SSAT(gnext1, 16); + + gnext0 = (q31_t) ((fnext0 * (*pk++)) >> 15U) + gcurr0; + gnext0 = __SSAT(gnext0, 16); + + stageCnt--; + } + + /* If the (filter length -1) is not a multiple of 4, compute the remaining filter taps */ + stageCnt = (numStages - 1U) % 0x4U; + + while (stageCnt > 0U) + { + gcurr0 = *px; + + /* save g value in state buffer */ + *px++ = (q15_t) gnext3; + + /* Process four samples for last three taps here */ + fnext0 = (q31_t) ((gcurr0 * (*pk)) >> 15U) + fcurr0; + fnext0 = __SSAT(fnext0, 16); + + fnext1 = (q31_t) ((gnext0 * (*pk)) >> 15U) + fcurr1; + fnext1 = __SSAT(fnext1, 16); + + fnext2 = (q31_t) ((gnext1 * (*pk)) >> 15U) + fcurr2; + fnext2 = __SSAT(fnext2, 16); + + fnext3 = (q31_t) ((gnext2 * (*pk)) >> 15U) + fcurr3; + fnext3 = __SSAT(fnext3, 16); + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext3 = (q31_t) ((fcurr3 * (*pk)) >> 15U) + gnext2; + gnext3 = __SSAT(gnext3, 16); + + gnext2 = (q31_t) ((fcurr2 * (*pk)) >> 15U) + gnext1; + gnext2 = __SSAT(gnext2, 16); + + gnext1 = (q31_t) ((fcurr1 * (*pk)) >> 15U) + gnext0; + gnext1 = __SSAT(gnext1, 16); + + gnext0 = (q31_t) ((fcurr0 * (*pk++)) >> 15U) + gcurr0; + gnext0 = __SSAT(gnext0, 16); + + /* Update of f values for next coefficient set processing */ + fcurr0 = fnext0; + fcurr1 = fnext1; + fcurr2 = fnext2; + fcurr3 = fnext3; + + stageCnt--; + } + + /* The results in the 4 accumulators, store in the destination buffer. */ + /* y(n) = fN(n) */ + +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pDst, __PKHBT(fcurr0, fcurr1, 16)); + write_q15x2_ia (&pDst, __PKHBT(fcurr2, fcurr3, 16)); +#else + write_q15x2_ia (&pDst, __PKHBT(fcurr1, fcurr0, 16)); + write_q15x2_ia (&pDst, __PKHBT(fcurr3, fcurr2, 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* f0(n) = x(n) */ + fcurr0 = *pSrc++; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pk = pCoeffs; + + /* read g2(n) from state buffer */ + gcurr0 = *px; + + /* for sample 1 processing */ + /* f1(n) = f0(n) + K1 * g0(n-1) */ + fnext0 = (((q31_t) gcurr0 * (*pk)) >> 15U) + fcurr0; + fnext0 = __SSAT(fnext0, 16); + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext0 = (((q31_t) fcurr0 * (*pk++)) >> 15U) + gcurr0; + gnext0 = __SSAT(gnext0, 16); + + /* save g1(n) in state buffer */ + *px++ = (q15_t) fcurr0; + + /* f1(n) is saved in fcurr0 for next stage processing */ + fcurr0 = fnext0; + + stageCnt = (numStages - 1U); + + /* stage loop */ + while (stageCnt > 0U) + { + /* read g2(n) from state buffer */ + gcurr0 = *px; + + /* save g1(n) in state buffer */ + *px++ = (q15_t) gnext0; + + /* Sample processing for K2, K3.... */ + /* f2(n) = f1(n) + K2 * g1(n-1) */ + fnext0 = (((q31_t) gcurr0 * (*pk)) >> 15U) + fcurr0; + fnext0 = __SSAT(fnext0, 16); + + /* g2(n) = f1(n) * K2 + g1(n-1) */ + gnext0 = (((q31_t) fcurr0 * (*pk++)) >> 15U) + gcurr0; + gnext0 = __SSAT(gnext0, 16); + + /* f1(n) is saved in fcurr0 for next stage processing */ + fcurr0 = fnext0; + + stageCnt--; + } + + /* y(n) = fN(n) */ + *pDst++ = __SSAT(fcurr0, 16); + + blkCnt--; + } + +#else +/* alternate version for CM0_FAMILY */ + + blkCnt = blockSize; + + while (blkCnt > 0U) + { + /* f0(n) = x(n) */ + fcurr0 = *pSrc++; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pk = pCoeffs; + + /* read g0(n-1) from state buffer */ + gcurr0 = *px; + + /* for sample 1 processing */ + /* f1(n) = f0(n) + K1 * g0(n-1) */ + fnext0 = ((gcurr0 * (*pk)) >> 15U) + fcurr0; + fnext0 = __SSAT(fnext, 16); + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext0 = ((fcurr0 * (*pk++)) >> 15U) + gcurr0; + gnext0 = __SSAT(gnext0, 16); + + /* save f0(n) in state buffer */ + *px++ = (q15_t) fcurr0; + + /* f1(n) is saved in fcurr for next stage processing */ + fcurr0 = fnext0; + + stageCnt = (numStages - 1U); + + /* stage loop */ + while (stageCnt > 0U) + { + /* read g1(n-1) from state buffer */ + gcurr0 = *px; + + /* save g0(n-1) in state buffer */ + *px++ = (q15_t) gnext0; + + /* Sample processing for K2, K3.... */ + /* f2(n) = f1(n) + K2 * g1(n-1) */ + fnext0 = ((gcurr0 * (*pk)) >> 15U) + fcurr0; + fnext0 = __SSAT(fnext0, 16); + + /* g2(n) = f1(n) * K2 + g1(n-1) */ + gnext0 = ((fcurr0 * (*pk++)) >> 15U) + gcurr0; + gnext0 = __SSAT(gnext0, 16); + + /* f1(n) is saved in fcurr0 for next stage processing */ + fcurr0 = fnext0; + + stageCnt--; + } + + /* y(n) = fN(n) */ + *pDst++ = __SSAT(fcurr0, 16); + + blkCnt--; + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of FIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_q31.c new file mode 100644 index 0000000..c8d28d7 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_lattice_q31.c @@ -0,0 +1,505 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_lattice_q31.c + * Description: Q31 FIR lattice filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Lattice + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + In order to avoid overflows the input signal must be scaled down by 2*log2(numStages) bits. + */ + +void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + q31_t *pState = S->pState; /* State pointer */ + const q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t *px; /* Temporary state pointer */ + const q31_t *pk; /* Temporary coefficient pointer */ + uint32_t numStages = S->numStages; /* Number of stages in the filter */ + uint32_t blkCnt, stageCnt; /* Loop counters */ + q31_t fcurr0, fnext0, gnext0, gcurr0; /* Temporary variables */ + +#if (1) +//#if !defined(ARM_MATH_CM0_FAMILY) + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t fcurr1, fnext1, gnext1; /* Temporary variables for second sample in loop unrolling */ + q31_t fcurr2, fnext2, gnext2; /* Temporary variables for third sample in loop unrolling */ + q31_t fcurr3, fnext3, gnext3; /* Temporary variables for fourth sample in loop unrolling */ +#endif + + gcurr0 = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Read two samples from input buffer */ + /* f0(n) = x(n) */ + fcurr0 = *pSrc++; + fcurr1 = *pSrc++; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pk = pCoeffs; + + /* Read g0(n-1) from state buffer */ + gcurr0 = *px; + + /* Process first sample for first tap */ + /* f1(n) = f0(n) + K1 * g0(n-1) */ + fnext0 = (q31_t) (((q63_t) gcurr0 * (*pk)) >> 32U); + fnext0 = (fnext0 << 1U) + fcurr0; + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext0 = (q31_t) (((q63_t) fcurr0 * (*pk)) >> 32U); + gnext0 = (gnext0 << 1U) + gcurr0; + + /* Process second sample for first tap */ + fnext1 = (q31_t) (((q63_t) fcurr0 * (*pk)) >> 32U); + fnext1 = (fnext1 << 1U) + fcurr1; + gnext1 = (q31_t) (((q63_t) fcurr1 * (*pk)) >> 32U); + gnext1 = (gnext1 << 1U) + fcurr0; + + /* Read next two samples from input buffer */ + /* f0(n+2) = x(n+2) */ + fcurr2 = *pSrc++; + fcurr3 = *pSrc++; + + /* Process third sample for first tap */ + fnext2 = (q31_t) (((q63_t) fcurr1 * (*pk)) >> 32U); + fnext2 = (fnext2 << 1U) + fcurr2; + gnext2 = (q31_t) (((q63_t) fcurr2 * (*pk)) >> 32U); + gnext2 = (gnext2 << 1U) + fcurr1; + + /* Process fourth sample for first tap */ + fnext3 = (q31_t) (((q63_t) fcurr2 * (*pk )) >> 32U); + fnext3 = (fnext3 << 1U) + fcurr3; + gnext3 = (q31_t) (((q63_t) fcurr3 * (*pk++)) >> 32U); + gnext3 = (gnext3 << 1U) + fcurr2; + + /* Copy only last input sample into the state buffer + which will be used for next samples processing */ + *px++ = fcurr3; + + /* Update of f values for next coefficient set processing */ + fcurr0 = fnext0; + fcurr1 = fnext1; + fcurr2 = fnext2; + fcurr3 = fnext3; + + /* Loop unrolling. Process 4 taps at a time . */ + stageCnt = (numStages - 1U) >> 2U; + + /* Loop over the number of taps. Unroll by a factor of 4. + Repeat until we've computed numStages-3 coefficients. */ + + /* Process 2nd, 3rd, 4th and 5th taps ... here */ + while (stageCnt > 0U) + { + /* Read g1(n-1), g3(n-1) .... from state */ + gcurr0 = *px; + + /* save g1(n) in state buffer */ + *px++ = gnext3; + + /* Process first sample for 2nd, 6th .. tap */ + /* Sample processing for K2, K6.... */ + /* f1(n) = f0(n) + K1 * g0(n-1) */ + fnext0 = (q31_t) (((q63_t) gcurr0 * (*pk)) >> 32U); + fnext0 = (fnext0 << 1U) + fcurr0; + + /* Process second sample for 2nd, 6th .. tap */ + /* for sample 2 processing */ + fnext1 = (q31_t) (((q63_t) gnext0 * (*pk)) >> 32U); + fnext1 = (fnext1 << 1U) + fcurr1; + + /* Process third sample for 2nd, 6th .. tap */ + fnext2 = (q31_t) (((q63_t) gnext1 * (*pk)) >> 32U); + fnext2 = (fnext2 << 1U) + fcurr2; + + /* Process fourth sample for 2nd, 6th .. tap */ + fnext3 = (q31_t) (((q63_t) gnext2 * (*pk)) >> 32U); + fnext3 = (fnext3 << 1U) + fcurr3; + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + /* Calculation of state values for next stage */ + gnext3 = (q31_t) (((q63_t) fcurr3 * (*pk)) >> 32U); + gnext3 = (gnext3 << 1U) + gnext2; + + gnext2 = (q31_t) (((q63_t) fcurr2 * (*pk)) >> 32U); + gnext2 = (gnext2 << 1U) + gnext1; + + gnext1 = (q31_t) (((q63_t) fcurr1 * (*pk)) >> 32U); + gnext1 = (gnext1 << 1U) + gnext0; + + gnext0 = (q31_t) (((q63_t) fcurr0 * (*pk++)) >> 32U); + gnext0 = (gnext0 << 1U) + gcurr0; + + + /* Read g2(n-1), g4(n-1) .... from state */ + gcurr0 = *px; + + /* save g1(n) in state buffer */ + *px++ = gnext3; + + /* Sample processing for K3, K7.... */ + /* Process first sample for 3rd, 7th .. tap */ + /* f3(n) = f2(n) + K3 * g2(n-1) */ + fcurr0 = (q31_t) (((q63_t) gcurr0 * (*pk)) >> 32U); + fcurr0 = (fcurr0 << 1U) + fnext0; + + /* Process second sample for 3rd, 7th .. tap */ + fcurr1 = (q31_t) (((q63_t) gnext0 * (*pk)) >> 32U); + fcurr1 = (fcurr1 << 1U) + fnext1; + + /* Process third sample for 3rd, 7th .. tap */ + fcurr2 = (q31_t) (((q63_t) gnext1 * (*pk)) >> 32U); + fcurr2 = (fcurr2 << 1U) + fnext2; + + /* Process fourth sample for 3rd, 7th .. tap */ + fcurr3 = (q31_t) (((q63_t) gnext2 * (*pk)) >> 32U); + fcurr3 = (fcurr3 << 1U) + fnext3; + + /* Calculation of state values for next stage */ + /* g3(n) = f2(n) * K3 + g2(n-1) */ + gnext3 = (q31_t) (((q63_t) fnext3 * (*pk)) >> 32U); + gnext3 = (gnext3 << 1U) + gnext2; + + gnext2 = (q31_t) (((q63_t) fnext2 * (*pk)) >> 32U); + gnext2 = (gnext2 << 1U) + gnext1; + + gnext1 = (q31_t) (((q63_t) fnext1 * (*pk)) >> 32U); + gnext1 = (gnext1 << 1U) + gnext0; + + gnext0 = (q31_t) (((q63_t) fnext0 * (*pk++)) >> 32U); + gnext0 = (gnext0 << 1U) + gcurr0; + + /* Read g1(n-1), g3(n-1) .... from state */ + gcurr0 = *px; + + /* save g1(n) in state buffer */ + *px++ = gnext3; + + /* Sample processing for K4, K8.... */ + /* Process first sample for 4th, 8th .. tap */ + /* f4(n) = f3(n) + K4 * g3(n-1) */ + fnext0 = (q31_t) (((q63_t) gcurr0 * (*pk)) >> 32U); + fnext0 = (fnext0 << 1U) + fcurr0; + + /* Process second sample for 4th, 8th .. tap */ + /* for sample 2 processing */ + fnext1 = (q31_t) (((q63_t) gnext0 * (*pk)) >> 32U); + fnext1 = (fnext1 << 1U) + fcurr1; + + /* Process third sample for 4th, 8th .. tap */ + fnext2 = (q31_t) (((q63_t) gnext1 * (*pk)) >> 32U); + fnext2 = (fnext2 << 1U) + fcurr2; + + /* Process fourth sample for 4th, 8th .. tap */ + fnext3 = (q31_t) (((q63_t) gnext2 * (*pk)) >> 32U); + fnext3 = (fnext3 << 1U) + fcurr3; + + /* g4(n) = f3(n) * K4 + g3(n-1) */ + /* Calculation of state values for next stage */ + gnext3 = (q31_t) (((q63_t) fcurr3 * (*pk)) >> 32U); + gnext3 = (gnext3 << 1U) + gnext2; + + gnext2 = (q31_t) (((q63_t) fcurr2 * (*pk)) >> 32U); + gnext2 = (gnext2 << 1U) + gnext1; + + gnext1 = (q31_t) (((q63_t) fcurr1 * (*pk)) >> 32U); + gnext1 = (gnext1 << 1U) + gnext0; + + gnext0 = (q31_t) (((q63_t) fcurr0 * (*pk++)) >> 32U); + gnext0 = (gnext0 << 1U) + gcurr0; + + /* Read g2(n-1), g4(n-1) .... from state */ + gcurr0 = *px; + + /* save g4(n) in state buffer */ + *px++ = gnext3; + + /* Sample processing for K5, K9.... */ + /* Process first sample for 5th, 9th .. tap */ + /* f5(n) = f4(n) + K5 * g4(n-1) */ + fcurr0 = (q31_t) (((q63_t) gcurr0 * (*pk)) >> 32U); + fcurr0 = (fcurr0 << 1U) + fnext0; + + /* Process second sample for 5th, 9th .. tap */ + fcurr1 = (q31_t) (((q63_t) gnext0 * (*pk)) >> 32U); + fcurr1 = (fcurr1 << 1U) + fnext1; + + /* Process third sample for 5th, 9th .. tap */ + fcurr2 = (q31_t) (((q63_t) gnext1 * (*pk)) >> 32U); + fcurr2 = (fcurr2 << 1U) + fnext2; + + /* Process fourth sample for 5th, 9th .. tap */ + fcurr3 = (q31_t) (((q63_t) gnext2 * (*pk)) >> 32U); + fcurr3 = (fcurr3 << 1U) + fnext3; + + /* Calculation of state values for next stage */ + /* g5(n) = f4(n) * K5 + g4(n-1) */ + gnext3 = (q31_t) (((q63_t) fnext3 * (*pk)) >> 32U); + gnext3 = (gnext3 << 1U) + gnext2; + + gnext2 = (q31_t) (((q63_t) fnext2 * (*pk)) >> 32U); + gnext2 = (gnext2 << 1U) + gnext1; + + gnext1 = (q31_t) (((q63_t) fnext1 * (*pk)) >> 32U); + gnext1 = (gnext1 << 1U) + gnext0; + + gnext0 = (q31_t) (((q63_t) fnext0 * (*pk++)) >> 32U); + gnext0 = (gnext0 << 1U) + gcurr0; + + stageCnt--; + } + + /* If the (filter length -1) is not a multiple of 4, compute the remaining filter taps */ + stageCnt = (numStages - 1U) % 0x4U; + + while (stageCnt > 0U) + { + gcurr0 = *px; + + /* save g value in state buffer */ + *px++ = gnext3; + + /* Process four samples for last three taps here */ + fnext0 = (q31_t) (((q63_t) gcurr0 * (*pk)) >> 32U); + fnext0 = (fnext0 << 1U) + fcurr0; + + fnext1 = (q31_t) (((q63_t) gnext0 * (*pk)) >> 32U); + fnext1 = (fnext1 << 1U) + fcurr1; + + fnext2 = (q31_t) (((q63_t) gnext1 * (*pk)) >> 32U); + fnext2 = (fnext2 << 1U) + fcurr2; + + fnext3 = (q31_t) (((q63_t) gnext2 * (*pk)) >> 32U); + fnext3 = (fnext3 << 1U) + fcurr3; + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext3 = (q31_t) (((q63_t) fcurr3 * (*pk)) >> 32U); + gnext3 = (gnext3 << 1U) + gnext2; + + gnext2 = (q31_t) (((q63_t) fcurr2 * (*pk)) >> 32U); + gnext2 = (gnext2 << 1U) + gnext1; + + gnext1 = (q31_t) (((q63_t) fcurr1 * (*pk)) >> 32U); + gnext1 = (gnext1 << 1U) + gnext0; + + gnext0 = (q31_t) (((q63_t) fcurr0 * (*pk++)) >> 32U); + gnext0 = (gnext0 << 1U) + gcurr0; + + /* Update of f values for next coefficient set processing */ + fcurr0 = fnext0; + fcurr1 = fnext1; + fcurr2 = fnext2; + fcurr3 = fnext3; + + stageCnt--; + } + + /* The results in the 4 accumulators, store in the destination buffer. */ + /* y(n) = fN(n) */ + *pDst++ = fcurr0; + *pDst++ = fcurr1; + *pDst++ = fcurr2; + *pDst++ = fcurr3; + + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* f0(n) = x(n) */ + fcurr0 = *pSrc++; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pk = pCoeffs; + + /* read g2(n) from state buffer */ + gcurr0 = *px; + + /* for sample 1 processing */ + /* f1(n) = f0(n) + K1 * g0(n-1) */ + fnext0 = (q31_t) (((q63_t) gcurr0 * (*pk)) >> 32U); + fnext0 = (fnext0 << 1U) + fcurr0; + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext0 = (q31_t) (((q63_t) fcurr0 * (*pk++)) >> 32U); + gnext0 = (gnext0 << 1U) + gcurr0; + + /* save g1(n) in state buffer */ + *px++ = fcurr0; + + /* f1(n) is saved in fcurr0 for next stage processing */ + fcurr0 = fnext0; + + stageCnt = (numStages - 1U); + + /* stage loop */ + while (stageCnt > 0U) + { + /* read g2(n) from state buffer */ + gcurr0 = *px; + + /* save g1(n) in state buffer */ + *px++ = gnext0; + + /* Sample processing for K2, K3.... */ + /* f2(n) = f1(n) + K2 * g1(n-1) */ + fnext0 = (q31_t) (((q63_t) gcurr0 * (*pk)) >> 32U); + fnext0 = (fnext0 << 1U) + fcurr0; + + /* g2(n) = f1(n) * K2 + g1(n-1) */ + gnext0 = (q31_t) (((q63_t) fcurr0 * (*pk++)) >> 32U); + gnext0 = (gnext0 << 1U) + gcurr0; + + /* f1(n) is saved in fcurr0 for next stage processing */ + fcurr0 = fnext0; + + stageCnt--; + } + + /* y(n) = fN(n) */ + *pDst++ = fcurr0; + + blkCnt--; + } + +#else +/* alternate version for CM0_FAMILY */ + + blkCnt = blockSize; + + while (blkCnt > 0U) + { + /* f0(n) = x(n) */ + fcurr0 = *pSrc++; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coeff pointer */ + pk = pCoeffs; + + /* read g0(n-1) from state buffer */ + gcurr0 = *px; + + /* for sample 1 processing */ + /* f1(n) = f0(n) + K1 * g0(n-1) */ + fnext0 = (q31_t) (((q63_t) gcurr0 * (*pk)) >> 32U); + fnext0 = (fnext << 1U) + fcurr0; + + /* g1(n) = f0(n) * K1 + g0(n-1) */ + gnext0 = (q31_t) (((q63_t) fcurr0 * (*pk++)) >> 32U); + gnext0 = (gnext0 << 1U) + gcurr0; + + /* save f0(n) in state buffer */ + *px++ = fcurr0; + + /* f1(n) is saved in fcurr for next stage processing */ + fcurr0 = fnext0; + + stageCnt = (numStages - 1U); + + /* stage loop */ + while (stageCnt > 0U) + { + /* read g1(n-1) from state buffer */ + gcurr0 = *px; + + /* save g0(n-1) in state buffer */ + *px++ = gnext0; + + /* Sample processing for K2, K3.... */ + /* f2(n) = f1(n) + K2 * g1(n-1) */ + fnext0 = (q31_t) (((q63_t) gcurr0 * (*pk)) >> 32U); + fnext0 = (fnext0 << 1U) + fcurr0; + + /* g2(n) = f1(n) * K2 + g1(n-1) */ + gnext0 = (q31_t) (((q63_t) fcurr0 * (*pk++)) >> 32U); + gnext0 = (gnext0 << 1U) + gcurr0; + + /* f1(n) is saved in fcurr0 for next stage processing */ + fcurr0 = fnext0; + + stageCnt--; + } + + /* y(n) = fN(n) */ + *pDst++ = fcurr0; + + blkCnt--; + } + +#endif /* #if !defined(ARM_MATH_CM0_FAMILY) */ + +} + +/** + @} end of FIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q15.c new file mode 100644 index 0000000..e20798e --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q15.c @@ -0,0 +1,332 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_q15.c + * Description: Q15 FIR filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR + @{ + */ + +/** + @brief Processing function for the Q15 FIR filter. + @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 + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both coefficients 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. + + @remark + Refer to \ref arm_fir_fast_q15() for a faster but less precise implementation of this function. + */ + +void arm_fir_q15( + const arm_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *pStateCurnt; /* Points to the current sample of the state */ + q15_t *px; /* Temporary pointer for state buffer */ + const q15_t *pb; /* Temporary pointer for coefficient buffer */ + q63_t acc0; /* Accumulators */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t tapCnt, blkCnt; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q63_t acc1, acc2, acc3; /* Accumulators */ + q31_t x0, x1, x2, c0; /* Temporary variables to hold state and coefficient values */ +#endif + + /* S->pState points to state array which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 output values simultaneously. + * The variables acc0 ... acc3 hold output values that are being computed: + * + * acc0 = b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0] + * acc1 = b[numTaps-1] * x[n-numTaps] + b[numTaps-2] * x[n-numTaps-1] + b[numTaps-3] * x[n-numTaps-2] +...+ b[0] * x[1] + * acc2 = b[numTaps-1] * x[n-numTaps+1] + b[numTaps-2] * x[n-numTaps] + b[numTaps-3] * x[n-numTaps-1] +...+ b[0] * x[2] + * acc3 = b[numTaps-1] * x[n-numTaps+2] + b[numTaps-2] * x[n-numTaps+1] + b[numTaps-3] * x[n-numTaps] +...+ b[0] * x[3] + */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Copy 4 new input samples into the state buffer. */ + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Typecast q15_t pointer to q31_t pointer for state reading in q31_t */ + px = pState; + + /* Typecast q15_t pointer to q31_t pointer for coefficient reading in q31_t */ + pb = pCoeffs; + + /* Read the first two samples from the state buffer: x[n-N], x[n-N-1] */ + x0 = read_q15x2_ia (&px); + + /* Read the third and forth samples from the state buffer: x[n-N-2], x[n-N-3] */ + x2 = read_q15x2_ia (&px); + + /* Loop over the number of taps. Unroll by a factor of 4. + Repeat until we've computed numTaps-(numTaps%4) coefficients. */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Read the first two coefficients using SIMD: b[N] and b[N-1] coefficients */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* acc0 += b[N] * x[n-N] + b[N-1] * x[n-N-1] */ + acc0 = __SMLALD(x0, c0, acc0); + + /* acc2 += b[N] * x[n-N-2] + b[N-1] * x[n-N-3] */ + acc2 = __SMLALD(x2, c0, acc2); + + /* pack x[n-N-1] and x[n-N-2] */ +#ifndef ARM_MATH_BIG_ENDIAN + x1 = __PKHBT(x2, x0, 0); +#else + x1 = __PKHBT(x0, x2, 0); +#endif + + /* Read state x[n-N-4], x[n-N-5] */ + x0 = read_q15x2_ia (&px); + + /* acc1 += b[N] * x[n-N-1] + b[N-1] * x[n-N-2] */ + acc1 = __SMLALDX(x1, c0, acc1); + + /* pack x[n-N-3] and x[n-N-4] */ +#ifndef ARM_MATH_BIG_ENDIAN + x1 = __PKHBT(x0, x2, 0); +#else + x1 = __PKHBT(x2, x0, 0); +#endif + + /* acc3 += b[N] * x[n-N-3] + b[N-1] * x[n-N-4] */ + acc3 = __SMLALDX(x1, c0, acc3); + + /* Read coefficients b[N-2], b[N-3] */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* acc0 += b[N-2] * x[n-N-2] + b[N-3] * x[n-N-3] */ + acc0 = __SMLALD(x2, c0, acc0); + + /* Read state x[n-N-6], x[n-N-7] with offset */ + x2 = read_q15x2_ia (&px); + + /* acc2 += b[N-2] * x[n-N-4] + b[N-3] * x[n-N-5] */ + acc2 = __SMLALD(x0, c0, acc2); + + /* acc1 += b[N-2] * x[n-N-3] + b[N-3] * x[n-N-4] */ + acc1 = __SMLALDX(x1, c0, acc1); + + /* pack x[n-N-5] and x[n-N-6] */ +#ifndef ARM_MATH_BIG_ENDIAN + x1 = __PKHBT(x2, x0, 0); +#else + x1 = __PKHBT(x0, x2, 0); +#endif + + /* acc3 += b[N-2] * x[n-N-5] + b[N-3] * x[n-N-6] */ + acc3 = __SMLALDX(x1, c0, acc3); + + /* Decrement tap count */ + tapCnt--; + } + + /* If the filter length is not a multiple of 4, compute the remaining filter taps. + This is always be 2 taps since the filter length is even. */ + if ((numTaps & 0x3U) != 0U) + { + /* Read last two coefficients */ + c0 = read_q15x2_ia ((q15_t **) &pb); + + /* Perform the multiply-accumulates */ + acc0 = __SMLALD(x0, c0, acc0); + acc2 = __SMLALD(x2, c0, acc2); + + /* pack state variables */ +#ifndef ARM_MATH_BIG_ENDIAN + x1 = __PKHBT(x2, x0, 0); +#else + x1 = __PKHBT(x0, x2, 0); +#endif + + /* Read last state variables */ + x0 = read_q15x2 (px); + + /* Perform the multiply-accumulates */ + acc1 = __SMLALDX(x1, c0, acc1); + + /* pack state variables */ +#ifndef ARM_MATH_BIG_ENDIAN + x1 = __PKHBT(x0, x2, 0); +#else + x1 = __PKHBT(x2, x0, 0); +#endif + + /* Perform the multiply-accumulates */ + acc3 = __SMLALDX(x1, c0, acc3); + } + + /* The results in the 4 accumulators are in 2.30 format. Convert to 1.15 with saturation. + Then store the 4 outputs in the destination buffer. */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pDst, __PKHBT(__SSAT((acc0 >> 15), 16), __SSAT((acc1 >> 15), 16), 16)); + write_q15x2_ia (&pDst, __PKHBT(__SSAT((acc2 >> 15), 16), __SSAT((acc3 >> 15), 16), 16)); +#else + write_q15x2_ia (&pDst, __PKHBT(__SSAT((acc1 >> 15), 16), __SSAT((acc0 >> 15), 16), 16)); + write_q15x2_ia (&pDst, __PKHBT(__SSAT((acc3 >> 15), 16), __SSAT((acc2 >> 15), 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Advance the state pointer by 4 to process the next group of 4 samples */ + pState = pState + 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining output samples */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of taps */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy two samples into state buffer */ + *pStateCurnt++ = *pSrc++; + + /* Set the accumulator to zero */ + acc0 = 0; + + /* Use SIMD to hold states and coefficients */ + px = pState; + pb = pCoeffs; + + tapCnt = numTaps >> 1U; + + do + { + acc0 += (q31_t) *px++ * *pb++; + acc0 += (q31_t) *px++ * *pb++; + + tapCnt--; + } + while (tapCnt > 0U); + + /* The result is in 2.30 format. Convert to 1.15 with saturation. + Then store the output in the destination buffer. */ + *pDst++ = (q15_t) (__SSAT((acc0 >> 15), 16)); + + /* Advance state pointer by 1 for the next sample */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCurnt = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = (numTaps - 1U) >> 2U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Calculate remaining number of copies */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy remaining data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of FIR group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q31.c new file mode 100644 index 0000000..c57371b --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q31.c @@ -0,0 +1,288 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_q31.c + * Description: Q31 FIR filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR + @{ + */ + +/** + @brief Processing function for 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 + @return none + + @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 log2(numTaps) bits. + After all multiply-accumulates are performed, the 2.62 accumulator is right shifted by 31 bits and saturated to 1.31 format to yield the final result. + + @remark + Refer to \ref arm_fir_fast_q31() for a faster but less precise implementation of this filter. + */ + +void arm_fir_q31( + const arm_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + q31_t *pState = S->pState; /* State pointer */ + const q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t *pStateCurnt; /* Points to the current sample of the state */ + q31_t *px; /* Temporary pointer for state buffer */ + const q31_t *pb; /* Temporary pointer for coefficient buffer */ + q63_t acc0; /* Accumulator */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t i, tapCnt, blkCnt; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q63_t acc1, acc2; /* Accumulators */ + q31_t x0, x1, x2; /* Temporary variables to hold state values */ + q31_t c0; /* Temporary variable to hold coefficient value */ +#endif + + /* S->pState points to state array which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 output values simultaneously. + * The variables acc0 ... acc3 hold output values that are being computed: + * + * acc0 = b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0] + * acc1 = b[numTaps-1] * x[n-numTaps] + b[numTaps-2] * x[n-numTaps-1] + b[numTaps-3] * x[n-numTaps-2] +...+ b[0] * x[1] + * acc2 = b[numTaps-1] * x[n-numTaps+1] + b[numTaps-2] * x[n-numTaps] + b[numTaps-3] * x[n-numTaps-1] +...+ b[0] * x[2] + * acc3 = b[numTaps-1] * x[n-numTaps+2] + b[numTaps-2] * x[n-numTaps+1] + b[numTaps-3] * x[n-numTaps] +...+ b[0] * x[3] + */ + + blkCnt = blockSize / 3; + + while (blkCnt > 0U) + { + /* Copy 3 new input samples into the state buffer. */ + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + + /* Read the first 2 samples from the state buffer: x[n-numTaps], x[n-numTaps-1] */ + x0 = *px++; + x1 = *px++; + + /* Loop unrolling: process 3 taps at a time. */ + tapCnt = numTaps / 3; + + while (tapCnt > 0U) + { + /* Read the b[numTaps] coefficient */ + c0 = *pb; + + /* Read x[n-numTaps-2] sample */ + x2 = *(px++); + + /* Perform the multiply-accumulates */ + acc0 += ((q63_t) x0 * c0); + acc1 += ((q63_t) x1 * c0); + acc2 += ((q63_t) x2 * c0); + + /* Read the coefficient and state */ + c0 = *(pb + 1U); + x0 = *(px++); + + /* Perform the multiply-accumulates */ + acc0 += ((q63_t) x1 * c0); + acc1 += ((q63_t) x2 * c0); + acc2 += ((q63_t) x0 * c0); + + /* Read the coefficient and state */ + c0 = *(pb + 2U); + x1 = *(px++); + + /* update coefficient pointer */ + pb += 3U; + + /* Perform the multiply-accumulates */ + acc0 += ((q63_t) x2 * c0); + acc1 += ((q63_t) x0 * c0); + acc2 += ((q63_t) x1 * c0); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + tapCnt = numTaps % 0x3U; + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *(pb++); + + /* Fetch 1 state variable */ + x2 = *(px++); + + /* Perform the multiply-accumulates */ + acc0 += ((q63_t) x0 * c0); + acc1 += ((q63_t) x1 * c0); + acc2 += ((q63_t) x2 * c0); + + /* Reuse the present sample states for next sample */ + x0 = x1; + x1 = x2; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Advance the state pointer by 3 to process the next group of 3 samples */ + pState = pState + 3; + + /* The result is in 2.30 format. Convert to 1.31 and store in destination buffer. */ + *pDst++ = (q31_t) (acc0 >> 31U); + *pDst++ = (q31_t) (acc1 >> 31U); + *pDst++ = (q31_t) (acc2 >> 31U); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining output samples */ + blkCnt = blockSize % 0x3U; + +#else + + /* Initialize blkCnt with number of taps */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy one sample at a time into state buffer */ + *pStateCurnt++ = *pSrc++; + + /* Set the accumulator to zero */ + acc0 = 0; + + /* Initialize state pointer */ + px = pState; + + /* Initialize Coefficient pointer */ + pb = pCoeffs; + + i = numTaps; + + /* Perform the multiply-accumulates */ + do + { + /* acc = b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0] */ + acc0 += (q63_t) *px++ * *pb++; + + i--; + } while (i > 0U); + + /* Result is in 2.62 format. Convert to 1.31 and store in destination buffer. */ + *pDst++ = (q31_t) (acc0 >> 31U); + + /* Advance state pointer by 1 for the next sample */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCurnt = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = (numTaps - 1U) >> 2U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Calculate remaining number of copies */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy remaining data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of FIR group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q7.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q7.c new file mode 100644 index 0000000..5f6d354 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_q7.c @@ -0,0 +1,323 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_q7.c + * Description: Q7 FIR filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR + @{ + */ + +/** + @brief Processing function for 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 + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 32-bit internal accumulator. + Both coefficients and state variables are represented in 1.7 format and multiplications yield a 2.14 result. + The 2.14 intermediate results are accumulated in a 32-bit accumulator in 18.14 format. + There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + The accumulator is converted to 18.7 format by discarding the low 7 bits. + Finally, the result is truncated to 1.7 format. + */ + +void arm_fir_q7( + const arm_fir_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize) +{ + q7_t *pState = S->pState; /* State pointer */ + const q7_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q7_t *pStateCurnt; /* Points to the current sample of the state */ + q7_t *px; /* Temporary pointer for state buffer */ + const q7_t *pb; /* Temporary pointer for coefficient buffer */ + q31_t acc0; /* Accumulators */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t i, tapCnt, blkCnt; /* Loop counters */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t acc1, acc2, acc3; /* Accumulators */ + q7_t x0, x1, x2, x3, c0; /* Temporary variables to hold state */ +#endif + + /* S->pState points to state array which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 output values simultaneously. + * The variables acc0 ... acc3 hold output values that are being computed: + * + * acc0 = b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0] + * acc1 = b[numTaps-1] * x[n-numTaps] + b[numTaps-2] * x[n-numTaps-1] + b[numTaps-3] * x[n-numTaps-2] +...+ b[0] * x[1] + * acc2 = b[numTaps-1] * x[n-numTaps+1] + b[numTaps-2] * x[n-numTaps] + b[numTaps-3] * x[n-numTaps-1] +...+ b[0] * x[2] + * acc3 = b[numTaps-1] * x[n-numTaps+2] + b[numTaps-2] * x[n-numTaps+1] + b[numTaps-3] * x[n-numTaps] +...+ b[0] * x[3] + */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Copy 4 new input samples into the state buffer. */ + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + *pStateCurnt++ = *pSrc++; + + /* Set all accumulators to zero */ + acc0 = 0; + acc1 = 0; + acc2 = 0; + acc3 = 0; + + /* Initialize state pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + + /* Read the first 3 samples from the state buffer: + * x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2] */ + x0 = *px++; + x1 = *px++; + x2 = *px++; + + /* Loop unrolling. Process 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + /* Loop over the number of taps. Unroll by a factor of 4. + Repeat until we've computed numTaps-4 coefficients. */ + while (tapCnt > 0U) + { + /* Read the b[numTaps] coefficient */ + c0 = *pb; + + /* Read x[n-numTaps-3] sample */ + x3 = *px; + + /* acc0 += b[numTaps] * x[n-numTaps] */ + acc0 += ((q15_t) x0 * c0); + + /* acc1 += b[numTaps] * x[n-numTaps-1] */ + acc1 += ((q15_t) x1 * c0); + + /* acc2 += b[numTaps] * x[n-numTaps-2] */ + acc2 += ((q15_t) x2 * c0); + + /* acc3 += b[numTaps] * x[n-numTaps-3] */ + acc3 += ((q15_t) x3 * c0); + + /* Read the b[numTaps-1] coefficient */ + c0 = *(pb + 1U); + + /* Read x[n-numTaps-4] sample */ + x0 = *(px + 1U); + + /* Perform the multiply-accumulates */ + acc0 += ((q15_t) x1 * c0); + acc1 += ((q15_t) x2 * c0); + acc2 += ((q15_t) x3 * c0); + acc3 += ((q15_t) x0 * c0); + + /* Read the b[numTaps-2] coefficient */ + c0 = *(pb + 2U); + + /* Read x[n-numTaps-5] sample */ + x1 = *(px + 2U); + + /* Perform the multiply-accumulates */ + acc0 += ((q15_t) x2 * c0); + acc1 += ((q15_t) x3 * c0); + acc2 += ((q15_t) x0 * c0); + acc3 += ((q15_t) x1 * c0); + + /* Read the b[numTaps-3] coefficients */ + c0 = *(pb + 3U); + + /* Read x[n-numTaps-6] sample */ + x2 = *(px + 3U); + + /* Perform the multiply-accumulates */ + acc0 += ((q15_t) x3 * c0); + acc1 += ((q15_t) x0 * c0); + acc2 += ((q15_t) x1 * c0); + acc3 += ((q15_t) x2 * c0); + + /* update coefficient pointer */ + pb += 4U; + px += 4U; + + /* Decrement loop counter */ + tapCnt--; + } + + /* If the filter length is not a multiple of 4, compute the remaining filter taps */ + tapCnt = numTaps % 0x4U; + + while (tapCnt > 0U) + { + /* Read coefficients */ + c0 = *(pb++); + + /* Fetch 1 state variable */ + x3 = *(px++); + + /* Perform the multiply-accumulates */ + acc0 += ((q15_t) x0 * c0); + acc1 += ((q15_t) x1 * c0); + acc2 += ((q15_t) x2 * c0); + acc3 += ((q15_t) x3 * c0); + + /* Reuse the present sample states for next sample */ + x0 = x1; + x1 = x2; + x2 = x3; + + /* Decrement loop counter */ + tapCnt--; + } + + /* The results in the 4 accumulators are in 2.62 format. Convert to 1.31 + Then store the 4 outputs in the destination buffer. */ + acc0 = __SSAT((acc0 >> 7U), 8); + *pDst++ = acc0; + acc1 = __SSAT((acc1 >> 7U), 8); + *pDst++ = acc1; + acc2 = __SSAT((acc2 >> 7U), 8); + *pDst++ = acc2; + acc3 = __SSAT((acc3 >> 7U), 8); + *pDst++ = acc3; + + /* Advance the state pointer by 4 to process the next group of 4 samples */ + pState = pState + 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining output samples */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of taps */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Copy one sample at a time into state buffer */ + *pStateCurnt++ = *pSrc++; + + /* Set the accumulator to zero */ + acc0 = 0; + + /* Initialize state pointer */ + px = pState; + + /* Initialize Coefficient pointer */ + pb = pCoeffs; + + i = numTaps; + + /* Perform the multiply-accumulates */ + do + { + acc0 += (q15_t) * (px++) * (*(pb++)); + i--; + } while (i > 0U); + + /* The result is in 2.14 format. Convert to 1.7 + Then store the output in the destination buffer. */ + *pDst++ = __SSAT((acc0 >> 7U), 8); + + /* Advance state pointer by 1 for the next sample */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the state buffer */ + pStateCurnt = S->pState; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time */ + tapCnt = (numTaps - 1U) >> 2U; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Calculate remaining number of copies */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of taps */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + /* Copy remaining data */ + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement the loop counter */ + tapCnt--; + } + +} + +/** + @} end of FIR group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_f32.c new file mode 100644 index 0000000..f44f037 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_f32.c @@ -0,0 +1,341 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_sparse_f32.c + * Description: Floating-point sparse FIR filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup FIR_Sparse Finite Impulse Response (FIR) Sparse Filters + + This group of functions implements sparse FIR filters. + Sparse FIR filters are equivalent to standard FIR filters except that most of the coefficients are equal to zero. + Sparse filters are used for simulating reflections in communications and audio applications. + + There are separate functions for Q7, Q15, Q31, and floating-point data types. + The functions operate on blocks of input and output data and each call to the function processes + blockSize samples through the filter. pSrc and + pDst points to input and output arrays respectively containing blockSize values. + + @par Algorithm + The sparse filter instant structure contains an array of tap indices pTapDelay which specifies the locations of the non-zero coefficients. + This is in addition to the coefficient array b. + The implementation essentially skips the multiplications by zero and leads to an efficient realization. +
+      y[n] = b[0] * x[n-pTapDelay[0]] + b[1] * x[n-pTapDelay[1]] + b[2] * x[n-pTapDelay[2]] + ...+ b[numTaps-1] * x[n-pTapDelay[numTaps-1]]
+  
+ @par + \image html FIRSparse.gif "Sparse FIR filter. b[n] represents the filter coefficients" + @par + pCoeffs points to a coefficient array of size numTaps; + pTapDelay points to an array of nonzero indices and is also of size numTaps; + pState points to a state array of size maxDelay + blockSize, where + maxDelay is the largest offset value that is ever used in the pTapDelay array. + Some of the processing functions also require temporary working buffers. + + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter. + Coefficient and offset arrays may be shared among several instances while state variable arrays cannot be shared. + There are separate instance structure declarations for each of the 4 supported data types. + + @par Initialization Functions + There is also an associated initialization function for each data type. + The initialization function performs the following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + numTaps, pCoeffs, pTapDelay, maxDelay, stateIndex, pState. Also set all of the values in pState to zero. + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + Set the values in the state buffer to zeros before static initialization. + The code below statically initializes each of the 4 different data type filter instance structures +
+      arm_fir_sparse_instance_f32 S = {numTaps, 0, pState, pCoeffs, maxDelay, pTapDelay};
+      arm_fir_sparse_instance_q31 S = {numTaps, 0, pState, pCoeffs, maxDelay, pTapDelay};
+      arm_fir_sparse_instance_q15 S = {numTaps, 0, pState, pCoeffs, maxDelay, pTapDelay};
+      arm_fir_sparse_instance_q7 S =  {numTaps, 0, pState, pCoeffs, maxDelay, pTapDelay};
+  
+ + @par Fixed-Point Behavior + Care must be taken when using the fixed-point versions of the sparse FIR filter 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 FIR_Sparse + @{ + */ + +/** + @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 + @return none + */ + +void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize) +{ + float32_t *pState = S->pState; /* State pointer */ + const float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t *px; /* Scratch buffer pointer */ + float32_t *py = pState; /* Temporary pointers for state buffer */ + float32_t *pb = pScratchIn; /* Temporary pointers for scratch buffer */ + float32_t *pOut; /* Destination pointer */ + int32_t *pTapDelay = S->pTapDelay; /* Pointer to the array containing offset of the non-zero tap values. */ + uint32_t delaySize = S->maxDelay + blockSize; /* state length */ + uint16_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + int32_t readIndex; /* Read index of the state buffer */ + uint32_t tapCnt, blkCnt; /* loop counters */ + float32_t coeff = *pCoeffs++; /* Read the first coefficient value */ + + + /* BlockSize of Input samples are copied into the state buffer */ + /* StateIndex points to the starting position to write in the state buffer */ + arm_circularWrite_f32((int32_t *) py, delaySize, &S->stateIndex, 1, (int32_t *) pSrc, 1, blockSize); + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_f32((int32_t *) py, delaySize, &readIndex, 1, + (int32_t *) pb, (int32_t *) pb, blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pOut = pDst; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform Multiplications and store in destination buffer */ + *pOut++ = *px++ * coeff; + + *pOut++ = *px++ * coeff; + + *pOut++ = *px++ * coeff; + + *pOut++ = *px++ * coeff; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiplication and store in destination buffer */ + *pOut++ = *px++ * coeff; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Load the coefficient value and + * increment the coefficient buffer for the next set of state values */ + coeff = *pCoeffs++; + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Loop over the number of taps. */ + tapCnt = (uint32_t) numTaps - 2U; + + while (tapCnt > 0U) + { + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_f32((int32_t *) py, delaySize, &readIndex, 1, + (int32_t *) pb, (int32_t *) pb, blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pOut = pDst; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + *pOut++ += *px++ * coeff; + + *pOut++ += *px++ * coeff; + + *pOut++ += *px++ * coeff; + + *pOut++ += *px++ * coeff; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + *pOut++ += *px++ * coeff; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Load the coefficient value and + * increment the coefficient buffer for the next set of state values */ + coeff = *pCoeffs++; + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Decrement tap loop counter */ + tapCnt--; + } + + /* Compute last tap without the final read of pTapDelay */ + + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_f32((int32_t *) py, delaySize, &readIndex, 1, + (int32_t *) pb, (int32_t *) pb, blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pOut = pDst; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + *pOut++ += *px++ * coeff; + *pOut++ += *px++ * coeff; + *pOut++ += *px++ * coeff; + *pOut++ += *px++ * coeff; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + *pOut++ += *px++ * coeff; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of FIR_Sparse group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_f32.c new file mode 100644 index 0000000..7745e71 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_f32.c @@ -0,0 +1,93 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_sparse_init_f32.c + * Description: Floating-point sparse FIR filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Sparse + @{ + */ + +/** + @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 + @return none + + @par Details + pCoeffs holds the filter coefficients and has length numTaps. + pState holds the filter's state variables and must be of length + maxDelay + blockSize, where maxDelay + is the maximum number of delay line values. + blockSize is the + number of samples processed by the arm_fir_sparse_f32() function. + */ + +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) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Assign TapDelay pointer */ + S->pTapDelay = pTapDelay; + + /* Assign MaxDelay */ + S->maxDelay = maxDelay; + + /* reset the stateIndex to 0 */ + S->stateIndex = 0U; + + /* Clear state buffer and size is always maxDelay + blockSize */ + memset(pState, 0, (maxDelay + blockSize) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of FIR_Sparse group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q15.c new file mode 100644 index 0000000..d07d611 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q15.c @@ -0,0 +1,93 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_sparse_init_q15.c + * Description: Q15 sparse FIR filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Sparse + @{ + */ + +/** + @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 + @return none + + @par Details + pCoeffs holds the filter coefficients and has length numTaps. + pState holds the filter's state variables and must be of length + maxDelay + blockSize, where maxDelay + is the maximum number of delay line values. + blockSize is the + number of words processed by arm_fir_sparse_q15() function. + */ + +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) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Assign TapDelay pointer */ + S->pTapDelay = pTapDelay; + + /* Assign MaxDelay */ + S->maxDelay = maxDelay; + + /* reset the stateIndex to 0 */ + S->stateIndex = 0U; + + /* Clear state buffer and size is always maxDelay + blockSize */ + memset(pState, 0, (maxDelay + blockSize) * sizeof(q15_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of FIR_Sparse group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q31.c new file mode 100644 index 0000000..7c32cea --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q31.c @@ -0,0 +1,92 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_sparse_init_q31.c + * Description: Q31 sparse FIR filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Sparse + @{ + */ + +/** + @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 + @return none + + @par Details + pCoeffs holds the filter coefficients and has length numTaps. + pState holds the filter's state variables and must be of length + maxDelay + blockSize, where maxDelay + is the maximum number of delay line values. + blockSize is the number of words processed by arm_fir_sparse_q31() function. + */ + +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) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Assign TapDelay pointer */ + S->pTapDelay = pTapDelay; + + /* Assign MaxDelay */ + S->maxDelay = maxDelay; + + /* reset the stateIndex to 0 */ + S->stateIndex = 0U; + + /* Clear state buffer and size is always maxDelay + blockSize */ + memset(pState, 0, (maxDelay + blockSize) * sizeof(q31_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of FIR_Sparse group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q7.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q7.c new file mode 100644 index 0000000..98153f3 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_init_q7.c @@ -0,0 +1,93 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_sparse_init_q7.c + * Description: Q7 sparse FIR filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Sparse + @{ + */ + +/** + @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 + @return none + + @par Details + pCoeffs holds the filter coefficients and has length numTaps. + pState holds the filter's state variables and must be of length + maxDelay + blockSize, where maxDelay + is the maximum number of delay line values. + blockSize is the + number of samples processed by the arm_fir_sparse_q7() function. + */ + +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) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Assign TapDelay pointer */ + S->pTapDelay = pTapDelay; + + /* Assign MaxDelay */ + S->maxDelay = maxDelay; + + /* reset the stateIndex to 0 */ + S->stateIndex = 0U; + + /* Clear state buffer and size is always maxDelay + blockSize */ + memset(pState, 0, (maxDelay + blockSize) * sizeof(q7_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of FIR_Sparse group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q15.c new file mode 100644 index 0000000..9cea93e --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q15.c @@ -0,0 +1,341 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_sparse_q15.c + * Description: Q15 sparse FIR filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Sparse + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The 1.15 x 1.15 multiplications yield a 2.30 result and these are added to a 2.30 accumulator. + Thus the full precision of the multiplications is maintained but there is only a single guard bit in the accumulator. + If the accumulator result overflows it will wrap around rather than saturate. + After all multiply-accumulates are performed, the 2.30 accumulator is truncated to 2.15 format and then saturated to 1.15 format. + In order to avoid overflows the input signal or coefficients must be scaled down by log2(numTaps) bits. + */ + +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) +{ + q15_t *pState = S->pState; /* State pointer */ + const q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *px; /* Temporary pointers for scratch buffer */ + q15_t *py = pState; /* Temporary pointers for state buffer */ + q15_t *pb = pScratchIn; /* Temporary pointers for scratch buffer */ + q15_t *pOut = pDst; /* Working pointer for output */ + int32_t *pTapDelay = S->pTapDelay; /* Pointer to the array containing offset of the non-zero tap values. */ + uint32_t delaySize = S->maxDelay + blockSize; /* state length */ + uint16_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + int32_t readIndex; /* Read index of the state buffer */ + uint32_t tapCnt, blkCnt; /* loop counters */ + q31_t *pScr2 = pScratchOut; /* Working pointer for scratch buffer of output values */ + q15_t coeff = *pCoeffs++; /* Read the first coefficient value */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t in1, in2; /* Temporary variables */ +#endif + + /* BlockSize of Input samples are copied into the state buffer */ + /* StateIndex points to the starting position to write in the state buffer */ + arm_circularWrite_q15(py, (int32_t) delaySize, &S->stateIndex, 1,pSrc, 1, blockSize); + + /* Loop over the number of taps. */ + tapCnt = numTaps; + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_q15(py, (int32_t) delaySize, &readIndex, 1, + pb, pb, (int32_t) blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pScratchOut = pScr2; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform multiplication and store in the scratch buffer */ + *pScratchOut++ = ((q31_t) *px++ * coeff); + *pScratchOut++ = ((q31_t) *px++ * coeff); + *pScratchOut++ = ((q31_t) *px++ * coeff); + *pScratchOut++ = ((q31_t) *px++ * coeff); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiplication and store in the scratch buffer */ + *pScratchOut++ = ((q31_t) *px++ * coeff); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Load the coefficient value and + * increment the coefficient buffer for the next set of state values */ + coeff = *pCoeffs++; + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Loop over the number of taps. */ + tapCnt = (uint32_t) numTaps - 2U; + + while (tapCnt > 0U) + { + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_q15(py, (int32_t) delaySize, &readIndex, 1, + pb, pb, (int32_t) blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pScratchOut = pScr2; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + *pScratchOut++ += (q31_t) *px++ * coeff; + *pScratchOut++ += (q31_t) *px++ * coeff; + *pScratchOut++ += (q31_t) *px++ * coeff; + *pScratchOut++ += (q31_t) *px++ * coeff; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + *pScratchOut++ += (q31_t) *px++ * coeff; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Load the coefficient value and + * increment the coefficient buffer for the next set of state values */ + coeff = *pCoeffs++; + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Decrement loop counter */ + tapCnt--; + } + + /* Compute last tap without the final read of pTapDelay */ + + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_q15(py, (int32_t) delaySize, &readIndex, 1, + pb, pb, (int32_t) blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pScratchOut = pScr2; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + *pScratchOut++ += (q31_t) *px++ * coeff; + *pScratchOut++ += (q31_t) *px++ * coeff; + *pScratchOut++ += (q31_t) *px++ * coeff; + *pScratchOut++ += (q31_t) *px++ * coeff; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + *pScratchOut++ += (q31_t) *px++ * coeff; + + /* Decrement loop counter */ + blkCnt--; + } + + /* All the output values are in pScratchOut buffer. + Convert them into 1.15 format, saturate and store in the destination buffer. */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + in1 = *pScr2++; + in2 = *pScr2++; + +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT((q15_t) __SSAT(in1 >> 15, 16), (q15_t) __SSAT(in2 >> 15, 16), 16)); +#else + write_q15x2_ia (&pOut, __PKHBT((q15_t) __SSAT(in2 >> 15, 16), (q15_t) __SSAT(in1 >> 15, 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + in1 = *pScr2++; + in2 = *pScr2++; + +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pOut, __PKHBT((q15_t) __SSAT(in1 >> 15, 16), (q15_t) __SSAT(in2 >> 15, 16), 16)); +#else + write_q15x2_ia (&pOut, __PKHBT((q15_t) __SSAT(in2 >> 15, 16), (q15_t) __SSAT(in1 >> 15, 16), 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + *pOut++ = (q15_t) __SSAT(*pScr2++ >> 15, 16); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of FIR_Sparse group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q31.c new file mode 100644 index 0000000..86d3e1d --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q31.c @@ -0,0 +1,357 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_sparse_q31.c + * Description: Q31 sparse FIR filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Sparse + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The 1.31 x 1.31 multiplications are truncated to 2.30 format. + This leads to loss of precision on the intermediate multiplications and provides only a single guard bit. + If the accumulator result overflows, it wraps around rather than saturate. + In order to avoid overflows the input signal or coefficients must be scaled down by log2(numTaps) bits. + */ + +void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize) +{ + q31_t *pState = S->pState; /* State pointer */ + const q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t *px; /* Scratch buffer pointer */ + q31_t *py = pState; /* Temporary pointers for state buffer */ + q31_t *pb = pScratchIn; /* Temporary pointers for scratch buffer */ + q31_t *pOut; /* Destination pointer */ + int32_t *pTapDelay = S->pTapDelay; /* Pointer to the array containing offset of the non-zero tap values. */ + uint32_t delaySize = S->maxDelay + blockSize; /* state length */ + uint16_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + int32_t readIndex; /* Read index of the state buffer */ + uint32_t tapCnt, blkCnt; /* loop counters */ + q31_t coeff = *pCoeffs++; /* Read the first coefficient value */ + q31_t in; + q63_t out; /* Temporary output variable */ + + + /* BlockSize of Input samples are copied into the state buffer */ + /* StateIndex points to the starting position to write in the state buffer */ + arm_circularWrite_f32((int32_t *) py, delaySize, &S->stateIndex, 1, + (int32_t *) pSrc, 1, blockSize); + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_f32((int32_t *) py, delaySize, &readIndex, 1, + (int32_t *) pb, (int32_t *) pb, blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pOut = pDst; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform Multiplications and store in destination buffer */ + *pOut++ = (q31_t) (((q63_t) *px++ * coeff) >> 32); + + *pOut++ = (q31_t) (((q63_t) *px++ * coeff) >> 32); + + *pOut++ = (q31_t) (((q63_t) *px++ * coeff) >> 32); + + *pOut++ = (q31_t) (((q63_t) *px++ * coeff) >> 32); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiplication and store in destination buffer */ + *pOut++ = (q31_t) (((q63_t) *px++ * coeff) >> 32); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Load the coefficient value and + * increment the coefficient buffer for the next set of state values */ + coeff = *pCoeffs++; + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Loop over the number of taps. */ + tapCnt = (uint32_t) numTaps - 2U; + + while (tapCnt > 0U) + { + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_f32((int32_t *) py, delaySize, &readIndex, 1, + (int32_t *) pb, (int32_t *) pb, blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pOut = pDst; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + out = *pOut; + out += ((q63_t) *px++ * coeff) >> 32; + *pOut++ = (q31_t) (out); + + out = *pOut; + out += ((q63_t) *px++ * coeff) >> 32; + *pOut++ = (q31_t) (out); + + out = *pOut; + out += ((q63_t) *px++ * coeff) >> 32; + *pOut++ = (q31_t) (out); + + out = *pOut; + out += ((q63_t) *px++ * coeff) >> 32; + *pOut++ = (q31_t) (out); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + out = *pOut; + out += ((q63_t) *px++ * coeff) >> 32; + *pOut++ = (q31_t) (out); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Load the coefficient value and + * increment the coefficient buffer for the next set of state values */ + coeff = *pCoeffs++; + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Decrement tap loop counter */ + tapCnt--; + } + + /* Compute last tap without the final read of pTapDelay */ + + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_f32((int32_t *) py, delaySize, &readIndex, 1, + (int32_t *) pb, (int32_t *) pb, blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pOut = pDst; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + out = *pOut; + out += ((q63_t) * px++ * coeff) >> 32; + *pOut++ = (q31_t) (out); + + out = *pOut; + out += ((q63_t) * px++ * coeff) >> 32; + *pOut++ = (q31_t) (out); + + out = *pOut; + out += ((q63_t) * px++ * coeff) >> 32; + *pOut++ = (q31_t) (out); + + out = *pOut; + out += ((q63_t) * px++ * coeff) >> 32; + *pOut++ = (q31_t) (out); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + out = *pOut; + out += ((q63_t) *px++ * coeff) >> 32; + *pOut++ = (q31_t) (out); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Working output pointer is updated */ + pOut = pDst; + + /* Output is converted into 1.31 format. */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + in = *pOut << 1; + *pOut++ = in; + in = *pOut << 1; + *pOut++ = in; + in = *pOut << 1; + *pOut++ = in; + in = *pOut << 1; + *pOut++ = in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + in = *pOut << 1; + *pOut++ = in; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of FIR_Sparse group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q7.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q7.c new file mode 100644 index 0000000..7a2b57f --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_fir_sparse_q7.c @@ -0,0 +1,341 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fir_sparse_q7.c + * Description: Q7 sparse FIR filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup FIR_Sparse + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 32-bit internal accumulator. + Both coefficients and state variables are represented in 1.7 format and multiplications yield a 2.14 result. + The 2.14 intermediate results are accumulated in a 32-bit accumulator in 18.14 format. + There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + The accumulator is then converted to 18.7 format by discarding the low 7 bits. + Finally, the result is truncated to 1.7 format. + */ + +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) +{ + q7_t *pState = S->pState; /* State pointer */ + const q7_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q7_t *px; /* Scratch buffer pointer */ + q7_t *py = pState; /* Temporary pointers for state buffer */ + q7_t *pb = pScratchIn; /* Temporary pointers for scratch buffer */ + q7_t *pOut = pDst; /* Destination pointer */ + int32_t *pTapDelay = S->pTapDelay; /* Pointer to the array containing offset of the non-zero tap values. */ + uint32_t delaySize = S->maxDelay + blockSize; /* state length */ + uint16_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + int32_t readIndex; /* Read index of the state buffer */ + uint32_t tapCnt, blkCnt; /* loop counters */ + q31_t *pScr2 = pScratchOut; /* Working pointer for scratch buffer of output values */ + q31_t in; + q7_t coeff = *pCoeffs++; /* Read the coefficient value */ + +#if defined (ARM_MATH_LOOPUNROLL) + q7_t in1, in2, in3, in4; +#endif + + /* BlockSize of Input samples are copied into the state buffer */ + /* StateIndex points to the starting position to write in the state buffer */ + arm_circularWrite_q7(py, (int32_t) delaySize, &S->stateIndex, 1, pSrc, 1, blockSize); + + /* Loop over the number of taps. */ + tapCnt = numTaps; + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_q7(py, (int32_t) delaySize, &readIndex, 1, + pb, pb, (int32_t) blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pScratchOut = pScr2; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform multiplication and store in the scratch buffer */ + *pScratchOut++ = ((q31_t) *px++ * coeff); + *pScratchOut++ = ((q31_t) *px++ * coeff); + *pScratchOut++ = ((q31_t) *px++ * coeff); + *pScratchOut++ = ((q31_t) *px++ * coeff); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiplication and store in the scratch buffer */ + *pScratchOut++ = ((q31_t) *px++ * coeff); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Load the coefficient value and + * increment the coefficient buffer for the next set of state values */ + coeff = *pCoeffs++; + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Loop over the number of taps. */ + tapCnt = (uint32_t) numTaps - 2U; + + while (tapCnt > 0U) + { + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_q7(py, (int32_t) delaySize, &readIndex, 1, + pb, pb, (int32_t) blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pScratchOut = pScr2; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + in = *pScratchOut + ((q31_t) * px++ * coeff); + *pScratchOut++ = in; + in = *pScratchOut + ((q31_t) * px++ * coeff); + *pScratchOut++ = in; + in = *pScratchOut + ((q31_t) * px++ * coeff); + *pScratchOut++ = in; + in = *pScratchOut + ((q31_t) * px++ * coeff); + *pScratchOut++ = in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + in = *pScratchOut + ((q31_t) *px++ * coeff); + *pScratchOut++ = in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Load the coefficient value and + * increment the coefficient buffer for the next set of state values */ + coeff = *pCoeffs++; + + /* Read Index, from where the state buffer should be read, is calculated. */ + readIndex = (int32_t) (S->stateIndex - blockSize) - *pTapDelay++; + + /* Wraparound of readIndex */ + if (readIndex < 0) + { + readIndex += (int32_t) delaySize; + } + + /* Decrement loop counter */ + tapCnt--; + } + + /* Compute last tap without the final read of pTapDelay */ + + /* Working pointer for state buffer is updated */ + py = pState; + + /* blockSize samples are read from the state buffer */ + arm_circularRead_q7(py, (int32_t) delaySize, &readIndex, 1, + pb, pb, (int32_t) blockSize, 1, blockSize); + + /* Working pointer for the scratch buffer of state values */ + px = pb; + + /* Working pointer for scratch buffer of output values */ + pScratchOut = pScr2; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + in = *pScratchOut + ((q31_t) *px++ * coeff); + *pScratchOut++ = in; + in = *pScratchOut + ((q31_t) *px++ * coeff); + *pScratchOut++ = in; + in = *pScratchOut + ((q31_t) *px++ * coeff); + *pScratchOut++ = in; + in = *pScratchOut + ((q31_t) *px++ * coeff); + *pScratchOut++ = in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Perform Multiply-Accumulate */ + in = *pScratchOut + ((q31_t) *px++ * coeff); + *pScratchOut++ = in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* All the output values are in pScratchOut buffer. + Convert them into 1.15 format, saturate and store in the destination buffer. */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time. */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + in1 = (q7_t) __SSAT(*pScr2++ >> 7, 8); + in2 = (q7_t) __SSAT(*pScr2++ >> 7, 8); + in3 = (q7_t) __SSAT(*pScr2++ >> 7, 8); + in4 = (q7_t) __SSAT(*pScr2++ >> 7, 8); + + write_q7x4_ia (&pOut, __PACKq7(in1, in2, in3, in4)); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + *pOut++ = (q7_t) __SSAT(*pScr2++ >> 7, 8); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of FIR_Sparse group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_f32.c new file mode 100644 index 0000000..c48efe3 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_f32.c @@ -0,0 +1,354 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_iir_lattice_f32.c + * Description: Floating-point IIR Lattice filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup IIR_Lattice Infinite Impulse Response (IIR) Lattice Filters + + This set of functions implements lattice filters + for Q15, Q31 and floating-point data types. Lattice filters are used in a + variety of adaptive filter applications. The filter structure has feedforward and + feedback components and the net impulse response is infinite length. + The functions operate on blocks + of input and output data and each call to the function processes + blockSize samples through the filter. pSrc and + pDst point to input and output arrays containing blockSize values. + + @par Algorithm + \image html IIRLattice.gif "Infinite Impulse Response Lattice filter" + @par +
+      fN(n)   = x(n)
+      fm-1(n) = fm(n) - km * gm-1(n-1)   for m = N, N-1, ..., 1
+      gm(n)   = km * fm-1(n) + gm-1(n-1) for m = N, N-1, ..., 1
+      y(n)    = vN * gN(n) + vN-1 * gN-1(n) + ...+ v0 * g0(n)
+  
+ @par + pkCoeffs points to array of reflection coefficients of size numStages. + Reflection Coefficients are stored in time-reversed order. + @par +
+     {kN, kN-1, ..., k1}
+  
+ @par + pvCoeffs points to the array of ladder coefficients of size (numStages+1). + Ladder coefficients are stored in time-reversed order. +
+      {vN, vN-1, ..., v0}
+  
+ @par + pState points to a state array of size numStages + blockSize. + The state variables shown in the figure above (the g values) are stored in the pState array. + The state variables are updated after each block of data is processed; the coefficients are untouched. + + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter. + Coefficient arrays may be shared among several instances while state variable arrays cannot be shared. + There are separate instance structure declarations for each of the 3 supported data types. + + @par Initialization Functions + There is also an associated initialization function for each data type. + The initialization function performs the following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + numStages, pkCoeffs, pvCoeffs, pState. Also set all of the values in pState to zero. + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + Set the values in the state buffer to zeros and then manually initialize the instance structure as follows: +
+      arm_iir_lattice_instance_f32 S = {numStages, pState, pkCoeffs, pvCoeffs};
+      arm_iir_lattice_instance_q31 S = {numStages, pState, pkCoeffs, pvCoeffs};
+      arm_iir_lattice_instance_q15 S = {numStages, pState, pkCoeffs, pvCoeffs};
+  
+ @par + where numStages is the number of stages in the filter; pState points to the state buffer array; + pkCoeffs points to array of the reflection coefficients; pvCoeffs points to the array of ladder coefficients. + + @par Fixed-Point Behavior + Care must be taken when using the fixed-point versions of the IIR lattice filter 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 IIR_Lattice + @{ + */ + +/** + @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 + @return none + */ + +void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + float32_t *pState = S->pState; /* State pointer */ + float32_t *pStateCur; /* State current pointer */ + float32_t acc; /* Accumlator */ + float32_t fnext1, fnext2, gcurr1, gnext; /* Temporary variables for lattice stages */ + float32_t *px1, *px2, *pk, *pv; /* Temporary pointers for state and coef */ + uint32_t numStages = S->numStages; /* Number of stages */ + uint32_t blkCnt, tapCnt; /* Temporary variables for counts */ + +#if defined (ARM_MATH_LOOPUNROLL) + float32_t gcurr2; /* Temporary variables for lattice stages */ + float32_t k1, k2; + float32_t v1, v2, v3, v4; +#endif + + /* initialise loop count */ + blkCnt = blockSize; + + /* Sample processing */ + while (blkCnt > 0U) + { + /* Read Sample from input buffer */ + /* fN(n) = x(n) */ + fnext2 = *pSrc++; + + /* Initialize Ladder coeff pointer */ + pv = &S->pvCoeffs[0]; + + /* Initialize Reflection coeff pointer */ + pk = &S->pkCoeffs[0]; + + /* Initialize state read pointer */ + px1 = pState; + + /* Initialize state write pointer */ + px2 = pState; + + /* Set accumulator to zero */ + acc = 0.0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = (numStages) >> 2U; + + while (tapCnt > 0U) + { + /* Read gN-1(n-1) from state buffer */ + gcurr1 = *px1; + + /* read reflection coefficient kN */ + k1 = *pk; + + /* fN-1(n) = fN(n) - kN * gN-1(n-1) */ + fnext1 = fnext2 - (k1 * gcurr1); + + /* read ladder coefficient vN */ + v1 = *pv; + + /* read next reflection coefficient kN-1 */ + k2 = *(pk + 1U); + + /* Read gN-2(n-1) from state buffer */ + gcurr2 = *(px1 + 1U); + + /* read next ladder coefficient vN-1 */ + v2 = *(pv + 1U); + + /* fN-2(n) = fN-1(n) - kN-1 * gN-2(n-1) */ + fnext2 = fnext1 - (k2 * gcurr2); + + /* gN(n) = kN * fN-1(n) + gN-1(n-1) */ + gnext = gcurr1 + (k1 * fnext1); + + /* read reflection coefficient kN-2 */ + k1 = *(pk + 2U); + + /* write gN(n) into state for next sample processing */ + *px2++ = gnext; + + /* Read gN-3(n-1) from state buffer */ + gcurr1 = *(px1 + 2U); + + /* y(n) += gN(n) * vN */ + acc += (gnext * v1); + + /* fN-3(n) = fN-2(n) - kN-2 * gN-3(n-1) */ + fnext1 = fnext2 - (k1 * gcurr1); + + /* gN-1(n) = kN-1 * fN-2(n) + gN-2(n-1) */ + gnext = gcurr2 + (k2 * fnext2); + + /* Read gN-4(n-1) from state buffer */ + gcurr2 = *(px1 + 3U); + + /* y(n) += gN-1(n) * vN-1 */ + acc += (gnext * v2); + + /* read reflection coefficient kN-3 */ + k2 = *(pk + 3U); + + /* write gN-1(n) into state for next sample processing */ + *px2++ = gnext; + + /* fN-4(n) = fN-3(n) - kN-3 * gN-4(n-1) */ + fnext2 = fnext1 - (k2 * gcurr2); + + /* gN-2(n) = kN-2 * fN-3(n) + gN-3(n-1) */ + gnext = gcurr1 + (k1 * fnext1); + + /* read ladder coefficient vN-2 */ + v3 = *(pv + 2U); + + /* y(n) += gN-2(n) * vN-2 */ + acc += (gnext * v3); + + /* write gN-2(n) into state for next sample processing */ + *px2++ = gnext; + + /* update pointer */ + pk += 4U; + + /* gN-3(n) = kN-3 * fN-4(n) + gN-4(n-1) */ + gnext = (fnext2 * k2) + gcurr2; + + /* read next ladder coefficient vN-3 */ + v4 = *(pv + 3U); + + /* y(n) += gN-4(n) * vN-4 */ + acc += (gnext * v4); + + /* write gN-3(n) into state for next sample processing */ + *px2++ = gnext; + + /* update pointers */ + px1 += 4U; + pv += 4U; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numStages % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numStages; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + gcurr1 = *px1++; + /* Process sample for last taps */ + fnext1 = fnext2 - ((*pk) * gcurr1); + gnext = (fnext1 * (*pk++)) + gcurr1; + /* Output samples for last taps */ + acc += (gnext * (*pv++)); + *px2++ = gnext; + fnext2 = fnext1; + + /* Decrement loop counter */ + tapCnt--; + } + + /* y(n) += g0(n) * v0 */ + acc += (fnext2 * (*pv)); + + *px2++ = fnext2; + + /* write out into pDst */ + *pDst++ = acc; + + /* Advance the state pointer by 4 to process the next group of 4 samples */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. Now copy last S->numStages samples to start of the buffer + for the preperation of next frame process */ + + /* Points to the start of the state buffer */ + pStateCur = &S->pState[0]; + pState = &S->pState[blockSize]; + + /* Copy data */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numStages >> 2U; + + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numStages % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + tapCnt = numStages; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of IIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_f32.c new file mode 100644 index 0000000..bd9f933 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_f32.c @@ -0,0 +1,77 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_iir_lattice_init_f32.c + * Description: Floating-point IIR lattice filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup IIR_Lattice + @{ + */ + +/** + @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 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 + @return none + */ + +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) +{ + /* Assign filter taps */ + S->numStages = numStages; + + /* Assign reflection coefficient pointer */ + S->pkCoeffs = pkCoeffs; + + /* Assign ladder coefficient pointer */ + S->pvCoeffs = pvCoeffs; + + /* Clear state buffer and size is always blockSize + numStages */ + memset(pState, 0, (numStages + blockSize) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of IIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_q15.c new file mode 100644 index 0000000..01abf48 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_q15.c @@ -0,0 +1,77 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_iir_lattice_init_q15.c + * Description: Q15 IIR lattice filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup IIR_Lattice + @{ + */ + +/** + @brief Initialization function for the Q15 IIR lattice filter. + @param[in] S points to an instance of the 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 + @return none + */ + +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) +{ + /* Assign filter taps */ + S->numStages = numStages; + + /* Assign reflection coefficient pointer */ + S->pkCoeffs = pkCoeffs; + + /* Assign ladder coefficient pointer */ + S->pvCoeffs = pvCoeffs; + + /* Clear state buffer and size is always blockSize + numStages */ + memset(pState, 0, (numStages + blockSize) * sizeof(q15_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of IIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_q31.c new file mode 100644 index 0000000..b472f6c --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_init_q31.c @@ -0,0 +1,77 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_iir_lattice_init_q31.c + * Description: Initialization function for the Q31 IIR lattice filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup IIR_Lattice + @{ + */ + +/** + @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 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 + @return none + */ + +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) +{ + /* Assign filter taps */ + S->numStages = numStages; + + /* Assign reflection coefficient pointer */ + S->pkCoeffs = pkCoeffs; + + /* Assign ladder coefficient pointer */ + S->pvCoeffs = pvCoeffs; + + /* Clear state buffer and size is always blockSize + numStages */ + memset(pState, 0, (numStages + blockSize) * sizeof(q31_t)); + + /* Assign state pointer */ + S->pState = pState; +} + +/** + @} end of IIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_q15.c new file mode 100644 index 0000000..9dbea81 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_q15.c @@ -0,0 +1,396 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_iir_lattice_q15.c + * Description: Q15 IIR Lattice filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup IIR_Lattice + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + Both coefficients 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. + */ + +void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + q15_t *pState = S->pState; /* State pointer */ + q15_t *pStateCur; /* State current pointer */ + q31_t fcurr, fnext = 0, gcurr = 0, gnext; /* Temporary variables for lattice stages */ + q63_t acc; /* Accumlator */ + q15_t *px1, *px2, *pk, *pv; /* Temporary pointers for state and coef */ + uint32_t numStages = S->numStages; /* Number of stages */ + uint32_t blkCnt, tapCnt; /* Temporary variables for counts */ + q15_t out; /* Temporary variable for output */ + +#if defined (ARM_MATH_DSP) && defined (ARM_MATH_LOOPUNROLL) + q15_t gnext1, gnext2; /* Temporary variables for lattice stages */ + q31_t v; /* Temporary variable for ladder coefficient */ +#endif + + /* initialise loop count */ + blkCnt = blockSize; + +#if defined (ARM_MATH_DSP) + + /* Sample processing */ + while (blkCnt > 0U) + { + /* Read Sample from input buffer */ + /* fN(n) = x(n) */ + fcurr = *pSrc++; + + /* Initialize Ladder coeff pointer */ + pv = &S->pvCoeffs[0]; + + /* Initialize Reflection coeff pointer */ + pk = &S->pkCoeffs[0]; + + /* Initialize state read pointer */ + px1 = pState; + + /* Initialize state write pointer */ + px2 = pState; + + /* Set accumulator to zero */ + acc = 0; + + /* Process sample for first tap */ + gcurr = *px1++; + /* fN-1(n) = fN(n) - kN * gN-1(n-1) */ + fnext = fcurr - (((q31_t) gcurr * (*pk)) >> 15); + fnext = __SSAT(fnext, 16); + + /* gN(n) = kN * fN-1(n) + gN-1(n-1) */ + gnext = (((q31_t) fnext * (*pk++)) >> 15) + gcurr; + gnext = __SSAT(gnext, 16); + + /* write gN(n) into state for next sample processing */ + *px2++ = (q15_t) gnext; + + /* y(n) += gN(n) * vN */ + acc += (q31_t) ((gnext * (*pv++))); + + /* Update f values for next coefficient processing */ + fcurr = fnext; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = (numStages - 1U) >> 2U; + + while (tapCnt > 0U) + { + /* Process sample for 2nd, 6th ...taps */ + /* Read gN-2(n-1) from state buffer */ + gcurr = *px1++; + /* fN-2(n) = fN-1(n) - kN-1 * gN-2(n-1) */ + fnext = fcurr - (((q31_t) gcurr * (*pk)) >> 15); + fnext = __SSAT(fnext, 16); + /* gN-1(n) = kN-1 * fN-2(n) + gN-2(n-1) */ + gnext = (((q31_t) fnext * (*pk++)) >> 15) + gcurr; + gnext1 = (q15_t) __SSAT(gnext, 16); + /* write gN-1(n) into state for next sample processing */ + *px2++ = (q15_t) gnext1; + + /* Process sample for 3nd, 7th ...taps */ + /* Read gN-3(n-1) from state buffer */ + gcurr = *px1++; + /* Process sample for 3rd, 7th .. taps */ + /* fN-3(n) = fN-2(n) - kN-2 * gN-3(n-1) */ + fcurr = fnext - (((q31_t) gcurr * (*pk)) >> 15); + fcurr = __SSAT(fcurr, 16); + /* gN-2(n) = kN-2 * fN-3(n) + gN-3(n-1) */ + gnext = (((q31_t) fcurr * (*pk++)) >> 15) + gcurr; + gnext2 = (q15_t) __SSAT(gnext, 16); + /* write gN-2(n) into state */ + *px2++ = (q15_t) gnext2; + + /* Read vN-1 and vN-2 at a time */ + v = read_q15x2_ia (&pv); + + /* Pack gN-1(n) and gN-2(n) */ + +#ifndef ARM_MATH_BIG_ENDIAN + gnext = __PKHBT(gnext1, gnext2, 16); +#else + gnext = __PKHBT(gnext2, gnext1, 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* y(n) += gN-1(n) * vN-1 */ + /* process for gN-5(n) * vN-5, gN-9(n) * vN-9 ... */ + /* y(n) += gN-2(n) * vN-2 */ + /* process for gN-6(n) * vN-6, gN-10(n) * vN-10 ... */ + acc = __SMLALD(gnext, v, acc); + + /* Process sample for 4th, 8th ...taps */ + /* Read gN-4(n-1) from state buffer */ + gcurr = *px1++; + /* Process sample for 4th, 8th .. taps */ + /* fN-4(n) = fN-3(n) - kN-3 * gN-4(n-1) */ + fnext = fcurr - (((q31_t) gcurr * (*pk)) >> 15); + fnext = __SSAT(fnext, 16); + /* gN-3(n) = kN-3 * fN-1(n) + gN-1(n-1) */ + gnext = (((q31_t) fnext * (*pk++)) >> 15) + gcurr; + gnext1 = (q15_t) __SSAT(gnext, 16); + /* write gN-3(n) for the next sample process */ + *px2++ = (q15_t) gnext1; + + /* Process sample for 5th, 9th ...taps */ + /* Read gN-5(n-1) from state buffer */ + gcurr = *px1++; + /* Process sample for 5th, 9th .. taps */ + /* fN-5(n) = fN-4(n) - kN-4 * gN-5(n-1) */ + fcurr = fnext - (((q31_t) gcurr * (*pk)) >> 15); + fcurr = __SSAT(fcurr, 16); + /* gN-4(n) = kN-4 * fN-5(n) + gN-5(n-1) */ + gnext = (((q31_t) fcurr * (*pk++)) >> 15) + gcurr; + gnext2 = (q15_t) __SSAT(gnext, 16); + /* write gN-4(n) for the next sample process */ + *px2++ = (q15_t) gnext2; + + /* Read vN-3 and vN-4 at a time */ + v = read_q15x2_ia (&pv); + + /* Pack gN-3(n) and gN-4(n) */ +#ifndef ARM_MATH_BIG_ENDIAN + gnext = __PKHBT(gnext1, gnext2, 16); +#else + gnext = __PKHBT(gnext2, gnext1, 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* y(n) += gN-4(n) * vN-4 */ + /* process for gN-8(n) * vN-8, gN-12(n) * vN-12 ... */ + /* y(n) += gN-3(n) * vN-3 */ + /* process for gN-7(n) * vN-7, gN-11(n) * vN-11 ... */ + acc = __SMLALD(gnext, v, acc); + + /* Decrement loop counter */ + tapCnt--; + } + + fnext = fcurr; + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numStages - 1U) % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + tapCnt = (numStages - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + gcurr = *px1++; + /* Process sample for last taps */ + fnext = fcurr - (((q31_t) gcurr * (*pk)) >> 15); + fnext = __SSAT(fnext, 16); + gnext = (((q31_t) fnext * (*pk++)) >> 15) + gcurr; + gnext = __SSAT(gnext, 16); + + /* Output samples for last taps */ + acc += (q31_t) (((q31_t) gnext * (*pv++))); + *px2++ = (q15_t) gnext; + fcurr = fnext; + + /* Decrement loop counter */ + tapCnt--; + } + + /* y(n) += g0(n) * v0 */ + acc += (q31_t) (((q31_t) fnext * (*pv++))); + + out = (q15_t) __SSAT(acc >> 15, 16); + *px2++ = (q15_t) fnext; + + /* write out into pDst */ + *pDst++ = out; + + /* Advance the state pointer by 4 to process the next group of 4 samples */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. Now copy last S->numStages samples to start of the buffer + for the preperation of next frame process */ + + /* Points to the start of the state buffer */ + pStateCur = &S->pState[0]; + pState = &S->pState[blockSize]; + + /* copy data */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numStages >> 2U; + + while (tapCnt > 0U) + { + write_q15x2_ia (&pStateCur, read_q15x2_ia (&pState)); + write_q15x2_ia (&pStateCur, read_q15x2_ia (&pState)); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numStages % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + tapCnt = (numStages - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +#else /* #if defined (ARM_MATH_DSP) */ + + /* Sample processing */ + while (blkCnt > 0U) + { + /* Read Sample from input buffer */ + /* fN(n) = x(n) */ + fcurr = *pSrc++; + + /* Initialize Ladder coeff pointer */ + pv = &S->pvCoeffs[0]; + + /* Initialize Reflection coeff pointer */ + pk = &S->pkCoeffs[0]; + + /* Initialize state read pointer */ + px1 = pState; + + /* Initialize state write pointer */ + px2 = pState; + + /* Set accumulator to zero */ + acc = 0; + + tapCnt = numStages; + + while (tapCnt > 0U) + { + gcurr = *px1++; + /* Process sample */ + /* fN-1(n) = fN(n) - kN * gN-1(n-1) */ + fnext = fcurr - ((gcurr * (*pk)) >> 15); + fnext = __SSAT(fnext, 16); + + /* gN(n) = kN * fN-1(n) + gN-1(n-1) */ + gnext = ((fnext * (*pk++)) >> 15) + gcurr; + gnext = __SSAT(gnext, 16); + + /* Output samples */ + /* y(n) += gN(n) * vN */ + acc += (q31_t) ((gnext * (*pv++))); + + /* write gN(n) into state for next sample processing */ + *px2++ = (q15_t) gnext; + + /* Update f values for next coefficient processing */ + fcurr = fnext; + + tapCnt--; + } + + /* y(n) += g0(n) * v0 */ + acc += (q31_t) ((fnext * (*pv++))); + + out = (q15_t) __SSAT(acc >> 15, 16); + *px2++ = (q15_t) fnext; + + /* write out into pDst */ + *pDst++ = out; + + /* Advance the state pointer by 1 to process the next group of samples */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. Now copy last S->numStages samples to start of the buffer + for the preperation of next frame process */ + + /* Points to the start of the state buffer */ + pStateCur = &S->pState[0]; + pState = &S->pState[blockSize]; + + tapCnt = numStages; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +#endif /* #if defined (ARM_MATH_DSP) */ + +} + +/** + @} end of IIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_q31.c new file mode 100644 index 0000000..c4b9a76 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_iir_lattice_q31.c @@ -0,0 +1,356 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_iir_lattice_q31.c + * Description: Q31 IIR Lattice filter processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup IIR_Lattice + @{ + */ + +/** + @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 + @return none + + @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*log2(numStages) bits. + After all multiply-accumulates are performed, the 2.62 accumulator is saturated to 1.32 format and then truncated to 1.31 format. + */ + +void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + q31_t *pState = S->pState; /* State pointer */ + q31_t *pStateCur; /* State current pointer */ + q31_t fcurr, fnext = 0, gcurr = 0, gnext; /* Temporary variables for lattice stages */ + q63_t acc; /* Accumlator */ + q31_t *px1, *px2, *pk, *pv; /* Temporary pointers for state and coef */ + uint32_t numStages = S->numStages; /* Number of stages */ + uint32_t blkCnt, tapCnt; /* Temporary variables for counts */ + + + /* initialise loop count */ + blkCnt = blockSize; + +#if defined (ARM_MATH_DSP) + + /* Sample processing */ + while (blkCnt > 0U) + { + /* Read Sample from input buffer */ + /* fN(n) = x(n) */ + fcurr = *pSrc++; + + /* Initialize Ladder coeff pointer */ + pv = &S->pvCoeffs[0]; + + /* Initialize Reflection coeff pointer */ + pk = &S->pkCoeffs[0]; + + /* Initialize state read pointer */ + px1 = pState; + + /* Initialize state write pointer */ + px2 = pState; + + /* Set accumulator to zero */ + acc = 0; + + /* Process sample for first tap */ + gcurr = *px1++; + /* fN-1(n) = fN(n) - kN * gN-1(n-1) */ + fnext = __QSUB(fcurr, (q31_t) (((q63_t) gcurr * (*pk )) >> 31)); + + /* gN(n) = kN * fN-1(n) + gN-1(n-1) */ + gnext = __QADD(gcurr, (q31_t) (((q63_t) fnext * (*pk++)) >> 31)); + + /* write gN-1(n-1) into state for next sample processing */ + *px2++ = gnext; + + /* y(n) += gN(n) * vN */ + acc += ((q63_t) gnext * *pv++); + + /* Update f values for next coefficient processing */ + fcurr = fnext; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = (numStages - 1U) >> 2U; + + while (tapCnt > 0U) + { + /* Process sample for 2nd, 6th ...taps */ + /* Read gN-2(n-1) from state buffer */ + gcurr = *px1++; + /* fN-2(n) = fN-1(n) - kN-1 * gN-2(n-1) */ + fnext = __QSUB(fcurr, (q31_t) (((q63_t) gcurr * (*pk )) >> 31)); + /* gN-1(n) = kN-1 * fN-2(n) + gN-2(n-1) */ + gnext = __QADD(gcurr, (q31_t) (((q63_t) fnext * (*pk++)) >> 31)); + /* y(n) += gN-1(n) * vN-1 */ + /* process for gN-5(n) * vN-5, gN-9(n) * vN-9 ... */ + acc += ((q63_t) gnext * *pv++); + /* write gN-1(n) into state for next sample processing */ + *px2++ = gnext; + + /* Process sample for 3nd, 7th ...taps */ + /* Read gN-3(n-1) from state buffer */ + gcurr = *px1++; + /* Process sample for 3rd, 7th .. taps */ + /* fN-3(n) = fN-2(n) - kN-2 * gN-3(n-1) */ + fcurr = __QSUB(fnext, (q31_t) (((q63_t) gcurr * (*pk )) >> 31)); + /* gN-2(n) = kN-2 * fN-3(n) + gN-3(n-1) */ + gnext = __QADD(gcurr, (q31_t) (((q63_t) fcurr * (*pk++)) >> 31)); + /* y(n) += gN-2(n) * vN-2 */ + /* process for gN-6(n) * vN-6, gN-10(n) * vN-10 ... */ + acc += ((q63_t) gnext * *pv++); + /* write gN-2(n) into state for next sample processing */ + *px2++ = gnext; + + /* Process sample for 4th, 8th ...taps */ + /* Read gN-4(n-1) from state buffer */ + gcurr = *px1++; + /* Process sample for 4th, 8th .. taps */ + /* fN-4(n) = fN-3(n) - kN-3 * gN-4(n-1) */ + fnext = __QSUB(fcurr, (q31_t) (((q63_t) gcurr * (*pk )) >> 31)); + /* gN-3(n) = kN-3 * fN-4(n) + gN-4(n-1) */ + gnext = __QADD(gcurr, (q31_t) (((q63_t) fnext * (*pk++)) >> 31)); + /* y(n) += gN-3(n) * vN-3 */ + /* process for gN-7(n) * vN-7, gN-11(n) * vN-11 ... */ + acc += ((q63_t) gnext * *pv++); + /* write gN-3(n) into state for next sample processing */ + *px2++ = gnext; + + /* Process sample for 5th, 9th ...taps */ + /* Read gN-5(n-1) from state buffer */ + gcurr = *px1++; + /* Process sample for 5th, 9th .. taps */ + /* fN-5(n) = fN-4(n) - kN-4 * gN-1(n-1) */ + fcurr = __QSUB(fnext, (q31_t) (((q63_t) gcurr * (*pk )) >> 31)); + /* gN-4(n) = kN-4 * fN-5(n) + gN-5(n-1) */ + gnext = __QADD(gcurr, (q31_t) (((q63_t) fcurr * (*pk++)) >> 31)); + /* y(n) += gN-4(n) * vN-4 */ + /* process for gN-8(n) * vN-8, gN-12(n) * vN-12 ... */ + acc += ((q63_t) gnext * *pv++); + + /* write gN-4(n) into state for next sample processing */ + *px2++ = gnext; + + /* Decrement loop counter */ + tapCnt--; + } + + fnext = fcurr; + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numStages - 1U) % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + tapCnt = (numStages - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + gcurr = *px1++; + /* Process sample for last taps */ + fnext = __QSUB(fcurr, (q31_t) (((q63_t) gcurr * (*pk )) >> 31)); + gnext = __QADD(gcurr, (q31_t) (((q63_t) fnext * (*pk++)) >> 31)); + + /* Output samples for last taps */ + acc += ((q63_t) gnext * *pv++); + *px2++ = gnext; + fcurr = fnext; + + /* Decrement loop counter */ + tapCnt--; + } + + /* y(n) += g0(n) * v0 */ + acc += ((q63_t) fnext * *pv++); + + *px2++ = fnext; + + /* write out into pDst */ + *pDst++ = (q31_t) (acc >> 31U); + + /* Advance the state pointer by 4 to process the next group of 4 samples */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. Now copy last S->numStages samples to start of the buffer + for the preperation of next frame process */ + + /* Points to the start of the state buffer */ + pStateCur = &S->pState[0]; + pState = &S->pState[blockSize]; + + /* Copy data */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numStages >> 2U; + + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numStages % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + tapCnt = (numStages - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +#else /* #if defined (ARM_MATH_DSP) */ + + /* Sample processing */ + while (blkCnt > 0U) + { + /* Read Sample from input buffer */ + /* fN(n) = x(n) */ + fcurr = *pSrc++; + + /* Initialize Ladder coeff pointer */ + pv = &S->pvCoeffs[0]; + + /* Initialize Reflection coeff pointer */ + pk = &S->pkCoeffs[0]; + + /* Initialize state read pointer */ + px1 = pState; + + /* Initialize state write pointer */ + px2 = pState; + + /* Set accumulator to zero */ + acc = 0; + + tapCnt = numStages; + + while (tapCnt > 0U) + { + gcurr = *px1++; + /* Process sample */ + /* fN-1(n) = fN(n) - kN * gN-1(n-1) */ + fnext = clip_q63_to_q31(((q63_t) fcurr - ((q31_t) (((q63_t) gcurr * (*pk )) >> 31)))); + + /* gN(n) = kN * fN-1(n) + gN-1(n-1) */ + gnext = clip_q63_to_q31(((q63_t) gcurr + ((q31_t) (((q63_t) fnext * (*pk++)) >> 31)))); + + /* Output samples */ + /* y(n) += gN(n) * vN */ + acc += ((q63_t) gnext * *pv++); + + /* write gN-1(n-1) into state for next sample processing */ + *px2++ = gnext; + + /* Update f values for next coefficient processing */ + fcurr = fnext; + + tapCnt--; + } + + /* y(n) += g0(n) * v0 */ + acc += ((q63_t) fnext * *pv++); + + *px2++ = fnext; + + /* write out into pDst */ + *pDst++ = (q31_t) (acc >> 31U); + + /* Advance the state pointer by 1 to process the next group of samples */ + pState = pState + 1U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. Now copy last S->numStages samples to start of the buffer + for the preperation of next frame process */ + + /* Points to the start of the state buffer */ + pStateCur = &S->pState[0]; + pState = &S->pState[blockSize]; + + tapCnt = numStages; + + /* Copy data */ + while (tapCnt > 0U) + { + *pStateCur++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +#endif /* #if defined (ARM_MATH_DSP) */ + +} + +/** + @} end of IIR_Lattice group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_f32.c new file mode 100644 index 0000000..07a9526 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_f32.c @@ -0,0 +1,360 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_f32.c + * Description: Processing function for the floating-point LMS filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup LMS Least Mean Square (LMS) Filters + + LMS filters are a class of adaptive filters that are able to "learn" an unknown transfer functions. + LMS filters use a gradient descent method in which the filter coefficients are updated based on the instantaneous error signal. + Adaptive filters are often used in communication systems, equalizers, and noise removal. + The CMSIS DSP Library contains LMS filter functions that operate on Q15, Q31, and floating-point data types. + The library also contains normalized LMS filters in which the filter coefficient adaptation is indepedent of the level of the input signal. + + An LMS filter consists of two components as shown below. + The first component is a standard transversal or FIR filter. + The second component is a coefficient update mechanism. + The LMS filter has two input signals. + The "input" feeds the FIR filter while the "reference input" corresponds to the desired output of the FIR filter. + That is, the FIR filter coefficients are updated so that the output of the FIR filter matches the reference input. + The filter coefficient update mechanism is based on the difference between the FIR filter output and the reference input. + This "error signal" tends towards zero as the filter adapts. + The LMS processing functions accept the input and reference input signals and generate the filter output and error signal. + \image html LMS.gif "Internal structure of the Least Mean Square filter" + + The functions operate on blocks of data and each call to the function processes + blockSize samples through the filter. + pSrc points to input signal, pRef points to reference signal, + pOut points to output signal and pErr points to error signal. + All arrays contain blockSize values. + + The functions operate on a block-by-block basis. + Internally, the filter coefficients b[n] are updated on a sample-by-sample basis. + The convergence of the LMS filter is slower compared to the normalized LMS algorithm. + + @par Algorithm + The output signal y[n] is computed by a standard FIR filter: +
+      y[n] = b[0] * x[n] + b[1] * x[n-1] + b[2] * x[n-2] + ...+ b[numTaps-1] * x[n-numTaps+1]
+  
+ + @par + The error signal equals the difference between the reference signal d[n] and the filter output: +
+      e[n] = d[n] - y[n].
+  
+ + @par + After each sample of the error signal is computed, the filter coefficients b[k] are updated on a sample-by-sample basis: +
+      b[k] = b[k] + e[n] * mu * x[n-k],  for k=0, 1, ..., numTaps-1
+  
+ where mu is the step size and controls the rate of coefficient convergence. + @par + In the APIs, pCoeffs points to a coefficient array of size numTaps. + Coefficients are stored in time reversed order. + @par +
+     {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ @par + pState points to a state array of size numTaps + blockSize - 1. + Samples in the state buffer are stored in the order: + @par +
+     {x[n-numTaps+1], x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2]....x[0], x[1], ..., x[blockSize-1]}
+  
+ @par + Note that the length of the state buffer exceeds the length of the coefficient array by blockSize-1 samples. + The increased state buffer length allows circular addressing, which is traditionally used in FIR filters, + to be avoided and yields a significant speed improvement. + The state variables are updated after each block of data is processed. + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter and + coefficient and state arrays cannot be shared among instances. + There are separate instance structure declarations for each of the 3 supported data types. + + @par Initialization Functions + There is also an associated initialization function for each data type. + The initialization function performs the following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + numTaps, pCoeffs, mu, postShift (not for f32), pState. Also set all of the values in pState to zero. + + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + Set the values in the state buffer to zeros before static initialization. + The code below statically initializes each of the 3 different data type filter instance structures +
+     arm_lms_instance_f32 S = {numTaps, pState, pCoeffs, mu};
+     arm_lms_instance_q31 S = {numTaps, pState, pCoeffs, mu, postShift};
+     arm_lms_instance_q15 S = {numTaps, pState, pCoeffs, mu, postShift};
+  
+ where numTaps is the number of filter coefficients in the filter; pState is the address of the state buffer; + pCoeffs is the address of the coefficient buffer; mu is the step size parameter; and postShift is the shift applied to coefficients. + + @par Fixed-Point Behavior + Care must be taken when using the Q15 and Q31 versions of the LMS filter. + The following issues must be considered: + - Scaling of coefficients + - Overflow and saturation + + @par Scaling of Coefficients + Filter coefficients are represented as fractional values and + coefficients are restricted to lie in the range [-1 +1). + The fixed-point functions have an additional scaling parameter postShift. + At the output of the filter's accumulator is a shift register which shifts the result by postShift bits. + This essentially scales the filter coefficients by 2^postShift and + allows the filter coefficients to exceed the range [+1 -1). + The value of postShift is set by the user based on the expected gain through the system being modeled. + + @par Overflow and Saturation + Overflow and saturation behavior of the fixed-point Q15 and Q31 versions are + described separately as part of the function specific documentation below. + */ + +/** + @addtogroup LMS + @{ + */ + +/** + @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 + @return none + */ + +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) +{ + float32_t *pState = S->pState; /* State pointer */ + float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t *pStateCurnt; /* Points to the current sample of the state */ + float32_t *px, *pb; /* Temporary pointers for state and coefficient buffers */ + float32_t mu = S->mu; /* Adaptive factor */ + float32_t acc, e; /* Accumulator, error */ + float32_t w; /* Weight factor */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t tapCnt, blkCnt; /* Loop counters */ + + /* Initializations of error, difference, Coefficient update */ + e = 0.0f; + w = 0.0f; + + /* S->pState points to state array which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + + /* initialise loop count */ + blkCnt = blockSize; + + while (blkCnt > 0U) + { + /* Copy the new input sample into the state buffer */ + *pStateCurnt++ = *pSrc++; + + /* Initialize pState pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + + /* Set the accumulator to zero */ + acc = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + acc += (*px++) * (*pb++); + + acc += (*px++) * (*pb++); + + acc += (*px++) * (*pb++); + + acc += (*px++) * (*pb++); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + acc += (*px++) * (*pb++); + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Store the result from accumulator into the destination buffer. */ + *pOut++ = acc; + + /* Compute and store error */ + e = (float32_t) *pRef++ - acc; + *pErr++ = e; + + /* Calculation of Weighting factor for updating filter coefficients */ + w = e * mu; + + /* Initialize pState pointer */ + /* Advance state pointer by 1 for the next sample */ + px = pState++; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + /* Update filter coefficients */ + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + *pb += w * (*px++); + pb++; + + *pb += w * (*px++); + pb++; + + *pb += w * (*px++); + pb++; + + *pb += w * (*px++); + pb++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + *pb += w * (*px++); + pb++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the pState buffer */ + pStateCurnt = S->pState; + + /* copy data */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = (numTaps - 1U) >> 2U; + + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of LMS group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_f32.c new file mode 100644 index 0000000..f418f46 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_f32.c @@ -0,0 +1,81 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_init_f32.c + * Description: Floating-point LMS filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @addtogroup LMS + @{ + */ + +/** + @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 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 + @return none + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+     {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ The initial filter coefficients serve as a starting point for the adaptive filter. + pState points to an array of length numTaps+blockSize-1 samples, where blockSize is the number of input samples processed by each call to arm_lms_f32(). + */ + +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) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always blockSize + numTaps */ + memset(pState, 0, (numTaps + (blockSize - 1)) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; + + /* Assign Step size value */ + S->mu = mu; +} + +/** + @} end of LMS group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_q15.c new file mode 100644 index 0000000..fe0a5c5 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_q15.c @@ -0,0 +1,92 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_init_q15.c + * Description: Q15 LMS filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup LMS + @{ + */ + +/** + @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 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. + @return none + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+     {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ The initial filter coefficients serve as a starting point for the adaptive filter. + pState points to the array of state variables and size of array is + numTaps+blockSize-1 samples, where blockSize is the number of + input samples processed by each call to arm_lms_q15(). + */ + +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) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always blockSize + numTaps - 1 */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(q15_t)); + + /* Assign state pointer */ + S->pState = pState; + + /* Assign Step size value */ + S->mu = mu; + + /* Assign postShift value to be applied */ + S->postShift = postShift; +} + +/** + @} end of LMS group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_q31.c new file mode 100644 index 0000000..3410b9f --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_init_q31.c @@ -0,0 +1,92 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_init_q31.c + * Description: Q31 LMS filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup LMS + @{ + */ + +/** + @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 + @return none + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+     {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ The initial filter coefficients serve as a starting point for the adaptive filter. + pState points to an array of length numTaps+blockSize-1 samples, + where blockSize is the number of input samples processed by each call to + arm_lms_q31(). + */ + +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) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always blockSize + numTaps - 1 */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(q31_t)); + + /* Assign state pointer */ + S->pState = pState; + + /* Assign Step size value */ + S->mu = mu; + + /* Assign postShift value to be applied */ + S->postShift = postShift; +} + +/** + @} end of LMS group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_f32.c new file mode 100644 index 0000000..5ae9229 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_f32.c @@ -0,0 +1,374 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_norm_f32.c + * Description: Processing function for the floating-point NLMS filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @defgroup LMS_NORM Normalized LMS Filters + + This set of functions implements a commonly used adaptive filter. + It is related to the Least Mean Square (LMS) adaptive filter and includes an additional normalization + factor which increases the adaptation rate of the filter. + The CMSIS DSP Library contains normalized LMS filter functions that operate on Q15, Q31, and floating-point data types. + + A normalized least mean square (NLMS) filter consists of two components as shown below. + The first component is a standard transversal or FIR filter. + The second component is a coefficient update mechanism. + The NLMS filter has two input signals. + The "input" feeds the FIR filter while the "reference input" corresponds to the desired output of the FIR filter. + That is, the FIR filter coefficients are updated so that the output of the FIR filter matches the reference input. + The filter coefficient update mechanism is based on the difference between the FIR filter output and the reference input. + This "error signal" tends towards zero as the filter adapts. + The NLMS processing functions accept the input and reference input signals and generate the filter output and error signal. + \image html LMS.gif "Internal structure of the NLMS adaptive filter" + + The functions operate on blocks of data and each call to the function processes + blockSize samples through the filter. + pSrc points to input signal, pRef points to reference signal, + pOut points to output signal and pErr points to error signal. + All arrays contain blockSize values. + + The functions operate on a block-by-block basis. + Internally, the filter coefficients b[n] are updated on a sample-by-sample basis. + The convergence of the LMS filter is slower compared to the normalized LMS algorithm. + + @par Algorithm + The output signal y[n] is computed by a standard FIR filter: +
+      y[n] = b[0] * x[n] + b[1] * x[n-1] + b[2] * x[n-2] + ...+ b[numTaps-1] * x[n-numTaps+1]
+  
+ + @par + The error signal equals the difference between the reference signal d[n] and the filter output: +
+      e[n] = d[n] - y[n].
+  
+ + @par + After each sample of the error signal is computed the instanteous energy of the filter state variables is calculated: +
+     E = x[n]^2 + x[n-1]^2 + ... + x[n-numTaps+1]^2.
+  
+ The filter coefficients b[k] are then updated on a sample-by-sample basis: +
+      b[k] = b[k] + e[n] * (mu/E) * x[n-k],  for k=0, 1, ..., numTaps-1
+  
+ where mu is the step size and controls the rate of coefficient convergence. + @par + In the APIs, pCoeffs points to a coefficient array of size numTaps. + Coefficients are stored in time reversed order. + @par +
+     {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ @par + pState points to a state array of size numTaps + blockSize - 1. + Samples in the state buffer are stored in the order: + @par +
+     {x[n-numTaps+1], x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2]....x[0], x[1], ..., x[blockSize-1]}
+  
+ @par + Note that the length of the state buffer exceeds the length of the coefficient array by blockSize-1 samples. + The increased state buffer length allows circular addressing, which is traditionally used in FIR filters, + to be avoided and yields a significant speed improvement. + The state variables are updated after each block of data is processed. + + @par Instance Structure + The coefficients and state variables for a filter are stored together in an instance data structure. + A separate instance structure must be defined for each filter and + coefficient and state arrays cannot be shared among instances. + There are separate instance structure declarations for each of the 3 supported data types. + + @par Initialization Functions + There is also an associated initialization function for each data type. + The initialization function performs the following operations: + - Sets the values of the internal structure fields. + - Zeros out the values in the state buffer. + To do this manually without calling the init function, assign the follow subfields of the instance structure: + numTaps, pCoeffs, mu, energy, x0, pState. Also set all of the values in pState to zero. + For Q7, Q15, and Q31 the following fields must also be initialized; + recipTable, postShift + @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 Q15 and Q31 versions of the normalised LMS filter. + The following issues must be considered: + - Scaling of coefficients + - Overflow and saturation + + @par Scaling of Coefficients + Filter coefficients are represented as fractional values and + coefficients are restricted to lie in the range [-1 +1). + The fixed-point functions have an additional scaling parameter postShift. + At the output of the filter's accumulator is a shift register which shifts the result by postShift bits. + This essentially scales the filter coefficients by 2^postShift and + allows the filter coefficients to exceed the range [+1 -1). + The value of postShift is set by the user based on the expected gain through the system being modeled. + + @par Overflow and Saturation + Overflow and saturation behavior of the fixed-point Q15 and Q31 versions are + described separately as part of the function specific documentation below. + */ + +/** + @addtogroup LMS_NORM + @{ + */ + +/** + @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 + @return none + */ + +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) +{ + float32_t *pState = S->pState; /* State pointer */ + float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + float32_t *pStateCurnt; /* Points to the current sample of the state */ + float32_t *px, *pb; /* Temporary pointers for state and coefficient buffers */ + float32_t mu = S->mu; /* Adaptive factor */ + float32_t acc, e; /* Accumulator, error */ + float32_t w; /* Weight factor */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t tapCnt, blkCnt; /* Loop counters */ + float32_t energy; /* Energy of the input */ + float32_t x0, in; /* Temporary variable to hold input sample and state */ + + /* Initializations of error, difference, Coefficient update */ + e = 0.0f; + w = 0.0f; + + energy = S->energy; + x0 = S->x0; + + /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + + /* initialise loop count */ + blkCnt = blockSize; + + while (blkCnt > 0U) + { + /* Copy the new input sample into the state buffer */ + *pStateCurnt++ = *pSrc; + + /* Initialize pState pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + + /* Read the sample from input buffer */ + in = *pSrc++; + + /* Update the energy calculation */ + energy -= x0 * x0; + energy += in * in; + + /* Set the accumulator to zero */ + acc = 0.0f; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + acc += (*px++) * (*pb++); + + acc += (*px++) * (*pb++); + + acc += (*px++) * (*pb++); + + acc += (*px++) * (*pb++); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + acc += (*px++) * (*pb++); + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Store the result from accumulator into the destination buffer. */ + *pOut++ = acc; + + /* Compute and store error */ + e = (float32_t) *pRef++ - acc; + *pErr++ = e; + + /* Calculation of Weighting factor for updating filter coefficients */ + /* epsilon value 0.000000119209289f */ + w = (e * mu) / (energy + 0.000000119209289f); + + /* Initialize pState pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + /* Update filter coefficients */ + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + *pb += w * (*px++); + pb++; + + *pb += w * (*px++); + pb++; + + *pb += w * (*px++); + pb++; + + *pb += w * (*px++); + pb++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + *pb += w * (*px++); + pb++; + + /* Decrement loop counter */ + tapCnt--; + } + + x0 = *pState; + + /* Advance state pointer by 1 for the next sample */ + pState = pState + 1; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Save energy and x0 values for the next frame */ + S->energy = energy; + S->x0 = x0; + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the pState buffer */ + pStateCurnt = S->pState; + + /* copy data */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = (numTaps - 1U) >> 2U; + + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of LMS_NORM group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_f32.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_f32.c new file mode 100644 index 0000000..543dc72 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_f32.c @@ -0,0 +1,92 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_norm_init_f32.c + * Description: Floating-point NLMS filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup LMS_NORM + @{ + */ + +/** + @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 + @return none + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+     {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ The initial filter coefficients serve as a starting point for the adaptive filter. + pState points to an array of length numTaps+blockSize-1 samples, + where blockSize is the number of input samples processed by each call to arm_lms_norm_f32(). + */ + +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) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always blockSize + numTaps - 1 */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(float32_t)); + + /* Assign state pointer */ + S->pState = pState; + + /* Assign Step size value */ + S->mu = mu; + + /* Initialise Energy to zero */ + S->energy = 0.0f; + + /* Initialise x0 to zero */ + S->x0 = 0.0f; +} + +/** + @} end of LMS_NORM group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_q15.c new file mode 100644 index 0000000..d581ac1 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_q15.c @@ -0,0 +1,98 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_norm_init_q15.c + * Description: Q15 NLMS filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @addtogroup LMS_NORM + @{ + */ + +/** + @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. + @return none + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+     {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ The initial filter coefficients serve as a starting point for the adaptive filter. + pState points to the array of state variables and size of array is + numTaps+blockSize-1 samples, where blockSize is the number of input samples processed + by each call to arm_lms_norm_q15(). + */ + +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) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always blockSize + numTaps - 1 */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(q15_t)); + + /* Assign post Shift value applied to coefficients */ + S->postShift = postShift; + + /* Assign state pointer */ + S->pState = pState; + + /* Assign Step size value */ + S->mu = mu; + + /* Initialize reciprocal pointer table */ + S->recipTable = (q15_t *) armRecipTableQ15; + + /* Initialise Energy to zero */ + S->energy = 0; + + /* Initialise x0 to zero */ + S->x0 = 0; +} + +/** + @} end of LMS_NORM group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_q31.c new file mode 100644 index 0000000..30e78ec --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_init_q31.c @@ -0,0 +1,97 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_norm_init_q31.c + * Description: Q31 NLMS filter initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @addtogroup LMS_NORM + @{ + */ + +/** + @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. + @return none + + @par Details + pCoeffs points to the array of filter coefficients stored in time reversed order: +
+     {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
+  
+ The initial filter coefficients serve as a starting point for the adaptive filter. + pState points to an array of length numTaps+blockSize-1 samples, + where blockSize is the number of input samples processed by each call to arm_lms_norm_q31(). + */ + +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) +{ + /* Assign filter taps */ + S->numTaps = numTaps; + + /* Assign coefficient pointer */ + S->pCoeffs = pCoeffs; + + /* Clear state buffer and size is always blockSize + numTaps - 1 */ + memset(pState, 0, (numTaps + (blockSize - 1U)) * sizeof(q31_t)); + + /* Assign post Shift value applied to coefficients */ + S->postShift = postShift; + + /* Assign state pointer */ + S->pState = pState; + + /* Assign Step size value */ + S->mu = mu; + + /* Initialize reciprocal pointer table */ + S->recipTable = (q31_t *) armRecipTableQ31; + + /* Initialise Energy to zero */ + S->energy = 0; + + /* Initialise x0 to zero */ + S->x0 = 0; +} + +/** + @} end of LMS_NORM group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_q15.c new file mode 100644 index 0000000..c15ad5e --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_q15.c @@ -0,0 +1,297 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_norm_q15.c + * Description: Processing function for Q15 normalized LMS filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup LMS_NORM + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both coefficients 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. + @par + In this filter, filter coefficients are updated for each sample and the + updation of filter cofficients are saturted. + */ + +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) +{ + q15_t *pState = S->pState; /* State pointer */ + q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *pStateCurnt; /* Points to the current sample of the state */ + q15_t *px, *pb; /* Temporary pointers for state and coefficient buffers */ + q15_t mu = S->mu; /* Adaptive factor */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t tapCnt, blkCnt; /* Loop counters */ + q63_t acc; /* Accumulator */ + q31_t energy; /* Energy of the input */ + q15_t e = 0, d = 0; /* Error, reference data sample */ + q15_t w = 0, in; /* Weight factor and state */ + q15_t x0; /* Temporary variable to hold input sample */ + q15_t errorXmu, oneByEnergy; /* Temporary variables to store error and mu product and reciprocal of energy */ + q15_t postShift; /* Post shift to be applied to weight after reciprocal calculation */ + q31_t coef; /* Temporary variable for coefficient */ + q31_t acc_l, acc_h; /* Temporary input */ + int32_t lShift = (15 - (int32_t) S->postShift); /* Post shift */ + int32_t uShift = (32 - lShift); + + energy = S->energy; + x0 = S->x0; + + /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + + /* initialise loop count */ + blkCnt = blockSize; + + while (blkCnt > 0U) + { + /* Copy the new input sample into the state buffer */ + *pStateCurnt++ = *pSrc; + + /* Initialize pState pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + + /* Read the sample from input buffer */ + in = *pSrc++; + + /* Update the energy calculation */ + energy -= (((q31_t) x0 * (x0)) >> 15); + energy += (((q31_t) in * (in)) >> 15); + + /* Set the accumulator to zero */ + acc = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + /* acc += b[N] * x[n-N] + b[N-1] * x[n-N-1] */ + acc = __SMLALD(read_q15x2_ia (&px), read_q15x2_ia (&pb), acc); + acc = __SMLALD(read_q15x2_ia (&px), read_q15x2_ia (&pb), acc); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + acc += (q63_t) (((q31_t) (*px++) * (*pb++))); + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + /* Apply shift for lower part of acc and upper part of acc */ + acc = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Converting the result to 1.15 format and saturate the output */ + acc = __SSAT(acc, 16U); + + /* Store the result from accumulator into the destination buffer. */ + *pOut++ = (q15_t) acc; + + /* Compute and store error */ + d = *pRef++; + e = d - (q15_t) acc; + *pErr++ = e; + + /* Calculation of 1/energy */ + postShift = arm_recip_q15((q15_t) energy + DELTA_Q15, &oneByEnergy, S->recipTable); + + /* Calculation of e * mu value */ + errorXmu = (q15_t) (((q31_t) e * mu) >> 15); + + /* Calculation of (e * mu) * (1/energy) value */ + acc = (((q31_t) errorXmu * oneByEnergy) >> (15 - postShift)); + + /* Weighting factor for the normalized version */ + w = (q15_t) __SSAT((q31_t) acc, 16); + + /* Initialize pState pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + /* Update filter coefficients */ + while (tapCnt > 0U) + { + coef = (q31_t) *pb + (((q31_t) w * (*px++)) >> 15); + *pb++ = (q15_t) __SSAT(coef, 16); + + coef = (q31_t) *pb + (((q31_t) w * (*px++)) >> 15); + *pb++ = (q15_t) __SSAT(coef, 16); + + coef = (q31_t) *pb + (((q31_t) w * (*px++)) >> 15); + *pb++ = (q15_t) __SSAT(coef, 16); + + coef = (q31_t) *pb + (((q31_t) w * (*px++)) >> 15); + *pb++ = (q15_t) __SSAT(coef, 16); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + coef = (q31_t) *pb + (((q31_t) w * (*px++)) >> 15); + *pb++ = (q15_t) __SSAT(coef, 16); + + /* Decrement loop counter */ + tapCnt--; + } + + x0 = *pState; + + /* Advance state pointer by 1 for the next sample */ + pState = pState + 1; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Save energy and x0 values for the next frame */ + S->energy = (q15_t) energy; + S->x0 = x0; + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the pState buffer */ + pStateCurnt = S->pState; + + /* copy data */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = (numTaps - 1U) >> 2U; + + while (tapCnt > 0U) + { + write_q15x2_ia (&pStateCurnt, read_q15x2_ia (&pState)); + write_q15x2_ia (&pStateCurnt, read_q15x2_ia (&pState)); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of LMS_NORM group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_q31.c new file mode 100644 index 0000000..e26219e --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_norm_q31.c @@ -0,0 +1,311 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_norm_q31.c + * Description: Processing function for the Q31 NLMS filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup LMS_NORM + @{ + */ + +/** + @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 + @return none + + @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 + log2(numTaps) bits. The reference signal should not be scaled down. + After all multiply-accumulates are performed, the 2.62 accumulator is shifted + and saturated to 1.31 format to yield the final result. + The output signal and error signal are in 1.31 format. + @par + In this filter, filter coefficients are updated for each sample and the + updation of filter cofficients are saturted. + */ + +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) +{ + q31_t *pState = S->pState; /* State pointer */ + q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t *pStateCurnt; /* Points to the current sample of the state */ + q31_t *px, *pb; /* Temporary pointers for state and coefficient buffers */ + q31_t mu = S->mu; /* Adaptive factor */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t tapCnt, blkCnt; /* Loop counters */ + q63_t acc; /* Accumulator */ + q63_t energy; /* Energy of the input */ + q31_t e = 0; /* Error data sample */ + q31_t w = 0, in; /* Weight factor and state */ + q31_t x0; /* Temporary variable to hold input sample */ + q31_t errorXmu, oneByEnergy; /* Temporary variables to store error and mu product and reciprocal of energy */ + q31_t postShift; /* Post shift to be applied to weight after reciprocal calculation */ + q31_t coef; /* Temporary variable for coef */ + q31_t acc_l, acc_h; /* Temporary input */ + uint32_t uShift = ((uint32_t) S->postShift + 1U); + uint32_t lShift = 32U - uShift; /* Shift to be applied to the output */ + + energy = S->energy; + x0 = S->x0; + + /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + + /* initialise loop count */ + blkCnt = blockSize; + + while (blkCnt > 0U) + { + /* Copy the new input sample into the state buffer */ + *pStateCurnt++ = *pSrc; + + /* Initialize pState pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + + /* Read the sample from input buffer */ + in = *pSrc++; + + /* Update the energy calculation */ + energy = (q31_t) ((((q63_t) energy << 32) - (((q63_t) x0 * x0) << 1)) >> 32); + energy = (q31_t) (((((q63_t) in * in) << 1) + (energy << 32)) >> 32); + + /* Set the accumulator to zero */ + acc = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + /* acc += b[N] * x[n-N] */ + acc += ((q63_t) (*px++)) * (*pb++); + + /* acc += b[N-1] * x[n-N-1] */ + acc += ((q63_t) (*px++)) * (*pb++); + + /* acc += b[N-2] * x[n-N-2] */ + acc += ((q63_t) (*px++)) * (*pb++); + + /* acc += b[N-3] * x[n-N-3] */ + acc += ((q63_t) (*px++)) * (*pb++); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + acc += ((q63_t) (*px++)) * (*pb++); + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Converting the result to 1.31 format */ + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + acc = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Store the result from accumulator into the destination buffer. */ + *pOut++ = (q31_t) acc; + + /* Compute and store error */ + e = *pRef++ - (q31_t) acc; + *pErr++ = e; + + /* Calculates the reciprocal of energy */ + postShift = arm_recip_q31(energy + DELTA_Q31, &oneByEnergy, &S->recipTable[0]); + + /* Calculation of product of (e * mu) */ + errorXmu = (q31_t) (((q63_t) e * mu) >> 31); + + /* Weighting factor for the normalized version */ + w = clip_q63_to_q31(((q63_t) errorXmu * oneByEnergy) >> (31 - postShift)); + + /* Initialize pState pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + /* Update filter coefficients */ + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + + /* coef is in 2.30 format */ + coef = (q31_t) (((q63_t) w * (*px++)) >> (32)); + /* get coef in 1.31 format by left shifting */ + *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1U)); + /* update coefficient buffer to next coefficient */ + pb++; + + coef = (q31_t) (((q63_t) w * (*px++)) >> (32)); + *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1U)); + pb++; + + coef = (q31_t) (((q63_t) w * (*px++)) >> (32)); + *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1U)); + pb++; + + coef = (q31_t) (((q63_t) w * (*px++)) >> (32)); + *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1U)); + pb++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + coef = (q31_t) (((q63_t) w * (*px++)) >> (32)); + *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1U)); + pb++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Read the sample from state buffer */ + x0 = *pState; + + /* Advance state pointer by 1 for the next sample */ + pState = pState + 1; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Save energy and x0 values for the next frame */ + S->energy = (q31_t) energy; + S->x0 = x0; + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the pState buffer */ + pStateCurnt = S->pState; + + /* copy data */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = (numTaps - 1U) >> 2U; + + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of LMS_NORM group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_q15.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_q15.c new file mode 100644 index 0000000..0fc9878 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_q15.c @@ -0,0 +1,262 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_q15.c + * Description: Processing function for Q15 LMS filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup LMS + @{ + */ + +/** + @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 + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + Both coefficients 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. + @par + In this filter, filter coefficients are updated for each sample and + the updation of filter cofficients are saturted. + */ + +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) +{ + q15_t *pState = S->pState; /* State pointer */ + q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q15_t *pStateCurnt; /* Points to the current sample of the state */ + q15_t *px, *pb; /* Temporary pointers for state and coefficient buffers */ + q15_t mu = S->mu; /* Adaptive factor */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t tapCnt, blkCnt; /* Loop counters */ + q63_t acc; /* Accumulator */ + q15_t e = 0; /* Error of data sample */ + q15_t alpha; /* Intermediate constant for taps update */ + q31_t coef; /* Temporary variable for coefficient */ + q31_t acc_l, acc_h; /* Temporary input */ + int32_t lShift = (15 - (int32_t) S->postShift); /* Post shift */ + int32_t uShift = (32 - lShift); + + /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + + /* initialise loop count */ + blkCnt = blockSize; + + while (blkCnt > 0U) + { + /* Copy the new input sample into the state buffer */ + *pStateCurnt++ = *pSrc++; + + /* Initialize pState pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + + /* Set the accumulator to zero */ + acc = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + /* acc += b[N] * x[n-N] + b[N-1] * x[n-N-1] */ + acc = __SMLALD(read_q15x2_ia (&px), read_q15x2_ia (&pb), acc); + acc = __SMLALD(read_q15x2_ia (&px), read_q15x2_ia (&pb), acc); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + acc += (q63_t) (((q31_t) (*px++) * (*pb++))); + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + /* Apply shift for lower part of acc and upper part of acc */ + acc = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Converting the result to 1.15 format and saturate the output */ + acc = __SSAT(acc, 16U); + + /* Store the result from accumulator into the destination buffer. */ + *pOut++ = (q15_t) acc; + + /* Compute and store error */ + e = *pRef++ - (q15_t) acc; + *pErr++ = (q15_t) e; + + /* Compute alpha i.e. intermediate constant for taps update */ + alpha = (q15_t) (((q31_t) e * (mu)) >> 15); + + /* Initialize pState pointer */ + /* Advance state pointer by 1 for the next sample */ + px = pState++; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + /* Update filter coefficients */ + while (tapCnt > 0U) + { + coef = (q31_t) *pb + (((q31_t) alpha * (*px++)) >> 15); + *pb++ = (q15_t) __SSAT((coef), 16); + + coef = (q31_t) *pb + (((q31_t) alpha * (*px++)) >> 15); + *pb++ = (q15_t) __SSAT((coef), 16); + + coef = (q31_t) *pb + (((q31_t) alpha * (*px++)) >> 15); + *pb++ = (q15_t) __SSAT((coef), 16); + + coef = (q31_t) *pb + (((q31_t) alpha * (*px++)) >> 15); + *pb++ = (q15_t) __SSAT((coef), 16); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + coef = (q31_t) *pb + (((q31_t) alpha * (*px++)) >> 15); + *pb++ = (q15_t) __SSAT((coef), 16); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the pState buffer */ + pStateCurnt = S->pState; + + /* copy data */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = (numTaps - 1U) >> 2U; + + while (tapCnt > 0U) + { + write_q15x2_ia (&pStateCurnt, read_q15x2_ia (&pState)); + write_q15x2_ia (&pStateCurnt, read_q15x2_ia (&pState)); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of LMS group + */ diff --git a/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_q31.c b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_q31.c new file mode 100644 index 0000000..b0c0e27 --- /dev/null +++ b/platform/cmsis/DSP_Lib/FilteringFunctions/arm_lms_q31.c @@ -0,0 +1,283 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_lms_q31.c + * Description: Processing function for the Q31 LMS filter + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupFilters + */ + +/** + @addtogroup LMS + @{ + */ + +/** + @brief Processing function for Q31 LMS filter. + @param[in] S points to an instance of the Q31 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. + @return none + + @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 clips. + In order to avoid overflows completely the input signal must be scaled down by + log2(numTaps) bits. + The reference signal should not be scaled down. + After all multiply-accumulates are performed, the 2.62 accumulator is shifted + and saturated to 1.31 format to yield the final result. + The output signal and error signal are in 1.31 format. + @par + In this filter, filter coefficients are updated for each sample and + the updation of filter cofficients are saturted. + */ + +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) +{ + q31_t *pState = S->pState; /* State pointer */ + q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ + q31_t *pStateCurnt; /* Points to the current sample of the state */ + q31_t *px, *pb; /* Temporary pointers for state and coefficient buffers */ + q31_t mu = S->mu; /* Adaptive factor */ + uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ + uint32_t tapCnt, blkCnt; /* Loop counters */ + q63_t acc; /* Accumulator */ + q31_t e = 0; /* Error of data sample */ + q31_t alpha; /* Intermediate constant for taps update */ + q31_t coef; /* Temporary variable for coef */ + q31_t acc_l, acc_h; /* Temporary input */ + uint32_t uShift = ((uint32_t) S->postShift + 1U); + uint32_t lShift = 32U - uShift; /* Shift to be applied to the output */ + + /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */ + /* pStateCurnt points to the location where the new input data should be written */ + pStateCurnt = &(S->pState[(numTaps - 1U)]); + + /* initialise loop count */ + blkCnt = blockSize; + + while (blkCnt > 0U) + { + /* Copy the new input sample into the state buffer */ + *pStateCurnt++ = *pSrc++; + + /* Initialize pState pointer */ + px = pState; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + + /* Set the accumulator to zero */ + acc = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + /* acc += b[N] * x[n-N] */ + acc += ((q63_t) (*px++)) * (*pb++); + + /* acc += b[N-1] * x[n-N-1] */ + acc += ((q63_t) (*px++)) * (*pb++); + + /* acc += b[N-2] * x[n-N-2] */ + acc += ((q63_t) (*px++)) * (*pb++); + + /* acc += b[N-3] * x[n-N-3] */ + acc += ((q63_t) (*px++)) * (*pb++); + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + acc += ((q63_t) (*px++)) * (*pb++); + + /* Decrement the loop counter */ + tapCnt--; + } + + /* Converting the result to 1.31 format */ + /* Calc lower part of acc */ + acc_l = acc & 0xffffffff; + + /* Calc upper part of acc */ + acc_h = (acc >> 32) & 0xffffffff; + + acc = (uint32_t) acc_l >> lShift | acc_h << uShift; + + /* Store the result from accumulator into the destination buffer. */ + *pOut++ = (q31_t) acc; + + /* Compute and store error */ + e = *pRef++ - (q31_t) acc; + *pErr++ = e; + + /* Compute alpha i.e. intermediate constant for taps update */ + alpha = (q31_t) (((q63_t) e * mu) >> 31); + + /* Initialize pState pointer */ + /* Advance state pointer by 1 for the next sample */ + px = pState++; + + /* Initialize coefficient pointer */ + pb = pCoeffs; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = numTaps >> 2U; + + /* Update filter coefficients */ + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + + /* coef is in 2.30 format */ + coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32)); + /* get coef in 1.31 format by left shifting */ + *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1U)); + /* update coefficient buffer to next coefficient */ + pb++; + + coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32)); + *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1U)); + pb++; + + coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32)); + *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1U)); + pb++; + + coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32)); + *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1U)); + pb++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = numTaps % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = numTaps; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + /* Perform the multiply-accumulate */ + coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32)); + *pb = clip_q63_to_q31((q63_t) * pb + (coef << 1U)); + pb++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Processing is complete. + Now copy the last numTaps - 1 samples to the start of the state buffer. + This prepares the state buffer for the next function call. */ + + /* Points to the start of the pState buffer */ + pStateCurnt = S->pState; + + /* copy data */ +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 taps at a time. */ + tapCnt = (numTaps - 1U) >> 2U; + + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + + /* Loop unrolling: Compute remaining taps */ + tapCnt = (numTaps - 1U) % 0x4U; + +#else + + /* Initialize tapCnt with number of samples */ + tapCnt = (numTaps - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (tapCnt > 0U) + { + *pStateCurnt++ = *pState++; + + /* Decrement loop counter */ + tapCnt--; + } + +} + +/** + @} end of LMS group + */ diff --git a/platform/cmsis/DSP_Lib/Makefile b/platform/cmsis/DSP_Lib/Makefile new file mode 100644 index 0000000..df3befd --- /dev/null +++ b/platform/cmsis/DSP_Lib/Makefile @@ -0,0 +1,51 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +#obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) + +ifeq ($(DSP_LIB_ALL_ENABLE),1) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*/Makefile)) +obj-y := $(obj-y:/Makefile=/) + +else + +obj-y := +obj-y += \ + CommonTables/CommonTables.c \ + BasicMathFunctions/arm_dot_prod_q15.c \ + FilteringFunctions/arm_biquad_cascade_df1_init_f32.c \ + FilteringFunctions/arm_biquad_cascade_df1_f32.c \ + FilteringFunctions/arm_fir_init_q15.c \ + FilteringFunctions/arm_fir_fast_q15.c \ + TransformFunctions/arm_bitreversal2.S \ + TransformFunctions/arm_cfft_f32.c \ + TransformFunctions/arm_cfft_q15.c \ + TransformFunctions/arm_cfft_radix4_q15.c \ + TransformFunctions/arm_cfft_radix8_f32.c \ + TransformFunctions/arm_rfft_fast_init_f32.c \ + TransformFunctions/arm_rfft_fast_f32.c \ + TransformFunctions/arm_rfft_init_q15.c \ + TransformFunctions/arm_rfft_q15.c \ + SupportFunctions/arm_copy_q31.c \ + SupportFunctions/arm_fill_q31.c \ + SupportFunctions/arm_q15_to_float.c \ + BasicMathFunctions/arm_dot_prod_q7.c \ + BasicMathFunctions/arm_add_q15.c \ + BasicMathFunctions/arm_shift_q15.c \ + BasicMathFunctions/arm_negate_q15.c \ + BasicMathFunctions/arm_offset_q15.c \ + BasicMathFunctions/arm_mult_q15.c \ + StatisticsFunctions/StatisticsFunctions.c + +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) + +endif + +ccflags-y += -DARM_MATH_LOOPUNROLL + +ifeq ($(SCO_CP_ACCEL),1) +cmsis_dsp_lib-y := $(obj-y) +obj-y := cmsis_dsp_lib.o +endif + diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/Makefile b/platform/cmsis/DSP_Lib/MatrixFunctions/Makefile new file mode 100644 index 0000000..88c2e8b --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/Makefile @@ -0,0 +1,6 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out %Functions.c,$(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/MatrixFunctions.c b/platform/cmsis/DSP_Lib/MatrixFunctions/MatrixFunctions.c new file mode 100644 index 0000000..da721fe --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/MatrixFunctions.c @@ -0,0 +1,53 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: MatrixFunctions.c + * Description: Combination of all matrix function source files. + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_mat_add_f32.c" +#include "arm_mat_add_q15.c" +#include "arm_mat_add_q31.c" +#include "arm_mat_cmplx_mult_f32.c" +#include "arm_mat_cmplx_mult_q15.c" +#include "arm_mat_cmplx_mult_q31.c" +#include "arm_mat_init_f32.c" +#include "arm_mat_init_q15.c" +#include "arm_mat_init_q31.c" +#include "arm_mat_inverse_f32.c" +#include "arm_mat_inverse_f64.c" +#include "arm_mat_mult_f32.c" +#include "arm_mat_mult_fast_q15.c" +#include "arm_mat_mult_fast_q31.c" +#include "arm_mat_mult_q15.c" +#include "arm_mat_mult_q31.c" +#include "arm_mat_scale_f32.c" +#include "arm_mat_scale_q15.c" +#include "arm_mat_scale_q31.c" +#include "arm_mat_sub_f32.c" +#include "arm_mat_sub_q15.c" +#include "arm_mat_sub_q31.c" +#include "arm_mat_trans_f32.c" +#include "arm_mat_trans_q15.c" +#include "arm_mat_trans_q31.c" diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_f32.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_f32.c new file mode 100644 index 0000000..d7bb44f --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_f32.c @@ -0,0 +1,146 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_add_f32.c + * Description: Floating-point matrix addition + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @defgroup MatrixAdd Matrix Addition + + Adds two matrices. + \image html MatrixAddition.gif "Addition of two 3 x 3 matrices" + + The functions check to make sure that + pSrcA, pSrcB, and pDst have the same + number of rows and columns. + */ + +/** + @addtogroup MatrixAdd + @{ + */ + +/** + @brief Floating-point matrix addition. + @param[in] pSrcA points to first input matrix structure + @param[in] pSrcB points to second input matrix structure + @param[out] pDst points to output matrix structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + */ + +arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst) +{ + float32_t *pInA = pSrcA->pData; /* input data matrix pointer A */ + float32_t *pInB = pSrcB->pData; /* input data matrix pointer B */ + float32_t *pOut = pDst->pData; /* output data matrix pointer */ + + uint32_t numSamples; /* total number of elements in the matrix */ + uint32_t blkCnt; /* loop counters */ + arm_status status; /* status of matrix addition */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numRows != pSrcB->numRows) || + (pSrcA->numCols != pSrcB->numCols) || + (pSrcA->numRows != pDst->numRows) || + (pSrcA->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Total number of samples in input matrix */ + numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) + B(m,n) */ + + /* Add and store result in destination buffer. */ + *pOut++ = *pInA++ + *pInB++; + + *pOut++ = *pInA++ + *pInB++; + + *pOut++ = *pInA++ + *pInB++; + + *pOut++ = *pInA++ + *pInB++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) + B(m,n) */ + + /* Add and store result in destination buffer. */ + *pOut++ = *pInA++ + *pInB++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixAdd group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_q15.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_q15.c new file mode 100644 index 0000000..2aaf849 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_q15.c @@ -0,0 +1,149 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_add_q15.c + * Description: Q15 matrix addition + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixAdd + @{ + */ + +/** + @brief Q15 matrix addition. + @param[in] pSrcA points to first input matrix structure + @param[in] pSrcB points to second input matrix structure + @param[out] pDst points to output matrix structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated. + */ + +arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst) +{ + q15_t *pInA = pSrcA->pData; /* input data matrix pointer A */ + q15_t *pInB = pSrcB->pData; /* input data matrix pointer B */ + q15_t *pOut = pDst->pData; /* output data matrix pointer */ + + uint32_t numSamples; /* total number of elements in the matrix */ + uint32_t blkCnt; /* loop counters */ + arm_status status; /* status of matrix addition */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numRows != pSrcB->numRows) || + (pSrcA->numCols != pSrcB->numCols) || + (pSrcA->numRows != pDst->numRows) || + (pSrcA->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Total number of samples in input matrix */ + numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) + B(m,n) */ + + /* Add, saturate and store result in destination buffer. */ +#if defined (ARM_MATH_DSP) + write_q15x2_ia (&pOut, __QADD16(read_q15x2_ia (&pInA), read_q15x2_ia (&pInB))); + + write_q15x2_ia (&pOut, __QADD16(read_q15x2_ia (&pInA), read_q15x2_ia (&pInB))); +#else + *pOut++ = (q15_t) __SSAT(((q31_t) *pInA++ + *pInB++), 16); + + *pOut++ = (q15_t) __SSAT(((q31_t) *pInA++ + *pInB++), 16); + + *pOut++ = (q15_t) __SSAT(((q31_t) *pInA++ + *pInB++), 16); + + *pOut++ = (q15_t) __SSAT(((q31_t) *pInA++ + *pInB++), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) + B(m,n) */ + + /* Add, saturate and store result in destination buffer. */ +#if defined (ARM_MATH_DSP) + *pOut++ = (q15_t) __QADD16(*pInA++, *pInB++); +#else + *pOut++ = (q15_t) __SSAT(((q31_t) *pInA++ + *pInB++), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixAdd group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_q31.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_q31.c new file mode 100644 index 0000000..6194809 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_add_q31.c @@ -0,0 +1,139 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_add_q31.c + * Description: Q31 matrix addition + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixAdd + @{ + */ + +/** + @brief Q31 matrix addition. + @param[in] pSrcA points to first input matrix structure + @param[in] pSrcB points to second input matrix structure + @param[out] pDst points to output matrix structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated. + */ + +arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst) +{ + q31_t *pInA = pSrcA->pData; /* input data matrix pointer A */ + q31_t *pInB = pSrcB->pData; /* input data matrix pointer B */ + q31_t *pOut = pDst->pData; /* output data matrix pointer */ + + uint32_t numSamples; /* total number of elements in the matrix */ + uint32_t blkCnt; /* loop counters */ + arm_status status; /* status of matrix addition */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numRows != pSrcB->numRows) || + (pSrcA->numCols != pSrcB->numCols) || + (pSrcA->numRows != pDst->numRows) || + (pSrcA->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Total number of samples in input matrix */ + numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) + B(m,n) */ + + /* Add, saturate and store result in destination buffer. */ + *pOut++ = __QADD(*pInA++, *pInB++); + + *pOut++ = __QADD(*pInA++, *pInB++); + + *pOut++ = __QADD(*pInA++, *pInB++); + + *pOut++ = __QADD(*pInA++, *pInB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) + B(m,n) */ + + /* Add, saturate and store result in destination buffer. */ + *pOut++ = __QADD(*pInA++, *pInB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixAdd group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_f32.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_f32.c new file mode 100644 index 0000000..1f50fcd --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_f32.c @@ -0,0 +1,286 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_cmplx_mult_f32.c + * Description: Floating-point matrix multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @defgroup CmplxMatrixMult Complex Matrix Multiplication + + Complex Matrix multiplication is only defined if the number of columns of the + first matrix equals the number of rows of the second matrix. + Multiplying an M x N matrix with an N x P matrix results + in an M x P matrix. + @par + When matrix size checking is enabled, the functions check: + - that the inner dimensions of pSrcA and pSrcB are equal; + - that the size of the output matrix equals the outer dimensions of pSrcA and pSrcB. + */ + +/** + @addtogroup CmplxMatrixMult + @{ + */ + +/** + @brief Floating-point Complex matrix multiplication. + @param[in] pSrcA points to first input complex matrix structure + @param[in] pSrcB points to second input complex matrix structure + @param[out] pDst points to output complex matrix structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + */ + +arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst) +{ + float32_t *pIn1 = pSrcA->pData; /* Input data matrix pointer A */ + float32_t *pIn2 = pSrcB->pData; /* Input data matrix pointer B */ + float32_t *pInA = pSrcA->pData; /* Input data matrix pointer A */ + float32_t *pOut = pDst->pData; /* Output data matrix pointer */ + float32_t *px; /* Temporary output data matrix pointer */ + uint16_t numRowsA = pSrcA->numRows; /* Number of rows of input matrix A */ + uint16_t numColsB = pSrcB->numCols; /* Number of columns of input matrix B */ + uint16_t numColsA = pSrcA->numCols; /* Number of columns of input matrix A */ + float32_t sumReal, sumImag; /* Accumulator */ + float32_t a1, b1, c1, d1; + uint32_t col, i = 0U, j, row = numRowsA, colCnt; /* loop counters */ + arm_status status; /* status of matrix multiplication */ + +#if defined (ARM_MATH_LOOPUNROLL) + float32_t a0, b0, c0, d0; +#endif + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numCols != pSrcB->numRows) || + (pSrcA->numRows != pDst->numRows) || + (pSrcB->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */ + /* row loop */ + do + { + /* Output pointer is set to starting address of the row being processed */ + px = pOut + 2 * i; + + /* For every row wise process, the column loop counter is to be initiated */ + col = numColsB; + + /* For every row wise process, the pIn2 pointer is set + ** to the starting address of the pSrcB data */ + pIn2 = pSrcB->pData; + + j = 0U; + + /* column loop */ + do + { + /* Set the variable sum, that acts as accumulator, to zero */ + sumReal = 0.0f; + sumImag = 0.0f; + + /* Initiate pointer pIn1 to point to starting address of column being processed */ + pIn1 = pInA; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + colCnt = numColsA >> 2U; + + /* matrix multiplication */ + while (colCnt > 0U) + { + + /* Reading real part of complex matrix A */ + a0 = *pIn1; + + /* Reading real part of complex matrix B */ + c0 = *pIn2; + + /* Reading imaginary part of complex matrix A */ + b0 = *(pIn1 + 1U); + + /* Reading imaginary part of complex matrix B */ + d0 = *(pIn2 + 1U); + + /* Multiply and Accumlates */ + sumReal += a0 * c0; + sumImag += b0 * c0; + + /* update pointers */ + pIn1 += 2U; + pIn2 += 2 * numColsB; + + /* Multiply and Accumlates */ + sumReal -= b0 * d0; + sumImag += a0 * d0; + + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + /* read real and imag values from pSrcA and pSrcB buffer */ + a1 = *(pIn1 ); + c1 = *(pIn2 ); + b1 = *(pIn1 + 1U); + d1 = *(pIn2 + 1U); + + /* Multiply and Accumlates */ + sumReal += a1 * c1; + sumImag += b1 * c1; + + /* update pointers */ + pIn1 += 2U; + pIn2 += 2 * numColsB; + + /* Multiply and Accumlates */ + sumReal -= b1 * d1; + sumImag += a1 * d1; + + a0 = *(pIn1 ); + c0 = *(pIn2 ); + b0 = *(pIn1 + 1U); + d0 = *(pIn2 + 1U); + + /* Multiply and Accumlates */ + sumReal += a0 * c0; + sumImag += b0 * c0; + + /* update pointers */ + pIn1 += 2U; + pIn2 += 2 * numColsB; + + /* Multiply and Accumlates */ + sumReal -= b0 * d0; + sumImag += a0 * d0; + + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + a1 = *(pIn1 ); + c1 = *(pIn2 ); + b1 = *(pIn1 + 1U); + d1 = *(pIn2 + 1U); + + /* Multiply and Accumlates */ + sumReal += a1 * c1; + sumImag += b1 * c1; + + /* update pointers */ + pIn1 += 2U; + pIn2 += 2 * numColsB; + + /* Multiply and Accumlates */ + sumReal -= b1 * d1; + sumImag += a1 * d1; + + /* Decrement loop count */ + colCnt--; + } + + /* If the columns of pSrcA is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + colCnt = numColsA % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + colCnt = numColsA; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + a1 = *(pIn1 ); + c1 = *(pIn2 ); + b1 = *(pIn1 + 1U); + d1 = *(pIn2 + 1U); + + /* Multiply and Accumlates */ + sumReal += a1 * c1; + sumImag += b1 * c1; + + /* update pointers */ + pIn1 += 2U; + pIn2 += 2 * numColsB; + + /* Multiply and Accumlates */ + sumReal -= b1 * d1; + sumImag += a1 * d1; + + /* Decrement loop counter */ + colCnt--; + } + + /* Store result in destination buffer */ + *px++ = sumReal; + *px++ = sumImag; + + /* Update pointer pIn2 to point to starting address of next column */ + j++; + pIn2 = pSrcB->pData + 2U * j; + + /* Decrement column loop counter */ + col--; + + } while (col > 0U); + + /* Update pointer pInA to point to starting address of next row */ + i = i + numColsB; + pInA = pInA + 2 * numColsA; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixMult group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_q15.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_q15.c new file mode 100644 index 0000000..4c5a45b --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_q15.c @@ -0,0 +1,340 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cmplx_mat_mult_q15.c + * Description: Q15 complex matrix multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup CmplxMatrixMult + @{ + */ + +/** + @brief Q15 Complex matrix multiplication. + @param[in] pSrcA points to first input complex matrix structure + @param[in] pSrcB points to second input complex matrix structure + @param[out] pDst points to output complex matrix structure + @param[in] pScratch points to an array for storing intermediate results + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @par Conditions for optimum performance + Input, output and state buffers should be aligned by 32-bit + + @par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. The inputs to the + multiplications are 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. + This approach provides 33 guard bits and there is no risk of overflow. The 34.30 result is then + truncated to 34.15 format by discarding the low 15 bits and then saturated to 1.15 format. + */ + +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) +{ + q15_t *pSrcBT = pScratch; /* input data matrix pointer for transpose */ + q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */ + q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */ + q15_t *px; /* Temporary output data matrix pointer */ + uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */ + uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */ + uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */ + uint16_t numRowsB = pSrcB->numRows; /* number of rows of input matrix A */ + q63_t sumReal, sumImag; /* accumulator */ + uint32_t col, i = 0U, row = numRowsB, colCnt; /* Loop counters */ + arm_status status; /* Status of matrix multiplication */ + +#if defined (ARM_MATH_DSP) + q31_t prod1, prod2; + q31_t pSourceA, pSourceB; +#else + q15_t a, b, c, d; +#endif /* #if defined (ARM_MATH_DSP) */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numCols != pSrcB->numRows) || + (pSrcA->numRows != pDst->numRows) || + (pSrcB->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Matrix transpose */ + do + { + /* The pointer px is set to starting address of column being processed */ + px = pSrcBT + i; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Apply loop unrolling and exchange the columns with row elements */ + col = numColsB >> 2; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + a second loop below computes the remaining 1 to 3 samples. */ + while (col > 0U) + { + /* Read two elements from row */ + write_q15x2 (px, read_q15x2_ia (&pInB)); + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB * 2; + + /* Read two elements from row */ + write_q15x2 (px, read_q15x2_ia (&pInB)); + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB * 2; + + /* Read two elements from row */ + write_q15x2 (px, read_q15x2_ia (&pInB)); + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB * 2; + + /* Read two elements from row */ + write_q15x2 (px, read_q15x2_ia (&pInB)); + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB * 2; + + /* Decrement column loop counter */ + col--; + } + + /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + col = numColsB % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + col = numColsB; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (col > 0U) + { + /* Read two elements from row */ + write_q15x2 (px, read_q15x2_ia (&pInB)); + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB * 2; + + /* Decrement column loop counter */ + col--; + } + + i = i + 2U; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); + + /* Reset variables for usage in following multiplication process */ + row = numRowsA; + i = 0U; + px = pDst->pData; + + /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */ + /* row loop */ + do + { + /* For every row wise process, column loop counter is to be initiated */ + col = numColsB; + + /* For every row wise process, pIn2 pointer is set to starting address of transposed pSrcB data */ + pInB = pSrcBT; + + /* column loop */ + do + { + /* Set variable sum, that acts as accumulator, to zero */ + sumReal = 0; + sumImag = 0; + + /* Initiate pointer pInA to point to starting address of column being processed */ + pInA = pSrcA->pData + i * 2; + + /* Apply loop unrolling and compute 2 MACs simultaneously. */ + colCnt = numColsA >> 1U; + + /* matrix multiplication */ + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + +#if defined (ARM_MATH_DSP) + + /* read real and imag values from pSrcA and pSrcB buffer */ + pSourceA = read_q15x2_ia ((q15_t **) &pInA); + pSourceB = read_q15x2_ia ((q15_t **) &pInB); + + /* Multiply and Accumlates */ +#ifdef ARM_MATH_BIG_ENDIAN + prod1 = -__SMUSD(pSourceA, pSourceB); +#else + prod1 = __SMUSD(pSourceA, pSourceB); +#endif + prod2 = __SMUADX(pSourceA, pSourceB); + sumReal += (q63_t) prod1; + sumImag += (q63_t) prod2; + + /* read real and imag values from pSrcA and pSrcB buffer */ + pSourceA = read_q15x2_ia ((q15_t **) &pInA); + pSourceB = read_q15x2_ia ((q15_t **) &pInB); + + /* Multiply and Accumlates */ +#ifdef ARM_MATH_BIG_ENDIAN + prod1 = -__SMUSD(pSourceA, pSourceB); +#else + prod1 = __SMUSD(pSourceA, pSourceB); +#endif + prod2 = __SMUADX(pSourceA, pSourceB); + sumReal += (q63_t) prod1; + sumImag += (q63_t) prod2; + +#else /* #if defined (ARM_MATH_DSP) */ + + /* read real and imag values from pSrcA buffer */ + a = *pInA; + b = *(pInA + 1U); + /* read real and imag values from pSrcB buffer */ + c = *pInB; + d = *(pInB + 1U); + + /* Multiply and Accumlates */ + sumReal += (q31_t) a *c; + sumImag += (q31_t) a *d; + sumReal -= (q31_t) b *d; + sumImag += (q31_t) b *c; + + /* read next real and imag values from pSrcA buffer */ + a = *(pInA + 2U); + b = *(pInA + 3U); + /* read next real and imag values from pSrcB buffer */ + c = *(pInB + 2U); + d = *(pInB + 3U); + + /* update pointer */ + pInA += 4U; + + /* Multiply and Accumlates */ + sumReal += (q31_t) a * c; + sumImag += (q31_t) a * d; + sumReal -= (q31_t) b * d; + sumImag += (q31_t) b * c; + /* update pointer */ + pInB += 4U; + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + colCnt--; + } + + /* process odd column samples */ + if ((numColsA & 0x1U) > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + +#if defined (ARM_MATH_DSP) + /* read real and imag values from pSrcA and pSrcB buffer */ + pSourceA = read_q15x2_ia ((q15_t **) &pInA); + pSourceB = read_q15x2_ia ((q15_t **) &pInB); + + /* Multiply and Accumlates */ +#ifdef ARM_MATH_BIG_ENDIAN + prod1 = -__SMUSD(pSourceA, pSourceB); +#else + prod1 = __SMUSD(pSourceA, pSourceB); +#endif + prod2 = __SMUADX(pSourceA, pSourceB); + sumReal += (q63_t) prod1; + sumImag += (q63_t) prod2; + +#else /* #if defined (ARM_MATH_DSP) */ + + /* read real and imag values from pSrcA and pSrcB buffer */ + a = *pInA++; + b = *pInA++; + c = *pInB++; + d = *pInB++; + + /* Multiply and Accumlates */ + sumReal += (q31_t) a * c; + sumImag += (q31_t) a * d; + sumReal -= (q31_t) b * d; + sumImag += (q31_t) b * c; + +#endif /* #if defined (ARM_MATH_DSP) */ + + } + + /* Saturate and store result in destination buffer */ + *px++ = (q15_t) (__SSAT(sumReal >> 15, 16)); + *px++ = (q15_t) (__SSAT(sumImag >> 15, 16)); + + /* Decrement column loop counter */ + col--; + + } while (col > 0U); + + i = i + numColsA; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixMult group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_q31.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_q31.c new file mode 100644 index 0000000..7b458f9 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_cmplx_mult_q31.c @@ -0,0 +1,283 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_cmplx_mult_q31.c + * Description: Floating-point matrix multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup CmplxMatrixMult + @{ + */ + +/** + @brief Q31 Complex matrix multiplication. + @param[in] pSrcA points to first input complex matrix structure + @param[in] pSrcB points to second input complex matrix structure + @param[out] pDst points to output complex matrix structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @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. There is no saturation + on intermediate additions. Thus, if the accumulator overflows it wraps around and + distorts the result. The input signals should be scaled down to avoid intermediate + overflows. The input is thus scaled down by log2(numColsA) bits + to avoid overflows, as a total of numColsA additions are performed internally. + The 2.62 accumulator is right shifted by 31 bits and saturated to 1.31 format to yield the final result. + */ + +arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst) +{ + q31_t *pIn1 = pSrcA->pData; /* Input data matrix pointer A */ + q31_t *pIn2 = pSrcB->pData; /* Input data matrix pointer B */ + q31_t *pInA = pSrcA->pData; /* Input data matrix pointer A */ + q31_t *pOut = pDst->pData; /* Output data matrix pointer */ + q31_t *px; /* Temporary output data matrix pointer */ + uint16_t numRowsA = pSrcA->numRows; /* Number of rows of input matrix A */ + uint16_t numColsB = pSrcB->numCols; /* Number of columns of input matrix B */ + uint16_t numColsA = pSrcA->numCols; /* Number of columns of input matrix A */ + q63_t sumReal, sumImag; /* Accumulator */ + q31_t a1, b1, c1, d1; + uint32_t col, i = 0U, j, row = numRowsA, colCnt; /* loop counters */ + arm_status status; /* status of matrix multiplication */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t a0, b0, c0, d0; +#endif + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numCols != pSrcB->numRows) || + (pSrcA->numRows != pDst->numRows) || + (pSrcB->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */ + /* row loop */ + do + { + /* Output pointer is set to starting address of the row being processed */ + px = pOut + 2 * i; + + /* For every row wise process, the column loop counter is to be initiated */ + col = numColsB; + + /* For every row wise process, the pIn2 pointer is set + ** to the starting address of the pSrcB data */ + pIn2 = pSrcB->pData; + + j = 0U; + + /* column loop */ + do + { + /* Set the variable sum, that acts as accumulator, to zero */ + sumReal = 0.0; + sumImag = 0.0; + + /* Initiate pointer pIn1 to point to starting address of column being processed */ + pIn1 = pInA; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Apply loop unrolling and compute 4 MACs simultaneously. */ + colCnt = numColsA >> 2U; + + /* matrix multiplication */ + while (colCnt > 0U) + { + + /* Reading real part of complex matrix A */ + a0 = *pIn1; + + /* Reading real part of complex matrix B */ + c0 = *pIn2; + + /* Reading imaginary part of complex matrix A */ + b0 = *(pIn1 + 1U); + + /* Reading imaginary part of complex matrix B */ + d0 = *(pIn2 + 1U); + + /* Multiply and Accumlates */ + sumReal += (q63_t) a0 * c0; + sumImag += (q63_t) b0 * c0; + + /* update pointers */ + pIn1 += 2U; + pIn2 += 2 * numColsB; + + /* Multiply and Accumlates */ + sumReal -= (q63_t) b0 * d0; + sumImag += (q63_t) a0 * d0; + + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + /* read real and imag values from pSrcA and pSrcB buffer */ + a1 = *(pIn1 ); + c1 = *(pIn2 ); + b1 = *(pIn1 + 1U); + d1 = *(pIn2 + 1U); + + /* Multiply and Accumlates */ + sumReal += (q63_t) a1 * c1; + sumImag += (q63_t) b1 * c1; + + /* update pointers */ + pIn1 += 2U; + pIn2 += 2 * numColsB; + + /* Multiply and Accumlates */ + sumReal -= (q63_t) b1 * d1; + sumImag += (q63_t) a1 * d1; + + a0 = *(pIn1 ); + c0 = *(pIn2 ); + b0 = *(pIn1 + 1U); + d0 = *(pIn2 + 1U); + + /* Multiply and Accumlates */ + sumReal += (q63_t) a0 * c0; + sumImag += (q63_t) b0 * c0; + + /* update pointers */ + pIn1 += 2U; + pIn2 += 2 * numColsB; + + /* Multiply and Accumlates */ + sumReal -= (q63_t) b0 * d0; + sumImag += (q63_t) a0 * d0; + + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + a1 = *(pIn1 ); + c1 = *(pIn2 ); + b1 = *(pIn1 + 1U); + d1 = *(pIn2 + 1U); + + /* Multiply and Accumlates */ + sumReal += (q63_t) a1 * c1; + sumImag += (q63_t) b1 * c1; + + /* update pointers */ + pIn1 += 2U; + pIn2 += 2 * numColsB; + + /* Multiply and Accumlates */ + sumReal -= (q63_t) b1 * d1; + sumImag += (q63_t) a1 * d1; + + /* Decrement loop count */ + colCnt--; + } + + /* If the columns of pSrcA is not a multiple of 4, compute any remaining MACs here. + ** No loop unrolling is used. */ + colCnt = numColsA % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + colCnt = numColsA; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + a1 = *(pIn1 ); + c1 = *(pIn2 ); + b1 = *(pIn1 + 1U); + d1 = *(pIn2 + 1U); + + /* Multiply and Accumlates */ + sumReal += (q63_t) a1 * c1; + sumImag += (q63_t) b1 * c1; + + /* update pointers */ + pIn1 += 2U; + pIn2 += 2 * numColsB; + + /* Multiply and Accumlates */ + sumReal -= (q63_t) b1 * d1; + sumImag += (q63_t) a1 * d1; + + /* Decrement loop counter */ + colCnt--; + } + + /* Store result in destination buffer */ + *px++ = (q31_t) clip_q63_to_q31(sumReal >> 31); + *px++ = (q31_t) clip_q63_to_q31(sumImag >> 31); + + /* Update pointer pIn2 to point to starting address of next column */ + j++; + pIn2 = pSrcB->pData + 2U * j; + + /* Decrement column loop counter */ + col--; + + } while (col > 0U); + + /* Update pointer pInA to point to starting address of next row */ + i = i + numColsB; + pInA = pInA + 2 * numColsA; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixMult group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_f32.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_f32.c new file mode 100644 index 0000000..ce02a25 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_f32.c @@ -0,0 +1,76 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_init_f32.c + * Description: Floating-point matrix initialization + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @defgroup MatrixInit Matrix Initialization + + Initializes the underlying matrix data structure. + The functions set the numRows, + numCols, and pData fields + of the matrix data structure. + */ + +/** + @addtogroup MatrixInit + @{ + */ + +/** + @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 + @return none + */ + +void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData) +{ + /* Assign Number of Rows */ + S->numRows = nRows; + + /* Assign Number of Columns */ + S->numCols = nColumns; + + /* Assign Data pointer */ + S->pData = pData; +} + +/** + @} end of MatrixInit group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_q15.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_q15.c new file mode 100644 index 0000000..0275503 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_q15.c @@ -0,0 +1,67 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_init_q15.c + * Description: Q15 matrix initialization + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixInit + @{ + */ + +/** + @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 + @return none + */ + +void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData) +{ + /* Assign Number of Rows */ + S->numRows = nRows; + + /* Assign Number of Columns */ + S->numCols = nColumns; + + /* Assign Data pointer */ + S->pData = pData; +} + +/** + @} end of MatrixInit group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_q31.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_q31.c new file mode 100644 index 0000000..d5c5722 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_init_q31.c @@ -0,0 +1,72 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_init_q31.c + * Description: Q31 matrix initialization + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @defgroup MatrixInit Matrix Initialization + + */ + +/** + @addtogroup MatrixInit + @{ + */ + +/** + @brief Q31 matrix initialization. + @param[in,out] S points to an instance of the Q31 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 + @return none + */ + +void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData) +{ + /* Assign Number of Rows */ + S->numRows = nRows; + + /* Assign Number of Columns */ + S->numCols = nColumns; + + /* Assign Data pointer */ + S->pData = pData; +} + +/** + @} end of MatrixInit group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_inverse_f32.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_inverse_f32.c new file mode 100644 index 0000000..91dad22 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_inverse_f32.c @@ -0,0 +1,693 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_inverse_f32.c + * Description: Floating-point matrix inverse + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @defgroup MatrixInv Matrix Inverse + + Computes the inverse of a matrix. + + The inverse is defined only if the input matrix is square and non-singular (the determinant is non-zero). + The function checks that the input and output matrices are square and of the same size. + + Matrix inversion is numerically sensitive and the CMSIS DSP library only supports matrix + inversion of floating-point matrices. + + @par Algorithm + The Gauss-Jordan method is used to find the inverse. + The algorithm performs a sequence of elementary row-operations until it + reduces the input matrix to an identity matrix. Applying the same sequence + of elementary row-operations to an identity matrix yields the inverse matrix. + If the input matrix is singular, then the algorithm terminates and returns error status + ARM_MATH_SINGULAR. + \image html MatrixInverse.gif "Matrix Inverse of a 3 x 3 matrix using Gauss-Jordan Method" + */ + +/** + @addtogroup MatrixInv + @{ + */ + +/** + @brief Floating-point matrix inverse. + @param[in] pSrc points to input matrix structure + @param[out] pDst points to output matrix structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + - \ref ARM_MATH_SINGULAR : Input matrix is found to be singular (non-invertible) + */ + +arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst) +{ + float32_t *pIn = pSrc->pData; /* input data matrix pointer */ + float32_t *pOut = pDst->pData; /* output data matrix pointer */ + float32_t *pInT1, *pInT2; /* Temporary input data matrix pointer */ + float32_t *pOutT1, *pOutT2; /* Temporary output data matrix pointer */ + float32_t *pPivotRowIn, *pPRT_in, *pPivotRowDst, *pPRT_pDst; /* Temporary input and output data matrix pointer */ + uint32_t numRows = pSrc->numRows; /* Number of rows in the matrix */ + uint32_t numCols = pSrc->numCols; /* Number of Cols in the matrix */ + +#if defined (ARM_MATH_DSP) + float32_t maxC; /* maximum value in the column */ + + float32_t Xchg, in = 0.0f, in1; /* Temporary input values */ + uint32_t i, rowCnt, flag = 0U, j, loopCnt, k, l; /* loop counters */ + arm_status status; /* status of matrix inverse */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrc->numRows != pSrc->numCols) || + (pDst->numRows != pDst->numCols) || + (pSrc->numRows != pDst->numRows) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + + /*-------------------------------------------------------------------------------------------------------------- + * Matrix Inverse can be solved using elementary row operations. + * + * Gauss-Jordan Method: + * + * 1. First combine the identity matrix and the input matrix separated by a bar to form an + * augmented matrix as follows: + * _ _ _ _ + * | a11 a12 | 1 0 | | X11 X12 | + * | | | = | | + * |_ a21 a22 | 0 1 _| |_ X21 X21 _| + * + * 2. In our implementation, pDst Matrix is used as identity matrix. + * + * 3. Begin with the first row. Let i = 1. + * + * 4. Check to see if the pivot for column i is the greatest of the column. + * The pivot is the element of the main diagonal that is on the current row. + * For instance, if working with row i, then the pivot element is aii. + * If the pivot is not the most significant of the columns, exchange that row with a row + * below it that does contain the most significant value in column i. If the most + * significant value of the column is zero, then an inverse to that matrix does not exist. + * The most significant value of the column is the absolute maximum. + * + * 5. Divide every element of row i by the pivot. + * + * 6. For every row below and row i, replace that row with the sum of that row and + * a multiple of row i so that each new element in column i below row i is zero. + * + * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros + * for every element below and above the main diagonal. + * + * 8. Now an identical matrix is formed to the left of the bar(input matrix, pSrc). + * Therefore, the matrix to the right of the bar is our solution(pDst matrix, pDst). + *----------------------------------------------------------------------------------------------------------------*/ + + /* Working pointer for destination matrix */ + pOutT1 = pOut; + + /* Loop over the number of rows */ + rowCnt = numRows; + + /* Making the destination matrix as identity matrix */ + while (rowCnt > 0U) + { + /* Writing all zeroes in lower triangle of the destination matrix */ + j = numRows - rowCnt; + while (j > 0U) + { + *pOutT1++ = 0.0f; + j--; + } + + /* Writing all ones in the diagonal of the destination matrix */ + *pOutT1++ = 1.0f; + + /* Writing all zeroes in upper triangle of the destination matrix */ + j = rowCnt - 1U; + while (j > 0U) + { + *pOutT1++ = 0.0f; + j--; + } + + /* Decrement loop counter */ + rowCnt--; + } + + /* Loop over the number of columns of the input matrix. + All the elements in each column are processed by the row operations */ + loopCnt = numCols; + + /* Index modifier to navigate through the columns */ + l = 0U; + + while (loopCnt > 0U) + { + /* Check if the pivot element is zero.. + * If it is zero then interchange the row with non zero row below. + * If there is no non zero element to replace in the rows below, + * then the matrix is Singular. */ + + /* Working pointer for the input matrix that points + * to the pivot element of the particular row */ + pInT1 = pIn + (l * numCols); + + /* Working pointer for the destination matrix that points + * to the pivot element of the particular row */ + pOutT1 = pOut + (l * numCols); + + /* Temporary variable to hold the pivot value */ + in = *pInT1; + + /* Grab the most significant value from column l */ + maxC = 0; + for (i = l; i < numRows; i++) + { + maxC = *pInT1 > 0 ? (*pInT1 > maxC ? *pInT1 : maxC) : (-*pInT1 > maxC ? -*pInT1 : maxC); + pInT1 += numCols; + } + + /* Update the status if the matrix is singular */ + if (maxC == 0.0f) + { + return ARM_MATH_SINGULAR; + } + + /* Restore pInT1 */ + pInT1 = pIn; + + /* Destination pointer modifier */ + k = 1U; + + /* Check if the pivot element is the most significant of the column */ + if ( (in > 0.0f ? in : -in) != maxC) + { + /* Loop over the number rows present below */ + i = numRows - (l + 1U); + + while (i > 0U) + { + /* Update the input and destination pointers */ + pInT2 = pInT1 + (numCols * l); + pOutT2 = pOutT1 + (numCols * k); + + /* Look for the most significant element to + * replace in the rows below */ + if ((*pInT2 > 0.0f ? *pInT2: -*pInT2) == maxC) + { + /* Loop over number of columns + * to the right of the pilot element */ + j = numCols - l; + + while (j > 0U) + { + /* Exchange the row elements of the input matrix */ + Xchg = *pInT2; + *pInT2++ = *pInT1; + *pInT1++ = Xchg; + + /* Decrement the loop counter */ + j--; + } + + /* Loop over number of columns of the destination matrix */ + j = numCols; + + while (j > 0U) + { + /* Exchange the row elements of the destination matrix */ + Xchg = *pOutT2; + *pOutT2++ = *pOutT1; + *pOutT1++ = Xchg; + + /* Decrement loop counter */ + j--; + } + + /* Flag to indicate whether exchange is done or not */ + flag = 1U; + + /* Break after exchange is done */ + break; + } + + /* Update the destination pointer modifier */ + k++; + + /* Decrement loop counter */ + i--; + } + } + + /* Update the status if the matrix is singular */ + if ((flag != 1U) && (in == 0.0f)) + { + return ARM_MATH_SINGULAR; + } + + /* Points to the pivot row of input and destination matrices */ + pPivotRowIn = pIn + (l * numCols); + pPivotRowDst = pOut + (l * numCols); + + /* Temporary pointers to the pivot row pointers */ + pInT1 = pPivotRowIn; + pInT2 = pPivotRowDst; + + /* Pivot element of the row */ + in = *pPivotRowIn; + + /* Loop over number of columns + * to the right of the pilot element */ + j = (numCols - l); + + while (j > 0U) + { + /* Divide each element of the row of the input matrix + * by the pivot element */ + in1 = *pInT1; + *pInT1++ = in1 / in; + + /* Decrement the loop counter */ + j--; + } + + /* Loop over number of columns of the destination matrix */ + j = numCols; + + while (j > 0U) + { + /* Divide each element of the row of the destination matrix + * by the pivot element */ + in1 = *pInT2; + *pInT2++ = in1 / in; + + /* Decrement the loop counter */ + j--; + } + + /* Replace the rows with the sum of that row and a multiple of row i + * so that each new element in column i above row i is zero.*/ + + /* Temporary pointers for input and destination matrices */ + pInT1 = pIn; + pInT2 = pOut; + + /* index used to check for pivot element */ + i = 0U; + + /* Loop over number of rows */ + /* to be replaced by the sum of that row and a multiple of row i */ + k = numRows; + + while (k > 0U) + { + /* Check for the pivot element */ + if (i == l) + { + /* If the processing element is the pivot element, + only the columns to the right are to be processed */ + pInT1 += numCols - l; + + pInT2 += numCols; + } + else + { + /* Element of the reference row */ + in = *pInT1; + + /* Working pointers for input and destination pivot rows */ + pPRT_in = pPivotRowIn; + pPRT_pDst = pPivotRowDst; + + /* Loop over the number of columns to the right of the pivot element, + to replace the elements in the input matrix */ + j = (numCols - l); + + while (j > 0U) + { + /* Replace the element by the sum of that row + and a multiple of the reference row */ + in1 = *pInT1; + *pInT1++ = in1 - (in * *pPRT_in++); + + /* Decrement the loop counter */ + j--; + } + + /* Loop over the number of columns to + replace the elements in the destination matrix */ + j = numCols; + + while (j > 0U) + { + /* Replace the element by the sum of that row + and a multiple of the reference row */ + in1 = *pInT2; + *pInT2++ = in1 - (in * *pPRT_pDst++); + + /* Decrement loop counter */ + j--; + } + + } + + /* Increment temporary input pointer */ + pInT1 = pInT1 + l; + + /* Decrement loop counter */ + k--; + + /* Increment pivot index */ + i++; + } + + /* Increment the input pointer */ + pIn++; + + /* Decrement the loop counter */ + loopCnt--; + + /* Increment the index modifier */ + l++; + } + + +#else + + float32_t Xchg, in = 0.0f; /* Temporary input values */ + uint32_t i, rowCnt, flag = 0U, j, loopCnt, k, l; /* loop counters */ + arm_status status; /* status of matrix inverse */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrc->numRows != pSrc->numCols) || + (pDst->numRows != pDst->numCols) || + (pSrc->numRows != pDst->numRows) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + + /*-------------------------------------------------------------------------------------------------------------- + * Matrix Inverse can be solved using elementary row operations. + * + * Gauss-Jordan Method: + * + * 1. First combine the identity matrix and the input matrix separated by a bar to form an + * augmented matrix as follows: + * _ _ _ _ _ _ _ _ + * | | a11 a12 | | | 1 0 | | | X11 X12 | + * | | | | | | | = | | + * |_ |_ a21 a22 _| | |_0 1 _| _| |_ X21 X21 _| + * + * 2. In our implementation, pDst Matrix is used as identity matrix. + * + * 3. Begin with the first row. Let i = 1. + * + * 4. Check to see if the pivot for row i is zero. + * The pivot is the element of the main diagonal that is on the current row. + * For instance, if working with row i, then the pivot element is aii. + * If the pivot is zero, exchange that row with a row below it that does not + * contain a zero in column i. If this is not possible, then an inverse + * to that matrix does not exist. + * + * 5. Divide every element of row i by the pivot. + * + * 6. For every row below and row i, replace that row with the sum of that row and + * a multiple of row i so that each new element in column i below row i is zero. + * + * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros + * for every element below and above the main diagonal. + * + * 8. Now an identical matrix is formed to the left of the bar(input matrix, src). + * Therefore, the matrix to the right of the bar is our solution(dst matrix, dst). + *----------------------------------------------------------------------------------------------------------------*/ + + /* Working pointer for destination matrix */ + pOutT1 = pOut; + + /* Loop over the number of rows */ + rowCnt = numRows; + + /* Making the destination matrix as identity matrix */ + while (rowCnt > 0U) + { + /* Writing all zeroes in lower triangle of the destination matrix */ + j = numRows - rowCnt; + while (j > 0U) + { + *pOutT1++ = 0.0f; + j--; + } + + /* Writing all ones in the diagonal of the destination matrix */ + *pOutT1++ = 1.0f; + + /* Writing all zeroes in upper triangle of the destination matrix */ + j = rowCnt - 1U; + while (j > 0U) + { + *pOutT1++ = 0.0f; + j--; + } + + /* Decrement loop counter */ + rowCnt--; + } + + /* Loop over the number of columns of the input matrix. + All the elements in each column are processed by the row operations */ + loopCnt = numCols; + + /* Index modifier to navigate through the columns */ + l = 0U; + + while (loopCnt > 0U) + { + /* Check if the pivot element is zero.. + * If it is zero then interchange the row with non zero row below. + * If there is no non zero element to replace in the rows below, + * then the matrix is Singular. */ + + /* Working pointer for the input matrix that points + * to the pivot element of the particular row */ + pInT1 = pIn + (l * numCols); + + /* Working pointer for the destination matrix that points + * to the pivot element of the particular row */ + pOutT1 = pOut + (l * numCols); + + /* Temporary variable to hold the pivot value */ + in = *pInT1; + + /* Destination pointer modifier */ + k = 1U; + + /* Check if the pivot element is zero */ + if (*pInT1 == 0.0f) + { + /* Loop over the number rows present below */ + for (i = (l + 1U); i < numRows; i++) + { + /* Update the input and destination pointers */ + pInT2 = pInT1 + (numCols * l); + pOutT2 = pOutT1 + (numCols * k); + + /* Check if there is a non zero pivot element to + * replace in the rows below */ + if (*pInT2 != 0.0f) + { + /* Loop over number of columns + * to the right of the pilot element */ + for (j = 0U; j < (numCols - l); j++) + { + /* Exchange the row elements of the input matrix */ + Xchg = *pInT2; + *pInT2++ = *pInT1; + *pInT1++ = Xchg; + } + + for (j = 0U; j < numCols; j++) + { + Xchg = *pOutT2; + *pOutT2++ = *pOutT1; + *pOutT1++ = Xchg; + } + + /* Flag to indicate whether exchange is done or not */ + flag = 1U; + + /* Break after exchange is done */ + break; + } + + /* Update the destination pointer modifier */ + k++; + } + } + + /* Update the status if the matrix is singular */ + if ((flag != 1U) && (in == 0.0f)) + { + return ARM_MATH_SINGULAR; + } + + /* Points to the pivot row of input and destination matrices */ + pPivotRowIn = pIn + (l * numCols); + pPivotRowDst = pOut + (l * numCols); + + /* Temporary pointers to the pivot row pointers */ + pInT1 = pPivotRowIn; + pOutT1 = pPivotRowDst; + + /* Pivot element of the row */ + in = *(pIn + (l * numCols)); + + /* Loop over number of columns + * to the right of the pilot element */ + for (j = 0U; j < (numCols - l); j++) + { + /* Divide each element of the row of the input matrix + * by the pivot element */ + *pInT1 = *pInT1 / in; + pInT1++; + } + for (j = 0U; j < numCols; j++) + { + /* Divide each element of the row of the destination matrix + * by the pivot element */ + *pOutT1 = *pOutT1 / in; + pOutT1++; + } + + /* Replace the rows with the sum of that row and a multiple of row i + * so that each new element in column i above row i is zero.*/ + + /* Temporary pointers for input and destination matrices */ + pInT1 = pIn; + pOutT1 = pOut; + + for (i = 0U; i < numRows; i++) + { + /* Check for the pivot element */ + if (i == l) + { + /* If the processing element is the pivot element, + only the columns to the right are to be processed */ + pInT1 += numCols - l; + pOutT1 += numCols; + } + else + { + /* Element of the reference row */ + in = *pInT1; + + /* Working pointers for input and destination pivot rows */ + pPRT_in = pPivotRowIn; + pPRT_pDst = pPivotRowDst; + + /* Loop over the number of columns to the right of the pivot element, + to replace the elements in the input matrix */ + for (j = 0U; j < (numCols - l); j++) + { + /* Replace the element by the sum of that row + and a multiple of the reference row */ + *pInT1 = *pInT1 - (in * *pPRT_in++); + pInT1++; + } + + /* Loop over the number of columns to + replace the elements in the destination matrix */ + for (j = 0U; j < numCols; j++) + { + /* Replace the element by the sum of that row + and a multiple of the reference row */ + *pOutT1 = *pOutT1 - (in * *pPRT_pDst++); + pOutT1++; + } + + } + + /* Increment temporary input pointer */ + pInT1 = pInT1 + l; + } + + /* Increment the input pointer */ + pIn++; + + /* Decrement the loop counter */ + loopCnt--; + + /* Increment the index modifier */ + l++; + } + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + + if ((flag != 1U) && (in == 0.0f)) + { + pIn = pSrc->pData; + for (i = 0; i < numRows * numCols; i++) + { + if (pIn[i] != 0.0f) + break; + } + + if (i == numRows * numCols) + status = ARM_MATH_SINGULAR; + } + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixInv group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_inverse_f64.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_inverse_f64.c new file mode 100644 index 0000000..26b0f70 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_inverse_f64.c @@ -0,0 +1,673 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_inverse_f64.c + * Description: Floating-point matrix inverse + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + + +/** + @addtogroup MatrixInv + @{ + */ + +/** + @brief Floating-point (64 bit) matrix inverse. + @param[in] pSrc points to input matrix structure + @param[out] pDst points to output matrix structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + - \ref ARM_MATH_SINGULAR : Input matrix is found to be singular (non-invertible) + */ + +arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * pSrc, + arm_matrix_instance_f64 * pDst) +{ + float64_t *pIn = pSrc->pData; /* input data matrix pointer */ + float64_t *pOut = pDst->pData; /* output data matrix pointer */ + float64_t *pInT1, *pInT2; /* Temporary input data matrix pointer */ + float64_t *pOutT1, *pOutT2; /* Temporary output data matrix pointer */ + float64_t *pPivotRowIn, *pPRT_in, *pPivotRowDst, *pPRT_pDst; /* Temporary input and output data matrix pointer */ + uint32_t numRows = pSrc->numRows; /* Number of rows in the matrix */ + uint32_t numCols = pSrc->numCols; /* Number of Cols in the matrix */ + +#if defined (ARM_MATH_DSP) + float64_t maxC; /* maximum value in the column */ + + float64_t Xchg, in = 0.0, in1; /* Temporary input values */ + uint32_t i, rowCnt, flag = 0U, j, loopCnt, k, l; /* loop counters */ + arm_status status; /* status of matrix inverse */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrc->numRows != pSrc->numCols) || + (pDst->numRows != pDst->numCols) || + (pSrc->numRows != pDst->numRows) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + + /*-------------------------------------------------------------------------------------------------------------- + * Matrix Inverse can be solved using elementary row operations. + * + * Gauss-Jordan Method: + * + * 1. First combine the identity matrix and the input matrix separated by a bar to form an + * augmented matrix as follows: + * _ _ _ _ + * | a11 a12 | 1 0 | | X11 X12 | + * | | | = | | + * |_ a21 a22 | 0 1 _| |_ X21 X21 _| + * + * 2. In our implementation, pDst Matrix is used as identity matrix. + * + * 3. Begin with the first row. Let i = 1. + * + * 4. Check to see if the pivot for column i is the greatest of the column. + * The pivot is the element of the main diagonal that is on the current row. + * For instance, if working with row i, then the pivot element is aii. + * If the pivot is not the most significant of the columns, exchange that row with a row + * below it that does contain the most significant value in column i. If the most + * significant value of the column is zero, then an inverse to that matrix does not exist. + * The most significant value of the column is the absolute maximum. + * + * 5. Divide every element of row i by the pivot. + * + * 6. For every row below and row i, replace that row with the sum of that row and + * a multiple of row i so that each new element in column i below row i is zero. + * + * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros + * for every element below and above the main diagonal. + * + * 8. Now an identical matrix is formed to the left of the bar(input matrix, pSrc). + * Therefore, the matrix to the right of the bar is our solution(pDst matrix, pDst). + *----------------------------------------------------------------------------------------------------------------*/ + + /* Working pointer for destination matrix */ + pOutT1 = pOut; + + /* Loop over the number of rows */ + rowCnt = numRows; + + /* Making the destination matrix as identity matrix */ + while (rowCnt > 0U) + { + /* Writing all zeroes in lower triangle of the destination matrix */ + j = numRows - rowCnt; + while (j > 0U) + { + *pOutT1++ = 0.0; + j--; + } + + /* Writing all ones in the diagonal of the destination matrix */ + *pOutT1++ = 1.0; + + /* Writing all zeroes in upper triangle of the destination matrix */ + j = rowCnt - 1U; + while (j > 0U) + { + *pOutT1++ = 0.0; + j--; + } + + /* Decrement loop counter */ + rowCnt--; + } + + /* Loop over the number of columns of the input matrix. + All the elements in each column are processed by the row operations */ + loopCnt = numCols; + + /* Index modifier to navigate through the columns */ + l = 0U; + + while (loopCnt > 0U) + { + /* Check if the pivot element is zero.. + * If it is zero then interchange the row with non zero row below. + * If there is no non zero element to replace in the rows below, + * then the matrix is Singular. */ + + /* Working pointer for the input matrix that points + * to the pivot element of the particular row */ + pInT1 = pIn + (l * numCols); + + /* Working pointer for the destination matrix that points + * to the pivot element of the particular row */ + pOutT1 = pOut + (l * numCols); + + /* Temporary variable to hold the pivot value */ + in = *pInT1; + + /* Grab the most significant value from column l */ + maxC = 0; + for (i = l; i < numRows; i++) + { + maxC = *pInT1 > 0 ? (*pInT1 > maxC ? *pInT1 : maxC) : (-*pInT1 > maxC ? -*pInT1 : maxC); + pInT1 += numCols; + } + + /* Update the status if the matrix is singular */ + if (maxC == (float64_t)0.0) + { + return ARM_MATH_SINGULAR; + } + + /* Restore pInT1 */ + pInT1 = pIn; + + /* Destination pointer modifier */ + k = 1U; + + /* Check if the pivot element is the most significant of the column */ + if ( (in > (float64_t)0.0 ? in : -in) != maxC) + { + /* Loop over the number rows present below */ + i = numRows - (l + 1U); + + while (i > 0U) + { + /* Update the input and destination pointers */ + pInT2 = pInT1 + (numCols * l); + pOutT2 = pOutT1 + (numCols * k); + + /* Look for the most significant element to + * replace in the rows below */ + if ((*pInT2 > (float64_t)0.0 ? *pInT2: -*pInT2) == maxC) + { + /* Loop over number of columns + * to the right of the pilot element */ + j = numCols - l; + + while (j > 0U) + { + /* Exchange the row elements of the input matrix */ + Xchg = *pInT2; + *pInT2++ = *pInT1; + *pInT1++ = Xchg; + + /* Decrement the loop counter */ + j--; + } + + /* Loop over number of columns of the destination matrix */ + j = numCols; + + while (j > 0U) + { + /* Exchange the row elements of the destination matrix */ + Xchg = *pOutT2; + *pOutT2++ = *pOutT1; + *pOutT1++ = Xchg; + + /* Decrement loop counter */ + j--; + } + + /* Flag to indicate whether exchange is done or not */ + flag = 1U; + + /* Break after exchange is done */ + break; + } + + /* Update the destination pointer modifier */ + k++; + + /* Decrement loop counter */ + i--; + } + } + + /* Update the status if the matrix is singular */ + if ((flag != 1U) && (in == (float64_t)0.0)) + { + return ARM_MATH_SINGULAR; + } + + /* Points to the pivot row of input and destination matrices */ + pPivotRowIn = pIn + (l * numCols); + pPivotRowDst = pOut + (l * numCols); + + /* Temporary pointers to the pivot row pointers */ + pInT1 = pPivotRowIn; + pInT2 = pPivotRowDst; + + /* Pivot element of the row */ + in = *pPivotRowIn; + + /* Loop over number of columns + * to the right of the pilot element */ + j = (numCols - l); + + while (j > 0U) + { + /* Divide each element of the row of the input matrix + * by the pivot element */ + in1 = *pInT1; + *pInT1++ = in1 / in; + + /* Decrement the loop counter */ + j--; + } + + /* Loop over number of columns of the destination matrix */ + j = numCols; + + while (j > 0U) + { + /* Divide each element of the row of the destination matrix + * by the pivot element */ + in1 = *pInT2; + *pInT2++ = in1 / in; + + /* Decrement the loop counter */ + j--; + } + + /* Replace the rows with the sum of that row and a multiple of row i + * so that each new element in column i above row i is zero.*/ + + /* Temporary pointers for input and destination matrices */ + pInT1 = pIn; + pInT2 = pOut; + + /* index used to check for pivot element */ + i = 0U; + + /* Loop over number of rows */ + /* to be replaced by the sum of that row and a multiple of row i */ + k = numRows; + + while (k > 0U) + { + /* Check for the pivot element */ + if (i == l) + { + /* If the processing element is the pivot element, + only the columns to the right are to be processed */ + pInT1 += numCols - l; + + pInT2 += numCols; + } + else + { + /* Element of the reference row */ + in = *pInT1; + + /* Working pointers for input and destination pivot rows */ + pPRT_in = pPivotRowIn; + pPRT_pDst = pPivotRowDst; + + /* Loop over the number of columns to the right of the pivot element, + to replace the elements in the input matrix */ + j = (numCols - l); + + while (j > 0U) + { + /* Replace the element by the sum of that row + and a multiple of the reference row */ + in1 = *pInT1; + *pInT1++ = in1 - (in * *pPRT_in++); + + /* Decrement the loop counter */ + j--; + } + + /* Loop over the number of columns to + replace the elements in the destination matrix */ + j = numCols; + + while (j > 0U) + { + /* Replace the element by the sum of that row + and a multiple of the reference row */ + in1 = *pInT2; + *pInT2++ = in1 - (in * *pPRT_pDst++); + + /* Decrement loop counter */ + j--; + } + + } + + /* Increment temporary input pointer */ + pInT1 = pInT1 + l; + + /* Decrement loop counter */ + k--; + + /* Increment pivot index */ + i++; + } + + /* Increment the input pointer */ + pIn++; + + /* Decrement the loop counter */ + loopCnt--; + + /* Increment the index modifier */ + l++; + } + + +#else + + float64_t Xchg, in = 0.0; /* Temporary input values */ + uint32_t i, rowCnt, flag = 0U, j, loopCnt, k, l; /* loop counters */ + arm_status status; /* status of matrix inverse */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrc->numRows != pSrc->numCols) || + (pDst->numRows != pDst->numCols) || + (pSrc->numRows != pDst->numRows) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + + /*-------------------------------------------------------------------------------------------------------------- + * Matrix Inverse can be solved using elementary row operations. + * + * Gauss-Jordan Method: + * + * 1. First combine the identity matrix and the input matrix separated by a bar to form an + * augmented matrix as follows: + * _ _ _ _ _ _ _ _ + * | | a11 a12 | | | 1 0 | | | X11 X12 | + * | | | | | | | = | | + * |_ |_ a21 a22 _| | |_0 1 _| _| |_ X21 X21 _| + * + * 2. In our implementation, pDst Matrix is used as identity matrix. + * + * 3. Begin with the first row. Let i = 1. + * + * 4. Check to see if the pivot for row i is zero. + * The pivot is the element of the main diagonal that is on the current row. + * For instance, if working with row i, then the pivot element is aii. + * If the pivot is zero, exchange that row with a row below it that does not + * contain a zero in column i. If this is not possible, then an inverse + * to that matrix does not exist. + * + * 5. Divide every element of row i by the pivot. + * + * 6. For every row below and row i, replace that row with the sum of that row and + * a multiple of row i so that each new element in column i below row i is zero. + * + * 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros + * for every element below and above the main diagonal. + * + * 8. Now an identical matrix is formed to the left of the bar(input matrix, src). + * Therefore, the matrix to the right of the bar is our solution(dst matrix, dst). + *----------------------------------------------------------------------------------------------------------------*/ + + /* Working pointer for destination matrix */ + pOutT1 = pOut; + + /* Loop over the number of rows */ + rowCnt = numRows; + + /* Making the destination matrix as identity matrix */ + while (rowCnt > 0U) + { + /* Writing all zeroes in lower triangle of the destination matrix */ + j = numRows - rowCnt; + while (j > 0U) + { + *pOutT1++ = 0.0; + j--; + } + + /* Writing all ones in the diagonal of the destination matrix */ + *pOutT1++ = 1.0; + + /* Writing all zeroes in upper triangle of the destination matrix */ + j = rowCnt - 1U; + while (j > 0U) + { + *pOutT1++ = 0.0; + j--; + } + + /* Decrement loop counter */ + rowCnt--; + } + + /* Loop over the number of columns of the input matrix. + All the elements in each column are processed by the row operations */ + loopCnt = numCols; + + /* Index modifier to navigate through the columns */ + l = 0U; + + while (loopCnt > 0U) + { + /* Check if the pivot element is zero.. + * If it is zero then interchange the row with non zero row below. + * If there is no non zero element to replace in the rows below, + * then the matrix is Singular. */ + + /* Working pointer for the input matrix that points + * to the pivot element of the particular row */ + pInT1 = pIn + (l * numCols); + + /* Working pointer for the destination matrix that points + * to the pivot element of the particular row */ + pOutT1 = pOut + (l * numCols); + + /* Temporary variable to hold the pivot value */ + in = *pInT1; + + /* Destination pointer modifier */ + k = 1U; + + /* Check if the pivot element is zero */ + if (*pInT1 == 0.0) + { + /* Loop over the number rows present below */ + for (i = (l + 1U); i < numRows; i++) + { + /* Update the input and destination pointers */ + pInT2 = pInT1 + (numCols * l); + pOutT2 = pOutT1 + (numCols * k); + + /* Check if there is a non zero pivot element to + * replace in the rows below */ + if (*pInT2 != 0.0) + { + /* Loop over number of columns + * to the right of the pilot element */ + for (j = 0U; j < (numCols - l); j++) + { + /* Exchange the row elements of the input matrix */ + Xchg = *pInT2; + *pInT2++ = *pInT1; + *pInT1++ = Xchg; + } + + for (j = 0U; j < numCols; j++) + { + Xchg = *pOutT2; + *pOutT2++ = *pOutT1; + *pOutT1++ = Xchg; + } + + /* Flag to indicate whether exchange is done or not */ + flag = 1U; + + /* Break after exchange is done */ + break; + } + + /* Update the destination pointer modifier */ + k++; + } + } + + /* Update the status if the matrix is singular */ + if ((flag != 1U) && (in == 0.0)) + { + return ARM_MATH_SINGULAR; + } + + /* Points to the pivot row of input and destination matrices */ + pPivotRowIn = pIn + (l * numCols); + pPivotRowDst = pOut + (l * numCols); + + /* Temporary pointers to the pivot row pointers */ + pInT1 = pPivotRowIn; + pOutT1 = pPivotRowDst; + + /* Pivot element of the row */ + in = *(pIn + (l * numCols)); + + /* Loop over number of columns + * to the right of the pilot element */ + for (j = 0U; j < (numCols - l); j++) + { + /* Divide each element of the row of the input matrix + * by the pivot element */ + *pInT1 = *pInT1 / in; + pInT1++; + } + for (j = 0U; j < numCols; j++) + { + /* Divide each element of the row of the destination matrix + * by the pivot element */ + *pOutT1 = *pOutT1 / in; + pOutT1++; + } + + /* Replace the rows with the sum of that row and a multiple of row i + * so that each new element in column i above row i is zero.*/ + + /* Temporary pointers for input and destination matrices */ + pInT1 = pIn; + pOutT1 = pOut; + + for (i = 0U; i < numRows; i++) + { + /* Check for the pivot element */ + if (i == l) + { + /* If the processing element is the pivot element, + only the columns to the right are to be processed */ + pInT1 += numCols - l; + pOutT1 += numCols; + } + else + { + /* Element of the reference row */ + in = *pInT1; + + /* Working pointers for input and destination pivot rows */ + pPRT_in = pPivotRowIn; + pPRT_pDst = pPivotRowDst; + + /* Loop over the number of columns to the right of the pivot element, + to replace the elements in the input matrix */ + for (j = 0U; j < (numCols - l); j++) + { + /* Replace the element by the sum of that row + and a multiple of the reference row */ + *pInT1 = *pInT1 - (in * *pPRT_in++); + pInT1++; + } + + /* Loop over the number of columns to + replace the elements in the destination matrix */ + for (j = 0U; j < numCols; j++) + { + /* Replace the element by the sum of that row + and a multiple of the reference row */ + *pOutT1 = *pOutT1 - (in * *pPRT_pDst++); + pOutT1++; + } + + } + + /* Increment temporary input pointer */ + pInT1 = pInT1 + l; + } + + /* Increment the input pointer */ + pIn++; + + /* Decrement the loop counter */ + loopCnt--; + + /* Increment the index modifier */ + l++; + } + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + + if ((flag != 1U) && (in == (float64_t)0.0)) + { + pIn = pSrc->pData; + for (i = 0; i < numRows * numCols; i++) + { + if (pIn[i] != (float64_t)0.0) + break; + } + + if (i == numRows * numCols) + status = ARM_MATH_SINGULAR; + } + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixInv group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_f32.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_f32.c new file mode 100644 index 0000000..e52d60c --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_f32.c @@ -0,0 +1,200 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_mult_f32.c + * Description: Floating-point matrix multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @defgroup MatrixMult Matrix Multiplication + + Multiplies two matrices. + + \image html MatrixMultiplication.gif "Multiplication of two 3 x 3 matrices" + + Matrix multiplication is only defined if the number of columns of the + first matrix equals the number of rows of the second matrix. + Multiplying an M x N matrix with an N x P matrix results + in an M x P matrix. + When matrix size checking is enabled, the functions check: + - that the inner dimensions of pSrcA and pSrcB are equal; + - that the size of the output matrix equals the outer dimensions of pSrcA and pSrcB. + */ + +/** + @addtogroup MatrixMult + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + */ + +arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst) +{ + float32_t *pIn1 = pSrcA->pData; /* Input data matrix pointer A */ + float32_t *pIn2 = pSrcB->pData; /* Input data matrix pointer B */ + float32_t *pInA = pSrcA->pData; /* Input data matrix pointer A */ + float32_t *pInB = pSrcB->pData; /* Input data matrix pointer B */ + float32_t *pOut = pDst->pData; /* Output data matrix pointer */ + float32_t *px; /* Temporary output data matrix pointer */ + float32_t sum; /* Accumulator */ + uint16_t numRowsA = pSrcA->numRows; /* Number of rows of input matrix A */ + uint16_t numColsB = pSrcB->numCols; /* Number of columns of input matrix B */ + uint16_t numColsA = pSrcA->numCols; /* Number of columns of input matrix A */ + uint32_t col, i = 0U, row = numRowsA, colCnt; /* Loop counters */ + arm_status status; /* Status of matrix multiplication */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numCols != pSrcB->numRows) || + (pSrcA->numRows != pDst->numRows) || + (pSrcB->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */ + /* row loop */ + do + { + /* Output pointer is set to starting address of row being processed */ + px = pOut + i; + + /* For every row wise process, column loop counter is to be initiated */ + col = numColsB; + + /* For every row wise process, pIn2 pointer is set to starting address of pSrcB data */ + pIn2 = pSrcB->pData; + + /* column loop */ + do + { + /* Set the variable sum, that acts as accumulator, to zero */ + sum = 0.0f; + + /* Initialize pointer pIn1 to point to starting address of column being processed */ + pIn1 = pInA; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 MACs at a time. */ + colCnt = numColsA >> 2U; + + /* matrix multiplication */ + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + /* Perform the multiply-accumulates */ + sum += *pIn1++ * *pIn2; + pIn2 += numColsB; + + sum += *pIn1++ * *pIn2; + pIn2 += numColsB; + + sum += *pIn1++ * *pIn2; + pIn2 += numColsB; + + sum += *pIn1++ * *pIn2; + pIn2 += numColsB; + + /* Decrement loop counter */ + colCnt--; + } + + /* Loop unrolling: Compute remaining MACs */ + colCnt = numColsA % 0x4U; + +#else + + /* Initialize cntCnt with number of columns */ + colCnt = numColsA; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + /* Perform the multiply-accumulates */ + sum += *pIn1++ * *pIn2; + pIn2 += numColsB; + + /* Decrement loop counter */ + colCnt--; + } + + /* Store result in destination buffer */ + *px++ = sum; + + /* Decrement column loop counter */ + col--; + + /* Update pointer pIn2 to point to starting address of next column */ + pIn2 = pInB + (numColsB - col); + + } while (col > 0U); + + /* Update pointer pInA to point to starting address of next row */ + i = i + numColsB; + pInA = pInA + numColsA; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixMult group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_fast_q15.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_fast_q15.c new file mode 100644 index 0000000..670ace1 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_fast_q15.c @@ -0,0 +1,483 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_mult_fast_q15.c + * Description: Q15 matrix multiplication (fast variant) + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixMult + @{ + */ + +/** + @brief Q15 matrix multiplication (fast variant). + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @par Scaling and Overflow Behavior + The difference between the function \ref arm_mat_mult_q15() and this fast variant is that + the fast variant use a 32-bit rather than a 64-bit accumulator. + The result of each 1.15 x 1.15 multiplication is truncated to + 2.30 format. These intermediate results are accumulated in a 32-bit register in 2.30 + format. Finally, the accumulator is saturated and converted to a 1.15 result. + @par + The fast version has the same overflow behavior as the standard version but provides + less precision since it discards the low 16 bits of each multiplication result. + In order to avoid overflows completely the input signals must be scaled down. + Scale down one of the input matrices by log2(numColsA) bits to avoid overflows, + as a total of numColsA additions are computed internally for each output element. + @remark + Refer to \ref arm_mat_mult_q15() for a slower implementation of this function + which uses 64-bit accumulation to provide higher precision. + */ + +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) +{ + q31_t sum; /* Accumulator */ + q15_t *pSrcBT = pState; /* Input data matrix pointer for transpose */ + q15_t *pInA = pSrcA->pData; /* Input data matrix pointer A of Q15 type */ + q15_t *pInB = pSrcB->pData; /* Input data matrix pointer B of Q15 type */ + q15_t *px; /* Temporary output data matrix pointer */ + uint16_t numRowsA = pSrcA->numRows; /* Number of rows of input matrix A */ + uint16_t numColsB = pSrcB->numCols; /* Number of columns of input matrix B */ + uint16_t numColsA = pSrcA->numCols; /* Number of columns of input matrix A */ + uint16_t numRowsB = pSrcB->numRows; /* Number of rows of input matrix A */ + uint32_t col, i = 0U, row = numRowsB, colCnt; /* Loop counters */ + arm_status status; /* Status of matrix multiplication */ + +#if defined (ARM_MATH_DSP) + q31_t in; /* Temporary variable to hold the input value */ + q31_t inA1, inB1, inA2, inB2; + q31_t sum2, sum3, sum4; + q15_t *pInA2, *pInB2, *px2; + uint32_t j = 0; +#else + q15_t in; /* Temporary variable to hold the input value */ + q15_t inA1, inB1, inA2, inB2; +#endif /* #if defined (ARM_MATH_DSP) */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numCols != pSrcB->numRows) || + (pSrcA->numRows != pDst->numRows) || + (pSrcB->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Matrix transpose */ + do + { + /* The pointer px is set to starting address of column being processed */ + px = pSrcBT + i; + + /* Apply loop unrolling and exchange columns with row elements */ + col = numColsB >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + while (col > 0U) + { + +#if defined (ARM_MATH_DSP) + + /* Read two elements from row */ + in = read_q15x2_ia ((q15_t **) &pInB); + + /* Unpack and store one element in destination */ +#ifndef ARM_MATH_BIG_ENDIAN + *px = (q15_t) in; +#else + *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB; + + /* Unpack and store second element in destination */ +#ifndef ARM_MATH_BIG_ENDIAN + *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#else + *px = (q15_t) in; +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB; + + in = read_q15x2_ia ((q15_t **) &pInB); +#ifndef ARM_MATH_BIG_ENDIAN + *px = (q15_t) in; +#else + *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + px += numRowsB; + +#ifndef ARM_MATH_BIG_ENDIAN + *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#else + *px = (q15_t) in; +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + px += numRowsB; + +#else /* #if defined (ARM_MATH_DSP) */ + + /* Read one element from row */ + in = *pInB++; + + /* Store one element in destination */ + *px = in; + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB; + + in = *pInB++; + *px = in; + px += numRowsB; + + in = *pInB++; + *px = in; + px += numRowsB; + + in = *pInB++; + *px = in; + px += numRowsB; + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement column loop counter */ + col--; + } + + /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + col = numColsB % 0x4U; + + while (col > 0U) + { + /* Read and store input element in destination */ + *px = *pInB++; + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB; + + /* Decrement column loop counter */ + col--; + } + + i++; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); + + /* Reset variables for usage in following multiplication process */ + row = numRowsA; + i = 0U; + px = pDst->pData; + +#if defined (ARM_MATH_DSP) + /* Process two rows from matrix A at a time and output two rows at a time */ + row = row >> 1U; + px2 = px + numColsB; +#endif + + /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */ + /* row loop */ + while (row > 0U) + { + /* For every row wise process, column loop counter is to be initiated */ + col = numColsB; + + /* For every row wise process, pIn2 pointer is set to starting address of transposed pSrcB data */ + pInB = pSrcBT; + +#if defined (ARM_MATH_DSP) + /* Process two (transposed) columns from matrix B at a time */ + col = col >> 1U; + j = 0; +#endif + + /* column loop */ + while (col > 0U) + { + /* Set variable sum, that acts as accumulator, to zero */ + sum = 0; + + /* Initiate pointer pInA to point to starting address of column being processed */ + pInA = pSrcA->pData + i; + +#if defined (ARM_MATH_DSP) + sum2 = 0; + sum3 = 0; + sum4 = 0; + pInB = pSrcBT + j; + pInA2 = pInA + numColsA; + pInB2 = pInB + numRowsB; + + /* Read in two elements at once - alows dual MAC instruction */ + colCnt = numColsA >> 1U; +#else + colCnt = numColsA >> 2U; +#endif + + /* matrix multiplication */ + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + +#if defined (ARM_MATH_DSP) + /* read real and imag values from pSrcA and pSrcB buffer */ + inA1 = read_q15x2_ia ((q15_t **) &pInA); + inB1 = read_q15x2_ia ((q15_t **) &pInB); + + inA2 = read_q15x2_ia ((q15_t **) &pInA2); + inB2 = read_q15x2_ia ((q15_t **) &pInB2); + + /* Multiply and Accumlates */ + sum = __SMLAD(inA1, inB1, sum); + sum2 = __SMLAD(inA1, inB2, sum2); + sum3 = __SMLAD(inA2, inB1, sum3); + sum4 = __SMLAD(inA2, inB2, sum4); +#else + /* read real and imag values from pSrcA and pSrcB buffer */ + inA1 = *pInA++; + inB1 = *pInB++; + /* Multiply and Accumlates */ + sum += inA1 * inB1; + + inA2 = *pInA++; + inB2 = *pInB++; + sum += inA2 * inB2; + + inA1 = *pInA++; + inB1 = *pInB++; + sum += inA1 * inB1; + + inA2 = *pInA++; + inB2 = *pInB++; + sum += inA2 * inB2; +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + colCnt--; + } + + /* process odd column samples */ +#if defined (ARM_MATH_DSP) + if (numColsA & 1U) { + inA1 = *pInA++; + inB1 = *pInB++; + inA2 = *pInA2++; + inB2 = *pInB2++; + sum += inA1 * inB1; + sum2 += inA1 * inB2; + sum3 += inA2 * inB1; + sum4 += inA2 * inB2; + } +#else + colCnt = numColsA % 0x4U; + + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + sum += (q31_t) *pInA++ * *pInB++; + + /* Decrement loop counter */ + colCnt--; + } +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Saturate and store result in destination buffer */ + *px++ = (q15_t) (sum >> 15); + +#if defined (ARM_MATH_DSP) + *px++ = (q15_t) (sum2 >> 15); + *px2++ = (q15_t) (sum3 >> 15); + *px2++ = (q15_t) (sum4 >> 15); + j += numRowsB * 2; +#endif + + /* Decrement column loop counter */ + col--; + + } + + i = i + numColsA; + +#if defined (ARM_MATH_DSP) + i = i + numColsA; + px = px2 + (numColsB & 1U); + px2 = px + numColsB; +#endif + + /* Decrement row loop counter */ + row--; + + } + + /* Compute any remaining odd row/column below */ + +#if defined (ARM_MATH_DSP) + + /* Compute remaining output column */ + if (numColsB & 1U) { + + /* Avoid redundant computation of last element */ + row = numRowsA & (~0x1); + + /* Point to remaining unfilled column in output matrix */ + px = pDst->pData + numColsB-1; + pInA = pSrcA->pData; + + /* row loop */ + while (row > 0) + { + + /* point to last column in matrix B */ + pInB = pSrcBT + numRowsB * (numColsB-1); + + /* Set variable sum, that acts as accumulator, to zero */ + sum = 0; + + /* Compute 4 columns at once */ + colCnt = numColsA >> 2U; + + /* matrix multiplication */ + while (colCnt > 0U) + { + inA1 = read_q15x2_ia ((q15_t **) &pInA); + inA2 = read_q15x2_ia ((q15_t **) &pInA); + inB1 = read_q15x2_ia ((q15_t **) &pInB); + inB2 = read_q15x2_ia ((q15_t **) &pInB); + + sum = __SMLAD(inA1, inB1, sum); + sum = __SMLAD(inA2, inB2, sum); + + /* Decrement loop counter */ + colCnt--; + } + + colCnt = numColsA & 3U; + while (colCnt > 0U) { + sum += (q31_t) (*pInA++) * (*pInB++); + colCnt--; + } + + /* Store result in destination buffer */ + *px = (q15_t) (sum >> 15); + px += numColsB; + + /* Decrement row loop counter */ + row--; + } + } + + /* Compute remaining output row */ + if (numRowsA & 1U) { + + /* point to last row in output matrix */ + px = pDst->pData + (numColsB) * (numRowsA-1); + + pInB = pSrcBT; + col = numColsB; + i = 0U; + + /* col loop */ + while (col > 0) + { + /* point to last row in matrix A */ + pInA = pSrcA->pData + (numRowsA-1) * numColsA; + + /* Set variable sum, that acts as accumulator, to zero */ + sum = 0; + + /* Compute 4 columns at once */ + colCnt = numColsA >> 2U; + + /* matrix multiplication */ + while (colCnt > 0U) + { + inA1 = read_q15x2_ia ((q15_t **) &pInA); + inA2 = read_q15x2_ia ((q15_t **) &pInA); + inB1 = read_q15x2_ia ((q15_t **) &pInB); + inB2 = read_q15x2_ia ((q15_t **) &pInB); + + sum = __SMLAD(inA1, inB1, sum); + sum = __SMLAD(inA2, inB2, sum); + + /* Decrement loop counter */ + colCnt--; + } + + colCnt = numColsA % 4U; + while (colCnt > 0U) { + sum += (q31_t) (*pInA++) * (*pInB++); + + colCnt--; + } + + /* Store result in destination buffer */ + *px++ = (q15_t) (sum >> 15); + + /* Decrement column loop counter */ + col--; + } + } + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixMult group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_fast_q31.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_fast_q31.c new file mode 100644 index 0000000..011959a --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_fast_q31.c @@ -0,0 +1,374 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_mult_fast_q31.c + * Description: Q31 matrix multiplication (fast variant) + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixMult + @{ + */ + +/** + @brief Q31 matrix multiplication (fast variant). + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @par Scaling and Overflow Behavior + The difference between the function \ref arm_mat_mult_q31() and this fast variant is that + the fast variant use a 32-bit rather than a 64-bit accumulator. + The result of each 1.31 x 1.31 multiplication is truncated to + 2.30 format. These intermediate results are accumulated in a 32-bit register in 2.30 + format. Finally, the accumulator is saturated and converted to a 1.31 result. + @par + The fast version has the same overflow behavior as the standard version but provides + less precision since it discards the low 32 bits of each multiplication result. + In order to avoid overflows completely the input signals must be scaled down. + Scale down one of the input matrices by log2(numColsA) bits to avoid overflows, + as a total of numColsA additions are computed internally for each output element. + @remark + Refer to \ref arm_mat_mult_q31() for a slower implementation of this function + which uses 64-bit accumulation to provide higher precision. + */ + +arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst) +{ + q31_t *pInA = pSrcA->pData; /* Input data matrix pointer A */ + q31_t *pInB = pSrcB->pData; /* Input data matrix pointer B */ + q31_t *pInA2; + q31_t *px; /* Temporary output data matrix pointer */ + q31_t *px2; + q31_t sum1, sum2, sum3, sum4; /* Accumulator */ + q31_t inA1, inA2, inB1, inB2; + uint16_t numRowsA = pSrcA->numRows; /* Number of rows of input matrix A */ + uint16_t numColsB = pSrcB->numCols; /* Number of columns of input matrix B */ + uint16_t numColsA = pSrcA->numCols; /* Number of columns of input matrix A */ + uint32_t col, i = 0U, j, row = numRowsA, colCnt; /* Loop counters */ + arm_status status; /* Status of matrix multiplication */ + + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numCols != pSrcB->numRows) || + (pSrcA->numRows != pDst->numRows) || + (pSrcB->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + px = pDst->pData; + + row = row >> 1U; + px2 = px + numColsB; + + /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */ + /* row loop */ + while (row > 0U) + { + /* For every row wise process, column loop counter is to be initiated */ + col = numColsB; + + /* For every row wise process, pIn2 pointer is set to starting address of pSrcB data */ + pInB = pSrcB->pData; + + j = 0U; + + col = col >> 1U; + + /* column loop */ + while (col > 0U) + { + /* Set the variable sum, that acts as accumulator, to zero */ + sum1 = 0; + sum2 = 0; + sum3 = 0; + sum4 = 0; + + /* Initiate data pointers */ + pInA = pSrcA->pData + i; + pInB = pSrcB->pData + j; + pInA2 = pInA + numColsA; + + colCnt = numColsA; + + /* matrix multiplication */ + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + inA1 = *pInA++; + inB1 = pInB[0]; + inA2 = *pInA2++; + inB2 = pInB[1]; + pInB += numColsB; + +#if defined (ARM_MATH_DSP) + sum1 = __SMMLA(inA1, inB1, sum1); + sum2 = __SMMLA(inA1, inB2, sum2); + sum3 = __SMMLA(inA2, inB1, sum3); + sum4 = __SMMLA(inA2, inB2, sum4); +#else + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) inA1 * inB1)) >> 32); + sum2 = (q31_t) ((((q63_t) sum2 << 32) + ((q63_t) inA1 * inB2)) >> 32); + sum3 = (q31_t) ((((q63_t) sum3 << 32) + ((q63_t) inA2 * inB1)) >> 32); + sum4 = (q31_t) ((((q63_t) sum4 << 32) + ((q63_t) inA2 * inB2)) >> 32); +#endif + + /* Decrement loop counter */ + colCnt--; + } + + /* Convert the result from 2.30 to 1.31 format and store in destination buffer */ + *px++ = sum1 << 1; + *px++ = sum2 << 1; + *px2++ = sum3 << 1; + *px2++ = sum4 << 1; + + j += 2; + + /* Decrement column loop counter */ + col--; + } + + i = i + (numColsA << 1U); + px = px2 + (numColsB & 1U); + px2 = px + numColsB; + + /* Decrement row loop counter */ + row--; + } + + /* Compute any remaining odd row/column below */ + + /* Compute remaining output column */ + if (numColsB & 1U) { + + /* Avoid redundant computation of last element */ + row = numRowsA & (~1U); + + /* Point to remaining unfilled column in output matrix */ + px = pDst->pData + numColsB-1; + pInA = pSrcA->pData; + + /* row loop */ + while (row > 0) + { + + /* point to last column in matrix B */ + pInB = pSrcB->pData + numColsB-1; + + /* Set variable sum1, that acts as accumulator, to zero */ + sum1 = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 columns at a time. */ + colCnt = numColsA >> 2U; + + /* matrix multiplication */ + while (colCnt > 0U) + { +#if defined (ARM_MATH_DSP) + sum1 = __SMMLA(*pInA++, *pInB, sum1); +#else + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) *pInA++ * *pInB)) >> 32); +#endif + pInB += numColsB; + +#if defined (ARM_MATH_DSP) + sum1 = __SMMLA(*pInA++, *pInB, sum1); +#else + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) *pInA++ * *pInB)) >> 32); +#endif + pInB += numColsB; + +#if defined (ARM_MATH_DSP) + sum1 = __SMMLA(*pInA++, *pInB, sum1); +#else + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) *pInA++ * *pInB)) >> 32); +#endif + pInB += numColsB; + +#if defined (ARM_MATH_DSP) + sum1 = __SMMLA(*pInA++, *pInB, sum1); +#else + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) *pInA++ * *pInB)) >> 32); +#endif + pInB += numColsB; + + /* Decrement loop counter */ + colCnt--; + } + + /* Loop unrolling: Compute remaining column */ + colCnt = numColsA % 4U; + +#else + + /* Initialize colCnt with number of columns */ + colCnt = numColsA; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (colCnt > 0U) { +#if defined (ARM_MATH_DSP) + sum1 = __SMMLA(*pInA++, *pInB, sum1); +#else + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) *pInA++ * *pInB)) >> 32); +#endif + pInB += numColsB; + + colCnt--; + } + + /* Convert the result from 2.30 to 1.31 format and store in destination buffer */ + *px = sum1 << 1; + px += numColsB; + + /* Decrement row loop counter */ + row--; + } + } + + /* Compute remaining output row */ + if (numRowsA & 1U) { + + /* point to last row in output matrix */ + px = pDst->pData + (numColsB) * (numRowsA-1); + + col = numColsB; + i = 0U; + + /* col loop */ + while (col > 0) + { + + /* point to last row in matrix A */ + pInA = pSrcA->pData + (numRowsA-1) * numColsA; + pInB = pSrcB->pData + i; + + /* Set variable sum1, that acts as accumulator, to zero */ + sum1 = 0; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 columns at a time. */ + colCnt = numColsA >> 2U; + + /* matrix multiplication */ + while (colCnt > 0U) + { + inA1 = *pInA++; + inA2 = *pInA++; + inB1 = *pInB; + pInB += numColsB; + inB2 = *pInB; + pInB += numColsB; +#if defined (ARM_MATH_DSP) + sum1 = __SMMLA(inA1, inB1, sum1); + sum1 = __SMMLA(inA2, inB2, sum1); +#else + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) inA1 * inB1)) >> 32); + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) inA2 * inB2)) >> 32); +#endif + + inA1 = *pInA++; + inA2 = *pInA++; + inB1 = *pInB; + pInB += numColsB; + inB2 = *pInB; + pInB += numColsB; +#if defined (ARM_MATH_DSP) + sum1 = __SMMLA(inA1, inB1, sum1); + sum1 = __SMMLA(inA2, inB2, sum1); +#else + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) inA1 * inB1)) >> 32); + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) inA2 * inB2)) >> 32); +#endif + + /* Decrement loop counter */ + colCnt--; + } + + /* Loop unrolling: Compute remaining column */ + colCnt = numColsA % 4U; + +#else + + /* Initialize colCnt with number of columns */ + colCnt = numColsA; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (colCnt > 0U) { +#if defined (ARM_MATH_DSP) + sum1 = __SMMLA(*pInA++, *pInB, sum1); +#else + sum1 = (q31_t) ((((q63_t) sum1 << 32) + ((q63_t) *pInA++ * *pInB)) >> 32); +#endif + pInB += numColsB; + + colCnt--; + } + + /* Saturate and store the result in the destination buffer */ + *px++ = sum1 << 1; + i++; + + /* Decrement col loop counter */ + col--; + } + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixMult group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_q15.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_q15.c new file mode 100644 index 0000000..1d2b69c --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_q15.c @@ -0,0 +1,357 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_mult_q15.c + * Description: Q15 matrix multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixMult + @{ + */ + +/** + @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 (Unused) + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. The inputs to the + multiplications are 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. + This approach provides 33 guard bits and there is no risk of overflow. + The 34.30 result is then truncated to 34.15 format by discarding the low 15 bits + and then saturated to 1.15 format. + @par + Refer to \ref arm_mat_mult_fast_q15() for a faster but less precise version of this function. + */ + +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) +{ + q63_t sum; /* Accumulator */ + +#if defined (ARM_MATH_DSP) /* != CM0 */ + + q15_t *pSrcBT = pState; /* Input data matrix pointer for transpose */ + q15_t *pInA = pSrcA->pData; /* Input data matrix pointer A of Q15 type */ + q15_t *pInB = pSrcB->pData; /* Input data matrix pointer B of Q15 type */ + q15_t *px; /* Temporary output data matrix pointer */ + uint16_t numRowsA = pSrcA->numRows; /* Number of rows of input matrix A */ + uint16_t numColsB = pSrcB->numCols; /* Number of columns of input matrix B */ + uint16_t numColsA = pSrcA->numCols; /* Number of columns of input matrix A */ + uint16_t numRowsB = pSrcB->numRows; /* Number of rows of input matrix A */ + uint32_t col, i = 0U, row = numRowsB, colCnt; /* Loop counters */ + arm_status status; /* Status of matrix multiplication */ + + q31_t in; /* Temporary variable to hold the input value */ + q31_t inA1, inB1, inA2, inB2; + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numCols != pSrcB->numRows) || + (pSrcA->numRows != pDst->numRows) || + (pSrcB->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Matrix transpose */ + do + { + /* The pointer px is set to starting address of column being processed */ + px = pSrcBT + i; + + /* Apply loop unrolling and exchange columns with row elements */ + col = numColsB >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + while (col > 0U) + { + /* Read two elements from row */ + in = read_q15x2_ia ((q15_t **) &pInB); + + /* Unpack and store one element in destination */ +#ifndef ARM_MATH_BIG_ENDIAN + *px = (q15_t) in; +#else + *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB; + + /* Unpack and store second element in destination */ +#ifndef ARM_MATH_BIG_ENDIAN + *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#else + *px = (q15_t) in; +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB; + + /* Read two elements from row */ + in = read_q15x2_ia ((q15_t **) &pInB); + + /* Unpack and store one element in destination */ +#ifndef ARM_MATH_BIG_ENDIAN + *px = (q15_t) in; +#else + *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + px += numRowsB; + +#ifndef ARM_MATH_BIG_ENDIAN + *px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#else + *px = (q15_t) in; +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + px += numRowsB; + + /* Decrement column loop counter */ + col--; + } + + /* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + col = numColsB % 0x4U; + + while (col > 0U) + { + /* Read and store input element in destination */ + *px = *pInB++; + + /* Update pointer px to point to next row of transposed matrix */ + px += numRowsB; + + /* Decrement column loop counter */ + col--; + } + + i++; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); + + /* Reset variables for usage in following multiplication process */ + row = numRowsA; + i = 0U; + px = pDst->pData; + + /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */ + /* row loop */ + do + { + /* For every row wise process, column loop counter is to be initiated */ + col = numColsB; + + /* For every row wise process, pIn2 pointer is set to starting address of transposed pSrcB data */ + pInB = pSrcBT; + + /* column loop */ + do + { + /* Set variable sum, that acts as accumulator, to zero */ + sum = 0; + + /* Initiate pointer pInA to point to starting address of column being processed */ + pInA = pSrcA->pData + i; + + /* Apply loop unrolling and compute 2 MACs simultaneously. */ + colCnt = numColsA >> 2U; + + /* matrix multiplication */ + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + /* read real and imag values from pSrcA and pSrcB buffer */ + inA1 = read_q15x2_ia ((q15_t **) &pInA); + inB1 = read_q15x2_ia ((q15_t **) &pInB); + + inA2 = read_q15x2_ia ((q15_t **) &pInA); + inB2 = read_q15x2_ia ((q15_t **) &pInB); + + /* Multiply and Accumlates */ + sum = __SMLALD(inA1, inB1, sum); + sum = __SMLALD(inA2, inB2, sum); + + /* Decrement loop counter */ + colCnt--; + } + + /* process remaining column samples */ + colCnt = numColsA % 0x4U; + + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + sum += *pInA++ * *pInB++; + + /* Decrement loop counter */ + colCnt--; + } + + /* Saturate and store result in destination buffer */ + *px = (q15_t) (__SSAT((sum >> 15), 16)); + px++; + + /* Decrement column loop counter */ + col--; + + } while (col > 0U); + + i = i + numColsA; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); + +#else /* #if defined (ARM_MATH_DSP) */ + + q15_t *pIn1 = pSrcA->pData; /* Input data matrix pointer A */ + q15_t *pIn2 = pSrcB->pData; /* Input data matrix pointer B */ + q15_t *pInA = pSrcA->pData; /* Input data matrix pointer A of Q15 type */ + q15_t *pInB = pSrcB->pData; /* Input data matrix pointer B of Q15 type */ + q15_t *pOut = pDst->pData; /* Output data matrix pointer */ + q15_t *px; /* Temporary output data matrix pointer */ + uint16_t numColsB = pSrcB->numCols; /* Number of columns of input matrix B */ + uint16_t numColsA = pSrcA->numCols; /* Number of columns of input matrix A */ + uint16_t numRowsA = pSrcA->numRows; /* Number of rows of input matrix A */ + uint32_t col, i = 0U, row = numRowsA, colCnt; /* Loop counters */ + arm_status status; /* Status of matrix multiplication */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numCols != pSrcB->numRows) || + (pSrcA->numRows != pDst->numRows) || + (pSrcB->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */ + /* row loop */ + do + { + /* Output pointer is set to starting address of the row being processed */ + px = pOut + i; + + /* For every row wise process, column loop counter is to be initiated */ + col = numColsB; + + /* For every row wise process, pIn2 pointer is set to starting address of pSrcB data */ + pIn2 = pSrcB->pData; + + /* column loop */ + do + { + /* Set the variable sum, that acts as accumulator, to zero */ + sum = 0; + + /* Initiate pointer pIn1 to point to starting address of pSrcA */ + pIn1 = pInA; + + /* Matrix A columns number of MAC operations are to be performed */ + colCnt = numColsA; + + /* matrix multiplication */ + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + /* Perform multiply-accumulates */ + sum += (q31_t) * pIn1++ * *pIn2; + pIn2 += numColsB; + + /* Decrement loop counter */ + colCnt--; + } + + /* Convert result from 34.30 to 1.15 format and store saturated value in destination buffer */ + + /* Saturate and store result in destination buffer */ + *px++ = (q15_t) __SSAT((sum >> 15), 16); + + /* Decrement column loop counter */ + col--; + + /* Update pointer pIn2 to point to starting address of next column */ + pIn2 = pInB + (numColsB - col); + + } while (col > 0U); + + /* Update pointer pSrcA to point to starting address of next row */ + i = i + numColsB; + pInA = pInA + numColsA; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixMult group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_q31.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_q31.c new file mode 100644 index 0000000..161e723 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_mult_q31.c @@ -0,0 +1,196 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_mult_q31.c + * Description: Q31 matrix multiplication + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixMult + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @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. There is no saturation + on intermediate additions. Thus, if the accumulator overflows it wraps around and + distorts the result. The input signals should be scaled down to avoid intermediate + overflows. The input is thus scaled down by log2(numColsA) bits + to avoid overflows, as a total of numColsA additions are performed internally. + The 2.62 accumulator is right shifted by 31 bits and saturated to 1.31 format to yield the final result. + @remark + Refer to \ref arm_mat_mult_fast_q31() for a faster but less precise implementation of this function. + */ + +arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst) +{ + q31_t *pIn1 = pSrcA->pData; /* Input data matrix pointer A */ + q31_t *pIn2 = pSrcB->pData; /* Input data matrix pointer B */ + q31_t *pInA = pSrcA->pData; /* Input data matrix pointer A */ + q31_t *pInB = pSrcB->pData; /* Input data matrix pointer B */ + q31_t *pOut = pDst->pData; /* Output data matrix pointer */ + q31_t *px; /* Temporary output data matrix pointer */ + q63_t sum; /* Accumulator */ + uint16_t numRowsA = pSrcA->numRows; /* Number of rows of input matrix A */ + uint16_t numColsB = pSrcB->numCols; /* Number of columns of input matrix B */ + uint16_t numColsA = pSrcA->numCols; /* Number of columns of input matrix A */ + uint32_t col, i = 0U, row = numRowsA, colCnt; /* Loop counters */ + arm_status status; /* Status of matrix multiplication */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numCols != pSrcB->numRows) || + (pSrcA->numRows != pDst->numRows) || + (pSrcB->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */ + /* row loop */ + do + { + /* Output pointer is set to starting address of row being processed */ + px = pOut + i; + + /* For every row wise process, column loop counter is to be initiated */ + col = numColsB; + + /* For every row wise process, pIn2 pointer is set to starting address of pSrcB data */ + pIn2 = pSrcB->pData; + + /* column loop */ + do + { + /* Set the variable sum, that acts as accumulator, to zero */ + sum = 0; + + /* Initialize pointer pIn1 to point to starting address of column being processed */ + pIn1 = pInA; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 MACs at a time. */ + colCnt = numColsA >> 2U; + + /* matrix multiplication */ + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + /* Perform the multiply-accumulates */ + sum += (q63_t) *pIn1++ * *pIn2; + pIn2 += numColsB; + + sum += (q63_t) *pIn1++ * *pIn2; + pIn2 += numColsB; + + sum += (q63_t) *pIn1++ * *pIn2; + pIn2 += numColsB; + + sum += (q63_t) *pIn1++ * *pIn2; + pIn2 += numColsB; + + /* Decrement loop counter */ + colCnt--; + } + + /* Loop unrolling: Compute remaining MACs */ + colCnt = numColsA % 0x4U; + +#else + + /* Initialize cntCnt with number of columns */ + colCnt = numColsA; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (colCnt > 0U) + { + /* c(m,n) = a(1,1) * b(1,1) + a(1,2) * b(2,1) + .... + a(m,p) * b(p,n) */ + + /* Perform the multiply-accumulates */ + sum += (q63_t) *pIn1++ * *pIn2; + pIn2 += numColsB; + + /* Decrement loop counter */ + colCnt--; + } + + /* Convert result from 2.62 to 1.31 format and store in destination buffer */ + *px++ = (q31_t) (sum >> 31); + + /* Decrement column loop counter */ + col--; + + /* Update pointer pIn2 to point to starting address of next column */ + pIn2 = pInB + (numColsB - col); + + } while (col > 0U); + + /* Update pointer pInA to point to starting address of next row */ + i = i + numColsB; + pInA = pInA + numColsA; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixMult group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_f32.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_f32.c new file mode 100644 index 0000000..cbf3182 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_f32.c @@ -0,0 +1,146 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_scale_f32.c + * Description: Multiplies a floating-point matrix by a scalar + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @defgroup MatrixScale Matrix Scale + + Multiplies a matrix by a scalar. This is accomplished by multiplying each element in the + matrix by the scalar. For example: + \image html MatrixScale.gif "Matrix Scaling of a 3 x 3 matrix" + + The function checks to make sure that the input and output matrices are of the same size. + + In the fixed-point Q15 and Q31 functions, scale is represented by + a fractional multiplication scaleFract and an arithmetic shift shift. + The shift allows the gain of the scaling operation to exceed 1.0. + The overall scale factor applied to the fixed-point data is +
+      scale = scaleFract * 2^shift.
+  
+ */ + +/** + @addtogroup MatrixScale + @{ + */ + +/** + @brief Floating-point matrix scaling. + @param[in] pSrc points to input matrix + @param[in] scale scale factor to be applied + @param[out] pDst points to output matrix structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + */ + +arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst) +{ + float32_t *pIn = pSrc->pData; /* Input data matrix pointer */ + float32_t *pOut = pDst->pData; /* Output data matrix pointer */ + uint32_t numSamples; /* Total number of elements in the matrix */ + uint32_t blkCnt; /* Loop counters */ + arm_status status; /* Status of matrix scaling */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrc->numRows != pDst->numRows) || + (pSrc->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Total number of samples in input matrix */ + numSamples = (uint32_t) pSrc->numRows * pSrc->numCols; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) * scale */ + + /* Scale and store result in destination buffer. */ + *pOut++ = (*pIn++) * scale; + *pOut++ = (*pIn++) * scale; + *pOut++ = (*pIn++) * scale; + *pOut++ = (*pIn++) * scale; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) * scale */ + + /* Scale and store result in destination buffer. */ + *pOut++ = (*pIn++) * scale; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixScale group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_q15.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_q15.c new file mode 100644 index 0000000..9b75d4e --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_q15.c @@ -0,0 +1,170 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_scale_q15.c + * Description: Multiplies a Q15 matrix by a scalar + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixScale + @{ + */ + +/** + @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 structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @par Scaling and Overflow Behavior + The input data *pSrc and scaleFract are in 1.15 format. + These are multiplied to yield a 2.30 intermediate result and this is shifted with saturation to 1.15 format. + */ + +arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst) +{ + q15_t *pIn = pSrc->pData; /* Input data matrix pointer */ + q15_t *pOut = pDst->pData; /* Output data matrix pointer */ + uint32_t numSamples; /* Total number of elements in the matrix */ + uint32_t blkCnt; /* Loop counter */ + arm_status status; /* Status of matrix scaling */ + int32_t kShift = 15 - shift; /* Total shift to apply after scaling */ + +#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP) + q31_t inA1, inA2; + q31_t out1, out2, out3, out4; /* Temporary output variables */ + q15_t in1, in2, in3, in4; /* Temporary input variables */ +#endif + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrc->numRows != pDst->numRows) || + (pSrc->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Total number of samples in input matrix */ + numSamples = (uint32_t) pSrc->numRows * pSrc->numCols; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) * k */ + +#if defined (ARM_MATH_DSP) + /* read 2 times 2 samples at a time from source */ + inA1 = read_q15x2_ia ((q15_t **) &pIn); + inA2 = read_q15x2_ia ((q15_t **) &pIn); + + /* Scale inputs and store result in temporary variables + * in single cycle by packing the outputs */ + out1 = (q31_t) ((q15_t) (inA1 >> 16) * scaleFract); + out2 = (q31_t) ((q15_t) (inA1 ) * scaleFract); + out3 = (q31_t) ((q15_t) (inA2 >> 16) * scaleFract); + out4 = (q31_t) ((q15_t) (inA2 ) * scaleFract); + + /* apply shifting */ + out1 = out1 >> kShift; + out2 = out2 >> kShift; + out3 = out3 >> kShift; + out4 = out4 >> kShift; + + /* saturate the output */ + in1 = (q15_t) (__SSAT(out1, 16)); + in2 = (q15_t) (__SSAT(out2, 16)); + in3 = (q15_t) (__SSAT(out3, 16)); + in4 = (q15_t) (__SSAT(out4, 16)); + + /* store result to destination */ + write_q15x2_ia (&pOut, __PKHBT(in2, in1, 16)); + write_q15x2_ia (&pOut, __PKHBT(in4, in3, 16)); + +#else + *pOut++ = (q15_t) (__SSAT(((q31_t) (*pIn++) * scaleFract) >> kShift, 16)); + *pOut++ = (q15_t) (__SSAT(((q31_t) (*pIn++) * scaleFract) >> kShift, 16)); + *pOut++ = (q15_t) (__SSAT(((q31_t) (*pIn++) * scaleFract) >> kShift, 16)); + *pOut++ = (q15_t) (__SSAT(((q31_t) (*pIn++) * scaleFract) >> kShift, 16)); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) * k */ + + /* Scale, saturate and store result in destination buffer. */ + *pOut++ = (q15_t) (__SSAT(((q31_t) (*pIn++) * scaleFract) >> kShift, 16)); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixScale group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_q31.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_q31.c new file mode 100644 index 0000000..929b17f --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_scale_q31.c @@ -0,0 +1,164 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_scale_q31.c + * Description: Multiplies a Q31 matrix by a scalar + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixScale + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @par Scaling and Overflow Behavior + The input data *pSrc and scaleFract are in 1.31 format. + These are multiplied to yield a 2.62 intermediate result which is shifted with saturation to 1.31 format. + */ + +arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst) +{ + q31_t *pIn = pSrc->pData; /* Input data matrix pointer */ + q31_t *pOut = pDst->pData; /* Output data matrix pointer */ + uint32_t numSamples; /* Total number of elements in the matrix */ + uint32_t blkCnt; /* Loop counter */ + arm_status status; /* Status of matrix scaling */ + int32_t kShift = shift + 1; /* Shift to apply after scaling */ + q31_t in, out; /* Temporary variabels */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrc->numRows != pDst->numRows) || + (pSrc->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Total number of samples in input matrix */ + numSamples = (uint32_t) pSrc->numRows * pSrc->numCols; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) * k */ + + /* Scale, saturate and store result in destination buffer. */ + in = *pIn++; /* read four inputs from source */ + in = ((q63_t) in * scaleFract) >> 32; /* multiply input with scaler value */ + out = in << kShift; /* apply shifting */ + if (in != (out >> kShift)) /* saturate the results. */ + out = 0x7FFFFFFF ^ (in >> 31); + *pOut++ = out; /* Store result destination */ + + in = *pIn++; + in = ((q63_t) in * scaleFract) >> 32; + out = in << kShift; + if (in != (out >> kShift)) + out = 0x7FFFFFFF ^ (in >> 31); + *pOut++ = out; + + in = *pIn++; + in = ((q63_t) in * scaleFract) >> 32; + out = in << kShift; + if (in != (out >> kShift)) + out = 0x7FFFFFFF ^ (in >> 31); + *pOut++ = out; + + in = *pIn++; + in = ((q63_t) in * scaleFract) >> 32; + out = in << kShift; + if (in != (out >> kShift)) + out = 0x7FFFFFFF ^ (in >> 31); + *pOut++ = out; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) * k */ + + /* Scale, saturate and store result in destination buffer. */ + in = *pIn++; + in = ((q63_t) in * scaleFract) >> 32; + out = in << kShift; + if (in != (out >> kShift)) + out = 0x7FFFFFFF ^ (in >> 31); + *pOut++ = out; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixScale group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_f32.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_f32.c new file mode 100644 index 0000000..5341216 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_f32.c @@ -0,0 +1,143 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_sub_f32.c + * Description: Floating-point matrix subtraction + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @defgroup MatrixSub Matrix Subtraction + + Subtract two matrices. + \image html MatrixSubtraction.gif "Subraction of two 3 x 3 matrices" + + The functions check to make sure that + pSrcA, pSrcB, and pDst have the same + number of rows and columns. + */ + +/** + @addtogroup MatrixSub + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + */ + +arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst) +{ + float32_t *pInA = pSrcA->pData; /* input data matrix pointer A */ + float32_t *pInB = pSrcB->pData; /* input data matrix pointer B */ + float32_t *pOut = pDst->pData; /* output data matrix pointer */ + + uint32_t numSamples; /* total number of elements in the matrix */ + uint32_t blkCnt; /* loop counters */ + arm_status status; /* status of matrix subtraction */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numRows != pSrcB->numRows) || + (pSrcA->numCols != pSrcB->numCols) || + (pSrcA->numRows != pDst->numRows) || + (pSrcA->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Total number of samples in input matrix */ + numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) - B(m,n) */ + + /* Subtract and store result in destination buffer. */ + *pOut++ = (*pInA++) - (*pInB++); + *pOut++ = (*pInA++) - (*pInB++); + *pOut++ = (*pInA++) - (*pInB++); + *pOut++ = (*pInA++) - (*pInB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) - B(m,n) */ + + /* Subtract and store result in destination buffer. */ + *pOut++ = (*pInA++) - (*pInB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixSub group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_q15.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_q15.c new file mode 100644 index 0000000..5d5e5d0 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_q15.c @@ -0,0 +1,144 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_sub_q15.c + * Description: Q15 Matrix subtraction + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixSub + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated. + */ + +arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst) +{ + q15_t *pInA = pSrcA->pData; /* input data matrix pointer A */ + q15_t *pInB = pSrcB->pData; /* input data matrix pointer B */ + q15_t *pOut = pDst->pData; /* output data matrix pointer */ + + uint32_t numSamples; /* total number of elements in the matrix */ + uint32_t blkCnt; /* loop counters */ + arm_status status; /* status of matrix subtraction */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numRows != pSrcB->numRows) || + (pSrcA->numCols != pSrcB->numCols) || + (pSrcA->numRows != pDst->numRows) || + (pSrcA->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Total number of samples in input matrix */ + numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) - B(m,n) */ + + /* Subtract, Saturate and store result in destination buffer. */ +#if defined (ARM_MATH_DSP) + write_q15x2_ia (&pOut, __QSUB16(read_q15x2_ia ((q15_t **) &pInA), read_q15x2_ia ((q15_t **) &pInB))); + write_q15x2_ia (&pOut, __QSUB16(read_q15x2_ia ((q15_t **) &pInA), read_q15x2_ia ((q15_t **) &pInB))); +#else + *pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ - *pInB++), 16); + *pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ - *pInB++), 16); + *pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ - *pInB++), 16); + *pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ - *pInB++), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) - B(m,n) */ + + /* Subtract and store result in destination buffer. */ +#if defined (ARM_MATH_DSP) + *pOut++ = (q15_t) __QSUB16(*pInA++, *pInB++); +#else + *pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ - *pInB++), 16); +#endif + + /* Decrement loop counter */ + blkCnt--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixSub group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_q31.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_q31.c new file mode 100644 index 0000000..40d1bef --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_sub_q31.c @@ -0,0 +1,139 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_sub_q31.c + * Description: Q31 matrix subtraction + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixSub + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated. + */ + +arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst) +{ + q31_t *pInA = pSrcA->pData; /* input data matrix pointer A */ + q31_t *pInB = pSrcB->pData; /* input data matrix pointer B */ + q31_t *pOut = pDst->pData; /* output data matrix pointer */ + + uint32_t numSamples; /* total number of elements in the matrix */ + uint32_t blkCnt; /* loop counters */ + arm_status status; /* status of matrix subtraction */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrcA->numRows != pSrcB->numRows) || + (pSrcA->numCols != pSrcB->numCols) || + (pSrcA->numRows != pDst->numRows) || + (pSrcA->numCols != pDst->numCols) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Total number of samples in input matrix */ + numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = numSamples >> 2U; + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) - B(m,n) */ + + /* Subtract, saturate and then store the results in the destination buffer. */ + *pOut++ = __QSUB(*pInA++, *pInB++); + + *pOut++ = __QSUB(*pInA++, *pInB++); + + *pOut++ = __QSUB(*pInA++, *pInB++); + + *pOut++ = __QSUB(*pInA++, *pInB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = numSamples % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = numSamples; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C(m,n) = A(m,n) - B(m,n) */ + + /* Subtract, saturate and store result in destination buffer. */ + *pOut++ = __QSUB(*pInA++, *pInB++); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixSub group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_f32.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_f32.c new file mode 100644 index 0000000..b137e61 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_f32.c @@ -0,0 +1,155 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_trans_f32.c + * Description: Floating-point matrix transpose + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @defgroup MatrixTrans Matrix Transpose + + Tranposes a matrix. + + Transposing an M x N matrix flips it around the center diagonal and results in an N x M matrix. + \image html MatrixTranspose.gif "Transpose of a 3 x 3 matrix" + */ + +/** + @addtogroup MatrixTrans + @{ + */ + +/** + @brief Floating-point matrix transpose. + @param[in] pSrc points to input matrix + @param[out] pDst points to output matrix + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + */ + +arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst) +{ + float32_t *pIn = pSrc->pData; /* input data matrix pointer */ + float32_t *pOut = pDst->pData; /* output data matrix pointer */ + float32_t *px; /* Temporary output data matrix pointer */ + uint16_t nRows = pSrc->numRows; /* number of rows */ + uint16_t nCols = pSrc->numCols; /* number of columns */ + uint32_t col, row = nRows, i = 0U; /* Loop counters */ + arm_status status; /* status of matrix transpose */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrc->numRows != pDst->numCols) || + (pSrc->numCols != pDst->numRows) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Matrix transpose by exchanging the rows with columns */ + /* row loop */ + do + { + /* Pointer px is set to starting address of column being processed */ + px = pOut + i; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + col = nCols >> 2U; + + while (col > 0U) /* column loop */ + { + /* Read and store input element in destination */ + *px = *pIn++; + /* Update pointer px to point to next row of transposed matrix */ + px += nRows; + + *px = *pIn++; + px += nRows; + + *px = *pIn++; + px += nRows; + + *px = *pIn++; + px += nRows; + + /* Decrement column loop counter */ + col--; + } + + /* Loop unrolling: Compute remaining outputs */ + col = nCols % 0x4U; + +#else + + /* Initialize col with number of samples */ + col = nCols; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (col > 0U) + { + /* Read and store input element in destination */ + *px = *pIn++; + + /* Update pointer px to point to next row of transposed matrix */ + px += nRows; + + /* Decrement column loop counter */ + col--; + } + + i++; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); /* row loop end */ + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixTrans group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_q15.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_q15.c new file mode 100644 index 0000000..707e0d6 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_q15.c @@ -0,0 +1,182 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_trans_q15.c + * Description: Q15 matrix transpose + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixTrans + @{ + */ + +/** + @brief Q15 matrix transpose. + @param[in] pSrc points to input matrix + @param[out] pDst points to output matrix + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + */ + +arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst) +{ + q15_t *pIn = pSrc->pData; /* input data matrix pointer */ + q15_t *pOut = pDst->pData; /* output data matrix pointer */ + uint16_t nRows = pSrc->numRows; /* number of rows */ + uint16_t nCols = pSrc->numCols; /* number of columns */ + uint32_t col, row = nRows, i = 0U; /* Loop counters */ + arm_status status; /* status of matrix transpose */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t in; /* variable to hold temporary output */ +#endif + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrc->numRows != pDst->numCols) || + (pSrc->numCols != pDst->numRows) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Matrix transpose by exchanging the rows with columns */ + /* row loop */ + do + { + /* Pointer pOut is set to starting address of column being processed */ + pOut = pDst->pData + i; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + col = nCols >> 2U; + + while (col > 0U) /* column loop */ + { + /* Read two elements from row */ + in = read_q15x2_ia ((q15_t **) &pIn); + + /* Unpack and store one element in destination */ +#ifndef ARM_MATH_BIG_ENDIAN + *pOut = (q15_t) in; +#else + *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Update pointer pOut to point to next row of transposed matrix */ + pOut += nRows; + + /* Unpack and store second element in destination */ +#ifndef ARM_MATH_BIG_ENDIAN + *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#else + *pOut = (q15_t) in; +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Update pointer pOut to point to next row of transposed matrix */ + pOut += nRows; + + /* Read two elements from row */ + in = read_q15x2_ia ((q15_t **) &pIn); + + /* Unpack and store one element in destination */ +#ifndef ARM_MATH_BIG_ENDIAN + *pOut = (q15_t) in; +#else + *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); + +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Update pointer pOut to point to next row of transposed matrix */ + pOut += nRows; + + /* Unpack and store second element in destination */ +#ifndef ARM_MATH_BIG_ENDIAN + *pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16); +#else + *pOut = (q15_t) in; +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Update pointer pOut to point to next row of transposed matrix */ + pOut += nRows; + + /* Decrement column loop counter */ + col--; + } + + /* Loop unrolling: Compute remaining outputs */ + col = nCols % 0x4U; + +#else + + /* Initialize col with number of samples */ + col = nCols; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (col > 0U) + { + /* Read and store input element in destination */ + *pOut = *pIn++; + + /* Update pointer pOut to point to next row of transposed matrix */ + pOut += nRows; + + /* Decrement column loop counter */ + col--; + } + + i++; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); /* row loop end */ + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixTrans group + */ diff --git a/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_q31.c b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_q31.c new file mode 100644 index 0000000..5d0b5e2 --- /dev/null +++ b/platform/cmsis/DSP_Lib/MatrixFunctions/arm_mat_trans_q31.c @@ -0,0 +1,146 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mat_trans_q31.c + * Description: Q31 matrix transpose + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupMatrix + */ + +/** + @addtogroup MatrixTrans + @{ + */ + +/** + @brief Q31 matrix transpose. + @param[in] pSrc points to input matrix + @param[out] pDst points to output matrix + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed + */ + +arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst) +{ + q31_t *pIn = pSrc->pData; /* input data matrix pointer */ + q31_t *pOut = pDst->pData; /* output data matrix pointer */ + q31_t *px; /* Temporary output data matrix pointer */ + uint16_t nRows = pSrc->numRows; /* number of rows */ + uint16_t nCols = pSrc->numCols; /* number of columns */ + uint32_t col, row = nRows, i = 0U; /* Loop counters */ + arm_status status; /* status of matrix transpose */ + +#ifdef ARM_MATH_MATRIX_CHECK + + /* Check for matrix mismatch condition */ + if ((pSrc->numRows != pDst->numCols) || + (pSrc->numCols != pDst->numRows) ) + { + /* Set status as ARM_MATH_SIZE_MISMATCH */ + status = ARM_MATH_SIZE_MISMATCH; + } + else + +#endif /* #ifdef ARM_MATH_MATRIX_CHECK */ + + { + /* Matrix transpose by exchanging the rows with columns */ + /* row loop */ + do + { + /* Pointer px is set to starting address of column being processed */ + px = pOut + i; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + col = nCols >> 2U; + + while (col > 0U) /* column loop */ + { + /* Read and store input element in destination */ + *px = *pIn++; + /* Update pointer px to point to next row of transposed matrix */ + px += nRows; + + *px = *pIn++; + px += nRows; + + *px = *pIn++; + px += nRows; + + *px = *pIn++; + px += nRows; + + /* Decrement column loop counter */ + col--; + } + + /* Loop unrolling: Compute remaining outputs */ + col = nCols % 0x4U; + +#else + + /* Initialize col with number of samples */ + col = nCols; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (col > 0U) + { + /* Read and store input element in destination */ + *px = *pIn++; + + /* Update pointer px to point to next row of transposed matrix */ + px += nRows; + + /* Decrement column loop counter */ + col--; + } + + i++; + + /* Decrement row loop counter */ + row--; + + } while (row > 0U); /* row loop end */ + + /* Set status as ARM_MATH_SUCCESS */ + status = ARM_MATH_SUCCESS; + } + + /* Return to application */ + return (status); +} + +/** + @} end of MatrixTrans group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/Makefile b/platform/cmsis/DSP_Lib/StatisticsFunctions/Makefile new file mode 100644 index 0000000..88c2e8b --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/Makefile @@ -0,0 +1,6 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out %Functions.c,$(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/StatisticsFunctions.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/StatisticsFunctions.c new file mode 100644 index 0000000..4f86aa4 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/StatisticsFunctions.c @@ -0,0 +1,53 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: StatisticsFunctions.c + * Description: Combination of all statistics function source files. + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_max_f32.c" +#include "arm_max_q15.c" +#include "arm_max_q31.c" +#include "arm_max_q7.c" +#include "arm_mean_f32.c" +#include "arm_mean_q15.c" +#include "arm_mean_q31.c" +#include "arm_mean_q7.c" +#include "arm_min_f32.c" +#include "arm_min_q15.c" +#include "arm_min_q31.c" +#include "arm_min_q7.c" +#include "arm_power_f32.c" +#include "arm_power_q15.c" +#include "arm_power_q31.c" +#include "arm_power_q7.c" +#include "arm_rms_f32.c" +#include "arm_rms_q15.c" +#include "arm_rms_q31.c" +#include "arm_std_f32.c" +#include "arm_std_q15.c" +#include "arm_std_q31.c" +#include "arm_var_f32.c" +#include "arm_var_q15.c" +#include "arm_var_q31.c" diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_f32.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_f32.c new file mode 100644 index 0000000..175fa92 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_f32.c @@ -0,0 +1,156 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_max_f32.c + * Description: Maximum value of a floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @defgroup Max Maximum + + Computes the maximum value of an array of data. + The function returns both the maximum value and its position within the array. + There are separate functions for floating-point, Q31, Q15, and Q7 data types. + */ + +/** + @addtogroup Max + @{ + */ + +/** + @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 + @param[out] pIndex index of maximum value returned here + @return none + */ + +void arm_max_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex) +{ + float32_t maxVal, out; /* Temporary variables to store the output value. */ + uint32_t blkCnt, outIndex; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + uint32_t index; /* index of maximum value */ +#endif + + /* Initialise index value to zero. */ + outIndex = 0U; + /* Load first input value that act as reference value for comparision */ + out = *pSrc++; + +#if defined (ARM_MATH_LOOPUNROLL) + /* Initialise index of maximum value. */ + index = 0U; + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (blockSize - 1U) >> 2U; + + while (blkCnt > 0U) + { + /* Initialize maxVal to next consecutive values one by one */ + maxVal = *pSrc++; + + /* compare for the maximum value */ + if (out < maxVal) + { + /* Update the maximum value and it's index */ + out = maxVal; + outIndex = index + 1U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 2U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 3U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 4U; + } + + index += 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (blockSize - 1U) % 4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (blockSize - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Initialize maxVal to the next consecutive values one by one */ + maxVal = *pSrc++; + + /* compare for the maximum value */ + if (out < maxVal) + { + /* Update the maximum value and it's index */ + out = maxVal; + outIndex = blockSize - blkCnt; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store the maximum value and it's index into destination pointers */ + *pResult = out; + *pIndex = outIndex; +} + +/** + @} end of Max group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q15.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q15.c new file mode 100644 index 0000000..329b0c8 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q15.c @@ -0,0 +1,148 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_max_q15.c + * Description: Maximum value of a Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup Max + @{ + */ + +/** + @brief Maximum value of a Q15 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 + @param[out] pIndex index of maximum value returned here + @return none + */ + +void arm_max_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex) +{ + q15_t maxVal, out; /* Temporary variables to store the output value. */ + uint32_t blkCnt, outIndex; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + uint32_t index; /* index of maximum value */ +#endif + + /* Initialise index value to zero. */ + outIndex = 0U; + /* Load first input value that act as reference value for comparision */ + out = *pSrc++; + +#if defined (ARM_MATH_LOOPUNROLL) + /* Initialise index of maximum value. */ + index = 0U; + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (blockSize - 1U) >> 2U; + + while (blkCnt > 0U) + { + /* Initialize maxVal to next consecutive values one by one */ + maxVal = *pSrc++; + + /* compare for the maximum value */ + if (out < maxVal) + { + /* Update the maximum value and it's index */ + out = maxVal; + outIndex = index + 1U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 2U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 3U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 4U; + } + + index += 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (blockSize - 1U) % 4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (blockSize - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Initialize maxVal to the next consecutive values one by one */ + maxVal = *pSrc++; + + /* compare for the maximum value */ + if (out < maxVal) + { + /* Update the maximum value and it's index */ + out = maxVal; + outIndex = blockSize - blkCnt; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store the maximum value and it's index into destination pointers */ + *pResult = out; + *pIndex = outIndex; +} + +/** + @} end of Max group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q31.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q31.c new file mode 100644 index 0000000..99de13e --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q31.c @@ -0,0 +1,148 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_max_q31.c + * Description: Maximum value of a Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup Max + @{ + */ + +/** + @brief Maximum value of a Q31 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 + @param[out] pIndex index of maximum value returned here + @return none + */ + +void arm_max_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex) +{ + q31_t maxVal, out; /* Temporary variables to store the output value. */ + uint32_t blkCnt, outIndex; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + uint32_t index; /* index of maximum value */ +#endif + + /* Initialise index value to zero. */ + outIndex = 0U; + /* Load first input value that act as reference value for comparision */ + out = *pSrc++; + +#if defined (ARM_MATH_LOOPUNROLL) + /* Initialise index of maximum value. */ + index = 0U; + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (blockSize - 1U) >> 2U; + + while (blkCnt > 0U) + { + /* Initialize maxVal to next consecutive values one by one */ + maxVal = *pSrc++; + + /* compare for the maximum value */ + if (out < maxVal) + { + /* Update the maximum value and it's index */ + out = maxVal; + outIndex = index + 1U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 2U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 3U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 4U; + } + + index += 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (blockSize - 1U) % 4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (blockSize - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Initialize maxVal to the next consecutive values one by one */ + maxVal = *pSrc++; + + /* compare for the maximum value */ + if (out < maxVal) + { + /* Update the maximum value and it's index */ + out = maxVal; + outIndex = blockSize - blkCnt; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store the maximum value and it's index into destination pointers */ + *pResult = out; + *pIndex = outIndex; +} + +/** + @} end of Max group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q7.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q7.c new file mode 100644 index 0000000..9c8b6d3 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_max_q7.c @@ -0,0 +1,148 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_max_q7.c + * Description: Maximum value of a Q7 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup Max + @{ + */ + +/** + @brief Maximum value of a Q7 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 + @param[out] pIndex index of maximum value returned here + @return none + */ + +void arm_max_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex) +{ + q7_t maxVal, out; /* Temporary variables to store the output value. */ + uint32_t blkCnt, outIndex; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + uint32_t index; /* index of maximum value */ +#endif + + /* Initialise index value to zero. */ + outIndex = 0U; + /* Load first input value that act as reference value for comparision */ + out = *pSrc++; + +#if defined (ARM_MATH_LOOPUNROLL) + /* Initialise index of maximum value. */ + index = 0U; + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (blockSize - 1U) >> 2U; + + while (blkCnt > 0U) + { + /* Initialize maxVal to next consecutive values one by one */ + maxVal = *pSrc++; + + /* compare for the maximum value */ + if (out < maxVal) + { + /* Update the maximum value and it's index */ + out = maxVal; + outIndex = index + 1U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 2U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 3U; + } + + maxVal = *pSrc++; + if (out < maxVal) + { + out = maxVal; + outIndex = index + 4U; + } + + index += 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (blockSize - 1U) % 4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (blockSize - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Initialize maxVal to the next consecutive values one by one */ + maxVal = *pSrc++; + + /* compare for the maximum value */ + if (out < maxVal) + { + /* Update the maximum value and it's index */ + out = maxVal; + outIndex = blockSize - blkCnt; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store the maximum value and it's index into destination pointers */ + *pResult = out; + *pIndex = outIndex; +} + +/** + @} end of Max group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_f32.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_f32.c new file mode 100644 index 0000000..11389c0 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_f32.c @@ -0,0 +1,115 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mean_f32.c + * Description: Mean value of a floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @defgroup mean Mean + + Calculates the mean of the input vector. Mean is defined as the average of the elements in the vector. + The underlying algorithm is used: + +
+      Result = (pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]) / blockSize;
+  
+ + There are separate functions for floating-point, Q31, Q15, and Q7 data types. + */ + +/** + @addtogroup mean + @{ + */ + +/** + @brief Mean 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 mean value returned here. + @return none + */ + +void arm_mean_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t sum = 0.0f; /* Temporary result storage */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + sum += *pSrc++; + + sum += *pSrc++; + + sum += *pSrc++; + + sum += *pSrc++; + + /* Decrement the loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + sum += *pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */ + /* Store result to destination */ + *pResult = (sum / blockSize); +} + +/** + @} end of mean group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q15.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q15.c new file mode 100644 index 0000000..463aa84 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q15.c @@ -0,0 +1,114 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mean_q15.c + * Description: Mean value of a Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup mean + @{ + */ + +/** + @brief Mean value of a Q15 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult mean value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 32-bit internal accumulator. + The input is represented in 1.15 format and is accumulated in a 32-bit + accumulator in 17.15 format. + There is no risk of internal overflow with this approach, and the + full precision of intermediate result is preserved. + Finally, the accumulator is truncated to yield a result of 1.15 format. + */ + +void arm_mean_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t sum = 0; /* Temporary result storage */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t in; +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + in = read_q15x2_ia ((q15_t **) &pSrc); + sum += ((in << 16U) >> 16U); + sum += (in >> 16U); + + in = read_q15x2_ia ((q15_t **) &pSrc); + sum += ((in << 16U) >> 16U); + sum += (in >> 16U); + + /* Decrement the loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + sum += *pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */ + /* Store result to destination */ + *pResult = (q15_t) (sum / (int32_t) blockSize); +} + +/** + @} end of mean group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q31.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q31.c new file mode 100644 index 0000000..4b0ed6e --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q31.c @@ -0,0 +1,110 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mean_q31.c + * Description: Mean value of a Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup mean + @{ + */ + +/** + @brief Mean value of a Q31 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult mean value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + The input is represented in 1.31 format and is accumulated in a 64-bit + accumulator in 33.31 format. + There is no risk of internal overflow with this approach, and the + full precision of intermediate result is preserved. + Finally, the accumulator is truncated to yield a result of 1.31 format. + */ + +void arm_mean_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q63_t sum = 0; /* Temporary result storage */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + sum += *pSrc++; + + sum += *pSrc++; + + sum += *pSrc++; + + sum += *pSrc++; + + /* Decrement the loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + sum += *pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */ + /* Store result to destination */ + *pResult = (q31_t) (sum / blockSize); +} + +/** + @} end of mean group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q7.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q7.c new file mode 100644 index 0000000..8f52211 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_mean_q7.c @@ -0,0 +1,112 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mean_q7.c + * Description: Mean value of a Q7 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup mean + @{ + */ + +/** + @brief Mean value of a Q7 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult mean value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 32-bit internal accumulator. + The input is represented in 1.7 format and is accumulated in a 32-bit + accumulator in 25.7 format. + There is no risk of internal overflow with this approach, and the + full precision of intermediate result is preserved. + Finally, the accumulator is truncated to yield a result of 1.7 format. + */ + +void arm_mean_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t sum = 0; /* Temporary result storage */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t in; +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + in = read_q7x4_ia ((q7_t **) &pSrc); + sum += ((in << 24U) >> 24U); + sum += ((in << 16U) >> 24U); + sum += ((in << 8U) >> 24U); + sum += (in >> 24U); + + /* Decrement the loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + sum += *pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */ + /* Store result to destination */ + *pResult = (q7_t) (sum / (int32_t) blockSize); +} + +/** + @} end of mean group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_f32.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_f32.c new file mode 100644 index 0000000..6daec0e --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_f32.c @@ -0,0 +1,156 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_min_f32.c + * Description: Minimum value of a floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @defgroup Min Minimum + + Computes the minimum value of an array of data. + The function returns both the minimum value and its position within the array. + There are separate functions for floating-point, Q31, Q15, and Q7 data types. + */ + +/** + @addtogroup Min + @{ + */ + +/** + @brief Minimum 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 minimum value returned here + @param[out] pIndex index of minimum value returned here + @return none + */ + +void arm_min_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex) +{ + float32_t minVal, out; /* Temporary variables to store the output value. */ + uint32_t blkCnt, outIndex; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + uint32_t index; /* index of maximum value */ +#endif + + /* Initialise index value to zero. */ + outIndex = 0U; + /* Load first input value that act as reference value for comparision */ + out = *pSrc++; + +#if defined (ARM_MATH_LOOPUNROLL) + /* Initialise index of maximum value. */ + index = 0U; + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (blockSize - 1U) >> 2U; + + while (blkCnt > 0U) + { + /* Initialize minVal to next consecutive values one by one */ + minVal = *pSrc++; + + /* compare for the minimum value */ + if (out > minVal) + { + /* Update the minimum value and it's index */ + out = minVal; + outIndex = index + 1U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 2U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 3U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 4U; + } + + index += 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (blockSize - 1U) % 4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (blockSize - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Initialize minVal to the next consecutive values one by one */ + minVal = *pSrc++; + + /* compare for the minimum value */ + if (out > minVal) + { + /* Update the minimum value and it's index */ + out = minVal; + outIndex = blockSize - blkCnt; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store the minimum value and it's index into destination pointers */ + *pResult = out; + *pIndex = outIndex; +} + +/** + @} end of Min group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q15.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q15.c new file mode 100644 index 0000000..9450383 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q15.c @@ -0,0 +1,149 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_min_q15.c + * Description: Minimum value of a Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + + +/** + @addtogroup Min + @{ + */ + +/** + @brief Minimum value of a Q15 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult minimum value returned here + @param[out] pIndex index of minimum value returned here + @return none + */ + +void arm_min_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex) +{ + q15_t minVal, out; /* Temporary variables to store the output value. */ + uint32_t blkCnt, outIndex; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + uint32_t index; /* index of maximum value */ +#endif + + /* Initialise index value to zero. */ + outIndex = 0U; + /* Load first input value that act as reference value for comparision */ + out = *pSrc++; + +#if defined (ARM_MATH_LOOPUNROLL) + /* Initialise index of maximum value. */ + index = 0U; + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (blockSize - 1U) >> 2U; + + while (blkCnt > 0U) + { + /* Initialize minVal to next consecutive values one by one */ + minVal = *pSrc++; + + /* compare for the minimum value */ + if (out > minVal) + { + /* Update the minimum value and it's index */ + out = minVal; + outIndex = index + 1U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 2U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 3U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 4U; + } + + index += 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (blockSize - 1U) % 4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (blockSize - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Initialize minVal to the next consecutive values one by one */ + minVal = *pSrc++; + + /* compare for the minimum value */ + if (out > minVal) + { + /* Update the minimum value and it's index */ + out = minVal; + outIndex = blockSize - blkCnt; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store the minimum value and it's index into destination pointers */ + *pResult = out; + *pIndex = outIndex; +} + +/** + @} end of Min group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q31.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q31.c new file mode 100644 index 0000000..e25eb47 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q31.c @@ -0,0 +1,149 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_min_q31.c + * Description: Minimum value of a Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + + +/** + @addtogroup Min + @{ + */ + +/** + @brief Minimum value of a Q31 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult minimum value returned here + @param[out] pIndex index of minimum value returned here + @return none + */ + +void arm_min_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex) +{ + q31_t minVal, out; /* Temporary variables to store the output value. */ + uint32_t blkCnt, outIndex; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + uint32_t index; /* index of maximum value */ +#endif + + /* Initialise index value to zero. */ + outIndex = 0U; + /* Load first input value that act as reference value for comparision */ + out = *pSrc++; + +#if defined (ARM_MATH_LOOPUNROLL) + /* Initialise index of maximum value. */ + index = 0U; + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (blockSize - 1U) >> 2U; + + while (blkCnt > 0U) + { + /* Initialize minVal to next consecutive values one by one */ + minVal = *pSrc++; + + /* compare for the minimum value */ + if (out > minVal) + { + /* Update the minimum value and it's index */ + out = minVal; + outIndex = index + 1U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 2U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 3U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 4U; + } + + index += 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (blockSize - 1U) % 4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (blockSize - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Initialize minVal to the next consecutive values one by one */ + minVal = *pSrc++; + + /* compare for the minimum value */ + if (out > minVal) + { + /* Update the minimum value and it's index */ + out = minVal; + outIndex = blockSize - blkCnt; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store the minimum value and it's index into destination pointers */ + *pResult = out; + *pIndex = outIndex; +} + +/** + @} end of Min group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q7.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q7.c new file mode 100644 index 0000000..2b171f0 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_min_q7.c @@ -0,0 +1,149 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_min_q7.c + * Description: Minimum value of a Q7 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + + +/** + @addtogroup Min + @{ + */ + +/** + @brief Minimum value of a Q7 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult minimum value returned here + @param[out] pIndex index of minimum value returned here + @return none + */ + +void arm_min_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex) +{ + q7_t minVal, out; /* Temporary variables to store the output value. */ + uint32_t blkCnt, outIndex; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + uint32_t index; /* index of maximum value */ +#endif + + /* Initialise index value to zero. */ + outIndex = 0U; + /* Load first input value that act as reference value for comparision */ + out = *pSrc++; + +#if defined (ARM_MATH_LOOPUNROLL) + /* Initialise index of maximum value. */ + index = 0U; + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = (blockSize - 1U) >> 2U; + + while (blkCnt > 0U) + { + /* Initialize minVal to next consecutive values one by one */ + minVal = *pSrc++; + + /* compare for the minimum value */ + if (out > minVal) + { + /* Update the minimum value and it's index */ + out = minVal; + outIndex = index + 1U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 2U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 3U; + } + + minVal = *pSrc++; + if (out > minVal) + { + out = minVal; + outIndex = index + 4U; + } + + index += 4U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = (blockSize - 1U) % 4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = (blockSize - 1U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* Initialize minVal to the next consecutive values one by one */ + minVal = *pSrc++; + + /* compare for the minimum value */ + if (out > minVal) + { + /* Update the minimum value and it's index */ + out = minVal; + outIndex = blockSize - blkCnt; + } + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store the minimum value and it's index into destination pointers */ + *pResult = out; + *pIndex = outIndex; +} + +/** + @} end of Min group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_f32.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_f32.c new file mode 100644 index 0000000..ad32211 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_f32.c @@ -0,0 +1,124 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_power_f32.c + * Description: Sum of the squares of the elements of a floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @defgroup power Power + + Calculates the sum of the squares of the elements in the input vector. + The underlying algorithm is used: + +
+      Result = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + pSrc[2] * pSrc[2] + ... + pSrc[blockSize-1] * pSrc[blockSize-1];
+  
+ + There are separate functions for floating point, Q31, Q15, and Q7 data types. + */ + +/** + @addtogroup power + @{ + */ + +/** + @brief Sum of the squares of the elements 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 sum of the squares value returned here + @return none + */ + +void arm_power_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t sum = 0.0f; /* Temporary result storage */ + float32_t in; /* Temporary variable to store input value */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + /* Compute Power and store result in a temporary variable, sum. */ + in = *pSrc++; + sum += in * in; + + in = *pSrc++; + sum += in * in; + + in = *pSrc++; + sum += in * in; + + in = *pSrc++; + sum += in * in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + /* Compute Power and store result in a temporary variable, sum. */ + in = *pSrc++; + sum += in * in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store result to destination */ + *pResult = sum; +} + +/** + @} end of power group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q15.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q15.c new file mode 100644 index 0000000..12f524d --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q15.c @@ -0,0 +1,132 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_power_q15.c + * Description: Sum of the squares of the elements of a Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup power + @{ + */ + +/** + @brief Sum of the squares of the elements of a Q15 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult sum of the squares value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + The input is represented in 1.15 format. + Intermediate multiplication yields a 2.30 format, and this + result is added without saturation to a 64-bit accumulator in 34.30 format. + With 33 guard bits in the accumulator, there is no risk of overflow, and the + full precision of the intermediate multiplication is preserved. + Finally, the return result is in 34.30 format. + */ + +void arm_power_q15( + const q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q63_t sum = 0; /* Temporary result storage */ + q15_t in; /* Temporary variable to store input value */ + +#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP) + q31_t in32; /* Temporary variable to store packed input value */ +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + /* Compute Power and store result in a temporary variable, sum. */ +#if defined (ARM_MATH_DSP) + in32 = read_q15x2_ia ((q15_t **) &pSrc); + sum = __SMLALD(in32, in32, sum); + + in32 = read_q15x2_ia ((q15_t **) &pSrc); + sum = __SMLALD(in32, in32, sum); +#else + in = *pSrc++; + sum += ((q31_t) in * in); + + in = *pSrc++; + sum += ((q31_t) in * in); + + in = *pSrc++; + sum += ((q31_t) in * in); + + in = *pSrc++; + sum += ((q31_t) in * in); +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + /* Compute Power and store result in a temporary variable, sum. */ + in = *pSrc++; + sum += ((q31_t) in * in); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store result in 34.30 format */ + *pResult = sum; +} + +/** + @} end of power group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q31.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q31.c new file mode 100644 index 0000000..1e193b3 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q31.c @@ -0,0 +1,121 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_power_q31.c + * Description: Sum of the squares of the elements of a Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup power + @{ + */ + +/** + @brief Sum of the squares of the elements of a Q31 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult sum of the squares value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + The input is represented in 1.31 format. + Intermediate multiplication yields a 2.62 format, and this + result is truncated to 2.48 format by discarding the lower 14 bits. + The 2.48 result is then added without saturation to a 64-bit accumulator in 16.48 format. + With 15 guard bits in the accumulator, there is no risk of overflow, and the + full precision of the intermediate multiplication is preserved. + Finally, the return result is in 16.48 format. + */ + +void arm_power_q31( + const q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q63_t sum = 0; /* Temporary result storage */ + q31_t in; /* Temporary variable to store input value */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + /* Compute Power then shift intermediate results by 14 bits to maintain 16.48 format and store result in a temporary variable sum, providing 15 guard bits. */ + in = *pSrc++; + sum += ((q63_t) in * in) >> 14U; + + in = *pSrc++; + sum += ((q63_t) in * in) >> 14U; + + in = *pSrc++; + sum += ((q63_t) in * in) >> 14U; + + in = *pSrc++; + sum += ((q63_t) in * in) >> 14U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + /* Compute Power and store result in a temporary variable, sum. */ + in = *pSrc++; + sum += ((q63_t) in * in) >> 14U; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store results in 16.48 format */ + *pResult = sum; +} + +/** + @} end of power group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q7.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q7.c new file mode 100644 index 0000000..47405cd --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_power_q7.c @@ -0,0 +1,136 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_power_q7.c + * Description: Sum of the squares of the elements of a Q7 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup power + @{ + */ + +/** + @brief Sum of the squares of the elements of a Q7 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult sum of the squares value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 32-bit internal accumulator. + The input is represented in 1.7 format. + Intermediate multiplication yields a 2.14 format, and this + result is added without saturation to an accumulator in 18.14 format. + With 17 guard bits in the accumulator, there is no risk of overflow, and the + full precision of the intermediate multiplication is preserved. + Finally, the return result is in 18.14 format. + */ + +void arm_power_q7( + const q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t sum = 0; /* Temporary result storage */ + q7_t in; /* Temporary variable to store input value */ + +#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP) + q31_t in32; /* Temporary variable to store packed input value */ + q31_t in1, in2; /* Temporary variables to store input value */ +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + /* Compute Power and store result in a temporary variable, sum. */ +#if defined (ARM_MATH_DSP) + in32 = read_q7x4_ia ((q7_t **) &pSrc); + + in1 = __SXTB16(__ROR(in32, 8)); + in2 = __SXTB16(in32); + + /* calculate power and accumulate to accumulator */ + sum = __SMLAD(in1, in1, sum); + sum = __SMLAD(in2, in2, sum); +#else + in = *pSrc++; + sum += ((q15_t) in * in); + + in = *pSrc++; + sum += ((q15_t) in * in); + + in = *pSrc++; + sum += ((q15_t) in * in); + + in = *pSrc++; + sum += ((q15_t) in * in); +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + /* Compute Power and store result in a temporary variable, sum. */ + in = *pSrc++; + sum += ((q15_t) in * in); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Store result in 18.14 format */ + *pResult = sum; +} + +/** + @} end of power group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_f32.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_f32.c new file mode 100644 index 0000000..68f7868 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_f32.c @@ -0,0 +1,124 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_rms_f32.c + * Description: Root mean square value of the elements of a floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @defgroup RMS Root mean square (RMS) + + Calculates the Root Mean Square of the elements in the input vector. + The underlying algorithm is used: + +
+      Result = sqrt(((pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]) / blockSize));
+  
+ + There are separate functions for floating point, Q31, and Q15 data types. + */ + +/** + @addtogroup RMS + @{ + */ + +/** + @brief Root Mean Square of the elements 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 root mean square value returned here + @return none + */ + +void arm_rms_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t sum = 0.0f; /* Temporary result storage */ + float32_t in; /* Temporary variable to store input value */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + in = *pSrc++; + /* Compute sum of squares and store result in a temporary variable, sum. */ + sum += in * in; + + in = *pSrc++; + sum += in * in; + + in = *pSrc++; + sum += in * in; + + in = *pSrc++; + sum += in * in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + in = *pSrc++; + /* Compute sum of squares and store result in a temporary variable. */ + sum += ( in * in); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Compute Rms and store result in destination */ + arm_sqrt_f32(sum / (float32_t) blockSize, pResult); +} + +/** + @} end of RMS group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_q15.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_q15.c new file mode 100644 index 0000000..9fcd964 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_q15.c @@ -0,0 +1,134 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_rms_q15.c + * Description: Root Mean Square of the elements of a Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup RMS + @{ + */ + +/** + @brief Root Mean Square of the elements of a Q15 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult root mean square value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + The input is represented in 1.15 format. + Intermediate multiplication yields a 2.30 format, and this + result is added without saturation to a 64-bit accumulator in 34.30 format. + With 33 guard bits in the accumulator, there is no risk of overflow, and the + full precision of the intermediate multiplication is preserved. + Finally, the 34.30 result is truncated to 34.15 format by discarding the lower + 15 bits, and then saturated to yield a result in 1.15 format. + */ + +void arm_rms_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q63_t sum = 0; /* Temporary result storage */ + q15_t in; /* Temporary variable to store input value */ + +#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP) + q31_t in32; /* Temporary variable to store input value */ +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + /* Compute sum of squares and store result in a temporary variable. */ +#if defined (ARM_MATH_DSP) + in32 = read_q15x2_ia ((q15_t **) &pSrc); + sum = __SMLALD(in32, in32, sum); + + in32 = read_q15x2_ia ((q15_t **) &pSrc); + sum = __SMLALD(in32, in32, sum); +#else + in = *pSrc++; + sum += ((q31_t) in * in); + + in = *pSrc++; + sum += ((q31_t) in * in); + + in = *pSrc++; + sum += ((q31_t) in * in); + + in = *pSrc++; + sum += ((q31_t) in * in); +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + in = *pSrc++; + /* Compute sum of squares and store result in a temporary variable. */ + sum += ((q31_t) in * in); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Truncating and saturating the accumulator to 1.15 format */ + /* Store result in destination */ + arm_sqrt_q15(__SSAT((sum / (q63_t)blockSize) >> 15, 16), pResult); +} + +/** + @} end of RMS group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_q31.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_q31.c new file mode 100644 index 0000000..5a3e8f3 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_rms_q31.c @@ -0,0 +1,124 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_rms_q31.c + * Description: Root Mean Square of the elements of a Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup RMS + @{ + */ + +/** + @brief Root Mean Square of the elements of a Q31 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult root mean square value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + The input is represented in 1.31 format, and intermediate multiplication + yields a 2.62 format. + The accumulator maintains full precision of the intermediate multiplication results, + but provides only a single guard bit. + There is no saturation on intermediate additions. + If the accumulator overflows, it wraps around and distorts the result. + In order to avoid overflows completely, the input signal must be scaled down by + log2(blockSize) bits, as a total of blockSize additions are performed internally. + Finally, the 2.62 accumulator is right shifted by 31 bits to yield a 1.31 format value. + */ + +void arm_rms_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + uint64_t sum = 0; /* Temporary result storage (can get never negative. changed type from q63 to uint64 */ + q31_t in; /* Temporary variable to store input value */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + in = *pSrc++; + /* Compute sum of squares and store result in a temporary variable, sum. */ + sum += ((q63_t) in * in); + + in = *pSrc++; + sum += ((q63_t) in * in); + + in = *pSrc++; + sum += ((q63_t) in * in); + + in = *pSrc++; + sum += ((q63_t) in * in); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + + in = *pSrc++; + /* Compute sum of squares and store result in a temporary variable. */ + sum += ((q63_t) in * in); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Convert data in 2.62 to 1.31 by 31 right shifts and saturate */ + /* Compute Rms and store result in destination vector */ + arm_sqrt_q31(clip_q63_to_q31((sum / (q63_t) blockSize) >> 31), pResult); +} + +/** + @} end of RMS group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_f32.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_f32.c new file mode 100644 index 0000000..041d1f4 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_f32.c @@ -0,0 +1,176 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_std_f32.c + * Description: Standard deviation of the elements of a floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @defgroup STD Standard deviation + + Calculates the standard deviation of the elements in the input vector. + The underlying algorithm is used: + +
+      Result = sqrt((sumOfSquares - sum2 / blockSize) / (blockSize - 1))
+
+      sumOfSquares = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]
+      sum = pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]
+  
+ + There are separate functions for floating point, Q31, and Q15 data types. + */ + +/** + @addtogroup STD + @{ + */ + +/** + @brief Standard deviation of the elements 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 standard deviation value returned here + @return none + */ + +void arm_std_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t sum = 0.0f; /* Temporary result storage */ + float32_t sumOfSquares = 0.0f; /* Sum of squares */ + float32_t in; /* Temporary variable to store input value */ + +#ifndef ARM_MATH_CM0_FAMILY + float32_t meanOfSquares, mean, squareOfMean; /* Temporary variables */ +#else + float32_t squareOfSum; /* Square of Sum */ + float32_t var; /* Temporary varaince storage */ +#endif + + if (blockSize <= 1U) + { + *pResult = 0; + return; + } + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + /* C = A[0] + A[1] + ... + A[blockSize-1] */ + + in = *pSrc++; + /* Compute sum of squares and store result in a temporary variable, sumOfSquares. */ + sumOfSquares += in * in; + /* Compute sum and store result in a temporary variable, sum. */ + sum += in; + + in = *pSrc++; + sumOfSquares += in * in; + sum += in; + + in = *pSrc++; + sumOfSquares += in * in; + sum += in; + + in = *pSrc++; + sumOfSquares += in * in; + sum += in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + /* C = A[0] + A[1] + ... + A[blockSize-1] */ + + in = *pSrc++; + /* Compute sum of squares and store result in a temporary variable, sumOfSquares. */ + sumOfSquares += ( in * in); + /* Compute sum and store result in a temporary variable, sum. */ + sum += in; + + /* Decrement loop counter */ + blkCnt--; + } + +#ifndef ARM_MATH_CM0_FAMILY + + /* Compute Mean of squares and store result in a temporary variable, meanOfSquares. */ + meanOfSquares = sumOfSquares / ((float32_t) blockSize - 1.0f); + + /* Compute mean of all input values */ + mean = sum / (float32_t) blockSize; + + /* Compute square of mean */ + squareOfMean = (mean * mean) * (((float32_t) blockSize) / + ((float32_t) blockSize - 1.0f)); + + /* Compute standard deviation and store result to destination */ + arm_sqrt_f32((meanOfSquares - squareOfMean), pResult); + +#else + + /* Compute square of sum */ + squareOfSum = ((sum * sum) / (float32_t) blockSize); + + /* Compute variance */ + var = ((sumOfSquares - squareOfSum) / (float32_t) (blockSize - 1.0f)); + + /* Compute standard deviation and store result in destination */ + arm_sqrt_f32(var, pResult); + +#endif /* #ifndef ARM_MATH_CM0_FAMILY */ + +} + +/** + @} end of STD group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_q15.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_q15.c new file mode 100644 index 0000000..8e5c042 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_q15.c @@ -0,0 +1,161 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_std_q15.c + * Description: Standard deviation of an array of Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup STD + @{ + */ + +/** + @brief Standard deviation of the elements of a Q15 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult standard deviation value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + The input is represented in 1.15 format. + Intermediate multiplication yields a 2.30 format, and this + result is added without saturation to a 64-bit accumulator in 34.30 format. + With 33 guard bits in the accumulator, there is no risk of overflow, and the + full precision of the intermediate multiplication is preserved. + Finally, the 34.30 result is truncated to 34.15 format by discarding the lower + 15 bits, and then saturated to yield a result in 1.15 format. + */ + +void arm_std_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t sum = 0; /* Accumulator */ + q31_t meanOfSquares, squareOfMean; /* Square of mean and mean of square */ + q63_t sumOfSquares = 0; /* Sum of squares */ + q15_t in; /* Temporary variable to store input value */ + +#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP) + q31_t in32; /* Temporary variable to store input value */ +#endif + + if (blockSize <= 1U) + { + *pResult = 0; + return; + } + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + /* C = A[0] + A[1] + ... + A[blockSize-1] */ + + /* Compute sum of squares and store result in a temporary variable, sumOfSquares. */ + /* Compute sum and store result in a temporary variable, sum. */ +#if defined (ARM_MATH_DSP) + in32 = read_q15x2_ia ((q15_t **) &pSrc); + sumOfSquares = __SMLALD(in32, in32, sumOfSquares); + sum += ((in32 << 16U) >> 16U); + sum += (in32 >> 16U); + + in32 = read_q15x2_ia ((q15_t **) &pSrc); + sumOfSquares = __SMLALD(in32, in32, sumOfSquares); + sum += ((in32 << 16U) >> 16U); + sum += (in32 >> 16U); +#else + in = *pSrc++; + sumOfSquares += (in * in); + sum += in; + + in = *pSrc++; + sumOfSquares += (in * in); + sum += in; + + in = *pSrc++; + sumOfSquares += (in * in); + sum += in; + + in = *pSrc++; + sumOfSquares += (in * in); + sum += in; +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + /* C = A[0] + A[1] + ... + A[blockSize-1] */ + + in = *pSrc++; + /* Compute sum of squares and store result in a temporary variable, sumOfSquares. */ + sumOfSquares += (in * in); + /* Compute sum and store result in a temporary variable, sum. */ + sum += in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Compute Mean of squares and store result in a temporary variable, meanOfSquares. */ + meanOfSquares = (q31_t) (sumOfSquares / (q63_t)(blockSize - 1U)); + + /* Compute square of mean */ + squareOfMean = (q31_t) ((q63_t) sum * sum / (q63_t)(blockSize * (blockSize - 1U))); + + /* mean of squares minus the square of mean. */ + /* Compute standard deviation and store result in destination */ + arm_sqrt_q15(__SSAT((meanOfSquares - squareOfMean) >> 15U, 16U), pResult); +} + +/** + @} end of STD group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_q31.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_q31.c new file mode 100644 index 0000000..cfb6cb8 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_std_q31.c @@ -0,0 +1,147 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_std_q31.c + * Description: Standard deviation of the elements of a Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup STD + @{ + */ + +/** + @brief Standard deviation of the elements of a Q31 vector. + @param[in] pSrc points to the input vector. + @param[in] blockSize number of samples in input vector. + @param[out] pResult standard deviation value returned here. + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + The input is represented in 1.31 format, which is then downshifted by 8 bits + which yields 1.23, and intermediate multiplication yields a 2.46 format. + The accumulator maintains full precision of the intermediate multiplication results, + but provides only a 16 guard bits. + There is no saturation on intermediate additions. + If the accumulator overflows it wraps around and distorts the result. + In order to avoid overflows completely the input signal must be scaled down by + log2(blockSize)-8 bits, as a total of blockSize additions are performed internally. + After division, internal variables should be Q18.46 + Finally, the 18.46 accumulator is right shifted by 15 bits to yield a 1.31 format value. + */ + +void arm_std_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q63_t sum = 0; /* Accumulator */ + q63_t meanOfSquares, squareOfMean; /* Square of mean and mean of square */ + q63_t sumOfSquares = 0; /* Sum of squares */ + q31_t in; /* Temporary variable to store input value */ + + if (blockSize <= 1U) + { + *pResult = 0; + return; + } + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + /* C = A[0] + A[1] + ... + A[blockSize-1] */ + + in = *pSrc++ >> 8U; + /* Compute sum of squares and store result in a temporary variable, sumOfSquares. */ + sumOfSquares += ((q63_t) (in) * (in)); + /* Compute sum and store result in a temporary variable, sum. */ + sum += in; + + in = *pSrc++ >> 8U; + sumOfSquares += ((q63_t) (in) * (in)); + sum += in; + + in = *pSrc++ >> 8U; + sumOfSquares += ((q63_t) (in) * (in)); + sum += in; + + in = *pSrc++ >> 8U; + sumOfSquares += ((q63_t) (in) * (in)); + sum += in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + /* C = A[0] + A[1] + ... + A[blockSize-1] */ + + in = *pSrc++ >> 8U; + /* Compute sum of squares and store result in a temporary variable, sumOfSquares. */ + sumOfSquares += ((q63_t) (in) * (in)); + /* Compute sum and store result in a temporary variable, sum. */ + sum += in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Compute Mean of squares and store result in a temporary variable, meanOfSquares. */ + meanOfSquares = (sumOfSquares / (q63_t)(blockSize - 1U)); + + /* Compute square of mean */ + squareOfMean = ( sum * sum / (q63_t)(blockSize * (blockSize - 1U))); + + /* Compute standard deviation and store result in destination */ + arm_sqrt_q31((meanOfSquares - squareOfMean) >> 15U, pResult); +} + +/** + @} end of STD group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_f32.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_f32.c new file mode 100644 index 0000000..f545d92 --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_f32.c @@ -0,0 +1,172 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_var_f32.c + * Description: Variance of the elements of a floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @defgroup variance Variance + + Calculates the variance of the elements in the input vector. + The underlying algorithm used is the direct method sometimes referred to as the two-pass method: + +
+      Result = sum(element - meanOfElements)^2) / numElement - 1
+
+      meanOfElements = ( pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] ) / blockSize
+  
+ + There are separate functions for floating point, Q31, and Q15 data types. + */ + +/** + @addtogroup variance + @{ + */ + +/** + @brief Variance of the elements 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 variance value returned here + @return none + */ + +void arm_var_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + float32_t sum = 0.0f; /* Temporary result storage */ + float32_t fSum = 0.0f; + float32_t fMean, fValue; + const float32_t * pInput = pSrc; + + if (blockSize <= 1U) + { + *pResult = 0; + return; + } + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + + sum += *pInput++; + sum += *pInput++; + sum += *pInput++; + sum += *pInput++; + + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + + sum += *pInput++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */ + fMean = sum / (float32_t) blockSize; + + pInput = pSrc; + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + fValue = *pInput++ - fMean; + fSum += fValue * fValue; + + fValue = *pInput++ - fMean; + fSum += fValue * fValue; + + fValue = *pInput++ - fMean; + fSum += fValue * fValue; + + fValue = *pInput++ - fMean; + fSum += fValue * fValue; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + fValue = *pInput++ - fMean; + fSum += fValue * fValue; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Variance */ + *pResult = fSum / (float32_t)(blockSize - 1.0f); +} + +/** + @} end of variance group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_q15.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_q15.c new file mode 100644 index 0000000..259e76b --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_q15.c @@ -0,0 +1,164 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_var_q15.c + * Description: Variance of an array of Q15 type + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup variance + @{ + */ + +/** + @brief Variance of the elements of a Q15 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult variance value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + The input is represented in 1.15 format. + Intermediate multiplication yields a 2.30 format, and this + result is added without saturation to a 64-bit accumulator in 34.30 format. + With 33 guard bits in the accumulator, there is no risk of overflow, and the + full precision of the intermediate multiplication is preserved. + Finally, the 34.30 result is truncated to 34.15 format by discarding the lower + 15 bits, and then saturated to yield a result in 1.15 format. + */ + +void arm_var_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q31_t sum = 0; /* Accumulator */ + q31_t meanOfSquares, squareOfMean; /* Square of mean and mean of square */ + q63_t sumOfSquares = 0; /* Sum of squares */ + q15_t in; /* Temporary variable to store input value */ + +#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP) + q31_t in32; /* Temporary variable to store input value */ +#endif + + if (blockSize <= 1U) + { + *pResult = 0; + return; + } + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + /* C = A[0] + A[1] + ... + A[blockSize-1] */ + + /* Compute sum of squares and store result in a temporary variable, sumOfSquares. */ + /* Compute sum and store result in a temporary variable, sum. */ +#if defined (ARM_MATH_DSP) + in32 = read_q15x2_ia ((q15_t **) &pSrc); + sumOfSquares = __SMLALD(in32, in32, sumOfSquares); + sum += ((in32 << 16U) >> 16U); + sum += (in32 >> 16U); + + in32 = read_q15x2_ia ((q15_t **) &pSrc); + sumOfSquares = __SMLALD(in32, in32, sumOfSquares); + sum += ((in32 << 16U) >> 16U); + sum += (in32 >> 16U); +#else + in = *pSrc++; + sumOfSquares += (in * in); + sum += in; + + in = *pSrc++; + sumOfSquares += (in * in); + sum += in; + + in = *pSrc++; + sumOfSquares += (in * in); + sum += in; + + in = *pSrc++; + sumOfSquares += (in * in); + sum += in; +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + /* C = A[0] + A[1] + ... + A[blockSize-1] */ + + in = *pSrc++; + /* Compute sum of squares and store result in a temporary variable, sumOfSquares. */ +#if defined (ARM_MATH_DSP) + sumOfSquares = __SMLALD(in, in, sumOfSquares); +#else + sumOfSquares += (in * in); +#endif /* #if defined (ARM_MATH_DSP) */ + /* Compute sum and store result in a temporary variable, sum. */ + sum += in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Compute Mean of squares and store result in a temporary variable, meanOfSquares. */ + meanOfSquares = (q31_t) (sumOfSquares / (q63_t)(blockSize - 1U)); + + /* Compute square of mean */ + squareOfMean = (q31_t) ((q63_t) sum * sum / (q63_t)(blockSize * (blockSize - 1U))); + + /* mean of squares minus the square of mean. */ + *pResult = (meanOfSquares - squareOfMean) >> 15U; +} + +/** + @} end of variance group + */ diff --git a/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_q31.c b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_q31.c new file mode 100644 index 0000000..558332f --- /dev/null +++ b/platform/cmsis/DSP_Lib/StatisticsFunctions/arm_var_q31.c @@ -0,0 +1,147 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_var_q31.c + * Description: Variance of an array of Q31 type + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupStats + */ + +/** + @addtogroup variance + @{ + */ + +/** + @brief Variance of the elements of a Q31 vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult variance value returned here + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + The input is represented in 1.31 format, which is then downshifted by 8 bits + which yields 1.23, and intermediate multiplication yields a 2.46 format. + The accumulator maintains full precision of the intermediate multiplication results, + but provides only a 16 guard bits. + There is no saturation on intermediate additions. + If the accumulator overflows it wraps around and distorts the result. + In order to avoid overflows completely the input signal must be scaled down by + log2(blockSize)-8 bits, as a total of blockSize additions are performed internally. + After division, internal variables should be Q18.46 + Finally, the 18.46 accumulator is right shifted by 15 bits to yield a 1.31 format value. + */ + +void arm_var_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult) +{ + uint32_t blkCnt; /* Loop counter */ + q63_t sum = 0; /* Temporary result storage */ + q63_t meanOfSquares, squareOfMean; /* Square of mean and mean of square */ + q63_t sumOfSquares = 0; /* Sum of squares */ + q31_t in; /* Temporary variable to store input value */ + + if (blockSize <= 1U) + { + *pResult = 0; + return; + } + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + /* C = A[0] + A[1] + ... + A[blockSize-1] */ + + in = *pSrc++ >> 8U; + /* Compute sum of squares and store result in a temporary variable, sumOfSquares. */ + sumOfSquares += ((q63_t) (in) * (in)); + /* Compute sum and store result in a temporary variable, sum. */ + sum += in; + + in = *pSrc++ >> 8U; + sumOfSquares += ((q63_t) (in) * (in)); + sum += in; + + in = *pSrc++ >> 8U; + sumOfSquares += ((q63_t) (in) * (in)); + sum += in; + + in = *pSrc++ >> 8U; + sumOfSquares += ((q63_t) (in) * (in)); + sum += in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */ + /* C = A[0] + A[1] + ... + A[blockSize-1] */ + + in = *pSrc++ >> 8U; + /* Compute sum of squares and store result in a temporary variable, sumOfSquares. */ + sumOfSquares += ((q63_t) (in) * (in)); + /* Compute sum and store result in a temporary variable, sum. */ + sum += in; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Compute Mean of squares and store result in a temporary variable, meanOfSquares. */ + meanOfSquares = (sumOfSquares / (q63_t)(blockSize - 1U)); + + /* Compute square of mean */ + squareOfMean = ( sum * sum / (q63_t)(blockSize * (blockSize - 1U))); + + /* Compute variance and store result in destination */ + *pResult = (meanOfSquares - squareOfMean) >> 15U; +} + +/** + @} end of variance group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/Makefile b/platform/cmsis/DSP_Lib/SupportFunctions/Makefile new file mode 100644 index 0000000..88c2e8b --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/Makefile @@ -0,0 +1,6 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out %Functions.c,$(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/SupportFunctions.c b/platform/cmsis/DSP_Lib/SupportFunctions/SupportFunctions.c new file mode 100644 index 0000000..4deb19b --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/SupportFunctions.c @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: SupportFunctions.c + * Description: Combination of all support function source files. + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_copy_f32.c" +#include "arm_copy_q15.c" +#include "arm_copy_q31.c" +#include "arm_copy_q7.c" +#include "arm_fill_f32.c" +#include "arm_fill_q15.c" +#include "arm_fill_q31.c" +#include "arm_fill_q7.c" +#include "arm_float_to_q15.c" +#include "arm_float_to_q31.c" +#include "arm_float_to_q7.c" +#include "arm_q15_to_float.c" +#include "arm_q15_to_q31.c" +#include "arm_q15_to_q7.c" +#include "arm_q31_to_float.c" +#include "arm_q31_to_q15.c" +#include "arm_q31_to_q7.c" +#include "arm_q7_to_float.c" +#include "arm_q7_to_q15.c" +#include "arm_q7_to_q31.c" diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_f32.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_f32.c new file mode 100644 index 0000000..a0ceb00 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_f32.c @@ -0,0 +1,110 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_copy_f32.c + * Description: Copies the elements of a floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @defgroup copy Vector Copy + + Copies sample by sample from source vector to destination vector. + +
+      pDst[n] = pSrc[n];   0 <= n < blockSize.
+  
+ + There are separate functions for floating point, Q31, Q15, and Q7 data types. + */ + +/** + @addtogroup copy + @{ + */ + +/** + @brief Copies the elements of a floating-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_copy_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A */ + + /* Copy and store result in destination buffer */ + *pDst++ = *pSrc++; + *pDst++ = *pSrc++; + *pDst++ = *pSrc++; + *pDst++ = *pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A */ + + /* Copy and store result in destination buffer */ + *pDst++ = *pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } +} + +/** + @} end of BasicCopy group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q15.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q15.c new file mode 100644 index 0000000..d8da113 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q15.c @@ -0,0 +1,96 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_copy_q15.c + * Description: Copies the elements of a Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup copy + @{ + */ + +/** + @brief Copies the elements of a Q15 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_copy_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A */ + + /* read 2 times 2 samples at a time */ + write_q15x2_ia (&pDst, read_q15x2_ia ((q15_t **) &pSrc)); + write_q15x2_ia (&pDst, read_q15x2_ia ((q15_t **) &pSrc)); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A */ + + /* Copy and store result in destination buffer */ + *pDst++ = *pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } +} + +/** + @} end of BasicCopy group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q31.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q31.c new file mode 100644 index 0000000..e342a32 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q31.c @@ -0,0 +1,98 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_copy_q31.c + * Description: Copies the elements of a Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup copy + @{ + */ + +/** + @brief Copies the elements of a Q31 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_copy_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A */ + + /* Copy and store result in destination buffer */ + *pDst++ = *pSrc++; + *pDst++ = *pSrc++; + *pDst++ = *pSrc++; + *pDst++ = *pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A */ + + /* Copy and store result in destination buffer */ + *pDst++ = *pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } +} + +/** + @} end of BasicCopy group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q7.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q7.c new file mode 100644 index 0000000..77da8ca --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_copy_q7.c @@ -0,0 +1,95 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_copy_q7.c + * Description: Copies the elements of a Q7 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup copy + @{ + */ + +/** + @brief Copies the elements of a Q7 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_copy_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A */ + + /* read 4 samples at a time */ + write_q7x4_ia (&pDst, read_q7x4_ia ((q7_t **) &pSrc)); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A */ + + /* Copy and store result in destination buffer */ + *pDst++ = *pSrc++; + + /* Decrement loop counter */ + blkCnt--; + } +} + +/** + @} end of BasicCopy group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_f32.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_f32.c new file mode 100644 index 0000000..b307d7f --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_f32.c @@ -0,0 +1,110 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fill_f32.c + * Description: Fills a constant value into a floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @defgroup Fill Vector Fill + + Fills the destination vector with a constant value. + +
+      pDst[n] = value;   0 <= n < blockSize.
+  
+ + There are separate functions for floating point, Q31, Q15, and Q7 data types. + */ + +/** + @addtogroup Fill + @{ + */ + +/** + @brief Fills a constant value into a floating-point vector. + @param[in] value input value to be filled + @param[out] pDst points to output vector + @param[in] blockSize number of samples in each vector + @return none + */ + +void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = value */ + + /* Fill value in destination buffer */ + *pDst++ = value; + *pDst++ = value; + *pDst++ = value; + *pDst++ = value; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = value */ + + /* Fill value in destination buffer */ + *pDst++ = value; + + /* Decrement loop counter */ + blkCnt--; + } +} + +/** + @} end of Fill group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q15.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q15.c new file mode 100644 index 0000000..d8c0f8d --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q15.c @@ -0,0 +1,100 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fill_q15.c + * Description: Fills a constant value into a Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup Fill + @{ + */ + +/** + @brief Fills a constant value into a Q15 vector. + @param[in] value input value to be filled + @param[out] pDst points to output vector + @param[in] blockSize number of samples in each vector + @return none + */ + +void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t packedValue; /* value packed to 32 bits */ + + /* Packing two 16 bit values to 32 bit value in order to use SIMD */ + packedValue = __PKHBT(value, value, 16U); + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = value */ + + /* fill 2 times 2 samples at a time */ + write_q15x2_ia (&pDst, packedValue); + write_q15x2_ia (&pDst, packedValue); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = value */ + + /* Fill value in destination buffer */ + *pDst++ = value; + + /* Decrement loop counter */ + blkCnt--; + } +} + +/** + @} end of Fill group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q31.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q31.c new file mode 100644 index 0000000..e174889 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q31.c @@ -0,0 +1,98 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fill_q31.c + * Description: Fills a constant value into a Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup Fill + @{ + */ + +/** + @brief Fills a constant value into a Q31 vector. + @param[in] value input value to be filled + @param[out] pDst points to output vector + @param[in] blockSize number of samples in each vector + @return none + */ + +void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = value */ + + /* Fill value in destination buffer */ + *pDst++ = value; + *pDst++ = value; + *pDst++ = value; + *pDst++ = value; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = value */ + + /* Fill value in destination buffer */ + *pDst++ = value; + + /* Decrement loop counter */ + blkCnt--; + } +} + +/** + @} end of Fill group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q7.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q7.c new file mode 100644 index 0000000..bca3267 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_fill_q7.c @@ -0,0 +1,99 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_fill_q7.c + * Description: Fills a constant value into a Q7 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup Fill + @{ + */ + +/** + @brief Fills a constant value into a Q7 vector. + @param[in] value input value to be filled + @param[out] pDst points to output vector + @param[in] blockSize number of samples in each vector + @return none + */ + +void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t packedValue; /* value packed to 32 bits */ + + /* Packing four 8 bit values to 32 bit value in order to use SIMD */ + packedValue = __PACKq7(value, value, value, value); + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = value */ + + /* fill 4 samples at a time */ + write_q7x4_ia (&pDst, packedValue); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = value */ + + /* Fill value in destination buffer */ + *pDst++ = value; + + /* Decrement loop counter */ + blkCnt--; + } +} + +/** + @} end of Fill group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q15.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q15.c new file mode 100644 index 0000000..6633afe --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q15.c @@ -0,0 +1,150 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_float_to_q15.c + * Description: Converts the elements of the floating-point vector to Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup float_to_x + @{ + */ + +/** + @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 number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (q15_t)(pSrc[n] * 32768);   0 <= n < blockSize.
+  
+ + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated. + + @note + In order to apply rounding, the library should be rebuilt with the ROUNDING macro + defined in the preprocessor section of project options. + */ + +void arm_float_to_q15( + const float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const float32_t *pIn = pSrc; /* Source pointer */ + +#ifdef ARM_MATH_ROUNDING + float32_t in; +#endif /* #ifdef ARM_MATH_ROUNDING */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A * 32768 */ + + /* convert from float to Q15 and store result in destination buffer */ +#ifdef ARM_MATH_ROUNDING + + in = (*pIn++ * 32768.0f); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16)); + + in = (*pIn++ * 32768.0f); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16)); + + in = (*pIn++ * 32768.0f); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16)); + + in = (*pIn++ * 32768.0f); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16)); + +#else + + *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16); + *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16); + *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16); + *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16); + +#endif /* #ifdef ARM_MATH_ROUNDING */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A * 32768 */ + + /* convert from float to Q15 and store result in destination buffer */ +#ifdef ARM_MATH_ROUNDING + + in = (*pIn++ * 32768.0f); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = (q15_t) (__SSAT((q31_t) (in), 16)); + +#else + + *pDst++ = (q15_t) __SSAT((q31_t) (*pIn++ * 32768.0f), 16); + +#endif /* #ifdef ARM_MATH_ROUNDING */ + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of float_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q31.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q31.c new file mode 100644 index 0000000..c9879d3 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q31.c @@ -0,0 +1,154 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_float_to_q31.c + * Description: Converts the elements of the floating-point vector to Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + * @defgroup float_to_x Convert 32-bit floating point value + */ + +/** + @addtogroup float_to_x + @{ + */ + +/** + @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 number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (q31_t)(pSrc[n] * 2147483648);   0 <= n < blockSize.
+  
+ + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] are saturated. + + @note + In order to apply rounding, the library should be rebuilt with the ROUNDING macro + defined in the preprocessor section of project options. + */ + +void arm_float_to_q31( + const float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const float32_t *pIn = pSrc; /* Source pointer */ + +#ifdef ARM_MATH_ROUNDING + float32_t in; +#endif /* #ifdef ARM_MATH_ROUNDING */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A * 2147483648 */ + + /* convert from float to Q31 and store result in destination buffer */ +#ifdef ARM_MATH_ROUNDING + + in = (*pIn++ * 2147483648.0f); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = clip_q63_to_q31((q63_t) (in)); + + in = (*pIn++ * 2147483648.0f); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = clip_q63_to_q31((q63_t) (in)); + + in = (*pIn++ * 2147483648.0f); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = clip_q63_to_q31((q63_t) (in)); + + in = (*pIn++ * 2147483648.0f); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = clip_q63_to_q31((q63_t) (in)); + +#else + + *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f)); + *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f)); + *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f)); + *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f)); + +#endif /* #ifdef ARM_MATH_ROUNDING */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A * 2147483648 */ + + /* convert from float to Q31 and store result in destination buffer */ +#ifdef ARM_MATH_ROUNDING + + in = (*pIn++ * 2147483648.0f); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = clip_q63_to_q31((q63_t) (in)); + +#else + + *pDst++ = clip_q63_to_q31((q63_t) (*pIn++ * 2147483648.0f)); + +#endif /* #ifdef ARM_MATH_ROUNDING */ + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of float_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q7.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q7.c new file mode 100644 index 0000000..4855ce4 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_float_to_q7.c @@ -0,0 +1,149 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_float_to_q7.c + * Description: Converts the elements of the floating-point vector to Q7 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup float_to_x + @{ + */ + +/** + @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 number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (q7_t)(pSrc[n] * 128);   0 <= n < blockSize.
+  
+ + @par Scaling and Overflow Behavior + The function uses saturating arithmetic. + Results outside of the allowable Q7 range [0x80 0x7F] are saturated. + @note + In order to apply rounding, the library should be rebuilt with the ROUNDING macro + defined in the preprocessor section of project options. + */ + +void arm_float_to_q7( + const float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const float32_t *pIn = pSrc; /* Source pointer */ + +#ifdef ARM_MATH_ROUNDING + float32_t in; +#endif /* #ifdef ARM_MATH_ROUNDING */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = A * 128 */ + + /* Convert from float to q7 and store result in destination buffer */ +#ifdef ARM_MATH_ROUNDING + + in = (*pIn++ * 128); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8)); + + in = (*pIn++ * 128); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8)); + + in = (*pIn++ * 128); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8)); + + in = (*pIn++ * 128); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8)); + +#else + + *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8); + *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8); + *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8); + *pDst++ = __SSAT((q31_t) (*pIn++ * 128.0f), 8); + +#endif /* #ifdef ARM_MATH_ROUNDING */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = A * 128 */ + + /* Convert from float to q7 and store result in destination buffer */ +#ifdef ARM_MATH_ROUNDING + + in = (*pIn++ * 128); + in += in > 0.0f ? 0.5f : -0.5f; + *pDst++ = (q7_t) (__SSAT((q15_t) (in), 8)); + +#else + + *pDst++ = (q7_t) __SSAT((q31_t) (*pIn++ * 128.0f), 8); + +#endif /* #ifdef ARM_MATH_ROUNDING */ + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of float_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_float.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_float.c new file mode 100644 index 0000000..a9384dc --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_float.c @@ -0,0 +1,110 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_q15_to_float.c + * Description: Converts the elements of the Q15 vector to floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + * @defgroup q15_to_x Convert 16-bit Integer value + */ + +/** + @addtogroup q15_to_x + @{ + */ + +/** + @brief Converts the elements of the Q15 vector to floating-point vector. + @param[in] pSrc points to the Q15 input vector + @param[out] pDst points to the floating-point output vector + @param[in] blockSize number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (float32_t) pSrc[n] / 32768;   0 <= n < blockSize.
+  
+ */ + +void arm_q15_to_float( + const q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const q15_t *pIn = pSrc; /* Source pointer */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (float32_t) A / 32768 */ + + /* Convert from q15 to float and store result in destination buffer */ + *pDst++ = ((float32_t) * pIn++ / 32768.0f); + *pDst++ = ((float32_t) * pIn++ / 32768.0f); + *pDst++ = ((float32_t) * pIn++ / 32768.0f); + *pDst++ = ((float32_t) * pIn++ / 32768.0f); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (float32_t) A / 32768 */ + + /* Convert from q15 to float and store result in destination buffer */ + *pDst++ = ((float32_t) *pIn++ / 32768.0f); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of q15_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_q31.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_q31.c new file mode 100644 index 0000000..1afd489 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_q31.c @@ -0,0 +1,138 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_q15_to_q31.c + * Description: Converts the elements of the Q15 vector to Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup q15_to_x + @{ + */ + +/** + @brief Converts the elements of the Q15 vector to Q31 vector. + @param[in] pSrc points to the Q15 input vector + @param[out] pDst points to the Q31 output vector + @param[in] blockSize number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (q31_t) pSrc[n] << 16;   0 <= n < blockSize.
+  
+ */ + +void arm_q15_to_q31( + const q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const q15_t *pIn = pSrc; /* Source pointer */ + +#if defined (ARM_MATH_LOOPUNROLL) + q31_t in1, in2; + q31_t out1, out2, out3, out4; +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (q31_t)A << 16 */ + + /* Convert from q15 to q31 and store result in destination buffer */ + in1 = read_q15x2_ia ((q15_t **) &pIn); + in2 = read_q15x2_ia ((q15_t **) &pIn); + +#ifndef ARM_MATH_BIG_ENDIAN + + /* extract lower 16 bits to 32 bit result */ + out1 = in1 << 16U; + /* extract upper 16 bits to 32 bit result */ + out2 = in1 & 0xFFFF0000; + /* extract lower 16 bits to 32 bit result */ + out3 = in2 << 16U; + /* extract upper 16 bits to 32 bit result */ + out4 = in2 & 0xFFFF0000; + +#else + + /* extract upper 16 bits to 32 bit result */ + out1 = in1 & 0xFFFF0000; + /* extract lower 16 bits to 32 bit result */ + out2 = in1 << 16U; + /* extract upper 16 bits to 32 bit result */ + out3 = in2 & 0xFFFF0000; + /* extract lower 16 bits to 32 bit result */ + out4 = in2 << 16U; + +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + *pDst++ = out1; + *pDst++ = out2; + *pDst++ = out3; + *pDst++ = out4; + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (q31_t) A << 16 */ + + /* Convert from q15 to q31 and store result in destination buffer */ + *pDst++ = (q31_t) *pIn++ << 16; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of q15_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_q7.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_q7.c new file mode 100644 index 0000000..d118b76 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q15_to_q7.c @@ -0,0 +1,146 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_q15_to_q7.c + * Description: Converts the elements of the Q15 vector to Q7 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup q15_to_x + @{ + */ + +/** + @brief Converts the elements of the Q15 vector to Q7 vector. + @param[in] pSrc points to the Q15 input vector + @param[out] pDst points to the Q7 output vector + @param[in] blockSize number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (q7_t) pSrc[n] >> 8;   0 <= n < blockSize.
+  
+ */ + +void arm_q15_to_q7( + const q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const q15_t *pIn = pSrc; /* Source pointer */ + +#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP) + q31_t in1, in2; + q31_t out1, out2; +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (q7_t) A >> 8 */ + + /* Convert from q15 to q7 and store result in destination buffer */ +#if defined (ARM_MATH_DSP) + + in1 = read_q15x2_ia ((q15_t **) &pIn); + in2 = read_q15x2_ia ((q15_t **) &pIn); + +#ifndef ARM_MATH_BIG_ENDIAN + + out1 = __PKHTB(in2, in1, 16); + out2 = __PKHBT(in2, in1, 16); + +#else + + out1 = __PKHTB(in1, in2, 16); + out2 = __PKHBT(in1, in2, 16); + +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* rotate packed value by 24 */ + out2 = ((uint32_t) out2 << 8) | ((uint32_t) out2 >> 24); + + /* anding with 0xff00ff00 to get two 8 bit values */ + out1 = out1 & 0xFF00FF00; + /* anding with 0x00ff00ff to get two 8 bit values */ + out2 = out2 & 0x00FF00FF; + + /* oring two values(contains two 8 bit values) to get four packed 8 bit values */ + out1 = out1 | out2; + + /* store 4 samples at a time to destiantion buffer */ + write_q7x4_ia (&pDst, out1); + +#else + + *pDst++ = (q7_t) (*pIn++ >> 8); + *pDst++ = (q7_t) (*pIn++ >> 8); + *pDst++ = (q7_t) (*pIn++ >> 8); + *pDst++ = (q7_t) (*pIn++ >> 8); + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (q7_t) A >> 8 */ + + /* Convert from q15 to q7 and store result in destination buffer */ + *pDst++ = (q7_t) (*pIn++ >> 8); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of q15_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_float.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_float.c new file mode 100644 index 0000000..2ad8736 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_float.c @@ -0,0 +1,110 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_q31_to_float.c + * Description: Converts the elements of the Q31 vector to floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + * @defgroup q31_to_x Convert 32-bit Integer value + */ + +/** + @addtogroup q31_to_x + @{ + */ + +/** + @brief Converts the elements of the Q31 vector to floating-point vector. + @param[in] pSrc points to the Q31 input vector + @param[out] pDst points to the floating-point output vector + @param[in] blockSize number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (float32_t) pSrc[n] / 2147483648;   0 <= n < blockSize.
+  
+ */ + +void arm_q31_to_float( + const q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const q31_t *pIn = pSrc; /* Source pointer */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (float32_t) A / 2147483648 */ + + /* Convert from q31 to float and store result in destination buffer */ + *pDst++ = ((float32_t) *pIn++ / 2147483648.0f); + *pDst++ = ((float32_t) *pIn++ / 2147483648.0f); + *pDst++ = ((float32_t) *pIn++ / 2147483648.0f); + *pDst++ = ((float32_t) *pIn++ / 2147483648.0f); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (float32_t) A / 2147483648 */ + + /* Convert from q31 to float and store result in destination buffer */ + *pDst++ = ((float32_t) *pIn++ / 2147483648.0f); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of q31_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_q15.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_q15.c new file mode 100644 index 0000000..8d82c28 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_q15.c @@ -0,0 +1,134 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_q31_to_q15.c + * Description: Converts the elements of the Q31 vector to Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup q31_to_x + @{ + */ + +/** + @brief Converts the elements of the Q31 vector to Q15 vector. + @param[in] pSrc points to the Q31 input vector + @param[out] pDst points to the Q15 output vector + @param[in] blockSize number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (q15_t) pSrc[n] >> 16;   0 <= n < blockSize.
+  
+ */ + +void arm_q31_to_q15( + const q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const q31_t *pIn = pSrc; /* Source pointer */ + +#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP) + q31_t in1, in2, in3, in4; + q31_t out1, out2; +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (q15_t) (A >> 16) */ + + /* Convert from q31 to q15 and store result in destination buffer */ +#if defined (ARM_MATH_DSP) + + in1 = *pIn++; + in2 = *pIn++; + in3 = *pIn++; + in4 = *pIn++; + + /* pack two higher 16-bit values from two 32-bit values */ +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __PKHTB(in2, in1, 16); + out2 = __PKHTB(in4, in3, 16); +#else + out1 = __PKHTB(in1, in2, 16); + out2 = __PKHTB(in3, in4, 16); +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + + write_q15x2_ia (&pDst, out1); + write_q15x2_ia (&pDst, out2); + +#else + + *pDst++ = (q15_t) (*pIn++ >> 16); + *pDst++ = (q15_t) (*pIn++ >> 16); + *pDst++ = (q15_t) (*pIn++ >> 16); + *pDst++ = (q15_t) (*pIn++ >> 16); + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (q15_t) (A >> 16) */ + + /* Convert from q31 to q15 and store result in destination buffer */ + *pDst++ = (q15_t) (*pIn++ >> 16); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of q31_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_q7.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_q7.c new file mode 100644 index 0000000..c7d1b4c --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q31_to_q7.c @@ -0,0 +1,110 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_q31_to_q7.c + * Description: Converts the elements of the Q31 vector to Q7 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup q31_to_x + @{ + */ + +/** + @brief Converts the elements of the Q31 vector to Q7 vector. + @param[in] pSrc points to the Q31 input vector + @param[out] pDst points to the Q7 output vector + @param[in] blockSize number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (q7_t) pSrc[n] >> 24;   0 <= n < blockSize.
+  
+ */ + +void arm_q31_to_q7( + const q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const q31_t *pIn = pSrc; /* Source pointer */ + +#if defined (ARM_MATH_LOOPUNROLL) + + q7_t out1, out2, out3, out4; + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (q7_t) (A >> 24) */ + + /* Convert from q31 to q7 and store result in destination buffer */ + + out1 = (q7_t) (*pIn++ >> 24); + out2 = (q7_t) (*pIn++ >> 24); + out3 = (q7_t) (*pIn++ >> 24); + out4 = (q7_t) (*pIn++ >> 24); + write_q7x4_ia (&pDst, __PACKq7(out1, out2, out3, out4)); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (q7_t) (A >> 24) */ + + /* Convert from q31 to q7 and store result in destination buffer */ + *pDst++ = (q7_t) (*pIn++ >> 24); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of q31_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_float.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_float.c new file mode 100644 index 0000000..c8e940b --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_float.c @@ -0,0 +1,110 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_q7_to_float.c + * Description: Converts the elements of the Q7 vector to floating-point vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + * @defgroup q7_to_x Convert 8-bit Integer value + */ + +/** + @addtogroup q7_to_x + @{ + */ + +/** + @brief Converts the elements of the Q7 vector to floating-point vector. + @param[in] pSrc points to the Q7 input vector + @param[out] pDst points to the floating-point output vector + @param[in] blockSize number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (float32_t) pSrc[n] / 128;   0 <= n < blockSize.
+  
+ */ + +void arm_q7_to_float( + const q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const q7_t *pIn = pSrc; /* Source pointer */ + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (float32_t) A / 128 */ + + /* Convert from q7 to float and store result in destination buffer */ + *pDst++ = ((float32_t) * pIn++ / 128.0f); + *pDst++ = ((float32_t) * pIn++ / 128.0f); + *pDst++ = ((float32_t) * pIn++ / 128.0f); + *pDst++ = ((float32_t) * pIn++ / 128.0f); + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (float32_t) A / 128 */ + + /* Convert from q7 to float and store result in destination buffer */ + *pDst++ = ((float32_t) * pIn++ / 128.0f); + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of q7_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_q15.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_q15.c new file mode 100644 index 0000000..89afd10 --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_q15.c @@ -0,0 +1,143 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_q7_to_q15.c + * Description: Converts the elements of the Q7 vector to Q15 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup q7_to_x + @{ + */ + +/** + @brief Converts the elements of the Q7 vector to Q15 vector. + @param[in] pSrc points to the Q7 input vector + @param[out] pDst points to the Q15 output vector + @param[in] blockSize number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (q15_t) pSrc[n] << 8;   0 <= n < blockSize.
+  
+ */ + +void arm_q7_to_q15( + const q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const q7_t *pIn = pSrc; /* Source pointer */ + +#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP) + q31_t in; + q31_t in1, in2; + q31_t out1, out2; +#endif + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (q15_t) A << 8 */ + + /* Convert from q7 to q15 and store result in destination buffer */ +#if defined (ARM_MATH_DSP) + + in = read_q7x4_ia ((q7_t **) &pIn); + + /* rotatate in by 8 and extend two q7_t values to q15_t values */ + in1 = __SXTB16(__ROR(in, 8)); + + /* extend remainig two q7_t values to q15_t values */ + in2 = __SXTB16(in); + + in1 = in1 << 8U; + in2 = in2 << 8U; + + in1 = in1 & 0xFF00FF00; + in2 = in2 & 0xFF00FF00; + +#ifndef ARM_MATH_BIG_ENDIAN + out2 = __PKHTB(in1, in2, 16); + out1 = __PKHBT(in2, in1, 16); +#else + out1 = __PKHTB(in1, in2, 16); + out2 = __PKHBT(in2, in1, 16); +#endif + + write_q15x2_ia (&pDst, out1); + write_q15x2_ia (&pDst, out2); + +#else + + *pDst++ = (q15_t) *pIn++ << 8; + *pDst++ = (q15_t) *pIn++ << 8; + *pDst++ = (q15_t) *pIn++ << 8; + *pDst++ = (q15_t) *pIn++ << 8; + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (q15_t) A << 8 */ + + /* Convert from q7 to q15 and store result in destination buffer */ + *pDst++ = (q15_t) * pIn++ << 8; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of q7_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_q31.c b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_q31.c new file mode 100644 index 0000000..641c02d --- /dev/null +++ b/platform/cmsis/DSP_Lib/SupportFunctions/arm_q7_to_q31.c @@ -0,0 +1,121 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_q7_to_q31.c + * Description: Converts the elements of the Q7 vector to Q31 vector + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupSupport + */ + +/** + @addtogroup q7_to_x + @{ + */ + +/** + @brief Converts the elements of the Q7 vector to Q31 vector. + @param[in] pSrc points to the Q7 input vector + @param[out] pDst points to the Q31 output vector + @param[in] blockSize number of samples in each vector + @return none + + @par Details + The equation used for the conversion process is: +
+      pDst[n] = (q31_t) pSrc[n] << 24;   0 <= n < blockSize.
+  
+ */ + +void arm_q7_to_q31( + const q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize) +{ + uint32_t blkCnt; /* Loop counter */ + const q7_t *pIn = pSrc; /* Source pointer */ + +#if defined (ARM_MATH_LOOPUNROLL) + + q31_t in; + + /* Loop unrolling: Compute 4 outputs at a time */ + blkCnt = blockSize >> 2U; + + while (blkCnt > 0U) + { + /* C = (q31_t) A << 24 */ + + /* Convert from q7 to q31 and store result in destination buffer */ + in = read_q7x4_ia ((q7_t **) &pIn); + +#ifndef ARM_MATH_BIG_ENDIAN + + *pDst++ = (__ROR(in, 8)) & 0xFF000000; + *pDst++ = (__ROR(in, 16)) & 0xFF000000; + *pDst++ = (__ROR(in, 24)) & 0xFF000000; + *pDst++ = (in & 0xFF000000); + +#else + + *pDst++ = (in & 0xFF000000); + *pDst++ = (__ROR(in, 24)) & 0xFF000000; + *pDst++ = (__ROR(in, 16)) & 0xFF000000; + *pDst++ = (__ROR(in, 8)) & 0xFF000000; + +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Decrement loop counter */ + blkCnt--; + } + + /* Loop unrolling: Compute remaining outputs */ + blkCnt = blockSize % 0x4U; + +#else + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + + while (blkCnt > 0U) + { + /* C = (q31_t) A << 24 */ + + /* Convert from q7 to q31 and store result in destination buffer */ + *pDst++ = (q31_t) * pIn++ << 24; + + /* Decrement loop counter */ + blkCnt--; + } + +} + +/** + @} end of q7_to_x group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/Makefile b/platform/cmsis/DSP_Lib/TransformFunctions/Makefile new file mode 100644 index 0000000..562f5ef --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/Makefile @@ -0,0 +1,6 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out %Functions.c arm_bitreversal2.c,$(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/TransformFunctions.c b/platform/cmsis/DSP_Lib/TransformFunctions/TransformFunctions.c new file mode 100644 index 0000000..d0f7ce4 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/TransformFunctions.c @@ -0,0 +1,60 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: TransformFunctions.c + * Description: Combination of all transform function source files. + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_bitreversal.c" +#include "arm_bitreversal2.c" +#include "arm_cfft_f32.c" +#include "arm_cfft_q15.c" +#include "arm_cfft_q31.c" +#include "arm_cfft_radix2_f32.c" +#include "arm_cfft_radix2_init_f32.c" +#include "arm_cfft_radix2_init_q15.c" +#include "arm_cfft_radix2_init_q31.c" +#include "arm_cfft_radix2_q15.c" +#include "arm_cfft_radix2_q31.c" +#include "arm_cfft_radix4_f32.c" +#include "arm_cfft_radix4_init_f32.c" +#include "arm_cfft_radix4_init_q15.c" +#include "arm_cfft_radix4_init_q31.c" +#include "arm_cfft_radix4_q15.c" +#include "arm_cfft_radix4_q31.c" +#include "arm_cfft_radix8_f32.c" +#include "arm_dct4_f32.c" +#include "arm_dct4_init_f32.c" +#include "arm_dct4_init_q15.c" +#include "arm_dct4_init_q31.c" +#include "arm_dct4_q15.c" +#include "arm_dct4_q31.c" +#include "arm_rfft_f32.c" +#include "arm_rfft_fast_f32.c" +#include "arm_rfft_fast_init_f32.c" +#include "arm_rfft_init_f32.c" +#include "arm_rfft_init_q15.c" +#include "arm_rfft_init_q31.c" +#include "arm_rfft_q15.c" +#include "arm_rfft_q31.c" diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal.c new file mode 100644 index 0000000..c608129 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal.c @@ -0,0 +1,229 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_bitreversal.c + * Description: Bitreversal functions + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @brief In-place floating-point bit reversal function. + @param[in,out] pSrc points to in-place floating-point data buffer + @param[in] fftSize length of FFT + @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + @param[in] pBitRevTab points to bit reversal table + @return none + */ + +void arm_bitreversal_f32( + float32_t * pSrc, + uint16_t fftSize, + uint16_t bitRevFactor, + const uint16_t * pBitRevTab) +{ + uint16_t fftLenBy2, fftLenBy2p1; + uint16_t i, j; + float32_t in; + + /* Initializations */ + j = 0U; + fftLenBy2 = fftSize >> 1U; + fftLenBy2p1 = (fftSize >> 1U) + 1U; + + /* Bit Reversal Implementation */ + for (i = 0U; i <= (fftLenBy2 - 2U); i += 2U) + { + if (i < j) + { + /* pSrc[i] <-> pSrc[j]; */ + in = pSrc[2U * i]; + pSrc[2U * i] = pSrc[2U * j]; + pSrc[2U * j] = in; + + /* pSrc[i+1U] <-> pSrc[j+1U] */ + in = pSrc[(2U * i) + 1U]; + pSrc[(2U * i) + 1U] = pSrc[(2U * j) + 1U]; + pSrc[(2U * j) + 1U] = in; + + /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */ + in = pSrc[2U * (i + fftLenBy2p1)]; + pSrc[2U * (i + fftLenBy2p1)] = pSrc[2U * (j + fftLenBy2p1)]; + pSrc[2U * (j + fftLenBy2p1)] = in; + + /* pSrc[i+fftLenBy2p1+1U] <-> pSrc[j+fftLenBy2p1+1U] */ + in = pSrc[(2U * (i + fftLenBy2p1)) + 1U]; + pSrc[(2U * (i + fftLenBy2p1)) + 1U] = + pSrc[(2U * (j + fftLenBy2p1)) + 1U]; + pSrc[(2U * (j + fftLenBy2p1)) + 1U] = in; + + } + + /* pSrc[i+1U] <-> pSrc[j+1U] */ + in = pSrc[2U * (i + 1U)]; + pSrc[2U * (i + 1U)] = pSrc[2U * (j + fftLenBy2)]; + pSrc[2U * (j + fftLenBy2)] = in; + + /* pSrc[i+2U] <-> pSrc[j+2U] */ + in = pSrc[(2U * (i + 1U)) + 1U]; + pSrc[(2U * (i + 1U)) + 1U] = pSrc[(2U * (j + fftLenBy2)) + 1U]; + pSrc[(2U * (j + fftLenBy2)) + 1U] = in; + + /* Reading the index for the bit reversal */ + j = *pBitRevTab; + + /* Updating the bit reversal index depending on the fft length */ + pBitRevTab += bitRevFactor; + } +} + + +/** + @brief In-place Q31 bit reversal function. + @param[in,out] pSrc points to in-place Q31 data buffer. + @param[in] fftLen length of FFT. + @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + @param[in] pBitRevTab points to bit reversal table + @return none +*/ + +void arm_bitreversal_q31( + q31_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + const uint16_t * pBitRevTab) +{ + uint32_t fftLenBy2, fftLenBy2p1, i, j; + q31_t in; + + /* Initializations */ + j = 0U; + fftLenBy2 = fftLen / 2U; + fftLenBy2p1 = (fftLen / 2U) + 1U; + + /* Bit Reversal Implementation */ + for (i = 0U; i <= (fftLenBy2 - 2U); i += 2U) + { + if (i < j) + { + /* pSrc[i] <-> pSrc[j]; */ + in = pSrc[2U * i]; + pSrc[2U * i] = pSrc[2U * j]; + pSrc[2U * j] = in; + + /* pSrc[i+1U] <-> pSrc[j+1U] */ + in = pSrc[(2U * i) + 1U]; + pSrc[(2U * i) + 1U] = pSrc[(2U * j) + 1U]; + pSrc[(2U * j) + 1U] = in; + + /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */ + in = pSrc[2U * (i + fftLenBy2p1)]; + pSrc[2U * (i + fftLenBy2p1)] = pSrc[2U * (j + fftLenBy2p1)]; + pSrc[2U * (j + fftLenBy2p1)] = in; + + /* pSrc[i+fftLenBy2p1+1U] <-> pSrc[j+fftLenBy2p1+1U] */ + in = pSrc[(2U * (i + fftLenBy2p1)) + 1U]; + pSrc[(2U * (i + fftLenBy2p1)) + 1U] = + pSrc[(2U * (j + fftLenBy2p1)) + 1U]; + pSrc[(2U * (j + fftLenBy2p1)) + 1U] = in; + + } + + /* pSrc[i+1U] <-> pSrc[j+1U] */ + in = pSrc[2U * (i + 1U)]; + pSrc[2U * (i + 1U)] = pSrc[2U * (j + fftLenBy2)]; + pSrc[2U * (j + fftLenBy2)] = in; + + /* pSrc[i+2U] <-> pSrc[j+2U] */ + in = pSrc[(2U * (i + 1U)) + 1U]; + pSrc[(2U * (i + 1U)) + 1U] = pSrc[(2U * (j + fftLenBy2)) + 1U]; + pSrc[(2U * (j + fftLenBy2)) + 1U] = in; + + /* Reading the index for the bit reversal */ + j = *pBitRevTab; + + /* Updating the bit reversal index depending on the fft length */ + pBitRevTab += bitRevFactor; + } +} + + + +/** + @brief In-place Q15 bit reversal function. + @param[in,out] pSrc16 points to in-place Q15 data buffer + @param[in] fftLen length of FFT + @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + @param[in] pBitRevTab points to bit reversal table + @return none +*/ + +void arm_bitreversal_q15( + q15_t * pSrc16, + uint32_t fftLen, + uint16_t bitRevFactor, + const uint16_t * pBitRevTab) +{ + q31_t *pSrc = (q31_t *) pSrc16; + q31_t in; + uint32_t fftLenBy2, fftLenBy2p1; + uint32_t i, j; + + /* Initializations */ + j = 0U; + fftLenBy2 = fftLen / 2U; + fftLenBy2p1 = (fftLen / 2U) + 1U; + + /* Bit Reversal Implementation */ + for (i = 0U; i <= (fftLenBy2 - 2U); i += 2U) + { + if (i < j) + { + /* pSrc[i] <-> pSrc[j]; */ + /* pSrc[i+1U] <-> pSrc[j+1U] */ + in = pSrc[i]; + pSrc[i] = pSrc[j]; + pSrc[j] = in; + + /* pSrc[i + fftLenBy2p1] <-> pSrc[j + fftLenBy2p1]; */ + /* pSrc[i + fftLenBy2p1+1U] <-> pSrc[j + fftLenBy2p1+1U] */ + in = pSrc[i + fftLenBy2p1]; + pSrc[i + fftLenBy2p1] = pSrc[j + fftLenBy2p1]; + pSrc[j + fftLenBy2p1] = in; + } + + /* pSrc[i+1U] <-> pSrc[j+fftLenBy2]; */ + /* pSrc[i+2] <-> pSrc[j+fftLenBy2+1U] */ + in = pSrc[i + 1U]; + pSrc[i + 1U] = pSrc[j + fftLenBy2]; + pSrc[j + fftLenBy2] = in; + + /* Reading the index for the bit reversal */ + j = *pBitRevTab; + + /* Updating the bit reversal index depending on the fft length */ + pBitRevTab += bitRevFactor; + } +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal2.S b/platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal2.S new file mode 100644 index 0000000..c16091b --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal2.S @@ -0,0 +1,216 @@ +;/* ---------------------------------------------------------------------- +; * Project: CMSIS DSP Library +; * Title: arm_bitreversal2.S +; * Description: arm_bitreversal_32 function done in assembly for maximum speed. +; * Called after doing an fft to reorder the output. +; * The function is loop unrolled by 2. arm_bitreversal_16 as well. +; * +; * $Date: 18. March 2019 +; * $Revision: V1.5.2 +; * +; * Target Processor: Cortex-M cores +; * -------------------------------------------------------------------- */ +;/* +; * 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. +; */ + +#if defined ( __CC_ARM ) /* Keil */ + #define CODESECT AREA ||.text||, CODE, READONLY, ALIGN=2 + #define LABEL +#elif defined ( __IASMARM__ ) /* IAR */ + #define CODESECT SECTION `.text`:CODE + #define PROC + #define LABEL + #define ENDP + #define EXPORT PUBLIC +#elif defined ( __CSMC__ ) /* Cosmic */ + #define CODESECT switch .text + #define THUMB + #define EXPORT xdef + #define PROC : + #define LABEL : + #define ENDP + #define arm_bitreversal_32 _arm_bitreversal_32 +#elif defined ( __TI_ARM__ ) /* TI ARM */ + #define THUMB .thumb + #define CODESECT .text + #define EXPORT .global + #define PROC : .asmfunc + #define LABEL : + #define ENDP .endasmfunc + #define END +#elif defined ( __GNUC__ ) /* GCC */ + #define THUMB .thumb + #define CODESECT .section .text + #define EXPORT .global + #define PROC : + #define LABEL : + #define ENDP + #define END + + .syntax unified +#endif + + CODESECT + THUMB + +;/** +; @brief In-place bit reversal function. +; @param[in,out] pSrc points to the in-place buffer of unknown 32-bit data type +; @param[in] bitRevLen bit reversal table length +; @param[in] pBitRevTab points to bit reversal table +; @return none +; */ + EXPORT arm_bitreversal_32 + EXPORT arm_bitreversal_16 + +#if defined ( __CC_ARM ) /* Keil */ +#elif defined ( __IASMARM__ ) /* IAR */ +#elif defined ( __CSMC__ ) /* Cosmic */ +#elif defined ( __TI_ARM__ ) /* TI ARM */ +#elif defined ( __GNUC__ ) /* GCC */ + .type arm_bitreversal_16, %function + .type arm_bitreversal_32, %function +#endif + +#if defined (ARM_MATH_CM0_FAMILY) + +arm_bitreversal_32 PROC + ADDS r3,r1,#1 + PUSH {r4-r6} + ADDS r1,r2,#0 + LSRS r3,r3,#1 +arm_bitreversal_32_0 LABEL + LDRH r2,[r1,#2] + LDRH r6,[r1,#0] + ADD r2,r0,r2 + ADD r6,r0,r6 + LDR r5,[r2,#0] + LDR r4,[r6,#0] + STR r5,[r6,#0] + STR r4,[r2,#0] + LDR r5,[r2,#4] + LDR r4,[r6,#4] + STR r5,[r6,#4] + STR r4,[r2,#4] + ADDS r1,r1,#4 + SUBS r3,r3,#1 + BNE arm_bitreversal_32_0 + POP {r4-r6} + BX lr + ENDP + +arm_bitreversal_16 PROC + ADDS r3,r1,#1 + PUSH {r4-r6} + ADDS r1,r2,#0 + LSRS r3,r3,#1 +arm_bitreversal_16_0 LABEL + LDRH r2,[r1,#2] + LDRH r6,[r1,#0] + LSRS r2,r2,#1 + LSRS r6,r6,#1 + ADD r2,r0,r2 + ADD r6,r0,r6 + LDR r5,[r2,#0] + LDR r4,[r6,#0] + STR r5,[r6,#0] + STR r4,[r2,#0] + ADDS r1,r1,#4 + SUBS r3,r3,#1 + BNE arm_bitreversal_16_0 + POP {r4-r6} + BX lr + ENDP + +#else + +arm_bitreversal_32 PROC + ADDS r3,r1,#1 + CMP r3,#1 + IT LS + BXLS lr + PUSH {r4-r9} + ADDS r1,r2,#2 + LSRS r3,r3,#2 +arm_bitreversal_32_0 LABEL ;/* loop unrolled by 2 */ + LDRH r8,[r1,#4] + LDRH r9,[r1,#2] + LDRH r2,[r1,#0] + LDRH r12,[r1,#-2] + ADD r8,r0,r8 + ADD r9,r0,r9 + ADD r2,r0,r2 + ADD r12,r0,r12 + LDR r7,[r9,#0] + LDR r6,[r8,#0] + LDR r5,[r2,#0] + LDR r4,[r12,#0] + STR r6,[r9,#0] + STR r7,[r8,#0] + STR r5,[r12,#0] + STR r4,[r2,#0] + LDR r7,[r9,#4] + LDR r6,[r8,#4] + LDR r5,[r2,#4] + LDR r4,[r12,#4] + STR r6,[r9,#4] + STR r7,[r8,#4] + STR r5,[r12,#4] + STR r4,[r2,#4] + ADDS r1,r1,#8 + SUBS r3,r3,#1 + BNE arm_bitreversal_32_0 + POP {r4-r9} + BX lr + ENDP + +arm_bitreversal_16 PROC + ADDS r3,r1,#1 + CMP r3,#1 + IT LS + BXLS lr + PUSH {r4-r9} + ADDS r1,r2,#2 + LSRS r3,r3,#2 +arm_bitreversal_16_0 LABEL ;/* loop unrolled by 2 */ + LDRH r8,[r1,#4] + LDRH r9,[r1,#2] + LDRH r2,[r1,#0] + LDRH r12,[r1,#-2] + ADD r8,r0,r8,LSR #1 + ADD r9,r0,r9,LSR #1 + ADD r2,r0,r2,LSR #1 + ADD r12,r0,r12,LSR #1 + LDR r7,[r9,#0] + LDR r6,[r8,#0] + LDR r5,[r2,#0] + LDR r4,[r12,#0] + STR r6,[r9,#0] + STR r7,[r8,#0] + STR r5,[r12,#0] + STR r4,[r2,#0] + ADDS r1,r1,#8 + SUBS r3,r3,#1 + BNE arm_bitreversal_16_0 + POP {r4-r9} + BX lr + ENDP + +#endif + + END diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal2.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal2.c new file mode 100644 index 0000000..c5fe60f --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_bitreversal2.c @@ -0,0 +1,99 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_bitreversal2.c + * Description: Bitreversal functions + * + * $Date: 18. March 2019 + * $Revision: V1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @brief In-place 32 bit reversal function. + @param[in,out] pSrc points to in-place buffer of unknown 32-bit data type + @param[in] bitRevLen bit reversal table length + @param[in] pBitRevTab points to bit reversal table + @return none +*/ + +void arm_bitreversal_32( + uint32_t *pSrc, + const uint16_t bitRevLen, + const uint16_t *pBitRevTab) +{ + uint32_t a, b, i, tmp; + + for (i = 0; i < bitRevLen; ) + { + a = pBitRevTab[i ] >> 2; + b = pBitRevTab[i + 1] >> 2; + + //real + tmp = pSrc[a]; + pSrc[a] = pSrc[b]; + pSrc[b] = tmp; + + //complex + tmp = pSrc[a+1]; + pSrc[a+1] = pSrc[b+1]; + pSrc[b+1] = tmp; + + i += 2; + } +} + + +/** + @brief In-place 16 bit reversal function. + @param[in,out] pSrc points to in-place buffer of unknown 16-bit data type + @param[in] bitRevLen bit reversal table length + @param[in] pBitRevTab points to bit reversal table + @return none +*/ + +void arm_bitreversal_16( + uint16_t *pSrc, + const uint16_t bitRevLen, + const uint16_t *pBitRevTab) +{ + uint16_t a, b, i, tmp; + + for (i = 0; i < bitRevLen; ) + { + a = pBitRevTab[i ] >> 2; + b = pBitRevTab[i + 1] >> 2; + + //real + tmp = pSrc[a]; + pSrc[a] = pSrc[b]; + pSrc[b] = tmp; + + //complex + tmp = pSrc[a+1]; + pSrc[a+1] = pSrc[b+1]; + pSrc[b+1] = tmp; + + i += 2; + } +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_f32.c new file mode 100644 index 0000000..2fff61c --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_f32.c @@ -0,0 +1,629 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_f32.c + * Description: Combined Radix Decimation in Frequency CFFT Floating point processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +extern void arm_radix8_butterfly_f32( + float32_t * pSrc, + uint16_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier); + +extern void arm_bitreversal_32( + uint32_t * pSrc, + const uint16_t bitRevLen, + const uint16_t * pBitRevTable); + +/** + @ingroup groupTransforms + */ + +/** + @defgroup ComplexFFT Complex FFT Functions + + @par + The Fast Fourier Transform (FFT) is an efficient algorithm for computing the + Discrete Fourier Transform (DFT). The FFT can be orders of magnitude faster + than the DFT, especially for long lengths. + The algorithms described in this section + operate on complex data. A separate set of functions is devoted to handling + of real sequences. + @par + There are separate algorithms for handling floating-point, Q15, and Q31 data + types. The algorithms available for each data type are described next. + @par + The FFT functions operate in-place. That is, the array holding the input data + will also be used to hold the corresponding result. The input data is complex + and contains 2*fftLen interleaved values as shown below. +
{real[0], imag[0], real[1], imag[1], ...} 
+ The FFT result will be contained in the same array and the frequency domain + values will have the same interleaving. + + @par Floating-point + The floating-point complex FFT uses a mixed-radix algorithm. Multiple radix-8 + stages are performed along with a single radix-2 or radix-4 stage, as needed. + The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses + a different twiddle factor table. + @par + The function uses the standard FFT definition and output values may grow by a + factor of fftLen when computing the forward transform. The + inverse transform includes a scale of 1/fftLen as part of the + calculation and this matches the textbook definition of the inverse FFT. + @par + Pre-initialized data structures containing twiddle factors and bit reversal + tables are provided and defined in arm_const_structs.h. Include + this header in your function and then pass one of the constant structures as + an argument to arm_cfft_f32. For example: + @par + arm_cfft_f32(arm_cfft_sR_f32_len64, pSrc, 1, 1) + @par + computes a 64-point inverse complex FFT including bit reversal. + The data structures are treated as constant data and not modified during the + calculation. The same data structure can be reused for multiple transforms + including mixing forward and inverse transforms. + @par + Earlier releases of the library provided separate radix-2 and radix-4 + algorithms that operated on floating-point data. These functions are still + provided but are deprecated. The older functions are slower and less general + than the new functions. + @par + An example of initialization of the constants for the arm_cfft_f32 function follows: + @code + const static arm_cfft_instance_f32 *S; + ... + switch (length) { + case 16: + S = &arm_cfft_sR_f32_len16; + break; + case 32: + S = &arm_cfft_sR_f32_len32; + break; + case 64: + S = &arm_cfft_sR_f32_len64; + break; + case 128: + S = &arm_cfft_sR_f32_len128; + break; + case 256: + S = &arm_cfft_sR_f32_len256; + break; + case 512: + S = &arm_cfft_sR_f32_len512; + break; + case 1024: + S = &arm_cfft_sR_f32_len1024; + break; + case 2048: + S = &arm_cfft_sR_f32_len2048; + break; + case 4096: + S = &arm_cfft_sR_f32_len4096; + break; + } + @endcode + @par Q15 and Q31 + The floating-point complex FFT uses a mixed-radix algorithm. Multiple radix-4 + stages are performed along with a single radix-2 stage, as needed. + The algorithm supports lengths of [16, 32, 64, ..., 4096] and each length uses + a different twiddle factor table. + @par + The function uses the standard FFT definition and output values may grow by a + factor of fftLen when computing the forward transform. The + inverse transform includes a scale of 1/fftLen as part of the + calculation and this matches the textbook definition of the inverse FFT. + @par + Pre-initialized data structures containing twiddle factors and bit reversal + tables are provided and defined in arm_const_structs.h. Include + this header in your function and then pass one of the constant structures as + an argument to arm_cfft_q31. For example: + @par + arm_cfft_q31(arm_cfft_sR_q31_len64, pSrc, 1, 1) + @par + computes a 64-point inverse complex FFT including bit reversal. + The data structures are treated as constant data and not modified during the + calculation. The same data structure can be reused for multiple transforms + including mixing forward and inverse transforms. + @par + Earlier releases of the library provided separate radix-2 and radix-4 + algorithms that operated on floating-point data. These functions are still + provided but are deprecated. The older functions are slower and less general + than the new functions. + @par + An example of initialization of the constants for the arm_cfft_q31 function follows: + @code + const static arm_cfft_instance_q31 *S; + ... + switch (length) { + case 16: + S = &arm_cfft_sR_q31_len16; + break; + case 32: + S = &arm_cfft_sR_q31_len32; + break; + case 64: + S = &arm_cfft_sR_q31_len64; + break; + case 128: + S = &arm_cfft_sR_q31_len128; + break; + case 256: + S = &arm_cfft_sR_q31_len256; + break; + case 512: + S = &arm_cfft_sR_q31_len512; + break; + case 1024: + S = &arm_cfft_sR_q31_len1024; + break; + case 2048: + S = &arm_cfft_sR_q31_len2048; + break; + case 4096: + S = &arm_cfft_sR_q31_len4096; + break; + } + @endcode + + */ + +void arm_cfft_radix8by2_f32 (arm_cfft_instance_f32 * S, float32_t * p1) +{ + uint32_t L = S->fftLen; + float32_t * pCol1, * pCol2, * pMid1, * pMid2; + float32_t * p2 = p1 + L; + const float32_t * tw = (float32_t *) S->pTwiddle; + float32_t t1[4], t2[4], t3[4], t4[4], twR, twI; + float32_t m0, m1, m2, m3; + uint32_t l; + + pCol1 = p1; + pCol2 = p2; + + /* Define new length */ + L >>= 1; + + /* Initialize mid pointers */ + pMid1 = p1 + L; + pMid2 = p2 + L; + + /* do two dot Fourier transform */ + for (l = L >> 2; l > 0; l-- ) + { + t1[0] = p1[0]; + t1[1] = p1[1]; + t1[2] = p1[2]; + t1[3] = p1[3]; + + t2[0] = p2[0]; + t2[1] = p2[1]; + t2[2] = p2[2]; + t2[3] = p2[3]; + + t3[0] = pMid1[0]; + t3[1] = pMid1[1]; + t3[2] = pMid1[2]; + t3[3] = pMid1[3]; + + t4[0] = pMid2[0]; + t4[1] = pMid2[1]; + t4[2] = pMid2[2]; + t4[3] = pMid2[3]; + + *p1++ = t1[0] + t2[0]; + *p1++ = t1[1] + t2[1]; + *p1++ = t1[2] + t2[2]; + *p1++ = t1[3] + t2[3]; /* col 1 */ + + t2[0] = t1[0] - t2[0]; + t2[1] = t1[1] - t2[1]; + t2[2] = t1[2] - t2[2]; + t2[3] = t1[3] - t2[3]; /* for col 2 */ + + *pMid1++ = t3[0] + t4[0]; + *pMid1++ = t3[1] + t4[1]; + *pMid1++ = t3[2] + t4[2]; + *pMid1++ = t3[3] + t4[3]; /* col 1 */ + + t4[0] = t4[0] - t3[0]; + t4[1] = t4[1] - t3[1]; + t4[2] = t4[2] - t3[2]; + t4[3] = t4[3] - t3[3]; /* for col 2 */ + + twR = *tw++; + twI = *tw++; + + /* multiply by twiddle factors */ + m0 = t2[0] * twR; + m1 = t2[1] * twI; + m2 = t2[1] * twR; + m3 = t2[0] * twI; + + /* R = R * Tr - I * Ti */ + *p2++ = m0 + m1; + /* I = I * Tr + R * Ti */ + *p2++ = m2 - m3; + + /* use vertical symmetry */ + /* 0.9988 - 0.0491i <==> -0.0491 - 0.9988i */ + m0 = t4[0] * twI; + m1 = t4[1] * twR; + m2 = t4[1] * twI; + m3 = t4[0] * twR; + + *pMid2++ = m0 - m1; + *pMid2++ = m2 + m3; + + twR = *tw++; + twI = *tw++; + + m0 = t2[2] * twR; + m1 = t2[3] * twI; + m2 = t2[3] * twR; + m3 = t2[2] * twI; + + *p2++ = m0 + m1; + *p2++ = m2 - m3; + + m0 = t4[2] * twI; + m1 = t4[3] * twR; + m2 = t4[3] * twI; + m3 = t4[2] * twR; + + *pMid2++ = m0 - m1; + *pMid2++ = m2 + m3; + } + + /* first col */ + arm_radix8_butterfly_f32 (pCol1, L, (float32_t *) S->pTwiddle, 2U); + + /* second col */ + arm_radix8_butterfly_f32 (pCol2, L, (float32_t *) S->pTwiddle, 2U); +} + +void arm_cfft_radix8by4_f32 (arm_cfft_instance_f32 * S, float32_t * p1) +{ + uint32_t L = S->fftLen >> 1; + float32_t * pCol1, *pCol2, *pCol3, *pCol4, *pEnd1, *pEnd2, *pEnd3, *pEnd4; + const float32_t *tw2, *tw3, *tw4; + float32_t * p2 = p1 + L; + float32_t * p3 = p2 + L; + float32_t * p4 = p3 + L; + float32_t t2[4], t3[4], t4[4], twR, twI; + float32_t p1ap3_0, p1sp3_0, p1ap3_1, p1sp3_1; + float32_t m0, m1, m2, m3; + uint32_t l, twMod2, twMod3, twMod4; + + pCol1 = p1; /* points to real values by default */ + pCol2 = p2; + pCol3 = p3; + pCol4 = p4; + pEnd1 = p2 - 1; /* points to imaginary values by default */ + pEnd2 = p3 - 1; + pEnd3 = p4 - 1; + pEnd4 = pEnd3 + L; + + tw2 = tw3 = tw4 = (float32_t *) S->pTwiddle; + + L >>= 1; + + /* do four dot Fourier transform */ + + twMod2 = 2; + twMod3 = 4; + twMod4 = 6; + + /* TOP */ + p1ap3_0 = p1[0] + p3[0]; + p1sp3_0 = p1[0] - p3[0]; + p1ap3_1 = p1[1] + p3[1]; + p1sp3_1 = p1[1] - p3[1]; + + /* col 2 */ + t2[0] = p1sp3_0 + p2[1] - p4[1]; + t2[1] = p1sp3_1 - p2[0] + p4[0]; + /* col 3 */ + t3[0] = p1ap3_0 - p2[0] - p4[0]; + t3[1] = p1ap3_1 - p2[1] - p4[1]; + /* col 4 */ + t4[0] = p1sp3_0 - p2[1] + p4[1]; + t4[1] = p1sp3_1 + p2[0] - p4[0]; + /* col 1 */ + *p1++ = p1ap3_0 + p2[0] + p4[0]; + *p1++ = p1ap3_1 + p2[1] + p4[1]; + + /* Twiddle factors are ones */ + *p2++ = t2[0]; + *p2++ = t2[1]; + *p3++ = t3[0]; + *p3++ = t3[1]; + *p4++ = t4[0]; + *p4++ = t4[1]; + + tw2 += twMod2; + tw3 += twMod3; + tw4 += twMod4; + + for (l = (L - 2) >> 1; l > 0; l-- ) + { + /* TOP */ + p1ap3_0 = p1[0] + p3[0]; + p1sp3_0 = p1[0] - p3[0]; + p1ap3_1 = p1[1] + p3[1]; + p1sp3_1 = p1[1] - p3[1]; + /* col 2 */ + t2[0] = p1sp3_0 + p2[1] - p4[1]; + t2[1] = p1sp3_1 - p2[0] + p4[0]; + /* col 3 */ + t3[0] = p1ap3_0 - p2[0] - p4[0]; + t3[1] = p1ap3_1 - p2[1] - p4[1]; + /* col 4 */ + t4[0] = p1sp3_0 - p2[1] + p4[1]; + t4[1] = p1sp3_1 + p2[0] - p4[0]; + /* col 1 - top */ + *p1++ = p1ap3_0 + p2[0] + p4[0]; + *p1++ = p1ap3_1 + p2[1] + p4[1]; + + /* BOTTOM */ + p1ap3_1 = pEnd1[-1] + pEnd3[-1]; + p1sp3_1 = pEnd1[-1] - pEnd3[-1]; + p1ap3_0 = pEnd1[ 0] + pEnd3[0]; + p1sp3_0 = pEnd1[ 0] - pEnd3[0]; + /* col 2 */ + t2[2] = pEnd2[0] - pEnd4[0] + p1sp3_1; + t2[3] = pEnd1[0] - pEnd3[0] - pEnd2[-1] + pEnd4[-1]; + /* col 3 */ + t3[2] = p1ap3_1 - pEnd2[-1] - pEnd4[-1]; + t3[3] = p1ap3_0 - pEnd2[ 0] - pEnd4[ 0]; + /* col 4 */ + t4[2] = pEnd2[ 0] - pEnd4[ 0] - p1sp3_1; + t4[3] = pEnd4[-1] - pEnd2[-1] - p1sp3_0; + /* col 1 - Bottom */ + *pEnd1-- = p1ap3_0 + pEnd2[ 0] + pEnd4[ 0]; + *pEnd1-- = p1ap3_1 + pEnd2[-1] + pEnd4[-1]; + + /* COL 2 */ + /* read twiddle factors */ + twR = *tw2++; + twI = *tw2++; + /* multiply by twiddle factors */ + /* let Z1 = a + i(b), Z2 = c + i(d) */ + /* => Z1 * Z2 = (a*c - b*d) + i(b*c + a*d) */ + + /* Top */ + m0 = t2[0] * twR; + m1 = t2[1] * twI; + m2 = t2[1] * twR; + m3 = t2[0] * twI; + + *p2++ = m0 + m1; + *p2++ = m2 - m3; + /* use vertical symmetry col 2 */ + /* 0.9997 - 0.0245i <==> 0.0245 - 0.9997i */ + /* Bottom */ + m0 = t2[3] * twI; + m1 = t2[2] * twR; + m2 = t2[2] * twI; + m3 = t2[3] * twR; + + *pEnd2-- = m0 - m1; + *pEnd2-- = m2 + m3; + + /* COL 3 */ + twR = tw3[0]; + twI = tw3[1]; + tw3 += twMod3; + /* Top */ + m0 = t3[0] * twR; + m1 = t3[1] * twI; + m2 = t3[1] * twR; + m3 = t3[0] * twI; + + *p3++ = m0 + m1; + *p3++ = m2 - m3; + /* use vertical symmetry col 3 */ + /* 0.9988 - 0.0491i <==> -0.9988 - 0.0491i */ + /* Bottom */ + m0 = -t3[3] * twR; + m1 = t3[2] * twI; + m2 = t3[2] * twR; + m3 = t3[3] * twI; + + *pEnd3-- = m0 - m1; + *pEnd3-- = m3 - m2; + + /* COL 4 */ + twR = tw4[0]; + twI = tw4[1]; + tw4 += twMod4; + /* Top */ + m0 = t4[0] * twR; + m1 = t4[1] * twI; + m2 = t4[1] * twR; + m3 = t4[0] * twI; + + *p4++ = m0 + m1; + *p4++ = m2 - m3; + /* use vertical symmetry col 4 */ + /* 0.9973 - 0.0736i <==> -0.0736 + 0.9973i */ + /* Bottom */ + m0 = t4[3] * twI; + m1 = t4[2] * twR; + m2 = t4[2] * twI; + m3 = t4[3] * twR; + + *pEnd4-- = m0 - m1; + *pEnd4-- = m2 + m3; + } + + /* MIDDLE */ + /* Twiddle factors are */ + /* 1.0000 0.7071-0.7071i -1.0000i -0.7071-0.7071i */ + p1ap3_0 = p1[0] + p3[0]; + p1sp3_0 = p1[0] - p3[0]; + p1ap3_1 = p1[1] + p3[1]; + p1sp3_1 = p1[1] - p3[1]; + + /* col 2 */ + t2[0] = p1sp3_0 + p2[1] - p4[1]; + t2[1] = p1sp3_1 - p2[0] + p4[0]; + /* col 3 */ + t3[0] = p1ap3_0 - p2[0] - p4[0]; + t3[1] = p1ap3_1 - p2[1] - p4[1]; + /* col 4 */ + t4[0] = p1sp3_0 - p2[1] + p4[1]; + t4[1] = p1sp3_1 + p2[0] - p4[0]; + /* col 1 - Top */ + *p1++ = p1ap3_0 + p2[0] + p4[0]; + *p1++ = p1ap3_1 + p2[1] + p4[1]; + + /* COL 2 */ + twR = tw2[0]; + twI = tw2[1]; + + m0 = t2[0] * twR; + m1 = t2[1] * twI; + m2 = t2[1] * twR; + m3 = t2[0] * twI; + + *p2++ = m0 + m1; + *p2++ = m2 - m3; + /* COL 3 */ + twR = tw3[0]; + twI = tw3[1]; + + m0 = t3[0] * twR; + m1 = t3[1] * twI; + m2 = t3[1] * twR; + m3 = t3[0] * twI; + + *p3++ = m0 + m1; + *p3++ = m2 - m3; + /* COL 4 */ + twR = tw4[0]; + twI = tw4[1]; + + m0 = t4[0] * twR; + m1 = t4[1] * twI; + m2 = t4[1] * twR; + m3 = t4[0] * twI; + + *p4++ = m0 + m1; + *p4++ = m2 - m3; + + /* first col */ + arm_radix8_butterfly_f32 (pCol1, L, (float32_t *) S->pTwiddle, 4U); + + /* second col */ + arm_radix8_butterfly_f32 (pCol2, L, (float32_t *) S->pTwiddle, 4U); + + /* third col */ + arm_radix8_butterfly_f32 (pCol3, L, (float32_t *) S->pTwiddle, 4U); + + /* fourth col */ + arm_radix8_butterfly_f32 (pCol4, L, (float32_t *) S->pTwiddle, 4U); +} + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Processing function for the floating-point complex FFT. + @param[in] S points to an instance of the floating-point CFFT structure + @param[in,out] p1 points to the complex data buffer of size 2*fftLen. Processing occurs in-place + @param[in] ifftFlag flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return none + */ + +void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag) +{ + uint32_t L = S->fftLen, l; + float32_t invL, * pSrc; + + if (ifftFlag == 1U) + { + /* Conjugate input data */ + pSrc = p1 + 1; + for (l = 0; l < L; l++) + { + *pSrc = -*pSrc; + pSrc += 2; + } + } + + switch (L) + { + case 16: + case 128: + case 1024: + arm_cfft_radix8by2_f32 ( (arm_cfft_instance_f32 *) S, p1); + break; + case 32: + case 256: + case 2048: + arm_cfft_radix8by4_f32 ( (arm_cfft_instance_f32 *) S, p1); + break; + case 64: + case 512: + case 4096: + arm_radix8_butterfly_f32 ( p1, L, (float32_t *) S->pTwiddle, 1); + break; + } + + if ( bitReverseFlag ) + arm_bitreversal_32 ((uint32_t*) p1, S->bitRevLength, S->pBitRevTable); + + if (ifftFlag == 1U) + { + invL = 1.0f / (float32_t)L; + + /* Conjugate and scale output data */ + pSrc = p1; + for (l= 0; l < L; l++) + { + *pSrc++ *= invL ; + *pSrc = -(*pSrc) * invL; + pSrc++; + } + } +} + +/** + @} end of ComplexFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_q15.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_q15.c new file mode 100644 index 0000000..28ad1e1 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_q15.c @@ -0,0 +1,332 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_q15.c + * Description: Combined Radix Decimation in Q15 Frequency CFFT processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +extern void arm_radix4_butterfly_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pCoef, + uint32_t twidCoefModifier); + +extern void arm_radix4_butterfly_inverse_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pCoef, + uint32_t twidCoefModifier); + +extern void arm_bitreversal_16( + uint16_t * pSrc, + const uint16_t bitRevLen, + const uint16_t * pBitRevTable); + +void arm_cfft_radix4by2_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pCoef); + +void arm_cfft_radix4by2_inverse_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pCoef); + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Processing function for Q15 complex FFT. + @param[in] S points to an instance of Q15 CFFT structure + @param[in,out] p1 points to the complex data buffer of size 2*fftLen. Processing occurs in-place + @param[in] ifftFlag flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return none + */ + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag) +{ + uint32_t L = S->fftLen; + + if (ifftFlag == 1U) + { + switch (L) + { + case 16: + case 64: + case 256: + case 1024: + case 4096: + arm_radix4_butterfly_inverse_q15 ( p1, L, (q15_t*)S->pTwiddle, 1 ); + break; + + case 32: + case 128: + case 512: + case 2048: + arm_cfft_radix4by2_inverse_q15 ( p1, L, S->pTwiddle ); + break; + } + } + else + { + switch (L) + { + case 16: + case 64: + case 256: + case 1024: + case 4096: + arm_radix4_butterfly_q15 ( p1, L, (q15_t*)S->pTwiddle, 1 ); + break; + + case 32: + case 128: + case 512: + case 2048: + arm_cfft_radix4by2_q15 ( p1, L, S->pTwiddle ); + break; + } + } + + if ( bitReverseFlag ) + arm_bitreversal_16 ((uint16_t*) p1, S->bitRevLength, S->pBitRevTable); +} + +/** + @} end of ComplexFFT group + */ + +void arm_cfft_radix4by2_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pCoef) +{ + uint32_t i; + uint32_t n2; + q15_t p0, p1, p2, p3; +#if defined (ARM_MATH_DSP) + q31_t T, S, R; + q31_t coeff, out1, out2; + const q15_t *pC = pCoef; + q15_t *pSi = pSrc; + q15_t *pSl = pSrc + fftLen; +#else + uint32_t l; + q15_t xt, yt, cosVal, sinVal; +#endif + + n2 = fftLen >> 1U; + +#if defined (ARM_MATH_DSP) + + for (i = n2; i > 0; i--) + { + coeff = read_q15x2_ia ((q15_t **) &pC); + + T = read_q15x2 (pSi); + T = __SHADD16(T, 0); /* this is just a SIMD arithmetic shift right by 1 */ + + S = read_q15x2 (pSl); + S = __SHADD16(S, 0); /* this is just a SIMD arithmetic shift right by 1 */ + + R = __QSUB16(T, S); + + write_q15x2_ia (&pSi, __SHADD16(T, S)); + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUAD(coeff, R) >> 16U; + out2 = __SMUSDX(coeff, R); +#else + out1 = __SMUSDX(R, coeff) >> 16U; + out2 = __SMUAD(coeff, R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + write_q15x2_ia (&pSl, (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + } + +#else /* #if defined (ARM_MATH_DSP) */ + + for (i = 0; i < n2; i++) + { + cosVal = pCoef[2 * i]; + sinVal = pCoef[2 * i + 1]; + + l = i + n2; + + xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U); + pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U; + + yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U); + pSrc[2 * i + 1] = ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U; + + pSrc[2 * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16U)) + + ((int16_t) (((q31_t) yt * sinVal) >> 16U)) ); + + pSrc[2 * l + 1] = (((int16_t) (((q31_t) yt * cosVal) >> 16U)) - + ((int16_t) (((q31_t) xt * sinVal) >> 16U)) ); + } + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* first col */ + arm_radix4_butterfly_q15( pSrc, n2, (q15_t*)pCoef, 2U); + + /* second col */ + arm_radix4_butterfly_q15( pSrc + fftLen, n2, (q15_t*)pCoef, 2U); + + n2 = fftLen >> 1U; + for (i = 0; i < n2; i++) + { + p0 = pSrc[4 * i + 0]; + p1 = pSrc[4 * i + 1]; + p2 = pSrc[4 * i + 2]; + p3 = pSrc[4 * i + 3]; + + p0 <<= 1U; + p1 <<= 1U; + p2 <<= 1U; + p3 <<= 1U; + + pSrc[4 * i + 0] = p0; + pSrc[4 * i + 1] = p1; + pSrc[4 * i + 2] = p2; + pSrc[4 * i + 3] = p3; + } + +} + +void arm_cfft_radix4by2_inverse_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pCoef) +{ + uint32_t i; + uint32_t n2; + q15_t p0, p1, p2, p3; +#if defined (ARM_MATH_DSP) + q31_t T, S, R; + q31_t coeff, out1, out2; + const q15_t *pC = pCoef; + q15_t *pSi = pSrc; + q15_t *pSl = pSrc + fftLen; +#else + uint32_t l; + q15_t xt, yt, cosVal, sinVal; +#endif + + n2 = fftLen >> 1U; + +#if defined (ARM_MATH_DSP) + + for (i = n2; i > 0; i--) + { + coeff = read_q15x2_ia ((q15_t **) &pC); + + T = read_q15x2 (pSi); + T = __SHADD16(T, 0); /* this is just a SIMD arithmetic shift right by 1 */ + + S = read_q15x2 (pSl); + S = __SHADD16(S, 0); /* this is just a SIMD arithmetic shift right by 1 */ + + R = __QSUB16(T, S); + + write_q15x2_ia (&pSi, __SHADD16(T, S)); + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUSD(coeff, R) >> 16U; + out2 = __SMUADX(coeff, R); +#else + out1 = __SMUADX(R, coeff) >> 16U; + out2 = __SMUSD(__QSUB(0, coeff), R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + write_q15x2_ia (&pSl, (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + } + +#else /* #if defined (ARM_MATH_DSP) */ + + for (i = 0; i < n2; i++) + { + cosVal = pCoef[2 * i]; + sinVal = pCoef[2 * i + 1]; + + l = i + n2; + + xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U); + pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U; + + yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U); + pSrc[2 * i + 1] = ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U; + + pSrc[2 * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16U)) - + ((int16_t) (((q31_t) yt * sinVal) >> 16U)) ); + + pSrc[2 * l + 1] = (((int16_t) (((q31_t) yt * cosVal) >> 16U)) + + ((int16_t) (((q31_t) xt * sinVal) >> 16U)) ); + } + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* first col */ + arm_radix4_butterfly_inverse_q15( pSrc, n2, (q15_t*)pCoef, 2U); + + /* second col */ + arm_radix4_butterfly_inverse_q15( pSrc + fftLen, n2, (q15_t*)pCoef, 2U); + + n2 = fftLen >> 1U; + for (i = 0; i < n2; i++) + { + p0 = pSrc[4 * i + 0]; + p1 = pSrc[4 * i + 1]; + p2 = pSrc[4 * i + 2]; + p3 = pSrc[4 * i + 3]; + + p0 <<= 1U; + p1 <<= 1U; + p2 <<= 1U; + p3 <<= 1U; + + pSrc[4 * i + 0] = p0; + pSrc[4 * i + 1] = p1; + pSrc[4 * i + 2] = p2; + pSrc[4 * i + 3] = p3; + } +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_q31.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_q31.c new file mode 100644 index 0000000..701ac95 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_q31.c @@ -0,0 +1,254 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_q31.c + * Description: Combined Radix Decimation in Frequency CFFT fixed point processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +extern void arm_radix4_butterfly_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef, + uint32_t twidCoefModifier); + +extern void arm_radix4_butterfly_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef, + uint32_t twidCoefModifier); + +extern void arm_bitreversal_32( + uint32_t * pSrc, + const uint16_t bitRevLen, + const uint16_t * pBitRevTable); + +void arm_cfft_radix4by2_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef); + +void arm_cfft_radix4by2_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef); + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Processing function for the Q31 complex FFT. + @param[in] S points to an instance of the fixed-point CFFT structure + @param[in,out] p1 points to the complex data buffer of size 2*fftLen. Processing occurs in-place + @param[in] ifftFlag flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return none + */ + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag) +{ + uint32_t L = S->fftLen; + + if (ifftFlag == 1U) + { + switch (L) + { + case 16: + case 64: + case 256: + case 1024: + case 4096: + arm_radix4_butterfly_inverse_q31 ( p1, L, (q31_t*)S->pTwiddle, 1 ); + break; + + case 32: + case 128: + case 512: + case 2048: + arm_cfft_radix4by2_inverse_q31 ( p1, L, S->pTwiddle ); + break; + } + } + else + { + switch (L) + { + case 16: + case 64: + case 256: + case 1024: + case 4096: + arm_radix4_butterfly_q31 ( p1, L, (q31_t*)S->pTwiddle, 1 ); + break; + + case 32: + case 128: + case 512: + case 2048: + arm_cfft_radix4by2_q31 ( p1, L, S->pTwiddle ); + break; + } + } + + if ( bitReverseFlag ) + arm_bitreversal_32 ((uint32_t*) p1, S->bitRevLength, S->pBitRevTable); +} + +/** + @} end of ComplexFFT group + */ + +void arm_cfft_radix4by2_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef) +{ + uint32_t i, l; + uint32_t n2; + q31_t xt, yt, cosVal, sinVal; + q31_t p0, p1; + + n2 = fftLen >> 1U; + for (i = 0; i < n2; i++) + { + cosVal = pCoef[2 * i]; + sinVal = pCoef[2 * i + 1]; + + l = i + n2; + + xt = (pSrc[2 * i] >> 2U) - (pSrc[2 * l] >> 2U); + pSrc[2 * i] = (pSrc[2 * i] >> 2U) + (pSrc[2 * l] >> 2U); + + yt = (pSrc[2 * i + 1] >> 2U) - (pSrc[2 * l + 1] >> 2U); + pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2U) + (pSrc[2 * i + 1] >> 2U); + + mult_32x32_keep32_R(p0, xt, cosVal); + mult_32x32_keep32_R(p1, yt, cosVal); + multAcc_32x32_keep32_R(p0, yt, sinVal); + multSub_32x32_keep32_R(p1, xt, sinVal); + + pSrc[2 * l] = p0 << 1; + pSrc[2 * l + 1] = p1 << 1; + } + + /* first col */ + arm_radix4_butterfly_q31 (pSrc, n2, (q31_t*)pCoef, 2U); + + /* second col */ + arm_radix4_butterfly_q31 (pSrc + fftLen, n2, (q31_t*)pCoef, 2U); + + n2 = fftLen >> 1U; + for (i = 0; i < n2; i++) + { + p0 = pSrc[4 * i + 0]; + p1 = pSrc[4 * i + 1]; + xt = pSrc[4 * i + 2]; + yt = pSrc[4 * i + 3]; + + p0 <<= 1U; + p1 <<= 1U; + xt <<= 1U; + yt <<= 1U; + + pSrc[4 * i + 0] = p0; + pSrc[4 * i + 1] = p1; + pSrc[4 * i + 2] = xt; + pSrc[4 * i + 3] = yt; + } + +} + +void arm_cfft_radix4by2_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef) +{ + uint32_t i, l; + uint32_t n2; + q31_t xt, yt, cosVal, sinVal; + q31_t p0, p1; + + n2 = fftLen >> 1U; + for (i = 0; i < n2; i++) + { + cosVal = pCoef[2 * i]; + sinVal = pCoef[2 * i + 1]; + + l = i + n2; + + xt = (pSrc[2 * i] >> 2U) - (pSrc[2 * l] >> 2U); + pSrc[2 * i] = (pSrc[2 * i] >> 2U) + (pSrc[2 * l] >> 2U); + + yt = (pSrc[2 * i + 1] >> 2U) - (pSrc[2 * l + 1] >> 2U); + pSrc[2 * i + 1] = (pSrc[2 * l + 1] >> 2U) + (pSrc[2 * i + 1] >> 2U); + + mult_32x32_keep32_R(p0, xt, cosVal); + mult_32x32_keep32_R(p1, yt, cosVal); + multSub_32x32_keep32_R(p0, yt, sinVal); + multAcc_32x32_keep32_R(p1, xt, sinVal); + + pSrc[2 * l] = p0 << 1U; + pSrc[2 * l + 1] = p1 << 1U; + } + + /* first col */ + arm_radix4_butterfly_inverse_q31( pSrc, n2, (q31_t*)pCoef, 2U); + + /* second col */ + arm_radix4_butterfly_inverse_q31( pSrc + fftLen, n2, (q31_t*)pCoef, 2U); + + n2 = fftLen >> 1U; + for (i = 0; i < n2; i++) + { + p0 = pSrc[4 * i + 0]; + p1 = pSrc[4 * i + 1]; + xt = pSrc[4 * i + 2]; + yt = pSrc[4 * i + 3]; + + p0 <<= 1U; + p1 <<= 1U; + xt <<= 1U; + yt <<= 1U; + + pSrc[4 * i + 0] = p0; + pSrc[4 * i + 1] = p1; + pSrc[4 * i + 2] = xt; + pSrc[4 * i + 3] = yt; + } +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_f32.c new file mode 100644 index 0000000..f75e329 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_f32.c @@ -0,0 +1,470 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix2_f32.c + * Description: Radix-2 Decimation in Frequency CFFT & CIFFT Floating point processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +void arm_radix2_butterfly_f32( + float32_t * pSrc, + uint32_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier); + +void arm_radix2_butterfly_inverse_f32( + float32_t * pSrc, + uint32_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier, + float32_t onebyfftLen); + +extern void arm_bitreversal_f32( + float32_t * pSrc, + uint16_t fftSize, + uint16_t bitRevFactor, + const uint16_t * pBitRevTab); + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Radix-2 CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed in the future + @param[in] S points to an instance of the floating-point Radix-2 CFFT/CIFFT structure + @param[in,out] pSrc points to the complex data buffer of size 2*fftLen. Processing occurs in-place + @return none + */ + +void arm_cfft_radix2_f32( +const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc) +{ + + if (S->ifftFlag == 1U) + { + /* Complex IFFT radix-2 */ + arm_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle, + S->twidCoefModifier, S->onebyfftLen); + } + else + { + /* Complex FFT radix-2 */ + arm_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle, + S->twidCoefModifier); + } + + if (S->bitReverseFlag == 1U) + { + /* Bit Reversal */ + arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable); + } + +} + + +/** + @} end of ComplexFFT group + */ + + + +/* ---------------------------------------------------------------------- + ** Internal helper function used by the FFTs + ** ------------------------------------------------------------------- */ + +/** + brief Core function for the floating-point CFFT butterfly process. + param[in,out] pSrc points to in-place buffer of floating-point data type + param[in] fftLen length of the FFT + param[in] pCoef points to twiddle coefficient buffer + param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table + return none + */ + +void arm_radix2_butterfly_f32( + float32_t * pSrc, + uint32_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier) +{ + + uint32_t i, j, k, l; + uint32_t n1, n2, ia; + float32_t xt, yt, cosVal, sinVal; + float32_t p0, p1, p2, p3; + float32_t a0, a1; + +#if defined (ARM_MATH_DSP) + + /* Initializations for the first stage */ + n2 = fftLen >> 1; + ia = 0; + i = 0; + + // loop for groups + for (k = n2; k > 0; k--) + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + + /* Twiddle coefficients index modifier */ + ia += twidCoefModifier; + + /* index calculation for the input as, */ + /* pSrc[i + 0], pSrc[i + fftLen/1] */ + l = i + n2; + + /* Butterfly implementation */ + a0 = pSrc[2 * i] + pSrc[2 * l]; + xt = pSrc[2 * i] - pSrc[2 * l]; + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; + + p0 = xt * cosVal; + p1 = yt * sinVal; + p2 = yt * cosVal; + p3 = xt * sinVal; + + pSrc[2 * i] = a0; + pSrc[2 * i + 1] = a1; + + pSrc[2 * l] = p0 + p1; + pSrc[2 * l + 1] = p2 - p3; + + i++; + } // groups loop end + + twidCoefModifier <<= 1U; + + // loop for stage + for (k = n2; k > 2; k = k >> 1) + { + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + // loop for groups + j = 0; + do + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia += twidCoefModifier; + + // loop for butterfly + i = j; + do + { + l = i + n2; + a0 = pSrc[2 * i] + pSrc[2 * l]; + xt = pSrc[2 * i] - pSrc[2 * l]; + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; + + p0 = xt * cosVal; + p1 = yt * sinVal; + p2 = yt * cosVal; + p3 = xt * sinVal; + + pSrc[2 * i] = a0; + pSrc[2 * i + 1] = a1; + + pSrc[2 * l] = p0 + p1; + pSrc[2 * l + 1] = p2 - p3; + + i += n1; + } while ( i < fftLen ); // butterfly loop end + j++; + } while ( j < n2); // groups loop end + twidCoefModifier <<= 1U; + } // stages loop end + + // loop for butterfly + for (i = 0; i < fftLen; i += 2) + { + a0 = pSrc[2 * i] + pSrc[2 * i + 2]; + xt = pSrc[2 * i] - pSrc[2 * i + 2]; + + yt = pSrc[2 * i + 1] - pSrc[2 * i + 3]; + a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1]; + + pSrc[2 * i] = a0; + pSrc[2 * i + 1] = a1; + pSrc[2 * i + 2] = xt; + pSrc[2 * i + 3] = yt; + } // groups loop end + +#else /* #if defined (ARM_MATH_DSP) */ + + n2 = fftLen; + + // loop for stage + for (k = fftLen; k > 1; k = k >> 1) + { + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + // loop for groups + j = 0; + do + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia += twidCoefModifier; + + // loop for butterfly + i = j; + do + { + l = i + n2; + a0 = pSrc[2 * i] + pSrc[2 * l]; + xt = pSrc[2 * i] - pSrc[2 * l]; + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; + + p0 = xt * cosVal; + p1 = yt * sinVal; + p2 = yt * cosVal; + p3 = xt * sinVal; + + pSrc[2 * i] = a0; + pSrc[2 * i + 1] = a1; + + pSrc[2 * l] = p0 + p1; + pSrc[2 * l + 1] = p2 - p3; + + i += n1; + } while (i < fftLen); + j++; + } while (j < n2); + twidCoefModifier <<= 1U; + } + +#endif /* #if defined (ARM_MATH_DSP) */ + +} + + +void arm_radix2_butterfly_inverse_f32( + float32_t * pSrc, + uint32_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier, + float32_t onebyfftLen) +{ + + uint32_t i, j, k, l; + uint32_t n1, n2, ia; + float32_t xt, yt, cosVal, sinVal; + float32_t p0, p1, p2, p3; + float32_t a0, a1; + +#if defined (ARM_MATH_DSP) + + n2 = fftLen >> 1; + ia = 0; + + // loop for groups + for (i = 0; i < n2; i++) + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia += twidCoefModifier; + + l = i + n2; + a0 = pSrc[2 * i] + pSrc[2 * l]; + xt = pSrc[2 * i] - pSrc[2 * l]; + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; + + p0 = xt * cosVal; + p1 = yt * sinVal; + p2 = yt * cosVal; + p3 = xt * sinVal; + + pSrc[2 * i] = a0; + pSrc[2 * i + 1] = a1; + + pSrc[2 * l] = p0 - p1; + pSrc[2 * l + 1] = p2 + p3; + } // groups loop end + + twidCoefModifier <<= 1U; + + // loop for stage + for (k = fftLen / 2; k > 2; k = k >> 1) + { + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + // loop for groups + j = 0; + do + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia += twidCoefModifier; + + // loop for butterfly + i = j; + do + { + l = i + n2; + a0 = pSrc[2 * i] + pSrc[2 * l]; + xt = pSrc[2 * i] - pSrc[2 * l]; + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; + + p0 = xt * cosVal; + p1 = yt * sinVal; + p2 = yt * cosVal; + p3 = xt * sinVal; + + pSrc[2 * i] = a0; + pSrc[2 * i + 1] = a1; + + pSrc[2 * l] = p0 - p1; + pSrc[2 * l + 1] = p2 + p3; + + i += n1; + } while ( i < fftLen ); // butterfly loop end + j++; + } while (j < n2); // groups loop end + + twidCoefModifier <<= 1U; + } // stages loop end + + // loop for butterfly + for (i = 0; i < fftLen; i += 2) + { + a0 = pSrc[2 * i] + pSrc[2 * i + 2]; + xt = pSrc[2 * i] - pSrc[2 * i + 2]; + + a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1]; + yt = pSrc[2 * i + 1] - pSrc[2 * i + 3]; + + p0 = a0 * onebyfftLen; + p2 = xt * onebyfftLen; + p1 = a1 * onebyfftLen; + p3 = yt * onebyfftLen; + + pSrc[2 * i] = p0; + pSrc[2 * i + 1] = p1; + pSrc[2 * i + 2] = p2; + pSrc[2 * i + 3] = p3; + } // butterfly loop end + +#else /* #if defined (ARM_MATH_DSP) */ + + n2 = fftLen; + + // loop for stage + for (k = fftLen; k > 2; k = k >> 1) + { + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + // loop for groups + j = 0; + do + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + // loop for butterfly + i = j; + do + { + l = i + n2; + a0 = pSrc[2 * i] + pSrc[2 * l]; + xt = pSrc[2 * i] - pSrc[2 * l]; + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; + + p0 = xt * cosVal; + p1 = yt * sinVal; + p2 = yt * cosVal; + p3 = xt * sinVal; + + pSrc[2 * i] = a0; + pSrc[2 * i + 1] = a1; + + pSrc[2 * l] = p0 - p1; + pSrc[2 * l + 1] = p2 + p3; + + i += n1; + } while ( i < fftLen ); // butterfly loop end + j++; + } while ( j < n2 ); // groups loop end + + twidCoefModifier = twidCoefModifier << 1U; + } // stages loop end + + n1 = n2; + n2 = n2 >> 1; + + // loop for butterfly + for (i = 0; i < fftLen; i += n1) + { + l = i + n2; + + a0 = pSrc[2 * i] + pSrc[2 * l]; + xt = pSrc[2 * i] - pSrc[2 * l]; + + a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1]; + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + + p0 = a0 * onebyfftLen; + p2 = xt * onebyfftLen; + p1 = a1 * onebyfftLen; + p3 = yt * onebyfftLen; + + pSrc[2 * i] = p0; + pSrc[2 * l] = p2; + + pSrc[2 * i + 1] = p1; + pSrc[2 * l + 1] = p3; + } // butterfly loop end + +#endif /* #if defined (ARM_MATH_DSP) */ + +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_f32.c new file mode 100644 index 0000000..417ad91 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_f32.c @@ -0,0 +1,197 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix2_init_f32.c + * Description: Radix-2 Decimation in Frequency Floating-point CFFT & CIFFT Initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Initialization function for the floating-point CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed in the future. + @param[in,out] S points to an instance of the floating-point CFFT/CIFFT structure + @param[in] fftLen length of the FFT + @param[in] ifftFlag flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : fftLen is not a supported length + + @par Details + The parameter ifftFlag controls whether a forward or inverse transform is computed. + Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated + @par + The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. + Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. + @par + The parameter fftLen Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024. + @par + This Function also initializes Twiddle factor table pointer and Bit reversal table pointer. +*/ + +arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag) +{ + /* Initialise the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + + /* Initialise the FFT length */ + S->fftLen = fftLen; + + /* Initialise the Twiddle coefficient pointer */ + S->pTwiddle = (float32_t *) twiddleCoef; + + /* Initialise the Flag for selection of CFFT or CIFFT */ + S->ifftFlag = ifftFlag; + + /* Initialise the Flag for calculation Bit reversal or not */ + S->bitReverseFlag = bitReverseFlag; + + /* Initializations of structure parameters depending on the FFT length */ + switch (S->fftLen) + { + + case 4096U: + /* Initializations of structure parameters for 4096 point FFT */ + + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 1U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 1U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) armBitRevTable; + /* Initialise the 1/fftLen Value */ + S->onebyfftLen = 0.000244140625; + break; + + case 2048U: + /* Initializations of structure parameters for 2048 point FFT */ + + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 2U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 2U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) & armBitRevTable[1]; + /* Initialise the 1/fftLen Value */ + S->onebyfftLen = 0.00048828125; + break; + + case 1024U: + /* Initializations of structure parameters for 1024 point FFT */ + + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 4U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 4U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) & armBitRevTable[3]; + /* Initialise the 1/fftLen Value */ + S->onebyfftLen = 0.0009765625f; + break; + + case 512U: + /* Initializations of structure parameters for 512 point FFT */ + + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 8U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 8U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) & armBitRevTable[7]; + /* Initialise the 1/fftLen Value */ + S->onebyfftLen = 0.001953125; + break; + + case 256U: + /* Initializations of structure parameters for 256 point FFT */ + S->twidCoefModifier = 16U; + S->bitRevFactor = 16U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[15]; + S->onebyfftLen = 0.00390625f; + break; + + case 128U: + /* Initializations of structure parameters for 128 point FFT */ + S->twidCoefModifier = 32U; + S->bitRevFactor = 32U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[31]; + S->onebyfftLen = 0.0078125; + break; + + case 64U: + /* Initializations of structure parameters for 64 point FFT */ + S->twidCoefModifier = 64U; + S->bitRevFactor = 64U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[63]; + S->onebyfftLen = 0.015625f; + break; + + case 32U: + /* Initializations of structure parameters for 64 point FFT */ + S->twidCoefModifier = 128U; + S->bitRevFactor = 128U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[127]; + S->onebyfftLen = 0.03125; + break; + + case 16U: + /* Initializations of structure parameters for 16 point FFT */ + S->twidCoefModifier = 256U; + S->bitRevFactor = 256U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[255]; + S->onebyfftLen = 0.0625f; + break; + + + default: + /* Reporting argument error if fftSize is not valid value */ + status = ARM_MATH_ARGUMENT_ERROR; + break; + } + + return (status); +} + +/** + @} end of ComplexFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_q15.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_q15.c new file mode 100644 index 0000000..3d865d0 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_q15.c @@ -0,0 +1,182 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix2_init_q15.c + * Description: Radix-2 Decimation in Frequency Q15 FFT & IFFT initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupTransforms + */ + + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Initialization function for the Q15 CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed + @param[in,out] S points to an instance of the Q15 CFFT/CIFFT structure. + @param[in] fftLen length of the FFT. + @param[in] ifftFlag flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : fftLen is not a supported length + + @par Details + The parameter ifftFlag controls whether a forward or inverse transform is computed. + Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated + @par + The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. + Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. + @par + The parameter fftLen Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024. + @par + This Function also initializes Twiddle factor table pointer and Bit reversal table pointer. +*/ + +arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag) +{ + /* Initialise the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + + /* Initialise the FFT length */ + S->fftLen = fftLen; + + /* Initialise the Twiddle coefficient pointer */ + S->pTwiddle = (q15_t *) twiddleCoef_4096_q15; + /* Initialise the Flag for selection of CFFT or CIFFT */ + S->ifftFlag = ifftFlag; + /* Initialise the Flag for calculation Bit reversal or not */ + S->bitReverseFlag = bitReverseFlag; + + /* Initializations of structure parameters depending on the FFT length */ + switch (S->fftLen) + { + case 4096U: + /* Initializations of structure parameters for 4096 point FFT */ + + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 1U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 1U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) armBitRevTable; + + break; + + case 2048U: + /* Initializations of structure parameters for 2048 point FFT */ + + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 2U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 2U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) & armBitRevTable[1]; + + break; + + case 1024U: + /* Initializations of structure parameters for 1024 point FFT */ + S->twidCoefModifier = 4U; + S->bitRevFactor = 4U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[3]; + + break; + + case 512U: + /* Initializations of structure parameters for 512 point FFT */ + S->twidCoefModifier = 8U; + S->bitRevFactor = 8U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[7]; + + break; + + case 256U: + /* Initializations of structure parameters for 256 point FFT */ + S->twidCoefModifier = 16U; + S->bitRevFactor = 16U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[15]; + + break; + + case 128U: + /* Initializations of structure parameters for 128 point FFT */ + S->twidCoefModifier = 32U; + S->bitRevFactor = 32U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[31]; + + break; + + case 64U: + /* Initializations of structure parameters for 64 point FFT */ + S->twidCoefModifier = 64U; + S->bitRevFactor = 64U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[63]; + + break; + + case 32U: + /* Initializations of structure parameters for 32 point FFT */ + S->twidCoefModifier = 128U; + S->bitRevFactor = 128U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[127]; + + break; + + case 16U: + /* Initializations of structure parameters for 16 point FFT */ + S->twidCoefModifier = 256U; + S->bitRevFactor = 256U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[255]; + + break; + + default: + /* Reporting argument error if fftSize is not valid value */ + status = ARM_MATH_ARGUMENT_ERROR; + break; + } + + return (status); +} + +/** + @} end of ComplexFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_q31.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_q31.c new file mode 100644 index 0000000..f4a20d6 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_init_q31.c @@ -0,0 +1,179 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix2_init_q31.c + * Description: Radix-2 Decimation in Frequency Fixed-point CFFT & CIFFT Initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Initialization function for the Q31 CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed in the future. + @param[in,out] S points to an instance of the Q31 CFFT/CIFFT structure + @param[in] fftLen length of the FFT + @param[in] ifftFlag flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : fftLen is not a supported length + + @par Details + The parameter ifftFlag controls whether a forward or inverse transform is computed. + Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated + @par + The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. + Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. + @par + The parameter fftLen Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024. + @par + This Function also initializes Twiddle factor table pointer and Bit reversal table pointer. +*/ + +arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag) +{ + /* Initialise the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + + /* Initialise the FFT length */ + S->fftLen = fftLen; + + /* Initialise the Twiddle coefficient pointer */ + S->pTwiddle = (q31_t *) twiddleCoef_4096_q31; + + /* Initialise the Flag for selection of CFFT or CIFFT */ + S->ifftFlag = ifftFlag; + + /* Initialise the Flag for calculation Bit reversal or not */ + S->bitReverseFlag = bitReverseFlag; + + /* Initializations of Instance structure depending on the FFT length */ + switch (S->fftLen) + { + /* Initializations of structure parameters for 4096 point FFT */ + case 4096U: + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 1U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 1U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) armBitRevTable; + break; + + /* Initializations of structure parameters for 2048 point FFT */ + case 2048U: + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 2U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 2U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) & armBitRevTable[1]; + break; + + /* Initializations of structure parameters for 1024 point FFT */ + case 1024U: + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 4U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 4U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) & armBitRevTable[3]; + break; + + /* Initializations of structure parameters for 512 point FFT */ + case 512U: + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 8U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 8U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) & armBitRevTable[7]; + break; + + case 256U: + /* Initializations of structure parameters for 256 point FFT */ + S->twidCoefModifier = 16U; + S->bitRevFactor = 16U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[15]; + break; + + case 128U: + /* Initializations of structure parameters for 128 point FFT */ + S->twidCoefModifier = 32U; + S->bitRevFactor = 32U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[31]; + break; + + case 64U: + /* Initializations of structure parameters for 64 point FFT */ + S->twidCoefModifier = 64U; + S->bitRevFactor = 64U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[63]; + break; + + case 32U: + /* Initializations of structure parameters for 32 point FFT */ + S->twidCoefModifier = 128U; + S->bitRevFactor = 128U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[127]; + break; + + case 16U: + /* Initializations of structure parameters for 16 point FFT */ + S->twidCoefModifier = 256U; + S->bitRevFactor = 256U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[255]; + break; + + + default: + /* Reporting argument error if fftSize is not valid value */ + status = ARM_MATH_ARGUMENT_ERROR; + break; + } + + return (status); +} + +/** + @} end of ComplexFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_q15.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_q15.c new file mode 100644 index 0000000..2a03b57 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_q15.c @@ -0,0 +1,689 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix2_q15.c + * Description: Radix-2 Decimation in Frequency CFFT & CIFFT Fixed point processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +void arm_radix2_butterfly_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pCoef, + uint16_t twidCoefModifier); + +void arm_radix2_butterfly_inverse_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pCoef, + uint16_t twidCoefModifier); + +void arm_bitreversal_q15( + q15_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + const uint16_t * pBitRevTab); + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Processing function for the fixed-point CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed in the future. + @param[in] S points to an instance of the fixed-point CFFT/CIFFT structure + @param[in,out] pSrc points to the complex data buffer of size 2*fftLen. Processing occurs in-place + @return none + */ + +void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc) +{ + + if (S->ifftFlag == 1U) + { + arm_radix2_butterfly_inverse_q15 (pSrc, S->fftLen, S->pTwiddle, S->twidCoefModifier); + } + else + { + arm_radix2_butterfly_q15 (pSrc, S->fftLen, S->pTwiddle, S->twidCoefModifier); + } + + arm_bitreversal_q15(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable); +} + +/** + @} end of ComplexFFT group + */ + +void arm_radix2_butterfly_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pCoef, + uint16_t twidCoefModifier) +{ +#if defined (ARM_MATH_DSP) + + uint32_t i, j, k, l; + uint32_t n1, n2, ia; + q15_t in; + q31_t T, S, R; + q31_t coeff, out1, out2; + + //N = fftLen; + n2 = fftLen; + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + // loop for groups + for (i = 0; i < n2; i++) + { + coeff = read_q15x2 ((q15_t *)pCoef + (ia * 2U)); + + ia = ia + twidCoefModifier; + + l = i + n2; + + T = read_q15x2 (pSrc + (2 * i)); + in = ((int16_t) (T & 0xFFFF)) >> 1; + T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF); + + S = read_q15x2 (pSrc + (2 * l)); + in = ((int16_t) (S & 0xFFFF)) >> 1; + S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __SHADD16(T, S)); + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUAD(coeff, R) >> 16; + out2 = __SMUSDX(coeff, R); +#else + out1 = __SMUSDX(R, coeff) >> 16U; + out2 = __SMUAD(coeff, R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + write_q15x2 (pSrc + (2U * l), (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + coeff = read_q15x2 ((q15_t *)pCoef + (ia * 2U)); + + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + i++; + l++; + + T = read_q15x2 (pSrc + (2 * i)); + in = ((int16_t) (T & 0xFFFF)) >> 1; + T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF); + + S = read_q15x2 (pSrc + (2 * l)); + in = ((int16_t) (S & 0xFFFF)) >> 1; + S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __SHADD16(T, S)); + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUAD(coeff, R) >> 16; + out2 = __SMUSDX(coeff, R); +#else + + out1 = __SMUSDX(R, coeff) >> 16U; + out2 = __SMUAD(coeff, R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + write_q15x2 (pSrc + (2U * l), (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + } /* groups loop end */ + + twidCoefModifier = twidCoefModifier << 1U; + + /* loop for stage */ + for (k = fftLen / 2; k > 2; k = k >> 1) + { + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + /* loop for groups */ + for (j = 0; j < n2; j++) + { + coeff = read_q15x2 ((q15_t *)pCoef + (ia * 2U)); + + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + for (i = j; i < fftLen; i += n1) + { + l = i + n2; + + T = read_q15x2 (pSrc + (2 * i)); + + S = read_q15x2 (pSrc + (2 * l)); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __SHADD16(T, S)); + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUAD(coeff, R) >> 16; + out2 = __SMUSDX(coeff, R); +#else + out1 = __SMUSDX(R, coeff) >> 16U; + out2 = __SMUAD(coeff, R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + write_q15x2 (pSrc + (2U * l), (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + i += n1; + + l = i + n2; + + T = read_q15x2 (pSrc + (2 * i)); + + S = read_q15x2 (pSrc + (2 * l)); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __SHADD16(T, S)); + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUAD(coeff, R) >> 16; + out2 = __SMUSDX(coeff, R); +#else + out1 = __SMUSDX(R, coeff) >> 16U; + out2 = __SMUAD(coeff, R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + write_q15x2 (pSrc + (2U * l), (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + } /* butterfly loop end */ + + } /* groups loop end */ + + twidCoefModifier = twidCoefModifier << 1U; + } /* stages loop end */ + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + coeff = read_q15x2 ((q15_t *)pCoef + (ia * 2U)); + + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + for (i = 0; i < fftLen; i += n1) + { + l = i + n2; + + T = read_q15x2 (pSrc + (2 * i)); + + S = read_q15x2 (pSrc + (2 * l)); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __QADD16(T, S)); + + write_q15x2 (pSrc + (2 * l), R); + + i += n1; + l = i + n2; + + T = read_q15x2 (pSrc + (2 * i)); + + S = read_q15x2 (pSrc + (2 * l)); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __QADD16(T, S)); + + write_q15x2 (pSrc + (2 * l), R); + + } /* groups loop end */ + + +#else /* #if defined (ARM_MATH_DSP) */ + + uint32_t i, j, k, l; + uint32_t n1, n2, ia; + q15_t xt, yt, cosVal, sinVal; + + + // N = fftLen; + n2 = fftLen; + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + /* loop for groups */ + for (j = 0; j < n2; j++) + { + cosVal = pCoef[(ia * 2)]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + for (i = j; i < fftLen; i += n1) + { + l = i + n2; + xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U); + pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U; + + yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U); + pSrc[2 * i + 1] = ((pSrc[2 * l + 1] >> 1U) + + (pSrc[2 * i + 1] >> 1U) ) >> 1U; + + pSrc[2 * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) + + ((int16_t) (((q31_t) yt * sinVal) >> 16))); + + pSrc[2U * l + 1] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) - + ((int16_t) (((q31_t) xt * sinVal) >> 16))); + + } /* butterfly loop end */ + + } /* groups loop end */ + + twidCoefModifier = twidCoefModifier << 1U; + + /* loop for stage */ + for (k = fftLen / 2; k > 2; k = k >> 1) + { + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + /* loop for groups */ + for (j = 0; j < n2; j++) + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + for (i = j; i < fftLen; i += n1) + { + l = i + n2; + xt = pSrc[2 * i] - pSrc[2 * l]; + pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U; + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U; + + pSrc[2 * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) + + ((int16_t) (((q31_t) yt * sinVal) >> 16))); + + pSrc[2U * l + 1] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) - + ((int16_t) (((q31_t) xt * sinVal) >> 16))); + + } /* butterfly loop end */ + + } /* groups loop end */ + + twidCoefModifier = twidCoefModifier << 1U; + } /* stages loop end */ + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + /* loop for groups */ + for (j = 0; j < n2; j++) + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + for (i = j; i < fftLen; i += n1) + { + l = i + n2; + xt = pSrc[2 * i] - pSrc[2 * l]; + pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]); + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]); + + pSrc[2 * l] = xt; + + pSrc[2 * l + 1] = yt; + + } /* butterfly loop end */ + + } /* groups loop end */ + + twidCoefModifier = twidCoefModifier << 1U; + +#endif /* #if defined (ARM_MATH_DSP) */ + +} + + +void arm_radix2_butterfly_inverse_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pCoef, + uint16_t twidCoefModifier) +{ +#if defined (ARM_MATH_DSP) + + uint32_t i, j, k, l; + uint32_t n1, n2, ia; + q15_t in; + q31_t T, S, R; + q31_t coeff, out1, out2; + + // N = fftLen; + n2 = fftLen; + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + /* loop for groups */ + for (i = 0; i < n2; i++) + { + coeff = read_q15x2 ((q15_t *)pCoef + (ia * 2U)); + + ia = ia + twidCoefModifier; + + l = i + n2; + + T = read_q15x2 (pSrc + (2 * i)); + in = ((int16_t) (T & 0xFFFF)) >> 1; + T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF); + + S = read_q15x2 (pSrc + (2 * l)); + in = ((int16_t) (S & 0xFFFF)) >> 1; + S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __SHADD16(T, S)); + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUSD(coeff, R) >> 16; + out2 = __SMUADX(coeff, R); +#else + out1 = __SMUADX(R, coeff) >> 16U; + out2 = __SMUSD(__QSUB(0, coeff), R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + write_q15x2 (pSrc + (2 * l), (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + coeff = read_q15x2 ((q15_t *)pCoef + (ia * 2U)); + + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + i++; + l++; + + T = read_q15x2 (pSrc + (2 * i)); + in = ((int16_t) (T & 0xFFFF)) >> 1; + T = ((T >> 1) & 0xFFFF0000) | (in & 0xFFFF); + + S = read_q15x2 (pSrc + (2 * l)); + in = ((int16_t) (S & 0xFFFF)) >> 1; + S = ((S >> 1) & 0xFFFF0000) | (in & 0xFFFF); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __SHADD16(T, S)); + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUSD(coeff, R) >> 16; + out2 = __SMUADX(coeff, R); +#else + out1 = __SMUADX(R, coeff) >> 16U; + out2 = __SMUSD(__QSUB(0, coeff), R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + write_q15x2 (pSrc + (2 * l), (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + } /* groups loop end */ + + twidCoefModifier = twidCoefModifier << 1U; + + /* loop for stage */ + for (k = fftLen / 2; k > 2; k = k >> 1) + { + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + /* loop for groups */ + for (j = 0; j < n2; j++) + { + coeff = read_q15x2 ((q15_t *)pCoef + (ia * 2U)); + + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + for (i = j; i < fftLen; i += n1) + { + l = i + n2; + + T = read_q15x2 (pSrc + (2 * i)); + + S = read_q15x2 (pSrc + (2 * l)); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __SHADD16(T, S)); + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUSD(coeff, R) >> 16; + out2 = __SMUADX(coeff, R); +#else + out1 = __SMUADX(R, coeff) >> 16U; + out2 = __SMUSD(__QSUB(0, coeff), R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + write_q15x2 (pSrc + (2 * l), (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + i += n1; + + l = i + n2; + + T = read_q15x2 (pSrc + (2 * i)); + + S = read_q15x2 (pSrc + (2 * l)); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __SHADD16(T, S)); + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUSD(coeff, R) >> 16; + out2 = __SMUADX(coeff, R); +#else + out1 = __SMUADX(R, coeff) >> 16U; + out2 = __SMUSD(__QSUB(0, coeff), R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + write_q15x2 (pSrc + (2 * l), (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + } /* butterfly loop end */ + + } /* groups loop end */ + + twidCoefModifier = twidCoefModifier << 1U; + } /* stages loop end */ + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + /* loop for groups */ + for (j = 0; j < n2; j++) + { + coeff = read_q15x2 ((q15_t *)pCoef + (ia * 2U)); + + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + for (i = j; i < fftLen; i += n1) + { + l = i + n2; + + T = read_q15x2 (pSrc + (2 * i)); + + S = read_q15x2 (pSrc + (2 * l)); + + R = __QSUB16(T, S); + + write_q15x2 (pSrc + (2 * i), __QADD16(T, S)); + + write_q15x2 (pSrc + (2 * l), R); + + } /* butterfly loop end */ + + } /* groups loop end */ + + twidCoefModifier = twidCoefModifier << 1U; + +#else /* #if defined (ARM_MATH_DSP) */ + + uint32_t i, j, k, l; + uint32_t n1, n2, ia; + q15_t xt, yt, cosVal, sinVal; + + // N = fftLen; + n2 = fftLen; + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + /* loop for groups */ + for (j = 0; j < n2; j++) + { + cosVal = pCoef[(ia * 2)]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + for (i = j; i < fftLen; i += n1) + { + l = i + n2; + xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U); + pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U; + + yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U); + pSrc[2 * i + 1] = ((pSrc[2 * l + 1] >> 1U) + + (pSrc[2 * i + 1] >> 1U) ) >> 1U; + + pSrc[2 * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) - + ((int16_t) (((q31_t) yt * sinVal) >> 16))); + + pSrc[2 * l + 1] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) + + ((int16_t) (((q31_t) xt * sinVal) >> 16))); + + } /* butterfly loop end */ + + } /* groups loop end */ + + twidCoefModifier = twidCoefModifier << 1U; + + /* loop for stage */ + for (k = fftLen / 2; k > 2; k = k >> 1) + { + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + /* loop for groups */ + for (j = 0; j < n2; j++) + { + cosVal = pCoef[(ia * 2)]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + for (i = j; i < fftLen; i += n1) + { + l = i + n2; + xt = pSrc[2 * i] - pSrc[2 * l]; + pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U; + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U; + + pSrc[2 * l] = (((int16_t) (((q31_t) xt * cosVal) >> 16)) - + ((int16_t) (((q31_t) yt * sinVal) >> 16)) ); + + pSrc[2 * l + 1] = (((int16_t) (((q31_t) yt * cosVal) >> 16)) + + ((int16_t) (((q31_t) xt * sinVal) >> 16)) ); + + } /* butterfly loop end */ + + } /* groups loop end */ + + twidCoefModifier = twidCoefModifier << 1U; + } /* stages loop end */ + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + cosVal = pCoef[(ia * 2)]; + sinVal = pCoef[(ia * 2) + 1]; + + ia = ia + twidCoefModifier; + + /* loop for butterfly */ + for (i = 0; i < fftLen; i += n1) + { + l = i + n2; + xt = pSrc[2 * i] - pSrc[2 * l]; + pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]); + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]); + + pSrc[2 * l] = xt; + + pSrc[2 * l + 1] = yt; + + } /* groups loop end */ + + +#endif /* #if defined (ARM_MATH_DSP) */ + +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_q31.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_q31.c new file mode 100644 index 0000000..6c79a65 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix2_q31.c @@ -0,0 +1,337 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix2_q31.c + * Description: Radix-2 Decimation in Frequency CFFT & CIFFT Fixed point processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +void arm_radix2_butterfly_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef, + uint16_t twidCoefModifier); + +void arm_radix2_butterfly_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef, + uint16_t twidCoefModifier); + +void arm_bitreversal_q31( + q31_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + const uint16_t * pBitRevTab); + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Processing function for the fixed-point CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed in the future. + @param[in] S points to an instance of the fixed-point CFFT/CIFFT structure + @param[in,out] pSrc points to the complex data buffer of size 2*fftLen. Processing occurs in-place + @return none + */ + +void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc) +{ + + if (S->ifftFlag == 1U) + { + arm_radix2_butterfly_inverse_q31(pSrc, S->fftLen, + S->pTwiddle, S->twidCoefModifier); + } + else + { + arm_radix2_butterfly_q31(pSrc, S->fftLen, + S->pTwiddle, S->twidCoefModifier); + } + + arm_bitreversal_q31(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable); +} + +/** + @} end of ComplexFFT group + */ + +void arm_radix2_butterfly_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef, + uint16_t twidCoefModifier) +{ + + unsigned i, j, k, l, m; + unsigned n1, n2, ia; + q31_t xt, yt, cosVal, sinVal; + q31_t p0, p1; + + //N = fftLen; + n2 = fftLen; + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + // loop for groups + for (i = 0; i < n2; i++) + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + l = i + n2; + xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U); + pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U; + + yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U); + pSrc[2 * i + 1] = + ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U; + + mult_32x32_keep32_R(p0, xt, cosVal); + mult_32x32_keep32_R(p1, yt, cosVal); + multAcc_32x32_keep32_R(p0, yt, sinVal); + multSub_32x32_keep32_R(p1, xt, sinVal); + + pSrc[2U * l] = p0; + pSrc[2U * l + 1U] = p1; + + } // groups loop end + + twidCoefModifier <<= 1U; + + // loop for stage + for (k = fftLen / 2; k > 2; k = k >> 1) + { + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + // loop for groups + for (j = 0; j < n2; j++) + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + // loop for butterfly + i = j; + m = fftLen / n1; + do + { + l = i + n2; + xt = pSrc[2 * i] - pSrc[2 * l]; + pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U; + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U; + + mult_32x32_keep32_R(p0, xt, cosVal); + mult_32x32_keep32_R(p1, yt, cosVal); + multAcc_32x32_keep32_R(p0, yt, sinVal); + multSub_32x32_keep32_R(p1, xt, sinVal); + + pSrc[2U * l] = p0; + pSrc[2U * l + 1U] = p1; + i += n1; + m--; + } while ( m > 0); // butterfly loop end + + } // groups loop end + + twidCoefModifier <<= 1U; + } // stages loop end + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + // loop for butterfly + for (i = 0; i < fftLen; i += n1) + { + l = i + n2; + xt = pSrc[2 * i] - pSrc[2 * l]; + pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]); + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]); + + pSrc[2U * l] = xt; + + pSrc[2U * l + 1U] = yt; + + i += n1; + l = i + n2; + + xt = pSrc[2 * i] - pSrc[2 * l]; + pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]); + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]); + + pSrc[2U * l] = xt; + + pSrc[2U * l + 1U] = yt; + + } // butterfly loop end + +} + + +void arm_radix2_butterfly_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef, + uint16_t twidCoefModifier) +{ + + unsigned i, j, k, l; + unsigned n1, n2, ia; + q31_t xt, yt, cosVal, sinVal; + q31_t p0, p1; + + //N = fftLen; + n2 = fftLen; + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + // loop for groups + for (i = 0; i < n2; i++) + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + l = i + n2; + xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U); + pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U; + + yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U); + pSrc[2 * i + 1] = + ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U; + + mult_32x32_keep32_R(p0, xt, cosVal); + mult_32x32_keep32_R(p1, yt, cosVal); + multSub_32x32_keep32_R(p0, yt, sinVal); + multAcc_32x32_keep32_R(p1, xt, sinVal); + + pSrc[2U * l] = p0; + pSrc[2U * l + 1U] = p1; + } // groups loop end + + twidCoefModifier = twidCoefModifier << 1U; + + // loop for stage + for (k = fftLen / 2; k > 2; k = k >> 1) + { + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + // loop for groups + for (j = 0; j < n2; j++) + { + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + // loop for butterfly + for (i = j; i < fftLen; i += n1) + { + l = i + n2; + xt = pSrc[2 * i] - pSrc[2 * l]; + pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U; + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U; + + mult_32x32_keep32_R(p0, xt, cosVal); + mult_32x32_keep32_R(p1, yt, cosVal); + multSub_32x32_keep32_R(p0, yt, sinVal); + multAcc_32x32_keep32_R(p1, xt, sinVal); + + pSrc[2U * l] = p0; + pSrc[2U * l + 1U] = p1; + } // butterfly loop end + + } // groups loop end + + twidCoefModifier = twidCoefModifier << 1U; + } // stages loop end + + n1 = n2; + n2 = n2 >> 1; + ia = 0; + + cosVal = pCoef[ia * 2]; + sinVal = pCoef[(ia * 2) + 1]; + ia = ia + twidCoefModifier; + + // loop for butterfly + for (i = 0; i < fftLen; i += n1) + { + l = i + n2; + xt = pSrc[2 * i] - pSrc[2 * l]; + pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]); + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]); + + pSrc[2U * l] = xt; + + pSrc[2U * l + 1U] = yt; + + i += n1; + l = i + n2; + + xt = pSrc[2 * i] - pSrc[2 * l]; + pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]); + + yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; + pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]); + + pSrc[2U * l] = xt; + + pSrc[2U * l + 1U] = yt; + + } // butterfly loop end + +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_f32.c new file mode 100644 index 0000000..9629145 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_f32.c @@ -0,0 +1,1200 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix4_f32.c + * Description: Radix-4 Decimation in Frequency CFFT & CIFFT Floating point processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +extern void arm_bitreversal_f32( + float32_t * pSrc, + uint16_t fftSize, + uint16_t bitRevFactor, + const uint16_t * pBitRevTab); + +void arm_radix4_butterfly_f32( + float32_t * pSrc, + uint16_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier); + +void arm_radix4_butterfly_inverse_f32( + float32_t * pSrc, + uint16_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier, + float32_t onebyfftLen); + + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Processing function for the floating-point Radix-4 CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_f32 and will be removed in the future. + @param[in] S points to an instance of the floating-point Radix-4 CFFT/CIFFT structure + @param[in,out] pSrc points to the complex data buffer of size 2*fftLen. Processing occurs in-place + @return none + */ + +void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc) +{ + if (S->ifftFlag == 1U) + { + /* Complex IFFT radix-4 */ + arm_radix4_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle, S->twidCoefModifier, S->onebyfftLen); + } + else + { + /* Complex FFT radix-4 */ + arm_radix4_butterfly_f32(pSrc, S->fftLen, S->pTwiddle, S->twidCoefModifier); + } + + if (S->bitReverseFlag == 1U) + { + /* Bit Reversal */ + arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable); + } + +} + +/** + @} end of ComplexFFT group + */ + +/* ---------------------------------------------------------------------- + * Internal helper function used by the FFTs + * ---------------------------------------------------------------------- */ + +/** + brief Core function for the floating-point CFFT butterfly process. + param[in,out] pSrc points to the in-place buffer of floating-point data type + param[in] fftLen length of the FFT + param[in] pCoef points to the twiddle coefficient buffer + param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table + return none + */ + +void arm_radix4_butterfly_f32( + float32_t * pSrc, + uint16_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier) +{ + float32_t co1, co2, co3, si1, si2, si3; + uint32_t ia1, ia2, ia3; + uint32_t i0, i1, i2, i3; + uint32_t n1, n2, j, k; + +#if defined (ARM_MATH_LOOPUNROLL) + + float32_t xaIn, yaIn, xbIn, ybIn, xcIn, ycIn, xdIn, ydIn; + float32_t Xaplusc, Xbplusd, Yaplusc, Ybplusd, Xaminusc, Xbminusd, Yaminusc, + Ybminusd; + float32_t Xb12C_out, Yb12C_out, Xc12C_out, Yc12C_out, Xd12C_out, Yd12C_out; + float32_t Xb12_out, Yb12_out, Xc12_out, Yc12_out, Xd12_out, Yd12_out; + float32_t *ptr1; + float32_t p0,p1,p2,p3,p4,p5; + float32_t a0,a1,a2,a3,a4,a5,a6,a7; + + /* Initializations for the first stage */ + n2 = fftLen; + n1 = n2; + + /* n2 = fftLen/4 */ + n2 >>= 2U; + i0 = 0U; + ia1 = 0U; + + j = n2; + + /* Calculation of first stage */ + do + { + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + xaIn = pSrc[(2U * i0)]; + yaIn = pSrc[(2U * i0) + 1U]; + + xbIn = pSrc[(2U * i1)]; + ybIn = pSrc[(2U * i1) + 1U]; + + xcIn = pSrc[(2U * i2)]; + ycIn = pSrc[(2U * i2) + 1U]; + + xdIn = pSrc[(2U * i3)]; + ydIn = pSrc[(2U * i3) + 1U]; + + /* xa + xc */ + Xaplusc = xaIn + xcIn; + /* xb + xd */ + Xbplusd = xbIn + xdIn; + /* ya + yc */ + Yaplusc = yaIn + ycIn; + /* yb + yd */ + Ybplusd = ybIn + ydIn; + + /* index calculation for the coefficients */ + ia2 = ia1 + ia1; + co2 = pCoef[ia2 * 2U]; + si2 = pCoef[(ia2 * 2U) + 1U]; + + /* xa - xc */ + Xaminusc = xaIn - xcIn; + /* xb - xd */ + Xbminusd = xbIn - xdIn; + /* ya - yc */ + Yaminusc = yaIn - ycIn; + /* yb - yd */ + Ybminusd = ybIn - ydIn; + + /* xa' = xa + xb + xc + xd */ + pSrc[(2U * i0)] = Xaplusc + Xbplusd; + /* ya' = ya + yb + yc + yd */ + pSrc[(2U * i0) + 1U] = Yaplusc + Ybplusd; + + /* (xa - xc) + (yb - yd) */ + Xb12C_out = (Xaminusc + Ybminusd); + /* (ya - yc) + (xb - xd) */ + Yb12C_out = (Yaminusc - Xbminusd); + /* (xa + xc) - (xb + xd) */ + Xc12C_out = (Xaplusc - Xbplusd); + /* (ya + yc) - (yb + yd) */ + Yc12C_out = (Yaplusc - Ybplusd); + /* (xa - xc) - (yb - yd) */ + Xd12C_out = (Xaminusc - Ybminusd); + /* (ya - yc) + (xb - xd) */ + Yd12C_out = (Xbminusd + Yaminusc); + + co1 = pCoef[ia1 * 2U]; + si1 = pCoef[(ia1 * 2U) + 1U]; + + /* index calculation for the coefficients */ + ia3 = ia2 + ia1; + co3 = pCoef[ia3 * 2U]; + si3 = pCoef[(ia3 * 2U) + 1U]; + + Xb12_out = Xb12C_out * co1; + Yb12_out = Yb12C_out * co1; + Xc12_out = Xc12C_out * co2; + Yc12_out = Yc12C_out * co2; + Xd12_out = Xd12C_out * co3; + Yd12_out = Yd12C_out * co3; + + /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */ + //Xb12_out -= Yb12C_out * si1; + p0 = Yb12C_out * si1; + /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */ + //Yb12_out += Xb12C_out * si1; + p1 = Xb12C_out * si1; + /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */ + //Xc12_out -= Yc12C_out * si2; + p2 = Yc12C_out * si2; + /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */ + //Yc12_out += Xc12C_out * si2; + p3 = Xc12C_out * si2; + /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */ + //Xd12_out -= Yd12C_out * si3; + p4 = Yd12C_out * si3; + /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */ + //Yd12_out += Xd12C_out * si3; + p5 = Xd12C_out * si3; + + Xb12_out += p0; + Yb12_out -= p1; + Xc12_out += p2; + Yc12_out -= p3; + Xd12_out += p4; + Yd12_out -= p5; + + /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = Xc12_out; + + /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */ + pSrc[(2U * i1) + 1U] = Yc12_out; + + /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = Xb12_out; + + /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = Yb12_out; + + /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */ + pSrc[2U * i3] = Xd12_out; + + /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = Yd12_out; + + /* Twiddle coefficients index modifier */ + ia1 += twidCoefModifier; + + /* Updating input index */ + i0++; + + } + while (--j); + + twidCoefModifier <<= 2U; + + /* Calculation of second stage to excluding last stage */ + for (k = fftLen >> 2U; k > 4U; k >>= 2U) + { + /* Initializations for the first stage */ + n1 = n2; + n2 >>= 2U; + ia1 = 0U; + + /* Calculation of first stage */ + j = 0; + do + { + /* index calculation for the coefficients */ + ia2 = ia1 + ia1; + ia3 = ia2 + ia1; + co1 = pCoef[(ia1 * 2U)]; + si1 = pCoef[(ia1 * 2U) + 1U]; + co2 = pCoef[(ia2 * 2U)]; + si2 = pCoef[(ia2 * 2U) + 1U]; + co3 = pCoef[(ia3 * 2U)]; + si3 = pCoef[(ia3 * 2U) + 1U]; + + /* Twiddle coefficients index modifier */ + ia1 += twidCoefModifier; + + i0 = j; + do + { + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + xaIn = pSrc[(2U * i0)]; + yaIn = pSrc[(2U * i0) + 1U]; + + xbIn = pSrc[(2U * i1)]; + ybIn = pSrc[(2U * i1) + 1U]; + + xcIn = pSrc[(2U * i2)]; + ycIn = pSrc[(2U * i2) + 1U]; + + xdIn = pSrc[(2U * i3)]; + ydIn = pSrc[(2U * i3) + 1U]; + + /* xa - xc */ + Xaminusc = xaIn - xcIn; + /* (xb - xd) */ + Xbminusd = xbIn - xdIn; + /* ya - yc */ + Yaminusc = yaIn - ycIn; + /* (yb - yd) */ + Ybminusd = ybIn - ydIn; + + /* xa + xc */ + Xaplusc = xaIn + xcIn; + /* xb + xd */ + Xbplusd = xbIn + xdIn; + /* ya + yc */ + Yaplusc = yaIn + ycIn; + /* yb + yd */ + Ybplusd = ybIn + ydIn; + + /* (xa - xc) + (yb - yd) */ + Xb12C_out = (Xaminusc + Ybminusd); + /* (ya - yc) - (xb - xd) */ + Yb12C_out = (Yaminusc - Xbminusd); + /* xa + xc -(xb + xd) */ + Xc12C_out = (Xaplusc - Xbplusd); + /* (ya + yc) - (yb + yd) */ + Yc12C_out = (Yaplusc - Ybplusd); + /* (xa - xc) - (yb - yd) */ + Xd12C_out = (Xaminusc - Ybminusd); + /* (ya - yc) + (xb - xd) */ + Yd12C_out = (Xbminusd + Yaminusc); + + pSrc[(2U * i0)] = Xaplusc + Xbplusd; + pSrc[(2U * i0) + 1U] = Yaplusc + Ybplusd; + + Xb12_out = Xb12C_out * co1; + Yb12_out = Yb12C_out * co1; + Xc12_out = Xc12C_out * co2; + Yc12_out = Yc12C_out * co2; + Xd12_out = Xd12C_out * co3; + Yd12_out = Yd12C_out * co3; + + /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */ + //Xb12_out -= Yb12C_out * si1; + p0 = Yb12C_out * si1; + /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */ + //Yb12_out += Xb12C_out * si1; + p1 = Xb12C_out * si1; + /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */ + //Xc12_out -= Yc12C_out * si2; + p2 = Yc12C_out * si2; + /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */ + //Yc12_out += Xc12C_out * si2; + p3 = Xc12C_out * si2; + /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */ + //Xd12_out -= Yd12C_out * si3; + p4 = Yd12C_out * si3; + /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */ + //Yd12_out += Xd12C_out * si3; + p5 = Xd12C_out * si3; + + Xb12_out += p0; + Yb12_out -= p1; + Xc12_out += p2; + Yc12_out -= p3; + Xd12_out += p4; + Yd12_out -= p5; + + /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = Xc12_out; + + /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */ + pSrc[(2U * i1) + 1U] = Yc12_out; + + /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = Xb12_out; + + /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = Yb12_out; + + /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */ + pSrc[2U * i3] = Xd12_out; + + /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = Yd12_out; + + i0 += n1; + } while (i0 < fftLen); + j++; + } while (j <= (n2 - 1U)); + twidCoefModifier <<= 2U; + } + + j = fftLen >> 2; + ptr1 = &pSrc[0]; + + /* Calculations of last stage */ + do + { + xaIn = ptr1[0]; + yaIn = ptr1[1]; + xbIn = ptr1[2]; + ybIn = ptr1[3]; + xcIn = ptr1[4]; + ycIn = ptr1[5]; + xdIn = ptr1[6]; + ydIn = ptr1[7]; + + /* xa + xc */ + Xaplusc = xaIn + xcIn; + + /* xa - xc */ + Xaminusc = xaIn - xcIn; + + /* ya + yc */ + Yaplusc = yaIn + ycIn; + + /* ya - yc */ + Yaminusc = yaIn - ycIn; + + /* xb + xd */ + Xbplusd = xbIn + xdIn; + + /* yb + yd */ + Ybplusd = ybIn + ydIn; + + /* (xb-xd) */ + Xbminusd = xbIn - xdIn; + + /* (yb-yd) */ + Ybminusd = ybIn - ydIn; + + /* xa' = xa + xb + xc + xd */ + a0 = (Xaplusc + Xbplusd); + /* ya' = ya + yb + yc + yd */ + a1 = (Yaplusc + Ybplusd); + /* xc' = (xa-xb+xc-xd) */ + a2 = (Xaplusc - Xbplusd); + /* yc' = (ya-yb+yc-yd) */ + a3 = (Yaplusc - Ybplusd); + /* xb' = (xa+yb-xc-yd) */ + a4 = (Xaminusc + Ybminusd); + /* yb' = (ya-xb-yc+xd) */ + a5 = (Yaminusc - Xbminusd); + /* xd' = (xa-yb-xc+yd)) */ + a6 = (Xaminusc - Ybminusd); + /* yd' = (ya+xb-yc-xd) */ + a7 = (Xbminusd + Yaminusc); + + ptr1[0] = a0; + ptr1[1] = a1; + ptr1[2] = a2; + ptr1[3] = a3; + ptr1[4] = a4; + ptr1[5] = a5; + ptr1[6] = a6; + ptr1[7] = a7; + + /* increment pointer by 8 */ + ptr1 += 8U; + } while (--j); + +#else + + float32_t t1, t2, r1, r2, s1, s2; + + /* Initializations for the fft calculation */ + n2 = fftLen; + n1 = n2; + for (k = fftLen; k > 1U; k >>= 2U) + { + /* Initializations for the fft calculation */ + n1 = n2; + n2 >>= 2U; + ia1 = 0U; + + /* FFT Calculation */ + j = 0; + do + { + /* index calculation for the coefficients */ + ia2 = ia1 + ia1; + ia3 = ia2 + ia1; + co1 = pCoef[ia1 * 2U]; + si1 = pCoef[(ia1 * 2U) + 1U]; + co2 = pCoef[ia2 * 2U]; + si2 = pCoef[(ia2 * 2U) + 1U]; + co3 = pCoef[ia3 * 2U]; + si3 = pCoef[(ia3 * 2U) + 1U]; + + /* Twiddle coefficients index modifier */ + ia1 = ia1 + twidCoefModifier; + + i0 = j; + do + { + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* xa + xc */ + r1 = pSrc[(2U * i0)] + pSrc[(2U * i2)]; + + /* xa - xc */ + r2 = pSrc[(2U * i0)] - pSrc[(2U * i2)]; + + /* ya + yc */ + s1 = pSrc[(2U * i0) + 1U] + pSrc[(2U * i2) + 1U]; + + /* ya - yc */ + s2 = pSrc[(2U * i0) + 1U] - pSrc[(2U * i2) + 1U]; + + /* xb + xd */ + t1 = pSrc[2U * i1] + pSrc[2U * i3]; + + /* xa' = xa + xb + xc + xd */ + pSrc[2U * i0] = r1 + t1; + + /* xa + xc -(xb + xd) */ + r1 = r1 - t1; + + /* yb + yd */ + t2 = pSrc[(2U * i1) + 1U] + pSrc[(2U * i3) + 1U]; + + /* ya' = ya + yb + yc + yd */ + pSrc[(2U * i0) + 1U] = s1 + t2; + + /* (ya + yc) - (yb + yd) */ + s1 = s1 - t2; + + /* (yb - yd) */ + t1 = pSrc[(2U * i1) + 1U] - pSrc[(2U * i3) + 1U]; + + /* (xb - xd) */ + t2 = pSrc[2U * i1] - pSrc[2U * i3]; + + /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = (r1 * co2) + (s1 * si2); + + /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */ + pSrc[(2U * i1) + 1U] = (s1 * co2) - (r1 * si2); + + /* (xa - xc) + (yb - yd) */ + r1 = r2 + t1; + + /* (xa - xc) - (yb - yd) */ + r2 = r2 - t1; + + /* (ya - yc) - (xb - xd) */ + s1 = s2 - t2; + + /* (ya - yc) + (xb - xd) */ + s2 = s2 + t2; + + /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = (r1 * co1) + (s1 * si1); + + /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = (s1 * co1) - (r1 * si1); + + /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */ + pSrc[2U * i3] = (r2 * co3) + (s2 * si3); + + /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = (s2 * co3) - (r2 * si3); + + i0 += n1; + } while ( i0 < fftLen); + j++; + } while (j <= (n2 - 1U)); + twidCoefModifier <<= 2U; + } + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + +} + +/** + brief Core function for the floating-point CIFFT butterfly process. + param[in,out] pSrc points to the in-place buffer of floating-point data type + param[in] fftLen length of the FFT + param[in] pCoef points to twiddle coefficient buffer + param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + param[in] onebyfftLen value of 1/fftLen + return none + */ + +void arm_radix4_butterfly_inverse_f32( + float32_t * pSrc, + uint16_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier, + float32_t onebyfftLen) +{ + float32_t co1, co2, co3, si1, si2, si3; + uint32_t ia1, ia2, ia3; + uint32_t i0, i1, i2, i3; + uint32_t n1, n2, j, k; + +#if defined (ARM_MATH_LOOPUNROLL) + + float32_t xaIn, yaIn, xbIn, ybIn, xcIn, ycIn, xdIn, ydIn; + float32_t Xaplusc, Xbplusd, Yaplusc, Ybplusd, Xaminusc, Xbminusd, Yaminusc, + Ybminusd; + float32_t Xb12C_out, Yb12C_out, Xc12C_out, Yc12C_out, Xd12C_out, Yd12C_out; + float32_t Xb12_out, Yb12_out, Xc12_out, Yc12_out, Xd12_out, Yd12_out; + float32_t *ptr1; + float32_t p0,p1,p2,p3,p4,p5,p6,p7; + float32_t a0,a1,a2,a3,a4,a5,a6,a7; + + + /* Initializations for the first stage */ + n2 = fftLen; + n1 = n2; + + /* n2 = fftLen/4 */ + n2 >>= 2U; + i0 = 0U; + ia1 = 0U; + + j = n2; + + /* Calculation of first stage */ + do + { + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Butterfly implementation */ + xaIn = pSrc[(2U * i0)]; + yaIn = pSrc[(2U * i0) + 1U]; + + xcIn = pSrc[(2U * i2)]; + ycIn = pSrc[(2U * i2) + 1U]; + + xbIn = pSrc[(2U * i1)]; + ybIn = pSrc[(2U * i1) + 1U]; + + xdIn = pSrc[(2U * i3)]; + ydIn = pSrc[(2U * i3) + 1U]; + + /* xa + xc */ + Xaplusc = xaIn + xcIn; + /* xb + xd */ + Xbplusd = xbIn + xdIn; + /* ya + yc */ + Yaplusc = yaIn + ycIn; + /* yb + yd */ + Ybplusd = ybIn + ydIn; + + /* index calculation for the coefficients */ + ia2 = ia1 + ia1; + co2 = pCoef[ia2 * 2U]; + si2 = pCoef[(ia2 * 2U) + 1U]; + + /* xa - xc */ + Xaminusc = xaIn - xcIn; + /* xb - xd */ + Xbminusd = xbIn - xdIn; + /* ya - yc */ + Yaminusc = yaIn - ycIn; + /* yb - yd */ + Ybminusd = ybIn - ydIn; + + /* xa' = xa + xb + xc + xd */ + pSrc[(2U * i0)] = Xaplusc + Xbplusd; + + /* ya' = ya + yb + yc + yd */ + pSrc[(2U * i0) + 1U] = Yaplusc + Ybplusd; + + /* (xa - xc) - (yb - yd) */ + Xb12C_out = (Xaminusc - Ybminusd); + /* (ya - yc) + (xb - xd) */ + Yb12C_out = (Yaminusc + Xbminusd); + /* (xa + xc) - (xb + xd) */ + Xc12C_out = (Xaplusc - Xbplusd); + /* (ya + yc) - (yb + yd) */ + Yc12C_out = (Yaplusc - Ybplusd); + /* (xa - xc) + (yb - yd) */ + Xd12C_out = (Xaminusc + Ybminusd); + /* (ya - yc) - (xb - xd) */ + Yd12C_out = (Yaminusc - Xbminusd); + + co1 = pCoef[ia1 * 2U]; + si1 = pCoef[(ia1 * 2U) + 1U]; + + /* index calculation for the coefficients */ + ia3 = ia2 + ia1; + co3 = pCoef[ia3 * 2U]; + si3 = pCoef[(ia3 * 2U) + 1U]; + + Xb12_out = Xb12C_out * co1; + Yb12_out = Yb12C_out * co1; + Xc12_out = Xc12C_out * co2; + Yc12_out = Yc12C_out * co2; + Xd12_out = Xd12C_out * co3; + Yd12_out = Yd12C_out * co3; + + /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */ + //Xb12_out -= Yb12C_out * si1; + p0 = Yb12C_out * si1; + /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */ + //Yb12_out += Xb12C_out * si1; + p1 = Xb12C_out * si1; + /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */ + //Xc12_out -= Yc12C_out * si2; + p2 = Yc12C_out * si2; + /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */ + //Yc12_out += Xc12C_out * si2; + p3 = Xc12C_out * si2; + /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */ + //Xd12_out -= Yd12C_out * si3; + p4 = Yd12C_out * si3; + /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */ + //Yd12_out += Xd12C_out * si3; + p5 = Xd12C_out * si3; + + Xb12_out -= p0; + Yb12_out += p1; + Xc12_out -= p2; + Yc12_out += p3; + Xd12_out -= p4; + Yd12_out += p5; + + /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = Xc12_out; + + /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */ + pSrc[(2U * i1) + 1U] = Yc12_out; + + /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = Xb12_out; + + /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = Yb12_out; + + /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */ + pSrc[2U * i3] = Xd12_out; + + /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = Yd12_out; + + /* Twiddle coefficients index modifier */ + ia1 = ia1 + twidCoefModifier; + + /* Updating input index */ + i0 = i0 + 1U; + + } while (--j); + + twidCoefModifier <<= 2U; + + /* Calculation of second stage to excluding last stage */ + for (k = fftLen >> 2U; k > 4U; k >>= 2U) + { + /* Initializations for the first stage */ + n1 = n2; + n2 >>= 2U; + ia1 = 0U; + + /* Calculation of first stage */ + j = 0; + do + { + /* index calculation for the coefficients */ + ia2 = ia1 + ia1; + ia3 = ia2 + ia1; + co1 = pCoef[ia1 * 2U]; + si1 = pCoef[(ia1 * 2U) + 1U]; + co2 = pCoef[ia2 * 2U]; + si2 = pCoef[(ia2 * 2U) + 1U]; + co3 = pCoef[ia3 * 2U]; + si3 = pCoef[(ia3 * 2U) + 1U]; + + /* Twiddle coefficients index modifier */ + ia1 = ia1 + twidCoefModifier; + + i0 = j; + do + { + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + xaIn = pSrc[(2U * i0)]; + yaIn = pSrc[(2U * i0) + 1U]; + + xbIn = pSrc[(2U * i1)]; + ybIn = pSrc[(2U * i1) + 1U]; + + xcIn = pSrc[(2U * i2)]; + ycIn = pSrc[(2U * i2) + 1U]; + + xdIn = pSrc[(2U * i3)]; + ydIn = pSrc[(2U * i3) + 1U]; + + /* xa - xc */ + Xaminusc = xaIn - xcIn; + /* (xb - xd) */ + Xbminusd = xbIn - xdIn; + /* ya - yc */ + Yaminusc = yaIn - ycIn; + /* (yb - yd) */ + Ybminusd = ybIn - ydIn; + + /* xa + xc */ + Xaplusc = xaIn + xcIn; + /* xb + xd */ + Xbplusd = xbIn + xdIn; + /* ya + yc */ + Yaplusc = yaIn + ycIn; + /* yb + yd */ + Ybplusd = ybIn + ydIn; + + /* (xa - xc) - (yb - yd) */ + Xb12C_out = (Xaminusc - Ybminusd); + /* (ya - yc) + (xb - xd) */ + Yb12C_out = (Yaminusc + Xbminusd); + /* xa + xc -(xb + xd) */ + Xc12C_out = (Xaplusc - Xbplusd); + /* (ya + yc) - (yb + yd) */ + Yc12C_out = (Yaplusc - Ybplusd); + /* (xa - xc) + (yb - yd) */ + Xd12C_out = (Xaminusc + Ybminusd); + /* (ya - yc) - (xb - xd) */ + Yd12C_out = (Yaminusc - Xbminusd); + + pSrc[(2U * i0)] = Xaplusc + Xbplusd; + pSrc[(2U * i0) + 1U] = Yaplusc + Ybplusd; + + Xb12_out = Xb12C_out * co1; + Yb12_out = Yb12C_out * co1; + Xc12_out = Xc12C_out * co2; + Yc12_out = Yc12C_out * co2; + Xd12_out = Xd12C_out * co3; + Yd12_out = Yd12C_out * co3; + + /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */ + //Xb12_out -= Yb12C_out * si1; + p0 = Yb12C_out * si1; + /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */ + //Yb12_out += Xb12C_out * si1; + p1 = Xb12C_out * si1; + /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */ + //Xc12_out -= Yc12C_out * si2; + p2 = Yc12C_out * si2; + /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */ + //Yc12_out += Xc12C_out * si2; + p3 = Xc12C_out * si2; + /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */ + //Xd12_out -= Yd12C_out * si3; + p4 = Yd12C_out * si3; + /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */ + //Yd12_out += Xd12C_out * si3; + p5 = Xd12C_out * si3; + + Xb12_out -= p0; + Yb12_out += p1; + Xc12_out -= p2; + Yc12_out += p3; + Xd12_out -= p4; + Yd12_out += p5; + + /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = Xc12_out; + + /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */ + pSrc[(2U * i1) + 1U] = Yc12_out; + + /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = Xb12_out; + + /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = Yb12_out; + + /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */ + pSrc[2U * i3] = Xd12_out; + + /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = Yd12_out; + + i0 += n1; + } while (i0 < fftLen); + j++; + } while (j <= (n2 - 1U)); + twidCoefModifier <<= 2U; + } + /* Initializations of last stage */ + + j = fftLen >> 2; + ptr1 = &pSrc[0]; + + /* Calculations of last stage */ + do + { + xaIn = ptr1[0]; + yaIn = ptr1[1]; + xbIn = ptr1[2]; + ybIn = ptr1[3]; + xcIn = ptr1[4]; + ycIn = ptr1[5]; + xdIn = ptr1[6]; + ydIn = ptr1[7]; + + /* Butterfly implementation */ + /* xa + xc */ + Xaplusc = xaIn + xcIn; + + /* xa - xc */ + Xaminusc = xaIn - xcIn; + + /* ya + yc */ + Yaplusc = yaIn + ycIn; + + /* ya - yc */ + Yaminusc = yaIn - ycIn; + + /* xb + xd */ + Xbplusd = xbIn + xdIn; + + /* yb + yd */ + Ybplusd = ybIn + ydIn; + + /* (xb-xd) */ + Xbminusd = xbIn - xdIn; + + /* (yb-yd) */ + Ybminusd = ybIn - ydIn; + + /* xa' = (xa+xb+xc+xd) * onebyfftLen */ + a0 = (Xaplusc + Xbplusd); + /* ya' = (ya+yb+yc+yd) * onebyfftLen */ + a1 = (Yaplusc + Ybplusd); + /* xc' = (xa-xb+xc-xd) * onebyfftLen */ + a2 = (Xaplusc - Xbplusd); + /* yc' = (ya-yb+yc-yd) * onebyfftLen */ + a3 = (Yaplusc - Ybplusd); + /* xb' = (xa-yb-xc+yd) * onebyfftLen */ + a4 = (Xaminusc - Ybminusd); + /* yb' = (ya+xb-yc-xd) * onebyfftLen */ + a5 = (Yaminusc + Xbminusd); + /* xd' = (xa-yb-xc+yd) * onebyfftLen */ + a6 = (Xaminusc + Ybminusd); + /* yd' = (ya-xb-yc+xd) * onebyfftLen */ + a7 = (Yaminusc - Xbminusd); + + p0 = a0 * onebyfftLen; + p1 = a1 * onebyfftLen; + p2 = a2 * onebyfftLen; + p3 = a3 * onebyfftLen; + p4 = a4 * onebyfftLen; + p5 = a5 * onebyfftLen; + p6 = a6 * onebyfftLen; + p7 = a7 * onebyfftLen; + + /* xa' = (xa+xb+xc+xd) * onebyfftLen */ + ptr1[0] = p0; + /* ya' = (ya+yb+yc+yd) * onebyfftLen */ + ptr1[1] = p1; + /* xc' = (xa-xb+xc-xd) * onebyfftLen */ + ptr1[2] = p2; + /* yc' = (ya-yb+yc-yd) * onebyfftLen */ + ptr1[3] = p3; + /* xb' = (xa-yb-xc+yd) * onebyfftLen */ + ptr1[4] = p4; + /* yb' = (ya+xb-yc-xd) * onebyfftLen */ + ptr1[5] = p5; + /* xd' = (xa-yb-xc+yd) * onebyfftLen */ + ptr1[6] = p6; + /* yd' = (ya-xb-yc+xd) * onebyfftLen */ + ptr1[7] = p7; + + /* increment source pointer by 8 for next calculations */ + ptr1 = ptr1 + 8U; + + } while (--j); + +#else + + float32_t t1, t2, r1, r2, s1, s2; + + /* Initializations for the first stage */ + n2 = fftLen; + n1 = n2; + + /* Calculation of first stage */ + for (k = fftLen; k > 4U; k >>= 2U) + { + /* Initializations for the first stage */ + n1 = n2; + n2 >>= 2U; + ia1 = 0U; + + /* Calculation of first stage */ + j = 0; + do + { + /* index calculation for the coefficients */ + ia2 = ia1 + ia1; + ia3 = ia2 + ia1; + co1 = pCoef[ia1 * 2U]; + si1 = pCoef[(ia1 * 2U) + 1U]; + co2 = pCoef[ia2 * 2U]; + si2 = pCoef[(ia2 * 2U) + 1U]; + co3 = pCoef[ia3 * 2U]; + si3 = pCoef[(ia3 * 2U) + 1U]; + + /* Twiddle coefficients index modifier */ + ia1 = ia1 + twidCoefModifier; + + i0 = j; + do + { + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* xa + xc */ + r1 = pSrc[(2U * i0)] + pSrc[(2U * i2)]; + + /* xa - xc */ + r2 = pSrc[(2U * i0)] - pSrc[(2U * i2)]; + + /* ya + yc */ + s1 = pSrc[(2U * i0) + 1U] + pSrc[(2U * i2) + 1U]; + + /* ya - yc */ + s2 = pSrc[(2U * i0) + 1U] - pSrc[(2U * i2) + 1U]; + + /* xb + xd */ + t1 = pSrc[2U * i1] + pSrc[2U * i3]; + + /* xa' = xa + xb + xc + xd */ + pSrc[2U * i0] = r1 + t1; + + /* xa + xc -(xb + xd) */ + r1 = r1 - t1; + + /* yb + yd */ + t2 = pSrc[(2U * i1) + 1U] + pSrc[(2U * i3) + 1U]; + + /* ya' = ya + yb + yc + yd */ + pSrc[(2U * i0) + 1U] = s1 + t2; + + /* (ya + yc) - (yb + yd) */ + s1 = s1 - t2; + + /* (yb - yd) */ + t1 = pSrc[(2U * i1) + 1U] - pSrc[(2U * i3) + 1U]; + + /* (xb - xd) */ + t2 = pSrc[2U * i1] - pSrc[2U * i3]; + + /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = (r1 * co2) - (s1 * si2); + + /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */ + pSrc[(2U * i1) + 1U] = (s1 * co2) + (r1 * si2); + + /* (xa - xc) - (yb - yd) */ + r1 = r2 - t1; + + /* (xa - xc) + (yb - yd) */ + r2 = r2 + t1; + + /* (ya - yc) + (xb - xd) */ + s1 = s2 + t2; + + /* (ya - yc) - (xb - xd) */ + s2 = s2 - t2; + + /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = (r1 * co1) - (s1 * si1); + + /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = (s1 * co1) + (r1 * si1); + + /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */ + pSrc[2U * i3] = (r2 * co3) - (s2 * si3); + + /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = (s2 * co3) + (r2 * si3); + + i0 += n1; + } while ( i0 < fftLen); + j++; + } while (j <= (n2 - 1U)); + twidCoefModifier <<= 2U; + } + /* Initializations of last stage */ + n1 = n2; + n2 >>= 2U; + + /* Calculations of last stage */ + for (i0 = 0U; i0 <= (fftLen - n1); i0 += n1) + { + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Butterfly implementation */ + /* xa + xc */ + r1 = pSrc[2U * i0] + pSrc[2U * i2]; + + /* xa - xc */ + r2 = pSrc[2U * i0] - pSrc[2U * i2]; + + /* ya + yc */ + s1 = pSrc[(2U * i0) + 1U] + pSrc[(2U * i2) + 1U]; + + /* ya - yc */ + s2 = pSrc[(2U * i0) + 1U] - pSrc[(2U * i2) + 1U]; + + /* xc + xd */ + t1 = pSrc[2U * i1] + pSrc[2U * i3]; + + /* xa' = xa + xb + xc + xd */ + pSrc[2U * i0] = (r1 + t1) * onebyfftLen; + + /* (xa + xb) - (xc + xd) */ + r1 = r1 - t1; + + /* yb + yd */ + t2 = pSrc[(2U * i1) + 1U] + pSrc[(2U * i3) + 1U]; + + /* ya' = ya + yb + yc + yd */ + pSrc[(2U * i0) + 1U] = (s1 + t2) * onebyfftLen; + + /* (ya + yc) - (yb + yd) */ + s1 = s1 - t2; + + /* (yb-yd) */ + t1 = pSrc[(2U * i1) + 1U] - pSrc[(2U * i3) + 1U]; + + /* (xb-xd) */ + t2 = pSrc[2U * i1] - pSrc[2U * i3]; + + /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = r1 * onebyfftLen; + + /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */ + pSrc[(2U * i1) + 1U] = s1 * onebyfftLen; + + /* (xa - xc) - (yb-yd) */ + r1 = r2 - t1; + + /* (xa - xc) + (yb-yd) */ + r2 = r2 + t1; + + /* (ya - yc) + (xb-xd) */ + s1 = s2 + t2; + + /* (ya - yc) - (xb-xd) */ + s2 = s2 - t2; + + /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = r1 * onebyfftLen; + + /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = s1 * onebyfftLen; + + /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */ + pSrc[2U * i3] = r2 * onebyfftLen; + + /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = s2 * onebyfftLen; + } + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ +} + + diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_f32.c new file mode 100644 index 0000000..930c2c1 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_f32.c @@ -0,0 +1,156 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix4_init_f32.c + * Description: Radix-4 Decimation in Frequency Floating-point CFFT & CIFFT Initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Initialization function for the floating-point CFFT/CIFFT. + @deprecated Do not use this function. It has been superceded by \ref arm_cfft_f32 and will be removed in the future. + @param[in,out] S points to an instance of the floating-point CFFT/CIFFT structure + @param[in] fftLen length of the FFT + @param[in] ifftFlag flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : fftLen is not a supported length + + @par Details + The parameter ifftFlag controls whether a forward or inverse transform is computed. + Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated + @par + The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. + Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. + @par + The parameter fftLen Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024. + @par + This Function also initializes Twiddle factor table pointer and Bit reversal table pointer. + */ + +arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag) +{ + /* Initialise the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + + /* Initialise the FFT length */ + S->fftLen = fftLen; + + /* Initialise the Twiddle coefficient pointer */ + S->pTwiddle = (float32_t *) twiddleCoef; + + /* Initialise the Flag for selection of CFFT or CIFFT */ + S->ifftFlag = ifftFlag; + + /* Initialise the Flag for calculation Bit reversal or not */ + S->bitReverseFlag = bitReverseFlag; + + /* Initializations of structure parameters depending on the FFT length */ + switch (S->fftLen) + { + + case 4096U: + /* Initializations of structure parameters for 4096 point FFT */ + + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 1U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 1U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) armBitRevTable; + /* Initialise the 1/fftLen Value */ + S->onebyfftLen = 0.000244140625; + break; + + case 1024U: + /* Initializations of structure parameters for 1024 point FFT */ + + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 4U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 4U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) & armBitRevTable[3]; + /* Initialise the 1/fftLen Value */ + S->onebyfftLen = 0.0009765625f; + break; + + + case 256U: + /* Initializations of structure parameters for 256 point FFT */ + S->twidCoefModifier = 16U; + S->bitRevFactor = 16U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[15]; + S->onebyfftLen = 0.00390625f; + break; + + case 64U: + /* Initializations of structure parameters for 64 point FFT */ + S->twidCoefModifier = 64U; + S->bitRevFactor = 64U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[63]; + S->onebyfftLen = 0.015625f; + break; + + case 16U: + /* Initializations of structure parameters for 16 point FFT */ + S->twidCoefModifier = 256U; + S->bitRevFactor = 256U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[255]; + S->onebyfftLen = 0.0625f; + break; + + + default: + /* Reporting argument error if fftSize is not valid value */ + status = ARM_MATH_ARGUMENT_ERROR; + break; + } + + return (status); +} + +/** + @} end of ComplexFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_q15.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_q15.c new file mode 100644 index 0000000..0090688 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_q15.c @@ -0,0 +1,145 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix4_init_q15.c + * Description: Radix-4 Decimation in Frequency Q15 FFT & IFFT initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupTransforms + */ + + +/** + @addtogroup ComplexFFT + @{ + */ + + +/** + @brief Initialization function for the Q15 CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed in the future. + @param[in,out] S points to an instance of the Q15 CFFT/CIFFT structure + @param[in] fftLen length of the FFT + @param[in] ifftFlag flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : fftLen is not a supported length + + @par Details + The parameter ifftFlag controls whether a forward or inverse transform is computed. + Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated + @par + The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. + Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. + @par + The parameter fftLen Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024. + @par + This Function also initializes Twiddle factor table pointer and Bit reversal table pointer. + */ + +arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag) +{ + /* Initialise the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + /* Initialise the FFT length */ + S->fftLen = fftLen; + /* Initialise the Twiddle coefficient pointer */ + S->pTwiddle = (q15_t *) twiddleCoef_4096_q15; + /* Initialise the Flag for selection of CFFT or CIFFT */ + S->ifftFlag = ifftFlag; + /* Initialise the Flag for calculation Bit reversal or not */ + S->bitReverseFlag = bitReverseFlag; + + /* Initializations of structure parameters depending on the FFT length */ + switch (S->fftLen) + { + case 4096U: + /* Initializations of structure parameters for 4096 point FFT */ + + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 1U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 1U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) armBitRevTable; + + break; + + case 1024U: + /* Initializations of structure parameters for 1024 point FFT */ + S->twidCoefModifier = 4U; + S->bitRevFactor = 4U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[3]; + + break; + + case 256U: + /* Initializations of structure parameters for 256 point FFT */ + S->twidCoefModifier = 16U; + S->bitRevFactor = 16U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[15]; + + break; + + case 64U: + /* Initializations of structure parameters for 64 point FFT */ + S->twidCoefModifier = 64U; + S->bitRevFactor = 64U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[63]; + + break; + + case 16U: + /* Initializations of structure parameters for 16 point FFT */ + S->twidCoefModifier = 256U; + S->bitRevFactor = 256U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[255]; + + break; + + default: + /* Reporting argument error if fftSize is not valid value */ + status = ARM_MATH_ARGUMENT_ERROR; + break; + } + + return (status); +} + +/** + @} end of ComplexFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_q31.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_q31.c new file mode 100644 index 0000000..17d16b7 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_init_q31.c @@ -0,0 +1,141 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix4_init_q31.c + * Description: Radix-4 Decimation in Frequency Q31 FFT & IFFT initialization function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + + @brief Initialization function for the Q31 CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed in the future. + @param[in,out] S points to an instance of the Q31 CFFT/CIFFT structure. + @param[in] fftLen length of the FFT. + @param[in] ifftFlag flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : fftLen is not a supported length + + @par Details + The parameter ifftFlag controls whether a forward or inverse transform is computed. + Set(=1) ifftFlag for calculation of CIFFT otherwise CFFT is calculated + @par + The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. + Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. + @par + The parameter fftLen Specifies length of CFFT/CIFFT process. Supported FFT Lengths are 16, 64, 256, 1024. + @par + This Function also initializes Twiddle factor table pointer and Bit reversal table pointer. +*/ + +arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag) +{ + /* Initialise the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + /* Initialise the FFT length */ + S->fftLen = fftLen; + /* Initialise the Twiddle coefficient pointer */ + S->pTwiddle = (q31_t *) twiddleCoef_4096_q31; + /* Initialise the Flag for selection of CFFT or CIFFT */ + S->ifftFlag = ifftFlag; + /* Initialise the Flag for calculation Bit reversal or not */ + S->bitReverseFlag = bitReverseFlag; + + /* Initializations of Instance structure depending on the FFT length */ + switch (S->fftLen) + { + /* Initializations of structure parameters for 4096 point FFT */ + case 4096U: + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 1U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 1U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) armBitRevTable; + break; + + /* Initializations of structure parameters for 1024 point FFT */ + case 1024U: + /* Initialise the twiddle coef modifier value */ + S->twidCoefModifier = 4U; + /* Initialise the bit reversal table modifier */ + S->bitRevFactor = 4U; + /* Initialise the bit reversal table pointer */ + S->pBitRevTable = (uint16_t *) & armBitRevTable[3]; + break; + + case 256U: + /* Initializations of structure parameters for 256 point FFT */ + S->twidCoefModifier = 16U; + S->bitRevFactor = 16U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[15]; + break; + + case 64U: + /* Initializations of structure parameters for 64 point FFT */ + S->twidCoefModifier = 64U; + S->bitRevFactor = 64U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[63]; + break; + + case 16U: + /* Initializations of structure parameters for 16 point FFT */ + S->twidCoefModifier = 256U; + S->bitRevFactor = 256U; + S->pBitRevTable = (uint16_t *) & armBitRevTable[255]; + break; + + default: + /* Reporting argument error if fftSize is not valid value */ + status = ARM_MATH_ARGUMENT_ERROR; + break; + } + + return (status); +} + +/** + @} end of ComplexFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_q15.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_q15.c new file mode 100644 index 0000000..b4cabb1 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_q15.c @@ -0,0 +1,1809 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix4_q15.c + * Description: This file has function definition of Radix-4 FFT & IFFT function and + * In-place bit reversal using bit reversal table + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + + +void arm_radix4_butterfly_q15( + q15_t * pSrc16, + uint32_t fftLen, + const q15_t * pCoef16, + uint32_t twidCoefModifier); + +void arm_radix4_butterfly_inverse_q15( + q15_t * pSrc16, + uint32_t fftLen, + const q15_t * pCoef16, + uint32_t twidCoefModifier); + +void arm_bitreversal_q15( + q15_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + const uint16_t * pBitRevTab); + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + + +/** + @brief Processing function for the Q15 CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q15 and will be removed in the future. + @param[in] S points to an instance of the Q15 CFFT/CIFFT structure. + @param[in,out] pSrc points to the complex data buffer. Processing occurs in-place. + @return none + + @par Input and output formats: + Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process. + Hence the output format is different for different FFT sizes. + The input and output formats for different FFT sizes and number of bits to upscale are mentioned in the tables below for CFFT and CIFFT: + @par + \image html CFFTQ15.gif "Input and Output Formats for Q15 CFFT" + \image html CIFFTQ15.gif "Input and Output Formats for Q15 CIFFT" + */ + +void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc) +{ + if (S->ifftFlag == 1U) + { + /* Complex IFFT radix-4 */ + arm_radix4_butterfly_inverse_q15(pSrc, S->fftLen, S->pTwiddle, S->twidCoefModifier); + } + else + { + /* Complex FFT radix-4 */ + arm_radix4_butterfly_q15(pSrc, S->fftLen, S->pTwiddle, S->twidCoefModifier); + } + + if (S->bitReverseFlag == 1U) + { + /* Bit Reversal */ + arm_bitreversal_q15(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable); + } + +} + +/** + @} end of ComplexFFT group + */ + +/* + * Radix-4 FFT algorithm used is : + * + * Input real and imaginary data: + * x(n) = xa + j * ya + * x(n+N/4 ) = xb + j * yb + * x(n+N/2 ) = xc + j * yc + * x(n+3N 4) = xd + j * yd + * + * + * Output real and imaginary data: + * x(4r) = xa'+ j * ya' + * x(4r+1) = xb'+ j * yb' + * x(4r+2) = xc'+ j * yc' + * x(4r+3) = xd'+ j * yd' + * + * + * Twiddle factors for radix-4 FFT: + * Wn = co1 + j * (- si1) + * W2n = co2 + j * (- si2) + * W3n = co3 + j * (- si3) + + * The real and imaginary output values for the radix-4 butterfly are + * xa' = xa + xb + xc + xd + * ya' = ya + yb + yc + yd + * xb' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) + * yb' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) + * xc' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) + * yc' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) + * xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3) + * yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3) + * + */ + +/** + @brief Core function for the Q15 CFFT butterfly process. + @param[in,out] pSrc16 points to the in-place buffer of Q15 data type + @param[in] fftLen length of the FFT + @param[in] pCoef16 points to twiddle coefficient buffer + @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table + @return none + */ + +void arm_radix4_butterfly_q15( + q15_t * pSrc16, + uint32_t fftLen, + const q15_t * pCoef16, + uint32_t twidCoefModifier) +{ + +#if defined (ARM_MATH_DSP) + + q31_t R, S, T, U; + q31_t C1, C2, C3, out1, out2; + uint32_t n1, n2, ic, i0, j, k; + + q15_t *ptr1; + q15_t *pSi0; + q15_t *pSi1; + q15_t *pSi2; + q15_t *pSi3; + + q31_t xaya, xbyb, xcyc, xdyd; + + /* Total process is divided into three stages */ + + /* process first stage, middle stages, & last stage */ + + /* Initializations for the first stage */ + n2 = fftLen; + n1 = n2; + + /* n2 = fftLen/4 */ + n2 >>= 2U; + + /* Index for twiddle coefficient */ + ic = 0U; + + /* Index for input read and output write */ + j = n2; + + pSi0 = pSrc16; + pSi1 = pSi0 + 2 * n2; + pSi2 = pSi1 + 2 * n2; + pSi3 = pSi2 + 2 * n2; + + /* Input is in 1.15(q15) format */ + + /* start of first stage process */ + do + { + /* Butterfly implementation */ + + /* Reading i0, i0+fftLen/2 inputs */ + /* Read ya (real), xa(imag) input */ + T = read_q15x2 (pSi0); + T = __SHADD16(T, 0); /* this is just a SIMD arithmetic shift right by 1 */ + T = __SHADD16(T, 0); /* it turns out doing this twice is 2 cycles, the alternative takes 3 cycles */ +/* + in = ((int16_t) (T & 0xFFFF)) >> 2; // alternative code that takes 3 cycles + T = ((T >> 2) & 0xFFFF0000) | (in & 0xFFFF); +*/ + + /* Read yc (real), xc(imag) input */ + S = read_q15x2 (pSi2); + S = __SHADD16(S, 0); + S = __SHADD16(S, 0); + + /* R = packed((ya + yc), (xa + xc) ) */ + R = __QADD16(T, S); + + /* S = packed((ya - yc), (xa - xc) ) */ + S = __QSUB16(T, S); + + /* Reading i0+fftLen/4 , i0+3fftLen/4 inputs */ + /* Read yb (real), xb(imag) input */ + T = read_q15x2 (pSi1); + T = __SHADD16(T, 0); + T = __SHADD16(T, 0); + + /* Read yd (real), xd(imag) input */ + U = read_q15x2 (pSi3); + U = __SHADD16(U, 0); + U = __SHADD16(U, 0); + + /* T = packed((yb + yd), (xb + xd) ) */ + T = __QADD16(T, U); + + /* writing the butterfly processed i0 sample */ + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + write_q15x2_ia (&pSi0, __SHADD16(R, T)); + + /* R = packed((ya + yc) - (yb + yd), (xa + xc)- (xb + xd)) */ + R = __QSUB16(R, T); + + /* co2 & si2 are read from SIMD Coefficient pointer */ + C2 = read_q15x2 ((q15_t *) pCoef16 + (4U * ic)); + +#ifndef ARM_MATH_BIG_ENDIAN + /* xc' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) */ + out1 = __SMUAD(C2, R) >> 16U; + /* yc' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + out2 = __SMUSDX(C2, R); +#else + /* xc' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + out1 = __SMUSDX(R, C2) >> 16U; + /* yc' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) */ + out2 = __SMUAD(C2, R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Reading i0+fftLen/4 */ + /* T = packed(yb, xb) */ + T = read_q15x2 (pSi1); + T = __SHADD16(T, 0); + T = __SHADD16(T, 0); + + /* writing the butterfly processed i0 + fftLen/4 sample */ + /* writing output(xc', yc') in little endian format */ + write_q15x2_ia (&pSi1, (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + /* Butterfly calculations */ + /* U = packed(yd, xd) */ + U = read_q15x2 (pSi3); + U = __SHADD16(U, 0); + U = __SHADD16(U, 0); + + /* T = packed(yb-yd, xb-xd) */ + T = __QSUB16(T, U); + +#ifndef ARM_MATH_BIG_ENDIAN + /* R = packed((ya-yc) + (xb- xd) , (xa-xc) - (yb-yd)) */ + R = __QASX(S, T); + /* S = packed((ya-yc) - (xb- xd), (xa-xc) + (yb-yd)) */ + S = __QSAX(S, T); +#else + /* R = packed((ya-yc) + (xb- xd) , (xa-xc) - (yb-yd)) */ + R = __QSAX(S, T); + /* S = packed((ya-yc) - (xb- xd), (xa-xc) + (yb-yd)) */ + S = __QASX(S, T); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* co1 & si1 are read from SIMD Coefficient pointer */ + C1 = read_q15x2 ((q15_t *) pCoef16 + (2U * ic)); + /* Butterfly process for the i0+fftLen/2 sample */ + +#ifndef ARM_MATH_BIG_ENDIAN + /* xb' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) */ + out1 = __SMUAD(C1, S) >> 16U; + /* yb' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) */ + out2 = __SMUSDX(C1, S); +#else + /* xb' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) */ + out1 = __SMUSDX(S, C1) >> 16U; + /* yb' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) */ + out2 = __SMUAD(C1, S); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* writing output(xb', yb') in little endian format */ + write_q15x2_ia (&pSi2, ((out2) & 0xFFFF0000) | ((out1) & 0x0000FFFF)); + + /* co3 & si3 are read from SIMD Coefficient pointer */ + C3 = read_q15x2 ((q15_t *) pCoef16 + (6U * ic)); + /* Butterfly process for the i0+3fftLen/4 sample */ + +#ifndef ARM_MATH_BIG_ENDIAN + /* xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3) */ + out1 = __SMUAD(C3, R) >> 16U; + /* yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3) */ + out2 = __SMUSDX(C3, R); +#else + /* xd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3) */ + out1 = __SMUSDX(R, C3) >> 16U; + /* yd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3) */ + out2 = __SMUAD(C3, R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* writing output(xd', yd') in little endian format */ + write_q15x2_ia (&pSi3, ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + /* Twiddle coefficients index modifier */ + ic = ic + twidCoefModifier; + + } while (--j); + /* data is in 4.11(q11) format */ + + /* end of first stage process */ + + + /* start of middle stage process */ + + /* Twiddle coefficients index modifier */ + twidCoefModifier <<= 2U; + + /* Calculation of Middle stage */ + for (k = fftLen / 4U; k > 4U; k >>= 2U) + { + /* Initializations for the middle stage */ + n1 = n2; + n2 >>= 2U; + ic = 0U; + + for (j = 0U; j <= (n2 - 1U); j++) + { + /* index calculation for the coefficients */ + C1 = read_q15x2 ((q15_t *) pCoef16 + (2U * ic)); + C2 = read_q15x2 ((q15_t *) pCoef16 + (4U * ic)); + C3 = read_q15x2 ((q15_t *) pCoef16 + (6U * ic)); + + /* Twiddle coefficients index modifier */ + ic = ic + twidCoefModifier; + + pSi0 = pSrc16 + 2 * j; + pSi1 = pSi0 + 2 * n2; + pSi2 = pSi1 + 2 * n2; + pSi3 = pSi2 + 2 * n2; + + /* Butterfly implementation */ + for (i0 = j; i0 < fftLen; i0 += n1) + { + /* Reading i0, i0+fftLen/2 inputs */ + /* Read ya (real), xa(imag) input */ + T = read_q15x2 (pSi0); + + /* Read yc (real), xc(imag) input */ + S = read_q15x2 (pSi2); + + /* R = packed( (ya + yc), (xa + xc)) */ + R = __QADD16(T, S); + + /* S = packed((ya - yc), (xa - xc)) */ + S = __QSUB16(T, S); + + /* Reading i0+fftLen/4 , i0+3fftLen/4 inputs */ + /* Read yb (real), xb(imag) input */ + T = read_q15x2 (pSi1); + + /* Read yd (real), xd(imag) input */ + U = read_q15x2 (pSi3); + + /* T = packed( (yb + yd), (xb + xd)) */ + T = __QADD16(T, U); + + /* writing the butterfly processed i0 sample */ + + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + out1 = __SHADD16(R, T); + out1 = __SHADD16(out1, 0); + write_q15x2 (pSi0, out1); + pSi0 += 2 * n1; + + /* R = packed( (ya + yc) - (yb + yd), (xa + xc) - (xb + xd)) */ + R = __SHSUB16(R, T); + +#ifndef ARM_MATH_BIG_ENDIAN + /* (ya-yb+yc-yd)* (si2) + (xa-xb+xc-xd)* co2 */ + out1 = __SMUAD(C2, R) >> 16U; + + /* (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + out2 = __SMUSDX(C2, R); +#else + /* (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + out1 = __SMUSDX(R, C2) >> 16U; + + /* (ya-yb+yc-yd)* (si2) + (xa-xb+xc-xd)* co2 */ + out2 = __SMUAD(C2, R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Reading i0+3fftLen/4 */ + /* Read yb (real), xb(imag) input */ + T = read_q15x2 (pSi1); + + /* writing the butterfly processed i0 + fftLen/4 sample */ + /* xc' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) */ + /* yc' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + write_q15x2 (pSi1, ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + pSi1 += 2 * n1; + + /* Butterfly calculations */ + + /* Read yd (real), xd(imag) input */ + U = read_q15x2 (pSi3); + + /* T = packed(yb-yd, xb-xd) */ + T = __QSUB16(T, U); + +#ifndef ARM_MATH_BIG_ENDIAN + /* R = packed((ya-yc) + (xb- xd) , (xa-xc) - (yb-yd)) */ + R = __SHASX(S, T); + + /* S = packed((ya-yc) - (xb- xd), (xa-xc) + (yb-yd)) */ + S = __SHSAX(S, T); + + + /* Butterfly process for the i0+fftLen/2 sample */ + out1 = __SMUAD(C1, S) >> 16U; + out2 = __SMUSDX(C1, S); +#else + /* R = packed((ya-yc) + (xb- xd) , (xa-xc) - (yb-yd)) */ + R = __SHSAX(S, T); + + /* S = packed((ya-yc) - (xb- xd), (xa-xc) + (yb-yd)) */ + S = __SHASX(S, T); + + + /* Butterfly process for the i0+fftLen/2 sample */ + out1 = __SMUSDX(S, C1) >> 16U; + out2 = __SMUAD(C1, S); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* xb' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) */ + /* yb' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) */ + write_q15x2 (pSi2, ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + pSi2 += 2 * n1; + + /* Butterfly process for the i0+3fftLen/4 sample */ + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUAD(C3, R) >> 16U; + out2 = __SMUSDX(C3, R); +#else + out1 = __SMUSDX(R, C3) >> 16U; + out2 = __SMUAD(C3, R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3) */ + /* yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3) */ + write_q15x2 (pSi3, ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + pSi3 += 2 * n1; + } + } + /* Twiddle coefficients index modifier */ + twidCoefModifier <<= 2U; + } + /* end of middle stage process */ + + + /* data is in 10.6(q6) format for the 1024 point */ + /* data is in 8.8(q8) format for the 256 point */ + /* data is in 6.10(q10) format for the 64 point */ + /* data is in 4.12(q12) format for the 16 point */ + + /* Initializations for the last stage */ + j = fftLen >> 2; + + ptr1 = &pSrc16[0]; + + /* start of last stage process */ + + /* Butterfly implementation */ + do + { + /* Read xa (real), ya(imag) input */ + xaya = read_q15x2_ia ((q15_t **) &ptr1); + + /* Read xb (real), yb(imag) input */ + xbyb = read_q15x2_ia ((q15_t **) &ptr1); + + /* Read xc (real), yc(imag) input */ + xcyc = read_q15x2_ia ((q15_t **) &ptr1); + + /* Read xd (real), yd(imag) input */ + xdyd = read_q15x2_ia ((q15_t **) &ptr1); + + /* R = packed((ya + yc), (xa + xc)) */ + R = __QADD16(xaya, xcyc); + + /* T = packed((yb + yd), (xb + xd)) */ + T = __QADD16(xbyb, xdyd); + + /* pointer updation for writing */ + ptr1 = ptr1 - 8U; + + + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + write_q15x2_ia (&ptr1, __SHADD16(R, T)); + + /* T = packed((yb + yd), (xb + xd)) */ + T = __QADD16(xbyb, xdyd); + + /* xc' = (xa-xb+xc-xd) */ + /* yc' = (ya-yb+yc-yd) */ + write_q15x2_ia (&ptr1, __SHSUB16(R, T)); + + /* S = packed((ya - yc), (xa - xc)) */ + S = __QSUB16(xaya, xcyc); + + /* Read yd (real), xd(imag) input */ + /* T = packed( (yb - yd), (xb - xd)) */ + U = __QSUB16(xbyb, xdyd); + +#ifndef ARM_MATH_BIG_ENDIAN + /* xb' = (xa+yb-xc-yd) */ + /* yb' = (ya-xb-yc+xd) */ + write_q15x2_ia (&ptr1, __SHSAX(S, U)); + + /* xd' = (xa-yb-xc+yd) */ + /* yd' = (ya+xb-yc-xd) */ + write_q15x2_ia (&ptr1, __SHASX(S, U)); +#else + /* xb' = (xa+yb-xc-yd) */ + /* yb' = (ya-xb-yc+xd) */ + write_q15x2_ia (&ptr1, __SHASX(S, U)); + + /* xd' = (xa-yb-xc+yd) */ + /* yd' = (ya+xb-yc-xd) */ + write_q15x2_ia (&ptr1, __SHSAX(S, U)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + } while (--j); + + /* end of last stage process */ + + /* output is in 11.5(q5) format for the 1024 point */ + /* output is in 9.7(q7) format for the 256 point */ + /* output is in 7.9(q9) format for the 64 point */ + /* output is in 5.11(q11) format for the 16 point */ + + +#else /* #if defined (ARM_MATH_DSP) */ + + q15_t R0, R1, S0, S1, T0, T1, U0, U1; + q15_t Co1, Si1, Co2, Si2, Co3, Si3, out1, out2; + uint32_t n1, n2, ic, i0, i1, i2, i3, j, k; + + /* Total process is divided into three stages */ + + /* process first stage, middle stages, & last stage */ + + /* Initializations for the first stage */ + n2 = fftLen; + n1 = n2; + + /* n2 = fftLen/4 */ + n2 >>= 2U; + + /* Index for twiddle coefficient */ + ic = 0U; + + /* Index for input read and output write */ + i0 = 0U; + j = n2; + + /* Input is in 1.15(q15) format */ + + /* start of first stage process */ + do + { + /* Butterfly implementation */ + + /* index calculation for the input as, */ + /* pSrc16[i0 + 0], pSrc16[i0 + fftLen/4], pSrc16[i0 + fftLen/2], pSrc16[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Reading i0, i0+fftLen/2 inputs */ + + /* input is down scale by 4 to avoid overflow */ + /* Read ya (real), xa(imag) input */ + T0 = pSrc16[i0 * 2U] >> 2U; + T1 = pSrc16[(i0 * 2U) + 1U] >> 2U; + + /* input is down scale by 4 to avoid overflow */ + /* Read yc (real), xc(imag) input */ + S0 = pSrc16[i2 * 2U] >> 2U; + S1 = pSrc16[(i2 * 2U) + 1U] >> 2U; + + /* R0 = (ya + yc) */ + R0 = __SSAT(T0 + S0, 16U); + /* R1 = (xa + xc) */ + R1 = __SSAT(T1 + S1, 16U); + + /* S0 = (ya - yc) */ + S0 = __SSAT(T0 - S0, 16); + /* S1 = (xa - xc) */ + S1 = __SSAT(T1 - S1, 16); + + /* Reading i0+fftLen/4 , i0+3fftLen/4 inputs */ + /* input is down scale by 4 to avoid overflow */ + /* Read yb (real), xb(imag) input */ + T0 = pSrc16[i1 * 2U] >> 2U; + T1 = pSrc16[(i1 * 2U) + 1U] >> 2U; + + /* input is down scale by 4 to avoid overflow */ + /* Read yd (real), xd(imag) input */ + U0 = pSrc16[i3 * 2U] >> 2U; + U1 = pSrc16[(i3 * 2U) + 1] >> 2U; + + /* T0 = (yb + yd) */ + T0 = __SSAT(T0 + U0, 16U); + /* T1 = (xb + xd) */ + T1 = __SSAT(T1 + U1, 16U); + + /* writing the butterfly processed i0 sample */ + /* ya' = ya + yb + yc + yd */ + /* xa' = xa + xb + xc + xd */ + pSrc16[i0 * 2U] = (R0 >> 1U) + (T0 >> 1U); + pSrc16[(i0 * 2U) + 1U] = (R1 >> 1U) + (T1 >> 1U); + + /* R0 = (ya + yc) - (yb + yd) */ + /* R1 = (xa + xc) - (xb + xd) */ + R0 = __SSAT(R0 - T0, 16U); + R1 = __SSAT(R1 - T1, 16U); + + /* co2 & si2 are read from Coefficient pointer */ + Co2 = pCoef16[2U * ic * 2U]; + Si2 = pCoef16[(2U * ic * 2U) + 1]; + + /* xc' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) */ + out1 = (q15_t) ((Co2 * R0 + Si2 * R1) >> 16U); + /* yc' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + out2 = (q15_t) ((-Si2 * R0 + Co2 * R1) >> 16U); + + /* Reading i0+fftLen/4 */ + /* input is down scale by 4 to avoid overflow */ + /* T0 = yb, T1 = xb */ + T0 = pSrc16[i1 * 2U] >> 2; + T1 = pSrc16[(i1 * 2U) + 1] >> 2; + + /* writing the butterfly processed i0 + fftLen/4 sample */ + /* writing output(xc', yc') in little endian format */ + pSrc16[i1 * 2U] = out1; + pSrc16[(i1 * 2U) + 1] = out2; + + /* Butterfly calculations */ + /* input is down scale by 4 to avoid overflow */ + /* U0 = yd, U1 = xd */ + U0 = pSrc16[i3 * 2U] >> 2; + U1 = pSrc16[(i3 * 2U) + 1] >> 2; + /* T0 = yb-yd */ + T0 = __SSAT(T0 - U0, 16); + /* T1 = xb-xd */ + T1 = __SSAT(T1 - U1, 16); + + /* R1 = (ya-yc) + (xb- xd), R0 = (xa-xc) - (yb-yd)) */ + R0 = (q15_t) __SSAT((q31_t) (S0 - T1), 16); + R1 = (q15_t) __SSAT((q31_t) (S1 + T0), 16); + + /* S1 = (ya-yc) - (xb- xd), S0 = (xa-xc) + (yb-yd)) */ + S0 = (q15_t) __SSAT(((q31_t) S0 + T1), 16U); + S1 = (q15_t) __SSAT(((q31_t) S1 - T0), 16U); + + /* co1 & si1 are read from Coefficient pointer */ + Co1 = pCoef16[ic * 2U]; + Si1 = pCoef16[(ic * 2U) + 1]; + /* Butterfly process for the i0+fftLen/2 sample */ + /* xb' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) */ + out1 = (q15_t) ((Si1 * S1 + Co1 * S0) >> 16); + /* yb' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) */ + out2 = (q15_t) ((-Si1 * S0 + Co1 * S1) >> 16); + + /* writing output(xb', yb') in little endian format */ + pSrc16[i2 * 2U] = out1; + pSrc16[(i2 * 2U) + 1] = out2; + + /* Co3 & si3 are read from Coefficient pointer */ + Co3 = pCoef16[3U * (ic * 2U)]; + Si3 = pCoef16[(3U * (ic * 2U)) + 1]; + /* Butterfly process for the i0+3fftLen/4 sample */ + /* xd' = (xa-yb-xc+yd)* Co3 + (ya+xb-yc-xd)* (si3) */ + out1 = (q15_t) ((Si3 * R1 + Co3 * R0) >> 16U); + /* yd' = (ya+xb-yc-xd)* Co3 - (xa-yb-xc+yd)* (si3) */ + out2 = (q15_t) ((-Si3 * R0 + Co3 * R1) >> 16U); + /* writing output(xd', yd') in little endian format */ + pSrc16[i3 * 2U] = out1; + pSrc16[(i3 * 2U) + 1] = out2; + + /* Twiddle coefficients index modifier */ + ic = ic + twidCoefModifier; + + /* Updating input index */ + i0 = i0 + 1U; + + } while (--j); + /* data is in 4.11(q11) format */ + + /* end of first stage process */ + + + /* start of middle stage process */ + + /* Twiddle coefficients index modifier */ + twidCoefModifier <<= 2U; + + /* Calculation of Middle stage */ + for (k = fftLen / 4U; k > 4U; k >>= 2U) + { + /* Initializations for the middle stage */ + n1 = n2; + n2 >>= 2U; + ic = 0U; + + for (j = 0U; j <= (n2 - 1U); j++) + { + /* index calculation for the coefficients */ + Co1 = pCoef16[ic * 2U]; + Si1 = pCoef16[(ic * 2U) + 1U]; + Co2 = pCoef16[2U * (ic * 2U)]; + Si2 = pCoef16[(2U * (ic * 2U)) + 1U]; + Co3 = pCoef16[3U * (ic * 2U)]; + Si3 = pCoef16[(3U * (ic * 2U)) + 1U]; + + /* Twiddle coefficients index modifier */ + ic = ic + twidCoefModifier; + + /* Butterfly implementation */ + for (i0 = j; i0 < fftLen; i0 += n1) + { + /* index calculation for the input as, */ + /* pSrc16[i0 + 0], pSrc16[i0 + fftLen/4], pSrc16[i0 + fftLen/2], pSrc16[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Reading i0, i0+fftLen/2 inputs */ + /* Read ya (real), xa(imag) input */ + T0 = pSrc16[i0 * 2U]; + T1 = pSrc16[(i0 * 2U) + 1U]; + + /* Read yc (real), xc(imag) input */ + S0 = pSrc16[i2 * 2U]; + S1 = pSrc16[(i2 * 2U) + 1U]; + + /* R0 = (ya + yc), R1 = (xa + xc) */ + R0 = __SSAT(T0 + S0, 16); + R1 = __SSAT(T1 + S1, 16); + + /* S0 = (ya - yc), S1 =(xa - xc) */ + S0 = __SSAT(T0 - S0, 16); + S1 = __SSAT(T1 - S1, 16); + + /* Reading i0+fftLen/4 , i0+3fftLen/4 inputs */ + /* Read yb (real), xb(imag) input */ + T0 = pSrc16[i1 * 2U]; + T1 = pSrc16[(i1 * 2U) + 1U]; + + /* Read yd (real), xd(imag) input */ + U0 = pSrc16[i3 * 2U]; + U1 = pSrc16[(i3 * 2U) + 1U]; + + + /* T0 = (yb + yd), T1 = (xb + xd) */ + T0 = __SSAT(T0 + U0, 16); + T1 = __SSAT(T1 + U1, 16); + + /* writing the butterfly processed i0 sample */ + + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + out1 = ((R0 >> 1U) + (T0 >> 1U)) >> 1U; + out2 = ((R1 >> 1U) + (T1 >> 1U)) >> 1U; + + pSrc16[i0 * 2U] = out1; + pSrc16[(2U * i0) + 1U] = out2; + + /* R0 = (ya + yc) - (yb + yd), R1 = (xa + xc) - (xb + xd) */ + R0 = (R0 >> 1U) - (T0 >> 1U); + R1 = (R1 >> 1U) - (T1 >> 1U); + + /* (ya-yb+yc-yd)* (si2) + (xa-xb+xc-xd)* co2 */ + out1 = (q15_t) ((Co2 * R0 + Si2 * R1) >> 16U); + + /* (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + out2 = (q15_t) ((-Si2 * R0 + Co2 * R1) >> 16U); + + /* Reading i0+3fftLen/4 */ + /* Read yb (real), xb(imag) input */ + T0 = pSrc16[i1 * 2U]; + T1 = pSrc16[(i1 * 2U) + 1U]; + + /* writing the butterfly processed i0 + fftLen/4 sample */ + /* xc' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) */ + /* yc' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + pSrc16[i1 * 2U] = out1; + pSrc16[(i1 * 2U) + 1U] = out2; + + /* Butterfly calculations */ + + /* Read yd (real), xd(imag) input */ + U0 = pSrc16[i3 * 2U]; + U1 = pSrc16[(i3 * 2U) + 1U]; + + /* T0 = yb-yd, T1 = xb-xd */ + T0 = __SSAT(T0 - U0, 16); + T1 = __SSAT(T1 - U1, 16); + + /* R0 = (ya-yc) + (xb- xd), R1 = (xa-xc) - (yb-yd)) */ + R0 = (S0 >> 1U) - (T1 >> 1U); + R1 = (S1 >> 1U) + (T0 >> 1U); + + /* S0 = (ya-yc) - (xb- xd), S1 = (xa-xc) + (yb-yd)) */ + S0 = (S0 >> 1U) + (T1 >> 1U); + S1 = (S1 >> 1U) - (T0 >> 1U); + + /* Butterfly process for the i0+fftLen/2 sample */ + out1 = (q15_t) ((Co1 * S0 + Si1 * S1) >> 16U); + + out2 = (q15_t) ((-Si1 * S0 + Co1 * S1) >> 16U); + + /* xb' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) */ + /* yb' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) */ + pSrc16[i2 * 2U] = out1; + pSrc16[(i2 * 2U) + 1U] = out2; + + /* Butterfly process for the i0+3fftLen/4 sample */ + out1 = (q15_t) ((Si3 * R1 + Co3 * R0) >> 16U); + + out2 = (q15_t) ((-Si3 * R0 + Co3 * R1) >> 16U); + /* xd' = (xa-yb-xc+yd)* Co3 + (ya+xb-yc-xd)* (si3) */ + /* yd' = (ya+xb-yc-xd)* Co3 - (xa-yb-xc+yd)* (si3) */ + pSrc16[i3 * 2U] = out1; + pSrc16[(i3 * 2U) + 1U] = out2; + } + } + /* Twiddle coefficients index modifier */ + twidCoefModifier <<= 2U; + } + /* end of middle stage process */ + + + /* data is in 10.6(q6) format for the 1024 point */ + /* data is in 8.8(q8) format for the 256 point */ + /* data is in 6.10(q10) format for the 64 point */ + /* data is in 4.12(q12) format for the 16 point */ + + /* Initializations for the last stage */ + n1 = n2; + n2 >>= 2U; + + /* start of last stage process */ + + /* Butterfly implementation */ + for (i0 = 0U; i0 <= (fftLen - n1); i0 += n1) + { + /* index calculation for the input as, */ + /* pSrc16[i0 + 0], pSrc16[i0 + fftLen/4], pSrc16[i0 + fftLen/2], pSrc16[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Reading i0, i0+fftLen/2 inputs */ + /* Read ya (real), xa(imag) input */ + T0 = pSrc16[i0 * 2U]; + T1 = pSrc16[(i0 * 2U) + 1U]; + + /* Read yc (real), xc(imag) input */ + S0 = pSrc16[i2 * 2U]; + S1 = pSrc16[(i2 * 2U) + 1U]; + + /* R0 = (ya + yc), R1 = (xa + xc) */ + R0 = __SSAT(T0 + S0, 16U); + R1 = __SSAT(T1 + S1, 16U); + + /* S0 = (ya - yc), S1 = (xa - xc) */ + S0 = __SSAT(T0 - S0, 16U); + S1 = __SSAT(T1 - S1, 16U); + + /* Reading i0+fftLen/4 , i0+3fftLen/4 inputs */ + /* Read yb (real), xb(imag) input */ + T0 = pSrc16[i1 * 2U]; + T1 = pSrc16[(i1 * 2U) + 1U]; + /* Read yd (real), xd(imag) input */ + U0 = pSrc16[i3 * 2U]; + U1 = pSrc16[(i3 * 2U) + 1U]; + + /* T0 = (yb + yd), T1 = (xb + xd)) */ + T0 = __SSAT(T0 + U0, 16U); + T1 = __SSAT(T1 + U1, 16U); + + /* writing the butterfly processed i0 sample */ + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + pSrc16[i0 * 2U] = (R0 >> 1U) + (T0 >> 1U); + pSrc16[(i0 * 2U) + 1U] = (R1 >> 1U) + (T1 >> 1U); + + /* R0 = (ya + yc) - (yb + yd), R1 = (xa + xc) - (xb + xd) */ + R0 = (R0 >> 1U) - (T0 >> 1U); + R1 = (R1 >> 1U) - (T1 >> 1U); + /* Read yb (real), xb(imag) input */ + T0 = pSrc16[i1 * 2U]; + T1 = pSrc16[(i1 * 2U) + 1U]; + + /* writing the butterfly processed i0 + fftLen/4 sample */ + /* xc' = (xa-xb+xc-xd) */ + /* yc' = (ya-yb+yc-yd) */ + pSrc16[i1 * 2U] = R0; + pSrc16[(i1 * 2U) + 1U] = R1; + + /* Read yd (real), xd(imag) input */ + U0 = pSrc16[i3 * 2U]; + U1 = pSrc16[(i3 * 2U) + 1U]; + /* T0 = (yb - yd), T1 = (xb - xd) */ + T0 = __SSAT(T0 - U0, 16U); + T1 = __SSAT(T1 - U1, 16U); + + /* writing the butterfly processed i0 + fftLen/2 sample */ + /* xb' = (xa+yb-xc-yd) */ + /* yb' = (ya-xb-yc+xd) */ + pSrc16[i2 * 2U] = (S0 >> 1U) + (T1 >> 1U); + pSrc16[(i2 * 2U) + 1U] = (S1 >> 1U) - (T0 >> 1U); + + /* writing the butterfly processed i0 + 3fftLen/4 sample */ + /* xd' = (xa-yb-xc+yd) */ + /* yd' = (ya+xb-yc-xd) */ + pSrc16[i3 * 2U] = (S0 >> 1U) - (T1 >> 1U); + pSrc16[(i3 * 2U) + 1U] = (S1 >> 1U) + (T0 >> 1U); + + } + + /* end of last stage process */ + + /* output is in 11.5(q5) format for the 1024 point */ + /* output is in 9.7(q7) format for the 256 point */ + /* output is in 7.9(q9) format for the 64 point */ + /* output is in 5.11(q11) format for the 16 point */ + +#endif /* #if defined (ARM_MATH_DSP) */ + +} + + +/** + @brief Core function for the Q15 CIFFT butterfly process. + @param[in,out] pSrc16 points to the in-place buffer of Q15 data type + @param[in] fftLen length of the FFT + @param[in] pCoef16 points to twiddle coefficient buffer + @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + @return none + */ + +/* + * Radix-4 IFFT algorithm used is : + * + * CIFFT uses same twiddle coefficients as CFFT function + * x[k] = x[n] + (j)k * x[n + fftLen/4] + (-1)k * x[n+fftLen/2] + (-j)k * x[n+3*fftLen/4] + * + * + * IFFT is implemented with following changes in equations from FFT + * + * Input real and imaginary data: + * x(n) = xa + j * ya + * x(n+N/4 ) = xb + j * yb + * x(n+N/2 ) = xc + j * yc + * x(n+3N 4) = xd + j * yd + * + * + * Output real and imaginary data: + * x(4r) = xa'+ j * ya' + * x(4r+1) = xb'+ j * yb' + * x(4r+2) = xc'+ j * yc' + * x(4r+3) = xd'+ j * yd' + * + * + * Twiddle factors for radix-4 IFFT: + * Wn = co1 + j * (si1) + * W2n = co2 + j * (si2) + * W3n = co3 + j * (si3) + + * The real and imaginary output values for the radix-4 butterfly are + * xa' = xa + xb + xc + xd + * ya' = ya + yb + yc + yd + * xb' = (xa-yb-xc+yd)* co1 - (ya+xb-yc-xd)* (si1) + * yb' = (ya+xb-yc-xd)* co1 + (xa-yb-xc+yd)* (si1) + * xc' = (xa-xb+xc-xd)* co2 - (ya-yb+yc-yd)* (si2) + * yc' = (ya-yb+yc-yd)* co2 + (xa-xb+xc-xd)* (si2) + * xd' = (xa+yb-xc-yd)* co3 - (ya-xb-yc+xd)* (si3) + * yd' = (ya-xb-yc+xd)* co3 + (xa+yb-xc-yd)* (si3) + * + */ + +void arm_radix4_butterfly_inverse_q15( + q15_t * pSrc16, + uint32_t fftLen, + const q15_t * pCoef16, + uint32_t twidCoefModifier) +{ + +#if defined (ARM_MATH_DSP) + + q31_t R, S, T, U; + q31_t C1, C2, C3, out1, out2; + uint32_t n1, n2, ic, i0, j, k; + + q15_t *ptr1; + q15_t *pSi0; + q15_t *pSi1; + q15_t *pSi2; + q15_t *pSi3; + + q31_t xaya, xbyb, xcyc, xdyd; + + /* Total process is divided into three stages */ + + /* process first stage, middle stages, & last stage */ + + /* Initializations for the first stage */ + n2 = fftLen; + n1 = n2; + + /* n2 = fftLen/4 */ + n2 >>= 2U; + + /* Index for twiddle coefficient */ + ic = 0U; + + /* Index for input read and output write */ + j = n2; + + pSi0 = pSrc16; + pSi1 = pSi0 + 2 * n2; + pSi2 = pSi1 + 2 * n2; + pSi3 = pSi2 + 2 * n2; + + /* Input is in 1.15(q15) format */ + + /* start of first stage process */ + do + { + /* Butterfly implementation */ + + /* Reading i0, i0+fftLen/2 inputs */ + /* Read ya (real), xa(imag) input */ + T = read_q15x2 (pSi0); + T = __SHADD16(T, 0); + T = __SHADD16(T, 0); + + /* Read yc (real), xc(imag) input */ + S = read_q15x2 (pSi2); + S = __SHADD16(S, 0); + S = __SHADD16(S, 0); + + /* R = packed((ya + yc), (xa + xc) ) */ + R = __QADD16(T, S); + + /* S = packed((ya - yc), (xa - xc) ) */ + S = __QSUB16(T, S); + + /* Reading i0+fftLen/4 , i0+3fftLen/4 inputs */ + /* Read yb (real), xb(imag) input */ + T = read_q15x2 (pSi1); + T = __SHADD16(T, 0); + T = __SHADD16(T, 0); + + /* Read yd (real), xd(imag) input */ + U = read_q15x2 (pSi3); + U = __SHADD16(U, 0); + U = __SHADD16(U, 0); + + /* T = packed((yb + yd), (xb + xd) ) */ + T = __QADD16(T, U); + + /* writing the butterfly processed i0 sample */ + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + write_q15x2_ia (&pSi0, __SHADD16(R, T)); + + /* R = packed((ya + yc) - (yb + yd), (xa + xc)- (xb + xd)) */ + R = __QSUB16(R, T); + + /* co2 & si2 are read from SIMD Coefficient pointer */ + C2 = read_q15x2 ((q15_t *) pCoef16 + (4U * ic)); + +#ifndef ARM_MATH_BIG_ENDIAN + /* xc' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) */ + out1 = __SMUSD(C2, R) >> 16U; + /* yc' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + out2 = __SMUADX(C2, R); +#else + /* xc' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + out1 = __SMUADX(C2, R) >> 16U; + /* yc' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) */ + out2 = __SMUSD(__QSUB16(0, C2), R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Reading i0+fftLen/4 */ + /* T = packed(yb, xb) */ + T = read_q15x2 (pSi1); + T = __SHADD16(T, 0); + T = __SHADD16(T, 0); + + /* writing the butterfly processed i0 + fftLen/4 sample */ + /* writing output(xc', yc') in little endian format */ + write_q15x2_ia (&pSi1, (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + /* Butterfly calculations */ + /* U = packed(yd, xd) */ + U = read_q15x2 (pSi3); + U = __SHADD16(U, 0); + U = __SHADD16(U, 0); + + /* T = packed(yb-yd, xb-xd) */ + T = __QSUB16(T, U); + +#ifndef ARM_MATH_BIG_ENDIAN + /* R = packed((ya-yc) + (xb- xd) , (xa-xc) - (yb-yd)) */ + R = __QSAX(S, T); + /* S = packed((ya-yc) + (xb- xd), (xa-xc) - (yb-yd)) */ + S = __QASX(S, T); +#else + /* R = packed((ya-yc) + (xb- xd) , (xa-xc) - (yb-yd)) */ + R = __QASX(S, T); + /* S = packed((ya-yc) - (xb- xd), (xa-xc) + (yb-yd)) */ + S = __QSAX(S, T); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* co1 & si1 are read from SIMD Coefficient pointer */ + C1 = read_q15x2 ((q15_t *) pCoef16 + (2U * ic)); + /* Butterfly process for the i0+fftLen/2 sample */ + +#ifndef ARM_MATH_BIG_ENDIAN + /* xb' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) */ + out1 = __SMUSD(C1, S) >> 16U; + /* yb' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) */ + out2 = __SMUADX(C1, S); +#else + /* xb' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) */ + out1 = __SMUADX(C1, S) >> 16U; + /* yb' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) */ + out2 = __SMUSD(__QSUB16(0, C1), S); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* writing output(xb', yb') in little endian format */ + write_q15x2_ia (&pSi2, ((out2) & 0xFFFF0000) | ((out1) & 0x0000FFFF)); + + /* co3 & si3 are read from SIMD Coefficient pointer */ + C3 = read_q15x2 ((q15_t *) pCoef16 + (6U * ic)); + /* Butterfly process for the i0+3fftLen/4 sample */ + +#ifndef ARM_MATH_BIG_ENDIAN + /* xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3) */ + out1 = __SMUSD(C3, R) >> 16U; + /* yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3) */ + out2 = __SMUADX(C3, R); +#else + /* xd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3) */ + out1 = __SMUADX(C3, R) >> 16U; + /* yd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3) */ + out2 = __SMUSD(__QSUB16(0, C3), R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* writing output(xd', yd') in little endian format */ + write_q15x2_ia (&pSi3, ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + + /* Twiddle coefficients index modifier */ + ic = ic + twidCoefModifier; + + } while (--j); + /* data is in 4.11(q11) format */ + + /* end of first stage process */ + + + /* start of middle stage process */ + + /* Twiddle coefficients index modifier */ + twidCoefModifier <<= 2U; + + /* Calculation of Middle stage */ + for (k = fftLen / 4U; k > 4U; k >>= 2U) + { + /* Initializations for the middle stage */ + n1 = n2; + n2 >>= 2U; + ic = 0U; + + for (j = 0U; j <= (n2 - 1U); j++) + { + /* index calculation for the coefficients */ + C1 = read_q15x2 ((q15_t *) pCoef16 + (2U * ic)); + C2 = read_q15x2 ((q15_t *) pCoef16 + (4U * ic)); + C3 = read_q15x2 ((q15_t *) pCoef16 + (6U * ic)); + + /* Twiddle coefficients index modifier */ + ic = ic + twidCoefModifier; + + pSi0 = pSrc16 + 2 * j; + pSi1 = pSi0 + 2 * n2; + pSi2 = pSi1 + 2 * n2; + pSi3 = pSi2 + 2 * n2; + + /* Butterfly implementation */ + for (i0 = j; i0 < fftLen; i0 += n1) + { + /* Reading i0, i0+fftLen/2 inputs */ + /* Read ya (real), xa(imag) input */ + T = read_q15x2 (pSi0); + + /* Read yc (real), xc(imag) input */ + S = read_q15x2 (pSi2); + + /* R = packed( (ya + yc), (xa + xc)) */ + R = __QADD16(T, S); + + /* S = packed((ya - yc), (xa - xc)) */ + S = __QSUB16(T, S); + + /* Reading i0+fftLen/4 , i0+3fftLen/4 inputs */ + /* Read yb (real), xb(imag) input */ + T = read_q15x2 (pSi1); + + /* Read yd (real), xd(imag) input */ + U = read_q15x2 (pSi3); + + /* T = packed( (yb + yd), (xb + xd)) */ + T = __QADD16(T, U); + + /* writing the butterfly processed i0 sample */ + + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + out1 = __SHADD16(R, T); + out1 = __SHADD16(out1, 0); + write_q15x2 (pSi0, out1); + pSi0 += 2 * n1; + + /* R = packed( (ya + yc) - (yb + yd), (xa + xc) - (xb + xd)) */ + R = __SHSUB16(R, T); + +#ifndef ARM_MATH_BIG_ENDIAN + /* (ya-yb+yc-yd)* (si2) + (xa-xb+xc-xd)* co2 */ + out1 = __SMUSD(C2, R) >> 16U; + + /* (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + out2 = __SMUADX(C2, R); +#else + /* (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + out1 = __SMUADX(R, C2) >> 16U; + + /* (ya-yb+yc-yd)* (si2) + (xa-xb+xc-xd)* co2 */ + out2 = __SMUSD(__QSUB16(0, C2), R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Reading i0+3fftLen/4 */ + /* Read yb (real), xb(imag) input */ + T = read_q15x2 (pSi1); + + /* writing the butterfly processed i0 + fftLen/4 sample */ + /* xc' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) */ + /* yc' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) */ + write_q15x2 (pSi1, ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + pSi1 += 2 * n1; + + /* Butterfly calculations */ + + /* Read yd (real), xd(imag) input */ + U = read_q15x2 (pSi3); + + /* T = packed(yb-yd, xb-xd) */ + T = __QSUB16(T, U); + +#ifndef ARM_MATH_BIG_ENDIAN + /* R = packed((ya-yc) + (xb- xd) , (xa-xc) - (yb-yd)) */ + R = __SHSAX(S, T); + + /* S = packed((ya-yc) - (xb- xd), (xa-xc) + (yb-yd)) */ + S = __SHASX(S, T); + + /* Butterfly process for the i0+fftLen/2 sample */ + out1 = __SMUSD(C1, S) >> 16U; + out2 = __SMUADX(C1, S); +#else + /* R = packed((ya-yc) + (xb- xd) , (xa-xc) - (yb-yd)) */ + R = __SHASX(S, T); + + /* S = packed((ya-yc) - (xb- xd), (xa-xc) + (yb-yd)) */ + S = __SHSAX(S, T); + + /* Butterfly process for the i0+fftLen/2 sample */ + out1 = __SMUADX(S, C1) >> 16U; + out2 = __SMUSD(__QSUB16(0, C1), S); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* xb' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) */ + /* yb' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) */ + write_q15x2 (pSi2, ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + pSi2 += 2 * n1; + + /* Butterfly process for the i0+3fftLen/4 sample */ + +#ifndef ARM_MATH_BIG_ENDIAN + out1 = __SMUSD(C3, R) >> 16U; + out2 = __SMUADX(C3, R); +#else + out1 = __SMUADX(C3, R) >> 16U; + out2 = __SMUSD(__QSUB16(0, C3), R); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3) */ + /* yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3) */ + write_q15x2 (pSi3, ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF)); + pSi3 += 2 * n1; + } + } + /* Twiddle coefficients index modifier */ + twidCoefModifier <<= 2U; + } + /* end of middle stage process */ + + /* data is in 10.6(q6) format for the 1024 point */ + /* data is in 8.8(q8) format for the 256 point */ + /* data is in 6.10(q10) format for the 64 point */ + /* data is in 4.12(q12) format for the 16 point */ + + /* Initializations for the last stage */ + j = fftLen >> 2; + + ptr1 = &pSrc16[0]; + + /* start of last stage process */ + + /* Butterfly implementation */ + do + { + /* Read xa (real), ya(imag) input */ + xaya = read_q15x2_ia ((q15_t **) &ptr1); + + /* Read xb (real), yb(imag) input */ + xbyb = read_q15x2_ia ((q15_t **) &ptr1); + + /* Read xc (real), yc(imag) input */ + xcyc = read_q15x2_ia ((q15_t **) &ptr1); + + /* Read xd (real), yd(imag) input */ + xdyd = read_q15x2_ia ((q15_t **) &ptr1); + + /* R = packed((ya + yc), (xa + xc)) */ + R = __QADD16(xaya, xcyc); + + /* T = packed((yb + yd), (xb + xd)) */ + T = __QADD16(xbyb, xdyd); + + /* pointer updation for writing */ + ptr1 = ptr1 - 8U; + + + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + write_q15x2_ia (&ptr1, __SHADD16(R, T)); + + /* T = packed((yb + yd), (xb + xd)) */ + T = __QADD16(xbyb, xdyd); + + /* xc' = (xa-xb+xc-xd) */ + /* yc' = (ya-yb+yc-yd) */ + write_q15x2_ia (&ptr1, __SHSUB16(R, T)); + + /* S = packed((ya - yc), (xa - xc)) */ + S = __QSUB16(xaya, xcyc); + + /* Read yd (real), xd(imag) input */ + /* T = packed( (yb - yd), (xb - xd)) */ + U = __QSUB16(xbyb, xdyd); + +#ifndef ARM_MATH_BIG_ENDIAN + /* xb' = (xa+yb-xc-yd) */ + /* yb' = (ya-xb-yc+xd) */ + write_q15x2_ia (&ptr1, __SHASX(S, U)); + + /* xd' = (xa-yb-xc+yd) */ + /* yd' = (ya+xb-yc-xd) */ + write_q15x2_ia (&ptr1, __SHSAX(S, U)); +#else + /* xb' = (xa+yb-xc-yd) */ + /* yb' = (ya-xb-yc+xd) */ + write_q15x2_ia (&ptr1, __SHSAX(S, U)); + + /* xd' = (xa-yb-xc+yd) */ + /* yd' = (ya+xb-yc-xd) */ + write_q15x2_ia (&ptr1, __SHASX(S, U)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + } while (--j); + + /* end of last stage process */ + + /* output is in 11.5(q5) format for the 1024 point */ + /* output is in 9.7(q7) format for the 256 point */ + /* output is in 7.9(q9) format for the 64 point */ + /* output is in 5.11(q11) format for the 16 point */ + + +#else /* arm_radix4_butterfly_inverse_q15 */ + + q15_t R0, R1, S0, S1, T0, T1, U0, U1; + q15_t Co1, Si1, Co2, Si2, Co3, Si3, out1, out2; + uint32_t n1, n2, ic, i0, i1, i2, i3, j, k; + + /* Total process is divided into three stages */ + + /* process first stage, middle stages, & last stage */ + + /* Initializations for the first stage */ + n2 = fftLen; + n1 = n2; + + /* n2 = fftLen/4 */ + n2 >>= 2U; + + /* Index for twiddle coefficient */ + ic = 0U; + + /* Index for input read and output write */ + i0 = 0U; + + j = n2; + + /* Input is in 1.15(q15) format */ + + /* Start of first stage process */ + do + { + /* Butterfly implementation */ + + /* index calculation for the input as, */ + /* pSrc16[i0 + 0], pSrc16[i0 + fftLen/4], pSrc16[i0 + fftLen/2], pSrc16[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Reading i0, i0+fftLen/2 inputs */ + /* input is down scale by 4 to avoid overflow */ + /* Read ya (real), xa(imag) input */ + T0 = pSrc16[i0 * 2U] >> 2U; + T1 = pSrc16[(i0 * 2U) + 1U] >> 2U; + /* input is down scale by 4 to avoid overflow */ + /* Read yc (real), xc(imag) input */ + S0 = pSrc16[i2 * 2U] >> 2U; + S1 = pSrc16[(i2 * 2U) + 1U] >> 2U; + + /* R0 = (ya + yc), R1 = (xa + xc) */ + R0 = __SSAT(T0 + S0, 16U); + R1 = __SSAT(T1 + S1, 16U); + /* S0 = (ya - yc), S1 = (xa - xc) */ + S0 = __SSAT(T0 - S0, 16U); + S1 = __SSAT(T1 - S1, 16U); + + /* Reading i0+fftLen/4 , i0+3fftLen/4 inputs */ + /* input is down scale by 4 to avoid overflow */ + /* Read yb (real), xb(imag) input */ + T0 = pSrc16[i1 * 2U] >> 2U; + T1 = pSrc16[(i1 * 2U) + 1U] >> 2U; + /* Read yd (real), xd(imag) input */ + /* input is down scale by 4 to avoid overflow */ + U0 = pSrc16[i3 * 2U] >> 2U; + U1 = pSrc16[(i3 * 2U) + 1U] >> 2U; + + /* T0 = (yb + yd), T1 = (xb + xd) */ + T0 = __SSAT(T0 + U0, 16U); + T1 = __SSAT(T1 + U1, 16U); + + /* writing the butterfly processed i0 sample */ + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + pSrc16[i0 * 2U] = (R0 >> 1U) + (T0 >> 1U); + pSrc16[(i0 * 2U) + 1U] = (R1 >> 1U) + (T1 >> 1U); + + /* R0 = (ya + yc) - (yb + yd), R1 = (xa + xc)- (xb + xd) */ + R0 = __SSAT(R0 - T0, 16U); + R1 = __SSAT(R1 - T1, 16U); + /* co2 & si2 are read from Coefficient pointer */ + Co2 = pCoef16[2U * ic * 2U]; + Si2 = pCoef16[(2U * ic * 2U) + 1U]; + /* xc' = (xa-xb+xc-xd)* co2 - (ya-yb+yc-yd)* (si2) */ + out1 = (q15_t) ((Co2 * R0 - Si2 * R1) >> 16U); + /* yc' = (ya-yb+yc-yd)* co2 + (xa-xb+xc-xd)* (si2) */ + out2 = (q15_t) ((Si2 * R0 + Co2 * R1) >> 16U); + + /* Reading i0+fftLen/4 */ + /* input is down scale by 4 to avoid overflow */ + /* T0 = yb, T1 = xb */ + T0 = pSrc16[i1 * 2U] >> 2U; + T1 = pSrc16[(i1 * 2U) + 1U] >> 2U; + + /* writing the butterfly processed i0 + fftLen/4 sample */ + /* writing output(xc', yc') in little endian format */ + pSrc16[i1 * 2U] = out1; + pSrc16[(i1 * 2U) + 1U] = out2; + + /* Butterfly calculations */ + /* input is down scale by 4 to avoid overflow */ + /* U0 = yd, U1 = xd) */ + U0 = pSrc16[i3 * 2U] >> 2U; + U1 = pSrc16[(i3 * 2U) + 1U] >> 2U; + + /* T0 = yb-yd, T1 = xb-xd) */ + T0 = __SSAT(T0 - U0, 16U); + T1 = __SSAT(T1 - U1, 16U); + /* R0 = (ya-yc) - (xb- xd) , R1 = (xa-xc) + (yb-yd) */ + R0 = (q15_t) __SSAT((q31_t) (S0 + T1), 16); + R1 = (q15_t) __SSAT((q31_t) (S1 - T0), 16); + /* S = (ya-yc) + (xb- xd), S1 = (xa-xc) - (yb-yd) */ + S0 = (q15_t) __SSAT((q31_t) (S0 - T1), 16); + S1 = (q15_t) __SSAT((q31_t) (S1 + T0), 16); + + /* co1 & si1 are read from Coefficient pointer */ + Co1 = pCoef16[ic * 2U]; + Si1 = pCoef16[(ic * 2U) + 1U]; + /* Butterfly process for the i0+fftLen/2 sample */ + /* xb' = (xa-yb-xc+yd)* co1 - (ya+xb-yc-xd)* (si1) */ + out1 = (q15_t) ((Co1 * S0 - Si1 * S1) >> 16U); + /* yb' = (ya+xb-yc-xd)* co1 + (xa-yb-xc+yd)* (si1) */ + out2 = (q15_t) ((Si1 * S0 + Co1 * S1) >> 16U); + /* writing output(xb', yb') in little endian format */ + pSrc16[i2 * 2U] = out1; + pSrc16[(i2 * 2U) + 1U] = out2; + + /* Co3 & si3 are read from Coefficient pointer */ + Co3 = pCoef16[3U * ic * 2U]; + Si3 = pCoef16[(3U * ic * 2U) + 1U]; + /* Butterfly process for the i0+3fftLen/4 sample */ + /* xd' = (xa+yb-xc-yd)* Co3 - (ya-xb-yc+xd)* (si3) */ + out1 = (q15_t) ((Co3 * R0 - Si3 * R1) >> 16U); + /* yd' = (ya-xb-yc+xd)* Co3 + (xa+yb-xc-yd)* (si3) */ + out2 = (q15_t) ((Si3 * R0 + Co3 * R1) >> 16U); + /* writing output(xd', yd') in little endian format */ + pSrc16[i3 * 2U] = out1; + pSrc16[(i3 * 2U) + 1U] = out2; + + /* Twiddle coefficients index modifier */ + ic = ic + twidCoefModifier; + + /* Updating input index */ + i0 = i0 + 1U; + + } while (--j); + + /* End of first stage process */ + + /* data is in 4.11(q11) format */ + + + /* Start of Middle stage process */ + + /* Twiddle coefficients index modifier */ + twidCoefModifier <<= 2U; + + /* Calculation of Middle stage */ + for (k = fftLen / 4U; k > 4U; k >>= 2U) + { + /* Initializations for the middle stage */ + n1 = n2; + n2 >>= 2U; + ic = 0U; + + for (j = 0U; j <= (n2 - 1U); j++) + { + /* index calculation for the coefficients */ + Co1 = pCoef16[ic * 2U]; + Si1 = pCoef16[(ic * 2U) + 1U]; + Co2 = pCoef16[2U * ic * 2U]; + Si2 = pCoef16[2U * ic * 2U + 1U]; + Co3 = pCoef16[3U * ic * 2U]; + Si3 = pCoef16[(3U * ic * 2U) + 1U]; + + /* Twiddle coefficients index modifier */ + ic = ic + twidCoefModifier; + + /* Butterfly implementation */ + for (i0 = j; i0 < fftLen; i0 += n1) + { + /* index calculation for the input as, */ + /* pSrc16[i0 + 0], pSrc16[i0 + fftLen/4], pSrc16[i0 + fftLen/2], pSrc16[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Reading i0, i0+fftLen/2 inputs */ + /* Read ya (real), xa(imag) input */ + T0 = pSrc16[i0 * 2U]; + T1 = pSrc16[(i0 * 2U) + 1U]; + + /* Read yc (real), xc(imag) input */ + S0 = pSrc16[i2 * 2U]; + S1 = pSrc16[(i2 * 2U) + 1U]; + + + /* R0 = (ya + yc), R1 = (xa + xc) */ + R0 = __SSAT(T0 + S0, 16U); + R1 = __SSAT(T1 + S1, 16U); + /* S0 = (ya - yc), S1 = (xa - xc) */ + S0 = __SSAT(T0 - S0, 16U); + S1 = __SSAT(T1 - S1, 16U); + + /* Reading i0+fftLen/4 , i0+3fftLen/4 inputs */ + /* Read yb (real), xb(imag) input */ + T0 = pSrc16[i1 * 2U]; + T1 = pSrc16[(i1 * 2U) + 1U]; + + /* Read yd (real), xd(imag) input */ + U0 = pSrc16[i3 * 2U]; + U1 = pSrc16[(i3 * 2U) + 1U]; + + /* T0 = (yb + yd), T1 = (xb + xd) */ + T0 = __SSAT(T0 + U0, 16U); + T1 = __SSAT(T1 + U1, 16U); + + /* writing the butterfly processed i0 sample */ + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + pSrc16[i0 * 2U] = ((R0 >> 1U) + (T0 >> 1U)) >> 1U; + pSrc16[(i0 * 2U) + 1U] = ((R1 >> 1U) + (T1 >> 1U)) >> 1U; + + /* R0 = (ya + yc) - (yb + yd), R1 = (xa + xc) - (xb + xd) */ + R0 = (R0 >> 1U) - (T0 >> 1U); + R1 = (R1 >> 1U) - (T1 >> 1U); + + /* (ya-yb+yc-yd)* (si2) - (xa-xb+xc-xd)* co2 */ + out1 = (q15_t) ((Co2 * R0 - Si2 * R1) >> 16); + /* (ya-yb+yc-yd)* co2 + (xa-xb+xc-xd)* (si2) */ + out2 = (q15_t) ((Si2 * R0 + Co2 * R1) >> 16); + + /* Reading i0+3fftLen/4 */ + /* Read yb (real), xb(imag) input */ + T0 = pSrc16[i1 * 2U]; + T1 = pSrc16[(i1 * 2U) + 1U]; + + /* writing the butterfly processed i0 + fftLen/4 sample */ + /* xc' = (xa-xb+xc-xd)* co2 - (ya-yb+yc-yd)* (si2) */ + /* yc' = (ya-yb+yc-yd)* co2 + (xa-xb+xc-xd)* (si2) */ + pSrc16[i1 * 2U] = out1; + pSrc16[(i1 * 2U) + 1U] = out2; + + /* Butterfly calculations */ + /* Read yd (real), xd(imag) input */ + U0 = pSrc16[i3 * 2U]; + U1 = pSrc16[(i3 * 2U) + 1U]; + + /* T0 = yb-yd, T1 = xb-xd) */ + T0 = __SSAT(T0 - U0, 16U); + T1 = __SSAT(T1 - U1, 16U); + + /* R0 = (ya-yc) - (xb- xd) , R1 = (xa-xc) + (yb-yd) */ + R0 = (S0 >> 1U) + (T1 >> 1U); + R1 = (S1 >> 1U) - (T0 >> 1U); + + /* S1 = (ya-yc) + (xb- xd), S1 = (xa-xc) - (yb-yd) */ + S0 = (S0 >> 1U) - (T1 >> 1U); + S1 = (S1 >> 1U) + (T0 >> 1U); + + /* Butterfly process for the i0+fftLen/2 sample */ + out1 = (q15_t) ((Co1 * S0 - Si1 * S1) >> 16U); + out2 = (q15_t) ((Si1 * S0 + Co1 * S1) >> 16U); + /* xb' = (xa-yb-xc+yd)* co1 - (ya+xb-yc-xd)* (si1) */ + /* yb' = (ya+xb-yc-xd)* co1 + (xa-yb-xc+yd)* (si1) */ + pSrc16[i2 * 2U] = out1; + pSrc16[(i2 * 2U) + 1U] = out2; + + /* Butterfly process for the i0+3fftLen/4 sample */ + out1 = (q15_t) ((Co3 * R0 - Si3 * R1) >> 16U); + + out2 = (q15_t) ((Si3 * R0 + Co3 * R1) >> 16U); + /* xd' = (xa+yb-xc-yd)* Co3 - (ya-xb-yc+xd)* (si3) */ + /* yd' = (ya-xb-yc+xd)* Co3 + (xa+yb-xc-yd)* (si3) */ + pSrc16[i3 * 2U] = out1; + pSrc16[(i3 * 2U) + 1U] = out2; + + + } + } + /* Twiddle coefficients index modifier */ + twidCoefModifier <<= 2U; + } + /* End of Middle stages process */ + + + /* data is in 10.6(q6) format for the 1024 point */ + /* data is in 8.8(q8) format for the 256 point */ + /* data is in 6.10(q10) format for the 64 point */ + /* data is in 4.12(q12) format for the 16 point */ + + /* start of last stage process */ + + + /* Initializations for the last stage */ + n1 = n2; + n2 >>= 2U; + + /* Butterfly implementation */ + for (i0 = 0U; i0 <= (fftLen - n1); i0 += n1) + { + /* index calculation for the input as, */ + /* pSrc16[i0 + 0], pSrc16[i0 + fftLen/4], pSrc16[i0 + fftLen/2], pSrc16[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Reading i0, i0+fftLen/2 inputs */ + /* Read ya (real), xa(imag) input */ + T0 = pSrc16[i0 * 2U]; + T1 = pSrc16[(i0 * 2U) + 1U]; + /* Read yc (real), xc(imag) input */ + S0 = pSrc16[i2 * 2U]; + S1 = pSrc16[(i2 * 2U) + 1U]; + + /* R0 = (ya + yc), R1 = (xa + xc) */ + R0 = __SSAT(T0 + S0, 16U); + R1 = __SSAT(T1 + S1, 16U); + /* S0 = (ya - yc), S1 = (xa - xc) */ + S0 = __SSAT(T0 - S0, 16U); + S1 = __SSAT(T1 - S1, 16U); + + /* Reading i0+fftLen/4 , i0+3fftLen/4 inputs */ + /* Read yb (real), xb(imag) input */ + T0 = pSrc16[i1 * 2U]; + T1 = pSrc16[(i1 * 2U) + 1U]; + /* Read yd (real), xd(imag) input */ + U0 = pSrc16[i3 * 2U]; + U1 = pSrc16[(i3 * 2U) + 1U]; + + /* T0 = (yb + yd), T1 = (xb + xd) */ + T0 = __SSAT(T0 + U0, 16U); + T1 = __SSAT(T1 + U1, 16U); + + /* writing the butterfly processed i0 sample */ + /* xa' = xa + xb + xc + xd */ + /* ya' = ya + yb + yc + yd */ + pSrc16[i0 * 2U] = (R0 >> 1U) + (T0 >> 1U); + pSrc16[(i0 * 2U) + 1U] = (R1 >> 1U) + (T1 >> 1U); + + /* R0 = (ya + yc) - (yb + yd), R1 = (xa + xc) - (xb + xd) */ + R0 = (R0 >> 1U) - (T0 >> 1U); + R1 = (R1 >> 1U) - (T1 >> 1U); + + /* Read yb (real), xb(imag) input */ + T0 = pSrc16[i1 * 2U]; + T1 = pSrc16[(i1 * 2U) + 1U]; + + /* writing the butterfly processed i0 + fftLen/4 sample */ + /* xc' = (xa-xb+xc-xd) */ + /* yc' = (ya-yb+yc-yd) */ + pSrc16[i1 * 2U] = R0; + pSrc16[(i1 * 2U) + 1U] = R1; + + /* Read yd (real), xd(imag) input */ + U0 = pSrc16[i3 * 2U]; + U1 = pSrc16[(i3 * 2U) + 1U]; + /* T0 = (yb - yd), T1 = (xb - xd) */ + T0 = __SSAT(T0 - U0, 16U); + T1 = __SSAT(T1 - U1, 16U); + + /* writing the butterfly processed i0 + fftLen/2 sample */ + /* xb' = (xa-yb-xc+yd) */ + /* yb' = (ya+xb-yc-xd) */ + pSrc16[i2 * 2U] = (S0 >> 1U) - (T1 >> 1U); + pSrc16[(i2 * 2U) + 1U] = (S1 >> 1U) + (T0 >> 1U); + + + /* writing the butterfly processed i0 + 3fftLen/4 sample */ + /* xd' = (xa+yb-xc-yd) */ + /* yd' = (ya-xb-yc+xd) */ + pSrc16[i3 * 2U] = (S0 >> 1U) + (T1 >> 1U); + pSrc16[(i3 * 2U) + 1U] = (S1 >> 1U) - (T0 >> 1U); + } + /* end of last stage process */ + + /* output is in 11.5(q5) format for the 1024 point */ + /* output is in 9.7(q7) format for the 256 point */ + /* output is in 7.9(q9) format for the 64 point */ + /* output is in 5.11(q11) format for the 16 point */ + +#endif /* #if defined (ARM_MATH_DSP) */ + +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_q31.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_q31.c new file mode 100644 index 0000000..a9a59dd --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix4_q31.c @@ -0,0 +1,827 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix4_q31.c + * Description: This file has function definition of Radix-4 FFT & IFFT function and + * In-place bit reversal using bit reversal table + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +void arm_radix4_butterfly_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef, + uint32_t twidCoefModifier); + +void arm_radix4_butterfly_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef, + uint32_t twidCoefModifier); + +void arm_bitreversal_q31( + q31_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + const uint16_t * pBitRevTab); + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup ComplexFFT + @{ + */ + +/** + @brief Processing function for the Q31 CFFT/CIFFT. + @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed in the future. + @param[in] S points to an instance of the Q31 CFFT/CIFFT structure + @param[in,out] pSrc points to the complex data buffer of size 2*fftLen. Processing occurs in-place + @return none + + @par Input and output formats: + Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process. + Hence the output format is different for different FFT sizes. + The input and output formats for different FFT sizes and number of bits to upscale are mentioned in the tables below for CFFT and CIFFT: + @par + \image html CFFTQ31.gif "Input and Output Formats for Q31 CFFT" + \image html CIFFTQ31.gif "Input and Output Formats for Q31 CIFFT" + */ + +void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc) +{ + if (S->ifftFlag == 1U) + { + /* Complex IFFT radix-4 */ + arm_radix4_butterfly_inverse_q31(pSrc, S->fftLen, S->pTwiddle, S->twidCoefModifier); + } + else + { + /* Complex FFT radix-4 */ + arm_radix4_butterfly_q31(pSrc, S->fftLen, S->pTwiddle, S->twidCoefModifier); + } + + if (S->bitReverseFlag == 1U) + { + /* Bit Reversal */ + arm_bitreversal_q31(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable); + } + +} + +/** + @} end of ComplexFFT group + */ + +/* + * Radix-4 FFT algorithm used is : + * + * Input real and imaginary data: + * x(n) = xa + j * ya + * x(n+N/4 ) = xb + j * yb + * x(n+N/2 ) = xc + j * yc + * x(n+3N 4) = xd + j * yd + * + * + * Output real and imaginary data: + * x(4r) = xa'+ j * ya' + * x(4r+1) = xb'+ j * yb' + * x(4r+2) = xc'+ j * yc' + * x(4r+3) = xd'+ j * yd' + * + * + * Twiddle factors for radix-4 FFT: + * Wn = co1 + j * (- si1) + * W2n = co2 + j * (- si2) + * W3n = co3 + j * (- si3) + * + * Butterfly implementation: + * xa' = xa + xb + xc + xd + * ya' = ya + yb + yc + yd + * xb' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1) + * yb' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1) + * xc' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2) + * yc' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2) + * xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3) + * yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3) + * + */ + +/** + @brief Core function for the Q31 CFFT butterfly process. + @param[in,out] pSrc points to the in-place buffer of Q31 data type. + @param[in] fftLen length of the FFT. + @param[in] pCoef points to twiddle coefficient buffer. + @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + @return none + */ + +void arm_radix4_butterfly_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef, + uint32_t twidCoefModifier) +{ + uint32_t n1, n2, ia1, ia2, ia3, i0, i1, i2, i3, j, k; + q31_t t1, t2, r1, r2, s1, s2, co1, co2, co3, si1, si2, si3; + + q31_t xa, xb, xc, xd; + q31_t ya, yb, yc, yd; + q31_t xa_out, xb_out, xc_out, xd_out; + q31_t ya_out, yb_out, yc_out, yd_out; + + q31_t *ptr1; + + /* Total process is divided into three stages */ + + /* process first stage, middle stages, & last stage */ + + + /* start of first stage process */ + + /* Initializations for the first stage */ + n2 = fftLen; + n1 = n2; + /* n2 = fftLen/4 */ + n2 >>= 2U; + i0 = 0U; + ia1 = 0U; + + j = n2; + + /* Calculation of first stage */ + do + { + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2U], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* input is in 1.31(q31) format and provide 4 guard bits for the input */ + + /* Butterfly implementation */ + /* xa + xc */ + r1 = (pSrc[(2U * i0)] >> 4U) + (pSrc[(2U * i2)] >> 4U); + /* xa - xc */ + r2 = (pSrc[(2U * i0)] >> 4U) - (pSrc[(2U * i2)] >> 4U); + + /* xb + xd */ + t1 = (pSrc[(2U * i1)] >> 4U) + (pSrc[(2U * i3)] >> 4U); + + /* ya + yc */ + s1 = (pSrc[(2U * i0) + 1U] >> 4U) + (pSrc[(2U * i2) + 1U] >> 4U); + /* ya - yc */ + s2 = (pSrc[(2U * i0) + 1U] >> 4U) - (pSrc[(2U * i2) + 1U] >> 4U); + + /* xa' = xa + xb + xc + xd */ + pSrc[2U * i0] = (r1 + t1); + /* (xa + xc) - (xb + xd) */ + r1 = r1 - t1; + /* yb + yd */ + t2 = (pSrc[(2U * i1) + 1U] >> 4U) + (pSrc[(2U * i3) + 1U] >> 4U); + + /* ya' = ya + yb + yc + yd */ + pSrc[(2U * i0) + 1U] = (s1 + t2); + + /* (ya + yc) - (yb + yd) */ + s1 = s1 - t2; + + /* yb - yd */ + t1 = (pSrc[(2U * i1) + 1U] >> 4U) - (pSrc[(2U * i3) + 1U] >> 4U); + /* xb - xd */ + t2 = (pSrc[(2U * i1)] >> 4U) - (pSrc[(2U * i3)] >> 4U); + + /* index calculation for the coefficients */ + ia2 = 2U * ia1; + co2 = pCoef[(ia2 * 2U)]; + si2 = pCoef[(ia2 * 2U) + 1U]; + + /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = (((int32_t) (((q63_t) r1 * co2) >> 32)) + + ((int32_t) (((q63_t) s1 * si2) >> 32))) << 1U; + + /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */ + pSrc[(2U * i1) + 1U] = (((int32_t) (((q63_t) s1 * co2) >> 32)) - + ((int32_t) (((q63_t) r1 * si2) >> 32))) << 1U; + + /* (xa - xc) + (yb - yd) */ + r1 = r2 + t1; + /* (xa - xc) - (yb - yd) */ + r2 = r2 - t1; + + /* (ya - yc) - (xb - xd) */ + s1 = s2 - t2; + /* (ya - yc) + (xb - xd) */ + s2 = s2 + t2; + + co1 = pCoef[(ia1 * 2U)]; + si1 = pCoef[(ia1 * 2U) + 1U]; + + /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = (((int32_t) (((q63_t) r1 * co1) >> 32)) + + ((int32_t) (((q63_t) s1 * si1) >> 32))) << 1U; + + /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = (((int32_t) (((q63_t) s1 * co1) >> 32)) - + ((int32_t) (((q63_t) r1 * si1) >> 32))) << 1U; + + /* index calculation for the coefficients */ + ia3 = 3U * ia1; + co3 = pCoef[(ia3 * 2U)]; + si3 = pCoef[(ia3 * 2U) + 1U]; + + /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */ + pSrc[2U * i3] = (((int32_t) (((q63_t) r2 * co3) >> 32)) + + ((int32_t) (((q63_t) s2 * si3) >> 32))) << 1U; + + /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = (((int32_t) (((q63_t) s2 * co3) >> 32)) - + ((int32_t) (((q63_t) r2 * si3) >> 32))) << 1U; + + /* Twiddle coefficients index modifier */ + ia1 = ia1 + twidCoefModifier; + + /* Updating input index */ + i0 = i0 + 1U; + + } while (--j); + + /* end of first stage process */ + + /* data is in 5.27(q27) format */ + + + /* start of Middle stages process */ + + + /* each stage in middle stages provides two down scaling of the input */ + + twidCoefModifier <<= 2U; + + + for (k = fftLen / 4U; k > 4U; k >>= 2U) + { + /* Initializations for the first stage */ + n1 = n2; + n2 >>= 2U; + ia1 = 0U; + + /* Calculation of first stage */ + for (j = 0U; j <= (n2 - 1U); j++) + { + /* index calculation for the coefficients */ + ia2 = ia1 + ia1; + ia3 = ia2 + ia1; + co1 = pCoef[(ia1 * 2U)]; + si1 = pCoef[(ia1 * 2U) + 1U]; + co2 = pCoef[(ia2 * 2U)]; + si2 = pCoef[(ia2 * 2U) + 1U]; + co3 = pCoef[(ia3 * 2U)]; + si3 = pCoef[(ia3 * 2U) + 1U]; + /* Twiddle coefficients index modifier */ + ia1 = ia1 + twidCoefModifier; + + for (i0 = j; i0 < fftLen; i0 += n1) + { + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2U], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Butterfly implementation */ + /* xa + xc */ + r1 = pSrc[2U * i0] + pSrc[2U * i2]; + /* xa - xc */ + r2 = pSrc[2U * i0] - pSrc[2U * i2]; + + /* ya + yc */ + s1 = pSrc[(2U * i0) + 1U] + pSrc[(2U * i2) + 1U]; + /* ya - yc */ + s2 = pSrc[(2U * i0) + 1U] - pSrc[(2U * i2) + 1U]; + + /* xb + xd */ + t1 = pSrc[2U * i1] + pSrc[2U * i3]; + + /* xa' = xa + xb + xc + xd */ + pSrc[2U * i0] = (r1 + t1) >> 2U; + /* xa + xc -(xb + xd) */ + r1 = r1 - t1; + + /* yb + yd */ + t2 = pSrc[(2U * i1) + 1U] + pSrc[(2U * i3) + 1U]; + /* ya' = ya + yb + yc + yd */ + pSrc[(2U * i0) + 1U] = (s1 + t2) >> 2U; + + /* (ya + yc) - (yb + yd) */ + s1 = s1 - t2; + + /* (yb - yd) */ + t1 = pSrc[(2U * i1) + 1U] - pSrc[(2U * i3) + 1U]; + /* (xb - xd) */ + t2 = pSrc[2U * i1] - pSrc[2U * i3]; + + /* xc' = (xa-xb+xc-xd)co2 + (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = (((int32_t) (((q63_t) r1 * co2) >> 32)) + + ((int32_t) (((q63_t) s1 * si2) >> 32))) >> 1U; + + /* yc' = (ya-yb+yc-yd)co2 - (xa-xb+xc-xd)(si2) */ + pSrc[(2U * i1) + 1U] = (((int32_t) (((q63_t) s1 * co2) >> 32)) - + ((int32_t) (((q63_t) r1 * si2) >> 32))) >> 1U; + + /* (xa - xc) + (yb - yd) */ + r1 = r2 + t1; + /* (xa - xc) - (yb - yd) */ + r2 = r2 - t1; + + /* (ya - yc) - (xb - xd) */ + s1 = s2 - t2; + /* (ya - yc) + (xb - xd) */ + s2 = s2 + t2; + + /* xb' = (xa+yb-xc-yd)co1 + (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = (((int32_t) (((q63_t) r1 * co1) >> 32)) + + ((int32_t) (((q63_t) s1 * si1) >> 32))) >> 1U; + + /* yb' = (ya-xb-yc+xd)co1 - (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = (((int32_t) (((q63_t) s1 * co1) >> 32)) - + ((int32_t) (((q63_t) r1 * si1) >> 32))) >> 1U; + + /* xd' = (xa-yb-xc+yd)co3 + (ya+xb-yc-xd)(si3) */ + pSrc[2U * i3] = (((int32_t) (((q63_t) r2 * co3) >> 32)) + + ((int32_t) (((q63_t) s2 * si3) >> 32))) >> 1U; + + /* yd' = (ya+xb-yc-xd)co3 - (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = (((int32_t) (((q63_t) s2 * co3) >> 32)) - + ((int32_t) (((q63_t) r2 * si3) >> 32))) >> 1U; + } + } + twidCoefModifier <<= 2U; + } + + /* End of Middle stages process */ + + /* data is in 11.21(q21) format for the 1024 point as there are 3 middle stages */ + /* data is in 9.23(q23) format for the 256 point as there are 2 middle stages */ + /* data is in 7.25(q25) format for the 64 point as there are 1 middle stage */ + /* data is in 5.27(q27) format for the 16 point as there are no middle stages */ + + + /* start of Last stage process */ + /* Initializations for the last stage */ + j = fftLen >> 2; + ptr1 = &pSrc[0]; + + /* Calculations of last stage */ + do + { + /* Read xa (real), ya(imag) input */ + xa = *ptr1++; + ya = *ptr1++; + + /* Read xb (real), yb(imag) input */ + xb = *ptr1++; + yb = *ptr1++; + + /* Read xc (real), yc(imag) input */ + xc = *ptr1++; + yc = *ptr1++; + + /* Read xc (real), yc(imag) input */ + xd = *ptr1++; + yd = *ptr1++; + + /* xa' = xa + xb + xc + xd */ + xa_out = xa + xb + xc + xd; + + /* ya' = ya + yb + yc + yd */ + ya_out = ya + yb + yc + yd; + + /* pointer updation for writing */ + ptr1 = ptr1 - 8U; + + /* writing xa' and ya' */ + *ptr1++ = xa_out; + *ptr1++ = ya_out; + + xc_out = (xa - xb + xc - xd); + yc_out = (ya - yb + yc - yd); + + /* writing xc' and yc' */ + *ptr1++ = xc_out; + *ptr1++ = yc_out; + + xb_out = (xa + yb - xc - yd); + yb_out = (ya - xb - yc + xd); + + /* writing xb' and yb' */ + *ptr1++ = xb_out; + *ptr1++ = yb_out; + + xd_out = (xa - yb - xc + yd); + yd_out = (ya + xb - yc - xd); + + /* writing xd' and yd' */ + *ptr1++ = xd_out; + *ptr1++ = yd_out; + + + } while (--j); + + /* output is in 11.21(q21) format for the 1024 point */ + /* output is in 9.23(q23) format for the 256 point */ + /* output is in 7.25(q25) format for the 64 point */ + /* output is in 5.27(q27) format for the 16 point */ + + /* End of last stage process */ + +} + + +/** + @brief Core function for the Q31 CIFFT butterfly process. + @param[in,out] pSrc points to the in-place buffer of Q31 data type. + @param[in] fftLen length of the FFT. + @param[in] pCoef points to twiddle coefficient buffer. + @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + @return none + */ + +/* + * Radix-4 IFFT algorithm used is : + * + * CIFFT uses same twiddle coefficients as CFFT Function + * x[k] = x[n] + (j)k * x[n + fftLen/4] + (-1)k * x[n+fftLen/2] + (-j)k * x[n+3*fftLen/4] + * + * + * IFFT is implemented with following changes in equations from FFT + * + * Input real and imaginary data: + * x(n) = xa + j * ya + * x(n+N/4 ) = xb + j * yb + * x(n+N/2 ) = xc + j * yc + * x(n+3N 4) = xd + j * yd + * + * + * Output real and imaginary data: + * x(4r) = xa'+ j * ya' + * x(4r+1) = xb'+ j * yb' + * x(4r+2) = xc'+ j * yc' + * x(4r+3) = xd'+ j * yd' + * + * + * Twiddle factors for radix-4 IFFT: + * Wn = co1 + j * (si1) + * W2n = co2 + j * (si2) + * W3n = co3 + j * (si3) + + * The real and imaginary output values for the radix-4 butterfly are + * xa' = xa + xb + xc + xd + * ya' = ya + yb + yc + yd + * xb' = (xa-yb-xc+yd)* co1 - (ya+xb-yc-xd)* (si1) + * yb' = (ya+xb-yc-xd)* co1 + (xa-yb-xc+yd)* (si1) + * xc' = (xa-xb+xc-xd)* co2 - (ya-yb+yc-yd)* (si2) + * yc' = (ya-yb+yc-yd)* co2 + (xa-xb+xc-xd)* (si2) + * xd' = (xa+yb-xc-yd)* co3 - (ya-xb-yc+xd)* (si3) + * yd' = (ya-xb-yc+xd)* co3 + (xa+yb-xc-yd)* (si3) + * + */ + +void arm_radix4_butterfly_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pCoef, + uint32_t twidCoefModifier) +{ + uint32_t n1, n2, ia1, ia2, ia3, i0, i1, i2, i3, j, k; + q31_t t1, t2, r1, r2, s1, s2, co1, co2, co3, si1, si2, si3; + q31_t xa, xb, xc, xd; + q31_t ya, yb, yc, yd; + q31_t xa_out, xb_out, xc_out, xd_out; + q31_t ya_out, yb_out, yc_out, yd_out; + + q31_t *ptr1; + + /* input is be 1.31(q31) format for all FFT sizes */ + /* Total process is divided into three stages */ + /* process first stage, middle stages, & last stage */ + + /* Start of first stage process */ + + /* Initializations for the first stage */ + n2 = fftLen; + n1 = n2; + /* n2 = fftLen/4 */ + n2 >>= 2U; + i0 = 0U; + ia1 = 0U; + + j = n2; + + do + { + /* input is in 1.31(q31) format and provide 4 guard bits for the input */ + + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2U], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Butterfly implementation */ + /* xa + xc */ + r1 = (pSrc[2U * i0] >> 4U) + (pSrc[2U * i2] >> 4U); + /* xa - xc */ + r2 = (pSrc[2U * i0] >> 4U) - (pSrc[2U * i2] >> 4U); + + /* xb + xd */ + t1 = (pSrc[2U * i1] >> 4U) + (pSrc[2U * i3] >> 4U); + + /* ya + yc */ + s1 = (pSrc[(2U * i0) + 1U] >> 4U) + (pSrc[(2U * i2) + 1U] >> 4U); + /* ya - yc */ + s2 = (pSrc[(2U * i0) + 1U] >> 4U) - (pSrc[(2U * i2) + 1U] >> 4U); + + /* xa' = xa + xb + xc + xd */ + pSrc[2U * i0] = (r1 + t1); + /* (xa + xc) - (xb + xd) */ + r1 = r1 - t1; + /* yb + yd */ + t2 = (pSrc[(2U * i1) + 1U] >> 4U) + (pSrc[(2U * i3) + 1U] >> 4U); + /* ya' = ya + yb + yc + yd */ + pSrc[(2U * i0) + 1U] = (s1 + t2); + + /* (ya + yc) - (yb + yd) */ + s1 = s1 - t2; + + /* yb - yd */ + t1 = (pSrc[(2U * i1) + 1U] >> 4U) - (pSrc[(2U * i3) + 1U] >> 4U); + /* xb - xd */ + t2 = (pSrc[2U * i1] >> 4U) - (pSrc[2U * i3] >> 4U); + + /* index calculation for the coefficients */ + ia2 = 2U * ia1; + co2 = pCoef[ia2 * 2U]; + si2 = pCoef[(ia2 * 2U) + 1U]; + + /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = (((int32_t) (((q63_t) r1 * co2) >> 32)) - + ((int32_t) (((q63_t) s1 * si2) >> 32))) << 1U; + + /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */ + pSrc[2U * i1 + 1U] = (((int32_t) (((q63_t) s1 * co2) >> 32)) + + ((int32_t) (((q63_t) r1 * si2) >> 32))) << 1U; + + /* (xa - xc) - (yb - yd) */ + r1 = r2 - t1; + /* (xa - xc) + (yb - yd) */ + r2 = r2 + t1; + + /* (ya - yc) + (xb - xd) */ + s1 = s2 + t2; + /* (ya - yc) - (xb - xd) */ + s2 = s2 - t2; + + co1 = pCoef[ia1 * 2U]; + si1 = pCoef[(ia1 * 2U) + 1U]; + + /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = (((int32_t) (((q63_t) r1 * co1) >> 32)) - + ((int32_t) (((q63_t) s1 * si1) >> 32))) << 1U; + + /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = (((int32_t) (((q63_t) s1 * co1) >> 32)) + + ((int32_t) (((q63_t) r1 * si1) >> 32))) << 1U; + + /* index calculation for the coefficients */ + ia3 = 3U * ia1; + co3 = pCoef[ia3 * 2U]; + si3 = pCoef[(ia3 * 2U) + 1U]; + + /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */ + pSrc[2U * i3] = (((int32_t) (((q63_t) r2 * co3) >> 32)) - + ((int32_t) (((q63_t) s2 * si3) >> 32))) << 1U; + + /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = (((int32_t) (((q63_t) s2 * co3) >> 32)) + + ((int32_t) (((q63_t) r2 * si3) >> 32))) << 1U; + + /* Twiddle coefficients index modifier */ + ia1 = ia1 + twidCoefModifier; + + /* Updating input index */ + i0 = i0 + 1U; + + } while (--j); + + /* data is in 5.27(q27) format */ + /* each stage provides two down scaling of the input */ + + + /* Start of Middle stages process */ + + twidCoefModifier <<= 2U; + + /* Calculation of second stage to excluding last stage */ + for (k = fftLen / 4U; k > 4U; k >>= 2U) + { + /* Initializations for the first stage */ + n1 = n2; + n2 >>= 2U; + ia1 = 0U; + + for (j = 0; j <= (n2 - 1U); j++) + { + /* index calculation for the coefficients */ + ia2 = ia1 + ia1; + ia3 = ia2 + ia1; + co1 = pCoef[(ia1 * 2U)]; + si1 = pCoef[(ia1 * 2U) + 1U]; + co2 = pCoef[(ia2 * 2U)]; + si2 = pCoef[(ia2 * 2U) + 1U]; + co3 = pCoef[(ia3 * 2U)]; + si3 = pCoef[(ia3 * 2U) + 1U]; + /* Twiddle coefficients index modifier */ + ia1 = ia1 + twidCoefModifier; + + for (i0 = j; i0 < fftLen; i0 += n1) + { + /* index calculation for the input as, */ + /* pSrc[i0 + 0], pSrc[i0 + fftLen/4], pSrc[i0 + fftLen/2U], pSrc[i0 + 3fftLen/4] */ + i1 = i0 + n2; + i2 = i1 + n2; + i3 = i2 + n2; + + /* Butterfly implementation */ + /* xa + xc */ + r1 = pSrc[2U * i0] + pSrc[2U * i2]; + /* xa - xc */ + r2 = pSrc[2U * i0] - pSrc[2U * i2]; + + /* ya + yc */ + s1 = pSrc[(2U * i0) + 1U] + pSrc[(2U * i2) + 1U]; + /* ya - yc */ + s2 = pSrc[(2U * i0) + 1U] - pSrc[(2U * i2) + 1U]; + + /* xb + xd */ + t1 = pSrc[2U * i1] + pSrc[2U * i3]; + + /* xa' = xa + xb + xc + xd */ + pSrc[2U * i0] = (r1 + t1) >> 2U; + /* xa + xc -(xb + xd) */ + r1 = r1 - t1; + /* yb + yd */ + t2 = pSrc[(2U * i1) + 1U] + pSrc[(2U * i3) + 1U]; + /* ya' = ya + yb + yc + yd */ + pSrc[(2U * i0) + 1U] = (s1 + t2) >> 2U; + + /* (ya + yc) - (yb + yd) */ + s1 = s1 - t2; + + /* (yb - yd) */ + t1 = pSrc[(2U * i1) + 1U] - pSrc[(2U * i3) + 1U]; + /* (xb - xd) */ + t2 = pSrc[2U * i1] - pSrc[2U * i3]; + + /* xc' = (xa-xb+xc-xd)co2 - (ya-yb+yc-yd)(si2) */ + pSrc[2U * i1] = (((int32_t) (((q63_t) r1 * co2) >> 32U)) - + ((int32_t) (((q63_t) s1 * si2) >> 32U))) >> 1U; + + /* yc' = (ya-yb+yc-yd)co2 + (xa-xb+xc-xd)(si2) */ + pSrc[(2U * i1) + 1U] = (((int32_t) (((q63_t) s1 * co2) >> 32U)) + + ((int32_t) (((q63_t) r1 * si2) >> 32U))) >> 1U; + + /* (xa - xc) - (yb - yd) */ + r1 = r2 - t1; + /* (xa - xc) + (yb - yd) */ + r2 = r2 + t1; + + /* (ya - yc) + (xb - xd) */ + s1 = s2 + t2; + /* (ya - yc) - (xb - xd) */ + s2 = s2 - t2; + + /* xb' = (xa+yb-xc-yd)co1 - (ya-xb-yc+xd)(si1) */ + pSrc[2U * i2] = (((int32_t) (((q63_t) r1 * co1) >> 32)) - + ((int32_t) (((q63_t) s1 * si1) >> 32))) >> 1U; + + /* yb' = (ya-xb-yc+xd)co1 + (xa+yb-xc-yd)(si1) */ + pSrc[(2U * i2) + 1U] = (((int32_t) (((q63_t) s1 * co1) >> 32)) + + ((int32_t) (((q63_t) r1 * si1) >> 32))) >> 1U; + + /* xd' = (xa-yb-xc+yd)co3 - (ya+xb-yc-xd)(si3) */ + pSrc[(2U * i3)] = (((int32_t) (((q63_t) r2 * co3) >> 32)) - + ((int32_t) (((q63_t) s2 * si3) >> 32))) >> 1U; + + /* yd' = (ya+xb-yc-xd)co3 + (xa-yb-xc+yd)(si3) */ + pSrc[(2U * i3) + 1U] = (((int32_t) (((q63_t) s2 * co3) >> 32)) + + ((int32_t) (((q63_t) r2 * si3) >> 32))) >> 1U; + } + } + twidCoefModifier <<= 2U; + } + + /* End of Middle stages process */ + + /* data is in 11.21(q21) format for the 1024 point as there are 3 middle stages */ + /* data is in 9.23(q23) format for the 256 point as there are 2 middle stages */ + /* data is in 7.25(q25) format for the 64 point as there are 1 middle stage */ + /* data is in 5.27(q27) format for the 16 point as there are no middle stages */ + + + /* Start of last stage process */ + + + /* Initializations for the last stage */ + j = fftLen >> 2; + ptr1 = &pSrc[0]; + + /* Calculations of last stage */ + do + { + /* Read xa (real), ya(imag) input */ + xa = *ptr1++; + ya = *ptr1++; + + /* Read xb (real), yb(imag) input */ + xb = *ptr1++; + yb = *ptr1++; + + /* Read xc (real), yc(imag) input */ + xc = *ptr1++; + yc = *ptr1++; + + /* Read xc (real), yc(imag) input */ + xd = *ptr1++; + yd = *ptr1++; + + /* xa' = xa + xb + xc + xd */ + xa_out = xa + xb + xc + xd; + + /* ya' = ya + yb + yc + yd */ + ya_out = ya + yb + yc + yd; + + /* pointer updation for writing */ + ptr1 = ptr1 - 8U; + + /* writing xa' and ya' */ + *ptr1++ = xa_out; + *ptr1++ = ya_out; + + xc_out = (xa - xb + xc - xd); + yc_out = (ya - yb + yc - yd); + + /* writing xc' and yc' */ + *ptr1++ = xc_out; + *ptr1++ = yc_out; + + xb_out = (xa - yb - xc + yd); + yb_out = (ya + xb - yc - xd); + + /* writing xb' and yb' */ + *ptr1++ = xb_out; + *ptr1++ = yb_out; + + xd_out = (xa + yb - xc - yd); + yd_out = (ya - xb - yc + xd); + + /* writing xd' and yd' */ + *ptr1++ = xd_out; + *ptr1++ = yd_out; + + } while (--j); + + /* output is in 11.21(q21) format for the 1024 point */ + /* output is in 9.23(q23) format for the 256 point */ + /* output is in 7.25(q25) format for the 64 point */ + /* output is in 5.27(q27) format for the 16 point */ + + /* End of last stage process */ +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix8_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix8_f32.c new file mode 100644 index 0000000..50048f6 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_cfft_radix8_f32.c @@ -0,0 +1,285 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_radix8_f32.c + * Description: Radix-8 Decimation in Frequency CFFT & CIFFT Floating point processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + + +/* ---------------------------------------------------------------------- + * Internal helper function used by the FFTs + * -------------------------------------------------------------------- */ + +/** + brief Core function for the floating-point CFFT butterfly process. + param[in,out] pSrc points to the in-place buffer of floating-point data type. + param[in] fftLen length of the FFT. + param[in] pCoef points to the twiddle coefficient buffer. + param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + return none +*/ + +void arm_radix8_butterfly_f32( + float32_t * pSrc, + uint16_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier) +{ + uint32_t ia1, ia2, ia3, ia4, ia5, ia6, ia7; + uint32_t i1, i2, i3, i4, i5, i6, i7, i8; + uint32_t id; + uint32_t n1, n2, j; + + float32_t r1, r2, r3, r4, r5, r6, r7, r8; + float32_t t1, t2; + float32_t s1, s2, s3, s4, s5, s6, s7, s8; + float32_t p1, p2, p3, p4; + float32_t co2, co3, co4, co5, co6, co7, co8; + float32_t si2, si3, si4, si5, si6, si7, si8; + const float32_t C81 = 0.70710678118f; + + n2 = fftLen; + + do + { + n1 = n2; + n2 = n2 >> 3; + i1 = 0; + + do + { + i2 = i1 + n2; + i3 = i2 + n2; + i4 = i3 + n2; + i5 = i4 + n2; + i6 = i5 + n2; + i7 = i6 + n2; + i8 = i7 + n2; + r1 = pSrc[2 * i1] + pSrc[2 * i5]; + r5 = pSrc[2 * i1] - pSrc[2 * i5]; + r2 = pSrc[2 * i2] + pSrc[2 * i6]; + r6 = pSrc[2 * i2] - pSrc[2 * i6]; + r3 = pSrc[2 * i3] + pSrc[2 * i7]; + r7 = pSrc[2 * i3] - pSrc[2 * i7]; + r4 = pSrc[2 * i4] + pSrc[2 * i8]; + r8 = pSrc[2 * i4] - pSrc[2 * i8]; + t1 = r1 - r3; + r1 = r1 + r3; + r3 = r2 - r4; + r2 = r2 + r4; + pSrc[2 * i1] = r1 + r2; + pSrc[2 * i5] = r1 - r2; + r1 = pSrc[2 * i1 + 1] + pSrc[2 * i5 + 1]; + s5 = pSrc[2 * i1 + 1] - pSrc[2 * i5 + 1]; + r2 = pSrc[2 * i2 + 1] + pSrc[2 * i6 + 1]; + s6 = pSrc[2 * i2 + 1] - pSrc[2 * i6 + 1]; + s3 = pSrc[2 * i3 + 1] + pSrc[2 * i7 + 1]; + s7 = pSrc[2 * i3 + 1] - pSrc[2 * i7 + 1]; + r4 = pSrc[2 * i4 + 1] + pSrc[2 * i8 + 1]; + s8 = pSrc[2 * i4 + 1] - pSrc[2 * i8 + 1]; + t2 = r1 - s3; + r1 = r1 + s3; + s3 = r2 - r4; + r2 = r2 + r4; + pSrc[2 * i1 + 1] = r1 + r2; + pSrc[2 * i5 + 1] = r1 - r2; + pSrc[2 * i3] = t1 + s3; + pSrc[2 * i7] = t1 - s3; + pSrc[2 * i3 + 1] = t2 - r3; + pSrc[2 * i7 + 1] = t2 + r3; + r1 = (r6 - r8) * C81; + r6 = (r6 + r8) * C81; + r2 = (s6 - s8) * C81; + s6 = (s6 + s8) * C81; + t1 = r5 - r1; + r5 = r5 + r1; + r8 = r7 - r6; + r7 = r7 + r6; + t2 = s5 - r2; + s5 = s5 + r2; + s8 = s7 - s6; + s7 = s7 + s6; + pSrc[2 * i2] = r5 + s7; + pSrc[2 * i8] = r5 - s7; + pSrc[2 * i6] = t1 + s8; + pSrc[2 * i4] = t1 - s8; + pSrc[2 * i2 + 1] = s5 - r7; + pSrc[2 * i8 + 1] = s5 + r7; + pSrc[2 * i6 + 1] = t2 - r8; + pSrc[2 * i4 + 1] = t2 + r8; + + i1 += n1; + } while (i1 < fftLen); + + if (n2 < 8) + break; + + ia1 = 0; + j = 1; + + do + { + /* index calculation for the coefficients */ + id = ia1 + twidCoefModifier; + ia1 = id; + ia2 = ia1 + id; + ia3 = ia2 + id; + ia4 = ia3 + id; + ia5 = ia4 + id; + ia6 = ia5 + id; + ia7 = ia6 + id; + + co2 = pCoef[2 * ia1]; + co3 = pCoef[2 * ia2]; + co4 = pCoef[2 * ia3]; + co5 = pCoef[2 * ia4]; + co6 = pCoef[2 * ia5]; + co7 = pCoef[2 * ia6]; + co8 = pCoef[2 * ia7]; + si2 = pCoef[2 * ia1 + 1]; + si3 = pCoef[2 * ia2 + 1]; + si4 = pCoef[2 * ia3 + 1]; + si5 = pCoef[2 * ia4 + 1]; + si6 = pCoef[2 * ia5 + 1]; + si7 = pCoef[2 * ia6 + 1]; + si8 = pCoef[2 * ia7 + 1]; + + i1 = j; + + do + { + /* index calculation for the input */ + i2 = i1 + n2; + i3 = i2 + n2; + i4 = i3 + n2; + i5 = i4 + n2; + i6 = i5 + n2; + i7 = i6 + n2; + i8 = i7 + n2; + r1 = pSrc[2 * i1] + pSrc[2 * i5]; + r5 = pSrc[2 * i1] - pSrc[2 * i5]; + r2 = pSrc[2 * i2] + pSrc[2 * i6]; + r6 = pSrc[2 * i2] - pSrc[2 * i6]; + r3 = pSrc[2 * i3] + pSrc[2 * i7]; + r7 = pSrc[2 * i3] - pSrc[2 * i7]; + r4 = pSrc[2 * i4] + pSrc[2 * i8]; + r8 = pSrc[2 * i4] - pSrc[2 * i8]; + t1 = r1 - r3; + r1 = r1 + r3; + r3 = r2 - r4; + r2 = r2 + r4; + pSrc[2 * i1] = r1 + r2; + r2 = r1 - r2; + s1 = pSrc[2 * i1 + 1] + pSrc[2 * i5 + 1]; + s5 = pSrc[2 * i1 + 1] - pSrc[2 * i5 + 1]; + s2 = pSrc[2 * i2 + 1] + pSrc[2 * i6 + 1]; + s6 = pSrc[2 * i2 + 1] - pSrc[2 * i6 + 1]; + s3 = pSrc[2 * i3 + 1] + pSrc[2 * i7 + 1]; + s7 = pSrc[2 * i3 + 1] - pSrc[2 * i7 + 1]; + s4 = pSrc[2 * i4 + 1] + pSrc[2 * i8 + 1]; + s8 = pSrc[2 * i4 + 1] - pSrc[2 * i8 + 1]; + t2 = s1 - s3; + s1 = s1 + s3; + s3 = s2 - s4; + s2 = s2 + s4; + r1 = t1 + s3; + t1 = t1 - s3; + pSrc[2 * i1 + 1] = s1 + s2; + s2 = s1 - s2; + s1 = t2 - r3; + t2 = t2 + r3; + p1 = co5 * r2; + p2 = si5 * s2; + p3 = co5 * s2; + p4 = si5 * r2; + pSrc[2 * i5] = p1 + p2; + pSrc[2 * i5 + 1] = p3 - p4; + p1 = co3 * r1; + p2 = si3 * s1; + p3 = co3 * s1; + p4 = si3 * r1; + pSrc[2 * i3] = p1 + p2; + pSrc[2 * i3 + 1] = p3 - p4; + p1 = co7 * t1; + p2 = si7 * t2; + p3 = co7 * t2; + p4 = si7 * t1; + pSrc[2 * i7] = p1 + p2; + pSrc[2 * i7 + 1] = p3 - p4; + r1 = (r6 - r8) * C81; + r6 = (r6 + r8) * C81; + s1 = (s6 - s8) * C81; + s6 = (s6 + s8) * C81; + t1 = r5 - r1; + r5 = r5 + r1; + r8 = r7 - r6; + r7 = r7 + r6; + t2 = s5 - s1; + s5 = s5 + s1; + s8 = s7 - s6; + s7 = s7 + s6; + r1 = r5 + s7; + r5 = r5 - s7; + r6 = t1 + s8; + t1 = t1 - s8; + s1 = s5 - r7; + s5 = s5 + r7; + s6 = t2 - r8; + t2 = t2 + r8; + p1 = co2 * r1; + p2 = si2 * s1; + p3 = co2 * s1; + p4 = si2 * r1; + pSrc[2 * i2] = p1 + p2; + pSrc[2 * i2 + 1] = p3 - p4; + p1 = co8 * r5; + p2 = si8 * s5; + p3 = co8 * s5; + p4 = si8 * r5; + pSrc[2 * i8] = p1 + p2; + pSrc[2 * i8 + 1] = p3 - p4; + p1 = co6 * r6; + p2 = si6 * s6; + p3 = co6 * s6; + p4 = si6 * r6; + pSrc[2 * i6] = p1 + p2; + pSrc[2 * i6 + 1] = p3 - p4; + p1 = co4 * t1; + p2 = si4 * t2; + p3 = co4 * t2; + p4 = si4 * t1; + pSrc[2 * i4] = p1 + p2; + pSrc[2 * i4 + 1] = p3 - p4; + + i1 += n1; + } while (i1 < fftLen); + + j++; + } while (j < n2); + + twidCoefModifier <<= 3; + } while (n2 > 7); +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_f32.c new file mode 100644 index 0000000..87455dc --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_f32.c @@ -0,0 +1,448 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_dct4_f32.c + * Description: Processing function of DCT4 & IDCT4 F32 + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup groupTransforms + */ + +/** + @defgroup DCT4_IDCT4 DCT Type IV Functions + + Representation of signals by minimum number of values is important for storage and transmission. + The possibility of large discontinuity between the beginning and end of a period of a signal + in DFT can be avoided by extending the signal so that it is even-symmetric. + Discrete Cosine Transform (DCT) is constructed such that its energy is heavily concentrated in the lower part of the + spectrum and is very widely used in signal and image coding applications. + The family of DCTs (DCT type- 1,2,3,4) is the outcome of different combinations of homogeneous boundary conditions. + DCT has an excellent energy-packing capability, hence has many applications and in data compression in particular. + + DCT is essentially the Discrete Fourier Transform(DFT) of an even-extended real signal. + Reordering of the input data makes the computation of DCT just a problem of + computing the DFT of a real signal with a few additional operations. + This approach provides regular, simple, and very efficient DCT algorithms for practical hardware and software implementations. + + DCT type-II can be implemented using Fast fourier transform (FFT) internally, as the transform is applied on real values, Real FFT can be used. + DCT4 is implemented using DCT2 as their implementations are similar except with some added pre-processing and post-processing. + DCT2 implementation can be described in the following steps: + - Re-ordering input + - Calculating Real FFT + - Multiplication of weights and Real FFT output and getting real part from the product. + + This process is explained by the block diagram below: + \image html DCT4.gif "Discrete Cosine Transform - type-IV" + + @par Algorithm + The N-point type-IV DCT is defined as a real, linear transformation by the formula: + \image html DCT4Equation.gif + where k = 0, 1, 2, ..., N-1 + @par + Its inverse is defined as follows: + \image html IDCT4Equation.gif + where n = 0, 1, 2, ..., N-1 + @par + The DCT4 matrices become involutory (i.e. they are self-inverse) by multiplying with an overall scale factor of sqrt(2/N). + The symmetry of the transform matrix indicates that the fast algorithms for the forward + and inverse transform computation are identical. + Note that the implementation of Inverse DCT4 and DCT4 is same, hence same process function can be used for both. + + @par Lengths supported by the transform: + As DCT4 internally uses Real FFT, it supports all the lengths 128, 512, 2048 and 8192. + The library provides separate functions for Q15, Q31, and floating-point data types. + + @par Instance Structure + The instances for Real FFT and FFT, cosine values table and twiddle factor table are stored in an instance data structure. + A separate instance structure must be defined for each transform. + There are separate instance structure declarations for each of the 3 supported data types. + + @par Initialization Functions + There is also an associated initialization function for each data type. + The initialization function performs the following operations: + - Sets the values of the internal structure fields. + - Initializes Real FFT as its process function is used internally in DCT4, by calling \ref arm_rfft_init_f32(). + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure cannot be placed into a const data section. + To place an instance structure into a const data section, the instance structure must be manually initialized. + Manually initialize the instance structure as follows: +
+      arm_dct4_instance_f32 S = {N, Nby2, normalize, pTwiddle, pCosFactor, pRfft, pCfft};
+      arm_dct4_instance_q31 S = {N, Nby2, normalize, pTwiddle, pCosFactor, pRfft, pCfft};
+      arm_dct4_instance_q15 S = {N, Nby2, normalize, pTwiddle, pCosFactor, pRfft, pCfft};
+  
+ where \c N is the length of the DCT4; \c Nby2 is half of the length of the DCT4; + \c normalize is normalizing factor used and is equal to sqrt(2/N); + \c pTwiddle points to the twiddle factor table; + \c pCosFactor points to the cosFactor table; + \c pRfft points to the real FFT instance; + \c pCfft points to the complex FFT instance; + The CFFT and RFFT structures also needs to be initialized, refer to arm_cfft_radix4_f32() + and arm_rfft_f32() respectively for details regarding static initialization. + + @par Fixed-Point Behavior + Care must be taken when using the fixed-point versions of the DCT4 transform 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 DCT4_IDCT4 + @{ + */ + +/** + @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 + @return none + */ + +void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer) +{ + const float32_t *weights = S->pTwiddle; /* Pointer to the Weights table */ + const float32_t *cosFact = S->pCosFactor; /* Pointer to the cos factors table */ + float32_t *pS1, *pS2, *pbuff; /* Temporary pointers for input buffer and pState buffer */ + float32_t in; /* Temporary variable */ + uint32_t i; /* Loop counter */ + + + /* DCT4 computation involves DCT2 (which is calculated using RFFT) + * along with some pre-processing and post-processing. + * Computational procedure is explained as follows: + * (a) Pre-processing involves multiplying input with cos factor, + * r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n)) + * where, + * r(n) -- output of preprocessing + * u(n) -- input to preprocessing(actual Source buffer) + * (b) Calculation of DCT2 using FFT is divided into three steps: + * Step1: Re-ordering of even and odd elements of input. + * Step2: Calculating FFT of the re-ordered input. + * Step3: Taking the real part of the product of FFT output and weights. + * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation: + * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0) + * where, + * Y4 -- DCT4 output, Y2 -- DCT2 output + * (d) Multiplying the output with the normalizing factor sqrt(2/N). + */ + + /*-------- Pre-processing ------------*/ + /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */ + arm_scale_f32(pInlineBuffer, 2.0f, pInlineBuffer, S->N); + arm_mult_f32(pInlineBuffer, cosFact, pInlineBuffer, S->N); + + /* ---------------------------------------------------------------- + * Step1: Re-ordering of even and odd elements as + * pState[i] = pInlineBuffer[2*i] and + * pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2 + ---------------------------------------------------------------------*/ + + /* pS1 initialized to pState */ + pS1 = pState; + + /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */ + pS2 = pState + (S->N - 1U); + + /* pbuff initialized to input buffer */ + pbuff = pInlineBuffer; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */ + i = S->Nby2 >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + do + { + /* Re-ordering of even and odd elements */ + /* pState[i] = pInlineBuffer[2*i] */ + *pS1++ = *pbuff++; + /* pState[N-i-1] = pInlineBuffer[2*i+1] */ + *pS2-- = *pbuff++; + + *pS1++ = *pbuff++; + *pS2-- = *pbuff++; + + *pS1++ = *pbuff++; + *pS2-- = *pbuff++; + + *pS1++ = *pbuff++; + *pS2-- = *pbuff++; + + /* Decrement loop counter */ + i--; + } while (i > 0U); + + /* pbuff initialized to input buffer */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Initializing the loop counter to N/4 instead of N for loop unrolling */ + i = S->N >> 2U; + + /* Processing with loop unrolling 4 times as N is always multiple of 4. + * Compute 4 outputs at a time */ + do + { + /* Writing the re-ordered output back to inplace input buffer */ + *pbuff++ = *pS1++; + *pbuff++ = *pS1++; + *pbuff++ = *pS1++; + *pbuff++ = *pS1++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + + /* --------------------------------------------------------- + * Step2: Calculate RFFT for N-point input + * ---------------------------------------------------------- */ + /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */ + arm_rfft_f32 (S->pRfft, pInlineBuffer, pState); + + /*---------------------------------------------------------------------- + * Step3: Multiply the FFT output with the weights. + *----------------------------------------------------------------------*/ + arm_cmplx_mult_cmplx_f32 (pState, weights, pState, S->N); + + /* ----------- Post-processing ---------- */ + /* DCT-IV can be obtained from DCT-II by the equation, + * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0) + * Hence, Y4(0) = Y2(0)/2 */ + /* Getting only real part from the output and Converting to DCT-IV */ + + /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */ + i = (S->N - 1U) >> 2U; + + /* pbuff initialized to input buffer. */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */ + in = *pS1++ * (float32_t) 0.5; + /* input buffer acts as inplace, so output values are stored in the input itself. */ + *pbuff++ = in; + + /* pState pointer is incremented twice as the real values are located alternatively in the array */ + pS1++; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + do + { + /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */ + /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */ + in = *pS1++ - in; + *pbuff++ = in; + /* points to the next real value */ + pS1++; + + in = *pS1++ - in; + *pbuff++ = in; + pS1++; + + in = *pS1++ - in; + *pbuff++ = in; + pS1++; + + in = *pS1++ - in; + *pbuff++ = in; + pS1++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + i = (S->N - 1U) % 0x4U; + + while (i > 0U) + { + /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */ + /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */ + in = *pS1++ - in; + *pbuff++ = in; + + /* points to the next real value */ + pS1++; + + /* Decrement the loop counter */ + i--; + } + + + /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/ + + /* Initializing the loop counter to N/4 instead of N for loop unrolling */ + i = S->N >> 2U; + + /* pbuff initialized to the pInlineBuffer(now contains the output values) */ + pbuff = pInlineBuffer; + + /* Processing with loop unrolling 4 times as N is always multiple of 4. Compute 4 outputs at a time */ + do + { + /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */ + in = *pbuff; + *pbuff++ = in * S->normalize; + + in = *pbuff; + *pbuff++ = in * S->normalize; + + in = *pbuff; + *pbuff++ = in * S->normalize; + + in = *pbuff; + *pbuff++ = in * S->normalize; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + +#else + + /* Initializing the loop counter to N/2 */ + i = S->Nby2; + + do + { + /* Re-ordering of even and odd elements */ + /* pState[i] = pInlineBuffer[2*i] */ + *pS1++ = *pbuff++; + /* pState[N-i-1] = pInlineBuffer[2*i+1] */ + *pS2-- = *pbuff++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + /* pbuff initialized to input buffer */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Initializing the loop counter */ + i = S->N; + + do + { + /* Writing the re-ordered output back to inplace input buffer */ + *pbuff++ = *pS1++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + + /* --------------------------------------------------------- + * Step2: Calculate RFFT for N-point input + * ---------------------------------------------------------- */ + /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */ + arm_rfft_f32 (S->pRfft, pInlineBuffer, pState); + + /*---------------------------------------------------------------------- + * Step3: Multiply the FFT output with the weights. + *----------------------------------------------------------------------*/ + arm_cmplx_mult_cmplx_f32 (pState, weights, pState, S->N); + + /* ----------- Post-processing ---------- */ + /* DCT-IV can be obtained from DCT-II by the equation, + * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0) + * Hence, Y4(0) = Y2(0)/2 */ + /* Getting only real part from the output and Converting to DCT-IV */ + + /* pbuff initialized to input buffer. */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */ + in = *pS1++ * (float32_t) 0.5; + /* input buffer acts as inplace, so output values are stored in the input itself. */ + *pbuff++ = in; + + /* pState pointer is incremented twice as the real values are located alternatively in the array */ + pS1++; + + /* Initializing the loop counter */ + i = (S->N - 1U); + + do + { + /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */ + /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */ + in = *pS1++ - in; + *pbuff++ = in; + + /* points to the next real value */ + pS1++; + + /* Decrement loop counter */ + i--; + } while (i > 0U); + + /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/ + + /* Initializing loop counter */ + i = S->N; + + /* pbuff initialized to the pInlineBuffer (now contains the output values) */ + pbuff = pInlineBuffer; + + do + { + /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */ + in = *pbuff; + *pbuff++ = in * S->normalize; + + /* Decrement loop counter */ + i--; + } while (i > 0U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + +} + +/** + @} end of DCT4_IDCT4 group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_f32.c new file mode 100644 index 0000000..588ee7d --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_f32.c @@ -0,0 +1,16027 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_dct4_init_f32.c + * Description: Initialization function of DCT-4 & IDCT4 F32 + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup DCT4_IDCT4 + */ + +/** + @addtogroup DCT4_IDCT4_Table DCT Type IV Tables + @{ + */ + +/** + @brief Weights Table + */ + +/** + @par + Weights tables are generated using the formula :
weights[n] = e^(-j*n*pi/(2*N))
+ @par + C command to generate the table +
+  for(i = 0; i< N; i++)
+  {
+    weights[(2*i)]   =  cos (i*c);
+    weights[(2*i)+1] = -sin (i*c);
+  } 
+ @par + where N is the Number of weights to be calculated and c is pi/(2*N) + @par + In the tables below the real and imaginary values are placed alternatively, hence the + array length is 2*N. + */ + +static const float32_t Weights_128[256] = { + 1.000000000000000000f, 0.000000000000000000f, 0.999924701839144500f, -0.012271538285719925f, + 0.999698818696204250f, -0.024541228522912288f, 0.999322384588349540f, -0.036807222941358832f, + 0.998795456205172410f, -0.049067674327418015f, 0.998118112900149180f, -0.061320736302208578f, + 0.997290456678690210f, -0.073564563599667426f, 0.996312612182778000f, -0.085797312344439894f, + 0.995184726672196930f, -0.098017140329560604f, 0.993906970002356060f, -0.110222207293883060f, + 0.992479534598709970f, -0.122410675199216200f, 0.990902635427780010f, -0.134580708507126170f, + 0.989176509964781010f, -0.146730474455361750f, 0.987301418157858430f, -0.158858143333861450f, + 0.985277642388941220f, -0.170961888760301220f, 0.983105487431216290f, -0.183039887955140950f, + 0.980785280403230430f, -0.195090322016128250f, 0.978317370719627650f, -0.207111376192218560f, + 0.975702130038528570f, -0.219101240156869800f, 0.972939952205560180f, -0.231058108280671110f, + 0.970031253194543970f, -0.242980179903263870f, 0.966976471044852070f, -0.254865659604514570f, + 0.963776065795439840f, -0.266712757474898370f, 0.960430519415565790f, -0.278519689385053060f, + 0.956940335732208820f, -0.290284677254462330f, 0.953306040354193860f, -0.302005949319228080f, + 0.949528180593036670f, -0.313681740398891520f, 0.945607325380521280f, -0.325310292162262930f, + 0.941544065183020810f, -0.336889853392220050f, 0.937339011912574960f, -0.348418680249434560f, + 0.932992798834738960f, -0.359895036534988110f, 0.928506080473215590f, -0.371317193951837540f, + 0.923879532511286740f, -0.382683432365089780f, 0.919113851690057770f, -0.393992040061048100f, + 0.914209755703530690f, -0.405241314004989860f, 0.909167983090522380f, -0.416429560097637150f, + 0.903989293123443340f, -0.427555093430282080f, 0.898674465693953820f, -0.438616238538527660f, + 0.893224301195515320f, -0.449611329654606540f, 0.887639620402853930f, -0.460538710958240010f, + 0.881921264348355050f, -0.471396736825997640f, 0.876070094195406600f, -0.482183772079122720f, + 0.870086991108711460f, -0.492898192229784040f, 0.863972856121586810f, -0.503538383725717580f, + 0.857728610000272120f, -0.514102744193221660f, 0.851355193105265200f, -0.524589682678468950f, + 0.844853565249707120f, -0.534997619887097150f, 0.838224705554838080f, -0.545324988422046460f, + 0.831469612302545240f, -0.555570233019602180f, 0.824589302785025290f, -0.565731810783613120f, + 0.817584813151583710f, -0.575808191417845340f, 0.810457198252594770f, -0.585797857456438860f, + 0.803207531480644940f, -0.595699304492433360f, 0.795836904608883570f, -0.605511041404325550f, + 0.788346427626606340f, -0.615231590580626820f, 0.780737228572094490f, -0.624859488142386340f, + 0.773010453362736990f, -0.634393284163645490f, 0.765167265622458960f, -0.643831542889791390f, + 0.757208846506484570f, -0.653172842953776760f, 0.749136394523459370f, -0.662415777590171780f, + 0.740951125354959110f, -0.671558954847018330f, 0.732654271672412820f, -0.680600997795453020f, + 0.724247082951467000f, -0.689540544737066830f, 0.715730825283818590f, -0.698376249408972920f, + 0.707106781186547570f, -0.707106781186547460f, 0.698376249408972920f, -0.715730825283818590f, + 0.689540544737066940f, -0.724247082951466890f, 0.680600997795453130f, -0.732654271672412820f, + 0.671558954847018330f, -0.740951125354959110f, 0.662415777590171780f, -0.749136394523459260f, + 0.653172842953776760f, -0.757208846506484460f, 0.643831542889791500f, -0.765167265622458960f, + 0.634393284163645490f, -0.773010453362736990f, 0.624859488142386450f, -0.780737228572094380f, + 0.615231590580626820f, -0.788346427626606230f, 0.605511041404325550f, -0.795836904608883460f, + 0.595699304492433470f, -0.803207531480644830f, 0.585797857456438860f, -0.810457198252594770f, + 0.575808191417845340f, -0.817584813151583710f, 0.565731810783613230f, -0.824589302785025290f, + 0.555570233019602290f, -0.831469612302545240f, 0.545324988422046460f, -0.838224705554837970f, + 0.534997619887097260f, -0.844853565249707010f, 0.524589682678468840f, -0.851355193105265200f, + 0.514102744193221660f, -0.857728610000272120f, 0.503538383725717580f, -0.863972856121586700f, + 0.492898192229784090f, -0.870086991108711350f, 0.482183772079122830f, -0.876070094195406600f, + 0.471396736825997810f, -0.881921264348354940f, 0.460538710958240010f, -0.887639620402853930f, + 0.449611329654606600f, -0.893224301195515320f, 0.438616238538527710f, -0.898674465693953820f, + 0.427555093430282200f, -0.903989293123443340f, 0.416429560097637320f, -0.909167983090522270f, + 0.405241314004989860f, -0.914209755703530690f, 0.393992040061048100f, -0.919113851690057770f, + 0.382683432365089840f, -0.923879532511286740f, 0.371317193951837600f, -0.928506080473215480f, + 0.359895036534988280f, -0.932992798834738850f, 0.348418680249434510f, -0.937339011912574960f, + 0.336889853392220050f, -0.941544065183020810f, 0.325310292162262980f, -0.945607325380521280f, + 0.313681740398891570f, -0.949528180593036670f, 0.302005949319228200f, -0.953306040354193750f, + 0.290284677254462330f, -0.956940335732208940f, 0.278519689385053060f, -0.960430519415565790f, + 0.266712757474898420f, -0.963776065795439840f, 0.254865659604514630f, -0.966976471044852070f, + 0.242980179903263980f, -0.970031253194543970f, 0.231058108280671280f, -0.972939952205560070f, + 0.219101240156869770f, -0.975702130038528570f, 0.207111376192218560f, -0.978317370719627650f, + 0.195090322016128330f, -0.980785280403230430f, 0.183039887955141060f, -0.983105487431216290f, + 0.170961888760301360f, -0.985277642388941220f, 0.158858143333861390f, -0.987301418157858430f, + 0.146730474455361750f, -0.989176509964781010f, 0.134580708507126220f, -0.990902635427780010f, + 0.122410675199216280f, -0.992479534598709970f, 0.110222207293883180f, -0.993906970002356060f, + 0.098017140329560770f, -0.995184726672196820f, 0.085797312344439880f, -0.996312612182778000f, + 0.073564563599667454f, -0.997290456678690210f, 0.061320736302208648f, -0.998118112900149180f, + 0.049067674327418126f, -0.998795456205172410f, 0.036807222941358991f, -0.999322384588349540f, + 0.024541228522912264f, -0.999698818696204250f, 0.012271538285719944f, -0.999924701839144500f +}; + +static const float32_t Weights_512[1024] = { + 1.000000000000000000f, 0.000000000000000000f, 0.999995293809576190f, -0.003067956762965976f, + 0.999981175282601110f, -0.006135884649154475f, 0.999957644551963900f, -0.009203754782059819f, + 0.999924701839144500f, -0.012271538285719925f, 0.999882347454212560f, -0.015339206284988100f, + 0.999830581795823400f, -0.018406729905804820f, 0.999769405351215280f, -0.021474080275469508f, + 0.999698818696204250f, -0.024541228522912288f, 0.999618822495178640f, -0.027608145778965740f, + 0.999529417501093140f, -0.030674803176636626f, 0.999430604555461730f, -0.033741171851377580f, + 0.999322384588349540f, -0.036807222941358832f, 0.999204758618363890f, -0.039872927587739811f, + 0.999077727752645360f, -0.042938256934940820f, 0.998941293186856870f, -0.046003182130914623f, + 0.998795456205172410f, -0.049067674327418015f, 0.998640218180265270f, -0.052131704680283324f, + 0.998475580573294770f, -0.055195244349689934f, 0.998301544933892890f, -0.058258264500435752f, + 0.998118112900149180f, -0.061320736302208578f, 0.997925286198596000f, -0.064382630929857465f, + 0.997723066644191640f, -0.067443919563664051f, 0.997511456140303450f, -0.070504573389613856f, + 0.997290456678690210f, -0.073564563599667426f, 0.997060070339482960f, -0.076623861392031492f, + 0.996820299291165670f, -0.079682437971430126f, 0.996571145790554840f, -0.082740264549375692f, + 0.996312612182778000f, -0.085797312344439894f, 0.996044700901251970f, -0.088853552582524600f, + 0.995767414467659820f, -0.091908956497132724f, 0.995480755491926940f, -0.094963495329638992f, + 0.995184726672196930f, -0.098017140329560604f, 0.994879330794805620f, -0.101069862754827820f, + 0.994564570734255420f, -0.104121633872054590f, 0.994240449453187900f, -0.107172424956808840f, + 0.993906970002356060f, -0.110222207293883060f, 0.993564135520595300f, -0.113270952177564350f, + 0.993211949234794500f, -0.116318630911904750f, 0.992850414459865100f, -0.119365214810991350f, + 0.992479534598709970f, -0.122410675199216200f, 0.992099313142191800f, -0.125454983411546230f, + 0.991709753669099530f, -0.128498110793793170f, 0.991310859846115440f, -0.131540028702883120f, + 0.990902635427780010f, -0.134580708507126170f, 0.990485084256457090f, -0.137620121586486040f, + 0.990058210262297120f, -0.140658239332849210f, 0.989622017463200890f, -0.143695033150294470f, + 0.989176509964781010f, -0.146730474455361750f, 0.988721691960323780f, -0.149764534677321510f, + 0.988257567730749460f, -0.152797185258443440f, 0.987784141644572180f, -0.155828397654265230f, + 0.987301418157858430f, -0.158858143333861450f, 0.986809401814185530f, -0.161886393780111830f, + 0.986308097244598670f, -0.164913120489969890f, 0.985797509167567480f, -0.167938294974731170f, + 0.985277642388941220f, -0.170961888760301220f, 0.984748501801904210f, -0.173983873387463820f, + 0.984210092386929030f, -0.177004220412148750f, 0.983662419211730250f, -0.180022901405699510f, + 0.983105487431216290f, -0.183039887955140950f, 0.982539302287441240f, -0.186055151663446630f, + 0.981963869109555240f, -0.189068664149806190f, 0.981379193313754560f, -0.192080397049892440f, + 0.980785280403230430f, -0.195090322016128250f, 0.980182135968117430f, -0.198098410717953560f, + 0.979569765685440520f, -0.201104634842091900f, 0.978948175319062200f, -0.204108966092816870f, + 0.978317370719627650f, -0.207111376192218560f, 0.977677357824509930f, -0.210111836880469610f, + 0.977028142657754390f, -0.213110319916091360f, 0.976369731330021140f, -0.216106797076219520f, + 0.975702130038528570f, -0.219101240156869800f, 0.975025345066994120f, -0.222093620973203510f, + 0.974339382785575860f, -0.225083911359792830f, 0.973644249650811980f, -0.228072083170885730f, + 0.972939952205560180f, -0.231058108280671110f, 0.972226497078936270f, -0.234041958583543430f, + 0.971503890986251780f, -0.237023605994367200f, 0.970772140728950350f, -0.240003022448741500f, + 0.970031253194543970f, -0.242980179903263870f, 0.969281235356548530f, -0.245955050335794590f, + 0.968522094274417380f, -0.248927605745720150f, 0.967753837093475510f, -0.251897818154216970f, + 0.966976471044852070f, -0.254865659604514570f, 0.966190003445412500f, -0.257831102162158990f, + 0.965394441697689400f, -0.260794117915275510f, 0.964589793289812760f, -0.263754678974831350f, + 0.963776065795439840f, -0.266712757474898370f, 0.962953266873683880f, -0.269668325572915090f, + 0.962121404269041580f, -0.272621355449948980f, 0.961280485811320640f, -0.275571819310958140f, + 0.960430519415565790f, -0.278519689385053060f, 0.959571513081984520f, -0.281464937925757940f, + 0.958703474895871600f, -0.284407537211271880f, 0.957826413027532910f, -0.287347459544729510f, + 0.956940335732208820f, -0.290284677254462330f, 0.956045251349996410f, -0.293219162694258630f, + 0.955141168305770780f, -0.296150888243623790f, 0.954228095109105670f, -0.299079826308040480f, + 0.953306040354193860f, -0.302005949319228080f, 0.952375012719765880f, -0.304929229735402370f, + 0.951435020969008340f, -0.307849640041534870f, 0.950486073949481700f, -0.310767152749611470f, + 0.949528180593036670f, -0.313681740398891520f, 0.948561349915730270f, -0.316593375556165850f, + 0.947585591017741090f, -0.319502030816015690f, 0.946600913083283530f, -0.322407678801069850f, + 0.945607325380521280f, -0.325310292162262930f, 0.944604837261480260f, -0.328209843579092500f, + 0.943593458161960390f, -0.331106305759876430f, 0.942573197601446870f, -0.333999651442009380f, + 0.941544065183020810f, -0.336889853392220050f, 0.940506070593268300f, -0.339776884406826850f, + 0.939459223602189920f, -0.342660717311994380f, 0.938403534063108060f, -0.345541324963989090f, + 0.937339011912574960f, -0.348418680249434560f, 0.936265667170278260f, -0.351292756085567090f, + 0.935183509938947610f, -0.354163525420490340f, 0.934092550404258980f, -0.357030961233429980f, + 0.932992798834738960f, -0.359895036534988110f, 0.931884265581668150f, -0.362755724367397230f, + 0.930766961078983710f, -0.365612997804773850f, 0.929640895843181330f, -0.368466829953372320f, + 0.928506080473215590f, -0.371317193951837540f, 0.927362525650401110f, -0.374164062971457930f, + 0.926210242138311380f, -0.377007410216418260f, 0.925049240782677580f, -0.379847208924051160f, + 0.923879532511286740f, -0.382683432365089780f, 0.922701128333878630f, -0.385516053843918850f, + 0.921514039342042010f, -0.388345046698826250f, 0.920318276709110590f, -0.391170384302253870f, + 0.919113851690057770f, -0.393992040061048100f, 0.917900775621390500f, -0.396809987416710310f, + 0.916679059921042700f, -0.399624199845646790f, 0.915448716088267830f, -0.402434650859418430f, + 0.914209755703530690f, -0.405241314004989860f, 0.912962190428398210f, -0.408044162864978690f, + 0.911706032005429880f, -0.410843171057903910f, 0.910441292258067250f, -0.413638312238434500f, + 0.909167983090522380f, -0.416429560097637150f, 0.907886116487666260f, -0.419216888363223910f, + 0.906595704514915330f, -0.422000270799799680f, 0.905296759318118820f, -0.424779681209108810f, + 0.903989293123443340f, -0.427555093430282080f, 0.902673318237258830f, -0.430326481340082610f, + 0.901348847046022030f, -0.433093818853151960f, 0.900015892016160280f, -0.435857079922255470f, + 0.898674465693953820f, -0.438616238538527660f, 0.897324580705418320f, -0.441371268731716670f, + 0.895966249756185220f, -0.444122144570429200f, 0.894599485631382700f, -0.446868840162374160f, + 0.893224301195515320f, -0.449611329654606540f, 0.891840709392342720f, -0.452349587233770890f, + 0.890448723244757880f, -0.455083587126343840f, 0.889048355854664570f, -0.457813303598877170f, + 0.887639620402853930f, -0.460538710958240010f, 0.886222530148880640f, -0.463259783551860150f, + 0.884797098430937790f, -0.465976495767966180f, 0.883363338665731580f, -0.468688822035827900f, + 0.881921264348355050f, -0.471396736825997640f, 0.880470889052160750f, -0.474100214650549970f, + 0.879012226428633530f, -0.476799230063322090f, 0.877545290207261350f, -0.479493757660153010f, + 0.876070094195406600f, -0.482183772079122720f, 0.874586652278176110f, -0.484869248000791060f, + 0.873094978418290090f, -0.487550160148436000f, 0.871595086655950980f, -0.490226483288291160f, + 0.870086991108711460f, -0.492898192229784040f, 0.868570705971340900f, -0.495565261825772540f, + 0.867046245515692650f, -0.498227666972781870f, 0.865513624090569090f, -0.500885382611240710f, + 0.863972856121586810f, -0.503538383725717580f, 0.862423956111040610f, -0.506186645345155230f, + 0.860866938637767310f, -0.508830142543106990f, 0.859301818357008470f, -0.511468850437970300f, + 0.857728610000272120f, -0.514102744193221660f, 0.856147328375194470f, -0.516731799017649870f, + 0.854557988365400530f, -0.519355990165589640f, 0.852960604930363630f, -0.521975292937154390f, + 0.851355193105265200f, -0.524589682678468950f, 0.849741768000852550f, -0.527199134781901280f, + 0.848120344803297230f, -0.529803624686294610f, 0.846490938774052130f, -0.532403127877197900f, + 0.844853565249707120f, -0.534997619887097150f, 0.843208239641845440f, -0.537587076295645390f, + 0.841554977436898440f, -0.540171472729892850f, 0.839893794195999520f, -0.542750784864515890f, + 0.838224705554838080f, -0.545324988422046460f, 0.836547727223512010f, -0.547894059173100190f, + 0.834862874986380010f, -0.550457972936604810f, 0.833170164701913190f, -0.553016705580027470f, + 0.831469612302545240f, -0.555570233019602180f, 0.829761233794523050f, -0.558118531220556100f, + 0.828045045257755800f, -0.560661576197336030f, 0.826321062845663530f, -0.563199344013834090f, + 0.824589302785025290f, -0.565731810783613120f, 0.822849781375826430f, -0.568258952670131490f, + 0.821102514991104650f, -0.570780745886967260f, 0.819347520076796900f, -0.573297166698042200f, + 0.817584813151583710f, -0.575808191417845340f, 0.815814410806733780f, -0.578313796411655590f, + 0.814036329705948410f, -0.580813958095764530f, 0.812250586585203880f, -0.583308652937698290f, + 0.810457198252594770f, -0.585797857456438860f, 0.808656181588174980f, -0.588281548222645220f, + 0.806847553543799330f, -0.590759701858874160f, 0.805031331142963660f, -0.593232295039799800f, + 0.803207531480644940f, -0.595699304492433360f, 0.801376171723140240f, -0.598160706996342270f, + 0.799537269107905010f, -0.600616479383868970f, 0.797690840943391160f, -0.603066598540348160f, + 0.795836904608883570f, -0.605511041404325550f, 0.793975477554337170f, -0.607949784967773630f, + 0.792106577300212390f, -0.610382806276309480f, 0.790230221437310030f, -0.612810082429409710f, + 0.788346427626606340f, -0.615231590580626820f, 0.786455213599085770f, -0.617647307937803870f, + 0.784556597155575240f, -0.620057211763289100f, 0.782650596166575730f, -0.622461279374149970f, + 0.780737228572094490f, -0.624859488142386340f, 0.778816512381475980f, -0.627251815495144080f, + 0.776888465673232440f, -0.629638238914926980f, 0.774953106594873930f, -0.632018735939809060f, + 0.773010453362736990f, -0.634393284163645490f, 0.771060524261813820f, -0.636761861236284200f, + 0.769103337645579700f, -0.639124444863775730f, 0.767138911935820400f, -0.641481012808583160f, + 0.765167265622458960f, -0.643831542889791390f, 0.763188417263381270f, -0.646176012983316280f, + 0.761202385484261780f, -0.648514401022112440f, 0.759209188978388070f, -0.650846684996380880f, + 0.757208846506484570f, -0.653172842953776760f, 0.755201376896536550f, -0.655492852999615350f, + 0.753186799043612520f, -0.657806693297078640f, 0.751165131909686480f, -0.660114342067420480f, + 0.749136394523459370f, -0.662415777590171780f, 0.747100605980180130f, -0.664710978203344790f, + 0.745057785441466060f, -0.666999922303637470f, 0.743007952135121720f, -0.669282588346636010f, + 0.740951125354959110f, -0.671558954847018330f, 0.738887324460615110f, -0.673829000378756040f, + 0.736816568877369900f, -0.676092703575315920f, 0.734738878095963500f, -0.678350043129861470f, + 0.732654271672412820f, -0.680600997795453020f, 0.730562769227827590f, -0.682845546385248080f, + 0.728464390448225200f, -0.685083667772700360f, 0.726359155084346010f, -0.687315340891759050f, + 0.724247082951467000f, -0.689540544737066830f, 0.722128193929215350f, -0.691759258364157750f, + 0.720002507961381650f, -0.693971460889654000f, 0.717870045055731710f, -0.696177131491462990f, + 0.715730825283818590f, -0.698376249408972920f, 0.713584868780793640f, -0.700568793943248340f, + 0.711432195745216430f, -0.702754744457225300f, 0.709272826438865690f, -0.704934080375904880f, + 0.707106781186547570f, -0.707106781186547460f, 0.704934080375904990f, -0.709272826438865580f, + 0.702754744457225300f, -0.711432195745216430f, 0.700568793943248450f, -0.713584868780793520f, + 0.698376249408972920f, -0.715730825283818590f, 0.696177131491462990f, -0.717870045055731710f, + 0.693971460889654000f, -0.720002507961381650f, 0.691759258364157750f, -0.722128193929215350f, + 0.689540544737066940f, -0.724247082951466890f, 0.687315340891759160f, -0.726359155084346010f, + 0.685083667772700360f, -0.728464390448225200f, 0.682845546385248080f, -0.730562769227827590f, + 0.680600997795453130f, -0.732654271672412820f, 0.678350043129861580f, -0.734738878095963390f, + 0.676092703575316030f, -0.736816568877369790f, 0.673829000378756150f, -0.738887324460615110f, + 0.671558954847018330f, -0.740951125354959110f, 0.669282588346636010f, -0.743007952135121720f, + 0.666999922303637470f, -0.745057785441465950f, 0.664710978203344900f, -0.747100605980180130f, + 0.662415777590171780f, -0.749136394523459260f, 0.660114342067420480f, -0.751165131909686370f, + 0.657806693297078640f, -0.753186799043612410f, 0.655492852999615460f, -0.755201376896536550f, + 0.653172842953776760f, -0.757208846506484460f, 0.650846684996380990f, -0.759209188978387960f, + 0.648514401022112550f, -0.761202385484261780f, 0.646176012983316390f, -0.763188417263381270f, + 0.643831542889791500f, -0.765167265622458960f, 0.641481012808583160f, -0.767138911935820400f, + 0.639124444863775730f, -0.769103337645579590f, 0.636761861236284200f, -0.771060524261813710f, + 0.634393284163645490f, -0.773010453362736990f, 0.632018735939809060f, -0.774953106594873820f, + 0.629638238914927100f, -0.776888465673232440f, 0.627251815495144190f, -0.778816512381475870f, + 0.624859488142386450f, -0.780737228572094380f, 0.622461279374150080f, -0.782650596166575730f, + 0.620057211763289210f, -0.784556597155575240f, 0.617647307937803980f, -0.786455213599085770f, + 0.615231590580626820f, -0.788346427626606230f, 0.612810082429409710f, -0.790230221437310030f, + 0.610382806276309480f, -0.792106577300212390f, 0.607949784967773740f, -0.793975477554337170f, + 0.605511041404325550f, -0.795836904608883460f, 0.603066598540348280f, -0.797690840943391040f, + 0.600616479383868970f, -0.799537269107905010f, 0.598160706996342380f, -0.801376171723140130f, + 0.595699304492433470f, -0.803207531480644830f, 0.593232295039799800f, -0.805031331142963660f, + 0.590759701858874280f, -0.806847553543799220f, 0.588281548222645330f, -0.808656181588174980f, + 0.585797857456438860f, -0.810457198252594770f, 0.583308652937698290f, -0.812250586585203880f, + 0.580813958095764530f, -0.814036329705948300f, 0.578313796411655590f, -0.815814410806733780f, + 0.575808191417845340f, -0.817584813151583710f, 0.573297166698042320f, -0.819347520076796900f, + 0.570780745886967370f, -0.821102514991104650f, 0.568258952670131490f, -0.822849781375826320f, + 0.565731810783613230f, -0.824589302785025290f, 0.563199344013834090f, -0.826321062845663420f, + 0.560661576197336030f, -0.828045045257755800f, 0.558118531220556100f, -0.829761233794523050f, + 0.555570233019602290f, -0.831469612302545240f, 0.553016705580027580f, -0.833170164701913190f, + 0.550457972936604810f, -0.834862874986380010f, 0.547894059173100190f, -0.836547727223511890f, + 0.545324988422046460f, -0.838224705554837970f, 0.542750784864516000f, -0.839893794195999410f, + 0.540171472729892970f, -0.841554977436898330f, 0.537587076295645510f, -0.843208239641845440f, + 0.534997619887097260f, -0.844853565249707010f, 0.532403127877198010f, -0.846490938774052020f, + 0.529803624686294830f, -0.848120344803297120f, 0.527199134781901390f, -0.849741768000852440f, + 0.524589682678468840f, -0.851355193105265200f, 0.521975292937154390f, -0.852960604930363630f, + 0.519355990165589530f, -0.854557988365400530f, 0.516731799017649980f, -0.856147328375194470f, + 0.514102744193221660f, -0.857728610000272120f, 0.511468850437970520f, -0.859301818357008360f, + 0.508830142543106990f, -0.860866938637767310f, 0.506186645345155450f, -0.862423956111040500f, + 0.503538383725717580f, -0.863972856121586700f, 0.500885382611240940f, -0.865513624090568980f, + 0.498227666972781870f, -0.867046245515692650f, 0.495565261825772490f, -0.868570705971340900f, + 0.492898192229784090f, -0.870086991108711350f, 0.490226483288291100f, -0.871595086655951090f, + 0.487550160148436050f, -0.873094978418290090f, 0.484869248000791120f, -0.874586652278176110f, + 0.482183772079122830f, -0.876070094195406600f, 0.479493757660153010f, -0.877545290207261240f, + 0.476799230063322250f, -0.879012226428633410f, 0.474100214650550020f, -0.880470889052160750f, + 0.471396736825997810f, -0.881921264348354940f, 0.468688822035827960f, -0.883363338665731580f, + 0.465976495767966130f, -0.884797098430937790f, 0.463259783551860260f, -0.886222530148880640f, + 0.460538710958240010f, -0.887639620402853930f, 0.457813303598877290f, -0.889048355854664570f, + 0.455083587126343840f, -0.890448723244757880f, 0.452349587233771000f, -0.891840709392342720f, + 0.449611329654606600f, -0.893224301195515320f, 0.446868840162374330f, -0.894599485631382580f, + 0.444122144570429260f, -0.895966249756185110f, 0.441371268731716620f, -0.897324580705418320f, + 0.438616238538527710f, -0.898674465693953820f, 0.435857079922255470f, -0.900015892016160280f, + 0.433093818853152010f, -0.901348847046022030f, 0.430326481340082610f, -0.902673318237258830f, + 0.427555093430282200f, -0.903989293123443340f, 0.424779681209108810f, -0.905296759318118820f, + 0.422000270799799790f, -0.906595704514915330f, 0.419216888363223960f, -0.907886116487666150f, + 0.416429560097637320f, -0.909167983090522270f, 0.413638312238434560f, -0.910441292258067140f, + 0.410843171057903910f, -0.911706032005429880f, 0.408044162864978740f, -0.912962190428398100f, + 0.405241314004989860f, -0.914209755703530690f, 0.402434650859418540f, -0.915448716088267830f, + 0.399624199845646790f, -0.916679059921042700f, 0.396809987416710420f, -0.917900775621390390f, + 0.393992040061048100f, -0.919113851690057770f, 0.391170384302253980f, -0.920318276709110480f, + 0.388345046698826300f, -0.921514039342041900f, 0.385516053843919020f, -0.922701128333878520f, + 0.382683432365089840f, -0.923879532511286740f, 0.379847208924051110f, -0.925049240782677580f, + 0.377007410216418310f, -0.926210242138311270f, 0.374164062971457990f, -0.927362525650401110f, + 0.371317193951837600f, -0.928506080473215480f, 0.368466829953372320f, -0.929640895843181330f, + 0.365612997804773960f, -0.930766961078983710f, 0.362755724367397230f, -0.931884265581668150f, + 0.359895036534988280f, -0.932992798834738850f, 0.357030961233430030f, -0.934092550404258870f, + 0.354163525420490510f, -0.935183509938947500f, 0.351292756085567150f, -0.936265667170278260f, + 0.348418680249434510f, -0.937339011912574960f, 0.345541324963989150f, -0.938403534063108060f, + 0.342660717311994380f, -0.939459223602189920f, 0.339776884406826960f, -0.940506070593268300f, + 0.336889853392220050f, -0.941544065183020810f, 0.333999651442009490f, -0.942573197601446870f, + 0.331106305759876430f, -0.943593458161960390f, 0.328209843579092660f, -0.944604837261480260f, + 0.325310292162262980f, -0.945607325380521280f, 0.322407678801070020f, -0.946600913083283530f, + 0.319502030816015750f, -0.947585591017741090f, 0.316593375556165850f, -0.948561349915730270f, + 0.313681740398891570f, -0.949528180593036670f, 0.310767152749611470f, -0.950486073949481700f, + 0.307849640041534980f, -0.951435020969008340f, 0.304929229735402430f, -0.952375012719765880f, + 0.302005949319228200f, -0.953306040354193750f, 0.299079826308040480f, -0.954228095109105670f, + 0.296150888243623960f, -0.955141168305770670f, 0.293219162694258680f, -0.956045251349996410f, + 0.290284677254462330f, -0.956940335732208940f, 0.287347459544729570f, -0.957826413027532910f, + 0.284407537211271820f, -0.958703474895871600f, 0.281464937925758050f, -0.959571513081984520f, + 0.278519689385053060f, -0.960430519415565790f, 0.275571819310958250f, -0.961280485811320640f, + 0.272621355449948980f, -0.962121404269041580f, 0.269668325572915200f, -0.962953266873683880f, + 0.266712757474898420f, -0.963776065795439840f, 0.263754678974831510f, -0.964589793289812650f, + 0.260794117915275570f, -0.965394441697689400f, 0.257831102162158930f, -0.966190003445412620f, + 0.254865659604514630f, -0.966976471044852070f, 0.251897818154216910f, -0.967753837093475510f, + 0.248927605745720260f, -0.968522094274417270f, 0.245955050335794590f, -0.969281235356548530f, + 0.242980179903263980f, -0.970031253194543970f, 0.240003022448741500f, -0.970772140728950350f, + 0.237023605994367340f, -0.971503890986251780f, 0.234041958583543460f, -0.972226497078936270f, + 0.231058108280671280f, -0.972939952205560070f, 0.228072083170885790f, -0.973644249650811870f, + 0.225083911359792780f, -0.974339382785575860f, 0.222093620973203590f, -0.975025345066994120f, + 0.219101240156869770f, -0.975702130038528570f, 0.216106797076219600f, -0.976369731330021140f, + 0.213110319916091360f, -0.977028142657754390f, 0.210111836880469720f, -0.977677357824509930f, + 0.207111376192218560f, -0.978317370719627650f, 0.204108966092817010f, -0.978948175319062200f, + 0.201104634842091960f, -0.979569765685440520f, 0.198098410717953730f, -0.980182135968117320f, + 0.195090322016128330f, -0.980785280403230430f, 0.192080397049892380f, -0.981379193313754560f, + 0.189068664149806280f, -0.981963869109555240f, 0.186055151663446630f, -0.982539302287441240f, + 0.183039887955141060f, -0.983105487431216290f, 0.180022901405699510f, -0.983662419211730250f, + 0.177004220412148860f, -0.984210092386929030f, 0.173983873387463850f, -0.984748501801904210f, + 0.170961888760301360f, -0.985277642388941220f, 0.167938294974731230f, -0.985797509167567370f, + 0.164913120489970090f, -0.986308097244598670f, 0.161886393780111910f, -0.986809401814185420f, + 0.158858143333861390f, -0.987301418157858430f, 0.155828397654265320f, -0.987784141644572180f, + 0.152797185258443410f, -0.988257567730749460f, 0.149764534677321620f, -0.988721691960323780f, + 0.146730474455361750f, -0.989176509964781010f, 0.143695033150294580f, -0.989622017463200780f, + 0.140658239332849240f, -0.990058210262297120f, 0.137620121586486180f, -0.990485084256456980f, + 0.134580708507126220f, -0.990902635427780010f, 0.131540028702883280f, -0.991310859846115440f, + 0.128498110793793220f, -0.991709753669099530f, 0.125454983411546210f, -0.992099313142191800f, + 0.122410675199216280f, -0.992479534598709970f, 0.119365214810991350f, -0.992850414459865100f, + 0.116318630911904880f, -0.993211949234794500f, 0.113270952177564360f, -0.993564135520595300f, + 0.110222207293883180f, -0.993906970002356060f, 0.107172424956808870f, -0.994240449453187900f, + 0.104121633872054730f, -0.994564570734255420f, 0.101069862754827880f, -0.994879330794805620f, + 0.098017140329560770f, -0.995184726672196820f, 0.094963495329639061f, -0.995480755491926940f, + 0.091908956497132696f, -0.995767414467659820f, 0.088853552582524684f, -0.996044700901251970f, + 0.085797312344439880f, -0.996312612182778000f, 0.082740264549375803f, -0.996571145790554840f, + 0.079682437971430126f, -0.996820299291165670f, 0.076623861392031617f, -0.997060070339482960f, + 0.073564563599667454f, -0.997290456678690210f, 0.070504573389614009f, -0.997511456140303450f, + 0.067443919563664106f, -0.997723066644191640f, 0.064382630929857410f, -0.997925286198596000f, + 0.061320736302208648f, -0.998118112900149180f, 0.058258264500435732f, -0.998301544933892890f, + 0.055195244349690031f, -0.998475580573294770f, 0.052131704680283317f, -0.998640218180265270f, + 0.049067674327418126f, -0.998795456205172410f, 0.046003182130914644f, -0.998941293186856870f, + 0.042938256934940959f, -0.999077727752645360f, 0.039872927587739845f, -0.999204758618363890f, + 0.036807222941358991f, -0.999322384588349540f, 0.033741171851377642f, -0.999430604555461730f, + 0.030674803176636581f, -0.999529417501093140f, 0.027608145778965820f, -0.999618822495178640f, + 0.024541228522912264f, -0.999698818696204250f, 0.021474080275469605f, -0.999769405351215280f, + 0.018406729905804820f, -0.999830581795823400f, 0.015339206284988220f, -0.999882347454212560f, + 0.012271538285719944f, -0.999924701839144500f, 0.009203754782059960f, -0.999957644551963900f, + 0.006135884649154515f, -0.999981175282601110f, 0.003067956762966138f, -0.999995293809576190f +}; + +static const float32_t Weights_2048[4096] = { + 1.000000000000000000f, 0.000000000000000000f, 0.999999705862882230f, -0.000766990318742704f, + 0.999998823451701880f, -0.001533980186284766f, 0.999997352766978210f, -0.002300969151425805f, + 0.999995293809576190f, -0.003067956762965976f, 0.999992646580707190f, -0.003834942569706228f, + 0.999989411081928400f, -0.004601926120448571f, 0.999985587315143200f, -0.005368906963996343f, + 0.999981175282601110f, -0.006135884649154475f, 0.999976174986897610f, -0.006902858724729756f, + 0.999970586430974140f, -0.007669828739531097f, 0.999964409618118280f, -0.008436794242369799f, + 0.999957644551963900f, -0.009203754782059819f, 0.999950291236490480f, -0.009970709907418031f, + 0.999942349676023910f, -0.010737659167264491f, 0.999933819875236000f, -0.011504602110422714f, + 0.999924701839144500f, -0.012271538285719925f, 0.999914995573113470f, -0.013038467241987334f, + 0.999904701082852900f, -0.013805388528060391f, 0.999893818374418490f, -0.014572301692779064f, + 0.999882347454212560f, -0.015339206284988100f, 0.999870288328982950f, -0.016106101853537287f, + 0.999857641005823860f, -0.016872987947281710f, 0.999844405492175240f, -0.017639864115082053f, + 0.999830581795823400f, -0.018406729905804820f, 0.999816169924900410f, -0.019173584868322623f, + 0.999801169887884260f, -0.019940428551514441f, 0.999785581693599210f, -0.020707260504265895f, + 0.999769405351215280f, -0.021474080275469508f, 0.999752640870248840f, -0.022240887414024961f, + 0.999735288260561680f, -0.023007681468839369f, 0.999717347532362190f, -0.023774461988827555f, + 0.999698818696204250f, -0.024541228522912288f, 0.999679701762987930f, -0.025307980620024571f, + 0.999659996743959220f, -0.026074717829103901f, 0.999639703650710200f, -0.026841439699098531f, + 0.999618822495178640f, -0.027608145778965740f, 0.999597353289648380f, -0.028374835617672099f, + 0.999575296046749220f, -0.029141508764193722f, 0.999552650779456990f, -0.029908164767516555f, + 0.999529417501093140f, -0.030674803176636626f, 0.999505596225325310f, -0.031441423540560301f, + 0.999481186966166950f, -0.032208025408304586f, 0.999456189737977340f, -0.032974608328897335f, + 0.999430604555461730f, -0.033741171851377580f, 0.999404431433671300f, -0.034507715524795750f, + 0.999377670388002850f, -0.035274238898213947f, 0.999350321434199440f, -0.036040741520706229f, + 0.999322384588349540f, -0.036807222941358832f, 0.999293859866887790f, -0.037573682709270494f, + 0.999264747286594420f, -0.038340120373552694f, 0.999235046864595850f, -0.039106535483329888f, + 0.999204758618363890f, -0.039872927587739811f, 0.999173882565716380f, -0.040639296235933736f, + 0.999142418724816910f, -0.041405640977076739f, 0.999110367114174890f, -0.042171961360347947f, + 0.999077727752645360f, -0.042938256934940820f, 0.999044500659429290f, -0.043704527250063421f, + 0.999010685854073380f, -0.044470771854938668f, 0.998976283356469820f, -0.045236990298804590f, + 0.998941293186856870f, -0.046003182130914623f, 0.998905715365818290f, -0.046769346900537863f, + 0.998869549914283560f, -0.047535484156959303f, 0.998832796853527990f, -0.048301593449480144f, + 0.998795456205172410f, -0.049067674327418015f, 0.998757527991183340f, -0.049833726340107277f, + 0.998719012233872940f, -0.050599749036899282f, 0.998679908955899090f, -0.051365741967162593f, + 0.998640218180265270f, -0.052131704680283324f, 0.998599939930320370f, -0.052897636725665324f, + 0.998559074229759310f, -0.053663537652730520f, 0.998517621102622210f, -0.054429407010919133f, + 0.998475580573294770f, -0.055195244349689934f, 0.998432952666508440f, -0.055961049218520569f, + 0.998389737407340160f, -0.056726821166907748f, 0.998345934821212370f, -0.057492559744367566f, + 0.998301544933892890f, -0.058258264500435752f, 0.998256567771495180f, -0.059023934984667931f, + 0.998211003360478190f, -0.059789570746639868f, 0.998164851727646240f, -0.060555171335947788f, + 0.998118112900149180f, -0.061320736302208578f, 0.998070786905482340f, -0.062086265195060088f, + 0.998022873771486240f, -0.062851757564161406f, 0.997974373526346990f, -0.063617212959193106f, + 0.997925286198596000f, -0.064382630929857465f, 0.997875611817110150f, -0.065148011025878833f, + 0.997825350411111640f, -0.065913352797003805f, 0.997774502010167820f, -0.066678655793001557f, + 0.997723066644191640f, -0.067443919563664051f, 0.997671044343441000f, -0.068209143658806329f, + 0.997618435138519550f, -0.068974327628266746f, 0.997565239060375750f, -0.069739471021907307f, + 0.997511456140303450f, -0.070504573389613856f, 0.997457086409941910f, -0.071269634281296401f, + 0.997402129901275300f, -0.072034653246889332f, 0.997346586646633230f, -0.072799629836351673f, + 0.997290456678690210f, -0.073564563599667426f, 0.997233740030466280f, -0.074329454086845756f, + 0.997176436735326190f, -0.075094300847921305f, 0.997118546826979980f, -0.075859103432954447f, + 0.997060070339482960f, -0.076623861392031492f, 0.997001007307235290f, -0.077388574275265049f, + 0.996941357764982160f, -0.078153241632794232f, 0.996881121747813850f, -0.078917863014784942f, + 0.996820299291165670f, -0.079682437971430126f, 0.996758890430818000f, -0.080446966052950014f, + 0.996696895202896060f, -0.081211446809592441f, 0.996634313643869900f, -0.081975879791633066f, + 0.996571145790554840f, -0.082740264549375692f, 0.996507391680110820f, -0.083504600633152432f, + 0.996443051350042630f, -0.084268887593324071f, 0.996378124838200210f, -0.085033124980280275f, + 0.996312612182778000f, -0.085797312344439894f, 0.996246513422315520f, -0.086561449236251170f, + 0.996179828595696980f, -0.087325535206192059f, 0.996112557742151130f, -0.088089569804770507f, + 0.996044700901251970f, -0.088853552582524600f, 0.995976258112917790f, -0.089617483090022959f, + 0.995907229417411720f, -0.090381360877864983f, 0.995837614855341610f, -0.091145185496681005f, + 0.995767414467659820f, -0.091908956497132724f, 0.995696628295663520f, -0.092672673429913310f, + 0.995625256380994310f, -0.093436335845747787f, 0.995553298765638470f, -0.094199943295393204f, + 0.995480755491926940f, -0.094963495329638992f, 0.995407626602534900f, -0.095726991499307162f, + 0.995333912140482280f, -0.096490431355252593f, 0.995259612149133390f, -0.097253814448363271f, + 0.995184726672196930f, -0.098017140329560604f, 0.995109255753726110f, -0.098780408549799623f, + 0.995033199438118630f, -0.099543618660069319f, 0.994956557770116380f, -0.100306770211392860f, + 0.994879330794805620f, -0.101069862754827820f, 0.994801518557617110f, -0.101832895841466530f, + 0.994723121104325700f, -0.102595869022436280f, 0.994644138481050710f, -0.103358781848899610f, + 0.994564570734255420f, -0.104121633872054590f, 0.994484417910747600f, -0.104884424643134970f, + 0.994403680057679100f, -0.105647153713410620f, 0.994322357222545810f, -0.106409820634187680f, + 0.994240449453187900f, -0.107172424956808840f, 0.994157956797789730f, -0.107934966232653650f, + 0.994074879304879370f, -0.108697444013138720f, 0.993991217023329380f, -0.109459857849717980f, + 0.993906970002356060f, -0.110222207293883060f, 0.993822138291519660f, -0.110984491897163390f, + 0.993736721940724600f, -0.111746711211126590f, 0.993650721000219120f, -0.112508864787378690f, + 0.993564135520595300f, -0.113270952177564350f, 0.993476965552789190f, -0.114032972933367200f, + 0.993389211148080650f, -0.114794926606510080f, 0.993300872358093280f, -0.115556812748755260f, + 0.993211949234794500f, -0.116318630911904750f, 0.993122441830495580f, -0.117080380647800590f, + 0.993032350197851410f, -0.117842061508324980f, 0.992941674389860470f, -0.118603673045400720f, + 0.992850414459865100f, -0.119365214810991350f, 0.992758570461551140f, -0.120126686357101500f, + 0.992666142448948020f, -0.120888087235777080f, 0.992573130476428810f, -0.121649416999105530f, + 0.992479534598709970f, -0.122410675199216200f, 0.992385354870851670f, -0.123171861388280480f, + 0.992290591348257370f, -0.123932975118512160f, 0.992195244086673920f, -0.124694015942167640f, + 0.992099313142191800f, -0.125454983411546230f, 0.992002798571244520f, -0.126215877078990350f, + 0.991905700430609330f, -0.126976696496885870f, 0.991808018777406430f, -0.127737441217662310f, + 0.991709753669099530f, -0.128498110793793170f, 0.991610905163495370f, -0.129258704777796140f, + 0.991511473318743900f, -0.130019222722233350f, 0.991411458193338540f, -0.130779664179711710f, + 0.991310859846115440f, -0.131540028702883120f, 0.991209678336254060f, -0.132300315844444650f, + 0.991107913723276890f, -0.133060525157139060f, 0.991005566067049370f, -0.133820656193754720f, + 0.990902635427780010f, -0.134580708507126170f, 0.990799121866020370f, -0.135340681650134210f, + 0.990695025442664630f, -0.136100575175706200f, 0.990590346218950150f, -0.136860388636816380f, + 0.990485084256457090f, -0.137620121586486040f, 0.990379239617108160f, -0.138379773577783890f, + 0.990272812363169110f, -0.139139344163826200f, 0.990165802557248400f, -0.139898832897777210f, + 0.990058210262297120f, -0.140658239332849210f, 0.989950035541608990f, -0.141417563022303020f, + 0.989841278458820530f, -0.142176803519448030f, 0.989731939077910570f, -0.142935960377642670f, + 0.989622017463200890f, -0.143695033150294470f, 0.989511513679355190f, -0.144454021390860470f, + 0.989400427791380380f, -0.145212924652847460f, 0.989288759864625170f, -0.145971742489812210f, + 0.989176509964781010f, -0.146730474455361750f, 0.989063678157881540f, -0.147489120103153570f, + 0.988950264510302990f, -0.148247678986896030f, 0.988836269088763540f, -0.149006150660348450f, + 0.988721691960323780f, -0.149764534677321510f, 0.988606533192386450f, -0.150522830591677400f, + 0.988490792852696590f, -0.151281037957330220f, 0.988374471009341280f, -0.152039156328246050f, + 0.988257567730749460f, -0.152797185258443440f, 0.988140083085692570f, -0.153555124301993450f, + 0.988022017143283530f, -0.154312973013020100f, 0.987903369972977790f, -0.155070730945700510f, + 0.987784141644572180f, -0.155828397654265230f, 0.987664332228205710f, -0.156585972692998430f, + 0.987543941794359230f, -0.157343455616238250f, 0.987422970413855410f, -0.158100845978376980f, + 0.987301418157858430f, -0.158858143333861450f, 0.987179285097874340f, -0.159615347237193060f, + 0.987056571305750970f, -0.160372457242928280f, 0.986933276853677710f, -0.161129472905678810f, + 0.986809401814185530f, -0.161886393780111830f, 0.986684946260146690f, -0.162643219420950310f, + 0.986559910264775410f, -0.163399949382973230f, 0.986434293901627180f, -0.164156583221015810f, + 0.986308097244598670f, -0.164913120489969890f, 0.986181320367928270f, -0.165669560744784120f, + 0.986053963346195440f, -0.166425903540464100f, 0.985926026254321130f, -0.167182148432072940f, + 0.985797509167567480f, -0.167938294974731170f, 0.985668412161537550f, -0.168694342723617330f, + 0.985538735312176060f, -0.169450291233967960f, 0.985408478695768420f, -0.170206140061078070f, + 0.985277642388941220f, -0.170961888760301220f, 0.985146226468662230f, -0.171717536887049970f, + 0.985014231012239840f, -0.172473083996795950f, 0.984881656097323700f, -0.173228529645070320f, + 0.984748501801904210f, -0.173983873387463820f, 0.984614768204312600f, -0.174739114779627200f, + 0.984480455383220930f, -0.175494253377271430f, 0.984345563417641900f, -0.176249288736167880f, + 0.984210092386929030f, -0.177004220412148750f, 0.984074042370776450f, -0.177759047961107170f, + 0.983937413449218920f, -0.178513770938997510f, 0.983800205702631600f, -0.179268388901835750f, + 0.983662419211730250f, -0.180022901405699510f, 0.983524054057571260f, -0.180777308006728590f, + 0.983385110321551180f, -0.181531608261124970f, 0.983245588085407070f, -0.182285801725153300f, + 0.983105487431216290f, -0.183039887955140950f, 0.982964808441396440f, -0.183793866507478450f, + 0.982823551198705240f, -0.184547736938619620f, 0.982681715786240860f, -0.185301498805081900f, + 0.982539302287441240f, -0.186055151663446630f, 0.982396310786084690f, -0.186808695070359270f, + 0.982252741366289370f, -0.187562128582529600f, 0.982108594112513610f, -0.188315451756732120f, + 0.981963869109555240f, -0.189068664149806190f, 0.981818566442552500f, -0.189821765318656410f, + 0.981672686196983110f, -0.190574754820252740f, 0.981526228458664770f, -0.191327632211630900f, + 0.981379193313754560f, -0.192080397049892440f, 0.981231580848749730f, -0.192833048892205230f, + 0.981083391150486710f, -0.193585587295803610f, 0.980934624306141640f, -0.194338011817988600f, + 0.980785280403230430f, -0.195090322016128250f, 0.980635359529608120f, -0.195842517447657850f, + 0.980484861773469380f, -0.196594597670080220f, 0.980333787223347960f, -0.197346562240965920f, + 0.980182135968117430f, -0.198098410717953560f, 0.980029908096990090f, -0.198850142658750090f, + 0.979877103699517640f, -0.199601757621130970f, 0.979723722865591170f, -0.200353255162940450f, + 0.979569765685440520f, -0.201104634842091900f, 0.979415232249634780f, -0.201855896216568050f, + 0.979260122649082020f, -0.202607038844421130f, 0.979104436975029250f, -0.203358062283773320f, + 0.978948175319062200f, -0.204108966092816870f, 0.978791337773105670f, -0.204859749829814420f, + 0.978633924429423210f, -0.205610413053099240f, 0.978475935380616830f, -0.206360955321075510f, + 0.978317370719627650f, -0.207111376192218560f, 0.978158230539735050f, -0.207861675225075070f, + 0.977998514934557140f, -0.208611851978263490f, 0.977838223998050430f, -0.209361906010474160f, + 0.977677357824509930f, -0.210111836880469610f, 0.977515916508569280f, -0.210861644147084860f, + 0.977353900145199960f, -0.211611327369227550f, 0.977191308829712280f, -0.212360886105878420f, + 0.977028142657754390f, -0.213110319916091360f, 0.976864401725312640f, -0.213859628358993750f, + 0.976700086128711840f, -0.214608810993786760f, 0.976535195964614470f, -0.215357867379745550f, + 0.976369731330021140f, -0.216106797076219520f, 0.976203692322270560f, -0.216855599642632620f, + 0.976037079039039020f, -0.217604274638483640f, 0.975869891578341030f, -0.218352821623346320f, + 0.975702130038528570f, -0.219101240156869800f, 0.975533794518291360f, -0.219849529798778700f, + 0.975364885116656980f, -0.220597690108873510f, 0.975195401932990370f, -0.221345720647030810f, + 0.975025345066994120f, -0.222093620973203510f, 0.974854714618708430f, -0.222841390647421120f, + 0.974683510688510670f, -0.223589029229789990f, 0.974511733377115720f, -0.224336536280493600f, + 0.974339382785575860f, -0.225083911359792830f, 0.974166459015280320f, -0.225831154028026170f, + 0.973992962167955830f, -0.226578263845610000f, 0.973818892345666100f, -0.227325240373038860f, + 0.973644249650811980f, -0.228072083170885730f, 0.973469034186131070f, -0.228818791799802220f, + 0.973293246054698250f, -0.229565365820518870f, 0.973116885359925130f, -0.230311804793845440f, + 0.972939952205560180f, -0.231058108280671110f, 0.972762446695688570f, -0.231804275841964780f, + 0.972584368934732210f, -0.232550307038775240f, 0.972405719027449770f, -0.233296201432231590f, + 0.972226497078936270f, -0.234041958583543430f, 0.972046703194623500f, -0.234787578054000970f, + 0.971866337480279400f, -0.235533059404975490f, 0.971685400042008540f, -0.236278402197919570f, + 0.971503890986251780f, -0.237023605994367200f, 0.971321810419786160f, -0.237768670355934190f, + 0.971139158449725090f, -0.238513594844318420f, 0.970955935183517970f, -0.239258379021299980f, + 0.970772140728950350f, -0.240003022448741500f, 0.970587775194143630f, -0.240747524688588430f, + 0.970402838687555500f, -0.241491885302869330f, 0.970217331317979160f, -0.242236103853696010f, + 0.970031253194543970f, -0.242980179903263870f, 0.969844604426714830f, -0.243724113013852160f, + 0.969657385124292450f, -0.244467902747824150f, 0.969469595397413060f, -0.245211548667627540f, + 0.969281235356548530f, -0.245955050335794590f, 0.969092305112506210f, -0.246698407314942410f, + 0.968902804776428870f, -0.247441619167773270f, 0.968712734459794780f, -0.248184685457074780f, + 0.968522094274417380f, -0.248927605745720150f, 0.968330884332445190f, -0.249670379596668570f, + 0.968139104746362440f, -0.250413006572965220f, 0.967946755628987800f, -0.251155486237741920f, + 0.967753837093475510f, -0.251897818154216970f, 0.967560349253314360f, -0.252640001885695520f, + 0.967366292222328510f, -0.253382036995570160f, 0.967171666114676640f, -0.254123923047320620f, + 0.966976471044852070f, -0.254865659604514570f, 0.966780707127683270f, -0.255607246230807380f, + 0.966584374478333120f, -0.256348682489942910f, 0.966387473212298900f, -0.257089967945753120f, + 0.966190003445412500f, -0.257831102162158990f, 0.965991965293840570f, + -0.258572084703170340f, + 0.965793358874083680f, -0.259312915132886230f, 0.965594184302976830f, + -0.260053593015495190f, + 0.965394441697689400f, -0.260794117915275510f, 0.965194131175724720f, + -0.261534489396595520f, + 0.964993252854920320f, -0.262274707023913590f, 0.964791806853447900f, + -0.263014770361779000f, + 0.964589793289812760f, -0.263754678974831350f, 0.964387212282854290f, + -0.264494432427801630f, + 0.964184063951745830f, -0.265234030285511790f, 0.963980348415994110f, + -0.265973472112875590f, + 0.963776065795439840f, -0.266712757474898370f, 0.963571216210257320f, + -0.267451885936677620f, + 0.963365799780954050f, -0.268190857063403180f, 0.963159816628371360f, + -0.268929670420357260f, + 0.962953266873683880f, -0.269668325572915090f, 0.962746150638399410f, + -0.270406822086544820f, + 0.962538468044359160f, -0.271145159526808010f, 0.962330219213737400f, + -0.271883337459359720f, + 0.962121404269041580f, -0.272621355449948980f, 0.961912023333112210f, + -0.273359213064418680f, + 0.961702076529122540f, -0.274096909868706380f, 0.961491563980579000f, + -0.274834445428843940f, + 0.961280485811320640f, -0.275571819310958140f, 0.961068842145519350f, + -0.276309031081271080f, + 0.960856633107679660f, -0.277046080306099900f, 0.960643858822638590f, + -0.277782966551857690f, + 0.960430519415565790f, -0.278519689385053060f, 0.960216615011963430f, + -0.279256248372291180f, + 0.960002145737665960f, -0.279992643080273220f, 0.959787111718839900f, + -0.280728873075797190f, + 0.959571513081984520f, -0.281464937925757940f, 0.959355349953930790f, + -0.282200837197147560f, + 0.959138622461841890f, -0.282936570457055390f, 0.958921330733213170f, + -0.283672137272668430f, + 0.958703474895871600f, -0.284407537211271880f, 0.958485055077976100f, + -0.285142769840248670f, + 0.958266071408017670f, -0.285877834727080620f, 0.958046524014818600f, + -0.286612731439347790f, + 0.957826413027532910f, -0.287347459544729510f, 0.957605738575646350f, + -0.288082018611004130f, + 0.957384500788975860f, -0.288816408206049480f, 0.957162699797670210f, + -0.289550627897843030f, + 0.956940335732208820f, -0.290284677254462330f, 0.956717408723403050f, + -0.291018555844085090f, + 0.956493918902395100f, -0.291752263234989260f, 0.956269866400658030f, + -0.292485798995553880f, + 0.956045251349996410f, -0.293219162694258630f, 0.955820073882545420f, + -0.293952353899684660f, + 0.955594334130771110f, -0.294685372180514330f, 0.955368032227470350f, + -0.295418217105532010f, + 0.955141168305770780f, -0.296150888243623790f, 0.954913742499130520f, + -0.296883385163778270f, + 0.954685754941338340f, -0.297615707435086200f, 0.954457205766513490f, + -0.298347854626741400f, + 0.954228095109105670f, -0.299079826308040480f, 0.953998423103894490f, + -0.299811622048383350f, + 0.953768189885990330f, -0.300543241417273450f, 0.953537395590833280f, + -0.301274683984317950f, + 0.953306040354193860f, -0.302005949319228080f, 0.953074124312172200f, + -0.302737036991819140f, + 0.952841647601198720f, -0.303467946572011320f, 0.952608610358033350f, + -0.304198677629829110f, + 0.952375012719765880f, -0.304929229735402370f, 0.952140854823815830f, + -0.305659602458966120f, + 0.951906136807932350f, -0.306389795370860920f, 0.951670858810193860f, + -0.307119808041533100f, + 0.951435020969008340f, -0.307849640041534870f, 0.951198623423113230f, + -0.308579290941525090f, + 0.950961666311575080f, -0.309308760312268730f, 0.950724149773789610f, + -0.310038047724637890f, + 0.950486073949481700f, -0.310767152749611470f, 0.950247438978705230f, + -0.311496074958275910f, + 0.950008245001843000f, -0.312224813921824880f, 0.949768492159606680f, + -0.312953369211560200f, + 0.949528180593036670f, -0.313681740398891520f, 0.949287310443502120f, + -0.314409927055336660f, + 0.949045881852700560f, -0.315137928752522440f, 0.948803894962658490f, + -0.315865745062183960f, + 0.948561349915730270f, -0.316593375556165850f, 0.948318246854599090f, + -0.317320819806421740f, + 0.948074585922276230f, -0.318048077385014950f, 0.947830367262101010f, + -0.318775147864118480f, + 0.947585591017741090f, -0.319502030816015690f, 0.947340257333192050f, + -0.320228725813099860f, + 0.947094366352777220f, -0.320955232427875210f, 0.946847918221148000f, + -0.321681550232956580f, + 0.946600913083283530f, -0.322407678801069850f, 0.946353351084490590f, + -0.323133617705052330f, + 0.946105232370403450f, -0.323859366517852850f, 0.945856557086983910f, + -0.324584924812532150f, + 0.945607325380521280f, -0.325310292162262930f, 0.945357537397632290f, + -0.326035468140330240f, + 0.945107193285260610f, -0.326760452320131730f, 0.944856293190677210f, + -0.327485244275178000f, + 0.944604837261480260f, -0.328209843579092500f, 0.944352825645594750f, + -0.328934249805612200f, + 0.944100258491272660f, -0.329658462528587490f, 0.943847135947092690f, + -0.330382481321982780f, + 0.943593458161960390f, -0.331106305759876430f, 0.943339225285107720f, + -0.331829935416461110f, + 0.943084437466093490f, -0.332553369866044220f, 0.942829094854802710f, + -0.333276608683047930f, + 0.942573197601446870f, -0.333999651442009380f, 0.942316745856563780f, + -0.334722497717581220f, + 0.942059739771017310f, -0.335445147084531600f, 0.941802179495997650f, + -0.336167599117744520f, + 0.941544065183020810f, -0.336889853392220050f, 0.941285396983928660f, + -0.337611909483074620f, + 0.941026175050889260f, -0.338333766965541130f, 0.940766399536396070f, + -0.339055425414969640f, + 0.940506070593268300f, -0.339776884406826850f, 0.940245188374650880f, + -0.340498143516697160f, + 0.939983753034014050f, -0.341219202320282360f, 0.939721764725153340f, + -0.341940060393402190f, + 0.939459223602189920f, -0.342660717311994380f, 0.939196129819569900f, + -0.343381172652115040f, + 0.938932483532064600f, -0.344101425989938810f, 0.938668284894770170f, + -0.344821476901759290f, + 0.938403534063108060f, -0.345541324963989090f, 0.938138231192824360f, + -0.346260969753160010f, + 0.937872376439989890f, -0.346980410845923680f, 0.937605969960999990f, + -0.347699647819051380f, + 0.937339011912574960f, -0.348418680249434560f, 0.937071502451759190f, + -0.349137507714084970f, + 0.936803441735921560f, -0.349856129790134920f, 0.936534829922755500f, + -0.350574546054837510f, + 0.936265667170278260f, -0.351292756085567090f, 0.935995953636831410f, + -0.352010759459819080f, + 0.935725689481080370f, -0.352728555755210730f, 0.935454874862014620f, + -0.353446144549480810f, + 0.935183509938947610f, -0.354163525420490340f, 0.934911594871516090f, + -0.354880697946222790f, + 0.934639129819680780f, -0.355597661704783850f, 0.934366114943725790f, + -0.356314416274402410f, + 0.934092550404258980f, -0.357030961233429980f, 0.933818436362210960f, + -0.357747296160341900f, + 0.933543772978836170f, -0.358463420633736540f, 0.933268560415712050f, + -0.359179334232336500f, + 0.932992798834738960f, -0.359895036534988110f, 0.932716488398140250f, + -0.360610527120662270f, + 0.932439629268462360f, -0.361325805568454280f, 0.932162221608574430f, + -0.362040871457584180f, + 0.931884265581668150f, -0.362755724367397230f, 0.931605761351257830f, + -0.363470363877363760f, + 0.931326709081180430f, -0.364184789567079890f, 0.931047108935595280f, + -0.364899001016267320f, + 0.930766961078983710f, -0.365612997804773850f, 0.930486265676149780f, + -0.366326779512573590f, + 0.930205022892219070f, -0.367040345719767180f, 0.929923232892639670f, + -0.367753696006581980f, + 0.929640895843181330f, -0.368466829953372320f, 0.929358011909935500f, + -0.369179747140620020f, + 0.929074581259315860f, -0.369892447148934100f, 0.928790604058057020f, + -0.370604929559051670f, + 0.928506080473215590f, -0.371317193951837540f, 0.928221010672169440f, + -0.372029239908285010f, + 0.927935394822617890f, -0.372741067009515760f, 0.927649233092581180f, + -0.373452674836780300f, + 0.927362525650401110f, -0.374164062971457930f, 0.927075272664740100f, + -0.374875230995057540f, + 0.926787474304581750f, -0.375586178489217220f, 0.926499130739230510f, + -0.376296905035704790f, + 0.926210242138311380f, -0.377007410216418260f, 0.925920808671770070f, + -0.377717693613385640f, + 0.925630830509872720f, -0.378427754808765560f, 0.925340307823206310f, + -0.379137593384847320f, + 0.925049240782677580f, -0.379847208924051160f, 0.924757629559513910f, + -0.380556601008928520f, + 0.924465474325262600f, -0.381265769222162380f, 0.924172775251791200f, + -0.381974713146567220f, + 0.923879532511286740f, -0.382683432365089780f, 0.923585746276256670f, + -0.383391926460808660f, + 0.923291416719527640f, -0.384100195016935040f, 0.922996544014246250f, + -0.384808237616812880f, + 0.922701128333878630f, -0.385516053843918850f, 0.922405169852209880f, + -0.386223643281862980f, + 0.922108668743345180f, -0.386931005514388580f, 0.921811625181708120f, + -0.387638140125372730f, + 0.921514039342042010f, -0.388345046698826250f, 0.921215911399408730f, + -0.389051724818894380f, + 0.920917241529189520f, -0.389758174069856410f, 0.920618029907083970f, + -0.390464394036126590f, + 0.920318276709110590f, -0.391170384302253870f, 0.920017982111606570f, + -0.391876144452922350f, + 0.919717146291227360f, -0.392581674072951470f, 0.919415769424947070f, + -0.393286972747296400f, + 0.919113851690057770f, -0.393992040061048100f, 0.918811393264170050f, + -0.394696875599433560f, + 0.918508394325212250f, -0.395401478947816350f, 0.918204855051430900f, + -0.396105849691696270f, + 0.917900775621390500f, -0.396809987416710310f, 0.917596156213972950f, + -0.397513891708632330f, + 0.917290997008377910f, -0.398217562153373560f, 0.916985298184123000f, + -0.398920998336982910f, + 0.916679059921042700f, -0.399624199845646790f, 0.916372282399289140f, + -0.400327166265690090f, + 0.916064965799331720f, -0.401029897183575620f, 0.915757110301956720f, + -0.401732392185905010f, + 0.915448716088267830f, -0.402434650859418430f, 0.915139783339685260f, + -0.403136672790995300f, + 0.914830312237946200f, -0.403838457567654070f, 0.914520302965104450f, + -0.404540004776553000f, + 0.914209755703530690f, -0.405241314004989860f, 0.913898670635911680f, + -0.405942384840402510f, + 0.913587047945250810f, -0.406643216870369030f, 0.913274887814867760f, + -0.407343809682607970f, + 0.912962190428398210f, -0.408044162864978690f, 0.912648955969793900f, + -0.408744276005481360f, + 0.912335184623322750f, -0.409444148692257590f, 0.912020876573568340f, + -0.410143780513590240f, + 0.911706032005429880f, -0.410843171057903910f, 0.911390651104122430f, + -0.411542319913765220f, + 0.911074734055176360f, -0.412241226669882890f, 0.910758281044437570f, + -0.412939890915108080f, + 0.910441292258067250f, -0.413638312238434500f, 0.910123767882541680f, + -0.414336490228999100f, + 0.909805708104652220f, -0.415034424476081630f, 0.909487113111505430f, + -0.415732114569105360f, + 0.909167983090522380f, -0.416429560097637150f, 0.908848318229439120f, + -0.417126760651387870f, + 0.908528118716306120f, -0.417823715820212270f, 0.908207384739488700f, + -0.418520425194109700f, + 0.907886116487666260f, -0.419216888363223910f, 0.907564314149832630f, + -0.419913104917843620f, + 0.907241977915295820f, -0.420609074448402510f, 0.906919107973678140f, + -0.421304796545479640f, + 0.906595704514915330f, -0.422000270799799680f, 0.906271767729257660f, + -0.422695496802232950f, + 0.905947297807268460f, -0.423390474143796050f, 0.905622294939825270f, + -0.424085202415651560f, + 0.905296759318118820f, -0.424779681209108810f, 0.904970691133653250f, + -0.425473910115623800f, + 0.904644090578246240f, -0.426167888726799620f, 0.904316957844028320f, + -0.426861616634386430f, + 0.903989293123443340f, -0.427555093430282080f, 0.903661096609247980f, + -0.428248318706531960f, + 0.903332368494511820f, -0.428941292055329490f, 0.903003108972617150f, + -0.429634013069016380f, + 0.902673318237258830f, -0.430326481340082610f, 0.902342996482444200f, + -0.431018696461167030f, + 0.902012143902493180f, -0.431710658025057260f, 0.901680760692037730f, + -0.432402365624690140f, + 0.901348847046022030f, -0.433093818853151960f, 0.901016403159702330f, + -0.433785017303678520f, + 0.900683429228646970f, -0.434475960569655650f, 0.900349925448735600f, + -0.435166648244619260f, + 0.900015892016160280f, -0.435857079922255470f, 0.899681329127423930f, + -0.436547255196401200f, + 0.899346236979341570f, -0.437237173661044090f, 0.899010615769039070f, + -0.437926834910322860f, + 0.898674465693953820f, -0.438616238538527660f, 0.898337786951834310f, + -0.439305384140099950f, + 0.898000579740739880f, -0.439994271309633260f, 0.897662844259040860f, + -0.440682899641872900f, + 0.897324580705418320f, -0.441371268731716670f, 0.896985789278863970f, + -0.442059378174214700f, + 0.896646470178680150f, -0.442747227564570020f, 0.896306623604479550f, + -0.443434816498138480f, + 0.895966249756185220f, -0.444122144570429200f, 0.895625348834030110f, + -0.444809211377104880f, + 0.895283921038557580f, -0.445496016513981740f, 0.894941966570620750f, + -0.446182559577030070f, + 0.894599485631382700f, -0.446868840162374160f, 0.894256478422316040f, + -0.447554857866293010f, + 0.893912945145203250f, -0.448240612285219890f, 0.893568886002135910f, + -0.448926103015743260f, + 0.893224301195515320f, -0.449611329654606540f, 0.892879190928051680f, + -0.450296291798708610f, + 0.892533555402764580f, -0.450980989045103860f, 0.892187394822982480f, + -0.451665420991002490f, + 0.891840709392342720f, -0.452349587233770890f, 0.891493499314791380f, + -0.453033487370931580f, + 0.891145764794583180f, -0.453717121000163870f, 0.890797506036281490f, + -0.454400487719303580f, + 0.890448723244757880f, -0.455083587126343840f, 0.890099416625192320f, + -0.455766418819434640f, + 0.889749586383072780f, -0.456448982396883920f, 0.889399232724195520f, + -0.457131277457156980f, + 0.889048355854664570f, -0.457813303598877170f, 0.888696955980891600f, + -0.458495060420826270f, + 0.888345033309596350f, -0.459176547521944090f, 0.887992588047805560f, + -0.459857764501329540f, + 0.887639620402853930f, -0.460538710958240010f, 0.887286130582383150f, + -0.461219386492092380f, + 0.886932118794342190f, -0.461899790702462730f, 0.886577585246987040f, + -0.462579923189086810f, + 0.886222530148880640f, -0.463259783551860150f, 0.885866953708892790f, + -0.463939371390838520f, + 0.885510856136199950f, -0.464618686306237820f, 0.885154237640285110f, + -0.465297727898434600f, + 0.884797098430937790f, -0.465976495767966180f, 0.884439438718253810f, + -0.466654989515530920f, + 0.884081258712634990f, -0.467333208741988420f, 0.883722558624789660f, + -0.468011153048359830f, + 0.883363338665731580f, -0.468688822035827900f, 0.883003599046780830f, + -0.469366215305737520f, + 0.882643339979562790f, -0.470043332459595620f, 0.882282561676008710f, + -0.470720173099071600f, + 0.881921264348355050f, -0.471396736825997640f, 0.881559448209143780f, + -0.472073023242368660f, + 0.881197113471222090f, -0.472749031950342790f, 0.880834260347742040f, + -0.473424762552241530f, + 0.880470889052160750f, -0.474100214650549970f, 0.880106999798240360f, + -0.474775387847917120f, + 0.879742592800047410f, -0.475450281747155870f, 0.879377668271953290f, + -0.476124895951243580f, + 0.879012226428633530f, -0.476799230063322090f, 0.878646267485068130f, + -0.477473283686698060f, + 0.878279791656541580f, -0.478147056424843010f, 0.877912799158641840f, + -0.478820547881393890f, + 0.877545290207261350f, -0.479493757660153010f, 0.877177265018595940f, + -0.480166685365088390f, + 0.876808723809145650f, -0.480839330600333960f, 0.876439666795713610f, + -0.481511692970189860f, + 0.876070094195406600f, -0.482183772079122720f, 0.875700006225634600f, + -0.482855567531765670f, + 0.875329403104110890f, -0.483527078932918740f, 0.874958285048851650f, + -0.484198305887549030f, + 0.874586652278176110f, -0.484869248000791060f, 0.874214505010706300f, + -0.485539904877946960f, + 0.873841843465366860f, -0.486210276124486420f, 0.873468667861384880f, + -0.486880361346047340f, + 0.873094978418290090f, -0.487550160148436000f, 0.872720775355914300f, + -0.488219672137626790f, + 0.872346058894391540f, -0.488888896919763170f, 0.871970829254157810f, + -0.489557834101157440f, + 0.871595086655950980f, -0.490226483288291160f, 0.871218831320811020f, + -0.490894844087815090f, + 0.870842063470078980f, -0.491562916106549900f, 0.870464783325397670f, + -0.492230698951486020f, + 0.870086991108711460f, -0.492898192229784040f, 0.869708687042265670f, + -0.493565395548774770f, + 0.869329871348606840f, -0.494232308515959670f, 0.868950544250582380f, + -0.494898930739011260f, + 0.868570705971340900f, -0.495565261825772540f, 0.868190356734331310f, + -0.496231301384258250f, + 0.867809496763303320f, -0.496897049022654470f, 0.867428126282306920f, + -0.497562504349319150f, + 0.867046245515692650f, -0.498227666972781870f, 0.866663854688111130f, + -0.498892536501744590f, + 0.866280954024512990f, -0.499557112545081840f, 0.865897543750148820f, + -0.500221394711840680f, + 0.865513624090569090f, -0.500885382611240710f, 0.865129195271623800f, + -0.501549075852675390f, + 0.864744257519462380f, -0.502212474045710790f, 0.864358811060534030f, + -0.502875576800086990f, + 0.863972856121586810f, -0.503538383725717580f, 0.863586392929668100f, + -0.504200894432690340f, + 0.863199421712124160f, -0.504863108531267590f, 0.862811942696600330f, + -0.505525025631885390f, + 0.862423956111040610f, -0.506186645345155230f, 0.862035462183687210f, + -0.506847967281863210f, + 0.861646461143081300f, -0.507508991052970870f, 0.861256953218062170f, + -0.508169716269614600f, + 0.860866938637767310f, -0.508830142543106990f, 0.860476417631632070f, + -0.509490269484936360f, + 0.860085390429390140f, -0.510150096706766810f, 0.859693857261072610f, + -0.510809623820439040f, + 0.859301818357008470f, -0.511468850437970300f, 0.858909273947823900f, + -0.512127776171554690f, + 0.858516224264442740f, -0.512786400633562960f, 0.858122669538086140f, + -0.513444723436543460f, + 0.857728610000272120f, -0.514102744193221660f, 0.857334045882815590f, + -0.514760462516501200f, + 0.856938977417828760f, -0.515417878019462930f, 0.856543404837719960f, + -0.516074990315366630f, + 0.856147328375194470f, -0.516731799017649870f, 0.855750748263253920f, + -0.517388303739929060f, + 0.855353664735196030f, -0.518044504095999340f, 0.854956078024614930f, + -0.518700399699834950f, + 0.854557988365400530f, -0.519355990165589640f, 0.854159395991738850f, + -0.520011275107596040f, + 0.853760301138111410f, -0.520666254140367160f, 0.853360704039295430f, + -0.521320926878595660f, + 0.852960604930363630f, -0.521975292937154390f, 0.852560004046684080f, + -0.522629351931096610f, + 0.852158901623919830f, -0.523283103475656430f, 0.851757297898029120f, + -0.523936547186248600f, + 0.851355193105265200f, -0.524589682678468950f, 0.850952587482175730f, + -0.525242509568094710f, + 0.850549481265603480f, -0.525895027471084630f, 0.850145874692685210f, + -0.526547236003579440f, + 0.849741768000852550f, -0.527199134781901280f, 0.849337161427830780f, + -0.527850723422555230f, + 0.848932055211639610f, -0.528502001542228480f, 0.848526449590592650f, + -0.529152968757790610f, + 0.848120344803297230f, -0.529803624686294610f, 0.847713741088654380f, + -0.530453968944976320f, + 0.847306638685858320f, -0.531104001151255000f, 0.846899037834397240f, + -0.531753720922733320f, + 0.846490938774052130f, -0.532403127877197900f, 0.846082341744897050f, + -0.533052221632619450f, + 0.845673246987299070f, -0.533701001807152960f, 0.845263654741918220f, + -0.534349468019137520f, + 0.844853565249707120f, -0.534997619887097150f, 0.844442978751910660f, + -0.535645457029741090f, + 0.844031895490066410f, -0.536292979065963180f, 0.843620315706004150f, + -0.536940185614842910f, + 0.843208239641845440f, -0.537587076295645390f, 0.842795667540004120f, + -0.538233650727821700f, + 0.842382599643185850f, -0.538879908531008420f, 0.841969036194387680f, + -0.539525849325028890f, + 0.841554977436898440f, -0.540171472729892850f, 0.841140423614298080f, + -0.540816778365796670f, + 0.840725374970458070f, -0.541461765853123440f, 0.840309831749540770f, + -0.542106434812443920f, + 0.839893794195999520f, -0.542750784864515890f, 0.839477262554578550f, + -0.543394815630284800f, + 0.839060237070312740f, -0.544038526730883820f, 0.838642717988527300f, + -0.544681917787634530f, + 0.838224705554838080f, -0.545324988422046460f, 0.837806200015150940f, + -0.545967738255817570f, + 0.837387201615661940f, -0.546610166910834860f, 0.836967710602857020f, + -0.547252274009174090f, + 0.836547727223512010f, -0.547894059173100190f, 0.836127251724692270f, + -0.548535522025067390f, + 0.835706284353752600f, -0.549176662187719660f, 0.835284825358337370f, + -0.549817479283890910f, + 0.834862874986380010f, -0.550457972936604810f, 0.834440433486103190f, + -0.551098142769075430f, + 0.834017501106018130f, -0.551737988404707340f, 0.833594078094925140f, + -0.552377509467096070f, + 0.833170164701913190f, -0.553016705580027470f, 0.832745761176359460f, + -0.553655576367479310f, + 0.832320867767929680f, -0.554294121453620000f, 0.831895484726577590f, + -0.554932340462810370f, + 0.831469612302545240f, -0.555570233019602180f, 0.831043250746362320f, + -0.556207798748739930f, + 0.830616400308846310f, -0.556845037275160100f, 0.830189061241102370f, + -0.557481948223991550f, + 0.829761233794523050f, -0.558118531220556100f, 0.829332918220788250f, + -0.558754785890368310f, + 0.828904114771864870f, -0.559390711859136140f, 0.828474823700007130f, + -0.560026308752760380f, + 0.828045045257755800f, -0.560661576197336030f, 0.827614779697938400f, + -0.561296513819151470f, + 0.827184027273669130f, -0.561931121244689470f, 0.826752788238348520f, + -0.562565398100626560f, + 0.826321062845663530f, -0.563199344013834090f, 0.825888851349586780f, + -0.563832958611378170f, + 0.825456154004377550f, -0.564466241520519500f, 0.825022971064580220f, + -0.565099192368713980f, + 0.824589302785025290f, -0.565731810783613120f, 0.824155149420828570f, + -0.566364096393063840f, + 0.823720511227391430f, -0.566996048825108680f, 0.823285388460400110f, + -0.567627667707986230f, + 0.822849781375826430f, -0.568258952670131490f, 0.822413690229926390f, + -0.568889903340175860f, + 0.821977115279241550f, -0.569520519346947140f, 0.821540056780597610f, + -0.570150800319470300f, + 0.821102514991104650f, -0.570780745886967260f, 0.820664490168157460f, + -0.571410355678857230f, + 0.820225982569434690f, -0.572039629324757050f, 0.819786992452898990f, + -0.572668566454481160f, + 0.819347520076796900f, -0.573297166698042200f, 0.818907565699658950f, + -0.573925429685650750f, + 0.818467129580298660f, -0.574553355047715760f, 0.818026211977813440f, + -0.575180942414845080f, + 0.817584813151583710f, -0.575808191417845340f, 0.817142933361272970f, + -0.576435101687721830f, + 0.816700572866827850f, -0.577061672855679440f, 0.816257731928477390f, + -0.577687904553122800f, + 0.815814410806733780f, -0.578313796411655590f, 0.815370609762391290f, + -0.578939348063081780f, + 0.814926329056526620f, -0.579564559139405630f, 0.814481568950498610f, + -0.580189429272831680f, + 0.814036329705948410f, -0.580813958095764530f, 0.813590611584798510f, + -0.581438145240810170f, + 0.813144414849253590f, -0.582061990340775440f, 0.812697739761799490f, + -0.582685493028668460f, + 0.812250586585203880f, -0.583308652937698290f, 0.811802955582515470f, + -0.583931469701276180f, + 0.811354847017063730f, -0.584553942953015330f, 0.810906261152459670f, + -0.585176072326730410f, + 0.810457198252594770f, -0.585797857456438860f, 0.810007658581641140f, + -0.586419297976360500f, + 0.809557642404051260f, -0.587040393520917970f, 0.809107149984558240f, + -0.587661143724736660f, + 0.808656181588174980f, -0.588281548222645220f, 0.808204737480194720f, + -0.588901606649675720f, + 0.807752817926190360f, -0.589521318641063940f, 0.807300423192014450f, + -0.590140683832248820f, + 0.806847553543799330f, -0.590759701858874160f, 0.806394209247956240f, + -0.591378372356787580f, + 0.805940390571176280f, -0.591996694962040990f, 0.805486097780429230f, + -0.592614669310891130f, + 0.805031331142963660f, -0.593232295039799800f, 0.804576090926307110f, + -0.593849571785433630f, + 0.804120377398265810f, -0.594466499184664430f, 0.803664190826924090f, + -0.595083076874569960f, + 0.803207531480644940f, -0.595699304492433360f, 0.802750399628069160f, + -0.596315181675743710f, + 0.802292795538115720f, -0.596930708062196500f, 0.801834719479981310f, + -0.597545883289693160f, + 0.801376171723140240f, -0.598160706996342270f, 0.800917152537344300f, + -0.598775178820458720f, + 0.800457662192622820f, -0.599389298400564540f, 0.799997700959281910f, + -0.600003065375388940f, + 0.799537269107905010f, -0.600616479383868970f, 0.799076366909352350f, + -0.601229540065148500f, + 0.798614994634760820f, -0.601842247058580030f, 0.798153152555543750f, + -0.602454600003723750f, + 0.797690840943391160f, -0.603066598540348160f, 0.797228060070268810f, + -0.603678242308430370f, + 0.796764810208418830f, -0.604289530948155960f, 0.796301091630359110f, + -0.604900464099919820f, + 0.795836904608883570f, -0.605511041404325550f, 0.795372249417061310f, + -0.606121262502186120f, + 0.794907126328237010f, -0.606731127034524480f, 0.794441535616030590f, + -0.607340634642572930f, + 0.793975477554337170f, -0.607949784967773630f, 0.793508952417326660f, + -0.608558577651779450f, + 0.793041960479443640f, -0.609167012336453210f, 0.792574502015407690f, + -0.609775088663868430f, + 0.792106577300212390f, -0.610382806276309480f, 0.791638186609125880f, + -0.610990164816271660f, + 0.791169330217690200f, -0.611597163926461910f, 0.790700008401721610f, + -0.612203803249797950f, + 0.790230221437310030f, -0.612810082429409710f, 0.789759969600819070f, + -0.613416001108638590f, + 0.789289253168885650f, -0.614021558931038380f, 0.788818072418420280f, + -0.614626755540375050f, + 0.788346427626606340f, -0.615231590580626820f, 0.787874319070900220f, + -0.615836063695985090f, + 0.787401747029031430f, -0.616440174530853650f, 0.786928711779001810f, + -0.617043922729849760f, + 0.786455213599085770f, -0.617647307937803870f, 0.785981252767830150f, + -0.618250329799760250f, + 0.785506829564053930f, -0.618852987960976320f, 0.785031944266848080f, + -0.619455282066924020f, + 0.784556597155575240f, -0.620057211763289100f, 0.784080788509869950f, + -0.620658776695972140f, + 0.783604518609638200f, -0.621259976511087550f, 0.783127787735057310f, + -0.621860810854965360f, + 0.782650596166575730f, -0.622461279374149970f, 0.782172944184913010f, + -0.623061381715401260f, + 0.781694832071059390f, -0.623661117525694530f, 0.781216260106276090f, + -0.624260486452220650f, + 0.780737228572094490f, -0.624859488142386340f, 0.780257737750316590f, + -0.625458122243814360f, + 0.779777787923014550f, -0.626056388404343520f, 0.779297379372530300f, + -0.626654286272029350f, + 0.778816512381475980f, -0.627251815495144080f, 0.778335187232733210f, + -0.627848975722176460f, + 0.777853404209453150f, -0.628445766601832710f, 0.777371163595056310f, + -0.629042187783036000f, + 0.776888465673232440f, -0.629638238914926980f, 0.776405310727940390f, + -0.630233919646864370f, + 0.775921699043407690f, -0.630829229628424470f, 0.775437630904130540f, + -0.631424168509401860f, + 0.774953106594873930f, -0.632018735939809060f, 0.774468126400670860f, + -0.632612931569877410f, + 0.773982690606822900f, -0.633206755050057190f, 0.773496799498899050f, + -0.633800206031017280f, + 0.773010453362736990f, -0.634393284163645490f, 0.772523652484441330f, + -0.634985989099049460f, + 0.772036397150384520f, -0.635578320488556110f, 0.771548687647206300f, + -0.636170277983712170f, + 0.771060524261813820f, -0.636761861236284200f, 0.770571907281380810f, + -0.637353069898259130f, + 0.770082836993347900f, -0.637943903621844060f, 0.769593313685422940f, + -0.638534362059466790f, + 0.769103337645579700f, -0.639124444863775730f, 0.768612909162058380f, + -0.639714151687640450f, + 0.768122028523365420f, -0.640303482184151670f, 0.767630696018273380f, + -0.640892436006621380f, + 0.767138911935820400f, -0.641481012808583160f, 0.766646676565310380f, + -0.642069212243792540f, + 0.766153990196312920f, -0.642657033966226860f, 0.765660853118662500f, + -0.643244477630085850f, + 0.765167265622458960f, -0.643831542889791390f, 0.764673227998067140f, + -0.644418229399988380f, + 0.764178740536116670f, -0.645004536815543930f, 0.763683803527501870f, + -0.645590464791548690f, + 0.763188417263381270f, -0.646176012983316280f, 0.762692582035177980f, + -0.646761181046383920f, + 0.762196298134578900f, -0.647345968636512060f, 0.761699565853535380f, + -0.647930375409685340f, + 0.761202385484261780f, -0.648514401022112440f, 0.760704757319236920f, + -0.649098045130225950f, + 0.760206681651202420f, -0.649681307390683190f, 0.759708158773163440f, + -0.650264187460365850f, + 0.759209188978388070f, -0.650846684996380880f, 0.758709772560407390f, + -0.651428799656059820f, + 0.758209909813015280f, -0.652010531096959500f, 0.757709601030268080f, + -0.652591878976862440f, + 0.757208846506484570f, -0.653172842953776760f, 0.756707646536245670f, + -0.653753422685936060f, + 0.756206001414394540f, -0.654333617831800440f, 0.755703911436035880f, + -0.654913428050056030f, + 0.755201376896536550f, -0.655492852999615350f, 0.754698398091524500f, + -0.656071892339617600f, + 0.754194975316889170f, -0.656650545729428940f, 0.753691108868781210f, + -0.657228812828642540f, + 0.753186799043612520f, -0.657806693297078640f, 0.752682046138055340f, + -0.658384186794785050f, + 0.752176850449042810f, -0.658961292982037320f, 0.751671212273768430f, + -0.659538011519338660f, + 0.751165131909686480f, -0.660114342067420480f, 0.750658609654510700f, + -0.660690284287242300f, + 0.750151645806215070f, -0.661265837839992270f, 0.749644240663033480f, + -0.661841002387086870f, + 0.749136394523459370f, -0.662415777590171780f, 0.748628107686245440f, + -0.662990163111121470f, + 0.748119380450403600f, -0.663564158612039770f, 0.747610213115205150f, + -0.664137763755260010f, + 0.747100605980180130f, -0.664710978203344790f, 0.746590559345117310f, + -0.665283801619087180f, + 0.746080073510063780f, -0.665856233665509720f, 0.745569148775325430f, + -0.666428274005865240f, + 0.745057785441466060f, -0.666999922303637470f, 0.744545983809307370f, + -0.667571178222540310f, + 0.744033744179929290f, -0.668142041426518450f, 0.743521066854669120f, + -0.668712511579747980f, + 0.743007952135121720f, -0.669282588346636010f, 0.742494400323139180f, + -0.669852271391821020f, + 0.741980411720831070f, -0.670421560380173090f, 0.741465986630563290f, + -0.670990454976794220f, + 0.740951125354959110f, -0.671558954847018330f, 0.740435828196898020f, + -0.672127059656411730f, + 0.739920095459516200f, -0.672694769070772860f, 0.739403927446205760f, + -0.673262082756132970f, + 0.738887324460615110f, -0.673829000378756040f, 0.738370286806648620f, + -0.674395521605139050f, + 0.737852814788465980f, -0.674961646102011930f, 0.737334908710482910f, + -0.675527373536338520f, + 0.736816568877369900f, -0.676092703575315920f, 0.736297795594053170f, + -0.676657635886374950f, + 0.735778589165713590f, -0.677222170137180330f, 0.735258949897786840f, + -0.677786305995631500f, + 0.734738878095963500f, -0.678350043129861470f, 0.734218374066188280f, + -0.678913381208238410f, + 0.733697438114660370f, -0.679476319899364970f, 0.733176070547832740f, + -0.680038858872078930f, + 0.732654271672412820f, -0.680600997795453020f, 0.732132041795361290f, + -0.681162736338795430f, + 0.731609381223892630f, -0.681724074171649710f, 0.731086290265474340f, + -0.682285010963795570f, + 0.730562769227827590f, -0.682845546385248080f, 0.730038818418926260f, + -0.683405680106258680f, + 0.729514438146997010f, -0.683965411797315400f, 0.728989628720519420f, + -0.684524741129142300f, + 0.728464390448225200f, -0.685083667772700360f, 0.727938723639098620f, + -0.685642191399187470f, + 0.727412628602375770f, -0.686200311680038590f, 0.726886105647544970f, + -0.686758028286925890f, + 0.726359155084346010f, -0.687315340891759050f, 0.725831777222770370f, + -0.687872249166685550f, + 0.725303972373060770f, -0.688428752784090440f, 0.724775740845711280f, + -0.688984851416597040f, + 0.724247082951467000f, -0.689540544737066830f, 0.723717999001323500f, + -0.690095832418599950f, + 0.723188489306527460f, -0.690650714134534600f, 0.722658554178575610f, + -0.691205189558448450f, + 0.722128193929215350f, -0.691759258364157750f, 0.721597408870443770f, + -0.692312920225718220f, + 0.721066199314508110f, -0.692866174817424630f, 0.720534565573905270f, + -0.693419021813811760f, + 0.720002507961381650f, -0.693971460889654000f, 0.719470026789932990f, + -0.694523491719965520f, + 0.718937122372804490f, -0.695075113980000880f, 0.718403795023489830f, + -0.695626327345254870f, + 0.717870045055731710f, -0.696177131491462990f, 0.717335872783521730f, + -0.696727526094601200f, + 0.716801278521099540f, -0.697277510830886520f, 0.716266262582953120f, + -0.697827085376777290f, + 0.715730825283818590f, -0.698376249408972920f, 0.715194966938680120f, + -0.698925002604414150f, + 0.714658687862769090f, -0.699473344640283770f, 0.714121988371564820f, + -0.700021275194006250f, + 0.713584868780793640f, -0.700568793943248340f, 0.713047329406429340f, + -0.701115900565918660f, + 0.712509370564692320f, -0.701662594740168450f, 0.711970992572050100f, + -0.702208876144391870f, + 0.711432195745216430f, -0.702754744457225300f, 0.710892980401151680f, + -0.703300199357548730f, + 0.710353346857062420f, -0.703845240524484940f, 0.709813295430400840f, + -0.704389867637400410f, + 0.709272826438865690f, -0.704934080375904880f, 0.708731940200400650f, + -0.705477878419852100f, + 0.708190637033195400f, -0.706021261449339740f, 0.707648917255684350f, + -0.706564229144709510f, + 0.707106781186547570f, -0.707106781186547460f, 0.706564229144709620f, + -0.707648917255684350f, + 0.706021261449339740f, -0.708190637033195290f, 0.705477878419852210f, + -0.708731940200400650f, + 0.704934080375904990f, -0.709272826438865580f, 0.704389867637400410f, + -0.709813295430400840f, + 0.703845240524484940f, -0.710353346857062310f, 0.703300199357548730f, + -0.710892980401151680f, + 0.702754744457225300f, -0.711432195745216430f, 0.702208876144391870f, + -0.711970992572049990f, + 0.701662594740168570f, -0.712509370564692320f, 0.701115900565918660f, + -0.713047329406429230f, + 0.700568793943248450f, -0.713584868780793520f, 0.700021275194006360f, + -0.714121988371564710f, + 0.699473344640283770f, -0.714658687862768980f, 0.698925002604414150f, + -0.715194966938680010f, + 0.698376249408972920f, -0.715730825283818590f, 0.697827085376777290f, + -0.716266262582953120f, + 0.697277510830886630f, -0.716801278521099540f, 0.696727526094601200f, + -0.717335872783521730f, + 0.696177131491462990f, -0.717870045055731710f, 0.695626327345254870f, + -0.718403795023489720f, + 0.695075113980000880f, -0.718937122372804380f, 0.694523491719965520f, + -0.719470026789932990f, + 0.693971460889654000f, -0.720002507961381650f, 0.693419021813811880f, + -0.720534565573905270f, + 0.692866174817424740f, -0.721066199314508110f, 0.692312920225718220f, + -0.721597408870443660f, + 0.691759258364157750f, -0.722128193929215350f, 0.691205189558448450f, + -0.722658554178575610f, + 0.690650714134534720f, -0.723188489306527350f, 0.690095832418599950f, + -0.723717999001323390f, + 0.689540544737066940f, -0.724247082951466890f, 0.688984851416597150f, + -0.724775740845711280f, + 0.688428752784090550f, -0.725303972373060660f, 0.687872249166685550f, + -0.725831777222770370f, + 0.687315340891759160f, -0.726359155084346010f, 0.686758028286925890f, + -0.726886105647544970f, + 0.686200311680038700f, -0.727412628602375770f, 0.685642191399187470f, + -0.727938723639098620f, + 0.685083667772700360f, -0.728464390448225200f, 0.684524741129142300f, + -0.728989628720519310f, + 0.683965411797315510f, -0.729514438146996900f, 0.683405680106258790f, + -0.730038818418926150f, + 0.682845546385248080f, -0.730562769227827590f, 0.682285010963795570f, + -0.731086290265474230f, + 0.681724074171649820f, -0.731609381223892520f, 0.681162736338795430f, + -0.732132041795361290f, + 0.680600997795453130f, -0.732654271672412820f, 0.680038858872079040f, + -0.733176070547832740f, + 0.679476319899365080f, -0.733697438114660260f, 0.678913381208238410f, + -0.734218374066188170f, + 0.678350043129861580f, -0.734738878095963390f, 0.677786305995631500f, + -0.735258949897786730f, + 0.677222170137180450f, -0.735778589165713480f, 0.676657635886374950f, + -0.736297795594053060f, + 0.676092703575316030f, -0.736816568877369790f, 0.675527373536338630f, + -0.737334908710482790f, + 0.674961646102012040f, -0.737852814788465980f, 0.674395521605139050f, + -0.738370286806648510f, + 0.673829000378756150f, -0.738887324460615110f, 0.673262082756132970f, + -0.739403927446205760f, + 0.672694769070772970f, -0.739920095459516090f, 0.672127059656411840f, + -0.740435828196898020f, + 0.671558954847018330f, -0.740951125354959110f, 0.670990454976794220f, + -0.741465986630563290f, + 0.670421560380173090f, -0.741980411720830960f, 0.669852271391821130f, + -0.742494400323139180f, + 0.669282588346636010f, -0.743007952135121720f, 0.668712511579748090f, + -0.743521066854669120f, + 0.668142041426518560f, -0.744033744179929180f, 0.667571178222540310f, + -0.744545983809307250f, + 0.666999922303637470f, -0.745057785441465950f, 0.666428274005865350f, + -0.745569148775325430f, + 0.665856233665509720f, -0.746080073510063780f, 0.665283801619087180f, + -0.746590559345117310f, + 0.664710978203344900f, -0.747100605980180130f, 0.664137763755260010f, + -0.747610213115205150f, + 0.663564158612039880f, -0.748119380450403490f, 0.662990163111121470f, + -0.748628107686245330f, + 0.662415777590171780f, -0.749136394523459260f, 0.661841002387086870f, + -0.749644240663033480f, + 0.661265837839992270f, -0.750151645806214960f, 0.660690284287242300f, + -0.750658609654510590f, + 0.660114342067420480f, -0.751165131909686370f, 0.659538011519338770f, + -0.751671212273768430f, + 0.658961292982037320f, -0.752176850449042700f, 0.658384186794785050f, + -0.752682046138055230f, + 0.657806693297078640f, -0.753186799043612410f, 0.657228812828642650f, + -0.753691108868781210f, + 0.656650545729429050f, -0.754194975316889170f, 0.656071892339617710f, + -0.754698398091524390f, + 0.655492852999615460f, -0.755201376896536550f, 0.654913428050056150f, + -0.755703911436035880f, + 0.654333617831800550f, -0.756206001414394540f, 0.653753422685936170f, + -0.756707646536245670f, + 0.653172842953776760f, -0.757208846506484460f, 0.652591878976862550f, + -0.757709601030268080f, + 0.652010531096959500f, -0.758209909813015280f, 0.651428799656059820f, + -0.758709772560407390f, + 0.650846684996380990f, -0.759209188978387960f, 0.650264187460365960f, + -0.759708158773163440f, + 0.649681307390683190f, -0.760206681651202420f, 0.649098045130226060f, + -0.760704757319236920f, + 0.648514401022112550f, -0.761202385484261780f, 0.647930375409685460f, + -0.761699565853535270f, + 0.647345968636512060f, -0.762196298134578900f, 0.646761181046383920f, + -0.762692582035177870f, + 0.646176012983316390f, -0.763188417263381270f, 0.645590464791548800f, + -0.763683803527501870f, + 0.645004536815544040f, -0.764178740536116670f, 0.644418229399988380f, + -0.764673227998067140f, + 0.643831542889791500f, -0.765167265622458960f, 0.643244477630085850f, + -0.765660853118662390f, + 0.642657033966226860f, -0.766153990196312810f, 0.642069212243792540f, + -0.766646676565310380f, + 0.641481012808583160f, -0.767138911935820400f, 0.640892436006621380f, + -0.767630696018273270f, + 0.640303482184151670f, -0.768122028523365310f, 0.639714151687640450f, + -0.768612909162058270f, + 0.639124444863775730f, -0.769103337645579590f, 0.638534362059466790f, + -0.769593313685422940f, + 0.637943903621844170f, -0.770082836993347900f, 0.637353069898259130f, + -0.770571907281380700f, + 0.636761861236284200f, -0.771060524261813710f, 0.636170277983712170f, + -0.771548687647206300f, + 0.635578320488556230f, -0.772036397150384410f, 0.634985989099049460f, + -0.772523652484441330f, + 0.634393284163645490f, -0.773010453362736990f, 0.633800206031017280f, + -0.773496799498899050f, + 0.633206755050057190f, -0.773982690606822790f, 0.632612931569877520f, + -0.774468126400670860f, + 0.632018735939809060f, -0.774953106594873820f, 0.631424168509401860f, + -0.775437630904130430f, + 0.630829229628424470f, -0.775921699043407580f, 0.630233919646864480f, + -0.776405310727940390f, + 0.629638238914927100f, -0.776888465673232440f, 0.629042187783036000f, + -0.777371163595056200f, + 0.628445766601832710f, -0.777853404209453040f, 0.627848975722176570f, + -0.778335187232733090f, + 0.627251815495144190f, -0.778816512381475870f, 0.626654286272029460f, + -0.779297379372530300f, + 0.626056388404343520f, -0.779777787923014440f, 0.625458122243814360f, + -0.780257737750316590f, + 0.624859488142386450f, -0.780737228572094380f, 0.624260486452220650f, + -0.781216260106276090f, + 0.623661117525694640f, -0.781694832071059390f, 0.623061381715401370f, + -0.782172944184912900f, + 0.622461279374150080f, -0.782650596166575730f, 0.621860810854965360f, + -0.783127787735057310f, + 0.621259976511087660f, -0.783604518609638200f, 0.620658776695972140f, + -0.784080788509869950f, + 0.620057211763289210f, -0.784556597155575240f, 0.619455282066924020f, + -0.785031944266848080f, + 0.618852987960976320f, -0.785506829564053930f, 0.618250329799760250f, + -0.785981252767830150f, + 0.617647307937803980f, -0.786455213599085770f, 0.617043922729849760f, + -0.786928711779001700f, + 0.616440174530853650f, -0.787401747029031320f, 0.615836063695985090f, + -0.787874319070900110f, + 0.615231590580626820f, -0.788346427626606230f, 0.614626755540375050f, + -0.788818072418420170f, + 0.614021558931038490f, -0.789289253168885650f, 0.613416001108638590f, + -0.789759969600819070f, + 0.612810082429409710f, -0.790230221437310030f, 0.612203803249798060f, + -0.790700008401721610f, + 0.611597163926462020f, -0.791169330217690090f, 0.610990164816271770f, + -0.791638186609125770f, + 0.610382806276309480f, -0.792106577300212390f, 0.609775088663868430f, + -0.792574502015407580f, + 0.609167012336453210f, -0.793041960479443640f, 0.608558577651779450f, + -0.793508952417326660f, + 0.607949784967773740f, -0.793975477554337170f, 0.607340634642572930f, + -0.794441535616030590f, + 0.606731127034524480f, -0.794907126328237010f, 0.606121262502186230f, + -0.795372249417061190f, + 0.605511041404325550f, -0.795836904608883460f, 0.604900464099919930f, + -0.796301091630359110f, + 0.604289530948156070f, -0.796764810208418720f, 0.603678242308430370f, + -0.797228060070268700f, + 0.603066598540348280f, -0.797690840943391040f, 0.602454600003723860f, + -0.798153152555543750f, + 0.601842247058580030f, -0.798614994634760820f, 0.601229540065148620f, + -0.799076366909352350f, + 0.600616479383868970f, -0.799537269107905010f, 0.600003065375389060f, + -0.799997700959281910f, + 0.599389298400564540f, -0.800457662192622710f, 0.598775178820458720f, + -0.800917152537344300f, + 0.598160706996342380f, -0.801376171723140130f, 0.597545883289693270f, + -0.801834719479981310f, + 0.596930708062196500f, -0.802292795538115720f, 0.596315181675743820f, + -0.802750399628069160f, + 0.595699304492433470f, -0.803207531480644830f, 0.595083076874569960f, + -0.803664190826924090f, + 0.594466499184664540f, -0.804120377398265700f, 0.593849571785433630f, + -0.804576090926307000f, + 0.593232295039799800f, -0.805031331142963660f, 0.592614669310891130f, + -0.805486097780429120f, + 0.591996694962040990f, -0.805940390571176280f, 0.591378372356787580f, + -0.806394209247956240f, + 0.590759701858874280f, -0.806847553543799220f, 0.590140683832248940f, + -0.807300423192014450f, + 0.589521318641063940f, -0.807752817926190360f, 0.588901606649675840f, + -0.808204737480194720f, + 0.588281548222645330f, -0.808656181588174980f, 0.587661143724736770f, + -0.809107149984558130f, + 0.587040393520918080f, -0.809557642404051260f, 0.586419297976360500f, + -0.810007658581641140f, + 0.585797857456438860f, -0.810457198252594770f, 0.585176072326730410f, + -0.810906261152459670f, + 0.584553942953015330f, -0.811354847017063730f, 0.583931469701276300f, + -0.811802955582515360f, + 0.583308652937698290f, -0.812250586585203880f, 0.582685493028668460f, + -0.812697739761799490f, + 0.582061990340775550f, -0.813144414849253590f, 0.581438145240810280f, + -0.813590611584798510f, + 0.580813958095764530f, -0.814036329705948300f, 0.580189429272831680f, + -0.814481568950498610f, + 0.579564559139405740f, -0.814926329056526620f, 0.578939348063081890f, + -0.815370609762391290f, + 0.578313796411655590f, -0.815814410806733780f, 0.577687904553122800f, + -0.816257731928477390f, + 0.577061672855679550f, -0.816700572866827850f, 0.576435101687721830f, + -0.817142933361272970f, + 0.575808191417845340f, -0.817584813151583710f, 0.575180942414845190f, + -0.818026211977813440f, + 0.574553355047715760f, -0.818467129580298660f, 0.573925429685650750f, + -0.818907565699658950f, + 0.573297166698042320f, -0.819347520076796900f, 0.572668566454481160f, + -0.819786992452898990f, + 0.572039629324757050f, -0.820225982569434690f, 0.571410355678857340f, + -0.820664490168157460f, + 0.570780745886967370f, -0.821102514991104650f, 0.570150800319470300f, + -0.821540056780597610f, + 0.569520519346947250f, -0.821977115279241550f, 0.568889903340175970f, + -0.822413690229926390f, + 0.568258952670131490f, -0.822849781375826320f, 0.567627667707986230f, + -0.823285388460400110f, + 0.566996048825108680f, -0.823720511227391320f, 0.566364096393063950f, + -0.824155149420828570f, + 0.565731810783613230f, -0.824589302785025290f, 0.565099192368714090f, + -0.825022971064580220f, + 0.564466241520519500f, -0.825456154004377440f, 0.563832958611378170f, + -0.825888851349586780f, + 0.563199344013834090f, -0.826321062845663420f, 0.562565398100626560f, + -0.826752788238348520f, + 0.561931121244689470f, -0.827184027273669020f, 0.561296513819151470f, + -0.827614779697938400f, + 0.560661576197336030f, -0.828045045257755800f, 0.560026308752760380f, + -0.828474823700007130f, + 0.559390711859136140f, -0.828904114771864870f, 0.558754785890368310f, + -0.829332918220788250f, + 0.558118531220556100f, -0.829761233794523050f, 0.557481948223991660f, + -0.830189061241102370f, + 0.556845037275160100f, -0.830616400308846200f, 0.556207798748739930f, + -0.831043250746362320f, + 0.555570233019602290f, -0.831469612302545240f, 0.554932340462810370f, + -0.831895484726577590f, + 0.554294121453620110f, -0.832320867767929680f, 0.553655576367479310f, + -0.832745761176359460f, + 0.553016705580027580f, -0.833170164701913190f, 0.552377509467096070f, + -0.833594078094925140f, + 0.551737988404707450f, -0.834017501106018130f, 0.551098142769075430f, + -0.834440433486103190f, + 0.550457972936604810f, -0.834862874986380010f, 0.549817479283891020f, + -0.835284825358337370f, + 0.549176662187719770f, -0.835706284353752600f, 0.548535522025067390f, + -0.836127251724692160f, + 0.547894059173100190f, -0.836547727223511890f, 0.547252274009174090f, + -0.836967710602857020f, + 0.546610166910834860f, -0.837387201615661940f, 0.545967738255817680f, + -0.837806200015150940f, + 0.545324988422046460f, -0.838224705554837970f, 0.544681917787634530f, + -0.838642717988527300f, + 0.544038526730883930f, -0.839060237070312630f, 0.543394815630284800f, + -0.839477262554578550f, + 0.542750784864516000f, -0.839893794195999410f, 0.542106434812444030f, + -0.840309831749540770f, + 0.541461765853123560f, -0.840725374970458070f, 0.540816778365796670f, + -0.841140423614298080f, + 0.540171472729892970f, -0.841554977436898330f, 0.539525849325029010f, + -0.841969036194387680f, + 0.538879908531008420f, -0.842382599643185960f, 0.538233650727821700f, + -0.842795667540004120f, + 0.537587076295645510f, -0.843208239641845440f, 0.536940185614843020f, + -0.843620315706004040f, + 0.536292979065963180f, -0.844031895490066410f, 0.535645457029741090f, + -0.844442978751910660f, + 0.534997619887097260f, -0.844853565249707010f, 0.534349468019137520f, + -0.845263654741918220f, + 0.533701001807152960f, -0.845673246987299070f, 0.533052221632619670f, + -0.846082341744896940f, + 0.532403127877198010f, -0.846490938774052020f, 0.531753720922733320f, + -0.846899037834397350f, + 0.531104001151255000f, -0.847306638685858320f, 0.530453968944976320f, + -0.847713741088654270f, + 0.529803624686294830f, -0.848120344803297120f, 0.529152968757790720f, + -0.848526449590592650f, + 0.528502001542228480f, -0.848932055211639610f, 0.527850723422555460f, + -0.849337161427830670f, + 0.527199134781901390f, -0.849741768000852440f, 0.526547236003579330f, + -0.850145874692685210f, + 0.525895027471084740f, -0.850549481265603370f, 0.525242509568094710f, + -0.850952587482175730f, + 0.524589682678468840f, -0.851355193105265200f, 0.523936547186248600f, + -0.851757297898029120f, + 0.523283103475656430f, -0.852158901623919830f, 0.522629351931096720f, + -0.852560004046683970f, + 0.521975292937154390f, -0.852960604930363630f, 0.521320926878595550f, + -0.853360704039295430f, + 0.520666254140367270f, -0.853760301138111300f, 0.520011275107596040f, + -0.854159395991738730f, + 0.519355990165589530f, -0.854557988365400530f, 0.518700399699835170f, + -0.854956078024614820f, + 0.518044504095999340f, -0.855353664735196030f, 0.517388303739929060f, + -0.855750748263253920f, + 0.516731799017649980f, -0.856147328375194470f, 0.516074990315366630f, + -0.856543404837719960f, + 0.515417878019463150f, -0.856938977417828650f, 0.514760462516501200f, + -0.857334045882815590f, + 0.514102744193221660f, -0.857728610000272120f, 0.513444723436543570f, + -0.858122669538086020f, + 0.512786400633563070f, -0.858516224264442740f, 0.512127776171554690f, + -0.858909273947823900f, + 0.511468850437970520f, -0.859301818357008360f, 0.510809623820439040f, + -0.859693857261072610f, + 0.510150096706766700f, -0.860085390429390140f, 0.509490269484936360f, + -0.860476417631632070f, + 0.508830142543106990f, -0.860866938637767310f, 0.508169716269614710f, + -0.861256953218062060f, + 0.507508991052970870f, -0.861646461143081300f, 0.506847967281863320f, + -0.862035462183687210f, + 0.506186645345155450f, -0.862423956111040500f, 0.505525025631885510f, + -0.862811942696600330f, + 0.504863108531267480f, -0.863199421712124160f, 0.504200894432690560f, + -0.863586392929667990f, + 0.503538383725717580f, -0.863972856121586700f, 0.502875576800086880f, + -0.864358811060534030f, + 0.502212474045710900f, -0.864744257519462380f, 0.501549075852675390f, + -0.865129195271623690f, + 0.500885382611240940f, -0.865513624090568980f, 0.500221394711840680f, + -0.865897543750148820f, + 0.499557112545081890f, -0.866280954024512990f, 0.498892536501744750f, + -0.866663854688111020f, + 0.498227666972781870f, -0.867046245515692650f, 0.497562504349319090f, + -0.867428126282306920f, + 0.496897049022654640f, -0.867809496763303210f, 0.496231301384258310f, + -0.868190356734331310f, + 0.495565261825772490f, -0.868570705971340900f, 0.494898930739011310f, + -0.868950544250582380f, + 0.494232308515959730f, -0.869329871348606730f, 0.493565395548774880f, + -0.869708687042265560f, + 0.492898192229784090f, -0.870086991108711350f, 0.492230698951486080f, + -0.870464783325397670f, + 0.491562916106550060f, -0.870842063470078860f, 0.490894844087815140f, + -0.871218831320810900f, + 0.490226483288291100f, -0.871595086655951090f, 0.489557834101157550f, + -0.871970829254157700f, + 0.488888896919763230f, -0.872346058894391540f, 0.488219672137626740f, + -0.872720775355914300f, + 0.487550160148436050f, -0.873094978418290090f, 0.486880361346047400f, + -0.873468667861384880f, + 0.486210276124486530f, -0.873841843465366750f, 0.485539904877947020f, + -0.874214505010706300f, + 0.484869248000791120f, -0.874586652278176110f, 0.484198305887549140f, + -0.874958285048851540f, + 0.483527078932918740f, -0.875329403104110780f, 0.482855567531765670f, + -0.875700006225634600f, + 0.482183772079122830f, -0.876070094195406600f, 0.481511692970189920f, + -0.876439666795713610f, + 0.480839330600333900f, -0.876808723809145760f, 0.480166685365088440f, + -0.877177265018595940f, + 0.479493757660153010f, -0.877545290207261240f, 0.478820547881394050f, + -0.877912799158641730f, + 0.478147056424843120f, -0.878279791656541460f, 0.477473283686698060f, + -0.878646267485068130f, + 0.476799230063322250f, -0.879012226428633410f, 0.476124895951243630f, + -0.879377668271953180f, + 0.475450281747155870f, -0.879742592800047410f, 0.474775387847917230f, + -0.880106999798240360f, + 0.474100214650550020f, -0.880470889052160750f, 0.473424762552241530f, + -0.880834260347742040f, + 0.472749031950342900f, -0.881197113471221980f, 0.472073023242368660f, + -0.881559448209143780f, + 0.471396736825997810f, -0.881921264348354940f, 0.470720173099071710f, + -0.882282561676008600f, + 0.470043332459595620f, -0.882643339979562790f, 0.469366215305737630f, + -0.883003599046780720f, + 0.468688822035827960f, -0.883363338665731580f, 0.468011153048359830f, + -0.883722558624789660f, + 0.467333208741988530f, -0.884081258712634990f, 0.466654989515530970f, + -0.884439438718253700f, + 0.465976495767966130f, -0.884797098430937790f, 0.465297727898434650f, + -0.885154237640285110f, + 0.464618686306237820f, -0.885510856136199950f, 0.463939371390838460f, + -0.885866953708892790f, + 0.463259783551860260f, -0.886222530148880640f, 0.462579923189086810f, + -0.886577585246987040f, + 0.461899790702462840f, -0.886932118794342080f, 0.461219386492092430f, + -0.887286130582383150f, + 0.460538710958240010f, -0.887639620402853930f, 0.459857764501329650f, + -0.887992588047805560f, + 0.459176547521944150f, -0.888345033309596240f, 0.458495060420826220f, + -0.888696955980891710f, + 0.457813303598877290f, -0.889048355854664570f, 0.457131277457156980f, + -0.889399232724195520f, + 0.456448982396883860f, -0.889749586383072890f, 0.455766418819434750f, + -0.890099416625192210f, + 0.455083587126343840f, -0.890448723244757880f, 0.454400487719303750f, + -0.890797506036281490f, + 0.453717121000163930f, -0.891145764794583180f, 0.453033487370931580f, + -0.891493499314791380f, + 0.452349587233771000f, -0.891840709392342720f, 0.451665420991002540f, + -0.892187394822982480f, + 0.450980989045103810f, -0.892533555402764690f, 0.450296291798708730f, + -0.892879190928051680f, + 0.449611329654606600f, -0.893224301195515320f, 0.448926103015743260f, + -0.893568886002136020f, + 0.448240612285220000f, -0.893912945145203250f, 0.447554857866293010f, + -0.894256478422316040f, + 0.446868840162374330f, -0.894599485631382580f, 0.446182559577030120f, + -0.894941966570620750f, + 0.445496016513981740f, -0.895283921038557580f, 0.444809211377105000f, + -0.895625348834030000f, + 0.444122144570429260f, -0.895966249756185110f, 0.443434816498138430f, + -0.896306623604479660f, + 0.442747227564570130f, -0.896646470178680150f, 0.442059378174214760f, + -0.896985789278863970f, + 0.441371268731716620f, -0.897324580705418320f, 0.440682899641873020f, + -0.897662844259040750f, + 0.439994271309633260f, -0.898000579740739880f, 0.439305384140100060f, + -0.898337786951834190f, + 0.438616238538527710f, -0.898674465693953820f, 0.437926834910322860f, + -0.899010615769039070f, + 0.437237173661044200f, -0.899346236979341460f, 0.436547255196401250f, + -0.899681329127423930f, + 0.435857079922255470f, -0.900015892016160280f, 0.435166648244619370f, + -0.900349925448735600f, + 0.434475960569655710f, -0.900683429228646860f, 0.433785017303678520f, + -0.901016403159702330f, + 0.433093818853152010f, -0.901348847046022030f, 0.432402365624690140f, + -0.901680760692037730f, + 0.431710658025057370f, -0.902012143902493070f, 0.431018696461167080f, + -0.902342996482444200f, + 0.430326481340082610f, -0.902673318237258830f, 0.429634013069016500f, + -0.903003108972617040f, + 0.428941292055329550f, -0.903332368494511820f, 0.428248318706531910f, + -0.903661096609247980f, + 0.427555093430282200f, -0.903989293123443340f, 0.426861616634386490f, + -0.904316957844028320f, + 0.426167888726799620f, -0.904644090578246240f, 0.425473910115623910f, + -0.904970691133653250f, + 0.424779681209108810f, -0.905296759318118820f, 0.424085202415651670f, + -0.905622294939825160f, + 0.423390474143796100f, -0.905947297807268460f, 0.422695496802232950f, + -0.906271767729257660f, + 0.422000270799799790f, -0.906595704514915330f, 0.421304796545479700f, + -0.906919107973678030f, + 0.420609074448402510f, -0.907241977915295930f, 0.419913104917843730f, + -0.907564314149832520f, + 0.419216888363223960f, -0.907886116487666150f, 0.418520425194109700f, + -0.908207384739488700f, + 0.417823715820212380f, -0.908528118716306120f, 0.417126760651387870f, + -0.908848318229439120f, + 0.416429560097637320f, -0.909167983090522270f, 0.415732114569105420f, + -0.909487113111505430f, + 0.415034424476081630f, -0.909805708104652220f, 0.414336490228999210f, + -0.910123767882541570f, + 0.413638312238434560f, -0.910441292258067140f, 0.412939890915108020f, + -0.910758281044437570f, + 0.412241226669883000f, -0.911074734055176250f, 0.411542319913765280f, + -0.911390651104122320f, + 0.410843171057903910f, -0.911706032005429880f, 0.410143780513590350f, + -0.912020876573568230f, + 0.409444148692257590f, -0.912335184623322750f, 0.408744276005481520f, + -0.912648955969793900f, + 0.408044162864978740f, -0.912962190428398100f, 0.407343809682607970f, + -0.913274887814867760f, + 0.406643216870369140f, -0.913587047945250810f, 0.405942384840402570f, + -0.913898670635911680f, + 0.405241314004989860f, -0.914209755703530690f, 0.404540004776553110f, + -0.914520302965104450f, + 0.403838457567654130f, -0.914830312237946090f, 0.403136672790995240f, + -0.915139783339685260f, + 0.402434650859418540f, -0.915448716088267830f, 0.401732392185905010f, + -0.915757110301956720f, + 0.401029897183575790f, -0.916064965799331610f, 0.400327166265690150f, + -0.916372282399289140f, + 0.399624199845646790f, -0.916679059921042700f, 0.398920998336983020f, + -0.916985298184122890f, + 0.398217562153373620f, -0.917290997008377910f, 0.397513891708632330f, + -0.917596156213972950f, + 0.396809987416710420f, -0.917900775621390390f, 0.396105849691696320f, + -0.918204855051430900f, + 0.395401478947816300f, -0.918508394325212250f, 0.394696875599433670f, + -0.918811393264169940f, + 0.393992040061048100f, -0.919113851690057770f, 0.393286972747296570f, + -0.919415769424946960f, + 0.392581674072951530f, -0.919717146291227360f, 0.391876144452922350f, + -0.920017982111606570f, + 0.391170384302253980f, -0.920318276709110480f, 0.390464394036126650f, + -0.920618029907083860f, + 0.389758174069856410f, -0.920917241529189520f, 0.389051724818894500f, + -0.921215911399408730f, + 0.388345046698826300f, -0.921514039342041900f, 0.387638140125372680f, + -0.921811625181708120f, + 0.386931005514388690f, -0.922108668743345070f, 0.386223643281862980f, + -0.922405169852209880f, + 0.385516053843919020f, -0.922701128333878520f, 0.384808237616812930f, + -0.922996544014246250f, + 0.384100195016935040f, -0.923291416719527640f, 0.383391926460808770f, + -0.923585746276256560f, + 0.382683432365089840f, -0.923879532511286740f, 0.381974713146567220f, + -0.924172775251791200f, + 0.381265769222162490f, -0.924465474325262600f, 0.380556601008928570f, + -0.924757629559513910f, + 0.379847208924051110f, -0.925049240782677580f, 0.379137593384847430f, + -0.925340307823206200f, + 0.378427754808765620f, -0.925630830509872720f, 0.377717693613385810f, + -0.925920808671769960f, + 0.377007410216418310f, -0.926210242138311270f, 0.376296905035704790f, + -0.926499130739230510f, + 0.375586178489217330f, -0.926787474304581750f, 0.374875230995057600f, + -0.927075272664740100f, + 0.374164062971457990f, -0.927362525650401110f, 0.373452674836780410f, + -0.927649233092581180f, + 0.372741067009515810f, -0.927935394822617890f, 0.372029239908284960f, + -0.928221010672169440f, + 0.371317193951837600f, -0.928506080473215480f, 0.370604929559051670f, + -0.928790604058057020f, + 0.369892447148934270f, -0.929074581259315750f, 0.369179747140620070f, + -0.929358011909935500f, + 0.368466829953372320f, -0.929640895843181330f, 0.367753696006582090f, + -0.929923232892639560f, + 0.367040345719767240f, -0.930205022892219070f, 0.366326779512573590f, + -0.930486265676149780f, + 0.365612997804773960f, -0.930766961078983710f, 0.364899001016267380f, + -0.931047108935595170f, + 0.364184789567079840f, -0.931326709081180430f, 0.363470363877363870f, + -0.931605761351257830f, + 0.362755724367397230f, -0.931884265581668150f, 0.362040871457584350f, + -0.932162221608574320f, + 0.361325805568454340f, -0.932439629268462360f, 0.360610527120662270f, + -0.932716488398140250f, + 0.359895036534988280f, -0.932992798834738850f, 0.359179334232336560f, + -0.933268560415712050f, + 0.358463420633736540f, -0.933543772978836170f, 0.357747296160342010f, + -0.933818436362210960f, + 0.357030961233430030f, -0.934092550404258870f, 0.356314416274402360f, + -0.934366114943725900f, + 0.355597661704783960f, -0.934639129819680780f, 0.354880697946222790f, + -0.934911594871516090f, + 0.354163525420490510f, -0.935183509938947500f, 0.353446144549480870f, + -0.935454874862014620f, + 0.352728555755210730f, -0.935725689481080370f, 0.352010759459819240f, + -0.935995953636831300f, + 0.351292756085567150f, -0.936265667170278260f, 0.350574546054837570f, + -0.936534829922755500f, + 0.349856129790135030f, -0.936803441735921560f, 0.349137507714085030f, + -0.937071502451759190f, + 0.348418680249434510f, -0.937339011912574960f, 0.347699647819051490f, + -0.937605969960999990f, + 0.346980410845923680f, -0.937872376439989890f, 0.346260969753160170f, + -0.938138231192824360f, + 0.345541324963989150f, -0.938403534063108060f, 0.344821476901759290f, + -0.938668284894770170f, + 0.344101425989938980f, -0.938932483532064490f, 0.343381172652115100f, + -0.939196129819569900f, + 0.342660717311994380f, -0.939459223602189920f, 0.341940060393402300f, + -0.939721764725153340f, + 0.341219202320282410f, -0.939983753034013940f, 0.340498143516697100f, + -0.940245188374650880f, + 0.339776884406826960f, -0.940506070593268300f, 0.339055425414969640f, + -0.940766399536396070f, + 0.338333766965541290f, -0.941026175050889260f, 0.337611909483074680f, + -0.941285396983928660f, + 0.336889853392220050f, -0.941544065183020810f, 0.336167599117744690f, + -0.941802179495997650f, + 0.335445147084531660f, -0.942059739771017310f, 0.334722497717581220f, + -0.942316745856563780f, + 0.333999651442009490f, -0.942573197601446870f, 0.333276608683047980f, + -0.942829094854802710f, + 0.332553369866044220f, -0.943084437466093490f, 0.331829935416461220f, + -0.943339225285107720f, + 0.331106305759876430f, -0.943593458161960390f, 0.330382481321982950f, + -0.943847135947092690f, + 0.329658462528587550f, -0.944100258491272660f, 0.328934249805612200f, + -0.944352825645594750f, + 0.328209843579092660f, -0.944604837261480260f, 0.327485244275178060f, + -0.944856293190677210f, + 0.326760452320131790f, -0.945107193285260610f, 0.326035468140330350f, + -0.945357537397632290f, + 0.325310292162262980f, -0.945607325380521280f, 0.324584924812532150f, + -0.945856557086983910f, + 0.323859366517852960f, -0.946105232370403340f, 0.323133617705052330f, + -0.946353351084490590f, + 0.322407678801070020f, -0.946600913083283530f, 0.321681550232956640f, + -0.946847918221148000f, + 0.320955232427875210f, -0.947094366352777220f, 0.320228725813100020f, + -0.947340257333191940f, + 0.319502030816015750f, -0.947585591017741090f, 0.318775147864118480f, + -0.947830367262101010f, + 0.318048077385015060f, -0.948074585922276230f, 0.317320819806421790f, + -0.948318246854599090f, + 0.316593375556165850f, -0.948561349915730270f, 0.315865745062184070f, + -0.948803894962658380f, + 0.315137928752522440f, -0.949045881852700560f, 0.314409927055336820f, + -0.949287310443502010f, + 0.313681740398891570f, -0.949528180593036670f, 0.312953369211560200f, + -0.949768492159606680f, + 0.312224813921825050f, -0.950008245001843000f, 0.311496074958275970f, + -0.950247438978705230f, + 0.310767152749611470f, -0.950486073949481700f, 0.310038047724638000f, + -0.950724149773789610f, + 0.309308760312268780f, -0.950961666311575080f, 0.308579290941525030f, + -0.951198623423113230f, + 0.307849640041534980f, -0.951435020969008340f, 0.307119808041533100f, + -0.951670858810193860f, + 0.306389795370861080f, -0.951906136807932230f, 0.305659602458966230f, + -0.952140854823815830f, + 0.304929229735402430f, -0.952375012719765880f, 0.304198677629829270f, + -0.952608610358033240f, + 0.303467946572011370f, -0.952841647601198720f, 0.302737036991819140f, + -0.953074124312172200f, + 0.302005949319228200f, -0.953306040354193750f, 0.301274683984318000f, + -0.953537395590833280f, + 0.300543241417273400f, -0.953768189885990330f, 0.299811622048383460f, + -0.953998423103894490f, + 0.299079826308040480f, -0.954228095109105670f, 0.298347854626741570f, + -0.954457205766513490f, + 0.297615707435086310f, -0.954685754941338340f, 0.296883385163778270f, + -0.954913742499130520f, + 0.296150888243623960f, -0.955141168305770670f, 0.295418217105532070f, + -0.955368032227470240f, + 0.294685372180514330f, -0.955594334130771110f, 0.293952353899684770f, + -0.955820073882545420f, + 0.293219162694258680f, -0.956045251349996410f, 0.292485798995553830f, + -0.956269866400658140f, + 0.291752263234989370f, -0.956493918902394990f, 0.291018555844085090f, + -0.956717408723403050f, + 0.290284677254462330f, -0.956940335732208940f, 0.289550627897843140f, + -0.957162699797670100f, + 0.288816408206049480f, -0.957384500788975860f, 0.288082018611004300f, + -0.957605738575646240f, + 0.287347459544729570f, -0.957826413027532910f, 0.286612731439347790f, + -0.958046524014818600f, + 0.285877834727080730f, -0.958266071408017670f, 0.285142769840248720f, + -0.958485055077976100f, + 0.284407537211271820f, -0.958703474895871600f, 0.283672137272668550f, + -0.958921330733213060f, + 0.282936570457055390f, -0.959138622461841890f, 0.282200837197147500f, + -0.959355349953930790f, + 0.281464937925758050f, -0.959571513081984520f, 0.280728873075797190f, + -0.959787111718839900f, + 0.279992643080273380f, -0.960002145737665850f, 0.279256248372291240f, + -0.960216615011963430f, + 0.278519689385053060f, -0.960430519415565790f, 0.277782966551857800f, + -0.960643858822638470f, + 0.277046080306099950f, -0.960856633107679660f, 0.276309031081271030f, + -0.961068842145519350f, + 0.275571819310958250f, -0.961280485811320640f, 0.274834445428843940f, + -0.961491563980579000f, + 0.274096909868706330f, -0.961702076529122540f, 0.273359213064418790f, + -0.961912023333112100f, + 0.272621355449948980f, -0.962121404269041580f, 0.271883337459359890f, + -0.962330219213737400f, + 0.271145159526808070f, -0.962538468044359160f, 0.270406822086544820f, + -0.962746150638399410f, + 0.269668325572915200f, -0.962953266873683880f, 0.268929670420357310f, + -0.963159816628371360f, + 0.268190857063403180f, -0.963365799780954050f, 0.267451885936677740f, + -0.963571216210257210f, + 0.266712757474898420f, -0.963776065795439840f, 0.265973472112875530f, + -0.963980348415994110f, + 0.265234030285511900f, -0.964184063951745720f, 0.264494432427801630f, + -0.964387212282854290f, + 0.263754678974831510f, -0.964589793289812650f, 0.263014770361779060f, + -0.964791806853447900f, + 0.262274707023913590f, -0.964993252854920320f, 0.261534489396595630f, + -0.965194131175724720f, + 0.260794117915275570f, -0.965394441697689400f, 0.260053593015495130f, + -0.965594184302976830f, + 0.259312915132886350f, -0.965793358874083570f, 0.258572084703170390f, + -0.965991965293840570f, + 0.257831102162158930f, -0.966190003445412620f, 0.257089967945753230f, + -0.966387473212298790f, + 0.256348682489942910f, -0.966584374478333120f, 0.255607246230807550f, + -0.966780707127683270f, + 0.254865659604514630f, -0.966976471044852070f, 0.254123923047320620f, + -0.967171666114676640f, + 0.253382036995570270f, -0.967366292222328510f, 0.252640001885695580f, + -0.967560349253314360f, + 0.251897818154216910f, -0.967753837093475510f, 0.251155486237742030f, + -0.967946755628987800f, + 0.250413006572965280f, -0.968139104746362330f, 0.249670379596668520f, + -0.968330884332445300f, + 0.248927605745720260f, -0.968522094274417270f, 0.248184685457074780f, + -0.968712734459794780f, + 0.247441619167773440f, -0.968902804776428870f, 0.246698407314942500f, + -0.969092305112506100f, + 0.245955050335794590f, -0.969281235356548530f, 0.245211548667627680f, + -0.969469595397412950f, + 0.244467902747824210f, -0.969657385124292450f, 0.243724113013852130f, + -0.969844604426714830f, + 0.242980179903263980f, -0.970031253194543970f, 0.242236103853696070f, + -0.970217331317979160f, + 0.241491885302869300f, -0.970402838687555500f, 0.240747524688588540f, + -0.970587775194143630f, + 0.240003022448741500f, -0.970772140728950350f, 0.239258379021300120f, + -0.970955935183517970f, + 0.238513594844318500f, -0.971139158449725090f, 0.237768670355934210f, + -0.971321810419786160f, + 0.237023605994367340f, -0.971503890986251780f, 0.236278402197919620f, + -0.971685400042008540f, + 0.235533059404975460f, -0.971866337480279400f, 0.234787578054001080f, + -0.972046703194623500f, + 0.234041958583543460f, -0.972226497078936270f, 0.233296201432231560f, + -0.972405719027449770f, + 0.232550307038775330f, -0.972584368934732210f, 0.231804275841964780f, + -0.972762446695688570f, + 0.231058108280671280f, -0.972939952205560070f, 0.230311804793845530f, + -0.973116885359925130f, + 0.229565365820518870f, -0.973293246054698250f, 0.228818791799802360f, + -0.973469034186130950f, + 0.228072083170885790f, -0.973644249650811870f, 0.227325240373038830f, + -0.973818892345666100f, + 0.226578263845610110f, -0.973992962167955830f, 0.225831154028026200f, + -0.974166459015280320f, + 0.225083911359792780f, -0.974339382785575860f, 0.224336536280493690f, + -0.974511733377115720f, + 0.223589029229790020f, -0.974683510688510670f, 0.222841390647421280f, + -0.974854714618708430f, + 0.222093620973203590f, -0.975025345066994120f, 0.221345720647030810f, + -0.975195401932990370f, + 0.220597690108873650f, -0.975364885116656870f, 0.219849529798778750f, + -0.975533794518291360f, + 0.219101240156869770f, -0.975702130038528570f, 0.218352821623346430f, + -0.975869891578341030f, + 0.217604274638483670f, -0.976037079039039020f, 0.216855599642632570f, + -0.976203692322270560f, + 0.216106797076219600f, -0.976369731330021140f, 0.215357867379745550f, + -0.976535195964614470f, + 0.214608810993786920f, -0.976700086128711840f, 0.213859628358993830f, + -0.976864401725312640f, + 0.213110319916091360f, -0.977028142657754390f, 0.212360886105878580f, + -0.977191308829712280f, + 0.211611327369227610f, -0.977353900145199960f, 0.210861644147084830f, + -0.977515916508569280f, + 0.210111836880469720f, -0.977677357824509930f, 0.209361906010474190f, + -0.977838223998050430f, + 0.208611851978263460f, -0.977998514934557140f, 0.207861675225075150f, + -0.978158230539735050f, + 0.207111376192218560f, -0.978317370719627650f, 0.206360955321075680f, + -0.978475935380616830f, + 0.205610413053099320f, -0.978633924429423100f, 0.204859749829814420f, + -0.978791337773105670f, + 0.204108966092817010f, -0.978948175319062200f, 0.203358062283773370f, + -0.979104436975029250f, + 0.202607038844421110f, -0.979260122649082020f, 0.201855896216568160f, + -0.979415232249634780f, + 0.201104634842091960f, -0.979569765685440520f, 0.200353255162940420f, + -0.979723722865591170f, + 0.199601757621131050f, -0.979877103699517640f, 0.198850142658750120f, + -0.980029908096989980f, + 0.198098410717953730f, -0.980182135968117320f, 0.197346562240966000f, + -0.980333787223347960f, + 0.196594597670080220f, -0.980484861773469380f, 0.195842517447657990f, + -0.980635359529608120f, + 0.195090322016128330f, -0.980785280403230430f, 0.194338011817988600f, + -0.980934624306141640f, + 0.193585587295803750f, -0.981083391150486590f, 0.192833048892205290f, + -0.981231580848749730f, + 0.192080397049892380f, -0.981379193313754560f, 0.191327632211630990f, + -0.981526228458664660f, + 0.190574754820252800f, -0.981672686196983110f, 0.189821765318656580f, + -0.981818566442552500f, + 0.189068664149806280f, -0.981963869109555240f, 0.188315451756732120f, + -0.982108594112513610f, + 0.187562128582529740f, -0.982252741366289370f, 0.186808695070359330f, + -0.982396310786084690f, + 0.186055151663446630f, -0.982539302287441240f, 0.185301498805082040f, + -0.982681715786240860f, + 0.184547736938619640f, -0.982823551198705240f, 0.183793866507478390f, + -0.982964808441396440f, + 0.183039887955141060f, -0.983105487431216290f, 0.182285801725153320f, + -0.983245588085407070f, + 0.181531608261125130f, -0.983385110321551180f, 0.180777308006728670f, + -0.983524054057571260f, + 0.180022901405699510f, -0.983662419211730250f, 0.179268388901835880f, + -0.983800205702631490f, + 0.178513770938997590f, -0.983937413449218920f, 0.177759047961107140f, + -0.984074042370776450f, + 0.177004220412148860f, -0.984210092386929030f, 0.176249288736167940f, + -0.984345563417641900f, + 0.175494253377271400f, -0.984480455383220930f, 0.174739114779627310f, + -0.984614768204312600f, + 0.173983873387463850f, -0.984748501801904210f, 0.173228529645070490f, + -0.984881656097323700f, + 0.172473083996796030f, -0.985014231012239840f, 0.171717536887049970f, + -0.985146226468662230f, + 0.170961888760301360f, -0.985277642388941220f, 0.170206140061078120f, + -0.985408478695768420f, + 0.169450291233967930f, -0.985538735312176060f, 0.168694342723617440f, + -0.985668412161537550f, + 0.167938294974731230f, -0.985797509167567370f, 0.167182148432072880f, + -0.985926026254321130f, + 0.166425903540464220f, -0.986053963346195440f, 0.165669560744784140f, + -0.986181320367928270f, + 0.164913120489970090f, -0.986308097244598670f, 0.164156583221015890f, + -0.986434293901627070f, + 0.163399949382973230f, -0.986559910264775410f, 0.162643219420950450f, + -0.986684946260146690f, + 0.161886393780111910f, -0.986809401814185420f, 0.161129472905678780f, + -0.986933276853677710f, + 0.160372457242928400f, -0.987056571305750970f, 0.159615347237193090f, + -0.987179285097874340f, + 0.158858143333861390f, -0.987301418157858430f, 0.158100845978377090f, + -0.987422970413855410f, + 0.157343455616238280f, -0.987543941794359230f, 0.156585972692998590f, + -0.987664332228205710f, + 0.155828397654265320f, -0.987784141644572180f, 0.155070730945700510f, + -0.987903369972977790f, + 0.154312973013020240f, -0.988022017143283530f, 0.153555124301993500f, + -0.988140083085692570f, + 0.152797185258443410f, -0.988257567730749460f, 0.152039156328246160f, + -0.988374471009341280f, + 0.151281037957330250f, -0.988490792852696590f, 0.150522830591677370f, + -0.988606533192386450f, + 0.149764534677321620f, -0.988721691960323780f, 0.149006150660348470f, + -0.988836269088763540f, + 0.148247678986896200f, -0.988950264510302990f, 0.147489120103153680f, + -0.989063678157881540f, + 0.146730474455361750f, -0.989176509964781010f, 0.145971742489812370f, + -0.989288759864625170f, + 0.145212924652847520f, -0.989400427791380380f, 0.144454021390860440f, + -0.989511513679355190f, + 0.143695033150294580f, -0.989622017463200780f, 0.142935960377642700f, + -0.989731939077910570f, + 0.142176803519448000f, -0.989841278458820530f, 0.141417563022303130f, + -0.989950035541608990f, + 0.140658239332849240f, -0.990058210262297120f, 0.139898832897777380f, + -0.990165802557248400f, + 0.139139344163826280f, -0.990272812363169110f, 0.138379773577783890f, + -0.990379239617108160f, + 0.137620121586486180f, -0.990485084256456980f, 0.136860388636816430f, + -0.990590346218950150f, + 0.136100575175706200f, -0.990695025442664630f, 0.135340681650134330f, + -0.990799121866020370f, + 0.134580708507126220f, -0.990902635427780010f, 0.133820656193754690f, + -0.991005566067049370f, + 0.133060525157139180f, -0.991107913723276780f, 0.132300315844444680f, + -0.991209678336254060f, + 0.131540028702883280f, -0.991310859846115440f, 0.130779664179711790f, + -0.991411458193338540f, + 0.130019222722233350f, -0.991511473318743900f, 0.129258704777796270f, + -0.991610905163495370f, + 0.128498110793793220f, -0.991709753669099530f, 0.127737441217662280f, + -0.991808018777406430f, + 0.126976696496885980f, -0.991905700430609330f, 0.126215877078990400f, + -0.992002798571244520f, + 0.125454983411546210f, -0.992099313142191800f, 0.124694015942167770f, + -0.992195244086673920f, + 0.123932975118512200f, -0.992290591348257370f, 0.123171861388280650f, + -0.992385354870851670f, + 0.122410675199216280f, -0.992479534598709970f, 0.121649416999105540f, + -0.992573130476428810f, + 0.120888087235777220f, -0.992666142448948020f, 0.120126686357101580f, + -0.992758570461551140f, + 0.119365214810991350f, -0.992850414459865100f, 0.118603673045400840f, + -0.992941674389860470f, + 0.117842061508325020f, -0.993032350197851410f, 0.117080380647800550f, + -0.993122441830495580f, + 0.116318630911904880f, -0.993211949234794500f, 0.115556812748755290f, + -0.993300872358093280f, + 0.114794926606510250f, -0.993389211148080650f, 0.114032972933367300f, + -0.993476965552789190f, + 0.113270952177564360f, -0.993564135520595300f, 0.112508864787378830f, + -0.993650721000219120f, + 0.111746711211126660f, -0.993736721940724600f, 0.110984491897163380f, + -0.993822138291519660f, + 0.110222207293883180f, -0.993906970002356060f, 0.109459857849718030f, + -0.993991217023329380f, + 0.108697444013138670f, -0.994074879304879370f, 0.107934966232653760f, + -0.994157956797789730f, + 0.107172424956808870f, -0.994240449453187900f, 0.106409820634187840f, + -0.994322357222545810f, + 0.105647153713410700f, -0.994403680057679100f, 0.104884424643134970f, + -0.994484417910747600f, + 0.104121633872054730f, -0.994564570734255420f, 0.103358781848899700f, + -0.994644138481050710f, + 0.102595869022436280f, -0.994723121104325700f, 0.101832895841466670f, + -0.994801518557617110f, + 0.101069862754827880f, -0.994879330794805620f, 0.100306770211392820f, + -0.994956557770116380f, + 0.099543618660069444f, -0.995033199438118630f, 0.098780408549799664f, + -0.995109255753726110f, + 0.098017140329560770f, -0.995184726672196820f, 0.097253814448363354f, + -0.995259612149133390f, + 0.096490431355252607f, -0.995333912140482280f, 0.095726991499307315f, + -0.995407626602534900f, + 0.094963495329639061f, -0.995480755491926940f, 0.094199943295393190f, + -0.995553298765638470f, + 0.093436335845747912f, -0.995625256380994310f, 0.092672673429913366f, + -0.995696628295663520f, + 0.091908956497132696f, -0.995767414467659820f, 0.091145185496681130f, + -0.995837614855341610f, + 0.090381360877865011f, -0.995907229417411720f, 0.089617483090022917f, + -0.995976258112917790f, + 0.088853552582524684f, -0.996044700901251970f, 0.088089569804770507f, + -0.996112557742151130f, + 0.087325535206192226f, -0.996179828595696870f, 0.086561449236251239f, + -0.996246513422315520f, + 0.085797312344439880f, -0.996312612182778000f, 0.085033124980280414f, + -0.996378124838200210f, + 0.084268887593324127f, -0.996443051350042630f, 0.083504600633152404f, + -0.996507391680110820f, + 0.082740264549375803f, -0.996571145790554840f, 0.081975879791633108f, + -0.996634313643869900f, + 0.081211446809592386f, -0.996696895202896060f, 0.080446966052950097f, + -0.996758890430818000f, + 0.079682437971430126f, -0.996820299291165670f, 0.078917863014785095f, + -0.996881121747813850f, + 0.078153241632794315f, -0.996941357764982160f, 0.077388574275265049f, + -0.997001007307235290f, + 0.076623861392031617f, -0.997060070339482960f, 0.075859103432954503f, + -0.997118546826979980f, + 0.075094300847921291f, -0.997176436735326190f, 0.074329454086845867f, + -0.997233740030466160f, + 0.073564563599667454f, -0.997290456678690210f, 0.072799629836351618f, + -0.997346586646633230f, + 0.072034653246889416f, -0.997402129901275300f, 0.071269634281296415f, + -0.997457086409941910f, + 0.070504573389614009f, -0.997511456140303450f, 0.069739471021907376f, + -0.997565239060375750f, + 0.068974327628266732f, -0.997618435138519550f, 0.068209143658806454f, + -0.997671044343441000f, + 0.067443919563664106f, -0.997723066644191640f, 0.066678655793001543f, + -0.997774502010167820f, + 0.065913352797003930f, -0.997825350411111640f, 0.065148011025878860f, + -0.997875611817110150f, + 0.064382630929857410f, -0.997925286198596000f, 0.063617212959193190f, + -0.997974373526346990f, + 0.062851757564161420f, -0.998022873771486240f, 0.062086265195060247f, + -0.998070786905482340f, + 0.061320736302208648f, -0.998118112900149180f, 0.060555171335947781f, + -0.998164851727646240f, + 0.059789570746640007f, -0.998211003360478190f, 0.059023934984667986f, + -0.998256567771495180f, + 0.058258264500435732f, -0.998301544933892890f, 0.057492559744367684f, + -0.998345934821212370f, + 0.056726821166907783f, -0.998389737407340160f, 0.055961049218520520f, + -0.998432952666508440f, + 0.055195244349690031f, -0.998475580573294770f, 0.054429407010919147f, + -0.998517621102622210f, + 0.053663537652730679f, -0.998559074229759310f, 0.052897636725665401f, + -0.998599939930320370f, + 0.052131704680283317f, -0.998640218180265270f, 0.051365741967162731f, + -0.998679908955899090f, + 0.050599749036899337f, -0.998719012233872940f, 0.049833726340107257f, + -0.998757527991183340f, + 0.049067674327418126f, -0.998795456205172410f, 0.048301593449480172f, + -0.998832796853527990f, + 0.047535484156959261f, -0.998869549914283560f, 0.046769346900537960f, + -0.998905715365818290f, + 0.046003182130914644f, -0.998941293186856870f, 0.045236990298804750f, + -0.998976283356469820f, + 0.044470771854938744f, -0.999010685854073380f, 0.043704527250063421f, + -0.999044500659429290f, + 0.042938256934940959f, -0.999077727752645360f, 0.042171961360348002f, + -0.999110367114174890f, + 0.041405640977076712f, -0.999142418724816910f, 0.040639296235933854f, + -0.999173882565716380f, + 0.039872927587739845f, -0.999204758618363890f, 0.039106535483329839f, + -0.999235046864595850f, + 0.038340120373552791f, -0.999264747286594420f, 0.037573682709270514f, + -0.999293859866887790f, + 0.036807222941358991f, -0.999322384588349540f, 0.036040741520706299f, + -0.999350321434199440f, + 0.035274238898213947f, -0.999377670388002850f, 0.034507715524795889f, + -0.999404431433671300f, + 0.033741171851377642f, -0.999430604555461730f, 0.032974608328897315f, + -0.999456189737977340f, + 0.032208025408304704f, -0.999481186966166950f, 0.031441423540560343f, + -0.999505596225325310f, + 0.030674803176636581f, -0.999529417501093140f, 0.029908164767516655f, + -0.999552650779456990f, + 0.029141508764193740f, -0.999575296046749220f, 0.028374835617672258f, + -0.999597353289648380f, + 0.027608145778965820f, -0.999618822495178640f, 0.026841439699098527f, + -0.999639703650710200f, + 0.026074717829104040f, -0.999659996743959220f, 0.025307980620024630f, + -0.999679701762987930f, + 0.024541228522912264f, -0.999698818696204250f, 0.023774461988827676f, + -0.999717347532362190f, + 0.023007681468839410f, -0.999735288260561680f, 0.022240887414024919f, + -0.999752640870248840f, + 0.021474080275469605f, -0.999769405351215280f, 0.020707260504265912f, + -0.999785581693599210f, + 0.019940428551514598f, -0.999801169887884260f, 0.019173584868322699f, + -0.999816169924900410f, + 0.018406729905804820f, -0.999830581795823400f, 0.017639864115082195f, + -0.999844405492175240f, + 0.016872987947281773f, -0.999857641005823860f, 0.016106101853537263f, + -0.999870288328982950f, + 0.015339206284988220f, -0.999882347454212560f, 0.014572301692779104f, + -0.999893818374418490f, + 0.013805388528060349f, -0.999904701082852900f, 0.013038467241987433f, + -0.999914995573113470f, + 0.012271538285719944f, -0.999924701839144500f, 0.011504602110422875f, + -0.999933819875236000f, + 0.010737659167264572f, -0.999942349676023910f, 0.009970709907418029f, + -0.999950291236490480f, + 0.009203754782059960f, -0.999957644551963900f, 0.008436794242369860f, + -0.999964409618118280f, + 0.007669828739531077f, -0.999970586430974140f, 0.006902858724729877f, + -0.999976174986897610f, + 0.006135884649154515f, -0.999981175282601110f, 0.005368906963996303f, + -0.999985587315143200f, + 0.004601926120448672f, -0.999989411081928400f, 0.003834942569706248f, + -0.999992646580707190f, + 0.003067956762966138f, -0.999995293809576190f, 0.002300969151425887f, + -0.999997352766978210f, + 0.001533980186284766f, -0.999998823451701880f, 0.000766990318742846f, + -0.999999705862882230f +}; + +static const float32_t Weights_8192[16384] = { + 1.000000000000000000f, -0.000000000000000000f, 0.999999981616429330f, + -0.000191747597310703f, + 0.999999926465717890f, -0.000383495187571396f, 0.999999834547867670f, + -0.000575242763732066f, + 0.999999705862882230f, -0.000766990318742704f, 0.999999540410766110f, + -0.000958737845553301f, + 0.999999338191525530f, -0.001150485337113849f, 0.999999099205167830f, + -0.001342232786374338f, + 0.999998823451701880f, -0.001533980186284766f, 0.999998510931137790f, + -0.001725727529795126f, + 0.999998161643486980f, -0.001917474809855419f, 0.999997775588762350f, + -0.002109222019415644f, + 0.999997352766978210f, -0.002300969151425805f, 0.999996893178149880f, + -0.002492716198835908f, + 0.999996396822294350f, -0.002684463154595962f, 0.999995863699429940f, + -0.002876210011655979f, + 0.999995293809576190f, -0.003067956762965976f, 0.999994687152754080f, + -0.003259703401475973f, + 0.999994043728985820f, -0.003451449920135994f, 0.999993363538295150f, + -0.003643196311896068f, + 0.999992646580707190f, -0.003834942569706228f, 0.999991892856248010f, + -0.004026688686516512f, + 0.999991102364945590f, -0.004218434655276963f, 0.999990275106828920f, + -0.004410180468937631f, + 0.999989411081928400f, -0.004601926120448571f, 0.999988510290275690f, + -0.004793671602759841f, + 0.999987572731904080f, -0.004985416908821511f, 0.999986598406848000f, + -0.005177162031583651f, + 0.999985587315143200f, -0.005368906963996343f, 0.999984539456826970f, + -0.005560651699009674f, + 0.999983454831937730f, -0.005752396229573736f, 0.999982333440515350f, + -0.005944140548638633f, + 0.999981175282601110f, -0.006135884649154475f, 0.999979980358237650f, + -0.006327628524071378f, + 0.999978748667468830f, -0.006519372166339468f, 0.999977480210339940f, + -0.006711115568908879f, + 0.999976174986897610f, -0.006902858724729756f, 0.999974832997189810f, + -0.007094601626752250f, + 0.999973454241265940f, -0.007286344267926521f, 0.999972038719176730f, + -0.007478086641202744f, + 0.999970586430974140f, -0.007669828739531097f, 0.999969097376711580f, + -0.007861570555861772f, + 0.999967571556443780f, -0.008053312083144972f, 0.999966008970226920f, + -0.008245053314330906f, + 0.999964409618118280f, -0.008436794242369799f, 0.999962773500176930f, + -0.008628534860211886f, + 0.999961100616462820f, -0.008820275160807412f, 0.999959390967037450f, + -0.009012015137106633f, + 0.999957644551963900f, -0.009203754782059819f, 0.999955861371306100f, + -0.009395494088617252f, + 0.999954041425129780f, -0.009587233049729225f, 0.999952184713501780f, + -0.009778971658346044f, + 0.999950291236490480f, -0.009970709907418031f, 0.999948360994165400f, + -0.010162447789895513f, + 0.999946393986597460f, -0.010354185298728842f, 0.999944390213859060f, + -0.010545922426868378f, + 0.999942349676023910f, -0.010737659167264491f, 0.999940272373166960f, + -0.010929395512867571f, + 0.999938158305364590f, -0.011121131456628021f, 0.999936007472694620f, + -0.011312866991496258f, + 0.999933819875236000f, -0.011504602110422714f, 0.999931595513069200f, + -0.011696336806357838f, + 0.999929334386276070f, -0.011888071072252092f, 0.999927036494939640f, + -0.012079804901055957f, + 0.999924701839144500f, -0.012271538285719925f, 0.999922330418976490f, + -0.012463271219194511f, + 0.999919922234522750f, -0.012655003694430242f, 0.999917477285871770f, + -0.012846735704377662f, + 0.999914995573113470f, -0.013038467241987334f, 0.999912477096339240f, + -0.013230198300209835f, + 0.999909921855641540f, -0.013421928871995765f, 0.999907329851114300f, + -0.013613658950295740f, + 0.999904701082852900f, -0.013805388528060391f, 0.999902035550953920f, + -0.013997117598240367f, + 0.999899333255515390f, -0.014188846153786345f, 0.999896594196636680f, + -0.014380574187649006f, + 0.999893818374418490f, -0.014572301692779064f, 0.999891005788962950f, + -0.014764028662127246f, + 0.999888156440373320f, -0.014955755088644296f, 0.999885270328754520f, + -0.015147480965280987f, + 0.999882347454212560f, -0.015339206284988100f, 0.999879387816854930f, + -0.015530931040716447f, + 0.999876391416790410f, -0.015722655225416857f, 0.999873358254129260f, + -0.015914378832040183f, + 0.999870288328982950f, -0.016106101853537287f, 0.999867181641464380f, + -0.016297824282859065f, + 0.999864038191687680f, -0.016489546112956437f, 0.999860857979768540f, + -0.016681267336780332f, + 0.999857641005823860f, -0.016872987947281710f, 0.999854387269971890f, + -0.017064707937411563f, + 0.999851096772332190f, -0.017256427300120877f, 0.999847769513025900f, + -0.017448146028360693f, + 0.999844405492175240f, -0.017639864115082053f, 0.999841004709904000f, + -0.017831581553236039f, + 0.999837567166337090f, -0.018023298335773746f, 0.999834092861600960f, + -0.018215014455646290f, + 0.999830581795823400f, -0.018406729905804820f, 0.999827033969133420f, + -0.018598444679200511f, + 0.999823449381661570f, -0.018790158768784555f, 0.999819828033539420f, + -0.018981872167508178f, + 0.999816169924900410f, -0.019173584868322623f, 0.999812475055878780f, + -0.019365296864179156f, + 0.999808743426610520f, -0.019557008148029083f, 0.999804975037232870f, + -0.019748718712823729f, + 0.999801169887884260f, -0.019940428551514441f, 0.999797327978704690f, + -0.020132137657052594f, + 0.999793449309835270f, -0.020323846022389593f, 0.999789533881418780f, + -0.020515553640476875f, + 0.999785581693599210f, -0.020707260504265895f, 0.999781592746521670f, + -0.020898966606708137f, + 0.999777567040332940f, -0.021090671940755121f, 0.999773504575180990f, + -0.021282376499358387f, + 0.999769405351215280f, -0.021474080275469508f, 0.999765269368586450f, + -0.021665783262040078f, + 0.999761096627446610f, -0.021857485452021735f, 0.999756887127949080f, + -0.022049186838366135f, + 0.999752640870248840f, -0.022240887414024961f, 0.999748357854501780f, + -0.022432587171949934f, + 0.999744038080865430f, -0.022624286105092803f, 0.999739681549498660f, + -0.022815984206405345f, + 0.999735288260561680f, -0.023007681468839369f, 0.999730858214216030f, + -0.023199377885346720f, + 0.999726391410624470f, -0.023391073448879258f, 0.999721887849951310f, + -0.023582768152388894f, + 0.999717347532362190f, -0.023774461988827555f, 0.999712770458023870f, + -0.023966154951147210f, + 0.999708156627104880f, -0.024157847032299864f, 0.999703506039774650f, + -0.024349538225237534f, + 0.999698818696204250f, -0.024541228522912288f, 0.999694094596566000f, + -0.024732917918276223f, + 0.999689333741033640f, -0.024924606404281468f, 0.999684536129782140f, + -0.025116293973880186f, + 0.999679701762987930f, -0.025307980620024571f, 0.999674830640828740f, + -0.025499666335666853f, + 0.999669922763483760f, -0.025691351113759295f, 0.999664978131133310f, + -0.025883034947254198f, + 0.999659996743959220f, -0.026074717829103901f, 0.999654978602144690f, + -0.026266399752260760f, + 0.999649923705874240f, -0.026458080709677187f, 0.999644832055333610f, + -0.026649760694305618f, + 0.999639703650710200f, -0.026841439699098531f, 0.999634538492192300f, + -0.027033117717008431f, + 0.999629336579970110f, -0.027224794740987875f, 0.999624097914234570f, + -0.027416470763989436f, + 0.999618822495178640f, -0.027608145778965740f, 0.999613510322995950f, + -0.027799819778869445f, + 0.999608161397882110f, -0.027991492756653243f, 0.999602775720033530f, + -0.028183164705269874f, + 0.999597353289648380f, -0.028374835617672099f, 0.999591894106925950f, + -0.028566505486812728f, + 0.999586398172067070f, -0.028758174305644615f, 0.999580865485273700f, + -0.028949842067120635f, + 0.999575296046749220f, -0.029141508764193722f, 0.999569689856698580f, + -0.029333174389816835f, + 0.999564046915327740f, -0.029524838936942976f, 0.999558367222844300f, + -0.029716502398525191f, + 0.999552650779456990f, -0.029908164767516555f, 0.999546897585375960f, + -0.030099826036870198f, + 0.999541107640812940f, -0.030291486199539284f, 0.999535280945980540f, + -0.030483145248477009f, + 0.999529417501093140f, -0.030674803176636626f, 0.999523517306366350f, + -0.030866459976971412f, + 0.999517580362016990f, -0.031058115642434700f, 0.999511606668263440f, + -0.031249770165979861f, + 0.999505596225325310f, -0.031441423540560301f, 0.999499549033423640f, + -0.031633075759129478f, + 0.999493465092780590f, -0.031824726814640887f, 0.999487344403620080f, + -0.032016376700048060f, + 0.999481186966166950f, -0.032208025408304586f, 0.999474992780647780f, + -0.032399672932364086f, + 0.999468761847290050f, -0.032591319265180226f, 0.999462494166323160f, + -0.032782964399706724f, + 0.999456189737977340f, -0.032974608328897335f, 0.999449848562484530f, + -0.033166251045705857f, + 0.999443470640077770f, -0.033357892543086139f, 0.999437055970991530f, + -0.033549532813992068f, + 0.999430604555461730f, -0.033741171851377580f, 0.999424116393725640f, + -0.033932809648196664f, + 0.999417591486021720f, -0.034124446197403326f, 0.999411029832589780f, + -0.034316081491951651f, + 0.999404431433671300f, -0.034507715524795750f, 0.999397796289508640f, + -0.034699348288889799f, + 0.999391124400346050f, -0.034890979777188004f, 0.999384415766428560f, + -0.035082609982644619f, + 0.999377670388002850f, -0.035274238898213947f, 0.999370888265317170f, + -0.035465866516850353f, + 0.999364069398620550f, -0.035657492831508222f, 0.999357213788164000f, + -0.035849117835142018f, + 0.999350321434199440f, -0.036040741520706229f, 0.999343392336980220f, + -0.036232363881155395f, + 0.999336426496761240f, -0.036423984909444110f, 0.999329423913798420f, + -0.036615604598527030f, + 0.999322384588349540f, -0.036807222941358832f, 0.999315308520673070f, + -0.036998839930894263f, + 0.999308195711029470f, -0.037190455560088119f, 0.999301046159680070f, + -0.037382069821895229f, + 0.999293859866887790f, -0.037573682709270494f, 0.999286636832916740f, + -0.037765294215168860f, + 0.999279377058032710f, -0.037956904332545310f, 0.999272080542502610f, + -0.038148513054354891f, + 0.999264747286594420f, -0.038340120373552694f, 0.999257377290578060f, + -0.038531726283093870f, + 0.999249970554724420f, -0.038723330775933623f, 0.999242527079305830f, + -0.038914933845027193f, + 0.999235046864595850f, -0.039106535483329888f, 0.999227529910869610f, + -0.039298135683797059f, + 0.999219976218403530f, -0.039489734439384118f, 0.999212385787475290f, + -0.039681331743046527f, + 0.999204758618363890f, -0.039872927587739811f, 0.999197094711349880f, + -0.040064521966419520f, + 0.999189394066714920f, -0.040256114872041282f, 0.999181656684742350f, + -0.040447706297560782f, + 0.999173882565716380f, -0.040639296235933736f, 0.999166071709923000f, + -0.040830884680115948f, + 0.999158224117649430f, -0.041022471623063238f, 0.999150339789184110f, + -0.041214057057731519f, + 0.999142418724816910f, -0.041405640977076739f, 0.999134460924839150f, + -0.041597223374054894f, + 0.999126466389543390f, -0.041788804241622061f, 0.999118435119223490f, + -0.041980383572734356f, + 0.999110367114174890f, -0.042171961360347947f, 0.999102262374694130f, + -0.042363537597419072f, + 0.999094120901079070f, -0.042555112276904020f, 0.999085942693629270f, + -0.042746685391759132f, + 0.999077727752645360f, -0.042938256934940820f, 0.999069476078429330f, + -0.043129826899405546f, + 0.999061187671284600f, -0.043321395278109825f, 0.999052862531515930f, + -0.043512962064010237f, + 0.999044500659429290f, -0.043704527250063421f, 0.999036102055332330f, + -0.043896090829226068f, + 0.999027666719533690f, -0.044087652794454944f, 0.999019194652343460f, + -0.044279213138706849f, + 0.999010685854073380f, -0.044470771854938668f, 0.999002140325035980f, + -0.044662328936107325f, + 0.998993558065545680f, -0.044853884375169815f, 0.998984939075918010f, + -0.045045438165083197f, + 0.998976283356469820f, -0.045236990298804590f, 0.998967590907519300f, + -0.045428540769291155f, + 0.998958861729386080f, -0.045620089569500144f, 0.998950095822391250f, + -0.045811636692388844f, + 0.998941293186856870f, -0.046003182130914623f, 0.998932453823106690f, + -0.046194725878034908f, + 0.998923577731465780f, -0.046386267926707157f, 0.998914664912260440f, + -0.046577808269888943f, + 0.998905715365818290f, -0.046769346900537863f, 0.998896729092468410f, + -0.046960883811611592f, + 0.998887706092541290f, -0.047152418996067869f, 0.998878646366368690f, + -0.047343952446864478f, + 0.998869549914283560f, -0.047535484156959303f, 0.998860416736620520f, + -0.047727014119310254f, + 0.998851246833715180f, -0.047918542326875327f, 0.998842040205904840f, + -0.048110068772612591f, + 0.998832796853527990f, -0.048301593449480144f, 0.998823516776924490f, + -0.048493116350436176f, + 0.998814199976435390f, -0.048684637468438943f, 0.998804846452403420f, + -0.048876156796446760f, + 0.998795456205172410f, -0.049067674327418015f, 0.998786029235087640f, + -0.049259190054311140f, + 0.998776565542495610f, -0.049450703970084664f, 0.998767065127744380f, + -0.049642216067697156f, + 0.998757527991183340f, -0.049833726340107277f, 0.998747954133162860f, + -0.050025234780273729f, + 0.998738343554035230f, -0.050216741381155311f, 0.998728696254153720f, + -0.050408246135710856f, + 0.998719012233872940f, -0.050599749036899282f, 0.998709291493549030f, + -0.050791250077679581f, + 0.998699534033539280f, -0.050982749251010803f, 0.998689739854202620f, + -0.051174246549852080f, + 0.998679908955899090f, -0.051365741967162593f, 0.998670041338990070f, + -0.051557235495901611f, + 0.998660137003838490f, -0.051748727129028456f, 0.998650195950808280f, + -0.051940216859502536f, + 0.998640218180265270f, -0.052131704680283324f, 0.998630203692576050f, + -0.052323190584330347f, + 0.998620152488108870f, -0.052514674564603223f, 0.998610064567233340f, + -0.052706156614061632f, + 0.998599939930320370f, -0.052897636725665324f, 0.998589778577742230f, + -0.053089114892374133f, + 0.998579580509872500f, -0.053280591107147945f, 0.998569345727086110f, + -0.053472065362946727f, + 0.998559074229759310f, -0.053663537652730520f, 0.998548766018269920f, + -0.053855007969459440f, + 0.998538421092996730f, -0.054046476306093660f, 0.998528039454320230f, + -0.054237942655593452f, + 0.998517621102622210f, -0.054429407010919133f, 0.998507166038285490f, + -0.054620869365031105f, + 0.998496674261694640f, -0.054812329710889854f, 0.998486145773235360f, + -0.055003788041455920f, + 0.998475580573294770f, -0.055195244349689934f, 0.998464978662261250f, + -0.055386698628552597f, + 0.998454340040524800f, -0.055578150871004678f, 0.998443664708476340f, + -0.055769601070007030f, + 0.998432952666508440f, -0.055961049218520569f, 0.998422203915015020f, + -0.056152495309506292f, + 0.998411418454391300f, -0.056343939335925290f, 0.998400596285033640f, + -0.056535381290738700f, + 0.998389737407340160f, -0.056726821166907748f, 0.998378841821709990f, + -0.056918258957393740f, + 0.998367909528543820f, -0.057109694655158062f, 0.998356940528243420f, + -0.057301128253162158f, + 0.998345934821212370f, -0.057492559744367566f, 0.998334892407855000f, + -0.057683989121735904f, + 0.998323813288577560f, -0.057875416378228857f, 0.998312697463787260f, + -0.058066841506808194f, + 0.998301544933892890f, -0.058258264500435752f, 0.998290355699304350f, + -0.058449685352073476f, + 0.998279129760433200f, -0.058641104054683341f, 0.998267867117692110f, + -0.058832520601227435f, + 0.998256567771495180f, -0.059023934984667931f, 0.998245231722257880f, + -0.059215347197967061f, + 0.998233858970396850f, -0.059406757234087150f, 0.998222449516330550f, + -0.059598165085990591f, + 0.998211003360478190f, -0.059789570746639868f, 0.998199520503260660f, + -0.059980974208997548f, + 0.998188000945100300f, -0.060172375466026259f, 0.998176444686420530f, + -0.060363774510688743f, + 0.998164851727646240f, -0.060555171335947788f, 0.998153222069203760f, + -0.060746565934766288f, + 0.998141555711520520f, -0.060937958300107203f, 0.998129852655025630f, + -0.061129348424933588f, + 0.998118112900149180f, -0.061320736302208578f, 0.998106336447323050f, + -0.061512121924895378f, + 0.998094523296980010f, -0.061703505285957298f, 0.998082673449554590f, + -0.061894886378357716f, + 0.998070786905482340f, -0.062086265195060088f, 0.998058863665200250f, + -0.062277641729027972f, + 0.998046903729146840f, -0.062469015973224996f, 0.998034907097761770f, + -0.062660387920614874f, + 0.998022873771486240f, -0.062851757564161406f, 0.998010803750762450f, + -0.063043124896828492f, + 0.997998697036034390f, -0.063234489911580066f, 0.997986553627747020f, + -0.063425852601380228f, + 0.997974373526346990f, -0.063617212959193106f, 0.997962156732281950f, + -0.063808570977982898f, + 0.997949903246001190f, -0.063999926650713940f, 0.997937613067955250f, + -0.064191279970350637f, + 0.997925286198596000f, -0.064382630929857465f, 0.997912922638376610f, + -0.064573979522198982f, + 0.997900522387751620f, -0.064765325740339885f, 0.997888085447177110f, + -0.064956669577244872f, + 0.997875611817110150f, -0.065148011025878833f, 0.997863101498009500f, + -0.065339350079206632f, + 0.997850554490335110f, -0.065530686730193327f, 0.997837970794548280f, + -0.065722020971803990f, + 0.997825350411111640f, -0.065913352797003805f, 0.997812693340489280f, + -0.066104682198758077f, + 0.997799999583146470f, -0.066296009170032130f, 0.997787269139549960f, + -0.066487333703791451f, + 0.997774502010167820f, -0.066678655793001557f, 0.997761698195469560f, + -0.066869975430628115f, + 0.997748857695925690f, -0.067061292609636822f, 0.997735980512008620f, + -0.067252607322993499f, + 0.997723066644191640f, -0.067443919563664051f, 0.997710116092949570f, + -0.067635229324614479f, + 0.997697128858758500f, -0.067826536598810869f, 0.997684104942096030f, + -0.068017841379219388f, + 0.997671044343441000f, -0.068209143658806329f, 0.997657947063273710f, + -0.068400443430538013f, + 0.997644813102075420f, -0.068591740687380942f, 0.997631642460329320f, + -0.068783035422301630f, + 0.997618435138519550f, -0.068974327628266746f, 0.997605191137131640f, + -0.069165617298242985f, + 0.997591910456652630f, -0.069356904425197208f, 0.997578593097570800f, + -0.069548189002096306f, + 0.997565239060375750f, -0.069739471021907307f, 0.997551848345558430f, + -0.069930750477597309f, + 0.997538420953611340f, -0.070122027362133521f, 0.997524956885027960f, + -0.070313301668483250f, + 0.997511456140303450f, -0.070504573389613856f, 0.997497918719934210f, + -0.070695842518492855f, + 0.997484344624417930f, -0.070887109048087801f, 0.997470733854253670f, + -0.071078372971366405f, + 0.997457086409941910f, -0.071269634281296401f, 0.997443402291984360f, + -0.071460892970845680f, + 0.997429681500884180f, -0.071652149032982212f, 0.997415924037145960f, + -0.071843402460674027f, + 0.997402129901275300f, -0.072034653246889332f, 0.997388299093779460f, + -0.072225901384596322f, + 0.997374431615167150f, -0.072417146866763413f, 0.997360527465947940f, + -0.072608389686358993f, + 0.997346586646633230f, -0.072799629836351673f, 0.997332609157735470f, + -0.072990867309710036f, + 0.997318594999768600f, -0.073182102099402888f, 0.997304544173247990f, + -0.073373334198399032f, + 0.997290456678690210f, -0.073564563599667426f, 0.997276332516613180f, + -0.073755790296177098f, + 0.997262171687536170f, -0.073947014280897200f, 0.997247974191979860f, + -0.074138235546796979f, + 0.997233740030466280f, -0.074329454086845756f, 0.997219469203518670f, + -0.074520669894013000f, + 0.997205161711661850f, -0.074711882961268211f, 0.997190817555421940f, + -0.074903093281581082f, + 0.997176436735326190f, -0.075094300847921305f, 0.997162019251903290f, + -0.075285505653258769f, + 0.997147565105683480f, -0.075476707690563388f, 0.997133074297198110f, + -0.075667906952805231f, + 0.997118546826979980f, -0.075859103432954447f, 0.997103982695563330f, + -0.076050297123981259f, + 0.997089381903483400f, -0.076241488018856066f, 0.997074744451277310f, + -0.076432676110549283f, + 0.997060070339482960f, -0.076623861392031492f, 0.997045359568640040f, + -0.076815043856273343f, + 0.997030612139289450f, -0.077006223496245640f, 0.997015828051973310f, + -0.077197400304919200f, + 0.997001007307235290f, -0.077388574275265049f, 0.996986149905620180f, + -0.077579745400254224f, + 0.996971255847674320f, -0.077770913672857947f, 0.996956325133945280f, + -0.077962079086047492f, + 0.996941357764982160f, -0.078153241632794232f, 0.996926353741335090f, + -0.078344401306069705f, + 0.996911313063555740f, -0.078535558098845479f, 0.996896235732197210f, + -0.078726712004093299f, + 0.996881121747813850f, -0.078917863014784942f, 0.996865971110961310f, + -0.079109011123892375f, + 0.996850783822196610f, -0.079300156324387597f, 0.996835559882078170f, + -0.079491298609242769f, + 0.996820299291165670f, -0.079682437971430126f, 0.996805002050020430f, + -0.079873574403921996f, + 0.996789668159204560f, -0.080064707899690890f, 0.996774297619282050f, + -0.080255838451709319f, + 0.996758890430818000f, -0.080446966052950014f, 0.996743446594378860f, + -0.080638090696385709f, + 0.996727966110532490f, -0.080829212374989329f, 0.996712448979848010f, + -0.081020331081733857f, + 0.996696895202896060f, -0.081211446809592441f, 0.996681304780248300f, + -0.081402559551538245f, + 0.996665677712478160f, -0.081593669300544652f, 0.996650014000160070f, + -0.081784776049585076f, + 0.996634313643869900f, -0.081975879791633066f, 0.996618576644185070f, + -0.082166980519662314f, + 0.996602803001684130f, -0.082358078226646536f, 0.996586992716946950f, + -0.082549172905559673f, + 0.996571145790554840f, -0.082740264549375692f, 0.996555262223090540f, + -0.082931353151068699f, + 0.996539342015137940f, -0.083122438703612911f, 0.996523385167282450f, + -0.083313521199982685f, + 0.996507391680110820f, -0.083504600633152432f, 0.996491361554210920f, + -0.083695676996096716f, + 0.996475294790172160f, -0.083886750281790226f, 0.996459191388585410f, + -0.084077820483207694f, + 0.996443051350042630f, -0.084268887593324071f, 0.996426874675137240f, + -0.084459951605114325f, + 0.996410661364464100f, -0.084651012511553617f, 0.996394411418619290f, + -0.084842070305617134f, + 0.996378124838200210f, -0.085033124980280275f, 0.996361801623805720f, + -0.085224176528518478f, + 0.996345441776035900f, -0.085415224943307333f, 0.996329045295492380f, + -0.085606270217622529f, + 0.996312612182778000f, -0.085797312344439894f, 0.996296142438496850f, + -0.085988351316735337f, + 0.996279636063254650f, -0.086179387127484894f, 0.996263093057658140f, + -0.086370419769664752f, + 0.996246513422315520f, -0.086561449236251170f, 0.996229897157836500f, + -0.086752475520220543f, + 0.996213244264832040f, -0.086943498614549378f, 0.996196554743914220f, + -0.087134518512214307f, + 0.996179828595696980f, -0.087325535206192059f, 0.996163065820794950f, + -0.087516548689459531f, + 0.996146266419824620f, -0.087707558954993659f, 0.996129430393403740f, + -0.087898565995771588f, + 0.996112557742151130f, -0.088089569804770507f, 0.996095648466687300f, + -0.088280570374967740f, + 0.996078702567633980f, -0.088471567699340767f, 0.996061720045614000f, + -0.088662561770867149f, + 0.996044700901251970f, -0.088853552582524600f, 0.996027645135173610f, + -0.089044540127290892f, + 0.996010552748005870f, -0.089235524398144014f, 0.995993423740377360f, + -0.089426505388061961f, + 0.995976258112917790f, -0.089617483090022959f, 0.995959055866258320f, + -0.089808457497005278f, + 0.995941817001031350f, -0.089999428601987341f, 0.995924541517870800f, + -0.090190396397947695f, + 0.995907229417411720f, -0.090381360877864983f, 0.995889880700290720f, + -0.090572322034717989f, + 0.995872495367145730f, -0.090763279861485621f, 0.995855073418615790f, + -0.090954234351146926f, + 0.995837614855341610f, -0.091145185496681005f, 0.995820119677964910f, + -0.091336133291067184f, + 0.995802587887129160f, -0.091527077727284828f, 0.995785019483478750f, + -0.091718018798313455f, + 0.995767414467659820f, -0.091908956497132724f, 0.995749772840319510f, + -0.092099890816722388f, + 0.995732094602106430f, -0.092290821750062355f, 0.995714379753670610f, + -0.092481749290132600f, + 0.995696628295663520f, -0.092672673429913310f, 0.995678840228737540f, + -0.092863594162384724f, + 0.995661015553546910f, -0.093054511480527249f, 0.995643154270746900f, + -0.093245425377321375f, + 0.995625256380994310f, -0.093436335845747787f, 0.995607321884947050f, + -0.093627242878787195f, + 0.995589350783264600f, -0.093818146469420549f, 0.995571343076607770f, + -0.094009046610628838f, + 0.995553298765638470f, -0.094199943295393204f, 0.995535217851020390f, + -0.094390836516694943f, + 0.995517100333418110f, -0.094581726267515445f, 0.995498946213497770f, + -0.094772612540836243f, + 0.995480755491926940f, -0.094963495329638992f, 0.995462528169374420f, + -0.095154374626905486f, + 0.995444264246510340f, -0.095345250425617617f, 0.995425963724006160f, + -0.095536122718757471f, + 0.995407626602534900f, -0.095726991499307162f, 0.995389252882770690f, + -0.095917856760249040f, + 0.995370842565388990f, -0.096108718494565509f, 0.995352395651066810f, + -0.096299576695239128f, + 0.995333912140482280f, -0.096490431355252593f, 0.995315392034315070f, + -0.096681282467588725f, + 0.995296835333246090f, -0.096872130025230471f, 0.995278242037957670f, + -0.097062974021160917f, + 0.995259612149133390f, -0.097253814448363271f, 0.995240945667458130f, + -0.097444651299820870f, + 0.995222242593618360f, -0.097635484568517200f, 0.995203502928301510f, + -0.097826314247435861f, + 0.995184726672196930f, -0.098017140329560604f, 0.995165913825994620f, + -0.098207962807875276f, + 0.995147064390386470f, -0.098398781675363881f, 0.995128178366065490f, + -0.098589596925010584f, + 0.995109255753726110f, -0.098780408549799623f, 0.995090296554064000f, + -0.098971216542715429f, + 0.995071300767776170f, -0.099162020896742503f, 0.995052268395561050f, + -0.099352821604865540f, + 0.995033199438118630f, -0.099543618660069319f, 0.995014093896149700f, + -0.099734412055338825f, + 0.994994951770357020f, -0.099925201783659073f, 0.994975773061444140f, + -0.100115987838015310f, + 0.994956557770116380f, -0.100306770211392860f, 0.994937305897080070f, + -0.100497548896777200f, + 0.994918017443043200f, -0.100688323887153960f, 0.994898692408714870f, + -0.100879095175508860f, + 0.994879330794805620f, -0.101069862754827820f, 0.994859932602027320f, + -0.101260626618096830f, + 0.994840497831093180f, -0.101451386758302080f, 0.994821026482717860f, + -0.101642143168429830f, + 0.994801518557617110f, -0.101832895841466530f, 0.994781974056508260f, + -0.102023644770398740f, + 0.994762392980109930f, -0.102214389948213210f, 0.994742775329142010f, + -0.102405131367896720f, + 0.994723121104325700f, -0.102595869022436280f, 0.994703430306383860f, + -0.102786602904819040f, + 0.994683702936040250f, -0.102977333008032220f, 0.994663938994020390f, + -0.103168059325063230f, + 0.994644138481050710f, -0.103358781848899610f, 0.994624301397859400f, + -0.103549500572529070f, + 0.994604427745175660f, -0.103740215488939370f, 0.994584517523730340f, + -0.103930926591118510f, + 0.994564570734255420f, -0.104121633872054590f, 0.994544587377484300f, + -0.104312337324735800f, + 0.994524567454151740f, -0.104503036942150570f, 0.994504510964993700f, + -0.104693732717287390f, + 0.994484417910747600f, -0.104884424643134970f, 0.994464288292152390f, + -0.105075112712682040f, + 0.994444122109948040f, -0.105265796918917600f, 0.994423919364875950f, + -0.105456477254830710f, + 0.994403680057679100f, -0.105647153713410620f, 0.994383404189101430f, + -0.105837826287646670f, + 0.994363091759888570f, -0.106028494970528410f, 0.994342742770787270f, + -0.106219159755045480f, + 0.994322357222545810f, -0.106409820634187680f, 0.994301935115913580f, + -0.106600477600944960f, + 0.994281476451641550f, -0.106791130648307390f, 0.994260981230481790f, + -0.106981779769265230f, + 0.994240449453187900f, -0.107172424956808840f, 0.994219881120514960f, + -0.107363066203928760f, + 0.994199276233218910f, -0.107553703503615620f, 0.994178634792057590f, + -0.107744336848860280f, + 0.994157956797789730f, -0.107934966232653650f, 0.994137242251175720f, + -0.108125591647986870f, + 0.994116491152977070f, -0.108316213087851170f, 0.994095703503956930f, + -0.108506830545237920f, + 0.994074879304879370f, -0.108697444013138720f, 0.994054018556510210f, + -0.108888053484545190f, + 0.994033121259616400f, -0.109078658952449240f, 0.994012187414966220f, + -0.109269260409842780f, + 0.993991217023329380f, -0.109459857849717980f, 0.993970210085476920f, + -0.109650451265067100f, + 0.993949166602181130f, -0.109841040648882600f, 0.993928086574215830f, + -0.110031625994157000f, + 0.993906970002356060f, -0.110222207293883060f, 0.993885816887378090f, + -0.110412784541053630f, + 0.993864627230059750f, -0.110603357728661730f, 0.993843401031180180f, + -0.110793926849700560f, + 0.993822138291519660f, -0.110984491897163390f, 0.993800839011860120f, + -0.111175052864043720f, + 0.993779503192984580f, -0.111365609743335160f, 0.993758130835677430f, + -0.111556162528031480f, + 0.993736721940724600f, -0.111746711211126590f, 0.993715276508913230f, + -0.111937255785614570f, + 0.993693794541031790f, -0.112127796244489640f, 0.993672276037870010f, + -0.112318332580746170f, + 0.993650721000219120f, -0.112508864787378690f, 0.993629129428871720f, + -0.112699392857381860f, + 0.993607501324621610f, -0.112889916783750520f, 0.993585836688263950f, + -0.113080436559479620f, + 0.993564135520595300f, -0.113270952177564350f, 0.993542397822413600f, + -0.113461463630999950f, + 0.993520623594518090f, -0.113651970912781870f, 0.993498812837709360f, + -0.113842474015905710f, + 0.993476965552789190f, -0.114032972933367200f, 0.993455081740560960f, + -0.114223467658162260f, + 0.993433161401829360f, -0.114413958183286920f, 0.993411204537400060f, + -0.114604444501737420f, + 0.993389211148080650f, -0.114794926606510080f, 0.993367181234679600f, + -0.114985404490601460f, + 0.993345114798006910f, -0.115175878147008190f, 0.993323011838873950f, + -0.115366347568727140f, + 0.993300872358093280f, -0.115556812748755260f, 0.993278696356479030f, + -0.115747273680089720f, + 0.993256483834846440f, -0.115937730355727780f, 0.993234234794012290f, + -0.116128182768666930f, + 0.993211949234794500f, -0.116318630911904750f, 0.993189627158012620f, + -0.116509074778439040f, + 0.993167268564487230f, -0.116699514361267690f, 0.993144873455040430f, + -0.116889949653388780f, + 0.993122441830495580f, -0.117080380647800590f, 0.993099973691677570f, + -0.117270807337501460f, + 0.993077469039412300f, -0.117461229715489990f, 0.993054927874527320f, + -0.117651647774764860f, + 0.993032350197851410f, -0.117842061508324980f, 0.993009736010214580f, + -0.118032470909169340f, + 0.992987085312448390f, -0.118222875970297170f, 0.992964398105385610f, + -0.118413276684707790f, + 0.992941674389860470f, -0.118603673045400720f, 0.992918914166708300f, + -0.118794065045375640f, + 0.992896117436765980f, -0.118984452677632340f, 0.992873284200871730f, + -0.119174835935170880f, + 0.992850414459865100f, -0.119365214810991350f, 0.992827508214586760f, + -0.119555589298094110f, + 0.992804565465879140f, -0.119745959389479600f, 0.992781586214585570f, + -0.119936325078148470f, + 0.992758570461551140f, -0.120126686357101500f, 0.992735518207621850f, + -0.120317043219339680f, + 0.992712429453645460f, -0.120507395657864130f, 0.992689304200470750f, + -0.120697743665676110f, + 0.992666142448948020f, -0.120888087235777080f, 0.992642944199928820f, + -0.121078426361168640f, + 0.992619709454266140f, -0.121268761034852600f, 0.992596438212814290f, + -0.121459091249830840f, + 0.992573130476428810f, -0.121649416999105530f, 0.992549786245966680f, + -0.121839738275678890f, + 0.992526405522286100f, -0.122030055072553360f, 0.992502988306246950f, + -0.122220367382731540f, + 0.992479534598709970f, -0.122410675199216200f, 0.992456044400537700f, + -0.122600978515010240f, + 0.992432517712593660f, -0.122791277323116770f, 0.992408954535742850f, + -0.122981571616539050f, + 0.992385354870851670f, -0.123171861388280480f, 0.992361718718787870f, + -0.123362146631344680f, + 0.992338046080420420f, -0.123552427338735370f, 0.992314336956619640f, + -0.123742703503456510f, + 0.992290591348257370f, -0.123932975118512160f, 0.992266809256206580f, + -0.124123242176906600f, + 0.992242990681341700f, -0.124313504671644230f, 0.992219135624538450f, + -0.124503762595729660f, + 0.992195244086673920f, -0.124694015942167640f, 0.992171316068626520f, + -0.124884264703963130f, + 0.992147351571276090f, -0.125074508874121170f, 0.992123350595503720f, + -0.125264748445647060f, + 0.992099313142191800f, -0.125454983411546230f, 0.992075239212224070f, + -0.125645213764824290f, + 0.992051128806485720f, -0.125835439498487000f, 0.992026981925863360f, + -0.126025660605540320f, + 0.992002798571244520f, -0.126215877078990350f, 0.991978578743518580f, + -0.126406088911843380f, + 0.991954322443575950f, -0.126596296097105850f, 0.991930029672308480f, + -0.126786498627784410f, + 0.991905700430609330f, -0.126976696496885870f, 0.991881334719373010f, + -0.127166889697417160f, + 0.991856932539495470f, -0.127357078222385400f, 0.991832493891873780f, + -0.127547262064797970f, + 0.991808018777406430f, -0.127737441217662310f, 0.991783507196993490f, + -0.127927615673986080f, + 0.991758959151536110f, -0.128117785426777130f, 0.991734374641936810f, + -0.128307950469043420f, + 0.991709753669099530f, -0.128498110793793170f, 0.991685096233929420f, + -0.128688266394034690f, + 0.991660402337333210f, -0.128878417262776550f, 0.991635671980218740f, + -0.129068563393027410f, + 0.991610905163495370f, -0.129258704777796140f, 0.991586101888073500f, + -0.129448841410091780f, + 0.991561262154865290f, -0.129638973282923560f, 0.991536385964783880f, + -0.129829100389300930f, + 0.991511473318743900f, -0.130019222722233350f, 0.991486524217661480f, + -0.130209340274730630f, + 0.991461538662453790f, -0.130399453039802690f, 0.991436516654039420f, + -0.130589561010459650f, + 0.991411458193338540f, -0.130779664179711710f, 0.991386363281272280f, + -0.130969762540569380f, + 0.991361231918763460f, -0.131159856086043270f, 0.991336064106736140f, + -0.131349944809144190f, + 0.991310859846115440f, -0.131540028702883120f, 0.991285619137828200f, + -0.131730107760271160f, + 0.991260341982802440f, -0.131920181974319790f, 0.991235028381967420f, + -0.132110251338040360f, + 0.991209678336254060f, -0.132300315844444650f, 0.991184291846594180f, + -0.132490375486544550f, + 0.991158868913921350f, -0.132680430257352070f, 0.991133409539170170f, + -0.132870480149879430f, + 0.991107913723276890f, -0.133060525157139060f, 0.991082381467178640f, + -0.133250565272143570f, + 0.991056812771814340f, -0.133440600487905680f, 0.991031207638124130f, + -0.133630630797438340f, + 0.991005566067049370f, -0.133820656193754720f, 0.990979888059532740f, + -0.134010676669868130f, + 0.990954173616518500f, -0.134200692218792020f, 0.990928422738951990f, + -0.134390702833540070f, + 0.990902635427780010f, -0.134580708507126170f, 0.990876811683950700f, + -0.134770709232564350f, + 0.990850951508413620f, -0.134960705002868750f, 0.990825054902119470f, + -0.135150695811053850f, + 0.990799121866020370f, -0.135340681650134210f, 0.990773152401069780f, + -0.135530662513124590f, + 0.990747146508222710f, -0.135720638393039910f, 0.990721104188435180f, + -0.135910609282895330f, + 0.990695025442664630f, -0.136100575175706200f, 0.990668910271870100f, + -0.136290536064487960f, + 0.990642758677011570f, -0.136480491942256280f, 0.990616570659050620f, + -0.136670442802027090f, + 0.990590346218950150f, -0.136860388636816380f, 0.990564085357674370f, + -0.137050329439640410f, + 0.990537788076188750f, -0.137240265203515590f, 0.990511454375460290f, + -0.137430195921458550f, + 0.990485084256457090f, -0.137620121586486040f, 0.990458677720148620f, + -0.137810042191615080f, + 0.990432234767505970f, -0.137999957729862790f, 0.990405755399501260f, + -0.138189868194246560f, + 0.990379239617108160f, -0.138379773577783890f, 0.990352687421301450f, + -0.138569673873492500f, + 0.990326098813057330f, -0.138759569074390350f, 0.990299473793353590f, + -0.138949459173495490f, + 0.990272812363169110f, -0.139139344163826200f, 0.990246114523483990f, + -0.139329224038400980f, + 0.990219380275280000f, -0.139519098790238490f, 0.990192609619540030f, + -0.139708968412357550f, + 0.990165802557248400f, -0.139898832897777210f, 0.990138959089390650f, + -0.140088692239516670f, + 0.990112079216953770f, -0.140278546430595420f, 0.990085162940925970f, + -0.140468395464033000f, + 0.990058210262297120f, -0.140658239332849210f, 0.990031221182058000f, + -0.140848078030064080f, + 0.990004195701200910f, -0.141037911548697710f, 0.989977133820719610f, + -0.141227739881770510f, + 0.989950035541608990f, -0.141417563022303020f, 0.989922900864865450f, + -0.141607380963316020f, + 0.989895729791486660f, -0.141797193697830390f, 0.989868522322471580f, + -0.141987001218867290f, + 0.989841278458820530f, -0.142176803519448030f, 0.989813998201535260f, + -0.142366600592594180f, + 0.989786681551618640f, -0.142556392431327340f, 0.989759328510075200f, + -0.142746179028669460f, + 0.989731939077910570f, -0.142935960377642670f, 0.989704513256131850f, + -0.143125736471269190f, + 0.989677051045747210f, -0.143315507302571500f, 0.989649552447766530f, + -0.143505272864572290f, + 0.989622017463200890f, -0.143695033150294470f, 0.989594446093062460f, + -0.143884788152760980f, + 0.989566838338365120f, -0.144074537864995160f, 0.989539194200123930f, + -0.144264282280020440f, + 0.989511513679355190f, -0.144454021390860470f, 0.989483796777076760f, + -0.144643755190539040f, + 0.989456043494307710f, -0.144833483672080210f, 0.989428253832068230f, + -0.145023206828508220f, + 0.989400427791380380f, -0.145212924652847460f, 0.989372565373267010f, + -0.145402637138122570f, + 0.989344666578752640f, -0.145592344277358340f, 0.989316731408863000f, + -0.145782046063579860f, + 0.989288759864625170f, -0.145971742489812210f, 0.989260751947067640f, + -0.146161433549080900f, + 0.989232707657220050f, -0.146351119234411460f, 0.989204626996113780f, + -0.146540799538829760f, + 0.989176509964781010f, -0.146730474455361750f, 0.989148356564255590f, + -0.146920143977033620f, + 0.989120166795572690f, -0.147109808096871820f, 0.989091940659768800f, + -0.147299466807902850f, + 0.989063678157881540f, -0.147489120103153570f, 0.989035379290950310f, + -0.147678767975650970f, + 0.989007044060015270f, -0.147868410418422220f, 0.988978672466118480f, + -0.148058047424494720f, + 0.988950264510302990f, -0.148247678986896030f, 0.988921820193613190f, + -0.148437305098653970f, + 0.988893339517095130f, -0.148626925752796540f, 0.988864822481795640f, + -0.148816540942351920f, + 0.988836269088763540f, -0.149006150660348450f, 0.988807679339048450f, + -0.149195754899814820f, + 0.988779053233701520f, -0.149385353653779720f, 0.988750390773775360f, + -0.149574946915272230f, + 0.988721691960323780f, -0.149764534677321510f, 0.988692956794401940f, + -0.149954116932956960f, + 0.988664185277066230f, -0.150143693675208190f, 0.988635377409374790f, + -0.150333264897105000f, + 0.988606533192386450f, -0.150522830591677400f, 0.988577652627162020f, + -0.150712390751955610f, + 0.988548735714763200f, -0.150901945370970040f, 0.988519782456253270f, + -0.151091494441751300f, + 0.988490792852696590f, -0.151281037957330220f, 0.988461766905159300f, + -0.151470575910737810f, + 0.988432704614708340f, -0.151660108295005310f, 0.988403605982412390f, + -0.151849635103164180f, + 0.988374471009341280f, -0.152039156328246050f, 0.988345299696566150f, + -0.152228671963282740f, + 0.988316092045159690f, -0.152418182001306330f, 0.988286848056195820f, + -0.152607686435349050f, + 0.988257567730749460f, -0.152797185258443440f, 0.988228251069897420f, + -0.152986678463622040f, + 0.988198898074717610f, -0.153176166043917840f, 0.988169508746289060f, + -0.153365647992363880f, + 0.988140083085692570f, -0.153555124301993450f, 0.988110621094009820f, + -0.153744594965840030f, + 0.988081122772324070f, -0.153934059976937350f, 0.988051588121720110f, + -0.154123519328319360f, + 0.988022017143283530f, -0.154312973013020100f, 0.987992409838101880f, + -0.154502421024073940f, + 0.987962766207263420f, -0.154691863354515430f, 0.987933086251858380f, + -0.154881299997379320f, + 0.987903369972977790f, -0.155070730945700510f, 0.987873617371714200f, + -0.155260156192514240f, + 0.987843828449161740f, -0.155449575730855850f, 0.987814003206415550f, + -0.155638989553760900f, + 0.987784141644572180f, -0.155828397654265230f, 0.987754243764729530f, + -0.156017800025404800f, + 0.987724309567986960f, -0.156207196660215900f, 0.987694339055445130f, + -0.156396587551734880f, + 0.987664332228205710f, -0.156585972692998430f, 0.987634289087372160f, + -0.156775352077043350f, + 0.987604209634049160f, -0.156964725696906780f, 0.987574093869342360f, + -0.157154093545625900f, + 0.987543941794359230f, -0.157343455616238250f, 0.987513753410208420f, + -0.157532811901781530f, + 0.987483528717999710f, -0.157722162395293630f, 0.987453267718844560f, + -0.157911507089812660f, + 0.987422970413855410f, -0.158100845978376980f, 0.987392636804146240f, + -0.158290179054025180f, + 0.987362266890832400f, -0.158479506309795960f, 0.987331860675030430f, + -0.158668827738728310f, + 0.987301418157858430f, -0.158858143333861450f, 0.987270939340435420f, + -0.159047453088234760f, + 0.987240424223882250f, -0.159236756994887850f, 0.987209872809320820f, + -0.159426055046860580f, + 0.987179285097874340f, -0.159615347237193060f, 0.987148661090667570f, + -0.159804633558925440f, + 0.987118000788826280f, -0.159993914005098270f, 0.987087304193477900f, + -0.160183188568752220f, + 0.987056571305750970f, -0.160372457242928280f, 0.987025802126775600f, + -0.160561720020667490f, + 0.986994996657682980f, -0.160750976895011220f, 0.986964154899605650f, + -0.160940227859001080f, + 0.986933276853677710f, -0.161129472905678810f, 0.986902362521034470f, + -0.161318712028086400f, + 0.986871411902812470f, -0.161507945219266120f, 0.986840425000149680f, + -0.161697172472260400f, + 0.986809401814185530f, -0.161886393780111830f, 0.986778342346060430f, + -0.162075609135863330f, + 0.986747246596916590f, -0.162264818532558000f, 0.986716114567897100f, + -0.162454021963239190f, + 0.986684946260146690f, -0.162643219420950310f, 0.986653741674811350f, + -0.162832410898735210f, + 0.986622500813038480f, -0.163021596389637840f, 0.986591223675976400f, + -0.163210775886702380f, + 0.986559910264775410f, -0.163399949382973230f, 0.986528560580586690f, + -0.163589116871495020f, + 0.986497174624562880f, -0.163778278345312670f, 0.986465752397857940f, + -0.163967433797471170f, + 0.986434293901627180f, -0.164156583221015810f, 0.986402799137027220f, + -0.164345726608992190f, + 0.986371268105216030f, -0.164534863954446000f, 0.986339700807353000f, + -0.164723995250423170f, + 0.986308097244598670f, -0.164913120489969890f, 0.986276457418115090f, + -0.165102239666132660f, + 0.986244781329065460f, -0.165291352771958000f, 0.986213068978614490f, + -0.165480459800492780f, + 0.986181320367928270f, -0.165669560744784120f, 0.986149535498173860f, + -0.165858655597879300f, + 0.986117714370520090f, -0.166047744352825790f, 0.986085856986136820f, + -0.166236827002671420f, + 0.986053963346195440f, -0.166425903540464100f, 0.986022033451868560f, + -0.166614973959252090f, + 0.985990067304330140f, -0.166804038252083730f, 0.985958064904755460f, + -0.166993096412007710f, + 0.985926026254321130f, -0.167182148432072940f, 0.985893951354205210f, + -0.167371194305328430f, + 0.985861840205586980f, -0.167560234024823560f, 0.985829692809647050f, + -0.167749267583607890f, + 0.985797509167567480f, -0.167938294974731170f, 0.985765289280531310f, + -0.168127316191243410f, + 0.985733033149723490f, -0.168316331226194830f, 0.985700740776329850f, + -0.168505340072635900f, + 0.985668412161537550f, -0.168694342723617330f, 0.985636047306535420f, + -0.168883339172189980f, + 0.985603646212513400f, -0.169072329411405010f, 0.985571208880662740f, + -0.169261313434313830f, + 0.985538735312176060f, -0.169450291233967960f, 0.985506225508247290f, + -0.169639262803419290f, + 0.985473679470071810f, -0.169828228135719850f, 0.985441097198846210f, + -0.170017187223921950f, + 0.985408478695768420f, -0.170206140061078070f, 0.985375823962037710f, + -0.170395086640240940f, + 0.985343132998854790f, -0.170584026954463590f, 0.985310405807421570f, + -0.170772960996799230f, + 0.985277642388941220f, -0.170961888760301220f, 0.985244842744618540f, + -0.171150810238023280f, + 0.985212006875659350f, -0.171339725423019310f, 0.985179134783271130f, + -0.171528634308343420f, + 0.985146226468662230f, -0.171717536887049970f, 0.985113281933042710f, + -0.171906433152193530f, + 0.985080301177623800f, -0.172095323096829010f, 0.985047284203618200f, + -0.172284206714011370f, + 0.985014231012239840f, -0.172473083996795950f, 0.984981141604703960f, + -0.172661954938238270f, + 0.984948015982227030f, -0.172850819531394080f, 0.984914854146027200f, + -0.173039677769319360f, + 0.984881656097323700f, -0.173228529645070320f, 0.984848421837337010f, + -0.173417375151703470f, + 0.984815151367289140f, -0.173606214282275410f, 0.984781844688403350f, + -0.173795047029843160f, + 0.984748501801904210f, -0.173983873387463820f, 0.984715122709017620f, + -0.174172693348194820f, + 0.984681707410970940f, -0.174361506905093750f, 0.984648255908992630f, + -0.174550314051218510f, + 0.984614768204312600f, -0.174739114779627200f, 0.984581244298162180f, + -0.174927909083378160f, + 0.984547684191773960f, -0.175116696955529920f, 0.984514087886381840f, + -0.175305478389141320f, + 0.984480455383220930f, -0.175494253377271430f, 0.984446786683527920f, + -0.175683021912979490f, + 0.984413081788540700f, -0.175871783989325040f, 0.984379340699498510f, + -0.176060539599367820f, + 0.984345563417641900f, -0.176249288736167880f, 0.984311749944212780f, + -0.176438031392785410f, + 0.984277900280454370f, -0.176626767562280880f, 0.984244014427611110f, + -0.176815497237715000f, + 0.984210092386929030f, -0.177004220412148750f, 0.984176134159655320f, + -0.177192937078643280f, + 0.984142139747038570f, -0.177381647230260040f, 0.984108109150328540f, + -0.177570350860060710f, + 0.984074042370776450f, -0.177759047961107170f, 0.984039939409634970f, + -0.177947738526461560f, + 0.984005800268157870f, -0.178136422549186300f, 0.983971624947600270f, + -0.178325100022344000f, + 0.983937413449218920f, -0.178513770938997510f, 0.983903165774271500f, + -0.178702435292209970f, + 0.983868881924017220f, -0.178891093075044720f, 0.983834561899716630f, + -0.179079744280565390f, + 0.983800205702631600f, -0.179268388901835750f, 0.983765813334025240f, + -0.179457026931919890f, + 0.983731384795162090f, -0.179645658363882160f, 0.983696920087308140f, + -0.179834283190787090f, + 0.983662419211730250f, -0.180022901405699510f, 0.983627882169697210f, + -0.180211513001684450f, + 0.983593308962478650f, -0.180400117971807240f, 0.983558699591345900f, + -0.180588716309133340f, + 0.983524054057571260f, -0.180777308006728590f, 0.983489372362428730f, + -0.180965893057658980f, + 0.983454654507193270f, -0.181154471454990810f, 0.983419900493141540f, + -0.181343043191790540f, + 0.983385110321551180f, -0.181531608261124970f, 0.983350283993701500f, + -0.181720166656061110f, + 0.983315421510872810f, -0.181908718369666160f, 0.983280522874346970f, + -0.182097263395007650f, + 0.983245588085407070f, -0.182285801725153300f, 0.983210617145337640f, + -0.182474333353171120f, + 0.983175610055424420f, -0.182662858272129270f, 0.983140566816954500f, + -0.182851376475096330f, + 0.983105487431216290f, -0.183039887955140950f, 0.983070371899499640f, + -0.183228392705332140f, + 0.983035220223095640f, -0.183416890718739100f, 0.983000032403296590f, + -0.183605381988431270f, + 0.982964808441396440f, -0.183793866507478450f, 0.982929548338690170f, + -0.183982344268950520f, + 0.982894252096474070f, -0.184170815265917720f, 0.982858919716046110f, + -0.184359279491450510f, + 0.982823551198705240f, -0.184547736938619620f, 0.982788146545751970f, + -0.184736187600495950f, + 0.982752705758487830f, -0.184924631470150790f, 0.982717228838215990f, + -0.185113068540655540f, + 0.982681715786240860f, -0.185301498805081900f, 0.982646166603868050f, + -0.185489922256501880f, + 0.982610581292404750f, -0.185678338887987630f, 0.982574959853159240f, + -0.185866748692611660f, + 0.982539302287441240f, -0.186055151663446630f, 0.982503608596561830f, + -0.186243547793565560f, + 0.982467878781833170f, -0.186431937076041610f, 0.982432112844569110f, + -0.186620319503948280f, + 0.982396310786084690f, -0.186808695070359270f, 0.982360472607696210f, + -0.186997063768348540f, + 0.982324598310721280f, -0.187185425590990330f, 0.982288687896478830f, + -0.187373780531359110f, + 0.982252741366289370f, -0.187562128582529600f, 0.982216758721474510f, + -0.187750469737576780f, + 0.982180739963357090f, -0.187938803989575910f, 0.982144685093261580f, + -0.188127131331602420f, + 0.982108594112513610f, -0.188315451756732120f, 0.982072467022440000f, + -0.188503765258040940f, + 0.982036303824369020f, -0.188692071828605230f, 0.982000104519630490f, + -0.188880371461501380f, + 0.981963869109555240f, -0.189068664149806190f, 0.981927597595475540f, + -0.189256949886596750f, + 0.981891289978725100f, -0.189445228664950230f, 0.981854946260638630f, + -0.189633500477944190f, + 0.981818566442552500f, -0.189821765318656410f, 0.981782150525804310f, + -0.190010023180164990f, + 0.981745698511732990f, -0.190198274055548150f, 0.981709210401678800f, + -0.190386517937884470f, + 0.981672686196983110f, -0.190574754820252740f, 0.981636125898989080f, + -0.190762984695732110f, + 0.981599529509040720f, -0.190951207557401800f, 0.981562897028483650f, + -0.191139423398341450f, + 0.981526228458664770f, -0.191327632211630900f, 0.981489523800932130f, + -0.191515833990350210f, + 0.981452783056635520f, -0.191704028727579800f, 0.981416006227125550f, + -0.191892216416400220f, + 0.981379193313754560f, -0.192080397049892440f, 0.981342344317876040f, + -0.192268570621137500f, + 0.981305459240844670f, -0.192456737123216840f, 0.981268538084016710f, + -0.192644896549212100f, + 0.981231580848749730f, -0.192833048892205230f, 0.981194587536402320f, + -0.193021194145278380f, + 0.981157558148334830f, -0.193209332301513960f, 0.981120492685908730f, + -0.193397463353994740f, + 0.981083391150486710f, -0.193585587295803610f, 0.981046253543432780f, + -0.193773704120023820f, + 0.981009079866112630f, -0.193961813819738840f, 0.980971870119892840f, + -0.194149916388032450f, + 0.980934624306141640f, -0.194338011817988600f, 0.980897342426228390f, + -0.194526100102691610f, + 0.980860024481523870f, -0.194714181235225960f, 0.980822670473400100f, + -0.194902255208676520f, + 0.980785280403230430f, -0.195090322016128250f, 0.980747854272389750f, + -0.195278381650666550f, + 0.980710392082253970f, -0.195466434105376980f, 0.980672893834200530f, + -0.195654479373345370f, + 0.980635359529608120f, -0.195842517447657850f, 0.980597789169856850f, + -0.196030548321400790f, + 0.980560182756327840f, -0.196218571987660880f, 0.980522540290404090f, + -0.196406588439524970f, + 0.980484861773469380f, -0.196594597670080220f, 0.980447147206909060f, + -0.196782599672414100f, + 0.980409396592109910f, -0.196970594439614340f, 0.980371609930459800f, + -0.197158581964768880f, + 0.980333787223347960f, -0.197346562240965920f, 0.980295928472165290f, + -0.197534535261294030f, + 0.980258033678303550f, -0.197722501018841920f, 0.980220102843156080f, + -0.197910459506698670f, + 0.980182135968117430f, -0.198098410717953560f, 0.980144133054583590f, + -0.198286354645696220f, + 0.980106094103951770f, -0.198474291283016390f, 0.980068019117620650f, + -0.198662220623004200f, + 0.980029908096990090f, -0.198850142658750090f, 0.979991761043461200f, + -0.199038057383344680f, + 0.979953577958436740f, -0.199225964789878830f, 0.979915358843320480f, + -0.199413864871443770f, + 0.979877103699517640f, -0.199601757621130970f, 0.979838812528434740f, + -0.199789643032032090f, + 0.979800485331479790f, -0.199977521097239150f, 0.979762122110061750f, + -0.200165391809844440f, + 0.979723722865591170f, -0.200353255162940450f, 0.979685287599479930f, + -0.200541111149619980f, + 0.979646816313141210f, -0.200728959762976140f, 0.979608309007989450f, + -0.200916800996102230f, + 0.979569765685440520f, -0.201104634842091900f, 0.979531186346911500f, + -0.201292461294039020f, + 0.979492570993820810f, -0.201480280345037730f, 0.979453919627588210f, + -0.201668091988182530f, + 0.979415232249634780f, -0.201855896216568050f, 0.979376508861383170f, + -0.202043693023289260f, + 0.979337749464256780f, -0.202231482401441450f, 0.979298954059681040f, + -0.202419264344120160f, + 0.979260122649082020f, -0.202607038844421130f, 0.979221255233887700f, + -0.202794805895440440f, + 0.979182351815526930f, -0.202982565490274440f, 0.979143412395430230f, + -0.203170317622019790f, + 0.979104436975029250f, -0.203358062283773320f, 0.979065425555756930f, + -0.203545799468632190f, + 0.979026378139047580f, -0.203733529169693920f, 0.978987294726337050f, + -0.203921251380056120f, + 0.978948175319062200f, -0.204108966092816870f, 0.978909019918661310f, + -0.204296673301074370f, + 0.978869828526574120f, -0.204484372997927240f, 0.978830601144241470f, + -0.204672065176474210f, + 0.978791337773105670f, -0.204859749829814420f, 0.978752038414610340f, + -0.205047426951047250f, + 0.978712703070200420f, -0.205235096533272350f, 0.978673331741322210f, + -0.205422758569589610f, + 0.978633924429423210f, -0.205610413053099240f, 0.978594481135952270f, + -0.205798059976901790f, + 0.978555001862359550f, -0.205985699334097910f, 0.978515486610096910f, + -0.206173331117788710f, + 0.978475935380616830f, -0.206360955321075510f, 0.978436348175373730f, + -0.206548571937059890f, + 0.978396724995823090f, -0.206736180958843690f, 0.978357065843421640f, + -0.206923782379529100f, + 0.978317370719627650f, -0.207111376192218560f, 0.978277639625900530f, + -0.207298962390014750f, + 0.978237872563701090f, -0.207486540966020650f, 0.978198069534491400f, + -0.207674111913339570f, + 0.978158230539735050f, -0.207861675225075070f, 0.978118355580896660f, + -0.208049230894330940f, + 0.978078444659442380f, -0.208236778914211330f, 0.978038497776839600f, + -0.208424319277820600f, + 0.977998514934557140f, -0.208611851978263490f, 0.977958496134064830f, + -0.208799377008644900f, + 0.977918441376834370f, -0.208986894362070070f, 0.977878350664338150f, + -0.209174404031644580f, + 0.977838223998050430f, -0.209361906010474160f, 0.977798061379446360f, + -0.209549400291664940f, + 0.977757862810002760f, -0.209736886868323290f, 0.977717628291197460f, + -0.209924365733555880f, + 0.977677357824509930f, -0.210111836880469610f, 0.977637051411420770f, + -0.210299300302171730f, + 0.977596709053411890f, -0.210486755991769720f, 0.977556330751966460f, + -0.210674203942371440f, + 0.977515916508569280f, -0.210861644147084860f, 0.977475466324706170f, + -0.211049076599018390f, + 0.977434980201864260f, -0.211236501291280710f, 0.977394458141532250f, + -0.211423918216980670f, + 0.977353900145199960f, -0.211611327369227550f, 0.977313306214358750f, + -0.211798728741130840f, + 0.977272676350500860f, -0.211986122325800330f, 0.977232010555120320f, + -0.212173508116346080f, + 0.977191308829712280f, -0.212360886105878420f, 0.977150571175773200f, + -0.212548256287508060f, + 0.977109797594800880f, -0.212735618654345930f, 0.977068988088294450f, + -0.212922973199503180f, + 0.977028142657754390f, -0.213110319916091360f, 0.976987261304682390f, + -0.213297658797222320f, + 0.976946344030581670f, -0.213484989836008050f, 0.976905390836956490f, + -0.213672313025560970f, + 0.976864401725312640f, -0.213859628358993750f, 0.976823376697157240f, + -0.214046935829419360f, + 0.976782315753998650f, -0.214234235429950990f, 0.976741218897346550f, + -0.214421527153702160f, + 0.976700086128711840f, -0.214608810993786760f, 0.976658917449606980f, + -0.214796086943318860f, + 0.976617712861545640f, -0.214983354995412820f, 0.976576472366042610f, + -0.215170615143183390f, + 0.976535195964614470f, -0.215357867379745550f, 0.976493883658778650f, + -0.215545111698214500f, + 0.976452535450054060f, -0.215732348091705880f, 0.976411151339961040f, + -0.215919576553335490f, + 0.976369731330021140f, -0.216106797076219520f, 0.976328275421757260f, + -0.216294009653474340f, + 0.976286783616693630f, -0.216481214278216730f, 0.976245255916355800f, + -0.216668410943563730f, + 0.976203692322270560f, -0.216855599642632620f, 0.976162092835966110f, + -0.217042780368540990f, + 0.976120457458971910f, -0.217229953114406790f, 0.976078786192818850f, + -0.217417117873348190f, + 0.976037079039039020f, -0.217604274638483640f, 0.975995335999165990f, + -0.217791423402931950f, + 0.975953557074734300f, -0.217978564159812200f, 0.975911742267280170f, + -0.218165696902243800f, + 0.975869891578341030f, -0.218352821623346320f, 0.975828005009455660f, + -0.218539938316239770f, + 0.975786082562163930f, -0.218727046974044440f, 0.975744124238007270f, + -0.218914147589880840f, + 0.975702130038528570f, -0.219101240156869800f, 0.975660099965271590f, + -0.219288324668132470f, + 0.975618034019781750f, -0.219475401116790310f, 0.975575932203605720f, + -0.219662469495965050f, + 0.975533794518291360f, -0.219849529798778700f, 0.975491620965388110f, + -0.220036582018353580f, + 0.975449411546446380f, -0.220223626147812380f, 0.975407166263018270f, + -0.220410662180277940f, + 0.975364885116656980f, -0.220597690108873510f, 0.975322568108916930f, + -0.220784709926722610f, + 0.975280215241354220f, -0.220971721626949110f, 0.975237826515525820f, + -0.221158725202677010f, + 0.975195401932990370f, -0.221345720647030810f, 0.975152941495307620f, + -0.221532707953135230f, + 0.975110445204038890f, -0.221719687114115220f, 0.975067913060746470f, + -0.221906658123096100f, + 0.975025345066994120f, -0.222093620973203510f, 0.974982741224347140f, + -0.222280575657563370f, + 0.974940101534371830f, -0.222467522169301880f, 0.974897425998635820f, + -0.222654460501545500f, + 0.974854714618708430f, -0.222841390647421120f, 0.974811967396159830f, + -0.223028312600055820f, + 0.974769184332561770f, -0.223215226352576980f, 0.974726365429487320f, + -0.223402131898112370f, + 0.974683510688510670f, -0.223589029229789990f, 0.974640620111207560f, + -0.223775918340738150f, + 0.974597693699155050f, -0.223962799224085460f, 0.974554731453931230f, + -0.224149671872960870f, + 0.974511733377115720f, -0.224336536280493600f, 0.974468699470289580f, + -0.224523392439813170f, + 0.974425629735034990f, -0.224710240344049430f, 0.974382524172935470f, + -0.224897079986332490f, + 0.974339382785575860f, -0.225083911359792830f, 0.974296205574542440f, + -0.225270734457561160f, + 0.974252992541422500f, -0.225457549272768540f, 0.974209743687805220f, + -0.225644355798546330f, + 0.974166459015280320f, -0.225831154028026170f, 0.974123138525439640f, + -0.226017943954340020f, + 0.974079782219875680f, -0.226204725570620190f, 0.974036390100182610f, + -0.226391498869999240f, + 0.973992962167955830f, -0.226578263845610000f, 0.973949498424792170f, + -0.226765020490585690f, + 0.973905998872289570f, -0.226951768798059810f, 0.973862463512047300f, + -0.227138508761166170f, + 0.973818892345666100f, -0.227325240373038860f, 0.973775285374748110f, + -0.227511963626812280f, + 0.973731642600896400f, -0.227698678515621170f, 0.973687964025715670f, + -0.227885385032600530f, + 0.973644249650811980f, -0.228072083170885730f, 0.973600499477792370f, + -0.228258772923612380f, + 0.973556713508265560f, -0.228445454283916470f, 0.973512891743841370f, + -0.228632127244934230f, + 0.973469034186131070f, -0.228818791799802220f, 0.973425140836747030f, + -0.229005447941657340f, + 0.973381211697303290f, -0.229192095663636770f, 0.973337246769414910f, + -0.229378734958878010f, + 0.973293246054698250f, -0.229565365820518870f, 0.973249209554771230f, + -0.229751988241697490f, + 0.973205137271252800f, -0.229938602215552210f, 0.973161029205763530f, + -0.230125207735221850f, + 0.973116885359925130f, -0.230311804793845440f, 0.973072705735360530f, + -0.230498393384562350f, + 0.973028490333694210f, -0.230684973500512200f, 0.972984239156551740f, + -0.230871545134835020f, + 0.972939952205560180f, -0.231058108280671110f, 0.972895629482347760f, + -0.231244662931161050f, + 0.972851270988544180f, -0.231431209079445750f, 0.972806876725780370f, + -0.231617746718666470f, + 0.972762446695688570f, -0.231804275841964780f, 0.972717980899902250f, + -0.231990796442482440f, + 0.972673479340056430f, -0.232177308513361710f, 0.972628942017787270f, + -0.232363812047745030f, + 0.972584368934732210f, -0.232550307038775240f, 0.972539760092530180f, + -0.232736793479595390f, + 0.972495115492821190f, -0.232923271363348980f, 0.972450435137246830f, + -0.233109740683179690f, + 0.972405719027449770f, -0.233296201432231590f, 0.972360967165074140f, + -0.233482653603649090f, + 0.972316179551765300f, -0.233669097190576820f, 0.972271356189170040f, + -0.233855532186159840f, + 0.972226497078936270f, -0.234041958583543430f, 0.972181602222713440f, + -0.234228376375873210f, + 0.972136671622152230f, -0.234414785556295160f, 0.972091705278904430f, + -0.234601186117955550f, + 0.972046703194623500f, -0.234787578054000970f, 0.972001665370963890f, + -0.234973961357578250f, + 0.971956591809581720f, -0.235160336021834730f, 0.971911482512134000f, + -0.235346702039917840f, + 0.971866337480279400f, -0.235533059404975490f, 0.971821156715677700f, + -0.235719408110155820f, + 0.971775940219990140f, -0.235905748148607370f, 0.971730687994879160f, + -0.236092079513478910f, + 0.971685400042008540f, -0.236278402197919570f, 0.971640076363043390f, + -0.236464716195078780f, + 0.971594716959650160f, -0.236651021498106380f, 0.971549321833496630f, + -0.236837318100152380f, + 0.971503890986251780f, -0.237023605994367200f, 0.971458424419585960f, + -0.237209885173901600f, + 0.971412922135170940f, -0.237396155631906610f, 0.971367384134679490f, + -0.237582417361533570f, + 0.971321810419786160f, -0.237768670355934190f, 0.971276200992166490f, + -0.237954914608260540f, + 0.971230555853497380f, -0.238141150111664840f, 0.971184875005457030f, + -0.238327376859299810f, + 0.971139158449725090f, -0.238513594844318420f, 0.971093406187982460f, + -0.238699804059873980f, + 0.971047618221911100f, -0.238886004499120040f, 0.971001794553194690f, + -0.239072196155210610f, + 0.970955935183517970f, -0.239258379021299980f, 0.970910040114567050f, + -0.239444553090542630f, + 0.970864109348029470f, -0.239630718356093560f, 0.970818142885593870f, + -0.239816874811108000f, + 0.970772140728950350f, -0.240003022448741500f, 0.970726102879790110f, + -0.240189161262149900f, + 0.970680029339806130f, -0.240375291244489450f, 0.970633920110692160f, + -0.240561412388916650f, + 0.970587775194143630f, -0.240747524688588430f, 0.970541594591857070f, + -0.240933628136661910f, + 0.970495378305530560f, -0.241119722726294590f, 0.970449126336863090f, + -0.241305808450644370f, + 0.970402838687555500f, -0.241491885302869330f, 0.970356515359309450f, + -0.241677953276128010f, + 0.970310156353828110f, -0.241864012363579180f, 0.970263761672816140f, + -0.242050062558382070f, + 0.970217331317979160f, -0.242236103853696010f, 0.970170865291024480f, + -0.242422136242680890f, + 0.970124363593660280f, -0.242608159718496810f, 0.970077826227596420f, + -0.242794174274304220f, + 0.970031253194543970f, -0.242980179903263870f, 0.969984644496215240f, + -0.243166176598536900f, + 0.969938000134323960f, -0.243352164353284740f, 0.969891320110585100f, + -0.243538143160669130f, + 0.969844604426714830f, -0.243724113013852160f, 0.969797853084430890f, + -0.243910073905996260f, + 0.969751066085452140f, -0.244096025830264210f, 0.969704243431498860f, + -0.244281968779819030f, + 0.969657385124292450f, -0.244467902747824150f, 0.969610491165555870f, + -0.244653827727443320f, + 0.969563561557013180f, -0.244839743711840670f, 0.969516596300390000f, + -0.245025650694180470f, + 0.969469595397413060f, -0.245211548667627540f, 0.969422558849810320f, + -0.245397437625346960f, + 0.969375486659311280f, -0.245583317560504060f, 0.969328378827646660f, + -0.245769188466264580f, + 0.969281235356548530f, -0.245955050335794590f, 0.969234056247750050f, + -0.246140903162260530f, + 0.969186841502985950f, -0.246326746938829030f, 0.969139591123992280f, + -0.246512581658667210f, + 0.969092305112506210f, -0.246698407314942410f, 0.969044983470266240f, + -0.246884223900822430f, + 0.968997626199012420f, -0.247070031409475250f, 0.968950233300485800f, + -0.247255829834069300f, + 0.968902804776428870f, -0.247441619167773270f, 0.968855340628585580f, + -0.247627399403756280f, + 0.968807840858700970f, -0.247813170535187670f, 0.968760305468521430f, + -0.247998932555237110f, + 0.968712734459794780f, -0.248184685457074780f, 0.968665127834270060f, + -0.248370429233870980f, + 0.968617485593697540f, -0.248556163878796560f, 0.968569807739828930f, + -0.248741889385022480f, + 0.968522094274417380f, -0.248927605745720150f, 0.968474345199216820f, + -0.249113312954061360f, + 0.968426560515983190f, -0.249299011003218190f, 0.968378740226473300f, + -0.249484699886362960f, + 0.968330884332445190f, -0.249670379596668550f, 0.968282992835658660f, + -0.249856050127307990f, + 0.968235065737874320f, -0.250041711471454650f, 0.968187103040854420f, + -0.250227363622282370f, + 0.968139104746362440f, -0.250413006572965220f, 0.968091070856162970f, + -0.250598640316677670f, + 0.968043001372022260f, -0.250784264846594500f, 0.967994896295707670f, + -0.250969880155890720f, + 0.967946755628987800f, -0.251155486237741920f, 0.967898579373632660f, + -0.251341083085323880f, + 0.967850367531413620f, -0.251526670691812610f, 0.967802120104103270f, + -0.251712249050384700f, + 0.967753837093475510f, -0.251897818154216970f, 0.967705518501305480f, + -0.252083377996486450f, + 0.967657164329369880f, -0.252268928570370810f, 0.967608774579446500f, + -0.252454469869047740f, + 0.967560349253314360f, -0.252640001885695520f, 0.967511888352754150f, + -0.252825524613492610f, + 0.967463391879547550f, -0.253011038045617860f, 0.967414859835477480f, + -0.253196542175250560f, + 0.967366292222328510f, -0.253382036995570160f, 0.967317689041886310f, + -0.253567522499756560f, + 0.967269050295937790f, -0.253752998680989990f, 0.967220375986271420f, + -0.253938465532451090f, + 0.967171666114676640f, -0.254123923047320620f, 0.967122920682944360f, + -0.254309371218780000f, + 0.967074139692867040f, -0.254494810040010730f, 0.967025323146238010f, + -0.254680239504194830f, + 0.966976471044852070f, -0.254865659604514570f, 0.966927583390505660f, + -0.255051070334152470f, + 0.966878660184995910f, -0.255236471686291710f, 0.966829701430121810f, + -0.255421863654115460f, + 0.966780707127683270f, -0.255607246230807380f, 0.966731677279481840f, + -0.255792619409551610f, + 0.966682611887320080f, -0.255977983183532430f, 0.966633510953002100f, + -0.256163337545934460f, + 0.966584374478333120f, -0.256348682489942910f, 0.966535202465119700f, + -0.256534018008743040f, + 0.966485994915169840f, -0.256719344095520660f, 0.966436751830292650f, + -0.256904660743461910f, + 0.966387473212298900f, -0.257089967945753120f, 0.966338159063000130f, + -0.257275265695581120f, + 0.966288809384209690f, -0.257460553986133100f, 0.966239424177741890f, + -0.257645832810596390f, + 0.966190003445412500f, -0.257831102162158990f, 0.966140547189038750f, + -0.258016362034009020f, + 0.966091055410438830f, -0.258201612419334870f, 0.966041528111432400f, + -0.258386853311325600f, + 0.965991965293840570f, -0.258572084703170340f, 0.965942366959485540f, + -0.258757306588058680f, + 0.965892733110190860f, -0.258942518959180520f, 0.965843063747781510f, + -0.259127721809726150f, + 0.965793358874083680f, -0.259312915132886230f, 0.965743618490924830f, + -0.259498098921851660f, + 0.965693842600133690f, -0.259683273169813770f, 0.965644031203540590f, + -0.259868437869964270f, + 0.965594184302976830f, -0.260053593015495190f, 0.965544301900275180f, + -0.260238738599598840f, + 0.965494383997269500f, -0.260423874615468010f, 0.965444430595795430f, + -0.260609001056295750f, + 0.965394441697689400f, -0.260794117915275510f, 0.965344417304789370f, + -0.260979225185601070f, + 0.965294357418934660f, -0.261164322860466480f, 0.965244262041965780f, + -0.261349410933066350f, + 0.965194131175724720f, -0.261534489396595520f, 0.965143964822054450f, + -0.261719558244249030f, + 0.965093762982799590f, -0.261904617469222610f, 0.965043525659805890f, + -0.262089667064712040f, + 0.964993252854920320f, -0.262274707023913590f, 0.964942944569991410f, + -0.262459737340023980f, + 0.964892600806868890f, -0.262644758006240040f, 0.964842221567403620f, + -0.262829769015759160f, + 0.964791806853447900f, -0.263014770361779000f, 0.964741356666855340f, + -0.263199762037497560f, + 0.964690871009481030f, -0.263384744036113280f, 0.964640349883180930f, + -0.263569716350824880f, + 0.964589793289812760f, -0.263754678974831350f, 0.964539201231235150f, + -0.263939631901332350f, + 0.964488573709308410f, -0.264124575123527550f, 0.964437910725893910f, + -0.264309508634617110f, + 0.964387212282854290f, -0.264494432427801630f, 0.964336478382053720f, + -0.264679346496281890f, + 0.964285709025357480f, -0.264864250833259260f, 0.964234904214632200f, + -0.265049145431935250f, + 0.964184063951745830f, -0.265234030285511790f, 0.964133188238567640f, + -0.265418905387191260f, + 0.964082277076968140f, -0.265603770730176330f, 0.964031330468819280f, + -0.265788626307669920f, + 0.963980348415994110f, -0.265973472112875590f, 0.963929330920367140f, + -0.266158308138996990f, + 0.963878277983814200f, -0.266343134379238180f, 0.963827189608212340f, + -0.266527950826803690f, + 0.963776065795439840f, -0.266712757474898370f, 0.963724906547376530f, + -0.266897554316727350f, + 0.963673711865903230f, -0.267082341345496300f, 0.963622481752902220f, + -0.267267118554410930f, + 0.963571216210257320f, -0.267451885936677620f, 0.963519915239853140f, + -0.267636643485503090f, + 0.963468578843575950f, -0.267821391194094150f, 0.963417207023313350f, + -0.268006129055658290f, + 0.963365799780954050f, -0.268190857063403180f, 0.963314357118388200f, + -0.268375575210536900f, + 0.963262879037507070f, -0.268560283490267890f, 0.963211365540203480f, + -0.268744981895804980f, + 0.963159816628371360f, -0.268929670420357260f, 0.963108232303906190f, + -0.269114349057134380f, + 0.963056612568704340f, -0.269299017799346120f, 0.963004957424663850f, + -0.269483676640202840f, + 0.962953266873683880f, -0.269668325572915090f, 0.962901540917665000f, + -0.269852964590693860f, + 0.962849779558509030f, -0.270037593686750570f, 0.962797982798119010f, + -0.270222212854296870f, + 0.962746150638399410f, -0.270406822086544820f, 0.962694283081255930f, + -0.270591421376706940f, + 0.962642380128595710f, -0.270776010717996010f, 0.962590441782326890f, + -0.270960590103625170f, + 0.962538468044359160f, -0.271145159526808010f, 0.962486458916603450f, + -0.271329718980758420f, + 0.962434414400972100f, -0.271514268458690700f, 0.962382334499378380f, + -0.271698807953819510f, + 0.962330219213737400f, -0.271883337459359720f, 0.962278068545965090f, + -0.272067856968526920f, + 0.962225882497979020f, -0.272252366474536710f, 0.962173661071697880f, + -0.272436865970605240f, + 0.962121404269041580f, -0.272621355449948980f, 0.962069112091931580f, + -0.272805834905784810f, + 0.962016784542290560f, -0.272990304331329920f, 0.961964421622042320f, + -0.273174763719801930f, + 0.961912023333112210f, -0.273359213064418680f, 0.961859589677426570f, + -0.273543652358398730f, + 0.961807120656913540f, -0.273728081594960540f, 0.961754616273502010f, + -0.273912500767323260f, + 0.961702076529122540f, -0.274096909868706380f, 0.961649501425706820f, + -0.274281308892329660f, + 0.961596890965187860f, -0.274465697831413220f, 0.961544245149499990f, + -0.274650076679177680f, + 0.961491563980579000f, -0.274834445428843940f, 0.961438847460361680f, + -0.275018804073633220f, + 0.961386095590786250f, -0.275203152606767310f, 0.961333308373792270f, + -0.275387491021468140f, + 0.961280485811320640f, -0.275571819310958140f, 0.961227627905313460f, + -0.275756137468460120f, + 0.961174734657714080f, -0.275940445487197150f, 0.961121806070467380f, + -0.276124743360392830f, + 0.961068842145519350f, -0.276309031081271080f, 0.961015842884817230f, + -0.276493308643055990f, + 0.960962808290309780f, -0.276677576038972420f, 0.960909738363946770f, + -0.276861833262245280f, + 0.960856633107679660f, -0.277046080306099900f, 0.960803492523460760f, + -0.277230317163762170f, + 0.960750316613243950f, -0.277414543828458090f, 0.960697105378984450f, + -0.277598760293414290f, + 0.960643858822638590f, -0.277782966551857690f, 0.960590576946164120f, + -0.277967162597015370f, + 0.960537259751520050f, -0.278151348422115090f, 0.960483907240666790f, + -0.278335524020384920f, + 0.960430519415565790f, -0.278519689385053060f, 0.960377096278180130f, + -0.278703844509348490f, + 0.960323637830473920f, -0.278887989386500280f, 0.960270144074412800f, + -0.279072124009737800f, + 0.960216615011963430f, -0.279256248372291180f, 0.960163050645094000f, + -0.279440362467390510f, + 0.960109450975773940f, -0.279624466288266590f, 0.960055816005973890f, + -0.279808559828150390f, + 0.960002145737665960f, -0.279992643080273220f, 0.959948440172823210f, + -0.280176716037866980f, + 0.959894699313420530f, -0.280360778694163810f, 0.959840923161433770f, + -0.280544831042396250f, + 0.959787111718839900f, -0.280728873075797190f, 0.959733264987617680f, + -0.280912904787600000f, + 0.959679382969746750f, -0.281096926171038260f, 0.959625465667208190f, + -0.281280937219346110f, + 0.959571513081984520f, -0.281464937925757940f, 0.959517525216059260f, + -0.281648928283508630f, + 0.959463502071417510f, -0.281832908285833350f, 0.959409443650045550f, + -0.282016877925967640f, + 0.959355349953930790f, -0.282200837197147560f, 0.959301220985062210f, + -0.282384786092609360f, + 0.959247056745430090f, -0.282568724605589740f, 0.959192857237025740f, + -0.282752652729325930f, + 0.959138622461841890f, -0.282936570457055390f, 0.959084352421872730f, + -0.283120477782015820f, + 0.959030047119113660f, -0.283304374697445740f, 0.958975706555561080f, + -0.283488261196583550f, + 0.958921330733213170f, -0.283672137272668430f, 0.958866919654069010f, + -0.283856002918939750f, + 0.958812473320129310f, -0.284039858128637190f, 0.958757991733395710f, + -0.284223702895001040f, + 0.958703474895871600f, -0.284407537211271880f, 0.958648922809561150f, + -0.284591361070690440f, + 0.958594335476470220f, -0.284775174466498300f, 0.958539712898605730f, + -0.284958977391937040f, + 0.958485055077976100f, -0.285142769840248670f, 0.958430362016590930f, + -0.285326551804675870f, + 0.958375633716461170f, -0.285510323278461260f, 0.958320870179598880f, + -0.285694084254848320f, + 0.958266071408017670f, -0.285877834727080620f, 0.958211237403732260f, + -0.286061574688402040f, + 0.958156368168758820f, -0.286245304132057120f, 0.958101463705114730f, + -0.286429023051290700f, + 0.958046524014818600f, -0.286612731439347790f, 0.957991549099890370f, + -0.286796429289474080f, + 0.957936538962351420f, -0.286980116594915570f, 0.957881493604224370f, + -0.287163793348918390f, + 0.957826413027532910f, -0.287347459544729510f, 0.957771297234302320f, + -0.287531115175595930f, + 0.957716146226558870f, -0.287714760234765170f, 0.957660960006330610f, + -0.287898394715485170f, + 0.957605738575646350f, -0.288082018611004130f, 0.957550481936536470f, + -0.288265631914570770f, + 0.957495190091032570f, -0.288449234619434220f, 0.957439863041167680f, + -0.288632826718843830f, + 0.957384500788975860f, -0.288816408206049480f, 0.957329103336492790f, + -0.288999979074301420f, + 0.957273670685755200f, -0.289183539316850200f, 0.957218202838801210f, + -0.289367088926947010f, + 0.957162699797670210f, -0.289550627897843030f, 0.957107161564402790f, + -0.289734156222790250f, + 0.957051588141040970f, -0.289917673895040750f, 0.956995979529628230f, + -0.290101180907847090f, + 0.956940335732208820f, -0.290284677254462330f, 0.956884656750828900f, + -0.290468162928139820f, + 0.956828942587535370f, -0.290651637922133220f, 0.956773193244376930f, + -0.290835102229696830f, + 0.956717408723403050f, -0.291018555844085090f, 0.956661589026665090f, + -0.291201998758552900f, + 0.956605734156215080f, -0.291385430966355660f, 0.956549844114106820f, + -0.291568852460749040f, + 0.956493918902395100f, -0.291752263234989260f, 0.956437958523136180f, + -0.291935663282332780f, + 0.956381962978387730f, -0.292119052596036380f, 0.956325932270208230f, + -0.292302431169357560f, + 0.956269866400658030f, -0.292485798995553880f, 0.956213765371798470f, + -0.292669156067883460f, + 0.956157629185692140f, -0.292852502379604810f, 0.956101457844403040f, + -0.293035837923976810f, + 0.956045251349996410f, -0.293219162694258630f, 0.955989009704538930f, + -0.293402476683710110f, + 0.955932732910098280f, -0.293585779885591200f, 0.955876420968743590f, + -0.293769072293162400f, + 0.955820073882545420f, -0.293952353899684660f, 0.955763691653575440f, + -0.294135624698419030f, + 0.955707274283906560f, -0.294318884682627400f, 0.955650821775613330f, + -0.294502133845571670f, + 0.955594334130771110f, -0.294685372180514330f, 0.955537811351456880f, + -0.294868599680718270f, + 0.955481253439748770f, -0.295051816339446720f, 0.955424660397726330f, + -0.295235022149963220f, + 0.955368032227470350f, -0.295418217105532010f, 0.955311368931062720f, + -0.295601401199417360f, + 0.955254670510586990f, -0.295784574424884260f, 0.955197936968127710f, + -0.295967736775197890f, + 0.955141168305770780f, -0.296150888243623790f, 0.955084364525603410f, + -0.296334028823428190f, + 0.955027525629714160f, -0.296517158507877470f, 0.954970651620192790f, + -0.296700277290238350f, + 0.954913742499130520f, -0.296883385163778270f, 0.954856798268619580f, + -0.297066482121764730f, + 0.954799818930753720f, -0.297249568157465840f, 0.954742804487627940f, + -0.297432643264150030f, + 0.954685754941338340f, -0.297615707435086200f, 0.954628670293982680f, + -0.297798760663543550f, + 0.954571550547659630f, -0.297981802942791810f, 0.954514395704469500f, + -0.298164834266100850f, + 0.954457205766513490f, -0.298347854626741400f, 0.954399980735894490f, + -0.298530864017984120f, + 0.954342720614716480f, -0.298713862433100330f, 0.954285425405084650f, + -0.298896849865361800f, + 0.954228095109105670f, -0.299079826308040480f, 0.954170729728887280f, + -0.299262791754408840f, + 0.954113329266538800f, -0.299445746197739890f, 0.954055893724170660f, + -0.299628689631306790f, + 0.953998423103894490f, -0.299811622048383350f, 0.953940917407823500f, + -0.299994543442243580f, + 0.953883376638071770f, -0.300177453806161950f, 0.953825800796755050f, + -0.300360353133413530f, + 0.953768189885990330f, -0.300543241417273450f, 0.953710543907895670f, + -0.300726118651017500f, + 0.953652862864590500f, -0.300908984827921890f, 0.953595146758195680f, + -0.301091839941263100f, + 0.953537395590833280f, -0.301274683984317950f, 0.953479609364626610f, + -0.301457516950363940f, + 0.953421788081700310f, -0.301640338832678770f, 0.953363931744180330f, + -0.301823149624540650f, + 0.953306040354193860f, -0.302005949319228080f, 0.953248113913869320f, + -0.302188737910019990f, + 0.953190152425336670f, -0.302371515390195970f, 0.953132155890726750f, + -0.302554281753035610f, + 0.953074124312172200f, -0.302737036991819140f, 0.953016057691806530f, + -0.302919781099827310f, + 0.952957956031764700f, -0.303102514070341060f, 0.952899819334182880f, + -0.303285235896641750f, + 0.952841647601198720f, -0.303467946572011320f, 0.952783440834950920f, + -0.303650646089731910f, + 0.952725199037579570f, -0.303833334443086360f, 0.952666922211226170f, + -0.304016011625357570f, + 0.952608610358033350f, -0.304198677629829110f, 0.952550263480144930f, + -0.304381332449784880f, + 0.952491881579706320f, -0.304563976078509100f, 0.952433464658864030f, + -0.304746608509286530f, + 0.952375012719765880f, -0.304929229735402370f, 0.952316525764560940f, + -0.305111839750142110f, + 0.952258003795399600f, -0.305294438546791670f, 0.952199446814433580f, + -0.305477026118637420f, + 0.952140854823815830f, -0.305659602458966120f, 0.952082227825700620f, + -0.305842167561065080f, + 0.952023565822243570f, -0.306024721418221790f, 0.951964868815601380f, + -0.306207264023724220f, + 0.951906136807932350f, -0.306389795370860920f, 0.951847369801395620f, + -0.306572315452920740f, + 0.951788567798152130f, -0.306754824263192780f, 0.951729730800363830f, + -0.306937321794966910f, + 0.951670858810193860f, -0.307119808041533100f, 0.951611951829806850f, + -0.307302282996181790f, + 0.951553009861368590f, -0.307484746652204100f, 0.951494032907046370f, + -0.307667199002891190f, + 0.951435020969008340f, -0.307849640041534870f, 0.951375974049424420f, + -0.308032069761427330f, + 0.951316892150465550f, -0.308214488155861050f, 0.951257775274304000f, + -0.308396895218129190f, + 0.951198623423113230f, -0.308579290941525090f, 0.951139436599068190f, + -0.308761675319342450f, + 0.951080214804345010f, -0.308944048344875710f, 0.951020958041121080f, + -0.309126410011419440f, + 0.950961666311575080f, -0.309308760312268730f, 0.950902339617887060f, + -0.309491099240719100f, + 0.950842977962238160f, -0.309673426790066380f, 0.950783581346811070f, + -0.309855742953607070f, + 0.950724149773789610f, -0.310038047724637890f, 0.950664683245358910f, + -0.310220341096455850f, + 0.950605181763705340f, -0.310402623062358720f, 0.950545645331016600f, + -0.310584893615644450f, + 0.950486073949481700f, -0.310767152749611470f, 0.950426467621290900f, + -0.310949400457558640f, + 0.950366826348635780f, -0.311131636732785270f, 0.950307150133709260f, + -0.311313861568590920f, + 0.950247438978705230f, -0.311496074958275910f, 0.950187692885819280f, + -0.311678276895140550f, + 0.950127911857248100f, -0.311860467372486020f, 0.950068095895189590f, + -0.312042646383613510f, + 0.950008245001843000f, -0.312224813921824880f, 0.949948359179409010f, + -0.312406969980422440f, + 0.949888438430089300f, -0.312589114552708710f, 0.949828482756087110f, + -0.312771247631986770f, + 0.949768492159606680f, -0.312953369211560200f, 0.949708466642853800f, + -0.313135479284732840f, + 0.949648406208035480f, -0.313317577844809010f, 0.949588310857359950f, + -0.313499664885093510f, + 0.949528180593036670f, -0.313681740398891520f, 0.949468015417276550f, + -0.313863804379508500f, + 0.949407815332291570f, -0.314045856820250710f, 0.949347580340295210f, + -0.314227897714424440f, + 0.949287310443502120f, -0.314409927055336660f, 0.949227005644128210f, + -0.314591944836294660f, + 0.949166665944390700f, -0.314773951050606070f, 0.949106291346508260f, + -0.314955945691579140f, + 0.949045881852700560f, -0.315137928752522440f, 0.948985437465188710f, + -0.315319900226744890f, + 0.948924958186195160f, -0.315501860107555990f, 0.948864444017943340f, + -0.315683808388265650f, + 0.948803894962658490f, -0.315865745062183960f, 0.948743311022566480f, + -0.316047670122621860f, + 0.948682692199895090f, -0.316229583562890330f, 0.948622038496872990f, + -0.316411485376300980f, + 0.948561349915730270f, -0.316593375556165850f, 0.948500626458698260f, + -0.316775254095797270f, + 0.948439868128009620f, -0.316957120988508150f, 0.948379074925898120f, + -0.317138976227611780f, + 0.948318246854599090f, -0.317320819806421740f, 0.948257383916349060f, + -0.317502651718252260f, + 0.948196486113385580f, -0.317684471956417970f, 0.948135553447947980f, + -0.317866280514233660f, + 0.948074585922276230f, -0.318048077385014950f, 0.948013583538612200f, + -0.318229862562077530f, + 0.947952546299198670f, -0.318411636038737790f, 0.947891474206279840f, + -0.318593397808312420f, + 0.947830367262101010f, -0.318775147864118480f, 0.947769225468909180f, + -0.318956886199473650f, + 0.947708048828952100f, -0.319138612807695900f, 0.947646837344479300f, + -0.319320327682103610f, + 0.947585591017741090f, -0.319502030816015690f, 0.947524309850989570f, + -0.319683722202751430f, + 0.947462993846477700f, -0.319865401835630500f, 0.947401643006459900f, + -0.320047069707973140f, + 0.947340257333192050f, -0.320228725813099860f, 0.947278836828930880f, + -0.320410370144331820f, + 0.947217381495934820f, -0.320592002694990330f, 0.947155891336463270f, + -0.320773623458397330f, + 0.947094366352777220f, -0.320955232427875210f, 0.947032806547138620f, + -0.321136829596746660f, + 0.946971211921810880f, -0.321318414958334850f, 0.946909582479058760f, + -0.321499988505963510f, + 0.946847918221148000f, -0.321681550232956580f, 0.946786219150346000f, + -0.321863100132638580f, + 0.946724485268921170f, -0.322044638198334510f, 0.946662716579143360f, + -0.322226164423369600f, + 0.946600913083283530f, -0.322407678801069850f, 0.946539074783614100f, + -0.322589181324761330f, + 0.946477201682408680f, -0.322770671987770710f, 0.946415293781942110f, + -0.322952150783425260f, + 0.946353351084490590f, -0.323133617705052330f, 0.946291373592331620f, + -0.323315072745979980f, + 0.946229361307743820f, -0.323496515899536710f, 0.946167314233007370f, + -0.323677947159051240f, + 0.946105232370403450f, -0.323859366517852850f, 0.946043115722214560f, + -0.324040773969271450f, + 0.945980964290724760f, -0.324222169506636960f, 0.945918778078219110f, + -0.324403553123280230f, + 0.945856557086983910f, -0.324584924812532150f, 0.945794301319306970f, + -0.324766284567724220f, + 0.945732010777477150f, -0.324947632382188430f, 0.945669685463784710f, + -0.325128968249257080f, + 0.945607325380521280f, -0.325310292162262930f, 0.945544930529979680f, + -0.325491604114539310f, + 0.945482500914453740f, -0.325672904099419850f, 0.945420036536239070f, + -0.325854192110238580f, + 0.945357537397632290f, -0.326035468140330240f, 0.945295003500931210f, + -0.326216732183029710f, + 0.945232434848435000f, -0.326397984231672490f, 0.945169831442444150f, + -0.326579224279594400f, + 0.945107193285260610f, -0.326760452320131730f, 0.945044520379187070f, + -0.326941668346621420f, + 0.944981812726528150f, -0.327122872352400510f, 0.944919070329589220f, + -0.327304064330806670f, + 0.944856293190677210f, -0.327485244275178000f, 0.944793481312100280f, + -0.327666412178853120f, + 0.944730634696167800f, -0.327847568035170840f, 0.944667753345190490f, + -0.328028711837470680f, + 0.944604837261480260f, -0.328209843579092500f, 0.944541886447350490f, + -0.328390963253376580f, + 0.944478900905115550f, -0.328572070853663740f, 0.944415880637091250f, + -0.328753166373294990f, + 0.944352825645594750f, -0.328934249805612200f, 0.944289735932944410f, + -0.329115321143957250f, + 0.944226611501459810f, -0.329296380381672750f, 0.944163452353461770f, + -0.329477427512101740f, + 0.944100258491272660f, -0.329658462528587490f, 0.944037029917215830f, + -0.329839485424473940f, + 0.943973766633615980f, -0.330020496193105420f, 0.943910468642799150f, + -0.330201494827826570f, + 0.943847135947092690f, -0.330382481321982780f, 0.943783768548825060f, + -0.330563455668919540f, + 0.943720366450326200f, -0.330744417861982890f, 0.943656929653927220f, + -0.330925367894519540f, + 0.943593458161960390f, -0.331106305759876430f, 0.943529951976759480f, + -0.331287231451400820f, + 0.943466411100659320f, -0.331468144962440870f, 0.943402835535996240f, + -0.331649046286344670f, + 0.943339225285107720f, -0.331829935416461110f, 0.943275580350332540f, + -0.332010812346139380f, + 0.943211900734010620f, -0.332191677068729150f, 0.943148186438483420f, + -0.332372529577580620f, + 0.943084437466093490f, -0.332553369866044220f, 0.943020653819184650f, + -0.332734197927471050f, + 0.942956835500102120f, -0.332915013755212650f, 0.942892982511192250f, + -0.333095817342620780f, + 0.942829094854802710f, -0.333276608683047930f, 0.942765172533282510f, + -0.333457387769846850f, + 0.942701215548981900f, -0.333638154596370860f, 0.942637223904252530f, + -0.333818909155973620f, + 0.942573197601446870f, -0.333999651442009380f, 0.942509136642919240f, + -0.334180381447832690f, + 0.942445041031024890f, -0.334361099166798740f, 0.942380910768120470f, + -0.334541804592262900f, + 0.942316745856563780f, -0.334722497717581220f, 0.942252546298714020f, + -0.334903178536110180f, + 0.942188312096931770f, -0.335083847041206580f, 0.942124043253578570f, + -0.335264503226227810f, + 0.942059739771017310f, -0.335445147084531600f, 0.941995401651612550f, + -0.335625778609476290f, + 0.941931028897729620f, -0.335806397794420450f, 0.941866621511735280f, + -0.335987004632723350f, + 0.941802179495997650f, -0.336167599117744520f, 0.941737702852886160f, + -0.336348181242844050f, + 0.941673191584771360f, -0.336528751001382410f, 0.941608645694025250f, + -0.336709308386720580f, + 0.941544065183020810f, -0.336889853392220050f, 0.941479450054132580f, + -0.337070386011242620f, + 0.941414800309736340f, -0.337250906237150590f, 0.941350115952208970f, + -0.337431414063306840f, + 0.941285396983928660f, -0.337611909483074620f, 0.941220643407275180f, + -0.337792392489817460f, + 0.941155855224629190f, -0.337972863076899720f, 0.941091032438372780f, + -0.338153321237685930f, + 0.941026175050889260f, -0.338333766965541130f, 0.940961283064563280f, + -0.338514200253830940f, + 0.940896356481780830f, -0.338694621095921190f, 0.940831395304928870f, + -0.338875029485178450f, + 0.940766399536396070f, -0.339055425414969640f, 0.940701369178571940f, + -0.339235808878661950f, + 0.940636304233847590f, -0.339416179869623360f, 0.940571204704615190f, + -0.339596538381222110f, + 0.940506070593268300f, -0.339776884406826850f, 0.940440901902201750f, + -0.339957217939806880f, + 0.940375698633811540f, -0.340137538973531720f, 0.940310460790495070f, + -0.340317847501371670f, + 0.940245188374650880f, -0.340498143516697160f, 0.940179881388678920f, + -0.340678427012879200f, + 0.940114539834980280f, -0.340858697983289440f, 0.940049163715957370f, + -0.341038956421299720f, + 0.939983753034014050f, -0.341219202320282360f, 0.939918307791555050f, + -0.341399435673610420f, + 0.939852827990986680f, -0.341579656474657160f, 0.939787313634716570f, + -0.341759864716796310f, + 0.939721764725153340f, -0.341940060393402190f, 0.939656181264707180f, + -0.342120243497849530f, + 0.939590563255789270f, -0.342300414023513520f, 0.939524910700812230f, + -0.342480571963769800f, + 0.939459223602189920f, -0.342660717311994380f, 0.939393501962337510f, + -0.342840850061563950f, + 0.939327745783671400f, -0.343020970205855540f, 0.939261955068609210f, + -0.343201077738246540f, + 0.939196129819569900f, -0.343381172652115040f, 0.939130270038973650f, + -0.343561254940839390f, + 0.939064375729241950f, -0.343741324597798490f, 0.938998446892797540f, + -0.343921381616371700f, + 0.938932483532064600f, -0.344101425989938810f, 0.938866485649468060f, + -0.344281457711880180f, + 0.938800453247434770f, -0.344461476775576540f, 0.938734386328392460f, + -0.344641483174408960f, + 0.938668284894770170f, -0.344821476901759290f, 0.938602148948998400f, + -0.345001457951009670f, + 0.938535978493508560f, -0.345181426315542550f, 0.938469773530733800f, + -0.345361381988741220f, + 0.938403534063108060f, -0.345541324963989090f, 0.938337260093066950f, + -0.345721255234670120f, + 0.938270951623047190f, -0.345901172794168990f, 0.938204608655486490f, + -0.346081077635870430f, + 0.938138231192824360f, -0.346260969753160010f, 0.938071819237501270f, + -0.346440849139423520f, + 0.938005372791958840f, -0.346620715788047320f, 0.937938891858640320f, + -0.346800569692418290f, + 0.937872376439989890f, -0.346980410845923680f, 0.937805826538453120f, + -0.347160239241951160f, + 0.937739242156476970f, -0.347340054873889140f, 0.937672623296509470f, + -0.347519857735126110f, + 0.937605969960999990f, -0.347699647819051380f, 0.937539282152399230f, + -0.347879425119054510f, + 0.937472559873159250f, -0.348059189628525610f, 0.937405803125732960f, + -0.348238941340855260f, + 0.937339011912574960f, -0.348418680249434560f, 0.937272186236140950f, + -0.348598406347654930f, + 0.937205326098887960f, -0.348778119628908420f, 0.937138431503274140f, + -0.348957820086587490f, + 0.937071502451759190f, -0.349137507714084970f, 0.937004538946803690f, + -0.349317182504794380f, + 0.936937540990869900f, -0.349496844452109550f, 0.936870508586420960f, + -0.349676493549424760f, + 0.936803441735921560f, -0.349856129790134920f, 0.936736340441837620f, + -0.350035753167635240f, + 0.936669204706636170f, -0.350215363675321580f, 0.936602034532785570f, + -0.350394961306590150f, + 0.936534829922755500f, -0.350574546054837510f, 0.936467590879016990f, + -0.350754117913461060f, + 0.936400317404042060f, -0.350933676875858360f, 0.936333009500304180f, + -0.351113222935427460f, + 0.936265667170278260f, -0.351292756085567090f, 0.936198290416440090f, + -0.351472276319676310f, + 0.936130879241267030f, -0.351651783631154570f, 0.936063433647237540f, + -0.351831278013402030f, + 0.935995953636831410f, -0.352010759459819080f, 0.935928439212529660f, + -0.352190227963806830f, + 0.935860890376814640f, -0.352369683518766630f, 0.935793307132169900f, + -0.352549126118100460f, + 0.935725689481080370f, -0.352728555755210730f, 0.935658037426032040f, + -0.352907972423500250f, + 0.935590350969512370f, -0.353087376116372480f, 0.935522630114009930f, + -0.353266766827231240f, + 0.935454874862014620f, -0.353446144549480810f, 0.935387085216017770f, + -0.353625509276525970f, + 0.935319261178511610f, -0.353804861001772050f, 0.935251402751989920f, + -0.353984199718624770f, + 0.935183509938947610f, -0.354163525420490340f, 0.935115582741880890f, + -0.354342838100775550f, + 0.935047621163287430f, -0.354522137752887430f, 0.934979625205665800f, + -0.354701424370233830f, + 0.934911594871516090f, -0.354880697946222790f, 0.934843530163339540f, + -0.355059958474262860f, + 0.934775431083638700f, -0.355239205947763310f, 0.934707297634917440f, + -0.355418440360133650f, + 0.934639129819680780f, -0.355597661704783850f, 0.934570927640435030f, + -0.355776869975124640f, + 0.934502691099687870f, -0.355956065164566850f, 0.934434420199948050f, + -0.356135247266522130f, + 0.934366114943725790f, -0.356314416274402410f, 0.934297775333532530f, + -0.356493572181620090f, + 0.934229401371880820f, -0.356672714981588260f, 0.934160993061284530f, + -0.356851844667720300f, + 0.934092550404258980f, -0.357030961233429980f, 0.934024073403320390f, + -0.357210064672131960f, + 0.933955562060986730f, -0.357389154977240940f, 0.933887016379776890f, + -0.357568232142172260f, + 0.933818436362210960f, -0.357747296160341900f, 0.933749822010810580f, + -0.357926347025166010f, + 0.933681173328098410f, -0.358105384730061590f, 0.933612490316598540f, + -0.358284409268445850f, + 0.933543772978836170f, -0.358463420633736540f, 0.933475021317337950f, + -0.358642418819351990f, + 0.933406235334631520f, -0.358821403818710860f, 0.933337415033246190f, + -0.359000375625232460f, + 0.933268560415712050f, -0.359179334232336500f, 0.933199671484560730f, + -0.359358279633443130f, + 0.933130748242325230f, -0.359537211821973070f, 0.933061790691539380f, + -0.359716130791347570f, + 0.932992798834738960f, -0.359895036534988110f, 0.932923772674460140f, + -0.360073929046317020f, + 0.932854712213241120f, -0.360252808318756890f, 0.932785617453621100f, + -0.360431674345730700f, + 0.932716488398140250f, -0.360610527120662270f, 0.932647325049340450f, + -0.360789366636975580f, + 0.932578127409764420f, -0.360968192888095230f, 0.932508895481956590f, + -0.361147005867446250f, + 0.932439629268462360f, -0.361325805568454280f, 0.932370328771828460f, + -0.361504591984545260f, + 0.932300993994602760f, -0.361683365109145840f, 0.932231624939334540f, + -0.361862124935682980f, + 0.932162221608574430f, -0.362040871457584180f, 0.932092784004874050f, + -0.362219604668277460f, + 0.932023312130786490f, -0.362398324561191310f, 0.931953805988866010f, + -0.362577031129754760f, + 0.931884265581668150f, -0.362755724367397230f, 0.931814690911749730f, + -0.362934404267548640f, + 0.931745081981668720f, -0.363113070823639470f, 0.931675438793984620f, + -0.363291724029100760f, + 0.931605761351257830f, -0.363470363877363760f, 0.931536049656050300f, + -0.363648990361860550f, + 0.931466303710925090f, -0.363827603476023500f, 0.931396523518446600f, + -0.364006203213285470f, + 0.931326709081180430f, -0.364184789567079890f, 0.931256860401693420f, + -0.364363362530840620f, + 0.931186977482553750f, -0.364541922098002120f, 0.931117060326330790f, + -0.364720468261999280f, + 0.931047108935595280f, -0.364899001016267320f, 0.930977123312918930f, + -0.365077520354242180f, + 0.930907103460875130f, -0.365256026269360320f, 0.930837049382038150f, + -0.365434518755058390f, + 0.930766961078983710f, -0.365612997804773850f, 0.930696838554288860f, + -0.365791463411944570f, + 0.930626681810531760f, -0.365969915570008740f, 0.930556490850291800f, + -0.366148354272405330f, + 0.930486265676149780f, -0.366326779512573590f, 0.930416006290687550f, + -0.366505191283953370f, + 0.930345712696488470f, -0.366683589579984930f, 0.930275384896137150f, + -0.366861974394109060f, + 0.930205022892219070f, -0.367040345719767180f, 0.930134626687321390f, + -0.367218703550400980f, + 0.930064196284032360f, -0.367397047879452710f, 0.929993731684941480f, + -0.367575378700365330f, + 0.929923232892639670f, -0.367753696006581980f, 0.929852699909718750f, + -0.367931999791546450f, + 0.929782132738772190f, -0.368110290048703050f, 0.929711531382394370f, + -0.368288566771496570f, + 0.929640895843181330f, -0.368466829953372320f, 0.929570226123729860f, + -0.368645079587776040f, + 0.929499522226638560f, -0.368823315668153910f, 0.929428784154506800f, + -0.369001538187952780f, + 0.929358011909935500f, -0.369179747140620020f, 0.929287205495526790f, + -0.369357942519603130f, + 0.929216364913884040f, -0.369536124318350650f, 0.929145490167611720f, + -0.369714292530311240f, + 0.929074581259315860f, -0.369892447148934100f, 0.929003638191603360f, + -0.370070588167669080f, + 0.928932660967082820f, -0.370248715579966360f, 0.928861649588363700f, + -0.370426829379276790f, + 0.928790604058057020f, -0.370604929559051670f, 0.928719524378774810f, + -0.370783016112742560f, + 0.928648410553130520f, -0.370961089033801980f, 0.928577262583738850f, + -0.371139148315682570f, + 0.928506080473215590f, -0.371317193951837540f, 0.928434864224177980f, + -0.371495225935720760f, + 0.928363613839244370f, -0.371673244260786520f, 0.928292329321034670f, + -0.371851248920489490f, + 0.928221010672169440f, -0.372029239908285010f, 0.928149657895271150f, + -0.372207217217628840f, + 0.928078270992963140f, -0.372385180841977360f, 0.928006849967869970f, + -0.372563130774787250f, + 0.927935394822617890f, -0.372741067009515760f, 0.927863905559833780f, + -0.372918989539620830f, + 0.927792382182146320f, -0.373096898358560640f, 0.927720824692185200f, + -0.373274793459793970f, + 0.927649233092581180f, -0.373452674836780300f, 0.927577607385966730f, + -0.373630542482979280f, + 0.927505947574975180f, -0.373808396391851210f, 0.927434253662241300f, + -0.373986236556857030f, + 0.927362525650401110f, -0.374164062971457930f, 0.927290763542091720f, + -0.374341875629115920f, + 0.927218967339951790f, -0.374519674523293210f, 0.927147137046620880f, + -0.374697459647452600f, + 0.927075272664740100f, -0.374875230995057540f, 0.927003374196951670f, + -0.375052988559571920f, + 0.926931441645899130f, -0.375230732334459920f, 0.926859475014227160f, + -0.375408462313186590f, + 0.926787474304581750f, -0.375586178489217220f, 0.926715439519610330f, + -0.375763880856017700f, + 0.926643370661961230f, -0.375941569407054420f, 0.926571267734284330f, + -0.376119244135794340f, + 0.926499130739230510f, -0.376296905035704790f, 0.926426959679452210f, + -0.376474552100253770f, + 0.926354754557602860f, -0.376652185322909560f, 0.926282515376337210f, + -0.376829804697141280f, + 0.926210242138311380f, -0.377007410216418260f, 0.926137934846182560f, + -0.377185001874210450f, + 0.926065593502609310f, -0.377362579663988340f, 0.925993218110251480f, + -0.377540143579222940f, + 0.925920808671770070f, -0.377717693613385640f, 0.925848365189827270f, + -0.377895229759948490f, + 0.925775887667086740f, -0.378072752012383990f, 0.925703376106213230f, + -0.378250260364165200f, + 0.925630830509872720f, -0.378427754808765560f, 0.925558250880732740f, + -0.378605235339659120f, + 0.925485637221461490f, -0.378782701950320540f, 0.925412989534729060f, + -0.378960154634224720f, + 0.925340307823206310f, -0.379137593384847320f, 0.925267592089565660f, + -0.379315018195664430f, + 0.925194842336480530f, -0.379492429060152630f, 0.925122058566625880f, + -0.379669825971788940f, + 0.925049240782677580f, -0.379847208924051160f, 0.924976388987313160f, + -0.380024577910417270f, + 0.924903503183210910f, -0.380201932924366050f, 0.924830583373050800f, + -0.380379273959376600f, + 0.924757629559513910f, -0.380556601008928520f, 0.924684641745282420f, + -0.380733914066502140f, + 0.924611619933039970f, -0.380911213125578070f, 0.924538564125471420f, + -0.381088498179637520f, + 0.924465474325262600f, -0.381265769222162380f, 0.924392350535101050f, + -0.381443026246634730f, + 0.924319192757675160f, -0.381620269246537360f, 0.924246000995674890f, + -0.381797498215353640f, + 0.924172775251791200f, -0.381974713146567220f, 0.924099515528716280f, + -0.382151914033662610f, + 0.924026221829143850f, -0.382329100870124510f, 0.923952894155768640f, + -0.382506273649438230f, + 0.923879532511286740f, -0.382683432365089780f, 0.923806136898395410f, + -0.382860577010565420f, + 0.923732707319793290f, -0.383037707579352020f, 0.923659243778179980f, + -0.383214824064937180f, + 0.923585746276256670f, -0.383391926460808660f, 0.923512214816725630f, + -0.383569014760454910f, + 0.923438649402290370f, -0.383746088957365010f, 0.923365050035655720f, + -0.383923149045028390f, + 0.923291416719527640f, -0.384100195016935040f, 0.923217749456613500f, + -0.384277226866575510f, + 0.923144048249621930f, -0.384454244587440820f, 0.923070313101262420f, + -0.384631248173022580f, + 0.922996544014246250f, -0.384808237616812880f, 0.922922740991285680f, + -0.384985212912304200f, + 0.922848904035094120f, -0.385162174052989860f, 0.922775033148386380f, + -0.385339121032363340f, + 0.922701128333878630f, -0.385516053843918850f, 0.922627189594287910f, + -0.385692972481151140f, + 0.922553216932332830f, -0.385869876937555310f, 0.922479210350733210f, + -0.386046767206627170f, + 0.922405169852209880f, -0.386223643281862980f, 0.922331095439485440f, + -0.386400505156759440f, + 0.922256987115283030f, -0.386577352824813920f, 0.922182844882327600f, + -0.386754186279524180f, + 0.922108668743345180f, -0.386931005514388580f, 0.922034458701062820f, + -0.387107810522905990f, + 0.921960214758209220f, -0.387284601298575840f, 0.921885936917513970f, + -0.387461377834897870f, + 0.921811625181708120f, -0.387638140125372730f, 0.921737279553523910f, + -0.387814888163501180f, + 0.921662900035694730f, -0.387991621942784860f, 0.921588486630955490f, + -0.388168341456725740f, + 0.921514039342042010f, -0.388345046698826250f, 0.921439558171691430f, + -0.388521737662589570f, + 0.921365043122642340f, -0.388698414341519190f, 0.921290494197634540f, + -0.388875076729119250f, + 0.921215911399408730f, -0.389051724818894380f, 0.921141294730707270f, + -0.389228358604349730f, + 0.921066644194273640f, -0.389404978078990940f, 0.920991959792852310f, + -0.389581583236324300f, + 0.920917241529189520f, -0.389758174069856410f, 0.920842489406032190f, + -0.389934750573094730f, + 0.920767703426128790f, -0.390111312739546910f, 0.920692883592229120f, + -0.390287860562721190f, + 0.920618029907083970f, -0.390464394036126590f, 0.920543142373445480f, + -0.390640913153272430f, + 0.920468220994067110f, -0.390817417907668500f, 0.920393265771703550f, + -0.390993908292825380f, + 0.920318276709110590f, -0.391170384302253870f, 0.920243253809045370f, + -0.391346845929465560f, + 0.920168197074266340f, -0.391523293167972410f, 0.920093106507533180f, + -0.391699726011286940f, + 0.920017982111606570f, -0.391876144452922350f, 0.919942823889248640f, + -0.392052548486392090f, + 0.919867631843222950f, -0.392228938105210310f, 0.919792405976293860f, + -0.392405313302891690f, + 0.919717146291227360f, -0.392581674072951470f, 0.919641852790790470f, + -0.392758020408905280f, + 0.919566525477751530f, -0.392934352304269490f, 0.919491164354880100f, + -0.393110669752560760f, + 0.919415769424947070f, -0.393286972747296400f, 0.919340340690724340f, + -0.393463261281994330f, + 0.919264878154985370f, -0.393639535350172880f, 0.919189381820504470f, + -0.393815794945351020f, + 0.919113851690057770f, -0.393992040061048100f, 0.919038287766422050f, + -0.394168270690784080f, + 0.918962690052375630f, -0.394344486828079600f, 0.918887058550697970f, + -0.394520688466455600f, + 0.918811393264170050f, -0.394696875599433560f, 0.918735694195573550f, + -0.394873048220535760f, + 0.918659961347691900f, -0.395049206323284770f, 0.918584194723309540f, + -0.395225349901203670f, + 0.918508394325212250f, -0.395401478947816350f, 0.918432560156186910f, + -0.395577593456646840f, + 0.918356692219021720f, -0.395753693421220080f, 0.918280790516506130f, + -0.395929778835061250f, + 0.918204855051430900f, -0.396105849691696270f, 0.918128885826588030f, + -0.396281905984651520f, + 0.918052882844770380f, -0.396457947707453910f, 0.917976846108772730f, + -0.396633974853630830f, + 0.917900775621390500f, -0.396809987416710310f, 0.917824671385420570f, + -0.396985985390220900f, + 0.917748533403661250f, -0.397161968767691610f, 0.917672361678911860f, + -0.397337937542652060f, + 0.917596156213972950f, -0.397513891708632330f, 0.917519917011646260f, + -0.397689831259163180f, + 0.917443644074735220f, -0.397865756187775750f, 0.917367337406043930f, + -0.398041666488001770f, + 0.917290997008377910f, -0.398217562153373560f, 0.917214622884544250f, + -0.398393443177423980f, + 0.917138215037350710f, -0.398569309553686300f, 0.917061773469606820f, + -0.398745161275694430f, + 0.916985298184123000f, -0.398920998336982910f, 0.916908789183710990f, + -0.399096820731086540f, + 0.916832246471183890f, -0.399272628451540990f, 0.916755670049355990f, + -0.399448421491882140f, + 0.916679059921042700f, -0.399624199845646790f, 0.916602416089060790f, + -0.399799963506371980f, + 0.916525738556228210f, -0.399975712467595330f, 0.916449027325364150f, + -0.400151446722855130f, + 0.916372282399289140f, -0.400327166265690090f, 0.916295503780824800f, + -0.400502871089639500f, + 0.916218691472794220f, -0.400678561188243240f, 0.916141845478021350f, + -0.400854236555041650f, + 0.916064965799331720f, -0.401029897183575620f, 0.915988052439551950f, + -0.401205543067386710f, + 0.915911105401509880f, -0.401381174200016790f, 0.915834124688034710f, + -0.401556790575008540f, + 0.915757110301956720f, -0.401732392185905010f, 0.915680062246107650f, + -0.401907979026249700f, + 0.915602980523320230f, -0.402083551089586990f, 0.915525865136428530f, + -0.402259108369461490f, + 0.915448716088267830f, -0.402434650859418430f, 0.915371533381674760f, + -0.402610178553003680f, + 0.915294317019487050f, -0.402785691443763530f, 0.915217067004543860f, + -0.402961189525244900f, + 0.915139783339685260f, -0.403136672790995300f, 0.915062466027752760f, + -0.403312141234562550f, + 0.914985115071589310f, -0.403487594849495310f, 0.914907730474038730f, + -0.403663033629342640f, + 0.914830312237946200f, -0.403838457567654070f, 0.914752860366158220f, + -0.404013866657979890f, + 0.914675374861522390f, -0.404189260893870690f, 0.914597855726887790f, + -0.404364640268877810f, + 0.914520302965104450f, -0.404540004776553000f, 0.914442716579023870f, + -0.404715354410448650f, + 0.914365096571498560f, -0.404890689164117580f, 0.914287442945382440f, + -0.405066009031113340f, + 0.914209755703530690f, -0.405241314004989860f, 0.914132034848799460f, + -0.405416604079301630f, + 0.914054280384046570f, -0.405591879247603870f, 0.913976492312130630f, + -0.405767139503452060f, + 0.913898670635911680f, -0.405942384840402510f, 0.913820815358251100f, + -0.406117615252011840f, + 0.913742926482011390f, -0.406292830731837360f, 0.913665004010056350f, + -0.406468031273437000f, + 0.913587047945250810f, -0.406643216870369030f, 0.913509058290461140f, + -0.406818387516192310f, + 0.913431035048554720f, -0.406993543204466510f, 0.913352978222400250f, + -0.407168683928751550f, + 0.913274887814867760f, -0.407343809682607970f, 0.913196763828828200f, + -0.407518920459596920f, + 0.913118606267154240f, -0.407694016253280110f, 0.913040415132719160f, + -0.407869097057219800f, + 0.912962190428398210f, -0.408044162864978690f, 0.912883932157067200f, + -0.408219213670120100f, + 0.912805640321603500f, -0.408394249466208000f, 0.912727314924885900f, + -0.408569270246806780f, + 0.912648955969793900f, -0.408744276005481360f, 0.912570563459208730f, + -0.408919266735797430f, + 0.912492137396012650f, -0.409094242431320980f, 0.912413677783089020f, + -0.409269203085618590f, + 0.912335184623322750f, -0.409444148692257590f, 0.912256657919599760f, + -0.409619079244805670f, + 0.912178097674807180f, -0.409793994736831150f, 0.912099503891833470f, + -0.409968895161902880f, + 0.912020876573568340f, -0.410143780513590240f, 0.911942215722902570f, + -0.410318650785463260f, + 0.911863521342728520f, -0.410493505971092410f, 0.911784793435939430f, + -0.410668346064048730f, + 0.911706032005429880f, -0.410843171057903910f, 0.911627237054095650f, + -0.411017980946230210f, + 0.911548408584833990f, -0.411192775722600160f, 0.911469546600543020f, + -0.411367555380587220f, + 0.911390651104122430f, -0.411542319913765220f, 0.911311722098472780f, + -0.411717069315708560f, + 0.911232759586496190f, -0.411891803579992170f, 0.911153763571095900f, + -0.412066522700191560f, + 0.911074734055176360f, -0.412241226669882890f, 0.910995671041643140f, + -0.412415915482642730f, + 0.910916574533403360f, -0.412590589132048210f, 0.910837444533365010f, + -0.412765247611677270f, + 0.910758281044437570f, -0.412939890915108080f, 0.910679084069531570f, + -0.413114519035919450f, + 0.910599853611558930f, -0.413289131967690960f, 0.910520589673432750f, + -0.413463729704002410f, + 0.910441292258067250f, -0.413638312238434500f, 0.910361961368377990f, + -0.413812879564568300f, + 0.910282597007281760f, -0.413987431675985400f, 0.910203199177696540f, + -0.414161968566268080f, + 0.910123767882541680f, -0.414336490228999100f, 0.910044303124737500f, + -0.414510996657761750f, + 0.909964804907205660f, -0.414685487846140010f, 0.909885273232869160f, + -0.414859963787718330f, + 0.909805708104652220f, -0.415034424476081630f, 0.909726109525480160f, + -0.415208869904815590f, + 0.909646477498279540f, -0.415383300067506230f, 0.909566812025978330f, + -0.415557714957740410f, + 0.909487113111505430f, -0.415732114569105360f, 0.909407380757791260f, + -0.415906498895188770f, + 0.909327614967767260f, -0.416080867929579210f, 0.909247815744366310f, + -0.416255221665865480f, + 0.909167983090522380f, -0.416429560097637150f, 0.909088117009170580f, + -0.416603883218484350f, + 0.909008217503247450f, -0.416778191021997650f, 0.908928284575690640f, + -0.416952483501768170f, + 0.908848318229439120f, -0.417126760651387870f, 0.908768318467432890f, + -0.417301022464448890f, + 0.908688285292613360f, -0.417475268934544290f, 0.908608218707923190f, + -0.417649500055267410f, + 0.908528118716306120f, -0.417823715820212270f, 0.908447985320707250f, + -0.417997916222973550f, + 0.908367818524072890f, -0.418172101257146320f, 0.908287618329350450f, + -0.418346270916326260f, + 0.908207384739488700f, -0.418520425194109700f, 0.908127117757437600f, + -0.418694564084093560f, + 0.908046817386148340f, -0.418868687579875050f, 0.907966483628573350f, + -0.419042795675052370f, + 0.907886116487666260f, -0.419216888363223910f, 0.907805715966381930f, + -0.419390965637988890f, + 0.907725282067676440f, -0.419565027492946880f, 0.907644814794507200f, + -0.419739073921698180f, + 0.907564314149832630f, -0.419913104917843620f, 0.907483780136612570f, + -0.420087120474984530f, + 0.907403212757808110f, -0.420261120586722880f, 0.907322612016381420f, + -0.420435105246661170f, + 0.907241977915295820f, -0.420609074448402510f, 0.907161310457516250f, + -0.420783028185550520f, + 0.907080609646008450f, -0.420956966451709440f, 0.906999875483739610f, + -0.421130889240483970f, + 0.906919107973678140f, -0.421304796545479640f, 0.906838307118793430f, + -0.421478688360302280f, + 0.906757472922056550f, -0.421652564678558330f, 0.906676605386439460f, + -0.421826425493854910f, + 0.906595704514915330f, -0.422000270799799680f, 0.906514770310458800f, + -0.422174100590000770f, + 0.906433802776045460f, -0.422347914858067050f, 0.906352801914652400f, + -0.422521713597607820f, + 0.906271767729257660f, -0.422695496802232950f, 0.906190700222840650f, + -0.422869264465553060f, + 0.906109599398381980f, -0.423043016581179040f, 0.906028465258863600f, + -0.423216753142722610f, + 0.905947297807268460f, -0.423390474143796050f, 0.905866097046580940f, + -0.423564179578011960f, + 0.905784862979786550f, -0.423737869438983840f, 0.905703595609872010f, + -0.423911543720325580f, + 0.905622294939825270f, -0.424085202415651560f, 0.905540960972635590f, + -0.424258845518576950f, + 0.905459593711293250f, -0.424432473022717420f, 0.905378193158790090f, + -0.424606084921689110f, + 0.905296759318118820f, -0.424779681209108810f, 0.905215292192273590f, + -0.424953261878593890f, + 0.905133791784249690f, -0.425126826923762360f, 0.905052258097043590f, + -0.425300376338232640f, + 0.904970691133653250f, -0.425473910115623800f, 0.904889090897077470f, + -0.425647428249555590f, + 0.904807457390316540f, -0.425820930733648240f, 0.904725790616371930f, + -0.425994417561522400f, + 0.904644090578246240f, -0.426167888726799620f, 0.904562357278943300f, + -0.426341344223101830f, + 0.904480590721468250f, -0.426514784044051520f, 0.904398790908827350f, + -0.426688208183271860f, + 0.904316957844028320f, -0.426861616634386430f, 0.904235091530079750f, + -0.427035009391019680f, + 0.904153191969991780f, -0.427208386446796320f, 0.904071259166775440f, + -0.427381747795341770f, + 0.903989293123443340f, -0.427555093430282080f, 0.903907293843009050f, + -0.427728423345243800f, + 0.903825261328487510f, -0.427901737533854080f, 0.903743195582894620f, + -0.428075035989740730f, + 0.903661096609247980f, -0.428248318706531960f, 0.903578964410566070f, + -0.428421585677856650f, + 0.903496798989868450f, -0.428594836897344400f, 0.903414600350176290f, + -0.428768072358625070f, + 0.903332368494511820f, -0.428941292055329490f, 0.903250103425898400f, + -0.429114495981088750f, + 0.903167805147360720f, -0.429287684129534610f, 0.903085473661924600f, + -0.429460856494299490f, + 0.903003108972617150f, -0.429634013069016380f, 0.902920711082466740f, + -0.429807153847318710f, + 0.902838279994502830f, -0.429980278822840620f, 0.902755815711756120f, + -0.430153387989216870f, + 0.902673318237258830f, -0.430326481340082610f, 0.902590787574043870f, + -0.430499558869073820f, + 0.902508223725145940f, -0.430672620569826800f, 0.902425626693600380f, + -0.430845666435978660f, + 0.902342996482444200f, -0.431018696461167030f, 0.902260333094715540f, + -0.431191710639029950f, + 0.902177636533453620f, -0.431364708963206330f, 0.902094906801698900f, + -0.431537691427335500f, + 0.902012143902493180f, -0.431710658025057260f, 0.901929347838879460f, + -0.431883608750012250f, + 0.901846518613901750f, -0.432056543595841500f, 0.901763656230605730f, + -0.432229462556186720f, + 0.901680760692037730f, -0.432402365624690140f, 0.901597832001245660f, + -0.432575252794994650f, + 0.901514870161278740f, -0.432748124060743700f, 0.901431875175186970f, + -0.432920979415581280f, + 0.901348847046022030f, -0.433093818853151960f, 0.901265785776836580f, + -0.433266642367100940f, + 0.901182691370684520f, -0.433439449951074090f, 0.901099563830620950f, + -0.433612241598717580f, + 0.901016403159702330f, -0.433785017303678520f, 0.900933209360986200f, + -0.433957777059604420f, + 0.900849982437531450f, -0.434130520860143310f, 0.900766722392397860f, + -0.434303248698943990f, + 0.900683429228646970f, -0.434475960569655650f, 0.900600102949340900f, + -0.434648656465928320f, + 0.900516743557543520f, -0.434821336381412290f, 0.900433351056319830f, + -0.434994000309758710f, + 0.900349925448735600f, -0.435166648244619260f, 0.900266466737858480f, + -0.435339280179646070f, + 0.900182974926756810f, -0.435511896108492000f, 0.900099450018500450f, + -0.435684496024810460f, + 0.900015892016160280f, -0.435857079922255470f, 0.899932300922808510f, + -0.436029647794481560f, + 0.899848676741518580f, -0.436202199635143950f, 0.899765019475365140f, + -0.436374735437898340f, + 0.899681329127423930f, -0.436547255196401200f, 0.899597605700772180f, + -0.436719758904309360f, + 0.899513849198487980f, -0.436892246555280360f, 0.899430059623650860f, + -0.437064718142972370f, + 0.899346236979341570f, -0.437237173661044090f, 0.899262381268642000f, + -0.437409613103154790f, + 0.899178492494635330f, -0.437582036462964400f, 0.899094570660405770f, + -0.437754443734133410f, + 0.899010615769039070f, -0.437926834910322860f, 0.898926627823621870f, + -0.438099209985194470f, + 0.898842606827242370f, -0.438271568952410430f, 0.898758552782989440f, + -0.438443911805633690f, + 0.898674465693953820f, -0.438616238538527660f, 0.898590345563227030f, + -0.438788549144756290f, + 0.898506192393901950f, -0.438960843617984320f, 0.898422006189072530f, + -0.439133121951876930f, + 0.898337786951834310f, -0.439305384140099950f, 0.898253534685283570f, + -0.439477630176319800f, + 0.898169249392518080f, -0.439649860054203480f, 0.898084931076636780f, + -0.439822073767418500f, + 0.898000579740739880f, -0.439994271309633260f, 0.897916195387928660f, + -0.440166452674516320f, + 0.897831778021305650f, -0.440338617855737250f, 0.897747327643974690f, + -0.440510766846965940f, + 0.897662844259040860f, -0.440682899641872900f, 0.897578327869610230f, + -0.440855016234129430f, + 0.897493778478790310f, -0.441027116617407230f, 0.897409196089689720f, + -0.441199200785378660f, + 0.897324580705418320f, -0.441371268731716670f, 0.897239932329087160f, + -0.441543320450094870f, + 0.897155250963808550f, -0.441715355934187310f, 0.897070536612695870f, + -0.441887375177668850f, + 0.896985789278863970f, -0.442059378174214700f, 0.896901008965428790f, + -0.442231364917500980f, + 0.896816195675507300f, -0.442403335401204080f, 0.896731349412217880f, + -0.442575289619001170f, + 0.896646470178680150f, -0.442747227564570020f, 0.896561557978014960f, + -0.442919149231588980f, + 0.896476612813344120f, -0.443091054613736880f, 0.896391634687790820f, + -0.443262943704693320f, + 0.896306623604479550f, -0.443434816498138480f, 0.896221579566536030f, + -0.443606672987752970f, + 0.896136502577086770f, -0.443778513167218220f, 0.896051392639260150f, + -0.443950337030216140f, + 0.895966249756185220f, -0.444122144570429200f, 0.895881073930992370f, + -0.444293935781540580f, + 0.895795865166813530f, -0.444465710657234000f, 0.895710623466781320f, + -0.444637469191193790f, + 0.895625348834030110f, -0.444809211377104880f, 0.895540041271694950f, + -0.444980937208652730f, + 0.895454700782912450f, -0.445152646679523640f, 0.895369327370820310f, + -0.445324339783404190f, + 0.895283921038557580f, -0.445496016513981740f, 0.895198481789264200f, + -0.445667676864944300f, + 0.895113009626081760f, -0.445839320829980290f, 0.895027504552152630f, + -0.446010948402778940f, + 0.894941966570620750f, -0.446182559577030070f, 0.894856395684631050f, + -0.446354154346423840f, + 0.894770791897329550f, -0.446525732704651350f, 0.894685155211863980f, + -0.446697294645404090f, + 0.894599485631382700f, -0.446868840162374160f, 0.894513783159035620f, + -0.447040369249254440f, + 0.894428047797973800f, -0.447211881899738320f, 0.894342279551349480f, + -0.447383378107519600f, + 0.894256478422316040f, -0.447554857866293010f, 0.894170644414028270f, + -0.447726321169753580f, + 0.894084777529641990f, -0.447897768011597310f, 0.893998877772314240f, + -0.448069198385520400f, + 0.893912945145203250f, -0.448240612285219890f, 0.893826979651468620f, + -0.448412009704393430f, + 0.893740981294271040f, -0.448583390636739240f, 0.893654950076772540f, + -0.448754755075955970f, + 0.893568886002135910f, -0.448926103015743260f, 0.893482789073525850f, + -0.449097434449801050f, + 0.893396659294107720f, -0.449268749371829920f, 0.893310496667048200f, + -0.449440047775531150f, + 0.893224301195515320f, -0.449611329654606540f, 0.893138072882678320f, + -0.449782595002758690f, + 0.893051811731707450f, -0.449953843813690520f, 0.892965517745774370f, + -0.450125076081105690f, + 0.892879190928051680f, -0.450296291798708610f, 0.892792831281713610f, + -0.450467490960204110f, + 0.892706438809935390f, -0.450638673559297600f, 0.892620013515893150f, + -0.450809839589695280f, + 0.892533555402764580f, -0.450980989045103860f, 0.892447064473728680f, + -0.451152121919230600f, + 0.892360540731965360f, -0.451323238205783520f, 0.892273984180655840f, + -0.451494337898471100f, + 0.892187394822982480f, -0.451665420991002490f, 0.892100772662129060f, + -0.451836487477087490f, + 0.892014117701280470f, -0.452007537350436420f, 0.891927429943622510f, + -0.452178570604760350f, + 0.891840709392342720f, -0.452349587233770890f, 0.891753956050629460f, + -0.452520587231180050f, + 0.891667169921672280f, -0.452691570590700920f, 0.891580351008662290f, + -0.452862537306046750f, + 0.891493499314791380f, -0.453033487370931580f, 0.891406614843252900f, + -0.453204420779070190f, + 0.891319697597241390f, -0.453375337524177750f, 0.891232747579952520f, + -0.453546237599970090f, + 0.891145764794583180f, -0.453717121000163870f, 0.891058749244331590f, + -0.453887987718476050f, + 0.890971700932396860f, -0.454058837748624430f, 0.890884619861979530f, + -0.454229671084327320f, + 0.890797506036281490f, -0.454400487719303580f, 0.890710359458505630f, + -0.454571287647272950f, + 0.890623180131855930f, -0.454742070861955450f, 0.890535968059537830f, + -0.454912837357071940f, + 0.890448723244757880f, -0.455083587126343840f, 0.890361445690723840f, + -0.455254320163493100f, + 0.890274135400644600f, -0.455425036462242360f, 0.890186792377730240f, + -0.455595736016314980f, + 0.890099416625192320f, -0.455766418819434640f, 0.890012008146243260f, + -0.455937084865326030f, + 0.889924566944096720f, -0.456107734147714110f, 0.889837093021967900f, + -0.456278366660324620f, + 0.889749586383072780f, -0.456448982396883920f, 0.889662047030628900f, + -0.456619581351118910f, + 0.889574474967854580f, -0.456790163516757160f, 0.889486870197969900f, + -0.456960728887526980f, + 0.889399232724195520f, -0.457131277457156980f, 0.889311562549753850f, + -0.457301809219376630f, + 0.889223859677868210f, -0.457472324167916060f, 0.889136124111763240f, + -0.457642822296505770f, + 0.889048355854664570f, -0.457813303598877170f, 0.888960554909799310f, + -0.457983768068762120f, + 0.888872721280395630f, -0.458154215699893060f, 0.888784854969682850f, + -0.458324646486003240f, + 0.888696955980891600f, -0.458495060420826270f, 0.888609024317253860f, + -0.458665457498096560f, + 0.888521059982002260f, -0.458835837711549120f, 0.888433062978371320f, + -0.459006201054919630f, + 0.888345033309596350f, -0.459176547521944090f, 0.888256970978913870f, + -0.459346877106359630f, + 0.888168875989561730f, -0.459517189801903480f, 0.888080748344778900f, + -0.459687485602313870f, + 0.887992588047805560f, -0.459857764501329540f, 0.887904395101883240f, + -0.460028026492689650f, + 0.887816169510254440f, -0.460198271570134320f, 0.887727911276163020f, + -0.460368499727404010f, + 0.887639620402853930f, -0.460538710958240010f, 0.887551296893573370f, + -0.460708905256384080f, + 0.887462940751568840f, -0.460879082615578690f, 0.887374551980088850f, + -0.461049243029566900f, + 0.887286130582383150f, -0.461219386492092380f, 0.887197676561702900f, + -0.461389512996899450f, + 0.887109189921300170f, -0.461559622537733080f, 0.887020670664428360f, + -0.461729715108338770f, + 0.886932118794342190f, -0.461899790702462730f, 0.886843534314297410f, + -0.462069849313851750f, + 0.886754917227550840f, -0.462239890936253340f, 0.886666267537361000f, + -0.462409915563415430f, + 0.886577585246987040f, -0.462579923189086810f, 0.886488870359689600f, + -0.462749913807016740f, + 0.886400122878730600f, -0.462919887410955080f, 0.886311342807372780f, + -0.463089843994652530f, + 0.886222530148880640f, -0.463259783551860150f, 0.886133684906519340f, + -0.463429706076329830f, + 0.886044807083555600f, -0.463599611561814010f, 0.885955896683257030f, + -0.463769500002065630f, + 0.885866953708892790f, -0.463939371390838520f, 0.885777978163732940f, + -0.464109225721886950f, + 0.885688970051048960f, -0.464279062988965760f, 0.885599929374113360f, + -0.464448883185830660f, + 0.885510856136199950f, -0.464618686306237820f, 0.885421750340583680f, + -0.464788472343943990f, + 0.885332611990540590f, -0.464958241292706690f, 0.885243441089348270f, + -0.465127993146283950f, + 0.885154237640285110f, -0.465297727898434600f, 0.885065001646630930f, + -0.465467445542917800f, + 0.884975733111666660f, -0.465637146073493660f, 0.884886432038674560f, + -0.465806829483922710f, + 0.884797098430937790f, -0.465976495767966180f, 0.884707732291741040f, + -0.466146144919385890f, + 0.884618333624369920f, -0.466315776931944430f, 0.884528902432111460f, + -0.466485391799404900f, + 0.884439438718253810f, -0.466654989515530920f, 0.884349942486086120f, + -0.466824570074086950f, + 0.884260413738899190f, -0.466994133468838000f, 0.884170852479984500f, + -0.467163679693549770f, + 0.884081258712634990f, -0.467333208741988420f, 0.883991632440144890f, + -0.467502720607920920f, + 0.883901973665809470f, -0.467672215285114770f, 0.883812282392925090f, + -0.467841692767338170f, + 0.883722558624789660f, -0.468011153048359830f, 0.883632802364701870f, + -0.468180596121949290f, + 0.883543013615961880f, -0.468350021981876530f, 0.883453192381870920f, + -0.468519430621912310f, + 0.883363338665731580f, -0.468688822035827900f, 0.883273452470847430f, + -0.468858196217395330f, + 0.883183533800523390f, -0.469027553160387130f, 0.883093582658065370f, + -0.469196892858576580f, + 0.883003599046780830f, -0.469366215305737520f, 0.882913582969978020f, + -0.469535520495644450f, + 0.882823534430966620f, -0.469704808422072460f, 0.882733453433057650f, + -0.469874079078797360f, + 0.882643339979562790f, -0.470043332459595620f, 0.882553194073795510f, + -0.470212568558244170f, + 0.882463015719070150f, -0.470381787368520650f, 0.882372804918702290f, + -0.470550988884203550f, + 0.882282561676008710f, -0.470720173099071600f, 0.882192285994307430f, + -0.470889340006904520f, + 0.882101977876917580f, -0.471058489601482500f, 0.882011637327159590f, + -0.471227621876586340f, + 0.881921264348355050f, -0.471396736825997640f, 0.881830858943826620f, + -0.471565834443498420f, + 0.881740421116898320f, -0.471734914722871430f, 0.881649950870895260f, + -0.471903977657900210f, + 0.881559448209143780f, -0.472073023242368660f, 0.881468913134971440f, + -0.472242051470061490f, + 0.881378345651706920f, -0.472411062334764040f, 0.881287745762680100f, + -0.472580055830262250f, + 0.881197113471222090f, -0.472749031950342790f, 0.881106448780665130f, + -0.472917990688792760f, + 0.881015751694342870f, -0.473086932039400050f, 0.880925022215589880f, + -0.473255855995953320f, + 0.880834260347742040f, -0.473424762552241530f, 0.880743466094136340f, + -0.473593651702054530f, + 0.880652639458111010f, -0.473762523439182850f, 0.880561780443005700f, + -0.473931377757417450f, + 0.880470889052160750f, -0.474100214650549970f, 0.880379965288918150f, + -0.474269034112372980f, + 0.880289009156621010f, -0.474437836136679230f, 0.880198020658613190f, + -0.474606620717262560f, + 0.880106999798240360f, -0.474775387847917120f, 0.880015946578849070f, + -0.474944137522437800f, + 0.879924861003786860f, -0.475112869734620300f, 0.879833743076402940f, + -0.475281584478260740f, + 0.879742592800047410f, -0.475450281747155870f, 0.879651410178071580f, + -0.475618961535103300f, + 0.879560195213827890f, -0.475787623835901120f, 0.879468947910670210f, + -0.475956268643348060f, + 0.879377668271953290f, -0.476124895951243580f, 0.879286356301033250f, + -0.476293505753387690f, + 0.879195012001267480f, -0.476462098043581190f, 0.879103635376014330f, + -0.476630672815625320f, + 0.879012226428633530f, -0.476799230063322090f, 0.878920785162485840f, + -0.476967769780474170f, + 0.878829311580933360f, -0.477136291960884810f, 0.878737805687339390f, + -0.477304796598357890f, + 0.878646267485068130f, -0.477473283686698060f, 0.878554696977485450f, + -0.477641753219710470f, + 0.878463094167957870f, -0.477810205191200990f, 0.878371459059853480f, + -0.477978639594976160f, + 0.878279791656541580f, -0.478147056424843010f, 0.878188091961392250f, + -0.478315455674609480f, + 0.878096359977777130f, -0.478483837338083970f, 0.878004595709069080f, + -0.478652201409075500f, + 0.877912799158641840f, -0.478820547881393890f, 0.877820970329870500f, + -0.478988876748849490f, + 0.877729109226131570f, -0.479157188005253310f, 0.877637215850802230f, + -0.479325481644417070f, + 0.877545290207261350f, -0.479493757660153010f, 0.877453332298888560f, + -0.479662016046274180f, + 0.877361342129065140f, -0.479830256796594190f, 0.877269319701173170f, + -0.479998479904927280f, + 0.877177265018595940f, -0.480166685365088390f, 0.877085178084718420f, + -0.480334873170893020f, + 0.876993058902925890f, -0.480503043316157510f, 0.876900907476605650f, + -0.480671195794698640f, + 0.876808723809145650f, -0.480839330600333960f, 0.876716507903935400f, + -0.481007447726881590f, + 0.876624259764365310f, -0.481175547168160300f, 0.876531979393827100f, + -0.481343628917989710f, + 0.876439666795713610f, -0.481511692970189860f, 0.876347321973419020f, + -0.481679739318581490f, + 0.876254944930338510f, -0.481847767956986030f, 0.876162535669868460f, + -0.482015778879225590f, + 0.876070094195406600f, -0.482183772079122720f, 0.875977620510351770f, + -0.482351747550500980f, + 0.875885114618103810f, -0.482519705287184350f, 0.875792576522063880f, + -0.482687645282997460f, + 0.875700006225634600f, -0.482855567531765670f, 0.875607403732219350f, + -0.483023472027314880f, + 0.875514769045222850f, -0.483191358763471860f, 0.875422102168050940f, + -0.483359227734063810f, + 0.875329403104110890f, -0.483527078932918740f, 0.875236671856810870f, + -0.483694912353865140f, + 0.875143908429560360f, -0.483862727990732270f, 0.875051112825769970f, + -0.484030525837350010f, + 0.874958285048851650f, -0.484198305887549030f, 0.874865425102218320f, + -0.484366068135160420f, + 0.874772532989284150f, -0.484533812574016180f, 0.874679608713464510f, + -0.484701539197948670f, + 0.874586652278176110f, -0.484869248000791060f, 0.874493663686836560f, + -0.485036938976377290f, + 0.874400642942864790f, -0.485204612118541820f, 0.874307590049680950f, + -0.485372267421119770f, + 0.874214505010706300f, -0.485539904877946960f, 0.874121387829363330f, + -0.485707524482859750f, + 0.874028238509075740f, -0.485875126229695250f, 0.873935057053268240f, + -0.486042710112291330f, + 0.873841843465366860f, -0.486210276124486420f, 0.873748597748798870f, + -0.486377824260119440f, + 0.873655319906992630f, -0.486545354513030270f, 0.873562009943377850f, + -0.486712866877059170f, + 0.873468667861384880f, -0.486880361346047340f, 0.873375293664446000f, + -0.487047837913836380f, + 0.873281887355994210f, -0.487215296574268760f, 0.873188448939463790f, + -0.487382737321187360f, + 0.873094978418290090f, -0.487550160148436000f, 0.873001475795909920f, + -0.487717565049858800f, + 0.872907941075761080f, -0.487884952019301040f, 0.872814374261282390f, + -0.488052321050608250f, + 0.872720775355914300f, -0.488219672137626790f, 0.872627144363097960f, + -0.488387005274203530f, + 0.872533481286276170f, -0.488554320454186180f, 0.872439786128892280f, + -0.488721617671423080f, + 0.872346058894391540f, -0.488888896919763170f, 0.872252299586219860f, + -0.489056158193056030f, + 0.872158508207824480f, -0.489223401485151980f, 0.872064684762653860f, + -0.489390626789901920f, + 0.871970829254157810f, -0.489557834101157440f, 0.871876941685786890f, + -0.489725023412770910f, + 0.871783022060993120f, -0.489892194718595190f, 0.871689070383229740f, + -0.490059348012483850f, + 0.871595086655950980f, -0.490226483288291160f, 0.871501070882612530f, + -0.490393600539871970f, + 0.871407023066670950f, -0.490560699761082020f, 0.871312943211584030f, + -0.490727780945777400f, + 0.871218831320811020f, -0.490894844087815090f, 0.871124687397811900f, + -0.491061889181052650f, + 0.871030511446048260f, -0.491228916219348280f, 0.870936303468982760f, + -0.491395925196560780f, + 0.870842063470078980f, -0.491562916106549900f, 0.870747791452801790f, + -0.491729888943175760f, + 0.870653487420617430f, -0.491896843700299290f, 0.870559151376993250f, + -0.492063780371782000f, + 0.870464783325397670f, -0.492230698951486020f, 0.870370383269300270f, + -0.492397599433274380f, + 0.870275951212171940f, -0.492564481811010590f, 0.870181487157484560f, + -0.492731346078558840f, + 0.870086991108711460f, -0.492898192229784040f, 0.869992463069326870f, + -0.493065020258551700f, + 0.869897903042806340f, -0.493231830158727900f, 0.869803311032626650f, + -0.493398621924179770f, + 0.869708687042265670f, -0.493565395548774770f, 0.869614031075202300f, + -0.493732151026381020f, + 0.869519343134916860f, -0.493898888350867480f, 0.869424623224890890f, + -0.494065607516103570f, + 0.869329871348606840f, -0.494232308515959670f, 0.869235087509548370f, + -0.494398991344306650f, + 0.869140271711200560f, -0.494565655995015950f, 0.869045423957049530f, + -0.494732302461959870f, + 0.868950544250582380f, -0.494898930739011260f, 0.868855632595287860f, + -0.495065540820043560f, + 0.868760688994655310f, -0.495232132698931180f, 0.868665713452175690f, + -0.495398706369549020f, + 0.868570705971340900f, -0.495565261825772540f, 0.868475666555644120f, + -0.495731799061477960f, + 0.868380595208579800f, -0.495898318070542190f, 0.868285491933643350f, + -0.496064818846842890f, + 0.868190356734331310f, -0.496231301384258250f, 0.868095189614141670f, + -0.496397765676667160f, + 0.867999990576573510f, -0.496564211717949290f, 0.867904759625126920f, + -0.496730639501984760f, + 0.867809496763303320f, -0.496897049022654470f, 0.867714201994605140f, + -0.497063440273840250f, + 0.867618875322536230f, -0.497229813249424220f, 0.867523516750601460f, + -0.497396167943289280f, + 0.867428126282306920f, -0.497562504349319150f, 0.867332703921159800f, + -0.497728822461397940f, + 0.867237249670668400f, -0.497895122273410870f, 0.867141763534342470f, + -0.498061403779243410f, + 0.867046245515692650f, -0.498227666972781870f, 0.866950695618230900f, + -0.498393911847913210f, + 0.866855113845470430f, -0.498560138398525140f, 0.866759500200925400f, + -0.498726346618505900f, + 0.866663854688111130f, -0.498892536501744590f, 0.866568177310544470f, + -0.499058708042130870f, + 0.866472468071743050f, -0.499224861233555080f, 0.866376726975225830f, + -0.499390996069908170f, + 0.866280954024512990f, -0.499557112545081840f, 0.866185149223125840f, + -0.499723210652968540f, + 0.866089312574586770f, -0.499889290387461330f, 0.865993444082419520f, + -0.500055351742453860f, + 0.865897543750148820f, -0.500221394711840680f, 0.865801611581300760f, + -0.500387419289516580f, + 0.865705647579402380f, -0.500553425469377420f, 0.865609651747981990f, + -0.500719413245319880f, + 0.865513624090569090f, -0.500885382611240710f, 0.865417564610694410f, + -0.501051333561038040f, + 0.865321473311889800f, -0.501217266088609950f, 0.865225350197688200f, + -0.501383180187855770f, + 0.865129195271623800f, -0.501549075852675390f, 0.865033008537231860f, + -0.501714953076969120f, + 0.864936789998049020f, -0.501880811854638290f, 0.864840539657612870f, + -0.502046652179584660f, + 0.864744257519462380f, -0.502212474045710790f, 0.864647943587137480f, + -0.502378277446919760f, + 0.864551597864179340f, -0.502544062377115690f, 0.864455220354130360f, + -0.502709828830202990f, + 0.864358811060534030f, -0.502875576800086990f, 0.864262369986934950f, + -0.503041306280673450f, + 0.864165897136879300f, -0.503207017265868920f, 0.864069392513913790f, + -0.503372709749581040f, + 0.863972856121586810f, -0.503538383725717580f, 0.863876287963447510f, + -0.503704039188187070f, + 0.863779688043046720f, -0.503869676130898950f, 0.863683056363935830f, + -0.504035294547763190f, + 0.863586392929668100f, -0.504200894432690340f, 0.863489697743797140f, + -0.504366475779592040f, + 0.863392970809878420f, -0.504532038582380270f, 0.863296212131468230f, + -0.504697582834967570f, + 0.863199421712124160f, -0.504863108531267590f, 0.863102599555404910f, + -0.505028615665194080f, + 0.863005745664870320f, -0.505194104230662240f, 0.862908860044081400f, + -0.505359574221587280f, + 0.862811942696600330f, -0.505525025631885390f, 0.862714993625990690f, + -0.505690458455473450f, + 0.862618012835816740f, -0.505855872686268860f, 0.862521000329644520f, + -0.506021268318189720f, + 0.862423956111040610f, -0.506186645345155230f, 0.862326880183573060f, + -0.506352003761084800f, + 0.862229772550811240f, -0.506517343559898530f, 0.862132633216325380f, + -0.506682664735517600f, + 0.862035462183687210f, -0.506847967281863210f, 0.861938259456469290f, + -0.507013251192858230f, + 0.861841025038245330f, -0.507178516462425180f, 0.861743758932590700f, + -0.507343763084487920f, + 0.861646461143081300f, -0.507508991052970870f, 0.861549131673294720f, + -0.507674200361798890f, + 0.861451770526809320f, -0.507839391004897720f, 0.861354377707204910f, + -0.508004562976194010f, + 0.861256953218062170f, -0.508169716269614600f, 0.861159497062963350f, + -0.508334850879087360f, + 0.861062009245491480f, -0.508499966798540930f, 0.860964489769231010f, + -0.508665064021904030f, + 0.860866938637767310f, -0.508830142543106990f, 0.860769355854687170f, + -0.508995202356080090f, + 0.860671741423578380f, -0.509160243454754640f, 0.860574095348029980f, + -0.509325265833062480f, + 0.860476417631632070f, -0.509490269484936360f, 0.860378708277976130f, + -0.509655254404309250f, + 0.860280967290654510f, -0.509820220585115450f, 0.860183194673260990f, + -0.509985168021289460f, + 0.860085390429390140f, -0.510150096706766810f, 0.859987554562638200f, + -0.510315006635483240f, + 0.859889687076602290f, -0.510479897801375700f, 0.859791787974880650f, + -0.510644770198381610f, + 0.859693857261072610f, -0.510809623820439040f, 0.859595894938779080f, + -0.510974458661486830f, + 0.859497901011601730f, -0.511139274715464390f, 0.859399875483143450f, + -0.511304071976312000f, + 0.859301818357008470f, -0.511468850437970300f, 0.859203729636801920f, + -0.511633610094381240f, + 0.859105609326130450f, -0.511798350939486890f, 0.859007457428601520f, + -0.511963072967230200f, + 0.858909273947823900f, -0.512127776171554690f, 0.858811058887407610f, + -0.512292460546404870f, + 0.858712812250963520f, -0.512457126085725690f, 0.858614534042104190f, + -0.512621772783462990f, + 0.858516224264442740f, -0.512786400633562960f, 0.858417882921593930f, + -0.512951009629972980f, + 0.858319510017173440f, -0.513115599766640560f, 0.858221105554798250f, + -0.513280171037514220f, + 0.858122669538086140f, -0.513444723436543460f, 0.858024201970656540f, + -0.513609256957677780f, + 0.857925702856129790f, -0.513773771594868030f, 0.857827172198127430f, + -0.513938267342065380f, + 0.857728610000272120f, -0.514102744193221660f, 0.857630016266187620f, + -0.514267202142289710f, + 0.857531390999499150f, -0.514431641183222820f, 0.857432734203832700f, + -0.514596061309975040f, + 0.857334045882815590f, -0.514760462516501200f, 0.857235326040076460f, + -0.514924844796756490f, + 0.857136574679244980f, -0.515089208144697160f, 0.857037791803951680f, + -0.515253552554280180f, + 0.856938977417828760f, -0.515417878019462930f, 0.856840131524509220f, + -0.515582184534203790f, + 0.856741254127627470f, -0.515746472092461380f, 0.856642345230818840f, + -0.515910740688195650f, + 0.856543404837719960f, -0.516074990315366630f, 0.856444432951968590f, + -0.516239220967935510f, + 0.856345429577203610f, -0.516403432639863990f, 0.856246394717065210f, + -0.516567625325114350f, + 0.856147328375194470f, -0.516731799017649870f, 0.856048230555233940f, + -0.516895953711434150f, + 0.855949101260826910f, -0.517060089400431910f, 0.855849940495618240f, + -0.517224206078608310f, + 0.855750748263253920f, -0.517388303739929060f, 0.855651524567380690f, + -0.517552382378360880f, + 0.855552269411646860f, -0.517716441987871150f, 0.855452982799701830f, + -0.517880482562427690f, + 0.855353664735196030f, -0.518044504095999340f, 0.855254315221780970f, + -0.518208506582555460f, + 0.855154934263109620f, -0.518372490016066110f, 0.855055521862835950f, + -0.518536454390502220f, + 0.854956078024614930f, -0.518700399699834950f, 0.854856602752102850f, + -0.518864325938036890f, + 0.854757096048957220f, -0.519028233099080860f, 0.854657557918836460f, + -0.519192121176940250f, + 0.854557988365400530f, -0.519355990165589640f, 0.854458387392310170f, + -0.519519840059003760f, + 0.854358755003227440f, -0.519683670851158410f, 0.854259091201815530f, + -0.519847482536030190f, + 0.854159395991738850f, -0.520011275107596040f, 0.854059669376662780f, + -0.520175048559833760f, + 0.853959911360254180f, -0.520338802886721960f, 0.853860121946180770f, + -0.520502538082239670f, + 0.853760301138111410f, -0.520666254140367160f, 0.853660448939716380f, + -0.520829951055084670f, + 0.853560565354666840f, -0.520993628820373920f, 0.853460650386635320f, + -0.521157287430216610f, + 0.853360704039295430f, -0.521320926878595660f, 0.853260726316321880f, + -0.521484547159494330f, + 0.853160717221390420f, -0.521648148266897090f, 0.853060676758178320f, + -0.521811730194788550f, + 0.852960604930363630f, -0.521975292937154390f, 0.852860501741625750f, + -0.522138836487980760f, + 0.852760367195645300f, -0.522302360841254590f, 0.852660201296103760f, + -0.522465865990963780f, + 0.852560004046684080f, -0.522629351931096610f, 0.852459775451070100f, + -0.522792818655642090f, + 0.852359515512947090f, -0.522956266158590140f, 0.852259224236001090f, + -0.523119694433931250f, + 0.852158901623919830f, -0.523283103475656430f, 0.852058547680391690f, + -0.523446493277757830f, + 0.851958162409106380f, -0.523609863834227920f, 0.851857745813754840f, + -0.523773215139060170f, + 0.851757297898029120f, -0.523936547186248600f, 0.851656818665622370f, + -0.524099859969787700f, + 0.851556308120228980f, -0.524263153483673360f, 0.851455766265544310f, + -0.524426427721901400f, + 0.851355193105265200f, -0.524589682678468950f, 0.851254588643089120f, + -0.524752918347373360f, + 0.851153952882715340f, -0.524916134722613000f, 0.851053285827843790f, + -0.525079331798186780f, + 0.850952587482175730f, -0.525242509568094710f, 0.850851857849413530f, + -0.525405668026336930f, + 0.850751096933260790f, -0.525568807166914680f, 0.850650304737422090f, + -0.525731926983829760f, + 0.850549481265603480f, -0.525895027471084630f, 0.850448626521511760f, + -0.526058108622682760f, + 0.850347740508854980f, -0.526221170432628060f, 0.850246823231342710f, + -0.526384212894925100f, + 0.850145874692685210f, -0.526547236003579440f, 0.850044894896594180f, + -0.526710239752597010f, + 0.849943883846782210f, -0.526873224135984590f, 0.849842841546963320f, + -0.527036189147750080f, + 0.849741768000852550f, -0.527199134781901280f, 0.849640663212165910f, + -0.527362061032447540f, + 0.849539527184620890f, -0.527524967893398200f, 0.849438359921936060f, + -0.527687855358763720f, + 0.849337161427830780f, -0.527850723422555230f, 0.849235931706025960f, + -0.528013572078784630f, + 0.849134670760243630f, -0.528176401321464370f, 0.849033378594206800f, + -0.528339211144607690f, + 0.848932055211639610f, -0.528502001542228480f, 0.848830700616267530f, + -0.528664772508341320f, + 0.848729314811817130f, -0.528827524036961870f, 0.848627897802015860f, + -0.528990256122106040f, + 0.848526449590592650f, -0.529152968757790610f, 0.848424970181277600f, + -0.529315661938033260f, + 0.848323459577801640f, -0.529478335656851980f, 0.848221917783896990f, + -0.529640989908265910f, + 0.848120344803297230f, -0.529803624686294610f, 0.848018740639736810f, + -0.529966239984958620f, + 0.847917105296951410f, -0.530128835798278960f, 0.847815438778677930f, + -0.530291412120277310f, + 0.847713741088654380f, -0.530453968944976320f, 0.847612012230619660f, + -0.530616506266399330f, + 0.847510252208314330f, -0.530779024078570140f, 0.847408461025479730f, + -0.530941522375513620f, + 0.847306638685858320f, -0.531104001151255000f, 0.847204785193194090f, + -0.531266460399820390f, + 0.847102900551231500f, -0.531428900115236800f, 0.847000984763716880f, + -0.531591320291531670f, + 0.846899037834397240f, -0.531753720922733320f, 0.846797059767020910f, + -0.531916102002870650f, + 0.846695050565337450f, -0.532078463525973540f, 0.846593010233097190f, + -0.532240805486072220f, + 0.846490938774052130f, -0.532403127877197900f, 0.846388836191954930f, + -0.532565430693382580f, + 0.846286702490559710f, -0.532727713928658810f, 0.846184537673621560f, + -0.532889977577059800f, + 0.846082341744897050f, -0.533052221632619450f, 0.845980114708143270f, + -0.533214446089372960f, + 0.845877856567119000f, -0.533376650941355330f, 0.845775567325584010f, + -0.533538836182603120f, + 0.845673246987299070f, -0.533701001807152960f, 0.845570895556026270f, + -0.533863147809042650f, + 0.845468513035528830f, -0.534025274182310380f, 0.845366099429570970f, + -0.534187380920995380f, + 0.845263654741918220f, -0.534349468019137520f, 0.845161178976337140f, + -0.534511535470777120f, + 0.845058672136595470f, -0.534673583269955510f, 0.844956134226462210f, + -0.534835611410714560f, + 0.844853565249707120f, -0.534997619887097150f, 0.844750965210101510f, + -0.535159608693146600f, + 0.844648334111417820f, -0.535321577822907120f, 0.844545671957429240f, + -0.535483527270423370f, + 0.844442978751910660f, -0.535645457029741090f, 0.844340254498637590f, + -0.535807367094906390f, + 0.844237499201387020f, -0.535969257459966710f, 0.844134712863936930f, + -0.536131128118969460f, + 0.844031895490066410f, -0.536292979065963180f, 0.843929047083555870f, + -0.536454810294997090f, + 0.843826167648186740f, -0.536616621800121040f, 0.843723257187741660f, + -0.536778413575385920f, + 0.843620315706004150f, -0.536940185614842910f, 0.843517343206759200f, + -0.537101937912544130f, + 0.843414339693792760f, -0.537263670462542530f, 0.843311305170892140f, + -0.537425383258891550f, + 0.843208239641845440f, -0.537587076295645390f, 0.843105143110442160f, + -0.537748749566859360f, + 0.843002015580472940f, -0.537910403066588880f, 0.842898857055729310f, + -0.538072036788890600f, + 0.842795667540004120f, -0.538233650727821700f, 0.842692447037091670f, + -0.538395244877439950f, + 0.842589195550786710f, -0.538556819231804100f, 0.842485913084885630f, + -0.538718373784973560f, + 0.842382599643185850f, -0.538879908531008420f, 0.842279255229485990f, + -0.539041423463969440f, + 0.842175879847585570f, -0.539202918577918240f, 0.842072473501285560f, + -0.539364393866917040f, + 0.841969036194387680f, -0.539525849325028890f, 0.841865567930695340f, + -0.539687284946317570f, + 0.841762068714012490f, -0.539848700724847590f, 0.841658538548144760f, + -0.540010096654684020f, + 0.841554977436898440f, -0.540171472729892850f, 0.841451385384081260f, + -0.540332828944540710f, + 0.841347762393501950f, -0.540494165292695230f, 0.841244108468970580f, + -0.540655481768424150f, + 0.841140423614298080f, -0.540816778365796670f, 0.841036707833296650f, + -0.540978055078882080f, + 0.840932961129779780f, -0.541139311901750800f, 0.840829183507561640f, + -0.541300548828474120f, + 0.840725374970458070f, -0.541461765853123440f, 0.840621535522285690f, + -0.541622962969771530f, + 0.840517665166862550f, -0.541784140172491550f, 0.840413763908007480f, + -0.541945297455357360f, + 0.840309831749540770f, -0.542106434812443920f, 0.840205868695283580f, + -0.542267552237826520f, + 0.840101874749058400f, -0.542428649725581250f, 0.839997849914688840f, + -0.542589727269785270f, + 0.839893794195999520f, -0.542750784864515890f, 0.839789707596816370f, + -0.542911822503851730f, + 0.839685590120966110f, -0.543072840181871740f, 0.839581441772277120f, + -0.543233837892655890f, + 0.839477262554578550f, -0.543394815630284800f, 0.839373052471700690f, + -0.543555773388839540f, + 0.839268811527475230f, -0.543716711162402280f, 0.839164539725734680f, + -0.543877628945055980f, + 0.839060237070312740f, -0.544038526730883820f, 0.838955903565044460f, + -0.544199404513970310f, + 0.838851539213765760f, -0.544360262288400400f, 0.838747144020313920f, + -0.544521100048259600f, + 0.838642717988527300f, -0.544681917787634530f, 0.838538261122245280f, + -0.544842715500612360f, + 0.838433773425308340f, -0.545003493181281160f, 0.838329254901558300f, + -0.545164250823729320f, + 0.838224705554838080f, -0.545324988422046460f, 0.838120125388991500f, + -0.545485705970322530f, + 0.838015514407863820f, -0.545646403462648590f, 0.837910872615301170f, + -0.545807080893116140f, + 0.837806200015150940f, -0.545967738255817570f, 0.837701496611261700f, + -0.546128375544845950f, + 0.837596762407483040f, -0.546288992754295210f, 0.837491997407665890f, + -0.546449589878259650f, + 0.837387201615661940f, -0.546610166910834860f, 0.837282375035324320f, + -0.546770723846116800f, + 0.837177517670507300f, -0.546931260678202190f, 0.837072629525066000f, + -0.547091777401188530f, + 0.836967710602857020f, -0.547252274009174090f, 0.836862760907737920f, + -0.547412750496257930f, + 0.836757780443567190f, -0.547573206856539760f, 0.836652769214204950f, + -0.547733643084120090f, + 0.836547727223512010f, -0.547894059173100190f, 0.836442654475350380f, + -0.548054455117581880f, + 0.836337550973583530f, -0.548214830911667780f, 0.836232416722075600f, + -0.548375186549461600f, + 0.836127251724692270f, -0.548535522025067390f, 0.836022055985299880f, + -0.548695837332590090f, + 0.835916829507766360f, -0.548856132466135290f, 0.835811572295960700f, + -0.549016407419809390f, + 0.835706284353752600f, -0.549176662187719660f, 0.835600965685013410f, + -0.549336896763974010f, + 0.835495616293615350f, -0.549497111142680960f, 0.835390236183431890f, + -0.549657305317949870f, + 0.835284825358337370f, -0.549817479283890910f, 0.835179383822207690f, + -0.549977633034614890f, + 0.835073911578919410f, -0.550137766564233630f, 0.834968408632350450f, + -0.550297879866859190f, + 0.834862874986380010f, -0.550457972936604810f, 0.834757310644888230f, + -0.550618045767584330f, + 0.834651715611756440f, -0.550778098353912120f, 0.834546089890866870f, + -0.550938130689703880f, + 0.834440433486103190f, -0.551098142769075430f, 0.834334746401350080f, + -0.551258134586143590f, + 0.834229028640493420f, -0.551418106135026060f, 0.834123280207420100f, + -0.551578057409841000f, + 0.834017501106018130f, -0.551737988404707340f, 0.833911691340176840f, + -0.551897899113745210f, + 0.833805850913786340f, -0.552057789531074980f, 0.833699979830738290f, + -0.552217659650817930f, + 0.833594078094925140f, -0.552377509467096070f, 0.833488145710240770f, + -0.552537338974032120f, + 0.833382182680579730f, -0.552697148165749770f, 0.833276189009838240f, + -0.552856937036373290f, + 0.833170164701913190f, -0.553016705580027470f, 0.833064109760702890f, + -0.553176453790838350f, + 0.832958024190106670f, -0.553336181662932300f, 0.832851907994025090f, + -0.553495889190436570f, + 0.832745761176359460f, -0.553655576367479310f, 0.832639583741012770f, + -0.553815243188189090f, + 0.832533375691888680f, -0.553974889646695500f, 0.832427137032892280f, + -0.554134515737128910f, + 0.832320867767929680f, -0.554294121453620000f, 0.832214567900907980f, + -0.554453706790300930f, + 0.832108237435735590f, -0.554613271741304040f, 0.832001876376321950f, + -0.554772816300762470f, + 0.831895484726577590f, -0.554932340462810370f, 0.831789062490414400f, + -0.555091844221582420f, + 0.831682609671745120f, -0.555251327571213980f, 0.831576126274483740f, + -0.555410790505841630f, + 0.831469612302545240f, -0.555570233019602180f, 0.831363067759845920f, + -0.555729655106633410f, + 0.831256492650303210f, -0.555889056761073810f, 0.831149886977835540f, + -0.556048437977062600f, + 0.831043250746362320f, -0.556207798748739930f, 0.830936583959804410f, + -0.556367139070246370f, + 0.830829886622083570f, -0.556526458935723610f, 0.830723158737122880f, + -0.556685758339313890f, + 0.830616400308846310f, -0.556845037275160100f, 0.830509611341179070f, + -0.557004295737405950f, + 0.830402791838047550f, -0.557163533720196220f, 0.830295941803379070f, + -0.557322751217676160f, + 0.830189061241102370f, -0.557481948223991550f, 0.830082150155146970f, + -0.557641124733289420f, + 0.829975208549443950f, -0.557800280739716990f, 0.829868236427924840f, + -0.557959416237422960f, + 0.829761233794523050f, -0.558118531220556100f, 0.829654200653172640f, + -0.558277625683266330f, + 0.829547137007808910f, -0.558436699619704100f, 0.829440042862368170f, + -0.558595753024020760f, + 0.829332918220788250f, -0.558754785890368310f, 0.829225763087007570f, + -0.558913798212899770f, + 0.829118577464965980f, -0.559072789985768480f, 0.829011361358604430f, + -0.559231761203128900f, + 0.828904114771864870f, -0.559390711859136140f, 0.828796837708690610f, + -0.559549641947945760f, + 0.828689530173025820f, -0.559708551463714680f, 0.828582192168815790f, + -0.559867440400600210f, + 0.828474823700007130f, -0.560026308752760380f, 0.828367424770547480f, + -0.560185156514354080f, + 0.828259995384385660f, -0.560343983679540860f, 0.828152535545471410f, + -0.560502790242481060f, + 0.828045045257755800f, -0.560661576197336030f, 0.827937524525190870f, + -0.560820341538267430f, + 0.827829973351729920f, -0.560979086259438150f, 0.827722391741327220f, + -0.561137810355011420f, + 0.827614779697938400f, -0.561296513819151470f, 0.827507137225519830f, + -0.561455196646023280f, + 0.827399464328029470f, -0.561613858829792420f, 0.827291761009425810f, + -0.561772500364625340f, + 0.827184027273669130f, -0.561931121244689470f, 0.827076263124720270f, + -0.562089721464152480f, + 0.826968468566541600f, -0.562248301017183150f, 0.826860643603096190f, + -0.562406859897951140f, + 0.826752788238348520f, -0.562565398100626560f, 0.826644902476264320f, + -0.562723915619380400f, + 0.826536986320809960f, -0.562882412448384440f, 0.826429039775953500f, + -0.563040888581811230f, + 0.826321062845663530f, -0.563199344013834090f, 0.826213055533910220f, + -0.563357778738627020f, + 0.826105017844664610f, -0.563516192750364800f, 0.825996949781899080f, + -0.563674586043223070f, + 0.825888851349586780f, -0.563832958611378170f, 0.825780722551702430f, + -0.563991310449006970f, + 0.825672563392221390f, -0.564149641550287680f, 0.825564373875120490f, + -0.564307951909398640f, + 0.825456154004377550f, -0.564466241520519500f, 0.825347903783971380f, + -0.564624510377830120f, + 0.825239623217882250f, -0.564782758475511400f, 0.825131312310091070f, + -0.564940985807745210f, + 0.825022971064580220f, -0.565099192368713980f, 0.824914599485333190f, + -0.565257378152600800f, + 0.824806197576334330f, -0.565415543153589660f, 0.824697765341569470f, + -0.565573687365865330f, + 0.824589302785025290f, -0.565731810783613120f, 0.824480809910689500f, + -0.565889913401019570f, + 0.824372286722551250f, -0.566047995212271450f, 0.824263733224600560f, + -0.566206056211556730f, + 0.824155149420828570f, -0.566364096393063840f, 0.824046535315227760f, + -0.566522115750982100f, + 0.823937890911791370f, -0.566680114279501600f, 0.823829216214513990f, + -0.566838091972813320f, + 0.823720511227391430f, -0.566996048825108680f, 0.823611775954420260f, + -0.567153984830580100f, + 0.823503010399598500f, -0.567311899983420800f, 0.823394214566925080f, + -0.567469794277824510f, + 0.823285388460400110f, -0.567627667707986230f, 0.823176532084024860f, + -0.567785520268101140f, + 0.823067645441801670f, -0.567943351952365560f, 0.822958728537734000f, + -0.568101162754976460f, + 0.822849781375826430f, -0.568258952670131490f, 0.822740803960084420f, + -0.568416721692029280f, + 0.822631796294514990f, -0.568574469814869140f, 0.822522758383125940f, + -0.568732197032851050f, + 0.822413690229926390f, -0.568889903340175860f, 0.822304591838926350f, + -0.569047588731045110f, + 0.822195463214137170f, -0.569205253199661200f, 0.822086304359571090f, + -0.569362896740227220f, + 0.821977115279241550f, -0.569520519346947140f, 0.821867895977163250f, + -0.569678121014025600f, + 0.821758646457351750f, -0.569835701735668000f, 0.821649366723823940f, + -0.569993261506080540f, + 0.821540056780597610f, -0.570150800319470300f, 0.821430716631691870f, + -0.570308318170044900f, + 0.821321346281126740f, -0.570465815052012990f, 0.821211945732923550f, + -0.570623290959583750f, + 0.821102514991104650f, -0.570780745886967260f, 0.820993054059693580f, + -0.570938179828374360f, + 0.820883562942714580f, -0.571095592778016690f, 0.820774041644193650f, + -0.571252984730106660f, + 0.820664490168157460f, -0.571410355678857230f, 0.820554908518633890f, + -0.571567705618482580f, + 0.820445296699652050f, -0.571725034543197120f, 0.820335654715241840f, + -0.571882342447216590f, + 0.820225982569434690f, -0.572039629324757050f, 0.820116280266262820f, + -0.572196895170035580f, + 0.820006547809759680f, -0.572354139977269920f, 0.819896785203959810f, + -0.572511363740678790f, + 0.819786992452898990f, -0.572668566454481160f, 0.819677169560613870f, + -0.572825748112897550f, + 0.819567316531142230f, -0.572982908710148560f, 0.819457433368523280f, + -0.573140048240455950f, + 0.819347520076796900f, -0.573297166698042200f, 0.819237576660004520f, + -0.573454264077130400f, + 0.819127603122188240f, -0.573611340371944610f, 0.819017599467391500f, + -0.573768395576709560f, + 0.818907565699658950f, -0.573925429685650750f, 0.818797501823036010f, + -0.574082442692994470f, + 0.818687407841569680f, -0.574239434592967890f, 0.818577283759307610f, + -0.574396405379798750f, + 0.818467129580298660f, -0.574553355047715760f, 0.818356945308593150f, + -0.574710283590948330f, + 0.818246730948242070f, -0.574867191003726740f, 0.818136486503297730f, + -0.575024077280281710f, + 0.818026211977813440f, -0.575180942414845080f, 0.817915907375843850f, + -0.575337786401649450f, + 0.817805572701444270f, -0.575494609234928120f, 0.817695207958671680f, + -0.575651410908915140f, + 0.817584813151583710f, -0.575808191417845340f, 0.817474388284239240f, + -0.575964950755954220f, + 0.817363933360698460f, -0.576121688917478280f, 0.817253448385022340f, + -0.576278405896654910f, + 0.817142933361272970f, -0.576435101687721830f, 0.817032388293513880f, + -0.576591776284917760f, + 0.816921813185809480f, -0.576748429682482410f, 0.816811208042225290f, + -0.576905061874655960f, + 0.816700572866827850f, -0.577061672855679440f, 0.816589907663684890f, + -0.577218262619794920f, + 0.816479212436865390f, -0.577374831161244880f, 0.816368487190439200f, + -0.577531378474272720f, + 0.816257731928477390f, -0.577687904553122800f, 0.816146946655052270f, + -0.577844409392039850f, + 0.816036131374236810f, -0.578000892985269910f, 0.815925286090105510f, + -0.578157355327059360f, + 0.815814410806733780f, -0.578313796411655590f, 0.815703505528198260f, + -0.578470216233306630f, + 0.815592570258576790f, -0.578626614786261430f, 0.815481605001947770f, + -0.578782992064769690f, + 0.815370609762391290f, -0.578939348063081780f, 0.815259584543988280f, + -0.579095682775449090f, + 0.815148529350820830f, -0.579251996196123550f, 0.815037444186972220f, + -0.579408288319357870f, + 0.814926329056526620f, -0.579564559139405630f, 0.814815183963569440f, + -0.579720808650521450f, + 0.814704008912187080f, -0.579877036846960350f, 0.814592803906467270f, + -0.580033243722978150f, + 0.814481568950498610f, -0.580189429272831680f, 0.814370304048371070f, + -0.580345593490778300f, + 0.814259009204175270f, -0.580501736371076490f, 0.814147684422003360f, + -0.580657857907985300f, + 0.814036329705948410f, -0.580813958095764530f, 0.813924945060104600f, + -0.580970036928674770f, + 0.813813530488567190f, -0.581126094400977620f, 0.813702085995432700f, + -0.581282130506935000f, + 0.813590611584798510f, -0.581438145240810170f, 0.813479107260763220f, + -0.581594138596866930f, + 0.813367573027426570f, -0.581750110569369650f, 0.813256008888889380f, + -0.581906061152583810f, + 0.813144414849253590f, -0.582061990340775440f, 0.813032790912622040f, + -0.582217898128211670f, + 0.812921137083098770f, -0.582373784509160110f, 0.812809453364789270f, + -0.582529649477889320f, + 0.812697739761799490f, -0.582685493028668460f, 0.812585996278237130f, + -0.582841315155767650f, + 0.812474222918210480f, -0.582997115853457700f, 0.812362419685829230f, + -0.583152895116010430f, + 0.812250586585203880f, -0.583308652937698290f, 0.812138723620446480f, + -0.583464389312794320f, + 0.812026830795669730f, -0.583620104235572760f, 0.811914908114987790f, + -0.583775797700308070f, + 0.811802955582515470f, -0.583931469701276180f, 0.811690973202369050f, + -0.584087120232753440f, + 0.811578960978665890f, -0.584242749289016980f, 0.811466918915524250f, + -0.584398356864344600f, + 0.811354847017063730f, -0.584553942953015330f, 0.811242745287404810f, + -0.584709507549308390f, + 0.811130613730669190f, -0.584865050647504490f, 0.811018452350979470f, + -0.585020572241884530f, + 0.810906261152459670f, -0.585176072326730410f, 0.810794040139234730f, + -0.585331550896324940f, + 0.810681789315430780f, -0.585487007944951340f, 0.810569508685174630f, + -0.585642443466894420f, + 0.810457198252594770f, -0.585797857456438860f, 0.810344858021820550f, + -0.585953249907870570f, + 0.810232487996982330f, -0.586108620815476430f, 0.810120088182211600f, + -0.586263970173543590f, + 0.810007658581641140f, -0.586419297976360500f, 0.809895199199404450f, + -0.586574604218216170f, + 0.809782710039636530f, -0.586729888893400390f, 0.809670191106473090f, + -0.586885151996203950f, + 0.809557642404051260f, -0.587040393520917970f, 0.809445063936509170f, + -0.587195613461834800f, + 0.809332455707985950f, -0.587350811813247660f, 0.809219817722621750f, + -0.587505988569450020f, + 0.809107149984558240f, -0.587661143724736660f, 0.808994452497937670f, + -0.587816277273402910f, + 0.808881725266903610f, -0.587971389209745010f, 0.808768968295600850f, + -0.588126479528059850f, + 0.808656181588174980f, -0.588281548222645220f, 0.808543365148773010f, + -0.588436595287799790f, + 0.808430518981542720f, -0.588591620717822890f, 0.808317643090633250f, + -0.588746624507014540f, + 0.808204737480194720f, -0.588901606649675720f, 0.808091802154378370f, + -0.589056567140108460f, + 0.807978837117336310f, -0.589211505972614960f, 0.807865842373222120f, + -0.589366423141498790f, + 0.807752817926190360f, -0.589521318641063940f, 0.807639763780396480f, + -0.589676192465615420f, + 0.807526679939997160f, -0.589831044609458790f, 0.807413566409150190f, + -0.589985875066900920f, + 0.807300423192014450f, -0.590140683832248820f, 0.807187250292749960f, + -0.590295470899810830f, + 0.807074047715517610f, -0.590450236263895810f, 0.806960815464479730f, + -0.590604979918813330f, + 0.806847553543799330f, -0.590759701858874160f, 0.806734261957640860f, + -0.590914402078389520f, + 0.806620940710169650f, -0.591069080571671400f, 0.806507589805552260f, + -0.591223737333032910f, + 0.806394209247956240f, -0.591378372356787580f, 0.806280799041550480f, + -0.591532985637249990f, + 0.806167359190504420f, -0.591687577168735430f, 0.806053889698989060f, + -0.591842146945560140f, + 0.805940390571176280f, -0.591996694962040990f, 0.805826861811239300f, + -0.592151221212495530f, + 0.805713303423352230f, -0.592305725691242290f, 0.805599715411690060f, + -0.592460208392600830f, + 0.805486097780429230f, -0.592614669310891130f, 0.805372450533747060f, + -0.592769108440434070f, + 0.805258773675822210f, -0.592923525775551300f, 0.805145067210834230f, + -0.593077921310565470f, + 0.805031331142963660f, -0.593232295039799800f, 0.804917565476392260f, + -0.593386646957578480f, + 0.804803770215302920f, -0.593540977058226390f, 0.804689945363879500f, + -0.593695285336069190f, + 0.804576090926307110f, -0.593849571785433630f, 0.804462206906771840f, + -0.594003836400646690f, + 0.804348293309460780f, -0.594158079176036800f, 0.804234350138562260f, + -0.594312300105932830f, + 0.804120377398265810f, -0.594466499184664430f, 0.804006375092761520f, + -0.594620676406562240f, + 0.803892343226241260f, -0.594774831765957580f, 0.803778281802897570f, + -0.594928965257182420f, + 0.803664190826924090f, -0.595083076874569960f, 0.803550070302515680f, + -0.595237166612453850f, + 0.803435920233868120f, -0.595391234465168730f, 0.803321740625178580f, + -0.595545280427049790f, + 0.803207531480644940f, -0.595699304492433360f, 0.803093292804466400f, + -0.595853306655656280f, + 0.802979024600843250f, -0.596007286911056530f, 0.802864726873976700f, + -0.596161245252972540f, + 0.802750399628069160f, -0.596315181675743710f, 0.802636042867324150f, + -0.596469096173710360f, + 0.802521656595946430f, -0.596622988741213220f, 0.802407240818141300f, + -0.596776859372594390f, + 0.802292795538115720f, -0.596930708062196500f, 0.802178320760077450f, + -0.597084534804362740f, + 0.802063816488235440f, -0.597238339593437420f, 0.801949282726799770f, + -0.597392122423765710f, + 0.801834719479981310f, -0.597545883289693160f, 0.801720126751992330f, + -0.597699622185566830f, + 0.801605504547046150f, -0.597853339105733910f, 0.801490852869356950f, + -0.598007034044542700f, + 0.801376171723140240f, -0.598160706996342270f, 0.801261461112612540f, + -0.598314357955482600f, + 0.801146721041991360f, -0.598467986916314310f, 0.801031951515495330f, + -0.598621593873188920f, + 0.800917152537344300f, -0.598775178820458720f, 0.800802324111759110f, + -0.598928741752476900f, + 0.800687466242961610f, -0.599082282663597310f, 0.800572578935174860f, + -0.599235801548174570f, + 0.800457662192622820f, -0.599389298400564540f, 0.800342716019530660f, + -0.599542773215123390f, + 0.800227740420124790f, -0.599696225986208310f, 0.800112735398632370f, + -0.599849656708177250f, + 0.799997700959281910f, -0.600003065375388940f, 0.799882637106302810f, + -0.600156451982203240f, + 0.799767543843925680f, -0.600309816522980430f, 0.799652421176382240f, + -0.600463158992081580f, + 0.799537269107905010f, -0.600616479383868970f, 0.799422087642728040f, + -0.600769777692705230f, + 0.799306876785086160f, -0.600923053912954090f, 0.799191636539215210f, + -0.601076308038980160f, + 0.799076366909352350f, -0.601229540065148500f, 0.798961067899735760f, + -0.601382749985825420f, + 0.798845739514604580f, -0.601535937795377730f, 0.798730381758199210f, + -0.601689103488172950f, + 0.798614994634760820f, -0.601842247058580030f, 0.798499578148532120f, + -0.601995368500968020f, + 0.798384132303756380f, -0.602148467809707210f, 0.798268657104678430f, + -0.602301544979168550f, + 0.798153152555543750f, -0.602454600003723750f, 0.798037618660599410f, + -0.602607632877745440f, + 0.797922055424093000f, -0.602760643595607220f, 0.797806462850273570f, + -0.602913632151683030f, + 0.797690840943391160f, -0.603066598540348160f, 0.797575189707696700f, + -0.603219542755978440f, + 0.797459509147442460f, -0.603372464792950260f, 0.797343799266881700f, + -0.603525364645641550f, + 0.797228060070268700f, -0.603678242308430370f, 0.797112291561858920f, + -0.603831097775695880f, + 0.796996493745908750f, -0.603983931041818020f, 0.796880666626675780f, + -0.604136742101177520f, + 0.796764810208418830f, -0.604289530948155960f, 0.796648924495397260f, + -0.604442297577135860f, + 0.796533009491872000f, -0.604595041982500360f, 0.796417065202104980f, + -0.604747764158633410f, + 0.796301091630359110f, -0.604900464099919820f, 0.796185088780898440f, + -0.605053141800745320f, + 0.796069056657987990f, -0.605205797255496500f, 0.795952995265893910f, + -0.605358430458560530f, + 0.795836904608883570f, -0.605511041404325550f, 0.795720784691225090f, + -0.605663630087180380f, + 0.795604635517188070f, -0.605816196501514970f, 0.795488457091042990f, + -0.605968740641719680f, + 0.795372249417061310f, -0.606121262502186120f, 0.795256012499515610f, + -0.606273762077306430f, + 0.795139746342679590f, -0.606426239361473550f, 0.795023450950828050f, + -0.606578694349081290f, + 0.794907126328237010f, -0.606731127034524480f, 0.794790772479183170f, + -0.606883537412198470f, + 0.794674389407944550f, -0.607035925476499650f, 0.794557977118800380f, + -0.607188291221825160f, + 0.794441535616030590f, -0.607340634642572930f, 0.794325064903916520f, + -0.607492955733141550f, + 0.794208564986740640f, -0.607645254487930830f, 0.794092035868785960f, + -0.607797530901341140f, + 0.793975477554337170f, -0.607949784967773630f, 0.793858890047679730f, + -0.608102016681630440f, + 0.793742273353100210f, -0.608254226037314490f, 0.793625627474886300f, + -0.608406413029229150f, + 0.793508952417326660f, -0.608558577651779450f, 0.793392248184711100f, + -0.608710719899370310f, + 0.793275514781330630f, -0.608862839766408200f, 0.793158752211477140f, + -0.609014937247299830f, + 0.793041960479443640f, -0.609167012336453210f, 0.792925139589524260f, + -0.609319065028276820f, + 0.792808289546014120f, -0.609471095317180240f, 0.792691410353209450f, + -0.609623103197573730f, + 0.792574502015407690f, -0.609775088663868430f, 0.792457564536907080f, + -0.609927051710476120f, + 0.792340597922007170f, -0.610078992331809620f, 0.792223602175008310f, + -0.610230910522282620f, + 0.792106577300212390f, -0.610382806276309480f, 0.791989523301921850f, + -0.610534679588305320f, + 0.791872440184440470f, -0.610686530452686280f, 0.791755327952073150f, + -0.610838358863869170f, + 0.791638186609125880f, -0.610990164816271660f, 0.791521016159905220f, + -0.611141948304312570f, + 0.791403816608719500f, -0.611293709322410890f, 0.791286587959877830f, + -0.611445447864987000f, + 0.791169330217690200f, -0.611597163926461910f, 0.791052043386467950f, + -0.611748857501257290f, + 0.790934727470523290f, -0.611900528583796070f, 0.790817382474169770f, + -0.612052177168501470f, + 0.790700008401721610f, -0.612203803249797950f, 0.790582605257494460f, + -0.612355406822110650f, + 0.790465173045804880f, -0.612506987879865570f, 0.790347711770970520f, + -0.612658546417489290f, + 0.790230221437310030f, -0.612810082429409710f, 0.790112702049143300f, + -0.612961595910055170f, + 0.789995153610791090f, -0.613113086853854910f, 0.789877576126575280f, + -0.613264555255239040f, + 0.789759969600819070f, -0.613416001108638590f, 0.789642334037846340f, + -0.613567424408485330f, + 0.789524669441982190f, -0.613718825149211720f, 0.789406975817552930f, + -0.613870203325251330f, + 0.789289253168885650f, -0.614021558931038380f, 0.789171501500308900f, + -0.614172891961007990f, + 0.789053720816151880f, -0.614324202409595950f, 0.788935911120745240f, + -0.614475490271239040f, + 0.788818072418420280f, -0.614626755540375050f, 0.788700204713509660f, + -0.614777998211442080f, + 0.788582308010347120f, -0.614929218278879590f, 0.788464382313267540f, + -0.615080415737127460f, + 0.788346427626606340f, -0.615231590580626820f, 0.788228443954700490f, + -0.615382742803819220f, + 0.788110431301888070f, -0.615533872401147320f, 0.787992389672507950f, + -0.615684979367054570f, + 0.787874319070900220f, -0.615836063695985090f, 0.787756219501406060f, + -0.615987125382383760f, + 0.787638090968367450f, -0.616138164420696910f, 0.787519933476127810f, + -0.616289180805370980f, + 0.787401747029031430f, -0.616440174530853650f, 0.787283531631423620f, + -0.616591145591593110f, + 0.787165287287651010f, -0.616742093982038720f, 0.787047014002060790f, + -0.616893019696640680f, + 0.786928711779001810f, -0.617043922729849760f, 0.786810380622823490f, + -0.617194803076117630f, + 0.786692020537876790f, -0.617345660729896830f, 0.786573631528513230f, + -0.617496495685640910f, + 0.786455213599085770f, -0.617647307937803870f, 0.786336766753948260f, + -0.617798097480841020f, + 0.786218290997455660f, -0.617948864309208150f, 0.786099786333963930f, + -0.618099608417362000f, + 0.785981252767830150f, -0.618250329799760250f, 0.785862690303412600f, + -0.618401028450860980f, + 0.785744098945070360f, -0.618551704365123740f, 0.785625478697163700f, + -0.618702357537008530f, + 0.785506829564053930f, -0.618852987960976320f, 0.785388151550103550f, + -0.619003595631488660f, + 0.785269444659675850f, -0.619154180543008410f, 0.785150708897135560f, + -0.619304742689998690f, + 0.785031944266848080f, -0.619455282066924020f, 0.784913150773180020f, + -0.619605798668249270f, + 0.784794328420499230f, -0.619756292488440660f, 0.784675477213174320f, + -0.619906763521964720f, + 0.784556597155575240f, -0.620057211763289100f, 0.784437688252072830f, + -0.620207637206882430f, + 0.784318750507038920f, -0.620358039847213720f, 0.784199783924846570f, + -0.620508419678753360f, + 0.784080788509869950f, -0.620658776695972140f, 0.783961764266484120f, + -0.620809110893341900f, + 0.783842711199065230f, -0.620959422265335180f, 0.783723629311990470f, + -0.621109710806425630f, + 0.783604518609638200f, -0.621259976511087550f, 0.783485379096387820f, + -0.621410219373796150f, + 0.783366210776619720f, -0.621560439389027160f, 0.783247013654715380f, + -0.621710636551257690f, + 0.783127787735057310f, -0.621860810854965360f, 0.783008533022029110f, + -0.622010962294628600f, + 0.782889249520015480f, -0.622161090864726820f, 0.782769937233402050f, + -0.622311196559740320f, + 0.782650596166575730f, -0.622461279374149970f, 0.782531226323924240f, + -0.622611339302437730f, + 0.782411827709836530f, -0.622761376339086350f, 0.782292400328702400f, + -0.622911390478579460f, + 0.782172944184913010f, -0.623061381715401260f, 0.782053459282860300f, + -0.623211350044037270f, + 0.781933945626937630f, -0.623361295458973230f, 0.781814403221538830f, + -0.623511217954696440f, + 0.781694832071059390f, -0.623661117525694530f, 0.781575232179895550f, + -0.623810994166456130f, + 0.781455603552444590f, -0.623960847871470660f, 0.781335946193104870f, + -0.624110678635228510f, + 0.781216260106276090f, -0.624260486452220650f, 0.781096545296358520f, + -0.624410271316939270f, + 0.780976801767753750f, -0.624560033223877210f, 0.780857029524864580f, + -0.624709772167528100f, + 0.780737228572094490f, -0.624859488142386340f, 0.780617398913848400f, + -0.625009181142947460f, + 0.780497540554531910f, -0.625158851163707620f, 0.780377653498552040f, + -0.625308498199164010f, + 0.780257737750316590f, -0.625458122243814360f, 0.780137793314234610f, + -0.625607723292157410f, + 0.780017820194715990f, -0.625757301338692900f, 0.779897818396172000f, + -0.625906856377921090f, + 0.779777787923014550f, -0.626056388404343520f, 0.779657728779656890f, + -0.626205897412462130f, + 0.779537640970513260f, -0.626355383396779990f, 0.779417524499998900f, + -0.626504846351800810f, + 0.779297379372530300f, -0.626654286272029350f, 0.779177205592524680f, + -0.626803703151971200f, + 0.779057003164400630f, -0.626953096986132660f, 0.778936772092577500f, + -0.627102467769020900f, + 0.778816512381475980f, -0.627251815495144080f, 0.778696224035517530f, + -0.627401140159011050f, + 0.778575907059125050f, -0.627550441755131530f, 0.778455561456721900f, + -0.627699720278016240f, + 0.778335187232733210f, -0.627848975722176460f, 0.778214784391584540f, + -0.627998208082124700f, + 0.778094352937702790f, -0.628147417352374000f, 0.777973892875516100f, + -0.628296603527438320f, + 0.777853404209453150f, -0.628445766601832710f, 0.777732886943944050f, + -0.628594906570072550f, + 0.777612341083420030f, -0.628744023426674680f, 0.777491766632313010f, + -0.628893117166156480f, + 0.777371163595056310f, -0.629042187783036000f, 0.777250531976084070f, + -0.629191235271832290f, + 0.777129871779831620f, -0.629340259627065630f, 0.777009183010735290f, + -0.629489260843256630f, + 0.776888465673232440f, -0.629638238914926980f, 0.776767719771761510f, + -0.629787193836599200f, + 0.776646945310762060f, -0.629936125602796440f, 0.776526142294674430f, + -0.630085034208043180f, + 0.776405310727940390f, -0.630233919646864370f, 0.776284450615002510f, + -0.630382781913785940f, + 0.776163561960304340f, -0.630531621003334600f, 0.776042644768290770f, + -0.630680436910037940f, + 0.775921699043407690f, -0.630829229628424470f, 0.775800724790101650f, + -0.630977999153023550f, + 0.775679722012820650f, -0.631126745478365340f, 0.775558690716013580f, + -0.631275468598980760f, + 0.775437630904130540f, -0.631424168509401860f, 0.775316542581622530f, + -0.631572845204161020f, + 0.775195425752941420f, -0.631721498677792260f, 0.775074280422540450f, + -0.631870128924829850f, + 0.774953106594873930f, -0.632018735939809060f, 0.774831904274396850f, + -0.632167319717265920f, + 0.774710673465565550f, -0.632315880251737570f, 0.774589414172837550f, + -0.632464417537761840f, + 0.774468126400670860f, -0.632612931569877410f, 0.774346810153525130f, + -0.632761422342624000f, + 0.774225465435860680f, -0.632909889850541750f, 0.774104092252139050f, + -0.633058334088172140f, + 0.773982690606822900f, -0.633206755050057190f, 0.773861260504375540f, + -0.633355152730739950f, + 0.773739801949261840f, -0.633503527124764320f, 0.773618314945947460f, + -0.633651878226674900f, + 0.773496799498899050f, -0.633800206031017280f, 0.773375255612584470f, + -0.633948510532337810f, + 0.773253683291472590f, -0.634096791725183740f, 0.773132082540033070f, + -0.634245049604103330f, + 0.773010453362736990f, -0.634393284163645490f, 0.772888795764056220f, + -0.634541495398360020f, + 0.772767109748463850f, -0.634689683302797740f, 0.772645395320433860f, + -0.634837847871509990f, + 0.772523652484441330f, -0.634985989099049460f, 0.772401881244962450f, + -0.635134106979969190f, + 0.772280081606474320f, -0.635282201508823420f, 0.772158253573455240f, + -0.635430272680167160f, + 0.772036397150384520f, -0.635578320488556110f, 0.771914512341742350f, + -0.635726344928547070f, + 0.771792599152010150f, -0.635874345994697720f, 0.771670657585670330f, + -0.636022323681566300f, + 0.771548687647206300f, -0.636170277983712170f, 0.771426689341102590f, + -0.636318208895695460f, + 0.771304662671844830f, -0.636466116412077180f, 0.771182607643919330f, + -0.636614000527419120f, + 0.771060524261813820f, -0.636761861236284200f, 0.770938412530016940f, + -0.636909698533235870f, + 0.770816272453018540f, -0.637057512412838590f, 0.770694104035309140f, + -0.637205302869657600f, + 0.770571907281380810f, -0.637353069898259130f, 0.770449682195725960f, + -0.637500813493210190f, + 0.770327428782838890f, -0.637648533649078810f, 0.770205147047214210f, + -0.637796230360433540f, + 0.770082836993347900f, -0.637943903621844060f, 0.769960498625737230f, + -0.638091553427880820f, + 0.769838131948879840f, -0.638239179773115280f, 0.769715736967275130f, + -0.638386782652119570f, + 0.769593313685422940f, -0.638534362059466790f, 0.769470862107824670f, + -0.638681917989730730f, + 0.769348382238982280f, -0.638829450437486290f, 0.769225874083399260f, + -0.638976959397309140f, + 0.769103337645579700f, -0.639124444863775730f, 0.768980772930028870f, + -0.639271906831463510f, + 0.768858179941253270f, -0.639419345294950700f, 0.768735558683760310f, + -0.639566760248816310f, + 0.768612909162058380f, -0.639714151687640450f, 0.768490231380656860f, + -0.639861519606003900f, + 0.768367525344066270f, -0.640008863998488440f, 0.768244791056798330f, + -0.640156184859676510f, + 0.768122028523365420f, -0.640303482184151670f, 0.767999237748281270f, + -0.640450755966498140f, + 0.767876418736060610f, -0.640598006201301030f, 0.767753571491219030f, + -0.640745232883146440f, + 0.767630696018273380f, -0.640892436006621380f, 0.767507792321741270f, + -0.641039615566313390f, + 0.767384860406141730f, -0.641186771556811250f, 0.767261900275994500f, + -0.641333903972704290f, + 0.767138911935820400f, -0.641481012808583160f, 0.767015895390141480f, + -0.641628098059038750f, + 0.766892850643480670f, -0.641775159718663500f, 0.766769777700361920f, + -0.641922197782050170f, + 0.766646676565310380f, -0.642069212243792540f, 0.766523547242852210f, + -0.642216203098485370f, + 0.766400389737514230f, -0.642363170340724320f, 0.766277204053824710f, + -0.642510113965105710f, + 0.766153990196312920f, -0.642657033966226860f, 0.766030748169509000f, + -0.642803930338685990f, + 0.765907477977944340f, -0.642950803077082080f, 0.765784179626150970f, + -0.643097652176015110f, + 0.765660853118662500f, -0.643244477630085850f, 0.765537498460013070f, + -0.643391279433895850f, + 0.765414115654738270f, -0.643538057582047740f, 0.765290704707374370f, + -0.643684812069144850f, + 0.765167265622458960f, -0.643831542889791390f, 0.765043798404530520f, + -0.643978250038592660f, + 0.764920303058128410f, -0.644124933510154540f, 0.764796779587793460f, + -0.644271593299083790f, + 0.764673227998067140f, -0.644418229399988380f, 0.764549648293492150f, + -0.644564841807476640f, + 0.764426040478612070f, -0.644711430516158310f, 0.764302404557971720f, + -0.644857995520643710f, + 0.764178740536116670f, -0.645004536815543930f, 0.764055048417593970f, + -0.645151054395471160f, + 0.763931328206951090f, -0.645297548255038380f, 0.763807579908737160f, + -0.645444018388859230f, + 0.763683803527501870f, -0.645590464791548690f, 0.763559999067796150f, + -0.645736887457722290f, + 0.763436166534172010f, -0.645883286381996320f, 0.763312305931182380f, + -0.646029661558988330f, + 0.763188417263381270f, -0.646176012983316280f, 0.763064500535323710f, + -0.646322340649599480f, + 0.762940555751565720f, -0.646468644552457780f, 0.762816582916664430f, + -0.646614924686512050f, + 0.762692582035177980f, -0.646761181046383920f, 0.762568553111665380f, + -0.646907413626696020f, + 0.762444496150687210f, -0.647053622422071540f, 0.762320411156804270f, + -0.647199807427135230f, + 0.762196298134578900f, -0.647345968636512060f, 0.762072157088574560f, + -0.647492106044828100f, + 0.761947988023355390f, -0.647638219646710310f, 0.761823790943486960f, + -0.647784309436786440f, + 0.761699565853535380f, -0.647930375409685340f, 0.761575312758068000f, + -0.648076417560036530f, + 0.761451031661653620f, -0.648222435882470420f, 0.761326722568861360f, + -0.648368430371618290f, + 0.761202385484261780f, -0.648514401022112440f, 0.761078020412426560f, + -0.648660347828585840f, + 0.760953627357928150f, -0.648806270785672550f, 0.760829206325340010f, + -0.648952169888007300f, + 0.760704757319236920f, -0.649098045130225950f, 0.760580280344194450f, + -0.649243896506964900f, + 0.760455775404789260f, -0.649389724012861660f, 0.760331242505599030f, + -0.649535527642554730f, + 0.760206681651202420f, -0.649681307390683190f, 0.760082092846179340f, + -0.649827063251887100f, + 0.759957476095110330f, -0.649972795220807530f, 0.759832831402577400f, + -0.650118503292086200f, + 0.759708158773163440f, -0.650264187460365850f, 0.759583458211452010f, + -0.650409847720290310f, + 0.759458729722028210f, -0.650555484066503880f, 0.759333973309477940f, + -0.650701096493652040f, + 0.759209188978388070f, -0.650846684996380880f, 0.759084376733346610f, + -0.650992249569337660f, + 0.758959536578942440f, -0.651137790207170330f, 0.758834668519765660f, + -0.651283306904527740f, + 0.758709772560407390f, -0.651428799656059820f, 0.758584848705459610f, + -0.651574268456416970f, + 0.758459896959515430f, -0.651719713300250910f, 0.758334917327168960f, + -0.651865134182213920f, + 0.758209909813015280f, -0.652010531096959500f, 0.758084874421650730f, + -0.652155904039141590f, + 0.757959811157672300f, -0.652301253003415460f, 0.757834720025678310f, + -0.652446577984436730f, + 0.757709601030268080f, -0.652591878976862440f, 0.757584454176041810f, + -0.652737155975350310f, + 0.757459279467600720f, -0.652882408974558850f, 0.757334076909547130f, + -0.653027637969147530f, + 0.757208846506484570f, -0.653172842953776760f, 0.757083588263017140f, + -0.653318023923107670f, + 0.756958302183750490f, -0.653463180871802330f, 0.756832988273290820f, + -0.653608313794523890f, + 0.756707646536245670f, -0.653753422685936060f, 0.756582276977223470f, + -0.653898507540703780f, + 0.756456879600833740f, -0.654043568353492640f, 0.756331454411686920f, + -0.654188605118969040f, + 0.756206001414394540f, -0.654333617831800440f, 0.756080520613569120f, + -0.654478606486655350f, + 0.755955012013824420f, -0.654623571078202680f, 0.755829475619774760f, + -0.654768511601112600f, + 0.755703911436035880f, -0.654913428050056030f, 0.755578319467224540f, + -0.655058320419704910f, + 0.755452699717958250f, -0.655203188704731820f, 0.755327052192855670f, + -0.655348032899810470f, + 0.755201376896536550f, -0.655492852999615350f, 0.755075673833621620f, + -0.655637648998821820f, + 0.754949943008732640f, -0.655782420892106030f, 0.754824184426492350f, + -0.655927168674145360f, + 0.754698398091524500f, -0.656071892339617600f, 0.754572584008453840f, + -0.656216591883201920f, + 0.754446742181906440f, -0.656361267299578000f, 0.754320872616508820f, + -0.656505918583426550f, + 0.754194975316889170f, -0.656650545729428940f, 0.754069050287676120f, + -0.656795148732268070f, + 0.753943097533499640f, -0.656939727586627110f, 0.753817117058990790f, + -0.657084282287190180f, + 0.753691108868781210f, -0.657228812828642540f, 0.753565072967504300f, + -0.657373319205670210f, + 0.753439009359793580f, -0.657517801412960120f, 0.753312918050284330f, + -0.657662259445200070f, + 0.753186799043612520f, -0.657806693297078640f, 0.753060652344415100f, + -0.657951102963285520f, + 0.752934477957330150f, -0.658095488438511180f, 0.752808275886996950f, + -0.658239849717446870f, + 0.752682046138055340f, -0.658384186794785050f, 0.752555788715146390f, + -0.658528499665218650f, + 0.752429503622912390f, -0.658672788323441890f, 0.752303190865996400f, + -0.658817052764149480f, + 0.752176850449042810f, -0.658961292982037320f, 0.752050482376696360f, + -0.659105508971802090f, + 0.751924086653603550f, -0.659249700728141490f, 0.751797663284411550f, + -0.659393868245753860f, + 0.751671212273768430f, -0.659538011519338660f, 0.751544733626323680f, + -0.659682130543596150f, + 0.751418227346727470f, -0.659826225313227320f, 0.751291693439630870f, + -0.659970295822934540f, + 0.751165131909686480f, -0.660114342067420480f, 0.751038542761547360f, + -0.660258364041389050f, + 0.750911925999867890f, -0.660402361739545030f, 0.750785281629303690f, + -0.660546335156593890f, + 0.750658609654510700f, -0.660690284287242300f, 0.750531910080146410f, + -0.660834209126197610f, + 0.750405182910869330f, -0.660978109668168060f, 0.750278428151338720f, + -0.661121985907862860f, + 0.750151645806215070f, -0.661265837839992270f, 0.750024835880159780f, + -0.661409665459266940f, + 0.749897998377835330f, -0.661553468760398890f, 0.749771133303905100f, + -0.661697247738101010f, + 0.749644240663033480f, -0.661841002387086870f, 0.749517320459886170f, + -0.661984732702070920f, + 0.749390372699129560f, -0.662128438677768720f, 0.749263397385431130f, + -0.662272120308896590f, + 0.749136394523459370f, -0.662415777590171780f, 0.749009364117883880f, + -0.662559410516312290f, + 0.748882306173375150f, -0.662703019082037440f, 0.748755220694604760f, + -0.662846603282066900f, + 0.748628107686245440f, -0.662990163111121470f, 0.748500967152970430f, + -0.663133698563923010f, + 0.748373799099454560f, -0.663277209635194100f, 0.748246603530373420f, + -0.663420696319658280f, + 0.748119380450403600f, -0.663564158612039770f, 0.747992129864222700f, + -0.663707596507064010f, + 0.747864851776509410f, -0.663851009999457340f, 0.747737546191943330f, + -0.663994399083946640f, + 0.747610213115205150f, -0.664137763755260010f, 0.747482852550976570f, + -0.664281104008126230f, + 0.747355464503940190f, -0.664424419837275180f, 0.747228048978779920f, + -0.664567711237437520f, + 0.747100605980180130f, -0.664710978203344790f, 0.746973135512826850f, + -0.664854220729729660f, + 0.746845637581406540f, -0.664997438811325340f, 0.746718112190607130f, + -0.665140632442866140f, + 0.746590559345117310f, -0.665283801619087180f, 0.746462979049626770f, + -0.665426946334724660f, + 0.746335371308826320f, -0.665570066584515450f, 0.746207736127407760f, + -0.665713162363197550f, + 0.746080073510063780f, -0.665856233665509720f, 0.745952383461488290f, + -0.665999280486191500f, + 0.745824665986376090f, -0.666142302819983540f, 0.745696921089422760f, + -0.666285300661627280f, + 0.745569148775325430f, -0.666428274005865240f, 0.745441349048781680f, + -0.666571222847440640f, + 0.745313521914490520f, -0.666714147181097670f, 0.745185667377151640f, + -0.666857047001581220f, + 0.745057785441466060f, -0.666999922303637470f, 0.744929876112135350f, + -0.667142773082013310f, + 0.744801939393862630f, -0.667285599331456370f, 0.744673975291351710f, + -0.667428401046715520f, + 0.744545983809307370f, -0.667571178222540310f, 0.744417964952435620f, + -0.667713930853681030f, + 0.744289918725443260f, -0.667856658934889320f, 0.744161845133038180f, + -0.667999362460917400f, + 0.744033744179929290f, -0.668142041426518450f, 0.743905615870826490f, + -0.668284695826446670f, + 0.743777460210440890f, -0.668427325655456820f, 0.743649277203484060f, + -0.668569930908304970f, + 0.743521066854669120f, -0.668712511579747980f, 0.743392829168709970f, + -0.668855067664543610f, + 0.743264564150321600f, -0.668997599157450270f, 0.743136271804219820f, + -0.669140106053227600f, + 0.743007952135121720f, -0.669282588346636010f, 0.742879605147745200f, + -0.669425046032436910f, + 0.742751230846809050f, -0.669567479105392490f, 0.742622829237033490f, + -0.669709887560265840f, + 0.742494400323139180f, -0.669852271391821020f, 0.742365944109848460f, + -0.669994630594823000f, + 0.742237460601884000f, -0.670136965164037650f, 0.742108949803969910f, + -0.670279275094231800f, + 0.741980411720831070f, -0.670421560380173090f, 0.741851846357193480f, + -0.670563821016630040f, + 0.741723253717784140f, -0.670706056998372160f, 0.741594633807331150f, + -0.670848268320169640f, + 0.741465986630563290f, -0.670990454976794220f, 0.741337312192210660f, + -0.671132616963017740f, + 0.741208610497004260f, -0.671274754273613490f, 0.741079881549676080f, + -0.671416866903355450f, + 0.740951125354959110f, -0.671558954847018330f, 0.740822341917587330f, + -0.671701018099378320f, + 0.740693531242295760f, -0.671843056655211930f, 0.740564693333820250f, + -0.671985070509296900f, + 0.740435828196898020f, -0.672127059656411730f, 0.740306935836266940f, + -0.672269024091335930f, + 0.740178016256666240f, -0.672410963808849790f, 0.740049069462835550f, + -0.672552878803734710f, + 0.739920095459516200f, -0.672694769070772860f, 0.739791094251449950f, + -0.672836634604747300f, + 0.739662065843380010f, -0.672978475400442090f, 0.739533010240050250f, + -0.673120291452642070f, + 0.739403927446205760f, -0.673262082756132970f, 0.739274817466592520f, + -0.673403849305701740f, + 0.739145680305957510f, -0.673545591096136100f, 0.739016515969048720f, + -0.673687308122224330f, + 0.738887324460615110f, -0.673829000378756040f, 0.738758105785406900f, + -0.673970667860521620f, + 0.738628859948174840f, -0.674112310562312360f, 0.738499586953671130f, + -0.674253928478920410f, + 0.738370286806648620f, -0.674395521605139050f, 0.738240959511861310f, + -0.674537089935762000f, + 0.738111605074064260f, -0.674678633465584540f, 0.737982223498013570f, + -0.674820152189402170f, + 0.737852814788465980f, -0.674961646102011930f, 0.737723378950179700f, + -0.675103115198211420f, + 0.737593915987913570f, -0.675244559472799270f, 0.737464425906427580f, + -0.675385978920574840f, + 0.737334908710482910f, -0.675527373536338520f, 0.737205364404841190f, + -0.675668743314891910f, + 0.737075792994265730f, -0.675810088251036940f, 0.736946194483520280f, + -0.675951408339577010f, + 0.736816568877369900f, -0.676092703575315920f, 0.736686916180580460f, + -0.676233973953058950f, + 0.736557236397919150f, -0.676375219467611590f, 0.736427529534153690f, + -0.676516440113781090f, + 0.736297795594053170f, -0.676657635886374950f, 0.736168034582387330f, + -0.676798806780201770f, + 0.736038246503927350f, -0.676939952790071130f, 0.735908431363445190f, + -0.677081073910793530f, + 0.735778589165713590f, -0.677222170137180330f, 0.735648719915506510f, + -0.677363241464043920f, + 0.735518823617598900f, -0.677504287886197430f, 0.735388900276766730f, + -0.677645309398454910f, + 0.735258949897786840f, -0.677786305995631500f, 0.735128972485437180f, + -0.677927277672543020f, + 0.734998968044496710f, -0.678068224424006600f, 0.734868936579745170f, + -0.678209146244839860f, + 0.734738878095963500f, -0.678350043129861470f, 0.734608792597933550f, + -0.678490915073891140f, + 0.734478680090438370f, -0.678631762071749360f, 0.734348540578261600f, + -0.678772584118257690f, + 0.734218374066188280f, -0.678913381208238410f, 0.734088180559004040f, + -0.679054153336514870f, + 0.733957960061495940f, -0.679194900497911200f, 0.733827712578451700f, + -0.679335622687252560f, + 0.733697438114660370f, -0.679476319899364970f, 0.733567136674911360f, + -0.679616992129075560f, + 0.733436808263995710f, -0.679757639371212030f, 0.733306452886705260f, + -0.679898261620603290f, + 0.733176070547832740f, -0.680038858872078930f, 0.733045661252172080f, + -0.680179431120469750f, + 0.732915225004517780f, -0.680319978360607200f, 0.732784761809665790f, + -0.680460500587323880f, + 0.732654271672412820f, -0.680600997795453020f, 0.732523754597556700f, + -0.680741469979829090f, + 0.732393210589896040f, -0.680881917135287230f, 0.732262639654230770f, + -0.681022339256663670f, + 0.732132041795361290f, -0.681162736338795430f, 0.732001417018089630f, + -0.681303108376520530f, + 0.731870765327218290f, -0.681443455364677870f, 0.731740086727550980f, + -0.681583777298107480f, + 0.731609381223892630f, -0.681724074171649710f, 0.731478648821048520f, + -0.681864345980146670f, + 0.731347889523825570f, -0.682004592718440830f, 0.731217103337031270f, + -0.682144814381375640f, + 0.731086290265474340f, -0.682285010963795570f, 0.730955450313964360f, + -0.682425182460546060f, + 0.730824583487312160f, -0.682565328866473250f, 0.730693689790329000f, + -0.682705450176424590f, + 0.730562769227827590f, -0.682845546385248080f, 0.730431821804621520f, + -0.682985617487792740f, + 0.730300847525525490f, -0.683125663478908680f, 0.730169846395354870f, + -0.683265684353446700f, + 0.730038818418926260f, -0.683405680106258680f, 0.729907763601057140f, + -0.683545650732197530f, + 0.729776681946566090f, -0.683685596226116580f, 0.729645573460272480f, + -0.683825516582870720f, + 0.729514438146997010f, -0.683965411797315400f, 0.729383276011561050f, + -0.684105281864307080f, + 0.729252087058786970f, -0.684245126778703080f, 0.729120871293498230f, + -0.684384946535361750f, + 0.728989628720519420f, -0.684524741129142300f, 0.728858359344675800f, + -0.684664510554904960f, + 0.728727063170793830f, -0.684804254807510620f, 0.728595740203700770f, + -0.684943973881821490f, + 0.728464390448225200f, -0.685083667772700360f, 0.728333013909196360f, + -0.685223336475011210f, + 0.728201610591444610f, -0.685362979983618730f, 0.728070180499801210f, + -0.685502598293388550f, + 0.727938723639098620f, -0.685642191399187470f, 0.727807240014169960f, + -0.685781759295883030f, + 0.727675729629849610f, -0.685921301978343560f, 0.727544192490972800f, + -0.686060819441438710f, + 0.727412628602375770f, -0.686200311680038590f, 0.727281037968895870f, + -0.686339778689014520f, + 0.727149420595371020f, -0.686479220463238950f, 0.727017776486640680f, + -0.686618636997584630f, + 0.726886105647544970f, -0.686758028286925890f, 0.726754408082925020f, + -0.686897394326137610f, + 0.726622683797622850f, -0.687036735110095660f, 0.726490932796481910f, + -0.687176050633676820f, + 0.726359155084346010f, -0.687315340891759050f, 0.726227350666060370f, + -0.687454605879221030f, + 0.726095519546471000f, -0.687593845590942170f, 0.725963661730424930f, + -0.687733060021803230f, + 0.725831777222770370f, -0.687872249166685550f, 0.725699866028356120f, + -0.688011413020471640f, + 0.725567928152032300f, -0.688150551578044830f, 0.725435963598649810f, + -0.688289664834289330f, + 0.725303972373060770f, -0.688428752784090440f, 0.725171954480117950f, + -0.688567815422334250f, + 0.725039909924675370f, -0.688706852743907750f, 0.724907838711587820f, + -0.688845864743699020f, + 0.724775740845711280f, -0.688984851416597040f, 0.724643616331902550f, + -0.689123812757491570f, + 0.724511465175019630f, -0.689262748761273470f, 0.724379287379921190f, + -0.689401659422834270f, + 0.724247082951467000f, -0.689540544737066830f, 0.724114851894517850f, + -0.689679404698864800f, + 0.723982594213935520f, -0.689818239303122470f, 0.723850309914582880f, + -0.689957048544735390f, + 0.723717999001323500f, -0.690095832418599950f, 0.723585661479022150f, + -0.690234590919613370f, + 0.723453297352544380f, -0.690373324042674040f, 0.723320906626756970f, + -0.690512031782681060f, + 0.723188489306527460f, -0.690650714134534600f, 0.723056045396724410f, + -0.690789371093135650f, + 0.722923574902217700f, -0.690928002653386160f, 0.722791077827877550f, + -0.691066608810189220f, + 0.722658554178575610f, -0.691205189558448450f, 0.722526003959184540f, + -0.691343744893068710f, + 0.722393427174577550f, -0.691482274808955850f, 0.722260823829629310f, + -0.691620779301016290f, + 0.722128193929215350f, -0.691759258364157750f, 0.721995537478211880f, + -0.691897711993288760f, + 0.721862854481496340f, -0.692036140183318720f, 0.721730144943947160f, + -0.692174542929158140f, + 0.721597408870443770f, -0.692312920225718220f, 0.721464646265866370f, + -0.692451272067911130f, + 0.721331857135096290f, -0.692589598450650380f, 0.721199041483015720f, + -0.692727899368849820f, + 0.721066199314508110f, -0.692866174817424630f, 0.720933330634457530f, + -0.693004424791290870f, + 0.720800435447749190f, -0.693142649285365400f, 0.720667513759269520f, + -0.693280848294566040f, + 0.720534565573905270f, -0.693419021813811760f, 0.720401590896544760f, + -0.693557169838022290f, + 0.720268589732077190f, -0.693695292362118240f, 0.720135562085392420f, + -0.693833389381021350f, + 0.720002507961381650f, -0.693971460889654000f, 0.719869427364936860f, + -0.694109506882939820f, + 0.719736320300951030f, -0.694247527355803310f, 0.719603186774318120f, + -0.694385522303169740f, + 0.719470026789932990f, -0.694523491719965520f, 0.719336840352691740f, + -0.694661435601117820f, + 0.719203627467491220f, -0.694799353941554900f, 0.719070388139229190f, + -0.694937246736205830f, + 0.718937122372804490f, -0.695075113980000880f, 0.718803830173116890f, + -0.695212955667870780f, + 0.718670511545067230f, -0.695350771794747690f, 0.718537166493557370f, + -0.695488562355564440f, + 0.718403795023489830f, -0.695626327345254870f, 0.718270397139768260f, + -0.695764066758753690f, + 0.718136972847297490f, -0.695901780590996830f, 0.718003522150983180f, + -0.696039468836920690f, + 0.717870045055731710f, -0.696177131491462990f, 0.717736541566450950f, + -0.696314768549562090f, + 0.717603011688049080f, -0.696452380006157830f, 0.717469455425435830f, + -0.696589965856190370f, + 0.717335872783521730f, -0.696727526094601200f, 0.717202263767218070f, + -0.696865060716332470f, + 0.717068628381437480f, -0.697002569716327460f, 0.716934966631093130f, + -0.697140053089530420f, + 0.716801278521099540f, -0.697277510830886520f, 0.716667564056371890f, + -0.697414942935341790f, + 0.716533823241826680f, -0.697552349397843160f, 0.716400056082381000f, + -0.697689730213338800f, + 0.716266262582953120f, -0.697827085376777290f, 0.716132442748462330f, + -0.697964414883108670f, + 0.715998596583828690f, -0.698101718727283770f, 0.715864724093973500f, + -0.698238996904254280f, + 0.715730825283818590f, -0.698376249408972920f, 0.715596900158287470f, + -0.698513476236393040f, + 0.715462948722303760f, -0.698650677381469460f, 0.715328970980792620f, + -0.698787852839157670f, + 0.715194966938680120f, -0.698925002604414150f, 0.715060936600893090f, + -0.699062126672196140f, + 0.714926879972359490f, -0.699199225037462120f, 0.714792797058008240f, + -0.699336297695171140f, + 0.714658687862769090f, -0.699473344640283770f, 0.714524552391572860f, + -0.699610365867761040f, + 0.714390390649351390f, -0.699747361372564990f, 0.714256202641037510f, + -0.699884331149658760f, + 0.714121988371564820f, -0.700021275194006250f, 0.713987747845867830f, + -0.700158193500572730f, + 0.713853481068882470f, -0.700295086064323780f, 0.713719188045545240f, + -0.700431952880226420f, + 0.713584868780793640f, -0.700568793943248340f, 0.713450523279566260f, + -0.700705609248358450f, + 0.713316151546802610f, -0.700842398790526120f, 0.713181753587443180f, + -0.700979162564722370f, + 0.713047329406429340f, -0.701115900565918660f, 0.712912879008703480f, + -0.701252612789087460f, + 0.712778402399208980f, -0.701389299229202230f, 0.712643899582890210f, + -0.701525959881237340f, + 0.712509370564692320f, -0.701662594740168450f, 0.712374815349561710f, + -0.701799203800971720f, + 0.712240233942445510f, -0.701935787058624360f, 0.712105626348291890f, + -0.702072344508104630f, + 0.711970992572050100f, -0.702208876144391870f, 0.711836332618670080f, + -0.702345381962465880f, + 0.711701646493102970f, -0.702481861957308000f, 0.711566934200300700f, + -0.702618316123900130f, + 0.711432195745216430f, -0.702754744457225300f, 0.711297431132803970f, + -0.702891146952267400f, + 0.711162640368018350f, -0.703027523604011220f, 0.711027823455815280f, + -0.703163874407442770f, + 0.710892980401151680f, -0.703300199357548730f, 0.710758111208985350f, + -0.703436498449316660f, + 0.710623215884275020f, -0.703572771677735580f, 0.710488294431980470f, + -0.703709019037794810f, + 0.710353346857062420f, -0.703845240524484940f, 0.710218373164482220f, + -0.703981436132797620f, + 0.710083373359202800f, -0.704117605857725310f, 0.709948347446187400f, + -0.704253749694261470f, + 0.709813295430400840f, -0.704389867637400410f, 0.709678217316808580f, + -0.704525959682137380f, + 0.709543113110376770f, -0.704662025823468820f, 0.709407982816072980f, + -0.704798066056391950f, + 0.709272826438865690f, -0.704934080375904880f, 0.709137643983724030f, + -0.705070068777006840f, + 0.709002435455618250f, -0.705206031254697830f, 0.708867200859519820f, + -0.705341967803978840f, + 0.708731940200400650f, -0.705477878419852100f, 0.708596653483234080f, + -0.705613763097320490f, + 0.708461340712994160f, -0.705749621831387790f, 0.708326001894655890f, + -0.705885454617058980f, + 0.708190637033195400f, -0.706021261449339740f, 0.708055246133589500f, + -0.706157042323237060f, + 0.707919829200816310f, -0.706292797233758480f, 0.707784386239854620f, + -0.706428526175912790f, + 0.707648917255684350f, -0.706564229144709510f, 0.707513422253286280f, + -0.706699906135159430f, + 0.707377901237642100f, -0.706835557142273750f, 0.707242354213734710f, + -0.706971182161065360f, + 0.707106781186547570f, -0.707106781186547460f, 0.706971182161065360f, + -0.707242354213734600f, + 0.706835557142273860f, -0.707377901237642100f, 0.706699906135159430f, + -0.707513422253286170f, + 0.706564229144709620f, -0.707648917255684350f, 0.706428526175912790f, + -0.707784386239854620f, + 0.706292797233758480f, -0.707919829200816310f, 0.706157042323237060f, + -0.708055246133589500f, + 0.706021261449339740f, -0.708190637033195290f, 0.705885454617058980f, + -0.708326001894655780f, + 0.705749621831387790f, -0.708461340712994050f, 0.705613763097320490f, + -0.708596653483234080f, + 0.705477878419852210f, -0.708731940200400650f, 0.705341967803978950f, + -0.708867200859519820f, + 0.705206031254697830f, -0.709002435455618250f, 0.705070068777006840f, + -0.709137643983723920f, + 0.704934080375904990f, -0.709272826438865580f, 0.704798066056391950f, + -0.709407982816072980f, + 0.704662025823468930f, -0.709543113110376770f, 0.704525959682137380f, + -0.709678217316808470f, + 0.704389867637400410f, -0.709813295430400840f, 0.704253749694261580f, + -0.709948347446187400f, + 0.704117605857725430f, -0.710083373359202690f, 0.703981436132797730f, + -0.710218373164482220f, + 0.703845240524484940f, -0.710353346857062310f, 0.703709019037794810f, + -0.710488294431980470f, + 0.703572771677735580f, -0.710623215884275020f, 0.703436498449316770f, + -0.710758111208985350f, + 0.703300199357548730f, -0.710892980401151680f, 0.703163874407442770f, + -0.711027823455815280f, + 0.703027523604011220f, -0.711162640368018350f, 0.702891146952267400f, + -0.711297431132803970f, + 0.702754744457225300f, -0.711432195745216430f, 0.702618316123900130f, + -0.711566934200300700f, + 0.702481861957308000f, -0.711701646493102970f, 0.702345381962465880f, + -0.711836332618670080f, + 0.702208876144391870f, -0.711970992572049990f, 0.702072344508104740f, + -0.712105626348291890f, + 0.701935787058624360f, -0.712240233942445510f, 0.701799203800971720f, + -0.712374815349561710f, + 0.701662594740168570f, -0.712509370564692320f, 0.701525959881237450f, + -0.712643899582890210f, + 0.701389299229202230f, -0.712778402399208870f, 0.701252612789087460f, + -0.712912879008703370f, + 0.701115900565918660f, -0.713047329406429230f, 0.700979162564722480f, + -0.713181753587443070f, + 0.700842398790526230f, -0.713316151546802610f, 0.700705609248358450f, + -0.713450523279566150f, + 0.700568793943248450f, -0.713584868780793520f, 0.700431952880226420f, + -0.713719188045545130f, + 0.700295086064323780f, -0.713853481068882470f, 0.700158193500572730f, + -0.713987747845867830f, + 0.700021275194006360f, -0.714121988371564710f, 0.699884331149658760f, + -0.714256202641037400f, + 0.699747361372564990f, -0.714390390649351390f, 0.699610365867761040f, + -0.714524552391572860f, + 0.699473344640283770f, -0.714658687862768980f, 0.699336297695171250f, + -0.714792797058008130f, + 0.699199225037462120f, -0.714926879972359370f, 0.699062126672196140f, + -0.715060936600892980f, + 0.698925002604414150f, -0.715194966938680010f, 0.698787852839157790f, + -0.715328970980792620f, + 0.698650677381469580f, -0.715462948722303650f, 0.698513476236393040f, + -0.715596900158287360f, + 0.698376249408972920f, -0.715730825283818590f, 0.698238996904254390f, + -0.715864724093973390f, + 0.698101718727283880f, -0.715998596583828690f, 0.697964414883108790f, + -0.716132442748462330f, + 0.697827085376777290f, -0.716266262582953120f, 0.697689730213338800f, + -0.716400056082380890f, + 0.697552349397843270f, -0.716533823241826570f, 0.697414942935341790f, + -0.716667564056371890f, + 0.697277510830886630f, -0.716801278521099540f, 0.697140053089530530f, + -0.716934966631093130f, + 0.697002569716327460f, -0.717068628381437480f, 0.696865060716332470f, + -0.717202263767218070f, + 0.696727526094601200f, -0.717335872783521730f, 0.696589965856190370f, + -0.717469455425435830f, + 0.696452380006157830f, -0.717603011688049080f, 0.696314768549562200f, + -0.717736541566450840f, + 0.696177131491462990f, -0.717870045055731710f, 0.696039468836920690f, + -0.718003522150983060f, + 0.695901780590996830f, -0.718136972847297490f, 0.695764066758753800f, + -0.718270397139768260f, + 0.695626327345254870f, -0.718403795023489720f, 0.695488562355564440f, + -0.718537166493557370f, + 0.695350771794747800f, -0.718670511545067230f, 0.695212955667870890f, + -0.718803830173116890f, + 0.695075113980000880f, -0.718937122372804380f, 0.694937246736205940f, + -0.719070388139229190f, + 0.694799353941554900f, -0.719203627467491220f, 0.694661435601117930f, + -0.719336840352691740f, + 0.694523491719965520f, -0.719470026789932990f, 0.694385522303169860f, + -0.719603186774318000f, + 0.694247527355803310f, -0.719736320300951030f, 0.694109506882939820f, + -0.719869427364936860f, + 0.693971460889654000f, -0.720002507961381650f, 0.693833389381021350f, + -0.720135562085392310f, + 0.693695292362118350f, -0.720268589732077080f, 0.693557169838022400f, + -0.720401590896544760f, + 0.693419021813811880f, -0.720534565573905270f, 0.693280848294566150f, + -0.720667513759269410f, + 0.693142649285365510f, -0.720800435447749190f, 0.693004424791290870f, + -0.720933330634457530f, + 0.692866174817424740f, -0.721066199314508110f, 0.692727899368849820f, + -0.721199041483015720f, + 0.692589598450650380f, -0.721331857135096180f, 0.692451272067911240f, + -0.721464646265866370f, + 0.692312920225718220f, -0.721597408870443660f, 0.692174542929158140f, + -0.721730144943947160f, + 0.692036140183318830f, -0.721862854481496340f, 0.691897711993288760f, + -0.721995537478211880f, + 0.691759258364157750f, -0.722128193929215350f, 0.691620779301016400f, + -0.722260823829629310f, + 0.691482274808955850f, -0.722393427174577550f, 0.691343744893068820f, + -0.722526003959184430f, + 0.691205189558448450f, -0.722658554178575610f, 0.691066608810189220f, + -0.722791077827877550f, + 0.690928002653386280f, -0.722923574902217700f, 0.690789371093135760f, + -0.723056045396724410f, + 0.690650714134534720f, -0.723188489306527350f, 0.690512031782681170f, + -0.723320906626756850f, + 0.690373324042674040f, -0.723453297352544380f, 0.690234590919613370f, + -0.723585661479022040f, + 0.690095832418599950f, -0.723717999001323390f, 0.689957048544735390f, + -0.723850309914582880f, + 0.689818239303122470f, -0.723982594213935520f, 0.689679404698864800f, + -0.724114851894517850f, + 0.689540544737066940f, -0.724247082951466890f, 0.689401659422834380f, + -0.724379287379921080f, + 0.689262748761273470f, -0.724511465175019520f, 0.689123812757491680f, + -0.724643616331902550f, + 0.688984851416597150f, -0.724775740845711280f, 0.688845864743699130f, + -0.724907838711587820f, + 0.688706852743907750f, -0.725039909924675370f, 0.688567815422334360f, + -0.725171954480117840f, + 0.688428752784090550f, -0.725303972373060660f, 0.688289664834289440f, + -0.725435963598649810f, + 0.688150551578044830f, -0.725567928152032300f, 0.688011413020471640f, + -0.725699866028356120f, + 0.687872249166685550f, -0.725831777222770370f, 0.687733060021803230f, + -0.725963661730424930f, + 0.687593845590942170f, -0.726095519546470890f, 0.687454605879221030f, + -0.726227350666060260f, + 0.687315340891759160f, -0.726359155084346010f, 0.687176050633676930f, + -0.726490932796481910f, + 0.687036735110095660f, -0.726622683797622850f, 0.686897394326137610f, + -0.726754408082924910f, + 0.686758028286925890f, -0.726886105647544970f, 0.686618636997584740f, + -0.727017776486640680f, + 0.686479220463238950f, -0.727149420595371020f, 0.686339778689014630f, + -0.727281037968895760f, + 0.686200311680038700f, -0.727412628602375770f, 0.686060819441438710f, + -0.727544192490972800f, + 0.685921301978343670f, -0.727675729629849610f, 0.685781759295883030f, + -0.727807240014169960f, + 0.685642191399187470f, -0.727938723639098620f, 0.685502598293388670f, + -0.728070180499801210f, + 0.685362979983618730f, -0.728201610591444500f, 0.685223336475011210f, + -0.728333013909196360f, + 0.685083667772700360f, -0.728464390448225200f, 0.684943973881821490f, + -0.728595740203700770f, + 0.684804254807510620f, -0.728727063170793720f, 0.684664510554904960f, + -0.728858359344675690f, + 0.684524741129142300f, -0.728989628720519310f, 0.684384946535361750f, + -0.729120871293498230f, + 0.684245126778703080f, -0.729252087058786970f, 0.684105281864307080f, + -0.729383276011561050f, + 0.683965411797315510f, -0.729514438146996900f, 0.683825516582870830f, + -0.729645573460272480f, + 0.683685596226116690f, -0.729776681946565970f, 0.683545650732197530f, + -0.729907763601057140f, + 0.683405680106258790f, -0.730038818418926150f, 0.683265684353446700f, + -0.730169846395354870f, + 0.683125663478908800f, -0.730300847525525380f, 0.682985617487792850f, + -0.730431821804621520f, + 0.682845546385248080f, -0.730562769227827590f, 0.682705450176424590f, + -0.730693689790328890f, + 0.682565328866473250f, -0.730824583487312050f, 0.682425182460546060f, + -0.730955450313964360f, + 0.682285010963795570f, -0.731086290265474230f, 0.682144814381375640f, + -0.731217103337031160f, + 0.682004592718440830f, -0.731347889523825460f, 0.681864345980146780f, + -0.731478648821048520f, + 0.681724074171649820f, -0.731609381223892520f, 0.681583777298107480f, + -0.731740086727550980f, + 0.681443455364677990f, -0.731870765327218290f, 0.681303108376520530f, + -0.732001417018089520f, + 0.681162736338795430f, -0.732132041795361290f, 0.681022339256663670f, + -0.732262639654230660f, + 0.680881917135287340f, -0.732393210589896040f, 0.680741469979829090f, + -0.732523754597556590f, + 0.680600997795453130f, -0.732654271672412820f, 0.680460500587323880f, + -0.732784761809665790f, + 0.680319978360607200f, -0.732915225004517780f, 0.680179431120469750f, + -0.733045661252171970f, + 0.680038858872079040f, -0.733176070547832740f, 0.679898261620603290f, + -0.733306452886705260f, + 0.679757639371212030f, -0.733436808263995710f, 0.679616992129075560f, + -0.733567136674911360f, + 0.679476319899365080f, -0.733697438114660260f, 0.679335622687252670f, + -0.733827712578451700f, + 0.679194900497911200f, -0.733957960061495940f, 0.679054153336514870f, + -0.734088180559004040f, + 0.678913381208238410f, -0.734218374066188170f, 0.678772584118257690f, + -0.734348540578261600f, + 0.678631762071749470f, -0.734478680090438370f, 0.678490915073891250f, + -0.734608792597933550f, + 0.678350043129861580f, -0.734738878095963390f, 0.678209146244839860f, + -0.734868936579745060f, + 0.678068224424006600f, -0.734998968044496600f, 0.677927277672543130f, + -0.735128972485437180f, + 0.677786305995631500f, -0.735258949897786730f, 0.677645309398454910f, + -0.735388900276766620f, + 0.677504287886197430f, -0.735518823617598900f, 0.677363241464044030f, + -0.735648719915506400f, + 0.677222170137180450f, -0.735778589165713480f, 0.677081073910793530f, + -0.735908431363445190f, + 0.676939952790071240f, -0.736038246503927350f, 0.676798806780201770f, + -0.736168034582387330f, + 0.676657635886374950f, -0.736297795594053060f, 0.676516440113781090f, + -0.736427529534153690f, + 0.676375219467611700f, -0.736557236397919150f, 0.676233973953058950f, + -0.736686916180580460f, + 0.676092703575316030f, -0.736816568877369790f, 0.675951408339577010f, + -0.736946194483520170f, + 0.675810088251037060f, -0.737075792994265620f, 0.675668743314891910f, + -0.737205364404841190f, + 0.675527373536338630f, -0.737334908710482790f, 0.675385978920574950f, + -0.737464425906427580f, + 0.675244559472799270f, -0.737593915987913460f, 0.675103115198211530f, + -0.737723378950179590f, + 0.674961646102012040f, -0.737852814788465980f, 0.674820152189402280f, + -0.737982223498013570f, + 0.674678633465584540f, -0.738111605074064260f, 0.674537089935762110f, + -0.738240959511861310f, + 0.674395521605139050f, -0.738370286806648510f, 0.674253928478920520f, + -0.738499586953671130f, + 0.674112310562312360f, -0.738628859948174840f, 0.673970667860521620f, + -0.738758105785406900f, + 0.673829000378756150f, -0.738887324460615110f, 0.673687308122224330f, + -0.739016515969048600f, + 0.673545591096136100f, -0.739145680305957400f, 0.673403849305701850f, + -0.739274817466592520f, + 0.673262082756132970f, -0.739403927446205760f, 0.673120291452642070f, + -0.739533010240050250f, + 0.672978475400442090f, -0.739662065843379900f, 0.672836634604747410f, + -0.739791094251449950f, + 0.672694769070772970f, -0.739920095459516090f, 0.672552878803734820f, + -0.740049069462835550f, + 0.672410963808849900f, -0.740178016256666240f, 0.672269024091336040f, + -0.740306935836266940f, + 0.672127059656411840f, -0.740435828196898020f, 0.671985070509296900f, + -0.740564693333820250f, + 0.671843056655211930f, -0.740693531242295640f, 0.671701018099378320f, + -0.740822341917587330f, + 0.671558954847018330f, -0.740951125354959110f, 0.671416866903355450f, + -0.741079881549676080f, + 0.671274754273613490f, -0.741208610497004260f, 0.671132616963017850f, + -0.741337312192210660f, + 0.670990454976794220f, -0.741465986630563290f, 0.670848268320169750f, + -0.741594633807331150f, + 0.670706056998372160f, -0.741723253717784140f, 0.670563821016630040f, + -0.741851846357193480f, + 0.670421560380173090f, -0.741980411720830960f, 0.670279275094231910f, + -0.742108949803969800f, + 0.670136965164037760f, -0.742237460601884000f, 0.669994630594823000f, + -0.742365944109848460f, + 0.669852271391821130f, -0.742494400323139180f, 0.669709887560265840f, + -0.742622829237033380f, + 0.669567479105392490f, -0.742751230846809050f, 0.669425046032436910f, + -0.742879605147745090f, + 0.669282588346636010f, -0.743007952135121720f, 0.669140106053227710f, + -0.743136271804219820f, + 0.668997599157450270f, -0.743264564150321490f, 0.668855067664543610f, + -0.743392829168709970f, + 0.668712511579748090f, -0.743521066854669120f, 0.668569930908305080f, + -0.743649277203484060f, + 0.668427325655456820f, -0.743777460210440780f, 0.668284695826446670f, + -0.743905615870826490f, + 0.668142041426518560f, -0.744033744179929180f, 0.667999362460917510f, + -0.744161845133038070f, + 0.667856658934889440f, -0.744289918725443140f, 0.667713930853681140f, + -0.744417964952435620f, + 0.667571178222540310f, -0.744545983809307250f, 0.667428401046715640f, + -0.744673975291351600f, + 0.667285599331456480f, -0.744801939393862630f, 0.667142773082013310f, + -0.744929876112135350f, + 0.666999922303637470f, -0.745057785441465950f, 0.666857047001581220f, + -0.745185667377151640f, + 0.666714147181097670f, -0.745313521914490410f, 0.666571222847440750f, + -0.745441349048781680f, + 0.666428274005865350f, -0.745569148775325430f, 0.666285300661627390f, + -0.745696921089422760f, + 0.666142302819983540f, -0.745824665986375980f, 0.665999280486191500f, + -0.745952383461488180f, + 0.665856233665509720f, -0.746080073510063780f, 0.665713162363197660f, + -0.746207736127407650f, + 0.665570066584515560f, -0.746335371308826320f, 0.665426946334724660f, + -0.746462979049626770f, + 0.665283801619087180f, -0.746590559345117310f, 0.665140632442866140f, + -0.746718112190607020f, + 0.664997438811325340f, -0.746845637581406540f, 0.664854220729729660f, + -0.746973135512826740f, + 0.664710978203344900f, -0.747100605980180130f, 0.664567711237437520f, + -0.747228048978779920f, + 0.664424419837275180f, -0.747355464503940190f, 0.664281104008126230f, + -0.747482852550976570f, + 0.664137763755260010f, -0.747610213115205150f, 0.663994399083946640f, + -0.747737546191943330f, + 0.663851009999457340f, -0.747864851776509410f, 0.663707596507064120f, + -0.747992129864222700f, + 0.663564158612039880f, -0.748119380450403490f, 0.663420696319658280f, + -0.748246603530373420f, + 0.663277209635194100f, -0.748373799099454560f, 0.663133698563923010f, + -0.748500967152970430f, + 0.662990163111121470f, -0.748628107686245330f, 0.662846603282066900f, + -0.748755220694604760f, + 0.662703019082037440f, -0.748882306173375030f, 0.662559410516312400f, + -0.749009364117883770f, + 0.662415777590171780f, -0.749136394523459260f, 0.662272120308896590f, + -0.749263397385431020f, + 0.662128438677768720f, -0.749390372699129560f, 0.661984732702071030f, + -0.749517320459886170f, + 0.661841002387086870f, -0.749644240663033480f, 0.661697247738101120f, + -0.749771133303904990f, + 0.661553468760399000f, -0.749897998377835220f, 0.661409665459266940f, + -0.750024835880159780f, + 0.661265837839992270f, -0.750151645806214960f, 0.661121985907862970f, + -0.750278428151338610f, + 0.660978109668168060f, -0.750405182910869220f, 0.660834209126197610f, + -0.750531910080146410f, + 0.660690284287242300f, -0.750658609654510590f, 0.660546335156593890f, + -0.750785281629303580f, + 0.660402361739545030f, -0.750911925999867890f, 0.660258364041389050f, + -0.751038542761547250f, + 0.660114342067420480f, -0.751165131909686370f, 0.659970295822934540f, + -0.751291693439630870f, + 0.659826225313227430f, -0.751418227346727360f, 0.659682130543596150f, + -0.751544733626323570f, + 0.659538011519338770f, -0.751671212273768430f, 0.659393868245753970f, + -0.751797663284411440f, + 0.659249700728141490f, -0.751924086653603550f, 0.659105508971802200f, + -0.752050482376696360f, + 0.658961292982037320f, -0.752176850449042700f, 0.658817052764149480f, + -0.752303190865996400f, + 0.658672788323441890f, -0.752429503622912390f, 0.658528499665218760f, + -0.752555788715146390f, + 0.658384186794785050f, -0.752682046138055230f, 0.658239849717446980f, + -0.752808275886996950f, + 0.658095488438511290f, -0.752934477957330150f, 0.657951102963285630f, + -0.753060652344415100f, + 0.657806693297078640f, -0.753186799043612410f, 0.657662259445200070f, + -0.753312918050284330f, + 0.657517801412960120f, -0.753439009359793580f, 0.657373319205670210f, + -0.753565072967504190f, + 0.657228812828642650f, -0.753691108868781210f, 0.657084282287190180f, + -0.753817117058990680f, + 0.656939727586627110f, -0.753943097533499640f, 0.656795148732268070f, + -0.754069050287676120f, + 0.656650545729429050f, -0.754194975316889170f, 0.656505918583426550f, + -0.754320872616508820f, + 0.656361267299578000f, -0.754446742181906330f, 0.656216591883202030f, + -0.754572584008453840f, + 0.656071892339617710f, -0.754698398091524390f, 0.655927168674145360f, + -0.754824184426492240f, + 0.655782420892106030f, -0.754949943008732640f, 0.655637648998821820f, + -0.755075673833621510f, + 0.655492852999615460f, -0.755201376896536550f, 0.655348032899810580f, + -0.755327052192855560f, + 0.655203188704731930f, -0.755452699717958140f, 0.655058320419704910f, + -0.755578319467224540f, + 0.654913428050056150f, -0.755703911436035880f, 0.654768511601112600f, + -0.755829475619774760f, + 0.654623571078202680f, -0.755955012013824310f, 0.654478606486655350f, + -0.756080520613569120f, + 0.654333617831800550f, -0.756206001414394540f, 0.654188605118969040f, + -0.756331454411686920f, + 0.654043568353492640f, -0.756456879600833630f, 0.653898507540703890f, + -0.756582276977223470f, + 0.653753422685936170f, -0.756707646536245670f, 0.653608313794523890f, + -0.756832988273290820f, + 0.653463180871802330f, -0.756958302183750490f, 0.653318023923107670f, + -0.757083588263017140f, + 0.653172842953776760f, -0.757208846506484460f, 0.653027637969147650f, + -0.757334076909547130f, + 0.652882408974558960f, -0.757459279467600720f, 0.652737155975350420f, + -0.757584454176041810f, + 0.652591878976862550f, -0.757709601030268080f, 0.652446577984436840f, + -0.757834720025678310f, + 0.652301253003415460f, -0.757959811157672300f, 0.652155904039141700f, + -0.758084874421650620f, + 0.652010531096959500f, -0.758209909813015280f, 0.651865134182214030f, + -0.758334917327168960f, + 0.651719713300251020f, -0.758459896959515320f, 0.651574268456417080f, + -0.758584848705459500f, + 0.651428799656059820f, -0.758709772560407390f, 0.651283306904527850f, + -0.758834668519765660f, + 0.651137790207170330f, -0.758959536578942440f, 0.650992249569337660f, + -0.759084376733346500f, + 0.650846684996380990f, -0.759209188978387960f, 0.650701096493652040f, + -0.759333973309477940f, + 0.650555484066503990f, -0.759458729722028210f, 0.650409847720290420f, + -0.759583458211452010f, + 0.650264187460365960f, -0.759708158773163440f, 0.650118503292086200f, + -0.759832831402577400f, + 0.649972795220807530f, -0.759957476095110330f, 0.649827063251887100f, + -0.760082092846179220f, + 0.649681307390683190f, -0.760206681651202420f, 0.649535527642554730f, + -0.760331242505599030f, + 0.649389724012861770f, -0.760455775404789260f, 0.649243896506965010f, + -0.760580280344194340f, + 0.649098045130226060f, -0.760704757319236920f, 0.648952169888007410f, + -0.760829206325340010f, + 0.648806270785672550f, -0.760953627357928040f, 0.648660347828585840f, + -0.761078020412426560f, + 0.648514401022112550f, -0.761202385484261780f, 0.648368430371618400f, + -0.761326722568861250f, + 0.648222435882470420f, -0.761451031661653510f, 0.648076417560036530f, + -0.761575312758068000f, + 0.647930375409685460f, -0.761699565853535270f, 0.647784309436786550f, + -0.761823790943486840f, + 0.647638219646710420f, -0.761947988023355390f, 0.647492106044828100f, + -0.762072157088574560f, + 0.647345968636512060f, -0.762196298134578900f, 0.647199807427135230f, + -0.762320411156804160f, + 0.647053622422071650f, -0.762444496150687100f, 0.646907413626696020f, + -0.762568553111665380f, + 0.646761181046383920f, -0.762692582035177870f, 0.646614924686512050f, + -0.762816582916664320f, + 0.646468644552457890f, -0.762940555751565720f, 0.646322340649599590f, + -0.763064500535323710f, + 0.646176012983316390f, -0.763188417263381270f, 0.646029661558988330f, + -0.763312305931182380f, + 0.645883286381996440f, -0.763436166534172010f, 0.645736887457722290f, + -0.763559999067796150f, + 0.645590464791548800f, -0.763683803527501870f, 0.645444018388859230f, + -0.763807579908737160f, + 0.645297548255038380f, -0.763931328206951090f, 0.645151054395471270f, + -0.764055048417593860f, + 0.645004536815544040f, -0.764178740536116670f, 0.644857995520643710f, + -0.764302404557971720f, + 0.644711430516158420f, -0.764426040478612070f, 0.644564841807476750f, + -0.764549648293492150f, + 0.644418229399988380f, -0.764673227998067140f, 0.644271593299083900f, + -0.764796779587793460f, + 0.644124933510154540f, -0.764920303058128410f, 0.643978250038592660f, + -0.765043798404530410f, + 0.643831542889791500f, -0.765167265622458960f, 0.643684812069144960f, + -0.765290704707374260f, + 0.643538057582047850f, -0.765414115654738160f, 0.643391279433895960f, + -0.765537498460013070f, + 0.643244477630085850f, -0.765660853118662390f, 0.643097652176015110f, + -0.765784179626150970f, + 0.642950803077082080f, -0.765907477977944230f, 0.642803930338686100f, + -0.766030748169509000f, + 0.642657033966226860f, -0.766153990196312810f, 0.642510113965105710f, + -0.766277204053824710f, + 0.642363170340724320f, -0.766400389737514120f, 0.642216203098485370f, + -0.766523547242852100f, + 0.642069212243792540f, -0.766646676565310380f, 0.641922197782050170f, + -0.766769777700361920f, + 0.641775159718663500f, -0.766892850643480670f, 0.641628098059038860f, + -0.767015895390141480f, + 0.641481012808583160f, -0.767138911935820400f, 0.641333903972704290f, + -0.767261900275994390f, + 0.641186771556811250f, -0.767384860406141620f, 0.641039615566313390f, + -0.767507792321741270f, + 0.640892436006621380f, -0.767630696018273270f, 0.640745232883146440f, + -0.767753571491219030f, + 0.640598006201301030f, -0.767876418736060610f, 0.640450755966498140f, + -0.767999237748281270f, + 0.640303482184151670f, -0.768122028523365310f, 0.640156184859676620f, + -0.768244791056798220f, + 0.640008863998488440f, -0.768367525344066270f, 0.639861519606004010f, + -0.768490231380656750f, + 0.639714151687640450f, -0.768612909162058270f, 0.639566760248816420f, + -0.768735558683760310f, + 0.639419345294950700f, -0.768858179941253270f, 0.639271906831463510f, + -0.768980772930028870f, + 0.639124444863775730f, -0.769103337645579590f, 0.638976959397309140f, + -0.769225874083399260f, + 0.638829450437486400f, -0.769348382238982280f, 0.638681917989730840f, + -0.769470862107824560f, + 0.638534362059466790f, -0.769593313685422940f, 0.638386782652119680f, + -0.769715736967275020f, + 0.638239179773115390f, -0.769838131948879840f, 0.638091553427880930f, + -0.769960498625737230f, + 0.637943903621844170f, -0.770082836993347900f, 0.637796230360433540f, + -0.770205147047214100f, + 0.637648533649078810f, -0.770327428782838770f, 0.637500813493210310f, + -0.770449682195725960f, + 0.637353069898259130f, -0.770571907281380700f, 0.637205302869657600f, + -0.770694104035309140f, + 0.637057512412838590f, -0.770816272453018430f, 0.636909698533235870f, + -0.770938412530016940f, + 0.636761861236284200f, -0.771060524261813710f, 0.636614000527419230f, + -0.771182607643919220f, + 0.636466116412077180f, -0.771304662671844720f, 0.636318208895695570f, + -0.771426689341102590f, + 0.636170277983712170f, -0.771548687647206300f, 0.636022323681566300f, + -0.771670657585670330f, + 0.635874345994697720f, -0.771792599152010150f, 0.635726344928547180f, + -0.771914512341742350f, + 0.635578320488556230f, -0.772036397150384410f, 0.635430272680167160f, + -0.772158253573455240f, + 0.635282201508823530f, -0.772280081606474320f, 0.635134106979969300f, + -0.772401881244962340f, + 0.634985989099049460f, -0.772523652484441330f, 0.634837847871510100f, + -0.772645395320433860f, + 0.634689683302797850f, -0.772767109748463740f, 0.634541495398360130f, + -0.772888795764056220f, + 0.634393284163645490f, -0.773010453362736990f, 0.634245049604103330f, + -0.773132082540033070f, + 0.634096791725183740f, -0.773253683291472590f, 0.633948510532337810f, + -0.773375255612584470f, + 0.633800206031017280f, -0.773496799498899050f, 0.633651878226674900f, + -0.773618314945947460f, + 0.633503527124764320f, -0.773739801949261840f, 0.633355152730740060f, + -0.773861260504375540f, + 0.633206755050057190f, -0.773982690606822790f, 0.633058334088172250f, + -0.774104092252138940f, + 0.632909889850541860f, -0.774225465435860570f, 0.632761422342624000f, + -0.774346810153525020f, + 0.632612931569877520f, -0.774468126400670860f, 0.632464417537761840f, + -0.774589414172837550f, + 0.632315880251737680f, -0.774710673465565550f, 0.632167319717266030f, + -0.774831904274396850f, + 0.632018735939809060f, -0.774953106594873820f, 0.631870128924829850f, + -0.775074280422540450f, + 0.631721498677792370f, -0.775195425752941310f, 0.631572845204161130f, + -0.775316542581622410f, + 0.631424168509401860f, -0.775437630904130430f, 0.631275468598980870f, + -0.775558690716013580f, + 0.631126745478365340f, -0.775679722012820540f, 0.630977999153023660f, + -0.775800724790101540f, + 0.630829229628424470f, -0.775921699043407580f, 0.630680436910038060f, + -0.776042644768290770f, + 0.630531621003334600f, -0.776163561960304340f, 0.630382781913785940f, + -0.776284450615002400f, + 0.630233919646864480f, -0.776405310727940390f, 0.630085034208043290f, + -0.776526142294674430f, + 0.629936125602796550f, -0.776646945310762060f, 0.629787193836599200f, + -0.776767719771761510f, + 0.629638238914927100f, -0.776888465673232440f, 0.629489260843256740f, + -0.777009183010735290f, + 0.629340259627065750f, -0.777129871779831620f, 0.629191235271832410f, + -0.777250531976084070f, + 0.629042187783036000f, -0.777371163595056200f, 0.628893117166156480f, + -0.777491766632312900f, + 0.628744023426674790f, -0.777612341083419920f, 0.628594906570072660f, + -0.777732886943944050f, + 0.628445766601832710f, -0.777853404209453040f, 0.628296603527438440f, + -0.777973892875515990f, + 0.628147417352374120f, -0.778094352937702790f, 0.627998208082124810f, + -0.778214784391584420f, + 0.627848975722176570f, -0.778335187232733090f, 0.627699720278016240f, + -0.778455561456721900f, + 0.627550441755131530f, -0.778575907059124940f, 0.627401140159011160f, + -0.778696224035517530f, + 0.627251815495144190f, -0.778816512381475870f, 0.627102467769021010f, + -0.778936772092577500f, + 0.626953096986132770f, -0.779057003164400630f, 0.626803703151971310f, + -0.779177205592524680f, + 0.626654286272029460f, -0.779297379372530300f, 0.626504846351800930f, + -0.779417524499998900f, + 0.626355383396779990f, -0.779537640970513150f, 0.626205897412462130f, + -0.779657728779656780f, + 0.626056388404343520f, -0.779777787923014440f, 0.625906856377921210f, + -0.779897818396171890f, + 0.625757301338692900f, -0.780017820194715990f, 0.625607723292157410f, + -0.780137793314234500f, + 0.625458122243814360f, -0.780257737750316590f, 0.625308498199164010f, + -0.780377653498552040f, + 0.625158851163707730f, -0.780497540554531910f, 0.625009181142947460f, + -0.780617398913848290f, + 0.624859488142386450f, -0.780737228572094380f, 0.624709772167528100f, + -0.780857029524864470f, + 0.624560033223877320f, -0.780976801767753750f, 0.624410271316939380f, + -0.781096545296358410f, + 0.624260486452220650f, -0.781216260106276090f, 0.624110678635228510f, + -0.781335946193104870f, + 0.623960847871470770f, -0.781455603552444480f, 0.623810994166456130f, + -0.781575232179895550f, + 0.623661117525694640f, -0.781694832071059390f, 0.623511217954696550f, + -0.781814403221538830f, + 0.623361295458973340f, -0.781933945626937630f, 0.623211350044037270f, + -0.782053459282860300f, + 0.623061381715401370f, -0.782172944184912900f, 0.622911390478579460f, + -0.782292400328702400f, + 0.622761376339086460f, -0.782411827709836420f, 0.622611339302437730f, + -0.782531226323924240f, + 0.622461279374150080f, -0.782650596166575730f, 0.622311196559740320f, + -0.782769937233402050f, + 0.622161090864726930f, -0.782889249520015480f, 0.622010962294628600f, + -0.783008533022029110f, + 0.621860810854965360f, -0.783127787735057310f, 0.621710636551257690f, + -0.783247013654715380f, + 0.621560439389027270f, -0.783366210776619720f, 0.621410219373796150f, + -0.783485379096387820f, + 0.621259976511087660f, -0.783604518609638200f, 0.621109710806425740f, + -0.783723629311990470f, + 0.620959422265335180f, -0.783842711199065230f, 0.620809110893341900f, + -0.783961764266484010f, + 0.620658776695972140f, -0.784080788509869950f, 0.620508419678753360f, + -0.784199783924846570f, + 0.620358039847213830f, -0.784318750507038920f, 0.620207637206882430f, + -0.784437688252072720f, + 0.620057211763289210f, -0.784556597155575240f, 0.619906763521964830f, + -0.784675477213174320f, + 0.619756292488440660f, -0.784794328420499230f, 0.619605798668249390f, + -0.784913150773180020f, + 0.619455282066924020f, -0.785031944266848080f, 0.619304742689998690f, + -0.785150708897135560f, + 0.619154180543008410f, -0.785269444659675850f, 0.619003595631488770f, + -0.785388151550103550f, + 0.618852987960976320f, -0.785506829564053930f, 0.618702357537008640f, + -0.785625478697163700f, + 0.618551704365123860f, -0.785744098945070360f, 0.618401028450860980f, + -0.785862690303412600f, + 0.618250329799760250f, -0.785981252767830150f, 0.618099608417362110f, + -0.786099786333963820f, + 0.617948864309208260f, -0.786218290997455550f, 0.617798097480841140f, + -0.786336766753948260f, + 0.617647307937803980f, -0.786455213599085770f, 0.617496495685640910f, + -0.786573631528513230f, + 0.617345660729896940f, -0.786692020537876680f, 0.617194803076117630f, + -0.786810380622823490f, + 0.617043922729849760f, -0.786928711779001700f, 0.616893019696640790f, + -0.787047014002060790f, + 0.616742093982038830f, -0.787165287287650890f, 0.616591145591593230f, + -0.787283531631423620f, + 0.616440174530853650f, -0.787401747029031320f, 0.616289180805370980f, + -0.787519933476127810f, + 0.616138164420696910f, -0.787638090968367450f, 0.615987125382383870f, + -0.787756219501405950f, + 0.615836063695985090f, -0.787874319070900110f, 0.615684979367054570f, + -0.787992389672507950f, + 0.615533872401147430f, -0.788110431301888070f, 0.615382742803819330f, + -0.788228443954700490f, + 0.615231590580626820f, -0.788346427626606230f, 0.615080415737127460f, + -0.788464382313267430f, + 0.614929218278879590f, -0.788582308010347120f, 0.614777998211442190f, + -0.788700204713509660f, + 0.614626755540375050f, -0.788818072418420170f, 0.614475490271239160f, + -0.788935911120745130f, + 0.614324202409595950f, -0.789053720816151880f, 0.614172891961007990f, + -0.789171501500308790f, + 0.614021558931038490f, -0.789289253168885650f, 0.613870203325251440f, + -0.789406975817552810f, + 0.613718825149211830f, -0.789524669441982190f, 0.613567424408485330f, + -0.789642334037846340f, + 0.613416001108638590f, -0.789759969600819070f, 0.613264555255239150f, + -0.789877576126575280f, + 0.613113086853854910f, -0.789995153610791090f, 0.612961595910055170f, + -0.790112702049143300f, + 0.612810082429409710f, -0.790230221437310030f, 0.612658546417489290f, + -0.790347711770970520f, + 0.612506987879865570f, -0.790465173045804880f, 0.612355406822110760f, + -0.790582605257494460f, + 0.612203803249798060f, -0.790700008401721610f, 0.612052177168501580f, + -0.790817382474169660f, + 0.611900528583796070f, -0.790934727470523290f, 0.611748857501257400f, + -0.791052043386467950f, + 0.611597163926462020f, -0.791169330217690090f, 0.611445447864987110f, + -0.791286587959877720f, + 0.611293709322411010f, -0.791403816608719500f, 0.611141948304312570f, + -0.791521016159905220f, + 0.610990164816271770f, -0.791638186609125770f, 0.610838358863869280f, + -0.791755327952073150f, + 0.610686530452686280f, -0.791872440184440470f, 0.610534679588305320f, + -0.791989523301921850f, + 0.610382806276309480f, -0.792106577300212390f, 0.610230910522282620f, + -0.792223602175008310f, + 0.610078992331809620f, -0.792340597922007060f, 0.609927051710476230f, + -0.792457564536906970f, + 0.609775088663868430f, -0.792574502015407580f, 0.609623103197573730f, + -0.792691410353209450f, + 0.609471095317180240f, -0.792808289546014120f, 0.609319065028276820f, + -0.792925139589524260f, + 0.609167012336453210f, -0.793041960479443640f, 0.609014937247299940f, + -0.793158752211477140f, + 0.608862839766408200f, -0.793275514781330630f, 0.608710719899370420f, + -0.793392248184711100f, + 0.608558577651779450f, -0.793508952417326660f, 0.608406413029229260f, + -0.793625627474886190f, + 0.608254226037314490f, -0.793742273353100100f, 0.608102016681630550f, + -0.793858890047679620f, + 0.607949784967773740f, -0.793975477554337170f, 0.607797530901341140f, + -0.794092035868785960f, + 0.607645254487930830f, -0.794208564986740640f, 0.607492955733141660f, + -0.794325064903916520f, + 0.607340634642572930f, -0.794441535616030590f, 0.607188291221825160f, + -0.794557977118800270f, + 0.607035925476499760f, -0.794674389407944550f, 0.606883537412198580f, + -0.794790772479183170f, + 0.606731127034524480f, -0.794907126328237010f, 0.606578694349081400f, + -0.795023450950828050f, + 0.606426239361473550f, -0.795139746342679590f, 0.606273762077306430f, + -0.795256012499515500f, + 0.606121262502186230f, -0.795372249417061190f, 0.605968740641719790f, + -0.795488457091042990f, + 0.605816196501515080f, -0.795604635517188070f, 0.605663630087180490f, + -0.795720784691225090f, + 0.605511041404325550f, -0.795836904608883460f, 0.605358430458560530f, + -0.795952995265893910f, + 0.605205797255496500f, -0.796069056657987990f, 0.605053141800745430f, + -0.796185088780898440f, + 0.604900464099919930f, -0.796301091630359110f, 0.604747764158633410f, + -0.796417065202104980f, + 0.604595041982500360f, -0.796533009491872000f, 0.604442297577135970f, + -0.796648924495397150f, + 0.604289530948156070f, -0.796764810208418720f, 0.604136742101177630f, + -0.796880666626675780f, + 0.603983931041818020f, -0.796996493745908750f, 0.603831097775695880f, + -0.797112291561858920f, + 0.603678242308430370f, -0.797228060070268700f, 0.603525364645641550f, + -0.797343799266881700f, + 0.603372464792950370f, -0.797459509147442460f, 0.603219542755978440f, + -0.797575189707696590f, + 0.603066598540348280f, -0.797690840943391040f, 0.602913632151683140f, + -0.797806462850273570f, + 0.602760643595607220f, -0.797922055424093000f, 0.602607632877745550f, + -0.798037618660599410f, + 0.602454600003723860f, -0.798153152555543750f, 0.602301544979168550f, + -0.798268657104678310f, + 0.602148467809707320f, -0.798384132303756380f, 0.601995368500968130f, + -0.798499578148532010f, + 0.601842247058580030f, -0.798614994634760820f, 0.601689103488173060f, + -0.798730381758199210f, + 0.601535937795377730f, -0.798845739514604580f, 0.601382749985825420f, + -0.798961067899735760f, + 0.601229540065148620f, -0.799076366909352350f, 0.601076308038980160f, + -0.799191636539215210f, + 0.600923053912954090f, -0.799306876785086160f, 0.600769777692705230f, + -0.799422087642728040f, + 0.600616479383868970f, -0.799537269107905010f, 0.600463158992081690f, + -0.799652421176382130f, + 0.600309816522980430f, -0.799767543843925680f, 0.600156451982203350f, + -0.799882637106302810f, + 0.600003065375389060f, -0.799997700959281910f, 0.599849656708177360f, + -0.800112735398632370f, + 0.599696225986208310f, -0.800227740420124790f, 0.599542773215123390f, + -0.800342716019530660f, + 0.599389298400564540f, -0.800457662192622710f, 0.599235801548174570f, + -0.800572578935174750f, + 0.599082282663597310f, -0.800687466242961500f, 0.598928741752476900f, + -0.800802324111759110f, + 0.598775178820458720f, -0.800917152537344300f, 0.598621593873188920f, + -0.801031951515495330f, + 0.598467986916314310f, -0.801146721041991250f, 0.598314357955482600f, + -0.801261461112612540f, + 0.598160706996342380f, -0.801376171723140130f, 0.598007034044542700f, + -0.801490852869356840f, + 0.597853339105733910f, -0.801605504547046040f, 0.597699622185566830f, + -0.801720126751992330f, + 0.597545883289693270f, -0.801834719479981310f, 0.597392122423765710f, + -0.801949282726799660f, + 0.597238339593437530f, -0.802063816488235440f, 0.597084534804362740f, + -0.802178320760077450f, + 0.596930708062196500f, -0.802292795538115720f, 0.596776859372594500f, + -0.802407240818141300f, + 0.596622988741213330f, -0.802521656595946320f, 0.596469096173710360f, + -0.802636042867324150f, + 0.596315181675743820f, -0.802750399628069160f, 0.596161245252972540f, + -0.802864726873976590f, + 0.596007286911056530f, -0.802979024600843140f, 0.595853306655656390f, + -0.803093292804466400f, + 0.595699304492433470f, -0.803207531480644830f, 0.595545280427049790f, + -0.803321740625178470f, + 0.595391234465168730f, -0.803435920233868120f, 0.595237166612453850f, + -0.803550070302515570f, + 0.595083076874569960f, -0.803664190826924090f, 0.594928965257182420f, + -0.803778281802897570f, + 0.594774831765957580f, -0.803892343226241260f, 0.594620676406562240f, + -0.804006375092761520f, + 0.594466499184664540f, -0.804120377398265700f, 0.594312300105932830f, + -0.804234350138562260f, + 0.594158079176036800f, -0.804348293309460780f, 0.594003836400646690f, + -0.804462206906771840f, + 0.593849571785433630f, -0.804576090926307000f, 0.593695285336069300f, + -0.804689945363879500f, + 0.593540977058226390f, -0.804803770215302810f, 0.593386646957578480f, + -0.804917565476392150f, + 0.593232295039799800f, -0.805031331142963660f, 0.593077921310565580f, + -0.805145067210834120f, + 0.592923525775551410f, -0.805258773675822210f, 0.592769108440434070f, + -0.805372450533747060f, + 0.592614669310891130f, -0.805486097780429120f, 0.592460208392600940f, + -0.805599715411689950f, + 0.592305725691242400f, -0.805713303423352120f, 0.592151221212495640f, + -0.805826861811239300f, + 0.591996694962040990f, -0.805940390571176280f, 0.591842146945560250f, + -0.806053889698988950f, + 0.591687577168735550f, -0.806167359190504310f, 0.591532985637249990f, + -0.806280799041550370f, + 0.591378372356787580f, -0.806394209247956240f, 0.591223737333032910f, + -0.806507589805552260f, + 0.591069080571671510f, -0.806620940710169650f, 0.590914402078389520f, + -0.806734261957640750f, + 0.590759701858874280f, -0.806847553543799220f, 0.590604979918813440f, + -0.806960815464479620f, + 0.590450236263895920f, -0.807074047715517610f, 0.590295470899810940f, + -0.807187250292749850f, + 0.590140683832248940f, -0.807300423192014450f, 0.589985875066900920f, + -0.807413566409150190f, + 0.589831044609458900f, -0.807526679939997160f, 0.589676192465615420f, + -0.807639763780396370f, + 0.589521318641063940f, -0.807752817926190360f, 0.589366423141498790f, + -0.807865842373222120f, + 0.589211505972615070f, -0.807978837117336310f, 0.589056567140108460f, + -0.808091802154378260f, + 0.588901606649675840f, -0.808204737480194720f, 0.588746624507014650f, + -0.808317643090633250f, + 0.588591620717822890f, -0.808430518981542720f, 0.588436595287799900f, + -0.808543365148773010f, + 0.588281548222645330f, -0.808656181588174980f, 0.588126479528059850f, + -0.808768968295600850f, + 0.587971389209745120f, -0.808881725266903610f, 0.587816277273403020f, + -0.808994452497937560f, + 0.587661143724736770f, -0.809107149984558130f, 0.587505988569450020f, + -0.809219817722621750f, + 0.587350811813247660f, -0.809332455707985840f, 0.587195613461834910f, + -0.809445063936509170f, + 0.587040393520918080f, -0.809557642404051260f, 0.586885151996203950f, + -0.809670191106473090f, + 0.586729888893400500f, -0.809782710039636420f, 0.586574604218216280f, + -0.809895199199404450f, + 0.586419297976360500f, -0.810007658581641140f, 0.586263970173543700f, + -0.810120088182211600f, + 0.586108620815476430f, -0.810232487996982330f, 0.585953249907870680f, + -0.810344858021820550f, + 0.585797857456438860f, -0.810457198252594770f, 0.585642443466894420f, + -0.810569508685174630f, + 0.585487007944951450f, -0.810681789315430670f, 0.585331550896324940f, + -0.810794040139234730f, + 0.585176072326730410f, -0.810906261152459670f, 0.585020572241884530f, + -0.811018452350979470f, + 0.584865050647504490f, -0.811130613730669190f, 0.584709507549308500f, + -0.811242745287404810f, + 0.584553942953015330f, -0.811354847017063730f, 0.584398356864344710f, + -0.811466918915524250f, + 0.584242749289016980f, -0.811578960978665890f, 0.584087120232753550f, + -0.811690973202369050f, + 0.583931469701276300f, -0.811802955582515360f, 0.583775797700308070f, + -0.811914908114987680f, + 0.583620104235572760f, -0.812026830795669730f, 0.583464389312794430f, + -0.812138723620446480f, + 0.583308652937698290f, -0.812250586585203880f, 0.583152895116010540f, + -0.812362419685829120f, + 0.582997115853457700f, -0.812474222918210480f, 0.582841315155767650f, + -0.812585996278237020f, + 0.582685493028668460f, -0.812697739761799490f, 0.582529649477889320f, + -0.812809453364789160f, + 0.582373784509160220f, -0.812921137083098770f, 0.582217898128211790f, + -0.813032790912621930f, + 0.582061990340775550f, -0.813144414849253590f, 0.581906061152583920f, + -0.813256008888889380f, + 0.581750110569369760f, -0.813367573027426570f, 0.581594138596866930f, + -0.813479107260763220f, + 0.581438145240810280f, -0.813590611584798510f, 0.581282130506935110f, + -0.813702085995432700f, + 0.581126094400977620f, -0.813813530488567190f, 0.580970036928674880f, + -0.813924945060104490f, + 0.580813958095764530f, -0.814036329705948300f, 0.580657857907985410f, + -0.814147684422003360f, + 0.580501736371076600f, -0.814259009204175270f, 0.580345593490778300f, + -0.814370304048371070f, + 0.580189429272831680f, -0.814481568950498610f, 0.580033243722978150f, + -0.814592803906467270f, + 0.579877036846960350f, -0.814704008912187080f, 0.579720808650521560f, + -0.814815183963569330f, + 0.579564559139405740f, -0.814926329056526620f, 0.579408288319357980f, + -0.815037444186972220f, + 0.579251996196123550f, -0.815148529350820830f, 0.579095682775449210f, + -0.815259584543988280f, + 0.578939348063081890f, -0.815370609762391290f, 0.578782992064769690f, + -0.815481605001947770f, + 0.578626614786261430f, -0.815592570258576680f, 0.578470216233306740f, + -0.815703505528198260f, + 0.578313796411655590f, -0.815814410806733780f, 0.578157355327059360f, + -0.815925286090105390f, + 0.578000892985269910f, -0.816036131374236700f, 0.577844409392039850f, + -0.816146946655052160f, + 0.577687904553122800f, -0.816257731928477390f, 0.577531378474272830f, + -0.816368487190439200f, + 0.577374831161244880f, -0.816479212436865390f, 0.577218262619794920f, + -0.816589907663684890f, + 0.577061672855679550f, -0.816700572866827850f, 0.576905061874655960f, + -0.816811208042225290f, + 0.576748429682482520f, -0.816921813185809480f, 0.576591776284917870f, + -0.817032388293513880f, + 0.576435101687721830f, -0.817142933361272970f, 0.576278405896654910f, + -0.817253448385022230f, + 0.576121688917478390f, -0.817363933360698460f, 0.575964950755954330f, + -0.817474388284239240f, + 0.575808191417845340f, -0.817584813151583710f, 0.575651410908915250f, + -0.817695207958671680f, + 0.575494609234928230f, -0.817805572701444270f, 0.575337786401649560f, + -0.817915907375843740f, + 0.575180942414845190f, -0.818026211977813440f, 0.575024077280281820f, + -0.818136486503297620f, + 0.574867191003726740f, -0.818246730948241960f, 0.574710283590948450f, + -0.818356945308593150f, + 0.574553355047715760f, -0.818467129580298660f, 0.574396405379798750f, + -0.818577283759307490f, + 0.574239434592967890f, -0.818687407841569570f, 0.574082442692994470f, + -0.818797501823036010f, + 0.573925429685650750f, -0.818907565699658950f, 0.573768395576709560f, + -0.819017599467391500f, + 0.573611340371944610f, -0.819127603122188240f, 0.573454264077130400f, + -0.819237576660004520f, + 0.573297166698042320f, -0.819347520076796900f, 0.573140048240456060f, + -0.819457433368523280f, + 0.572982908710148680f, -0.819567316531142230f, 0.572825748112897550f, + -0.819677169560613760f, + 0.572668566454481160f, -0.819786992452898990f, 0.572511363740678790f, + -0.819896785203959810f, + 0.572354139977270030f, -0.820006547809759680f, 0.572196895170035580f, + -0.820116280266262710f, + 0.572039629324757050f, -0.820225982569434690f, 0.571882342447216590f, + -0.820335654715241840f, + 0.571725034543197120f, -0.820445296699652050f, 0.571567705618482580f, + -0.820554908518633890f, + 0.571410355678857340f, -0.820664490168157460f, 0.571252984730106660f, + -0.820774041644193650f, + 0.571095592778016690f, -0.820883562942714580f, 0.570938179828374360f, + -0.820993054059693470f, + 0.570780745886967370f, -0.821102514991104650f, 0.570623290959583860f, + -0.821211945732923550f, + 0.570465815052012990f, -0.821321346281126740f, 0.570308318170045010f, + -0.821430716631691760f, + 0.570150800319470300f, -0.821540056780597610f, 0.569993261506080650f, + -0.821649366723823830f, + 0.569835701735668110f, -0.821758646457351640f, 0.569678121014025710f, + -0.821867895977163140f, + 0.569520519346947250f, -0.821977115279241550f, 0.569362896740227330f, + -0.822086304359571090f, + 0.569205253199661200f, -0.822195463214137170f, 0.569047588731045220f, + -0.822304591838926350f, + 0.568889903340175970f, -0.822413690229926390f, 0.568732197032851160f, + -0.822522758383125940f, + 0.568574469814869250f, -0.822631796294514990f, 0.568416721692029390f, + -0.822740803960084420f, + 0.568258952670131490f, -0.822849781375826320f, 0.568101162754976570f, + -0.822958728537734000f, + 0.567943351952365670f, -0.823067645441801670f, 0.567785520268101250f, + -0.823176532084024860f, + 0.567627667707986230f, -0.823285388460400110f, 0.567469794277824620f, + -0.823394214566925080f, + 0.567311899983420800f, -0.823503010399598390f, 0.567153984830580100f, + -0.823611775954420260f, + 0.566996048825108680f, -0.823720511227391320f, 0.566838091972813320f, + -0.823829216214513990f, + 0.566680114279501710f, -0.823937890911791370f, 0.566522115750982100f, + -0.824046535315227760f, + 0.566364096393063950f, -0.824155149420828570f, 0.566206056211556840f, + -0.824263733224600450f, + 0.566047995212271560f, -0.824372286722551250f, 0.565889913401019570f, + -0.824480809910689500f, + 0.565731810783613230f, -0.824589302785025290f, 0.565573687365865440f, + -0.824697765341569470f, + 0.565415543153589770f, -0.824806197576334330f, 0.565257378152600910f, + -0.824914599485333080f, + 0.565099192368714090f, -0.825022971064580220f, 0.564940985807745320f, + -0.825131312310090960f, + 0.564782758475511400f, -0.825239623217882130f, 0.564624510377830120f, + -0.825347903783971380f, + 0.564466241520519500f, -0.825456154004377440f, 0.564307951909398750f, + -0.825564373875120490f, + 0.564149641550287680f, -0.825672563392221390f, 0.563991310449007080f, + -0.825780722551702430f, + 0.563832958611378170f, -0.825888851349586780f, 0.563674586043223180f, + -0.825996949781898970f, + 0.563516192750364910f, -0.826105017844664610f, 0.563357778738627020f, + -0.826213055533910110f, + 0.563199344013834090f, -0.826321062845663420f, 0.563040888581811230f, + -0.826429039775953390f, + 0.562882412448384550f, -0.826536986320809960f, 0.562723915619380400f, + -0.826644902476264210f, + 0.562565398100626560f, -0.826752788238348520f, 0.562406859897951140f, + -0.826860643603096080f, + 0.562248301017183150f, -0.826968468566541490f, 0.562089721464152480f, + -0.827076263124720270f, + 0.561931121244689470f, -0.827184027273669020f, 0.561772500364625450f, + -0.827291761009425810f, + 0.561613858829792420f, -0.827399464328029350f, 0.561455196646023280f, + -0.827507137225519830f, + 0.561296513819151470f, -0.827614779697938400f, 0.561137810355011530f, + -0.827722391741327220f, + 0.560979086259438260f, -0.827829973351729810f, 0.560820341538267540f, + -0.827937524525190870f, + 0.560661576197336030f, -0.828045045257755800f, 0.560502790242481060f, + -0.828152535545471410f, + 0.560343983679540860f, -0.828259995384385550f, 0.560185156514354080f, + -0.828367424770547480f, + 0.560026308752760380f, -0.828474823700007130f, 0.559867440400600320f, + -0.828582192168815790f, + 0.559708551463714790f, -0.828689530173025710f, 0.559549641947945870f, + -0.828796837708690610f, + 0.559390711859136140f, -0.828904114771864870f, 0.559231761203129010f, + -0.829011361358604430f, + 0.559072789985768480f, -0.829118577464965980f, 0.558913798212899770f, + -0.829225763087007570f, + 0.558754785890368310f, -0.829332918220788250f, 0.558595753024020760f, + -0.829440042862368170f, + 0.558436699619704100f, -0.829547137007808800f, 0.558277625683266330f, + -0.829654200653172640f, + 0.558118531220556100f, -0.829761233794523050f, 0.557959416237422960f, + -0.829868236427924840f, + 0.557800280739717100f, -0.829975208549443840f, 0.557641124733289420f, + -0.830082150155146970f, + 0.557481948223991660f, -0.830189061241102370f, 0.557322751217676160f, + -0.830295941803379070f, + 0.557163533720196340f, -0.830402791838047550f, 0.557004295737406060f, + -0.830509611341179070f, + 0.556845037275160100f, -0.830616400308846200f, 0.556685758339313890f, + -0.830723158737122880f, + 0.556526458935723720f, -0.830829886622083570f, 0.556367139070246490f, + -0.830936583959804410f, + 0.556207798748739930f, -0.831043250746362320f, 0.556048437977062720f, + -0.831149886977835430f, + 0.555889056761073920f, -0.831256492650303210f, 0.555729655106633520f, + -0.831363067759845920f, + 0.555570233019602290f, -0.831469612302545240f, 0.555410790505841740f, + -0.831576126274483630f, + 0.555251327571214090f, -0.831682609671745120f, 0.555091844221582420f, + -0.831789062490414400f, + 0.554932340462810370f, -0.831895484726577590f, 0.554772816300762580f, + -0.832001876376321840f, + 0.554613271741304040f, -0.832108237435735480f, 0.554453706790301040f, + -0.832214567900907980f, + 0.554294121453620110f, -0.832320867767929680f, 0.554134515737128910f, + -0.832427137032892280f, + 0.553974889646695610f, -0.832533375691888680f, 0.553815243188189090f, + -0.832639583741012770f, + 0.553655576367479310f, -0.832745761176359460f, 0.553495889190436570f, + -0.832851907994024980f, + 0.553336181662932410f, -0.832958024190106670f, 0.553176453790838460f, + -0.833064109760702890f, + 0.553016705580027580f, -0.833170164701913190f, 0.552856937036373290f, + -0.833276189009838240f, + 0.552697148165749770f, -0.833382182680579730f, 0.552537338974032120f, + -0.833488145710240770f, + 0.552377509467096070f, -0.833594078094925140f, 0.552217659650817930f, + -0.833699979830738290f, + 0.552057789531074980f, -0.833805850913786340f, 0.551897899113745320f, + -0.833911691340176730f, + 0.551737988404707450f, -0.834017501106018130f, 0.551578057409841000f, + -0.834123280207419990f, + 0.551418106135026060f, -0.834229028640493420f, 0.551258134586143700f, + -0.834334746401350080f, + 0.551098142769075430f, -0.834440433486103190f, 0.550938130689703880f, + -0.834546089890866760f, + 0.550778098353912230f, -0.834651715611756330f, 0.550618045767584330f, + -0.834757310644888230f, + 0.550457972936604810f, -0.834862874986380010f, 0.550297879866859190f, + -0.834968408632350450f, + 0.550137766564233630f, -0.835073911578919300f, 0.549977633034615000f, + -0.835179383822207580f, + 0.549817479283891020f, -0.835284825358337370f, 0.549657305317949980f, + -0.835390236183431780f, + 0.549497111142680960f, -0.835495616293615350f, 0.549336896763974010f, + -0.835600965685013410f, + 0.549176662187719770f, -0.835706284353752600f, 0.549016407419809390f, + -0.835811572295960590f, + 0.548856132466135290f, -0.835916829507766360f, 0.548695837332590090f, + -0.836022055985299880f, + 0.548535522025067390f, -0.836127251724692160f, 0.548375186549461600f, + -0.836232416722075600f, + 0.548214830911667780f, -0.836337550973583530f, 0.548054455117581880f, + -0.836442654475350380f, + 0.547894059173100190f, -0.836547727223511890f, 0.547733643084120200f, + -0.836652769214204950f, + 0.547573206856539870f, -0.836757780443567190f, 0.547412750496257930f, + -0.836862760907737810f, + 0.547252274009174090f, -0.836967710602857020f, 0.547091777401188530f, + -0.837072629525066000f, + 0.546931260678202190f, -0.837177517670507190f, 0.546770723846116800f, + -0.837282375035324320f, + 0.546610166910834860f, -0.837387201615661940f, 0.546449589878259760f, + -0.837491997407665890f, + 0.546288992754295210f, -0.837596762407483040f, 0.546128375544846060f, + -0.837701496611261700f, + 0.545967738255817680f, -0.837806200015150940f, 0.545807080893116140f, + -0.837910872615301060f, + 0.545646403462648590f, -0.838015514407863700f, 0.545485705970322530f, + -0.838120125388991500f, + 0.545324988422046460f, -0.838224705554837970f, 0.545164250823729320f, + -0.838329254901558300f, + 0.545003493181281160f, -0.838433773425308340f, 0.544842715500612470f, + -0.838538261122245170f, + 0.544681917787634530f, -0.838642717988527300f, 0.544521100048259710f, + -0.838747144020313920f, + 0.544360262288400400f, -0.838851539213765760f, 0.544199404513970420f, + -0.838955903565044350f, + 0.544038526730883930f, -0.839060237070312630f, 0.543877628945055980f, + -0.839164539725734570f, + 0.543716711162402390f, -0.839268811527475230f, 0.543555773388839650f, + -0.839373052471700690f, + 0.543394815630284800f, -0.839477262554578550f, 0.543233837892656000f, + -0.839581441772277120f, + 0.543072840181871850f, -0.839685590120966110f, 0.542911822503851730f, + -0.839789707596816260f, + 0.542750784864516000f, -0.839893794195999410f, 0.542589727269785270f, + -0.839997849914688730f, + 0.542428649725581360f, -0.840101874749058400f, 0.542267552237826520f, + -0.840205868695283580f, + 0.542106434812444030f, -0.840309831749540770f, 0.541945297455357470f, + -0.840413763908007480f, + 0.541784140172491660f, -0.840517665166862440f, 0.541622962969771640f, + -0.840621535522285690f, + 0.541461765853123560f, -0.840725374970458070f, 0.541300548828474120f, + -0.840829183507561640f, + 0.541139311901750910f, -0.840932961129779670f, 0.540978055078882190f, + -0.841036707833296650f, + 0.540816778365796670f, -0.841140423614298080f, 0.540655481768424260f, + -0.841244108468970580f, + 0.540494165292695230f, -0.841347762393501950f, 0.540332828944540820f, + -0.841451385384081260f, + 0.540171472729892970f, -0.841554977436898330f, 0.540010096654684020f, + -0.841658538548144760f, + 0.539848700724847700f, -0.841762068714012490f, 0.539687284946317570f, + -0.841865567930695340f, + 0.539525849325029010f, -0.841969036194387680f, 0.539364393866917150f, + -0.842072473501285450f, + 0.539202918577918240f, -0.842175879847585570f, 0.539041423463969550f, + -0.842279255229485880f, + 0.538879908531008420f, -0.842382599643185960f, 0.538718373784973670f, + -0.842485913084885630f, + 0.538556819231804210f, -0.842589195550786600f, 0.538395244877439950f, + -0.842692447037091560f, + 0.538233650727821700f, -0.842795667540004120f, 0.538072036788890600f, + -0.842898857055729310f, + 0.537910403066588990f, -0.843002015580472830f, 0.537748749566859470f, + -0.843105143110442050f, + 0.537587076295645510f, -0.843208239641845440f, 0.537425383258891660f, + -0.843311305170892030f, + 0.537263670462542530f, -0.843414339693792760f, 0.537101937912544240f, + -0.843517343206759080f, + 0.536940185614843020f, -0.843620315706004040f, 0.536778413575385920f, + -0.843723257187741550f, + 0.536616621800121150f, -0.843826167648186740f, 0.536454810294997090f, + -0.843929047083555870f, + 0.536292979065963180f, -0.844031895490066410f, 0.536131128118969350f, + -0.844134712863936930f, + 0.535969257459966710f, -0.844237499201387020f, 0.535807367094906620f, + -0.844340254498637590f, + 0.535645457029741090f, -0.844442978751910660f, 0.535483527270423370f, + -0.844545671957429240f, + 0.535321577822907010f, -0.844648334111417820f, 0.535159608693146720f, + -0.844750965210101510f, + 0.534997619887097260f, -0.844853565249707010f, 0.534835611410714670f, + -0.844956134226462100f, + 0.534673583269955510f, -0.845058672136595470f, 0.534511535470777010f, + -0.845161178976337140f, + 0.534349468019137520f, -0.845263654741918220f, 0.534187380920995600f, + -0.845366099429570970f, + 0.534025274182310380f, -0.845468513035528830f, 0.533863147809042650f, + -0.845570895556026270f, + 0.533701001807152960f, -0.845673246987299070f, 0.533538836182603120f, + -0.845775567325583900f, + 0.533376650941355560f, -0.845877856567118890f, 0.533214446089372960f, + -0.845980114708143270f, + 0.533052221632619670f, -0.846082341744896940f, 0.532889977577059690f, + -0.846184537673621670f, + 0.532727713928658810f, -0.846286702490559710f, 0.532565430693382580f, + -0.846388836191954930f, + 0.532403127877198010f, -0.846490938774052020f, 0.532240805486072330f, + -0.846593010233097190f, + 0.532078463525973540f, -0.846695050565337450f, 0.531916102002870760f, + -0.846797059767020910f, + 0.531753720922733320f, -0.846899037834397350f, 0.531591320291531780f, + -0.847000984763716880f, + 0.531428900115236910f, -0.847102900551231500f, 0.531266460399820390f, + -0.847204785193193980f, + 0.531104001151255000f, -0.847306638685858320f, 0.530941522375513510f, + -0.847408461025479730f, + 0.530779024078570250f, -0.847510252208314330f, 0.530616506266399450f, + -0.847612012230619660f, + 0.530453968944976320f, -0.847713741088654270f, 0.530291412120277420f, + -0.847815438778677930f, + 0.530128835798278850f, -0.847917105296951410f, 0.529966239984958620f, + -0.848018740639736810f, + 0.529803624686294830f, -0.848120344803297120f, 0.529640989908265910f, + -0.848221917783896990f, + 0.529478335656852090f, -0.848323459577801530f, 0.529315661938033140f, + -0.848424970181277600f, + 0.529152968757790720f, -0.848526449590592650f, 0.528990256122106040f, + -0.848627897802015860f, + 0.528827524036961980f, -0.848729314811817010f, 0.528664772508341540f, + -0.848830700616267530f, + 0.528502001542228480f, -0.848932055211639610f, 0.528339211144607690f, + -0.849033378594206690f, + 0.528176401321464370f, -0.849134670760243630f, 0.528013572078784740f, + -0.849235931706025960f, + 0.527850723422555460f, -0.849337161427830670f, 0.527687855358763720f, + -0.849438359921935950f, + 0.527524967893398200f, -0.849539527184620890f, 0.527362061032447430f, + -0.849640663212165910f, + 0.527199134781901390f, -0.849741768000852440f, 0.527036189147750190f, + -0.849842841546963210f, + 0.526873224135984700f, -0.849943883846782210f, 0.526710239752597010f, + -0.850044894896594070f, + 0.526547236003579330f, -0.850145874692685210f, 0.526384212894925210f, + -0.850246823231342710f, + 0.526221170432628170f, -0.850347740508854980f, 0.526058108622682760f, + -0.850448626521511650f, + 0.525895027471084740f, -0.850549481265603370f, 0.525731926983829640f, + -0.850650304737422200f, + 0.525568807166914680f, -0.850751096933260790f, 0.525405668026336810f, + -0.850851857849413640f, + 0.525242509568094710f, -0.850952587482175730f, 0.525079331798186890f, + -0.851053285827843790f, + 0.524916134722612890f, -0.851153952882715340f, 0.524752918347373360f, + -0.851254588643089120f, + 0.524589682678468840f, -0.851355193105265200f, 0.524426427721901510f, + -0.851455766265544310f, + 0.524263153483673470f, -0.851556308120228870f, 0.524099859969787810f, + -0.851656818665622370f, + 0.523936547186248600f, -0.851757297898029120f, 0.523773215139060170f, + -0.851857745813754840f, + 0.523609863834228030f, -0.851958162409106380f, 0.523446493277757940f, + -0.852058547680391580f, + 0.523283103475656430f, -0.852158901623919830f, 0.523119694433931250f, + -0.852259224236001090f, + 0.522956266158590140f, -0.852359515512947090f, 0.522792818655642200f, + -0.852459775451070100f, + 0.522629351931096720f, -0.852560004046683970f, 0.522465865990963900f, + -0.852660201296103760f, + 0.522302360841254700f, -0.852760367195645300f, 0.522138836487980650f, + -0.852860501741625860f, + 0.521975292937154390f, -0.852960604930363630f, 0.521811730194788550f, + -0.853060676758178320f, + 0.521648148266897090f, -0.853160717221390420f, 0.521484547159494550f, + -0.853260726316321770f, + 0.521320926878595550f, -0.853360704039295430f, 0.521157287430216610f, + -0.853460650386635320f, + 0.520993628820373810f, -0.853560565354666840f, 0.520829951055084780f, + -0.853660448939716270f, + 0.520666254140367270f, -0.853760301138111300f, 0.520502538082239790f, + -0.853860121946180660f, + 0.520338802886721960f, -0.853959911360254060f, 0.520175048559833760f, + -0.854059669376662780f, + 0.520011275107596040f, -0.854159395991738730f, 0.519847482536030300f, + -0.854259091201815420f, + 0.519683670851158520f, -0.854358755003227440f, 0.519519840059003870f, + -0.854458387392310060f, + 0.519355990165589530f, -0.854557988365400530f, 0.519192121176940360f, + -0.854657557918836460f, + 0.519028233099080970f, -0.854757096048957110f, 0.518864325938037000f, + -0.854856602752102850f, + 0.518700399699835170f, -0.854956078024614820f, 0.518536454390502110f, + -0.855055521862835950f, + 0.518372490016066220f, -0.855154934263109620f, 0.518208506582555460f, + -0.855254315221781080f, + 0.518044504095999340f, -0.855353664735196030f, 0.517880482562427800f, + -0.855452982799701830f, + 0.517716441987871150f, -0.855552269411646970f, 0.517552382378360990f, + -0.855651524567380690f, + 0.517388303739929060f, -0.855750748263253920f, 0.517224206078608310f, + -0.855849940495618240f, + 0.517060089400432130f, -0.855949101260826790f, 0.516895953711434260f, + -0.856048230555233820f, + 0.516731799017649980f, -0.856147328375194470f, 0.516567625325114350f, + -0.856246394717065210f, + 0.516403432639863990f, -0.856345429577203610f, 0.516239220967935620f, + -0.856444432951968480f, + 0.516074990315366630f, -0.856543404837719960f, 0.515910740688195650f, + -0.856642345230818720f, + 0.515746472092461380f, -0.856741254127627470f, 0.515582184534203790f, + -0.856840131524509220f, + 0.515417878019463150f, -0.856938977417828650f, 0.515253552554280290f, + -0.857037791803951680f, + 0.515089208144697270f, -0.857136574679244870f, 0.514924844796756490f, + -0.857235326040076460f, + 0.514760462516501200f, -0.857334045882815590f, 0.514596061309975040f, + -0.857432734203832700f, + 0.514431641183222930f, -0.857531390999499040f, 0.514267202142289830f, + -0.857630016266187620f, + 0.514102744193221660f, -0.857728610000272120f, 0.513938267342065490f, + -0.857827172198127320f, + 0.513773771594868030f, -0.857925702856129790f, 0.513609256957677900f, + -0.858024201970656540f, + 0.513444723436543570f, -0.858122669538086020f, 0.513280171037514330f, + -0.858221105554798250f, + 0.513115599766640560f, -0.858319510017173440f, 0.512951009629972860f, + -0.858417882921594040f, + 0.512786400633563070f, -0.858516224264442740f, 0.512621772783463100f, + -0.858614534042104080f, + 0.512457126085725800f, -0.858712812250963520f, 0.512292460546404980f, + -0.858811058887407500f, + 0.512127776171554690f, -0.858909273947823900f, 0.511963072967230200f, + -0.859007457428601410f, + 0.511798350939487000f, -0.859105609326130340f, 0.511633610094381350f, + -0.859203729636801920f, + 0.511468850437970520f, -0.859301818357008360f, 0.511304071976311890f, + -0.859399875483143450f, + 0.511139274715464390f, -0.859497901011601620f, 0.510974458661486720f, + -0.859595894938779080f, + 0.510809623820439040f, -0.859693857261072610f, 0.510644770198381730f, + -0.859791787974880540f, + 0.510479897801375700f, -0.859889687076602290f, 0.510315006635483350f, + -0.859987554562638200f, + 0.510150096706766700f, -0.860085390429390140f, 0.509985168021289570f, + -0.860183194673260880f, + 0.509820220585115560f, -0.860280967290654510f, 0.509655254404309250f, + -0.860378708277976130f, + 0.509490269484936360f, -0.860476417631632070f, 0.509325265833062480f, + -0.860574095348029980f, + 0.509160243454754750f, -0.860671741423578380f, 0.508995202356080310f, + -0.860769355854687060f, + 0.508830142543106990f, -0.860866938637767310f, 0.508665064021904260f, + -0.860964489769230900f, + 0.508499966798540810f, -0.861062009245491480f, 0.508334850879087470f, + -0.861159497062963350f, + 0.508169716269614710f, -0.861256953218062060f, 0.508004562976194010f, + -0.861354377707204800f, + 0.507839391004897940f, -0.861451770526809210f, 0.507674200361798890f, + -0.861549131673294720f, + 0.507508991052970870f, -0.861646461143081300f, 0.507343763084487920f, + -0.861743758932590700f, + 0.507178516462425290f, -0.861841025038245330f, 0.507013251192858340f, + -0.861938259456469180f, + 0.506847967281863320f, -0.862035462183687210f, 0.506682664735517600f, + -0.862132633216325380f, + 0.506517343559898530f, -0.862229772550811240f, 0.506352003761084800f, + -0.862326880183573060f, + 0.506186645345155450f, -0.862423956111040500f, 0.506021268318189830f, + -0.862521000329644520f, + 0.505855872686268860f, -0.862618012835816740f, 0.505690458455473340f, + -0.862714993625990690f, + 0.505525025631885510f, -0.862811942696600330f, 0.505359574221587390f, + -0.862908860044081290f, + 0.505194104230662240f, -0.863005745664870210f, 0.505028615665194300f, + -0.863102599555404800f, + 0.504863108531267480f, -0.863199421712124160f, 0.504697582834967680f, + -0.863296212131468230f, + 0.504532038582380380f, -0.863392970809878310f, 0.504366475779592150f, + -0.863489697743797140f, + 0.504200894432690560f, -0.863586392929667990f, 0.504035294547763080f, + -0.863683056363935940f, + 0.503869676130898950f, -0.863779688043046610f, 0.503704039188186960f, + -0.863876287963447510f, + 0.503538383725717580f, -0.863972856121586700f, 0.503372709749581150f, + -0.864069392513913680f, + 0.503207017265869030f, -0.864165897136879300f, 0.503041306280673450f, + -0.864262369986934950f, + 0.502875576800086880f, -0.864358811060534030f, 0.502709828830203100f, + -0.864455220354130250f, + 0.502544062377115800f, -0.864551597864179230f, 0.502378277446919870f, + -0.864647943587137480f, + 0.502212474045710900f, -0.864744257519462380f, 0.502046652179584660f, + -0.864840539657612980f, + 0.501880811854638400f, -0.864936789998049020f, 0.501714953076969230f, + -0.865033008537231750f, + 0.501549075852675390f, -0.865129195271623690f, 0.501383180187855880f, + -0.865225350197688090f, + 0.501217266088609950f, -0.865321473311889800f, 0.501051333561038040f, + -0.865417564610694410f, + 0.500885382611240940f, -0.865513624090568980f, 0.500719413245319880f, + -0.865609651747981880f, + 0.500553425469377640f, -0.865705647579402270f, 0.500387419289516580f, + -0.865801611581300760f, + 0.500221394711840680f, -0.865897543750148820f, 0.500055351742453860f, + -0.865993444082419520f, + 0.499889290387461380f, -0.866089312574586770f, 0.499723210652968710f, + -0.866185149223125730f, + 0.499557112545081890f, -0.866280954024512990f, 0.499390996069908220f, + -0.866376726975225830f, + 0.499224861233555030f, -0.866472468071743050f, 0.499058708042130930f, + -0.866568177310544360f, + 0.498892536501744750f, -0.866663854688111020f, 0.498726346618505960f, + -0.866759500200925290f, + 0.498560138398525200f, -0.866855113845470320f, 0.498393911847913150f, + -0.866950695618231020f, + 0.498227666972781870f, -0.867046245515692650f, 0.498061403779243520f, + -0.867141763534342360f, + 0.497895122273410930f, -0.867237249670668400f, 0.497728822461398100f, + -0.867332703921159690f, + 0.497562504349319090f, -0.867428126282306920f, 0.497396167943289340f, + -0.867523516750601460f, + 0.497229813249424340f, -0.867618875322536230f, 0.497063440273840310f, + -0.867714201994605140f, + 0.496897049022654640f, -0.867809496763303210f, 0.496730639501984710f, + -0.867904759625126920f, + 0.496564211717949340f, -0.867999990576573400f, 0.496397765676667160f, + -0.868095189614141670f, + 0.496231301384258310f, -0.868190356734331310f, 0.496064818846843060f, + -0.868285491933643240f, + 0.495898318070542240f, -0.868380595208579800f, 0.495731799061478020f, + -0.868475666555644120f, + 0.495565261825772490f, -0.868570705971340900f, 0.495398706369549080f, + -0.868665713452175580f, + 0.495232132698931350f, -0.868760688994655190f, 0.495065540820043610f, + -0.868855632595287750f, + 0.494898930739011310f, -0.868950544250582380f, 0.494732302461959820f, + -0.869045423957049530f, + 0.494565655995016010f, -0.869140271711200560f, 0.494398991344306760f, + -0.869235087509548250f, + 0.494232308515959730f, -0.869329871348606730f, 0.494065607516103730f, + -0.869424623224890780f, + 0.493898888350867430f, -0.869519343134916970f, 0.493732151026381070f, + -0.869614031075202300f, + 0.493565395548774880f, -0.869708687042265560f, 0.493398621924179830f, + -0.869803311032626650f, + 0.493231830158728070f, -0.869897903042806340f, 0.493065020258551650f, + -0.869992463069326870f, + 0.492898192229784090f, -0.870086991108711350f, 0.492731346078558840f, + -0.870181487157484560f, + 0.492564481811010650f, -0.870275951212171830f, 0.492397599433274550f, + -0.870370383269300160f, + 0.492230698951486080f, -0.870464783325397670f, 0.492063780371782060f, + -0.870559151376993250f, + 0.491896843700299240f, -0.870653487420617540f, 0.491729888943175820f, + -0.870747791452801790f, + 0.491562916106550060f, -0.870842063470078860f, 0.491395925196560830f, + -0.870936303468982760f, + 0.491228916219348330f, -0.871030511446048260f, 0.491061889181052590f, + -0.871124687397811900f, + 0.490894844087815140f, -0.871218831320810900f, 0.490727780945777570f, + -0.871312943211583920f, + 0.490560699761082080f, -0.871407023066670950f, 0.490393600539872130f, + -0.871501070882612530f, + 0.490226483288291100f, -0.871595086655951090f, 0.490059348012483910f, + -0.871689070383229740f, + 0.489892194718595300f, -0.871783022060993010f, 0.489725023412770970f, + -0.871876941685786890f, + 0.489557834101157550f, -0.871970829254157700f, 0.489390626789901920f, + -0.872064684762653970f, + 0.489223401485152030f, -0.872158508207824480f, 0.489056158193055980f, + -0.872252299586219860f, + 0.488888896919763230f, -0.872346058894391540f, 0.488721617671423250f, + -0.872439786128892280f, + 0.488554320454186230f, -0.872533481286276060f, 0.488387005274203590f, + -0.872627144363097960f, + 0.488219672137626740f, -0.872720775355914300f, 0.488052321050608310f, + -0.872814374261282390f, + 0.487884952019301210f, -0.872907941075760970f, 0.487717565049858860f, + -0.873001475795909920f, + 0.487550160148436050f, -0.873094978418290090f, 0.487382737321187310f, + -0.873188448939463790f, + 0.487215296574268820f, -0.873281887355994210f, 0.487047837913836550f, + -0.873375293664446000f, + 0.486880361346047400f, -0.873468667861384880f, 0.486712866877059340f, + -0.873562009943377740f, + 0.486545354513030270f, -0.873655319906992630f, 0.486377824260119500f, + -0.873748597748798870f, + 0.486210276124486530f, -0.873841843465366750f, 0.486042710112291390f, + -0.873935057053268130f, + 0.485875126229695420f, -0.874028238509075630f, 0.485707524482859750f, + -0.874121387829363330f, + 0.485539904877947020f, -0.874214505010706300f, 0.485372267421119770f, + -0.874307590049680950f, + 0.485204612118541880f, -0.874400642942864790f, 0.485036938976377450f, + -0.874493663686836450f, + 0.484869248000791120f, -0.874586652278176110f, 0.484701539197948730f, + -0.874679608713464510f, + 0.484533812574016120f, -0.874772532989284150f, 0.484366068135160480f, + -0.874865425102218210f, + 0.484198305887549140f, -0.874958285048851540f, 0.484030525837350010f, + -0.875051112825769970f, + 0.483862727990732320f, -0.875143908429560250f, 0.483694912353865080f, + -0.875236671856810870f, + 0.483527078932918740f, -0.875329403104110780f, 0.483359227734063980f, + -0.875422102168050830f, + 0.483191358763471910f, -0.875514769045222740f, 0.483023472027315050f, + -0.875607403732219240f, + 0.482855567531765670f, -0.875700006225634600f, 0.482687645282997510f, + -0.875792576522063880f, + 0.482519705287184520f, -0.875885114618103700f, 0.482351747550501030f, + -0.875977620510351660f, + 0.482183772079122830f, -0.876070094195406600f, 0.482015778879225530f, + -0.876162535669868460f, + 0.481847767956986080f, -0.876254944930338400f, 0.481679739318581490f, + -0.876347321973419020f, + 0.481511692970189920f, -0.876439666795713610f, 0.481343628917989870f, + -0.876531979393827100f, + 0.481175547168160360f, -0.876624259764365310f, 0.481007447726881640f, + -0.876716507903935400f, + 0.480839330600333900f, -0.876808723809145760f, 0.480671195794698690f, + -0.876900907476605650f, + 0.480503043316157670f, -0.876993058902925780f, 0.480334873170893070f, + -0.877085178084718310f, + 0.480166685365088440f, -0.877177265018595940f, 0.479998479904927220f, + -0.877269319701173170f, + 0.479830256796594250f, -0.877361342129065140f, 0.479662016046274340f, + -0.877453332298888560f, + 0.479493757660153060f, -0.877545290207261240f, 0.479325481644417130f, + -0.877637215850802120f, + 0.479157188005253310f, -0.877729109226131570f, 0.478988876748849550f, + -0.877820970329870500f, + 0.478820547881394050f, -0.877912799158641730f, 0.478652201409075550f, + -0.878004595709069080f, + 0.478483837338084080f, -0.878096359977777130f, 0.478315455674609480f, + -0.878188091961392250f, + 0.478147056424843120f, -0.878279791656541460f, 0.477978639594976110f, + -0.878371459059853590f, + 0.477810205191201040f, -0.878463094167957870f, 0.477641753219710590f, + -0.878554696977485340f, + 0.477473283686698060f, -0.878646267485068130f, 0.477304796598358010f, + -0.878737805687339280f, + 0.477136291960884750f, -0.878829311580933360f, 0.476967769780474230f, + -0.878920785162485840f, + 0.476799230063322250f, -0.879012226428633410f, 0.476630672815625380f, + -0.879103635376014330f, + 0.476462098043581310f, -0.879195012001267370f, 0.476293505753387750f, + -0.879286356301033250f, + 0.476124895951243630f, -0.879377668271953180f, 0.475956268643348220f, + -0.879468947910670100f, + 0.475787623835901120f, -0.879560195213827890f, 0.475618961535103410f, + -0.879651410178071470f, + 0.475450281747155870f, -0.879742592800047410f, 0.475281584478260800f, + -0.879833743076402940f, + 0.475112869734620470f, -0.879924861003786860f, 0.474944137522437860f, + -0.880015946578848960f, + 0.474775387847917230f, -0.880106999798240360f, 0.474606620717262560f, + -0.880198020658613190f, + 0.474437836136679340f, -0.880289009156620890f, 0.474269034112372920f, + -0.880379965288918260f, + 0.474100214650550020f, -0.880470889052160750f, 0.473931377757417560f, + -0.880561780443005590f, + 0.473762523439182850f, -0.880652639458111010f, 0.473593651702054640f, + -0.880743466094136230f, + 0.473424762552241530f, -0.880834260347742040f, 0.473255855995953380f, + -0.880925022215589880f, + 0.473086932039400220f, -0.881015751694342760f, 0.472917990688792760f, + -0.881106448780665130f, + 0.472749031950342900f, -0.881197113471221980f, 0.472580055830262250f, + -0.881287745762680100f, + 0.472411062334764100f, -0.881378345651706810f, 0.472242051470061650f, + -0.881468913134971330f, + 0.472073023242368660f, -0.881559448209143780f, 0.471903977657900320f, + -0.881649950870895260f, + 0.471734914722871430f, -0.881740421116898320f, 0.471565834443498480f, + -0.881830858943826620f, + 0.471396736825997810f, -0.881921264348354940f, 0.471227621876586400f, + -0.882011637327159590f, + 0.471058489601482610f, -0.882101977876917580f, 0.470889340006904520f, + -0.882192285994307430f, + 0.470720173099071710f, -0.882282561676008600f, 0.470550988884203490f, + -0.882372804918702290f, + 0.470381787368520710f, -0.882463015719070040f, 0.470212568558244280f, + -0.882553194073795400f, + 0.470043332459595620f, -0.882643339979562790f, 0.469874079078797470f, + -0.882733453433057540f, + 0.469704808422072460f, -0.882823534430966730f, 0.469535520495644510f, + -0.882913582969978020f, + 0.469366215305737630f, -0.883003599046780720f, 0.469196892858576630f, + -0.883093582658065370f, + 0.469027553160387240f, -0.883183533800523280f, 0.468858196217395330f, + -0.883273452470847430f, + 0.468688822035827960f, -0.883363338665731580f, 0.468519430621912420f, + -0.883453192381870920f, + 0.468350021981876530f, -0.883543013615961880f, 0.468180596121949400f, + -0.883632802364701760f, + 0.468011153048359830f, -0.883722558624789660f, 0.467841692767338220f, + -0.883812282392925090f, + 0.467672215285114710f, -0.883901973665809470f, 0.467502720607920920f, + -0.883991632440144890f, + 0.467333208741988530f, -0.884081258712634990f, 0.467163679693549770f, + -0.884170852479984500f, + 0.466994133468838110f, -0.884260413738899080f, 0.466824570074086950f, + -0.884349942486086120f, + 0.466654989515530970f, -0.884439438718253700f, 0.466485391799405010f, + -0.884528902432111350f, + 0.466315776931944480f, -0.884618333624369920f, 0.466146144919386000f, + -0.884707732291740930f, + 0.465976495767966130f, -0.884797098430937790f, 0.465806829483922770f, + -0.884886432038674560f, + 0.465637146073493770f, -0.884975733111666660f, 0.465467445542917800f, + -0.885065001646630930f, + 0.465297727898434650f, -0.885154237640285110f, 0.465127993146283950f, + -0.885243441089348270f, + 0.464958241292706740f, -0.885332611990540590f, 0.464788472343944160f, + -0.885421750340583570f, + 0.464618686306237820f, -0.885510856136199950f, 0.464448883185830770f, + -0.885599929374113360f, + 0.464279062988965760f, -0.885688970051048960f, 0.464109225721887010f, + -0.885777978163732940f, + 0.463939371390838460f, -0.885866953708892790f, 0.463769500002065680f, + -0.885955896683257030f, + 0.463599611561814120f, -0.886044807083555490f, 0.463429706076329880f, + -0.886133684906519340f, + 0.463259783551860260f, -0.886222530148880640f, 0.463089843994652470f, + -0.886311342807372890f, + 0.462919887410955130f, -0.886400122878730490f, 0.462749913807016850f, + -0.886488870359689600f, + 0.462579923189086810f, -0.886577585246987040f, 0.462409915563415540f, + -0.886666267537360890f, + 0.462239890936253280f, -0.886754917227550950f, 0.462069849313851810f, + -0.886843534314297300f, + 0.461899790702462840f, -0.886932118794342080f, 0.461729715108338770f, + -0.887020670664428360f, + 0.461559622537733190f, -0.887109189921300060f, 0.461389512996899450f, + -0.887197676561702900f, + 0.461219386492092430f, -0.887286130582383150f, 0.461049243029567010f, + -0.887374551980088740f, + 0.460879082615578690f, -0.887462940751568840f, 0.460708905256384190f, + -0.887551296893573370f, + 0.460538710958240010f, -0.887639620402853930f, 0.460368499727404070f, + -0.887727911276163020f, + 0.460198271570134270f, -0.887816169510254550f, 0.460028026492689700f, + -0.887904395101883240f, + 0.459857764501329650f, -0.887992588047805560f, 0.459687485602313870f, + -0.888080748344778900f, + 0.459517189801903590f, -0.888168875989561620f, 0.459346877106359570f, + -0.888256970978913870f, + 0.459176547521944150f, -0.888345033309596240f, 0.459006201054919680f, + -0.888433062978371320f, + 0.458835837711549120f, -0.888521059982002260f, 0.458665457498096670f, + -0.888609024317253750f, + 0.458495060420826220f, -0.888696955980891710f, 0.458324646486003300f, + -0.888784854969682850f, + 0.458154215699893230f, -0.888872721280395520f, 0.457983768068762180f, + -0.888960554909799310f, + 0.457813303598877290f, -0.889048355854664570f, 0.457642822296505770f, + -0.889136124111763240f, + 0.457472324167916110f, -0.889223859677868210f, 0.457301809219376800f, + -0.889311562549753850f, + 0.457131277457156980f, -0.889399232724195520f, 0.456960728887527030f, + -0.889486870197969790f, + 0.456790163516757220f, -0.889574474967854580f, 0.456619581351118960f, + -0.889662047030628790f, + 0.456448982396883860f, -0.889749586383072890f, 0.456278366660324670f, + -0.889837093021967900f, + 0.456107734147714220f, -0.889924566944096720f, 0.455937084865326030f, + -0.890012008146243260f, + 0.455766418819434750f, -0.890099416625192210f, 0.455595736016314920f, + -0.890186792377730240f, + 0.455425036462242420f, -0.890274135400644480f, 0.455254320163493210f, + -0.890361445690723730f, + 0.455083587126343840f, -0.890448723244757880f, 0.454912837357072050f, + -0.890535968059537830f, + 0.454742070861955450f, -0.890623180131855930f, 0.454571287647273000f, + -0.890710359458505520f, + 0.454400487719303750f, -0.890797506036281490f, 0.454229671084327320f, + -0.890884619861979530f, + 0.454058837748624540f, -0.890971700932396750f, 0.453887987718476050f, + -0.891058749244331590f, + 0.453717121000163930f, -0.891145764794583180f, 0.453546237599970260f, + -0.891232747579952520f, + 0.453375337524177750f, -0.891319697597241390f, 0.453204420779070300f, + -0.891406614843252900f, + 0.453033487370931580f, -0.891493499314791380f, 0.452862537306046810f, + -0.891580351008662290f, + 0.452691570590700860f, -0.891667169921672390f, 0.452520587231180100f, + -0.891753956050629460f, + 0.452349587233771000f, -0.891840709392342720f, 0.452178570604760410f, + -0.891927429943622510f, + 0.452007537350436530f, -0.892014117701280360f, 0.451836487477087430f, + -0.892100772662129170f, + 0.451665420991002540f, -0.892187394822982480f, 0.451494337898471210f, + -0.892273984180655730f, + 0.451323238205783520f, -0.892360540731965360f, 0.451152121919230710f, + -0.892447064473728680f, + 0.450980989045103810f, -0.892533555402764690f, 0.450809839589695340f, + -0.892620013515893040f, + 0.450638673559297760f, -0.892706438809935280f, 0.450467490960204110f, + -0.892792831281713610f, + 0.450296291798708730f, -0.892879190928051680f, 0.450125076081105750f, + -0.892965517745774260f, + 0.449953843813690580f, -0.893051811731707450f, 0.449782595002758860f, + -0.893138072882678210f, + 0.449611329654606600f, -0.893224301195515320f, 0.449440047775531260f, + -0.893310496667048090f, + 0.449268749371829920f, -0.893396659294107610f, 0.449097434449801100f, + -0.893482789073525850f, + 0.448926103015743260f, -0.893568886002136020f, 0.448754755075956020f, + -0.893654950076772430f, + 0.448583390636739300f, -0.893740981294271040f, 0.448412009704393430f, + -0.893826979651468620f, + 0.448240612285220000f, -0.893912945145203250f, 0.448069198385520340f, + -0.893998877772314240f, + 0.447897768011597310f, -0.894084777529641990f, 0.447726321169753750f, + -0.894170644414028270f, + 0.447554857866293010f, -0.894256478422316040f, 0.447383378107519710f, + -0.894342279551349480f, + 0.447211881899738260f, -0.894428047797973800f, 0.447040369249254500f, + -0.894513783159035620f, + 0.446868840162374330f, -0.894599485631382580f, 0.446697294645404090f, + -0.894685155211863980f, + 0.446525732704651400f, -0.894770791897329550f, 0.446354154346423840f, + -0.894856395684630930f, + 0.446182559577030120f, -0.894941966570620750f, 0.446010948402779110f, + -0.895027504552152630f, + 0.445839320829980350f, -0.895113009626081760f, 0.445667676864944350f, + -0.895198481789264200f, + 0.445496016513981740f, -0.895283921038557580f, 0.445324339783404240f, + -0.895369327370820310f, + 0.445152646679523590f, -0.895454700782912450f, 0.444980937208652780f, + -0.895540041271694840f, + 0.444809211377105000f, -0.895625348834030000f, 0.444637469191193790f, + -0.895710623466781320f, + 0.444465710657234110f, -0.895795865166813420f, 0.444293935781540580f, + -0.895881073930992370f, + 0.444122144570429260f, -0.895966249756185110f, 0.443950337030216250f, + -0.896051392639260040f, + 0.443778513167218220f, -0.896136502577086770f, 0.443606672987753080f, + -0.896221579566535920f, + 0.443434816498138430f, -0.896306623604479660f, 0.443262943704693380f, + -0.896391634687790820f, + 0.443091054613736990f, -0.896476612813344010f, 0.442919149231588980f, + -0.896561557978014960f, + 0.442747227564570130f, -0.896646470178680150f, 0.442575289619001170f, + -0.896731349412217880f, + 0.442403335401204130f, -0.896816195675507190f, 0.442231364917501090f, + -0.896901008965428680f, + 0.442059378174214760f, -0.896985789278863970f, 0.441887375177668960f, + -0.897070536612695870f, + 0.441715355934187310f, -0.897155250963808550f, 0.441543320450094920f, + -0.897239932329087050f, + 0.441371268731716620f, -0.897324580705418320f, 0.441199200785378660f, + -0.897409196089689720f, + 0.441027116617407340f, -0.897493778478790190f, 0.440855016234129430f, + -0.897578327869610230f, + 0.440682899641873020f, -0.897662844259040750f, 0.440510766846965880f, + -0.897747327643974690f, + 0.440338617855737300f, -0.897831778021305650f, 0.440166452674516480f, + -0.897916195387928550f, + 0.439994271309633260f, -0.898000579740739880f, 0.439822073767418610f, + -0.898084931076636780f, + 0.439649860054203420f, -0.898169249392518080f, 0.439477630176319860f, + -0.898253534685283570f, + 0.439305384140100060f, -0.898337786951834190f, 0.439133121951876930f, + -0.898422006189072530f, + 0.438960843617984430f, -0.898506192393901840f, 0.438788549144756290f, + -0.898590345563227030f, + 0.438616238538527710f, -0.898674465693953820f, 0.438443911805633860f, + -0.898758552782989440f, + 0.438271568952410480f, -0.898842606827242260f, 0.438099209985194580f, + -0.898926627823621870f, + 0.437926834910322860f, -0.899010615769039070f, 0.437754443734133470f, + -0.899094570660405770f, + 0.437582036462964340f, -0.899178492494635330f, 0.437409613103154850f, + -0.899262381268642000f, + 0.437237173661044200f, -0.899346236979341460f, 0.437064718142972370f, + -0.899430059623650860f, + 0.436892246555280470f, -0.899513849198487870f, 0.436719758904309310f, + -0.899597605700772180f, + 0.436547255196401250f, -0.899681329127423930f, 0.436374735437898510f, + -0.899765019475365020f, + 0.436202199635143950f, -0.899848676741518580f, 0.436029647794481670f, + -0.899932300922808400f, + 0.435857079922255470f, -0.900015892016160280f, 0.435684496024810520f, + -0.900099450018500340f, + 0.435511896108492170f, -0.900182974926756700f, 0.435339280179646070f, + -0.900266466737858480f, + 0.435166648244619370f, -0.900349925448735600f, 0.434994000309758710f, + -0.900433351056319830f, + 0.434821336381412350f, -0.900516743557543520f, 0.434648656465928430f, + -0.900600102949340790f, + 0.434475960569655710f, -0.900683429228646860f, 0.434303248698944100f, + -0.900766722392397860f, + 0.434130520860143310f, -0.900849982437531450f, 0.433957777059604480f, + -0.900933209360986200f, + 0.433785017303678520f, -0.901016403159702330f, 0.433612241598717640f, + -0.901099563830620950f, + 0.433439449951074200f, -0.901182691370684410f, 0.433266642367100940f, + -0.901265785776836580f, + 0.433093818853152010f, -0.901348847046022030f, 0.432920979415581220f, + -0.901431875175186970f, + 0.432748124060743760f, -0.901514870161278630f, 0.432575252794994810f, + -0.901597832001245660f, + 0.432402365624690140f, -0.901680760692037730f, 0.432229462556186770f, + -0.901763656230605610f, + 0.432056543595841450f, -0.901846518613901860f, 0.431883608750012300f, + -0.901929347838879350f, + 0.431710658025057370f, -0.902012143902493070f, 0.431537691427335500f, + -0.902094906801698900f, + 0.431364708963206440f, -0.902177636533453510f, 0.431191710639030000f, + -0.902260333094715540f, + 0.431018696461167080f, -0.902342996482444200f, 0.430845666435978820f, + -0.902425626693600270f, + 0.430672620569826860f, -0.902508223725145830f, 0.430499558869073930f, + -0.902590787574043870f, + 0.430326481340082610f, -0.902673318237258830f, 0.430153387989216930f, + -0.902755815711756120f, + 0.429980278822840570f, -0.902838279994502830f, 0.429807153847318770f, + -0.902920711082466630f, + 0.429634013069016500f, -0.903003108972617040f, 0.429460856494299490f, + -0.903085473661924600f, + 0.429287684129534720f, -0.903167805147360610f, 0.429114495981088690f, + -0.903250103425898400f, + 0.428941292055329550f, -0.903332368494511820f, 0.428768072358625240f, + -0.903414600350176290f, + 0.428594836897344400f, -0.903496798989868450f, 0.428421585677856760f, + -0.903578964410565950f, + 0.428248318706531910f, -0.903661096609247980f, 0.428075035989740780f, + -0.903743195582894620f, + 0.427901737533854240f, -0.903825261328487390f, 0.427728423345243860f, + -0.903907293843009050f, + 0.427555093430282200f, -0.903989293123443340f, 0.427381747795341770f, + -0.904071259166775440f, + 0.427208386446796370f, -0.904153191969991670f, 0.427035009391019790f, + -0.904235091530079750f, + 0.426861616634386490f, -0.904316957844028320f, 0.426688208183271970f, + -0.904398790908827350f, + 0.426514784044051520f, -0.904480590721468250f, 0.426341344223101880f, + -0.904562357278943190f, + 0.426167888726799620f, -0.904644090578246240f, 0.425994417561522450f, + -0.904725790616371930f, + 0.425820930733648300f, -0.904807457390316540f, 0.425647428249555590f, + -0.904889090897077470f, + 0.425473910115623910f, -0.904970691133653250f, 0.425300376338232590f, + -0.905052258097043590f, + 0.425126826923762410f, -0.905133791784249580f, 0.424953261878594060f, + -0.905215292192273480f, + 0.424779681209108810f, -0.905296759318118820f, 0.424606084921689220f, + -0.905378193158789980f, + 0.424432473022717420f, -0.905459593711293250f, 0.424258845518577010f, + -0.905540960972635480f, + 0.424085202415651670f, -0.905622294939825160f, 0.423911543720325580f, + -0.905703595609872010f, + 0.423737869438983950f, -0.905784862979786440f, 0.423564179578011960f, + -0.905866097046580940f, + 0.423390474143796100f, -0.905947297807268460f, 0.423216753142722780f, + -0.906028465258863490f, + 0.423043016581179100f, -0.906109599398381980f, 0.422869264465553170f, + -0.906190700222840540f, + 0.422695496802232950f, -0.906271767729257660f, 0.422521713597607870f, + -0.906352801914652280f, + 0.422347914858067000f, -0.906433802776045460f, 0.422174100590000820f, + -0.906514770310458800f, + 0.422000270799799790f, -0.906595704514915330f, 0.421826425493854910f, + -0.906676605386439460f, + 0.421652564678558380f, -0.906757472922056550f, 0.421478688360302220f, + -0.906838307118793540f, + 0.421304796545479700f, -0.906919107973678030f, 0.421130889240484140f, + -0.906999875483739610f, + 0.420956966451709440f, -0.907080609646008450f, 0.420783028185550630f, + -0.907161310457516250f, + 0.420609074448402510f, -0.907241977915295930f, 0.420435105246661220f, + -0.907322612016381310f, + 0.420261120586723050f, -0.907403212757808000f, 0.420087120474984590f, + -0.907483780136612570f, + 0.419913104917843730f, -0.907564314149832520f, 0.419739073921698180f, + -0.907644814794507090f, + 0.419565027492946940f, -0.907725282067676330f, 0.419390965637989050f, + -0.907805715966381820f, + 0.419216888363223960f, -0.907886116487666150f, 0.419042795675052480f, + -0.907966483628573240f, + 0.418868687579875110f, -0.908046817386148340f, 0.418694564084093610f, + -0.908127117757437600f, + 0.418520425194109700f, -0.908207384739488700f, 0.418346270916326310f, + -0.908287618329350450f, + 0.418172101257146430f, -0.908367818524072780f, 0.417997916222973550f, + -0.908447985320707250f, + 0.417823715820212380f, -0.908528118716306120f, 0.417649500055267410f, + -0.908608218707923190f, + 0.417475268934544340f, -0.908688285292613360f, 0.417301022464449060f, + -0.908768318467432780f, + 0.417126760651387870f, -0.908848318229439120f, 0.416952483501768280f, + -0.908928284575690640f, + 0.416778191021997590f, -0.909008217503247450f, 0.416603883218484410f, + -0.909088117009170580f, + 0.416429560097637320f, -0.909167983090522270f, 0.416255221665865480f, + -0.909247815744366310f, + 0.416080867929579320f, -0.909327614967767260f, 0.415906498895188770f, + -0.909407380757791260f, + 0.415732114569105420f, -0.909487113111505430f, 0.415557714957740580f, + -0.909566812025978220f, + 0.415383300067506290f, -0.909646477498279540f, 0.415208869904815650f, + -0.909726109525480160f, + 0.415034424476081630f, -0.909805708104652220f, 0.414859963787718390f, + -0.909885273232869160f, + 0.414685487846140010f, -0.909964804907205660f, 0.414510996657761810f, + -0.910044303124737390f, + 0.414336490228999210f, -0.910123767882541570f, 0.414161968566268080f, + -0.910203199177696540f, + 0.413987431675985510f, -0.910282597007281760f, 0.413812879564568300f, + -0.910361961368377990f, + 0.413638312238434560f, -0.910441292258067140f, 0.413463729704002580f, + -0.910520589673432630f, + 0.413289131967690960f, -0.910599853611558930f, 0.413114519035919560f, + -0.910679084069531570f, + 0.412939890915108020f, -0.910758281044437570f, 0.412765247611677320f, + -0.910837444533365010f, + 0.412590589132048380f, -0.910916574533403240f, 0.412415915482642730f, + -0.910995671041643140f, + 0.412241226669883000f, -0.911074734055176250f, 0.412066522700191560f, + -0.911153763571095900f, + 0.411891803579992220f, -0.911232759586496190f, 0.411717069315708670f, + -0.911311722098472670f, + 0.411542319913765280f, -0.911390651104122320f, 0.411367555380587340f, + -0.911469546600543020f, + 0.411192775722600160f, -0.911548408584833990f, 0.411017980946230270f, + -0.911627237054095650f, + 0.410843171057903910f, -0.911706032005429880f, 0.410668346064048780f, + -0.911784793435939430f, + 0.410493505971092520f, -0.911863521342728520f, 0.410318650785463260f, + -0.911942215722902570f, + 0.410143780513590350f, -0.912020876573568230f, 0.409968895161902820f, + -0.912099503891833470f, + 0.409793994736831200f, -0.912178097674807060f, 0.409619079244805840f, + -0.912256657919599650f, + 0.409444148692257590f, -0.912335184623322750f, 0.409269203085618700f, + -0.912413677783089020f, + 0.409094242431320920f, -0.912492137396012650f, 0.408919266735797480f, + -0.912570563459208730f, + 0.408744276005481520f, -0.912648955969793900f, 0.408569270246806780f, + -0.912727314924885900f, + 0.408394249466208110f, -0.912805640321603500f, 0.408219213670120100f, + -0.912883932157067200f, + 0.408044162864978740f, -0.912962190428398100f, 0.407869097057219960f, + -0.913040415132719160f, + 0.407694016253280170f, -0.913118606267154130f, 0.407518920459597030f, + -0.913196763828828200f, + 0.407343809682607970f, -0.913274887814867760f, 0.407168683928751610f, + -0.913352978222400250f, + 0.406993543204466460f, -0.913431035048554720f, 0.406818387516192370f, + -0.913509058290461140f, + 0.406643216870369140f, -0.913587047945250810f, 0.406468031273437000f, + -0.913665004010056350f, + 0.406292830731837470f, -0.913742926482011390f, 0.406117615252011790f, + -0.913820815358251100f, + 0.405942384840402570f, -0.913898670635911680f, 0.405767139503452220f, + -0.913976492312130520f, + 0.405591879247603870f, -0.914054280384046460f, 0.405416604079301750f, + -0.914132034848799460f, + 0.405241314004989860f, -0.914209755703530690f, 0.405066009031113390f, + -0.914287442945382440f, + 0.404890689164117750f, -0.914365096571498450f, 0.404715354410448650f, + -0.914442716579023870f, + 0.404540004776553110f, -0.914520302965104450f, 0.404364640268877810f, + -0.914597855726887790f, + 0.404189260893870750f, -0.914675374861522390f, 0.404013866657980060f, + -0.914752860366158100f, + 0.403838457567654130f, -0.914830312237946090f, 0.403663033629342750f, + -0.914907730474038620f, + 0.403487594849495310f, -0.914985115071589310f, 0.403312141234562660f, + -0.915062466027752760f, + 0.403136672790995240f, -0.915139783339685260f, 0.402961189525244960f, + -0.915217067004543750f, + 0.402785691443763640f, -0.915294317019487050f, 0.402610178553003680f, + -0.915371533381674760f, + 0.402434650859418540f, -0.915448716088267830f, 0.402259108369461440f, + -0.915525865136428530f, + 0.402083551089587040f, -0.915602980523320230f, 0.401907979026249860f, + -0.915680062246107650f, + 0.401732392185905010f, -0.915757110301956720f, 0.401556790575008650f, + -0.915834124688034710f, + 0.401381174200016790f, -0.915911105401509880f, 0.401205543067386760f, + -0.915988052439551840f, + 0.401029897183575790f, -0.916064965799331610f, 0.400854236555041650f, + -0.916141845478021350f, + 0.400678561188243350f, -0.916218691472794110f, 0.400502871089639500f, + -0.916295503780824800f, + 0.400327166265690150f, -0.916372282399289140f, 0.400151446722855300f, + -0.916449027325364040f, + 0.399975712467595390f, -0.916525738556228100f, 0.399799963506372090f, + -0.916602416089060680f, + 0.399624199845646790f, -0.916679059921042700f, 0.399448421491882260f, + -0.916755670049355990f, + 0.399272628451540930f, -0.916832246471183890f, 0.399096820731086600f, + -0.916908789183710990f, + 0.398920998336983020f, -0.916985298184122890f, 0.398745161275694480f, + -0.917061773469606820f, + 0.398569309553686360f, -0.917138215037350710f, 0.398393443177423920f, + -0.917214622884544250f, + 0.398217562153373620f, -0.917290997008377910f, 0.398041666488001930f, + -0.917367337406043810f, + 0.397865756187775750f, -0.917443644074735220f, 0.397689831259163240f, + -0.917519917011646260f, + 0.397513891708632330f, -0.917596156213972950f, 0.397337937542652120f, + -0.917672361678911750f, + 0.397161968767691720f, -0.917748533403661250f, 0.396985985390220900f, + -0.917824671385420570f, + 0.396809987416710420f, -0.917900775621390390f, 0.396633974853630830f, + -0.917976846108772730f, + 0.396457947707453960f, -0.918052882844770380f, 0.396281905984651680f, + -0.918128885826587910f, + 0.396105849691696320f, -0.918204855051430900f, 0.395929778835061360f, + -0.918280790516506130f, + 0.395753693421220080f, -0.918356692219021720f, 0.395577593456646950f, + -0.918432560156186790f, + 0.395401478947816300f, -0.918508394325212250f, 0.395225349901203730f, + -0.918584194723309540f, + 0.395049206323284880f, -0.918659961347691900f, 0.394873048220535760f, + -0.918735694195573550f, + 0.394696875599433670f, -0.918811393264169940f, 0.394520688466455550f, + -0.918887058550697970f, + 0.394344486828079650f, -0.918962690052375630f, 0.394168270690784250f, + -0.919038287766421940f, + 0.393992040061048100f, -0.919113851690057770f, 0.393815794945351130f, + -0.919189381820504470f, + 0.393639535350172880f, -0.919264878154985250f, 0.393463261281994380f, + -0.919340340690724230f, + 0.393286972747296570f, -0.919415769424946960f, 0.393110669752560760f, + -0.919491164354880100f, + 0.392934352304269600f, -0.919566525477751530f, 0.392758020408905280f, + -0.919641852790790470f, + 0.392581674072951530f, -0.919717146291227360f, 0.392405313302891860f, + -0.919792405976293750f, + 0.392228938105210370f, -0.919867631843222950f, 0.392052548486392200f, + -0.919942823889248640f, + 0.391876144452922350f, -0.920017982111606570f, 0.391699726011287050f, + -0.920093106507533070f, + 0.391523293167972350f, -0.920168197074266450f, 0.391346845929465610f, + -0.920243253809045370f, + 0.391170384302253980f, -0.920318276709110480f, 0.390993908292825380f, + -0.920393265771703550f, + 0.390817417907668610f, -0.920468220994067110f, 0.390640913153272370f, + -0.920543142373445480f, + 0.390464394036126650f, -0.920618029907083860f, 0.390287860562721360f, + -0.920692883592229010f, + 0.390111312739546910f, -0.920767703426128790f, 0.389934750573094790f, + -0.920842489406032080f, + 0.389758174069856410f, -0.920917241529189520f, 0.389581583236324360f, + -0.920991959792852310f, + 0.389404978078991100f, -0.921066644194273530f, 0.389228358604349730f, + -0.921141294730707270f, + 0.389051724818894500f, -0.921215911399408730f, 0.388875076729119250f, + -0.921290494197634540f, + 0.388698414341519250f, -0.921365043122642340f, 0.388521737662589740f, + -0.921439558171691320f, + 0.388345046698826300f, -0.921514039342041900f, 0.388168341456725850f, + -0.921588486630955380f, + 0.387991621942784910f, -0.921662900035694730f, 0.387814888163501290f, + -0.921737279553523800f, + 0.387638140125372680f, -0.921811625181708120f, 0.387461377834897920f, + -0.921885936917513970f, + 0.387284601298575890f, -0.921960214758209110f, 0.387107810522905990f, + -0.922034458701062820f, + 0.386931005514388690f, -0.922108668743345070f, 0.386754186279524130f, + -0.922182844882327600f, + 0.386577352824813980f, -0.922256987115283030f, 0.386400505156759610f, + -0.922331095439485330f, + 0.386223643281862980f, -0.922405169852209880f, 0.386046767206627280f, + -0.922479210350733100f, + 0.385869876937555310f, -0.922553216932332830f, 0.385692972481151200f, + -0.922627189594287800f, + 0.385516053843919020f, -0.922701128333878520f, 0.385339121032363340f, + -0.922775033148386380f, + 0.385162174052989970f, -0.922848904035094120f, 0.384985212912304200f, + -0.922922740991285680f, + 0.384808237616812930f, -0.922996544014246250f, 0.384631248173022740f, + -0.923070313101262420f, + 0.384454244587440870f, -0.923144048249621820f, 0.384277226866575620f, + -0.923217749456613500f, + 0.384100195016935040f, -0.923291416719527640f, 0.383923149045028500f, + -0.923365050035655610f, + 0.383746088957365010f, -0.923438649402290370f, 0.383569014760454960f, + -0.923512214816725520f, + 0.383391926460808770f, -0.923585746276256560f, 0.383214824064937180f, + -0.923659243778179980f, + 0.383037707579352130f, -0.923732707319793180f, 0.382860577010565360f, + -0.923806136898395410f, + 0.382683432365089840f, -0.923879532511286740f, 0.382506273649438400f, + -0.923952894155768640f, + 0.382329100870124510f, -0.924026221829143850f, 0.382151914033662720f, + -0.924099515528716280f, + 0.381974713146567220f, -0.924172775251791200f, 0.381797498215353690f, + -0.924246000995674890f, + 0.381620269246537520f, -0.924319192757675160f, 0.381443026246634730f, + -0.924392350535101050f, + 0.381265769222162490f, -0.924465474325262600f, 0.381088498179637520f, + -0.924538564125471420f, + 0.380911213125578130f, -0.924611619933039970f, 0.380733914066502090f, + -0.924684641745282530f, + 0.380556601008928570f, -0.924757629559513910f, 0.380379273959376710f, + -0.924830583373050800f, + 0.380201932924366050f, -0.924903503183210910f, 0.380024577910417380f, + -0.924976388987313050f, + 0.379847208924051110f, -0.925049240782677580f, 0.379669825971789000f, + -0.925122058566625770f, + 0.379492429060152740f, -0.925194842336480420f, 0.379315018195664430f, + -0.925267592089565550f, + 0.379137593384847430f, -0.925340307823206200f, 0.378960154634224720f, + -0.925412989534729060f, + 0.378782701950320600f, -0.925485637221461490f, 0.378605235339659290f, + -0.925558250880732620f, + 0.378427754808765620f, -0.925630830509872720f, 0.378250260364165310f, + -0.925703376106213120f, + 0.378072752012383990f, -0.925775887667086740f, 0.377895229759948550f, + -0.925848365189827270f, + 0.377717693613385810f, -0.925920808671769960f, 0.377540143579222940f, + -0.925993218110251480f, + 0.377362579663988450f, -0.926065593502609310f, 0.377185001874210450f, + -0.926137934846182560f, + 0.377007410216418310f, -0.926210242138311270f, 0.376829804697141220f, + -0.926282515376337210f, + 0.376652185322909620f, -0.926354754557602860f, 0.376474552100253880f, + -0.926426959679452100f, + 0.376296905035704790f, -0.926499130739230510f, 0.376119244135794390f, + -0.926571267734284220f, + 0.375941569407054420f, -0.926643370661961230f, 0.375763880856017750f, + -0.926715439519610330f, + 0.375586178489217330f, -0.926787474304581750f, 0.375408462313186590f, + -0.926859475014227160f, + 0.375230732334460030f, -0.926931441645899130f, 0.375052988559571860f, + -0.927003374196951670f, + 0.374875230995057600f, -0.927075272664740100f, 0.374697459647452770f, + -0.927147137046620880f, + 0.374519674523293210f, -0.927218967339951790f, 0.374341875629116030f, + -0.927290763542091720f, + 0.374164062971457990f, -0.927362525650401110f, 0.373986236556857090f, + -0.927434253662241300f, + 0.373808396391851370f, -0.927505947574975180f, 0.373630542482979280f, + -0.927577607385966730f, + 0.373452674836780410f, -0.927649233092581180f, 0.373274793459794030f, + -0.927720824692185200f, + 0.373096898358560690f, -0.927792382182146320f, 0.372918989539620770f, + -0.927863905559833780f, + 0.372741067009515810f, -0.927935394822617890f, 0.372563130774787370f, + -0.928006849967869970f, + 0.372385180841977360f, -0.928078270992963140f, 0.372207217217628950f, + -0.928149657895271150f, + 0.372029239908284960f, -0.928221010672169440f, 0.371851248920489540f, + -0.928292329321034560f, + 0.371673244260786630f, -0.928363613839244370f, 0.371495225935720760f, + -0.928434864224177980f, + 0.371317193951837600f, -0.928506080473215480f, 0.371139148315682510f, + -0.928577262583738850f, + 0.370961089033802040f, -0.928648410553130520f, 0.370783016112742720f, + -0.928719524378774700f, + 0.370604929559051670f, -0.928790604058057020f, 0.370426829379276900f, + -0.928861649588363700f, + 0.370248715579966360f, -0.928932660967082820f, 0.370070588167669130f, + -0.929003638191603360f, + 0.369892447148934270f, -0.929074581259315750f, 0.369714292530311240f, + -0.929145490167611720f, + 0.369536124318350760f, -0.929216364913883930f, 0.369357942519603190f, + -0.929287205495526790f, + 0.369179747140620070f, -0.929358011909935500f, 0.369001538187952780f, + -0.929428784154506800f, + 0.368823315668153960f, -0.929499522226638560f, 0.368645079587776150f, + -0.929570226123729860f, + 0.368466829953372320f, -0.929640895843181330f, 0.368288566771496680f, + -0.929711531382394370f, + 0.368110290048703050f, -0.929782132738772190f, 0.367931999791546500f, + -0.929852699909718750f, + 0.367753696006582090f, -0.929923232892639560f, 0.367575378700365330f, + -0.929993731684941480f, + 0.367397047879452820f, -0.930064196284032360f, 0.367218703550400930f, + -0.930134626687321390f, + 0.367040345719767240f, -0.930205022892219070f, 0.366861974394109220f, + -0.930275384896137040f, + 0.366683589579984930f, -0.930345712696488470f, 0.366505191283953480f, + -0.930416006290687550f, + 0.366326779512573590f, -0.930486265676149780f, 0.366148354272405390f, + -0.930556490850291800f, + 0.365969915570008910f, -0.930626681810531650f, 0.365791463411944570f, + -0.930696838554288860f, + 0.365612997804773960f, -0.930766961078983710f, 0.365434518755058390f, + -0.930837049382038150f, + 0.365256026269360380f, -0.930907103460875020f, 0.365077520354242180f, + -0.930977123312918930f, + 0.364899001016267380f, -0.931047108935595170f, 0.364720468261999390f, + -0.931117060326330790f, + 0.364541922098002180f, -0.931186977482553750f, 0.364363362530840730f, + -0.931256860401693420f, + 0.364184789567079840f, -0.931326709081180430f, 0.364006203213285530f, + -0.931396523518446600f, + 0.363827603476023610f, -0.931466303710925090f, 0.363648990361860550f, + -0.931536049656050300f, + 0.363470363877363870f, -0.931605761351257830f, 0.363291724029100700f, + -0.931675438793984620f, + 0.363113070823639530f, -0.931745081981668720f, 0.362934404267548750f, + -0.931814690911749620f, + 0.362755724367397230f, -0.931884265581668150f, 0.362577031129754870f, + -0.931953805988865900f, + 0.362398324561191310f, -0.932023312130786490f, 0.362219604668277570f, + -0.932092784004874050f, + 0.362040871457584350f, -0.932162221608574320f, 0.361862124935682980f, + -0.932231624939334540f, + 0.361683365109145950f, -0.932300993994602640f, 0.361504591984545260f, + -0.932370328771828460f, + 0.361325805568454340f, -0.932439629268462360f, 0.361147005867446190f, + -0.932508895481956700f, + 0.360968192888095290f, -0.932578127409764420f, 0.360789366636975690f, + -0.932647325049340340f, + 0.360610527120662270f, -0.932716488398140250f, 0.360431674345730810f, + -0.932785617453620990f, + 0.360252808318756830f, -0.932854712213241230f, 0.360073929046317080f, + -0.932923772674460140f, + 0.359895036534988280f, -0.932992798834738850f, 0.359716130791347570f, + -0.933061790691539380f, + 0.359537211821973180f, -0.933130748242325110f, 0.359358279633443080f, + -0.933199671484560730f, + 0.359179334232336560f, -0.933268560415712050f, 0.359000375625232630f, + -0.933337415033246080f, + 0.358821403818710920f, -0.933406235334631520f, 0.358642418819352100f, + -0.933475021317337950f, + 0.358463420633736540f, -0.933543772978836170f, 0.358284409268445900f, + -0.933612490316598540f, + 0.358105384730061760f, -0.933681173328098300f, 0.357926347025166070f, + -0.933749822010810580f, + 0.357747296160342010f, -0.933818436362210960f, 0.357568232142172260f, + -0.933887016379776890f, + 0.357389154977241000f, -0.933955562060986730f, 0.357210064672131900f, + -0.934024073403320500f, + 0.357030961233430030f, -0.934092550404258870f, 0.356851844667720410f, + -0.934160993061284420f, + 0.356672714981588260f, -0.934229401371880820f, 0.356493572181620200f, + -0.934297775333532530f, + 0.356314416274402360f, -0.934366114943725900f, 0.356135247266522180f, + -0.934434420199948050f, + 0.355956065164567010f, -0.934502691099687870f, 0.355776869975124640f, + -0.934570927640435030f, + 0.355597661704783960f, -0.934639129819680780f, 0.355418440360133590f, + -0.934707297634917440f, + 0.355239205947763370f, -0.934775431083638700f, 0.355059958474263030f, + -0.934843530163339430f, + 0.354880697946222790f, -0.934911594871516090f, 0.354701424370233940f, + -0.934979625205665800f, + 0.354522137752887430f, -0.935047621163287430f, 0.354342838100775600f, + -0.935115582741880890f, + 0.354163525420490510f, -0.935183509938947500f, 0.353984199718624830f, + -0.935251402751989810f, + 0.353804861001772160f, -0.935319261178511500f, 0.353625509276525970f, + -0.935387085216017770f, + 0.353446144549480870f, -0.935454874862014620f, 0.353266766827231180f, + -0.935522630114009930f, + 0.353087376116372530f, -0.935590350969512370f, 0.352907972423500360f, + -0.935658037426032040f, + 0.352728555755210730f, -0.935725689481080370f, 0.352549126118100580f, + -0.935793307132169900f, + 0.352369683518766630f, -0.935860890376814640f, 0.352190227963806890f, + -0.935928439212529660f, + 0.352010759459819240f, -0.935995953636831300f, 0.351831278013402030f, + -0.936063433647237540f, + 0.351651783631154680f, -0.936130879241266920f, 0.351472276319676260f, + -0.936198290416440090f, + 0.351292756085567150f, -0.936265667170278260f, 0.351113222935427630f, + -0.936333009500304180f, + 0.350933676875858360f, -0.936400317404042060f, 0.350754117913461170f, + -0.936467590879016880f, + 0.350574546054837570f, -0.936534829922755500f, 0.350394961306590200f, + -0.936602034532785570f, + 0.350215363675321740f, -0.936669204706636060f, 0.350035753167635300f, + -0.936736340441837620f, + 0.349856129790135030f, -0.936803441735921560f, 0.349676493549424760f, + -0.936870508586420960f, + 0.349496844452109600f, -0.936937540990869900f, 0.349317182504794320f, + -0.937004538946803690f, + 0.349137507714085030f, -0.937071502451759190f, 0.348957820086587600f, + -0.937138431503274140f, + 0.348778119628908420f, -0.937205326098887960f, 0.348598406347655040f, + -0.937272186236140950f, + 0.348418680249434510f, -0.937339011912574960f, 0.348238941340855310f, + -0.937405803125732850f, + 0.348059189628525780f, -0.937472559873159140f, 0.347879425119054510f, + -0.937539282152399230f, + 0.347699647819051490f, -0.937605969960999990f, 0.347519857735126110f, + -0.937672623296509470f, + 0.347340054873889190f, -0.937739242156476970f, 0.347160239241951330f, + -0.937805826538453010f, + 0.346980410845923680f, -0.937872376439989890f, 0.346800569692418400f, + -0.937938891858640210f, + 0.346620715788047320f, -0.938005372791958840f, 0.346440849139423580f, + -0.938071819237501160f, + 0.346260969753160170f, -0.938138231192824360f, 0.346081077635870480f, + -0.938204608655486490f, + 0.345901172794169100f, -0.938270951623047080f, 0.345721255234670120f, + -0.938337260093066950f, + 0.345541324963989150f, -0.938403534063108060f, 0.345361381988741170f, + -0.938469773530733800f, + 0.345181426315542610f, -0.938535978493508560f, 0.345001457951009780f, + -0.938602148948998290f, + 0.344821476901759290f, -0.938668284894770170f, 0.344641483174409070f, + -0.938734386328392460f, + 0.344461476775576480f, -0.938800453247434770f, 0.344281457711880230f, + -0.938866485649468060f, + 0.344101425989938980f, -0.938932483532064490f, 0.343921381616371700f, + -0.938998446892797540f, + 0.343741324597798600f, -0.939064375729241950f, 0.343561254940839330f, + -0.939130270038973650f, + 0.343381172652115100f, -0.939196129819569900f, 0.343201077738246710f, + -0.939261955068609100f, + 0.343020970205855540f, -0.939327745783671400f, 0.342840850061564060f, + -0.939393501962337510f, + 0.342660717311994380f, -0.939459223602189920f, 0.342480571963769850f, + -0.939524910700812120f, + 0.342300414023513690f, -0.939590563255789160f, 0.342120243497849590f, + -0.939656181264707070f, + 0.341940060393402300f, -0.939721764725153340f, 0.341759864716796310f, + -0.939787313634716570f, + 0.341579656474657210f, -0.939852827990986680f, 0.341399435673610360f, + -0.939918307791555050f, + 0.341219202320282410f, -0.939983753034013940f, 0.341038956421299830f, + -0.940049163715957370f, + 0.340858697983289440f, -0.940114539834980280f, 0.340678427012879310f, + -0.940179881388678810f, + 0.340498143516697100f, -0.940245188374650880f, 0.340317847501371730f, + -0.940310460790495070f, + 0.340137538973531880f, -0.940375698633811540f, 0.339957217939806880f, + -0.940440901902201750f, + 0.339776884406826960f, -0.940506070593268300f, 0.339596538381222060f, + -0.940571204704615190f, + 0.339416179869623410f, -0.940636304233847590f, 0.339235808878662120f, + -0.940701369178571940f, + 0.339055425414969640f, -0.940766399536396070f, 0.338875029485178560f, + -0.940831395304928870f, + 0.338694621095921190f, -0.940896356481780830f, 0.338514200253831000f, + -0.940961283064563280f, + 0.338333766965541290f, -0.941026175050889260f, 0.338153321237685990f, + -0.941091032438372780f, + 0.337972863076899830f, -0.941155855224629190f, 0.337792392489817460f, + -0.941220643407275180f, + 0.337611909483074680f, -0.941285396983928660f, 0.337431414063306790f, + -0.941350115952208970f, + 0.337250906237150650f, -0.941414800309736230f, 0.337070386011242730f, + -0.941479450054132580f, + 0.336889853392220050f, -0.941544065183020810f, 0.336709308386720700f, + -0.941608645694025140f, + 0.336528751001382350f, -0.941673191584771360f, 0.336348181242844100f, + -0.941737702852886160f, + 0.336167599117744690f, -0.941802179495997650f, 0.335987004632723350f, + -0.941866621511735280f, + 0.335806397794420560f, -0.941931028897729510f, 0.335625778609476230f, + -0.941995401651612550f, + 0.335445147084531660f, -0.942059739771017310f, 0.335264503226227970f, + -0.942124043253578460f, + 0.335083847041206580f, -0.942188312096931770f, 0.334903178536110290f, + -0.942252546298714020f, + 0.334722497717581220f, -0.942316745856563780f, 0.334541804592262960f, + -0.942380910768120470f, + 0.334361099166798900f, -0.942445041031024890f, 0.334180381447832740f, + -0.942509136642919240f, + 0.333999651442009490f, -0.942573197601446870f, 0.333818909155973620f, + -0.942637223904252530f, + 0.333638154596370920f, -0.942701215548981900f, 0.333457387769846790f, + -0.942765172533282510f, + 0.333276608683047980f, -0.942829094854802710f, 0.333095817342620890f, + -0.942892982511192130f, + 0.332915013755212650f, -0.942956835500102120f, 0.332734197927471160f, + -0.943020653819184650f, + 0.332553369866044220f, -0.943084437466093490f, 0.332372529577580680f, + -0.943148186438483420f, + 0.332191677068729320f, -0.943211900734010620f, 0.332010812346139380f, + -0.943275580350332540f, + 0.331829935416461220f, -0.943339225285107720f, 0.331649046286344620f, + -0.943402835535996240f, + 0.331468144962440920f, -0.943466411100659320f, 0.331287231451400990f, + -0.943529951976759370f, + 0.331106305759876430f, -0.943593458161960390f, 0.330925367894519650f, + -0.943656929653927110f, + 0.330744417861982890f, -0.943720366450326200f, 0.330563455668919590f, + -0.943783768548825060f, + 0.330382481321982950f, -0.943847135947092690f, 0.330201494827826620f, + -0.943910468642799150f, + 0.330020496193105530f, -0.943973766633615980f, 0.329839485424473940f, + -0.944037029917215830f, + 0.329658462528587550f, -0.944100258491272660f, 0.329477427512101680f, + -0.944163452353461770f, + 0.329296380381672800f, -0.944226611501459810f, 0.329115321143957360f, + -0.944289735932944410f, + 0.328934249805612200f, -0.944352825645594750f, 0.328753166373295100f, + -0.944415880637091250f, + 0.328572070853663690f, -0.944478900905115550f, 0.328390963253376630f, + -0.944541886447350380f, + 0.328209843579092660f, -0.944604837261480260f, 0.328028711837470730f, + -0.944667753345190490f, + 0.327847568035170960f, -0.944730634696167800f, 0.327666412178853060f, + -0.944793481312100280f, + 0.327485244275178060f, -0.944856293190677210f, 0.327304064330806830f, + -0.944919070329589220f, + 0.327122872352400510f, -0.944981812726528150f, 0.326941668346621530f, + -0.945044520379187070f, + 0.326760452320131790f, -0.945107193285260610f, 0.326579224279594460f, + -0.945169831442444150f, + 0.326397984231672660f, -0.945232434848434890f, 0.326216732183029770f, + -0.945295003500931100f, + 0.326035468140330350f, -0.945357537397632290f, 0.325854192110238580f, + -0.945420036536239070f, + 0.325672904099419900f, -0.945482500914453740f, 0.325491604114539260f, + -0.945544930529979680f, + 0.325310292162262980f, -0.945607325380521280f, 0.325128968249257190f, + -0.945669685463784710f, + 0.324947632382188430f, -0.945732010777477150f, 0.324766284567724330f, + -0.945794301319306860f, + 0.324584924812532150f, -0.945856557086983910f, 0.324403553123280290f, + -0.945918778078219110f, + 0.324222169506637130f, -0.945980964290724760f, 0.324040773969271450f, + -0.946043115722214560f, + 0.323859366517852960f, -0.946105232370403340f, 0.323677947159051180f, + -0.946167314233007370f, + 0.323496515899536760f, -0.946229361307743820f, 0.323315072745980150f, + -0.946291373592331510f, + 0.323133617705052330f, -0.946353351084490590f, 0.322952150783425370f, + -0.946415293781942110f, + 0.322770671987770710f, -0.946477201682408680f, 0.322589181324761390f, + -0.946539074783614100f, + 0.322407678801070020f, -0.946600913083283530f, 0.322226164423369650f, + -0.946662716579143360f, + 0.322044638198334620f, -0.946724485268921170f, 0.321863100132638580f, + -0.946786219150346000f, + 0.321681550232956640f, -0.946847918221148000f, 0.321499988505963450f, + -0.946909582479058760f, + 0.321318414958334910f, -0.946971211921810880f, 0.321136829596746780f, + -0.947032806547138620f, + 0.320955232427875210f, -0.947094366352777220f, 0.320773623458397440f, + -0.947155891336463270f, + 0.320592002694990330f, -0.947217381495934820f, 0.320410370144331880f, + -0.947278836828930880f, + 0.320228725813100020f, -0.947340257333191940f, 0.320047069707973140f, + -0.947401643006459900f, + 0.319865401835630610f, -0.947462993846477700f, 0.319683722202751370f, + -0.947524309850989570f, + 0.319502030816015750f, -0.947585591017741090f, 0.319320327682103720f, + -0.947646837344479190f, + 0.319138612807695900f, -0.947708048828952100f, 0.318956886199473770f, + -0.947769225468909180f, + 0.318775147864118480f, -0.947830367262101010f, 0.318593397808312470f, + -0.947891474206279730f, + 0.318411636038737960f, -0.947952546299198560f, 0.318229862562077580f, + -0.948013583538612200f, + 0.318048077385015060f, -0.948074585922276230f, 0.317866280514233660f, + -0.948135553447947980f, + 0.317684471956418020f, -0.948196486113385580f, 0.317502651718252260f, + -0.948257383916349060f, + 0.317320819806421790f, -0.948318246854599090f, 0.317138976227611890f, + -0.948379074925898120f, + 0.316957120988508150f, -0.948439868128009620f, 0.316775254095797380f, + -0.948500626458698260f, + 0.316593375556165850f, -0.948561349915730270f, 0.316411485376301090f, + -0.948622038496872990f, + 0.316229583562890490f, -0.948682692199895090f, 0.316047670122621860f, + -0.948743311022566480f, + 0.315865745062184070f, -0.948803894962658380f, 0.315683808388265600f, + -0.948864444017943340f, + 0.315501860107556040f, -0.948924958186195160f, 0.315319900226745050f, + -0.948985437465188710f, + 0.315137928752522440f, -0.949045881852700560f, 0.314955945691579250f, + -0.949106291346508260f, + 0.314773951050606070f, -0.949166665944390700f, 0.314591944836294710f, + -0.949227005644128210f, + 0.314409927055336820f, -0.949287310443502010f, 0.314227897714424500f, + -0.949347580340295210f, + 0.314045856820250820f, -0.949407815332291460f, 0.313863804379508500f, + -0.949468015417276550f, + 0.313681740398891570f, -0.949528180593036670f, 0.313499664885093450f, + -0.949588310857359950f, + 0.313317577844809070f, -0.949648406208035480f, 0.313135479284732950f, + -0.949708466642853800f, + 0.312953369211560200f, -0.949768492159606680f, 0.312771247631986880f, + -0.949828482756087000f, + 0.312589114552708660f, -0.949888438430089300f, 0.312406969980422500f, + -0.949948359179409010f, + 0.312224813921825050f, -0.950008245001843000f, 0.312042646383613510f, + -0.950068095895189590f, + 0.311860467372486130f, -0.950127911857248100f, 0.311678276895140550f, + -0.950187692885819280f, + 0.311496074958275970f, -0.950247438978705230f, 0.311313861568591090f, + -0.950307150133709140f, + 0.311131636732785270f, -0.950366826348635780f, 0.310949400457558760f, + -0.950426467621290900f, + 0.310767152749611470f, -0.950486073949481700f, 0.310584893615644560f, + -0.950545645331016600f, + 0.310402623062358880f, -0.950605181763705230f, 0.310220341096455910f, + -0.950664683245358910f, + 0.310038047724638000f, -0.950724149773789610f, 0.309855742953607130f, + -0.950783581346811070f, + 0.309673426790066490f, -0.950842977962238160f, 0.309491099240719050f, + -0.950902339617887060f, + 0.309308760312268780f, -0.950961666311575080f, 0.309126410011419550f, + -0.951020958041121080f, + 0.308944048344875710f, -0.951080214804345010f, 0.308761675319342570f, + -0.951139436599068190f, + 0.308579290941525030f, -0.951198623423113230f, 0.308396895218129240f, + -0.951257775274304000f, + 0.308214488155861220f, -0.951316892150465550f, 0.308032069761427330f, + -0.951375974049424420f, + 0.307849640041534980f, -0.951435020969008340f, 0.307667199002891190f, + -0.951494032907046370f, + 0.307484746652204160f, -0.951553009861368590f, 0.307302282996181950f, + -0.951611951829806730f, + 0.307119808041533100f, -0.951670858810193860f, 0.306937321794967020f, + -0.951729730800363720f, + 0.306754824263192780f, -0.951788567798152130f, 0.306572315452920800f, + -0.951847369801395620f, + 0.306389795370861080f, -0.951906136807932230f, 0.306207264023724280f, + -0.951964868815601380f, + 0.306024721418221900f, -0.952023565822243570f, 0.305842167561065080f, + -0.952082227825700620f, + 0.305659602458966230f, -0.952140854823815830f, 0.305477026118637360f, + -0.952199446814433580f, + 0.305294438546791720f, -0.952258003795399600f, 0.305111839750142220f, + -0.952316525764560830f, + 0.304929229735402430f, -0.952375012719765880f, 0.304746608509286640f, + -0.952433464658864030f, + 0.304563976078509050f, -0.952491881579706320f, 0.304381332449784940f, + -0.952550263480144930f, + 0.304198677629829270f, -0.952608610358033240f, 0.304016011625357570f, + -0.952666922211226170f, + 0.303833334443086470f, -0.952725199037579570f, 0.303650646089731910f, + -0.952783440834950920f, + 0.303467946572011370f, -0.952841647601198720f, 0.303285235896641910f, + -0.952899819334182880f, + 0.303102514070341060f, -0.952957956031764700f, 0.302919781099827420f, + -0.953016057691806530f, + 0.302737036991819140f, -0.953074124312172200f, 0.302554281753035670f, + -0.953132155890726750f, + 0.302371515390196130f, -0.953190152425336560f, 0.302188737910020040f, + -0.953248113913869320f, + 0.302005949319228200f, -0.953306040354193750f, 0.301823149624540650f, + -0.953363931744180330f, + 0.301640338832678880f, -0.953421788081700310f, 0.301457516950363940f, + -0.953479609364626610f, + 0.301274683984318000f, -0.953537395590833280f, 0.301091839941263210f, + -0.953595146758195680f, + 0.300908984827921890f, -0.953652862864590500f, 0.300726118651017620f, + -0.953710543907895560f, + 0.300543241417273400f, -0.953768189885990330f, 0.300360353133413580f, + -0.953825800796755050f, + 0.300177453806162120f, -0.953883376638071770f, 0.299994543442243580f, + -0.953940917407823500f, + 0.299811622048383460f, -0.953998423103894490f, 0.299628689631306790f, + -0.954055893724170660f, + 0.299445746197739950f, -0.954113329266538800f, 0.299262791754409010f, + -0.954170729728887280f, + 0.299079826308040480f, -0.954228095109105670f, 0.298896849865361910f, + -0.954285425405084650f, + 0.298713862433100390f, -0.954342720614716480f, 0.298530864017984230f, + -0.954399980735894490f, + 0.298347854626741570f, -0.954457205766513490f, 0.298164834266100910f, + -0.954514395704469500f, + 0.297981802942791920f, -0.954571550547659630f, 0.297798760663543550f, + -0.954628670293982680f, + 0.297615707435086310f, -0.954685754941338340f, 0.297432643264150030f, + -0.954742804487627940f, + 0.297249568157465890f, -0.954799818930753720f, 0.297066482121764840f, + -0.954856798268619580f, + 0.296883385163778270f, -0.954913742499130520f, 0.296700277290238460f, + -0.954970651620192790f, + 0.296517158507877410f, -0.955027525629714160f, 0.296334028823428240f, + -0.955084364525603410f, + 0.296150888243623960f, -0.955141168305770670f, 0.295967736775197890f, + -0.955197936968127710f, + 0.295784574424884370f, -0.955254670510586990f, 0.295601401199417360f, + -0.955311368931062720f, + 0.295418217105532070f, -0.955368032227470240f, 0.295235022149963390f, + -0.955424660397726330f, + 0.295051816339446720f, -0.955481253439748770f, 0.294868599680718380f, + -0.955537811351456770f, + 0.294685372180514330f, -0.955594334130771110f, 0.294502133845571720f, + -0.955650821775613220f, + 0.294318884682627570f, -0.955707274283906560f, 0.294135624698419080f, + -0.955763691653575440f, + 0.293952353899684770f, -0.955820073882545420f, 0.293769072293162400f, + -0.955876420968743590f, + 0.293585779885591310f, -0.955932732910098170f, 0.293402476683710060f, + -0.955989009704538930f, + 0.293219162694258680f, -0.956045251349996410f, 0.293035837923976920f, + -0.956101457844403040f, + 0.292852502379604810f, -0.956157629185692140f, 0.292669156067883570f, + -0.956213765371798470f, + 0.292485798995553830f, -0.956269866400658140f, 0.292302431169357610f, + -0.956325932270208230f, + 0.292119052596036540f, -0.956381962978387620f, 0.291935663282332780f, + -0.956437958523136180f, + 0.291752263234989370f, -0.956493918902394990f, 0.291568852460749040f, + -0.956549844114106820f, + 0.291385430966355720f, -0.956605734156215080f, 0.291201998758553020f, + -0.956661589026664980f, + 0.291018555844085090f, -0.956717408723403050f, 0.290835102229696940f, + -0.956773193244376930f, + 0.290651637922133220f, -0.956828942587535370f, 0.290468162928139870f, + -0.956884656750828900f, + 0.290284677254462330f, -0.956940335732208940f, 0.290101180907847140f, + -0.956995979529628230f, + 0.289917673895040860f, -0.957051588141040970f, 0.289734156222790250f, + -0.957107161564402790f, + 0.289550627897843140f, -0.957162699797670100f, 0.289367088926946960f, + -0.957218202838801210f, + 0.289183539316850310f, -0.957273670685755200f, 0.288999979074301530f, + -0.957329103336492790f, + 0.288816408206049480f, -0.957384500788975860f, 0.288632826718843940f, + -0.957439863041167570f, + 0.288449234619434170f, -0.957495190091032570f, 0.288265631914570830f, + -0.957550481936536470f, + 0.288082018611004300f, -0.957605738575646240f, 0.287898394715485170f, + -0.957660960006330610f, + 0.287714760234765280f, -0.957716146226558870f, 0.287531115175595930f, + -0.957771297234302320f, + 0.287347459544729570f, -0.957826413027532910f, 0.287163793348918560f, + -0.957881493604224250f, + 0.286980116594915570f, -0.957936538962351420f, 0.286796429289474190f, + -0.957991549099890370f, + 0.286612731439347790f, -0.958046524014818600f, 0.286429023051290750f, + -0.958101463705114620f, + 0.286245304132057120f, -0.958156368168758820f, 0.286061574688402100f, + -0.958211237403732260f, + 0.285877834727080730f, -0.958266071408017670f, 0.285694084254848320f, + -0.958320870179598880f, + 0.285510323278461380f, -0.958375633716461170f, 0.285326551804675810f, + -0.958430362016591040f, + 0.285142769840248720f, -0.958485055077976100f, 0.284958977391937150f, + -0.958539712898605730f, + 0.284775174466498300f, -0.958594335476470220f, 0.284591361070690550f, + -0.958648922809561040f, + 0.284407537211271820f, -0.958703474895871600f, 0.284223702895001100f, + -0.958757991733395710f, + 0.284039858128637360f, -0.958812473320129200f, 0.283856002918939750f, + -0.958866919654069010f, + 0.283672137272668550f, -0.958921330733213060f, 0.283488261196583550f, + -0.958975706555561080f, + 0.283304374697445790f, -0.959030047119113550f, 0.283120477782015990f, + -0.959084352421872730f, + 0.282936570457055390f, -0.959138622461841890f, 0.282752652729326040f, + -0.959192857237025740f, + 0.282568724605589740f, -0.959247056745430090f, 0.282384786092609420f, + -0.959301220985062210f, + 0.282200837197147500f, -0.959355349953930790f, 0.282016877925967690f, + -0.959409443650045550f, + 0.281832908285833460f, -0.959463502071417510f, 0.281648928283508680f, + -0.959517525216059260f, + 0.281464937925758050f, -0.959571513081984520f, 0.281280937219346110f, + -0.959625465667208300f, + 0.281096926171038320f, -0.959679382969746750f, 0.280912904787600120f, + -0.959733264987617680f, + 0.280728873075797190f, -0.959787111718839900f, 0.280544831042396360f, + -0.959840923161433660f, + 0.280360778694163810f, -0.959894699313420530f, 0.280176716037867040f, + -0.959948440172823210f, + 0.279992643080273380f, -0.960002145737665850f, 0.279808559828150390f, + -0.960055816005973890f, + 0.279624466288266700f, -0.960109450975773940f, 0.279440362467390510f, + -0.960163050645094000f, + 0.279256248372291240f, -0.960216615011963430f, 0.279072124009737970f, + -0.960270144074412800f, + 0.278887989386500280f, -0.960323637830473920f, 0.278703844509348600f, + -0.960377096278180130f, + 0.278519689385053060f, -0.960430519415565790f, 0.278335524020384970f, + -0.960483907240666790f, + 0.278151348422115090f, -0.960537259751520050f, 0.277967162597015430f, + -0.960590576946164120f, + 0.277782966551857800f, -0.960643858822638470f, 0.277598760293414290f, + -0.960697105378984450f, + 0.277414543828458200f, -0.960750316613243950f, 0.277230317163762120f, + -0.960803492523460760f, + 0.277046080306099950f, -0.960856633107679660f, 0.276861833262245390f, + -0.960909738363946770f, + 0.276677576038972420f, -0.960962808290309780f, 0.276493308643056100f, + -0.961015842884817230f, + 0.276309031081271030f, -0.961068842145519350f, 0.276124743360392890f, + -0.961121806070467380f, + 0.275940445487197320f, -0.961174734657714080f, 0.275756137468460120f, + -0.961227627905313460f, + 0.275571819310958250f, -0.961280485811320640f, 0.275387491021468140f, + -0.961333308373792270f, + 0.275203152606767370f, -0.961386095590786250f, 0.275018804073633380f, + -0.961438847460361570f, + 0.274834445428843940f, -0.961491563980579000f, 0.274650076679177790f, + -0.961544245149499990f, + 0.274465697831413220f, -0.961596890965187860f, 0.274281308892329710f, + -0.961649501425706820f, + 0.274096909868706330f, -0.961702076529122540f, 0.273912500767323320f, + -0.961754616273502010f, + 0.273728081594960650f, -0.961807120656913540f, 0.273543652358398730f, + -0.961859589677426570f, + 0.273359213064418790f, -0.961912023333112100f, 0.273174763719801870f, + -0.961964421622042320f, + 0.272990304331329980f, -0.962016784542290560f, 0.272805834905784920f, + -0.962069112091931580f, + 0.272621355449948980f, -0.962121404269041580f, 0.272436865970605350f, + -0.962173661071697770f, + 0.272252366474536660f, -0.962225882497979020f, 0.272067856968526980f, + -0.962278068545965090f, + 0.271883337459359890f, -0.962330219213737400f, 0.271698807953819510f, + -0.962382334499378380f, + 0.271514268458690810f, -0.962434414400971990f, 0.271329718980758420f, + -0.962486458916603450f, + 0.271145159526808070f, -0.962538468044359160f, 0.270960590103625330f, + -0.962590441782326780f, + 0.270776010717996010f, -0.962642380128595710f, 0.270591421376707050f, + -0.962694283081255930f, + 0.270406822086544820f, -0.962746150638399410f, 0.270222212854296930f, + -0.962797982798119010f, + 0.270037593686750510f, -0.962849779558509030f, 0.269852964590693910f, + -0.962901540917665000f, + 0.269668325572915200f, -0.962953266873683880f, 0.269483676640202840f, + -0.963004957424663850f, + 0.269299017799346230f, -0.963056612568704340f, 0.269114349057134330f, + -0.963108232303906190f, + 0.268929670420357310f, -0.963159816628371360f, 0.268744981895805090f, + -0.963211365540203480f, + 0.268560283490267890f, -0.963262879037507070f, 0.268375575210537010f, + -0.963314357118388090f, + 0.268190857063403180f, -0.963365799780954050f, 0.268006129055658350f, + -0.963417207023313350f, + 0.267821391194094320f, -0.963468578843575950f, 0.267636643485503090f, + -0.963519915239853140f, + 0.267451885936677740f, -0.963571216210257210f, 0.267267118554410930f, + -0.963622481752902220f, + 0.267082341345496350f, -0.963673711865903230f, 0.266897554316727510f, + -0.963724906547376410f, + 0.266712757474898420f, -0.963776065795439840f, 0.266527950826803810f, + -0.963827189608212340f, + 0.266343134379238180f, -0.963878277983814200f, 0.266158308138997050f, + -0.963929330920367140f, + 0.265973472112875530f, -0.963980348415994110f, 0.265788626307669970f, + -0.964031330468819280f, + 0.265603770730176440f, -0.964082277076968140f, 0.265418905387191260f, + -0.964133188238567640f, + 0.265234030285511900f, -0.964184063951745720f, 0.265049145431935200f, + -0.964234904214632200f, + 0.264864250833259320f, -0.964285709025357370f, 0.264679346496282050f, + -0.964336478382053720f, + 0.264494432427801630f, -0.964387212282854290f, 0.264309508634617220f, + -0.964437910725893910f, + 0.264124575123527490f, -0.964488573709308410f, 0.263939631901332410f, + -0.964539201231235150f, + 0.263754678974831510f, -0.964589793289812650f, 0.263569716350824880f, + -0.964640349883180930f, + 0.263384744036113390f, -0.964690871009480920f, 0.263199762037497560f, + -0.964741356666855340f, + 0.263014770361779060f, -0.964791806853447900f, 0.262829769015759330f, + -0.964842221567403510f, + 0.262644758006240100f, -0.964892600806868890f, 0.262459737340024090f, + -0.964942944569991410f, + 0.262274707023913590f, -0.964993252854920320f, 0.262089667064712100f, + -0.965043525659805890f, + 0.261904617469222560f, -0.965093762982799590f, 0.261719558244249080f, + -0.965143964822054450f, + 0.261534489396595630f, -0.965194131175724720f, 0.261349410933066350f, + -0.965244262041965780f, + 0.261164322860466590f, -0.965294357418934660f, 0.260979225185601020f, + -0.965344417304789370f, + 0.260794117915275570f, -0.965394441697689400f, 0.260609001056295920f, + -0.965444430595795430f, + 0.260423874615468010f, -0.965494383997269500f, 0.260238738599598950f, + -0.965544301900275070f, + 0.260053593015495130f, -0.965594184302976830f, 0.259868437869964330f, + -0.965644031203540590f, + 0.259683273169813930f, -0.965693842600133690f, 0.259498098921851660f, + -0.965743618490924830f, + 0.259312915132886350f, -0.965793358874083570f, 0.259127721809726150f, + -0.965843063747781510f, + 0.258942518959180580f, -0.965892733110190860f, 0.258757306588058840f, + -0.965942366959485540f, + 0.258572084703170390f, -0.965991965293840570f, 0.258386853311325710f, + -0.966041528111432400f, + 0.258201612419334870f, -0.966091055410438830f, 0.258016362034009070f, + -0.966140547189038750f, + 0.257831102162158930f, -0.966190003445412620f, 0.257645832810596440f, + -0.966239424177741890f, + 0.257460553986133210f, -0.966288809384209580f, 0.257275265695581120f, + -0.966338159063000130f, + 0.257089967945753230f, -0.966387473212298790f, 0.256904660743461850f, + -0.966436751830292650f, + 0.256719344095520720f, -0.966485994915169840f, 0.256534018008743200f, + -0.966535202465119700f, + 0.256348682489942910f, -0.966584374478333120f, 0.256163337545934570f, + -0.966633510953002100f, + 0.255977983183532380f, -0.966682611887320190f, 0.255792619409551670f, + -0.966731677279481840f, + 0.255607246230807550f, -0.966780707127683270f, 0.255421863654115460f, + -0.966829701430121810f, + 0.255236471686291820f, -0.966878660184995910f, 0.255051070334152530f, + -0.966927583390505660f, + 0.254865659604514630f, -0.966976471044852070f, 0.254680239504194990f, + -0.967025323146237900f, + 0.254494810040010790f, -0.967074139692867040f, 0.254309371218780110f, + -0.967122920682944360f, + 0.254123923047320620f, -0.967171666114676640f, 0.253938465532451140f, + -0.967220375986271310f, + 0.253752998680989940f, -0.967269050295937790f, 0.253567522499756610f, + -0.967317689041886310f, + 0.253382036995570270f, -0.967366292222328510f, 0.253196542175250560f, + -0.967414859835477480f, + 0.253011038045617980f, -0.967463391879547440f, 0.252825524613492610f, + -0.967511888352754150f, + 0.252640001885695580f, -0.967560349253314360f, 0.252454469869047900f, + -0.967608774579446380f, + 0.252268928570370810f, -0.967657164329369880f, 0.252083377996486560f, + -0.967705518501305480f, + 0.251897818154216910f, -0.967753837093475510f, 0.251712249050384750f, + -0.967802120104103270f, + 0.251526670691812780f, -0.967850367531413620f, 0.251341083085323880f, + -0.967898579373632660f, + 0.251155486237742030f, -0.967946755628987800f, 0.250969880155890720f, + -0.967994896295707670f, + 0.250784264846594550f, -0.968043001372022260f, 0.250598640316677830f, + -0.968091070856162970f, + 0.250413006572965280f, -0.968139104746362330f, 0.250227363622282540f, + -0.968187103040854420f, + 0.250041711471454650f, -0.968235065737874320f, 0.249856050127308050f, + -0.968282992835658660f, + 0.249670379596668520f, -0.968330884332445300f, 0.249484699886363010f, + -0.968378740226473300f, + 0.249299011003218300f, -0.968426560515983190f, 0.249113312954061360f, + -0.968474345199216820f, + 0.248927605745720260f, -0.968522094274417270f, 0.248741889385022420f, + -0.968569807739828930f, + 0.248556163878796620f, -0.968617485593697540f, 0.248370429233871150f, + -0.968665127834269950f, + 0.248184685457074780f, -0.968712734459794780f, 0.247998932555237220f, + -0.968760305468521430f, + 0.247813170535187620f, -0.968807840858700970f, 0.247627399403756330f, + -0.968855340628585580f, + 0.247441619167773440f, -0.968902804776428870f, 0.247255829834069320f, + -0.968950233300485800f, + 0.247070031409475370f, -0.968997626199012310f, 0.246884223900822430f, + -0.969044983470266240f, + 0.246698407314942500f, -0.969092305112506100f, 0.246512581658667380f, + -0.969139591123992280f, + 0.246326746938829060f, -0.969186841502985950f, 0.246140903162260640f, + -0.969234056247750050f, + 0.245955050335794590f, -0.969281235356548530f, 0.245769188466264670f, + -0.969328378827646660f, + 0.245583317560504000f, -0.969375486659311280f, 0.245397437625346990f, + -0.969422558849810320f, + 0.245211548667627680f, -0.969469595397412950f, 0.245025650694180470f, + -0.969516596300390000f, + 0.244839743711840750f, -0.969563561557013180f, 0.244653827727443320f, + -0.969610491165555870f, + 0.244467902747824210f, -0.969657385124292450f, 0.244281968779819170f, + -0.969704243431498750f, + 0.244096025830264210f, -0.969751066085452140f, 0.243910073905996370f, + -0.969797853084430890f, + 0.243724113013852130f, -0.969844604426714830f, 0.243538143160669180f, + -0.969891320110585100f, + 0.243352164353284880f, -0.969938000134323960f, 0.243166176598536930f, + -0.969984644496215240f, + 0.242980179903263980f, -0.970031253194543970f, 0.242794174274304190f, + -0.970077826227596420f, + 0.242608159718496890f, -0.970124363593660280f, 0.242422136242681050f, + -0.970170865291024360f, + 0.242236103853696040f, -0.970217331317979160f, 0.242050062558382180f, + -0.970263761672816140f, + 0.241864012363579210f, -0.970310156353828110f, 0.241677953276128090f, + -0.970356515359309450f, + 0.241491885302869300f, -0.970402838687555500f, 0.241305808450644390f, + -0.970449126336863090f, + 0.241119722726294730f, -0.970495378305530450f, 0.240933628136661910f, + -0.970541594591857070f, + 0.240747524688588540f, -0.970587775194143630f, 0.240561412388916620f, + -0.970633920110692160f, + 0.240375291244489500f, -0.970680029339806130f, 0.240189161262150040f, + -0.970726102879790110f, + 0.240003022448741500f, -0.970772140728950350f, 0.239816874811108110f, + -0.970818142885593870f, + 0.239630718356093560f, -0.970864109348029470f, 0.239444553090542720f, + -0.970910040114567050f, + 0.239258379021300120f, -0.970955935183517970f, 0.239072196155210660f, + -0.971001794553194690f, + 0.238886004499120170f, -0.971047618221911100f, 0.238699804059873950f, + -0.971093406187982460f, + 0.238513594844318500f, -0.971139158449725090f, 0.238327376859299970f, + -0.971184875005457030f, + 0.238141150111664870f, -0.971230555853497380f, 0.237954914608260650f, + -0.971276200992166490f, + 0.237768670355934210f, -0.971321810419786160f, 0.237582417361533650f, + -0.971367384134679490f, + 0.237396155631906550f, -0.971412922135170940f, 0.237209885173901620f, + -0.971458424419585960f, + 0.237023605994367340f, -0.971503890986251780f, 0.236837318100152380f, + -0.971549321833496630f, + 0.236651021498106460f, -0.971594716959650160f, 0.236464716195078750f, + -0.971640076363043390f, + 0.236278402197919620f, -0.971685400042008540f, 0.236092079513479050f, + -0.971730687994879160f, + 0.235905748148607370f, -0.971775940219990140f, 0.235719408110155930f, + -0.971821156715677700f, + 0.235533059404975460f, -0.971866337480279400f, 0.235346702039917920f, + -0.971911482512134000f, + 0.235160336021834860f, -0.971956591809581600f, 0.234973961357578310f, + -0.972001665370963890f, + 0.234787578054001080f, -0.972046703194623380f, 0.234601186117955550f, + -0.972091705278904430f, + 0.234414785556295250f, -0.972136671622152120f, 0.234228376375873380f, + -0.972181602222713440f, + 0.234041958583543460f, -0.972226497078936270f, 0.233855532186159950f, + -0.972271356189170040f, + 0.233669097190576820f, -0.972316179551765300f, 0.233482653603649170f, + -0.972360967165074140f, + 0.233296201432231560f, -0.972405719027449770f, 0.233109740683179740f, + -0.972450435137246830f, + 0.232923271363349120f, -0.972495115492821190f, 0.232736793479595420f, + -0.972539760092530180f, + 0.232550307038775330f, -0.972584368934732210f, 0.232363812047745010f, + -0.972628942017787270f, + 0.232177308513361770f, -0.972673479340056430f, 0.231990796442482580f, + -0.972717980899902250f, + 0.231804275841964780f, -0.972762446695688570f, 0.231617746718666580f, + -0.972806876725780370f, + 0.231431209079445730f, -0.972851270988544180f, 0.231244662931161110f, + -0.972895629482347760f, + 0.231058108280671280f, -0.972939952205560070f, 0.230871545134835070f, + -0.972984239156551740f, + 0.230684973500512310f, -0.973028490333694100f, 0.230498393384562320f, + -0.973072705735360530f, + 0.230311804793845530f, -0.973116885359925130f, 0.230125207735222020f, + -0.973161029205763530f, + 0.229938602215552260f, -0.973205137271252800f, 0.229751988241697600f, + -0.973249209554771120f, + 0.229565365820518870f, -0.973293246054698250f, 0.229378734958878120f, + -0.973337246769414800f, + 0.229192095663636740f, -0.973381211697303290f, 0.229005447941657390f, + -0.973425140836747030f, + 0.228818791799802360f, -0.973469034186130950f, 0.228632127244934230f, + -0.973512891743841370f, + 0.228445454283916550f, -0.973556713508265560f, 0.228258772923612350f, + -0.973600499477792370f, + 0.228072083170885790f, -0.973644249650811870f, 0.227885385032600700f, + -0.973687964025715670f, + 0.227698678515621170f, -0.973731642600896400f, 0.227511963626812390f, + -0.973775285374748000f, + 0.227325240373038830f, -0.973818892345666100f, 0.227138508761166260f, + -0.973862463512047300f, + 0.226951768798059980f, -0.973905998872289460f, 0.226765020490585720f, + -0.973949498424792170f, + 0.226578263845610110f, -0.973992962167955830f, 0.226391498869999210f, + -0.974036390100182610f, + 0.226204725570620270f, -0.974079782219875680f, 0.226017943954340190f, + -0.974123138525439520f, + 0.225831154028026200f, -0.974166459015280320f, 0.225644355798546440f, + -0.974209743687805110f, + 0.225457549272768540f, -0.974252992541422500f, 0.225270734457561240f, + -0.974296205574542330f, + 0.225083911359792780f, -0.974339382785575860f, 0.224897079986332540f, + -0.974382524172935470f, + 0.224710240344049570f, -0.974425629735034990f, 0.224523392439813170f, + -0.974468699470289580f, + 0.224336536280493690f, -0.974511733377115720f, 0.224149671872960840f, + -0.974554731453931230f, + 0.223962799224085520f, -0.974597693699155050f, 0.223775918340738290f, + -0.974640620111207560f, + 0.223589029229790020f, -0.974683510688510670f, 0.223402131898112480f, + -0.974726365429487320f, + 0.223215226352576960f, -0.974769184332561770f, 0.223028312600055870f, + -0.974811967396159830f, + 0.222841390647421280f, -0.974854714618708430f, 0.222654460501545550f, + -0.974897425998635820f, + 0.222467522169301990f, -0.974940101534371720f, 0.222280575657563370f, + -0.974982741224347140f, + 0.222093620973203590f, -0.975025345066994120f, 0.221906658123096260f, + -0.975067913060746360f, + 0.221719687114115240f, -0.975110445204038890f, 0.221532707953135340f, + -0.975152941495307620f, + 0.221345720647030810f, -0.975195401932990370f, 0.221158725202677100f, + -0.975237826515525820f, + 0.220971721626949060f, -0.975280215241354220f, 0.220784709926722670f, + -0.975322568108916930f, + 0.220597690108873650f, -0.975364885116656870f, 0.220410662180277940f, + -0.975407166263018270f, + 0.220223626147812460f, -0.975449411546446380f, 0.220036582018353550f, + -0.975491620965388110f, + 0.219849529798778750f, -0.975533794518291360f, 0.219662469495965180f, + -0.975575932203605610f, + 0.219475401116790340f, -0.975618034019781750f, 0.219288324668132580f, + -0.975660099965271590f, + 0.219101240156869770f, -0.975702130038528570f, 0.218914147589880900f, + -0.975744124238007270f, + 0.218727046974044600f, -0.975786082562163930f, 0.218539938316239830f, + -0.975828005009455550f, + 0.218352821623346430f, -0.975869891578341030f, 0.218165696902243770f, + -0.975911742267280170f, + 0.217978564159812290f, -0.975953557074734300f, 0.217791423402932120f, + -0.975995335999165880f, + 0.217604274638483670f, -0.976037079039039020f, 0.217417117873348300f, + -0.976078786192818850f, + 0.217229953114406790f, -0.976120457458971910f, 0.217042780368541080f, + -0.976162092835966110f, + 0.216855599642632570f, -0.976203692322270560f, 0.216668410943563790f, + -0.976245255916355800f, + 0.216481214278216900f, -0.976286783616693630f, 0.216294009653474370f, + -0.976328275421757260f, + 0.216106797076219600f, -0.976369731330021140f, 0.215919576553335460f, + -0.976411151339961040f, + 0.215732348091705940f, -0.976452535450054060f, 0.215545111698214660f, + -0.976493883658778540f, + 0.215357867379745550f, -0.976535195964614470f, 0.215170615143183500f, + -0.976576472366042610f, + 0.214983354995412820f, -0.976617712861545640f, 0.214796086943318920f, + -0.976658917449606980f, + 0.214608810993786920f, -0.976700086128711840f, 0.214421527153702190f, + -0.976741218897346550f, + 0.214234235429951100f, -0.976782315753998650f, 0.214046935829419330f, + -0.976823376697157240f, + 0.213859628358993830f, -0.976864401725312640f, 0.213672313025561140f, + -0.976905390836956490f, + 0.213484989836008080f, -0.976946344030581560f, 0.213297658797222430f, + -0.976987261304682390f, + 0.213110319916091360f, -0.977028142657754390f, 0.212922973199503260f, + -0.977068988088294450f, + 0.212735618654345870f, -0.977109797594800880f, 0.212548256287508120f, + -0.977150571175773200f, + 0.212360886105878580f, -0.977191308829712280f, 0.212173508116346080f, + -0.977232010555120320f, + 0.211986122325800410f, -0.977272676350500860f, 0.211798728741130820f, + -0.977313306214358750f, + 0.211611327369227610f, -0.977353900145199960f, 0.211423918216980810f, + -0.977394458141532250f, + 0.211236501291280710f, -0.977434980201864260f, 0.211049076599018500f, + -0.977475466324706050f, + 0.210861644147084830f, -0.977515916508569280f, 0.210674203942371490f, + -0.977556330751966460f, + 0.210486755991769890f, -0.977596709053411780f, 0.210299300302171750f, + -0.977637051411420770f, + 0.210111836880469720f, -0.977677357824509930f, 0.209924365733555860f, + -0.977717628291197570f, + 0.209736886868323370f, -0.977757862810002760f, 0.209549400291665110f, + -0.977798061379446360f, + 0.209361906010474190f, -0.977838223998050430f, 0.209174404031644700f, + -0.977878350664338150f, + 0.208986894362070070f, -0.977918441376834370f, 0.208799377008644980f, + -0.977958496134064830f, + 0.208611851978263460f, -0.977998514934557140f, 0.208424319277820650f, + -0.978038497776839600f, + 0.208236778914211470f, -0.978078444659442380f, 0.208049230894330940f, + -0.978118355580896660f, + 0.207861675225075150f, -0.978158230539735050f, 0.207674111913339540f, + -0.978198069534491400f, + 0.207486540966020700f, -0.978237872563701090f, 0.207298962390014880f, + -0.978277639625900420f, + 0.207111376192218560f, -0.978317370719627650f, 0.206923782379529210f, + -0.978357065843421640f, + 0.206736180958843660f, -0.978396724995823090f, 0.206548571937059940f, + -0.978436348175373730f, + 0.206360955321075680f, -0.978475935380616830f, 0.206173331117788770f, + -0.978515486610096910f, + 0.205985699334098050f, -0.978555001862359550f, 0.205798059976901760f, + -0.978594481135952270f, + 0.205610413053099320f, -0.978633924429423100f, 0.205422758569589780f, + -0.978673331741322210f, + 0.205235096533272380f, -0.978712703070200420f, 0.205047426951047380f, + -0.978752038414610340f, + 0.204859749829814420f, -0.978791337773105670f, 0.204672065176474290f, + -0.978830601144241470f, + 0.204484372997927180f, -0.978869828526574120f, 0.204296673301074430f, + -0.978909019918661310f, + 0.204108966092817010f, -0.978948175319062200f, 0.203921251380056150f, + -0.978987294726337050f, + 0.203733529169694010f, -0.979026378139047580f, 0.203545799468632190f, + -0.979065425555756930f, + 0.203358062283773370f, -0.979104436975029250f, 0.203170317622019920f, + -0.979143412395430230f, + 0.202982565490274460f, -0.979182351815526930f, 0.202794805895440550f, + -0.979221255233887700f, + 0.202607038844421110f, -0.979260122649082020f, 0.202419264344120220f, + -0.979298954059681040f, + 0.202231482401441620f, -0.979337749464256780f, 0.202043693023289280f, + -0.979376508861383170f, + 0.201855896216568160f, -0.979415232249634780f, 0.201668091988182500f, + -0.979453919627588210f, + 0.201480280345037820f, -0.979492570993820700f, 0.201292461294039190f, + -0.979531186346911390f, + 0.201104634842091960f, -0.979569765685440520f, 0.200916800996102370f, + -0.979608309007989450f, + 0.200728959762976140f, -0.979646816313141210f, 0.200541111149620090f, + -0.979685287599479930f, + 0.200353255162940420f, -0.979723722865591170f, 0.200165391809844500f, + -0.979762122110061640f, + 0.199977521097239290f, -0.979800485331479680f, 0.199789643032032120f, + -0.979838812528434740f, + 0.199601757621131050f, -0.979877103699517640f, 0.199413864871443750f, + -0.979915358843320480f, + 0.199225964789878890f, -0.979953577958436740f, 0.199038057383344820f, + -0.979991761043461200f, + 0.198850142658750120f, -0.980029908096989980f, 0.198662220623004320f, + -0.980068019117620650f, + 0.198474291283016360f, -0.980106094103951770f, 0.198286354645696270f, + -0.980144133054583590f, + 0.198098410717953730f, -0.980182135968117320f, 0.197910459506698720f, + -0.980220102843155970f, + 0.197722501018842030f, -0.980258033678303550f, 0.197534535261294000f, + -0.980295928472165290f, + 0.197346562240966000f, -0.980333787223347960f, 0.197158581964769040f, + -0.980371609930459690f, + 0.196970594439614370f, -0.980409396592109910f, 0.196782599672414240f, + -0.980447147206909060f, + 0.196594597670080220f, -0.980484861773469380f, 0.196406588439525050f, + -0.980522540290404090f, + 0.196218571987660850f, -0.980560182756327950f, 0.196030548321400880f, + -0.980597789169856850f, + 0.195842517447657990f, -0.980635359529608120f, 0.195654479373345370f, + -0.980672893834200530f, + 0.195466434105377090f, -0.980710392082253970f, 0.195278381650666520f, + -0.980747854272389750f, + 0.195090322016128330f, -0.980785280403230430f, 0.194902255208676660f, + -0.980822670473399990f, + 0.194714181235225990f, -0.980860024481523870f, 0.194526100102691720f, + -0.980897342426228390f, + 0.194338011817988600f, -0.980934624306141640f, 0.194149916388032530f, + -0.980971870119892840f, + 0.193961813819739010f, -0.981009079866112630f, 0.193773704120023840f, + -0.981046253543432780f, + 0.193585587295803750f, -0.981083391150486590f, 0.193397463353994740f, + -0.981120492685908730f, + 0.193209332301514080f, -0.981157558148334830f, 0.193021194145278320f, + -0.981194587536402320f, + 0.192833048892205290f, -0.981231580848749730f, 0.192644896549212240f, + -0.981268538084016710f, + 0.192456737123216840f, -0.981305459240844670f, 0.192268570621137590f, + -0.981342344317875930f, + 0.192080397049892380f, -0.981379193313754560f, 0.191892216416400310f, + -0.981416006227125550f, + 0.191704028727579940f, -0.981452783056635520f, 0.191515833990350240f, + -0.981489523800932130f, + 0.191327632211630990f, -0.981526228458664660f, 0.191139423398341420f, + -0.981562897028483650f, + 0.190951207557401860f, -0.981599529509040720f, 0.190762984695732250f, + -0.981636125898989080f, + 0.190574754820252800f, -0.981672686196983110f, 0.190386517937884580f, + -0.981709210401678800f, + 0.190198274055548120f, -0.981745698511732990f, 0.190010023180165050f, + -0.981782150525804310f, + 0.189821765318656580f, -0.981818566442552500f, 0.189633500477944220f, + -0.981854946260638630f, + 0.189445228664950340f, -0.981891289978724990f, 0.189256949886596720f, + -0.981927597595475540f, + 0.189068664149806280f, -0.981963869109555240f, 0.188880371461501330f, + -0.982000104519630490f, + 0.188692071828605260f, -0.982036303824369020f, 0.188503765258041080f, + -0.982072467022439890f, + 0.188315451756732120f, -0.982108594112513610f, 0.188127131331602530f, + -0.982144685093261580f, + 0.187938803989575850f, -0.982180739963357200f, 0.187750469737576840f, + -0.982216758721474510f, + 0.187562128582529740f, -0.982252741366289370f, 0.187373780531359110f, + -0.982288687896478830f, + 0.187185425590990440f, -0.982324598310721160f, 0.186997063768348510f, + -0.982360472607696210f, + 0.186808695070359330f, -0.982396310786084690f, 0.186620319503948420f, + -0.982432112844569110f, + 0.186431937076041640f, -0.982467878781833170f, 0.186243547793565670f, + -0.982503608596561720f, + 0.186055151663446630f, -0.982539302287441240f, 0.185866748692611720f, + -0.982574959853159240f, + 0.185678338887987790f, -0.982610581292404750f, 0.185489922256501900f, + -0.982646166603868050f, + 0.185301498805082040f, -0.982681715786240860f, 0.185113068540655510f, + -0.982717228838215990f, + 0.184924631470150870f, -0.982752705758487830f, 0.184736187600495930f, + -0.982788146545751970f, + 0.184547736938619640f, -0.982823551198705240f, 0.184359279491450640f, + -0.982858919716046110f, + 0.184170815265917720f, -0.982894252096474070f, 0.183982344268950600f, + -0.982929548338690060f, + 0.183793866507478390f, -0.982964808441396440f, 0.183605381988431350f, + -0.983000032403296590f, + 0.183416890718739230f, -0.983035220223095640f, 0.183228392705332140f, + -0.983070371899499640f, + 0.183039887955141060f, -0.983105487431216290f, 0.182851376475096310f, + -0.983140566816954500f, + 0.182662858272129360f, -0.983175610055424420f, 0.182474333353171260f, + -0.983210617145337640f, + 0.182285801725153320f, -0.983245588085407070f, 0.182097263395007760f, + -0.983280522874346970f, + 0.181908718369666160f, -0.983315421510872810f, 0.181720166656061170f, + -0.983350283993701500f, + 0.181531608261125130f, -0.983385110321551180f, 0.181343043191790590f, + -0.983419900493141540f, + 0.181154471454990920f, -0.983454654507193270f, 0.180965893057658980f, + -0.983489372362428730f, + 0.180777308006728670f, -0.983524054057571260f, 0.180588716309133280f, + -0.983558699591345900f, + 0.180400117971807270f, -0.983593308962478650f, 0.180211513001684590f, + -0.983627882169697210f, + 0.180022901405699510f, -0.983662419211730250f, 0.179834283190787180f, + -0.983696920087308020f, + 0.179645658363882100f, -0.983731384795162090f, 0.179457026931919950f, + -0.983765813334025240f, + 0.179268388901835880f, -0.983800205702631490f, 0.179079744280565390f, + -0.983834561899716630f, + 0.178891093075044830f, -0.983868881924017220f, 0.178702435292209940f, + -0.983903165774271500f, + 0.178513770938997590f, -0.983937413449218920f, 0.178325100022344140f, + -0.983971624947600270f, + 0.178136422549186320f, -0.984005800268157870f, 0.177947738526461670f, + -0.984039939409634970f, + 0.177759047961107140f, -0.984074042370776450f, 0.177570350860060790f, + -0.984108109150328540f, + 0.177381647230260200f, -0.984142139747038570f, 0.177192937078643310f, + -0.984176134159655320f, + 0.177004220412148860f, -0.984210092386929030f, 0.176815497237715000f, + -0.984244014427611110f, + 0.176626767562280960f, -0.984277900280454370f, 0.176438031392785350f, + -0.984311749944212780f, + 0.176249288736167940f, -0.984345563417641900f, 0.176060539599367960f, + -0.984379340699498510f, + 0.175871783989325040f, -0.984413081788540700f, 0.175683021912979580f, + -0.984446786683527920f, + 0.175494253377271400f, -0.984480455383220930f, 0.175305478389141370f, + -0.984514087886381840f, + 0.175116696955530060f, -0.984547684191773960f, 0.174927909083378160f, + -0.984581244298162180f, + 0.174739114779627310f, -0.984614768204312600f, 0.174550314051218490f, + -0.984648255908992630f, + 0.174361506905093830f, -0.984681707410970940f, 0.174172693348194960f, + -0.984715122709017620f, + 0.173983873387463850f, -0.984748501801904210f, 0.173795047029843270f, + -0.984781844688403350f, + 0.173606214282275410f, -0.984815151367289140f, 0.173417375151703520f, + -0.984848421837337010f, + 0.173228529645070490f, -0.984881656097323700f, 0.173039677769319390f, + -0.984914854146027200f, + 0.172850819531394200f, -0.984948015982227030f, 0.172661954938238270f, + -0.984981141604703960f, + 0.172473083996796030f, -0.985014231012239840f, 0.172284206714011350f, + -0.985047284203618200f, + 0.172095323096829040f, -0.985080301177623800f, 0.171906433152193700f, + -0.985113281933042590f, + 0.171717536887049970f, -0.985146226468662230f, 0.171528634308343500f, + -0.985179134783271020f, + 0.171339725423019260f, -0.985212006875659460f, 0.171150810238023340f, + -0.985244842744618540f, + 0.170961888760301360f, -0.985277642388941220f, 0.170772960996799230f, + -0.985310405807421570f, + 0.170584026954463700f, -0.985343132998854790f, 0.170395086640240920f, + -0.985375823962037710f, + 0.170206140061078120f, -0.985408478695768420f, 0.170017187223922090f, + -0.985441097198846210f, + 0.169828228135719880f, -0.985473679470071810f, 0.169639262803419400f, + -0.985506225508247290f, + 0.169450291233967930f, -0.985538735312176060f, 0.169261313434313890f, + -0.985571208880662740f, + 0.169072329411405180f, -0.985603646212513400f, 0.168883339172190010f, + -0.985636047306535420f, + 0.168694342723617440f, -0.985668412161537550f, 0.168505340072635900f, + -0.985700740776329850f, + 0.168316331226194910f, -0.985733033149723490f, 0.168127316191243350f, + -0.985765289280531310f, + 0.167938294974731230f, -0.985797509167567370f, 0.167749267583608030f, + -0.985829692809647050f, + 0.167560234024823590f, -0.985861840205586980f, 0.167371194305328540f, + -0.985893951354205210f, + 0.167182148432072880f, -0.985926026254321130f, 0.166993096412007770f, + -0.985958064904755460f, + 0.166804038252083870f, -0.985990067304330030f, 0.166614973959252090f, + -0.986022033451868560f, + 0.166425903540464220f, -0.986053963346195440f, 0.166236827002671390f, + -0.986085856986136820f, + 0.166047744352825850f, -0.986117714370520090f, 0.165858655597879430f, + -0.986149535498173860f, + 0.165669560744784140f, -0.986181320367928270f, 0.165480459800492890f, + -0.986213068978614490f, + 0.165291352771957970f, -0.986244781329065460f, 0.165102239666132720f, + -0.986276457418114980f, + 0.164913120489970090f, -0.986308097244598670f, 0.164723995250423190f, + -0.986339700807353000f, + 0.164534863954446110f, -0.986371268105216030f, 0.164345726608992190f, + -0.986402799137027220f, + 0.164156583221015890f, -0.986434293901627070f, 0.163967433797471110f, + -0.986465752397857940f, + 0.163778278345312690f, -0.986497174624562880f, 0.163589116871495160f, + -0.986528560580586690f, + 0.163399949382973230f, -0.986559910264775410f, 0.163210775886702460f, + -0.986591223675976400f, + 0.163021596389637810f, -0.986622500813038480f, 0.162832410898735260f, + -0.986653741674811350f, + 0.162643219420950450f, -0.986684946260146690f, 0.162454021963239190f, + -0.986716114567897100f, + 0.162264818532558110f, -0.986747246596916480f, 0.162075609135863330f, + -0.986778342346060430f, + 0.161886393780111910f, -0.986809401814185420f, 0.161697172472260540f, + -0.986840425000149680f, + 0.161507945219266150f, -0.986871411902812470f, 0.161318712028086540f, + -0.986902362521034470f, + 0.161129472905678780f, -0.986933276853677710f, 0.160940227859001140f, + -0.986964154899605650f, + 0.160750976895011390f, -0.986994996657682870f, 0.160561720020667510f, + -0.987025802126775600f, + 0.160372457242928400f, -0.987056571305750970f, 0.160183188568752240f, + -0.987087304193477900f, + 0.159993914005098350f, -0.987118000788826280f, 0.159804633558925380f, + -0.987148661090667570f, + 0.159615347237193090f, -0.987179285097874340f, 0.159426055046860750f, + -0.987209872809320820f, + 0.159236756994887850f, -0.987240424223882250f, 0.159047453088234840f, + -0.987270939340435420f, + 0.158858143333861390f, -0.987301418157858430f, 0.158668827738728370f, + -0.987331860675030430f, + 0.158479506309796100f, -0.987362266890832400f, 0.158290179054025180f, + -0.987392636804146240f, + 0.158100845978377090f, -0.987422970413855410f, 0.157911507089812640f, + -0.987453267718844560f, + 0.157722162395293690f, -0.987483528717999710f, 0.157532811901781670f, + -0.987513753410208420f, + 0.157343455616238280f, -0.987543941794359230f, 0.157154093545626010f, + -0.987574093869342360f, + 0.156964725696906750f, -0.987604209634049160f, 0.156775352077043430f, + -0.987634289087372160f, + 0.156585972692998590f, -0.987664332228205710f, 0.156396587551734940f, + -0.987694339055445130f, + 0.156207196660216040f, -0.987724309567986960f, 0.156017800025404830f, + -0.987754243764729530f, + 0.155828397654265320f, -0.987784141644572180f, 0.155638989553760850f, + -0.987814003206415550f, + 0.155449575730855880f, -0.987843828449161740f, 0.155260156192514380f, + -0.987873617371714200f, + 0.155070730945700510f, -0.987903369972977790f, 0.154881299997379400f, + -0.987933086251858380f, + 0.154691863354515400f, -0.987962766207263420f, 0.154502421024073990f, + -0.987992409838101880f, + 0.154312973013020240f, -0.988022017143283530f, 0.154123519328319360f, + -0.988051588121720110f, + 0.153934059976937460f, -0.988081122772324070f, 0.153744594965840000f, + -0.988110621094009820f, + 0.153555124301993500f, -0.988140083085692570f, 0.153365647992364020f, + -0.988169508746289060f, + 0.153176166043917870f, -0.988198898074717610f, 0.152986678463622160f, + -0.988228251069897420f, + 0.152797185258443410f, -0.988257567730749460f, 0.152607686435349140f, + -0.988286848056195710f, + 0.152418182001306500f, -0.988316092045159690f, 0.152228671963282770f, + -0.988345299696566150f, + 0.152039156328246160f, -0.988374471009341280f, 0.151849635103164180f, + -0.988403605982412390f, + 0.151660108295005400f, -0.988432704614708340f, 0.151470575910737760f, + -0.988461766905159300f, + 0.151281037957330250f, -0.988490792852696590f, 0.151091494441751430f, + -0.988519782456253270f, + 0.150901945370970040f, -0.988548735714763200f, 0.150712390751955720f, + -0.988577652627162020f, + 0.150522830591677370f, -0.988606533192386450f, 0.150333264897105050f, + -0.988635377409374790f, + 0.150143693675208330f, -0.988664185277066230f, 0.149954116932956990f, + -0.988692956794401940f, + 0.149764534677321620f, -0.988721691960323780f, 0.149574946915272210f, + -0.988750390773775360f, + 0.149385353653779810f, -0.988779053233701520f, 0.149195754899814960f, + -0.988807679339048340f, + 0.149006150660348470f, -0.988836269088763540f, 0.148816540942352030f, + -0.988864822481795640f, + 0.148626925752796540f, -0.988893339517095130f, 0.148437305098654050f, + -0.988921820193613190f, + 0.148247678986896200f, -0.988950264510302990f, 0.148058047424494740f, + -0.988978672466118480f, + 0.147868410418422360f, -0.989007044060015270f, 0.147678767975650970f, + -0.989035379290950310f, + 0.147489120103153680f, -0.989063678157881540f, 0.147299466807902820f, + -0.989091940659768800f, + 0.147109808096871850f, -0.989120166795572690f, 0.146920143977033760f, + -0.989148356564255590f, + 0.146730474455361750f, -0.989176509964781010f, 0.146540799538829870f, + -0.989204626996113780f, + 0.146351119234411440f, -0.989232707657220050f, 0.146161433549080950f, + -0.989260751947067640f, + 0.145971742489812370f, -0.989288759864625170f, 0.145782046063579860f, + -0.989316731408863000f, + 0.145592344277358450f, -0.989344666578752640f, 0.145402637138122540f, + -0.989372565373267010f, + 0.145212924652847520f, -0.989400427791380380f, 0.145023206828508360f, + -0.989428253832068230f, + 0.144833483672080240f, -0.989456043494307710f, 0.144643755190539150f, + -0.989483796777076760f, + 0.144454021390860440f, -0.989511513679355190f, 0.144264282280020530f, + -0.989539194200123930f, + 0.144074537864995330f, -0.989566838338365120f, 0.143884788152761010f, + -0.989594446093062460f, + 0.143695033150294580f, -0.989622017463200780f, 0.143505272864572290f, + -0.989649552447766530f, + 0.143315507302571590f, -0.989677051045747210f, 0.143125736471269140f, + -0.989704513256131850f, + 0.142935960377642700f, -0.989731939077910570f, 0.142746179028669620f, + -0.989759328510075200f, + 0.142556392431327340f, -0.989786681551618640f, 0.142366600592594260f, + -0.989813998201535260f, + 0.142176803519448000f, -0.989841278458820530f, 0.141987001218867340f, + -0.989868522322471580f, + 0.141797193697830530f, -0.989895729791486660f, 0.141607380963316020f, + -0.989922900864865450f, + 0.141417563022303130f, -0.989950035541608990f, 0.141227739881770480f, + -0.989977133820719610f, + 0.141037911548697770f, -0.990004195701200910f, 0.140848078030064220f, + -0.990031221182058000f, + 0.140658239332849240f, -0.990058210262297120f, 0.140468395464033110f, + -0.990085162940925970f, + 0.140278546430595420f, -0.990112079216953770f, 0.140088692239516780f, + -0.990138959089390650f, + 0.139898832897777380f, -0.990165802557248400f, 0.139708968412357580f, + -0.990192609619540030f, + 0.139519098790238600f, -0.990219380275280000f, 0.139329224038400980f, + -0.990246114523483990f, + 0.139139344163826280f, -0.990272812363169110f, 0.138949459173495440f, + -0.990299473793353590f, + 0.138759569074390380f, -0.990326098813057330f, 0.138569673873492640f, + -0.990352687421301340f, + 0.138379773577783890f, -0.990379239617108160f, 0.138189868194246640f, + -0.990405755399501260f, + 0.137999957729862760f, -0.990432234767505970f, 0.137810042191615130f, + -0.990458677720148620f, + 0.137620121586486180f, -0.990485084256456980f, 0.137430195921458550f, + -0.990511454375460290f, + 0.137240265203515700f, -0.990537788076188750f, 0.137050329439640380f, + -0.990564085357674370f, + 0.136860388636816430f, -0.990590346218950150f, 0.136670442802027230f, + -0.990616570659050620f, + 0.136480491942256310f, -0.990642758677011570f, 0.136290536064488070f, + -0.990668910271869980f, + 0.136100575175706200f, -0.990695025442664630f, 0.135910609282895440f, + -0.990721104188435180f, + 0.135720638393040080f, -0.990747146508222710f, 0.135530662513124620f, + -0.990773152401069780f, + 0.135340681650134330f, -0.990799121866020370f, 0.135150695811053850f, + -0.990825054902119470f, + 0.134960705002868830f, -0.990850951508413620f, 0.134770709232564290f, + -0.990876811683950810f, + 0.134580708507126220f, -0.990902635427780010f, 0.134390702833540240f, + -0.990928422738951990f, + 0.134200692218792020f, -0.990954173616518500f, 0.134010676669868210f, + -0.990979888059532740f, + 0.133820656193754690f, -0.991005566067049370f, 0.133630630797438390f, + -0.991031207638124130f, + 0.133440600487905820f, -0.991056812771814340f, 0.133250565272143570f, + -0.991082381467178640f, + 0.133060525157139180f, -0.991107913723276780f, 0.132870480149879400f, + -0.991133409539170170f, + 0.132680430257352130f, -0.991158868913921350f, 0.132490375486544710f, + -0.991184291846594180f, + 0.132300315844444680f, -0.991209678336254060f, 0.132110251338040470f, + -0.991235028381967420f, + 0.131920181974319760f, -0.991260341982802440f, 0.131730107760271280f, + -0.991285619137828200f, + 0.131540028702883280f, -0.991310859846115440f, 0.131349944809144220f, + -0.991336064106736140f, + 0.131159856086043410f, -0.991361231918763460f, 0.130969762540569380f, + -0.991386363281272280f, + 0.130779664179711790f, -0.991411458193338540f, 0.130589561010459600f, + -0.991436516654039420f, + 0.130399453039802740f, -0.991461538662453790f, 0.130209340274730770f, + -0.991486524217661480f, + 0.130019222722233350f, -0.991511473318743900f, 0.129829100389301010f, + -0.991536385964783880f, + 0.129638973282923540f, -0.991561262154865290f, 0.129448841410091830f, + -0.991586101888073500f, + 0.129258704777796270f, -0.991610905163495370f, 0.129068563393027410f, + -0.991635671980218740f, + 0.128878417262776660f, -0.991660402337333210f, 0.128688266394034690f, + -0.991685096233929530f, + 0.128498110793793220f, -0.991709753669099530f, 0.128307950469043590f, + -0.991734374641936810f, + 0.128117785426777150f, -0.991758959151536110f, 0.127927615673986190f, + -0.991783507196993490f, + 0.127737441217662280f, -0.991808018777406430f, 0.127547262064798050f, + -0.991832493891873780f, + 0.127357078222385570f, -0.991856932539495360f, 0.127166889697417180f, + -0.991881334719373010f, + 0.126976696496885980f, -0.991905700430609330f, 0.126786498627784430f, + -0.991930029672308480f, + 0.126596296097105960f, -0.991954322443575950f, 0.126406088911843320f, + -0.991978578743518580f, + 0.126215877078990400f, -0.992002798571244520f, 0.126025660605540460f, + -0.992026981925863360f, + 0.125835439498487020f, -0.992051128806485720f, 0.125645213764824380f, + -0.992075239212224070f, + 0.125454983411546210f, -0.992099313142191800f, 0.125264748445647110f, + -0.992123350595503720f, + 0.125074508874121300f, -0.992147351571276090f, 0.124884264703963150f, + -0.992171316068626520f, + 0.124694015942167770f, -0.992195244086673920f, 0.124503762595729650f, + -0.992219135624538450f, + 0.124313504671644300f, -0.992242990681341700f, 0.124123242176906760f, + -0.992266809256206580f, + 0.123932975118512200f, -0.992290591348257370f, 0.123742703503456630f, + -0.992314336956619640f, + 0.123552427338735370f, -0.992338046080420420f, 0.123362146631344750f, + -0.992361718718787870f, + 0.123171861388280650f, -0.992385354870851670f, 0.122981571616539080f, + -0.992408954535742850f, + 0.122791277323116900f, -0.992432517712593550f, 0.122600978515010240f, + -0.992456044400537700f, + 0.122410675199216280f, -0.992479534598709970f, 0.122220367382731500f, + -0.992502988306246950f, + 0.122030055072553410f, -0.992526405522286100f, 0.121839738275679020f, + -0.992549786245966570f, + 0.121649416999105540f, -0.992573130476428810f, 0.121459091249830950f, + -0.992596438212814290f, + 0.121268761034852550f, -0.992619709454266140f, 0.121078426361168710f, + -0.992642944199928820f, + 0.120888087235777220f, -0.992666142448948020f, 0.120697743665676120f, + -0.992689304200470750f, + 0.120507395657864240f, -0.992712429453645460f, 0.120317043219339670f, + -0.992735518207621850f, + 0.120126686357101580f, -0.992758570461551140f, 0.119936325078148620f, + -0.992781586214585570f, + 0.119745959389479630f, -0.992804565465879140f, 0.119555589298094230f, + -0.992827508214586760f, + 0.119365214810991350f, -0.992850414459865100f, 0.119174835935170960f, + -0.992873284200871730f, + 0.118984452677632520f, -0.992896117436765980f, 0.118794065045375670f, + -0.992918914166708300f, + 0.118603673045400840f, -0.992941674389860470f, 0.118413276684707770f, + -0.992964398105385610f, + 0.118222875970297250f, -0.992987085312448390f, 0.118032470909169300f, + -0.993009736010214580f, + 0.117842061508325020f, -0.993032350197851410f, 0.117651647774765000f, + -0.993054927874527320f, + 0.117461229715489990f, -0.993077469039412300f, 0.117270807337501560f, + -0.993099973691677570f, + 0.117080380647800550f, -0.993122441830495580f, 0.116889949653388850f, + -0.993144873455040430f, + 0.116699514361267840f, -0.993167268564487230f, 0.116509074778439050f, + -0.993189627158012620f, + 0.116318630911904880f, -0.993211949234794500f, 0.116128182768666920f, + -0.993234234794012290f, + 0.115937730355727850f, -0.993256483834846440f, 0.115747273680089870f, + -0.993278696356479030f, + 0.115556812748755290f, -0.993300872358093280f, 0.115366347568727250f, + -0.993323011838873950f, + 0.115175878147008180f, -0.993345114798006910f, 0.114985404490601530f, + -0.993367181234679600f, + 0.114794926606510250f, -0.993389211148080650f, 0.114604444501737460f, + -0.993411204537400060f, + 0.114413958183287050f, -0.993433161401829360f, 0.114223467658162260f, + -0.993455081740560960f, + 0.114032972933367300f, -0.993476965552789190f, 0.113842474015905660f, + -0.993498812837709360f, + 0.113651970912781920f, -0.993520623594518090f, 0.113461463631000080f, + -0.993542397822413600f, + 0.113270952177564360f, -0.993564135520595300f, 0.113080436559479720f, + -0.993585836688263950f, + 0.112889916783750470f, -0.993607501324621610f, 0.112699392857381910f, + -0.993629129428871720f, + 0.112508864787378830f, -0.993650721000219120f, 0.112318332580746190f, + -0.993672276037870010f, + 0.112127796244489750f, -0.993693794541031680f, 0.111937255785614560f, + -0.993715276508913230f, + 0.111746711211126660f, -0.993736721940724600f, 0.111556162528031630f, + -0.993758130835677430f, + 0.111365609743335190f, -0.993779503192984580f, 0.111175052864043830f, + -0.993800839011860120f, + 0.110984491897163380f, -0.993822138291519660f, 0.110793926849700630f, + -0.993843401031180180f, + 0.110603357728661910f, -0.993864627230059750f, 0.110412784541053660f, + -0.993885816887378090f, + 0.110222207293883180f, -0.993906970002356060f, 0.110031625994157000f, + -0.993928086574215830f, + 0.109841040648882680f, -0.993949166602181130f, 0.109650451265067080f, + -0.993970210085476920f, + 0.109459857849718030f, -0.993991217023329380f, 0.109269260409842920f, + -0.994012187414966220f, + 0.109078658952449240f, -0.994033121259616400f, 0.108888053484545310f, + -0.994054018556510210f, + 0.108697444013138670f, -0.994074879304879370f, 0.108506830545237980f, + -0.994095703503956930f, + 0.108316213087851300f, -0.994116491152977070f, 0.108125591647986880f, + -0.994137242251175720f, + 0.107934966232653760f, -0.994157956797789730f, 0.107744336848860260f, + -0.994178634792057590f, + 0.107553703503615710f, -0.994199276233218910f, 0.107363066203928920f, + -0.994219881120514850f, + 0.107172424956808870f, -0.994240449453187900f, 0.106981779769265340f, + -0.994260981230481790f, + 0.106791130648307380f, -0.994281476451641550f, 0.106600477600945030f, + -0.994301935115913580f, + 0.106409820634187840f, -0.994322357222545810f, 0.106219159755045520f, + -0.994342742770787270f, + 0.106028494970528530f, -0.994363091759888570f, 0.105837826287646670f, + -0.994383404189101430f, + 0.105647153713410700f, -0.994403680057679100f, 0.105456477254830660f, + -0.994423919364875950f, + 0.105265796918917650f, -0.994444122109948040f, 0.105075112712682180f, + -0.994464288292152390f, + 0.104884424643134970f, -0.994484417910747600f, 0.104693732717287500f, + -0.994504510964993590f, + 0.104503036942150550f, -0.994524567454151740f, 0.104312337324735870f, + -0.994544587377484300f, + 0.104121633872054730f, -0.994564570734255420f, 0.103930926591118540f, + -0.994584517523730340f, + 0.103740215488939480f, -0.994604427745175660f, 0.103549500572529040f, + -0.994624301397859400f, + 0.103358781848899700f, -0.994644138481050710f, 0.103168059325063390f, + -0.994663938994020280f, + 0.102977333008032250f, -0.994683702936040250f, 0.102786602904819150f, + -0.994703430306383860f, + 0.102595869022436280f, -0.994723121104325700f, 0.102405131367896790f, + -0.994742775329142010f, + 0.102214389948213370f, -0.994762392980109930f, 0.102023644770398800f, + -0.994781974056508260f, + 0.101832895841466670f, -0.994801518557617110f, 0.101642143168429830f, + -0.994821026482717860f, + 0.101451386758302160f, -0.994840497831093180f, 0.101260626618096800f, + -0.994859932602027320f, + 0.101069862754827880f, -0.994879330794805620f, 0.100879095175509010f, + -0.994898692408714870f, + 0.100688323887153970f, -0.994918017443043200f, 0.100497548896777310f, + -0.994937305897080070f, + 0.100306770211392820f, -0.994956557770116380f, 0.100115987838015370f, + -0.994975773061444140f, + 0.099925201783659226f, -0.994994951770357020f, 0.099734412055338839f, + -0.995014093896149700f, + 0.099543618660069444f, -0.995033199438118630f, 0.099352821604865513f, + -0.995052268395561160f, + 0.099162020896742573f, -0.995071300767776170f, 0.098971216542715582f, + -0.995090296554063890f, + 0.098780408549799664f, -0.995109255753726110f, 0.098589596925010708f, + -0.995128178366065490f, + 0.098398781675363881f, -0.995147064390386470f, 0.098207962807875346f, + -0.995165913825994620f, + 0.098017140329560770f, -0.995184726672196820f, 0.097826314247435903f, + -0.995203502928301510f, + 0.097635484568517339f, -0.995222242593618240f, 0.097444651299820870f, + -0.995240945667458130f, + 0.097253814448363354f, -0.995259612149133390f, 0.097062974021160875f, + -0.995278242037957670f, + 0.096872130025230527f, -0.995296835333246090f, 0.096681282467588864f, + -0.995315392034315070f, + 0.096490431355252607f, -0.995333912140482280f, 0.096299576695239225f, + -0.995352395651066810f, + 0.096108718494565468f, -0.995370842565388990f, 0.095917856760249096f, + -0.995389252882770690f, + 0.095726991499307315f, -0.995407626602534900f, 0.095536122718757485f, + -0.995425963724006160f, + 0.095345250425617742f, -0.995444264246510340f, 0.095154374626905472f, + -0.995462528169374420f, + 0.094963495329639061f, -0.995480755491926940f, 0.094772612540836410f, + -0.995498946213497770f, + 0.094581726267515473f, -0.995517100333418110f, 0.094390836516695067f, + -0.995535217851020390f, + 0.094199943295393190f, -0.995553298765638470f, 0.094009046610628907f, + -0.995571343076607770f, + 0.093818146469420494f, -0.995589350783264600f, 0.093627242878787237f, + -0.995607321884947050f, + 0.093436335845747912f, -0.995625256380994310f, 0.093245425377321389f, + -0.995643154270746900f, + 0.093054511480527333f, -0.995661015553546910f, 0.092863594162384697f, + -0.995678840228737540f, + 0.092672673429913366f, -0.995696628295663520f, 0.092481749290132753f, + -0.995714379753670610f, + 0.092290821750062355f, -0.995732094602106430f, 0.092099890816722485f, + -0.995749772840319400f, + 0.091908956497132696f, -0.995767414467659820f, 0.091718018798313525f, + -0.995785019483478750f, + 0.091527077727284981f, -0.995802587887129160f, 0.091336133291067212f, + -0.995820119677964910f, + 0.091145185496681130f, -0.995837614855341610f, 0.090954234351146898f, + -0.995855073418615790f, + 0.090763279861485704f, -0.995872495367145730f, 0.090572322034718156f, + -0.995889880700290720f, + 0.090381360877865011f, -0.995907229417411720f, 0.090190396397947820f, + -0.995924541517870690f, + 0.089999428601987341f, -0.995941817001031350f, 0.089808457497005362f, + -0.995959055866258320f, + 0.089617483090022917f, -0.995976258112917790f, 0.089426505388062016f, + -0.995993423740377360f, + 0.089235524398144139f, -0.996010552748005870f, 0.089044540127290905f, + -0.996027645135173610f, + 0.088853552582524684f, -0.996044700901251970f, 0.088662561770867121f, + -0.996061720045614000f, + 0.088471567699340822f, -0.996078702567633980f, 0.088280570374967879f, + -0.996095648466687300f, + 0.088089569804770507f, -0.996112557742151130f, 0.087898565995771685f, + -0.996129430393403740f, + 0.087707558954993645f, -0.996146266419824620f, 0.087516548689459586f, + -0.996163065820794950f, + 0.087325535206192226f, -0.996179828595696870f, 0.087134518512214321f, + -0.996196554743914220f, + 0.086943498614549489f, -0.996213244264832040f, 0.086752475520220515f, + -0.996229897157836500f, + 0.086561449236251239f, -0.996246513422315520f, 0.086370419769664919f, + -0.996263093057658030f, + 0.086179387127484922f, -0.996279636063254650f, 0.085988351316735448f, + -0.996296142438496850f, + 0.085797312344439880f, -0.996312612182778000f, 0.085606270217622613f, + -0.996329045295492380f, + 0.085415224943307277f, -0.996345441776035900f, 0.085224176528518519f, + -0.996361801623805720f, + 0.085033124980280414f, -0.996378124838200210f, 0.084842070305617148f, + -0.996394411418619290f, + 0.084651012511553700f, -0.996410661364464100f, 0.084459951605114297f, + -0.996426874675137240f, + 0.084268887593324127f, -0.996443051350042630f, 0.084077820483207846f, + -0.996459191388585410f, + 0.083886750281790226f, -0.996475294790172160f, 0.083695676996096827f, + -0.996491361554210920f, + 0.083504600633152404f, -0.996507391680110820f, 0.083313521199982740f, + -0.996523385167282450f, + 0.083122438703613077f, -0.996539342015137940f, 0.082931353151068726f, + -0.996555262223090540f, + 0.082740264549375803f, -0.996571145790554840f, 0.082549172905559659f, + -0.996586992716946950f, + 0.082358078226646619f, -0.996602803001684130f, 0.082166980519662466f, + -0.996618576644185070f, + 0.081975879791633108f, -0.996634313643869900f, 0.081784776049585201f, + -0.996650014000160070f, + 0.081593669300544638f, -0.996665677712478160f, 0.081402559551538328f, + -0.996681304780248300f, + 0.081211446809592386f, -0.996696895202896060f, 0.081020331081733912f, + -0.996712448979848010f, + 0.080829212374989468f, -0.996727966110532490f, 0.080638090696385709f, + -0.996743446594378860f, + 0.080446966052950097f, -0.996758890430818000f, 0.080255838451709291f, + -0.996774297619282050f, + 0.080064707899690932f, -0.996789668159204560f, 0.079873574403922148f, + -0.996805002050020320f, + 0.079682437971430126f, -0.996820299291165670f, 0.079491298609242866f, + -0.996835559882078170f, + 0.079300156324387569f, -0.996850783822196610f, 0.079109011123892431f, + -0.996865971110961310f, + 0.078917863014785095f, -0.996881121747813850f, 0.078726712004093313f, + -0.996896235732197210f, + 0.078535558098845590f, -0.996911313063555740f, 0.078344401306069678f, + -0.996926353741335090f, + 0.078153241632794315f, -0.996941357764982160f, 0.077962079086047645f, + -0.996956325133945280f, + 0.077770913672857989f, -0.996971255847674320f, 0.077579745400254363f, + -0.996986149905620180f, + 0.077388574275265049f, -0.997001007307235290f, 0.077197400304919297f, + -0.997015828051973310f, + 0.077006223496245585f, -0.997030612139289450f, 0.076815043856273399f, + -0.997045359568640040f, + 0.076623861392031617f, -0.997060070339482960f, 0.076432676110549283f, + -0.997074744451277310f, + 0.076241488018856149f, -0.997089381903483400f, 0.076050297123981231f, + -0.997103982695563330f, + 0.075859103432954503f, -0.997118546826979980f, 0.075667906952805383f, + -0.997133074297198110f, + 0.075476707690563416f, -0.997147565105683480f, 0.075285505653258880f, + -0.997162019251903290f, + 0.075094300847921291f, -0.997176436735326190f, 0.074903093281581137f, + -0.997190817555421940f, + 0.074711882961268378f, -0.997205161711661850f, 0.074520669894013014f, + -0.997219469203518670f, + 0.074329454086845867f, -0.997233740030466160f, 0.074138235546796952f, + -0.997247974191979860f, + 0.073947014280897269f, -0.997262171687536170f, 0.073755790296177265f, + -0.997276332516613180f, + 0.073564563599667454f, -0.997290456678690210f, 0.073373334198399157f, + -0.997304544173247990f, + 0.073182102099402888f, -0.997318594999768600f, 0.072990867309710133f, + -0.997332609157735470f, + 0.072799629836351618f, -0.997346586646633230f, 0.072608389686359048f, + -0.997360527465947940f, + 0.072417146866763538f, -0.997374431615167030f, 0.072225901384596336f, + -0.997388299093779460f, + 0.072034653246889416f, -0.997402129901275300f, 0.071843402460674000f, + -0.997415924037145960f, + 0.071652149032982254f, -0.997429681500884180f, 0.071460892970845832f, + -0.997443402291984360f, + 0.071269634281296415f, -0.997457086409941910f, 0.071078372971366502f, + -0.997470733854253670f, + 0.070887109048087787f, -0.997484344624417930f, 0.070695842518492924f, + -0.997497918719934210f, + 0.070504573389614009f, -0.997511456140303450f, 0.070313301668483263f, + -0.997524956885027960f, + 0.070122027362133646f, -0.997538420953611230f, 0.069930750477597295f, + -0.997551848345558430f, + 0.069739471021907376f, -0.997565239060375750f, 0.069548189002096472f, + -0.997578593097570800f, + 0.069356904425197236f, -0.997591910456652630f, 0.069165617298243109f, + -0.997605191137131640f, + 0.068974327628266732f, -0.997618435138519550f, 0.068783035422301728f, + -0.997631642460329320f, + 0.068591740687380900f, -0.997644813102075420f, 0.068400443430538069f, + -0.997657947063273710f, + 0.068209143658806454f, -0.997671044343441000f, 0.068017841379219388f, + -0.997684104942096030f, + 0.067826536598810966f, -0.997697128858758500f, 0.067635229324614451f, + -0.997710116092949570f, + 0.067443919563664106f, -0.997723066644191640f, 0.067252607322993652f, + -0.997735980512008620f, + 0.067061292609636836f, -0.997748857695925690f, 0.066869975430628226f, + -0.997761698195469560f, + 0.066678655793001543f, -0.997774502010167820f, 0.066487333703791507f, + -0.997787269139549960f, + 0.066296009170032283f, -0.997799999583146470f, 0.066104682198758091f, + -0.997812693340489280f, + 0.065913352797003930f, -0.997825350411111640f, 0.065722020971803977f, + -0.997837970794548280f, + 0.065530686730193397f, -0.997850554490335110f, 0.065339350079206798f, + -0.997863101498009500f, + 0.065148011025878860f, -0.997875611817110150f, 0.064956669577245010f, + -0.997888085447177110f, + 0.064765325740339871f, -0.997900522387751620f, 0.064573979522199065f, + -0.997912922638376610f, + 0.064382630929857410f, -0.997925286198596000f, 0.064191279970350679f, + -0.997937613067955250f, + 0.063999926650714078f, -0.997949903246001190f, 0.063808570977982898f, + -0.997962156732281950f, + 0.063617212959193190f, -0.997974373526346990f, 0.063425852601380200f, + -0.997986553627747020f, + 0.063234489911580136f, -0.997998697036034390f, 0.063043124896828631f, + -0.998010803750762450f, + 0.062851757564161420f, -0.998022873771486240f, 0.062660387920614985f, + -0.998034907097761770f, + 0.062469015973224969f, -0.998046903729146840f, 0.062277641729028041f, + -0.998058863665200250f, + 0.062086265195060247f, -0.998070786905482340f, 0.061894886378357744f, + -0.998082673449554590f, + 0.061703505285957416f, -0.998094523296980010f, 0.061512121924895365f, + -0.998106336447323050f, + 0.061320736302208648f, -0.998118112900149180f, 0.061129348424933755f, + -0.998129852655025520f, + 0.060937958300107238f, -0.998141555711520520f, 0.060746565934766412f, + -0.998153222069203650f, + 0.060555171335947781f, -0.998164851727646240f, 0.060363774510688827f, + -0.998176444686420530f, + 0.060172375466026218f, -0.998188000945100300f, 0.059980974208997596f, + -0.998199520503260660f, + 0.059789570746640007f, -0.998211003360478190f, 0.059598165085990598f, + -0.998222449516330550f, + 0.059406757234087247f, -0.998233858970396850f, 0.059215347197967026f, + -0.998245231722257880f, + 0.059023934984667986f, -0.998256567771495180f, 0.058832520601227581f, + -0.998267867117692110f, + 0.058641104054683348f, -0.998279129760433200f, 0.058449685352073573f, + -0.998290355699304350f, + 0.058258264500435732f, -0.998301544933892890f, 0.058066841506808263f, + -0.998312697463787260f, + 0.057875416378229017f, -0.998323813288577560f, 0.057683989121735932f, + -0.998334892407855000f, + 0.057492559744367684f, -0.998345934821212370f, 0.057301128253162144f, + -0.998356940528243420f, + 0.057109694655158132f, -0.998367909528543820f, 0.056918258957393907f, + -0.998378841821709990f, + 0.056726821166907783f, -0.998389737407340160f, 0.056535381290738825f, + -0.998400596285033640f, + 0.056343939335925283f, -0.998411418454391300f, 0.056152495309506383f, + -0.998422203915015020f, + 0.055961049218520520f, -0.998432952666508440f, 0.055769601070007072f, + -0.998443664708476340f, + 0.055578150871004817f, -0.998454340040524800f, 0.055386698628552604f, + -0.998464978662261250f, + 0.055195244349690031f, -0.998475580573294770f, 0.055003788041455885f, + -0.998486145773235360f, + 0.054812329710889909f, -0.998496674261694640f, 0.054620869365031251f, + -0.998507166038285490f, + 0.054429407010919147f, -0.998517621102622210f, 0.054237942655593556f, + -0.998528039454320230f, + 0.054046476306093640f, -0.998538421092996730f, 0.053855007969459509f, + -0.998548766018269920f, + 0.053663537652730679f, -0.998559074229759310f, 0.053472065362946755f, + -0.998569345727086110f, + 0.053280591107148056f, -0.998579580509872500f, 0.053089114892374119f, + -0.998589778577742230f, + 0.052897636725665401f, -0.998599939930320370f, 0.052706156614061798f, + -0.998610064567233340f, + 0.052514674564603257f, -0.998620152488108870f, 0.052323190584330471f, + -0.998630203692576050f, + 0.052131704680283317f, -0.998640218180265270f, 0.051940216859502626f, + -0.998650195950808280f, + 0.051748727129028414f, -0.998660137003838490f, 0.051557235495901653f, + -0.998670041338990070f, + 0.051365741967162731f, -0.998679908955899090f, 0.051174246549852087f, + -0.998689739854202620f, + 0.050982749251010900f, -0.998699534033539280f, 0.050791250077679546f, + -0.998709291493549030f, + 0.050599749036899337f, -0.998719012233872940f, 0.050408246135710995f, + -0.998728696254153720f, + 0.050216741381155325f, -0.998738343554035230f, 0.050025234780273840f, + -0.998747954133162860f, + 0.049833726340107257f, -0.998757527991183340f, 0.049642216067697226f, + -0.998767065127744380f, + 0.049450703970084824f, -0.998776565542495610f, 0.049259190054311168f, + -0.998786029235087640f, + 0.049067674327418126f, -0.998795456205172410f, 0.048876156796446746f, + -0.998804846452403420f, + 0.048684637468439020f, -0.998814199976435390f, 0.048493116350436342f, + -0.998823516776924380f, + 0.048301593449480172f, -0.998832796853527990f, 0.048110068772612716f, + -0.998842040205904840f, + 0.047918542326875327f, -0.998851246833715180f, 0.047727014119310344f, + -0.998860416736620520f, + 0.047535484156959261f, -0.998869549914283560f, 0.047343952446864526f, + -0.998878646366368690f, + 0.047152418996068000f, -0.998887706092541290f, 0.046960883811611599f, + -0.998896729092468410f, + 0.046769346900537960f, -0.998905715365818290f, 0.046577808269888908f, + -0.998914664912260440f, + 0.046386267926707213f, -0.998923577731465780f, 0.046194725878035046f, + -0.998932453823106690f, + 0.046003182130914644f, -0.998941293186856870f, 0.045811636692388955f, + -0.998950095822391250f, + 0.045620089569500123f, -0.998958861729386080f, 0.045428540769291224f, + -0.998967590907519300f, + 0.045236990298804750f, -0.998976283356469820f, 0.045045438165083225f, + -0.998984939075918010f, + 0.044853884375169933f, -0.998993558065545680f, 0.044662328936107311f, + -0.999002140325035980f, + 0.044470771854938744f, -0.999010685854073380f, 0.044279213138707016f, + -0.999019194652343460f, + 0.044087652794454979f, -0.999027666719533690f, 0.043896090829226200f, + -0.999036102055332330f, + 0.043704527250063421f, -0.999044500659429290f, 0.043512962064010327f, + -0.999052862531515930f, + 0.043321395278109784f, -0.999061187671284600f, 0.043129826899405595f, + -0.999069476078429330f, + 0.042938256934940959f, -0.999077727752645360f, 0.042746685391759139f, + -0.999085942693629270f, + 0.042555112276904117f, -0.999094120901079070f, 0.042363537597419038f, + -0.999102262374694130f, + 0.042171961360348002f, -0.999110367114174890f, 0.041980383572734502f, + -0.999118435119223490f, + 0.041788804241622082f, -0.999126466389543390f, 0.041597223374055005f, + -0.999134460924839150f, + 0.041405640977076712f, -0.999142418724816910f, 0.041214057057731589f, + -0.999150339789184110f, + 0.041022471623063397f, -0.999158224117649430f, 0.040830884680115968f, + -0.999166071709923000f, + 0.040639296235933854f, -0.999173882565716380f, 0.040447706297560768f, + -0.999181656684742350f, + 0.040256114872041358f, -0.999189394066714920f, 0.040064521966419686f, + -0.999197094711349880f, + 0.039872927587739845f, -0.999204758618363890f, 0.039681331743046659f, + -0.999212385787475290f, + 0.039489734439384118f, -0.999219976218403530f, 0.039298135683797149f, + -0.999227529910869610f, + 0.039106535483329839f, -0.999235046864595850f, 0.038914933845027241f, + -0.999242527079305830f, + 0.038723330775933762f, -0.999249970554724420f, 0.038531726283093877f, + -0.999257377290578060f, + 0.038340120373552791f, -0.999264747286594420f, 0.038148513054354856f, + -0.999272080542502610f, + 0.037956904332545366f, -0.999279377058032710f, 0.037765294215169005f, + -0.999286636832916740f, + 0.037573682709270514f, -0.999293859866887790f, 0.037382069821895340f, + -0.999301046159680070f, + 0.037190455560088091f, -0.999308195711029470f, 0.036998839930894332f, + -0.999315308520673070f, + 0.036807222941358991f, -0.999322384588349540f, 0.036615604598527057f, + -0.999329423913798420f, + 0.036423984909444228f, -0.999336426496761240f, 0.036232363881155374f, + -0.999343392336980220f, + 0.036040741520706299f, -0.999350321434199440f, 0.035849117835142184f, + -0.999357213788164000f, + 0.035657492831508264f, -0.999364069398620550f, 0.035465866516850478f, + -0.999370888265317060f, + 0.035274238898213947f, -0.999377670388002850f, 0.035082609982644702f, + -0.999384415766428560f, + 0.034890979777187955f, -0.999391124400346050f, 0.034699348288889847f, + -0.999397796289508640f, + 0.034507715524795889f, -0.999404431433671300f, 0.034316081491951658f, + -0.999411029832589780f, + 0.034124446197403423f, -0.999417591486021720f, 0.033932809648196623f, + -0.999424116393725640f, + 0.033741171851377642f, -0.999430604555461730f, 0.033549532813992221f, + -0.999437055970991530f, + 0.033357892543086159f, -0.999443470640077770f, 0.033166251045705968f, + -0.999449848562484530f, + 0.032974608328897315f, -0.999456189737977340f, 0.032782964399706793f, + -0.999462494166323160f, + 0.032591319265180385f, -0.999468761847290050f, 0.032399672932364114f, + -0.999474992780647780f, + 0.032208025408304704f, -0.999481186966166950f, 0.032016376700048046f, + -0.999487344403620080f, + 0.031824726814640963f, -0.999493465092780590f, 0.031633075759129645f, + -0.999499549033423640f, + 0.031441423540560343f, -0.999505596225325310f, 0.031249770165979990f, + -0.999511606668263440f, + 0.031058115642434700f, -0.999517580362016990f, 0.030866459976971503f, + -0.999523517306366350f, + 0.030674803176636581f, -0.999529417501093140f, 0.030483145248477058f, + -0.999535280945980540f, + 0.030291486199539423f, -0.999541107640812940f, 0.030099826036870208f, + -0.999546897585375960f, + 0.029908164767516655f, -0.999552650779456990f, 0.029716502398525156f, + -0.999558367222844300f, + 0.029524838936943035f, -0.999564046915327740f, 0.029333174389816984f, + -0.999569689856698580f, + 0.029141508764193740f, -0.999575296046749220f, 0.028949842067120746f, + -0.999580865485273700f, + 0.028758174305644590f, -0.999586398172067070f, 0.028566505486812797f, + -0.999591894106925950f, + 0.028374835617672258f, -0.999597353289648380f, 0.028183164705269902f, + -0.999602775720033530f, + 0.027991492756653365f, -0.999608161397882110f, 0.027799819778869434f, + -0.999613510322995950f, + 0.027608145778965820f, -0.999618822495178640f, 0.027416470763989606f, + -0.999624097914234570f, + 0.027224794740987910f, -0.999629336579970110f, 0.027033117717008563f, + -0.999634538492192300f, + 0.026841439699098527f, -0.999639703650710200f, 0.026649760694305708f, + -0.999644832055333610f, + 0.026458080709677145f, -0.999649923705874240f, 0.026266399752260809f, + -0.999654978602144690f, + 0.026074717829104040f, -0.999659996743959220f, 0.025883034947254208f, + -0.999664978131133310f, + 0.025691351113759395f, -0.999669922763483760f, 0.025499666335666818f, + -0.999674830640828740f, + 0.025307980620024630f, -0.999679701762987930f, 0.025116293973880335f, + -0.999684536129782140f, + 0.024924606404281485f, -0.999689333741033640f, 0.024732917918276334f, + -0.999694094596566000f, + 0.024541228522912264f, -0.999698818696204250f, 0.024349538225237600f, + -0.999703506039774650f, + 0.024157847032300020f, -0.999708156627104880f, 0.023966154951147241f, + -0.999712770458023870f, + 0.023774461988827676f, -0.999717347532362190f, 0.023582768152388880f, + -0.999721887849951310f, + 0.023391073448879338f, -0.999726391410624470f, 0.023199377885346890f, + -0.999730858214216030f, + 0.023007681468839410f, -0.999735288260561680f, 0.022815984206405477f, + -0.999739681549498660f, + 0.022624286105092803f, -0.999744038080865430f, 0.022432587171950024f, + -0.999748357854501780f, + 0.022240887414024919f, -0.999752640870248840f, 0.022049186838366180f, + -0.999756887127949080f, + 0.021857485452021874f, -0.999761096627446610f, 0.021665783262040089f, + -0.999765269368586450f, + 0.021474080275469605f, -0.999769405351215280f, 0.021282376499358355f, + -0.999773504575180990f, + 0.021090671940755180f, -0.999777567040332940f, 0.020898966606708289f, + -0.999781592746521670f, + 0.020707260504265912f, -0.999785581693599210f, 0.020515553640476986f, + -0.999789533881418780f, + 0.020323846022389572f, -0.999793449309835270f, 0.020132137657052664f, + -0.999797327978704690f, + 0.019940428551514598f, -0.999801169887884260f, 0.019748718712823757f, + -0.999804975037232870f, + 0.019557008148029204f, -0.999808743426610520f, 0.019365296864179146f, + -0.999812475055878780f, + 0.019173584868322699f, -0.999816169924900410f, 0.018981872167508348f, + -0.999819828033539420f, + 0.018790158768784596f, -0.999823449381661570f, 0.018598444679200642f, + -0.999827033969133420f, + 0.018406729905804820f, -0.999830581795823400f, 0.018215014455646376f, + -0.999834092861600960f, + 0.018023298335773701f, -0.999837567166337090f, 0.017831581553236088f, + -0.999841004709904000f, + 0.017639864115082195f, -0.999844405492175240f, 0.017448146028360704f, + -0.999847769513025900f, + 0.017256427300120978f, -0.999851096772332190f, 0.017064707937411529f, + -0.999854387269971890f, + 0.016872987947281773f, -0.999857641005823860f, 0.016681267336780482f, + -0.999860857979768540f, + 0.016489546112956454f, -0.999864038191687680f, 0.016297824282859176f, + -0.999867181641464380f, + 0.016106101853537263f, -0.999870288328982950f, 0.015914378832040249f, + -0.999873358254129260f, + 0.015722655225417017f, -0.999876391416790410f, 0.015530931040716478f, + -0.999879387816854930f, + 0.015339206284988220f, -0.999882347454212560f, 0.015147480965280975f, + -0.999885270328754520f, + 0.014955755088644378f, -0.999888156440373320f, 0.014764028662127416f, + -0.999891005788962950f, + 0.014572301692779104f, -0.999893818374418490f, 0.014380574187649138f, + -0.999896594196636680f, + 0.014188846153786343f, -0.999899333255515390f, 0.013997117598240459f, + -0.999902035550953920f, + 0.013805388528060349f, -0.999904701082852900f, 0.013613658950295789f, + -0.999907329851114300f, + 0.013421928871995907f, -0.999909921855641540f, 0.013230198300209845f, + -0.999912477096339240f, + 0.013038467241987433f, -0.999914995573113470f, 0.012846735704377631f, + -0.999917477285871770f, + 0.012655003694430301f, -0.999919922234522750f, 0.012463271219194662f, + -0.999922330418976490f, + 0.012271538285719944f, -0.999924701839144500f, 0.012079804901056066f, + -0.999927036494939640f, + 0.011888071072252072f, -0.999929334386276070f, 0.011696336806357907f, + -0.999931595513069200f, + 0.011504602110422875f, -0.999933819875236000f, 0.011312866991496287f, + -0.999936007472694620f, + 0.011121131456628141f, -0.999938158305364590f, 0.010929395512867561f, + -0.999940272373166960f, + 0.010737659167264572f, -0.999942349676023910f, 0.010545922426868548f, + -0.999944390213859060f, + 0.010354185298728884f, -0.999946393986597460f, 0.010162447789895645f, + -0.999948360994165400f, + 0.009970709907418029f, -0.999950291236490480f, 0.009778971658346134f, + -0.999952184713501780f, + 0.009587233049729183f, -0.999954041425129780f, 0.009395494088617302f, + -0.999955861371306100f, + 0.009203754782059960f, -0.999957644551963900f, 0.009012015137106642f, + -0.999959390967037450f, + 0.008820275160807512f, -0.999961100616462820f, 0.008628534860211857f, + -0.999962773500176930f, + 0.008436794242369860f, -0.999964409618118280f, 0.008245053314331058f, + -0.999966008970226920f, + 0.008053312083144991f, -0.999967571556443780f, 0.007861570555861883f, + -0.999969097376711580f, + 0.007669828739531077f, -0.999970586430974140f, 0.007478086641202815f, + -0.999972038719176730f, + 0.007286344267926684f, -0.999973454241265940f, 0.007094601626752279f, + -0.999974832997189810f, + 0.006902858724729877f, -0.999976174986897610f, 0.006711115568908869f, + -0.999977480210339940f, + 0.006519372166339549f, -0.999978748667468830f, 0.006327628524071549f, + -0.999979980358237650f, + 0.006135884649154515f, -0.999981175282601110f, 0.005944140548638765f, + -0.999982333440515350f, + 0.005752396229573737f, -0.999983454831937730f, 0.005560651699009764f, + -0.999984539456826970f, + 0.005368906963996303f, -0.999985587315143200f, 0.005177162031583702f, + -0.999986598406848000f, + 0.004985416908821652f, -0.999987572731904080f, 0.004793671602759852f, + -0.999988510290275690f, + 0.004601926120448672f, -0.999989411081928400f, 0.004410180468937601f, + -0.999990275106828920f, + 0.004218434655277024f, -0.999991102364945590f, 0.004026688686516664f, + -0.999991892856248010f, + 0.003834942569706248f, -0.999992646580707190f, 0.003643196311896179f, + -0.999993363538295150f, + 0.003451449920135975f, -0.999994043728985820f, 0.003259703401476044f, + -0.999994687152754080f, + 0.003067956762966138f, -0.999995293809576190f, 0.002876210011656010f, + -0.999995863699429940f, + 0.002684463154596083f, -0.999996396822294350f, 0.002492716198835898f, + -0.999996893178149880f, + 0.002300969151425887f, -0.999997352766978210f, 0.002109222019415816f, + -0.999997775588762350f, + 0.001917474809855460f, -0.999998161643486980f, 0.001725727529795258f, + -0.999998510931137790f, + 0.001533980186284766f, -0.999998823451701880f, 0.001342232786374430f, + -0.999999099205167830f, + 0.001150485337113809f, -0.999999338191525530f, 0.000958737845553352f, + -0.999999540410766110f, + 0.000766990318742846f, -0.999999705862882230f, 0.000575242763732077f, + -0.999999834547867670f, + 0.000383495187571497f, -0.999999926465717890f, 0.000191747597310674f, + -0.999999981616429330f +}; + +/** + @par + cosFactor tables are generated using the formula :
cos_factors[n] = 2 * cos((2n+1)*pi/(4*N))
+ @par + C command to generate the table + @par +
 for(i = 0; i< N; i++)
+  {
+     cos_factors[i]= 2 * cos((2*i+1)*c/2);
+  } 
+ @par + where N is the number of factors to generate and c is pi/(2*N) +*/ +static const float32_t cos_factors_128[128] = { + 0.999981175282601110f, 0.999830581795823400f, 0.999529417501093140f, + 0.999077727752645360f, + 0.998475580573294770f, 0.997723066644191640f, 0.996820299291165670f, + 0.995767414467659820f, + 0.994564570734255420f, 0.993211949234794500f, 0.991709753669099530f, + 0.990058210262297120f, + 0.988257567730749460f, 0.986308097244598670f, 0.984210092386929030f, + 0.981963869109555240f, + 0.979569765685440520f, 0.977028142657754390f, 0.974339382785575860f, + 0.971503890986251780f, + 0.968522094274417380f, 0.965394441697689400f, 0.962121404269041580f, + 0.958703474895871600f, + 0.955141168305770780f, 0.951435020969008340f, 0.947585591017741090f, + 0.943593458161960390f, + 0.939459223602189920f, 0.935183509938947610f, 0.930766961078983710f, + 0.926210242138311380f, + 0.921514039342042010f, 0.916679059921042700f, 0.911706032005429880f, + 0.906595704514915330f, + 0.901348847046022030f, 0.895966249756185220f, 0.890448723244757880f, + 0.884797098430937790f, + 0.879012226428633530f, 0.873094978418290090f, 0.867046245515692650f, + 0.860866938637767310f, + 0.854557988365400530f, 0.848120344803297230f, 0.841554977436898440f, + 0.834862874986380010f, + 0.828045045257755800f, 0.821102514991104650f, 0.814036329705948410f, + 0.806847553543799330f, + 0.799537269107905010f, 0.792106577300212390f, 0.784556597155575240f, + 0.776888465673232440f, + 0.769103337645579700f, 0.761202385484261780f, 0.753186799043612520f, + 0.745057785441466060f, + 0.736816568877369900f, 0.728464390448225200f, 0.720002507961381650f, + 0.711432195745216430f, + 0.702754744457225300f, 0.693971460889654000f, 0.685083667772700360f, + 0.676092703575316030f, + 0.666999922303637470f, 0.657806693297078640f, 0.648514401022112550f, + 0.639124444863775730f, + 0.629638238914927100f, 0.620057211763289210f, 0.610382806276309480f, + 0.600616479383868970f, + 0.590759701858874280f, 0.580813958095764530f, 0.570780745886967370f, + 0.560661576197336030f, + 0.550457972936604810f, 0.540171472729892970f, 0.529803624686294830f, + 0.519355990165589530f, + 0.508830142543106990f, 0.498227666972781870f, 0.487550160148436050f, + 0.476799230063322250f, + 0.465976495767966130f, 0.455083587126343840f, 0.444122144570429260f, + 0.433093818853152010f, + 0.422000270799799790f, 0.410843171057903910f, 0.399624199845646790f, + 0.388345046698826300f, + 0.377007410216418310f, 0.365612997804773960f, 0.354163525420490510f, + 0.342660717311994380f, + 0.331106305759876430f, 0.319502030816015750f, 0.307849640041534980f, + 0.296150888243623960f, + 0.284407537211271820f, 0.272621355449948980f, 0.260794117915275570f, + 0.248927605745720260f, + 0.237023605994367340f, 0.225083911359792780f, 0.213110319916091360f, + 0.201104634842091960f, + 0.189068664149806280f, 0.177004220412148860f, 0.164913120489970090f, + 0.152797185258443410f, + 0.140658239332849240f, 0.128498110793793220f, 0.116318630911904880f, + 0.104121633872054730f, + 0.091908956497132696f, 0.079682437971430126f, 0.067443919563664106f, + 0.055195244349690031f, + 0.042938256934940959f, 0.030674803176636581f, 0.018406729905804820f, + 0.006135884649154515f +}; + +static const float32_t cos_factors_512[512] = { + 0.999998823451701880f, 0.999989411081928400f, 0.999970586430974140f, + 0.999942349676023910f, + 0.999904701082852900f, 0.999857641005823860f, 0.999801169887884260f, + 0.999735288260561680f, + 0.999659996743959220f, 0.999575296046749220f, 0.999481186966166950f, + 0.999377670388002850f, + 0.999264747286594420f, 0.999142418724816910f, 0.999010685854073380f, + 0.998869549914283560f, + 0.998719012233872940f, 0.998559074229759310f, 0.998389737407340160f, + 0.998211003360478190f, + 0.998022873771486240f, 0.997825350411111640f, 0.997618435138519550f, + 0.997402129901275300f, + 0.997176436735326190f, 0.996941357764982160f, 0.996696895202896060f, + 0.996443051350042630f, + 0.996179828595696980f, 0.995907229417411720f, 0.995625256380994310f, + 0.995333912140482280f, + 0.995033199438118630f, 0.994723121104325700f, 0.994403680057679100f, + 0.994074879304879370f, + 0.993736721940724600f, 0.993389211148080650f, 0.993032350197851410f, + 0.992666142448948020f, + 0.992290591348257370f, 0.991905700430609330f, 0.991511473318743900f, + 0.991107913723276890f, + 0.990695025442664630f, 0.990272812363169110f, 0.989841278458820530f, + 0.989400427791380380f, + 0.988950264510302990f, 0.988490792852696590f, 0.988022017143283530f, + 0.987543941794359230f, + 0.987056571305750970f, 0.986559910264775410f, 0.986053963346195440f, + 0.985538735312176060f, + 0.985014231012239840f, 0.984480455383220930f, 0.983937413449218920f, + 0.983385110321551180f, + 0.982823551198705240f, 0.982252741366289370f, 0.981672686196983110f, + 0.981083391150486710f, + 0.980484861773469380f, 0.979877103699517640f, 0.979260122649082020f, + 0.978633924429423210f, + 0.977998514934557140f, 0.977353900145199960f, 0.976700086128711840f, + 0.976037079039039020f, + 0.975364885116656980f, 0.974683510688510670f, 0.973992962167955830f, + 0.973293246054698250f, + 0.972584368934732210f, 0.971866337480279400f, 0.971139158449725090f, + 0.970402838687555500f, + 0.969657385124292450f, 0.968902804776428870f, 0.968139104746362440f, + 0.967366292222328510f, + 0.966584374478333120f, 0.965793358874083680f, 0.964993252854920320f, + 0.964184063951745830f, + 0.963365799780954050f, 0.962538468044359160f, 0.961702076529122540f, + 0.960856633107679660f, + 0.960002145737665960f, 0.959138622461841890f, 0.958266071408017670f, + 0.957384500788975860f, + 0.956493918902395100f, 0.955594334130771110f, 0.954685754941338340f, + 0.953768189885990330f, + 0.952841647601198720f, 0.951906136807932350f, 0.950961666311575080f, + 0.950008245001843000f, + 0.949045881852700560f, 0.948074585922276230f, 0.947094366352777220f, + 0.946105232370403450f, + 0.945107193285260610f, 0.944100258491272660f, 0.943084437466093490f, + 0.942059739771017310f, + 0.941026175050889260f, 0.939983753034014050f, 0.938932483532064600f, + 0.937872376439989890f, + 0.936803441735921560f, 0.935725689481080370f, 0.934639129819680780f, + 0.933543772978836170f, + 0.932439629268462360f, 0.931326709081180430f, 0.930205022892219070f, + 0.929074581259315860f, + 0.927935394822617890f, 0.926787474304581750f, 0.925630830509872720f, + 0.924465474325262600f, + 0.923291416719527640f, 0.922108668743345180f, 0.920917241529189520f, + 0.919717146291227360f, + 0.918508394325212250f, 0.917290997008377910f, 0.916064965799331720f, + 0.914830312237946200f, + 0.913587047945250810f, 0.912335184623322750f, 0.911074734055176360f, + 0.909805708104652220f, + 0.908528118716306120f, 0.907241977915295820f, 0.905947297807268460f, + 0.904644090578246240f, + 0.903332368494511820f, 0.902012143902493180f, 0.900683429228646970f, + 0.899346236979341570f, + 0.898000579740739880f, 0.896646470178680150f, 0.895283921038557580f, + 0.893912945145203250f, + 0.892533555402764580f, 0.891145764794583180f, 0.889749586383072780f, + 0.888345033309596350f, + 0.886932118794342190f, 0.885510856136199950f, 0.884081258712634990f, + 0.882643339979562790f, + 0.881197113471222090f, 0.879742592800047410f, 0.878279791656541580f, + 0.876808723809145650f, + 0.875329403104110890f, 0.873841843465366860f, 0.872346058894391540f, + 0.870842063470078980f, + 0.869329871348606840f, 0.867809496763303320f, 0.866280954024512990f, + 0.864744257519462380f, + 0.863199421712124160f, 0.861646461143081300f, 0.860085390429390140f, + 0.858516224264442740f, + 0.856938977417828760f, 0.855353664735196030f, 0.853760301138111410f, + 0.852158901623919830f, + 0.850549481265603480f, 0.848932055211639610f, 0.847306638685858320f, + 0.845673246987299070f, + 0.844031895490066410f, 0.842382599643185850f, 0.840725374970458070f, + 0.839060237070312740f, + 0.837387201615661940f, 0.835706284353752600f, 0.834017501106018130f, + 0.832320867767929680f, + 0.830616400308846310f, 0.828904114771864870f, 0.827184027273669130f, + 0.825456154004377550f, + 0.823720511227391430f, 0.821977115279241550f, 0.820225982569434690f, + 0.818467129580298660f, + 0.816700572866827850f, 0.814926329056526620f, 0.813144414849253590f, + 0.811354847017063730f, + 0.809557642404051260f, 0.807752817926190360f, 0.805940390571176280f, + 0.804120377398265810f, + 0.802292795538115720f, 0.800457662192622820f, 0.798614994634760820f, + 0.796764810208418830f, + 0.794907126328237010f, 0.793041960479443640f, 0.791169330217690200f, + 0.789289253168885650f, + 0.787401747029031430f, 0.785506829564053930f, 0.783604518609638200f, + 0.781694832071059390f, + 0.779777787923014550f, 0.777853404209453150f, 0.775921699043407690f, + 0.773982690606822900f, + 0.772036397150384520f, 0.770082836993347900f, 0.768122028523365420f, + 0.766153990196312920f, + 0.764178740536116670f, 0.762196298134578900f, 0.760206681651202420f, + 0.758209909813015280f, + 0.756206001414394540f, 0.754194975316889170f, 0.752176850449042810f, + 0.750151645806215070f, + 0.748119380450403600f, 0.746080073510063780f, 0.744033744179929290f, + 0.741980411720831070f, + 0.739920095459516200f, 0.737852814788465980f, 0.735778589165713590f, + 0.733697438114660370f, + 0.731609381223892630f, 0.729514438146997010f, 0.727412628602375770f, + 0.725303972373060770f, + 0.723188489306527460f, 0.721066199314508110f, 0.718937122372804490f, + 0.716801278521099540f, + 0.714658687862769090f, 0.712509370564692320f, 0.710353346857062420f, + 0.708190637033195400f, + 0.706021261449339740f, 0.703845240524484940f, 0.701662594740168570f, + 0.699473344640283770f, + 0.697277510830886630f, 0.695075113980000880f, 0.692866174817424740f, + 0.690650714134534720f, + 0.688428752784090550f, 0.686200311680038700f, 0.683965411797315510f, + 0.681724074171649820f, + 0.679476319899365080f, 0.677222170137180450f, 0.674961646102012040f, + 0.672694769070772970f, + 0.670421560380173090f, 0.668142041426518560f, 0.665856233665509720f, + 0.663564158612039880f, + 0.661265837839992270f, 0.658961292982037320f, 0.656650545729429050f, + 0.654333617831800550f, + 0.652010531096959500f, 0.649681307390683190f, 0.647345968636512060f, + 0.645004536815544040f, + 0.642657033966226860f, 0.640303482184151670f, 0.637943903621844170f, + 0.635578320488556230f, + 0.633206755050057190f, 0.630829229628424470f, 0.628445766601832710f, + 0.626056388404343520f, + 0.623661117525694640f, 0.621259976511087660f, 0.618852987960976320f, + 0.616440174530853650f, + 0.614021558931038490f, 0.611597163926462020f, 0.609167012336453210f, + 0.606731127034524480f, + 0.604289530948156070f, 0.601842247058580030f, 0.599389298400564540f, + 0.596930708062196500f, + 0.594466499184664540f, 0.591996694962040990f, 0.589521318641063940f, + 0.587040393520918080f, + 0.584553942953015330f, 0.582061990340775550f, 0.579564559139405740f, + 0.577061672855679550f, + 0.574553355047715760f, 0.572039629324757050f, 0.569520519346947250f, + 0.566996048825108680f, + 0.564466241520519500f, 0.561931121244689470f, 0.559390711859136140f, + 0.556845037275160100f, + 0.554294121453620110f, 0.551737988404707450f, 0.549176662187719770f, + 0.546610166910834860f, + 0.544038526730883930f, 0.541461765853123560f, 0.538879908531008420f, + 0.536292979065963180f, + 0.533701001807152960f, 0.531104001151255000f, 0.528502001542228480f, + 0.525895027471084740f, + 0.523283103475656430f, 0.520666254140367270f, 0.518044504095999340f, + 0.515417878019463150f, + 0.512786400633563070f, 0.510150096706766700f, 0.507508991052970870f, + 0.504863108531267480f, + 0.502212474045710900f, 0.499557112545081890f, 0.496897049022654640f, + 0.494232308515959730f, + 0.491562916106550060f, 0.488888896919763230f, 0.486210276124486530f, + 0.483527078932918740f, + 0.480839330600333900f, 0.478147056424843120f, 0.475450281747155870f, + 0.472749031950342900f, + 0.470043332459595620f, 0.467333208741988530f, 0.464618686306237820f, + 0.461899790702462840f, + 0.459176547521944150f, 0.456448982396883860f, 0.453717121000163930f, + 0.450980989045103810f, + 0.448240612285220000f, 0.445496016513981740f, 0.442747227564570130f, + 0.439994271309633260f, + 0.437237173661044200f, 0.434475960569655710f, 0.431710658025057370f, + 0.428941292055329550f, + 0.426167888726799620f, 0.423390474143796100f, 0.420609074448402510f, + 0.417823715820212380f, + 0.415034424476081630f, 0.412241226669883000f, 0.409444148692257590f, + 0.406643216870369140f, + 0.403838457567654130f, 0.401029897183575790f, 0.398217562153373620f, + 0.395401478947816300f, + 0.392581674072951530f, 0.389758174069856410f, 0.386931005514388690f, + 0.384100195016935040f, + 0.381265769222162490f, 0.378427754808765620f, 0.375586178489217330f, + 0.372741067009515810f, + 0.369892447148934270f, 0.367040345719767240f, 0.364184789567079840f, + 0.361325805568454340f, + 0.358463420633736540f, 0.355597661704783960f, 0.352728555755210730f, + 0.349856129790135030f, + 0.346980410845923680f, 0.344101425989938980f, 0.341219202320282410f, + 0.338333766965541290f, + 0.335445147084531660f, 0.332553369866044220f, 0.329658462528587550f, + 0.326760452320131790f, + 0.323859366517852960f, 0.320955232427875210f, 0.318048077385015060f, + 0.315137928752522440f, + 0.312224813921825050f, 0.309308760312268780f, 0.306389795370861080f, + 0.303467946572011370f, + 0.300543241417273400f, 0.297615707435086310f, 0.294685372180514330f, + 0.291752263234989370f, + 0.288816408206049480f, 0.285877834727080730f, 0.282936570457055390f, + 0.279992643080273380f, + 0.277046080306099950f, 0.274096909868706330f, 0.271145159526808070f, + 0.268190857063403180f, + 0.265234030285511900f, 0.262274707023913590f, 0.259312915132886350f, + 0.256348682489942910f, + 0.253382036995570270f, 0.250413006572965280f, 0.247441619167773440f, + 0.244467902747824210f, + 0.241491885302869300f, 0.238513594844318500f, 0.235533059404975460f, + 0.232550307038775330f, + 0.229565365820518870f, 0.226578263845610110f, 0.223589029229790020f, + 0.220597690108873650f, + 0.217604274638483670f, 0.214608810993786920f, 0.211611327369227610f, + 0.208611851978263460f, + 0.205610413053099320f, 0.202607038844421110f, 0.199601757621131050f, + 0.196594597670080220f, + 0.193585587295803750f, 0.190574754820252800f, 0.187562128582529740f, + 0.184547736938619640f, + 0.181531608261125130f, 0.178513770938997590f, 0.175494253377271400f, + 0.172473083996796030f, + 0.169450291233967930f, 0.166425903540464220f, 0.163399949382973230f, + 0.160372457242928400f, + 0.157343455616238280f, 0.154312973013020240f, 0.151281037957330250f, + 0.148247678986896200f, + 0.145212924652847520f, 0.142176803519448000f, 0.139139344163826280f, + 0.136100575175706200f, + 0.133060525157139180f, 0.130019222722233350f, 0.126976696496885980f, + 0.123932975118512200f, + 0.120888087235777220f, 0.117842061508325020f, 0.114794926606510250f, + 0.111746711211126660f, + 0.108697444013138670f, 0.105647153713410700f, 0.102595869022436280f, + 0.099543618660069444f, + 0.096490431355252607f, 0.093436335845747912f, 0.090381360877865011f, + 0.087325535206192226f, + 0.084268887593324127f, 0.081211446809592386f, 0.078153241632794315f, + 0.075094300847921291f, + 0.072034653246889416f, 0.068974327628266732f, 0.065913352797003930f, + 0.062851757564161420f, + 0.059789570746640007f, 0.056726821166907783f, 0.053663537652730679f, + 0.050599749036899337f, + 0.047535484156959261f, 0.044470771854938744f, 0.041405640977076712f, + 0.038340120373552791f, + 0.035274238898213947f, 0.032208025408304704f, 0.029141508764193740f, + 0.026074717829104040f, + 0.023007681468839410f, 0.019940428551514598f, 0.016872987947281773f, + 0.013805388528060349f, + 0.010737659167264572f, 0.007669828739531077f, 0.004601926120448672f, + 0.001533980186284766f +}; + +static const float32_t cos_factors_2048[2048] = { + 0.999999926465717890f, 0.999999338191525530f, 0.999998161643486980f, + 0.999996396822294350f, + 0.999994043728985820f, 0.999991102364945590f, 0.999987572731904080f, + 0.999983454831937730f, + 0.999978748667468830f, 0.999973454241265940f, 0.999967571556443780f, + 0.999961100616462820f, + 0.999954041425129780f, 0.999946393986597460f, 0.999938158305364590f, + 0.999929334386276070f, + 0.999919922234522750f, 0.999909921855641540f, 0.999899333255515390f, + 0.999888156440373320f, + 0.999876391416790410f, 0.999864038191687680f, 0.999851096772332190f, + 0.999837567166337090f, + 0.999823449381661570f, 0.999808743426610520f, 0.999793449309835270f, + 0.999777567040332940f, + 0.999761096627446610f, 0.999744038080865430f, 0.999726391410624470f, + 0.999708156627104880f, + 0.999689333741033640f, 0.999669922763483760f, 0.999649923705874240f, + 0.999629336579970110f, + 0.999608161397882110f, 0.999586398172067070f, 0.999564046915327740f, + 0.999541107640812940f, + 0.999517580362016990f, 0.999493465092780590f, 0.999468761847290050f, + 0.999443470640077770f, + 0.999417591486021720f, 0.999391124400346050f, 0.999364069398620550f, + 0.999336426496761240f, + 0.999308195711029470f, 0.999279377058032710f, 0.999249970554724420f, + 0.999219976218403530f, + 0.999189394066714920f, 0.999158224117649430f, 0.999126466389543390f, + 0.999094120901079070f, + 0.999061187671284600f, 0.999027666719533690f, 0.998993558065545680f, + 0.998958861729386080f, + 0.998923577731465780f, 0.998887706092541290f, 0.998851246833715180f, + 0.998814199976435390f, + 0.998776565542495610f, 0.998738343554035230f, 0.998699534033539280f, + 0.998660137003838490f, + 0.998620152488108870f, 0.998579580509872500f, 0.998538421092996730f, + 0.998496674261694640f, + 0.998454340040524800f, 0.998411418454391300f, 0.998367909528543820f, + 0.998323813288577560f, + 0.998279129760433200f, 0.998233858970396850f, 0.998188000945100300f, + 0.998141555711520520f, + 0.998094523296980010f, 0.998046903729146840f, 0.997998697036034390f, + 0.997949903246001190f, + 0.997900522387751620f, 0.997850554490335110f, 0.997799999583146470f, + 0.997748857695925690f, + 0.997697128858758500f, 0.997644813102075420f, 0.997591910456652630f, + 0.997538420953611340f, + 0.997484344624417930f, 0.997429681500884180f, 0.997374431615167150f, + 0.997318594999768600f, + 0.997262171687536170f, 0.997205161711661850f, 0.997147565105683480f, + 0.997089381903483400f, + 0.997030612139289450f, 0.996971255847674320f, 0.996911313063555740f, + 0.996850783822196610f, + 0.996789668159204560f, 0.996727966110532490f, 0.996665677712478160f, + 0.996602803001684130f, + 0.996539342015137940f, 0.996475294790172160f, 0.996410661364464100f, + 0.996345441776035900f, + 0.996279636063254650f, 0.996213244264832040f, 0.996146266419824620f, + 0.996078702567633980f, + 0.996010552748005870f, 0.995941817001031350f, 0.995872495367145730f, + 0.995802587887129160f, + 0.995732094602106430f, 0.995661015553546910f, 0.995589350783264600f, + 0.995517100333418110f, + 0.995444264246510340f, 0.995370842565388990f, 0.995296835333246090f, + 0.995222242593618360f, + 0.995147064390386470f, 0.995071300767776170f, 0.994994951770357020f, + 0.994918017443043200f, + 0.994840497831093180f, 0.994762392980109930f, 0.994683702936040250f, + 0.994604427745175660f, + 0.994524567454151740f, 0.994444122109948040f, 0.994363091759888570f, + 0.994281476451641550f, + 0.994199276233218910f, 0.994116491152977070f, 0.994033121259616400f, + 0.993949166602181130f, + 0.993864627230059750f, 0.993779503192984580f, 0.993693794541031790f, + 0.993607501324621610f, + 0.993520623594518090f, 0.993433161401829360f, 0.993345114798006910f, + 0.993256483834846440f, + 0.993167268564487230f, 0.993077469039412300f, 0.992987085312448390f, + 0.992896117436765980f, + 0.992804565465879140f, 0.992712429453645460f, 0.992619709454266140f, + 0.992526405522286100f, + 0.992432517712593660f, 0.992338046080420420f, 0.992242990681341700f, + 0.992147351571276090f, + 0.992051128806485720f, 0.991954322443575950f, 0.991856932539495470f, + 0.991758959151536110f, + 0.991660402337333210f, 0.991561262154865290f, 0.991461538662453790f, + 0.991361231918763460f, + 0.991260341982802440f, 0.991158868913921350f, 0.991056812771814340f, + 0.990954173616518500f, + 0.990850951508413620f, 0.990747146508222710f, 0.990642758677011570f, + 0.990537788076188750f, + 0.990432234767505970f, 0.990326098813057330f, 0.990219380275280000f, + 0.990112079216953770f, + 0.990004195701200910f, 0.989895729791486660f, 0.989786681551618640f, + 0.989677051045747210f, + 0.989566838338365120f, 0.989456043494307710f, 0.989344666578752640f, + 0.989232707657220050f, + 0.989120166795572690f, 0.989007044060015270f, 0.988893339517095130f, + 0.988779053233701520f, + 0.988664185277066230f, 0.988548735714763200f, 0.988432704614708340f, + 0.988316092045159690f, + 0.988198898074717610f, 0.988081122772324070f, 0.987962766207263420f, + 0.987843828449161740f, + 0.987724309567986960f, 0.987604209634049160f, 0.987483528717999710f, + 0.987362266890832400f, + 0.987240424223882250f, 0.987118000788826280f, 0.986994996657682980f, + 0.986871411902812470f, + 0.986747246596916590f, 0.986622500813038480f, 0.986497174624562880f, + 0.986371268105216030f, + 0.986244781329065460f, 0.986117714370520090f, 0.985990067304330140f, + 0.985861840205586980f, + 0.985733033149723490f, 0.985603646212513400f, 0.985473679470071810f, + 0.985343132998854790f, + 0.985212006875659350f, 0.985080301177623800f, 0.984948015982227030f, + 0.984815151367289140f, + 0.984681707410970940f, 0.984547684191773960f, 0.984413081788540700f, + 0.984277900280454370f, + 0.984142139747038570f, 0.984005800268157870f, 0.983868881924017220f, + 0.983731384795162090f, + 0.983593308962478650f, 0.983454654507193270f, 0.983315421510872810f, + 0.983175610055424420f, + 0.983035220223095640f, 0.982894252096474070f, 0.982752705758487830f, + 0.982610581292404750f, + 0.982467878781833170f, 0.982324598310721280f, 0.982180739963357090f, + 0.982036303824369020f, + 0.981891289978725100f, 0.981745698511732990f, 0.981599529509040720f, + 0.981452783056635520f, + 0.981305459240844670f, 0.981157558148334830f, 0.981009079866112630f, + 0.980860024481523870f, + 0.980710392082253970f, 0.980560182756327840f, 0.980409396592109910f, + 0.980258033678303550f, + 0.980106094103951770f, 0.979953577958436740f, 0.979800485331479790f, + 0.979646816313141210f, + 0.979492570993820810f, 0.979337749464256780f, 0.979182351815526930f, + 0.979026378139047580f, + 0.978869828526574120f, 0.978712703070200420f, 0.978555001862359550f, + 0.978396724995823090f, + 0.978237872563701090f, 0.978078444659442380f, 0.977918441376834370f, + 0.977757862810002760f, + 0.977596709053411890f, 0.977434980201864260f, 0.977272676350500860f, + 0.977109797594800880f, + 0.976946344030581670f, 0.976782315753998650f, 0.976617712861545640f, + 0.976452535450054060f, + 0.976286783616693630f, 0.976120457458971910f, 0.975953557074734300f, + 0.975786082562163930f, + 0.975618034019781750f, 0.975449411546446380f, 0.975280215241354220f, + 0.975110445204038890f, + 0.974940101534371830f, 0.974769184332561770f, 0.974597693699155050f, + 0.974425629735034990f, + 0.974252992541422500f, 0.974079782219875680f, 0.973905998872289570f, + 0.973731642600896400f, + 0.973556713508265560f, 0.973381211697303290f, 0.973205137271252800f, + 0.973028490333694210f, + 0.972851270988544180f, 0.972673479340056430f, 0.972495115492821190f, + 0.972316179551765300f, + 0.972136671622152230f, 0.971956591809581720f, 0.971775940219990140f, + 0.971594716959650160f, + 0.971412922135170940f, 0.971230555853497380f, 0.971047618221911100f, + 0.970864109348029470f, + 0.970680029339806130f, 0.970495378305530560f, 0.970310156353828110f, + 0.970124363593660280f, + 0.969938000134323960f, 0.969751066085452140f, 0.969563561557013180f, + 0.969375486659311280f, + 0.969186841502985950f, 0.968997626199012420f, 0.968807840858700970f, + 0.968617485593697540f, + 0.968426560515983190f, 0.968235065737874320f, 0.968043001372022260f, + 0.967850367531413620f, + 0.967657164329369880f, 0.967463391879547550f, 0.967269050295937790f, + 0.967074139692867040f, + 0.966878660184995910f, 0.966682611887320080f, 0.966485994915169840f, + 0.966288809384209690f, + 0.966091055410438830f, 0.965892733110190860f, 0.965693842600133690f, + 0.965494383997269500f, + 0.965294357418934660f, 0.965093762982799590f, 0.964892600806868890f, + 0.964690871009481030f, + 0.964488573709308410f, 0.964285709025357480f, 0.964082277076968140f, + 0.963878277983814200f, + 0.963673711865903230f, 0.963468578843575950f, 0.963262879037507070f, + 0.963056612568704340f, + 0.962849779558509030f, 0.962642380128595710f, 0.962434414400972100f, + 0.962225882497979020f, + 0.962016784542290560f, 0.961807120656913540f, 0.961596890965187860f, + 0.961386095590786250f, + 0.961174734657714080f, 0.960962808290309780f, 0.960750316613243950f, + 0.960537259751520050f, + 0.960323637830473920f, 0.960109450975773940f, 0.959894699313420530f, + 0.959679382969746750f, + 0.959463502071417510f, 0.959247056745430090f, 0.959030047119113660f, + 0.958812473320129310f, + 0.958594335476470220f, 0.958375633716461170f, 0.958156368168758820f, + 0.957936538962351420f, + 0.957716146226558870f, 0.957495190091032570f, 0.957273670685755200f, + 0.957051588141040970f, + 0.956828942587535370f, 0.956605734156215080f, 0.956381962978387730f, + 0.956157629185692140f, + 0.955932732910098280f, 0.955707274283906560f, 0.955481253439748770f, + 0.955254670510586990f, + 0.955027525629714160f, 0.954799818930753720f, 0.954571550547659630f, + 0.954342720614716480f, + 0.954113329266538800f, 0.953883376638071770f, 0.953652862864590500f, + 0.953421788081700310f, + 0.953190152425336670f, 0.952957956031764700f, 0.952725199037579570f, + 0.952491881579706320f, + 0.952258003795399600f, 0.952023565822243570f, 0.951788567798152130f, + 0.951553009861368590f, + 0.951316892150465550f, 0.951080214804345010f, 0.950842977962238160f, + 0.950605181763705340f, + 0.950366826348635780f, 0.950127911857248100f, 0.949888438430089300f, + 0.949648406208035480f, + 0.949407815332291570f, 0.949166665944390700f, 0.948924958186195160f, + 0.948682692199895090f, + 0.948439868128009620f, 0.948196486113385580f, 0.947952546299198670f, + 0.947708048828952100f, + 0.947462993846477700f, 0.947217381495934820f, 0.946971211921810880f, + 0.946724485268921170f, + 0.946477201682408680f, 0.946229361307743820f, 0.945980964290724760f, + 0.945732010777477150f, + 0.945482500914453740f, 0.945232434848435000f, 0.944981812726528150f, + 0.944730634696167800f, + 0.944478900905115550f, 0.944226611501459810f, 0.943973766633615980f, + 0.943720366450326200f, + 0.943466411100659320f, 0.943211900734010620f, 0.942956835500102120f, + 0.942701215548981900f, + 0.942445041031024890f, 0.942188312096931770f, 0.941931028897729620f, + 0.941673191584771360f, + 0.941414800309736340f, 0.941155855224629190f, 0.940896356481780830f, + 0.940636304233847590f, + 0.940375698633811540f, 0.940114539834980280f, 0.939852827990986680f, + 0.939590563255789270f, + 0.939327745783671400f, 0.939064375729241950f, 0.938800453247434770f, + 0.938535978493508560f, + 0.938270951623047190f, 0.938005372791958840f, 0.937739242156476970f, + 0.937472559873159250f, + 0.937205326098887960f, 0.936937540990869900f, 0.936669204706636170f, + 0.936400317404042060f, + 0.936130879241267030f, 0.935860890376814640f, 0.935590350969512370f, + 0.935319261178511610f, + 0.935047621163287430f, 0.934775431083638700f, 0.934502691099687870f, + 0.934229401371880820f, + 0.933955562060986730f, 0.933681173328098410f, 0.933406235334631520f, + 0.933130748242325230f, + 0.932854712213241120f, 0.932578127409764420f, 0.932300993994602760f, + 0.932023312130786490f, + 0.931745081981668720f, 0.931466303710925090f, 0.931186977482553750f, + 0.930907103460875130f, + 0.930626681810531760f, 0.930345712696488470f, 0.930064196284032360f, + 0.929782132738772190f, + 0.929499522226638560f, 0.929216364913884040f, 0.928932660967082820f, + 0.928648410553130520f, + 0.928363613839244370f, 0.928078270992963140f, 0.927792382182146320f, + 0.927505947574975180f, + 0.927218967339951790f, 0.926931441645899130f, 0.926643370661961230f, + 0.926354754557602860f, + 0.926065593502609310f, 0.925775887667086740f, 0.925485637221461490f, + 0.925194842336480530f, + 0.924903503183210910f, 0.924611619933039970f, 0.924319192757675160f, + 0.924026221829143850f, + 0.923732707319793290f, 0.923438649402290370f, 0.923144048249621930f, + 0.922848904035094120f, + 0.922553216932332830f, 0.922256987115283030f, 0.921960214758209220f, + 0.921662900035694730f, + 0.921365043122642340f, 0.921066644194273640f, 0.920767703426128790f, + 0.920468220994067110f, + 0.920168197074266340f, 0.919867631843222950f, 0.919566525477751530f, + 0.919264878154985370f, + 0.918962690052375630f, 0.918659961347691900f, 0.918356692219021720f, + 0.918052882844770380f, + 0.917748533403661250f, 0.917443644074735220f, 0.917138215037350710f, + 0.916832246471183890f, + 0.916525738556228210f, 0.916218691472794220f, 0.915911105401509880f, + 0.915602980523320230f, + 0.915294317019487050f, 0.914985115071589310f, 0.914675374861522390f, + 0.914365096571498560f, + 0.914054280384046570f, 0.913742926482011390f, 0.913431035048554720f, + 0.913118606267154240f, + 0.912805640321603500f, 0.912492137396012650f, 0.912178097674807180f, + 0.911863521342728520f, + 0.911548408584833990f, 0.911232759586496190f, 0.910916574533403360f, + 0.910599853611558930f, + 0.910282597007281760f, 0.909964804907205660f, 0.909646477498279540f, + 0.909327614967767260f, + 0.909008217503247450f, 0.908688285292613360f, 0.908367818524072890f, + 0.908046817386148340f, + 0.907725282067676440f, 0.907403212757808110f, 0.907080609646008450f, + 0.906757472922056550f, + 0.906433802776045460f, 0.906109599398381980f, 0.905784862979786550f, + 0.905459593711293250f, + 0.905133791784249690f, 0.904807457390316540f, 0.904480590721468250f, + 0.904153191969991780f, + 0.903825261328487510f, 0.903496798989868450f, 0.903167805147360720f, + 0.902838279994502830f, + 0.902508223725145940f, 0.902177636533453620f, 0.901846518613901750f, + 0.901514870161278740f, + 0.901182691370684520f, 0.900849982437531450f, 0.900516743557543520f, + 0.900182974926756810f, + 0.899848676741518580f, 0.899513849198487980f, 0.899178492494635330f, + 0.898842606827242370f, + 0.898506192393901950f, 0.898169249392518080f, 0.897831778021305650f, + 0.897493778478790310f, + 0.897155250963808550f, 0.896816195675507300f, 0.896476612813344120f, + 0.896136502577086770f, + 0.895795865166813530f, 0.895454700782912450f, 0.895113009626081760f, + 0.894770791897329550f, + 0.894428047797973800f, 0.894084777529641990f, 0.893740981294271040f, + 0.893396659294107720f, + 0.893051811731707450f, 0.892706438809935390f, 0.892360540731965360f, + 0.892014117701280470f, + 0.891667169921672280f, 0.891319697597241390f, 0.890971700932396860f, + 0.890623180131855930f, + 0.890274135400644600f, 0.889924566944096720f, 0.889574474967854580f, + 0.889223859677868210f, + 0.888872721280395630f, 0.888521059982002260f, 0.888168875989561730f, + 0.887816169510254440f, + 0.887462940751568840f, 0.887109189921300170f, 0.886754917227550840f, + 0.886400122878730600f, + 0.886044807083555600f, 0.885688970051048960f, 0.885332611990540590f, + 0.884975733111666660f, + 0.884618333624369920f, 0.884260413738899190f, 0.883901973665809470f, + 0.883543013615961880f, + 0.883183533800523390f, 0.882823534430966620f, 0.882463015719070150f, + 0.882101977876917580f, + 0.881740421116898320f, 0.881378345651706920f, 0.881015751694342870f, + 0.880652639458111010f, + 0.880289009156621010f, 0.879924861003786860f, 0.879560195213827890f, + 0.879195012001267480f, + 0.878829311580933360f, 0.878463094167957870f, 0.878096359977777130f, + 0.877729109226131570f, + 0.877361342129065140f, 0.876993058902925890f, 0.876624259764365310f, + 0.876254944930338510f, + 0.875885114618103810f, 0.875514769045222850f, 0.875143908429560360f, + 0.874772532989284150f, + 0.874400642942864790f, 0.874028238509075740f, 0.873655319906992630f, + 0.873281887355994210f, + 0.872907941075761080f, 0.872533481286276170f, 0.872158508207824480f, + 0.871783022060993120f, + 0.871407023066670950f, 0.871030511446048260f, 0.870653487420617430f, + 0.870275951212171940f, + 0.869897903042806340f, 0.869519343134916860f, 0.869140271711200560f, + 0.868760688994655310f, + 0.868380595208579800f, 0.867999990576573510f, 0.867618875322536230f, + 0.867237249670668400f, + 0.866855113845470430f, 0.866472468071743050f, 0.866089312574586770f, + 0.865705647579402380f, + 0.865321473311889800f, 0.864936789998049020f, 0.864551597864179340f, + 0.864165897136879300f, + 0.863779688043046720f, 0.863392970809878420f, 0.863005745664870320f, + 0.862618012835816740f, + 0.862229772550811240f, 0.861841025038245330f, 0.861451770526809320f, + 0.861062009245491480f, + 0.860671741423578380f, 0.860280967290654510f, 0.859889687076602290f, + 0.859497901011601730f, + 0.859105609326130450f, 0.858712812250963520f, 0.858319510017173440f, + 0.857925702856129790f, + 0.857531390999499150f, 0.857136574679244980f, 0.856741254127627470f, + 0.856345429577203610f, + 0.855949101260826910f, 0.855552269411646860f, 0.855154934263109620f, + 0.854757096048957220f, + 0.854358755003227440f, 0.853959911360254180f, 0.853560565354666840f, + 0.853160717221390420f, + 0.852760367195645300f, 0.852359515512947090f, 0.851958162409106380f, + 0.851556308120228980f, + 0.851153952882715340f, 0.850751096933260790f, 0.850347740508854980f, + 0.849943883846782210f, + 0.849539527184620890f, 0.849134670760243630f, 0.848729314811817130f, + 0.848323459577801640f, + 0.847917105296951410f, 0.847510252208314330f, 0.847102900551231500f, + 0.846695050565337450f, + 0.846286702490559710f, 0.845877856567119000f, 0.845468513035528830f, + 0.845058672136595470f, + 0.844648334111417820f, 0.844237499201387020f, 0.843826167648186740f, + 0.843414339693792760f, + 0.843002015580472940f, 0.842589195550786710f, 0.842175879847585570f, + 0.841762068714012490f, + 0.841347762393501950f, 0.840932961129779780f, 0.840517665166862550f, + 0.840101874749058400f, + 0.839685590120966110f, 0.839268811527475230f, 0.838851539213765760f, + 0.838433773425308340f, + 0.838015514407863820f, 0.837596762407483040f, 0.837177517670507300f, + 0.836757780443567190f, + 0.836337550973583530f, 0.835916829507766360f, 0.835495616293615350f, + 0.835073911578919410f, + 0.834651715611756440f, 0.834229028640493420f, 0.833805850913786340f, + 0.833382182680579730f, + 0.832958024190106670f, 0.832533375691888680f, 0.832108237435735590f, + 0.831682609671745120f, + 0.831256492650303210f, 0.830829886622083570f, 0.830402791838047550f, + 0.829975208549443950f, + 0.829547137007808910f, 0.829118577464965980f, 0.828689530173025820f, + 0.828259995384385660f, + 0.827829973351729920f, 0.827399464328029470f, 0.826968468566541600f, + 0.826536986320809960f, + 0.826105017844664610f, 0.825672563392221390f, 0.825239623217882250f, + 0.824806197576334330f, + 0.824372286722551250f, 0.823937890911791370f, 0.823503010399598500f, + 0.823067645441801670f, + 0.822631796294514990f, 0.822195463214137170f, 0.821758646457351750f, + 0.821321346281126740f, + 0.820883562942714580f, 0.820445296699652050f, 0.820006547809759680f, + 0.819567316531142230f, + 0.819127603122188240f, 0.818687407841569680f, 0.818246730948242070f, + 0.817805572701444270f, + 0.817363933360698460f, 0.816921813185809480f, 0.816479212436865390f, + 0.816036131374236810f, + 0.815592570258576790f, 0.815148529350820830f, 0.814704008912187080f, + 0.814259009204175270f, + 0.813813530488567190f, 0.813367573027426570f, 0.812921137083098770f, + 0.812474222918210480f, + 0.812026830795669730f, 0.811578960978665890f, 0.811130613730669190f, + 0.810681789315430780f, + 0.810232487996982330f, 0.809782710039636530f, 0.809332455707985950f, + 0.808881725266903610f, + 0.808430518981542720f, 0.807978837117336310f, 0.807526679939997160f, + 0.807074047715517610f, + 0.806620940710169650f, 0.806167359190504420f, 0.805713303423352230f, + 0.805258773675822210f, + 0.804803770215302920f, 0.804348293309460780f, 0.803892343226241260f, + 0.803435920233868120f, + 0.802979024600843250f, 0.802521656595946430f, 0.802063816488235440f, + 0.801605504547046150f, + 0.801146721041991360f, 0.800687466242961610f, 0.800227740420124790f, + 0.799767543843925680f, + 0.799306876785086160f, 0.798845739514604580f, 0.798384132303756380f, + 0.797922055424093000f, + 0.797459509147442460f, 0.796996493745908750f, 0.796533009491872000f, + 0.796069056657987990f, + 0.795604635517188070f, 0.795139746342679590f, 0.794674389407944550f, + 0.794208564986740640f, + 0.793742273353100210f, 0.793275514781330630f, 0.792808289546014120f, + 0.792340597922007170f, + 0.791872440184440470f, 0.791403816608719500f, 0.790934727470523290f, + 0.790465173045804880f, + 0.789995153610791090f, 0.789524669441982190f, 0.789053720816151880f, + 0.788582308010347120f, + 0.788110431301888070f, 0.787638090968367450f, 0.787165287287651010f, + 0.786692020537876790f, + 0.786218290997455660f, 0.785744098945070360f, 0.785269444659675850f, + 0.784794328420499230f, + 0.784318750507038920f, 0.783842711199065230f, 0.783366210776619720f, + 0.782889249520015480f, + 0.782411827709836530f, 0.781933945626937630f, 0.781455603552444590f, + 0.780976801767753750f, + 0.780497540554531910f, 0.780017820194715990f, 0.779537640970513260f, + 0.779057003164400630f, + 0.778575907059125050f, 0.778094352937702790f, 0.777612341083420030f, + 0.777129871779831620f, + 0.776646945310762060f, 0.776163561960304340f, 0.775679722012820650f, + 0.775195425752941420f, + 0.774710673465565550f, 0.774225465435860680f, 0.773739801949261840f, + 0.773253683291472590f, + 0.772767109748463850f, 0.772280081606474320f, 0.771792599152010150f, + 0.771304662671844830f, + 0.770816272453018540f, 0.770327428782838890f, 0.769838131948879840f, + 0.769348382238982280f, + 0.768858179941253270f, 0.768367525344066270f, 0.767876418736060610f, + 0.767384860406141730f, + 0.766892850643480670f, 0.766400389737514230f, 0.765907477977944340f, + 0.765414115654738270f, + 0.764920303058128410f, 0.764426040478612070f, 0.763931328206951090f, + 0.763436166534172010f, + 0.762940555751565720f, 0.762444496150687210f, 0.761947988023355390f, + 0.761451031661653620f, + 0.760953627357928150f, 0.760455775404789260f, 0.759957476095110330f, + 0.759458729722028210f, + 0.758959536578942440f, 0.758459896959515430f, 0.757959811157672300f, + 0.757459279467600720f, + 0.756958302183750490f, 0.756456879600833740f, 0.755955012013824420f, + 0.755452699717958250f, + 0.754949943008732640f, 0.754446742181906440f, 0.753943097533499640f, + 0.753439009359793580f, + 0.752934477957330150f, 0.752429503622912390f, 0.751924086653603550f, + 0.751418227346727470f, + 0.750911925999867890f, 0.750405182910869330f, 0.749897998377835330f, + 0.749390372699129560f, + 0.748882306173375150f, 0.748373799099454560f, 0.747864851776509410f, + 0.747355464503940190f, + 0.746845637581406540f, 0.746335371308826320f, 0.745824665986376090f, + 0.745313521914490520f, + 0.744801939393862630f, 0.744289918725443260f, 0.743777460210440890f, + 0.743264564150321600f, + 0.742751230846809050f, 0.742237460601884000f, 0.741723253717784140f, + 0.741208610497004260f, + 0.740693531242295760f, 0.740178016256666240f, 0.739662065843380010f, + 0.739145680305957510f, + 0.738628859948174840f, 0.738111605074064260f, 0.737593915987913570f, + 0.737075792994265730f, + 0.736557236397919150f, 0.736038246503927350f, 0.735518823617598900f, + 0.734998968044496710f, + 0.734478680090438370f, 0.733957960061495940f, 0.733436808263995710f, + 0.732915225004517780f, + 0.732393210589896040f, 0.731870765327218290f, 0.731347889523825570f, + 0.730824583487312160f, + 0.730300847525525490f, 0.729776681946566090f, 0.729252087058786970f, + 0.728727063170793830f, + 0.728201610591444610f, 0.727675729629849610f, 0.727149420595371020f, + 0.726622683797622850f, + 0.726095519546471000f, 0.725567928152032300f, 0.725039909924675370f, + 0.724511465175019630f, + 0.723982594213935520f, 0.723453297352544380f, 0.722923574902217700f, + 0.722393427174577550f, + 0.721862854481496340f, 0.721331857135096290f, 0.720800435447749190f, + 0.720268589732077190f, + 0.719736320300951030f, 0.719203627467491220f, 0.718670511545067230f, + 0.718136972847297490f, + 0.717603011688049080f, 0.717068628381437480f, 0.716533823241826680f, + 0.715998596583828690f, + 0.715462948722303760f, 0.714926879972359490f, 0.714390390649351390f, + 0.713853481068882470f, + 0.713316151546802610f, 0.712778402399208980f, 0.712240233942445510f, + 0.711701646493102970f, + 0.711162640368018350f, 0.710623215884275020f, 0.710083373359202800f, + 0.709543113110376770f, + 0.709002435455618250f, 0.708461340712994160f, 0.707919829200816310f, + 0.707377901237642100f, + 0.706835557142273860f, 0.706292797233758480f, 0.705749621831387790f, + 0.705206031254697830f, + 0.704662025823468930f, 0.704117605857725430f, 0.703572771677735580f, + 0.703027523604011220f, + 0.702481861957308000f, 0.701935787058624360f, 0.701389299229202230f, + 0.700842398790526230f, + 0.700295086064323780f, 0.699747361372564990f, 0.699199225037462120f, + 0.698650677381469580f, + 0.698101718727283880f, 0.697552349397843270f, 0.697002569716327460f, + 0.696452380006157830f, + 0.695901780590996830f, 0.695350771794747800f, 0.694799353941554900f, + 0.694247527355803310f, + 0.693695292362118350f, 0.693142649285365510f, 0.692589598450650380f, + 0.692036140183318830f, + 0.691482274808955850f, 0.690928002653386280f, 0.690373324042674040f, + 0.689818239303122470f, + 0.689262748761273470f, 0.688706852743907750f, 0.688150551578044830f, + 0.687593845590942170f, + 0.687036735110095660f, 0.686479220463238950f, 0.685921301978343670f, + 0.685362979983618730f, + 0.684804254807510620f, 0.684245126778703080f, 0.683685596226116690f, + 0.683125663478908800f, + 0.682565328866473250f, 0.682004592718440830f, 0.681443455364677990f, + 0.680881917135287340f, + 0.680319978360607200f, 0.679757639371212030f, 0.679194900497911200f, + 0.678631762071749470f, + 0.678068224424006600f, 0.677504287886197430f, 0.676939952790071240f, + 0.676375219467611700f, + 0.675810088251037060f, 0.675244559472799270f, 0.674678633465584540f, + 0.674112310562312360f, + 0.673545591096136100f, 0.672978475400442090f, 0.672410963808849900f, + 0.671843056655211930f, + 0.671274754273613490f, 0.670706056998372160f, 0.670136965164037760f, + 0.669567479105392490f, + 0.668997599157450270f, 0.668427325655456820f, 0.667856658934889440f, + 0.667285599331456480f, + 0.666714147181097670f, 0.666142302819983540f, 0.665570066584515560f, + 0.664997438811325340f, + 0.664424419837275180f, 0.663851009999457340f, 0.663277209635194100f, + 0.662703019082037440f, + 0.662128438677768720f, 0.661553468760399000f, 0.660978109668168060f, + 0.660402361739545030f, + 0.659826225313227430f, 0.659249700728141490f, 0.658672788323441890f, + 0.658095488438511290f, + 0.657517801412960120f, 0.656939727586627110f, 0.656361267299578000f, + 0.655782420892106030f, + 0.655203188704731930f, 0.654623571078202680f, 0.654043568353492640f, + 0.653463180871802330f, + 0.652882408974558960f, 0.652301253003415460f, 0.651719713300251020f, + 0.651137790207170330f, + 0.650555484066503990f, 0.649972795220807530f, 0.649389724012861770f, + 0.648806270785672550f, + 0.648222435882470420f, 0.647638219646710420f, 0.647053622422071650f, + 0.646468644552457890f, + 0.645883286381996440f, 0.645297548255038380f, 0.644711430516158420f, + 0.644124933510154540f, + 0.643538057582047850f, 0.642950803077082080f, 0.642363170340724320f, + 0.641775159718663500f, + 0.641186771556811250f, 0.640598006201301030f, 0.640008863998488440f, + 0.639419345294950700f, + 0.638829450437486400f, 0.638239179773115390f, 0.637648533649078810f, + 0.637057512412838590f, + 0.636466116412077180f, 0.635874345994697720f, 0.635282201508823530f, + 0.634689683302797850f, + 0.634096791725183740f, 0.633503527124764320f, 0.632909889850541860f, + 0.632315880251737680f, + 0.631721498677792370f, 0.631126745478365340f, 0.630531621003334600f, + 0.629936125602796550f, + 0.629340259627065750f, 0.628744023426674790f, 0.628147417352374120f, + 0.627550441755131530f, + 0.626953096986132770f, 0.626355383396779990f, 0.625757301338692900f, + 0.625158851163707730f, + 0.624560033223877320f, 0.623960847871470770f, 0.623361295458973340f, + 0.622761376339086460f, + 0.622161090864726930f, 0.621560439389027270f, 0.620959422265335180f, + 0.620358039847213830f, + 0.619756292488440660f, 0.619154180543008410f, 0.618551704365123860f, + 0.617948864309208260f, + 0.617345660729896940f, 0.616742093982038830f, 0.616138164420696910f, + 0.615533872401147430f, + 0.614929218278879590f, 0.614324202409595950f, 0.613718825149211830f, + 0.613113086853854910f, + 0.612506987879865570f, 0.611900528583796070f, 0.611293709322411010f, + 0.610686530452686280f, + 0.610078992331809620f, 0.609471095317180240f, 0.608862839766408200f, + 0.608254226037314490f, + 0.607645254487930830f, 0.607035925476499760f, 0.606426239361473550f, + 0.605816196501515080f, + 0.605205797255496500f, 0.604595041982500360f, 0.603983931041818020f, + 0.603372464792950370f, + 0.602760643595607220f, 0.602148467809707320f, 0.601535937795377730f, + 0.600923053912954090f, + 0.600309816522980430f, 0.599696225986208310f, 0.599082282663597310f, + 0.598467986916314310f, + 0.597853339105733910f, 0.597238339593437530f, 0.596622988741213330f, + 0.596007286911056530f, + 0.595391234465168730f, 0.594774831765957580f, 0.594158079176036800f, + 0.593540977058226390f, + 0.592923525775551410f, 0.592305725691242400f, 0.591687577168735550f, + 0.591069080571671510f, + 0.590450236263895920f, 0.589831044609458900f, 0.589211505972615070f, + 0.588591620717822890f, + 0.587971389209745120f, 0.587350811813247660f, 0.586729888893400500f, + 0.586108620815476430f, + 0.585487007944951450f, 0.584865050647504490f, 0.584242749289016980f, + 0.583620104235572760f, + 0.582997115853457700f, 0.582373784509160220f, 0.581750110569369760f, + 0.581126094400977620f, + 0.580501736371076600f, 0.579877036846960350f, 0.579251996196123550f, + 0.578626614786261430f, + 0.578000892985269910f, 0.577374831161244880f, 0.576748429682482520f, + 0.576121688917478390f, + 0.575494609234928230f, 0.574867191003726740f, 0.574239434592967890f, + 0.573611340371944610f, + 0.572982908710148680f, 0.572354139977270030f, 0.571725034543197120f, + 0.571095592778016690f, + 0.570465815052012990f, 0.569835701735668110f, 0.569205253199661200f, + 0.568574469814869250f, + 0.567943351952365670f, 0.567311899983420800f, 0.566680114279501710f, + 0.566047995212271560f, + 0.565415543153589770f, 0.564782758475511400f, 0.564149641550287680f, + 0.563516192750364910f, + 0.562882412448384550f, 0.562248301017183150f, 0.561613858829792420f, + 0.560979086259438260f, + 0.560343983679540860f, 0.559708551463714790f, 0.559072789985768480f, + 0.558436699619704100f, + 0.557800280739717100f, 0.557163533720196340f, 0.556526458935723720f, + 0.555889056761073920f, + 0.555251327571214090f, 0.554613271741304040f, 0.553974889646695610f, + 0.553336181662932410f, + 0.552697148165749770f, 0.552057789531074980f, 0.551418106135026060f, + 0.550778098353912230f, + 0.550137766564233630f, 0.549497111142680960f, 0.548856132466135290f, + 0.548214830911667780f, + 0.547573206856539870f, 0.546931260678202190f, 0.546288992754295210f, + 0.545646403462648590f, + 0.545003493181281160f, 0.544360262288400400f, 0.543716711162402390f, + 0.543072840181871850f, + 0.542428649725581360f, 0.541784140172491660f, 0.541139311901750910f, + 0.540494165292695230f, + 0.539848700724847700f, 0.539202918577918240f, 0.538556819231804210f, + 0.537910403066588990f, + 0.537263670462542530f, 0.536616621800121150f, 0.535969257459966710f, + 0.535321577822907010f, + 0.534673583269955510f, 0.534025274182310380f, 0.533376650941355560f, + 0.532727713928658810f, + 0.532078463525973540f, 0.531428900115236910f, 0.530779024078570250f, + 0.530128835798278850f, + 0.529478335656852090f, 0.528827524036961980f, 0.528176401321464370f, + 0.527524967893398200f, + 0.526873224135984700f, 0.526221170432628170f, 0.525568807166914680f, + 0.524916134722612890f, + 0.524263153483673470f, 0.523609863834228030f, 0.522956266158590140f, + 0.522302360841254700f, + 0.521648148266897090f, 0.520993628820373810f, 0.520338802886721960f, + 0.519683670851158520f, + 0.519028233099080970f, 0.518372490016066220f, 0.517716441987871150f, + 0.517060089400432130f, + 0.516403432639863990f, 0.515746472092461380f, 0.515089208144697270f, + 0.514431641183222930f, + 0.513773771594868030f, 0.513115599766640560f, 0.512457126085725800f, + 0.511798350939487000f, + 0.511139274715464390f, 0.510479897801375700f, 0.509820220585115560f, + 0.509160243454754750f, + 0.508499966798540810f, 0.507839391004897940f, 0.507178516462425290f, + 0.506517343559898530f, + 0.505855872686268860f, 0.505194104230662240f, 0.504532038582380380f, + 0.503869676130898950f, + 0.503207017265869030f, 0.502544062377115800f, 0.501880811854638400f, + 0.501217266088609950f, + 0.500553425469377640f, 0.499889290387461380f, 0.499224861233555030f, + 0.498560138398525200f, + 0.497895122273410930f, 0.497229813249424340f, 0.496564211717949340f, + 0.495898318070542240f, + 0.495232132698931350f, 0.494565655995016010f, 0.493898888350867430f, + 0.493231830158728070f, + 0.492564481811010650f, 0.491896843700299240f, 0.491228916219348330f, + 0.490560699761082080f, + 0.489892194718595300f, 0.489223401485152030f, 0.488554320454186230f, + 0.487884952019301210f, + 0.487215296574268820f, 0.486545354513030270f, 0.485875126229695420f, + 0.485204612118541880f, + 0.484533812574016120f, 0.483862727990732320f, 0.483191358763471910f, + 0.482519705287184520f, + 0.481847767956986080f, 0.481175547168160360f, 0.480503043316157670f, + 0.479830256796594250f, + 0.479157188005253310f, 0.478483837338084080f, 0.477810205191201040f, + 0.477136291960884750f, + 0.476462098043581310f, 0.475787623835901120f, 0.475112869734620470f, + 0.474437836136679340f, + 0.473762523439182850f, 0.473086932039400220f, 0.472411062334764100f, + 0.471734914722871430f, + 0.471058489601482610f, 0.470381787368520710f, 0.469704808422072460f, + 0.469027553160387240f, + 0.468350021981876530f, 0.467672215285114710f, 0.466994133468838110f, + 0.466315776931944480f, + 0.465637146073493770f, 0.464958241292706740f, 0.464279062988965760f, + 0.463599611561814120f, + 0.462919887410955130f, 0.462239890936253280f, 0.461559622537733190f, + 0.460879082615578690f, + 0.460198271570134270f, 0.459517189801903590f, 0.458835837711549120f, + 0.458154215699893230f, + 0.457472324167916110f, 0.456790163516757220f, 0.456107734147714220f, + 0.455425036462242420f, + 0.454742070861955450f, 0.454058837748624540f, 0.453375337524177750f, + 0.452691570590700860f, + 0.452007537350436530f, 0.451323238205783520f, 0.450638673559297760f, + 0.449953843813690580f, + 0.449268749371829920f, 0.448583390636739300f, 0.447897768011597360f, + 0.447211881899738260f, + 0.446525732704651400f, 0.445839320829980350f, 0.445152646679523590f, + 0.444465710657234110f, + 0.443778513167218280f, 0.443091054613736990f, 0.442403335401204130f, + 0.441715355934187310f, + 0.441027116617407340f, 0.440338617855737300f, 0.439649860054203420f, + 0.438960843617984430f, + 0.438271568952410480f, 0.437582036462964340f, 0.436892246555280470f, + 0.436202199635143950f, + 0.435511896108492170f, 0.434821336381412350f, 0.434130520860143310f, + 0.433439449951074200f, + 0.432748124060743760f, 0.432056543595841450f, 0.431364708963206440f, + 0.430672620569826860f, + 0.429980278822840570f, 0.429287684129534720f, 0.428594836897344400f, + 0.427901737533854240f, + 0.427208386446796370f, 0.426514784044051520f, 0.425820930733648350f, + 0.425126826923762410f, + 0.424432473022717420f, 0.423737869438983950f, 0.423043016581179100f, + 0.422347914858067000f, + 0.421652564678558380f, 0.420956966451709440f, 0.420261120586723050f, + 0.419565027492946940f, + 0.418868687579875110f, 0.418172101257146430f, 0.417475268934544340f, + 0.416778191021997590f, + 0.416080867929579320f, 0.415383300067506290f, 0.414685487846140010f, + 0.413987431675985510f, + 0.413289131967690960f, 0.412590589132048380f, 0.411891803579992220f, + 0.411192775722600160f, + 0.410493505971092520f, 0.409793994736831200f, 0.409094242431320920f, + 0.408394249466208110f, + 0.407694016253280170f, 0.406993543204466460f, 0.406292830731837470f, + 0.405591879247603870f, + 0.404890689164117750f, 0.404189260893870750f, 0.403487594849495310f, + 0.402785691443763640f, + 0.402083551089587040f, 0.401381174200016790f, 0.400678561188243350f, + 0.399975712467595390f, + 0.399272628451540930f, 0.398569309553686360f, 0.397865756187775750f, + 0.397161968767691720f, + 0.396457947707453960f, 0.395753693421220080f, 0.395049206323284880f, + 0.394344486828079650f, + 0.393639535350172880f, 0.392934352304269600f, 0.392228938105210370f, + 0.391523293167972350f, + 0.390817417907668610f, 0.390111312739546910f, 0.389404978078991100f, + 0.388698414341519250f, + 0.387991621942784910f, 0.387284601298575890f, 0.386577352824813980f, + 0.385869876937555310f, + 0.385162174052989970f, 0.384454244587440870f, 0.383746088957365010f, + 0.383037707579352130f, + 0.382329100870124510f, 0.381620269246537520f, 0.380911213125578130f, + 0.380201932924366050f, + 0.379492429060152740f, 0.378782701950320600f, 0.378072752012383990f, + 0.377362579663988450f, + 0.376652185322909620f, 0.375941569407054420f, 0.375230732334460030f, + 0.374519674523293210f, + 0.373808396391851370f, 0.373096898358560690f, 0.372385180841977360f, + 0.371673244260786630f, + 0.370961089033802040f, 0.370248715579966360f, 0.369536124318350760f, + 0.368823315668153960f, + 0.368110290048703050f, 0.367397047879452820f, 0.366683589579984930f, + 0.365969915570008910f, + 0.365256026269360380f, 0.364541922098002180f, 0.363827603476023610f, + 0.363113070823639530f, + 0.362398324561191310f, 0.361683365109145950f, 0.360968192888095290f, + 0.360252808318756830f, + 0.359537211821973180f, 0.358821403818710860f, 0.358105384730061760f, + 0.357389154977241000f, + 0.356672714981588260f, 0.355956065164567010f, 0.355239205947763370f, + 0.354522137752887430f, + 0.353804861001772160f, 0.353087376116372530f, 0.352369683518766630f, + 0.351651783631154680f, + 0.350933676875858360f, 0.350215363675321740f, 0.349496844452109600f, + 0.348778119628908420f, + 0.348059189628525780f, 0.347340054873889190f, 0.346620715788047320f, + 0.345901172794169100f, + 0.345181426315542610f, 0.344461476775576480f, 0.343741324597798600f, + 0.343020970205855540f, + 0.342300414023513690f, 0.341579656474657210f, 0.340858697983289440f, + 0.340137538973531880f, + 0.339416179869623410f, 0.338694621095921190f, 0.337972863076899830f, + 0.337250906237150650f, + 0.336528751001382350f, 0.335806397794420560f, 0.335083847041206580f, + 0.334361099166798900f, + 0.333638154596370920f, 0.332915013755212650f, 0.332191677068729320f, + 0.331468144962440920f, + 0.330744417861982890f, 0.330020496193105530f, 0.329296380381672800f, + 0.328572070853663690f, + 0.327847568035170960f, 0.327122872352400510f, 0.326397984231672660f, + 0.325672904099419900f, + 0.324947632382188430f, 0.324222169506637130f, 0.323496515899536760f, + 0.322770671987770710f, + 0.322044638198334620f, 0.321318414958334910f, 0.320592002694990330f, + 0.319865401835630610f, + 0.319138612807695900f, 0.318411636038737960f, 0.317684471956418020f, + 0.316957120988508150f, + 0.316229583562890490f, 0.315501860107556040f, 0.314773951050606070f, + 0.314045856820250820f, + 0.313317577844809070f, 0.312589114552708660f, 0.311860467372486130f, + 0.311131636732785270f, + 0.310402623062358880f, 0.309673426790066490f, 0.308944048344875710f, + 0.308214488155861220f, + 0.307484746652204160f, 0.306754824263192780f, 0.306024721418221900f, + 0.305294438546791720f, + 0.304563976078509050f, 0.303833334443086470f, 0.303102514070341060f, + 0.302371515390196130f, + 0.301640338832678880f, 0.300908984827921890f, 0.300177453806162120f, + 0.299445746197739950f, + 0.298713862433100390f, 0.297981802942791920f, 0.297249568157465890f, + 0.296517158507877410f, + 0.295784574424884370f, 0.295051816339446720f, 0.294318884682627570f, + 0.293585779885591310f, + 0.292852502379604810f, 0.292119052596036540f, 0.291385430966355720f, + 0.290651637922133220f, + 0.289917673895040860f, 0.289183539316850310f, 0.288449234619434170f, + 0.287714760234765280f, + 0.286980116594915570f, 0.286245304132057120f, 0.285510323278461380f, + 0.284775174466498300f, + 0.284039858128637360f, 0.283304374697445790f, 0.282568724605589740f, + 0.281832908285833460f, + 0.281096926171038320f, 0.280360778694163810f, 0.279624466288266700f, + 0.278887989386500280f, + 0.278151348422115090f, 0.277414543828458200f, 0.276677576038972420f, + 0.275940445487197320f, + 0.275203152606767370f, 0.274465697831413220f, 0.273728081594960650f, + 0.272990304331329980f, + 0.272252366474536660f, 0.271514268458690810f, 0.270776010717996010f, + 0.270037593686750510f, + 0.269299017799346230f, 0.268560283490267890f, 0.267821391194094320f, + 0.267082341345496350f, + 0.266343134379238180f, 0.265603770730176440f, 0.264864250833259320f, + 0.264124575123527490f, + 0.263384744036113390f, 0.262644758006240100f, 0.261904617469222560f, + 0.261164322860466590f, + 0.260423874615468010f, 0.259683273169813930f, 0.258942518959180580f, + 0.258201612419334870f, + 0.257460553986133210f, 0.256719344095520720f, 0.255977983183532380f, + 0.255236471686291820f, + 0.254494810040010790f, 0.253752998680989940f, 0.253011038045617980f, + 0.252268928570370810f, + 0.251526670691812780f, 0.250784264846594550f, 0.250041711471454650f, + 0.249299011003218300f, + 0.248556163878796620f, 0.247813170535187620f, 0.247070031409475370f, + 0.246326746938829060f, + 0.245583317560504000f, 0.244839743711840750f, 0.244096025830264210f, + 0.243352164353284880f, + 0.242608159718496890f, 0.241864012363579210f, 0.241119722726294730f, + 0.240375291244489500f, + 0.239630718356093560f, 0.238886004499120170f, 0.238141150111664870f, + 0.237396155631906550f, + 0.236651021498106460f, 0.235905748148607370f, 0.235160336021834860f, + 0.234414785556295250f, + 0.233669097190576820f, 0.232923271363349120f, 0.232177308513361770f, + 0.231431209079445730f, + 0.230684973500512310f, 0.229938602215552260f, 0.229192095663636740f, + 0.228445454283916550f, + 0.227698678515621170f, 0.226951768798059980f, 0.226204725570620270f, + 0.225457549272768540f, + 0.224710240344049570f, 0.223962799224085520f, 0.223215226352576960f, + 0.222467522169301990f, + 0.221719687114115240f, 0.220971721626949060f, 0.220223626147812460f, + 0.219475401116790340f, + 0.218727046974044600f, 0.217978564159812290f, 0.217229953114406790f, + 0.216481214278216900f, + 0.215732348091705940f, 0.214983354995412820f, 0.214234235429951100f, + 0.213484989836008080f, + 0.212735618654345870f, 0.211986122325800410f, 0.211236501291280710f, + 0.210486755991769890f, + 0.209736886868323370f, 0.208986894362070070f, 0.208236778914211470f, + 0.207486540966020700f, + 0.206736180958843660f, 0.205985699334098050f, 0.205235096533272380f, + 0.204484372997927180f, + 0.203733529169694010f, 0.202982565490274460f, 0.202231482401441620f, + 0.201480280345037820f, + 0.200728959762976140f, 0.199977521097239290f, 0.199225964789878890f, + 0.198474291283016360f, + 0.197722501018842030f, 0.196970594439614370f, 0.196218571987660850f, + 0.195466434105377090f, + 0.194714181235225990f, 0.193961813819739010f, 0.193209332301514080f, + 0.192456737123216840f, + 0.191704028727579940f, 0.190951207557401860f, 0.190198274055548120f, + 0.189445228664950340f, + 0.188692071828605260f, 0.187938803989575850f, 0.187185425590990440f, + 0.186431937076041640f, + 0.185678338887987790f, 0.184924631470150870f, 0.184170815265917720f, + 0.183416890718739230f, + 0.182662858272129360f, 0.181908718369666160f, 0.181154471454990920f, + 0.180400117971807270f, + 0.179645658363882100f, 0.178891093075044830f, 0.178136422549186320f, + 0.177381647230260200f, + 0.176626767562280960f, 0.175871783989325040f, 0.175116696955530060f, + 0.174361506905093830f, + 0.173606214282275410f, 0.172850819531394200f, 0.172095323096829040f, + 0.171339725423019260f, + 0.170584026954463700f, 0.169828228135719880f, 0.169072329411405180f, + 0.168316331226194910f, + 0.167560234024823590f, 0.166804038252083870f, 0.166047744352825850f, + 0.165291352771957970f, + 0.164534863954446110f, 0.163778278345312690f, 0.163021596389637810f, + 0.162264818532558110f, + 0.161507945219266150f, 0.160750976895011390f, 0.159993914005098350f, + 0.159236756994887850f, + 0.158479506309796100f, 0.157722162395293690f, 0.156964725696906750f, + 0.156207196660216040f, + 0.155449575730855880f, 0.154691863354515400f, 0.153934059976937460f, + 0.153176166043917870f, + 0.152418182001306500f, 0.151660108295005400f, 0.150901945370970040f, + 0.150143693675208330f, + 0.149385353653779810f, 0.148626925752796540f, 0.147868410418422360f, + 0.147109808096871850f, + 0.146351119234411440f, 0.145592344277358450f, 0.144833483672080240f, + 0.144074537864995330f, + 0.143315507302571590f, 0.142556392431327340f, 0.141797193697830530f, + 0.141037911548697770f, + 0.140278546430595420f, 0.139519098790238600f, 0.138759569074390380f, + 0.137999957729862760f, + 0.137240265203515700f, 0.136480491942256310f, 0.135720638393040080f, + 0.134960705002868830f, + 0.134200692218792020f, 0.133440600487905820f, 0.132680430257352130f, + 0.131920181974319760f, + 0.131159856086043410f, 0.130399453039802740f, 0.129638973282923540f, + 0.128878417262776660f, + 0.128117785426777150f, 0.127357078222385570f, 0.126596296097105960f, + 0.125835439498487020f, + 0.125074508874121300f, 0.124313504671644300f, 0.123552427338735370f, + 0.122791277323116900f, + 0.122030055072553410f, 0.121268761034852550f, 0.120507395657864240f, + 0.119745959389479630f, + 0.118984452677632520f, 0.118222875970297250f, 0.117461229715489990f, + 0.116699514361267840f, + 0.115937730355727850f, 0.115175878147008180f, 0.114413958183287050f, + 0.113651970912781920f, + 0.112889916783750470f, 0.112127796244489750f, 0.111365609743335190f, + 0.110603357728661910f, + 0.109841040648882680f, 0.109078658952449240f, 0.108316213087851300f, + 0.107553703503615710f, + 0.106791130648307380f, 0.106028494970528530f, 0.105265796918917650f, + 0.104503036942150550f, + 0.103740215488939480f, 0.102977333008032250f, 0.102214389948213370f, + 0.101451386758302160f, + 0.100688323887153970f, 0.099925201783659226f, 0.099162020896742573f, + 0.098398781675363881f, + 0.097635484568517339f, 0.096872130025230527f, 0.096108718494565468f, + 0.095345250425617742f, + 0.094581726267515473f, 0.093818146469420494f, 0.093054511480527333f, + 0.092290821750062355f, + 0.091527077727284981f, 0.090763279861485704f, 0.089999428601987341f, + 0.089235524398144139f, + 0.088471567699340822f, 0.087707558954993645f, 0.086943498614549489f, + 0.086179387127484922f, + 0.085415224943307277f, 0.084651012511553700f, 0.083886750281790226f, + 0.083122438703613077f, + 0.082358078226646619f, 0.081593669300544638f, 0.080829212374989468f, + 0.080064707899690932f, + 0.079300156324387569f, 0.078535558098845590f, 0.077770913672857989f, + 0.077006223496245585f, + 0.076241488018856149f, 0.075476707690563416f, 0.074711882961268378f, + 0.073947014280897269f, + 0.073182102099402888f, 0.072417146866763538f, 0.071652149032982254f, + 0.070887109048087787f, + 0.070122027362133646f, 0.069356904425197236f, 0.068591740687380900f, + 0.067826536598810966f, + 0.067061292609636836f, 0.066296009170032283f, 0.065530686730193397f, + 0.064765325740339871f, + 0.063999926650714078f, 0.063234489911580136f, 0.062469015973224969f, + 0.061703505285957416f, + 0.060937958300107238f, 0.060172375466026218f, 0.059406757234087247f, + 0.058641104054683348f, + 0.057875416378229017f, 0.057109694655158132f, 0.056343939335925283f, + 0.055578150871004817f, + 0.054812329710889909f, 0.054046476306093640f, 0.053280591107148056f, + 0.052514674564603257f, + 0.051748727129028414f, 0.050982749251010900f, 0.050216741381155325f, + 0.049450703970084824f, + 0.048684637468439020f, 0.047918542326875327f, 0.047152418996068000f, + 0.046386267926707213f, + 0.045620089569500123f, 0.044853884375169933f, 0.044087652794454979f, + 0.043321395278109784f, + 0.042555112276904117f, 0.041788804241622082f, 0.041022471623063397f, + 0.040256114872041358f, + 0.039489734439384118f, 0.038723330775933762f, 0.037956904332545366f, + 0.037190455560088091f, + 0.036423984909444228f, 0.035657492831508264f, 0.034890979777187955f, + 0.034124446197403423f, + 0.033357892543086159f, 0.032591319265180385f, 0.031824726814640963f, + 0.031058115642434700f, + 0.030291486199539423f, 0.029524838936943035f, 0.028758174305644590f, + 0.027991492756653365f, + 0.027224794740987910f, 0.026458080709677145f, 0.025691351113759395f, + 0.024924606404281485f, + 0.024157847032300020f, 0.023391073448879338f, 0.022624286105092803f, + 0.021857485452021874f, + 0.021090671940755180f, 0.020323846022389572f, 0.019557008148029204f, + 0.018790158768784596f, + 0.018023298335773701f, 0.017256427300120978f, 0.016489546112956454f, + 0.015722655225417017f, + 0.014955755088644378f, 0.014188846153786343f, 0.013421928871995907f, + 0.012655003694430301f, + 0.011888071072252072f, 0.011121131456628141f, 0.010354185298728884f, + 0.009587233049729183f, + 0.008820275160807512f, 0.008053312083144991f, 0.007286344267926684f, + 0.006519372166339549f, + 0.005752396229573737f, 0.004985416908821652f, 0.004218434655277024f, + 0.003451449920135975f, + 0.002684463154596083f, 0.001917474809855460f, 0.001150485337113809f, + 0.000383495187571497f +}; + +static const float32_t cos_factors_8192[8192] = { + 1.999999990808214700f, 1.999999917273932200f, 1.999999770205369800f, + 1.999999549602533100f, + 1.999999255465430200f, 1.999998887794072000f, 1.999998446588471700f, + 1.999997931848645600f, + 1.999997343574612800f, 1.999996681766395000f, 1.999995946424016200f, + 1.999995137547503600f, + 1.999994255136887000f, 1.999993299192198700f, 1.999992269713474200f, + 1.999991166700750800f, + 1.999989990154069600f, 1.999988740073473500f, 1.999987416459008600f, + 1.999986019310723500f, + 1.999984548628669600f, 1.999983004412901000f, 1.999981386663474400f, + 1.999979695380449400f, + 1.999977930563888100f, 1.999976092213855400f, 1.999974180330418700f, + 1.999972194913648900f, + 1.999970135963618400f, 1.999968003480403000f, 1.999965797464081200f, + 1.999963517914734100f, + 1.999961164832445800f, 1.999958738217302300f, 1.999956238069392900f, + 1.999953664388809800f, + 1.999951017175647600f, 1.999948296430003500f, 1.999945502151977600f, + 1.999942634341672600f, + 1.999939692999193900f, 1.999936678124649700f, 1.999933589718150700f, + 1.999930427779810900f, + 1.999927192309745900f, 1.999923883308075200f, 1.999920500774920300f, + 1.999917044710405500f, + 1.999913515114657900f, 1.999909911987807200f, 1.999906235329986100f, + 1.999902485141329400f, + 1.999898661421975400f, 1.999894764172064600f, 1.999890793391740000f, + 1.999886749081147800f, + 1.999882631240436700f, 1.999878439869758200f, 1.999874174969266300f, + 1.999869836539117700f, + 1.999865424579472000f, 1.999860939090491600f, 1.999856380072341000f, + 1.999851747525188200f, + 1.999847041449203300f, 1.999842261844559700f, 1.999837408711432600f, + 1.999832482050000900f, + 1.999827481860445300f, 1.999822408142949900f, 1.999817260897701400f, + 1.999812040124888700f, + 1.999806745824704000f, 1.999801377997341800f, 1.999795936642999600f, + 1.999790421761877400f, + 1.999784833354177900f, 1.999779171420106700f, 1.999773435959872000f, + 1.999767626973684400f, + 1.999761744461757700f, 1.999755788424308200f, 1.999749758861554900f, + 1.999743655773719400f, + 1.999737479161026100f, 1.999731229023702200f, 1.999724905361977200f, + 1.999718508176084000f, + 1.999712037466257600f, 1.999705493232735800f, 1.999698875475759600f, + 1.999692184195571900f, + 1.999685419392419000f, 1.999678581066549400f, 1.999671669218214600f, + 1.999664683847668800f, + 1.999657624955168700f, 1.999650492540973900f, 1.999643286605346800f, + 1.999636007148552400f, + 1.999628654170857900f, 1.999621227672533800f, 1.999613727653853500f, + 1.999606154115092500f, + 1.999598507056529000f, 1.999590786478444600f, 1.999582992381123000f, + 1.999575124764850800f, + 1.999567183629917100f, 1.999559168976613900f, 1.999551080805236100f, + 1.999542919116081000f, + 1.999534683909448600f, 1.999526375185641800f, 1.999517992944965800f, + 1.999509537187729200f, + 1.999501007914242600f, 1.999492405124819700f, 1.999483728819776900f, + 1.999474978999432800f, + 1.999466155664109600f, 1.999457258814131500f, 1.999448288449825500f, + 1.999439244571521700f, + 1.999430127179552500f, 1.999420936274252800f, 1.999411671855960900f, + 1.999402333925017300f, + 1.999392922481765500f, 1.999383437526551300f, 1.999373879059723500f, + 1.999364247081633500f, + 1.999354541592635500f, 1.999344762593086500f, 1.999334910083345700f, + 1.999324984063775700f, + 1.999314984534741100f, 1.999304911496609700f, 1.999294764949752100f, + 1.999284544894541100f, + 1.999274251331352400f, 1.999263884260564600f, 1.999253443682558900f, + 1.999242929597719200f, + 1.999232342006432000f, 1.999221680909086400f, 1.999210946306074500f, + 1.999200138197791100f, + 1.999189256584633600f, 1.999178301467001900f, 1.999167272845298900f, + 1.999156170719930100f, + 1.999144995091303600f, 1.999133745959830600f, 1.999122423325924200f, + 1.999111027190001000f, + 1.999099557552479900f, 1.999088014413782800f, 1.999076397774334000f, + 1.999064707634560700f, + 1.999052943994892300f, 1.999041106855761900f, 1.999029196217604100f, + 1.999017212080857400f, + 1.999005154445962200f, 1.998993023313361700f, 1.998980818683502100f, + 1.998968540556831800f, + 1.998956188933802800f, 1.998943763814868800f, 1.998931265200486900f, + 1.998918693091116200f, + 1.998906047487219600f, 1.998893328389261400f, 1.998880535797709700f, + 1.998867669713034500f, + 1.998854730135709400f, 1.998841717066209400f, 1.998828630505013400f, + 1.998815470452602400f, + 1.998802236909460500f, 1.998788929876074100f, 1.998775549352932400f, + 1.998762095340527400f, + 1.998748567839354000f, 1.998734966849909000f, 1.998721292372693100f, + 1.998707544408208700f, + 1.998693722956961500f, 1.998679828019459300f, 1.998665859596213500f, + 1.998651817687737300f, + 1.998637702294547000f, 1.998623513417161700f, 1.998609251056103100f, + 1.998594915211895600f, + 1.998580505885066100f, 1.998566023076144600f, 1.998551466785663400f, + 1.998536837014157900f, + 1.998522133762165900f, 1.998507357030227900f, 1.998492506818887200f, + 1.998477583128690100f, + 1.998462585960185000f, 1.998447515313923400f, 1.998432371190459500f, + 1.998417153590349900f, + 1.998401862514154200f, 1.998386497962434800f, 1.998371059935756300f, + 1.998355548434686400f, + 1.998339963459795400f, 1.998324305011656600f, 1.998308573090845200f, + 1.998292767697940100f, + 1.998276888833522300f, 1.998260936498175400f, 1.998244910692486000f, + 1.998228811417043700f, + 1.998212638672439900f, 1.998196392459269400f, 1.998180072778129600f, + 1.998163679629620500f, + 1.998147213014344900f, 1.998130672932908000f, 1.998114059385918400f, + 1.998097372373986300f, + 1.998080611897725700f, 1.998063777957752600f, 1.998046870554686100f, + 1.998029889689147700f, + 1.998012835361761900f, 1.997995707573155600f, 1.997978506323958600f, + 1.997961231614803200f, + 1.997943883446324800f, 1.997926461819161000f, 1.997908966733952500f, + 1.997891398191342400f, + 1.997873756191977000f, 1.997856040736504500f, 1.997838251825576400f, + 1.997820389459846700f, + 1.997802453639972300f, 1.997784444366612600f, 1.997766361640429800f, + 1.997748205462088500f, + 1.997729975832256600f, 1.997711672751604200f, 1.997693296220804000f, + 1.997674846240532000f, + 1.997656322811466500f, 1.997637725934288300f, 1.997619055609681600f, + 1.997600311838332500f, + 1.997581494620930300f, 1.997562603958166600f, 1.997543639850736200f, + 1.997524602299336500f, + 1.997505491304667000f, 1.997486306867430900f, 1.997467048988333000f, + 1.997447717668082000f, + 1.997428312907388200f, 1.997408834706965000f, 1.997389283067528800f, + 1.997369657989798400f, + 1.997349959474495200f, 1.997330187522343700f, 1.997310342134070800f, + 1.997290423310406100f, + 1.997270431052081900f, 1.997250365359833200f, 1.997230226234397900f, + 1.997210013676516700f, + 1.997189727686932400f, 1.997169368266390900f, 1.997148935415640600f, + 1.997128429135433400f, + 1.997107849426522600f, 1.997087196289665000f, 1.997066469725620200f, + 1.997045669735150000f, + 1.997024796319019300f, 1.997003849477995600f, 1.996982829212848900f, + 1.996961735524351900f, + 1.996940568413280600f, 1.996919327880412900f, 1.996898013926530000f, + 1.996876626552415400f, + 1.996855165758855600f, 1.996833631546639300f, 1.996812023916558800f, + 1.996790342869408000f, + 1.996768588405984300f, 1.996746760527087700f, 1.996724859233520500f, + 1.996702884526087900f, + 1.996680836405598100f, 1.996658714872861800f, 1.996636519928692000f, + 1.996614251573904900f, + 1.996591909809319400f, 1.996569494635756600f, 1.996547006054041100f, + 1.996524444064999400f, + 1.996501808669461000f, 1.996479099868258400f, 1.996456317662226300f, + 1.996433462052202600f, + 1.996410533039027400f, 1.996387530623543900f, 1.996364454806597500f, + 1.996341305589037100f, + 1.996318082971713500f, 1.996294786955480800f, 1.996271417541195300f, + 1.996247974729716200f, + 1.996224458521905600f, 1.996200868918628100f, 1.996177205920750800f, + 1.996153469529144100f, + 1.996129659744680300f, 1.996105776568235100f, 1.996081820000686500f, + 1.996057790042915500f, + 1.996033686695805300f, 1.996009509960242400f, 1.995985259837115500f, + 1.995960936327316300f, + 1.995936539431739000f, 1.995912069151280800f, 1.995887525486841300f, + 1.995862908439323100f, + 1.995838218009630800f, 1.995813454198672700f, 1.995788617007359100f, + 1.995763706436603200f, + 1.995738722487320600f, 1.995713665160430600f, 1.995688534456853800f, + 1.995663330377514400f, + 1.995638052923339300f, 1.995612702095257400f, 1.995587277894201400f, + 1.995561780321105600f, + 1.995536209376907600f, 1.995510565062547800f, 1.995484847378968600f, + 1.995459056327116000f, + 1.995433191907938000f, 1.995407254122385700f, 1.995381242971412600f, + 1.995355158455975200f, + 1.995329000577032800f, 1.995302769335546500f, 1.995276464732481200f, + 1.995250086768804100f, + 1.995223635445484900f, 1.995197110763496000f, 1.995170512723813100f, + 1.995143841327413400f, + 1.995117096575278200f, 1.995090278468390600f, 1.995063387007736600f, + 1.995036422194304700f, + 1.995009384029086800f, 1.994982272513076600f, 1.994955087647271000f, + 1.994927829432669800f, + 1.994900497870274900f, 1.994873092961091200f, 1.994845614706126400f, + 1.994818063106391000f, + 1.994790438162897600f, 1.994762739876662100f, 1.994734968248702800f, + 1.994707123280041100f, + 1.994679204971700100f, 1.994651213324707000f, 1.994623148340090700f, + 1.994595010018883000f, + 1.994566798362118300f, 1.994538513370834200f, 1.994510155046070700f, + 1.994481723388870100f, + 1.994453218400277900f, 1.994424640081342100f, 1.994395988433113700f, + 1.994367263456646100f, + 1.994338465152995000f, 1.994309593523219600f, 1.994280648568381500f, + 1.994251630289544600f, + 1.994222538687776100f, 1.994193373764145500f, 1.994164135519725000f, + 1.994134823955589800f, + 1.994105439072817700f, 1.994075980872488800f, 1.994046449355686200f, + 1.994016844523496000f, + 1.993987166377006600f, 1.993957414917308700f, 1.993927590145496900f, + 1.993897692062667200f, + 1.993867720669919400f, 1.993837675968354700f, 1.993807557959078600f, + 1.993777366643197900f, + 1.993747102021822900f, 1.993716764096066200f, 1.993686352867043200f, + 1.993655868335872300f, + 1.993625310503674100f, 1.993594679371572200f, 1.993563974940692800f, + 1.993533197212164800f, + 1.993502346187119700f, 1.993471421866692200f, 1.993440424252018900f, + 1.993409353344239600f, + 1.993378209144496700f, 1.993346991653935300f, 1.993315700873703200f, + 1.993284336804950900f, + 1.993252899448831400f, 1.993221388806500900f, 1.993189804879117500f, + 1.993158147667842800f, + 1.993126417173840500f, 1.993094613398277400f, 1.993062736342323000f, + 1.993030786007148800f, + 1.992998762393930000f, 1.992966665503844000f, 1.992934495338070800f, + 1.992902251897793000f, + 1.992869935184196300f, 1.992837545198469000f, 1.992805081941801700f, + 1.992772545415388200f, + 1.992739935620424700f, 1.992707252558110200f, 1.992674496229646500f, + 1.992641666636237700f, + 1.992608763779091000f, 1.992575787659416100f, 1.992542738278425300f, + 1.992509615637334100f, + 1.992476419737359900f, 1.992443150579723500f, 1.992409808165648100f, + 1.992376392496359300f, + 1.992342903573086000f, 1.992309341397059600f, 1.992275705969513800f, + 1.992241997291685400f, + 1.992208215364813700f, 1.992174360190140900f, 1.992140431768911500f, + 1.992106430102373400f, + 1.992072355191776300f, 1.992038207038373300f, 1.992003985643419700f, + 1.991969691008174100f, + 1.991935323133897000f, 1.991900882021852200f, 1.991866367673306200f, + 1.991831780089527500f, + 1.991797119271788300f, 1.991762385221362600f, 1.991727577939527600f, + 1.991692697427563300f, + 1.991657743686751700f, 1.991622716718378400f, 1.991587616523731000f, + 1.991552443104099800f, + 1.991517196460778500f, 1.991481876595062800f, 1.991446483508251500f, + 1.991411017201645500f, + 1.991375477676549100f, 1.991339864934268800f, 1.991304178976114100f, + 1.991268419803397200f, + 1.991232587417432600f, 1.991196681819537900f, 1.991160703011033200f, + 1.991124650993241400f, + 1.991088525767488200f, 1.991052327335101300f, 1.991016055697411900f, + 1.990979710855753900f, + 1.990943292811463000f, 1.990906801565878600f, 1.990870237120342400f, + 1.990833599476198800f, + 1.990796888634794400f, 1.990760104597479400f, 1.990723247365606200f, + 1.990686316940529800f, + 1.990649313323608100f, 1.990612236516201300f, 1.990575086519673200f, + 1.990537863335389400f, + 1.990500566964718400f, 1.990463197409031700f, 1.990425754669703100f, + 1.990388238748109100f, + 1.990350649645629600f, 1.990312987363646000f, 1.990275251903543600f, + 1.990237443266709400f, + 1.990199561454533600f, 1.990161606468409300f, 1.990123578309731700f, + 1.990085476979899000f, + 1.990047302480312300f, 1.990009054812374800f, 1.989970733977493000f, + 1.989932339977075900f, + 1.989893872812535000f, 1.989855332485284800f, 1.989816718996742200f, + 1.989778032348326700f, + 1.989739272541461100f, 1.989700439577570400f, 1.989661533458082100f, + 1.989622554184426800f, + 1.989583501758037700f, 1.989544376180350600f, 1.989505177452804100f, + 1.989465905576839600f, + 1.989426560553900500f, 1.989387142385433900f, 1.989347651072888900f, + 1.989308086617717500f, + 1.989268449021374300f, 1.989228738285316900f, 1.989188954411005100f, + 1.989149097399901500f, + 1.989109167253472000f, 1.989069163973184300f, 1.989029087560509700f, + 1.988988938016921000f, + 1.988948715343894900f, 1.988908419542910100f, 1.988868050615448100f, + 1.988827608562993200f, + 1.988787093387032600f, 1.988746505089055600f, 1.988705843670554500f, + 1.988665109133024500f, + 1.988624301477963200f, 1.988583420706871100f, 1.988542466821251000f, + 1.988501439822608900f, + 1.988460339712453200f, 1.988419166492295000f, 1.988377920163648000f, + 1.988336600728029000f, + 1.988295208186956700f, 1.988253742541953800f, 1.988212203794544000f, + 1.988170591946255100f, + 1.988128906998616800f, 1.988087148953161700f, 1.988045317811425700f, + 1.988003413574946000f, + 1.987961436245263800f, 1.987919385823922400f, 1.987877262312467600f, + 1.987835065712448600f, + 1.987792796025416500f, 1.987750453252925500f, 1.987708037396532800f, + 1.987665548457797400f, + 1.987622986438281700f, 1.987580351339550700f, 1.987537643163171700f, + 1.987494861910715100f, + 1.987452007583754100f, 1.987409080183863800f, 1.987366079712622900f, + 1.987323006171612500f, + 1.987279859562415900f, 1.987236639886619700f, 1.987193347145813000f, + 1.987149981341587400f, + 1.987106542475537400f, 1.987063030549260300f, 1.987019445564355700f, + 1.986975787522426100f, + 1.986932056425076800f, 1.986888252273915500f, 1.986844375070552900f, + 1.986800424816602200f, + 1.986756401513679400f, 1.986712305163403000f, 1.986668135767394300f, + 1.986623893327277500f, + 1.986579577844678900f, 1.986535189321228000f, 1.986490727758556800f, + 1.986446193158300400f, + 1.986401585522095600f, 1.986356904851583000f, 1.986312151148405200f, + 1.986267324414207500f, + 1.986222424650638400f, 1.986177451859348200f, 1.986132406041990900f, + 1.986087287200222700f, + 1.986042095335702300f, 1.985996830450091200f, 1.985951492545054100f, + 1.985906081622257300f, + 1.985860597683371000f, 1.985815040730067200f, 1.985769410764020900f, + 1.985723707786909900f, + 1.985677931800414500f, 1.985632082806217900f, 1.985586160806005700f, + 1.985540165801466200f, + 1.985494097794290800f, 1.985447956786173100f, 1.985401742778809500f, + 1.985355455773899500f, + 1.985309095773144500f, 1.985262662778249300f, 1.985216156790921000f, + 1.985169577812869500f, + 1.985122925845807400f, 1.985076200891450000f, 1.985029402951515200f, + 1.984982532027723700f, + 1.984935588121798700f, 1.984888571235466200f, 1.984841481370454900f, + 1.984794318528496200f, + 1.984747082711324100f, 1.984699773920675300f, 1.984652392158289500f, + 1.984604937425908300f, + 1.984557409725276700f, 1.984509809058142300f, 1.984462135426255000f, + 1.984414388831367900f, + 1.984366569275236400f, 1.984318676759618400f, 1.984270711286275200f, + 1.984222672856969800f, + 1.984174561473469200f, 1.984126377137541700f, 1.984078119850959200f, + 1.984029789615495900f, + 1.983981386432928800f, 1.983932910305037400f, 1.983884361233604100f, + 1.983835739220414000f, + 1.983787044267254700f, 1.983738276375916800f, 1.983689435548192900f, + 1.983640521785879200f, + 1.983591535090773800f, 1.983542475464678000f, 1.983493342909395500f, + 1.983444137426732600f, + 1.983394859018498900f, 1.983345507686505900f, 1.983296083432567900f, + 1.983246586258502700f, + 1.983197016166129400f, 1.983147373157271300f, 1.983097657233753100f, + 1.983047868397403100f, + 1.982998006650051400f, 1.982948071993531700f, 1.982898064429679900f, + 1.982847983960334600f, + 1.982797830587336800f, 1.982747604312531200f, 1.982697305137763700f, + 1.982646933064884200f, + 1.982596488095744300f, 1.982545970232199000f, 1.982495379476105800f, + 1.982444715829324600f, + 1.982393979293718200f, 1.982343169871152000f, 1.982292287563494300f, + 1.982241332372615600f, + 1.982190304300389400f, 1.982139203348692200f, 1.982088029519402300f, + 1.982036782814401900f, + 1.981985463235574700f, 1.981934070784807400f, 1.981882605463990200f, + 1.981831067275015000f, + 1.981779456219776600f, 1.981727772300172500f, 1.981676015518103500f, + 1.981624185875472000f, + 1.981572283374183800f, 1.981520308016147200f, 1.981468259803273300f, + 1.981416138737475800f, + 1.981363944820670800f, 1.981311678054777500f, 1.981259338441717400f, + 1.981206925983415300f, + 1.981154440681797800f, 1.981101882538794900f, 1.981049251556338900f, + 1.980996547736364900f, + 1.980943771080810700f, 1.980890921591616600f, 1.980837999270726100f, + 1.980785004120084700f, + 1.980731936141640900f, 1.980678795337345900f, 1.980625581709153600f, + 1.980572295259020600f, + 1.980518935988905700f, 1.980465503900771000f, 1.980411998996581200f, + 1.980358421278303200f, + 1.980304770747907300f, 1.980251047407365600f, 1.980197251258653900f, + 1.980143382303749500f, + 1.980089440544633600f, 1.980035425983289300f, 1.979981338621702200f, + 1.979927178461861500f, + 1.979872945505758000f, 1.979818639755386100f, 1.979764261212742400f, + 1.979709809879825800f, + 1.979655285758638900f, 1.979600688851186100f, 1.979546019159474900f, + 1.979491276685515300f, + 1.979436461431320000f, 1.979381573398904400f, 1.979326612590286400f, + 1.979271579007487100f, + 1.979216472652529900f, 1.979161293527440500f, 1.979106041634248100f, + 1.979050716974983800f, + 1.978995319551682100f, 1.978939849366379700f, 1.978884306421115900f, + 1.978828690717932900f, + 1.978773002258875600f, 1.978717241045991700f, 1.978661407081331100f, + 1.978605500366946700f, + 1.978549520904894000f, 1.978493468697231300f, 1.978437343746019600f, + 1.978381146053322000f, + 1.978324875621205300f, 1.978268532451738200f, 1.978212116546992100f, + 1.978155627909041300f, + 1.978099066539962900f, 1.978042432441836400f, 1.977985725616743900f, + 1.977928946066770600f, + 1.977872093794004200f, 1.977815168800534500f, 1.977758171088455100f, + 1.977701100659861300f, + 1.977643957516851400f, 1.977586741661526500f, 1.977529453095990200f, + 1.977472091822348700f, + 1.977414657842711200f, 1.977357151159189400f, 1.977299571773897700f, + 1.977241919688953000f, + 1.977184194906475000f, 1.977126397428586000f, 1.977068527257411300f, + 1.977010584395078300f, + 1.976952568843717700f, 1.976894480605462500f, 1.976836319682448300f, + 1.976778086076813600f, + 1.976719779790699500f, 1.976661400826249500f, 1.976602949185610500f, + 1.976544424870931400f, + 1.976485827884363800f, 1.976427158228062100f, 1.976368415904183900f, + 1.976309600914888400f, + 1.976250713262338600f, 1.976191752948699200f, 1.976132719976138000f, + 1.976073614346825800f, + 1.976014436062935700f, 1.975955185126643300f, 1.975895861540127200f, + 1.975836465305568400f, + 1.975776996425151000f, 1.975717454901061400f, 1.975657840735488800f, + 1.975598153930624900f, + 1.975538394488664200f, 1.975478562411804100f, 1.975418657702244300f, + 1.975358680362187400f, + 1.975298630393838500f, 1.975238507799405500f, 1.975178312581099100f, + 1.975118044741132300f, + 1.975057704281721000f, 1.974997291205083700f, 1.974936805513442000f, + 1.974876247209019100f, + 1.974815616294042200f, 1.974754912770740200f, 1.974694136641345300f, + 1.974633287908091500f, + 1.974572366573216400f, 1.974511372638960000f, 1.974450306107564900f, + 1.974389166981275900f, + 1.974327955262341400f, 1.974266670953011400f, 1.974205314055540000f, + 1.974143884572182400f, + 1.974082382505197400f, 1.974020807856846400f, 1.973959160629393100f, + 1.973897440825104200f, + 1.973835648446248900f, 1.973773783495099500f, 1.973711845973930000f, + 1.973649835885018100f, + 1.973587753230643400f, 1.973525598013088800f, 1.973463370234639600f, + 1.973401069897583200f, + 1.973338697004211100f, 1.973276251556815600f, 1.973213733557693400f, + 1.973151143009142800f, + 1.973088479913465100f, 1.973025744272964200f, 1.972962936089946800f, + 1.972900055366722000f, + 1.972837102105601900f, 1.972774076308901200f, 1.972710977978936900f, + 1.972647807118029300f, + 1.972584563728500700f, 1.972521247812676600f, 1.972457859372884500f, + 1.972394398411455800f, + 1.972330864930723200f, 1.972267258933022600f, 1.972203580420693000f, + 1.972139829396075200f, + 1.972076005861513700f, 1.972012109819354600f, 1.971948141271947500f, + 1.971884100221644300f, + 1.971819986670799500f, 1.971755800621770400f, 1.971691542076916800f, + 1.971627211038601500f, + 1.971562807509189800f, 1.971498331491049700f, 1.971433782986551400f, + 1.971369161998068400f, + 1.971304468527976800f, 1.971239702578655000f, 1.971174864152484400f, + 1.971109953251848600f, + 1.971044969879134600f, 1.970979914036731500f, 1.970914785727030800f, + 1.970849584952427900f, + 1.970784311715319400f, 1.970718966018105500f, 1.970653547863188600f, + 1.970588057252973900f, + 1.970522494189869800f, 1.970456858676286300f, 1.970391150714636800f, + 1.970325370307337100f, + 1.970259517456806100f, 1.970193592165464700f, 1.970127594435737000f, + 1.970061524270049400f, + 1.969995381670831100f, 1.969929166640514100f, 1.969862879181532700f, + 1.969796519296324300f, + 1.969730086987328900f, 1.969663582256988600f, 1.969597005107748900f, + 1.969530355542057800f, + 1.969463633562365400f, 1.969396839171125200f, 1.969329972370792700f, + 1.969263033163826800f, + 1.969196021552688500f, 1.969128937539841500f, 1.969061781127752400f, + 1.968994552318890300f, + 1.968927251115727200f, 1.968859877520737300f, 1.968792431536398000f, + 1.968724913165188900f, + 1.968657322409592500f, 1.968589659272094000f, 1.968521923755181000f, + 1.968454115861344000f, + 1.968386235593076300f, 1.968318282952873600f, 1.968250257943234200f, + 1.968182160566659000f, + 1.968113990825652200f, 1.968045748722719900f, 1.967977434260371300f, + 1.967909047441118100f, + 1.967840588267474500f, 1.967772056741957900f, 1.967703452867087800f, + 1.967634776645386600f, + 1.967566028079379200f, 1.967497207171593500f, 1.967428313924559600f, + 1.967359348340810700f, + 1.967290310422882700f, 1.967221200173313400f, 1.967152017594644200f, + 1.967082762689418500f, + 1.967013435460182700f, 1.966944035909485600f, 1.966874564039879300f, + 1.966805019853917500f, + 1.966735403354157500f, 1.966665714543159000f, 1.966595953423483800f, + 1.966526119997697100f, + 1.966456214268366600f, 1.966386236238062200f, 1.966316185909357200f, + 1.966246063284826700f, + 1.966175868367049400f, 1.966105601158605600f, 1.966035261662079300f, + 1.965964849880056600f, + 1.965894365815126000f, 1.965823809469879400f, 1.965753180846910900f, + 1.965682479948817100f, + 1.965611706778197700f, 1.965540861337654600f, 1.965469943629792700f, + 1.965398953657219600f, + 1.965327891422544900f, 1.965256756928382100f, 1.965185550177345900f, + 1.965114271172054800f, + 1.965042919915129400f, 1.964971496409193100f, 1.964900000656872000f, + 1.964828432660794500f, + 1.964756792423592200f, 1.964685079947899200f, 1.964613295236352000f, + 1.964541438291590000f, + 1.964469509116255000f, 1.964397507712991800f, 1.964325434084447600f, + 1.964253288233272400f, + 1.964181070162119000f, 1.964108779873642100f, 1.964036417370500300f, + 1.963963982655353400f, + 1.963891475730865400f, 1.963818896599701400f, 1.963746245264530700f, + 1.963673521728023900f, + 1.963600725992855200f, 1.963527858061700600f, 1.963454917937239800f, + 1.963381905622154400f, + 1.963308821119128700f, 1.963235664430850200f, 1.963162435560008100f, + 1.963089134509295300f, + 1.963015761281406800f, 1.962942315879040000f, 1.962868798304895400f, + 1.962795208561676200f, + 1.962721546652088200f, 1.962647812578839400f, 1.962574006344640900f, + 1.962500127952206300f, + 1.962426177404252200f, 1.962352154703497200f, 1.962278059852663000f, + 1.962203892854473800f, + 1.962129653711656800f, 1.962055342426941400f, 1.961980959003059500f, + 1.961906503442746300f, + 1.961831975748739200f, 1.961757375923778700f, 1.961682703970607100f, + 1.961607959891970200f, + 1.961533143690616000f, 1.961458255369295400f, 1.961383294930761700f, + 1.961308262377770900f, + 1.961233157713082200f, 1.961157980939456400f, 1.961082732059657800f, + 1.961007411076453000f, + 1.960932017992611500f, 1.960856552810905200f, 1.960781015534108800f, + 1.960705406164999300f, + 1.960629724706357100f, 1.960553971160964500f, 1.960478145531606700f, + 1.960402247821071900f, + 1.960326278032150200f, 1.960250236167635100f, 1.960174122230322400f, + 1.960097936223010400f, + 1.960021678148500500f, 1.959945348009596500f, 1.959868945809104500f, + 1.959792471549834000f, + 1.959715925234596600f, 1.959639306866206600f, 1.959562616447480900f, + 1.959485853981239600f, + 1.959409019470304700f, 1.959332112917501400f, 1.959255134325657000f, + 1.959178083697602300f, + 1.959100961036169800f, 1.959023766344195200f, 1.958946499624516700f, + 1.958869160879975500f, + 1.958791750113414700f, 1.958714267327680500f, 1.958636712525621900f, + 1.958559085710090500f, + 1.958481386883940100f, 1.958403616050027600f, 1.958325773211212300f, + 1.958247858370356400f, + 1.958169871530324600f, 1.958091812693984400f, 1.958013681864205500f, + 1.957935479043860600f, + 1.957857204235825100f, 1.957778857442976900f, 1.957700438668196700f, + 1.957621947914367500f, + 1.957543385184375300f, 1.957464750481108700f, 1.957386043807458800f, + 1.957307265166319500f, + 1.957228414560587200f, 1.957149491993160900f, 1.957070497466942400f, + 1.956991430984836400f, + 1.956912292549749500f, 1.956833082164591600f, 1.956753799832275300f, + 1.956674445555715000f, + 1.956595019337829000f, 1.956515521181537000f, 1.956435951089762200f, + 1.956356309065430100f, + 1.956276595111468900f, 1.956196809230809500f, 1.956116951426385600f, + 1.956037021701132900f, + 1.955957020057990500f, 1.955876946499899700f, 1.955796801029804800f, + 1.955716583650652000f, + 1.955636294365391300f, 1.955555933176974300f, 1.955475500088355900f, + 1.955394995102493100f, + 1.955314418222346100f, 1.955233769450877200f, 1.955153048791052000f, + 1.955072256245838000f, + 1.954991391818206000f, 1.954910455511129000f, 1.954829447327582900f, + 1.954748367270545900f, + 1.954667215342999600f, 1.954585991547927100f, 1.954504695888315000f, + 1.954423328367152600f, + 1.954341888987431100f, 1.954260377752145000f, 1.954178794664291200f, + 1.954097139726869600f, + 1.954015412942881900f, 1.953933614315333200f, 1.953851743847231100f, + 1.953769801541585400f, + 1.953687787401409400f, 1.953605701429718100f, 1.953523543629529700f, + 1.953441314003864900f, + 1.953359012555747200f, 1.953276639288202400f, 1.953194194204259200f, + 1.953111677306948800f, + 1.953029088599305100f, 1.952946428084364900f, 1.952863695765167100f, + 1.952780891644753500f, + 1.952698015726169100f, 1.952615068012460300f, 1.952532048506677300f, + 1.952448957211872200f, + 1.952365794131100300f, 1.952282559267419100f, 1.952199252623889200f, + 1.952115874203572900f, + 1.952032424009536600f, 1.951948902044847900f, 1.951865308312577900f, + 1.951781642815800100f, + 1.951697905557590700f, 1.951614096541028500f, 1.951530215769194700f, + 1.951446263245173500f, + 1.951362238972051500f, 1.951278142952918200f, 1.951193975190865600f, + 1.951109735688987900f, + 1.951025424450382900f, 1.950941041478150100f, 1.950856586775392200f, + 1.950772060345214300f, + 1.950687462190724200f, 1.950602792315032200f, 1.950518050721251600f, + 1.950433237412498000f, + 1.950348352391889600f, 1.950263395662547700f, 1.950178367227595900f, + 1.950093267090159800f, + 1.950008095253369200f, 1.949922851720355100f, 1.949837536494251700f, + 1.949752149578196000f, + 1.949666690975327100f, 1.949581160688787400f, 1.949495558721721500f, + 1.949409885077276500f, + 1.949324139758602700f, 1.949238322768852800f, 1.949152434111181700f, + 1.949066473788747300f, + 1.948980441804710300f, 1.948894338162233900f, 1.948808162864483600f, + 1.948721915914628100f, + 1.948635597315838200f, 1.948549207071288000f, 1.948462745184153400f, + 1.948376211657613500f, + 1.948289606494849800f, 1.948202929699046800f, 1.948116181273391100f, + 1.948029361221072400f, + 1.947942469545282500f, 1.947855506249216700f, 1.947768471336071700f, + 1.947681364809048100f, + 1.947594186671348000f, 1.947506936926177300f, 1.947419615576743600f, + 1.947332222626257500f, + 1.947244758077932200f, 1.947157221934983500f, 1.947069614200629900f, + 1.946981934878092300f, + 1.946894183970594900f, 1.946806361481363500f, 1.946718467413627300f, + 1.946630501770618000f, + 1.946542464555569800f, 1.946454355771719300f, 1.946366175422306500f, + 1.946277923510573200f, + 1.946189600039764300f, 1.946101205013127000f, 1.946012738433911600f, + 1.945924200305370700f, + 1.945835590630759400f, 1.945746909413335900f, 1.945658156656360700f, + 1.945569332363096700f, + 1.945480436536810100f, 1.945391469180769200f, 1.945302430298244900f, + 1.945213319892511200f, + 1.945124137966844200f, 1.945034884524523100f, 1.944945559568829200f, + 1.944856163103046800f, + 1.944766695130463000f, 1.944677155654366900f, 1.944587544678050900f, + 1.944497862204809900f, + 1.944408108237940700f, 1.944318282780743900f, 1.944228385836521700f, + 1.944138417408579400f, + 1.944048377500225100f, 1.943958266114769200f, 1.943868083255524800f, + 1.943777828925807600f, + 1.943687503128936200f, 1.943597105868231500f, 1.943506637147017300f, + 1.943416096968619400f, + 1.943325485336367300f, 1.943234802253592400f, 1.943144047723628400f, + 1.943053221749812400f, + 1.942962324335484100f, 1.942871355483985200f, 1.942780315198660200f, + 1.942689203482856900f, + 1.942598020339924700f, 1.942506765773216500f, 1.942415439786087300f, + 1.942324042381895000f, + 1.942232573564000000f, 1.942141033335765400f, 1.942049421700556600f, + 1.941957738661741900f, + 1.941865984222692900f, 1.941774158386782200f, 1.941682261157386700f, + 1.941590292537884700f, + 1.941498252531658200f, 1.941406141142090600f, 1.941313958372568900f, + 1.941221704226482500f, + 1.941129378707223000f, 1.941036981818185400f, 1.940944513562766300f, + 1.940851973944365900f, + 1.940759362966386600f, 1.940666680632233200f, 1.940573926945313700f, + 1.940481101909038200f, + 1.940388205526819600f, 1.940295237802073500f, 1.940202198738217900f, + 1.940109088338673600f, + 1.940015906606864300f, 1.939922653546215500f, 1.939829329160156500f, + 1.939735933452118000f, + 1.939642466425534300f, 1.939548928083841800f, 1.939455318430479500f, + 1.939361637468889100f, + 1.939267885202515400f, 1.939174061634805000f, 1.939080166769207700f, + 1.938986200609175600f, + 1.938892163158163700f, 1.938798054419629500f, 1.938703874397032800f, + 1.938609623093837000f, + 1.938515300513506700f, 1.938420906659510600f, 1.938326441535318500f, + 1.938231905144404400f, + 1.938137297490243500f, 1.938042618576314400f, 1.937947868406098500f, + 1.937853046983079300f, + 1.937758154310742900f, 1.937663190392578500f, 1.937568155232077600f, + 1.937473048832734500f, + 1.937377871198045600f, 1.937282622331510500f, 1.937187302236631500f, + 1.937091910916912900f, + 1.936996448375861900f, 1.936900914616988900f, 1.936805309643805800f, + 1.936709633459828200f, + 1.936613886068573500f, 1.936518067473562300f, 1.936422177678317300f, + 1.936326216686364400f, + 1.936230184501231500f, 1.936134081126449800f, 1.936037906565552400f, + 1.935941660822075600f, + 1.935845343899558000f, 1.935748955801540800f, 1.935652496531568000f, + 1.935555966093186300f, + 1.935459364489944500f, 1.935362691725394500f, 1.935265947803090900f, + 1.935169132726590500f, + 1.935072246499453000f, 1.934975289125240500f, 1.934878260607517900f, + 1.934781160949852600f, + 1.934683990155814800f, 1.934586748228977100f, 1.934489435172914900f, + 1.934392050991206300f, + 1.934294595687431300f, 1.934197069265173500f, 1.934099471728018700f, + 1.934001803079554700f, + 1.933904063323373300f, 1.933806252463067500f, 1.933708370502233800f, + 1.933610417444471000f, + 1.933512393293380600f, 1.933414298052566600f, 1.933316131725635800f, + 1.933217894316197300f, + 1.933119585827862900f, 1.933021206264247600f, 1.932922755628968100f, + 1.932824233925644300f, + 1.932725641157898600f, 1.932626977329356100f, 1.932528242443643900f, + 1.932429436504392800f, + 1.932330559515235100f, 1.932231611479806800f, 1.932132592401745400f, + 1.932033502284691700f, + 1.931934341132289100f, 1.931835108948183300f, 1.931735805736022800f, + 1.931636431499459000f, + 1.931536986242145200f, 1.931437469967737900f, 1.931337882679895900f, + 1.931238224382281000f, + 1.931138495078557300f, 1.931038694772391200f, 1.930938823467452500f, + 1.930838881167413100f, + 1.930738867875947400f, 1.930638783596732700f, 1.930538628333448900f, + 1.930438402089778200f, + 1.930338104869405900f, 1.930237736676019500f, 1.930137297513309300f, + 1.930036787384968200f, + 1.929936206294691400f, 1.929835554246177400f, 1.929734831243126600f, + 1.929634037289242400f, + 1.929533172388230700f, 1.929432236543799900f, 1.929331229759661200f, + 1.929230152039528500f, + 1.929129003387117800f, 1.929027783806148300f, 1.928926493300341400f, + 1.928825131873421500f, + 1.928723699529115000f, 1.928622196271151800f, 1.928520622103263400f, + 1.928418977029184600f, + 1.928317261052652700f, 1.928215474177407100f, 1.928113616407190600f, + 1.928011687745748300f, + 1.927909688196827400f, 1.927807617764178300f, 1.927705476451554000f, + 1.927603264262709900f, + 1.927500981201404100f, 1.927398627271397000f, 1.927296202476451900f, + 1.927193706820335100f, + 1.927091140306814500f, 1.926988502939661400f, 1.926885794722649600f, + 1.926783015659555300f, + 1.926680165754157500f, 1.926577245010237400f, 1.926474253431579500f, + 1.926371191021970100f, + 1.926268057785198700f, 1.926164853725057300f, 1.926061578845340600f, + 1.925958233149845000f, + 1.925854816642371000f, 1.925751329326720600f, 1.925647771206698600f, + 1.925544142286112800f, + 1.925440442568773000f, 1.925336672058492300f, 1.925232830759086000f, + 1.925128918674371900f, + 1.925024935808170600f, 1.924920882164305300f, 1.924816757746601800f, + 1.924712562558888100f, + 1.924608296604995800f, 1.924503959888757900f, 1.924399552414010700f, + 1.924295074184593000f, + 1.924190525204346300f, 1.924085905477114400f, 1.923981215006744100f, + 1.923876453797084300f, + 1.923771621851986700f, 1.923666719175306100f, 1.923561745770898900f, + 1.923456701642625200f, + 1.923351586794346900f, 1.923246401229928600f, 1.923141144953238300f, + 1.923035817968145300f, + 1.922930420278522500f, 1.922824951888245000f, 1.922719412801190600f, + 1.922613803021239600f, + 1.922508122552275100f, 1.922402371398182600f, 1.922296549562850100f, + 1.922190657050168800f, + 1.922084693864031700f, 1.921978660008334600f, 1.921872555486976700f, + 1.921766380303858500f, + 1.921660134462884100f, 1.921553817967959900f, 1.921447430822994500f, + 1.921340973031900000f, + 1.921234444598590100f, 1.921127845526981600f, 1.921021175820994100f, + 1.920914435484549100f, + 1.920807624521571700f, 1.920700742935988600f, 1.920593790731729600f, + 1.920486767912727300f, + 1.920379674482916500f, 1.920272510446234400f, 1.920165275806621400f, + 1.920057970568020100f, + 1.919950594734376000f, 1.919843148309637000f, 1.919735631297753400f, + 1.919628043702678300f, + 1.919520385528367300f, 1.919412656778779000f, 1.919304857457874200f, + 1.919196987569616200f, + 1.919089047117971100f, 1.918981036106907700f, 1.918872954540397300f, + 1.918764802422413500f, + 1.918656579756932800f, 1.918548286547934400f, 1.918439922799399800f, + 1.918331488515313300f, + 1.918222983699661600f, 1.918114408356434300f, 1.918005762489623400f, + 1.917897046103223200f, + 1.917788259201231200f, 1.917679401787647100f, 1.917570473866473200f, + 1.917461475441714500f, + 1.917352406517378600f, 1.917243267097475700f, 1.917134057186018300f, + 1.917024776787022100f, + 1.916915425904504700f, 1.916806004542486800f, 1.916696512704991500f, + 1.916586950396044400f, + 1.916477317619674100f, 1.916367614379911100f, 1.916257840680788900f, + 1.916147996526343700f, + 1.916038081920614400f, 1.915928096867641800f, 1.915818041371470000f, + 1.915707915436145200f, + 1.915597719065716700f, 1.915487452264236000f, 1.915377115035757200f, + 1.915266707384337200f, + 1.915156229314035200f, 1.915045680828913400f, 1.914935061933036300f, + 1.914824372630470800f, + 1.914713612925287100f, 1.914602782821557000f, 1.914491882323355700f, + 1.914380911434760500f, + 1.914269870159851700f, 1.914158758502712000f, 1.914047576467426500f, + 1.913936324058083100f, + 1.913825001278772100f, 1.913713608133586600f, 1.913602144626622500f, + 1.913490610761977600f, + 1.913379006543752800f, 1.913267331976051400f, 1.913155587062979500f, + 1.913043771808645700f, + 1.912931886217160900f, 1.912819930292639000f, 1.912707904039196300f, + 1.912595807460951500f, + 1.912483640562026200f, 1.912371403346544400f, 1.912259095818632700f, + 1.912146717982420500f, + 1.912034269842039600f, 1.911921751401624200f, 1.911809162665311500f, + 1.911696503637241100f, + 1.911583774321554700f, 1.911470974722397500f, 1.911358104843916500f, + 1.911245164690262000f, + 1.911132154265586100f, 1.911019073574044200f, 1.910905922619793800f, + 1.910792701406995000f, + 1.910679409939810600f, 1.910566048222406300f, 1.910452616258949900f, + 1.910339114053611900f, + 1.910225541610565800f, 1.910111898933986900f, 1.909998186028053700f, + 1.909884402896947100f, + 1.909770549544850500f, 1.909656625975950200f, 1.909542632194434700f, + 1.909428568204495100f, + 1.909314434010325400f, 1.909200229616121700f, 1.909085955026083200f, + 1.908971610244411600f, + 1.908857195275310800f, 1.908742710122987700f, 1.908628154791651300f, + 1.908513529285513500f, + 1.908398833608789100f, 1.908284067765694900f, 1.908169231760450400f, + 1.908054325597278200f, + 1.907939349280402400f, 1.907824302814050900f, 1.907709186202453600f, + 1.907593999449842800f, + 1.907478742560453600f, 1.907363415538523700f, 1.907248018388293400f, + 1.907132551114005600f, + 1.907017013719905600f, 1.906901406210241200f, 1.906785728589263300f, + 1.906669980861224900f, + 1.906554163030381500f, 1.906438275100991600f, 1.906322317077316300f, + 1.906206288963618700f, + 1.906090190764164700f, 1.905974022483223300f, 1.905857784125065500f, + 1.905741475693964800f, + 1.905625097194197900f, 1.905508648630043700f, 1.905392130005783400f, + 1.905275541325701400f, + 1.905158882594083900f, 1.905042153815220700f, 1.904925354993402900f, + 1.904808486132925300f, + 1.904691547238084800f, 1.904574538313180700f, 1.904457459362515200f, + 1.904340310390393100f, + 1.904223091401121600f, 1.904105802399010300f, 1.903988443388371600f, + 1.903871014373520700f, + 1.903753515358774800f, 1.903635946348454500f, 1.903518307346881800f, + 1.903400598358382600f, + 1.903282819387284200f, 1.903164970437917400f, 1.903047051514615000f, + 1.902929062621712600f, + 1.902811003763547900f, 1.902692874944462300f, 1.902574676168798700f, + 1.902456407440902700f, + 1.902338068765123200f, 1.902219660145810800f, 1.902101181587319000f, + 1.901982633094004200f, + 1.901864014670225000f, 1.901745326320342500f, 1.901626568048721000f, + 1.901507739859726200f, + 1.901388841757727600f, 1.901269873747096600f, 1.901150835832207100f, + 1.901031728017436300f, + 1.900912550307162700f, 1.900793302705768900f, 1.900673985217638900f, + 1.900554597847159400f, + 1.900435140598720500f, 1.900315613476714100f, 1.900196016485534700f, + 1.900076349629579600f, + 1.899956612913248800f, 1.899836806340944300f, 1.899716929917071500f, + 1.899596983646037600f, + 1.899476967532252900f, 1.899356881580129800f, 1.899236725794083600f, + 1.899116500178532200f, + 1.898996204737895900f, 1.898875839476597700f, 1.898755404399062900f, + 1.898634899509719500f, + 1.898514324812998300f, 1.898393680313332600f, 1.898272966015157800f, + 1.898152181922912600f, + 1.898031328041037700f, 1.897910404373976500f, 1.897789410926175000f, + 1.897668347702081900f, + 1.897547214706148300f, 1.897426011942827900f, 1.897304739416577200f, + 1.897183397131854600f, + 1.897061985093121800f, 1.896940503304842800f, 1.896818951771484000f, + 1.896697330497514800f, + 1.896575639487406300f, 1.896453878745633100f, 1.896332048276672100f, + 1.896210148085002400f, + 1.896088178175106200f, 1.895966138551467700f, 1.895844029218574100f, + 1.895721850180915000f, + 1.895599601442982600f, 1.895477283009271400f, 1.895354894884279100f, + 1.895232437072505300f, + 1.895109909578452500f, 1.894987312406625700f, 1.894864645561532100f, + 1.894741909047682500f, + 1.894619102869589100f, 1.894496227031767100f, 1.894373281538734400f, + 1.894250266395011600f, + 1.894127181605121100f, 1.894004027173588700f, 1.893880803104942600f, + 1.893757509403713100f, + 1.893634146074433500f, 1.893510713121639300f, 1.893387210549869000f, + 1.893263638363663400f, + 1.893139996567565900f, 1.893016285166122500f, 1.892892504163881600f, + 1.892768653565394300f, + 1.892644733375214300f, 1.892520743597897700f, 1.892396684238003300f, + 1.892272555300092300f, + 1.892148356788728700f, 1.892024088708479200f, 1.891899751063912200f, + 1.891775343859599400f, + 1.891650867100115300f, 1.891526320790036100f, 1.891401704933941100f, + 1.891277019536412400f, + 1.891152264602033800f, 1.891027440135392600f, 1.890902546141078000f, + 1.890777582623682300f, + 1.890652549587799700f, 1.890527447038027300f, 1.890402274978965100f, + 1.890277033415215200f, + 1.890151722351382200f, 1.890026341792073500f, 1.889900891741899100f, + 1.889775372205471300f, + 1.889649783187405100f, 1.889524124692318200f, 1.889398396724830500f, + 1.889272599289564900f, + 1.889146732391146400f, 1.889020796034202700f, 1.888894790223364600f, + 1.888768714963264400f, + 1.888642570258537700f, 1.888516356113822700f, 1.888390072533759700f, + 1.888263719522991900f, + 1.888137297086165000f, 1.888010805227927000f, 1.887884243952928600f, + 1.887757613265823400f, + 1.887630913171267000f, 1.887504143673917700f, 1.887377304778437000f, + 1.887250396489487800f, + 1.887123418811736500f, 1.886996371749851700f, 1.886869255308504200f, + 1.886742069492368000f, + 1.886614814306119400f, 1.886487489754437300f, 1.886360095842002600f, + 1.886232632573499700f, + 1.886105099953614900f, 1.885977497987037000f, 1.885849826678457800f, + 1.885722086032571200f, + 1.885594276054074300f, 1.885466396747665700f, 1.885338448118047700f, + 1.885210430169924200f, + 1.885082342908002400f, 1.884954186336991400f, 1.884825960461603100f, + 1.884697665286552400f, + 1.884569300816556000f, 1.884440867056333700f, 1.884312364010607600f, + 1.884183791684102400f, + 1.884055150081545200f, 1.883926439207665800f, 1.883797659067196800f, + 1.883668809664872600f, + 1.883539891005431100f, 1.883410903093611900f, 1.883281845934157800f, + 1.883152719531813800f, + 1.883023523891327300f, 1.882894259017448900f, 1.882764924914930700f, + 1.882635521588528400f, + 1.882506049042999700f, 1.882376507283104900f, 1.882246896313606800f, + 1.882117216139270700f, + 1.881987466764865100f, 1.881857648195159900f, 1.881727760434928500f, + 1.881597803488946500f, + 1.881467777361992100f, 1.881337682058845700f, 1.881207517584290600f, + 1.881077283943112900f, + 1.880946981140100500f, 1.880816609180044700f, 1.880686168067738500f, + 1.880555657807977800f, + 1.880425078405561600f, 1.880294429865290600f, 1.880163712191968300f, + 1.880032925390400900f, + 1.879902069465397200f, 1.879771144421768200f, 1.879640150264327600f, + 1.879509086997891900f, + 1.879377954627279700f, 1.879246753157312700f, 1.879115482592814500f, + 1.878984142938611600f, + 1.878852734199532900f, 1.878721256380410100f, 1.878589709486077300f, + 1.878458093521370800f, + 1.878326408491130200f, 1.878194654400196600f, 1.878062831253414900f, + 1.877930939055631100f, + 1.877798977811695200f, 1.877666947526458700f, 1.877534848204775800f, + 1.877402679851504000f, + 1.877270442471502100f, 1.877138136069632400f, 1.877005760650759500f, + 1.876873316219750200f, + 1.876740802781474500f, 1.876608220340804100f, 1.876475568902614000f, + 1.876342848471781200f, + 1.876210059053185600f, 1.876077200651709500f, 1.875944273272237800f, + 1.875811276919657500f, + 1.875678211598858800f, 1.875545077314734000f, 1.875411874072178100f, + 1.875278601876088700f, + 1.875145260731365700f, 1.875011850642911600f, 1.874878371615631900f, + 1.874744823654434000f, + 1.874611206764227800f, 1.874477520949926500f, 1.874343766216444800f, + 1.874209942568701100f, + 1.874076050011615400f, 1.873942088550110400f, 1.873808058189111700f, + 1.873673958933546900f, + 1.873539790788347100f, 1.873405553758444600f, 1.873271247848775400f, + 1.873136873064277000f, + 1.873002429409890600f, 1.872867916890558900f, 1.872733335511227700f, + 1.872598685276845000f, + 1.872463966192361900f, 1.872329178262731200f, 1.872194321492908700f, + 1.872059395887852900f, + 1.871924401452524700f, 1.871789338191887100f, 1.871654206110906500f, + 1.871519005214550700f, + 1.871383735507791100f, 1.871248396995601300f, 1.871112989682956800f, + 1.870977513574836500f, + 1.870841968676221400f, 1.870706354992095000f, 1.870570672527443600f, + 1.870434921287255700f, + 1.870299101276522400f, 1.870163212500237900f, 1.870027254963397800f, + 1.869891228671001200f, + 1.869755133628049600f, 1.869618969839546500f, 1.869482737310498100f, + 1.869346436045913800f, + 1.869210066050804600f, 1.869073627330184700f, 1.868937119889070300f, + 1.868800543732480600f, + 1.868663898865437200f, 1.868527185292963700f, 1.868390403020087100f, + 1.868253552051836200f, + 1.868116632393243000f, 1.867979644049341200f, 1.867842587025167800f, + 1.867705461325761800f, + 1.867568266956164800f, 1.867431003921421500f, 1.867293672226578300f, + 1.867156271876684500f, + 1.867018802876792200f, 1.866881265231955500f, 1.866743658947231300f, + 1.866605984027679000f, + 1.866468240478360600f, 1.866330428304340300f, 1.866192547510685300f, + 1.866054598102465000f, + 1.865916580084751500f, 1.865778493462619100f, 1.865640338241145100f, + 1.865502114425408900f, + 1.865363822020492700f, 1.865225461031480900f, 1.865087031463460900f, + 1.864948533321522300f, + 1.864809966610757400f, 1.864671331336260600f, 1.864532627503129100f, + 1.864393855116463200f, + 1.864255014181364500f, 1.864116104702938000f, 1.863977126686291200f, + 1.863838080136534000f, + 1.863698965058778300f, 1.863559781458139300f, 1.863420529339734100f, + 1.863281208708683000f, + 1.863141819570107900f, 1.863002361929134500f, 1.862862835790889400f, + 1.862723241160503300f, + 1.862583578043108100f, 1.862443846443839300f, 1.862304046367834200f, + 1.862164177820232700f, + 1.862024240806177800f, 1.861884235330814300f, 1.861744161399289600f, + 1.861604019016754200f, + 1.861463808188360500f, 1.861323528919263800f, 1.861183181214621600f, + 1.861042765079594200f, + 1.860902280519344500f, 1.860761727539037300f, 1.860621106143840500f, + 1.860480416338924600f, + 1.860339658129461800f, 1.860198831520627900f, 1.860057936517600700f, + 1.859916973125560000f, + 1.859775941349689000f, 1.859634841195173100f, 1.859493672667199800f, + 1.859352435770959900f, + 1.859211130511645900f, 1.859069756894453400f, 1.858928314924580300f, + 1.858786804607227100f, + 1.858645225947596300f, 1.858503578950893900f, 1.858361863622327400f, + 1.858220079967107600f, + 1.858078227990447300f, 1.857936307697561900f, 1.857794319093669900f, + 1.857652262183991000f, + 1.857510136973749000f, 1.857367943468169100f, 1.857225681672479300f, + 1.857083351591910300f, + 1.856940953231694900f, 1.856798486597069000f, 1.856655951693270600f, + 1.856513348525540300f, + 1.856370677099121100f, 1.856227937419258700f, 1.856085129491201100f, + 1.855942253320199200f, + 1.855799308911506100f, 1.855656296270377300f, 1.855513215402071000f, + 1.855370066311848000f, + 1.855226849004971500f, 1.855083563486706900f, 1.854940209762322700f, + 1.854796787837089500f, + 1.854653297716280400f, 1.854509739405171300f, 1.854366112909040300f, + 1.854222418233168400f, + 1.854078655382838300f, 1.853934824363336200f, 1.853790925179950500f, + 1.853646957837971500f, + 1.853502922342692600f, 1.853358818699409900f, 1.853214646913421200f, + 1.853070406990027500f, + 1.852926098934532200f, 1.852781722752241000f, 1.852637278448462200f, + 1.852492766028506400f, + 1.852348185497687300f, 1.852203536861320600f, 1.852058820124724300f, + 1.851914035293219700f, + 1.851769182372129600f, 1.851624261366780400f, 1.851479272282500000f, + 1.851334215124619300f, + 1.851189089898471800f, 1.851043896609393400f, 1.850898635262721900f, + 1.850753305863798800f, + 1.850607908417967200f, 1.850462442930572900f, 1.850316909406964200f, + 1.850171307852492200f, + 1.850025638272510000f, 1.849879900672373600f, 1.849734095057441200f, + 1.849588221433073700f, + 1.849442279804634600f, 1.849296270177489800f, 1.849150192557007300f, + 1.849004046948558200f, + 1.848857833357515900f, 1.848711551789256300f, 1.848565202249157400f, + 1.848418784742600400f, + 1.848272299274968500f, 1.848125745851647800f, 1.847979124478026100f, + 1.847832435159495000f, + 1.847685677901447200f, 1.847538852709279100f, 1.847391959588388300f, + 1.847244998544176300f, + 1.847097969582046200f, 1.846950872707404000f, 1.846803707925657600f, + 1.846656475242218300f, + 1.846509174662499300f, 1.846361806191916000f, 1.846214369835887500f, + 1.846066865599834000f, + 1.845919293489179000f, 1.845771653509348200f, 1.845623945665770100f, + 1.845476169963875500f, + 1.845328326409097400f, 1.845180415006871800f, 1.845032435762637100f, + 1.844884388681833800f, + 1.844736273769905300f, 1.844588091032297400f, 1.844439840474458200f, + 1.844291522101838800f, + 1.844143135919891900f, 1.843994681934073600f, 1.843846160149842200f, + 1.843697570572658200f, + 1.843548913207985000f, 1.843400188061288000f, 1.843251395138035800f, + 1.843102534443698900f, + 1.842953605983750400f, 1.842804609763666100f, 1.842655545788924000f, + 1.842506414065004900f, + 1.842357214597392100f, 1.842207947391570900f, 1.842058612453029600f, + 1.841909209787258900f, + 1.841759739399751800f, 1.841610201296003800f, 1.841460595481513100f, + 1.841310921961780500f, + 1.841161180742308500f, 1.841011371828603200f, 1.840861495226172600f, + 1.840711550940526700f, + 1.840561538977179200f, 1.840411459341645400f, 1.840261312039443100f, + 1.840111097076092800f, + 1.839960814457117600f, 1.839810464188043100f, 1.839660046274397100f, + 1.839509560721709800f, + 1.839359007535514400f, 1.839208386721346500f, 1.839057698284743500f, + 1.838906942231246100f, + 1.838756118566397200f, 1.838605227295741800f, 1.838454268424828400f, + 1.838303241959206700f, + 1.838152147904429800f, 1.838000986266052900f, 1.837849757049633900f, + 1.837698460260732900f, + 1.837547095904912700f, 1.837395663987738700f, 1.837244164514778600f, + 1.837092597491602100f, + 1.836940962923782700f, 1.836789260816895000f, 1.836637491176516600f, + 1.836485654008228200f, + 1.836333749317611700f, 1.836181777110252900f, 1.836029737391738700f, + 1.835877630167659800f, + 1.835725455443608200f, 1.835573213225179400f, 1.835420903517970500f, + 1.835268526327581900f, + 1.835116081659615700f, 1.834963569519677100f, 1.834810989913373500f, + 1.834658342846314800f, + 1.834505628324113200f, 1.834352846352383700f, 1.834199996936744000f, + 1.834047080082813300f, + 1.833894095796214400f, 1.833741044082571900f, 1.833587924947513100f, + 1.833434738396668000f, + 1.833281484435668400f, 1.833128163070149300f, 1.832974774305747600f, + 1.832821318148103500f, + 1.832667794602858400f, 1.832514203675657600f, 1.832360545372147900f, + 1.832206819697979000f, + 1.832053026658802700f, 1.831899166260273700f, 1.831745238508049300f, + 1.831591243407788300f, + 1.831437180965153100f, 1.831283051185808300f, 1.831128854075420500f, + 1.830974589639659000f, + 1.830820257884196100f, 1.830665858814705600f, 1.830511392436864800f, + 1.830356858756352800f, + 1.830202257778851300f, 1.830047589510044500f, 1.829892853955619200f, + 1.829738051121264600f, + 1.829583181012672400f, 1.829428243635536500f, 1.829273238995553700f, + 1.829118167098423100f, + 1.828963027949846100f, 1.828807821555527000f, 1.828652547921171900f, + 1.828497207052490100f, + 1.828341798955192900f, 1.828186323634994200f, 1.828030781097610400f, + 1.827875171348760400f, + 1.827719494394165500f, 1.827563750239549400f, 1.827407938890638600f, + 1.827252060353161500f, + 1.827096114632849700f, 1.826940101735436500f, 1.826784021666658400f, + 1.826627874432253700f, + 1.826471660037963800f, 1.826315378489531800f, 1.826159029792704400f, + 1.826002613953229500f, + 1.825846130976858100f, 1.825689580869344100f, 1.825532963636443000f, + 1.825376279283913200f, + 1.825219527817515800f, 1.825062709243013800f, 1.824905823566173000f, + 1.824748870792761900f, + 1.824591850928550800f, 1.824434763979313300f, 1.824277609950824700f, + 1.824120388848863300f, + 1.823963100679209600f, 1.823805745447646600f, 1.823648323159960100f, + 1.823490833821937600f, + 1.823333277439369600f, 1.823175654018049300f, 1.823017963563772000f, + 1.822860206082335300f, + 1.822702381579539800f, 1.822544490061187800f, 1.822386531533084900f, + 1.822228506001038800f, + 1.822070413470859600f, 1.821912253948359700f, 1.821754027439354400f, + 1.821595733949661100f, + 1.821437373485099900f, 1.821278946051493100f, 1.821120451654665700f, + 1.820961890300445400f, + 1.820803261994661500f, 1.820644566743146800f, 1.820485804551735800f, + 1.820326975426265600f, + 1.820168079372576300f, 1.820009116396509800f, 1.819850086503910700f, + 1.819690989700625900f, + 1.819531825992505500f, 1.819372595385401000f, 1.819213297885166900f, + 1.819053933497660300f, + 1.818894502228740600f, 1.818735004084269600f, 1.818575439070111200f, + 1.818415807192132600f, + 1.818256108456203000f, 1.818096342868193800f, 1.817936510433979300f, + 1.817776611159436000f, + 1.817616645050443000f, 1.817456612112881900f, 1.817296512352636300f, + 1.817136345775592900f, + 1.816976112387640700f, 1.816815812194670700f, 1.816655445202576700f, + 1.816495011417255300f, + 1.816334510844604700f, 1.816173943490526400f, 1.816013309360923900f, + 1.815852608461703300f, + 1.815691840798773000f, 1.815531006378043900f, 1.815370105205429600f, + 1.815209137286846200f, + 1.815048102628211500f, 1.814887001235446600f, 1.814725833114474700f, + 1.814564598271221300f, + 1.814403296711615000f, 1.814241928441585800f, 1.814080493467067300f, + 1.813918991793994900f, + 1.813757423428306000f, 1.813595788375941700f, 1.813434086642844400f, + 1.813272318234959700f, + 1.813110483158235400f, 1.812948581418621500f, 1.812786613022070700f, + 1.812624577974538000f, + 1.812462476281981200f, 1.812300307950360300f, 1.812138072985637800f, + 1.811975771393778300f, + 1.811813403180749300f, 1.811650968352521000f, 1.811488466915065000f, + 1.811325898874356800f, + 1.811163264236372900f, 1.811000563007093100f, 1.810837795192499400f, + 1.810674960798576600f, + 1.810512059831311400f, 1.810349092296693400f, 1.810186058200714100f, + 1.810022957549368000f, + 1.809859790348652200f, 1.809696556604565300f, 1.809533256323109200f, + 1.809369889510288100f, + 1.809206456172108200f, 1.809042956314578900f, 1.808879389943711200f, + 1.808715757065519200f, + 1.808552057686019200f, 1.808388291811230000f, 1.808224459447172800f, + 1.808060560599871200f, + 1.807896595275351200f, 1.807732563479641300f, 1.807568465218772900f, + 1.807404300498778800f, + 1.807240069325695400f, 1.807075771705560800f, 1.806911407644415700f, + 1.806746977148303300f, + 1.806582480223269500f, 1.806417916875362000f, 1.806253287110631600f, + 1.806088590935131000f, + 1.805923828354915900f, 1.805758999376044100f, 1.805594104004575800f, + 1.805429142246573600f, + 1.805264114108102900f, 1.805099019595231200f, 1.804933858714028700f, + 1.804768631470567500f, + 1.804603337870923000f, 1.804437977921172300f, 1.804272551627395400f, + 1.804107058995674500f, + 1.803941500032094200f, 1.803775874742741500f, 1.803610183133706400f, + 1.803444425211080400f, + 1.803278600980958300f, 1.803112710449436900f, 1.802946753622615400f, + 1.802780730506595700f, + 1.802614641107481900f, 1.802448485431380900f, 1.802282263484401300f, + 1.802115975272655000f, + 1.801949620802255600f, 1.801783200079319900f, 1.801616713109966300f, + 1.801450159900316300f, + 1.801283540456493700f, 1.801116854784624400f, 1.800950102890836800f, + 1.800783284781262200f, + 1.800616400462033800f, 1.800449449939287800f, 1.800282433219162000f, + 1.800115350307797600f, + 1.799948201211337500f, 1.799780985935927300f, 1.799613704487715200f, + 1.799446356872851400f, + 1.799278943097489100f, 1.799111463167783400f, 1.798943917089892000f, + 1.798776304869975200f, + 1.798608626514195800f, 1.798440882028718500f, 1.798273071419711000f, + 1.798105194693343500f, + 1.797937251855787700f, 1.797769242913218800f, 1.797601167871813800f, + 1.797433026737752700f, + 1.797264819517217200f, 1.797096546216391900f, 1.796928206841463800f, + 1.796759801398622100f, + 1.796591329894058800f, 1.796422792333968000f, 1.796254188724546500f, + 1.796085519071992900f, + 1.795916783382509200f, 1.795747981662299200f, 1.795579113917569200f, + 1.795410180154527900f, + 1.795241180379386800f, 1.795072114598359200f, 1.794902982817661500f, + 1.794733785043511900f, + 1.794564521282131300f, 1.794395191539743400f, 1.794225795822573600f, + 1.794056334136850300f, + 1.793886806488804100f, 1.793717212884667900f, 1.793547553330677300f, + 1.793377827833070100f, + 1.793208036398086900f, 1.793038179031970000f, 1.792868255740965000f, + 1.792698266531319400f, + 1.792528211409282900f, 1.792358090381108300f, 1.792187903453050100f, + 1.792017650631366100f, + 1.791847331922315600f, 1.791676947332161000f, 1.791506496867166600f, + 1.791335980533599300f, + 1.791165398337728900f, 1.790994750285827000f, 1.790824036384167900f, + 1.790653256639028100f, + 1.790482411056686800f, 1.790311499643425500f, 1.790140522405528200f, + 1.789969479349281100f, + 1.789798370480973000f, 1.789627195806895200f, 1.789455955333341100f, + 1.789284649066606800f, + 1.789113277012990900f, 1.788941839178794100f, 1.788770335570319700f, + 1.788598766193873600f, + 1.788427131055763600f, 1.788255430162300400f, 1.788083663519796800f, + 1.787911831134568300f, + 1.787739933012932900f, 1.787567969161210300f, 1.787395939585723500f, + 1.787223844292797500f, + 1.787051683288759500f, 1.786879456579939700f, 1.786707164172670200f, + 1.786534806073285700f, + 1.786362382288123400f, 1.786189892823522700f, 1.786017337685825700f, + 1.785844716881376700f, + 1.785672030416522300f, 1.785499278297612000f, 1.785326460530997300f, + 1.785153577123032000f, + 1.784980628080072900f, 1.784807613408478300f, 1.784634533114609800f, + 1.784461387204831400f, + 1.784288175685508700f, 1.784114898563010200f, 1.783941555843707100f, + 1.783768147533972200f, + 1.783594673640181800f, 1.783421134168713800f, 1.783247529125948900f, + 1.783073858518269700f, + 1.782900122352062000f, 1.782726320633713200f, 1.782552453369613800f, + 1.782378520566156200f, + 1.782204522229735600f, 1.782030458366749200f, 1.781856328983596900f, + 1.781682134086680900f, + 1.781507873682406200f, 1.781333547777179200f, 1.781159156377410100f, + 1.780984699489510200f, + 1.780810177119894100f, 1.780635589274978600f, 1.780460935961182300f, + 1.780286217184927000f, + 1.780111432952636600f, 1.779936583270737400f, 1.779761668145658300f, + 1.779586687583830200f, + 1.779411641591686500f, 1.779236530175663600f, 1.779061353342199500f, + 1.778886111097735000f, + 1.778710803448713400f, 1.778535430401580100f, 1.778359991962783000f, + 1.778184488138772900f, + 1.778008918936002000f, 1.777833284360925900f, 1.777657584420002000f, + 1.777481819119690200f, + 1.777305988466453000f, 1.777130092466755200f, 1.776954131127064200f, + 1.776778104453849100f, + 1.776602012453582400f, 1.776425855132738100f, 1.776249632497793200f, + 1.776073344555227000f, + 1.775896991311520800f, 1.775720572773158900f, 1.775544088946627600f, + 1.775367539838415700f, + 1.775190925455014400f, 1.775014245802917200f, 1.774837500888620400f, + 1.774660690718622000f, + 1.774483815299423100f, 1.774306874637527000f, 1.774129868739439100f, + 1.773952797611667100f, + 1.773775661260722100f, 1.773598459693116500f, 1.773421192915365400f, + 1.773243860933986400f, + 1.773066463755499800f, 1.772889001386427800f, 1.772711473833295200f, + 1.772533881102629000f, + 1.772356223200959100f, 1.772178500134817100f, 1.772000711910737700f, + 1.771822858535257600f, + 1.771644940014915700f, 1.771466956356254000f, 1.771288907565816000f, + 1.771110793650148500f, + 1.770932614615799800f, 1.770754370469321400f, 1.770576061217266500f, + 1.770397686866191300f, + 1.770219247422653700f, 1.770040742893215000f, 1.769862173284438000f, + 1.769683538602888000f, + 1.769504838855133100f, 1.769326074047743700f, 1.769147244187292200f, + 1.768968349280353800f, + 1.768789389333506000f, 1.768610364353328600f, 1.768431274346403900f, + 1.768252119319316400f, + 1.768072899278653200f, 1.767893614231003800f, 1.767714264182959500f, + 1.767534849141115100f, + 1.767355369112067100f, 1.767175824102414000f, 1.766996214118757800f, + 1.766816539167701800f, + 1.766636799255852300f, 1.766456994389817600f, 1.766277124576209000f, + 1.766097189821639300f, + 1.765917190132724600f, 1.765737125516083000f, 1.765556995978334800f, + 1.765376801526102700f, + 1.765196542166012100f, 1.765016217904690900f, 1.764835828748768400f, + 1.764655374704877700f, + 1.764474855779653200f, 1.764294271979732100f, 1.764113623311754000f, + 1.763932909782361100f, + 1.763752131398197200f, 1.763571288165909400f, 1.763390380092146400f, + 1.763209407183560200f, + 1.763028369446804500f, 1.762847266888535100f, 1.762666099515411100f, + 1.762484867334093400f, + 1.762303570351245300f, 1.762122208573532600f, 1.761940782007623600f, + 1.761759290660188400f, + 1.761577734537900500f, 1.761396113647435000f, 1.761214427995469100f, + 1.761032677588683800f, + 1.760850862433760700f, 1.760668982537384900f, 1.760487037906243600f, + 1.760305028547026500f, + 1.760122954466425600f, 1.759940815671135100f, 1.759758612167851700f, + 1.759576343963274600f, + 1.759394011064105100f, 1.759211613477047200f, 1.759029151208807400f, + 1.758846624266093800f, + 1.758664032655617500f, 1.758481376384092500f, 1.758298655458233600f, + 1.758115869884759700f, + 1.757933019670390800f, 1.757750104821850000f, 1.757567125345862700f, + 1.757384081249156100f, + 1.757200972538460700f, 1.757017799220508500f, 1.756834561302034400f, + 1.756651258789775800f, + 1.756467891690471700f, 1.756284460010864200f, 1.756100963757697900f, + 1.755917402937718900f, + 1.755733777557676500f, 1.755550087624322000f, 1.755366333144409200f, + 1.755182514124693900f, + 1.754998630571935200f, 1.754814682492893600f, 1.754630669894332600f, + 1.754446592783017500f, + 1.754262451165716300f, 1.754078245049199600f, 1.753893974440240000f, + 1.753709639345612600f, + 1.753525239772095100f, 1.753340775726466700f, 1.753156247215510400f, + 1.752971654246010300f, + 1.752786996824753600f, 1.752602274958529500f, 1.752417488654129700f, + 1.752232637918348200f, + 1.752047722757981600f, 1.751862743179828600f, 1.751677699190690400f, + 1.751492590797370600f, + 1.751307418006674800f, 1.751122180825411800f, 1.750936879260391700f, + 1.750751513318427700f, + 1.750566083006335600f, 1.750380588330932500f, 1.750195029299038900f, + 1.750009405917477100f, + 1.749823718193071800f, 1.749637966132650900f, 1.749452149743043100f, + 1.749266269031080700f, + 1.749080324003598100f, 1.748894314667431800f, 1.748708241029421000f, + 1.748522103096407300f, + 1.748335900875233900f, 1.748149634372747200f, 1.747963303595795500f, + 1.747776908551230000f, + 1.747590449245904000f, 1.747403925686672500f, 1.747217337880393900f, + 1.747030685833928200f, + 1.746843969554138200f, 1.746657189047889200f, 1.746470344322048200f, + 1.746283435383485100f, + 1.746096462239072000f, 1.745909424895683200f, 1.745722323360195900f, + 1.745535157639489100f, + 1.745347927740444200f, 1.745160633669945200f, 1.744973275434878300f, + 1.744785853042132300f, + 1.744598366498598200f, 1.744410815811169300f, 1.744223200986741100f, + 1.744035522032211900f, + 1.743847778954482000f, 1.743659971760454200f, 1.743472100457033700f, + 1.743284165051127700f, + 1.743096165549646400f, 1.742908101959502100f, 1.742719974287608900f, + 1.742531782540884100f, + 1.742343526726246800f, 1.742155206850618800f, 1.741966822920923800f, + 1.741778374944088000f, + 1.741589862927040800f, 1.741401286876712800f, 1.741212646800037300f, + 1.741023942703950200f, + 1.740835174595389600f, 1.740646342481295900f, 1.740457446368612000f, + 1.740268486264283200f, + 1.740079462175256900f, 1.739890374108482600f, 1.739701222070913200f, + 1.739512006069502800f, + 1.739322726111208500f, 1.739133382202989500f, 1.738943974351807600f, + 1.738754502564626700f, + 1.738564966848413100f, 1.738375367210135400f, 1.738185703656765200f, + 1.737995976195275000f, + 1.737806184832640900f, 1.737616329575841300f, 1.737426410431856200f, + 1.737236427407668800f, + 1.737046380510263800f, 1.736856269746629000f, 1.736666095123754000f, + 1.736475856648631400f, + 1.736285554328254900f, 1.736095188169622500f, 1.735904758179732400f, + 1.735714264365586700f, + 1.735523706734189100f, 1.735333085292545900f, 1.735142400047666100f, + 1.734951651006560100f, + 1.734760838176241400f, 1.734569961563725600f, 1.734379021176030600f, + 1.734188017020177100f, + 1.733996949103187500f, 1.733805817432086900f, 1.733614622013902600f, + 1.733423362855664100f, + 1.733232039964403900f, 1.733040653347156300f, 1.732849203010957900f, + 1.732657688962847600f, + 1.732466111209867200f, 1.732274469759060200f, 1.732082764617472800f, + 1.731890995792153600f, + 1.731699163290153100f, 1.731507267118524500f, 1.731315307284323700f, + 1.731123283794607800f, + 1.730931196656437600f, 1.730739045876875200f, 1.730546831462985500f, + 1.730354553421835600f, + 1.730162211760495300f, 1.729969806486036500f, 1.729777337605533000f, + 1.729584805126061400f, + 1.729392209054700900f, 1.729199549398532400f, 1.729006826164639400f, + 1.728814039360108100f, + 1.728621188992026400f, 1.728428275067485100f, 1.728235297593577100f, + 1.728042256577397200f, + 1.727849152026043500f, 1.727655983946615700f, 1.727462752346216000f, + 1.727269457231948900f, + 1.727076098610921500f, 1.726882676490243000f, 1.726689190877025000f, + 1.726495641778381200f, + 1.726302029201427900f, 1.726108353153283900f, 1.725914613641069900f, + 1.725720810671909300f, + 1.725526944252927700f, 1.725333014391252900f, 1.725139021094015200f, + 1.724944964368347000f, + 1.724750844221383500f, 1.724556660660261800f, 1.724362413692121400f, + 1.724168103324104300f, + 1.723973729563354600f, 1.723779292417019200f, 1.723584791892246700f, + 1.723390227996188600f, + 1.723195600735998100f, 1.723000910118831300f, 1.722806156151846400f, + 1.722611338842204000f, + 1.722416458197066900f, 1.722221514223600100f, 1.722026506928971500f, + 1.721831436320350800f, + 1.721636302404910200f, 1.721441105189824000f, 1.721245844682269600f, + 1.721050520889425600f, + 1.720855133818473900f, 1.720659683476597900f, 1.720464169870984200f, + 1.720268593008821100f, + 1.720072952897299100f, 1.719877249543611900f, 1.719681482954954500f, + 1.719485653138524800f, + 1.719289760101522900f, 1.719093803851151400f, 1.718897784394614900f, + 1.718701701739120400f, + 1.718505555891877400f, 1.718309346860097600f, 1.718113074650995200f, + 1.717916739271786500f, + 1.717720340729689700f, 1.717523879031926500f, 1.717327354185719900f, + 1.717130766198295700f, + 1.716934115076881800f, 1.716737400828708400f, 1.716540623461008100f, + 1.716343782981016200f, + 1.716146879395969500f, 1.715949912713108100f, 1.715752882939673300f, + 1.715555790082909900f, + 1.715358634150064000f, 1.715161415148384500f, 1.714964133085122900f, + 1.714766787967532600f, + 1.714569379802868900f, 1.714371908598390800f, 1.714174374361358000f, + 1.713976777099033700f, + 1.713779116818682900f, 1.713581393527573000f, 1.713383607232973600f, + 1.713185757942156800f, + 1.712987845662396800f, 1.712789870400970700f, 1.712591832165157200f, + 1.712393730962237500f, + 1.712195566799495500f, 1.711997339684216700f, 1.711799049623689900f, + 1.711600696625205300f, + 1.711402280696055800f, 1.711203801843536700f, 1.711005260074945200f, + 1.710806655397581600f, + 1.710607987818747700f, 1.710409257345748100f, 1.710210463985889500f, + 1.710011607746480600f, + 1.709812688634833300f, 1.709613706658261100f, 1.709414661824080000f, + 1.709215554139608400f, + 1.709016383612166600f, 1.708817150249077900f, 1.708617854057667300f, + 1.708418495045262300f, + 1.708219073219193300f, 1.708019588586791700f, 1.707820041155392500f, + 1.707620430932332400f, + 1.707420757924950300f, 1.707221022140587900f, 1.707021223586588700f, + 1.706821362270298600f, + 1.706621438199066300f, 1.706421451380242000f, 1.706221401821179200f, + 1.706021289529232800f, + 1.705821114511760300f, 1.705620876776121600f, 1.705420576329679000f, + 1.705220213179796900f, + 1.705019787333842200f, 1.704819298799183700f, 1.704618747583193100f, + 1.704418133693243800f, + 1.704217457136711900f, 1.704016717920976000f, 1.703815916053416300f, + 1.703615051541415900f, + 1.703414124392360000f, 1.703213134613636100f, 1.703012082212634000f, + 1.702810967196746000f, + 1.702609789573366300f, 1.702408549349891500f, 1.702207246533721000f, + 1.702005881132255800f, + 1.701804453152900000f, 1.701602962603059100f, 1.701401409490141300f, + 1.701199793821557300f, + 1.700998115604720000f, 1.700796374847044300f, 1.700594571555948100f, + 1.700392705738850400f, + 1.700190777403173700f, 1.699988786556342300f, 1.699786733205783000f, + 1.699584617358924400f, + 1.699382439023197700f, 1.699180198206036600f, 1.698977894914877100f, + 1.698775529157156700f, + 1.698573100940316400f, 1.698370610271798800f, 1.698168057159048700f, + 1.697965441609513300f, + 1.697762763630642700f, 1.697560023229888200f, 1.697357220414704500f, + 1.697154355192547900f, + 1.696951427570877000f, 1.696748437557152900f, 1.696545385158839200f, + 1.696342270383401200f, + 1.696139093238307400f, 1.695935853731027600f, 1.695732551869034300f, + 1.695529187659802400f, + 1.695325761110809200f, 1.695122272229534000f, 1.694918721023458600f, + 1.694715107500066800f, + 1.694511431666845000f, 1.694307693531282000f, 1.694103893100868100f, + 1.693900030383096900f, + 1.693696105385463800f, 1.693492118115466500f, 1.693288068580604900f, + 1.693083956788381500f, + 1.692879782746300700f, 1.692675546461869900f, 1.692471247942597600f, + 1.692266887195995600f, + 1.692062464229577600f, 1.691857979050859900f, 1.691653431667360600f, + 1.691448822086600400f, + 1.691244150316102000f, 1.691039416363390800f, 1.690834620235994300f, + 1.690629761941442100f, + 1.690424841487266700f, 1.690219858881001800f, 1.690014814130184300f, + 1.689809707242353200f, + 1.689604538225049700f, 1.689399307085817300f, 1.689194013832201500f, + 1.688988658471750600f, + 1.688783241012014700f, 1.688577761460546800f, 1.688372219824901400f, + 1.688166616112636100f, + 1.687960950331309800f, 1.687755222488484600f, 1.687549432591724400f, + 1.687343580648595700f, + 1.687137666666667100f, 1.686931690653509000f, 1.686725652616694900f, + 1.686519552563800400f, + 1.686313390502403000f, 1.686107166440082600f, 1.685900880384421800f, + 1.685694532343004600f, + 1.685488122323418400f, 1.685281650333251900f, 1.685075116380096800f, + 1.684868520471546600f, + 1.684661862615197000f, 1.684455142818646700f, 1.684248361089495800f, + 1.684041517435347400f, + 1.683834611863806100f, 1.683627644382479800f, 1.683420614998977900f, + 1.683213523720911800f, + 1.683006370555896400f, 1.682799155511547600f, 1.682591878595484300f, + 1.682384539815327400f, + 1.682177139178700400f, 1.681969676693228600f, 1.681762152366539600f, + 1.681554566206263900f, + 1.681346918220033800f, 1.681139208415483700f, 1.680931436800250600f, + 1.680723603381973500f, + 1.680515708168294200f, 1.680307751166856300f, 1.680099732385305300f, + 1.679891651831290100f, + 1.679683509512460900f, 1.679475305436470600f, 1.679267039610974300f, + 1.679058712043629300f, + 1.678850322742095200f, 1.678641871714033900f, 1.678433358967109400f, + 1.678224784508988400f, + 1.678016148347339300f, 1.677807450489833300f, 1.677598690944143400f, + 1.677389869717945000f, + 1.677180986818916300f, 1.676972042254736900f, 1.676763036033089600f, + 1.676553968161658600f, + 1.676344838648130600f, 1.676135647500194700f, 1.675926394725542700f, + 1.675717080331867900f, + 1.675507704326866200f, 1.675298266718235900f, 1.675088767513677200f, + 1.674879206720892900f, + 1.674669584347587800f, 1.674459900401469700f, 1.674250154890247300f, + 1.674040347821632800f, + 1.673830479203340000f, 1.673620549043085500f, 1.673410557348587600f, + 1.673200504127567000f, + 1.672990389387746700f, 1.672780213136852300f, 1.672569975382611300f, + 1.672359676132753500f, + 1.672149315395010900f, 1.671938893177118000f, 1.671728409486811500f, + 1.671517864331830000f, + 1.671307257719914800f, 1.671096589658809500f, 1.670885860156259300f, + 1.670675069220012500f, + 1.670464216857819200f, 1.670253303077431800f, 1.670042327886605200f, + 1.669831291293095900f, + 1.669620193304663500f, 1.669409033929069500f, 1.669197813174077200f, + 1.668986531047453000f, + 1.668775187556965000f, 1.668563782710383600f, 1.668352316515481700f, + 1.668140788980034400f, + 1.667929200111818400f, 1.667717549918614100f, 1.667505838408202700f, + 1.667294065588368100f, + 1.667082231466896900f, 1.666870336051577800f, 1.666658379350201000f, + 1.666446361370560000f, + 1.666234282120450100f, 1.666022141607668600f, 1.665809939840015500f, + 1.665597676825292700f, + 1.665385352571304500f, 1.665172967085857700f, 1.664960520376761000f, + 1.664748012451825200f, + 1.664535443318863900f, 1.664322812985692600f, 1.664110121460129000f, + 1.663897368749993400f, + 1.663684554863107800f, 1.663471679807296800f, 1.663258743590387400f, + 1.663045746220208600f, + 1.662832687704591800f, 1.662619568051370500f, 1.662406387268380100f, + 1.662193145363459100f, + 1.661979842344447600f, 1.661766478219188300f, 1.661553052995526000f, + 1.661339566681307600f, + 1.661126019284382200f, 1.660912410812601900f, 1.660698741273819700f, + 1.660485010675892400f, + 1.660271219026677700f, 1.660057366334036300f, 1.659843452605831200f, + 1.659629477849926800f, + 1.659415442074190900f, 1.659201345286492900f, 1.658987187494704200f, + 1.658772968706699000f, + 1.658558688930353400f, 1.658344348173546300f, 1.658129946444157700f, + 1.657915483750071100f, + 1.657700960099171200f, 1.657486375499345900f, 1.657271729958484500f, + 1.657057023484479000f, + 1.656842256085223800f, 1.656627427768615000f, 1.656412538542551200f, + 1.656197588414933600f, + 1.655982577393664700f, 1.655767505486650500f, 1.655552372701798200f, + 1.655337179047017700f, + 1.655121924530220900f, 1.654906609159322500f, 1.654691232942238500f, + 1.654475795886888300f, + 1.654260298001192200f, 1.654044739293073900f, 1.653829119770458900f, + 1.653613439441274500f, + 1.653397698313451300f, 1.653181896394921000f, 1.652966033693617800f, + 1.652750110217479100f, + 1.652534125974443000f, 1.652318080972451400f, 1.652101975219447200f, + 1.651885808723375900f, + 1.651669581492185300f, 1.651453293533826000f, 1.651236944856249600f, + 1.651020535467411200f, + 1.650804065375267400f, 1.650587534587776700f, 1.650370943112901000f, + 1.650154290958603300f, + 1.649937578132849400f, 1.649720804643607400f, 1.649503970498847200f, + 1.649287075706541200f, + 1.649070120274664000f, 1.648853104211192700f, 1.648636027524106100f, + 1.648418890221385400f, + 1.648201692311014300f, 1.647984433800978600f, 1.647767114699266100f, + 1.647549735013867000f, + 1.647332294752774200f, 1.647114793923981600f, 1.646897232535486500f, + 1.646679610595287900f, + 1.646461928111387300f, 1.646244185091788400f, 1.646026381544496400f, + 1.645808517477519700f, + 1.645590592898868600f, 1.645372607816555400f, 1.645154562238594800f, + 1.644936456173004000f, + 1.644718289627801600f, 1.644500062611009300f, 1.644281775130650900f, + 1.644063427194751600f, + 1.643845018811340300f, 1.643626549988446200f, 1.643408020734102600f, + 1.643189431056343700f, + 1.642970780963206800f, 1.642752070462730800f, 1.642533299562957100f, + 1.642314468271929300f, + 1.642095576597693200f, 1.641876624548297000f, 1.641657612131790500f, + 1.641438539356226500f, + 1.641219406229659700f, 1.641000212760146800f, 1.640780958955747200f, + 1.640561644824521700f, + 1.640342270374534500f, 1.640122835613851100f, 1.639903340550539200f, + 1.639683785192669600f, + 1.639464169548314100f, 1.639244493625547900f, 1.639024757432447500f, + 1.638804960977092100f, + 1.638585104267562800f, 1.638365187311943400f, 1.638145210118319400f, + 1.637925172694778800f, + 1.637705075049411800f, 1.637484917190310800f, 1.637264699125570200f, + 1.637044420863286600f, + 1.636824082411559600f, 1.636603683778490100f, 1.636383224972181500f, + 1.636162706000739300f, + 1.635942126872271800f, 1.635721487594888400f, 1.635500788176702100f, + 1.635280028625826900f, + 1.635059208950379700f, 1.634838329158479200f, 1.634617389258246700f, + 1.634396389257805700f, + 1.634175329165281400f, 1.633954208988801700f, 1.633733028736496400f, + 1.633511788416498000f, + 1.633290488036940500f, 1.633069127605960800f, 1.632847707131697600f, + 1.632626226622291700f, + 1.632404686085886300f, 1.632183085530627200f, 1.631961424964661700f, + 1.631739704396139900f, + 1.631517923833213400f, 1.631296083284036900f, 1.631074182756766300f, + 1.630852222259560700f, + 1.630630201800580900f, 1.630408121387990000f, 1.630185981029953000f, + 1.629963780734637400f, + 1.629741520510213000f, 1.629519200364851800f, 1.629296820306727700f, + 1.629074380344017100f, + 1.628851880484898200f, 1.628629320737551700f, 1.628406701110161100f, + 1.628184021610910700f, + 1.627961282247988300f, 1.627738483029583100f, 1.627515623963887000f, + 1.627292705059093700f, + 1.627069726323399500f, 1.626846687765002700f, 1.626623589392103500f, + 1.626400431212904800f, + 1.626177213235611400f, 1.625953935468430500f, 1.625730597919571300f, + 1.625507200597245500f, + 1.625283743509666300f, 1.625060226665050000f, 1.624836650071614500f, + 1.624613013737580000f, + 1.624389317671169500f, 1.624165561880607000f, 1.623941746374119500f, + 1.623717871159936300f, + 1.623493936246288300f, 1.623269941641409400f, 1.623045887353534900f, + 1.622821773390902700f, + 1.622597599761753000f, 1.622373366474327800f, 1.622149073536871800f, + 1.621924720957631300f, + 1.621700308744855200f, 1.621475836906794500f, 1.621251305451702400f, + 1.621026714387834300f, + 1.620802063723447700f, 1.620577353466802700f, 1.620352583626160500f, + 1.620127754209786100f, + 1.619902865225945300f, 1.619677916682906700f, 1.619452908588941300f, + 1.619227840952321800f, + 1.619002713781323200f, 1.618777527084222800f, 1.618552280869300300f, + 1.618326975144837000f, + 1.618101609919117200f, 1.617876185200426600f, 1.617650700997053500f, + 1.617425157317288200f, + 1.617199554169423500f, 1.616973891561754200f, 1.616748169502577200f, + 1.616522388000191500f, + 1.616296547062898500f, 1.616070646699001800f, 1.615844686916807300f, + 1.615618667724622700f, + 1.615392589130757900f, 1.615166451143525300f, 1.614940253771239400f, + 1.614713997022216900f, + 1.614487680904776600f, 1.614261305427239200f, 1.614034870597928400f, + 1.613808376425168900f, + 1.613581822917288900f, 1.613355210082617800f, 1.613128537929487500f, + 1.612901806466232200f, + 1.612675015701188000f, 1.612448165642693400f, 1.612221256299089200f, + 1.611994287678718100f, + 1.611767259789925100f, 1.611540172641057200f, 1.611313026240463800f, + 1.611085820596496600f, + 1.610858555717509200f, 1.610631231611857800f, 1.610403848287899700f, + 1.610176405753995800f, + 1.609948904018508200f, 1.609721343089801600f, 1.609493722976242900f, + 1.609266043686200700f, + 1.609038305228046400f, 1.608810507610153100f, 1.608582650840896200f, + 1.608354734928653800f, + 1.608126759881805400f, 1.607898725708732900f, 1.607670632417820500f, + 1.607442480017454700f, + 1.607214268516024000f, 1.606985997921919000f, 1.606757668243532500f, + 1.606529279489259600f, + 1.606300831667497600f, 1.606072324786645500f, 1.605843758855105300f, + 1.605615133881280700f, + 1.605386449873577300f, 1.605157706840403300f, 1.604928904790168700f, + 1.604700043731286200f, + 1.604471123672170500f, 1.604242144621237800f, 1.604013106586907400f, + 1.603784009577600100f, + 1.603554853601739700f, 1.603325638667751000f, 1.603096364784061900f, + 1.602867031959102100f, + 1.602637640201303400f, 1.602408189519099800f, 1.602178679920927900f, + 1.601949111415226000f, + 1.601719484010434300f, 1.601489797714996000f, 1.601260052537355700f, + 1.601030248485960900f, + 1.600800385569260300f, 1.600570463795705700f, 1.600340483173750400f, + 1.600110443711850300f, + 1.599880345418463100f, 1.599650188302049100f, 1.599419972371070500f, + 1.599189697633991400f, + 1.598959364099278700f, 1.598728971775401000f, 1.598498520670828900f, + 1.598268010794035900f, + 1.598037442153496900f, 1.597806814757689200f, 1.597576128615092200f, + 1.597345383734188000f, + 1.597114580123460100f, 1.596883717791394800f, 1.596652796746479600f, + 1.596421816997205500f, + 1.596190778552064800f, 1.595959681419551800f, 1.595728525608163700f, + 1.595497311126399300f, + 1.595266037982759500f, 1.595034706185747500f, 1.594803315743869000f, + 1.594571866665631700f, + 1.594340358959544800f, 1.594108792634120600f, 1.593877167697873100f, + 1.593645484159318200f, + 1.593413742026974500f, 1.593181941309362400f, 1.592950082015004700f, + 1.592718164152426000f, + 1.592486187730153300f, 1.592254152756715600f, 1.592022059240644400f, + 1.591789907190473100f, + 1.591557696614737100f, 1.591325427521974100f, 1.591093099920724200f, + 1.590860713819529400f, + 1.590628269226933600f, 1.590395766151483400f, 1.590163204601727100f, + 1.589930584586215500f, + 1.589697906113501000f, 1.589465169192139100f, 1.589232373830686400f, + 1.588999520037702300f, + 1.588766607821748200f, 1.588533637191387400f, 1.588300608155185600f, + 1.588067520721711000f, + 1.587834374899533400f, 1.587601170697224600f, 1.587367908123358900f, + 1.587134587186513000f, + 1.586901207895265300f, 1.586667770258196600f, 1.586434274283889500f, + 1.586200719980929200f, + 1.585967107357902700f, 1.585733436423399000f, 1.585499707186010200f, + 1.585265919654329300f, + 1.585032073836952100f, 1.584798169742476400f, 1.584564207379502500f, + 1.584330186756632200f, + 1.584096107882470000f, 1.583861970765622100f, 1.583627775414697000f, + 1.583393521838305700f, + 1.583159210045060900f, 1.582924840043577400f, 1.582690411842472700f, + 1.582455925450365600f, + 1.582221380875877800f, 1.581986778127632700f, 1.581752117214255900f, + 1.581517398144375800f, + 1.581282620926621300f, 1.581047785569625400f, 1.580812892082021900f, + 1.580577940472447200f, + 1.580342930749539800f, 1.580107862921940700f, 1.579872736998292100f, + 1.579637552987239100f, + 1.579402310897428900f, 1.579167010737510600f, 1.578931652516135700f, + 1.578696236241957200f, + 1.578460761923630800f, 1.578225229569814700f, 1.577989639189168100f, + 1.577753990790353500f, + 1.577518284382034800f, 1.577282519972878200f, 1.577046697571552000f, + 1.576810817186727000f, + 1.576574878827075700f, 1.576338882501273000f, 1.576102828217995600f, + 1.575866715985922500f, + 1.575630545813735200f, 1.575394317710116600f, 1.575158031683752300f, + 1.574921687743330300f, + 1.574685285897539800f, 1.574448826155072400f, 1.574212308524622500f, + 1.573975733014886000f, + 1.573739099634561500f, 1.573502408392348600f, 1.573265659296950300f, + 1.573028852357070800f, + 1.572791987581417100f, 1.572555064978698100f, 1.572318084557624800f, + 1.572081046326909900f, + 1.571843950295269000f, 1.571606796471419100f, 1.571369584864080100f, + 1.571132315481973200f, + 1.570894988333822400f, 1.570657603428353300f, 1.570420160774294000f, + 1.570182660380374600f, + 1.569945102255327200f, 1.569707486407886600f, 1.569469812846788500f, + 1.569232081580771900f, + 1.568994292618577400f, 1.568756445968948000f, 1.568518541640628400f, + 1.568280579642366000f, + 1.568042559982909500f, 1.567804482671010500f, 1.567566347715422500f, + 1.567328155124900800f, + 1.567089904908203200f, 1.566851597074089500f, 1.566613231631321500f, + 1.566374808588663300f, + 1.566136327954881000f, 1.565897789738742900f, 1.565659193949019400f, + 1.565420540594482800f, + 1.565181829683907700f, 1.564943061226071100f, 1.564704235229751500f, + 1.564465351703730400f, + 1.564226410656790000f, 1.563987412097716200f, 1.563748356035296000f, + 1.563509242478319000f, + 1.563270071435576500f, 1.563030842915862100f, 1.562791556927971800f, + 1.562552213480703300f, + 1.562312812582856500f, 1.562073354243233700f, 1.561833838470639200f, + 1.561594265273878800f, + 1.561354634661761300f, 1.561114946643096900f, 1.560875201226698900f, + 1.560635398421381400f, + 1.560395538235961800f, 1.560155620679258400f, 1.559915645760092900f, + 1.559675613487288200f, + 1.559435523869669500f, 1.559195376916064700f, 1.558955172635302800f, + 1.558714911036215700f, + 1.558474592127637100f, 1.558234215918402600f, 1.557993782417350400f, + 1.557753291633320500f, + 1.557512743575155000f, 1.557272138251698300f, 1.557031475671796400f, + 1.556790755844298400f, + 1.556549978778054300f, 1.556309144481917300f, 1.556068252964741600f, + 1.555827304235384500f, + 1.555586298302704900f, 1.555345235175563900f, 1.555104114862824600f, + 1.554862937373352500f, + 1.554621702716015000f, 1.554380410899681300f, 1.554139061933223200f, + 1.553897655825514600f, + 1.553656192585431100f, 1.553414672221850700f, 1.553173094743653300f, + 1.552931460159721100f, + 1.552689768478938500f, 1.552448019710191300f, 1.552206213862368500f, + 1.551964350944360100f, + 1.551722430965059000f, 1.551480453933359800f, 1.551238419858159700f, + 1.550996328748356800f, + 1.550754180612852900f, 1.550511975460550500f, 1.550269713300355100f, + 1.550027394141174000f, + 1.549785017991916400f, 1.549542584861493900f, 1.549300094758820000f, + 1.549057547692810600f, + 1.548814943672383300f, 1.548572282706457900f, 1.548329564803956300f, + 1.548086789973802700f, + 1.547843958224923000f, 1.547601069566245900f, 1.547358124006701400f, + 1.547115121555221700f, + 1.546872062220741700f, 1.546628946012197800f, 1.546385772938528600f, + 1.546142543008675300f, + 1.545899256231580300f, 1.545655912616188800f, 1.545412512171447700f, + 1.545169054906306200f, + 1.544925540829715600f, 1.544681969950629300f, 1.544438342278002600f, + 1.544194657820792800f, + 1.543950916587959700f, 1.543707118588464800f, 1.543463263831272000f, + 1.543219352325347200f, + 1.542975384079658300f, 1.542731359103175300f, 1.542487277404870100f, + 1.542243138993717000f, + 1.541998943878692300f, 1.541754692068774600f, 1.541510383572944000f, + 1.541266018400183200f, + 1.541021596559476700f, 1.540777118059811100f, 1.540532582910175500f, + 1.540287991119560600f, + 1.540043342696959100f, 1.539798637651366400f, 1.539553875991779300f, + 1.539309057727197300f, + 1.539064182866621400f, 1.538819251419055100f, 1.538574263393503800f, + 1.538329218798974800f, + 1.538084117644477900f, 1.537838959939025200f, 1.537593745691629500f, + 1.537348474911307300f, + 1.537103147607076200f, 1.536857763787956400f, 1.536612323462969800f, + 1.536366826641140800f, + 1.536121273331495300f, 1.535875663543061700f, 1.535629997284870400f, + 1.535384274565953600f, + 1.535138495395346400f, 1.534892659782085100f, 1.534646767735208000f, + 1.534400819263756400f, + 1.534154814376772700f, 1.533908753083302200f, 1.533662635392391700f, + 1.533416461313090100f, + 1.533170230854448400f, 1.532923944025520200f, 1.532677600835360600f, + 1.532431201293027000f, + 1.532184745407578500f, 1.531938233188077100f, 1.531691664643585900f, + 1.531445039783170500f, + 1.531198358615898800f, 1.530951621150840700f, 1.530704827397067800f, + 1.530457977363654000f, + 1.530211071059675200f, 1.529964108494209700f, 1.529717089676337500f, + 1.529470014615140800f, + 1.529222883319703700f, 1.528975695799112500f, 1.528728452062455600f, + 1.528481152118823700f, + 1.528233795977309400f, 1.527986383647006500f, 1.527738915137012400f, + 1.527491390456425600f, + 1.527243809614346600f, 1.526996172619878900f, 1.526748479482126700f, + 1.526500730210197200f, + 1.526252924813199500f, 1.526005063300244900f, 1.525757145680446200f, + 1.525509171962918800f, + 1.525261142156779900f, 1.525013056271149000f, 1.524764914315147200f, + 1.524516716297898300f, + 1.524268462228527900f, 1.524020152116163200f, 1.523771785969934000f, + 1.523523363798972000f, + 1.523274885612411200f, 1.523026351419387100f, 1.522777761229038100f, + 1.522529115050503600f, + 1.522280412892925900f, 1.522031654765448900f, 1.521782840677218700f, + 1.521533970637383800f, + 1.521285044655094300f, 1.521036062739502300f, 1.520787024899762100f, + 1.520537931145030400f, + 1.520288781484465700f, 1.520039575927228500f, 1.519790314482481100f, + 1.519540997159388300f, + 1.519291623967116600f, 1.519042194914835200f, 1.518792710011714500f, + 1.518543169266927600f, + 1.518293572689648900f, 1.518043920289055900f, 1.517794212074327500f, + 1.517544448054644500f, + 1.517294628239190400f, 1.517044752637150000f, 1.516794821257710500f, + 1.516544834110061600f, + 1.516294791203394200f, 1.516044692546901800f, 1.515794538149779700f, + 1.515544328021225500f, + 1.515294062170438700f, 1.515043740606620800f, 1.514793363338975600f, + 1.514542930376708600f, + 1.514292441729027300f, 1.514041897405141700f, 1.513791297414263800f, + 1.513540641765606800f, + 1.513289930468387300f, 1.513039163531823000f, 1.512788340965133500f, + 1.512537462777541200f, + 1.512286528978270300f, 1.512035539576546600f, 1.511784494581598600f, + 1.511533394002656100f, + 1.511282237848951400f, 1.511031026129719100f, 1.510779758854195400f, + 1.510528436031618900f, + 1.510277057671229400f, 1.510025623782270000f, 1.509774134373984800f, + 1.509522589455620600f, + 1.509270989036425800f, 1.509019333125651200f, 1.508767621732549400f, + 1.508515854866375100f, + 1.508264032536385000f, 1.508012154751837700f, 1.507760221521994700f, + 1.507508232856118200f, + 1.507256188763473200f, 1.507004089253327000f, 1.506751934334948000f, + 1.506499724017607900f, + 1.506247458310579400f, 1.505995137223137500f, 1.505742760764559300f, + 1.505490328944124200f, + 1.505237841771113200f, 1.504985299254809800f, 1.504732701404498900f, + 1.504480048229468000f, + 1.504227339739006500f, 1.503974575942405700f, 1.503721756848958700f, + 1.503468882467961600f, + 1.503215952808711500f, 1.502962967880507600f, 1.502709927692651900f, + 1.502456832254447600f, + 1.502203681575200700f, 1.501950475664218600f, 1.501697214530810700f, + 1.501443898184289200f, + 1.501190526633967600f, 1.500937099889161600f, 1.500683617959188900f, + 1.500430080853369500f, + 1.500176488581024900f, 1.499922841151479600f, 1.499669138574058800f, + 1.499415380858090800f, + 1.499161568012905300f, 1.498907700047834600f, 1.498653776972212600f, + 1.498399798795375000f, + 1.498145765526660300f, 1.497891677175408500f, 1.497637533750961300f, + 1.497383335262663300f, + 1.497129081719860400f, 1.496874773131900800f, 1.496620409508134800f, + 1.496365990857914600f, + 1.496111517190594300f, 1.495856988515530400f, 1.495602404842080800f, + 1.495347766179606400f, + 1.495093072537469100f, 1.494838323925033400f, 1.494583520351665500f, + 1.494328661826734200f, + 1.494073748359609600f, 1.493818779959664300f, 1.493563756636272500f, + 1.493308678398810800f, + 1.493053545256657800f, 1.492798357219194100f, 1.492543114295801900f, + 1.492287816495866200f, + 1.492032463828773200f, 1.491777056303911700f, 1.491521593930672100f, + 1.491266076718446900f, + 1.491010504676631500f, 1.490754877814621800f, 1.490499196141816600f, + 1.490243459667616600f, + 1.489987668401424800f, 1.489731822352645500f, 1.489475921530685900f, + 1.489219965944954300f, + 1.488963955604861500f, 1.488707890519820600f, 1.488451770699245900f, + 1.488195596152554800f, + 1.487939366889165600f, 1.487683082918499300f, 1.487426744249978400f, + 1.487170350893028500f, + 1.486913902857075700f, 1.486657400151549600f, 1.486400842785880100f, + 1.486144230769501000f, + 1.485887564111846500f, 1.485630842822354100f, 1.485374066910462500f, + 1.485117236385612200f, + 1.484860351257246500f, 1.484603411534810300f, 1.484346417227750700f, + 1.484089368345516300f, + 1.483832264897558400f, 1.483575106893329600f, 1.483317894342285100f, + 1.483060627253882000f, + 1.482803305637578900f, 1.482545929502837100f, 1.482288498859119400f, + 1.482031013715890700f, + 1.481773474082618300f, 1.481515879968770900f, 1.481258231383819800f, + 1.481000528337237800f, + 1.480742770838499900f, 1.480484958897083200f, 1.480227092522466500f, + 1.479969171724131200f, + 1.479711196511560100f, 1.479453166894238100f, 1.479195082881652200f, + 1.478936944483291600f, + 1.478678751708647000f, 1.478420504567211900f, 1.478162203068481100f, + 1.477903847221951400f, + 1.477645437037121900f, 1.477386972523493800f, 1.477128453690569800f, + 1.476869880547855300f, + 1.476611253104856700f, 1.476352571371083700f, 1.476093835356046700f, + 1.475835045069259000f, + 1.475576200520235500f, 1.475317301718493300f, 1.475058348673551100f, + 1.474799341394929900f, + 1.474540279892153000f, 1.474281164174744900f, 1.474021994252233000f, + 1.473762770134145800f, + 1.473503491830014300f, 1.473244159349371700f, 1.472984772701752900f, + 1.472725331896694400f, + 1.472465836943735600f, 1.472206287852416900f, 1.471946684632281500f, + 1.471687027292874400f, + 1.471427315843742100f, 1.471167550294433700f, 1.470907730654499800f, + 1.470647856933493300f, + 1.470387929140969200f, 1.470127947286484100f, 1.469867911379596900f, + 1.469607821429868500f, + 1.469347677446861500f, 1.469087479440140300f, 1.468827227419272200f, + 1.468566921393825700f, + 1.468306561373371900f, 1.468046147367482600f, 1.467785679385733300f, + 1.467525157437700200f, + 1.467264581532962100f, 1.467003951681099800f, 1.466743267891695800f, + 1.466482530174334500f, + 1.466221738538602500f, 1.465960892994088800f, 1.465699993550383400f, + 1.465439040217079400f, + 1.465178033003770700f, 1.464916971920054100f, 1.464655856975527900f, + 1.464394688179792900f, + 1.464133465542451200f, 1.463872189073107500f, 1.463610858781367900f, + 1.463349474676840700f, + 1.463088036769136600f, 1.462826545067867700f, 1.462564999582648600f, + 1.462303400323095000f, + 1.462041747298825900f, 1.461780040519460800f, 1.461518279994622200f, + 1.461256465733934400f, + 1.460994597747023600f, 1.460732676043517800f, 1.460470700633046800f, + 1.460208671525243400f, + 1.459946588729741100f, 1.459684452256176300f, 1.459422262114186800f, + 1.459160018313412400f, + 1.458897720863495500f, 1.458635369774079500f, 1.458372965054810700f, + 1.458110506715337000f, + 1.457847994765308200f, 1.457585429214375700f, 1.457322810072193800f, + 1.457060137348418000f, + 1.456797411052706200f, 1.456534631194717800f, 1.456271797784114900f, + 1.456008910830560500f, + 1.455745970343720800f, 1.455482976333263100f, 1.455219928808857200f, + 1.454956827780174100f, + 1.454693673256887600f, 1.454430465248673300f, 1.454167203765208000f, + 1.453903888816171900f, + 1.453640520411245900f, 1.453377098560113100f, 1.453113623272459100f, + 1.452850094557971000f, + 1.452586512426338000f, 1.452322876887251400f, 1.452059187950404100f, + 1.451795445625491300f, + 1.451531649922210200f, 1.451267800850259500f, 1.451003898419340500f, + 1.450739942639155800f, + 1.450475933519410400f, 1.450211871069811300f, 1.449947755300067500f, + 1.449683586219889400f, + 1.449419363838989800f, 1.449155088167083600f, 1.448890759213887100f, + 1.448626376989119400f, + 1.448361941502500900f, 1.448097452763754000f, 1.447832910782603100f, + 1.447568315568775100f, + 1.447303667131997900f, 1.447038965482002200f, 1.446774210628520200f, + 1.446509402581286400f, + 1.446244541350036700f, 1.445979626944509300f, 1.445714659374444500f, + 1.445449638649584500f, + 1.445184564779673500f, 1.444919437774456700f, 1.444654257643682900f, + 1.444389024397101600f, + 1.444123738044464900f, 1.443858398595526400f, 1.443593006060042100f, + 1.443327560447769600f, + 1.443062061768468400f, 1.442796510031900500f, 1.442530905247829200f, + 1.442265247426020200f, + 1.441999536576240800f, 1.441733772708260600f, 1.441467955831850800f, + 1.441202085956784900f, + 1.440936163092837900f, 1.440670187249787600f, 1.440404158437412500f, + 1.440138076665494100f, + 1.439871941943815300f, 1.439605754282161400f, 1.439339513690319100f, + 1.439073220178077400f, + 1.438806873755226900f, 1.438540474431560600f, 1.438274022216873500f, + 1.438007517120961900f, + 1.437740959153624500f, 1.437474348324662100f, 1.437207684643876800f, + 1.436940968121073600f, + 1.436674198766058500f, 1.436407376588640000f, 1.436140501598628400f, + 1.435873573805835900f, + 1.435606593220076600f, 1.435339559851166500f, 1.435072473708924000f, + 1.434805334803169100f, + 1.434538143143723200f, 1.434270898740410700f, 1.434003601603057300f, + 1.433736251741490700f, + 1.433468849165540500f, 1.433201393885038500f, 1.432933885909818000f, + 1.432666325249714700f, + 1.432398711914566200f, 1.432131045914211600f, 1.431863327258492400f, + 1.431595555957251700f, + 1.431327732020334800f, 1.431059855457588600f, 1.430791926278862400f, + 1.430523944494007400f, + 1.430255910112876000f, 1.429987823145323100f, 1.429719683601205800f, + 1.429451491490382900f, + 1.429183246822714800f, 1.428914949608064200f, 1.428646599856295400f, + 1.428378197577275100f, + 1.428109742780871800f, 1.427841235476955400f, 1.427572675675398600f, + 1.427304063386075200f, + 1.427035398618861500f, 1.426766681383635500f, 1.426497911690277000f, + 1.426229089548668200f, + 1.425960214968693000f, 1.425691287960236600f, 1.425422308533187200f, + 1.425153276697434000f, + 1.424884192462868800f, 1.424615055839385300f, 1.424345866836878200f, + 1.424076625465245500f, + 1.423807331734385800f, 1.423537985654200800f, 1.423268587234593400f, + 1.422999136485468600f, + 1.422729633416733200f, 1.422460078038296300f, 1.422190470360068300f, + 1.421920810391962500f, + 1.421651098143893000f, 1.421381333625776600f, 1.421111516847531700f, + 1.420841647819078600f, + 1.420571726550339700f, 1.420301753051239400f, 1.420031727331703800f, + 1.419761649401660500f, + 1.419491519271040000f, 1.419221336949774100f, 1.418951102447796800f, + 1.418680815775043500f, + 1.418410476941452100f, 1.418140085956961900f, 1.417869642831514700f, + 1.417599147575054000f, + 1.417328600197524900f, 1.417058000708874700f, 1.416787349119052600f, + 1.416516645438009600f, + 1.416245889675698900f, 1.415975081842075300f, 1.415704221947095700f, + 1.415433310000718600f, + 1.415162346012905000f, 1.414891329993617200f, 1.414620261952819600f, + 1.414349141900479000f, + 1.414077969846563500f, 1.413806745801043500f, 1.413535469773890700f, + 1.413264141775079300f, + 1.412992761814585400f, 1.412721329902386900f, 1.412449846048463600f, + 1.412178310262796900f, + 1.411906722555370500f, 1.411635082936170100f, 1.411363391415182900f, + 1.411091648002398500f, + 1.410819852707807700f, 1.410548005541404100f, 1.410276106513182400f, + 1.410004155633139500f, + 1.409732152911274500f, 1.409460098357588200f, 1.409187991982083100f, + 1.408915833794763800f, + 1.408643623805636800f, 1.408371362024710500f, 1.408099048461995300f, + 1.407826683127503000f, + 1.407554266031248100f, 1.407281797183246500f, 1.407009276593515800f, + 1.406736704272076400f, + 1.406464080228949600f, 1.406191404474159000f, 1.405918677017730100f, + 1.405645897869690400f, + 1.405373067040069300f, 1.405100184538898000f, 1.404827250376209400f, + 1.404554264562038400f, + 1.404281227106422400f, 1.404008138019399800f, 1.403734997311011600f, + 1.403461804991300100f, + 1.403188561070310100f, 1.402915265558087700f, 1.402641918464681400f, + 1.402368519800141200f, + 1.402095069574519800f, 1.401821567797870300f, 1.401548014480249000f, + 1.401274409631713600f, + 1.401000753262323900f, 1.400727045382141400f, 1.400453286001229800f, + 1.400179475129653700f, + 1.399905612777481200f, 1.399631698954780800f, 1.399357733671623900f, + 1.399083716938083600f, + 1.398809648764234100f, 1.398535529160152400f, 1.398261358135917300f, + 1.397987135701609200f, + 1.397712861867310300f, 1.397438536643105000f, 1.397164160039079200f, + 1.396889732065321300f, + 1.396615252731921100f, 1.396340722048970300f, 1.396066140026562800f, + 1.395791506674794100f, + 1.395516822003761700f, 1.395242086023564800f, 1.394967298744304900f, + 1.394692460176085300f, + 1.394417570329010700f, 1.394142629213188000f, 1.393867636838725900f, + 1.393592593215735600f, + 1.393317498354329300f, 1.393042352264621600f, 1.392767154956728400f, + 1.392491906440768600f, + 1.392216606726861800f, 1.391941255825130100f, 1.391665853745697400f, + 1.391390400498689700f, + 1.391114896094234100f, 1.390839340542460600f, 1.390563733853500200f, + 1.390288076037486500f, + 1.390012367104554600f, 1.389736607064841100f, 1.389460795928485500f, + 1.389184933705628300f, + 1.388909020406412100f, 1.388633056040981600f, 1.388357040619483200f, + 1.388080974152065200f, + 1.387804856648877600f, 1.387528688120072600f, 1.387252468575804100f, + 1.386976198026228100f, + 1.386699876481501900f, 1.386423503951785200f, 1.386147080447239600f, + 1.385870605978028100f, + 1.385594080554316100f, 1.385317504186270900f, 1.385040876884061000f, + 1.384764198657857200f, + 1.384487469517832200f, 1.384210689474160600f, 1.383933858537019100f, + 1.383656976716585600f, + 1.383380044023040400f, 1.383103060466565300f, 1.382826026057344600f, + 1.382548940805563800f, + 1.382271804721410600f, 1.381994617815074400f, 1.381717380096746800f, + 1.381440091576620700f, + 1.381162752264891500f, 1.380885362171756300f, 1.380607921307413400f, + 1.380330429682064000f, + 1.380052887305910400f, 1.379775294189157000f, 1.379497650342010400f, + 1.379219955774678700f, + 1.378942210497371600f, 1.378664414520301500f, 1.378386567853681700f, + 1.378108670507728300f, + 1.377830722492658500f, 1.377552723818691500f, 1.377274674496048700f, + 1.376996574534953300f, + 1.376718423945630000f, 1.376440222738305700f, 1.376161970923209400f, + 1.375883668510570900f, + 1.375605315510623200f, 1.375326911933600200f, 1.375048457789738400f, + 1.374769953089275400f, + 1.374491397842451100f, 1.374212792059507100f, 1.373934135750687100f, + 1.373655428926236400f, + 1.373376671596402400f, 1.373097863771434200f, 1.372819005461582500f, + 1.372540096677100200f, + 1.372261137428242300f, 1.371982127725264800f, 1.371703067578426700f, + 1.371423956997988000f, + 1.371144795994210500f, 1.370865584577358300f, 1.370586322757697500f, + 1.370307010545495500f, + 1.370027647951022100f, 1.369748234984548000f, 1.369468771656347200f, + 1.369189257976694200f, + 1.368909693955866000f, 1.368630079604142000f, 1.368350414931802000f, + 1.368070699949128800f, + 1.367790934666406600f, 1.367511119093921800f, 1.367231253241962200f, + 1.366951337120818000f, + 1.366671370740780500f, 1.366391354112143500f, 1.366111287245202400f, + 1.365831170150254300f, + 1.365551002837598600f, 1.365270785317536100f, 1.364990517600369400f, + 1.364710199696403300f, + 1.364429831615944200f, 1.364149413369300600f, 1.363868944966782900f, + 1.363588426418702600f, + 1.363307857735373900f, 1.363027238927112300f, 1.362746570004235400f, + 1.362465850977062900f, + 1.362185081855915600f, 1.361904262651116900f, 1.361623393372991300f, + 1.361342474031866000f, + 1.361061504638069400f, 1.360780485201932300f, 1.360499415733786400f, + 1.360218296243966200f, + 1.359937126742807300f, 1.359655907240648000f, 1.359374637747827700f, + 1.359093318274687800f, + 1.358811948831571500f, 1.358530529428824400f, 1.358249060076792900f, + 1.357967540785826300f, + 1.357685971566275200f, 1.357404352428492000f, 1.357122683382830900f, + 1.356840964439648200f, + 1.356559195609301700f, 1.356277376902151900f, 1.355995508328559500f, + 1.355713589898888800f, + 1.355431621623504700f, 1.355149603512774400f, 1.354867535577067200f, + 1.354585417826753800f, + 1.354303250272206500f, 1.354021032923800300f, 1.353738765791911100f, + 1.353456448886917200f, + 1.353174082219199100f, 1.352891665799137900f, 1.352609199637117500f, + 1.352326683743523300f, + 1.352044118128742600f, 1.351761502803164900f, 1.351478837777180700f, + 1.351196123061183100f, + 1.350913358665566400f, 1.350630544600727200f, 1.350347680877063800f, + 1.350064767504976400f, + 1.349781804494866600f, 1.349498791857138400f, 1.349215729602197400f, + 1.348932617740450600f, + 1.348649456282307700f, 1.348366245238179500f, 1.348082984618478800f, + 1.347799674433620500f, + 1.347516314694020800f, 1.347232905410098200f, 1.346949446592273100f, + 1.346665938250967100f, + 1.346382380396604000f, 1.346098773039609700f, 1.345815116190411300f, + 1.345531409859438200f, + 1.345247654057121700f, 1.344963848793894200f, 1.344679994080190800f, + 1.344396089926448000f, + 1.344112136343103900f, 1.343828133340598800f, 1.343544080929374800f, + 1.343259979119875600f, + 1.342975827922546600f, 1.342691627347835500f, 1.342407377406191500f, + 1.342123078108065700f, + 1.341838729463910900f, 1.341554331484181600f, 1.341269884179334700f, + 1.340985387559828100f, + 1.340700841636122400f, 1.340416246418678800f, 1.340131601917961900f, + 1.339846908144436600f, + 1.339562165108570700f, 1.339277372820833400f, 1.338992531291695500f, + 1.338707640531629800f, + 1.338422700551110900f, 1.338137711360615200f, 1.337852672970621300f, + 1.337567585391608900f, + 1.337282448634059800f, 1.336997262708457900f, 1.336712027625288600f, + 1.336426743395039000f, + 1.336141410028198500f, 1.335856027535258000f, 1.335570595926709700f, + 1.335285115213048500f, + 1.334999585404770700f, 1.334714006512374400f, 1.334428378546359500f, + 1.334142701517227600f, + 1.333856975435482300f, 1.333571200311629100f, 1.333285376156174700f, + 1.332999502979628700f, + 1.332713580792501500f, 1.332427609605305400f, 1.332141589428554900f, + 1.331855520272766200f, + 1.331569402148457400f, 1.331283235066148100f, 1.330997019036359800f, + 1.330710754069615700f, + 1.330424440176441300f, 1.330138077367363200f, 1.329851665652910500f, + 1.329565205043613800f, + 1.329278695550004700f, 1.328992137182618100f, 1.328705529951989400f, + 1.328418873868656900f, + 1.328132168943159800f, 1.327845415186039000f, 1.327558612607838500f, + 1.327271761219102500f, + 1.326984861030378000f, 1.326697912052213500f, 1.326410914295159400f, + 1.326123867769767500f, + 1.325836772486591800f, 1.325549628456188100f, 1.325262435689113600f, + 1.324975194195928000f, + 1.324687903987191900f, 1.324400565073468300f, 1.324113177465321900f, + 1.323825741173318700f, + 1.323538256208027800f, 1.323250722580018500f, 1.322963140299862500f, + 1.322675509378133900f, + 1.322387829825407700f, 1.322100101652261100f, 1.321812324869273500f, + 1.321524499487024800f, + 1.321236625516098100f, 1.320948702967077400f, 1.320660731850549000f, + 1.320372712177100700f, + 1.320084643957322400f, 1.319796527201805300f, 1.319508361921142500f, + 1.319220148125929100f, + 1.318931885826762000f, 1.318643575034239800f, 1.318355215758962900f, + 1.318066808011533200f, + 1.317778351802554800f, 1.317489847142633300f, 1.317201294042376300f, + 1.316912692512393300f, + 1.316624042563294900f, 1.316335344205694200f, 1.316046597450205800f, + 1.315757802307445900f, + 1.315468958788033000f, 1.315180066902586800f, 1.314891126661728900f, + 1.314602138076083300f, + 1.314313101156274800f, 1.314024015912930600f, 1.313734882356679900f, + 1.313445700498152800f, + 1.313156470347981900f, 1.312867191916801100f, 1.312577865215246900f, + 1.312288490253956900f, + 1.311999067043570200f, 1.311709595594728000f, 1.311420075918073900f, + 1.311130508024252400f, + 1.310840891923910100f, 1.310551227627695400f, 1.310261515146258200f, + 1.309971754490250700f, + 1.309681945670326400f, 1.309392088697140900f, 1.309102183581351200f, + 1.308812230333616500f, + 1.308522228964597500f, 1.308232179484956500f, 1.307942081905358000f, + 1.307651936236467800f, + 1.307361742488954300f, 1.307071500673486800f, 1.306781210800736200f, + 1.306490872881376200f, + 1.306200486926081700f, 1.305910052945529200f, 1.305619570950396800f, + 1.305329040951365100f, + 1.305038462959116100f, 1.304747836984333300f, 1.304457163037702200f, + 1.304166441129910300f, + 1.303875671271646400f, 1.303584853473601200f, 1.303293987746467300f, + 1.303003074100939100f, + 1.302712112547712800f, 1.302421103097485900f, 1.302130045760958100f, + 1.301838940548830600f, + 1.301547787471806900f, 1.301256586540591600f, 1.300965337765891600f, + 1.300674041158414800f, + 1.300382696728871400f, 1.300091304487973800f, 1.299799864446435200f, + 1.299508376614971500f, + 1.299216841004299200f, 1.298925257625137800f, 1.298633626488207500f, + 1.298341947604231300f, + 1.298050220983932900f, 1.297758446638038700f, 1.297466624577275900f, + 1.297174754812374400f, + 1.296882837354065100f, 1.296590872213081200f, 1.296298859400157700f, + 1.296006798926030200f, + 1.295714690801437600f, 1.295422535037119800f, 1.295130331643818500f, + 1.294838080632277000f, + 1.294545782013240900f, 1.294253435797456900f, 1.293961041995673700f, + 1.293668600618642000f, + 1.293376111677113900f, 1.293083575181843500f, 1.292790991143586200f, + 1.292498359573099700f, + 1.292205680481143500f, 1.291912953878477900f, 1.291620179775866400f, + 1.291327358184073200f, + 1.291034489113864100f, 1.290741572576007400f, 1.290448608581273000f, + 1.290155597140431700f, + 1.289862538264257700f, 1.289569431963524900f, 1.289276278249010600f, + 1.288983077131493000f, + 1.288689828621752300f, 1.288396532730570400f, 1.288103189468731400f, + 1.287809798847019800f, + 1.287516360876223500f, 1.287222875567130900f, 1.286929342930532800f, + 1.286635762977221800f, + 1.286342135717991600f, 1.286048461163638000f, 1.285754739324958900f, + 1.285460970212753500f, + 1.285167153837822900f, 1.284873290210969900f, 1.284579379342998700f, + 1.284285421244715900f, + 1.283991415926929400f, 1.283697363400448900f, 1.283403263676086100f, + 1.283109116764654000f, + 1.282814922676967400f, 1.282520681423843000f, 1.282226393016099500f, + 1.281932057464557000f, + 1.281637674780037100f, 1.281343244973363700f, 1.281048768055361900f, + 1.280754244036858900f, + 1.280459672928683500f, 1.280165054741666300f, 1.279870389486639400f, + 1.279575677174437100f, + 1.279280917815894600f, 1.278986111421849900f, 1.278691258003142000f, + 1.278396357570611900f, + 1.278101410135101800f, 1.277806415707456700f, 1.277511374298522200f, + 1.277216285919146500f, + 1.276921150580179200f, 1.276625968292471000f, 1.276330739066875400f, + 1.276035462914247000f, + 1.275740139845442400f, 1.275444769871319600f, 1.275149353002738700f, + 1.274853889250561200f, + 1.274558378625650200f, 1.274262821138871300f, 1.273967216801090900f, + 1.273671565623178100f, + 1.273375867616002300f, 1.273080122790436000f, 1.272784331157352800f, + 1.272488492727628100f, + 1.272192607512139300f, 1.271896675521764900f, 1.271600696767385400f, + 1.271304671259883200f, + 1.271008599010142500f, 1.270712480029048800f, 1.270416314327489800f, + 1.270120101916354600f, + 1.269823842806533800f, 1.269527537008920300f, 1.269231184534408200f, + 1.268934785393893700f, + 1.268638339598274500f, 1.268341847158450200f, 1.268045308085321800f, + 1.267748722389792100f, + 1.267452090082765900f, 1.267155411175149500f, 1.266858685677851000f, + 1.266561913601780100f, + 1.266265094957848000f, 1.265968229756968100f, 1.265671318010055400f, + 1.265374359728026500f, + 1.265077354921799300f, 1.264780303602294200f, 1.264483205780432700f, + 1.264186061467138500f, + 1.263888870673336400f, 1.263591633409954000f, 1.263294349687918800f, + 1.262997019518161700f, + 1.262699642911614600f, 1.262402219879211300f, 1.262104750431887000f, + 1.261807234580578900f, + 1.261509672336225600f, 1.261212063709767900f, 1.260914408712147800f, + 1.260616707354309500f, + 1.260318959647198400f, 1.260021165601761900f, 1.259723325228949000f, + 1.259425438539710300f, + 1.259127505544998600f, 1.258829526255768000f, 1.258531500682973800f, + 1.258233428837574300f, + 1.257935310730528000f, 1.257637146372796400f, 1.257338935775342200f, + 1.257040678949129500f, + 1.256742375905124400f, 1.256444026654294400f, 1.256145631207609400f, + 1.255847189576040100f, + 1.255548701770560000f, 1.255250167802143000f, 1.254951587681765600f, + 1.254652961420405600f, + 1.254354289029042900f, 1.254055570518658500f, 1.253756805900235700f, + 1.253457995184759300f, + 1.253159138383215200f, 1.252860235506592100f, 1.252561286565879300f, + 1.252262291572068900f, + 1.251963250536153500f, 1.251664163469128300f, 1.251365030381989700f, + 1.251065851285736200f, + 1.250766626191367500f, 1.250467355109885500f, 1.250168038052293500f, + 1.249868675029596200f, + 1.249569266052800800f, 1.249269811132915200f, 1.248970310280950200f, + 1.248670763507917100f, + 1.248371170824829300f, 1.248071532242702100f, 1.247771847772552300f, + 1.247472117425398700f, + 1.247172341212261500f, 1.246872519144162300f, 1.246572651232124700f, + 1.246272737487174300f, + 1.245972777920338000f, 1.245672772542644400f, 1.245372721365123600f, + 1.245072624398807900f, + 1.244772481654731000f, 1.244472293143928300f, 1.244172058877436800f, + 1.243871778866295400f, + 1.243571453121544000f, 1.243271081654225400f, 1.242970664475383100f, + 1.242670201596062700f, + 1.242369693027311200f, 1.242069138780177400f, 1.241768538865712000f, + 1.241467893294967200f, + 1.241167202078996800f, 1.240866465228856100f, 1.240565682755603100f, + 1.240264854670295900f, + 1.239963980983995300f, 1.239663061707763700f, 1.239362096852665300f, + 1.239061086429765300f, + 1.238760030450130900f, 1.238458928924831600f, 1.238157781864937400f, + 1.237856589281521000f, + 1.237555351185656500f, 1.237254067588419400f, 1.236952738500886900f, + 1.236651363934138300f, + 1.236349943899254000f, 1.236048478407316500f, 1.235746967469409900f, + 1.235445411096619500f, + 1.235143809300033300f, 1.234842162090739700f, 1.234540469479829900f, + 1.234238731478396000f, + 1.233936948097532400f, 1.233635119348334400f, 1.233333245241899200f, + 1.233031325789326400f, + 1.232729361001716500f, 1.232427350890172000f, 1.232125295465796600f, + 1.231823194739696300f, + 1.231521048722978200f, 1.231218857426751700f, 1.230916620862127400f, + 1.230614339040217800f, + 1.230312011972136500f, 1.230009639668999500f, 1.229707222141924100f, + 1.229404759402029400f, + 1.229102251460436400f, 1.228799698328266700f, 1.228497100016644900f, + 1.228194456536696500f, + 1.227891767899548700f, 1.227589034116330700f, 1.227286255198173100f, + 1.226983431156208200f, + 1.226680562001569900f, 1.226377647745394000f, 1.226074688398817600f, + 1.225771683972980200f, + 1.225468634479021500f, 1.225165539928084300f, 1.224862400331312400f, + 1.224559215699851500f, + 1.224255986044848500f, 1.223952711377453100f, 1.223649391708814700f, + 1.223346027050086400f, + 1.223042617412421600f, 1.222739162806975900f, 1.222435663244906700f, + 1.222132118737372400f, + 1.221828529295533800f, 1.221524894930552800f, 1.221221215653593100f, + 1.220917491475820500f, + 1.220613722408401900f, 1.220309908462505800f, 1.220006049649302800f, + 1.219702145979964600f, + 1.219398197465665400f, 1.219094204117580300f, 1.218790165946886100f, + 1.218486082964761500f, + 1.218181955182386500f, 1.217877782610943700f, 1.217573565261616000f, + 1.217269303145589000f, + 1.216964996274049400f, 1.216660644658185600f, 1.216356248309187600f, + 1.216051807238247800f, + 1.215747321456559300f, 1.215442790975316700f, 1.215138215805717300f, + 1.214833595958959300f, + 1.214528931446242600f, 1.214224222278769100f, 1.213919468467741900f, + 1.213614670024366000f, + 1.213309826959847700f, 1.213004939285395400f, 1.212700007012219100f, + 1.212395030151530300f, + 1.212090008714541600f, 1.211784942712468300f, 1.211479832156526800f, + 1.211174677057934800f, + 1.210869477427912300f, 1.210564233277680500f, 1.210258944618462200f, + 1.209953611461482200f, + 1.209648233817966600f, 1.209342811699143600f, 1.209037345116242400f, + 1.208731834080493800f, + 1.208426278603131200f, 1.208120678695388600f, 1.207815034368502100f, + 1.207509345633709600f, + 1.207203612502250300f, 1.206897834985365000f, 1.206592013094296200f, + 1.206286146840288300f, + 1.205980236234587100f, 1.205674281288440000f, 1.205368282013096200f, + 1.205062238419806200f, + 1.204756150519822300f, 1.204450018324398900f, 1.204143841844791200f, + 1.203837621092256800f, + 1.203531356078054100f, 1.203225046813444000f, 1.202918693309688300f, + 1.202612295578050900f, + 1.202305853629797500f, 1.201999367476194400f, 1.201692837128510700f, + 1.201386262598016500f, + 1.201079643895983700f, 1.200772981033685800f, 1.200466274022397900f, + 1.200159522873396800f, + 1.199852727597960700f, 1.199545888207369700f, 1.199239004712905300f, + 1.198932077125851100f, + 1.198625105457491700f, 1.198318089719113200f, 1.198011029922004400f, + 1.197703926077454200f, + 1.197396778196754700f, 1.197089586291198500f, 1.196782350372080300f, + 1.196475070450696100f, + 1.196167746538343600f, 1.195860378646322700f, 1.195552966785933900f, + 1.195245510968480300f, + 1.194938011205265900f, 1.194630467507596500f, 1.194322879886780000f, + 1.194015248354125100f, + 1.193707572920943000f, 1.193399853598545500f, 1.193092090398246900f, + 1.192784283331362700f, + 1.192476432409210100f, 1.192168537643107900f, 1.191860599044376500f, + 1.191552616624337800f, + 1.191244590394315400f, 1.190936520365635000f, 1.190628406549622900f, + 1.190320248957608100f, + 1.190012047600920200f, 1.189703802490891000f, 1.189395513638853900f, + 1.189087181056143900f, + 1.188778804754097300f, 1.188470384744052100f, 1.188161921037348400f, + 1.187853413645327100f, + 1.187544862579331500f, 1.187236267850706000f, 1.186927629470796900f, + 1.186618947450951600f, + 1.186310221802519900f, 1.186001452536852300f, 1.185692639665301600f, + 1.185383783199222000f, + 1.185074883149969100f, 1.184765939528900500f, 1.184456952347374900f, + 1.184147921616753200f, + 1.183838847348397400f, 1.183529729553671500f, 1.183220568243940300f, + 1.182911363430571200f, + 1.182602115124932900f, 1.182292823338395100f, 1.181983488082330300f, + 1.181674109368111300f, + 1.181364687207113100f, 1.181055221610712400f, 1.180745712590287400f, + 1.180436160157217800f, + 1.180126564322885100f, 1.179816925098671900f, 1.179507242495962900f, + 1.179197516526144600f, + 1.178887747200604300f, 1.178577934530731700f, 1.178268078527917200f, + 1.177958179203553800f, + 1.177648236569035300f, 1.177338250635757700f, 1.177028221415118200f, + 1.176718148918515700f, + 1.176408033157350300f, 1.176097874143024600f, 1.175787671886942000f, + 1.175477426400507700f, + 1.175167137695128900f, 1.174856805782213500f, 1.174546430673171900f, + 1.174236012379415600f, + 1.173925550912357800f, 1.173615046283413200f, 1.173304498503998400f, + 1.172993907585530900f, + 1.172683273539430800f, 1.172372596377118800f, 1.172061876110017700f, + 1.171751112749551900f, + 1.171440306307147200f, 1.171129456794231200f, 1.170818564222232800f, + 1.170507628602582800f, + 1.170196649946713100f, 1.169885628266057900f, 1.169574563572052300f, + 1.169263455876133200f, + 1.168952305189739200f, 1.168641111524310700f, 1.168329874891289400f, + 1.168018595302118000f, + 1.167707272768241800f, 1.167395907301107100f, 1.167084498912162300f, + 1.166773047612856400f, + 1.166461553414641000f, 1.166150016328968600f, 1.165838436367293800f, + 1.165526813541072100f, + 1.165215147861761400f, 1.164903439340820900f, 1.164591687989710500f, + 1.164279893819892800f, + 1.163968056842831700f, 1.163656177069992500f, 1.163344254512841800f, + 1.163032289182848800f, + 1.162720281091483000f, 1.162408230250216100f, 1.162096136670521600f, + 1.161784000363874000f, + 1.161471821341749900f, 1.161159599615627000f, 1.160847335196984800f, + 1.160535028097304600f, + 1.160222678328068700f, 1.159910285900761700f, 1.159597850826869200f, + 1.159285373117878500f, + 1.158972852785278500f, 1.158660289840559800f, 1.158347684295214300f, + 1.158035036160735900f, + 1.157722345448619400f, 1.157409612170361600f, 1.157096836337461000f, + 1.156784017961417500f, + 1.156471157053732300f, 1.156158253625908700f, 1.155845307689450800f, + 1.155532319255865300f, + 1.155219288336659400f, 1.154906214943342700f, 1.154593099087426000f, + 1.154279940780421400f, + 1.153966740033842900f, 1.153653496859206000f, 1.153340211268028000f, + 1.153026883271827300f, + 1.152713512882124400f, 1.152400100110440700f, 1.152086644968299400f, + 1.151773147467225300f, + 1.151459607618745300f, 1.151146025434387000f, 1.150832400925680100f, + 1.150518734104155400f, + 1.150205024981345800f, 1.149891273568785400f, 1.149577479878009800f, + 1.149263643920556800f, + 1.148949765707964600f, 1.148635845251773800f, 1.148321882563526400f, + 1.148007877654766200f, + 1.147693830537038100f, 1.147379741221888500f, 1.147065609720865600f, + 1.146751436045519300f, + 1.146437220207400700f, 1.146122962218062600f, 1.145808662089060000f, + 1.145494319831947800f, + 1.145179935458284100f, 1.144865508979627800f, 1.144551040407539400f, + 1.144236529753581000f, + 1.143921977029316500f, 1.143607382246310600f, 1.143292745416130600f, + 1.142978066550344400f, + 1.142663345660522000f, 1.142348582758234900f, 1.142033777855056000f, + 1.141718930962559500f, + 1.141404042092321500f, 1.141089111255919800f, 1.140774138464933700f, + 1.140459123730943200f, + 1.140144067065530700f, 1.139828968480280300f, 1.139513827986776900f, + 1.139198645596607400f, + 1.138883421321360600f, 1.138568155172625700f, 1.138252847161994400f, + 1.137937497301059600f, + 1.137622105601416000f, 1.137306672074659900f, 1.136991196732388200f, + 1.136675679586200500f, + 1.136360120647697200f, 1.136044519928480800f, 1.135728877440154800f, + 1.135413193194324800f, + 1.135097467202597100f, 1.134781699476580300f, 1.134465890027884300f, + 1.134150038868120500f, + 1.133834146008902100f, 1.133518211461843200f, 1.133202235238559800f, + 1.132886217350669500f, + 1.132570157809791500f, 1.132254056627546300f, 1.131937913815556300f, + 1.131621729385444900f, + 1.131305503348837300f, 1.130989235717360100f, 1.130672926502642100f, + 1.130356575716312500f, + 1.130040183370002900f, 1.129723749475346000f, 1.129407274043976200f, + 1.129090757087529500f, + 1.128774198617643200f, 1.128457598645956600f, 1.128140957184109700f, + 1.127824274243744500f, + 1.127507549836505000f, 1.127190783974035800f, 1.126873976667983800f, + 1.126557127929996800f, + 1.126240237771724700f, 1.125923306204818400f, 1.125606333240930700f, + 1.125289318891715900f, + 1.124972263168829500f, 1.124655166083928800f, 1.124338027648672500f, + 1.124020847874721100f, + 1.123703626773736100f, 1.123386364357381200f, 1.123069060637320600f, + 1.122751715625221400f, + 1.122434329332750800f, 1.122116901771578400f, 1.121799432953375600f, + 1.121481922889814300f, + 1.121164371592568300f, 1.120846779073313400f, 1.120529145343726500f, + 1.120211470415486200f, + 1.119893754300272300f, 1.119575997009766300f, 1.119258198555651300f, + 1.118940358949611900f, + 1.118622478203333800f, 1.118304556328505200f, 1.117986593336814700f, + 1.117668589239953200f, + 1.117350544049612300f, 1.117032457777486200f, 1.116714330435269600f, + 1.116396162034659600f, + 1.116077952587353600f, 1.115759702105052000f, 1.115441410599455500f, + 1.115123078082267000f, + 1.114804704565190500f, 1.114486290059931900f, 1.114167834578198200f, + 1.113849338131698300f, + 1.113530800732142100f, 1.113212222391241500f, 1.112893603120710000f, + 1.112574942932261600f, + 1.112256241837613000f, 1.111937499848481900f, 1.111618716976587700f, + 1.111299893233650600f, + 1.110981028631393700f, 1.110662123181539900f, 1.110343176895814500f, + 1.110024189785944900f, + 1.109705161863658600f, 1.109386093140686000f, 1.109066983628758100f, + 1.108747833339607200f, + 1.108428642284968100f, 1.108109410476576300f, 1.107790137926169200f, + 1.107470824645485600f, + 1.107151470646265300f, 1.106832075940250600f, 1.106512640539184100f, + 1.106193164454811100f, + 1.105873647698877300f, 1.105554090283131100f, 1.105234492219321100f, + 1.104914853519198400f, + 1.104595174194514800f, 1.104275454257024300f, 1.103955693718482200f, + 1.103635892590644900f, + 1.103316050885270600f, 1.102996168614119000f, 1.102676245788951400f, + 1.102356282421530300f, + 1.102036278523620000f, 1.101716234106985700f, 1.101396149183395000f, + 1.101076023764616400f, + 1.100755857862419700f, 1.100435651488577100f, 1.100115404654861100f, + 1.099795117373046200f, + 1.099474789654909100f, 1.099154421512226600f, 1.098834012956778200f, + 1.098513564000344300f, + 1.098193074654706800f, 1.097872544931649100f, 1.097551974842956500f, + 1.097231364400415000f, + 1.096910713615813200f, 1.096590022500939700f, 1.096269291067585700f, + 1.095948519327543800f, + 1.095627707292607700f, 1.095306854974572800f, 1.094985962385235800f, + 1.094665029536395100f, + 1.094344056439850600f, 1.094023043107403200f, 1.093701989550856000f, + 1.093380895782013000f, + 1.093059761812680100f, 1.092738587654664300f, 1.092417373319774200f, + 1.092096118819820200f, + 1.091774824166613600f, 1.091453489371968100f, 1.091132114447697300f, + 1.090810699405617900f, + 1.090489244257547300f, 1.090167749015304300f, 1.089846213690709900f, + 1.089524638295585400f, + 1.089203022841754400f, 1.088881367341041800f, 1.088559671805274100f, + 1.088237936246279100f, + 1.087916160675885800f, 1.087594345105925300f, 1.087272489548229700f, + 1.086950594014632700f, + 1.086628658516969500f, 1.086306683067076900f, 1.085984667676792600f, + 1.085662612357956500f, + 1.085340517122409800f, 1.085018381981994500f, 1.084696206948555300f, + 1.084373992033937000f, + 1.084051737249986900f, 1.083729442608553300f, 1.083407108121486000f, + 1.083084733800636200f, + 1.082762319657857100f, 1.082439865705002500f, 1.082117371953928300f, + 1.081794838416491700f, + 1.081472265104551200f, 1.081149652029967000f, 1.080826999204601100f, + 1.080504306640315500f, + 1.080181574348975500f, 1.079858802342446900f, 1.079535990632596800f, + 1.079213139231294500f, + 1.078890248150409700f, 1.078567317401815100f, 1.078244346997383300f, + 1.077921336948988600f, + 1.077598287268508400f, 1.077275197967819000f, 1.076952069058800400f, + 1.076628900553332700f, + 1.076305692463297900f, 1.075982444800579700f, 1.075659157577062200f, + 1.075335830804633000f, + 1.075012464495178800f, 1.074689058660589700f, 1.074365613312755900f, + 1.074042128463569500f, + 1.073718604124924500f, 1.073395040308715400f, 1.073071437026839500f, + 1.072747794291194300f, + 1.072424112113678600f, 1.072100390506194500f, 1.071776629480643500f, + 1.071452829048929800f, + 1.071128989222958500f, 1.070805110014635900f, 1.070481191435870500f, + 1.070157233498571600f, + 1.069833236214650800f, 1.069509199596019800f, 1.069185123654592600f, + 1.068861008402285200f, + 1.068536853851013600f, 1.068212660012696700f, 1.067888426899253500f, + 1.067564154522606000f, + 1.067239842894676100f, 1.066915492027387600f, 1.066591101932666800f, + 1.066266672622439700f, + 1.065942204108635300f, 1.065617696403183400f, 1.065293149518014500f, + 1.064968563465062100f, + 1.064643938256259400f, 1.064319273903543000f, 1.063994570418849400f, + 1.063669827814116300f, + 1.063345046101285000f, 1.063020225292295300f, 1.062695365399091200f, + 1.062370466433616400f, + 1.062045528407815900f, 1.061720551333637600f, 1.061395535223029500f, + 1.061070480087941800f, + 1.060745385940325500f, 1.060420252792134000f, 1.060095080655320900f, + 1.059769869541841800f, + 1.059444619463654400f, 1.059119330432716700f, 1.058794002460989000f, + 1.058468635560432500f, + 1.058143229743009600f, 1.057817785020685100f, 1.057492301405424500f, + 1.057166778909195000f, + 1.056841217543965200f, 1.056515617321704500f, 1.056189978254385100f, + 1.055864300353978900f, + 1.055538583632461100f, 1.055212828101807200f, 1.054887033773993300f, + 1.054561200660999200f, + 1.054235328774803900f, 1.053909418127389400f, 1.053583468730738200f, + 1.053257480596834700f, + 1.052931453737664600f, 1.052605388165214700f, 1.052279283891473600f, + 1.051953140928431100f, + 1.051626959288079100f, 1.051300738982409800f, 1.050974480023417500f, + 1.050648182423098000f, + 1.050321846193448000f, 1.049995471346466300f, 1.049669057894152800f, + 1.049342605848508200f, + 1.049016115221536000f, 1.048689586025239700f, 1.048363018271625300f, + 1.048036411972699500f, + 1.047709767140470500f, 1.047383083786948700f, 1.047056361924144400f, + 1.046729601564071200f, + 1.046402802718742400f, 1.046075965400174300f, 1.045749089620383200f, + 1.045422175391386800f, + 1.045095222725206200f, 1.044768231633861100f, 1.044441202129375200f, + 1.044114134223771900f, + 1.043787027929076000f, 1.043459883257315400f, 1.043132700220517300f, + 1.042805478830712200f, + 1.042478219099930400f, 1.042150921040204200f, 1.041823584663568200f, + 1.041496209982056600f, + 1.041168797007707000f, 1.040841345752557200f, 1.040513856228645800f, + 1.040186328448014800f, + 1.039858762422705600f, 1.039531158164762400f, 1.039203515686230000f, + 1.038875834999155100f, + 1.038548116115585800f, 1.038220359047570500f, 1.037892563807160800f, + 1.037564730406408200f, + 1.037236858857366600f, 1.036908949172090900f, 1.036581001362636600f, + 1.036253015441062700f, + 1.035924991419427100f, 1.035596929309791300f, 1.035268829124216700f, + 1.034940690874766300f, + 1.034612514573505700f, 1.034284300232500000f, 1.033956047863817500f, + 1.033627757479526700f, + 1.033299429091697700f, 1.032971062712402700f, 1.032642658353714300f, + 1.032314216027707700f, + 1.031985735746457900f, 1.031657217522042900f, 1.031328661366541300f, + 1.031000067292032300f, + 1.030671435310598600f, 1.030342765434322200f, 1.030014057675287900f, + 1.029685312045581100f, + 1.029356528557288300f, 1.029027707222499100f, 1.028698848053302100f, + 1.028369951061789600f, + 1.028041016260053500f, 1.027712043660187600f, 1.027383033274288400f, + 1.027053985114451100f, + 1.026724899192775300f, 1.026395775521359500f, 1.026066614112305600f, + 1.025737414977715200f, + 1.025408178129692000f, 1.025078903580341600f, 1.024749591341769700f, + 1.024420241426085200f, + 1.024090853845396800f, 1.023761428611814600f, 1.023431965737451800f, + 1.023102465234420700f, + 1.022772927114837100f, 1.022443351390816400f, 1.022113738074476300f, + 1.021784087177936000f, + 1.021454398713315600f, 1.021124672692737000f, 1.020794909128323000f, + 1.020465108032198300f, + 1.020135269416488700f, 1.019805393293321100f, 1.019475479674824900f, + 1.019145528573129000f, + 1.018815540000365800f, 1.018485513968667500f, 1.018155450490168000f, + 1.017825349577003300f, + 1.017495211241309800f, 1.017165035495226400f, 1.016834822350892300f, + 1.016504571820448000f, + 1.016174283916036800f, 1.015843958649801600f, 1.015513596033888400f, + 1.015183196080442900f, + 1.014852758801613200f, 1.014522284209548900f, 1.014191772316400000f, + 1.013861223134318900f, + 1.013530636675459100f, 1.013200012951974700f, 1.012869351976022300f, + 1.012538653759758900f, + 1.012207918315344300f, 1.011877145654937400f, 1.011546335790700600f, + 1.011215488734796800f, + 1.010884604499389800f, 1.010553683096645900f, 1.010222724538731600f, + 1.009891728837815700f, + 1.009560696006067900f, 1.009229626055658800f, 1.008898518998761800f, + 1.008567374847549900f, + 1.008236193614199000f, 1.007904975310885300f, 1.007573719949786700f, + 1.007242427543082900f, + 1.006911098102953900f, 1.006579731641582500f, 1.006248328171152100f, + 1.005916887703846500f, + 1.005585410251852700f, 1.005253895827357800f, 1.004922344442551000f, + 1.004590756109621900f, + 1.004259130840762700f, 1.003927468648166100f, 1.003595769544025900f, + 1.003264033540538500f, + 1.002932260649900000f, 1.002600450884309800f, 1.002268604255967200f, + 1.001936720777072400f, + 1.001604800459829000f, 1.001272843316440000f, 1.000940849359111000f, + 1.000608818600048100f, + 1.000276751051459200f, 0.999944646725553720f, 0.999612505634541740f, + 0.999280327790635690f, + 0.998948113206048590f, 0.998615861892994560f, 0.998283573863690270f, + 0.997951249130352380f, + 0.997618887705200020f, 0.997286489600452630f, 0.996954054828332210f, + 0.996621583401061110f, + 0.996289075330862860f, 0.995956530629963810f, 0.995623949310589620f, + 0.995291331384969390f, + 0.994958676865332010f, 0.994625985763907820f, 0.994293258092929790f, + 0.993960493864630480f, + 0.993627693091245660f, 0.993294855785010760f, 0.992961981958163210f, + 0.992629071622942340f, + 0.992296124791587690f, 0.991963141476341460f, 0.991630121689446090f, + 0.991297065443145440f, + 0.990963972749685840f, 0.990630843621313260f, 0.990297678070276800f, + 0.989964476108825210f, + 0.989631237749210020f, 0.989297963003683330f, 0.988964651884498000f, + 0.988631304403909890f, + 0.988297920574174430f, 0.987964500407549910f, 0.987631043916294970f, + 0.987297551112669370f, + 0.986964022008935520f, 0.986630456617355380f, 0.986296854950194260f, + 0.985963217019717120f, + 0.985629542838190490f, 0.985295832417883540f, 0.984962085771065030f, + 0.984628302910006580f, + 0.984294483846980150f, 0.983960628594258810f, 0.983626737164118190f, + 0.983292809568833910f, + 0.982958845820684270f, 0.982624845931947320f, 0.982290809914904140f, + 0.981956737781835790f, + 0.981622629545024770f, 0.981288485216756160f, 0.980954304809314670f, + 0.980620088334987930f, + 0.980285835806063770f, 0.979951547234831130f, 0.979617222633581860f, + 0.979282862014607240f, + 0.978948465390201530f, 0.978614032772659240f, 0.978279564174275860f, + 0.977945059607349900f, + 0.977610519084179290f, 0.977275942617064740f, 0.976941330218307540f, + 0.976606681900209830f, + 0.976271997675076550f, 0.975937277555212310f, 0.975602521552924600f, + 0.975267729680520560f, + 0.974932901950310350f, 0.974598038374604350f, 0.974263138965714040f, + 0.973928203735953460f, + 0.973593232697636530f, 0.973258225863079970f, 0.972923183244600480f, + 0.972588104854516410f, + 0.972252990705148370f, 0.971917840808816710f, 0.971582655177844700f, + 0.971247433824555920f, + 0.970912176761274950f, 0.970576884000329040f, 0.970241555554045230f, + 0.969906191434753320f, + 0.969570791654783330f, 0.969235356226466500f, 0.968899885162136650f, + 0.968564378474127350f, + 0.968228836174775060f, 0.967893258276415700f, 0.967557644791388500f, + 0.967221995732032490f, + 0.966886311110688230f, 0.966550590939698640f, 0.966214835231406500f, + 0.965879043998157160f, + 0.965543217252296420f, 0.965207355006171270f, 0.964871457272131190f, + 0.964535524062525410f, + 0.964199555389706030f, 0.963863551266025300f, 0.963527511703836660f, + 0.963191436715496120f, + 0.962855326313359350f, 0.962519180509785130f, 0.962182999317132030f, + 0.961846782747760140f, + 0.961510530814032040f, 0.961174243528309820f, 0.960837920902958720f, + 0.960501562950343390f, + 0.960165169682831830f, 0.959828741112791590f, 0.959492277252591900f, + 0.959155778114604400f, + 0.958819243711200310f, 0.958482674054753960f, 0.958146069157639560f, + 0.957809429032232760f, + 0.957472753690911670f, 0.957136043146054050f, 0.956799297410040440f, + 0.956462516495251940f, + 0.956125700414070300f, 0.955788849178880300f, 0.955451962802066120f, + 0.955115041296014880f, + 0.954778084673113870f, 0.954441092945751630f, 0.954104066126319150f, + 0.953767004227207060f, + 0.953429907260809120f, 0.953092775239518630f, 0.952755608175731570f, + 0.952418406081844360f, + 0.952081168970254520f, 0.951743896853362140f, 0.951406589743566950f, + 0.951069247653271500f, + 0.950731870594878510f, 0.950394458580791970f, 0.950057011623418380f, + 0.949719529735163940f, + 0.949382012928437600f, 0.949044461215648560f, 0.948706874609207220f, + 0.948369253121526420f, + 0.948031596765018910f, 0.947693905552099870f, 0.947356179495185020f, + 0.947018418606691230f, + 0.946680622899037650f, 0.946342792384643360f, 0.946004927075930090f, + 0.945667026985319680f, + 0.945329092125236190f, 0.944991122508104350f, 0.944653118146349890f, + 0.944315079052401090f, + 0.943977005238685770f, 0.943638896717634900f, 0.943300753501679190f, + 0.942962575603250920f, + 0.942624363034784580f, 0.942286115808714690f, 0.941947833937478270f, + 0.941609517433512730f, + 0.941271166309256450f, 0.940932780577150460f, 0.940594360249635500f, + 0.940255905339155150f, + 0.939917415858152920f, 0.939578891819073720f, 0.939240333234364950f, + 0.938901740116473540f, + 0.938563112477849630f, 0.938224450330942590f, 0.937885753688204820f, + 0.937547022562088990f, + 0.937208256965048840f, 0.936869456909540490f, 0.936530622408019990f, + 0.936191753472946030f, + 0.935852850116777430f, 0.935513912351974450f, 0.935174940190999560f, + 0.934835933646314900f, + 0.934496892730385720f, 0.934157817455677160f, 0.933818707834655590f, + 0.933479563879790030f, + 0.933140385603548840f, 0.932801173018403480f, 0.932461926136825660f, + 0.932122644971287830f, + 0.931783329534265240f, 0.931443979838232900f, 0.931104595895668410f, + 0.930765177719049210f, + 0.930425725320855430f, 0.930086238713567440f, 0.929746717909666790f, + 0.929407162921637610f, + 0.929067573761963250f, 0.928727950443130500f, 0.928388292977625930f, + 0.928048601377937210f, + 0.927708875656554800f, 0.927369115825968480f, 0.927029321898671270f, + 0.926689493887155820f, + 0.926349631803916270f, 0.926009735661449170f, 0.925669805472250860f, + 0.925329841248820340f, + 0.924989843003656610f, 0.924649810749260110f, 0.924309744498133750f, + 0.923969644262779830f, + 0.923629510055703820f, 0.923289341889410480f, 0.922949139776407800f, + 0.922608903729203570f, + 0.922268633760306990f, 0.921928329882229390f, 0.921587992107482210f, + 0.921247620448579440f, + 0.920907214918035070f, 0.920566775528364410f, 0.920226302292085460f, + 0.919885795221715540f, + 0.919545254329774850f, 0.919204679628783720f, 0.918864071131263780f, + 0.918523428849739030f, + 0.918182752796733110f, 0.917842042984772340f, 0.917501299426383480f, + 0.917160522134094160f, + 0.916819711120434700f, 0.916478866397934850f, 0.916137987979127270f, + 0.915797075876544350f, + 0.915456130102721200f, 0.915115150670193110f, 0.914774137591496510f, + 0.914433090879170130f, + 0.914092010545752620f, 0.913750896603785280f, 0.913409749065809520f, + 0.913068567944367970f, + 0.912727353252005710f, 0.912386105001267270f, 0.912044823204700370f, + 0.911703507874852440f, + 0.911362159024272310f, 0.911020776665511290f, 0.910679360811120000f, + 0.910337911473652390f, + 0.909996428665661990f, 0.909654912399703860f, 0.909313362688335290f, + 0.908971779544113350f, + 0.908630162979597760f, 0.908288513007348140f, 0.907946829639926790f, + 0.907605112889895870f, + 0.907263362769819000f, 0.906921579292262250f, 0.906579762469791110f, + 0.906237912314974080f, + 0.905896028840379560f, 0.905554112058577170f, 0.905212161982139160f, + 0.904870178623637170f, + 0.904528161995645670f, 0.904186112110739510f, 0.903844028981494190f, + 0.903501912620488070f, + 0.903159763040298880f, 0.902817580253507450f, 0.902475364272694370f, + 0.902133115110441470f, + 0.901790832779333250f, 0.901448517291953520f, 0.901106168660889110f, + 0.900763786898726380f, + 0.900421372018054500f, 0.900078924031462610f, 0.899736442951541320f, + 0.899393928790883420f, + 0.899051381562081310f, 0.898708801277730340f, 0.898366187950425780f, + 0.898023541592764210f, + 0.897680862217344440f, 0.897338149836764960f, 0.896995404463627350f, + 0.896652626110532870f, + 0.896309814790084090f, 0.895966970514885940f, 0.895624093297543110f, + 0.895281183150662960f, + 0.894938240086852970f, 0.894595264118721810f, 0.894252255258880410f, + 0.893909213519939460f, + 0.893566138914512420f, 0.893223031455212530f, 0.892879891154655380f, + 0.892536718025457090f, + 0.892193512080234670f, 0.891850273331607600f, 0.891507001792195000f, + 0.891163697474618880f, + 0.890820360391500920f, 0.890476990555464480f, 0.890133587979135000f, + 0.889790152675137610f, + 0.889446684656100330f, 0.889103183934650930f, 0.888759650523418650f, + 0.888416084435035060f, + 0.888072485682131150f, 0.887728854277341050f, 0.887385190233298650f, + 0.887041493562639060f, + 0.886697764277999840f, 0.886354002392018110f, 0.886010207917333760f, + 0.885666380866586560f, + 0.885322521252418610f, 0.884978629087472270f, 0.884634704384391180f, + 0.884290747155821230f, + 0.883946757414407980f, 0.883602735172799640f, 0.883258680443644530f, + 0.882914593239592320f, + 0.882570473573294660f, 0.882226321457403320f, 0.881882136904572400f, + 0.881537919927456340f, + 0.881193670538710450f, 0.880849388750992610f, 0.880505074576960370f, + 0.880160728029273920f, + 0.879816349120593590f, 0.879471937863580690f, 0.879127494270899090f, + 0.878783018355212220f, + 0.878438510129186170f, 0.878093969605486800f, 0.877749396796782770f, + 0.877404791715742370f, + 0.877060154375035710f, 0.876715484787334630f, 0.876370782965310900f, + 0.876026048921639160f, + 0.875681282668993700f, 0.875336484220050390f, 0.874991653587487090f, + 0.874646790783981660f, + 0.874301895822214290f, 0.873956968714865500f, 0.873612009474616810f, + 0.873267018114152300f, + 0.872921994646155390f, 0.872576939083312460f, 0.872231851438309840f, + 0.871886731723835020f, + 0.871541579952577750f, 0.871196396137227660f, 0.870851180290476810f, + 0.870505932425017060f, + 0.870160652553543020f, 0.869815340688749220f, 0.869469996843331370f, + 0.869124621029987670f, + 0.868779213261415610f, 0.868433773550315810f, 0.868088301909388680f, + 0.867742798351335720f, + 0.867397262888861100f, 0.867051695534668210f, 0.866706096301463340f, + 0.866360465201952980f, + 0.866014802248844420f, 0.865669107454847490f, 0.865323380832671800f, + 0.864977622395029290f, + 0.864631832154632240f, 0.864286010124194040f, 0.863940156316430170f, + 0.863594270744056040f, + 0.863248353419789670f, 0.862902404356348570f, 0.862556423566453230f, + 0.862210411062823810f, + 0.861864366858181910f, 0.861518290965251340f, 0.861172183396755500f, + 0.860826044165420630f, + 0.860479873283972910f, 0.860133670765139580f, 0.859787436621650360f, + 0.859441170866234390f, + 0.859094873511623840f, 0.858748544570550610f, 0.858402184055747750f, + 0.858055791979950740f, + 0.857709368355894840f, 0.857362913196317630f, 0.857016426513956930f, + 0.856669908321551650f, + 0.856323358631843170f, 0.855976777457572280f, 0.855630164811482460f, + 0.855283520706317080f, + 0.854936845154821930f, 0.854590138169742830f, 0.854243399763827020f, + 0.853896629949823630f, + 0.853549828740481690f, 0.853202996148552880f, 0.852856132186788910f, + 0.852509236867942440f, + 0.852162310204768740f, 0.851815352210022470f, 0.851468362896461110f, + 0.851121342276842110f, + 0.850774290363923820f, 0.850427207170467380f, 0.850080092709233130f, + 0.849732946992984290f, + 0.849385770034483680f, 0.849038561846496730f, 0.848691322441788910f, + 0.848344051833126780f, + 0.847996750033279350f, 0.847649417055015060f, 0.847302052911105160f, + 0.846954657614320980f, + 0.846607231177434640f, 0.846259773613221020f, 0.845912284934454140f, + 0.845564765153910990f, + 0.845217214284368690f, 0.844869632338605130f, 0.844522019329400630f, + 0.844174375269535320f, + 0.843826700171791620f, 0.843478994048952440f, 0.843131256913801420f, + 0.842783488779124570f, + 0.842435689657707650f, 0.842087859562339000f, 0.841739998505806610f, + 0.841392106500900900f, + 0.841044183560412770f, 0.840696229697133760f, 0.840348244923857960f, + 0.840000229253379030f, + 0.839652182698493290f, 0.839304105271996950f, 0.838955996986687550f, + 0.838607857855364740f, + 0.838259687890827830f, 0.837911487105878820f, 0.837563255513319780f, + 0.837214993125953600f, + 0.836866699956585690f, 0.836518376018021260f, 0.836170021323067610f, + 0.835821635884532730f, + 0.835473219715225040f, 0.835124772827955830f, 0.834776295235535540f, + 0.834427786950777460f, + 0.834079247986494690f, 0.833730678355502630f, 0.833382078070616820f, + 0.833033447144653880f, + 0.832684785590432690f, 0.832336093420771970f, 0.831987370648492710f, + 0.831638617286416190f, + 0.831289833347364620f, 0.830941018844162600f, 0.830592173789634240f, + 0.830243298196606360f, + 0.829894392077905720f, 0.829545455446360270f, 0.829196488314800080f, + 0.828847490696055010f, + 0.828498462602957340f, 0.828149404048339590f, 0.827800315045035150f, + 0.827451195605879990f, + 0.827102045743709160f, 0.826752865471360950f, 0.826403654801672770f, + 0.826054413747485010f, + 0.825705142321637720f, 0.825355840536972420f, 0.825006508406332490f, + 0.824657145942561230f, + 0.824307753158504460f, 0.823958330067008030f, 0.823608876680918760f, + 0.823259393013085820f, + 0.822909879076357930f, 0.822560334883586490f, 0.822210760447622980f, + 0.821861155781319800f, + 0.821511520897531660f, 0.821161855809112830f, 0.820812160528920360f, + 0.820462435069811090f, + 0.820112679444643060f, 0.819762893666276530f, 0.819413077747571440f, + 0.819063231701390170f, + 0.818713355540594880f, 0.818363449278050270f, 0.818013512926620940f, + 0.817663546499172720f, + 0.817313550008573640f, 0.816963523467691410f, 0.816613466889396070f, + 0.816263380286557980f, + 0.815913263672048310f, 0.815563117058740630f, 0.815212940459508210f, + 0.814862733887226740f, + 0.814512497354771830f, 0.814162230875020380f, 0.813811934460851430f, + 0.813461608125143560f, + 0.813111251880778150f, 0.812760865740636440f, 0.812410449717600570f, + 0.812060003824555230f, + 0.811709528074384460f, 0.811359022479975040f, 0.811008487054213360f, + 0.810657921809988410f, + 0.810307326760189020f, 0.809956701917705080f, 0.809606047295428950f, + 0.809255362906252440f, + 0.808904648763069890f, 0.808553904878775760f, 0.808203131266265420f, + 0.807852327938436750f, + 0.807501494908186900f, 0.807150632188415760f, 0.806799739792023240f, + 0.806448817731910130f, + 0.806097866020979660f, 0.805746884672134620f, 0.805395873698280360f, + 0.805044833112322000f, + 0.804693762927166100f, 0.804342663155721230f, 0.803991533810895500f, + 0.803640374905599810f, + 0.803289186452744390f, 0.802937968465242240f, 0.802586720956006250f, + 0.802235443937950320f, + 0.801884137423990890f, 0.801532801427043530f, 0.801181435960026780f, + 0.800830041035858750f, + 0.800478616667459010f, 0.800127162867749210f, 0.799775679649650460f, + 0.799424167026086540f, + 0.799072625009981330f, 0.798721053614259490f, 0.798369452851848020f, + 0.798017822735673680f, + 0.797666163278665570f, 0.797314474493752810f, 0.796962756393865600f, + 0.796611008991936490f, + 0.796259232300897350f, 0.795907426333682830f, 0.795555591103226930f, + 0.795203726622466520f, + 0.794851832904338360f, 0.794499909961779990f, 0.794147957807731400f, + 0.793795976455132220f, + 0.793443965916924570f, 0.793091926206050400f, 0.792739857335452710f, + 0.792387759318077150f, + 0.792035632166868230f, 0.791683475894773720f, 0.791331290514740830f, + 0.790979076039718180f, + 0.790626832482656310f, 0.790274559856505520f, 0.789922258174218570f, + 0.789569927448748320f, + 0.789217567693048520f, 0.788865178920075130f, 0.788512761142783790f, + 0.788160314374132590f, + 0.787807838627079260f, 0.787455333914584220f, 0.787102800249607550f, + 0.786750237645110430f, + 0.786397646114056490f, 0.786045025669408700f, 0.785692376324132690f, + 0.785339698091194080f, + 0.784986990983559170f, 0.784634255014197040f, 0.784281490196075850f, + 0.783928696542166680f, + 0.783575874065440270f, 0.783223022778868350f, 0.782870142695425320f, + 0.782517233828084580f, + 0.782164296189822530f, 0.781811329793615120f, 0.781458334652439630f, + 0.781105310779275470f, + 0.780752258187101480f, 0.780399176888899150f, 0.780046066897649550f, + 0.779692928226336290f, + 0.779339760887942880f, 0.778986564895453810f, 0.778633340261856040f, + 0.778280087000135730f, + 0.777926805123281830f, 0.777573494644283050f, 0.777220155576129220f, + 0.776866787931812410f, + 0.776513391724324210f, 0.776159966966658680f, 0.775806513671809860f, + 0.775453031852772920f, + 0.775099521522545020f, 0.774745982694123090f, 0.774392415380506400f, + 0.774038819594694230f, + 0.773685195349686940f, 0.773331542658487140f, 0.772977861534096640f, + 0.772624151989520280f, + 0.772270414037761980f, 0.771916647691828660f, 0.771562852964726710f, + 0.771209029869463940f, + 0.770855178419050050f, 0.770501298626494410f, 0.770147390504808960f, + 0.769793454067005500f, + 0.769439489326096850f, 0.769085496295098040f, 0.768731474987023660f, + 0.768377425414890850f, + 0.768023347591716640f, 0.767669241530518850f, 0.767315107244318060f, + 0.766960944746133740f, + 0.766606754048988260f, 0.766252535165903970f, 0.765898288109903900f, + 0.765544012894013530f, + 0.765189709531257760f, 0.764835378034664170f, 0.764481018417259680f, + 0.764126630692073870f, + 0.763772214872136200f, 0.763417770970477140f, 0.763063299000129260f, + 0.762708798974124800f, + 0.762354270905498450f, 0.761999714807284790f, 0.761645130692519490f, + 0.761290518574240350f, + 0.760935878465484720f, 0.760581210379292380f, 0.760226514328703140f, + 0.759871790326757670f, + 0.759517038386499090f, 0.759162258520969860f, 0.758807450743214760f, + 0.758452615066278920f, + 0.758097751503208020f, 0.757742860067050380f, 0.757387940770853360f, + 0.757032993627667290f, + 0.756678018650541630f, 0.756323015852528700f, 0.755967985246680520f, + 0.755612926846050080f, + 0.755257840663692730f, 0.754902726712663120f, 0.754547585006018600f, + 0.754192415556816380f, + 0.753837218378114460f, 0.753481993482973400f, 0.753126740884452970f, + 0.752771460595615500f, + 0.752416152629523330f, 0.752060816999239660f, 0.751705453717829930f, + 0.751350062798359140f, + 0.750994644253894730f, 0.750639198097504010f, 0.750283724342255320f, + 0.749928223001219310f, + 0.749572694087465850f, 0.749217137614067500f, 0.748861553594096340f, + 0.748505942040627040f, + 0.748150302966733790f, 0.747794636385492150f, 0.747438942309979870f, + 0.747083220753273820f, + 0.746727471728453770f, 0.746371695248599140f, 0.746015891326790470f, + 0.745660059976110400f, + 0.745304201209641030f, 0.744948315040467210f, 0.744592401481673270f, + 0.744236460546344850f, + 0.743880492247569580f, 0.743524496598434670f, 0.743168473612029980f, + 0.742812423301444810f, + 0.742456345679769810f, 0.742100240760097840f, 0.741744108555520860f, + 0.741387949079133860f, + 0.741031762344030790f, 0.740675548363308620f, 0.740319307150063780f, + 0.739963038717393880f, + 0.739606743078398690f, 0.739250420246177380f, 0.738894070233831800f, + 0.738537693054463370f, + 0.738181288721174830f, 0.737824857247070810f, 0.737468398645255490f, + 0.737111912928835710f, + 0.736755400110918000f, 0.736398860204609870f, 0.736042293223021060f, + 0.735685699179260850f, + 0.735329078086440880f, 0.734972429957672760f, 0.734615754806068890f, + 0.734259052644744230f, + 0.733902323486812610f, 0.733545567345390890f, 0.733188784233595240f, + 0.732831974164544150f, + 0.732475137151356370f, 0.732118273207151170f, 0.731761382345050280f, + 0.731404464578174760f, + 0.731047519919648340f, 0.730690548382594280f, 0.730333549980137110f, + 0.729976524725403530f, + 0.729619472631519270f, 0.729262393711613280f, 0.728905287978813600f, + 0.728548155446249730f, + 0.728190996127053180f, 0.727833810034354990f, 0.727476597181288540f, + 0.727119357580987220f, + 0.726762091246585200f, 0.726404798191218950f, 0.726047478428024420f, + 0.725690131970139980f, + 0.725332758830703360f, 0.724975359022855150f, 0.724617932559735390f, + 0.724260479454485130f, + 0.723902999720247850f, 0.723545493370166160f, 0.723187960417385530f, + 0.722830400875050790f, + 0.722472814756308090f, 0.722115202074305680f, 0.721757562842191060f, + 0.721399897073114470f, + 0.721042204780225960f, 0.720684485976676230f, 0.720326740675618530f, + 0.719968968890205230f, + 0.719611170633591480f, 0.719253345918932090f, 0.718895494759382860f, + 0.718537617168101610f, + 0.718179713158245800f, 0.717821782742975370f, 0.717463825935449550f, + 0.717105842748830160f, + 0.716747833196278770f, 0.716389797290958090f, 0.716031735046032900f, + 0.715673646474667140f, + 0.715315531590027700f, 0.714957390405280950f, 0.714599222933594240f, + 0.714241029188137260f, + 0.713882809182079030f, 0.713524562928591010f, 0.713166290440844450f, + 0.712807991732011590f, + 0.712449666815266890f, 0.712091315703784260f, 0.711732938410739810f, + 0.711374534949309800f, + 0.711016105332671340f, 0.710657649574003460f, 0.710299167686484930f, + 0.709940659683296890f, + 0.709582125577619790f, 0.709223565382636760f, 0.708864979111530680f, + 0.708506366777485130f, + 0.708147728393686340f, 0.707789063973319310f, 0.707430373529572170f, + 0.707071657075632460f, + 0.706712914624688770f, 0.706354146189931750f, 0.705995351784551530f, + 0.705636531421740880f, + 0.705277685114692020f, 0.704918812876598410f, 0.704559914720655490f, + 0.704200990660058150f, + 0.703842040708003820f, 0.703483064877689630f, 0.703124063182313690f, + 0.702765035635076310f, + 0.702405982249177160f, 0.702046903037818250f, 0.701687798014201110f, + 0.701328667191529980f, + 0.700969510583008600f, 0.700610328201841660f, 0.700251120061236020f, + 0.699891886174398130f, + 0.699532626554536630f, 0.699173341214860190f, 0.698814030168578240f, + 0.698454693428902320f, + 0.698095331009043640f, 0.697735942922215520f, 0.697376529181631400f, + 0.697017089800505250f, + 0.696657624792053730f, 0.696298134169492380f, 0.695938617946039510f, + 0.695579076134912990f, + 0.695219508749331800f, 0.694859915802517050f, 0.694500297307689140f, + 0.694140653278070950f, + 0.693780983726884790f, 0.693421288667355530f, 0.693061568112707690f, + 0.692701822076166820f, + 0.692342050570960430f, 0.691982253610315510f, 0.691622431207461700f, + 0.691262583375628180f, + 0.690902710128045050f, 0.690542811477944610f, 0.690182887438558710f, + 0.689822938023121220f, + 0.689462963244866330f, 0.689102963117028790f, 0.688742937652845550f, + 0.688382886865552930f, + 0.688022810768389670f, 0.687662709374594510f, 0.687302582697406850f, + 0.686942430750068330f, + 0.686582253545819920f, 0.686222051097905130f, 0.685861823419566700f, + 0.685501570524050140f, + 0.685141292424600310f, 0.684780989134463280f, 0.684420660666887120f, + 0.684060307035119440f, + 0.683699928252410110f, 0.683339524332008840f, 0.682979095287166160f, + 0.682618641131135020f, + 0.682258161877167370f, 0.681897657538517720f, 0.681537128128440470f, + 0.681176573660190910f, + 0.680815994147026320f, 0.680455389602203310f, 0.680094760038981280f, + 0.679734105470619080f, + 0.679373425910376310f, 0.679012721371515250f, 0.678651991867297080f, + 0.678291237410985510f, + 0.677930458015843620f, 0.677569653695137220f, 0.677208824462131490f, + 0.676847970330092700f, + 0.676487091312289350f, 0.676126187421989040f, 0.675765258672461950f, + 0.675404305076978020f, + 0.675043326648808170f, 0.674682323401225250f, 0.674321295347501510f, + 0.673960242500911690f, + 0.673599164874730370f, 0.673238062482232950f, 0.672876935336696900f, + 0.672515783451398950f, + 0.672154606839618470f, 0.671793405514634180f, 0.671432179489727110f, + 0.671070928778178090f, + 0.670709653393269050f, 0.670348353348283690f, 0.669987028656505170f, + 0.669625679331219300f, + 0.669264305385711360f, 0.668902906833267590f, 0.668541483687176590f, + 0.668180035960725840f, + 0.667818563667205600f, 0.667457066819905800f, 0.667095545432117240f, + 0.666733999517132860f, + 0.666372429088244790f, 0.666010834158747840f, 0.665649214741936390f, + 0.665287570851105680f, + 0.664925902499553190f, 0.664564209700575500f, 0.664202492467472090f, + 0.663840750813541210f, + 0.663478984752084110f, 0.663117194296401260f, 0.662755379459794350f, + 0.662393540255567070f, + 0.662031676697022450f, 0.661669788797465960f, 0.661307876570202740f, + 0.660945940028538900f, + 0.660583979185782600f, 0.660221994055241400f, 0.659859984650225110f, + 0.659497950984043510f, + 0.659135893070007080f, 0.658773810921428500f, 0.658411704551619570f, + 0.658049573973894850f, + 0.657687419201568260f, 0.657325240247955020f, 0.656963037126372160f, + 0.656600809850135910f, + 0.656238558432565400f, 0.655876282886978410f, 0.655513983226695960f, + 0.655151659465038060f, + 0.654789311615326050f, 0.654426939690883280f, 0.654064543705032310f, + 0.653702123671098150f, + 0.653339679602405470f, 0.652977211512280050f, 0.652614719414049580f, + 0.652252203321041060f, + 0.651889663246583930f, 0.651527099204007310f, 0.651164511206641320f, + 0.650801899267818060f, + 0.650439263400868990f, 0.650076603619127890f, 0.649713919935928420f, + 0.649351212364604910f, + 0.648988480918494040f, 0.648625725610931460f, 0.648262946455255510f, + 0.647900143464803730f, + 0.647537316652916140f, 0.647174466032932490f, 0.646811591618193350f, + 0.646448693422041360f, + 0.646085771457818310f, 0.645722825738868860f, 0.645359856278536980f, + 0.644996863090167570f, + 0.644633846187107620f, 0.644270805582703550f, 0.643907741290304040f, + 0.643544653323257610f, + 0.643181541694913480f, 0.642818406418622980f, 0.642455247507736860f, + 0.642092064975608220f, + 0.641728858835589830f, 0.641365629101035340f, 0.641002375785300500f, + 0.640639098901740200f, + 0.640275798463712080f, 0.639912474484572560f, 0.639549126977681070f, + 0.639185755956396480f, + 0.638822361434078330f, 0.638458943424088490f, 0.638095501939787920f, + 0.637732036994540290f, + 0.637368548601708660f, 0.637005036774657030f, 0.636641501526751590f, + 0.636277942871357530f, + 0.635914360821842830f, 0.635550755391574910f, 0.635187126593922070f, + 0.634823474442254840f, + 0.634459798949942640f, 0.634096100130357660f, 0.633732377996871770f, + 0.633368632562857470f, + 0.633004863841689520f, 0.632641071846741790f, 0.632277256591390780f, + 0.631913418089012020f, + 0.631549556352983710f, 0.631185671396683470f, 0.630821763233490040f, + 0.630457831876783950f, + 0.630093877339945260f, 0.629729899636356280f, 0.629365898779399080f, + 0.629001874782456500f, + 0.628637827658913300f, 0.628273757422153860f, 0.627909664085564810f, + 0.627545547662532230f, + 0.627181408166443410f, 0.626817245610687520f, 0.626453060008652860f, + 0.626088851373730380f, + 0.625724619719310480f, 0.625360365058784670f, 0.624996087405546350f, + 0.624631786772988030f, + 0.624267463174504880f, 0.623903116623491180f, 0.623538747133343780f, + 0.623174354717459190f, + 0.622809939389234460f, 0.622445501162069090f, 0.622081040049361490f, + 0.621716556064512820f, + 0.621352049220923570f, 0.620987519531995270f, 0.620622967011131400f, + 0.620258391671734690f, + 0.619893793527210410f, 0.619529172590963410f, 0.619164528876399280f, + 0.618799862396925750f, + 0.618435173165949760f, 0.618070461196880800f, 0.617705726503127720f, + 0.617340969098100430f, + 0.616976188995210780f, 0.616611386207870040f, 0.616246560749491690f, + 0.615881712633488340f, + 0.615516841873275490f, 0.615151948482267840f, 0.614787032473881110f, + 0.614422093861533010f, + 0.614057132658640590f, 0.613692148878623000f, 0.613327142534899510f, + 0.612962113640889710f, + 0.612597062210015750f, 0.612231988255698470f, 0.611866891791361560f, + 0.611501772830428060f, + 0.611136631386322020f, 0.610771467472469460f, 0.610406281102295440f, + 0.610041072289227990f, + 0.609675841046694030f, 0.609310587388121830f, 0.608945311326941520f, + 0.608580012876582370f, + 0.608214692050476290f, 0.607849348862054220f, 0.607483983324749510f, + 0.607118595451995420f, + 0.606753185257225550f, 0.606387752753876020f, 0.606022297955381760f, + 0.605656820875180360f, + 0.605291321526709060f, 0.604925799923405670f, 0.604560256078710220f, + 0.604194690006061960f, + 0.603829101718902580f, 0.603463491230673220f, 0.603097858554815790f, + 0.602732203704774650f, + 0.602366526693992930f, 0.602000827535916330f, 0.601635106243990190f, + 0.601269362831660550f, + 0.600903597312375640f, 0.600537809699582810f, 0.600172000006731770f, + 0.599806168247271620f, + 0.599440314434653620f, 0.599074438582328780f, 0.598708540703749010f, + 0.598342620812368000f, + 0.597976678921638860f, 0.597610715045016950f, 0.597244729195957500f, + 0.596878721387916090f, + 0.596512691634350830f, 0.596146639948718640f, 0.595780566344478960f, + 0.595414470835091030f, + 0.595048353434014630f, 0.594682214154711790f, 0.594316053010643270f, + 0.593949870015273000f, + 0.593583665182063740f, 0.593217438524479500f, 0.592851190055986300f, + 0.592484919790049140f, + 0.592118627740135460f, 0.591752313919712170f, 0.591385978342248260f, + 0.591019621021212420f, + 0.590653241970074180f, 0.590286841202305120f, 0.589920418731375800f, + 0.589553974570759530f, + 0.589187508733928890f, 0.588821021234357310f, 0.588454512085520460f, + 0.588087981300892900f, + 0.587721428893951850f, 0.587354854878173850f, 0.586988259267036350f, + 0.586621642074019120f, + 0.586255003312600500f, 0.585888342996261690f, 0.585521661138483250f, + 0.585154957752746730f, + 0.584788232852535560f, 0.584421486451332410f, 0.584054718562622140f, + 0.583687929199888990f, + 0.583321118376619710f, 0.582954286106300290f, 0.582587432402417840f, + 0.582220557278461340f, + 0.581853660747918780f, 0.581486742824280810f, 0.581119803521037650f, + 0.580752842851679940f, + 0.580385860829700780f, 0.580018857468592270f, 0.579651832781848730f, + 0.579284786782964360f, + 0.578917719485433800f, 0.578550630902754050f, 0.578183521048421080f, + 0.577816389935933090f, + 0.577449237578788300f, 0.577082063990485340f, 0.576714869184524860f, + 0.576347653174406840f, + 0.575980415973633590f, 0.575613157595706530f, 0.575245878054129520f, + 0.574878577362406000f, + 0.574511255534040030f, 0.574143912582537940f, 0.573776548521405030f, + 0.573409163364148930f, + 0.573041757124277180f, 0.572674329815297640f, 0.572306881450720390f, + 0.571939412044054740f, + 0.571571921608812320f, 0.571204410158504090f, 0.570836877706642270f, + 0.570469324266740570f, + 0.570101749852312100f, 0.569734154476872480f, 0.569366538153936560f, + 0.568998900897020210f, + 0.568631242719641270f, 0.568263563635316600f, 0.567895863657565500f, + 0.567528142799906490f, + 0.567160401075860410f, 0.566792638498947680f, 0.566424855082689470f, + 0.566057050840608870f, + 0.565689225786228160f, 0.565321379933072190f, 0.564953513294665140f, + 0.564585625884531870f, + 0.564217717716199550f, 0.563849788803194140f, 0.563481839159044150f, + 0.563113868797277870f, + 0.562745877731423820f, 0.562377865975012940f, 0.562009833541575080f, + 0.561641780444642640f, + 0.561273706697747450f, 0.560905612314422150f, 0.560537497308201240f, + 0.560169361692618440f, + 0.559801205481210040f, 0.559433028687510990f, 0.559064831325059240f, + 0.558696613407391630f, + 0.558328374948046320f, 0.557960115960563050f, 0.557591836458480870f, + 0.557223536455341280f, + 0.556855215964685120f, 0.556486875000054000f, 0.556118513574991650f, + 0.555750131703040880f, + 0.555381729397746880f, 0.555013306672654360f, 0.554644863541308600f, + 0.554276400017257090f, + 0.553907916114046440f, 0.553539411845225590f, 0.553170887224342820f, + 0.552802342264947400f, + 0.552433776980590490f, 0.552065191384822350f, 0.551696585491195710f, + 0.551327959313262280f, + 0.550959312864576220f, 0.550590646158691240f, 0.550221959209161620f, + 0.549853252029543830f, + 0.549484524633393480f, 0.549115777034268170f, 0.548747009245725500f, + 0.548378221281323520f, + 0.548009413154622370f, 0.547640584879181100f, 0.547271736468561530f, + 0.546902867936324590f, + 0.546533979296032200f, 0.546165070561248080f, 0.545796141745535150f, + 0.545427192862458780f, + 0.545058223925583670f, 0.544689234948475210f, 0.544320225944701200f, + 0.543951196927828010f, + 0.543582147911424560f, 0.543213078909059120f, 0.542843989934301940f, + 0.542474881000723050f, + 0.542105752121893050f, 0.541736603311384620f, 0.541367434582769480f, + 0.540998245949621760f, + 0.540629037425515050f, 0.540259809024023600f, 0.539890560758723770f, + 0.539521292643190930f, + 0.539152004691002770f, 0.538782696915736770f, 0.538413369330970610f, + 0.538044021950284450f, + 0.537674654787257180f, 0.537305267855470390f, 0.536935861168504670f, + 0.536566434739941920f, + 0.536196988583365510f, 0.535827522712358230f, 0.535458037140505110f, + 0.535088531881390050f, + 0.534719006948599860f, 0.534349462355720230f, 0.533979898116337950f, + 0.533610314244041710f, + 0.533240710752419080f, 0.532871087655060300f, 0.532501444965554960f, + 0.532131782697493170f, + 0.531762100864467290f, 0.531392399480068670f, 0.531022678557890980f, + 0.530652938111527360f, + 0.530283178154571710f, 0.529913398700619820f, 0.529543599763266700f, + 0.529173781356109600f, + 0.528803943492745180f, 0.528434086186771010f, 0.528064209451786560f, + 0.527694313301390160f, + 0.527324397749182720f, 0.526954462808764120f, 0.526584508493736840f, + 0.526214534817702310f, + 0.525844541794263210f, 0.525474529437023890f, 0.525104497759587900f, + 0.524734446775560910f, + 0.524364376498548390f, 0.523994286942156220f, 0.523624178119992400f, + 0.523254050045663940f, + 0.522883902732780290f, 0.522513736194950230f, 0.522143550445783310f, + 0.521773345498891090f, + 0.521403121367884030f, 0.521032878066375100f, 0.520662615607976660f, + 0.520292334006301820f, + 0.519922033274965560f, 0.519551713427582000f, 0.519181374477767470f, + 0.518811016439137520f, + 0.518440639325310040f, 0.518070243149902240f, 0.517699827926532130f, + 0.517329393668819580f, + 0.516958940390383700f, 0.516588468104845820f, 0.516217976825826600f, + 0.515847466566947580f, + 0.515476937341832310f, 0.515106389164103120f, 0.514735822047384990f, + 0.514365236005302040f, + 0.513994631051479240f, 0.513624007199543600f, 0.513253364463121090f, + 0.512882702855839920f, + 0.512512022391327980f, 0.512141323083213470f, 0.511770604945127050f, + 0.511399867990697920f, + 0.511029112233557960f, 0.510658337687338040f, 0.510287544365671140f, + 0.509916732282189920f, + 0.509545901450527690f, 0.509175051884319660f, 0.508804183597200140f, + 0.508433296602805670f, + 0.508062390914772230f, 0.507691466546736580f, 0.507320523512337470f, + 0.506949561825212450f, + 0.506578581499001590f, 0.506207582547344550f, 0.505836564983881190f, + 0.505465528822253710f, + 0.505094474076103310f, 0.504723400759073290f, 0.504352308884806750f, + 0.503981198466947000f, + 0.503610069519139780f, 0.503238922055029400f, 0.502867756088262840f, + 0.502496571632486070f, + 0.502125368701347050f, 0.501754147308493770f, 0.501382907467574190f, + 0.501011649192238950f, + 0.500640372496137020f, 0.500269077392920150f, 0.499897763896239410f, + 0.499526432019746450f, + 0.499155081777094940f, 0.498783713181937540f, 0.498412326247929250f, + 0.498040920988724490f, + 0.497669497417978280f, 0.497298055549347750f, 0.496926595396488870f, + 0.496555116973059980f, + 0.496183620292718900f, 0.495812105369124070f, 0.495440572215935850f, + 0.495069020846813650f, + 0.494697451275419140f, 0.494325863515413130f, 0.493954257580458580f, + 0.493582633484217940f, + 0.493210991240354450f, 0.492839330862533120f, 0.492467652364417970f, + 0.492095955759675460f, + 0.491724241061971320f, 0.491352508284972070f, 0.490980757442346090f, + 0.490608988547760690f, + 0.490237201614885710f, 0.489865396657390210f, 0.489493573688943970f, + 0.489121732723218740f, + 0.488749873773885120f, 0.488377996854616250f, 0.488006101979084450f, + 0.487634189160962910f, + 0.487262258413926560f, 0.486890309751649490f, 0.486518343187807900f, + 0.486146358736077200f, + 0.485774356410135000f, 0.485402336223658360f, 0.485030298190324950f, + 0.484658242323814380f, + 0.484286168637805270f, 0.483914077145978560f, 0.483541967862014480f, + 0.483169840799594130f, + 0.482797695972400300f, 0.482425533394114920f, 0.482053353078422120f, + 0.481681155039005550f, + 0.481308939289549380f, 0.480936705843739820f, 0.480564454715261990f, + 0.480192185917803270f, + 0.479819899465050160f, 0.479447595370691370f, 0.479075273648415010f, + 0.478702934311909910f, + 0.478330577374866780f, 0.477958202850975230f, 0.477585810753927250f, + 0.477213401097414220f, + 0.476840973895128200f, 0.476468529160763100f, 0.476096066908011760f, + 0.475723587150569390f, + 0.475351089902130650f, 0.474978575176390750f, 0.474606042987046840f, + 0.474233493347795020f, + 0.473860926272333670f, 0.473488341774360670f, 0.473115739867574380f, + 0.472743120565675250f, + 0.472370483882362520f, 0.471997829831337810f, 0.471625158426301700f, + 0.471252469680957190f, + 0.470879763609006460f, 0.470507040224152460f, 0.470134299540099940f, + 0.469761541570552780f, + 0.469388766329217000f, 0.469015973829798090f, 0.468643164086002100f, + 0.468270337111537040f, + 0.467897492920109850f, 0.467524631525429830f, 0.467151752941205530f, + 0.466778857181146260f, + 0.466405944258963200f, 0.466033014188366350f, 0.465660066983068220f, + 0.465287102656780530f, + 0.464914121223215740f, 0.464541122696088100f, 0.464168107089110940f, + 0.463795074415999760f, + 0.463422024690469060f, 0.463048957926235630f, 0.462675874137015720f, + 0.462302773336526080f, + 0.461929655538485470f, 0.461556520756611410f, 0.461183369004623920f, + 0.460810200296242310f, + 0.460437014645186440f, 0.460063812065178160f, 0.459690592569938270f, + 0.459317356173189750f, + 0.458944102888655060f, 0.458570832730057170f, 0.458197545711121090f, + 0.457824241845570630f, + 0.457450921147131930f, 0.457077583629530550f, 0.456704229306492570f, + 0.456330858191746010f, + 0.455957470299017840f, 0.455584065642037350f, 0.455210644234532610f, + 0.454837206090234200f, + 0.454463751222871910f, 0.454090279646176210f, 0.453716791373879380f, + 0.453343286419712720f, + 0.452969764797409750f, 0.452596226520703360f, 0.452222671603327130f, + 0.451849100059016350f, + 0.451475511901505420f, 0.451101907144530910f, 0.450728285801828830f, + 0.450354647887135640f, + 0.449980993414189900f, 0.449607322396728900f, 0.449233634848492320f, + 0.448859930783219170f, + 0.448486210214649020f, 0.448112473156523420f, 0.447738719622582710f, + 0.447364949626569590f, + 0.446991163182225700f, 0.446617360303294910f, 0.446243541003520480f, + 0.445869705296646270f, + 0.445495853196417930f, 0.445121984716580210f, 0.444748099870879880f, + 0.444374198673063330f, + 0.444000281136877280f, 0.443626347276070590f, 0.443252397104390790f, + 0.442878430635587910f, + 0.442504447883411090f, 0.442130448861610240f, 0.441756433583937120f, + 0.441382402064142250f, + 0.441008354315978680f, 0.440634290353198510f, 0.440260210189554690f, + 0.439886113838801880f, + 0.439512001314693700f, 0.439137872630986080f, 0.438763727801433690f, + 0.438389566839793740f, + 0.438015389759822630f, 0.437641196575277220f, 0.437266987299916590f, + 0.436892761947498260f, + 0.436518520531782470f, 0.436144263066528480f, 0.435769989565496290f, + 0.435395700042447710f, + 0.435021394511143410f, 0.434647072985346380f, 0.434272735478819010f, + 0.433898382005324050f, + 0.433524012578626440f, 0.433149627212489670f, 0.432775225920679740f, + 0.432400808716961900f, + 0.432026375615101930f, 0.431651926628867530f, 0.431277461772025310f, + 0.430902981058344070f, + 0.430528484501591540f, 0.430153972115537800f, 0.429779443913952170f, + 0.429404899910604490f, + 0.429030340119266550f, 0.428655764553708960f, 0.428281173227704760f, + 0.427906566155026040f, + 0.427531943349445720f, 0.427157304824738350f, 0.426782650594677570f, + 0.426407980673039090f, + 0.426033295073598160f, 0.425658593810130330f, 0.425283876896413280f, + 0.424909144346223290f, + 0.424534396173339160f, 0.424159632391538870f, 0.423784853014600950f, + 0.423410058056305830f, + 0.423035247530432810f, 0.422660421450763490f, 0.422285579831078230f, + 0.421910722685159720f, + 0.421535850026790060f, 0.421160961869751720f, 0.420786058227829220f, + 0.420411139114805770f, + 0.420036204544466940f, 0.419661254530597550f, 0.419286289086983070f, + 0.418911308227410740f, + 0.418536311965666650f, 0.418161300315539220f, 0.417786273290816130f, + 0.417411230905285650f, + 0.417036173172737830f, 0.416661100106961610f, 0.416286011721748230f, + 0.415910908030888200f, + 0.415535789048172620f, 0.415160654787394280f, 0.414785505262345030f, + 0.414410340486818910f, + 0.414035160474608700f, 0.413659965239509710f, 0.413284754795316230f, + 0.412909529155823300f, + 0.412534288334827750f, 0.412159032346125280f, 0.411783761203513790f, + 0.411408474920790520f, + 0.411033173511753220f, 0.410657856990201580f, 0.410282525369933980f, + 0.409907178664751180f, + 0.409531816888453190f, 0.409156440054840590f, 0.408781048177715660f, + 0.408405641270879690f, + 0.408030219348136270f, 0.407654782423288010f, 0.407279330510138260f, + 0.406903863622492260f, + 0.406528381774153900f, 0.406152884978929480f, 0.405777373250624070f, + 0.405401846603045010f, + 0.405026305049998980f, 0.404650748605293040f, 0.404275177282736260f, + 0.403899591096136380f, + 0.403523990059303620f, 0.403148374186047210f, 0.402772743490177110f, + 0.402397097985504990f, + 0.402021437685841480f, 0.401645762604999350f, 0.401270072756790610f, + 0.400894368155027990f, + 0.400518648813525830f, 0.400142914746097480f, 0.399767165966558420f, + 0.399391402488723400f, + 0.399015624326407800f, 0.398639831493428740f, 0.398264024003602220f, + 0.397888201870746420f, + 0.397512365108678430f, 0.397136513731217500f, 0.396760647752182230f, + 0.396384767185391620f, + 0.396008872044666730f, 0.395632962343827170f, 0.395257038096694990f, + 0.394881099317091370f, + 0.394505146018838130f, 0.394129178215758820f, 0.393753195921675850f, + 0.393377199150413860f, + 0.393001187915796750f, 0.392625162231649010f, 0.392249122111796800f, + 0.391873067570065240f, + 0.391496998620281590f, 0.391120915276272410f, 0.390744817551864850f, + 0.390368705460887750f, + 0.389992579017168830f, 0.389616438234538010f, 0.389240283126824070f, + 0.388864113707858060f, + 0.388487929991470140f, 0.388111731991491180f, 0.387735519721753690f, + 0.387359293196089140f, + 0.386983052428331030f, 0.386606797432312350f, 0.386230528221866430f, + 0.385854244810828530f, + 0.385477947213032580f, 0.385101635442314900f, 0.384725309512510880f, + 0.384348969437456610f, + 0.383972615230989860f, 0.383596246906947210f, 0.383219864479167560f, + 0.382843467961488940f, + 0.382467057367749940f, 0.382090632711791060f, 0.381714194007451380f, + 0.381337741268572390f, + 0.380961274508994250f, 0.380584793742559550f, 0.380208298983109930f, + 0.379831790244487540f, + 0.379455267540536490f, 0.379078730885099520f, 0.378702180292021630f, + 0.378325615775147170f, + 0.377949037348320800f, 0.377572445025389230f, 0.377195838820197690f, + 0.376819218746593910f, + 0.376442584818424570f, 0.376065937049537060f, 0.375689275453780500f, + 0.375312600045002780f, + 0.374935910837054080f, 0.374559207843783660f, 0.374182491079041500f, + 0.373805760556679190f, + 0.373429016290547200f, 0.373052258294498230f, 0.372675486582383640f, + 0.372298701168057190f, + 0.371921902065371730f, 0.371545089288180640f, 0.371168262850339210f, + 0.370791422765701320f, + 0.370414569048123140f, 0.370037701711460170f, 0.369660820769568240f, + 0.369283926236305070f, + 0.368907018125527120f, 0.368530096451093140f, 0.368153161226860980f, + 0.367776212466689010f, + 0.367399250184437480f, 0.367022274393965340f, 0.366645285109133750f, + 0.366268282343803150f, + 0.365891266111834370f, 0.365514236427090080f, 0.365137193303431750f, + 0.364760136754723020f, + 0.364383066794826350f, 0.364005983437606320f, 0.363628886696926890f, + 0.363251776586652310f, + 0.362874653120648700f, 0.362497516312780990f, 0.362120366176916230f, + 0.361743202726920790f, + 0.361366025976661450f, 0.360988835940006750f, 0.360611632630824020f, + 0.360234416062982840f, + 0.359857186250351960f, 0.359479943206800550f, 0.359102686946199680f, + 0.358725417482419150f, + 0.358348134829330870f, 0.357970839000806010f, 0.357593530010716310f, + 0.357216207872935120f, + 0.356838872601334680f, 0.356461524209789380f, 0.356084162712172360f, + 0.355706788122359060f, + 0.355329400454223950f, 0.354951999721642100f, 0.354574585938490280f, + 0.354197159118644080f, + 0.353819719275981330f, 0.353442266424378930f, 0.353064800577714280f, + 0.352687321749866610f, + 0.352309829954713830f, 0.351932325206136210f, 0.351554807518012990f, + 0.351177276904224070f, + 0.350799733378650890f, 0.350422176955173910f, 0.350044607647675640f, + 0.349667025470037810f, + 0.349289430436142520f, 0.348911822559873850f, 0.348534201855114360f, + 0.348156568335749040f, + 0.347778922015661520f, 0.347401262908737570f, 0.347023591028862320f, + 0.346645906389921150f, + 0.346268209005801410f, 0.345890498890388980f, 0.345512776057572080f, + 0.345135040521238170f, + 0.344757292295274910f, 0.344379531393571970f, 0.344001757830017680f, + 0.343623971618502560f, + 0.343246172772916250f, 0.342868361307148980f, 0.342490537235092600f, + 0.342112700570637750f, + 0.341734851327677280f, 0.341356989520103240f, 0.340979115161808070f, + 0.340601228266685980f, + 0.340223328848629880f, 0.339845416921535030f, 0.339467492499295200f, + 0.339089555595806560f, + 0.338711606224964210f, 0.338333644400663940f, 0.337955670136803170f, + 0.337577683447278010f, + 0.337199684345986910f, 0.336821672846827290f, 0.336443648963697160f, + 0.336065612710496290f, + 0.335687564101123050f, 0.335309503149478110f, 0.334931429869461230f, + 0.334553344274972690f, + 0.334175246379914470f, 0.333797136198187240f, 0.333419013743693980f, + 0.333040879030336690f, + 0.332662732072017800f, 0.332284572882641680f, 0.331906401476111280f, + 0.331528217866331690f, + 0.331150022067206780f, 0.330771814092642610f, 0.330393593956544440f, + 0.330015361672817750f, + 0.329637117255370090f, 0.329258860718107450f, 0.328880592074938190f, + 0.328502311339769700f, + 0.328124018526509800f, 0.327745713649068180f, 0.327367396721353070f, + 0.326989067757275040f, + 0.326610726770743760f, 0.326232373775669270f, 0.325854008785963320f, + 0.325475631815536570f, + 0.325097242878301660f, 0.324718841988170470f, 0.324340429159055250f, + 0.323962004404870050f, + 0.323583567739527570f, 0.323205119176942720f, 0.322826658731029110f, + 0.322448186415702550f, + 0.322069702244877910f, 0.321691206232470550f, 0.321312698392397570f, + 0.320934178738574720f, + 0.320555647284919980f, 0.320177104045350440f, 0.319798549033783570f, + 0.319419982264138650f, + 0.319041403750333630f, 0.318662813506288670f, 0.318284211545923010f, + 0.317905597883156250f, + 0.317526972531909870f, 0.317148335506103940f, 0.316769686819660780f, + 0.316391026486501690f, + 0.316012354520548600f, 0.315633670935725030f, 0.315254975745953180f, + 0.314876268965157470f, + 0.314497550607261090f, 0.314118820686189180f, 0.313740079215866160f, + 0.313361326210216840f, + 0.312982561683167790f, 0.312603785648644220f, 0.312224998120573420f, + 0.311846199112882030f, + 0.311467388639496860f, 0.311088566714346650f, 0.310709733351358600f, + 0.310330888564462340f, + 0.309952032367586390f, 0.309573164774659850f, 0.309194285799613390f, + 0.308815395456376430f, + 0.308436493758880660f, 0.308057580721056660f, 0.307678656356835560f, + 0.307299720680150270f, + 0.306920773704932260f, 0.306541815445115160f, 0.306162845914631390f, + 0.305783865127415400f, + 0.305404873097400780f, 0.305025869838521590f, 0.304646855364713530f, + 0.304267829689911010f, + 0.303888792828050650f, 0.303509744793068030f, 0.303130685598899270f, + 0.302751615259482190f, + 0.302372533788753170f, 0.301993441200650910f, 0.301614337509113100f, + 0.301235222728077840f, + 0.300856096871485010f, 0.300476959953273060f, 0.300097811987382670f, + 0.299718652987753580f, + 0.299339482968325970f, 0.298960301943041680f, 0.298581109925841300f, + 0.298201906930667390f, + 0.297822692971461410f, 0.297443468062166820f, 0.297064232216726120f, + 0.296684985449082390f, + 0.296305727773180260f, 0.295926459202963120f, 0.295547179752376430f, + 0.295167889435364820f, + 0.294788588265873170f, 0.294409276257848300f, 0.294029953425235520f, + 0.293650619781982260f, + 0.293271275342035120f, 0.292891920119341120f, 0.292512554127848930f, + 0.292133177381505850f, + 0.291753789894261320f, 0.291374391680063520f, 0.290994982752862730f, + 0.290615563126608250f, + 0.290236132815249790f, 0.289856691832738880f, 0.289477240193025510f, + 0.289097777910061970f, + 0.288718304997799550f, 0.288338821470189910f, 0.287959327341186510f, + 0.287579822624741350f, + 0.287200307334808670f, 0.286820781485341620f, 0.286441245090293950f, + 0.286061698163620930f, + 0.285682140719276560f, 0.285302572771216960f, 0.284922994333397350f, + 0.284543405419773240f, + 0.284163806044301910f, 0.283784196220939370f, 0.283404575963643550f, + 0.283024945286371230f, + 0.282645304203081090f, 0.282265652727731130f, 0.281885990874279570f, + 0.281506318656686290f, + 0.281126636088910030f, 0.280746943184911340f, 0.280367239958650150f, + 0.279987526424086530f, + 0.279607802595182420f, 0.279228068485898210f, 0.278848324110196550f, + 0.278468569482039130f, + 0.278088804615388040f, 0.277709029524206950f, 0.277329244222458250f, + 0.276949448724106480f, + 0.276569643043115150f, 0.276189827193448200f, 0.275810001189071290f, + 0.275430165043948570f, + 0.275050318772046500f, 0.274670462387330010f, 0.274290595903766200f, + 0.273910719335321300f, + 0.273530832695961790f, 0.273150935999655950f, 0.272771029260370560f, + 0.272391112492074590f, + 0.272011185708736060f, 0.271631248924323390f, 0.271251302152806570f, + 0.270871345408154380f, + 0.270491378704337540f, 0.270111402055325910f, 0.269731415475089780f, + 0.269351418977600950f, + 0.268971412576829990f, 0.268591396286749500f, 0.268211370121331170f, + 0.267831334094547010f, + 0.267451288220370730f, 0.267071232512774700f, 0.266691166985733360f, + 0.266311091653219700f, + 0.265931006529208920f, 0.265550911627675250f, 0.265170806962593210f, + 0.264790692547939020f, + 0.264410568397687560f, 0.264030434525815760f, 0.263650290946299660f, + 0.263270137673115630f, + 0.262889974720241610f, 0.262509802101654310f, 0.262129619831332370f, + 0.261749427923253670f, + 0.261369226391396310f, 0.260989015249740050f, 0.260608794512263380f, + 0.260228564192946710f, + 0.259848324305769600f, 0.259468074864711960f, 0.259087815883755400f, + 0.258707547376880010f, + 0.258327269358068100f, 0.257946981841300490f, 0.257566684840560170f, + 0.257186378369829110f, + 0.256806062443089680f, 0.256425737074325920f, 0.256045402277520320f, + 0.255665058066657680f, + 0.255284704455721660f, 0.254904341458696390f, 0.254523969089567590f, + 0.254143587362319620f, + 0.253763196290938850f, 0.253382795889410710f, 0.253002386171721110f, + 0.252621967151857420f, + 0.252241538843805680f, 0.251861101261554090f, 0.251480654419089730f, + 0.251100198330400150f, + 0.250719733009474530f, 0.250339258470300590f, 0.249958774726868170f, + 0.249578281793165680f, + 0.249197779683183660f, 0.248817268410911650f, 0.248436747990339490f, + 0.248056218435458720f, + 0.247675679760259450f, 0.247295131978733870f, 0.246914575104873220f, + 0.246534009152669040f, + 0.246153434136114490f, 0.245772850069201410f, 0.245392256965923620f, + 0.245011654840274010f, + 0.244631043706245800f, 0.244250423577833860f, 0.243869794469031620f, + 0.243489156393834590f, + 0.243108509366237320f, 0.242727853400234670f, 0.242347188509823150f, + 0.241966514708997830f, + 0.241585832011755900f, 0.241205140432093070f, 0.240824439984007180f, + 0.240443730681495050f, + 0.240063012538553830f, 0.239682285569182310f, 0.239301549787377890f, + 0.238920805207139960f, + 0.238540051842467020f, 0.238159289707357810f, 0.237778518815812740f, + 0.237397739181830820f, + 0.237016950819413100f, 0.236636153742559610f, 0.236255347965270780f, + 0.235874533501548580f, + 0.235493710365393630f, 0.235112878570808560f, 0.234732038131795020f, + 0.234351189062355030f, + 0.233970331376492150f, 0.233589465088208580f, 0.233208590211508550f, + 0.232827706760394850f, + 0.232446814748872410f, 0.232065914190945020f, 0.231685005100616930f, + 0.231304087491893930f, + 0.230923161378780380f, 0.230542226775282770f, 0.230161283695406500f, + 0.229780332153157300f, + 0.229399372162542610f, 0.229018403737568290f, 0.228637426892242400f, + 0.228256441640571880f, + 0.227875447996564060f, 0.227494445974227850f, 0.227113435587570770f, + 0.226732416850602300f, + 0.226351389777330990f, 0.225970354381765690f, 0.225589310677916880f, + 0.225208258679793520f, + 0.224827198401406690f, 0.224446129856766040f, 0.224065053059883250f, + 0.223683968024768950f, + 0.223302874765434120f, 0.222921773295891380f, 0.222540663630151820f, + 0.222159545782228660f, + 0.221778419766134050f, 0.221397285595880480f, 0.221016143285482050f, + 0.220634992848951380f, + 0.220253834300303180f, 0.219872667653551100f, 0.219491492922709110f, + 0.219110310121792800f, + 0.218729119264816280f, 0.218347920365795780f, 0.217966713438746380f, + 0.217585498497683580f, + 0.217204275556624420f, 0.216823044629584520f, 0.216441805730581500f, + 0.216060558873631570f, + 0.215679304072752960f, 0.215298041341962870f, 0.214916770695278810f, + 0.214535492146719880f, + 0.214154205710303750f, 0.213772911400050090f, 0.213391609229977570f, + 0.213010299214105140f, + 0.212628981366453330f, 0.212247655701041290f, 0.211866322231890090f, + 0.211484980973019880f, + 0.211103631938451000f, 0.210722275142205480f, 0.210340910598303870f, + 0.209959538320768660f, + 0.209578158323621420f, 0.209196770620883960f, 0.208815375226579670f, + 0.208433972154730530f, + 0.208052561419360520f, 0.207671143034492080f, 0.207289717014149830f, + 0.206908283372357230f, + 0.206526842123138070f, 0.206145393280517730f, 0.205763936858520150f, + 0.205382472871171230f, + 0.205001001332495910f, 0.204619522256519300f, 0.204238035657268250f, + 0.203856541548768030f, + 0.203475039945045950f, 0.203093530860128300f, 0.202712014308041620f, + 0.202330490302814110f, + 0.201948958858472420f, 0.201567419989045200f, 0.201185873708560170f, + 0.200804320031045230f, + 0.200422758970529910f, 0.200041190541042220f, 0.199659614756612230f, + 0.199278031631268500f, + 0.198896441179041650f, 0.198514843413961220f, 0.198133238350057030f, + 0.197751626001360480f, + 0.197370006381901520f, 0.196988379505712050f, 0.196606745386822960f, + 0.196225104039265410f, + 0.195843455477072190f, 0.195461799714274460f, 0.195080136764905570f, + 0.194698466642997730f, + 0.194316789362583340f, 0.193935104937696560f, 0.193553413382369890f, + 0.193171714710637930f, + 0.192790008936534220f, 0.192408296074092570f, 0.192026576137348330f, + 0.191644849140335360f, + 0.191263115097089540f, 0.190881374021645320f, 0.190499625928039040f, + 0.190117870830306100f, + 0.189736108742482030f, 0.189354339678604100f, 0.188972563652707950f, + 0.188590780678831250f, + 0.188208990771010640f, 0.187827193943283040f, 0.187445390209686870f, + 0.187063579584259070f, + 0.186681762081038650f, 0.186299937714063470f, 0.185918106497371700f, + 0.185536268445003070f, + 0.185154423570995760f, 0.184772571889390000f, 0.184390713414225000f, + 0.184008848159540110f, + 0.183626976139376310f, 0.183245097367773090f, 0.182863211858771880f, + 0.182481319626412670f, + 0.182099420684737420f, 0.181717515047787020f, 0.181335602729602590f, + 0.180953683744226880f, + 0.180571758105701030f, 0.180189825828068250f, 0.179807886925370670f, + 0.179425941411650660f, + 0.179043989300952110f, 0.178662030607317450f, 0.178280065344791100f, + 0.177898093527416370f, + 0.177516115169236820f, 0.177134130284297610f, 0.176752138886642350f, + 0.176370140990316640f, + 0.175988136609365020f, 0.175606125757832240f, 0.175224108449764660f, + 0.174842084699207030f, + 0.174460054520206240f, 0.174078017926807490f, 0.173695974933058080f, + 0.173313925553004180f, + 0.172931869800692250f, 0.172549807690170230f, 0.172167739235484620f, + 0.171785664450683800f, + 0.171403583349815180f, 0.171021495946926340f, 0.170639402256066410f, + 0.170257302291283000f, + 0.169875196066625710f, 0.169493083596143100f, 0.169110964893883830f, + 0.168728839973898290f, + 0.168346708850235140f, 0.167964571536945220f, 0.167582428048078130f, + 0.167200278397683750f, + 0.166818122599813570f, 0.166435960668517400f, 0.166053792617847200f, + 0.165671618461853270f, + 0.165289438214587970f, 0.164907251890102520f, 0.164525059502448390f, + 0.164142861065678550f, + 0.163760656593844480f, 0.163378446100999640f, 0.162996229601196390f, + 0.162614007108487250f, + 0.162231778636926370f, 0.161849544200566300f, 0.161467303813461580f, + 0.161085057489665670f, + 0.160702805243232240f, 0.160320547088216470f, 0.159938283038672050f, + 0.159556013108654580f, + 0.159173737312218650f, 0.158791455663418930f, 0.158409168176311760f, + 0.158026874864951870f, + 0.157644575743395960f, 0.157262270825699210f, 0.156879960125918730f, + 0.156497643658110590f, + 0.156115321436331000f, 0.155732993474637760f, 0.155350659787087090f, + 0.154968320387737170f, + 0.154585975290645110f, 0.154203624509868190f, 0.153821268059465250f, + 0.153438905953493550f, + 0.153056538206012340f, 0.152674164831079730f, 0.152291785842754070f, + 0.151909401255095250f, + 0.151527011082161540f, 0.151144615338013210f, 0.150762214036709470f, + 0.150379807192309620f, + 0.149997394818874590f, 0.149614976930463660f, 0.149232553541138180f, + 0.148850124664957870f, + 0.148467690315984390f, 0.148085250508278370f, 0.147702805255900570f, + 0.147320354572913260f, + 0.146937898473377210f, 0.146555436971355090f, 0.146172970080908520f, + 0.145790497816099230f, + 0.145408020190990560f, 0.145025537219644170f, 0.144643048916123810f, + 0.144260555294492000f, + 0.143878056368811510f, 0.143495552153146630f, 0.143113042661560050f, + 0.142730527908116440f, + 0.142348007906879320f, 0.141965482671912420f, 0.141582952217280980f, + 0.141200416557048680f, + 0.140817875705281120f, 0.140435329676042390f, 0.140052778483398480f, + 0.139670222141414250f, + 0.139287660664154770f, 0.138905094065686600f, 0.138522522360074780f, + 0.138139945561386200f, + 0.137757363683686740f, 0.137374776741042340f, 0.136992184747520560f, + 0.136609587717187310f, + 0.136226985664110460f, 0.135844378602356760f, 0.135461766545993150f, + 0.135079149509088060f, + 0.134696527505708320f, 0.134313900549922760f, 0.133931268655799020f, + 0.133548631837404950f, + 0.133165990108809860f, 0.132783343484081580f, 0.132400691977289760f, + 0.132018035602502530f, + 0.131635374373789940f, 0.131252708305220960f, 0.130870037410864640f, + 0.130487361704791580f, + 0.130104681201070800f, 0.129721995913773260f, 0.129339305856968730f, + 0.128956611044727220f, + 0.128573911491120210f, 0.128191207210217570f, 0.127808498216091110f, + 0.127425784522811530f, + 0.127043066144449680f, 0.126660343095077900f, 0.126277615388766920f, + 0.125894883039589430f, + 0.125512146061616980f, 0.125129404468921260f, 0.124746658275575490f, + 0.124363907495651240f, + 0.123981152143222060f, 0.123598392232359880f, 0.123215627777138580f, + 0.122832858791630880f, + 0.122450085289909640f, 0.122067307286049230f, 0.121684524794122440f, + 0.121301737828203960f, + 0.120918946402367330f, 0.120536150530686250f, 0.120153350227235940f, + 0.119770545506089950f, + 0.119387736381323830f, 0.119004922867011920f, 0.118622104977228730f, + 0.118239282726050290f, + 0.117856456127550970f, 0.117473625195807100f, 0.117090789944893860f, + 0.116707950388886520f, + 0.116325106541861910f, 0.115942258417895240f, 0.115559406031063570f, + 0.115176549395442460f, + 0.114793688525109290f, 0.114410823434140360f, 0.114027954136612060f, + 0.113645080646602280f, + 0.113262202978187320f, 0.112879321145445350f, 0.112496435162453430f, + 0.112113545043288730f, + 0.111730650802029900f, 0.111347752452754000f, 0.110964850009539970f, + 0.110581943486465610f, + 0.110199032897608850f, 0.109816118257049110f, 0.109433199578864170f, + 0.109050276877133770f, + 0.108667350165936400f, 0.108284419459350770f, 0.107901484771457020f, + 0.107518546116333660f, + 0.107135603508061170f, 0.106752656960718350f, 0.106369706488385940f, + 0.105986752105143480f, + 0.105603793825070680f, 0.105220831662248700f, 0.104837865630757090f, + 0.104454895744677270f, + 0.104071922018089540f, 0.103688944465074300f, 0.103305963099713400f, + 0.102922977936087120f, + 0.102539988988277600f, 0.102156996270365800f, 0.101773999796432830f, + 0.101390999580561250f, + 0.101007995636832020f, 0.100624987979327970f, 0.100241976622130760f, + 0.099858961579322170f, + 0.099475942864985456f, 0.099092920493202258f, 0.098709894478056073f, + 0.098326864833628791f, + 0.097943831574004214f, 0.097560794713264939f, 0.097177754265493674f, + 0.096794710244774623f, + 0.096411662665190329f, 0.096028611540825232f, 0.095645556885762609f, + 0.095262498714085819f, + 0.094879437039879722f, 0.094496371877227495f, 0.094113303240214247f, + 0.093730231142923864f, + 0.093347155599440373f, 0.092964076623849271f, 0.092580994230234359f, + 0.092197908432681386f, + 0.091814819245274432f, 0.091431726682099479f, 0.091048630757241303f, + 0.090665531484784803f, + 0.090282428878816323f, 0.089899322953420582f, 0.089516213722684160f, + 0.089133101200692441f, + 0.088749985401530951f, 0.088366866339286629f, 0.087983744028044805f, + 0.087600618481892656f, + 0.087217489714916191f, 0.086834357741201490f, 0.086451222574836131f, + 0.086068084229906014f, + 0.085684942720498897f, 0.085301798060701386f, 0.084918650264600160f, + 0.084535499346283349f, + 0.084152345319837438f, 0.083769188199350780f, 0.083386027998910095f, + 0.083002864732603973f, + 0.082619698414519799f, 0.082236529058745025f, 0.081853356679368619f, + 0.081470181290477811f, + 0.081087002906161790f, 0.080703821540508452f, 0.080320637207605849f, + 0.079937449921543474f, + 0.079554259696409127f, 0.079171066546292510f, 0.078787870485282088f, + 0.078404671527466441f, + 0.078021469686935602f, 0.077638264977777913f, 0.077255057414083589f, + 0.076871847009941652f, + 0.076488633779441206f, 0.076105417736672773f, 0.075722198895725248f, + 0.075338977270689375f, + 0.074955752875654230f, 0.074572525724710764f, 0.074189295831948693f, + 0.073806063211457842f, + 0.073422827877329483f, 0.073039589843653177f, 0.072656349124520389f, + 0.072273105734021334f, + 0.071889859686246352f, 0.071506610995287156f, 0.071123359675233852f, + 0.070740105740178361f, + 0.070356849204211397f, 0.069973590081423773f, 0.069590328385907715f, + 0.069207064131753759f, + 0.068823797333054326f, 0.068440528003900616f, 0.068057256158383886f, + 0.067673981810596848f, + 0.067290704974630494f, 0.066907425664577733f, 0.066524143894529736f, + 0.066140859678579578f, + 0.065757573030819083f, 0.065374283965340146f, 0.064990992496236119f, + 0.064607698637598646f, + 0.064224402403521202f, 0.063841103808096086f, 0.063457802865415636f, + 0.063074499589573618f, + 0.062691193994662109f, 0.062307886094775049f, 0.061924575904005130f, + 0.061541263436445129f, + 0.061157948706189229f, 0.060774631727329942f, 0.060391312513961619f, + 0.060007991080177375f, + 0.059624667440070382f, 0.059241341607735261f, 0.058858013597264912f, + 0.058474683422754095f, + 0.058091351098295878f, 0.057708016637985186f, 0.057324680055915692f, + 0.056941341366181127f, + 0.056558000582876661f, 0.056174657720095743f, 0.055791312791933681f, + 0.055407965812484541f, + 0.055024616795842439f, 0.054641265756102911f, 0.054257912707359794f, + 0.053874557663708772f, + 0.053491200639244271f, 0.053107841648060788f, 0.052724480704254229f, + 0.052341117821918783f, + 0.051957753015150501f, 0.051574386298044173f, 0.051191017684694640f, + 0.050807647189198162f, + 0.050424274825649297f, 0.050040900608144430f, 0.049657524550778251f, + 0.049274146667647289f, + 0.048890766972846805f, 0.048507385480472134f, 0.048124002204620014f, + 0.047740617159385448f, + 0.047357230358865306f, 0.046973841817155179f, 0.046590451548350717f, + 0.046207059566548990f, + 0.045823665885845313f, 0.045440270520336883f, 0.045056873484119603f, + 0.044673474791289434f, + 0.044290074455943754f, 0.043906672492178188f, 0.043523268914090238f, + 0.043139863735776100f, + 0.042756456971332048f, 0.042373048634855741f, 0.041989638740443119f, + 0.041606227302191955f, + 0.041222814334198304f, 0.040839399850560058f, 0.040455983865373815f, + 0.040072566392736257f, + 0.039689147446745419f, 0.039305727041497644f, 0.038922305191091085f, + 0.038538881909622631f, + 0.038155457211189216f, 0.037772031109889144f, 0.037388603619819022f, + 0.037005174755077273f, + 0.036621744529761024f, 0.036238312957967478f, 0.035854880053795196f, + 0.035471445831341021f, + 0.035088010304703626f, 0.034704573487980395f, 0.034321135395268765f, + 0.033937696040667535f, + 0.033554255438273790f, 0.033170813602186440f, 0.032787370546502645f, + 0.032403926285321405f, + 0.032020480832740429f, 0.031637034202857461f, 0.031253586409771626f, + 0.030870137467580314f, + 0.030486687390382738f, 0.030103236192276818f, 0.029719783887360508f, + 0.029336330489733147f, + 0.028952876013492331f, 0.028569420472737472f, 0.028185963881566689f, + 0.027802506254078142f, + 0.027419047604371360f, 0.027035587946544135f, 0.026652127294696067f, + 0.026268665662925468f, + 0.025885203065330677f, 0.025501739516011413f, 0.025118275029065638f, + 0.024734809618593138f, + 0.024351343298691951f, 0.023967876083461924f, 0.023584407987001611f, + 0.023200939023409587f, + 0.022817469206785804f, 0.022433998551228459f, 0.022050527070837558f, + 0.021667054779711814f, + 0.021283581691949955f, 0.020900107821652084f, 0.020516633182916549f, + 0.020133157789843505f, + 0.019749681656531803f, 0.019366204797080316f, 0.018982727225589285f, + 0.018599248956157190f, + 0.018215770002884327f, 0.017832290379869671f, 0.017448810101212228f, + 0.017065329181012358f, + 0.016681847633368677f, 0.016298365472381587f, 0.015914882712149747f, + 0.015531399366773606f, + 0.015147915450352307f, 0.014764430976985016f, 0.014380945960772247f, + 0.013997460415812761f, + 0.013613974356207112f, 0.013230487796054543f, 0.012847000749454314f, + 0.012463513230507034f, + 0.012080025253311559f, 0.011696536831968529f, 0.011313047980577277f, + 0.010929558713237145f, + 0.010546069044048827f, 0.010162578987111254f, 0.009779088556525145f, + 0.009395597766389905f, + 0.009012106630804949f, 0.008628615163871038f, 0.008245123379687167f, + 0.007861631292354124f, + 0.007478138915970929f, 0.007094646264638386f, 0.006711153352455981f, + 0.006327660193523208f, + 0.005944166801940901f, 0.005560673191808128f, 0.005177179377225743f, + 0.004793685372293270f, + 0.004410191191110246f, 0.004026696847777542f, 0.003643202356394263f, + 0.003259707731061291f, + 0.002876212985878184f, 0.002492718134944503f, 0.002109223192361147f, + 0.001725728172227238f, + 0.001342233088643682f, 0.000958737955710053f, 0.000575242787525925f, + 0.000191747598192208f +}; + +/** + @} end of DCT4_IDCT4_Table group + */ + +/** + @addtogroup DCT4_IDCT4 + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : N is not a supported transform length + + @par Normalizing factor + The normalizing factor is sqrt(2/N), which depends on the size of transform N. + Floating-point normalizing factors are mentioned in the table below for different DCT sizes: + + \image html dct4NormalizingF32Table.gif + */ + +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) +{ + /* Initialize the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + + /* Initializing the pointer array with the weight table base addresses of different lengths */ + float32_t *twiddlePtr[4] = + { (float32_t *) Weights_128, (float32_t *) Weights_512, + (float32_t *) Weights_2048, (float32_t *) Weights_8192 + }; + + /* Initializing the pointer array with the cos factor table base addresses of different lengths */ + float32_t *pCosFactor[4] = + { (float32_t *) cos_factors_128, (float32_t *) cos_factors_512, + (float32_t *) cos_factors_2048, (float32_t *) cos_factors_8192 + }; + + /* Initialize the DCT4 length */ + S->N = N; + + /* Initialize the half of DCT4 length */ + S->Nby2 = Nby2; + + /* Initialize the DCT4 Normalizing factor */ + S->normalize = normalize; + + /* Initialize Real FFT Instance */ + S->pRfft = S_RFFT; + + /* Initialize Complex FFT Instance */ + S->pCfft = S_CFFT; + + switch (N) + { + /* Initialize the table modifier values */ + case 8192U: + S->pTwiddle = twiddlePtr[3]; + S->pCosFactor = pCosFactor[3]; + break; + case 2048U: + S->pTwiddle = twiddlePtr[2]; + S->pCosFactor = pCosFactor[2]; + break; + case 512U: + S->pTwiddle = twiddlePtr[1]; + S->pCosFactor = pCosFactor[1]; + break; + case 128U: + S->pTwiddle = twiddlePtr[0]; + S->pCosFactor = pCosFactor[0]; + break; + default: + status = ARM_MATH_ARGUMENT_ERROR; + } + + /* Initialize the RFFT/RIFFT Function */ + arm_rfft_init_f32(S->pRfft, S->pCfft, S->N, 0U, 1U); + + /* return the status of DCT4 Init function */ + return (status); +} + +/** + @} end of DCT4_IDCT4 group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_q15.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_q15.c new file mode 100644 index 0000000..78f63d4 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_q15.c @@ -0,0 +1,4283 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_dct4_init_q15.c + * Description: Initialization function of DCT-4 & IDCT4 Q15 + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup DCT4_IDCT4 + */ + +/** + @addtogroup DCT4_IDCT4_Table DCT Type IV Tables + @{ + */ + +/** + @brief Weights Table + */ + +/** + @par + Weights tables are generated using the formula :
weights[n] = e^(-j*n*pi/(2*N))
+ @par + C command to generate the table +
+  for(i = 0; i< N; i++)
+  { 
+    weights[(2*i)]   =  cos(i*c);
+    weights[(2*i)+1] = -sin(i*c);
+  } 
+ @par + where N is the Number of weights to be calculated and c is pi/(2*N) + @par + Converted the output to q15 format by multiplying with 2^31 and saturated if required. + @par + In the tables below the real and imaginary values are placed alternatively, hence the + array length is 2*N. + */ + +static const q15_t __ALIGNED(4) WeightsQ15_128[256] = { + (q15_t)0x7fff, (q15_t)0x0, (q15_t)0x7ffd, (q15_t)0xfe6e, (q15_t)0x7ff6, (q15_t)0xfcdc, (q15_t)0x7fe9, (q15_t)0xfb4a, + (q15_t)0x7fd8, (q15_t)0xf9b9, (q15_t)0x7fc2, (q15_t)0xf827, (q15_t)0x7fa7, (q15_t)0xf696, (q15_t)0x7f87, (q15_t)0xf505, + (q15_t)0x7f62, (q15_t)0xf375, (q15_t)0x7f38, (q15_t)0xf1e5, (q15_t)0x7f09, (q15_t)0xf055, (q15_t)0x7ed5, (q15_t)0xeec7, + (q15_t)0x7e9d, (q15_t)0xed38, (q15_t)0x7e5f, (q15_t)0xebab, (q15_t)0x7e1d, (q15_t)0xea1e, (q15_t)0x7dd6, (q15_t)0xe893, + (q15_t)0x7d8a, (q15_t)0xe708, (q15_t)0x7d39, (q15_t)0xe57e, (q15_t)0x7ce3, (q15_t)0xe3f5, (q15_t)0x7c89, (q15_t)0xe26d, + (q15_t)0x7c29, (q15_t)0xe0e7, (q15_t)0x7bc5, (q15_t)0xdf61, (q15_t)0x7b5d, (q15_t)0xdddd, (q15_t)0x7aef, (q15_t)0xdc5a, + (q15_t)0x7a7d, (q15_t)0xdad8, (q15_t)0x7a05, (q15_t)0xd958, (q15_t)0x798a, (q15_t)0xd7da, (q15_t)0x7909, (q15_t)0xd65d, + (q15_t)0x7884, (q15_t)0xd4e1, (q15_t)0x77fa, (q15_t)0xd368, (q15_t)0x776c, (q15_t)0xd1ef, (q15_t)0x76d9, (q15_t)0xd079, + (q15_t)0x7641, (q15_t)0xcf05, (q15_t)0x75a5, (q15_t)0xcd92, (q15_t)0x7504, (q15_t)0xcc22, (q15_t)0x745f, (q15_t)0xcab3, + (q15_t)0x73b5, (q15_t)0xc946, (q15_t)0x7307, (q15_t)0xc7dc, (q15_t)0x7255, (q15_t)0xc674, (q15_t)0x719e, (q15_t)0xc50e, + (q15_t)0x70e2, (q15_t)0xc3aa, (q15_t)0x7023, (q15_t)0xc248, (q15_t)0x6f5f, (q15_t)0xc0e9, (q15_t)0x6e96, (q15_t)0xbf8d, + (q15_t)0x6dca, (q15_t)0xbe32, (q15_t)0x6cf9, (q15_t)0xbcdb, (q15_t)0x6c24, (q15_t)0xbb86, (q15_t)0x6b4a, (q15_t)0xba33, + (q15_t)0x6a6d, (q15_t)0xb8e4, (q15_t)0x698c, (q15_t)0xb797, (q15_t)0x68a6, (q15_t)0xb64c, (q15_t)0x67bd, (q15_t)0xb505, + (q15_t)0x66cf, (q15_t)0xb3c1, (q15_t)0x65dd, (q15_t)0xb27f, (q15_t)0x64e8, (q15_t)0xb141, (q15_t)0x63ef, (q15_t)0xb005, + (q15_t)0x62f2, (q15_t)0xaecd, (q15_t)0x61f1, (q15_t)0xad97, (q15_t)0x60ec, (q15_t)0xac65, (q15_t)0x5fe3, (q15_t)0xab36, + (q15_t)0x5ed7, (q15_t)0xaa0b, (q15_t)0x5dc7, (q15_t)0xa8e3, (q15_t)0x5cb4, (q15_t)0xa7be, (q15_t)0x5b9d, (q15_t)0xa69c, + (q15_t)0x5a82, (q15_t)0xa57e, (q15_t)0x5964, (q15_t)0xa463, (q15_t)0x5842, (q15_t)0xa34c, (q15_t)0x571d, (q15_t)0xa239, + (q15_t)0x55f5, (q15_t)0xa129, (q15_t)0x54ca, (q15_t)0xa01d, (q15_t)0x539b, (q15_t)0x9f14, (q15_t)0x5269, (q15_t)0x9e0f, + (q15_t)0x5133, (q15_t)0x9d0e, (q15_t)0x4ffb, (q15_t)0x9c11, (q15_t)0x4ebf, (q15_t)0x9b18, (q15_t)0x4d81, (q15_t)0x9a23, + (q15_t)0x4c3f, (q15_t)0x9931, (q15_t)0x4afb, (q15_t)0x9843, (q15_t)0x49b4, (q15_t)0x975a, (q15_t)0x4869, (q15_t)0x9674, + (q15_t)0x471c, (q15_t)0x9593, (q15_t)0x45cd, (q15_t)0x94b6, (q15_t)0x447a, (q15_t)0x93dc, (q15_t)0x4325, (q15_t)0x9307, + (q15_t)0x41ce, (q15_t)0x9236, (q15_t)0x4073, (q15_t)0x916a, (q15_t)0x3f17, (q15_t)0x90a1, (q15_t)0x3db8, (q15_t)0x8fdd, + (q15_t)0x3c56, (q15_t)0x8f1e, (q15_t)0x3af2, (q15_t)0x8e62, (q15_t)0x398c, (q15_t)0x8dab, (q15_t)0x3824, (q15_t)0x8cf9, + (q15_t)0x36ba, (q15_t)0x8c4b, (q15_t)0x354d, (q15_t)0x8ba1, (q15_t)0x33de, (q15_t)0x8afc, (q15_t)0x326e, (q15_t)0x8a5b, + (q15_t)0x30fb, (q15_t)0x89bf, (q15_t)0x2f87, (q15_t)0x8927, (q15_t)0x2e11, (q15_t)0x8894, (q15_t)0x2c98, (q15_t)0x8806, + (q15_t)0x2b1f, (q15_t)0x877c, (q15_t)0x29a3, (q15_t)0x86f7, (q15_t)0x2826, (q15_t)0x8676, (q15_t)0x26a8, (q15_t)0x85fb, + (q15_t)0x2528, (q15_t)0x8583, (q15_t)0x23a6, (q15_t)0x8511, (q15_t)0x2223, (q15_t)0x84a3, (q15_t)0x209f, (q15_t)0x843b, + (q15_t)0x1f19, (q15_t)0x83d7, (q15_t)0x1d93, (q15_t)0x8377, (q15_t)0x1c0b, (q15_t)0x831d, (q15_t)0x1a82, (q15_t)0x82c7, + (q15_t)0x18f8, (q15_t)0x8276, (q15_t)0x176d, (q15_t)0x822a, (q15_t)0x15e2, (q15_t)0x81e3, (q15_t)0x1455, (q15_t)0x81a1, + (q15_t)0x12c8, (q15_t)0x8163, (q15_t)0x1139, (q15_t)0x812b, (q15_t)0xfab, (q15_t)0x80f7, (q15_t)0xe1b, (q15_t)0x80c8, + (q15_t)0xc8b, (q15_t)0x809e, (q15_t)0xafb, (q15_t)0x8079, (q15_t)0x96a, (q15_t)0x8059, (q15_t)0x7d9, (q15_t)0x803e, + (q15_t)0x647, (q15_t)0x8028, (q15_t)0x4b6, (q15_t)0x8017, (q15_t)0x324, (q15_t)0x800a, (q15_t)0x192, (q15_t)0x8003 +}; + +static const q15_t __ALIGNED(4) WeightsQ15_512[1024] = { + (q15_t)0x7fff, (q15_t)0x0, (q15_t)0x7fff, (q15_t)0xff9c, (q15_t)0x7fff, (q15_t)0xff37, (q15_t)0x7ffe, (q15_t)0xfed3, + (q15_t)0x7ffd, (q15_t)0xfe6e, (q15_t)0x7ffc, (q15_t)0xfe0a, (q15_t)0x7ffa, (q15_t)0xfda5, (q15_t)0x7ff8, (q15_t)0xfd41, + (q15_t)0x7ff6, (q15_t)0xfcdc, (q15_t)0x7ff3, (q15_t)0xfc78, (q15_t)0x7ff0, (q15_t)0xfc13, (q15_t)0x7fed, (q15_t)0xfbaf, + (q15_t)0x7fe9, (q15_t)0xfb4a, (q15_t)0x7fe5, (q15_t)0xfae6, (q15_t)0x7fe1, (q15_t)0xfa81, (q15_t)0x7fdd, (q15_t)0xfa1d, + (q15_t)0x7fd8, (q15_t)0xf9b9, (q15_t)0x7fd3, (q15_t)0xf954, (q15_t)0x7fce, (q15_t)0xf8f0, (q15_t)0x7fc8, (q15_t)0xf88b, + (q15_t)0x7fc2, (q15_t)0xf827, (q15_t)0x7fbc, (q15_t)0xf7c3, (q15_t)0x7fb5, (q15_t)0xf75e, (q15_t)0x7fae, (q15_t)0xf6fa, + (q15_t)0x7fa7, (q15_t)0xf696, (q15_t)0x7f9f, (q15_t)0xf632, (q15_t)0x7f97, (q15_t)0xf5cd, (q15_t)0x7f8f, (q15_t)0xf569, + (q15_t)0x7f87, (q15_t)0xf505, (q15_t)0x7f7e, (q15_t)0xf4a1, (q15_t)0x7f75, (q15_t)0xf43d, (q15_t)0x7f6b, (q15_t)0xf3d9, + (q15_t)0x7f62, (q15_t)0xf375, (q15_t)0x7f58, (q15_t)0xf311, (q15_t)0x7f4d, (q15_t)0xf2ad, (q15_t)0x7f43, (q15_t)0xf249, + (q15_t)0x7f38, (q15_t)0xf1e5, (q15_t)0x7f2d, (q15_t)0xf181, (q15_t)0x7f21, (q15_t)0xf11d, (q15_t)0x7f15, (q15_t)0xf0b9, + (q15_t)0x7f09, (q15_t)0xf055, (q15_t)0x7efd, (q15_t)0xeff2, (q15_t)0x7ef0, (q15_t)0xef8e, (q15_t)0x7ee3, (q15_t)0xef2a, + (q15_t)0x7ed5, (q15_t)0xeec7, (q15_t)0x7ec8, (q15_t)0xee63, (q15_t)0x7eba, (q15_t)0xedff, (q15_t)0x7eab, (q15_t)0xed9c, + (q15_t)0x7e9d, (q15_t)0xed38, (q15_t)0x7e8e, (q15_t)0xecd5, (q15_t)0x7e7f, (q15_t)0xec72, (q15_t)0x7e6f, (q15_t)0xec0e, + (q15_t)0x7e5f, (q15_t)0xebab, (q15_t)0x7e4f, (q15_t)0xeb48, (q15_t)0x7e3f, (q15_t)0xeae5, (q15_t)0x7e2e, (q15_t)0xea81, + (q15_t)0x7e1d, (q15_t)0xea1e, (q15_t)0x7e0c, (q15_t)0xe9bb, (q15_t)0x7dfa, (q15_t)0xe958, (q15_t)0x7de8, (q15_t)0xe8f6, + (q15_t)0x7dd6, (q15_t)0xe893, (q15_t)0x7dc3, (q15_t)0xe830, (q15_t)0x7db0, (q15_t)0xe7cd, (q15_t)0x7d9d, (q15_t)0xe76a, + (q15_t)0x7d8a, (q15_t)0xe708, (q15_t)0x7d76, (q15_t)0xe6a5, (q15_t)0x7d62, (q15_t)0xe643, (q15_t)0x7d4e, (q15_t)0xe5e0, + (q15_t)0x7d39, (q15_t)0xe57e, (q15_t)0x7d24, (q15_t)0xe51c, (q15_t)0x7d0f, (q15_t)0xe4b9, (q15_t)0x7cf9, (q15_t)0xe457, + (q15_t)0x7ce3, (q15_t)0xe3f5, (q15_t)0x7ccd, (q15_t)0xe393, (q15_t)0x7cb7, (q15_t)0xe331, (q15_t)0x7ca0, (q15_t)0xe2cf, + (q15_t)0x7c89, (q15_t)0xe26d, (q15_t)0x7c71, (q15_t)0xe20b, (q15_t)0x7c5a, (q15_t)0xe1aa, (q15_t)0x7c42, (q15_t)0xe148, + (q15_t)0x7c29, (q15_t)0xe0e7, (q15_t)0x7c11, (q15_t)0xe085, (q15_t)0x7bf8, (q15_t)0xe024, (q15_t)0x7bdf, (q15_t)0xdfc2, + (q15_t)0x7bc5, (q15_t)0xdf61, (q15_t)0x7bac, (q15_t)0xdf00, (q15_t)0x7b92, (q15_t)0xde9f, (q15_t)0x7b77, (q15_t)0xde3e, + (q15_t)0x7b5d, (q15_t)0xdddd, (q15_t)0x7b42, (q15_t)0xdd7c, (q15_t)0x7b26, (q15_t)0xdd1b, (q15_t)0x7b0b, (q15_t)0xdcbb, + (q15_t)0x7aef, (q15_t)0xdc5a, (q15_t)0x7ad3, (q15_t)0xdbf9, (q15_t)0x7ab6, (q15_t)0xdb99, (q15_t)0x7a9a, (q15_t)0xdb39, + (q15_t)0x7a7d, (q15_t)0xdad8, (q15_t)0x7a5f, (q15_t)0xda78, (q15_t)0x7a42, (q15_t)0xda18, (q15_t)0x7a24, (q15_t)0xd9b8, + (q15_t)0x7a05, (q15_t)0xd958, (q15_t)0x79e7, (q15_t)0xd8f9, (q15_t)0x79c8, (q15_t)0xd899, (q15_t)0x79a9, (q15_t)0xd839, + (q15_t)0x798a, (q15_t)0xd7da, (q15_t)0x796a, (q15_t)0xd77a, (q15_t)0x794a, (q15_t)0xd71b, (q15_t)0x792a, (q15_t)0xd6bc, + (q15_t)0x7909, (q15_t)0xd65d, (q15_t)0x78e8, (q15_t)0xd5fe, (q15_t)0x78c7, (q15_t)0xd59f, (q15_t)0x78a6, (q15_t)0xd540, + (q15_t)0x7884, (q15_t)0xd4e1, (q15_t)0x7862, (q15_t)0xd483, (q15_t)0x7840, (q15_t)0xd424, (q15_t)0x781d, (q15_t)0xd3c6, + (q15_t)0x77fa, (q15_t)0xd368, (q15_t)0x77d7, (q15_t)0xd309, (q15_t)0x77b4, (q15_t)0xd2ab, (q15_t)0x7790, (q15_t)0xd24d, + (q15_t)0x776c, (q15_t)0xd1ef, (q15_t)0x7747, (q15_t)0xd192, (q15_t)0x7723, (q15_t)0xd134, (q15_t)0x76fe, (q15_t)0xd0d7, + (q15_t)0x76d9, (q15_t)0xd079, (q15_t)0x76b3, (q15_t)0xd01c, (q15_t)0x768e, (q15_t)0xcfbf, (q15_t)0x7668, (q15_t)0xcf62, + (q15_t)0x7641, (q15_t)0xcf05, (q15_t)0x761b, (q15_t)0xcea8, (q15_t)0x75f4, (q15_t)0xce4b, (q15_t)0x75cc, (q15_t)0xcdef, + (q15_t)0x75a5, (q15_t)0xcd92, (q15_t)0x757d, (q15_t)0xcd36, (q15_t)0x7555, (q15_t)0xccda, (q15_t)0x752d, (q15_t)0xcc7e, + (q15_t)0x7504, (q15_t)0xcc22, (q15_t)0x74db, (q15_t)0xcbc6, (q15_t)0x74b2, (q15_t)0xcb6a, (q15_t)0x7489, (q15_t)0xcb0e, + (q15_t)0x745f, (q15_t)0xcab3, (q15_t)0x7435, (q15_t)0xca58, (q15_t)0x740b, (q15_t)0xc9fc, (q15_t)0x73e0, (q15_t)0xc9a1, + (q15_t)0x73b5, (q15_t)0xc946, (q15_t)0x738a, (q15_t)0xc8ec, (q15_t)0x735f, (q15_t)0xc891, (q15_t)0x7333, (q15_t)0xc836, + (q15_t)0x7307, (q15_t)0xc7dc, (q15_t)0x72db, (q15_t)0xc782, (q15_t)0x72af, (q15_t)0xc728, (q15_t)0x7282, (q15_t)0xc6ce, + (q15_t)0x7255, (q15_t)0xc674, (q15_t)0x7227, (q15_t)0xc61a, (q15_t)0x71fa, (q15_t)0xc5c0, (q15_t)0x71cc, (q15_t)0xc567, + (q15_t)0x719e, (q15_t)0xc50e, (q15_t)0x716f, (q15_t)0xc4b4, (q15_t)0x7141, (q15_t)0xc45b, (q15_t)0x7112, (q15_t)0xc403, + (q15_t)0x70e2, (q15_t)0xc3aa, (q15_t)0x70b3, (q15_t)0xc351, (q15_t)0x7083, (q15_t)0xc2f9, (q15_t)0x7053, (q15_t)0xc2a0, + (q15_t)0x7023, (q15_t)0xc248, (q15_t)0x6ff2, (q15_t)0xc1f0, (q15_t)0x6fc1, (q15_t)0xc198, (q15_t)0x6f90, (q15_t)0xc141, + (q15_t)0x6f5f, (q15_t)0xc0e9, (q15_t)0x6f2d, (q15_t)0xc092, (q15_t)0x6efb, (q15_t)0xc03b, (q15_t)0x6ec9, (q15_t)0xbfe3, + (q15_t)0x6e96, (q15_t)0xbf8d, (q15_t)0x6e63, (q15_t)0xbf36, (q15_t)0x6e30, (q15_t)0xbedf, (q15_t)0x6dfd, (q15_t)0xbe89, + (q15_t)0x6dca, (q15_t)0xbe32, (q15_t)0x6d96, (q15_t)0xbddc, (q15_t)0x6d62, (q15_t)0xbd86, (q15_t)0x6d2d, (q15_t)0xbd30, + (q15_t)0x6cf9, (q15_t)0xbcdb, (q15_t)0x6cc4, (q15_t)0xbc85, (q15_t)0x6c8f, (q15_t)0xbc30, (q15_t)0x6c59, (q15_t)0xbbdb, + (q15_t)0x6c24, (q15_t)0xbb86, (q15_t)0x6bee, (q15_t)0xbb31, (q15_t)0x6bb8, (q15_t)0xbadc, (q15_t)0x6b81, (q15_t)0xba88, + (q15_t)0x6b4a, (q15_t)0xba33, (q15_t)0x6b13, (q15_t)0xb9df, (q15_t)0x6adc, (q15_t)0xb98b, (q15_t)0x6aa5, (q15_t)0xb937, + (q15_t)0x6a6d, (q15_t)0xb8e4, (q15_t)0x6a35, (q15_t)0xb890, (q15_t)0x69fd, (q15_t)0xb83d, (q15_t)0x69c4, (q15_t)0xb7ea, + (q15_t)0x698c, (q15_t)0xb797, (q15_t)0x6953, (q15_t)0xb744, (q15_t)0x6919, (q15_t)0xb6f1, (q15_t)0x68e0, (q15_t)0xb69f, + (q15_t)0x68a6, (q15_t)0xb64c, (q15_t)0x686c, (q15_t)0xb5fa, (q15_t)0x6832, (q15_t)0xb5a8, (q15_t)0x67f7, (q15_t)0xb557, + (q15_t)0x67bd, (q15_t)0xb505, (q15_t)0x6782, (q15_t)0xb4b4, (q15_t)0x6746, (q15_t)0xb462, (q15_t)0x670b, (q15_t)0xb411, + (q15_t)0x66cf, (q15_t)0xb3c1, (q15_t)0x6693, (q15_t)0xb370, (q15_t)0x6657, (q15_t)0xb31f, (q15_t)0x661a, (q15_t)0xb2cf, + (q15_t)0x65dd, (q15_t)0xb27f, (q15_t)0x65a0, (q15_t)0xb22f, (q15_t)0x6563, (q15_t)0xb1df, (q15_t)0x6526, (q15_t)0xb190, + (q15_t)0x64e8, (q15_t)0xb141, (q15_t)0x64aa, (q15_t)0xb0f1, (q15_t)0x646c, (q15_t)0xb0a2, (q15_t)0x642d, (q15_t)0xb054, + (q15_t)0x63ef, (q15_t)0xb005, (q15_t)0x63b0, (q15_t)0xafb7, (q15_t)0x6371, (q15_t)0xaf69, (q15_t)0x6331, (q15_t)0xaf1b, + (q15_t)0x62f2, (q15_t)0xaecd, (q15_t)0x62b2, (q15_t)0xae7f, (q15_t)0x6271, (q15_t)0xae32, (q15_t)0x6231, (q15_t)0xade4, + (q15_t)0x61f1, (q15_t)0xad97, (q15_t)0x61b0, (q15_t)0xad4b, (q15_t)0x616f, (q15_t)0xacfe, (q15_t)0x612d, (q15_t)0xacb2, + (q15_t)0x60ec, (q15_t)0xac65, (q15_t)0x60aa, (q15_t)0xac19, (q15_t)0x6068, (q15_t)0xabcd, (q15_t)0x6026, (q15_t)0xab82, + (q15_t)0x5fe3, (q15_t)0xab36, (q15_t)0x5fa0, (q15_t)0xaaeb, (q15_t)0x5f5e, (q15_t)0xaaa0, (q15_t)0x5f1a, (q15_t)0xaa55, + (q15_t)0x5ed7, (q15_t)0xaa0b, (q15_t)0x5e93, (q15_t)0xa9c0, (q15_t)0x5e50, (q15_t)0xa976, (q15_t)0x5e0b, (q15_t)0xa92c, + (q15_t)0x5dc7, (q15_t)0xa8e3, (q15_t)0x5d83, (q15_t)0xa899, (q15_t)0x5d3e, (q15_t)0xa850, (q15_t)0x5cf9, (q15_t)0xa807, + (q15_t)0x5cb4, (q15_t)0xa7be, (q15_t)0x5c6e, (q15_t)0xa775, (q15_t)0x5c29, (q15_t)0xa72c, (q15_t)0x5be3, (q15_t)0xa6e4, + (q15_t)0x5b9d, (q15_t)0xa69c, (q15_t)0x5b56, (q15_t)0xa654, (q15_t)0x5b10, (q15_t)0xa60d, (q15_t)0x5ac9, (q15_t)0xa5c5, + (q15_t)0x5a82, (q15_t)0xa57e, (q15_t)0x5a3b, (q15_t)0xa537, (q15_t)0x59f3, (q15_t)0xa4f0, (q15_t)0x59ac, (q15_t)0xa4aa, + (q15_t)0x5964, (q15_t)0xa463, (q15_t)0x591c, (q15_t)0xa41d, (q15_t)0x58d4, (q15_t)0xa3d7, (q15_t)0x588b, (q15_t)0xa392, + (q15_t)0x5842, (q15_t)0xa34c, (q15_t)0x57f9, (q15_t)0xa307, (q15_t)0x57b0, (q15_t)0xa2c2, (q15_t)0x5767, (q15_t)0xa27d, + (q15_t)0x571d, (q15_t)0xa239, (q15_t)0x56d4, (q15_t)0xa1f5, (q15_t)0x568a, (q15_t)0xa1b0, (q15_t)0x5640, (q15_t)0xa16d, + (q15_t)0x55f5, (q15_t)0xa129, (q15_t)0x55ab, (q15_t)0xa0e6, (q15_t)0x5560, (q15_t)0xa0a2, (q15_t)0x5515, (q15_t)0xa060, + (q15_t)0x54ca, (q15_t)0xa01d, (q15_t)0x547e, (q15_t)0x9fda, (q15_t)0x5433, (q15_t)0x9f98, (q15_t)0x53e7, (q15_t)0x9f56, + (q15_t)0x539b, (q15_t)0x9f14, (q15_t)0x534e, (q15_t)0x9ed3, (q15_t)0x5302, (q15_t)0x9e91, (q15_t)0x52b5, (q15_t)0x9e50, + (q15_t)0x5269, (q15_t)0x9e0f, (q15_t)0x521c, (q15_t)0x9dcf, (q15_t)0x51ce, (q15_t)0x9d8f, (q15_t)0x5181, (q15_t)0x9d4e, + (q15_t)0x5133, (q15_t)0x9d0e, (q15_t)0x50e5, (q15_t)0x9ccf, (q15_t)0x5097, (q15_t)0x9c8f, (q15_t)0x5049, (q15_t)0x9c50, + (q15_t)0x4ffb, (q15_t)0x9c11, (q15_t)0x4fac, (q15_t)0x9bd3, (q15_t)0x4f5e, (q15_t)0x9b94, (q15_t)0x4f0f, (q15_t)0x9b56, + (q15_t)0x4ebf, (q15_t)0x9b18, (q15_t)0x4e70, (q15_t)0x9ada, (q15_t)0x4e21, (q15_t)0x9a9d, (q15_t)0x4dd1, (q15_t)0x9a60, + (q15_t)0x4d81, (q15_t)0x9a23, (q15_t)0x4d31, (q15_t)0x99e6, (q15_t)0x4ce1, (q15_t)0x99a9, (q15_t)0x4c90, (q15_t)0x996d, + (q15_t)0x4c3f, (q15_t)0x9931, (q15_t)0x4bef, (q15_t)0x98f5, (q15_t)0x4b9e, (q15_t)0x98ba, (q15_t)0x4b4c, (q15_t)0x987e, + (q15_t)0x4afb, (q15_t)0x9843, (q15_t)0x4aa9, (q15_t)0x9809, (q15_t)0x4a58, (q15_t)0x97ce, (q15_t)0x4a06, (q15_t)0x9794, + (q15_t)0x49b4, (q15_t)0x975a, (q15_t)0x4961, (q15_t)0x9720, (q15_t)0x490f, (q15_t)0x96e7, (q15_t)0x48bc, (q15_t)0x96ad, + (q15_t)0x4869, (q15_t)0x9674, (q15_t)0x4816, (q15_t)0x963c, (q15_t)0x47c3, (q15_t)0x9603, (q15_t)0x4770, (q15_t)0x95cb, + (q15_t)0x471c, (q15_t)0x9593, (q15_t)0x46c9, (q15_t)0x955b, (q15_t)0x4675, (q15_t)0x9524, (q15_t)0x4621, (q15_t)0x94ed, + (q15_t)0x45cd, (q15_t)0x94b6, (q15_t)0x4578, (q15_t)0x947f, (q15_t)0x4524, (q15_t)0x9448, (q15_t)0x44cf, (q15_t)0x9412, + (q15_t)0x447a, (q15_t)0x93dc, (q15_t)0x4425, (q15_t)0x93a7, (q15_t)0x43d0, (q15_t)0x9371, (q15_t)0x437b, (q15_t)0x933c, + (q15_t)0x4325, (q15_t)0x9307, (q15_t)0x42d0, (q15_t)0x92d3, (q15_t)0x427a, (q15_t)0x929e, (q15_t)0x4224, (q15_t)0x926a, + (q15_t)0x41ce, (q15_t)0x9236, (q15_t)0x4177, (q15_t)0x9203, (q15_t)0x4121, (q15_t)0x91d0, (q15_t)0x40ca, (q15_t)0x919d, + (q15_t)0x4073, (q15_t)0x916a, (q15_t)0x401d, (q15_t)0x9137, (q15_t)0x3fc5, (q15_t)0x9105, (q15_t)0x3f6e, (q15_t)0x90d3, + (q15_t)0x3f17, (q15_t)0x90a1, (q15_t)0x3ebf, (q15_t)0x9070, (q15_t)0x3e68, (q15_t)0x903f, (q15_t)0x3e10, (q15_t)0x900e, + (q15_t)0x3db8, (q15_t)0x8fdd, (q15_t)0x3d60, (q15_t)0x8fad, (q15_t)0x3d07, (q15_t)0x8f7d, (q15_t)0x3caf, (q15_t)0x8f4d, + (q15_t)0x3c56, (q15_t)0x8f1e, (q15_t)0x3bfd, (q15_t)0x8eee, (q15_t)0x3ba5, (q15_t)0x8ebf, (q15_t)0x3b4c, (q15_t)0x8e91, + (q15_t)0x3af2, (q15_t)0x8e62, (q15_t)0x3a99, (q15_t)0x8e34, (q15_t)0x3a40, (q15_t)0x8e06, (q15_t)0x39e6, (q15_t)0x8dd9, + (q15_t)0x398c, (q15_t)0x8dab, (q15_t)0x3932, (q15_t)0x8d7e, (q15_t)0x38d8, (q15_t)0x8d51, (q15_t)0x387e, (q15_t)0x8d25, + (q15_t)0x3824, (q15_t)0x8cf9, (q15_t)0x37ca, (q15_t)0x8ccd, (q15_t)0x376f, (q15_t)0x8ca1, (q15_t)0x3714, (q15_t)0x8c76, + (q15_t)0x36ba, (q15_t)0x8c4b, (q15_t)0x365f, (q15_t)0x8c20, (q15_t)0x3604, (q15_t)0x8bf5, (q15_t)0x35a8, (q15_t)0x8bcb, + (q15_t)0x354d, (q15_t)0x8ba1, (q15_t)0x34f2, (q15_t)0x8b77, (q15_t)0x3496, (q15_t)0x8b4e, (q15_t)0x343a, (q15_t)0x8b25, + (q15_t)0x33de, (q15_t)0x8afc, (q15_t)0x3382, (q15_t)0x8ad3, (q15_t)0x3326, (q15_t)0x8aab, (q15_t)0x32ca, (q15_t)0x8a83, + (q15_t)0x326e, (q15_t)0x8a5b, (q15_t)0x3211, (q15_t)0x8a34, (q15_t)0x31b5, (q15_t)0x8a0c, (q15_t)0x3158, (q15_t)0x89e5, + (q15_t)0x30fb, (q15_t)0x89bf, (q15_t)0x309e, (q15_t)0x8998, (q15_t)0x3041, (q15_t)0x8972, (q15_t)0x2fe4, (q15_t)0x894d, + (q15_t)0x2f87, (q15_t)0x8927, (q15_t)0x2f29, (q15_t)0x8902, (q15_t)0x2ecc, (q15_t)0x88dd, (q15_t)0x2e6e, (q15_t)0x88b9, + (q15_t)0x2e11, (q15_t)0x8894, (q15_t)0x2db3, (q15_t)0x8870, (q15_t)0x2d55, (q15_t)0x884c, (q15_t)0x2cf7, (q15_t)0x8829, + (q15_t)0x2c98, (q15_t)0x8806, (q15_t)0x2c3a, (q15_t)0x87e3, (q15_t)0x2bdc, (q15_t)0x87c0, (q15_t)0x2b7d, (q15_t)0x879e, + (q15_t)0x2b1f, (q15_t)0x877c, (q15_t)0x2ac0, (q15_t)0x875a, (q15_t)0x2a61, (q15_t)0x8739, (q15_t)0x2a02, (q15_t)0x8718, + (q15_t)0x29a3, (q15_t)0x86f7, (q15_t)0x2944, (q15_t)0x86d6, (q15_t)0x28e5, (q15_t)0x86b6, (q15_t)0x2886, (q15_t)0x8696, + (q15_t)0x2826, (q15_t)0x8676, (q15_t)0x27c7, (q15_t)0x8657, (q15_t)0x2767, (q15_t)0x8638, (q15_t)0x2707, (q15_t)0x8619, + (q15_t)0x26a8, (q15_t)0x85fb, (q15_t)0x2648, (q15_t)0x85dc, (q15_t)0x25e8, (q15_t)0x85be, (q15_t)0x2588, (q15_t)0x85a1, + (q15_t)0x2528, (q15_t)0x8583, (q15_t)0x24c7, (q15_t)0x8566, (q15_t)0x2467, (q15_t)0x854a, (q15_t)0x2407, (q15_t)0x852d, + (q15_t)0x23a6, (q15_t)0x8511, (q15_t)0x2345, (q15_t)0x84f5, (q15_t)0x22e5, (q15_t)0x84da, (q15_t)0x2284, (q15_t)0x84be, + (q15_t)0x2223, (q15_t)0x84a3, (q15_t)0x21c2, (q15_t)0x8489, (q15_t)0x2161, (q15_t)0x846e, (q15_t)0x2100, (q15_t)0x8454, + (q15_t)0x209f, (q15_t)0x843b, (q15_t)0x203e, (q15_t)0x8421, (q15_t)0x1fdc, (q15_t)0x8408, (q15_t)0x1f7b, (q15_t)0x83ef, + (q15_t)0x1f19, (q15_t)0x83d7, (q15_t)0x1eb8, (q15_t)0x83be, (q15_t)0x1e56, (q15_t)0x83a6, (q15_t)0x1df5, (q15_t)0x838f, + (q15_t)0x1d93, (q15_t)0x8377, (q15_t)0x1d31, (q15_t)0x8360, (q15_t)0x1ccf, (q15_t)0x8349, (q15_t)0x1c6d, (q15_t)0x8333, + (q15_t)0x1c0b, (q15_t)0x831d, (q15_t)0x1ba9, (q15_t)0x8307, (q15_t)0x1b47, (q15_t)0x82f1, (q15_t)0x1ae4, (q15_t)0x82dc, + (q15_t)0x1a82, (q15_t)0x82c7, (q15_t)0x1a20, (q15_t)0x82b2, (q15_t)0x19bd, (q15_t)0x829e, (q15_t)0x195b, (q15_t)0x828a, + (q15_t)0x18f8, (q15_t)0x8276, (q15_t)0x1896, (q15_t)0x8263, (q15_t)0x1833, (q15_t)0x8250, (q15_t)0x17d0, (q15_t)0x823d, + (q15_t)0x176d, (q15_t)0x822a, (q15_t)0x170a, (q15_t)0x8218, (q15_t)0x16a8, (q15_t)0x8206, (q15_t)0x1645, (q15_t)0x81f4, + (q15_t)0x15e2, (q15_t)0x81e3, (q15_t)0x157f, (q15_t)0x81d2, (q15_t)0x151b, (q15_t)0x81c1, (q15_t)0x14b8, (q15_t)0x81b1, + (q15_t)0x1455, (q15_t)0x81a1, (q15_t)0x13f2, (q15_t)0x8191, (q15_t)0x138e, (q15_t)0x8181, (q15_t)0x132b, (q15_t)0x8172, + (q15_t)0x12c8, (q15_t)0x8163, (q15_t)0x1264, (q15_t)0x8155, (q15_t)0x1201, (q15_t)0x8146, (q15_t)0x119d, (q15_t)0x8138, + (q15_t)0x1139, (q15_t)0x812b, (q15_t)0x10d6, (q15_t)0x811d, (q15_t)0x1072, (q15_t)0x8110, (q15_t)0x100e, (q15_t)0x8103, + (q15_t)0xfab, (q15_t)0x80f7, (q15_t)0xf47, (q15_t)0x80eb, (q15_t)0xee3, (q15_t)0x80df, (q15_t)0xe7f, (q15_t)0x80d3, + (q15_t)0xe1b, (q15_t)0x80c8, (q15_t)0xdb7, (q15_t)0x80bd, (q15_t)0xd53, (q15_t)0x80b3, (q15_t)0xcef, (q15_t)0x80a8, + (q15_t)0xc8b, (q15_t)0x809e, (q15_t)0xc27, (q15_t)0x8095, (q15_t)0xbc3, (q15_t)0x808b, (q15_t)0xb5f, (q15_t)0x8082, + (q15_t)0xafb, (q15_t)0x8079, (q15_t)0xa97, (q15_t)0x8071, (q15_t)0xa33, (q15_t)0x8069, (q15_t)0x9ce, (q15_t)0x8061, + (q15_t)0x96a, (q15_t)0x8059, (q15_t)0x906, (q15_t)0x8052, (q15_t)0x8a2, (q15_t)0x804b, (q15_t)0x83d, (q15_t)0x8044, + (q15_t)0x7d9, (q15_t)0x803e, (q15_t)0x775, (q15_t)0x8038, (q15_t)0x710, (q15_t)0x8032, (q15_t)0x6ac, (q15_t)0x802d, + (q15_t)0x647, (q15_t)0x8028, (q15_t)0x5e3, (q15_t)0x8023, (q15_t)0x57f, (q15_t)0x801f, (q15_t)0x51a, (q15_t)0x801b, + (q15_t)0x4b6, (q15_t)0x8017, (q15_t)0x451, (q15_t)0x8013, (q15_t)0x3ed, (q15_t)0x8010, (q15_t)0x388, (q15_t)0x800d, + (q15_t)0x324, (q15_t)0x800a, (q15_t)0x2bf, (q15_t)0x8008, (q15_t)0x25b, (q15_t)0x8006, (q15_t)0x1f6, (q15_t)0x8004, + (q15_t)0x192, (q15_t)0x8003, (q15_t)0x12d, (q15_t)0x8002, (q15_t)0xc9, (q15_t)0x8001, (q15_t)0x64, (q15_t)0x8001 +}; + +static const q15_t __ALIGNED(4) WeightsQ15_2048[4096] = { + (q15_t)0x7fff, (q15_t)0x0, (q15_t)0x7fff, (q15_t)0xffe7, (q15_t)0x7fff, (q15_t)0xffce, (q15_t)0x7fff, (q15_t)0xffb5, + (q15_t)0x7fff, (q15_t)0xff9c, (q15_t)0x7fff, (q15_t)0xff83, (q15_t)0x7fff, (q15_t)0xff6a, (q15_t)0x7fff, (q15_t)0xff51, + (q15_t)0x7fff, (q15_t)0xff37, (q15_t)0x7fff, (q15_t)0xff1e, (q15_t)0x7fff, (q15_t)0xff05, (q15_t)0x7ffe, (q15_t)0xfeec, + (q15_t)0x7ffe, (q15_t)0xfed3, (q15_t)0x7ffe, (q15_t)0xfeba, (q15_t)0x7ffe, (q15_t)0xfea1, (q15_t)0x7ffd, (q15_t)0xfe88, + (q15_t)0x7ffd, (q15_t)0xfe6e, (q15_t)0x7ffd, (q15_t)0xfe55, (q15_t)0x7ffc, (q15_t)0xfe3c, (q15_t)0x7ffc, (q15_t)0xfe23, + (q15_t)0x7ffc, (q15_t)0xfe0a, (q15_t)0x7ffb, (q15_t)0xfdf1, (q15_t)0x7ffb, (q15_t)0xfdd8, (q15_t)0x7ffa, (q15_t)0xfdbe, + (q15_t)0x7ffa, (q15_t)0xfda5, (q15_t)0x7ff9, (q15_t)0xfd8c, (q15_t)0x7ff9, (q15_t)0xfd73, (q15_t)0x7ff8, (q15_t)0xfd5a, + (q15_t)0x7ff8, (q15_t)0xfd41, (q15_t)0x7ff7, (q15_t)0xfd28, (q15_t)0x7ff7, (q15_t)0xfd0f, (q15_t)0x7ff6, (q15_t)0xfcf5, + (q15_t)0x7ff6, (q15_t)0xfcdc, (q15_t)0x7ff5, (q15_t)0xfcc3, (q15_t)0x7ff4, (q15_t)0xfcaa, (q15_t)0x7ff4, (q15_t)0xfc91, + (q15_t)0x7ff3, (q15_t)0xfc78, (q15_t)0x7ff2, (q15_t)0xfc5f, (q15_t)0x7ff2, (q15_t)0xfc46, (q15_t)0x7ff1, (q15_t)0xfc2c, + (q15_t)0x7ff0, (q15_t)0xfc13, (q15_t)0x7fef, (q15_t)0xfbfa, (q15_t)0x7fee, (q15_t)0xfbe1, (q15_t)0x7fee, (q15_t)0xfbc8, + (q15_t)0x7fed, (q15_t)0xfbaf, (q15_t)0x7fec, (q15_t)0xfb96, (q15_t)0x7feb, (q15_t)0xfb7d, (q15_t)0x7fea, (q15_t)0xfb64, + (q15_t)0x7fe9, (q15_t)0xfb4a, (q15_t)0x7fe8, (q15_t)0xfb31, (q15_t)0x7fe7, (q15_t)0xfb18, (q15_t)0x7fe6, (q15_t)0xfaff, + (q15_t)0x7fe5, (q15_t)0xfae6, (q15_t)0x7fe4, (q15_t)0xfacd, (q15_t)0x7fe3, (q15_t)0xfab4, (q15_t)0x7fe2, (q15_t)0xfa9b, + (q15_t)0x7fe1, (q15_t)0xfa81, (q15_t)0x7fe0, (q15_t)0xfa68, (q15_t)0x7fdf, (q15_t)0xfa4f, (q15_t)0x7fde, (q15_t)0xfa36, + (q15_t)0x7fdd, (q15_t)0xfa1d, (q15_t)0x7fdc, (q15_t)0xfa04, (q15_t)0x7fda, (q15_t)0xf9eb, (q15_t)0x7fd9, (q15_t)0xf9d2, + (q15_t)0x7fd8, (q15_t)0xf9b9, (q15_t)0x7fd7, (q15_t)0xf9a0, (q15_t)0x7fd6, (q15_t)0xf986, (q15_t)0x7fd4, (q15_t)0xf96d, + (q15_t)0x7fd3, (q15_t)0xf954, (q15_t)0x7fd2, (q15_t)0xf93b, (q15_t)0x7fd0, (q15_t)0xf922, (q15_t)0x7fcf, (q15_t)0xf909, + (q15_t)0x7fce, (q15_t)0xf8f0, (q15_t)0x7fcc, (q15_t)0xf8d7, (q15_t)0x7fcb, (q15_t)0xf8be, (q15_t)0x7fc9, (q15_t)0xf8a5, + (q15_t)0x7fc8, (q15_t)0xf88b, (q15_t)0x7fc6, (q15_t)0xf872, (q15_t)0x7fc5, (q15_t)0xf859, (q15_t)0x7fc3, (q15_t)0xf840, + (q15_t)0x7fc2, (q15_t)0xf827, (q15_t)0x7fc0, (q15_t)0xf80e, (q15_t)0x7fbf, (q15_t)0xf7f5, (q15_t)0x7fbd, (q15_t)0xf7dc, + (q15_t)0x7fbc, (q15_t)0xf7c3, (q15_t)0x7fba, (q15_t)0xf7aa, (q15_t)0x7fb8, (q15_t)0xf791, (q15_t)0x7fb7, (q15_t)0xf778, + (q15_t)0x7fb5, (q15_t)0xf75e, (q15_t)0x7fb3, (q15_t)0xf745, (q15_t)0x7fb1, (q15_t)0xf72c, (q15_t)0x7fb0, (q15_t)0xf713, + (q15_t)0x7fae, (q15_t)0xf6fa, (q15_t)0x7fac, (q15_t)0xf6e1, (q15_t)0x7faa, (q15_t)0xf6c8, (q15_t)0x7fa9, (q15_t)0xf6af, + (q15_t)0x7fa7, (q15_t)0xf696, (q15_t)0x7fa5, (q15_t)0xf67d, (q15_t)0x7fa3, (q15_t)0xf664, (q15_t)0x7fa1, (q15_t)0xf64b, + (q15_t)0x7f9f, (q15_t)0xf632, (q15_t)0x7f9d, (q15_t)0xf619, (q15_t)0x7f9b, (q15_t)0xf600, (q15_t)0x7f99, (q15_t)0xf5e7, + (q15_t)0x7f97, (q15_t)0xf5cd, (q15_t)0x7f95, (q15_t)0xf5b4, (q15_t)0x7f93, (q15_t)0xf59b, (q15_t)0x7f91, (q15_t)0xf582, + (q15_t)0x7f8f, (q15_t)0xf569, (q15_t)0x7f8d, (q15_t)0xf550, (q15_t)0x7f8b, (q15_t)0xf537, (q15_t)0x7f89, (q15_t)0xf51e, + (q15_t)0x7f87, (q15_t)0xf505, (q15_t)0x7f85, (q15_t)0xf4ec, (q15_t)0x7f82, (q15_t)0xf4d3, (q15_t)0x7f80, (q15_t)0xf4ba, + (q15_t)0x7f7e, (q15_t)0xf4a1, (q15_t)0x7f7c, (q15_t)0xf488, (q15_t)0x7f79, (q15_t)0xf46f, (q15_t)0x7f77, (q15_t)0xf456, + (q15_t)0x7f75, (q15_t)0xf43d, (q15_t)0x7f72, (q15_t)0xf424, (q15_t)0x7f70, (q15_t)0xf40b, (q15_t)0x7f6e, (q15_t)0xf3f2, + (q15_t)0x7f6b, (q15_t)0xf3d9, (q15_t)0x7f69, (q15_t)0xf3c0, (q15_t)0x7f67, (q15_t)0xf3a7, (q15_t)0x7f64, (q15_t)0xf38e, + (q15_t)0x7f62, (q15_t)0xf375, (q15_t)0x7f5f, (q15_t)0xf35c, (q15_t)0x7f5d, (q15_t)0xf343, (q15_t)0x7f5a, (q15_t)0xf32a, + (q15_t)0x7f58, (q15_t)0xf311, (q15_t)0x7f55, (q15_t)0xf2f8, (q15_t)0x7f53, (q15_t)0xf2df, (q15_t)0x7f50, (q15_t)0xf2c6, + (q15_t)0x7f4d, (q15_t)0xf2ad, (q15_t)0x7f4b, (q15_t)0xf294, (q15_t)0x7f48, (q15_t)0xf27b, (q15_t)0x7f45, (q15_t)0xf262, + (q15_t)0x7f43, (q15_t)0xf249, (q15_t)0x7f40, (q15_t)0xf230, (q15_t)0x7f3d, (q15_t)0xf217, (q15_t)0x7f3b, (q15_t)0xf1fe, + (q15_t)0x7f38, (q15_t)0xf1e5, (q15_t)0x7f35, (q15_t)0xf1cc, (q15_t)0x7f32, (q15_t)0xf1b3, (q15_t)0x7f2f, (q15_t)0xf19a, + (q15_t)0x7f2d, (q15_t)0xf181, (q15_t)0x7f2a, (q15_t)0xf168, (q15_t)0x7f27, (q15_t)0xf14f, (q15_t)0x7f24, (q15_t)0xf136, + (q15_t)0x7f21, (q15_t)0xf11d, (q15_t)0x7f1e, (q15_t)0xf104, (q15_t)0x7f1b, (q15_t)0xf0eb, (q15_t)0x7f18, (q15_t)0xf0d2, + (q15_t)0x7f15, (q15_t)0xf0b9, (q15_t)0x7f12, (q15_t)0xf0a0, (q15_t)0x7f0f, (q15_t)0xf087, (q15_t)0x7f0c, (q15_t)0xf06e, + (q15_t)0x7f09, (q15_t)0xf055, (q15_t)0x7f06, (q15_t)0xf03c, (q15_t)0x7f03, (q15_t)0xf023, (q15_t)0x7f00, (q15_t)0xf00b, + (q15_t)0x7efd, (q15_t)0xeff2, (q15_t)0x7ef9, (q15_t)0xefd9, (q15_t)0x7ef6, (q15_t)0xefc0, (q15_t)0x7ef3, (q15_t)0xefa7, + (q15_t)0x7ef0, (q15_t)0xef8e, (q15_t)0x7eed, (q15_t)0xef75, (q15_t)0x7ee9, (q15_t)0xef5c, (q15_t)0x7ee6, (q15_t)0xef43, + (q15_t)0x7ee3, (q15_t)0xef2a, (q15_t)0x7edf, (q15_t)0xef11, (q15_t)0x7edc, (q15_t)0xeef8, (q15_t)0x7ed9, (q15_t)0xeedf, + (q15_t)0x7ed5, (q15_t)0xeec7, (q15_t)0x7ed2, (q15_t)0xeeae, (q15_t)0x7ecf, (q15_t)0xee95, (q15_t)0x7ecb, (q15_t)0xee7c, + (q15_t)0x7ec8, (q15_t)0xee63, (q15_t)0x7ec4, (q15_t)0xee4a, (q15_t)0x7ec1, (q15_t)0xee31, (q15_t)0x7ebd, (q15_t)0xee18, + (q15_t)0x7eba, (q15_t)0xedff, (q15_t)0x7eb6, (q15_t)0xede7, (q15_t)0x7eb3, (q15_t)0xedce, (q15_t)0x7eaf, (q15_t)0xedb5, + (q15_t)0x7eab, (q15_t)0xed9c, (q15_t)0x7ea8, (q15_t)0xed83, (q15_t)0x7ea4, (q15_t)0xed6a, (q15_t)0x7ea1, (q15_t)0xed51, + (q15_t)0x7e9d, (q15_t)0xed38, (q15_t)0x7e99, (q15_t)0xed20, (q15_t)0x7e95, (q15_t)0xed07, (q15_t)0x7e92, (q15_t)0xecee, + (q15_t)0x7e8e, (q15_t)0xecd5, (q15_t)0x7e8a, (q15_t)0xecbc, (q15_t)0x7e86, (q15_t)0xeca3, (q15_t)0x7e83, (q15_t)0xec8a, + (q15_t)0x7e7f, (q15_t)0xec72, (q15_t)0x7e7b, (q15_t)0xec59, (q15_t)0x7e77, (q15_t)0xec40, (q15_t)0x7e73, (q15_t)0xec27, + (q15_t)0x7e6f, (q15_t)0xec0e, (q15_t)0x7e6b, (q15_t)0xebf5, (q15_t)0x7e67, (q15_t)0xebdd, (q15_t)0x7e63, (q15_t)0xebc4, + (q15_t)0x7e5f, (q15_t)0xebab, (q15_t)0x7e5b, (q15_t)0xeb92, (q15_t)0x7e57, (q15_t)0xeb79, (q15_t)0x7e53, (q15_t)0xeb61, + (q15_t)0x7e4f, (q15_t)0xeb48, (q15_t)0x7e4b, (q15_t)0xeb2f, (q15_t)0x7e47, (q15_t)0xeb16, (q15_t)0x7e43, (q15_t)0xeafd, + (q15_t)0x7e3f, (q15_t)0xeae5, (q15_t)0x7e3b, (q15_t)0xeacc, (q15_t)0x7e37, (q15_t)0xeab3, (q15_t)0x7e32, (q15_t)0xea9a, + (q15_t)0x7e2e, (q15_t)0xea81, (q15_t)0x7e2a, (q15_t)0xea69, (q15_t)0x7e26, (q15_t)0xea50, (q15_t)0x7e21, (q15_t)0xea37, + (q15_t)0x7e1d, (q15_t)0xea1e, (q15_t)0x7e19, (q15_t)0xea06, (q15_t)0x7e14, (q15_t)0xe9ed, (q15_t)0x7e10, (q15_t)0xe9d4, + (q15_t)0x7e0c, (q15_t)0xe9bb, (q15_t)0x7e07, (q15_t)0xe9a3, (q15_t)0x7e03, (q15_t)0xe98a, (q15_t)0x7dff, (q15_t)0xe971, + (q15_t)0x7dfa, (q15_t)0xe958, (q15_t)0x7df6, (q15_t)0xe940, (q15_t)0x7df1, (q15_t)0xe927, (q15_t)0x7ded, (q15_t)0xe90e, + (q15_t)0x7de8, (q15_t)0xe8f6, (q15_t)0x7de4, (q15_t)0xe8dd, (q15_t)0x7ddf, (q15_t)0xe8c4, (q15_t)0x7dda, (q15_t)0xe8ab, + (q15_t)0x7dd6, (q15_t)0xe893, (q15_t)0x7dd1, (q15_t)0xe87a, (q15_t)0x7dcd, (q15_t)0xe861, (q15_t)0x7dc8, (q15_t)0xe849, + (q15_t)0x7dc3, (q15_t)0xe830, (q15_t)0x7dbf, (q15_t)0xe817, (q15_t)0x7dba, (q15_t)0xe7fe, (q15_t)0x7db5, (q15_t)0xe7e6, + (q15_t)0x7db0, (q15_t)0xe7cd, (q15_t)0x7dac, (q15_t)0xe7b4, (q15_t)0x7da7, (q15_t)0xe79c, (q15_t)0x7da2, (q15_t)0xe783, + (q15_t)0x7d9d, (q15_t)0xe76a, (q15_t)0x7d98, (q15_t)0xe752, (q15_t)0x7d94, (q15_t)0xe739, (q15_t)0x7d8f, (q15_t)0xe720, + (q15_t)0x7d8a, (q15_t)0xe708, (q15_t)0x7d85, (q15_t)0xe6ef, (q15_t)0x7d80, (q15_t)0xe6d6, (q15_t)0x7d7b, (q15_t)0xe6be, + (q15_t)0x7d76, (q15_t)0xe6a5, (q15_t)0x7d71, (q15_t)0xe68d, (q15_t)0x7d6c, (q15_t)0xe674, (q15_t)0x7d67, (q15_t)0xe65b, + (q15_t)0x7d62, (q15_t)0xe643, (q15_t)0x7d5d, (q15_t)0xe62a, (q15_t)0x7d58, (q15_t)0xe611, (q15_t)0x7d53, (q15_t)0xe5f9, + (q15_t)0x7d4e, (q15_t)0xe5e0, (q15_t)0x7d49, (q15_t)0xe5c8, (q15_t)0x7d43, (q15_t)0xe5af, (q15_t)0x7d3e, (q15_t)0xe596, + (q15_t)0x7d39, (q15_t)0xe57e, (q15_t)0x7d34, (q15_t)0xe565, (q15_t)0x7d2f, (q15_t)0xe54d, (q15_t)0x7d29, (q15_t)0xe534, + (q15_t)0x7d24, (q15_t)0xe51c, (q15_t)0x7d1f, (q15_t)0xe503, (q15_t)0x7d19, (q15_t)0xe4ea, (q15_t)0x7d14, (q15_t)0xe4d2, + (q15_t)0x7d0f, (q15_t)0xe4b9, (q15_t)0x7d09, (q15_t)0xe4a1, (q15_t)0x7d04, (q15_t)0xe488, (q15_t)0x7cff, (q15_t)0xe470, + (q15_t)0x7cf9, (q15_t)0xe457, (q15_t)0x7cf4, (q15_t)0xe43f, (q15_t)0x7cee, (q15_t)0xe426, (q15_t)0x7ce9, (q15_t)0xe40e, + (q15_t)0x7ce3, (q15_t)0xe3f5, (q15_t)0x7cde, (q15_t)0xe3dc, (q15_t)0x7cd8, (q15_t)0xe3c4, (q15_t)0x7cd3, (q15_t)0xe3ab, + (q15_t)0x7ccd, (q15_t)0xe393, (q15_t)0x7cc8, (q15_t)0xe37a, (q15_t)0x7cc2, (q15_t)0xe362, (q15_t)0x7cbc, (q15_t)0xe349, + (q15_t)0x7cb7, (q15_t)0xe331, (q15_t)0x7cb1, (q15_t)0xe318, (q15_t)0x7cab, (q15_t)0xe300, (q15_t)0x7ca6, (q15_t)0xe2e8, + (q15_t)0x7ca0, (q15_t)0xe2cf, (q15_t)0x7c9a, (q15_t)0xe2b7, (q15_t)0x7c94, (q15_t)0xe29e, (q15_t)0x7c8f, (q15_t)0xe286, + (q15_t)0x7c89, (q15_t)0xe26d, (q15_t)0x7c83, (q15_t)0xe255, (q15_t)0x7c7d, (q15_t)0xe23c, (q15_t)0x7c77, (q15_t)0xe224, + (q15_t)0x7c71, (q15_t)0xe20b, (q15_t)0x7c6c, (q15_t)0xe1f3, (q15_t)0x7c66, (q15_t)0xe1db, (q15_t)0x7c60, (q15_t)0xe1c2, + (q15_t)0x7c5a, (q15_t)0xe1aa, (q15_t)0x7c54, (q15_t)0xe191, (q15_t)0x7c4e, (q15_t)0xe179, (q15_t)0x7c48, (q15_t)0xe160, + (q15_t)0x7c42, (q15_t)0xe148, (q15_t)0x7c3c, (q15_t)0xe130, (q15_t)0x7c36, (q15_t)0xe117, (q15_t)0x7c30, (q15_t)0xe0ff, + (q15_t)0x7c29, (q15_t)0xe0e7, (q15_t)0x7c23, (q15_t)0xe0ce, (q15_t)0x7c1d, (q15_t)0xe0b6, (q15_t)0x7c17, (q15_t)0xe09d, + (q15_t)0x7c11, (q15_t)0xe085, (q15_t)0x7c0b, (q15_t)0xe06d, (q15_t)0x7c05, (q15_t)0xe054, (q15_t)0x7bfe, (q15_t)0xe03c, + (q15_t)0x7bf8, (q15_t)0xe024, (q15_t)0x7bf2, (q15_t)0xe00b, (q15_t)0x7beb, (q15_t)0xdff3, (q15_t)0x7be5, (q15_t)0xdfdb, + (q15_t)0x7bdf, (q15_t)0xdfc2, (q15_t)0x7bd9, (q15_t)0xdfaa, (q15_t)0x7bd2, (q15_t)0xdf92, (q15_t)0x7bcc, (q15_t)0xdf79, + (q15_t)0x7bc5, (q15_t)0xdf61, (q15_t)0x7bbf, (q15_t)0xdf49, (q15_t)0x7bb9, (q15_t)0xdf30, (q15_t)0x7bb2, (q15_t)0xdf18, + (q15_t)0x7bac, (q15_t)0xdf00, (q15_t)0x7ba5, (q15_t)0xdee8, (q15_t)0x7b9f, (q15_t)0xdecf, (q15_t)0x7b98, (q15_t)0xdeb7, + (q15_t)0x7b92, (q15_t)0xde9f, (q15_t)0x7b8b, (q15_t)0xde87, (q15_t)0x7b84, (q15_t)0xde6e, (q15_t)0x7b7e, (q15_t)0xde56, + (q15_t)0x7b77, (q15_t)0xde3e, (q15_t)0x7b71, (q15_t)0xde26, (q15_t)0x7b6a, (q15_t)0xde0d, (q15_t)0x7b63, (q15_t)0xddf5, + (q15_t)0x7b5d, (q15_t)0xdddd, (q15_t)0x7b56, (q15_t)0xddc5, (q15_t)0x7b4f, (q15_t)0xddac, (q15_t)0x7b48, (q15_t)0xdd94, + (q15_t)0x7b42, (q15_t)0xdd7c, (q15_t)0x7b3b, (q15_t)0xdd64, (q15_t)0x7b34, (q15_t)0xdd4c, (q15_t)0x7b2d, (q15_t)0xdd33, + (q15_t)0x7b26, (q15_t)0xdd1b, (q15_t)0x7b1f, (q15_t)0xdd03, (q15_t)0x7b19, (q15_t)0xdceb, (q15_t)0x7b12, (q15_t)0xdcd3, + (q15_t)0x7b0b, (q15_t)0xdcbb, (q15_t)0x7b04, (q15_t)0xdca2, (q15_t)0x7afd, (q15_t)0xdc8a, (q15_t)0x7af6, (q15_t)0xdc72, + (q15_t)0x7aef, (q15_t)0xdc5a, (q15_t)0x7ae8, (q15_t)0xdc42, (q15_t)0x7ae1, (q15_t)0xdc2a, (q15_t)0x7ada, (q15_t)0xdc12, + (q15_t)0x7ad3, (q15_t)0xdbf9, (q15_t)0x7acc, (q15_t)0xdbe1, (q15_t)0x7ac5, (q15_t)0xdbc9, (q15_t)0x7abd, (q15_t)0xdbb1, + (q15_t)0x7ab6, (q15_t)0xdb99, (q15_t)0x7aaf, (q15_t)0xdb81, (q15_t)0x7aa8, (q15_t)0xdb69, (q15_t)0x7aa1, (q15_t)0xdb51, + (q15_t)0x7a9a, (q15_t)0xdb39, (q15_t)0x7a92, (q15_t)0xdb21, (q15_t)0x7a8b, (q15_t)0xdb09, (q15_t)0x7a84, (q15_t)0xdaf1, + (q15_t)0x7a7d, (q15_t)0xdad8, (q15_t)0x7a75, (q15_t)0xdac0, (q15_t)0x7a6e, (q15_t)0xdaa8, (q15_t)0x7a67, (q15_t)0xda90, + (q15_t)0x7a5f, (q15_t)0xda78, (q15_t)0x7a58, (q15_t)0xda60, (q15_t)0x7a50, (q15_t)0xda48, (q15_t)0x7a49, (q15_t)0xda30, + (q15_t)0x7a42, (q15_t)0xda18, (q15_t)0x7a3a, (q15_t)0xda00, (q15_t)0x7a33, (q15_t)0xd9e8, (q15_t)0x7a2b, (q15_t)0xd9d0, + (q15_t)0x7a24, (q15_t)0xd9b8, (q15_t)0x7a1c, (q15_t)0xd9a0, (q15_t)0x7a15, (q15_t)0xd988, (q15_t)0x7a0d, (q15_t)0xd970, + (q15_t)0x7a05, (q15_t)0xd958, (q15_t)0x79fe, (q15_t)0xd940, (q15_t)0x79f6, (q15_t)0xd928, (q15_t)0x79ef, (q15_t)0xd911, + (q15_t)0x79e7, (q15_t)0xd8f9, (q15_t)0x79df, (q15_t)0xd8e1, (q15_t)0x79d8, (q15_t)0xd8c9, (q15_t)0x79d0, (q15_t)0xd8b1, + (q15_t)0x79c8, (q15_t)0xd899, (q15_t)0x79c0, (q15_t)0xd881, (q15_t)0x79b9, (q15_t)0xd869, (q15_t)0x79b1, (q15_t)0xd851, + (q15_t)0x79a9, (q15_t)0xd839, (q15_t)0x79a1, (q15_t)0xd821, (q15_t)0x7999, (q15_t)0xd80a, (q15_t)0x7992, (q15_t)0xd7f2, + (q15_t)0x798a, (q15_t)0xd7da, (q15_t)0x7982, (q15_t)0xd7c2, (q15_t)0x797a, (q15_t)0xd7aa, (q15_t)0x7972, (q15_t)0xd792, + (q15_t)0x796a, (q15_t)0xd77a, (q15_t)0x7962, (q15_t)0xd763, (q15_t)0x795a, (q15_t)0xd74b, (q15_t)0x7952, (q15_t)0xd733, + (q15_t)0x794a, (q15_t)0xd71b, (q15_t)0x7942, (q15_t)0xd703, (q15_t)0x793a, (q15_t)0xd6eb, (q15_t)0x7932, (q15_t)0xd6d4, + (q15_t)0x792a, (q15_t)0xd6bc, (q15_t)0x7922, (q15_t)0xd6a4, (q15_t)0x7919, (q15_t)0xd68c, (q15_t)0x7911, (q15_t)0xd675, + (q15_t)0x7909, (q15_t)0xd65d, (q15_t)0x7901, (q15_t)0xd645, (q15_t)0x78f9, (q15_t)0xd62d, (q15_t)0x78f1, (q15_t)0xd615, + (q15_t)0x78e8, (q15_t)0xd5fe, (q15_t)0x78e0, (q15_t)0xd5e6, (q15_t)0x78d8, (q15_t)0xd5ce, (q15_t)0x78cf, (q15_t)0xd5b7, + (q15_t)0x78c7, (q15_t)0xd59f, (q15_t)0x78bf, (q15_t)0xd587, (q15_t)0x78b6, (q15_t)0xd56f, (q15_t)0x78ae, (q15_t)0xd558, + (q15_t)0x78a6, (q15_t)0xd540, (q15_t)0x789d, (q15_t)0xd528, (q15_t)0x7895, (q15_t)0xd511, (q15_t)0x788c, (q15_t)0xd4f9, + (q15_t)0x7884, (q15_t)0xd4e1, (q15_t)0x787c, (q15_t)0xd4ca, (q15_t)0x7873, (q15_t)0xd4b2, (q15_t)0x786b, (q15_t)0xd49a, + (q15_t)0x7862, (q15_t)0xd483, (q15_t)0x7859, (q15_t)0xd46b, (q15_t)0x7851, (q15_t)0xd453, (q15_t)0x7848, (q15_t)0xd43c, + (q15_t)0x7840, (q15_t)0xd424, (q15_t)0x7837, (q15_t)0xd40d, (q15_t)0x782e, (q15_t)0xd3f5, (q15_t)0x7826, (q15_t)0xd3dd, + (q15_t)0x781d, (q15_t)0xd3c6, (q15_t)0x7814, (q15_t)0xd3ae, (q15_t)0x780c, (q15_t)0xd397, (q15_t)0x7803, (q15_t)0xd37f, + (q15_t)0x77fa, (q15_t)0xd368, (q15_t)0x77f1, (q15_t)0xd350, (q15_t)0x77e9, (q15_t)0xd338, (q15_t)0x77e0, (q15_t)0xd321, + (q15_t)0x77d7, (q15_t)0xd309, (q15_t)0x77ce, (q15_t)0xd2f2, (q15_t)0x77c5, (q15_t)0xd2da, (q15_t)0x77bc, (q15_t)0xd2c3, + (q15_t)0x77b4, (q15_t)0xd2ab, (q15_t)0x77ab, (q15_t)0xd294, (q15_t)0x77a2, (q15_t)0xd27c, (q15_t)0x7799, (q15_t)0xd265, + (q15_t)0x7790, (q15_t)0xd24d, (q15_t)0x7787, (q15_t)0xd236, (q15_t)0x777e, (q15_t)0xd21e, (q15_t)0x7775, (q15_t)0xd207, + (q15_t)0x776c, (q15_t)0xd1ef, (q15_t)0x7763, (q15_t)0xd1d8, (q15_t)0x775a, (q15_t)0xd1c1, (q15_t)0x7751, (q15_t)0xd1a9, + (q15_t)0x7747, (q15_t)0xd192, (q15_t)0x773e, (q15_t)0xd17a, (q15_t)0x7735, (q15_t)0xd163, (q15_t)0x772c, (q15_t)0xd14b, + (q15_t)0x7723, (q15_t)0xd134, (q15_t)0x771a, (q15_t)0xd11d, (q15_t)0x7710, (q15_t)0xd105, (q15_t)0x7707, (q15_t)0xd0ee, + (q15_t)0x76fe, (q15_t)0xd0d7, (q15_t)0x76f5, (q15_t)0xd0bf, (q15_t)0x76eb, (q15_t)0xd0a8, (q15_t)0x76e2, (q15_t)0xd091, + (q15_t)0x76d9, (q15_t)0xd079, (q15_t)0x76cf, (q15_t)0xd062, (q15_t)0x76c6, (q15_t)0xd04b, (q15_t)0x76bd, (q15_t)0xd033, + (q15_t)0x76b3, (q15_t)0xd01c, (q15_t)0x76aa, (q15_t)0xd005, (q15_t)0x76a0, (q15_t)0xcfed, (q15_t)0x7697, (q15_t)0xcfd6, + (q15_t)0x768e, (q15_t)0xcfbf, (q15_t)0x7684, (q15_t)0xcfa7, (q15_t)0x767b, (q15_t)0xcf90, (q15_t)0x7671, (q15_t)0xcf79, + (q15_t)0x7668, (q15_t)0xcf62, (q15_t)0x765e, (q15_t)0xcf4a, (q15_t)0x7654, (q15_t)0xcf33, (q15_t)0x764b, (q15_t)0xcf1c, + (q15_t)0x7641, (q15_t)0xcf05, (q15_t)0x7638, (q15_t)0xceee, (q15_t)0x762e, (q15_t)0xced6, (q15_t)0x7624, (q15_t)0xcebf, + (q15_t)0x761b, (q15_t)0xcea8, (q15_t)0x7611, (q15_t)0xce91, (q15_t)0x7607, (q15_t)0xce7a, (q15_t)0x75fd, (q15_t)0xce62, + (q15_t)0x75f4, (q15_t)0xce4b, (q15_t)0x75ea, (q15_t)0xce34, (q15_t)0x75e0, (q15_t)0xce1d, (q15_t)0x75d6, (q15_t)0xce06, + (q15_t)0x75cc, (q15_t)0xcdef, (q15_t)0x75c3, (q15_t)0xcdd8, (q15_t)0x75b9, (q15_t)0xcdc0, (q15_t)0x75af, (q15_t)0xcda9, + (q15_t)0x75a5, (q15_t)0xcd92, (q15_t)0x759b, (q15_t)0xcd7b, (q15_t)0x7591, (q15_t)0xcd64, (q15_t)0x7587, (q15_t)0xcd4d, + (q15_t)0x757d, (q15_t)0xcd36, (q15_t)0x7573, (q15_t)0xcd1f, (q15_t)0x7569, (q15_t)0xcd08, (q15_t)0x755f, (q15_t)0xccf1, + (q15_t)0x7555, (q15_t)0xccda, (q15_t)0x754b, (q15_t)0xccc3, (q15_t)0x7541, (q15_t)0xccac, (q15_t)0x7537, (q15_t)0xcc95, + (q15_t)0x752d, (q15_t)0xcc7e, (q15_t)0x7523, (q15_t)0xcc67, (q15_t)0x7519, (q15_t)0xcc50, (q15_t)0x750f, (q15_t)0xcc39, + (q15_t)0x7504, (q15_t)0xcc22, (q15_t)0x74fa, (q15_t)0xcc0b, (q15_t)0x74f0, (q15_t)0xcbf4, (q15_t)0x74e6, (q15_t)0xcbdd, + (q15_t)0x74db, (q15_t)0xcbc6, (q15_t)0x74d1, (q15_t)0xcbaf, (q15_t)0x74c7, (q15_t)0xcb98, (q15_t)0x74bd, (q15_t)0xcb81, + (q15_t)0x74b2, (q15_t)0xcb6a, (q15_t)0x74a8, (q15_t)0xcb53, (q15_t)0x749e, (q15_t)0xcb3c, (q15_t)0x7493, (q15_t)0xcb25, + (q15_t)0x7489, (q15_t)0xcb0e, (q15_t)0x747e, (q15_t)0xcaf8, (q15_t)0x7474, (q15_t)0xcae1, (q15_t)0x746a, (q15_t)0xcaca, + (q15_t)0x745f, (q15_t)0xcab3, (q15_t)0x7455, (q15_t)0xca9c, (q15_t)0x744a, (q15_t)0xca85, (q15_t)0x7440, (q15_t)0xca6e, + (q15_t)0x7435, (q15_t)0xca58, (q15_t)0x742b, (q15_t)0xca41, (q15_t)0x7420, (q15_t)0xca2a, (q15_t)0x7415, (q15_t)0xca13, + (q15_t)0x740b, (q15_t)0xc9fc, (q15_t)0x7400, (q15_t)0xc9e6, (q15_t)0x73f6, (q15_t)0xc9cf, (q15_t)0x73eb, (q15_t)0xc9b8, + (q15_t)0x73e0, (q15_t)0xc9a1, (q15_t)0x73d6, (q15_t)0xc98b, (q15_t)0x73cb, (q15_t)0xc974, (q15_t)0x73c0, (q15_t)0xc95d, + (q15_t)0x73b5, (q15_t)0xc946, (q15_t)0x73ab, (q15_t)0xc930, (q15_t)0x73a0, (q15_t)0xc919, (q15_t)0x7395, (q15_t)0xc902, + (q15_t)0x738a, (q15_t)0xc8ec, (q15_t)0x737f, (q15_t)0xc8d5, (q15_t)0x7375, (q15_t)0xc8be, (q15_t)0x736a, (q15_t)0xc8a8, + (q15_t)0x735f, (q15_t)0xc891, (q15_t)0x7354, (q15_t)0xc87a, (q15_t)0x7349, (q15_t)0xc864, (q15_t)0x733e, (q15_t)0xc84d, + (q15_t)0x7333, (q15_t)0xc836, (q15_t)0x7328, (q15_t)0xc820, (q15_t)0x731d, (q15_t)0xc809, (q15_t)0x7312, (q15_t)0xc7f3, + (q15_t)0x7307, (q15_t)0xc7dc, (q15_t)0x72fc, (q15_t)0xc7c5, (q15_t)0x72f1, (q15_t)0xc7af, (q15_t)0x72e6, (q15_t)0xc798, + (q15_t)0x72db, (q15_t)0xc782, (q15_t)0x72d0, (q15_t)0xc76b, (q15_t)0x72c5, (q15_t)0xc755, (q15_t)0x72ba, (q15_t)0xc73e, + (q15_t)0x72af, (q15_t)0xc728, (q15_t)0x72a3, (q15_t)0xc711, (q15_t)0x7298, (q15_t)0xc6fa, (q15_t)0x728d, (q15_t)0xc6e4, + (q15_t)0x7282, (q15_t)0xc6ce, (q15_t)0x7276, (q15_t)0xc6b7, (q15_t)0x726b, (q15_t)0xc6a1, (q15_t)0x7260, (q15_t)0xc68a, + (q15_t)0x7255, (q15_t)0xc674, (q15_t)0x7249, (q15_t)0xc65d, (q15_t)0x723e, (q15_t)0xc647, (q15_t)0x7233, (q15_t)0xc630, + (q15_t)0x7227, (q15_t)0xc61a, (q15_t)0x721c, (q15_t)0xc603, (q15_t)0x7211, (q15_t)0xc5ed, (q15_t)0x7205, (q15_t)0xc5d7, + (q15_t)0x71fa, (q15_t)0xc5c0, (q15_t)0x71ee, (q15_t)0xc5aa, (q15_t)0x71e3, (q15_t)0xc594, (q15_t)0x71d7, (q15_t)0xc57d, + (q15_t)0x71cc, (q15_t)0xc567, (q15_t)0x71c0, (q15_t)0xc551, (q15_t)0x71b5, (q15_t)0xc53a, (q15_t)0x71a9, (q15_t)0xc524, + (q15_t)0x719e, (q15_t)0xc50e, (q15_t)0x7192, (q15_t)0xc4f7, (q15_t)0x7186, (q15_t)0xc4e1, (q15_t)0x717b, (q15_t)0xc4cb, + (q15_t)0x716f, (q15_t)0xc4b4, (q15_t)0x7164, (q15_t)0xc49e, (q15_t)0x7158, (q15_t)0xc488, (q15_t)0x714c, (q15_t)0xc472, + (q15_t)0x7141, (q15_t)0xc45b, (q15_t)0x7135, (q15_t)0xc445, (q15_t)0x7129, (q15_t)0xc42f, (q15_t)0x711d, (q15_t)0xc419, + (q15_t)0x7112, (q15_t)0xc403, (q15_t)0x7106, (q15_t)0xc3ec, (q15_t)0x70fa, (q15_t)0xc3d6, (q15_t)0x70ee, (q15_t)0xc3c0, + (q15_t)0x70e2, (q15_t)0xc3aa, (q15_t)0x70d6, (q15_t)0xc394, (q15_t)0x70cb, (q15_t)0xc37d, (q15_t)0x70bf, (q15_t)0xc367, + (q15_t)0x70b3, (q15_t)0xc351, (q15_t)0x70a7, (q15_t)0xc33b, (q15_t)0x709b, (q15_t)0xc325, (q15_t)0x708f, (q15_t)0xc30f, + (q15_t)0x7083, (q15_t)0xc2f9, (q15_t)0x7077, (q15_t)0xc2e3, (q15_t)0x706b, (q15_t)0xc2cd, (q15_t)0x705f, (q15_t)0xc2b7, + (q15_t)0x7053, (q15_t)0xc2a0, (q15_t)0x7047, (q15_t)0xc28a, (q15_t)0x703b, (q15_t)0xc274, (q15_t)0x702f, (q15_t)0xc25e, + (q15_t)0x7023, (q15_t)0xc248, (q15_t)0x7016, (q15_t)0xc232, (q15_t)0x700a, (q15_t)0xc21c, (q15_t)0x6ffe, (q15_t)0xc206, + (q15_t)0x6ff2, (q15_t)0xc1f0, (q15_t)0x6fe6, (q15_t)0xc1da, (q15_t)0x6fda, (q15_t)0xc1c4, (q15_t)0x6fcd, (q15_t)0xc1ae, + (q15_t)0x6fc1, (q15_t)0xc198, (q15_t)0x6fb5, (q15_t)0xc183, (q15_t)0x6fa9, (q15_t)0xc16d, (q15_t)0x6f9c, (q15_t)0xc157, + (q15_t)0x6f90, (q15_t)0xc141, (q15_t)0x6f84, (q15_t)0xc12b, (q15_t)0x6f77, (q15_t)0xc115, (q15_t)0x6f6b, (q15_t)0xc0ff, + (q15_t)0x6f5f, (q15_t)0xc0e9, (q15_t)0x6f52, (q15_t)0xc0d3, (q15_t)0x6f46, (q15_t)0xc0bd, (q15_t)0x6f39, (q15_t)0xc0a8, + (q15_t)0x6f2d, (q15_t)0xc092, (q15_t)0x6f20, (q15_t)0xc07c, (q15_t)0x6f14, (q15_t)0xc066, (q15_t)0x6f07, (q15_t)0xc050, + (q15_t)0x6efb, (q15_t)0xc03b, (q15_t)0x6eee, (q15_t)0xc025, (q15_t)0x6ee2, (q15_t)0xc00f, (q15_t)0x6ed5, (q15_t)0xbff9, + (q15_t)0x6ec9, (q15_t)0xbfe3, (q15_t)0x6ebc, (q15_t)0xbfce, (q15_t)0x6eaf, (q15_t)0xbfb8, (q15_t)0x6ea3, (q15_t)0xbfa2, + (q15_t)0x6e96, (q15_t)0xbf8d, (q15_t)0x6e89, (q15_t)0xbf77, (q15_t)0x6e7d, (q15_t)0xbf61, (q15_t)0x6e70, (q15_t)0xbf4b, + (q15_t)0x6e63, (q15_t)0xbf36, (q15_t)0x6e57, (q15_t)0xbf20, (q15_t)0x6e4a, (q15_t)0xbf0a, (q15_t)0x6e3d, (q15_t)0xbef5, + (q15_t)0x6e30, (q15_t)0xbedf, (q15_t)0x6e24, (q15_t)0xbeca, (q15_t)0x6e17, (q15_t)0xbeb4, (q15_t)0x6e0a, (q15_t)0xbe9e, + (q15_t)0x6dfd, (q15_t)0xbe89, (q15_t)0x6df0, (q15_t)0xbe73, (q15_t)0x6de3, (q15_t)0xbe5e, (q15_t)0x6dd6, (q15_t)0xbe48, + (q15_t)0x6dca, (q15_t)0xbe32, (q15_t)0x6dbd, (q15_t)0xbe1d, (q15_t)0x6db0, (q15_t)0xbe07, (q15_t)0x6da3, (q15_t)0xbdf2, + (q15_t)0x6d96, (q15_t)0xbddc, (q15_t)0x6d89, (q15_t)0xbdc7, (q15_t)0x6d7c, (q15_t)0xbdb1, (q15_t)0x6d6f, (q15_t)0xbd9c, + (q15_t)0x6d62, (q15_t)0xbd86, (q15_t)0x6d55, (q15_t)0xbd71, (q15_t)0x6d48, (q15_t)0xbd5b, (q15_t)0x6d3a, (q15_t)0xbd46, + (q15_t)0x6d2d, (q15_t)0xbd30, (q15_t)0x6d20, (q15_t)0xbd1b, (q15_t)0x6d13, (q15_t)0xbd06, (q15_t)0x6d06, (q15_t)0xbcf0, + (q15_t)0x6cf9, (q15_t)0xbcdb, (q15_t)0x6cec, (q15_t)0xbcc5, (q15_t)0x6cde, (q15_t)0xbcb0, (q15_t)0x6cd1, (q15_t)0xbc9b, + (q15_t)0x6cc4, (q15_t)0xbc85, (q15_t)0x6cb7, (q15_t)0xbc70, (q15_t)0x6ca9, (q15_t)0xbc5b, (q15_t)0x6c9c, (q15_t)0xbc45, + (q15_t)0x6c8f, (q15_t)0xbc30, (q15_t)0x6c81, (q15_t)0xbc1b, (q15_t)0x6c74, (q15_t)0xbc05, (q15_t)0x6c67, (q15_t)0xbbf0, + (q15_t)0x6c59, (q15_t)0xbbdb, (q15_t)0x6c4c, (q15_t)0xbbc5, (q15_t)0x6c3f, (q15_t)0xbbb0, (q15_t)0x6c31, (q15_t)0xbb9b, + (q15_t)0x6c24, (q15_t)0xbb86, (q15_t)0x6c16, (q15_t)0xbb70, (q15_t)0x6c09, (q15_t)0xbb5b, (q15_t)0x6bfb, (q15_t)0xbb46, + (q15_t)0x6bee, (q15_t)0xbb31, (q15_t)0x6be0, (q15_t)0xbb1c, (q15_t)0x6bd3, (q15_t)0xbb06, (q15_t)0x6bc5, (q15_t)0xbaf1, + (q15_t)0x6bb8, (q15_t)0xbadc, (q15_t)0x6baa, (q15_t)0xbac7, (q15_t)0x6b9c, (q15_t)0xbab2, (q15_t)0x6b8f, (q15_t)0xba9d, + (q15_t)0x6b81, (q15_t)0xba88, (q15_t)0x6b73, (q15_t)0xba73, (q15_t)0x6b66, (q15_t)0xba5d, (q15_t)0x6b58, (q15_t)0xba48, + (q15_t)0x6b4a, (q15_t)0xba33, (q15_t)0x6b3d, (q15_t)0xba1e, (q15_t)0x6b2f, (q15_t)0xba09, (q15_t)0x6b21, (q15_t)0xb9f4, + (q15_t)0x6b13, (q15_t)0xb9df, (q15_t)0x6b06, (q15_t)0xb9ca, (q15_t)0x6af8, (q15_t)0xb9b5, (q15_t)0x6aea, (q15_t)0xb9a0, + (q15_t)0x6adc, (q15_t)0xb98b, (q15_t)0x6ace, (q15_t)0xb976, (q15_t)0x6ac1, (q15_t)0xb961, (q15_t)0x6ab3, (q15_t)0xb94c, + (q15_t)0x6aa5, (q15_t)0xb937, (q15_t)0x6a97, (q15_t)0xb922, (q15_t)0x6a89, (q15_t)0xb90d, (q15_t)0x6a7b, (q15_t)0xb8f8, + (q15_t)0x6a6d, (q15_t)0xb8e4, (q15_t)0x6a5f, (q15_t)0xb8cf, (q15_t)0x6a51, (q15_t)0xb8ba, (q15_t)0x6a43, (q15_t)0xb8a5, + (q15_t)0x6a35, (q15_t)0xb890, (q15_t)0x6a27, (q15_t)0xb87b, (q15_t)0x6a19, (q15_t)0xb866, (q15_t)0x6a0b, (q15_t)0xb852, + (q15_t)0x69fd, (q15_t)0xb83d, (q15_t)0x69ef, (q15_t)0xb828, (q15_t)0x69e1, (q15_t)0xb813, (q15_t)0x69d3, (q15_t)0xb7fe, + (q15_t)0x69c4, (q15_t)0xb7ea, (q15_t)0x69b6, (q15_t)0xb7d5, (q15_t)0x69a8, (q15_t)0xb7c0, (q15_t)0x699a, (q15_t)0xb7ab, + (q15_t)0x698c, (q15_t)0xb797, (q15_t)0x697d, (q15_t)0xb782, (q15_t)0x696f, (q15_t)0xb76d, (q15_t)0x6961, (q15_t)0xb758, + (q15_t)0x6953, (q15_t)0xb744, (q15_t)0x6944, (q15_t)0xb72f, (q15_t)0x6936, (q15_t)0xb71a, (q15_t)0x6928, (q15_t)0xb706, + (q15_t)0x6919, (q15_t)0xb6f1, (q15_t)0x690b, (q15_t)0xb6dd, (q15_t)0x68fd, (q15_t)0xb6c8, (q15_t)0x68ee, (q15_t)0xb6b3, + (q15_t)0x68e0, (q15_t)0xb69f, (q15_t)0x68d1, (q15_t)0xb68a, (q15_t)0x68c3, (q15_t)0xb676, (q15_t)0x68b5, (q15_t)0xb661, + (q15_t)0x68a6, (q15_t)0xb64c, (q15_t)0x6898, (q15_t)0xb638, (q15_t)0x6889, (q15_t)0xb623, (q15_t)0x687b, (q15_t)0xb60f, + (q15_t)0x686c, (q15_t)0xb5fa, (q15_t)0x685e, (q15_t)0xb5e6, (q15_t)0x684f, (q15_t)0xb5d1, (q15_t)0x6840, (q15_t)0xb5bd, + (q15_t)0x6832, (q15_t)0xb5a8, (q15_t)0x6823, (q15_t)0xb594, (q15_t)0x6815, (q15_t)0xb57f, (q15_t)0x6806, (q15_t)0xb56b, + (q15_t)0x67f7, (q15_t)0xb557, (q15_t)0x67e9, (q15_t)0xb542, (q15_t)0x67da, (q15_t)0xb52e, (q15_t)0x67cb, (q15_t)0xb519, + (q15_t)0x67bd, (q15_t)0xb505, (q15_t)0x67ae, (q15_t)0xb4f1, (q15_t)0x679f, (q15_t)0xb4dc, (q15_t)0x6790, (q15_t)0xb4c8, + (q15_t)0x6782, (q15_t)0xb4b4, (q15_t)0x6773, (q15_t)0xb49f, (q15_t)0x6764, (q15_t)0xb48b, (q15_t)0x6755, (q15_t)0xb477, + (q15_t)0x6746, (q15_t)0xb462, (q15_t)0x6737, (q15_t)0xb44e, (q15_t)0x6729, (q15_t)0xb43a, (q15_t)0x671a, (q15_t)0xb426, + (q15_t)0x670b, (q15_t)0xb411, (q15_t)0x66fc, (q15_t)0xb3fd, (q15_t)0x66ed, (q15_t)0xb3e9, (q15_t)0x66de, (q15_t)0xb3d5, + (q15_t)0x66cf, (q15_t)0xb3c1, (q15_t)0x66c0, (q15_t)0xb3ac, (q15_t)0x66b1, (q15_t)0xb398, (q15_t)0x66a2, (q15_t)0xb384, + (q15_t)0x6693, (q15_t)0xb370, (q15_t)0x6684, (q15_t)0xb35c, (q15_t)0x6675, (q15_t)0xb348, (q15_t)0x6666, (q15_t)0xb334, + (q15_t)0x6657, (q15_t)0xb31f, (q15_t)0x6648, (q15_t)0xb30b, (q15_t)0x6639, (q15_t)0xb2f7, (q15_t)0x6629, (q15_t)0xb2e3, + (q15_t)0x661a, (q15_t)0xb2cf, (q15_t)0x660b, (q15_t)0xb2bb, (q15_t)0x65fc, (q15_t)0xb2a7, (q15_t)0x65ed, (q15_t)0xb293, + (q15_t)0x65dd, (q15_t)0xb27f, (q15_t)0x65ce, (q15_t)0xb26b, (q15_t)0x65bf, (q15_t)0xb257, (q15_t)0x65b0, (q15_t)0xb243, + (q15_t)0x65a0, (q15_t)0xb22f, (q15_t)0x6591, (q15_t)0xb21b, (q15_t)0x6582, (q15_t)0xb207, (q15_t)0x6573, (q15_t)0xb1f3, + (q15_t)0x6563, (q15_t)0xb1df, (q15_t)0x6554, (q15_t)0xb1cc, (q15_t)0x6545, (q15_t)0xb1b8, (q15_t)0x6535, (q15_t)0xb1a4, + (q15_t)0x6526, (q15_t)0xb190, (q15_t)0x6516, (q15_t)0xb17c, (q15_t)0x6507, (q15_t)0xb168, (q15_t)0x64f7, (q15_t)0xb154, + (q15_t)0x64e8, (q15_t)0xb141, (q15_t)0x64d9, (q15_t)0xb12d, (q15_t)0x64c9, (q15_t)0xb119, (q15_t)0x64ba, (q15_t)0xb105, + (q15_t)0x64aa, (q15_t)0xb0f1, (q15_t)0x649b, (q15_t)0xb0de, (q15_t)0x648b, (q15_t)0xb0ca, (q15_t)0x647b, (q15_t)0xb0b6, + (q15_t)0x646c, (q15_t)0xb0a2, (q15_t)0x645c, (q15_t)0xb08f, (q15_t)0x644d, (q15_t)0xb07b, (q15_t)0x643d, (q15_t)0xb067, + (q15_t)0x642d, (q15_t)0xb054, (q15_t)0x641e, (q15_t)0xb040, (q15_t)0x640e, (q15_t)0xb02c, (q15_t)0x63fe, (q15_t)0xb019, + (q15_t)0x63ef, (q15_t)0xb005, (q15_t)0x63df, (q15_t)0xaff1, (q15_t)0x63cf, (q15_t)0xafde, (q15_t)0x63c0, (q15_t)0xafca, + (q15_t)0x63b0, (q15_t)0xafb7, (q15_t)0x63a0, (q15_t)0xafa3, (q15_t)0x6390, (q15_t)0xaf90, (q15_t)0x6380, (q15_t)0xaf7c, + (q15_t)0x6371, (q15_t)0xaf69, (q15_t)0x6361, (q15_t)0xaf55, (q15_t)0x6351, (q15_t)0xaf41, (q15_t)0x6341, (q15_t)0xaf2e, + (q15_t)0x6331, (q15_t)0xaf1b, (q15_t)0x6321, (q15_t)0xaf07, (q15_t)0x6311, (q15_t)0xaef4, (q15_t)0x6301, (q15_t)0xaee0, + (q15_t)0x62f2, (q15_t)0xaecd, (q15_t)0x62e2, (q15_t)0xaeb9, (q15_t)0x62d2, (q15_t)0xaea6, (q15_t)0x62c2, (q15_t)0xae92, + (q15_t)0x62b2, (q15_t)0xae7f, (q15_t)0x62a2, (q15_t)0xae6c, (q15_t)0x6292, (q15_t)0xae58, (q15_t)0x6282, (q15_t)0xae45, + (q15_t)0x6271, (q15_t)0xae32, (q15_t)0x6261, (q15_t)0xae1e, (q15_t)0x6251, (q15_t)0xae0b, (q15_t)0x6241, (q15_t)0xadf8, + (q15_t)0x6231, (q15_t)0xade4, (q15_t)0x6221, (q15_t)0xadd1, (q15_t)0x6211, (q15_t)0xadbe, (q15_t)0x6201, (q15_t)0xadab, + (q15_t)0x61f1, (q15_t)0xad97, (q15_t)0x61e0, (q15_t)0xad84, (q15_t)0x61d0, (q15_t)0xad71, (q15_t)0x61c0, (q15_t)0xad5e, + (q15_t)0x61b0, (q15_t)0xad4b, (q15_t)0x619f, (q15_t)0xad37, (q15_t)0x618f, (q15_t)0xad24, (q15_t)0x617f, (q15_t)0xad11, + (q15_t)0x616f, (q15_t)0xacfe, (q15_t)0x615e, (q15_t)0xaceb, (q15_t)0x614e, (q15_t)0xacd8, (q15_t)0x613e, (q15_t)0xacc5, + (q15_t)0x612d, (q15_t)0xacb2, (q15_t)0x611d, (q15_t)0xac9e, (q15_t)0x610d, (q15_t)0xac8b, (q15_t)0x60fc, (q15_t)0xac78, + (q15_t)0x60ec, (q15_t)0xac65, (q15_t)0x60db, (q15_t)0xac52, (q15_t)0x60cb, (q15_t)0xac3f, (q15_t)0x60ba, (q15_t)0xac2c, + (q15_t)0x60aa, (q15_t)0xac19, (q15_t)0x6099, (q15_t)0xac06, (q15_t)0x6089, (q15_t)0xabf3, (q15_t)0x6078, (q15_t)0xabe0, + (q15_t)0x6068, (q15_t)0xabcd, (q15_t)0x6057, (q15_t)0xabbb, (q15_t)0x6047, (q15_t)0xaba8, (q15_t)0x6036, (q15_t)0xab95, + (q15_t)0x6026, (q15_t)0xab82, (q15_t)0x6015, (q15_t)0xab6f, (q15_t)0x6004, (q15_t)0xab5c, (q15_t)0x5ff4, (q15_t)0xab49, + (q15_t)0x5fe3, (q15_t)0xab36, (q15_t)0x5fd3, (q15_t)0xab24, (q15_t)0x5fc2, (q15_t)0xab11, (q15_t)0x5fb1, (q15_t)0xaafe, + (q15_t)0x5fa0, (q15_t)0xaaeb, (q15_t)0x5f90, (q15_t)0xaad8, (q15_t)0x5f7f, (q15_t)0xaac6, (q15_t)0x5f6e, (q15_t)0xaab3, + (q15_t)0x5f5e, (q15_t)0xaaa0, (q15_t)0x5f4d, (q15_t)0xaa8e, (q15_t)0x5f3c, (q15_t)0xaa7b, (q15_t)0x5f2b, (q15_t)0xaa68, + (q15_t)0x5f1a, (q15_t)0xaa55, (q15_t)0x5f0a, (q15_t)0xaa43, (q15_t)0x5ef9, (q15_t)0xaa30, (q15_t)0x5ee8, (q15_t)0xaa1d, + (q15_t)0x5ed7, (q15_t)0xaa0b, (q15_t)0x5ec6, (q15_t)0xa9f8, (q15_t)0x5eb5, (q15_t)0xa9e6, (q15_t)0x5ea4, (q15_t)0xa9d3, + (q15_t)0x5e93, (q15_t)0xa9c0, (q15_t)0x5e82, (q15_t)0xa9ae, (q15_t)0x5e71, (q15_t)0xa99b, (q15_t)0x5e60, (q15_t)0xa989, + (q15_t)0x5e50, (q15_t)0xa976, (q15_t)0x5e3f, (q15_t)0xa964, (q15_t)0x5e2d, (q15_t)0xa951, (q15_t)0x5e1c, (q15_t)0xa93f, + (q15_t)0x5e0b, (q15_t)0xa92c, (q15_t)0x5dfa, (q15_t)0xa91a, (q15_t)0x5de9, (q15_t)0xa907, (q15_t)0x5dd8, (q15_t)0xa8f5, + (q15_t)0x5dc7, (q15_t)0xa8e3, (q15_t)0x5db6, (q15_t)0xa8d0, (q15_t)0x5da5, (q15_t)0xa8be, (q15_t)0x5d94, (q15_t)0xa8ab, + (q15_t)0x5d83, (q15_t)0xa899, (q15_t)0x5d71, (q15_t)0xa887, (q15_t)0x5d60, (q15_t)0xa874, (q15_t)0x5d4f, (q15_t)0xa862, + (q15_t)0x5d3e, (q15_t)0xa850, (q15_t)0x5d2d, (q15_t)0xa83d, (q15_t)0x5d1b, (q15_t)0xa82b, (q15_t)0x5d0a, (q15_t)0xa819, + (q15_t)0x5cf9, (q15_t)0xa807, (q15_t)0x5ce8, (q15_t)0xa7f4, (q15_t)0x5cd6, (q15_t)0xa7e2, (q15_t)0x5cc5, (q15_t)0xa7d0, + (q15_t)0x5cb4, (q15_t)0xa7be, (q15_t)0x5ca2, (q15_t)0xa7ab, (q15_t)0x5c91, (q15_t)0xa799, (q15_t)0x5c80, (q15_t)0xa787, + (q15_t)0x5c6e, (q15_t)0xa775, (q15_t)0x5c5d, (q15_t)0xa763, (q15_t)0x5c4b, (q15_t)0xa751, (q15_t)0x5c3a, (q15_t)0xa73f, + (q15_t)0x5c29, (q15_t)0xa72c, (q15_t)0x5c17, (q15_t)0xa71a, (q15_t)0x5c06, (q15_t)0xa708, (q15_t)0x5bf4, (q15_t)0xa6f6, + (q15_t)0x5be3, (q15_t)0xa6e4, (q15_t)0x5bd1, (q15_t)0xa6d2, (q15_t)0x5bc0, (q15_t)0xa6c0, (q15_t)0x5bae, (q15_t)0xa6ae, + (q15_t)0x5b9d, (q15_t)0xa69c, (q15_t)0x5b8b, (q15_t)0xa68a, (q15_t)0x5b79, (q15_t)0xa678, (q15_t)0x5b68, (q15_t)0xa666, + (q15_t)0x5b56, (q15_t)0xa654, (q15_t)0x5b45, (q15_t)0xa642, (q15_t)0x5b33, (q15_t)0xa630, (q15_t)0x5b21, (q15_t)0xa61f, + (q15_t)0x5b10, (q15_t)0xa60d, (q15_t)0x5afe, (q15_t)0xa5fb, (q15_t)0x5aec, (q15_t)0xa5e9, (q15_t)0x5adb, (q15_t)0xa5d7, + (q15_t)0x5ac9, (q15_t)0xa5c5, (q15_t)0x5ab7, (q15_t)0xa5b3, (q15_t)0x5aa5, (q15_t)0xa5a2, (q15_t)0x5a94, (q15_t)0xa590, + (q15_t)0x5a82, (q15_t)0xa57e, (q15_t)0x5a70, (q15_t)0xa56c, (q15_t)0x5a5e, (q15_t)0xa55b, (q15_t)0x5a4d, (q15_t)0xa549, + (q15_t)0x5a3b, (q15_t)0xa537, (q15_t)0x5a29, (q15_t)0xa525, (q15_t)0x5a17, (q15_t)0xa514, (q15_t)0x5a05, (q15_t)0xa502, + (q15_t)0x59f3, (q15_t)0xa4f0, (q15_t)0x59e1, (q15_t)0xa4df, (q15_t)0x59d0, (q15_t)0xa4cd, (q15_t)0x59be, (q15_t)0xa4bb, + (q15_t)0x59ac, (q15_t)0xa4aa, (q15_t)0x599a, (q15_t)0xa498, (q15_t)0x5988, (q15_t)0xa487, (q15_t)0x5976, (q15_t)0xa475, + (q15_t)0x5964, (q15_t)0xa463, (q15_t)0x5952, (q15_t)0xa452, (q15_t)0x5940, (q15_t)0xa440, (q15_t)0x592e, (q15_t)0xa42f, + (q15_t)0x591c, (q15_t)0xa41d, (q15_t)0x590a, (q15_t)0xa40c, (q15_t)0x58f8, (q15_t)0xa3fa, (q15_t)0x58e6, (q15_t)0xa3e9, + (q15_t)0x58d4, (q15_t)0xa3d7, (q15_t)0x58c1, (q15_t)0xa3c6, (q15_t)0x58af, (q15_t)0xa3b5, (q15_t)0x589d, (q15_t)0xa3a3, + (q15_t)0x588b, (q15_t)0xa392, (q15_t)0x5879, (q15_t)0xa380, (q15_t)0x5867, (q15_t)0xa36f, (q15_t)0x5855, (q15_t)0xa35e, + (q15_t)0x5842, (q15_t)0xa34c, (q15_t)0x5830, (q15_t)0xa33b, (q15_t)0x581e, (q15_t)0xa32a, (q15_t)0x580c, (q15_t)0xa318, + (q15_t)0x57f9, (q15_t)0xa307, (q15_t)0x57e7, (q15_t)0xa2f6, (q15_t)0x57d5, (q15_t)0xa2e5, (q15_t)0x57c3, (q15_t)0xa2d3, + (q15_t)0x57b0, (q15_t)0xa2c2, (q15_t)0x579e, (q15_t)0xa2b1, (q15_t)0x578c, (q15_t)0xa2a0, (q15_t)0x5779, (q15_t)0xa28f, + (q15_t)0x5767, (q15_t)0xa27d, (q15_t)0x5755, (q15_t)0xa26c, (q15_t)0x5742, (q15_t)0xa25b, (q15_t)0x5730, (q15_t)0xa24a, + (q15_t)0x571d, (q15_t)0xa239, (q15_t)0x570b, (q15_t)0xa228, (q15_t)0x56f9, (q15_t)0xa217, (q15_t)0x56e6, (q15_t)0xa206, + (q15_t)0x56d4, (q15_t)0xa1f5, (q15_t)0x56c1, (q15_t)0xa1e4, (q15_t)0x56af, (q15_t)0xa1d3, (q15_t)0x569c, (q15_t)0xa1c1, + (q15_t)0x568a, (q15_t)0xa1b0, (q15_t)0x5677, (q15_t)0xa1a0, (q15_t)0x5665, (q15_t)0xa18f, (q15_t)0x5652, (q15_t)0xa17e, + (q15_t)0x5640, (q15_t)0xa16d, (q15_t)0x562d, (q15_t)0xa15c, (q15_t)0x561a, (q15_t)0xa14b, (q15_t)0x5608, (q15_t)0xa13a, + (q15_t)0x55f5, (q15_t)0xa129, (q15_t)0x55e3, (q15_t)0xa118, (q15_t)0x55d0, (q15_t)0xa107, (q15_t)0x55bd, (q15_t)0xa0f6, + (q15_t)0x55ab, (q15_t)0xa0e6, (q15_t)0x5598, (q15_t)0xa0d5, (q15_t)0x5585, (q15_t)0xa0c4, (q15_t)0x5572, (q15_t)0xa0b3, + (q15_t)0x5560, (q15_t)0xa0a2, (q15_t)0x554d, (q15_t)0xa092, (q15_t)0x553a, (q15_t)0xa081, (q15_t)0x5528, (q15_t)0xa070, + (q15_t)0x5515, (q15_t)0xa060, (q15_t)0x5502, (q15_t)0xa04f, (q15_t)0x54ef, (q15_t)0xa03e, (q15_t)0x54dc, (q15_t)0xa02d, + (q15_t)0x54ca, (q15_t)0xa01d, (q15_t)0x54b7, (q15_t)0xa00c, (q15_t)0x54a4, (q15_t)0x9ffc, (q15_t)0x5491, (q15_t)0x9feb, + (q15_t)0x547e, (q15_t)0x9fda, (q15_t)0x546b, (q15_t)0x9fca, (q15_t)0x5458, (q15_t)0x9fb9, (q15_t)0x5445, (q15_t)0x9fa9, + (q15_t)0x5433, (q15_t)0x9f98, (q15_t)0x5420, (q15_t)0x9f88, (q15_t)0x540d, (q15_t)0x9f77, (q15_t)0x53fa, (q15_t)0x9f67, + (q15_t)0x53e7, (q15_t)0x9f56, (q15_t)0x53d4, (q15_t)0x9f46, (q15_t)0x53c1, (q15_t)0x9f35, (q15_t)0x53ae, (q15_t)0x9f25, + (q15_t)0x539b, (q15_t)0x9f14, (q15_t)0x5388, (q15_t)0x9f04, (q15_t)0x5375, (q15_t)0x9ef3, (q15_t)0x5362, (q15_t)0x9ee3, + (q15_t)0x534e, (q15_t)0x9ed3, (q15_t)0x533b, (q15_t)0x9ec2, (q15_t)0x5328, (q15_t)0x9eb2, (q15_t)0x5315, (q15_t)0x9ea2, + (q15_t)0x5302, (q15_t)0x9e91, (q15_t)0x52ef, (q15_t)0x9e81, (q15_t)0x52dc, (q15_t)0x9e71, (q15_t)0x52c9, (q15_t)0x9e61, + (q15_t)0x52b5, (q15_t)0x9e50, (q15_t)0x52a2, (q15_t)0x9e40, (q15_t)0x528f, (q15_t)0x9e30, (q15_t)0x527c, (q15_t)0x9e20, + (q15_t)0x5269, (q15_t)0x9e0f, (q15_t)0x5255, (q15_t)0x9dff, (q15_t)0x5242, (q15_t)0x9def, (q15_t)0x522f, (q15_t)0x9ddf, + (q15_t)0x521c, (q15_t)0x9dcf, (q15_t)0x5208, (q15_t)0x9dbf, (q15_t)0x51f5, (q15_t)0x9daf, (q15_t)0x51e2, (q15_t)0x9d9f, + (q15_t)0x51ce, (q15_t)0x9d8f, (q15_t)0x51bb, (q15_t)0x9d7e, (q15_t)0x51a8, (q15_t)0x9d6e, (q15_t)0x5194, (q15_t)0x9d5e, + (q15_t)0x5181, (q15_t)0x9d4e, (q15_t)0x516e, (q15_t)0x9d3e, (q15_t)0x515a, (q15_t)0x9d2e, (q15_t)0x5147, (q15_t)0x9d1e, + (q15_t)0x5133, (q15_t)0x9d0e, (q15_t)0x5120, (q15_t)0x9cff, (q15_t)0x510c, (q15_t)0x9cef, (q15_t)0x50f9, (q15_t)0x9cdf, + (q15_t)0x50e5, (q15_t)0x9ccf, (q15_t)0x50d2, (q15_t)0x9cbf, (q15_t)0x50bf, (q15_t)0x9caf, (q15_t)0x50ab, (q15_t)0x9c9f, + (q15_t)0x5097, (q15_t)0x9c8f, (q15_t)0x5084, (q15_t)0x9c80, (q15_t)0x5070, (q15_t)0x9c70, (q15_t)0x505d, (q15_t)0x9c60, + (q15_t)0x5049, (q15_t)0x9c50, (q15_t)0x5036, (q15_t)0x9c40, (q15_t)0x5022, (q15_t)0x9c31, (q15_t)0x500f, (q15_t)0x9c21, + (q15_t)0x4ffb, (q15_t)0x9c11, (q15_t)0x4fe7, (q15_t)0x9c02, (q15_t)0x4fd4, (q15_t)0x9bf2, (q15_t)0x4fc0, (q15_t)0x9be2, + (q15_t)0x4fac, (q15_t)0x9bd3, (q15_t)0x4f99, (q15_t)0x9bc3, (q15_t)0x4f85, (q15_t)0x9bb3, (q15_t)0x4f71, (q15_t)0x9ba4, + (q15_t)0x4f5e, (q15_t)0x9b94, (q15_t)0x4f4a, (q15_t)0x9b85, (q15_t)0x4f36, (q15_t)0x9b75, (q15_t)0x4f22, (q15_t)0x9b65, + (q15_t)0x4f0f, (q15_t)0x9b56, (q15_t)0x4efb, (q15_t)0x9b46, (q15_t)0x4ee7, (q15_t)0x9b37, (q15_t)0x4ed3, (q15_t)0x9b27, + (q15_t)0x4ebf, (q15_t)0x9b18, (q15_t)0x4eac, (q15_t)0x9b09, (q15_t)0x4e98, (q15_t)0x9af9, (q15_t)0x4e84, (q15_t)0x9aea, + (q15_t)0x4e70, (q15_t)0x9ada, (q15_t)0x4e5c, (q15_t)0x9acb, (q15_t)0x4e48, (q15_t)0x9abb, (q15_t)0x4e34, (q15_t)0x9aac, + (q15_t)0x4e21, (q15_t)0x9a9d, (q15_t)0x4e0d, (q15_t)0x9a8d, (q15_t)0x4df9, (q15_t)0x9a7e, (q15_t)0x4de5, (q15_t)0x9a6f, + (q15_t)0x4dd1, (q15_t)0x9a60, (q15_t)0x4dbd, (q15_t)0x9a50, (q15_t)0x4da9, (q15_t)0x9a41, (q15_t)0x4d95, (q15_t)0x9a32, + (q15_t)0x4d81, (q15_t)0x9a23, (q15_t)0x4d6d, (q15_t)0x9a13, (q15_t)0x4d59, (q15_t)0x9a04, (q15_t)0x4d45, (q15_t)0x99f5, + (q15_t)0x4d31, (q15_t)0x99e6, (q15_t)0x4d1d, (q15_t)0x99d7, (q15_t)0x4d09, (q15_t)0x99c7, (q15_t)0x4cf5, (q15_t)0x99b8, + (q15_t)0x4ce1, (q15_t)0x99a9, (q15_t)0x4ccc, (q15_t)0x999a, (q15_t)0x4cb8, (q15_t)0x998b, (q15_t)0x4ca4, (q15_t)0x997c, + (q15_t)0x4c90, (q15_t)0x996d, (q15_t)0x4c7c, (q15_t)0x995e, (q15_t)0x4c68, (q15_t)0x994f, (q15_t)0x4c54, (q15_t)0x9940, + (q15_t)0x4c3f, (q15_t)0x9931, (q15_t)0x4c2b, (q15_t)0x9922, (q15_t)0x4c17, (q15_t)0x9913, (q15_t)0x4c03, (q15_t)0x9904, + (q15_t)0x4bef, (q15_t)0x98f5, (q15_t)0x4bda, (q15_t)0x98e6, (q15_t)0x4bc6, (q15_t)0x98d7, (q15_t)0x4bb2, (q15_t)0x98c9, + (q15_t)0x4b9e, (q15_t)0x98ba, (q15_t)0x4b89, (q15_t)0x98ab, (q15_t)0x4b75, (q15_t)0x989c, (q15_t)0x4b61, (q15_t)0x988d, + (q15_t)0x4b4c, (q15_t)0x987e, (q15_t)0x4b38, (q15_t)0x9870, (q15_t)0x4b24, (q15_t)0x9861, (q15_t)0x4b0f, (q15_t)0x9852, + (q15_t)0x4afb, (q15_t)0x9843, (q15_t)0x4ae7, (q15_t)0x9835, (q15_t)0x4ad2, (q15_t)0x9826, (q15_t)0x4abe, (q15_t)0x9817, + (q15_t)0x4aa9, (q15_t)0x9809, (q15_t)0x4a95, (q15_t)0x97fa, (q15_t)0x4a81, (q15_t)0x97eb, (q15_t)0x4a6c, (q15_t)0x97dd, + (q15_t)0x4a58, (q15_t)0x97ce, (q15_t)0x4a43, (q15_t)0x97c0, (q15_t)0x4a2f, (q15_t)0x97b1, (q15_t)0x4a1a, (q15_t)0x97a2, + (q15_t)0x4a06, (q15_t)0x9794, (q15_t)0x49f1, (q15_t)0x9785, (q15_t)0x49dd, (q15_t)0x9777, (q15_t)0x49c8, (q15_t)0x9768, + (q15_t)0x49b4, (q15_t)0x975a, (q15_t)0x499f, (q15_t)0x974b, (q15_t)0x498a, (q15_t)0x973d, (q15_t)0x4976, (q15_t)0x972f, + (q15_t)0x4961, (q15_t)0x9720, (q15_t)0x494d, (q15_t)0x9712, (q15_t)0x4938, (q15_t)0x9703, (q15_t)0x4923, (q15_t)0x96f5, + (q15_t)0x490f, (q15_t)0x96e7, (q15_t)0x48fa, (q15_t)0x96d8, (q15_t)0x48e6, (q15_t)0x96ca, (q15_t)0x48d1, (q15_t)0x96bc, + (q15_t)0x48bc, (q15_t)0x96ad, (q15_t)0x48a8, (q15_t)0x969f, (q15_t)0x4893, (q15_t)0x9691, (q15_t)0x487e, (q15_t)0x9683, + (q15_t)0x4869, (q15_t)0x9674, (q15_t)0x4855, (q15_t)0x9666, (q15_t)0x4840, (q15_t)0x9658, (q15_t)0x482b, (q15_t)0x964a, + (q15_t)0x4816, (q15_t)0x963c, (q15_t)0x4802, (q15_t)0x962d, (q15_t)0x47ed, (q15_t)0x961f, (q15_t)0x47d8, (q15_t)0x9611, + (q15_t)0x47c3, (q15_t)0x9603, (q15_t)0x47ae, (q15_t)0x95f5, (q15_t)0x479a, (q15_t)0x95e7, (q15_t)0x4785, (q15_t)0x95d9, + (q15_t)0x4770, (q15_t)0x95cb, (q15_t)0x475b, (q15_t)0x95bd, (q15_t)0x4746, (q15_t)0x95af, (q15_t)0x4731, (q15_t)0x95a1, + (q15_t)0x471c, (q15_t)0x9593, (q15_t)0x4708, (q15_t)0x9585, (q15_t)0x46f3, (q15_t)0x9577, (q15_t)0x46de, (q15_t)0x9569, + (q15_t)0x46c9, (q15_t)0x955b, (q15_t)0x46b4, (q15_t)0x954d, (q15_t)0x469f, (q15_t)0x953f, (q15_t)0x468a, (q15_t)0x9532, + (q15_t)0x4675, (q15_t)0x9524, (q15_t)0x4660, (q15_t)0x9516, (q15_t)0x464b, (q15_t)0x9508, (q15_t)0x4636, (q15_t)0x94fa, + (q15_t)0x4621, (q15_t)0x94ed, (q15_t)0x460c, (q15_t)0x94df, (q15_t)0x45f7, (q15_t)0x94d1, (q15_t)0x45e2, (q15_t)0x94c3, + (q15_t)0x45cd, (q15_t)0x94b6, (q15_t)0x45b8, (q15_t)0x94a8, (q15_t)0x45a3, (q15_t)0x949a, (q15_t)0x458d, (q15_t)0x948d, + (q15_t)0x4578, (q15_t)0x947f, (q15_t)0x4563, (q15_t)0x9471, (q15_t)0x454e, (q15_t)0x9464, (q15_t)0x4539, (q15_t)0x9456, + (q15_t)0x4524, (q15_t)0x9448, (q15_t)0x450f, (q15_t)0x943b, (q15_t)0x44fa, (q15_t)0x942d, (q15_t)0x44e4, (q15_t)0x9420, + (q15_t)0x44cf, (q15_t)0x9412, (q15_t)0x44ba, (q15_t)0x9405, (q15_t)0x44a5, (q15_t)0x93f7, (q15_t)0x4490, (q15_t)0x93ea, + (q15_t)0x447a, (q15_t)0x93dc, (q15_t)0x4465, (q15_t)0x93cf, (q15_t)0x4450, (q15_t)0x93c1, (q15_t)0x443b, (q15_t)0x93b4, + (q15_t)0x4425, (q15_t)0x93a7, (q15_t)0x4410, (q15_t)0x9399, (q15_t)0x43fb, (q15_t)0x938c, (q15_t)0x43e5, (q15_t)0x937f, + (q15_t)0x43d0, (q15_t)0x9371, (q15_t)0x43bb, (q15_t)0x9364, (q15_t)0x43a5, (q15_t)0x9357, (q15_t)0x4390, (q15_t)0x9349, + (q15_t)0x437b, (q15_t)0x933c, (q15_t)0x4365, (q15_t)0x932f, (q15_t)0x4350, (q15_t)0x9322, (q15_t)0x433b, (q15_t)0x9314, + (q15_t)0x4325, (q15_t)0x9307, (q15_t)0x4310, (q15_t)0x92fa, (q15_t)0x42fa, (q15_t)0x92ed, (q15_t)0x42e5, (q15_t)0x92e0, + (q15_t)0x42d0, (q15_t)0x92d3, (q15_t)0x42ba, (q15_t)0x92c6, (q15_t)0x42a5, (q15_t)0x92b8, (q15_t)0x428f, (q15_t)0x92ab, + (q15_t)0x427a, (q15_t)0x929e, (q15_t)0x4264, (q15_t)0x9291, (q15_t)0x424f, (q15_t)0x9284, (q15_t)0x4239, (q15_t)0x9277, + (q15_t)0x4224, (q15_t)0x926a, (q15_t)0x420e, (q15_t)0x925d, (q15_t)0x41f9, (q15_t)0x9250, (q15_t)0x41e3, (q15_t)0x9243, + (q15_t)0x41ce, (q15_t)0x9236, (q15_t)0x41b8, (q15_t)0x922a, (q15_t)0x41a2, (q15_t)0x921d, (q15_t)0x418d, (q15_t)0x9210, + (q15_t)0x4177, (q15_t)0x9203, (q15_t)0x4162, (q15_t)0x91f6, (q15_t)0x414c, (q15_t)0x91e9, (q15_t)0x4136, (q15_t)0x91dc, + (q15_t)0x4121, (q15_t)0x91d0, (q15_t)0x410b, (q15_t)0x91c3, (q15_t)0x40f6, (q15_t)0x91b6, (q15_t)0x40e0, (q15_t)0x91a9, + (q15_t)0x40ca, (q15_t)0x919d, (q15_t)0x40b5, (q15_t)0x9190, (q15_t)0x409f, (q15_t)0x9183, (q15_t)0x4089, (q15_t)0x9177, + (q15_t)0x4073, (q15_t)0x916a, (q15_t)0x405e, (q15_t)0x915d, (q15_t)0x4048, (q15_t)0x9151, (q15_t)0x4032, (q15_t)0x9144, + (q15_t)0x401d, (q15_t)0x9137, (q15_t)0x4007, (q15_t)0x912b, (q15_t)0x3ff1, (q15_t)0x911e, (q15_t)0x3fdb, (q15_t)0x9112, + (q15_t)0x3fc5, (q15_t)0x9105, (q15_t)0x3fb0, (q15_t)0x90f9, (q15_t)0x3f9a, (q15_t)0x90ec, (q15_t)0x3f84, (q15_t)0x90e0, + (q15_t)0x3f6e, (q15_t)0x90d3, (q15_t)0x3f58, (q15_t)0x90c7, (q15_t)0x3f43, (q15_t)0x90ba, (q15_t)0x3f2d, (q15_t)0x90ae, + (q15_t)0x3f17, (q15_t)0x90a1, (q15_t)0x3f01, (q15_t)0x9095, (q15_t)0x3eeb, (q15_t)0x9089, (q15_t)0x3ed5, (q15_t)0x907c, + (q15_t)0x3ebf, (q15_t)0x9070, (q15_t)0x3ea9, (q15_t)0x9064, (q15_t)0x3e93, (q15_t)0x9057, (q15_t)0x3e7d, (q15_t)0x904b, + (q15_t)0x3e68, (q15_t)0x903f, (q15_t)0x3e52, (q15_t)0x9033, (q15_t)0x3e3c, (q15_t)0x9026, (q15_t)0x3e26, (q15_t)0x901a, + (q15_t)0x3e10, (q15_t)0x900e, (q15_t)0x3dfa, (q15_t)0x9002, (q15_t)0x3de4, (q15_t)0x8ff6, (q15_t)0x3dce, (q15_t)0x8fea, + (q15_t)0x3db8, (q15_t)0x8fdd, (q15_t)0x3da2, (q15_t)0x8fd1, (q15_t)0x3d8c, (q15_t)0x8fc5, (q15_t)0x3d76, (q15_t)0x8fb9, + (q15_t)0x3d60, (q15_t)0x8fad, (q15_t)0x3d49, (q15_t)0x8fa1, (q15_t)0x3d33, (q15_t)0x8f95, (q15_t)0x3d1d, (q15_t)0x8f89, + (q15_t)0x3d07, (q15_t)0x8f7d, (q15_t)0x3cf1, (q15_t)0x8f71, (q15_t)0x3cdb, (q15_t)0x8f65, (q15_t)0x3cc5, (q15_t)0x8f59, + (q15_t)0x3caf, (q15_t)0x8f4d, (q15_t)0x3c99, (q15_t)0x8f41, (q15_t)0x3c83, (q15_t)0x8f35, (q15_t)0x3c6c, (q15_t)0x8f2a, + (q15_t)0x3c56, (q15_t)0x8f1e, (q15_t)0x3c40, (q15_t)0x8f12, (q15_t)0x3c2a, (q15_t)0x8f06, (q15_t)0x3c14, (q15_t)0x8efa, + (q15_t)0x3bfd, (q15_t)0x8eee, (q15_t)0x3be7, (q15_t)0x8ee3, (q15_t)0x3bd1, (q15_t)0x8ed7, (q15_t)0x3bbb, (q15_t)0x8ecb, + (q15_t)0x3ba5, (q15_t)0x8ebf, (q15_t)0x3b8e, (q15_t)0x8eb4, (q15_t)0x3b78, (q15_t)0x8ea8, (q15_t)0x3b62, (q15_t)0x8e9c, + (q15_t)0x3b4c, (q15_t)0x8e91, (q15_t)0x3b35, (q15_t)0x8e85, (q15_t)0x3b1f, (q15_t)0x8e7a, (q15_t)0x3b09, (q15_t)0x8e6e, + (q15_t)0x3af2, (q15_t)0x8e62, (q15_t)0x3adc, (q15_t)0x8e57, (q15_t)0x3ac6, (q15_t)0x8e4b, (q15_t)0x3aaf, (q15_t)0x8e40, + (q15_t)0x3a99, (q15_t)0x8e34, (q15_t)0x3a83, (q15_t)0x8e29, (q15_t)0x3a6c, (q15_t)0x8e1d, (q15_t)0x3a56, (q15_t)0x8e12, + (q15_t)0x3a40, (q15_t)0x8e06, (q15_t)0x3a29, (q15_t)0x8dfb, (q15_t)0x3a13, (q15_t)0x8def, (q15_t)0x39fd, (q15_t)0x8de4, + (q15_t)0x39e6, (q15_t)0x8dd9, (q15_t)0x39d0, (q15_t)0x8dcd, (q15_t)0x39b9, (q15_t)0x8dc2, (q15_t)0x39a3, (q15_t)0x8db7, + (q15_t)0x398c, (q15_t)0x8dab, (q15_t)0x3976, (q15_t)0x8da0, (q15_t)0x395f, (q15_t)0x8d95, (q15_t)0x3949, (q15_t)0x8d8a, + (q15_t)0x3932, (q15_t)0x8d7e, (q15_t)0x391c, (q15_t)0x8d73, (q15_t)0x3906, (q15_t)0x8d68, (q15_t)0x38ef, (q15_t)0x8d5d, + (q15_t)0x38d8, (q15_t)0x8d51, (q15_t)0x38c2, (q15_t)0x8d46, (q15_t)0x38ab, (q15_t)0x8d3b, (q15_t)0x3895, (q15_t)0x8d30, + (q15_t)0x387e, (q15_t)0x8d25, (q15_t)0x3868, (q15_t)0x8d1a, (q15_t)0x3851, (q15_t)0x8d0f, (q15_t)0x383b, (q15_t)0x8d04, + (q15_t)0x3824, (q15_t)0x8cf9, (q15_t)0x380d, (q15_t)0x8cee, (q15_t)0x37f7, (q15_t)0x8ce3, (q15_t)0x37e0, (q15_t)0x8cd8, + (q15_t)0x37ca, (q15_t)0x8ccd, (q15_t)0x37b3, (q15_t)0x8cc2, (q15_t)0x379c, (q15_t)0x8cb7, (q15_t)0x3786, (q15_t)0x8cac, + (q15_t)0x376f, (q15_t)0x8ca1, (q15_t)0x3758, (q15_t)0x8c96, (q15_t)0x3742, (q15_t)0x8c8b, (q15_t)0x372b, (q15_t)0x8c81, + (q15_t)0x3714, (q15_t)0x8c76, (q15_t)0x36fe, (q15_t)0x8c6b, (q15_t)0x36e7, (q15_t)0x8c60, (q15_t)0x36d0, (q15_t)0x8c55, + (q15_t)0x36ba, (q15_t)0x8c4b, (q15_t)0x36a3, (q15_t)0x8c40, (q15_t)0x368c, (q15_t)0x8c35, (q15_t)0x3675, (q15_t)0x8c2a, + (q15_t)0x365f, (q15_t)0x8c20, (q15_t)0x3648, (q15_t)0x8c15, (q15_t)0x3631, (q15_t)0x8c0a, (q15_t)0x361a, (q15_t)0x8c00, + (q15_t)0x3604, (q15_t)0x8bf5, (q15_t)0x35ed, (q15_t)0x8beb, (q15_t)0x35d6, (q15_t)0x8be0, (q15_t)0x35bf, (q15_t)0x8bd5, + (q15_t)0x35a8, (q15_t)0x8bcb, (q15_t)0x3592, (q15_t)0x8bc0, (q15_t)0x357b, (q15_t)0x8bb6, (q15_t)0x3564, (q15_t)0x8bab, + (q15_t)0x354d, (q15_t)0x8ba1, (q15_t)0x3536, (q15_t)0x8b96, (q15_t)0x351f, (q15_t)0x8b8c, (q15_t)0x3508, (q15_t)0x8b82, + (q15_t)0x34f2, (q15_t)0x8b77, (q15_t)0x34db, (q15_t)0x8b6d, (q15_t)0x34c4, (q15_t)0x8b62, (q15_t)0x34ad, (q15_t)0x8b58, + (q15_t)0x3496, (q15_t)0x8b4e, (q15_t)0x347f, (q15_t)0x8b43, (q15_t)0x3468, (q15_t)0x8b39, (q15_t)0x3451, (q15_t)0x8b2f, + (q15_t)0x343a, (q15_t)0x8b25, (q15_t)0x3423, (q15_t)0x8b1a, (q15_t)0x340c, (q15_t)0x8b10, (q15_t)0x33f5, (q15_t)0x8b06, + (q15_t)0x33de, (q15_t)0x8afc, (q15_t)0x33c7, (q15_t)0x8af1, (q15_t)0x33b0, (q15_t)0x8ae7, (q15_t)0x3399, (q15_t)0x8add, + (q15_t)0x3382, (q15_t)0x8ad3, (q15_t)0x336b, (q15_t)0x8ac9, (q15_t)0x3354, (q15_t)0x8abf, (q15_t)0x333d, (q15_t)0x8ab5, + (q15_t)0x3326, (q15_t)0x8aab, (q15_t)0x330f, (q15_t)0x8aa1, (q15_t)0x32f8, (q15_t)0x8a97, (q15_t)0x32e1, (q15_t)0x8a8d, + (q15_t)0x32ca, (q15_t)0x8a83, (q15_t)0x32b3, (q15_t)0x8a79, (q15_t)0x329c, (q15_t)0x8a6f, (q15_t)0x3285, (q15_t)0x8a65, + (q15_t)0x326e, (q15_t)0x8a5b, (q15_t)0x3257, (q15_t)0x8a51, (q15_t)0x3240, (q15_t)0x8a47, (q15_t)0x3228, (q15_t)0x8a3d, + (q15_t)0x3211, (q15_t)0x8a34, (q15_t)0x31fa, (q15_t)0x8a2a, (q15_t)0x31e3, (q15_t)0x8a20, (q15_t)0x31cc, (q15_t)0x8a16, + (q15_t)0x31b5, (q15_t)0x8a0c, (q15_t)0x319e, (q15_t)0x8a03, (q15_t)0x3186, (q15_t)0x89f9, (q15_t)0x316f, (q15_t)0x89ef, + (q15_t)0x3158, (q15_t)0x89e5, (q15_t)0x3141, (q15_t)0x89dc, (q15_t)0x312a, (q15_t)0x89d2, (q15_t)0x3112, (q15_t)0x89c8, + (q15_t)0x30fb, (q15_t)0x89bf, (q15_t)0x30e4, (q15_t)0x89b5, (q15_t)0x30cd, (q15_t)0x89ac, (q15_t)0x30b6, (q15_t)0x89a2, + (q15_t)0x309e, (q15_t)0x8998, (q15_t)0x3087, (q15_t)0x898f, (q15_t)0x3070, (q15_t)0x8985, (q15_t)0x3059, (q15_t)0x897c, + (q15_t)0x3041, (q15_t)0x8972, (q15_t)0x302a, (q15_t)0x8969, (q15_t)0x3013, (q15_t)0x8960, (q15_t)0x2ffb, (q15_t)0x8956, + (q15_t)0x2fe4, (q15_t)0x894d, (q15_t)0x2fcd, (q15_t)0x8943, (q15_t)0x2fb5, (q15_t)0x893a, (q15_t)0x2f9e, (q15_t)0x8931, + (q15_t)0x2f87, (q15_t)0x8927, (q15_t)0x2f6f, (q15_t)0x891e, (q15_t)0x2f58, (q15_t)0x8915, (q15_t)0x2f41, (q15_t)0x890b, + (q15_t)0x2f29, (q15_t)0x8902, (q15_t)0x2f12, (q15_t)0x88f9, (q15_t)0x2efb, (q15_t)0x88f0, (q15_t)0x2ee3, (q15_t)0x88e6, + (q15_t)0x2ecc, (q15_t)0x88dd, (q15_t)0x2eb5, (q15_t)0x88d4, (q15_t)0x2e9d, (q15_t)0x88cb, (q15_t)0x2e86, (q15_t)0x88c2, + (q15_t)0x2e6e, (q15_t)0x88b9, (q15_t)0x2e57, (q15_t)0x88af, (q15_t)0x2e3f, (q15_t)0x88a6, (q15_t)0x2e28, (q15_t)0x889d, + (q15_t)0x2e11, (q15_t)0x8894, (q15_t)0x2df9, (q15_t)0x888b, (q15_t)0x2de2, (q15_t)0x8882, (q15_t)0x2dca, (q15_t)0x8879, + (q15_t)0x2db3, (q15_t)0x8870, (q15_t)0x2d9b, (q15_t)0x8867, (q15_t)0x2d84, (q15_t)0x885e, (q15_t)0x2d6c, (q15_t)0x8855, + (q15_t)0x2d55, (q15_t)0x884c, (q15_t)0x2d3d, (q15_t)0x8844, (q15_t)0x2d26, (q15_t)0x883b, (q15_t)0x2d0e, (q15_t)0x8832, + (q15_t)0x2cf7, (q15_t)0x8829, (q15_t)0x2cdf, (q15_t)0x8820, (q15_t)0x2cc8, (q15_t)0x8817, (q15_t)0x2cb0, (q15_t)0x880f, + (q15_t)0x2c98, (q15_t)0x8806, (q15_t)0x2c81, (q15_t)0x87fd, (q15_t)0x2c69, (q15_t)0x87f4, (q15_t)0x2c52, (q15_t)0x87ec, + (q15_t)0x2c3a, (q15_t)0x87e3, (q15_t)0x2c23, (q15_t)0x87da, (q15_t)0x2c0b, (q15_t)0x87d2, (q15_t)0x2bf3, (q15_t)0x87c9, + (q15_t)0x2bdc, (q15_t)0x87c0, (q15_t)0x2bc4, (q15_t)0x87b8, (q15_t)0x2bad, (q15_t)0x87af, (q15_t)0x2b95, (q15_t)0x87a7, + (q15_t)0x2b7d, (q15_t)0x879e, (q15_t)0x2b66, (q15_t)0x8795, (q15_t)0x2b4e, (q15_t)0x878d, (q15_t)0x2b36, (q15_t)0x8784, + (q15_t)0x2b1f, (q15_t)0x877c, (q15_t)0x2b07, (q15_t)0x8774, (q15_t)0x2aef, (q15_t)0x876b, (q15_t)0x2ad8, (q15_t)0x8763, + (q15_t)0x2ac0, (q15_t)0x875a, (q15_t)0x2aa8, (q15_t)0x8752, (q15_t)0x2a91, (q15_t)0x874a, (q15_t)0x2a79, (q15_t)0x8741, + (q15_t)0x2a61, (q15_t)0x8739, (q15_t)0x2a49, (q15_t)0x8731, (q15_t)0x2a32, (q15_t)0x8728, (q15_t)0x2a1a, (q15_t)0x8720, + (q15_t)0x2a02, (q15_t)0x8718, (q15_t)0x29eb, (q15_t)0x870f, (q15_t)0x29d3, (q15_t)0x8707, (q15_t)0x29bb, (q15_t)0x86ff, + (q15_t)0x29a3, (q15_t)0x86f7, (q15_t)0x298b, (q15_t)0x86ef, (q15_t)0x2974, (q15_t)0x86e7, (q15_t)0x295c, (q15_t)0x86de, + (q15_t)0x2944, (q15_t)0x86d6, (q15_t)0x292c, (q15_t)0x86ce, (q15_t)0x2915, (q15_t)0x86c6, (q15_t)0x28fd, (q15_t)0x86be, + (q15_t)0x28e5, (q15_t)0x86b6, (q15_t)0x28cd, (q15_t)0x86ae, (q15_t)0x28b5, (q15_t)0x86a6, (q15_t)0x289d, (q15_t)0x869e, + (q15_t)0x2886, (q15_t)0x8696, (q15_t)0x286e, (q15_t)0x868e, (q15_t)0x2856, (q15_t)0x8686, (q15_t)0x283e, (q15_t)0x867e, + (q15_t)0x2826, (q15_t)0x8676, (q15_t)0x280e, (q15_t)0x866e, (q15_t)0x27f6, (q15_t)0x8667, (q15_t)0x27df, (q15_t)0x865f, + (q15_t)0x27c7, (q15_t)0x8657, (q15_t)0x27af, (q15_t)0x864f, (q15_t)0x2797, (q15_t)0x8647, (q15_t)0x277f, (q15_t)0x8640, + (q15_t)0x2767, (q15_t)0x8638, (q15_t)0x274f, (q15_t)0x8630, (q15_t)0x2737, (q15_t)0x8628, (q15_t)0x271f, (q15_t)0x8621, + (q15_t)0x2707, (q15_t)0x8619, (q15_t)0x26ef, (q15_t)0x8611, (q15_t)0x26d8, (q15_t)0x860a, (q15_t)0x26c0, (q15_t)0x8602, + (q15_t)0x26a8, (q15_t)0x85fb, (q15_t)0x2690, (q15_t)0x85f3, (q15_t)0x2678, (q15_t)0x85eb, (q15_t)0x2660, (q15_t)0x85e4, + (q15_t)0x2648, (q15_t)0x85dc, (q15_t)0x2630, (q15_t)0x85d5, (q15_t)0x2618, (q15_t)0x85cd, (q15_t)0x2600, (q15_t)0x85c6, + (q15_t)0x25e8, (q15_t)0x85be, (q15_t)0x25d0, (q15_t)0x85b7, (q15_t)0x25b8, (q15_t)0x85b0, (q15_t)0x25a0, (q15_t)0x85a8, + (q15_t)0x2588, (q15_t)0x85a1, (q15_t)0x2570, (q15_t)0x8599, (q15_t)0x2558, (q15_t)0x8592, (q15_t)0x2540, (q15_t)0x858b, + (q15_t)0x2528, (q15_t)0x8583, (q15_t)0x250f, (q15_t)0x857c, (q15_t)0x24f7, (q15_t)0x8575, (q15_t)0x24df, (q15_t)0x856e, + (q15_t)0x24c7, (q15_t)0x8566, (q15_t)0x24af, (q15_t)0x855f, (q15_t)0x2497, (q15_t)0x8558, (q15_t)0x247f, (q15_t)0x8551, + (q15_t)0x2467, (q15_t)0x854a, (q15_t)0x244f, (q15_t)0x8543, (q15_t)0x2437, (q15_t)0x853b, (q15_t)0x241f, (q15_t)0x8534, + (q15_t)0x2407, (q15_t)0x852d, (q15_t)0x23ee, (q15_t)0x8526, (q15_t)0x23d6, (q15_t)0x851f, (q15_t)0x23be, (q15_t)0x8518, + (q15_t)0x23a6, (q15_t)0x8511, (q15_t)0x238e, (q15_t)0x850a, (q15_t)0x2376, (q15_t)0x8503, (q15_t)0x235e, (q15_t)0x84fc, + (q15_t)0x2345, (q15_t)0x84f5, (q15_t)0x232d, (q15_t)0x84ee, (q15_t)0x2315, (q15_t)0x84e7, (q15_t)0x22fd, (q15_t)0x84e1, + (q15_t)0x22e5, (q15_t)0x84da, (q15_t)0x22cd, (q15_t)0x84d3, (q15_t)0x22b4, (q15_t)0x84cc, (q15_t)0x229c, (q15_t)0x84c5, + (q15_t)0x2284, (q15_t)0x84be, (q15_t)0x226c, (q15_t)0x84b8, (q15_t)0x2254, (q15_t)0x84b1, (q15_t)0x223b, (q15_t)0x84aa, + (q15_t)0x2223, (q15_t)0x84a3, (q15_t)0x220b, (q15_t)0x849d, (q15_t)0x21f3, (q15_t)0x8496, (q15_t)0x21da, (q15_t)0x848f, + (q15_t)0x21c2, (q15_t)0x8489, (q15_t)0x21aa, (q15_t)0x8482, (q15_t)0x2192, (q15_t)0x847c, (q15_t)0x2179, (q15_t)0x8475, + (q15_t)0x2161, (q15_t)0x846e, (q15_t)0x2149, (q15_t)0x8468, (q15_t)0x2131, (q15_t)0x8461, (q15_t)0x2118, (q15_t)0x845b, + (q15_t)0x2100, (q15_t)0x8454, (q15_t)0x20e8, (q15_t)0x844e, (q15_t)0x20d0, (q15_t)0x8447, (q15_t)0x20b7, (q15_t)0x8441, + (q15_t)0x209f, (q15_t)0x843b, (q15_t)0x2087, (q15_t)0x8434, (q15_t)0x206e, (q15_t)0x842e, (q15_t)0x2056, (q15_t)0x8427, + (q15_t)0x203e, (q15_t)0x8421, (q15_t)0x2025, (q15_t)0x841b, (q15_t)0x200d, (q15_t)0x8415, (q15_t)0x1ff5, (q15_t)0x840e, + (q15_t)0x1fdc, (q15_t)0x8408, (q15_t)0x1fc4, (q15_t)0x8402, (q15_t)0x1fac, (q15_t)0x83fb, (q15_t)0x1f93, (q15_t)0x83f5, + (q15_t)0x1f7b, (q15_t)0x83ef, (q15_t)0x1f63, (q15_t)0x83e9, (q15_t)0x1f4a, (q15_t)0x83e3, (q15_t)0x1f32, (q15_t)0x83dd, + (q15_t)0x1f19, (q15_t)0x83d7, (q15_t)0x1f01, (q15_t)0x83d0, (q15_t)0x1ee9, (q15_t)0x83ca, (q15_t)0x1ed0, (q15_t)0x83c4, + (q15_t)0x1eb8, (q15_t)0x83be, (q15_t)0x1ea0, (q15_t)0x83b8, (q15_t)0x1e87, (q15_t)0x83b2, (q15_t)0x1e6f, (q15_t)0x83ac, + (q15_t)0x1e56, (q15_t)0x83a6, (q15_t)0x1e3e, (q15_t)0x83a0, (q15_t)0x1e25, (q15_t)0x839a, (q15_t)0x1e0d, (q15_t)0x8394, + (q15_t)0x1df5, (q15_t)0x838f, (q15_t)0x1ddc, (q15_t)0x8389, (q15_t)0x1dc4, (q15_t)0x8383, (q15_t)0x1dab, (q15_t)0x837d, + (q15_t)0x1d93, (q15_t)0x8377, (q15_t)0x1d7a, (q15_t)0x8371, (q15_t)0x1d62, (q15_t)0x836c, (q15_t)0x1d49, (q15_t)0x8366, + (q15_t)0x1d31, (q15_t)0x8360, (q15_t)0x1d18, (q15_t)0x835a, (q15_t)0x1d00, (q15_t)0x8355, (q15_t)0x1ce8, (q15_t)0x834f, + (q15_t)0x1ccf, (q15_t)0x8349, (q15_t)0x1cb7, (q15_t)0x8344, (q15_t)0x1c9e, (q15_t)0x833e, (q15_t)0x1c86, (q15_t)0x8338, + (q15_t)0x1c6d, (q15_t)0x8333, (q15_t)0x1c55, (q15_t)0x832d, (q15_t)0x1c3c, (q15_t)0x8328, (q15_t)0x1c24, (q15_t)0x8322, + (q15_t)0x1c0b, (q15_t)0x831d, (q15_t)0x1bf2, (q15_t)0x8317, (q15_t)0x1bda, (q15_t)0x8312, (q15_t)0x1bc1, (q15_t)0x830c, + (q15_t)0x1ba9, (q15_t)0x8307, (q15_t)0x1b90, (q15_t)0x8301, (q15_t)0x1b78, (q15_t)0x82fc, (q15_t)0x1b5f, (q15_t)0x82f7, + (q15_t)0x1b47, (q15_t)0x82f1, (q15_t)0x1b2e, (q15_t)0x82ec, (q15_t)0x1b16, (q15_t)0x82e7, (q15_t)0x1afd, (q15_t)0x82e1, + (q15_t)0x1ae4, (q15_t)0x82dc, (q15_t)0x1acc, (q15_t)0x82d7, (q15_t)0x1ab3, (q15_t)0x82d1, (q15_t)0x1a9b, (q15_t)0x82cc, + (q15_t)0x1a82, (q15_t)0x82c7, (q15_t)0x1a6a, (q15_t)0x82c2, (q15_t)0x1a51, (q15_t)0x82bd, (q15_t)0x1a38, (q15_t)0x82b7, + (q15_t)0x1a20, (q15_t)0x82b2, (q15_t)0x1a07, (q15_t)0x82ad, (q15_t)0x19ef, (q15_t)0x82a8, (q15_t)0x19d6, (q15_t)0x82a3, + (q15_t)0x19bd, (q15_t)0x829e, (q15_t)0x19a5, (q15_t)0x8299, (q15_t)0x198c, (q15_t)0x8294, (q15_t)0x1973, (q15_t)0x828f, + (q15_t)0x195b, (q15_t)0x828a, (q15_t)0x1942, (q15_t)0x8285, (q15_t)0x192a, (q15_t)0x8280, (q15_t)0x1911, (q15_t)0x827b, + (q15_t)0x18f8, (q15_t)0x8276, (q15_t)0x18e0, (q15_t)0x8271, (q15_t)0x18c7, (q15_t)0x826c, (q15_t)0x18ae, (q15_t)0x8268, + (q15_t)0x1896, (q15_t)0x8263, (q15_t)0x187d, (q15_t)0x825e, (q15_t)0x1864, (q15_t)0x8259, (q15_t)0x184c, (q15_t)0x8254, + (q15_t)0x1833, (q15_t)0x8250, (q15_t)0x181a, (q15_t)0x824b, (q15_t)0x1802, (q15_t)0x8246, (q15_t)0x17e9, (q15_t)0x8241, + (q15_t)0x17d0, (q15_t)0x823d, (q15_t)0x17b7, (q15_t)0x8238, (q15_t)0x179f, (q15_t)0x8233, (q15_t)0x1786, (q15_t)0x822f, + (q15_t)0x176d, (q15_t)0x822a, (q15_t)0x1755, (q15_t)0x8226, (q15_t)0x173c, (q15_t)0x8221, (q15_t)0x1723, (q15_t)0x821c, + (q15_t)0x170a, (q15_t)0x8218, (q15_t)0x16f2, (q15_t)0x8213, (q15_t)0x16d9, (q15_t)0x820f, (q15_t)0x16c0, (q15_t)0x820a, + (q15_t)0x16a8, (q15_t)0x8206, (q15_t)0x168f, (q15_t)0x8201, (q15_t)0x1676, (q15_t)0x81fd, (q15_t)0x165d, (q15_t)0x81f9, + (q15_t)0x1645, (q15_t)0x81f4, (q15_t)0x162c, (q15_t)0x81f0, (q15_t)0x1613, (q15_t)0x81ec, (q15_t)0x15fa, (q15_t)0x81e7, + (q15_t)0x15e2, (q15_t)0x81e3, (q15_t)0x15c9, (q15_t)0x81df, (q15_t)0x15b0, (q15_t)0x81da, (q15_t)0x1597, (q15_t)0x81d6, + (q15_t)0x157f, (q15_t)0x81d2, (q15_t)0x1566, (q15_t)0x81ce, (q15_t)0x154d, (q15_t)0x81c9, (q15_t)0x1534, (q15_t)0x81c5, + (q15_t)0x151b, (q15_t)0x81c1, (q15_t)0x1503, (q15_t)0x81bd, (q15_t)0x14ea, (q15_t)0x81b9, (q15_t)0x14d1, (q15_t)0x81b5, + (q15_t)0x14b8, (q15_t)0x81b1, (q15_t)0x149f, (q15_t)0x81ad, (q15_t)0x1487, (q15_t)0x81a9, (q15_t)0x146e, (q15_t)0x81a5, + (q15_t)0x1455, (q15_t)0x81a1, (q15_t)0x143c, (q15_t)0x819d, (q15_t)0x1423, (q15_t)0x8199, (q15_t)0x140b, (q15_t)0x8195, + (q15_t)0x13f2, (q15_t)0x8191, (q15_t)0x13d9, (q15_t)0x818d, (q15_t)0x13c0, (q15_t)0x8189, (q15_t)0x13a7, (q15_t)0x8185, + (q15_t)0x138e, (q15_t)0x8181, (q15_t)0x1376, (q15_t)0x817d, (q15_t)0x135d, (q15_t)0x817a, (q15_t)0x1344, (q15_t)0x8176, + (q15_t)0x132b, (q15_t)0x8172, (q15_t)0x1312, (q15_t)0x816e, (q15_t)0x12f9, (q15_t)0x816b, (q15_t)0x12e0, (q15_t)0x8167, + (q15_t)0x12c8, (q15_t)0x8163, (q15_t)0x12af, (q15_t)0x815f, (q15_t)0x1296, (q15_t)0x815c, (q15_t)0x127d, (q15_t)0x8158, + (q15_t)0x1264, (q15_t)0x8155, (q15_t)0x124b, (q15_t)0x8151, (q15_t)0x1232, (q15_t)0x814d, (q15_t)0x1219, (q15_t)0x814a, + (q15_t)0x1201, (q15_t)0x8146, (q15_t)0x11e8, (q15_t)0x8143, (q15_t)0x11cf, (q15_t)0x813f, (q15_t)0x11b6, (q15_t)0x813c, + (q15_t)0x119d, (q15_t)0x8138, (q15_t)0x1184, (q15_t)0x8135, (q15_t)0x116b, (q15_t)0x8131, (q15_t)0x1152, (q15_t)0x812e, + (q15_t)0x1139, (q15_t)0x812b, (q15_t)0x1121, (q15_t)0x8127, (q15_t)0x1108, (q15_t)0x8124, (q15_t)0x10ef, (q15_t)0x8121, + (q15_t)0x10d6, (q15_t)0x811d, (q15_t)0x10bd, (q15_t)0x811a, (q15_t)0x10a4, (q15_t)0x8117, (q15_t)0x108b, (q15_t)0x8113, + (q15_t)0x1072, (q15_t)0x8110, (q15_t)0x1059, (q15_t)0x810d, (q15_t)0x1040, (q15_t)0x810a, (q15_t)0x1027, (q15_t)0x8107, + (q15_t)0x100e, (q15_t)0x8103, (q15_t)0xff5, (q15_t)0x8100, (q15_t)0xfdd, (q15_t)0x80fd, (q15_t)0xfc4, (q15_t)0x80fa, + (q15_t)0xfab, (q15_t)0x80f7, (q15_t)0xf92, (q15_t)0x80f4, (q15_t)0xf79, (q15_t)0x80f1, (q15_t)0xf60, (q15_t)0x80ee, + (q15_t)0xf47, (q15_t)0x80eb, (q15_t)0xf2e, (q15_t)0x80e8, (q15_t)0xf15, (q15_t)0x80e5, (q15_t)0xefc, (q15_t)0x80e2, + (q15_t)0xee3, (q15_t)0x80df, (q15_t)0xeca, (q15_t)0x80dc, (q15_t)0xeb1, (q15_t)0x80d9, (q15_t)0xe98, (q15_t)0x80d6, + (q15_t)0xe7f, (q15_t)0x80d3, (q15_t)0xe66, (q15_t)0x80d1, (q15_t)0xe4d, (q15_t)0x80ce, (q15_t)0xe34, (q15_t)0x80cb, + (q15_t)0xe1b, (q15_t)0x80c8, (q15_t)0xe02, (q15_t)0x80c5, (q15_t)0xde9, (q15_t)0x80c3, (q15_t)0xdd0, (q15_t)0x80c0, + (q15_t)0xdb7, (q15_t)0x80bd, (q15_t)0xd9e, (q15_t)0x80bb, (q15_t)0xd85, (q15_t)0x80b8, (q15_t)0xd6c, (q15_t)0x80b5, + (q15_t)0xd53, (q15_t)0x80b3, (q15_t)0xd3a, (q15_t)0x80b0, (q15_t)0xd21, (q15_t)0x80ad, (q15_t)0xd08, (q15_t)0x80ab, + (q15_t)0xcef, (q15_t)0x80a8, (q15_t)0xcd6, (q15_t)0x80a6, (q15_t)0xcbd, (q15_t)0x80a3, (q15_t)0xca4, (q15_t)0x80a1, + (q15_t)0xc8b, (q15_t)0x809e, (q15_t)0xc72, (q15_t)0x809c, (q15_t)0xc59, (q15_t)0x8099, (q15_t)0xc40, (q15_t)0x8097, + (q15_t)0xc27, (q15_t)0x8095, (q15_t)0xc0e, (q15_t)0x8092, (q15_t)0xbf5, (q15_t)0x8090, (q15_t)0xbdc, (q15_t)0x808e, + (q15_t)0xbc3, (q15_t)0x808b, (q15_t)0xbaa, (q15_t)0x8089, (q15_t)0xb91, (q15_t)0x8087, (q15_t)0xb78, (q15_t)0x8084, + (q15_t)0xb5f, (q15_t)0x8082, (q15_t)0xb46, (q15_t)0x8080, (q15_t)0xb2d, (q15_t)0x807e, (q15_t)0xb14, (q15_t)0x807b, + (q15_t)0xafb, (q15_t)0x8079, (q15_t)0xae2, (q15_t)0x8077, (q15_t)0xac9, (q15_t)0x8075, (q15_t)0xab0, (q15_t)0x8073, + (q15_t)0xa97, (q15_t)0x8071, (q15_t)0xa7e, (q15_t)0x806f, (q15_t)0xa65, (q15_t)0x806d, (q15_t)0xa4c, (q15_t)0x806b, + (q15_t)0xa33, (q15_t)0x8069, (q15_t)0xa19, (q15_t)0x8067, (q15_t)0xa00, (q15_t)0x8065, (q15_t)0x9e7, (q15_t)0x8063, + (q15_t)0x9ce, (q15_t)0x8061, (q15_t)0x9b5, (q15_t)0x805f, (q15_t)0x99c, (q15_t)0x805d, (q15_t)0x983, (q15_t)0x805b, + (q15_t)0x96a, (q15_t)0x8059, (q15_t)0x951, (q15_t)0x8057, (q15_t)0x938, (q15_t)0x8056, (q15_t)0x91f, (q15_t)0x8054, + (q15_t)0x906, (q15_t)0x8052, (q15_t)0x8ed, (q15_t)0x8050, (q15_t)0x8d4, (q15_t)0x804f, (q15_t)0x8bb, (q15_t)0x804d, + (q15_t)0x8a2, (q15_t)0x804b, (q15_t)0x888, (q15_t)0x8049, (q15_t)0x86f, (q15_t)0x8048, (q15_t)0x856, (q15_t)0x8046, + (q15_t)0x83d, (q15_t)0x8044, (q15_t)0x824, (q15_t)0x8043, (q15_t)0x80b, (q15_t)0x8041, (q15_t)0x7f2, (q15_t)0x8040, + (q15_t)0x7d9, (q15_t)0x803e, (q15_t)0x7c0, (q15_t)0x803d, (q15_t)0x7a7, (q15_t)0x803b, (q15_t)0x78e, (q15_t)0x803a, + (q15_t)0x775, (q15_t)0x8038, (q15_t)0x75b, (q15_t)0x8037, (q15_t)0x742, (q15_t)0x8035, (q15_t)0x729, (q15_t)0x8034, + (q15_t)0x710, (q15_t)0x8032, (q15_t)0x6f7, (q15_t)0x8031, (q15_t)0x6de, (q15_t)0x8030, (q15_t)0x6c5, (q15_t)0x802e, + (q15_t)0x6ac, (q15_t)0x802d, (q15_t)0x693, (q15_t)0x802c, (q15_t)0x67a, (q15_t)0x802a, (q15_t)0x660, (q15_t)0x8029, + (q15_t)0x647, (q15_t)0x8028, (q15_t)0x62e, (q15_t)0x8027, (q15_t)0x615, (q15_t)0x8026, (q15_t)0x5fc, (q15_t)0x8024, + (q15_t)0x5e3, (q15_t)0x8023, (q15_t)0x5ca, (q15_t)0x8022, (q15_t)0x5b1, (q15_t)0x8021, (q15_t)0x598, (q15_t)0x8020, + (q15_t)0x57f, (q15_t)0x801f, (q15_t)0x565, (q15_t)0x801e, (q15_t)0x54c, (q15_t)0x801d, (q15_t)0x533, (q15_t)0x801c, + (q15_t)0x51a, (q15_t)0x801b, (q15_t)0x501, (q15_t)0x801a, (q15_t)0x4e8, (q15_t)0x8019, (q15_t)0x4cf, (q15_t)0x8018, + (q15_t)0x4b6, (q15_t)0x8017, (q15_t)0x49c, (q15_t)0x8016, (q15_t)0x483, (q15_t)0x8015, (q15_t)0x46a, (q15_t)0x8014, + (q15_t)0x451, (q15_t)0x8013, (q15_t)0x438, (q15_t)0x8012, (q15_t)0x41f, (q15_t)0x8012, (q15_t)0x406, (q15_t)0x8011, + (q15_t)0x3ed, (q15_t)0x8010, (q15_t)0x3d4, (q15_t)0x800f, (q15_t)0x3ba, (q15_t)0x800e, (q15_t)0x3a1, (q15_t)0x800e, + (q15_t)0x388, (q15_t)0x800d, (q15_t)0x36f, (q15_t)0x800c, (q15_t)0x356, (q15_t)0x800c, (q15_t)0x33d, (q15_t)0x800b, + (q15_t)0x324, (q15_t)0x800a, (q15_t)0x30b, (q15_t)0x800a, (q15_t)0x2f1, (q15_t)0x8009, (q15_t)0x2d8, (q15_t)0x8009, + (q15_t)0x2bf, (q15_t)0x8008, (q15_t)0x2a6, (q15_t)0x8008, (q15_t)0x28d, (q15_t)0x8007, (q15_t)0x274, (q15_t)0x8007, + (q15_t)0x25b, (q15_t)0x8006, (q15_t)0x242, (q15_t)0x8006, (q15_t)0x228, (q15_t)0x8005, (q15_t)0x20f, (q15_t)0x8005, + (q15_t)0x1f6, (q15_t)0x8004, (q15_t)0x1dd, (q15_t)0x8004, (q15_t)0x1c4, (q15_t)0x8004, (q15_t)0x1ab, (q15_t)0x8003, + (q15_t)0x192, (q15_t)0x8003, (q15_t)0x178, (q15_t)0x8003, (q15_t)0x15f, (q15_t)0x8002, (q15_t)0x146, (q15_t)0x8002, + (q15_t)0x12d, (q15_t)0x8002, (q15_t)0x114, (q15_t)0x8002, (q15_t)0xfb, (q15_t)0x8001, (q15_t)0xe2, (q15_t)0x8001, + (q15_t)0xc9, (q15_t)0x8001, (q15_t)0xaf, (q15_t)0x8001, (q15_t)0x96, (q15_t)0x8001, (q15_t)0x7d, (q15_t)0x8001, + (q15_t)0x64, (q15_t)0x8001, (q15_t)0x4b, (q15_t)0x8001, (q15_t)0x32, (q15_t)0x8001, (q15_t)0x19, (q15_t)0x8001 +}; + +static const q15_t __ALIGNED(4) WeightsQ15_8192[16384] = { + (q15_t)0x7fff, (q15_t)0x0, (q15_t)0x7fff, (q15_t)0xfffa, (q15_t)0x7fff, (q15_t)0xfff4, (q15_t)0x7fff, (q15_t)0xffee, + (q15_t)0x7fff, (q15_t)0xffe7, (q15_t)0x7fff, (q15_t)0xffe1, (q15_t)0x7fff, (q15_t)0xffdb, (q15_t)0x7fff, (q15_t)0xffd5, + (q15_t)0x7fff, (q15_t)0xffce, (q15_t)0x7fff, (q15_t)0xffc8, (q15_t)0x7fff, (q15_t)0xffc2, (q15_t)0x7fff, (q15_t)0xffbb, + (q15_t)0x7fff, (q15_t)0xffb5, (q15_t)0x7fff, (q15_t)0xffaf, (q15_t)0x7fff, (q15_t)0xffa9, (q15_t)0x7fff, (q15_t)0xffa2, + (q15_t)0x7fff, (q15_t)0xff9c, (q15_t)0x7fff, (q15_t)0xff96, (q15_t)0x7fff, (q15_t)0xff8f, (q15_t)0x7fff, (q15_t)0xff89, + (q15_t)0x7fff, (q15_t)0xff83, (q15_t)0x7fff, (q15_t)0xff7d, (q15_t)0x7fff, (q15_t)0xff76, (q15_t)0x7fff, (q15_t)0xff70, + (q15_t)0x7fff, (q15_t)0xff6a, (q15_t)0x7fff, (q15_t)0xff63, (q15_t)0x7fff, (q15_t)0xff5d, (q15_t)0x7fff, (q15_t)0xff57, + (q15_t)0x7fff, (q15_t)0xff51, (q15_t)0x7fff, (q15_t)0xff4a, (q15_t)0x7fff, (q15_t)0xff44, (q15_t)0x7fff, (q15_t)0xff3e, + (q15_t)0x7fff, (q15_t)0xff37, (q15_t)0x7fff, (q15_t)0xff31, (q15_t)0x7fff, (q15_t)0xff2b, (q15_t)0x7fff, (q15_t)0xff25, + (q15_t)0x7fff, (q15_t)0xff1e, (q15_t)0x7fff, (q15_t)0xff18, (q15_t)0x7fff, (q15_t)0xff12, (q15_t)0x7fff, (q15_t)0xff0b, + (q15_t)0x7fff, (q15_t)0xff05, (q15_t)0x7ffe, (q15_t)0xfeff, (q15_t)0x7ffe, (q15_t)0xfef9, (q15_t)0x7ffe, (q15_t)0xfef2, + (q15_t)0x7ffe, (q15_t)0xfeec, (q15_t)0x7ffe, (q15_t)0xfee6, (q15_t)0x7ffe, (q15_t)0xfedf, (q15_t)0x7ffe, (q15_t)0xfed9, + (q15_t)0x7ffe, (q15_t)0xfed3, (q15_t)0x7ffe, (q15_t)0xfecd, (q15_t)0x7ffe, (q15_t)0xfec6, (q15_t)0x7ffe, (q15_t)0xfec0, + (q15_t)0x7ffe, (q15_t)0xfeba, (q15_t)0x7ffe, (q15_t)0xfeb3, (q15_t)0x7ffe, (q15_t)0xfead, (q15_t)0x7ffe, (q15_t)0xfea7, + (q15_t)0x7ffe, (q15_t)0xfea1, (q15_t)0x7ffe, (q15_t)0xfe9a, (q15_t)0x7ffd, (q15_t)0xfe94, (q15_t)0x7ffd, (q15_t)0xfe8e, + (q15_t)0x7ffd, (q15_t)0xfe88, (q15_t)0x7ffd, (q15_t)0xfe81, (q15_t)0x7ffd, (q15_t)0xfe7b, (q15_t)0x7ffd, (q15_t)0xfe75, + (q15_t)0x7ffd, (q15_t)0xfe6e, (q15_t)0x7ffd, (q15_t)0xfe68, (q15_t)0x7ffd, (q15_t)0xfe62, (q15_t)0x7ffd, (q15_t)0xfe5c, + (q15_t)0x7ffd, (q15_t)0xfe55, (q15_t)0x7ffd, (q15_t)0xfe4f, (q15_t)0x7ffd, (q15_t)0xfe49, (q15_t)0x7ffc, (q15_t)0xfe42, + (q15_t)0x7ffc, (q15_t)0xfe3c, (q15_t)0x7ffc, (q15_t)0xfe36, (q15_t)0x7ffc, (q15_t)0xfe30, (q15_t)0x7ffc, (q15_t)0xfe29, + (q15_t)0x7ffc, (q15_t)0xfe23, (q15_t)0x7ffc, (q15_t)0xfe1d, (q15_t)0x7ffc, (q15_t)0xfe16, (q15_t)0x7ffc, (q15_t)0xfe10, + (q15_t)0x7ffc, (q15_t)0xfe0a, (q15_t)0x7ffc, (q15_t)0xfe04, (q15_t)0x7ffb, (q15_t)0xfdfd, (q15_t)0x7ffb, (q15_t)0xfdf7, + (q15_t)0x7ffb, (q15_t)0xfdf1, (q15_t)0x7ffb, (q15_t)0xfdea, (q15_t)0x7ffb, (q15_t)0xfde4, (q15_t)0x7ffb, (q15_t)0xfdde, + (q15_t)0x7ffb, (q15_t)0xfdd8, (q15_t)0x7ffb, (q15_t)0xfdd1, (q15_t)0x7ffb, (q15_t)0xfdcb, (q15_t)0x7ffb, (q15_t)0xfdc5, + (q15_t)0x7ffa, (q15_t)0xfdbe, (q15_t)0x7ffa, (q15_t)0xfdb8, (q15_t)0x7ffa, (q15_t)0xfdb2, (q15_t)0x7ffa, (q15_t)0xfdac, + (q15_t)0x7ffa, (q15_t)0xfda5, (q15_t)0x7ffa, (q15_t)0xfd9f, (q15_t)0x7ffa, (q15_t)0xfd99, (q15_t)0x7ffa, (q15_t)0xfd93, + (q15_t)0x7ff9, (q15_t)0xfd8c, (q15_t)0x7ff9, (q15_t)0xfd86, (q15_t)0x7ff9, (q15_t)0xfd80, (q15_t)0x7ff9, (q15_t)0xfd79, + (q15_t)0x7ff9, (q15_t)0xfd73, (q15_t)0x7ff9, (q15_t)0xfd6d, (q15_t)0x7ff9, (q15_t)0xfd67, (q15_t)0x7ff9, (q15_t)0xfd60, + (q15_t)0x7ff8, (q15_t)0xfd5a, (q15_t)0x7ff8, (q15_t)0xfd54, (q15_t)0x7ff8, (q15_t)0xfd4d, (q15_t)0x7ff8, (q15_t)0xfd47, + (q15_t)0x7ff8, (q15_t)0xfd41, (q15_t)0x7ff8, (q15_t)0xfd3b, (q15_t)0x7ff8, (q15_t)0xfd34, (q15_t)0x7ff8, (q15_t)0xfd2e, + (q15_t)0x7ff7, (q15_t)0xfd28, (q15_t)0x7ff7, (q15_t)0xfd21, (q15_t)0x7ff7, (q15_t)0xfd1b, (q15_t)0x7ff7, (q15_t)0xfd15, + (q15_t)0x7ff7, (q15_t)0xfd0f, (q15_t)0x7ff7, (q15_t)0xfd08, (q15_t)0x7ff7, (q15_t)0xfd02, (q15_t)0x7ff6, (q15_t)0xfcfc, + (q15_t)0x7ff6, (q15_t)0xfcf5, (q15_t)0x7ff6, (q15_t)0xfcef, (q15_t)0x7ff6, (q15_t)0xfce9, (q15_t)0x7ff6, (q15_t)0xfce3, + (q15_t)0x7ff6, (q15_t)0xfcdc, (q15_t)0x7ff5, (q15_t)0xfcd6, (q15_t)0x7ff5, (q15_t)0xfcd0, (q15_t)0x7ff5, (q15_t)0xfcc9, + (q15_t)0x7ff5, (q15_t)0xfcc3, (q15_t)0x7ff5, (q15_t)0xfcbd, (q15_t)0x7ff5, (q15_t)0xfcb7, (q15_t)0x7ff5, (q15_t)0xfcb0, + (q15_t)0x7ff4, (q15_t)0xfcaa, (q15_t)0x7ff4, (q15_t)0xfca4, (q15_t)0x7ff4, (q15_t)0xfc9e, (q15_t)0x7ff4, (q15_t)0xfc97, + (q15_t)0x7ff4, (q15_t)0xfc91, (q15_t)0x7ff4, (q15_t)0xfc8b, (q15_t)0x7ff3, (q15_t)0xfc84, (q15_t)0x7ff3, (q15_t)0xfc7e, + (q15_t)0x7ff3, (q15_t)0xfc78, (q15_t)0x7ff3, (q15_t)0xfc72, (q15_t)0x7ff3, (q15_t)0xfc6b, (q15_t)0x7ff2, (q15_t)0xfc65, + (q15_t)0x7ff2, (q15_t)0xfc5f, (q15_t)0x7ff2, (q15_t)0xfc58, (q15_t)0x7ff2, (q15_t)0xfc52, (q15_t)0x7ff2, (q15_t)0xfc4c, + (q15_t)0x7ff2, (q15_t)0xfc46, (q15_t)0x7ff1, (q15_t)0xfc3f, (q15_t)0x7ff1, (q15_t)0xfc39, (q15_t)0x7ff1, (q15_t)0xfc33, + (q15_t)0x7ff1, (q15_t)0xfc2c, (q15_t)0x7ff1, (q15_t)0xfc26, (q15_t)0x7ff0, (q15_t)0xfc20, (q15_t)0x7ff0, (q15_t)0xfc1a, + (q15_t)0x7ff0, (q15_t)0xfc13, (q15_t)0x7ff0, (q15_t)0xfc0d, (q15_t)0x7ff0, (q15_t)0xfc07, (q15_t)0x7fef, (q15_t)0xfc01, + (q15_t)0x7fef, (q15_t)0xfbfa, (q15_t)0x7fef, (q15_t)0xfbf4, (q15_t)0x7fef, (q15_t)0xfbee, (q15_t)0x7fef, (q15_t)0xfbe7, + (q15_t)0x7fee, (q15_t)0xfbe1, (q15_t)0x7fee, (q15_t)0xfbdb, (q15_t)0x7fee, (q15_t)0xfbd5, (q15_t)0x7fee, (q15_t)0xfbce, + (q15_t)0x7fee, (q15_t)0xfbc8, (q15_t)0x7fed, (q15_t)0xfbc2, (q15_t)0x7fed, (q15_t)0xfbbb, (q15_t)0x7fed, (q15_t)0xfbb5, + (q15_t)0x7fed, (q15_t)0xfbaf, (q15_t)0x7fed, (q15_t)0xfba9, (q15_t)0x7fec, (q15_t)0xfba2, (q15_t)0x7fec, (q15_t)0xfb9c, + (q15_t)0x7fec, (q15_t)0xfb96, (q15_t)0x7fec, (q15_t)0xfb8f, (q15_t)0x7fec, (q15_t)0xfb89, (q15_t)0x7feb, (q15_t)0xfb83, + (q15_t)0x7feb, (q15_t)0xfb7d, (q15_t)0x7feb, (q15_t)0xfb76, (q15_t)0x7feb, (q15_t)0xfb70, (q15_t)0x7fea, (q15_t)0xfb6a, + (q15_t)0x7fea, (q15_t)0xfb64, (q15_t)0x7fea, (q15_t)0xfb5d, (q15_t)0x7fea, (q15_t)0xfb57, (q15_t)0x7fea, (q15_t)0xfb51, + (q15_t)0x7fe9, (q15_t)0xfb4a, (q15_t)0x7fe9, (q15_t)0xfb44, (q15_t)0x7fe9, (q15_t)0xfb3e, (q15_t)0x7fe9, (q15_t)0xfb38, + (q15_t)0x7fe8, (q15_t)0xfb31, (q15_t)0x7fe8, (q15_t)0xfb2b, (q15_t)0x7fe8, (q15_t)0xfb25, (q15_t)0x7fe8, (q15_t)0xfb1e, + (q15_t)0x7fe7, (q15_t)0xfb18, (q15_t)0x7fe7, (q15_t)0xfb12, (q15_t)0x7fe7, (q15_t)0xfb0c, (q15_t)0x7fe7, (q15_t)0xfb05, + (q15_t)0x7fe6, (q15_t)0xfaff, (q15_t)0x7fe6, (q15_t)0xfaf9, (q15_t)0x7fe6, (q15_t)0xfaf3, (q15_t)0x7fe6, (q15_t)0xfaec, + (q15_t)0x7fe5, (q15_t)0xfae6, (q15_t)0x7fe5, (q15_t)0xfae0, (q15_t)0x7fe5, (q15_t)0xfad9, (q15_t)0x7fe5, (q15_t)0xfad3, + (q15_t)0x7fe4, (q15_t)0xfacd, (q15_t)0x7fe4, (q15_t)0xfac7, (q15_t)0x7fe4, (q15_t)0xfac0, (q15_t)0x7fe4, (q15_t)0xfaba, + (q15_t)0x7fe3, (q15_t)0xfab4, (q15_t)0x7fe3, (q15_t)0xfaad, (q15_t)0x7fe3, (q15_t)0xfaa7, (q15_t)0x7fe3, (q15_t)0xfaa1, + (q15_t)0x7fe2, (q15_t)0xfa9b, (q15_t)0x7fe2, (q15_t)0xfa94, (q15_t)0x7fe2, (q15_t)0xfa8e, (q15_t)0x7fe2, (q15_t)0xfa88, + (q15_t)0x7fe1, (q15_t)0xfa81, (q15_t)0x7fe1, (q15_t)0xfa7b, (q15_t)0x7fe1, (q15_t)0xfa75, (q15_t)0x7fe0, (q15_t)0xfa6f, + (q15_t)0x7fe0, (q15_t)0xfa68, (q15_t)0x7fe0, (q15_t)0xfa62, (q15_t)0x7fe0, (q15_t)0xfa5c, (q15_t)0x7fdf, (q15_t)0xfa56, + (q15_t)0x7fdf, (q15_t)0xfa4f, (q15_t)0x7fdf, (q15_t)0xfa49, (q15_t)0x7fdf, (q15_t)0xfa43, (q15_t)0x7fde, (q15_t)0xfa3c, + (q15_t)0x7fde, (q15_t)0xfa36, (q15_t)0x7fde, (q15_t)0xfa30, (q15_t)0x7fdd, (q15_t)0xfa2a, (q15_t)0x7fdd, (q15_t)0xfa23, + (q15_t)0x7fdd, (q15_t)0xfa1d, (q15_t)0x7fdd, (q15_t)0xfa17, (q15_t)0x7fdc, (q15_t)0xfa11, (q15_t)0x7fdc, (q15_t)0xfa0a, + (q15_t)0x7fdc, (q15_t)0xfa04, (q15_t)0x7fdb, (q15_t)0xf9fe, (q15_t)0x7fdb, (q15_t)0xf9f7, (q15_t)0x7fdb, (q15_t)0xf9f1, + (q15_t)0x7fda, (q15_t)0xf9eb, (q15_t)0x7fda, (q15_t)0xf9e5, (q15_t)0x7fda, (q15_t)0xf9de, (q15_t)0x7fda, (q15_t)0xf9d8, + (q15_t)0x7fd9, (q15_t)0xf9d2, (q15_t)0x7fd9, (q15_t)0xf9cb, (q15_t)0x7fd9, (q15_t)0xf9c5, (q15_t)0x7fd8, (q15_t)0xf9bf, + (q15_t)0x7fd8, (q15_t)0xf9b9, (q15_t)0x7fd8, (q15_t)0xf9b2, (q15_t)0x7fd7, (q15_t)0xf9ac, (q15_t)0x7fd7, (q15_t)0xf9a6, + (q15_t)0x7fd7, (q15_t)0xf9a0, (q15_t)0x7fd6, (q15_t)0xf999, (q15_t)0x7fd6, (q15_t)0xf993, (q15_t)0x7fd6, (q15_t)0xf98d, + (q15_t)0x7fd6, (q15_t)0xf986, (q15_t)0x7fd5, (q15_t)0xf980, (q15_t)0x7fd5, (q15_t)0xf97a, (q15_t)0x7fd5, (q15_t)0xf974, + (q15_t)0x7fd4, (q15_t)0xf96d, (q15_t)0x7fd4, (q15_t)0xf967, (q15_t)0x7fd4, (q15_t)0xf961, (q15_t)0x7fd3, (q15_t)0xf95b, + (q15_t)0x7fd3, (q15_t)0xf954, (q15_t)0x7fd3, (q15_t)0xf94e, (q15_t)0x7fd2, (q15_t)0xf948, (q15_t)0x7fd2, (q15_t)0xf941, + (q15_t)0x7fd2, (q15_t)0xf93b, (q15_t)0x7fd1, (q15_t)0xf935, (q15_t)0x7fd1, (q15_t)0xf92f, (q15_t)0x7fd1, (q15_t)0xf928, + (q15_t)0x7fd0, (q15_t)0xf922, (q15_t)0x7fd0, (q15_t)0xf91c, (q15_t)0x7fd0, (q15_t)0xf916, (q15_t)0x7fcf, (q15_t)0xf90f, + (q15_t)0x7fcf, (q15_t)0xf909, (q15_t)0x7fcf, (q15_t)0xf903, (q15_t)0x7fce, (q15_t)0xf8fc, (q15_t)0x7fce, (q15_t)0xf8f6, + (q15_t)0x7fce, (q15_t)0xf8f0, (q15_t)0x7fcd, (q15_t)0xf8ea, (q15_t)0x7fcd, (q15_t)0xf8e3, (q15_t)0x7fcd, (q15_t)0xf8dd, + (q15_t)0x7fcc, (q15_t)0xf8d7, (q15_t)0x7fcc, (q15_t)0xf8d0, (q15_t)0x7fcb, (q15_t)0xf8ca, (q15_t)0x7fcb, (q15_t)0xf8c4, + (q15_t)0x7fcb, (q15_t)0xf8be, (q15_t)0x7fca, (q15_t)0xf8b7, (q15_t)0x7fca, (q15_t)0xf8b1, (q15_t)0x7fca, (q15_t)0xf8ab, + (q15_t)0x7fc9, (q15_t)0xf8a5, (q15_t)0x7fc9, (q15_t)0xf89e, (q15_t)0x7fc9, (q15_t)0xf898, (q15_t)0x7fc8, (q15_t)0xf892, + (q15_t)0x7fc8, (q15_t)0xf88b, (q15_t)0x7fc7, (q15_t)0xf885, (q15_t)0x7fc7, (q15_t)0xf87f, (q15_t)0x7fc7, (q15_t)0xf879, + (q15_t)0x7fc6, (q15_t)0xf872, (q15_t)0x7fc6, (q15_t)0xf86c, (q15_t)0x7fc6, (q15_t)0xf866, (q15_t)0x7fc5, (q15_t)0xf860, + (q15_t)0x7fc5, (q15_t)0xf859, (q15_t)0x7fc5, (q15_t)0xf853, (q15_t)0x7fc4, (q15_t)0xf84d, (q15_t)0x7fc4, (q15_t)0xf846, + (q15_t)0x7fc3, (q15_t)0xf840, (q15_t)0x7fc3, (q15_t)0xf83a, (q15_t)0x7fc3, (q15_t)0xf834, (q15_t)0x7fc2, (q15_t)0xf82d, + (q15_t)0x7fc2, (q15_t)0xf827, (q15_t)0x7fc1, (q15_t)0xf821, (q15_t)0x7fc1, (q15_t)0xf81b, (q15_t)0x7fc1, (q15_t)0xf814, + (q15_t)0x7fc0, (q15_t)0xf80e, (q15_t)0x7fc0, (q15_t)0xf808, (q15_t)0x7fc0, (q15_t)0xf802, (q15_t)0x7fbf, (q15_t)0xf7fb, + (q15_t)0x7fbf, (q15_t)0xf7f5, (q15_t)0x7fbe, (q15_t)0xf7ef, (q15_t)0x7fbe, (q15_t)0xf7e8, (q15_t)0x7fbe, (q15_t)0xf7e2, + (q15_t)0x7fbd, (q15_t)0xf7dc, (q15_t)0x7fbd, (q15_t)0xf7d6, (q15_t)0x7fbc, (q15_t)0xf7cf, (q15_t)0x7fbc, (q15_t)0xf7c9, + (q15_t)0x7fbc, (q15_t)0xf7c3, (q15_t)0x7fbb, (q15_t)0xf7bd, (q15_t)0x7fbb, (q15_t)0xf7b6, (q15_t)0x7fba, (q15_t)0xf7b0, + (q15_t)0x7fba, (q15_t)0xf7aa, (q15_t)0x7fb9, (q15_t)0xf7a3, (q15_t)0x7fb9, (q15_t)0xf79d, (q15_t)0x7fb9, (q15_t)0xf797, + (q15_t)0x7fb8, (q15_t)0xf791, (q15_t)0x7fb8, (q15_t)0xf78a, (q15_t)0x7fb7, (q15_t)0xf784, (q15_t)0x7fb7, (q15_t)0xf77e, + (q15_t)0x7fb7, (q15_t)0xf778, (q15_t)0x7fb6, (q15_t)0xf771, (q15_t)0x7fb6, (q15_t)0xf76b, (q15_t)0x7fb5, (q15_t)0xf765, + (q15_t)0x7fb5, (q15_t)0xf75e, (q15_t)0x7fb4, (q15_t)0xf758, (q15_t)0x7fb4, (q15_t)0xf752, (q15_t)0x7fb4, (q15_t)0xf74c, + (q15_t)0x7fb3, (q15_t)0xf745, (q15_t)0x7fb3, (q15_t)0xf73f, (q15_t)0x7fb2, (q15_t)0xf739, (q15_t)0x7fb2, (q15_t)0xf733, + (q15_t)0x7fb1, (q15_t)0xf72c, (q15_t)0x7fb1, (q15_t)0xf726, (q15_t)0x7fb1, (q15_t)0xf720, (q15_t)0x7fb0, (q15_t)0xf71a, + (q15_t)0x7fb0, (q15_t)0xf713, (q15_t)0x7faf, (q15_t)0xf70d, (q15_t)0x7faf, (q15_t)0xf707, (q15_t)0x7fae, (q15_t)0xf700, + (q15_t)0x7fae, (q15_t)0xf6fa, (q15_t)0x7fae, (q15_t)0xf6f4, (q15_t)0x7fad, (q15_t)0xf6ee, (q15_t)0x7fad, (q15_t)0xf6e7, + (q15_t)0x7fac, (q15_t)0xf6e1, (q15_t)0x7fac, (q15_t)0xf6db, (q15_t)0x7fab, (q15_t)0xf6d5, (q15_t)0x7fab, (q15_t)0xf6ce, + (q15_t)0x7faa, (q15_t)0xf6c8, (q15_t)0x7faa, (q15_t)0xf6c2, (q15_t)0x7fa9, (q15_t)0xf6bc, (q15_t)0x7fa9, (q15_t)0xf6b5, + (q15_t)0x7fa9, (q15_t)0xf6af, (q15_t)0x7fa8, (q15_t)0xf6a9, (q15_t)0x7fa8, (q15_t)0xf6a2, (q15_t)0x7fa7, (q15_t)0xf69c, + (q15_t)0x7fa7, (q15_t)0xf696, (q15_t)0x7fa6, (q15_t)0xf690, (q15_t)0x7fa6, (q15_t)0xf689, (q15_t)0x7fa5, (q15_t)0xf683, + (q15_t)0x7fa5, (q15_t)0xf67d, (q15_t)0x7fa4, (q15_t)0xf677, (q15_t)0x7fa4, (q15_t)0xf670, (q15_t)0x7fa3, (q15_t)0xf66a, + (q15_t)0x7fa3, (q15_t)0xf664, (q15_t)0x7fa3, (q15_t)0xf65e, (q15_t)0x7fa2, (q15_t)0xf657, (q15_t)0x7fa2, (q15_t)0xf651, + (q15_t)0x7fa1, (q15_t)0xf64b, (q15_t)0x7fa1, (q15_t)0xf644, (q15_t)0x7fa0, (q15_t)0xf63e, (q15_t)0x7fa0, (q15_t)0xf638, + (q15_t)0x7f9f, (q15_t)0xf632, (q15_t)0x7f9f, (q15_t)0xf62b, (q15_t)0x7f9e, (q15_t)0xf625, (q15_t)0x7f9e, (q15_t)0xf61f, + (q15_t)0x7f9d, (q15_t)0xf619, (q15_t)0x7f9d, (q15_t)0xf612, (q15_t)0x7f9c, (q15_t)0xf60c, (q15_t)0x7f9c, (q15_t)0xf606, + (q15_t)0x7f9b, (q15_t)0xf600, (q15_t)0x7f9b, (q15_t)0xf5f9, (q15_t)0x7f9a, (q15_t)0xf5f3, (q15_t)0x7f9a, (q15_t)0xf5ed, + (q15_t)0x7f99, (q15_t)0xf5e7, (q15_t)0x7f99, (q15_t)0xf5e0, (q15_t)0x7f98, (q15_t)0xf5da, (q15_t)0x7f98, (q15_t)0xf5d4, + (q15_t)0x7f97, (q15_t)0xf5cd, (q15_t)0x7f97, (q15_t)0xf5c7, (q15_t)0x7f96, (q15_t)0xf5c1, (q15_t)0x7f96, (q15_t)0xf5bb, + (q15_t)0x7f95, (q15_t)0xf5b4, (q15_t)0x7f95, (q15_t)0xf5ae, (q15_t)0x7f94, (q15_t)0xf5a8, (q15_t)0x7f94, (q15_t)0xf5a2, + (q15_t)0x7f93, (q15_t)0xf59b, (q15_t)0x7f93, (q15_t)0xf595, (q15_t)0x7f92, (q15_t)0xf58f, (q15_t)0x7f92, (q15_t)0xf589, + (q15_t)0x7f91, (q15_t)0xf582, (q15_t)0x7f91, (q15_t)0xf57c, (q15_t)0x7f90, (q15_t)0xf576, (q15_t)0x7f90, (q15_t)0xf570, + (q15_t)0x7f8f, (q15_t)0xf569, (q15_t)0x7f8f, (q15_t)0xf563, (q15_t)0x7f8e, (q15_t)0xf55d, (q15_t)0x7f8e, (q15_t)0xf556, + (q15_t)0x7f8d, (q15_t)0xf550, (q15_t)0x7f8d, (q15_t)0xf54a, (q15_t)0x7f8c, (q15_t)0xf544, (q15_t)0x7f8b, (q15_t)0xf53d, + (q15_t)0x7f8b, (q15_t)0xf537, (q15_t)0x7f8a, (q15_t)0xf531, (q15_t)0x7f8a, (q15_t)0xf52b, (q15_t)0x7f89, (q15_t)0xf524, + (q15_t)0x7f89, (q15_t)0xf51e, (q15_t)0x7f88, (q15_t)0xf518, (q15_t)0x7f88, (q15_t)0xf512, (q15_t)0x7f87, (q15_t)0xf50b, + (q15_t)0x7f87, (q15_t)0xf505, (q15_t)0x7f86, (q15_t)0xf4ff, (q15_t)0x7f86, (q15_t)0xf4f9, (q15_t)0x7f85, (q15_t)0xf4f2, + (q15_t)0x7f85, (q15_t)0xf4ec, (q15_t)0x7f84, (q15_t)0xf4e6, (q15_t)0x7f83, (q15_t)0xf4e0, (q15_t)0x7f83, (q15_t)0xf4d9, + (q15_t)0x7f82, (q15_t)0xf4d3, (q15_t)0x7f82, (q15_t)0xf4cd, (q15_t)0x7f81, (q15_t)0xf4c6, (q15_t)0x7f81, (q15_t)0xf4c0, + (q15_t)0x7f80, (q15_t)0xf4ba, (q15_t)0x7f80, (q15_t)0xf4b4, (q15_t)0x7f7f, (q15_t)0xf4ad, (q15_t)0x7f7e, (q15_t)0xf4a7, + (q15_t)0x7f7e, (q15_t)0xf4a1, (q15_t)0x7f7d, (q15_t)0xf49b, (q15_t)0x7f7d, (q15_t)0xf494, (q15_t)0x7f7c, (q15_t)0xf48e, + (q15_t)0x7f7c, (q15_t)0xf488, (q15_t)0x7f7b, (q15_t)0xf482, (q15_t)0x7f7b, (q15_t)0xf47b, (q15_t)0x7f7a, (q15_t)0xf475, + (q15_t)0x7f79, (q15_t)0xf46f, (q15_t)0x7f79, (q15_t)0xf469, (q15_t)0x7f78, (q15_t)0xf462, (q15_t)0x7f78, (q15_t)0xf45c, + (q15_t)0x7f77, (q15_t)0xf456, (q15_t)0x7f77, (q15_t)0xf450, (q15_t)0x7f76, (q15_t)0xf449, (q15_t)0x7f75, (q15_t)0xf443, + (q15_t)0x7f75, (q15_t)0xf43d, (q15_t)0x7f74, (q15_t)0xf437, (q15_t)0x7f74, (q15_t)0xf430, (q15_t)0x7f73, (q15_t)0xf42a, + (q15_t)0x7f72, (q15_t)0xf424, (q15_t)0x7f72, (q15_t)0xf41e, (q15_t)0x7f71, (q15_t)0xf417, (q15_t)0x7f71, (q15_t)0xf411, + (q15_t)0x7f70, (q15_t)0xf40b, (q15_t)0x7f70, (q15_t)0xf405, (q15_t)0x7f6f, (q15_t)0xf3fe, (q15_t)0x7f6e, (q15_t)0xf3f8, + (q15_t)0x7f6e, (q15_t)0xf3f2, (q15_t)0x7f6d, (q15_t)0xf3ec, (q15_t)0x7f6d, (q15_t)0xf3e5, (q15_t)0x7f6c, (q15_t)0xf3df, + (q15_t)0x7f6b, (q15_t)0xf3d9, (q15_t)0x7f6b, (q15_t)0xf3d2, (q15_t)0x7f6a, (q15_t)0xf3cc, (q15_t)0x7f6a, (q15_t)0xf3c6, + (q15_t)0x7f69, (q15_t)0xf3c0, (q15_t)0x7f68, (q15_t)0xf3b9, (q15_t)0x7f68, (q15_t)0xf3b3, (q15_t)0x7f67, (q15_t)0xf3ad, + (q15_t)0x7f67, (q15_t)0xf3a7, (q15_t)0x7f66, (q15_t)0xf3a0, (q15_t)0x7f65, (q15_t)0xf39a, (q15_t)0x7f65, (q15_t)0xf394, + (q15_t)0x7f64, (q15_t)0xf38e, (q15_t)0x7f64, (q15_t)0xf387, (q15_t)0x7f63, (q15_t)0xf381, (q15_t)0x7f62, (q15_t)0xf37b, + (q15_t)0x7f62, (q15_t)0xf375, (q15_t)0x7f61, (q15_t)0xf36e, (q15_t)0x7f60, (q15_t)0xf368, (q15_t)0x7f60, (q15_t)0xf362, + (q15_t)0x7f5f, (q15_t)0xf35c, (q15_t)0x7f5f, (q15_t)0xf355, (q15_t)0x7f5e, (q15_t)0xf34f, (q15_t)0x7f5d, (q15_t)0xf349, + (q15_t)0x7f5d, (q15_t)0xf343, (q15_t)0x7f5c, (q15_t)0xf33c, (q15_t)0x7f5b, (q15_t)0xf336, (q15_t)0x7f5b, (q15_t)0xf330, + (q15_t)0x7f5a, (q15_t)0xf32a, (q15_t)0x7f5a, (q15_t)0xf323, (q15_t)0x7f59, (q15_t)0xf31d, (q15_t)0x7f58, (q15_t)0xf317, + (q15_t)0x7f58, (q15_t)0xf311, (q15_t)0x7f57, (q15_t)0xf30a, (q15_t)0x7f56, (q15_t)0xf304, (q15_t)0x7f56, (q15_t)0xf2fe, + (q15_t)0x7f55, (q15_t)0xf2f8, (q15_t)0x7f55, (q15_t)0xf2f1, (q15_t)0x7f54, (q15_t)0xf2eb, (q15_t)0x7f53, (q15_t)0xf2e5, + (q15_t)0x7f53, (q15_t)0xf2df, (q15_t)0x7f52, (q15_t)0xf2d8, (q15_t)0x7f51, (q15_t)0xf2d2, (q15_t)0x7f51, (q15_t)0xf2cc, + (q15_t)0x7f50, (q15_t)0xf2c6, (q15_t)0x7f4f, (q15_t)0xf2bf, (q15_t)0x7f4f, (q15_t)0xf2b9, (q15_t)0x7f4e, (q15_t)0xf2b3, + (q15_t)0x7f4d, (q15_t)0xf2ad, (q15_t)0x7f4d, (q15_t)0xf2a6, (q15_t)0x7f4c, (q15_t)0xf2a0, (q15_t)0x7f4b, (q15_t)0xf29a, + (q15_t)0x7f4b, (q15_t)0xf294, (q15_t)0x7f4a, (q15_t)0xf28d, (q15_t)0x7f49, (q15_t)0xf287, (q15_t)0x7f49, (q15_t)0xf281, + (q15_t)0x7f48, (q15_t)0xf27b, (q15_t)0x7f47, (q15_t)0xf274, (q15_t)0x7f47, (q15_t)0xf26e, (q15_t)0x7f46, (q15_t)0xf268, + (q15_t)0x7f45, (q15_t)0xf262, (q15_t)0x7f45, (q15_t)0xf25b, (q15_t)0x7f44, (q15_t)0xf255, (q15_t)0x7f43, (q15_t)0xf24f, + (q15_t)0x7f43, (q15_t)0xf249, (q15_t)0x7f42, (q15_t)0xf242, (q15_t)0x7f41, (q15_t)0xf23c, (q15_t)0x7f41, (q15_t)0xf236, + (q15_t)0x7f40, (q15_t)0xf230, (q15_t)0x7f3f, (q15_t)0xf229, (q15_t)0x7f3f, (q15_t)0xf223, (q15_t)0x7f3e, (q15_t)0xf21d, + (q15_t)0x7f3d, (q15_t)0xf217, (q15_t)0x7f3d, (q15_t)0xf210, (q15_t)0x7f3c, (q15_t)0xf20a, (q15_t)0x7f3b, (q15_t)0xf204, + (q15_t)0x7f3b, (q15_t)0xf1fe, (q15_t)0x7f3a, (q15_t)0xf1f7, (q15_t)0x7f39, (q15_t)0xf1f1, (q15_t)0x7f39, (q15_t)0xf1eb, + (q15_t)0x7f38, (q15_t)0xf1e5, (q15_t)0x7f37, (q15_t)0xf1de, (q15_t)0x7f36, (q15_t)0xf1d8, (q15_t)0x7f36, (q15_t)0xf1d2, + (q15_t)0x7f35, (q15_t)0xf1cc, (q15_t)0x7f34, (q15_t)0xf1c6, (q15_t)0x7f34, (q15_t)0xf1bf, (q15_t)0x7f33, (q15_t)0xf1b9, + (q15_t)0x7f32, (q15_t)0xf1b3, (q15_t)0x7f32, (q15_t)0xf1ad, (q15_t)0x7f31, (q15_t)0xf1a6, (q15_t)0x7f30, (q15_t)0xf1a0, + (q15_t)0x7f2f, (q15_t)0xf19a, (q15_t)0x7f2f, (q15_t)0xf194, (q15_t)0x7f2e, (q15_t)0xf18d, (q15_t)0x7f2d, (q15_t)0xf187, + (q15_t)0x7f2d, (q15_t)0xf181, (q15_t)0x7f2c, (q15_t)0xf17b, (q15_t)0x7f2b, (q15_t)0xf174, (q15_t)0x7f2a, (q15_t)0xf16e, + (q15_t)0x7f2a, (q15_t)0xf168, (q15_t)0x7f29, (q15_t)0xf162, (q15_t)0x7f28, (q15_t)0xf15b, (q15_t)0x7f28, (q15_t)0xf155, + (q15_t)0x7f27, (q15_t)0xf14f, (q15_t)0x7f26, (q15_t)0xf149, (q15_t)0x7f25, (q15_t)0xf142, (q15_t)0x7f25, (q15_t)0xf13c, + (q15_t)0x7f24, (q15_t)0xf136, (q15_t)0x7f23, (q15_t)0xf130, (q15_t)0x7f23, (q15_t)0xf129, (q15_t)0x7f22, (q15_t)0xf123, + (q15_t)0x7f21, (q15_t)0xf11d, (q15_t)0x7f20, (q15_t)0xf117, (q15_t)0x7f20, (q15_t)0xf110, (q15_t)0x7f1f, (q15_t)0xf10a, + (q15_t)0x7f1e, (q15_t)0xf104, (q15_t)0x7f1d, (q15_t)0xf0fe, (q15_t)0x7f1d, (q15_t)0xf0f8, (q15_t)0x7f1c, (q15_t)0xf0f1, + (q15_t)0x7f1b, (q15_t)0xf0eb, (q15_t)0x7f1a, (q15_t)0xf0e5, (q15_t)0x7f1a, (q15_t)0xf0df, (q15_t)0x7f19, (q15_t)0xf0d8, + (q15_t)0x7f18, (q15_t)0xf0d2, (q15_t)0x7f17, (q15_t)0xf0cc, (q15_t)0x7f17, (q15_t)0xf0c6, (q15_t)0x7f16, (q15_t)0xf0bf, + (q15_t)0x7f15, (q15_t)0xf0b9, (q15_t)0x7f14, (q15_t)0xf0b3, (q15_t)0x7f14, (q15_t)0xf0ad, (q15_t)0x7f13, (q15_t)0xf0a6, + (q15_t)0x7f12, (q15_t)0xf0a0, (q15_t)0x7f11, (q15_t)0xf09a, (q15_t)0x7f11, (q15_t)0xf094, (q15_t)0x7f10, (q15_t)0xf08d, + (q15_t)0x7f0f, (q15_t)0xf087, (q15_t)0x7f0e, (q15_t)0xf081, (q15_t)0x7f0e, (q15_t)0xf07b, (q15_t)0x7f0d, (q15_t)0xf075, + (q15_t)0x7f0c, (q15_t)0xf06e, (q15_t)0x7f0b, (q15_t)0xf068, (q15_t)0x7f0b, (q15_t)0xf062, (q15_t)0x7f0a, (q15_t)0xf05c, + (q15_t)0x7f09, (q15_t)0xf055, (q15_t)0x7f08, (q15_t)0xf04f, (q15_t)0x7f08, (q15_t)0xf049, (q15_t)0x7f07, (q15_t)0xf043, + (q15_t)0x7f06, (q15_t)0xf03c, (q15_t)0x7f05, (q15_t)0xf036, (q15_t)0x7f04, (q15_t)0xf030, (q15_t)0x7f04, (q15_t)0xf02a, + (q15_t)0x7f03, (q15_t)0xf023, (q15_t)0x7f02, (q15_t)0xf01d, (q15_t)0x7f01, (q15_t)0xf017, (q15_t)0x7f01, (q15_t)0xf011, + (q15_t)0x7f00, (q15_t)0xf00b, (q15_t)0x7eff, (q15_t)0xf004, (q15_t)0x7efe, (q15_t)0xeffe, (q15_t)0x7efd, (q15_t)0xeff8, + (q15_t)0x7efd, (q15_t)0xeff2, (q15_t)0x7efc, (q15_t)0xefeb, (q15_t)0x7efb, (q15_t)0xefe5, (q15_t)0x7efa, (q15_t)0xefdf, + (q15_t)0x7ef9, (q15_t)0xefd9, (q15_t)0x7ef9, (q15_t)0xefd2, (q15_t)0x7ef8, (q15_t)0xefcc, (q15_t)0x7ef7, (q15_t)0xefc6, + (q15_t)0x7ef6, (q15_t)0xefc0, (q15_t)0x7ef5, (q15_t)0xefb9, (q15_t)0x7ef5, (q15_t)0xefb3, (q15_t)0x7ef4, (q15_t)0xefad, + (q15_t)0x7ef3, (q15_t)0xefa7, (q15_t)0x7ef2, (q15_t)0xefa1, (q15_t)0x7ef1, (q15_t)0xef9a, (q15_t)0x7ef1, (q15_t)0xef94, + (q15_t)0x7ef0, (q15_t)0xef8e, (q15_t)0x7eef, (q15_t)0xef88, (q15_t)0x7eee, (q15_t)0xef81, (q15_t)0x7eed, (q15_t)0xef7b, + (q15_t)0x7eed, (q15_t)0xef75, (q15_t)0x7eec, (q15_t)0xef6f, (q15_t)0x7eeb, (q15_t)0xef68, (q15_t)0x7eea, (q15_t)0xef62, + (q15_t)0x7ee9, (q15_t)0xef5c, (q15_t)0x7ee9, (q15_t)0xef56, (q15_t)0x7ee8, (q15_t)0xef50, (q15_t)0x7ee7, (q15_t)0xef49, + (q15_t)0x7ee6, (q15_t)0xef43, (q15_t)0x7ee5, (q15_t)0xef3d, (q15_t)0x7ee4, (q15_t)0xef37, (q15_t)0x7ee4, (q15_t)0xef30, + (q15_t)0x7ee3, (q15_t)0xef2a, (q15_t)0x7ee2, (q15_t)0xef24, (q15_t)0x7ee1, (q15_t)0xef1e, (q15_t)0x7ee0, (q15_t)0xef18, + (q15_t)0x7edf, (q15_t)0xef11, (q15_t)0x7edf, (q15_t)0xef0b, (q15_t)0x7ede, (q15_t)0xef05, (q15_t)0x7edd, (q15_t)0xeeff, + (q15_t)0x7edc, (q15_t)0xeef8, (q15_t)0x7edb, (q15_t)0xeef2, (q15_t)0x7eda, (q15_t)0xeeec, (q15_t)0x7eda, (q15_t)0xeee6, + (q15_t)0x7ed9, (q15_t)0xeedf, (q15_t)0x7ed8, (q15_t)0xeed9, (q15_t)0x7ed7, (q15_t)0xeed3, (q15_t)0x7ed6, (q15_t)0xeecd, + (q15_t)0x7ed5, (q15_t)0xeec7, (q15_t)0x7ed5, (q15_t)0xeec0, (q15_t)0x7ed4, (q15_t)0xeeba, (q15_t)0x7ed3, (q15_t)0xeeb4, + (q15_t)0x7ed2, (q15_t)0xeeae, (q15_t)0x7ed1, (q15_t)0xeea7, (q15_t)0x7ed0, (q15_t)0xeea1, (q15_t)0x7ecf, (q15_t)0xee9b, + (q15_t)0x7ecf, (q15_t)0xee95, (q15_t)0x7ece, (q15_t)0xee8f, (q15_t)0x7ecd, (q15_t)0xee88, (q15_t)0x7ecc, (q15_t)0xee82, + (q15_t)0x7ecb, (q15_t)0xee7c, (q15_t)0x7eca, (q15_t)0xee76, (q15_t)0x7ec9, (q15_t)0xee6f, (q15_t)0x7ec9, (q15_t)0xee69, + (q15_t)0x7ec8, (q15_t)0xee63, (q15_t)0x7ec7, (q15_t)0xee5d, (q15_t)0x7ec6, (q15_t)0xee57, (q15_t)0x7ec5, (q15_t)0xee50, + (q15_t)0x7ec4, (q15_t)0xee4a, (q15_t)0x7ec3, (q15_t)0xee44, (q15_t)0x7ec3, (q15_t)0xee3e, (q15_t)0x7ec2, (q15_t)0xee37, + (q15_t)0x7ec1, (q15_t)0xee31, (q15_t)0x7ec0, (q15_t)0xee2b, (q15_t)0x7ebf, (q15_t)0xee25, (q15_t)0x7ebe, (q15_t)0xee1f, + (q15_t)0x7ebd, (q15_t)0xee18, (q15_t)0x7ebc, (q15_t)0xee12, (q15_t)0x7ebb, (q15_t)0xee0c, (q15_t)0x7ebb, (q15_t)0xee06, + (q15_t)0x7eba, (q15_t)0xedff, (q15_t)0x7eb9, (q15_t)0xedf9, (q15_t)0x7eb8, (q15_t)0xedf3, (q15_t)0x7eb7, (q15_t)0xeded, + (q15_t)0x7eb6, (q15_t)0xede7, (q15_t)0x7eb5, (q15_t)0xede0, (q15_t)0x7eb4, (q15_t)0xedda, (q15_t)0x7eb4, (q15_t)0xedd4, + (q15_t)0x7eb3, (q15_t)0xedce, (q15_t)0x7eb2, (q15_t)0xedc7, (q15_t)0x7eb1, (q15_t)0xedc1, (q15_t)0x7eb0, (q15_t)0xedbb, + (q15_t)0x7eaf, (q15_t)0xedb5, (q15_t)0x7eae, (q15_t)0xedaf, (q15_t)0x7ead, (q15_t)0xeda8, (q15_t)0x7eac, (q15_t)0xeda2, + (q15_t)0x7eab, (q15_t)0xed9c, (q15_t)0x7eab, (q15_t)0xed96, (q15_t)0x7eaa, (q15_t)0xed8f, (q15_t)0x7ea9, (q15_t)0xed89, + (q15_t)0x7ea8, (q15_t)0xed83, (q15_t)0x7ea7, (q15_t)0xed7d, (q15_t)0x7ea6, (q15_t)0xed77, (q15_t)0x7ea5, (q15_t)0xed70, + (q15_t)0x7ea4, (q15_t)0xed6a, (q15_t)0x7ea3, (q15_t)0xed64, (q15_t)0x7ea2, (q15_t)0xed5e, (q15_t)0x7ea1, (q15_t)0xed58, + (q15_t)0x7ea1, (q15_t)0xed51, (q15_t)0x7ea0, (q15_t)0xed4b, (q15_t)0x7e9f, (q15_t)0xed45, (q15_t)0x7e9e, (q15_t)0xed3f, + (q15_t)0x7e9d, (q15_t)0xed38, (q15_t)0x7e9c, (q15_t)0xed32, (q15_t)0x7e9b, (q15_t)0xed2c, (q15_t)0x7e9a, (q15_t)0xed26, + (q15_t)0x7e99, (q15_t)0xed20, (q15_t)0x7e98, (q15_t)0xed19, (q15_t)0x7e97, (q15_t)0xed13, (q15_t)0x7e96, (q15_t)0xed0d, + (q15_t)0x7e95, (q15_t)0xed07, (q15_t)0x7e94, (q15_t)0xed01, (q15_t)0x7e94, (q15_t)0xecfa, (q15_t)0x7e93, (q15_t)0xecf4, + (q15_t)0x7e92, (q15_t)0xecee, (q15_t)0x7e91, (q15_t)0xece8, (q15_t)0x7e90, (q15_t)0xece1, (q15_t)0x7e8f, (q15_t)0xecdb, + (q15_t)0x7e8e, (q15_t)0xecd5, (q15_t)0x7e8d, (q15_t)0xeccf, (q15_t)0x7e8c, (q15_t)0xecc9, (q15_t)0x7e8b, (q15_t)0xecc2, + (q15_t)0x7e8a, (q15_t)0xecbc, (q15_t)0x7e89, (q15_t)0xecb6, (q15_t)0x7e88, (q15_t)0xecb0, (q15_t)0x7e87, (q15_t)0xecaa, + (q15_t)0x7e86, (q15_t)0xeca3, (q15_t)0x7e85, (q15_t)0xec9d, (q15_t)0x7e84, (q15_t)0xec97, (q15_t)0x7e84, (q15_t)0xec91, + (q15_t)0x7e83, (q15_t)0xec8a, (q15_t)0x7e82, (q15_t)0xec84, (q15_t)0x7e81, (q15_t)0xec7e, (q15_t)0x7e80, (q15_t)0xec78, + (q15_t)0x7e7f, (q15_t)0xec72, (q15_t)0x7e7e, (q15_t)0xec6b, (q15_t)0x7e7d, (q15_t)0xec65, (q15_t)0x7e7c, (q15_t)0xec5f, + (q15_t)0x7e7b, (q15_t)0xec59, (q15_t)0x7e7a, (q15_t)0xec53, (q15_t)0x7e79, (q15_t)0xec4c, (q15_t)0x7e78, (q15_t)0xec46, + (q15_t)0x7e77, (q15_t)0xec40, (q15_t)0x7e76, (q15_t)0xec3a, (q15_t)0x7e75, (q15_t)0xec34, (q15_t)0x7e74, (q15_t)0xec2d, + (q15_t)0x7e73, (q15_t)0xec27, (q15_t)0x7e72, (q15_t)0xec21, (q15_t)0x7e71, (q15_t)0xec1b, (q15_t)0x7e70, (q15_t)0xec15, + (q15_t)0x7e6f, (q15_t)0xec0e, (q15_t)0x7e6e, (q15_t)0xec08, (q15_t)0x7e6d, (q15_t)0xec02, (q15_t)0x7e6c, (q15_t)0xebfc, + (q15_t)0x7e6b, (q15_t)0xebf5, (q15_t)0x7e6a, (q15_t)0xebef, (q15_t)0x7e69, (q15_t)0xebe9, (q15_t)0x7e68, (q15_t)0xebe3, + (q15_t)0x7e67, (q15_t)0xebdd, (q15_t)0x7e66, (q15_t)0xebd6, (q15_t)0x7e65, (q15_t)0xebd0, (q15_t)0x7e64, (q15_t)0xebca, + (q15_t)0x7e63, (q15_t)0xebc4, (q15_t)0x7e62, (q15_t)0xebbe, (q15_t)0x7e61, (q15_t)0xebb7, (q15_t)0x7e60, (q15_t)0xebb1, + (q15_t)0x7e5f, (q15_t)0xebab, (q15_t)0x7e5e, (q15_t)0xeba5, (q15_t)0x7e5d, (q15_t)0xeb9f, (q15_t)0x7e5c, (q15_t)0xeb98, + (q15_t)0x7e5b, (q15_t)0xeb92, (q15_t)0x7e5a, (q15_t)0xeb8c, (q15_t)0x7e59, (q15_t)0xeb86, (q15_t)0x7e58, (q15_t)0xeb80, + (q15_t)0x7e57, (q15_t)0xeb79, (q15_t)0x7e56, (q15_t)0xeb73, (q15_t)0x7e55, (q15_t)0xeb6d, (q15_t)0x7e54, (q15_t)0xeb67, + (q15_t)0x7e53, (q15_t)0xeb61, (q15_t)0x7e52, (q15_t)0xeb5a, (q15_t)0x7e51, (q15_t)0xeb54, (q15_t)0x7e50, (q15_t)0xeb4e, + (q15_t)0x7e4f, (q15_t)0xeb48, (q15_t)0x7e4e, (q15_t)0xeb42, (q15_t)0x7e4d, (q15_t)0xeb3b, (q15_t)0x7e4c, (q15_t)0xeb35, + (q15_t)0x7e4b, (q15_t)0xeb2f, (q15_t)0x7e4a, (q15_t)0xeb29, (q15_t)0x7e49, (q15_t)0xeb23, (q15_t)0x7e48, (q15_t)0xeb1c, + (q15_t)0x7e47, (q15_t)0xeb16, (q15_t)0x7e46, (q15_t)0xeb10, (q15_t)0x7e45, (q15_t)0xeb0a, (q15_t)0x7e44, (q15_t)0xeb04, + (q15_t)0x7e43, (q15_t)0xeafd, (q15_t)0x7e42, (q15_t)0xeaf7, (q15_t)0x7e41, (q15_t)0xeaf1, (q15_t)0x7e40, (q15_t)0xeaeb, + (q15_t)0x7e3f, (q15_t)0xeae5, (q15_t)0x7e3e, (q15_t)0xeade, (q15_t)0x7e3d, (q15_t)0xead8, (q15_t)0x7e3c, (q15_t)0xead2, + (q15_t)0x7e3b, (q15_t)0xeacc, (q15_t)0x7e3a, (q15_t)0xeac6, (q15_t)0x7e39, (q15_t)0xeabf, (q15_t)0x7e38, (q15_t)0xeab9, + (q15_t)0x7e37, (q15_t)0xeab3, (q15_t)0x7e35, (q15_t)0xeaad, (q15_t)0x7e34, (q15_t)0xeaa7, (q15_t)0x7e33, (q15_t)0xeaa0, + (q15_t)0x7e32, (q15_t)0xea9a, (q15_t)0x7e31, (q15_t)0xea94, (q15_t)0x7e30, (q15_t)0xea8e, (q15_t)0x7e2f, (q15_t)0xea88, + (q15_t)0x7e2e, (q15_t)0xea81, (q15_t)0x7e2d, (q15_t)0xea7b, (q15_t)0x7e2c, (q15_t)0xea75, (q15_t)0x7e2b, (q15_t)0xea6f, + (q15_t)0x7e2a, (q15_t)0xea69, (q15_t)0x7e29, (q15_t)0xea63, (q15_t)0x7e28, (q15_t)0xea5c, (q15_t)0x7e27, (q15_t)0xea56, + (q15_t)0x7e26, (q15_t)0xea50, (q15_t)0x7e25, (q15_t)0xea4a, (q15_t)0x7e24, (q15_t)0xea44, (q15_t)0x7e22, (q15_t)0xea3d, + (q15_t)0x7e21, (q15_t)0xea37, (q15_t)0x7e20, (q15_t)0xea31, (q15_t)0x7e1f, (q15_t)0xea2b, (q15_t)0x7e1e, (q15_t)0xea25, + (q15_t)0x7e1d, (q15_t)0xea1e, (q15_t)0x7e1c, (q15_t)0xea18, (q15_t)0x7e1b, (q15_t)0xea12, (q15_t)0x7e1a, (q15_t)0xea0c, + (q15_t)0x7e19, (q15_t)0xea06, (q15_t)0x7e18, (q15_t)0xe9ff, (q15_t)0x7e17, (q15_t)0xe9f9, (q15_t)0x7e16, (q15_t)0xe9f3, + (q15_t)0x7e14, (q15_t)0xe9ed, (q15_t)0x7e13, (q15_t)0xe9e7, (q15_t)0x7e12, (q15_t)0xe9e1, (q15_t)0x7e11, (q15_t)0xe9da, + (q15_t)0x7e10, (q15_t)0xe9d4, (q15_t)0x7e0f, (q15_t)0xe9ce, (q15_t)0x7e0e, (q15_t)0xe9c8, (q15_t)0x7e0d, (q15_t)0xe9c2, + (q15_t)0x7e0c, (q15_t)0xe9bb, (q15_t)0x7e0b, (q15_t)0xe9b5, (q15_t)0x7e0a, (q15_t)0xe9af, (q15_t)0x7e08, (q15_t)0xe9a9, + (q15_t)0x7e07, (q15_t)0xe9a3, (q15_t)0x7e06, (q15_t)0xe99c, (q15_t)0x7e05, (q15_t)0xe996, (q15_t)0x7e04, (q15_t)0xe990, + (q15_t)0x7e03, (q15_t)0xe98a, (q15_t)0x7e02, (q15_t)0xe984, (q15_t)0x7e01, (q15_t)0xe97e, (q15_t)0x7e00, (q15_t)0xe977, + (q15_t)0x7dff, (q15_t)0xe971, (q15_t)0x7dfd, (q15_t)0xe96b, (q15_t)0x7dfc, (q15_t)0xe965, (q15_t)0x7dfb, (q15_t)0xe95f, + (q15_t)0x7dfa, (q15_t)0xe958, (q15_t)0x7df9, (q15_t)0xe952, (q15_t)0x7df8, (q15_t)0xe94c, (q15_t)0x7df7, (q15_t)0xe946, + (q15_t)0x7df6, (q15_t)0xe940, (q15_t)0x7df5, (q15_t)0xe93a, (q15_t)0x7df3, (q15_t)0xe933, (q15_t)0x7df2, (q15_t)0xe92d, + (q15_t)0x7df1, (q15_t)0xe927, (q15_t)0x7df0, (q15_t)0xe921, (q15_t)0x7def, (q15_t)0xe91b, (q15_t)0x7dee, (q15_t)0xe914, + (q15_t)0x7ded, (q15_t)0xe90e, (q15_t)0x7dec, (q15_t)0xe908, (q15_t)0x7dea, (q15_t)0xe902, (q15_t)0x7de9, (q15_t)0xe8fc, + (q15_t)0x7de8, (q15_t)0xe8f6, (q15_t)0x7de7, (q15_t)0xe8ef, (q15_t)0x7de6, (q15_t)0xe8e9, (q15_t)0x7de5, (q15_t)0xe8e3, + (q15_t)0x7de4, (q15_t)0xe8dd, (q15_t)0x7de2, (q15_t)0xe8d7, (q15_t)0x7de1, (q15_t)0xe8d0, (q15_t)0x7de0, (q15_t)0xe8ca, + (q15_t)0x7ddf, (q15_t)0xe8c4, (q15_t)0x7dde, (q15_t)0xe8be, (q15_t)0x7ddd, (q15_t)0xe8b8, (q15_t)0x7ddc, (q15_t)0xe8b2, + (q15_t)0x7dda, (q15_t)0xe8ab, (q15_t)0x7dd9, (q15_t)0xe8a5, (q15_t)0x7dd8, (q15_t)0xe89f, (q15_t)0x7dd7, (q15_t)0xe899, + (q15_t)0x7dd6, (q15_t)0xe893, (q15_t)0x7dd5, (q15_t)0xe88c, (q15_t)0x7dd4, (q15_t)0xe886, (q15_t)0x7dd2, (q15_t)0xe880, + (q15_t)0x7dd1, (q15_t)0xe87a, (q15_t)0x7dd0, (q15_t)0xe874, (q15_t)0x7dcf, (q15_t)0xe86e, (q15_t)0x7dce, (q15_t)0xe867, + (q15_t)0x7dcd, (q15_t)0xe861, (q15_t)0x7dcc, (q15_t)0xe85b, (q15_t)0x7dca, (q15_t)0xe855, (q15_t)0x7dc9, (q15_t)0xe84f, + (q15_t)0x7dc8, (q15_t)0xe849, (q15_t)0x7dc7, (q15_t)0xe842, (q15_t)0x7dc6, (q15_t)0xe83c, (q15_t)0x7dc5, (q15_t)0xe836, + (q15_t)0x7dc3, (q15_t)0xe830, (q15_t)0x7dc2, (q15_t)0xe82a, (q15_t)0x7dc1, (q15_t)0xe823, (q15_t)0x7dc0, (q15_t)0xe81d, + (q15_t)0x7dbf, (q15_t)0xe817, (q15_t)0x7dbd, (q15_t)0xe811, (q15_t)0x7dbc, (q15_t)0xe80b, (q15_t)0x7dbb, (q15_t)0xe805, + (q15_t)0x7dba, (q15_t)0xe7fe, (q15_t)0x7db9, (q15_t)0xe7f8, (q15_t)0x7db8, (q15_t)0xe7f2, (q15_t)0x7db6, (q15_t)0xe7ec, + (q15_t)0x7db5, (q15_t)0xe7e6, (q15_t)0x7db4, (q15_t)0xe7e0, (q15_t)0x7db3, (q15_t)0xe7d9, (q15_t)0x7db2, (q15_t)0xe7d3, + (q15_t)0x7db0, (q15_t)0xe7cd, (q15_t)0x7daf, (q15_t)0xe7c7, (q15_t)0x7dae, (q15_t)0xe7c1, (q15_t)0x7dad, (q15_t)0xe7bb, + (q15_t)0x7dac, (q15_t)0xe7b4, (q15_t)0x7dab, (q15_t)0xe7ae, (q15_t)0x7da9, (q15_t)0xe7a8, (q15_t)0x7da8, (q15_t)0xe7a2, + (q15_t)0x7da7, (q15_t)0xe79c, (q15_t)0x7da6, (q15_t)0xe796, (q15_t)0x7da5, (q15_t)0xe78f, (q15_t)0x7da3, (q15_t)0xe789, + (q15_t)0x7da2, (q15_t)0xe783, (q15_t)0x7da1, (q15_t)0xe77d, (q15_t)0x7da0, (q15_t)0xe777, (q15_t)0x7d9f, (q15_t)0xe771, + (q15_t)0x7d9d, (q15_t)0xe76a, (q15_t)0x7d9c, (q15_t)0xe764, (q15_t)0x7d9b, (q15_t)0xe75e, (q15_t)0x7d9a, (q15_t)0xe758, + (q15_t)0x7d98, (q15_t)0xe752, (q15_t)0x7d97, (q15_t)0xe74c, (q15_t)0x7d96, (q15_t)0xe745, (q15_t)0x7d95, (q15_t)0xe73f, + (q15_t)0x7d94, (q15_t)0xe739, (q15_t)0x7d92, (q15_t)0xe733, (q15_t)0x7d91, (q15_t)0xe72d, (q15_t)0x7d90, (q15_t)0xe727, + (q15_t)0x7d8f, (q15_t)0xe720, (q15_t)0x7d8e, (q15_t)0xe71a, (q15_t)0x7d8c, (q15_t)0xe714, (q15_t)0x7d8b, (q15_t)0xe70e, + (q15_t)0x7d8a, (q15_t)0xe708, (q15_t)0x7d89, (q15_t)0xe702, (q15_t)0x7d87, (q15_t)0xe6fb, (q15_t)0x7d86, (q15_t)0xe6f5, + (q15_t)0x7d85, (q15_t)0xe6ef, (q15_t)0x7d84, (q15_t)0xe6e9, (q15_t)0x7d82, (q15_t)0xe6e3, (q15_t)0x7d81, (q15_t)0xe6dd, + (q15_t)0x7d80, (q15_t)0xe6d6, (q15_t)0x7d7f, (q15_t)0xe6d0, (q15_t)0x7d7e, (q15_t)0xe6ca, (q15_t)0x7d7c, (q15_t)0xe6c4, + (q15_t)0x7d7b, (q15_t)0xe6be, (q15_t)0x7d7a, (q15_t)0xe6b8, (q15_t)0x7d79, (q15_t)0xe6b2, (q15_t)0x7d77, (q15_t)0xe6ab, + (q15_t)0x7d76, (q15_t)0xe6a5, (q15_t)0x7d75, (q15_t)0xe69f, (q15_t)0x7d74, (q15_t)0xe699, (q15_t)0x7d72, (q15_t)0xe693, + (q15_t)0x7d71, (q15_t)0xe68d, (q15_t)0x7d70, (q15_t)0xe686, (q15_t)0x7d6f, (q15_t)0xe680, (q15_t)0x7d6d, (q15_t)0xe67a, + (q15_t)0x7d6c, (q15_t)0xe674, (q15_t)0x7d6b, (q15_t)0xe66e, (q15_t)0x7d6a, (q15_t)0xe668, (q15_t)0x7d68, (q15_t)0xe661, + (q15_t)0x7d67, (q15_t)0xe65b, (q15_t)0x7d66, (q15_t)0xe655, (q15_t)0x7d65, (q15_t)0xe64f, (q15_t)0x7d63, (q15_t)0xe649, + (q15_t)0x7d62, (q15_t)0xe643, (q15_t)0x7d61, (q15_t)0xe63d, (q15_t)0x7d60, (q15_t)0xe636, (q15_t)0x7d5e, (q15_t)0xe630, + (q15_t)0x7d5d, (q15_t)0xe62a, (q15_t)0x7d5c, (q15_t)0xe624, (q15_t)0x7d5a, (q15_t)0xe61e, (q15_t)0x7d59, (q15_t)0xe618, + (q15_t)0x7d58, (q15_t)0xe611, (q15_t)0x7d57, (q15_t)0xe60b, (q15_t)0x7d55, (q15_t)0xe605, (q15_t)0x7d54, (q15_t)0xe5ff, + (q15_t)0x7d53, (q15_t)0xe5f9, (q15_t)0x7d52, (q15_t)0xe5f3, (q15_t)0x7d50, (q15_t)0xe5ed, (q15_t)0x7d4f, (q15_t)0xe5e6, + (q15_t)0x7d4e, (q15_t)0xe5e0, (q15_t)0x7d4c, (q15_t)0xe5da, (q15_t)0x7d4b, (q15_t)0xe5d4, (q15_t)0x7d4a, (q15_t)0xe5ce, + (q15_t)0x7d49, (q15_t)0xe5c8, (q15_t)0x7d47, (q15_t)0xe5c2, (q15_t)0x7d46, (q15_t)0xe5bb, (q15_t)0x7d45, (q15_t)0xe5b5, + (q15_t)0x7d43, (q15_t)0xe5af, (q15_t)0x7d42, (q15_t)0xe5a9, (q15_t)0x7d41, (q15_t)0xe5a3, (q15_t)0x7d3f, (q15_t)0xe59d, + (q15_t)0x7d3e, (q15_t)0xe596, (q15_t)0x7d3d, (q15_t)0xe590, (q15_t)0x7d3c, (q15_t)0xe58a, (q15_t)0x7d3a, (q15_t)0xe584, + (q15_t)0x7d39, (q15_t)0xe57e, (q15_t)0x7d38, (q15_t)0xe578, (q15_t)0x7d36, (q15_t)0xe572, (q15_t)0x7d35, (q15_t)0xe56b, + (q15_t)0x7d34, (q15_t)0xe565, (q15_t)0x7d32, (q15_t)0xe55f, (q15_t)0x7d31, (q15_t)0xe559, (q15_t)0x7d30, (q15_t)0xe553, + (q15_t)0x7d2f, (q15_t)0xe54d, (q15_t)0x7d2d, (q15_t)0xe547, (q15_t)0x7d2c, (q15_t)0xe540, (q15_t)0x7d2b, (q15_t)0xe53a, + (q15_t)0x7d29, (q15_t)0xe534, (q15_t)0x7d28, (q15_t)0xe52e, (q15_t)0x7d27, (q15_t)0xe528, (q15_t)0x7d25, (q15_t)0xe522, + (q15_t)0x7d24, (q15_t)0xe51c, (q15_t)0x7d23, (q15_t)0xe515, (q15_t)0x7d21, (q15_t)0xe50f, (q15_t)0x7d20, (q15_t)0xe509, + (q15_t)0x7d1f, (q15_t)0xe503, (q15_t)0x7d1d, (q15_t)0xe4fd, (q15_t)0x7d1c, (q15_t)0xe4f7, (q15_t)0x7d1b, (q15_t)0xe4f1, + (q15_t)0x7d19, (q15_t)0xe4ea, (q15_t)0x7d18, (q15_t)0xe4e4, (q15_t)0x7d17, (q15_t)0xe4de, (q15_t)0x7d15, (q15_t)0xe4d8, + (q15_t)0x7d14, (q15_t)0xe4d2, (q15_t)0x7d13, (q15_t)0xe4cc, (q15_t)0x7d11, (q15_t)0xe4c6, (q15_t)0x7d10, (q15_t)0xe4bf, + (q15_t)0x7d0f, (q15_t)0xe4b9, (q15_t)0x7d0d, (q15_t)0xe4b3, (q15_t)0x7d0c, (q15_t)0xe4ad, (q15_t)0x7d0b, (q15_t)0xe4a7, + (q15_t)0x7d09, (q15_t)0xe4a1, (q15_t)0x7d08, (q15_t)0xe49b, (q15_t)0x7d07, (q15_t)0xe494, (q15_t)0x7d05, (q15_t)0xe48e, + (q15_t)0x7d04, (q15_t)0xe488, (q15_t)0x7d03, (q15_t)0xe482, (q15_t)0x7d01, (q15_t)0xe47c, (q15_t)0x7d00, (q15_t)0xe476, + (q15_t)0x7cff, (q15_t)0xe470, (q15_t)0x7cfd, (q15_t)0xe46a, (q15_t)0x7cfc, (q15_t)0xe463, (q15_t)0x7cfb, (q15_t)0xe45d, + (q15_t)0x7cf9, (q15_t)0xe457, (q15_t)0x7cf8, (q15_t)0xe451, (q15_t)0x7cf6, (q15_t)0xe44b, (q15_t)0x7cf5, (q15_t)0xe445, + (q15_t)0x7cf4, (q15_t)0xe43f, (q15_t)0x7cf2, (q15_t)0xe438, (q15_t)0x7cf1, (q15_t)0xe432, (q15_t)0x7cf0, (q15_t)0xe42c, + (q15_t)0x7cee, (q15_t)0xe426, (q15_t)0x7ced, (q15_t)0xe420, (q15_t)0x7cec, (q15_t)0xe41a, (q15_t)0x7cea, (q15_t)0xe414, + (q15_t)0x7ce9, (q15_t)0xe40e, (q15_t)0x7ce7, (q15_t)0xe407, (q15_t)0x7ce6, (q15_t)0xe401, (q15_t)0x7ce5, (q15_t)0xe3fb, + (q15_t)0x7ce3, (q15_t)0xe3f5, (q15_t)0x7ce2, (q15_t)0xe3ef, (q15_t)0x7ce1, (q15_t)0xe3e9, (q15_t)0x7cdf, (q15_t)0xe3e3, + (q15_t)0x7cde, (q15_t)0xe3dc, (q15_t)0x7cdc, (q15_t)0xe3d6, (q15_t)0x7cdb, (q15_t)0xe3d0, (q15_t)0x7cda, (q15_t)0xe3ca, + (q15_t)0x7cd8, (q15_t)0xe3c4, (q15_t)0x7cd7, (q15_t)0xe3be, (q15_t)0x7cd5, (q15_t)0xe3b8, (q15_t)0x7cd4, (q15_t)0xe3b2, + (q15_t)0x7cd3, (q15_t)0xe3ab, (q15_t)0x7cd1, (q15_t)0xe3a5, (q15_t)0x7cd0, (q15_t)0xe39f, (q15_t)0x7ccf, (q15_t)0xe399, + (q15_t)0x7ccd, (q15_t)0xe393, (q15_t)0x7ccc, (q15_t)0xe38d, (q15_t)0x7cca, (q15_t)0xe387, (q15_t)0x7cc9, (q15_t)0xe381, + (q15_t)0x7cc8, (q15_t)0xe37a, (q15_t)0x7cc6, (q15_t)0xe374, (q15_t)0x7cc5, (q15_t)0xe36e, (q15_t)0x7cc3, (q15_t)0xe368, + (q15_t)0x7cc2, (q15_t)0xe362, (q15_t)0x7cc1, (q15_t)0xe35c, (q15_t)0x7cbf, (q15_t)0xe356, (q15_t)0x7cbe, (q15_t)0xe350, + (q15_t)0x7cbc, (q15_t)0xe349, (q15_t)0x7cbb, (q15_t)0xe343, (q15_t)0x7cb9, (q15_t)0xe33d, (q15_t)0x7cb8, (q15_t)0xe337, + (q15_t)0x7cb7, (q15_t)0xe331, (q15_t)0x7cb5, (q15_t)0xe32b, (q15_t)0x7cb4, (q15_t)0xe325, (q15_t)0x7cb2, (q15_t)0xe31f, + (q15_t)0x7cb1, (q15_t)0xe318, (q15_t)0x7cb0, (q15_t)0xe312, (q15_t)0x7cae, (q15_t)0xe30c, (q15_t)0x7cad, (q15_t)0xe306, + (q15_t)0x7cab, (q15_t)0xe300, (q15_t)0x7caa, (q15_t)0xe2fa, (q15_t)0x7ca8, (q15_t)0xe2f4, (q15_t)0x7ca7, (q15_t)0xe2ee, + (q15_t)0x7ca6, (q15_t)0xe2e8, (q15_t)0x7ca4, (q15_t)0xe2e1, (q15_t)0x7ca3, (q15_t)0xe2db, (q15_t)0x7ca1, (q15_t)0xe2d5, + (q15_t)0x7ca0, (q15_t)0xe2cf, (q15_t)0x7c9e, (q15_t)0xe2c9, (q15_t)0x7c9d, (q15_t)0xe2c3, (q15_t)0x7c9c, (q15_t)0xe2bd, + (q15_t)0x7c9a, (q15_t)0xe2b7, (q15_t)0x7c99, (q15_t)0xe2b0, (q15_t)0x7c97, (q15_t)0xe2aa, (q15_t)0x7c96, (q15_t)0xe2a4, + (q15_t)0x7c94, (q15_t)0xe29e, (q15_t)0x7c93, (q15_t)0xe298, (q15_t)0x7c91, (q15_t)0xe292, (q15_t)0x7c90, (q15_t)0xe28c, + (q15_t)0x7c8f, (q15_t)0xe286, (q15_t)0x7c8d, (q15_t)0xe280, (q15_t)0x7c8c, (q15_t)0xe279, (q15_t)0x7c8a, (q15_t)0xe273, + (q15_t)0x7c89, (q15_t)0xe26d, (q15_t)0x7c87, (q15_t)0xe267, (q15_t)0x7c86, (q15_t)0xe261, (q15_t)0x7c84, (q15_t)0xe25b, + (q15_t)0x7c83, (q15_t)0xe255, (q15_t)0x7c82, (q15_t)0xe24f, (q15_t)0x7c80, (q15_t)0xe249, (q15_t)0x7c7f, (q15_t)0xe242, + (q15_t)0x7c7d, (q15_t)0xe23c, (q15_t)0x7c7c, (q15_t)0xe236, (q15_t)0x7c7a, (q15_t)0xe230, (q15_t)0x7c79, (q15_t)0xe22a, + (q15_t)0x7c77, (q15_t)0xe224, (q15_t)0x7c76, (q15_t)0xe21e, (q15_t)0x7c74, (q15_t)0xe218, (q15_t)0x7c73, (q15_t)0xe212, + (q15_t)0x7c71, (q15_t)0xe20b, (q15_t)0x7c70, (q15_t)0xe205, (q15_t)0x7c6e, (q15_t)0xe1ff, (q15_t)0x7c6d, (q15_t)0xe1f9, + (q15_t)0x7c6c, (q15_t)0xe1f3, (q15_t)0x7c6a, (q15_t)0xe1ed, (q15_t)0x7c69, (q15_t)0xe1e7, (q15_t)0x7c67, (q15_t)0xe1e1, + (q15_t)0x7c66, (q15_t)0xe1db, (q15_t)0x7c64, (q15_t)0xe1d4, (q15_t)0x7c63, (q15_t)0xe1ce, (q15_t)0x7c61, (q15_t)0xe1c8, + (q15_t)0x7c60, (q15_t)0xe1c2, (q15_t)0x7c5e, (q15_t)0xe1bc, (q15_t)0x7c5d, (q15_t)0xe1b6, (q15_t)0x7c5b, (q15_t)0xe1b0, + (q15_t)0x7c5a, (q15_t)0xe1aa, (q15_t)0x7c58, (q15_t)0xe1a4, (q15_t)0x7c57, (q15_t)0xe19e, (q15_t)0x7c55, (q15_t)0xe197, + (q15_t)0x7c54, (q15_t)0xe191, (q15_t)0x7c52, (q15_t)0xe18b, (q15_t)0x7c51, (q15_t)0xe185, (q15_t)0x7c4f, (q15_t)0xe17f, + (q15_t)0x7c4e, (q15_t)0xe179, (q15_t)0x7c4c, (q15_t)0xe173, (q15_t)0x7c4b, (q15_t)0xe16d, (q15_t)0x7c49, (q15_t)0xe167, + (q15_t)0x7c48, (q15_t)0xe160, (q15_t)0x7c46, (q15_t)0xe15a, (q15_t)0x7c45, (q15_t)0xe154, (q15_t)0x7c43, (q15_t)0xe14e, + (q15_t)0x7c42, (q15_t)0xe148, (q15_t)0x7c40, (q15_t)0xe142, (q15_t)0x7c3f, (q15_t)0xe13c, (q15_t)0x7c3d, (q15_t)0xe136, + (q15_t)0x7c3c, (q15_t)0xe130, (q15_t)0x7c3a, (q15_t)0xe12a, (q15_t)0x7c39, (q15_t)0xe123, (q15_t)0x7c37, (q15_t)0xe11d, + (q15_t)0x7c36, (q15_t)0xe117, (q15_t)0x7c34, (q15_t)0xe111, (q15_t)0x7c33, (q15_t)0xe10b, (q15_t)0x7c31, (q15_t)0xe105, + (q15_t)0x7c30, (q15_t)0xe0ff, (q15_t)0x7c2e, (q15_t)0xe0f9, (q15_t)0x7c2d, (q15_t)0xe0f3, (q15_t)0x7c2b, (q15_t)0xe0ed, + (q15_t)0x7c29, (q15_t)0xe0e7, (q15_t)0x7c28, (q15_t)0xe0e0, (q15_t)0x7c26, (q15_t)0xe0da, (q15_t)0x7c25, (q15_t)0xe0d4, + (q15_t)0x7c23, (q15_t)0xe0ce, (q15_t)0x7c22, (q15_t)0xe0c8, (q15_t)0x7c20, (q15_t)0xe0c2, (q15_t)0x7c1f, (q15_t)0xe0bc, + (q15_t)0x7c1d, (q15_t)0xe0b6, (q15_t)0x7c1c, (q15_t)0xe0b0, (q15_t)0x7c1a, (q15_t)0xe0aa, (q15_t)0x7c19, (q15_t)0xe0a3, + (q15_t)0x7c17, (q15_t)0xe09d, (q15_t)0x7c16, (q15_t)0xe097, (q15_t)0x7c14, (q15_t)0xe091, (q15_t)0x7c12, (q15_t)0xe08b, + (q15_t)0x7c11, (q15_t)0xe085, (q15_t)0x7c0f, (q15_t)0xe07f, (q15_t)0x7c0e, (q15_t)0xe079, (q15_t)0x7c0c, (q15_t)0xe073, + (q15_t)0x7c0b, (q15_t)0xe06d, (q15_t)0x7c09, (q15_t)0xe067, (q15_t)0x7c08, (q15_t)0xe061, (q15_t)0x7c06, (q15_t)0xe05a, + (q15_t)0x7c05, (q15_t)0xe054, (q15_t)0x7c03, (q15_t)0xe04e, (q15_t)0x7c01, (q15_t)0xe048, (q15_t)0x7c00, (q15_t)0xe042, + (q15_t)0x7bfe, (q15_t)0xe03c, (q15_t)0x7bfd, (q15_t)0xe036, (q15_t)0x7bfb, (q15_t)0xe030, (q15_t)0x7bfa, (q15_t)0xe02a, + (q15_t)0x7bf8, (q15_t)0xe024, (q15_t)0x7bf6, (q15_t)0xe01e, (q15_t)0x7bf5, (q15_t)0xe017, (q15_t)0x7bf3, (q15_t)0xe011, + (q15_t)0x7bf2, (q15_t)0xe00b, (q15_t)0x7bf0, (q15_t)0xe005, (q15_t)0x7bef, (q15_t)0xdfff, (q15_t)0x7bed, (q15_t)0xdff9, + (q15_t)0x7beb, (q15_t)0xdff3, (q15_t)0x7bea, (q15_t)0xdfed, (q15_t)0x7be8, (q15_t)0xdfe7, (q15_t)0x7be7, (q15_t)0xdfe1, + (q15_t)0x7be5, (q15_t)0xdfdb, (q15_t)0x7be4, (q15_t)0xdfd5, (q15_t)0x7be2, (q15_t)0xdfce, (q15_t)0x7be0, (q15_t)0xdfc8, + (q15_t)0x7bdf, (q15_t)0xdfc2, (q15_t)0x7bdd, (q15_t)0xdfbc, (q15_t)0x7bdc, (q15_t)0xdfb6, (q15_t)0x7bda, (q15_t)0xdfb0, + (q15_t)0x7bd9, (q15_t)0xdfaa, (q15_t)0x7bd7, (q15_t)0xdfa4, (q15_t)0x7bd5, (q15_t)0xdf9e, (q15_t)0x7bd4, (q15_t)0xdf98, + (q15_t)0x7bd2, (q15_t)0xdf92, (q15_t)0x7bd1, (q15_t)0xdf8c, (q15_t)0x7bcf, (q15_t)0xdf86, (q15_t)0x7bcd, (q15_t)0xdf7f, + (q15_t)0x7bcc, (q15_t)0xdf79, (q15_t)0x7bca, (q15_t)0xdf73, (q15_t)0x7bc9, (q15_t)0xdf6d, (q15_t)0x7bc7, (q15_t)0xdf67, + (q15_t)0x7bc5, (q15_t)0xdf61, (q15_t)0x7bc4, (q15_t)0xdf5b, (q15_t)0x7bc2, (q15_t)0xdf55, (q15_t)0x7bc1, (q15_t)0xdf4f, + (q15_t)0x7bbf, (q15_t)0xdf49, (q15_t)0x7bbd, (q15_t)0xdf43, (q15_t)0x7bbc, (q15_t)0xdf3d, (q15_t)0x7bba, (q15_t)0xdf37, + (q15_t)0x7bb9, (q15_t)0xdf30, (q15_t)0x7bb7, (q15_t)0xdf2a, (q15_t)0x7bb5, (q15_t)0xdf24, (q15_t)0x7bb4, (q15_t)0xdf1e, + (q15_t)0x7bb2, (q15_t)0xdf18, (q15_t)0x7bb0, (q15_t)0xdf12, (q15_t)0x7baf, (q15_t)0xdf0c, (q15_t)0x7bad, (q15_t)0xdf06, + (q15_t)0x7bac, (q15_t)0xdf00, (q15_t)0x7baa, (q15_t)0xdefa, (q15_t)0x7ba8, (q15_t)0xdef4, (q15_t)0x7ba7, (q15_t)0xdeee, + (q15_t)0x7ba5, (q15_t)0xdee8, (q15_t)0x7ba3, (q15_t)0xdee2, (q15_t)0x7ba2, (q15_t)0xdedb, (q15_t)0x7ba0, (q15_t)0xded5, + (q15_t)0x7b9f, (q15_t)0xdecf, (q15_t)0x7b9d, (q15_t)0xdec9, (q15_t)0x7b9b, (q15_t)0xdec3, (q15_t)0x7b9a, (q15_t)0xdebd, + (q15_t)0x7b98, (q15_t)0xdeb7, (q15_t)0x7b96, (q15_t)0xdeb1, (q15_t)0x7b95, (q15_t)0xdeab, (q15_t)0x7b93, (q15_t)0xdea5, + (q15_t)0x7b92, (q15_t)0xde9f, (q15_t)0x7b90, (q15_t)0xde99, (q15_t)0x7b8e, (q15_t)0xde93, (q15_t)0x7b8d, (q15_t)0xde8d, + (q15_t)0x7b8b, (q15_t)0xde87, (q15_t)0x7b89, (q15_t)0xde80, (q15_t)0x7b88, (q15_t)0xde7a, (q15_t)0x7b86, (q15_t)0xde74, + (q15_t)0x7b84, (q15_t)0xde6e, (q15_t)0x7b83, (q15_t)0xde68, (q15_t)0x7b81, (q15_t)0xde62, (q15_t)0x7b7f, (q15_t)0xde5c, + (q15_t)0x7b7e, (q15_t)0xde56, (q15_t)0x7b7c, (q15_t)0xde50, (q15_t)0x7b7a, (q15_t)0xde4a, (q15_t)0x7b79, (q15_t)0xde44, + (q15_t)0x7b77, (q15_t)0xde3e, (q15_t)0x7b76, (q15_t)0xde38, (q15_t)0x7b74, (q15_t)0xde32, (q15_t)0x7b72, (q15_t)0xde2c, + (q15_t)0x7b71, (q15_t)0xde26, (q15_t)0x7b6f, (q15_t)0xde1f, (q15_t)0x7b6d, (q15_t)0xde19, (q15_t)0x7b6c, (q15_t)0xde13, + (q15_t)0x7b6a, (q15_t)0xde0d, (q15_t)0x7b68, (q15_t)0xde07, (q15_t)0x7b67, (q15_t)0xde01, (q15_t)0x7b65, (q15_t)0xddfb, + (q15_t)0x7b63, (q15_t)0xddf5, (q15_t)0x7b62, (q15_t)0xddef, (q15_t)0x7b60, (q15_t)0xdde9, (q15_t)0x7b5e, (q15_t)0xdde3, + (q15_t)0x7b5d, (q15_t)0xdddd, (q15_t)0x7b5b, (q15_t)0xddd7, (q15_t)0x7b59, (q15_t)0xddd1, (q15_t)0x7b57, (q15_t)0xddcb, + (q15_t)0x7b56, (q15_t)0xddc5, (q15_t)0x7b54, (q15_t)0xddbf, (q15_t)0x7b52, (q15_t)0xddb9, (q15_t)0x7b51, (q15_t)0xddb2, + (q15_t)0x7b4f, (q15_t)0xddac, (q15_t)0x7b4d, (q15_t)0xdda6, (q15_t)0x7b4c, (q15_t)0xdda0, (q15_t)0x7b4a, (q15_t)0xdd9a, + (q15_t)0x7b48, (q15_t)0xdd94, (q15_t)0x7b47, (q15_t)0xdd8e, (q15_t)0x7b45, (q15_t)0xdd88, (q15_t)0x7b43, (q15_t)0xdd82, + (q15_t)0x7b42, (q15_t)0xdd7c, (q15_t)0x7b40, (q15_t)0xdd76, (q15_t)0x7b3e, (q15_t)0xdd70, (q15_t)0x7b3c, (q15_t)0xdd6a, + (q15_t)0x7b3b, (q15_t)0xdd64, (q15_t)0x7b39, (q15_t)0xdd5e, (q15_t)0x7b37, (q15_t)0xdd58, (q15_t)0x7b36, (q15_t)0xdd52, + (q15_t)0x7b34, (q15_t)0xdd4c, (q15_t)0x7b32, (q15_t)0xdd46, (q15_t)0x7b31, (q15_t)0xdd40, (q15_t)0x7b2f, (q15_t)0xdd39, + (q15_t)0x7b2d, (q15_t)0xdd33, (q15_t)0x7b2b, (q15_t)0xdd2d, (q15_t)0x7b2a, (q15_t)0xdd27, (q15_t)0x7b28, (q15_t)0xdd21, + (q15_t)0x7b26, (q15_t)0xdd1b, (q15_t)0x7b25, (q15_t)0xdd15, (q15_t)0x7b23, (q15_t)0xdd0f, (q15_t)0x7b21, (q15_t)0xdd09, + (q15_t)0x7b1f, (q15_t)0xdd03, (q15_t)0x7b1e, (q15_t)0xdcfd, (q15_t)0x7b1c, (q15_t)0xdcf7, (q15_t)0x7b1a, (q15_t)0xdcf1, + (q15_t)0x7b19, (q15_t)0xdceb, (q15_t)0x7b17, (q15_t)0xdce5, (q15_t)0x7b15, (q15_t)0xdcdf, (q15_t)0x7b13, (q15_t)0xdcd9, + (q15_t)0x7b12, (q15_t)0xdcd3, (q15_t)0x7b10, (q15_t)0xdccd, (q15_t)0x7b0e, (q15_t)0xdcc7, (q15_t)0x7b0c, (q15_t)0xdcc1, + (q15_t)0x7b0b, (q15_t)0xdcbb, (q15_t)0x7b09, (q15_t)0xdcb5, (q15_t)0x7b07, (q15_t)0xdcae, (q15_t)0x7b06, (q15_t)0xdca8, + (q15_t)0x7b04, (q15_t)0xdca2, (q15_t)0x7b02, (q15_t)0xdc9c, (q15_t)0x7b00, (q15_t)0xdc96, (q15_t)0x7aff, (q15_t)0xdc90, + (q15_t)0x7afd, (q15_t)0xdc8a, (q15_t)0x7afb, (q15_t)0xdc84, (q15_t)0x7af9, (q15_t)0xdc7e, (q15_t)0x7af8, (q15_t)0xdc78, + (q15_t)0x7af6, (q15_t)0xdc72, (q15_t)0x7af4, (q15_t)0xdc6c, (q15_t)0x7af2, (q15_t)0xdc66, (q15_t)0x7af1, (q15_t)0xdc60, + (q15_t)0x7aef, (q15_t)0xdc5a, (q15_t)0x7aed, (q15_t)0xdc54, (q15_t)0x7aeb, (q15_t)0xdc4e, (q15_t)0x7aea, (q15_t)0xdc48, + (q15_t)0x7ae8, (q15_t)0xdc42, (q15_t)0x7ae6, (q15_t)0xdc3c, (q15_t)0x7ae4, (q15_t)0xdc36, (q15_t)0x7ae3, (q15_t)0xdc30, + (q15_t)0x7ae1, (q15_t)0xdc2a, (q15_t)0x7adf, (q15_t)0xdc24, (q15_t)0x7add, (q15_t)0xdc1e, (q15_t)0x7adc, (q15_t)0xdc18, + (q15_t)0x7ada, (q15_t)0xdc12, (q15_t)0x7ad8, (q15_t)0xdc0c, (q15_t)0x7ad6, (q15_t)0xdc06, (q15_t)0x7ad5, (q15_t)0xdbff, + (q15_t)0x7ad3, (q15_t)0xdbf9, (q15_t)0x7ad1, (q15_t)0xdbf3, (q15_t)0x7acf, (q15_t)0xdbed, (q15_t)0x7acd, (q15_t)0xdbe7, + (q15_t)0x7acc, (q15_t)0xdbe1, (q15_t)0x7aca, (q15_t)0xdbdb, (q15_t)0x7ac8, (q15_t)0xdbd5, (q15_t)0x7ac6, (q15_t)0xdbcf, + (q15_t)0x7ac5, (q15_t)0xdbc9, (q15_t)0x7ac3, (q15_t)0xdbc3, (q15_t)0x7ac1, (q15_t)0xdbbd, (q15_t)0x7abf, (q15_t)0xdbb7, + (q15_t)0x7abd, (q15_t)0xdbb1, (q15_t)0x7abc, (q15_t)0xdbab, (q15_t)0x7aba, (q15_t)0xdba5, (q15_t)0x7ab8, (q15_t)0xdb9f, + (q15_t)0x7ab6, (q15_t)0xdb99, (q15_t)0x7ab5, (q15_t)0xdb93, (q15_t)0x7ab3, (q15_t)0xdb8d, (q15_t)0x7ab1, (q15_t)0xdb87, + (q15_t)0x7aaf, (q15_t)0xdb81, (q15_t)0x7aad, (q15_t)0xdb7b, (q15_t)0x7aac, (q15_t)0xdb75, (q15_t)0x7aaa, (q15_t)0xdb6f, + (q15_t)0x7aa8, (q15_t)0xdb69, (q15_t)0x7aa6, (q15_t)0xdb63, (q15_t)0x7aa4, (q15_t)0xdb5d, (q15_t)0x7aa3, (q15_t)0xdb57, + (q15_t)0x7aa1, (q15_t)0xdb51, (q15_t)0x7a9f, (q15_t)0xdb4b, (q15_t)0x7a9d, (q15_t)0xdb45, (q15_t)0x7a9b, (q15_t)0xdb3f, + (q15_t)0x7a9a, (q15_t)0xdb39, (q15_t)0x7a98, (q15_t)0xdb33, (q15_t)0x7a96, (q15_t)0xdb2d, (q15_t)0x7a94, (q15_t)0xdb27, + (q15_t)0x7a92, (q15_t)0xdb21, (q15_t)0x7a91, (q15_t)0xdb1b, (q15_t)0x7a8f, (q15_t)0xdb15, (q15_t)0x7a8d, (q15_t)0xdb0f, + (q15_t)0x7a8b, (q15_t)0xdb09, (q15_t)0x7a89, (q15_t)0xdb03, (q15_t)0x7a87, (q15_t)0xdafd, (q15_t)0x7a86, (q15_t)0xdaf7, + (q15_t)0x7a84, (q15_t)0xdaf1, (q15_t)0x7a82, (q15_t)0xdaea, (q15_t)0x7a80, (q15_t)0xdae4, (q15_t)0x7a7e, (q15_t)0xdade, + (q15_t)0x7a7d, (q15_t)0xdad8, (q15_t)0x7a7b, (q15_t)0xdad2, (q15_t)0x7a79, (q15_t)0xdacc, (q15_t)0x7a77, (q15_t)0xdac6, + (q15_t)0x7a75, (q15_t)0xdac0, (q15_t)0x7a73, (q15_t)0xdaba, (q15_t)0x7a72, (q15_t)0xdab4, (q15_t)0x7a70, (q15_t)0xdaae, + (q15_t)0x7a6e, (q15_t)0xdaa8, (q15_t)0x7a6c, (q15_t)0xdaa2, (q15_t)0x7a6a, (q15_t)0xda9c, (q15_t)0x7a68, (q15_t)0xda96, + (q15_t)0x7a67, (q15_t)0xda90, (q15_t)0x7a65, (q15_t)0xda8a, (q15_t)0x7a63, (q15_t)0xda84, (q15_t)0x7a61, (q15_t)0xda7e, + (q15_t)0x7a5f, (q15_t)0xda78, (q15_t)0x7a5d, (q15_t)0xda72, (q15_t)0x7a5c, (q15_t)0xda6c, (q15_t)0x7a5a, (q15_t)0xda66, + (q15_t)0x7a58, (q15_t)0xda60, (q15_t)0x7a56, (q15_t)0xda5a, (q15_t)0x7a54, (q15_t)0xda54, (q15_t)0x7a52, (q15_t)0xda4e, + (q15_t)0x7a50, (q15_t)0xda48, (q15_t)0x7a4f, (q15_t)0xda42, (q15_t)0x7a4d, (q15_t)0xda3c, (q15_t)0x7a4b, (q15_t)0xda36, + (q15_t)0x7a49, (q15_t)0xda30, (q15_t)0x7a47, (q15_t)0xda2a, (q15_t)0x7a45, (q15_t)0xda24, (q15_t)0x7a43, (q15_t)0xda1e, + (q15_t)0x7a42, (q15_t)0xda18, (q15_t)0x7a40, (q15_t)0xda12, (q15_t)0x7a3e, (q15_t)0xda0c, (q15_t)0x7a3c, (q15_t)0xda06, + (q15_t)0x7a3a, (q15_t)0xda00, (q15_t)0x7a38, (q15_t)0xd9fa, (q15_t)0x7a36, (q15_t)0xd9f4, (q15_t)0x7a35, (q15_t)0xd9ee, + (q15_t)0x7a33, (q15_t)0xd9e8, (q15_t)0x7a31, (q15_t)0xd9e2, (q15_t)0x7a2f, (q15_t)0xd9dc, (q15_t)0x7a2d, (q15_t)0xd9d6, + (q15_t)0x7a2b, (q15_t)0xd9d0, (q15_t)0x7a29, (q15_t)0xd9ca, (q15_t)0x7a27, (q15_t)0xd9c4, (q15_t)0x7a26, (q15_t)0xd9be, + (q15_t)0x7a24, (q15_t)0xd9b8, (q15_t)0x7a22, (q15_t)0xd9b2, (q15_t)0x7a20, (q15_t)0xd9ac, (q15_t)0x7a1e, (q15_t)0xd9a6, + (q15_t)0x7a1c, (q15_t)0xd9a0, (q15_t)0x7a1a, (q15_t)0xd99a, (q15_t)0x7a18, (q15_t)0xd994, (q15_t)0x7a16, (q15_t)0xd98e, + (q15_t)0x7a15, (q15_t)0xd988, (q15_t)0x7a13, (q15_t)0xd982, (q15_t)0x7a11, (q15_t)0xd97c, (q15_t)0x7a0f, (q15_t)0xd976, + (q15_t)0x7a0d, (q15_t)0xd970, (q15_t)0x7a0b, (q15_t)0xd96a, (q15_t)0x7a09, (q15_t)0xd964, (q15_t)0x7a07, (q15_t)0xd95e, + (q15_t)0x7a05, (q15_t)0xd958, (q15_t)0x7a04, (q15_t)0xd952, (q15_t)0x7a02, (q15_t)0xd94c, (q15_t)0x7a00, (q15_t)0xd946, + (q15_t)0x79fe, (q15_t)0xd940, (q15_t)0x79fc, (q15_t)0xd93a, (q15_t)0x79fa, (q15_t)0xd934, (q15_t)0x79f8, (q15_t)0xd92e, + (q15_t)0x79f6, (q15_t)0xd928, (q15_t)0x79f4, (q15_t)0xd922, (q15_t)0x79f2, (q15_t)0xd91c, (q15_t)0x79f0, (q15_t)0xd917, + (q15_t)0x79ef, (q15_t)0xd911, (q15_t)0x79ed, (q15_t)0xd90b, (q15_t)0x79eb, (q15_t)0xd905, (q15_t)0x79e9, (q15_t)0xd8ff, + (q15_t)0x79e7, (q15_t)0xd8f9, (q15_t)0x79e5, (q15_t)0xd8f3, (q15_t)0x79e3, (q15_t)0xd8ed, (q15_t)0x79e1, (q15_t)0xd8e7, + (q15_t)0x79df, (q15_t)0xd8e1, (q15_t)0x79dd, (q15_t)0xd8db, (q15_t)0x79db, (q15_t)0xd8d5, (q15_t)0x79d9, (q15_t)0xd8cf, + (q15_t)0x79d8, (q15_t)0xd8c9, (q15_t)0x79d6, (q15_t)0xd8c3, (q15_t)0x79d4, (q15_t)0xd8bd, (q15_t)0x79d2, (q15_t)0xd8b7, + (q15_t)0x79d0, (q15_t)0xd8b1, (q15_t)0x79ce, (q15_t)0xd8ab, (q15_t)0x79cc, (q15_t)0xd8a5, (q15_t)0x79ca, (q15_t)0xd89f, + (q15_t)0x79c8, (q15_t)0xd899, (q15_t)0x79c6, (q15_t)0xd893, (q15_t)0x79c4, (q15_t)0xd88d, (q15_t)0x79c2, (q15_t)0xd887, + (q15_t)0x79c0, (q15_t)0xd881, (q15_t)0x79be, (q15_t)0xd87b, (q15_t)0x79bc, (q15_t)0xd875, (q15_t)0x79bb, (q15_t)0xd86f, + (q15_t)0x79b9, (q15_t)0xd869, (q15_t)0x79b7, (q15_t)0xd863, (q15_t)0x79b5, (q15_t)0xd85d, (q15_t)0x79b3, (q15_t)0xd857, + (q15_t)0x79b1, (q15_t)0xd851, (q15_t)0x79af, (q15_t)0xd84b, (q15_t)0x79ad, (q15_t)0xd845, (q15_t)0x79ab, (q15_t)0xd83f, + (q15_t)0x79a9, (q15_t)0xd839, (q15_t)0x79a7, (q15_t)0xd833, (q15_t)0x79a5, (q15_t)0xd82d, (q15_t)0x79a3, (q15_t)0xd827, + (q15_t)0x79a1, (q15_t)0xd821, (q15_t)0x799f, (q15_t)0xd81b, (q15_t)0x799d, (q15_t)0xd815, (q15_t)0x799b, (q15_t)0xd80f, + (q15_t)0x7999, (q15_t)0xd80a, (q15_t)0x7997, (q15_t)0xd804, (q15_t)0x7995, (q15_t)0xd7fe, (q15_t)0x7993, (q15_t)0xd7f8, + (q15_t)0x7992, (q15_t)0xd7f2, (q15_t)0x7990, (q15_t)0xd7ec, (q15_t)0x798e, (q15_t)0xd7e6, (q15_t)0x798c, (q15_t)0xd7e0, + (q15_t)0x798a, (q15_t)0xd7da, (q15_t)0x7988, (q15_t)0xd7d4, (q15_t)0x7986, (q15_t)0xd7ce, (q15_t)0x7984, (q15_t)0xd7c8, + (q15_t)0x7982, (q15_t)0xd7c2, (q15_t)0x7980, (q15_t)0xd7bc, (q15_t)0x797e, (q15_t)0xd7b6, (q15_t)0x797c, (q15_t)0xd7b0, + (q15_t)0x797a, (q15_t)0xd7aa, (q15_t)0x7978, (q15_t)0xd7a4, (q15_t)0x7976, (q15_t)0xd79e, (q15_t)0x7974, (q15_t)0xd798, + (q15_t)0x7972, (q15_t)0xd792, (q15_t)0x7970, (q15_t)0xd78c, (q15_t)0x796e, (q15_t)0xd786, (q15_t)0x796c, (q15_t)0xd780, + (q15_t)0x796a, (q15_t)0xd77a, (q15_t)0x7968, (q15_t)0xd774, (q15_t)0x7966, (q15_t)0xd76e, (q15_t)0x7964, (q15_t)0xd768, + (q15_t)0x7962, (q15_t)0xd763, (q15_t)0x7960, (q15_t)0xd75d, (q15_t)0x795e, (q15_t)0xd757, (q15_t)0x795c, (q15_t)0xd751, + (q15_t)0x795a, (q15_t)0xd74b, (q15_t)0x7958, (q15_t)0xd745, (q15_t)0x7956, (q15_t)0xd73f, (q15_t)0x7954, (q15_t)0xd739, + (q15_t)0x7952, (q15_t)0xd733, (q15_t)0x7950, (q15_t)0xd72d, (q15_t)0x794e, (q15_t)0xd727, (q15_t)0x794c, (q15_t)0xd721, + (q15_t)0x794a, (q15_t)0xd71b, (q15_t)0x7948, (q15_t)0xd715, (q15_t)0x7946, (q15_t)0xd70f, (q15_t)0x7944, (q15_t)0xd709, + (q15_t)0x7942, (q15_t)0xd703, (q15_t)0x7940, (q15_t)0xd6fd, (q15_t)0x793e, (q15_t)0xd6f7, (q15_t)0x793c, (q15_t)0xd6f1, + (q15_t)0x793a, (q15_t)0xd6eb, (q15_t)0x7938, (q15_t)0xd6e5, (q15_t)0x7936, (q15_t)0xd6e0, (q15_t)0x7934, (q15_t)0xd6da, + (q15_t)0x7932, (q15_t)0xd6d4, (q15_t)0x7930, (q15_t)0xd6ce, (q15_t)0x792e, (q15_t)0xd6c8, (q15_t)0x792c, (q15_t)0xd6c2, + (q15_t)0x792a, (q15_t)0xd6bc, (q15_t)0x7928, (q15_t)0xd6b6, (q15_t)0x7926, (q15_t)0xd6b0, (q15_t)0x7924, (q15_t)0xd6aa, + (q15_t)0x7922, (q15_t)0xd6a4, (q15_t)0x7920, (q15_t)0xd69e, (q15_t)0x791e, (q15_t)0xd698, (q15_t)0x791c, (q15_t)0xd692, + (q15_t)0x7919, (q15_t)0xd68c, (q15_t)0x7917, (q15_t)0xd686, (q15_t)0x7915, (q15_t)0xd680, (q15_t)0x7913, (q15_t)0xd67a, + (q15_t)0x7911, (q15_t)0xd675, (q15_t)0x790f, (q15_t)0xd66f, (q15_t)0x790d, (q15_t)0xd669, (q15_t)0x790b, (q15_t)0xd663, + (q15_t)0x7909, (q15_t)0xd65d, (q15_t)0x7907, (q15_t)0xd657, (q15_t)0x7905, (q15_t)0xd651, (q15_t)0x7903, (q15_t)0xd64b, + (q15_t)0x7901, (q15_t)0xd645, (q15_t)0x78ff, (q15_t)0xd63f, (q15_t)0x78fd, (q15_t)0xd639, (q15_t)0x78fb, (q15_t)0xd633, + (q15_t)0x78f9, (q15_t)0xd62d, (q15_t)0x78f7, (q15_t)0xd627, (q15_t)0x78f5, (q15_t)0xd621, (q15_t)0x78f3, (q15_t)0xd61b, + (q15_t)0x78f1, (q15_t)0xd615, (q15_t)0x78ee, (q15_t)0xd610, (q15_t)0x78ec, (q15_t)0xd60a, (q15_t)0x78ea, (q15_t)0xd604, + (q15_t)0x78e8, (q15_t)0xd5fe, (q15_t)0x78e6, (q15_t)0xd5f8, (q15_t)0x78e4, (q15_t)0xd5f2, (q15_t)0x78e2, (q15_t)0xd5ec, + (q15_t)0x78e0, (q15_t)0xd5e6, (q15_t)0x78de, (q15_t)0xd5e0, (q15_t)0x78dc, (q15_t)0xd5da, (q15_t)0x78da, (q15_t)0xd5d4, + (q15_t)0x78d8, (q15_t)0xd5ce, (q15_t)0x78d6, (q15_t)0xd5c8, (q15_t)0x78d4, (q15_t)0xd5c2, (q15_t)0x78d2, (q15_t)0xd5bc, + (q15_t)0x78cf, (q15_t)0xd5b7, (q15_t)0x78cd, (q15_t)0xd5b1, (q15_t)0x78cb, (q15_t)0xd5ab, (q15_t)0x78c9, (q15_t)0xd5a5, + (q15_t)0x78c7, (q15_t)0xd59f, (q15_t)0x78c5, (q15_t)0xd599, (q15_t)0x78c3, (q15_t)0xd593, (q15_t)0x78c1, (q15_t)0xd58d, + (q15_t)0x78bf, (q15_t)0xd587, (q15_t)0x78bd, (q15_t)0xd581, (q15_t)0x78bb, (q15_t)0xd57b, (q15_t)0x78b9, (q15_t)0xd575, + (q15_t)0x78b6, (q15_t)0xd56f, (q15_t)0x78b4, (q15_t)0xd569, (q15_t)0x78b2, (q15_t)0xd564, (q15_t)0x78b0, (q15_t)0xd55e, + (q15_t)0x78ae, (q15_t)0xd558, (q15_t)0x78ac, (q15_t)0xd552, (q15_t)0x78aa, (q15_t)0xd54c, (q15_t)0x78a8, (q15_t)0xd546, + (q15_t)0x78a6, (q15_t)0xd540, (q15_t)0x78a4, (q15_t)0xd53a, (q15_t)0x78a2, (q15_t)0xd534, (q15_t)0x789f, (q15_t)0xd52e, + (q15_t)0x789d, (q15_t)0xd528, (q15_t)0x789b, (q15_t)0xd522, (q15_t)0x7899, (q15_t)0xd51c, (q15_t)0x7897, (q15_t)0xd517, + (q15_t)0x7895, (q15_t)0xd511, (q15_t)0x7893, (q15_t)0xd50b, (q15_t)0x7891, (q15_t)0xd505, (q15_t)0x788f, (q15_t)0xd4ff, + (q15_t)0x788c, (q15_t)0xd4f9, (q15_t)0x788a, (q15_t)0xd4f3, (q15_t)0x7888, (q15_t)0xd4ed, (q15_t)0x7886, (q15_t)0xd4e7, + (q15_t)0x7884, (q15_t)0xd4e1, (q15_t)0x7882, (q15_t)0xd4db, (q15_t)0x7880, (q15_t)0xd4d5, (q15_t)0x787e, (q15_t)0xd4d0, + (q15_t)0x787c, (q15_t)0xd4ca, (q15_t)0x7879, (q15_t)0xd4c4, (q15_t)0x7877, (q15_t)0xd4be, (q15_t)0x7875, (q15_t)0xd4b8, + (q15_t)0x7873, (q15_t)0xd4b2, (q15_t)0x7871, (q15_t)0xd4ac, (q15_t)0x786f, (q15_t)0xd4a6, (q15_t)0x786d, (q15_t)0xd4a0, + (q15_t)0x786b, (q15_t)0xd49a, (q15_t)0x7868, (q15_t)0xd494, (q15_t)0x7866, (q15_t)0xd48f, (q15_t)0x7864, (q15_t)0xd489, + (q15_t)0x7862, (q15_t)0xd483, (q15_t)0x7860, (q15_t)0xd47d, (q15_t)0x785e, (q15_t)0xd477, (q15_t)0x785c, (q15_t)0xd471, + (q15_t)0x7859, (q15_t)0xd46b, (q15_t)0x7857, (q15_t)0xd465, (q15_t)0x7855, (q15_t)0xd45f, (q15_t)0x7853, (q15_t)0xd459, + (q15_t)0x7851, (q15_t)0xd453, (q15_t)0x784f, (q15_t)0xd44e, (q15_t)0x784d, (q15_t)0xd448, (q15_t)0x784a, (q15_t)0xd442, + (q15_t)0x7848, (q15_t)0xd43c, (q15_t)0x7846, (q15_t)0xd436, (q15_t)0x7844, (q15_t)0xd430, (q15_t)0x7842, (q15_t)0xd42a, + (q15_t)0x7840, (q15_t)0xd424, (q15_t)0x783e, (q15_t)0xd41e, (q15_t)0x783b, (q15_t)0xd418, (q15_t)0x7839, (q15_t)0xd412, + (q15_t)0x7837, (q15_t)0xd40d, (q15_t)0x7835, (q15_t)0xd407, (q15_t)0x7833, (q15_t)0xd401, (q15_t)0x7831, (q15_t)0xd3fb, + (q15_t)0x782e, (q15_t)0xd3f5, (q15_t)0x782c, (q15_t)0xd3ef, (q15_t)0x782a, (q15_t)0xd3e9, (q15_t)0x7828, (q15_t)0xd3e3, + (q15_t)0x7826, (q15_t)0xd3dd, (q15_t)0x7824, (q15_t)0xd3d7, (q15_t)0x7821, (q15_t)0xd3d2, (q15_t)0x781f, (q15_t)0xd3cc, + (q15_t)0x781d, (q15_t)0xd3c6, (q15_t)0x781b, (q15_t)0xd3c0, (q15_t)0x7819, (q15_t)0xd3ba, (q15_t)0x7817, (q15_t)0xd3b4, + (q15_t)0x7814, (q15_t)0xd3ae, (q15_t)0x7812, (q15_t)0xd3a8, (q15_t)0x7810, (q15_t)0xd3a2, (q15_t)0x780e, (q15_t)0xd39d, + (q15_t)0x780c, (q15_t)0xd397, (q15_t)0x780a, (q15_t)0xd391, (q15_t)0x7807, (q15_t)0xd38b, (q15_t)0x7805, (q15_t)0xd385, + (q15_t)0x7803, (q15_t)0xd37f, (q15_t)0x7801, (q15_t)0xd379, (q15_t)0x77ff, (q15_t)0xd373, (q15_t)0x77fc, (q15_t)0xd36d, + (q15_t)0x77fa, (q15_t)0xd368, (q15_t)0x77f8, (q15_t)0xd362, (q15_t)0x77f6, (q15_t)0xd35c, (q15_t)0x77f4, (q15_t)0xd356, + (q15_t)0x77f1, (q15_t)0xd350, (q15_t)0x77ef, (q15_t)0xd34a, (q15_t)0x77ed, (q15_t)0xd344, (q15_t)0x77eb, (q15_t)0xd33e, + (q15_t)0x77e9, (q15_t)0xd338, (q15_t)0x77e6, (q15_t)0xd333, (q15_t)0x77e4, (q15_t)0xd32d, (q15_t)0x77e2, (q15_t)0xd327, + (q15_t)0x77e0, (q15_t)0xd321, (q15_t)0x77de, (q15_t)0xd31b, (q15_t)0x77db, (q15_t)0xd315, (q15_t)0x77d9, (q15_t)0xd30f, + (q15_t)0x77d7, (q15_t)0xd309, (q15_t)0x77d5, (q15_t)0xd303, (q15_t)0x77d3, (q15_t)0xd2fe, (q15_t)0x77d0, (q15_t)0xd2f8, + (q15_t)0x77ce, (q15_t)0xd2f2, (q15_t)0x77cc, (q15_t)0xd2ec, (q15_t)0x77ca, (q15_t)0xd2e6, (q15_t)0x77c8, (q15_t)0xd2e0, + (q15_t)0x77c5, (q15_t)0xd2da, (q15_t)0x77c3, (q15_t)0xd2d4, (q15_t)0x77c1, (q15_t)0xd2cf, (q15_t)0x77bf, (q15_t)0xd2c9, + (q15_t)0x77bc, (q15_t)0xd2c3, (q15_t)0x77ba, (q15_t)0xd2bd, (q15_t)0x77b8, (q15_t)0xd2b7, (q15_t)0x77b6, (q15_t)0xd2b1, + (q15_t)0x77b4, (q15_t)0xd2ab, (q15_t)0x77b1, (q15_t)0xd2a5, (q15_t)0x77af, (q15_t)0xd2a0, (q15_t)0x77ad, (q15_t)0xd29a, + (q15_t)0x77ab, (q15_t)0xd294, (q15_t)0x77a8, (q15_t)0xd28e, (q15_t)0x77a6, (q15_t)0xd288, (q15_t)0x77a4, (q15_t)0xd282, + (q15_t)0x77a2, (q15_t)0xd27c, (q15_t)0x77a0, (q15_t)0xd276, (q15_t)0x779d, (q15_t)0xd271, (q15_t)0x779b, (q15_t)0xd26b, + (q15_t)0x7799, (q15_t)0xd265, (q15_t)0x7797, (q15_t)0xd25f, (q15_t)0x7794, (q15_t)0xd259, (q15_t)0x7792, (q15_t)0xd253, + (q15_t)0x7790, (q15_t)0xd24d, (q15_t)0x778e, (q15_t)0xd247, (q15_t)0x778b, (q15_t)0xd242, (q15_t)0x7789, (q15_t)0xd23c, + (q15_t)0x7787, (q15_t)0xd236, (q15_t)0x7785, (q15_t)0xd230, (q15_t)0x7782, (q15_t)0xd22a, (q15_t)0x7780, (q15_t)0xd224, + (q15_t)0x777e, (q15_t)0xd21e, (q15_t)0x777c, (q15_t)0xd219, (q15_t)0x7779, (q15_t)0xd213, (q15_t)0x7777, (q15_t)0xd20d, + (q15_t)0x7775, (q15_t)0xd207, (q15_t)0x7773, (q15_t)0xd201, (q15_t)0x7770, (q15_t)0xd1fb, (q15_t)0x776e, (q15_t)0xd1f5, + (q15_t)0x776c, (q15_t)0xd1ef, (q15_t)0x776a, (q15_t)0xd1ea, (q15_t)0x7767, (q15_t)0xd1e4, (q15_t)0x7765, (q15_t)0xd1de, + (q15_t)0x7763, (q15_t)0xd1d8, (q15_t)0x7760, (q15_t)0xd1d2, (q15_t)0x775e, (q15_t)0xd1cc, (q15_t)0x775c, (q15_t)0xd1c6, + (q15_t)0x775a, (q15_t)0xd1c1, (q15_t)0x7757, (q15_t)0xd1bb, (q15_t)0x7755, (q15_t)0xd1b5, (q15_t)0x7753, (q15_t)0xd1af, + (q15_t)0x7751, (q15_t)0xd1a9, (q15_t)0x774e, (q15_t)0xd1a3, (q15_t)0x774c, (q15_t)0xd19d, (q15_t)0x774a, (q15_t)0xd198, + (q15_t)0x7747, (q15_t)0xd192, (q15_t)0x7745, (q15_t)0xd18c, (q15_t)0x7743, (q15_t)0xd186, (q15_t)0x7741, (q15_t)0xd180, + (q15_t)0x773e, (q15_t)0xd17a, (q15_t)0x773c, (q15_t)0xd174, (q15_t)0x773a, (q15_t)0xd16f, (q15_t)0x7738, (q15_t)0xd169, + (q15_t)0x7735, (q15_t)0xd163, (q15_t)0x7733, (q15_t)0xd15d, (q15_t)0x7731, (q15_t)0xd157, (q15_t)0x772e, (q15_t)0xd151, + (q15_t)0x772c, (q15_t)0xd14b, (q15_t)0x772a, (q15_t)0xd146, (q15_t)0x7727, (q15_t)0xd140, (q15_t)0x7725, (q15_t)0xd13a, + (q15_t)0x7723, (q15_t)0xd134, (q15_t)0x7721, (q15_t)0xd12e, (q15_t)0x771e, (q15_t)0xd128, (q15_t)0x771c, (q15_t)0xd123, + (q15_t)0x771a, (q15_t)0xd11d, (q15_t)0x7717, (q15_t)0xd117, (q15_t)0x7715, (q15_t)0xd111, (q15_t)0x7713, (q15_t)0xd10b, + (q15_t)0x7710, (q15_t)0xd105, (q15_t)0x770e, (q15_t)0xd0ff, (q15_t)0x770c, (q15_t)0xd0fa, (q15_t)0x770a, (q15_t)0xd0f4, + (q15_t)0x7707, (q15_t)0xd0ee, (q15_t)0x7705, (q15_t)0xd0e8, (q15_t)0x7703, (q15_t)0xd0e2, (q15_t)0x7700, (q15_t)0xd0dc, + (q15_t)0x76fe, (q15_t)0xd0d7, (q15_t)0x76fc, (q15_t)0xd0d1, (q15_t)0x76f9, (q15_t)0xd0cb, (q15_t)0x76f7, (q15_t)0xd0c5, + (q15_t)0x76f5, (q15_t)0xd0bf, (q15_t)0x76f2, (q15_t)0xd0b9, (q15_t)0x76f0, (q15_t)0xd0b4, (q15_t)0x76ee, (q15_t)0xd0ae, + (q15_t)0x76eb, (q15_t)0xd0a8, (q15_t)0x76e9, (q15_t)0xd0a2, (q15_t)0x76e7, (q15_t)0xd09c, (q15_t)0x76e4, (q15_t)0xd096, + (q15_t)0x76e2, (q15_t)0xd091, (q15_t)0x76e0, (q15_t)0xd08b, (q15_t)0x76dd, (q15_t)0xd085, (q15_t)0x76db, (q15_t)0xd07f, + (q15_t)0x76d9, (q15_t)0xd079, (q15_t)0x76d6, (q15_t)0xd073, (q15_t)0x76d4, (q15_t)0xd06e, (q15_t)0x76d2, (q15_t)0xd068, + (q15_t)0x76cf, (q15_t)0xd062, (q15_t)0x76cd, (q15_t)0xd05c, (q15_t)0x76cb, (q15_t)0xd056, (q15_t)0x76c8, (q15_t)0xd050, + (q15_t)0x76c6, (q15_t)0xd04b, (q15_t)0x76c4, (q15_t)0xd045, (q15_t)0x76c1, (q15_t)0xd03f, (q15_t)0x76bf, (q15_t)0xd039, + (q15_t)0x76bd, (q15_t)0xd033, (q15_t)0x76ba, (q15_t)0xd02d, (q15_t)0x76b8, (q15_t)0xd028, (q15_t)0x76b6, (q15_t)0xd022, + (q15_t)0x76b3, (q15_t)0xd01c, (q15_t)0x76b1, (q15_t)0xd016, (q15_t)0x76af, (q15_t)0xd010, (q15_t)0x76ac, (q15_t)0xd00a, + (q15_t)0x76aa, (q15_t)0xd005, (q15_t)0x76a8, (q15_t)0xcfff, (q15_t)0x76a5, (q15_t)0xcff9, (q15_t)0x76a3, (q15_t)0xcff3, + (q15_t)0x76a0, (q15_t)0xcfed, (q15_t)0x769e, (q15_t)0xcfe7, (q15_t)0x769c, (q15_t)0xcfe2, (q15_t)0x7699, (q15_t)0xcfdc, + (q15_t)0x7697, (q15_t)0xcfd6, (q15_t)0x7695, (q15_t)0xcfd0, (q15_t)0x7692, (q15_t)0xcfca, (q15_t)0x7690, (q15_t)0xcfc5, + (q15_t)0x768e, (q15_t)0xcfbf, (q15_t)0x768b, (q15_t)0xcfb9, (q15_t)0x7689, (q15_t)0xcfb3, (q15_t)0x7686, (q15_t)0xcfad, + (q15_t)0x7684, (q15_t)0xcfa7, (q15_t)0x7682, (q15_t)0xcfa2, (q15_t)0x767f, (q15_t)0xcf9c, (q15_t)0x767d, (q15_t)0xcf96, + (q15_t)0x767b, (q15_t)0xcf90, (q15_t)0x7678, (q15_t)0xcf8a, (q15_t)0x7676, (q15_t)0xcf85, (q15_t)0x7673, (q15_t)0xcf7f, + (q15_t)0x7671, (q15_t)0xcf79, (q15_t)0x766f, (q15_t)0xcf73, (q15_t)0x766c, (q15_t)0xcf6d, (q15_t)0x766a, (q15_t)0xcf67, + (q15_t)0x7668, (q15_t)0xcf62, (q15_t)0x7665, (q15_t)0xcf5c, (q15_t)0x7663, (q15_t)0xcf56, (q15_t)0x7660, (q15_t)0xcf50, + (q15_t)0x765e, (q15_t)0xcf4a, (q15_t)0x765c, (q15_t)0xcf45, (q15_t)0x7659, (q15_t)0xcf3f, (q15_t)0x7657, (q15_t)0xcf39, + (q15_t)0x7654, (q15_t)0xcf33, (q15_t)0x7652, (q15_t)0xcf2d, (q15_t)0x7650, (q15_t)0xcf28, (q15_t)0x764d, (q15_t)0xcf22, + (q15_t)0x764b, (q15_t)0xcf1c, (q15_t)0x7648, (q15_t)0xcf16, (q15_t)0x7646, (q15_t)0xcf10, (q15_t)0x7644, (q15_t)0xcf0b, + (q15_t)0x7641, (q15_t)0xcf05, (q15_t)0x763f, (q15_t)0xceff, (q15_t)0x763c, (q15_t)0xcef9, (q15_t)0x763a, (q15_t)0xcef3, + (q15_t)0x7638, (q15_t)0xceee, (q15_t)0x7635, (q15_t)0xcee8, (q15_t)0x7633, (q15_t)0xcee2, (q15_t)0x7630, (q15_t)0xcedc, + (q15_t)0x762e, (q15_t)0xced6, (q15_t)0x762b, (q15_t)0xced1, (q15_t)0x7629, (q15_t)0xcecb, (q15_t)0x7627, (q15_t)0xcec5, + (q15_t)0x7624, (q15_t)0xcebf, (q15_t)0x7622, (q15_t)0xceb9, (q15_t)0x761f, (q15_t)0xceb4, (q15_t)0x761d, (q15_t)0xceae, + (q15_t)0x761b, (q15_t)0xcea8, (q15_t)0x7618, (q15_t)0xcea2, (q15_t)0x7616, (q15_t)0xce9c, (q15_t)0x7613, (q15_t)0xce97, + (q15_t)0x7611, (q15_t)0xce91, (q15_t)0x760e, (q15_t)0xce8b, (q15_t)0x760c, (q15_t)0xce85, (q15_t)0x760a, (q15_t)0xce7f, + (q15_t)0x7607, (q15_t)0xce7a, (q15_t)0x7605, (q15_t)0xce74, (q15_t)0x7602, (q15_t)0xce6e, (q15_t)0x7600, (q15_t)0xce68, + (q15_t)0x75fd, (q15_t)0xce62, (q15_t)0x75fb, (q15_t)0xce5d, (q15_t)0x75f9, (q15_t)0xce57, (q15_t)0x75f6, (q15_t)0xce51, + (q15_t)0x75f4, (q15_t)0xce4b, (q15_t)0x75f1, (q15_t)0xce45, (q15_t)0x75ef, (q15_t)0xce40, (q15_t)0x75ec, (q15_t)0xce3a, + (q15_t)0x75ea, (q15_t)0xce34, (q15_t)0x75e7, (q15_t)0xce2e, (q15_t)0x75e5, (q15_t)0xce28, (q15_t)0x75e3, (q15_t)0xce23, + (q15_t)0x75e0, (q15_t)0xce1d, (q15_t)0x75de, (q15_t)0xce17, (q15_t)0x75db, (q15_t)0xce11, (q15_t)0x75d9, (q15_t)0xce0c, + (q15_t)0x75d6, (q15_t)0xce06, (q15_t)0x75d4, (q15_t)0xce00, (q15_t)0x75d1, (q15_t)0xcdfa, (q15_t)0x75cf, (q15_t)0xcdf4, + (q15_t)0x75cc, (q15_t)0xcdef, (q15_t)0x75ca, (q15_t)0xcde9, (q15_t)0x75c8, (q15_t)0xcde3, (q15_t)0x75c5, (q15_t)0xcddd, + (q15_t)0x75c3, (q15_t)0xcdd8, (q15_t)0x75c0, (q15_t)0xcdd2, (q15_t)0x75be, (q15_t)0xcdcc, (q15_t)0x75bb, (q15_t)0xcdc6, + (q15_t)0x75b9, (q15_t)0xcdc0, (q15_t)0x75b6, (q15_t)0xcdbb, (q15_t)0x75b4, (q15_t)0xcdb5, (q15_t)0x75b1, (q15_t)0xcdaf, + (q15_t)0x75af, (q15_t)0xcda9, (q15_t)0x75ac, (q15_t)0xcda3, (q15_t)0x75aa, (q15_t)0xcd9e, (q15_t)0x75a7, (q15_t)0xcd98, + (q15_t)0x75a5, (q15_t)0xcd92, (q15_t)0x75a3, (q15_t)0xcd8c, (q15_t)0x75a0, (q15_t)0xcd87, (q15_t)0x759e, (q15_t)0xcd81, + (q15_t)0x759b, (q15_t)0xcd7b, (q15_t)0x7599, (q15_t)0xcd75, (q15_t)0x7596, (q15_t)0xcd70, (q15_t)0x7594, (q15_t)0xcd6a, + (q15_t)0x7591, (q15_t)0xcd64, (q15_t)0x758f, (q15_t)0xcd5e, (q15_t)0x758c, (q15_t)0xcd58, (q15_t)0x758a, (q15_t)0xcd53, + (q15_t)0x7587, (q15_t)0xcd4d, (q15_t)0x7585, (q15_t)0xcd47, (q15_t)0x7582, (q15_t)0xcd41, (q15_t)0x7580, (q15_t)0xcd3c, + (q15_t)0x757d, (q15_t)0xcd36, (q15_t)0x757b, (q15_t)0xcd30, (q15_t)0x7578, (q15_t)0xcd2a, (q15_t)0x7576, (q15_t)0xcd25, + (q15_t)0x7573, (q15_t)0xcd1f, (q15_t)0x7571, (q15_t)0xcd19, (q15_t)0x756e, (q15_t)0xcd13, (q15_t)0x756c, (q15_t)0xcd0d, + (q15_t)0x7569, (q15_t)0xcd08, (q15_t)0x7567, (q15_t)0xcd02, (q15_t)0x7564, (q15_t)0xccfc, (q15_t)0x7562, (q15_t)0xccf6, + (q15_t)0x755f, (q15_t)0xccf1, (q15_t)0x755d, (q15_t)0xcceb, (q15_t)0x755a, (q15_t)0xcce5, (q15_t)0x7558, (q15_t)0xccdf, + (q15_t)0x7555, (q15_t)0xccda, (q15_t)0x7553, (q15_t)0xccd4, (q15_t)0x7550, (q15_t)0xccce, (q15_t)0x754e, (q15_t)0xccc8, + (q15_t)0x754b, (q15_t)0xccc3, (q15_t)0x7549, (q15_t)0xccbd, (q15_t)0x7546, (q15_t)0xccb7, (q15_t)0x7544, (q15_t)0xccb1, + (q15_t)0x7541, (q15_t)0xccac, (q15_t)0x753f, (q15_t)0xcca6, (q15_t)0x753c, (q15_t)0xcca0, (q15_t)0x753a, (q15_t)0xcc9a, + (q15_t)0x7537, (q15_t)0xcc95, (q15_t)0x7535, (q15_t)0xcc8f, (q15_t)0x7532, (q15_t)0xcc89, (q15_t)0x752f, (q15_t)0xcc83, + (q15_t)0x752d, (q15_t)0xcc7e, (q15_t)0x752a, (q15_t)0xcc78, (q15_t)0x7528, (q15_t)0xcc72, (q15_t)0x7525, (q15_t)0xcc6c, + (q15_t)0x7523, (q15_t)0xcc67, (q15_t)0x7520, (q15_t)0xcc61, (q15_t)0x751e, (q15_t)0xcc5b, (q15_t)0x751b, (q15_t)0xcc55, + (q15_t)0x7519, (q15_t)0xcc50, (q15_t)0x7516, (q15_t)0xcc4a, (q15_t)0x7514, (q15_t)0xcc44, (q15_t)0x7511, (q15_t)0xcc3e, + (q15_t)0x750f, (q15_t)0xcc39, (q15_t)0x750c, (q15_t)0xcc33, (q15_t)0x7509, (q15_t)0xcc2d, (q15_t)0x7507, (q15_t)0xcc27, + (q15_t)0x7504, (q15_t)0xcc22, (q15_t)0x7502, (q15_t)0xcc1c, (q15_t)0x74ff, (q15_t)0xcc16, (q15_t)0x74fd, (q15_t)0xcc10, + (q15_t)0x74fa, (q15_t)0xcc0b, (q15_t)0x74f8, (q15_t)0xcc05, (q15_t)0x74f5, (q15_t)0xcbff, (q15_t)0x74f2, (q15_t)0xcbf9, + (q15_t)0x74f0, (q15_t)0xcbf4, (q15_t)0x74ed, (q15_t)0xcbee, (q15_t)0x74eb, (q15_t)0xcbe8, (q15_t)0x74e8, (q15_t)0xcbe2, + (q15_t)0x74e6, (q15_t)0xcbdd, (q15_t)0x74e3, (q15_t)0xcbd7, (q15_t)0x74e1, (q15_t)0xcbd1, (q15_t)0x74de, (q15_t)0xcbcb, + (q15_t)0x74db, (q15_t)0xcbc6, (q15_t)0x74d9, (q15_t)0xcbc0, (q15_t)0x74d6, (q15_t)0xcbba, (q15_t)0x74d4, (q15_t)0xcbb5, + (q15_t)0x74d1, (q15_t)0xcbaf, (q15_t)0x74cf, (q15_t)0xcba9, (q15_t)0x74cc, (q15_t)0xcba3, (q15_t)0x74c9, (q15_t)0xcb9e, + (q15_t)0x74c7, (q15_t)0xcb98, (q15_t)0x74c4, (q15_t)0xcb92, (q15_t)0x74c2, (q15_t)0xcb8c, (q15_t)0x74bf, (q15_t)0xcb87, + (q15_t)0x74bd, (q15_t)0xcb81, (q15_t)0x74ba, (q15_t)0xcb7b, (q15_t)0x74b7, (q15_t)0xcb75, (q15_t)0x74b5, (q15_t)0xcb70, + (q15_t)0x74b2, (q15_t)0xcb6a, (q15_t)0x74b0, (q15_t)0xcb64, (q15_t)0x74ad, (q15_t)0xcb5f, (q15_t)0x74ab, (q15_t)0xcb59, + (q15_t)0x74a8, (q15_t)0xcb53, (q15_t)0x74a5, (q15_t)0xcb4d, (q15_t)0x74a3, (q15_t)0xcb48, (q15_t)0x74a0, (q15_t)0xcb42, + (q15_t)0x749e, (q15_t)0xcb3c, (q15_t)0x749b, (q15_t)0xcb36, (q15_t)0x7498, (q15_t)0xcb31, (q15_t)0x7496, (q15_t)0xcb2b, + (q15_t)0x7493, (q15_t)0xcb25, (q15_t)0x7491, (q15_t)0xcb20, (q15_t)0x748e, (q15_t)0xcb1a, (q15_t)0x748b, (q15_t)0xcb14, + (q15_t)0x7489, (q15_t)0xcb0e, (q15_t)0x7486, (q15_t)0xcb09, (q15_t)0x7484, (q15_t)0xcb03, (q15_t)0x7481, (q15_t)0xcafd, + (q15_t)0x747e, (q15_t)0xcaf8, (q15_t)0x747c, (q15_t)0xcaf2, (q15_t)0x7479, (q15_t)0xcaec, (q15_t)0x7477, (q15_t)0xcae6, + (q15_t)0x7474, (q15_t)0xcae1, (q15_t)0x7471, (q15_t)0xcadb, (q15_t)0x746f, (q15_t)0xcad5, (q15_t)0x746c, (q15_t)0xcad0, + (q15_t)0x746a, (q15_t)0xcaca, (q15_t)0x7467, (q15_t)0xcac4, (q15_t)0x7464, (q15_t)0xcabe, (q15_t)0x7462, (q15_t)0xcab9, + (q15_t)0x745f, (q15_t)0xcab3, (q15_t)0x745c, (q15_t)0xcaad, (q15_t)0x745a, (q15_t)0xcaa8, (q15_t)0x7457, (q15_t)0xcaa2, + (q15_t)0x7455, (q15_t)0xca9c, (q15_t)0x7452, (q15_t)0xca96, (q15_t)0x744f, (q15_t)0xca91, (q15_t)0x744d, (q15_t)0xca8b, + (q15_t)0x744a, (q15_t)0xca85, (q15_t)0x7448, (q15_t)0xca80, (q15_t)0x7445, (q15_t)0xca7a, (q15_t)0x7442, (q15_t)0xca74, + (q15_t)0x7440, (q15_t)0xca6e, (q15_t)0x743d, (q15_t)0xca69, (q15_t)0x743a, (q15_t)0xca63, (q15_t)0x7438, (q15_t)0xca5d, + (q15_t)0x7435, (q15_t)0xca58, (q15_t)0x7432, (q15_t)0xca52, (q15_t)0x7430, (q15_t)0xca4c, (q15_t)0x742d, (q15_t)0xca46, + (q15_t)0x742b, (q15_t)0xca41, (q15_t)0x7428, (q15_t)0xca3b, (q15_t)0x7425, (q15_t)0xca35, (q15_t)0x7423, (q15_t)0xca30, + (q15_t)0x7420, (q15_t)0xca2a, (q15_t)0x741d, (q15_t)0xca24, (q15_t)0x741b, (q15_t)0xca1f, (q15_t)0x7418, (q15_t)0xca19, + (q15_t)0x7415, (q15_t)0xca13, (q15_t)0x7413, (q15_t)0xca0d, (q15_t)0x7410, (q15_t)0xca08, (q15_t)0x740d, (q15_t)0xca02, + (q15_t)0x740b, (q15_t)0xc9fc, (q15_t)0x7408, (q15_t)0xc9f7, (q15_t)0x7406, (q15_t)0xc9f1, (q15_t)0x7403, (q15_t)0xc9eb, + (q15_t)0x7400, (q15_t)0xc9e6, (q15_t)0x73fe, (q15_t)0xc9e0, (q15_t)0x73fb, (q15_t)0xc9da, (q15_t)0x73f8, (q15_t)0xc9d5, + (q15_t)0x73f6, (q15_t)0xc9cf, (q15_t)0x73f3, (q15_t)0xc9c9, (q15_t)0x73f0, (q15_t)0xc9c3, (q15_t)0x73ee, (q15_t)0xc9be, + (q15_t)0x73eb, (q15_t)0xc9b8, (q15_t)0x73e8, (q15_t)0xc9b2, (q15_t)0x73e6, (q15_t)0xc9ad, (q15_t)0x73e3, (q15_t)0xc9a7, + (q15_t)0x73e0, (q15_t)0xc9a1, (q15_t)0x73de, (q15_t)0xc99c, (q15_t)0x73db, (q15_t)0xc996, (q15_t)0x73d8, (q15_t)0xc990, + (q15_t)0x73d6, (q15_t)0xc98b, (q15_t)0x73d3, (q15_t)0xc985, (q15_t)0x73d0, (q15_t)0xc97f, (q15_t)0x73ce, (q15_t)0xc97a, + (q15_t)0x73cb, (q15_t)0xc974, (q15_t)0x73c8, (q15_t)0xc96e, (q15_t)0x73c6, (q15_t)0xc968, (q15_t)0x73c3, (q15_t)0xc963, + (q15_t)0x73c0, (q15_t)0xc95d, (q15_t)0x73bd, (q15_t)0xc957, (q15_t)0x73bb, (q15_t)0xc952, (q15_t)0x73b8, (q15_t)0xc94c, + (q15_t)0x73b5, (q15_t)0xc946, (q15_t)0x73b3, (q15_t)0xc941, (q15_t)0x73b0, (q15_t)0xc93b, (q15_t)0x73ad, (q15_t)0xc935, + (q15_t)0x73ab, (q15_t)0xc930, (q15_t)0x73a8, (q15_t)0xc92a, (q15_t)0x73a5, (q15_t)0xc924, (q15_t)0x73a3, (q15_t)0xc91f, + (q15_t)0x73a0, (q15_t)0xc919, (q15_t)0x739d, (q15_t)0xc913, (q15_t)0x739b, (q15_t)0xc90e, (q15_t)0x7398, (q15_t)0xc908, + (q15_t)0x7395, (q15_t)0xc902, (q15_t)0x7392, (q15_t)0xc8fd, (q15_t)0x7390, (q15_t)0xc8f7, (q15_t)0x738d, (q15_t)0xc8f1, + (q15_t)0x738a, (q15_t)0xc8ec, (q15_t)0x7388, (q15_t)0xc8e6, (q15_t)0x7385, (q15_t)0xc8e0, (q15_t)0x7382, (q15_t)0xc8db, + (q15_t)0x737f, (q15_t)0xc8d5, (q15_t)0x737d, (q15_t)0xc8cf, (q15_t)0x737a, (q15_t)0xc8ca, (q15_t)0x7377, (q15_t)0xc8c4, + (q15_t)0x7375, (q15_t)0xc8be, (q15_t)0x7372, (q15_t)0xc8b9, (q15_t)0x736f, (q15_t)0xc8b3, (q15_t)0x736c, (q15_t)0xc8ad, + (q15_t)0x736a, (q15_t)0xc8a8, (q15_t)0x7367, (q15_t)0xc8a2, (q15_t)0x7364, (q15_t)0xc89c, (q15_t)0x7362, (q15_t)0xc897, + (q15_t)0x735f, (q15_t)0xc891, (q15_t)0x735c, (q15_t)0xc88b, (q15_t)0x7359, (q15_t)0xc886, (q15_t)0x7357, (q15_t)0xc880, + (q15_t)0x7354, (q15_t)0xc87a, (q15_t)0x7351, (q15_t)0xc875, (q15_t)0x734f, (q15_t)0xc86f, (q15_t)0x734c, (q15_t)0xc869, + (q15_t)0x7349, (q15_t)0xc864, (q15_t)0x7346, (q15_t)0xc85e, (q15_t)0x7344, (q15_t)0xc858, (q15_t)0x7341, (q15_t)0xc853, + (q15_t)0x733e, (q15_t)0xc84d, (q15_t)0x733b, (q15_t)0xc847, (q15_t)0x7339, (q15_t)0xc842, (q15_t)0x7336, (q15_t)0xc83c, + (q15_t)0x7333, (q15_t)0xc836, (q15_t)0x7330, (q15_t)0xc831, (q15_t)0x732e, (q15_t)0xc82b, (q15_t)0x732b, (q15_t)0xc825, + (q15_t)0x7328, (q15_t)0xc820, (q15_t)0x7326, (q15_t)0xc81a, (q15_t)0x7323, (q15_t)0xc814, (q15_t)0x7320, (q15_t)0xc80f, + (q15_t)0x731d, (q15_t)0xc809, (q15_t)0x731b, (q15_t)0xc803, (q15_t)0x7318, (q15_t)0xc7fe, (q15_t)0x7315, (q15_t)0xc7f8, + (q15_t)0x7312, (q15_t)0xc7f3, (q15_t)0x7310, (q15_t)0xc7ed, (q15_t)0x730d, (q15_t)0xc7e7, (q15_t)0x730a, (q15_t)0xc7e2, + (q15_t)0x7307, (q15_t)0xc7dc, (q15_t)0x7305, (q15_t)0xc7d6, (q15_t)0x7302, (q15_t)0xc7d1, (q15_t)0x72ff, (q15_t)0xc7cb, + (q15_t)0x72fc, (q15_t)0xc7c5, (q15_t)0x72f9, (q15_t)0xc7c0, (q15_t)0x72f7, (q15_t)0xc7ba, (q15_t)0x72f4, (q15_t)0xc7b4, + (q15_t)0x72f1, (q15_t)0xc7af, (q15_t)0x72ee, (q15_t)0xc7a9, (q15_t)0x72ec, (q15_t)0xc7a3, (q15_t)0x72e9, (q15_t)0xc79e, + (q15_t)0x72e6, (q15_t)0xc798, (q15_t)0x72e3, (q15_t)0xc793, (q15_t)0x72e1, (q15_t)0xc78d, (q15_t)0x72de, (q15_t)0xc787, + (q15_t)0x72db, (q15_t)0xc782, (q15_t)0x72d8, (q15_t)0xc77c, (q15_t)0x72d5, (q15_t)0xc776, (q15_t)0x72d3, (q15_t)0xc771, + (q15_t)0x72d0, (q15_t)0xc76b, (q15_t)0x72cd, (q15_t)0xc765, (q15_t)0x72ca, (q15_t)0xc760, (q15_t)0x72c8, (q15_t)0xc75a, + (q15_t)0x72c5, (q15_t)0xc755, (q15_t)0x72c2, (q15_t)0xc74f, (q15_t)0x72bf, (q15_t)0xc749, (q15_t)0x72bc, (q15_t)0xc744, + (q15_t)0x72ba, (q15_t)0xc73e, (q15_t)0x72b7, (q15_t)0xc738, (q15_t)0x72b4, (q15_t)0xc733, (q15_t)0x72b1, (q15_t)0xc72d, + (q15_t)0x72af, (q15_t)0xc728, (q15_t)0x72ac, (q15_t)0xc722, (q15_t)0x72a9, (q15_t)0xc71c, (q15_t)0x72a6, (q15_t)0xc717, + (q15_t)0x72a3, (q15_t)0xc711, (q15_t)0x72a1, (q15_t)0xc70b, (q15_t)0x729e, (q15_t)0xc706, (q15_t)0x729b, (q15_t)0xc700, + (q15_t)0x7298, (q15_t)0xc6fa, (q15_t)0x7295, (q15_t)0xc6f5, (q15_t)0x7293, (q15_t)0xc6ef, (q15_t)0x7290, (q15_t)0xc6ea, + (q15_t)0x728d, (q15_t)0xc6e4, (q15_t)0x728a, (q15_t)0xc6de, (q15_t)0x7287, (q15_t)0xc6d9, (q15_t)0x7285, (q15_t)0xc6d3, + (q15_t)0x7282, (q15_t)0xc6ce, (q15_t)0x727f, (q15_t)0xc6c8, (q15_t)0x727c, (q15_t)0xc6c2, (q15_t)0x7279, (q15_t)0xc6bd, + (q15_t)0x7276, (q15_t)0xc6b7, (q15_t)0x7274, (q15_t)0xc6b1, (q15_t)0x7271, (q15_t)0xc6ac, (q15_t)0x726e, (q15_t)0xc6a6, + (q15_t)0x726b, (q15_t)0xc6a1, (q15_t)0x7268, (q15_t)0xc69b, (q15_t)0x7266, (q15_t)0xc695, (q15_t)0x7263, (q15_t)0xc690, + (q15_t)0x7260, (q15_t)0xc68a, (q15_t)0x725d, (q15_t)0xc684, (q15_t)0x725a, (q15_t)0xc67f, (q15_t)0x7257, (q15_t)0xc679, + (q15_t)0x7255, (q15_t)0xc674, (q15_t)0x7252, (q15_t)0xc66e, (q15_t)0x724f, (q15_t)0xc668, (q15_t)0x724c, (q15_t)0xc663, + (q15_t)0x7249, (q15_t)0xc65d, (q15_t)0x7247, (q15_t)0xc658, (q15_t)0x7244, (q15_t)0xc652, (q15_t)0x7241, (q15_t)0xc64c, + (q15_t)0x723e, (q15_t)0xc647, (q15_t)0x723b, (q15_t)0xc641, (q15_t)0x7238, (q15_t)0xc63c, (q15_t)0x7236, (q15_t)0xc636, + (q15_t)0x7233, (q15_t)0xc630, (q15_t)0x7230, (q15_t)0xc62b, (q15_t)0x722d, (q15_t)0xc625, (q15_t)0x722a, (q15_t)0xc620, + (q15_t)0x7227, (q15_t)0xc61a, (q15_t)0x7224, (q15_t)0xc614, (q15_t)0x7222, (q15_t)0xc60f, (q15_t)0x721f, (q15_t)0xc609, + (q15_t)0x721c, (q15_t)0xc603, (q15_t)0x7219, (q15_t)0xc5fe, (q15_t)0x7216, (q15_t)0xc5f8, (q15_t)0x7213, (q15_t)0xc5f3, + (q15_t)0x7211, (q15_t)0xc5ed, (q15_t)0x720e, (q15_t)0xc5e7, (q15_t)0x720b, (q15_t)0xc5e2, (q15_t)0x7208, (q15_t)0xc5dc, + (q15_t)0x7205, (q15_t)0xc5d7, (q15_t)0x7202, (q15_t)0xc5d1, (q15_t)0x71ff, (q15_t)0xc5cc, (q15_t)0x71fd, (q15_t)0xc5c6, + (q15_t)0x71fa, (q15_t)0xc5c0, (q15_t)0x71f7, (q15_t)0xc5bb, (q15_t)0x71f4, (q15_t)0xc5b5, (q15_t)0x71f1, (q15_t)0xc5b0, + (q15_t)0x71ee, (q15_t)0xc5aa, (q15_t)0x71eb, (q15_t)0xc5a4, (q15_t)0x71e9, (q15_t)0xc59f, (q15_t)0x71e6, (q15_t)0xc599, + (q15_t)0x71e3, (q15_t)0xc594, (q15_t)0x71e0, (q15_t)0xc58e, (q15_t)0x71dd, (q15_t)0xc588, (q15_t)0x71da, (q15_t)0xc583, + (q15_t)0x71d7, (q15_t)0xc57d, (q15_t)0x71d4, (q15_t)0xc578, (q15_t)0x71d2, (q15_t)0xc572, (q15_t)0x71cf, (q15_t)0xc56c, + (q15_t)0x71cc, (q15_t)0xc567, (q15_t)0x71c9, (q15_t)0xc561, (q15_t)0x71c6, (q15_t)0xc55c, (q15_t)0x71c3, (q15_t)0xc556, + (q15_t)0x71c0, (q15_t)0xc551, (q15_t)0x71bd, (q15_t)0xc54b, (q15_t)0x71bb, (q15_t)0xc545, (q15_t)0x71b8, (q15_t)0xc540, + (q15_t)0x71b5, (q15_t)0xc53a, (q15_t)0x71b2, (q15_t)0xc535, (q15_t)0x71af, (q15_t)0xc52f, (q15_t)0x71ac, (q15_t)0xc529, + (q15_t)0x71a9, (q15_t)0xc524, (q15_t)0x71a6, (q15_t)0xc51e, (q15_t)0x71a3, (q15_t)0xc519, (q15_t)0x71a1, (q15_t)0xc513, + (q15_t)0x719e, (q15_t)0xc50e, (q15_t)0x719b, (q15_t)0xc508, (q15_t)0x7198, (q15_t)0xc502, (q15_t)0x7195, (q15_t)0xc4fd, + (q15_t)0x7192, (q15_t)0xc4f7, (q15_t)0x718f, (q15_t)0xc4f2, (q15_t)0x718c, (q15_t)0xc4ec, (q15_t)0x7189, (q15_t)0xc4e7, + (q15_t)0x7186, (q15_t)0xc4e1, (q15_t)0x7184, (q15_t)0xc4db, (q15_t)0x7181, (q15_t)0xc4d6, (q15_t)0x717e, (q15_t)0xc4d0, + (q15_t)0x717b, (q15_t)0xc4cb, (q15_t)0x7178, (q15_t)0xc4c5, (q15_t)0x7175, (q15_t)0xc4c0, (q15_t)0x7172, (q15_t)0xc4ba, + (q15_t)0x716f, (q15_t)0xc4b4, (q15_t)0x716c, (q15_t)0xc4af, (q15_t)0x7169, (q15_t)0xc4a9, (q15_t)0x7167, (q15_t)0xc4a4, + (q15_t)0x7164, (q15_t)0xc49e, (q15_t)0x7161, (q15_t)0xc499, (q15_t)0x715e, (q15_t)0xc493, (q15_t)0x715b, (q15_t)0xc48d, + (q15_t)0x7158, (q15_t)0xc488, (q15_t)0x7155, (q15_t)0xc482, (q15_t)0x7152, (q15_t)0xc47d, (q15_t)0x714f, (q15_t)0xc477, + (q15_t)0x714c, (q15_t)0xc472, (q15_t)0x7149, (q15_t)0xc46c, (q15_t)0x7146, (q15_t)0xc467, (q15_t)0x7143, (q15_t)0xc461, + (q15_t)0x7141, (q15_t)0xc45b, (q15_t)0x713e, (q15_t)0xc456, (q15_t)0x713b, (q15_t)0xc450, (q15_t)0x7138, (q15_t)0xc44b, + (q15_t)0x7135, (q15_t)0xc445, (q15_t)0x7132, (q15_t)0xc440, (q15_t)0x712f, (q15_t)0xc43a, (q15_t)0x712c, (q15_t)0xc434, + (q15_t)0x7129, (q15_t)0xc42f, (q15_t)0x7126, (q15_t)0xc429, (q15_t)0x7123, (q15_t)0xc424, (q15_t)0x7120, (q15_t)0xc41e, + (q15_t)0x711d, (q15_t)0xc419, (q15_t)0x711a, (q15_t)0xc413, (q15_t)0x7117, (q15_t)0xc40e, (q15_t)0x7114, (q15_t)0xc408, + (q15_t)0x7112, (q15_t)0xc403, (q15_t)0x710f, (q15_t)0xc3fd, (q15_t)0x710c, (q15_t)0xc3f7, (q15_t)0x7109, (q15_t)0xc3f2, + (q15_t)0x7106, (q15_t)0xc3ec, (q15_t)0x7103, (q15_t)0xc3e7, (q15_t)0x7100, (q15_t)0xc3e1, (q15_t)0x70fd, (q15_t)0xc3dc, + (q15_t)0x70fa, (q15_t)0xc3d6, (q15_t)0x70f7, (q15_t)0xc3d1, (q15_t)0x70f4, (q15_t)0xc3cb, (q15_t)0x70f1, (q15_t)0xc3c5, + (q15_t)0x70ee, (q15_t)0xc3c0, (q15_t)0x70eb, (q15_t)0xc3ba, (q15_t)0x70e8, (q15_t)0xc3b5, (q15_t)0x70e5, (q15_t)0xc3af, + (q15_t)0x70e2, (q15_t)0xc3aa, (q15_t)0x70df, (q15_t)0xc3a4, (q15_t)0x70dc, (q15_t)0xc39f, (q15_t)0x70d9, (q15_t)0xc399, + (q15_t)0x70d6, (q15_t)0xc394, (q15_t)0x70d3, (q15_t)0xc38e, (q15_t)0x70d1, (q15_t)0xc389, (q15_t)0x70ce, (q15_t)0xc383, + (q15_t)0x70cb, (q15_t)0xc37d, (q15_t)0x70c8, (q15_t)0xc378, (q15_t)0x70c5, (q15_t)0xc372, (q15_t)0x70c2, (q15_t)0xc36d, + (q15_t)0x70bf, (q15_t)0xc367, (q15_t)0x70bc, (q15_t)0xc362, (q15_t)0x70b9, (q15_t)0xc35c, (q15_t)0x70b6, (q15_t)0xc357, + (q15_t)0x70b3, (q15_t)0xc351, (q15_t)0x70b0, (q15_t)0xc34c, (q15_t)0x70ad, (q15_t)0xc346, (q15_t)0x70aa, (q15_t)0xc341, + (q15_t)0x70a7, (q15_t)0xc33b, (q15_t)0x70a4, (q15_t)0xc336, (q15_t)0x70a1, (q15_t)0xc330, (q15_t)0x709e, (q15_t)0xc32a, + (q15_t)0x709b, (q15_t)0xc325, (q15_t)0x7098, (q15_t)0xc31f, (q15_t)0x7095, (q15_t)0xc31a, (q15_t)0x7092, (q15_t)0xc314, + (q15_t)0x708f, (q15_t)0xc30f, (q15_t)0x708c, (q15_t)0xc309, (q15_t)0x7089, (q15_t)0xc304, (q15_t)0x7086, (q15_t)0xc2fe, + (q15_t)0x7083, (q15_t)0xc2f9, (q15_t)0x7080, (q15_t)0xc2f3, (q15_t)0x707d, (q15_t)0xc2ee, (q15_t)0x707a, (q15_t)0xc2e8, + (q15_t)0x7077, (q15_t)0xc2e3, (q15_t)0x7074, (q15_t)0xc2dd, (q15_t)0x7071, (q15_t)0xc2d8, (q15_t)0x706e, (q15_t)0xc2d2, + (q15_t)0x706b, (q15_t)0xc2cd, (q15_t)0x7068, (q15_t)0xc2c7, (q15_t)0x7065, (q15_t)0xc2c2, (q15_t)0x7062, (q15_t)0xc2bc, + (q15_t)0x705f, (q15_t)0xc2b7, (q15_t)0x705c, (q15_t)0xc2b1, (q15_t)0x7059, (q15_t)0xc2ab, (q15_t)0x7056, (q15_t)0xc2a6, + (q15_t)0x7053, (q15_t)0xc2a0, (q15_t)0x7050, (q15_t)0xc29b, (q15_t)0x704d, (q15_t)0xc295, (q15_t)0x704a, (q15_t)0xc290, + (q15_t)0x7047, (q15_t)0xc28a, (q15_t)0x7044, (q15_t)0xc285, (q15_t)0x7041, (q15_t)0xc27f, (q15_t)0x703e, (q15_t)0xc27a, + (q15_t)0x703b, (q15_t)0xc274, (q15_t)0x7038, (q15_t)0xc26f, (q15_t)0x7035, (q15_t)0xc269, (q15_t)0x7032, (q15_t)0xc264, + (q15_t)0x702f, (q15_t)0xc25e, (q15_t)0x702c, (q15_t)0xc259, (q15_t)0x7029, (q15_t)0xc253, (q15_t)0x7026, (q15_t)0xc24e, + (q15_t)0x7023, (q15_t)0xc248, (q15_t)0x7020, (q15_t)0xc243, (q15_t)0x701d, (q15_t)0xc23d, (q15_t)0x7019, (q15_t)0xc238, + (q15_t)0x7016, (q15_t)0xc232, (q15_t)0x7013, (q15_t)0xc22d, (q15_t)0x7010, (q15_t)0xc227, (q15_t)0x700d, (q15_t)0xc222, + (q15_t)0x700a, (q15_t)0xc21c, (q15_t)0x7007, (q15_t)0xc217, (q15_t)0x7004, (q15_t)0xc211, (q15_t)0x7001, (q15_t)0xc20c, + (q15_t)0x6ffe, (q15_t)0xc206, (q15_t)0x6ffb, (q15_t)0xc201, (q15_t)0x6ff8, (q15_t)0xc1fb, (q15_t)0x6ff5, (q15_t)0xc1f6, + (q15_t)0x6ff2, (q15_t)0xc1f0, (q15_t)0x6fef, (q15_t)0xc1eb, (q15_t)0x6fec, (q15_t)0xc1e5, (q15_t)0x6fe9, (q15_t)0xc1e0, + (q15_t)0x6fe6, (q15_t)0xc1da, (q15_t)0x6fe3, (q15_t)0xc1d5, (q15_t)0x6fe0, (q15_t)0xc1cf, (q15_t)0x6fdd, (q15_t)0xc1ca, + (q15_t)0x6fda, (q15_t)0xc1c4, (q15_t)0x6fd6, (q15_t)0xc1bf, (q15_t)0x6fd3, (q15_t)0xc1b9, (q15_t)0x6fd0, (q15_t)0xc1b4, + (q15_t)0x6fcd, (q15_t)0xc1ae, (q15_t)0x6fca, (q15_t)0xc1a9, (q15_t)0x6fc7, (q15_t)0xc1a3, (q15_t)0x6fc4, (q15_t)0xc19e, + (q15_t)0x6fc1, (q15_t)0xc198, (q15_t)0x6fbe, (q15_t)0xc193, (q15_t)0x6fbb, (q15_t)0xc18d, (q15_t)0x6fb8, (q15_t)0xc188, + (q15_t)0x6fb5, (q15_t)0xc183, (q15_t)0x6fb2, (q15_t)0xc17d, (q15_t)0x6faf, (q15_t)0xc178, (q15_t)0x6fac, (q15_t)0xc172, + (q15_t)0x6fa9, (q15_t)0xc16d, (q15_t)0x6fa5, (q15_t)0xc167, (q15_t)0x6fa2, (q15_t)0xc162, (q15_t)0x6f9f, (q15_t)0xc15c, + (q15_t)0x6f9c, (q15_t)0xc157, (q15_t)0x6f99, (q15_t)0xc151, (q15_t)0x6f96, (q15_t)0xc14c, (q15_t)0x6f93, (q15_t)0xc146, + (q15_t)0x6f90, (q15_t)0xc141, (q15_t)0x6f8d, (q15_t)0xc13b, (q15_t)0x6f8a, (q15_t)0xc136, (q15_t)0x6f87, (q15_t)0xc130, + (q15_t)0x6f84, (q15_t)0xc12b, (q15_t)0x6f81, (q15_t)0xc125, (q15_t)0x6f7d, (q15_t)0xc120, (q15_t)0x6f7a, (q15_t)0xc11a, + (q15_t)0x6f77, (q15_t)0xc115, (q15_t)0x6f74, (q15_t)0xc10f, (q15_t)0x6f71, (q15_t)0xc10a, (q15_t)0x6f6e, (q15_t)0xc105, + (q15_t)0x6f6b, (q15_t)0xc0ff, (q15_t)0x6f68, (q15_t)0xc0fa, (q15_t)0x6f65, (q15_t)0xc0f4, (q15_t)0x6f62, (q15_t)0xc0ef, + (q15_t)0x6f5f, (q15_t)0xc0e9, (q15_t)0x6f5b, (q15_t)0xc0e4, (q15_t)0x6f58, (q15_t)0xc0de, (q15_t)0x6f55, (q15_t)0xc0d9, + (q15_t)0x6f52, (q15_t)0xc0d3, (q15_t)0x6f4f, (q15_t)0xc0ce, (q15_t)0x6f4c, (q15_t)0xc0c8, (q15_t)0x6f49, (q15_t)0xc0c3, + (q15_t)0x6f46, (q15_t)0xc0bd, (q15_t)0x6f43, (q15_t)0xc0b8, (q15_t)0x6f3f, (q15_t)0xc0b3, (q15_t)0x6f3c, (q15_t)0xc0ad, + (q15_t)0x6f39, (q15_t)0xc0a8, (q15_t)0x6f36, (q15_t)0xc0a2, (q15_t)0x6f33, (q15_t)0xc09d, (q15_t)0x6f30, (q15_t)0xc097, + (q15_t)0x6f2d, (q15_t)0xc092, (q15_t)0x6f2a, (q15_t)0xc08c, (q15_t)0x6f27, (q15_t)0xc087, (q15_t)0x6f23, (q15_t)0xc081, + (q15_t)0x6f20, (q15_t)0xc07c, (q15_t)0x6f1d, (q15_t)0xc077, (q15_t)0x6f1a, (q15_t)0xc071, (q15_t)0x6f17, (q15_t)0xc06c, + (q15_t)0x6f14, (q15_t)0xc066, (q15_t)0x6f11, (q15_t)0xc061, (q15_t)0x6f0e, (q15_t)0xc05b, (q15_t)0x6f0b, (q15_t)0xc056, + (q15_t)0x6f07, (q15_t)0xc050, (q15_t)0x6f04, (q15_t)0xc04b, (q15_t)0x6f01, (q15_t)0xc045, (q15_t)0x6efe, (q15_t)0xc040, + (q15_t)0x6efb, (q15_t)0xc03b, (q15_t)0x6ef8, (q15_t)0xc035, (q15_t)0x6ef5, (q15_t)0xc030, (q15_t)0x6ef1, (q15_t)0xc02a, + (q15_t)0x6eee, (q15_t)0xc025, (q15_t)0x6eeb, (q15_t)0xc01f, (q15_t)0x6ee8, (q15_t)0xc01a, (q15_t)0x6ee5, (q15_t)0xc014, + (q15_t)0x6ee2, (q15_t)0xc00f, (q15_t)0x6edf, (q15_t)0xc00a, (q15_t)0x6edc, (q15_t)0xc004, (q15_t)0x6ed8, (q15_t)0xbfff, + (q15_t)0x6ed5, (q15_t)0xbff9, (q15_t)0x6ed2, (q15_t)0xbff4, (q15_t)0x6ecf, (q15_t)0xbfee, (q15_t)0x6ecc, (q15_t)0xbfe9, + (q15_t)0x6ec9, (q15_t)0xbfe3, (q15_t)0x6ec6, (q15_t)0xbfde, (q15_t)0x6ec2, (q15_t)0xbfd9, (q15_t)0x6ebf, (q15_t)0xbfd3, + (q15_t)0x6ebc, (q15_t)0xbfce, (q15_t)0x6eb9, (q15_t)0xbfc8, (q15_t)0x6eb6, (q15_t)0xbfc3, (q15_t)0x6eb3, (q15_t)0xbfbd, + (q15_t)0x6eaf, (q15_t)0xbfb8, (q15_t)0x6eac, (q15_t)0xbfb3, (q15_t)0x6ea9, (q15_t)0xbfad, (q15_t)0x6ea6, (q15_t)0xbfa8, + (q15_t)0x6ea3, (q15_t)0xbfa2, (q15_t)0x6ea0, (q15_t)0xbf9d, (q15_t)0x6e9c, (q15_t)0xbf97, (q15_t)0x6e99, (q15_t)0xbf92, + (q15_t)0x6e96, (q15_t)0xbf8d, (q15_t)0x6e93, (q15_t)0xbf87, (q15_t)0x6e90, (q15_t)0xbf82, (q15_t)0x6e8d, (q15_t)0xbf7c, + (q15_t)0x6e89, (q15_t)0xbf77, (q15_t)0x6e86, (q15_t)0xbf71, (q15_t)0x6e83, (q15_t)0xbf6c, (q15_t)0x6e80, (q15_t)0xbf67, + (q15_t)0x6e7d, (q15_t)0xbf61, (q15_t)0x6e7a, (q15_t)0xbf5c, (q15_t)0x6e76, (q15_t)0xbf56, (q15_t)0x6e73, (q15_t)0xbf51, + (q15_t)0x6e70, (q15_t)0xbf4b, (q15_t)0x6e6d, (q15_t)0xbf46, (q15_t)0x6e6a, (q15_t)0xbf41, (q15_t)0x6e67, (q15_t)0xbf3b, + (q15_t)0x6e63, (q15_t)0xbf36, (q15_t)0x6e60, (q15_t)0xbf30, (q15_t)0x6e5d, (q15_t)0xbf2b, (q15_t)0x6e5a, (q15_t)0xbf26, + (q15_t)0x6e57, (q15_t)0xbf20, (q15_t)0x6e53, (q15_t)0xbf1b, (q15_t)0x6e50, (q15_t)0xbf15, (q15_t)0x6e4d, (q15_t)0xbf10, + (q15_t)0x6e4a, (q15_t)0xbf0a, (q15_t)0x6e47, (q15_t)0xbf05, (q15_t)0x6e44, (q15_t)0xbf00, (q15_t)0x6e40, (q15_t)0xbefa, + (q15_t)0x6e3d, (q15_t)0xbef5, (q15_t)0x6e3a, (q15_t)0xbeef, (q15_t)0x6e37, (q15_t)0xbeea, (q15_t)0x6e34, (q15_t)0xbee5, + (q15_t)0x6e30, (q15_t)0xbedf, (q15_t)0x6e2d, (q15_t)0xbeda, (q15_t)0x6e2a, (q15_t)0xbed4, (q15_t)0x6e27, (q15_t)0xbecf, + (q15_t)0x6e24, (q15_t)0xbeca, (q15_t)0x6e20, (q15_t)0xbec4, (q15_t)0x6e1d, (q15_t)0xbebf, (q15_t)0x6e1a, (q15_t)0xbeb9, + (q15_t)0x6e17, (q15_t)0xbeb4, (q15_t)0x6e14, (q15_t)0xbeae, (q15_t)0x6e10, (q15_t)0xbea9, (q15_t)0x6e0d, (q15_t)0xbea4, + (q15_t)0x6e0a, (q15_t)0xbe9e, (q15_t)0x6e07, (q15_t)0xbe99, (q15_t)0x6e04, (q15_t)0xbe93, (q15_t)0x6e00, (q15_t)0xbe8e, + (q15_t)0x6dfd, (q15_t)0xbe89, (q15_t)0x6dfa, (q15_t)0xbe83, (q15_t)0x6df7, (q15_t)0xbe7e, (q15_t)0x6df3, (q15_t)0xbe78, + (q15_t)0x6df0, (q15_t)0xbe73, (q15_t)0x6ded, (q15_t)0xbe6e, (q15_t)0x6dea, (q15_t)0xbe68, (q15_t)0x6de7, (q15_t)0xbe63, + (q15_t)0x6de3, (q15_t)0xbe5e, (q15_t)0x6de0, (q15_t)0xbe58, (q15_t)0x6ddd, (q15_t)0xbe53, (q15_t)0x6dda, (q15_t)0xbe4d, + (q15_t)0x6dd6, (q15_t)0xbe48, (q15_t)0x6dd3, (q15_t)0xbe43, (q15_t)0x6dd0, (q15_t)0xbe3d, (q15_t)0x6dcd, (q15_t)0xbe38, + (q15_t)0x6dca, (q15_t)0xbe32, (q15_t)0x6dc6, (q15_t)0xbe2d, (q15_t)0x6dc3, (q15_t)0xbe28, (q15_t)0x6dc0, (q15_t)0xbe22, + (q15_t)0x6dbd, (q15_t)0xbe1d, (q15_t)0x6db9, (q15_t)0xbe17, (q15_t)0x6db6, (q15_t)0xbe12, (q15_t)0x6db3, (q15_t)0xbe0d, + (q15_t)0x6db0, (q15_t)0xbe07, (q15_t)0x6dac, (q15_t)0xbe02, (q15_t)0x6da9, (q15_t)0xbdfd, (q15_t)0x6da6, (q15_t)0xbdf7, + (q15_t)0x6da3, (q15_t)0xbdf2, (q15_t)0x6d9f, (q15_t)0xbdec, (q15_t)0x6d9c, (q15_t)0xbde7, (q15_t)0x6d99, (q15_t)0xbde2, + (q15_t)0x6d96, (q15_t)0xbddc, (q15_t)0x6d92, (q15_t)0xbdd7, (q15_t)0x6d8f, (q15_t)0xbdd1, (q15_t)0x6d8c, (q15_t)0xbdcc, + (q15_t)0x6d89, (q15_t)0xbdc7, (q15_t)0x6d85, (q15_t)0xbdc1, (q15_t)0x6d82, (q15_t)0xbdbc, (q15_t)0x6d7f, (q15_t)0xbdb7, + (q15_t)0x6d7c, (q15_t)0xbdb1, (q15_t)0x6d78, (q15_t)0xbdac, (q15_t)0x6d75, (q15_t)0xbda6, (q15_t)0x6d72, (q15_t)0xbda1, + (q15_t)0x6d6f, (q15_t)0xbd9c, (q15_t)0x6d6b, (q15_t)0xbd96, (q15_t)0x6d68, (q15_t)0xbd91, (q15_t)0x6d65, (q15_t)0xbd8c, + (q15_t)0x6d62, (q15_t)0xbd86, (q15_t)0x6d5e, (q15_t)0xbd81, (q15_t)0x6d5b, (q15_t)0xbd7c, (q15_t)0x6d58, (q15_t)0xbd76, + (q15_t)0x6d55, (q15_t)0xbd71, (q15_t)0x6d51, (q15_t)0xbd6b, (q15_t)0x6d4e, (q15_t)0xbd66, (q15_t)0x6d4b, (q15_t)0xbd61, + (q15_t)0x6d48, (q15_t)0xbd5b, (q15_t)0x6d44, (q15_t)0xbd56, (q15_t)0x6d41, (q15_t)0xbd51, (q15_t)0x6d3e, (q15_t)0xbd4b, + (q15_t)0x6d3a, (q15_t)0xbd46, (q15_t)0x6d37, (q15_t)0xbd40, (q15_t)0x6d34, (q15_t)0xbd3b, (q15_t)0x6d31, (q15_t)0xbd36, + (q15_t)0x6d2d, (q15_t)0xbd30, (q15_t)0x6d2a, (q15_t)0xbd2b, (q15_t)0x6d27, (q15_t)0xbd26, (q15_t)0x6d23, (q15_t)0xbd20, + (q15_t)0x6d20, (q15_t)0xbd1b, (q15_t)0x6d1d, (q15_t)0xbd16, (q15_t)0x6d1a, (q15_t)0xbd10, (q15_t)0x6d16, (q15_t)0xbd0b, + (q15_t)0x6d13, (q15_t)0xbd06, (q15_t)0x6d10, (q15_t)0xbd00, (q15_t)0x6d0c, (q15_t)0xbcfb, (q15_t)0x6d09, (q15_t)0xbcf5, + (q15_t)0x6d06, (q15_t)0xbcf0, (q15_t)0x6d03, (q15_t)0xbceb, (q15_t)0x6cff, (q15_t)0xbce5, (q15_t)0x6cfc, (q15_t)0xbce0, + (q15_t)0x6cf9, (q15_t)0xbcdb, (q15_t)0x6cf5, (q15_t)0xbcd5, (q15_t)0x6cf2, (q15_t)0xbcd0, (q15_t)0x6cef, (q15_t)0xbccb, + (q15_t)0x6cec, (q15_t)0xbcc5, (q15_t)0x6ce8, (q15_t)0xbcc0, (q15_t)0x6ce5, (q15_t)0xbcbb, (q15_t)0x6ce2, (q15_t)0xbcb5, + (q15_t)0x6cde, (q15_t)0xbcb0, (q15_t)0x6cdb, (q15_t)0xbcab, (q15_t)0x6cd8, (q15_t)0xbca5, (q15_t)0x6cd4, (q15_t)0xbca0, + (q15_t)0x6cd1, (q15_t)0xbc9b, (q15_t)0x6cce, (q15_t)0xbc95, (q15_t)0x6cca, (q15_t)0xbc90, (q15_t)0x6cc7, (q15_t)0xbc8b, + (q15_t)0x6cc4, (q15_t)0xbc85, (q15_t)0x6cc1, (q15_t)0xbc80, (q15_t)0x6cbd, (q15_t)0xbc7b, (q15_t)0x6cba, (q15_t)0xbc75, + (q15_t)0x6cb7, (q15_t)0xbc70, (q15_t)0x6cb3, (q15_t)0xbc6b, (q15_t)0x6cb0, (q15_t)0xbc65, (q15_t)0x6cad, (q15_t)0xbc60, + (q15_t)0x6ca9, (q15_t)0xbc5b, (q15_t)0x6ca6, (q15_t)0xbc55, (q15_t)0x6ca3, (q15_t)0xbc50, (q15_t)0x6c9f, (q15_t)0xbc4b, + (q15_t)0x6c9c, (q15_t)0xbc45, (q15_t)0x6c99, (q15_t)0xbc40, (q15_t)0x6c95, (q15_t)0xbc3b, (q15_t)0x6c92, (q15_t)0xbc35, + (q15_t)0x6c8f, (q15_t)0xbc30, (q15_t)0x6c8b, (q15_t)0xbc2b, (q15_t)0x6c88, (q15_t)0xbc25, (q15_t)0x6c85, (q15_t)0xbc20, + (q15_t)0x6c81, (q15_t)0xbc1b, (q15_t)0x6c7e, (q15_t)0xbc15, (q15_t)0x6c7b, (q15_t)0xbc10, (q15_t)0x6c77, (q15_t)0xbc0b, + (q15_t)0x6c74, (q15_t)0xbc05, (q15_t)0x6c71, (q15_t)0xbc00, (q15_t)0x6c6d, (q15_t)0xbbfb, (q15_t)0x6c6a, (q15_t)0xbbf5, + (q15_t)0x6c67, (q15_t)0xbbf0, (q15_t)0x6c63, (q15_t)0xbbeb, (q15_t)0x6c60, (q15_t)0xbbe5, (q15_t)0x6c5d, (q15_t)0xbbe0, + (q15_t)0x6c59, (q15_t)0xbbdb, (q15_t)0x6c56, (q15_t)0xbbd5, (q15_t)0x6c53, (q15_t)0xbbd0, (q15_t)0x6c4f, (q15_t)0xbbcb, + (q15_t)0x6c4c, (q15_t)0xbbc5, (q15_t)0x6c49, (q15_t)0xbbc0, (q15_t)0x6c45, (q15_t)0xbbbb, (q15_t)0x6c42, (q15_t)0xbbb5, + (q15_t)0x6c3f, (q15_t)0xbbb0, (q15_t)0x6c3b, (q15_t)0xbbab, (q15_t)0x6c38, (q15_t)0xbba6, (q15_t)0x6c34, (q15_t)0xbba0, + (q15_t)0x6c31, (q15_t)0xbb9b, (q15_t)0x6c2e, (q15_t)0xbb96, (q15_t)0x6c2a, (q15_t)0xbb90, (q15_t)0x6c27, (q15_t)0xbb8b, + (q15_t)0x6c24, (q15_t)0xbb86, (q15_t)0x6c20, (q15_t)0xbb80, (q15_t)0x6c1d, (q15_t)0xbb7b, (q15_t)0x6c1a, (q15_t)0xbb76, + (q15_t)0x6c16, (q15_t)0xbb70, (q15_t)0x6c13, (q15_t)0xbb6b, (q15_t)0x6c0f, (q15_t)0xbb66, (q15_t)0x6c0c, (q15_t)0xbb61, + (q15_t)0x6c09, (q15_t)0xbb5b, (q15_t)0x6c05, (q15_t)0xbb56, (q15_t)0x6c02, (q15_t)0xbb51, (q15_t)0x6bff, (q15_t)0xbb4b, + (q15_t)0x6bfb, (q15_t)0xbb46, (q15_t)0x6bf8, (q15_t)0xbb41, (q15_t)0x6bf5, (q15_t)0xbb3b, (q15_t)0x6bf1, (q15_t)0xbb36, + (q15_t)0x6bee, (q15_t)0xbb31, (q15_t)0x6bea, (q15_t)0xbb2c, (q15_t)0x6be7, (q15_t)0xbb26, (q15_t)0x6be4, (q15_t)0xbb21, + (q15_t)0x6be0, (q15_t)0xbb1c, (q15_t)0x6bdd, (q15_t)0xbb16, (q15_t)0x6bd9, (q15_t)0xbb11, (q15_t)0x6bd6, (q15_t)0xbb0c, + (q15_t)0x6bd3, (q15_t)0xbb06, (q15_t)0x6bcf, (q15_t)0xbb01, (q15_t)0x6bcc, (q15_t)0xbafc, (q15_t)0x6bc9, (q15_t)0xbaf7, + (q15_t)0x6bc5, (q15_t)0xbaf1, (q15_t)0x6bc2, (q15_t)0xbaec, (q15_t)0x6bbe, (q15_t)0xbae7, (q15_t)0x6bbb, (q15_t)0xbae1, + (q15_t)0x6bb8, (q15_t)0xbadc, (q15_t)0x6bb4, (q15_t)0xbad7, (q15_t)0x6bb1, (q15_t)0xbad2, (q15_t)0x6bad, (q15_t)0xbacc, + (q15_t)0x6baa, (q15_t)0xbac7, (q15_t)0x6ba7, (q15_t)0xbac2, (q15_t)0x6ba3, (q15_t)0xbabc, (q15_t)0x6ba0, (q15_t)0xbab7, + (q15_t)0x6b9c, (q15_t)0xbab2, (q15_t)0x6b99, (q15_t)0xbaad, (q15_t)0x6b96, (q15_t)0xbaa7, (q15_t)0x6b92, (q15_t)0xbaa2, + (q15_t)0x6b8f, (q15_t)0xba9d, (q15_t)0x6b8b, (q15_t)0xba97, (q15_t)0x6b88, (q15_t)0xba92, (q15_t)0x6b85, (q15_t)0xba8d, + (q15_t)0x6b81, (q15_t)0xba88, (q15_t)0x6b7e, (q15_t)0xba82, (q15_t)0x6b7a, (q15_t)0xba7d, (q15_t)0x6b77, (q15_t)0xba78, + (q15_t)0x6b73, (q15_t)0xba73, (q15_t)0x6b70, (q15_t)0xba6d, (q15_t)0x6b6d, (q15_t)0xba68, (q15_t)0x6b69, (q15_t)0xba63, + (q15_t)0x6b66, (q15_t)0xba5d, (q15_t)0x6b62, (q15_t)0xba58, (q15_t)0x6b5f, (q15_t)0xba53, (q15_t)0x6b5c, (q15_t)0xba4e, + (q15_t)0x6b58, (q15_t)0xba48, (q15_t)0x6b55, (q15_t)0xba43, (q15_t)0x6b51, (q15_t)0xba3e, (q15_t)0x6b4e, (q15_t)0xba39, + (q15_t)0x6b4a, (q15_t)0xba33, (q15_t)0x6b47, (q15_t)0xba2e, (q15_t)0x6b44, (q15_t)0xba29, (q15_t)0x6b40, (q15_t)0xba23, + (q15_t)0x6b3d, (q15_t)0xba1e, (q15_t)0x6b39, (q15_t)0xba19, (q15_t)0x6b36, (q15_t)0xba14, (q15_t)0x6b32, (q15_t)0xba0e, + (q15_t)0x6b2f, (q15_t)0xba09, (q15_t)0x6b2c, (q15_t)0xba04, (q15_t)0x6b28, (q15_t)0xb9ff, (q15_t)0x6b25, (q15_t)0xb9f9, + (q15_t)0x6b21, (q15_t)0xb9f4, (q15_t)0x6b1e, (q15_t)0xb9ef, (q15_t)0x6b1a, (q15_t)0xb9ea, (q15_t)0x6b17, (q15_t)0xb9e4, + (q15_t)0x6b13, (q15_t)0xb9df, (q15_t)0x6b10, (q15_t)0xb9da, (q15_t)0x6b0d, (q15_t)0xb9d5, (q15_t)0x6b09, (q15_t)0xb9cf, + (q15_t)0x6b06, (q15_t)0xb9ca, (q15_t)0x6b02, (q15_t)0xb9c5, (q15_t)0x6aff, (q15_t)0xb9c0, (q15_t)0x6afb, (q15_t)0xb9ba, + (q15_t)0x6af8, (q15_t)0xb9b5, (q15_t)0x6af4, (q15_t)0xb9b0, (q15_t)0x6af1, (q15_t)0xb9ab, (q15_t)0x6aee, (q15_t)0xb9a5, + (q15_t)0x6aea, (q15_t)0xb9a0, (q15_t)0x6ae7, (q15_t)0xb99b, (q15_t)0x6ae3, (q15_t)0xb996, (q15_t)0x6ae0, (q15_t)0xb990, + (q15_t)0x6adc, (q15_t)0xb98b, (q15_t)0x6ad9, (q15_t)0xb986, (q15_t)0x6ad5, (q15_t)0xb981, (q15_t)0x6ad2, (q15_t)0xb97b, + (q15_t)0x6ace, (q15_t)0xb976, (q15_t)0x6acb, (q15_t)0xb971, (q15_t)0x6ac8, (q15_t)0xb96c, (q15_t)0x6ac4, (q15_t)0xb966, + (q15_t)0x6ac1, (q15_t)0xb961, (q15_t)0x6abd, (q15_t)0xb95c, (q15_t)0x6aba, (q15_t)0xb957, (q15_t)0x6ab6, (q15_t)0xb951, + (q15_t)0x6ab3, (q15_t)0xb94c, (q15_t)0x6aaf, (q15_t)0xb947, (q15_t)0x6aac, (q15_t)0xb942, (q15_t)0x6aa8, (q15_t)0xb93c, + (q15_t)0x6aa5, (q15_t)0xb937, (q15_t)0x6aa1, (q15_t)0xb932, (q15_t)0x6a9e, (q15_t)0xb92d, (q15_t)0x6a9a, (q15_t)0xb928, + (q15_t)0x6a97, (q15_t)0xb922, (q15_t)0x6a93, (q15_t)0xb91d, (q15_t)0x6a90, (q15_t)0xb918, (q15_t)0x6a8c, (q15_t)0xb913, + (q15_t)0x6a89, (q15_t)0xb90d, (q15_t)0x6a86, (q15_t)0xb908, (q15_t)0x6a82, (q15_t)0xb903, (q15_t)0x6a7f, (q15_t)0xb8fe, + (q15_t)0x6a7b, (q15_t)0xb8f8, (q15_t)0x6a78, (q15_t)0xb8f3, (q15_t)0x6a74, (q15_t)0xb8ee, (q15_t)0x6a71, (q15_t)0xb8e9, + (q15_t)0x6a6d, (q15_t)0xb8e4, (q15_t)0x6a6a, (q15_t)0xb8de, (q15_t)0x6a66, (q15_t)0xb8d9, (q15_t)0x6a63, (q15_t)0xb8d4, + (q15_t)0x6a5f, (q15_t)0xb8cf, (q15_t)0x6a5c, (q15_t)0xb8c9, (q15_t)0x6a58, (q15_t)0xb8c4, (q15_t)0x6a55, (q15_t)0xb8bf, + (q15_t)0x6a51, (q15_t)0xb8ba, (q15_t)0x6a4e, (q15_t)0xb8b5, (q15_t)0x6a4a, (q15_t)0xb8af, (q15_t)0x6a47, (q15_t)0xb8aa, + (q15_t)0x6a43, (q15_t)0xb8a5, (q15_t)0x6a40, (q15_t)0xb8a0, (q15_t)0x6a3c, (q15_t)0xb89b, (q15_t)0x6a39, (q15_t)0xb895, + (q15_t)0x6a35, (q15_t)0xb890, (q15_t)0x6a32, (q15_t)0xb88b, (q15_t)0x6a2e, (q15_t)0xb886, (q15_t)0x6a2b, (q15_t)0xb880, + (q15_t)0x6a27, (q15_t)0xb87b, (q15_t)0x6a24, (q15_t)0xb876, (q15_t)0x6a20, (q15_t)0xb871, (q15_t)0x6a1d, (q15_t)0xb86c, + (q15_t)0x6a19, (q15_t)0xb866, (q15_t)0x6a16, (q15_t)0xb861, (q15_t)0x6a12, (q15_t)0xb85c, (q15_t)0x6a0e, (q15_t)0xb857, + (q15_t)0x6a0b, (q15_t)0xb852, (q15_t)0x6a07, (q15_t)0xb84c, (q15_t)0x6a04, (q15_t)0xb847, (q15_t)0x6a00, (q15_t)0xb842, + (q15_t)0x69fd, (q15_t)0xb83d, (q15_t)0x69f9, (q15_t)0xb838, (q15_t)0x69f6, (q15_t)0xb832, (q15_t)0x69f2, (q15_t)0xb82d, + (q15_t)0x69ef, (q15_t)0xb828, (q15_t)0x69eb, (q15_t)0xb823, (q15_t)0x69e8, (q15_t)0xb81e, (q15_t)0x69e4, (q15_t)0xb818, + (q15_t)0x69e1, (q15_t)0xb813, (q15_t)0x69dd, (q15_t)0xb80e, (q15_t)0x69da, (q15_t)0xb809, (q15_t)0x69d6, (q15_t)0xb804, + (q15_t)0x69d3, (q15_t)0xb7fe, (q15_t)0x69cf, (q15_t)0xb7f9, (q15_t)0x69cb, (q15_t)0xb7f4, (q15_t)0x69c8, (q15_t)0xb7ef, + (q15_t)0x69c4, (q15_t)0xb7ea, (q15_t)0x69c1, (q15_t)0xb7e4, (q15_t)0x69bd, (q15_t)0xb7df, (q15_t)0x69ba, (q15_t)0xb7da, + (q15_t)0x69b6, (q15_t)0xb7d5, (q15_t)0x69b3, (q15_t)0xb7d0, (q15_t)0x69af, (q15_t)0xb7ca, (q15_t)0x69ac, (q15_t)0xb7c5, + (q15_t)0x69a8, (q15_t)0xb7c0, (q15_t)0x69a5, (q15_t)0xb7bb, (q15_t)0x69a1, (q15_t)0xb7b6, (q15_t)0x699d, (q15_t)0xb7b1, + (q15_t)0x699a, (q15_t)0xb7ab, (q15_t)0x6996, (q15_t)0xb7a6, (q15_t)0x6993, (q15_t)0xb7a1, (q15_t)0x698f, (q15_t)0xb79c, + (q15_t)0x698c, (q15_t)0xb797, (q15_t)0x6988, (q15_t)0xb791, (q15_t)0x6985, (q15_t)0xb78c, (q15_t)0x6981, (q15_t)0xb787, + (q15_t)0x697d, (q15_t)0xb782, (q15_t)0x697a, (q15_t)0xb77d, (q15_t)0x6976, (q15_t)0xb778, (q15_t)0x6973, (q15_t)0xb772, + (q15_t)0x696f, (q15_t)0xb76d, (q15_t)0x696c, (q15_t)0xb768, (q15_t)0x6968, (q15_t)0xb763, (q15_t)0x6964, (q15_t)0xb75e, + (q15_t)0x6961, (q15_t)0xb758, (q15_t)0x695d, (q15_t)0xb753, (q15_t)0x695a, (q15_t)0xb74e, (q15_t)0x6956, (q15_t)0xb749, + (q15_t)0x6953, (q15_t)0xb744, (q15_t)0x694f, (q15_t)0xb73f, (q15_t)0x694b, (q15_t)0xb739, (q15_t)0x6948, (q15_t)0xb734, + (q15_t)0x6944, (q15_t)0xb72f, (q15_t)0x6941, (q15_t)0xb72a, (q15_t)0x693d, (q15_t)0xb725, (q15_t)0x693a, (q15_t)0xb720, + (q15_t)0x6936, (q15_t)0xb71a, (q15_t)0x6932, (q15_t)0xb715, (q15_t)0x692f, (q15_t)0xb710, (q15_t)0x692b, (q15_t)0xb70b, + (q15_t)0x6928, (q15_t)0xb706, (q15_t)0x6924, (q15_t)0xb701, (q15_t)0x6921, (q15_t)0xb6fb, (q15_t)0x691d, (q15_t)0xb6f6, + (q15_t)0x6919, (q15_t)0xb6f1, (q15_t)0x6916, (q15_t)0xb6ec, (q15_t)0x6912, (q15_t)0xb6e7, (q15_t)0x690f, (q15_t)0xb6e2, + (q15_t)0x690b, (q15_t)0xb6dd, (q15_t)0x6907, (q15_t)0xb6d7, (q15_t)0x6904, (q15_t)0xb6d2, (q15_t)0x6900, (q15_t)0xb6cd, + (q15_t)0x68fd, (q15_t)0xb6c8, (q15_t)0x68f9, (q15_t)0xb6c3, (q15_t)0x68f5, (q15_t)0xb6be, (q15_t)0x68f2, (q15_t)0xb6b8, + (q15_t)0x68ee, (q15_t)0xb6b3, (q15_t)0x68eb, (q15_t)0xb6ae, (q15_t)0x68e7, (q15_t)0xb6a9, (q15_t)0x68e3, (q15_t)0xb6a4, + (q15_t)0x68e0, (q15_t)0xb69f, (q15_t)0x68dc, (q15_t)0xb69a, (q15_t)0x68d9, (q15_t)0xb694, (q15_t)0x68d5, (q15_t)0xb68f, + (q15_t)0x68d1, (q15_t)0xb68a, (q15_t)0x68ce, (q15_t)0xb685, (q15_t)0x68ca, (q15_t)0xb680, (q15_t)0x68c7, (q15_t)0xb67b, + (q15_t)0x68c3, (q15_t)0xb676, (q15_t)0x68bf, (q15_t)0xb670, (q15_t)0x68bc, (q15_t)0xb66b, (q15_t)0x68b8, (q15_t)0xb666, + (q15_t)0x68b5, (q15_t)0xb661, (q15_t)0x68b1, (q15_t)0xb65c, (q15_t)0x68ad, (q15_t)0xb657, (q15_t)0x68aa, (q15_t)0xb652, + (q15_t)0x68a6, (q15_t)0xb64c, (q15_t)0x68a3, (q15_t)0xb647, (q15_t)0x689f, (q15_t)0xb642, (q15_t)0x689b, (q15_t)0xb63d, + (q15_t)0x6898, (q15_t)0xb638, (q15_t)0x6894, (q15_t)0xb633, (q15_t)0x6890, (q15_t)0xb62e, (q15_t)0x688d, (q15_t)0xb628, + (q15_t)0x6889, (q15_t)0xb623, (q15_t)0x6886, (q15_t)0xb61e, (q15_t)0x6882, (q15_t)0xb619, (q15_t)0x687e, (q15_t)0xb614, + (q15_t)0x687b, (q15_t)0xb60f, (q15_t)0x6877, (q15_t)0xb60a, (q15_t)0x6873, (q15_t)0xb605, (q15_t)0x6870, (q15_t)0xb5ff, + (q15_t)0x686c, (q15_t)0xb5fa, (q15_t)0x6868, (q15_t)0xb5f5, (q15_t)0x6865, (q15_t)0xb5f0, (q15_t)0x6861, (q15_t)0xb5eb, + (q15_t)0x685e, (q15_t)0xb5e6, (q15_t)0x685a, (q15_t)0xb5e1, (q15_t)0x6856, (q15_t)0xb5dc, (q15_t)0x6853, (q15_t)0xb5d6, + (q15_t)0x684f, (q15_t)0xb5d1, (q15_t)0x684b, (q15_t)0xb5cc, (q15_t)0x6848, (q15_t)0xb5c7, (q15_t)0x6844, (q15_t)0xb5c2, + (q15_t)0x6840, (q15_t)0xb5bd, (q15_t)0x683d, (q15_t)0xb5b8, (q15_t)0x6839, (q15_t)0xb5b3, (q15_t)0x6835, (q15_t)0xb5ae, + (q15_t)0x6832, (q15_t)0xb5a8, (q15_t)0x682e, (q15_t)0xb5a3, (q15_t)0x682b, (q15_t)0xb59e, (q15_t)0x6827, (q15_t)0xb599, + (q15_t)0x6823, (q15_t)0xb594, (q15_t)0x6820, (q15_t)0xb58f, (q15_t)0x681c, (q15_t)0xb58a, (q15_t)0x6818, (q15_t)0xb585, + (q15_t)0x6815, (q15_t)0xb57f, (q15_t)0x6811, (q15_t)0xb57a, (q15_t)0x680d, (q15_t)0xb575, (q15_t)0x680a, (q15_t)0xb570, + (q15_t)0x6806, (q15_t)0xb56b, (q15_t)0x6802, (q15_t)0xb566, (q15_t)0x67ff, (q15_t)0xb561, (q15_t)0x67fb, (q15_t)0xb55c, + (q15_t)0x67f7, (q15_t)0xb557, (q15_t)0x67f4, (q15_t)0xb552, (q15_t)0x67f0, (q15_t)0xb54c, (q15_t)0x67ec, (q15_t)0xb547, + (q15_t)0x67e9, (q15_t)0xb542, (q15_t)0x67e5, (q15_t)0xb53d, (q15_t)0x67e1, (q15_t)0xb538, (q15_t)0x67de, (q15_t)0xb533, + (q15_t)0x67da, (q15_t)0xb52e, (q15_t)0x67d6, (q15_t)0xb529, (q15_t)0x67d3, (q15_t)0xb524, (q15_t)0x67cf, (q15_t)0xb51f, + (q15_t)0x67cb, (q15_t)0xb519, (q15_t)0x67c8, (q15_t)0xb514, (q15_t)0x67c4, (q15_t)0xb50f, (q15_t)0x67c0, (q15_t)0xb50a, + (q15_t)0x67bd, (q15_t)0xb505, (q15_t)0x67b9, (q15_t)0xb500, (q15_t)0x67b5, (q15_t)0xb4fb, (q15_t)0x67b2, (q15_t)0xb4f6, + (q15_t)0x67ae, (q15_t)0xb4f1, (q15_t)0x67aa, (q15_t)0xb4ec, (q15_t)0x67a6, (q15_t)0xb4e7, (q15_t)0x67a3, (q15_t)0xb4e1, + (q15_t)0x679f, (q15_t)0xb4dc, (q15_t)0x679b, (q15_t)0xb4d7, (q15_t)0x6798, (q15_t)0xb4d2, (q15_t)0x6794, (q15_t)0xb4cd, + (q15_t)0x6790, (q15_t)0xb4c8, (q15_t)0x678d, (q15_t)0xb4c3, (q15_t)0x6789, (q15_t)0xb4be, (q15_t)0x6785, (q15_t)0xb4b9, + (q15_t)0x6782, (q15_t)0xb4b4, (q15_t)0x677e, (q15_t)0xb4af, (q15_t)0x677a, (q15_t)0xb4aa, (q15_t)0x6776, (q15_t)0xb4a4, + (q15_t)0x6773, (q15_t)0xb49f, (q15_t)0x676f, (q15_t)0xb49a, (q15_t)0x676b, (q15_t)0xb495, (q15_t)0x6768, (q15_t)0xb490, + (q15_t)0x6764, (q15_t)0xb48b, (q15_t)0x6760, (q15_t)0xb486, (q15_t)0x675d, (q15_t)0xb481, (q15_t)0x6759, (q15_t)0xb47c, + (q15_t)0x6755, (q15_t)0xb477, (q15_t)0x6751, (q15_t)0xb472, (q15_t)0x674e, (q15_t)0xb46d, (q15_t)0x674a, (q15_t)0xb468, + (q15_t)0x6746, (q15_t)0xb462, (q15_t)0x6743, (q15_t)0xb45d, (q15_t)0x673f, (q15_t)0xb458, (q15_t)0x673b, (q15_t)0xb453, + (q15_t)0x6737, (q15_t)0xb44e, (q15_t)0x6734, (q15_t)0xb449, (q15_t)0x6730, (q15_t)0xb444, (q15_t)0x672c, (q15_t)0xb43f, + (q15_t)0x6729, (q15_t)0xb43a, (q15_t)0x6725, (q15_t)0xb435, (q15_t)0x6721, (q15_t)0xb430, (q15_t)0x671d, (q15_t)0xb42b, + (q15_t)0x671a, (q15_t)0xb426, (q15_t)0x6716, (q15_t)0xb421, (q15_t)0x6712, (q15_t)0xb41c, (q15_t)0x670e, (q15_t)0xb417, + (q15_t)0x670b, (q15_t)0xb411, (q15_t)0x6707, (q15_t)0xb40c, (q15_t)0x6703, (q15_t)0xb407, (q15_t)0x6700, (q15_t)0xb402, + (q15_t)0x66fc, (q15_t)0xb3fd, (q15_t)0x66f8, (q15_t)0xb3f8, (q15_t)0x66f4, (q15_t)0xb3f3, (q15_t)0x66f1, (q15_t)0xb3ee, + (q15_t)0x66ed, (q15_t)0xb3e9, (q15_t)0x66e9, (q15_t)0xb3e4, (q15_t)0x66e5, (q15_t)0xb3df, (q15_t)0x66e2, (q15_t)0xb3da, + (q15_t)0x66de, (q15_t)0xb3d5, (q15_t)0x66da, (q15_t)0xb3d0, (q15_t)0x66d6, (q15_t)0xb3cb, (q15_t)0x66d3, (q15_t)0xb3c6, + (q15_t)0x66cf, (q15_t)0xb3c1, (q15_t)0x66cb, (q15_t)0xb3bc, (q15_t)0x66c8, (q15_t)0xb3b7, (q15_t)0x66c4, (q15_t)0xb3b1, + (q15_t)0x66c0, (q15_t)0xb3ac, (q15_t)0x66bc, (q15_t)0xb3a7, (q15_t)0x66b9, (q15_t)0xb3a2, (q15_t)0x66b5, (q15_t)0xb39d, + (q15_t)0x66b1, (q15_t)0xb398, (q15_t)0x66ad, (q15_t)0xb393, (q15_t)0x66aa, (q15_t)0xb38e, (q15_t)0x66a6, (q15_t)0xb389, + (q15_t)0x66a2, (q15_t)0xb384, (q15_t)0x669e, (q15_t)0xb37f, (q15_t)0x669b, (q15_t)0xb37a, (q15_t)0x6697, (q15_t)0xb375, + (q15_t)0x6693, (q15_t)0xb370, (q15_t)0x668f, (q15_t)0xb36b, (q15_t)0x668b, (q15_t)0xb366, (q15_t)0x6688, (q15_t)0xb361, + (q15_t)0x6684, (q15_t)0xb35c, (q15_t)0x6680, (q15_t)0xb357, (q15_t)0x667c, (q15_t)0xb352, (q15_t)0x6679, (q15_t)0xb34d, + (q15_t)0x6675, (q15_t)0xb348, (q15_t)0x6671, (q15_t)0xb343, (q15_t)0x666d, (q15_t)0xb33e, (q15_t)0x666a, (q15_t)0xb339, + (q15_t)0x6666, (q15_t)0xb334, (q15_t)0x6662, (q15_t)0xb32f, (q15_t)0x665e, (q15_t)0xb32a, (q15_t)0x665b, (q15_t)0xb325, + (q15_t)0x6657, (q15_t)0xb31f, (q15_t)0x6653, (q15_t)0xb31a, (q15_t)0x664f, (q15_t)0xb315, (q15_t)0x664b, (q15_t)0xb310, + (q15_t)0x6648, (q15_t)0xb30b, (q15_t)0x6644, (q15_t)0xb306, (q15_t)0x6640, (q15_t)0xb301, (q15_t)0x663c, (q15_t)0xb2fc, + (q15_t)0x6639, (q15_t)0xb2f7, (q15_t)0x6635, (q15_t)0xb2f2, (q15_t)0x6631, (q15_t)0xb2ed, (q15_t)0x662d, (q15_t)0xb2e8, + (q15_t)0x6629, (q15_t)0xb2e3, (q15_t)0x6626, (q15_t)0xb2de, (q15_t)0x6622, (q15_t)0xb2d9, (q15_t)0x661e, (q15_t)0xb2d4, + (q15_t)0x661a, (q15_t)0xb2cf, (q15_t)0x6616, (q15_t)0xb2ca, (q15_t)0x6613, (q15_t)0xb2c5, (q15_t)0x660f, (q15_t)0xb2c0, + (q15_t)0x660b, (q15_t)0xb2bb, (q15_t)0x6607, (q15_t)0xb2b6, (q15_t)0x6603, (q15_t)0xb2b1, (q15_t)0x6600, (q15_t)0xb2ac, + (q15_t)0x65fc, (q15_t)0xb2a7, (q15_t)0x65f8, (q15_t)0xb2a2, (q15_t)0x65f4, (q15_t)0xb29d, (q15_t)0x65f0, (q15_t)0xb298, + (q15_t)0x65ed, (q15_t)0xb293, (q15_t)0x65e9, (q15_t)0xb28e, (q15_t)0x65e5, (q15_t)0xb289, (q15_t)0x65e1, (q15_t)0xb284, + (q15_t)0x65dd, (q15_t)0xb27f, (q15_t)0x65da, (q15_t)0xb27a, (q15_t)0x65d6, (q15_t)0xb275, (q15_t)0x65d2, (q15_t)0xb270, + (q15_t)0x65ce, (q15_t)0xb26b, (q15_t)0x65ca, (q15_t)0xb266, (q15_t)0x65c7, (q15_t)0xb261, (q15_t)0x65c3, (q15_t)0xb25c, + (q15_t)0x65bf, (q15_t)0xb257, (q15_t)0x65bb, (q15_t)0xb252, (q15_t)0x65b7, (q15_t)0xb24d, (q15_t)0x65b4, (q15_t)0xb248, + (q15_t)0x65b0, (q15_t)0xb243, (q15_t)0x65ac, (q15_t)0xb23e, (q15_t)0x65a8, (q15_t)0xb239, (q15_t)0x65a4, (q15_t)0xb234, + (q15_t)0x65a0, (q15_t)0xb22f, (q15_t)0x659d, (q15_t)0xb22a, (q15_t)0x6599, (q15_t)0xb225, (q15_t)0x6595, (q15_t)0xb220, + (q15_t)0x6591, (q15_t)0xb21b, (q15_t)0x658d, (q15_t)0xb216, (q15_t)0x658a, (q15_t)0xb211, (q15_t)0x6586, (q15_t)0xb20c, + (q15_t)0x6582, (q15_t)0xb207, (q15_t)0x657e, (q15_t)0xb202, (q15_t)0x657a, (q15_t)0xb1fd, (q15_t)0x6576, (q15_t)0xb1f8, + (q15_t)0x6573, (q15_t)0xb1f3, (q15_t)0x656f, (q15_t)0xb1ee, (q15_t)0x656b, (q15_t)0xb1e9, (q15_t)0x6567, (q15_t)0xb1e4, + (q15_t)0x6563, (q15_t)0xb1df, (q15_t)0x655f, (q15_t)0xb1da, (q15_t)0x655c, (q15_t)0xb1d6, (q15_t)0x6558, (q15_t)0xb1d1, + (q15_t)0x6554, (q15_t)0xb1cc, (q15_t)0x6550, (q15_t)0xb1c7, (q15_t)0x654c, (q15_t)0xb1c2, (q15_t)0x6548, (q15_t)0xb1bd, + (q15_t)0x6545, (q15_t)0xb1b8, (q15_t)0x6541, (q15_t)0xb1b3, (q15_t)0x653d, (q15_t)0xb1ae, (q15_t)0x6539, (q15_t)0xb1a9, + (q15_t)0x6535, (q15_t)0xb1a4, (q15_t)0x6531, (q15_t)0xb19f, (q15_t)0x652d, (q15_t)0xb19a, (q15_t)0x652a, (q15_t)0xb195, + (q15_t)0x6526, (q15_t)0xb190, (q15_t)0x6522, (q15_t)0xb18b, (q15_t)0x651e, (q15_t)0xb186, (q15_t)0x651a, (q15_t)0xb181, + (q15_t)0x6516, (q15_t)0xb17c, (q15_t)0x6513, (q15_t)0xb177, (q15_t)0x650f, (q15_t)0xb172, (q15_t)0x650b, (q15_t)0xb16d, + (q15_t)0x6507, (q15_t)0xb168, (q15_t)0x6503, (q15_t)0xb163, (q15_t)0x64ff, (q15_t)0xb15e, (q15_t)0x64fb, (q15_t)0xb159, + (q15_t)0x64f7, (q15_t)0xb154, (q15_t)0x64f4, (q15_t)0xb14f, (q15_t)0x64f0, (q15_t)0xb14a, (q15_t)0x64ec, (q15_t)0xb146, + (q15_t)0x64e8, (q15_t)0xb141, (q15_t)0x64e4, (q15_t)0xb13c, (q15_t)0x64e0, (q15_t)0xb137, (q15_t)0x64dc, (q15_t)0xb132, + (q15_t)0x64d9, (q15_t)0xb12d, (q15_t)0x64d5, (q15_t)0xb128, (q15_t)0x64d1, (q15_t)0xb123, (q15_t)0x64cd, (q15_t)0xb11e, + (q15_t)0x64c9, (q15_t)0xb119, (q15_t)0x64c5, (q15_t)0xb114, (q15_t)0x64c1, (q15_t)0xb10f, (q15_t)0x64bd, (q15_t)0xb10a, + (q15_t)0x64ba, (q15_t)0xb105, (q15_t)0x64b6, (q15_t)0xb100, (q15_t)0x64b2, (q15_t)0xb0fb, (q15_t)0x64ae, (q15_t)0xb0f6, + (q15_t)0x64aa, (q15_t)0xb0f1, (q15_t)0x64a6, (q15_t)0xb0ec, (q15_t)0x64a2, (q15_t)0xb0e8, (q15_t)0x649e, (q15_t)0xb0e3, + (q15_t)0x649b, (q15_t)0xb0de, (q15_t)0x6497, (q15_t)0xb0d9, (q15_t)0x6493, (q15_t)0xb0d4, (q15_t)0x648f, (q15_t)0xb0cf, + (q15_t)0x648b, (q15_t)0xb0ca, (q15_t)0x6487, (q15_t)0xb0c5, (q15_t)0x6483, (q15_t)0xb0c0, (q15_t)0x647f, (q15_t)0xb0bb, + (q15_t)0x647b, (q15_t)0xb0b6, (q15_t)0x6478, (q15_t)0xb0b1, (q15_t)0x6474, (q15_t)0xb0ac, (q15_t)0x6470, (q15_t)0xb0a7, + (q15_t)0x646c, (q15_t)0xb0a2, (q15_t)0x6468, (q15_t)0xb09e, (q15_t)0x6464, (q15_t)0xb099, (q15_t)0x6460, (q15_t)0xb094, + (q15_t)0x645c, (q15_t)0xb08f, (q15_t)0x6458, (q15_t)0xb08a, (q15_t)0x6454, (q15_t)0xb085, (q15_t)0x6451, (q15_t)0xb080, + (q15_t)0x644d, (q15_t)0xb07b, (q15_t)0x6449, (q15_t)0xb076, (q15_t)0x6445, (q15_t)0xb071, (q15_t)0x6441, (q15_t)0xb06c, + (q15_t)0x643d, (q15_t)0xb067, (q15_t)0x6439, (q15_t)0xb062, (q15_t)0x6435, (q15_t)0xb05e, (q15_t)0x6431, (q15_t)0xb059, + (q15_t)0x642d, (q15_t)0xb054, (q15_t)0x6429, (q15_t)0xb04f, (q15_t)0x6426, (q15_t)0xb04a, (q15_t)0x6422, (q15_t)0xb045, + (q15_t)0x641e, (q15_t)0xb040, (q15_t)0x641a, (q15_t)0xb03b, (q15_t)0x6416, (q15_t)0xb036, (q15_t)0x6412, (q15_t)0xb031, + (q15_t)0x640e, (q15_t)0xb02c, (q15_t)0x640a, (q15_t)0xb027, (q15_t)0x6406, (q15_t)0xb023, (q15_t)0x6402, (q15_t)0xb01e, + (q15_t)0x63fe, (q15_t)0xb019, (q15_t)0x63fa, (q15_t)0xb014, (q15_t)0x63f7, (q15_t)0xb00f, (q15_t)0x63f3, (q15_t)0xb00a, + (q15_t)0x63ef, (q15_t)0xb005, (q15_t)0x63eb, (q15_t)0xb000, (q15_t)0x63e7, (q15_t)0xaffb, (q15_t)0x63e3, (q15_t)0xaff6, + (q15_t)0x63df, (q15_t)0xaff1, (q15_t)0x63db, (q15_t)0xafed, (q15_t)0x63d7, (q15_t)0xafe8, (q15_t)0x63d3, (q15_t)0xafe3, + (q15_t)0x63cf, (q15_t)0xafde, (q15_t)0x63cb, (q15_t)0xafd9, (q15_t)0x63c7, (q15_t)0xafd4, (q15_t)0x63c3, (q15_t)0xafcf, + (q15_t)0x63c0, (q15_t)0xafca, (q15_t)0x63bc, (q15_t)0xafc5, (q15_t)0x63b8, (q15_t)0xafc1, (q15_t)0x63b4, (q15_t)0xafbc, + (q15_t)0x63b0, (q15_t)0xafb7, (q15_t)0x63ac, (q15_t)0xafb2, (q15_t)0x63a8, (q15_t)0xafad, (q15_t)0x63a4, (q15_t)0xafa8, + (q15_t)0x63a0, (q15_t)0xafa3, (q15_t)0x639c, (q15_t)0xaf9e, (q15_t)0x6398, (q15_t)0xaf99, (q15_t)0x6394, (q15_t)0xaf94, + (q15_t)0x6390, (q15_t)0xaf90, (q15_t)0x638c, (q15_t)0xaf8b, (q15_t)0x6388, (q15_t)0xaf86, (q15_t)0x6384, (q15_t)0xaf81, + (q15_t)0x6380, (q15_t)0xaf7c, (q15_t)0x637c, (q15_t)0xaf77, (q15_t)0x6378, (q15_t)0xaf72, (q15_t)0x6375, (q15_t)0xaf6d, + (q15_t)0x6371, (q15_t)0xaf69, (q15_t)0x636d, (q15_t)0xaf64, (q15_t)0x6369, (q15_t)0xaf5f, (q15_t)0x6365, (q15_t)0xaf5a, + (q15_t)0x6361, (q15_t)0xaf55, (q15_t)0x635d, (q15_t)0xaf50, (q15_t)0x6359, (q15_t)0xaf4b, (q15_t)0x6355, (q15_t)0xaf46, + (q15_t)0x6351, (q15_t)0xaf41, (q15_t)0x634d, (q15_t)0xaf3d, (q15_t)0x6349, (q15_t)0xaf38, (q15_t)0x6345, (q15_t)0xaf33, + (q15_t)0x6341, (q15_t)0xaf2e, (q15_t)0x633d, (q15_t)0xaf29, (q15_t)0x6339, (q15_t)0xaf24, (q15_t)0x6335, (q15_t)0xaf1f, + (q15_t)0x6331, (q15_t)0xaf1b, (q15_t)0x632d, (q15_t)0xaf16, (q15_t)0x6329, (q15_t)0xaf11, (q15_t)0x6325, (q15_t)0xaf0c, + (q15_t)0x6321, (q15_t)0xaf07, (q15_t)0x631d, (q15_t)0xaf02, (q15_t)0x6319, (q15_t)0xaefd, (q15_t)0x6315, (q15_t)0xaef8, + (q15_t)0x6311, (q15_t)0xaef4, (q15_t)0x630d, (q15_t)0xaeef, (q15_t)0x6309, (q15_t)0xaeea, (q15_t)0x6305, (q15_t)0xaee5, + (q15_t)0x6301, (q15_t)0xaee0, (q15_t)0x62fd, (q15_t)0xaedb, (q15_t)0x62f9, (q15_t)0xaed6, (q15_t)0x62f5, (q15_t)0xaed2, + (q15_t)0x62f2, (q15_t)0xaecd, (q15_t)0x62ee, (q15_t)0xaec8, (q15_t)0x62ea, (q15_t)0xaec3, (q15_t)0x62e6, (q15_t)0xaebe, + (q15_t)0x62e2, (q15_t)0xaeb9, (q15_t)0x62de, (q15_t)0xaeb4, (q15_t)0x62da, (q15_t)0xaeb0, (q15_t)0x62d6, (q15_t)0xaeab, + (q15_t)0x62d2, (q15_t)0xaea6, (q15_t)0x62ce, (q15_t)0xaea1, (q15_t)0x62ca, (q15_t)0xae9c, (q15_t)0x62c6, (q15_t)0xae97, + (q15_t)0x62c2, (q15_t)0xae92, (q15_t)0x62be, (q15_t)0xae8e, (q15_t)0x62ba, (q15_t)0xae89, (q15_t)0x62b6, (q15_t)0xae84, + (q15_t)0x62b2, (q15_t)0xae7f, (q15_t)0x62ae, (q15_t)0xae7a, (q15_t)0x62aa, (q15_t)0xae75, (q15_t)0x62a6, (q15_t)0xae71, + (q15_t)0x62a2, (q15_t)0xae6c, (q15_t)0x629e, (q15_t)0xae67, (q15_t)0x629a, (q15_t)0xae62, (q15_t)0x6296, (q15_t)0xae5d, + (q15_t)0x6292, (q15_t)0xae58, (q15_t)0x628e, (q15_t)0xae54, (q15_t)0x628a, (q15_t)0xae4f, (q15_t)0x6286, (q15_t)0xae4a, + (q15_t)0x6282, (q15_t)0xae45, (q15_t)0x627e, (q15_t)0xae40, (q15_t)0x627a, (q15_t)0xae3b, (q15_t)0x6275, (q15_t)0xae37, + (q15_t)0x6271, (q15_t)0xae32, (q15_t)0x626d, (q15_t)0xae2d, (q15_t)0x6269, (q15_t)0xae28, (q15_t)0x6265, (q15_t)0xae23, + (q15_t)0x6261, (q15_t)0xae1e, (q15_t)0x625d, (q15_t)0xae1a, (q15_t)0x6259, (q15_t)0xae15, (q15_t)0x6255, (q15_t)0xae10, + (q15_t)0x6251, (q15_t)0xae0b, (q15_t)0x624d, (q15_t)0xae06, (q15_t)0x6249, (q15_t)0xae01, (q15_t)0x6245, (q15_t)0xadfd, + (q15_t)0x6241, (q15_t)0xadf8, (q15_t)0x623d, (q15_t)0xadf3, (q15_t)0x6239, (q15_t)0xadee, (q15_t)0x6235, (q15_t)0xade9, + (q15_t)0x6231, (q15_t)0xade4, (q15_t)0x622d, (q15_t)0xade0, (q15_t)0x6229, (q15_t)0xaddb, (q15_t)0x6225, (q15_t)0xadd6, + (q15_t)0x6221, (q15_t)0xadd1, (q15_t)0x621d, (q15_t)0xadcc, (q15_t)0x6219, (q15_t)0xadc8, (q15_t)0x6215, (q15_t)0xadc3, + (q15_t)0x6211, (q15_t)0xadbe, (q15_t)0x620d, (q15_t)0xadb9, (q15_t)0x6209, (q15_t)0xadb4, (q15_t)0x6205, (q15_t)0xadaf, + (q15_t)0x6201, (q15_t)0xadab, (q15_t)0x61fd, (q15_t)0xada6, (q15_t)0x61f9, (q15_t)0xada1, (q15_t)0x61f5, (q15_t)0xad9c, + (q15_t)0x61f1, (q15_t)0xad97, (q15_t)0x61ec, (q15_t)0xad93, (q15_t)0x61e8, (q15_t)0xad8e, (q15_t)0x61e4, (q15_t)0xad89, + (q15_t)0x61e0, (q15_t)0xad84, (q15_t)0x61dc, (q15_t)0xad7f, (q15_t)0x61d8, (q15_t)0xad7b, (q15_t)0x61d4, (q15_t)0xad76, + (q15_t)0x61d0, (q15_t)0xad71, (q15_t)0x61cc, (q15_t)0xad6c, (q15_t)0x61c8, (q15_t)0xad67, (q15_t)0x61c4, (q15_t)0xad63, + (q15_t)0x61c0, (q15_t)0xad5e, (q15_t)0x61bc, (q15_t)0xad59, (q15_t)0x61b8, (q15_t)0xad54, (q15_t)0x61b4, (q15_t)0xad4f, + (q15_t)0x61b0, (q15_t)0xad4b, (q15_t)0x61ac, (q15_t)0xad46, (q15_t)0x61a8, (q15_t)0xad41, (q15_t)0x61a3, (q15_t)0xad3c, + (q15_t)0x619f, (q15_t)0xad37, (q15_t)0x619b, (q15_t)0xad33, (q15_t)0x6197, (q15_t)0xad2e, (q15_t)0x6193, (q15_t)0xad29, + (q15_t)0x618f, (q15_t)0xad24, (q15_t)0x618b, (q15_t)0xad1f, (q15_t)0x6187, (q15_t)0xad1b, (q15_t)0x6183, (q15_t)0xad16, + (q15_t)0x617f, (q15_t)0xad11, (q15_t)0x617b, (q15_t)0xad0c, (q15_t)0x6177, (q15_t)0xad08, (q15_t)0x6173, (q15_t)0xad03, + (q15_t)0x616f, (q15_t)0xacfe, (q15_t)0x616b, (q15_t)0xacf9, (q15_t)0x6166, (q15_t)0xacf4, (q15_t)0x6162, (q15_t)0xacf0, + (q15_t)0x615e, (q15_t)0xaceb, (q15_t)0x615a, (q15_t)0xace6, (q15_t)0x6156, (q15_t)0xace1, (q15_t)0x6152, (q15_t)0xacdd, + (q15_t)0x614e, (q15_t)0xacd8, (q15_t)0x614a, (q15_t)0xacd3, (q15_t)0x6146, (q15_t)0xacce, (q15_t)0x6142, (q15_t)0xacc9, + (q15_t)0x613e, (q15_t)0xacc5, (q15_t)0x613a, (q15_t)0xacc0, (q15_t)0x6135, (q15_t)0xacbb, (q15_t)0x6131, (q15_t)0xacb6, + (q15_t)0x612d, (q15_t)0xacb2, (q15_t)0x6129, (q15_t)0xacad, (q15_t)0x6125, (q15_t)0xaca8, (q15_t)0x6121, (q15_t)0xaca3, + (q15_t)0x611d, (q15_t)0xac9e, (q15_t)0x6119, (q15_t)0xac9a, (q15_t)0x6115, (q15_t)0xac95, (q15_t)0x6111, (q15_t)0xac90, + (q15_t)0x610d, (q15_t)0xac8b, (q15_t)0x6108, (q15_t)0xac87, (q15_t)0x6104, (q15_t)0xac82, (q15_t)0x6100, (q15_t)0xac7d, + (q15_t)0x60fc, (q15_t)0xac78, (q15_t)0x60f8, (q15_t)0xac74, (q15_t)0x60f4, (q15_t)0xac6f, (q15_t)0x60f0, (q15_t)0xac6a, + (q15_t)0x60ec, (q15_t)0xac65, (q15_t)0x60e8, (q15_t)0xac61, (q15_t)0x60e4, (q15_t)0xac5c, (q15_t)0x60df, (q15_t)0xac57, + (q15_t)0x60db, (q15_t)0xac52, (q15_t)0x60d7, (q15_t)0xac4e, (q15_t)0x60d3, (q15_t)0xac49, (q15_t)0x60cf, (q15_t)0xac44, + (q15_t)0x60cb, (q15_t)0xac3f, (q15_t)0x60c7, (q15_t)0xac3b, (q15_t)0x60c3, (q15_t)0xac36, (q15_t)0x60bf, (q15_t)0xac31, + (q15_t)0x60ba, (q15_t)0xac2c, (q15_t)0x60b6, (q15_t)0xac28, (q15_t)0x60b2, (q15_t)0xac23, (q15_t)0x60ae, (q15_t)0xac1e, + (q15_t)0x60aa, (q15_t)0xac19, (q15_t)0x60a6, (q15_t)0xac15, (q15_t)0x60a2, (q15_t)0xac10, (q15_t)0x609e, (q15_t)0xac0b, + (q15_t)0x6099, (q15_t)0xac06, (q15_t)0x6095, (q15_t)0xac02, (q15_t)0x6091, (q15_t)0xabfd, (q15_t)0x608d, (q15_t)0xabf8, + (q15_t)0x6089, (q15_t)0xabf3, (q15_t)0x6085, (q15_t)0xabef, (q15_t)0x6081, (q15_t)0xabea, (q15_t)0x607d, (q15_t)0xabe5, + (q15_t)0x6078, (q15_t)0xabe0, (q15_t)0x6074, (q15_t)0xabdc, (q15_t)0x6070, (q15_t)0xabd7, (q15_t)0x606c, (q15_t)0xabd2, + (q15_t)0x6068, (q15_t)0xabcd, (q15_t)0x6064, (q15_t)0xabc9, (q15_t)0x6060, (q15_t)0xabc4, (q15_t)0x605c, (q15_t)0xabbf, + (q15_t)0x6057, (q15_t)0xabbb, (q15_t)0x6053, (q15_t)0xabb6, (q15_t)0x604f, (q15_t)0xabb1, (q15_t)0x604b, (q15_t)0xabac, + (q15_t)0x6047, (q15_t)0xaba8, (q15_t)0x6043, (q15_t)0xaba3, (q15_t)0x603f, (q15_t)0xab9e, (q15_t)0x603a, (q15_t)0xab99, + (q15_t)0x6036, (q15_t)0xab95, (q15_t)0x6032, (q15_t)0xab90, (q15_t)0x602e, (q15_t)0xab8b, (q15_t)0x602a, (q15_t)0xab87, + (q15_t)0x6026, (q15_t)0xab82, (q15_t)0x6022, (q15_t)0xab7d, (q15_t)0x601d, (q15_t)0xab78, (q15_t)0x6019, (q15_t)0xab74, + (q15_t)0x6015, (q15_t)0xab6f, (q15_t)0x6011, (q15_t)0xab6a, (q15_t)0x600d, (q15_t)0xab66, (q15_t)0x6009, (q15_t)0xab61, + (q15_t)0x6004, (q15_t)0xab5c, (q15_t)0x6000, (q15_t)0xab57, (q15_t)0x5ffc, (q15_t)0xab53, (q15_t)0x5ff8, (q15_t)0xab4e, + (q15_t)0x5ff4, (q15_t)0xab49, (q15_t)0x5ff0, (q15_t)0xab45, (q15_t)0x5fec, (q15_t)0xab40, (q15_t)0x5fe7, (q15_t)0xab3b, + (q15_t)0x5fe3, (q15_t)0xab36, (q15_t)0x5fdf, (q15_t)0xab32, (q15_t)0x5fdb, (q15_t)0xab2d, (q15_t)0x5fd7, (q15_t)0xab28, + (q15_t)0x5fd3, (q15_t)0xab24, (q15_t)0x5fce, (q15_t)0xab1f, (q15_t)0x5fca, (q15_t)0xab1a, (q15_t)0x5fc6, (q15_t)0xab16, + (q15_t)0x5fc2, (q15_t)0xab11, (q15_t)0x5fbe, (q15_t)0xab0c, (q15_t)0x5fba, (q15_t)0xab07, (q15_t)0x5fb5, (q15_t)0xab03, + (q15_t)0x5fb1, (q15_t)0xaafe, (q15_t)0x5fad, (q15_t)0xaaf9, (q15_t)0x5fa9, (q15_t)0xaaf5, (q15_t)0x5fa5, (q15_t)0xaaf0, + (q15_t)0x5fa0, (q15_t)0xaaeb, (q15_t)0x5f9c, (q15_t)0xaae7, (q15_t)0x5f98, (q15_t)0xaae2, (q15_t)0x5f94, (q15_t)0xaadd, + (q15_t)0x5f90, (q15_t)0xaad8, (q15_t)0x5f8c, (q15_t)0xaad4, (q15_t)0x5f87, (q15_t)0xaacf, (q15_t)0x5f83, (q15_t)0xaaca, + (q15_t)0x5f7f, (q15_t)0xaac6, (q15_t)0x5f7b, (q15_t)0xaac1, (q15_t)0x5f77, (q15_t)0xaabc, (q15_t)0x5f72, (q15_t)0xaab8, + (q15_t)0x5f6e, (q15_t)0xaab3, (q15_t)0x5f6a, (q15_t)0xaaae, (q15_t)0x5f66, (q15_t)0xaaaa, (q15_t)0x5f62, (q15_t)0xaaa5, + (q15_t)0x5f5e, (q15_t)0xaaa0, (q15_t)0x5f59, (q15_t)0xaa9c, (q15_t)0x5f55, (q15_t)0xaa97, (q15_t)0x5f51, (q15_t)0xaa92, + (q15_t)0x5f4d, (q15_t)0xaa8e, (q15_t)0x5f49, (q15_t)0xaa89, (q15_t)0x5f44, (q15_t)0xaa84, (q15_t)0x5f40, (q15_t)0xaa7f, + (q15_t)0x5f3c, (q15_t)0xaa7b, (q15_t)0x5f38, (q15_t)0xaa76, (q15_t)0x5f34, (q15_t)0xaa71, (q15_t)0x5f2f, (q15_t)0xaa6d, + (q15_t)0x5f2b, (q15_t)0xaa68, (q15_t)0x5f27, (q15_t)0xaa63, (q15_t)0x5f23, (q15_t)0xaa5f, (q15_t)0x5f1f, (q15_t)0xaa5a, + (q15_t)0x5f1a, (q15_t)0xaa55, (q15_t)0x5f16, (q15_t)0xaa51, (q15_t)0x5f12, (q15_t)0xaa4c, (q15_t)0x5f0e, (q15_t)0xaa47, + (q15_t)0x5f0a, (q15_t)0xaa43, (q15_t)0x5f05, (q15_t)0xaa3e, (q15_t)0x5f01, (q15_t)0xaa39, (q15_t)0x5efd, (q15_t)0xaa35, + (q15_t)0x5ef9, (q15_t)0xaa30, (q15_t)0x5ef5, (q15_t)0xaa2b, (q15_t)0x5ef0, (q15_t)0xaa27, (q15_t)0x5eec, (q15_t)0xaa22, + (q15_t)0x5ee8, (q15_t)0xaa1d, (q15_t)0x5ee4, (q15_t)0xaa19, (q15_t)0x5edf, (q15_t)0xaa14, (q15_t)0x5edb, (q15_t)0xaa10, + (q15_t)0x5ed7, (q15_t)0xaa0b, (q15_t)0x5ed3, (q15_t)0xaa06, (q15_t)0x5ecf, (q15_t)0xaa02, (q15_t)0x5eca, (q15_t)0xa9fd, + (q15_t)0x5ec6, (q15_t)0xa9f8, (q15_t)0x5ec2, (q15_t)0xa9f4, (q15_t)0x5ebe, (q15_t)0xa9ef, (q15_t)0x5eb9, (q15_t)0xa9ea, + (q15_t)0x5eb5, (q15_t)0xa9e6, (q15_t)0x5eb1, (q15_t)0xa9e1, (q15_t)0x5ead, (q15_t)0xa9dc, (q15_t)0x5ea9, (q15_t)0xa9d8, + (q15_t)0x5ea4, (q15_t)0xa9d3, (q15_t)0x5ea0, (q15_t)0xa9ce, (q15_t)0x5e9c, (q15_t)0xa9ca, (q15_t)0x5e98, (q15_t)0xa9c5, + (q15_t)0x5e93, (q15_t)0xa9c0, (q15_t)0x5e8f, (q15_t)0xa9bc, (q15_t)0x5e8b, (q15_t)0xa9b7, (q15_t)0x5e87, (q15_t)0xa9b3, + (q15_t)0x5e82, (q15_t)0xa9ae, (q15_t)0x5e7e, (q15_t)0xa9a9, (q15_t)0x5e7a, (q15_t)0xa9a5, (q15_t)0x5e76, (q15_t)0xa9a0, + (q15_t)0x5e71, (q15_t)0xa99b, (q15_t)0x5e6d, (q15_t)0xa997, (q15_t)0x5e69, (q15_t)0xa992, (q15_t)0x5e65, (q15_t)0xa98d, + (q15_t)0x5e60, (q15_t)0xa989, (q15_t)0x5e5c, (q15_t)0xa984, (q15_t)0x5e58, (q15_t)0xa980, (q15_t)0x5e54, (q15_t)0xa97b, + (q15_t)0x5e50, (q15_t)0xa976, (q15_t)0x5e4b, (q15_t)0xa972, (q15_t)0x5e47, (q15_t)0xa96d, (q15_t)0x5e43, (q15_t)0xa968, + (q15_t)0x5e3f, (q15_t)0xa964, (q15_t)0x5e3a, (q15_t)0xa95f, (q15_t)0x5e36, (q15_t)0xa95b, (q15_t)0x5e32, (q15_t)0xa956, + (q15_t)0x5e2d, (q15_t)0xa951, (q15_t)0x5e29, (q15_t)0xa94d, (q15_t)0x5e25, (q15_t)0xa948, (q15_t)0x5e21, (q15_t)0xa943, + (q15_t)0x5e1c, (q15_t)0xa93f, (q15_t)0x5e18, (q15_t)0xa93a, (q15_t)0x5e14, (q15_t)0xa936, (q15_t)0x5e10, (q15_t)0xa931, + (q15_t)0x5e0b, (q15_t)0xa92c, (q15_t)0x5e07, (q15_t)0xa928, (q15_t)0x5e03, (q15_t)0xa923, (q15_t)0x5dff, (q15_t)0xa91e, + (q15_t)0x5dfa, (q15_t)0xa91a, (q15_t)0x5df6, (q15_t)0xa915, (q15_t)0x5df2, (q15_t)0xa911, (q15_t)0x5dee, (q15_t)0xa90c, + (q15_t)0x5de9, (q15_t)0xa907, (q15_t)0x5de5, (q15_t)0xa903, (q15_t)0x5de1, (q15_t)0xa8fe, (q15_t)0x5ddc, (q15_t)0xa8fa, + (q15_t)0x5dd8, (q15_t)0xa8f5, (q15_t)0x5dd4, (q15_t)0xa8f0, (q15_t)0x5dd0, (q15_t)0xa8ec, (q15_t)0x5dcb, (q15_t)0xa8e7, + (q15_t)0x5dc7, (q15_t)0xa8e3, (q15_t)0x5dc3, (q15_t)0xa8de, (q15_t)0x5dbf, (q15_t)0xa8d9, (q15_t)0x5dba, (q15_t)0xa8d5, + (q15_t)0x5db6, (q15_t)0xa8d0, (q15_t)0x5db2, (q15_t)0xa8cc, (q15_t)0x5dad, (q15_t)0xa8c7, (q15_t)0x5da9, (q15_t)0xa8c2, + (q15_t)0x5da5, (q15_t)0xa8be, (q15_t)0x5da1, (q15_t)0xa8b9, (q15_t)0x5d9c, (q15_t)0xa8b5, (q15_t)0x5d98, (q15_t)0xa8b0, + (q15_t)0x5d94, (q15_t)0xa8ab, (q15_t)0x5d8f, (q15_t)0xa8a7, (q15_t)0x5d8b, (q15_t)0xa8a2, (q15_t)0x5d87, (q15_t)0xa89e, + (q15_t)0x5d83, (q15_t)0xa899, (q15_t)0x5d7e, (q15_t)0xa894, (q15_t)0x5d7a, (q15_t)0xa890, (q15_t)0x5d76, (q15_t)0xa88b, + (q15_t)0x5d71, (q15_t)0xa887, (q15_t)0x5d6d, (q15_t)0xa882, (q15_t)0x5d69, (q15_t)0xa87d, (q15_t)0x5d65, (q15_t)0xa879, + (q15_t)0x5d60, (q15_t)0xa874, (q15_t)0x5d5c, (q15_t)0xa870, (q15_t)0x5d58, (q15_t)0xa86b, (q15_t)0x5d53, (q15_t)0xa867, + (q15_t)0x5d4f, (q15_t)0xa862, (q15_t)0x5d4b, (q15_t)0xa85d, (q15_t)0x5d46, (q15_t)0xa859, (q15_t)0x5d42, (q15_t)0xa854, + (q15_t)0x5d3e, (q15_t)0xa850, (q15_t)0x5d3a, (q15_t)0xa84b, (q15_t)0x5d35, (q15_t)0xa847, (q15_t)0x5d31, (q15_t)0xa842, + (q15_t)0x5d2d, (q15_t)0xa83d, (q15_t)0x5d28, (q15_t)0xa839, (q15_t)0x5d24, (q15_t)0xa834, (q15_t)0x5d20, (q15_t)0xa830, + (q15_t)0x5d1b, (q15_t)0xa82b, (q15_t)0x5d17, (q15_t)0xa827, (q15_t)0x5d13, (q15_t)0xa822, (q15_t)0x5d0e, (q15_t)0xa81d, + (q15_t)0x5d0a, (q15_t)0xa819, (q15_t)0x5d06, (q15_t)0xa814, (q15_t)0x5d01, (q15_t)0xa810, (q15_t)0x5cfd, (q15_t)0xa80b, + (q15_t)0x5cf9, (q15_t)0xa807, (q15_t)0x5cf5, (q15_t)0xa802, (q15_t)0x5cf0, (q15_t)0xa7fd, (q15_t)0x5cec, (q15_t)0xa7f9, + (q15_t)0x5ce8, (q15_t)0xa7f4, (q15_t)0x5ce3, (q15_t)0xa7f0, (q15_t)0x5cdf, (q15_t)0xa7eb, (q15_t)0x5cdb, (q15_t)0xa7e7, + (q15_t)0x5cd6, (q15_t)0xa7e2, (q15_t)0x5cd2, (q15_t)0xa7de, (q15_t)0x5cce, (q15_t)0xa7d9, (q15_t)0x5cc9, (q15_t)0xa7d4, + (q15_t)0x5cc5, (q15_t)0xa7d0, (q15_t)0x5cc1, (q15_t)0xa7cb, (q15_t)0x5cbc, (q15_t)0xa7c7, (q15_t)0x5cb8, (q15_t)0xa7c2, + (q15_t)0x5cb4, (q15_t)0xa7be, (q15_t)0x5caf, (q15_t)0xa7b9, (q15_t)0x5cab, (q15_t)0xa7b5, (q15_t)0x5ca7, (q15_t)0xa7b0, + (q15_t)0x5ca2, (q15_t)0xa7ab, (q15_t)0x5c9e, (q15_t)0xa7a7, (q15_t)0x5c9a, (q15_t)0xa7a2, (q15_t)0x5c95, (q15_t)0xa79e, + (q15_t)0x5c91, (q15_t)0xa799, (q15_t)0x5c8d, (q15_t)0xa795, (q15_t)0x5c88, (q15_t)0xa790, (q15_t)0x5c84, (q15_t)0xa78c, + (q15_t)0x5c80, (q15_t)0xa787, (q15_t)0x5c7b, (q15_t)0xa783, (q15_t)0x5c77, (q15_t)0xa77e, (q15_t)0x5c73, (q15_t)0xa779, + (q15_t)0x5c6e, (q15_t)0xa775, (q15_t)0x5c6a, (q15_t)0xa770, (q15_t)0x5c66, (q15_t)0xa76c, (q15_t)0x5c61, (q15_t)0xa767, + (q15_t)0x5c5d, (q15_t)0xa763, (q15_t)0x5c58, (q15_t)0xa75e, (q15_t)0x5c54, (q15_t)0xa75a, (q15_t)0x5c50, (q15_t)0xa755, + (q15_t)0x5c4b, (q15_t)0xa751, (q15_t)0x5c47, (q15_t)0xa74c, (q15_t)0x5c43, (q15_t)0xa748, (q15_t)0x5c3e, (q15_t)0xa743, + (q15_t)0x5c3a, (q15_t)0xa73f, (q15_t)0x5c36, (q15_t)0xa73a, (q15_t)0x5c31, (q15_t)0xa735, (q15_t)0x5c2d, (q15_t)0xa731, + (q15_t)0x5c29, (q15_t)0xa72c, (q15_t)0x5c24, (q15_t)0xa728, (q15_t)0x5c20, (q15_t)0xa723, (q15_t)0x5c1b, (q15_t)0xa71f, + (q15_t)0x5c17, (q15_t)0xa71a, (q15_t)0x5c13, (q15_t)0xa716, (q15_t)0x5c0e, (q15_t)0xa711, (q15_t)0x5c0a, (q15_t)0xa70d, + (q15_t)0x5c06, (q15_t)0xa708, (q15_t)0x5c01, (q15_t)0xa704, (q15_t)0x5bfd, (q15_t)0xa6ff, (q15_t)0x5bf9, (q15_t)0xa6fb, + (q15_t)0x5bf4, (q15_t)0xa6f6, (q15_t)0x5bf0, (q15_t)0xa6f2, (q15_t)0x5beb, (q15_t)0xa6ed, (q15_t)0x5be7, (q15_t)0xa6e9, + (q15_t)0x5be3, (q15_t)0xa6e4, (q15_t)0x5bde, (q15_t)0xa6e0, (q15_t)0x5bda, (q15_t)0xa6db, (q15_t)0x5bd6, (q15_t)0xa6d7, + (q15_t)0x5bd1, (q15_t)0xa6d2, (q15_t)0x5bcd, (q15_t)0xa6ce, (q15_t)0x5bc8, (q15_t)0xa6c9, (q15_t)0x5bc4, (q15_t)0xa6c5, + (q15_t)0x5bc0, (q15_t)0xa6c0, (q15_t)0x5bbb, (q15_t)0xa6bc, (q15_t)0x5bb7, (q15_t)0xa6b7, (q15_t)0x5bb2, (q15_t)0xa6b3, + (q15_t)0x5bae, (q15_t)0xa6ae, (q15_t)0x5baa, (q15_t)0xa6aa, (q15_t)0x5ba5, (q15_t)0xa6a5, (q15_t)0x5ba1, (q15_t)0xa6a1, + (q15_t)0x5b9d, (q15_t)0xa69c, (q15_t)0x5b98, (q15_t)0xa698, (q15_t)0x5b94, (q15_t)0xa693, (q15_t)0x5b8f, (q15_t)0xa68f, + (q15_t)0x5b8b, (q15_t)0xa68a, (q15_t)0x5b87, (q15_t)0xa686, (q15_t)0x5b82, (q15_t)0xa681, (q15_t)0x5b7e, (q15_t)0xa67d, + (q15_t)0x5b79, (q15_t)0xa678, (q15_t)0x5b75, (q15_t)0xa674, (q15_t)0x5b71, (q15_t)0xa66f, (q15_t)0x5b6c, (q15_t)0xa66b, + (q15_t)0x5b68, (q15_t)0xa666, (q15_t)0x5b63, (q15_t)0xa662, (q15_t)0x5b5f, (q15_t)0xa65d, (q15_t)0x5b5b, (q15_t)0xa659, + (q15_t)0x5b56, (q15_t)0xa654, (q15_t)0x5b52, (q15_t)0xa650, (q15_t)0x5b4d, (q15_t)0xa64b, (q15_t)0x5b49, (q15_t)0xa647, + (q15_t)0x5b45, (q15_t)0xa642, (q15_t)0x5b40, (q15_t)0xa63e, (q15_t)0x5b3c, (q15_t)0xa639, (q15_t)0x5b37, (q15_t)0xa635, + (q15_t)0x5b33, (q15_t)0xa630, (q15_t)0x5b2f, (q15_t)0xa62c, (q15_t)0x5b2a, (q15_t)0xa627, (q15_t)0x5b26, (q15_t)0xa623, + (q15_t)0x5b21, (q15_t)0xa61f, (q15_t)0x5b1d, (q15_t)0xa61a, (q15_t)0x5b19, (q15_t)0xa616, (q15_t)0x5b14, (q15_t)0xa611, + (q15_t)0x5b10, (q15_t)0xa60d, (q15_t)0x5b0b, (q15_t)0xa608, (q15_t)0x5b07, (q15_t)0xa604, (q15_t)0x5b02, (q15_t)0xa5ff, + (q15_t)0x5afe, (q15_t)0xa5fb, (q15_t)0x5afa, (q15_t)0xa5f6, (q15_t)0x5af5, (q15_t)0xa5f2, (q15_t)0x5af1, (q15_t)0xa5ed, + (q15_t)0x5aec, (q15_t)0xa5e9, (q15_t)0x5ae8, (q15_t)0xa5e4, (q15_t)0x5ae4, (q15_t)0xa5e0, (q15_t)0x5adf, (q15_t)0xa5dc, + (q15_t)0x5adb, (q15_t)0xa5d7, (q15_t)0x5ad6, (q15_t)0xa5d3, (q15_t)0x5ad2, (q15_t)0xa5ce, (q15_t)0x5acd, (q15_t)0xa5ca, + (q15_t)0x5ac9, (q15_t)0xa5c5, (q15_t)0x5ac5, (q15_t)0xa5c1, (q15_t)0x5ac0, (q15_t)0xa5bc, (q15_t)0x5abc, (q15_t)0xa5b8, + (q15_t)0x5ab7, (q15_t)0xa5b3, (q15_t)0x5ab3, (q15_t)0xa5af, (q15_t)0x5aae, (q15_t)0xa5aa, (q15_t)0x5aaa, (q15_t)0xa5a6, + (q15_t)0x5aa5, (q15_t)0xa5a2, (q15_t)0x5aa1, (q15_t)0xa59d, (q15_t)0x5a9d, (q15_t)0xa599, (q15_t)0x5a98, (q15_t)0xa594, + (q15_t)0x5a94, (q15_t)0xa590, (q15_t)0x5a8f, (q15_t)0xa58b, (q15_t)0x5a8b, (q15_t)0xa587, (q15_t)0x5a86, (q15_t)0xa582, + (q15_t)0x5a82, (q15_t)0xa57e, (q15_t)0x5a7e, (q15_t)0xa57a, (q15_t)0x5a79, (q15_t)0xa575, (q15_t)0x5a75, (q15_t)0xa571, + (q15_t)0x5a70, (q15_t)0xa56c, (q15_t)0x5a6c, (q15_t)0xa568, (q15_t)0x5a67, (q15_t)0xa563, (q15_t)0x5a63, (q15_t)0xa55f, + (q15_t)0x5a5e, (q15_t)0xa55b, (q15_t)0x5a5a, (q15_t)0xa556, (q15_t)0x5a56, (q15_t)0xa552, (q15_t)0x5a51, (q15_t)0xa54d, + (q15_t)0x5a4d, (q15_t)0xa549, (q15_t)0x5a48, (q15_t)0xa544, (q15_t)0x5a44, (q15_t)0xa540, (q15_t)0x5a3f, (q15_t)0xa53b, + (q15_t)0x5a3b, (q15_t)0xa537, (q15_t)0x5a36, (q15_t)0xa533, (q15_t)0x5a32, (q15_t)0xa52e, (q15_t)0x5a2d, (q15_t)0xa52a, + (q15_t)0x5a29, (q15_t)0xa525, (q15_t)0x5a24, (q15_t)0xa521, (q15_t)0x5a20, (q15_t)0xa51c, (q15_t)0x5a1c, (q15_t)0xa518, + (q15_t)0x5a17, (q15_t)0xa514, (q15_t)0x5a13, (q15_t)0xa50f, (q15_t)0x5a0e, (q15_t)0xa50b, (q15_t)0x5a0a, (q15_t)0xa506, + (q15_t)0x5a05, (q15_t)0xa502, (q15_t)0x5a01, (q15_t)0xa4fe, (q15_t)0x59fc, (q15_t)0xa4f9, (q15_t)0x59f8, (q15_t)0xa4f5, + (q15_t)0x59f3, (q15_t)0xa4f0, (q15_t)0x59ef, (q15_t)0xa4ec, (q15_t)0x59ea, (q15_t)0xa4e7, (q15_t)0x59e6, (q15_t)0xa4e3, + (q15_t)0x59e1, (q15_t)0xa4df, (q15_t)0x59dd, (q15_t)0xa4da, (q15_t)0x59d9, (q15_t)0xa4d6, (q15_t)0x59d4, (q15_t)0xa4d1, + (q15_t)0x59d0, (q15_t)0xa4cd, (q15_t)0x59cb, (q15_t)0xa4c9, (q15_t)0x59c7, (q15_t)0xa4c4, (q15_t)0x59c2, (q15_t)0xa4c0, + (q15_t)0x59be, (q15_t)0xa4bb, (q15_t)0x59b9, (q15_t)0xa4b7, (q15_t)0x59b5, (q15_t)0xa4b3, (q15_t)0x59b0, (q15_t)0xa4ae, + (q15_t)0x59ac, (q15_t)0xa4aa, (q15_t)0x59a7, (q15_t)0xa4a5, (q15_t)0x59a3, (q15_t)0xa4a1, (q15_t)0x599e, (q15_t)0xa49d, + (q15_t)0x599a, (q15_t)0xa498, (q15_t)0x5995, (q15_t)0xa494, (q15_t)0x5991, (q15_t)0xa48f, (q15_t)0x598c, (q15_t)0xa48b, + (q15_t)0x5988, (q15_t)0xa487, (q15_t)0x5983, (q15_t)0xa482, (q15_t)0x597f, (q15_t)0xa47e, (q15_t)0x597a, (q15_t)0xa479, + (q15_t)0x5976, (q15_t)0xa475, (q15_t)0x5971, (q15_t)0xa471, (q15_t)0x596d, (q15_t)0xa46c, (q15_t)0x5968, (q15_t)0xa468, + (q15_t)0x5964, (q15_t)0xa463, (q15_t)0x595f, (q15_t)0xa45f, (q15_t)0x595b, (q15_t)0xa45b, (q15_t)0x5956, (q15_t)0xa456, + (q15_t)0x5952, (q15_t)0xa452, (q15_t)0x594d, (q15_t)0xa44e, (q15_t)0x5949, (q15_t)0xa449, (q15_t)0x5944, (q15_t)0xa445, + (q15_t)0x5940, (q15_t)0xa440, (q15_t)0x593b, (q15_t)0xa43c, (q15_t)0x5937, (q15_t)0xa438, (q15_t)0x5932, (q15_t)0xa433, + (q15_t)0x592e, (q15_t)0xa42f, (q15_t)0x5929, (q15_t)0xa42a, (q15_t)0x5925, (q15_t)0xa426, (q15_t)0x5920, (q15_t)0xa422, + (q15_t)0x591c, (q15_t)0xa41d, (q15_t)0x5917, (q15_t)0xa419, (q15_t)0x5913, (q15_t)0xa415, (q15_t)0x590e, (q15_t)0xa410, + (q15_t)0x590a, (q15_t)0xa40c, (q15_t)0x5905, (q15_t)0xa407, (q15_t)0x5901, (q15_t)0xa403, (q15_t)0x58fc, (q15_t)0xa3ff, + (q15_t)0x58f8, (q15_t)0xa3fa, (q15_t)0x58f3, (q15_t)0xa3f6, (q15_t)0x58ef, (q15_t)0xa3f2, (q15_t)0x58ea, (q15_t)0xa3ed, + (q15_t)0x58e6, (q15_t)0xa3e9, (q15_t)0x58e1, (q15_t)0xa3e5, (q15_t)0x58dd, (q15_t)0xa3e0, (q15_t)0x58d8, (q15_t)0xa3dc, + (q15_t)0x58d4, (q15_t)0xa3d7, (q15_t)0x58cf, (q15_t)0xa3d3, (q15_t)0x58cb, (q15_t)0xa3cf, (q15_t)0x58c6, (q15_t)0xa3ca, + (q15_t)0x58c1, (q15_t)0xa3c6, (q15_t)0x58bd, (q15_t)0xa3c2, (q15_t)0x58b8, (q15_t)0xa3bd, (q15_t)0x58b4, (q15_t)0xa3b9, + (q15_t)0x58af, (q15_t)0xa3b5, (q15_t)0x58ab, (q15_t)0xa3b0, (q15_t)0x58a6, (q15_t)0xa3ac, (q15_t)0x58a2, (q15_t)0xa3a8, + (q15_t)0x589d, (q15_t)0xa3a3, (q15_t)0x5899, (q15_t)0xa39f, (q15_t)0x5894, (q15_t)0xa39a, (q15_t)0x5890, (q15_t)0xa396, + (q15_t)0x588b, (q15_t)0xa392, (q15_t)0x5887, (q15_t)0xa38d, (q15_t)0x5882, (q15_t)0xa389, (q15_t)0x587d, (q15_t)0xa385, + (q15_t)0x5879, (q15_t)0xa380, (q15_t)0x5874, (q15_t)0xa37c, (q15_t)0x5870, (q15_t)0xa378, (q15_t)0x586b, (q15_t)0xa373, + (q15_t)0x5867, (q15_t)0xa36f, (q15_t)0x5862, (q15_t)0xa36b, (q15_t)0x585e, (q15_t)0xa366, (q15_t)0x5859, (q15_t)0xa362, + (q15_t)0x5855, (q15_t)0xa35e, (q15_t)0x5850, (q15_t)0xa359, (q15_t)0x584b, (q15_t)0xa355, (q15_t)0x5847, (q15_t)0xa351, + (q15_t)0x5842, (q15_t)0xa34c, (q15_t)0x583e, (q15_t)0xa348, (q15_t)0x5839, (q15_t)0xa344, (q15_t)0x5835, (q15_t)0xa33f, + (q15_t)0x5830, (q15_t)0xa33b, (q15_t)0x582c, (q15_t)0xa337, (q15_t)0x5827, (q15_t)0xa332, (q15_t)0x5822, (q15_t)0xa32e, + (q15_t)0x581e, (q15_t)0xa32a, (q15_t)0x5819, (q15_t)0xa325, (q15_t)0x5815, (q15_t)0xa321, (q15_t)0x5810, (q15_t)0xa31d, + (q15_t)0x580c, (q15_t)0xa318, (q15_t)0x5807, (q15_t)0xa314, (q15_t)0x5803, (q15_t)0xa310, (q15_t)0x57fe, (q15_t)0xa30b, + (q15_t)0x57f9, (q15_t)0xa307, (q15_t)0x57f5, (q15_t)0xa303, (q15_t)0x57f0, (q15_t)0xa2ff, (q15_t)0x57ec, (q15_t)0xa2fa, + (q15_t)0x57e7, (q15_t)0xa2f6, (q15_t)0x57e3, (q15_t)0xa2f2, (q15_t)0x57de, (q15_t)0xa2ed, (q15_t)0x57d9, (q15_t)0xa2e9, + (q15_t)0x57d5, (q15_t)0xa2e5, (q15_t)0x57d0, (q15_t)0xa2e0, (q15_t)0x57cc, (q15_t)0xa2dc, (q15_t)0x57c7, (q15_t)0xa2d8, + (q15_t)0x57c3, (q15_t)0xa2d3, (q15_t)0x57be, (q15_t)0xa2cf, (q15_t)0x57b9, (q15_t)0xa2cb, (q15_t)0x57b5, (q15_t)0xa2c6, + (q15_t)0x57b0, (q15_t)0xa2c2, (q15_t)0x57ac, (q15_t)0xa2be, (q15_t)0x57a7, (q15_t)0xa2ba, (q15_t)0x57a3, (q15_t)0xa2b5, + (q15_t)0x579e, (q15_t)0xa2b1, (q15_t)0x5799, (q15_t)0xa2ad, (q15_t)0x5795, (q15_t)0xa2a8, (q15_t)0x5790, (q15_t)0xa2a4, + (q15_t)0x578c, (q15_t)0xa2a0, (q15_t)0x5787, (q15_t)0xa29b, (q15_t)0x5783, (q15_t)0xa297, (q15_t)0x577e, (q15_t)0xa293, + (q15_t)0x5779, (q15_t)0xa28f, (q15_t)0x5775, (q15_t)0xa28a, (q15_t)0x5770, (q15_t)0xa286, (q15_t)0x576c, (q15_t)0xa282, + (q15_t)0x5767, (q15_t)0xa27d, (q15_t)0x5762, (q15_t)0xa279, (q15_t)0x575e, (q15_t)0xa275, (q15_t)0x5759, (q15_t)0xa271, + (q15_t)0x5755, (q15_t)0xa26c, (q15_t)0x5750, (q15_t)0xa268, (q15_t)0x574b, (q15_t)0xa264, (q15_t)0x5747, (q15_t)0xa25f, + (q15_t)0x5742, (q15_t)0xa25b, (q15_t)0x573e, (q15_t)0xa257, (q15_t)0x5739, (q15_t)0xa253, (q15_t)0x5734, (q15_t)0xa24e, + (q15_t)0x5730, (q15_t)0xa24a, (q15_t)0x572b, (q15_t)0xa246, (q15_t)0x5727, (q15_t)0xa241, (q15_t)0x5722, (q15_t)0xa23d, + (q15_t)0x571d, (q15_t)0xa239, (q15_t)0x5719, (q15_t)0xa235, (q15_t)0x5714, (q15_t)0xa230, (q15_t)0x5710, (q15_t)0xa22c, + (q15_t)0x570b, (q15_t)0xa228, (q15_t)0x5706, (q15_t)0xa224, (q15_t)0x5702, (q15_t)0xa21f, (q15_t)0x56fd, (q15_t)0xa21b, + (q15_t)0x56f9, (q15_t)0xa217, (q15_t)0x56f4, (q15_t)0xa212, (q15_t)0x56ef, (q15_t)0xa20e, (q15_t)0x56eb, (q15_t)0xa20a, + (q15_t)0x56e6, (q15_t)0xa206, (q15_t)0x56e2, (q15_t)0xa201, (q15_t)0x56dd, (q15_t)0xa1fd, (q15_t)0x56d8, (q15_t)0xa1f9, + (q15_t)0x56d4, (q15_t)0xa1f5, (q15_t)0x56cf, (q15_t)0xa1f0, (q15_t)0x56ca, (q15_t)0xa1ec, (q15_t)0x56c6, (q15_t)0xa1e8, + (q15_t)0x56c1, (q15_t)0xa1e4, (q15_t)0x56bd, (q15_t)0xa1df, (q15_t)0x56b8, (q15_t)0xa1db, (q15_t)0x56b3, (q15_t)0xa1d7, + (q15_t)0x56af, (q15_t)0xa1d3, (q15_t)0x56aa, (q15_t)0xa1ce, (q15_t)0x56a5, (q15_t)0xa1ca, (q15_t)0x56a1, (q15_t)0xa1c6, + (q15_t)0x569c, (q15_t)0xa1c1, (q15_t)0x5698, (q15_t)0xa1bd, (q15_t)0x5693, (q15_t)0xa1b9, (q15_t)0x568e, (q15_t)0xa1b5, + (q15_t)0x568a, (q15_t)0xa1b0, (q15_t)0x5685, (q15_t)0xa1ac, (q15_t)0x5680, (q15_t)0xa1a8, (q15_t)0x567c, (q15_t)0xa1a4, + (q15_t)0x5677, (q15_t)0xa1a0, (q15_t)0x5673, (q15_t)0xa19b, (q15_t)0x566e, (q15_t)0xa197, (q15_t)0x5669, (q15_t)0xa193, + (q15_t)0x5665, (q15_t)0xa18f, (q15_t)0x5660, (q15_t)0xa18a, (q15_t)0x565b, (q15_t)0xa186, (q15_t)0x5657, (q15_t)0xa182, + (q15_t)0x5652, (q15_t)0xa17e, (q15_t)0x564d, (q15_t)0xa179, (q15_t)0x5649, (q15_t)0xa175, (q15_t)0x5644, (q15_t)0xa171, + (q15_t)0x5640, (q15_t)0xa16d, (q15_t)0x563b, (q15_t)0xa168, (q15_t)0x5636, (q15_t)0xa164, (q15_t)0x5632, (q15_t)0xa160, + (q15_t)0x562d, (q15_t)0xa15c, (q15_t)0x5628, (q15_t)0xa157, (q15_t)0x5624, (q15_t)0xa153, (q15_t)0x561f, (q15_t)0xa14f, + (q15_t)0x561a, (q15_t)0xa14b, (q15_t)0x5616, (q15_t)0xa147, (q15_t)0x5611, (q15_t)0xa142, (q15_t)0x560c, (q15_t)0xa13e, + (q15_t)0x5608, (q15_t)0xa13a, (q15_t)0x5603, (q15_t)0xa136, (q15_t)0x55fe, (q15_t)0xa131, (q15_t)0x55fa, (q15_t)0xa12d, + (q15_t)0x55f5, (q15_t)0xa129, (q15_t)0x55f0, (q15_t)0xa125, (q15_t)0x55ec, (q15_t)0xa121, (q15_t)0x55e7, (q15_t)0xa11c, + (q15_t)0x55e3, (q15_t)0xa118, (q15_t)0x55de, (q15_t)0xa114, (q15_t)0x55d9, (q15_t)0xa110, (q15_t)0x55d5, (q15_t)0xa10b, + (q15_t)0x55d0, (q15_t)0xa107, (q15_t)0x55cb, (q15_t)0xa103, (q15_t)0x55c7, (q15_t)0xa0ff, (q15_t)0x55c2, (q15_t)0xa0fb, + (q15_t)0x55bd, (q15_t)0xa0f6, (q15_t)0x55b9, (q15_t)0xa0f2, (q15_t)0x55b4, (q15_t)0xa0ee, (q15_t)0x55af, (q15_t)0xa0ea, + (q15_t)0x55ab, (q15_t)0xa0e6, (q15_t)0x55a6, (q15_t)0xa0e1, (q15_t)0x55a1, (q15_t)0xa0dd, (q15_t)0x559d, (q15_t)0xa0d9, + (q15_t)0x5598, (q15_t)0xa0d5, (q15_t)0x5593, (q15_t)0xa0d1, (q15_t)0x558f, (q15_t)0xa0cc, (q15_t)0x558a, (q15_t)0xa0c8, + (q15_t)0x5585, (q15_t)0xa0c4, (q15_t)0x5581, (q15_t)0xa0c0, (q15_t)0x557c, (q15_t)0xa0bc, (q15_t)0x5577, (q15_t)0xa0b7, + (q15_t)0x5572, (q15_t)0xa0b3, (q15_t)0x556e, (q15_t)0xa0af, (q15_t)0x5569, (q15_t)0xa0ab, (q15_t)0x5564, (q15_t)0xa0a7, + (q15_t)0x5560, (q15_t)0xa0a2, (q15_t)0x555b, (q15_t)0xa09e, (q15_t)0x5556, (q15_t)0xa09a, (q15_t)0x5552, (q15_t)0xa096, + (q15_t)0x554d, (q15_t)0xa092, (q15_t)0x5548, (q15_t)0xa08e, (q15_t)0x5544, (q15_t)0xa089, (q15_t)0x553f, (q15_t)0xa085, + (q15_t)0x553a, (q15_t)0xa081, (q15_t)0x5536, (q15_t)0xa07d, (q15_t)0x5531, (q15_t)0xa079, (q15_t)0x552c, (q15_t)0xa074, + (q15_t)0x5528, (q15_t)0xa070, (q15_t)0x5523, (q15_t)0xa06c, (q15_t)0x551e, (q15_t)0xa068, (q15_t)0x5519, (q15_t)0xa064, + (q15_t)0x5515, (q15_t)0xa060, (q15_t)0x5510, (q15_t)0xa05b, (q15_t)0x550b, (q15_t)0xa057, (q15_t)0x5507, (q15_t)0xa053, + (q15_t)0x5502, (q15_t)0xa04f, (q15_t)0x54fd, (q15_t)0xa04b, (q15_t)0x54f9, (q15_t)0xa046, (q15_t)0x54f4, (q15_t)0xa042, + (q15_t)0x54ef, (q15_t)0xa03e, (q15_t)0x54ea, (q15_t)0xa03a, (q15_t)0x54e6, (q15_t)0xa036, (q15_t)0x54e1, (q15_t)0xa032, + (q15_t)0x54dc, (q15_t)0xa02d, (q15_t)0x54d8, (q15_t)0xa029, (q15_t)0x54d3, (q15_t)0xa025, (q15_t)0x54ce, (q15_t)0xa021, + (q15_t)0x54ca, (q15_t)0xa01d, (q15_t)0x54c5, (q15_t)0xa019, (q15_t)0x54c0, (q15_t)0xa014, (q15_t)0x54bb, (q15_t)0xa010, + (q15_t)0x54b7, (q15_t)0xa00c, (q15_t)0x54b2, (q15_t)0xa008, (q15_t)0x54ad, (q15_t)0xa004, (q15_t)0x54a9, (q15_t)0xa000, + (q15_t)0x54a4, (q15_t)0x9ffc, (q15_t)0x549f, (q15_t)0x9ff7, (q15_t)0x549a, (q15_t)0x9ff3, (q15_t)0x5496, (q15_t)0x9fef, + (q15_t)0x5491, (q15_t)0x9feb, (q15_t)0x548c, (q15_t)0x9fe7, (q15_t)0x5488, (q15_t)0x9fe3, (q15_t)0x5483, (q15_t)0x9fde, + (q15_t)0x547e, (q15_t)0x9fda, (q15_t)0x5479, (q15_t)0x9fd6, (q15_t)0x5475, (q15_t)0x9fd2, (q15_t)0x5470, (q15_t)0x9fce, + (q15_t)0x546b, (q15_t)0x9fca, (q15_t)0x5467, (q15_t)0x9fc6, (q15_t)0x5462, (q15_t)0x9fc1, (q15_t)0x545d, (q15_t)0x9fbd, + (q15_t)0x5458, (q15_t)0x9fb9, (q15_t)0x5454, (q15_t)0x9fb5, (q15_t)0x544f, (q15_t)0x9fb1, (q15_t)0x544a, (q15_t)0x9fad, + (q15_t)0x5445, (q15_t)0x9fa9, (q15_t)0x5441, (q15_t)0x9fa4, (q15_t)0x543c, (q15_t)0x9fa0, (q15_t)0x5437, (q15_t)0x9f9c, + (q15_t)0x5433, (q15_t)0x9f98, (q15_t)0x542e, (q15_t)0x9f94, (q15_t)0x5429, (q15_t)0x9f90, (q15_t)0x5424, (q15_t)0x9f8c, + (q15_t)0x5420, (q15_t)0x9f88, (q15_t)0x541b, (q15_t)0x9f83, (q15_t)0x5416, (q15_t)0x9f7f, (q15_t)0x5411, (q15_t)0x9f7b, + (q15_t)0x540d, (q15_t)0x9f77, (q15_t)0x5408, (q15_t)0x9f73, (q15_t)0x5403, (q15_t)0x9f6f, (q15_t)0x53fe, (q15_t)0x9f6b, + (q15_t)0x53fa, (q15_t)0x9f67, (q15_t)0x53f5, (q15_t)0x9f62, (q15_t)0x53f0, (q15_t)0x9f5e, (q15_t)0x53eb, (q15_t)0x9f5a, + (q15_t)0x53e7, (q15_t)0x9f56, (q15_t)0x53e2, (q15_t)0x9f52, (q15_t)0x53dd, (q15_t)0x9f4e, (q15_t)0x53d8, (q15_t)0x9f4a, + (q15_t)0x53d4, (q15_t)0x9f46, (q15_t)0x53cf, (q15_t)0x9f41, (q15_t)0x53ca, (q15_t)0x9f3d, (q15_t)0x53c5, (q15_t)0x9f39, + (q15_t)0x53c1, (q15_t)0x9f35, (q15_t)0x53bc, (q15_t)0x9f31, (q15_t)0x53b7, (q15_t)0x9f2d, (q15_t)0x53b2, (q15_t)0x9f29, + (q15_t)0x53ae, (q15_t)0x9f25, (q15_t)0x53a9, (q15_t)0x9f21, (q15_t)0x53a4, (q15_t)0x9f1c, (q15_t)0x539f, (q15_t)0x9f18, + (q15_t)0x539b, (q15_t)0x9f14, (q15_t)0x5396, (q15_t)0x9f10, (q15_t)0x5391, (q15_t)0x9f0c, (q15_t)0x538c, (q15_t)0x9f08, + (q15_t)0x5388, (q15_t)0x9f04, (q15_t)0x5383, (q15_t)0x9f00, (q15_t)0x537e, (q15_t)0x9efc, (q15_t)0x5379, (q15_t)0x9ef8, + (q15_t)0x5375, (q15_t)0x9ef3, (q15_t)0x5370, (q15_t)0x9eef, (q15_t)0x536b, (q15_t)0x9eeb, (q15_t)0x5366, (q15_t)0x9ee7, + (q15_t)0x5362, (q15_t)0x9ee3, (q15_t)0x535d, (q15_t)0x9edf, (q15_t)0x5358, (q15_t)0x9edb, (q15_t)0x5353, (q15_t)0x9ed7, + (q15_t)0x534e, (q15_t)0x9ed3, (q15_t)0x534a, (q15_t)0x9ecf, (q15_t)0x5345, (q15_t)0x9ecb, (q15_t)0x5340, (q15_t)0x9ec6, + (q15_t)0x533b, (q15_t)0x9ec2, (q15_t)0x5337, (q15_t)0x9ebe, (q15_t)0x5332, (q15_t)0x9eba, (q15_t)0x532d, (q15_t)0x9eb6, + (q15_t)0x5328, (q15_t)0x9eb2, (q15_t)0x5323, (q15_t)0x9eae, (q15_t)0x531f, (q15_t)0x9eaa, (q15_t)0x531a, (q15_t)0x9ea6, + (q15_t)0x5315, (q15_t)0x9ea2, (q15_t)0x5310, (q15_t)0x9e9e, (q15_t)0x530c, (q15_t)0x9e9a, (q15_t)0x5307, (q15_t)0x9e95, + (q15_t)0x5302, (q15_t)0x9e91, (q15_t)0x52fd, (q15_t)0x9e8d, (q15_t)0x52f8, (q15_t)0x9e89, (q15_t)0x52f4, (q15_t)0x9e85, + (q15_t)0x52ef, (q15_t)0x9e81, (q15_t)0x52ea, (q15_t)0x9e7d, (q15_t)0x52e5, (q15_t)0x9e79, (q15_t)0x52e1, (q15_t)0x9e75, + (q15_t)0x52dc, (q15_t)0x9e71, (q15_t)0x52d7, (q15_t)0x9e6d, (q15_t)0x52d2, (q15_t)0x9e69, (q15_t)0x52cd, (q15_t)0x9e65, + (q15_t)0x52c9, (q15_t)0x9e61, (q15_t)0x52c4, (q15_t)0x9e5d, (q15_t)0x52bf, (q15_t)0x9e58, (q15_t)0x52ba, (q15_t)0x9e54, + (q15_t)0x52b5, (q15_t)0x9e50, (q15_t)0x52b1, (q15_t)0x9e4c, (q15_t)0x52ac, (q15_t)0x9e48, (q15_t)0x52a7, (q15_t)0x9e44, + (q15_t)0x52a2, (q15_t)0x9e40, (q15_t)0x529d, (q15_t)0x9e3c, (q15_t)0x5299, (q15_t)0x9e38, (q15_t)0x5294, (q15_t)0x9e34, + (q15_t)0x528f, (q15_t)0x9e30, (q15_t)0x528a, (q15_t)0x9e2c, (q15_t)0x5285, (q15_t)0x9e28, (q15_t)0x5281, (q15_t)0x9e24, + (q15_t)0x527c, (q15_t)0x9e20, (q15_t)0x5277, (q15_t)0x9e1c, (q15_t)0x5272, (q15_t)0x9e18, (q15_t)0x526d, (q15_t)0x9e14, + (q15_t)0x5269, (q15_t)0x9e0f, (q15_t)0x5264, (q15_t)0x9e0b, (q15_t)0x525f, (q15_t)0x9e07, (q15_t)0x525a, (q15_t)0x9e03, + (q15_t)0x5255, (q15_t)0x9dff, (q15_t)0x5251, (q15_t)0x9dfb, (q15_t)0x524c, (q15_t)0x9df7, (q15_t)0x5247, (q15_t)0x9df3, + (q15_t)0x5242, (q15_t)0x9def, (q15_t)0x523d, (q15_t)0x9deb, (q15_t)0x5238, (q15_t)0x9de7, (q15_t)0x5234, (q15_t)0x9de3, + (q15_t)0x522f, (q15_t)0x9ddf, (q15_t)0x522a, (q15_t)0x9ddb, (q15_t)0x5225, (q15_t)0x9dd7, (q15_t)0x5220, (q15_t)0x9dd3, + (q15_t)0x521c, (q15_t)0x9dcf, (q15_t)0x5217, (q15_t)0x9dcb, (q15_t)0x5212, (q15_t)0x9dc7, (q15_t)0x520d, (q15_t)0x9dc3, + (q15_t)0x5208, (q15_t)0x9dbf, (q15_t)0x5203, (q15_t)0x9dbb, (q15_t)0x51ff, (q15_t)0x9db7, (q15_t)0x51fa, (q15_t)0x9db3, + (q15_t)0x51f5, (q15_t)0x9daf, (q15_t)0x51f0, (q15_t)0x9dab, (q15_t)0x51eb, (q15_t)0x9da7, (q15_t)0x51e6, (q15_t)0x9da3, + (q15_t)0x51e2, (q15_t)0x9d9f, (q15_t)0x51dd, (q15_t)0x9d9b, (q15_t)0x51d8, (q15_t)0x9d97, (q15_t)0x51d3, (q15_t)0x9d93, + (q15_t)0x51ce, (q15_t)0x9d8f, (q15_t)0x51c9, (q15_t)0x9d8b, (q15_t)0x51c5, (q15_t)0x9d86, (q15_t)0x51c0, (q15_t)0x9d82, + (q15_t)0x51bb, (q15_t)0x9d7e, (q15_t)0x51b6, (q15_t)0x9d7a, (q15_t)0x51b1, (q15_t)0x9d76, (q15_t)0x51ac, (q15_t)0x9d72, + (q15_t)0x51a8, (q15_t)0x9d6e, (q15_t)0x51a3, (q15_t)0x9d6a, (q15_t)0x519e, (q15_t)0x9d66, (q15_t)0x5199, (q15_t)0x9d62, + (q15_t)0x5194, (q15_t)0x9d5e, (q15_t)0x518f, (q15_t)0x9d5a, (q15_t)0x518b, (q15_t)0x9d56, (q15_t)0x5186, (q15_t)0x9d52, + (q15_t)0x5181, (q15_t)0x9d4e, (q15_t)0x517c, (q15_t)0x9d4a, (q15_t)0x5177, (q15_t)0x9d46, (q15_t)0x5172, (q15_t)0x9d42, + (q15_t)0x516e, (q15_t)0x9d3e, (q15_t)0x5169, (q15_t)0x9d3a, (q15_t)0x5164, (q15_t)0x9d36, (q15_t)0x515f, (q15_t)0x9d32, + (q15_t)0x515a, (q15_t)0x9d2e, (q15_t)0x5155, (q15_t)0x9d2a, (q15_t)0x5150, (q15_t)0x9d26, (q15_t)0x514c, (q15_t)0x9d22, + (q15_t)0x5147, (q15_t)0x9d1e, (q15_t)0x5142, (q15_t)0x9d1a, (q15_t)0x513d, (q15_t)0x9d16, (q15_t)0x5138, (q15_t)0x9d12, + (q15_t)0x5133, (q15_t)0x9d0e, (q15_t)0x512e, (q15_t)0x9d0b, (q15_t)0x512a, (q15_t)0x9d07, (q15_t)0x5125, (q15_t)0x9d03, + (q15_t)0x5120, (q15_t)0x9cff, (q15_t)0x511b, (q15_t)0x9cfb, (q15_t)0x5116, (q15_t)0x9cf7, (q15_t)0x5111, (q15_t)0x9cf3, + (q15_t)0x510c, (q15_t)0x9cef, (q15_t)0x5108, (q15_t)0x9ceb, (q15_t)0x5103, (q15_t)0x9ce7, (q15_t)0x50fe, (q15_t)0x9ce3, + (q15_t)0x50f9, (q15_t)0x9cdf, (q15_t)0x50f4, (q15_t)0x9cdb, (q15_t)0x50ef, (q15_t)0x9cd7, (q15_t)0x50ea, (q15_t)0x9cd3, + (q15_t)0x50e5, (q15_t)0x9ccf, (q15_t)0x50e1, (q15_t)0x9ccb, (q15_t)0x50dc, (q15_t)0x9cc7, (q15_t)0x50d7, (q15_t)0x9cc3, + (q15_t)0x50d2, (q15_t)0x9cbf, (q15_t)0x50cd, (q15_t)0x9cbb, (q15_t)0x50c8, (q15_t)0x9cb7, (q15_t)0x50c3, (q15_t)0x9cb3, + (q15_t)0x50bf, (q15_t)0x9caf, (q15_t)0x50ba, (q15_t)0x9cab, (q15_t)0x50b5, (q15_t)0x9ca7, (q15_t)0x50b0, (q15_t)0x9ca3, + (q15_t)0x50ab, (q15_t)0x9c9f, (q15_t)0x50a6, (q15_t)0x9c9b, (q15_t)0x50a1, (q15_t)0x9c97, (q15_t)0x509c, (q15_t)0x9c93, + (q15_t)0x5097, (q15_t)0x9c8f, (q15_t)0x5093, (q15_t)0x9c8b, (q15_t)0x508e, (q15_t)0x9c88, (q15_t)0x5089, (q15_t)0x9c84, + (q15_t)0x5084, (q15_t)0x9c80, (q15_t)0x507f, (q15_t)0x9c7c, (q15_t)0x507a, (q15_t)0x9c78, (q15_t)0x5075, (q15_t)0x9c74, + (q15_t)0x5070, (q15_t)0x9c70, (q15_t)0x506c, (q15_t)0x9c6c, (q15_t)0x5067, (q15_t)0x9c68, (q15_t)0x5062, (q15_t)0x9c64, + (q15_t)0x505d, (q15_t)0x9c60, (q15_t)0x5058, (q15_t)0x9c5c, (q15_t)0x5053, (q15_t)0x9c58, (q15_t)0x504e, (q15_t)0x9c54, + (q15_t)0x5049, (q15_t)0x9c50, (q15_t)0x5044, (q15_t)0x9c4c, (q15_t)0x503f, (q15_t)0x9c48, (q15_t)0x503b, (q15_t)0x9c44, + (q15_t)0x5036, (q15_t)0x9c40, (q15_t)0x5031, (q15_t)0x9c3d, (q15_t)0x502c, (q15_t)0x9c39, (q15_t)0x5027, (q15_t)0x9c35, + (q15_t)0x5022, (q15_t)0x9c31, (q15_t)0x501d, (q15_t)0x9c2d, (q15_t)0x5018, (q15_t)0x9c29, (q15_t)0x5013, (q15_t)0x9c25, + (q15_t)0x500f, (q15_t)0x9c21, (q15_t)0x500a, (q15_t)0x9c1d, (q15_t)0x5005, (q15_t)0x9c19, (q15_t)0x5000, (q15_t)0x9c15, + (q15_t)0x4ffb, (q15_t)0x9c11, (q15_t)0x4ff6, (q15_t)0x9c0d, (q15_t)0x4ff1, (q15_t)0x9c09, (q15_t)0x4fec, (q15_t)0x9c06, + (q15_t)0x4fe7, (q15_t)0x9c02, (q15_t)0x4fe2, (q15_t)0x9bfe, (q15_t)0x4fdd, (q15_t)0x9bfa, (q15_t)0x4fd9, (q15_t)0x9bf6, + (q15_t)0x4fd4, (q15_t)0x9bf2, (q15_t)0x4fcf, (q15_t)0x9bee, (q15_t)0x4fca, (q15_t)0x9bea, (q15_t)0x4fc5, (q15_t)0x9be6, + (q15_t)0x4fc0, (q15_t)0x9be2, (q15_t)0x4fbb, (q15_t)0x9bde, (q15_t)0x4fb6, (q15_t)0x9bda, (q15_t)0x4fb1, (q15_t)0x9bd7, + (q15_t)0x4fac, (q15_t)0x9bd3, (q15_t)0x4fa7, (q15_t)0x9bcf, (q15_t)0x4fa2, (q15_t)0x9bcb, (q15_t)0x4f9e, (q15_t)0x9bc7, + (q15_t)0x4f99, (q15_t)0x9bc3, (q15_t)0x4f94, (q15_t)0x9bbf, (q15_t)0x4f8f, (q15_t)0x9bbb, (q15_t)0x4f8a, (q15_t)0x9bb7, + (q15_t)0x4f85, (q15_t)0x9bb3, (q15_t)0x4f80, (q15_t)0x9baf, (q15_t)0x4f7b, (q15_t)0x9bac, (q15_t)0x4f76, (q15_t)0x9ba8, + (q15_t)0x4f71, (q15_t)0x9ba4, (q15_t)0x4f6c, (q15_t)0x9ba0, (q15_t)0x4f67, (q15_t)0x9b9c, (q15_t)0x4f62, (q15_t)0x9b98, + (q15_t)0x4f5e, (q15_t)0x9b94, (q15_t)0x4f59, (q15_t)0x9b90, (q15_t)0x4f54, (q15_t)0x9b8c, (q15_t)0x4f4f, (q15_t)0x9b88, + (q15_t)0x4f4a, (q15_t)0x9b85, (q15_t)0x4f45, (q15_t)0x9b81, (q15_t)0x4f40, (q15_t)0x9b7d, (q15_t)0x4f3b, (q15_t)0x9b79, + (q15_t)0x4f36, (q15_t)0x9b75, (q15_t)0x4f31, (q15_t)0x9b71, (q15_t)0x4f2c, (q15_t)0x9b6d, (q15_t)0x4f27, (q15_t)0x9b69, + (q15_t)0x4f22, (q15_t)0x9b65, (q15_t)0x4f1d, (q15_t)0x9b62, (q15_t)0x4f18, (q15_t)0x9b5e, (q15_t)0x4f14, (q15_t)0x9b5a, + (q15_t)0x4f0f, (q15_t)0x9b56, (q15_t)0x4f0a, (q15_t)0x9b52, (q15_t)0x4f05, (q15_t)0x9b4e, (q15_t)0x4f00, (q15_t)0x9b4a, + (q15_t)0x4efb, (q15_t)0x9b46, (q15_t)0x4ef6, (q15_t)0x9b43, (q15_t)0x4ef1, (q15_t)0x9b3f, (q15_t)0x4eec, (q15_t)0x9b3b, + (q15_t)0x4ee7, (q15_t)0x9b37, (q15_t)0x4ee2, (q15_t)0x9b33, (q15_t)0x4edd, (q15_t)0x9b2f, (q15_t)0x4ed8, (q15_t)0x9b2b, + (q15_t)0x4ed3, (q15_t)0x9b27, (q15_t)0x4ece, (q15_t)0x9b24, (q15_t)0x4ec9, (q15_t)0x9b20, (q15_t)0x4ec4, (q15_t)0x9b1c, + (q15_t)0x4ebf, (q15_t)0x9b18, (q15_t)0x4eba, (q15_t)0x9b14, (q15_t)0x4eb6, (q15_t)0x9b10, (q15_t)0x4eb1, (q15_t)0x9b0c, + (q15_t)0x4eac, (q15_t)0x9b09, (q15_t)0x4ea7, (q15_t)0x9b05, (q15_t)0x4ea2, (q15_t)0x9b01, (q15_t)0x4e9d, (q15_t)0x9afd, + (q15_t)0x4e98, (q15_t)0x9af9, (q15_t)0x4e93, (q15_t)0x9af5, (q15_t)0x4e8e, (q15_t)0x9af1, (q15_t)0x4e89, (q15_t)0x9aed, + (q15_t)0x4e84, (q15_t)0x9aea, (q15_t)0x4e7f, (q15_t)0x9ae6, (q15_t)0x4e7a, (q15_t)0x9ae2, (q15_t)0x4e75, (q15_t)0x9ade, + (q15_t)0x4e70, (q15_t)0x9ada, (q15_t)0x4e6b, (q15_t)0x9ad6, (q15_t)0x4e66, (q15_t)0x9ad3, (q15_t)0x4e61, (q15_t)0x9acf, + (q15_t)0x4e5c, (q15_t)0x9acb, (q15_t)0x4e57, (q15_t)0x9ac7, (q15_t)0x4e52, (q15_t)0x9ac3, (q15_t)0x4e4d, (q15_t)0x9abf, + (q15_t)0x4e48, (q15_t)0x9abb, (q15_t)0x4e43, (q15_t)0x9ab8, (q15_t)0x4e3e, (q15_t)0x9ab4, (q15_t)0x4e39, (q15_t)0x9ab0, + (q15_t)0x4e34, (q15_t)0x9aac, (q15_t)0x4e2f, (q15_t)0x9aa8, (q15_t)0x4e2a, (q15_t)0x9aa4, (q15_t)0x4e26, (q15_t)0x9aa1, + (q15_t)0x4e21, (q15_t)0x9a9d, (q15_t)0x4e1c, (q15_t)0x9a99, (q15_t)0x4e17, (q15_t)0x9a95, (q15_t)0x4e12, (q15_t)0x9a91, + (q15_t)0x4e0d, (q15_t)0x9a8d, (q15_t)0x4e08, (q15_t)0x9a8a, (q15_t)0x4e03, (q15_t)0x9a86, (q15_t)0x4dfe, (q15_t)0x9a82, + (q15_t)0x4df9, (q15_t)0x9a7e, (q15_t)0x4df4, (q15_t)0x9a7a, (q15_t)0x4def, (q15_t)0x9a76, (q15_t)0x4dea, (q15_t)0x9a73, + (q15_t)0x4de5, (q15_t)0x9a6f, (q15_t)0x4de0, (q15_t)0x9a6b, (q15_t)0x4ddb, (q15_t)0x9a67, (q15_t)0x4dd6, (q15_t)0x9a63, + (q15_t)0x4dd1, (q15_t)0x9a60, (q15_t)0x4dcc, (q15_t)0x9a5c, (q15_t)0x4dc7, (q15_t)0x9a58, (q15_t)0x4dc2, (q15_t)0x9a54, + (q15_t)0x4dbd, (q15_t)0x9a50, (q15_t)0x4db8, (q15_t)0x9a4c, (q15_t)0x4db3, (q15_t)0x9a49, (q15_t)0x4dae, (q15_t)0x9a45, + (q15_t)0x4da9, (q15_t)0x9a41, (q15_t)0x4da4, (q15_t)0x9a3d, (q15_t)0x4d9f, (q15_t)0x9a39, (q15_t)0x4d9a, (q15_t)0x9a36, + (q15_t)0x4d95, (q15_t)0x9a32, (q15_t)0x4d90, (q15_t)0x9a2e, (q15_t)0x4d8b, (q15_t)0x9a2a, (q15_t)0x4d86, (q15_t)0x9a26, + (q15_t)0x4d81, (q15_t)0x9a23, (q15_t)0x4d7c, (q15_t)0x9a1f, (q15_t)0x4d77, (q15_t)0x9a1b, (q15_t)0x4d72, (q15_t)0x9a17, + (q15_t)0x4d6d, (q15_t)0x9a13, (q15_t)0x4d68, (q15_t)0x9a10, (q15_t)0x4d63, (q15_t)0x9a0c, (q15_t)0x4d5e, (q15_t)0x9a08, + (q15_t)0x4d59, (q15_t)0x9a04, (q15_t)0x4d54, (q15_t)0x9a00, (q15_t)0x4d4f, (q15_t)0x99fd, (q15_t)0x4d4a, (q15_t)0x99f9, + (q15_t)0x4d45, (q15_t)0x99f5, (q15_t)0x4d40, (q15_t)0x99f1, (q15_t)0x4d3b, (q15_t)0x99ed, (q15_t)0x4d36, (q15_t)0x99ea, + (q15_t)0x4d31, (q15_t)0x99e6, (q15_t)0x4d2c, (q15_t)0x99e2, (q15_t)0x4d27, (q15_t)0x99de, (q15_t)0x4d22, (q15_t)0x99da, + (q15_t)0x4d1d, (q15_t)0x99d7, (q15_t)0x4d18, (q15_t)0x99d3, (q15_t)0x4d13, (q15_t)0x99cf, (q15_t)0x4d0e, (q15_t)0x99cb, + (q15_t)0x4d09, (q15_t)0x99c7, (q15_t)0x4d04, (q15_t)0x99c4, (q15_t)0x4cff, (q15_t)0x99c0, (q15_t)0x4cfa, (q15_t)0x99bc, + (q15_t)0x4cf5, (q15_t)0x99b8, (q15_t)0x4cf0, (q15_t)0x99b5, (q15_t)0x4ceb, (q15_t)0x99b1, (q15_t)0x4ce6, (q15_t)0x99ad, + (q15_t)0x4ce1, (q15_t)0x99a9, (q15_t)0x4cdb, (q15_t)0x99a5, (q15_t)0x4cd6, (q15_t)0x99a2, (q15_t)0x4cd1, (q15_t)0x999e, + (q15_t)0x4ccc, (q15_t)0x999a, (q15_t)0x4cc7, (q15_t)0x9996, (q15_t)0x4cc2, (q15_t)0x9993, (q15_t)0x4cbd, (q15_t)0x998f, + (q15_t)0x4cb8, (q15_t)0x998b, (q15_t)0x4cb3, (q15_t)0x9987, (q15_t)0x4cae, (q15_t)0x9984, (q15_t)0x4ca9, (q15_t)0x9980, + (q15_t)0x4ca4, (q15_t)0x997c, (q15_t)0x4c9f, (q15_t)0x9978, (q15_t)0x4c9a, (q15_t)0x9975, (q15_t)0x4c95, (q15_t)0x9971, + (q15_t)0x4c90, (q15_t)0x996d, (q15_t)0x4c8b, (q15_t)0x9969, (q15_t)0x4c86, (q15_t)0x9965, (q15_t)0x4c81, (q15_t)0x9962, + (q15_t)0x4c7c, (q15_t)0x995e, (q15_t)0x4c77, (q15_t)0x995a, (q15_t)0x4c72, (q15_t)0x9956, (q15_t)0x4c6d, (q15_t)0x9953, + (q15_t)0x4c68, (q15_t)0x994f, (q15_t)0x4c63, (q15_t)0x994b, (q15_t)0x4c5e, (q15_t)0x9947, (q15_t)0x4c59, (q15_t)0x9944, + (q15_t)0x4c54, (q15_t)0x9940, (q15_t)0x4c4f, (q15_t)0x993c, (q15_t)0x4c49, (q15_t)0x9938, (q15_t)0x4c44, (q15_t)0x9935, + (q15_t)0x4c3f, (q15_t)0x9931, (q15_t)0x4c3a, (q15_t)0x992d, (q15_t)0x4c35, (q15_t)0x992a, (q15_t)0x4c30, (q15_t)0x9926, + (q15_t)0x4c2b, (q15_t)0x9922, (q15_t)0x4c26, (q15_t)0x991e, (q15_t)0x4c21, (q15_t)0x991b, (q15_t)0x4c1c, (q15_t)0x9917, + (q15_t)0x4c17, (q15_t)0x9913, (q15_t)0x4c12, (q15_t)0x990f, (q15_t)0x4c0d, (q15_t)0x990c, (q15_t)0x4c08, (q15_t)0x9908, + (q15_t)0x4c03, (q15_t)0x9904, (q15_t)0x4bfe, (q15_t)0x9900, (q15_t)0x4bf9, (q15_t)0x98fd, (q15_t)0x4bf4, (q15_t)0x98f9, + (q15_t)0x4bef, (q15_t)0x98f5, (q15_t)0x4be9, (q15_t)0x98f2, (q15_t)0x4be4, (q15_t)0x98ee, (q15_t)0x4bdf, (q15_t)0x98ea, + (q15_t)0x4bda, (q15_t)0x98e6, (q15_t)0x4bd5, (q15_t)0x98e3, (q15_t)0x4bd0, (q15_t)0x98df, (q15_t)0x4bcb, (q15_t)0x98db, + (q15_t)0x4bc6, (q15_t)0x98d7, (q15_t)0x4bc1, (q15_t)0x98d4, (q15_t)0x4bbc, (q15_t)0x98d0, (q15_t)0x4bb7, (q15_t)0x98cc, + (q15_t)0x4bb2, (q15_t)0x98c9, (q15_t)0x4bad, (q15_t)0x98c5, (q15_t)0x4ba8, (q15_t)0x98c1, (q15_t)0x4ba3, (q15_t)0x98bd, + (q15_t)0x4b9e, (q15_t)0x98ba, (q15_t)0x4b98, (q15_t)0x98b6, (q15_t)0x4b93, (q15_t)0x98b2, (q15_t)0x4b8e, (q15_t)0x98af, + (q15_t)0x4b89, (q15_t)0x98ab, (q15_t)0x4b84, (q15_t)0x98a7, (q15_t)0x4b7f, (q15_t)0x98a3, (q15_t)0x4b7a, (q15_t)0x98a0, + (q15_t)0x4b75, (q15_t)0x989c, (q15_t)0x4b70, (q15_t)0x9898, (q15_t)0x4b6b, (q15_t)0x9895, (q15_t)0x4b66, (q15_t)0x9891, + (q15_t)0x4b61, (q15_t)0x988d, (q15_t)0x4b5c, (q15_t)0x988a, (q15_t)0x4b56, (q15_t)0x9886, (q15_t)0x4b51, (q15_t)0x9882, + (q15_t)0x4b4c, (q15_t)0x987e, (q15_t)0x4b47, (q15_t)0x987b, (q15_t)0x4b42, (q15_t)0x9877, (q15_t)0x4b3d, (q15_t)0x9873, + (q15_t)0x4b38, (q15_t)0x9870, (q15_t)0x4b33, (q15_t)0x986c, (q15_t)0x4b2e, (q15_t)0x9868, (q15_t)0x4b29, (q15_t)0x9865, + (q15_t)0x4b24, (q15_t)0x9861, (q15_t)0x4b1f, (q15_t)0x985d, (q15_t)0x4b19, (q15_t)0x985a, (q15_t)0x4b14, (q15_t)0x9856, + (q15_t)0x4b0f, (q15_t)0x9852, (q15_t)0x4b0a, (q15_t)0x984e, (q15_t)0x4b05, (q15_t)0x984b, (q15_t)0x4b00, (q15_t)0x9847, + (q15_t)0x4afb, (q15_t)0x9843, (q15_t)0x4af6, (q15_t)0x9840, (q15_t)0x4af1, (q15_t)0x983c, (q15_t)0x4aec, (q15_t)0x9838, + (q15_t)0x4ae7, (q15_t)0x9835, (q15_t)0x4ae1, (q15_t)0x9831, (q15_t)0x4adc, (q15_t)0x982d, (q15_t)0x4ad7, (q15_t)0x982a, + (q15_t)0x4ad2, (q15_t)0x9826, (q15_t)0x4acd, (q15_t)0x9822, (q15_t)0x4ac8, (q15_t)0x981f, (q15_t)0x4ac3, (q15_t)0x981b, + (q15_t)0x4abe, (q15_t)0x9817, (q15_t)0x4ab9, (q15_t)0x9814, (q15_t)0x4ab4, (q15_t)0x9810, (q15_t)0x4aae, (q15_t)0x980c, + (q15_t)0x4aa9, (q15_t)0x9809, (q15_t)0x4aa4, (q15_t)0x9805, (q15_t)0x4a9f, (q15_t)0x9801, (q15_t)0x4a9a, (q15_t)0x97fe, + (q15_t)0x4a95, (q15_t)0x97fa, (q15_t)0x4a90, (q15_t)0x97f6, (q15_t)0x4a8b, (q15_t)0x97f3, (q15_t)0x4a86, (q15_t)0x97ef, + (q15_t)0x4a81, (q15_t)0x97eb, (q15_t)0x4a7b, (q15_t)0x97e8, (q15_t)0x4a76, (q15_t)0x97e4, (q15_t)0x4a71, (q15_t)0x97e0, + (q15_t)0x4a6c, (q15_t)0x97dd, (q15_t)0x4a67, (q15_t)0x97d9, (q15_t)0x4a62, (q15_t)0x97d5, (q15_t)0x4a5d, (q15_t)0x97d2, + (q15_t)0x4a58, (q15_t)0x97ce, (q15_t)0x4a52, (q15_t)0x97cb, (q15_t)0x4a4d, (q15_t)0x97c7, (q15_t)0x4a48, (q15_t)0x97c3, + (q15_t)0x4a43, (q15_t)0x97c0, (q15_t)0x4a3e, (q15_t)0x97bc, (q15_t)0x4a39, (q15_t)0x97b8, (q15_t)0x4a34, (q15_t)0x97b5, + (q15_t)0x4a2f, (q15_t)0x97b1, (q15_t)0x4a2a, (q15_t)0x97ad, (q15_t)0x4a24, (q15_t)0x97aa, (q15_t)0x4a1f, (q15_t)0x97a6, + (q15_t)0x4a1a, (q15_t)0x97a2, (q15_t)0x4a15, (q15_t)0x979f, (q15_t)0x4a10, (q15_t)0x979b, (q15_t)0x4a0b, (q15_t)0x9798, + (q15_t)0x4a06, (q15_t)0x9794, (q15_t)0x4a01, (q15_t)0x9790, (q15_t)0x49fb, (q15_t)0x978d, (q15_t)0x49f6, (q15_t)0x9789, + (q15_t)0x49f1, (q15_t)0x9785, (q15_t)0x49ec, (q15_t)0x9782, (q15_t)0x49e7, (q15_t)0x977e, (q15_t)0x49e2, (q15_t)0x977a, + (q15_t)0x49dd, (q15_t)0x9777, (q15_t)0x49d8, (q15_t)0x9773, (q15_t)0x49d2, (q15_t)0x9770, (q15_t)0x49cd, (q15_t)0x976c, + (q15_t)0x49c8, (q15_t)0x9768, (q15_t)0x49c3, (q15_t)0x9765, (q15_t)0x49be, (q15_t)0x9761, (q15_t)0x49b9, (q15_t)0x975d, + (q15_t)0x49b4, (q15_t)0x975a, (q15_t)0x49ae, (q15_t)0x9756, (q15_t)0x49a9, (q15_t)0x9753, (q15_t)0x49a4, (q15_t)0x974f, + (q15_t)0x499f, (q15_t)0x974b, (q15_t)0x499a, (q15_t)0x9748, (q15_t)0x4995, (q15_t)0x9744, (q15_t)0x4990, (q15_t)0x9741, + (q15_t)0x498a, (q15_t)0x973d, (q15_t)0x4985, (q15_t)0x9739, (q15_t)0x4980, (q15_t)0x9736, (q15_t)0x497b, (q15_t)0x9732, + (q15_t)0x4976, (q15_t)0x972f, (q15_t)0x4971, (q15_t)0x972b, (q15_t)0x496c, (q15_t)0x9727, (q15_t)0x4966, (q15_t)0x9724, + (q15_t)0x4961, (q15_t)0x9720, (q15_t)0x495c, (q15_t)0x971d, (q15_t)0x4957, (q15_t)0x9719, (q15_t)0x4952, (q15_t)0x9715, + (q15_t)0x494d, (q15_t)0x9712, (q15_t)0x4948, (q15_t)0x970e, (q15_t)0x4942, (q15_t)0x970b, (q15_t)0x493d, (q15_t)0x9707, + (q15_t)0x4938, (q15_t)0x9703, (q15_t)0x4933, (q15_t)0x9700, (q15_t)0x492e, (q15_t)0x96fc, (q15_t)0x4929, (q15_t)0x96f9, + (q15_t)0x4923, (q15_t)0x96f5, (q15_t)0x491e, (q15_t)0x96f1, (q15_t)0x4919, (q15_t)0x96ee, (q15_t)0x4914, (q15_t)0x96ea, + (q15_t)0x490f, (q15_t)0x96e7, (q15_t)0x490a, (q15_t)0x96e3, (q15_t)0x4905, (q15_t)0x96df, (q15_t)0x48ff, (q15_t)0x96dc, + (q15_t)0x48fa, (q15_t)0x96d8, (q15_t)0x48f5, (q15_t)0x96d5, (q15_t)0x48f0, (q15_t)0x96d1, (q15_t)0x48eb, (q15_t)0x96ce, + (q15_t)0x48e6, (q15_t)0x96ca, (q15_t)0x48e0, (q15_t)0x96c6, (q15_t)0x48db, (q15_t)0x96c3, (q15_t)0x48d6, (q15_t)0x96bf, + (q15_t)0x48d1, (q15_t)0x96bc, (q15_t)0x48cc, (q15_t)0x96b8, (q15_t)0x48c7, (q15_t)0x96b5, (q15_t)0x48c1, (q15_t)0x96b1, + (q15_t)0x48bc, (q15_t)0x96ad, (q15_t)0x48b7, (q15_t)0x96aa, (q15_t)0x48b2, (q15_t)0x96a6, (q15_t)0x48ad, (q15_t)0x96a3, + (q15_t)0x48a8, (q15_t)0x969f, (q15_t)0x48a2, (q15_t)0x969c, (q15_t)0x489d, (q15_t)0x9698, (q15_t)0x4898, (q15_t)0x9694, + (q15_t)0x4893, (q15_t)0x9691, (q15_t)0x488e, (q15_t)0x968d, (q15_t)0x4888, (q15_t)0x968a, (q15_t)0x4883, (q15_t)0x9686, + (q15_t)0x487e, (q15_t)0x9683, (q15_t)0x4879, (q15_t)0x967f, (q15_t)0x4874, (q15_t)0x967b, (q15_t)0x486f, (q15_t)0x9678, + (q15_t)0x4869, (q15_t)0x9674, (q15_t)0x4864, (q15_t)0x9671, (q15_t)0x485f, (q15_t)0x966d, (q15_t)0x485a, (q15_t)0x966a, + (q15_t)0x4855, (q15_t)0x9666, (q15_t)0x484f, (q15_t)0x9663, (q15_t)0x484a, (q15_t)0x965f, (q15_t)0x4845, (q15_t)0x965b, + (q15_t)0x4840, (q15_t)0x9658, (q15_t)0x483b, (q15_t)0x9654, (q15_t)0x4836, (q15_t)0x9651, (q15_t)0x4830, (q15_t)0x964d, + (q15_t)0x482b, (q15_t)0x964a, (q15_t)0x4826, (q15_t)0x9646, (q15_t)0x4821, (q15_t)0x9643, (q15_t)0x481c, (q15_t)0x963f, + (q15_t)0x4816, (q15_t)0x963c, (q15_t)0x4811, (q15_t)0x9638, (q15_t)0x480c, (q15_t)0x9635, (q15_t)0x4807, (q15_t)0x9631, + (q15_t)0x4802, (q15_t)0x962d, (q15_t)0x47fc, (q15_t)0x962a, (q15_t)0x47f7, (q15_t)0x9626, (q15_t)0x47f2, (q15_t)0x9623, + (q15_t)0x47ed, (q15_t)0x961f, (q15_t)0x47e8, (q15_t)0x961c, (q15_t)0x47e2, (q15_t)0x9618, (q15_t)0x47dd, (q15_t)0x9615, + (q15_t)0x47d8, (q15_t)0x9611, (q15_t)0x47d3, (q15_t)0x960e, (q15_t)0x47ce, (q15_t)0x960a, (q15_t)0x47c8, (q15_t)0x9607, + (q15_t)0x47c3, (q15_t)0x9603, (q15_t)0x47be, (q15_t)0x9600, (q15_t)0x47b9, (q15_t)0x95fc, (q15_t)0x47b4, (q15_t)0x95f9, + (q15_t)0x47ae, (q15_t)0x95f5, (q15_t)0x47a9, (q15_t)0x95f2, (q15_t)0x47a4, (q15_t)0x95ee, (q15_t)0x479f, (q15_t)0x95ea, + (q15_t)0x479a, (q15_t)0x95e7, (q15_t)0x4794, (q15_t)0x95e3, (q15_t)0x478f, (q15_t)0x95e0, (q15_t)0x478a, (q15_t)0x95dc, + (q15_t)0x4785, (q15_t)0x95d9, (q15_t)0x4780, (q15_t)0x95d5, (q15_t)0x477a, (q15_t)0x95d2, (q15_t)0x4775, (q15_t)0x95ce, + (q15_t)0x4770, (q15_t)0x95cb, (q15_t)0x476b, (q15_t)0x95c7, (q15_t)0x4765, (q15_t)0x95c4, (q15_t)0x4760, (q15_t)0x95c0, + (q15_t)0x475b, (q15_t)0x95bd, (q15_t)0x4756, (q15_t)0x95b9, (q15_t)0x4751, (q15_t)0x95b6, (q15_t)0x474b, (q15_t)0x95b2, + (q15_t)0x4746, (q15_t)0x95af, (q15_t)0x4741, (q15_t)0x95ab, (q15_t)0x473c, (q15_t)0x95a8, (q15_t)0x4737, (q15_t)0x95a4, + (q15_t)0x4731, (q15_t)0x95a1, (q15_t)0x472c, (q15_t)0x959d, (q15_t)0x4727, (q15_t)0x959a, (q15_t)0x4722, (q15_t)0x9596, + (q15_t)0x471c, (q15_t)0x9593, (q15_t)0x4717, (q15_t)0x958f, (q15_t)0x4712, (q15_t)0x958c, (q15_t)0x470d, (q15_t)0x9588, + (q15_t)0x4708, (q15_t)0x9585, (q15_t)0x4702, (q15_t)0x9581, (q15_t)0x46fd, (q15_t)0x957e, (q15_t)0x46f8, (q15_t)0x957a, + (q15_t)0x46f3, (q15_t)0x9577, (q15_t)0x46ed, (q15_t)0x9574, (q15_t)0x46e8, (q15_t)0x9570, (q15_t)0x46e3, (q15_t)0x956d, + (q15_t)0x46de, (q15_t)0x9569, (q15_t)0x46d8, (q15_t)0x9566, (q15_t)0x46d3, (q15_t)0x9562, (q15_t)0x46ce, (q15_t)0x955f, + (q15_t)0x46c9, (q15_t)0x955b, (q15_t)0x46c4, (q15_t)0x9558, (q15_t)0x46be, (q15_t)0x9554, (q15_t)0x46b9, (q15_t)0x9551, + (q15_t)0x46b4, (q15_t)0x954d, (q15_t)0x46af, (q15_t)0x954a, (q15_t)0x46a9, (q15_t)0x9546, (q15_t)0x46a4, (q15_t)0x9543, + (q15_t)0x469f, (q15_t)0x953f, (q15_t)0x469a, (q15_t)0x953c, (q15_t)0x4694, (q15_t)0x9538, (q15_t)0x468f, (q15_t)0x9535, + (q15_t)0x468a, (q15_t)0x9532, (q15_t)0x4685, (q15_t)0x952e, (q15_t)0x467f, (q15_t)0x952b, (q15_t)0x467a, (q15_t)0x9527, + (q15_t)0x4675, (q15_t)0x9524, (q15_t)0x4670, (q15_t)0x9520, (q15_t)0x466a, (q15_t)0x951d, (q15_t)0x4665, (q15_t)0x9519, + (q15_t)0x4660, (q15_t)0x9516, (q15_t)0x465b, (q15_t)0x9512, (q15_t)0x4655, (q15_t)0x950f, (q15_t)0x4650, (q15_t)0x950c, + (q15_t)0x464b, (q15_t)0x9508, (q15_t)0x4646, (q15_t)0x9505, (q15_t)0x4640, (q15_t)0x9501, (q15_t)0x463b, (q15_t)0x94fe, + (q15_t)0x4636, (q15_t)0x94fa, (q15_t)0x4631, (q15_t)0x94f7, (q15_t)0x462b, (q15_t)0x94f3, (q15_t)0x4626, (q15_t)0x94f0, + (q15_t)0x4621, (q15_t)0x94ed, (q15_t)0x461c, (q15_t)0x94e9, (q15_t)0x4616, (q15_t)0x94e6, (q15_t)0x4611, (q15_t)0x94e2, + (q15_t)0x460c, (q15_t)0x94df, (q15_t)0x4607, (q15_t)0x94db, (q15_t)0x4601, (q15_t)0x94d8, (q15_t)0x45fc, (q15_t)0x94d4, + (q15_t)0x45f7, (q15_t)0x94d1, (q15_t)0x45f2, (q15_t)0x94ce, (q15_t)0x45ec, (q15_t)0x94ca, (q15_t)0x45e7, (q15_t)0x94c7, + (q15_t)0x45e2, (q15_t)0x94c3, (q15_t)0x45dd, (q15_t)0x94c0, (q15_t)0x45d7, (q15_t)0x94bc, (q15_t)0x45d2, (q15_t)0x94b9, + (q15_t)0x45cd, (q15_t)0x94b6, (q15_t)0x45c7, (q15_t)0x94b2, (q15_t)0x45c2, (q15_t)0x94af, (q15_t)0x45bd, (q15_t)0x94ab, + (q15_t)0x45b8, (q15_t)0x94a8, (q15_t)0x45b2, (q15_t)0x94a4, (q15_t)0x45ad, (q15_t)0x94a1, (q15_t)0x45a8, (q15_t)0x949e, + (q15_t)0x45a3, (q15_t)0x949a, (q15_t)0x459d, (q15_t)0x9497, (q15_t)0x4598, (q15_t)0x9493, (q15_t)0x4593, (q15_t)0x9490, + (q15_t)0x458d, (q15_t)0x948d, (q15_t)0x4588, (q15_t)0x9489, (q15_t)0x4583, (q15_t)0x9486, (q15_t)0x457e, (q15_t)0x9482, + (q15_t)0x4578, (q15_t)0x947f, (q15_t)0x4573, (q15_t)0x947b, (q15_t)0x456e, (q15_t)0x9478, (q15_t)0x4569, (q15_t)0x9475, + (q15_t)0x4563, (q15_t)0x9471, (q15_t)0x455e, (q15_t)0x946e, (q15_t)0x4559, (q15_t)0x946a, (q15_t)0x4553, (q15_t)0x9467, + (q15_t)0x454e, (q15_t)0x9464, (q15_t)0x4549, (q15_t)0x9460, (q15_t)0x4544, (q15_t)0x945d, (q15_t)0x453e, (q15_t)0x9459, + (q15_t)0x4539, (q15_t)0x9456, (q15_t)0x4534, (q15_t)0x9453, (q15_t)0x452e, (q15_t)0x944f, (q15_t)0x4529, (q15_t)0x944c, + (q15_t)0x4524, (q15_t)0x9448, (q15_t)0x451f, (q15_t)0x9445, (q15_t)0x4519, (q15_t)0x9442, (q15_t)0x4514, (q15_t)0x943e, + (q15_t)0x450f, (q15_t)0x943b, (q15_t)0x4509, (q15_t)0x9437, (q15_t)0x4504, (q15_t)0x9434, (q15_t)0x44ff, (q15_t)0x9431, + (q15_t)0x44fa, (q15_t)0x942d, (q15_t)0x44f4, (q15_t)0x942a, (q15_t)0x44ef, (q15_t)0x9427, (q15_t)0x44ea, (q15_t)0x9423, + (q15_t)0x44e4, (q15_t)0x9420, (q15_t)0x44df, (q15_t)0x941c, (q15_t)0x44da, (q15_t)0x9419, (q15_t)0x44d4, (q15_t)0x9416, + (q15_t)0x44cf, (q15_t)0x9412, (q15_t)0x44ca, (q15_t)0x940f, (q15_t)0x44c5, (q15_t)0x940b, (q15_t)0x44bf, (q15_t)0x9408, + (q15_t)0x44ba, (q15_t)0x9405, (q15_t)0x44b5, (q15_t)0x9401, (q15_t)0x44af, (q15_t)0x93fe, (q15_t)0x44aa, (q15_t)0x93fb, + (q15_t)0x44a5, (q15_t)0x93f7, (q15_t)0x449f, (q15_t)0x93f4, (q15_t)0x449a, (q15_t)0x93f1, (q15_t)0x4495, (q15_t)0x93ed, + (q15_t)0x4490, (q15_t)0x93ea, (q15_t)0x448a, (q15_t)0x93e6, (q15_t)0x4485, (q15_t)0x93e3, (q15_t)0x4480, (q15_t)0x93e0, + (q15_t)0x447a, (q15_t)0x93dc, (q15_t)0x4475, (q15_t)0x93d9, (q15_t)0x4470, (q15_t)0x93d6, (q15_t)0x446a, (q15_t)0x93d2, + (q15_t)0x4465, (q15_t)0x93cf, (q15_t)0x4460, (q15_t)0x93cc, (q15_t)0x445a, (q15_t)0x93c8, (q15_t)0x4455, (q15_t)0x93c5, + (q15_t)0x4450, (q15_t)0x93c1, (q15_t)0x444b, (q15_t)0x93be, (q15_t)0x4445, (q15_t)0x93bb, (q15_t)0x4440, (q15_t)0x93b7, + (q15_t)0x443b, (q15_t)0x93b4, (q15_t)0x4435, (q15_t)0x93b1, (q15_t)0x4430, (q15_t)0x93ad, (q15_t)0x442b, (q15_t)0x93aa, + (q15_t)0x4425, (q15_t)0x93a7, (q15_t)0x4420, (q15_t)0x93a3, (q15_t)0x441b, (q15_t)0x93a0, (q15_t)0x4415, (q15_t)0x939d, + (q15_t)0x4410, (q15_t)0x9399, (q15_t)0x440b, (q15_t)0x9396, (q15_t)0x4405, (q15_t)0x9393, (q15_t)0x4400, (q15_t)0x938f, + (q15_t)0x43fb, (q15_t)0x938c, (q15_t)0x43f5, (q15_t)0x9389, (q15_t)0x43f0, (q15_t)0x9385, (q15_t)0x43eb, (q15_t)0x9382, + (q15_t)0x43e5, (q15_t)0x937f, (q15_t)0x43e0, (q15_t)0x937b, (q15_t)0x43db, (q15_t)0x9378, (q15_t)0x43d5, (q15_t)0x9375, + (q15_t)0x43d0, (q15_t)0x9371, (q15_t)0x43cb, (q15_t)0x936e, (q15_t)0x43c5, (q15_t)0x936b, (q15_t)0x43c0, (q15_t)0x9367, + (q15_t)0x43bb, (q15_t)0x9364, (q15_t)0x43b5, (q15_t)0x9361, (q15_t)0x43b0, (q15_t)0x935d, (q15_t)0x43ab, (q15_t)0x935a, + (q15_t)0x43a5, (q15_t)0x9357, (q15_t)0x43a0, (q15_t)0x9353, (q15_t)0x439b, (q15_t)0x9350, (q15_t)0x4395, (q15_t)0x934d, + (q15_t)0x4390, (q15_t)0x9349, (q15_t)0x438b, (q15_t)0x9346, (q15_t)0x4385, (q15_t)0x9343, (q15_t)0x4380, (q15_t)0x933f, + (q15_t)0x437b, (q15_t)0x933c, (q15_t)0x4375, (q15_t)0x9339, (q15_t)0x4370, (q15_t)0x9336, (q15_t)0x436b, (q15_t)0x9332, + (q15_t)0x4365, (q15_t)0x932f, (q15_t)0x4360, (q15_t)0x932c, (q15_t)0x435b, (q15_t)0x9328, (q15_t)0x4355, (q15_t)0x9325, + (q15_t)0x4350, (q15_t)0x9322, (q15_t)0x434b, (q15_t)0x931e, (q15_t)0x4345, (q15_t)0x931b, (q15_t)0x4340, (q15_t)0x9318, + (q15_t)0x433b, (q15_t)0x9314, (q15_t)0x4335, (q15_t)0x9311, (q15_t)0x4330, (q15_t)0x930e, (q15_t)0x432b, (q15_t)0x930b, + (q15_t)0x4325, (q15_t)0x9307, (q15_t)0x4320, (q15_t)0x9304, (q15_t)0x431b, (q15_t)0x9301, (q15_t)0x4315, (q15_t)0x92fd, + (q15_t)0x4310, (q15_t)0x92fa, (q15_t)0x430b, (q15_t)0x92f7, (q15_t)0x4305, (q15_t)0x92f4, (q15_t)0x4300, (q15_t)0x92f0, + (q15_t)0x42fa, (q15_t)0x92ed, (q15_t)0x42f5, (q15_t)0x92ea, (q15_t)0x42f0, (q15_t)0x92e6, (q15_t)0x42ea, (q15_t)0x92e3, + (q15_t)0x42e5, (q15_t)0x92e0, (q15_t)0x42e0, (q15_t)0x92dd, (q15_t)0x42da, (q15_t)0x92d9, (q15_t)0x42d5, (q15_t)0x92d6, + (q15_t)0x42d0, (q15_t)0x92d3, (q15_t)0x42ca, (q15_t)0x92cf, (q15_t)0x42c5, (q15_t)0x92cc, (q15_t)0x42c0, (q15_t)0x92c9, + (q15_t)0x42ba, (q15_t)0x92c6, (q15_t)0x42b5, (q15_t)0x92c2, (q15_t)0x42af, (q15_t)0x92bf, (q15_t)0x42aa, (q15_t)0x92bc, + (q15_t)0x42a5, (q15_t)0x92b8, (q15_t)0x429f, (q15_t)0x92b5, (q15_t)0x429a, (q15_t)0x92b2, (q15_t)0x4295, (q15_t)0x92af, + (q15_t)0x428f, (q15_t)0x92ab, (q15_t)0x428a, (q15_t)0x92a8, (q15_t)0x4284, (q15_t)0x92a5, (q15_t)0x427f, (q15_t)0x92a2, + (q15_t)0x427a, (q15_t)0x929e, (q15_t)0x4274, (q15_t)0x929b, (q15_t)0x426f, (q15_t)0x9298, (q15_t)0x426a, (q15_t)0x9295, + (q15_t)0x4264, (q15_t)0x9291, (q15_t)0x425f, (q15_t)0x928e, (q15_t)0x425a, (q15_t)0x928b, (q15_t)0x4254, (q15_t)0x9288, + (q15_t)0x424f, (q15_t)0x9284, (q15_t)0x4249, (q15_t)0x9281, (q15_t)0x4244, (q15_t)0x927e, (q15_t)0x423f, (q15_t)0x927b, + (q15_t)0x4239, (q15_t)0x9277, (q15_t)0x4234, (q15_t)0x9274, (q15_t)0x422f, (q15_t)0x9271, (q15_t)0x4229, (q15_t)0x926e, + (q15_t)0x4224, (q15_t)0x926a, (q15_t)0x421e, (q15_t)0x9267, (q15_t)0x4219, (q15_t)0x9264, (q15_t)0x4214, (q15_t)0x9261, + (q15_t)0x420e, (q15_t)0x925d, (q15_t)0x4209, (q15_t)0x925a, (q15_t)0x4203, (q15_t)0x9257, (q15_t)0x41fe, (q15_t)0x9254, + (q15_t)0x41f9, (q15_t)0x9250, (q15_t)0x41f3, (q15_t)0x924d, (q15_t)0x41ee, (q15_t)0x924a, (q15_t)0x41e9, (q15_t)0x9247, + (q15_t)0x41e3, (q15_t)0x9243, (q15_t)0x41de, (q15_t)0x9240, (q15_t)0x41d8, (q15_t)0x923d, (q15_t)0x41d3, (q15_t)0x923a, + (q15_t)0x41ce, (q15_t)0x9236, (q15_t)0x41c8, (q15_t)0x9233, (q15_t)0x41c3, (q15_t)0x9230, (q15_t)0x41bd, (q15_t)0x922d, + (q15_t)0x41b8, (q15_t)0x922a, (q15_t)0x41b3, (q15_t)0x9226, (q15_t)0x41ad, (q15_t)0x9223, (q15_t)0x41a8, (q15_t)0x9220, + (q15_t)0x41a2, (q15_t)0x921d, (q15_t)0x419d, (q15_t)0x9219, (q15_t)0x4198, (q15_t)0x9216, (q15_t)0x4192, (q15_t)0x9213, + (q15_t)0x418d, (q15_t)0x9210, (q15_t)0x4188, (q15_t)0x920d, (q15_t)0x4182, (q15_t)0x9209, (q15_t)0x417d, (q15_t)0x9206, + (q15_t)0x4177, (q15_t)0x9203, (q15_t)0x4172, (q15_t)0x9200, (q15_t)0x416d, (q15_t)0x91fc, (q15_t)0x4167, (q15_t)0x91f9, + (q15_t)0x4162, (q15_t)0x91f6, (q15_t)0x415c, (q15_t)0x91f3, (q15_t)0x4157, (q15_t)0x91f0, (q15_t)0x4152, (q15_t)0x91ec, + (q15_t)0x414c, (q15_t)0x91e9, (q15_t)0x4147, (q15_t)0x91e6, (q15_t)0x4141, (q15_t)0x91e3, (q15_t)0x413c, (q15_t)0x91e0, + (q15_t)0x4136, (q15_t)0x91dc, (q15_t)0x4131, (q15_t)0x91d9, (q15_t)0x412c, (q15_t)0x91d6, (q15_t)0x4126, (q15_t)0x91d3, + (q15_t)0x4121, (q15_t)0x91d0, (q15_t)0x411b, (q15_t)0x91cc, (q15_t)0x4116, (q15_t)0x91c9, (q15_t)0x4111, (q15_t)0x91c6, + (q15_t)0x410b, (q15_t)0x91c3, (q15_t)0x4106, (q15_t)0x91c0, (q15_t)0x4100, (q15_t)0x91bc, (q15_t)0x40fb, (q15_t)0x91b9, + (q15_t)0x40f6, (q15_t)0x91b6, (q15_t)0x40f0, (q15_t)0x91b3, (q15_t)0x40eb, (q15_t)0x91b0, (q15_t)0x40e5, (q15_t)0x91ad, + (q15_t)0x40e0, (q15_t)0x91a9, (q15_t)0x40da, (q15_t)0x91a6, (q15_t)0x40d5, (q15_t)0x91a3, (q15_t)0x40d0, (q15_t)0x91a0, + (q15_t)0x40ca, (q15_t)0x919d, (q15_t)0x40c5, (q15_t)0x9199, (q15_t)0x40bf, (q15_t)0x9196, (q15_t)0x40ba, (q15_t)0x9193, + (q15_t)0x40b5, (q15_t)0x9190, (q15_t)0x40af, (q15_t)0x918d, (q15_t)0x40aa, (q15_t)0x918a, (q15_t)0x40a4, (q15_t)0x9186, + (q15_t)0x409f, (q15_t)0x9183, (q15_t)0x4099, (q15_t)0x9180, (q15_t)0x4094, (q15_t)0x917d, (q15_t)0x408f, (q15_t)0x917a, + (q15_t)0x4089, (q15_t)0x9177, (q15_t)0x4084, (q15_t)0x9173, (q15_t)0x407e, (q15_t)0x9170, (q15_t)0x4079, (q15_t)0x916d, + (q15_t)0x4073, (q15_t)0x916a, (q15_t)0x406e, (q15_t)0x9167, (q15_t)0x4069, (q15_t)0x9164, (q15_t)0x4063, (q15_t)0x9160, + (q15_t)0x405e, (q15_t)0x915d, (q15_t)0x4058, (q15_t)0x915a, (q15_t)0x4053, (q15_t)0x9157, (q15_t)0x404d, (q15_t)0x9154, + (q15_t)0x4048, (q15_t)0x9151, (q15_t)0x4043, (q15_t)0x914d, (q15_t)0x403d, (q15_t)0x914a, (q15_t)0x4038, (q15_t)0x9147, + (q15_t)0x4032, (q15_t)0x9144, (q15_t)0x402d, (q15_t)0x9141, (q15_t)0x4027, (q15_t)0x913e, (q15_t)0x4022, (q15_t)0x913a, + (q15_t)0x401d, (q15_t)0x9137, (q15_t)0x4017, (q15_t)0x9134, (q15_t)0x4012, (q15_t)0x9131, (q15_t)0x400c, (q15_t)0x912e, + (q15_t)0x4007, (q15_t)0x912b, (q15_t)0x4001, (q15_t)0x9128, (q15_t)0x3ffc, (q15_t)0x9124, (q15_t)0x3ff6, (q15_t)0x9121, + (q15_t)0x3ff1, (q15_t)0x911e, (q15_t)0x3fec, (q15_t)0x911b, (q15_t)0x3fe6, (q15_t)0x9118, (q15_t)0x3fe1, (q15_t)0x9115, + (q15_t)0x3fdb, (q15_t)0x9112, (q15_t)0x3fd6, (q15_t)0x910f, (q15_t)0x3fd0, (q15_t)0x910b, (q15_t)0x3fcb, (q15_t)0x9108, + (q15_t)0x3fc5, (q15_t)0x9105, (q15_t)0x3fc0, (q15_t)0x9102, (q15_t)0x3fbb, (q15_t)0x90ff, (q15_t)0x3fb5, (q15_t)0x90fc, + (q15_t)0x3fb0, (q15_t)0x90f9, (q15_t)0x3faa, (q15_t)0x90f5, (q15_t)0x3fa5, (q15_t)0x90f2, (q15_t)0x3f9f, (q15_t)0x90ef, + (q15_t)0x3f9a, (q15_t)0x90ec, (q15_t)0x3f94, (q15_t)0x90e9, (q15_t)0x3f8f, (q15_t)0x90e6, (q15_t)0x3f89, (q15_t)0x90e3, + (q15_t)0x3f84, (q15_t)0x90e0, (q15_t)0x3f7f, (q15_t)0x90dd, (q15_t)0x3f79, (q15_t)0x90d9, (q15_t)0x3f74, (q15_t)0x90d6, + (q15_t)0x3f6e, (q15_t)0x90d3, (q15_t)0x3f69, (q15_t)0x90d0, (q15_t)0x3f63, (q15_t)0x90cd, (q15_t)0x3f5e, (q15_t)0x90ca, + (q15_t)0x3f58, (q15_t)0x90c7, (q15_t)0x3f53, (q15_t)0x90c4, (q15_t)0x3f4d, (q15_t)0x90c1, (q15_t)0x3f48, (q15_t)0x90bd, + (q15_t)0x3f43, (q15_t)0x90ba, (q15_t)0x3f3d, (q15_t)0x90b7, (q15_t)0x3f38, (q15_t)0x90b4, (q15_t)0x3f32, (q15_t)0x90b1, + (q15_t)0x3f2d, (q15_t)0x90ae, (q15_t)0x3f27, (q15_t)0x90ab, (q15_t)0x3f22, (q15_t)0x90a8, (q15_t)0x3f1c, (q15_t)0x90a5, + (q15_t)0x3f17, (q15_t)0x90a1, (q15_t)0x3f11, (q15_t)0x909e, (q15_t)0x3f0c, (q15_t)0x909b, (q15_t)0x3f06, (q15_t)0x9098, + (q15_t)0x3f01, (q15_t)0x9095, (q15_t)0x3efb, (q15_t)0x9092, (q15_t)0x3ef6, (q15_t)0x908f, (q15_t)0x3ef1, (q15_t)0x908c, + (q15_t)0x3eeb, (q15_t)0x9089, (q15_t)0x3ee6, (q15_t)0x9086, (q15_t)0x3ee0, (q15_t)0x9083, (q15_t)0x3edb, (q15_t)0x907f, + (q15_t)0x3ed5, (q15_t)0x907c, (q15_t)0x3ed0, (q15_t)0x9079, (q15_t)0x3eca, (q15_t)0x9076, (q15_t)0x3ec5, (q15_t)0x9073, + (q15_t)0x3ebf, (q15_t)0x9070, (q15_t)0x3eba, (q15_t)0x906d, (q15_t)0x3eb4, (q15_t)0x906a, (q15_t)0x3eaf, (q15_t)0x9067, + (q15_t)0x3ea9, (q15_t)0x9064, (q15_t)0x3ea4, (q15_t)0x9061, (q15_t)0x3e9e, (q15_t)0x905e, (q15_t)0x3e99, (q15_t)0x905b, + (q15_t)0x3e93, (q15_t)0x9057, (q15_t)0x3e8e, (q15_t)0x9054, (q15_t)0x3e88, (q15_t)0x9051, (q15_t)0x3e83, (q15_t)0x904e, + (q15_t)0x3e7d, (q15_t)0x904b, (q15_t)0x3e78, (q15_t)0x9048, (q15_t)0x3e73, (q15_t)0x9045, (q15_t)0x3e6d, (q15_t)0x9042, + (q15_t)0x3e68, (q15_t)0x903f, (q15_t)0x3e62, (q15_t)0x903c, (q15_t)0x3e5d, (q15_t)0x9039, (q15_t)0x3e57, (q15_t)0x9036, + (q15_t)0x3e52, (q15_t)0x9033, (q15_t)0x3e4c, (q15_t)0x9030, (q15_t)0x3e47, (q15_t)0x902d, (q15_t)0x3e41, (q15_t)0x902a, + (q15_t)0x3e3c, (q15_t)0x9026, (q15_t)0x3e36, (q15_t)0x9023, (q15_t)0x3e31, (q15_t)0x9020, (q15_t)0x3e2b, (q15_t)0x901d, + (q15_t)0x3e26, (q15_t)0x901a, (q15_t)0x3e20, (q15_t)0x9017, (q15_t)0x3e1b, (q15_t)0x9014, (q15_t)0x3e15, (q15_t)0x9011, + (q15_t)0x3e10, (q15_t)0x900e, (q15_t)0x3e0a, (q15_t)0x900b, (q15_t)0x3e05, (q15_t)0x9008, (q15_t)0x3dff, (q15_t)0x9005, + (q15_t)0x3dfa, (q15_t)0x9002, (q15_t)0x3df4, (q15_t)0x8fff, (q15_t)0x3def, (q15_t)0x8ffc, (q15_t)0x3de9, (q15_t)0x8ff9, + (q15_t)0x3de4, (q15_t)0x8ff6, (q15_t)0x3dde, (q15_t)0x8ff3, (q15_t)0x3dd9, (q15_t)0x8ff0, (q15_t)0x3dd3, (q15_t)0x8fed, + (q15_t)0x3dce, (q15_t)0x8fea, (q15_t)0x3dc8, (q15_t)0x8fe7, (q15_t)0x3dc3, (q15_t)0x8fe3, (q15_t)0x3dbd, (q15_t)0x8fe0, + (q15_t)0x3db8, (q15_t)0x8fdd, (q15_t)0x3db2, (q15_t)0x8fda, (q15_t)0x3dad, (q15_t)0x8fd7, (q15_t)0x3da7, (q15_t)0x8fd4, + (q15_t)0x3da2, (q15_t)0x8fd1, (q15_t)0x3d9c, (q15_t)0x8fce, (q15_t)0x3d97, (q15_t)0x8fcb, (q15_t)0x3d91, (q15_t)0x8fc8, + (q15_t)0x3d8c, (q15_t)0x8fc5, (q15_t)0x3d86, (q15_t)0x8fc2, (q15_t)0x3d81, (q15_t)0x8fbf, (q15_t)0x3d7b, (q15_t)0x8fbc, + (q15_t)0x3d76, (q15_t)0x8fb9, (q15_t)0x3d70, (q15_t)0x8fb6, (q15_t)0x3d6b, (q15_t)0x8fb3, (q15_t)0x3d65, (q15_t)0x8fb0, + (q15_t)0x3d60, (q15_t)0x8fad, (q15_t)0x3d5a, (q15_t)0x8faa, (q15_t)0x3d55, (q15_t)0x8fa7, (q15_t)0x3d4f, (q15_t)0x8fa4, + (q15_t)0x3d49, (q15_t)0x8fa1, (q15_t)0x3d44, (q15_t)0x8f9e, (q15_t)0x3d3e, (q15_t)0x8f9b, (q15_t)0x3d39, (q15_t)0x8f98, + (q15_t)0x3d33, (q15_t)0x8f95, (q15_t)0x3d2e, (q15_t)0x8f92, (q15_t)0x3d28, (q15_t)0x8f8f, (q15_t)0x3d23, (q15_t)0x8f8c, + (q15_t)0x3d1d, (q15_t)0x8f89, (q15_t)0x3d18, (q15_t)0x8f86, (q15_t)0x3d12, (q15_t)0x8f83, (q15_t)0x3d0d, (q15_t)0x8f80, + (q15_t)0x3d07, (q15_t)0x8f7d, (q15_t)0x3d02, (q15_t)0x8f7a, (q15_t)0x3cfc, (q15_t)0x8f77, (q15_t)0x3cf7, (q15_t)0x8f74, + (q15_t)0x3cf1, (q15_t)0x8f71, (q15_t)0x3cec, (q15_t)0x8f6e, (q15_t)0x3ce6, (q15_t)0x8f6b, (q15_t)0x3ce1, (q15_t)0x8f68, + (q15_t)0x3cdb, (q15_t)0x8f65, (q15_t)0x3cd6, (q15_t)0x8f62, (q15_t)0x3cd0, (q15_t)0x8f5f, (q15_t)0x3cca, (q15_t)0x8f5c, + (q15_t)0x3cc5, (q15_t)0x8f59, (q15_t)0x3cbf, (q15_t)0x8f56, (q15_t)0x3cba, (q15_t)0x8f53, (q15_t)0x3cb4, (q15_t)0x8f50, + (q15_t)0x3caf, (q15_t)0x8f4d, (q15_t)0x3ca9, (q15_t)0x8f4a, (q15_t)0x3ca4, (q15_t)0x8f47, (q15_t)0x3c9e, (q15_t)0x8f44, + (q15_t)0x3c99, (q15_t)0x8f41, (q15_t)0x3c93, (q15_t)0x8f3e, (q15_t)0x3c8e, (q15_t)0x8f3b, (q15_t)0x3c88, (q15_t)0x8f38, + (q15_t)0x3c83, (q15_t)0x8f35, (q15_t)0x3c7d, (q15_t)0x8f32, (q15_t)0x3c77, (q15_t)0x8f2f, (q15_t)0x3c72, (q15_t)0x8f2d, + (q15_t)0x3c6c, (q15_t)0x8f2a, (q15_t)0x3c67, (q15_t)0x8f27, (q15_t)0x3c61, (q15_t)0x8f24, (q15_t)0x3c5c, (q15_t)0x8f21, + (q15_t)0x3c56, (q15_t)0x8f1e, (q15_t)0x3c51, (q15_t)0x8f1b, (q15_t)0x3c4b, (q15_t)0x8f18, (q15_t)0x3c46, (q15_t)0x8f15, + (q15_t)0x3c40, (q15_t)0x8f12, (q15_t)0x3c3b, (q15_t)0x8f0f, (q15_t)0x3c35, (q15_t)0x8f0c, (q15_t)0x3c2f, (q15_t)0x8f09, + (q15_t)0x3c2a, (q15_t)0x8f06, (q15_t)0x3c24, (q15_t)0x8f03, (q15_t)0x3c1f, (q15_t)0x8f00, (q15_t)0x3c19, (q15_t)0x8efd, + (q15_t)0x3c14, (q15_t)0x8efa, (q15_t)0x3c0e, (q15_t)0x8ef7, (q15_t)0x3c09, (q15_t)0x8ef4, (q15_t)0x3c03, (q15_t)0x8ef1, + (q15_t)0x3bfd, (q15_t)0x8eee, (q15_t)0x3bf8, (q15_t)0x8eec, (q15_t)0x3bf2, (q15_t)0x8ee9, (q15_t)0x3bed, (q15_t)0x8ee6, + (q15_t)0x3be7, (q15_t)0x8ee3, (q15_t)0x3be2, (q15_t)0x8ee0, (q15_t)0x3bdc, (q15_t)0x8edd, (q15_t)0x3bd7, (q15_t)0x8eda, + (q15_t)0x3bd1, (q15_t)0x8ed7, (q15_t)0x3bcc, (q15_t)0x8ed4, (q15_t)0x3bc6, (q15_t)0x8ed1, (q15_t)0x3bc0, (q15_t)0x8ece, + (q15_t)0x3bbb, (q15_t)0x8ecb, (q15_t)0x3bb5, (q15_t)0x8ec8, (q15_t)0x3bb0, (q15_t)0x8ec5, (q15_t)0x3baa, (q15_t)0x8ec2, + (q15_t)0x3ba5, (q15_t)0x8ebf, (q15_t)0x3b9f, (q15_t)0x8ebd, (q15_t)0x3b99, (q15_t)0x8eba, (q15_t)0x3b94, (q15_t)0x8eb7, + (q15_t)0x3b8e, (q15_t)0x8eb4, (q15_t)0x3b89, (q15_t)0x8eb1, (q15_t)0x3b83, (q15_t)0x8eae, (q15_t)0x3b7e, (q15_t)0x8eab, + (q15_t)0x3b78, (q15_t)0x8ea8, (q15_t)0x3b73, (q15_t)0x8ea5, (q15_t)0x3b6d, (q15_t)0x8ea2, (q15_t)0x3b67, (q15_t)0x8e9f, + (q15_t)0x3b62, (q15_t)0x8e9c, (q15_t)0x3b5c, (q15_t)0x8e99, (q15_t)0x3b57, (q15_t)0x8e97, (q15_t)0x3b51, (q15_t)0x8e94, + (q15_t)0x3b4c, (q15_t)0x8e91, (q15_t)0x3b46, (q15_t)0x8e8e, (q15_t)0x3b40, (q15_t)0x8e8b, (q15_t)0x3b3b, (q15_t)0x8e88, + (q15_t)0x3b35, (q15_t)0x8e85, (q15_t)0x3b30, (q15_t)0x8e82, (q15_t)0x3b2a, (q15_t)0x8e7f, (q15_t)0x3b25, (q15_t)0x8e7c, + (q15_t)0x3b1f, (q15_t)0x8e7a, (q15_t)0x3b19, (q15_t)0x8e77, (q15_t)0x3b14, (q15_t)0x8e74, (q15_t)0x3b0e, (q15_t)0x8e71, + (q15_t)0x3b09, (q15_t)0x8e6e, (q15_t)0x3b03, (q15_t)0x8e6b, (q15_t)0x3afe, (q15_t)0x8e68, (q15_t)0x3af8, (q15_t)0x8e65, + (q15_t)0x3af2, (q15_t)0x8e62, (q15_t)0x3aed, (q15_t)0x8e5f, (q15_t)0x3ae7, (q15_t)0x8e5d, (q15_t)0x3ae2, (q15_t)0x8e5a, + (q15_t)0x3adc, (q15_t)0x8e57, (q15_t)0x3ad7, (q15_t)0x8e54, (q15_t)0x3ad1, (q15_t)0x8e51, (q15_t)0x3acb, (q15_t)0x8e4e, + (q15_t)0x3ac6, (q15_t)0x8e4b, (q15_t)0x3ac0, (q15_t)0x8e48, (q15_t)0x3abb, (q15_t)0x8e45, (q15_t)0x3ab5, (q15_t)0x8e43, + (q15_t)0x3aaf, (q15_t)0x8e40, (q15_t)0x3aaa, (q15_t)0x8e3d, (q15_t)0x3aa4, (q15_t)0x8e3a, (q15_t)0x3a9f, (q15_t)0x8e37, + (q15_t)0x3a99, (q15_t)0x8e34, (q15_t)0x3a94, (q15_t)0x8e31, (q15_t)0x3a8e, (q15_t)0x8e2e, (q15_t)0x3a88, (q15_t)0x8e2c, + (q15_t)0x3a83, (q15_t)0x8e29, (q15_t)0x3a7d, (q15_t)0x8e26, (q15_t)0x3a78, (q15_t)0x8e23, (q15_t)0x3a72, (q15_t)0x8e20, + (q15_t)0x3a6c, (q15_t)0x8e1d, (q15_t)0x3a67, (q15_t)0x8e1a, (q15_t)0x3a61, (q15_t)0x8e17, (q15_t)0x3a5c, (q15_t)0x8e15, + (q15_t)0x3a56, (q15_t)0x8e12, (q15_t)0x3a50, (q15_t)0x8e0f, (q15_t)0x3a4b, (q15_t)0x8e0c, (q15_t)0x3a45, (q15_t)0x8e09, + (q15_t)0x3a40, (q15_t)0x8e06, (q15_t)0x3a3a, (q15_t)0x8e03, (q15_t)0x3a34, (q15_t)0x8e01, (q15_t)0x3a2f, (q15_t)0x8dfe, + (q15_t)0x3a29, (q15_t)0x8dfb, (q15_t)0x3a24, (q15_t)0x8df8, (q15_t)0x3a1e, (q15_t)0x8df5, (q15_t)0x3a19, (q15_t)0x8df2, + (q15_t)0x3a13, (q15_t)0x8def, (q15_t)0x3a0d, (q15_t)0x8ded, (q15_t)0x3a08, (q15_t)0x8dea, (q15_t)0x3a02, (q15_t)0x8de7, + (q15_t)0x39fd, (q15_t)0x8de4, (q15_t)0x39f7, (q15_t)0x8de1, (q15_t)0x39f1, (q15_t)0x8dde, (q15_t)0x39ec, (q15_t)0x8ddc, + (q15_t)0x39e6, (q15_t)0x8dd9, (q15_t)0x39e0, (q15_t)0x8dd6, (q15_t)0x39db, (q15_t)0x8dd3, (q15_t)0x39d5, (q15_t)0x8dd0, + (q15_t)0x39d0, (q15_t)0x8dcd, (q15_t)0x39ca, (q15_t)0x8dca, (q15_t)0x39c4, (q15_t)0x8dc8, (q15_t)0x39bf, (q15_t)0x8dc5, + (q15_t)0x39b9, (q15_t)0x8dc2, (q15_t)0x39b4, (q15_t)0x8dbf, (q15_t)0x39ae, (q15_t)0x8dbc, (q15_t)0x39a8, (q15_t)0x8db9, + (q15_t)0x39a3, (q15_t)0x8db7, (q15_t)0x399d, (q15_t)0x8db4, (q15_t)0x3998, (q15_t)0x8db1, (q15_t)0x3992, (q15_t)0x8dae, + (q15_t)0x398c, (q15_t)0x8dab, (q15_t)0x3987, (q15_t)0x8da9, (q15_t)0x3981, (q15_t)0x8da6, (q15_t)0x397c, (q15_t)0x8da3, + (q15_t)0x3976, (q15_t)0x8da0, (q15_t)0x3970, (q15_t)0x8d9d, (q15_t)0x396b, (q15_t)0x8d9a, (q15_t)0x3965, (q15_t)0x8d98, + (q15_t)0x395f, (q15_t)0x8d95, (q15_t)0x395a, (q15_t)0x8d92, (q15_t)0x3954, (q15_t)0x8d8f, (q15_t)0x394f, (q15_t)0x8d8c, + (q15_t)0x3949, (q15_t)0x8d8a, (q15_t)0x3943, (q15_t)0x8d87, (q15_t)0x393e, (q15_t)0x8d84, (q15_t)0x3938, (q15_t)0x8d81, + (q15_t)0x3932, (q15_t)0x8d7e, (q15_t)0x392d, (q15_t)0x8d7b, (q15_t)0x3927, (q15_t)0x8d79, (q15_t)0x3922, (q15_t)0x8d76, + (q15_t)0x391c, (q15_t)0x8d73, (q15_t)0x3916, (q15_t)0x8d70, (q15_t)0x3911, (q15_t)0x8d6d, (q15_t)0x390b, (q15_t)0x8d6b, + (q15_t)0x3906, (q15_t)0x8d68, (q15_t)0x3900, (q15_t)0x8d65, (q15_t)0x38fa, (q15_t)0x8d62, (q15_t)0x38f5, (q15_t)0x8d5f, + (q15_t)0x38ef, (q15_t)0x8d5d, (q15_t)0x38e9, (q15_t)0x8d5a, (q15_t)0x38e4, (q15_t)0x8d57, (q15_t)0x38de, (q15_t)0x8d54, + (q15_t)0x38d8, (q15_t)0x8d51, (q15_t)0x38d3, (q15_t)0x8d4f, (q15_t)0x38cd, (q15_t)0x8d4c, (q15_t)0x38c8, (q15_t)0x8d49, + (q15_t)0x38c2, (q15_t)0x8d46, (q15_t)0x38bc, (q15_t)0x8d44, (q15_t)0x38b7, (q15_t)0x8d41, (q15_t)0x38b1, (q15_t)0x8d3e, + (q15_t)0x38ab, (q15_t)0x8d3b, (q15_t)0x38a6, (q15_t)0x8d38, (q15_t)0x38a0, (q15_t)0x8d36, (q15_t)0x389b, (q15_t)0x8d33, + (q15_t)0x3895, (q15_t)0x8d30, (q15_t)0x388f, (q15_t)0x8d2d, (q15_t)0x388a, (q15_t)0x8d2b, (q15_t)0x3884, (q15_t)0x8d28, + (q15_t)0x387e, (q15_t)0x8d25, (q15_t)0x3879, (q15_t)0x8d22, (q15_t)0x3873, (q15_t)0x8d1f, (q15_t)0x386d, (q15_t)0x8d1d, + (q15_t)0x3868, (q15_t)0x8d1a, (q15_t)0x3862, (q15_t)0x8d17, (q15_t)0x385d, (q15_t)0x8d14, (q15_t)0x3857, (q15_t)0x8d12, + (q15_t)0x3851, (q15_t)0x8d0f, (q15_t)0x384c, (q15_t)0x8d0c, (q15_t)0x3846, (q15_t)0x8d09, (q15_t)0x3840, (q15_t)0x8d07, + (q15_t)0x383b, (q15_t)0x8d04, (q15_t)0x3835, (q15_t)0x8d01, (q15_t)0x382f, (q15_t)0x8cfe, (q15_t)0x382a, (q15_t)0x8cfb, + (q15_t)0x3824, (q15_t)0x8cf9, (q15_t)0x381e, (q15_t)0x8cf6, (q15_t)0x3819, (q15_t)0x8cf3, (q15_t)0x3813, (q15_t)0x8cf0, + (q15_t)0x380d, (q15_t)0x8cee, (q15_t)0x3808, (q15_t)0x8ceb, (q15_t)0x3802, (q15_t)0x8ce8, (q15_t)0x37fd, (q15_t)0x8ce5, + (q15_t)0x37f7, (q15_t)0x8ce3, (q15_t)0x37f1, (q15_t)0x8ce0, (q15_t)0x37ec, (q15_t)0x8cdd, (q15_t)0x37e6, (q15_t)0x8cda, + (q15_t)0x37e0, (q15_t)0x8cd8, (q15_t)0x37db, (q15_t)0x8cd5, (q15_t)0x37d5, (q15_t)0x8cd2, (q15_t)0x37cf, (q15_t)0x8cd0, + (q15_t)0x37ca, (q15_t)0x8ccd, (q15_t)0x37c4, (q15_t)0x8cca, (q15_t)0x37be, (q15_t)0x8cc7, (q15_t)0x37b9, (q15_t)0x8cc5, + (q15_t)0x37b3, (q15_t)0x8cc2, (q15_t)0x37ad, (q15_t)0x8cbf, (q15_t)0x37a8, (q15_t)0x8cbc, (q15_t)0x37a2, (q15_t)0x8cba, + (q15_t)0x379c, (q15_t)0x8cb7, (q15_t)0x3797, (q15_t)0x8cb4, (q15_t)0x3791, (q15_t)0x8cb1, (q15_t)0x378b, (q15_t)0x8caf, + (q15_t)0x3786, (q15_t)0x8cac, (q15_t)0x3780, (q15_t)0x8ca9, (q15_t)0x377a, (q15_t)0x8ca7, (q15_t)0x3775, (q15_t)0x8ca4, + (q15_t)0x376f, (q15_t)0x8ca1, (q15_t)0x3769, (q15_t)0x8c9e, (q15_t)0x3764, (q15_t)0x8c9c, (q15_t)0x375e, (q15_t)0x8c99, + (q15_t)0x3758, (q15_t)0x8c96, (q15_t)0x3753, (q15_t)0x8c94, (q15_t)0x374d, (q15_t)0x8c91, (q15_t)0x3747, (q15_t)0x8c8e, + (q15_t)0x3742, (q15_t)0x8c8b, (q15_t)0x373c, (q15_t)0x8c89, (q15_t)0x3736, (q15_t)0x8c86, (q15_t)0x3731, (q15_t)0x8c83, + (q15_t)0x372b, (q15_t)0x8c81, (q15_t)0x3725, (q15_t)0x8c7e, (q15_t)0x3720, (q15_t)0x8c7b, (q15_t)0x371a, (q15_t)0x8c78, + (q15_t)0x3714, (q15_t)0x8c76, (q15_t)0x370f, (q15_t)0x8c73, (q15_t)0x3709, (q15_t)0x8c70, (q15_t)0x3703, (q15_t)0x8c6e, + (q15_t)0x36fe, (q15_t)0x8c6b, (q15_t)0x36f8, (q15_t)0x8c68, (q15_t)0x36f2, (q15_t)0x8c65, (q15_t)0x36ed, (q15_t)0x8c63, + (q15_t)0x36e7, (q15_t)0x8c60, (q15_t)0x36e1, (q15_t)0x8c5d, (q15_t)0x36dc, (q15_t)0x8c5b, (q15_t)0x36d6, (q15_t)0x8c58, + (q15_t)0x36d0, (q15_t)0x8c55, (q15_t)0x36cb, (q15_t)0x8c53, (q15_t)0x36c5, (q15_t)0x8c50, (q15_t)0x36bf, (q15_t)0x8c4d, + (q15_t)0x36ba, (q15_t)0x8c4b, (q15_t)0x36b4, (q15_t)0x8c48, (q15_t)0x36ae, (q15_t)0x8c45, (q15_t)0x36a9, (q15_t)0x8c43, + (q15_t)0x36a3, (q15_t)0x8c40, (q15_t)0x369d, (q15_t)0x8c3d, (q15_t)0x3698, (q15_t)0x8c3a, (q15_t)0x3692, (q15_t)0x8c38, + (q15_t)0x368c, (q15_t)0x8c35, (q15_t)0x3686, (q15_t)0x8c32, (q15_t)0x3681, (q15_t)0x8c30, (q15_t)0x367b, (q15_t)0x8c2d, + (q15_t)0x3675, (q15_t)0x8c2a, (q15_t)0x3670, (q15_t)0x8c28, (q15_t)0x366a, (q15_t)0x8c25, (q15_t)0x3664, (q15_t)0x8c22, + (q15_t)0x365f, (q15_t)0x8c20, (q15_t)0x3659, (q15_t)0x8c1d, (q15_t)0x3653, (q15_t)0x8c1a, (q15_t)0x364e, (q15_t)0x8c18, + (q15_t)0x3648, (q15_t)0x8c15, (q15_t)0x3642, (q15_t)0x8c12, (q15_t)0x363d, (q15_t)0x8c10, (q15_t)0x3637, (q15_t)0x8c0d, + (q15_t)0x3631, (q15_t)0x8c0a, (q15_t)0x362b, (q15_t)0x8c08, (q15_t)0x3626, (q15_t)0x8c05, (q15_t)0x3620, (q15_t)0x8c02, + (q15_t)0x361a, (q15_t)0x8c00, (q15_t)0x3615, (q15_t)0x8bfd, (q15_t)0x360f, (q15_t)0x8bfa, (q15_t)0x3609, (q15_t)0x8bf8, + (q15_t)0x3604, (q15_t)0x8bf5, (q15_t)0x35fe, (q15_t)0x8bf3, (q15_t)0x35f8, (q15_t)0x8bf0, (q15_t)0x35f3, (q15_t)0x8bed, + (q15_t)0x35ed, (q15_t)0x8beb, (q15_t)0x35e7, (q15_t)0x8be8, (q15_t)0x35e1, (q15_t)0x8be5, (q15_t)0x35dc, (q15_t)0x8be3, + (q15_t)0x35d6, (q15_t)0x8be0, (q15_t)0x35d0, (q15_t)0x8bdd, (q15_t)0x35cb, (q15_t)0x8bdb, (q15_t)0x35c5, (q15_t)0x8bd8, + (q15_t)0x35bf, (q15_t)0x8bd5, (q15_t)0x35ba, (q15_t)0x8bd3, (q15_t)0x35b4, (q15_t)0x8bd0, (q15_t)0x35ae, (q15_t)0x8bce, + (q15_t)0x35a8, (q15_t)0x8bcb, (q15_t)0x35a3, (q15_t)0x8bc8, (q15_t)0x359d, (q15_t)0x8bc6, (q15_t)0x3597, (q15_t)0x8bc3, + (q15_t)0x3592, (q15_t)0x8bc0, (q15_t)0x358c, (q15_t)0x8bbe, (q15_t)0x3586, (q15_t)0x8bbb, (q15_t)0x3580, (q15_t)0x8bb8, + (q15_t)0x357b, (q15_t)0x8bb6, (q15_t)0x3575, (q15_t)0x8bb3, (q15_t)0x356f, (q15_t)0x8bb1, (q15_t)0x356a, (q15_t)0x8bae, + (q15_t)0x3564, (q15_t)0x8bab, (q15_t)0x355e, (q15_t)0x8ba9, (q15_t)0x3558, (q15_t)0x8ba6, (q15_t)0x3553, (q15_t)0x8ba4, + (q15_t)0x354d, (q15_t)0x8ba1, (q15_t)0x3547, (q15_t)0x8b9e, (q15_t)0x3542, (q15_t)0x8b9c, (q15_t)0x353c, (q15_t)0x8b99, + (q15_t)0x3536, (q15_t)0x8b96, (q15_t)0x3530, (q15_t)0x8b94, (q15_t)0x352b, (q15_t)0x8b91, (q15_t)0x3525, (q15_t)0x8b8f, + (q15_t)0x351f, (q15_t)0x8b8c, (q15_t)0x351a, (q15_t)0x8b89, (q15_t)0x3514, (q15_t)0x8b87, (q15_t)0x350e, (q15_t)0x8b84, + (q15_t)0x3508, (q15_t)0x8b82, (q15_t)0x3503, (q15_t)0x8b7f, (q15_t)0x34fd, (q15_t)0x8b7c, (q15_t)0x34f7, (q15_t)0x8b7a, + (q15_t)0x34f2, (q15_t)0x8b77, (q15_t)0x34ec, (q15_t)0x8b75, (q15_t)0x34e6, (q15_t)0x8b72, (q15_t)0x34e0, (q15_t)0x8b6f, + (q15_t)0x34db, (q15_t)0x8b6d, (q15_t)0x34d5, (q15_t)0x8b6a, (q15_t)0x34cf, (q15_t)0x8b68, (q15_t)0x34ca, (q15_t)0x8b65, + (q15_t)0x34c4, (q15_t)0x8b62, (q15_t)0x34be, (q15_t)0x8b60, (q15_t)0x34b8, (q15_t)0x8b5d, (q15_t)0x34b3, (q15_t)0x8b5b, + (q15_t)0x34ad, (q15_t)0x8b58, (q15_t)0x34a7, (q15_t)0x8b55, (q15_t)0x34a1, (q15_t)0x8b53, (q15_t)0x349c, (q15_t)0x8b50, + (q15_t)0x3496, (q15_t)0x8b4e, (q15_t)0x3490, (q15_t)0x8b4b, (q15_t)0x348b, (q15_t)0x8b49, (q15_t)0x3485, (q15_t)0x8b46, + (q15_t)0x347f, (q15_t)0x8b43, (q15_t)0x3479, (q15_t)0x8b41, (q15_t)0x3474, (q15_t)0x8b3e, (q15_t)0x346e, (q15_t)0x8b3c, + (q15_t)0x3468, (q15_t)0x8b39, (q15_t)0x3462, (q15_t)0x8b37, (q15_t)0x345d, (q15_t)0x8b34, (q15_t)0x3457, (q15_t)0x8b31, + (q15_t)0x3451, (q15_t)0x8b2f, (q15_t)0x344b, (q15_t)0x8b2c, (q15_t)0x3446, (q15_t)0x8b2a, (q15_t)0x3440, (q15_t)0x8b27, + (q15_t)0x343a, (q15_t)0x8b25, (q15_t)0x3435, (q15_t)0x8b22, (q15_t)0x342f, (q15_t)0x8b1f, (q15_t)0x3429, (q15_t)0x8b1d, + (q15_t)0x3423, (q15_t)0x8b1a, (q15_t)0x341e, (q15_t)0x8b18, (q15_t)0x3418, (q15_t)0x8b15, (q15_t)0x3412, (q15_t)0x8b13, + (q15_t)0x340c, (q15_t)0x8b10, (q15_t)0x3407, (q15_t)0x8b0e, (q15_t)0x3401, (q15_t)0x8b0b, (q15_t)0x33fb, (q15_t)0x8b08, + (q15_t)0x33f5, (q15_t)0x8b06, (q15_t)0x33f0, (q15_t)0x8b03, (q15_t)0x33ea, (q15_t)0x8b01, (q15_t)0x33e4, (q15_t)0x8afe, + (q15_t)0x33de, (q15_t)0x8afc, (q15_t)0x33d9, (q15_t)0x8af9, (q15_t)0x33d3, (q15_t)0x8af7, (q15_t)0x33cd, (q15_t)0x8af4, + (q15_t)0x33c7, (q15_t)0x8af1, (q15_t)0x33c2, (q15_t)0x8aef, (q15_t)0x33bc, (q15_t)0x8aec, (q15_t)0x33b6, (q15_t)0x8aea, + (q15_t)0x33b0, (q15_t)0x8ae7, (q15_t)0x33ab, (q15_t)0x8ae5, (q15_t)0x33a5, (q15_t)0x8ae2, (q15_t)0x339f, (q15_t)0x8ae0, + (q15_t)0x3399, (q15_t)0x8add, (q15_t)0x3394, (q15_t)0x8adb, (q15_t)0x338e, (q15_t)0x8ad8, (q15_t)0x3388, (q15_t)0x8ad6, + (q15_t)0x3382, (q15_t)0x8ad3, (q15_t)0x337d, (q15_t)0x8ad1, (q15_t)0x3377, (q15_t)0x8ace, (q15_t)0x3371, (q15_t)0x8acb, + (q15_t)0x336b, (q15_t)0x8ac9, (q15_t)0x3366, (q15_t)0x8ac6, (q15_t)0x3360, (q15_t)0x8ac4, (q15_t)0x335a, (q15_t)0x8ac1, + (q15_t)0x3354, (q15_t)0x8abf, (q15_t)0x334f, (q15_t)0x8abc, (q15_t)0x3349, (q15_t)0x8aba, (q15_t)0x3343, (q15_t)0x8ab7, + (q15_t)0x333d, (q15_t)0x8ab5, (q15_t)0x3338, (q15_t)0x8ab2, (q15_t)0x3332, (q15_t)0x8ab0, (q15_t)0x332c, (q15_t)0x8aad, + (q15_t)0x3326, (q15_t)0x8aab, (q15_t)0x3321, (q15_t)0x8aa8, (q15_t)0x331b, (q15_t)0x8aa6, (q15_t)0x3315, (q15_t)0x8aa3, + (q15_t)0x330f, (q15_t)0x8aa1, (q15_t)0x330a, (q15_t)0x8a9e, (q15_t)0x3304, (q15_t)0x8a9c, (q15_t)0x32fe, (q15_t)0x8a99, + (q15_t)0x32f8, (q15_t)0x8a97, (q15_t)0x32f3, (q15_t)0x8a94, (q15_t)0x32ed, (q15_t)0x8a92, (q15_t)0x32e7, (q15_t)0x8a8f, + (q15_t)0x32e1, (q15_t)0x8a8d, (q15_t)0x32db, (q15_t)0x8a8a, (q15_t)0x32d6, (q15_t)0x8a88, (q15_t)0x32d0, (q15_t)0x8a85, + (q15_t)0x32ca, (q15_t)0x8a83, (q15_t)0x32c4, (q15_t)0x8a80, (q15_t)0x32bf, (q15_t)0x8a7e, (q15_t)0x32b9, (q15_t)0x8a7b, + (q15_t)0x32b3, (q15_t)0x8a79, (q15_t)0x32ad, (q15_t)0x8a76, (q15_t)0x32a8, (q15_t)0x8a74, (q15_t)0x32a2, (q15_t)0x8a71, + (q15_t)0x329c, (q15_t)0x8a6f, (q15_t)0x3296, (q15_t)0x8a6c, (q15_t)0x3290, (q15_t)0x8a6a, (q15_t)0x328b, (q15_t)0x8a67, + (q15_t)0x3285, (q15_t)0x8a65, (q15_t)0x327f, (q15_t)0x8a62, (q15_t)0x3279, (q15_t)0x8a60, (q15_t)0x3274, (q15_t)0x8a5d, + (q15_t)0x326e, (q15_t)0x8a5b, (q15_t)0x3268, (q15_t)0x8a59, (q15_t)0x3262, (q15_t)0x8a56, (q15_t)0x325d, (q15_t)0x8a54, + (q15_t)0x3257, (q15_t)0x8a51, (q15_t)0x3251, (q15_t)0x8a4f, (q15_t)0x324b, (q15_t)0x8a4c, (q15_t)0x3245, (q15_t)0x8a4a, + (q15_t)0x3240, (q15_t)0x8a47, (q15_t)0x323a, (q15_t)0x8a45, (q15_t)0x3234, (q15_t)0x8a42, (q15_t)0x322e, (q15_t)0x8a40, + (q15_t)0x3228, (q15_t)0x8a3d, (q15_t)0x3223, (q15_t)0x8a3b, (q15_t)0x321d, (q15_t)0x8a38, (q15_t)0x3217, (q15_t)0x8a36, + (q15_t)0x3211, (q15_t)0x8a34, (q15_t)0x320c, (q15_t)0x8a31, (q15_t)0x3206, (q15_t)0x8a2f, (q15_t)0x3200, (q15_t)0x8a2c, + (q15_t)0x31fa, (q15_t)0x8a2a, (q15_t)0x31f4, (q15_t)0x8a27, (q15_t)0x31ef, (q15_t)0x8a25, (q15_t)0x31e9, (q15_t)0x8a22, + (q15_t)0x31e3, (q15_t)0x8a20, (q15_t)0x31dd, (q15_t)0x8a1d, (q15_t)0x31d8, (q15_t)0x8a1b, (q15_t)0x31d2, (q15_t)0x8a19, + (q15_t)0x31cc, (q15_t)0x8a16, (q15_t)0x31c6, (q15_t)0x8a14, (q15_t)0x31c0, (q15_t)0x8a11, (q15_t)0x31bb, (q15_t)0x8a0f, + (q15_t)0x31b5, (q15_t)0x8a0c, (q15_t)0x31af, (q15_t)0x8a0a, (q15_t)0x31a9, (q15_t)0x8a07, (q15_t)0x31a3, (q15_t)0x8a05, + (q15_t)0x319e, (q15_t)0x8a03, (q15_t)0x3198, (q15_t)0x8a00, (q15_t)0x3192, (q15_t)0x89fe, (q15_t)0x318c, (q15_t)0x89fb, + (q15_t)0x3186, (q15_t)0x89f9, (q15_t)0x3181, (q15_t)0x89f6, (q15_t)0x317b, (q15_t)0x89f4, (q15_t)0x3175, (q15_t)0x89f2, + (q15_t)0x316f, (q15_t)0x89ef, (q15_t)0x3169, (q15_t)0x89ed, (q15_t)0x3164, (q15_t)0x89ea, (q15_t)0x315e, (q15_t)0x89e8, + (q15_t)0x3158, (q15_t)0x89e5, (q15_t)0x3152, (q15_t)0x89e3, (q15_t)0x314c, (q15_t)0x89e1, (q15_t)0x3147, (q15_t)0x89de, + (q15_t)0x3141, (q15_t)0x89dc, (q15_t)0x313b, (q15_t)0x89d9, (q15_t)0x3135, (q15_t)0x89d7, (q15_t)0x312f, (q15_t)0x89d5, + (q15_t)0x312a, (q15_t)0x89d2, (q15_t)0x3124, (q15_t)0x89d0, (q15_t)0x311e, (q15_t)0x89cd, (q15_t)0x3118, (q15_t)0x89cb, + (q15_t)0x3112, (q15_t)0x89c8, (q15_t)0x310d, (q15_t)0x89c6, (q15_t)0x3107, (q15_t)0x89c4, (q15_t)0x3101, (q15_t)0x89c1, + (q15_t)0x30fb, (q15_t)0x89bf, (q15_t)0x30f5, (q15_t)0x89bc, (q15_t)0x30f0, (q15_t)0x89ba, (q15_t)0x30ea, (q15_t)0x89b8, + (q15_t)0x30e4, (q15_t)0x89b5, (q15_t)0x30de, (q15_t)0x89b3, (q15_t)0x30d8, (q15_t)0x89b0, (q15_t)0x30d3, (q15_t)0x89ae, + (q15_t)0x30cd, (q15_t)0x89ac, (q15_t)0x30c7, (q15_t)0x89a9, (q15_t)0x30c1, (q15_t)0x89a7, (q15_t)0x30bb, (q15_t)0x89a4, + (q15_t)0x30b6, (q15_t)0x89a2, (q15_t)0x30b0, (q15_t)0x89a0, (q15_t)0x30aa, (q15_t)0x899d, (q15_t)0x30a4, (q15_t)0x899b, + (q15_t)0x309e, (q15_t)0x8998, (q15_t)0x3099, (q15_t)0x8996, (q15_t)0x3093, (q15_t)0x8994, (q15_t)0x308d, (q15_t)0x8991, + (q15_t)0x3087, (q15_t)0x898f, (q15_t)0x3081, (q15_t)0x898d, (q15_t)0x307b, (q15_t)0x898a, (q15_t)0x3076, (q15_t)0x8988, + (q15_t)0x3070, (q15_t)0x8985, (q15_t)0x306a, (q15_t)0x8983, (q15_t)0x3064, (q15_t)0x8981, (q15_t)0x305e, (q15_t)0x897e, + (q15_t)0x3059, (q15_t)0x897c, (q15_t)0x3053, (q15_t)0x897a, (q15_t)0x304d, (q15_t)0x8977, (q15_t)0x3047, (q15_t)0x8975, + (q15_t)0x3041, (q15_t)0x8972, (q15_t)0x303b, (q15_t)0x8970, (q15_t)0x3036, (q15_t)0x896e, (q15_t)0x3030, (q15_t)0x896b, + (q15_t)0x302a, (q15_t)0x8969, (q15_t)0x3024, (q15_t)0x8967, (q15_t)0x301e, (q15_t)0x8964, (q15_t)0x3019, (q15_t)0x8962, + (q15_t)0x3013, (q15_t)0x8960, (q15_t)0x300d, (q15_t)0x895d, (q15_t)0x3007, (q15_t)0x895b, (q15_t)0x3001, (q15_t)0x8958, + (q15_t)0x2ffb, (q15_t)0x8956, (q15_t)0x2ff6, (q15_t)0x8954, (q15_t)0x2ff0, (q15_t)0x8951, (q15_t)0x2fea, (q15_t)0x894f, + (q15_t)0x2fe4, (q15_t)0x894d, (q15_t)0x2fde, (q15_t)0x894a, (q15_t)0x2fd8, (q15_t)0x8948, (q15_t)0x2fd3, (q15_t)0x8946, + (q15_t)0x2fcd, (q15_t)0x8943, (q15_t)0x2fc7, (q15_t)0x8941, (q15_t)0x2fc1, (q15_t)0x893f, (q15_t)0x2fbb, (q15_t)0x893c, + (q15_t)0x2fb5, (q15_t)0x893a, (q15_t)0x2fb0, (q15_t)0x8938, (q15_t)0x2faa, (q15_t)0x8935, (q15_t)0x2fa4, (q15_t)0x8933, + (q15_t)0x2f9e, (q15_t)0x8931, (q15_t)0x2f98, (q15_t)0x892e, (q15_t)0x2f92, (q15_t)0x892c, (q15_t)0x2f8d, (q15_t)0x892a, + (q15_t)0x2f87, (q15_t)0x8927, (q15_t)0x2f81, (q15_t)0x8925, (q15_t)0x2f7b, (q15_t)0x8923, (q15_t)0x2f75, (q15_t)0x8920, + (q15_t)0x2f6f, (q15_t)0x891e, (q15_t)0x2f6a, (q15_t)0x891c, (q15_t)0x2f64, (q15_t)0x8919, (q15_t)0x2f5e, (q15_t)0x8917, + (q15_t)0x2f58, (q15_t)0x8915, (q15_t)0x2f52, (q15_t)0x8912, (q15_t)0x2f4c, (q15_t)0x8910, (q15_t)0x2f47, (q15_t)0x890e, + (q15_t)0x2f41, (q15_t)0x890b, (q15_t)0x2f3b, (q15_t)0x8909, (q15_t)0x2f35, (q15_t)0x8907, (q15_t)0x2f2f, (q15_t)0x8904, + (q15_t)0x2f29, (q15_t)0x8902, (q15_t)0x2f24, (q15_t)0x8900, (q15_t)0x2f1e, (q15_t)0x88fd, (q15_t)0x2f18, (q15_t)0x88fb, + (q15_t)0x2f12, (q15_t)0x88f9, (q15_t)0x2f0c, (q15_t)0x88f6, (q15_t)0x2f06, (q15_t)0x88f4, (q15_t)0x2f01, (q15_t)0x88f2, + (q15_t)0x2efb, (q15_t)0x88f0, (q15_t)0x2ef5, (q15_t)0x88ed, (q15_t)0x2eef, (q15_t)0x88eb, (q15_t)0x2ee9, (q15_t)0x88e9, + (q15_t)0x2ee3, (q15_t)0x88e6, (q15_t)0x2edd, (q15_t)0x88e4, (q15_t)0x2ed8, (q15_t)0x88e2, (q15_t)0x2ed2, (q15_t)0x88df, + (q15_t)0x2ecc, (q15_t)0x88dd, (q15_t)0x2ec6, (q15_t)0x88db, (q15_t)0x2ec0, (q15_t)0x88d9, (q15_t)0x2eba, (q15_t)0x88d6, + (q15_t)0x2eb5, (q15_t)0x88d4, (q15_t)0x2eaf, (q15_t)0x88d2, (q15_t)0x2ea9, (q15_t)0x88cf, (q15_t)0x2ea3, (q15_t)0x88cd, + (q15_t)0x2e9d, (q15_t)0x88cb, (q15_t)0x2e97, (q15_t)0x88c8, (q15_t)0x2e91, (q15_t)0x88c6, (q15_t)0x2e8c, (q15_t)0x88c4, + (q15_t)0x2e86, (q15_t)0x88c2, (q15_t)0x2e80, (q15_t)0x88bf, (q15_t)0x2e7a, (q15_t)0x88bd, (q15_t)0x2e74, (q15_t)0x88bb, + (q15_t)0x2e6e, (q15_t)0x88b9, (q15_t)0x2e68, (q15_t)0x88b6, (q15_t)0x2e63, (q15_t)0x88b4, (q15_t)0x2e5d, (q15_t)0x88b2, + (q15_t)0x2e57, (q15_t)0x88af, (q15_t)0x2e51, (q15_t)0x88ad, (q15_t)0x2e4b, (q15_t)0x88ab, (q15_t)0x2e45, (q15_t)0x88a9, + (q15_t)0x2e3f, (q15_t)0x88a6, (q15_t)0x2e3a, (q15_t)0x88a4, (q15_t)0x2e34, (q15_t)0x88a2, (q15_t)0x2e2e, (q15_t)0x88a0, + (q15_t)0x2e28, (q15_t)0x889d, (q15_t)0x2e22, (q15_t)0x889b, (q15_t)0x2e1c, (q15_t)0x8899, (q15_t)0x2e16, (q15_t)0x8896, + (q15_t)0x2e11, (q15_t)0x8894, (q15_t)0x2e0b, (q15_t)0x8892, (q15_t)0x2e05, (q15_t)0x8890, (q15_t)0x2dff, (q15_t)0x888d, + (q15_t)0x2df9, (q15_t)0x888b, (q15_t)0x2df3, (q15_t)0x8889, (q15_t)0x2ded, (q15_t)0x8887, (q15_t)0x2de7, (q15_t)0x8884, + (q15_t)0x2de2, (q15_t)0x8882, (q15_t)0x2ddc, (q15_t)0x8880, (q15_t)0x2dd6, (q15_t)0x887e, (q15_t)0x2dd0, (q15_t)0x887b, + (q15_t)0x2dca, (q15_t)0x8879, (q15_t)0x2dc4, (q15_t)0x8877, (q15_t)0x2dbe, (q15_t)0x8875, (q15_t)0x2db9, (q15_t)0x8872, + (q15_t)0x2db3, (q15_t)0x8870, (q15_t)0x2dad, (q15_t)0x886e, (q15_t)0x2da7, (q15_t)0x886c, (q15_t)0x2da1, (q15_t)0x8869, + (q15_t)0x2d9b, (q15_t)0x8867, (q15_t)0x2d95, (q15_t)0x8865, (q15_t)0x2d8f, (q15_t)0x8863, (q15_t)0x2d8a, (q15_t)0x8860, + (q15_t)0x2d84, (q15_t)0x885e, (q15_t)0x2d7e, (q15_t)0x885c, (q15_t)0x2d78, (q15_t)0x885a, (q15_t)0x2d72, (q15_t)0x8858, + (q15_t)0x2d6c, (q15_t)0x8855, (q15_t)0x2d66, (q15_t)0x8853, (q15_t)0x2d60, (q15_t)0x8851, (q15_t)0x2d5b, (q15_t)0x884f, + (q15_t)0x2d55, (q15_t)0x884c, (q15_t)0x2d4f, (q15_t)0x884a, (q15_t)0x2d49, (q15_t)0x8848, (q15_t)0x2d43, (q15_t)0x8846, + (q15_t)0x2d3d, (q15_t)0x8844, (q15_t)0x2d37, (q15_t)0x8841, (q15_t)0x2d31, (q15_t)0x883f, (q15_t)0x2d2c, (q15_t)0x883d, + (q15_t)0x2d26, (q15_t)0x883b, (q15_t)0x2d20, (q15_t)0x8838, (q15_t)0x2d1a, (q15_t)0x8836, (q15_t)0x2d14, (q15_t)0x8834, + (q15_t)0x2d0e, (q15_t)0x8832, (q15_t)0x2d08, (q15_t)0x8830, (q15_t)0x2d02, (q15_t)0x882d, (q15_t)0x2cfd, (q15_t)0x882b, + (q15_t)0x2cf7, (q15_t)0x8829, (q15_t)0x2cf1, (q15_t)0x8827, (q15_t)0x2ceb, (q15_t)0x8825, (q15_t)0x2ce5, (q15_t)0x8822, + (q15_t)0x2cdf, (q15_t)0x8820, (q15_t)0x2cd9, (q15_t)0x881e, (q15_t)0x2cd3, (q15_t)0x881c, (q15_t)0x2ccd, (q15_t)0x881a, + (q15_t)0x2cc8, (q15_t)0x8817, (q15_t)0x2cc2, (q15_t)0x8815, (q15_t)0x2cbc, (q15_t)0x8813, (q15_t)0x2cb6, (q15_t)0x8811, + (q15_t)0x2cb0, (q15_t)0x880f, (q15_t)0x2caa, (q15_t)0x880c, (q15_t)0x2ca4, (q15_t)0x880a, (q15_t)0x2c9e, (q15_t)0x8808, + (q15_t)0x2c98, (q15_t)0x8806, (q15_t)0x2c93, (q15_t)0x8804, (q15_t)0x2c8d, (q15_t)0x8801, (q15_t)0x2c87, (q15_t)0x87ff, + (q15_t)0x2c81, (q15_t)0x87fd, (q15_t)0x2c7b, (q15_t)0x87fb, (q15_t)0x2c75, (q15_t)0x87f9, (q15_t)0x2c6f, (q15_t)0x87f6, + (q15_t)0x2c69, (q15_t)0x87f4, (q15_t)0x2c63, (q15_t)0x87f2, (q15_t)0x2c5e, (q15_t)0x87f0, (q15_t)0x2c58, (q15_t)0x87ee, + (q15_t)0x2c52, (q15_t)0x87ec, (q15_t)0x2c4c, (q15_t)0x87e9, (q15_t)0x2c46, (q15_t)0x87e7, (q15_t)0x2c40, (q15_t)0x87e5, + (q15_t)0x2c3a, (q15_t)0x87e3, (q15_t)0x2c34, (q15_t)0x87e1, (q15_t)0x2c2e, (q15_t)0x87df, (q15_t)0x2c29, (q15_t)0x87dc, + (q15_t)0x2c23, (q15_t)0x87da, (q15_t)0x2c1d, (q15_t)0x87d8, (q15_t)0x2c17, (q15_t)0x87d6, (q15_t)0x2c11, (q15_t)0x87d4, + (q15_t)0x2c0b, (q15_t)0x87d2, (q15_t)0x2c05, (q15_t)0x87cf, (q15_t)0x2bff, (q15_t)0x87cd, (q15_t)0x2bf9, (q15_t)0x87cb, + (q15_t)0x2bf3, (q15_t)0x87c9, (q15_t)0x2bee, (q15_t)0x87c7, (q15_t)0x2be8, (q15_t)0x87c5, (q15_t)0x2be2, (q15_t)0x87c2, + (q15_t)0x2bdc, (q15_t)0x87c0, (q15_t)0x2bd6, (q15_t)0x87be, (q15_t)0x2bd0, (q15_t)0x87bc, (q15_t)0x2bca, (q15_t)0x87ba, + (q15_t)0x2bc4, (q15_t)0x87b8, (q15_t)0x2bbe, (q15_t)0x87b6, (q15_t)0x2bb8, (q15_t)0x87b3, (q15_t)0x2bb2, (q15_t)0x87b1, + (q15_t)0x2bad, (q15_t)0x87af, (q15_t)0x2ba7, (q15_t)0x87ad, (q15_t)0x2ba1, (q15_t)0x87ab, (q15_t)0x2b9b, (q15_t)0x87a9, + (q15_t)0x2b95, (q15_t)0x87a7, (q15_t)0x2b8f, (q15_t)0x87a4, (q15_t)0x2b89, (q15_t)0x87a2, (q15_t)0x2b83, (q15_t)0x87a0, + (q15_t)0x2b7d, (q15_t)0x879e, (q15_t)0x2b77, (q15_t)0x879c, (q15_t)0x2b71, (q15_t)0x879a, (q15_t)0x2b6c, (q15_t)0x8798, + (q15_t)0x2b66, (q15_t)0x8795, (q15_t)0x2b60, (q15_t)0x8793, (q15_t)0x2b5a, (q15_t)0x8791, (q15_t)0x2b54, (q15_t)0x878f, + (q15_t)0x2b4e, (q15_t)0x878d, (q15_t)0x2b48, (q15_t)0x878b, (q15_t)0x2b42, (q15_t)0x8789, (q15_t)0x2b3c, (q15_t)0x8787, + (q15_t)0x2b36, (q15_t)0x8784, (q15_t)0x2b30, (q15_t)0x8782, (q15_t)0x2b2b, (q15_t)0x8780, (q15_t)0x2b25, (q15_t)0x877e, + (q15_t)0x2b1f, (q15_t)0x877c, (q15_t)0x2b19, (q15_t)0x877a, (q15_t)0x2b13, (q15_t)0x8778, (q15_t)0x2b0d, (q15_t)0x8776, + (q15_t)0x2b07, (q15_t)0x8774, (q15_t)0x2b01, (q15_t)0x8771, (q15_t)0x2afb, (q15_t)0x876f, (q15_t)0x2af5, (q15_t)0x876d, + (q15_t)0x2aef, (q15_t)0x876b, (q15_t)0x2ae9, (q15_t)0x8769, (q15_t)0x2ae4, (q15_t)0x8767, (q15_t)0x2ade, (q15_t)0x8765, + (q15_t)0x2ad8, (q15_t)0x8763, (q15_t)0x2ad2, (q15_t)0x8761, (q15_t)0x2acc, (q15_t)0x875e, (q15_t)0x2ac6, (q15_t)0x875c, + (q15_t)0x2ac0, (q15_t)0x875a, (q15_t)0x2aba, (q15_t)0x8758, (q15_t)0x2ab4, (q15_t)0x8756, (q15_t)0x2aae, (q15_t)0x8754, + (q15_t)0x2aa8, (q15_t)0x8752, (q15_t)0x2aa2, (q15_t)0x8750, (q15_t)0x2a9c, (q15_t)0x874e, (q15_t)0x2a97, (q15_t)0x874c, + (q15_t)0x2a91, (q15_t)0x874a, (q15_t)0x2a8b, (q15_t)0x8747, (q15_t)0x2a85, (q15_t)0x8745, (q15_t)0x2a7f, (q15_t)0x8743, + (q15_t)0x2a79, (q15_t)0x8741, (q15_t)0x2a73, (q15_t)0x873f, (q15_t)0x2a6d, (q15_t)0x873d, (q15_t)0x2a67, (q15_t)0x873b, + (q15_t)0x2a61, (q15_t)0x8739, (q15_t)0x2a5b, (q15_t)0x8737, (q15_t)0x2a55, (q15_t)0x8735, (q15_t)0x2a4f, (q15_t)0x8733, + (q15_t)0x2a49, (q15_t)0x8731, (q15_t)0x2a44, (q15_t)0x872e, (q15_t)0x2a3e, (q15_t)0x872c, (q15_t)0x2a38, (q15_t)0x872a, + (q15_t)0x2a32, (q15_t)0x8728, (q15_t)0x2a2c, (q15_t)0x8726, (q15_t)0x2a26, (q15_t)0x8724, (q15_t)0x2a20, (q15_t)0x8722, + (q15_t)0x2a1a, (q15_t)0x8720, (q15_t)0x2a14, (q15_t)0x871e, (q15_t)0x2a0e, (q15_t)0x871c, (q15_t)0x2a08, (q15_t)0x871a, + (q15_t)0x2a02, (q15_t)0x8718, (q15_t)0x29fc, (q15_t)0x8716, (q15_t)0x29f6, (q15_t)0x8714, (q15_t)0x29f0, (q15_t)0x8712, + (q15_t)0x29eb, (q15_t)0x870f, (q15_t)0x29e5, (q15_t)0x870d, (q15_t)0x29df, (q15_t)0x870b, (q15_t)0x29d9, (q15_t)0x8709, + (q15_t)0x29d3, (q15_t)0x8707, (q15_t)0x29cd, (q15_t)0x8705, (q15_t)0x29c7, (q15_t)0x8703, (q15_t)0x29c1, (q15_t)0x8701, + (q15_t)0x29bb, (q15_t)0x86ff, (q15_t)0x29b5, (q15_t)0x86fd, (q15_t)0x29af, (q15_t)0x86fb, (q15_t)0x29a9, (q15_t)0x86f9, + (q15_t)0x29a3, (q15_t)0x86f7, (q15_t)0x299d, (q15_t)0x86f5, (q15_t)0x2997, (q15_t)0x86f3, (q15_t)0x2991, (q15_t)0x86f1, + (q15_t)0x298b, (q15_t)0x86ef, (q15_t)0x2986, (q15_t)0x86ed, (q15_t)0x2980, (q15_t)0x86eb, (q15_t)0x297a, (q15_t)0x86e9, + (q15_t)0x2974, (q15_t)0x86e7, (q15_t)0x296e, (q15_t)0x86e4, (q15_t)0x2968, (q15_t)0x86e2, (q15_t)0x2962, (q15_t)0x86e0, + (q15_t)0x295c, (q15_t)0x86de, (q15_t)0x2956, (q15_t)0x86dc, (q15_t)0x2950, (q15_t)0x86da, (q15_t)0x294a, (q15_t)0x86d8, + (q15_t)0x2944, (q15_t)0x86d6, (q15_t)0x293e, (q15_t)0x86d4, (q15_t)0x2938, (q15_t)0x86d2, (q15_t)0x2932, (q15_t)0x86d0, + (q15_t)0x292c, (q15_t)0x86ce, (q15_t)0x2926, (q15_t)0x86cc, (q15_t)0x2920, (q15_t)0x86ca, (q15_t)0x291b, (q15_t)0x86c8, + (q15_t)0x2915, (q15_t)0x86c6, (q15_t)0x290f, (q15_t)0x86c4, (q15_t)0x2909, (q15_t)0x86c2, (q15_t)0x2903, (q15_t)0x86c0, + (q15_t)0x28fd, (q15_t)0x86be, (q15_t)0x28f7, (q15_t)0x86bc, (q15_t)0x28f1, (q15_t)0x86ba, (q15_t)0x28eb, (q15_t)0x86b8, + (q15_t)0x28e5, (q15_t)0x86b6, (q15_t)0x28df, (q15_t)0x86b4, (q15_t)0x28d9, (q15_t)0x86b2, (q15_t)0x28d3, (q15_t)0x86b0, + (q15_t)0x28cd, (q15_t)0x86ae, (q15_t)0x28c7, (q15_t)0x86ac, (q15_t)0x28c1, (q15_t)0x86aa, (q15_t)0x28bb, (q15_t)0x86a8, + (q15_t)0x28b5, (q15_t)0x86a6, (q15_t)0x28af, (q15_t)0x86a4, (q15_t)0x28a9, (q15_t)0x86a2, (q15_t)0x28a3, (q15_t)0x86a0, + (q15_t)0x289d, (q15_t)0x869e, (q15_t)0x2898, (q15_t)0x869c, (q15_t)0x2892, (q15_t)0x869a, (q15_t)0x288c, (q15_t)0x8698, + (q15_t)0x2886, (q15_t)0x8696, (q15_t)0x2880, (q15_t)0x8694, (q15_t)0x287a, (q15_t)0x8692, (q15_t)0x2874, (q15_t)0x8690, + (q15_t)0x286e, (q15_t)0x868e, (q15_t)0x2868, (q15_t)0x868c, (q15_t)0x2862, (q15_t)0x868a, (q15_t)0x285c, (q15_t)0x8688, + (q15_t)0x2856, (q15_t)0x8686, (q15_t)0x2850, (q15_t)0x8684, (q15_t)0x284a, (q15_t)0x8682, (q15_t)0x2844, (q15_t)0x8680, + (q15_t)0x283e, (q15_t)0x867e, (q15_t)0x2838, (q15_t)0x867c, (q15_t)0x2832, (q15_t)0x867a, (q15_t)0x282c, (q15_t)0x8678, + (q15_t)0x2826, (q15_t)0x8676, (q15_t)0x2820, (q15_t)0x8674, (q15_t)0x281a, (q15_t)0x8672, (q15_t)0x2814, (q15_t)0x8670, + (q15_t)0x280e, (q15_t)0x866e, (q15_t)0x2808, (q15_t)0x866d, (q15_t)0x2802, (q15_t)0x866b, (q15_t)0x27fc, (q15_t)0x8669, + (q15_t)0x27f6, (q15_t)0x8667, (q15_t)0x27f1, (q15_t)0x8665, (q15_t)0x27eb, (q15_t)0x8663, (q15_t)0x27e5, (q15_t)0x8661, + (q15_t)0x27df, (q15_t)0x865f, (q15_t)0x27d9, (q15_t)0x865d, (q15_t)0x27d3, (q15_t)0x865b, (q15_t)0x27cd, (q15_t)0x8659, + (q15_t)0x27c7, (q15_t)0x8657, (q15_t)0x27c1, (q15_t)0x8655, (q15_t)0x27bb, (q15_t)0x8653, (q15_t)0x27b5, (q15_t)0x8651, + (q15_t)0x27af, (q15_t)0x864f, (q15_t)0x27a9, (q15_t)0x864d, (q15_t)0x27a3, (q15_t)0x864b, (q15_t)0x279d, (q15_t)0x8649, + (q15_t)0x2797, (q15_t)0x8647, (q15_t)0x2791, (q15_t)0x8645, (q15_t)0x278b, (q15_t)0x8644, (q15_t)0x2785, (q15_t)0x8642, + (q15_t)0x277f, (q15_t)0x8640, (q15_t)0x2779, (q15_t)0x863e, (q15_t)0x2773, (q15_t)0x863c, (q15_t)0x276d, (q15_t)0x863a, + (q15_t)0x2767, (q15_t)0x8638, (q15_t)0x2761, (q15_t)0x8636, (q15_t)0x275b, (q15_t)0x8634, (q15_t)0x2755, (q15_t)0x8632, + (q15_t)0x274f, (q15_t)0x8630, (q15_t)0x2749, (q15_t)0x862e, (q15_t)0x2743, (q15_t)0x862c, (q15_t)0x273d, (q15_t)0x862a, + (q15_t)0x2737, (q15_t)0x8628, (q15_t)0x2731, (q15_t)0x8627, (q15_t)0x272b, (q15_t)0x8625, (q15_t)0x2725, (q15_t)0x8623, + (q15_t)0x271f, (q15_t)0x8621, (q15_t)0x2719, (q15_t)0x861f, (q15_t)0x2713, (q15_t)0x861d, (q15_t)0x270d, (q15_t)0x861b, + (q15_t)0x2707, (q15_t)0x8619, (q15_t)0x2701, (q15_t)0x8617, (q15_t)0x26fb, (q15_t)0x8615, (q15_t)0x26f5, (q15_t)0x8613, + (q15_t)0x26ef, (q15_t)0x8611, (q15_t)0x26e9, (q15_t)0x8610, (q15_t)0x26e4, (q15_t)0x860e, (q15_t)0x26de, (q15_t)0x860c, + (q15_t)0x26d8, (q15_t)0x860a, (q15_t)0x26d2, (q15_t)0x8608, (q15_t)0x26cc, (q15_t)0x8606, (q15_t)0x26c6, (q15_t)0x8604, + (q15_t)0x26c0, (q15_t)0x8602, (q15_t)0x26ba, (q15_t)0x8600, (q15_t)0x26b4, (q15_t)0x85fe, (q15_t)0x26ae, (q15_t)0x85fc, + (q15_t)0x26a8, (q15_t)0x85fb, (q15_t)0x26a2, (q15_t)0x85f9, (q15_t)0x269c, (q15_t)0x85f7, (q15_t)0x2696, (q15_t)0x85f5, + (q15_t)0x2690, (q15_t)0x85f3, (q15_t)0x268a, (q15_t)0x85f1, (q15_t)0x2684, (q15_t)0x85ef, (q15_t)0x267e, (q15_t)0x85ed, + (q15_t)0x2678, (q15_t)0x85eb, (q15_t)0x2672, (q15_t)0x85ea, (q15_t)0x266c, (q15_t)0x85e8, (q15_t)0x2666, (q15_t)0x85e6, + (q15_t)0x2660, (q15_t)0x85e4, (q15_t)0x265a, (q15_t)0x85e2, (q15_t)0x2654, (q15_t)0x85e0, (q15_t)0x264e, (q15_t)0x85de, + (q15_t)0x2648, (q15_t)0x85dc, (q15_t)0x2642, (q15_t)0x85da, (q15_t)0x263c, (q15_t)0x85d9, (q15_t)0x2636, (q15_t)0x85d7, + (q15_t)0x2630, (q15_t)0x85d5, (q15_t)0x262a, (q15_t)0x85d3, (q15_t)0x2624, (q15_t)0x85d1, (q15_t)0x261e, (q15_t)0x85cf, + (q15_t)0x2618, (q15_t)0x85cd, (q15_t)0x2612, (q15_t)0x85cb, (q15_t)0x260c, (q15_t)0x85ca, (q15_t)0x2606, (q15_t)0x85c8, + (q15_t)0x2600, (q15_t)0x85c6, (q15_t)0x25fa, (q15_t)0x85c4, (q15_t)0x25f4, (q15_t)0x85c2, (q15_t)0x25ee, (q15_t)0x85c0, + (q15_t)0x25e8, (q15_t)0x85be, (q15_t)0x25e2, (q15_t)0x85bd, (q15_t)0x25dc, (q15_t)0x85bb, (q15_t)0x25d6, (q15_t)0x85b9, + (q15_t)0x25d0, (q15_t)0x85b7, (q15_t)0x25ca, (q15_t)0x85b5, (q15_t)0x25c4, (q15_t)0x85b3, (q15_t)0x25be, (q15_t)0x85b1, + (q15_t)0x25b8, (q15_t)0x85b0, (q15_t)0x25b2, (q15_t)0x85ae, (q15_t)0x25ac, (q15_t)0x85ac, (q15_t)0x25a6, (q15_t)0x85aa, + (q15_t)0x25a0, (q15_t)0x85a8, (q15_t)0x259a, (q15_t)0x85a6, (q15_t)0x2594, (q15_t)0x85a4, (q15_t)0x258e, (q15_t)0x85a3, + (q15_t)0x2588, (q15_t)0x85a1, (q15_t)0x2582, (q15_t)0x859f, (q15_t)0x257c, (q15_t)0x859d, (q15_t)0x2576, (q15_t)0x859b, + (q15_t)0x2570, (q15_t)0x8599, (q15_t)0x256a, (q15_t)0x8598, (q15_t)0x2564, (q15_t)0x8596, (q15_t)0x255e, (q15_t)0x8594, + (q15_t)0x2558, (q15_t)0x8592, (q15_t)0x2552, (q15_t)0x8590, (q15_t)0x254c, (q15_t)0x858e, (q15_t)0x2546, (q15_t)0x858d, + (q15_t)0x2540, (q15_t)0x858b, (q15_t)0x253a, (q15_t)0x8589, (q15_t)0x2534, (q15_t)0x8587, (q15_t)0x252e, (q15_t)0x8585, + (q15_t)0x2528, (q15_t)0x8583, (q15_t)0x2522, (q15_t)0x8582, (q15_t)0x251c, (q15_t)0x8580, (q15_t)0x2516, (q15_t)0x857e, + (q15_t)0x250f, (q15_t)0x857c, (q15_t)0x2509, (q15_t)0x857a, (q15_t)0x2503, (q15_t)0x8579, (q15_t)0x24fd, (q15_t)0x8577, + (q15_t)0x24f7, (q15_t)0x8575, (q15_t)0x24f1, (q15_t)0x8573, (q15_t)0x24eb, (q15_t)0x8571, (q15_t)0x24e5, (q15_t)0x856f, + (q15_t)0x24df, (q15_t)0x856e, (q15_t)0x24d9, (q15_t)0x856c, (q15_t)0x24d3, (q15_t)0x856a, (q15_t)0x24cd, (q15_t)0x8568, + (q15_t)0x24c7, (q15_t)0x8566, (q15_t)0x24c1, (q15_t)0x8565, (q15_t)0x24bb, (q15_t)0x8563, (q15_t)0x24b5, (q15_t)0x8561, + (q15_t)0x24af, (q15_t)0x855f, (q15_t)0x24a9, (q15_t)0x855d, (q15_t)0x24a3, (q15_t)0x855c, (q15_t)0x249d, (q15_t)0x855a, + (q15_t)0x2497, (q15_t)0x8558, (q15_t)0x2491, (q15_t)0x8556, (q15_t)0x248b, (q15_t)0x8554, (q15_t)0x2485, (q15_t)0x8553, + (q15_t)0x247f, (q15_t)0x8551, (q15_t)0x2479, (q15_t)0x854f, (q15_t)0x2473, (q15_t)0x854d, (q15_t)0x246d, (q15_t)0x854b, + (q15_t)0x2467, (q15_t)0x854a, (q15_t)0x2461, (q15_t)0x8548, (q15_t)0x245b, (q15_t)0x8546, (q15_t)0x2455, (q15_t)0x8544, + (q15_t)0x244f, (q15_t)0x8543, (q15_t)0x2449, (q15_t)0x8541, (q15_t)0x2443, (q15_t)0x853f, (q15_t)0x243d, (q15_t)0x853d, + (q15_t)0x2437, (q15_t)0x853b, (q15_t)0x2431, (q15_t)0x853a, (q15_t)0x242b, (q15_t)0x8538, (q15_t)0x2425, (q15_t)0x8536, + (q15_t)0x241f, (q15_t)0x8534, (q15_t)0x2419, (q15_t)0x8533, (q15_t)0x2413, (q15_t)0x8531, (q15_t)0x240d, (q15_t)0x852f, + (q15_t)0x2407, (q15_t)0x852d, (q15_t)0x2401, (q15_t)0x852b, (q15_t)0x23fa, (q15_t)0x852a, (q15_t)0x23f4, (q15_t)0x8528, + (q15_t)0x23ee, (q15_t)0x8526, (q15_t)0x23e8, (q15_t)0x8524, (q15_t)0x23e2, (q15_t)0x8523, (q15_t)0x23dc, (q15_t)0x8521, + (q15_t)0x23d6, (q15_t)0x851f, (q15_t)0x23d0, (q15_t)0x851d, (q15_t)0x23ca, (q15_t)0x851c, (q15_t)0x23c4, (q15_t)0x851a, + (q15_t)0x23be, (q15_t)0x8518, (q15_t)0x23b8, (q15_t)0x8516, (q15_t)0x23b2, (q15_t)0x8515, (q15_t)0x23ac, (q15_t)0x8513, + (q15_t)0x23a6, (q15_t)0x8511, (q15_t)0x23a0, (q15_t)0x850f, (q15_t)0x239a, (q15_t)0x850e, (q15_t)0x2394, (q15_t)0x850c, + (q15_t)0x238e, (q15_t)0x850a, (q15_t)0x2388, (q15_t)0x8508, (q15_t)0x2382, (q15_t)0x8507, (q15_t)0x237c, (q15_t)0x8505, + (q15_t)0x2376, (q15_t)0x8503, (q15_t)0x2370, (q15_t)0x8501, (q15_t)0x236a, (q15_t)0x8500, (q15_t)0x2364, (q15_t)0x84fe, + (q15_t)0x235e, (q15_t)0x84fc, (q15_t)0x2358, (q15_t)0x84fa, (q15_t)0x2352, (q15_t)0x84f9, (q15_t)0x234b, (q15_t)0x84f7, + (q15_t)0x2345, (q15_t)0x84f5, (q15_t)0x233f, (q15_t)0x84f4, (q15_t)0x2339, (q15_t)0x84f2, (q15_t)0x2333, (q15_t)0x84f0, + (q15_t)0x232d, (q15_t)0x84ee, (q15_t)0x2327, (q15_t)0x84ed, (q15_t)0x2321, (q15_t)0x84eb, (q15_t)0x231b, (q15_t)0x84e9, + (q15_t)0x2315, (q15_t)0x84e7, (q15_t)0x230f, (q15_t)0x84e6, (q15_t)0x2309, (q15_t)0x84e4, (q15_t)0x2303, (q15_t)0x84e2, + (q15_t)0x22fd, (q15_t)0x84e1, (q15_t)0x22f7, (q15_t)0x84df, (q15_t)0x22f1, (q15_t)0x84dd, (q15_t)0x22eb, (q15_t)0x84db, + (q15_t)0x22e5, (q15_t)0x84da, (q15_t)0x22df, (q15_t)0x84d8, (q15_t)0x22d9, (q15_t)0x84d6, (q15_t)0x22d3, (q15_t)0x84d5, + (q15_t)0x22cd, (q15_t)0x84d3, (q15_t)0x22c7, (q15_t)0x84d1, (q15_t)0x22c0, (q15_t)0x84cf, (q15_t)0x22ba, (q15_t)0x84ce, + (q15_t)0x22b4, (q15_t)0x84cc, (q15_t)0x22ae, (q15_t)0x84ca, (q15_t)0x22a8, (q15_t)0x84c9, (q15_t)0x22a2, (q15_t)0x84c7, + (q15_t)0x229c, (q15_t)0x84c5, (q15_t)0x2296, (q15_t)0x84c4, (q15_t)0x2290, (q15_t)0x84c2, (q15_t)0x228a, (q15_t)0x84c0, + (q15_t)0x2284, (q15_t)0x84be, (q15_t)0x227e, (q15_t)0x84bd, (q15_t)0x2278, (q15_t)0x84bb, (q15_t)0x2272, (q15_t)0x84b9, + (q15_t)0x226c, (q15_t)0x84b8, (q15_t)0x2266, (q15_t)0x84b6, (q15_t)0x2260, (q15_t)0x84b4, (q15_t)0x225a, (q15_t)0x84b3, + (q15_t)0x2254, (q15_t)0x84b1, (q15_t)0x224e, (q15_t)0x84af, (q15_t)0x2247, (q15_t)0x84ae, (q15_t)0x2241, (q15_t)0x84ac, + (q15_t)0x223b, (q15_t)0x84aa, (q15_t)0x2235, (q15_t)0x84a9, (q15_t)0x222f, (q15_t)0x84a7, (q15_t)0x2229, (q15_t)0x84a5, + (q15_t)0x2223, (q15_t)0x84a3, (q15_t)0x221d, (q15_t)0x84a2, (q15_t)0x2217, (q15_t)0x84a0, (q15_t)0x2211, (q15_t)0x849e, + (q15_t)0x220b, (q15_t)0x849d, (q15_t)0x2205, (q15_t)0x849b, (q15_t)0x21ff, (q15_t)0x8499, (q15_t)0x21f9, (q15_t)0x8498, + (q15_t)0x21f3, (q15_t)0x8496, (q15_t)0x21ed, (q15_t)0x8494, (q15_t)0x21e7, (q15_t)0x8493, (q15_t)0x21e1, (q15_t)0x8491, + (q15_t)0x21da, (q15_t)0x848f, (q15_t)0x21d4, (q15_t)0x848e, (q15_t)0x21ce, (q15_t)0x848c, (q15_t)0x21c8, (q15_t)0x848a, + (q15_t)0x21c2, (q15_t)0x8489, (q15_t)0x21bc, (q15_t)0x8487, (q15_t)0x21b6, (q15_t)0x8486, (q15_t)0x21b0, (q15_t)0x8484, + (q15_t)0x21aa, (q15_t)0x8482, (q15_t)0x21a4, (q15_t)0x8481, (q15_t)0x219e, (q15_t)0x847f, (q15_t)0x2198, (q15_t)0x847d, + (q15_t)0x2192, (q15_t)0x847c, (q15_t)0x218c, (q15_t)0x847a, (q15_t)0x2186, (q15_t)0x8478, (q15_t)0x2180, (q15_t)0x8477, + (q15_t)0x2179, (q15_t)0x8475, (q15_t)0x2173, (q15_t)0x8473, (q15_t)0x216d, (q15_t)0x8472, (q15_t)0x2167, (q15_t)0x8470, + (q15_t)0x2161, (q15_t)0x846e, (q15_t)0x215b, (q15_t)0x846d, (q15_t)0x2155, (q15_t)0x846b, (q15_t)0x214f, (q15_t)0x846a, + (q15_t)0x2149, (q15_t)0x8468, (q15_t)0x2143, (q15_t)0x8466, (q15_t)0x213d, (q15_t)0x8465, (q15_t)0x2137, (q15_t)0x8463, + (q15_t)0x2131, (q15_t)0x8461, (q15_t)0x212b, (q15_t)0x8460, (q15_t)0x2125, (q15_t)0x845e, (q15_t)0x211e, (q15_t)0x845d, + (q15_t)0x2118, (q15_t)0x845b, (q15_t)0x2112, (q15_t)0x8459, (q15_t)0x210c, (q15_t)0x8458, (q15_t)0x2106, (q15_t)0x8456, + (q15_t)0x2100, (q15_t)0x8454, (q15_t)0x20fa, (q15_t)0x8453, (q15_t)0x20f4, (q15_t)0x8451, (q15_t)0x20ee, (q15_t)0x8450, + (q15_t)0x20e8, (q15_t)0x844e, (q15_t)0x20e2, (q15_t)0x844c, (q15_t)0x20dc, (q15_t)0x844b, (q15_t)0x20d6, (q15_t)0x8449, + (q15_t)0x20d0, (q15_t)0x8447, (q15_t)0x20c9, (q15_t)0x8446, (q15_t)0x20c3, (q15_t)0x8444, (q15_t)0x20bd, (q15_t)0x8443, + (q15_t)0x20b7, (q15_t)0x8441, (q15_t)0x20b1, (q15_t)0x843f, (q15_t)0x20ab, (q15_t)0x843e, (q15_t)0x20a5, (q15_t)0x843c, + (q15_t)0x209f, (q15_t)0x843b, (q15_t)0x2099, (q15_t)0x8439, (q15_t)0x2093, (q15_t)0x8437, (q15_t)0x208d, (q15_t)0x8436, + (q15_t)0x2087, (q15_t)0x8434, (q15_t)0x2081, (q15_t)0x8433, (q15_t)0x207a, (q15_t)0x8431, (q15_t)0x2074, (q15_t)0x842f, + (q15_t)0x206e, (q15_t)0x842e, (q15_t)0x2068, (q15_t)0x842c, (q15_t)0x2062, (q15_t)0x842b, (q15_t)0x205c, (q15_t)0x8429, + (q15_t)0x2056, (q15_t)0x8427, (q15_t)0x2050, (q15_t)0x8426, (q15_t)0x204a, (q15_t)0x8424, (q15_t)0x2044, (q15_t)0x8423, + (q15_t)0x203e, (q15_t)0x8421, (q15_t)0x2038, (q15_t)0x8420, (q15_t)0x2032, (q15_t)0x841e, (q15_t)0x202b, (q15_t)0x841c, + (q15_t)0x2025, (q15_t)0x841b, (q15_t)0x201f, (q15_t)0x8419, (q15_t)0x2019, (q15_t)0x8418, (q15_t)0x2013, (q15_t)0x8416, + (q15_t)0x200d, (q15_t)0x8415, (q15_t)0x2007, (q15_t)0x8413, (q15_t)0x2001, (q15_t)0x8411, (q15_t)0x1ffb, (q15_t)0x8410, + (q15_t)0x1ff5, (q15_t)0x840e, (q15_t)0x1fef, (q15_t)0x840d, (q15_t)0x1fe9, (q15_t)0x840b, (q15_t)0x1fe2, (q15_t)0x840a, + (q15_t)0x1fdc, (q15_t)0x8408, (q15_t)0x1fd6, (q15_t)0x8406, (q15_t)0x1fd0, (q15_t)0x8405, (q15_t)0x1fca, (q15_t)0x8403, + (q15_t)0x1fc4, (q15_t)0x8402, (q15_t)0x1fbe, (q15_t)0x8400, (q15_t)0x1fb8, (q15_t)0x83ff, (q15_t)0x1fb2, (q15_t)0x83fd, + (q15_t)0x1fac, (q15_t)0x83fb, (q15_t)0x1fa6, (q15_t)0x83fa, (q15_t)0x1f9f, (q15_t)0x83f8, (q15_t)0x1f99, (q15_t)0x83f7, + (q15_t)0x1f93, (q15_t)0x83f5, (q15_t)0x1f8d, (q15_t)0x83f4, (q15_t)0x1f87, (q15_t)0x83f2, (q15_t)0x1f81, (q15_t)0x83f1, + (q15_t)0x1f7b, (q15_t)0x83ef, (q15_t)0x1f75, (q15_t)0x83ee, (q15_t)0x1f6f, (q15_t)0x83ec, (q15_t)0x1f69, (q15_t)0x83ea, + (q15_t)0x1f63, (q15_t)0x83e9, (q15_t)0x1f5d, (q15_t)0x83e7, (q15_t)0x1f56, (q15_t)0x83e6, (q15_t)0x1f50, (q15_t)0x83e4, + (q15_t)0x1f4a, (q15_t)0x83e3, (q15_t)0x1f44, (q15_t)0x83e1, (q15_t)0x1f3e, (q15_t)0x83e0, (q15_t)0x1f38, (q15_t)0x83de, + (q15_t)0x1f32, (q15_t)0x83dd, (q15_t)0x1f2c, (q15_t)0x83db, (q15_t)0x1f26, (q15_t)0x83da, (q15_t)0x1f20, (q15_t)0x83d8, + (q15_t)0x1f19, (q15_t)0x83d7, (q15_t)0x1f13, (q15_t)0x83d5, (q15_t)0x1f0d, (q15_t)0x83d3, (q15_t)0x1f07, (q15_t)0x83d2, + (q15_t)0x1f01, (q15_t)0x83d0, (q15_t)0x1efb, (q15_t)0x83cf, (q15_t)0x1ef5, (q15_t)0x83cd, (q15_t)0x1eef, (q15_t)0x83cc, + (q15_t)0x1ee9, (q15_t)0x83ca, (q15_t)0x1ee3, (q15_t)0x83c9, (q15_t)0x1edd, (q15_t)0x83c7, (q15_t)0x1ed6, (q15_t)0x83c6, + (q15_t)0x1ed0, (q15_t)0x83c4, (q15_t)0x1eca, (q15_t)0x83c3, (q15_t)0x1ec4, (q15_t)0x83c1, (q15_t)0x1ebe, (q15_t)0x83c0, + (q15_t)0x1eb8, (q15_t)0x83be, (q15_t)0x1eb2, (q15_t)0x83bd, (q15_t)0x1eac, (q15_t)0x83bb, (q15_t)0x1ea6, (q15_t)0x83ba, + (q15_t)0x1ea0, (q15_t)0x83b8, (q15_t)0x1e99, (q15_t)0x83b7, (q15_t)0x1e93, (q15_t)0x83b5, (q15_t)0x1e8d, (q15_t)0x83b4, + (q15_t)0x1e87, (q15_t)0x83b2, (q15_t)0x1e81, (q15_t)0x83b1, (q15_t)0x1e7b, (q15_t)0x83af, (q15_t)0x1e75, (q15_t)0x83ae, + (q15_t)0x1e6f, (q15_t)0x83ac, (q15_t)0x1e69, (q15_t)0x83ab, (q15_t)0x1e62, (q15_t)0x83a9, (q15_t)0x1e5c, (q15_t)0x83a8, + (q15_t)0x1e56, (q15_t)0x83a6, (q15_t)0x1e50, (q15_t)0x83a5, (q15_t)0x1e4a, (q15_t)0x83a3, (q15_t)0x1e44, (q15_t)0x83a2, + (q15_t)0x1e3e, (q15_t)0x83a0, (q15_t)0x1e38, (q15_t)0x839f, (q15_t)0x1e32, (q15_t)0x839d, (q15_t)0x1e2c, (q15_t)0x839c, + (q15_t)0x1e25, (q15_t)0x839a, (q15_t)0x1e1f, (q15_t)0x8399, (q15_t)0x1e19, (q15_t)0x8397, (q15_t)0x1e13, (q15_t)0x8396, + (q15_t)0x1e0d, (q15_t)0x8394, (q15_t)0x1e07, (q15_t)0x8393, (q15_t)0x1e01, (q15_t)0x8392, (q15_t)0x1dfb, (q15_t)0x8390, + (q15_t)0x1df5, (q15_t)0x838f, (q15_t)0x1dee, (q15_t)0x838d, (q15_t)0x1de8, (q15_t)0x838c, (q15_t)0x1de2, (q15_t)0x838a, + (q15_t)0x1ddc, (q15_t)0x8389, (q15_t)0x1dd6, (q15_t)0x8387, (q15_t)0x1dd0, (q15_t)0x8386, (q15_t)0x1dca, (q15_t)0x8384, + (q15_t)0x1dc4, (q15_t)0x8383, (q15_t)0x1dbe, (q15_t)0x8381, (q15_t)0x1db7, (q15_t)0x8380, (q15_t)0x1db1, (q15_t)0x837e, + (q15_t)0x1dab, (q15_t)0x837d, (q15_t)0x1da5, (q15_t)0x837c, (q15_t)0x1d9f, (q15_t)0x837a, (q15_t)0x1d99, (q15_t)0x8379, + (q15_t)0x1d93, (q15_t)0x8377, (q15_t)0x1d8d, (q15_t)0x8376, (q15_t)0x1d87, (q15_t)0x8374, (q15_t)0x1d80, (q15_t)0x8373, + (q15_t)0x1d7a, (q15_t)0x8371, (q15_t)0x1d74, (q15_t)0x8370, (q15_t)0x1d6e, (q15_t)0x836f, (q15_t)0x1d68, (q15_t)0x836d, + (q15_t)0x1d62, (q15_t)0x836c, (q15_t)0x1d5c, (q15_t)0x836a, (q15_t)0x1d56, (q15_t)0x8369, (q15_t)0x1d50, (q15_t)0x8367, + (q15_t)0x1d49, (q15_t)0x8366, (q15_t)0x1d43, (q15_t)0x8364, (q15_t)0x1d3d, (q15_t)0x8363, (q15_t)0x1d37, (q15_t)0x8362, + (q15_t)0x1d31, (q15_t)0x8360, (q15_t)0x1d2b, (q15_t)0x835f, (q15_t)0x1d25, (q15_t)0x835d, (q15_t)0x1d1f, (q15_t)0x835c, + (q15_t)0x1d18, (q15_t)0x835a, (q15_t)0x1d12, (q15_t)0x8359, (q15_t)0x1d0c, (q15_t)0x8358, (q15_t)0x1d06, (q15_t)0x8356, + (q15_t)0x1d00, (q15_t)0x8355, (q15_t)0x1cfa, (q15_t)0x8353, (q15_t)0x1cf4, (q15_t)0x8352, (q15_t)0x1cee, (q15_t)0x8350, + (q15_t)0x1ce8, (q15_t)0x834f, (q15_t)0x1ce1, (q15_t)0x834e, (q15_t)0x1cdb, (q15_t)0x834c, (q15_t)0x1cd5, (q15_t)0x834b, + (q15_t)0x1ccf, (q15_t)0x8349, (q15_t)0x1cc9, (q15_t)0x8348, (q15_t)0x1cc3, (q15_t)0x8347, (q15_t)0x1cbd, (q15_t)0x8345, + (q15_t)0x1cb7, (q15_t)0x8344, (q15_t)0x1cb0, (q15_t)0x8342, (q15_t)0x1caa, (q15_t)0x8341, (q15_t)0x1ca4, (q15_t)0x833f, + (q15_t)0x1c9e, (q15_t)0x833e, (q15_t)0x1c98, (q15_t)0x833d, (q15_t)0x1c92, (q15_t)0x833b, (q15_t)0x1c8c, (q15_t)0x833a, + (q15_t)0x1c86, (q15_t)0x8338, (q15_t)0x1c7f, (q15_t)0x8337, (q15_t)0x1c79, (q15_t)0x8336, (q15_t)0x1c73, (q15_t)0x8334, + (q15_t)0x1c6d, (q15_t)0x8333, (q15_t)0x1c67, (q15_t)0x8331, (q15_t)0x1c61, (q15_t)0x8330, (q15_t)0x1c5b, (q15_t)0x832f, + (q15_t)0x1c55, (q15_t)0x832d, (q15_t)0x1c4e, (q15_t)0x832c, (q15_t)0x1c48, (q15_t)0x832b, (q15_t)0x1c42, (q15_t)0x8329, + (q15_t)0x1c3c, (q15_t)0x8328, (q15_t)0x1c36, (q15_t)0x8326, (q15_t)0x1c30, (q15_t)0x8325, (q15_t)0x1c2a, (q15_t)0x8324, + (q15_t)0x1c24, (q15_t)0x8322, (q15_t)0x1c1d, (q15_t)0x8321, (q15_t)0x1c17, (q15_t)0x831f, (q15_t)0x1c11, (q15_t)0x831e, + (q15_t)0x1c0b, (q15_t)0x831d, (q15_t)0x1c05, (q15_t)0x831b, (q15_t)0x1bff, (q15_t)0x831a, (q15_t)0x1bf9, (q15_t)0x8319, + (q15_t)0x1bf2, (q15_t)0x8317, (q15_t)0x1bec, (q15_t)0x8316, (q15_t)0x1be6, (q15_t)0x8314, (q15_t)0x1be0, (q15_t)0x8313, + (q15_t)0x1bda, (q15_t)0x8312, (q15_t)0x1bd4, (q15_t)0x8310, (q15_t)0x1bce, (q15_t)0x830f, (q15_t)0x1bc8, (q15_t)0x830e, + (q15_t)0x1bc1, (q15_t)0x830c, (q15_t)0x1bbb, (q15_t)0x830b, (q15_t)0x1bb5, (q15_t)0x830a, (q15_t)0x1baf, (q15_t)0x8308, + (q15_t)0x1ba9, (q15_t)0x8307, (q15_t)0x1ba3, (q15_t)0x8305, (q15_t)0x1b9d, (q15_t)0x8304, (q15_t)0x1b96, (q15_t)0x8303, + (q15_t)0x1b90, (q15_t)0x8301, (q15_t)0x1b8a, (q15_t)0x8300, (q15_t)0x1b84, (q15_t)0x82ff, (q15_t)0x1b7e, (q15_t)0x82fd, + (q15_t)0x1b78, (q15_t)0x82fc, (q15_t)0x1b72, (q15_t)0x82fb, (q15_t)0x1b6c, (q15_t)0x82f9, (q15_t)0x1b65, (q15_t)0x82f8, + (q15_t)0x1b5f, (q15_t)0x82f7, (q15_t)0x1b59, (q15_t)0x82f5, (q15_t)0x1b53, (q15_t)0x82f4, (q15_t)0x1b4d, (q15_t)0x82f3, + (q15_t)0x1b47, (q15_t)0x82f1, (q15_t)0x1b41, (q15_t)0x82f0, (q15_t)0x1b3a, (q15_t)0x82ef, (q15_t)0x1b34, (q15_t)0x82ed, + (q15_t)0x1b2e, (q15_t)0x82ec, (q15_t)0x1b28, (q15_t)0x82eb, (q15_t)0x1b22, (q15_t)0x82e9, (q15_t)0x1b1c, (q15_t)0x82e8, + (q15_t)0x1b16, (q15_t)0x82e7, (q15_t)0x1b0f, (q15_t)0x82e5, (q15_t)0x1b09, (q15_t)0x82e4, (q15_t)0x1b03, (q15_t)0x82e3, + (q15_t)0x1afd, (q15_t)0x82e1, (q15_t)0x1af7, (q15_t)0x82e0, (q15_t)0x1af1, (q15_t)0x82df, (q15_t)0x1aeb, (q15_t)0x82dd, + (q15_t)0x1ae4, (q15_t)0x82dc, (q15_t)0x1ade, (q15_t)0x82db, (q15_t)0x1ad8, (q15_t)0x82d9, (q15_t)0x1ad2, (q15_t)0x82d8, + (q15_t)0x1acc, (q15_t)0x82d7, (q15_t)0x1ac6, (q15_t)0x82d5, (q15_t)0x1ac0, (q15_t)0x82d4, (q15_t)0x1ab9, (q15_t)0x82d3, + (q15_t)0x1ab3, (q15_t)0x82d1, (q15_t)0x1aad, (q15_t)0x82d0, (q15_t)0x1aa7, (q15_t)0x82cf, (q15_t)0x1aa1, (q15_t)0x82ce, + (q15_t)0x1a9b, (q15_t)0x82cc, (q15_t)0x1a95, (q15_t)0x82cb, (q15_t)0x1a8e, (q15_t)0x82ca, (q15_t)0x1a88, (q15_t)0x82c8, + (q15_t)0x1a82, (q15_t)0x82c7, (q15_t)0x1a7c, (q15_t)0x82c6, (q15_t)0x1a76, (q15_t)0x82c4, (q15_t)0x1a70, (q15_t)0x82c3, + (q15_t)0x1a6a, (q15_t)0x82c2, (q15_t)0x1a63, (q15_t)0x82c1, (q15_t)0x1a5d, (q15_t)0x82bf, (q15_t)0x1a57, (q15_t)0x82be, + (q15_t)0x1a51, (q15_t)0x82bd, (q15_t)0x1a4b, (q15_t)0x82bb, (q15_t)0x1a45, (q15_t)0x82ba, (q15_t)0x1a3e, (q15_t)0x82b9, + (q15_t)0x1a38, (q15_t)0x82b7, (q15_t)0x1a32, (q15_t)0x82b6, (q15_t)0x1a2c, (q15_t)0x82b5, (q15_t)0x1a26, (q15_t)0x82b4, + (q15_t)0x1a20, (q15_t)0x82b2, (q15_t)0x1a1a, (q15_t)0x82b1, (q15_t)0x1a13, (q15_t)0x82b0, (q15_t)0x1a0d, (q15_t)0x82ae, + (q15_t)0x1a07, (q15_t)0x82ad, (q15_t)0x1a01, (q15_t)0x82ac, (q15_t)0x19fb, (q15_t)0x82ab, (q15_t)0x19f5, (q15_t)0x82a9, + (q15_t)0x19ef, (q15_t)0x82a8, (q15_t)0x19e8, (q15_t)0x82a7, (q15_t)0x19e2, (q15_t)0x82a6, (q15_t)0x19dc, (q15_t)0x82a4, + (q15_t)0x19d6, (q15_t)0x82a3, (q15_t)0x19d0, (q15_t)0x82a2, (q15_t)0x19ca, (q15_t)0x82a0, (q15_t)0x19c3, (q15_t)0x829f, + (q15_t)0x19bd, (q15_t)0x829e, (q15_t)0x19b7, (q15_t)0x829d, (q15_t)0x19b1, (q15_t)0x829b, (q15_t)0x19ab, (q15_t)0x829a, + (q15_t)0x19a5, (q15_t)0x8299, (q15_t)0x199f, (q15_t)0x8298, (q15_t)0x1998, (q15_t)0x8296, (q15_t)0x1992, (q15_t)0x8295, + (q15_t)0x198c, (q15_t)0x8294, (q15_t)0x1986, (q15_t)0x8293, (q15_t)0x1980, (q15_t)0x8291, (q15_t)0x197a, (q15_t)0x8290, + (q15_t)0x1973, (q15_t)0x828f, (q15_t)0x196d, (q15_t)0x828e, (q15_t)0x1967, (q15_t)0x828c, (q15_t)0x1961, (q15_t)0x828b, + (q15_t)0x195b, (q15_t)0x828a, (q15_t)0x1955, (q15_t)0x8289, (q15_t)0x194e, (q15_t)0x8287, (q15_t)0x1948, (q15_t)0x8286, + (q15_t)0x1942, (q15_t)0x8285, (q15_t)0x193c, (q15_t)0x8284, (q15_t)0x1936, (q15_t)0x8282, (q15_t)0x1930, (q15_t)0x8281, + (q15_t)0x192a, (q15_t)0x8280, (q15_t)0x1923, (q15_t)0x827f, (q15_t)0x191d, (q15_t)0x827e, (q15_t)0x1917, (q15_t)0x827c, + (q15_t)0x1911, (q15_t)0x827b, (q15_t)0x190b, (q15_t)0x827a, (q15_t)0x1905, (q15_t)0x8279, (q15_t)0x18fe, (q15_t)0x8277, + (q15_t)0x18f8, (q15_t)0x8276, (q15_t)0x18f2, (q15_t)0x8275, (q15_t)0x18ec, (q15_t)0x8274, (q15_t)0x18e6, (q15_t)0x8272, + (q15_t)0x18e0, (q15_t)0x8271, (q15_t)0x18d9, (q15_t)0x8270, (q15_t)0x18d3, (q15_t)0x826f, (q15_t)0x18cd, (q15_t)0x826e, + (q15_t)0x18c7, (q15_t)0x826c, (q15_t)0x18c1, (q15_t)0x826b, (q15_t)0x18bb, (q15_t)0x826a, (q15_t)0x18b4, (q15_t)0x8269, + (q15_t)0x18ae, (q15_t)0x8268, (q15_t)0x18a8, (q15_t)0x8266, (q15_t)0x18a2, (q15_t)0x8265, (q15_t)0x189c, (q15_t)0x8264, + (q15_t)0x1896, (q15_t)0x8263, (q15_t)0x188f, (q15_t)0x8261, (q15_t)0x1889, (q15_t)0x8260, (q15_t)0x1883, (q15_t)0x825f, + (q15_t)0x187d, (q15_t)0x825e, (q15_t)0x1877, (q15_t)0x825d, (q15_t)0x1871, (q15_t)0x825b, (q15_t)0x186a, (q15_t)0x825a, + (q15_t)0x1864, (q15_t)0x8259, (q15_t)0x185e, (q15_t)0x8258, (q15_t)0x1858, (q15_t)0x8257, (q15_t)0x1852, (q15_t)0x8255, + (q15_t)0x184c, (q15_t)0x8254, (q15_t)0x1845, (q15_t)0x8253, (q15_t)0x183f, (q15_t)0x8252, (q15_t)0x1839, (q15_t)0x8251, + (q15_t)0x1833, (q15_t)0x8250, (q15_t)0x182d, (q15_t)0x824e, (q15_t)0x1827, (q15_t)0x824d, (q15_t)0x1820, (q15_t)0x824c, + (q15_t)0x181a, (q15_t)0x824b, (q15_t)0x1814, (q15_t)0x824a, (q15_t)0x180e, (q15_t)0x8248, (q15_t)0x1808, (q15_t)0x8247, + (q15_t)0x1802, (q15_t)0x8246, (q15_t)0x17fb, (q15_t)0x8245, (q15_t)0x17f5, (q15_t)0x8244, (q15_t)0x17ef, (q15_t)0x8243, + (q15_t)0x17e9, (q15_t)0x8241, (q15_t)0x17e3, (q15_t)0x8240, (q15_t)0x17dd, (q15_t)0x823f, (q15_t)0x17d6, (q15_t)0x823e, + (q15_t)0x17d0, (q15_t)0x823d, (q15_t)0x17ca, (q15_t)0x823b, (q15_t)0x17c4, (q15_t)0x823a, (q15_t)0x17be, (q15_t)0x8239, + (q15_t)0x17b7, (q15_t)0x8238, (q15_t)0x17b1, (q15_t)0x8237, (q15_t)0x17ab, (q15_t)0x8236, (q15_t)0x17a5, (q15_t)0x8234, + (q15_t)0x179f, (q15_t)0x8233, (q15_t)0x1799, (q15_t)0x8232, (q15_t)0x1792, (q15_t)0x8231, (q15_t)0x178c, (q15_t)0x8230, + (q15_t)0x1786, (q15_t)0x822f, (q15_t)0x1780, (q15_t)0x822e, (q15_t)0x177a, (q15_t)0x822c, (q15_t)0x1774, (q15_t)0x822b, + (q15_t)0x176d, (q15_t)0x822a, (q15_t)0x1767, (q15_t)0x8229, (q15_t)0x1761, (q15_t)0x8228, (q15_t)0x175b, (q15_t)0x8227, + (q15_t)0x1755, (q15_t)0x8226, (q15_t)0x174e, (q15_t)0x8224, (q15_t)0x1748, (q15_t)0x8223, (q15_t)0x1742, (q15_t)0x8222, + (q15_t)0x173c, (q15_t)0x8221, (q15_t)0x1736, (q15_t)0x8220, (q15_t)0x1730, (q15_t)0x821f, (q15_t)0x1729, (q15_t)0x821e, + (q15_t)0x1723, (q15_t)0x821c, (q15_t)0x171d, (q15_t)0x821b, (q15_t)0x1717, (q15_t)0x821a, (q15_t)0x1711, (q15_t)0x8219, + (q15_t)0x170a, (q15_t)0x8218, (q15_t)0x1704, (q15_t)0x8217, (q15_t)0x16fe, (q15_t)0x8216, (q15_t)0x16f8, (q15_t)0x8214, + (q15_t)0x16f2, (q15_t)0x8213, (q15_t)0x16ec, (q15_t)0x8212, (q15_t)0x16e5, (q15_t)0x8211, (q15_t)0x16df, (q15_t)0x8210, + (q15_t)0x16d9, (q15_t)0x820f, (q15_t)0x16d3, (q15_t)0x820e, (q15_t)0x16cd, (q15_t)0x820d, (q15_t)0x16c6, (q15_t)0x820b, + (q15_t)0x16c0, (q15_t)0x820a, (q15_t)0x16ba, (q15_t)0x8209, (q15_t)0x16b4, (q15_t)0x8208, (q15_t)0x16ae, (q15_t)0x8207, + (q15_t)0x16a8, (q15_t)0x8206, (q15_t)0x16a1, (q15_t)0x8205, (q15_t)0x169b, (q15_t)0x8204, (q15_t)0x1695, (q15_t)0x8203, + (q15_t)0x168f, (q15_t)0x8201, (q15_t)0x1689, (q15_t)0x8200, (q15_t)0x1682, (q15_t)0x81ff, (q15_t)0x167c, (q15_t)0x81fe, + (q15_t)0x1676, (q15_t)0x81fd, (q15_t)0x1670, (q15_t)0x81fc, (q15_t)0x166a, (q15_t)0x81fb, (q15_t)0x1664, (q15_t)0x81fa, + (q15_t)0x165d, (q15_t)0x81f9, (q15_t)0x1657, (q15_t)0x81f8, (q15_t)0x1651, (q15_t)0x81f6, (q15_t)0x164b, (q15_t)0x81f5, + (q15_t)0x1645, (q15_t)0x81f4, (q15_t)0x163e, (q15_t)0x81f3, (q15_t)0x1638, (q15_t)0x81f2, (q15_t)0x1632, (q15_t)0x81f1, + (q15_t)0x162c, (q15_t)0x81f0, (q15_t)0x1626, (q15_t)0x81ef, (q15_t)0x161f, (q15_t)0x81ee, (q15_t)0x1619, (q15_t)0x81ed, + (q15_t)0x1613, (q15_t)0x81ec, (q15_t)0x160d, (q15_t)0x81ea, (q15_t)0x1607, (q15_t)0x81e9, (q15_t)0x1601, (q15_t)0x81e8, + (q15_t)0x15fa, (q15_t)0x81e7, (q15_t)0x15f4, (q15_t)0x81e6, (q15_t)0x15ee, (q15_t)0x81e5, (q15_t)0x15e8, (q15_t)0x81e4, + (q15_t)0x15e2, (q15_t)0x81e3, (q15_t)0x15db, (q15_t)0x81e2, (q15_t)0x15d5, (q15_t)0x81e1, (q15_t)0x15cf, (q15_t)0x81e0, + (q15_t)0x15c9, (q15_t)0x81df, (q15_t)0x15c3, (q15_t)0x81de, (q15_t)0x15bc, (q15_t)0x81dc, (q15_t)0x15b6, (q15_t)0x81db, + (q15_t)0x15b0, (q15_t)0x81da, (q15_t)0x15aa, (q15_t)0x81d9, (q15_t)0x15a4, (q15_t)0x81d8, (q15_t)0x159d, (q15_t)0x81d7, + (q15_t)0x1597, (q15_t)0x81d6, (q15_t)0x1591, (q15_t)0x81d5, (q15_t)0x158b, (q15_t)0x81d4, (q15_t)0x1585, (q15_t)0x81d3, + (q15_t)0x157f, (q15_t)0x81d2, (q15_t)0x1578, (q15_t)0x81d1, (q15_t)0x1572, (q15_t)0x81d0, (q15_t)0x156c, (q15_t)0x81cf, + (q15_t)0x1566, (q15_t)0x81ce, (q15_t)0x1560, (q15_t)0x81cd, (q15_t)0x1559, (q15_t)0x81cc, (q15_t)0x1553, (q15_t)0x81cb, + (q15_t)0x154d, (q15_t)0x81c9, (q15_t)0x1547, (q15_t)0x81c8, (q15_t)0x1541, (q15_t)0x81c7, (q15_t)0x153a, (q15_t)0x81c6, + (q15_t)0x1534, (q15_t)0x81c5, (q15_t)0x152e, (q15_t)0x81c4, (q15_t)0x1528, (q15_t)0x81c3, (q15_t)0x1522, (q15_t)0x81c2, + (q15_t)0x151b, (q15_t)0x81c1, (q15_t)0x1515, (q15_t)0x81c0, (q15_t)0x150f, (q15_t)0x81bf, (q15_t)0x1509, (q15_t)0x81be, + (q15_t)0x1503, (q15_t)0x81bd, (q15_t)0x14fc, (q15_t)0x81bc, (q15_t)0x14f6, (q15_t)0x81bb, (q15_t)0x14f0, (q15_t)0x81ba, + (q15_t)0x14ea, (q15_t)0x81b9, (q15_t)0x14e4, (q15_t)0x81b8, (q15_t)0x14dd, (q15_t)0x81b7, (q15_t)0x14d7, (q15_t)0x81b6, + (q15_t)0x14d1, (q15_t)0x81b5, (q15_t)0x14cb, (q15_t)0x81b4, (q15_t)0x14c5, (q15_t)0x81b3, (q15_t)0x14be, (q15_t)0x81b2, + (q15_t)0x14b8, (q15_t)0x81b1, (q15_t)0x14b2, (q15_t)0x81b0, (q15_t)0x14ac, (q15_t)0x81af, (q15_t)0x14a6, (q15_t)0x81ae, + (q15_t)0x149f, (q15_t)0x81ad, (q15_t)0x1499, (q15_t)0x81ac, (q15_t)0x1493, (q15_t)0x81ab, (q15_t)0x148d, (q15_t)0x81aa, + (q15_t)0x1487, (q15_t)0x81a9, (q15_t)0x1480, (q15_t)0x81a8, (q15_t)0x147a, (q15_t)0x81a7, (q15_t)0x1474, (q15_t)0x81a6, + (q15_t)0x146e, (q15_t)0x81a5, (q15_t)0x1468, (q15_t)0x81a4, (q15_t)0x1461, (q15_t)0x81a3, (q15_t)0x145b, (q15_t)0x81a2, + (q15_t)0x1455, (q15_t)0x81a1, (q15_t)0x144f, (q15_t)0x81a0, (q15_t)0x1449, (q15_t)0x819f, (q15_t)0x1442, (q15_t)0x819e, + (q15_t)0x143c, (q15_t)0x819d, (q15_t)0x1436, (q15_t)0x819c, (q15_t)0x1430, (q15_t)0x819b, (q15_t)0x142a, (q15_t)0x819a, + (q15_t)0x1423, (q15_t)0x8199, (q15_t)0x141d, (q15_t)0x8198, (q15_t)0x1417, (q15_t)0x8197, (q15_t)0x1411, (q15_t)0x8196, + (q15_t)0x140b, (q15_t)0x8195, (q15_t)0x1404, (q15_t)0x8194, (q15_t)0x13fe, (q15_t)0x8193, (q15_t)0x13f8, (q15_t)0x8192, + (q15_t)0x13f2, (q15_t)0x8191, (q15_t)0x13eb, (q15_t)0x8190, (q15_t)0x13e5, (q15_t)0x818f, (q15_t)0x13df, (q15_t)0x818e, + (q15_t)0x13d9, (q15_t)0x818d, (q15_t)0x13d3, (q15_t)0x818c, (q15_t)0x13cc, (q15_t)0x818b, (q15_t)0x13c6, (q15_t)0x818a, + (q15_t)0x13c0, (q15_t)0x8189, (q15_t)0x13ba, (q15_t)0x8188, (q15_t)0x13b4, (q15_t)0x8187, (q15_t)0x13ad, (q15_t)0x8186, + (q15_t)0x13a7, (q15_t)0x8185, (q15_t)0x13a1, (q15_t)0x8184, (q15_t)0x139b, (q15_t)0x8183, (q15_t)0x1395, (q15_t)0x8182, + (q15_t)0x138e, (q15_t)0x8181, (q15_t)0x1388, (q15_t)0x8180, (q15_t)0x1382, (q15_t)0x817f, (q15_t)0x137c, (q15_t)0x817e, + (q15_t)0x1376, (q15_t)0x817d, (q15_t)0x136f, (q15_t)0x817c, (q15_t)0x1369, (q15_t)0x817c, (q15_t)0x1363, (q15_t)0x817b, + (q15_t)0x135d, (q15_t)0x817a, (q15_t)0x1356, (q15_t)0x8179, (q15_t)0x1350, (q15_t)0x8178, (q15_t)0x134a, (q15_t)0x8177, + (q15_t)0x1344, (q15_t)0x8176, (q15_t)0x133e, (q15_t)0x8175, (q15_t)0x1337, (q15_t)0x8174, (q15_t)0x1331, (q15_t)0x8173, + (q15_t)0x132b, (q15_t)0x8172, (q15_t)0x1325, (q15_t)0x8171, (q15_t)0x131f, (q15_t)0x8170, (q15_t)0x1318, (q15_t)0x816f, + (q15_t)0x1312, (q15_t)0x816e, (q15_t)0x130c, (q15_t)0x816d, (q15_t)0x1306, (q15_t)0x816c, (q15_t)0x12ff, (q15_t)0x816c, + (q15_t)0x12f9, (q15_t)0x816b, (q15_t)0x12f3, (q15_t)0x816a, (q15_t)0x12ed, (q15_t)0x8169, (q15_t)0x12e7, (q15_t)0x8168, + (q15_t)0x12e0, (q15_t)0x8167, (q15_t)0x12da, (q15_t)0x8166, (q15_t)0x12d4, (q15_t)0x8165, (q15_t)0x12ce, (q15_t)0x8164, + (q15_t)0x12c8, (q15_t)0x8163, (q15_t)0x12c1, (q15_t)0x8162, (q15_t)0x12bb, (q15_t)0x8161, (q15_t)0x12b5, (q15_t)0x8160, + (q15_t)0x12af, (q15_t)0x815f, (q15_t)0x12a8, (q15_t)0x815f, (q15_t)0x12a2, (q15_t)0x815e, (q15_t)0x129c, (q15_t)0x815d, + (q15_t)0x1296, (q15_t)0x815c, (q15_t)0x1290, (q15_t)0x815b, (q15_t)0x1289, (q15_t)0x815a, (q15_t)0x1283, (q15_t)0x8159, + (q15_t)0x127d, (q15_t)0x8158, (q15_t)0x1277, (q15_t)0x8157, (q15_t)0x1271, (q15_t)0x8156, (q15_t)0x126a, (q15_t)0x8155, + (q15_t)0x1264, (q15_t)0x8155, (q15_t)0x125e, (q15_t)0x8154, (q15_t)0x1258, (q15_t)0x8153, (q15_t)0x1251, (q15_t)0x8152, + (q15_t)0x124b, (q15_t)0x8151, (q15_t)0x1245, (q15_t)0x8150, (q15_t)0x123f, (q15_t)0x814f, (q15_t)0x1239, (q15_t)0x814e, + (q15_t)0x1232, (q15_t)0x814d, (q15_t)0x122c, (q15_t)0x814c, (q15_t)0x1226, (q15_t)0x814c, (q15_t)0x1220, (q15_t)0x814b, + (q15_t)0x1219, (q15_t)0x814a, (q15_t)0x1213, (q15_t)0x8149, (q15_t)0x120d, (q15_t)0x8148, (q15_t)0x1207, (q15_t)0x8147, + (q15_t)0x1201, (q15_t)0x8146, (q15_t)0x11fa, (q15_t)0x8145, (q15_t)0x11f4, (q15_t)0x8145, (q15_t)0x11ee, (q15_t)0x8144, + (q15_t)0x11e8, (q15_t)0x8143, (q15_t)0x11e1, (q15_t)0x8142, (q15_t)0x11db, (q15_t)0x8141, (q15_t)0x11d5, (q15_t)0x8140, + (q15_t)0x11cf, (q15_t)0x813f, (q15_t)0x11c9, (q15_t)0x813e, (q15_t)0x11c2, (q15_t)0x813d, (q15_t)0x11bc, (q15_t)0x813d, + (q15_t)0x11b6, (q15_t)0x813c, (q15_t)0x11b0, (q15_t)0x813b, (q15_t)0x11a9, (q15_t)0x813a, (q15_t)0x11a3, (q15_t)0x8139, + (q15_t)0x119d, (q15_t)0x8138, (q15_t)0x1197, (q15_t)0x8137, (q15_t)0x1191, (q15_t)0x8137, (q15_t)0x118a, (q15_t)0x8136, + (q15_t)0x1184, (q15_t)0x8135, (q15_t)0x117e, (q15_t)0x8134, (q15_t)0x1178, (q15_t)0x8133, (q15_t)0x1171, (q15_t)0x8132, + (q15_t)0x116b, (q15_t)0x8131, (q15_t)0x1165, (q15_t)0x8131, (q15_t)0x115f, (q15_t)0x8130, (q15_t)0x1159, (q15_t)0x812f, + (q15_t)0x1152, (q15_t)0x812e, (q15_t)0x114c, (q15_t)0x812d, (q15_t)0x1146, (q15_t)0x812c, (q15_t)0x1140, (q15_t)0x812b, + (q15_t)0x1139, (q15_t)0x812b, (q15_t)0x1133, (q15_t)0x812a, (q15_t)0x112d, (q15_t)0x8129, (q15_t)0x1127, (q15_t)0x8128, + (q15_t)0x1121, (q15_t)0x8127, (q15_t)0x111a, (q15_t)0x8126, (q15_t)0x1114, (q15_t)0x8126, (q15_t)0x110e, (q15_t)0x8125, + (q15_t)0x1108, (q15_t)0x8124, (q15_t)0x1101, (q15_t)0x8123, (q15_t)0x10fb, (q15_t)0x8122, (q15_t)0x10f5, (q15_t)0x8121, + (q15_t)0x10ef, (q15_t)0x8121, (q15_t)0x10e8, (q15_t)0x8120, (q15_t)0x10e2, (q15_t)0x811f, (q15_t)0x10dc, (q15_t)0x811e, + (q15_t)0x10d6, (q15_t)0x811d, (q15_t)0x10d0, (q15_t)0x811c, (q15_t)0x10c9, (q15_t)0x811c, (q15_t)0x10c3, (q15_t)0x811b, + (q15_t)0x10bd, (q15_t)0x811a, (q15_t)0x10b7, (q15_t)0x8119, (q15_t)0x10b0, (q15_t)0x8118, (q15_t)0x10aa, (q15_t)0x8117, + (q15_t)0x10a4, (q15_t)0x8117, (q15_t)0x109e, (q15_t)0x8116, (q15_t)0x1098, (q15_t)0x8115, (q15_t)0x1091, (q15_t)0x8114, + (q15_t)0x108b, (q15_t)0x8113, (q15_t)0x1085, (q15_t)0x8113, (q15_t)0x107f, (q15_t)0x8112, (q15_t)0x1078, (q15_t)0x8111, + (q15_t)0x1072, (q15_t)0x8110, (q15_t)0x106c, (q15_t)0x810f, (q15_t)0x1066, (q15_t)0x810f, (q15_t)0x105f, (q15_t)0x810e, + (q15_t)0x1059, (q15_t)0x810d, (q15_t)0x1053, (q15_t)0x810c, (q15_t)0x104d, (q15_t)0x810b, (q15_t)0x1047, (q15_t)0x810b, + (q15_t)0x1040, (q15_t)0x810a, (q15_t)0x103a, (q15_t)0x8109, (q15_t)0x1034, (q15_t)0x8108, (q15_t)0x102e, (q15_t)0x8107, + (q15_t)0x1027, (q15_t)0x8107, (q15_t)0x1021, (q15_t)0x8106, (q15_t)0x101b, (q15_t)0x8105, (q15_t)0x1015, (q15_t)0x8104, + (q15_t)0x100e, (q15_t)0x8103, (q15_t)0x1008, (q15_t)0x8103, (q15_t)0x1002, (q15_t)0x8102, (q15_t)0xffc, (q15_t)0x8101, + (q15_t)0xff5, (q15_t)0x8100, (q15_t)0xfef, (q15_t)0x80ff, (q15_t)0xfe9, (q15_t)0x80ff, (q15_t)0xfe3, (q15_t)0x80fe, + (q15_t)0xfdd, (q15_t)0x80fd, (q15_t)0xfd6, (q15_t)0x80fc, (q15_t)0xfd0, (q15_t)0x80fc, (q15_t)0xfca, (q15_t)0x80fb, + (q15_t)0xfc4, (q15_t)0x80fa, (q15_t)0xfbd, (q15_t)0x80f9, (q15_t)0xfb7, (q15_t)0x80f8, (q15_t)0xfb1, (q15_t)0x80f8, + (q15_t)0xfab, (q15_t)0x80f7, (q15_t)0xfa4, (q15_t)0x80f6, (q15_t)0xf9e, (q15_t)0x80f5, (q15_t)0xf98, (q15_t)0x80f5, + (q15_t)0xf92, (q15_t)0x80f4, (q15_t)0xf8b, (q15_t)0x80f3, (q15_t)0xf85, (q15_t)0x80f2, (q15_t)0xf7f, (q15_t)0x80f2, + (q15_t)0xf79, (q15_t)0x80f1, (q15_t)0xf73, (q15_t)0x80f0, (q15_t)0xf6c, (q15_t)0x80ef, (q15_t)0xf66, (q15_t)0x80ef, + (q15_t)0xf60, (q15_t)0x80ee, (q15_t)0xf5a, (q15_t)0x80ed, (q15_t)0xf53, (q15_t)0x80ec, (q15_t)0xf4d, (q15_t)0x80ec, + (q15_t)0xf47, (q15_t)0x80eb, (q15_t)0xf41, (q15_t)0x80ea, (q15_t)0xf3a, (q15_t)0x80e9, (q15_t)0xf34, (q15_t)0x80e9, + (q15_t)0xf2e, (q15_t)0x80e8, (q15_t)0xf28, (q15_t)0x80e7, (q15_t)0xf21, (q15_t)0x80e6, (q15_t)0xf1b, (q15_t)0x80e6, + (q15_t)0xf15, (q15_t)0x80e5, (q15_t)0xf0f, (q15_t)0x80e4, (q15_t)0xf08, (q15_t)0x80e3, (q15_t)0xf02, (q15_t)0x80e3, + (q15_t)0xefc, (q15_t)0x80e2, (q15_t)0xef6, (q15_t)0x80e1, (q15_t)0xef0, (q15_t)0x80e0, (q15_t)0xee9, (q15_t)0x80e0, + (q15_t)0xee3, (q15_t)0x80df, (q15_t)0xedd, (q15_t)0x80de, (q15_t)0xed7, (q15_t)0x80dd, (q15_t)0xed0, (q15_t)0x80dd, + (q15_t)0xeca, (q15_t)0x80dc, (q15_t)0xec4, (q15_t)0x80db, (q15_t)0xebe, (q15_t)0x80db, (q15_t)0xeb7, (q15_t)0x80da, + (q15_t)0xeb1, (q15_t)0x80d9, (q15_t)0xeab, (q15_t)0x80d8, (q15_t)0xea5, (q15_t)0x80d8, (q15_t)0xe9e, (q15_t)0x80d7, + (q15_t)0xe98, (q15_t)0x80d6, (q15_t)0xe92, (q15_t)0x80d6, (q15_t)0xe8c, (q15_t)0x80d5, (q15_t)0xe85, (q15_t)0x80d4, + (q15_t)0xe7f, (q15_t)0x80d3, (q15_t)0xe79, (q15_t)0x80d3, (q15_t)0xe73, (q15_t)0x80d2, (q15_t)0xe6c, (q15_t)0x80d1, + (q15_t)0xe66, (q15_t)0x80d1, (q15_t)0xe60, (q15_t)0x80d0, (q15_t)0xe5a, (q15_t)0x80cf, (q15_t)0xe53, (q15_t)0x80ce, + (q15_t)0xe4d, (q15_t)0x80ce, (q15_t)0xe47, (q15_t)0x80cd, (q15_t)0xe41, (q15_t)0x80cc, (q15_t)0xe3a, (q15_t)0x80cc, + (q15_t)0xe34, (q15_t)0x80cb, (q15_t)0xe2e, (q15_t)0x80ca, (q15_t)0xe28, (q15_t)0x80ca, (q15_t)0xe22, (q15_t)0x80c9, + (q15_t)0xe1b, (q15_t)0x80c8, (q15_t)0xe15, (q15_t)0x80c7, (q15_t)0xe0f, (q15_t)0x80c7, (q15_t)0xe09, (q15_t)0x80c6, + (q15_t)0xe02, (q15_t)0x80c5, (q15_t)0xdfc, (q15_t)0x80c5, (q15_t)0xdf6, (q15_t)0x80c4, (q15_t)0xdf0, (q15_t)0x80c3, + (q15_t)0xde9, (q15_t)0x80c3, (q15_t)0xde3, (q15_t)0x80c2, (q15_t)0xddd, (q15_t)0x80c1, (q15_t)0xdd7, (q15_t)0x80c1, + (q15_t)0xdd0, (q15_t)0x80c0, (q15_t)0xdca, (q15_t)0x80bf, (q15_t)0xdc4, (q15_t)0x80bf, (q15_t)0xdbe, (q15_t)0x80be, + (q15_t)0xdb7, (q15_t)0x80bd, (q15_t)0xdb1, (q15_t)0x80bd, (q15_t)0xdab, (q15_t)0x80bc, (q15_t)0xda5, (q15_t)0x80bb, + (q15_t)0xd9e, (q15_t)0x80bb, (q15_t)0xd98, (q15_t)0x80ba, (q15_t)0xd92, (q15_t)0x80b9, (q15_t)0xd8c, (q15_t)0x80b9, + (q15_t)0xd85, (q15_t)0x80b8, (q15_t)0xd7f, (q15_t)0x80b7, (q15_t)0xd79, (q15_t)0x80b7, (q15_t)0xd73, (q15_t)0x80b6, + (q15_t)0xd6c, (q15_t)0x80b5, (q15_t)0xd66, (q15_t)0x80b5, (q15_t)0xd60, (q15_t)0x80b4, (q15_t)0xd5a, (q15_t)0x80b3, + (q15_t)0xd53, (q15_t)0x80b3, (q15_t)0xd4d, (q15_t)0x80b2, (q15_t)0xd47, (q15_t)0x80b1, (q15_t)0xd41, (q15_t)0x80b1, + (q15_t)0xd3a, (q15_t)0x80b0, (q15_t)0xd34, (q15_t)0x80af, (q15_t)0xd2e, (q15_t)0x80af, (q15_t)0xd28, (q15_t)0x80ae, + (q15_t)0xd21, (q15_t)0x80ad, (q15_t)0xd1b, (q15_t)0x80ad, (q15_t)0xd15, (q15_t)0x80ac, (q15_t)0xd0f, (q15_t)0x80ab, + (q15_t)0xd08, (q15_t)0x80ab, (q15_t)0xd02, (q15_t)0x80aa, (q15_t)0xcfc, (q15_t)0x80aa, (q15_t)0xcf6, (q15_t)0x80a9, + (q15_t)0xcef, (q15_t)0x80a8, (q15_t)0xce9, (q15_t)0x80a8, (q15_t)0xce3, (q15_t)0x80a7, (q15_t)0xcdd, (q15_t)0x80a6, + (q15_t)0xcd6, (q15_t)0x80a6, (q15_t)0xcd0, (q15_t)0x80a5, (q15_t)0xcca, (q15_t)0x80a5, (q15_t)0xcc4, (q15_t)0x80a4, + (q15_t)0xcbd, (q15_t)0x80a3, (q15_t)0xcb7, (q15_t)0x80a3, (q15_t)0xcb1, (q15_t)0x80a2, (q15_t)0xcab, (q15_t)0x80a1, + (q15_t)0xca4, (q15_t)0x80a1, (q15_t)0xc9e, (q15_t)0x80a0, (q15_t)0xc98, (q15_t)0x80a0, (q15_t)0xc92, (q15_t)0x809f, + (q15_t)0xc8b, (q15_t)0x809e, (q15_t)0xc85, (q15_t)0x809e, (q15_t)0xc7f, (q15_t)0x809d, (q15_t)0xc79, (q15_t)0x809c, + (q15_t)0xc72, (q15_t)0x809c, (q15_t)0xc6c, (q15_t)0x809b, (q15_t)0xc66, (q15_t)0x809b, (q15_t)0xc60, (q15_t)0x809a, + (q15_t)0xc59, (q15_t)0x8099, (q15_t)0xc53, (q15_t)0x8099, (q15_t)0xc4d, (q15_t)0x8098, (q15_t)0xc47, (q15_t)0x8098, + (q15_t)0xc40, (q15_t)0x8097, (q15_t)0xc3a, (q15_t)0x8096, (q15_t)0xc34, (q15_t)0x8096, (q15_t)0xc2e, (q15_t)0x8095, + (q15_t)0xc27, (q15_t)0x8095, (q15_t)0xc21, (q15_t)0x8094, (q15_t)0xc1b, (q15_t)0x8093, (q15_t)0xc14, (q15_t)0x8093, + (q15_t)0xc0e, (q15_t)0x8092, (q15_t)0xc08, (q15_t)0x8092, (q15_t)0xc02, (q15_t)0x8091, (q15_t)0xbfb, (q15_t)0x8090, + (q15_t)0xbf5, (q15_t)0x8090, (q15_t)0xbef, (q15_t)0x808f, (q15_t)0xbe9, (q15_t)0x808f, (q15_t)0xbe2, (q15_t)0x808e, + (q15_t)0xbdc, (q15_t)0x808e, (q15_t)0xbd6, (q15_t)0x808d, (q15_t)0xbd0, (q15_t)0x808c, (q15_t)0xbc9, (q15_t)0x808c, + (q15_t)0xbc3, (q15_t)0x808b, (q15_t)0xbbd, (q15_t)0x808b, (q15_t)0xbb7, (q15_t)0x808a, (q15_t)0xbb0, (q15_t)0x8089, + (q15_t)0xbaa, (q15_t)0x8089, (q15_t)0xba4, (q15_t)0x8088, (q15_t)0xb9e, (q15_t)0x8088, (q15_t)0xb97, (q15_t)0x8087, + (q15_t)0xb91, (q15_t)0x8087, (q15_t)0xb8b, (q15_t)0x8086, (q15_t)0xb85, (q15_t)0x8085, (q15_t)0xb7e, (q15_t)0x8085, + (q15_t)0xb78, (q15_t)0x8084, (q15_t)0xb72, (q15_t)0x8084, (q15_t)0xb6c, (q15_t)0x8083, (q15_t)0xb65, (q15_t)0x8083, + (q15_t)0xb5f, (q15_t)0x8082, (q15_t)0xb59, (q15_t)0x8082, (q15_t)0xb53, (q15_t)0x8081, (q15_t)0xb4c, (q15_t)0x8080, + (q15_t)0xb46, (q15_t)0x8080, (q15_t)0xb40, (q15_t)0x807f, (q15_t)0xb3a, (q15_t)0x807f, (q15_t)0xb33, (q15_t)0x807e, + (q15_t)0xb2d, (q15_t)0x807e, (q15_t)0xb27, (q15_t)0x807d, (q15_t)0xb20, (q15_t)0x807d, (q15_t)0xb1a, (q15_t)0x807c, + (q15_t)0xb14, (q15_t)0x807b, (q15_t)0xb0e, (q15_t)0x807b, (q15_t)0xb07, (q15_t)0x807a, (q15_t)0xb01, (q15_t)0x807a, + (q15_t)0xafb, (q15_t)0x8079, (q15_t)0xaf5, (q15_t)0x8079, (q15_t)0xaee, (q15_t)0x8078, (q15_t)0xae8, (q15_t)0x8078, + (q15_t)0xae2, (q15_t)0x8077, (q15_t)0xadc, (q15_t)0x8077, (q15_t)0xad5, (q15_t)0x8076, (q15_t)0xacf, (q15_t)0x8076, + (q15_t)0xac9, (q15_t)0x8075, (q15_t)0xac3, (q15_t)0x8075, (q15_t)0xabc, (q15_t)0x8074, (q15_t)0xab6, (q15_t)0x8073, + (q15_t)0xab0, (q15_t)0x8073, (q15_t)0xaaa, (q15_t)0x8072, (q15_t)0xaa3, (q15_t)0x8072, (q15_t)0xa9d, (q15_t)0x8071, + (q15_t)0xa97, (q15_t)0x8071, (q15_t)0xa90, (q15_t)0x8070, (q15_t)0xa8a, (q15_t)0x8070, (q15_t)0xa84, (q15_t)0x806f, + (q15_t)0xa7e, (q15_t)0x806f, (q15_t)0xa77, (q15_t)0x806e, (q15_t)0xa71, (q15_t)0x806e, (q15_t)0xa6b, (q15_t)0x806d, + (q15_t)0xa65, (q15_t)0x806d, (q15_t)0xa5e, (q15_t)0x806c, (q15_t)0xa58, (q15_t)0x806c, (q15_t)0xa52, (q15_t)0x806b, + (q15_t)0xa4c, (q15_t)0x806b, (q15_t)0xa45, (q15_t)0x806a, (q15_t)0xa3f, (q15_t)0x806a, (q15_t)0xa39, (q15_t)0x8069, + (q15_t)0xa33, (q15_t)0x8069, (q15_t)0xa2c, (q15_t)0x8068, (q15_t)0xa26, (q15_t)0x8068, (q15_t)0xa20, (q15_t)0x8067, + (q15_t)0xa19, (q15_t)0x8067, (q15_t)0xa13, (q15_t)0x8066, (q15_t)0xa0d, (q15_t)0x8066, (q15_t)0xa07, (q15_t)0x8065, + (q15_t)0xa00, (q15_t)0x8065, (q15_t)0x9fa, (q15_t)0x8064, (q15_t)0x9f4, (q15_t)0x8064, (q15_t)0x9ee, (q15_t)0x8063, + (q15_t)0x9e7, (q15_t)0x8063, (q15_t)0x9e1, (q15_t)0x8062, (q15_t)0x9db, (q15_t)0x8062, (q15_t)0x9d5, (q15_t)0x8061, + (q15_t)0x9ce, (q15_t)0x8061, (q15_t)0x9c8, (q15_t)0x8060, (q15_t)0x9c2, (q15_t)0x8060, (q15_t)0x9bc, (q15_t)0x805f, + (q15_t)0x9b5, (q15_t)0x805f, (q15_t)0x9af, (q15_t)0x805e, (q15_t)0x9a9, (q15_t)0x805e, (q15_t)0x9a2, (q15_t)0x805d, + (q15_t)0x99c, (q15_t)0x805d, (q15_t)0x996, (q15_t)0x805d, (q15_t)0x990, (q15_t)0x805c, (q15_t)0x989, (q15_t)0x805c, + (q15_t)0x983, (q15_t)0x805b, (q15_t)0x97d, (q15_t)0x805b, (q15_t)0x977, (q15_t)0x805a, (q15_t)0x970, (q15_t)0x805a, + (q15_t)0x96a, (q15_t)0x8059, (q15_t)0x964, (q15_t)0x8059, (q15_t)0x95e, (q15_t)0x8058, (q15_t)0x957, (q15_t)0x8058, + (q15_t)0x951, (q15_t)0x8057, (q15_t)0x94b, (q15_t)0x8057, (q15_t)0x944, (q15_t)0x8057, (q15_t)0x93e, (q15_t)0x8056, + (q15_t)0x938, (q15_t)0x8056, (q15_t)0x932, (q15_t)0x8055, (q15_t)0x92b, (q15_t)0x8055, (q15_t)0x925, (q15_t)0x8054, + (q15_t)0x91f, (q15_t)0x8054, (q15_t)0x919, (q15_t)0x8053, (q15_t)0x912, (q15_t)0x8053, (q15_t)0x90c, (q15_t)0x8052, + (q15_t)0x906, (q15_t)0x8052, (q15_t)0x900, (q15_t)0x8052, (q15_t)0x8f9, (q15_t)0x8051, (q15_t)0x8f3, (q15_t)0x8051, + (q15_t)0x8ed, (q15_t)0x8050, (q15_t)0x8e6, (q15_t)0x8050, (q15_t)0x8e0, (q15_t)0x804f, (q15_t)0x8da, (q15_t)0x804f, + (q15_t)0x8d4, (q15_t)0x804f, (q15_t)0x8cd, (q15_t)0x804e, (q15_t)0x8c7, (q15_t)0x804e, (q15_t)0x8c1, (q15_t)0x804d, + (q15_t)0x8bb, (q15_t)0x804d, (q15_t)0x8b4, (q15_t)0x804c, (q15_t)0x8ae, (q15_t)0x804c, (q15_t)0x8a8, (q15_t)0x804c, + (q15_t)0x8a2, (q15_t)0x804b, (q15_t)0x89b, (q15_t)0x804b, (q15_t)0x895, (q15_t)0x804a, (q15_t)0x88f, (q15_t)0x804a, + (q15_t)0x888, (q15_t)0x8049, (q15_t)0x882, (q15_t)0x8049, (q15_t)0x87c, (q15_t)0x8049, (q15_t)0x876, (q15_t)0x8048, + (q15_t)0x86f, (q15_t)0x8048, (q15_t)0x869, (q15_t)0x8047, (q15_t)0x863, (q15_t)0x8047, (q15_t)0x85d, (q15_t)0x8047, + (q15_t)0x856, (q15_t)0x8046, (q15_t)0x850, (q15_t)0x8046, (q15_t)0x84a, (q15_t)0x8045, (q15_t)0x843, (q15_t)0x8045, + (q15_t)0x83d, (q15_t)0x8044, (q15_t)0x837, (q15_t)0x8044, (q15_t)0x831, (q15_t)0x8044, (q15_t)0x82a, (q15_t)0x8043, + (q15_t)0x824, (q15_t)0x8043, (q15_t)0x81e, (q15_t)0x8042, (q15_t)0x818, (q15_t)0x8042, (q15_t)0x811, (q15_t)0x8042, + (q15_t)0x80b, (q15_t)0x8041, (q15_t)0x805, (q15_t)0x8041, (q15_t)0x7fe, (q15_t)0x8040, (q15_t)0x7f8, (q15_t)0x8040, + (q15_t)0x7f2, (q15_t)0x8040, (q15_t)0x7ec, (q15_t)0x803f, (q15_t)0x7e5, (q15_t)0x803f, (q15_t)0x7df, (q15_t)0x803f, + (q15_t)0x7d9, (q15_t)0x803e, (q15_t)0x7d3, (q15_t)0x803e, (q15_t)0x7cc, (q15_t)0x803d, (q15_t)0x7c6, (q15_t)0x803d, + (q15_t)0x7c0, (q15_t)0x803d, (q15_t)0x7ba, (q15_t)0x803c, (q15_t)0x7b3, (q15_t)0x803c, (q15_t)0x7ad, (q15_t)0x803b, + (q15_t)0x7a7, (q15_t)0x803b, (q15_t)0x7a0, (q15_t)0x803b, (q15_t)0x79a, (q15_t)0x803a, (q15_t)0x794, (q15_t)0x803a, + (q15_t)0x78e, (q15_t)0x803a, (q15_t)0x787, (q15_t)0x8039, (q15_t)0x781, (q15_t)0x8039, (q15_t)0x77b, (q15_t)0x8039, + (q15_t)0x775, (q15_t)0x8038, (q15_t)0x76e, (q15_t)0x8038, (q15_t)0x768, (q15_t)0x8037, (q15_t)0x762, (q15_t)0x8037, + (q15_t)0x75b, (q15_t)0x8037, (q15_t)0x755, (q15_t)0x8036, (q15_t)0x74f, (q15_t)0x8036, (q15_t)0x749, (q15_t)0x8036, + (q15_t)0x742, (q15_t)0x8035, (q15_t)0x73c, (q15_t)0x8035, (q15_t)0x736, (q15_t)0x8035, (q15_t)0x730, (q15_t)0x8034, + (q15_t)0x729, (q15_t)0x8034, (q15_t)0x723, (q15_t)0x8033, (q15_t)0x71d, (q15_t)0x8033, (q15_t)0x716, (q15_t)0x8033, + (q15_t)0x710, (q15_t)0x8032, (q15_t)0x70a, (q15_t)0x8032, (q15_t)0x704, (q15_t)0x8032, (q15_t)0x6fd, (q15_t)0x8031, + (q15_t)0x6f7, (q15_t)0x8031, (q15_t)0x6f1, (q15_t)0x8031, (q15_t)0x6ea, (q15_t)0x8030, (q15_t)0x6e4, (q15_t)0x8030, + (q15_t)0x6de, (q15_t)0x8030, (q15_t)0x6d8, (q15_t)0x802f, (q15_t)0x6d1, (q15_t)0x802f, (q15_t)0x6cb, (q15_t)0x802f, + (q15_t)0x6c5, (q15_t)0x802e, (q15_t)0x6bf, (q15_t)0x802e, (q15_t)0x6b8, (q15_t)0x802e, (q15_t)0x6b2, (q15_t)0x802d, + (q15_t)0x6ac, (q15_t)0x802d, (q15_t)0x6a5, (q15_t)0x802d, (q15_t)0x69f, (q15_t)0x802c, (q15_t)0x699, (q15_t)0x802c, + (q15_t)0x693, (q15_t)0x802c, (q15_t)0x68c, (q15_t)0x802b, (q15_t)0x686, (q15_t)0x802b, (q15_t)0x680, (q15_t)0x802b, + (q15_t)0x67a, (q15_t)0x802a, (q15_t)0x673, (q15_t)0x802a, (q15_t)0x66d, (q15_t)0x802a, (q15_t)0x667, (q15_t)0x802a, + (q15_t)0x660, (q15_t)0x8029, (q15_t)0x65a, (q15_t)0x8029, (q15_t)0x654, (q15_t)0x8029, (q15_t)0x64e, (q15_t)0x8028, + (q15_t)0x647, (q15_t)0x8028, (q15_t)0x641, (q15_t)0x8028, (q15_t)0x63b, (q15_t)0x8027, (q15_t)0x635, (q15_t)0x8027, + (q15_t)0x62e, (q15_t)0x8027, (q15_t)0x628, (q15_t)0x8026, (q15_t)0x622, (q15_t)0x8026, (q15_t)0x61b, (q15_t)0x8026, + (q15_t)0x615, (q15_t)0x8026, (q15_t)0x60f, (q15_t)0x8025, (q15_t)0x609, (q15_t)0x8025, (q15_t)0x602, (q15_t)0x8025, + (q15_t)0x5fc, (q15_t)0x8024, (q15_t)0x5f6, (q15_t)0x8024, (q15_t)0x5ef, (q15_t)0x8024, (q15_t)0x5e9, (q15_t)0x8023, + (q15_t)0x5e3, (q15_t)0x8023, (q15_t)0x5dd, (q15_t)0x8023, (q15_t)0x5d6, (q15_t)0x8023, (q15_t)0x5d0, (q15_t)0x8022, + (q15_t)0x5ca, (q15_t)0x8022, (q15_t)0x5c4, (q15_t)0x8022, (q15_t)0x5bd, (q15_t)0x8021, (q15_t)0x5b7, (q15_t)0x8021, + (q15_t)0x5b1, (q15_t)0x8021, (q15_t)0x5aa, (q15_t)0x8021, (q15_t)0x5a4, (q15_t)0x8020, (q15_t)0x59e, (q15_t)0x8020, + (q15_t)0x598, (q15_t)0x8020, (q15_t)0x591, (q15_t)0x8020, (q15_t)0x58b, (q15_t)0x801f, (q15_t)0x585, (q15_t)0x801f, + (q15_t)0x57f, (q15_t)0x801f, (q15_t)0x578, (q15_t)0x801e, (q15_t)0x572, (q15_t)0x801e, (q15_t)0x56c, (q15_t)0x801e, + (q15_t)0x565, (q15_t)0x801e, (q15_t)0x55f, (q15_t)0x801d, (q15_t)0x559, (q15_t)0x801d, (q15_t)0x553, (q15_t)0x801d, + (q15_t)0x54c, (q15_t)0x801d, (q15_t)0x546, (q15_t)0x801c, (q15_t)0x540, (q15_t)0x801c, (q15_t)0x539, (q15_t)0x801c, + (q15_t)0x533, (q15_t)0x801c, (q15_t)0x52d, (q15_t)0x801b, (q15_t)0x527, (q15_t)0x801b, (q15_t)0x520, (q15_t)0x801b, + (q15_t)0x51a, (q15_t)0x801b, (q15_t)0x514, (q15_t)0x801a, (q15_t)0x50d, (q15_t)0x801a, (q15_t)0x507, (q15_t)0x801a, + (q15_t)0x501, (q15_t)0x801a, (q15_t)0x4fb, (q15_t)0x8019, (q15_t)0x4f4, (q15_t)0x8019, (q15_t)0x4ee, (q15_t)0x8019, + (q15_t)0x4e8, (q15_t)0x8019, (q15_t)0x4e2, (q15_t)0x8018, (q15_t)0x4db, (q15_t)0x8018, (q15_t)0x4d5, (q15_t)0x8018, + (q15_t)0x4cf, (q15_t)0x8018, (q15_t)0x4c8, (q15_t)0x8017, (q15_t)0x4c2, (q15_t)0x8017, (q15_t)0x4bc, (q15_t)0x8017, + (q15_t)0x4b6, (q15_t)0x8017, (q15_t)0x4af, (q15_t)0x8016, (q15_t)0x4a9, (q15_t)0x8016, (q15_t)0x4a3, (q15_t)0x8016, + (q15_t)0x49c, (q15_t)0x8016, (q15_t)0x496, (q15_t)0x8016, (q15_t)0x490, (q15_t)0x8015, (q15_t)0x48a, (q15_t)0x8015, + (q15_t)0x483, (q15_t)0x8015, (q15_t)0x47d, (q15_t)0x8015, (q15_t)0x477, (q15_t)0x8014, (q15_t)0x471, (q15_t)0x8014, + (q15_t)0x46a, (q15_t)0x8014, (q15_t)0x464, (q15_t)0x8014, (q15_t)0x45e, (q15_t)0x8014, (q15_t)0x457, (q15_t)0x8013, + (q15_t)0x451, (q15_t)0x8013, (q15_t)0x44b, (q15_t)0x8013, (q15_t)0x445, (q15_t)0x8013, (q15_t)0x43e, (q15_t)0x8013, + (q15_t)0x438, (q15_t)0x8012, (q15_t)0x432, (q15_t)0x8012, (q15_t)0x42b, (q15_t)0x8012, (q15_t)0x425, (q15_t)0x8012, + (q15_t)0x41f, (q15_t)0x8012, (q15_t)0x419, (q15_t)0x8011, (q15_t)0x412, (q15_t)0x8011, (q15_t)0x40c, (q15_t)0x8011, + (q15_t)0x406, (q15_t)0x8011, (q15_t)0x3ff, (q15_t)0x8011, (q15_t)0x3f9, (q15_t)0x8010, (q15_t)0x3f3, (q15_t)0x8010, + (q15_t)0x3ed, (q15_t)0x8010, (q15_t)0x3e6, (q15_t)0x8010, (q15_t)0x3e0, (q15_t)0x8010, (q15_t)0x3da, (q15_t)0x800f, + (q15_t)0x3d4, (q15_t)0x800f, (q15_t)0x3cd, (q15_t)0x800f, (q15_t)0x3c7, (q15_t)0x800f, (q15_t)0x3c1, (q15_t)0x800f, + (q15_t)0x3ba, (q15_t)0x800e, (q15_t)0x3b4, (q15_t)0x800e, (q15_t)0x3ae, (q15_t)0x800e, (q15_t)0x3a8, (q15_t)0x800e, + (q15_t)0x3a1, (q15_t)0x800e, (q15_t)0x39b, (q15_t)0x800e, (q15_t)0x395, (q15_t)0x800d, (q15_t)0x38e, (q15_t)0x800d, + (q15_t)0x388, (q15_t)0x800d, (q15_t)0x382, (q15_t)0x800d, (q15_t)0x37c, (q15_t)0x800d, (q15_t)0x375, (q15_t)0x800c, + (q15_t)0x36f, (q15_t)0x800c, (q15_t)0x369, (q15_t)0x800c, (q15_t)0x362, (q15_t)0x800c, (q15_t)0x35c, (q15_t)0x800c, + (q15_t)0x356, (q15_t)0x800c, (q15_t)0x350, (q15_t)0x800b, (q15_t)0x349, (q15_t)0x800b, (q15_t)0x343, (q15_t)0x800b, + (q15_t)0x33d, (q15_t)0x800b, (q15_t)0x337, (q15_t)0x800b, (q15_t)0x330, (q15_t)0x800b, (q15_t)0x32a, (q15_t)0x800b, + (q15_t)0x324, (q15_t)0x800a, (q15_t)0x31d, (q15_t)0x800a, (q15_t)0x317, (q15_t)0x800a, (q15_t)0x311, (q15_t)0x800a, + (q15_t)0x30b, (q15_t)0x800a, (q15_t)0x304, (q15_t)0x800a, (q15_t)0x2fe, (q15_t)0x8009, (q15_t)0x2f8, (q15_t)0x8009, + (q15_t)0x2f1, (q15_t)0x8009, (q15_t)0x2eb, (q15_t)0x8009, (q15_t)0x2e5, (q15_t)0x8009, (q15_t)0x2df, (q15_t)0x8009, + (q15_t)0x2d8, (q15_t)0x8009, (q15_t)0x2d2, (q15_t)0x8008, (q15_t)0x2cc, (q15_t)0x8008, (q15_t)0x2c5, (q15_t)0x8008, + (q15_t)0x2bf, (q15_t)0x8008, (q15_t)0x2b9, (q15_t)0x8008, (q15_t)0x2b3, (q15_t)0x8008, (q15_t)0x2ac, (q15_t)0x8008, + (q15_t)0x2a6, (q15_t)0x8008, (q15_t)0x2a0, (q15_t)0x8007, (q15_t)0x299, (q15_t)0x8007, (q15_t)0x293, (q15_t)0x8007, + (q15_t)0x28d, (q15_t)0x8007, (q15_t)0x287, (q15_t)0x8007, (q15_t)0x280, (q15_t)0x8007, (q15_t)0x27a, (q15_t)0x8007, + (q15_t)0x274, (q15_t)0x8007, (q15_t)0x26d, (q15_t)0x8006, (q15_t)0x267, (q15_t)0x8006, (q15_t)0x261, (q15_t)0x8006, + (q15_t)0x25b, (q15_t)0x8006, (q15_t)0x254, (q15_t)0x8006, (q15_t)0x24e, (q15_t)0x8006, (q15_t)0x248, (q15_t)0x8006, + (q15_t)0x242, (q15_t)0x8006, (q15_t)0x23b, (q15_t)0x8005, (q15_t)0x235, (q15_t)0x8005, (q15_t)0x22f, (q15_t)0x8005, + (q15_t)0x228, (q15_t)0x8005, (q15_t)0x222, (q15_t)0x8005, (q15_t)0x21c, (q15_t)0x8005, (q15_t)0x216, (q15_t)0x8005, + (q15_t)0x20f, (q15_t)0x8005, (q15_t)0x209, (q15_t)0x8005, (q15_t)0x203, (q15_t)0x8005, (q15_t)0x1fc, (q15_t)0x8004, + (q15_t)0x1f6, (q15_t)0x8004, (q15_t)0x1f0, (q15_t)0x8004, (q15_t)0x1ea, (q15_t)0x8004, (q15_t)0x1e3, (q15_t)0x8004, + (q15_t)0x1dd, (q15_t)0x8004, (q15_t)0x1d7, (q15_t)0x8004, (q15_t)0x1d0, (q15_t)0x8004, (q15_t)0x1ca, (q15_t)0x8004, + (q15_t)0x1c4, (q15_t)0x8004, (q15_t)0x1be, (q15_t)0x8004, (q15_t)0x1b7, (q15_t)0x8003, (q15_t)0x1b1, (q15_t)0x8003, + (q15_t)0x1ab, (q15_t)0x8003, (q15_t)0x1a4, (q15_t)0x8003, (q15_t)0x19e, (q15_t)0x8003, (q15_t)0x198, (q15_t)0x8003, + (q15_t)0x192, (q15_t)0x8003, (q15_t)0x18b, (q15_t)0x8003, (q15_t)0x185, (q15_t)0x8003, (q15_t)0x17f, (q15_t)0x8003, + (q15_t)0x178, (q15_t)0x8003, (q15_t)0x172, (q15_t)0x8003, (q15_t)0x16c, (q15_t)0x8003, (q15_t)0x166, (q15_t)0x8002, + (q15_t)0x15f, (q15_t)0x8002, (q15_t)0x159, (q15_t)0x8002, (q15_t)0x153, (q15_t)0x8002, (q15_t)0x14d, (q15_t)0x8002, + (q15_t)0x146, (q15_t)0x8002, (q15_t)0x140, (q15_t)0x8002, (q15_t)0x13a, (q15_t)0x8002, (q15_t)0x133, (q15_t)0x8002, + (q15_t)0x12d, (q15_t)0x8002, (q15_t)0x127, (q15_t)0x8002, (q15_t)0x121, (q15_t)0x8002, (q15_t)0x11a, (q15_t)0x8002, + (q15_t)0x114, (q15_t)0x8002, (q15_t)0x10e, (q15_t)0x8002, (q15_t)0x107, (q15_t)0x8002, (q15_t)0x101, (q15_t)0x8002, + (q15_t)0xfb, (q15_t)0x8001, (q15_t)0xf5, (q15_t)0x8001, (q15_t)0xee, (q15_t)0x8001, (q15_t)0xe8, (q15_t)0x8001, + (q15_t)0xe2, (q15_t)0x8001, (q15_t)0xdb, (q15_t)0x8001, (q15_t)0xd5, (q15_t)0x8001, (q15_t)0xcf, (q15_t)0x8001, + (q15_t)0xc9, (q15_t)0x8001, (q15_t)0xc2, (q15_t)0x8001, (q15_t)0xbc, (q15_t)0x8001, (q15_t)0xb6, (q15_t)0x8001, + (q15_t)0xaf, (q15_t)0x8001, (q15_t)0xa9, (q15_t)0x8001, (q15_t)0xa3, (q15_t)0x8001, (q15_t)0x9d, (q15_t)0x8001, + (q15_t)0x96, (q15_t)0x8001, (q15_t)0x90, (q15_t)0x8001, (q15_t)0x8a, (q15_t)0x8001, (q15_t)0x83, (q15_t)0x8001, + (q15_t)0x7d, (q15_t)0x8001, (q15_t)0x77, (q15_t)0x8001, (q15_t)0x71, (q15_t)0x8001, (q15_t)0x6a, (q15_t)0x8001, + (q15_t)0x64, (q15_t)0x8001, (q15_t)0x5e, (q15_t)0x8001, (q15_t)0x57, (q15_t)0x8001, (q15_t)0x51, (q15_t)0x8001, + (q15_t)0x4b, (q15_t)0x8001, (q15_t)0x45, (q15_t)0x8001, (q15_t)0x3e, (q15_t)0x8001, (q15_t)0x38, (q15_t)0x8001, + (q15_t)0x32, (q15_t)0x8001, (q15_t)0x2b, (q15_t)0x8001, (q15_t)0x25, (q15_t)0x8001, (q15_t)0x1f, (q15_t)0x8001, + (q15_t)0x19, (q15_t)0x8001, (q15_t)0x12, (q15_t)0x8001, (q15_t)0xc, (q15_t)0x8001, (q15_t)0x6, (q15_t)0x8001 +}; + + +/** + @par + cosFactor tables are generated using the formula :
 cos_factors[n] = 2 * cos((2n+1)*pi/(4*N)) 
+ @par + C command to generate the table +
+  for (i = 0; i< N; i++)
+  {
+    cos_factors[i] = 2 * cos((2*i+1)*c/2);
+  } 
+ @par + where N is the number of factors to generate and c is pi/(2*N) + @par + Then converted to q15 format by multiplying with 2^31 and saturated if required. +*/ + +static const q15_t __ALIGNED(4) cos_factorsQ15_128[128] = { + (q15_t)0x7fff, (q15_t)0x7ffa, (q15_t)0x7ff0, (q15_t)0x7fe1, (q15_t)0x7fce, (q15_t)0x7fb5, (q15_t)0x7f97, (q15_t)0x7f75, + (q15_t)0x7f4d, (q15_t)0x7f21, (q15_t)0x7ef0, (q15_t)0x7eba, (q15_t)0x7e7f, (q15_t)0x7e3f, (q15_t)0x7dfa, (q15_t)0x7db0, + (q15_t)0x7d62, (q15_t)0x7d0f, (q15_t)0x7cb7, (q15_t)0x7c5a, (q15_t)0x7bf8, (q15_t)0x7b92, (q15_t)0x7b26, (q15_t)0x7ab6, + (q15_t)0x7a42, (q15_t)0x79c8, (q15_t)0x794a, (q15_t)0x78c7, (q15_t)0x7840, (q15_t)0x77b4, (q15_t)0x7723, (q15_t)0x768e, + (q15_t)0x75f4, (q15_t)0x7555, (q15_t)0x74b2, (q15_t)0x740b, (q15_t)0x735f, (q15_t)0x72af, (q15_t)0x71fa, (q15_t)0x7141, + (q15_t)0x7083, (q15_t)0x6fc1, (q15_t)0x6efb, (q15_t)0x6e30, (q15_t)0x6d62, (q15_t)0x6c8f, (q15_t)0x6bb8, (q15_t)0x6adc, + (q15_t)0x69fd, (q15_t)0x6919, (q15_t)0x6832, (q15_t)0x6746, (q15_t)0x6657, (q15_t)0x6563, (q15_t)0x646c, (q15_t)0x6371, + (q15_t)0x6271, (q15_t)0x616f, (q15_t)0x6068, (q15_t)0x5f5e, (q15_t)0x5e50, (q15_t)0x5d3e, (q15_t)0x5c29, (q15_t)0x5b10, + (q15_t)0x59f3, (q15_t)0x58d4, (q15_t)0x57b0, (q15_t)0x568a, (q15_t)0x5560, (q15_t)0x5433, (q15_t)0x5302, (q15_t)0x51ce, + (q15_t)0x5097, (q15_t)0x4f5e, (q15_t)0x4e21, (q15_t)0x4ce1, (q15_t)0x4b9e, (q15_t)0x4a58, (q15_t)0x490f, (q15_t)0x47c3, + (q15_t)0x4675, (q15_t)0x4524, (q15_t)0x43d0, (q15_t)0x427a, (q15_t)0x4121, (q15_t)0x3fc5, (q15_t)0x3e68, (q15_t)0x3d07, + (q15_t)0x3ba5, (q15_t)0x3a40, (q15_t)0x38d8, (q15_t)0x376f, (q15_t)0x3604, (q15_t)0x3496, (q15_t)0x3326, (q15_t)0x31b5, + (q15_t)0x3041, (q15_t)0x2ecc, (q15_t)0x2d55, (q15_t)0x2bdc, (q15_t)0x2a61, (q15_t)0x28e5, (q15_t)0x2767, (q15_t)0x25e8, + (q15_t)0x2467, (q15_t)0x22e5, (q15_t)0x2161, (q15_t)0x1fdc, (q15_t)0x1e56, (q15_t)0x1ccf, (q15_t)0x1b47, (q15_t)0x19bd, + (q15_t)0x1833, (q15_t)0x16a8, (q15_t)0x151b, (q15_t)0x138e, (q15_t)0x1201, (q15_t)0x1072, (q15_t)0xee3, (q15_t)0xd53, + (q15_t)0xbc3, (q15_t)0xa33, (q15_t)0x8a2, (q15_t)0x710, (q15_t)0x57f, (q15_t)0x3ed, (q15_t)0x25b, (q15_t)0xc9 +}; + +static const q15_t __ALIGNED(4) cos_factorsQ15_512[512] = { + (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7ffe, (q15_t)0x7ffc, (q15_t)0x7ffb, (q15_t)0x7ff9, (q15_t)0x7ff7, + (q15_t)0x7ff4, (q15_t)0x7ff2, (q15_t)0x7fee, (q15_t)0x7feb, (q15_t)0x7fe7, (q15_t)0x7fe3, (q15_t)0x7fdf, (q15_t)0x7fda, + (q15_t)0x7fd6, (q15_t)0x7fd0, (q15_t)0x7fcb, (q15_t)0x7fc5, (q15_t)0x7fbf, (q15_t)0x7fb8, (q15_t)0x7fb1, (q15_t)0x7faa, + (q15_t)0x7fa3, (q15_t)0x7f9b, (q15_t)0x7f93, (q15_t)0x7f8b, (q15_t)0x7f82, (q15_t)0x7f79, (q15_t)0x7f70, (q15_t)0x7f67, + (q15_t)0x7f5d, (q15_t)0x7f53, (q15_t)0x7f48, (q15_t)0x7f3d, (q15_t)0x7f32, (q15_t)0x7f27, (q15_t)0x7f1b, (q15_t)0x7f0f, + (q15_t)0x7f03, (q15_t)0x7ef6, (q15_t)0x7ee9, (q15_t)0x7edc, (q15_t)0x7ecf, (q15_t)0x7ec1, (q15_t)0x7eb3, (q15_t)0x7ea4, + (q15_t)0x7e95, (q15_t)0x7e86, (q15_t)0x7e77, (q15_t)0x7e67, (q15_t)0x7e57, (q15_t)0x7e47, (q15_t)0x7e37, (q15_t)0x7e26, + (q15_t)0x7e14, (q15_t)0x7e03, (q15_t)0x7df1, (q15_t)0x7ddf, (q15_t)0x7dcd, (q15_t)0x7dba, (q15_t)0x7da7, (q15_t)0x7d94, + (q15_t)0x7d80, (q15_t)0x7d6c, (q15_t)0x7d58, (q15_t)0x7d43, (q15_t)0x7d2f, (q15_t)0x7d19, (q15_t)0x7d04, (q15_t)0x7cee, + (q15_t)0x7cd8, (q15_t)0x7cc2, (q15_t)0x7cab, (q15_t)0x7c94, (q15_t)0x7c7d, (q15_t)0x7c66, (q15_t)0x7c4e, (q15_t)0x7c36, + (q15_t)0x7c1d, (q15_t)0x7c05, (q15_t)0x7beb, (q15_t)0x7bd2, (q15_t)0x7bb9, (q15_t)0x7b9f, (q15_t)0x7b84, (q15_t)0x7b6a, + (q15_t)0x7b4f, (q15_t)0x7b34, (q15_t)0x7b19, (q15_t)0x7afd, (q15_t)0x7ae1, (q15_t)0x7ac5, (q15_t)0x7aa8, (q15_t)0x7a8b, + (q15_t)0x7a6e, (q15_t)0x7a50, (q15_t)0x7a33, (q15_t)0x7a15, (q15_t)0x79f6, (q15_t)0x79d8, (q15_t)0x79b9, (q15_t)0x7999, + (q15_t)0x797a, (q15_t)0x795a, (q15_t)0x793a, (q15_t)0x7919, (q15_t)0x78f9, (q15_t)0x78d8, (q15_t)0x78b6, (q15_t)0x7895, + (q15_t)0x7873, (q15_t)0x7851, (q15_t)0x782e, (q15_t)0x780c, (q15_t)0x77e9, (q15_t)0x77c5, (q15_t)0x77a2, (q15_t)0x777e, + (q15_t)0x775a, (q15_t)0x7735, (q15_t)0x7710, (q15_t)0x76eb, (q15_t)0x76c6, (q15_t)0x76a0, (q15_t)0x767b, (q15_t)0x7654, + (q15_t)0x762e, (q15_t)0x7607, (q15_t)0x75e0, (q15_t)0x75b9, (q15_t)0x7591, (q15_t)0x7569, (q15_t)0x7541, (q15_t)0x7519, + (q15_t)0x74f0, (q15_t)0x74c7, (q15_t)0x749e, (q15_t)0x7474, (q15_t)0x744a, (q15_t)0x7420, (q15_t)0x73f6, (q15_t)0x73cb, + (q15_t)0x73a0, (q15_t)0x7375, (q15_t)0x7349, (q15_t)0x731d, (q15_t)0x72f1, (q15_t)0x72c5, (q15_t)0x7298, (q15_t)0x726b, + (q15_t)0x723e, (q15_t)0x7211, (q15_t)0x71e3, (q15_t)0x71b5, (q15_t)0x7186, (q15_t)0x7158, (q15_t)0x7129, (q15_t)0x70fa, + (q15_t)0x70cb, (q15_t)0x709b, (q15_t)0x706b, (q15_t)0x703b, (q15_t)0x700a, (q15_t)0x6fda, (q15_t)0x6fa9, (q15_t)0x6f77, + (q15_t)0x6f46, (q15_t)0x6f14, (q15_t)0x6ee2, (q15_t)0x6eaf, (q15_t)0x6e7d, (q15_t)0x6e4a, (q15_t)0x6e17, (q15_t)0x6de3, + (q15_t)0x6db0, (q15_t)0x6d7c, (q15_t)0x6d48, (q15_t)0x6d13, (q15_t)0x6cde, (q15_t)0x6ca9, (q15_t)0x6c74, (q15_t)0x6c3f, + (q15_t)0x6c09, (q15_t)0x6bd3, (q15_t)0x6b9c, (q15_t)0x6b66, (q15_t)0x6b2f, (q15_t)0x6af8, (q15_t)0x6ac1, (q15_t)0x6a89, + (q15_t)0x6a51, (q15_t)0x6a19, (q15_t)0x69e1, (q15_t)0x69a8, (q15_t)0x696f, (q15_t)0x6936, (q15_t)0x68fd, (q15_t)0x68c3, + (q15_t)0x6889, (q15_t)0x684f, (q15_t)0x6815, (q15_t)0x67da, (q15_t)0x679f, (q15_t)0x6764, (q15_t)0x6729, (q15_t)0x66ed, + (q15_t)0x66b1, (q15_t)0x6675, (q15_t)0x6639, (q15_t)0x65fc, (q15_t)0x65bf, (q15_t)0x6582, (q15_t)0x6545, (q15_t)0x6507, + (q15_t)0x64c9, (q15_t)0x648b, (q15_t)0x644d, (q15_t)0x640e, (q15_t)0x63cf, (q15_t)0x6390, (q15_t)0x6351, (q15_t)0x6311, + (q15_t)0x62d2, (q15_t)0x6292, (q15_t)0x6251, (q15_t)0x6211, (q15_t)0x61d0, (q15_t)0x618f, (q15_t)0x614e, (q15_t)0x610d, + (q15_t)0x60cb, (q15_t)0x6089, (q15_t)0x6047, (q15_t)0x6004, (q15_t)0x5fc2, (q15_t)0x5f7f, (q15_t)0x5f3c, (q15_t)0x5ef9, + (q15_t)0x5eb5, (q15_t)0x5e71, (q15_t)0x5e2d, (q15_t)0x5de9, (q15_t)0x5da5, (q15_t)0x5d60, (q15_t)0x5d1b, (q15_t)0x5cd6, + (q15_t)0x5c91, (q15_t)0x5c4b, (q15_t)0x5c06, (q15_t)0x5bc0, (q15_t)0x5b79, (q15_t)0x5b33, (q15_t)0x5aec, (q15_t)0x5aa5, + (q15_t)0x5a5e, (q15_t)0x5a17, (q15_t)0x59d0, (q15_t)0x5988, (q15_t)0x5940, (q15_t)0x58f8, (q15_t)0x58af, (q15_t)0x5867, + (q15_t)0x581e, (q15_t)0x57d5, (q15_t)0x578c, (q15_t)0x5742, (q15_t)0x56f9, (q15_t)0x56af, (q15_t)0x5665, (q15_t)0x561a, + (q15_t)0x55d0, (q15_t)0x5585, (q15_t)0x553a, (q15_t)0x54ef, (q15_t)0x54a4, (q15_t)0x5458, (q15_t)0x540d, (q15_t)0x53c1, + (q15_t)0x5375, (q15_t)0x5328, (q15_t)0x52dc, (q15_t)0x528f, (q15_t)0x5242, (q15_t)0x51f5, (q15_t)0x51a8, (q15_t)0x515a, + (q15_t)0x510c, (q15_t)0x50bf, (q15_t)0x5070, (q15_t)0x5022, (q15_t)0x4fd4, (q15_t)0x4f85, (q15_t)0x4f36, (q15_t)0x4ee7, + (q15_t)0x4e98, (q15_t)0x4e48, (q15_t)0x4df9, (q15_t)0x4da9, (q15_t)0x4d59, (q15_t)0x4d09, (q15_t)0x4cb8, (q15_t)0x4c68, + (q15_t)0x4c17, (q15_t)0x4bc6, (q15_t)0x4b75, (q15_t)0x4b24, (q15_t)0x4ad2, (q15_t)0x4a81, (q15_t)0x4a2f, (q15_t)0x49dd, + (q15_t)0x498a, (q15_t)0x4938, (q15_t)0x48e6, (q15_t)0x4893, (q15_t)0x4840, (q15_t)0x47ed, (q15_t)0x479a, (q15_t)0x4746, + (q15_t)0x46f3, (q15_t)0x469f, (q15_t)0x464b, (q15_t)0x45f7, (q15_t)0x45a3, (q15_t)0x454e, (q15_t)0x44fa, (q15_t)0x44a5, + (q15_t)0x4450, (q15_t)0x43fb, (q15_t)0x43a5, (q15_t)0x4350, (q15_t)0x42fa, (q15_t)0x42a5, (q15_t)0x424f, (q15_t)0x41f9, + (q15_t)0x41a2, (q15_t)0x414c, (q15_t)0x40f6, (q15_t)0x409f, (q15_t)0x4048, (q15_t)0x3ff1, (q15_t)0x3f9a, (q15_t)0x3f43, + (q15_t)0x3eeb, (q15_t)0x3e93, (q15_t)0x3e3c, (q15_t)0x3de4, (q15_t)0x3d8c, (q15_t)0x3d33, (q15_t)0x3cdb, (q15_t)0x3c83, + (q15_t)0x3c2a, (q15_t)0x3bd1, (q15_t)0x3b78, (q15_t)0x3b1f, (q15_t)0x3ac6, (q15_t)0x3a6c, (q15_t)0x3a13, (q15_t)0x39b9, + (q15_t)0x395f, (q15_t)0x3906, (q15_t)0x38ab, (q15_t)0x3851, (q15_t)0x37f7, (q15_t)0x379c, (q15_t)0x3742, (q15_t)0x36e7, + (q15_t)0x368c, (q15_t)0x3631, (q15_t)0x35d6, (q15_t)0x357b, (q15_t)0x351f, (q15_t)0x34c4, (q15_t)0x3468, (q15_t)0x340c, + (q15_t)0x33b0, (q15_t)0x3354, (q15_t)0x32f8, (q15_t)0x329c, (q15_t)0x3240, (q15_t)0x31e3, (q15_t)0x3186, (q15_t)0x312a, + (q15_t)0x30cd, (q15_t)0x3070, (q15_t)0x3013, (q15_t)0x2fb5, (q15_t)0x2f58, (q15_t)0x2efb, (q15_t)0x2e9d, (q15_t)0x2e3f, + (q15_t)0x2de2, (q15_t)0x2d84, (q15_t)0x2d26, (q15_t)0x2cc8, (q15_t)0x2c69, (q15_t)0x2c0b, (q15_t)0x2bad, (q15_t)0x2b4e, + (q15_t)0x2aef, (q15_t)0x2a91, (q15_t)0x2a32, (q15_t)0x29d3, (q15_t)0x2974, (q15_t)0x2915, (q15_t)0x28b5, (q15_t)0x2856, + (q15_t)0x27f6, (q15_t)0x2797, (q15_t)0x2737, (q15_t)0x26d8, (q15_t)0x2678, (q15_t)0x2618, (q15_t)0x25b8, (q15_t)0x2558, + (q15_t)0x24f7, (q15_t)0x2497, (q15_t)0x2437, (q15_t)0x23d6, (q15_t)0x2376, (q15_t)0x2315, (q15_t)0x22b4, (q15_t)0x2254, + (q15_t)0x21f3, (q15_t)0x2192, (q15_t)0x2131, (q15_t)0x20d0, (q15_t)0x206e, (q15_t)0x200d, (q15_t)0x1fac, (q15_t)0x1f4a, + (q15_t)0x1ee9, (q15_t)0x1e87, (q15_t)0x1e25, (q15_t)0x1dc4, (q15_t)0x1d62, (q15_t)0x1d00, (q15_t)0x1c9e, (q15_t)0x1c3c, + (q15_t)0x1bda, (q15_t)0x1b78, (q15_t)0x1b16, (q15_t)0x1ab3, (q15_t)0x1a51, (q15_t)0x19ef, (q15_t)0x198c, (q15_t)0x192a, + (q15_t)0x18c7, (q15_t)0x1864, (q15_t)0x1802, (q15_t)0x179f, (q15_t)0x173c, (q15_t)0x16d9, (q15_t)0x1676, (q15_t)0x1613, + (q15_t)0x15b0, (q15_t)0x154d, (q15_t)0x14ea, (q15_t)0x1487, (q15_t)0x1423, (q15_t)0x13c0, (q15_t)0x135d, (q15_t)0x12f9, + (q15_t)0x1296, (q15_t)0x1232, (q15_t)0x11cf, (q15_t)0x116b, (q15_t)0x1108, (q15_t)0x10a4, (q15_t)0x1040, (q15_t)0xfdd, + (q15_t)0xf79, (q15_t)0xf15, (q15_t)0xeb1, (q15_t)0xe4d, (q15_t)0xde9, (q15_t)0xd85, (q15_t)0xd21, (q15_t)0xcbd, + (q15_t)0xc59, (q15_t)0xbf5, (q15_t)0xb91, (q15_t)0xb2d, (q15_t)0xac9, (q15_t)0xa65, (q15_t)0xa00, (q15_t)0x99c, + (q15_t)0x938, (q15_t)0x8d4, (q15_t)0x86f, (q15_t)0x80b, (q15_t)0x7a7, (q15_t)0x742, (q15_t)0x6de, (q15_t)0x67a, + (q15_t)0x615, (q15_t)0x5b1, (q15_t)0x54c, (q15_t)0x4e8, (q15_t)0x483, (q15_t)0x41f, (q15_t)0x3ba, (q15_t)0x356, + (q15_t)0x2f1, (q15_t)0x28d, (q15_t)0x228, (q15_t)0x1c4, (q15_t)0x15f, (q15_t)0xfb, (q15_t)0x96, (q15_t)0x32 +}; + +static const q15_t __ALIGNED(4) cos_factorsQ15_2048[2048] = { + (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, + (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffd, (q15_t)0x7ffd, + (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffc, (q15_t)0x7ffc, (q15_t)0x7ffb, (q15_t)0x7ffb, (q15_t)0x7ffb, (q15_t)0x7ffa, + (q15_t)0x7ffa, (q15_t)0x7ff9, (q15_t)0x7ff9, (q15_t)0x7ff8, (q15_t)0x7ff8, (q15_t)0x7ff7, (q15_t)0x7ff7, (q15_t)0x7ff6, + (q15_t)0x7ff5, (q15_t)0x7ff5, (q15_t)0x7ff4, (q15_t)0x7ff3, (q15_t)0x7ff3, (q15_t)0x7ff2, (q15_t)0x7ff1, (q15_t)0x7ff0, + (q15_t)0x7ff0, (q15_t)0x7fef, (q15_t)0x7fee, (q15_t)0x7fed, (q15_t)0x7fec, (q15_t)0x7fec, (q15_t)0x7feb, (q15_t)0x7fea, + (q15_t)0x7fe9, (q15_t)0x7fe8, (q15_t)0x7fe7, (q15_t)0x7fe6, (q15_t)0x7fe5, (q15_t)0x7fe4, (q15_t)0x7fe3, (q15_t)0x7fe2, + (q15_t)0x7fe1, (q15_t)0x7fe0, (q15_t)0x7fdf, (q15_t)0x7fdd, (q15_t)0x7fdc, (q15_t)0x7fdb, (q15_t)0x7fda, (q15_t)0x7fd9, + (q15_t)0x7fd7, (q15_t)0x7fd6, (q15_t)0x7fd5, (q15_t)0x7fd4, (q15_t)0x7fd2, (q15_t)0x7fd1, (q15_t)0x7fd0, (q15_t)0x7fce, + (q15_t)0x7fcd, (q15_t)0x7fcb, (q15_t)0x7fca, (q15_t)0x7fc9, (q15_t)0x7fc7, (q15_t)0x7fc6, (q15_t)0x7fc4, (q15_t)0x7fc3, + (q15_t)0x7fc1, (q15_t)0x7fc0, (q15_t)0x7fbe, (q15_t)0x7fbc, (q15_t)0x7fbb, (q15_t)0x7fb9, (q15_t)0x7fb7, (q15_t)0x7fb6, + (q15_t)0x7fb4, (q15_t)0x7fb2, (q15_t)0x7fb1, (q15_t)0x7faf, (q15_t)0x7fad, (q15_t)0x7fab, (q15_t)0x7fa9, (q15_t)0x7fa8, + (q15_t)0x7fa6, (q15_t)0x7fa4, (q15_t)0x7fa2, (q15_t)0x7fa0, (q15_t)0x7f9e, (q15_t)0x7f9c, (q15_t)0x7f9a, (q15_t)0x7f98, + (q15_t)0x7f96, (q15_t)0x7f94, (q15_t)0x7f92, (q15_t)0x7f90, (q15_t)0x7f8e, (q15_t)0x7f8c, (q15_t)0x7f8a, (q15_t)0x7f88, + (q15_t)0x7f86, (q15_t)0x7f83, (q15_t)0x7f81, (q15_t)0x7f7f, (q15_t)0x7f7d, (q15_t)0x7f7b, (q15_t)0x7f78, (q15_t)0x7f76, + (q15_t)0x7f74, (q15_t)0x7f71, (q15_t)0x7f6f, (q15_t)0x7f6d, (q15_t)0x7f6a, (q15_t)0x7f68, (q15_t)0x7f65, (q15_t)0x7f63, + (q15_t)0x7f60, (q15_t)0x7f5e, (q15_t)0x7f5b, (q15_t)0x7f59, (q15_t)0x7f56, (q15_t)0x7f54, (q15_t)0x7f51, (q15_t)0x7f4f, + (q15_t)0x7f4c, (q15_t)0x7f49, (q15_t)0x7f47, (q15_t)0x7f44, (q15_t)0x7f41, (q15_t)0x7f3f, (q15_t)0x7f3c, (q15_t)0x7f39, + (q15_t)0x7f36, (q15_t)0x7f34, (q15_t)0x7f31, (q15_t)0x7f2e, (q15_t)0x7f2b, (q15_t)0x7f28, (q15_t)0x7f25, (q15_t)0x7f23, + (q15_t)0x7f20, (q15_t)0x7f1d, (q15_t)0x7f1a, (q15_t)0x7f17, (q15_t)0x7f14, (q15_t)0x7f11, (q15_t)0x7f0e, (q15_t)0x7f0b, + (q15_t)0x7f08, (q15_t)0x7f04, (q15_t)0x7f01, (q15_t)0x7efe, (q15_t)0x7efb, (q15_t)0x7ef8, (q15_t)0x7ef5, (q15_t)0x7ef1, + (q15_t)0x7eee, (q15_t)0x7eeb, (q15_t)0x7ee8, (q15_t)0x7ee4, (q15_t)0x7ee1, (q15_t)0x7ede, (q15_t)0x7eda, (q15_t)0x7ed7, + (q15_t)0x7ed4, (q15_t)0x7ed0, (q15_t)0x7ecd, (q15_t)0x7ec9, (q15_t)0x7ec6, (q15_t)0x7ec3, (q15_t)0x7ebf, (q15_t)0x7ebb, + (q15_t)0x7eb8, (q15_t)0x7eb4, (q15_t)0x7eb1, (q15_t)0x7ead, (q15_t)0x7eaa, (q15_t)0x7ea6, (q15_t)0x7ea2, (q15_t)0x7e9f, + (q15_t)0x7e9b, (q15_t)0x7e97, (q15_t)0x7e94, (q15_t)0x7e90, (q15_t)0x7e8c, (q15_t)0x7e88, (q15_t)0x7e84, (q15_t)0x7e81, + (q15_t)0x7e7d, (q15_t)0x7e79, (q15_t)0x7e75, (q15_t)0x7e71, (q15_t)0x7e6d, (q15_t)0x7e69, (q15_t)0x7e65, (q15_t)0x7e61, + (q15_t)0x7e5d, (q15_t)0x7e59, (q15_t)0x7e55, (q15_t)0x7e51, (q15_t)0x7e4d, (q15_t)0x7e49, (q15_t)0x7e45, (q15_t)0x7e41, + (q15_t)0x7e3d, (q15_t)0x7e39, (q15_t)0x7e34, (q15_t)0x7e30, (q15_t)0x7e2c, (q15_t)0x7e28, (q15_t)0x7e24, (q15_t)0x7e1f, + (q15_t)0x7e1b, (q15_t)0x7e17, (q15_t)0x7e12, (q15_t)0x7e0e, (q15_t)0x7e0a, (q15_t)0x7e05, (q15_t)0x7e01, (q15_t)0x7dfc, + (q15_t)0x7df8, (q15_t)0x7df3, (q15_t)0x7def, (q15_t)0x7dea, (q15_t)0x7de6, (q15_t)0x7de1, (q15_t)0x7ddd, (q15_t)0x7dd8, + (q15_t)0x7dd4, (q15_t)0x7dcf, (q15_t)0x7dca, (q15_t)0x7dc6, (q15_t)0x7dc1, (q15_t)0x7dbc, (q15_t)0x7db8, (q15_t)0x7db3, + (q15_t)0x7dae, (q15_t)0x7da9, (q15_t)0x7da5, (q15_t)0x7da0, (q15_t)0x7d9b, (q15_t)0x7d96, (q15_t)0x7d91, (q15_t)0x7d8c, + (q15_t)0x7d87, (q15_t)0x7d82, (q15_t)0x7d7e, (q15_t)0x7d79, (q15_t)0x7d74, (q15_t)0x7d6f, (q15_t)0x7d6a, (q15_t)0x7d65, + (q15_t)0x7d60, (q15_t)0x7d5a, (q15_t)0x7d55, (q15_t)0x7d50, (q15_t)0x7d4b, (q15_t)0x7d46, (q15_t)0x7d41, (q15_t)0x7d3c, + (q15_t)0x7d36, (q15_t)0x7d31, (q15_t)0x7d2c, (q15_t)0x7d27, (q15_t)0x7d21, (q15_t)0x7d1c, (q15_t)0x7d17, (q15_t)0x7d11, + (q15_t)0x7d0c, (q15_t)0x7d07, (q15_t)0x7d01, (q15_t)0x7cfc, (q15_t)0x7cf6, (q15_t)0x7cf1, (q15_t)0x7cec, (q15_t)0x7ce6, + (q15_t)0x7ce1, (q15_t)0x7cdb, (q15_t)0x7cd5, (q15_t)0x7cd0, (q15_t)0x7cca, (q15_t)0x7cc5, (q15_t)0x7cbf, (q15_t)0x7cb9, + (q15_t)0x7cb4, (q15_t)0x7cae, (q15_t)0x7ca8, (q15_t)0x7ca3, (q15_t)0x7c9d, (q15_t)0x7c97, (q15_t)0x7c91, (q15_t)0x7c8c, + (q15_t)0x7c86, (q15_t)0x7c80, (q15_t)0x7c7a, (q15_t)0x7c74, (q15_t)0x7c6e, (q15_t)0x7c69, (q15_t)0x7c63, (q15_t)0x7c5d, + (q15_t)0x7c57, (q15_t)0x7c51, (q15_t)0x7c4b, (q15_t)0x7c45, (q15_t)0x7c3f, (q15_t)0x7c39, (q15_t)0x7c33, (q15_t)0x7c2d, + (q15_t)0x7c26, (q15_t)0x7c20, (q15_t)0x7c1a, (q15_t)0x7c14, (q15_t)0x7c0e, (q15_t)0x7c08, (q15_t)0x7c01, (q15_t)0x7bfb, + (q15_t)0x7bf5, (q15_t)0x7bef, (q15_t)0x7be8, (q15_t)0x7be2, (q15_t)0x7bdc, (q15_t)0x7bd5, (q15_t)0x7bcf, (q15_t)0x7bc9, + (q15_t)0x7bc2, (q15_t)0x7bbc, (q15_t)0x7bb5, (q15_t)0x7baf, (q15_t)0x7ba8, (q15_t)0x7ba2, (q15_t)0x7b9b, (q15_t)0x7b95, + (q15_t)0x7b8e, (q15_t)0x7b88, (q15_t)0x7b81, (q15_t)0x7b7a, (q15_t)0x7b74, (q15_t)0x7b6d, (q15_t)0x7b67, (q15_t)0x7b60, + (q15_t)0x7b59, (q15_t)0x7b52, (q15_t)0x7b4c, (q15_t)0x7b45, (q15_t)0x7b3e, (q15_t)0x7b37, (q15_t)0x7b31, (q15_t)0x7b2a, + (q15_t)0x7b23, (q15_t)0x7b1c, (q15_t)0x7b15, (q15_t)0x7b0e, (q15_t)0x7b07, (q15_t)0x7b00, (q15_t)0x7af9, (q15_t)0x7af2, + (q15_t)0x7aeb, (q15_t)0x7ae4, (q15_t)0x7add, (q15_t)0x7ad6, (q15_t)0x7acf, (q15_t)0x7ac8, (q15_t)0x7ac1, (q15_t)0x7aba, + (q15_t)0x7ab3, (q15_t)0x7aac, (q15_t)0x7aa4, (q15_t)0x7a9d, (q15_t)0x7a96, (q15_t)0x7a8f, (q15_t)0x7a87, (q15_t)0x7a80, + (q15_t)0x7a79, (q15_t)0x7a72, (q15_t)0x7a6a, (q15_t)0x7a63, (q15_t)0x7a5c, (q15_t)0x7a54, (q15_t)0x7a4d, (q15_t)0x7a45, + (q15_t)0x7a3e, (q15_t)0x7a36, (q15_t)0x7a2f, (q15_t)0x7a27, (q15_t)0x7a20, (q15_t)0x7a18, (q15_t)0x7a11, (q15_t)0x7a09, + (q15_t)0x7a02, (q15_t)0x79fa, (q15_t)0x79f2, (q15_t)0x79eb, (q15_t)0x79e3, (q15_t)0x79db, (q15_t)0x79d4, (q15_t)0x79cc, + (q15_t)0x79c4, (q15_t)0x79bc, (q15_t)0x79b5, (q15_t)0x79ad, (q15_t)0x79a5, (q15_t)0x799d, (q15_t)0x7995, (q15_t)0x798e, + (q15_t)0x7986, (q15_t)0x797e, (q15_t)0x7976, (q15_t)0x796e, (q15_t)0x7966, (q15_t)0x795e, (q15_t)0x7956, (q15_t)0x794e, + (q15_t)0x7946, (q15_t)0x793e, (q15_t)0x7936, (q15_t)0x792e, (q15_t)0x7926, (q15_t)0x791e, (q15_t)0x7915, (q15_t)0x790d, + (q15_t)0x7905, (q15_t)0x78fd, (q15_t)0x78f5, (q15_t)0x78ec, (q15_t)0x78e4, (q15_t)0x78dc, (q15_t)0x78d4, (q15_t)0x78cb, + (q15_t)0x78c3, (q15_t)0x78bb, (q15_t)0x78b2, (q15_t)0x78aa, (q15_t)0x78a2, (q15_t)0x7899, (q15_t)0x7891, (q15_t)0x7888, + (q15_t)0x7880, (q15_t)0x7877, (q15_t)0x786f, (q15_t)0x7866, (q15_t)0x785e, (q15_t)0x7855, (q15_t)0x784d, (q15_t)0x7844, + (q15_t)0x783b, (q15_t)0x7833, (q15_t)0x782a, (q15_t)0x7821, (q15_t)0x7819, (q15_t)0x7810, (q15_t)0x7807, (q15_t)0x77ff, + (q15_t)0x77f6, (q15_t)0x77ed, (q15_t)0x77e4, (q15_t)0x77db, (q15_t)0x77d3, (q15_t)0x77ca, (q15_t)0x77c1, (q15_t)0x77b8, + (q15_t)0x77af, (q15_t)0x77a6, (q15_t)0x779d, (q15_t)0x7794, (q15_t)0x778b, (q15_t)0x7782, (q15_t)0x7779, (q15_t)0x7770, + (q15_t)0x7767, (q15_t)0x775e, (q15_t)0x7755, (q15_t)0x774c, (q15_t)0x7743, (q15_t)0x773a, (q15_t)0x7731, (q15_t)0x7727, + (q15_t)0x771e, (q15_t)0x7715, (q15_t)0x770c, (q15_t)0x7703, (q15_t)0x76f9, (q15_t)0x76f0, (q15_t)0x76e7, (q15_t)0x76dd, + (q15_t)0x76d4, (q15_t)0x76cb, (q15_t)0x76c1, (q15_t)0x76b8, (q15_t)0x76af, (q15_t)0x76a5, (q15_t)0x769c, (q15_t)0x7692, + (q15_t)0x7689, (q15_t)0x767f, (q15_t)0x7676, (q15_t)0x766c, (q15_t)0x7663, (q15_t)0x7659, (q15_t)0x7650, (q15_t)0x7646, + (q15_t)0x763c, (q15_t)0x7633, (q15_t)0x7629, (q15_t)0x761f, (q15_t)0x7616, (q15_t)0x760c, (q15_t)0x7602, (q15_t)0x75f9, + (q15_t)0x75ef, (q15_t)0x75e5, (q15_t)0x75db, (q15_t)0x75d1, (q15_t)0x75c8, (q15_t)0x75be, (q15_t)0x75b4, (q15_t)0x75aa, + (q15_t)0x75a0, (q15_t)0x7596, (q15_t)0x758c, (q15_t)0x7582, (q15_t)0x7578, (q15_t)0x756e, (q15_t)0x7564, (q15_t)0x755a, + (q15_t)0x7550, (q15_t)0x7546, (q15_t)0x753c, (q15_t)0x7532, (q15_t)0x7528, (q15_t)0x751e, (q15_t)0x7514, (q15_t)0x7509, + (q15_t)0x74ff, (q15_t)0x74f5, (q15_t)0x74eb, (q15_t)0x74e1, (q15_t)0x74d6, (q15_t)0x74cc, (q15_t)0x74c2, (q15_t)0x74b7, + (q15_t)0x74ad, (q15_t)0x74a3, (q15_t)0x7498, (q15_t)0x748e, (q15_t)0x7484, (q15_t)0x7479, (q15_t)0x746f, (q15_t)0x7464, + (q15_t)0x745a, (q15_t)0x744f, (q15_t)0x7445, (q15_t)0x743a, (q15_t)0x7430, (q15_t)0x7425, (q15_t)0x741b, (q15_t)0x7410, + (q15_t)0x7406, (q15_t)0x73fb, (q15_t)0x73f0, (q15_t)0x73e6, (q15_t)0x73db, (q15_t)0x73d0, (q15_t)0x73c6, (q15_t)0x73bb, + (q15_t)0x73b0, (q15_t)0x73a5, (q15_t)0x739b, (q15_t)0x7390, (q15_t)0x7385, (q15_t)0x737a, (q15_t)0x736f, (q15_t)0x7364, + (q15_t)0x7359, (q15_t)0x734f, (q15_t)0x7344, (q15_t)0x7339, (q15_t)0x732e, (q15_t)0x7323, (q15_t)0x7318, (q15_t)0x730d, + (q15_t)0x7302, (q15_t)0x72f7, (q15_t)0x72ec, (q15_t)0x72e1, (q15_t)0x72d5, (q15_t)0x72ca, (q15_t)0x72bf, (q15_t)0x72b4, + (q15_t)0x72a9, (q15_t)0x729e, (q15_t)0x7293, (q15_t)0x7287, (q15_t)0x727c, (q15_t)0x7271, (q15_t)0x7266, (q15_t)0x725a, + (q15_t)0x724f, (q15_t)0x7244, (q15_t)0x7238, (q15_t)0x722d, (q15_t)0x7222, (q15_t)0x7216, (q15_t)0x720b, (q15_t)0x71ff, + (q15_t)0x71f4, (q15_t)0x71e9, (q15_t)0x71dd, (q15_t)0x71d2, (q15_t)0x71c6, (q15_t)0x71bb, (q15_t)0x71af, (q15_t)0x71a3, + (q15_t)0x7198, (q15_t)0x718c, (q15_t)0x7181, (q15_t)0x7175, (q15_t)0x7169, (q15_t)0x715e, (q15_t)0x7152, (q15_t)0x7146, + (q15_t)0x713b, (q15_t)0x712f, (q15_t)0x7123, (q15_t)0x7117, (q15_t)0x710c, (q15_t)0x7100, (q15_t)0x70f4, (q15_t)0x70e8, + (q15_t)0x70dc, (q15_t)0x70d1, (q15_t)0x70c5, (q15_t)0x70b9, (q15_t)0x70ad, (q15_t)0x70a1, (q15_t)0x7095, (q15_t)0x7089, + (q15_t)0x707d, (q15_t)0x7071, (q15_t)0x7065, (q15_t)0x7059, (q15_t)0x704d, (q15_t)0x7041, (q15_t)0x7035, (q15_t)0x7029, + (q15_t)0x701d, (q15_t)0x7010, (q15_t)0x7004, (q15_t)0x6ff8, (q15_t)0x6fec, (q15_t)0x6fe0, (q15_t)0x6fd3, (q15_t)0x6fc7, + (q15_t)0x6fbb, (q15_t)0x6faf, (q15_t)0x6fa2, (q15_t)0x6f96, (q15_t)0x6f8a, (q15_t)0x6f7d, (q15_t)0x6f71, (q15_t)0x6f65, + (q15_t)0x6f58, (q15_t)0x6f4c, (q15_t)0x6f3f, (q15_t)0x6f33, (q15_t)0x6f27, (q15_t)0x6f1a, (q15_t)0x6f0e, (q15_t)0x6f01, + (q15_t)0x6ef5, (q15_t)0x6ee8, (q15_t)0x6edc, (q15_t)0x6ecf, (q15_t)0x6ec2, (q15_t)0x6eb6, (q15_t)0x6ea9, (q15_t)0x6e9c, + (q15_t)0x6e90, (q15_t)0x6e83, (q15_t)0x6e76, (q15_t)0x6e6a, (q15_t)0x6e5d, (q15_t)0x6e50, (q15_t)0x6e44, (q15_t)0x6e37, + (q15_t)0x6e2a, (q15_t)0x6e1d, (q15_t)0x6e10, (q15_t)0x6e04, (q15_t)0x6df7, (q15_t)0x6dea, (q15_t)0x6ddd, (q15_t)0x6dd0, + (q15_t)0x6dc3, (q15_t)0x6db6, (q15_t)0x6da9, (q15_t)0x6d9c, (q15_t)0x6d8f, (q15_t)0x6d82, (q15_t)0x6d75, (q15_t)0x6d68, + (q15_t)0x6d5b, (q15_t)0x6d4e, (q15_t)0x6d41, (q15_t)0x6d34, (q15_t)0x6d27, (q15_t)0x6d1a, (q15_t)0x6d0c, (q15_t)0x6cff, + (q15_t)0x6cf2, (q15_t)0x6ce5, (q15_t)0x6cd8, (q15_t)0x6cca, (q15_t)0x6cbd, (q15_t)0x6cb0, (q15_t)0x6ca3, (q15_t)0x6c95, + (q15_t)0x6c88, (q15_t)0x6c7b, (q15_t)0x6c6d, (q15_t)0x6c60, (q15_t)0x6c53, (q15_t)0x6c45, (q15_t)0x6c38, (q15_t)0x6c2a, + (q15_t)0x6c1d, (q15_t)0x6c0f, (q15_t)0x6c02, (q15_t)0x6bf5, (q15_t)0x6be7, (q15_t)0x6bd9, (q15_t)0x6bcc, (q15_t)0x6bbe, + (q15_t)0x6bb1, (q15_t)0x6ba3, (q15_t)0x6b96, (q15_t)0x6b88, (q15_t)0x6b7a, (q15_t)0x6b6d, (q15_t)0x6b5f, (q15_t)0x6b51, + (q15_t)0x6b44, (q15_t)0x6b36, (q15_t)0x6b28, (q15_t)0x6b1a, (q15_t)0x6b0d, (q15_t)0x6aff, (q15_t)0x6af1, (q15_t)0x6ae3, + (q15_t)0x6ad5, (q15_t)0x6ac8, (q15_t)0x6aba, (q15_t)0x6aac, (q15_t)0x6a9e, (q15_t)0x6a90, (q15_t)0x6a82, (q15_t)0x6a74, + (q15_t)0x6a66, (q15_t)0x6a58, (q15_t)0x6a4a, (q15_t)0x6a3c, (q15_t)0x6a2e, (q15_t)0x6a20, (q15_t)0x6a12, (q15_t)0x6a04, + (q15_t)0x69f6, (q15_t)0x69e8, (q15_t)0x69da, (q15_t)0x69cb, (q15_t)0x69bd, (q15_t)0x69af, (q15_t)0x69a1, (q15_t)0x6993, + (q15_t)0x6985, (q15_t)0x6976, (q15_t)0x6968, (q15_t)0x695a, (q15_t)0x694b, (q15_t)0x693d, (q15_t)0x692f, (q15_t)0x6921, + (q15_t)0x6912, (q15_t)0x6904, (q15_t)0x68f5, (q15_t)0x68e7, (q15_t)0x68d9, (q15_t)0x68ca, (q15_t)0x68bc, (q15_t)0x68ad, + (q15_t)0x689f, (q15_t)0x6890, (q15_t)0x6882, (q15_t)0x6873, (q15_t)0x6865, (q15_t)0x6856, (q15_t)0x6848, (q15_t)0x6839, + (q15_t)0x682b, (q15_t)0x681c, (q15_t)0x680d, (q15_t)0x67ff, (q15_t)0x67f0, (q15_t)0x67e1, (q15_t)0x67d3, (q15_t)0x67c4, + (q15_t)0x67b5, (q15_t)0x67a6, (q15_t)0x6798, (q15_t)0x6789, (q15_t)0x677a, (q15_t)0x676b, (q15_t)0x675d, (q15_t)0x674e, + (q15_t)0x673f, (q15_t)0x6730, (q15_t)0x6721, (q15_t)0x6712, (q15_t)0x6703, (q15_t)0x66f4, (q15_t)0x66e5, (q15_t)0x66d6, + (q15_t)0x66c8, (q15_t)0x66b9, (q15_t)0x66aa, (q15_t)0x669b, (q15_t)0x668b, (q15_t)0x667c, (q15_t)0x666d, (q15_t)0x665e, + (q15_t)0x664f, (q15_t)0x6640, (q15_t)0x6631, (q15_t)0x6622, (q15_t)0x6613, (q15_t)0x6603, (q15_t)0x65f4, (q15_t)0x65e5, + (q15_t)0x65d6, (q15_t)0x65c7, (q15_t)0x65b7, (q15_t)0x65a8, (q15_t)0x6599, (q15_t)0x658a, (q15_t)0x657a, (q15_t)0x656b, + (q15_t)0x655c, (q15_t)0x654c, (q15_t)0x653d, (q15_t)0x652d, (q15_t)0x651e, (q15_t)0x650f, (q15_t)0x64ff, (q15_t)0x64f0, + (q15_t)0x64e0, (q15_t)0x64d1, (q15_t)0x64c1, (q15_t)0x64b2, (q15_t)0x64a2, (q15_t)0x6493, (q15_t)0x6483, (q15_t)0x6474, + (q15_t)0x6464, (q15_t)0x6454, (q15_t)0x6445, (q15_t)0x6435, (q15_t)0x6426, (q15_t)0x6416, (q15_t)0x6406, (q15_t)0x63f7, + (q15_t)0x63e7, (q15_t)0x63d7, (q15_t)0x63c7, (q15_t)0x63b8, (q15_t)0x63a8, (q15_t)0x6398, (q15_t)0x6388, (q15_t)0x6378, + (q15_t)0x6369, (q15_t)0x6359, (q15_t)0x6349, (q15_t)0x6339, (q15_t)0x6329, (q15_t)0x6319, (q15_t)0x6309, (q15_t)0x62f9, + (q15_t)0x62ea, (q15_t)0x62da, (q15_t)0x62ca, (q15_t)0x62ba, (q15_t)0x62aa, (q15_t)0x629a, (q15_t)0x628a, (q15_t)0x627a, + (q15_t)0x6269, (q15_t)0x6259, (q15_t)0x6249, (q15_t)0x6239, (q15_t)0x6229, (q15_t)0x6219, (q15_t)0x6209, (q15_t)0x61f9, + (q15_t)0x61e8, (q15_t)0x61d8, (q15_t)0x61c8, (q15_t)0x61b8, (q15_t)0x61a8, (q15_t)0x6197, (q15_t)0x6187, (q15_t)0x6177, + (q15_t)0x6166, (q15_t)0x6156, (q15_t)0x6146, (q15_t)0x6135, (q15_t)0x6125, (q15_t)0x6115, (q15_t)0x6104, (q15_t)0x60f4, + (q15_t)0x60e4, (q15_t)0x60d3, (q15_t)0x60c3, (q15_t)0x60b2, (q15_t)0x60a2, (q15_t)0x6091, (q15_t)0x6081, (q15_t)0x6070, + (q15_t)0x6060, (q15_t)0x604f, (q15_t)0x603f, (q15_t)0x602e, (q15_t)0x601d, (q15_t)0x600d, (q15_t)0x5ffc, (q15_t)0x5fec, + (q15_t)0x5fdb, (q15_t)0x5fca, (q15_t)0x5fba, (q15_t)0x5fa9, (q15_t)0x5f98, (q15_t)0x5f87, (q15_t)0x5f77, (q15_t)0x5f66, + (q15_t)0x5f55, (q15_t)0x5f44, (q15_t)0x5f34, (q15_t)0x5f23, (q15_t)0x5f12, (q15_t)0x5f01, (q15_t)0x5ef0, (q15_t)0x5edf, + (q15_t)0x5ecf, (q15_t)0x5ebe, (q15_t)0x5ead, (q15_t)0x5e9c, (q15_t)0x5e8b, (q15_t)0x5e7a, (q15_t)0x5e69, (q15_t)0x5e58, + (q15_t)0x5e47, (q15_t)0x5e36, (q15_t)0x5e25, (q15_t)0x5e14, (q15_t)0x5e03, (q15_t)0x5df2, (q15_t)0x5de1, (q15_t)0x5dd0, + (q15_t)0x5dbf, (q15_t)0x5dad, (q15_t)0x5d9c, (q15_t)0x5d8b, (q15_t)0x5d7a, (q15_t)0x5d69, (q15_t)0x5d58, (q15_t)0x5d46, + (q15_t)0x5d35, (q15_t)0x5d24, (q15_t)0x5d13, (q15_t)0x5d01, (q15_t)0x5cf0, (q15_t)0x5cdf, (q15_t)0x5cce, (q15_t)0x5cbc, + (q15_t)0x5cab, (q15_t)0x5c9a, (q15_t)0x5c88, (q15_t)0x5c77, (q15_t)0x5c66, (q15_t)0x5c54, (q15_t)0x5c43, (q15_t)0x5c31, + (q15_t)0x5c20, (q15_t)0x5c0e, (q15_t)0x5bfd, (q15_t)0x5beb, (q15_t)0x5bda, (q15_t)0x5bc8, (q15_t)0x5bb7, (q15_t)0x5ba5, + (q15_t)0x5b94, (q15_t)0x5b82, (q15_t)0x5b71, (q15_t)0x5b5f, (q15_t)0x5b4d, (q15_t)0x5b3c, (q15_t)0x5b2a, (q15_t)0x5b19, + (q15_t)0x5b07, (q15_t)0x5af5, (q15_t)0x5ae4, (q15_t)0x5ad2, (q15_t)0x5ac0, (q15_t)0x5aae, (q15_t)0x5a9d, (q15_t)0x5a8b, + (q15_t)0x5a79, (q15_t)0x5a67, (q15_t)0x5a56, (q15_t)0x5a44, (q15_t)0x5a32, (q15_t)0x5a20, (q15_t)0x5a0e, (q15_t)0x59fc, + (q15_t)0x59ea, (q15_t)0x59d9, (q15_t)0x59c7, (q15_t)0x59b5, (q15_t)0x59a3, (q15_t)0x5991, (q15_t)0x597f, (q15_t)0x596d, + (q15_t)0x595b, (q15_t)0x5949, (q15_t)0x5937, (q15_t)0x5925, (q15_t)0x5913, (q15_t)0x5901, (q15_t)0x58ef, (q15_t)0x58dd, + (q15_t)0x58cb, (q15_t)0x58b8, (q15_t)0x58a6, (q15_t)0x5894, (q15_t)0x5882, (q15_t)0x5870, (q15_t)0x585e, (q15_t)0x584b, + (q15_t)0x5839, (q15_t)0x5827, (q15_t)0x5815, (q15_t)0x5803, (q15_t)0x57f0, (q15_t)0x57de, (q15_t)0x57cc, (q15_t)0x57b9, + (q15_t)0x57a7, (q15_t)0x5795, (q15_t)0x5783, (q15_t)0x5770, (q15_t)0x575e, (q15_t)0x574b, (q15_t)0x5739, (q15_t)0x5727, + (q15_t)0x5714, (q15_t)0x5702, (q15_t)0x56ef, (q15_t)0x56dd, (q15_t)0x56ca, (q15_t)0x56b8, (q15_t)0x56a5, (q15_t)0x5693, + (q15_t)0x5680, (q15_t)0x566e, (q15_t)0x565b, (q15_t)0x5649, (q15_t)0x5636, (q15_t)0x5624, (q15_t)0x5611, (q15_t)0x55fe, + (q15_t)0x55ec, (q15_t)0x55d9, (q15_t)0x55c7, (q15_t)0x55b4, (q15_t)0x55a1, (q15_t)0x558f, (q15_t)0x557c, (q15_t)0x5569, + (q15_t)0x5556, (q15_t)0x5544, (q15_t)0x5531, (q15_t)0x551e, (q15_t)0x550b, (q15_t)0x54f9, (q15_t)0x54e6, (q15_t)0x54d3, + (q15_t)0x54c0, (q15_t)0x54ad, (q15_t)0x549a, (q15_t)0x5488, (q15_t)0x5475, (q15_t)0x5462, (q15_t)0x544f, (q15_t)0x543c, + (q15_t)0x5429, (q15_t)0x5416, (q15_t)0x5403, (q15_t)0x53f0, (q15_t)0x53dd, (q15_t)0x53ca, (q15_t)0x53b7, (q15_t)0x53a4, + (q15_t)0x5391, (q15_t)0x537e, (q15_t)0x536b, (q15_t)0x5358, (q15_t)0x5345, (q15_t)0x5332, (q15_t)0x531f, (q15_t)0x530c, + (q15_t)0x52f8, (q15_t)0x52e5, (q15_t)0x52d2, (q15_t)0x52bf, (q15_t)0x52ac, (q15_t)0x5299, (q15_t)0x5285, (q15_t)0x5272, + (q15_t)0x525f, (q15_t)0x524c, (q15_t)0x5238, (q15_t)0x5225, (q15_t)0x5212, (q15_t)0x51ff, (q15_t)0x51eb, (q15_t)0x51d8, + (q15_t)0x51c5, (q15_t)0x51b1, (q15_t)0x519e, (q15_t)0x518b, (q15_t)0x5177, (q15_t)0x5164, (q15_t)0x5150, (q15_t)0x513d, + (q15_t)0x512a, (q15_t)0x5116, (q15_t)0x5103, (q15_t)0x50ef, (q15_t)0x50dc, (q15_t)0x50c8, (q15_t)0x50b5, (q15_t)0x50a1, + (q15_t)0x508e, (q15_t)0x507a, (q15_t)0x5067, (q15_t)0x5053, (q15_t)0x503f, (q15_t)0x502c, (q15_t)0x5018, (q15_t)0x5005, + (q15_t)0x4ff1, (q15_t)0x4fdd, (q15_t)0x4fca, (q15_t)0x4fb6, (q15_t)0x4fa2, (q15_t)0x4f8f, (q15_t)0x4f7b, (q15_t)0x4f67, + (q15_t)0x4f54, (q15_t)0x4f40, (q15_t)0x4f2c, (q15_t)0x4f18, (q15_t)0x4f05, (q15_t)0x4ef1, (q15_t)0x4edd, (q15_t)0x4ec9, + (q15_t)0x4eb6, (q15_t)0x4ea2, (q15_t)0x4e8e, (q15_t)0x4e7a, (q15_t)0x4e66, (q15_t)0x4e52, (q15_t)0x4e3e, (q15_t)0x4e2a, + (q15_t)0x4e17, (q15_t)0x4e03, (q15_t)0x4def, (q15_t)0x4ddb, (q15_t)0x4dc7, (q15_t)0x4db3, (q15_t)0x4d9f, (q15_t)0x4d8b, + (q15_t)0x4d77, (q15_t)0x4d63, (q15_t)0x4d4f, (q15_t)0x4d3b, (q15_t)0x4d27, (q15_t)0x4d13, (q15_t)0x4cff, (q15_t)0x4ceb, + (q15_t)0x4cd6, (q15_t)0x4cc2, (q15_t)0x4cae, (q15_t)0x4c9a, (q15_t)0x4c86, (q15_t)0x4c72, (q15_t)0x4c5e, (q15_t)0x4c49, + (q15_t)0x4c35, (q15_t)0x4c21, (q15_t)0x4c0d, (q15_t)0x4bf9, (q15_t)0x4be4, (q15_t)0x4bd0, (q15_t)0x4bbc, (q15_t)0x4ba8, + (q15_t)0x4b93, (q15_t)0x4b7f, (q15_t)0x4b6b, (q15_t)0x4b56, (q15_t)0x4b42, (q15_t)0x4b2e, (q15_t)0x4b19, (q15_t)0x4b05, + (q15_t)0x4af1, (q15_t)0x4adc, (q15_t)0x4ac8, (q15_t)0x4ab4, (q15_t)0x4a9f, (q15_t)0x4a8b, (q15_t)0x4a76, (q15_t)0x4a62, + (q15_t)0x4a4d, (q15_t)0x4a39, (q15_t)0x4a24, (q15_t)0x4a10, (q15_t)0x49fb, (q15_t)0x49e7, (q15_t)0x49d2, (q15_t)0x49be, + (q15_t)0x49a9, (q15_t)0x4995, (q15_t)0x4980, (q15_t)0x496c, (q15_t)0x4957, (q15_t)0x4942, (q15_t)0x492e, (q15_t)0x4919, + (q15_t)0x4905, (q15_t)0x48f0, (q15_t)0x48db, (q15_t)0x48c7, (q15_t)0x48b2, (q15_t)0x489d, (q15_t)0x4888, (q15_t)0x4874, + (q15_t)0x485f, (q15_t)0x484a, (q15_t)0x4836, (q15_t)0x4821, (q15_t)0x480c, (q15_t)0x47f7, (q15_t)0x47e2, (q15_t)0x47ce, + (q15_t)0x47b9, (q15_t)0x47a4, (q15_t)0x478f, (q15_t)0x477a, (q15_t)0x4765, (q15_t)0x4751, (q15_t)0x473c, (q15_t)0x4727, + (q15_t)0x4712, (q15_t)0x46fd, (q15_t)0x46e8, (q15_t)0x46d3, (q15_t)0x46be, (q15_t)0x46a9, (q15_t)0x4694, (q15_t)0x467f, + (q15_t)0x466a, (q15_t)0x4655, (q15_t)0x4640, (q15_t)0x462b, (q15_t)0x4616, (q15_t)0x4601, (q15_t)0x45ec, (q15_t)0x45d7, + (q15_t)0x45c2, (q15_t)0x45ad, (q15_t)0x4598, (q15_t)0x4583, (q15_t)0x456e, (q15_t)0x4559, (q15_t)0x4544, (q15_t)0x452e, + (q15_t)0x4519, (q15_t)0x4504, (q15_t)0x44ef, (q15_t)0x44da, (q15_t)0x44c5, (q15_t)0x44af, (q15_t)0x449a, (q15_t)0x4485, + (q15_t)0x4470, (q15_t)0x445a, (q15_t)0x4445, (q15_t)0x4430, (q15_t)0x441b, (q15_t)0x4405, (q15_t)0x43f0, (q15_t)0x43db, + (q15_t)0x43c5, (q15_t)0x43b0, (q15_t)0x439b, (q15_t)0x4385, (q15_t)0x4370, (q15_t)0x435b, (q15_t)0x4345, (q15_t)0x4330, + (q15_t)0x431b, (q15_t)0x4305, (q15_t)0x42f0, (q15_t)0x42da, (q15_t)0x42c5, (q15_t)0x42af, (q15_t)0x429a, (q15_t)0x4284, + (q15_t)0x426f, (q15_t)0x425a, (q15_t)0x4244, (q15_t)0x422f, (q15_t)0x4219, (q15_t)0x4203, (q15_t)0x41ee, (q15_t)0x41d8, + (q15_t)0x41c3, (q15_t)0x41ad, (q15_t)0x4198, (q15_t)0x4182, (q15_t)0x416d, (q15_t)0x4157, (q15_t)0x4141, (q15_t)0x412c, + (q15_t)0x4116, (q15_t)0x4100, (q15_t)0x40eb, (q15_t)0x40d5, (q15_t)0x40bf, (q15_t)0x40aa, (q15_t)0x4094, (q15_t)0x407e, + (q15_t)0x4069, (q15_t)0x4053, (q15_t)0x403d, (q15_t)0x4027, (q15_t)0x4012, (q15_t)0x3ffc, (q15_t)0x3fe6, (q15_t)0x3fd0, + (q15_t)0x3fbb, (q15_t)0x3fa5, (q15_t)0x3f8f, (q15_t)0x3f79, (q15_t)0x3f63, (q15_t)0x3f4d, (q15_t)0x3f38, (q15_t)0x3f22, + (q15_t)0x3f0c, (q15_t)0x3ef6, (q15_t)0x3ee0, (q15_t)0x3eca, (q15_t)0x3eb4, (q15_t)0x3e9e, (q15_t)0x3e88, (q15_t)0x3e73, + (q15_t)0x3e5d, (q15_t)0x3e47, (q15_t)0x3e31, (q15_t)0x3e1b, (q15_t)0x3e05, (q15_t)0x3def, (q15_t)0x3dd9, (q15_t)0x3dc3, + (q15_t)0x3dad, (q15_t)0x3d97, (q15_t)0x3d81, (q15_t)0x3d6b, (q15_t)0x3d55, (q15_t)0x3d3e, (q15_t)0x3d28, (q15_t)0x3d12, + (q15_t)0x3cfc, (q15_t)0x3ce6, (q15_t)0x3cd0, (q15_t)0x3cba, (q15_t)0x3ca4, (q15_t)0x3c8e, (q15_t)0x3c77, (q15_t)0x3c61, + (q15_t)0x3c4b, (q15_t)0x3c35, (q15_t)0x3c1f, (q15_t)0x3c09, (q15_t)0x3bf2, (q15_t)0x3bdc, (q15_t)0x3bc6, (q15_t)0x3bb0, + (q15_t)0x3b99, (q15_t)0x3b83, (q15_t)0x3b6d, (q15_t)0x3b57, (q15_t)0x3b40, (q15_t)0x3b2a, (q15_t)0x3b14, (q15_t)0x3afe, + (q15_t)0x3ae7, (q15_t)0x3ad1, (q15_t)0x3abb, (q15_t)0x3aa4, (q15_t)0x3a8e, (q15_t)0x3a78, (q15_t)0x3a61, (q15_t)0x3a4b, + (q15_t)0x3a34, (q15_t)0x3a1e, (q15_t)0x3a08, (q15_t)0x39f1, (q15_t)0x39db, (q15_t)0x39c4, (q15_t)0x39ae, (q15_t)0x3998, + (q15_t)0x3981, (q15_t)0x396b, (q15_t)0x3954, (q15_t)0x393e, (q15_t)0x3927, (q15_t)0x3911, (q15_t)0x38fa, (q15_t)0x38e4, + (q15_t)0x38cd, (q15_t)0x38b7, (q15_t)0x38a0, (q15_t)0x388a, (q15_t)0x3873, (q15_t)0x385d, (q15_t)0x3846, (q15_t)0x382f, + (q15_t)0x3819, (q15_t)0x3802, (q15_t)0x37ec, (q15_t)0x37d5, (q15_t)0x37be, (q15_t)0x37a8, (q15_t)0x3791, (q15_t)0x377a, + (q15_t)0x3764, (q15_t)0x374d, (q15_t)0x3736, (q15_t)0x3720, (q15_t)0x3709, (q15_t)0x36f2, (q15_t)0x36dc, (q15_t)0x36c5, + (q15_t)0x36ae, (q15_t)0x3698, (q15_t)0x3681, (q15_t)0x366a, (q15_t)0x3653, (q15_t)0x363d, (q15_t)0x3626, (q15_t)0x360f, + (q15_t)0x35f8, (q15_t)0x35e1, (q15_t)0x35cb, (q15_t)0x35b4, (q15_t)0x359d, (q15_t)0x3586, (q15_t)0x356f, (q15_t)0x3558, + (q15_t)0x3542, (q15_t)0x352b, (q15_t)0x3514, (q15_t)0x34fd, (q15_t)0x34e6, (q15_t)0x34cf, (q15_t)0x34b8, (q15_t)0x34a1, + (q15_t)0x348b, (q15_t)0x3474, (q15_t)0x345d, (q15_t)0x3446, (q15_t)0x342f, (q15_t)0x3418, (q15_t)0x3401, (q15_t)0x33ea, + (q15_t)0x33d3, (q15_t)0x33bc, (q15_t)0x33a5, (q15_t)0x338e, (q15_t)0x3377, (q15_t)0x3360, (q15_t)0x3349, (q15_t)0x3332, + (q15_t)0x331b, (q15_t)0x3304, (q15_t)0x32ed, (q15_t)0x32d6, (q15_t)0x32bf, (q15_t)0x32a8, (q15_t)0x3290, (q15_t)0x3279, + (q15_t)0x3262, (q15_t)0x324b, (q15_t)0x3234, (q15_t)0x321d, (q15_t)0x3206, (q15_t)0x31ef, (q15_t)0x31d8, (q15_t)0x31c0, + (q15_t)0x31a9, (q15_t)0x3192, (q15_t)0x317b, (q15_t)0x3164, (q15_t)0x314c, (q15_t)0x3135, (q15_t)0x311e, (q15_t)0x3107, + (q15_t)0x30f0, (q15_t)0x30d8, (q15_t)0x30c1, (q15_t)0x30aa, (q15_t)0x3093, (q15_t)0x307b, (q15_t)0x3064, (q15_t)0x304d, + (q15_t)0x3036, (q15_t)0x301e, (q15_t)0x3007, (q15_t)0x2ff0, (q15_t)0x2fd8, (q15_t)0x2fc1, (q15_t)0x2faa, (q15_t)0x2f92, + (q15_t)0x2f7b, (q15_t)0x2f64, (q15_t)0x2f4c, (q15_t)0x2f35, (q15_t)0x2f1e, (q15_t)0x2f06, (q15_t)0x2eef, (q15_t)0x2ed8, + (q15_t)0x2ec0, (q15_t)0x2ea9, (q15_t)0x2e91, (q15_t)0x2e7a, (q15_t)0x2e63, (q15_t)0x2e4b, (q15_t)0x2e34, (q15_t)0x2e1c, + (q15_t)0x2e05, (q15_t)0x2ded, (q15_t)0x2dd6, (q15_t)0x2dbe, (q15_t)0x2da7, (q15_t)0x2d8f, (q15_t)0x2d78, (q15_t)0x2d60, + (q15_t)0x2d49, (q15_t)0x2d31, (q15_t)0x2d1a, (q15_t)0x2d02, (q15_t)0x2ceb, (q15_t)0x2cd3, (q15_t)0x2cbc, (q15_t)0x2ca4, + (q15_t)0x2c8d, (q15_t)0x2c75, (q15_t)0x2c5e, (q15_t)0x2c46, (q15_t)0x2c2e, (q15_t)0x2c17, (q15_t)0x2bff, (q15_t)0x2be8, + (q15_t)0x2bd0, (q15_t)0x2bb8, (q15_t)0x2ba1, (q15_t)0x2b89, (q15_t)0x2b71, (q15_t)0x2b5a, (q15_t)0x2b42, (q15_t)0x2b2b, + (q15_t)0x2b13, (q15_t)0x2afb, (q15_t)0x2ae4, (q15_t)0x2acc, (q15_t)0x2ab4, (q15_t)0x2a9c, (q15_t)0x2a85, (q15_t)0x2a6d, + (q15_t)0x2a55, (q15_t)0x2a3e, (q15_t)0x2a26, (q15_t)0x2a0e, (q15_t)0x29f6, (q15_t)0x29df, (q15_t)0x29c7, (q15_t)0x29af, + (q15_t)0x2997, (q15_t)0x2980, (q15_t)0x2968, (q15_t)0x2950, (q15_t)0x2938, (q15_t)0x2920, (q15_t)0x2909, (q15_t)0x28f1, + (q15_t)0x28d9, (q15_t)0x28c1, (q15_t)0x28a9, (q15_t)0x2892, (q15_t)0x287a, (q15_t)0x2862, (q15_t)0x284a, (q15_t)0x2832, + (q15_t)0x281a, (q15_t)0x2802, (q15_t)0x27eb, (q15_t)0x27d3, (q15_t)0x27bb, (q15_t)0x27a3, (q15_t)0x278b, (q15_t)0x2773, + (q15_t)0x275b, (q15_t)0x2743, (q15_t)0x272b, (q15_t)0x2713, (q15_t)0x26fb, (q15_t)0x26e4, (q15_t)0x26cc, (q15_t)0x26b4, + (q15_t)0x269c, (q15_t)0x2684, (q15_t)0x266c, (q15_t)0x2654, (q15_t)0x263c, (q15_t)0x2624, (q15_t)0x260c, (q15_t)0x25f4, + (q15_t)0x25dc, (q15_t)0x25c4, (q15_t)0x25ac, (q15_t)0x2594, (q15_t)0x257c, (q15_t)0x2564, (q15_t)0x254c, (q15_t)0x2534, + (q15_t)0x251c, (q15_t)0x2503, (q15_t)0x24eb, (q15_t)0x24d3, (q15_t)0x24bb, (q15_t)0x24a3, (q15_t)0x248b, (q15_t)0x2473, + (q15_t)0x245b, (q15_t)0x2443, (q15_t)0x242b, (q15_t)0x2413, (q15_t)0x23fa, (q15_t)0x23e2, (q15_t)0x23ca, (q15_t)0x23b2, + (q15_t)0x239a, (q15_t)0x2382, (q15_t)0x236a, (q15_t)0x2352, (q15_t)0x2339, (q15_t)0x2321, (q15_t)0x2309, (q15_t)0x22f1, + (q15_t)0x22d9, (q15_t)0x22c0, (q15_t)0x22a8, (q15_t)0x2290, (q15_t)0x2278, (q15_t)0x2260, (q15_t)0x2247, (q15_t)0x222f, + (q15_t)0x2217, (q15_t)0x21ff, (q15_t)0x21e7, (q15_t)0x21ce, (q15_t)0x21b6, (q15_t)0x219e, (q15_t)0x2186, (q15_t)0x216d, + (q15_t)0x2155, (q15_t)0x213d, (q15_t)0x2125, (q15_t)0x210c, (q15_t)0x20f4, (q15_t)0x20dc, (q15_t)0x20c3, (q15_t)0x20ab, + (q15_t)0x2093, (q15_t)0x207a, (q15_t)0x2062, (q15_t)0x204a, (q15_t)0x2032, (q15_t)0x2019, (q15_t)0x2001, (q15_t)0x1fe9, + (q15_t)0x1fd0, (q15_t)0x1fb8, (q15_t)0x1f9f, (q15_t)0x1f87, (q15_t)0x1f6f, (q15_t)0x1f56, (q15_t)0x1f3e, (q15_t)0x1f26, + (q15_t)0x1f0d, (q15_t)0x1ef5, (q15_t)0x1edd, (q15_t)0x1ec4, (q15_t)0x1eac, (q15_t)0x1e93, (q15_t)0x1e7b, (q15_t)0x1e62, + (q15_t)0x1e4a, (q15_t)0x1e32, (q15_t)0x1e19, (q15_t)0x1e01, (q15_t)0x1de8, (q15_t)0x1dd0, (q15_t)0x1db7, (q15_t)0x1d9f, + (q15_t)0x1d87, (q15_t)0x1d6e, (q15_t)0x1d56, (q15_t)0x1d3d, (q15_t)0x1d25, (q15_t)0x1d0c, (q15_t)0x1cf4, (q15_t)0x1cdb, + (q15_t)0x1cc3, (q15_t)0x1caa, (q15_t)0x1c92, (q15_t)0x1c79, (q15_t)0x1c61, (q15_t)0x1c48, (q15_t)0x1c30, (q15_t)0x1c17, + (q15_t)0x1bff, (q15_t)0x1be6, (q15_t)0x1bce, (q15_t)0x1bb5, (q15_t)0x1b9d, (q15_t)0x1b84, (q15_t)0x1b6c, (q15_t)0x1b53, + (q15_t)0x1b3a, (q15_t)0x1b22, (q15_t)0x1b09, (q15_t)0x1af1, (q15_t)0x1ad8, (q15_t)0x1ac0, (q15_t)0x1aa7, (q15_t)0x1a8e, + (q15_t)0x1a76, (q15_t)0x1a5d, (q15_t)0x1a45, (q15_t)0x1a2c, (q15_t)0x1a13, (q15_t)0x19fb, (q15_t)0x19e2, (q15_t)0x19ca, + (q15_t)0x19b1, (q15_t)0x1998, (q15_t)0x1980, (q15_t)0x1967, (q15_t)0x194e, (q15_t)0x1936, (q15_t)0x191d, (q15_t)0x1905, + (q15_t)0x18ec, (q15_t)0x18d3, (q15_t)0x18bb, (q15_t)0x18a2, (q15_t)0x1889, (q15_t)0x1871, (q15_t)0x1858, (q15_t)0x183f, + (q15_t)0x1827, (q15_t)0x180e, (q15_t)0x17f5, (q15_t)0x17dd, (q15_t)0x17c4, (q15_t)0x17ab, (q15_t)0x1792, (q15_t)0x177a, + (q15_t)0x1761, (q15_t)0x1748, (q15_t)0x1730, (q15_t)0x1717, (q15_t)0x16fe, (q15_t)0x16e5, (q15_t)0x16cd, (q15_t)0x16b4, + (q15_t)0x169b, (q15_t)0x1682, (q15_t)0x166a, (q15_t)0x1651, (q15_t)0x1638, (q15_t)0x161f, (q15_t)0x1607, (q15_t)0x15ee, + (q15_t)0x15d5, (q15_t)0x15bc, (q15_t)0x15a4, (q15_t)0x158b, (q15_t)0x1572, (q15_t)0x1559, (q15_t)0x1541, (q15_t)0x1528, + (q15_t)0x150f, (q15_t)0x14f6, (q15_t)0x14dd, (q15_t)0x14c5, (q15_t)0x14ac, (q15_t)0x1493, (q15_t)0x147a, (q15_t)0x1461, + (q15_t)0x1449, (q15_t)0x1430, (q15_t)0x1417, (q15_t)0x13fe, (q15_t)0x13e5, (q15_t)0x13cc, (q15_t)0x13b4, (q15_t)0x139b, + (q15_t)0x1382, (q15_t)0x1369, (q15_t)0x1350, (q15_t)0x1337, (q15_t)0x131f, (q15_t)0x1306, (q15_t)0x12ed, (q15_t)0x12d4, + (q15_t)0x12bb, (q15_t)0x12a2, (q15_t)0x1289, (q15_t)0x1271, (q15_t)0x1258, (q15_t)0x123f, (q15_t)0x1226, (q15_t)0x120d, + (q15_t)0x11f4, (q15_t)0x11db, (q15_t)0x11c2, (q15_t)0x11a9, (q15_t)0x1191, (q15_t)0x1178, (q15_t)0x115f, (q15_t)0x1146, + (q15_t)0x112d, (q15_t)0x1114, (q15_t)0x10fb, (q15_t)0x10e2, (q15_t)0x10c9, (q15_t)0x10b0, (q15_t)0x1098, (q15_t)0x107f, + (q15_t)0x1066, (q15_t)0x104d, (q15_t)0x1034, (q15_t)0x101b, (q15_t)0x1002, (q15_t)0xfe9, (q15_t)0xfd0, (q15_t)0xfb7, + (q15_t)0xf9e, (q15_t)0xf85, (q15_t)0xf6c, (q15_t)0xf53, (q15_t)0xf3a, (q15_t)0xf21, (q15_t)0xf08, (q15_t)0xef0, + (q15_t)0xed7, (q15_t)0xebe, (q15_t)0xea5, (q15_t)0xe8c, (q15_t)0xe73, (q15_t)0xe5a, (q15_t)0xe41, (q15_t)0xe28, + (q15_t)0xe0f, (q15_t)0xdf6, (q15_t)0xddd, (q15_t)0xdc4, (q15_t)0xdab, (q15_t)0xd92, (q15_t)0xd79, (q15_t)0xd60, + (q15_t)0xd47, (q15_t)0xd2e, (q15_t)0xd15, (q15_t)0xcfc, (q15_t)0xce3, (q15_t)0xcca, (q15_t)0xcb1, (q15_t)0xc98, + (q15_t)0xc7f, (q15_t)0xc66, (q15_t)0xc4d, (q15_t)0xc34, (q15_t)0xc1b, (q15_t)0xc02, (q15_t)0xbe9, (q15_t)0xbd0, + (q15_t)0xbb7, (q15_t)0xb9e, (q15_t)0xb85, (q15_t)0xb6c, (q15_t)0xb53, (q15_t)0xb3a, (q15_t)0xb20, (q15_t)0xb07, + (q15_t)0xaee, (q15_t)0xad5, (q15_t)0xabc, (q15_t)0xaa3, (q15_t)0xa8a, (q15_t)0xa71, (q15_t)0xa58, (q15_t)0xa3f, + (q15_t)0xa26, (q15_t)0xa0d, (q15_t)0x9f4, (q15_t)0x9db, (q15_t)0x9c2, (q15_t)0x9a9, (q15_t)0x990, (q15_t)0x977, + (q15_t)0x95e, (q15_t)0x944, (q15_t)0x92b, (q15_t)0x912, (q15_t)0x8f9, (q15_t)0x8e0, (q15_t)0x8c7, (q15_t)0x8ae, + (q15_t)0x895, (q15_t)0x87c, (q15_t)0x863, (q15_t)0x84a, (q15_t)0x831, (q15_t)0x818, (q15_t)0x7fe, (q15_t)0x7e5, + (q15_t)0x7cc, (q15_t)0x7b3, (q15_t)0x79a, (q15_t)0x781, (q15_t)0x768, (q15_t)0x74f, (q15_t)0x736, (q15_t)0x71d, + (q15_t)0x704, (q15_t)0x6ea, (q15_t)0x6d1, (q15_t)0x6b8, (q15_t)0x69f, (q15_t)0x686, (q15_t)0x66d, (q15_t)0x654, + (q15_t)0x63b, (q15_t)0x622, (q15_t)0x609, (q15_t)0x5ef, (q15_t)0x5d6, (q15_t)0x5bd, (q15_t)0x5a4, (q15_t)0x58b, + (q15_t)0x572, (q15_t)0x559, (q15_t)0x540, (q15_t)0x527, (q15_t)0x50d, (q15_t)0x4f4, (q15_t)0x4db, (q15_t)0x4c2, + (q15_t)0x4a9, (q15_t)0x490, (q15_t)0x477, (q15_t)0x45e, (q15_t)0x445, (q15_t)0x42b, (q15_t)0x412, (q15_t)0x3f9, + (q15_t)0x3e0, (q15_t)0x3c7, (q15_t)0x3ae, (q15_t)0x395, (q15_t)0x37c, (q15_t)0x362, (q15_t)0x349, (q15_t)0x330, + (q15_t)0x317, (q15_t)0x2fe, (q15_t)0x2e5, (q15_t)0x2cc, (q15_t)0x2b3, (q15_t)0x299, (q15_t)0x280, (q15_t)0x267, + (q15_t)0x24e, (q15_t)0x235, (q15_t)0x21c, (q15_t)0x203, (q15_t)0x1ea, (q15_t)0x1d0, (q15_t)0x1b7, (q15_t)0x19e, + (q15_t)0x185, (q15_t)0x16c, (q15_t)0x153, (q15_t)0x13a, (q15_t)0x121, (q15_t)0x107, (q15_t)0xee, (q15_t)0xd5, + (q15_t)0xbc, (q15_t)0xa3, (q15_t)0x8a, (q15_t)0x71, (q15_t)0x57, (q15_t)0x3e, (q15_t)0x25, (q15_t)0xc + +}; + +static const q15_t __ALIGNED(4) cos_factorsQ15_8192[8192] = { + (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, + (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, + (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, + (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, + (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, (q15_t)0x7fff, + (q15_t)0x7fff, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, + (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffe, + (q15_t)0x7ffe, (q15_t)0x7ffe, (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffd, + (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffd, (q15_t)0x7ffc, + (q15_t)0x7ffc, (q15_t)0x7ffc, (q15_t)0x7ffc, (q15_t)0x7ffc, (q15_t)0x7ffc, (q15_t)0x7ffc, (q15_t)0x7ffc, (q15_t)0x7ffc, + (q15_t)0x7ffc, (q15_t)0x7ffb, (q15_t)0x7ffb, (q15_t)0x7ffb, (q15_t)0x7ffb, (q15_t)0x7ffb, (q15_t)0x7ffb, (q15_t)0x7ffb, + (q15_t)0x7ffb, (q15_t)0x7ffb, (q15_t)0x7ffb, (q15_t)0x7ffa, (q15_t)0x7ffa, (q15_t)0x7ffa, (q15_t)0x7ffa, (q15_t)0x7ffa, + (q15_t)0x7ffa, (q15_t)0x7ffa, (q15_t)0x7ffa, (q15_t)0x7ffa, (q15_t)0x7ff9, (q15_t)0x7ff9, (q15_t)0x7ff9, (q15_t)0x7ff9, + (q15_t)0x7ff9, (q15_t)0x7ff9, (q15_t)0x7ff9, (q15_t)0x7ff9, (q15_t)0x7ff8, (q15_t)0x7ff8, (q15_t)0x7ff8, (q15_t)0x7ff8, + (q15_t)0x7ff8, (q15_t)0x7ff8, (q15_t)0x7ff8, (q15_t)0x7ff7, (q15_t)0x7ff7, (q15_t)0x7ff7, (q15_t)0x7ff7, (q15_t)0x7ff7, + (q15_t)0x7ff7, (q15_t)0x7ff7, (q15_t)0x7ff6, (q15_t)0x7ff6, (q15_t)0x7ff6, (q15_t)0x7ff6, (q15_t)0x7ff6, (q15_t)0x7ff6, + (q15_t)0x7ff6, (q15_t)0x7ff5, (q15_t)0x7ff5, (q15_t)0x7ff5, (q15_t)0x7ff5, (q15_t)0x7ff5, (q15_t)0x7ff5, (q15_t)0x7ff4, + (q15_t)0x7ff4, (q15_t)0x7ff4, (q15_t)0x7ff4, (q15_t)0x7ff4, (q15_t)0x7ff4, (q15_t)0x7ff3, (q15_t)0x7ff3, (q15_t)0x7ff3, + (q15_t)0x7ff3, (q15_t)0x7ff3, (q15_t)0x7ff3, (q15_t)0x7ff2, (q15_t)0x7ff2, (q15_t)0x7ff2, (q15_t)0x7ff2, (q15_t)0x7ff2, + (q15_t)0x7ff1, (q15_t)0x7ff1, (q15_t)0x7ff1, (q15_t)0x7ff1, (q15_t)0x7ff1, (q15_t)0x7ff1, (q15_t)0x7ff0, (q15_t)0x7ff0, + (q15_t)0x7ff0, (q15_t)0x7ff0, (q15_t)0x7ff0, (q15_t)0x7fef, (q15_t)0x7fef, (q15_t)0x7fef, (q15_t)0x7fef, (q15_t)0x7fef, + (q15_t)0x7fee, (q15_t)0x7fee, (q15_t)0x7fee, (q15_t)0x7fee, (q15_t)0x7fee, (q15_t)0x7fed, (q15_t)0x7fed, (q15_t)0x7fed, + (q15_t)0x7fed, (q15_t)0x7fed, (q15_t)0x7fec, (q15_t)0x7fec, (q15_t)0x7fec, (q15_t)0x7fec, (q15_t)0x7feb, (q15_t)0x7feb, + (q15_t)0x7feb, (q15_t)0x7feb, (q15_t)0x7feb, (q15_t)0x7fea, (q15_t)0x7fea, (q15_t)0x7fea, (q15_t)0x7fea, (q15_t)0x7fe9, + (q15_t)0x7fe9, (q15_t)0x7fe9, (q15_t)0x7fe9, (q15_t)0x7fe8, (q15_t)0x7fe8, (q15_t)0x7fe8, (q15_t)0x7fe8, (q15_t)0x7fe8, + (q15_t)0x7fe7, (q15_t)0x7fe7, (q15_t)0x7fe7, (q15_t)0x7fe7, (q15_t)0x7fe6, (q15_t)0x7fe6, (q15_t)0x7fe6, (q15_t)0x7fe6, + (q15_t)0x7fe5, (q15_t)0x7fe5, (q15_t)0x7fe5, (q15_t)0x7fe5, (q15_t)0x7fe4, (q15_t)0x7fe4, (q15_t)0x7fe4, (q15_t)0x7fe4, + (q15_t)0x7fe3, (q15_t)0x7fe3, (q15_t)0x7fe3, (q15_t)0x7fe2, (q15_t)0x7fe2, (q15_t)0x7fe2, (q15_t)0x7fe2, (q15_t)0x7fe1, + (q15_t)0x7fe1, (q15_t)0x7fe1, (q15_t)0x7fe1, (q15_t)0x7fe0, (q15_t)0x7fe0, (q15_t)0x7fe0, (q15_t)0x7fdf, (q15_t)0x7fdf, + (q15_t)0x7fdf, (q15_t)0x7fdf, (q15_t)0x7fde, (q15_t)0x7fde, (q15_t)0x7fde, (q15_t)0x7fde, (q15_t)0x7fdd, (q15_t)0x7fdd, + (q15_t)0x7fdd, (q15_t)0x7fdc, (q15_t)0x7fdc, (q15_t)0x7fdc, (q15_t)0x7fdb, (q15_t)0x7fdb, (q15_t)0x7fdb, (q15_t)0x7fdb, + (q15_t)0x7fda, (q15_t)0x7fda, (q15_t)0x7fda, (q15_t)0x7fd9, (q15_t)0x7fd9, (q15_t)0x7fd9, (q15_t)0x7fd8, (q15_t)0x7fd8, + (q15_t)0x7fd8, (q15_t)0x7fd8, (q15_t)0x7fd7, (q15_t)0x7fd7, (q15_t)0x7fd7, (q15_t)0x7fd6, (q15_t)0x7fd6, (q15_t)0x7fd6, + (q15_t)0x7fd5, (q15_t)0x7fd5, (q15_t)0x7fd5, (q15_t)0x7fd4, (q15_t)0x7fd4, (q15_t)0x7fd4, (q15_t)0x7fd3, (q15_t)0x7fd3, + (q15_t)0x7fd3, (q15_t)0x7fd2, (q15_t)0x7fd2, (q15_t)0x7fd2, (q15_t)0x7fd1, (q15_t)0x7fd1, (q15_t)0x7fd1, (q15_t)0x7fd0, + (q15_t)0x7fd0, (q15_t)0x7fd0, (q15_t)0x7fcf, (q15_t)0x7fcf, (q15_t)0x7fcf, (q15_t)0x7fce, (q15_t)0x7fce, (q15_t)0x7fce, + (q15_t)0x7fcd, (q15_t)0x7fcd, (q15_t)0x7fcd, (q15_t)0x7fcc, (q15_t)0x7fcc, (q15_t)0x7fcc, (q15_t)0x7fcb, (q15_t)0x7fcb, + (q15_t)0x7fcb, (q15_t)0x7fca, (q15_t)0x7fca, (q15_t)0x7fc9, (q15_t)0x7fc9, (q15_t)0x7fc9, (q15_t)0x7fc8, (q15_t)0x7fc8, + (q15_t)0x7fc8, (q15_t)0x7fc7, (q15_t)0x7fc7, (q15_t)0x7fc7, (q15_t)0x7fc6, (q15_t)0x7fc6, (q15_t)0x7fc5, (q15_t)0x7fc5, + (q15_t)0x7fc5, (q15_t)0x7fc4, (q15_t)0x7fc4, (q15_t)0x7fc4, (q15_t)0x7fc3, (q15_t)0x7fc3, (q15_t)0x7fc2, (q15_t)0x7fc2, + (q15_t)0x7fc2, (q15_t)0x7fc1, (q15_t)0x7fc1, (q15_t)0x7fc0, (q15_t)0x7fc0, (q15_t)0x7fc0, (q15_t)0x7fbf, (q15_t)0x7fbf, + (q15_t)0x7fbf, (q15_t)0x7fbe, (q15_t)0x7fbe, (q15_t)0x7fbd, (q15_t)0x7fbd, (q15_t)0x7fbd, (q15_t)0x7fbc, (q15_t)0x7fbc, + (q15_t)0x7fbb, (q15_t)0x7fbb, (q15_t)0x7fbb, (q15_t)0x7fba, (q15_t)0x7fba, (q15_t)0x7fb9, (q15_t)0x7fb9, (q15_t)0x7fb8, + (q15_t)0x7fb8, (q15_t)0x7fb8, (q15_t)0x7fb7, (q15_t)0x7fb7, (q15_t)0x7fb6, (q15_t)0x7fb6, (q15_t)0x7fb6, (q15_t)0x7fb5, + (q15_t)0x7fb5, (q15_t)0x7fb4, (q15_t)0x7fb4, (q15_t)0x7fb3, (q15_t)0x7fb3, (q15_t)0x7fb3, (q15_t)0x7fb2, (q15_t)0x7fb2, + (q15_t)0x7fb1, (q15_t)0x7fb1, (q15_t)0x7fb0, (q15_t)0x7fb0, (q15_t)0x7faf, (q15_t)0x7faf, (q15_t)0x7faf, (q15_t)0x7fae, + (q15_t)0x7fae, (q15_t)0x7fad, (q15_t)0x7fad, (q15_t)0x7fac, (q15_t)0x7fac, (q15_t)0x7fac, (q15_t)0x7fab, (q15_t)0x7fab, + (q15_t)0x7faa, (q15_t)0x7faa, (q15_t)0x7fa9, (q15_t)0x7fa9, (q15_t)0x7fa8, (q15_t)0x7fa8, (q15_t)0x7fa7, (q15_t)0x7fa7, + (q15_t)0x7fa6, (q15_t)0x7fa6, (q15_t)0x7fa6, (q15_t)0x7fa5, (q15_t)0x7fa5, (q15_t)0x7fa4, (q15_t)0x7fa4, (q15_t)0x7fa3, + (q15_t)0x7fa3, (q15_t)0x7fa2, (q15_t)0x7fa2, (q15_t)0x7fa1, (q15_t)0x7fa1, (q15_t)0x7fa0, (q15_t)0x7fa0, (q15_t)0x7f9f, + (q15_t)0x7f9f, (q15_t)0x7f9e, (q15_t)0x7f9e, (q15_t)0x7f9d, (q15_t)0x7f9d, (q15_t)0x7f9c, (q15_t)0x7f9c, (q15_t)0x7f9c, + (q15_t)0x7f9b, (q15_t)0x7f9b, (q15_t)0x7f9a, (q15_t)0x7f9a, (q15_t)0x7f99, (q15_t)0x7f99, (q15_t)0x7f98, (q15_t)0x7f98, + (q15_t)0x7f97, (q15_t)0x7f97, (q15_t)0x7f96, (q15_t)0x7f96, (q15_t)0x7f95, (q15_t)0x7f95, (q15_t)0x7f94, (q15_t)0x7f94, + (q15_t)0x7f93, (q15_t)0x7f92, (q15_t)0x7f92, (q15_t)0x7f91, (q15_t)0x7f91, (q15_t)0x7f90, (q15_t)0x7f90, (q15_t)0x7f8f, + (q15_t)0x7f8f, (q15_t)0x7f8e, (q15_t)0x7f8e, (q15_t)0x7f8d, (q15_t)0x7f8d, (q15_t)0x7f8c, (q15_t)0x7f8c, (q15_t)0x7f8b, + (q15_t)0x7f8b, (q15_t)0x7f8a, (q15_t)0x7f8a, (q15_t)0x7f89, (q15_t)0x7f89, (q15_t)0x7f88, (q15_t)0x7f87, (q15_t)0x7f87, + (q15_t)0x7f86, (q15_t)0x7f86, (q15_t)0x7f85, (q15_t)0x7f85, (q15_t)0x7f84, (q15_t)0x7f84, (q15_t)0x7f83, (q15_t)0x7f83, + (q15_t)0x7f82, (q15_t)0x7f81, (q15_t)0x7f81, (q15_t)0x7f80, (q15_t)0x7f80, (q15_t)0x7f7f, (q15_t)0x7f7f, (q15_t)0x7f7e, + (q15_t)0x7f7e, (q15_t)0x7f7d, (q15_t)0x7f7c, (q15_t)0x7f7c, (q15_t)0x7f7b, (q15_t)0x7f7b, (q15_t)0x7f7a, (q15_t)0x7f7a, + (q15_t)0x7f79, (q15_t)0x7f79, (q15_t)0x7f78, (q15_t)0x7f77, (q15_t)0x7f77, (q15_t)0x7f76, (q15_t)0x7f76, (q15_t)0x7f75, + (q15_t)0x7f75, (q15_t)0x7f74, (q15_t)0x7f73, (q15_t)0x7f73, (q15_t)0x7f72, (q15_t)0x7f72, (q15_t)0x7f71, (q15_t)0x7f70, + (q15_t)0x7f70, (q15_t)0x7f6f, (q15_t)0x7f6f, (q15_t)0x7f6e, (q15_t)0x7f6d, (q15_t)0x7f6d, (q15_t)0x7f6c, (q15_t)0x7f6c, + (q15_t)0x7f6b, (q15_t)0x7f6b, (q15_t)0x7f6a, (q15_t)0x7f69, (q15_t)0x7f69, (q15_t)0x7f68, (q15_t)0x7f68, (q15_t)0x7f67, + (q15_t)0x7f66, (q15_t)0x7f66, (q15_t)0x7f65, (q15_t)0x7f64, (q15_t)0x7f64, (q15_t)0x7f63, (q15_t)0x7f63, (q15_t)0x7f62, + (q15_t)0x7f61, (q15_t)0x7f61, (q15_t)0x7f60, (q15_t)0x7f60, (q15_t)0x7f5f, (q15_t)0x7f5e, (q15_t)0x7f5e, (q15_t)0x7f5d, + (q15_t)0x7f5c, (q15_t)0x7f5c, (q15_t)0x7f5b, (q15_t)0x7f5b, (q15_t)0x7f5a, (q15_t)0x7f59, (q15_t)0x7f59, (q15_t)0x7f58, + (q15_t)0x7f57, (q15_t)0x7f57, (q15_t)0x7f56, (q15_t)0x7f55, (q15_t)0x7f55, (q15_t)0x7f54, (q15_t)0x7f54, (q15_t)0x7f53, + (q15_t)0x7f52, (q15_t)0x7f52, (q15_t)0x7f51, (q15_t)0x7f50, (q15_t)0x7f50, (q15_t)0x7f4f, (q15_t)0x7f4e, (q15_t)0x7f4e, + (q15_t)0x7f4d, (q15_t)0x7f4c, (q15_t)0x7f4c, (q15_t)0x7f4b, (q15_t)0x7f4a, (q15_t)0x7f4a, (q15_t)0x7f49, (q15_t)0x7f48, + (q15_t)0x7f48, (q15_t)0x7f47, (q15_t)0x7f46, (q15_t)0x7f46, (q15_t)0x7f45, (q15_t)0x7f44, (q15_t)0x7f44, (q15_t)0x7f43, + (q15_t)0x7f42, (q15_t)0x7f42, (q15_t)0x7f41, (q15_t)0x7f40, (q15_t)0x7f40, (q15_t)0x7f3f, (q15_t)0x7f3e, (q15_t)0x7f3e, + (q15_t)0x7f3d, (q15_t)0x7f3c, (q15_t)0x7f3c, (q15_t)0x7f3b, (q15_t)0x7f3a, (q15_t)0x7f3a, (q15_t)0x7f39, (q15_t)0x7f38, + (q15_t)0x7f37, (q15_t)0x7f37, (q15_t)0x7f36, (q15_t)0x7f35, (q15_t)0x7f35, (q15_t)0x7f34, (q15_t)0x7f33, (q15_t)0x7f33, + (q15_t)0x7f32, (q15_t)0x7f31, (q15_t)0x7f31, (q15_t)0x7f30, (q15_t)0x7f2f, (q15_t)0x7f2e, (q15_t)0x7f2e, (q15_t)0x7f2d, + (q15_t)0x7f2c, (q15_t)0x7f2c, (q15_t)0x7f2b, (q15_t)0x7f2a, (q15_t)0x7f29, (q15_t)0x7f29, (q15_t)0x7f28, (q15_t)0x7f27, + (q15_t)0x7f27, (q15_t)0x7f26, (q15_t)0x7f25, (q15_t)0x7f24, (q15_t)0x7f24, (q15_t)0x7f23, (q15_t)0x7f22, (q15_t)0x7f21, + (q15_t)0x7f21, (q15_t)0x7f20, (q15_t)0x7f1f, (q15_t)0x7f1f, (q15_t)0x7f1e, (q15_t)0x7f1d, (q15_t)0x7f1c, (q15_t)0x7f1c, + (q15_t)0x7f1b, (q15_t)0x7f1a, (q15_t)0x7f19, (q15_t)0x7f19, (q15_t)0x7f18, (q15_t)0x7f17, (q15_t)0x7f16, (q15_t)0x7f16, + (q15_t)0x7f15, (q15_t)0x7f14, (q15_t)0x7f13, (q15_t)0x7f13, (q15_t)0x7f12, (q15_t)0x7f11, (q15_t)0x7f10, (q15_t)0x7f10, + (q15_t)0x7f0f, (q15_t)0x7f0e, (q15_t)0x7f0d, (q15_t)0x7f0d, (q15_t)0x7f0c, (q15_t)0x7f0b, (q15_t)0x7f0a, (q15_t)0x7f09, + (q15_t)0x7f09, (q15_t)0x7f08, (q15_t)0x7f07, (q15_t)0x7f06, (q15_t)0x7f06, (q15_t)0x7f05, (q15_t)0x7f04, (q15_t)0x7f03, + (q15_t)0x7f02, (q15_t)0x7f02, (q15_t)0x7f01, (q15_t)0x7f00, (q15_t)0x7eff, (q15_t)0x7eff, (q15_t)0x7efe, (q15_t)0x7efd, + (q15_t)0x7efc, (q15_t)0x7efb, (q15_t)0x7efb, (q15_t)0x7efa, (q15_t)0x7ef9, (q15_t)0x7ef8, (q15_t)0x7ef7, (q15_t)0x7ef7, + (q15_t)0x7ef6, (q15_t)0x7ef5, (q15_t)0x7ef4, (q15_t)0x7ef3, (q15_t)0x7ef3, (q15_t)0x7ef2, (q15_t)0x7ef1, (q15_t)0x7ef0, + (q15_t)0x7eef, (q15_t)0x7eef, (q15_t)0x7eee, (q15_t)0x7eed, (q15_t)0x7eec, (q15_t)0x7eeb, (q15_t)0x7eeb, (q15_t)0x7eea, + (q15_t)0x7ee9, (q15_t)0x7ee8, (q15_t)0x7ee7, (q15_t)0x7ee6, (q15_t)0x7ee6, (q15_t)0x7ee5, (q15_t)0x7ee4, (q15_t)0x7ee3, + (q15_t)0x7ee2, (q15_t)0x7ee2, (q15_t)0x7ee1, (q15_t)0x7ee0, (q15_t)0x7edf, (q15_t)0x7ede, (q15_t)0x7edd, (q15_t)0x7edd, + (q15_t)0x7edc, (q15_t)0x7edb, (q15_t)0x7eda, (q15_t)0x7ed9, (q15_t)0x7ed8, (q15_t)0x7ed8, (q15_t)0x7ed7, (q15_t)0x7ed6, + (q15_t)0x7ed5, (q15_t)0x7ed4, (q15_t)0x7ed3, (q15_t)0x7ed2, (q15_t)0x7ed2, (q15_t)0x7ed1, (q15_t)0x7ed0, (q15_t)0x7ecf, + (q15_t)0x7ece, (q15_t)0x7ecd, (q15_t)0x7ecc, (q15_t)0x7ecc, (q15_t)0x7ecb, (q15_t)0x7eca, (q15_t)0x7ec9, (q15_t)0x7ec8, + (q15_t)0x7ec7, (q15_t)0x7ec6, (q15_t)0x7ec6, (q15_t)0x7ec5, (q15_t)0x7ec4, (q15_t)0x7ec3, (q15_t)0x7ec2, (q15_t)0x7ec1, + (q15_t)0x7ec0, (q15_t)0x7ebf, (q15_t)0x7ebf, (q15_t)0x7ebe, (q15_t)0x7ebd, (q15_t)0x7ebc, (q15_t)0x7ebb, (q15_t)0x7eba, + (q15_t)0x7eb9, (q15_t)0x7eb8, (q15_t)0x7eb8, (q15_t)0x7eb7, (q15_t)0x7eb6, (q15_t)0x7eb5, (q15_t)0x7eb4, (q15_t)0x7eb3, + (q15_t)0x7eb2, (q15_t)0x7eb1, (q15_t)0x7eb0, (q15_t)0x7eaf, (q15_t)0x7eaf, (q15_t)0x7eae, (q15_t)0x7ead, (q15_t)0x7eac, + (q15_t)0x7eab, (q15_t)0x7eaa, (q15_t)0x7ea9, (q15_t)0x7ea8, (q15_t)0x7ea7, (q15_t)0x7ea6, (q15_t)0x7ea6, (q15_t)0x7ea5, + (q15_t)0x7ea4, (q15_t)0x7ea3, (q15_t)0x7ea2, (q15_t)0x7ea1, (q15_t)0x7ea0, (q15_t)0x7e9f, (q15_t)0x7e9e, (q15_t)0x7e9d, + (q15_t)0x7e9c, (q15_t)0x7e9b, (q15_t)0x7e9b, (q15_t)0x7e9a, (q15_t)0x7e99, (q15_t)0x7e98, (q15_t)0x7e97, (q15_t)0x7e96, + (q15_t)0x7e95, (q15_t)0x7e94, (q15_t)0x7e93, (q15_t)0x7e92, (q15_t)0x7e91, (q15_t)0x7e90, (q15_t)0x7e8f, (q15_t)0x7e8e, + (q15_t)0x7e8d, (q15_t)0x7e8d, (q15_t)0x7e8c, (q15_t)0x7e8b, (q15_t)0x7e8a, (q15_t)0x7e89, (q15_t)0x7e88, (q15_t)0x7e87, + (q15_t)0x7e86, (q15_t)0x7e85, (q15_t)0x7e84, (q15_t)0x7e83, (q15_t)0x7e82, (q15_t)0x7e81, (q15_t)0x7e80, (q15_t)0x7e7f, + (q15_t)0x7e7e, (q15_t)0x7e7d, (q15_t)0x7e7c, (q15_t)0x7e7b, (q15_t)0x7e7a, (q15_t)0x7e79, (q15_t)0x7e78, (q15_t)0x7e77, + (q15_t)0x7e77, (q15_t)0x7e76, (q15_t)0x7e75, (q15_t)0x7e74, (q15_t)0x7e73, (q15_t)0x7e72, (q15_t)0x7e71, (q15_t)0x7e70, + (q15_t)0x7e6f, (q15_t)0x7e6e, (q15_t)0x7e6d, (q15_t)0x7e6c, (q15_t)0x7e6b, (q15_t)0x7e6a, (q15_t)0x7e69, (q15_t)0x7e68, + (q15_t)0x7e67, (q15_t)0x7e66, (q15_t)0x7e65, (q15_t)0x7e64, (q15_t)0x7e63, (q15_t)0x7e62, (q15_t)0x7e61, (q15_t)0x7e60, + (q15_t)0x7e5f, (q15_t)0x7e5e, (q15_t)0x7e5d, (q15_t)0x7e5c, (q15_t)0x7e5b, (q15_t)0x7e5a, (q15_t)0x7e59, (q15_t)0x7e58, + (q15_t)0x7e57, (q15_t)0x7e56, (q15_t)0x7e55, (q15_t)0x7e54, (q15_t)0x7e53, (q15_t)0x7e52, (q15_t)0x7e51, (q15_t)0x7e50, + (q15_t)0x7e4f, (q15_t)0x7e4e, (q15_t)0x7e4d, (q15_t)0x7e4c, (q15_t)0x7e4b, (q15_t)0x7e4a, (q15_t)0x7e49, (q15_t)0x7e48, + (q15_t)0x7e47, (q15_t)0x7e46, (q15_t)0x7e45, (q15_t)0x7e43, (q15_t)0x7e42, (q15_t)0x7e41, (q15_t)0x7e40, (q15_t)0x7e3f, + (q15_t)0x7e3e, (q15_t)0x7e3d, (q15_t)0x7e3c, (q15_t)0x7e3b, (q15_t)0x7e3a, (q15_t)0x7e39, (q15_t)0x7e38, (q15_t)0x7e37, + (q15_t)0x7e36, (q15_t)0x7e35, (q15_t)0x7e34, (q15_t)0x7e33, (q15_t)0x7e32, (q15_t)0x7e31, (q15_t)0x7e30, (q15_t)0x7e2f, + (q15_t)0x7e2e, (q15_t)0x7e2d, (q15_t)0x7e2b, (q15_t)0x7e2a, (q15_t)0x7e29, (q15_t)0x7e28, (q15_t)0x7e27, (q15_t)0x7e26, + (q15_t)0x7e25, (q15_t)0x7e24, (q15_t)0x7e23, (q15_t)0x7e22, (q15_t)0x7e21, (q15_t)0x7e20, (q15_t)0x7e1f, (q15_t)0x7e1e, + (q15_t)0x7e1d, (q15_t)0x7e1b, (q15_t)0x7e1a, (q15_t)0x7e19, (q15_t)0x7e18, (q15_t)0x7e17, (q15_t)0x7e16, (q15_t)0x7e15, + (q15_t)0x7e14, (q15_t)0x7e13, (q15_t)0x7e12, (q15_t)0x7e11, (q15_t)0x7e10, (q15_t)0x7e0e, (q15_t)0x7e0d, (q15_t)0x7e0c, + (q15_t)0x7e0b, (q15_t)0x7e0a, (q15_t)0x7e09, (q15_t)0x7e08, (q15_t)0x7e07, (q15_t)0x7e06, (q15_t)0x7e05, (q15_t)0x7e04, + (q15_t)0x7e02, (q15_t)0x7e01, (q15_t)0x7e00, (q15_t)0x7dff, (q15_t)0x7dfe, (q15_t)0x7dfd, (q15_t)0x7dfc, (q15_t)0x7dfb, + (q15_t)0x7dfa, (q15_t)0x7df8, (q15_t)0x7df7, (q15_t)0x7df6, (q15_t)0x7df5, (q15_t)0x7df4, (q15_t)0x7df3, (q15_t)0x7df2, + (q15_t)0x7df1, (q15_t)0x7def, (q15_t)0x7dee, (q15_t)0x7ded, (q15_t)0x7dec, (q15_t)0x7deb, (q15_t)0x7dea, (q15_t)0x7de9, + (q15_t)0x7de8, (q15_t)0x7de6, (q15_t)0x7de5, (q15_t)0x7de4, (q15_t)0x7de3, (q15_t)0x7de2, (q15_t)0x7de1, (q15_t)0x7de0, + (q15_t)0x7dde, (q15_t)0x7ddd, (q15_t)0x7ddc, (q15_t)0x7ddb, (q15_t)0x7dda, (q15_t)0x7dd9, (q15_t)0x7dd8, (q15_t)0x7dd6, + (q15_t)0x7dd5, (q15_t)0x7dd4, (q15_t)0x7dd3, (q15_t)0x7dd2, (q15_t)0x7dd1, (q15_t)0x7dd0, (q15_t)0x7dce, (q15_t)0x7dcd, + (q15_t)0x7dcc, (q15_t)0x7dcb, (q15_t)0x7dca, (q15_t)0x7dc9, (q15_t)0x7dc7, (q15_t)0x7dc6, (q15_t)0x7dc5, (q15_t)0x7dc4, + (q15_t)0x7dc3, (q15_t)0x7dc2, (q15_t)0x7dc0, (q15_t)0x7dbf, (q15_t)0x7dbe, (q15_t)0x7dbd, (q15_t)0x7dbc, (q15_t)0x7dbb, + (q15_t)0x7db9, (q15_t)0x7db8, (q15_t)0x7db7, (q15_t)0x7db6, (q15_t)0x7db5, (q15_t)0x7db3, (q15_t)0x7db2, (q15_t)0x7db1, + (q15_t)0x7db0, (q15_t)0x7daf, (q15_t)0x7dae, (q15_t)0x7dac, (q15_t)0x7dab, (q15_t)0x7daa, (q15_t)0x7da9, (q15_t)0x7da8, + (q15_t)0x7da6, (q15_t)0x7da5, (q15_t)0x7da4, (q15_t)0x7da3, (q15_t)0x7da2, (q15_t)0x7da0, (q15_t)0x7d9f, (q15_t)0x7d9e, + (q15_t)0x7d9d, (q15_t)0x7d9c, (q15_t)0x7d9a, (q15_t)0x7d99, (q15_t)0x7d98, (q15_t)0x7d97, (q15_t)0x7d95, (q15_t)0x7d94, + (q15_t)0x7d93, (q15_t)0x7d92, (q15_t)0x7d91, (q15_t)0x7d8f, (q15_t)0x7d8e, (q15_t)0x7d8d, (q15_t)0x7d8c, (q15_t)0x7d8a, + (q15_t)0x7d89, (q15_t)0x7d88, (q15_t)0x7d87, (q15_t)0x7d86, (q15_t)0x7d84, (q15_t)0x7d83, (q15_t)0x7d82, (q15_t)0x7d81, + (q15_t)0x7d7f, (q15_t)0x7d7e, (q15_t)0x7d7d, (q15_t)0x7d7c, (q15_t)0x7d7a, (q15_t)0x7d79, (q15_t)0x7d78, (q15_t)0x7d77, + (q15_t)0x7d75, (q15_t)0x7d74, (q15_t)0x7d73, (q15_t)0x7d72, (q15_t)0x7d70, (q15_t)0x7d6f, (q15_t)0x7d6e, (q15_t)0x7d6d, + (q15_t)0x7d6b, (q15_t)0x7d6a, (q15_t)0x7d69, (q15_t)0x7d68, (q15_t)0x7d66, (q15_t)0x7d65, (q15_t)0x7d64, (q15_t)0x7d63, + (q15_t)0x7d61, (q15_t)0x7d60, (q15_t)0x7d5f, (q15_t)0x7d5e, (q15_t)0x7d5c, (q15_t)0x7d5b, (q15_t)0x7d5a, (q15_t)0x7d59, + (q15_t)0x7d57, (q15_t)0x7d56, (q15_t)0x7d55, (q15_t)0x7d53, (q15_t)0x7d52, (q15_t)0x7d51, (q15_t)0x7d50, (q15_t)0x7d4e, + (q15_t)0x7d4d, (q15_t)0x7d4c, (q15_t)0x7d4a, (q15_t)0x7d49, (q15_t)0x7d48, (q15_t)0x7d47, (q15_t)0x7d45, (q15_t)0x7d44, + (q15_t)0x7d43, (q15_t)0x7d41, (q15_t)0x7d40, (q15_t)0x7d3f, (q15_t)0x7d3e, (q15_t)0x7d3c, (q15_t)0x7d3b, (q15_t)0x7d3a, + (q15_t)0x7d38, (q15_t)0x7d37, (q15_t)0x7d36, (q15_t)0x7d34, (q15_t)0x7d33, (q15_t)0x7d32, (q15_t)0x7d31, (q15_t)0x7d2f, + (q15_t)0x7d2e, (q15_t)0x7d2d, (q15_t)0x7d2b, (q15_t)0x7d2a, (q15_t)0x7d29, (q15_t)0x7d27, (q15_t)0x7d26, (q15_t)0x7d25, + (q15_t)0x7d23, (q15_t)0x7d22, (q15_t)0x7d21, (q15_t)0x7d1f, (q15_t)0x7d1e, (q15_t)0x7d1d, (q15_t)0x7d1b, (q15_t)0x7d1a, + (q15_t)0x7d19, (q15_t)0x7d17, (q15_t)0x7d16, (q15_t)0x7d15, (q15_t)0x7d13, (q15_t)0x7d12, (q15_t)0x7d11, (q15_t)0x7d0f, + (q15_t)0x7d0e, (q15_t)0x7d0d, (q15_t)0x7d0b, (q15_t)0x7d0a, (q15_t)0x7d09, (q15_t)0x7d07, (q15_t)0x7d06, (q15_t)0x7d05, + (q15_t)0x7d03, (q15_t)0x7d02, (q15_t)0x7d01, (q15_t)0x7cff, (q15_t)0x7cfe, (q15_t)0x7cfd, (q15_t)0x7cfb, (q15_t)0x7cfa, + (q15_t)0x7cf9, (q15_t)0x7cf7, (q15_t)0x7cf6, (q15_t)0x7cf4, (q15_t)0x7cf3, (q15_t)0x7cf2, (q15_t)0x7cf0, (q15_t)0x7cef, + (q15_t)0x7cee, (q15_t)0x7cec, (q15_t)0x7ceb, (q15_t)0x7ce9, (q15_t)0x7ce8, (q15_t)0x7ce7, (q15_t)0x7ce5, (q15_t)0x7ce4, + (q15_t)0x7ce3, (q15_t)0x7ce1, (q15_t)0x7ce0, (q15_t)0x7cde, (q15_t)0x7cdd, (q15_t)0x7cdc, (q15_t)0x7cda, (q15_t)0x7cd9, + (q15_t)0x7cd8, (q15_t)0x7cd6, (q15_t)0x7cd5, (q15_t)0x7cd3, (q15_t)0x7cd2, (q15_t)0x7cd1, (q15_t)0x7ccf, (q15_t)0x7cce, + (q15_t)0x7ccc, (q15_t)0x7ccb, (q15_t)0x7cca, (q15_t)0x7cc8, (q15_t)0x7cc7, (q15_t)0x7cc5, (q15_t)0x7cc4, (q15_t)0x7cc3, + (q15_t)0x7cc1, (q15_t)0x7cc0, (q15_t)0x7cbe, (q15_t)0x7cbd, (q15_t)0x7cbc, (q15_t)0x7cba, (q15_t)0x7cb9, (q15_t)0x7cb7, + (q15_t)0x7cb6, (q15_t)0x7cb5, (q15_t)0x7cb3, (q15_t)0x7cb2, (q15_t)0x7cb0, (q15_t)0x7caf, (q15_t)0x7cad, (q15_t)0x7cac, + (q15_t)0x7cab, (q15_t)0x7ca9, (q15_t)0x7ca8, (q15_t)0x7ca6, (q15_t)0x7ca5, (q15_t)0x7ca3, (q15_t)0x7ca2, (q15_t)0x7ca1, + (q15_t)0x7c9f, (q15_t)0x7c9e, (q15_t)0x7c9c, (q15_t)0x7c9b, (q15_t)0x7c99, (q15_t)0x7c98, (q15_t)0x7c97, (q15_t)0x7c95, + (q15_t)0x7c94, (q15_t)0x7c92, (q15_t)0x7c91, (q15_t)0x7c8f, (q15_t)0x7c8e, (q15_t)0x7c8c, (q15_t)0x7c8b, (q15_t)0x7c8a, + (q15_t)0x7c88, (q15_t)0x7c87, (q15_t)0x7c85, (q15_t)0x7c84, (q15_t)0x7c82, (q15_t)0x7c81, (q15_t)0x7c7f, (q15_t)0x7c7e, + (q15_t)0x7c7c, (q15_t)0x7c7b, (q15_t)0x7c79, (q15_t)0x7c78, (q15_t)0x7c77, (q15_t)0x7c75, (q15_t)0x7c74, (q15_t)0x7c72, + (q15_t)0x7c71, (q15_t)0x7c6f, (q15_t)0x7c6e, (q15_t)0x7c6c, (q15_t)0x7c6b, (q15_t)0x7c69, (q15_t)0x7c68, (q15_t)0x7c66, + (q15_t)0x7c65, (q15_t)0x7c63, (q15_t)0x7c62, (q15_t)0x7c60, (q15_t)0x7c5f, (q15_t)0x7c5d, (q15_t)0x7c5c, (q15_t)0x7c5a, + (q15_t)0x7c59, (q15_t)0x7c58, (q15_t)0x7c56, (q15_t)0x7c55, (q15_t)0x7c53, (q15_t)0x7c52, (q15_t)0x7c50, (q15_t)0x7c4f, + (q15_t)0x7c4d, (q15_t)0x7c4c, (q15_t)0x7c4a, (q15_t)0x7c49, (q15_t)0x7c47, (q15_t)0x7c46, (q15_t)0x7c44, (q15_t)0x7c43, + (q15_t)0x7c41, (q15_t)0x7c3f, (q15_t)0x7c3e, (q15_t)0x7c3c, (q15_t)0x7c3b, (q15_t)0x7c39, (q15_t)0x7c38, (q15_t)0x7c36, + (q15_t)0x7c35, (q15_t)0x7c33, (q15_t)0x7c32, (q15_t)0x7c30, (q15_t)0x7c2f, (q15_t)0x7c2d, (q15_t)0x7c2c, (q15_t)0x7c2a, + (q15_t)0x7c29, (q15_t)0x7c27, (q15_t)0x7c26, (q15_t)0x7c24, (q15_t)0x7c23, (q15_t)0x7c21, (q15_t)0x7c20, (q15_t)0x7c1e, + (q15_t)0x7c1c, (q15_t)0x7c1b, (q15_t)0x7c19, (q15_t)0x7c18, (q15_t)0x7c16, (q15_t)0x7c15, (q15_t)0x7c13, (q15_t)0x7c12, + (q15_t)0x7c10, (q15_t)0x7c0f, (q15_t)0x7c0d, (q15_t)0x7c0b, (q15_t)0x7c0a, (q15_t)0x7c08, (q15_t)0x7c07, (q15_t)0x7c05, + (q15_t)0x7c04, (q15_t)0x7c02, (q15_t)0x7c01, (q15_t)0x7bff, (q15_t)0x7bfd, (q15_t)0x7bfc, (q15_t)0x7bfa, (q15_t)0x7bf9, + (q15_t)0x7bf7, (q15_t)0x7bf6, (q15_t)0x7bf4, (q15_t)0x7bf3, (q15_t)0x7bf1, (q15_t)0x7bef, (q15_t)0x7bee, (q15_t)0x7bec, + (q15_t)0x7beb, (q15_t)0x7be9, (q15_t)0x7be8, (q15_t)0x7be6, (q15_t)0x7be4, (q15_t)0x7be3, (q15_t)0x7be1, (q15_t)0x7be0, + (q15_t)0x7bde, (q15_t)0x7bdc, (q15_t)0x7bdb, (q15_t)0x7bd9, (q15_t)0x7bd8, (q15_t)0x7bd6, (q15_t)0x7bd5, (q15_t)0x7bd3, + (q15_t)0x7bd1, (q15_t)0x7bd0, (q15_t)0x7bce, (q15_t)0x7bcd, (q15_t)0x7bcb, (q15_t)0x7bc9, (q15_t)0x7bc8, (q15_t)0x7bc6, + (q15_t)0x7bc5, (q15_t)0x7bc3, (q15_t)0x7bc1, (q15_t)0x7bc0, (q15_t)0x7bbe, (q15_t)0x7bbd, (q15_t)0x7bbb, (q15_t)0x7bb9, + (q15_t)0x7bb8, (q15_t)0x7bb6, (q15_t)0x7bb5, (q15_t)0x7bb3, (q15_t)0x7bb1, (q15_t)0x7bb0, (q15_t)0x7bae, (q15_t)0x7bac, + (q15_t)0x7bab, (q15_t)0x7ba9, (q15_t)0x7ba8, (q15_t)0x7ba6, (q15_t)0x7ba4, (q15_t)0x7ba3, (q15_t)0x7ba1, (q15_t)0x7b9f, + (q15_t)0x7b9e, (q15_t)0x7b9c, (q15_t)0x7b9b, (q15_t)0x7b99, (q15_t)0x7b97, (q15_t)0x7b96, (q15_t)0x7b94, (q15_t)0x7b92, + (q15_t)0x7b91, (q15_t)0x7b8f, (q15_t)0x7b8d, (q15_t)0x7b8c, (q15_t)0x7b8a, (q15_t)0x7b89, (q15_t)0x7b87, (q15_t)0x7b85, + (q15_t)0x7b84, (q15_t)0x7b82, (q15_t)0x7b80, (q15_t)0x7b7f, (q15_t)0x7b7d, (q15_t)0x7b7b, (q15_t)0x7b7a, (q15_t)0x7b78, + (q15_t)0x7b76, (q15_t)0x7b75, (q15_t)0x7b73, (q15_t)0x7b71, (q15_t)0x7b70, (q15_t)0x7b6e, (q15_t)0x7b6c, (q15_t)0x7b6b, + (q15_t)0x7b69, (q15_t)0x7b67, (q15_t)0x7b66, (q15_t)0x7b64, (q15_t)0x7b62, (q15_t)0x7b61, (q15_t)0x7b5f, (q15_t)0x7b5d, + (q15_t)0x7b5c, (q15_t)0x7b5a, (q15_t)0x7b58, (q15_t)0x7b57, (q15_t)0x7b55, (q15_t)0x7b53, (q15_t)0x7b52, (q15_t)0x7b50, + (q15_t)0x7b4e, (q15_t)0x7b4d, (q15_t)0x7b4b, (q15_t)0x7b49, (q15_t)0x7b47, (q15_t)0x7b46, (q15_t)0x7b44, (q15_t)0x7b42, + (q15_t)0x7b41, (q15_t)0x7b3f, (q15_t)0x7b3d, (q15_t)0x7b3c, (q15_t)0x7b3a, (q15_t)0x7b38, (q15_t)0x7b37, (q15_t)0x7b35, + (q15_t)0x7b33, (q15_t)0x7b31, (q15_t)0x7b30, (q15_t)0x7b2e, (q15_t)0x7b2c, (q15_t)0x7b2b, (q15_t)0x7b29, (q15_t)0x7b27, + (q15_t)0x7b25, (q15_t)0x7b24, (q15_t)0x7b22, (q15_t)0x7b20, (q15_t)0x7b1f, (q15_t)0x7b1d, (q15_t)0x7b1b, (q15_t)0x7b19, + (q15_t)0x7b18, (q15_t)0x7b16, (q15_t)0x7b14, (q15_t)0x7b13, (q15_t)0x7b11, (q15_t)0x7b0f, (q15_t)0x7b0d, (q15_t)0x7b0c, + (q15_t)0x7b0a, (q15_t)0x7b08, (q15_t)0x7b06, (q15_t)0x7b05, (q15_t)0x7b03, (q15_t)0x7b01, (q15_t)0x7aff, (q15_t)0x7afe, + (q15_t)0x7afc, (q15_t)0x7afa, (q15_t)0x7af8, (q15_t)0x7af7, (q15_t)0x7af5, (q15_t)0x7af3, (q15_t)0x7af2, (q15_t)0x7af0, + (q15_t)0x7aee, (q15_t)0x7aec, (q15_t)0x7aeb, (q15_t)0x7ae9, (q15_t)0x7ae7, (q15_t)0x7ae5, (q15_t)0x7ae3, (q15_t)0x7ae2, + (q15_t)0x7ae0, (q15_t)0x7ade, (q15_t)0x7adc, (q15_t)0x7adb, (q15_t)0x7ad9, (q15_t)0x7ad7, (q15_t)0x7ad5, (q15_t)0x7ad4, + (q15_t)0x7ad2, (q15_t)0x7ad0, (q15_t)0x7ace, (q15_t)0x7acd, (q15_t)0x7acb, (q15_t)0x7ac9, (q15_t)0x7ac7, (q15_t)0x7ac5, + (q15_t)0x7ac4, (q15_t)0x7ac2, (q15_t)0x7ac0, (q15_t)0x7abe, (q15_t)0x7abd, (q15_t)0x7abb, (q15_t)0x7ab9, (q15_t)0x7ab7, + (q15_t)0x7ab5, (q15_t)0x7ab4, (q15_t)0x7ab2, (q15_t)0x7ab0, (q15_t)0x7aae, (q15_t)0x7aac, (q15_t)0x7aab, (q15_t)0x7aa9, + (q15_t)0x7aa7, (q15_t)0x7aa5, (q15_t)0x7aa3, (q15_t)0x7aa2, (q15_t)0x7aa0, (q15_t)0x7a9e, (q15_t)0x7a9c, (q15_t)0x7a9a, + (q15_t)0x7a99, (q15_t)0x7a97, (q15_t)0x7a95, (q15_t)0x7a93, (q15_t)0x7a91, (q15_t)0x7a90, (q15_t)0x7a8e, (q15_t)0x7a8c, + (q15_t)0x7a8a, (q15_t)0x7a88, (q15_t)0x7a87, (q15_t)0x7a85, (q15_t)0x7a83, (q15_t)0x7a81, (q15_t)0x7a7f, (q15_t)0x7a7d, + (q15_t)0x7a7c, (q15_t)0x7a7a, (q15_t)0x7a78, (q15_t)0x7a76, (q15_t)0x7a74, (q15_t)0x7a72, (q15_t)0x7a71, (q15_t)0x7a6f, + (q15_t)0x7a6d, (q15_t)0x7a6b, (q15_t)0x7a69, (q15_t)0x7a67, (q15_t)0x7a66, (q15_t)0x7a64, (q15_t)0x7a62, (q15_t)0x7a60, + (q15_t)0x7a5e, (q15_t)0x7a5c, (q15_t)0x7a5b, (q15_t)0x7a59, (q15_t)0x7a57, (q15_t)0x7a55, (q15_t)0x7a53, (q15_t)0x7a51, + (q15_t)0x7a4f, (q15_t)0x7a4e, (q15_t)0x7a4c, (q15_t)0x7a4a, (q15_t)0x7a48, (q15_t)0x7a46, (q15_t)0x7a44, (q15_t)0x7a42, + (q15_t)0x7a41, (q15_t)0x7a3f, (q15_t)0x7a3d, (q15_t)0x7a3b, (q15_t)0x7a39, (q15_t)0x7a37, (q15_t)0x7a35, (q15_t)0x7a34, + (q15_t)0x7a32, (q15_t)0x7a30, (q15_t)0x7a2e, (q15_t)0x7a2c, (q15_t)0x7a2a, (q15_t)0x7a28, (q15_t)0x7a26, (q15_t)0x7a25, + (q15_t)0x7a23, (q15_t)0x7a21, (q15_t)0x7a1f, (q15_t)0x7a1d, (q15_t)0x7a1b, (q15_t)0x7a19, (q15_t)0x7a17, (q15_t)0x7a16, + (q15_t)0x7a14, (q15_t)0x7a12, (q15_t)0x7a10, (q15_t)0x7a0e, (q15_t)0x7a0c, (q15_t)0x7a0a, (q15_t)0x7a08, (q15_t)0x7a06, + (q15_t)0x7a04, (q15_t)0x7a03, (q15_t)0x7a01, (q15_t)0x79ff, (q15_t)0x79fd, (q15_t)0x79fb, (q15_t)0x79f9, (q15_t)0x79f7, + (q15_t)0x79f5, (q15_t)0x79f3, (q15_t)0x79f1, (q15_t)0x79f0, (q15_t)0x79ee, (q15_t)0x79ec, (q15_t)0x79ea, (q15_t)0x79e8, + (q15_t)0x79e6, (q15_t)0x79e4, (q15_t)0x79e2, (q15_t)0x79e0, (q15_t)0x79de, (q15_t)0x79dc, (q15_t)0x79da, (q15_t)0x79d9, + (q15_t)0x79d7, (q15_t)0x79d5, (q15_t)0x79d3, (q15_t)0x79d1, (q15_t)0x79cf, (q15_t)0x79cd, (q15_t)0x79cb, (q15_t)0x79c9, + (q15_t)0x79c7, (q15_t)0x79c5, (q15_t)0x79c3, (q15_t)0x79c1, (q15_t)0x79bf, (q15_t)0x79bd, (q15_t)0x79bc, (q15_t)0x79ba, + (q15_t)0x79b8, (q15_t)0x79b6, (q15_t)0x79b4, (q15_t)0x79b2, (q15_t)0x79b0, (q15_t)0x79ae, (q15_t)0x79ac, (q15_t)0x79aa, + (q15_t)0x79a8, (q15_t)0x79a6, (q15_t)0x79a4, (q15_t)0x79a2, (q15_t)0x79a0, (q15_t)0x799e, (q15_t)0x799c, (q15_t)0x799a, + (q15_t)0x7998, (q15_t)0x7996, (q15_t)0x7994, (q15_t)0x7992, (q15_t)0x7991, (q15_t)0x798f, (q15_t)0x798d, (q15_t)0x798b, + (q15_t)0x7989, (q15_t)0x7987, (q15_t)0x7985, (q15_t)0x7983, (q15_t)0x7981, (q15_t)0x797f, (q15_t)0x797d, (q15_t)0x797b, + (q15_t)0x7979, (q15_t)0x7977, (q15_t)0x7975, (q15_t)0x7973, (q15_t)0x7971, (q15_t)0x796f, (q15_t)0x796d, (q15_t)0x796b, + (q15_t)0x7969, (q15_t)0x7967, (q15_t)0x7965, (q15_t)0x7963, (q15_t)0x7961, (q15_t)0x795f, (q15_t)0x795d, (q15_t)0x795b, + (q15_t)0x7959, (q15_t)0x7957, (q15_t)0x7955, (q15_t)0x7953, (q15_t)0x7951, (q15_t)0x794f, (q15_t)0x794d, (q15_t)0x794b, + (q15_t)0x7949, (q15_t)0x7947, (q15_t)0x7945, (q15_t)0x7943, (q15_t)0x7941, (q15_t)0x793f, (q15_t)0x793d, (q15_t)0x793b, + (q15_t)0x7939, (q15_t)0x7937, (q15_t)0x7935, (q15_t)0x7933, (q15_t)0x7931, (q15_t)0x792f, (q15_t)0x792d, (q15_t)0x792b, + (q15_t)0x7929, (q15_t)0x7927, (q15_t)0x7925, (q15_t)0x7923, (q15_t)0x7921, (q15_t)0x791f, (q15_t)0x791d, (q15_t)0x791a, + (q15_t)0x7918, (q15_t)0x7916, (q15_t)0x7914, (q15_t)0x7912, (q15_t)0x7910, (q15_t)0x790e, (q15_t)0x790c, (q15_t)0x790a, + (q15_t)0x7908, (q15_t)0x7906, (q15_t)0x7904, (q15_t)0x7902, (q15_t)0x7900, (q15_t)0x78fe, (q15_t)0x78fc, (q15_t)0x78fa, + (q15_t)0x78f8, (q15_t)0x78f6, (q15_t)0x78f4, (q15_t)0x78f2, (q15_t)0x78f0, (q15_t)0x78ed, (q15_t)0x78eb, (q15_t)0x78e9, + (q15_t)0x78e7, (q15_t)0x78e5, (q15_t)0x78e3, (q15_t)0x78e1, (q15_t)0x78df, (q15_t)0x78dd, (q15_t)0x78db, (q15_t)0x78d9, + (q15_t)0x78d7, (q15_t)0x78d5, (q15_t)0x78d3, (q15_t)0x78d1, (q15_t)0x78ce, (q15_t)0x78cc, (q15_t)0x78ca, (q15_t)0x78c8, + (q15_t)0x78c6, (q15_t)0x78c4, (q15_t)0x78c2, (q15_t)0x78c0, (q15_t)0x78be, (q15_t)0x78bc, (q15_t)0x78ba, (q15_t)0x78b8, + (q15_t)0x78b5, (q15_t)0x78b3, (q15_t)0x78b1, (q15_t)0x78af, (q15_t)0x78ad, (q15_t)0x78ab, (q15_t)0x78a9, (q15_t)0x78a7, + (q15_t)0x78a5, (q15_t)0x78a3, (q15_t)0x78a0, (q15_t)0x789e, (q15_t)0x789c, (q15_t)0x789a, (q15_t)0x7898, (q15_t)0x7896, + (q15_t)0x7894, (q15_t)0x7892, (q15_t)0x7890, (q15_t)0x788e, (q15_t)0x788b, (q15_t)0x7889, (q15_t)0x7887, (q15_t)0x7885, + (q15_t)0x7883, (q15_t)0x7881, (q15_t)0x787f, (q15_t)0x787d, (q15_t)0x787a, (q15_t)0x7878, (q15_t)0x7876, (q15_t)0x7874, + (q15_t)0x7872, (q15_t)0x7870, (q15_t)0x786e, (q15_t)0x786c, (q15_t)0x7869, (q15_t)0x7867, (q15_t)0x7865, (q15_t)0x7863, + (q15_t)0x7861, (q15_t)0x785f, (q15_t)0x785d, (q15_t)0x785b, (q15_t)0x7858, (q15_t)0x7856, (q15_t)0x7854, (q15_t)0x7852, + (q15_t)0x7850, (q15_t)0x784e, (q15_t)0x784c, (q15_t)0x7849, (q15_t)0x7847, (q15_t)0x7845, (q15_t)0x7843, (q15_t)0x7841, + (q15_t)0x783f, (q15_t)0x783c, (q15_t)0x783a, (q15_t)0x7838, (q15_t)0x7836, (q15_t)0x7834, (q15_t)0x7832, (q15_t)0x7830, + (q15_t)0x782d, (q15_t)0x782b, (q15_t)0x7829, (q15_t)0x7827, (q15_t)0x7825, (q15_t)0x7823, (q15_t)0x7820, (q15_t)0x781e, + (q15_t)0x781c, (q15_t)0x781a, (q15_t)0x7818, (q15_t)0x7816, (q15_t)0x7813, (q15_t)0x7811, (q15_t)0x780f, (q15_t)0x780d, + (q15_t)0x780b, (q15_t)0x7808, (q15_t)0x7806, (q15_t)0x7804, (q15_t)0x7802, (q15_t)0x7800, (q15_t)0x77fe, (q15_t)0x77fb, + (q15_t)0x77f9, (q15_t)0x77f7, (q15_t)0x77f5, (q15_t)0x77f3, (q15_t)0x77f0, (q15_t)0x77ee, (q15_t)0x77ec, (q15_t)0x77ea, + (q15_t)0x77e8, (q15_t)0x77e5, (q15_t)0x77e3, (q15_t)0x77e1, (q15_t)0x77df, (q15_t)0x77dd, (q15_t)0x77da, (q15_t)0x77d8, + (q15_t)0x77d6, (q15_t)0x77d4, (q15_t)0x77d2, (q15_t)0x77cf, (q15_t)0x77cd, (q15_t)0x77cb, (q15_t)0x77c9, (q15_t)0x77c6, + (q15_t)0x77c4, (q15_t)0x77c2, (q15_t)0x77c0, (q15_t)0x77be, (q15_t)0x77bb, (q15_t)0x77b9, (q15_t)0x77b7, (q15_t)0x77b5, + (q15_t)0x77b2, (q15_t)0x77b0, (q15_t)0x77ae, (q15_t)0x77ac, (q15_t)0x77aa, (q15_t)0x77a7, (q15_t)0x77a5, (q15_t)0x77a3, + (q15_t)0x77a1, (q15_t)0x779e, (q15_t)0x779c, (q15_t)0x779a, (q15_t)0x7798, (q15_t)0x7795, (q15_t)0x7793, (q15_t)0x7791, + (q15_t)0x778f, (q15_t)0x778c, (q15_t)0x778a, (q15_t)0x7788, (q15_t)0x7786, (q15_t)0x7783, (q15_t)0x7781, (q15_t)0x777f, + (q15_t)0x777d, (q15_t)0x777a, (q15_t)0x7778, (q15_t)0x7776, (q15_t)0x7774, (q15_t)0x7771, (q15_t)0x776f, (q15_t)0x776d, + (q15_t)0x776b, (q15_t)0x7768, (q15_t)0x7766, (q15_t)0x7764, (q15_t)0x7762, (q15_t)0x775f, (q15_t)0x775d, (q15_t)0x775b, + (q15_t)0x7759, (q15_t)0x7756, (q15_t)0x7754, (q15_t)0x7752, (q15_t)0x774f, (q15_t)0x774d, (q15_t)0x774b, (q15_t)0x7749, + (q15_t)0x7746, (q15_t)0x7744, (q15_t)0x7742, (q15_t)0x773f, (q15_t)0x773d, (q15_t)0x773b, (q15_t)0x7739, (q15_t)0x7736, + (q15_t)0x7734, (q15_t)0x7732, (q15_t)0x772f, (q15_t)0x772d, (q15_t)0x772b, (q15_t)0x7729, (q15_t)0x7726, (q15_t)0x7724, + (q15_t)0x7722, (q15_t)0x771f, (q15_t)0x771d, (q15_t)0x771b, (q15_t)0x7719, (q15_t)0x7716, (q15_t)0x7714, (q15_t)0x7712, + (q15_t)0x770f, (q15_t)0x770d, (q15_t)0x770b, (q15_t)0x7708, (q15_t)0x7706, (q15_t)0x7704, (q15_t)0x7701, (q15_t)0x76ff, + (q15_t)0x76fd, (q15_t)0x76fa, (q15_t)0x76f8, (q15_t)0x76f6, (q15_t)0x76f4, (q15_t)0x76f1, (q15_t)0x76ef, (q15_t)0x76ed, + (q15_t)0x76ea, (q15_t)0x76e8, (q15_t)0x76e6, (q15_t)0x76e3, (q15_t)0x76e1, (q15_t)0x76df, (q15_t)0x76dc, (q15_t)0x76da, + (q15_t)0x76d8, (q15_t)0x76d5, (q15_t)0x76d3, (q15_t)0x76d1, (q15_t)0x76ce, (q15_t)0x76cc, (q15_t)0x76ca, (q15_t)0x76c7, + (q15_t)0x76c5, (q15_t)0x76c3, (q15_t)0x76c0, (q15_t)0x76be, (q15_t)0x76bc, (q15_t)0x76b9, (q15_t)0x76b7, (q15_t)0x76b4, + (q15_t)0x76b2, (q15_t)0x76b0, (q15_t)0x76ad, (q15_t)0x76ab, (q15_t)0x76a9, (q15_t)0x76a6, (q15_t)0x76a4, (q15_t)0x76a2, + (q15_t)0x769f, (q15_t)0x769d, (q15_t)0x769b, (q15_t)0x7698, (q15_t)0x7696, (q15_t)0x7693, (q15_t)0x7691, (q15_t)0x768f, + (q15_t)0x768c, (q15_t)0x768a, (q15_t)0x7688, (q15_t)0x7685, (q15_t)0x7683, (q15_t)0x7681, (q15_t)0x767e, (q15_t)0x767c, + (q15_t)0x7679, (q15_t)0x7677, (q15_t)0x7675, (q15_t)0x7672, (q15_t)0x7670, (q15_t)0x766d, (q15_t)0x766b, (q15_t)0x7669, + (q15_t)0x7666, (q15_t)0x7664, (q15_t)0x7662, (q15_t)0x765f, (q15_t)0x765d, (q15_t)0x765a, (q15_t)0x7658, (q15_t)0x7656, + (q15_t)0x7653, (q15_t)0x7651, (q15_t)0x764e, (q15_t)0x764c, (q15_t)0x764a, (q15_t)0x7647, (q15_t)0x7645, (q15_t)0x7642, + (q15_t)0x7640, (q15_t)0x763e, (q15_t)0x763b, (q15_t)0x7639, (q15_t)0x7636, (q15_t)0x7634, (q15_t)0x7632, (q15_t)0x762f, + (q15_t)0x762d, (q15_t)0x762a, (q15_t)0x7628, (q15_t)0x7625, (q15_t)0x7623, (q15_t)0x7621, (q15_t)0x761e, (q15_t)0x761c, + (q15_t)0x7619, (q15_t)0x7617, (q15_t)0x7615, (q15_t)0x7612, (q15_t)0x7610, (q15_t)0x760d, (q15_t)0x760b, (q15_t)0x7608, + (q15_t)0x7606, (q15_t)0x7604, (q15_t)0x7601, (q15_t)0x75ff, (q15_t)0x75fc, (q15_t)0x75fa, (q15_t)0x75f7, (q15_t)0x75f5, + (q15_t)0x75f2, (q15_t)0x75f0, (q15_t)0x75ee, (q15_t)0x75eb, (q15_t)0x75e9, (q15_t)0x75e6, (q15_t)0x75e4, (q15_t)0x75e1, + (q15_t)0x75df, (q15_t)0x75dc, (q15_t)0x75da, (q15_t)0x75d8, (q15_t)0x75d5, (q15_t)0x75d3, (q15_t)0x75d0, (q15_t)0x75ce, + (q15_t)0x75cb, (q15_t)0x75c9, (q15_t)0x75c6, (q15_t)0x75c4, (q15_t)0x75c1, (q15_t)0x75bf, (q15_t)0x75bc, (q15_t)0x75ba, + (q15_t)0x75b8, (q15_t)0x75b5, (q15_t)0x75b3, (q15_t)0x75b0, (q15_t)0x75ae, (q15_t)0x75ab, (q15_t)0x75a9, (q15_t)0x75a6, + (q15_t)0x75a4, (q15_t)0x75a1, (q15_t)0x759f, (q15_t)0x759c, (q15_t)0x759a, (q15_t)0x7597, (q15_t)0x7595, (q15_t)0x7592, + (q15_t)0x7590, (q15_t)0x758d, (q15_t)0x758b, (q15_t)0x7588, (q15_t)0x7586, (q15_t)0x7584, (q15_t)0x7581, (q15_t)0x757f, + (q15_t)0x757c, (q15_t)0x757a, (q15_t)0x7577, (q15_t)0x7575, (q15_t)0x7572, (q15_t)0x7570, (q15_t)0x756d, (q15_t)0x756b, + (q15_t)0x7568, (q15_t)0x7566, (q15_t)0x7563, (q15_t)0x7561, (q15_t)0x755e, (q15_t)0x755c, (q15_t)0x7559, (q15_t)0x7556, + (q15_t)0x7554, (q15_t)0x7551, (q15_t)0x754f, (q15_t)0x754c, (q15_t)0x754a, (q15_t)0x7547, (q15_t)0x7545, (q15_t)0x7542, + (q15_t)0x7540, (q15_t)0x753d, (q15_t)0x753b, (q15_t)0x7538, (q15_t)0x7536, (q15_t)0x7533, (q15_t)0x7531, (q15_t)0x752e, + (q15_t)0x752c, (q15_t)0x7529, (q15_t)0x7527, (q15_t)0x7524, (q15_t)0x7522, (q15_t)0x751f, (q15_t)0x751c, (q15_t)0x751a, + (q15_t)0x7517, (q15_t)0x7515, (q15_t)0x7512, (q15_t)0x7510, (q15_t)0x750d, (q15_t)0x750b, (q15_t)0x7508, (q15_t)0x7506, + (q15_t)0x7503, (q15_t)0x7501, (q15_t)0x74fe, (q15_t)0x74fb, (q15_t)0x74f9, (q15_t)0x74f6, (q15_t)0x74f4, (q15_t)0x74f1, + (q15_t)0x74ef, (q15_t)0x74ec, (q15_t)0x74ea, (q15_t)0x74e7, (q15_t)0x74e4, (q15_t)0x74e2, (q15_t)0x74df, (q15_t)0x74dd, + (q15_t)0x74da, (q15_t)0x74d8, (q15_t)0x74d5, (q15_t)0x74d2, (q15_t)0x74d0, (q15_t)0x74cd, (q15_t)0x74cb, (q15_t)0x74c8, + (q15_t)0x74c6, (q15_t)0x74c3, (q15_t)0x74c0, (q15_t)0x74be, (q15_t)0x74bb, (q15_t)0x74b9, (q15_t)0x74b6, (q15_t)0x74b4, + (q15_t)0x74b1, (q15_t)0x74ae, (q15_t)0x74ac, (q15_t)0x74a9, (q15_t)0x74a7, (q15_t)0x74a4, (q15_t)0x74a1, (q15_t)0x749f, + (q15_t)0x749c, (q15_t)0x749a, (q15_t)0x7497, (q15_t)0x7495, (q15_t)0x7492, (q15_t)0x748f, (q15_t)0x748d, (q15_t)0x748a, + (q15_t)0x7488, (q15_t)0x7485, (q15_t)0x7482, (q15_t)0x7480, (q15_t)0x747d, (q15_t)0x747b, (q15_t)0x7478, (q15_t)0x7475, + (q15_t)0x7473, (q15_t)0x7470, (q15_t)0x746d, (q15_t)0x746b, (q15_t)0x7468, (q15_t)0x7466, (q15_t)0x7463, (q15_t)0x7460, + (q15_t)0x745e, (q15_t)0x745b, (q15_t)0x7459, (q15_t)0x7456, (q15_t)0x7453, (q15_t)0x7451, (q15_t)0x744e, (q15_t)0x744b, + (q15_t)0x7449, (q15_t)0x7446, (q15_t)0x7444, (q15_t)0x7441, (q15_t)0x743e, (q15_t)0x743c, (q15_t)0x7439, (q15_t)0x7436, + (q15_t)0x7434, (q15_t)0x7431, (q15_t)0x742f, (q15_t)0x742c, (q15_t)0x7429, (q15_t)0x7427, (q15_t)0x7424, (q15_t)0x7421, + (q15_t)0x741f, (q15_t)0x741c, (q15_t)0x7419, (q15_t)0x7417, (q15_t)0x7414, (q15_t)0x7411, (q15_t)0x740f, (q15_t)0x740c, + (q15_t)0x740a, (q15_t)0x7407, (q15_t)0x7404, (q15_t)0x7402, (q15_t)0x73ff, (q15_t)0x73fc, (q15_t)0x73fa, (q15_t)0x73f7, + (q15_t)0x73f4, (q15_t)0x73f2, (q15_t)0x73ef, (q15_t)0x73ec, (q15_t)0x73ea, (q15_t)0x73e7, (q15_t)0x73e4, (q15_t)0x73e2, + (q15_t)0x73df, (q15_t)0x73dc, (q15_t)0x73da, (q15_t)0x73d7, (q15_t)0x73d4, (q15_t)0x73d2, (q15_t)0x73cf, (q15_t)0x73cc, + (q15_t)0x73ca, (q15_t)0x73c7, (q15_t)0x73c4, (q15_t)0x73c1, (q15_t)0x73bf, (q15_t)0x73bc, (q15_t)0x73b9, (q15_t)0x73b7, + (q15_t)0x73b4, (q15_t)0x73b1, (q15_t)0x73af, (q15_t)0x73ac, (q15_t)0x73a9, (q15_t)0x73a7, (q15_t)0x73a4, (q15_t)0x73a1, + (q15_t)0x739f, (q15_t)0x739c, (q15_t)0x7399, (q15_t)0x7396, (q15_t)0x7394, (q15_t)0x7391, (q15_t)0x738e, (q15_t)0x738c, + (q15_t)0x7389, (q15_t)0x7386, (q15_t)0x7384, (q15_t)0x7381, (q15_t)0x737e, (q15_t)0x737b, (q15_t)0x7379, (q15_t)0x7376, + (q15_t)0x7373, (q15_t)0x7371, (q15_t)0x736e, (q15_t)0x736b, (q15_t)0x7368, (q15_t)0x7366, (q15_t)0x7363, (q15_t)0x7360, + (q15_t)0x735e, (q15_t)0x735b, (q15_t)0x7358, (q15_t)0x7355, (q15_t)0x7353, (q15_t)0x7350, (q15_t)0x734d, (q15_t)0x734a, + (q15_t)0x7348, (q15_t)0x7345, (q15_t)0x7342, (q15_t)0x7340, (q15_t)0x733d, (q15_t)0x733a, (q15_t)0x7337, (q15_t)0x7335, + (q15_t)0x7332, (q15_t)0x732f, (q15_t)0x732c, (q15_t)0x732a, (q15_t)0x7327, (q15_t)0x7324, (q15_t)0x7321, (q15_t)0x731f, + (q15_t)0x731c, (q15_t)0x7319, (q15_t)0x7316, (q15_t)0x7314, (q15_t)0x7311, (q15_t)0x730e, (q15_t)0x730b, (q15_t)0x7309, + (q15_t)0x7306, (q15_t)0x7303, (q15_t)0x7300, (q15_t)0x72fe, (q15_t)0x72fb, (q15_t)0x72f8, (q15_t)0x72f5, (q15_t)0x72f3, + (q15_t)0x72f0, (q15_t)0x72ed, (q15_t)0x72ea, (q15_t)0x72e8, (q15_t)0x72e5, (q15_t)0x72e2, (q15_t)0x72df, (q15_t)0x72dc, + (q15_t)0x72da, (q15_t)0x72d7, (q15_t)0x72d4, (q15_t)0x72d1, (q15_t)0x72cf, (q15_t)0x72cc, (q15_t)0x72c9, (q15_t)0x72c6, + (q15_t)0x72c3, (q15_t)0x72c1, (q15_t)0x72be, (q15_t)0x72bb, (q15_t)0x72b8, (q15_t)0x72b5, (q15_t)0x72b3, (q15_t)0x72b0, + (q15_t)0x72ad, (q15_t)0x72aa, (q15_t)0x72a8, (q15_t)0x72a5, (q15_t)0x72a2, (q15_t)0x729f, (q15_t)0x729c, (q15_t)0x729a, + (q15_t)0x7297, (q15_t)0x7294, (q15_t)0x7291, (q15_t)0x728e, (q15_t)0x728c, (q15_t)0x7289, (q15_t)0x7286, (q15_t)0x7283, + (q15_t)0x7280, (q15_t)0x727e, (q15_t)0x727b, (q15_t)0x7278, (q15_t)0x7275, (q15_t)0x7272, (q15_t)0x726f, (q15_t)0x726d, + (q15_t)0x726a, (q15_t)0x7267, (q15_t)0x7264, (q15_t)0x7261, (q15_t)0x725f, (q15_t)0x725c, (q15_t)0x7259, (q15_t)0x7256, + (q15_t)0x7253, (q15_t)0x7250, (q15_t)0x724e, (q15_t)0x724b, (q15_t)0x7248, (q15_t)0x7245, (q15_t)0x7242, (q15_t)0x723f, + (q15_t)0x723d, (q15_t)0x723a, (q15_t)0x7237, (q15_t)0x7234, (q15_t)0x7231, (q15_t)0x722e, (q15_t)0x722c, (q15_t)0x7229, + (q15_t)0x7226, (q15_t)0x7223, (q15_t)0x7220, (q15_t)0x721d, (q15_t)0x721b, (q15_t)0x7218, (q15_t)0x7215, (q15_t)0x7212, + (q15_t)0x720f, (q15_t)0x720c, (q15_t)0x7209, (q15_t)0x7207, (q15_t)0x7204, (q15_t)0x7201, (q15_t)0x71fe, (q15_t)0x71fb, + (q15_t)0x71f8, (q15_t)0x71f5, (q15_t)0x71f3, (q15_t)0x71f0, (q15_t)0x71ed, (q15_t)0x71ea, (q15_t)0x71e7, (q15_t)0x71e4, + (q15_t)0x71e1, (q15_t)0x71df, (q15_t)0x71dc, (q15_t)0x71d9, (q15_t)0x71d6, (q15_t)0x71d3, (q15_t)0x71d0, (q15_t)0x71cd, + (q15_t)0x71ca, (q15_t)0x71c8, (q15_t)0x71c5, (q15_t)0x71c2, (q15_t)0x71bf, (q15_t)0x71bc, (q15_t)0x71b9, (q15_t)0x71b6, + (q15_t)0x71b3, (q15_t)0x71b0, (q15_t)0x71ae, (q15_t)0x71ab, (q15_t)0x71a8, (q15_t)0x71a5, (q15_t)0x71a2, (q15_t)0x719f, + (q15_t)0x719c, (q15_t)0x7199, (q15_t)0x7196, (q15_t)0x7194, (q15_t)0x7191, (q15_t)0x718e, (q15_t)0x718b, (q15_t)0x7188, + (q15_t)0x7185, (q15_t)0x7182, (q15_t)0x717f, (q15_t)0x717c, (q15_t)0x7179, (q15_t)0x7177, (q15_t)0x7174, (q15_t)0x7171, + (q15_t)0x716e, (q15_t)0x716b, (q15_t)0x7168, (q15_t)0x7165, (q15_t)0x7162, (q15_t)0x715f, (q15_t)0x715c, (q15_t)0x7159, + (q15_t)0x7156, (q15_t)0x7154, (q15_t)0x7151, (q15_t)0x714e, (q15_t)0x714b, (q15_t)0x7148, (q15_t)0x7145, (q15_t)0x7142, + (q15_t)0x713f, (q15_t)0x713c, (q15_t)0x7139, (q15_t)0x7136, (q15_t)0x7133, (q15_t)0x7130, (q15_t)0x712d, (q15_t)0x712b, + (q15_t)0x7128, (q15_t)0x7125, (q15_t)0x7122, (q15_t)0x711f, (q15_t)0x711c, (q15_t)0x7119, (q15_t)0x7116, (q15_t)0x7113, + (q15_t)0x7110, (q15_t)0x710d, (q15_t)0x710a, (q15_t)0x7107, (q15_t)0x7104, (q15_t)0x7101, (q15_t)0x70fe, (q15_t)0x70fb, + (q15_t)0x70f8, (q15_t)0x70f6, (q15_t)0x70f3, (q15_t)0x70f0, (q15_t)0x70ed, (q15_t)0x70ea, (q15_t)0x70e7, (q15_t)0x70e4, + (q15_t)0x70e1, (q15_t)0x70de, (q15_t)0x70db, (q15_t)0x70d8, (q15_t)0x70d5, (q15_t)0x70d2, (q15_t)0x70cf, (q15_t)0x70cc, + (q15_t)0x70c9, (q15_t)0x70c6, (q15_t)0x70c3, (q15_t)0x70c0, (q15_t)0x70bd, (q15_t)0x70ba, (q15_t)0x70b7, (q15_t)0x70b4, + (q15_t)0x70b1, (q15_t)0x70ae, (q15_t)0x70ab, (q15_t)0x70a8, (q15_t)0x70a5, (q15_t)0x70a2, (q15_t)0x709f, (q15_t)0x709c, + (q15_t)0x7099, (q15_t)0x7096, (q15_t)0x7093, (q15_t)0x7090, (q15_t)0x708d, (q15_t)0x708a, (q15_t)0x7087, (q15_t)0x7084, + (q15_t)0x7081, (q15_t)0x707e, (q15_t)0x707b, (q15_t)0x7078, (q15_t)0x7075, (q15_t)0x7072, (q15_t)0x706f, (q15_t)0x706c, + (q15_t)0x7069, (q15_t)0x7066, (q15_t)0x7063, (q15_t)0x7060, (q15_t)0x705d, (q15_t)0x705a, (q15_t)0x7057, (q15_t)0x7054, + (q15_t)0x7051, (q15_t)0x704e, (q15_t)0x704b, (q15_t)0x7048, (q15_t)0x7045, (q15_t)0x7042, (q15_t)0x703f, (q15_t)0x703c, + (q15_t)0x7039, (q15_t)0x7036, (q15_t)0x7033, (q15_t)0x7030, (q15_t)0x702d, (q15_t)0x702a, (q15_t)0x7027, (q15_t)0x7024, + (q15_t)0x7021, (q15_t)0x701e, (q15_t)0x701b, (q15_t)0x7018, (q15_t)0x7015, (q15_t)0x7012, (q15_t)0x700f, (q15_t)0x700c, + (q15_t)0x7009, (q15_t)0x7006, (q15_t)0x7003, (q15_t)0x7000, (q15_t)0x6ffd, (q15_t)0x6ffa, (q15_t)0x6ff7, (q15_t)0x6ff3, + (q15_t)0x6ff0, (q15_t)0x6fed, (q15_t)0x6fea, (q15_t)0x6fe7, (q15_t)0x6fe4, (q15_t)0x6fe1, (q15_t)0x6fde, (q15_t)0x6fdb, + (q15_t)0x6fd8, (q15_t)0x6fd5, (q15_t)0x6fd2, (q15_t)0x6fcf, (q15_t)0x6fcc, (q15_t)0x6fc9, (q15_t)0x6fc6, (q15_t)0x6fc3, + (q15_t)0x6fc0, (q15_t)0x6fbc, (q15_t)0x6fb9, (q15_t)0x6fb6, (q15_t)0x6fb3, (q15_t)0x6fb0, (q15_t)0x6fad, (q15_t)0x6faa, + (q15_t)0x6fa7, (q15_t)0x6fa4, (q15_t)0x6fa1, (q15_t)0x6f9e, (q15_t)0x6f9b, (q15_t)0x6f98, (q15_t)0x6f95, (q15_t)0x6f91, + (q15_t)0x6f8e, (q15_t)0x6f8b, (q15_t)0x6f88, (q15_t)0x6f85, (q15_t)0x6f82, (q15_t)0x6f7f, (q15_t)0x6f7c, (q15_t)0x6f79, + (q15_t)0x6f76, (q15_t)0x6f73, (q15_t)0x6f70, (q15_t)0x6f6c, (q15_t)0x6f69, (q15_t)0x6f66, (q15_t)0x6f63, (q15_t)0x6f60, + (q15_t)0x6f5d, (q15_t)0x6f5a, (q15_t)0x6f57, (q15_t)0x6f54, (q15_t)0x6f51, (q15_t)0x6f4d, (q15_t)0x6f4a, (q15_t)0x6f47, + (q15_t)0x6f44, (q15_t)0x6f41, (q15_t)0x6f3e, (q15_t)0x6f3b, (q15_t)0x6f38, (q15_t)0x6f35, (q15_t)0x6f31, (q15_t)0x6f2e, + (q15_t)0x6f2b, (q15_t)0x6f28, (q15_t)0x6f25, (q15_t)0x6f22, (q15_t)0x6f1f, (q15_t)0x6f1c, (q15_t)0x6f19, (q15_t)0x6f15, + (q15_t)0x6f12, (q15_t)0x6f0f, (q15_t)0x6f0c, (q15_t)0x6f09, (q15_t)0x6f06, (q15_t)0x6f03, (q15_t)0x6f00, (q15_t)0x6efc, + (q15_t)0x6ef9, (q15_t)0x6ef6, (q15_t)0x6ef3, (q15_t)0x6ef0, (q15_t)0x6eed, (q15_t)0x6eea, (q15_t)0x6ee7, (q15_t)0x6ee3, + (q15_t)0x6ee0, (q15_t)0x6edd, (q15_t)0x6eda, (q15_t)0x6ed7, (q15_t)0x6ed4, (q15_t)0x6ed1, (q15_t)0x6ecd, (q15_t)0x6eca, + (q15_t)0x6ec7, (q15_t)0x6ec4, (q15_t)0x6ec1, (q15_t)0x6ebe, (q15_t)0x6eba, (q15_t)0x6eb7, (q15_t)0x6eb4, (q15_t)0x6eb1, + (q15_t)0x6eae, (q15_t)0x6eab, (q15_t)0x6ea8, (q15_t)0x6ea4, (q15_t)0x6ea1, (q15_t)0x6e9e, (q15_t)0x6e9b, (q15_t)0x6e98, + (q15_t)0x6e95, (q15_t)0x6e91, (q15_t)0x6e8e, (q15_t)0x6e8b, (q15_t)0x6e88, (q15_t)0x6e85, (q15_t)0x6e82, (q15_t)0x6e7e, + (q15_t)0x6e7b, (q15_t)0x6e78, (q15_t)0x6e75, (q15_t)0x6e72, (q15_t)0x6e6f, (q15_t)0x6e6b, (q15_t)0x6e68, (q15_t)0x6e65, + (q15_t)0x6e62, (q15_t)0x6e5f, (q15_t)0x6e5b, (q15_t)0x6e58, (q15_t)0x6e55, (q15_t)0x6e52, (q15_t)0x6e4f, (q15_t)0x6e4c, + (q15_t)0x6e48, (q15_t)0x6e45, (q15_t)0x6e42, (q15_t)0x6e3f, (q15_t)0x6e3c, (q15_t)0x6e38, (q15_t)0x6e35, (q15_t)0x6e32, + (q15_t)0x6e2f, (q15_t)0x6e2c, (q15_t)0x6e28, (q15_t)0x6e25, (q15_t)0x6e22, (q15_t)0x6e1f, (q15_t)0x6e1c, (q15_t)0x6e18, + (q15_t)0x6e15, (q15_t)0x6e12, (q15_t)0x6e0f, (q15_t)0x6e0c, (q15_t)0x6e08, (q15_t)0x6e05, (q15_t)0x6e02, (q15_t)0x6dff, + (q15_t)0x6dfb, (q15_t)0x6df8, (q15_t)0x6df5, (q15_t)0x6df2, (q15_t)0x6def, (q15_t)0x6deb, (q15_t)0x6de8, (q15_t)0x6de5, + (q15_t)0x6de2, (q15_t)0x6ddf, (q15_t)0x6ddb, (q15_t)0x6dd8, (q15_t)0x6dd5, (q15_t)0x6dd2, (q15_t)0x6dce, (q15_t)0x6dcb, + (q15_t)0x6dc8, (q15_t)0x6dc5, (q15_t)0x6dc1, (q15_t)0x6dbe, (q15_t)0x6dbb, (q15_t)0x6db8, (q15_t)0x6db5, (q15_t)0x6db1, + (q15_t)0x6dae, (q15_t)0x6dab, (q15_t)0x6da8, (q15_t)0x6da4, (q15_t)0x6da1, (q15_t)0x6d9e, (q15_t)0x6d9b, (q15_t)0x6d97, + (q15_t)0x6d94, (q15_t)0x6d91, (q15_t)0x6d8e, (q15_t)0x6d8a, (q15_t)0x6d87, (q15_t)0x6d84, (q15_t)0x6d81, (q15_t)0x6d7d, + (q15_t)0x6d7a, (q15_t)0x6d77, (q15_t)0x6d74, (q15_t)0x6d70, (q15_t)0x6d6d, (q15_t)0x6d6a, (q15_t)0x6d67, (q15_t)0x6d63, + (q15_t)0x6d60, (q15_t)0x6d5d, (q15_t)0x6d59, (q15_t)0x6d56, (q15_t)0x6d53, (q15_t)0x6d50, (q15_t)0x6d4c, (q15_t)0x6d49, + (q15_t)0x6d46, (q15_t)0x6d43, (q15_t)0x6d3f, (q15_t)0x6d3c, (q15_t)0x6d39, (q15_t)0x6d36, (q15_t)0x6d32, (q15_t)0x6d2f, + (q15_t)0x6d2c, (q15_t)0x6d28, (q15_t)0x6d25, (q15_t)0x6d22, (q15_t)0x6d1f, (q15_t)0x6d1b, (q15_t)0x6d18, (q15_t)0x6d15, + (q15_t)0x6d11, (q15_t)0x6d0e, (q15_t)0x6d0b, (q15_t)0x6d08, (q15_t)0x6d04, (q15_t)0x6d01, (q15_t)0x6cfe, (q15_t)0x6cfa, + (q15_t)0x6cf7, (q15_t)0x6cf4, (q15_t)0x6cf0, (q15_t)0x6ced, (q15_t)0x6cea, (q15_t)0x6ce7, (q15_t)0x6ce3, (q15_t)0x6ce0, + (q15_t)0x6cdd, (q15_t)0x6cd9, (q15_t)0x6cd6, (q15_t)0x6cd3, (q15_t)0x6ccf, (q15_t)0x6ccc, (q15_t)0x6cc9, (q15_t)0x6cc5, + (q15_t)0x6cc2, (q15_t)0x6cbf, (q15_t)0x6cbc, (q15_t)0x6cb8, (q15_t)0x6cb5, (q15_t)0x6cb2, (q15_t)0x6cae, (q15_t)0x6cab, + (q15_t)0x6ca8, (q15_t)0x6ca4, (q15_t)0x6ca1, (q15_t)0x6c9e, (q15_t)0x6c9a, (q15_t)0x6c97, (q15_t)0x6c94, (q15_t)0x6c90, + (q15_t)0x6c8d, (q15_t)0x6c8a, (q15_t)0x6c86, (q15_t)0x6c83, (q15_t)0x6c80, (q15_t)0x6c7c, (q15_t)0x6c79, (q15_t)0x6c76, + (q15_t)0x6c72, (q15_t)0x6c6f, (q15_t)0x6c6c, (q15_t)0x6c68, (q15_t)0x6c65, (q15_t)0x6c62, (q15_t)0x6c5e, (q15_t)0x6c5b, + (q15_t)0x6c58, (q15_t)0x6c54, (q15_t)0x6c51, (q15_t)0x6c4e, (q15_t)0x6c4a, (q15_t)0x6c47, (q15_t)0x6c44, (q15_t)0x6c40, + (q15_t)0x6c3d, (q15_t)0x6c39, (q15_t)0x6c36, (q15_t)0x6c33, (q15_t)0x6c2f, (q15_t)0x6c2c, (q15_t)0x6c29, (q15_t)0x6c25, + (q15_t)0x6c22, (q15_t)0x6c1f, (q15_t)0x6c1b, (q15_t)0x6c18, (q15_t)0x6c15, (q15_t)0x6c11, (q15_t)0x6c0e, (q15_t)0x6c0a, + (q15_t)0x6c07, (q15_t)0x6c04, (q15_t)0x6c00, (q15_t)0x6bfd, (q15_t)0x6bfa, (q15_t)0x6bf6, (q15_t)0x6bf3, (q15_t)0x6bef, + (q15_t)0x6bec, (q15_t)0x6be9, (q15_t)0x6be5, (q15_t)0x6be2, (q15_t)0x6bdf, (q15_t)0x6bdb, (q15_t)0x6bd8, (q15_t)0x6bd4, + (q15_t)0x6bd1, (q15_t)0x6bce, (q15_t)0x6bca, (q15_t)0x6bc7, (q15_t)0x6bc3, (q15_t)0x6bc0, (q15_t)0x6bbd, (q15_t)0x6bb9, + (q15_t)0x6bb6, (q15_t)0x6bb2, (q15_t)0x6baf, (q15_t)0x6bac, (q15_t)0x6ba8, (q15_t)0x6ba5, (q15_t)0x6ba1, (q15_t)0x6b9e, + (q15_t)0x6b9b, (q15_t)0x6b97, (q15_t)0x6b94, (q15_t)0x6b90, (q15_t)0x6b8d, (q15_t)0x6b8a, (q15_t)0x6b86, (q15_t)0x6b83, + (q15_t)0x6b7f, (q15_t)0x6b7c, (q15_t)0x6b79, (q15_t)0x6b75, (q15_t)0x6b72, (q15_t)0x6b6e, (q15_t)0x6b6b, (q15_t)0x6b68, + (q15_t)0x6b64, (q15_t)0x6b61, (q15_t)0x6b5d, (q15_t)0x6b5a, (q15_t)0x6b56, (q15_t)0x6b53, (q15_t)0x6b50, (q15_t)0x6b4c, + (q15_t)0x6b49, (q15_t)0x6b45, (q15_t)0x6b42, (q15_t)0x6b3e, (q15_t)0x6b3b, (q15_t)0x6b38, (q15_t)0x6b34, (q15_t)0x6b31, + (q15_t)0x6b2d, (q15_t)0x6b2a, (q15_t)0x6b26, (q15_t)0x6b23, (q15_t)0x6b20, (q15_t)0x6b1c, (q15_t)0x6b19, (q15_t)0x6b15, + (q15_t)0x6b12, (q15_t)0x6b0e, (q15_t)0x6b0b, (q15_t)0x6b07, (q15_t)0x6b04, (q15_t)0x6b01, (q15_t)0x6afd, (q15_t)0x6afa, + (q15_t)0x6af6, (q15_t)0x6af3, (q15_t)0x6aef, (q15_t)0x6aec, (q15_t)0x6ae8, (q15_t)0x6ae5, (q15_t)0x6ae1, (q15_t)0x6ade, + (q15_t)0x6adb, (q15_t)0x6ad7, (q15_t)0x6ad4, (q15_t)0x6ad0, (q15_t)0x6acd, (q15_t)0x6ac9, (q15_t)0x6ac6, (q15_t)0x6ac2, + (q15_t)0x6abf, (q15_t)0x6abb, (q15_t)0x6ab8, (q15_t)0x6ab4, (q15_t)0x6ab1, (q15_t)0x6aae, (q15_t)0x6aaa, (q15_t)0x6aa7, + (q15_t)0x6aa3, (q15_t)0x6aa0, (q15_t)0x6a9c, (q15_t)0x6a99, (q15_t)0x6a95, (q15_t)0x6a92, (q15_t)0x6a8e, (q15_t)0x6a8b, + (q15_t)0x6a87, (q15_t)0x6a84, (q15_t)0x6a80, (q15_t)0x6a7d, (q15_t)0x6a79, (q15_t)0x6a76, (q15_t)0x6a72, (q15_t)0x6a6f, + (q15_t)0x6a6b, (q15_t)0x6a68, (q15_t)0x6a64, (q15_t)0x6a61, (q15_t)0x6a5d, (q15_t)0x6a5a, (q15_t)0x6a56, (q15_t)0x6a53, + (q15_t)0x6a4f, (q15_t)0x6a4c, (q15_t)0x6a48, (q15_t)0x6a45, (q15_t)0x6a41, (q15_t)0x6a3e, (q15_t)0x6a3a, (q15_t)0x6a37, + (q15_t)0x6a33, (q15_t)0x6a30, (q15_t)0x6a2c, (q15_t)0x6a29, (q15_t)0x6a25, (q15_t)0x6a22, (q15_t)0x6a1e, (q15_t)0x6a1b, + (q15_t)0x6a17, (q15_t)0x6a14, (q15_t)0x6a10, (q15_t)0x6a0d, (q15_t)0x6a09, (q15_t)0x6a06, (q15_t)0x6a02, (q15_t)0x69ff, + (q15_t)0x69fb, (q15_t)0x69f8, (q15_t)0x69f4, (q15_t)0x69f1, (q15_t)0x69ed, (q15_t)0x69e9, (q15_t)0x69e6, (q15_t)0x69e2, + (q15_t)0x69df, (q15_t)0x69db, (q15_t)0x69d8, (q15_t)0x69d4, (q15_t)0x69d1, (q15_t)0x69cd, (q15_t)0x69ca, (q15_t)0x69c6, + (q15_t)0x69c3, (q15_t)0x69bf, (q15_t)0x69bc, (q15_t)0x69b8, (q15_t)0x69b4, (q15_t)0x69b1, (q15_t)0x69ad, (q15_t)0x69aa, + (q15_t)0x69a6, (q15_t)0x69a3, (q15_t)0x699f, (q15_t)0x699c, (q15_t)0x6998, (q15_t)0x6995, (q15_t)0x6991, (q15_t)0x698d, + (q15_t)0x698a, (q15_t)0x6986, (q15_t)0x6983, (q15_t)0x697f, (q15_t)0x697c, (q15_t)0x6978, (q15_t)0x6975, (q15_t)0x6971, + (q15_t)0x696d, (q15_t)0x696a, (q15_t)0x6966, (q15_t)0x6963, (q15_t)0x695f, (q15_t)0x695c, (q15_t)0x6958, (q15_t)0x6954, + (q15_t)0x6951, (q15_t)0x694d, (q15_t)0x694a, (q15_t)0x6946, (q15_t)0x6943, (q15_t)0x693f, (q15_t)0x693b, (q15_t)0x6938, + (q15_t)0x6934, (q15_t)0x6931, (q15_t)0x692d, (q15_t)0x692a, (q15_t)0x6926, (q15_t)0x6922, (q15_t)0x691f, (q15_t)0x691b, + (q15_t)0x6918, (q15_t)0x6914, (q15_t)0x6910, (q15_t)0x690d, (q15_t)0x6909, (q15_t)0x6906, (q15_t)0x6902, (q15_t)0x68fe, + (q15_t)0x68fb, (q15_t)0x68f7, (q15_t)0x68f4, (q15_t)0x68f0, (q15_t)0x68ec, (q15_t)0x68e9, (q15_t)0x68e5, (q15_t)0x68e2, + (q15_t)0x68de, (q15_t)0x68da, (q15_t)0x68d7, (q15_t)0x68d3, (q15_t)0x68d0, (q15_t)0x68cc, (q15_t)0x68c8, (q15_t)0x68c5, + (q15_t)0x68c1, (q15_t)0x68be, (q15_t)0x68ba, (q15_t)0x68b6, (q15_t)0x68b3, (q15_t)0x68af, (q15_t)0x68ac, (q15_t)0x68a8, + (q15_t)0x68a4, (q15_t)0x68a1, (q15_t)0x689d, (q15_t)0x6899, (q15_t)0x6896, (q15_t)0x6892, (q15_t)0x688f, (q15_t)0x688b, + (q15_t)0x6887, (q15_t)0x6884, (q15_t)0x6880, (q15_t)0x687c, (q15_t)0x6879, (q15_t)0x6875, (q15_t)0x6872, (q15_t)0x686e, + (q15_t)0x686a, (q15_t)0x6867, (q15_t)0x6863, (q15_t)0x685f, (q15_t)0x685c, (q15_t)0x6858, (q15_t)0x6854, (q15_t)0x6851, + (q15_t)0x684d, (q15_t)0x684a, (q15_t)0x6846, (q15_t)0x6842, (q15_t)0x683f, (q15_t)0x683b, (q15_t)0x6837, (q15_t)0x6834, + (q15_t)0x6830, (q15_t)0x682c, (q15_t)0x6829, (q15_t)0x6825, (q15_t)0x6821, (q15_t)0x681e, (q15_t)0x681a, (q15_t)0x6816, + (q15_t)0x6813, (q15_t)0x680f, (q15_t)0x680b, (q15_t)0x6808, (q15_t)0x6804, (q15_t)0x6800, (q15_t)0x67fd, (q15_t)0x67f9, + (q15_t)0x67f5, (q15_t)0x67f2, (q15_t)0x67ee, (q15_t)0x67ea, (q15_t)0x67e7, (q15_t)0x67e3, (q15_t)0x67df, (q15_t)0x67dc, + (q15_t)0x67d8, (q15_t)0x67d4, (q15_t)0x67d1, (q15_t)0x67cd, (q15_t)0x67c9, (q15_t)0x67c6, (q15_t)0x67c2, (q15_t)0x67be, + (q15_t)0x67bb, (q15_t)0x67b7, (q15_t)0x67b3, (q15_t)0x67b0, (q15_t)0x67ac, (q15_t)0x67a8, (q15_t)0x67a5, (q15_t)0x67a1, + (q15_t)0x679d, (q15_t)0x679a, (q15_t)0x6796, (q15_t)0x6792, (q15_t)0x678e, (q15_t)0x678b, (q15_t)0x6787, (q15_t)0x6783, + (q15_t)0x6780, (q15_t)0x677c, (q15_t)0x6778, (q15_t)0x6775, (q15_t)0x6771, (q15_t)0x676d, (q15_t)0x6769, (q15_t)0x6766, + (q15_t)0x6762, (q15_t)0x675e, (q15_t)0x675b, (q15_t)0x6757, (q15_t)0x6753, (q15_t)0x6750, (q15_t)0x674c, (q15_t)0x6748, + (q15_t)0x6744, (q15_t)0x6741, (q15_t)0x673d, (q15_t)0x6739, (q15_t)0x6736, (q15_t)0x6732, (q15_t)0x672e, (q15_t)0x672a, + (q15_t)0x6727, (q15_t)0x6723, (q15_t)0x671f, (q15_t)0x671c, (q15_t)0x6718, (q15_t)0x6714, (q15_t)0x6710, (q15_t)0x670d, + (q15_t)0x6709, (q15_t)0x6705, (q15_t)0x6701, (q15_t)0x66fe, (q15_t)0x66fa, (q15_t)0x66f6, (q15_t)0x66f3, (q15_t)0x66ef, + (q15_t)0x66eb, (q15_t)0x66e7, (q15_t)0x66e4, (q15_t)0x66e0, (q15_t)0x66dc, (q15_t)0x66d8, (q15_t)0x66d5, (q15_t)0x66d1, + (q15_t)0x66cd, (q15_t)0x66c9, (q15_t)0x66c6, (q15_t)0x66c2, (q15_t)0x66be, (q15_t)0x66ba, (q15_t)0x66b7, (q15_t)0x66b3, + (q15_t)0x66af, (q15_t)0x66ab, (q15_t)0x66a8, (q15_t)0x66a4, (q15_t)0x66a0, (q15_t)0x669c, (q15_t)0x6699, (q15_t)0x6695, + (q15_t)0x6691, (q15_t)0x668d, (q15_t)0x668a, (q15_t)0x6686, (q15_t)0x6682, (q15_t)0x667e, (q15_t)0x667b, (q15_t)0x6677, + (q15_t)0x6673, (q15_t)0x666f, (q15_t)0x666b, (q15_t)0x6668, (q15_t)0x6664, (q15_t)0x6660, (q15_t)0x665c, (q15_t)0x6659, + (q15_t)0x6655, (q15_t)0x6651, (q15_t)0x664d, (q15_t)0x664a, (q15_t)0x6646, (q15_t)0x6642, (q15_t)0x663e, (q15_t)0x663a, + (q15_t)0x6637, (q15_t)0x6633, (q15_t)0x662f, (q15_t)0x662b, (q15_t)0x6627, (q15_t)0x6624, (q15_t)0x6620, (q15_t)0x661c, + (q15_t)0x6618, (q15_t)0x6615, (q15_t)0x6611, (q15_t)0x660d, (q15_t)0x6609, (q15_t)0x6605, (q15_t)0x6602, (q15_t)0x65fe, + (q15_t)0x65fa, (q15_t)0x65f6, (q15_t)0x65f2, (q15_t)0x65ef, (q15_t)0x65eb, (q15_t)0x65e7, (q15_t)0x65e3, (q15_t)0x65df, + (q15_t)0x65dc, (q15_t)0x65d8, (q15_t)0x65d4, (q15_t)0x65d0, (q15_t)0x65cc, (q15_t)0x65c9, (q15_t)0x65c5, (q15_t)0x65c1, + (q15_t)0x65bd, (q15_t)0x65b9, (q15_t)0x65b5, (q15_t)0x65b2, (q15_t)0x65ae, (q15_t)0x65aa, (q15_t)0x65a6, (q15_t)0x65a2, + (q15_t)0x659f, (q15_t)0x659b, (q15_t)0x6597, (q15_t)0x6593, (q15_t)0x658f, (q15_t)0x658b, (q15_t)0x6588, (q15_t)0x6584, + (q15_t)0x6580, (q15_t)0x657c, (q15_t)0x6578, (q15_t)0x6574, (q15_t)0x6571, (q15_t)0x656d, (q15_t)0x6569, (q15_t)0x6565, + (q15_t)0x6561, (q15_t)0x655d, (q15_t)0x655a, (q15_t)0x6556, (q15_t)0x6552, (q15_t)0x654e, (q15_t)0x654a, (q15_t)0x6546, + (q15_t)0x6543, (q15_t)0x653f, (q15_t)0x653b, (q15_t)0x6537, (q15_t)0x6533, (q15_t)0x652f, (q15_t)0x652c, (q15_t)0x6528, + (q15_t)0x6524, (q15_t)0x6520, (q15_t)0x651c, (q15_t)0x6518, (q15_t)0x6514, (q15_t)0x6511, (q15_t)0x650d, (q15_t)0x6509, + (q15_t)0x6505, (q15_t)0x6501, (q15_t)0x64fd, (q15_t)0x64f9, (q15_t)0x64f6, (q15_t)0x64f2, (q15_t)0x64ee, (q15_t)0x64ea, + (q15_t)0x64e6, (q15_t)0x64e2, (q15_t)0x64de, (q15_t)0x64db, (q15_t)0x64d7, (q15_t)0x64d3, (q15_t)0x64cf, (q15_t)0x64cb, + (q15_t)0x64c7, (q15_t)0x64c3, (q15_t)0x64bf, (q15_t)0x64bc, (q15_t)0x64b8, (q15_t)0x64b4, (q15_t)0x64b0, (q15_t)0x64ac, + (q15_t)0x64a8, (q15_t)0x64a4, (q15_t)0x64a0, (q15_t)0x649c, (q15_t)0x6499, (q15_t)0x6495, (q15_t)0x6491, (q15_t)0x648d, + (q15_t)0x6489, (q15_t)0x6485, (q15_t)0x6481, (q15_t)0x647d, (q15_t)0x6479, (q15_t)0x6476, (q15_t)0x6472, (q15_t)0x646e, + (q15_t)0x646a, (q15_t)0x6466, (q15_t)0x6462, (q15_t)0x645e, (q15_t)0x645a, (q15_t)0x6456, (q15_t)0x6453, (q15_t)0x644f, + (q15_t)0x644b, (q15_t)0x6447, (q15_t)0x6443, (q15_t)0x643f, (q15_t)0x643b, (q15_t)0x6437, (q15_t)0x6433, (q15_t)0x642f, + (q15_t)0x642b, (q15_t)0x6428, (q15_t)0x6424, (q15_t)0x6420, (q15_t)0x641c, (q15_t)0x6418, (q15_t)0x6414, (q15_t)0x6410, + (q15_t)0x640c, (q15_t)0x6408, (q15_t)0x6404, (q15_t)0x6400, (q15_t)0x63fc, (q15_t)0x63f9, (q15_t)0x63f5, (q15_t)0x63f1, + (q15_t)0x63ed, (q15_t)0x63e9, (q15_t)0x63e5, (q15_t)0x63e1, (q15_t)0x63dd, (q15_t)0x63d9, (q15_t)0x63d5, (q15_t)0x63d1, + (q15_t)0x63cd, (q15_t)0x63c9, (q15_t)0x63c5, (q15_t)0x63c1, (q15_t)0x63be, (q15_t)0x63ba, (q15_t)0x63b6, (q15_t)0x63b2, + (q15_t)0x63ae, (q15_t)0x63aa, (q15_t)0x63a6, (q15_t)0x63a2, (q15_t)0x639e, (q15_t)0x639a, (q15_t)0x6396, (q15_t)0x6392, + (q15_t)0x638e, (q15_t)0x638a, (q15_t)0x6386, (q15_t)0x6382, (q15_t)0x637e, (q15_t)0x637a, (q15_t)0x6377, (q15_t)0x6373, + (q15_t)0x636f, (q15_t)0x636b, (q15_t)0x6367, (q15_t)0x6363, (q15_t)0x635f, (q15_t)0x635b, (q15_t)0x6357, (q15_t)0x6353, + (q15_t)0x634f, (q15_t)0x634b, (q15_t)0x6347, (q15_t)0x6343, (q15_t)0x633f, (q15_t)0x633b, (q15_t)0x6337, (q15_t)0x6333, + (q15_t)0x632f, (q15_t)0x632b, (q15_t)0x6327, (q15_t)0x6323, (q15_t)0x631f, (q15_t)0x631b, (q15_t)0x6317, (q15_t)0x6313, + (q15_t)0x630f, (q15_t)0x630b, (q15_t)0x6307, (q15_t)0x6303, (q15_t)0x62ff, (q15_t)0x62fb, (q15_t)0x62f7, (q15_t)0x62f3, + (q15_t)0x62f0, (q15_t)0x62ec, (q15_t)0x62e8, (q15_t)0x62e4, (q15_t)0x62e0, (q15_t)0x62dc, (q15_t)0x62d8, (q15_t)0x62d4, + (q15_t)0x62d0, (q15_t)0x62cc, (q15_t)0x62c8, (q15_t)0x62c4, (q15_t)0x62c0, (q15_t)0x62bc, (q15_t)0x62b8, (q15_t)0x62b4, + (q15_t)0x62b0, (q15_t)0x62ac, (q15_t)0x62a8, (q15_t)0x62a4, (q15_t)0x62a0, (q15_t)0x629c, (q15_t)0x6298, (q15_t)0x6294, + (q15_t)0x6290, (q15_t)0x628c, (q15_t)0x6288, (q15_t)0x6284, (q15_t)0x6280, (q15_t)0x627c, (q15_t)0x6278, (q15_t)0x6273, + (q15_t)0x626f, (q15_t)0x626b, (q15_t)0x6267, (q15_t)0x6263, (q15_t)0x625f, (q15_t)0x625b, (q15_t)0x6257, (q15_t)0x6253, + (q15_t)0x624f, (q15_t)0x624b, (q15_t)0x6247, (q15_t)0x6243, (q15_t)0x623f, (q15_t)0x623b, (q15_t)0x6237, (q15_t)0x6233, + (q15_t)0x622f, (q15_t)0x622b, (q15_t)0x6227, (q15_t)0x6223, (q15_t)0x621f, (q15_t)0x621b, (q15_t)0x6217, (q15_t)0x6213, + (q15_t)0x620f, (q15_t)0x620b, (q15_t)0x6207, (q15_t)0x6203, (q15_t)0x61ff, (q15_t)0x61fb, (q15_t)0x61f7, (q15_t)0x61f3, + (q15_t)0x61ee, (q15_t)0x61ea, (q15_t)0x61e6, (q15_t)0x61e2, (q15_t)0x61de, (q15_t)0x61da, (q15_t)0x61d6, (q15_t)0x61d2, + (q15_t)0x61ce, (q15_t)0x61ca, (q15_t)0x61c6, (q15_t)0x61c2, (q15_t)0x61be, (q15_t)0x61ba, (q15_t)0x61b6, (q15_t)0x61b2, + (q15_t)0x61ae, (q15_t)0x61aa, (q15_t)0x61a6, (q15_t)0x61a1, (q15_t)0x619d, (q15_t)0x6199, (q15_t)0x6195, (q15_t)0x6191, + (q15_t)0x618d, (q15_t)0x6189, (q15_t)0x6185, (q15_t)0x6181, (q15_t)0x617d, (q15_t)0x6179, (q15_t)0x6175, (q15_t)0x6171, + (q15_t)0x616d, (q15_t)0x6168, (q15_t)0x6164, (q15_t)0x6160, (q15_t)0x615c, (q15_t)0x6158, (q15_t)0x6154, (q15_t)0x6150, + (q15_t)0x614c, (q15_t)0x6148, (q15_t)0x6144, (q15_t)0x6140, (q15_t)0x613c, (q15_t)0x6137, (q15_t)0x6133, (q15_t)0x612f, + (q15_t)0x612b, (q15_t)0x6127, (q15_t)0x6123, (q15_t)0x611f, (q15_t)0x611b, (q15_t)0x6117, (q15_t)0x6113, (q15_t)0x610f, + (q15_t)0x610a, (q15_t)0x6106, (q15_t)0x6102, (q15_t)0x60fe, (q15_t)0x60fa, (q15_t)0x60f6, (q15_t)0x60f2, (q15_t)0x60ee, + (q15_t)0x60ea, (q15_t)0x60e6, (q15_t)0x60e1, (q15_t)0x60dd, (q15_t)0x60d9, (q15_t)0x60d5, (q15_t)0x60d1, (q15_t)0x60cd, + (q15_t)0x60c9, (q15_t)0x60c5, (q15_t)0x60c1, (q15_t)0x60bc, (q15_t)0x60b8, (q15_t)0x60b4, (q15_t)0x60b0, (q15_t)0x60ac, + (q15_t)0x60a8, (q15_t)0x60a4, (q15_t)0x60a0, (q15_t)0x609c, (q15_t)0x6097, (q15_t)0x6093, (q15_t)0x608f, (q15_t)0x608b, + (q15_t)0x6087, (q15_t)0x6083, (q15_t)0x607f, (q15_t)0x607b, (q15_t)0x6076, (q15_t)0x6072, (q15_t)0x606e, (q15_t)0x606a, + (q15_t)0x6066, (q15_t)0x6062, (q15_t)0x605e, (q15_t)0x6059, (q15_t)0x6055, (q15_t)0x6051, (q15_t)0x604d, (q15_t)0x6049, + (q15_t)0x6045, (q15_t)0x6041, (q15_t)0x603c, (q15_t)0x6038, (q15_t)0x6034, (q15_t)0x6030, (q15_t)0x602c, (q15_t)0x6028, + (q15_t)0x6024, (q15_t)0x601f, (q15_t)0x601b, (q15_t)0x6017, (q15_t)0x6013, (q15_t)0x600f, (q15_t)0x600b, (q15_t)0x6007, + (q15_t)0x6002, (q15_t)0x5ffe, (q15_t)0x5ffa, (q15_t)0x5ff6, (q15_t)0x5ff2, (q15_t)0x5fee, (q15_t)0x5fe9, (q15_t)0x5fe5, + (q15_t)0x5fe1, (q15_t)0x5fdd, (q15_t)0x5fd9, (q15_t)0x5fd5, (q15_t)0x5fd0, (q15_t)0x5fcc, (q15_t)0x5fc8, (q15_t)0x5fc4, + (q15_t)0x5fc0, (q15_t)0x5fbc, (q15_t)0x5fb7, (q15_t)0x5fb3, (q15_t)0x5faf, (q15_t)0x5fab, (q15_t)0x5fa7, (q15_t)0x5fa3, + (q15_t)0x5f9e, (q15_t)0x5f9a, (q15_t)0x5f96, (q15_t)0x5f92, (q15_t)0x5f8e, (q15_t)0x5f8a, (q15_t)0x5f85, (q15_t)0x5f81, + (q15_t)0x5f7d, (q15_t)0x5f79, (q15_t)0x5f75, (q15_t)0x5f70, (q15_t)0x5f6c, (q15_t)0x5f68, (q15_t)0x5f64, (q15_t)0x5f60, + (q15_t)0x5f5b, (q15_t)0x5f57, (q15_t)0x5f53, (q15_t)0x5f4f, (q15_t)0x5f4b, (q15_t)0x5f46, (q15_t)0x5f42, (q15_t)0x5f3e, + (q15_t)0x5f3a, (q15_t)0x5f36, (q15_t)0x5f31, (q15_t)0x5f2d, (q15_t)0x5f29, (q15_t)0x5f25, (q15_t)0x5f21, (q15_t)0x5f1c, + (q15_t)0x5f18, (q15_t)0x5f14, (q15_t)0x5f10, (q15_t)0x5f0c, (q15_t)0x5f07, (q15_t)0x5f03, (q15_t)0x5eff, (q15_t)0x5efb, + (q15_t)0x5ef7, (q15_t)0x5ef2, (q15_t)0x5eee, (q15_t)0x5eea, (q15_t)0x5ee6, (q15_t)0x5ee2, (q15_t)0x5edd, (q15_t)0x5ed9, + (q15_t)0x5ed5, (q15_t)0x5ed1, (q15_t)0x5ecc, (q15_t)0x5ec8, (q15_t)0x5ec4, (q15_t)0x5ec0, (q15_t)0x5ebc, (q15_t)0x5eb7, + (q15_t)0x5eb3, (q15_t)0x5eaf, (q15_t)0x5eab, (q15_t)0x5ea6, (q15_t)0x5ea2, (q15_t)0x5e9e, (q15_t)0x5e9a, (q15_t)0x5e95, + (q15_t)0x5e91, (q15_t)0x5e8d, (q15_t)0x5e89, (q15_t)0x5e85, (q15_t)0x5e80, (q15_t)0x5e7c, (q15_t)0x5e78, (q15_t)0x5e74, + (q15_t)0x5e6f, (q15_t)0x5e6b, (q15_t)0x5e67, (q15_t)0x5e63, (q15_t)0x5e5e, (q15_t)0x5e5a, (q15_t)0x5e56, (q15_t)0x5e52, + (q15_t)0x5e4d, (q15_t)0x5e49, (q15_t)0x5e45, (q15_t)0x5e41, (q15_t)0x5e3c, (q15_t)0x5e38, (q15_t)0x5e34, (q15_t)0x5e30, + (q15_t)0x5e2b, (q15_t)0x5e27, (q15_t)0x5e23, (q15_t)0x5e1f, (q15_t)0x5e1a, (q15_t)0x5e16, (q15_t)0x5e12, (q15_t)0x5e0e, + (q15_t)0x5e09, (q15_t)0x5e05, (q15_t)0x5e01, (q15_t)0x5dfd, (q15_t)0x5df8, (q15_t)0x5df4, (q15_t)0x5df0, (q15_t)0x5deb, + (q15_t)0x5de7, (q15_t)0x5de3, (q15_t)0x5ddf, (q15_t)0x5dda, (q15_t)0x5dd6, (q15_t)0x5dd2, (q15_t)0x5dce, (q15_t)0x5dc9, + (q15_t)0x5dc5, (q15_t)0x5dc1, (q15_t)0x5dbc, (q15_t)0x5db8, (q15_t)0x5db4, (q15_t)0x5db0, (q15_t)0x5dab, (q15_t)0x5da7, + (q15_t)0x5da3, (q15_t)0x5d9e, (q15_t)0x5d9a, (q15_t)0x5d96, (q15_t)0x5d92, (q15_t)0x5d8d, (q15_t)0x5d89, (q15_t)0x5d85, + (q15_t)0x5d80, (q15_t)0x5d7c, (q15_t)0x5d78, (q15_t)0x5d74, (q15_t)0x5d6f, (q15_t)0x5d6b, (q15_t)0x5d67, (q15_t)0x5d62, + (q15_t)0x5d5e, (q15_t)0x5d5a, (q15_t)0x5d55, (q15_t)0x5d51, (q15_t)0x5d4d, (q15_t)0x5d49, (q15_t)0x5d44, (q15_t)0x5d40, + (q15_t)0x5d3c, (q15_t)0x5d37, (q15_t)0x5d33, (q15_t)0x5d2f, (q15_t)0x5d2a, (q15_t)0x5d26, (q15_t)0x5d22, (q15_t)0x5d1e, + (q15_t)0x5d19, (q15_t)0x5d15, (q15_t)0x5d11, (q15_t)0x5d0c, (q15_t)0x5d08, (q15_t)0x5d04, (q15_t)0x5cff, (q15_t)0x5cfb, + (q15_t)0x5cf7, (q15_t)0x5cf2, (q15_t)0x5cee, (q15_t)0x5cea, (q15_t)0x5ce5, (q15_t)0x5ce1, (q15_t)0x5cdd, (q15_t)0x5cd8, + (q15_t)0x5cd4, (q15_t)0x5cd0, (q15_t)0x5ccb, (q15_t)0x5cc7, (q15_t)0x5cc3, (q15_t)0x5cbe, (q15_t)0x5cba, (q15_t)0x5cb6, + (q15_t)0x5cb1, (q15_t)0x5cad, (q15_t)0x5ca9, (q15_t)0x5ca4, (q15_t)0x5ca0, (q15_t)0x5c9c, (q15_t)0x5c97, (q15_t)0x5c93, + (q15_t)0x5c8f, (q15_t)0x5c8a, (q15_t)0x5c86, (q15_t)0x5c82, (q15_t)0x5c7d, (q15_t)0x5c79, (q15_t)0x5c75, (q15_t)0x5c70, + (q15_t)0x5c6c, (q15_t)0x5c68, (q15_t)0x5c63, (q15_t)0x5c5f, (q15_t)0x5c5b, (q15_t)0x5c56, (q15_t)0x5c52, (q15_t)0x5c4e, + (q15_t)0x5c49, (q15_t)0x5c45, (q15_t)0x5c41, (q15_t)0x5c3c, (q15_t)0x5c38, (q15_t)0x5c33, (q15_t)0x5c2f, (q15_t)0x5c2b, + (q15_t)0x5c26, (q15_t)0x5c22, (q15_t)0x5c1e, (q15_t)0x5c19, (q15_t)0x5c15, (q15_t)0x5c11, (q15_t)0x5c0c, (q15_t)0x5c08, + (q15_t)0x5c03, (q15_t)0x5bff, (q15_t)0x5bfb, (q15_t)0x5bf6, (q15_t)0x5bf2, (q15_t)0x5bee, (q15_t)0x5be9, (q15_t)0x5be5, + (q15_t)0x5be0, (q15_t)0x5bdc, (q15_t)0x5bd8, (q15_t)0x5bd3, (q15_t)0x5bcf, (q15_t)0x5bcb, (q15_t)0x5bc6, (q15_t)0x5bc2, + (q15_t)0x5bbd, (q15_t)0x5bb9, (q15_t)0x5bb5, (q15_t)0x5bb0, (q15_t)0x5bac, (q15_t)0x5ba8, (q15_t)0x5ba3, (q15_t)0x5b9f, + (q15_t)0x5b9a, (q15_t)0x5b96, (q15_t)0x5b92, (q15_t)0x5b8d, (q15_t)0x5b89, (q15_t)0x5b84, (q15_t)0x5b80, (q15_t)0x5b7c, + (q15_t)0x5b77, (q15_t)0x5b73, (q15_t)0x5b6e, (q15_t)0x5b6a, (q15_t)0x5b66, (q15_t)0x5b61, (q15_t)0x5b5d, (q15_t)0x5b58, + (q15_t)0x5b54, (q15_t)0x5b50, (q15_t)0x5b4b, (q15_t)0x5b47, (q15_t)0x5b42, (q15_t)0x5b3e, (q15_t)0x5b3a, (q15_t)0x5b35, + (q15_t)0x5b31, (q15_t)0x5b2c, (q15_t)0x5b28, (q15_t)0x5b24, (q15_t)0x5b1f, (q15_t)0x5b1b, (q15_t)0x5b16, (q15_t)0x5b12, + (q15_t)0x5b0e, (q15_t)0x5b09, (q15_t)0x5b05, (q15_t)0x5b00, (q15_t)0x5afc, (q15_t)0x5af7, (q15_t)0x5af3, (q15_t)0x5aef, + (q15_t)0x5aea, (q15_t)0x5ae6, (q15_t)0x5ae1, (q15_t)0x5add, (q15_t)0x5ad8, (q15_t)0x5ad4, (q15_t)0x5ad0, (q15_t)0x5acb, + (q15_t)0x5ac7, (q15_t)0x5ac2, (q15_t)0x5abe, (q15_t)0x5ab9, (q15_t)0x5ab5, (q15_t)0x5ab1, (q15_t)0x5aac, (q15_t)0x5aa8, + (q15_t)0x5aa3, (q15_t)0x5a9f, (q15_t)0x5a9a, (q15_t)0x5a96, (q15_t)0x5a92, (q15_t)0x5a8d, (q15_t)0x5a89, (q15_t)0x5a84, + (q15_t)0x5a80, (q15_t)0x5a7b, (q15_t)0x5a77, (q15_t)0x5a72, (q15_t)0x5a6e, (q15_t)0x5a6a, (q15_t)0x5a65, (q15_t)0x5a61, + (q15_t)0x5a5c, (q15_t)0x5a58, (q15_t)0x5a53, (q15_t)0x5a4f, (q15_t)0x5a4a, (q15_t)0x5a46, (q15_t)0x5a41, (q15_t)0x5a3d, + (q15_t)0x5a39, (q15_t)0x5a34, (q15_t)0x5a30, (q15_t)0x5a2b, (q15_t)0x5a27, (q15_t)0x5a22, (q15_t)0x5a1e, (q15_t)0x5a19, + (q15_t)0x5a15, (q15_t)0x5a10, (q15_t)0x5a0c, (q15_t)0x5a07, (q15_t)0x5a03, (q15_t)0x59ff, (q15_t)0x59fa, (q15_t)0x59f6, + (q15_t)0x59f1, (q15_t)0x59ed, (q15_t)0x59e8, (q15_t)0x59e4, (q15_t)0x59df, (q15_t)0x59db, (q15_t)0x59d6, (q15_t)0x59d2, + (q15_t)0x59cd, (q15_t)0x59c9, (q15_t)0x59c4, (q15_t)0x59c0, (q15_t)0x59bb, (q15_t)0x59b7, (q15_t)0x59b2, (q15_t)0x59ae, + (q15_t)0x59a9, (q15_t)0x59a5, (q15_t)0x59a1, (q15_t)0x599c, (q15_t)0x5998, (q15_t)0x5993, (q15_t)0x598f, (q15_t)0x598a, + (q15_t)0x5986, (q15_t)0x5981, (q15_t)0x597d, (q15_t)0x5978, (q15_t)0x5974, (q15_t)0x596f, (q15_t)0x596b, (q15_t)0x5966, + (q15_t)0x5962, (q15_t)0x595d, (q15_t)0x5959, (q15_t)0x5954, (q15_t)0x5950, (q15_t)0x594b, (q15_t)0x5947, (q15_t)0x5942, + (q15_t)0x593e, (q15_t)0x5939, (q15_t)0x5935, (q15_t)0x5930, (q15_t)0x592c, (q15_t)0x5927, (q15_t)0x5923, (q15_t)0x591e, + (q15_t)0x591a, (q15_t)0x5915, (q15_t)0x5911, (q15_t)0x590c, (q15_t)0x5908, (q15_t)0x5903, (q15_t)0x58fe, (q15_t)0x58fa, + (q15_t)0x58f5, (q15_t)0x58f1, (q15_t)0x58ec, (q15_t)0x58e8, (q15_t)0x58e3, (q15_t)0x58df, (q15_t)0x58da, (q15_t)0x58d6, + (q15_t)0x58d1, (q15_t)0x58cd, (q15_t)0x58c8, (q15_t)0x58c4, (q15_t)0x58bf, (q15_t)0x58bb, (q15_t)0x58b6, (q15_t)0x58b2, + (q15_t)0x58ad, (q15_t)0x58a9, (q15_t)0x58a4, (q15_t)0x589f, (q15_t)0x589b, (q15_t)0x5896, (q15_t)0x5892, (q15_t)0x588d, + (q15_t)0x5889, (q15_t)0x5884, (q15_t)0x5880, (q15_t)0x587b, (q15_t)0x5877, (q15_t)0x5872, (q15_t)0x586e, (q15_t)0x5869, + (q15_t)0x5864, (q15_t)0x5860, (q15_t)0x585b, (q15_t)0x5857, (q15_t)0x5852, (q15_t)0x584e, (q15_t)0x5849, (q15_t)0x5845, + (q15_t)0x5840, (q15_t)0x583c, (q15_t)0x5837, (q15_t)0x5832, (q15_t)0x582e, (q15_t)0x5829, (q15_t)0x5825, (q15_t)0x5820, + (q15_t)0x581c, (q15_t)0x5817, (q15_t)0x5813, (q15_t)0x580e, (q15_t)0x5809, (q15_t)0x5805, (q15_t)0x5800, (q15_t)0x57fc, + (q15_t)0x57f7, (q15_t)0x57f3, (q15_t)0x57ee, (q15_t)0x57e9, (q15_t)0x57e5, (q15_t)0x57e0, (q15_t)0x57dc, (q15_t)0x57d7, + (q15_t)0x57d3, (q15_t)0x57ce, (q15_t)0x57c9, (q15_t)0x57c5, (q15_t)0x57c0, (q15_t)0x57bc, (q15_t)0x57b7, (q15_t)0x57b3, + (q15_t)0x57ae, (q15_t)0x57a9, (q15_t)0x57a5, (q15_t)0x57a0, (q15_t)0x579c, (q15_t)0x5797, (q15_t)0x5793, (q15_t)0x578e, + (q15_t)0x5789, (q15_t)0x5785, (q15_t)0x5780, (q15_t)0x577c, (q15_t)0x5777, (q15_t)0x5772, (q15_t)0x576e, (q15_t)0x5769, + (q15_t)0x5765, (q15_t)0x5760, (q15_t)0x575c, (q15_t)0x5757, (q15_t)0x5752, (q15_t)0x574e, (q15_t)0x5749, (q15_t)0x5745, + (q15_t)0x5740, (q15_t)0x573b, (q15_t)0x5737, (q15_t)0x5732, (q15_t)0x572e, (q15_t)0x5729, (q15_t)0x5724, (q15_t)0x5720, + (q15_t)0x571b, (q15_t)0x5717, (q15_t)0x5712, (q15_t)0x570d, (q15_t)0x5709, (q15_t)0x5704, (q15_t)0x56ff, (q15_t)0x56fb, + (q15_t)0x56f6, (q15_t)0x56f2, (q15_t)0x56ed, (q15_t)0x56e8, (q15_t)0x56e4, (q15_t)0x56df, (q15_t)0x56db, (q15_t)0x56d6, + (q15_t)0x56d1, (q15_t)0x56cd, (q15_t)0x56c8, (q15_t)0x56c4, (q15_t)0x56bf, (q15_t)0x56ba, (q15_t)0x56b6, (q15_t)0x56b1, + (q15_t)0x56ac, (q15_t)0x56a8, (q15_t)0x56a3, (q15_t)0x569f, (q15_t)0x569a, (q15_t)0x5695, (q15_t)0x5691, (q15_t)0x568c, + (q15_t)0x5687, (q15_t)0x5683, (q15_t)0x567e, (q15_t)0x5679, (q15_t)0x5675, (q15_t)0x5670, (q15_t)0x566c, (q15_t)0x5667, + (q15_t)0x5662, (q15_t)0x565e, (q15_t)0x5659, (q15_t)0x5654, (q15_t)0x5650, (q15_t)0x564b, (q15_t)0x5646, (q15_t)0x5642, + (q15_t)0x563d, (q15_t)0x5639, (q15_t)0x5634, (q15_t)0x562f, (q15_t)0x562b, (q15_t)0x5626, (q15_t)0x5621, (q15_t)0x561d, + (q15_t)0x5618, (q15_t)0x5613, (q15_t)0x560f, (q15_t)0x560a, (q15_t)0x5605, (q15_t)0x5601, (q15_t)0x55fc, (q15_t)0x55f7, + (q15_t)0x55f3, (q15_t)0x55ee, (q15_t)0x55ea, (q15_t)0x55e5, (q15_t)0x55e0, (q15_t)0x55dc, (q15_t)0x55d7, (q15_t)0x55d2, + (q15_t)0x55ce, (q15_t)0x55c9, (q15_t)0x55c4, (q15_t)0x55c0, (q15_t)0x55bb, (q15_t)0x55b6, (q15_t)0x55b2, (q15_t)0x55ad, + (q15_t)0x55a8, (q15_t)0x55a4, (q15_t)0x559f, (q15_t)0x559a, (q15_t)0x5596, (q15_t)0x5591, (q15_t)0x558c, (q15_t)0x5588, + (q15_t)0x5583, (q15_t)0x557e, (q15_t)0x5579, (q15_t)0x5575, (q15_t)0x5570, (q15_t)0x556b, (q15_t)0x5567, (q15_t)0x5562, + (q15_t)0x555d, (q15_t)0x5559, (q15_t)0x5554, (q15_t)0x554f, (q15_t)0x554b, (q15_t)0x5546, (q15_t)0x5541, (q15_t)0x553d, + (q15_t)0x5538, (q15_t)0x5533, (q15_t)0x552f, (q15_t)0x552a, (q15_t)0x5525, (q15_t)0x5520, (q15_t)0x551c, (q15_t)0x5517, + (q15_t)0x5512, (q15_t)0x550e, (q15_t)0x5509, (q15_t)0x5504, (q15_t)0x5500, (q15_t)0x54fb, (q15_t)0x54f6, (q15_t)0x54f2, + (q15_t)0x54ed, (q15_t)0x54e8, (q15_t)0x54e3, (q15_t)0x54df, (q15_t)0x54da, (q15_t)0x54d5, (q15_t)0x54d1, (q15_t)0x54cc, + (q15_t)0x54c7, (q15_t)0x54c2, (q15_t)0x54be, (q15_t)0x54b9, (q15_t)0x54b4, (q15_t)0x54b0, (q15_t)0x54ab, (q15_t)0x54a6, + (q15_t)0x54a2, (q15_t)0x549d, (q15_t)0x5498, (q15_t)0x5493, (q15_t)0x548f, (q15_t)0x548a, (q15_t)0x5485, (q15_t)0x5480, + (q15_t)0x547c, (q15_t)0x5477, (q15_t)0x5472, (q15_t)0x546e, (q15_t)0x5469, (q15_t)0x5464, (q15_t)0x545f, (q15_t)0x545b, + (q15_t)0x5456, (q15_t)0x5451, (q15_t)0x544d, (q15_t)0x5448, (q15_t)0x5443, (q15_t)0x543e, (q15_t)0x543a, (q15_t)0x5435, + (q15_t)0x5430, (q15_t)0x542b, (q15_t)0x5427, (q15_t)0x5422, (q15_t)0x541d, (q15_t)0x5418, (q15_t)0x5414, (q15_t)0x540f, + (q15_t)0x540a, (q15_t)0x5406, (q15_t)0x5401, (q15_t)0x53fc, (q15_t)0x53f7, (q15_t)0x53f3, (q15_t)0x53ee, (q15_t)0x53e9, + (q15_t)0x53e4, (q15_t)0x53e0, (q15_t)0x53db, (q15_t)0x53d6, (q15_t)0x53d1, (q15_t)0x53cd, (q15_t)0x53c8, (q15_t)0x53c3, + (q15_t)0x53be, (q15_t)0x53ba, (q15_t)0x53b5, (q15_t)0x53b0, (q15_t)0x53ab, (q15_t)0x53a7, (q15_t)0x53a2, (q15_t)0x539d, + (q15_t)0x5398, (q15_t)0x5394, (q15_t)0x538f, (q15_t)0x538a, (q15_t)0x5385, (q15_t)0x5380, (q15_t)0x537c, (q15_t)0x5377, + (q15_t)0x5372, (q15_t)0x536d, (q15_t)0x5369, (q15_t)0x5364, (q15_t)0x535f, (q15_t)0x535a, (q15_t)0x5356, (q15_t)0x5351, + (q15_t)0x534c, (q15_t)0x5347, (q15_t)0x5343, (q15_t)0x533e, (q15_t)0x5339, (q15_t)0x5334, (q15_t)0x532f, (q15_t)0x532b, + (q15_t)0x5326, (q15_t)0x5321, (q15_t)0x531c, (q15_t)0x5318, (q15_t)0x5313, (q15_t)0x530e, (q15_t)0x5309, (q15_t)0x5304, + (q15_t)0x5300, (q15_t)0x52fb, (q15_t)0x52f6, (q15_t)0x52f1, (q15_t)0x52ec, (q15_t)0x52e8, (q15_t)0x52e3, (q15_t)0x52de, + (q15_t)0x52d9, (q15_t)0x52d5, (q15_t)0x52d0, (q15_t)0x52cb, (q15_t)0x52c6, (q15_t)0x52c1, (q15_t)0x52bd, (q15_t)0x52b8, + (q15_t)0x52b3, (q15_t)0x52ae, (q15_t)0x52a9, (q15_t)0x52a5, (q15_t)0x52a0, (q15_t)0x529b, (q15_t)0x5296, (q15_t)0x5291, + (q15_t)0x528d, (q15_t)0x5288, (q15_t)0x5283, (q15_t)0x527e, (q15_t)0x5279, (q15_t)0x5275, (q15_t)0x5270, (q15_t)0x526b, + (q15_t)0x5266, (q15_t)0x5261, (q15_t)0x525d, (q15_t)0x5258, (q15_t)0x5253, (q15_t)0x524e, (q15_t)0x5249, (q15_t)0x5244, + (q15_t)0x5240, (q15_t)0x523b, (q15_t)0x5236, (q15_t)0x5231, (q15_t)0x522c, (q15_t)0x5228, (q15_t)0x5223, (q15_t)0x521e, + (q15_t)0x5219, (q15_t)0x5214, (q15_t)0x520f, (q15_t)0x520b, (q15_t)0x5206, (q15_t)0x5201, (q15_t)0x51fc, (q15_t)0x51f7, + (q15_t)0x51f3, (q15_t)0x51ee, (q15_t)0x51e9, (q15_t)0x51e4, (q15_t)0x51df, (q15_t)0x51da, (q15_t)0x51d6, (q15_t)0x51d1, + (q15_t)0x51cc, (q15_t)0x51c7, (q15_t)0x51c2, (q15_t)0x51bd, (q15_t)0x51b9, (q15_t)0x51b4, (q15_t)0x51af, (q15_t)0x51aa, + (q15_t)0x51a5, (q15_t)0x51a0, (q15_t)0x519c, (q15_t)0x5197, (q15_t)0x5192, (q15_t)0x518d, (q15_t)0x5188, (q15_t)0x5183, + (q15_t)0x517e, (q15_t)0x517a, (q15_t)0x5175, (q15_t)0x5170, (q15_t)0x516b, (q15_t)0x5166, (q15_t)0x5161, (q15_t)0x515d, + (q15_t)0x5158, (q15_t)0x5153, (q15_t)0x514e, (q15_t)0x5149, (q15_t)0x5144, (q15_t)0x513f, (q15_t)0x513b, (q15_t)0x5136, + (q15_t)0x5131, (q15_t)0x512c, (q15_t)0x5127, (q15_t)0x5122, (q15_t)0x511d, (q15_t)0x5119, (q15_t)0x5114, (q15_t)0x510f, + (q15_t)0x510a, (q15_t)0x5105, (q15_t)0x5100, (q15_t)0x50fb, (q15_t)0x50f7, (q15_t)0x50f2, (q15_t)0x50ed, (q15_t)0x50e8, + (q15_t)0x50e3, (q15_t)0x50de, (q15_t)0x50d9, (q15_t)0x50d4, (q15_t)0x50d0, (q15_t)0x50cb, (q15_t)0x50c6, (q15_t)0x50c1, + (q15_t)0x50bc, (q15_t)0x50b7, (q15_t)0x50b2, (q15_t)0x50ad, (q15_t)0x50a9, (q15_t)0x50a4, (q15_t)0x509f, (q15_t)0x509a, + (q15_t)0x5095, (q15_t)0x5090, (q15_t)0x508b, (q15_t)0x5086, (q15_t)0x5082, (q15_t)0x507d, (q15_t)0x5078, (q15_t)0x5073, + (q15_t)0x506e, (q15_t)0x5069, (q15_t)0x5064, (q15_t)0x505f, (q15_t)0x505a, (q15_t)0x5056, (q15_t)0x5051, (q15_t)0x504c, + (q15_t)0x5047, (q15_t)0x5042, (q15_t)0x503d, (q15_t)0x5038, (q15_t)0x5033, (q15_t)0x502e, (q15_t)0x5029, (q15_t)0x5025, + (q15_t)0x5020, (q15_t)0x501b, (q15_t)0x5016, (q15_t)0x5011, (q15_t)0x500c, (q15_t)0x5007, (q15_t)0x5002, (q15_t)0x4ffd, + (q15_t)0x4ff8, (q15_t)0x4ff4, (q15_t)0x4fef, (q15_t)0x4fea, (q15_t)0x4fe5, (q15_t)0x4fe0, (q15_t)0x4fdb, (q15_t)0x4fd6, + (q15_t)0x4fd1, (q15_t)0x4fcc, (q15_t)0x4fc7, (q15_t)0x4fc2, (q15_t)0x4fbe, (q15_t)0x4fb9, (q15_t)0x4fb4, (q15_t)0x4faf, + (q15_t)0x4faa, (q15_t)0x4fa5, (q15_t)0x4fa0, (q15_t)0x4f9b, (q15_t)0x4f96, (q15_t)0x4f91, (q15_t)0x4f8c, (q15_t)0x4f87, + (q15_t)0x4f82, (q15_t)0x4f7e, (q15_t)0x4f79, (q15_t)0x4f74, (q15_t)0x4f6f, (q15_t)0x4f6a, (q15_t)0x4f65, (q15_t)0x4f60, + (q15_t)0x4f5b, (q15_t)0x4f56, (q15_t)0x4f51, (q15_t)0x4f4c, (q15_t)0x4f47, (q15_t)0x4f42, (q15_t)0x4f3d, (q15_t)0x4f39, + (q15_t)0x4f34, (q15_t)0x4f2f, (q15_t)0x4f2a, (q15_t)0x4f25, (q15_t)0x4f20, (q15_t)0x4f1b, (q15_t)0x4f16, (q15_t)0x4f11, + (q15_t)0x4f0c, (q15_t)0x4f07, (q15_t)0x4f02, (q15_t)0x4efd, (q15_t)0x4ef8, (q15_t)0x4ef3, (q15_t)0x4eee, (q15_t)0x4ee9, + (q15_t)0x4ee5, (q15_t)0x4ee0, (q15_t)0x4edb, (q15_t)0x4ed6, (q15_t)0x4ed1, (q15_t)0x4ecc, (q15_t)0x4ec7, (q15_t)0x4ec2, + (q15_t)0x4ebd, (q15_t)0x4eb8, (q15_t)0x4eb3, (q15_t)0x4eae, (q15_t)0x4ea9, (q15_t)0x4ea4, (q15_t)0x4e9f, (q15_t)0x4e9a, + (q15_t)0x4e95, (q15_t)0x4e90, (q15_t)0x4e8b, (q15_t)0x4e86, (q15_t)0x4e81, (q15_t)0x4e7c, (q15_t)0x4e78, (q15_t)0x4e73, + (q15_t)0x4e6e, (q15_t)0x4e69, (q15_t)0x4e64, (q15_t)0x4e5f, (q15_t)0x4e5a, (q15_t)0x4e55, (q15_t)0x4e50, (q15_t)0x4e4b, + (q15_t)0x4e46, (q15_t)0x4e41, (q15_t)0x4e3c, (q15_t)0x4e37, (q15_t)0x4e32, (q15_t)0x4e2d, (q15_t)0x4e28, (q15_t)0x4e23, + (q15_t)0x4e1e, (q15_t)0x4e19, (q15_t)0x4e14, (q15_t)0x4e0f, (q15_t)0x4e0a, (q15_t)0x4e05, (q15_t)0x4e00, (q15_t)0x4dfb, + (q15_t)0x4df6, (q15_t)0x4df1, (q15_t)0x4dec, (q15_t)0x4de7, (q15_t)0x4de2, (q15_t)0x4ddd, (q15_t)0x4dd8, (q15_t)0x4dd3, + (q15_t)0x4dce, (q15_t)0x4dc9, (q15_t)0x4dc4, (q15_t)0x4dbf, (q15_t)0x4dba, (q15_t)0x4db5, (q15_t)0x4db0, (q15_t)0x4dab, + (q15_t)0x4da6, (q15_t)0x4da1, (q15_t)0x4d9c, (q15_t)0x4d97, (q15_t)0x4d92, (q15_t)0x4d8d, (q15_t)0x4d88, (q15_t)0x4d83, + (q15_t)0x4d7e, (q15_t)0x4d79, (q15_t)0x4d74, (q15_t)0x4d6f, (q15_t)0x4d6a, (q15_t)0x4d65, (q15_t)0x4d60, (q15_t)0x4d5b, + (q15_t)0x4d56, (q15_t)0x4d51, (q15_t)0x4d4c, (q15_t)0x4d47, (q15_t)0x4d42, (q15_t)0x4d3d, (q15_t)0x4d38, (q15_t)0x4d33, + (q15_t)0x4d2e, (q15_t)0x4d29, (q15_t)0x4d24, (q15_t)0x4d1f, (q15_t)0x4d1a, (q15_t)0x4d15, (q15_t)0x4d10, (q15_t)0x4d0b, + (q15_t)0x4d06, (q15_t)0x4d01, (q15_t)0x4cfc, (q15_t)0x4cf7, (q15_t)0x4cf2, (q15_t)0x4ced, (q15_t)0x4ce8, (q15_t)0x4ce3, + (q15_t)0x4cde, (q15_t)0x4cd9, (q15_t)0x4cd4, (q15_t)0x4ccf, (q15_t)0x4cca, (q15_t)0x4cc5, (q15_t)0x4cc0, (q15_t)0x4cbb, + (q15_t)0x4cb6, (q15_t)0x4cb1, (q15_t)0x4cac, (q15_t)0x4ca7, (q15_t)0x4ca2, (q15_t)0x4c9d, (q15_t)0x4c98, (q15_t)0x4c93, + (q15_t)0x4c8e, (q15_t)0x4c88, (q15_t)0x4c83, (q15_t)0x4c7e, (q15_t)0x4c79, (q15_t)0x4c74, (q15_t)0x4c6f, (q15_t)0x4c6a, + (q15_t)0x4c65, (q15_t)0x4c60, (q15_t)0x4c5b, (q15_t)0x4c56, (q15_t)0x4c51, (q15_t)0x4c4c, (q15_t)0x4c47, (q15_t)0x4c42, + (q15_t)0x4c3d, (q15_t)0x4c38, (q15_t)0x4c33, (q15_t)0x4c2e, (q15_t)0x4c29, (q15_t)0x4c24, (q15_t)0x4c1f, (q15_t)0x4c1a, + (q15_t)0x4c14, (q15_t)0x4c0f, (q15_t)0x4c0a, (q15_t)0x4c05, (q15_t)0x4c00, (q15_t)0x4bfb, (q15_t)0x4bf6, (q15_t)0x4bf1, + (q15_t)0x4bec, (q15_t)0x4be7, (q15_t)0x4be2, (q15_t)0x4bdd, (q15_t)0x4bd8, (q15_t)0x4bd3, (q15_t)0x4bce, (q15_t)0x4bc9, + (q15_t)0x4bc4, (q15_t)0x4bbe, (q15_t)0x4bb9, (q15_t)0x4bb4, (q15_t)0x4baf, (q15_t)0x4baa, (q15_t)0x4ba5, (q15_t)0x4ba0, + (q15_t)0x4b9b, (q15_t)0x4b96, (q15_t)0x4b91, (q15_t)0x4b8c, (q15_t)0x4b87, (q15_t)0x4b82, (q15_t)0x4b7d, (q15_t)0x4b77, + (q15_t)0x4b72, (q15_t)0x4b6d, (q15_t)0x4b68, (q15_t)0x4b63, (q15_t)0x4b5e, (q15_t)0x4b59, (q15_t)0x4b54, (q15_t)0x4b4f, + (q15_t)0x4b4a, (q15_t)0x4b45, (q15_t)0x4b40, (q15_t)0x4b3b, (q15_t)0x4b35, (q15_t)0x4b30, (q15_t)0x4b2b, (q15_t)0x4b26, + (q15_t)0x4b21, (q15_t)0x4b1c, (q15_t)0x4b17, (q15_t)0x4b12, (q15_t)0x4b0d, (q15_t)0x4b08, (q15_t)0x4b03, (q15_t)0x4afd, + (q15_t)0x4af8, (q15_t)0x4af3, (q15_t)0x4aee, (q15_t)0x4ae9, (q15_t)0x4ae4, (q15_t)0x4adf, (q15_t)0x4ada, (q15_t)0x4ad5, + (q15_t)0x4ad0, (q15_t)0x4acb, (q15_t)0x4ac5, (q15_t)0x4ac0, (q15_t)0x4abb, (q15_t)0x4ab6, (q15_t)0x4ab1, (q15_t)0x4aac, + (q15_t)0x4aa7, (q15_t)0x4aa2, (q15_t)0x4a9d, (q15_t)0x4a97, (q15_t)0x4a92, (q15_t)0x4a8d, (q15_t)0x4a88, (q15_t)0x4a83, + (q15_t)0x4a7e, (q15_t)0x4a79, (q15_t)0x4a74, (q15_t)0x4a6f, (q15_t)0x4a6a, (q15_t)0x4a64, (q15_t)0x4a5f, (q15_t)0x4a5a, + (q15_t)0x4a55, (q15_t)0x4a50, (q15_t)0x4a4b, (q15_t)0x4a46, (q15_t)0x4a41, (q15_t)0x4a3b, (q15_t)0x4a36, (q15_t)0x4a31, + (q15_t)0x4a2c, (q15_t)0x4a27, (q15_t)0x4a22, (q15_t)0x4a1d, (q15_t)0x4a18, (q15_t)0x4a12, (q15_t)0x4a0d, (q15_t)0x4a08, + (q15_t)0x4a03, (q15_t)0x49fe, (q15_t)0x49f9, (q15_t)0x49f4, (q15_t)0x49ef, (q15_t)0x49e9, (q15_t)0x49e4, (q15_t)0x49df, + (q15_t)0x49da, (q15_t)0x49d5, (q15_t)0x49d0, (q15_t)0x49cb, (q15_t)0x49c6, (q15_t)0x49c0, (q15_t)0x49bb, (q15_t)0x49b6, + (q15_t)0x49b1, (q15_t)0x49ac, (q15_t)0x49a7, (q15_t)0x49a2, (q15_t)0x499c, (q15_t)0x4997, (q15_t)0x4992, (q15_t)0x498d, + (q15_t)0x4988, (q15_t)0x4983, (q15_t)0x497e, (q15_t)0x4978, (q15_t)0x4973, (q15_t)0x496e, (q15_t)0x4969, (q15_t)0x4964, + (q15_t)0x495f, (q15_t)0x495a, (q15_t)0x4954, (q15_t)0x494f, (q15_t)0x494a, (q15_t)0x4945, (q15_t)0x4940, (q15_t)0x493b, + (q15_t)0x4936, (q15_t)0x4930, (q15_t)0x492b, (q15_t)0x4926, (q15_t)0x4921, (q15_t)0x491c, (q15_t)0x4917, (q15_t)0x4911, + (q15_t)0x490c, (q15_t)0x4907, (q15_t)0x4902, (q15_t)0x48fd, (q15_t)0x48f8, (q15_t)0x48f2, (q15_t)0x48ed, (q15_t)0x48e8, + (q15_t)0x48e3, (q15_t)0x48de, (q15_t)0x48d9, (q15_t)0x48d3, (q15_t)0x48ce, (q15_t)0x48c9, (q15_t)0x48c4, (q15_t)0x48bf, + (q15_t)0x48ba, (q15_t)0x48b4, (q15_t)0x48af, (q15_t)0x48aa, (q15_t)0x48a5, (q15_t)0x48a0, (q15_t)0x489b, (q15_t)0x4895, + (q15_t)0x4890, (q15_t)0x488b, (q15_t)0x4886, (q15_t)0x4881, (q15_t)0x487c, (q15_t)0x4876, (q15_t)0x4871, (q15_t)0x486c, + (q15_t)0x4867, (q15_t)0x4862, (q15_t)0x485c, (q15_t)0x4857, (q15_t)0x4852, (q15_t)0x484d, (q15_t)0x4848, (q15_t)0x4843, + (q15_t)0x483d, (q15_t)0x4838, (q15_t)0x4833, (q15_t)0x482e, (q15_t)0x4829, (q15_t)0x4823, (q15_t)0x481e, (q15_t)0x4819, + (q15_t)0x4814, (q15_t)0x480f, (q15_t)0x4809, (q15_t)0x4804, (q15_t)0x47ff, (q15_t)0x47fa, (q15_t)0x47f5, (q15_t)0x47ef, + (q15_t)0x47ea, (q15_t)0x47e5, (q15_t)0x47e0, (q15_t)0x47db, (q15_t)0x47d5, (q15_t)0x47d0, (q15_t)0x47cb, (q15_t)0x47c6, + (q15_t)0x47c1, (q15_t)0x47bb, (q15_t)0x47b6, (q15_t)0x47b1, (q15_t)0x47ac, (q15_t)0x47a7, (q15_t)0x47a1, (q15_t)0x479c, + (q15_t)0x4797, (q15_t)0x4792, (q15_t)0x478d, (q15_t)0x4787, (q15_t)0x4782, (q15_t)0x477d, (q15_t)0x4778, (q15_t)0x4773, + (q15_t)0x476d, (q15_t)0x4768, (q15_t)0x4763, (q15_t)0x475e, (q15_t)0x4758, (q15_t)0x4753, (q15_t)0x474e, (q15_t)0x4749, + (q15_t)0x4744, (q15_t)0x473e, (q15_t)0x4739, (q15_t)0x4734, (q15_t)0x472f, (q15_t)0x4729, (q15_t)0x4724, (q15_t)0x471f, + (q15_t)0x471a, (q15_t)0x4715, (q15_t)0x470f, (q15_t)0x470a, (q15_t)0x4705, (q15_t)0x4700, (q15_t)0x46fa, (q15_t)0x46f5, + (q15_t)0x46f0, (q15_t)0x46eb, (q15_t)0x46e6, (q15_t)0x46e0, (q15_t)0x46db, (q15_t)0x46d6, (q15_t)0x46d1, (q15_t)0x46cb, + (q15_t)0x46c6, (q15_t)0x46c1, (q15_t)0x46bc, (q15_t)0x46b6, (q15_t)0x46b1, (q15_t)0x46ac, (q15_t)0x46a7, (q15_t)0x46a1, + (q15_t)0x469c, (q15_t)0x4697, (q15_t)0x4692, (q15_t)0x468d, (q15_t)0x4687, (q15_t)0x4682, (q15_t)0x467d, (q15_t)0x4678, + (q15_t)0x4672, (q15_t)0x466d, (q15_t)0x4668, (q15_t)0x4663, (q15_t)0x465d, (q15_t)0x4658, (q15_t)0x4653, (q15_t)0x464e, + (q15_t)0x4648, (q15_t)0x4643, (q15_t)0x463e, (q15_t)0x4639, (q15_t)0x4633, (q15_t)0x462e, (q15_t)0x4629, (q15_t)0x4624, + (q15_t)0x461e, (q15_t)0x4619, (q15_t)0x4614, (q15_t)0x460e, (q15_t)0x4609, (q15_t)0x4604, (q15_t)0x45ff, (q15_t)0x45f9, + (q15_t)0x45f4, (q15_t)0x45ef, (q15_t)0x45ea, (q15_t)0x45e4, (q15_t)0x45df, (q15_t)0x45da, (q15_t)0x45d5, (q15_t)0x45cf, + (q15_t)0x45ca, (q15_t)0x45c5, (q15_t)0x45c0, (q15_t)0x45ba, (q15_t)0x45b5, (q15_t)0x45b0, (q15_t)0x45aa, (q15_t)0x45a5, + (q15_t)0x45a0, (q15_t)0x459b, (q15_t)0x4595, (q15_t)0x4590, (q15_t)0x458b, (q15_t)0x4586, (q15_t)0x4580, (q15_t)0x457b, + (q15_t)0x4576, (q15_t)0x4570, (q15_t)0x456b, (q15_t)0x4566, (q15_t)0x4561, (q15_t)0x455b, (q15_t)0x4556, (q15_t)0x4551, + (q15_t)0x454b, (q15_t)0x4546, (q15_t)0x4541, (q15_t)0x453c, (q15_t)0x4536, (q15_t)0x4531, (q15_t)0x452c, (q15_t)0x4526, + (q15_t)0x4521, (q15_t)0x451c, (q15_t)0x4517, (q15_t)0x4511, (q15_t)0x450c, (q15_t)0x4507, (q15_t)0x4501, (q15_t)0x44fc, + (q15_t)0x44f7, (q15_t)0x44f2, (q15_t)0x44ec, (q15_t)0x44e7, (q15_t)0x44e2, (q15_t)0x44dc, (q15_t)0x44d7, (q15_t)0x44d2, + (q15_t)0x44cd, (q15_t)0x44c7, (q15_t)0x44c2, (q15_t)0x44bd, (q15_t)0x44b7, (q15_t)0x44b2, (q15_t)0x44ad, (q15_t)0x44a7, + (q15_t)0x44a2, (q15_t)0x449d, (q15_t)0x4497, (q15_t)0x4492, (q15_t)0x448d, (q15_t)0x4488, (q15_t)0x4482, (q15_t)0x447d, + (q15_t)0x4478, (q15_t)0x4472, (q15_t)0x446d, (q15_t)0x4468, (q15_t)0x4462, (q15_t)0x445d, (q15_t)0x4458, (q15_t)0x4452, + (q15_t)0x444d, (q15_t)0x4448, (q15_t)0x4443, (q15_t)0x443d, (q15_t)0x4438, (q15_t)0x4433, (q15_t)0x442d, (q15_t)0x4428, + (q15_t)0x4423, (q15_t)0x441d, (q15_t)0x4418, (q15_t)0x4413, (q15_t)0x440d, (q15_t)0x4408, (q15_t)0x4403, (q15_t)0x43fd, + (q15_t)0x43f8, (q15_t)0x43f3, (q15_t)0x43ed, (q15_t)0x43e8, (q15_t)0x43e3, (q15_t)0x43dd, (q15_t)0x43d8, (q15_t)0x43d3, + (q15_t)0x43cd, (q15_t)0x43c8, (q15_t)0x43c3, (q15_t)0x43bd, (q15_t)0x43b8, (q15_t)0x43b3, (q15_t)0x43ad, (q15_t)0x43a8, + (q15_t)0x43a3, (q15_t)0x439d, (q15_t)0x4398, (q15_t)0x4393, (q15_t)0x438d, (q15_t)0x4388, (q15_t)0x4383, (q15_t)0x437d, + (q15_t)0x4378, (q15_t)0x4373, (q15_t)0x436d, (q15_t)0x4368, (q15_t)0x4363, (q15_t)0x435d, (q15_t)0x4358, (q15_t)0x4353, + (q15_t)0x434d, (q15_t)0x4348, (q15_t)0x4343, (q15_t)0x433d, (q15_t)0x4338, (q15_t)0x4333, (q15_t)0x432d, (q15_t)0x4328, + (q15_t)0x4323, (q15_t)0x431d, (q15_t)0x4318, (q15_t)0x4313, (q15_t)0x430d, (q15_t)0x4308, (q15_t)0x4302, (q15_t)0x42fd, + (q15_t)0x42f8, (q15_t)0x42f2, (q15_t)0x42ed, (q15_t)0x42e8, (q15_t)0x42e2, (q15_t)0x42dd, (q15_t)0x42d8, (q15_t)0x42d2, + (q15_t)0x42cd, (q15_t)0x42c8, (q15_t)0x42c2, (q15_t)0x42bd, (q15_t)0x42b7, (q15_t)0x42b2, (q15_t)0x42ad, (q15_t)0x42a7, + (q15_t)0x42a2, (q15_t)0x429d, (q15_t)0x4297, (q15_t)0x4292, (q15_t)0x428d, (q15_t)0x4287, (q15_t)0x4282, (q15_t)0x427c, + (q15_t)0x4277, (q15_t)0x4272, (q15_t)0x426c, (q15_t)0x4267, (q15_t)0x4262, (q15_t)0x425c, (q15_t)0x4257, (q15_t)0x4251, + (q15_t)0x424c, (q15_t)0x4247, (q15_t)0x4241, (q15_t)0x423c, (q15_t)0x4237, (q15_t)0x4231, (q15_t)0x422c, (q15_t)0x4226, + (q15_t)0x4221, (q15_t)0x421c, (q15_t)0x4216, (q15_t)0x4211, (q15_t)0x420c, (q15_t)0x4206, (q15_t)0x4201, (q15_t)0x41fb, + (q15_t)0x41f6, (q15_t)0x41f1, (q15_t)0x41eb, (q15_t)0x41e6, (q15_t)0x41e0, (q15_t)0x41db, (q15_t)0x41d6, (q15_t)0x41d0, + (q15_t)0x41cb, (q15_t)0x41c6, (q15_t)0x41c0, (q15_t)0x41bb, (q15_t)0x41b5, (q15_t)0x41b0, (q15_t)0x41ab, (q15_t)0x41a5, + (q15_t)0x41a0, (q15_t)0x419a, (q15_t)0x4195, (q15_t)0x4190, (q15_t)0x418a, (q15_t)0x4185, (q15_t)0x417f, (q15_t)0x417a, + (q15_t)0x4175, (q15_t)0x416f, (q15_t)0x416a, (q15_t)0x4164, (q15_t)0x415f, (q15_t)0x415a, (q15_t)0x4154, (q15_t)0x414f, + (q15_t)0x4149, (q15_t)0x4144, (q15_t)0x413f, (q15_t)0x4139, (q15_t)0x4134, (q15_t)0x412e, (q15_t)0x4129, (q15_t)0x4124, + (q15_t)0x411e, (q15_t)0x4119, (q15_t)0x4113, (q15_t)0x410e, (q15_t)0x4108, (q15_t)0x4103, (q15_t)0x40fe, (q15_t)0x40f8, + (q15_t)0x40f3, (q15_t)0x40ed, (q15_t)0x40e8, (q15_t)0x40e3, (q15_t)0x40dd, (q15_t)0x40d8, (q15_t)0x40d2, (q15_t)0x40cd, + (q15_t)0x40c8, (q15_t)0x40c2, (q15_t)0x40bd, (q15_t)0x40b7, (q15_t)0x40b2, (q15_t)0x40ac, (q15_t)0x40a7, (q15_t)0x40a2, + (q15_t)0x409c, (q15_t)0x4097, (q15_t)0x4091, (q15_t)0x408c, (q15_t)0x4086, (q15_t)0x4081, (q15_t)0x407c, (q15_t)0x4076, + (q15_t)0x4071, (q15_t)0x406b, (q15_t)0x4066, (q15_t)0x4060, (q15_t)0x405b, (q15_t)0x4056, (q15_t)0x4050, (q15_t)0x404b, + (q15_t)0x4045, (q15_t)0x4040, (q15_t)0x403a, (q15_t)0x4035, (q15_t)0x4030, (q15_t)0x402a, (q15_t)0x4025, (q15_t)0x401f, + (q15_t)0x401a, (q15_t)0x4014, (q15_t)0x400f, (q15_t)0x4009, (q15_t)0x4004, (q15_t)0x3fff, (q15_t)0x3ff9, (q15_t)0x3ff4, + (q15_t)0x3fee, (q15_t)0x3fe9, (q15_t)0x3fe3, (q15_t)0x3fde, (q15_t)0x3fd8, (q15_t)0x3fd3, (q15_t)0x3fce, (q15_t)0x3fc8, + (q15_t)0x3fc3, (q15_t)0x3fbd, (q15_t)0x3fb8, (q15_t)0x3fb2, (q15_t)0x3fad, (q15_t)0x3fa7, (q15_t)0x3fa2, (q15_t)0x3f9d, + (q15_t)0x3f97, (q15_t)0x3f92, (q15_t)0x3f8c, (q15_t)0x3f87, (q15_t)0x3f81, (q15_t)0x3f7c, (q15_t)0x3f76, (q15_t)0x3f71, + (q15_t)0x3f6b, (q15_t)0x3f66, (q15_t)0x3f61, (q15_t)0x3f5b, (q15_t)0x3f56, (q15_t)0x3f50, (q15_t)0x3f4b, (q15_t)0x3f45, + (q15_t)0x3f40, (q15_t)0x3f3a, (q15_t)0x3f35, (q15_t)0x3f2f, (q15_t)0x3f2a, (q15_t)0x3f24, (q15_t)0x3f1f, (q15_t)0x3f1a, + (q15_t)0x3f14, (q15_t)0x3f0f, (q15_t)0x3f09, (q15_t)0x3f04, (q15_t)0x3efe, (q15_t)0x3ef9, (q15_t)0x3ef3, (q15_t)0x3eee, + (q15_t)0x3ee8, (q15_t)0x3ee3, (q15_t)0x3edd, (q15_t)0x3ed8, (q15_t)0x3ed2, (q15_t)0x3ecd, (q15_t)0x3ec7, (q15_t)0x3ec2, + (q15_t)0x3ebd, (q15_t)0x3eb7, (q15_t)0x3eb2, (q15_t)0x3eac, (q15_t)0x3ea7, (q15_t)0x3ea1, (q15_t)0x3e9c, (q15_t)0x3e96, + (q15_t)0x3e91, (q15_t)0x3e8b, (q15_t)0x3e86, (q15_t)0x3e80, (q15_t)0x3e7b, (q15_t)0x3e75, (q15_t)0x3e70, (q15_t)0x3e6a, + (q15_t)0x3e65, (q15_t)0x3e5f, (q15_t)0x3e5a, (q15_t)0x3e54, (q15_t)0x3e4f, (q15_t)0x3e49, (q15_t)0x3e44, (q15_t)0x3e3e, + (q15_t)0x3e39, (q15_t)0x3e33, (q15_t)0x3e2e, (q15_t)0x3e28, (q15_t)0x3e23, (q15_t)0x3e1d, (q15_t)0x3e18, (q15_t)0x3e12, + (q15_t)0x3e0d, (q15_t)0x3e07, (q15_t)0x3e02, (q15_t)0x3dfc, (q15_t)0x3df7, (q15_t)0x3df1, (q15_t)0x3dec, (q15_t)0x3de6, + (q15_t)0x3de1, (q15_t)0x3ddb, (q15_t)0x3dd6, (q15_t)0x3dd0, (q15_t)0x3dcb, (q15_t)0x3dc5, (q15_t)0x3dc0, (q15_t)0x3dba, + (q15_t)0x3db5, (q15_t)0x3daf, (q15_t)0x3daa, (q15_t)0x3da4, (q15_t)0x3d9f, (q15_t)0x3d99, (q15_t)0x3d94, (q15_t)0x3d8e, + (q15_t)0x3d89, (q15_t)0x3d83, (q15_t)0x3d7e, (q15_t)0x3d78, (q15_t)0x3d73, (q15_t)0x3d6d, (q15_t)0x3d68, (q15_t)0x3d62, + (q15_t)0x3d5d, (q15_t)0x3d57, (q15_t)0x3d52, (q15_t)0x3d4c, (q15_t)0x3d47, (q15_t)0x3d41, (q15_t)0x3d3c, (q15_t)0x3d36, + (q15_t)0x3d31, (q15_t)0x3d2b, (q15_t)0x3d26, (q15_t)0x3d20, (q15_t)0x3d1b, (q15_t)0x3d15, (q15_t)0x3d10, (q15_t)0x3d0a, + (q15_t)0x3d04, (q15_t)0x3cff, (q15_t)0x3cf9, (q15_t)0x3cf4, (q15_t)0x3cee, (q15_t)0x3ce9, (q15_t)0x3ce3, (q15_t)0x3cde, + (q15_t)0x3cd8, (q15_t)0x3cd3, (q15_t)0x3ccd, (q15_t)0x3cc8, (q15_t)0x3cc2, (q15_t)0x3cbd, (q15_t)0x3cb7, (q15_t)0x3cb2, + (q15_t)0x3cac, (q15_t)0x3ca7, (q15_t)0x3ca1, (q15_t)0x3c9b, (q15_t)0x3c96, (q15_t)0x3c90, (q15_t)0x3c8b, (q15_t)0x3c85, + (q15_t)0x3c80, (q15_t)0x3c7a, (q15_t)0x3c75, (q15_t)0x3c6f, (q15_t)0x3c6a, (q15_t)0x3c64, (q15_t)0x3c5f, (q15_t)0x3c59, + (q15_t)0x3c53, (q15_t)0x3c4e, (q15_t)0x3c48, (q15_t)0x3c43, (q15_t)0x3c3d, (q15_t)0x3c38, (q15_t)0x3c32, (q15_t)0x3c2d, + (q15_t)0x3c27, (q15_t)0x3c22, (q15_t)0x3c1c, (q15_t)0x3c16, (q15_t)0x3c11, (q15_t)0x3c0b, (q15_t)0x3c06, (q15_t)0x3c00, + (q15_t)0x3bfb, (q15_t)0x3bf5, (q15_t)0x3bf0, (q15_t)0x3bea, (q15_t)0x3be5, (q15_t)0x3bdf, (q15_t)0x3bd9, (q15_t)0x3bd4, + (q15_t)0x3bce, (q15_t)0x3bc9, (q15_t)0x3bc3, (q15_t)0x3bbe, (q15_t)0x3bb8, (q15_t)0x3bb3, (q15_t)0x3bad, (q15_t)0x3ba7, + (q15_t)0x3ba2, (q15_t)0x3b9c, (q15_t)0x3b97, (q15_t)0x3b91, (q15_t)0x3b8c, (q15_t)0x3b86, (q15_t)0x3b80, (q15_t)0x3b7b, + (q15_t)0x3b75, (q15_t)0x3b70, (q15_t)0x3b6a, (q15_t)0x3b65, (q15_t)0x3b5f, (q15_t)0x3b5a, (q15_t)0x3b54, (q15_t)0x3b4e, + (q15_t)0x3b49, (q15_t)0x3b43, (q15_t)0x3b3e, (q15_t)0x3b38, (q15_t)0x3b33, (q15_t)0x3b2d, (q15_t)0x3b27, (q15_t)0x3b22, + (q15_t)0x3b1c, (q15_t)0x3b17, (q15_t)0x3b11, (q15_t)0x3b0c, (q15_t)0x3b06, (q15_t)0x3b00, (q15_t)0x3afb, (q15_t)0x3af5, + (q15_t)0x3af0, (q15_t)0x3aea, (q15_t)0x3ae4, (q15_t)0x3adf, (q15_t)0x3ad9, (q15_t)0x3ad4, (q15_t)0x3ace, (q15_t)0x3ac9, + (q15_t)0x3ac3, (q15_t)0x3abd, (q15_t)0x3ab8, (q15_t)0x3ab2, (q15_t)0x3aad, (q15_t)0x3aa7, (q15_t)0x3aa2, (q15_t)0x3a9c, + (q15_t)0x3a96, (q15_t)0x3a91, (q15_t)0x3a8b, (q15_t)0x3a86, (q15_t)0x3a80, (q15_t)0x3a7a, (q15_t)0x3a75, (q15_t)0x3a6f, + (q15_t)0x3a6a, (q15_t)0x3a64, (q15_t)0x3a5e, (q15_t)0x3a59, (q15_t)0x3a53, (q15_t)0x3a4e, (q15_t)0x3a48, (q15_t)0x3a42, + (q15_t)0x3a3d, (q15_t)0x3a37, (q15_t)0x3a32, (q15_t)0x3a2c, (q15_t)0x3a26, (q15_t)0x3a21, (q15_t)0x3a1b, (q15_t)0x3a16, + (q15_t)0x3a10, (q15_t)0x3a0b, (q15_t)0x3a05, (q15_t)0x39ff, (q15_t)0x39fa, (q15_t)0x39f4, (q15_t)0x39ee, (q15_t)0x39e9, + (q15_t)0x39e3, (q15_t)0x39de, (q15_t)0x39d8, (q15_t)0x39d2, (q15_t)0x39cd, (q15_t)0x39c7, (q15_t)0x39c2, (q15_t)0x39bc, + (q15_t)0x39b6, (q15_t)0x39b1, (q15_t)0x39ab, (q15_t)0x39a6, (q15_t)0x39a0, (q15_t)0x399a, (q15_t)0x3995, (q15_t)0x398f, + (q15_t)0x398a, (q15_t)0x3984, (q15_t)0x397e, (q15_t)0x3979, (q15_t)0x3973, (q15_t)0x396d, (q15_t)0x3968, (q15_t)0x3962, + (q15_t)0x395d, (q15_t)0x3957, (q15_t)0x3951, (q15_t)0x394c, (q15_t)0x3946, (q15_t)0x3941, (q15_t)0x393b, (q15_t)0x3935, + (q15_t)0x3930, (q15_t)0x392a, (q15_t)0x3924, (q15_t)0x391f, (q15_t)0x3919, (q15_t)0x3914, (q15_t)0x390e, (q15_t)0x3908, + (q15_t)0x3903, (q15_t)0x38fd, (q15_t)0x38f7, (q15_t)0x38f2, (q15_t)0x38ec, (q15_t)0x38e7, (q15_t)0x38e1, (q15_t)0x38db, + (q15_t)0x38d6, (q15_t)0x38d0, (q15_t)0x38ca, (q15_t)0x38c5, (q15_t)0x38bf, (q15_t)0x38ba, (q15_t)0x38b4, (q15_t)0x38ae, + (q15_t)0x38a9, (q15_t)0x38a3, (q15_t)0x389d, (q15_t)0x3898, (q15_t)0x3892, (q15_t)0x388c, (q15_t)0x3887, (q15_t)0x3881, + (q15_t)0x387c, (q15_t)0x3876, (q15_t)0x3870, (q15_t)0x386b, (q15_t)0x3865, (q15_t)0x385f, (q15_t)0x385a, (q15_t)0x3854, + (q15_t)0x384e, (q15_t)0x3849, (q15_t)0x3843, (q15_t)0x383d, (q15_t)0x3838, (q15_t)0x3832, (q15_t)0x382d, (q15_t)0x3827, + (q15_t)0x3821, (q15_t)0x381c, (q15_t)0x3816, (q15_t)0x3810, (q15_t)0x380b, (q15_t)0x3805, (q15_t)0x37ff, (q15_t)0x37fa, + (q15_t)0x37f4, (q15_t)0x37ee, (q15_t)0x37e9, (q15_t)0x37e3, (q15_t)0x37dd, (q15_t)0x37d8, (q15_t)0x37d2, (q15_t)0x37cc, + (q15_t)0x37c7, (q15_t)0x37c1, (q15_t)0x37bc, (q15_t)0x37b6, (q15_t)0x37b0, (q15_t)0x37ab, (q15_t)0x37a5, (q15_t)0x379f, + (q15_t)0x379a, (q15_t)0x3794, (q15_t)0x378e, (q15_t)0x3789, (q15_t)0x3783, (q15_t)0x377d, (q15_t)0x3778, (q15_t)0x3772, + (q15_t)0x376c, (q15_t)0x3767, (q15_t)0x3761, (q15_t)0x375b, (q15_t)0x3756, (q15_t)0x3750, (q15_t)0x374a, (q15_t)0x3745, + (q15_t)0x373f, (q15_t)0x3739, (q15_t)0x3734, (q15_t)0x372e, (q15_t)0x3728, (q15_t)0x3723, (q15_t)0x371d, (q15_t)0x3717, + (q15_t)0x3712, (q15_t)0x370c, (q15_t)0x3706, (q15_t)0x3701, (q15_t)0x36fb, (q15_t)0x36f5, (q15_t)0x36f0, (q15_t)0x36ea, + (q15_t)0x36e4, (q15_t)0x36df, (q15_t)0x36d9, (q15_t)0x36d3, (q15_t)0x36ce, (q15_t)0x36c8, (q15_t)0x36c2, (q15_t)0x36bc, + (q15_t)0x36b7, (q15_t)0x36b1, (q15_t)0x36ab, (q15_t)0x36a6, (q15_t)0x36a0, (q15_t)0x369a, (q15_t)0x3695, (q15_t)0x368f, + (q15_t)0x3689, (q15_t)0x3684, (q15_t)0x367e, (q15_t)0x3678, (q15_t)0x3673, (q15_t)0x366d, (q15_t)0x3667, (q15_t)0x3662, + (q15_t)0x365c, (q15_t)0x3656, (q15_t)0x3650, (q15_t)0x364b, (q15_t)0x3645, (q15_t)0x363f, (q15_t)0x363a, (q15_t)0x3634, + (q15_t)0x362e, (q15_t)0x3629, (q15_t)0x3623, (q15_t)0x361d, (q15_t)0x3618, (q15_t)0x3612, (q15_t)0x360c, (q15_t)0x3606, + (q15_t)0x3601, (q15_t)0x35fb, (q15_t)0x35f5, (q15_t)0x35f0, (q15_t)0x35ea, (q15_t)0x35e4, (q15_t)0x35df, (q15_t)0x35d9, + (q15_t)0x35d3, (q15_t)0x35cd, (q15_t)0x35c8, (q15_t)0x35c2, (q15_t)0x35bc, (q15_t)0x35b7, (q15_t)0x35b1, (q15_t)0x35ab, + (q15_t)0x35a6, (q15_t)0x35a0, (q15_t)0x359a, (q15_t)0x3594, (q15_t)0x358f, (q15_t)0x3589, (q15_t)0x3583, (q15_t)0x357e, + (q15_t)0x3578, (q15_t)0x3572, (q15_t)0x356c, (q15_t)0x3567, (q15_t)0x3561, (q15_t)0x355b, (q15_t)0x3556, (q15_t)0x3550, + (q15_t)0x354a, (q15_t)0x3544, (q15_t)0x353f, (q15_t)0x3539, (q15_t)0x3533, (q15_t)0x352e, (q15_t)0x3528, (q15_t)0x3522, + (q15_t)0x351c, (q15_t)0x3517, (q15_t)0x3511, (q15_t)0x350b, (q15_t)0x3506, (q15_t)0x3500, (q15_t)0x34fa, (q15_t)0x34f4, + (q15_t)0x34ef, (q15_t)0x34e9, (q15_t)0x34e3, (q15_t)0x34de, (q15_t)0x34d8, (q15_t)0x34d2, (q15_t)0x34cc, (q15_t)0x34c7, + (q15_t)0x34c1, (q15_t)0x34bb, (q15_t)0x34b6, (q15_t)0x34b0, (q15_t)0x34aa, (q15_t)0x34a4, (q15_t)0x349f, (q15_t)0x3499, + (q15_t)0x3493, (q15_t)0x348d, (q15_t)0x3488, (q15_t)0x3482, (q15_t)0x347c, (q15_t)0x3476, (q15_t)0x3471, (q15_t)0x346b, + (q15_t)0x3465, (q15_t)0x3460, (q15_t)0x345a, (q15_t)0x3454, (q15_t)0x344e, (q15_t)0x3449, (q15_t)0x3443, (q15_t)0x343d, + (q15_t)0x3437, (q15_t)0x3432, (q15_t)0x342c, (q15_t)0x3426, (q15_t)0x3420, (q15_t)0x341b, (q15_t)0x3415, (q15_t)0x340f, + (q15_t)0x340a, (q15_t)0x3404, (q15_t)0x33fe, (q15_t)0x33f8, (q15_t)0x33f3, (q15_t)0x33ed, (q15_t)0x33e7, (q15_t)0x33e1, + (q15_t)0x33dc, (q15_t)0x33d6, (q15_t)0x33d0, (q15_t)0x33ca, (q15_t)0x33c5, (q15_t)0x33bf, (q15_t)0x33b9, (q15_t)0x33b3, + (q15_t)0x33ae, (q15_t)0x33a8, (q15_t)0x33a2, (q15_t)0x339c, (q15_t)0x3397, (q15_t)0x3391, (q15_t)0x338b, (q15_t)0x3385, + (q15_t)0x3380, (q15_t)0x337a, (q15_t)0x3374, (q15_t)0x336e, (q15_t)0x3369, (q15_t)0x3363, (q15_t)0x335d, (q15_t)0x3357, + (q15_t)0x3352, (q15_t)0x334c, (q15_t)0x3346, (q15_t)0x3340, (q15_t)0x333b, (q15_t)0x3335, (q15_t)0x332f, (q15_t)0x3329, + (q15_t)0x3324, (q15_t)0x331e, (q15_t)0x3318, (q15_t)0x3312, (q15_t)0x330c, (q15_t)0x3307, (q15_t)0x3301, (q15_t)0x32fb, + (q15_t)0x32f5, (q15_t)0x32f0, (q15_t)0x32ea, (q15_t)0x32e4, (q15_t)0x32de, (q15_t)0x32d9, (q15_t)0x32d3, (q15_t)0x32cd, + (q15_t)0x32c7, (q15_t)0x32c2, (q15_t)0x32bc, (q15_t)0x32b6, (q15_t)0x32b0, (q15_t)0x32aa, (q15_t)0x32a5, (q15_t)0x329f, + (q15_t)0x3299, (q15_t)0x3293, (q15_t)0x328e, (q15_t)0x3288, (q15_t)0x3282, (q15_t)0x327c, (q15_t)0x3276, (q15_t)0x3271, + (q15_t)0x326b, (q15_t)0x3265, (q15_t)0x325f, (q15_t)0x325a, (q15_t)0x3254, (q15_t)0x324e, (q15_t)0x3248, (q15_t)0x3243, + (q15_t)0x323d, (q15_t)0x3237, (q15_t)0x3231, (q15_t)0x322b, (q15_t)0x3226, (q15_t)0x3220, (q15_t)0x321a, (q15_t)0x3214, + (q15_t)0x320e, (q15_t)0x3209, (q15_t)0x3203, (q15_t)0x31fd, (q15_t)0x31f7, (q15_t)0x31f2, (q15_t)0x31ec, (q15_t)0x31e6, + (q15_t)0x31e0, (q15_t)0x31da, (q15_t)0x31d5, (q15_t)0x31cf, (q15_t)0x31c9, (q15_t)0x31c3, (q15_t)0x31bd, (q15_t)0x31b8, + (q15_t)0x31b2, (q15_t)0x31ac, (q15_t)0x31a6, (q15_t)0x31a1, (q15_t)0x319b, (q15_t)0x3195, (q15_t)0x318f, (q15_t)0x3189, + (q15_t)0x3184, (q15_t)0x317e, (q15_t)0x3178, (q15_t)0x3172, (q15_t)0x316c, (q15_t)0x3167, (q15_t)0x3161, (q15_t)0x315b, + (q15_t)0x3155, (q15_t)0x314f, (q15_t)0x314a, (q15_t)0x3144, (q15_t)0x313e, (q15_t)0x3138, (q15_t)0x3132, (q15_t)0x312d, + (q15_t)0x3127, (q15_t)0x3121, (q15_t)0x311b, (q15_t)0x3115, (q15_t)0x3110, (q15_t)0x310a, (q15_t)0x3104, (q15_t)0x30fe, + (q15_t)0x30f8, (q15_t)0x30f3, (q15_t)0x30ed, (q15_t)0x30e7, (q15_t)0x30e1, (q15_t)0x30db, (q15_t)0x30d6, (q15_t)0x30d0, + (q15_t)0x30ca, (q15_t)0x30c4, (q15_t)0x30be, (q15_t)0x30b8, (q15_t)0x30b3, (q15_t)0x30ad, (q15_t)0x30a7, (q15_t)0x30a1, + (q15_t)0x309b, (q15_t)0x3096, (q15_t)0x3090, (q15_t)0x308a, (q15_t)0x3084, (q15_t)0x307e, (q15_t)0x3079, (q15_t)0x3073, + (q15_t)0x306d, (q15_t)0x3067, (q15_t)0x3061, (q15_t)0x305b, (q15_t)0x3056, (q15_t)0x3050, (q15_t)0x304a, (q15_t)0x3044, + (q15_t)0x303e, (q15_t)0x3039, (q15_t)0x3033, (q15_t)0x302d, (q15_t)0x3027, (q15_t)0x3021, (q15_t)0x301b, (q15_t)0x3016, + (q15_t)0x3010, (q15_t)0x300a, (q15_t)0x3004, (q15_t)0x2ffe, (q15_t)0x2ff8, (q15_t)0x2ff3, (q15_t)0x2fed, (q15_t)0x2fe7, + (q15_t)0x2fe1, (q15_t)0x2fdb, (q15_t)0x2fd6, (q15_t)0x2fd0, (q15_t)0x2fca, (q15_t)0x2fc4, (q15_t)0x2fbe, (q15_t)0x2fb8, + (q15_t)0x2fb3, (q15_t)0x2fad, (q15_t)0x2fa7, (q15_t)0x2fa1, (q15_t)0x2f9b, (q15_t)0x2f95, (q15_t)0x2f90, (q15_t)0x2f8a, + (q15_t)0x2f84, (q15_t)0x2f7e, (q15_t)0x2f78, (q15_t)0x2f72, (q15_t)0x2f6d, (q15_t)0x2f67, (q15_t)0x2f61, (q15_t)0x2f5b, + (q15_t)0x2f55, (q15_t)0x2f4f, (q15_t)0x2f4a, (q15_t)0x2f44, (q15_t)0x2f3e, (q15_t)0x2f38, (q15_t)0x2f32, (q15_t)0x2f2c, + (q15_t)0x2f27, (q15_t)0x2f21, (q15_t)0x2f1b, (q15_t)0x2f15, (q15_t)0x2f0f, (q15_t)0x2f09, (q15_t)0x2f03, (q15_t)0x2efe, + (q15_t)0x2ef8, (q15_t)0x2ef2, (q15_t)0x2eec, (q15_t)0x2ee6, (q15_t)0x2ee0, (q15_t)0x2edb, (q15_t)0x2ed5, (q15_t)0x2ecf, + (q15_t)0x2ec9, (q15_t)0x2ec3, (q15_t)0x2ebd, (q15_t)0x2eb7, (q15_t)0x2eb2, (q15_t)0x2eac, (q15_t)0x2ea6, (q15_t)0x2ea0, + (q15_t)0x2e9a, (q15_t)0x2e94, (q15_t)0x2e8e, (q15_t)0x2e89, (q15_t)0x2e83, (q15_t)0x2e7d, (q15_t)0x2e77, (q15_t)0x2e71, + (q15_t)0x2e6b, (q15_t)0x2e65, (q15_t)0x2e60, (q15_t)0x2e5a, (q15_t)0x2e54, (q15_t)0x2e4e, (q15_t)0x2e48, (q15_t)0x2e42, + (q15_t)0x2e3c, (q15_t)0x2e37, (q15_t)0x2e31, (q15_t)0x2e2b, (q15_t)0x2e25, (q15_t)0x2e1f, (q15_t)0x2e19, (q15_t)0x2e13, + (q15_t)0x2e0e, (q15_t)0x2e08, (q15_t)0x2e02, (q15_t)0x2dfc, (q15_t)0x2df6, (q15_t)0x2df0, (q15_t)0x2dea, (q15_t)0x2de5, + (q15_t)0x2ddf, (q15_t)0x2dd9, (q15_t)0x2dd3, (q15_t)0x2dcd, (q15_t)0x2dc7, (q15_t)0x2dc1, (q15_t)0x2dbb, (q15_t)0x2db6, + (q15_t)0x2db0, (q15_t)0x2daa, (q15_t)0x2da4, (q15_t)0x2d9e, (q15_t)0x2d98, (q15_t)0x2d92, (q15_t)0x2d8d, (q15_t)0x2d87, + (q15_t)0x2d81, (q15_t)0x2d7b, (q15_t)0x2d75, (q15_t)0x2d6f, (q15_t)0x2d69, (q15_t)0x2d63, (q15_t)0x2d5e, (q15_t)0x2d58, + (q15_t)0x2d52, (q15_t)0x2d4c, (q15_t)0x2d46, (q15_t)0x2d40, (q15_t)0x2d3a, (q15_t)0x2d34, (q15_t)0x2d2f, (q15_t)0x2d29, + (q15_t)0x2d23, (q15_t)0x2d1d, (q15_t)0x2d17, (q15_t)0x2d11, (q15_t)0x2d0b, (q15_t)0x2d05, (q15_t)0x2cff, (q15_t)0x2cfa, + (q15_t)0x2cf4, (q15_t)0x2cee, (q15_t)0x2ce8, (q15_t)0x2ce2, (q15_t)0x2cdc, (q15_t)0x2cd6, (q15_t)0x2cd0, (q15_t)0x2ccb, + (q15_t)0x2cc5, (q15_t)0x2cbf, (q15_t)0x2cb9, (q15_t)0x2cb3, (q15_t)0x2cad, (q15_t)0x2ca7, (q15_t)0x2ca1, (q15_t)0x2c9b, + (q15_t)0x2c96, (q15_t)0x2c90, (q15_t)0x2c8a, (q15_t)0x2c84, (q15_t)0x2c7e, (q15_t)0x2c78, (q15_t)0x2c72, (q15_t)0x2c6c, + (q15_t)0x2c66, (q15_t)0x2c61, (q15_t)0x2c5b, (q15_t)0x2c55, (q15_t)0x2c4f, (q15_t)0x2c49, (q15_t)0x2c43, (q15_t)0x2c3d, + (q15_t)0x2c37, (q15_t)0x2c31, (q15_t)0x2c2b, (q15_t)0x2c26, (q15_t)0x2c20, (q15_t)0x2c1a, (q15_t)0x2c14, (q15_t)0x2c0e, + (q15_t)0x2c08, (q15_t)0x2c02, (q15_t)0x2bfc, (q15_t)0x2bf6, (q15_t)0x2bf0, (q15_t)0x2beb, (q15_t)0x2be5, (q15_t)0x2bdf, + (q15_t)0x2bd9, (q15_t)0x2bd3, (q15_t)0x2bcd, (q15_t)0x2bc7, (q15_t)0x2bc1, (q15_t)0x2bbb, (q15_t)0x2bb5, (q15_t)0x2bb0, + (q15_t)0x2baa, (q15_t)0x2ba4, (q15_t)0x2b9e, (q15_t)0x2b98, (q15_t)0x2b92, (q15_t)0x2b8c, (q15_t)0x2b86, (q15_t)0x2b80, + (q15_t)0x2b7a, (q15_t)0x2b74, (q15_t)0x2b6f, (q15_t)0x2b69, (q15_t)0x2b63, (q15_t)0x2b5d, (q15_t)0x2b57, (q15_t)0x2b51, + (q15_t)0x2b4b, (q15_t)0x2b45, (q15_t)0x2b3f, (q15_t)0x2b39, (q15_t)0x2b33, (q15_t)0x2b2d, (q15_t)0x2b28, (q15_t)0x2b22, + (q15_t)0x2b1c, (q15_t)0x2b16, (q15_t)0x2b10, (q15_t)0x2b0a, (q15_t)0x2b04, (q15_t)0x2afe, (q15_t)0x2af8, (q15_t)0x2af2, + (q15_t)0x2aec, (q15_t)0x2ae6, (q15_t)0x2ae1, (q15_t)0x2adb, (q15_t)0x2ad5, (q15_t)0x2acf, (q15_t)0x2ac9, (q15_t)0x2ac3, + (q15_t)0x2abd, (q15_t)0x2ab7, (q15_t)0x2ab1, (q15_t)0x2aab, (q15_t)0x2aa5, (q15_t)0x2a9f, (q15_t)0x2a99, (q15_t)0x2a94, + (q15_t)0x2a8e, (q15_t)0x2a88, (q15_t)0x2a82, (q15_t)0x2a7c, (q15_t)0x2a76, (q15_t)0x2a70, (q15_t)0x2a6a, (q15_t)0x2a64, + (q15_t)0x2a5e, (q15_t)0x2a58, (q15_t)0x2a52, (q15_t)0x2a4c, (q15_t)0x2a47, (q15_t)0x2a41, (q15_t)0x2a3b, (q15_t)0x2a35, + (q15_t)0x2a2f, (q15_t)0x2a29, (q15_t)0x2a23, (q15_t)0x2a1d, (q15_t)0x2a17, (q15_t)0x2a11, (q15_t)0x2a0b, (q15_t)0x2a05, + (q15_t)0x29ff, (q15_t)0x29f9, (q15_t)0x29f3, (q15_t)0x29ee, (q15_t)0x29e8, (q15_t)0x29e2, (q15_t)0x29dc, (q15_t)0x29d6, + (q15_t)0x29d0, (q15_t)0x29ca, (q15_t)0x29c4, (q15_t)0x29be, (q15_t)0x29b8, (q15_t)0x29b2, (q15_t)0x29ac, (q15_t)0x29a6, + (q15_t)0x29a0, (q15_t)0x299a, (q15_t)0x2994, (q15_t)0x298e, (q15_t)0x2989, (q15_t)0x2983, (q15_t)0x297d, (q15_t)0x2977, + (q15_t)0x2971, (q15_t)0x296b, (q15_t)0x2965, (q15_t)0x295f, (q15_t)0x2959, (q15_t)0x2953, (q15_t)0x294d, (q15_t)0x2947, + (q15_t)0x2941, (q15_t)0x293b, (q15_t)0x2935, (q15_t)0x292f, (q15_t)0x2929, (q15_t)0x2923, (q15_t)0x291d, (q15_t)0x2918, + (q15_t)0x2912, (q15_t)0x290c, (q15_t)0x2906, (q15_t)0x2900, (q15_t)0x28fa, (q15_t)0x28f4, (q15_t)0x28ee, (q15_t)0x28e8, + (q15_t)0x28e2, (q15_t)0x28dc, (q15_t)0x28d6, (q15_t)0x28d0, (q15_t)0x28ca, (q15_t)0x28c4, (q15_t)0x28be, (q15_t)0x28b8, + (q15_t)0x28b2, (q15_t)0x28ac, (q15_t)0x28a6, (q15_t)0x28a0, (q15_t)0x289a, (q15_t)0x2895, (q15_t)0x288f, (q15_t)0x2889, + (q15_t)0x2883, (q15_t)0x287d, (q15_t)0x2877, (q15_t)0x2871, (q15_t)0x286b, (q15_t)0x2865, (q15_t)0x285f, (q15_t)0x2859, + (q15_t)0x2853, (q15_t)0x284d, (q15_t)0x2847, (q15_t)0x2841, (q15_t)0x283b, (q15_t)0x2835, (q15_t)0x282f, (q15_t)0x2829, + (q15_t)0x2823, (q15_t)0x281d, (q15_t)0x2817, (q15_t)0x2811, (q15_t)0x280b, (q15_t)0x2805, (q15_t)0x27ff, (q15_t)0x27f9, + (q15_t)0x27f3, (q15_t)0x27ee, (q15_t)0x27e8, (q15_t)0x27e2, (q15_t)0x27dc, (q15_t)0x27d6, (q15_t)0x27d0, (q15_t)0x27ca, + (q15_t)0x27c4, (q15_t)0x27be, (q15_t)0x27b8, (q15_t)0x27b2, (q15_t)0x27ac, (q15_t)0x27a6, (q15_t)0x27a0, (q15_t)0x279a, + (q15_t)0x2794, (q15_t)0x278e, (q15_t)0x2788, (q15_t)0x2782, (q15_t)0x277c, (q15_t)0x2776, (q15_t)0x2770, (q15_t)0x276a, + (q15_t)0x2764, (q15_t)0x275e, (q15_t)0x2758, (q15_t)0x2752, (q15_t)0x274c, (q15_t)0x2746, (q15_t)0x2740, (q15_t)0x273a, + (q15_t)0x2734, (q15_t)0x272e, (q15_t)0x2728, (q15_t)0x2722, (q15_t)0x271c, (q15_t)0x2716, (q15_t)0x2710, (q15_t)0x270a, + (q15_t)0x2704, (q15_t)0x26fe, (q15_t)0x26f8, (q15_t)0x26f2, (q15_t)0x26ec, (q15_t)0x26e7, (q15_t)0x26e1, (q15_t)0x26db, + (q15_t)0x26d5, (q15_t)0x26cf, (q15_t)0x26c9, (q15_t)0x26c3, (q15_t)0x26bd, (q15_t)0x26b7, (q15_t)0x26b1, (q15_t)0x26ab, + (q15_t)0x26a5, (q15_t)0x269f, (q15_t)0x2699, (q15_t)0x2693, (q15_t)0x268d, (q15_t)0x2687, (q15_t)0x2681, (q15_t)0x267b, + (q15_t)0x2675, (q15_t)0x266f, (q15_t)0x2669, (q15_t)0x2663, (q15_t)0x265d, (q15_t)0x2657, (q15_t)0x2651, (q15_t)0x264b, + (q15_t)0x2645, (q15_t)0x263f, (q15_t)0x2639, (q15_t)0x2633, (q15_t)0x262d, (q15_t)0x2627, (q15_t)0x2621, (q15_t)0x261b, + (q15_t)0x2615, (q15_t)0x260f, (q15_t)0x2609, (q15_t)0x2603, (q15_t)0x25fd, (q15_t)0x25f7, (q15_t)0x25f1, (q15_t)0x25eb, + (q15_t)0x25e5, (q15_t)0x25df, (q15_t)0x25d9, (q15_t)0x25d3, (q15_t)0x25cd, (q15_t)0x25c7, (q15_t)0x25c1, (q15_t)0x25bb, + (q15_t)0x25b5, (q15_t)0x25af, (q15_t)0x25a9, (q15_t)0x25a3, (q15_t)0x259d, (q15_t)0x2597, (q15_t)0x2591, (q15_t)0x258b, + (q15_t)0x2585, (q15_t)0x257f, (q15_t)0x2579, (q15_t)0x2573, (q15_t)0x256d, (q15_t)0x2567, (q15_t)0x2561, (q15_t)0x255b, + (q15_t)0x2555, (q15_t)0x254f, (q15_t)0x2549, (q15_t)0x2543, (q15_t)0x253d, (q15_t)0x2537, (q15_t)0x2531, (q15_t)0x252b, + (q15_t)0x2525, (q15_t)0x251f, (q15_t)0x2519, (q15_t)0x2513, (q15_t)0x250c, (q15_t)0x2506, (q15_t)0x2500, (q15_t)0x24fa, + (q15_t)0x24f4, (q15_t)0x24ee, (q15_t)0x24e8, (q15_t)0x24e2, (q15_t)0x24dc, (q15_t)0x24d6, (q15_t)0x24d0, (q15_t)0x24ca, + (q15_t)0x24c4, (q15_t)0x24be, (q15_t)0x24b8, (q15_t)0x24b2, (q15_t)0x24ac, (q15_t)0x24a6, (q15_t)0x24a0, (q15_t)0x249a, + (q15_t)0x2494, (q15_t)0x248e, (q15_t)0x2488, (q15_t)0x2482, (q15_t)0x247c, (q15_t)0x2476, (q15_t)0x2470, (q15_t)0x246a, + (q15_t)0x2464, (q15_t)0x245e, (q15_t)0x2458, (q15_t)0x2452, (q15_t)0x244c, (q15_t)0x2446, (q15_t)0x2440, (q15_t)0x243a, + (q15_t)0x2434, (q15_t)0x242e, (q15_t)0x2428, (q15_t)0x2422, (q15_t)0x241c, (q15_t)0x2416, (q15_t)0x2410, (q15_t)0x240a, + (q15_t)0x2404, (q15_t)0x23fd, (q15_t)0x23f7, (q15_t)0x23f1, (q15_t)0x23eb, (q15_t)0x23e5, (q15_t)0x23df, (q15_t)0x23d9, + (q15_t)0x23d3, (q15_t)0x23cd, (q15_t)0x23c7, (q15_t)0x23c1, (q15_t)0x23bb, (q15_t)0x23b5, (q15_t)0x23af, (q15_t)0x23a9, + (q15_t)0x23a3, (q15_t)0x239d, (q15_t)0x2397, (q15_t)0x2391, (q15_t)0x238b, (q15_t)0x2385, (q15_t)0x237f, (q15_t)0x2379, + (q15_t)0x2373, (q15_t)0x236d, (q15_t)0x2367, (q15_t)0x2361, (q15_t)0x235b, (q15_t)0x2355, (q15_t)0x234e, (q15_t)0x2348, + (q15_t)0x2342, (q15_t)0x233c, (q15_t)0x2336, (q15_t)0x2330, (q15_t)0x232a, (q15_t)0x2324, (q15_t)0x231e, (q15_t)0x2318, + (q15_t)0x2312, (q15_t)0x230c, (q15_t)0x2306, (q15_t)0x2300, (q15_t)0x22fa, (q15_t)0x22f4, (q15_t)0x22ee, (q15_t)0x22e8, + (q15_t)0x22e2, (q15_t)0x22dc, (q15_t)0x22d6, (q15_t)0x22d0, (q15_t)0x22ca, (q15_t)0x22c4, (q15_t)0x22bd, (q15_t)0x22b7, + (q15_t)0x22b1, (q15_t)0x22ab, (q15_t)0x22a5, (q15_t)0x229f, (q15_t)0x2299, (q15_t)0x2293, (q15_t)0x228d, (q15_t)0x2287, + (q15_t)0x2281, (q15_t)0x227b, (q15_t)0x2275, (q15_t)0x226f, (q15_t)0x2269, (q15_t)0x2263, (q15_t)0x225d, (q15_t)0x2257, + (q15_t)0x2251, (q15_t)0x224a, (q15_t)0x2244, (q15_t)0x223e, (q15_t)0x2238, (q15_t)0x2232, (q15_t)0x222c, (q15_t)0x2226, + (q15_t)0x2220, (q15_t)0x221a, (q15_t)0x2214, (q15_t)0x220e, (q15_t)0x2208, (q15_t)0x2202, (q15_t)0x21fc, (q15_t)0x21f6, + (q15_t)0x21f0, (q15_t)0x21ea, (q15_t)0x21e4, (q15_t)0x21dd, (q15_t)0x21d7, (q15_t)0x21d1, (q15_t)0x21cb, (q15_t)0x21c5, + (q15_t)0x21bf, (q15_t)0x21b9, (q15_t)0x21b3, (q15_t)0x21ad, (q15_t)0x21a7, (q15_t)0x21a1, (q15_t)0x219b, (q15_t)0x2195, + (q15_t)0x218f, (q15_t)0x2189, (q15_t)0x2183, (q15_t)0x217c, (q15_t)0x2176, (q15_t)0x2170, (q15_t)0x216a, (q15_t)0x2164, + (q15_t)0x215e, (q15_t)0x2158, (q15_t)0x2152, (q15_t)0x214c, (q15_t)0x2146, (q15_t)0x2140, (q15_t)0x213a, (q15_t)0x2134, + (q15_t)0x212e, (q15_t)0x2128, (q15_t)0x2121, (q15_t)0x211b, (q15_t)0x2115, (q15_t)0x210f, (q15_t)0x2109, (q15_t)0x2103, + (q15_t)0x20fd, (q15_t)0x20f7, (q15_t)0x20f1, (q15_t)0x20eb, (q15_t)0x20e5, (q15_t)0x20df, (q15_t)0x20d9, (q15_t)0x20d3, + (q15_t)0x20cc, (q15_t)0x20c6, (q15_t)0x20c0, (q15_t)0x20ba, (q15_t)0x20b4, (q15_t)0x20ae, (q15_t)0x20a8, (q15_t)0x20a2, + (q15_t)0x209c, (q15_t)0x2096, (q15_t)0x2090, (q15_t)0x208a, (q15_t)0x2084, (q15_t)0x207e, (q15_t)0x2077, (q15_t)0x2071, + (q15_t)0x206b, (q15_t)0x2065, (q15_t)0x205f, (q15_t)0x2059, (q15_t)0x2053, (q15_t)0x204d, (q15_t)0x2047, (q15_t)0x2041, + (q15_t)0x203b, (q15_t)0x2035, (q15_t)0x202e, (q15_t)0x2028, (q15_t)0x2022, (q15_t)0x201c, (q15_t)0x2016, (q15_t)0x2010, + (q15_t)0x200a, (q15_t)0x2004, (q15_t)0x1ffe, (q15_t)0x1ff8, (q15_t)0x1ff2, (q15_t)0x1fec, (q15_t)0x1fe5, (q15_t)0x1fdf, + (q15_t)0x1fd9, (q15_t)0x1fd3, (q15_t)0x1fcd, (q15_t)0x1fc7, (q15_t)0x1fc1, (q15_t)0x1fbb, (q15_t)0x1fb5, (q15_t)0x1faf, + (q15_t)0x1fa9, (q15_t)0x1fa3, (q15_t)0x1f9c, (q15_t)0x1f96, (q15_t)0x1f90, (q15_t)0x1f8a, (q15_t)0x1f84, (q15_t)0x1f7e, + (q15_t)0x1f78, (q15_t)0x1f72, (q15_t)0x1f6c, (q15_t)0x1f66, (q15_t)0x1f60, (q15_t)0x1f59, (q15_t)0x1f53, (q15_t)0x1f4d, + (q15_t)0x1f47, (q15_t)0x1f41, (q15_t)0x1f3b, (q15_t)0x1f35, (q15_t)0x1f2f, (q15_t)0x1f29, (q15_t)0x1f23, (q15_t)0x1f1d, + (q15_t)0x1f16, (q15_t)0x1f10, (q15_t)0x1f0a, (q15_t)0x1f04, (q15_t)0x1efe, (q15_t)0x1ef8, (q15_t)0x1ef2, (q15_t)0x1eec, + (q15_t)0x1ee6, (q15_t)0x1ee0, (q15_t)0x1ed9, (q15_t)0x1ed3, (q15_t)0x1ecd, (q15_t)0x1ec7, (q15_t)0x1ec1, (q15_t)0x1ebb, + (q15_t)0x1eb5, (q15_t)0x1eaf, (q15_t)0x1ea9, (q15_t)0x1ea3, (q15_t)0x1e9c, (q15_t)0x1e96, (q15_t)0x1e90, (q15_t)0x1e8a, + (q15_t)0x1e84, (q15_t)0x1e7e, (q15_t)0x1e78, (q15_t)0x1e72, (q15_t)0x1e6c, (q15_t)0x1e66, (q15_t)0x1e5f, (q15_t)0x1e59, + (q15_t)0x1e53, (q15_t)0x1e4d, (q15_t)0x1e47, (q15_t)0x1e41, (q15_t)0x1e3b, (q15_t)0x1e35, (q15_t)0x1e2f, (q15_t)0x1e29, + (q15_t)0x1e22, (q15_t)0x1e1c, (q15_t)0x1e16, (q15_t)0x1e10, (q15_t)0x1e0a, (q15_t)0x1e04, (q15_t)0x1dfe, (q15_t)0x1df8, + (q15_t)0x1df2, (q15_t)0x1deb, (q15_t)0x1de5, (q15_t)0x1ddf, (q15_t)0x1dd9, (q15_t)0x1dd3, (q15_t)0x1dcd, (q15_t)0x1dc7, + (q15_t)0x1dc1, (q15_t)0x1dbb, (q15_t)0x1db4, (q15_t)0x1dae, (q15_t)0x1da8, (q15_t)0x1da2, (q15_t)0x1d9c, (q15_t)0x1d96, + (q15_t)0x1d90, (q15_t)0x1d8a, (q15_t)0x1d84, (q15_t)0x1d7d, (q15_t)0x1d77, (q15_t)0x1d71, (q15_t)0x1d6b, (q15_t)0x1d65, + (q15_t)0x1d5f, (q15_t)0x1d59, (q15_t)0x1d53, (q15_t)0x1d4c, (q15_t)0x1d46, (q15_t)0x1d40, (q15_t)0x1d3a, (q15_t)0x1d34, + (q15_t)0x1d2e, (q15_t)0x1d28, (q15_t)0x1d22, (q15_t)0x1d1c, (q15_t)0x1d15, (q15_t)0x1d0f, (q15_t)0x1d09, (q15_t)0x1d03, + (q15_t)0x1cfd, (q15_t)0x1cf7, (q15_t)0x1cf1, (q15_t)0x1ceb, (q15_t)0x1ce4, (q15_t)0x1cde, (q15_t)0x1cd8, (q15_t)0x1cd2, + (q15_t)0x1ccc, (q15_t)0x1cc6, (q15_t)0x1cc0, (q15_t)0x1cba, (q15_t)0x1cb3, (q15_t)0x1cad, (q15_t)0x1ca7, (q15_t)0x1ca1, + (q15_t)0x1c9b, (q15_t)0x1c95, (q15_t)0x1c8f, (q15_t)0x1c89, (q15_t)0x1c83, (q15_t)0x1c7c, (q15_t)0x1c76, (q15_t)0x1c70, + (q15_t)0x1c6a, (q15_t)0x1c64, (q15_t)0x1c5e, (q15_t)0x1c58, (q15_t)0x1c51, (q15_t)0x1c4b, (q15_t)0x1c45, (q15_t)0x1c3f, + (q15_t)0x1c39, (q15_t)0x1c33, (q15_t)0x1c2d, (q15_t)0x1c27, (q15_t)0x1c20, (q15_t)0x1c1a, (q15_t)0x1c14, (q15_t)0x1c0e, + (q15_t)0x1c08, (q15_t)0x1c02, (q15_t)0x1bfc, (q15_t)0x1bf6, (q15_t)0x1bef, (q15_t)0x1be9, (q15_t)0x1be3, (q15_t)0x1bdd, + (q15_t)0x1bd7, (q15_t)0x1bd1, (q15_t)0x1bcb, (q15_t)0x1bc4, (q15_t)0x1bbe, (q15_t)0x1bb8, (q15_t)0x1bb2, (q15_t)0x1bac, + (q15_t)0x1ba6, (q15_t)0x1ba0, (q15_t)0x1b9a, (q15_t)0x1b93, (q15_t)0x1b8d, (q15_t)0x1b87, (q15_t)0x1b81, (q15_t)0x1b7b, + (q15_t)0x1b75, (q15_t)0x1b6f, (q15_t)0x1b68, (q15_t)0x1b62, (q15_t)0x1b5c, (q15_t)0x1b56, (q15_t)0x1b50, (q15_t)0x1b4a, + (q15_t)0x1b44, (q15_t)0x1b3d, (q15_t)0x1b37, (q15_t)0x1b31, (q15_t)0x1b2b, (q15_t)0x1b25, (q15_t)0x1b1f, (q15_t)0x1b19, + (q15_t)0x1b13, (q15_t)0x1b0c, (q15_t)0x1b06, (q15_t)0x1b00, (q15_t)0x1afa, (q15_t)0x1af4, (q15_t)0x1aee, (q15_t)0x1ae8, + (q15_t)0x1ae1, (q15_t)0x1adb, (q15_t)0x1ad5, (q15_t)0x1acf, (q15_t)0x1ac9, (q15_t)0x1ac3, (q15_t)0x1abd, (q15_t)0x1ab6, + (q15_t)0x1ab0, (q15_t)0x1aaa, (q15_t)0x1aa4, (q15_t)0x1a9e, (q15_t)0x1a98, (q15_t)0x1a91, (q15_t)0x1a8b, (q15_t)0x1a85, + (q15_t)0x1a7f, (q15_t)0x1a79, (q15_t)0x1a73, (q15_t)0x1a6d, (q15_t)0x1a66, (q15_t)0x1a60, (q15_t)0x1a5a, (q15_t)0x1a54, + (q15_t)0x1a4e, (q15_t)0x1a48, (q15_t)0x1a42, (q15_t)0x1a3b, (q15_t)0x1a35, (q15_t)0x1a2f, (q15_t)0x1a29, (q15_t)0x1a23, + (q15_t)0x1a1d, (q15_t)0x1a17, (q15_t)0x1a10, (q15_t)0x1a0a, (q15_t)0x1a04, (q15_t)0x19fe, (q15_t)0x19f8, (q15_t)0x19f2, + (q15_t)0x19eb, (q15_t)0x19e5, (q15_t)0x19df, (q15_t)0x19d9, (q15_t)0x19d3, (q15_t)0x19cd, (q15_t)0x19c7, (q15_t)0x19c0, + (q15_t)0x19ba, (q15_t)0x19b4, (q15_t)0x19ae, (q15_t)0x19a8, (q15_t)0x19a2, (q15_t)0x199b, (q15_t)0x1995, (q15_t)0x198f, + (q15_t)0x1989, (q15_t)0x1983, (q15_t)0x197d, (q15_t)0x1977, (q15_t)0x1970, (q15_t)0x196a, (q15_t)0x1964, (q15_t)0x195e, + (q15_t)0x1958, (q15_t)0x1952, (q15_t)0x194b, (q15_t)0x1945, (q15_t)0x193f, (q15_t)0x1939, (q15_t)0x1933, (q15_t)0x192d, + (q15_t)0x1926, (q15_t)0x1920, (q15_t)0x191a, (q15_t)0x1914, (q15_t)0x190e, (q15_t)0x1908, (q15_t)0x1901, (q15_t)0x18fb, + (q15_t)0x18f5, (q15_t)0x18ef, (q15_t)0x18e9, (q15_t)0x18e3, (q15_t)0x18dc, (q15_t)0x18d6, (q15_t)0x18d0, (q15_t)0x18ca, + (q15_t)0x18c4, (q15_t)0x18be, (q15_t)0x18b8, (q15_t)0x18b1, (q15_t)0x18ab, (q15_t)0x18a5, (q15_t)0x189f, (q15_t)0x1899, + (q15_t)0x1893, (q15_t)0x188c, (q15_t)0x1886, (q15_t)0x1880, (q15_t)0x187a, (q15_t)0x1874, (q15_t)0x186e, (q15_t)0x1867, + (q15_t)0x1861, (q15_t)0x185b, (q15_t)0x1855, (q15_t)0x184f, (q15_t)0x1848, (q15_t)0x1842, (q15_t)0x183c, (q15_t)0x1836, + (q15_t)0x1830, (q15_t)0x182a, (q15_t)0x1823, (q15_t)0x181d, (q15_t)0x1817, (q15_t)0x1811, (q15_t)0x180b, (q15_t)0x1805, + (q15_t)0x17fe, (q15_t)0x17f8, (q15_t)0x17f2, (q15_t)0x17ec, (q15_t)0x17e6, (q15_t)0x17e0, (q15_t)0x17d9, (q15_t)0x17d3, + (q15_t)0x17cd, (q15_t)0x17c7, (q15_t)0x17c1, (q15_t)0x17bb, (q15_t)0x17b4, (q15_t)0x17ae, (q15_t)0x17a8, (q15_t)0x17a2, + (q15_t)0x179c, (q15_t)0x1795, (q15_t)0x178f, (q15_t)0x1789, (q15_t)0x1783, (q15_t)0x177d, (q15_t)0x1777, (q15_t)0x1770, + (q15_t)0x176a, (q15_t)0x1764, (q15_t)0x175e, (q15_t)0x1758, (q15_t)0x1752, (q15_t)0x174b, (q15_t)0x1745, (q15_t)0x173f, + (q15_t)0x1739, (q15_t)0x1733, (q15_t)0x172c, (q15_t)0x1726, (q15_t)0x1720, (q15_t)0x171a, (q15_t)0x1714, (q15_t)0x170e, + (q15_t)0x1707, (q15_t)0x1701, (q15_t)0x16fb, (q15_t)0x16f5, (q15_t)0x16ef, (q15_t)0x16e8, (q15_t)0x16e2, (q15_t)0x16dc, + (q15_t)0x16d6, (q15_t)0x16d0, (q15_t)0x16ca, (q15_t)0x16c3, (q15_t)0x16bd, (q15_t)0x16b7, (q15_t)0x16b1, (q15_t)0x16ab, + (q15_t)0x16a4, (q15_t)0x169e, (q15_t)0x1698, (q15_t)0x1692, (q15_t)0x168c, (q15_t)0x1686, (q15_t)0x167f, (q15_t)0x1679, + (q15_t)0x1673, (q15_t)0x166d, (q15_t)0x1667, (q15_t)0x1660, (q15_t)0x165a, (q15_t)0x1654, (q15_t)0x164e, (q15_t)0x1648, + (q15_t)0x1642, (q15_t)0x163b, (q15_t)0x1635, (q15_t)0x162f, (q15_t)0x1629, (q15_t)0x1623, (q15_t)0x161c, (q15_t)0x1616, + (q15_t)0x1610, (q15_t)0x160a, (q15_t)0x1604, (q15_t)0x15fd, (q15_t)0x15f7, (q15_t)0x15f1, (q15_t)0x15eb, (q15_t)0x15e5, + (q15_t)0x15de, (q15_t)0x15d8, (q15_t)0x15d2, (q15_t)0x15cc, (q15_t)0x15c6, (q15_t)0x15c0, (q15_t)0x15b9, (q15_t)0x15b3, + (q15_t)0x15ad, (q15_t)0x15a7, (q15_t)0x15a1, (q15_t)0x159a, (q15_t)0x1594, (q15_t)0x158e, (q15_t)0x1588, (q15_t)0x1582, + (q15_t)0x157b, (q15_t)0x1575, (q15_t)0x156f, (q15_t)0x1569, (q15_t)0x1563, (q15_t)0x155c, (q15_t)0x1556, (q15_t)0x1550, + (q15_t)0x154a, (q15_t)0x1544, (q15_t)0x153d, (q15_t)0x1537, (q15_t)0x1531, (q15_t)0x152b, (q15_t)0x1525, (q15_t)0x151e, + (q15_t)0x1518, (q15_t)0x1512, (q15_t)0x150c, (q15_t)0x1506, (q15_t)0x14ff, (q15_t)0x14f9, (q15_t)0x14f3, (q15_t)0x14ed, + (q15_t)0x14e7, (q15_t)0x14e0, (q15_t)0x14da, (q15_t)0x14d4, (q15_t)0x14ce, (q15_t)0x14c8, (q15_t)0x14c1, (q15_t)0x14bb, + (q15_t)0x14b5, (q15_t)0x14af, (q15_t)0x14a9, (q15_t)0x14a2, (q15_t)0x149c, (q15_t)0x1496, (q15_t)0x1490, (q15_t)0x148a, + (q15_t)0x1483, (q15_t)0x147d, (q15_t)0x1477, (q15_t)0x1471, (q15_t)0x146b, (q15_t)0x1464, (q15_t)0x145e, (q15_t)0x1458, + (q15_t)0x1452, (q15_t)0x144c, (q15_t)0x1445, (q15_t)0x143f, (q15_t)0x1439, (q15_t)0x1433, (q15_t)0x142d, (q15_t)0x1426, + (q15_t)0x1420, (q15_t)0x141a, (q15_t)0x1414, (q15_t)0x140e, (q15_t)0x1407, (q15_t)0x1401, (q15_t)0x13fb, (q15_t)0x13f5, + (q15_t)0x13ef, (q15_t)0x13e8, (q15_t)0x13e2, (q15_t)0x13dc, (q15_t)0x13d6, (q15_t)0x13d0, (q15_t)0x13c9, (q15_t)0x13c3, + (q15_t)0x13bd, (q15_t)0x13b7, (q15_t)0x13b1, (q15_t)0x13aa, (q15_t)0x13a4, (q15_t)0x139e, (q15_t)0x1398, (q15_t)0x1391, + (q15_t)0x138b, (q15_t)0x1385, (q15_t)0x137f, (q15_t)0x1379, (q15_t)0x1372, (q15_t)0x136c, (q15_t)0x1366, (q15_t)0x1360, + (q15_t)0x135a, (q15_t)0x1353, (q15_t)0x134d, (q15_t)0x1347, (q15_t)0x1341, (q15_t)0x133b, (q15_t)0x1334, (q15_t)0x132e, + (q15_t)0x1328, (q15_t)0x1322, (q15_t)0x131b, (q15_t)0x1315, (q15_t)0x130f, (q15_t)0x1309, (q15_t)0x1303, (q15_t)0x12fc, + (q15_t)0x12f6, (q15_t)0x12f0, (q15_t)0x12ea, (q15_t)0x12e4, (q15_t)0x12dd, (q15_t)0x12d7, (q15_t)0x12d1, (q15_t)0x12cb, + (q15_t)0x12c4, (q15_t)0x12be, (q15_t)0x12b8, (q15_t)0x12b2, (q15_t)0x12ac, (q15_t)0x12a5, (q15_t)0x129f, (q15_t)0x1299, + (q15_t)0x1293, (q15_t)0x128d, (q15_t)0x1286, (q15_t)0x1280, (q15_t)0x127a, (q15_t)0x1274, (q15_t)0x126d, (q15_t)0x1267, + (q15_t)0x1261, (q15_t)0x125b, (q15_t)0x1255, (q15_t)0x124e, (q15_t)0x1248, (q15_t)0x1242, (q15_t)0x123c, (q15_t)0x1235, + (q15_t)0x122f, (q15_t)0x1229, (q15_t)0x1223, (q15_t)0x121d, (q15_t)0x1216, (q15_t)0x1210, (q15_t)0x120a, (q15_t)0x1204, + (q15_t)0x11fd, (q15_t)0x11f7, (q15_t)0x11f1, (q15_t)0x11eb, (q15_t)0x11e5, (q15_t)0x11de, (q15_t)0x11d8, (q15_t)0x11d2, + (q15_t)0x11cc, (q15_t)0x11c5, (q15_t)0x11bf, (q15_t)0x11b9, (q15_t)0x11b3, (q15_t)0x11ad, (q15_t)0x11a6, (q15_t)0x11a0, + (q15_t)0x119a, (q15_t)0x1194, (q15_t)0x118d, (q15_t)0x1187, (q15_t)0x1181, (q15_t)0x117b, (q15_t)0x1175, (q15_t)0x116e, + (q15_t)0x1168, (q15_t)0x1162, (q15_t)0x115c, (q15_t)0x1155, (q15_t)0x114f, (q15_t)0x1149, (q15_t)0x1143, (q15_t)0x113d, + (q15_t)0x1136, (q15_t)0x1130, (q15_t)0x112a, (q15_t)0x1124, (q15_t)0x111d, (q15_t)0x1117, (q15_t)0x1111, (q15_t)0x110b, + (q15_t)0x1105, (q15_t)0x10fe, (q15_t)0x10f8, (q15_t)0x10f2, (q15_t)0x10ec, (q15_t)0x10e5, (q15_t)0x10df, (q15_t)0x10d9, + (q15_t)0x10d3, (q15_t)0x10cc, (q15_t)0x10c6, (q15_t)0x10c0, (q15_t)0x10ba, (q15_t)0x10b4, (q15_t)0x10ad, (q15_t)0x10a7, + (q15_t)0x10a1, (q15_t)0x109b, (q15_t)0x1094, (q15_t)0x108e, (q15_t)0x1088, (q15_t)0x1082, (q15_t)0x107b, (q15_t)0x1075, + (q15_t)0x106f, (q15_t)0x1069, (q15_t)0x1063, (q15_t)0x105c, (q15_t)0x1056, (q15_t)0x1050, (q15_t)0x104a, (q15_t)0x1043, + (q15_t)0x103d, (q15_t)0x1037, (q15_t)0x1031, (q15_t)0x102a, (q15_t)0x1024, (q15_t)0x101e, (q15_t)0x1018, (q15_t)0x1012, + (q15_t)0x100b, (q15_t)0x1005, (q15_t)0xfff, (q15_t)0xff9, (q15_t)0xff2, (q15_t)0xfec, (q15_t)0xfe6, (q15_t)0xfe0, + (q15_t)0xfd9, (q15_t)0xfd3, (q15_t)0xfcd, (q15_t)0xfc7, (q15_t)0xfc0, (q15_t)0xfba, (q15_t)0xfb4, (q15_t)0xfae, + (q15_t)0xfa8, (q15_t)0xfa1, (q15_t)0xf9b, (q15_t)0xf95, (q15_t)0xf8f, (q15_t)0xf88, (q15_t)0xf82, (q15_t)0xf7c, + (q15_t)0xf76, (q15_t)0xf6f, (q15_t)0xf69, (q15_t)0xf63, (q15_t)0xf5d, (q15_t)0xf56, (q15_t)0xf50, (q15_t)0xf4a, + (q15_t)0xf44, (q15_t)0xf3e, (q15_t)0xf37, (q15_t)0xf31, (q15_t)0xf2b, (q15_t)0xf25, (q15_t)0xf1e, (q15_t)0xf18, + (q15_t)0xf12, (q15_t)0xf0c, (q15_t)0xf05, (q15_t)0xeff, (q15_t)0xef9, (q15_t)0xef3, (q15_t)0xeec, (q15_t)0xee6, + (q15_t)0xee0, (q15_t)0xeda, (q15_t)0xed3, (q15_t)0xecd, (q15_t)0xec7, (q15_t)0xec1, (q15_t)0xeba, (q15_t)0xeb4, + (q15_t)0xeae, (q15_t)0xea8, (q15_t)0xea1, (q15_t)0xe9b, (q15_t)0xe95, (q15_t)0xe8f, (q15_t)0xe89, (q15_t)0xe82, + (q15_t)0xe7c, (q15_t)0xe76, (q15_t)0xe70, (q15_t)0xe69, (q15_t)0xe63, (q15_t)0xe5d, (q15_t)0xe57, (q15_t)0xe50, + (q15_t)0xe4a, (q15_t)0xe44, (q15_t)0xe3e, (q15_t)0xe37, (q15_t)0xe31, (q15_t)0xe2b, (q15_t)0xe25, (q15_t)0xe1e, + (q15_t)0xe18, (q15_t)0xe12, (q15_t)0xe0c, (q15_t)0xe05, (q15_t)0xdff, (q15_t)0xdf9, (q15_t)0xdf3, (q15_t)0xdec, + (q15_t)0xde6, (q15_t)0xde0, (q15_t)0xdda, (q15_t)0xdd3, (q15_t)0xdcd, (q15_t)0xdc7, (q15_t)0xdc1, (q15_t)0xdba, + (q15_t)0xdb4, (q15_t)0xdae, (q15_t)0xda8, (q15_t)0xda1, (q15_t)0xd9b, (q15_t)0xd95, (q15_t)0xd8f, (q15_t)0xd88, + (q15_t)0xd82, (q15_t)0xd7c, (q15_t)0xd76, (q15_t)0xd6f, (q15_t)0xd69, (q15_t)0xd63, (q15_t)0xd5d, (q15_t)0xd56, + (q15_t)0xd50, (q15_t)0xd4a, (q15_t)0xd44, (q15_t)0xd3d, (q15_t)0xd37, (q15_t)0xd31, (q15_t)0xd2b, (q15_t)0xd24, + (q15_t)0xd1e, (q15_t)0xd18, (q15_t)0xd12, (q15_t)0xd0b, (q15_t)0xd05, (q15_t)0xcff, (q15_t)0xcf9, (q15_t)0xcf2, + (q15_t)0xcec, (q15_t)0xce6, (q15_t)0xce0, (q15_t)0xcd9, (q15_t)0xcd3, (q15_t)0xccd, (q15_t)0xcc7, (q15_t)0xcc0, + (q15_t)0xcba, (q15_t)0xcb4, (q15_t)0xcae, (q15_t)0xca7, (q15_t)0xca1, (q15_t)0xc9b, (q15_t)0xc95, (q15_t)0xc8e, + (q15_t)0xc88, (q15_t)0xc82, (q15_t)0xc7c, (q15_t)0xc75, (q15_t)0xc6f, (q15_t)0xc69, (q15_t)0xc63, (q15_t)0xc5c, + (q15_t)0xc56, (q15_t)0xc50, (q15_t)0xc4a, (q15_t)0xc43, (q15_t)0xc3d, (q15_t)0xc37, (q15_t)0xc31, (q15_t)0xc2a, + (q15_t)0xc24, (q15_t)0xc1e, (q15_t)0xc18, (q15_t)0xc11, (q15_t)0xc0b, (q15_t)0xc05, (q15_t)0xbff, (q15_t)0xbf8, + (q15_t)0xbf2, (q15_t)0xbec, (q15_t)0xbe6, (q15_t)0xbdf, (q15_t)0xbd9, (q15_t)0xbd3, (q15_t)0xbcd, (q15_t)0xbc6, + (q15_t)0xbc0, (q15_t)0xbba, (q15_t)0xbb4, (q15_t)0xbad, (q15_t)0xba7, (q15_t)0xba1, (q15_t)0xb9b, (q15_t)0xb94, + (q15_t)0xb8e, (q15_t)0xb88, (q15_t)0xb81, (q15_t)0xb7b, (q15_t)0xb75, (q15_t)0xb6f, (q15_t)0xb68, (q15_t)0xb62, + (q15_t)0xb5c, (q15_t)0xb56, (q15_t)0xb4f, (q15_t)0xb49, (q15_t)0xb43, (q15_t)0xb3d, (q15_t)0xb36, (q15_t)0xb30, + (q15_t)0xb2a, (q15_t)0xb24, (q15_t)0xb1d, (q15_t)0xb17, (q15_t)0xb11, (q15_t)0xb0b, (q15_t)0xb04, (q15_t)0xafe, + (q15_t)0xaf8, (q15_t)0xaf2, (q15_t)0xaeb, (q15_t)0xae5, (q15_t)0xadf, (q15_t)0xad8, (q15_t)0xad2, (q15_t)0xacc, + (q15_t)0xac6, (q15_t)0xabf, (q15_t)0xab9, (q15_t)0xab3, (q15_t)0xaad, (q15_t)0xaa6, (q15_t)0xaa0, (q15_t)0xa9a, + (q15_t)0xa94, (q15_t)0xa8d, (q15_t)0xa87, (q15_t)0xa81, (q15_t)0xa7b, (q15_t)0xa74, (q15_t)0xa6e, (q15_t)0xa68, + (q15_t)0xa62, (q15_t)0xa5b, (q15_t)0xa55, (q15_t)0xa4f, (q15_t)0xa48, (q15_t)0xa42, (q15_t)0xa3c, (q15_t)0xa36, + (q15_t)0xa2f, (q15_t)0xa29, (q15_t)0xa23, (q15_t)0xa1d, (q15_t)0xa16, (q15_t)0xa10, (q15_t)0xa0a, (q15_t)0xa04, + (q15_t)0x9fd, (q15_t)0x9f7, (q15_t)0x9f1, (q15_t)0x9eb, (q15_t)0x9e4, (q15_t)0x9de, (q15_t)0x9d8, (q15_t)0x9d1, + (q15_t)0x9cb, (q15_t)0x9c5, (q15_t)0x9bf, (q15_t)0x9b8, (q15_t)0x9b2, (q15_t)0x9ac, (q15_t)0x9a6, (q15_t)0x99f, + (q15_t)0x999, (q15_t)0x993, (q15_t)0x98d, (q15_t)0x986, (q15_t)0x980, (q15_t)0x97a, (q15_t)0x973, (q15_t)0x96d, + (q15_t)0x967, (q15_t)0x961, (q15_t)0x95a, (q15_t)0x954, (q15_t)0x94e, (q15_t)0x948, (q15_t)0x941, (q15_t)0x93b, + (q15_t)0x935, (q15_t)0x92f, (q15_t)0x928, (q15_t)0x922, (q15_t)0x91c, (q15_t)0x915, (q15_t)0x90f, (q15_t)0x909, + (q15_t)0x903, (q15_t)0x8fc, (q15_t)0x8f6, (q15_t)0x8f0, (q15_t)0x8ea, (q15_t)0x8e3, (q15_t)0x8dd, (q15_t)0x8d7, + (q15_t)0x8d1, (q15_t)0x8ca, (q15_t)0x8c4, (q15_t)0x8be, (q15_t)0x8b7, (q15_t)0x8b1, (q15_t)0x8ab, (q15_t)0x8a5, + (q15_t)0x89e, (q15_t)0x898, (q15_t)0x892, (q15_t)0x88c, (q15_t)0x885, (q15_t)0x87f, (q15_t)0x879, (q15_t)0x872, + (q15_t)0x86c, (q15_t)0x866, (q15_t)0x860, (q15_t)0x859, (q15_t)0x853, (q15_t)0x84d, (q15_t)0x847, (q15_t)0x840, + (q15_t)0x83a, (q15_t)0x834, (q15_t)0x82e, (q15_t)0x827, (q15_t)0x821, (q15_t)0x81b, (q15_t)0x814, (q15_t)0x80e, + (q15_t)0x808, (q15_t)0x802, (q15_t)0x7fb, (q15_t)0x7f5, (q15_t)0x7ef, (q15_t)0x7e9, (q15_t)0x7e2, (q15_t)0x7dc, + (q15_t)0x7d6, (q15_t)0x7cf, (q15_t)0x7c9, (q15_t)0x7c3, (q15_t)0x7bd, (q15_t)0x7b6, (q15_t)0x7b0, (q15_t)0x7aa, + (q15_t)0x7a4, (q15_t)0x79d, (q15_t)0x797, (q15_t)0x791, (q15_t)0x78a, (q15_t)0x784, (q15_t)0x77e, (q15_t)0x778, + (q15_t)0x771, (q15_t)0x76b, (q15_t)0x765, (q15_t)0x75f, (q15_t)0x758, (q15_t)0x752, (q15_t)0x74c, (q15_t)0x745, + (q15_t)0x73f, (q15_t)0x739, (q15_t)0x733, (q15_t)0x72c, (q15_t)0x726, (q15_t)0x720, (q15_t)0x71a, (q15_t)0x713, + (q15_t)0x70d, (q15_t)0x707, (q15_t)0x700, (q15_t)0x6fa, (q15_t)0x6f4, (q15_t)0x6ee, (q15_t)0x6e7, (q15_t)0x6e1, + (q15_t)0x6db, (q15_t)0x6d5, (q15_t)0x6ce, (q15_t)0x6c8, (q15_t)0x6c2, (q15_t)0x6bb, (q15_t)0x6b5, (q15_t)0x6af, + (q15_t)0x6a9, (q15_t)0x6a2, (q15_t)0x69c, (q15_t)0x696, (q15_t)0x690, (q15_t)0x689, (q15_t)0x683, (q15_t)0x67d, + (q15_t)0x676, (q15_t)0x670, (q15_t)0x66a, (q15_t)0x664, (q15_t)0x65d, (q15_t)0x657, (q15_t)0x651, (q15_t)0x64a, + (q15_t)0x644, (q15_t)0x63e, (q15_t)0x638, (q15_t)0x631, (q15_t)0x62b, (q15_t)0x625, (q15_t)0x61f, (q15_t)0x618, + (q15_t)0x612, (q15_t)0x60c, (q15_t)0x605, (q15_t)0x5ff, (q15_t)0x5f9, (q15_t)0x5f3, (q15_t)0x5ec, (q15_t)0x5e6, + (q15_t)0x5e0, (q15_t)0x5da, (q15_t)0x5d3, (q15_t)0x5cd, (q15_t)0x5c7, (q15_t)0x5c0, (q15_t)0x5ba, (q15_t)0x5b4, + (q15_t)0x5ae, (q15_t)0x5a7, (q15_t)0x5a1, (q15_t)0x59b, (q15_t)0x594, (q15_t)0x58e, (q15_t)0x588, (q15_t)0x582, + (q15_t)0x57b, (q15_t)0x575, (q15_t)0x56f, (q15_t)0x569, (q15_t)0x562, (q15_t)0x55c, (q15_t)0x556, (q15_t)0x54f, + (q15_t)0x549, (q15_t)0x543, (q15_t)0x53d, (q15_t)0x536, (q15_t)0x530, (q15_t)0x52a, (q15_t)0x523, (q15_t)0x51d, + (q15_t)0x517, (q15_t)0x511, (q15_t)0x50a, (q15_t)0x504, (q15_t)0x4fe, (q15_t)0x4f8, (q15_t)0x4f1, (q15_t)0x4eb, + (q15_t)0x4e5, (q15_t)0x4de, (q15_t)0x4d8, (q15_t)0x4d2, (q15_t)0x4cc, (q15_t)0x4c5, (q15_t)0x4bf, (q15_t)0x4b9, + (q15_t)0x4b2, (q15_t)0x4ac, (q15_t)0x4a6, (q15_t)0x4a0, (q15_t)0x499, (q15_t)0x493, (q15_t)0x48d, (q15_t)0x487, + (q15_t)0x480, (q15_t)0x47a, (q15_t)0x474, (q15_t)0x46d, (q15_t)0x467, (q15_t)0x461, (q15_t)0x45b, (q15_t)0x454, + (q15_t)0x44e, (q15_t)0x448, (q15_t)0x441, (q15_t)0x43b, (q15_t)0x435, (q15_t)0x42f, (q15_t)0x428, (q15_t)0x422, + (q15_t)0x41c, (q15_t)0x415, (q15_t)0x40f, (q15_t)0x409, (q15_t)0x403, (q15_t)0x3fc, (q15_t)0x3f6, (q15_t)0x3f0, + (q15_t)0x3ea, (q15_t)0x3e3, (q15_t)0x3dd, (q15_t)0x3d7, (q15_t)0x3d0, (q15_t)0x3ca, (q15_t)0x3c4, (q15_t)0x3be, + (q15_t)0x3b7, (q15_t)0x3b1, (q15_t)0x3ab, (q15_t)0x3a4, (q15_t)0x39e, (q15_t)0x398, (q15_t)0x392, (q15_t)0x38b, + (q15_t)0x385, (q15_t)0x37f, (q15_t)0x378, (q15_t)0x372, (q15_t)0x36c, (q15_t)0x366, (q15_t)0x35f, (q15_t)0x359, + (q15_t)0x353, (q15_t)0x34c, (q15_t)0x346, (q15_t)0x340, (q15_t)0x33a, (q15_t)0x333, (q15_t)0x32d, (q15_t)0x327, + (q15_t)0x321, (q15_t)0x31a, (q15_t)0x314, (q15_t)0x30e, (q15_t)0x307, (q15_t)0x301, (q15_t)0x2fb, (q15_t)0x2f5, + (q15_t)0x2ee, (q15_t)0x2e8, (q15_t)0x2e2, (q15_t)0x2db, (q15_t)0x2d5, (q15_t)0x2cf, (q15_t)0x2c9, (q15_t)0x2c2, + (q15_t)0x2bc, (q15_t)0x2b6, (q15_t)0x2af, (q15_t)0x2a9, (q15_t)0x2a3, (q15_t)0x29d, (q15_t)0x296, (q15_t)0x290, + (q15_t)0x28a, (q15_t)0x283, (q15_t)0x27d, (q15_t)0x277, (q15_t)0x271, (q15_t)0x26a, (q15_t)0x264, (q15_t)0x25e, + (q15_t)0x258, (q15_t)0x251, (q15_t)0x24b, (q15_t)0x245, (q15_t)0x23e, (q15_t)0x238, (q15_t)0x232, (q15_t)0x22c, + (q15_t)0x225, (q15_t)0x21f, (q15_t)0x219, (q15_t)0x212, (q15_t)0x20c, (q15_t)0x206, (q15_t)0x200, (q15_t)0x1f9, + (q15_t)0x1f3, (q15_t)0x1ed, (q15_t)0x1e6, (q15_t)0x1e0, (q15_t)0x1da, (q15_t)0x1d4, (q15_t)0x1cd, (q15_t)0x1c7, + (q15_t)0x1c1, (q15_t)0x1ba, (q15_t)0x1b4, (q15_t)0x1ae, (q15_t)0x1a8, (q15_t)0x1a1, (q15_t)0x19b, (q15_t)0x195, + (q15_t)0x18e, (q15_t)0x188, (q15_t)0x182, (q15_t)0x17c, (q15_t)0x175, (q15_t)0x16f, (q15_t)0x169, (q15_t)0x162, + (q15_t)0x15c, (q15_t)0x156, (q15_t)0x150, (q15_t)0x149, (q15_t)0x143, (q15_t)0x13d, (q15_t)0x137, (q15_t)0x130, + (q15_t)0x12a, (q15_t)0x124, (q15_t)0x11d, (q15_t)0x117, (q15_t)0x111, (q15_t)0x10b, (q15_t)0x104, (q15_t)0xfe, + (q15_t)0xf8, (q15_t)0xf1, (q15_t)0xeb, (q15_t)0xe5, (q15_t)0xdf, (q15_t)0xd8, (q15_t)0xd2, (q15_t)0xcc, + (q15_t)0xc5, (q15_t)0xbf, (q15_t)0xb9, (q15_t)0xb3, (q15_t)0xac, (q15_t)0xa6, (q15_t)0xa0, (q15_t)0x99, + (q15_t)0x93, (q15_t)0x8d, (q15_t)0x87, (q15_t)0x80, (q15_t)0x7a, (q15_t)0x74, (q15_t)0x6d, (q15_t)0x67, + (q15_t)0x61, (q15_t)0x5b, (q15_t)0x54, (q15_t)0x4e, (q15_t)0x48, (q15_t)0x41, (q15_t)0x3b, (q15_t)0x35, + (q15_t)0x2f, (q15_t)0x28, (q15_t)0x22, (q15_t)0x1c, (q15_t)0x15, (q15_t)0xf, (q15_t)0x9, (q15_t)0x3 +}; + +/** + @} end of DCT4_IDCT4_Table group + */ + +/** + @addtogroup DCT4_IDCT4 + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : N is not a supported transform length + + @par Normalizing factor + The normalizing factor is sqrt(2/N), which depends on the size of transform N. + Normalizing factors in 1.15 format are mentioned in the table below for different DCT sizes: + + \image html dct4NormalizingQ15Table.gif + */ + +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) +{ + /* Initialise the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + + /* Initializing the pointer array with the weight table base addresses of different lengths */ + q15_t *twiddlePtr[4] = { (q15_t *) WeightsQ15_128, (q15_t *) WeightsQ15_512, + (q15_t *) WeightsQ15_2048, (q15_t *) WeightsQ15_8192 + }; + + /* Initializing the pointer array with the cos factor table base addresses of different lengths */ + q15_t *pCosFactor[4] = + { (q15_t *) cos_factorsQ15_128, (q15_t *) cos_factorsQ15_512, + (q15_t *) cos_factorsQ15_2048, (q15_t *) cos_factorsQ15_8192 + }; + + /* Initialize the DCT4 length */ + S->N = N; + + /* Initialize the half of DCT4 length */ + S->Nby2 = Nby2; + + /* Initialize the DCT4 Normalizing factor */ + S->normalize = normalize; + + /* Initialize Real FFT Instance */ + S->pRfft = S_RFFT; + + /* Initialize Complex FFT Instance */ + S->pCfft = S_CFFT; + + switch (N) + { + /* Initialize the table modifier values */ + case 8192U: + S->pTwiddle = twiddlePtr[3]; + S->pCosFactor = pCosFactor[3]; + break; + case 2048U: + S->pTwiddle = twiddlePtr[2]; + S->pCosFactor = pCosFactor[2]; + break; + case 512U: + S->pTwiddle = twiddlePtr[1]; + S->pCosFactor = pCosFactor[1]; + break; + case 128U: + S->pTwiddle = twiddlePtr[0]; + S->pCosFactor = pCosFactor[0]; + break; + default: + status = ARM_MATH_ARGUMENT_ERROR; + } + + /* Initialize the RFFT/RIFFT */ + arm_rfft_init_q15(S->pRfft, S->N, 0U, 1U); + + /* return the status of DCT4 Init function */ + return (status); +} + +/** + @} end of DCT4_IDCT4 group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_q31.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_q31.c new file mode 100644 index 0000000..44fe1d1 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_init_q31.c @@ -0,0 +1,4619 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_dct4_init_q31.c + * Description: Initialization function of DCT-4 & IDCT4 Q31 + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup DCT4_IDCT4 + */ + +/** + @addtogroup DCT4_IDCT4_Table DCT Type IV Tables + @{ + */ + +/** + @brief Weights Table + */ + +/** + @par + Weights tables are generated using the formula :
weights[n] = e^(-j*n*pi/(2*N))
+ @par + C command to generate the table +
+  for (i = 0; i< N; i++)
+  {
+    weights[(2*i)]   =  cos(i*c);
+    weights[(2*i)+1] = -sin(i*c);
+  } 
+ @par + where N is the Number of weights to be calculated and c is pi/(2*N) + @par + Convert the output to q31 format by multiplying with 2^31 and saturated if required. + @par + In the tables below the real and imaginary values are placed alternatively, hence the + array length is 2*N. + */ + +static const q31_t WeightsQ31_128[256] = { + (q31_t)0x7fffffff, (q31_t)0x00000000, (q31_t)0x7ffd885a, (q31_t)0xfe6de2e0, (q31_t)0x7ff62182, (q31_t)0xfcdbd541, (q31_t)0x7fe9cbc0, (q31_t)0xfb49e6a3, + (q31_t)0x7fd8878e, (q31_t)0xf9b82684, (q31_t)0x7fc25596, (q31_t)0xf826a462, (q31_t)0x7fa736b4, (q31_t)0xf6956fb7, (q31_t)0x7f872bf3, (q31_t)0xf50497fb, + (q31_t)0x7f62368f, (q31_t)0xf3742ca2, (q31_t)0x7f3857f6, (q31_t)0xf1e43d1c, (q31_t)0x7f0991c4, (q31_t)0xf054d8d5, (q31_t)0x7ed5e5c6, (q31_t)0xeec60f31, + (q31_t)0x7e9d55fc, (q31_t)0xed37ef91, (q31_t)0x7e5fe493, (q31_t)0xebaa894f, (q31_t)0x7e1d93ea, (q31_t)0xea1debbb, (q31_t)0x7dd6668f, (q31_t)0xe8922622, + (q31_t)0x7d8a5f40, (q31_t)0xe70747c4, (q31_t)0x7d3980ec, (q31_t)0xe57d5fda, (q31_t)0x7ce3ceb2, (q31_t)0xe3f47d96, (q31_t)0x7c894bde, (q31_t)0xe26cb01b, + (q31_t)0x7c29fbee, (q31_t)0xe0e60685, (q31_t)0x7bc5e290, (q31_t)0xdf608fe4, (q31_t)0x7b5d039e, (q31_t)0xdddc5b3b, (q31_t)0x7aef6323, (q31_t)0xdc597781, + (q31_t)0x7a7d055b, (q31_t)0xdad7f3a2, (q31_t)0x7a05eead, (q31_t)0xd957de7a, (q31_t)0x798a23b1, (q31_t)0xd7d946d8, (q31_t)0x7909a92d, (q31_t)0xd65c3b7b, + (q31_t)0x78848414, (q31_t)0xd4e0cb15, (q31_t)0x77fab989, (q31_t)0xd3670446, (q31_t)0x776c4edb, (q31_t)0xd1eef59e, (q31_t)0x76d94989, (q31_t)0xd078ad9e, + (q31_t)0x7641af3d, (q31_t)0xcf043ab3, (q31_t)0x75a585cf, (q31_t)0xcd91ab39, (q31_t)0x7504d345, (q31_t)0xcc210d79, (q31_t)0x745f9dd1, (q31_t)0xcab26fa9, + (q31_t)0x73b5ebd1, (q31_t)0xc945dfec, (q31_t)0x7307c3d0, (q31_t)0xc7db6c50, (q31_t)0x72552c85, (q31_t)0xc67322ce, (q31_t)0x719e2cd2, (q31_t)0xc50d1149, + (q31_t)0x70e2cbc6, (q31_t)0xc3a94590, (q31_t)0x7023109a, (q31_t)0xc247cd5a, (q31_t)0x6f5f02b2, (q31_t)0xc0e8b648, (q31_t)0x6e96a99d, (q31_t)0xbf8c0de3, + (q31_t)0x6dca0d14, (q31_t)0xbe31e19b, (q31_t)0x6cf934fc, (q31_t)0xbcda3ecb, (q31_t)0x6c242960, (q31_t)0xbb8532b0, (q31_t)0x6b4af279, (q31_t)0xba32ca71, + (q31_t)0x6a6d98a4, (q31_t)0xb8e31319, (q31_t)0x698c246c, (q31_t)0xb796199b, (q31_t)0x68a69e81, (q31_t)0xb64beacd, (q31_t)0x67bd0fbd, (q31_t)0xb5049368, + (q31_t)0x66cf8120, (q31_t)0xb3c0200c, (q31_t)0x65ddfbd3, (q31_t)0xb27e9d3c, (q31_t)0x64e88926, (q31_t)0xb140175b, (q31_t)0x63ef3290, (q31_t)0xb0049ab3, + (q31_t)0x62f201ac, (q31_t)0xaecc336c, (q31_t)0x61f1003f, (q31_t)0xad96ed92, (q31_t)0x60ec3830, (q31_t)0xac64d510, (q31_t)0x5fe3b38d, (q31_t)0xab35f5b5, + (q31_t)0x5ed77c8a, (q31_t)0xaa0a5b2e, (q31_t)0x5dc79d7c, (q31_t)0xa8e21106, (q31_t)0x5cb420e0, (q31_t)0xa7bd22ac, (q31_t)0x5b9d1154, (q31_t)0xa69b9b68, + (q31_t)0x5a82799a, (q31_t)0xa57d8666, (q31_t)0x59646498, (q31_t)0xa462eeac, (q31_t)0x5842dd54, (q31_t)0xa34bdf20, (q31_t)0x571deefa, (q31_t)0xa2386284, + (q31_t)0x55f5a4d2, (q31_t)0xa1288376, (q31_t)0x54ca0a4b, (q31_t)0xa01c4c73, (q31_t)0x539b2af0, (q31_t)0x9f13c7d0, (q31_t)0x5269126e, (q31_t)0x9e0effc1, + (q31_t)0x5133cc94, (q31_t)0x9d0dfe54, (q31_t)0x4ffb654d, (q31_t)0x9c10cd70, (q31_t)0x4ebfe8a5, (q31_t)0x9b1776da, (q31_t)0x4d8162c4, (q31_t)0x9a22042d, + (q31_t)0x4c3fdff4, (q31_t)0x99307ee0, (q31_t)0x4afb6c98, (q31_t)0x9842f043, (q31_t)0x49b41533, (q31_t)0x9759617f, (q31_t)0x4869e665, (q31_t)0x9673db94, + (q31_t)0x471cece7, (q31_t)0x9592675c, (q31_t)0x45cd358f, (q31_t)0x94b50d87, (q31_t)0x447acd50, (q31_t)0x93dbd6a0, (q31_t)0x4325c135, (q31_t)0x9306cb04, + (q31_t)0x41ce1e65, (q31_t)0x9235f2ec, (q31_t)0x4073f21d, (q31_t)0x91695663, (q31_t)0x3f1749b8, (q31_t)0x90a0fd4e, (q31_t)0x3db832a6, (q31_t)0x8fdcef66, + (q31_t)0x3c56ba70, (q31_t)0x8f1d343a, (q31_t)0x3af2eeb7, (q31_t)0x8e61d32e, (q31_t)0x398cdd32, (q31_t)0x8daad37b, (q31_t)0x382493b0, (q31_t)0x8cf83c30, + (q31_t)0x36ba2014, (q31_t)0x8c4a142f, (q31_t)0x354d9057, (q31_t)0x8ba0622f, (q31_t)0x33def287, (q31_t)0x8afb2cbb, (q31_t)0x326e54c7, (q31_t)0x8a5a7a31, + (q31_t)0x30fbc54d, (q31_t)0x89be50c3, (q31_t)0x2f875262, (q31_t)0x8926b677, (q31_t)0x2e110a62, (q31_t)0x8893b125, (q31_t)0x2c98fbba, (q31_t)0x88054677, + (q31_t)0x2b1f34eb, (q31_t)0x877b7bec, (q31_t)0x29a3c485, (q31_t)0x86f656d3, (q31_t)0x2826b928, (q31_t)0x8675dc4f, (q31_t)0x26a82186, (q31_t)0x85fa1153, + (q31_t)0x25280c5e, (q31_t)0x8582faa5, (q31_t)0x23a6887f, (q31_t)0x85109cdd, (q31_t)0x2223a4c5, (q31_t)0x84a2fc62, (q31_t)0x209f701c, (q31_t)0x843a1d70, + (q31_t)0x1f19f97b, (q31_t)0x83d60412, (q31_t)0x1d934fe5, (q31_t)0x8376b422, (q31_t)0x1c0b826a, (q31_t)0x831c314e, (q31_t)0x1a82a026, (q31_t)0x82c67f14, + (q31_t)0x18f8b83c, (q31_t)0x8275a0c0, (q31_t)0x176dd9de, (q31_t)0x82299971, (q31_t)0x15e21445, (q31_t)0x81e26c16, (q31_t)0x145576b1, (q31_t)0x81a01b6d, + (q31_t)0x12c8106f, (q31_t)0x8162aa04, (q31_t)0x1139f0cf, (q31_t)0x812a1a3a, (q31_t)0x0fab272b, (q31_t)0x80f66e3c, (q31_t)0x0e1bc2e4, (q31_t)0x80c7a80a, + (q31_t)0x0c8bd35e, (q31_t)0x809dc971, (q31_t)0x0afb6805, (q31_t)0x8078d40d, (q31_t)0x096a9049, (q31_t)0x8058c94c, (q31_t)0x07d95b9e, (q31_t)0x803daa6a, + (q31_t)0x0647d97c, (q31_t)0x80277872, (q31_t)0x04b6195d, (q31_t)0x80163440, (q31_t)0x03242abf, (q31_t)0x8009de7e, (q31_t)0x01921d20, (q31_t)0x800277a6 +}; + +static const q31_t WeightsQ31_512[1024] = { + (q31_t)0x7fffffff, (q31_t)0x00000000, (q31_t)0x7fffd886, (q31_t)0xff9b781d, (q31_t)0x7fff6216, (q31_t)0xff36f078, (q31_t)0x7ffe9cb2, (q31_t)0xfed2694f, + (q31_t)0x7ffd885a, (q31_t)0xfe6de2e0, (q31_t)0x7ffc250f, (q31_t)0xfe095d69, (q31_t)0x7ffa72d1, (q31_t)0xfda4d929, (q31_t)0x7ff871a2, (q31_t)0xfd40565c, + (q31_t)0x7ff62182, (q31_t)0xfcdbd541, (q31_t)0x7ff38274, (q31_t)0xfc775616, (q31_t)0x7ff09478, (q31_t)0xfc12d91a, (q31_t)0x7fed5791, (q31_t)0xfbae5e89, + (q31_t)0x7fe9cbc0, (q31_t)0xfb49e6a3, (q31_t)0x7fe5f108, (q31_t)0xfae571a4, (q31_t)0x7fe1c76b, (q31_t)0xfa80ffcb, (q31_t)0x7fdd4eec, (q31_t)0xfa1c9157, + (q31_t)0x7fd8878e, (q31_t)0xf9b82684, (q31_t)0x7fd37153, (q31_t)0xf953bf91, (q31_t)0x7fce0c3e, (q31_t)0xf8ef5cbb, (q31_t)0x7fc85854, (q31_t)0xf88afe42, + (q31_t)0x7fc25596, (q31_t)0xf826a462, (q31_t)0x7fbc040a, (q31_t)0xf7c24f59, (q31_t)0x7fb563b3, (q31_t)0xf75dff66, (q31_t)0x7fae7495, (q31_t)0xf6f9b4c6, + (q31_t)0x7fa736b4, (q31_t)0xf6956fb7, (q31_t)0x7f9faa15, (q31_t)0xf6313077, (q31_t)0x7f97cebd, (q31_t)0xf5ccf743, (q31_t)0x7f8fa4b0, (q31_t)0xf568c45b, + (q31_t)0x7f872bf3, (q31_t)0xf50497fb, (q31_t)0x7f7e648c, (q31_t)0xf4a07261, (q31_t)0x7f754e80, (q31_t)0xf43c53cb, (q31_t)0x7f6be9d4, (q31_t)0xf3d83c77, + (q31_t)0x7f62368f, (q31_t)0xf3742ca2, (q31_t)0x7f5834b7, (q31_t)0xf310248a, (q31_t)0x7f4de451, (q31_t)0xf2ac246e, (q31_t)0x7f434563, (q31_t)0xf2482c8a, + (q31_t)0x7f3857f6, (q31_t)0xf1e43d1c, (q31_t)0x7f2d1c0e, (q31_t)0xf1805662, (q31_t)0x7f2191b4, (q31_t)0xf11c789a, (q31_t)0x7f15b8ee, (q31_t)0xf0b8a401, + (q31_t)0x7f0991c4, (q31_t)0xf054d8d5, (q31_t)0x7efd1c3c, (q31_t)0xeff11753, (q31_t)0x7ef05860, (q31_t)0xef8d5fb8, (q31_t)0x7ee34636, (q31_t)0xef29b243, + (q31_t)0x7ed5e5c6, (q31_t)0xeec60f31, (q31_t)0x7ec8371a, (q31_t)0xee6276bf, (q31_t)0x7eba3a39, (q31_t)0xedfee92b, (q31_t)0x7eabef2c, (q31_t)0xed9b66b2, + (q31_t)0x7e9d55fc, (q31_t)0xed37ef91, (q31_t)0x7e8e6eb2, (q31_t)0xecd48407, (q31_t)0x7e7f3957, (q31_t)0xec71244f, (q31_t)0x7e6fb5f4, (q31_t)0xec0dd0a8, + (q31_t)0x7e5fe493, (q31_t)0xebaa894f, (q31_t)0x7e4fc53e, (q31_t)0xeb474e81, (q31_t)0x7e3f57ff, (q31_t)0xeae4207a, (q31_t)0x7e2e9cdf, (q31_t)0xea80ff7a, + (q31_t)0x7e1d93ea, (q31_t)0xea1debbb, (q31_t)0x7e0c3d29, (q31_t)0xe9bae57d, (q31_t)0x7dfa98a8, (q31_t)0xe957ecfb, (q31_t)0x7de8a670, (q31_t)0xe8f50273, + (q31_t)0x7dd6668f, (q31_t)0xe8922622, (q31_t)0x7dc3d90d, (q31_t)0xe82f5844, (q31_t)0x7db0fdf8, (q31_t)0xe7cc9917, (q31_t)0x7d9dd55a, (q31_t)0xe769e8d8, + (q31_t)0x7d8a5f40, (q31_t)0xe70747c4, (q31_t)0x7d769bb5, (q31_t)0xe6a4b616, (q31_t)0x7d628ac6, (q31_t)0xe642340d, (q31_t)0x7d4e2c7f, (q31_t)0xe5dfc1e5, + (q31_t)0x7d3980ec, (q31_t)0xe57d5fda, (q31_t)0x7d24881b, (q31_t)0xe51b0e2a, (q31_t)0x7d0f4218, (q31_t)0xe4b8cd11, (q31_t)0x7cf9aef0, (q31_t)0xe4569ccb, + (q31_t)0x7ce3ceb2, (q31_t)0xe3f47d96, (q31_t)0x7ccda169, (q31_t)0xe3926fad, (q31_t)0x7cb72724, (q31_t)0xe330734d, (q31_t)0x7ca05ff1, (q31_t)0xe2ce88b3, + (q31_t)0x7c894bde, (q31_t)0xe26cb01b, (q31_t)0x7c71eaf9, (q31_t)0xe20ae9c1, (q31_t)0x7c5a3d50, (q31_t)0xe1a935e2, (q31_t)0x7c4242f2, (q31_t)0xe14794ba, + (q31_t)0x7c29fbee, (q31_t)0xe0e60685, (q31_t)0x7c116853, (q31_t)0xe0848b7f, (q31_t)0x7bf88830, (q31_t)0xe02323e5, (q31_t)0x7bdf5b94, (q31_t)0xdfc1cff3, + (q31_t)0x7bc5e290, (q31_t)0xdf608fe4, (q31_t)0x7bac1d31, (q31_t)0xdeff63f4, (q31_t)0x7b920b89, (q31_t)0xde9e4c60, (q31_t)0x7b77ada8, (q31_t)0xde3d4964, + (q31_t)0x7b5d039e, (q31_t)0xdddc5b3b, (q31_t)0x7b420d7a, (q31_t)0xdd7b8220, (q31_t)0x7b26cb4f, (q31_t)0xdd1abe51, (q31_t)0x7b0b3d2c, (q31_t)0xdcba1008, + (q31_t)0x7aef6323, (q31_t)0xdc597781, (q31_t)0x7ad33d45, (q31_t)0xdbf8f4f8, (q31_t)0x7ab6cba4, (q31_t)0xdb9888a8, (q31_t)0x7a9a0e50, (q31_t)0xdb3832cd, + (q31_t)0x7a7d055b, (q31_t)0xdad7f3a2, (q31_t)0x7a5fb0d8, (q31_t)0xda77cb63, (q31_t)0x7a4210d8, (q31_t)0xda17ba4a, (q31_t)0x7a24256f, (q31_t)0xd9b7c094, + (q31_t)0x7a05eead, (q31_t)0xd957de7a, (q31_t)0x79e76ca7, (q31_t)0xd8f81439, (q31_t)0x79c89f6e, (q31_t)0xd898620c, (q31_t)0x79a98715, (q31_t)0xd838c82d, + (q31_t)0x798a23b1, (q31_t)0xd7d946d8, (q31_t)0x796a7554, (q31_t)0xd779de47, (q31_t)0x794a7c12, (q31_t)0xd71a8eb5, (q31_t)0x792a37fe, (q31_t)0xd6bb585e, + (q31_t)0x7909a92d, (q31_t)0xd65c3b7b, (q31_t)0x78e8cfb2, (q31_t)0xd5fd3848, (q31_t)0x78c7aba2, (q31_t)0xd59e4eff, (q31_t)0x78a63d11, (q31_t)0xd53f7fda, + (q31_t)0x78848414, (q31_t)0xd4e0cb15, (q31_t)0x786280bf, (q31_t)0xd48230e9, (q31_t)0x78403329, (q31_t)0xd423b191, (q31_t)0x781d9b65, (q31_t)0xd3c54d47, + (q31_t)0x77fab989, (q31_t)0xd3670446, (q31_t)0x77d78daa, (q31_t)0xd308d6c7, (q31_t)0x77b417df, (q31_t)0xd2aac504, (q31_t)0x7790583e, (q31_t)0xd24ccf39, + (q31_t)0x776c4edb, (q31_t)0xd1eef59e, (q31_t)0x7747fbce, (q31_t)0xd191386e, (q31_t)0x77235f2d, (q31_t)0xd13397e2, (q31_t)0x76fe790e, (q31_t)0xd0d61434, + (q31_t)0x76d94989, (q31_t)0xd078ad9e, (q31_t)0x76b3d0b4, (q31_t)0xd01b6459, (q31_t)0x768e0ea6, (q31_t)0xcfbe389f, (q31_t)0x76680376, (q31_t)0xcf612aaa, + (q31_t)0x7641af3d, (q31_t)0xcf043ab3, (q31_t)0x761b1211, (q31_t)0xcea768f2, (q31_t)0x75f42c0b, (q31_t)0xce4ab5a2, (q31_t)0x75ccfd42, (q31_t)0xcdee20fc, + (q31_t)0x75a585cf, (q31_t)0xcd91ab39, (q31_t)0x757dc5ca, (q31_t)0xcd355491, (q31_t)0x7555bd4c, (q31_t)0xccd91d3d, (q31_t)0x752d6c6c, (q31_t)0xcc7d0578, + (q31_t)0x7504d345, (q31_t)0xcc210d79, (q31_t)0x74dbf1ef, (q31_t)0xcbc53579, (q31_t)0x74b2c884, (q31_t)0xcb697db0, (q31_t)0x7489571c, (q31_t)0xcb0de658, + (q31_t)0x745f9dd1, (q31_t)0xcab26fa9, (q31_t)0x74359cbd, (q31_t)0xca5719db, (q31_t)0x740b53fb, (q31_t)0xc9fbe527, (q31_t)0x73e0c3a3, (q31_t)0xc9a0d1c5, + (q31_t)0x73b5ebd1, (q31_t)0xc945dfec, (q31_t)0x738acc9e, (q31_t)0xc8eb0fd6, (q31_t)0x735f6626, (q31_t)0xc89061ba, (q31_t)0x7333b883, (q31_t)0xc835d5d0, + (q31_t)0x7307c3d0, (q31_t)0xc7db6c50, (q31_t)0x72db8828, (q31_t)0xc7812572, (q31_t)0x72af05a7, (q31_t)0xc727016d, (q31_t)0x72823c67, (q31_t)0xc6cd0079, + (q31_t)0x72552c85, (q31_t)0xc67322ce, (q31_t)0x7227d61c, (q31_t)0xc61968a2, (q31_t)0x71fa3949, (q31_t)0xc5bfd22e, (q31_t)0x71cc5626, (q31_t)0xc5665fa9, + (q31_t)0x719e2cd2, (q31_t)0xc50d1149, (q31_t)0x716fbd68, (q31_t)0xc4b3e746, (q31_t)0x71410805, (q31_t)0xc45ae1d7, (q31_t)0x71120cc5, (q31_t)0xc4020133, + (q31_t)0x70e2cbc6, (q31_t)0xc3a94590, (q31_t)0x70b34525, (q31_t)0xc350af26, (q31_t)0x708378ff, (q31_t)0xc2f83e2a, (q31_t)0x70536771, (q31_t)0xc29ff2d4, + (q31_t)0x7023109a, (q31_t)0xc247cd5a, (q31_t)0x6ff27497, (q31_t)0xc1efcdf3, (q31_t)0x6fc19385, (q31_t)0xc197f4d4, (q31_t)0x6f906d84, (q31_t)0xc1404233, + (q31_t)0x6f5f02b2, (q31_t)0xc0e8b648, (q31_t)0x6f2d532c, (q31_t)0xc0915148, (q31_t)0x6efb5f12, (q31_t)0xc03a1368, (q31_t)0x6ec92683, (q31_t)0xbfe2fcdf, + (q31_t)0x6e96a99d, (q31_t)0xbf8c0de3, (q31_t)0x6e63e87f, (q31_t)0xbf3546a8, (q31_t)0x6e30e34a, (q31_t)0xbedea765, (q31_t)0x6dfd9a1c, (q31_t)0xbe88304f, + (q31_t)0x6dca0d14, (q31_t)0xbe31e19b, (q31_t)0x6d963c54, (q31_t)0xbddbbb7f, (q31_t)0x6d6227fa, (q31_t)0xbd85be30, (q31_t)0x6d2dd027, (q31_t)0xbd2fe9e2, + (q31_t)0x6cf934fc, (q31_t)0xbcda3ecb, (q31_t)0x6cc45698, (q31_t)0xbc84bd1f, (q31_t)0x6c8f351c, (q31_t)0xbc2f6513, (q31_t)0x6c59d0a9, (q31_t)0xbbda36dd, + (q31_t)0x6c242960, (q31_t)0xbb8532b0, (q31_t)0x6bee3f62, (q31_t)0xbb3058c0, (q31_t)0x6bb812d1, (q31_t)0xbadba943, (q31_t)0x6b81a3cd, (q31_t)0xba87246d, + (q31_t)0x6b4af279, (q31_t)0xba32ca71, (q31_t)0x6b13fef5, (q31_t)0xb9de9b83, (q31_t)0x6adcc964, (q31_t)0xb98a97d8, (q31_t)0x6aa551e9, (q31_t)0xb936bfa4, + (q31_t)0x6a6d98a4, (q31_t)0xb8e31319, (q31_t)0x6a359db9, (q31_t)0xb88f926d, (q31_t)0x69fd614a, (q31_t)0xb83c3dd1, (q31_t)0x69c4e37a, (q31_t)0xb7e9157a, + (q31_t)0x698c246c, (q31_t)0xb796199b, (q31_t)0x69532442, (q31_t)0xb7434a67, (q31_t)0x6919e320, (q31_t)0xb6f0a812, (q31_t)0x68e06129, (q31_t)0xb69e32cd, + (q31_t)0x68a69e81, (q31_t)0xb64beacd, (q31_t)0x686c9b4b, (q31_t)0xb5f9d043, (q31_t)0x683257ab, (q31_t)0xb5a7e362, (q31_t)0x67f7d3c5, (q31_t)0xb556245e, + (q31_t)0x67bd0fbd, (q31_t)0xb5049368, (q31_t)0x67820bb7, (q31_t)0xb4b330b3, (q31_t)0x6746c7d8, (q31_t)0xb461fc70, (q31_t)0x670b4444, (q31_t)0xb410f6d3, + (q31_t)0x66cf8120, (q31_t)0xb3c0200c, (q31_t)0x66937e91, (q31_t)0xb36f784f, (q31_t)0x66573cbb, (q31_t)0xb31effcc, (q31_t)0x661abbc5, (q31_t)0xb2ceb6b5, + (q31_t)0x65ddfbd3, (q31_t)0xb27e9d3c, (q31_t)0x65a0fd0b, (q31_t)0xb22eb392, (q31_t)0x6563bf92, (q31_t)0xb1def9e9, (q31_t)0x6526438f, (q31_t)0xb18f7071, + (q31_t)0x64e88926, (q31_t)0xb140175b, (q31_t)0x64aa907f, (q31_t)0xb0f0eeda, (q31_t)0x646c59bf, (q31_t)0xb0a1f71d, (q31_t)0x642de50d, (q31_t)0xb0533055, + (q31_t)0x63ef3290, (q31_t)0xb0049ab3, (q31_t)0x63b0426d, (q31_t)0xafb63667, (q31_t)0x637114cc, (q31_t)0xaf6803a2, (q31_t)0x6331a9d4, (q31_t)0xaf1a0293, + (q31_t)0x62f201ac, (q31_t)0xaecc336c, (q31_t)0x62b21c7b, (q31_t)0xae7e965b, (q31_t)0x6271fa69, (q31_t)0xae312b92, (q31_t)0x62319b9d, (q31_t)0xade3f33e, + (q31_t)0x61f1003f, (q31_t)0xad96ed92, (q31_t)0x61b02876, (q31_t)0xad4a1aba, (q31_t)0x616f146c, (q31_t)0xacfd7ae8, (q31_t)0x612dc447, (q31_t)0xacb10e4b, + (q31_t)0x60ec3830, (q31_t)0xac64d510, (q31_t)0x60aa7050, (q31_t)0xac18cf69, (q31_t)0x60686ccf, (q31_t)0xabccfd83, (q31_t)0x60262dd6, (q31_t)0xab815f8d, + (q31_t)0x5fe3b38d, (q31_t)0xab35f5b5, (q31_t)0x5fa0fe1f, (q31_t)0xaaeac02c, (q31_t)0x5f5e0db3, (q31_t)0xaa9fbf1e, (q31_t)0x5f1ae274, (q31_t)0xaa54f2ba, + (q31_t)0x5ed77c8a, (q31_t)0xaa0a5b2e, (q31_t)0x5e93dc1f, (q31_t)0xa9bff8a8, (q31_t)0x5e50015d, (q31_t)0xa975cb57, (q31_t)0x5e0bec6e, (q31_t)0xa92bd367, + (q31_t)0x5dc79d7c, (q31_t)0xa8e21106, (q31_t)0x5d8314b1, (q31_t)0xa8988463, (q31_t)0x5d3e5237, (q31_t)0xa84f2daa, (q31_t)0x5cf95638, (q31_t)0xa8060d08, + (q31_t)0x5cb420e0, (q31_t)0xa7bd22ac, (q31_t)0x5c6eb258, (q31_t)0xa7746ec0, (q31_t)0x5c290acc, (q31_t)0xa72bf174, (q31_t)0x5be32a67, (q31_t)0xa6e3aaf2, + (q31_t)0x5b9d1154, (q31_t)0xa69b9b68, (q31_t)0x5b56bfbd, (q31_t)0xa653c303, (q31_t)0x5b1035cf, (q31_t)0xa60c21ee, (q31_t)0x5ac973b5, (q31_t)0xa5c4b855, + (q31_t)0x5a82799a, (q31_t)0xa57d8666, (q31_t)0x5a3b47ab, (q31_t)0xa5368c4b, (q31_t)0x59f3de12, (q31_t)0xa4efca31, (q31_t)0x59ac3cfd, (q31_t)0xa4a94043, + (q31_t)0x59646498, (q31_t)0xa462eeac, (q31_t)0x591c550e, (q31_t)0xa41cd599, (q31_t)0x58d40e8c, (q31_t)0xa3d6f534, (q31_t)0x588b9140, (q31_t)0xa3914da8, + (q31_t)0x5842dd54, (q31_t)0xa34bdf20, (q31_t)0x57f9f2f8, (q31_t)0xa306a9c8, (q31_t)0x57b0d256, (q31_t)0xa2c1adc9, (q31_t)0x57677b9d, (q31_t)0xa27ceb4f, + (q31_t)0x571deefa, (q31_t)0xa2386284, (q31_t)0x56d42c99, (q31_t)0xa1f41392, (q31_t)0x568a34a9, (q31_t)0xa1affea3, (q31_t)0x56400758, (q31_t)0xa16c23e1, + (q31_t)0x55f5a4d2, (q31_t)0xa1288376, (q31_t)0x55ab0d46, (q31_t)0xa0e51d8c, (q31_t)0x556040e2, (q31_t)0xa0a1f24d, (q31_t)0x55153fd4, (q31_t)0xa05f01e1, + (q31_t)0x54ca0a4b, (q31_t)0xa01c4c73, (q31_t)0x547ea073, (q31_t)0x9fd9d22a, (q31_t)0x5433027d, (q31_t)0x9f979331, (q31_t)0x53e73097, (q31_t)0x9f558fb0, + (q31_t)0x539b2af0, (q31_t)0x9f13c7d0, (q31_t)0x534ef1b5, (q31_t)0x9ed23bb9, (q31_t)0x53028518, (q31_t)0x9e90eb94, (q31_t)0x52b5e546, (q31_t)0x9e4fd78a, + (q31_t)0x5269126e, (q31_t)0x9e0effc1, (q31_t)0x521c0cc2, (q31_t)0x9dce6463, (q31_t)0x51ced46e, (q31_t)0x9d8e0597, (q31_t)0x518169a5, (q31_t)0x9d4de385, + (q31_t)0x5133cc94, (q31_t)0x9d0dfe54, (q31_t)0x50e5fd6d, (q31_t)0x9cce562c, (q31_t)0x5097fc5e, (q31_t)0x9c8eeb34, (q31_t)0x5049c999, (q31_t)0x9c4fbd93, + (q31_t)0x4ffb654d, (q31_t)0x9c10cd70, (q31_t)0x4faccfab, (q31_t)0x9bd21af3, (q31_t)0x4f5e08e3, (q31_t)0x9b93a641, (q31_t)0x4f0f1126, (q31_t)0x9b556f81, + (q31_t)0x4ebfe8a5, (q31_t)0x9b1776da, (q31_t)0x4e708f8f, (q31_t)0x9ad9bc71, (q31_t)0x4e210617, (q31_t)0x9a9c406e, (q31_t)0x4dd14c6e, (q31_t)0x9a5f02f5, + (q31_t)0x4d8162c4, (q31_t)0x9a22042d, (q31_t)0x4d31494b, (q31_t)0x99e5443b, (q31_t)0x4ce10034, (q31_t)0x99a8c345, (q31_t)0x4c9087b1, (q31_t)0x996c816f, + (q31_t)0x4c3fdff4, (q31_t)0x99307ee0, (q31_t)0x4bef092d, (q31_t)0x98f4bbbc, (q31_t)0x4b9e0390, (q31_t)0x98b93828, (q31_t)0x4b4ccf4d, (q31_t)0x987df449, + (q31_t)0x4afb6c98, (q31_t)0x9842f043, (q31_t)0x4aa9dba2, (q31_t)0x98082c3b, (q31_t)0x4a581c9e, (q31_t)0x97cda855, (q31_t)0x4a062fbd, (q31_t)0x979364b5, + (q31_t)0x49b41533, (q31_t)0x9759617f, (q31_t)0x4961cd33, (q31_t)0x971f9ed7, (q31_t)0x490f57ee, (q31_t)0x96e61ce0, (q31_t)0x48bcb599, (q31_t)0x96acdbbe, + (q31_t)0x4869e665, (q31_t)0x9673db94, (q31_t)0x4816ea86, (q31_t)0x963b1c86, (q31_t)0x47c3c22f, (q31_t)0x96029eb6, (q31_t)0x47706d93, (q31_t)0x95ca6247, + (q31_t)0x471cece7, (q31_t)0x9592675c, (q31_t)0x46c9405c, (q31_t)0x955aae17, (q31_t)0x46756828, (q31_t)0x9523369c, (q31_t)0x4621647d, (q31_t)0x94ec010b, + (q31_t)0x45cd358f, (q31_t)0x94b50d87, (q31_t)0x4578db93, (q31_t)0x947e5c33, (q31_t)0x452456bd, (q31_t)0x9447ed2f, (q31_t)0x44cfa740, (q31_t)0x9411c09e, + (q31_t)0x447acd50, (q31_t)0x93dbd6a0, (q31_t)0x4425c923, (q31_t)0x93a62f57, (q31_t)0x43d09aed, (q31_t)0x9370cae4, (q31_t)0x437b42e1, (q31_t)0x933ba968, + (q31_t)0x4325c135, (q31_t)0x9306cb04, (q31_t)0x42d0161e, (q31_t)0x92d22fd9, (q31_t)0x427a41d0, (q31_t)0x929dd806, (q31_t)0x42244481, (q31_t)0x9269c3ac, + (q31_t)0x41ce1e65, (q31_t)0x9235f2ec, (q31_t)0x4177cfb1, (q31_t)0x920265e4, (q31_t)0x4121589b, (q31_t)0x91cf1cb6, (q31_t)0x40cab958, (q31_t)0x919c1781, + (q31_t)0x4073f21d, (q31_t)0x91695663, (q31_t)0x401d0321, (q31_t)0x9136d97d, (q31_t)0x3fc5ec98, (q31_t)0x9104a0ee, (q31_t)0x3f6eaeb8, (q31_t)0x90d2acd4, + (q31_t)0x3f1749b8, (q31_t)0x90a0fd4e, (q31_t)0x3ebfbdcd, (q31_t)0x906f927c, (q31_t)0x3e680b2c, (q31_t)0x903e6c7b, (q31_t)0x3e10320d, (q31_t)0x900d8b69, + (q31_t)0x3db832a6, (q31_t)0x8fdcef66, (q31_t)0x3d600d2c, (q31_t)0x8fac988f, (q31_t)0x3d07c1d6, (q31_t)0x8f7c8701, (q31_t)0x3caf50da, (q31_t)0x8f4cbadb, + (q31_t)0x3c56ba70, (q31_t)0x8f1d343a, (q31_t)0x3bfdfecd, (q31_t)0x8eedf33b, (q31_t)0x3ba51e29, (q31_t)0x8ebef7fb, (q31_t)0x3b4c18ba, (q31_t)0x8e904298, + (q31_t)0x3af2eeb7, (q31_t)0x8e61d32e, (q31_t)0x3a99a057, (q31_t)0x8e33a9da, (q31_t)0x3a402dd2, (q31_t)0x8e05c6b7, (q31_t)0x39e6975e, (q31_t)0x8dd829e4, + (q31_t)0x398cdd32, (q31_t)0x8daad37b, (q31_t)0x3932ff87, (q31_t)0x8d7dc399, (q31_t)0x38d8fe93, (q31_t)0x8d50fa59, (q31_t)0x387eda8e, (q31_t)0x8d2477d8, + (q31_t)0x382493b0, (q31_t)0x8cf83c30, (q31_t)0x37ca2a30, (q31_t)0x8ccc477d, (q31_t)0x376f9e46, (q31_t)0x8ca099da, (q31_t)0x3714f02a, (q31_t)0x8c753362, + (q31_t)0x36ba2014, (q31_t)0x8c4a142f, (q31_t)0x365f2e3b, (q31_t)0x8c1f3c5d, (q31_t)0x36041ad9, (q31_t)0x8bf4ac05, (q31_t)0x35a8e625, (q31_t)0x8bca6343, + (q31_t)0x354d9057, (q31_t)0x8ba0622f, (q31_t)0x34f219a8, (q31_t)0x8b76a8e4, (q31_t)0x34968250, (q31_t)0x8b4d377c, (q31_t)0x343aca87, (q31_t)0x8b240e11, + (q31_t)0x33def287, (q31_t)0x8afb2cbb, (q31_t)0x3382fa88, (q31_t)0x8ad29394, (q31_t)0x3326e2c3, (q31_t)0x8aaa42b4, (q31_t)0x32caab6f, (q31_t)0x8a823a36, + (q31_t)0x326e54c7, (q31_t)0x8a5a7a31, (q31_t)0x3211df04, (q31_t)0x8a3302be, (q31_t)0x31b54a5e, (q31_t)0x8a0bd3f5, (q31_t)0x3158970e, (q31_t)0x89e4edef, + (q31_t)0x30fbc54d, (q31_t)0x89be50c3, (q31_t)0x309ed556, (q31_t)0x8997fc8a, (q31_t)0x3041c761, (q31_t)0x8971f15a, (q31_t)0x2fe49ba7, (q31_t)0x894c2f4c, + (q31_t)0x2f875262, (q31_t)0x8926b677, (q31_t)0x2f29ebcc, (q31_t)0x890186f2, (q31_t)0x2ecc681e, (q31_t)0x88dca0d3, (q31_t)0x2e6ec792, (q31_t)0x88b80432, + (q31_t)0x2e110a62, (q31_t)0x8893b125, (q31_t)0x2db330c7, (q31_t)0x886fa7c2, (q31_t)0x2d553afc, (q31_t)0x884be821, (q31_t)0x2cf72939, (q31_t)0x88287256, + (q31_t)0x2c98fbba, (q31_t)0x88054677, (q31_t)0x2c3ab2b9, (q31_t)0x87e2649b, (q31_t)0x2bdc4e6f, (q31_t)0x87bfccd7, (q31_t)0x2b7dcf17, (q31_t)0x879d7f41, + (q31_t)0x2b1f34eb, (q31_t)0x877b7bec, (q31_t)0x2ac08026, (q31_t)0x8759c2ef, (q31_t)0x2a61b101, (q31_t)0x8738545e, (q31_t)0x2a02c7b8, (q31_t)0x8717304e, + (q31_t)0x29a3c485, (q31_t)0x86f656d3, (q31_t)0x2944a7a2, (q31_t)0x86d5c802, (q31_t)0x28e5714b, (q31_t)0x86b583ee, (q31_t)0x288621b9, (q31_t)0x86958aac, + (q31_t)0x2826b928, (q31_t)0x8675dc4f, (q31_t)0x27c737d3, (q31_t)0x865678eb, (q31_t)0x27679df4, (q31_t)0x86376092, (q31_t)0x2707ebc7, (q31_t)0x86189359, + (q31_t)0x26a82186, (q31_t)0x85fa1153, (q31_t)0x26483f6c, (q31_t)0x85dbda91, (q31_t)0x25e845b6, (q31_t)0x85bdef28, (q31_t)0x2588349d, (q31_t)0x85a04f28, + (q31_t)0x25280c5e, (q31_t)0x8582faa5, (q31_t)0x24c7cd33, (q31_t)0x8565f1b0, (q31_t)0x24677758, (q31_t)0x8549345c, (q31_t)0x24070b08, (q31_t)0x852cc2bb, + (q31_t)0x23a6887f, (q31_t)0x85109cdd, (q31_t)0x2345eff8, (q31_t)0x84f4c2d4, (q31_t)0x22e541af, (q31_t)0x84d934b1, (q31_t)0x22847de0, (q31_t)0x84bdf286, + (q31_t)0x2223a4c5, (q31_t)0x84a2fc62, (q31_t)0x21c2b69c, (q31_t)0x84885258, (q31_t)0x2161b3a0, (q31_t)0x846df477, (q31_t)0x21009c0c, (q31_t)0x8453e2cf, + (q31_t)0x209f701c, (q31_t)0x843a1d70, (q31_t)0x203e300d, (q31_t)0x8420a46c, (q31_t)0x1fdcdc1b, (q31_t)0x840777d0, (q31_t)0x1f7b7481, (q31_t)0x83ee97ad, + (q31_t)0x1f19f97b, (q31_t)0x83d60412, (q31_t)0x1eb86b46, (q31_t)0x83bdbd0e, (q31_t)0x1e56ca1e, (q31_t)0x83a5c2b0, (q31_t)0x1df5163f, (q31_t)0x838e1507, + (q31_t)0x1d934fe5, (q31_t)0x8376b422, (q31_t)0x1d31774d, (q31_t)0x835fa00f, (q31_t)0x1ccf8cb3, (q31_t)0x8348d8dc, (q31_t)0x1c6d9053, (q31_t)0x83325e97, + (q31_t)0x1c0b826a, (q31_t)0x831c314e, (q31_t)0x1ba96335, (q31_t)0x83065110, (q31_t)0x1b4732ef, (q31_t)0x82f0bde8, (q31_t)0x1ae4f1d6, (q31_t)0x82db77e5, + (q31_t)0x1a82a026, (q31_t)0x82c67f14, (q31_t)0x1a203e1b, (q31_t)0x82b1d381, (q31_t)0x19bdcbf3, (q31_t)0x829d753a, (q31_t)0x195b49ea, (q31_t)0x8289644b, + (q31_t)0x18f8b83c, (q31_t)0x8275a0c0, (q31_t)0x18961728, (q31_t)0x82622aa6, (q31_t)0x183366e9, (q31_t)0x824f0208, (q31_t)0x17d0a7bc, (q31_t)0x823c26f3, + (q31_t)0x176dd9de, (q31_t)0x82299971, (q31_t)0x170afd8d, (q31_t)0x82175990, (q31_t)0x16a81305, (q31_t)0x82056758, (q31_t)0x16451a83, (q31_t)0x81f3c2d7, + (q31_t)0x15e21445, (q31_t)0x81e26c16, (q31_t)0x157f0086, (q31_t)0x81d16321, (q31_t)0x151bdf86, (q31_t)0x81c0a801, (q31_t)0x14b8b17f, (q31_t)0x81b03ac2, + (q31_t)0x145576b1, (q31_t)0x81a01b6d, (q31_t)0x13f22f58, (q31_t)0x81904a0c, (q31_t)0x138edbb1, (q31_t)0x8180c6a9, (q31_t)0x132b7bf9, (q31_t)0x8171914e, + (q31_t)0x12c8106f, (q31_t)0x8162aa04, (q31_t)0x1264994e, (q31_t)0x815410d4, (q31_t)0x120116d5, (q31_t)0x8145c5c7, (q31_t)0x119d8941, (q31_t)0x8137c8e6, + (q31_t)0x1139f0cf, (q31_t)0x812a1a3a, (q31_t)0x10d64dbd, (q31_t)0x811cb9ca, (q31_t)0x1072a048, (q31_t)0x810fa7a0, (q31_t)0x100ee8ad, (q31_t)0x8102e3c4, + (q31_t)0x0fab272b, (q31_t)0x80f66e3c, (q31_t)0x0f475bff, (q31_t)0x80ea4712, (q31_t)0x0ee38766, (q31_t)0x80de6e4c, (q31_t)0x0e7fa99e, (q31_t)0x80d2e3f2, + (q31_t)0x0e1bc2e4, (q31_t)0x80c7a80a, (q31_t)0x0db7d376, (q31_t)0x80bcba9d, (q31_t)0x0d53db92, (q31_t)0x80b21baf, (q31_t)0x0cefdb76, (q31_t)0x80a7cb49, + (q31_t)0x0c8bd35e, (q31_t)0x809dc971, (q31_t)0x0c27c389, (q31_t)0x8094162c, (q31_t)0x0bc3ac35, (q31_t)0x808ab180, (q31_t)0x0b5f8d9f, (q31_t)0x80819b74, + (q31_t)0x0afb6805, (q31_t)0x8078d40d, (q31_t)0x0a973ba5, (q31_t)0x80705b50, (q31_t)0x0a3308bd, (q31_t)0x80683143, (q31_t)0x09cecf89, (q31_t)0x806055eb, + (q31_t)0x096a9049, (q31_t)0x8058c94c, (q31_t)0x09064b3a, (q31_t)0x80518b6b, (q31_t)0x08a2009a, (q31_t)0x804a9c4d, (q31_t)0x083db0a7, (q31_t)0x8043fbf6, + (q31_t)0x07d95b9e, (q31_t)0x803daa6a, (q31_t)0x077501be, (q31_t)0x8037a7ac, (q31_t)0x0710a345, (q31_t)0x8031f3c2, (q31_t)0x06ac406f, (q31_t)0x802c8ead, + (q31_t)0x0647d97c, (q31_t)0x80277872, (q31_t)0x05e36ea9, (q31_t)0x8022b114, (q31_t)0x057f0035, (q31_t)0x801e3895, (q31_t)0x051a8e5c, (q31_t)0x801a0ef8, + (q31_t)0x04b6195d, (q31_t)0x80163440, (q31_t)0x0451a177, (q31_t)0x8012a86f, (q31_t)0x03ed26e6, (q31_t)0x800f6b88, (q31_t)0x0388a9ea, (q31_t)0x800c7d8c, + (q31_t)0x03242abf, (q31_t)0x8009de7e, (q31_t)0x02bfa9a4, (q31_t)0x80078e5e, (q31_t)0x025b26d7, (q31_t)0x80058d2f, (q31_t)0x01f6a297, (q31_t)0x8003daf1, + (q31_t)0x01921d20, (q31_t)0x800277a6, (q31_t)0x012d96b1, (q31_t)0x8001634e, (q31_t)0x00c90f88, (q31_t)0x80009dea, (q31_t)0x006487e3, (q31_t)0x8000277a +}; + +static const q31_t WeightsQ31_2048[4096] = { + (q31_t)0x7fffffff, (q31_t)0x00000000, (q31_t)0x7ffffd88, (q31_t)0xffe6de05, (q31_t)0x7ffff621, (q31_t)0xffcdbc0b, (q31_t)0x7fffe9cb, (q31_t)0xffb49a12, + (q31_t)0x7fffd886, (q31_t)0xff9b781d, (q31_t)0x7fffc251, (q31_t)0xff82562c, (q31_t)0x7fffa72c, (q31_t)0xff69343f, (q31_t)0x7fff8719, (q31_t)0xff501258, + (q31_t)0x7fff6216, (q31_t)0xff36f078, (q31_t)0x7fff3824, (q31_t)0xff1dcea0, (q31_t)0x7fff0943, (q31_t)0xff04acd0, (q31_t)0x7ffed572, (q31_t)0xfeeb8b0a, + (q31_t)0x7ffe9cb2, (q31_t)0xfed2694f, (q31_t)0x7ffe5f03, (q31_t)0xfeb947a0, (q31_t)0x7ffe1c65, (q31_t)0xfea025fd, (q31_t)0x7ffdd4d7, (q31_t)0xfe870467, + (q31_t)0x7ffd885a, (q31_t)0xfe6de2e0, (q31_t)0x7ffd36ee, (q31_t)0xfe54c169, (q31_t)0x7ffce093, (q31_t)0xfe3ba002, (q31_t)0x7ffc8549, (q31_t)0xfe227eac, + (q31_t)0x7ffc250f, (q31_t)0xfe095d69, (q31_t)0x7ffbbfe6, (q31_t)0xfdf03c3a, (q31_t)0x7ffb55ce, (q31_t)0xfdd71b1e, (q31_t)0x7ffae6c7, (q31_t)0xfdbdfa18, + (q31_t)0x7ffa72d1, (q31_t)0xfda4d929, (q31_t)0x7ff9f9ec, (q31_t)0xfd8bb850, (q31_t)0x7ff97c18, (q31_t)0xfd729790, (q31_t)0x7ff8f954, (q31_t)0xfd5976e9, + (q31_t)0x7ff871a2, (q31_t)0xfd40565c, (q31_t)0x7ff7e500, (q31_t)0xfd2735ea, (q31_t)0x7ff75370, (q31_t)0xfd0e1594, (q31_t)0x7ff6bcf0, (q31_t)0xfcf4f55c, + (q31_t)0x7ff62182, (q31_t)0xfcdbd541, (q31_t)0x7ff58125, (q31_t)0xfcc2b545, (q31_t)0x7ff4dbd9, (q31_t)0xfca9956a, (q31_t)0x7ff4319d, (q31_t)0xfc9075af, + (q31_t)0x7ff38274, (q31_t)0xfc775616, (q31_t)0x7ff2ce5b, (q31_t)0xfc5e36a0, (q31_t)0x7ff21553, (q31_t)0xfc45174e, (q31_t)0x7ff1575d, (q31_t)0xfc2bf821, + (q31_t)0x7ff09478, (q31_t)0xfc12d91a, (q31_t)0x7fefcca4, (q31_t)0xfbf9ba39, (q31_t)0x7feeffe1, (q31_t)0xfbe09b80, (q31_t)0x7fee2e30, (q31_t)0xfbc77cf0, + (q31_t)0x7fed5791, (q31_t)0xfbae5e89, (q31_t)0x7fec7c02, (q31_t)0xfb95404d, (q31_t)0x7feb9b85, (q31_t)0xfb7c223d, (q31_t)0x7feab61a, (q31_t)0xfb630459, + (q31_t)0x7fe9cbc0, (q31_t)0xfb49e6a3, (q31_t)0x7fe8dc78, (q31_t)0xfb30c91b, (q31_t)0x7fe7e841, (q31_t)0xfb17abc2, (q31_t)0x7fe6ef1c, (q31_t)0xfafe8e9b, + (q31_t)0x7fe5f108, (q31_t)0xfae571a4, (q31_t)0x7fe4ee06, (q31_t)0xfacc54e0, (q31_t)0x7fe3e616, (q31_t)0xfab3384f, (q31_t)0x7fe2d938, (q31_t)0xfa9a1bf3, + (q31_t)0x7fe1c76b, (q31_t)0xfa80ffcb, (q31_t)0x7fe0b0b1, (q31_t)0xfa67e3da, (q31_t)0x7fdf9508, (q31_t)0xfa4ec821, (q31_t)0x7fde7471, (q31_t)0xfa35ac9f, + (q31_t)0x7fdd4eec, (q31_t)0xfa1c9157, (q31_t)0x7fdc247a, (q31_t)0xfa037648, (q31_t)0x7fdaf519, (q31_t)0xf9ea5b75, (q31_t)0x7fd9c0ca, (q31_t)0xf9d140de, + (q31_t)0x7fd8878e, (q31_t)0xf9b82684, (q31_t)0x7fd74964, (q31_t)0xf99f0c68, (q31_t)0x7fd6064c, (q31_t)0xf985f28a, (q31_t)0x7fd4be46, (q31_t)0xf96cd8ed, + (q31_t)0x7fd37153, (q31_t)0xf953bf91, (q31_t)0x7fd21f72, (q31_t)0xf93aa676, (q31_t)0x7fd0c8a3, (q31_t)0xf9218d9e, (q31_t)0x7fcf6ce8, (q31_t)0xf908750a, + (q31_t)0x7fce0c3e, (q31_t)0xf8ef5cbb, (q31_t)0x7fcca6a7, (q31_t)0xf8d644b2, (q31_t)0x7fcb3c23, (q31_t)0xf8bd2cef, (q31_t)0x7fc9ccb2, (q31_t)0xf8a41574, + (q31_t)0x7fc85854, (q31_t)0xf88afe42, (q31_t)0x7fc6df08, (q31_t)0xf871e759, (q31_t)0x7fc560cf, (q31_t)0xf858d0bb, (q31_t)0x7fc3dda9, (q31_t)0xf83fba68, + (q31_t)0x7fc25596, (q31_t)0xf826a462, (q31_t)0x7fc0c896, (q31_t)0xf80d8ea9, (q31_t)0x7fbf36aa, (q31_t)0xf7f4793e, (q31_t)0x7fbd9fd0, (q31_t)0xf7db6423, + (q31_t)0x7fbc040a, (q31_t)0xf7c24f59, (q31_t)0x7fba6357, (q31_t)0xf7a93ae0, (q31_t)0x7fb8bdb8, (q31_t)0xf79026b9, (q31_t)0x7fb7132b, (q31_t)0xf77712e5, + (q31_t)0x7fb563b3, (q31_t)0xf75dff66, (q31_t)0x7fb3af4e, (q31_t)0xf744ec3b, (q31_t)0x7fb1f5fc, (q31_t)0xf72bd967, (q31_t)0x7fb037bf, (q31_t)0xf712c6ea, + (q31_t)0x7fae7495, (q31_t)0xf6f9b4c6, (q31_t)0x7facac7f, (q31_t)0xf6e0a2fa, (q31_t)0x7faadf7c, (q31_t)0xf6c79188, (q31_t)0x7fa90d8e, (q31_t)0xf6ae8071, + (q31_t)0x7fa736b4, (q31_t)0xf6956fb7, (q31_t)0x7fa55aee, (q31_t)0xf67c5f59, (q31_t)0x7fa37a3c, (q31_t)0xf6634f59, (q31_t)0x7fa1949e, (q31_t)0xf64a3fb8, + (q31_t)0x7f9faa15, (q31_t)0xf6313077, (q31_t)0x7f9dbaa0, (q31_t)0xf6182196, (q31_t)0x7f9bc640, (q31_t)0xf5ff1318, (q31_t)0x7f99ccf4, (q31_t)0xf5e604fc, + (q31_t)0x7f97cebd, (q31_t)0xf5ccf743, (q31_t)0x7f95cb9a, (q31_t)0xf5b3e9f0, (q31_t)0x7f93c38c, (q31_t)0xf59add02, (q31_t)0x7f91b694, (q31_t)0xf581d07b, + (q31_t)0x7f8fa4b0, (q31_t)0xf568c45b, (q31_t)0x7f8d8de1, (q31_t)0xf54fb8a4, (q31_t)0x7f8b7227, (q31_t)0xf536ad56, (q31_t)0x7f895182, (q31_t)0xf51da273, + (q31_t)0x7f872bf3, (q31_t)0xf50497fb, (q31_t)0x7f850179, (q31_t)0xf4eb8def, (q31_t)0x7f82d214, (q31_t)0xf4d28451, (q31_t)0x7f809dc5, (q31_t)0xf4b97b21, + (q31_t)0x7f7e648c, (q31_t)0xf4a07261, (q31_t)0x7f7c2668, (q31_t)0xf4876a10, (q31_t)0x7f79e35a, (q31_t)0xf46e6231, (q31_t)0x7f779b62, (q31_t)0xf4555ac5, + (q31_t)0x7f754e80, (q31_t)0xf43c53cb, (q31_t)0x7f72fcb4, (q31_t)0xf4234d45, (q31_t)0x7f70a5fe, (q31_t)0xf40a4735, (q31_t)0x7f6e4a5e, (q31_t)0xf3f1419a, + (q31_t)0x7f6be9d4, (q31_t)0xf3d83c77, (q31_t)0x7f698461, (q31_t)0xf3bf37cb, (q31_t)0x7f671a05, (q31_t)0xf3a63398, (q31_t)0x7f64aabf, (q31_t)0xf38d2fe0, + (q31_t)0x7f62368f, (q31_t)0xf3742ca2, (q31_t)0x7f5fbd77, (q31_t)0xf35b29e0, (q31_t)0x7f5d3f75, (q31_t)0xf342279b, (q31_t)0x7f5abc8a, (q31_t)0xf32925d3, + (q31_t)0x7f5834b7, (q31_t)0xf310248a, (q31_t)0x7f55a7fa, (q31_t)0xf2f723c1, (q31_t)0x7f531655, (q31_t)0xf2de2379, (q31_t)0x7f507fc7, (q31_t)0xf2c523b2, + (q31_t)0x7f4de451, (q31_t)0xf2ac246e, (q31_t)0x7f4b43f2, (q31_t)0xf29325ad, (q31_t)0x7f489eaa, (q31_t)0xf27a2771, (q31_t)0x7f45f47b, (q31_t)0xf26129ba, + (q31_t)0x7f434563, (q31_t)0xf2482c8a, (q31_t)0x7f409164, (q31_t)0xf22f2fe1, (q31_t)0x7f3dd87c, (q31_t)0xf21633c0, (q31_t)0x7f3b1aad, (q31_t)0xf1fd3829, + (q31_t)0x7f3857f6, (q31_t)0xf1e43d1c, (q31_t)0x7f359057, (q31_t)0xf1cb429a, (q31_t)0x7f32c3d1, (q31_t)0xf1b248a5, (q31_t)0x7f2ff263, (q31_t)0xf1994f3d, + (q31_t)0x7f2d1c0e, (q31_t)0xf1805662, (q31_t)0x7f2a40d2, (q31_t)0xf1675e17, (q31_t)0x7f2760af, (q31_t)0xf14e665c, (q31_t)0x7f247ba5, (q31_t)0xf1356f32, + (q31_t)0x7f2191b4, (q31_t)0xf11c789a, (q31_t)0x7f1ea2dc, (q31_t)0xf1038295, (q31_t)0x7f1baf1e, (q31_t)0xf0ea8d24, (q31_t)0x7f18b679, (q31_t)0xf0d19848, + (q31_t)0x7f15b8ee, (q31_t)0xf0b8a401, (q31_t)0x7f12b67c, (q31_t)0xf09fb051, (q31_t)0x7f0faf25, (q31_t)0xf086bd39, (q31_t)0x7f0ca2e7, (q31_t)0xf06dcaba, + (q31_t)0x7f0991c4, (q31_t)0xf054d8d5, (q31_t)0x7f067bba, (q31_t)0xf03be78a, (q31_t)0x7f0360cb, (q31_t)0xf022f6da, (q31_t)0x7f0040f6, (q31_t)0xf00a06c8, + (q31_t)0x7efd1c3c, (q31_t)0xeff11753, (q31_t)0x7ef9f29d, (q31_t)0xefd8287c, (q31_t)0x7ef6c418, (q31_t)0xefbf3a45, (q31_t)0x7ef390ae, (q31_t)0xefa64cae, + (q31_t)0x7ef05860, (q31_t)0xef8d5fb8, (q31_t)0x7eed1b2c, (q31_t)0xef747365, (q31_t)0x7ee9d914, (q31_t)0xef5b87b5, (q31_t)0x7ee69217, (q31_t)0xef429caa, + (q31_t)0x7ee34636, (q31_t)0xef29b243, (q31_t)0x7edff570, (q31_t)0xef10c883, (q31_t)0x7edc9fc6, (q31_t)0xeef7df6a, (q31_t)0x7ed94538, (q31_t)0xeedef6f9, + (q31_t)0x7ed5e5c6, (q31_t)0xeec60f31, (q31_t)0x7ed28171, (q31_t)0xeead2813, (q31_t)0x7ecf1837, (q31_t)0xee9441a0, (q31_t)0x7ecbaa1a, (q31_t)0xee7b5bd9, + (q31_t)0x7ec8371a, (q31_t)0xee6276bf, (q31_t)0x7ec4bf36, (q31_t)0xee499253, (q31_t)0x7ec14270, (q31_t)0xee30ae96, (q31_t)0x7ebdc0c6, (q31_t)0xee17cb88, + (q31_t)0x7eba3a39, (q31_t)0xedfee92b, (q31_t)0x7eb6aeca, (q31_t)0xede60780, (q31_t)0x7eb31e78, (q31_t)0xedcd2687, (q31_t)0x7eaf8943, (q31_t)0xedb44642, + (q31_t)0x7eabef2c, (q31_t)0xed9b66b2, (q31_t)0x7ea85033, (q31_t)0xed8287d7, (q31_t)0x7ea4ac58, (q31_t)0xed69a9b3, (q31_t)0x7ea1039b, (q31_t)0xed50cc46, + (q31_t)0x7e9d55fc, (q31_t)0xed37ef91, (q31_t)0x7e99a37c, (q31_t)0xed1f1396, (q31_t)0x7e95ec1a, (q31_t)0xed063856, (q31_t)0x7e922fd6, (q31_t)0xeced5dd0, + (q31_t)0x7e8e6eb2, (q31_t)0xecd48407, (q31_t)0x7e8aa8ac, (q31_t)0xecbbaafb, (q31_t)0x7e86ddc6, (q31_t)0xeca2d2ad, (q31_t)0x7e830dff, (q31_t)0xec89fb1e, + (q31_t)0x7e7f3957, (q31_t)0xec71244f, (q31_t)0x7e7b5fce, (q31_t)0xec584e41, (q31_t)0x7e778166, (q31_t)0xec3f78f6, (q31_t)0x7e739e1d, (q31_t)0xec26a46d, + (q31_t)0x7e6fb5f4, (q31_t)0xec0dd0a8, (q31_t)0x7e6bc8eb, (q31_t)0xebf4fda8, (q31_t)0x7e67d703, (q31_t)0xebdc2b6e, (q31_t)0x7e63e03b, (q31_t)0xebc359fb, + (q31_t)0x7e5fe493, (q31_t)0xebaa894f, (q31_t)0x7e5be40c, (q31_t)0xeb91b96c, (q31_t)0x7e57dea7, (q31_t)0xeb78ea52, (q31_t)0x7e53d462, (q31_t)0xeb601c04, + (q31_t)0x7e4fc53e, (q31_t)0xeb474e81, (q31_t)0x7e4bb13c, (q31_t)0xeb2e81ca, (q31_t)0x7e47985b, (q31_t)0xeb15b5e1, (q31_t)0x7e437a9c, (q31_t)0xeafceac6, + (q31_t)0x7e3f57ff, (q31_t)0xeae4207a, (q31_t)0x7e3b3083, (q31_t)0xeacb56ff, (q31_t)0x7e37042a, (q31_t)0xeab28e56, (q31_t)0x7e32d2f4, (q31_t)0xea99c67e, + (q31_t)0x7e2e9cdf, (q31_t)0xea80ff7a, (q31_t)0x7e2a61ed, (q31_t)0xea683949, (q31_t)0x7e26221f, (q31_t)0xea4f73ee, (q31_t)0x7e21dd73, (q31_t)0xea36af69, + (q31_t)0x7e1d93ea, (q31_t)0xea1debbb, (q31_t)0x7e194584, (q31_t)0xea0528e5, (q31_t)0x7e14f242, (q31_t)0xe9ec66e8, (q31_t)0x7e109a24, (q31_t)0xe9d3a5c5, + (q31_t)0x7e0c3d29, (q31_t)0xe9bae57d, (q31_t)0x7e07db52, (q31_t)0xe9a22610, (q31_t)0x7e0374a0, (q31_t)0xe9896781, (q31_t)0x7dff0911, (q31_t)0xe970a9ce, + (q31_t)0x7dfa98a8, (q31_t)0xe957ecfb, (q31_t)0x7df62362, (q31_t)0xe93f3107, (q31_t)0x7df1a942, (q31_t)0xe92675f4, (q31_t)0x7ded2a47, (q31_t)0xe90dbbc2, + (q31_t)0x7de8a670, (q31_t)0xe8f50273, (q31_t)0x7de41dc0, (q31_t)0xe8dc4a07, (q31_t)0x7ddf9034, (q31_t)0xe8c39280, (q31_t)0x7ddafdce, (q31_t)0xe8aadbde, + (q31_t)0x7dd6668f, (q31_t)0xe8922622, (q31_t)0x7dd1ca75, (q31_t)0xe879714d, (q31_t)0x7dcd2981, (q31_t)0xe860bd61, (q31_t)0x7dc883b4, (q31_t)0xe8480a5d, + (q31_t)0x7dc3d90d, (q31_t)0xe82f5844, (q31_t)0x7dbf298d, (q31_t)0xe816a716, (q31_t)0x7dba7534, (q31_t)0xe7fdf6d4, (q31_t)0x7db5bc02, (q31_t)0xe7e5477f, + (q31_t)0x7db0fdf8, (q31_t)0xe7cc9917, (q31_t)0x7dac3b15, (q31_t)0xe7b3eb9f, (q31_t)0x7da77359, (q31_t)0xe79b3f16, (q31_t)0x7da2a6c6, (q31_t)0xe782937e, + (q31_t)0x7d9dd55a, (q31_t)0xe769e8d8, (q31_t)0x7d98ff17, (q31_t)0xe7513f25, (q31_t)0x7d9423fc, (q31_t)0xe7389665, (q31_t)0x7d8f4409, (q31_t)0xe71fee99, + (q31_t)0x7d8a5f40, (q31_t)0xe70747c4, (q31_t)0x7d85759f, (q31_t)0xe6eea1e4, (q31_t)0x7d808728, (q31_t)0xe6d5fcfc, (q31_t)0x7d7b93da, (q31_t)0xe6bd590d, + (q31_t)0x7d769bb5, (q31_t)0xe6a4b616, (q31_t)0x7d719eba, (q31_t)0xe68c141a, (q31_t)0x7d6c9ce9, (q31_t)0xe6737319, (q31_t)0x7d679642, (q31_t)0xe65ad315, + (q31_t)0x7d628ac6, (q31_t)0xe642340d, (q31_t)0x7d5d7a74, (q31_t)0xe6299604, (q31_t)0x7d58654d, (q31_t)0xe610f8f9, (q31_t)0x7d534b50, (q31_t)0xe5f85cef, + (q31_t)0x7d4e2c7f, (q31_t)0xe5dfc1e5, (q31_t)0x7d4908d9, (q31_t)0xe5c727dd, (q31_t)0x7d43e05e, (q31_t)0xe5ae8ed8, (q31_t)0x7d3eb30f, (q31_t)0xe595f6d7, + (q31_t)0x7d3980ec, (q31_t)0xe57d5fda, (q31_t)0x7d3449f5, (q31_t)0xe564c9e3, (q31_t)0x7d2f0e2b, (q31_t)0xe54c34f3, (q31_t)0x7d29cd8c, (q31_t)0xe533a10a, + (q31_t)0x7d24881b, (q31_t)0xe51b0e2a, (q31_t)0x7d1f3dd6, (q31_t)0xe5027c53, (q31_t)0x7d19eebf, (q31_t)0xe4e9eb87, (q31_t)0x7d149ad5, (q31_t)0xe4d15bc6, + (q31_t)0x7d0f4218, (q31_t)0xe4b8cd11, (q31_t)0x7d09e489, (q31_t)0xe4a03f69, (q31_t)0x7d048228, (q31_t)0xe487b2d0, (q31_t)0x7cff1af5, (q31_t)0xe46f2745, + (q31_t)0x7cf9aef0, (q31_t)0xe4569ccb, (q31_t)0x7cf43e1a, (q31_t)0xe43e1362, (q31_t)0x7ceec873, (q31_t)0xe4258b0a, (q31_t)0x7ce94dfb, (q31_t)0xe40d03c6, + (q31_t)0x7ce3ceb2, (q31_t)0xe3f47d96, (q31_t)0x7cde4a98, (q31_t)0xe3dbf87a, (q31_t)0x7cd8c1ae, (q31_t)0xe3c37474, (q31_t)0x7cd333f3, (q31_t)0xe3aaf184, + (q31_t)0x7ccda169, (q31_t)0xe3926fad, (q31_t)0x7cc80a0f, (q31_t)0xe379eeed, (q31_t)0x7cc26de5, (q31_t)0xe3616f48, (q31_t)0x7cbcccec, (q31_t)0xe348f0bd, + (q31_t)0x7cb72724, (q31_t)0xe330734d, (q31_t)0x7cb17c8d, (q31_t)0xe317f6fa, (q31_t)0x7cabcd28, (q31_t)0xe2ff7bc3, (q31_t)0x7ca618f3, (q31_t)0xe2e701ac, + (q31_t)0x7ca05ff1, (q31_t)0xe2ce88b3, (q31_t)0x7c9aa221, (q31_t)0xe2b610da, (q31_t)0x7c94df83, (q31_t)0xe29d9a23, (q31_t)0x7c8f1817, (q31_t)0xe285248d, + (q31_t)0x7c894bde, (q31_t)0xe26cb01b, (q31_t)0x7c837ad8, (q31_t)0xe2543ccc, (q31_t)0x7c7da505, (q31_t)0xe23bcaa2, (q31_t)0x7c77ca65, (q31_t)0xe223599e, + (q31_t)0x7c71eaf9, (q31_t)0xe20ae9c1, (q31_t)0x7c6c06c0, (q31_t)0xe1f27b0b, (q31_t)0x7c661dbc, (q31_t)0xe1da0d7e, (q31_t)0x7c602fec, (q31_t)0xe1c1a11b, + (q31_t)0x7c5a3d50, (q31_t)0xe1a935e2, (q31_t)0x7c5445e9, (q31_t)0xe190cbd4, (q31_t)0x7c4e49b7, (q31_t)0xe17862f3, (q31_t)0x7c4848ba, (q31_t)0xe15ffb3f, + (q31_t)0x7c4242f2, (q31_t)0xe14794ba, (q31_t)0x7c3c3860, (q31_t)0xe12f2f63, (q31_t)0x7c362904, (q31_t)0xe116cb3d, (q31_t)0x7c3014de, (q31_t)0xe0fe6848, + (q31_t)0x7c29fbee, (q31_t)0xe0e60685, (q31_t)0x7c23de35, (q31_t)0xe0cda5f5, (q31_t)0x7c1dbbb3, (q31_t)0xe0b54698, (q31_t)0x7c179467, (q31_t)0xe09ce871, + (q31_t)0x7c116853, (q31_t)0xe0848b7f, (q31_t)0x7c0b3777, (q31_t)0xe06c2fc4, (q31_t)0x7c0501d2, (q31_t)0xe053d541, (q31_t)0x7bfec765, (q31_t)0xe03b7bf6, + (q31_t)0x7bf88830, (q31_t)0xe02323e5, (q31_t)0x7bf24434, (q31_t)0xe00acd0e, (q31_t)0x7bebfb70, (q31_t)0xdff27773, (q31_t)0x7be5ade6, (q31_t)0xdfda2314, + (q31_t)0x7bdf5b94, (q31_t)0xdfc1cff3, (q31_t)0x7bd9047c, (q31_t)0xdfa97e0f, (q31_t)0x7bd2a89e, (q31_t)0xdf912d6b, (q31_t)0x7bcc47fa, (q31_t)0xdf78de07, + (q31_t)0x7bc5e290, (q31_t)0xdf608fe4, (q31_t)0x7bbf7860, (q31_t)0xdf484302, (q31_t)0x7bb9096b, (q31_t)0xdf2ff764, (q31_t)0x7bb295b0, (q31_t)0xdf17ad0a, + (q31_t)0x7bac1d31, (q31_t)0xdeff63f4, (q31_t)0x7ba59fee, (q31_t)0xdee71c24, (q31_t)0x7b9f1de6, (q31_t)0xdeced59b, (q31_t)0x7b989719, (q31_t)0xdeb69059, + (q31_t)0x7b920b89, (q31_t)0xde9e4c60, (q31_t)0x7b8b7b36, (q31_t)0xde8609b1, (q31_t)0x7b84e61f, (q31_t)0xde6dc84b, (q31_t)0x7b7e4c45, (q31_t)0xde558831, + (q31_t)0x7b77ada8, (q31_t)0xde3d4964, (q31_t)0x7b710a49, (q31_t)0xde250be3, (q31_t)0x7b6a6227, (q31_t)0xde0ccfb1, (q31_t)0x7b63b543, (q31_t)0xddf494ce, + (q31_t)0x7b5d039e, (q31_t)0xdddc5b3b, (q31_t)0x7b564d36, (q31_t)0xddc422f8, (q31_t)0x7b4f920e, (q31_t)0xddabec08, (q31_t)0x7b48d225, (q31_t)0xdd93b66a, + (q31_t)0x7b420d7a, (q31_t)0xdd7b8220, (q31_t)0x7b3b4410, (q31_t)0xdd634f2b, (q31_t)0x7b3475e5, (q31_t)0xdd4b1d8c, (q31_t)0x7b2da2fa, (q31_t)0xdd32ed43, + (q31_t)0x7b26cb4f, (q31_t)0xdd1abe51, (q31_t)0x7b1feee5, (q31_t)0xdd0290b8, (q31_t)0x7b190dbc, (q31_t)0xdcea6478, (q31_t)0x7b1227d3, (q31_t)0xdcd23993, + (q31_t)0x7b0b3d2c, (q31_t)0xdcba1008, (q31_t)0x7b044dc7, (q31_t)0xdca1e7da, (q31_t)0x7afd59a4, (q31_t)0xdc89c109, (q31_t)0x7af660c2, (q31_t)0xdc719b96, + (q31_t)0x7aef6323, (q31_t)0xdc597781, (q31_t)0x7ae860c7, (q31_t)0xdc4154cd, (q31_t)0x7ae159ae, (q31_t)0xdc293379, (q31_t)0x7ada4dd8, (q31_t)0xdc111388, + (q31_t)0x7ad33d45, (q31_t)0xdbf8f4f8, (q31_t)0x7acc27f7, (q31_t)0xdbe0d7cd, (q31_t)0x7ac50dec, (q31_t)0xdbc8bc06, (q31_t)0x7abdef25, (q31_t)0xdbb0a1a4, + (q31_t)0x7ab6cba4, (q31_t)0xdb9888a8, (q31_t)0x7aafa367, (q31_t)0xdb807114, (q31_t)0x7aa8766f, (q31_t)0xdb685ae9, (q31_t)0x7aa144bc, (q31_t)0xdb504626, + (q31_t)0x7a9a0e50, (q31_t)0xdb3832cd, (q31_t)0x7a92d329, (q31_t)0xdb2020e0, (q31_t)0x7a8b9348, (q31_t)0xdb08105e, (q31_t)0x7a844eae, (q31_t)0xdaf00149, + (q31_t)0x7a7d055b, (q31_t)0xdad7f3a2, (q31_t)0x7a75b74f, (q31_t)0xdabfe76a, (q31_t)0x7a6e648a, (q31_t)0xdaa7dca1, (q31_t)0x7a670d0d, (q31_t)0xda8fd349, + (q31_t)0x7a5fb0d8, (q31_t)0xda77cb63, (q31_t)0x7a584feb, (q31_t)0xda5fc4ef, (q31_t)0x7a50ea47, (q31_t)0xda47bfee, (q31_t)0x7a497feb, (q31_t)0xda2fbc61, + (q31_t)0x7a4210d8, (q31_t)0xda17ba4a, (q31_t)0x7a3a9d0f, (q31_t)0xd9ffb9a9, (q31_t)0x7a332490, (q31_t)0xd9e7ba7f, (q31_t)0x7a2ba75a, (q31_t)0xd9cfbccd, + (q31_t)0x7a24256f, (q31_t)0xd9b7c094, (q31_t)0x7a1c9ece, (q31_t)0xd99fc5d4, (q31_t)0x7a151378, (q31_t)0xd987cc90, (q31_t)0x7a0d836d, (q31_t)0xd96fd4c7, + (q31_t)0x7a05eead, (q31_t)0xd957de7a, (q31_t)0x79fe5539, (q31_t)0xd93fe9ab, (q31_t)0x79f6b711, (q31_t)0xd927f65b, (q31_t)0x79ef1436, (q31_t)0xd910048a, + (q31_t)0x79e76ca7, (q31_t)0xd8f81439, (q31_t)0x79dfc064, (q31_t)0xd8e0256a, (q31_t)0x79d80f6f, (q31_t)0xd8c8381d, (q31_t)0x79d059c8, (q31_t)0xd8b04c52, + (q31_t)0x79c89f6e, (q31_t)0xd898620c, (q31_t)0x79c0e062, (q31_t)0xd880794b, (q31_t)0x79b91ca4, (q31_t)0xd868920f, (q31_t)0x79b15435, (q31_t)0xd850ac5a, + (q31_t)0x79a98715, (q31_t)0xd838c82d, (q31_t)0x79a1b545, (q31_t)0xd820e589, (q31_t)0x7999dec4, (q31_t)0xd809046e, (q31_t)0x79920392, (q31_t)0xd7f124dd, + (q31_t)0x798a23b1, (q31_t)0xd7d946d8, (q31_t)0x79823f20, (q31_t)0xd7c16a5f, (q31_t)0x797a55e0, (q31_t)0xd7a98f73, (q31_t)0x797267f2, (q31_t)0xd791b616, + (q31_t)0x796a7554, (q31_t)0xd779de47, (q31_t)0x79627e08, (q31_t)0xd7620808, (q31_t)0x795a820e, (q31_t)0xd74a335b, (q31_t)0x79528167, (q31_t)0xd732603f, + (q31_t)0x794a7c12, (q31_t)0xd71a8eb5, (q31_t)0x79427210, (q31_t)0xd702bec0, (q31_t)0x793a6361, (q31_t)0xd6eaf05f, (q31_t)0x79325006, (q31_t)0xd6d32393, + (q31_t)0x792a37fe, (q31_t)0xd6bb585e, (q31_t)0x79221b4b, (q31_t)0xd6a38ec0, (q31_t)0x7919f9ec, (q31_t)0xd68bc6ba, (q31_t)0x7911d3e2, (q31_t)0xd674004e, + (q31_t)0x7909a92d, (q31_t)0xd65c3b7b, (q31_t)0x790179cd, (q31_t)0xd6447844, (q31_t)0x78f945c3, (q31_t)0xd62cb6a8, (q31_t)0x78f10d0f, (q31_t)0xd614f6a9, + (q31_t)0x78e8cfb2, (q31_t)0xd5fd3848, (q31_t)0x78e08dab, (q31_t)0xd5e57b85, (q31_t)0x78d846fb, (q31_t)0xd5cdc062, (q31_t)0x78cffba3, (q31_t)0xd5b606e0, + (q31_t)0x78c7aba2, (q31_t)0xd59e4eff, (q31_t)0x78bf56f9, (q31_t)0xd58698c0, (q31_t)0x78b6fda8, (q31_t)0xd56ee424, (q31_t)0x78ae9fb0, (q31_t)0xd557312d, + (q31_t)0x78a63d11, (q31_t)0xd53f7fda, (q31_t)0x789dd5cb, (q31_t)0xd527d02e, (q31_t)0x789569df, (q31_t)0xd5102228, (q31_t)0x788cf94c, (q31_t)0xd4f875ca, + (q31_t)0x78848414, (q31_t)0xd4e0cb15, (q31_t)0x787c0a36, (q31_t)0xd4c92209, (q31_t)0x78738bb3, (q31_t)0xd4b17aa8, (q31_t)0x786b088c, (q31_t)0xd499d4f2, + (q31_t)0x786280bf, (q31_t)0xd48230e9, (q31_t)0x7859f44f, (q31_t)0xd46a8e8d, (q31_t)0x7851633b, (q31_t)0xd452eddf, (q31_t)0x7848cd83, (q31_t)0xd43b4ee0, + (q31_t)0x78403329, (q31_t)0xd423b191, (q31_t)0x7837942b, (q31_t)0xd40c15f3, (q31_t)0x782ef08b, (q31_t)0xd3f47c06, (q31_t)0x78264849, (q31_t)0xd3dce3cd, + (q31_t)0x781d9b65, (q31_t)0xd3c54d47, (q31_t)0x7814e9df, (q31_t)0xd3adb876, (q31_t)0x780c33b8, (q31_t)0xd396255a, (q31_t)0x780378f1, (q31_t)0xd37e93f4, + (q31_t)0x77fab989, (q31_t)0xd3670446, (q31_t)0x77f1f581, (q31_t)0xd34f764f, (q31_t)0x77e92cd9, (q31_t)0xd337ea12, (q31_t)0x77e05f91, (q31_t)0xd3205f8f, + (q31_t)0x77d78daa, (q31_t)0xd308d6c7, (q31_t)0x77ceb725, (q31_t)0xd2f14fba, (q31_t)0x77c5dc01, (q31_t)0xd2d9ca6a, (q31_t)0x77bcfc3f, (q31_t)0xd2c246d8, + (q31_t)0x77b417df, (q31_t)0xd2aac504, (q31_t)0x77ab2ee2, (q31_t)0xd29344f0, (q31_t)0x77a24148, (q31_t)0xd27bc69c, (q31_t)0x77994f11, (q31_t)0xd2644a0a, + (q31_t)0x7790583e, (q31_t)0xd24ccf39, (q31_t)0x77875cce, (q31_t)0xd235562b, (q31_t)0x777e5cc3, (q31_t)0xd21ddee2, (q31_t)0x7775581d, (q31_t)0xd206695d, + (q31_t)0x776c4edb, (q31_t)0xd1eef59e, (q31_t)0x776340ff, (q31_t)0xd1d783a6, (q31_t)0x775a2e89, (q31_t)0xd1c01375, (q31_t)0x77511778, (q31_t)0xd1a8a50d, + (q31_t)0x7747fbce, (q31_t)0xd191386e, (q31_t)0x773edb8b, (q31_t)0xd179cd99, (q31_t)0x7735b6af, (q31_t)0xd1626490, (q31_t)0x772c8d3a, (q31_t)0xd14afd52, + (q31_t)0x77235f2d, (q31_t)0xd13397e2, (q31_t)0x771a2c88, (q31_t)0xd11c343f, (q31_t)0x7710f54c, (q31_t)0xd104d26b, (q31_t)0x7707b979, (q31_t)0xd0ed7267, + (q31_t)0x76fe790e, (q31_t)0xd0d61434, (q31_t)0x76f5340e, (q31_t)0xd0beb7d2, (q31_t)0x76ebea77, (q31_t)0xd0a75d42, (q31_t)0x76e29c4b, (q31_t)0xd0900486, + (q31_t)0x76d94989, (q31_t)0xd078ad9e, (q31_t)0x76cff232, (q31_t)0xd061588b, (q31_t)0x76c69647, (q31_t)0xd04a054e, (q31_t)0x76bd35c7, (q31_t)0xd032b3e7, + (q31_t)0x76b3d0b4, (q31_t)0xd01b6459, (q31_t)0x76aa670d, (q31_t)0xd00416a3, (q31_t)0x76a0f8d2, (q31_t)0xcfeccac7, (q31_t)0x76978605, (q31_t)0xcfd580c6, + (q31_t)0x768e0ea6, (q31_t)0xcfbe389f, (q31_t)0x768492b4, (q31_t)0xcfa6f255, (q31_t)0x767b1231, (q31_t)0xcf8fade9, (q31_t)0x76718d1c, (q31_t)0xcf786b5a, + (q31_t)0x76680376, (q31_t)0xcf612aaa, (q31_t)0x765e7540, (q31_t)0xcf49ebda, (q31_t)0x7654e279, (q31_t)0xcf32aeeb, (q31_t)0x764b4b23, (q31_t)0xcf1b73de, + (q31_t)0x7641af3d, (q31_t)0xcf043ab3, (q31_t)0x76380ec8, (q31_t)0xceed036b, (q31_t)0x762e69c4, (q31_t)0xced5ce08, (q31_t)0x7624c031, (q31_t)0xcebe9a8a, + (q31_t)0x761b1211, (q31_t)0xcea768f2, (q31_t)0x76115f63, (q31_t)0xce903942, (q31_t)0x7607a828, (q31_t)0xce790b79, (q31_t)0x75fdec60, (q31_t)0xce61df99, + (q31_t)0x75f42c0b, (q31_t)0xce4ab5a2, (q31_t)0x75ea672a, (q31_t)0xce338d97, (q31_t)0x75e09dbd, (q31_t)0xce1c6777, (q31_t)0x75d6cfc5, (q31_t)0xce054343, + (q31_t)0x75ccfd42, (q31_t)0xcdee20fc, (q31_t)0x75c32634, (q31_t)0xcdd700a4, (q31_t)0x75b94a9c, (q31_t)0xcdbfe23a, (q31_t)0x75af6a7b, (q31_t)0xcda8c5c1, + (q31_t)0x75a585cf, (q31_t)0xcd91ab39, (q31_t)0x759b9c9b, (q31_t)0xcd7a92a2, (q31_t)0x7591aedd, (q31_t)0xcd637bfe, (q31_t)0x7587bc98, (q31_t)0xcd4c674d, + (q31_t)0x757dc5ca, (q31_t)0xcd355491, (q31_t)0x7573ca75, (q31_t)0xcd1e43ca, (q31_t)0x7569ca99, (q31_t)0xcd0734f9, (q31_t)0x755fc635, (q31_t)0xccf0281f, + (q31_t)0x7555bd4c, (q31_t)0xccd91d3d, (q31_t)0x754bafdc, (q31_t)0xccc21455, (q31_t)0x75419de7, (q31_t)0xccab0d65, (q31_t)0x7537876c, (q31_t)0xcc940871, + (q31_t)0x752d6c6c, (q31_t)0xcc7d0578, (q31_t)0x75234ce8, (q31_t)0xcc66047b, (q31_t)0x751928e0, (q31_t)0xcc4f057c, (q31_t)0x750f0054, (q31_t)0xcc38087b, + (q31_t)0x7504d345, (q31_t)0xcc210d79, (q31_t)0x74faa1b3, (q31_t)0xcc0a1477, (q31_t)0x74f06b9e, (q31_t)0xcbf31d75, (q31_t)0x74e63108, (q31_t)0xcbdc2876, + (q31_t)0x74dbf1ef, (q31_t)0xcbc53579, (q31_t)0x74d1ae55, (q31_t)0xcbae447f, (q31_t)0x74c7663a, (q31_t)0xcb97558a, (q31_t)0x74bd199f, (q31_t)0xcb80689a, + (q31_t)0x74b2c884, (q31_t)0xcb697db0, (q31_t)0x74a872e8, (q31_t)0xcb5294ce, (q31_t)0x749e18cd, (q31_t)0xcb3badf3, (q31_t)0x7493ba34, (q31_t)0xcb24c921, + (q31_t)0x7489571c, (q31_t)0xcb0de658, (q31_t)0x747eef85, (q31_t)0xcaf7059a, (q31_t)0x74748371, (q31_t)0xcae026e8, (q31_t)0x746a12df, (q31_t)0xcac94a42, + (q31_t)0x745f9dd1, (q31_t)0xcab26fa9, (q31_t)0x74552446, (q31_t)0xca9b971e, (q31_t)0x744aa63f, (q31_t)0xca84c0a3, (q31_t)0x744023bc, (q31_t)0xca6dec37, + (q31_t)0x74359cbd, (q31_t)0xca5719db, (q31_t)0x742b1144, (q31_t)0xca404992, (q31_t)0x74208150, (q31_t)0xca297b5a, (q31_t)0x7415ece2, (q31_t)0xca12af37, + (q31_t)0x740b53fb, (q31_t)0xc9fbe527, (q31_t)0x7400b69a, (q31_t)0xc9e51d2d, (q31_t)0x73f614c0, (q31_t)0xc9ce5748, (q31_t)0x73eb6e6e, (q31_t)0xc9b7937a, + (q31_t)0x73e0c3a3, (q31_t)0xc9a0d1c5, (q31_t)0x73d61461, (q31_t)0xc98a1227, (q31_t)0x73cb60a8, (q31_t)0xc97354a4, (q31_t)0x73c0a878, (q31_t)0xc95c993a, + (q31_t)0x73b5ebd1, (q31_t)0xc945dfec, (q31_t)0x73ab2ab4, (q31_t)0xc92f28ba, (q31_t)0x73a06522, (q31_t)0xc91873a5, (q31_t)0x73959b1b, (q31_t)0xc901c0ae, + (q31_t)0x738acc9e, (q31_t)0xc8eb0fd6, (q31_t)0x737ff9ae, (q31_t)0xc8d4611d, (q31_t)0x73752249, (q31_t)0xc8bdb485, (q31_t)0x736a4671, (q31_t)0xc8a70a0e, + (q31_t)0x735f6626, (q31_t)0xc89061ba, (q31_t)0x73548168, (q31_t)0xc879bb89, (q31_t)0x73499838, (q31_t)0xc863177b, (q31_t)0x733eaa96, (q31_t)0xc84c7593, + (q31_t)0x7333b883, (q31_t)0xc835d5d0, (q31_t)0x7328c1ff, (q31_t)0xc81f3834, (q31_t)0x731dc70a, (q31_t)0xc8089cbf, (q31_t)0x7312c7a5, (q31_t)0xc7f20373, + (q31_t)0x7307c3d0, (q31_t)0xc7db6c50, (q31_t)0x72fcbb8c, (q31_t)0xc7c4d757, (q31_t)0x72f1aed9, (q31_t)0xc7ae4489, (q31_t)0x72e69db7, (q31_t)0xc797b3e7, + (q31_t)0x72db8828, (q31_t)0xc7812572, (q31_t)0x72d06e2b, (q31_t)0xc76a992a, (q31_t)0x72c54fc1, (q31_t)0xc7540f11, (q31_t)0x72ba2cea, (q31_t)0xc73d8727, + (q31_t)0x72af05a7, (q31_t)0xc727016d, (q31_t)0x72a3d9f7, (q31_t)0xc7107de4, (q31_t)0x7298a9dd, (q31_t)0xc6f9fc8d, (q31_t)0x728d7557, (q31_t)0xc6e37d69, + (q31_t)0x72823c67, (q31_t)0xc6cd0079, (q31_t)0x7276ff0d, (q31_t)0xc6b685bd, (q31_t)0x726bbd48, (q31_t)0xc6a00d37, (q31_t)0x7260771b, (q31_t)0xc68996e7, + (q31_t)0x72552c85, (q31_t)0xc67322ce, (q31_t)0x7249dd86, (q31_t)0xc65cb0ed, (q31_t)0x723e8a20, (q31_t)0xc6464144, (q31_t)0x72333251, (q31_t)0xc62fd3d6, + (q31_t)0x7227d61c, (q31_t)0xc61968a2, (q31_t)0x721c7580, (q31_t)0xc602ffaa, (q31_t)0x7211107e, (q31_t)0xc5ec98ee, (q31_t)0x7205a716, (q31_t)0xc5d6346f, + (q31_t)0x71fa3949, (q31_t)0xc5bfd22e, (q31_t)0x71eec716, (q31_t)0xc5a9722c, (q31_t)0x71e35080, (q31_t)0xc593146a, (q31_t)0x71d7d585, (q31_t)0xc57cb8e9, + (q31_t)0x71cc5626, (q31_t)0xc5665fa9, (q31_t)0x71c0d265, (q31_t)0xc55008ab, (q31_t)0x71b54a41, (q31_t)0xc539b3f1, (q31_t)0x71a9bdba, (q31_t)0xc523617a, + (q31_t)0x719e2cd2, (q31_t)0xc50d1149, (q31_t)0x71929789, (q31_t)0xc4f6c35d, (q31_t)0x7186fdde, (q31_t)0xc4e077b8, (q31_t)0x717b5fd3, (q31_t)0xc4ca2e5b, + (q31_t)0x716fbd68, (q31_t)0xc4b3e746, (q31_t)0x7164169d, (q31_t)0xc49da27a, (q31_t)0x71586b74, (q31_t)0xc4875ff9, (q31_t)0x714cbbeb, (q31_t)0xc4711fc2, + (q31_t)0x71410805, (q31_t)0xc45ae1d7, (q31_t)0x71354fc0, (q31_t)0xc444a639, (q31_t)0x7129931f, (q31_t)0xc42e6ce8, (q31_t)0x711dd220, (q31_t)0xc41835e6, + (q31_t)0x71120cc5, (q31_t)0xc4020133, (q31_t)0x7106430e, (q31_t)0xc3ebced0, (q31_t)0x70fa74fc, (q31_t)0xc3d59ebe, (q31_t)0x70eea28e, (q31_t)0xc3bf70fd, + (q31_t)0x70e2cbc6, (q31_t)0xc3a94590, (q31_t)0x70d6f0a4, (q31_t)0xc3931c76, (q31_t)0x70cb1128, (q31_t)0xc37cf5b0, (q31_t)0x70bf2d53, (q31_t)0xc366d140, + (q31_t)0x70b34525, (q31_t)0xc350af26, (q31_t)0x70a7589f, (q31_t)0xc33a8f62, (q31_t)0x709b67c0, (q31_t)0xc32471f7, (q31_t)0x708f728b, (q31_t)0xc30e56e4, + (q31_t)0x708378ff, (q31_t)0xc2f83e2a, (q31_t)0x70777b1c, (q31_t)0xc2e227cb, (q31_t)0x706b78e3, (q31_t)0xc2cc13c7, (q31_t)0x705f7255, (q31_t)0xc2b6021f, + (q31_t)0x70536771, (q31_t)0xc29ff2d4, (q31_t)0x70475839, (q31_t)0xc289e5e7, (q31_t)0x703b44ad, (q31_t)0xc273db58, (q31_t)0x702f2ccd, (q31_t)0xc25dd329, + (q31_t)0x7023109a, (q31_t)0xc247cd5a, (q31_t)0x7016f014, (q31_t)0xc231c9ec, (q31_t)0x700acb3c, (q31_t)0xc21bc8e1, (q31_t)0x6ffea212, (q31_t)0xc205ca38, + (q31_t)0x6ff27497, (q31_t)0xc1efcdf3, (q31_t)0x6fe642ca, (q31_t)0xc1d9d412, (q31_t)0x6fda0cae, (q31_t)0xc1c3dc97, (q31_t)0x6fcdd241, (q31_t)0xc1ade781, + (q31_t)0x6fc19385, (q31_t)0xc197f4d4, (q31_t)0x6fb5507a, (q31_t)0xc182048d, (q31_t)0x6fa90921, (q31_t)0xc16c16b0, (q31_t)0x6f9cbd79, (q31_t)0xc1562b3d, + (q31_t)0x6f906d84, (q31_t)0xc1404233, (q31_t)0x6f841942, (q31_t)0xc12a5b95, (q31_t)0x6f77c0b3, (q31_t)0xc1147764, (q31_t)0x6f6b63d8, (q31_t)0xc0fe959f, + (q31_t)0x6f5f02b2, (q31_t)0xc0e8b648, (q31_t)0x6f529d40, (q31_t)0xc0d2d960, (q31_t)0x6f463383, (q31_t)0xc0bcfee7, (q31_t)0x6f39c57d, (q31_t)0xc0a726df, + (q31_t)0x6f2d532c, (q31_t)0xc0915148, (q31_t)0x6f20dc92, (q31_t)0xc07b7e23, (q31_t)0x6f1461b0, (q31_t)0xc065ad70, (q31_t)0x6f07e285, (q31_t)0xc04fdf32, + (q31_t)0x6efb5f12, (q31_t)0xc03a1368, (q31_t)0x6eeed758, (q31_t)0xc0244a14, (q31_t)0x6ee24b57, (q31_t)0xc00e8336, (q31_t)0x6ed5bb10, (q31_t)0xbff8bece, + (q31_t)0x6ec92683, (q31_t)0xbfe2fcdf, (q31_t)0x6ebc8db0, (q31_t)0xbfcd3d69, (q31_t)0x6eaff099, (q31_t)0xbfb7806c, (q31_t)0x6ea34f3d, (q31_t)0xbfa1c5ea, + (q31_t)0x6e96a99d, (q31_t)0xbf8c0de3, (q31_t)0x6e89ffb9, (q31_t)0xbf765858, (q31_t)0x6e7d5193, (q31_t)0xbf60a54a, (q31_t)0x6e709f2a, (q31_t)0xbf4af4ba, + (q31_t)0x6e63e87f, (q31_t)0xbf3546a8, (q31_t)0x6e572d93, (q31_t)0xbf1f9b16, (q31_t)0x6e4a6e66, (q31_t)0xbf09f205, (q31_t)0x6e3daaf8, (q31_t)0xbef44b74, + (q31_t)0x6e30e34a, (q31_t)0xbedea765, (q31_t)0x6e24175c, (q31_t)0xbec905d9, (q31_t)0x6e174730, (q31_t)0xbeb366d1, (q31_t)0x6e0a72c5, (q31_t)0xbe9dca4e, + (q31_t)0x6dfd9a1c, (q31_t)0xbe88304f, (q31_t)0x6df0bd35, (q31_t)0xbe7298d7, (q31_t)0x6de3dc11, (q31_t)0xbe5d03e6, (q31_t)0x6dd6f6b1, (q31_t)0xbe47717c, + (q31_t)0x6dca0d14, (q31_t)0xbe31e19b, (q31_t)0x6dbd1f3c, (q31_t)0xbe1c5444, (q31_t)0x6db02d29, (q31_t)0xbe06c977, (q31_t)0x6da336dc, (q31_t)0xbdf14135, + (q31_t)0x6d963c54, (q31_t)0xbddbbb7f, (q31_t)0x6d893d93, (q31_t)0xbdc63856, (q31_t)0x6d7c3a98, (q31_t)0xbdb0b7bb, (q31_t)0x6d6f3365, (q31_t)0xbd9b39ad, + (q31_t)0x6d6227fa, (q31_t)0xbd85be30, (q31_t)0x6d551858, (q31_t)0xbd704542, (q31_t)0x6d48047e, (q31_t)0xbd5acee5, (q31_t)0x6d3aec6e, (q31_t)0xbd455b1a, + (q31_t)0x6d2dd027, (q31_t)0xbd2fe9e2, (q31_t)0x6d20afac, (q31_t)0xbd1a7b3d, (q31_t)0x6d138afb, (q31_t)0xbd050f2c, (q31_t)0x6d066215, (q31_t)0xbcefa5b0, + (q31_t)0x6cf934fc, (q31_t)0xbcda3ecb, (q31_t)0x6cec03af, (q31_t)0xbcc4da7b, (q31_t)0x6cdece2f, (q31_t)0xbcaf78c4, (q31_t)0x6cd1947c, (q31_t)0xbc9a19a5, + (q31_t)0x6cc45698, (q31_t)0xbc84bd1f, (q31_t)0x6cb71482, (q31_t)0xbc6f6333, (q31_t)0x6ca9ce3b, (q31_t)0xbc5a0be2, (q31_t)0x6c9c83c3, (q31_t)0xbc44b72c, + (q31_t)0x6c8f351c, (q31_t)0xbc2f6513, (q31_t)0x6c81e245, (q31_t)0xbc1a1598, (q31_t)0x6c748b3f, (q31_t)0xbc04c8ba, (q31_t)0x6c67300b, (q31_t)0xbbef7e7c, + (q31_t)0x6c59d0a9, (q31_t)0xbbda36dd, (q31_t)0x6c4c6d1a, (q31_t)0xbbc4f1df, (q31_t)0x6c3f055d, (q31_t)0xbbafaf82, (q31_t)0x6c319975, (q31_t)0xbb9a6fc7, + (q31_t)0x6c242960, (q31_t)0xbb8532b0, (q31_t)0x6c16b521, (q31_t)0xbb6ff83c, (q31_t)0x6c093cb6, (q31_t)0xbb5ac06d, (q31_t)0x6bfbc021, (q31_t)0xbb458b43, + (q31_t)0x6bee3f62, (q31_t)0xbb3058c0, (q31_t)0x6be0ba7b, (q31_t)0xbb1b28e4, (q31_t)0x6bd3316a, (q31_t)0xbb05fbb0, (q31_t)0x6bc5a431, (q31_t)0xbaf0d125, + (q31_t)0x6bb812d1, (q31_t)0xbadba943, (q31_t)0x6baa7d49, (q31_t)0xbac6840c, (q31_t)0x6b9ce39b, (q31_t)0xbab16180, (q31_t)0x6b8f45c7, (q31_t)0xba9c41a0, + (q31_t)0x6b81a3cd, (q31_t)0xba87246d, (q31_t)0x6b73fdae, (q31_t)0xba7209e7, (q31_t)0x6b66536b, (q31_t)0xba5cf210, (q31_t)0x6b58a503, (q31_t)0xba47dce8, + (q31_t)0x6b4af279, (q31_t)0xba32ca71, (q31_t)0x6b3d3bcb, (q31_t)0xba1dbaaa, (q31_t)0x6b2f80fb, (q31_t)0xba08ad95, (q31_t)0x6b21c208, (q31_t)0xb9f3a332, + (q31_t)0x6b13fef5, (q31_t)0xb9de9b83, (q31_t)0x6b0637c1, (q31_t)0xb9c99688, (q31_t)0x6af86c6c, (q31_t)0xb9b49442, (q31_t)0x6aea9cf8, (q31_t)0xb99f94b2, + (q31_t)0x6adcc964, (q31_t)0xb98a97d8, (q31_t)0x6acef1b2, (q31_t)0xb9759db6, (q31_t)0x6ac115e2, (q31_t)0xb960a64c, (q31_t)0x6ab335f4, (q31_t)0xb94bb19b, + (q31_t)0x6aa551e9, (q31_t)0xb936bfa4, (q31_t)0x6a9769c1, (q31_t)0xb921d067, (q31_t)0x6a897d7d, (q31_t)0xb90ce3e6, (q31_t)0x6a7b8d1e, (q31_t)0xb8f7fa21, + (q31_t)0x6a6d98a4, (q31_t)0xb8e31319, (q31_t)0x6a5fa010, (q31_t)0xb8ce2ecf, (q31_t)0x6a51a361, (q31_t)0xb8b94d44, (q31_t)0x6a43a29a, (q31_t)0xb8a46e78, + (q31_t)0x6a359db9, (q31_t)0xb88f926d, (q31_t)0x6a2794c1, (q31_t)0xb87ab922, (q31_t)0x6a1987b0, (q31_t)0xb865e299, (q31_t)0x6a0b7689, (q31_t)0xb8510ed4, + (q31_t)0x69fd614a, (q31_t)0xb83c3dd1, (q31_t)0x69ef47f6, (q31_t)0xb8276f93, (q31_t)0x69e12a8c, (q31_t)0xb812a41a, (q31_t)0x69d3090e, (q31_t)0xb7fddb67, + (q31_t)0x69c4e37a, (q31_t)0xb7e9157a, (q31_t)0x69b6b9d3, (q31_t)0xb7d45255, (q31_t)0x69a88c19, (q31_t)0xb7bf91f8, (q31_t)0x699a5a4c, (q31_t)0xb7aad465, + (q31_t)0x698c246c, (q31_t)0xb796199b, (q31_t)0x697dea7b, (q31_t)0xb781619c, (q31_t)0x696fac78, (q31_t)0xb76cac69, (q31_t)0x69616a65, (q31_t)0xb757fa01, + (q31_t)0x69532442, (q31_t)0xb7434a67, (q31_t)0x6944da10, (q31_t)0xb72e9d9b, (q31_t)0x69368bce, (q31_t)0xb719f39e, (q31_t)0x6928397e, (q31_t)0xb7054c6f, + (q31_t)0x6919e320, (q31_t)0xb6f0a812, (q31_t)0x690b88b5, (q31_t)0xb6dc0685, (q31_t)0x68fd2a3d, (q31_t)0xb6c767ca, (q31_t)0x68eec7b9, (q31_t)0xb6b2cbe2, + (q31_t)0x68e06129, (q31_t)0xb69e32cd, (q31_t)0x68d1f68f, (q31_t)0xb6899c8d, (q31_t)0x68c387e9, (q31_t)0xb6750921, (q31_t)0x68b5153a, (q31_t)0xb660788c, + (q31_t)0x68a69e81, (q31_t)0xb64beacd, (q31_t)0x689823bf, (q31_t)0xb6375fe5, (q31_t)0x6889a4f6, (q31_t)0xb622d7d6, (q31_t)0x687b2224, (q31_t)0xb60e529f, + (q31_t)0x686c9b4b, (q31_t)0xb5f9d043, (q31_t)0x685e106c, (q31_t)0xb5e550c1, (q31_t)0x684f8186, (q31_t)0xb5d0d41a, (q31_t)0x6840ee9b, (q31_t)0xb5bc5a50, + (q31_t)0x683257ab, (q31_t)0xb5a7e362, (q31_t)0x6823bcb7, (q31_t)0xb5936f53, (q31_t)0x68151dbe, (q31_t)0xb57efe22, (q31_t)0x68067ac3, (q31_t)0xb56a8fd0, + (q31_t)0x67f7d3c5, (q31_t)0xb556245e, (q31_t)0x67e928c5, (q31_t)0xb541bbcd, (q31_t)0x67da79c3, (q31_t)0xb52d561e, (q31_t)0x67cbc6c0, (q31_t)0xb518f351, + (q31_t)0x67bd0fbd, (q31_t)0xb5049368, (q31_t)0x67ae54ba, (q31_t)0xb4f03663, (q31_t)0x679f95b7, (q31_t)0xb4dbdc42, (q31_t)0x6790d2b6, (q31_t)0xb4c78507, + (q31_t)0x67820bb7, (q31_t)0xb4b330b3, (q31_t)0x677340ba, (q31_t)0xb49edf45, (q31_t)0x676471c0, (q31_t)0xb48a90c0, (q31_t)0x67559eca, (q31_t)0xb4764523, + (q31_t)0x6746c7d8, (q31_t)0xb461fc70, (q31_t)0x6737ecea, (q31_t)0xb44db6a8, (q31_t)0x67290e02, (q31_t)0xb43973ca, (q31_t)0x671a2b20, (q31_t)0xb42533d8, + (q31_t)0x670b4444, (q31_t)0xb410f6d3, (q31_t)0x66fc596f, (q31_t)0xb3fcbcbb, (q31_t)0x66ed6aa1, (q31_t)0xb3e88592, (q31_t)0x66de77dc, (q31_t)0xb3d45157, + (q31_t)0x66cf8120, (q31_t)0xb3c0200c, (q31_t)0x66c0866d, (q31_t)0xb3abf1b2, (q31_t)0x66b187c3, (q31_t)0xb397c649, (q31_t)0x66a28524, (q31_t)0xb3839dd3, + (q31_t)0x66937e91, (q31_t)0xb36f784f, (q31_t)0x66847408, (q31_t)0xb35b55bf, (q31_t)0x6675658c, (q31_t)0xb3473623, (q31_t)0x6666531d, (q31_t)0xb333197c, + (q31_t)0x66573cbb, (q31_t)0xb31effcc, (q31_t)0x66482267, (q31_t)0xb30ae912, (q31_t)0x66390422, (q31_t)0xb2f6d550, (q31_t)0x6629e1ec, (q31_t)0xb2e2c486, + (q31_t)0x661abbc5, (q31_t)0xb2ceb6b5, (q31_t)0x660b91af, (q31_t)0xb2baabde, (q31_t)0x65fc63a9, (q31_t)0xb2a6a402, (q31_t)0x65ed31b5, (q31_t)0xb2929f21, + (q31_t)0x65ddfbd3, (q31_t)0xb27e9d3c, (q31_t)0x65cec204, (q31_t)0xb26a9e54, (q31_t)0x65bf8447, (q31_t)0xb256a26a, (q31_t)0x65b0429f, (q31_t)0xb242a97e, + (q31_t)0x65a0fd0b, (q31_t)0xb22eb392, (q31_t)0x6591b38c, (q31_t)0xb21ac0a6, (q31_t)0x65826622, (q31_t)0xb206d0ba, (q31_t)0x657314cf, (q31_t)0xb1f2e3d0, + (q31_t)0x6563bf92, (q31_t)0xb1def9e9, (q31_t)0x6554666d, (q31_t)0xb1cb1304, (q31_t)0x6545095f, (q31_t)0xb1b72f23, (q31_t)0x6535a86b, (q31_t)0xb1a34e47, + (q31_t)0x6526438f, (q31_t)0xb18f7071, (q31_t)0x6516dacd, (q31_t)0xb17b95a0, (q31_t)0x65076e25, (q31_t)0xb167bdd7, (q31_t)0x64f7fd98, (q31_t)0xb153e915, + (q31_t)0x64e88926, (q31_t)0xb140175b, (q31_t)0x64d910d1, (q31_t)0xb12c48ab, (q31_t)0x64c99498, (q31_t)0xb1187d05, (q31_t)0x64ba147d, (q31_t)0xb104b46a, + (q31_t)0x64aa907f, (q31_t)0xb0f0eeda, (q31_t)0x649b08a0, (q31_t)0xb0dd2c56, (q31_t)0x648b7ce0, (q31_t)0xb0c96ce0, (q31_t)0x647bed3f, (q31_t)0xb0b5b077, + (q31_t)0x646c59bf, (q31_t)0xb0a1f71d, (q31_t)0x645cc260, (q31_t)0xb08e40d2, (q31_t)0x644d2722, (q31_t)0xb07a8d97, (q31_t)0x643d8806, (q31_t)0xb066dd6d, + (q31_t)0x642de50d, (q31_t)0xb0533055, (q31_t)0x641e3e38, (q31_t)0xb03f864f, (q31_t)0x640e9386, (q31_t)0xb02bdf5c, (q31_t)0x63fee4f8, (q31_t)0xb0183b7d, + (q31_t)0x63ef3290, (q31_t)0xb0049ab3, (q31_t)0x63df7c4d, (q31_t)0xaff0fcfe, (q31_t)0x63cfc231, (q31_t)0xafdd625f, (q31_t)0x63c0043b, (q31_t)0xafc9cad7, + (q31_t)0x63b0426d, (q31_t)0xafb63667, (q31_t)0x63a07cc7, (q31_t)0xafa2a50f, (q31_t)0x6390b34a, (q31_t)0xaf8f16d1, (q31_t)0x6380e5f6, (q31_t)0xaf7b8bac, + (q31_t)0x637114cc, (q31_t)0xaf6803a2, (q31_t)0x63613fcd, (q31_t)0xaf547eb3, (q31_t)0x635166f9, (q31_t)0xaf40fce1, (q31_t)0x63418a50, (q31_t)0xaf2d7e2b, + (q31_t)0x6331a9d4, (q31_t)0xaf1a0293, (q31_t)0x6321c585, (q31_t)0xaf068a1a, (q31_t)0x6311dd64, (q31_t)0xaef314c0, (q31_t)0x6301f171, (q31_t)0xaedfa285, + (q31_t)0x62f201ac, (q31_t)0xaecc336c, (q31_t)0x62e20e17, (q31_t)0xaeb8c774, (q31_t)0x62d216b3, (q31_t)0xaea55e9e, (q31_t)0x62c21b7e, (q31_t)0xae91f8eb, + (q31_t)0x62b21c7b, (q31_t)0xae7e965b, (q31_t)0x62a219aa, (q31_t)0xae6b36f0, (q31_t)0x6292130c, (q31_t)0xae57daab, (q31_t)0x628208a1, (q31_t)0xae44818b, + (q31_t)0x6271fa69, (q31_t)0xae312b92, (q31_t)0x6261e866, (q31_t)0xae1dd8c0, (q31_t)0x6251d298, (q31_t)0xae0a8916, (q31_t)0x6241b8ff, (q31_t)0xadf73c96, + (q31_t)0x62319b9d, (q31_t)0xade3f33e, (q31_t)0x62217a72, (q31_t)0xadd0ad12, (q31_t)0x6211557e, (q31_t)0xadbd6a10, (q31_t)0x62012cc2, (q31_t)0xadaa2a3b, + (q31_t)0x61f1003f, (q31_t)0xad96ed92, (q31_t)0x61e0cff5, (q31_t)0xad83b416, (q31_t)0x61d09be5, (q31_t)0xad707dc8, (q31_t)0x61c06410, (q31_t)0xad5d4aaa, + (q31_t)0x61b02876, (q31_t)0xad4a1aba, (q31_t)0x619fe918, (q31_t)0xad36edfc, (q31_t)0x618fa5f7, (q31_t)0xad23c46e, (q31_t)0x617f5f12, (q31_t)0xad109e12, + (q31_t)0x616f146c, (q31_t)0xacfd7ae8, (q31_t)0x615ec603, (q31_t)0xacea5af2, (q31_t)0x614e73da, (q31_t)0xacd73e30, (q31_t)0x613e1df0, (q31_t)0xacc424a3, + (q31_t)0x612dc447, (q31_t)0xacb10e4b, (q31_t)0x611d66de, (q31_t)0xac9dfb29, (q31_t)0x610d05b7, (q31_t)0xac8aeb3e, (q31_t)0x60fca0d2, (q31_t)0xac77de8b, + (q31_t)0x60ec3830, (q31_t)0xac64d510, (q31_t)0x60dbcbd1, (q31_t)0xac51cecf, (q31_t)0x60cb5bb7, (q31_t)0xac3ecbc7, (q31_t)0x60bae7e1, (q31_t)0xac2bcbfa, + (q31_t)0x60aa7050, (q31_t)0xac18cf69, (q31_t)0x6099f505, (q31_t)0xac05d613, (q31_t)0x60897601, (q31_t)0xabf2dffb, (q31_t)0x6078f344, (q31_t)0xabdfed1f, + (q31_t)0x60686ccf, (q31_t)0xabccfd83, (q31_t)0x6057e2a2, (q31_t)0xabba1125, (q31_t)0x604754bf, (q31_t)0xaba72807, (q31_t)0x6036c325, (q31_t)0xab944229, + (q31_t)0x60262dd6, (q31_t)0xab815f8d, (q31_t)0x601594d1, (q31_t)0xab6e8032, (q31_t)0x6004f819, (q31_t)0xab5ba41a, (q31_t)0x5ff457ad, (q31_t)0xab48cb46, + (q31_t)0x5fe3b38d, (q31_t)0xab35f5b5, (q31_t)0x5fd30bbc, (q31_t)0xab23236a, (q31_t)0x5fc26038, (q31_t)0xab105464, (q31_t)0x5fb1b104, (q31_t)0xaafd88a4, + (q31_t)0x5fa0fe1f, (q31_t)0xaaeac02c, (q31_t)0x5f90478a, (q31_t)0xaad7fafb, (q31_t)0x5f7f8d46, (q31_t)0xaac53912, (q31_t)0x5f6ecf53, (q31_t)0xaab27a73, + (q31_t)0x5f5e0db3, (q31_t)0xaa9fbf1e, (q31_t)0x5f4d4865, (q31_t)0xaa8d0713, (q31_t)0x5f3c7f6b, (q31_t)0xaa7a5253, (q31_t)0x5f2bb2c5, (q31_t)0xaa67a0e0, + (q31_t)0x5f1ae274, (q31_t)0xaa54f2ba, (q31_t)0x5f0a0e77, (q31_t)0xaa4247e1, (q31_t)0x5ef936d1, (q31_t)0xaa2fa056, (q31_t)0x5ee85b82, (q31_t)0xaa1cfc1a, + (q31_t)0x5ed77c8a, (q31_t)0xaa0a5b2e, (q31_t)0x5ec699e9, (q31_t)0xa9f7bd92, (q31_t)0x5eb5b3a2, (q31_t)0xa9e52347, (q31_t)0x5ea4c9b3, (q31_t)0xa9d28c4e, + (q31_t)0x5e93dc1f, (q31_t)0xa9bff8a8, (q31_t)0x5e82eae5, (q31_t)0xa9ad6855, (q31_t)0x5e71f606, (q31_t)0xa99adb56, (q31_t)0x5e60fd84, (q31_t)0xa98851ac, + (q31_t)0x5e50015d, (q31_t)0xa975cb57, (q31_t)0x5e3f0194, (q31_t)0xa9634858, (q31_t)0x5e2dfe29, (q31_t)0xa950c8b0, (q31_t)0x5e1cf71c, (q31_t)0xa93e4c5f, + (q31_t)0x5e0bec6e, (q31_t)0xa92bd367, (q31_t)0x5dfade20, (q31_t)0xa9195dc7, (q31_t)0x5de9cc33, (q31_t)0xa906eb82, (q31_t)0x5dd8b6a7, (q31_t)0xa8f47c97, + (q31_t)0x5dc79d7c, (q31_t)0xa8e21106, (q31_t)0x5db680b4, (q31_t)0xa8cfa8d2, (q31_t)0x5da5604f, (q31_t)0xa8bd43fa, (q31_t)0x5d943c4e, (q31_t)0xa8aae280, + (q31_t)0x5d8314b1, (q31_t)0xa8988463, (q31_t)0x5d71e979, (q31_t)0xa88629a5, (q31_t)0x5d60baa7, (q31_t)0xa873d246, (q31_t)0x5d4f883b, (q31_t)0xa8617e48, + (q31_t)0x5d3e5237, (q31_t)0xa84f2daa, (q31_t)0x5d2d189a, (q31_t)0xa83ce06e, (q31_t)0x5d1bdb65, (q31_t)0xa82a9693, (q31_t)0x5d0a9a9a, (q31_t)0xa818501c, + (q31_t)0x5cf95638, (q31_t)0xa8060d08, (q31_t)0x5ce80e41, (q31_t)0xa7f3cd59, (q31_t)0x5cd6c2b5, (q31_t)0xa7e1910f, (q31_t)0x5cc57394, (q31_t)0xa7cf582a, + (q31_t)0x5cb420e0, (q31_t)0xa7bd22ac, (q31_t)0x5ca2ca99, (q31_t)0xa7aaf094, (q31_t)0x5c9170bf, (q31_t)0xa798c1e5, (q31_t)0x5c801354, (q31_t)0xa786969e, + (q31_t)0x5c6eb258, (q31_t)0xa7746ec0, (q31_t)0x5c5d4dcc, (q31_t)0xa7624a4d, (q31_t)0x5c4be5b0, (q31_t)0xa7502943, (q31_t)0x5c3a7a05, (q31_t)0xa73e0ba5, + (q31_t)0x5c290acc, (q31_t)0xa72bf174, (q31_t)0x5c179806, (q31_t)0xa719daae, (q31_t)0x5c0621b2, (q31_t)0xa707c757, (q31_t)0x5bf4a7d2, (q31_t)0xa6f5b76d, + (q31_t)0x5be32a67, (q31_t)0xa6e3aaf2, (q31_t)0x5bd1a971, (q31_t)0xa6d1a1e7, (q31_t)0x5bc024f0, (q31_t)0xa6bf9c4b, (q31_t)0x5bae9ce7, (q31_t)0xa6ad9a21, + (q31_t)0x5b9d1154, (q31_t)0xa69b9b68, (q31_t)0x5b8b8239, (q31_t)0xa689a022, (q31_t)0x5b79ef96, (q31_t)0xa677a84e, (q31_t)0x5b68596d, (q31_t)0xa665b3ee, + (q31_t)0x5b56bfbd, (q31_t)0xa653c303, (q31_t)0x5b452288, (q31_t)0xa641d58c, (q31_t)0x5b3381ce, (q31_t)0xa62feb8b, (q31_t)0x5b21dd90, (q31_t)0xa61e0501, + (q31_t)0x5b1035cf, (q31_t)0xa60c21ee, (q31_t)0x5afe8a8b, (q31_t)0xa5fa4252, (q31_t)0x5aecdbc5, (q31_t)0xa5e8662f, (q31_t)0x5adb297d, (q31_t)0xa5d68d85, + (q31_t)0x5ac973b5, (q31_t)0xa5c4b855, (q31_t)0x5ab7ba6c, (q31_t)0xa5b2e6a0, (q31_t)0x5aa5fda5, (q31_t)0xa5a11866, (q31_t)0x5a943d5e, (q31_t)0xa58f4da8, + (q31_t)0x5a82799a, (q31_t)0xa57d8666, (q31_t)0x5a70b258, (q31_t)0xa56bc2a2, (q31_t)0x5a5ee79a, (q31_t)0xa55a025b, (q31_t)0x5a4d1960, (q31_t)0xa5484594, + (q31_t)0x5a3b47ab, (q31_t)0xa5368c4b, (q31_t)0x5a29727b, (q31_t)0xa524d683, (q31_t)0x5a1799d1, (q31_t)0xa513243b, (q31_t)0x5a05bdae, (q31_t)0xa5017575, + (q31_t)0x59f3de12, (q31_t)0xa4efca31, (q31_t)0x59e1faff, (q31_t)0xa4de2270, (q31_t)0x59d01475, (q31_t)0xa4cc7e32, (q31_t)0x59be2a74, (q31_t)0xa4badd78, + (q31_t)0x59ac3cfd, (q31_t)0xa4a94043, (q31_t)0x599a4c12, (q31_t)0xa497a693, (q31_t)0x598857b2, (q31_t)0xa486106a, (q31_t)0x59765fde, (q31_t)0xa4747dc7, + (q31_t)0x59646498, (q31_t)0xa462eeac, (q31_t)0x595265df, (q31_t)0xa4516319, (q31_t)0x594063b5, (q31_t)0xa43fdb10, (q31_t)0x592e5e19, (q31_t)0xa42e568f, + (q31_t)0x591c550e, (q31_t)0xa41cd599, (q31_t)0x590a4893, (q31_t)0xa40b582e, (q31_t)0x58f838a9, (q31_t)0xa3f9de4e, (q31_t)0x58e62552, (q31_t)0xa3e867fa, + (q31_t)0x58d40e8c, (q31_t)0xa3d6f534, (q31_t)0x58c1f45b, (q31_t)0xa3c585fb, (q31_t)0x58afd6bd, (q31_t)0xa3b41a50, (q31_t)0x589db5b3, (q31_t)0xa3a2b234, + (q31_t)0x588b9140, (q31_t)0xa3914da8, (q31_t)0x58796962, (q31_t)0xa37fecac, (q31_t)0x58673e1b, (q31_t)0xa36e8f41, (q31_t)0x58550f6c, (q31_t)0xa35d3567, + (q31_t)0x5842dd54, (q31_t)0xa34bdf20, (q31_t)0x5830a7d6, (q31_t)0xa33a8c6c, (q31_t)0x581e6ef1, (q31_t)0xa3293d4b, (q31_t)0x580c32a7, (q31_t)0xa317f1bf, + (q31_t)0x57f9f2f8, (q31_t)0xa306a9c8, (q31_t)0x57e7afe4, (q31_t)0xa2f56566, (q31_t)0x57d5696d, (q31_t)0xa2e4249b, (q31_t)0x57c31f92, (q31_t)0xa2d2e766, + (q31_t)0x57b0d256, (q31_t)0xa2c1adc9, (q31_t)0x579e81b8, (q31_t)0xa2b077c5, (q31_t)0x578c2dba, (q31_t)0xa29f4559, (q31_t)0x5779d65b, (q31_t)0xa28e1687, + (q31_t)0x57677b9d, (q31_t)0xa27ceb4f, (q31_t)0x57551d80, (q31_t)0xa26bc3b2, (q31_t)0x5742bc06, (q31_t)0xa25a9fb1, (q31_t)0x5730572e, (q31_t)0xa2497f4c, + (q31_t)0x571deefa, (q31_t)0xa2386284, (q31_t)0x570b8369, (q31_t)0xa2274959, (q31_t)0x56f9147e, (q31_t)0xa21633cd, (q31_t)0x56e6a239, (q31_t)0xa20521e0, + (q31_t)0x56d42c99, (q31_t)0xa1f41392, (q31_t)0x56c1b3a1, (q31_t)0xa1e308e4, (q31_t)0x56af3750, (q31_t)0xa1d201d7, (q31_t)0x569cb7a8, (q31_t)0xa1c0fe6c, + (q31_t)0x568a34a9, (q31_t)0xa1affea3, (q31_t)0x5677ae54, (q31_t)0xa19f027c, (q31_t)0x566524aa, (q31_t)0xa18e09fa, (q31_t)0x565297ab, (q31_t)0xa17d151b, + (q31_t)0x56400758, (q31_t)0xa16c23e1, (q31_t)0x562d73b2, (q31_t)0xa15b364d, (q31_t)0x561adcb9, (q31_t)0xa14a4c5e, (q31_t)0x5608426e, (q31_t)0xa1396617, + (q31_t)0x55f5a4d2, (q31_t)0xa1288376, (q31_t)0x55e303e6, (q31_t)0xa117a47e, (q31_t)0x55d05faa, (q31_t)0xa106c92f, (q31_t)0x55bdb81f, (q31_t)0xa0f5f189, + (q31_t)0x55ab0d46, (q31_t)0xa0e51d8c, (q31_t)0x55985f20, (q31_t)0xa0d44d3b, (q31_t)0x5585adad, (q31_t)0xa0c38095, (q31_t)0x5572f8ed, (q31_t)0xa0b2b79b, + (q31_t)0x556040e2, (q31_t)0xa0a1f24d, (q31_t)0x554d858d, (q31_t)0xa09130ad, (q31_t)0x553ac6ee, (q31_t)0xa08072ba, (q31_t)0x55280505, (q31_t)0xa06fb876, + (q31_t)0x55153fd4, (q31_t)0xa05f01e1, (q31_t)0x5502775c, (q31_t)0xa04e4efc, (q31_t)0x54efab9c, (q31_t)0xa03d9fc8, (q31_t)0x54dcdc96, (q31_t)0xa02cf444, + (q31_t)0x54ca0a4b, (q31_t)0xa01c4c73, (q31_t)0x54b734ba, (q31_t)0xa00ba853, (q31_t)0x54a45be6, (q31_t)0x9ffb07e7, (q31_t)0x54917fce, (q31_t)0x9fea6b2f, + (q31_t)0x547ea073, (q31_t)0x9fd9d22a, (q31_t)0x546bbdd7, (q31_t)0x9fc93cdb, (q31_t)0x5458d7f9, (q31_t)0x9fb8ab41, (q31_t)0x5445eedb, (q31_t)0x9fa81d5e, + (q31_t)0x5433027d, (q31_t)0x9f979331, (q31_t)0x542012e1, (q31_t)0x9f870cbc, (q31_t)0x540d2005, (q31_t)0x9f7689ff, (q31_t)0x53fa29ed, (q31_t)0x9f660afb, + (q31_t)0x53e73097, (q31_t)0x9f558fb0, (q31_t)0x53d43406, (q31_t)0x9f45181f, (q31_t)0x53c13439, (q31_t)0x9f34a449, (q31_t)0x53ae3131, (q31_t)0x9f24342f, + (q31_t)0x539b2af0, (q31_t)0x9f13c7d0, (q31_t)0x53882175, (q31_t)0x9f035f2e, (q31_t)0x537514c2, (q31_t)0x9ef2fa49, (q31_t)0x536204d7, (q31_t)0x9ee29922, + (q31_t)0x534ef1b5, (q31_t)0x9ed23bb9, (q31_t)0x533bdb5d, (q31_t)0x9ec1e210, (q31_t)0x5328c1d0, (q31_t)0x9eb18c26, (q31_t)0x5315a50e, (q31_t)0x9ea139fd, + (q31_t)0x53028518, (q31_t)0x9e90eb94, (q31_t)0x52ef61ee, (q31_t)0x9e80a0ee, (q31_t)0x52dc3b92, (q31_t)0x9e705a09, (q31_t)0x52c91204, (q31_t)0x9e6016e8, + (q31_t)0x52b5e546, (q31_t)0x9e4fd78a, (q31_t)0x52a2b556, (q31_t)0x9e3f9bf0, (q31_t)0x528f8238, (q31_t)0x9e2f641b, (q31_t)0x527c4bea, (q31_t)0x9e1f300b, + (q31_t)0x5269126e, (q31_t)0x9e0effc1, (q31_t)0x5255d5c5, (q31_t)0x9dfed33e, (q31_t)0x524295f0, (q31_t)0x9deeaa82, (q31_t)0x522f52ee, (q31_t)0x9dde858e, + (q31_t)0x521c0cc2, (q31_t)0x9dce6463, (q31_t)0x5208c36a, (q31_t)0x9dbe4701, (q31_t)0x51f576ea, (q31_t)0x9dae2d68, (q31_t)0x51e22740, (q31_t)0x9d9e179a, + (q31_t)0x51ced46e, (q31_t)0x9d8e0597, (q31_t)0x51bb7e75, (q31_t)0x9d7df75f, (q31_t)0x51a82555, (q31_t)0x9d6decf4, (q31_t)0x5194c910, (q31_t)0x9d5de656, + (q31_t)0x518169a5, (q31_t)0x9d4de385, (q31_t)0x516e0715, (q31_t)0x9d3de482, (q31_t)0x515aa162, (q31_t)0x9d2de94d, (q31_t)0x5147388c, (q31_t)0x9d1df1e9, + (q31_t)0x5133cc94, (q31_t)0x9d0dfe54, (q31_t)0x51205d7b, (q31_t)0x9cfe0e8f, (q31_t)0x510ceb40, (q31_t)0x9cee229c, (q31_t)0x50f975e6, (q31_t)0x9cde3a7b, + (q31_t)0x50e5fd6d, (q31_t)0x9cce562c, (q31_t)0x50d281d5, (q31_t)0x9cbe75b0, (q31_t)0x50bf031f, (q31_t)0x9cae9907, (q31_t)0x50ab814d, (q31_t)0x9c9ec033, + (q31_t)0x5097fc5e, (q31_t)0x9c8eeb34, (q31_t)0x50847454, (q31_t)0x9c7f1a0a, (q31_t)0x5070e92f, (q31_t)0x9c6f4cb6, (q31_t)0x505d5af1, (q31_t)0x9c5f8339, + (q31_t)0x5049c999, (q31_t)0x9c4fbd93, (q31_t)0x50363529, (q31_t)0x9c3ffbc5, (q31_t)0x50229da1, (q31_t)0x9c303dcf, (q31_t)0x500f0302, (q31_t)0x9c2083b3, + (q31_t)0x4ffb654d, (q31_t)0x9c10cd70, (q31_t)0x4fe7c483, (q31_t)0x9c011b08, (q31_t)0x4fd420a4, (q31_t)0x9bf16c7a, (q31_t)0x4fc079b1, (q31_t)0x9be1c1c8, + (q31_t)0x4faccfab, (q31_t)0x9bd21af3, (q31_t)0x4f992293, (q31_t)0x9bc277fa, (q31_t)0x4f857269, (q31_t)0x9bb2d8de, (q31_t)0x4f71bf2e, (q31_t)0x9ba33da0, + (q31_t)0x4f5e08e3, (q31_t)0x9b93a641, (q31_t)0x4f4a4f89, (q31_t)0x9b8412c1, (q31_t)0x4f369320, (q31_t)0x9b748320, (q31_t)0x4f22d3aa, (q31_t)0x9b64f760, + (q31_t)0x4f0f1126, (q31_t)0x9b556f81, (q31_t)0x4efb4b96, (q31_t)0x9b45eb83, (q31_t)0x4ee782fb, (q31_t)0x9b366b68, (q31_t)0x4ed3b755, (q31_t)0x9b26ef2f, + (q31_t)0x4ebfe8a5, (q31_t)0x9b1776da, (q31_t)0x4eac16eb, (q31_t)0x9b080268, (q31_t)0x4e984229, (q31_t)0x9af891db, (q31_t)0x4e846a60, (q31_t)0x9ae92533, + (q31_t)0x4e708f8f, (q31_t)0x9ad9bc71, (q31_t)0x4e5cb1b9, (q31_t)0x9aca5795, (q31_t)0x4e48d0dd, (q31_t)0x9abaf6a1, (q31_t)0x4e34ecfc, (q31_t)0x9aab9993, + (q31_t)0x4e210617, (q31_t)0x9a9c406e, (q31_t)0x4e0d1c30, (q31_t)0x9a8ceb31, (q31_t)0x4df92f46, (q31_t)0x9a7d99de, (q31_t)0x4de53f5a, (q31_t)0x9a6e4c74, + (q31_t)0x4dd14c6e, (q31_t)0x9a5f02f5, (q31_t)0x4dbd5682, (q31_t)0x9a4fbd61, (q31_t)0x4da95d96, (q31_t)0x9a407bb9, (q31_t)0x4d9561ac, (q31_t)0x9a313dfc, + (q31_t)0x4d8162c4, (q31_t)0x9a22042d, (q31_t)0x4d6d60df, (q31_t)0x9a12ce4b, (q31_t)0x4d595bfe, (q31_t)0x9a039c57, (q31_t)0x4d455422, (q31_t)0x99f46e51, + (q31_t)0x4d31494b, (q31_t)0x99e5443b, (q31_t)0x4d1d3b7a, (q31_t)0x99d61e14, (q31_t)0x4d092ab0, (q31_t)0x99c6fbde, (q31_t)0x4cf516ee, (q31_t)0x99b7dd99, + (q31_t)0x4ce10034, (q31_t)0x99a8c345, (q31_t)0x4ccce684, (q31_t)0x9999ace3, (q31_t)0x4cb8c9dd, (q31_t)0x998a9a74, (q31_t)0x4ca4aa41, (q31_t)0x997b8bf8, + (q31_t)0x4c9087b1, (q31_t)0x996c816f, (q31_t)0x4c7c622d, (q31_t)0x995d7adc, (q31_t)0x4c6839b7, (q31_t)0x994e783d, (q31_t)0x4c540e4e, (q31_t)0x993f7993, + (q31_t)0x4c3fdff4, (q31_t)0x99307ee0, (q31_t)0x4c2baea9, (q31_t)0x99218824, (q31_t)0x4c177a6e, (q31_t)0x9912955f, (q31_t)0x4c034345, (q31_t)0x9903a691, + (q31_t)0x4bef092d, (q31_t)0x98f4bbbc, (q31_t)0x4bdacc28, (q31_t)0x98e5d4e0, (q31_t)0x4bc68c36, (q31_t)0x98d6f1fe, (q31_t)0x4bb24958, (q31_t)0x98c81316, + (q31_t)0x4b9e0390, (q31_t)0x98b93828, (q31_t)0x4b89badd, (q31_t)0x98aa6136, (q31_t)0x4b756f40, (q31_t)0x989b8e40, (q31_t)0x4b6120bb, (q31_t)0x988cbf46, + (q31_t)0x4b4ccf4d, (q31_t)0x987df449, (q31_t)0x4b387af9, (q31_t)0x986f2d4a, (q31_t)0x4b2423be, (q31_t)0x98606a49, (q31_t)0x4b0fc99d, (q31_t)0x9851ab46, + (q31_t)0x4afb6c98, (q31_t)0x9842f043, (q31_t)0x4ae70caf, (q31_t)0x98343940, (q31_t)0x4ad2a9e2, (q31_t)0x9825863d, (q31_t)0x4abe4433, (q31_t)0x9816d73b, + (q31_t)0x4aa9dba2, (q31_t)0x98082c3b, (q31_t)0x4a957030, (q31_t)0x97f9853d, (q31_t)0x4a8101de, (q31_t)0x97eae242, (q31_t)0x4a6c90ad, (q31_t)0x97dc4349, + (q31_t)0x4a581c9e, (q31_t)0x97cda855, (q31_t)0x4a43a5b0, (q31_t)0x97bf1165, (q31_t)0x4a2f2be6, (q31_t)0x97b07e7a, (q31_t)0x4a1aaf3f, (q31_t)0x97a1ef94, + (q31_t)0x4a062fbd, (q31_t)0x979364b5, (q31_t)0x49f1ad61, (q31_t)0x9784dddc, (q31_t)0x49dd282a, (q31_t)0x97765b0a, (q31_t)0x49c8a01b, (q31_t)0x9767dc41, + (q31_t)0x49b41533, (q31_t)0x9759617f, (q31_t)0x499f8774, (q31_t)0x974aeac6, (q31_t)0x498af6df, (q31_t)0x973c7817, (q31_t)0x49766373, (q31_t)0x972e0971, + (q31_t)0x4961cd33, (q31_t)0x971f9ed7, (q31_t)0x494d341e, (q31_t)0x97113847, (q31_t)0x49389836, (q31_t)0x9702d5c3, (q31_t)0x4923f97b, (q31_t)0x96f4774b, + (q31_t)0x490f57ee, (q31_t)0x96e61ce0, (q31_t)0x48fab391, (q31_t)0x96d7c682, (q31_t)0x48e60c62, (q31_t)0x96c97432, (q31_t)0x48d16265, (q31_t)0x96bb25f0, + (q31_t)0x48bcb599, (q31_t)0x96acdbbe, (q31_t)0x48a805ff, (q31_t)0x969e959b, (q31_t)0x48935397, (q31_t)0x96905388, (q31_t)0x487e9e64, (q31_t)0x96821585, + (q31_t)0x4869e665, (q31_t)0x9673db94, (q31_t)0x48552b9b, (q31_t)0x9665a5b4, (q31_t)0x48406e08, (q31_t)0x965773e7, (q31_t)0x482badab, (q31_t)0x9649462d, + (q31_t)0x4816ea86, (q31_t)0x963b1c86, (q31_t)0x48022499, (q31_t)0x962cf6f2, (q31_t)0x47ed5be6, (q31_t)0x961ed574, (q31_t)0x47d8906d, (q31_t)0x9610b80a, + (q31_t)0x47c3c22f, (q31_t)0x96029eb6, (q31_t)0x47aef12c, (q31_t)0x95f48977, (q31_t)0x479a1d67, (q31_t)0x95e67850, (q31_t)0x478546de, (q31_t)0x95d86b3f, + (q31_t)0x47706d93, (q31_t)0x95ca6247, (q31_t)0x475b9188, (q31_t)0x95bc5d66, (q31_t)0x4746b2bc, (q31_t)0x95ae5c9f, (q31_t)0x4731d131, (q31_t)0x95a05ff0, + (q31_t)0x471cece7, (q31_t)0x9592675c, (q31_t)0x470805df, (q31_t)0x958472e2, (q31_t)0x46f31c1a, (q31_t)0x95768283, (q31_t)0x46de2f99, (q31_t)0x9568963f, + (q31_t)0x46c9405c, (q31_t)0x955aae17, (q31_t)0x46b44e65, (q31_t)0x954cca0c, (q31_t)0x469f59b4, (q31_t)0x953eea1e, (q31_t)0x468a624a, (q31_t)0x95310e4e, + (q31_t)0x46756828, (q31_t)0x9523369c, (q31_t)0x46606b4e, (q31_t)0x95156308, (q31_t)0x464b6bbe, (q31_t)0x95079394, (q31_t)0x46366978, (q31_t)0x94f9c83f, + (q31_t)0x4621647d, (q31_t)0x94ec010b, (q31_t)0x460c5cce, (q31_t)0x94de3df8, (q31_t)0x45f7526b, (q31_t)0x94d07f05, (q31_t)0x45e24556, (q31_t)0x94c2c435, + (q31_t)0x45cd358f, (q31_t)0x94b50d87, (q31_t)0x45b82318, (q31_t)0x94a75afd, (q31_t)0x45a30df0, (q31_t)0x9499ac95, (q31_t)0x458df619, (q31_t)0x948c0252, + (q31_t)0x4578db93, (q31_t)0x947e5c33, (q31_t)0x4563be60, (q31_t)0x9470ba39, (q31_t)0x454e9e80, (q31_t)0x94631c65, (q31_t)0x45397bf4, (q31_t)0x945582b7, + (q31_t)0x452456bd, (q31_t)0x9447ed2f, (q31_t)0x450f2edb, (q31_t)0x943a5bcf, (q31_t)0x44fa0450, (q31_t)0x942cce96, (q31_t)0x44e4d71c, (q31_t)0x941f4585, + (q31_t)0x44cfa740, (q31_t)0x9411c09e, (q31_t)0x44ba74bd, (q31_t)0x94043fdf, (q31_t)0x44a53f93, (q31_t)0x93f6c34a, (q31_t)0x449007c4, (q31_t)0x93e94adf, + (q31_t)0x447acd50, (q31_t)0x93dbd6a0, (q31_t)0x44659039, (q31_t)0x93ce668b, (q31_t)0x4450507e, (q31_t)0x93c0faa3, (q31_t)0x443b0e21, (q31_t)0x93b392e6, + (q31_t)0x4425c923, (q31_t)0x93a62f57, (q31_t)0x44108184, (q31_t)0x9398cff5, (q31_t)0x43fb3746, (q31_t)0x938b74c1, (q31_t)0x43e5ea68, (q31_t)0x937e1dbb, + (q31_t)0x43d09aed, (q31_t)0x9370cae4, (q31_t)0x43bb48d4, (q31_t)0x93637c3d, (q31_t)0x43a5f41e, (q31_t)0x935631c5, (q31_t)0x43909ccd, (q31_t)0x9348eb7e, + (q31_t)0x437b42e1, (q31_t)0x933ba968, (q31_t)0x4365e65b, (q31_t)0x932e6b84, (q31_t)0x4350873c, (q31_t)0x932131d1, (q31_t)0x433b2585, (q31_t)0x9313fc51, + (q31_t)0x4325c135, (q31_t)0x9306cb04, (q31_t)0x43105a50, (q31_t)0x92f99deb, (q31_t)0x42faf0d4, (q31_t)0x92ec7505, (q31_t)0x42e584c3, (q31_t)0x92df5054, + (q31_t)0x42d0161e, (q31_t)0x92d22fd9, (q31_t)0x42baa4e6, (q31_t)0x92c51392, (q31_t)0x42a5311b, (q31_t)0x92b7fb82, (q31_t)0x428fbabe, (q31_t)0x92aae7a8, + (q31_t)0x427a41d0, (q31_t)0x929dd806, (q31_t)0x4264c653, (q31_t)0x9290cc9b, (q31_t)0x424f4845, (q31_t)0x9283c568, (q31_t)0x4239c7aa, (q31_t)0x9276c26d, + (q31_t)0x42244481, (q31_t)0x9269c3ac, (q31_t)0x420ebecb, (q31_t)0x925cc924, (q31_t)0x41f93689, (q31_t)0x924fd2d7, (q31_t)0x41e3abbc, (q31_t)0x9242e0c4, + (q31_t)0x41ce1e65, (q31_t)0x9235f2ec, (q31_t)0x41b88e84, (q31_t)0x9229094f, (q31_t)0x41a2fc1a, (q31_t)0x921c23ef, (q31_t)0x418d6729, (q31_t)0x920f42cb, + (q31_t)0x4177cfb1, (q31_t)0x920265e4, (q31_t)0x416235b2, (q31_t)0x91f58d3b, (q31_t)0x414c992f, (q31_t)0x91e8b8d0, (q31_t)0x4136fa27, (q31_t)0x91dbe8a4, + (q31_t)0x4121589b, (q31_t)0x91cf1cb6, (q31_t)0x410bb48c, (q31_t)0x91c25508, (q31_t)0x40f60dfb, (q31_t)0x91b5919a, (q31_t)0x40e064ea, (q31_t)0x91a8d26d, + (q31_t)0x40cab958, (q31_t)0x919c1781, (q31_t)0x40b50b46, (q31_t)0x918f60d6, (q31_t)0x409f5ab6, (q31_t)0x9182ae6d, (q31_t)0x4089a7a8, (q31_t)0x91760047, + (q31_t)0x4073f21d, (q31_t)0x91695663, (q31_t)0x405e3a16, (q31_t)0x915cb0c3, (q31_t)0x40487f94, (q31_t)0x91500f67, (q31_t)0x4032c297, (q31_t)0x91437250, + (q31_t)0x401d0321, (q31_t)0x9136d97d, (q31_t)0x40074132, (q31_t)0x912a44f0, (q31_t)0x3ff17cca, (q31_t)0x911db4a9, (q31_t)0x3fdbb5ec, (q31_t)0x911128a8, + (q31_t)0x3fc5ec98, (q31_t)0x9104a0ee, (q31_t)0x3fb020ce, (q31_t)0x90f81d7b, (q31_t)0x3f9a5290, (q31_t)0x90eb9e50, (q31_t)0x3f8481dd, (q31_t)0x90df236e, + (q31_t)0x3f6eaeb8, (q31_t)0x90d2acd4, (q31_t)0x3f58d921, (q31_t)0x90c63a83, (q31_t)0x3f430119, (q31_t)0x90b9cc7d, (q31_t)0x3f2d26a0, (q31_t)0x90ad62c0, + (q31_t)0x3f1749b8, (q31_t)0x90a0fd4e, (q31_t)0x3f016a61, (q31_t)0x90949c28, (q31_t)0x3eeb889c, (q31_t)0x90883f4d, (q31_t)0x3ed5a46b, (q31_t)0x907be6be, + (q31_t)0x3ebfbdcd, (q31_t)0x906f927c, (q31_t)0x3ea9d4c3, (q31_t)0x90634287, (q31_t)0x3e93e950, (q31_t)0x9056f6df, (q31_t)0x3e7dfb73, (q31_t)0x904aaf86, + (q31_t)0x3e680b2c, (q31_t)0x903e6c7b, (q31_t)0x3e52187f, (q31_t)0x90322dbf, (q31_t)0x3e3c2369, (q31_t)0x9025f352, (q31_t)0x3e262bee, (q31_t)0x9019bd36, + (q31_t)0x3e10320d, (q31_t)0x900d8b69, (q31_t)0x3dfa35c8, (q31_t)0x90015dee, (q31_t)0x3de4371f, (q31_t)0x8ff534c4, (q31_t)0x3dce3614, (q31_t)0x8fe90fec, + (q31_t)0x3db832a6, (q31_t)0x8fdcef66, (q31_t)0x3da22cd7, (q31_t)0x8fd0d333, (q31_t)0x3d8c24a8, (q31_t)0x8fc4bb53, (q31_t)0x3d761a19, (q31_t)0x8fb8a7c7, + (q31_t)0x3d600d2c, (q31_t)0x8fac988f, (q31_t)0x3d49fde1, (q31_t)0x8fa08dab, (q31_t)0x3d33ec39, (q31_t)0x8f94871d, (q31_t)0x3d1dd835, (q31_t)0x8f8884e4, + (q31_t)0x3d07c1d6, (q31_t)0x8f7c8701, (q31_t)0x3cf1a91c, (q31_t)0x8f708d75, (q31_t)0x3cdb8e09, (q31_t)0x8f649840, (q31_t)0x3cc5709e, (q31_t)0x8f58a761, + (q31_t)0x3caf50da, (q31_t)0x8f4cbadb, (q31_t)0x3c992ec0, (q31_t)0x8f40d2ad, (q31_t)0x3c830a50, (q31_t)0x8f34eed8, (q31_t)0x3c6ce38a, (q31_t)0x8f290f5c, + (q31_t)0x3c56ba70, (q31_t)0x8f1d343a, (q31_t)0x3c408f03, (q31_t)0x8f115d72, (q31_t)0x3c2a6142, (q31_t)0x8f058b04, (q31_t)0x3c143130, (q31_t)0x8ef9bcf2, + (q31_t)0x3bfdfecd, (q31_t)0x8eedf33b, (q31_t)0x3be7ca1a, (q31_t)0x8ee22de0, (q31_t)0x3bd19318, (q31_t)0x8ed66ce1, (q31_t)0x3bbb59c7, (q31_t)0x8ecab040, + (q31_t)0x3ba51e29, (q31_t)0x8ebef7fb, (q31_t)0x3b8ee03e, (q31_t)0x8eb34415, (q31_t)0x3b78a007, (q31_t)0x8ea7948c, (q31_t)0x3b625d86, (q31_t)0x8e9be963, + (q31_t)0x3b4c18ba, (q31_t)0x8e904298, (q31_t)0x3b35d1a5, (q31_t)0x8e84a02d, (q31_t)0x3b1f8848, (q31_t)0x8e790222, (q31_t)0x3b093ca3, (q31_t)0x8e6d6877, + (q31_t)0x3af2eeb7, (q31_t)0x8e61d32e, (q31_t)0x3adc9e86, (q31_t)0x8e564246, (q31_t)0x3ac64c0f, (q31_t)0x8e4ab5bf, (q31_t)0x3aaff755, (q31_t)0x8e3f2d9b, + (q31_t)0x3a99a057, (q31_t)0x8e33a9da, (q31_t)0x3a834717, (q31_t)0x8e282a7b, (q31_t)0x3a6ceb96, (q31_t)0x8e1caf80, (q31_t)0x3a568dd4, (q31_t)0x8e1138ea, + (q31_t)0x3a402dd2, (q31_t)0x8e05c6b7, (q31_t)0x3a29cb91, (q31_t)0x8dfa58ea, (q31_t)0x3a136712, (q31_t)0x8deeef82, (q31_t)0x39fd0056, (q31_t)0x8de38a80, + (q31_t)0x39e6975e, (q31_t)0x8dd829e4, (q31_t)0x39d02c2a, (q31_t)0x8dcccdaf, (q31_t)0x39b9bebc, (q31_t)0x8dc175e0, (q31_t)0x39a34f13, (q31_t)0x8db6227a, + (q31_t)0x398cdd32, (q31_t)0x8daad37b, (q31_t)0x39766919, (q31_t)0x8d9f88e5, (q31_t)0x395ff2c9, (q31_t)0x8d9442b8, (q31_t)0x39497a43, (q31_t)0x8d8900f3, + (q31_t)0x3932ff87, (q31_t)0x8d7dc399, (q31_t)0x391c8297, (q31_t)0x8d728aa9, (q31_t)0x39060373, (q31_t)0x8d675623, (q31_t)0x38ef821c, (q31_t)0x8d5c2609, + (q31_t)0x38d8fe93, (q31_t)0x8d50fa59, (q31_t)0x38c278d9, (q31_t)0x8d45d316, (q31_t)0x38abf0ef, (q31_t)0x8d3ab03f, (q31_t)0x389566d6, (q31_t)0x8d2f91d5, + (q31_t)0x387eda8e, (q31_t)0x8d2477d8, (q31_t)0x38684c19, (q31_t)0x8d196249, (q31_t)0x3851bb77, (q31_t)0x8d0e5127, (q31_t)0x383b28a9, (q31_t)0x8d034474, + (q31_t)0x382493b0, (q31_t)0x8cf83c30, (q31_t)0x380dfc8d, (q31_t)0x8ced385b, (q31_t)0x37f76341, (q31_t)0x8ce238f6, (q31_t)0x37e0c7cc, (q31_t)0x8cd73e01, + (q31_t)0x37ca2a30, (q31_t)0x8ccc477d, (q31_t)0x37b38a6d, (q31_t)0x8cc1556a, (q31_t)0x379ce885, (q31_t)0x8cb667c8, (q31_t)0x37864477, (q31_t)0x8cab7e98, + (q31_t)0x376f9e46, (q31_t)0x8ca099da, (q31_t)0x3758f5f2, (q31_t)0x8c95b98f, (q31_t)0x37424b7b, (q31_t)0x8c8addb7, (q31_t)0x372b9ee3, (q31_t)0x8c800652, + (q31_t)0x3714f02a, (q31_t)0x8c753362, (q31_t)0x36fe3f52, (q31_t)0x8c6a64e5, (q31_t)0x36e78c5b, (q31_t)0x8c5f9ade, (q31_t)0x36d0d746, (q31_t)0x8c54d54c, + (q31_t)0x36ba2014, (q31_t)0x8c4a142f, (q31_t)0x36a366c6, (q31_t)0x8c3f5788, (q31_t)0x368cab5c, (q31_t)0x8c349f58, (q31_t)0x3675edd9, (q31_t)0x8c29eb9f, + (q31_t)0x365f2e3b, (q31_t)0x8c1f3c5d, (q31_t)0x36486c86, (q31_t)0x8c149192, (q31_t)0x3631a8b8, (q31_t)0x8c09eb40, (q31_t)0x361ae2d3, (q31_t)0x8bff4966, + (q31_t)0x36041ad9, (q31_t)0x8bf4ac05, (q31_t)0x35ed50c9, (q31_t)0x8bea131e, (q31_t)0x35d684a6, (q31_t)0x8bdf7eb0, (q31_t)0x35bfb66e, (q31_t)0x8bd4eebc, + (q31_t)0x35a8e625, (q31_t)0x8bca6343, (q31_t)0x359213c9, (q31_t)0x8bbfdc44, (q31_t)0x357b3f5d, (q31_t)0x8bb559c1, (q31_t)0x356468e2, (q31_t)0x8baadbba, + (q31_t)0x354d9057, (q31_t)0x8ba0622f, (q31_t)0x3536b5be, (q31_t)0x8b95ed21, (q31_t)0x351fd918, (q31_t)0x8b8b7c8f, (q31_t)0x3508fa66, (q31_t)0x8b81107b, + (q31_t)0x34f219a8, (q31_t)0x8b76a8e4, (q31_t)0x34db36df, (q31_t)0x8b6c45cc, (q31_t)0x34c4520d, (q31_t)0x8b61e733, (q31_t)0x34ad6b32, (q31_t)0x8b578d18, + (q31_t)0x34968250, (q31_t)0x8b4d377c, (q31_t)0x347f9766, (q31_t)0x8b42e661, (q31_t)0x3468aa76, (q31_t)0x8b3899c6, (q31_t)0x3451bb81, (q31_t)0x8b2e51ab, + (q31_t)0x343aca87, (q31_t)0x8b240e11, (q31_t)0x3423d78a, (q31_t)0x8b19cef8, (q31_t)0x340ce28b, (q31_t)0x8b0f9462, (q31_t)0x33f5eb89, (q31_t)0x8b055e4d, + (q31_t)0x33def287, (q31_t)0x8afb2cbb, (q31_t)0x33c7f785, (q31_t)0x8af0ffac, (q31_t)0x33b0fa84, (q31_t)0x8ae6d720, (q31_t)0x3399fb85, (q31_t)0x8adcb318, + (q31_t)0x3382fa88, (q31_t)0x8ad29394, (q31_t)0x336bf78f, (q31_t)0x8ac87894, (q31_t)0x3354f29b, (q31_t)0x8abe6219, (q31_t)0x333debab, (q31_t)0x8ab45024, + (q31_t)0x3326e2c3, (q31_t)0x8aaa42b4, (q31_t)0x330fd7e1, (q31_t)0x8aa039cb, (q31_t)0x32f8cb07, (q31_t)0x8a963567, (q31_t)0x32e1bc36, (q31_t)0x8a8c358b, + (q31_t)0x32caab6f, (q31_t)0x8a823a36, (q31_t)0x32b398b3, (q31_t)0x8a784368, (q31_t)0x329c8402, (q31_t)0x8a6e5123, (q31_t)0x32856d5e, (q31_t)0x8a646365, + (q31_t)0x326e54c7, (q31_t)0x8a5a7a31, (q31_t)0x32573a3f, (q31_t)0x8a509585, (q31_t)0x32401dc6, (q31_t)0x8a46b564, (q31_t)0x3228ff5c, (q31_t)0x8a3cd9cc, + (q31_t)0x3211df04, (q31_t)0x8a3302be, (q31_t)0x31fabcbd, (q31_t)0x8a29303b, (q31_t)0x31e39889, (q31_t)0x8a1f6243, (q31_t)0x31cc7269, (q31_t)0x8a1598d6, + (q31_t)0x31b54a5e, (q31_t)0x8a0bd3f5, (q31_t)0x319e2067, (q31_t)0x8a0213a0, (q31_t)0x3186f487, (q31_t)0x89f857d8, (q31_t)0x316fc6be, (q31_t)0x89eea09d, + (q31_t)0x3158970e, (q31_t)0x89e4edef, (q31_t)0x31416576, (q31_t)0x89db3fcf, (q31_t)0x312a31f8, (q31_t)0x89d1963c, (q31_t)0x3112fc95, (q31_t)0x89c7f138, + (q31_t)0x30fbc54d, (q31_t)0x89be50c3, (q31_t)0x30e48c22, (q31_t)0x89b4b4dd, (q31_t)0x30cd5115, (q31_t)0x89ab1d87, (q31_t)0x30b61426, (q31_t)0x89a18ac0, + (q31_t)0x309ed556, (q31_t)0x8997fc8a, (q31_t)0x308794a6, (q31_t)0x898e72e4, (q31_t)0x30705217, (q31_t)0x8984edcf, (q31_t)0x30590dab, (q31_t)0x897b6d4c, + (q31_t)0x3041c761, (q31_t)0x8971f15a, (q31_t)0x302a7f3a, (q31_t)0x896879fb, (q31_t)0x30133539, (q31_t)0x895f072e, (q31_t)0x2ffbe95d, (q31_t)0x895598f3, + (q31_t)0x2fe49ba7, (q31_t)0x894c2f4c, (q31_t)0x2fcd4c19, (q31_t)0x8942ca39, (q31_t)0x2fb5fab2, (q31_t)0x893969b9, (q31_t)0x2f9ea775, (q31_t)0x89300dce, + (q31_t)0x2f875262, (q31_t)0x8926b677, (q31_t)0x2f6ffb7a, (q31_t)0x891d63b5, (q31_t)0x2f58a2be, (q31_t)0x89141589, (q31_t)0x2f41482e, (q31_t)0x890acbf2, + (q31_t)0x2f29ebcc, (q31_t)0x890186f2, (q31_t)0x2f128d99, (q31_t)0x88f84687, (q31_t)0x2efb2d95, (q31_t)0x88ef0ab4, (q31_t)0x2ee3cbc1, (q31_t)0x88e5d378, + (q31_t)0x2ecc681e, (q31_t)0x88dca0d3, (q31_t)0x2eb502ae, (q31_t)0x88d372c6, (q31_t)0x2e9d9b70, (q31_t)0x88ca4951, (q31_t)0x2e863267, (q31_t)0x88c12475, + (q31_t)0x2e6ec792, (q31_t)0x88b80432, (q31_t)0x2e575af3, (q31_t)0x88aee888, (q31_t)0x2e3fec8b, (q31_t)0x88a5d177, (q31_t)0x2e287c5a, (q31_t)0x889cbf01, + (q31_t)0x2e110a62, (q31_t)0x8893b125, (q31_t)0x2df996a3, (q31_t)0x888aa7e3, (q31_t)0x2de2211e, (q31_t)0x8881a33d, (q31_t)0x2dcaa9d5, (q31_t)0x8878a332, + (q31_t)0x2db330c7, (q31_t)0x886fa7c2, (q31_t)0x2d9bb5f6, (q31_t)0x8866b0ef, (q31_t)0x2d843964, (q31_t)0x885dbeb8, (q31_t)0x2d6cbb10, (q31_t)0x8854d11e, + (q31_t)0x2d553afc, (q31_t)0x884be821, (q31_t)0x2d3db928, (q31_t)0x884303c1, (q31_t)0x2d263596, (q31_t)0x883a23ff, (q31_t)0x2d0eb046, (q31_t)0x883148db, + (q31_t)0x2cf72939, (q31_t)0x88287256, (q31_t)0x2cdfa071, (q31_t)0x881fa06f, (q31_t)0x2cc815ee, (q31_t)0x8816d327, (q31_t)0x2cb089b1, (q31_t)0x880e0a7f, + (q31_t)0x2c98fbba, (q31_t)0x88054677, (q31_t)0x2c816c0c, (q31_t)0x87fc870f, (q31_t)0x2c69daa6, (q31_t)0x87f3cc48, (q31_t)0x2c52478a, (q31_t)0x87eb1621, + (q31_t)0x2c3ab2b9, (q31_t)0x87e2649b, (q31_t)0x2c231c33, (q31_t)0x87d9b7b7, (q31_t)0x2c0b83fa, (q31_t)0x87d10f75, (q31_t)0x2bf3ea0d, (q31_t)0x87c86bd5, + (q31_t)0x2bdc4e6f, (q31_t)0x87bfccd7, (q31_t)0x2bc4b120, (q31_t)0x87b7327d, (q31_t)0x2bad1221, (q31_t)0x87ae9cc5, (q31_t)0x2b957173, (q31_t)0x87a60bb1, + (q31_t)0x2b7dcf17, (q31_t)0x879d7f41, (q31_t)0x2b662b0e, (q31_t)0x8794f774, (q31_t)0x2b4e8558, (q31_t)0x878c744d, (q31_t)0x2b36ddf7, (q31_t)0x8783f5ca, + (q31_t)0x2b1f34eb, (q31_t)0x877b7bec, (q31_t)0x2b078a36, (q31_t)0x877306b4, (q31_t)0x2aefddd8, (q31_t)0x876a9621, (q31_t)0x2ad82fd2, (q31_t)0x87622a35, + (q31_t)0x2ac08026, (q31_t)0x8759c2ef, (q31_t)0x2aa8ced3, (q31_t)0x87516050, (q31_t)0x2a911bdc, (q31_t)0x87490258, (q31_t)0x2a796740, (q31_t)0x8740a907, + (q31_t)0x2a61b101, (q31_t)0x8738545e, (q31_t)0x2a49f920, (q31_t)0x8730045d, (q31_t)0x2a323f9e, (q31_t)0x8727b905, (q31_t)0x2a1a847b, (q31_t)0x871f7255, + (q31_t)0x2a02c7b8, (q31_t)0x8717304e, (q31_t)0x29eb0957, (q31_t)0x870ef2f1, (q31_t)0x29d34958, (q31_t)0x8706ba3d, (q31_t)0x29bb87bc, (q31_t)0x86fe8633, + (q31_t)0x29a3c485, (q31_t)0x86f656d3, (q31_t)0x298bffb2, (q31_t)0x86ee2c1e, (q31_t)0x29743946, (q31_t)0x86e60614, (q31_t)0x295c7140, (q31_t)0x86dde4b5, + (q31_t)0x2944a7a2, (q31_t)0x86d5c802, (q31_t)0x292cdc6d, (q31_t)0x86cdaffa, (q31_t)0x29150fa1, (q31_t)0x86c59c9f, (q31_t)0x28fd4140, (q31_t)0x86bd8df0, + (q31_t)0x28e5714b, (q31_t)0x86b583ee, (q31_t)0x28cd9fc1, (q31_t)0x86ad7e99, (q31_t)0x28b5cca5, (q31_t)0x86a57df2, (q31_t)0x289df7f8, (q31_t)0x869d81f8, + (q31_t)0x288621b9, (q31_t)0x86958aac, (q31_t)0x286e49ea, (q31_t)0x868d980e, (q31_t)0x2856708d, (q31_t)0x8685aa20, (q31_t)0x283e95a1, (q31_t)0x867dc0e0, + (q31_t)0x2826b928, (q31_t)0x8675dc4f, (q31_t)0x280edb23, (q31_t)0x866dfc6e, (q31_t)0x27f6fb92, (q31_t)0x8666213c, (q31_t)0x27df1a77, (q31_t)0x865e4abb, + (q31_t)0x27c737d3, (q31_t)0x865678eb, (q31_t)0x27af53a6, (q31_t)0x864eabcb, (q31_t)0x27976df1, (q31_t)0x8646e35c, (q31_t)0x277f86b5, (q31_t)0x863f1f9e, + (q31_t)0x27679df4, (q31_t)0x86376092, (q31_t)0x274fb3ae, (q31_t)0x862fa638, (q31_t)0x2737c7e3, (q31_t)0x8627f091, (q31_t)0x271fda96, (q31_t)0x86203f9c, + (q31_t)0x2707ebc7, (q31_t)0x86189359, (q31_t)0x26effb76, (q31_t)0x8610ebca, (q31_t)0x26d809a5, (q31_t)0x860948ef, (q31_t)0x26c01655, (q31_t)0x8601aac7, + (q31_t)0x26a82186, (q31_t)0x85fa1153, (q31_t)0x26902b39, (q31_t)0x85f27c93, (q31_t)0x26783370, (q31_t)0x85eaec88, (q31_t)0x26603a2c, (q31_t)0x85e36132, + (q31_t)0x26483f6c, (q31_t)0x85dbda91, (q31_t)0x26304333, (q31_t)0x85d458a6, (q31_t)0x26184581, (q31_t)0x85ccdb70, (q31_t)0x26004657, (q31_t)0x85c562f1, + (q31_t)0x25e845b6, (q31_t)0x85bdef28, (q31_t)0x25d0439f, (q31_t)0x85b68015, (q31_t)0x25b84012, (q31_t)0x85af15b9, (q31_t)0x25a03b11, (q31_t)0x85a7b015, + (q31_t)0x2588349d, (q31_t)0x85a04f28, (q31_t)0x25702cb7, (q31_t)0x8598f2f3, (q31_t)0x2558235f, (q31_t)0x85919b76, (q31_t)0x25401896, (q31_t)0x858a48b1, + (q31_t)0x25280c5e, (q31_t)0x8582faa5, (q31_t)0x250ffeb7, (q31_t)0x857bb152, (q31_t)0x24f7efa2, (q31_t)0x85746cb8, (q31_t)0x24dfdf20, (q31_t)0x856d2cd7, + (q31_t)0x24c7cd33, (q31_t)0x8565f1b0, (q31_t)0x24afb9da, (q31_t)0x855ebb44, (q31_t)0x2497a517, (q31_t)0x85578991, (q31_t)0x247f8eec, (q31_t)0x85505c99, + (q31_t)0x24677758, (q31_t)0x8549345c, (q31_t)0x244f5e5c, (q31_t)0x854210db, (q31_t)0x243743fa, (q31_t)0x853af214, (q31_t)0x241f2833, (q31_t)0x8533d809, + (q31_t)0x24070b08, (q31_t)0x852cc2bb, (q31_t)0x23eeec78, (q31_t)0x8525b228, (q31_t)0x23d6cc87, (q31_t)0x851ea652, (q31_t)0x23beab33, (q31_t)0x85179f39, + (q31_t)0x23a6887f, (q31_t)0x85109cdd, (q31_t)0x238e646a, (q31_t)0x85099f3e, (q31_t)0x23763ef7, (q31_t)0x8502a65c, (q31_t)0x235e1826, (q31_t)0x84fbb239, + (q31_t)0x2345eff8, (q31_t)0x84f4c2d4, (q31_t)0x232dc66d, (q31_t)0x84edd82d, (q31_t)0x23159b88, (q31_t)0x84e6f244, (q31_t)0x22fd6f48, (q31_t)0x84e0111b, + (q31_t)0x22e541af, (q31_t)0x84d934b1, (q31_t)0x22cd12bd, (q31_t)0x84d25d06, (q31_t)0x22b4e274, (q31_t)0x84cb8a1b, (q31_t)0x229cb0d5, (q31_t)0x84c4bbf0, + (q31_t)0x22847de0, (q31_t)0x84bdf286, (q31_t)0x226c4996, (q31_t)0x84b72ddb, (q31_t)0x225413f8, (q31_t)0x84b06df2, (q31_t)0x223bdd08, (q31_t)0x84a9b2ca, + (q31_t)0x2223a4c5, (q31_t)0x84a2fc62, (q31_t)0x220b6b32, (q31_t)0x849c4abd, (q31_t)0x21f3304f, (q31_t)0x84959dd9, (q31_t)0x21daf41d, (q31_t)0x848ef5b7, + (q31_t)0x21c2b69c, (q31_t)0x84885258, (q31_t)0x21aa77cf, (q31_t)0x8481b3bb, (q31_t)0x219237b5, (q31_t)0x847b19e1, (q31_t)0x2179f64f, (q31_t)0x847484ca, + (q31_t)0x2161b3a0, (q31_t)0x846df477, (q31_t)0x21496fa7, (q31_t)0x846768e7, (q31_t)0x21312a65, (q31_t)0x8460e21a, (q31_t)0x2118e3dc, (q31_t)0x845a6012, + (q31_t)0x21009c0c, (q31_t)0x8453e2cf, (q31_t)0x20e852f6, (q31_t)0x844d6a50, (q31_t)0x20d0089c, (q31_t)0x8446f695, (q31_t)0x20b7bcfe, (q31_t)0x844087a0, + (q31_t)0x209f701c, (q31_t)0x843a1d70, (q31_t)0x208721f9, (q31_t)0x8433b806, (q31_t)0x206ed295, (q31_t)0x842d5762, (q31_t)0x205681f1, (q31_t)0x8426fb84, + (q31_t)0x203e300d, (q31_t)0x8420a46c, (q31_t)0x2025dcec, (q31_t)0x841a521a, (q31_t)0x200d888d, (q31_t)0x84140490, (q31_t)0x1ff532f2, (q31_t)0x840dbbcc, + (q31_t)0x1fdcdc1b, (q31_t)0x840777d0, (q31_t)0x1fc4840a, (q31_t)0x8401389b, (q31_t)0x1fac2abf, (q31_t)0x83fafe2e, (q31_t)0x1f93d03c, (q31_t)0x83f4c889, + (q31_t)0x1f7b7481, (q31_t)0x83ee97ad, (q31_t)0x1f63178f, (q31_t)0x83e86b99, (q31_t)0x1f4ab968, (q31_t)0x83e2444d, (q31_t)0x1f325a0b, (q31_t)0x83dc21cb, + (q31_t)0x1f19f97b, (q31_t)0x83d60412, (q31_t)0x1f0197b8, (q31_t)0x83cfeb22, (q31_t)0x1ee934c3, (q31_t)0x83c9d6fc, (q31_t)0x1ed0d09d, (q31_t)0x83c3c7a0, + (q31_t)0x1eb86b46, (q31_t)0x83bdbd0e, (q31_t)0x1ea004c1, (q31_t)0x83b7b746, (q31_t)0x1e879d0d, (q31_t)0x83b1b649, (q31_t)0x1e6f342c, (q31_t)0x83abba17, + (q31_t)0x1e56ca1e, (q31_t)0x83a5c2b0, (q31_t)0x1e3e5ee5, (q31_t)0x839fd014, (q31_t)0x1e25f282, (q31_t)0x8399e244, (q31_t)0x1e0d84f5, (q31_t)0x8393f940, + (q31_t)0x1df5163f, (q31_t)0x838e1507, (q31_t)0x1ddca662, (q31_t)0x8388359b, (q31_t)0x1dc4355e, (q31_t)0x83825afb, (q31_t)0x1dabc334, (q31_t)0x837c8528, + (q31_t)0x1d934fe5, (q31_t)0x8376b422, (q31_t)0x1d7adb73, (q31_t)0x8370e7e9, (q31_t)0x1d6265dd, (q31_t)0x836b207d, (q31_t)0x1d49ef26, (q31_t)0x83655ddf, + (q31_t)0x1d31774d, (q31_t)0x835fa00f, (q31_t)0x1d18fe54, (q31_t)0x8359e70d, (q31_t)0x1d00843d, (q31_t)0x835432d8, (q31_t)0x1ce80906, (q31_t)0x834e8373, + (q31_t)0x1ccf8cb3, (q31_t)0x8348d8dc, (q31_t)0x1cb70f43, (q31_t)0x83433314, (q31_t)0x1c9e90b8, (q31_t)0x833d921b, (q31_t)0x1c861113, (q31_t)0x8337f5f1, + (q31_t)0x1c6d9053, (q31_t)0x83325e97, (q31_t)0x1c550e7c, (q31_t)0x832ccc0d, (q31_t)0x1c3c8b8c, (q31_t)0x83273e52, (q31_t)0x1c240786, (q31_t)0x8321b568, + (q31_t)0x1c0b826a, (q31_t)0x831c314e, (q31_t)0x1bf2fc3a, (q31_t)0x8316b205, (q31_t)0x1bda74f6, (q31_t)0x8311378d, (q31_t)0x1bc1ec9e, (q31_t)0x830bc1e6, + (q31_t)0x1ba96335, (q31_t)0x83065110, (q31_t)0x1b90d8bb, (q31_t)0x8300e50b, (q31_t)0x1b784d30, (q31_t)0x82fb7dd8, (q31_t)0x1b5fc097, (q31_t)0x82f61b77, + (q31_t)0x1b4732ef, (q31_t)0x82f0bde8, (q31_t)0x1b2ea43a, (q31_t)0x82eb652b, (q31_t)0x1b161479, (q31_t)0x82e61141, (q31_t)0x1afd83ad, (q31_t)0x82e0c22a, + (q31_t)0x1ae4f1d6, (q31_t)0x82db77e5, (q31_t)0x1acc5ef6, (q31_t)0x82d63274, (q31_t)0x1ab3cb0d, (q31_t)0x82d0f1d5, (q31_t)0x1a9b361d, (q31_t)0x82cbb60b, + (q31_t)0x1a82a026, (q31_t)0x82c67f14, (q31_t)0x1a6a0929, (q31_t)0x82c14cf1, (q31_t)0x1a517128, (q31_t)0x82bc1fa2, (q31_t)0x1a38d823, (q31_t)0x82b6f727, + (q31_t)0x1a203e1b, (q31_t)0x82b1d381, (q31_t)0x1a07a311, (q31_t)0x82acb4b0, (q31_t)0x19ef0707, (q31_t)0x82a79ab3, (q31_t)0x19d669fc, (q31_t)0x82a2858c, + (q31_t)0x19bdcbf3, (q31_t)0x829d753a, (q31_t)0x19a52ceb, (q31_t)0x829869be, (q31_t)0x198c8ce7, (q31_t)0x82936317, (q31_t)0x1973ebe6, (q31_t)0x828e6146, + (q31_t)0x195b49ea, (q31_t)0x8289644b, (q31_t)0x1942a6f3, (q31_t)0x82846c26, (q31_t)0x192a0304, (q31_t)0x827f78d8, (q31_t)0x19115e1c, (q31_t)0x827a8a61, + (q31_t)0x18f8b83c, (q31_t)0x8275a0c0, (q31_t)0x18e01167, (q31_t)0x8270bbf7, (q31_t)0x18c7699b, (q31_t)0x826bdc04, (q31_t)0x18aec0db, (q31_t)0x826700e9, + (q31_t)0x18961728, (q31_t)0x82622aa6, (q31_t)0x187d6c82, (q31_t)0x825d593a, (q31_t)0x1864c0ea, (q31_t)0x82588ca7, (q31_t)0x184c1461, (q31_t)0x8253c4eb, + (q31_t)0x183366e9, (q31_t)0x824f0208, (q31_t)0x181ab881, (q31_t)0x824a43fe, (q31_t)0x1802092c, (q31_t)0x82458acc, (q31_t)0x17e958ea, (q31_t)0x8240d673, + (q31_t)0x17d0a7bc, (q31_t)0x823c26f3, (q31_t)0x17b7f5a3, (q31_t)0x82377c4c, (q31_t)0x179f429f, (q31_t)0x8232d67f, (q31_t)0x17868eb3, (q31_t)0x822e358b, + (q31_t)0x176dd9de, (q31_t)0x82299971, (q31_t)0x17552422, (q31_t)0x82250232, (q31_t)0x173c6d80, (q31_t)0x82206fcc, (q31_t)0x1723b5f9, (q31_t)0x821be240, + (q31_t)0x170afd8d, (q31_t)0x82175990, (q31_t)0x16f2443e, (q31_t)0x8212d5b9, (q31_t)0x16d98a0c, (q31_t)0x820e56be, (q31_t)0x16c0cef9, (q31_t)0x8209dc9e, + (q31_t)0x16a81305, (q31_t)0x82056758, (q31_t)0x168f5632, (q31_t)0x8200f6ef, (q31_t)0x1676987f, (q31_t)0x81fc8b60, (q31_t)0x165dd9f0, (q31_t)0x81f824ae, + (q31_t)0x16451a83, (q31_t)0x81f3c2d7, (q31_t)0x162c5a3b, (q31_t)0x81ef65dc, (q31_t)0x16139918, (q31_t)0x81eb0dbe, (q31_t)0x15fad71b, (q31_t)0x81e6ba7c, + (q31_t)0x15e21445, (q31_t)0x81e26c16, (q31_t)0x15c95097, (q31_t)0x81de228d, (q31_t)0x15b08c12, (q31_t)0x81d9dde1, (q31_t)0x1597c6b7, (q31_t)0x81d59e13, + (q31_t)0x157f0086, (q31_t)0x81d16321, (q31_t)0x15663982, (q31_t)0x81cd2d0c, (q31_t)0x154d71aa, (q31_t)0x81c8fbd6, (q31_t)0x1534a901, (q31_t)0x81c4cf7d, + (q31_t)0x151bdf86, (q31_t)0x81c0a801, (q31_t)0x1503153a, (q31_t)0x81bc8564, (q31_t)0x14ea4a1f, (q31_t)0x81b867a5, (q31_t)0x14d17e36, (q31_t)0x81b44ec4, + (q31_t)0x14b8b17f, (q31_t)0x81b03ac2, (q31_t)0x149fe3fc, (q31_t)0x81ac2b9e, (q31_t)0x148715ae, (q31_t)0x81a82159, (q31_t)0x146e4694, (q31_t)0x81a41bf4, + (q31_t)0x145576b1, (q31_t)0x81a01b6d, (q31_t)0x143ca605, (q31_t)0x819c1fc5, (q31_t)0x1423d492, (q31_t)0x819828fd, (q31_t)0x140b0258, (q31_t)0x81943715, + (q31_t)0x13f22f58, (q31_t)0x81904a0c, (q31_t)0x13d95b93, (q31_t)0x818c61e3, (q31_t)0x13c0870a, (q31_t)0x81887e9a, (q31_t)0x13a7b1bf, (q31_t)0x8184a032, + (q31_t)0x138edbb1, (q31_t)0x8180c6a9, (q31_t)0x137604e2, (q31_t)0x817cf201, (q31_t)0x135d2d53, (q31_t)0x8179223a, (q31_t)0x13445505, (q31_t)0x81755754, + (q31_t)0x132b7bf9, (q31_t)0x8171914e, (q31_t)0x1312a230, (q31_t)0x816dd02a, (q31_t)0x12f9c7aa, (q31_t)0x816a13e6, (q31_t)0x12e0ec6a, (q31_t)0x81665c84, + (q31_t)0x12c8106f, (q31_t)0x8162aa04, (q31_t)0x12af33ba, (q31_t)0x815efc65, (q31_t)0x1296564d, (q31_t)0x815b53a8, (q31_t)0x127d7829, (q31_t)0x8157afcd, + (q31_t)0x1264994e, (q31_t)0x815410d4, (q31_t)0x124bb9be, (q31_t)0x815076bd, (q31_t)0x1232d979, (q31_t)0x814ce188, (q31_t)0x1219f880, (q31_t)0x81495136, + (q31_t)0x120116d5, (q31_t)0x8145c5c7, (q31_t)0x11e83478, (q31_t)0x81423f3a, (q31_t)0x11cf516a, (q31_t)0x813ebd90, (q31_t)0x11b66dad, (q31_t)0x813b40ca, + (q31_t)0x119d8941, (q31_t)0x8137c8e6, (q31_t)0x1184a427, (q31_t)0x813455e6, (q31_t)0x116bbe60, (q31_t)0x8130e7c9, (q31_t)0x1152d7ed, (q31_t)0x812d7e8f, + (q31_t)0x1139f0cf, (q31_t)0x812a1a3a, (q31_t)0x11210907, (q31_t)0x8126bac8, (q31_t)0x11082096, (q31_t)0x8123603a, (q31_t)0x10ef377d, (q31_t)0x81200a90, + (q31_t)0x10d64dbd, (q31_t)0x811cb9ca, (q31_t)0x10bd6356, (q31_t)0x81196de9, (q31_t)0x10a4784b, (q31_t)0x811626ec, (q31_t)0x108b8c9b, (q31_t)0x8112e4d4, + (q31_t)0x1072a048, (q31_t)0x810fa7a0, (q31_t)0x1059b352, (q31_t)0x810c6f52, (q31_t)0x1040c5bb, (q31_t)0x81093be8, (q31_t)0x1027d784, (q31_t)0x81060d63, + (q31_t)0x100ee8ad, (q31_t)0x8102e3c4, (q31_t)0xff5f938, (q31_t)0x80ffbf0a, (q31_t)0xfdd0926, (q31_t)0x80fc9f35, (q31_t)0xfc41876, (q31_t)0x80f98446, + (q31_t)0xfab272b, (q31_t)0x80f66e3c, (q31_t)0xf923546, (q31_t)0x80f35d19, (q31_t)0xf7942c7, (q31_t)0x80f050db, (q31_t)0xf604faf, (q31_t)0x80ed4984, + (q31_t)0xf475bff, (q31_t)0x80ea4712, (q31_t)0xf2e67b8, (q31_t)0x80e74987, (q31_t)0xf1572dc, (q31_t)0x80e450e2, (q31_t)0xefc7d6b, (q31_t)0x80e15d24, + (q31_t)0xee38766, (q31_t)0x80de6e4c, (q31_t)0xeca90ce, (q31_t)0x80db845b, (q31_t)0xeb199a4, (q31_t)0x80d89f51, (q31_t)0xe98a1e9, (q31_t)0x80d5bf2e, + (q31_t)0xe7fa99e, (q31_t)0x80d2e3f2, (q31_t)0xe66b0c3, (q31_t)0x80d00d9d, (q31_t)0xe4db75b, (q31_t)0x80cd3c2f, (q31_t)0xe34bd66, (q31_t)0x80ca6fa9, + (q31_t)0xe1bc2e4, (q31_t)0x80c7a80a, (q31_t)0xe02c7d7, (q31_t)0x80c4e553, (q31_t)0xde9cc40, (q31_t)0x80c22784, (q31_t)0xdd0d01f, (q31_t)0x80bf6e9c, + (q31_t)0xdb7d376, (q31_t)0x80bcba9d, (q31_t)0xd9ed646, (q31_t)0x80ba0b85, (q31_t)0xd85d88f, (q31_t)0x80b76156, (q31_t)0xd6cda53, (q31_t)0x80b4bc0e, + (q31_t)0xd53db92, (q31_t)0x80b21baf, (q31_t)0xd3adc4e, (q31_t)0x80af8039, (q31_t)0xd21dc87, (q31_t)0x80ace9ab, (q31_t)0xd08dc3f, (q31_t)0x80aa5806, + (q31_t)0xcefdb76, (q31_t)0x80a7cb49, (q31_t)0xcd6da2d, (q31_t)0x80a54376, (q31_t)0xcbdd865, (q31_t)0x80a2c08b, (q31_t)0xca4d620, (q31_t)0x80a04289, + (q31_t)0xc8bd35e, (q31_t)0x809dc971, (q31_t)0xc72d020, (q31_t)0x809b5541, (q31_t)0xc59cc68, (q31_t)0x8098e5fb, (q31_t)0xc40c835, (q31_t)0x80967b9f, + (q31_t)0xc27c389, (q31_t)0x8094162c, (q31_t)0xc0ebe66, (q31_t)0x8091b5a2, (q31_t)0xbf5b8cb, (q31_t)0x808f5a02, (q31_t)0xbdcb2bb, (q31_t)0x808d034c, + (q31_t)0xbc3ac35, (q31_t)0x808ab180, (q31_t)0xbaaa53b, (q31_t)0x8088649e, (q31_t)0xb919dcf, (q31_t)0x80861ca6, (q31_t)0xb7895f0, (q31_t)0x8083d998, + (q31_t)0xb5f8d9f, (q31_t)0x80819b74, (q31_t)0xb4684df, (q31_t)0x807f623b, (q31_t)0xb2d7baf, (q31_t)0x807d2dec, (q31_t)0xb147211, (q31_t)0x807afe87, + (q31_t)0xafb6805, (q31_t)0x8078d40d, (q31_t)0xae25d8d, (q31_t)0x8076ae7e, (q31_t)0xac952aa, (q31_t)0x80748dd9, (q31_t)0xab0475c, (q31_t)0x8072721f, + (q31_t)0xa973ba5, (q31_t)0x80705b50, (q31_t)0xa7e2f85, (q31_t)0x806e496c, (q31_t)0xa6522fe, (q31_t)0x806c3c74, (q31_t)0xa4c1610, (q31_t)0x806a3466, + (q31_t)0xa3308bd, (q31_t)0x80683143, (q31_t)0xa19fb04, (q31_t)0x8066330c, (q31_t)0xa00ece8, (q31_t)0x806439c0, (q31_t)0x9e7de6a, (q31_t)0x80624560, + (q31_t)0x9cecf89, (q31_t)0x806055eb, (q31_t)0x9b5c048, (q31_t)0x805e6b62, (q31_t)0x99cb0a7, (q31_t)0x805c85c4, (q31_t)0x983a0a7, (q31_t)0x805aa512, + (q31_t)0x96a9049, (q31_t)0x8058c94c, (q31_t)0x9517f8f, (q31_t)0x8056f272, (q31_t)0x9386e78, (q31_t)0x80552084, (q31_t)0x91f5d06, (q31_t)0x80535381, + (q31_t)0x9064b3a, (q31_t)0x80518b6b, (q31_t)0x8ed3916, (q31_t)0x804fc841, (q31_t)0x8d42699, (q31_t)0x804e0a04, (q31_t)0x8bb13c5, (q31_t)0x804c50b2, + (q31_t)0x8a2009a, (q31_t)0x804a9c4d, (q31_t)0x888ed1b, (q31_t)0x8048ecd5, (q31_t)0x86fd947, (q31_t)0x80474248, (q31_t)0x856c520, (q31_t)0x80459ca9, + (q31_t)0x83db0a7, (q31_t)0x8043fbf6, (q31_t)0x8249bdd, (q31_t)0x80426030, (q31_t)0x80b86c2, (q31_t)0x8040c956, (q31_t)0x7f27157, (q31_t)0x803f376a, + (q31_t)0x7d95b9e, (q31_t)0x803daa6a, (q31_t)0x7c04598, (q31_t)0x803c2257, (q31_t)0x7a72f45, (q31_t)0x803a9f31, (q31_t)0x78e18a7, (q31_t)0x803920f8, + (q31_t)0x77501be, (q31_t)0x8037a7ac, (q31_t)0x75bea8c, (q31_t)0x8036334e, (q31_t)0x742d311, (q31_t)0x8034c3dd, (q31_t)0x729bb4e, (q31_t)0x80335959, + (q31_t)0x710a345, (q31_t)0x8031f3c2, (q31_t)0x6f78af6, (q31_t)0x80309318, (q31_t)0x6de7262, (q31_t)0x802f375d, (q31_t)0x6c5598a, (q31_t)0x802de08e, + (q31_t)0x6ac406f, (q31_t)0x802c8ead, (q31_t)0x6932713, (q31_t)0x802b41ba, (q31_t)0x67a0d76, (q31_t)0x8029f9b4, (q31_t)0x660f398, (q31_t)0x8028b69c, + (q31_t)0x647d97c, (q31_t)0x80277872, (q31_t)0x62ebf22, (q31_t)0x80263f36, (q31_t)0x615a48b, (q31_t)0x80250ae7, (q31_t)0x5fc89b8, (q31_t)0x8023db86, + (q31_t)0x5e36ea9, (q31_t)0x8022b114, (q31_t)0x5ca5361, (q31_t)0x80218b8f, (q31_t)0x5b137df, (q31_t)0x80206af8, (q31_t)0x5981c26, (q31_t)0x801f4f4f, + (q31_t)0x57f0035, (q31_t)0x801e3895, (q31_t)0x565e40d, (q31_t)0x801d26c8, (q31_t)0x54cc7b1, (q31_t)0x801c19ea, (q31_t)0x533ab20, (q31_t)0x801b11fa, + (q31_t)0x51a8e5c, (q31_t)0x801a0ef8, (q31_t)0x5017165, (q31_t)0x801910e4, (q31_t)0x4e8543e, (q31_t)0x801817bf, (q31_t)0x4cf36e5, (q31_t)0x80172388, + (q31_t)0x4b6195d, (q31_t)0x80163440, (q31_t)0x49cfba7, (q31_t)0x801549e6, (q31_t)0x483ddc3, (q31_t)0x8014647b, (q31_t)0x46abfb3, (q31_t)0x801383fe, + (q31_t)0x451a177, (q31_t)0x8012a86f, (q31_t)0x4388310, (q31_t)0x8011d1d0, (q31_t)0x41f6480, (q31_t)0x8011001f, (q31_t)0x40645c7, (q31_t)0x8010335c, + (q31_t)0x3ed26e6, (q31_t)0x800f6b88, (q31_t)0x3d407df, (q31_t)0x800ea8a3, (q31_t)0x3bae8b2, (q31_t)0x800deaad, (q31_t)0x3a1c960, (q31_t)0x800d31a5, + (q31_t)0x388a9ea, (q31_t)0x800c7d8c, (q31_t)0x36f8a51, (q31_t)0x800bce63, (q31_t)0x3566a96, (q31_t)0x800b2427, (q31_t)0x33d4abb, (q31_t)0x800a7edb, + (q31_t)0x3242abf, (q31_t)0x8009de7e, (q31_t)0x30b0aa4, (q31_t)0x80094310, (q31_t)0x2f1ea6c, (q31_t)0x8008ac90, (q31_t)0x2d8ca16, (q31_t)0x80081b00, + (q31_t)0x2bfa9a4, (q31_t)0x80078e5e, (q31_t)0x2a68917, (q31_t)0x800706ac, (q31_t)0x28d6870, (q31_t)0x800683e8, (q31_t)0x27447b0, (q31_t)0x80060614, + (q31_t)0x25b26d7, (q31_t)0x80058d2f, (q31_t)0x24205e8, (q31_t)0x80051939, (q31_t)0x228e4e2, (q31_t)0x8004aa32, (q31_t)0x20fc3c6, (q31_t)0x8004401a, + (q31_t)0x1f6a297, (q31_t)0x8003daf1, (q31_t)0x1dd8154, (q31_t)0x80037ab7, (q31_t)0x1c45ffe, (q31_t)0x80031f6d, (q31_t)0x1ab3e97, (q31_t)0x8002c912, + (q31_t)0x1921d20, (q31_t)0x800277a6, (q31_t)0x178fb99, (q31_t)0x80022b29, (q31_t)0x15fda03, (q31_t)0x8001e39b, (q31_t)0x146b860, (q31_t)0x8001a0fd, + (q31_t)0x12d96b1, (q31_t)0x8001634e, (q31_t)0x11474f6, (q31_t)0x80012a8e, (q31_t)0x0fb5330, (q31_t)0x8000f6bd, (q31_t)0xe23160, (q31_t)0x8000c7dc, + (q31_t)0x0c90f88, (q31_t)0x80009dea, (q31_t)0x0afeda8, (q31_t)0x800078e7, (q31_t)0x096cbc1, (q31_t)0x800058d4, (q31_t)0x7da9d4, (q31_t)0x80003daf, + (q31_t)0x06487e3, (q31_t)0x8000277a, (q31_t)0x04b65ee, (q31_t)0x80001635, (q31_t)0x03243f5, (q31_t)0x800009df, (q31_t)0x1921fb, (q31_t)0x80000278 +}; + +static const q31_t WeightsQ31_8192[16384] = { + (q31_t)0x7fffffff, (q31_t)0x00000000, (q31_t)0x7fffffd9, (q31_t)0xfff9b781, (q31_t)0x7fffff62, (q31_t)0xfff36f02, (q31_t)0x7ffffe9d, (q31_t)0xffed2684, + (q31_t)0x7ffffd88, (q31_t)0xffe6de05, (q31_t)0x7ffffc25, (q31_t)0xffe09586, (q31_t)0x7ffffa73, (q31_t)0xffda4d08, (q31_t)0x7ffff872, (q31_t)0xffd40489, + (q31_t)0x7ffff621, (q31_t)0xffcdbc0b, (q31_t)0x7ffff382, (q31_t)0xffc7738c, (q31_t)0x7ffff094, (q31_t)0xffc12b0e, (q31_t)0x7fffed57, (q31_t)0xffbae290, + (q31_t)0x7fffe9cb, (q31_t)0xffb49a12, (q31_t)0x7fffe5f0, (q31_t)0xffae5195, (q31_t)0x7fffe1c6, (q31_t)0xffa80917, (q31_t)0x7fffdd4d, (q31_t)0xffa1c09a, + (q31_t)0x7fffd886, (q31_t)0xff9b781d, (q31_t)0x7fffd36f, (q31_t)0xff952fa0, (q31_t)0x7fffce09, (q31_t)0xff8ee724, (q31_t)0x7fffc854, (q31_t)0xff889ea7, + (q31_t)0x7fffc251, (q31_t)0xff82562c, (q31_t)0x7fffbbfe, (q31_t)0xff7c0db0, (q31_t)0x7fffb55c, (q31_t)0xff75c535, (q31_t)0x7fffae6c, (q31_t)0xff6f7cba, + (q31_t)0x7fffa72c, (q31_t)0xff69343f, (q31_t)0x7fff9f9e, (q31_t)0xff62ebc5, (q31_t)0x7fff97c1, (q31_t)0xff5ca34b, (q31_t)0x7fff8f94, (q31_t)0xff565ad1, + (q31_t)0x7fff8719, (q31_t)0xff501258, (q31_t)0x7fff7e4f, (q31_t)0xff49c9df, (q31_t)0x7fff7536, (q31_t)0xff438167, (q31_t)0x7fff6bcd, (q31_t)0xff3d38ef, + (q31_t)0x7fff6216, (q31_t)0xff36f078, (q31_t)0x7fff5810, (q31_t)0xff30a801, (q31_t)0x7fff4dbb, (q31_t)0xff2a5f8b, (q31_t)0x7fff4317, (q31_t)0xff241715, + (q31_t)0x7fff3824, (q31_t)0xff1dcea0, (q31_t)0x7fff2ce2, (q31_t)0xff17862b, (q31_t)0x7fff2151, (q31_t)0xff113db7, (q31_t)0x7fff1572, (q31_t)0xff0af543, + (q31_t)0x7fff0943, (q31_t)0xff04acd0, (q31_t)0x7ffefcc5, (q31_t)0xfefe645e, (q31_t)0x7ffeeff8, (q31_t)0xfef81bec, (q31_t)0x7ffee2dd, (q31_t)0xfef1d37b, + (q31_t)0x7ffed572, (q31_t)0xfeeb8b0a, (q31_t)0x7ffec7b9, (q31_t)0xfee5429a, (q31_t)0x7ffeb9b0, (q31_t)0xfedefa2b, (q31_t)0x7ffeab59, (q31_t)0xfed8b1bd, + (q31_t)0x7ffe9cb2, (q31_t)0xfed2694f, (q31_t)0x7ffe8dbd, (q31_t)0xfecc20e2, (q31_t)0x7ffe7e79, (q31_t)0xfec5d876, (q31_t)0x7ffe6ee5, (q31_t)0xfebf900a, + (q31_t)0x7ffe5f03, (q31_t)0xfeb947a0, (q31_t)0x7ffe4ed2, (q31_t)0xfeb2ff36, (q31_t)0x7ffe3e52, (q31_t)0xfeacb6cc, (q31_t)0x7ffe2d83, (q31_t)0xfea66e64, + (q31_t)0x7ffe1c65, (q31_t)0xfea025fd, (q31_t)0x7ffe0af8, (q31_t)0xfe99dd96, (q31_t)0x7ffdf93c, (q31_t)0xfe939530, (q31_t)0x7ffde731, (q31_t)0xfe8d4ccb, + (q31_t)0x7ffdd4d7, (q31_t)0xfe870467, (q31_t)0x7ffdc22e, (q31_t)0xfe80bc04, (q31_t)0x7ffdaf37, (q31_t)0xfe7a73a2, (q31_t)0x7ffd9bf0, (q31_t)0xfe742b41, + (q31_t)0x7ffd885a, (q31_t)0xfe6de2e0, (q31_t)0x7ffd7476, (q31_t)0xfe679a81, (q31_t)0x7ffd6042, (q31_t)0xfe615223, (q31_t)0x7ffd4bc0, (q31_t)0xfe5b09c5, + (q31_t)0x7ffd36ee, (q31_t)0xfe54c169, (q31_t)0x7ffd21ce, (q31_t)0xfe4e790d, (q31_t)0x7ffd0c5f, (q31_t)0xfe4830b3, (q31_t)0x7ffcf6a0, (q31_t)0xfe41e85a, + (q31_t)0x7ffce093, (q31_t)0xfe3ba002, (q31_t)0x7ffcca37, (q31_t)0xfe3557ab, (q31_t)0x7ffcb38c, (q31_t)0xfe2f0f55, (q31_t)0x7ffc9c92, (q31_t)0xfe28c700, + (q31_t)0x7ffc8549, (q31_t)0xfe227eac, (q31_t)0x7ffc6db1, (q31_t)0xfe1c365a, (q31_t)0x7ffc55ca, (q31_t)0xfe15ee09, (q31_t)0x7ffc3d94, (q31_t)0xfe0fa5b8, + (q31_t)0x7ffc250f, (q31_t)0xfe095d69, (q31_t)0x7ffc0c3b, (q31_t)0xfe03151c, (q31_t)0x7ffbf319, (q31_t)0xfdfccccf, (q31_t)0x7ffbd9a7, (q31_t)0xfdf68484, + (q31_t)0x7ffbbfe6, (q31_t)0xfdf03c3a, (q31_t)0x7ffba5d7, (q31_t)0xfde9f3f1, (q31_t)0x7ffb8b78, (q31_t)0xfde3aba9, (q31_t)0x7ffb70cb, (q31_t)0xfddd6363, + (q31_t)0x7ffb55ce, (q31_t)0xfdd71b1e, (q31_t)0x7ffb3a83, (q31_t)0xfdd0d2db, (q31_t)0x7ffb1ee9, (q31_t)0xfdca8a99, (q31_t)0x7ffb0300, (q31_t)0xfdc44258, + (q31_t)0x7ffae6c7, (q31_t)0xfdbdfa18, (q31_t)0x7ffaca40, (q31_t)0xfdb7b1da, (q31_t)0x7ffaad6a, (q31_t)0xfdb1699e, (q31_t)0x7ffa9045, (q31_t)0xfdab2162, + (q31_t)0x7ffa72d1, (q31_t)0xfda4d929, (q31_t)0x7ffa550e, (q31_t)0xfd9e90f0, (q31_t)0x7ffa36fc, (q31_t)0xfd9848b9, (q31_t)0x7ffa189c, (q31_t)0xfd920084, + (q31_t)0x7ff9f9ec, (q31_t)0xfd8bb850, (q31_t)0x7ff9daed, (q31_t)0xfd85701e, (q31_t)0x7ff9bba0, (q31_t)0xfd7f27ed, (q31_t)0x7ff99c03, (q31_t)0xfd78dfbd, + (q31_t)0x7ff97c18, (q31_t)0xfd729790, (q31_t)0x7ff95bdd, (q31_t)0xfd6c4f64, (q31_t)0x7ff93b54, (q31_t)0xfd660739, (q31_t)0x7ff91a7b, (q31_t)0xfd5fbf10, + (q31_t)0x7ff8f954, (q31_t)0xfd5976e9, (q31_t)0x7ff8d7de, (q31_t)0xfd532ec3, (q31_t)0x7ff8b619, (q31_t)0xfd4ce69f, (q31_t)0x7ff89405, (q31_t)0xfd469e7c, + (q31_t)0x7ff871a2, (q31_t)0xfd40565c, (q31_t)0x7ff84ef0, (q31_t)0xfd3a0e3d, (q31_t)0x7ff82bef, (q31_t)0xfd33c61f, (q31_t)0x7ff8089f, (q31_t)0xfd2d7e04, + (q31_t)0x7ff7e500, (q31_t)0xfd2735ea, (q31_t)0x7ff7c113, (q31_t)0xfd20edd2, (q31_t)0x7ff79cd6, (q31_t)0xfd1aa5bc, (q31_t)0x7ff7784a, (q31_t)0xfd145da7, + (q31_t)0x7ff75370, (q31_t)0xfd0e1594, (q31_t)0x7ff72e46, (q31_t)0xfd07cd83, (q31_t)0x7ff708ce, (q31_t)0xfd018574, (q31_t)0x7ff6e307, (q31_t)0xfcfb3d67, + (q31_t)0x7ff6bcf0, (q31_t)0xfcf4f55c, (q31_t)0x7ff6968b, (q31_t)0xfceead52, (q31_t)0x7ff66fd7, (q31_t)0xfce8654b, (q31_t)0x7ff648d4, (q31_t)0xfce21d45, + (q31_t)0x7ff62182, (q31_t)0xfcdbd541, (q31_t)0x7ff5f9e1, (q31_t)0xfcd58d3f, (q31_t)0x7ff5d1f1, (q31_t)0xfccf453f, (q31_t)0x7ff5a9b2, (q31_t)0xfcc8fd41, + (q31_t)0x7ff58125, (q31_t)0xfcc2b545, (q31_t)0x7ff55848, (q31_t)0xfcbc6d4c, (q31_t)0x7ff52f1d, (q31_t)0xfcb62554, (q31_t)0x7ff505a2, (q31_t)0xfcafdd5e, + (q31_t)0x7ff4dbd9, (q31_t)0xfca9956a, (q31_t)0x7ff4b1c0, (q31_t)0xfca34d78, (q31_t)0x7ff48759, (q31_t)0xfc9d0588, (q31_t)0x7ff45ca3, (q31_t)0xfc96bd9b, + (q31_t)0x7ff4319d, (q31_t)0xfc9075af, (q31_t)0x7ff40649, (q31_t)0xfc8a2dc6, (q31_t)0x7ff3daa6, (q31_t)0xfc83e5de, (q31_t)0x7ff3aeb4, (q31_t)0xfc7d9df9, + (q31_t)0x7ff38274, (q31_t)0xfc775616, (q31_t)0x7ff355e4, (q31_t)0xfc710e36, (q31_t)0x7ff32905, (q31_t)0xfc6ac657, (q31_t)0x7ff2fbd7, (q31_t)0xfc647e7b, + (q31_t)0x7ff2ce5b, (q31_t)0xfc5e36a0, (q31_t)0x7ff2a08f, (q31_t)0xfc57eec9, (q31_t)0x7ff27275, (q31_t)0xfc51a6f3, (q31_t)0x7ff2440b, (q31_t)0xfc4b5f20, + (q31_t)0x7ff21553, (q31_t)0xfc45174e, (q31_t)0x7ff1e64c, (q31_t)0xfc3ecf80, (q31_t)0x7ff1b6f6, (q31_t)0xfc3887b3, (q31_t)0x7ff18751, (q31_t)0xfc323fe9, + (q31_t)0x7ff1575d, (q31_t)0xfc2bf821, (q31_t)0x7ff1271a, (q31_t)0xfc25b05c, (q31_t)0x7ff0f688, (q31_t)0xfc1f6899, (q31_t)0x7ff0c5a7, (q31_t)0xfc1920d8, + (q31_t)0x7ff09478, (q31_t)0xfc12d91a, (q31_t)0x7ff062f9, (q31_t)0xfc0c915e, (q31_t)0x7ff0312c, (q31_t)0xfc0649a5, (q31_t)0x7fefff0f, (q31_t)0xfc0001ee, + (q31_t)0x7fefcca4, (q31_t)0xfbf9ba39, (q31_t)0x7fef99ea, (q31_t)0xfbf37287, (q31_t)0x7fef66e1, (q31_t)0xfbed2ad8, (q31_t)0x7fef3388, (q31_t)0xfbe6e32b, + (q31_t)0x7feeffe1, (q31_t)0xfbe09b80, (q31_t)0x7feecbec, (q31_t)0xfbda53d8, (q31_t)0x7fee97a7, (q31_t)0xfbd40c33, (q31_t)0x7fee6313, (q31_t)0xfbcdc490, + (q31_t)0x7fee2e30, (q31_t)0xfbc77cf0, (q31_t)0x7fedf8ff, (q31_t)0xfbc13552, (q31_t)0x7fedc37e, (q31_t)0xfbbaedb7, (q31_t)0x7fed8daf, (q31_t)0xfbb4a61f, + (q31_t)0x7fed5791, (q31_t)0xfbae5e89, (q31_t)0x7fed2123, (q31_t)0xfba816f6, (q31_t)0x7fecea67, (q31_t)0xfba1cf66, (q31_t)0x7fecb35c, (q31_t)0xfb9b87d8, + (q31_t)0x7fec7c02, (q31_t)0xfb95404d, (q31_t)0x7fec4459, (q31_t)0xfb8ef8c5, (q31_t)0x7fec0c62, (q31_t)0xfb88b13f, (q31_t)0x7febd41b, (q31_t)0xfb8269bd, + (q31_t)0x7feb9b85, (q31_t)0xfb7c223d, (q31_t)0x7feb62a1, (q31_t)0xfb75dac0, (q31_t)0x7feb296d, (q31_t)0xfb6f9345, (q31_t)0x7feaefeb, (q31_t)0xfb694bce, + (q31_t)0x7feab61a, (q31_t)0xfb630459, (q31_t)0x7fea7bfa, (q31_t)0xfb5cbce7, (q31_t)0x7fea418b, (q31_t)0xfb567578, (q31_t)0x7fea06cd, (q31_t)0xfb502e0c, + (q31_t)0x7fe9cbc0, (q31_t)0xfb49e6a3, (q31_t)0x7fe99064, (q31_t)0xfb439f3c, (q31_t)0x7fe954ba, (q31_t)0xfb3d57d9, (q31_t)0x7fe918c0, (q31_t)0xfb371078, + (q31_t)0x7fe8dc78, (q31_t)0xfb30c91b, (q31_t)0x7fe89fe0, (q31_t)0xfb2a81c0, (q31_t)0x7fe862fa, (q31_t)0xfb243a69, (q31_t)0x7fe825c5, (q31_t)0xfb1df314, + (q31_t)0x7fe7e841, (q31_t)0xfb17abc2, (q31_t)0x7fe7aa6e, (q31_t)0xfb116474, (q31_t)0x7fe76c4c, (q31_t)0xfb0b1d28, (q31_t)0x7fe72ddb, (q31_t)0xfb04d5e0, + (q31_t)0x7fe6ef1c, (q31_t)0xfafe8e9b, (q31_t)0x7fe6b00d, (q31_t)0xfaf84758, (q31_t)0x7fe670b0, (q31_t)0xfaf20019, (q31_t)0x7fe63103, (q31_t)0xfaebb8dd, + (q31_t)0x7fe5f108, (q31_t)0xfae571a4, (q31_t)0x7fe5b0be, (q31_t)0xfadf2a6e, (q31_t)0x7fe57025, (q31_t)0xfad8e33c, (q31_t)0x7fe52f3d, (q31_t)0xfad29c0c, + (q31_t)0x7fe4ee06, (q31_t)0xfacc54e0, (q31_t)0x7fe4ac81, (q31_t)0xfac60db7, (q31_t)0x7fe46aac, (q31_t)0xfabfc691, (q31_t)0x7fe42889, (q31_t)0xfab97f6e, + (q31_t)0x7fe3e616, (q31_t)0xfab3384f, (q31_t)0x7fe3a355, (q31_t)0xfaacf133, (q31_t)0x7fe36045, (q31_t)0xfaa6aa1a, (q31_t)0x7fe31ce6, (q31_t)0xfaa06305, + (q31_t)0x7fe2d938, (q31_t)0xfa9a1bf3, (q31_t)0x7fe2953b, (q31_t)0xfa93d4e4, (q31_t)0x7fe250ef, (q31_t)0xfa8d8dd8, (q31_t)0x7fe20c55, (q31_t)0xfa8746d0, + (q31_t)0x7fe1c76b, (q31_t)0xfa80ffcb, (q31_t)0x7fe18233, (q31_t)0xfa7ab8ca, (q31_t)0x7fe13cac, (q31_t)0xfa7471cc, (q31_t)0x7fe0f6d6, (q31_t)0xfa6e2ad1, + (q31_t)0x7fe0b0b1, (q31_t)0xfa67e3da, (q31_t)0x7fe06a3d, (q31_t)0xfa619ce7, (q31_t)0x7fe0237a, (q31_t)0xfa5b55f7, (q31_t)0x7fdfdc69, (q31_t)0xfa550f0a, + (q31_t)0x7fdf9508, (q31_t)0xfa4ec821, (q31_t)0x7fdf4d59, (q31_t)0xfa48813b, (q31_t)0x7fdf055a, (q31_t)0xfa423a59, (q31_t)0x7fdebd0d, (q31_t)0xfa3bf37a, + (q31_t)0x7fde7471, (q31_t)0xfa35ac9f, (q31_t)0x7fde2b86, (q31_t)0xfa2f65c8, (q31_t)0x7fdde24d, (q31_t)0xfa291ef4, (q31_t)0x7fdd98c4, (q31_t)0xfa22d823, + (q31_t)0x7fdd4eec, (q31_t)0xfa1c9157, (q31_t)0x7fdd04c6, (q31_t)0xfa164a8e, (q31_t)0x7fdcba51, (q31_t)0xfa1003c8, (q31_t)0x7fdc6f8d, (q31_t)0xfa09bd06, + (q31_t)0x7fdc247a, (q31_t)0xfa037648, (q31_t)0x7fdbd918, (q31_t)0xf9fd2f8e, (q31_t)0x7fdb8d67, (q31_t)0xf9f6e8d7, (q31_t)0x7fdb4167, (q31_t)0xf9f0a224, + (q31_t)0x7fdaf519, (q31_t)0xf9ea5b75, (q31_t)0x7fdaa87c, (q31_t)0xf9e414ca, (q31_t)0x7fda5b8f, (q31_t)0xf9ddce22, (q31_t)0x7fda0e54, (q31_t)0xf9d7877e, + (q31_t)0x7fd9c0ca, (q31_t)0xf9d140de, (q31_t)0x7fd972f2, (q31_t)0xf9cafa42, (q31_t)0x7fd924ca, (q31_t)0xf9c4b3a9, (q31_t)0x7fd8d653, (q31_t)0xf9be6d15, + (q31_t)0x7fd8878e, (q31_t)0xf9b82684, (q31_t)0x7fd8387a, (q31_t)0xf9b1dff7, (q31_t)0x7fd7e917, (q31_t)0xf9ab996e, (q31_t)0x7fd79965, (q31_t)0xf9a552e9, + (q31_t)0x7fd74964, (q31_t)0xf99f0c68, (q31_t)0x7fd6f914, (q31_t)0xf998c5ea, (q31_t)0x7fd6a875, (q31_t)0xf9927f71, (q31_t)0x7fd65788, (q31_t)0xf98c38fc, + (q31_t)0x7fd6064c, (q31_t)0xf985f28a, (q31_t)0x7fd5b4c1, (q31_t)0xf97fac1d, (q31_t)0x7fd562e7, (q31_t)0xf97965b4, (q31_t)0x7fd510be, (q31_t)0xf9731f4e, + (q31_t)0x7fd4be46, (q31_t)0xf96cd8ed, (q31_t)0x7fd46b80, (q31_t)0xf9669290, (q31_t)0x7fd4186a, (q31_t)0xf9604c37, (q31_t)0x7fd3c506, (q31_t)0xf95a05e2, + (q31_t)0x7fd37153, (q31_t)0xf953bf91, (q31_t)0x7fd31d51, (q31_t)0xf94d7944, (q31_t)0x7fd2c900, (q31_t)0xf94732fb, (q31_t)0x7fd27460, (q31_t)0xf940ecb7, + (q31_t)0x7fd21f72, (q31_t)0xf93aa676, (q31_t)0x7fd1ca35, (q31_t)0xf934603a, (q31_t)0x7fd174a8, (q31_t)0xf92e1a02, (q31_t)0x7fd11ecd, (q31_t)0xf927d3ce, + (q31_t)0x7fd0c8a3, (q31_t)0xf9218d9e, (q31_t)0x7fd0722b, (q31_t)0xf91b4773, (q31_t)0x7fd01b63, (q31_t)0xf915014c, (q31_t)0x7fcfc44d, (q31_t)0xf90ebb29, + (q31_t)0x7fcf6ce8, (q31_t)0xf908750a, (q31_t)0x7fcf1533, (q31_t)0xf9022ef0, (q31_t)0x7fcebd31, (q31_t)0xf8fbe8da, (q31_t)0x7fce64df, (q31_t)0xf8f5a2c9, + (q31_t)0x7fce0c3e, (q31_t)0xf8ef5cbb, (q31_t)0x7fcdb34f, (q31_t)0xf8e916b2, (q31_t)0x7fcd5a11, (q31_t)0xf8e2d0ae, (q31_t)0x7fcd0083, (q31_t)0xf8dc8aae, + (q31_t)0x7fcca6a7, (q31_t)0xf8d644b2, (q31_t)0x7fcc4c7d, (q31_t)0xf8cffebb, (q31_t)0x7fcbf203, (q31_t)0xf8c9b8c8, (q31_t)0x7fcb973b, (q31_t)0xf8c372d9, + (q31_t)0x7fcb3c23, (q31_t)0xf8bd2cef, (q31_t)0x7fcae0bd, (q31_t)0xf8b6e70a, (q31_t)0x7fca8508, (q31_t)0xf8b0a129, (q31_t)0x7fca2905, (q31_t)0xf8aa5b4c, + (q31_t)0x7fc9ccb2, (q31_t)0xf8a41574, (q31_t)0x7fc97011, (q31_t)0xf89dcfa1, (q31_t)0x7fc91320, (q31_t)0xf89789d2, (q31_t)0x7fc8b5e1, (q31_t)0xf8914407, + (q31_t)0x7fc85854, (q31_t)0xf88afe42, (q31_t)0x7fc7fa77, (q31_t)0xf884b880, (q31_t)0x7fc79c4b, (q31_t)0xf87e72c4, (q31_t)0x7fc73dd1, (q31_t)0xf8782d0c, + (q31_t)0x7fc6df08, (q31_t)0xf871e759, (q31_t)0x7fc67ff0, (q31_t)0xf86ba1aa, (q31_t)0x7fc62089, (q31_t)0xf8655c00, (q31_t)0x7fc5c0d3, (q31_t)0xf85f165b, + (q31_t)0x7fc560cf, (q31_t)0xf858d0bb, (q31_t)0x7fc5007c, (q31_t)0xf8528b1f, (q31_t)0x7fc49fda, (q31_t)0xf84c4588, (q31_t)0x7fc43ee9, (q31_t)0xf845fff5, + (q31_t)0x7fc3dda9, (q31_t)0xf83fba68, (q31_t)0x7fc37c1b, (q31_t)0xf83974df, (q31_t)0x7fc31a3d, (q31_t)0xf8332f5b, (q31_t)0x7fc2b811, (q31_t)0xf82ce9dc, + (q31_t)0x7fc25596, (q31_t)0xf826a462, (q31_t)0x7fc1f2cc, (q31_t)0xf8205eec, (q31_t)0x7fc18fb4, (q31_t)0xf81a197b, (q31_t)0x7fc12c4d, (q31_t)0xf813d410, + (q31_t)0x7fc0c896, (q31_t)0xf80d8ea9, (q31_t)0x7fc06491, (q31_t)0xf8074947, (q31_t)0x7fc0003e, (q31_t)0xf80103ea, (q31_t)0x7fbf9b9b, (q31_t)0xf7fabe92, + (q31_t)0x7fbf36aa, (q31_t)0xf7f4793e, (q31_t)0x7fbed16a, (q31_t)0xf7ee33f0, (q31_t)0x7fbe6bdb, (q31_t)0xf7e7eea7, (q31_t)0x7fbe05fd, (q31_t)0xf7e1a963, + (q31_t)0x7fbd9fd0, (q31_t)0xf7db6423, (q31_t)0x7fbd3955, (q31_t)0xf7d51ee9, (q31_t)0x7fbcd28b, (q31_t)0xf7ced9b4, (q31_t)0x7fbc6b72, (q31_t)0xf7c89484, + (q31_t)0x7fbc040a, (q31_t)0xf7c24f59, (q31_t)0x7fbb9c53, (q31_t)0xf7bc0a33, (q31_t)0x7fbb344e, (q31_t)0xf7b5c512, (q31_t)0x7fbacbfa, (q31_t)0xf7af7ff6, + (q31_t)0x7fba6357, (q31_t)0xf7a93ae0, (q31_t)0x7fb9fa65, (q31_t)0xf7a2f5ce, (q31_t)0x7fb99125, (q31_t)0xf79cb0c2, (q31_t)0x7fb92796, (q31_t)0xf7966bbb, + (q31_t)0x7fb8bdb8, (q31_t)0xf79026b9, (q31_t)0x7fb8538b, (q31_t)0xf789e1bc, (q31_t)0x7fb7e90f, (q31_t)0xf7839cc4, (q31_t)0x7fb77e45, (q31_t)0xf77d57d2, + (q31_t)0x7fb7132b, (q31_t)0xf77712e5, (q31_t)0x7fb6a7c3, (q31_t)0xf770cdfd, (q31_t)0x7fb63c0d, (q31_t)0xf76a891b, (q31_t)0x7fb5d007, (q31_t)0xf764443d, + (q31_t)0x7fb563b3, (q31_t)0xf75dff66, (q31_t)0x7fb4f710, (q31_t)0xf757ba93, (q31_t)0x7fb48a1e, (q31_t)0xf75175c6, (q31_t)0x7fb41cdd, (q31_t)0xf74b30fe, + (q31_t)0x7fb3af4e, (q31_t)0xf744ec3b, (q31_t)0x7fb34170, (q31_t)0xf73ea77e, (q31_t)0x7fb2d343, (q31_t)0xf73862c6, (q31_t)0x7fb264c7, (q31_t)0xf7321e14, + (q31_t)0x7fb1f5fc, (q31_t)0xf72bd967, (q31_t)0x7fb186e3, (q31_t)0xf72594c0, (q31_t)0x7fb1177b, (q31_t)0xf71f501e, (q31_t)0x7fb0a7c4, (q31_t)0xf7190b81, + (q31_t)0x7fb037bf, (q31_t)0xf712c6ea, (q31_t)0x7fafc76a, (q31_t)0xf70c8259, (q31_t)0x7faf56c7, (q31_t)0xf7063dcd, (q31_t)0x7faee5d5, (q31_t)0xf6fff946, + (q31_t)0x7fae7495, (q31_t)0xf6f9b4c6, (q31_t)0x7fae0305, (q31_t)0xf6f3704a, (q31_t)0x7fad9127, (q31_t)0xf6ed2bd4, (q31_t)0x7fad1efa, (q31_t)0xf6e6e764, + (q31_t)0x7facac7f, (q31_t)0xf6e0a2fa, (q31_t)0x7fac39b4, (q31_t)0xf6da5e95, (q31_t)0x7fabc69b, (q31_t)0xf6d41a36, (q31_t)0x7fab5333, (q31_t)0xf6cdd5dc, + (q31_t)0x7faadf7c, (q31_t)0xf6c79188, (q31_t)0x7faa6b77, (q31_t)0xf6c14d3a, (q31_t)0x7fa9f723, (q31_t)0xf6bb08f1, (q31_t)0x7fa98280, (q31_t)0xf6b4c4ae, + (q31_t)0x7fa90d8e, (q31_t)0xf6ae8071, (q31_t)0x7fa8984e, (q31_t)0xf6a83c3a, (q31_t)0x7fa822bf, (q31_t)0xf6a1f808, (q31_t)0x7fa7ace1, (q31_t)0xf69bb3dd, + (q31_t)0x7fa736b4, (q31_t)0xf6956fb7, (q31_t)0x7fa6c039, (q31_t)0xf68f2b96, (q31_t)0x7fa6496e, (q31_t)0xf688e77c, (q31_t)0x7fa5d256, (q31_t)0xf682a367, + (q31_t)0x7fa55aee, (q31_t)0xf67c5f59, (q31_t)0x7fa4e338, (q31_t)0xf6761b50, (q31_t)0x7fa46b32, (q31_t)0xf66fd74d, (q31_t)0x7fa3f2df, (q31_t)0xf6699350, + (q31_t)0x7fa37a3c, (q31_t)0xf6634f59, (q31_t)0x7fa3014b, (q31_t)0xf65d0b68, (q31_t)0x7fa2880b, (q31_t)0xf656c77c, (q31_t)0x7fa20e7c, (q31_t)0xf6508397, + (q31_t)0x7fa1949e, (q31_t)0xf64a3fb8, (q31_t)0x7fa11a72, (q31_t)0xf643fbdf, (q31_t)0x7fa09ff7, (q31_t)0xf63db80b, (q31_t)0x7fa0252e, (q31_t)0xf637743e, + (q31_t)0x7f9faa15, (q31_t)0xf6313077, (q31_t)0x7f9f2eae, (q31_t)0xf62aecb5, (q31_t)0x7f9eb2f8, (q31_t)0xf624a8fa, (q31_t)0x7f9e36f4, (q31_t)0xf61e6545, + (q31_t)0x7f9dbaa0, (q31_t)0xf6182196, (q31_t)0x7f9d3dfe, (q31_t)0xf611dded, (q31_t)0x7f9cc10d, (q31_t)0xf60b9a4b, (q31_t)0x7f9c43ce, (q31_t)0xf60556ae, + (q31_t)0x7f9bc640, (q31_t)0xf5ff1318, (q31_t)0x7f9b4863, (q31_t)0xf5f8cf87, (q31_t)0x7f9aca37, (q31_t)0xf5f28bfd, (q31_t)0x7f9a4bbd, (q31_t)0xf5ec4879, + (q31_t)0x7f99ccf4, (q31_t)0xf5e604fc, (q31_t)0x7f994ddc, (q31_t)0xf5dfc184, (q31_t)0x7f98ce76, (q31_t)0xf5d97e13, (q31_t)0x7f984ec1, (q31_t)0xf5d33aa8, + (q31_t)0x7f97cebd, (q31_t)0xf5ccf743, (q31_t)0x7f974e6a, (q31_t)0xf5c6b3e5, (q31_t)0x7f96cdc9, (q31_t)0xf5c0708d, (q31_t)0x7f964cd9, (q31_t)0xf5ba2d3b, + (q31_t)0x7f95cb9a, (q31_t)0xf5b3e9f0, (q31_t)0x7f954a0d, (q31_t)0xf5ada6ab, (q31_t)0x7f94c831, (q31_t)0xf5a7636c, (q31_t)0x7f944606, (q31_t)0xf5a12034, + (q31_t)0x7f93c38c, (q31_t)0xf59add02, (q31_t)0x7f9340c4, (q31_t)0xf59499d6, (q31_t)0x7f92bdad, (q31_t)0xf58e56b1, (q31_t)0x7f923a48, (q31_t)0xf5881393, + (q31_t)0x7f91b694, (q31_t)0xf581d07b, (q31_t)0x7f913291, (q31_t)0xf57b8d69, (q31_t)0x7f90ae3f, (q31_t)0xf5754a5e, (q31_t)0x7f90299f, (q31_t)0xf56f0759, + (q31_t)0x7f8fa4b0, (q31_t)0xf568c45b, (q31_t)0x7f8f1f72, (q31_t)0xf5628163, (q31_t)0x7f8e99e6, (q31_t)0xf55c3e72, (q31_t)0x7f8e140a, (q31_t)0xf555fb88, + (q31_t)0x7f8d8de1, (q31_t)0xf54fb8a4, (q31_t)0x7f8d0768, (q31_t)0xf54975c6, (q31_t)0x7f8c80a1, (q31_t)0xf54332ef, (q31_t)0x7f8bf98b, (q31_t)0xf53cf01f, + (q31_t)0x7f8b7227, (q31_t)0xf536ad56, (q31_t)0x7f8aea74, (q31_t)0xf5306a93, (q31_t)0x7f8a6272, (q31_t)0xf52a27d7, (q31_t)0x7f89da21, (q31_t)0xf523e521, + (q31_t)0x7f895182, (q31_t)0xf51da273, (q31_t)0x7f88c894, (q31_t)0xf5175fca, (q31_t)0x7f883f58, (q31_t)0xf5111d29, (q31_t)0x7f87b5cd, (q31_t)0xf50ada8f, + (q31_t)0x7f872bf3, (q31_t)0xf50497fb, (q31_t)0x7f86a1ca, (q31_t)0xf4fe556e, (q31_t)0x7f861753, (q31_t)0xf4f812e7, (q31_t)0x7f858c8d, (q31_t)0xf4f1d068, + (q31_t)0x7f850179, (q31_t)0xf4eb8def, (q31_t)0x7f847616, (q31_t)0xf4e54b7d, (q31_t)0x7f83ea64, (q31_t)0xf4df0912, (q31_t)0x7f835e64, (q31_t)0xf4d8c6ae, + (q31_t)0x7f82d214, (q31_t)0xf4d28451, (q31_t)0x7f824577, (q31_t)0xf4cc41fb, (q31_t)0x7f81b88a, (q31_t)0xf4c5ffab, (q31_t)0x7f812b4f, (q31_t)0xf4bfbd63, + (q31_t)0x7f809dc5, (q31_t)0xf4b97b21, (q31_t)0x7f800fed, (q31_t)0xf4b338e7, (q31_t)0x7f7f81c6, (q31_t)0xf4acf6b3, (q31_t)0x7f7ef350, (q31_t)0xf4a6b486, + (q31_t)0x7f7e648c, (q31_t)0xf4a07261, (q31_t)0x7f7dd579, (q31_t)0xf49a3042, (q31_t)0x7f7d4617, (q31_t)0xf493ee2b, (q31_t)0x7f7cb667, (q31_t)0xf48dac1a, + (q31_t)0x7f7c2668, (q31_t)0xf4876a10, (q31_t)0x7f7b961b, (q31_t)0xf481280e, (q31_t)0x7f7b057e, (q31_t)0xf47ae613, (q31_t)0x7f7a7494, (q31_t)0xf474a41f, + (q31_t)0x7f79e35a, (q31_t)0xf46e6231, (q31_t)0x7f7951d2, (q31_t)0xf468204b, (q31_t)0x7f78bffb, (q31_t)0xf461de6d, (q31_t)0x7f782dd6, (q31_t)0xf45b9c95, + (q31_t)0x7f779b62, (q31_t)0xf4555ac5, (q31_t)0x7f77089f, (q31_t)0xf44f18fb, (q31_t)0x7f76758e, (q31_t)0xf448d739, (q31_t)0x7f75e22e, (q31_t)0xf442957e, + (q31_t)0x7f754e80, (q31_t)0xf43c53cb, (q31_t)0x7f74ba83, (q31_t)0xf436121e, (q31_t)0x7f742637, (q31_t)0xf42fd079, (q31_t)0x7f73919d, (q31_t)0xf4298edc, + (q31_t)0x7f72fcb4, (q31_t)0xf4234d45, (q31_t)0x7f72677c, (q31_t)0xf41d0bb6, (q31_t)0x7f71d1f6, (q31_t)0xf416ca2e, (q31_t)0x7f713c21, (q31_t)0xf41088ae, + (q31_t)0x7f70a5fe, (q31_t)0xf40a4735, (q31_t)0x7f700f8c, (q31_t)0xf40405c3, (q31_t)0x7f6f78cb, (q31_t)0xf3fdc459, (q31_t)0x7f6ee1bc, (q31_t)0xf3f782f6, + (q31_t)0x7f6e4a5e, (q31_t)0xf3f1419a, (q31_t)0x7f6db2b1, (q31_t)0xf3eb0046, (q31_t)0x7f6d1ab6, (q31_t)0xf3e4bef9, (q31_t)0x7f6c826d, (q31_t)0xf3de7db4, + (q31_t)0x7f6be9d4, (q31_t)0xf3d83c77, (q31_t)0x7f6b50ed, (q31_t)0xf3d1fb40, (q31_t)0x7f6ab7b8, (q31_t)0xf3cbba12, (q31_t)0x7f6a1e34, (q31_t)0xf3c578eb, + (q31_t)0x7f698461, (q31_t)0xf3bf37cb, (q31_t)0x7f68ea40, (q31_t)0xf3b8f6b3, (q31_t)0x7f684fd0, (q31_t)0xf3b2b5a3, (q31_t)0x7f67b512, (q31_t)0xf3ac749a, + (q31_t)0x7f671a05, (q31_t)0xf3a63398, (q31_t)0x7f667ea9, (q31_t)0xf39ff29f, (q31_t)0x7f65e2ff, (q31_t)0xf399b1ad, (q31_t)0x7f654706, (q31_t)0xf39370c2, + (q31_t)0x7f64aabf, (q31_t)0xf38d2fe0, (q31_t)0x7f640e29, (q31_t)0xf386ef05, (q31_t)0x7f637144, (q31_t)0xf380ae31, (q31_t)0x7f62d411, (q31_t)0xf37a6d66, + (q31_t)0x7f62368f, (q31_t)0xf3742ca2, (q31_t)0x7f6198bf, (q31_t)0xf36debe6, (q31_t)0x7f60faa0, (q31_t)0xf367ab31, (q31_t)0x7f605c33, (q31_t)0xf3616a85, + (q31_t)0x7f5fbd77, (q31_t)0xf35b29e0, (q31_t)0x7f5f1e6c, (q31_t)0xf354e943, (q31_t)0x7f5e7f13, (q31_t)0xf34ea8ae, (q31_t)0x7f5ddf6b, (q31_t)0xf3486820, + (q31_t)0x7f5d3f75, (q31_t)0xf342279b, (q31_t)0x7f5c9f30, (q31_t)0xf33be71d, (q31_t)0x7f5bfe9d, (q31_t)0xf335a6a7, (q31_t)0x7f5b5dbb, (q31_t)0xf32f6639, + (q31_t)0x7f5abc8a, (q31_t)0xf32925d3, (q31_t)0x7f5a1b0b, (q31_t)0xf322e575, (q31_t)0x7f59793e, (q31_t)0xf31ca51f, (q31_t)0x7f58d721, (q31_t)0xf31664d1, + (q31_t)0x7f5834b7, (q31_t)0xf310248a, (q31_t)0x7f5791fd, (q31_t)0xf309e44c, (q31_t)0x7f56eef5, (q31_t)0xf303a416, (q31_t)0x7f564b9f, (q31_t)0xf2fd63e8, + (q31_t)0x7f55a7fa, (q31_t)0xf2f723c1, (q31_t)0x7f550407, (q31_t)0xf2f0e3a3, (q31_t)0x7f545fc5, (q31_t)0xf2eaa38d, (q31_t)0x7f53bb34, (q31_t)0xf2e4637f, + (q31_t)0x7f531655, (q31_t)0xf2de2379, (q31_t)0x7f527127, (q31_t)0xf2d7e37b, (q31_t)0x7f51cbab, (q31_t)0xf2d1a385, (q31_t)0x7f5125e0, (q31_t)0xf2cb6398, + (q31_t)0x7f507fc7, (q31_t)0xf2c523b2, (q31_t)0x7f4fd95f, (q31_t)0xf2bee3d5, (q31_t)0x7f4f32a9, (q31_t)0xf2b8a400, (q31_t)0x7f4e8ba4, (q31_t)0xf2b26433, + (q31_t)0x7f4de451, (q31_t)0xf2ac246e, (q31_t)0x7f4d3caf, (q31_t)0xf2a5e4b1, (q31_t)0x7f4c94be, (q31_t)0xf29fa4fd, (q31_t)0x7f4bec7f, (q31_t)0xf2996551, + (q31_t)0x7f4b43f2, (q31_t)0xf29325ad, (q31_t)0x7f4a9b16, (q31_t)0xf28ce612, (q31_t)0x7f49f1eb, (q31_t)0xf286a67e, (q31_t)0x7f494872, (q31_t)0xf28066f4, + (q31_t)0x7f489eaa, (q31_t)0xf27a2771, (q31_t)0x7f47f494, (q31_t)0xf273e7f7, (q31_t)0x7f474a30, (q31_t)0xf26da885, (q31_t)0x7f469f7d, (q31_t)0xf267691b, + (q31_t)0x7f45f47b, (q31_t)0xf26129ba, (q31_t)0x7f45492b, (q31_t)0xf25aea61, (q31_t)0x7f449d8c, (q31_t)0xf254ab11, (q31_t)0x7f43f19f, (q31_t)0xf24e6bc9, + (q31_t)0x7f434563, (q31_t)0xf2482c8a, (q31_t)0x7f4298d9, (q31_t)0xf241ed53, (q31_t)0x7f41ec01, (q31_t)0xf23bae24, (q31_t)0x7f413ed9, (q31_t)0xf2356efe, + (q31_t)0x7f409164, (q31_t)0xf22f2fe1, (q31_t)0x7f3fe3a0, (q31_t)0xf228f0cc, (q31_t)0x7f3f358d, (q31_t)0xf222b1c0, (q31_t)0x7f3e872c, (q31_t)0xf21c72bc, + (q31_t)0x7f3dd87c, (q31_t)0xf21633c0, (q31_t)0x7f3d297e, (q31_t)0xf20ff4ce, (q31_t)0x7f3c7a31, (q31_t)0xf209b5e4, (q31_t)0x7f3bca96, (q31_t)0xf2037702, + (q31_t)0x7f3b1aad, (q31_t)0xf1fd3829, (q31_t)0x7f3a6a75, (q31_t)0xf1f6f959, (q31_t)0x7f39b9ee, (q31_t)0xf1f0ba91, (q31_t)0x7f390919, (q31_t)0xf1ea7bd2, + (q31_t)0x7f3857f6, (q31_t)0xf1e43d1c, (q31_t)0x7f37a684, (q31_t)0xf1ddfe6f, (q31_t)0x7f36f4c3, (q31_t)0xf1d7bfca, (q31_t)0x7f3642b4, (q31_t)0xf1d1812e, + (q31_t)0x7f359057, (q31_t)0xf1cb429a, (q31_t)0x7f34ddab, (q31_t)0xf1c50410, (q31_t)0x7f342ab1, (q31_t)0xf1bec58e, (q31_t)0x7f337768, (q31_t)0xf1b88715, + (q31_t)0x7f32c3d1, (q31_t)0xf1b248a5, (q31_t)0x7f320feb, (q31_t)0xf1ac0a3e, (q31_t)0x7f315bb7, (q31_t)0xf1a5cbdf, (q31_t)0x7f30a734, (q31_t)0xf19f8d89, + (q31_t)0x7f2ff263, (q31_t)0xf1994f3d, (q31_t)0x7f2f3d44, (q31_t)0xf19310f9, (q31_t)0x7f2e87d6, (q31_t)0xf18cd2be, (q31_t)0x7f2dd219, (q31_t)0xf186948c, + (q31_t)0x7f2d1c0e, (q31_t)0xf1805662, (q31_t)0x7f2c65b5, (q31_t)0xf17a1842, (q31_t)0x7f2baf0d, (q31_t)0xf173da2b, (q31_t)0x7f2af817, (q31_t)0xf16d9c1d, + (q31_t)0x7f2a40d2, (q31_t)0xf1675e17, (q31_t)0x7f29893f, (q31_t)0xf161201b, (q31_t)0x7f28d15d, (q31_t)0xf15ae228, (q31_t)0x7f28192d, (q31_t)0xf154a43d, + (q31_t)0x7f2760af, (q31_t)0xf14e665c, (q31_t)0x7f26a7e2, (q31_t)0xf1482884, (q31_t)0x7f25eec7, (q31_t)0xf141eab5, (q31_t)0x7f25355d, (q31_t)0xf13bacef, + (q31_t)0x7f247ba5, (q31_t)0xf1356f32, (q31_t)0x7f23c19e, (q31_t)0xf12f317e, (q31_t)0x7f230749, (q31_t)0xf128f3d4, (q31_t)0x7f224ca6, (q31_t)0xf122b632, + (q31_t)0x7f2191b4, (q31_t)0xf11c789a, (q31_t)0x7f20d674, (q31_t)0xf1163b0b, (q31_t)0x7f201ae5, (q31_t)0xf10ffd85, (q31_t)0x7f1f5f08, (q31_t)0xf109c009, + (q31_t)0x7f1ea2dc, (q31_t)0xf1038295, (q31_t)0x7f1de662, (q31_t)0xf0fd452b, (q31_t)0x7f1d299a, (q31_t)0xf0f707ca, (q31_t)0x7f1c6c83, (q31_t)0xf0f0ca72, + (q31_t)0x7f1baf1e, (q31_t)0xf0ea8d24, (q31_t)0x7f1af16a, (q31_t)0xf0e44fdf, (q31_t)0x7f1a3368, (q31_t)0xf0de12a3, (q31_t)0x7f197518, (q31_t)0xf0d7d571, + (q31_t)0x7f18b679, (q31_t)0xf0d19848, (q31_t)0x7f17f78c, (q31_t)0xf0cb5b28, (q31_t)0x7f173850, (q31_t)0xf0c51e12, (q31_t)0x7f1678c6, (q31_t)0xf0bee105, + (q31_t)0x7f15b8ee, (q31_t)0xf0b8a401, (q31_t)0x7f14f8c7, (q31_t)0xf0b26707, (q31_t)0x7f143852, (q31_t)0xf0ac2a16, (q31_t)0x7f13778e, (q31_t)0xf0a5ed2f, + (q31_t)0x7f12b67c, (q31_t)0xf09fb051, (q31_t)0x7f11f51c, (q31_t)0xf099737d, (q31_t)0x7f11336d, (q31_t)0xf09336b2, (q31_t)0x7f107170, (q31_t)0xf08cf9f1, + (q31_t)0x7f0faf25, (q31_t)0xf086bd39, (q31_t)0x7f0eec8b, (q31_t)0xf080808b, (q31_t)0x7f0e29a3, (q31_t)0xf07a43e7, (q31_t)0x7f0d666c, (q31_t)0xf074074c, + (q31_t)0x7f0ca2e7, (q31_t)0xf06dcaba, (q31_t)0x7f0bdf14, (q31_t)0xf0678e32, (q31_t)0x7f0b1af2, (q31_t)0xf06151b4, (q31_t)0x7f0a5682, (q31_t)0xf05b1540, + (q31_t)0x7f0991c4, (q31_t)0xf054d8d5, (q31_t)0x7f08ccb7, (q31_t)0xf04e9c73, (q31_t)0x7f08075c, (q31_t)0xf048601c, (q31_t)0x7f0741b2, (q31_t)0xf04223ce, + (q31_t)0x7f067bba, (q31_t)0xf03be78a, (q31_t)0x7f05b574, (q31_t)0xf035ab4f, (q31_t)0x7f04eedf, (q31_t)0xf02f6f1f, (q31_t)0x7f0427fc, (q31_t)0xf02932f8, + (q31_t)0x7f0360cb, (q31_t)0xf022f6da, (q31_t)0x7f02994b, (q31_t)0xf01cbac7, (q31_t)0x7f01d17d, (q31_t)0xf0167ebd, (q31_t)0x7f010961, (q31_t)0xf01042be, + (q31_t)0x7f0040f6, (q31_t)0xf00a06c8, (q31_t)0x7eff783d, (q31_t)0xf003cadc, (q31_t)0x7efeaf36, (q31_t)0xeffd8ef9, (q31_t)0x7efde5e0, (q31_t)0xeff75321, + (q31_t)0x7efd1c3c, (q31_t)0xeff11753, (q31_t)0x7efc524a, (q31_t)0xefeadb8e, (q31_t)0x7efb8809, (q31_t)0xefe49fd3, (q31_t)0x7efabd7a, (q31_t)0xefde6423, + (q31_t)0x7ef9f29d, (q31_t)0xefd8287c, (q31_t)0x7ef92771, (q31_t)0xefd1ecdf, (q31_t)0x7ef85bf7, (q31_t)0xefcbb14c, (q31_t)0x7ef7902f, (q31_t)0xefc575c3, + (q31_t)0x7ef6c418, (q31_t)0xefbf3a45, (q31_t)0x7ef5f7b3, (q31_t)0xefb8fed0, (q31_t)0x7ef52b00, (q31_t)0xefb2c365, (q31_t)0x7ef45dfe, (q31_t)0xefac8804, + (q31_t)0x7ef390ae, (q31_t)0xefa64cae, (q31_t)0x7ef2c310, (q31_t)0xefa01161, (q31_t)0x7ef1f524, (q31_t)0xef99d61f, (q31_t)0x7ef126e9, (q31_t)0xef939ae6, + (q31_t)0x7ef05860, (q31_t)0xef8d5fb8, (q31_t)0x7eef8988, (q31_t)0xef872494, (q31_t)0x7eeeba62, (q31_t)0xef80e97a, (q31_t)0x7eedeaee, (q31_t)0xef7aae6b, + (q31_t)0x7eed1b2c, (q31_t)0xef747365, (q31_t)0x7eec4b1b, (q31_t)0xef6e386a, (q31_t)0x7eeb7abc, (q31_t)0xef67fd79, (q31_t)0x7eeaaa0f, (q31_t)0xef61c292, + (q31_t)0x7ee9d914, (q31_t)0xef5b87b5, (q31_t)0x7ee907ca, (q31_t)0xef554ce3, (q31_t)0x7ee83632, (q31_t)0xef4f121b, (q31_t)0x7ee7644c, (q31_t)0xef48d75d, + (q31_t)0x7ee69217, (q31_t)0xef429caa, (q31_t)0x7ee5bf94, (q31_t)0xef3c6201, (q31_t)0x7ee4ecc3, (q31_t)0xef362762, (q31_t)0x7ee419a3, (q31_t)0xef2feccd, + (q31_t)0x7ee34636, (q31_t)0xef29b243, (q31_t)0x7ee2727a, (q31_t)0xef2377c4, (q31_t)0x7ee19e6f, (q31_t)0xef1d3d4e, (q31_t)0x7ee0ca17, (q31_t)0xef1702e4, + (q31_t)0x7edff570, (q31_t)0xef10c883, (q31_t)0x7edf207b, (q31_t)0xef0a8e2d, (q31_t)0x7ede4b38, (q31_t)0xef0453e2, (q31_t)0x7edd75a6, (q31_t)0xeefe19a1, + (q31_t)0x7edc9fc6, (q31_t)0xeef7df6a, (q31_t)0x7edbc998, (q31_t)0xeef1a53e, (q31_t)0x7edaf31c, (q31_t)0xeeeb6b1c, (q31_t)0x7eda1c51, (q31_t)0xeee53105, + (q31_t)0x7ed94538, (q31_t)0xeedef6f9, (q31_t)0x7ed86dd1, (q31_t)0xeed8bcf7, (q31_t)0x7ed7961c, (q31_t)0xeed28300, (q31_t)0x7ed6be18, (q31_t)0xeecc4913, + (q31_t)0x7ed5e5c6, (q31_t)0xeec60f31, (q31_t)0x7ed50d26, (q31_t)0xeebfd55a, (q31_t)0x7ed43438, (q31_t)0xeeb99b8d, (q31_t)0x7ed35afb, (q31_t)0xeeb361cb, + (q31_t)0x7ed28171, (q31_t)0xeead2813, (q31_t)0x7ed1a798, (q31_t)0xeea6ee66, (q31_t)0x7ed0cd70, (q31_t)0xeea0b4c4, (q31_t)0x7ecff2fb, (q31_t)0xee9a7b2d, + (q31_t)0x7ecf1837, (q31_t)0xee9441a0, (q31_t)0x7ece3d25, (q31_t)0xee8e081e, (q31_t)0x7ecd61c5, (q31_t)0xee87cea7, (q31_t)0x7ecc8617, (q31_t)0xee81953b, + (q31_t)0x7ecbaa1a, (q31_t)0xee7b5bd9, (q31_t)0x7ecacdd0, (q31_t)0xee752283, (q31_t)0x7ec9f137, (q31_t)0xee6ee937, (q31_t)0x7ec9144f, (q31_t)0xee68aff6, + (q31_t)0x7ec8371a, (q31_t)0xee6276bf, (q31_t)0x7ec75996, (q31_t)0xee5c3d94, (q31_t)0x7ec67bc5, (q31_t)0xee560473, (q31_t)0x7ec59da5, (q31_t)0xee4fcb5e, + (q31_t)0x7ec4bf36, (q31_t)0xee499253, (q31_t)0x7ec3e07a, (q31_t)0xee435953, (q31_t)0x7ec3016f, (q31_t)0xee3d205e, (q31_t)0x7ec22217, (q31_t)0xee36e775, + (q31_t)0x7ec14270, (q31_t)0xee30ae96, (q31_t)0x7ec0627a, (q31_t)0xee2a75c2, (q31_t)0x7ebf8237, (q31_t)0xee243cf9, (q31_t)0x7ebea1a6, (q31_t)0xee1e043b, + (q31_t)0x7ebdc0c6, (q31_t)0xee17cb88, (q31_t)0x7ebcdf98, (q31_t)0xee1192e0, (q31_t)0x7ebbfe1c, (q31_t)0xee0b5a43, (q31_t)0x7ebb1c52, (q31_t)0xee0521b2, + (q31_t)0x7eba3a39, (q31_t)0xedfee92b, (q31_t)0x7eb957d2, (q31_t)0xedf8b0b0, (q31_t)0x7eb8751e, (q31_t)0xedf2783f, (q31_t)0x7eb7921b, (q31_t)0xedec3fda, + (q31_t)0x7eb6aeca, (q31_t)0xede60780, (q31_t)0x7eb5cb2a, (q31_t)0xeddfcf31, (q31_t)0x7eb4e73d, (q31_t)0xedd996ed, (q31_t)0x7eb40301, (q31_t)0xedd35eb5, + (q31_t)0x7eb31e78, (q31_t)0xedcd2687, (q31_t)0x7eb239a0, (q31_t)0xedc6ee65, (q31_t)0x7eb1547a, (q31_t)0xedc0b64e, (q31_t)0x7eb06f05, (q31_t)0xedba7e43, + (q31_t)0x7eaf8943, (q31_t)0xedb44642, (q31_t)0x7eaea333, (q31_t)0xedae0e4d, (q31_t)0x7eadbcd4, (q31_t)0xeda7d664, (q31_t)0x7eacd627, (q31_t)0xeda19e85, + (q31_t)0x7eabef2c, (q31_t)0xed9b66b2, (q31_t)0x7eab07e3, (q31_t)0xed952eea, (q31_t)0x7eaa204c, (q31_t)0xed8ef72e, (q31_t)0x7ea93867, (q31_t)0xed88bf7d, + (q31_t)0x7ea85033, (q31_t)0xed8287d7, (q31_t)0x7ea767b2, (q31_t)0xed7c503d, (q31_t)0x7ea67ee2, (q31_t)0xed7618ae, (q31_t)0x7ea595c4, (q31_t)0xed6fe12b, + (q31_t)0x7ea4ac58, (q31_t)0xed69a9b3, (q31_t)0x7ea3c29e, (q31_t)0xed637246, (q31_t)0x7ea2d896, (q31_t)0xed5d3ae5, (q31_t)0x7ea1ee3f, (q31_t)0xed570390, + (q31_t)0x7ea1039b, (q31_t)0xed50cc46, (q31_t)0x7ea018a8, (q31_t)0xed4a9507, (q31_t)0x7e9f2d68, (q31_t)0xed445dd5, (q31_t)0x7e9e41d9, (q31_t)0xed3e26ad, + (q31_t)0x7e9d55fc, (q31_t)0xed37ef91, (q31_t)0x7e9c69d1, (q31_t)0xed31b881, (q31_t)0x7e9b7d58, (q31_t)0xed2b817d, (q31_t)0x7e9a9091, (q31_t)0xed254a84, + (q31_t)0x7e99a37c, (q31_t)0xed1f1396, (q31_t)0x7e98b618, (q31_t)0xed18dcb5, (q31_t)0x7e97c867, (q31_t)0xed12a5df, (q31_t)0x7e96da67, (q31_t)0xed0c6f14, + (q31_t)0x7e95ec1a, (q31_t)0xed063856, (q31_t)0x7e94fd7e, (q31_t)0xed0001a3, (q31_t)0x7e940e94, (q31_t)0xecf9cafb, (q31_t)0x7e931f5c, (q31_t)0xecf39460, + (q31_t)0x7e922fd6, (q31_t)0xeced5dd0, (q31_t)0x7e914002, (q31_t)0xece7274c, (q31_t)0x7e904fe0, (q31_t)0xece0f0d4, (q31_t)0x7e8f5f70, (q31_t)0xecdaba67, + (q31_t)0x7e8e6eb2, (q31_t)0xecd48407, (q31_t)0x7e8d7da6, (q31_t)0xecce4db2, (q31_t)0x7e8c8c4b, (q31_t)0xecc81769, (q31_t)0x7e8b9aa3, (q31_t)0xecc1e12c, + (q31_t)0x7e8aa8ac, (q31_t)0xecbbaafb, (q31_t)0x7e89b668, (q31_t)0xecb574d5, (q31_t)0x7e88c3d5, (q31_t)0xecaf3ebc, (q31_t)0x7e87d0f5, (q31_t)0xeca908ae, + (q31_t)0x7e86ddc6, (q31_t)0xeca2d2ad, (q31_t)0x7e85ea49, (q31_t)0xec9c9cb7, (q31_t)0x7e84f67e, (q31_t)0xec9666cd, (q31_t)0x7e840265, (q31_t)0xec9030f0, + (q31_t)0x7e830dff, (q31_t)0xec89fb1e, (q31_t)0x7e82194a, (q31_t)0xec83c558, (q31_t)0x7e812447, (q31_t)0xec7d8f9e, (q31_t)0x7e802ef6, (q31_t)0xec7759f1, + (q31_t)0x7e7f3957, (q31_t)0xec71244f, (q31_t)0x7e7e436a, (q31_t)0xec6aeeba, (q31_t)0x7e7d4d2f, (q31_t)0xec64b930, (q31_t)0x7e7c56a5, (q31_t)0xec5e83b3, + (q31_t)0x7e7b5fce, (q31_t)0xec584e41, (q31_t)0x7e7a68a9, (q31_t)0xec5218dc, (q31_t)0x7e797136, (q31_t)0xec4be383, (q31_t)0x7e787975, (q31_t)0xec45ae36, + (q31_t)0x7e778166, (q31_t)0xec3f78f6, (q31_t)0x7e768908, (q31_t)0xec3943c1, (q31_t)0x7e75905d, (q31_t)0xec330e99, (q31_t)0x7e749764, (q31_t)0xec2cd97d, + (q31_t)0x7e739e1d, (q31_t)0xec26a46d, (q31_t)0x7e72a488, (q31_t)0xec206f69, (q31_t)0x7e71aaa4, (q31_t)0xec1a3a72, (q31_t)0x7e70b073, (q31_t)0xec140587, + (q31_t)0x7e6fb5f4, (q31_t)0xec0dd0a8, (q31_t)0x7e6ebb27, (q31_t)0xec079bd6, (q31_t)0x7e6dc00c, (q31_t)0xec01670f, (q31_t)0x7e6cc4a2, (q31_t)0xebfb3256, + (q31_t)0x7e6bc8eb, (q31_t)0xebf4fda8, (q31_t)0x7e6acce6, (q31_t)0xebeec907, (q31_t)0x7e69d093, (q31_t)0xebe89472, (q31_t)0x7e68d3f2, (q31_t)0xebe25fea, + (q31_t)0x7e67d703, (q31_t)0xebdc2b6e, (q31_t)0x7e66d9c6, (q31_t)0xebd5f6fe, (q31_t)0x7e65dc3b, (q31_t)0xebcfc29b, (q31_t)0x7e64de62, (q31_t)0xebc98e45, + (q31_t)0x7e63e03b, (q31_t)0xebc359fb, (q31_t)0x7e62e1c6, (q31_t)0xebbd25bd, (q31_t)0x7e61e303, (q31_t)0xebb6f18c, (q31_t)0x7e60e3f2, (q31_t)0xebb0bd67, + (q31_t)0x7e5fe493, (q31_t)0xebaa894f, (q31_t)0x7e5ee4e6, (q31_t)0xeba45543, (q31_t)0x7e5de4ec, (q31_t)0xeb9e2144, (q31_t)0x7e5ce4a3, (q31_t)0xeb97ed52, + (q31_t)0x7e5be40c, (q31_t)0xeb91b96c, (q31_t)0x7e5ae328, (q31_t)0xeb8b8593, (q31_t)0x7e59e1f5, (q31_t)0xeb8551c6, (q31_t)0x7e58e075, (q31_t)0xeb7f1e06, + (q31_t)0x7e57dea7, (q31_t)0xeb78ea52, (q31_t)0x7e56dc8a, (q31_t)0xeb72b6ac, (q31_t)0x7e55da20, (q31_t)0xeb6c8312, (q31_t)0x7e54d768, (q31_t)0xeb664f84, + (q31_t)0x7e53d462, (q31_t)0xeb601c04, (q31_t)0x7e52d10e, (q31_t)0xeb59e890, (q31_t)0x7e51cd6c, (q31_t)0xeb53b529, (q31_t)0x7e50c97c, (q31_t)0xeb4d81ce, + (q31_t)0x7e4fc53e, (q31_t)0xeb474e81, (q31_t)0x7e4ec0b2, (q31_t)0xeb411b40, (q31_t)0x7e4dbbd9, (q31_t)0xeb3ae80c, (q31_t)0x7e4cb6b1, (q31_t)0xeb34b4e4, + (q31_t)0x7e4bb13c, (q31_t)0xeb2e81ca, (q31_t)0x7e4aab78, (q31_t)0xeb284ebc, (q31_t)0x7e49a567, (q31_t)0xeb221bbb, (q31_t)0x7e489f08, (q31_t)0xeb1be8c8, + (q31_t)0x7e47985b, (q31_t)0xeb15b5e1, (q31_t)0x7e469160, (q31_t)0xeb0f8307, (q31_t)0x7e458a17, (q31_t)0xeb095039, (q31_t)0x7e448281, (q31_t)0xeb031d79, + (q31_t)0x7e437a9c, (q31_t)0xeafceac6, (q31_t)0x7e427269, (q31_t)0xeaf6b81f, (q31_t)0x7e4169e9, (q31_t)0xeaf08586, (q31_t)0x7e40611b, (q31_t)0xeaea52fa, + (q31_t)0x7e3f57ff, (q31_t)0xeae4207a, (q31_t)0x7e3e4e95, (q31_t)0xeaddee08, (q31_t)0x7e3d44dd, (q31_t)0xead7bba3, (q31_t)0x7e3c3ad7, (q31_t)0xead1894b, + (q31_t)0x7e3b3083, (q31_t)0xeacb56ff, (q31_t)0x7e3a25e2, (q31_t)0xeac524c1, (q31_t)0x7e391af3, (q31_t)0xeabef290, (q31_t)0x7e380fb5, (q31_t)0xeab8c06c, + (q31_t)0x7e37042a, (q31_t)0xeab28e56, (q31_t)0x7e35f851, (q31_t)0xeaac5c4c, (q31_t)0x7e34ec2b, (q31_t)0xeaa62a4f, (q31_t)0x7e33dfb6, (q31_t)0xea9ff860, + (q31_t)0x7e32d2f4, (q31_t)0xea99c67e, (q31_t)0x7e31c5e3, (q31_t)0xea9394a9, (q31_t)0x7e30b885, (q31_t)0xea8d62e1, (q31_t)0x7e2faad9, (q31_t)0xea873127, + (q31_t)0x7e2e9cdf, (q31_t)0xea80ff7a, (q31_t)0x7e2d8e97, (q31_t)0xea7acdda, (q31_t)0x7e2c8002, (q31_t)0xea749c47, (q31_t)0x7e2b711f, (q31_t)0xea6e6ac2, + (q31_t)0x7e2a61ed, (q31_t)0xea683949, (q31_t)0x7e29526e, (q31_t)0xea6207df, (q31_t)0x7e2842a2, (q31_t)0xea5bd681, (q31_t)0x7e273287, (q31_t)0xea55a531, + (q31_t)0x7e26221f, (q31_t)0xea4f73ee, (q31_t)0x7e251168, (q31_t)0xea4942b9, (q31_t)0x7e240064, (q31_t)0xea431191, (q31_t)0x7e22ef12, (q31_t)0xea3ce077, + (q31_t)0x7e21dd73, (q31_t)0xea36af69, (q31_t)0x7e20cb85, (q31_t)0xea307e6a, (q31_t)0x7e1fb94a, (q31_t)0xea2a4d78, (q31_t)0x7e1ea6c1, (q31_t)0xea241c93, + (q31_t)0x7e1d93ea, (q31_t)0xea1debbb, (q31_t)0x7e1c80c5, (q31_t)0xea17baf2, (q31_t)0x7e1b6d53, (q31_t)0xea118a35, (q31_t)0x7e1a5992, (q31_t)0xea0b5987, + (q31_t)0x7e194584, (q31_t)0xea0528e5, (q31_t)0x7e183128, (q31_t)0xe9fef852, (q31_t)0x7e171c7f, (q31_t)0xe9f8c7cc, (q31_t)0x7e160787, (q31_t)0xe9f29753, + (q31_t)0x7e14f242, (q31_t)0xe9ec66e8, (q31_t)0x7e13dcaf, (q31_t)0xe9e6368b, (q31_t)0x7e12c6ce, (q31_t)0xe9e0063c, (q31_t)0x7e11b0a0, (q31_t)0xe9d9d5fa, + (q31_t)0x7e109a24, (q31_t)0xe9d3a5c5, (q31_t)0x7e0f835a, (q31_t)0xe9cd759f, (q31_t)0x7e0e6c42, (q31_t)0xe9c74586, (q31_t)0x7e0d54dc, (q31_t)0xe9c1157a, + (q31_t)0x7e0c3d29, (q31_t)0xe9bae57d, (q31_t)0x7e0b2528, (q31_t)0xe9b4b58d, (q31_t)0x7e0a0cd9, (q31_t)0xe9ae85ab, (q31_t)0x7e08f43d, (q31_t)0xe9a855d7, + (q31_t)0x7e07db52, (q31_t)0xe9a22610, (q31_t)0x7e06c21a, (q31_t)0xe99bf658, (q31_t)0x7e05a894, (q31_t)0xe995c6ad, (q31_t)0x7e048ec1, (q31_t)0xe98f9710, + (q31_t)0x7e0374a0, (q31_t)0xe9896781, (q31_t)0x7e025a31, (q31_t)0xe98337ff, (q31_t)0x7e013f74, (q31_t)0xe97d088c, (q31_t)0x7e00246a, (q31_t)0xe976d926, + (q31_t)0x7dff0911, (q31_t)0xe970a9ce, (q31_t)0x7dfded6c, (q31_t)0xe96a7a85, (q31_t)0x7dfcd178, (q31_t)0xe9644b49, (q31_t)0x7dfbb537, (q31_t)0xe95e1c1b, + (q31_t)0x7dfa98a8, (q31_t)0xe957ecfb, (q31_t)0x7df97bcb, (q31_t)0xe951bde9, (q31_t)0x7df85ea0, (q31_t)0xe94b8ee5, (q31_t)0x7df74128, (q31_t)0xe9455fef, + (q31_t)0x7df62362, (q31_t)0xe93f3107, (q31_t)0x7df5054f, (q31_t)0xe939022d, (q31_t)0x7df3e6ee, (q31_t)0xe932d361, (q31_t)0x7df2c83f, (q31_t)0xe92ca4a4, + (q31_t)0x7df1a942, (q31_t)0xe92675f4, (q31_t)0x7df089f8, (q31_t)0xe9204752, (q31_t)0x7def6a60, (q31_t)0xe91a18bf, (q31_t)0x7dee4a7a, (q31_t)0xe913ea39, + (q31_t)0x7ded2a47, (q31_t)0xe90dbbc2, (q31_t)0x7dec09c6, (q31_t)0xe9078d59, (q31_t)0x7deae8f7, (q31_t)0xe9015efe, (q31_t)0x7de9c7da, (q31_t)0xe8fb30b1, + (q31_t)0x7de8a670, (q31_t)0xe8f50273, (q31_t)0x7de784b9, (q31_t)0xe8eed443, (q31_t)0x7de662b3, (q31_t)0xe8e8a621, (q31_t)0x7de54060, (q31_t)0xe8e2780d, + (q31_t)0x7de41dc0, (q31_t)0xe8dc4a07, (q31_t)0x7de2fad1, (q31_t)0xe8d61c10, (q31_t)0x7de1d795, (q31_t)0xe8cfee27, (q31_t)0x7de0b40b, (q31_t)0xe8c9c04c, + (q31_t)0x7ddf9034, (q31_t)0xe8c39280, (q31_t)0x7dde6c0f, (q31_t)0xe8bd64c2, (q31_t)0x7ddd479d, (q31_t)0xe8b73712, (q31_t)0x7ddc22dc, (q31_t)0xe8b10971, + (q31_t)0x7ddafdce, (q31_t)0xe8aadbde, (q31_t)0x7dd9d873, (q31_t)0xe8a4ae59, (q31_t)0x7dd8b2ca, (q31_t)0xe89e80e3, (q31_t)0x7dd78cd3, (q31_t)0xe898537b, + (q31_t)0x7dd6668f, (q31_t)0xe8922622, (q31_t)0x7dd53ffc, (q31_t)0xe88bf8d7, (q31_t)0x7dd4191d, (q31_t)0xe885cb9a, (q31_t)0x7dd2f1f0, (q31_t)0xe87f9e6c, + (q31_t)0x7dd1ca75, (q31_t)0xe879714d, (q31_t)0x7dd0a2ac, (q31_t)0xe873443c, (q31_t)0x7dcf7a96, (q31_t)0xe86d173a, (q31_t)0x7dce5232, (q31_t)0xe866ea46, + (q31_t)0x7dcd2981, (q31_t)0xe860bd61, (q31_t)0x7dcc0082, (q31_t)0xe85a908a, (q31_t)0x7dcad736, (q31_t)0xe85463c2, (q31_t)0x7dc9ad9c, (q31_t)0xe84e3708, + (q31_t)0x7dc883b4, (q31_t)0xe8480a5d, (q31_t)0x7dc7597f, (q31_t)0xe841ddc1, (q31_t)0x7dc62efc, (q31_t)0xe83bb133, (q31_t)0x7dc5042b, (q31_t)0xe83584b4, + (q31_t)0x7dc3d90d, (q31_t)0xe82f5844, (q31_t)0x7dc2ada2, (q31_t)0xe8292be3, (q31_t)0x7dc181e8, (q31_t)0xe822ff90, (q31_t)0x7dc055e2, (q31_t)0xe81cd34b, + (q31_t)0x7dbf298d, (q31_t)0xe816a716, (q31_t)0x7dbdfceb, (q31_t)0xe8107aef, (q31_t)0x7dbccffc, (q31_t)0xe80a4ed7, (q31_t)0x7dbba2bf, (q31_t)0xe80422ce, + (q31_t)0x7dba7534, (q31_t)0xe7fdf6d4, (q31_t)0x7db9475c, (q31_t)0xe7f7cae8, (q31_t)0x7db81936, (q31_t)0xe7f19f0c, (q31_t)0x7db6eac3, (q31_t)0xe7eb733e, + (q31_t)0x7db5bc02, (q31_t)0xe7e5477f, (q31_t)0x7db48cf4, (q31_t)0xe7df1bcf, (q31_t)0x7db35d98, (q31_t)0xe7d8f02d, (q31_t)0x7db22def, (q31_t)0xe7d2c49b, + (q31_t)0x7db0fdf8, (q31_t)0xe7cc9917, (q31_t)0x7dafcdb3, (q31_t)0xe7c66da3, (q31_t)0x7dae9d21, (q31_t)0xe7c0423d, (q31_t)0x7dad6c42, (q31_t)0xe7ba16e7, + (q31_t)0x7dac3b15, (q31_t)0xe7b3eb9f, (q31_t)0x7dab099a, (q31_t)0xe7adc066, (q31_t)0x7da9d7d2, (q31_t)0xe7a7953d, (q31_t)0x7da8a5bc, (q31_t)0xe7a16a22, + (q31_t)0x7da77359, (q31_t)0xe79b3f16, (q31_t)0x7da640a9, (q31_t)0xe795141a, (q31_t)0x7da50dab, (q31_t)0xe78ee92c, (q31_t)0x7da3da5f, (q31_t)0xe788be4e, + (q31_t)0x7da2a6c6, (q31_t)0xe782937e, (q31_t)0x7da172df, (q31_t)0xe77c68be, (q31_t)0x7da03eab, (q31_t)0xe7763e0d, (q31_t)0x7d9f0a29, (q31_t)0xe770136b, + (q31_t)0x7d9dd55a, (q31_t)0xe769e8d8, (q31_t)0x7d9ca03e, (q31_t)0xe763be55, (q31_t)0x7d9b6ad3, (q31_t)0xe75d93e0, (q31_t)0x7d9a351c, (q31_t)0xe757697b, + (q31_t)0x7d98ff17, (q31_t)0xe7513f25, (q31_t)0x7d97c8c4, (q31_t)0xe74b14de, (q31_t)0x7d969224, (q31_t)0xe744eaa6, (q31_t)0x7d955b37, (q31_t)0xe73ec07e, + (q31_t)0x7d9423fc, (q31_t)0xe7389665, (q31_t)0x7d92ec73, (q31_t)0xe7326c5b, (q31_t)0x7d91b49e, (q31_t)0xe72c4260, (q31_t)0x7d907c7a, (q31_t)0xe7261875, + (q31_t)0x7d8f4409, (q31_t)0xe71fee99, (q31_t)0x7d8e0b4b, (q31_t)0xe719c4cd, (q31_t)0x7d8cd240, (q31_t)0xe7139b10, (q31_t)0x7d8b98e6, (q31_t)0xe70d7162, + (q31_t)0x7d8a5f40, (q31_t)0xe70747c4, (q31_t)0x7d89254c, (q31_t)0xe7011e35, (q31_t)0x7d87eb0a, (q31_t)0xe6faf4b5, (q31_t)0x7d86b07c, (q31_t)0xe6f4cb45, + (q31_t)0x7d85759f, (q31_t)0xe6eea1e4, (q31_t)0x7d843a76, (q31_t)0xe6e87893, (q31_t)0x7d82fefe, (q31_t)0xe6e24f51, (q31_t)0x7d81c33a, (q31_t)0xe6dc261f, + (q31_t)0x7d808728, (q31_t)0xe6d5fcfc, (q31_t)0x7d7f4ac8, (q31_t)0xe6cfd3e9, (q31_t)0x7d7e0e1c, (q31_t)0xe6c9aae5, (q31_t)0x7d7cd121, (q31_t)0xe6c381f1, + (q31_t)0x7d7b93da, (q31_t)0xe6bd590d, (q31_t)0x7d7a5645, (q31_t)0xe6b73038, (q31_t)0x7d791862, (q31_t)0xe6b10772, (q31_t)0x7d77da32, (q31_t)0xe6aadebc, + (q31_t)0x7d769bb5, (q31_t)0xe6a4b616, (q31_t)0x7d755cea, (q31_t)0xe69e8d80, (q31_t)0x7d741dd2, (q31_t)0xe69864f9, (q31_t)0x7d72de6d, (q31_t)0xe6923c82, + (q31_t)0x7d719eba, (q31_t)0xe68c141a, (q31_t)0x7d705eba, (q31_t)0xe685ebc2, (q31_t)0x7d6f1e6c, (q31_t)0xe67fc37a, (q31_t)0x7d6dddd2, (q31_t)0xe6799b42, + (q31_t)0x7d6c9ce9, (q31_t)0xe6737319, (q31_t)0x7d6b5bb4, (q31_t)0xe66d4b01, (q31_t)0x7d6a1a31, (q31_t)0xe66722f7, (q31_t)0x7d68d860, (q31_t)0xe660fafe, + (q31_t)0x7d679642, (q31_t)0xe65ad315, (q31_t)0x7d6653d7, (q31_t)0xe654ab3b, (q31_t)0x7d65111f, (q31_t)0xe64e8371, (q31_t)0x7d63ce19, (q31_t)0xe6485bb7, + (q31_t)0x7d628ac6, (q31_t)0xe642340d, (q31_t)0x7d614725, (q31_t)0xe63c0c73, (q31_t)0x7d600338, (q31_t)0xe635e4e9, (q31_t)0x7d5ebefc, (q31_t)0xe62fbd6e, + (q31_t)0x7d5d7a74, (q31_t)0xe6299604, (q31_t)0x7d5c359e, (q31_t)0xe6236ea9, (q31_t)0x7d5af07b, (q31_t)0xe61d475e, (q31_t)0x7d59ab0a, (q31_t)0xe6172024, + (q31_t)0x7d58654d, (q31_t)0xe610f8f9, (q31_t)0x7d571f41, (q31_t)0xe60ad1de, (q31_t)0x7d55d8e9, (q31_t)0xe604aad4, (q31_t)0x7d549243, (q31_t)0xe5fe83d9, + (q31_t)0x7d534b50, (q31_t)0xe5f85cef, (q31_t)0x7d520410, (q31_t)0xe5f23614, (q31_t)0x7d50bc82, (q31_t)0xe5ec0f4a, (q31_t)0x7d4f74a7, (q31_t)0xe5e5e88f, + (q31_t)0x7d4e2c7f, (q31_t)0xe5dfc1e5, (q31_t)0x7d4ce409, (q31_t)0xe5d99b4b, (q31_t)0x7d4b9b46, (q31_t)0xe5d374c1, (q31_t)0x7d4a5236, (q31_t)0xe5cd4e47, + (q31_t)0x7d4908d9, (q31_t)0xe5c727dd, (q31_t)0x7d47bf2e, (q31_t)0xe5c10184, (q31_t)0x7d467536, (q31_t)0xe5badb3a, (q31_t)0x7d452af1, (q31_t)0xe5b4b501, + (q31_t)0x7d43e05e, (q31_t)0xe5ae8ed8, (q31_t)0x7d42957e, (q31_t)0xe5a868bf, (q31_t)0x7d414a51, (q31_t)0xe5a242b7, (q31_t)0x7d3ffed7, (q31_t)0xe59c1cbf, + (q31_t)0x7d3eb30f, (q31_t)0xe595f6d7, (q31_t)0x7d3d66fa, (q31_t)0xe58fd0ff, (q31_t)0x7d3c1a98, (q31_t)0xe589ab38, (q31_t)0x7d3acde9, (q31_t)0xe5838581, + (q31_t)0x7d3980ec, (q31_t)0xe57d5fda, (q31_t)0x7d3833a2, (q31_t)0xe5773a44, (q31_t)0x7d36e60b, (q31_t)0xe57114be, (q31_t)0x7d359827, (q31_t)0xe56aef49, + (q31_t)0x7d3449f5, (q31_t)0xe564c9e3, (q31_t)0x7d32fb76, (q31_t)0xe55ea48f, (q31_t)0x7d31acaa, (q31_t)0xe5587f4a, (q31_t)0x7d305d91, (q31_t)0xe5525a17, + (q31_t)0x7d2f0e2b, (q31_t)0xe54c34f3, (q31_t)0x7d2dbe77, (q31_t)0xe5460fe0, (q31_t)0x7d2c6e76, (q31_t)0xe53feade, (q31_t)0x7d2b1e28, (q31_t)0xe539c5ec, + (q31_t)0x7d29cd8c, (q31_t)0xe533a10a, (q31_t)0x7d287ca4, (q31_t)0xe52d7c39, (q31_t)0x7d272b6e, (q31_t)0xe5275779, (q31_t)0x7d25d9eb, (q31_t)0xe52132c9, + (q31_t)0x7d24881b, (q31_t)0xe51b0e2a, (q31_t)0x7d2335fe, (q31_t)0xe514e99b, (q31_t)0x7d21e393, (q31_t)0xe50ec51d, (q31_t)0x7d2090db, (q31_t)0xe508a0b0, + (q31_t)0x7d1f3dd6, (q31_t)0xe5027c53, (q31_t)0x7d1dea84, (q31_t)0xe4fc5807, (q31_t)0x7d1c96e5, (q31_t)0xe4f633cc, (q31_t)0x7d1b42f9, (q31_t)0xe4f00fa1, + (q31_t)0x7d19eebf, (q31_t)0xe4e9eb87, (q31_t)0x7d189a38, (q31_t)0xe4e3c77d, (q31_t)0x7d174564, (q31_t)0xe4dda385, (q31_t)0x7d15f043, (q31_t)0xe4d77f9d, + (q31_t)0x7d149ad5, (q31_t)0xe4d15bc6, (q31_t)0x7d134519, (q31_t)0xe4cb37ff, (q31_t)0x7d11ef11, (q31_t)0xe4c5144a, (q31_t)0x7d1098bb, (q31_t)0xe4bef0a5, + (q31_t)0x7d0f4218, (q31_t)0xe4b8cd11, (q31_t)0x7d0deb28, (q31_t)0xe4b2a98e, (q31_t)0x7d0c93eb, (q31_t)0xe4ac861b, (q31_t)0x7d0b3c60, (q31_t)0xe4a662ba, + (q31_t)0x7d09e489, (q31_t)0xe4a03f69, (q31_t)0x7d088c64, (q31_t)0xe49a1c29, (q31_t)0x7d0733f3, (q31_t)0xe493f8fb, (q31_t)0x7d05db34, (q31_t)0xe48dd5dd, + (q31_t)0x7d048228, (q31_t)0xe487b2d0, (q31_t)0x7d0328cf, (q31_t)0xe4818fd4, (q31_t)0x7d01cf29, (q31_t)0xe47b6ce9, (q31_t)0x7d007535, (q31_t)0xe4754a0e, + (q31_t)0x7cff1af5, (q31_t)0xe46f2745, (q31_t)0x7cfdc068, (q31_t)0xe469048d, (q31_t)0x7cfc658d, (q31_t)0xe462e1e6, (q31_t)0x7cfb0a65, (q31_t)0xe45cbf50, + (q31_t)0x7cf9aef0, (q31_t)0xe4569ccb, (q31_t)0x7cf8532f, (q31_t)0xe4507a57, (q31_t)0x7cf6f720, (q31_t)0xe44a57f4, (q31_t)0x7cf59ac4, (q31_t)0xe44435a2, + (q31_t)0x7cf43e1a, (q31_t)0xe43e1362, (q31_t)0x7cf2e124, (q31_t)0xe437f132, (q31_t)0x7cf183e1, (q31_t)0xe431cf14, (q31_t)0x7cf02651, (q31_t)0xe42bad07, + (q31_t)0x7ceec873, (q31_t)0xe4258b0a, (q31_t)0x7ced6a49, (q31_t)0xe41f6920, (q31_t)0x7cec0bd1, (q31_t)0xe4194746, (q31_t)0x7ceaad0c, (q31_t)0xe413257d, + (q31_t)0x7ce94dfb, (q31_t)0xe40d03c6, (q31_t)0x7ce7ee9c, (q31_t)0xe406e220, (q31_t)0x7ce68ef0, (q31_t)0xe400c08b, (q31_t)0x7ce52ef7, (q31_t)0xe3fa9f08, + (q31_t)0x7ce3ceb2, (q31_t)0xe3f47d96, (q31_t)0x7ce26e1f, (q31_t)0xe3ee5c35, (q31_t)0x7ce10d3f, (q31_t)0xe3e83ae5, (q31_t)0x7cdfac12, (q31_t)0xe3e219a7, + (q31_t)0x7cde4a98, (q31_t)0xe3dbf87a, (q31_t)0x7cdce8d1, (q31_t)0xe3d5d75e, (q31_t)0x7cdb86bd, (q31_t)0xe3cfb654, (q31_t)0x7cda245c, (q31_t)0xe3c9955b, + (q31_t)0x7cd8c1ae, (q31_t)0xe3c37474, (q31_t)0x7cd75eb3, (q31_t)0xe3bd539e, (q31_t)0x7cd5fb6a, (q31_t)0xe3b732d9, (q31_t)0x7cd497d5, (q31_t)0xe3b11226, + (q31_t)0x7cd333f3, (q31_t)0xe3aaf184, (q31_t)0x7cd1cfc4, (q31_t)0xe3a4d0f4, (q31_t)0x7cd06b48, (q31_t)0xe39eb075, (q31_t)0x7ccf067f, (q31_t)0xe3989008, + (q31_t)0x7ccda169, (q31_t)0xe3926fad, (q31_t)0x7ccc3c06, (q31_t)0xe38c4f63, (q31_t)0x7ccad656, (q31_t)0xe3862f2a, (q31_t)0x7cc97059, (q31_t)0xe3800f03, + (q31_t)0x7cc80a0f, (q31_t)0xe379eeed, (q31_t)0x7cc6a378, (q31_t)0xe373ceea, (q31_t)0x7cc53c94, (q31_t)0xe36daef7, (q31_t)0x7cc3d563, (q31_t)0xe3678f17, + (q31_t)0x7cc26de5, (q31_t)0xe3616f48, (q31_t)0x7cc1061a, (q31_t)0xe35b4f8b, (q31_t)0x7cbf9e03, (q31_t)0xe3552fdf, (q31_t)0x7cbe359e, (q31_t)0xe34f1045, + (q31_t)0x7cbcccec, (q31_t)0xe348f0bd, (q31_t)0x7cbb63ee, (q31_t)0xe342d146, (q31_t)0x7cb9faa2, (q31_t)0xe33cb1e1, (q31_t)0x7cb8910a, (q31_t)0xe336928e, + (q31_t)0x7cb72724, (q31_t)0xe330734d, (q31_t)0x7cb5bcf2, (q31_t)0xe32a541d, (q31_t)0x7cb45272, (q31_t)0xe3243500, (q31_t)0x7cb2e7a6, (q31_t)0xe31e15f4, + (q31_t)0x7cb17c8d, (q31_t)0xe317f6fa, (q31_t)0x7cb01127, (q31_t)0xe311d811, (q31_t)0x7caea574, (q31_t)0xe30bb93b, (q31_t)0x7cad3974, (q31_t)0xe3059a76, + (q31_t)0x7cabcd28, (q31_t)0xe2ff7bc3, (q31_t)0x7caa608e, (q31_t)0xe2f95d23, (q31_t)0x7ca8f3a7, (q31_t)0xe2f33e94, (q31_t)0x7ca78674, (q31_t)0xe2ed2017, + (q31_t)0x7ca618f3, (q31_t)0xe2e701ac, (q31_t)0x7ca4ab26, (q31_t)0xe2e0e352, (q31_t)0x7ca33d0c, (q31_t)0xe2dac50b, (q31_t)0x7ca1cea5, (q31_t)0xe2d4a6d6, + (q31_t)0x7ca05ff1, (q31_t)0xe2ce88b3, (q31_t)0x7c9ef0f0, (q31_t)0xe2c86aa2, (q31_t)0x7c9d81a3, (q31_t)0xe2c24ca2, (q31_t)0x7c9c1208, (q31_t)0xe2bc2eb5, + (q31_t)0x7c9aa221, (q31_t)0xe2b610da, (q31_t)0x7c9931ec, (q31_t)0xe2aff311, (q31_t)0x7c97c16b, (q31_t)0xe2a9d55a, (q31_t)0x7c96509d, (q31_t)0xe2a3b7b5, + (q31_t)0x7c94df83, (q31_t)0xe29d9a23, (q31_t)0x7c936e1b, (q31_t)0xe2977ca2, (q31_t)0x7c91fc66, (q31_t)0xe2915f34, (q31_t)0x7c908a65, (q31_t)0xe28b41d7, + (q31_t)0x7c8f1817, (q31_t)0xe285248d, (q31_t)0x7c8da57c, (q31_t)0xe27f0755, (q31_t)0x7c8c3294, (q31_t)0xe278ea30, (q31_t)0x7c8abf5f, (q31_t)0xe272cd1c, + (q31_t)0x7c894bde, (q31_t)0xe26cb01b, (q31_t)0x7c87d810, (q31_t)0xe266932c, (q31_t)0x7c8663f4, (q31_t)0xe260764f, (q31_t)0x7c84ef8c, (q31_t)0xe25a5984, + (q31_t)0x7c837ad8, (q31_t)0xe2543ccc, (q31_t)0x7c8205d6, (q31_t)0xe24e2026, (q31_t)0x7c809088, (q31_t)0xe2480393, (q31_t)0x7c7f1aed, (q31_t)0xe241e711, + (q31_t)0x7c7da505, (q31_t)0xe23bcaa2, (q31_t)0x7c7c2ed0, (q31_t)0xe235ae46, (q31_t)0x7c7ab84e, (q31_t)0xe22f91fc, (q31_t)0x7c794180, (q31_t)0xe22975c4, + (q31_t)0x7c77ca65, (q31_t)0xe223599e, (q31_t)0x7c7652fd, (q31_t)0xe21d3d8b, (q31_t)0x7c74db48, (q31_t)0xe217218b, (q31_t)0x7c736347, (q31_t)0xe211059d, + (q31_t)0x7c71eaf9, (q31_t)0xe20ae9c1, (q31_t)0x7c70725e, (q31_t)0xe204cdf8, (q31_t)0x7c6ef976, (q31_t)0xe1feb241, (q31_t)0x7c6d8041, (q31_t)0xe1f8969d, + (q31_t)0x7c6c06c0, (q31_t)0xe1f27b0b, (q31_t)0x7c6a8cf2, (q31_t)0xe1ec5f8c, (q31_t)0x7c6912d7, (q31_t)0xe1e64420, (q31_t)0x7c679870, (q31_t)0xe1e028c6, + (q31_t)0x7c661dbc, (q31_t)0xe1da0d7e, (q31_t)0x7c64a2bb, (q31_t)0xe1d3f24a, (q31_t)0x7c63276d, (q31_t)0xe1cdd727, (q31_t)0x7c61abd3, (q31_t)0xe1c7bc18, + (q31_t)0x7c602fec, (q31_t)0xe1c1a11b, (q31_t)0x7c5eb3b8, (q31_t)0xe1bb8631, (q31_t)0x7c5d3737, (q31_t)0xe1b56b59, (q31_t)0x7c5bba6a, (q31_t)0xe1af5094, + (q31_t)0x7c5a3d50, (q31_t)0xe1a935e2, (q31_t)0x7c58bfe9, (q31_t)0xe1a31b42, (q31_t)0x7c574236, (q31_t)0xe19d00b6, (q31_t)0x7c55c436, (q31_t)0xe196e63c, + (q31_t)0x7c5445e9, (q31_t)0xe190cbd4, (q31_t)0x7c52c74f, (q31_t)0xe18ab180, (q31_t)0x7c514869, (q31_t)0xe184973e, (q31_t)0x7c4fc936, (q31_t)0xe17e7d0f, + (q31_t)0x7c4e49b7, (q31_t)0xe17862f3, (q31_t)0x7c4cc9ea, (q31_t)0xe17248ea, (q31_t)0x7c4b49d2, (q31_t)0xe16c2ef4, (q31_t)0x7c49c96c, (q31_t)0xe1661510, + (q31_t)0x7c4848ba, (q31_t)0xe15ffb3f, (q31_t)0x7c46c7bb, (q31_t)0xe159e182, (q31_t)0x7c45466f, (q31_t)0xe153c7d7, (q31_t)0x7c43c4d7, (q31_t)0xe14dae3f, + (q31_t)0x7c4242f2, (q31_t)0xe14794ba, (q31_t)0x7c40c0c1, (q31_t)0xe1417b48, (q31_t)0x7c3f3e42, (q31_t)0xe13b61e9, (q31_t)0x7c3dbb78, (q31_t)0xe135489d, + (q31_t)0x7c3c3860, (q31_t)0xe12f2f63, (q31_t)0x7c3ab4fc, (q31_t)0xe129163d, (q31_t)0x7c39314b, (q31_t)0xe122fd2a, (q31_t)0x7c37ad4e, (q31_t)0xe11ce42a, + (q31_t)0x7c362904, (q31_t)0xe116cb3d, (q31_t)0x7c34a46d, (q31_t)0xe110b263, (q31_t)0x7c331f8a, (q31_t)0xe10a999c, (q31_t)0x7c319a5a, (q31_t)0xe10480e9, + (q31_t)0x7c3014de, (q31_t)0xe0fe6848, (q31_t)0x7c2e8f15, (q31_t)0xe0f84fbb, (q31_t)0x7c2d08ff, (q31_t)0xe0f23740, (q31_t)0x7c2b829d, (q31_t)0xe0ec1ed9, + (q31_t)0x7c29fbee, (q31_t)0xe0e60685, (q31_t)0x7c2874f3, (q31_t)0xe0dfee44, (q31_t)0x7c26edab, (q31_t)0xe0d9d616, (q31_t)0x7c256616, (q31_t)0xe0d3bdfc, + (q31_t)0x7c23de35, (q31_t)0xe0cda5f5, (q31_t)0x7c225607, (q31_t)0xe0c78e01, (q31_t)0x7c20cd8d, (q31_t)0xe0c17620, (q31_t)0x7c1f44c6, (q31_t)0xe0bb5e53, + (q31_t)0x7c1dbbb3, (q31_t)0xe0b54698, (q31_t)0x7c1c3253, (q31_t)0xe0af2ef2, (q31_t)0x7c1aa8a6, (q31_t)0xe0a9175e, (q31_t)0x7c191ead, (q31_t)0xe0a2ffde, + (q31_t)0x7c179467, (q31_t)0xe09ce871, (q31_t)0x7c1609d5, (q31_t)0xe096d117, (q31_t)0x7c147ef6, (q31_t)0xe090b9d1, (q31_t)0x7c12f3cb, (q31_t)0xe08aa29f, + (q31_t)0x7c116853, (q31_t)0xe0848b7f, (q31_t)0x7c0fdc8f, (q31_t)0xe07e7473, (q31_t)0x7c0e507e, (q31_t)0xe0785d7b, (q31_t)0x7c0cc421, (q31_t)0xe0724696, + (q31_t)0x7c0b3777, (q31_t)0xe06c2fc4, (q31_t)0x7c09aa80, (q31_t)0xe0661906, (q31_t)0x7c081d3d, (q31_t)0xe060025c, (q31_t)0x7c068fae, (q31_t)0xe059ebc5, + (q31_t)0x7c0501d2, (q31_t)0xe053d541, (q31_t)0x7c0373a9, (q31_t)0xe04dbed1, (q31_t)0x7c01e534, (q31_t)0xe047a875, (q31_t)0x7c005673, (q31_t)0xe041922c, + (q31_t)0x7bfec765, (q31_t)0xe03b7bf6, (q31_t)0x7bfd380a, (q31_t)0xe03565d5, (q31_t)0x7bfba863, (q31_t)0xe02f4fc6, (q31_t)0x7bfa1870, (q31_t)0xe02939cc, + (q31_t)0x7bf88830, (q31_t)0xe02323e5, (q31_t)0x7bf6f7a4, (q31_t)0xe01d0e12, (q31_t)0x7bf566cb, (q31_t)0xe016f852, (q31_t)0x7bf3d5a6, (q31_t)0xe010e2a7, + (q31_t)0x7bf24434, (q31_t)0xe00acd0e, (q31_t)0x7bf0b276, (q31_t)0xe004b78a, (q31_t)0x7bef206b, (q31_t)0xdffea219, (q31_t)0x7bed8e14, (q31_t)0xdff88cbc, + (q31_t)0x7bebfb70, (q31_t)0xdff27773, (q31_t)0x7bea6880, (q31_t)0xdfec623e, (q31_t)0x7be8d544, (q31_t)0xdfe64d1c, (q31_t)0x7be741bb, (q31_t)0xdfe0380e, + (q31_t)0x7be5ade6, (q31_t)0xdfda2314, (q31_t)0x7be419c4, (q31_t)0xdfd40e2e, (q31_t)0x7be28556, (q31_t)0xdfcdf95c, (q31_t)0x7be0f09b, (q31_t)0xdfc7e49d, + (q31_t)0x7bdf5b94, (q31_t)0xdfc1cff3, (q31_t)0x7bddc641, (q31_t)0xdfbbbb5c, (q31_t)0x7bdc30a1, (q31_t)0xdfb5a6d9, (q31_t)0x7bda9ab5, (q31_t)0xdfaf926a, + (q31_t)0x7bd9047c, (q31_t)0xdfa97e0f, (q31_t)0x7bd76df7, (q31_t)0xdfa369c8, (q31_t)0x7bd5d726, (q31_t)0xdf9d5595, (q31_t)0x7bd44008, (q31_t)0xdf974176, + (q31_t)0x7bd2a89e, (q31_t)0xdf912d6b, (q31_t)0x7bd110e8, (q31_t)0xdf8b1974, (q31_t)0x7bcf78e5, (q31_t)0xdf850591, (q31_t)0x7bcde095, (q31_t)0xdf7ef1c2, + (q31_t)0x7bcc47fa, (q31_t)0xdf78de07, (q31_t)0x7bcaaf12, (q31_t)0xdf72ca60, (q31_t)0x7bc915dd, (q31_t)0xdf6cb6cd, (q31_t)0x7bc77c5d, (q31_t)0xdf66a34e, + (q31_t)0x7bc5e290, (q31_t)0xdf608fe4, (q31_t)0x7bc44876, (q31_t)0xdf5a7c8d, (q31_t)0x7bc2ae10, (q31_t)0xdf54694b, (q31_t)0x7bc1135e, (q31_t)0xdf4e561c, + (q31_t)0x7bbf7860, (q31_t)0xdf484302, (q31_t)0x7bbddd15, (q31_t)0xdf422ffd, (q31_t)0x7bbc417e, (q31_t)0xdf3c1d0b, (q31_t)0x7bbaa59a, (q31_t)0xdf360a2d, + (q31_t)0x7bb9096b, (q31_t)0xdf2ff764, (q31_t)0x7bb76cef, (q31_t)0xdf29e4af, (q31_t)0x7bb5d026, (q31_t)0xdf23d20e, (q31_t)0x7bb43311, (q31_t)0xdf1dbf82, + (q31_t)0x7bb295b0, (q31_t)0xdf17ad0a, (q31_t)0x7bb0f803, (q31_t)0xdf119aa6, (q31_t)0x7baf5a09, (q31_t)0xdf0b8856, (q31_t)0x7badbbc3, (q31_t)0xdf05761b, + (q31_t)0x7bac1d31, (q31_t)0xdeff63f4, (q31_t)0x7baa7e53, (q31_t)0xdef951e2, (q31_t)0x7ba8df28, (q31_t)0xdef33fe3, (q31_t)0x7ba73fb1, (q31_t)0xdeed2dfa, + (q31_t)0x7ba59fee, (q31_t)0xdee71c24, (q31_t)0x7ba3ffde, (q31_t)0xdee10a63, (q31_t)0x7ba25f82, (q31_t)0xdedaf8b7, (q31_t)0x7ba0beda, (q31_t)0xded4e71f, + (q31_t)0x7b9f1de6, (q31_t)0xdeced59b, (q31_t)0x7b9d7ca5, (q31_t)0xdec8c42c, (q31_t)0x7b9bdb18, (q31_t)0xdec2b2d1, (q31_t)0x7b9a393f, (q31_t)0xdebca18b, + (q31_t)0x7b989719, (q31_t)0xdeb69059, (q31_t)0x7b96f4a8, (q31_t)0xdeb07f3c, (q31_t)0x7b9551ea, (q31_t)0xdeaa6e34, (q31_t)0x7b93aee0, (q31_t)0xdea45d40, + (q31_t)0x7b920b89, (q31_t)0xde9e4c60, (q31_t)0x7b9067e7, (q31_t)0xde983b95, (q31_t)0x7b8ec3f8, (q31_t)0xde922adf, (q31_t)0x7b8d1fbd, (q31_t)0xde8c1a3e, + (q31_t)0x7b8b7b36, (q31_t)0xde8609b1, (q31_t)0x7b89d662, (q31_t)0xde7ff938, (q31_t)0x7b883143, (q31_t)0xde79e8d5, (q31_t)0x7b868bd7, (q31_t)0xde73d886, + (q31_t)0x7b84e61f, (q31_t)0xde6dc84b, (q31_t)0x7b83401b, (q31_t)0xde67b826, (q31_t)0x7b8199ca, (q31_t)0xde61a815, (q31_t)0x7b7ff32e, (q31_t)0xde5b9819, + (q31_t)0x7b7e4c45, (q31_t)0xde558831, (q31_t)0x7b7ca510, (q31_t)0xde4f785f, (q31_t)0x7b7afd8f, (q31_t)0xde4968a1, (q31_t)0x7b7955c2, (q31_t)0xde4358f8, + (q31_t)0x7b77ada8, (q31_t)0xde3d4964, (q31_t)0x7b760542, (q31_t)0xde3739e4, (q31_t)0x7b745c91, (q31_t)0xde312a7a, (q31_t)0x7b72b393, (q31_t)0xde2b1b24, + (q31_t)0x7b710a49, (q31_t)0xde250be3, (q31_t)0x7b6f60b2, (q31_t)0xde1efcb7, (q31_t)0x7b6db6d0, (q31_t)0xde18eda0, (q31_t)0x7b6c0ca2, (q31_t)0xde12de9e, + (q31_t)0x7b6a6227, (q31_t)0xde0ccfb1, (q31_t)0x7b68b760, (q31_t)0xde06c0d9, (q31_t)0x7b670c4d, (q31_t)0xde00b216, (q31_t)0x7b6560ee, (q31_t)0xddfaa367, + (q31_t)0x7b63b543, (q31_t)0xddf494ce, (q31_t)0x7b62094c, (q31_t)0xddee8649, (q31_t)0x7b605d09, (q31_t)0xdde877da, (q31_t)0x7b5eb079, (q31_t)0xdde26980, + (q31_t)0x7b5d039e, (q31_t)0xdddc5b3b, (q31_t)0x7b5b5676, (q31_t)0xddd64d0a, (q31_t)0x7b59a902, (q31_t)0xddd03eef, (q31_t)0x7b57fb42, (q31_t)0xddca30e9, + (q31_t)0x7b564d36, (q31_t)0xddc422f8, (q31_t)0x7b549ede, (q31_t)0xddbe151d, (q31_t)0x7b52f03a, (q31_t)0xddb80756, (q31_t)0x7b51414a, (q31_t)0xddb1f9a4, + (q31_t)0x7b4f920e, (q31_t)0xddabec08, (q31_t)0x7b4de286, (q31_t)0xdda5de81, (q31_t)0x7b4c32b1, (q31_t)0xdd9fd10f, (q31_t)0x7b4a8291, (q31_t)0xdd99c3b2, + (q31_t)0x7b48d225, (q31_t)0xdd93b66a, (q31_t)0x7b47216c, (q31_t)0xdd8da938, (q31_t)0x7b457068, (q31_t)0xdd879c1b, (q31_t)0x7b43bf17, (q31_t)0xdd818f13, + (q31_t)0x7b420d7a, (q31_t)0xdd7b8220, (q31_t)0x7b405b92, (q31_t)0xdd757543, (q31_t)0x7b3ea95d, (q31_t)0xdd6f687b, (q31_t)0x7b3cf6dc, (q31_t)0xdd695bc9, + (q31_t)0x7b3b4410, (q31_t)0xdd634f2b, (q31_t)0x7b3990f7, (q31_t)0xdd5d42a3, (q31_t)0x7b37dd92, (q31_t)0xdd573631, (q31_t)0x7b3629e1, (q31_t)0xdd5129d4, + (q31_t)0x7b3475e5, (q31_t)0xdd4b1d8c, (q31_t)0x7b32c19c, (q31_t)0xdd451159, (q31_t)0x7b310d07, (q31_t)0xdd3f053c, (q31_t)0x7b2f5826, (q31_t)0xdd38f935, + (q31_t)0x7b2da2fa, (q31_t)0xdd32ed43, (q31_t)0x7b2bed81, (q31_t)0xdd2ce166, (q31_t)0x7b2a37bc, (q31_t)0xdd26d59f, (q31_t)0x7b2881ac, (q31_t)0xdd20c9ed, + (q31_t)0x7b26cb4f, (q31_t)0xdd1abe51, (q31_t)0x7b2514a6, (q31_t)0xdd14b2ca, (q31_t)0x7b235db2, (q31_t)0xdd0ea759, (q31_t)0x7b21a671, (q31_t)0xdd089bfe, + (q31_t)0x7b1feee5, (q31_t)0xdd0290b8, (q31_t)0x7b1e370d, (q31_t)0xdcfc8588, (q31_t)0x7b1c7ee8, (q31_t)0xdcf67a6d, (q31_t)0x7b1ac678, (q31_t)0xdcf06f68, + (q31_t)0x7b190dbc, (q31_t)0xdcea6478, (q31_t)0x7b1754b3, (q31_t)0xdce4599e, (q31_t)0x7b159b5f, (q31_t)0xdcde4eda, (q31_t)0x7b13e1bf, (q31_t)0xdcd8442b, + (q31_t)0x7b1227d3, (q31_t)0xdcd23993, (q31_t)0x7b106d9b, (q31_t)0xdccc2f0f, (q31_t)0x7b0eb318, (q31_t)0xdcc624a2, (q31_t)0x7b0cf848, (q31_t)0xdcc01a4a, + (q31_t)0x7b0b3d2c, (q31_t)0xdcba1008, (q31_t)0x7b0981c5, (q31_t)0xdcb405dc, (q31_t)0x7b07c612, (q31_t)0xdcadfbc5, (q31_t)0x7b060a12, (q31_t)0xdca7f1c5, + (q31_t)0x7b044dc7, (q31_t)0xdca1e7da, (q31_t)0x7b029130, (q31_t)0xdc9bde05, (q31_t)0x7b00d44d, (q31_t)0xdc95d446, (q31_t)0x7aff171e, (q31_t)0xdc8fca9c, + (q31_t)0x7afd59a4, (q31_t)0xdc89c109, (q31_t)0x7afb9bdd, (q31_t)0xdc83b78b, (q31_t)0x7af9ddcb, (q31_t)0xdc7dae23, (q31_t)0x7af81f6c, (q31_t)0xdc77a4d2, + (q31_t)0x7af660c2, (q31_t)0xdc719b96, (q31_t)0x7af4a1cc, (q31_t)0xdc6b9270, (q31_t)0x7af2e28b, (q31_t)0xdc658960, (q31_t)0x7af122fd, (q31_t)0xdc5f8066, + (q31_t)0x7aef6323, (q31_t)0xdc597781, (q31_t)0x7aeda2fe, (q31_t)0xdc536eb3, (q31_t)0x7aebe28d, (q31_t)0xdc4d65fb, (q31_t)0x7aea21d0, (q31_t)0xdc475d59, + (q31_t)0x7ae860c7, (q31_t)0xdc4154cd, (q31_t)0x7ae69f73, (q31_t)0xdc3b4c57, (q31_t)0x7ae4ddd2, (q31_t)0xdc3543f7, (q31_t)0x7ae31be6, (q31_t)0xdc2f3bad, + (q31_t)0x7ae159ae, (q31_t)0xdc293379, (q31_t)0x7adf972a, (q31_t)0xdc232b5c, (q31_t)0x7addd45b, (q31_t)0xdc1d2354, (q31_t)0x7adc113f, (q31_t)0xdc171b63, + (q31_t)0x7ada4dd8, (q31_t)0xdc111388, (q31_t)0x7ad88a25, (q31_t)0xdc0b0bc2, (q31_t)0x7ad6c626, (q31_t)0xdc050414, (q31_t)0x7ad501dc, (q31_t)0xdbfefc7b, + (q31_t)0x7ad33d45, (q31_t)0xdbf8f4f8, (q31_t)0x7ad17863, (q31_t)0xdbf2ed8c, (q31_t)0x7acfb336, (q31_t)0xdbece636, (q31_t)0x7acdedbc, (q31_t)0xdbe6def6, + (q31_t)0x7acc27f7, (q31_t)0xdbe0d7cd, (q31_t)0x7aca61e6, (q31_t)0xdbdad0b9, (q31_t)0x7ac89b89, (q31_t)0xdbd4c9bc, (q31_t)0x7ac6d4e0, (q31_t)0xdbcec2d6, + (q31_t)0x7ac50dec, (q31_t)0xdbc8bc06, (q31_t)0x7ac346ac, (q31_t)0xdbc2b54c, (q31_t)0x7ac17f20, (q31_t)0xdbbcaea8, (q31_t)0x7abfb749, (q31_t)0xdbb6a81b, + (q31_t)0x7abdef25, (q31_t)0xdbb0a1a4, (q31_t)0x7abc26b7, (q31_t)0xdbaa9b43, (q31_t)0x7aba5dfc, (q31_t)0xdba494f9, (q31_t)0x7ab894f6, (q31_t)0xdb9e8ec6, + (q31_t)0x7ab6cba4, (q31_t)0xdb9888a8, (q31_t)0x7ab50206, (q31_t)0xdb9282a2, (q31_t)0x7ab3381d, (q31_t)0xdb8c7cb1, (q31_t)0x7ab16de7, (q31_t)0xdb8676d8, + (q31_t)0x7aafa367, (q31_t)0xdb807114, (q31_t)0x7aadd89a, (q31_t)0xdb7a6b68, (q31_t)0x7aac0d82, (q31_t)0xdb7465d1, (q31_t)0x7aaa421e, (q31_t)0xdb6e6052, + (q31_t)0x7aa8766f, (q31_t)0xdb685ae9, (q31_t)0x7aa6aa74, (q31_t)0xdb625596, (q31_t)0x7aa4de2d, (q31_t)0xdb5c505a, (q31_t)0x7aa3119a, (q31_t)0xdb564b35, + (q31_t)0x7aa144bc, (q31_t)0xdb504626, (q31_t)0x7a9f7793, (q31_t)0xdb4a412e, (q31_t)0x7a9daa1d, (q31_t)0xdb443c4c, (q31_t)0x7a9bdc5c, (q31_t)0xdb3e3781, + (q31_t)0x7a9a0e50, (q31_t)0xdb3832cd, (q31_t)0x7a983ff7, (q31_t)0xdb322e30, (q31_t)0x7a967153, (q31_t)0xdb2c29a9, (q31_t)0x7a94a264, (q31_t)0xdb262539, + (q31_t)0x7a92d329, (q31_t)0xdb2020e0, (q31_t)0x7a9103a2, (q31_t)0xdb1a1c9d, (q31_t)0x7a8f33d0, (q31_t)0xdb141871, (q31_t)0x7a8d63b2, (q31_t)0xdb0e145c, + (q31_t)0x7a8b9348, (q31_t)0xdb08105e, (q31_t)0x7a89c293, (q31_t)0xdb020c77, (q31_t)0x7a87f192, (q31_t)0xdafc08a6, (q31_t)0x7a862046, (q31_t)0xdaf604ec, + (q31_t)0x7a844eae, (q31_t)0xdaf00149, (q31_t)0x7a827ccb, (q31_t)0xdae9fdbd, (q31_t)0x7a80aa9c, (q31_t)0xdae3fa48, (q31_t)0x7a7ed821, (q31_t)0xdaddf6ea, + (q31_t)0x7a7d055b, (q31_t)0xdad7f3a2, (q31_t)0x7a7b3249, (q31_t)0xdad1f072, (q31_t)0x7a795eec, (q31_t)0xdacbed58, (q31_t)0x7a778b43, (q31_t)0xdac5ea56, + (q31_t)0x7a75b74f, (q31_t)0xdabfe76a, (q31_t)0x7a73e30f, (q31_t)0xdab9e495, (q31_t)0x7a720e84, (q31_t)0xdab3e1d8, (q31_t)0x7a7039ad, (q31_t)0xdaaddf31, + (q31_t)0x7a6e648a, (q31_t)0xdaa7dca1, (q31_t)0x7a6c8f1c, (q31_t)0xdaa1da29, (q31_t)0x7a6ab963, (q31_t)0xda9bd7c7, (q31_t)0x7a68e35e, (q31_t)0xda95d57d, + (q31_t)0x7a670d0d, (q31_t)0xda8fd349, (q31_t)0x7a653671, (q31_t)0xda89d12d, (q31_t)0x7a635f8a, (q31_t)0xda83cf28, (q31_t)0x7a618857, (q31_t)0xda7dcd3a, + (q31_t)0x7a5fb0d8, (q31_t)0xda77cb63, (q31_t)0x7a5dd90e, (q31_t)0xda71c9a3, (q31_t)0x7a5c00f9, (q31_t)0xda6bc7fa, (q31_t)0x7a5a2898, (q31_t)0xda65c669, + (q31_t)0x7a584feb, (q31_t)0xda5fc4ef, (q31_t)0x7a5676f3, (q31_t)0xda59c38c, (q31_t)0x7a549db0, (q31_t)0xda53c240, (q31_t)0x7a52c421, (q31_t)0xda4dc10b, + (q31_t)0x7a50ea47, (q31_t)0xda47bfee, (q31_t)0x7a4f1021, (q31_t)0xda41bee8, (q31_t)0x7a4d35b0, (q31_t)0xda3bbdf9, (q31_t)0x7a4b5af3, (q31_t)0xda35bd22, + (q31_t)0x7a497feb, (q31_t)0xda2fbc61, (q31_t)0x7a47a498, (q31_t)0xda29bbb9, (q31_t)0x7a45c8f9, (q31_t)0xda23bb27, (q31_t)0x7a43ed0e, (q31_t)0xda1dbaad, + (q31_t)0x7a4210d8, (q31_t)0xda17ba4a, (q31_t)0x7a403457, (q31_t)0xda11b9ff, (q31_t)0x7a3e578b, (q31_t)0xda0bb9cb, (q31_t)0x7a3c7a73, (q31_t)0xda05b9ae, + (q31_t)0x7a3a9d0f, (q31_t)0xd9ffb9a9, (q31_t)0x7a38bf60, (q31_t)0xd9f9b9bb, (q31_t)0x7a36e166, (q31_t)0xd9f3b9e5, (q31_t)0x7a350321, (q31_t)0xd9edba26, + (q31_t)0x7a332490, (q31_t)0xd9e7ba7f, (q31_t)0x7a3145b3, (q31_t)0xd9e1baef, (q31_t)0x7a2f668c, (q31_t)0xd9dbbb77, (q31_t)0x7a2d8719, (q31_t)0xd9d5bc16, + (q31_t)0x7a2ba75a, (q31_t)0xd9cfbccd, (q31_t)0x7a29c750, (q31_t)0xd9c9bd9b, (q31_t)0x7a27e6fb, (q31_t)0xd9c3be81, (q31_t)0x7a26065b, (q31_t)0xd9bdbf7e, + (q31_t)0x7a24256f, (q31_t)0xd9b7c094, (q31_t)0x7a224437, (q31_t)0xd9b1c1c0, (q31_t)0x7a2062b5, (q31_t)0xd9abc305, (q31_t)0x7a1e80e7, (q31_t)0xd9a5c461, + (q31_t)0x7a1c9ece, (q31_t)0xd99fc5d4, (q31_t)0x7a1abc69, (q31_t)0xd999c75f, (q31_t)0x7a18d9b9, (q31_t)0xd993c902, (q31_t)0x7a16f6be, (q31_t)0xd98dcabd, + (q31_t)0x7a151378, (q31_t)0xd987cc90, (q31_t)0x7a132fe6, (q31_t)0xd981ce7a, (q31_t)0x7a114c09, (q31_t)0xd97bd07c, (q31_t)0x7a0f67e0, (q31_t)0xd975d295, + (q31_t)0x7a0d836d, (q31_t)0xd96fd4c7, (q31_t)0x7a0b9eae, (q31_t)0xd969d710, (q31_t)0x7a09b9a4, (q31_t)0xd963d971, (q31_t)0x7a07d44e, (q31_t)0xd95ddbea, + (q31_t)0x7a05eead, (q31_t)0xd957de7a, (q31_t)0x7a0408c1, (q31_t)0xd951e123, (q31_t)0x7a02228a, (q31_t)0xd94be3e3, (q31_t)0x7a003c07, (q31_t)0xd945e6bb, + (q31_t)0x79fe5539, (q31_t)0xd93fe9ab, (q31_t)0x79fc6e20, (q31_t)0xd939ecb3, (q31_t)0x79fa86bc, (q31_t)0xd933efd3, (q31_t)0x79f89f0c, (q31_t)0xd92df30b, + (q31_t)0x79f6b711, (q31_t)0xd927f65b, (q31_t)0x79f4cecb, (q31_t)0xd921f9c3, (q31_t)0x79f2e63a, (q31_t)0xd91bfd43, (q31_t)0x79f0fd5d, (q31_t)0xd91600da, + (q31_t)0x79ef1436, (q31_t)0xd910048a, (q31_t)0x79ed2ac3, (q31_t)0xd90a0852, (q31_t)0x79eb4105, (q31_t)0xd9040c32, (q31_t)0x79e956fb, (q31_t)0xd8fe1029, + (q31_t)0x79e76ca7, (q31_t)0xd8f81439, (q31_t)0x79e58207, (q31_t)0xd8f21861, (q31_t)0x79e3971c, (q31_t)0xd8ec1ca1, (q31_t)0x79e1abe6, (q31_t)0xd8e620fa, + (q31_t)0x79dfc064, (q31_t)0xd8e0256a, (q31_t)0x79ddd498, (q31_t)0xd8da29f2, (q31_t)0x79dbe880, (q31_t)0xd8d42e93, (q31_t)0x79d9fc1d, (q31_t)0xd8ce334c, + (q31_t)0x79d80f6f, (q31_t)0xd8c8381d, (q31_t)0x79d62276, (q31_t)0xd8c23d06, (q31_t)0x79d43532, (q31_t)0xd8bc4207, (q31_t)0x79d247a2, (q31_t)0xd8b64720, + (q31_t)0x79d059c8, (q31_t)0xd8b04c52, (q31_t)0x79ce6ba2, (q31_t)0xd8aa519c, (q31_t)0x79cc7d31, (q31_t)0xd8a456ff, (q31_t)0x79ca8e75, (q31_t)0xd89e5c79, + (q31_t)0x79c89f6e, (q31_t)0xd898620c, (q31_t)0x79c6b01b, (q31_t)0xd89267b7, (q31_t)0x79c4c07e, (q31_t)0xd88c6d7b, (q31_t)0x79c2d095, (q31_t)0xd8867356, + (q31_t)0x79c0e062, (q31_t)0xd880794b, (q31_t)0x79beefe3, (q31_t)0xd87a7f57, (q31_t)0x79bcff19, (q31_t)0xd874857c, (q31_t)0x79bb0e04, (q31_t)0xd86e8bb9, + (q31_t)0x79b91ca4, (q31_t)0xd868920f, (q31_t)0x79b72af9, (q31_t)0xd862987d, (q31_t)0x79b53903, (q31_t)0xd85c9f04, (q31_t)0x79b346c2, (q31_t)0xd856a5a3, + (q31_t)0x79b15435, (q31_t)0xd850ac5a, (q31_t)0x79af615e, (q31_t)0xd84ab32a, (q31_t)0x79ad6e3c, (q31_t)0xd844ba13, (q31_t)0x79ab7ace, (q31_t)0xd83ec114, + (q31_t)0x79a98715, (q31_t)0xd838c82d, (q31_t)0x79a79312, (q31_t)0xd832cf5f, (q31_t)0x79a59ec3, (q31_t)0xd82cd6aa, (q31_t)0x79a3aa29, (q31_t)0xd826de0d, + (q31_t)0x79a1b545, (q31_t)0xd820e589, (q31_t)0x799fc015, (q31_t)0xd81aed1d, (q31_t)0x799dca9a, (q31_t)0xd814f4ca, (q31_t)0x799bd4d4, (q31_t)0xd80efc8f, + (q31_t)0x7999dec4, (q31_t)0xd809046e, (q31_t)0x7997e868, (q31_t)0xd8030c64, (q31_t)0x7995f1c1, (q31_t)0xd7fd1474, (q31_t)0x7993facf, (q31_t)0xd7f71c9c, + (q31_t)0x79920392, (q31_t)0xd7f124dd, (q31_t)0x79900c0a, (q31_t)0xd7eb2d37, (q31_t)0x798e1438, (q31_t)0xd7e535a9, (q31_t)0x798c1c1a, (q31_t)0xd7df3e34, + (q31_t)0x798a23b1, (q31_t)0xd7d946d8, (q31_t)0x79882afd, (q31_t)0xd7d34f94, (q31_t)0x798631ff, (q31_t)0xd7cd586a, (q31_t)0x798438b5, (q31_t)0xd7c76158, + (q31_t)0x79823f20, (q31_t)0xd7c16a5f, (q31_t)0x79804541, (q31_t)0xd7bb737f, (q31_t)0x797e4b16, (q31_t)0xd7b57cb7, (q31_t)0x797c50a1, (q31_t)0xd7af8609, + (q31_t)0x797a55e0, (q31_t)0xd7a98f73, (q31_t)0x79785ad5, (q31_t)0xd7a398f6, (q31_t)0x79765f7f, (q31_t)0xd79da293, (q31_t)0x797463de, (q31_t)0xd797ac48, + (q31_t)0x797267f2, (q31_t)0xd791b616, (q31_t)0x79706bbb, (q31_t)0xd78bbffc, (q31_t)0x796e6f39, (q31_t)0xd785c9fc, (q31_t)0x796c726c, (q31_t)0xd77fd415, + (q31_t)0x796a7554, (q31_t)0xd779de47, (q31_t)0x796877f1, (q31_t)0xd773e892, (q31_t)0x79667a44, (q31_t)0xd76df2f6, (q31_t)0x79647c4c, (q31_t)0xd767fd72, + (q31_t)0x79627e08, (q31_t)0xd7620808, (q31_t)0x79607f7a, (q31_t)0xd75c12b7, (q31_t)0x795e80a1, (q31_t)0xd7561d7f, (q31_t)0x795c817d, (q31_t)0xd7502860, + (q31_t)0x795a820e, (q31_t)0xd74a335b, (q31_t)0x79588255, (q31_t)0xd7443e6e, (q31_t)0x79568250, (q31_t)0xd73e499a, (q31_t)0x79548201, (q31_t)0xd73854e0, + (q31_t)0x79528167, (q31_t)0xd732603f, (q31_t)0x79508082, (q31_t)0xd72c6bb6, (q31_t)0x794e7f52, (q31_t)0xd7267748, (q31_t)0x794c7dd7, (q31_t)0xd72082f2, + (q31_t)0x794a7c12, (q31_t)0xd71a8eb5, (q31_t)0x79487a01, (q31_t)0xd7149a92, (q31_t)0x794677a6, (q31_t)0xd70ea688, (q31_t)0x79447500, (q31_t)0xd708b297, + (q31_t)0x79427210, (q31_t)0xd702bec0, (q31_t)0x79406ed4, (q31_t)0xd6fccb01, (q31_t)0x793e6b4e, (q31_t)0xd6f6d75d, (q31_t)0x793c677d, (q31_t)0xd6f0e3d1, + (q31_t)0x793a6361, (q31_t)0xd6eaf05f, (q31_t)0x79385efa, (q31_t)0xd6e4fd06, (q31_t)0x79365a49, (q31_t)0xd6df09c6, (q31_t)0x7934554d, (q31_t)0xd6d916a0, + (q31_t)0x79325006, (q31_t)0xd6d32393, (q31_t)0x79304a74, (q31_t)0xd6cd30a0, (q31_t)0x792e4497, (q31_t)0xd6c73dc6, (q31_t)0x792c3e70, (q31_t)0xd6c14b05, + (q31_t)0x792a37fe, (q31_t)0xd6bb585e, (q31_t)0x79283141, (q31_t)0xd6b565d0, (q31_t)0x79262a3a, (q31_t)0xd6af735c, (q31_t)0x792422e8, (q31_t)0xd6a98101, + (q31_t)0x79221b4b, (q31_t)0xd6a38ec0, (q31_t)0x79201363, (q31_t)0xd69d9c98, (q31_t)0x791e0b31, (q31_t)0xd697aa8a, (q31_t)0x791c02b4, (q31_t)0xd691b895, + (q31_t)0x7919f9ec, (q31_t)0xd68bc6ba, (q31_t)0x7917f0d9, (q31_t)0xd685d4f9, (q31_t)0x7915e77c, (q31_t)0xd67fe351, (q31_t)0x7913ddd4, (q31_t)0xd679f1c2, + (q31_t)0x7911d3e2, (q31_t)0xd674004e, (q31_t)0x790fc9a4, (q31_t)0xd66e0ef2, (q31_t)0x790dbf1d, (q31_t)0xd6681db1, (q31_t)0x790bb44a, (q31_t)0xd6622c89, + (q31_t)0x7909a92d, (q31_t)0xd65c3b7b, (q31_t)0x79079dc5, (q31_t)0xd6564a87, (q31_t)0x79059212, (q31_t)0xd65059ac, (q31_t)0x79038615, (q31_t)0xd64a68eb, + (q31_t)0x790179cd, (q31_t)0xd6447844, (q31_t)0x78ff6d3b, (q31_t)0xd63e87b6, (q31_t)0x78fd605d, (q31_t)0xd6389742, (q31_t)0x78fb5336, (q31_t)0xd632a6e8, + (q31_t)0x78f945c3, (q31_t)0xd62cb6a8, (q31_t)0x78f73806, (q31_t)0xd626c681, (q31_t)0x78f529fe, (q31_t)0xd620d675, (q31_t)0x78f31bac, (q31_t)0xd61ae682, + (q31_t)0x78f10d0f, (q31_t)0xd614f6a9, (q31_t)0x78eefe28, (q31_t)0xd60f06ea, (q31_t)0x78eceef6, (q31_t)0xd6091745, (q31_t)0x78eadf79, (q31_t)0xd60327b9, + (q31_t)0x78e8cfb2, (q31_t)0xd5fd3848, (q31_t)0x78e6bfa0, (q31_t)0xd5f748f0, (q31_t)0x78e4af44, (q31_t)0xd5f159b3, (q31_t)0x78e29e9d, (q31_t)0xd5eb6a8f, + (q31_t)0x78e08dab, (q31_t)0xd5e57b85, (q31_t)0x78de7c6f, (q31_t)0xd5df8c96, (q31_t)0x78dc6ae8, (q31_t)0xd5d99dc0, (q31_t)0x78da5917, (q31_t)0xd5d3af04, + (q31_t)0x78d846fb, (q31_t)0xd5cdc062, (q31_t)0x78d63495, (q31_t)0xd5c7d1db, (q31_t)0x78d421e4, (q31_t)0xd5c1e36d, (q31_t)0x78d20ee9, (q31_t)0xd5bbf519, + (q31_t)0x78cffba3, (q31_t)0xd5b606e0, (q31_t)0x78cde812, (q31_t)0xd5b018c0, (q31_t)0x78cbd437, (q31_t)0xd5aa2abb, (q31_t)0x78c9c012, (q31_t)0xd5a43cd0, + (q31_t)0x78c7aba2, (q31_t)0xd59e4eff, (q31_t)0x78c596e7, (q31_t)0xd5986148, (q31_t)0x78c381e2, (q31_t)0xd59273ab, (q31_t)0x78c16c93, (q31_t)0xd58c8628, + (q31_t)0x78bf56f9, (q31_t)0xd58698c0, (q31_t)0x78bd4114, (q31_t)0xd580ab72, (q31_t)0x78bb2ae5, (q31_t)0xd57abe3d, (q31_t)0x78b9146c, (q31_t)0xd574d124, + (q31_t)0x78b6fda8, (q31_t)0xd56ee424, (q31_t)0x78b4e69a, (q31_t)0xd568f73f, (q31_t)0x78b2cf41, (q31_t)0xd5630a74, (q31_t)0x78b0b79e, (q31_t)0xd55d1dc3, + (q31_t)0x78ae9fb0, (q31_t)0xd557312d, (q31_t)0x78ac8778, (q31_t)0xd55144b0, (q31_t)0x78aa6ef5, (q31_t)0xd54b584f, (q31_t)0x78a85628, (q31_t)0xd5456c07, + (q31_t)0x78a63d11, (q31_t)0xd53f7fda, (q31_t)0x78a423af, (q31_t)0xd53993c7, (q31_t)0x78a20a03, (q31_t)0xd533a7cf, (q31_t)0x789ff00c, (q31_t)0xd52dbbf1, + (q31_t)0x789dd5cb, (q31_t)0xd527d02e, (q31_t)0x789bbb3f, (q31_t)0xd521e484, (q31_t)0x7899a06a, (q31_t)0xd51bf8f6, (q31_t)0x78978549, (q31_t)0xd5160d82, + (q31_t)0x789569df, (q31_t)0xd5102228, (q31_t)0x78934e2a, (q31_t)0xd50a36e9, (q31_t)0x7891322a, (q31_t)0xd5044bc4, (q31_t)0x788f15e0, (q31_t)0xd4fe60ba, + (q31_t)0x788cf94c, (q31_t)0xd4f875ca, (q31_t)0x788adc6e, (q31_t)0xd4f28af5, (q31_t)0x7888bf45, (q31_t)0xd4eca03a, (q31_t)0x7886a1d1, (q31_t)0xd4e6b59a, + (q31_t)0x78848414, (q31_t)0xd4e0cb15, (q31_t)0x7882660c, (q31_t)0xd4dae0aa, (q31_t)0x788047ba, (q31_t)0xd4d4f65a, (q31_t)0x787e291d, (q31_t)0xd4cf0c24, + (q31_t)0x787c0a36, (q31_t)0xd4c92209, (q31_t)0x7879eb05, (q31_t)0xd4c33809, (q31_t)0x7877cb89, (q31_t)0xd4bd4e23, (q31_t)0x7875abc3, (q31_t)0xd4b76458, + (q31_t)0x78738bb3, (q31_t)0xd4b17aa8, (q31_t)0x78716b59, (q31_t)0xd4ab9112, (q31_t)0x786f4ab4, (q31_t)0xd4a5a798, (q31_t)0x786d29c5, (q31_t)0xd49fbe37, + (q31_t)0x786b088c, (q31_t)0xd499d4f2, (q31_t)0x7868e708, (q31_t)0xd493ebc8, (q31_t)0x7866c53a, (q31_t)0xd48e02b8, (q31_t)0x7864a322, (q31_t)0xd48819c3, + (q31_t)0x786280bf, (q31_t)0xd48230e9, (q31_t)0x78605e13, (q31_t)0xd47c4829, (q31_t)0x785e3b1c, (q31_t)0xd4765f85, (q31_t)0x785c17db, (q31_t)0xd47076fb, + (q31_t)0x7859f44f, (q31_t)0xd46a8e8d, (q31_t)0x7857d079, (q31_t)0xd464a639, (q31_t)0x7855ac5a, (q31_t)0xd45ebe00, (q31_t)0x785387ef, (q31_t)0xd458d5e2, + (q31_t)0x7851633b, (q31_t)0xd452eddf, (q31_t)0x784f3e3c, (q31_t)0xd44d05f6, (q31_t)0x784d18f4, (q31_t)0xd4471e29, (q31_t)0x784af361, (q31_t)0xd4413677, + (q31_t)0x7848cd83, (q31_t)0xd43b4ee0, (q31_t)0x7846a75c, (q31_t)0xd4356763, (q31_t)0x784480ea, (q31_t)0xd42f8002, (q31_t)0x78425a2f, (q31_t)0xd42998bc, + (q31_t)0x78403329, (q31_t)0xd423b191, (q31_t)0x783e0bd9, (q31_t)0xd41dca81, (q31_t)0x783be43e, (q31_t)0xd417e38c, (q31_t)0x7839bc5a, (q31_t)0xd411fcb2, + (q31_t)0x7837942b, (q31_t)0xd40c15f3, (q31_t)0x78356bb2, (q31_t)0xd4062f4f, (q31_t)0x783342ef, (q31_t)0xd40048c6, (q31_t)0x783119e2, (q31_t)0xd3fa6259, + (q31_t)0x782ef08b, (q31_t)0xd3f47c06, (q31_t)0x782cc6ea, (q31_t)0xd3ee95cf, (q31_t)0x782a9cfe, (q31_t)0xd3e8afb3, (q31_t)0x782872c8, (q31_t)0xd3e2c9b2, + (q31_t)0x78264849, (q31_t)0xd3dce3cd, (q31_t)0x78241d7f, (q31_t)0xd3d6fe03, (q31_t)0x7821f26b, (q31_t)0xd3d11853, (q31_t)0x781fc70d, (q31_t)0xd3cb32c0, + (q31_t)0x781d9b65, (q31_t)0xd3c54d47, (q31_t)0x781b6f72, (q31_t)0xd3bf67ea, (q31_t)0x78194336, (q31_t)0xd3b982a8, (q31_t)0x781716b0, (q31_t)0xd3b39d81, + (q31_t)0x7814e9df, (q31_t)0xd3adb876, (q31_t)0x7812bcc4, (q31_t)0xd3a7d385, (q31_t)0x78108f60, (q31_t)0xd3a1eeb1, (q31_t)0x780e61b1, (q31_t)0xd39c09f7, + (q31_t)0x780c33b8, (q31_t)0xd396255a, (q31_t)0x780a0575, (q31_t)0xd39040d7, (q31_t)0x7807d6e9, (q31_t)0xd38a5c70, (q31_t)0x7805a812, (q31_t)0xd3847824, + (q31_t)0x780378f1, (q31_t)0xd37e93f4, (q31_t)0x78014986, (q31_t)0xd378afdf, (q31_t)0x77ff19d1, (q31_t)0xd372cbe6, (q31_t)0x77fce9d2, (q31_t)0xd36ce808, + (q31_t)0x77fab989, (q31_t)0xd3670446, (q31_t)0x77f888f6, (q31_t)0xd361209f, (q31_t)0x77f65819, (q31_t)0xd35b3d13, (q31_t)0x77f426f2, (q31_t)0xd35559a4, + (q31_t)0x77f1f581, (q31_t)0xd34f764f, (q31_t)0x77efc3c5, (q31_t)0xd3499317, (q31_t)0x77ed91c0, (q31_t)0xd343affa, (q31_t)0x77eb5f71, (q31_t)0xd33dccf8, + (q31_t)0x77e92cd9, (q31_t)0xd337ea12, (q31_t)0x77e6f9f6, (q31_t)0xd3320748, (q31_t)0x77e4c6c9, (q31_t)0xd32c2499, (q31_t)0x77e29352, (q31_t)0xd3264206, + (q31_t)0x77e05f91, (q31_t)0xd3205f8f, (q31_t)0x77de2b86, (q31_t)0xd31a7d33, (q31_t)0x77dbf732, (q31_t)0xd3149af3, (q31_t)0x77d9c293, (q31_t)0xd30eb8cf, + (q31_t)0x77d78daa, (q31_t)0xd308d6c7, (q31_t)0x77d55878, (q31_t)0xd302f4da, (q31_t)0x77d322fc, (q31_t)0xd2fd1309, (q31_t)0x77d0ed35, (q31_t)0xd2f73154, + (q31_t)0x77ceb725, (q31_t)0xd2f14fba, (q31_t)0x77cc80cb, (q31_t)0xd2eb6e3c, (q31_t)0x77ca4a27, (q31_t)0xd2e58cdb, (q31_t)0x77c81339, (q31_t)0xd2dfab95, + (q31_t)0x77c5dc01, (q31_t)0xd2d9ca6a, (q31_t)0x77c3a47f, (q31_t)0xd2d3e95c, (q31_t)0x77c16cb4, (q31_t)0xd2ce0869, (q31_t)0x77bf349f, (q31_t)0xd2c82793, + (q31_t)0x77bcfc3f, (q31_t)0xd2c246d8, (q31_t)0x77bac396, (q31_t)0xd2bc6639, (q31_t)0x77b88aa3, (q31_t)0xd2b685b6, (q31_t)0x77b65166, (q31_t)0xd2b0a54f, + (q31_t)0x77b417df, (q31_t)0xd2aac504, (q31_t)0x77b1de0f, (q31_t)0xd2a4e4d5, (q31_t)0x77afa3f5, (q31_t)0xd29f04c2, (q31_t)0x77ad6990, (q31_t)0xd29924cb, + (q31_t)0x77ab2ee2, (q31_t)0xd29344f0, (q31_t)0x77a8f3ea, (q31_t)0xd28d6531, (q31_t)0x77a6b8a9, (q31_t)0xd287858e, (q31_t)0x77a47d1d, (q31_t)0xd281a607, + (q31_t)0x77a24148, (q31_t)0xd27bc69c, (q31_t)0x77a00529, (q31_t)0xd275e74d, (q31_t)0x779dc8c0, (q31_t)0xd270081b, (q31_t)0x779b8c0e, (q31_t)0xd26a2904, + (q31_t)0x77994f11, (q31_t)0xd2644a0a, (q31_t)0x779711cb, (q31_t)0xd25e6b2b, (q31_t)0x7794d43b, (q31_t)0xd2588c69, (q31_t)0x77929661, (q31_t)0xd252adc3, + (q31_t)0x7790583e, (q31_t)0xd24ccf39, (q31_t)0x778e19d0, (q31_t)0xd246f0cb, (q31_t)0x778bdb19, (q31_t)0xd241127a, (q31_t)0x77899c19, (q31_t)0xd23b3444, + (q31_t)0x77875cce, (q31_t)0xd235562b, (q31_t)0x77851d3a, (q31_t)0xd22f782f, (q31_t)0x7782dd5c, (q31_t)0xd2299a4e, (q31_t)0x77809d35, (q31_t)0xd223bc8a, + (q31_t)0x777e5cc3, (q31_t)0xd21ddee2, (q31_t)0x777c1c08, (q31_t)0xd2180156, (q31_t)0x7779db03, (q31_t)0xd21223e7, (q31_t)0x777799b5, (q31_t)0xd20c4694, + (q31_t)0x7775581d, (q31_t)0xd206695d, (q31_t)0x7773163b, (q31_t)0xd2008c43, (q31_t)0x7770d40f, (q31_t)0xd1faaf45, (q31_t)0x776e919a, (q31_t)0xd1f4d263, + (q31_t)0x776c4edb, (q31_t)0xd1eef59e, (q31_t)0x776a0bd3, (q31_t)0xd1e918f5, (q31_t)0x7767c880, (q31_t)0xd1e33c69, (q31_t)0x776584e5, (q31_t)0xd1dd5ff9, + (q31_t)0x776340ff, (q31_t)0xd1d783a6, (q31_t)0x7760fcd0, (q31_t)0xd1d1a76f, (q31_t)0x775eb857, (q31_t)0xd1cbcb54, (q31_t)0x775c7395, (q31_t)0xd1c5ef56, + (q31_t)0x775a2e89, (q31_t)0xd1c01375, (q31_t)0x7757e933, (q31_t)0xd1ba37b0, (q31_t)0x7755a394, (q31_t)0xd1b45c08, (q31_t)0x77535dab, (q31_t)0xd1ae807c, + (q31_t)0x77511778, (q31_t)0xd1a8a50d, (q31_t)0x774ed0fc, (q31_t)0xd1a2c9ba, (q31_t)0x774c8a36, (q31_t)0xd19cee84, (q31_t)0x774a4327, (q31_t)0xd197136b, + (q31_t)0x7747fbce, (q31_t)0xd191386e, (q31_t)0x7745b42c, (q31_t)0xd18b5d8e, (q31_t)0x77436c40, (q31_t)0xd18582ca, (q31_t)0x7741240a, (q31_t)0xd17fa823, + (q31_t)0x773edb8b, (q31_t)0xd179cd99, (q31_t)0x773c92c2, (q31_t)0xd173f32c, (q31_t)0x773a49b0, (q31_t)0xd16e18db, (q31_t)0x77380054, (q31_t)0xd1683ea7, + (q31_t)0x7735b6af, (q31_t)0xd1626490, (q31_t)0x77336cc0, (q31_t)0xd15c8a95, (q31_t)0x77312287, (q31_t)0xd156b0b7, (q31_t)0x772ed805, (q31_t)0xd150d6f6, + (q31_t)0x772c8d3a, (q31_t)0xd14afd52, (q31_t)0x772a4225, (q31_t)0xd14523cb, (q31_t)0x7727f6c6, (q31_t)0xd13f4a60, (q31_t)0x7725ab1f, (q31_t)0xd1397113, + (q31_t)0x77235f2d, (q31_t)0xd13397e2, (q31_t)0x772112f2, (q31_t)0xd12dbece, (q31_t)0x771ec66e, (q31_t)0xd127e5d7, (q31_t)0x771c79a0, (q31_t)0xd1220cfc, + (q31_t)0x771a2c88, (q31_t)0xd11c343f, (q31_t)0x7717df27, (q31_t)0xd1165b9f, (q31_t)0x7715917d, (q31_t)0xd110831b, (q31_t)0x77134389, (q31_t)0xd10aaab5, + (q31_t)0x7710f54c, (q31_t)0xd104d26b, (q31_t)0x770ea6c5, (q31_t)0xd0fefa3f, (q31_t)0x770c57f5, (q31_t)0xd0f9222f, (q31_t)0x770a08dc, (q31_t)0xd0f34a3d, + (q31_t)0x7707b979, (q31_t)0xd0ed7267, (q31_t)0x770569cc, (q31_t)0xd0e79aaf, (q31_t)0x770319d6, (q31_t)0xd0e1c313, (q31_t)0x7700c997, (q31_t)0xd0dbeb95, + (q31_t)0x76fe790e, (q31_t)0xd0d61434, (q31_t)0x76fc283c, (q31_t)0xd0d03cf0, (q31_t)0x76f9d721, (q31_t)0xd0ca65c9, (q31_t)0x76f785bc, (q31_t)0xd0c48ebf, + (q31_t)0x76f5340e, (q31_t)0xd0beb7d2, (q31_t)0x76f2e216, (q31_t)0xd0b8e102, (q31_t)0x76f08fd5, (q31_t)0xd0b30a50, (q31_t)0x76ee3d4b, (q31_t)0xd0ad33ba, + (q31_t)0x76ebea77, (q31_t)0xd0a75d42, (q31_t)0x76e9975a, (q31_t)0xd0a186e7, (q31_t)0x76e743f4, (q31_t)0xd09bb0aa, (q31_t)0x76e4f044, (q31_t)0xd095da89, + (q31_t)0x76e29c4b, (q31_t)0xd0900486, (q31_t)0x76e04808, (q31_t)0xd08a2ea0, (q31_t)0x76ddf37c, (q31_t)0xd08458d7, (q31_t)0x76db9ea7, (q31_t)0xd07e832c, + (q31_t)0x76d94989, (q31_t)0xd078ad9e, (q31_t)0x76d6f421, (q31_t)0xd072d82d, (q31_t)0x76d49e70, (q31_t)0xd06d02da, (q31_t)0x76d24876, (q31_t)0xd0672da3, + (q31_t)0x76cff232, (q31_t)0xd061588b, (q31_t)0x76cd9ba5, (q31_t)0xd05b838f, (q31_t)0x76cb44cf, (q31_t)0xd055aeb1, (q31_t)0x76c8edb0, (q31_t)0xd04fd9f1, + (q31_t)0x76c69647, (q31_t)0xd04a054e, (q31_t)0x76c43e95, (q31_t)0xd04430c8, (q31_t)0x76c1e699, (q31_t)0xd03e5c60, (q31_t)0x76bf8e55, (q31_t)0xd0388815, + (q31_t)0x76bd35c7, (q31_t)0xd032b3e7, (q31_t)0x76badcf0, (q31_t)0xd02cdfd8, (q31_t)0x76b883d0, (q31_t)0xd0270be5, (q31_t)0x76b62a66, (q31_t)0xd0213810, + (q31_t)0x76b3d0b4, (q31_t)0xd01b6459, (q31_t)0x76b176b8, (q31_t)0xd01590bf, (q31_t)0x76af1c72, (q31_t)0xd00fbd43, (q31_t)0x76acc1e4, (q31_t)0xd009e9e4, + (q31_t)0x76aa670d, (q31_t)0xd00416a3, (q31_t)0x76a80bec, (q31_t)0xcffe4380, (q31_t)0x76a5b082, (q31_t)0xcff8707a, (q31_t)0x76a354cf, (q31_t)0xcff29d92, + (q31_t)0x76a0f8d2, (q31_t)0xcfeccac7, (q31_t)0x769e9c8d, (q31_t)0xcfe6f81a, (q31_t)0x769c3ffe, (q31_t)0xcfe1258b, (q31_t)0x7699e326, (q31_t)0xcfdb531a, + (q31_t)0x76978605, (q31_t)0xcfd580c6, (q31_t)0x7695289b, (q31_t)0xcfcfae8f, (q31_t)0x7692cae8, (q31_t)0xcfc9dc77, (q31_t)0x76906ceb, (q31_t)0xcfc40a7c, + (q31_t)0x768e0ea6, (q31_t)0xcfbe389f, (q31_t)0x768bb017, (q31_t)0xcfb866e0, (q31_t)0x7689513f, (q31_t)0xcfb2953f, (q31_t)0x7686f21e, (q31_t)0xcfacc3bb, + (q31_t)0x768492b4, (q31_t)0xcfa6f255, (q31_t)0x76823301, (q31_t)0xcfa1210d, (q31_t)0x767fd304, (q31_t)0xcf9b4fe3, (q31_t)0x767d72bf, (q31_t)0xcf957ed7, + (q31_t)0x767b1231, (q31_t)0xcf8fade9, (q31_t)0x7678b159, (q31_t)0xcf89dd18, (q31_t)0x76765038, (q31_t)0xcf840c65, (q31_t)0x7673eecf, (q31_t)0xcf7e3bd1, + (q31_t)0x76718d1c, (q31_t)0xcf786b5a, (q31_t)0x766f2b20, (q31_t)0xcf729b01, (q31_t)0x766cc8db, (q31_t)0xcf6ccac6, (q31_t)0x766a664d, (q31_t)0xcf66faa9, + (q31_t)0x76680376, (q31_t)0xcf612aaa, (q31_t)0x7665a056, (q31_t)0xcf5b5ac9, (q31_t)0x76633ced, (q31_t)0xcf558b06, (q31_t)0x7660d93b, (q31_t)0xcf4fbb61, + (q31_t)0x765e7540, (q31_t)0xcf49ebda, (q31_t)0x765c10fc, (q31_t)0xcf441c71, (q31_t)0x7659ac6f, (q31_t)0xcf3e4d26, (q31_t)0x76574798, (q31_t)0xcf387dfa, + (q31_t)0x7654e279, (q31_t)0xcf32aeeb, (q31_t)0x76527d11, (q31_t)0xcf2cdffa, (q31_t)0x76501760, (q31_t)0xcf271128, (q31_t)0x764db166, (q31_t)0xcf214274, + (q31_t)0x764b4b23, (q31_t)0xcf1b73de, (q31_t)0x7648e497, (q31_t)0xcf15a566, (q31_t)0x76467dc2, (q31_t)0xcf0fd70c, (q31_t)0x764416a4, (q31_t)0xcf0a08d0, + (q31_t)0x7641af3d, (q31_t)0xcf043ab3, (q31_t)0x763f478d, (q31_t)0xcefe6cb3, (q31_t)0x763cdf94, (q31_t)0xcef89ed2, (q31_t)0x763a7752, (q31_t)0xcef2d110, + (q31_t)0x76380ec8, (q31_t)0xceed036b, (q31_t)0x7635a5f4, (q31_t)0xcee735e5, (q31_t)0x76333cd8, (q31_t)0xcee1687d, (q31_t)0x7630d372, (q31_t)0xcedb9b33, + (q31_t)0x762e69c4, (q31_t)0xced5ce08, (q31_t)0x762bffcd, (q31_t)0xced000fb, (q31_t)0x7629958c, (q31_t)0xceca340c, (q31_t)0x76272b03, (q31_t)0xcec4673c, + (q31_t)0x7624c031, (q31_t)0xcebe9a8a, (q31_t)0x76225517, (q31_t)0xceb8cdf7, (q31_t)0x761fe9b3, (q31_t)0xceb30181, (q31_t)0x761d7e06, (q31_t)0xcead352b, + (q31_t)0x761b1211, (q31_t)0xcea768f2, (q31_t)0x7618a5d3, (q31_t)0xcea19cd8, (q31_t)0x7616394c, (q31_t)0xce9bd0dd, (q31_t)0x7613cc7c, (q31_t)0xce960500, + (q31_t)0x76115f63, (q31_t)0xce903942, (q31_t)0x760ef201, (q31_t)0xce8a6da2, (q31_t)0x760c8457, (q31_t)0xce84a220, (q31_t)0x760a1664, (q31_t)0xce7ed6bd, + (q31_t)0x7607a828, (q31_t)0xce790b79, (q31_t)0x760539a3, (q31_t)0xce734053, (q31_t)0x7602cad5, (q31_t)0xce6d754c, (q31_t)0x76005bbf, (q31_t)0xce67aa63, + (q31_t)0x75fdec60, (q31_t)0xce61df99, (q31_t)0x75fb7cb8, (q31_t)0xce5c14ed, (q31_t)0x75f90cc7, (q31_t)0xce564a60, (q31_t)0x75f69c8d, (q31_t)0xce507ff2, + (q31_t)0x75f42c0b, (q31_t)0xce4ab5a2, (q31_t)0x75f1bb40, (q31_t)0xce44eb71, (q31_t)0x75ef4a2c, (q31_t)0xce3f215f, (q31_t)0x75ecd8cf, (q31_t)0xce39576c, + (q31_t)0x75ea672a, (q31_t)0xce338d97, (q31_t)0x75e7f53c, (q31_t)0xce2dc3e1, (q31_t)0x75e58305, (q31_t)0xce27fa49, (q31_t)0x75e31086, (q31_t)0xce2230d0, + (q31_t)0x75e09dbd, (q31_t)0xce1c6777, (q31_t)0x75de2aac, (q31_t)0xce169e3b, (q31_t)0x75dbb753, (q31_t)0xce10d51f, (q31_t)0x75d943b0, (q31_t)0xce0b0c21, + (q31_t)0x75d6cfc5, (q31_t)0xce054343, (q31_t)0x75d45b92, (q31_t)0xcdff7a83, (q31_t)0x75d1e715, (q31_t)0xcdf9b1e2, (q31_t)0x75cf7250, (q31_t)0xcdf3e95f, + (q31_t)0x75ccfd42, (q31_t)0xcdee20fc, (q31_t)0x75ca87ec, (q31_t)0xcde858b8, (q31_t)0x75c8124d, (q31_t)0xcde29092, (q31_t)0x75c59c65, (q31_t)0xcddcc88b, + (q31_t)0x75c32634, (q31_t)0xcdd700a4, (q31_t)0x75c0afbb, (q31_t)0xcdd138db, (q31_t)0x75be38fa, (q31_t)0xcdcb7131, (q31_t)0x75bbc1ef, (q31_t)0xcdc5a9a6, + (q31_t)0x75b94a9c, (q31_t)0xcdbfe23a, (q31_t)0x75b6d301, (q31_t)0xcdba1aee, (q31_t)0x75b45b1d, (q31_t)0xcdb453c0, (q31_t)0x75b1e2f0, (q31_t)0xcdae8cb1, + (q31_t)0x75af6a7b, (q31_t)0xcda8c5c1, (q31_t)0x75acf1bd, (q31_t)0xcda2fef0, (q31_t)0x75aa78b6, (q31_t)0xcd9d383f, (q31_t)0x75a7ff67, (q31_t)0xcd9771ac, + (q31_t)0x75a585cf, (q31_t)0xcd91ab39, (q31_t)0x75a30bef, (q31_t)0xcd8be4e4, (q31_t)0x75a091c6, (q31_t)0xcd861eaf, (q31_t)0x759e1755, (q31_t)0xcd805899, + (q31_t)0x759b9c9b, (q31_t)0xcd7a92a2, (q31_t)0x75992198, (q31_t)0xcd74ccca, (q31_t)0x7596a64d, (q31_t)0xcd6f0711, (q31_t)0x75942ab9, (q31_t)0xcd694178, + (q31_t)0x7591aedd, (q31_t)0xcd637bfe, (q31_t)0x758f32b9, (q31_t)0xcd5db6a3, (q31_t)0x758cb64c, (q31_t)0xcd57f167, (q31_t)0x758a3996, (q31_t)0xcd522c4a, + (q31_t)0x7587bc98, (q31_t)0xcd4c674d, (q31_t)0x75853f51, (q31_t)0xcd46a26f, (q31_t)0x7582c1c2, (q31_t)0xcd40ddb0, (q31_t)0x758043ea, (q31_t)0xcd3b1911, + (q31_t)0x757dc5ca, (q31_t)0xcd355491, (q31_t)0x757b4762, (q31_t)0xcd2f9030, (q31_t)0x7578c8b0, (q31_t)0xcd29cbee, (q31_t)0x757649b7, (q31_t)0xcd2407cc, + (q31_t)0x7573ca75, (q31_t)0xcd1e43ca, (q31_t)0x75714aea, (q31_t)0xcd187fe6, (q31_t)0x756ecb18, (q31_t)0xcd12bc22, (q31_t)0x756c4afc, (q31_t)0xcd0cf87e, + (q31_t)0x7569ca99, (q31_t)0xcd0734f9, (q31_t)0x756749ec, (q31_t)0xcd017193, (q31_t)0x7564c8f8, (q31_t)0xccfbae4d, (q31_t)0x756247bb, (q31_t)0xccf5eb26, + (q31_t)0x755fc635, (q31_t)0xccf0281f, (q31_t)0x755d4467, (q31_t)0xccea6538, (q31_t)0x755ac251, (q31_t)0xcce4a26f, (q31_t)0x75583ff3, (q31_t)0xccdedfc7, + (q31_t)0x7555bd4c, (q31_t)0xccd91d3d, (q31_t)0x75533a5c, (q31_t)0xccd35ad4, (q31_t)0x7550b725, (q31_t)0xcccd988a, (q31_t)0x754e33a4, (q31_t)0xccc7d65f, + (q31_t)0x754bafdc, (q31_t)0xccc21455, (q31_t)0x75492bcb, (q31_t)0xccbc5269, (q31_t)0x7546a772, (q31_t)0xccb6909e, (q31_t)0x754422d0, (q31_t)0xccb0cef2, + (q31_t)0x75419de7, (q31_t)0xccab0d65, (q31_t)0x753f18b4, (q31_t)0xcca54bf9, (q31_t)0x753c933a, (q31_t)0xcc9f8aac, (q31_t)0x753a0d77, (q31_t)0xcc99c97e, + (q31_t)0x7537876c, (q31_t)0xcc940871, (q31_t)0x75350118, (q31_t)0xcc8e4783, (q31_t)0x75327a7d, (q31_t)0xcc8886b5, (q31_t)0x752ff399, (q31_t)0xcc82c607, + (q31_t)0x752d6c6c, (q31_t)0xcc7d0578, (q31_t)0x752ae4f8, (q31_t)0xcc774509, (q31_t)0x75285d3b, (q31_t)0xcc7184ba, (q31_t)0x7525d536, (q31_t)0xcc6bc48b, + (q31_t)0x75234ce8, (q31_t)0xcc66047b, (q31_t)0x7520c453, (q31_t)0xcc60448c, (q31_t)0x751e3b75, (q31_t)0xcc5a84bc, (q31_t)0x751bb24f, (q31_t)0xcc54c50c, + (q31_t)0x751928e0, (q31_t)0xcc4f057c, (q31_t)0x75169f2a, (q31_t)0xcc49460c, (q31_t)0x7514152b, (q31_t)0xcc4386bc, (q31_t)0x75118ae4, (q31_t)0xcc3dc78b, + (q31_t)0x750f0054, (q31_t)0xcc38087b, (q31_t)0x750c757d, (q31_t)0xcc32498a, (q31_t)0x7509ea5d, (q31_t)0xcc2c8aba, (q31_t)0x75075ef5, (q31_t)0xcc26cc09, + (q31_t)0x7504d345, (q31_t)0xcc210d79, (q31_t)0x7502474d, (q31_t)0xcc1b4f08, (q31_t)0x74ffbb0d, (q31_t)0xcc1590b8, (q31_t)0x74fd2e84, (q31_t)0xcc0fd287, + (q31_t)0x74faa1b3, (q31_t)0xcc0a1477, (q31_t)0x74f8149a, (q31_t)0xcc045686, (q31_t)0x74f58739, (q31_t)0xcbfe98b6, (q31_t)0x74f2f990, (q31_t)0xcbf8db05, + (q31_t)0x74f06b9e, (q31_t)0xcbf31d75, (q31_t)0x74eddd65, (q31_t)0xcbed6005, (q31_t)0x74eb4ee3, (q31_t)0xcbe7a2b5, (q31_t)0x74e8c01a, (q31_t)0xcbe1e585, + (q31_t)0x74e63108, (q31_t)0xcbdc2876, (q31_t)0x74e3a1ae, (q31_t)0xcbd66b86, (q31_t)0x74e1120c, (q31_t)0xcbd0aeb7, (q31_t)0x74de8221, (q31_t)0xcbcaf208, + (q31_t)0x74dbf1ef, (q31_t)0xcbc53579, (q31_t)0x74d96175, (q31_t)0xcbbf790a, (q31_t)0x74d6d0b2, (q31_t)0xcbb9bcbb, (q31_t)0x74d43fa8, (q31_t)0xcbb4008d, + (q31_t)0x74d1ae55, (q31_t)0xcbae447f, (q31_t)0x74cf1cbb, (q31_t)0xcba88891, (q31_t)0x74cc8ad8, (q31_t)0xcba2ccc4, (q31_t)0x74c9f8ad, (q31_t)0xcb9d1117, + (q31_t)0x74c7663a, (q31_t)0xcb97558a, (q31_t)0x74c4d380, (q31_t)0xcb919a1d, (q31_t)0x74c2407d, (q31_t)0xcb8bded1, (q31_t)0x74bfad32, (q31_t)0xcb8623a5, + (q31_t)0x74bd199f, (q31_t)0xcb80689a, (q31_t)0x74ba85c4, (q31_t)0xcb7aadaf, (q31_t)0x74b7f1a1, (q31_t)0xcb74f2e4, (q31_t)0x74b55d36, (q31_t)0xcb6f383a, + (q31_t)0x74b2c884, (q31_t)0xcb697db0, (q31_t)0x74b03389, (q31_t)0xcb63c347, (q31_t)0x74ad9e46, (q31_t)0xcb5e08fe, (q31_t)0x74ab08bb, (q31_t)0xcb584ed6, + (q31_t)0x74a872e8, (q31_t)0xcb5294ce, (q31_t)0x74a5dccd, (q31_t)0xcb4cdae6, (q31_t)0x74a3466b, (q31_t)0xcb47211f, (q31_t)0x74a0afc0, (q31_t)0xcb416779, + (q31_t)0x749e18cd, (q31_t)0xcb3badf3, (q31_t)0x749b8193, (q31_t)0xcb35f48d, (q31_t)0x7498ea11, (q31_t)0xcb303b49, (q31_t)0x74965246, (q31_t)0xcb2a8224, + (q31_t)0x7493ba34, (q31_t)0xcb24c921, (q31_t)0x749121da, (q31_t)0xcb1f103e, (q31_t)0x748e8938, (q31_t)0xcb19577b, (q31_t)0x748bf04d, (q31_t)0xcb139ed9, + (q31_t)0x7489571c, (q31_t)0xcb0de658, (q31_t)0x7486bda2, (q31_t)0xcb082df8, (q31_t)0x748423e0, (q31_t)0xcb0275b8, (q31_t)0x748189d7, (q31_t)0xcafcbd99, + (q31_t)0x747eef85, (q31_t)0xcaf7059a, (q31_t)0x747c54ec, (q31_t)0xcaf14dbd, (q31_t)0x7479ba0b, (q31_t)0xcaeb9600, (q31_t)0x74771ee2, (q31_t)0xcae5de64, + (q31_t)0x74748371, (q31_t)0xcae026e8, (q31_t)0x7471e7b8, (q31_t)0xcada6f8d, (q31_t)0x746f4bb8, (q31_t)0xcad4b853, (q31_t)0x746caf70, (q31_t)0xcacf013a, + (q31_t)0x746a12df, (q31_t)0xcac94a42, (q31_t)0x74677608, (q31_t)0xcac3936b, (q31_t)0x7464d8e8, (q31_t)0xcabddcb4, (q31_t)0x74623b80, (q31_t)0xcab8261e, + (q31_t)0x745f9dd1, (q31_t)0xcab26fa9, (q31_t)0x745cffda, (q31_t)0xcaacb955, (q31_t)0x745a619b, (q31_t)0xcaa70322, (q31_t)0x7457c314, (q31_t)0xcaa14d10, + (q31_t)0x74552446, (q31_t)0xca9b971e, (q31_t)0x74528530, (q31_t)0xca95e14e, (q31_t)0x744fe5d2, (q31_t)0xca902b9f, (q31_t)0x744d462c, (q31_t)0xca8a7610, + (q31_t)0x744aa63f, (q31_t)0xca84c0a3, (q31_t)0x7448060a, (q31_t)0xca7f0b56, (q31_t)0x7445658d, (q31_t)0xca79562b, (q31_t)0x7442c4c8, (q31_t)0xca73a120, + (q31_t)0x744023bc, (q31_t)0xca6dec37, (q31_t)0x743d8268, (q31_t)0xca68376e, (q31_t)0x743ae0cc, (q31_t)0xca6282c7, (q31_t)0x74383ee9, (q31_t)0xca5cce40, + (q31_t)0x74359cbd, (q31_t)0xca5719db, (q31_t)0x7432fa4b, (q31_t)0xca516597, (q31_t)0x74305790, (q31_t)0xca4bb174, (q31_t)0x742db48e, (q31_t)0xca45fd72, + (q31_t)0x742b1144, (q31_t)0xca404992, (q31_t)0x74286db3, (q31_t)0xca3a95d2, (q31_t)0x7425c9da, (q31_t)0xca34e234, (q31_t)0x742325b9, (q31_t)0xca2f2eb6, + (q31_t)0x74208150, (q31_t)0xca297b5a, (q31_t)0x741ddca0, (q31_t)0xca23c820, (q31_t)0x741b37a9, (q31_t)0xca1e1506, (q31_t)0x74189269, (q31_t)0xca18620e, + (q31_t)0x7415ece2, (q31_t)0xca12af37, (q31_t)0x74134714, (q31_t)0xca0cfc81, (q31_t)0x7410a0fe, (q31_t)0xca0749ec, (q31_t)0x740dfaa0, (q31_t)0xca019779, + (q31_t)0x740b53fb, (q31_t)0xc9fbe527, (q31_t)0x7408ad0e, (q31_t)0xc9f632f6, (q31_t)0x740605d9, (q31_t)0xc9f080e7, (q31_t)0x74035e5d, (q31_t)0xc9eacef9, + (q31_t)0x7400b69a, (q31_t)0xc9e51d2d, (q31_t)0x73fe0e8f, (q31_t)0xc9df6b81, (q31_t)0x73fb663c, (q31_t)0xc9d9b9f7, (q31_t)0x73f8bda2, (q31_t)0xc9d4088f, + (q31_t)0x73f614c0, (q31_t)0xc9ce5748, (q31_t)0x73f36b97, (q31_t)0xc9c8a622, (q31_t)0x73f0c226, (q31_t)0xc9c2f51e, (q31_t)0x73ee186e, (q31_t)0xc9bd443c, + (q31_t)0x73eb6e6e, (q31_t)0xc9b7937a, (q31_t)0x73e8c426, (q31_t)0xc9b1e2db, (q31_t)0x73e61997, (q31_t)0xc9ac325d, (q31_t)0x73e36ec1, (q31_t)0xc9a68200, + (q31_t)0x73e0c3a3, (q31_t)0xc9a0d1c5, (q31_t)0x73de183e, (q31_t)0xc99b21ab, (q31_t)0x73db6c91, (q31_t)0xc99571b3, (q31_t)0x73d8c09d, (q31_t)0xc98fc1dc, + (q31_t)0x73d61461, (q31_t)0xc98a1227, (q31_t)0x73d367de, (q31_t)0xc9846294, (q31_t)0x73d0bb13, (q31_t)0xc97eb322, (q31_t)0x73ce0e01, (q31_t)0xc97903d2, + (q31_t)0x73cb60a8, (q31_t)0xc97354a4, (q31_t)0x73c8b307, (q31_t)0xc96da597, (q31_t)0x73c6051f, (q31_t)0xc967f6ac, (q31_t)0x73c356ef, (q31_t)0xc96247e2, + (q31_t)0x73c0a878, (q31_t)0xc95c993a, (q31_t)0x73bdf9b9, (q31_t)0xc956eab4, (q31_t)0x73bb4ab3, (q31_t)0xc9513c50, (q31_t)0x73b89b66, (q31_t)0xc94b8e0d, + (q31_t)0x73b5ebd1, (q31_t)0xc945dfec, (q31_t)0x73b33bf5, (q31_t)0xc94031ed, (q31_t)0x73b08bd1, (q31_t)0xc93a8410, (q31_t)0x73addb67, (q31_t)0xc934d654, + (q31_t)0x73ab2ab4, (q31_t)0xc92f28ba, (q31_t)0x73a879bb, (q31_t)0xc9297b42, (q31_t)0x73a5c87a, (q31_t)0xc923cdec, (q31_t)0x73a316f2, (q31_t)0xc91e20b8, + (q31_t)0x73a06522, (q31_t)0xc91873a5, (q31_t)0x739db30b, (q31_t)0xc912c6b5, (q31_t)0x739b00ad, (q31_t)0xc90d19e6, (q31_t)0x73984e07, (q31_t)0xc9076d39, + (q31_t)0x73959b1b, (q31_t)0xc901c0ae, (q31_t)0x7392e7e6, (q31_t)0xc8fc1445, (q31_t)0x7390346b, (q31_t)0xc8f667fe, (q31_t)0x738d80a8, (q31_t)0xc8f0bbd9, + (q31_t)0x738acc9e, (q31_t)0xc8eb0fd6, (q31_t)0x7388184d, (q31_t)0xc8e563f5, (q31_t)0x738563b5, (q31_t)0xc8dfb836, (q31_t)0x7382aed5, (q31_t)0xc8da0c99, + (q31_t)0x737ff9ae, (q31_t)0xc8d4611d, (q31_t)0x737d4440, (q31_t)0xc8ceb5c4, (q31_t)0x737a8e8a, (q31_t)0xc8c90a8d, (q31_t)0x7377d88d, (q31_t)0xc8c35f78, + (q31_t)0x73752249, (q31_t)0xc8bdb485, (q31_t)0x73726bbe, (q31_t)0xc8b809b4, (q31_t)0x736fb4ec, (q31_t)0xc8b25f06, (q31_t)0x736cfdd2, (q31_t)0xc8acb479, + (q31_t)0x736a4671, (q31_t)0xc8a70a0e, (q31_t)0x73678ec9, (q31_t)0xc8a15fc6, (q31_t)0x7364d6da, (q31_t)0xc89bb5a0, (q31_t)0x73621ea4, (q31_t)0xc8960b9c, + (q31_t)0x735f6626, (q31_t)0xc89061ba, (q31_t)0x735cad61, (q31_t)0xc88ab7fa, (q31_t)0x7359f456, (q31_t)0xc8850e5d, (q31_t)0x73573b03, (q31_t)0xc87f64e2, + (q31_t)0x73548168, (q31_t)0xc879bb89, (q31_t)0x7351c787, (q31_t)0xc8741252, (q31_t)0x734f0d5f, (q31_t)0xc86e693d, (q31_t)0x734c52ef, (q31_t)0xc868c04b, + (q31_t)0x73499838, (q31_t)0xc863177b, (q31_t)0x7346dd3a, (q31_t)0xc85d6ece, (q31_t)0x734421f6, (q31_t)0xc857c642, (q31_t)0x7341666a, (q31_t)0xc8521dd9, + (q31_t)0x733eaa96, (q31_t)0xc84c7593, (q31_t)0x733bee7c, (q31_t)0xc846cd6e, (q31_t)0x7339321b, (q31_t)0xc841256d, (q31_t)0x73367572, (q31_t)0xc83b7d8d, + (q31_t)0x7333b883, (q31_t)0xc835d5d0, (q31_t)0x7330fb4d, (q31_t)0xc8302e35, (q31_t)0x732e3dcf, (q31_t)0xc82a86bd, (q31_t)0x732b800a, (q31_t)0xc824df67, + (q31_t)0x7328c1ff, (q31_t)0xc81f3834, (q31_t)0x732603ac, (q31_t)0xc8199123, (q31_t)0x73234512, (q31_t)0xc813ea35, (q31_t)0x73208632, (q31_t)0xc80e4369, + (q31_t)0x731dc70a, (q31_t)0xc8089cbf, (q31_t)0x731b079b, (q31_t)0xc802f638, (q31_t)0x731847e5, (q31_t)0xc7fd4fd4, (q31_t)0x731587e8, (q31_t)0xc7f7a992, + (q31_t)0x7312c7a5, (q31_t)0xc7f20373, (q31_t)0x7310071a, (q31_t)0xc7ec5d76, (q31_t)0x730d4648, (q31_t)0xc7e6b79c, (q31_t)0x730a8530, (q31_t)0xc7e111e5, + (q31_t)0x7307c3d0, (q31_t)0xc7db6c50, (q31_t)0x73050229, (q31_t)0xc7d5c6de, (q31_t)0x7302403c, (q31_t)0xc7d0218e, (q31_t)0x72ff7e07, (q31_t)0xc7ca7c61, + (q31_t)0x72fcbb8c, (q31_t)0xc7c4d757, (q31_t)0x72f9f8c9, (q31_t)0xc7bf3270, (q31_t)0x72f735c0, (q31_t)0xc7b98dab, (q31_t)0x72f47270, (q31_t)0xc7b3e909, + (q31_t)0x72f1aed9, (q31_t)0xc7ae4489, (q31_t)0x72eeeafb, (q31_t)0xc7a8a02c, (q31_t)0x72ec26d6, (q31_t)0xc7a2fbf3, (q31_t)0x72e9626a, (q31_t)0xc79d57db, + (q31_t)0x72e69db7, (q31_t)0xc797b3e7, (q31_t)0x72e3d8be, (q31_t)0xc7921015, (q31_t)0x72e1137d, (q31_t)0xc78c6c67, (q31_t)0x72de4df6, (q31_t)0xc786c8db, + (q31_t)0x72db8828, (q31_t)0xc7812572, (q31_t)0x72d8c213, (q31_t)0xc77b822b, (q31_t)0x72d5fbb7, (q31_t)0xc775df08, (q31_t)0x72d33514, (q31_t)0xc7703c08, + (q31_t)0x72d06e2b, (q31_t)0xc76a992a, (q31_t)0x72cda6fb, (q31_t)0xc764f66f, (q31_t)0x72cadf83, (q31_t)0xc75f53d7, (q31_t)0x72c817c6, (q31_t)0xc759b163, + (q31_t)0x72c54fc1, (q31_t)0xc7540f11, (q31_t)0x72c28775, (q31_t)0xc74e6ce2, (q31_t)0x72bfbee3, (q31_t)0xc748cad6, (q31_t)0x72bcf60a, (q31_t)0xc74328ed, + (q31_t)0x72ba2cea, (q31_t)0xc73d8727, (q31_t)0x72b76383, (q31_t)0xc737e584, (q31_t)0x72b499d6, (q31_t)0xc7324404, (q31_t)0x72b1cfe1, (q31_t)0xc72ca2a7, + (q31_t)0x72af05a7, (q31_t)0xc727016d, (q31_t)0x72ac3b25, (q31_t)0xc7216056, (q31_t)0x72a9705c, (q31_t)0xc71bbf62, (q31_t)0x72a6a54d, (q31_t)0xc7161e92, + (q31_t)0x72a3d9f7, (q31_t)0xc7107de4, (q31_t)0x72a10e5b, (q31_t)0xc70add5a, (q31_t)0x729e4277, (q31_t)0xc7053cf2, (q31_t)0x729b764d, (q31_t)0xc6ff9cae, + (q31_t)0x7298a9dd, (q31_t)0xc6f9fc8d, (q31_t)0x7295dd25, (q31_t)0xc6f45c8f, (q31_t)0x72931027, (q31_t)0xc6eebcb5, (q31_t)0x729042e3, (q31_t)0xc6e91cfd, + (q31_t)0x728d7557, (q31_t)0xc6e37d69, (q31_t)0x728aa785, (q31_t)0xc6ddddf8, (q31_t)0x7287d96c, (q31_t)0xc6d83eab, (q31_t)0x72850b0d, (q31_t)0xc6d29f80, + (q31_t)0x72823c67, (q31_t)0xc6cd0079, (q31_t)0x727f6d7a, (q31_t)0xc6c76195, (q31_t)0x727c9e47, (q31_t)0xc6c1c2d4, (q31_t)0x7279cecd, (q31_t)0xc6bc2437, + (q31_t)0x7276ff0d, (q31_t)0xc6b685bd, (q31_t)0x72742f05, (q31_t)0xc6b0e767, (q31_t)0x72715eb8, (q31_t)0xc6ab4933, (q31_t)0x726e8e23, (q31_t)0xc6a5ab23, + (q31_t)0x726bbd48, (q31_t)0xc6a00d37, (q31_t)0x7268ec27, (q31_t)0xc69a6f6e, (q31_t)0x72661abf, (q31_t)0xc694d1c8, (q31_t)0x72634910, (q31_t)0xc68f3446, + (q31_t)0x7260771b, (q31_t)0xc68996e7, (q31_t)0x725da4df, (q31_t)0xc683f9ab, (q31_t)0x725ad25d, (q31_t)0xc67e5c93, (q31_t)0x7257ff94, (q31_t)0xc678bf9f, + (q31_t)0x72552c85, (q31_t)0xc67322ce, (q31_t)0x7252592f, (q31_t)0xc66d8620, (q31_t)0x724f8593, (q31_t)0xc667e996, (q31_t)0x724cb1b0, (q31_t)0xc6624d30, + (q31_t)0x7249dd86, (q31_t)0xc65cb0ed, (q31_t)0x72470916, (q31_t)0xc65714cd, (q31_t)0x72443460, (q31_t)0xc65178d1, (q31_t)0x72415f63, (q31_t)0xc64bdcf9, + (q31_t)0x723e8a20, (q31_t)0xc6464144, (q31_t)0x723bb496, (q31_t)0xc640a5b3, (q31_t)0x7238dec5, (q31_t)0xc63b0a46, (q31_t)0x723608af, (q31_t)0xc6356efc, + (q31_t)0x72333251, (q31_t)0xc62fd3d6, (q31_t)0x72305bae, (q31_t)0xc62a38d4, (q31_t)0x722d84c4, (q31_t)0xc6249df5, (q31_t)0x722aad93, (q31_t)0xc61f033a, + (q31_t)0x7227d61c, (q31_t)0xc61968a2, (q31_t)0x7224fe5f, (q31_t)0xc613ce2f, (q31_t)0x7222265b, (q31_t)0xc60e33df, (q31_t)0x721f4e11, (q31_t)0xc60899b2, + (q31_t)0x721c7580, (q31_t)0xc602ffaa, (q31_t)0x72199ca9, (q31_t)0xc5fd65c5, (q31_t)0x7216c38c, (q31_t)0xc5f7cc04, (q31_t)0x7213ea28, (q31_t)0xc5f23267, + (q31_t)0x7211107e, (q31_t)0xc5ec98ee, (q31_t)0x720e368d, (q31_t)0xc5e6ff98, (q31_t)0x720b5c57, (q31_t)0xc5e16667, (q31_t)0x720881d9, (q31_t)0xc5dbcd59, + (q31_t)0x7205a716, (q31_t)0xc5d6346f, (q31_t)0x7202cc0c, (q31_t)0xc5d09ba9, (q31_t)0x71fff0bc, (q31_t)0xc5cb0307, (q31_t)0x71fd1525, (q31_t)0xc5c56a89, + (q31_t)0x71fa3949, (q31_t)0xc5bfd22e, (q31_t)0x71f75d25, (q31_t)0xc5ba39f8, (q31_t)0x71f480bc, (q31_t)0xc5b4a1e5, (q31_t)0x71f1a40c, (q31_t)0xc5af09f7, + (q31_t)0x71eec716, (q31_t)0xc5a9722c, (q31_t)0x71ebe9da, (q31_t)0xc5a3da86, (q31_t)0x71e90c57, (q31_t)0xc59e4303, (q31_t)0x71e62e8f, (q31_t)0xc598aba5, + (q31_t)0x71e35080, (q31_t)0xc593146a, (q31_t)0x71e0722a, (q31_t)0xc58d7d54, (q31_t)0x71dd938f, (q31_t)0xc587e661, (q31_t)0x71dab4ad, (q31_t)0xc5824f93, + (q31_t)0x71d7d585, (q31_t)0xc57cb8e9, (q31_t)0x71d4f617, (q31_t)0xc5772263, (q31_t)0x71d21662, (q31_t)0xc5718c00, (q31_t)0x71cf3667, (q31_t)0xc56bf5c2, + (q31_t)0x71cc5626, (q31_t)0xc5665fa9, (q31_t)0x71c9759f, (q31_t)0xc560c9b3, (q31_t)0x71c694d2, (q31_t)0xc55b33e2, (q31_t)0x71c3b3bf, (q31_t)0xc5559e34, + (q31_t)0x71c0d265, (q31_t)0xc55008ab, (q31_t)0x71bdf0c5, (q31_t)0xc54a7346, (q31_t)0x71bb0edf, (q31_t)0xc544de05, (q31_t)0x71b82cb3, (q31_t)0xc53f48e9, + (q31_t)0x71b54a41, (q31_t)0xc539b3f1, (q31_t)0x71b26788, (q31_t)0xc5341f1d, (q31_t)0x71af848a, (q31_t)0xc52e8a6d, (q31_t)0x71aca145, (q31_t)0xc528f5e1, + (q31_t)0x71a9bdba, (q31_t)0xc523617a, (q31_t)0x71a6d9e9, (q31_t)0xc51dcd37, (q31_t)0x71a3f5d2, (q31_t)0xc5183919, (q31_t)0x71a11175, (q31_t)0xc512a51f, + (q31_t)0x719e2cd2, (q31_t)0xc50d1149, (q31_t)0x719b47e9, (q31_t)0xc5077d97, (q31_t)0x719862b9, (q31_t)0xc501ea0a, (q31_t)0x71957d44, (q31_t)0xc4fc56a2, + (q31_t)0x71929789, (q31_t)0xc4f6c35d, (q31_t)0x718fb187, (q31_t)0xc4f1303d, (q31_t)0x718ccb3f, (q31_t)0xc4eb9d42, (q31_t)0x7189e4b2, (q31_t)0xc4e60a6b, + (q31_t)0x7186fdde, (q31_t)0xc4e077b8, (q31_t)0x718416c4, (q31_t)0xc4dae52a, (q31_t)0x71812f65, (q31_t)0xc4d552c1, (q31_t)0x717e47bf, (q31_t)0xc4cfc07c, + (q31_t)0x717b5fd3, (q31_t)0xc4ca2e5b, (q31_t)0x717877a1, (q31_t)0xc4c49c5f, (q31_t)0x71758f29, (q31_t)0xc4bf0a87, (q31_t)0x7172a66c, (q31_t)0xc4b978d4, + (q31_t)0x716fbd68, (q31_t)0xc4b3e746, (q31_t)0x716cd41e, (q31_t)0xc4ae55dc, (q31_t)0x7169ea8f, (q31_t)0xc4a8c497, (q31_t)0x716700b9, (q31_t)0xc4a33376, + (q31_t)0x7164169d, (q31_t)0xc49da27a, (q31_t)0x71612c3c, (q31_t)0xc49811a3, (q31_t)0x715e4194, (q31_t)0xc49280f0, (q31_t)0x715b56a7, (q31_t)0xc48cf062, + (q31_t)0x71586b74, (q31_t)0xc4875ff9, (q31_t)0x71557ffa, (q31_t)0xc481cfb4, (q31_t)0x7152943b, (q31_t)0xc47c3f94, (q31_t)0x714fa836, (q31_t)0xc476af98, + (q31_t)0x714cbbeb, (q31_t)0xc4711fc2, (q31_t)0x7149cf5a, (q31_t)0xc46b9010, (q31_t)0x7146e284, (q31_t)0xc4660083, (q31_t)0x7143f567, (q31_t)0xc460711b, + (q31_t)0x71410805, (q31_t)0xc45ae1d7, (q31_t)0x713e1a5c, (q31_t)0xc45552b8, (q31_t)0x713b2c6e, (q31_t)0xc44fc3be, (q31_t)0x71383e3a, (q31_t)0xc44a34e9, + (q31_t)0x71354fc0, (q31_t)0xc444a639, (q31_t)0x71326101, (q31_t)0xc43f17ad, (q31_t)0x712f71fb, (q31_t)0xc4398947, (q31_t)0x712c82b0, (q31_t)0xc433fb05, + (q31_t)0x7129931f, (q31_t)0xc42e6ce8, (q31_t)0x7126a348, (q31_t)0xc428def0, (q31_t)0x7123b32b, (q31_t)0xc423511d, (q31_t)0x7120c2c8, (q31_t)0xc41dc36f, + (q31_t)0x711dd220, (q31_t)0xc41835e6, (q31_t)0x711ae132, (q31_t)0xc412a882, (q31_t)0x7117effe, (q31_t)0xc40d1b42, (q31_t)0x7114fe84, (q31_t)0xc4078e28, + (q31_t)0x71120cc5, (q31_t)0xc4020133, (q31_t)0x710f1ac0, (q31_t)0xc3fc7462, (q31_t)0x710c2875, (q31_t)0xc3f6e7b7, (q31_t)0x710935e4, (q31_t)0xc3f15b31, + (q31_t)0x7106430e, (q31_t)0xc3ebced0, (q31_t)0x71034ff2, (q31_t)0xc3e64294, (q31_t)0x71005c90, (q31_t)0xc3e0b67d, (q31_t)0x70fd68e9, (q31_t)0xc3db2a8b, + (q31_t)0x70fa74fc, (q31_t)0xc3d59ebe, (q31_t)0x70f780c9, (q31_t)0xc3d01316, (q31_t)0x70f48c50, (q31_t)0xc3ca8793, (q31_t)0x70f19792, (q31_t)0xc3c4fc36, + (q31_t)0x70eea28e, (q31_t)0xc3bf70fd, (q31_t)0x70ebad45, (q31_t)0xc3b9e5ea, (q31_t)0x70e8b7b5, (q31_t)0xc3b45afc, (q31_t)0x70e5c1e1, (q31_t)0xc3aed034, + (q31_t)0x70e2cbc6, (q31_t)0xc3a94590, (q31_t)0x70dfd566, (q31_t)0xc3a3bb12, (q31_t)0x70dcdec0, (q31_t)0xc39e30b8, (q31_t)0x70d9e7d5, (q31_t)0xc398a685, + (q31_t)0x70d6f0a4, (q31_t)0xc3931c76, (q31_t)0x70d3f92d, (q31_t)0xc38d928d, (q31_t)0x70d10171, (q31_t)0xc38808c9, (q31_t)0x70ce096f, (q31_t)0xc3827f2a, + (q31_t)0x70cb1128, (q31_t)0xc37cf5b0, (q31_t)0x70c8189b, (q31_t)0xc3776c5c, (q31_t)0x70c51fc8, (q31_t)0xc371e32d, (q31_t)0x70c226b0, (q31_t)0xc36c5a24, + (q31_t)0x70bf2d53, (q31_t)0xc366d140, (q31_t)0x70bc33b0, (q31_t)0xc3614881, (q31_t)0x70b939c7, (q31_t)0xc35bbfe8, (q31_t)0x70b63f99, (q31_t)0xc3563774, + (q31_t)0x70b34525, (q31_t)0xc350af26, (q31_t)0x70b04a6b, (q31_t)0xc34b26fc, (q31_t)0x70ad4f6d, (q31_t)0xc3459ef9, (q31_t)0x70aa5428, (q31_t)0xc340171b, + (q31_t)0x70a7589f, (q31_t)0xc33a8f62, (q31_t)0x70a45ccf, (q31_t)0xc33507cf, (q31_t)0x70a160ba, (q31_t)0xc32f8061, (q31_t)0x709e6460, (q31_t)0xc329f919, + (q31_t)0x709b67c0, (q31_t)0xc32471f7, (q31_t)0x70986adb, (q31_t)0xc31eeaf9, (q31_t)0x70956db1, (q31_t)0xc3196422, (q31_t)0x70927041, (q31_t)0xc313dd70, + (q31_t)0x708f728b, (q31_t)0xc30e56e4, (q31_t)0x708c7490, (q31_t)0xc308d07d, (q31_t)0x70897650, (q31_t)0xc3034a3c, (q31_t)0x708677ca, (q31_t)0xc2fdc420, + (q31_t)0x708378ff, (q31_t)0xc2f83e2a, (q31_t)0x708079ee, (q31_t)0xc2f2b85a, (q31_t)0x707d7a98, (q31_t)0xc2ed32af, (q31_t)0x707a7afd, (q31_t)0xc2e7ad2a, + (q31_t)0x70777b1c, (q31_t)0xc2e227cb, (q31_t)0x70747af6, (q31_t)0xc2dca291, (q31_t)0x70717a8a, (q31_t)0xc2d71d7e, (q31_t)0x706e79d9, (q31_t)0xc2d1988f, + (q31_t)0x706b78e3, (q31_t)0xc2cc13c7, (q31_t)0x706877a7, (q31_t)0xc2c68f24, (q31_t)0x70657626, (q31_t)0xc2c10aa7, (q31_t)0x70627460, (q31_t)0xc2bb8650, + (q31_t)0x705f7255, (q31_t)0xc2b6021f, (q31_t)0x705c7004, (q31_t)0xc2b07e14, (q31_t)0x70596d6d, (q31_t)0xc2aafa2e, (q31_t)0x70566a92, (q31_t)0xc2a5766e, + (q31_t)0x70536771, (q31_t)0xc29ff2d4, (q31_t)0x7050640b, (q31_t)0xc29a6f60, (q31_t)0x704d6060, (q31_t)0xc294ec12, (q31_t)0x704a5c6f, (q31_t)0xc28f68e9, + (q31_t)0x70475839, (q31_t)0xc289e5e7, (q31_t)0x704453be, (q31_t)0xc284630a, (q31_t)0x70414efd, (q31_t)0xc27ee054, (q31_t)0x703e49f8, (q31_t)0xc2795dc3, + (q31_t)0x703b44ad, (q31_t)0xc273db58, (q31_t)0x70383f1d, (q31_t)0xc26e5913, (q31_t)0x70353947, (q31_t)0xc268d6f5, (q31_t)0x7032332d, (q31_t)0xc26354fc, + (q31_t)0x702f2ccd, (q31_t)0xc25dd329, (q31_t)0x702c2628, (q31_t)0xc258517c, (q31_t)0x70291f3e, (q31_t)0xc252cff5, (q31_t)0x7026180e, (q31_t)0xc24d4e95, + (q31_t)0x7023109a, (q31_t)0xc247cd5a, (q31_t)0x702008e0, (q31_t)0xc2424c46, (q31_t)0x701d00e1, (q31_t)0xc23ccb57, (q31_t)0x7019f89d, (q31_t)0xc2374a8f, + (q31_t)0x7016f014, (q31_t)0xc231c9ec, (q31_t)0x7013e746, (q31_t)0xc22c4970, (q31_t)0x7010de32, (q31_t)0xc226c91a, (q31_t)0x700dd4da, (q31_t)0xc22148ea, + (q31_t)0x700acb3c, (q31_t)0xc21bc8e1, (q31_t)0x7007c159, (q31_t)0xc21648fd, (q31_t)0x7004b731, (q31_t)0xc210c940, (q31_t)0x7001acc4, (q31_t)0xc20b49a9, + (q31_t)0x6ffea212, (q31_t)0xc205ca38, (q31_t)0x6ffb971b, (q31_t)0xc2004aed, (q31_t)0x6ff88bde, (q31_t)0xc1facbc9, (q31_t)0x6ff5805d, (q31_t)0xc1f54cca, + (q31_t)0x6ff27497, (q31_t)0xc1efcdf3, (q31_t)0x6fef688b, (q31_t)0xc1ea4f41, (q31_t)0x6fec5c3b, (q31_t)0xc1e4d0b6, (q31_t)0x6fe94fa5, (q31_t)0xc1df5251, + (q31_t)0x6fe642ca, (q31_t)0xc1d9d412, (q31_t)0x6fe335ab, (q31_t)0xc1d455f9, (q31_t)0x6fe02846, (q31_t)0xc1ced807, (q31_t)0x6fdd1a9c, (q31_t)0xc1c95a3c, + (q31_t)0x6fda0cae, (q31_t)0xc1c3dc97, (q31_t)0x6fd6fe7a, (q31_t)0xc1be5f18, (q31_t)0x6fd3f001, (q31_t)0xc1b8e1bf, (q31_t)0x6fd0e144, (q31_t)0xc1b3648d, + (q31_t)0x6fcdd241, (q31_t)0xc1ade781, (q31_t)0x6fcac2fa, (q31_t)0xc1a86a9c, (q31_t)0x6fc7b36d, (q31_t)0xc1a2edde, (q31_t)0x6fc4a39c, (q31_t)0xc19d7145, + (q31_t)0x6fc19385, (q31_t)0xc197f4d4, (q31_t)0x6fbe832a, (q31_t)0xc1927888, (q31_t)0x6fbb728a, (q31_t)0xc18cfc63, (q31_t)0x6fb861a4, (q31_t)0xc1878065, + (q31_t)0x6fb5507a, (q31_t)0xc182048d, (q31_t)0x6fb23f0b, (q31_t)0xc17c88dc, (q31_t)0x6faf2d57, (q31_t)0xc1770d52, (q31_t)0x6fac1b5f, (q31_t)0xc17191ee, + (q31_t)0x6fa90921, (q31_t)0xc16c16b0, (q31_t)0x6fa5f69e, (q31_t)0xc1669b99, (q31_t)0x6fa2e3d7, (q31_t)0xc16120a9, (q31_t)0x6f9fd0cb, (q31_t)0xc15ba5df, + (q31_t)0x6f9cbd79, (q31_t)0xc1562b3d, (q31_t)0x6f99a9e3, (q31_t)0xc150b0c0, (q31_t)0x6f969608, (q31_t)0xc14b366b, (q31_t)0x6f9381e9, (q31_t)0xc145bc3c, + (q31_t)0x6f906d84, (q31_t)0xc1404233, (q31_t)0x6f8d58db, (q31_t)0xc13ac852, (q31_t)0x6f8a43ed, (q31_t)0xc1354e97, (q31_t)0x6f872eba, (q31_t)0xc12fd503, + (q31_t)0x6f841942, (q31_t)0xc12a5b95, (q31_t)0x6f810386, (q31_t)0xc124e24f, (q31_t)0x6f7ded84, (q31_t)0xc11f692f, (q31_t)0x6f7ad73e, (q31_t)0xc119f036, + (q31_t)0x6f77c0b3, (q31_t)0xc1147764, (q31_t)0x6f74a9e4, (q31_t)0xc10efeb8, (q31_t)0x6f7192cf, (q31_t)0xc1098634, (q31_t)0x6f6e7b76, (q31_t)0xc1040dd6, + (q31_t)0x6f6b63d8, (q31_t)0xc0fe959f, (q31_t)0x6f684bf6, (q31_t)0xc0f91d8f, (q31_t)0x6f6533ce, (q31_t)0xc0f3a5a6, (q31_t)0x6f621b62, (q31_t)0xc0ee2de3, + (q31_t)0x6f5f02b2, (q31_t)0xc0e8b648, (q31_t)0x6f5be9bc, (q31_t)0xc0e33ed4, (q31_t)0x6f58d082, (q31_t)0xc0ddc786, (q31_t)0x6f55b703, (q31_t)0xc0d8505f, + (q31_t)0x6f529d40, (q31_t)0xc0d2d960, (q31_t)0x6f4f8338, (q31_t)0xc0cd6287, (q31_t)0x6f4c68eb, (q31_t)0xc0c7ebd6, (q31_t)0x6f494e5a, (q31_t)0xc0c2754b, + (q31_t)0x6f463383, (q31_t)0xc0bcfee7, (q31_t)0x6f431869, (q31_t)0xc0b788ab, (q31_t)0x6f3ffd09, (q31_t)0xc0b21295, (q31_t)0x6f3ce165, (q31_t)0xc0ac9ca6, + (q31_t)0x6f39c57d, (q31_t)0xc0a726df, (q31_t)0x6f36a94f, (q31_t)0xc0a1b13e, (q31_t)0x6f338cde, (q31_t)0xc09c3bc5, (q31_t)0x6f307027, (q31_t)0xc096c673, + (q31_t)0x6f2d532c, (q31_t)0xc0915148, (q31_t)0x6f2a35ed, (q31_t)0xc08bdc44, (q31_t)0x6f271868, (q31_t)0xc0866767, (q31_t)0x6f23faa0, (q31_t)0xc080f2b1, + (q31_t)0x6f20dc92, (q31_t)0xc07b7e23, (q31_t)0x6f1dbe41, (q31_t)0xc07609bb, (q31_t)0x6f1a9faa, (q31_t)0xc070957b, (q31_t)0x6f1780cf, (q31_t)0xc06b2162, + (q31_t)0x6f1461b0, (q31_t)0xc065ad70, (q31_t)0x6f11424c, (q31_t)0xc06039a6, (q31_t)0x6f0e22a3, (q31_t)0xc05ac603, (q31_t)0x6f0b02b6, (q31_t)0xc0555287, + (q31_t)0x6f07e285, (q31_t)0xc04fdf32, (q31_t)0x6f04c20f, (q31_t)0xc04a6c05, (q31_t)0x6f01a155, (q31_t)0xc044f8fe, (q31_t)0x6efe8056, (q31_t)0xc03f8620, + (q31_t)0x6efb5f12, (q31_t)0xc03a1368, (q31_t)0x6ef83d8a, (q31_t)0xc034a0d8, (q31_t)0x6ef51bbe, (q31_t)0xc02f2e6f, (q31_t)0x6ef1f9ad, (q31_t)0xc029bc2e, + (q31_t)0x6eeed758, (q31_t)0xc0244a14, (q31_t)0x6eebb4bf, (q31_t)0xc01ed821, (q31_t)0x6ee891e1, (q31_t)0xc0196656, (q31_t)0x6ee56ebe, (q31_t)0xc013f4b2, + (q31_t)0x6ee24b57, (q31_t)0xc00e8336, (q31_t)0x6edf27ac, (q31_t)0xc00911e1, (q31_t)0x6edc03bc, (q31_t)0xc003a0b3, (q31_t)0x6ed8df88, (q31_t)0xbffe2fad, + (q31_t)0x6ed5bb10, (q31_t)0xbff8bece, (q31_t)0x6ed29653, (q31_t)0xbff34e17, (q31_t)0x6ecf7152, (q31_t)0xbfeddd88, (q31_t)0x6ecc4c0d, (q31_t)0xbfe86d20, + (q31_t)0x6ec92683, (q31_t)0xbfe2fcdf, (q31_t)0x6ec600b5, (q31_t)0xbfdd8cc6, (q31_t)0x6ec2daa2, (q31_t)0xbfd81cd5, (q31_t)0x6ebfb44b, (q31_t)0xbfd2ad0b, + (q31_t)0x6ebc8db0, (q31_t)0xbfcd3d69, (q31_t)0x6eb966d1, (q31_t)0xbfc7cdee, (q31_t)0x6eb63fad, (q31_t)0xbfc25e9b, (q31_t)0x6eb31845, (q31_t)0xbfbcef70, + (q31_t)0x6eaff099, (q31_t)0xbfb7806c, (q31_t)0x6eacc8a8, (q31_t)0xbfb21190, (q31_t)0x6ea9a073, (q31_t)0xbfaca2dc, (q31_t)0x6ea677fa, (q31_t)0xbfa7344f, + (q31_t)0x6ea34f3d, (q31_t)0xbfa1c5ea, (q31_t)0x6ea0263b, (q31_t)0xbf9c57ac, (q31_t)0x6e9cfcf5, (q31_t)0xbf96e997, (q31_t)0x6e99d36b, (q31_t)0xbf917ba9, + (q31_t)0x6e96a99d, (q31_t)0xbf8c0de3, (q31_t)0x6e937f8a, (q31_t)0xbf86a044, (q31_t)0x6e905534, (q31_t)0xbf8132ce, (q31_t)0x6e8d2a99, (q31_t)0xbf7bc57f, + (q31_t)0x6e89ffb9, (q31_t)0xbf765858, (q31_t)0x6e86d496, (q31_t)0xbf70eb59, (q31_t)0x6e83a92f, (q31_t)0xbf6b7e81, (q31_t)0x6e807d83, (q31_t)0xbf6611d2, + (q31_t)0x6e7d5193, (q31_t)0xbf60a54a, (q31_t)0x6e7a255f, (q31_t)0xbf5b38ea, (q31_t)0x6e76f8e7, (q31_t)0xbf55ccb2, (q31_t)0x6e73cc2b, (q31_t)0xbf5060a2, + (q31_t)0x6e709f2a, (q31_t)0xbf4af4ba, (q31_t)0x6e6d71e6, (q31_t)0xbf4588fa, (q31_t)0x6e6a445d, (q31_t)0xbf401d61, (q31_t)0x6e671690, (q31_t)0xbf3ab1f1, + (q31_t)0x6e63e87f, (q31_t)0xbf3546a8, (q31_t)0x6e60ba2a, (q31_t)0xbf2fdb88, (q31_t)0x6e5d8b91, (q31_t)0xbf2a708f, (q31_t)0x6e5a5cb4, (q31_t)0xbf2505bf, + (q31_t)0x6e572d93, (q31_t)0xbf1f9b16, (q31_t)0x6e53fe2e, (q31_t)0xbf1a3096, (q31_t)0x6e50ce84, (q31_t)0xbf14c63d, (q31_t)0x6e4d9e97, (q31_t)0xbf0f5c0d, + (q31_t)0x6e4a6e66, (q31_t)0xbf09f205, (q31_t)0x6e473df0, (q31_t)0xbf048824, (q31_t)0x6e440d37, (q31_t)0xbeff1e6c, (q31_t)0x6e40dc39, (q31_t)0xbef9b4dc, + (q31_t)0x6e3daaf8, (q31_t)0xbef44b74, (q31_t)0x6e3a7972, (q31_t)0xbeeee234, (q31_t)0x6e3747a9, (q31_t)0xbee9791c, (q31_t)0x6e34159b, (q31_t)0xbee4102d, + (q31_t)0x6e30e34a, (q31_t)0xbedea765, (q31_t)0x6e2db0b4, (q31_t)0xbed93ec6, (q31_t)0x6e2a7ddb, (q31_t)0xbed3d64f, (q31_t)0x6e274abe, (q31_t)0xbece6e00, + (q31_t)0x6e24175c, (q31_t)0xbec905d9, (q31_t)0x6e20e3b7, (q31_t)0xbec39ddb, (q31_t)0x6e1dafce, (q31_t)0xbebe3605, (q31_t)0x6e1a7ba1, (q31_t)0xbeb8ce57, + (q31_t)0x6e174730, (q31_t)0xbeb366d1, (q31_t)0x6e14127b, (q31_t)0xbeadff74, (q31_t)0x6e10dd82, (q31_t)0xbea8983f, (q31_t)0x6e0da845, (q31_t)0xbea33132, + (q31_t)0x6e0a72c5, (q31_t)0xbe9dca4e, (q31_t)0x6e073d00, (q31_t)0xbe986391, (q31_t)0x6e0406f8, (q31_t)0xbe92fcfe, (q31_t)0x6e00d0ac, (q31_t)0xbe8d9692, + (q31_t)0x6dfd9a1c, (q31_t)0xbe88304f, (q31_t)0x6dfa6348, (q31_t)0xbe82ca35, (q31_t)0x6df72c30, (q31_t)0xbe7d6442, (q31_t)0x6df3f4d4, (q31_t)0xbe77fe78, + (q31_t)0x6df0bd35, (q31_t)0xbe7298d7, (q31_t)0x6ded8552, (q31_t)0xbe6d335e, (q31_t)0x6dea4d2b, (q31_t)0xbe67ce0d, (q31_t)0x6de714c0, (q31_t)0xbe6268e5, + (q31_t)0x6de3dc11, (q31_t)0xbe5d03e6, (q31_t)0x6de0a31f, (q31_t)0xbe579f0f, (q31_t)0x6ddd69e9, (q31_t)0xbe523a60, (q31_t)0x6dda306f, (q31_t)0xbe4cd5da, + (q31_t)0x6dd6f6b1, (q31_t)0xbe47717c, (q31_t)0x6dd3bcaf, (q31_t)0xbe420d47, (q31_t)0x6dd0826a, (q31_t)0xbe3ca93b, (q31_t)0x6dcd47e1, (q31_t)0xbe374557, + (q31_t)0x6dca0d14, (q31_t)0xbe31e19b, (q31_t)0x6dc6d204, (q31_t)0xbe2c7e09, (q31_t)0x6dc396b0, (q31_t)0xbe271a9f, (q31_t)0x6dc05b18, (q31_t)0xbe21b75d, + (q31_t)0x6dbd1f3c, (q31_t)0xbe1c5444, (q31_t)0x6db9e31d, (q31_t)0xbe16f154, (q31_t)0x6db6a6ba, (q31_t)0xbe118e8c, (q31_t)0x6db36a14, (q31_t)0xbe0c2bed, + (q31_t)0x6db02d29, (q31_t)0xbe06c977, (q31_t)0x6daceffb, (q31_t)0xbe01672a, (q31_t)0x6da9b28a, (q31_t)0xbdfc0505, (q31_t)0x6da674d5, (q31_t)0xbdf6a309, + (q31_t)0x6da336dc, (q31_t)0xbdf14135, (q31_t)0x6d9ff89f, (q31_t)0xbdebdf8b, (q31_t)0x6d9cba1f, (q31_t)0xbde67e09, (q31_t)0x6d997b5b, (q31_t)0xbde11cb0, + (q31_t)0x6d963c54, (q31_t)0xbddbbb7f, (q31_t)0x6d92fd09, (q31_t)0xbdd65a78, (q31_t)0x6d8fbd7a, (q31_t)0xbdd0f999, (q31_t)0x6d8c7da8, (q31_t)0xbdcb98e3, + (q31_t)0x6d893d93, (q31_t)0xbdc63856, (q31_t)0x6d85fd39, (q31_t)0xbdc0d7f2, (q31_t)0x6d82bc9d, (q31_t)0xbdbb77b7, (q31_t)0x6d7f7bbc, (q31_t)0xbdb617a4, + (q31_t)0x6d7c3a98, (q31_t)0xbdb0b7bb, (q31_t)0x6d78f931, (q31_t)0xbdab57fa, (q31_t)0x6d75b786, (q31_t)0xbda5f862, (q31_t)0x6d727597, (q31_t)0xbda098f3, + (q31_t)0x6d6f3365, (q31_t)0xbd9b39ad, (q31_t)0x6d6bf0f0, (q31_t)0xbd95da91, (q31_t)0x6d68ae37, (q31_t)0xbd907b9d, (q31_t)0x6d656b3a, (q31_t)0xbd8b1cd2, + (q31_t)0x6d6227fa, (q31_t)0xbd85be30, (q31_t)0x6d5ee477, (q31_t)0xbd805fb7, (q31_t)0x6d5ba0b0, (q31_t)0xbd7b0167, (q31_t)0x6d585ca6, (q31_t)0xbd75a340, + (q31_t)0x6d551858, (q31_t)0xbd704542, (q31_t)0x6d51d3c6, (q31_t)0xbd6ae76d, (q31_t)0x6d4e8ef2, (q31_t)0xbd6589c1, (q31_t)0x6d4b49da, (q31_t)0xbd602c3f, + (q31_t)0x6d48047e, (q31_t)0xbd5acee5, (q31_t)0x6d44bedf, (q31_t)0xbd5571b5, (q31_t)0x6d4178fd, (q31_t)0xbd5014ad, (q31_t)0x6d3e32d7, (q31_t)0xbd4ab7cf, + (q31_t)0x6d3aec6e, (q31_t)0xbd455b1a, (q31_t)0x6d37a5c1, (q31_t)0xbd3ffe8e, (q31_t)0x6d345ed1, (q31_t)0xbd3aa22c, (q31_t)0x6d31179e, (q31_t)0xbd3545f2, + (q31_t)0x6d2dd027, (q31_t)0xbd2fe9e2, (q31_t)0x6d2a886e, (q31_t)0xbd2a8dfb, (q31_t)0x6d274070, (q31_t)0xbd25323d, (q31_t)0x6d23f830, (q31_t)0xbd1fd6a8, + (q31_t)0x6d20afac, (q31_t)0xbd1a7b3d, (q31_t)0x6d1d66e4, (q31_t)0xbd151ffb, (q31_t)0x6d1a1dda, (q31_t)0xbd0fc4e2, (q31_t)0x6d16d48c, (q31_t)0xbd0a69f2, + (q31_t)0x6d138afb, (q31_t)0xbd050f2c, (q31_t)0x6d104126, (q31_t)0xbcffb48f, (q31_t)0x6d0cf70f, (q31_t)0xbcfa5a1b, (q31_t)0x6d09acb4, (q31_t)0xbcf4ffd1, + (q31_t)0x6d066215, (q31_t)0xbcefa5b0, (q31_t)0x6d031734, (q31_t)0xbcea4bb9, (q31_t)0x6cffcc0f, (q31_t)0xbce4f1eb, (q31_t)0x6cfc80a7, (q31_t)0xbcdf9846, + (q31_t)0x6cf934fc, (q31_t)0xbcda3ecb, (q31_t)0x6cf5e90d, (q31_t)0xbcd4e579, (q31_t)0x6cf29cdc, (q31_t)0xbccf8c50, (q31_t)0x6cef5067, (q31_t)0xbcca3351, + (q31_t)0x6cec03af, (q31_t)0xbcc4da7b, (q31_t)0x6ce8b6b4, (q31_t)0xbcbf81cf, (q31_t)0x6ce56975, (q31_t)0xbcba294d, (q31_t)0x6ce21bf4, (q31_t)0xbcb4d0f4, + (q31_t)0x6cdece2f, (q31_t)0xbcaf78c4, (q31_t)0x6cdb8027, (q31_t)0xbcaa20be, (q31_t)0x6cd831dc, (q31_t)0xbca4c8e1, (q31_t)0x6cd4e34e, (q31_t)0xbc9f712e, + (q31_t)0x6cd1947c, (q31_t)0xbc9a19a5, (q31_t)0x6cce4568, (q31_t)0xbc94c245, (q31_t)0x6ccaf610, (q31_t)0xbc8f6b0f, (q31_t)0x6cc7a676, (q31_t)0xbc8a1402, + (q31_t)0x6cc45698, (q31_t)0xbc84bd1f, (q31_t)0x6cc10677, (q31_t)0xbc7f6665, (q31_t)0x6cbdb613, (q31_t)0xbc7a0fd6, (q31_t)0x6cba656c, (q31_t)0xbc74b96f, + (q31_t)0x6cb71482, (q31_t)0xbc6f6333, (q31_t)0x6cb3c355, (q31_t)0xbc6a0d20, (q31_t)0x6cb071e4, (q31_t)0xbc64b737, (q31_t)0x6cad2031, (q31_t)0xbc5f6177, + (q31_t)0x6ca9ce3b, (q31_t)0xbc5a0be2, (q31_t)0x6ca67c01, (q31_t)0xbc54b676, (q31_t)0x6ca32985, (q31_t)0xbc4f6134, (q31_t)0x6c9fd6c6, (q31_t)0xbc4a0c1b, + (q31_t)0x6c9c83c3, (q31_t)0xbc44b72c, (q31_t)0x6c99307e, (q31_t)0xbc3f6267, (q31_t)0x6c95dcf6, (q31_t)0xbc3a0dcc, (q31_t)0x6c92892a, (q31_t)0xbc34b95b, + (q31_t)0x6c8f351c, (q31_t)0xbc2f6513, (q31_t)0x6c8be0cb, (q31_t)0xbc2a10f6, (q31_t)0x6c888c36, (q31_t)0xbc24bd02, (q31_t)0x6c85375f, (q31_t)0xbc1f6938, + (q31_t)0x6c81e245, (q31_t)0xbc1a1598, (q31_t)0x6c7e8ce8, (q31_t)0xbc14c221, (q31_t)0x6c7b3748, (q31_t)0xbc0f6ed5, (q31_t)0x6c77e165, (q31_t)0xbc0a1bb3, + (q31_t)0x6c748b3f, (q31_t)0xbc04c8ba, (q31_t)0x6c7134d7, (q31_t)0xbbff75ec, (q31_t)0x6c6dde2b, (q31_t)0xbbfa2347, (q31_t)0x6c6a873d, (q31_t)0xbbf4d0cc, + (q31_t)0x6c67300b, (q31_t)0xbbef7e7c, (q31_t)0x6c63d897, (q31_t)0xbbea2c55, (q31_t)0x6c6080e0, (q31_t)0xbbe4da58, (q31_t)0x6c5d28e6, (q31_t)0xbbdf8885, + (q31_t)0x6c59d0a9, (q31_t)0xbbda36dd, (q31_t)0x6c56782a, (q31_t)0xbbd4e55e, (q31_t)0x6c531f67, (q31_t)0xbbcf940a, (q31_t)0x6c4fc662, (q31_t)0xbbca42df, + (q31_t)0x6c4c6d1a, (q31_t)0xbbc4f1df, (q31_t)0x6c49138f, (q31_t)0xbbbfa108, (q31_t)0x6c45b9c1, (q31_t)0xbbba505c, (q31_t)0x6c425fb1, (q31_t)0xbbb4ffda, + (q31_t)0x6c3f055d, (q31_t)0xbbafaf82, (q31_t)0x6c3baac7, (q31_t)0xbbaa5f54, (q31_t)0x6c384fef, (q31_t)0xbba50f50, (q31_t)0x6c34f4d3, (q31_t)0xbb9fbf77, + (q31_t)0x6c319975, (q31_t)0xbb9a6fc7, (q31_t)0x6c2e3dd4, (q31_t)0xbb952042, (q31_t)0x6c2ae1f0, (q31_t)0xbb8fd0e7, (q31_t)0x6c2785ca, (q31_t)0xbb8a81b6, + (q31_t)0x6c242960, (q31_t)0xbb8532b0, (q31_t)0x6c20ccb4, (q31_t)0xbb7fe3d3, (q31_t)0x6c1d6fc6, (q31_t)0xbb7a9521, (q31_t)0x6c1a1295, (q31_t)0xbb754699, + (q31_t)0x6c16b521, (q31_t)0xbb6ff83c, (q31_t)0x6c13576a, (q31_t)0xbb6aaa09, (q31_t)0x6c0ff971, (q31_t)0xbb655c00, (q31_t)0x6c0c9b35, (q31_t)0xbb600e21, + (q31_t)0x6c093cb6, (q31_t)0xbb5ac06d, (q31_t)0x6c05ddf5, (q31_t)0xbb5572e3, (q31_t)0x6c027ef1, (q31_t)0xbb502583, (q31_t)0x6bff1faa, (q31_t)0xbb4ad84e, + (q31_t)0x6bfbc021, (q31_t)0xbb458b43, (q31_t)0x6bf86055, (q31_t)0xbb403e63, (q31_t)0x6bf50047, (q31_t)0xbb3af1ad, (q31_t)0x6bf19ff6, (q31_t)0xbb35a521, + (q31_t)0x6bee3f62, (q31_t)0xbb3058c0, (q31_t)0x6beade8c, (q31_t)0xbb2b0c8a, (q31_t)0x6be77d74, (q31_t)0xbb25c07d, (q31_t)0x6be41c18, (q31_t)0xbb20749c, + (q31_t)0x6be0ba7b, (q31_t)0xbb1b28e4, (q31_t)0x6bdd589a, (q31_t)0xbb15dd57, (q31_t)0x6bd9f677, (q31_t)0xbb1091f5, (q31_t)0x6bd69412, (q31_t)0xbb0b46bd, + (q31_t)0x6bd3316a, (q31_t)0xbb05fbb0, (q31_t)0x6bcfce80, (q31_t)0xbb00b0ce, (q31_t)0x6bcc6b53, (q31_t)0xbafb6615, (q31_t)0x6bc907e3, (q31_t)0xbaf61b88, + (q31_t)0x6bc5a431, (q31_t)0xbaf0d125, (q31_t)0x6bc2403d, (q31_t)0xbaeb86ed, (q31_t)0x6bbedc06, (q31_t)0xbae63cdf, (q31_t)0x6bbb778d, (q31_t)0xbae0f2fc, + (q31_t)0x6bb812d1, (q31_t)0xbadba943, (q31_t)0x6bb4add3, (q31_t)0xbad65fb5, (q31_t)0x6bb14892, (q31_t)0xbad11652, (q31_t)0x6bade30f, (q31_t)0xbacbcd1a, + (q31_t)0x6baa7d49, (q31_t)0xbac6840c, (q31_t)0x6ba71741, (q31_t)0xbac13b29, (q31_t)0x6ba3b0f7, (q31_t)0xbabbf270, (q31_t)0x6ba04a6a, (q31_t)0xbab6a9e3, + (q31_t)0x6b9ce39b, (q31_t)0xbab16180, (q31_t)0x6b997c8a, (q31_t)0xbaac1948, (q31_t)0x6b961536, (q31_t)0xbaa6d13a, (q31_t)0x6b92ada0, (q31_t)0xbaa18958, + (q31_t)0x6b8f45c7, (q31_t)0xba9c41a0, (q31_t)0x6b8bddac, (q31_t)0xba96fa13, (q31_t)0x6b88754f, (q31_t)0xba91b2b1, (q31_t)0x6b850caf, (q31_t)0xba8c6b79, + (q31_t)0x6b81a3cd, (q31_t)0xba87246d, (q31_t)0x6b7e3aa9, (q31_t)0xba81dd8b, (q31_t)0x6b7ad142, (q31_t)0xba7c96d4, (q31_t)0x6b776799, (q31_t)0xba775048, + (q31_t)0x6b73fdae, (q31_t)0xba7209e7, (q31_t)0x6b709381, (q31_t)0xba6cc3b1, (q31_t)0x6b6d2911, (q31_t)0xba677da6, (q31_t)0x6b69be5f, (q31_t)0xba6237c5, + (q31_t)0x6b66536b, (q31_t)0xba5cf210, (q31_t)0x6b62e834, (q31_t)0xba57ac86, (q31_t)0x6b5f7cbc, (q31_t)0xba526726, (q31_t)0x6b5c1101, (q31_t)0xba4d21f2, + (q31_t)0x6b58a503, (q31_t)0xba47dce8, (q31_t)0x6b5538c4, (q31_t)0xba42980a, (q31_t)0x6b51cc42, (q31_t)0xba3d5356, (q31_t)0x6b4e5f7f, (q31_t)0xba380ece, + (q31_t)0x6b4af279, (q31_t)0xba32ca71, (q31_t)0x6b478530, (q31_t)0xba2d863e, (q31_t)0x6b4417a6, (q31_t)0xba284237, (q31_t)0x6b40a9d9, (q31_t)0xba22fe5b, + (q31_t)0x6b3d3bcb, (q31_t)0xba1dbaaa, (q31_t)0x6b39cd7a, (q31_t)0xba187724, (q31_t)0x6b365ee7, (q31_t)0xba1333c9, (q31_t)0x6b32f012, (q31_t)0xba0df099, + (q31_t)0x6b2f80fb, (q31_t)0xba08ad95, (q31_t)0x6b2c11a1, (q31_t)0xba036abb, (q31_t)0x6b28a206, (q31_t)0xb9fe280d, (q31_t)0x6b253228, (q31_t)0xb9f8e58a, + (q31_t)0x6b21c208, (q31_t)0xb9f3a332, (q31_t)0x6b1e51a7, (q31_t)0xb9ee6106, (q31_t)0x6b1ae103, (q31_t)0xb9e91f04, (q31_t)0x6b17701d, (q31_t)0xb9e3dd2e, + (q31_t)0x6b13fef5, (q31_t)0xb9de9b83, (q31_t)0x6b108d8b, (q31_t)0xb9d95a03, (q31_t)0x6b0d1bdf, (q31_t)0xb9d418af, (q31_t)0x6b09a9f1, (q31_t)0xb9ced786, + (q31_t)0x6b0637c1, (q31_t)0xb9c99688, (q31_t)0x6b02c54f, (q31_t)0xb9c455b6, (q31_t)0x6aff529a, (q31_t)0xb9bf150e, (q31_t)0x6afbdfa4, (q31_t)0xb9b9d493, + (q31_t)0x6af86c6c, (q31_t)0xb9b49442, (q31_t)0x6af4f8f2, (q31_t)0xb9af541d, (q31_t)0x6af18536, (q31_t)0xb9aa1423, (q31_t)0x6aee1138, (q31_t)0xb9a4d455, + (q31_t)0x6aea9cf8, (q31_t)0xb99f94b2, (q31_t)0x6ae72876, (q31_t)0xb99a553a, (q31_t)0x6ae3b3b2, (q31_t)0xb99515ee, (q31_t)0x6ae03eac, (q31_t)0xb98fd6cd, + (q31_t)0x6adcc964, (q31_t)0xb98a97d8, (q31_t)0x6ad953db, (q31_t)0xb985590e, (q31_t)0x6ad5de0f, (q31_t)0xb9801a70, (q31_t)0x6ad26802, (q31_t)0xb97adbfd, + (q31_t)0x6acef1b2, (q31_t)0xb9759db6, (q31_t)0x6acb7b21, (q31_t)0xb9705f9a, (q31_t)0x6ac8044e, (q31_t)0xb96b21aa, (q31_t)0x6ac48d39, (q31_t)0xb965e3e5, + (q31_t)0x6ac115e2, (q31_t)0xb960a64c, (q31_t)0x6abd9e49, (q31_t)0xb95b68de, (q31_t)0x6aba266e, (q31_t)0xb9562b9c, (q31_t)0x6ab6ae52, (q31_t)0xb950ee86, + (q31_t)0x6ab335f4, (q31_t)0xb94bb19b, (q31_t)0x6aafbd54, (q31_t)0xb94674dc, (q31_t)0x6aac4472, (q31_t)0xb9413848, (q31_t)0x6aa8cb4e, (q31_t)0xb93bfbe0, + (q31_t)0x6aa551e9, (q31_t)0xb936bfa4, (q31_t)0x6aa1d841, (q31_t)0xb9318393, (q31_t)0x6a9e5e58, (q31_t)0xb92c47ae, (q31_t)0x6a9ae42e, (q31_t)0xb9270bf5, + (q31_t)0x6a9769c1, (q31_t)0xb921d067, (q31_t)0x6a93ef13, (q31_t)0xb91c9505, (q31_t)0x6a907423, (q31_t)0xb91759cf, (q31_t)0x6a8cf8f1, (q31_t)0xb9121ec5, + (q31_t)0x6a897d7d, (q31_t)0xb90ce3e6, (q31_t)0x6a8601c8, (q31_t)0xb907a933, (q31_t)0x6a8285d1, (q31_t)0xb9026eac, (q31_t)0x6a7f0999, (q31_t)0xb8fd3451, + (q31_t)0x6a7b8d1e, (q31_t)0xb8f7fa21, (q31_t)0x6a781062, (q31_t)0xb8f2c01d, (q31_t)0x6a749365, (q31_t)0xb8ed8646, (q31_t)0x6a711625, (q31_t)0xb8e84c99, + (q31_t)0x6a6d98a4, (q31_t)0xb8e31319, (q31_t)0x6a6a1ae2, (q31_t)0xb8ddd9c5, (q31_t)0x6a669cdd, (q31_t)0xb8d8a09d, (q31_t)0x6a631e97, (q31_t)0xb8d367a0, + (q31_t)0x6a5fa010, (q31_t)0xb8ce2ecf, (q31_t)0x6a5c2147, (q31_t)0xb8c8f62b, (q31_t)0x6a58a23c, (q31_t)0xb8c3bdb2, (q31_t)0x6a5522ef, (q31_t)0xb8be8565, + (q31_t)0x6a51a361, (q31_t)0xb8b94d44, (q31_t)0x6a4e2392, (q31_t)0xb8b4154f, (q31_t)0x6a4aa381, (q31_t)0xb8aedd86, (q31_t)0x6a47232e, (q31_t)0xb8a9a5e9, + (q31_t)0x6a43a29a, (q31_t)0xb8a46e78, (q31_t)0x6a4021c4, (q31_t)0xb89f3733, (q31_t)0x6a3ca0ad, (q31_t)0xb89a001a, (q31_t)0x6a391f54, (q31_t)0xb894c92d, + (q31_t)0x6a359db9, (q31_t)0xb88f926d, (q31_t)0x6a321bdd, (q31_t)0xb88a5bd8, (q31_t)0x6a2e99c0, (q31_t)0xb885256f, (q31_t)0x6a2b1761, (q31_t)0xb87fef33, + (q31_t)0x6a2794c1, (q31_t)0xb87ab922, (q31_t)0x6a2411df, (q31_t)0xb875833e, (q31_t)0x6a208ebb, (q31_t)0xb8704d85, (q31_t)0x6a1d0b57, (q31_t)0xb86b17f9, + (q31_t)0x6a1987b0, (q31_t)0xb865e299, (q31_t)0x6a1603c8, (q31_t)0xb860ad66, (q31_t)0x6a127f9f, (q31_t)0xb85b785e, (q31_t)0x6a0efb35, (q31_t)0xb8564383, + (q31_t)0x6a0b7689, (q31_t)0xb8510ed4, (q31_t)0x6a07f19b, (q31_t)0xb84bda51, (q31_t)0x6a046c6c, (q31_t)0xb846a5fa, (q31_t)0x6a00e6fc, (q31_t)0xb84171cf, + (q31_t)0x69fd614a, (q31_t)0xb83c3dd1, (q31_t)0x69f9db57, (q31_t)0xb83709ff, (q31_t)0x69f65523, (q31_t)0xb831d659, (q31_t)0x69f2cead, (q31_t)0xb82ca2e0, + (q31_t)0x69ef47f6, (q31_t)0xb8276f93, (q31_t)0x69ebc0fe, (q31_t)0xb8223c72, (q31_t)0x69e839c4, (q31_t)0xb81d097e, (q31_t)0x69e4b249, (q31_t)0xb817d6b6, + (q31_t)0x69e12a8c, (q31_t)0xb812a41a, (q31_t)0x69dda28f, (q31_t)0xb80d71aa, (q31_t)0x69da1a50, (q31_t)0xb8083f67, (q31_t)0x69d691cf, (q31_t)0xb8030d51, + (q31_t)0x69d3090e, (q31_t)0xb7fddb67, (q31_t)0x69cf800b, (q31_t)0xb7f8a9a9, (q31_t)0x69cbf6c7, (q31_t)0xb7f37818, (q31_t)0x69c86d41, (q31_t)0xb7ee46b3, + (q31_t)0x69c4e37a, (q31_t)0xb7e9157a, (q31_t)0x69c15973, (q31_t)0xb7e3e46e, (q31_t)0x69bdcf29, (q31_t)0xb7deb38f, (q31_t)0x69ba449f, (q31_t)0xb7d982dc, + (q31_t)0x69b6b9d3, (q31_t)0xb7d45255, (q31_t)0x69b32ec7, (q31_t)0xb7cf21fb, (q31_t)0x69afa378, (q31_t)0xb7c9f1ce, (q31_t)0x69ac17e9, (q31_t)0xb7c4c1cd, + (q31_t)0x69a88c19, (q31_t)0xb7bf91f8, (q31_t)0x69a50007, (q31_t)0xb7ba6251, (q31_t)0x69a173b5, (q31_t)0xb7b532d6, (q31_t)0x699de721, (q31_t)0xb7b00387, + (q31_t)0x699a5a4c, (q31_t)0xb7aad465, (q31_t)0x6996cd35, (q31_t)0xb7a5a570, (q31_t)0x69933fde, (q31_t)0xb7a076a7, (q31_t)0x698fb246, (q31_t)0xb79b480b, + (q31_t)0x698c246c, (q31_t)0xb796199b, (q31_t)0x69889651, (q31_t)0xb790eb58, (q31_t)0x698507f6, (q31_t)0xb78bbd42, (q31_t)0x69817959, (q31_t)0xb7868f59, + (q31_t)0x697dea7b, (q31_t)0xb781619c, (q31_t)0x697a5b5c, (q31_t)0xb77c340c, (q31_t)0x6976cbfc, (q31_t)0xb77706a9, (q31_t)0x69733c5b, (q31_t)0xb771d972, + (q31_t)0x696fac78, (q31_t)0xb76cac69, (q31_t)0x696c1c55, (q31_t)0xb7677f8c, (q31_t)0x69688bf1, (q31_t)0xb76252db, (q31_t)0x6964fb4c, (q31_t)0xb75d2658, + (q31_t)0x69616a65, (q31_t)0xb757fa01, (q31_t)0x695dd93e, (q31_t)0xb752cdd8, (q31_t)0x695a47d6, (q31_t)0xb74da1db, (q31_t)0x6956b62d, (q31_t)0xb748760b, + (q31_t)0x69532442, (q31_t)0xb7434a67, (q31_t)0x694f9217, (q31_t)0xb73e1ef1, (q31_t)0x694bffab, (q31_t)0xb738f3a7, (q31_t)0x69486cfe, (q31_t)0xb733c88b, + (q31_t)0x6944da10, (q31_t)0xb72e9d9b, (q31_t)0x694146e1, (q31_t)0xb72972d8, (q31_t)0x693db371, (q31_t)0xb7244842, (q31_t)0x693a1fc0, (q31_t)0xb71f1dd9, + (q31_t)0x69368bce, (q31_t)0xb719f39e, (q31_t)0x6932f79b, (q31_t)0xb714c98e, (q31_t)0x692f6328, (q31_t)0xb70f9fac, (q31_t)0x692bce73, (q31_t)0xb70a75f7, + (q31_t)0x6928397e, (q31_t)0xb7054c6f, (q31_t)0x6924a448, (q31_t)0xb7002314, (q31_t)0x69210ed1, (q31_t)0xb6faf9e6, (q31_t)0x691d7919, (q31_t)0xb6f5d0e5, + (q31_t)0x6919e320, (q31_t)0xb6f0a812, (q31_t)0x69164ce7, (q31_t)0xb6eb7f6b, (q31_t)0x6912b66c, (q31_t)0xb6e656f1, (q31_t)0x690f1fb1, (q31_t)0xb6e12ea4, + (q31_t)0x690b88b5, (q31_t)0xb6dc0685, (q31_t)0x6907f178, (q31_t)0xb6d6de92, (q31_t)0x690459fb, (q31_t)0xb6d1b6cd, (q31_t)0x6900c23c, (q31_t)0xb6cc8f35, + (q31_t)0x68fd2a3d, (q31_t)0xb6c767ca, (q31_t)0x68f991fd, (q31_t)0xb6c2408c, (q31_t)0x68f5f97d, (q31_t)0xb6bd197c, (q31_t)0x68f260bb, (q31_t)0xb6b7f298, + (q31_t)0x68eec7b9, (q31_t)0xb6b2cbe2, (q31_t)0x68eb2e76, (q31_t)0xb6ada559, (q31_t)0x68e794f3, (q31_t)0xb6a87efd, (q31_t)0x68e3fb2e, (q31_t)0xb6a358ce, + (q31_t)0x68e06129, (q31_t)0xb69e32cd, (q31_t)0x68dcc6e4, (q31_t)0xb6990cf9, (q31_t)0x68d92c5d, (q31_t)0xb693e752, (q31_t)0x68d59196, (q31_t)0xb68ec1d9, + (q31_t)0x68d1f68f, (q31_t)0xb6899c8d, (q31_t)0x68ce5b46, (q31_t)0xb684776e, (q31_t)0x68cabfbd, (q31_t)0xb67f527c, (q31_t)0x68c723f3, (q31_t)0xb67a2db8, + (q31_t)0x68c387e9, (q31_t)0xb6750921, (q31_t)0x68bfeb9e, (q31_t)0xb66fe4b8, (q31_t)0x68bc4f13, (q31_t)0xb66ac07c, (q31_t)0x68b8b247, (q31_t)0xb6659c6d, + (q31_t)0x68b5153a, (q31_t)0xb660788c, (q31_t)0x68b177ed, (q31_t)0xb65b54d8, (q31_t)0x68adda5f, (q31_t)0xb6563151, (q31_t)0x68aa3c90, (q31_t)0xb6510df8, + (q31_t)0x68a69e81, (q31_t)0xb64beacd, (q31_t)0x68a30031, (q31_t)0xb646c7ce, (q31_t)0x689f61a1, (q31_t)0xb641a4fe, (q31_t)0x689bc2d1, (q31_t)0xb63c825b, + (q31_t)0x689823bf, (q31_t)0xb6375fe5, (q31_t)0x6894846e, (q31_t)0xb6323d9d, (q31_t)0x6890e4dc, (q31_t)0xb62d1b82, (q31_t)0x688d4509, (q31_t)0xb627f995, + (q31_t)0x6889a4f6, (q31_t)0xb622d7d6, (q31_t)0x688604a2, (q31_t)0xb61db644, (q31_t)0x6882640e, (q31_t)0xb61894df, (q31_t)0x687ec339, (q31_t)0xb61373a9, + (q31_t)0x687b2224, (q31_t)0xb60e529f, (q31_t)0x687780ce, (q31_t)0xb60931c4, (q31_t)0x6873df38, (q31_t)0xb6041116, (q31_t)0x68703d62, (q31_t)0xb5fef095, + (q31_t)0x686c9b4b, (q31_t)0xb5f9d043, (q31_t)0x6868f8f4, (q31_t)0xb5f4b01e, (q31_t)0x6865565c, (q31_t)0xb5ef9026, (q31_t)0x6861b384, (q31_t)0xb5ea705d, + (q31_t)0x685e106c, (q31_t)0xb5e550c1, (q31_t)0x685a6d13, (q31_t)0xb5e03153, (q31_t)0x6856c979, (q31_t)0xb5db1212, (q31_t)0x685325a0, (q31_t)0xb5d5f2ff, + (q31_t)0x684f8186, (q31_t)0xb5d0d41a, (q31_t)0x684bdd2c, (q31_t)0xb5cbb563, (q31_t)0x68483891, (q31_t)0xb5c696da, (q31_t)0x684493b6, (q31_t)0xb5c1787e, + (q31_t)0x6840ee9b, (q31_t)0xb5bc5a50, (q31_t)0x683d493f, (q31_t)0xb5b73c50, (q31_t)0x6839a3a4, (q31_t)0xb5b21e7e, (q31_t)0x6835fdc7, (q31_t)0xb5ad00d9, + (q31_t)0x683257ab, (q31_t)0xb5a7e362, (q31_t)0x682eb14e, (q31_t)0xb5a2c61a, (q31_t)0x682b0ab1, (q31_t)0xb59da8ff, (q31_t)0x682763d4, (q31_t)0xb5988c12, + (q31_t)0x6823bcb7, (q31_t)0xb5936f53, (q31_t)0x68201559, (q31_t)0xb58e52c2, (q31_t)0x681c6dbb, (q31_t)0xb589365e, (q31_t)0x6818c5dd, (q31_t)0xb5841a29, + (q31_t)0x68151dbe, (q31_t)0xb57efe22, (q31_t)0x68117560, (q31_t)0xb579e248, (q31_t)0x680dccc1, (q31_t)0xb574c69d, (q31_t)0x680a23e2, (q31_t)0xb56fab1f, + (q31_t)0x68067ac3, (q31_t)0xb56a8fd0, (q31_t)0x6802d164, (q31_t)0xb56574ae, (q31_t)0x67ff27c4, (q31_t)0xb56059bb, (q31_t)0x67fb7de5, (q31_t)0xb55b3ef5, + (q31_t)0x67f7d3c5, (q31_t)0xb556245e, (q31_t)0x67f42965, (q31_t)0xb55109f5, (q31_t)0x67f07ec5, (q31_t)0xb54befba, (q31_t)0x67ecd3e5, (q31_t)0xb546d5ac, + (q31_t)0x67e928c5, (q31_t)0xb541bbcd, (q31_t)0x67e57d64, (q31_t)0xb53ca21c, (q31_t)0x67e1d1c4, (q31_t)0xb5378899, (q31_t)0x67de25e3, (q31_t)0xb5326f45, + (q31_t)0x67da79c3, (q31_t)0xb52d561e, (q31_t)0x67d6cd62, (q31_t)0xb5283d26, (q31_t)0x67d320c1, (q31_t)0xb523245b, (q31_t)0x67cf73e1, (q31_t)0xb51e0bbf, + (q31_t)0x67cbc6c0, (q31_t)0xb518f351, (q31_t)0x67c8195f, (q31_t)0xb513db12, (q31_t)0x67c46bbe, (q31_t)0xb50ec300, (q31_t)0x67c0bddd, (q31_t)0xb509ab1d, + (q31_t)0x67bd0fbd, (q31_t)0xb5049368, (q31_t)0x67b9615c, (q31_t)0xb4ff7be1, (q31_t)0x67b5b2bb, (q31_t)0xb4fa6489, (q31_t)0x67b203da, (q31_t)0xb4f54d5f, + (q31_t)0x67ae54ba, (q31_t)0xb4f03663, (q31_t)0x67aaa559, (q31_t)0xb4eb1f95, (q31_t)0x67a6f5b8, (q31_t)0xb4e608f6, (q31_t)0x67a345d8, (q31_t)0xb4e0f285, + (q31_t)0x679f95b7, (q31_t)0xb4dbdc42, (q31_t)0x679be557, (q31_t)0xb4d6c62e, (q31_t)0x679834b6, (q31_t)0xb4d1b048, (q31_t)0x679483d6, (q31_t)0xb4cc9a90, + (q31_t)0x6790d2b6, (q31_t)0xb4c78507, (q31_t)0x678d2156, (q31_t)0xb4c26fad, (q31_t)0x67896fb6, (q31_t)0xb4bd5a80, (q31_t)0x6785bdd6, (q31_t)0xb4b84582, + (q31_t)0x67820bb7, (q31_t)0xb4b330b3, (q31_t)0x677e5957, (q31_t)0xb4ae1c12, (q31_t)0x677aa6b8, (q31_t)0xb4a9079f, (q31_t)0x6776f3d9, (q31_t)0xb4a3f35b, + (q31_t)0x677340ba, (q31_t)0xb49edf45, (q31_t)0x676f8d5b, (q31_t)0xb499cb5e, (q31_t)0x676bd9bd, (q31_t)0xb494b7a6, (q31_t)0x676825de, (q31_t)0xb48fa41c, + (q31_t)0x676471c0, (q31_t)0xb48a90c0, (q31_t)0x6760bd62, (q31_t)0xb4857d93, (q31_t)0x675d08c4, (q31_t)0xb4806a95, (q31_t)0x675953e7, (q31_t)0xb47b57c5, + (q31_t)0x67559eca, (q31_t)0xb4764523, (q31_t)0x6751e96d, (q31_t)0xb47132b1, (q31_t)0x674e33d0, (q31_t)0xb46c206d, (q31_t)0x674a7df4, (q31_t)0xb4670e57, + (q31_t)0x6746c7d8, (q31_t)0xb461fc70, (q31_t)0x6743117c, (q31_t)0xb45ceab8, (q31_t)0x673f5ae0, (q31_t)0xb457d92f, (q31_t)0x673ba405, (q31_t)0xb452c7d4, + (q31_t)0x6737ecea, (q31_t)0xb44db6a8, (q31_t)0x67343590, (q31_t)0xb448a5aa, (q31_t)0x67307df5, (q31_t)0xb44394db, (q31_t)0x672cc61c, (q31_t)0xb43e843b, + (q31_t)0x67290e02, (q31_t)0xb43973ca, (q31_t)0x672555a9, (q31_t)0xb4346387, (q31_t)0x67219d10, (q31_t)0xb42f5373, (q31_t)0x671de438, (q31_t)0xb42a438e, + (q31_t)0x671a2b20, (q31_t)0xb42533d8, (q31_t)0x671671c8, (q31_t)0xb4202451, (q31_t)0x6712b831, (q31_t)0xb41b14f8, (q31_t)0x670efe5a, (q31_t)0xb41605ce, + (q31_t)0x670b4444, (q31_t)0xb410f6d3, (q31_t)0x670789ee, (q31_t)0xb40be807, (q31_t)0x6703cf58, (q31_t)0xb406d969, (q31_t)0x67001483, (q31_t)0xb401cafb, + (q31_t)0x66fc596f, (q31_t)0xb3fcbcbb, (q31_t)0x66f89e1b, (q31_t)0xb3f7aeaa, (q31_t)0x66f4e287, (q31_t)0xb3f2a0c9, (q31_t)0x66f126b4, (q31_t)0xb3ed9316, + (q31_t)0x66ed6aa1, (q31_t)0xb3e88592, (q31_t)0x66e9ae4f, (q31_t)0xb3e3783d, (q31_t)0x66e5f1be, (q31_t)0xb3de6b17, (q31_t)0x66e234ed, (q31_t)0xb3d95e1f, + (q31_t)0x66de77dc, (q31_t)0xb3d45157, (q31_t)0x66daba8c, (q31_t)0xb3cf44be, (q31_t)0x66d6fcfd, (q31_t)0xb3ca3854, (q31_t)0x66d33f2e, (q31_t)0xb3c52c19, + (q31_t)0x66cf8120, (q31_t)0xb3c0200c, (q31_t)0x66cbc2d2, (q31_t)0xb3bb142f, (q31_t)0x66c80445, (q31_t)0xb3b60881, (q31_t)0x66c44579, (q31_t)0xb3b0fd02, + (q31_t)0x66c0866d, (q31_t)0xb3abf1b2, (q31_t)0x66bcc721, (q31_t)0xb3a6e691, (q31_t)0x66b90797, (q31_t)0xb3a1dba0, (q31_t)0x66b547cd, (q31_t)0xb39cd0dd, + (q31_t)0x66b187c3, (q31_t)0xb397c649, (q31_t)0x66adc77b, (q31_t)0xb392bbe5, (q31_t)0x66aa06f3, (q31_t)0xb38db1b0, (q31_t)0x66a6462b, (q31_t)0xb388a7aa, + (q31_t)0x66a28524, (q31_t)0xb3839dd3, (q31_t)0x669ec3de, (q31_t)0xb37e942b, (q31_t)0x669b0259, (q31_t)0xb3798ab2, (q31_t)0x66974095, (q31_t)0xb3748169, + (q31_t)0x66937e91, (q31_t)0xb36f784f, (q31_t)0x668fbc4e, (q31_t)0xb36a6f64, (q31_t)0x668bf9cb, (q31_t)0xb36566a8, (q31_t)0x66883709, (q31_t)0xb3605e1c, + (q31_t)0x66847408, (q31_t)0xb35b55bf, (q31_t)0x6680b0c8, (q31_t)0xb3564d91, (q31_t)0x667ced49, (q31_t)0xb3514592, (q31_t)0x6679298a, (q31_t)0xb34c3dc3, + (q31_t)0x6675658c, (q31_t)0xb3473623, (q31_t)0x6671a14f, (q31_t)0xb3422eb2, (q31_t)0x666ddcd3, (q31_t)0xb33d2771, (q31_t)0x666a1818, (q31_t)0xb338205f, + (q31_t)0x6666531d, (q31_t)0xb333197c, (q31_t)0x66628de4, (q31_t)0xb32e12c9, (q31_t)0x665ec86b, (q31_t)0xb3290c45, (q31_t)0x665b02b3, (q31_t)0xb32405f1, + (q31_t)0x66573cbb, (q31_t)0xb31effcc, (q31_t)0x66537685, (q31_t)0xb319f9d6, (q31_t)0x664fb010, (q31_t)0xb314f410, (q31_t)0x664be95b, (q31_t)0xb30fee79, + (q31_t)0x66482267, (q31_t)0xb30ae912, (q31_t)0x66445b35, (q31_t)0xb305e3da, (q31_t)0x664093c3, (q31_t)0xb300ded2, (q31_t)0x663ccc12, (q31_t)0xb2fbd9f9, + (q31_t)0x66390422, (q31_t)0xb2f6d550, (q31_t)0x66353bf3, (q31_t)0xb2f1d0d6, (q31_t)0x66317385, (q31_t)0xb2eccc8c, (q31_t)0x662daad8, (q31_t)0xb2e7c871, + (q31_t)0x6629e1ec, (q31_t)0xb2e2c486, (q31_t)0x662618c1, (q31_t)0xb2ddc0ca, (q31_t)0x66224f56, (q31_t)0xb2d8bd3e, (q31_t)0x661e85ad, (q31_t)0xb2d3b9e2, + (q31_t)0x661abbc5, (q31_t)0xb2ceb6b5, (q31_t)0x6616f19e, (q31_t)0xb2c9b3b8, (q31_t)0x66132738, (q31_t)0xb2c4b0ea, (q31_t)0x660f5c93, (q31_t)0xb2bfae4c, + (q31_t)0x660b91af, (q31_t)0xb2baabde, (q31_t)0x6607c68c, (q31_t)0xb2b5a99f, (q31_t)0x6603fb2a, (q31_t)0xb2b0a790, (q31_t)0x66002f89, (q31_t)0xb2aba5b1, + (q31_t)0x65fc63a9, (q31_t)0xb2a6a402, (q31_t)0x65f8978b, (q31_t)0xb2a1a282, (q31_t)0x65f4cb2d, (q31_t)0xb29ca132, (q31_t)0x65f0fe91, (q31_t)0xb297a011, + (q31_t)0x65ed31b5, (q31_t)0xb2929f21, (q31_t)0x65e9649b, (q31_t)0xb28d9e60, (q31_t)0x65e59742, (q31_t)0xb2889dcf, (q31_t)0x65e1c9aa, (q31_t)0xb2839d6d, + (q31_t)0x65ddfbd3, (q31_t)0xb27e9d3c, (q31_t)0x65da2dbd, (q31_t)0xb2799d3a, (q31_t)0x65d65f69, (q31_t)0xb2749d68, (q31_t)0x65d290d6, (q31_t)0xb26f9dc6, + (q31_t)0x65cec204, (q31_t)0xb26a9e54, (q31_t)0x65caf2f3, (q31_t)0xb2659f12, (q31_t)0x65c723a3, (q31_t)0xb2609fff, (q31_t)0x65c35415, (q31_t)0xb25ba11d, + (q31_t)0x65bf8447, (q31_t)0xb256a26a, (q31_t)0x65bbb43b, (q31_t)0xb251a3e7, (q31_t)0x65b7e3f1, (q31_t)0xb24ca594, (q31_t)0x65b41367, (q31_t)0xb247a771, + (q31_t)0x65b0429f, (q31_t)0xb242a97e, (q31_t)0x65ac7198, (q31_t)0xb23dabbb, (q31_t)0x65a8a052, (q31_t)0xb238ae28, (q31_t)0x65a4cece, (q31_t)0xb233b0c5, + (q31_t)0x65a0fd0b, (q31_t)0xb22eb392, (q31_t)0x659d2b09, (q31_t)0xb229b68f, (q31_t)0x659958c9, (q31_t)0xb224b9bc, (q31_t)0x6595864a, (q31_t)0xb21fbd19, + (q31_t)0x6591b38c, (q31_t)0xb21ac0a6, (q31_t)0x658de08f, (q31_t)0xb215c463, (q31_t)0x658a0d54, (q31_t)0xb210c850, (q31_t)0x658639db, (q31_t)0xb20bcc6d, + (q31_t)0x65826622, (q31_t)0xb206d0ba, (q31_t)0x657e922b, (q31_t)0xb201d537, (q31_t)0x657abdf6, (q31_t)0xb1fcd9e5, (q31_t)0x6576e982, (q31_t)0xb1f7dec2, + (q31_t)0x657314cf, (q31_t)0xb1f2e3d0, (q31_t)0x656f3fde, (q31_t)0xb1ede90e, (q31_t)0x656b6aae, (q31_t)0xb1e8ee7c, (q31_t)0x6567953f, (q31_t)0xb1e3f41a, + (q31_t)0x6563bf92, (q31_t)0xb1def9e9, (q31_t)0x655fe9a7, (q31_t)0xb1d9ffe7, (q31_t)0x655c137d, (q31_t)0xb1d50616, (q31_t)0x65583d14, (q31_t)0xb1d00c75, + (q31_t)0x6554666d, (q31_t)0xb1cb1304, (q31_t)0x65508f87, (q31_t)0xb1c619c3, (q31_t)0x654cb863, (q31_t)0xb1c120b3, (q31_t)0x6548e101, (q31_t)0xb1bc27d3, + (q31_t)0x6545095f, (q31_t)0xb1b72f23, (q31_t)0x65413180, (q31_t)0xb1b236a4, (q31_t)0x653d5962, (q31_t)0xb1ad3e55, (q31_t)0x65398105, (q31_t)0xb1a84636, + (q31_t)0x6535a86b, (q31_t)0xb1a34e47, (q31_t)0x6531cf91, (q31_t)0xb19e5689, (q31_t)0x652df679, (q31_t)0xb1995efb, (q31_t)0x652a1d23, (q31_t)0xb194679e, + (q31_t)0x6526438f, (q31_t)0xb18f7071, (q31_t)0x652269bc, (q31_t)0xb18a7974, (q31_t)0x651e8faa, (q31_t)0xb18582a8, (q31_t)0x651ab55b, (q31_t)0xb1808c0c, + (q31_t)0x6516dacd, (q31_t)0xb17b95a0, (q31_t)0x65130000, (q31_t)0xb1769f65, (q31_t)0x650f24f5, (q31_t)0xb171a95b, (q31_t)0x650b49ac, (q31_t)0xb16cb380, + (q31_t)0x65076e25, (q31_t)0xb167bdd7, (q31_t)0x6503925f, (q31_t)0xb162c85d, (q31_t)0x64ffb65b, (q31_t)0xb15dd315, (q31_t)0x64fbda18, (q31_t)0xb158ddfd, + (q31_t)0x64f7fd98, (q31_t)0xb153e915, (q31_t)0x64f420d9, (q31_t)0xb14ef45e, (q31_t)0x64f043dc, (q31_t)0xb149ffd7, (q31_t)0x64ec66a0, (q31_t)0xb1450b81, + (q31_t)0x64e88926, (q31_t)0xb140175b, (q31_t)0x64e4ab6e, (q31_t)0xb13b2367, (q31_t)0x64e0cd78, (q31_t)0xb1362fa2, (q31_t)0x64dcef44, (q31_t)0xb1313c0e, + (q31_t)0x64d910d1, (q31_t)0xb12c48ab, (q31_t)0x64d53220, (q31_t)0xb1275579, (q31_t)0x64d15331, (q31_t)0xb1226277, (q31_t)0x64cd7404, (q31_t)0xb11d6fa6, + (q31_t)0x64c99498, (q31_t)0xb1187d05, (q31_t)0x64c5b4ef, (q31_t)0xb1138a95, (q31_t)0x64c1d507, (q31_t)0xb10e9856, (q31_t)0x64bdf4e1, (q31_t)0xb109a648, + (q31_t)0x64ba147d, (q31_t)0xb104b46a, (q31_t)0x64b633da, (q31_t)0xb0ffc2bd, (q31_t)0x64b252fa, (q31_t)0xb0fad140, (q31_t)0x64ae71dc, (q31_t)0xb0f5dff5, + (q31_t)0x64aa907f, (q31_t)0xb0f0eeda, (q31_t)0x64a6aee4, (q31_t)0xb0ebfdf0, (q31_t)0x64a2cd0c, (q31_t)0xb0e70d37, (q31_t)0x649eeaf5, (q31_t)0xb0e21cae, + (q31_t)0x649b08a0, (q31_t)0xb0dd2c56, (q31_t)0x6497260d, (q31_t)0xb0d83c2f, (q31_t)0x6493433c, (q31_t)0xb0d34c39, (q31_t)0x648f602d, (q31_t)0xb0ce5c74, + (q31_t)0x648b7ce0, (q31_t)0xb0c96ce0, (q31_t)0x64879955, (q31_t)0xb0c47d7c, (q31_t)0x6483b58c, (q31_t)0xb0bf8e4a, (q31_t)0x647fd185, (q31_t)0xb0ba9f48, + (q31_t)0x647bed3f, (q31_t)0xb0b5b077, (q31_t)0x647808bc, (q31_t)0xb0b0c1d7, (q31_t)0x647423fb, (q31_t)0xb0abd368, (q31_t)0x64703efc, (q31_t)0xb0a6e52a, + (q31_t)0x646c59bf, (q31_t)0xb0a1f71d, (q31_t)0x64687444, (q31_t)0xb09d0941, (q31_t)0x64648e8c, (q31_t)0xb0981b96, (q31_t)0x6460a895, (q31_t)0xb0932e1b, + (q31_t)0x645cc260, (q31_t)0xb08e40d2, (q31_t)0x6458dbed, (q31_t)0xb08953ba, (q31_t)0x6454f53d, (q31_t)0xb08466d3, (q31_t)0x64510e4e, (q31_t)0xb07f7a1c, + (q31_t)0x644d2722, (q31_t)0xb07a8d97, (q31_t)0x64493fb8, (q31_t)0xb075a143, (q31_t)0x64455810, (q31_t)0xb070b520, (q31_t)0x6441702a, (q31_t)0xb06bc92e, + (q31_t)0x643d8806, (q31_t)0xb066dd6d, (q31_t)0x64399fa5, (q31_t)0xb061f1de, (q31_t)0x6435b706, (q31_t)0xb05d067f, (q31_t)0x6431ce28, (q31_t)0xb0581b51, + (q31_t)0x642de50d, (q31_t)0xb0533055, (q31_t)0x6429fbb5, (q31_t)0xb04e458a, (q31_t)0x6426121e, (q31_t)0xb0495af0, (q31_t)0x6422284a, (q31_t)0xb0447087, + (q31_t)0x641e3e38, (q31_t)0xb03f864f, (q31_t)0x641a53e8, (q31_t)0xb03a9c49, (q31_t)0x6416695a, (q31_t)0xb035b273, (q31_t)0x64127e8f, (q31_t)0xb030c8cf, + (q31_t)0x640e9386, (q31_t)0xb02bdf5c, (q31_t)0x640aa83f, (q31_t)0xb026f61b, (q31_t)0x6406bcba, (q31_t)0xb0220d0a, (q31_t)0x6402d0f8, (q31_t)0xb01d242b, + (q31_t)0x63fee4f8, (q31_t)0xb0183b7d, (q31_t)0x63faf8bb, (q31_t)0xb0135301, (q31_t)0x63f70c3f, (q31_t)0xb00e6ab5, (q31_t)0x63f31f86, (q31_t)0xb009829c, + (q31_t)0x63ef3290, (q31_t)0xb0049ab3, (q31_t)0x63eb455c, (q31_t)0xafffb2fc, (q31_t)0x63e757ea, (q31_t)0xaffacb76, (q31_t)0x63e36a3a, (q31_t)0xaff5e421, + (q31_t)0x63df7c4d, (q31_t)0xaff0fcfe, (q31_t)0x63db8e22, (q31_t)0xafec160c, (q31_t)0x63d79fba, (q31_t)0xafe72f4c, (q31_t)0x63d3b114, (q31_t)0xafe248bd, + (q31_t)0x63cfc231, (q31_t)0xafdd625f, (q31_t)0x63cbd310, (q31_t)0xafd87c33, (q31_t)0x63c7e3b1, (q31_t)0xafd39638, (q31_t)0x63c3f415, (q31_t)0xafceb06f, + (q31_t)0x63c0043b, (q31_t)0xafc9cad7, (q31_t)0x63bc1424, (q31_t)0xafc4e571, (q31_t)0x63b823cf, (q31_t)0xafc0003c, (q31_t)0x63b4333d, (q31_t)0xafbb1b39, + (q31_t)0x63b0426d, (q31_t)0xafb63667, (q31_t)0x63ac5160, (q31_t)0xafb151c7, (q31_t)0x63a86015, (q31_t)0xafac6d58, (q31_t)0x63a46e8d, (q31_t)0xafa7891b, + (q31_t)0x63a07cc7, (q31_t)0xafa2a50f, (q31_t)0x639c8ac4, (q31_t)0xaf9dc135, (q31_t)0x63989884, (q31_t)0xaf98dd8d, (q31_t)0x6394a606, (q31_t)0xaf93fa16, + (q31_t)0x6390b34a, (q31_t)0xaf8f16d1, (q31_t)0x638cc051, (q31_t)0xaf8a33bd, (q31_t)0x6388cd1b, (q31_t)0xaf8550db, (q31_t)0x6384d9a7, (q31_t)0xaf806e2b, + (q31_t)0x6380e5f6, (q31_t)0xaf7b8bac, (q31_t)0x637cf208, (q31_t)0xaf76a95f, (q31_t)0x6378fddc, (q31_t)0xaf71c743, (q31_t)0x63750973, (q31_t)0xaf6ce55a, + (q31_t)0x637114cc, (q31_t)0xaf6803a2, (q31_t)0x636d1fe9, (q31_t)0xaf63221c, (q31_t)0x63692ac7, (q31_t)0xaf5e40c7, (q31_t)0x63653569, (q31_t)0xaf595fa4, + (q31_t)0x63613fcd, (q31_t)0xaf547eb3, (q31_t)0x635d49f4, (q31_t)0xaf4f9df4, (q31_t)0x635953dd, (q31_t)0xaf4abd66, (q31_t)0x63555d8a, (q31_t)0xaf45dd0b, + (q31_t)0x635166f9, (q31_t)0xaf40fce1, (q31_t)0x634d702b, (q31_t)0xaf3c1ce9, (q31_t)0x6349791f, (q31_t)0xaf373d22, (q31_t)0x634581d6, (q31_t)0xaf325d8e, + (q31_t)0x63418a50, (q31_t)0xaf2d7e2b, (q31_t)0x633d928d, (q31_t)0xaf289efa, (q31_t)0x63399a8d, (q31_t)0xaf23bffb, (q31_t)0x6335a24f, (q31_t)0xaf1ee12e, + (q31_t)0x6331a9d4, (q31_t)0xaf1a0293, (q31_t)0x632db11c, (q31_t)0xaf15242a, (q31_t)0x6329b827, (q31_t)0xaf1045f3, (q31_t)0x6325bef5, (q31_t)0xaf0b67ed, + (q31_t)0x6321c585, (q31_t)0xaf068a1a, (q31_t)0x631dcbd9, (q31_t)0xaf01ac78, (q31_t)0x6319d1ef, (q31_t)0xaefccf09, (q31_t)0x6315d7c8, (q31_t)0xaef7f1cb, + (q31_t)0x6311dd64, (q31_t)0xaef314c0, (q31_t)0x630de2c3, (q31_t)0xaeee37e6, (q31_t)0x6309e7e4, (q31_t)0xaee95b3f, (q31_t)0x6305ecc9, (q31_t)0xaee47ec9, + (q31_t)0x6301f171, (q31_t)0xaedfa285, (q31_t)0x62fdf5db, (q31_t)0xaedac674, (q31_t)0x62f9fa09, (q31_t)0xaed5ea95, (q31_t)0x62f5fdf9, (q31_t)0xaed10ee7, + (q31_t)0x62f201ac, (q31_t)0xaecc336c, (q31_t)0x62ee0523, (q31_t)0xaec75823, (q31_t)0x62ea085c, (q31_t)0xaec27d0c, (q31_t)0x62e60b58, (q31_t)0xaebda227, + (q31_t)0x62e20e17, (q31_t)0xaeb8c774, (q31_t)0x62de109a, (q31_t)0xaeb3ecf3, (q31_t)0x62da12df, (q31_t)0xaeaf12a4, (q31_t)0x62d614e7, (q31_t)0xaeaa3888, + (q31_t)0x62d216b3, (q31_t)0xaea55e9e, (q31_t)0x62ce1841, (q31_t)0xaea084e6, (q31_t)0x62ca1992, (q31_t)0xae9bab60, (q31_t)0x62c61aa7, (q31_t)0xae96d20c, + (q31_t)0x62c21b7e, (q31_t)0xae91f8eb, (q31_t)0x62be1c19, (q31_t)0xae8d1ffb, (q31_t)0x62ba1c77, (q31_t)0xae88473e, (q31_t)0x62b61c98, (q31_t)0xae836eb4, + (q31_t)0x62b21c7b, (q31_t)0xae7e965b, (q31_t)0x62ae1c23, (q31_t)0xae79be35, (q31_t)0x62aa1b8d, (q31_t)0xae74e641, (q31_t)0x62a61aba, (q31_t)0xae700e80, + (q31_t)0x62a219aa, (q31_t)0xae6b36f0, (q31_t)0x629e185e, (q31_t)0xae665f93, (q31_t)0x629a16d5, (q31_t)0xae618869, (q31_t)0x6296150f, (q31_t)0xae5cb171, + (q31_t)0x6292130c, (q31_t)0xae57daab, (q31_t)0x628e10cc, (q31_t)0xae530417, (q31_t)0x628a0e50, (q31_t)0xae4e2db6, (q31_t)0x62860b97, (q31_t)0xae495787, + (q31_t)0x628208a1, (q31_t)0xae44818b, (q31_t)0x627e056e, (q31_t)0xae3fabc1, (q31_t)0x627a01fe, (q31_t)0xae3ad629, (q31_t)0x6275fe52, (q31_t)0xae3600c4, + (q31_t)0x6271fa69, (q31_t)0xae312b92, (q31_t)0x626df643, (q31_t)0xae2c5691, (q31_t)0x6269f1e1, (q31_t)0xae2781c4, (q31_t)0x6265ed42, (q31_t)0xae22ad29, + (q31_t)0x6261e866, (q31_t)0xae1dd8c0, (q31_t)0x625de34e, (q31_t)0xae19048a, (q31_t)0x6259ddf8, (q31_t)0xae143086, (q31_t)0x6255d866, (q31_t)0xae0f5cb5, + (q31_t)0x6251d298, (q31_t)0xae0a8916, (q31_t)0x624dcc8d, (q31_t)0xae05b5aa, (q31_t)0x6249c645, (q31_t)0xae00e271, (q31_t)0x6245bfc0, (q31_t)0xadfc0f6a, + (q31_t)0x6241b8ff, (q31_t)0xadf73c96, (q31_t)0x623db202, (q31_t)0xadf269f4, (q31_t)0x6239aac7, (q31_t)0xaded9785, (q31_t)0x6235a351, (q31_t)0xade8c548, + (q31_t)0x62319b9d, (q31_t)0xade3f33e, (q31_t)0x622d93ad, (q31_t)0xaddf2167, (q31_t)0x62298b81, (q31_t)0xadda4fc3, (q31_t)0x62258317, (q31_t)0xadd57e51, + (q31_t)0x62217a72, (q31_t)0xadd0ad12, (q31_t)0x621d7190, (q31_t)0xadcbdc05, (q31_t)0x62196871, (q31_t)0xadc70b2c, (q31_t)0x62155f16, (q31_t)0xadc23a85, + (q31_t)0x6211557e, (q31_t)0xadbd6a10, (q31_t)0x620d4baa, (q31_t)0xadb899cf, (q31_t)0x62094199, (q31_t)0xadb3c9c0, (q31_t)0x6205374c, (q31_t)0xadaef9e4, + (q31_t)0x62012cc2, (q31_t)0xadaa2a3b, (q31_t)0x61fd21fc, (q31_t)0xada55ac4, (q31_t)0x61f916f9, (q31_t)0xada08b80, (q31_t)0x61f50bba, (q31_t)0xad9bbc70, + (q31_t)0x61f1003f, (q31_t)0xad96ed92, (q31_t)0x61ecf487, (q31_t)0xad921ee6, (q31_t)0x61e8e893, (q31_t)0xad8d506e, (q31_t)0x61e4dc62, (q31_t)0xad888229, + (q31_t)0x61e0cff5, (q31_t)0xad83b416, (q31_t)0x61dcc34c, (q31_t)0xad7ee636, (q31_t)0x61d8b666, (q31_t)0xad7a1889, (q31_t)0x61d4a944, (q31_t)0xad754b0f, + (q31_t)0x61d09be5, (q31_t)0xad707dc8, (q31_t)0x61cc8e4b, (q31_t)0xad6bb0b4, (q31_t)0x61c88074, (q31_t)0xad66e3d3, (q31_t)0x61c47260, (q31_t)0xad621725, + (q31_t)0x61c06410, (q31_t)0xad5d4aaa, (q31_t)0x61bc5584, (q31_t)0xad587e61, (q31_t)0x61b846bc, (q31_t)0xad53b24c, (q31_t)0x61b437b7, (q31_t)0xad4ee66a, + (q31_t)0x61b02876, (q31_t)0xad4a1aba, (q31_t)0x61ac18f9, (q31_t)0xad454f3e, (q31_t)0x61a80940, (q31_t)0xad4083f5, (q31_t)0x61a3f94a, (q31_t)0xad3bb8df, + (q31_t)0x619fe918, (q31_t)0xad36edfc, (q31_t)0x619bd8aa, (q31_t)0xad32234b, (q31_t)0x6197c800, (q31_t)0xad2d58ce, (q31_t)0x6193b719, (q31_t)0xad288e85, + (q31_t)0x618fa5f7, (q31_t)0xad23c46e, (q31_t)0x618b9498, (q31_t)0xad1efa8a, (q31_t)0x618782fd, (q31_t)0xad1a30d9, (q31_t)0x61837126, (q31_t)0xad15675c, + (q31_t)0x617f5f12, (q31_t)0xad109e12, (q31_t)0x617b4cc3, (q31_t)0xad0bd4fb, (q31_t)0x61773a37, (q31_t)0xad070c17, (q31_t)0x61732770, (q31_t)0xad024366, + (q31_t)0x616f146c, (q31_t)0xacfd7ae8, (q31_t)0x616b012c, (q31_t)0xacf8b29e, (q31_t)0x6166edb0, (q31_t)0xacf3ea87, (q31_t)0x6162d9f8, (q31_t)0xacef22a3, + (q31_t)0x615ec603, (q31_t)0xacea5af2, (q31_t)0x615ab1d3, (q31_t)0xace59375, (q31_t)0x61569d67, (q31_t)0xace0cc2b, (q31_t)0x615288be, (q31_t)0xacdc0514, + (q31_t)0x614e73da, (q31_t)0xacd73e30, (q31_t)0x614a5eba, (q31_t)0xacd27780, (q31_t)0x6146495d, (q31_t)0xaccdb103, (q31_t)0x614233c5, (q31_t)0xacc8eab9, + (q31_t)0x613e1df0, (q31_t)0xacc424a3, (q31_t)0x613a07e0, (q31_t)0xacbf5ec0, (q31_t)0x6135f193, (q31_t)0xacba9910, (q31_t)0x6131db0b, (q31_t)0xacb5d394, + (q31_t)0x612dc447, (q31_t)0xacb10e4b, (q31_t)0x6129ad46, (q31_t)0xacac4935, (q31_t)0x6125960a, (q31_t)0xaca78453, (q31_t)0x61217e92, (q31_t)0xaca2bfa4, + (q31_t)0x611d66de, (q31_t)0xac9dfb29, (q31_t)0x61194eee, (q31_t)0xac9936e1, (q31_t)0x611536c2, (q31_t)0xac9472cd, (q31_t)0x61111e5b, (q31_t)0xac8faeec, + (q31_t)0x610d05b7, (q31_t)0xac8aeb3e, (q31_t)0x6108ecd8, (q31_t)0xac8627c4, (q31_t)0x6104d3bc, (q31_t)0xac81647e, (q31_t)0x6100ba65, (q31_t)0xac7ca16b, + (q31_t)0x60fca0d2, (q31_t)0xac77de8b, (q31_t)0x60f88703, (q31_t)0xac731bdf, (q31_t)0x60f46cf9, (q31_t)0xac6e5967, (q31_t)0x60f052b2, (q31_t)0xac699722, + (q31_t)0x60ec3830, (q31_t)0xac64d510, (q31_t)0x60e81d72, (q31_t)0xac601333, (q31_t)0x60e40278, (q31_t)0xac5b5189, (q31_t)0x60dfe743, (q31_t)0xac569012, + (q31_t)0x60dbcbd1, (q31_t)0xac51cecf, (q31_t)0x60d7b024, (q31_t)0xac4d0dc0, (q31_t)0x60d3943b, (q31_t)0xac484ce4, (q31_t)0x60cf7817, (q31_t)0xac438c3c, + (q31_t)0x60cb5bb7, (q31_t)0xac3ecbc7, (q31_t)0x60c73f1b, (q31_t)0xac3a0b87, (q31_t)0x60c32243, (q31_t)0xac354b7a, (q31_t)0x60bf0530, (q31_t)0xac308ba0, + (q31_t)0x60bae7e1, (q31_t)0xac2bcbfa, (q31_t)0x60b6ca56, (q31_t)0xac270c88, (q31_t)0x60b2ac8f, (q31_t)0xac224d4a, (q31_t)0x60ae8e8d, (q31_t)0xac1d8e40, + (q31_t)0x60aa7050, (q31_t)0xac18cf69, (q31_t)0x60a651d7, (q31_t)0xac1410c6, (q31_t)0x60a23322, (q31_t)0xac0f5256, (q31_t)0x609e1431, (q31_t)0xac0a941b, + (q31_t)0x6099f505, (q31_t)0xac05d613, (q31_t)0x6095d59d, (q31_t)0xac01183f, (q31_t)0x6091b5fa, (q31_t)0xabfc5a9f, (q31_t)0x608d961b, (q31_t)0xabf79d33, + (q31_t)0x60897601, (q31_t)0xabf2dffb, (q31_t)0x608555ab, (q31_t)0xabee22f6, (q31_t)0x60813519, (q31_t)0xabe96625, (q31_t)0x607d144c, (q31_t)0xabe4a988, + (q31_t)0x6078f344, (q31_t)0xabdfed1f, (q31_t)0x6074d200, (q31_t)0xabdb30ea, (q31_t)0x6070b080, (q31_t)0xabd674e9, (q31_t)0x606c8ec5, (q31_t)0xabd1b91c, + (q31_t)0x60686ccf, (q31_t)0xabccfd83, (q31_t)0x60644a9d, (q31_t)0xabc8421d, (q31_t)0x6060282f, (q31_t)0xabc386ec, (q31_t)0x605c0587, (q31_t)0xabbecbee, + (q31_t)0x6057e2a2, (q31_t)0xabba1125, (q31_t)0x6053bf82, (q31_t)0xabb5568f, (q31_t)0x604f9c27, (q31_t)0xabb09c2e, (q31_t)0x604b7891, (q31_t)0xababe200, + (q31_t)0x604754bf, (q31_t)0xaba72807, (q31_t)0x604330b1, (q31_t)0xaba26e41, (q31_t)0x603f0c69, (q31_t)0xab9db4b0, (q31_t)0x603ae7e5, (q31_t)0xab98fb52, + (q31_t)0x6036c325, (q31_t)0xab944229, (q31_t)0x60329e2a, (q31_t)0xab8f8934, (q31_t)0x602e78f4, (q31_t)0xab8ad073, (q31_t)0x602a5383, (q31_t)0xab8617e6, + (q31_t)0x60262dd6, (q31_t)0xab815f8d, (q31_t)0x602207ee, (q31_t)0xab7ca768, (q31_t)0x601de1ca, (q31_t)0xab77ef77, (q31_t)0x6019bb6b, (q31_t)0xab7337bb, + (q31_t)0x601594d1, (q31_t)0xab6e8032, (q31_t)0x60116dfc, (q31_t)0xab69c8de, (q31_t)0x600d46ec, (q31_t)0xab6511be, (q31_t)0x60091fa0, (q31_t)0xab605ad2, + (q31_t)0x6004f819, (q31_t)0xab5ba41a, (q31_t)0x6000d057, (q31_t)0xab56ed97, (q31_t)0x5ffca859, (q31_t)0xab523748, (q31_t)0x5ff88021, (q31_t)0xab4d812d, + (q31_t)0x5ff457ad, (q31_t)0xab48cb46, (q31_t)0x5ff02efe, (q31_t)0xab441593, (q31_t)0x5fec0613, (q31_t)0xab3f6015, (q31_t)0x5fe7dcee, (q31_t)0xab3aaacb, + (q31_t)0x5fe3b38d, (q31_t)0xab35f5b5, (q31_t)0x5fdf89f2, (q31_t)0xab3140d4, (q31_t)0x5fdb601b, (q31_t)0xab2c8c27, (q31_t)0x5fd73609, (q31_t)0xab27d7ae, + (q31_t)0x5fd30bbc, (q31_t)0xab23236a, (q31_t)0x5fcee133, (q31_t)0xab1e6f5a, (q31_t)0x5fcab670, (q31_t)0xab19bb7e, (q31_t)0x5fc68b72, (q31_t)0xab1507d7, + (q31_t)0x5fc26038, (q31_t)0xab105464, (q31_t)0x5fbe34c4, (q31_t)0xab0ba125, (q31_t)0x5fba0914, (q31_t)0xab06ee1b, (q31_t)0x5fb5dd29, (q31_t)0xab023b46, + (q31_t)0x5fb1b104, (q31_t)0xaafd88a4, (q31_t)0x5fad84a3, (q31_t)0xaaf8d637, (q31_t)0x5fa95807, (q31_t)0xaaf423ff, (q31_t)0x5fa52b31, (q31_t)0xaaef71fb, + (q31_t)0x5fa0fe1f, (q31_t)0xaaeac02c, (q31_t)0x5f9cd0d2, (q31_t)0xaae60e91, (q31_t)0x5f98a34a, (q31_t)0xaae15d2a, (q31_t)0x5f947588, (q31_t)0xaadcabf8, + (q31_t)0x5f90478a, (q31_t)0xaad7fafb, (q31_t)0x5f8c1951, (q31_t)0xaad34a32, (q31_t)0x5f87eade, (q31_t)0xaace999d, (q31_t)0x5f83bc2f, (q31_t)0xaac9e93e, + (q31_t)0x5f7f8d46, (q31_t)0xaac53912, (q31_t)0x5f7b5e22, (q31_t)0xaac0891c, (q31_t)0x5f772ec2, (q31_t)0xaabbd959, (q31_t)0x5f72ff28, (q31_t)0xaab729cc, + (q31_t)0x5f6ecf53, (q31_t)0xaab27a73, (q31_t)0x5f6a9f44, (q31_t)0xaaadcb4f, (q31_t)0x5f666ef9, (q31_t)0xaaa91c5f, (q31_t)0x5f623e73, (q31_t)0xaaa46da4, + (q31_t)0x5f5e0db3, (q31_t)0xaa9fbf1e, (q31_t)0x5f59dcb8, (q31_t)0xaa9b10cc, (q31_t)0x5f55ab82, (q31_t)0xaa9662af, (q31_t)0x5f517a11, (q31_t)0xaa91b4c7, + (q31_t)0x5f4d4865, (q31_t)0xaa8d0713, (q31_t)0x5f49167f, (q31_t)0xaa885994, (q31_t)0x5f44e45e, (q31_t)0xaa83ac4a, (q31_t)0x5f40b202, (q31_t)0xaa7eff34, + (q31_t)0x5f3c7f6b, (q31_t)0xaa7a5253, (q31_t)0x5f384c9a, (q31_t)0xaa75a5a8, (q31_t)0x5f34198e, (q31_t)0xaa70f930, (q31_t)0x5f2fe647, (q31_t)0xaa6c4cee, + (q31_t)0x5f2bb2c5, (q31_t)0xaa67a0e0, (q31_t)0x5f277f09, (q31_t)0xaa62f507, (q31_t)0x5f234b12, (q31_t)0xaa5e4963, (q31_t)0x5f1f16e0, (q31_t)0xaa599df4, + (q31_t)0x5f1ae274, (q31_t)0xaa54f2ba, (q31_t)0x5f16adcc, (q31_t)0xaa5047b4, (q31_t)0x5f1278eb, (q31_t)0xaa4b9ce3, (q31_t)0x5f0e43ce, (q31_t)0xaa46f248, + (q31_t)0x5f0a0e77, (q31_t)0xaa4247e1, (q31_t)0x5f05d8e6, (q31_t)0xaa3d9daf, (q31_t)0x5f01a31a, (q31_t)0xaa38f3b1, (q31_t)0x5efd6d13, (q31_t)0xaa3449e9, + (q31_t)0x5ef936d1, (q31_t)0xaa2fa056, (q31_t)0x5ef50055, (q31_t)0xaa2af6f7, (q31_t)0x5ef0c99f, (q31_t)0xaa264dce, (q31_t)0x5eec92ae, (q31_t)0xaa21a4d9, + (q31_t)0x5ee85b82, (q31_t)0xaa1cfc1a, (q31_t)0x5ee4241c, (q31_t)0xaa18538f, (q31_t)0x5edfec7b, (q31_t)0xaa13ab3a, (q31_t)0x5edbb49f, (q31_t)0xaa0f0319, + (q31_t)0x5ed77c8a, (q31_t)0xaa0a5b2e, (q31_t)0x5ed34439, (q31_t)0xaa05b377, (q31_t)0x5ecf0baf, (q31_t)0xaa010bf6, (q31_t)0x5ecad2e9, (q31_t)0xa9fc64a9, + (q31_t)0x5ec699e9, (q31_t)0xa9f7bd92, (q31_t)0x5ec260af, (q31_t)0xa9f316b0, (q31_t)0x5ebe273b, (q31_t)0xa9ee7002, (q31_t)0x5eb9ed8b, (q31_t)0xa9e9c98a, + (q31_t)0x5eb5b3a2, (q31_t)0xa9e52347, (q31_t)0x5eb1797e, (q31_t)0xa9e07d39, (q31_t)0x5ead3f1f, (q31_t)0xa9dbd761, (q31_t)0x5ea90487, (q31_t)0xa9d731bd, + (q31_t)0x5ea4c9b3, (q31_t)0xa9d28c4e, (q31_t)0x5ea08ea6, (q31_t)0xa9cde715, (q31_t)0x5e9c535e, (q31_t)0xa9c94211, (q31_t)0x5e9817dc, (q31_t)0xa9c49d42, + (q31_t)0x5e93dc1f, (q31_t)0xa9bff8a8, (q31_t)0x5e8fa028, (q31_t)0xa9bb5444, (q31_t)0x5e8b63f7, (q31_t)0xa9b6b014, (q31_t)0x5e87278b, (q31_t)0xa9b20c1a, + (q31_t)0x5e82eae5, (q31_t)0xa9ad6855, (q31_t)0x5e7eae05, (q31_t)0xa9a8c4c5, (q31_t)0x5e7a70ea, (q31_t)0xa9a4216b, (q31_t)0x5e763395, (q31_t)0xa99f7e46, + (q31_t)0x5e71f606, (q31_t)0xa99adb56, (q31_t)0x5e6db83d, (q31_t)0xa996389b, (q31_t)0x5e697a39, (q31_t)0xa9919616, (q31_t)0x5e653bfc, (q31_t)0xa98cf3c6, + (q31_t)0x5e60fd84, (q31_t)0xa98851ac, (q31_t)0x5e5cbed1, (q31_t)0xa983afc6, (q31_t)0x5e587fe5, (q31_t)0xa97f0e16, (q31_t)0x5e5440be, (q31_t)0xa97a6c9c, + (q31_t)0x5e50015d, (q31_t)0xa975cb57, (q31_t)0x5e4bc1c2, (q31_t)0xa9712a47, (q31_t)0x5e4781ed, (q31_t)0xa96c896c, (q31_t)0x5e4341de, (q31_t)0xa967e8c7, + (q31_t)0x5e3f0194, (q31_t)0xa9634858, (q31_t)0x5e3ac110, (q31_t)0xa95ea81d, (q31_t)0x5e368053, (q31_t)0xa95a0819, (q31_t)0x5e323f5b, (q31_t)0xa9556849, + (q31_t)0x5e2dfe29, (q31_t)0xa950c8b0, (q31_t)0x5e29bcbd, (q31_t)0xa94c294b, (q31_t)0x5e257b17, (q31_t)0xa9478a1c, (q31_t)0x5e213936, (q31_t)0xa942eb23, + (q31_t)0x5e1cf71c, (q31_t)0xa93e4c5f, (q31_t)0x5e18b4c8, (q31_t)0xa939add1, (q31_t)0x5e147239, (q31_t)0xa9350f78, (q31_t)0x5e102f71, (q31_t)0xa9307155, + (q31_t)0x5e0bec6e, (q31_t)0xa92bd367, (q31_t)0x5e07a932, (q31_t)0xa92735af, (q31_t)0x5e0365bb, (q31_t)0xa922982c, (q31_t)0x5dff220b, (q31_t)0xa91dfadf, + (q31_t)0x5dfade20, (q31_t)0xa9195dc7, (q31_t)0x5df699fc, (q31_t)0xa914c0e6, (q31_t)0x5df2559e, (q31_t)0xa9102439, (q31_t)0x5dee1105, (q31_t)0xa90b87c3, + (q31_t)0x5de9cc33, (q31_t)0xa906eb82, (q31_t)0x5de58727, (q31_t)0xa9024f76, (q31_t)0x5de141e1, (q31_t)0xa8fdb3a1, (q31_t)0x5ddcfc61, (q31_t)0xa8f91801, + (q31_t)0x5dd8b6a7, (q31_t)0xa8f47c97, (q31_t)0x5dd470b3, (q31_t)0xa8efe162, (q31_t)0x5dd02a85, (q31_t)0xa8eb4663, (q31_t)0x5dcbe41d, (q31_t)0xa8e6ab9a, + (q31_t)0x5dc79d7c, (q31_t)0xa8e21106, (q31_t)0x5dc356a1, (q31_t)0xa8dd76a9, (q31_t)0x5dbf0f8c, (q31_t)0xa8d8dc81, (q31_t)0x5dbac83d, (q31_t)0xa8d4428f, + (q31_t)0x5db680b4, (q31_t)0xa8cfa8d2, (q31_t)0x5db238f1, (q31_t)0xa8cb0f4b, (q31_t)0x5dadf0f5, (q31_t)0xa8c675fb, (q31_t)0x5da9a8bf, (q31_t)0xa8c1dce0, + (q31_t)0x5da5604f, (q31_t)0xa8bd43fa, (q31_t)0x5da117a5, (q31_t)0xa8b8ab4b, (q31_t)0x5d9ccec2, (q31_t)0xa8b412d1, (q31_t)0x5d9885a5, (q31_t)0xa8af7a8e, + (q31_t)0x5d943c4e, (q31_t)0xa8aae280, (q31_t)0x5d8ff2bd, (q31_t)0xa8a64aa8, (q31_t)0x5d8ba8f3, (q31_t)0xa8a1b306, (q31_t)0x5d875eef, (q31_t)0xa89d1b99, + (q31_t)0x5d8314b1, (q31_t)0xa8988463, (q31_t)0x5d7eca39, (q31_t)0xa893ed63, (q31_t)0x5d7a7f88, (q31_t)0xa88f5698, (q31_t)0x5d76349d, (q31_t)0xa88ac004, + (q31_t)0x5d71e979, (q31_t)0xa88629a5, (q31_t)0x5d6d9e1b, (q31_t)0xa881937c, (q31_t)0x5d695283, (q31_t)0xa87cfd8a, (q31_t)0x5d6506b2, (q31_t)0xa87867cd, + (q31_t)0x5d60baa7, (q31_t)0xa873d246, (q31_t)0x5d5c6e62, (q31_t)0xa86f3cf6, (q31_t)0x5d5821e4, (q31_t)0xa86aa7db, (q31_t)0x5d53d52d, (q31_t)0xa86612f6, + (q31_t)0x5d4f883b, (q31_t)0xa8617e48, (q31_t)0x5d4b3b10, (q31_t)0xa85ce9cf, (q31_t)0x5d46edac, (q31_t)0xa858558d, (q31_t)0x5d42a00e, (q31_t)0xa853c180, + (q31_t)0x5d3e5237, (q31_t)0xa84f2daa, (q31_t)0x5d3a0426, (q31_t)0xa84a9a0a, (q31_t)0x5d35b5db, (q31_t)0xa84606a0, (q31_t)0x5d316757, (q31_t)0xa841736c, + (q31_t)0x5d2d189a, (q31_t)0xa83ce06e, (q31_t)0x5d28c9a3, (q31_t)0xa8384da6, (q31_t)0x5d247a72, (q31_t)0xa833bb14, (q31_t)0x5d202b09, (q31_t)0xa82f28b9, + (q31_t)0x5d1bdb65, (q31_t)0xa82a9693, (q31_t)0x5d178b89, (q31_t)0xa82604a4, (q31_t)0x5d133b72, (q31_t)0xa82172eb, (q31_t)0x5d0eeb23, (q31_t)0xa81ce169, + (q31_t)0x5d0a9a9a, (q31_t)0xa818501c, (q31_t)0x5d0649d7, (q31_t)0xa813bf06, (q31_t)0x5d01f8dc, (q31_t)0xa80f2e26, (q31_t)0x5cfda7a7, (q31_t)0xa80a9d7c, + (q31_t)0x5cf95638, (q31_t)0xa8060d08, (q31_t)0x5cf50490, (q31_t)0xa8017ccb, (q31_t)0x5cf0b2af, (q31_t)0xa7fcecc4, (q31_t)0x5cec6095, (q31_t)0xa7f85cf3, + (q31_t)0x5ce80e41, (q31_t)0xa7f3cd59, (q31_t)0x5ce3bbb4, (q31_t)0xa7ef3df5, (q31_t)0x5cdf68ed, (q31_t)0xa7eaaec7, (q31_t)0x5cdb15ed, (q31_t)0xa7e61fd0, + (q31_t)0x5cd6c2b5, (q31_t)0xa7e1910f, (q31_t)0x5cd26f42, (q31_t)0xa7dd0284, (q31_t)0x5cce1b97, (q31_t)0xa7d8742f, (q31_t)0x5cc9c7b2, (q31_t)0xa7d3e611, + (q31_t)0x5cc57394, (q31_t)0xa7cf582a, (q31_t)0x5cc11f3d, (q31_t)0xa7caca79, (q31_t)0x5cbccaac, (q31_t)0xa7c63cfe, (q31_t)0x5cb875e3, (q31_t)0xa7c1afb9, + (q31_t)0x5cb420e0, (q31_t)0xa7bd22ac, (q31_t)0x5cafcba4, (q31_t)0xa7b895d4, (q31_t)0x5cab762f, (q31_t)0xa7b40933, (q31_t)0x5ca72080, (q31_t)0xa7af7cc8, + (q31_t)0x5ca2ca99, (q31_t)0xa7aaf094, (q31_t)0x5c9e7478, (q31_t)0xa7a66497, (q31_t)0x5c9a1e1e, (q31_t)0xa7a1d8d0, (q31_t)0x5c95c78b, (q31_t)0xa79d4d3f, + (q31_t)0x5c9170bf, (q31_t)0xa798c1e5, (q31_t)0x5c8d19ba, (q31_t)0xa79436c1, (q31_t)0x5c88c27c, (q31_t)0xa78fabd4, (q31_t)0x5c846b05, (q31_t)0xa78b211e, + (q31_t)0x5c801354, (q31_t)0xa786969e, (q31_t)0x5c7bbb6b, (q31_t)0xa7820c55, (q31_t)0x5c776348, (q31_t)0xa77d8242, (q31_t)0x5c730aed, (q31_t)0xa778f866, + (q31_t)0x5c6eb258, (q31_t)0xa7746ec0, (q31_t)0x5c6a598b, (q31_t)0xa76fe551, (q31_t)0x5c660084, (q31_t)0xa76b5c19, (q31_t)0x5c61a745, (q31_t)0xa766d317, + (q31_t)0x5c5d4dcc, (q31_t)0xa7624a4d, (q31_t)0x5c58f41a, (q31_t)0xa75dc1b8, (q31_t)0x5c549a30, (q31_t)0xa759395b, (q31_t)0x5c50400d, (q31_t)0xa754b134, + (q31_t)0x5c4be5b0, (q31_t)0xa7502943, (q31_t)0x5c478b1b, (q31_t)0xa74ba18a, (q31_t)0x5c43304d, (q31_t)0xa7471a07, (q31_t)0x5c3ed545, (q31_t)0xa74292bb, + (q31_t)0x5c3a7a05, (q31_t)0xa73e0ba5, (q31_t)0x5c361e8c, (q31_t)0xa73984c7, (q31_t)0x5c31c2db, (q31_t)0xa734fe1f, (q31_t)0x5c2d66f0, (q31_t)0xa73077ae, + (q31_t)0x5c290acc, (q31_t)0xa72bf174, (q31_t)0x5c24ae70, (q31_t)0xa7276b70, (q31_t)0x5c2051db, (q31_t)0xa722e5a3, (q31_t)0x5c1bf50d, (q31_t)0xa71e600d, + (q31_t)0x5c179806, (q31_t)0xa719daae, (q31_t)0x5c133ac6, (q31_t)0xa7155586, (q31_t)0x5c0edd4e, (q31_t)0xa710d095, (q31_t)0x5c0a7f9c, (q31_t)0xa70c4bda, + (q31_t)0x5c0621b2, (q31_t)0xa707c757, (q31_t)0x5c01c38f, (q31_t)0xa703430a, (q31_t)0x5bfd6534, (q31_t)0xa6febef4, (q31_t)0x5bf906a0, (q31_t)0xa6fa3b15, + (q31_t)0x5bf4a7d2, (q31_t)0xa6f5b76d, (q31_t)0x5bf048cd, (q31_t)0xa6f133fc, (q31_t)0x5bebe98e, (q31_t)0xa6ecb0c2, (q31_t)0x5be78a17, (q31_t)0xa6e82dbe, + (q31_t)0x5be32a67, (q31_t)0xa6e3aaf2, (q31_t)0x5bdeca7f, (q31_t)0xa6df285d, (q31_t)0x5bda6a5d, (q31_t)0xa6daa5fe, (q31_t)0x5bd60a03, (q31_t)0xa6d623d7, + (q31_t)0x5bd1a971, (q31_t)0xa6d1a1e7, (q31_t)0x5bcd48a6, (q31_t)0xa6cd202d, (q31_t)0x5bc8e7a2, (q31_t)0xa6c89eab, (q31_t)0x5bc48666, (q31_t)0xa6c41d60, + (q31_t)0x5bc024f0, (q31_t)0xa6bf9c4b, (q31_t)0x5bbbc343, (q31_t)0xa6bb1b6e, (q31_t)0x5bb7615d, (q31_t)0xa6b69ac8, (q31_t)0x5bb2ff3e, (q31_t)0xa6b21a59, + (q31_t)0x5bae9ce7, (q31_t)0xa6ad9a21, (q31_t)0x5baa3a57, (q31_t)0xa6a91a20, (q31_t)0x5ba5d78e, (q31_t)0xa6a49a56, (q31_t)0x5ba1748d, (q31_t)0xa6a01ac4, + (q31_t)0x5b9d1154, (q31_t)0xa69b9b68, (q31_t)0x5b98ade2, (q31_t)0xa6971c44, (q31_t)0x5b944a37, (q31_t)0xa6929d57, (q31_t)0x5b8fe654, (q31_t)0xa68e1ea1, + (q31_t)0x5b8b8239, (q31_t)0xa689a022, (q31_t)0x5b871de5, (q31_t)0xa68521da, (q31_t)0x5b82b958, (q31_t)0xa680a3ca, (q31_t)0x5b7e5493, (q31_t)0xa67c25f0, + (q31_t)0x5b79ef96, (q31_t)0xa677a84e, (q31_t)0x5b758a60, (q31_t)0xa6732ae3, (q31_t)0x5b7124f2, (q31_t)0xa66eadb0, (q31_t)0x5b6cbf4c, (q31_t)0xa66a30b3, + (q31_t)0x5b68596d, (q31_t)0xa665b3ee, (q31_t)0x5b63f355, (q31_t)0xa6613760, (q31_t)0x5b5f8d06, (q31_t)0xa65cbb0a, (q31_t)0x5b5b267e, (q31_t)0xa6583eeb, + (q31_t)0x5b56bfbd, (q31_t)0xa653c303, (q31_t)0x5b5258c4, (q31_t)0xa64f4752, (q31_t)0x5b4df193, (q31_t)0xa64acbd9, (q31_t)0x5b498a2a, (q31_t)0xa6465097, + (q31_t)0x5b452288, (q31_t)0xa641d58c, (q31_t)0x5b40baae, (q31_t)0xa63d5ab9, (q31_t)0x5b3c529c, (q31_t)0xa638e01d, (q31_t)0x5b37ea51, (q31_t)0xa63465b9, + (q31_t)0x5b3381ce, (q31_t)0xa62feb8b, (q31_t)0x5b2f1913, (q31_t)0xa62b7196, (q31_t)0x5b2ab020, (q31_t)0xa626f7d7, (q31_t)0x5b2646f4, (q31_t)0xa6227e50, + (q31_t)0x5b21dd90, (q31_t)0xa61e0501, (q31_t)0x5b1d73f4, (q31_t)0xa6198be9, (q31_t)0x5b190a20, (q31_t)0xa6151308, (q31_t)0x5b14a014, (q31_t)0xa6109a5f, + (q31_t)0x5b1035cf, (q31_t)0xa60c21ee, (q31_t)0x5b0bcb52, (q31_t)0xa607a9b4, (q31_t)0x5b07609d, (q31_t)0xa60331b1, (q31_t)0x5b02f5b0, (q31_t)0xa5feb9e6, + (q31_t)0x5afe8a8b, (q31_t)0xa5fa4252, (q31_t)0x5afa1f2e, (q31_t)0xa5f5caf6, (q31_t)0x5af5b398, (q31_t)0xa5f153d2, (q31_t)0x5af147ca, (q31_t)0xa5ecdce5, + (q31_t)0x5aecdbc5, (q31_t)0xa5e8662f, (q31_t)0x5ae86f87, (q31_t)0xa5e3efb1, (q31_t)0x5ae40311, (q31_t)0xa5df796b, (q31_t)0x5adf9663, (q31_t)0xa5db035c, + (q31_t)0x5adb297d, (q31_t)0xa5d68d85, (q31_t)0x5ad6bc5f, (q31_t)0xa5d217e6, (q31_t)0x5ad24f09, (q31_t)0xa5cda27e, (q31_t)0x5acde17b, (q31_t)0xa5c92d4e, + (q31_t)0x5ac973b5, (q31_t)0xa5c4b855, (q31_t)0x5ac505b7, (q31_t)0xa5c04395, (q31_t)0x5ac09781, (q31_t)0xa5bbcf0b, (q31_t)0x5abc2912, (q31_t)0xa5b75aba, + (q31_t)0x5ab7ba6c, (q31_t)0xa5b2e6a0, (q31_t)0x5ab34b8e, (q31_t)0xa5ae72be, (q31_t)0x5aaedc78, (q31_t)0xa5a9ff14, (q31_t)0x5aaa6d2b, (q31_t)0xa5a58ba1, + (q31_t)0x5aa5fda5, (q31_t)0xa5a11866, (q31_t)0x5aa18de7, (q31_t)0xa59ca563, (q31_t)0x5a9d1df1, (q31_t)0xa5983297, (q31_t)0x5a98adc4, (q31_t)0xa593c004, + (q31_t)0x5a943d5e, (q31_t)0xa58f4da8, (q31_t)0x5a8fccc1, (q31_t)0xa58adb84, (q31_t)0x5a8b5bec, (q31_t)0xa5866997, (q31_t)0x5a86eadf, (q31_t)0xa581f7e3, + (q31_t)0x5a82799a, (q31_t)0xa57d8666, (q31_t)0x5a7e081d, (q31_t)0xa5791521, (q31_t)0x5a799669, (q31_t)0xa574a414, (q31_t)0x5a75247c, (q31_t)0xa570333f, + (q31_t)0x5a70b258, (q31_t)0xa56bc2a2, (q31_t)0x5a6c3ffc, (q31_t)0xa567523c, (q31_t)0x5a67cd69, (q31_t)0xa562e20f, (q31_t)0x5a635a9d, (q31_t)0xa55e7219, + (q31_t)0x5a5ee79a, (q31_t)0xa55a025b, (q31_t)0x5a5a745f, (q31_t)0xa55592d5, (q31_t)0x5a5600ec, (q31_t)0xa5512388, (q31_t)0x5a518d42, (q31_t)0xa54cb472, + (q31_t)0x5a4d1960, (q31_t)0xa5484594, (q31_t)0x5a48a546, (q31_t)0xa543d6ee, (q31_t)0x5a4430f5, (q31_t)0xa53f687f, (q31_t)0x5a3fbc6b, (q31_t)0xa53afa49, + (q31_t)0x5a3b47ab, (q31_t)0xa5368c4b, (q31_t)0x5a36d2b2, (q31_t)0xa5321e85, (q31_t)0x5a325d82, (q31_t)0xa52db0f7, (q31_t)0x5a2de81a, (q31_t)0xa52943a1, + (q31_t)0x5a29727b, (q31_t)0xa524d683, (q31_t)0x5a24fca4, (q31_t)0xa520699d, (q31_t)0x5a208695, (q31_t)0xa51bfcef, (q31_t)0x5a1c104f, (q31_t)0xa5179079, + (q31_t)0x5a1799d1, (q31_t)0xa513243b, (q31_t)0x5a13231b, (q31_t)0xa50eb836, (q31_t)0x5a0eac2e, (q31_t)0xa50a4c68, (q31_t)0x5a0a350a, (q31_t)0xa505e0d2, + (q31_t)0x5a05bdae, (q31_t)0xa5017575, (q31_t)0x5a01461a, (q31_t)0xa4fd0a50, (q31_t)0x59fcce4f, (q31_t)0xa4f89f63, (q31_t)0x59f8564c, (q31_t)0xa4f434ae, + (q31_t)0x59f3de12, (q31_t)0xa4efca31, (q31_t)0x59ef65a1, (q31_t)0xa4eb5fec, (q31_t)0x59eaecf8, (q31_t)0xa4e6f5e0, (q31_t)0x59e67417, (q31_t)0xa4e28c0c, + (q31_t)0x59e1faff, (q31_t)0xa4de2270, (q31_t)0x59dd81b0, (q31_t)0xa4d9b90c, (q31_t)0x59d90829, (q31_t)0xa4d54fe0, (q31_t)0x59d48e6a, (q31_t)0xa4d0e6ed, + (q31_t)0x59d01475, (q31_t)0xa4cc7e32, (q31_t)0x59cb9a47, (q31_t)0xa4c815af, (q31_t)0x59c71fe3, (q31_t)0xa4c3ad64, (q31_t)0x59c2a547, (q31_t)0xa4bf4552, + (q31_t)0x59be2a74, (q31_t)0xa4badd78, (q31_t)0x59b9af69, (q31_t)0xa4b675d6, (q31_t)0x59b53427, (q31_t)0xa4b20e6d, (q31_t)0x59b0b8ae, (q31_t)0xa4ada73c, + (q31_t)0x59ac3cfd, (q31_t)0xa4a94043, (q31_t)0x59a7c115, (q31_t)0xa4a4d982, (q31_t)0x59a344f6, (q31_t)0xa4a072fa, (q31_t)0x599ec8a0, (q31_t)0xa49c0cab, + (q31_t)0x599a4c12, (q31_t)0xa497a693, (q31_t)0x5995cf4d, (q31_t)0xa49340b4, (q31_t)0x59915250, (q31_t)0xa48edb0e, (q31_t)0x598cd51d, (q31_t)0xa48a75a0, + (q31_t)0x598857b2, (q31_t)0xa486106a, (q31_t)0x5983da10, (q31_t)0xa481ab6d, (q31_t)0x597f5c36, (q31_t)0xa47d46a8, (q31_t)0x597ade26, (q31_t)0xa478e21b, + (q31_t)0x59765fde, (q31_t)0xa4747dc7, (q31_t)0x5971e15f, (q31_t)0xa47019ac, (q31_t)0x596d62a9, (q31_t)0xa46bb5c9, (q31_t)0x5968e3bc, (q31_t)0xa467521e, + (q31_t)0x59646498, (q31_t)0xa462eeac, (q31_t)0x595fe53c, (q31_t)0xa45e8b73, (q31_t)0x595b65aa, (q31_t)0xa45a2872, (q31_t)0x5956e5e0, (q31_t)0xa455c5a9, + (q31_t)0x595265df, (q31_t)0xa4516319, (q31_t)0x594de5a7, (q31_t)0xa44d00c2, (q31_t)0x59496538, (q31_t)0xa4489ea3, (q31_t)0x5944e492, (q31_t)0xa4443cbd, + (q31_t)0x594063b5, (q31_t)0xa43fdb10, (q31_t)0x593be2a0, (q31_t)0xa43b799a, (q31_t)0x59376155, (q31_t)0xa437185e, (q31_t)0x5932dfd3, (q31_t)0xa432b75a, + (q31_t)0x592e5e19, (q31_t)0xa42e568f, (q31_t)0x5929dc29, (q31_t)0xa429f5fd, (q31_t)0x59255a02, (q31_t)0xa42595a3, (q31_t)0x5920d7a3, (q31_t)0xa4213581, + (q31_t)0x591c550e, (q31_t)0xa41cd599, (q31_t)0x5917d242, (q31_t)0xa41875e9, (q31_t)0x59134f3e, (q31_t)0xa4141672, (q31_t)0x590ecc04, (q31_t)0xa40fb733, + (q31_t)0x590a4893, (q31_t)0xa40b582e, (q31_t)0x5905c4eb, (q31_t)0xa406f960, (q31_t)0x5901410c, (q31_t)0xa4029acc, (q31_t)0x58fcbcf6, (q31_t)0xa3fe3c71, + (q31_t)0x58f838a9, (q31_t)0xa3f9de4e, (q31_t)0x58f3b426, (q31_t)0xa3f58064, (q31_t)0x58ef2f6b, (q31_t)0xa3f122b2, (q31_t)0x58eaaa7a, (q31_t)0xa3ecc53a, + (q31_t)0x58e62552, (q31_t)0xa3e867fa, (q31_t)0x58e19ff3, (q31_t)0xa3e40af3, (q31_t)0x58dd1a5d, (q31_t)0xa3dfae25, (q31_t)0x58d89490, (q31_t)0xa3db5190, + (q31_t)0x58d40e8c, (q31_t)0xa3d6f534, (q31_t)0x58cf8852, (q31_t)0xa3d29910, (q31_t)0x58cb01e1, (q31_t)0xa3ce3d25, (q31_t)0x58c67b39, (q31_t)0xa3c9e174, + (q31_t)0x58c1f45b, (q31_t)0xa3c585fb, (q31_t)0x58bd6d45, (q31_t)0xa3c12abb, (q31_t)0x58b8e5f9, (q31_t)0xa3bccfb3, (q31_t)0x58b45e76, (q31_t)0xa3b874e5, + (q31_t)0x58afd6bd, (q31_t)0xa3b41a50, (q31_t)0x58ab4ecc, (q31_t)0xa3afbff3, (q31_t)0x58a6c6a5, (q31_t)0xa3ab65d0, (q31_t)0x58a23e48, (q31_t)0xa3a70be6, + (q31_t)0x589db5b3, (q31_t)0xa3a2b234, (q31_t)0x58992ce9, (q31_t)0xa39e58bb, (q31_t)0x5894a3e7, (q31_t)0xa399ff7c, (q31_t)0x58901aaf, (q31_t)0xa395a675, + (q31_t)0x588b9140, (q31_t)0xa3914da8, (q31_t)0x5887079a, (q31_t)0xa38cf513, (q31_t)0x58827dbe, (q31_t)0xa3889cb8, (q31_t)0x587df3ab, (q31_t)0xa3844495, + (q31_t)0x58796962, (q31_t)0xa37fecac, (q31_t)0x5874dee2, (q31_t)0xa37b94fb, (q31_t)0x5870542c, (q31_t)0xa3773d84, (q31_t)0x586bc93f, (q31_t)0xa372e646, + (q31_t)0x58673e1b, (q31_t)0xa36e8f41, (q31_t)0x5862b2c1, (q31_t)0xa36a3875, (q31_t)0x585e2730, (q31_t)0xa365e1e2, (q31_t)0x58599b69, (q31_t)0xa3618b88, + (q31_t)0x58550f6c, (q31_t)0xa35d3567, (q31_t)0x58508338, (q31_t)0xa358df80, (q31_t)0x584bf6cd, (q31_t)0xa35489d1, (q31_t)0x58476a2c, (q31_t)0xa350345c, + (q31_t)0x5842dd54, (q31_t)0xa34bdf20, (q31_t)0x583e5047, (q31_t)0xa3478a1d, (q31_t)0x5839c302, (q31_t)0xa3433554, (q31_t)0x58353587, (q31_t)0xa33ee0c3, + (q31_t)0x5830a7d6, (q31_t)0xa33a8c6c, (q31_t)0x582c19ef, (q31_t)0xa336384e, (q31_t)0x58278bd1, (q31_t)0xa331e469, (q31_t)0x5822fd7c, (q31_t)0xa32d90be, + (q31_t)0x581e6ef1, (q31_t)0xa3293d4b, (q31_t)0x5819e030, (q31_t)0xa324ea13, (q31_t)0x58155139, (q31_t)0xa3209713, (q31_t)0x5810c20b, (q31_t)0xa31c444c, + (q31_t)0x580c32a7, (q31_t)0xa317f1bf, (q31_t)0x5807a30d, (q31_t)0xa3139f6b, (q31_t)0x5803133c, (q31_t)0xa30f4d51, (q31_t)0x57fe8335, (q31_t)0xa30afb70, + (q31_t)0x57f9f2f8, (q31_t)0xa306a9c8, (q31_t)0x57f56284, (q31_t)0xa3025859, (q31_t)0x57f0d1da, (q31_t)0xa2fe0724, (q31_t)0x57ec40fa, (q31_t)0xa2f9b629, + (q31_t)0x57e7afe4, (q31_t)0xa2f56566, (q31_t)0x57e31e97, (q31_t)0xa2f114dd, (q31_t)0x57de8d15, (q31_t)0xa2ecc48e, (q31_t)0x57d9fb5c, (q31_t)0xa2e87477, + (q31_t)0x57d5696d, (q31_t)0xa2e4249b, (q31_t)0x57d0d747, (q31_t)0xa2dfd4f7, (q31_t)0x57cc44ec, (q31_t)0xa2db858e, (q31_t)0x57c7b25a, (q31_t)0xa2d7365d, + (q31_t)0x57c31f92, (q31_t)0xa2d2e766, (q31_t)0x57be8c94, (q31_t)0xa2ce98a9, (q31_t)0x57b9f960, (q31_t)0xa2ca4a25, (q31_t)0x57b565f6, (q31_t)0xa2c5fbda, + (q31_t)0x57b0d256, (q31_t)0xa2c1adc9, (q31_t)0x57ac3e80, (q31_t)0xa2bd5ff2, (q31_t)0x57a7aa73, (q31_t)0xa2b91254, (q31_t)0x57a31631, (q31_t)0xa2b4c4f0, + (q31_t)0x579e81b8, (q31_t)0xa2b077c5, (q31_t)0x5799ed0a, (q31_t)0xa2ac2ad3, (q31_t)0x57955825, (q31_t)0xa2a7de1c, (q31_t)0x5790c30a, (q31_t)0xa2a3919e, + (q31_t)0x578c2dba, (q31_t)0xa29f4559, (q31_t)0x57879833, (q31_t)0xa29af94e, (q31_t)0x57830276, (q31_t)0xa296ad7d, (q31_t)0x577e6c84, (q31_t)0xa29261e5, + (q31_t)0x5779d65b, (q31_t)0xa28e1687, (q31_t)0x57753ffc, (q31_t)0xa289cb63, (q31_t)0x5770a968, (q31_t)0xa2858078, (q31_t)0x576c129d, (q31_t)0xa28135c7, + (q31_t)0x57677b9d, (q31_t)0xa27ceb4f, (q31_t)0x5762e467, (q31_t)0xa278a111, (q31_t)0x575e4cfa, (q31_t)0xa274570d, (q31_t)0x5759b558, (q31_t)0xa2700d43, + (q31_t)0x57551d80, (q31_t)0xa26bc3b2, (q31_t)0x57508572, (q31_t)0xa2677a5b, (q31_t)0x574bed2f, (q31_t)0xa263313e, (q31_t)0x574754b5, (q31_t)0xa25ee85b, + (q31_t)0x5742bc06, (q31_t)0xa25a9fb1, (q31_t)0x573e2320, (q31_t)0xa2565741, (q31_t)0x57398a05, (q31_t)0xa2520f0b, (q31_t)0x5734f0b5, (q31_t)0xa24dc70f, + (q31_t)0x5730572e, (q31_t)0xa2497f4c, (q31_t)0x572bbd71, (q31_t)0xa24537c3, (q31_t)0x5727237f, (q31_t)0xa240f074, (q31_t)0x57228957, (q31_t)0xa23ca95f, + (q31_t)0x571deefa, (q31_t)0xa2386284, (q31_t)0x57195466, (q31_t)0xa2341be3, (q31_t)0x5714b99d, (q31_t)0xa22fd57b, (q31_t)0x57101e9e, (q31_t)0xa22b8f4d, + (q31_t)0x570b8369, (q31_t)0xa2274959, (q31_t)0x5706e7ff, (q31_t)0xa223039f, (q31_t)0x57024c5f, (q31_t)0xa21ebe1f, (q31_t)0x56fdb08a, (q31_t)0xa21a78d9, + (q31_t)0x56f9147e, (q31_t)0xa21633cd, (q31_t)0x56f4783d, (q31_t)0xa211eefb, (q31_t)0x56efdbc7, (q31_t)0xa20daa62, (q31_t)0x56eb3f1a, (q31_t)0xa2096604, + (q31_t)0x56e6a239, (q31_t)0xa20521e0, (q31_t)0x56e20521, (q31_t)0xa200ddf5, (q31_t)0x56dd67d4, (q31_t)0xa1fc9a45, (q31_t)0x56d8ca51, (q31_t)0xa1f856ce, + (q31_t)0x56d42c99, (q31_t)0xa1f41392, (q31_t)0x56cf8eab, (q31_t)0xa1efd08f, (q31_t)0x56caf088, (q31_t)0xa1eb8dc7, (q31_t)0x56c6522f, (q31_t)0xa1e74b38, + (q31_t)0x56c1b3a1, (q31_t)0xa1e308e4, (q31_t)0x56bd14dd, (q31_t)0xa1dec6ca, (q31_t)0x56b875e4, (q31_t)0xa1da84e9, (q31_t)0x56b3d6b5, (q31_t)0xa1d64343, + (q31_t)0x56af3750, (q31_t)0xa1d201d7, (q31_t)0x56aa97b7, (q31_t)0xa1cdc0a5, (q31_t)0x56a5f7e7, (q31_t)0xa1c97fad, (q31_t)0x56a157e3, (q31_t)0xa1c53ef0, + (q31_t)0x569cb7a8, (q31_t)0xa1c0fe6c, (q31_t)0x56981739, (q31_t)0xa1bcbe22, (q31_t)0x56937694, (q31_t)0xa1b87e13, (q31_t)0x568ed5b9, (q31_t)0xa1b43e3e, + (q31_t)0x568a34a9, (q31_t)0xa1affea3, (q31_t)0x56859364, (q31_t)0xa1abbf42, (q31_t)0x5680f1ea, (q31_t)0xa1a7801b, (q31_t)0x567c503a, (q31_t)0xa1a3412f, + (q31_t)0x5677ae54, (q31_t)0xa19f027c, (q31_t)0x56730c3a, (q31_t)0xa19ac404, (q31_t)0x566e69ea, (q31_t)0xa19685c7, (q31_t)0x5669c765, (q31_t)0xa19247c3, + (q31_t)0x566524aa, (q31_t)0xa18e09fa, (q31_t)0x566081ba, (q31_t)0xa189cc6b, (q31_t)0x565bde95, (q31_t)0xa1858f16, (q31_t)0x56573b3b, (q31_t)0xa18151fb, + (q31_t)0x565297ab, (q31_t)0xa17d151b, (q31_t)0x564df3e6, (q31_t)0xa178d875, (q31_t)0x56494fec, (q31_t)0xa1749c09, (q31_t)0x5644abbc, (q31_t)0xa1705fd8, + (q31_t)0x56400758, (q31_t)0xa16c23e1, (q31_t)0x563b62be, (q31_t)0xa167e824, (q31_t)0x5636bdef, (q31_t)0xa163aca2, (q31_t)0x563218eb, (q31_t)0xa15f715a, + (q31_t)0x562d73b2, (q31_t)0xa15b364d, (q31_t)0x5628ce43, (q31_t)0xa156fb79, (q31_t)0x5624289f, (q31_t)0xa152c0e1, (q31_t)0x561f82c7, (q31_t)0xa14e8682, + (q31_t)0x561adcb9, (q31_t)0xa14a4c5e, (q31_t)0x56163676, (q31_t)0xa1461275, (q31_t)0x56118ffe, (q31_t)0xa141d8c5, (q31_t)0x560ce950, (q31_t)0xa13d9f51, + (q31_t)0x5608426e, (q31_t)0xa1396617, (q31_t)0x56039b57, (q31_t)0xa1352d17, (q31_t)0x55fef40a, (q31_t)0xa130f451, (q31_t)0x55fa4c89, (q31_t)0xa12cbbc7, + (q31_t)0x55f5a4d2, (q31_t)0xa1288376, (q31_t)0x55f0fce7, (q31_t)0xa1244b61, (q31_t)0x55ec54c6, (q31_t)0xa1201385, (q31_t)0x55e7ac71, (q31_t)0xa11bdbe4, + (q31_t)0x55e303e6, (q31_t)0xa117a47e, (q31_t)0x55de5b27, (q31_t)0xa1136d52, (q31_t)0x55d9b232, (q31_t)0xa10f3661, (q31_t)0x55d50909, (q31_t)0xa10affab, + (q31_t)0x55d05faa, (q31_t)0xa106c92f, (q31_t)0x55cbb617, (q31_t)0xa10292ed, (q31_t)0x55c70c4f, (q31_t)0xa0fe5ce6, (q31_t)0x55c26251, (q31_t)0xa0fa271a, + (q31_t)0x55bdb81f, (q31_t)0xa0f5f189, (q31_t)0x55b90db8, (q31_t)0xa0f1bc32, (q31_t)0x55b4631d, (q31_t)0xa0ed8715, (q31_t)0x55afb84c, (q31_t)0xa0e95234, + (q31_t)0x55ab0d46, (q31_t)0xa0e51d8c, (q31_t)0x55a6620c, (q31_t)0xa0e0e920, (q31_t)0x55a1b69d, (q31_t)0xa0dcb4ee, (q31_t)0x559d0af9, (q31_t)0xa0d880f7, + (q31_t)0x55985f20, (q31_t)0xa0d44d3b, (q31_t)0x5593b312, (q31_t)0xa0d019b9, (q31_t)0x558f06d0, (q31_t)0xa0cbe672, (q31_t)0x558a5a58, (q31_t)0xa0c7b366, + (q31_t)0x5585adad, (q31_t)0xa0c38095, (q31_t)0x558100cc, (q31_t)0xa0bf4dfe, (q31_t)0x557c53b6, (q31_t)0xa0bb1ba2, (q31_t)0x5577a66c, (q31_t)0xa0b6e981, + (q31_t)0x5572f8ed, (q31_t)0xa0b2b79b, (q31_t)0x556e4b39, (q31_t)0xa0ae85ef, (q31_t)0x55699d51, (q31_t)0xa0aa547e, (q31_t)0x5564ef34, (q31_t)0xa0a62348, + (q31_t)0x556040e2, (q31_t)0xa0a1f24d, (q31_t)0x555b925c, (q31_t)0xa09dc18d, (q31_t)0x5556e3a1, (q31_t)0xa0999107, (q31_t)0x555234b1, (q31_t)0xa09560bc, + (q31_t)0x554d858d, (q31_t)0xa09130ad, (q31_t)0x5548d634, (q31_t)0xa08d00d8, (q31_t)0x554426a7, (q31_t)0xa088d13e, (q31_t)0x553f76e4, (q31_t)0xa084a1de, + (q31_t)0x553ac6ee, (q31_t)0xa08072ba, (q31_t)0x553616c2, (q31_t)0xa07c43d1, (q31_t)0x55316663, (q31_t)0xa0781522, (q31_t)0x552cb5ce, (q31_t)0xa073e6af, + (q31_t)0x55280505, (q31_t)0xa06fb876, (q31_t)0x55235408, (q31_t)0xa06b8a78, (q31_t)0x551ea2d6, (q31_t)0xa0675cb6, (q31_t)0x5519f16f, (q31_t)0xa0632f2e, + (q31_t)0x55153fd4, (q31_t)0xa05f01e1, (q31_t)0x55108e05, (q31_t)0xa05ad4cf, (q31_t)0x550bdc01, (q31_t)0xa056a7f9, (q31_t)0x550729c9, (q31_t)0xa0527b5d, + (q31_t)0x5502775c, (q31_t)0xa04e4efc, (q31_t)0x54fdc4ba, (q31_t)0xa04a22d7, (q31_t)0x54f911e5, (q31_t)0xa045f6ec, (q31_t)0x54f45edb, (q31_t)0xa041cb3c, + (q31_t)0x54efab9c, (q31_t)0xa03d9fc8, (q31_t)0x54eaf829, (q31_t)0xa039748e, (q31_t)0x54e64482, (q31_t)0xa0354990, (q31_t)0x54e190a6, (q31_t)0xa0311ecd, + (q31_t)0x54dcdc96, (q31_t)0xa02cf444, (q31_t)0x54d82852, (q31_t)0xa028c9f7, (q31_t)0x54d373d9, (q31_t)0xa0249fe5, (q31_t)0x54cebf2c, (q31_t)0xa020760e, + (q31_t)0x54ca0a4b, (q31_t)0xa01c4c73, (q31_t)0x54c55535, (q31_t)0xa0182312, (q31_t)0x54c09feb, (q31_t)0xa013f9ed, (q31_t)0x54bbea6d, (q31_t)0xa00fd102, + (q31_t)0x54b734ba, (q31_t)0xa00ba853, (q31_t)0x54b27ed3, (q31_t)0xa0077fdf, (q31_t)0x54adc8b8, (q31_t)0xa00357a7, (q31_t)0x54a91269, (q31_t)0x9fff2fa9, + (q31_t)0x54a45be6, (q31_t)0x9ffb07e7, (q31_t)0x549fa52e, (q31_t)0x9ff6e060, (q31_t)0x549aee42, (q31_t)0x9ff2b914, (q31_t)0x54963722, (q31_t)0x9fee9204, + (q31_t)0x54917fce, (q31_t)0x9fea6b2f, (q31_t)0x548cc845, (q31_t)0x9fe64495, (q31_t)0x54881089, (q31_t)0x9fe21e36, (q31_t)0x54835898, (q31_t)0x9fddf812, + (q31_t)0x547ea073, (q31_t)0x9fd9d22a, (q31_t)0x5479e81a, (q31_t)0x9fd5ac7d, (q31_t)0x54752f8d, (q31_t)0x9fd1870c, (q31_t)0x547076cc, (q31_t)0x9fcd61d6, + (q31_t)0x546bbdd7, (q31_t)0x9fc93cdb, (q31_t)0x546704ae, (q31_t)0x9fc5181b, (q31_t)0x54624b50, (q31_t)0x9fc0f397, (q31_t)0x545d91bf, (q31_t)0x9fbccf4f, + (q31_t)0x5458d7f9, (q31_t)0x9fb8ab41, (q31_t)0x54541e00, (q31_t)0x9fb4876f, (q31_t)0x544f63d2, (q31_t)0x9fb063d9, (q31_t)0x544aa971, (q31_t)0x9fac407e, + (q31_t)0x5445eedb, (q31_t)0x9fa81d5e, (q31_t)0x54413412, (q31_t)0x9fa3fa79, (q31_t)0x543c7914, (q31_t)0x9f9fd7d1, (q31_t)0x5437bde3, (q31_t)0x9f9bb563, + (q31_t)0x5433027d, (q31_t)0x9f979331, (q31_t)0x542e46e4, (q31_t)0x9f93713b, (q31_t)0x54298b17, (q31_t)0x9f8f4f80, (q31_t)0x5424cf16, (q31_t)0x9f8b2e00, + (q31_t)0x542012e1, (q31_t)0x9f870cbc, (q31_t)0x541b5678, (q31_t)0x9f82ebb4, (q31_t)0x541699db, (q31_t)0x9f7ecae7, (q31_t)0x5411dd0a, (q31_t)0x9f7aaa55, + (q31_t)0x540d2005, (q31_t)0x9f7689ff, (q31_t)0x540862cd, (q31_t)0x9f7269e5, (q31_t)0x5403a561, (q31_t)0x9f6e4a06, (q31_t)0x53fee7c1, (q31_t)0x9f6a2a63, + (q31_t)0x53fa29ed, (q31_t)0x9f660afb, (q31_t)0x53f56be5, (q31_t)0x9f61ebcf, (q31_t)0x53f0adaa, (q31_t)0x9f5dccde, (q31_t)0x53ebef3a, (q31_t)0x9f59ae29, + (q31_t)0x53e73097, (q31_t)0x9f558fb0, (q31_t)0x53e271c0, (q31_t)0x9f517173, (q31_t)0x53ddb2b6, (q31_t)0x9f4d5371, (q31_t)0x53d8f378, (q31_t)0x9f4935aa, + (q31_t)0x53d43406, (q31_t)0x9f45181f, (q31_t)0x53cf7460, (q31_t)0x9f40fad0, (q31_t)0x53cab486, (q31_t)0x9f3cddbd, (q31_t)0x53c5f479, (q31_t)0x9f38c0e5, + (q31_t)0x53c13439, (q31_t)0x9f34a449, (q31_t)0x53bc73c4, (q31_t)0x9f3087e9, (q31_t)0x53b7b31c, (q31_t)0x9f2c6bc5, (q31_t)0x53b2f240, (q31_t)0x9f284fdc, + (q31_t)0x53ae3131, (q31_t)0x9f24342f, (q31_t)0x53a96fee, (q31_t)0x9f2018bd, (q31_t)0x53a4ae77, (q31_t)0x9f1bfd88, (q31_t)0x539feccd, (q31_t)0x9f17e28e, + (q31_t)0x539b2af0, (q31_t)0x9f13c7d0, (q31_t)0x539668de, (q31_t)0x9f0fad4e, (q31_t)0x5391a699, (q31_t)0x9f0b9307, (q31_t)0x538ce421, (q31_t)0x9f0778fd, + (q31_t)0x53882175, (q31_t)0x9f035f2e, (q31_t)0x53835e95, (q31_t)0x9eff459b, (q31_t)0x537e9b82, (q31_t)0x9efb2c44, (q31_t)0x5379d83c, (q31_t)0x9ef71328, + (q31_t)0x537514c2, (q31_t)0x9ef2fa49, (q31_t)0x53705114, (q31_t)0x9eeee1a5, (q31_t)0x536b8d33, (q31_t)0x9eeac93e, (q31_t)0x5366c91f, (q31_t)0x9ee6b112, + (q31_t)0x536204d7, (q31_t)0x9ee29922, (q31_t)0x535d405c, (q31_t)0x9ede816e, (q31_t)0x53587bad, (q31_t)0x9eda69f6, (q31_t)0x5353b6cb, (q31_t)0x9ed652ba, + (q31_t)0x534ef1b5, (q31_t)0x9ed23bb9, (q31_t)0x534a2c6c, (q31_t)0x9ece24f5, (q31_t)0x534566f0, (q31_t)0x9eca0e6d, (q31_t)0x5340a140, (q31_t)0x9ec5f820, + (q31_t)0x533bdb5d, (q31_t)0x9ec1e210, (q31_t)0x53371547, (q31_t)0x9ebdcc3b, (q31_t)0x53324efd, (q31_t)0x9eb9b6a3, (q31_t)0x532d8880, (q31_t)0x9eb5a146, + (q31_t)0x5328c1d0, (q31_t)0x9eb18c26, (q31_t)0x5323faec, (q31_t)0x9ead7742, (q31_t)0x531f33d5, (q31_t)0x9ea96299, (q31_t)0x531a6c8b, (q31_t)0x9ea54e2d, + (q31_t)0x5315a50e, (q31_t)0x9ea139fd, (q31_t)0x5310dd5d, (q31_t)0x9e9d2608, (q31_t)0x530c1579, (q31_t)0x9e991250, (q31_t)0x53074d62, (q31_t)0x9e94fed4, + (q31_t)0x53028518, (q31_t)0x9e90eb94, (q31_t)0x52fdbc9a, (q31_t)0x9e8cd890, (q31_t)0x52f8f3e9, (q31_t)0x9e88c5c9, (q31_t)0x52f42b05, (q31_t)0x9e84b33d, + (q31_t)0x52ef61ee, (q31_t)0x9e80a0ee, (q31_t)0x52ea98a4, (q31_t)0x9e7c8eda, (q31_t)0x52e5cf27, (q31_t)0x9e787d03, (q31_t)0x52e10576, (q31_t)0x9e746b68, + (q31_t)0x52dc3b92, (q31_t)0x9e705a09, (q31_t)0x52d7717b, (q31_t)0x9e6c48e7, (q31_t)0x52d2a732, (q31_t)0x9e683800, (q31_t)0x52cddcb5, (q31_t)0x9e642756, + (q31_t)0x52c91204, (q31_t)0x9e6016e8, (q31_t)0x52c44721, (q31_t)0x9e5c06b6, (q31_t)0x52bf7c0b, (q31_t)0x9e57f6c0, (q31_t)0x52bab0c2, (q31_t)0x9e53e707, + (q31_t)0x52b5e546, (q31_t)0x9e4fd78a, (q31_t)0x52b11996, (q31_t)0x9e4bc849, (q31_t)0x52ac4db4, (q31_t)0x9e47b944, (q31_t)0x52a7819f, (q31_t)0x9e43aa7c, + (q31_t)0x52a2b556, (q31_t)0x9e3f9bf0, (q31_t)0x529de8db, (q31_t)0x9e3b8da0, (q31_t)0x52991c2d, (q31_t)0x9e377f8c, (q31_t)0x52944f4c, (q31_t)0x9e3371b5, + (q31_t)0x528f8238, (q31_t)0x9e2f641b, (q31_t)0x528ab4f1, (q31_t)0x9e2b56bc, (q31_t)0x5285e777, (q31_t)0x9e27499a, (q31_t)0x528119ca, (q31_t)0x9e233cb4, + (q31_t)0x527c4bea, (q31_t)0x9e1f300b, (q31_t)0x52777dd7, (q31_t)0x9e1b239e, (q31_t)0x5272af92, (q31_t)0x9e17176d, (q31_t)0x526de11a, (q31_t)0x9e130b79, + (q31_t)0x5269126e, (q31_t)0x9e0effc1, (q31_t)0x52644390, (q31_t)0x9e0af446, (q31_t)0x525f7480, (q31_t)0x9e06e907, (q31_t)0x525aa53c, (q31_t)0x9e02de04, + (q31_t)0x5255d5c5, (q31_t)0x9dfed33e, (q31_t)0x5251061c, (q31_t)0x9dfac8b4, (q31_t)0x524c3640, (q31_t)0x9df6be67, (q31_t)0x52476631, (q31_t)0x9df2b456, + (q31_t)0x524295f0, (q31_t)0x9deeaa82, (q31_t)0x523dc57b, (q31_t)0x9deaa0ea, (q31_t)0x5238f4d4, (q31_t)0x9de6978f, (q31_t)0x523423fb, (q31_t)0x9de28e70, + (q31_t)0x522f52ee, (q31_t)0x9dde858e, (q31_t)0x522a81af, (q31_t)0x9dda7ce9, (q31_t)0x5225b03d, (q31_t)0x9dd6747f, (q31_t)0x5220de99, (q31_t)0x9dd26c53, + (q31_t)0x521c0cc2, (q31_t)0x9dce6463, (q31_t)0x52173ab8, (q31_t)0x9dca5caf, (q31_t)0x5212687b, (q31_t)0x9dc65539, (q31_t)0x520d960c, (q31_t)0x9dc24dfe, + (q31_t)0x5208c36a, (q31_t)0x9dbe4701, (q31_t)0x5203f096, (q31_t)0x9dba4040, (q31_t)0x51ff1d8f, (q31_t)0x9db639bb, (q31_t)0x51fa4a56, (q31_t)0x9db23373, + (q31_t)0x51f576ea, (q31_t)0x9dae2d68, (q31_t)0x51f0a34b, (q31_t)0x9daa279a, (q31_t)0x51ebcf7a, (q31_t)0x9da62208, (q31_t)0x51e6fb76, (q31_t)0x9da21cb2, + (q31_t)0x51e22740, (q31_t)0x9d9e179a, (q31_t)0x51dd52d7, (q31_t)0x9d9a12be, (q31_t)0x51d87e3c, (q31_t)0x9d960e1f, (q31_t)0x51d3a96f, (q31_t)0x9d9209bd, + (q31_t)0x51ced46e, (q31_t)0x9d8e0597, (q31_t)0x51c9ff3c, (q31_t)0x9d8a01ae, (q31_t)0x51c529d7, (q31_t)0x9d85fe02, (q31_t)0x51c0543f, (q31_t)0x9d81fa92, + (q31_t)0x51bb7e75, (q31_t)0x9d7df75f, (q31_t)0x51b6a879, (q31_t)0x9d79f469, (q31_t)0x51b1d24a, (q31_t)0x9d75f1b0, (q31_t)0x51acfbe9, (q31_t)0x9d71ef34, + (q31_t)0x51a82555, (q31_t)0x9d6decf4, (q31_t)0x51a34e8f, (q31_t)0x9d69eaf1, (q31_t)0x519e7797, (q31_t)0x9d65e92b, (q31_t)0x5199a06d, (q31_t)0x9d61e7a2, + (q31_t)0x5194c910, (q31_t)0x9d5de656, (q31_t)0x518ff180, (q31_t)0x9d59e546, (q31_t)0x518b19bf, (q31_t)0x9d55e473, (q31_t)0x518641cb, (q31_t)0x9d51e3dd, + (q31_t)0x518169a5, (q31_t)0x9d4de385, (q31_t)0x517c914c, (q31_t)0x9d49e368, (q31_t)0x5177b8c2, (q31_t)0x9d45e389, (q31_t)0x5172e005, (q31_t)0x9d41e3e7, + (q31_t)0x516e0715, (q31_t)0x9d3de482, (q31_t)0x51692df4, (q31_t)0x9d39e559, (q31_t)0x516454a0, (q31_t)0x9d35e66e, (q31_t)0x515f7b1a, (q31_t)0x9d31e7bf, + (q31_t)0x515aa162, (q31_t)0x9d2de94d, (q31_t)0x5155c778, (q31_t)0x9d29eb19, (q31_t)0x5150ed5c, (q31_t)0x9d25ed21, (q31_t)0x514c130d, (q31_t)0x9d21ef66, + (q31_t)0x5147388c, (q31_t)0x9d1df1e9, (q31_t)0x51425dd9, (q31_t)0x9d19f4a8, (q31_t)0x513d82f4, (q31_t)0x9d15f7a4, (q31_t)0x5138a7dd, (q31_t)0x9d11fadd, + (q31_t)0x5133cc94, (q31_t)0x9d0dfe54, (q31_t)0x512ef119, (q31_t)0x9d0a0207, (q31_t)0x512a156b, (q31_t)0x9d0605f7, (q31_t)0x5125398c, (q31_t)0x9d020a25, + (q31_t)0x51205d7b, (q31_t)0x9cfe0e8f, (q31_t)0x511b8137, (q31_t)0x9cfa1337, (q31_t)0x5116a4c1, (q31_t)0x9cf6181c, (q31_t)0x5111c81a, (q31_t)0x9cf21d3d, + (q31_t)0x510ceb40, (q31_t)0x9cee229c, (q31_t)0x51080e35, (q31_t)0x9cea2838, (q31_t)0x510330f7, (q31_t)0x9ce62e11, (q31_t)0x50fe5388, (q31_t)0x9ce23427, + (q31_t)0x50f975e6, (q31_t)0x9cde3a7b, (q31_t)0x50f49813, (q31_t)0x9cda410b, (q31_t)0x50efba0d, (q31_t)0x9cd647d9, (q31_t)0x50eadbd6, (q31_t)0x9cd24ee4, + (q31_t)0x50e5fd6d, (q31_t)0x9cce562c, (q31_t)0x50e11ed2, (q31_t)0x9cca5db1, (q31_t)0x50dc4005, (q31_t)0x9cc66573, (q31_t)0x50d76106, (q31_t)0x9cc26d73, + (q31_t)0x50d281d5, (q31_t)0x9cbe75b0, (q31_t)0x50cda272, (q31_t)0x9cba7e2a, (q31_t)0x50c8c2de, (q31_t)0x9cb686e1, (q31_t)0x50c3e317, (q31_t)0x9cb28fd5, + (q31_t)0x50bf031f, (q31_t)0x9cae9907, (q31_t)0x50ba22f5, (q31_t)0x9caaa276, (q31_t)0x50b5429a, (q31_t)0x9ca6ac23, (q31_t)0x50b0620c, (q31_t)0x9ca2b60c, + (q31_t)0x50ab814d, (q31_t)0x9c9ec033, (q31_t)0x50a6a05c, (q31_t)0x9c9aca97, (q31_t)0x50a1bf39, (q31_t)0x9c96d539, (q31_t)0x509cdde4, (q31_t)0x9c92e017, + (q31_t)0x5097fc5e, (q31_t)0x9c8eeb34, (q31_t)0x50931aa6, (q31_t)0x9c8af68d, (q31_t)0x508e38bd, (q31_t)0x9c870224, (q31_t)0x508956a1, (q31_t)0x9c830df8, + (q31_t)0x50847454, (q31_t)0x9c7f1a0a, (q31_t)0x507f91d5, (q31_t)0x9c7b2659, (q31_t)0x507aaf25, (q31_t)0x9c7732e5, (q31_t)0x5075cc43, (q31_t)0x9c733faf, + (q31_t)0x5070e92f, (q31_t)0x9c6f4cb6, (q31_t)0x506c05ea, (q31_t)0x9c6b59fa, (q31_t)0x50672273, (q31_t)0x9c67677c, (q31_t)0x50623ecb, (q31_t)0x9c63753c, + (q31_t)0x505d5af1, (q31_t)0x9c5f8339, (q31_t)0x505876e5, (q31_t)0x9c5b9173, (q31_t)0x505392a8, (q31_t)0x9c579feb, (q31_t)0x504eae39, (q31_t)0x9c53aea0, + (q31_t)0x5049c999, (q31_t)0x9c4fbd93, (q31_t)0x5044e4c7, (q31_t)0x9c4bccc3, (q31_t)0x503fffc4, (q31_t)0x9c47dc31, (q31_t)0x503b1a8f, (q31_t)0x9c43ebdc, + (q31_t)0x50363529, (q31_t)0x9c3ffbc5, (q31_t)0x50314f91, (q31_t)0x9c3c0beb, (q31_t)0x502c69c8, (q31_t)0x9c381c4f, (q31_t)0x502783cd, (q31_t)0x9c342cf0, + (q31_t)0x50229da1, (q31_t)0x9c303dcf, (q31_t)0x501db743, (q31_t)0x9c2c4eec, (q31_t)0x5018d0b4, (q31_t)0x9c286046, (q31_t)0x5013e9f4, (q31_t)0x9c2471de, + (q31_t)0x500f0302, (q31_t)0x9c2083b3, (q31_t)0x500a1bdf, (q31_t)0x9c1c95c6, (q31_t)0x5005348a, (q31_t)0x9c18a816, (q31_t)0x50004d04, (q31_t)0x9c14baa4, + (q31_t)0x4ffb654d, (q31_t)0x9c10cd70, (q31_t)0x4ff67d64, (q31_t)0x9c0ce07a, (q31_t)0x4ff1954b, (q31_t)0x9c08f3c1, (q31_t)0x4fecacff, (q31_t)0x9c050745, + (q31_t)0x4fe7c483, (q31_t)0x9c011b08, (q31_t)0x4fe2dbd5, (q31_t)0x9bfd2f08, (q31_t)0x4fddf2f6, (q31_t)0x9bf94346, (q31_t)0x4fd909e5, (q31_t)0x9bf557c1, + (q31_t)0x4fd420a4, (q31_t)0x9bf16c7a, (q31_t)0x4fcf3731, (q31_t)0x9bed8171, (q31_t)0x4fca4d8d, (q31_t)0x9be996a6, (q31_t)0x4fc563b7, (q31_t)0x9be5ac18, + (q31_t)0x4fc079b1, (q31_t)0x9be1c1c8, (q31_t)0x4fbb8f79, (q31_t)0x9bddd7b6, (q31_t)0x4fb6a510, (q31_t)0x9bd9ede2, (q31_t)0x4fb1ba76, (q31_t)0x9bd6044b, + (q31_t)0x4faccfab, (q31_t)0x9bd21af3, (q31_t)0x4fa7e4af, (q31_t)0x9bce31d8, (q31_t)0x4fa2f981, (q31_t)0x9bca48fa, (q31_t)0x4f9e0e22, (q31_t)0x9bc6605b, + (q31_t)0x4f992293, (q31_t)0x9bc277fa, (q31_t)0x4f9436d2, (q31_t)0x9bbe8fd6, (q31_t)0x4f8f4ae0, (q31_t)0x9bbaa7f0, (q31_t)0x4f8a5ebd, (q31_t)0x9bb6c048, + (q31_t)0x4f857269, (q31_t)0x9bb2d8de, (q31_t)0x4f8085e4, (q31_t)0x9baef1b2, (q31_t)0x4f7b992d, (q31_t)0x9bab0ac3, (q31_t)0x4f76ac46, (q31_t)0x9ba72413, + (q31_t)0x4f71bf2e, (q31_t)0x9ba33da0, (q31_t)0x4f6cd1e5, (q31_t)0x9b9f576b, (q31_t)0x4f67e46a, (q31_t)0x9b9b7174, (q31_t)0x4f62f6bf, (q31_t)0x9b978bbc, + (q31_t)0x4f5e08e3, (q31_t)0x9b93a641, (q31_t)0x4f591ad6, (q31_t)0x9b8fc104, (q31_t)0x4f542c98, (q31_t)0x9b8bdc05, (q31_t)0x4f4f3e29, (q31_t)0x9b87f744, + (q31_t)0x4f4a4f89, (q31_t)0x9b8412c1, (q31_t)0x4f4560b8, (q31_t)0x9b802e7b, (q31_t)0x4f4071b6, (q31_t)0x9b7c4a74, (q31_t)0x4f3b8284, (q31_t)0x9b7866ab, + (q31_t)0x4f369320, (q31_t)0x9b748320, (q31_t)0x4f31a38c, (q31_t)0x9b709fd3, (q31_t)0x4f2cb3c7, (q31_t)0x9b6cbcc4, (q31_t)0x4f27c3d1, (q31_t)0x9b68d9f3, + (q31_t)0x4f22d3aa, (q31_t)0x9b64f760, (q31_t)0x4f1de352, (q31_t)0x9b61150b, (q31_t)0x4f18f2c9, (q31_t)0x9b5d32f4, (q31_t)0x4f140210, (q31_t)0x9b59511c, + (q31_t)0x4f0f1126, (q31_t)0x9b556f81, (q31_t)0x4f0a200b, (q31_t)0x9b518e24, (q31_t)0x4f052ec0, (q31_t)0x9b4dad06, (q31_t)0x4f003d43, (q31_t)0x9b49cc26, + (q31_t)0x4efb4b96, (q31_t)0x9b45eb83, (q31_t)0x4ef659b8, (q31_t)0x9b420b1f, (q31_t)0x4ef167aa, (q31_t)0x9b3e2af9, (q31_t)0x4eec756b, (q31_t)0x9b3a4b11, + (q31_t)0x4ee782fb, (q31_t)0x9b366b68, (q31_t)0x4ee2905a, (q31_t)0x9b328bfc, (q31_t)0x4edd9d89, (q31_t)0x9b2eaccf, (q31_t)0x4ed8aa87, (q31_t)0x9b2acde0, + (q31_t)0x4ed3b755, (q31_t)0x9b26ef2f, (q31_t)0x4ecec3f2, (q31_t)0x9b2310bc, (q31_t)0x4ec9d05e, (q31_t)0x9b1f3288, (q31_t)0x4ec4dc99, (q31_t)0x9b1b5492, + (q31_t)0x4ebfe8a5, (q31_t)0x9b1776da, (q31_t)0x4ebaf47f, (q31_t)0x9b139960, (q31_t)0x4eb60029, (q31_t)0x9b0fbc24, (q31_t)0x4eb10ba2, (q31_t)0x9b0bdf27, + (q31_t)0x4eac16eb, (q31_t)0x9b080268, (q31_t)0x4ea72203, (q31_t)0x9b0425e8, (q31_t)0x4ea22ceb, (q31_t)0x9b0049a5, (q31_t)0x4e9d37a3, (q31_t)0x9afc6da1, + (q31_t)0x4e984229, (q31_t)0x9af891db, (q31_t)0x4e934c80, (q31_t)0x9af4b654, (q31_t)0x4e8e56a5, (q31_t)0x9af0db0b, (q31_t)0x4e89609b, (q31_t)0x9aed0000, + (q31_t)0x4e846a60, (q31_t)0x9ae92533, (q31_t)0x4e7f73f4, (q31_t)0x9ae54aa5, (q31_t)0x4e7a7d58, (q31_t)0x9ae17056, (q31_t)0x4e75868c, (q31_t)0x9add9644, + (q31_t)0x4e708f8f, (q31_t)0x9ad9bc71, (q31_t)0x4e6b9862, (q31_t)0x9ad5e2dd, (q31_t)0x4e66a105, (q31_t)0x9ad20987, (q31_t)0x4e61a977, (q31_t)0x9ace306f, + (q31_t)0x4e5cb1b9, (q31_t)0x9aca5795, (q31_t)0x4e57b9ca, (q31_t)0x9ac67efb, (q31_t)0x4e52c1ab, (q31_t)0x9ac2a69e, (q31_t)0x4e4dc95c, (q31_t)0x9abece80, + (q31_t)0x4e48d0dd, (q31_t)0x9abaf6a1, (q31_t)0x4e43d82d, (q31_t)0x9ab71eff, (q31_t)0x4e3edf4d, (q31_t)0x9ab3479d, (q31_t)0x4e39e63d, (q31_t)0x9aaf7079, + (q31_t)0x4e34ecfc, (q31_t)0x9aab9993, (q31_t)0x4e2ff38b, (q31_t)0x9aa7c2ec, (q31_t)0x4e2af9ea, (q31_t)0x9aa3ec83, (q31_t)0x4e260019, (q31_t)0x9aa01659, + (q31_t)0x4e210617, (q31_t)0x9a9c406e, (q31_t)0x4e1c0be6, (q31_t)0x9a986ac1, (q31_t)0x4e171184, (q31_t)0x9a949552, (q31_t)0x4e1216f2, (q31_t)0x9a90c022, + (q31_t)0x4e0d1c30, (q31_t)0x9a8ceb31, (q31_t)0x4e08213e, (q31_t)0x9a89167e, (q31_t)0x4e03261b, (q31_t)0x9a85420a, (q31_t)0x4dfe2ac9, (q31_t)0x9a816dd5, + (q31_t)0x4df92f46, (q31_t)0x9a7d99de, (q31_t)0x4df43393, (q31_t)0x9a79c625, (q31_t)0x4def37b0, (q31_t)0x9a75f2ac, (q31_t)0x4dea3b9d, (q31_t)0x9a721f71, + (q31_t)0x4de53f5a, (q31_t)0x9a6e4c74, (q31_t)0x4de042e7, (q31_t)0x9a6a79b6, (q31_t)0x4ddb4644, (q31_t)0x9a66a737, (q31_t)0x4dd64971, (q31_t)0x9a62d4f7, + (q31_t)0x4dd14c6e, (q31_t)0x9a5f02f5, (q31_t)0x4dcc4f3b, (q31_t)0x9a5b3132, (q31_t)0x4dc751d8, (q31_t)0x9a575fae, (q31_t)0x4dc25445, (q31_t)0x9a538e68, + (q31_t)0x4dbd5682, (q31_t)0x9a4fbd61, (q31_t)0x4db8588f, (q31_t)0x9a4bec99, (q31_t)0x4db35a6c, (q31_t)0x9a481c0f, (q31_t)0x4dae5c19, (q31_t)0x9a444bc5, + (q31_t)0x4da95d96, (q31_t)0x9a407bb9, (q31_t)0x4da45ee3, (q31_t)0x9a3cabeb, (q31_t)0x4d9f6001, (q31_t)0x9a38dc5d, (q31_t)0x4d9a60ee, (q31_t)0x9a350d0d, + (q31_t)0x4d9561ac, (q31_t)0x9a313dfc, (q31_t)0x4d90623a, (q31_t)0x9a2d6f2a, (q31_t)0x4d8b6298, (q31_t)0x9a29a097, (q31_t)0x4d8662c6, (q31_t)0x9a25d243, + (q31_t)0x4d8162c4, (q31_t)0x9a22042d, (q31_t)0x4d7c6293, (q31_t)0x9a1e3656, (q31_t)0x4d776231, (q31_t)0x9a1a68be, (q31_t)0x4d7261a0, (q31_t)0x9a169b65, + (q31_t)0x4d6d60df, (q31_t)0x9a12ce4b, (q31_t)0x4d685fef, (q31_t)0x9a0f016f, (q31_t)0x4d635ece, (q31_t)0x9a0b34d3, (q31_t)0x4d5e5d7e, (q31_t)0x9a076875, + (q31_t)0x4d595bfe, (q31_t)0x9a039c57, (q31_t)0x4d545a4f, (q31_t)0x99ffd077, (q31_t)0x4d4f5870, (q31_t)0x99fc04d6, (q31_t)0x4d4a5661, (q31_t)0x99f83974, + (q31_t)0x4d455422, (q31_t)0x99f46e51, (q31_t)0x4d4051b4, (q31_t)0x99f0a36d, (q31_t)0x4d3b4f16, (q31_t)0x99ecd8c8, (q31_t)0x4d364c48, (q31_t)0x99e90e62, + (q31_t)0x4d31494b, (q31_t)0x99e5443b, (q31_t)0x4d2c461e, (q31_t)0x99e17a53, (q31_t)0x4d2742c2, (q31_t)0x99ddb0aa, (q31_t)0x4d223f36, (q31_t)0x99d9e73f, + (q31_t)0x4d1d3b7a, (q31_t)0x99d61e14, (q31_t)0x4d18378f, (q31_t)0x99d25528, (q31_t)0x4d133374, (q31_t)0x99ce8c7b, (q31_t)0x4d0e2f2a, (q31_t)0x99cac40d, + (q31_t)0x4d092ab0, (q31_t)0x99c6fbde, (q31_t)0x4d042607, (q31_t)0x99c333ee, (q31_t)0x4cff212e, (q31_t)0x99bf6c3d, (q31_t)0x4cfa1c26, (q31_t)0x99bba4cb, + (q31_t)0x4cf516ee, (q31_t)0x99b7dd99, (q31_t)0x4cf01187, (q31_t)0x99b416a5, (q31_t)0x4ceb0bf0, (q31_t)0x99b04ff0, (q31_t)0x4ce6062a, (q31_t)0x99ac897b, + (q31_t)0x4ce10034, (q31_t)0x99a8c345, (q31_t)0x4cdbfa0f, (q31_t)0x99a4fd4d, (q31_t)0x4cd6f3bb, (q31_t)0x99a13795, (q31_t)0x4cd1ed37, (q31_t)0x999d721c, + (q31_t)0x4ccce684, (q31_t)0x9999ace3, (q31_t)0x4cc7dfa1, (q31_t)0x9995e7e8, (q31_t)0x4cc2d88f, (q31_t)0x9992232d, (q31_t)0x4cbdd14e, (q31_t)0x998e5eb1, + (q31_t)0x4cb8c9dd, (q31_t)0x998a9a74, (q31_t)0x4cb3c23d, (q31_t)0x9986d676, (q31_t)0x4caeba6e, (q31_t)0x998312b7, (q31_t)0x4ca9b26f, (q31_t)0x997f4f38, + (q31_t)0x4ca4aa41, (q31_t)0x997b8bf8, (q31_t)0x4c9fa1e4, (q31_t)0x9977c8f7, (q31_t)0x4c9a9958, (q31_t)0x99740635, (q31_t)0x4c95909c, (q31_t)0x997043b2, + (q31_t)0x4c9087b1, (q31_t)0x996c816f, (q31_t)0x4c8b7e97, (q31_t)0x9968bf6b, (q31_t)0x4c86754e, (q31_t)0x9964fda7, (q31_t)0x4c816bd5, (q31_t)0x99613c22, + (q31_t)0x4c7c622d, (q31_t)0x995d7adc, (q31_t)0x4c775856, (q31_t)0x9959b9d5, (q31_t)0x4c724e50, (q31_t)0x9955f90d, (q31_t)0x4c6d441b, (q31_t)0x99523885, + (q31_t)0x4c6839b7, (q31_t)0x994e783d, (q31_t)0x4c632f23, (q31_t)0x994ab833, (q31_t)0x4c5e2460, (q31_t)0x9946f869, (q31_t)0x4c59196f, (q31_t)0x994338df, + (q31_t)0x4c540e4e, (q31_t)0x993f7993, (q31_t)0x4c4f02fe, (q31_t)0x993bba87, (q31_t)0x4c49f77f, (q31_t)0x9937fbbb, (q31_t)0x4c44ebd1, (q31_t)0x99343d2e, + (q31_t)0x4c3fdff4, (q31_t)0x99307ee0, (q31_t)0x4c3ad3e7, (q31_t)0x992cc0d2, (q31_t)0x4c35c7ac, (q31_t)0x99290303, (q31_t)0x4c30bb42, (q31_t)0x99254574, + (q31_t)0x4c2baea9, (q31_t)0x99218824, (q31_t)0x4c26a1e1, (q31_t)0x991dcb13, (q31_t)0x4c2194e9, (q31_t)0x991a0e42, (q31_t)0x4c1c87c3, (q31_t)0x991651b1, + (q31_t)0x4c177a6e, (q31_t)0x9912955f, (q31_t)0x4c126cea, (q31_t)0x990ed94c, (q31_t)0x4c0d5f37, (q31_t)0x990b1d79, (q31_t)0x4c085156, (q31_t)0x990761e5, + (q31_t)0x4c034345, (q31_t)0x9903a691, (q31_t)0x4bfe3505, (q31_t)0x98ffeb7d, (q31_t)0x4bf92697, (q31_t)0x98fc30a8, (q31_t)0x4bf417f9, (q31_t)0x98f87612, + (q31_t)0x4bef092d, (q31_t)0x98f4bbbc, (q31_t)0x4be9fa32, (q31_t)0x98f101a6, (q31_t)0x4be4eb08, (q31_t)0x98ed47cf, (q31_t)0x4bdfdbaf, (q31_t)0x98e98e38, + (q31_t)0x4bdacc28, (q31_t)0x98e5d4e0, (q31_t)0x4bd5bc72, (q31_t)0x98e21bc8, (q31_t)0x4bd0ac8d, (q31_t)0x98de62f0, (q31_t)0x4bcb9c79, (q31_t)0x98daaa57, + (q31_t)0x4bc68c36, (q31_t)0x98d6f1fe, (q31_t)0x4bc17bc5, (q31_t)0x98d339e4, (q31_t)0x4bbc6b25, (q31_t)0x98cf820b, (q31_t)0x4bb75a56, (q31_t)0x98cbca70, + (q31_t)0x4bb24958, (q31_t)0x98c81316, (q31_t)0x4bad382c, (q31_t)0x98c45bfb, (q31_t)0x4ba826d1, (q31_t)0x98c0a520, (q31_t)0x4ba31548, (q31_t)0x98bcee84, + (q31_t)0x4b9e0390, (q31_t)0x98b93828, (q31_t)0x4b98f1a9, (q31_t)0x98b5820c, (q31_t)0x4b93df93, (q31_t)0x98b1cc30, (q31_t)0x4b8ecd4f, (q31_t)0x98ae1693, + (q31_t)0x4b89badd, (q31_t)0x98aa6136, (q31_t)0x4b84a83b, (q31_t)0x98a6ac19, (q31_t)0x4b7f956b, (q31_t)0x98a2f73c, (q31_t)0x4b7a826d, (q31_t)0x989f429e, + (q31_t)0x4b756f40, (q31_t)0x989b8e40, (q31_t)0x4b705be4, (q31_t)0x9897da22, (q31_t)0x4b6b485a, (q31_t)0x98942643, (q31_t)0x4b6634a2, (q31_t)0x989072a5, + (q31_t)0x4b6120bb, (q31_t)0x988cbf46, (q31_t)0x4b5c0ca5, (q31_t)0x98890c27, (q31_t)0x4b56f861, (q31_t)0x98855948, (q31_t)0x4b51e3ee, (q31_t)0x9881a6a9, + (q31_t)0x4b4ccf4d, (q31_t)0x987df449, (q31_t)0x4b47ba7e, (q31_t)0x987a422a, (q31_t)0x4b42a580, (q31_t)0x9876904a, (q31_t)0x4b3d9053, (q31_t)0x9872deaa, + (q31_t)0x4b387af9, (q31_t)0x986f2d4a, (q31_t)0x4b336570, (q31_t)0x986b7c2a, (q31_t)0x4b2e4fb8, (q31_t)0x9867cb4a, (q31_t)0x4b2939d2, (q31_t)0x98641aa9, + (q31_t)0x4b2423be, (q31_t)0x98606a49, (q31_t)0x4b1f0d7b, (q31_t)0x985cba28, (q31_t)0x4b19f70a, (q31_t)0x98590a48, (q31_t)0x4b14e06b, (q31_t)0x98555aa7, + (q31_t)0x4b0fc99d, (q31_t)0x9851ab46, (q31_t)0x4b0ab2a1, (q31_t)0x984dfc26, (q31_t)0x4b059b77, (q31_t)0x984a4d45, (q31_t)0x4b00841f, (q31_t)0x98469ea4, + (q31_t)0x4afb6c98, (q31_t)0x9842f043, (q31_t)0x4af654e3, (q31_t)0x983f4223, (q31_t)0x4af13d00, (q31_t)0x983b9442, (q31_t)0x4aec24ee, (q31_t)0x9837e6a1, + (q31_t)0x4ae70caf, (q31_t)0x98343940, (q31_t)0x4ae1f441, (q31_t)0x98308c1f, (q31_t)0x4adcdba5, (q31_t)0x982cdf3f, (q31_t)0x4ad7c2da, (q31_t)0x9829329e, + (q31_t)0x4ad2a9e2, (q31_t)0x9825863d, (q31_t)0x4acd90bb, (q31_t)0x9821da1d, (q31_t)0x4ac87767, (q31_t)0x981e2e3c, (q31_t)0x4ac35de4, (q31_t)0x981a829c, + (q31_t)0x4abe4433, (q31_t)0x9816d73b, (q31_t)0x4ab92a54, (q31_t)0x98132c1b, (q31_t)0x4ab41046, (q31_t)0x980f813b, (q31_t)0x4aaef60b, (q31_t)0x980bd69b, + (q31_t)0x4aa9dba2, (q31_t)0x98082c3b, (q31_t)0x4aa4c10b, (q31_t)0x9804821b, (q31_t)0x4a9fa645, (q31_t)0x9800d83c, (q31_t)0x4a9a8b52, (q31_t)0x97fd2e9c, + (q31_t)0x4a957030, (q31_t)0x97f9853d, (q31_t)0x4a9054e1, (q31_t)0x97f5dc1e, (q31_t)0x4a8b3963, (q31_t)0x97f2333f, (q31_t)0x4a861db8, (q31_t)0x97ee8aa0, + (q31_t)0x4a8101de, (q31_t)0x97eae242, (q31_t)0x4a7be5d7, (q31_t)0x97e73a23, (q31_t)0x4a76c9a2, (q31_t)0x97e39245, (q31_t)0x4a71ad3e, (q31_t)0x97dfeaa7, + (q31_t)0x4a6c90ad, (q31_t)0x97dc4349, (q31_t)0x4a6773ee, (q31_t)0x97d89c2c, (q31_t)0x4a625701, (q31_t)0x97d4f54f, (q31_t)0x4a5d39e6, (q31_t)0x97d14eb2, + (q31_t)0x4a581c9e, (q31_t)0x97cda855, (q31_t)0x4a52ff27, (q31_t)0x97ca0239, (q31_t)0x4a4de182, (q31_t)0x97c65c5c, (q31_t)0x4a48c3b0, (q31_t)0x97c2b6c1, + (q31_t)0x4a43a5b0, (q31_t)0x97bf1165, (q31_t)0x4a3e8782, (q31_t)0x97bb6c4a, (q31_t)0x4a396926, (q31_t)0x97b7c76f, (q31_t)0x4a344a9d, (q31_t)0x97b422d4, + (q31_t)0x4a2f2be6, (q31_t)0x97b07e7a, (q31_t)0x4a2a0d01, (q31_t)0x97acda60, (q31_t)0x4a24edee, (q31_t)0x97a93687, (q31_t)0x4a1fcead, (q31_t)0x97a592ed, + (q31_t)0x4a1aaf3f, (q31_t)0x97a1ef94, (q31_t)0x4a158fa3, (q31_t)0x979e4c7c, (q31_t)0x4a106fda, (q31_t)0x979aa9a4, (q31_t)0x4a0b4fe2, (q31_t)0x9797070c, + (q31_t)0x4a062fbd, (q31_t)0x979364b5, (q31_t)0x4a010f6b, (q31_t)0x978fc29e, (q31_t)0x49fbeeea, (q31_t)0x978c20c8, (q31_t)0x49f6ce3c, (q31_t)0x97887f32, + (q31_t)0x49f1ad61, (q31_t)0x9784dddc, (q31_t)0x49ec8c57, (q31_t)0x97813cc7, (q31_t)0x49e76b21, (q31_t)0x977d9bf2, (q31_t)0x49e249bc, (q31_t)0x9779fb5e, + (q31_t)0x49dd282a, (q31_t)0x97765b0a, (q31_t)0x49d8066b, (q31_t)0x9772baf7, (q31_t)0x49d2e47e, (q31_t)0x976f1b24, (q31_t)0x49cdc263, (q31_t)0x976b7b92, + (q31_t)0x49c8a01b, (q31_t)0x9767dc41, (q31_t)0x49c37da5, (q31_t)0x97643d2f, (q31_t)0x49be5b02, (q31_t)0x97609e5f, (q31_t)0x49b93832, (q31_t)0x975cffcf, + (q31_t)0x49b41533, (q31_t)0x9759617f, (q31_t)0x49aef208, (q31_t)0x9755c370, (q31_t)0x49a9ceaf, (q31_t)0x975225a1, (q31_t)0x49a4ab28, (q31_t)0x974e8813, + (q31_t)0x499f8774, (q31_t)0x974aeac6, (q31_t)0x499a6393, (q31_t)0x97474db9, (q31_t)0x49953f84, (q31_t)0x9743b0ed, (q31_t)0x49901b48, (q31_t)0x97401462, + (q31_t)0x498af6df, (q31_t)0x973c7817, (q31_t)0x4985d248, (q31_t)0x9738dc0d, (q31_t)0x4980ad84, (q31_t)0x97354043, (q31_t)0x497b8892, (q31_t)0x9731a4ba, + (q31_t)0x49766373, (q31_t)0x972e0971, (q31_t)0x49713e27, (q31_t)0x972a6e6a, (q31_t)0x496c18ae, (q31_t)0x9726d3a3, (q31_t)0x4966f307, (q31_t)0x9723391c, + (q31_t)0x4961cd33, (q31_t)0x971f9ed7, (q31_t)0x495ca732, (q31_t)0x971c04d2, (q31_t)0x49578103, (q31_t)0x97186b0d, (q31_t)0x49525aa7, (q31_t)0x9714d18a, + (q31_t)0x494d341e, (q31_t)0x97113847, (q31_t)0x49480d68, (q31_t)0x970d9f45, (q31_t)0x4942e684, (q31_t)0x970a0683, (q31_t)0x493dbf74, (q31_t)0x97066e03, + (q31_t)0x49389836, (q31_t)0x9702d5c3, (q31_t)0x493370cb, (q31_t)0x96ff3dc4, (q31_t)0x492e4933, (q31_t)0x96fba605, (q31_t)0x4929216e, (q31_t)0x96f80e88, + (q31_t)0x4923f97b, (q31_t)0x96f4774b, (q31_t)0x491ed15c, (q31_t)0x96f0e04f, (q31_t)0x4919a90f, (q31_t)0x96ed4994, (q31_t)0x49148095, (q31_t)0x96e9b319, + (q31_t)0x490f57ee, (q31_t)0x96e61ce0, (q31_t)0x490a2f1b, (q31_t)0x96e286e7, (q31_t)0x4905061a, (q31_t)0x96def12f, (q31_t)0x48ffdcec, (q31_t)0x96db5bb8, + (q31_t)0x48fab391, (q31_t)0x96d7c682, (q31_t)0x48f58a09, (q31_t)0x96d4318d, (q31_t)0x48f06054, (q31_t)0x96d09cd8, (q31_t)0x48eb3672, (q31_t)0x96cd0865, + (q31_t)0x48e60c62, (q31_t)0x96c97432, (q31_t)0x48e0e227, (q31_t)0x96c5e040, (q31_t)0x48dbb7be, (q31_t)0x96c24c8f, (q31_t)0x48d68d28, (q31_t)0x96beb91f, + (q31_t)0x48d16265, (q31_t)0x96bb25f0, (q31_t)0x48cc3775, (q31_t)0x96b79302, (q31_t)0x48c70c59, (q31_t)0x96b40055, (q31_t)0x48c1e10f, (q31_t)0x96b06de9, + (q31_t)0x48bcb599, (q31_t)0x96acdbbe, (q31_t)0x48b789f5, (q31_t)0x96a949d3, (q31_t)0x48b25e25, (q31_t)0x96a5b82a, (q31_t)0x48ad3228, (q31_t)0x96a226c2, + (q31_t)0x48a805ff, (q31_t)0x969e959b, (q31_t)0x48a2d9a8, (q31_t)0x969b04b4, (q31_t)0x489dad25, (q31_t)0x9697740f, (q31_t)0x48988074, (q31_t)0x9693e3ab, + (q31_t)0x48935397, (q31_t)0x96905388, (q31_t)0x488e268e, (q31_t)0x968cc3a5, (q31_t)0x4888f957, (q31_t)0x96893404, (q31_t)0x4883cbf4, (q31_t)0x9685a4a4, + (q31_t)0x487e9e64, (q31_t)0x96821585, (q31_t)0x487970a7, (q31_t)0x967e86a7, (q31_t)0x487442be, (q31_t)0x967af80a, (q31_t)0x486f14a8, (q31_t)0x967769af, + (q31_t)0x4869e665, (q31_t)0x9673db94, (q31_t)0x4864b7f5, (q31_t)0x96704dba, (q31_t)0x485f8959, (q31_t)0x966cc022, (q31_t)0x485a5a90, (q31_t)0x966932cb, + (q31_t)0x48552b9b, (q31_t)0x9665a5b4, (q31_t)0x484ffc79, (q31_t)0x966218df, (q31_t)0x484acd2a, (q31_t)0x965e8c4b, (q31_t)0x48459daf, (q31_t)0x965afff9, + (q31_t)0x48406e08, (q31_t)0x965773e7, (q31_t)0x483b3e33, (q31_t)0x9653e817, (q31_t)0x48360e32, (q31_t)0x96505c88, (q31_t)0x4830de05, (q31_t)0x964cd139, + (q31_t)0x482badab, (q31_t)0x9649462d, (q31_t)0x48267d24, (q31_t)0x9645bb61, (q31_t)0x48214c71, (q31_t)0x964230d7, (q31_t)0x481c1b92, (q31_t)0x963ea68d, + (q31_t)0x4816ea86, (q31_t)0x963b1c86, (q31_t)0x4811b94d, (q31_t)0x963792bf, (q31_t)0x480c87e8, (q31_t)0x96340939, (q31_t)0x48075657, (q31_t)0x96307ff5, + (q31_t)0x48022499, (q31_t)0x962cf6f2, (q31_t)0x47fcf2af, (q31_t)0x96296e31, (q31_t)0x47f7c099, (q31_t)0x9625e5b0, (q31_t)0x47f28e56, (q31_t)0x96225d71, + (q31_t)0x47ed5be6, (q31_t)0x961ed574, (q31_t)0x47e8294a, (q31_t)0x961b4db7, (q31_t)0x47e2f682, (q31_t)0x9617c63c, (q31_t)0x47ddc38e, (q31_t)0x96143f02, + (q31_t)0x47d8906d, (q31_t)0x9610b80a, (q31_t)0x47d35d20, (q31_t)0x960d3153, (q31_t)0x47ce29a7, (q31_t)0x9609aadd, (q31_t)0x47c8f601, (q31_t)0x960624a9, + (q31_t)0x47c3c22f, (q31_t)0x96029eb6, (q31_t)0x47be8e31, (q31_t)0x95ff1904, (q31_t)0x47b95a06, (q31_t)0x95fb9394, (q31_t)0x47b425af, (q31_t)0x95f80e65, + (q31_t)0x47aef12c, (q31_t)0x95f48977, (q31_t)0x47a9bc7d, (q31_t)0x95f104cb, (q31_t)0x47a487a2, (q31_t)0x95ed8061, (q31_t)0x479f529a, (q31_t)0x95e9fc38, + (q31_t)0x479a1d67, (q31_t)0x95e67850, (q31_t)0x4794e807, (q31_t)0x95e2f4a9, (q31_t)0x478fb27b, (q31_t)0x95df7145, (q31_t)0x478a7cc2, (q31_t)0x95dbee21, + (q31_t)0x478546de, (q31_t)0x95d86b3f, (q31_t)0x478010cd, (q31_t)0x95d4e89f, (q31_t)0x477ada91, (q31_t)0x95d16640, (q31_t)0x4775a428, (q31_t)0x95cde423, + (q31_t)0x47706d93, (q31_t)0x95ca6247, (q31_t)0x476b36d3, (q31_t)0x95c6e0ac, (q31_t)0x4765ffe6, (q31_t)0x95c35f53, (q31_t)0x4760c8cd, (q31_t)0x95bfde3c, + (q31_t)0x475b9188, (q31_t)0x95bc5d66, (q31_t)0x47565a17, (q31_t)0x95b8dcd2, (q31_t)0x4751227a, (q31_t)0x95b55c7f, (q31_t)0x474beab1, (q31_t)0x95b1dc6e, + (q31_t)0x4746b2bc, (q31_t)0x95ae5c9f, (q31_t)0x47417a9b, (q31_t)0x95aadd11, (q31_t)0x473c424e, (q31_t)0x95a75dc4, (q31_t)0x473709d5, (q31_t)0x95a3deb9, + (q31_t)0x4731d131, (q31_t)0x95a05ff0, (q31_t)0x472c9860, (q31_t)0x959ce169, (q31_t)0x47275f63, (q31_t)0x95996323, (q31_t)0x4722263b, (q31_t)0x9595e51e, + (q31_t)0x471cece7, (q31_t)0x9592675c, (q31_t)0x4717b367, (q31_t)0x958ee9db, (q31_t)0x471279ba, (q31_t)0x958b6c9b, (q31_t)0x470d3fe3, (q31_t)0x9587ef9e, + (q31_t)0x470805df, (q31_t)0x958472e2, (q31_t)0x4702cbaf, (q31_t)0x9580f667, (q31_t)0x46fd9154, (q31_t)0x957d7a2f, (q31_t)0x46f856cd, (q31_t)0x9579fe38, + (q31_t)0x46f31c1a, (q31_t)0x95768283, (q31_t)0x46ede13b, (q31_t)0x9573070f, (q31_t)0x46e8a631, (q31_t)0x956f8bdd, (q31_t)0x46e36afb, (q31_t)0x956c10ed, + (q31_t)0x46de2f99, (q31_t)0x9568963f, (q31_t)0x46d8f40b, (q31_t)0x95651bd2, (q31_t)0x46d3b852, (q31_t)0x9561a1a8, (q31_t)0x46ce7c6d, (q31_t)0x955e27bf, + (q31_t)0x46c9405c, (q31_t)0x955aae17, (q31_t)0x46c40420, (q31_t)0x955734b2, (q31_t)0x46bec7b8, (q31_t)0x9553bb8e, (q31_t)0x46b98b24, (q31_t)0x955042ac, + (q31_t)0x46b44e65, (q31_t)0x954cca0c, (q31_t)0x46af117a, (q31_t)0x954951ae, (q31_t)0x46a9d464, (q31_t)0x9545d992, (q31_t)0x46a49722, (q31_t)0x954261b7, + (q31_t)0x469f59b4, (q31_t)0x953eea1e, (q31_t)0x469a1c1b, (q31_t)0x953b72c7, (q31_t)0x4694de56, (q31_t)0x9537fbb2, (q31_t)0x468fa066, (q31_t)0x953484df, + (q31_t)0x468a624a, (q31_t)0x95310e4e, (q31_t)0x46852403, (q31_t)0x952d97fe, (q31_t)0x467fe590, (q31_t)0x952a21f1, (q31_t)0x467aa6f2, (q31_t)0x9526ac25, + (q31_t)0x46756828, (q31_t)0x9523369c, (q31_t)0x46702933, (q31_t)0x951fc154, (q31_t)0x466aea12, (q31_t)0x951c4c4e, (q31_t)0x4665aac6, (q31_t)0x9518d78a, + (q31_t)0x46606b4e, (q31_t)0x95156308, (q31_t)0x465b2bab, (q31_t)0x9511eec8, (q31_t)0x4655ebdd, (q31_t)0x950e7aca, (q31_t)0x4650abe3, (q31_t)0x950b070e, + (q31_t)0x464b6bbe, (q31_t)0x95079394, (q31_t)0x46462b6d, (q31_t)0x9504205c, (q31_t)0x4640eaf2, (q31_t)0x9500ad66, (q31_t)0x463baa4a, (q31_t)0x94fd3ab1, + (q31_t)0x46366978, (q31_t)0x94f9c83f, (q31_t)0x4631287a, (q31_t)0x94f6560f, (q31_t)0x462be751, (q31_t)0x94f2e421, (q31_t)0x4626a5fd, (q31_t)0x94ef7275, + (q31_t)0x4621647d, (q31_t)0x94ec010b, (q31_t)0x461c22d2, (q31_t)0x94e88fe3, (q31_t)0x4616e0fc, (q31_t)0x94e51efd, (q31_t)0x46119efa, (q31_t)0x94e1ae59, + (q31_t)0x460c5cce, (q31_t)0x94de3df8, (q31_t)0x46071a76, (q31_t)0x94dacdd8, (q31_t)0x4601d7f3, (q31_t)0x94d75dfa, (q31_t)0x45fc9545, (q31_t)0x94d3ee5f, + (q31_t)0x45f7526b, (q31_t)0x94d07f05, (q31_t)0x45f20f67, (q31_t)0x94cd0fee, (q31_t)0x45eccc37, (q31_t)0x94c9a119, (q31_t)0x45e788dc, (q31_t)0x94c63286, + (q31_t)0x45e24556, (q31_t)0x94c2c435, (q31_t)0x45dd01a5, (q31_t)0x94bf5627, (q31_t)0x45d7bdc9, (q31_t)0x94bbe85a, (q31_t)0x45d279c2, (q31_t)0x94b87ad0, + (q31_t)0x45cd358f, (q31_t)0x94b50d87, (q31_t)0x45c7f132, (q31_t)0x94b1a081, (q31_t)0x45c2acaa, (q31_t)0x94ae33be, (q31_t)0x45bd67f6, (q31_t)0x94aac73c, + (q31_t)0x45b82318, (q31_t)0x94a75afd, (q31_t)0x45b2de0e, (q31_t)0x94a3eeff, (q31_t)0x45ad98da, (q31_t)0x94a08344, (q31_t)0x45a8537a, (q31_t)0x949d17cc, + (q31_t)0x45a30df0, (q31_t)0x9499ac95, (q31_t)0x459dc83b, (q31_t)0x949641a1, (q31_t)0x4598825a, (q31_t)0x9492d6ef, (q31_t)0x45933c4f, (q31_t)0x948f6c7f, + (q31_t)0x458df619, (q31_t)0x948c0252, (q31_t)0x4588afb8, (q31_t)0x94889867, (q31_t)0x4583692c, (q31_t)0x94852ebe, (q31_t)0x457e2275, (q31_t)0x9481c557, + (q31_t)0x4578db93, (q31_t)0x947e5c33, (q31_t)0x45739487, (q31_t)0x947af351, (q31_t)0x456e4d4f, (q31_t)0x94778ab1, (q31_t)0x456905ed, (q31_t)0x94742254, + (q31_t)0x4563be60, (q31_t)0x9470ba39, (q31_t)0x455e76a8, (q31_t)0x946d5260, (q31_t)0x45592ec6, (q31_t)0x9469eaca, (q31_t)0x4553e6b8, (q31_t)0x94668376, + (q31_t)0x454e9e80, (q31_t)0x94631c65, (q31_t)0x4549561d, (q31_t)0x945fb596, (q31_t)0x45440d90, (q31_t)0x945c4f09, (q31_t)0x453ec4d7, (q31_t)0x9458e8bf, + (q31_t)0x45397bf4, (q31_t)0x945582b7, (q31_t)0x453432e6, (q31_t)0x94521cf1, (q31_t)0x452ee9ae, (q31_t)0x944eb76e, (q31_t)0x4529a04b, (q31_t)0x944b522d, + (q31_t)0x452456bd, (q31_t)0x9447ed2f, (q31_t)0x451f0d04, (q31_t)0x94448873, (q31_t)0x4519c321, (q31_t)0x944123fa, (q31_t)0x45147913, (q31_t)0x943dbfc3, + (q31_t)0x450f2edb, (q31_t)0x943a5bcf, (q31_t)0x4509e478, (q31_t)0x9436f81d, (q31_t)0x450499eb, (q31_t)0x943394ad, (q31_t)0x44ff4f32, (q31_t)0x94303180, + (q31_t)0x44fa0450, (q31_t)0x942cce96, (q31_t)0x44f4b943, (q31_t)0x94296bee, (q31_t)0x44ef6e0b, (q31_t)0x94260989, (q31_t)0x44ea22a9, (q31_t)0x9422a766, + (q31_t)0x44e4d71c, (q31_t)0x941f4585, (q31_t)0x44df8b64, (q31_t)0x941be3e8, (q31_t)0x44da3f83, (q31_t)0x9418828c, (q31_t)0x44d4f376, (q31_t)0x94152174, + (q31_t)0x44cfa740, (q31_t)0x9411c09e, (q31_t)0x44ca5adf, (q31_t)0x940e600a, (q31_t)0x44c50e53, (q31_t)0x940affb9, (q31_t)0x44bfc19d, (q31_t)0x94079fab, + (q31_t)0x44ba74bd, (q31_t)0x94043fdf, (q31_t)0x44b527b2, (q31_t)0x9400e056, (q31_t)0x44afda7d, (q31_t)0x93fd810f, (q31_t)0x44aa8d1d, (q31_t)0x93fa220b, + (q31_t)0x44a53f93, (q31_t)0x93f6c34a, (q31_t)0x449ff1df, (q31_t)0x93f364cb, (q31_t)0x449aa400, (q31_t)0x93f0068f, (q31_t)0x449555f7, (q31_t)0x93eca896, + (q31_t)0x449007c4, (q31_t)0x93e94adf, (q31_t)0x448ab967, (q31_t)0x93e5ed6b, (q31_t)0x44856adf, (q31_t)0x93e2903a, (q31_t)0x44801c2d, (q31_t)0x93df334c, + (q31_t)0x447acd50, (q31_t)0x93dbd6a0, (q31_t)0x44757e4a, (q31_t)0x93d87a36, (q31_t)0x44702f19, (q31_t)0x93d51e10, (q31_t)0x446adfbe, (q31_t)0x93d1c22c, + (q31_t)0x44659039, (q31_t)0x93ce668b, (q31_t)0x44604089, (q31_t)0x93cb0b2d, (q31_t)0x445af0b0, (q31_t)0x93c7b011, (q31_t)0x4455a0ac, (q31_t)0x93c45539, + (q31_t)0x4450507e, (q31_t)0x93c0faa3, (q31_t)0x444b0026, (q31_t)0x93bda04f, (q31_t)0x4445afa4, (q31_t)0x93ba463f, (q31_t)0x44405ef8, (q31_t)0x93b6ec71, + (q31_t)0x443b0e21, (q31_t)0x93b392e6, (q31_t)0x4435bd21, (q31_t)0x93b0399e, (q31_t)0x44306bf6, (q31_t)0x93ace099, (q31_t)0x442b1aa2, (q31_t)0x93a987d6, + (q31_t)0x4425c923, (q31_t)0x93a62f57, (q31_t)0x4420777b, (q31_t)0x93a2d71a, (q31_t)0x441b25a8, (q31_t)0x939f7f20, (q31_t)0x4415d3ab, (q31_t)0x939c2769, + (q31_t)0x44108184, (q31_t)0x9398cff5, (q31_t)0x440b2f34, (q31_t)0x939578c3, (q31_t)0x4405dcb9, (q31_t)0x939221d5, (q31_t)0x44008a14, (q31_t)0x938ecb29, + (q31_t)0x43fb3746, (q31_t)0x938b74c1, (q31_t)0x43f5e44d, (q31_t)0x93881e9b, (q31_t)0x43f0912b, (q31_t)0x9384c8b8, (q31_t)0x43eb3ddf, (q31_t)0x93817318, + (q31_t)0x43e5ea68, (q31_t)0x937e1dbb, (q31_t)0x43e096c8, (q31_t)0x937ac8a1, (q31_t)0x43db42fe, (q31_t)0x937773ca, (q31_t)0x43d5ef0a, (q31_t)0x93741f35, + (q31_t)0x43d09aed, (q31_t)0x9370cae4, (q31_t)0x43cb46a5, (q31_t)0x936d76d6, (q31_t)0x43c5f234, (q31_t)0x936a230a, (q31_t)0x43c09d99, (q31_t)0x9366cf82, + (q31_t)0x43bb48d4, (q31_t)0x93637c3d, (q31_t)0x43b5f3e5, (q31_t)0x9360293a, (q31_t)0x43b09ecc, (q31_t)0x935cd67b, (q31_t)0x43ab498a, (q31_t)0x935983ff, + (q31_t)0x43a5f41e, (q31_t)0x935631c5, (q31_t)0x43a09e89, (q31_t)0x9352dfcf, (q31_t)0x439b48c9, (q31_t)0x934f8e1c, (q31_t)0x4395f2e0, (q31_t)0x934c3cab, + (q31_t)0x43909ccd, (q31_t)0x9348eb7e, (q31_t)0x438b4691, (q31_t)0x93459a94, (q31_t)0x4385f02a, (q31_t)0x934249ed, (q31_t)0x4380999b, (q31_t)0x933ef989, + (q31_t)0x437b42e1, (q31_t)0x933ba968, (q31_t)0x4375ebfe, (q31_t)0x9338598a, (q31_t)0x437094f1, (q31_t)0x933509f0, (q31_t)0x436b3dbb, (q31_t)0x9331ba98, + (q31_t)0x4365e65b, (q31_t)0x932e6b84, (q31_t)0x43608ed2, (q31_t)0x932b1cb2, (q31_t)0x435b371f, (q31_t)0x9327ce24, (q31_t)0x4355df42, (q31_t)0x93247fd9, + (q31_t)0x4350873c, (q31_t)0x932131d1, (q31_t)0x434b2f0c, (q31_t)0x931de40c, (q31_t)0x4345d6b3, (q31_t)0x931a968b, (q31_t)0x43407e31, (q31_t)0x9317494c, + (q31_t)0x433b2585, (q31_t)0x9313fc51, (q31_t)0x4335ccaf, (q31_t)0x9310af99, (q31_t)0x433073b0, (q31_t)0x930d6324, (q31_t)0x432b1a87, (q31_t)0x930a16f3, + (q31_t)0x4325c135, (q31_t)0x9306cb04, (q31_t)0x432067ba, (q31_t)0x93037f59, (q31_t)0x431b0e15, (q31_t)0x930033f1, (q31_t)0x4315b447, (q31_t)0x92fce8cc, + (q31_t)0x43105a50, (q31_t)0x92f99deb, (q31_t)0x430b002f, (q31_t)0x92f6534c, (q31_t)0x4305a5e5, (q31_t)0x92f308f1, (q31_t)0x43004b71, (q31_t)0x92efbeda, + (q31_t)0x42faf0d4, (q31_t)0x92ec7505, (q31_t)0x42f5960e, (q31_t)0x92e92b74, (q31_t)0x42f03b1e, (q31_t)0x92e5e226, (q31_t)0x42eae005, (q31_t)0x92e2991c, + (q31_t)0x42e584c3, (q31_t)0x92df5054, (q31_t)0x42e02958, (q31_t)0x92dc07d0, (q31_t)0x42dacdc3, (q31_t)0x92d8bf90, (q31_t)0x42d57205, (q31_t)0x92d57792, + (q31_t)0x42d0161e, (q31_t)0x92d22fd9, (q31_t)0x42caba0e, (q31_t)0x92cee862, (q31_t)0x42c55dd4, (q31_t)0x92cba12f, (q31_t)0x42c00172, (q31_t)0x92c85a3f, + (q31_t)0x42baa4e6, (q31_t)0x92c51392, (q31_t)0x42b54831, (q31_t)0x92c1cd29, (q31_t)0x42afeb53, (q31_t)0x92be8703, (q31_t)0x42aa8e4b, (q31_t)0x92bb4121, + (q31_t)0x42a5311b, (q31_t)0x92b7fb82, (q31_t)0x429fd3c1, (q31_t)0x92b4b626, (q31_t)0x429a763f, (q31_t)0x92b1710e, (q31_t)0x42951893, (q31_t)0x92ae2c3a, + (q31_t)0x428fbabe, (q31_t)0x92aae7a8, (q31_t)0x428a5cc0, (q31_t)0x92a7a35a, (q31_t)0x4284fe99, (q31_t)0x92a45f50, (q31_t)0x427fa049, (q31_t)0x92a11b89, + (q31_t)0x427a41d0, (q31_t)0x929dd806, (q31_t)0x4274e32e, (q31_t)0x929a94c6, (q31_t)0x426f8463, (q31_t)0x929751c9, (q31_t)0x426a256f, (q31_t)0x92940f10, + (q31_t)0x4264c653, (q31_t)0x9290cc9b, (q31_t)0x425f670d, (q31_t)0x928d8a69, (q31_t)0x425a079e, (q31_t)0x928a487a, (q31_t)0x4254a806, (q31_t)0x928706cf, + (q31_t)0x424f4845, (q31_t)0x9283c568, (q31_t)0x4249e85c, (q31_t)0x92808444, (q31_t)0x42448849, (q31_t)0x927d4363, (q31_t)0x423f280e, (q31_t)0x927a02c7, + (q31_t)0x4239c7aa, (q31_t)0x9276c26d, (q31_t)0x4234671d, (q31_t)0x92738258, (q31_t)0x422f0667, (q31_t)0x92704286, (q31_t)0x4229a588, (q31_t)0x926d02f7, + (q31_t)0x42244481, (q31_t)0x9269c3ac, (q31_t)0x421ee350, (q31_t)0x926684a5, (q31_t)0x421981f7, (q31_t)0x926345e1, (q31_t)0x42142075, (q31_t)0x92600761, + (q31_t)0x420ebecb, (q31_t)0x925cc924, (q31_t)0x42095cf7, (q31_t)0x92598b2b, (q31_t)0x4203fafb, (q31_t)0x92564d76, (q31_t)0x41fe98d6, (q31_t)0x92531005, + (q31_t)0x41f93689, (q31_t)0x924fd2d7, (q31_t)0x41f3d413, (q31_t)0x924c95ec, (q31_t)0x41ee7174, (q31_t)0x92495946, (q31_t)0x41e90eac, (q31_t)0x92461ce3, + (q31_t)0x41e3abbc, (q31_t)0x9242e0c4, (q31_t)0x41de48a3, (q31_t)0x923fa4e8, (q31_t)0x41d8e561, (q31_t)0x923c6950, (q31_t)0x41d381f7, (q31_t)0x92392dfc, + (q31_t)0x41ce1e65, (q31_t)0x9235f2ec, (q31_t)0x41c8baa9, (q31_t)0x9232b81f, (q31_t)0x41c356c5, (q31_t)0x922f7d96, (q31_t)0x41bdf2b9, (q31_t)0x922c4351, + (q31_t)0x41b88e84, (q31_t)0x9229094f, (q31_t)0x41b32a26, (q31_t)0x9225cf91, (q31_t)0x41adc5a0, (q31_t)0x92229617, (q31_t)0x41a860f1, (q31_t)0x921f5ce1, + (q31_t)0x41a2fc1a, (q31_t)0x921c23ef, (q31_t)0x419d971b, (q31_t)0x9218eb40, (q31_t)0x419831f3, (q31_t)0x9215b2d5, (q31_t)0x4192cca2, (q31_t)0x92127aae, + (q31_t)0x418d6729, (q31_t)0x920f42cb, (q31_t)0x41880188, (q31_t)0x920c0b2c, (q31_t)0x41829bbe, (q31_t)0x9208d3d0, (q31_t)0x417d35cb, (q31_t)0x92059cb8, + (q31_t)0x4177cfb1, (q31_t)0x920265e4, (q31_t)0x4172696e, (q31_t)0x91ff2f54, (q31_t)0x416d0302, (q31_t)0x91fbf908, (q31_t)0x41679c6f, (q31_t)0x91f8c300, + (q31_t)0x416235b2, (q31_t)0x91f58d3b, (q31_t)0x415ccece, (q31_t)0x91f257bb, (q31_t)0x415767c1, (q31_t)0x91ef227e, (q31_t)0x4152008c, (q31_t)0x91ebed85, + (q31_t)0x414c992f, (q31_t)0x91e8b8d0, (q31_t)0x414731a9, (q31_t)0x91e5845f, (q31_t)0x4141c9fb, (q31_t)0x91e25032, (q31_t)0x413c6225, (q31_t)0x91df1c49, + (q31_t)0x4136fa27, (q31_t)0x91dbe8a4, (q31_t)0x41319200, (q31_t)0x91d8b542, (q31_t)0x412c29b1, (q31_t)0x91d58225, (q31_t)0x4126c13a, (q31_t)0x91d24f4c, + (q31_t)0x4121589b, (q31_t)0x91cf1cb6, (q31_t)0x411befd3, (q31_t)0x91cbea65, (q31_t)0x411686e4, (q31_t)0x91c8b857, (q31_t)0x41111dcc, (q31_t)0x91c5868e, + (q31_t)0x410bb48c, (q31_t)0x91c25508, (q31_t)0x41064b24, (q31_t)0x91bf23c7, (q31_t)0x4100e194, (q31_t)0x91bbf2c9, (q31_t)0x40fb77dc, (q31_t)0x91b8c210, + (q31_t)0x40f60dfb, (q31_t)0x91b5919a, (q31_t)0x40f0a3f3, (q31_t)0x91b26169, (q31_t)0x40eb39c3, (q31_t)0x91af317c, (q31_t)0x40e5cf6a, (q31_t)0x91ac01d2, + (q31_t)0x40e064ea, (q31_t)0x91a8d26d, (q31_t)0x40dafa41, (q31_t)0x91a5a34c, (q31_t)0x40d58f71, (q31_t)0x91a2746f, (q31_t)0x40d02478, (q31_t)0x919f45d6, + (q31_t)0x40cab958, (q31_t)0x919c1781, (q31_t)0x40c54e0f, (q31_t)0x9198e970, (q31_t)0x40bfe29f, (q31_t)0x9195bba3, (q31_t)0x40ba7706, (q31_t)0x91928e1a, + (q31_t)0x40b50b46, (q31_t)0x918f60d6, (q31_t)0x40af9f5e, (q31_t)0x918c33d5, (q31_t)0x40aa334e, (q31_t)0x91890719, (q31_t)0x40a4c716, (q31_t)0x9185daa1, + (q31_t)0x409f5ab6, (q31_t)0x9182ae6d, (q31_t)0x4099ee2e, (q31_t)0x917f827d, (q31_t)0x4094817f, (q31_t)0x917c56d1, (q31_t)0x408f14a7, (q31_t)0x91792b6a, + (q31_t)0x4089a7a8, (q31_t)0x91760047, (q31_t)0x40843a81, (q31_t)0x9172d567, (q31_t)0x407ecd32, (q31_t)0x916faacc, (q31_t)0x40795fbc, (q31_t)0x916c8076, + (q31_t)0x4073f21d, (q31_t)0x91695663, (q31_t)0x406e8457, (q31_t)0x91662c95, (q31_t)0x40691669, (q31_t)0x9163030b, (q31_t)0x4063a854, (q31_t)0x915fd9c5, + (q31_t)0x405e3a16, (q31_t)0x915cb0c3, (q31_t)0x4058cbb1, (q31_t)0x91598806, (q31_t)0x40535d24, (q31_t)0x91565f8d, (q31_t)0x404dee70, (q31_t)0x91533758, + (q31_t)0x40487f94, (q31_t)0x91500f67, (q31_t)0x40431090, (q31_t)0x914ce7bb, (q31_t)0x403da165, (q31_t)0x9149c053, (q31_t)0x40383212, (q31_t)0x9146992f, + (q31_t)0x4032c297, (q31_t)0x91437250, (q31_t)0x402d52f5, (q31_t)0x91404bb5, (q31_t)0x4027e32b, (q31_t)0x913d255e, (q31_t)0x4022733a, (q31_t)0x9139ff4b, + (q31_t)0x401d0321, (q31_t)0x9136d97d, (q31_t)0x401792e0, (q31_t)0x9133b3f3, (q31_t)0x40122278, (q31_t)0x91308eae, (q31_t)0x400cb1e9, (q31_t)0x912d69ad, + (q31_t)0x40074132, (q31_t)0x912a44f0, (q31_t)0x4001d053, (q31_t)0x91272078, (q31_t)0x3ffc5f4d, (q31_t)0x9123fc44, (q31_t)0x3ff6ee1f, (q31_t)0x9120d854, + (q31_t)0x3ff17cca, (q31_t)0x911db4a9, (q31_t)0x3fec0b4e, (q31_t)0x911a9142, (q31_t)0x3fe699aa, (q31_t)0x91176e1f, (q31_t)0x3fe127df, (q31_t)0x91144b41, + (q31_t)0x3fdbb5ec, (q31_t)0x911128a8, (q31_t)0x3fd643d2, (q31_t)0x910e0653, (q31_t)0x3fd0d191, (q31_t)0x910ae442, (q31_t)0x3fcb5f28, (q31_t)0x9107c276, + (q31_t)0x3fc5ec98, (q31_t)0x9104a0ee, (q31_t)0x3fc079e0, (q31_t)0x91017faa, (q31_t)0x3fbb0702, (q31_t)0x90fe5eab, (q31_t)0x3fb593fb, (q31_t)0x90fb3df1, + (q31_t)0x3fb020ce, (q31_t)0x90f81d7b, (q31_t)0x3faaad79, (q31_t)0x90f4fd4a, (q31_t)0x3fa539fd, (q31_t)0x90f1dd5d, (q31_t)0x3f9fc65a, (q31_t)0x90eebdb4, + (q31_t)0x3f9a5290, (q31_t)0x90eb9e50, (q31_t)0x3f94de9e, (q31_t)0x90e87f31, (q31_t)0x3f8f6a85, (q31_t)0x90e56056, (q31_t)0x3f89f645, (q31_t)0x90e241bf, + (q31_t)0x3f8481dd, (q31_t)0x90df236e, (q31_t)0x3f7f0d4f, (q31_t)0x90dc0560, (q31_t)0x3f799899, (q31_t)0x90d8e798, (q31_t)0x3f7423bc, (q31_t)0x90d5ca13, + (q31_t)0x3f6eaeb8, (q31_t)0x90d2acd4, (q31_t)0x3f69398d, (q31_t)0x90cf8fd9, (q31_t)0x3f63c43b, (q31_t)0x90cc7322, (q31_t)0x3f5e4ec2, (q31_t)0x90c956b1, + (q31_t)0x3f58d921, (q31_t)0x90c63a83, (q31_t)0x3f53635a, (q31_t)0x90c31e9b, (q31_t)0x3f4ded6b, (q31_t)0x90c002f7, (q31_t)0x3f487755, (q31_t)0x90bce797, + (q31_t)0x3f430119, (q31_t)0x90b9cc7d, (q31_t)0x3f3d8ab5, (q31_t)0x90b6b1a6, (q31_t)0x3f38142a, (q31_t)0x90b39715, (q31_t)0x3f329d79, (q31_t)0x90b07cc8, + (q31_t)0x3f2d26a0, (q31_t)0x90ad62c0, (q31_t)0x3f27afa1, (q31_t)0x90aa48fd, (q31_t)0x3f22387a, (q31_t)0x90a72f7e, (q31_t)0x3f1cc12c, (q31_t)0x90a41644, + (q31_t)0x3f1749b8, (q31_t)0x90a0fd4e, (q31_t)0x3f11d21d, (q31_t)0x909de49e, (q31_t)0x3f0c5a5a, (q31_t)0x909acc32, (q31_t)0x3f06e271, (q31_t)0x9097b40a, + (q31_t)0x3f016a61, (q31_t)0x90949c28, (q31_t)0x3efbf22a, (q31_t)0x9091848a, (q31_t)0x3ef679cc, (q31_t)0x908e6d31, (q31_t)0x3ef10148, (q31_t)0x908b561c, + (q31_t)0x3eeb889c, (q31_t)0x90883f4d, (q31_t)0x3ee60fca, (q31_t)0x908528c2, (q31_t)0x3ee096d1, (q31_t)0x9082127c, (q31_t)0x3edb1db1, (q31_t)0x907efc7a, + (q31_t)0x3ed5a46b, (q31_t)0x907be6be, (q31_t)0x3ed02afd, (q31_t)0x9078d146, (q31_t)0x3ecab169, (q31_t)0x9075bc13, (q31_t)0x3ec537ae, (q31_t)0x9072a725, + (q31_t)0x3ebfbdcd, (q31_t)0x906f927c, (q31_t)0x3eba43c4, (q31_t)0x906c7e17, (q31_t)0x3eb4c995, (q31_t)0x906969f8, (q31_t)0x3eaf4f40, (q31_t)0x9066561d, + (q31_t)0x3ea9d4c3, (q31_t)0x90634287, (q31_t)0x3ea45a21, (q31_t)0x90602f35, (q31_t)0x3e9edf57, (q31_t)0x905d1c29, (q31_t)0x3e996467, (q31_t)0x905a0962, + (q31_t)0x3e93e950, (q31_t)0x9056f6df, (q31_t)0x3e8e6e12, (q31_t)0x9053e4a1, (q31_t)0x3e88f2ae, (q31_t)0x9050d2a9, (q31_t)0x3e837724, (q31_t)0x904dc0f5, + (q31_t)0x3e7dfb73, (q31_t)0x904aaf86, (q31_t)0x3e787f9b, (q31_t)0x90479e5c, (q31_t)0x3e73039d, (q31_t)0x90448d76, (q31_t)0x3e6d8778, (q31_t)0x90417cd6, + (q31_t)0x3e680b2c, (q31_t)0x903e6c7b, (q31_t)0x3e628ebb, (q31_t)0x903b5c64, (q31_t)0x3e5d1222, (q31_t)0x90384c93, (q31_t)0x3e579564, (q31_t)0x90353d06, + (q31_t)0x3e52187f, (q31_t)0x90322dbf, (q31_t)0x3e4c9b73, (q31_t)0x902f1ebc, (q31_t)0x3e471e41, (q31_t)0x902c0fff, (q31_t)0x3e41a0e8, (q31_t)0x90290186, + (q31_t)0x3e3c2369, (q31_t)0x9025f352, (q31_t)0x3e36a5c4, (q31_t)0x9022e564, (q31_t)0x3e3127f9, (q31_t)0x901fd7ba, (q31_t)0x3e2baa07, (q31_t)0x901cca55, + (q31_t)0x3e262bee, (q31_t)0x9019bd36, (q31_t)0x3e20adaf, (q31_t)0x9016b05b, (q31_t)0x3e1b2f4a, (q31_t)0x9013a3c5, (q31_t)0x3e15b0bf, (q31_t)0x90109775, + (q31_t)0x3e10320d, (q31_t)0x900d8b69, (q31_t)0x3e0ab336, (q31_t)0x900a7fa3, (q31_t)0x3e053437, (q31_t)0x90077422, (q31_t)0x3dffb513, (q31_t)0x900468e5, + (q31_t)0x3dfa35c8, (q31_t)0x90015dee, (q31_t)0x3df4b657, (q31_t)0x8ffe533c, (q31_t)0x3def36c0, (q31_t)0x8ffb48cf, (q31_t)0x3de9b703, (q31_t)0x8ff83ea7, + (q31_t)0x3de4371f, (q31_t)0x8ff534c4, (q31_t)0x3ddeb716, (q31_t)0x8ff22b26, (q31_t)0x3dd936e6, (q31_t)0x8fef21ce, (q31_t)0x3dd3b690, (q31_t)0x8fec18ba, + (q31_t)0x3dce3614, (q31_t)0x8fe90fec, (q31_t)0x3dc8b571, (q31_t)0x8fe60763, (q31_t)0x3dc334a9, (q31_t)0x8fe2ff1f, (q31_t)0x3dbdb3ba, (q31_t)0x8fdff720, + (q31_t)0x3db832a6, (q31_t)0x8fdcef66, (q31_t)0x3db2b16b, (q31_t)0x8fd9e7f2, (q31_t)0x3dad300b, (q31_t)0x8fd6e0c2, (q31_t)0x3da7ae84, (q31_t)0x8fd3d9d8, + (q31_t)0x3da22cd7, (q31_t)0x8fd0d333, (q31_t)0x3d9cab04, (q31_t)0x8fcdccd3, (q31_t)0x3d97290b, (q31_t)0x8fcac6b9, (q31_t)0x3d91a6ed, (q31_t)0x8fc7c0e3, + (q31_t)0x3d8c24a8, (q31_t)0x8fc4bb53, (q31_t)0x3d86a23d, (q31_t)0x8fc1b608, (q31_t)0x3d811fac, (q31_t)0x8fbeb103, (q31_t)0x3d7b9cf6, (q31_t)0x8fbbac42, + (q31_t)0x3d761a19, (q31_t)0x8fb8a7c7, (q31_t)0x3d709717, (q31_t)0x8fb5a391, (q31_t)0x3d6b13ee, (q31_t)0x8fb29fa0, (q31_t)0x3d6590a0, (q31_t)0x8faf9bf5, + (q31_t)0x3d600d2c, (q31_t)0x8fac988f, (q31_t)0x3d5a8992, (q31_t)0x8fa9956e, (q31_t)0x3d5505d2, (q31_t)0x8fa69293, (q31_t)0x3d4f81ec, (q31_t)0x8fa38ffc, + (q31_t)0x3d49fde1, (q31_t)0x8fa08dab, (q31_t)0x3d4479b0, (q31_t)0x8f9d8ba0, (q31_t)0x3d3ef559, (q31_t)0x8f9a89da, (q31_t)0x3d3970dc, (q31_t)0x8f978859, + (q31_t)0x3d33ec39, (q31_t)0x8f94871d, (q31_t)0x3d2e6771, (q31_t)0x8f918627, (q31_t)0x3d28e282, (q31_t)0x8f8e8576, (q31_t)0x3d235d6f, (q31_t)0x8f8b850a, + (q31_t)0x3d1dd835, (q31_t)0x8f8884e4, (q31_t)0x3d1852d6, (q31_t)0x8f858503, (q31_t)0x3d12cd51, (q31_t)0x8f828568, (q31_t)0x3d0d47a6, (q31_t)0x8f7f8612, + (q31_t)0x3d07c1d6, (q31_t)0x8f7c8701, (q31_t)0x3d023be0, (q31_t)0x8f798836, (q31_t)0x3cfcb5c4, (q31_t)0x8f7689b0, (q31_t)0x3cf72f83, (q31_t)0x8f738b70, + (q31_t)0x3cf1a91c, (q31_t)0x8f708d75, (q31_t)0x3cec2290, (q31_t)0x8f6d8fbf, (q31_t)0x3ce69bde, (q31_t)0x8f6a924f, (q31_t)0x3ce11507, (q31_t)0x8f679525, + (q31_t)0x3cdb8e09, (q31_t)0x8f649840, (q31_t)0x3cd606e7, (q31_t)0x8f619ba0, (q31_t)0x3cd07f9f, (q31_t)0x8f5e9f46, (q31_t)0x3ccaf831, (q31_t)0x8f5ba331, + (q31_t)0x3cc5709e, (q31_t)0x8f58a761, (q31_t)0x3cbfe8e5, (q31_t)0x8f55abd8, (q31_t)0x3cba6107, (q31_t)0x8f52b093, (q31_t)0x3cb4d904, (q31_t)0x8f4fb595, + (q31_t)0x3caf50da, (q31_t)0x8f4cbadb, (q31_t)0x3ca9c88c, (q31_t)0x8f49c067, (q31_t)0x3ca44018, (q31_t)0x8f46c639, (q31_t)0x3c9eb77f, (q31_t)0x8f43cc50, + (q31_t)0x3c992ec0, (q31_t)0x8f40d2ad, (q31_t)0x3c93a5dc, (q31_t)0x8f3dd950, (q31_t)0x3c8e1cd3, (q31_t)0x8f3ae038, (q31_t)0x3c8893a4, (q31_t)0x8f37e765, + (q31_t)0x3c830a50, (q31_t)0x8f34eed8, (q31_t)0x3c7d80d6, (q31_t)0x8f31f691, (q31_t)0x3c77f737, (q31_t)0x8f2efe8f, (q31_t)0x3c726d73, (q31_t)0x8f2c06d3, + (q31_t)0x3c6ce38a, (q31_t)0x8f290f5c, (q31_t)0x3c67597b, (q31_t)0x8f26182b, (q31_t)0x3c61cf48, (q31_t)0x8f232140, (q31_t)0x3c5c44ee, (q31_t)0x8f202a9a, + (q31_t)0x3c56ba70, (q31_t)0x8f1d343a, (q31_t)0x3c512fcc, (q31_t)0x8f1a3e1f, (q31_t)0x3c4ba504, (q31_t)0x8f17484b, (q31_t)0x3c461a16, (q31_t)0x8f1452bb, + (q31_t)0x3c408f03, (q31_t)0x8f115d72, (q31_t)0x3c3b03ca, (q31_t)0x8f0e686e, (q31_t)0x3c35786d, (q31_t)0x8f0b73b0, (q31_t)0x3c2fecea, (q31_t)0x8f087f37, + (q31_t)0x3c2a6142, (q31_t)0x8f058b04, (q31_t)0x3c24d575, (q31_t)0x8f029717, (q31_t)0x3c1f4983, (q31_t)0x8effa370, (q31_t)0x3c19bd6c, (q31_t)0x8efcb00e, + (q31_t)0x3c143130, (q31_t)0x8ef9bcf2, (q31_t)0x3c0ea4cf, (q31_t)0x8ef6ca1c, (q31_t)0x3c091849, (q31_t)0x8ef3d78b, (q31_t)0x3c038b9e, (q31_t)0x8ef0e540, + (q31_t)0x3bfdfecd, (q31_t)0x8eedf33b, (q31_t)0x3bf871d8, (q31_t)0x8eeb017c, (q31_t)0x3bf2e4be, (q31_t)0x8ee81002, (q31_t)0x3bed577e, (q31_t)0x8ee51ece, + (q31_t)0x3be7ca1a, (q31_t)0x8ee22de0, (q31_t)0x3be23c91, (q31_t)0x8edf3d38, (q31_t)0x3bdcaee3, (q31_t)0x8edc4cd5, (q31_t)0x3bd72110, (q31_t)0x8ed95cb8, + (q31_t)0x3bd19318, (q31_t)0x8ed66ce1, (q31_t)0x3bcc04fb, (q31_t)0x8ed37d50, (q31_t)0x3bc676b9, (q31_t)0x8ed08e05, (q31_t)0x3bc0e853, (q31_t)0x8ecd9eff, + (q31_t)0x3bbb59c7, (q31_t)0x8ecab040, (q31_t)0x3bb5cb17, (q31_t)0x8ec7c1c6, (q31_t)0x3bb03c42, (q31_t)0x8ec4d392, (q31_t)0x3baaad48, (q31_t)0x8ec1e5a4, + (q31_t)0x3ba51e29, (q31_t)0x8ebef7fb, (q31_t)0x3b9f8ee5, (q31_t)0x8ebc0a99, (q31_t)0x3b99ff7d, (q31_t)0x8eb91d7c, (q31_t)0x3b946ff0, (q31_t)0x8eb630a6, + (q31_t)0x3b8ee03e, (q31_t)0x8eb34415, (q31_t)0x3b895068, (q31_t)0x8eb057ca, (q31_t)0x3b83c06c, (q31_t)0x8ead6bc5, (q31_t)0x3b7e304c, (q31_t)0x8eaa8006, + (q31_t)0x3b78a007, (q31_t)0x8ea7948c, (q31_t)0x3b730f9e, (q31_t)0x8ea4a959, (q31_t)0x3b6d7f10, (q31_t)0x8ea1be6c, (q31_t)0x3b67ee5d, (q31_t)0x8e9ed3c4, + (q31_t)0x3b625d86, (q31_t)0x8e9be963, (q31_t)0x3b5ccc8a, (q31_t)0x8e98ff47, (q31_t)0x3b573b69, (q31_t)0x8e961571, (q31_t)0x3b51aa24, (q31_t)0x8e932be2, + (q31_t)0x3b4c18ba, (q31_t)0x8e904298, (q31_t)0x3b46872c, (q31_t)0x8e8d5994, (q31_t)0x3b40f579, (q31_t)0x8e8a70d7, (q31_t)0x3b3b63a1, (q31_t)0x8e87885f, + (q31_t)0x3b35d1a5, (q31_t)0x8e84a02d, (q31_t)0x3b303f84, (q31_t)0x8e81b841, (q31_t)0x3b2aad3f, (q31_t)0x8e7ed09b, (q31_t)0x3b251ad6, (q31_t)0x8e7be93c, + (q31_t)0x3b1f8848, (q31_t)0x8e790222, (q31_t)0x3b19f595, (q31_t)0x8e761b4e, (q31_t)0x3b1462be, (q31_t)0x8e7334c1, (q31_t)0x3b0ecfc3, (q31_t)0x8e704e79, + (q31_t)0x3b093ca3, (q31_t)0x8e6d6877, (q31_t)0x3b03a95e, (q31_t)0x8e6a82bc, (q31_t)0x3afe15f6, (q31_t)0x8e679d47, (q31_t)0x3af88269, (q31_t)0x8e64b817, + (q31_t)0x3af2eeb7, (q31_t)0x8e61d32e, (q31_t)0x3aed5ae1, (q31_t)0x8e5eee8b, (q31_t)0x3ae7c6e7, (q31_t)0x8e5c0a2e, (q31_t)0x3ae232c9, (q31_t)0x8e592617, + (q31_t)0x3adc9e86, (q31_t)0x8e564246, (q31_t)0x3ad70a1f, (q31_t)0x8e535ebb, (q31_t)0x3ad17593, (q31_t)0x8e507b76, (q31_t)0x3acbe0e3, (q31_t)0x8e4d9878, + (q31_t)0x3ac64c0f, (q31_t)0x8e4ab5bf, (q31_t)0x3ac0b717, (q31_t)0x8e47d34d, (q31_t)0x3abb21fb, (q31_t)0x8e44f121, (q31_t)0x3ab58cba, (q31_t)0x8e420f3b, + (q31_t)0x3aaff755, (q31_t)0x8e3f2d9b, (q31_t)0x3aaa61cc, (q31_t)0x8e3c4c41, (q31_t)0x3aa4cc1e, (q31_t)0x8e396b2e, (q31_t)0x3a9f364d, (q31_t)0x8e368a61, + (q31_t)0x3a99a057, (q31_t)0x8e33a9da, (q31_t)0x3a940a3e, (q31_t)0x8e30c999, (q31_t)0x3a8e7400, (q31_t)0x8e2de99e, (q31_t)0x3a88dd9d, (q31_t)0x8e2b09e9, + (q31_t)0x3a834717, (q31_t)0x8e282a7b, (q31_t)0x3a7db06d, (q31_t)0x8e254b53, (q31_t)0x3a78199f, (q31_t)0x8e226c71, (q31_t)0x3a7282ac, (q31_t)0x8e1f8dd6, + (q31_t)0x3a6ceb96, (q31_t)0x8e1caf80, (q31_t)0x3a67545b, (q31_t)0x8e19d171, (q31_t)0x3a61bcfd, (q31_t)0x8e16f3a9, (q31_t)0x3a5c257a, (q31_t)0x8e141626, + (q31_t)0x3a568dd4, (q31_t)0x8e1138ea, (q31_t)0x3a50f609, (q31_t)0x8e0e5bf4, (q31_t)0x3a4b5e1b, (q31_t)0x8e0b7f44, (q31_t)0x3a45c608, (q31_t)0x8e08a2db, + (q31_t)0x3a402dd2, (q31_t)0x8e05c6b7, (q31_t)0x3a3a9577, (q31_t)0x8e02eadb, (q31_t)0x3a34fcf9, (q31_t)0x8e000f44, (q31_t)0x3a2f6457, (q31_t)0x8dfd33f4, + (q31_t)0x3a29cb91, (q31_t)0x8dfa58ea, (q31_t)0x3a2432a7, (q31_t)0x8df77e27, (q31_t)0x3a1e9999, (q31_t)0x8df4a3a9, (q31_t)0x3a190068, (q31_t)0x8df1c973, + (q31_t)0x3a136712, (q31_t)0x8deeef82, (q31_t)0x3a0dcd99, (q31_t)0x8dec15d8, (q31_t)0x3a0833fc, (q31_t)0x8de93c74, (q31_t)0x3a029a3b, (q31_t)0x8de66357, + (q31_t)0x39fd0056, (q31_t)0x8de38a80, (q31_t)0x39f7664e, (q31_t)0x8de0b1ef, (q31_t)0x39f1cc21, (q31_t)0x8dddd9a5, (q31_t)0x39ec31d1, (q31_t)0x8ddb01a1, + (q31_t)0x39e6975e, (q31_t)0x8dd829e4, (q31_t)0x39e0fcc6, (q31_t)0x8dd5526d, (q31_t)0x39db620b, (q31_t)0x8dd27b3c, (q31_t)0x39d5c72c, (q31_t)0x8dcfa452, + (q31_t)0x39d02c2a, (q31_t)0x8dcccdaf, (q31_t)0x39ca9104, (q31_t)0x8dc9f751, (q31_t)0x39c4f5ba, (q31_t)0x8dc7213b, (q31_t)0x39bf5a4d, (q31_t)0x8dc44b6a, + (q31_t)0x39b9bebc, (q31_t)0x8dc175e0, (q31_t)0x39b42307, (q31_t)0x8dbea09d, (q31_t)0x39ae872f, (q31_t)0x8dbbcba0, (q31_t)0x39a8eb33, (q31_t)0x8db8f6ea, + (q31_t)0x39a34f13, (q31_t)0x8db6227a, (q31_t)0x399db2d0, (q31_t)0x8db34e50, (q31_t)0x3998166a, (q31_t)0x8db07a6d, (q31_t)0x399279e0, (q31_t)0x8dada6d1, + (q31_t)0x398cdd32, (q31_t)0x8daad37b, (q31_t)0x39874061, (q31_t)0x8da8006c, (q31_t)0x3981a36d, (q31_t)0x8da52da3, (q31_t)0x397c0655, (q31_t)0x8da25b21, + (q31_t)0x39766919, (q31_t)0x8d9f88e5, (q31_t)0x3970cbba, (q31_t)0x8d9cb6f0, (q31_t)0x396b2e38, (q31_t)0x8d99e541, (q31_t)0x39659092, (q31_t)0x8d9713d9, + (q31_t)0x395ff2c9, (q31_t)0x8d9442b8, (q31_t)0x395a54dd, (q31_t)0x8d9171dd, (q31_t)0x3954b6cd, (q31_t)0x8d8ea148, (q31_t)0x394f1899, (q31_t)0x8d8bd0fb, + (q31_t)0x39497a43, (q31_t)0x8d8900f3, (q31_t)0x3943dbc9, (q31_t)0x8d863133, (q31_t)0x393e3d2c, (q31_t)0x8d8361b9, (q31_t)0x39389e6b, (q31_t)0x8d809286, + (q31_t)0x3932ff87, (q31_t)0x8d7dc399, (q31_t)0x392d6080, (q31_t)0x8d7af4f3, (q31_t)0x3927c155, (q31_t)0x8d782694, (q31_t)0x39222208, (q31_t)0x8d75587b, + (q31_t)0x391c8297, (q31_t)0x8d728aa9, (q31_t)0x3916e303, (q31_t)0x8d6fbd1d, (q31_t)0x3911434b, (q31_t)0x8d6cefd9, (q31_t)0x390ba371, (q31_t)0x8d6a22db, + (q31_t)0x39060373, (q31_t)0x8d675623, (q31_t)0x39006352, (q31_t)0x8d6489b3, (q31_t)0x38fac30e, (q31_t)0x8d61bd89, (q31_t)0x38f522a6, (q31_t)0x8d5ef1a5, + (q31_t)0x38ef821c, (q31_t)0x8d5c2609, (q31_t)0x38e9e16e, (q31_t)0x8d595ab3, (q31_t)0x38e4409e, (q31_t)0x8d568fa4, (q31_t)0x38de9faa, (q31_t)0x8d53c4db, + (q31_t)0x38d8fe93, (q31_t)0x8d50fa59, (q31_t)0x38d35d59, (q31_t)0x8d4e301f, (q31_t)0x38cdbbfc, (q31_t)0x8d4b662a, (q31_t)0x38c81a7c, (q31_t)0x8d489c7d, + (q31_t)0x38c278d9, (q31_t)0x8d45d316, (q31_t)0x38bcd713, (q31_t)0x8d4309f6, (q31_t)0x38b7352a, (q31_t)0x8d40411d, (q31_t)0x38b1931e, (q31_t)0x8d3d788b, + (q31_t)0x38abf0ef, (q31_t)0x8d3ab03f, (q31_t)0x38a64e9d, (q31_t)0x8d37e83a, (q31_t)0x38a0ac29, (q31_t)0x8d35207d, (q31_t)0x389b0991, (q31_t)0x8d325905, + (q31_t)0x389566d6, (q31_t)0x8d2f91d5, (q31_t)0x388fc3f8, (q31_t)0x8d2ccaec, (q31_t)0x388a20f8, (q31_t)0x8d2a0449, (q31_t)0x38847dd5, (q31_t)0x8d273ded, + (q31_t)0x387eda8e, (q31_t)0x8d2477d8, (q31_t)0x38793725, (q31_t)0x8d21b20a, (q31_t)0x38739399, (q31_t)0x8d1eec83, (q31_t)0x386defeb, (q31_t)0x8d1c2742, + (q31_t)0x38684c19, (q31_t)0x8d196249, (q31_t)0x3862a825, (q31_t)0x8d169d96, (q31_t)0x385d040d, (q31_t)0x8d13d92a, (q31_t)0x38575fd4, (q31_t)0x8d111505, + (q31_t)0x3851bb77, (q31_t)0x8d0e5127, (q31_t)0x384c16f7, (q31_t)0x8d0b8d90, (q31_t)0x38467255, (q31_t)0x8d08ca40, (q31_t)0x3840cd90, (q31_t)0x8d060737, + (q31_t)0x383b28a9, (q31_t)0x8d034474, (q31_t)0x3835839f, (q31_t)0x8d0081f9, (q31_t)0x382fde72, (q31_t)0x8cfdbfc4, (q31_t)0x382a3922, (q31_t)0x8cfafdd7, + (q31_t)0x382493b0, (q31_t)0x8cf83c30, (q31_t)0x381eee1b, (q31_t)0x8cf57ad0, (q31_t)0x38194864, (q31_t)0x8cf2b9b8, (q31_t)0x3813a28a, (q31_t)0x8ceff8e6, + (q31_t)0x380dfc8d, (q31_t)0x8ced385b, (q31_t)0x3808566e, (q31_t)0x8cea7818, (q31_t)0x3802b02c, (q31_t)0x8ce7b81b, (q31_t)0x37fd09c8, (q31_t)0x8ce4f865, + (q31_t)0x37f76341, (q31_t)0x8ce238f6, (q31_t)0x37f1bc97, (q31_t)0x8cdf79ce, (q31_t)0x37ec15cb, (q31_t)0x8cdcbaee, (q31_t)0x37e66edd, (q31_t)0x8cd9fc54, + (q31_t)0x37e0c7cc, (q31_t)0x8cd73e01, (q31_t)0x37db2099, (q31_t)0x8cd47ff6, (q31_t)0x37d57943, (q31_t)0x8cd1c231, (q31_t)0x37cfd1cb, (q31_t)0x8ccf04b3, + (q31_t)0x37ca2a30, (q31_t)0x8ccc477d, (q31_t)0x37c48273, (q31_t)0x8cc98a8e, (q31_t)0x37beda93, (q31_t)0x8cc6cde5, (q31_t)0x37b93292, (q31_t)0x8cc41184, + (q31_t)0x37b38a6d, (q31_t)0x8cc1556a, (q31_t)0x37ade227, (q31_t)0x8cbe9996, (q31_t)0x37a839be, (q31_t)0x8cbbde0a, (q31_t)0x37a29132, (q31_t)0x8cb922c6, + (q31_t)0x379ce885, (q31_t)0x8cb667c8, (q31_t)0x37973fb5, (q31_t)0x8cb3ad11, (q31_t)0x379196c3, (q31_t)0x8cb0f2a1, (q31_t)0x378bedae, (q31_t)0x8cae3879, + (q31_t)0x37864477, (q31_t)0x8cab7e98, (q31_t)0x37809b1e, (q31_t)0x8ca8c4fd, (q31_t)0x377af1a3, (q31_t)0x8ca60baa, (q31_t)0x37754806, (q31_t)0x8ca3529f, + (q31_t)0x376f9e46, (q31_t)0x8ca099da, (q31_t)0x3769f464, (q31_t)0x8c9de15c, (q31_t)0x37644a60, (q31_t)0x8c9b2926, (q31_t)0x375ea03a, (q31_t)0x8c987137, + (q31_t)0x3758f5f2, (q31_t)0x8c95b98f, (q31_t)0x37534b87, (q31_t)0x8c93022e, (q31_t)0x374da0fa, (q31_t)0x8c904b14, (q31_t)0x3747f64c, (q31_t)0x8c8d9442, + (q31_t)0x37424b7b, (q31_t)0x8c8addb7, (q31_t)0x373ca088, (q31_t)0x8c882773, (q31_t)0x3736f573, (q31_t)0x8c857176, (q31_t)0x37314a3c, (q31_t)0x8c82bbc0, + (q31_t)0x372b9ee3, (q31_t)0x8c800652, (q31_t)0x3725f367, (q31_t)0x8c7d512b, (q31_t)0x372047ca, (q31_t)0x8c7a9c4b, (q31_t)0x371a9c0b, (q31_t)0x8c77e7b3, + (q31_t)0x3714f02a, (q31_t)0x8c753362, (q31_t)0x370f4427, (q31_t)0x8c727f58, (q31_t)0x37099802, (q31_t)0x8c6fcb95, (q31_t)0x3703ebbb, (q31_t)0x8c6d181a, + (q31_t)0x36fe3f52, (q31_t)0x8c6a64e5, (q31_t)0x36f892c7, (q31_t)0x8c67b1f9, (q31_t)0x36f2e61a, (q31_t)0x8c64ff53, (q31_t)0x36ed394b, (q31_t)0x8c624cf5, + (q31_t)0x36e78c5b, (q31_t)0x8c5f9ade, (q31_t)0x36e1df48, (q31_t)0x8c5ce90e, (q31_t)0x36dc3214, (q31_t)0x8c5a3786, (q31_t)0x36d684be, (q31_t)0x8c578645, + (q31_t)0x36d0d746, (q31_t)0x8c54d54c, (q31_t)0x36cb29ac, (q31_t)0x8c522499, (q31_t)0x36c57bf0, (q31_t)0x8c4f742f, (q31_t)0x36bfce13, (q31_t)0x8c4cc40b, + (q31_t)0x36ba2014, (q31_t)0x8c4a142f, (q31_t)0x36b471f3, (q31_t)0x8c47649a, (q31_t)0x36aec3b0, (q31_t)0x8c44b54d, (q31_t)0x36a9154c, (q31_t)0x8c420647, + (q31_t)0x36a366c6, (q31_t)0x8c3f5788, (q31_t)0x369db81e, (q31_t)0x8c3ca911, (q31_t)0x36980954, (q31_t)0x8c39fae1, (q31_t)0x36925a69, (q31_t)0x8c374cf9, + (q31_t)0x368cab5c, (q31_t)0x8c349f58, (q31_t)0x3686fc2e, (q31_t)0x8c31f1ff, (q31_t)0x36814cde, (q31_t)0x8c2f44ed, (q31_t)0x367b9d6c, (q31_t)0x8c2c9822, + (q31_t)0x3675edd9, (q31_t)0x8c29eb9f, (q31_t)0x36703e24, (q31_t)0x8c273f63, (q31_t)0x366a8e4d, (q31_t)0x8c24936f, (q31_t)0x3664de55, (q31_t)0x8c21e7c2, + (q31_t)0x365f2e3b, (q31_t)0x8c1f3c5d, (q31_t)0x36597e00, (q31_t)0x8c1c913f, (q31_t)0x3653cda3, (q31_t)0x8c19e669, (q31_t)0x364e1d25, (q31_t)0x8c173bda, + (q31_t)0x36486c86, (q31_t)0x8c149192, (q31_t)0x3642bbc4, (q31_t)0x8c11e792, (q31_t)0x363d0ae2, (q31_t)0x8c0f3dda, (q31_t)0x363759de, (q31_t)0x8c0c9469, + (q31_t)0x3631a8b8, (q31_t)0x8c09eb40, (q31_t)0x362bf771, (q31_t)0x8c07425e, (q31_t)0x36264609, (q31_t)0x8c0499c4, (q31_t)0x3620947f, (q31_t)0x8c01f171, + (q31_t)0x361ae2d3, (q31_t)0x8bff4966, (q31_t)0x36153107, (q31_t)0x8bfca1a3, (q31_t)0x360f7f19, (q31_t)0x8bf9fa27, (q31_t)0x3609cd0a, (q31_t)0x8bf752f2, + (q31_t)0x36041ad9, (q31_t)0x8bf4ac05, (q31_t)0x35fe6887, (q31_t)0x8bf20560, (q31_t)0x35f8b614, (q31_t)0x8bef5f02, (q31_t)0x35f3037f, (q31_t)0x8becb8ec, + (q31_t)0x35ed50c9, (q31_t)0x8bea131e, (q31_t)0x35e79df2, (q31_t)0x8be76d97, (q31_t)0x35e1eafa, (q31_t)0x8be4c857, (q31_t)0x35dc37e0, (q31_t)0x8be22360, + (q31_t)0x35d684a6, (q31_t)0x8bdf7eb0, (q31_t)0x35d0d14a, (q31_t)0x8bdcda47, (q31_t)0x35cb1dcc, (q31_t)0x8bda3626, (q31_t)0x35c56a2e, (q31_t)0x8bd7924d, + (q31_t)0x35bfb66e, (q31_t)0x8bd4eebc, (q31_t)0x35ba028e, (q31_t)0x8bd24b72, (q31_t)0x35b44e8c, (q31_t)0x8bcfa870, (q31_t)0x35ae9a69, (q31_t)0x8bcd05b5, + (q31_t)0x35a8e625, (q31_t)0x8bca6343, (q31_t)0x35a331c0, (q31_t)0x8bc7c117, (q31_t)0x359d7d39, (q31_t)0x8bc51f34, (q31_t)0x3597c892, (q31_t)0x8bc27d98, + (q31_t)0x359213c9, (q31_t)0x8bbfdc44, (q31_t)0x358c5ee0, (q31_t)0x8bbd3b38, (q31_t)0x3586a9d5, (q31_t)0x8bba9a73, (q31_t)0x3580f4aa, (q31_t)0x8bb7f9f6, + (q31_t)0x357b3f5d, (q31_t)0x8bb559c1, (q31_t)0x357589f0, (q31_t)0x8bb2b9d4, (q31_t)0x356fd461, (q31_t)0x8bb01a2e, (q31_t)0x356a1eb2, (q31_t)0x8bad7ad0, + (q31_t)0x356468e2, (q31_t)0x8baadbba, (q31_t)0x355eb2f0, (q31_t)0x8ba83cec, (q31_t)0x3558fcde, (q31_t)0x8ba59e65, (q31_t)0x355346ab, (q31_t)0x8ba30026, + (q31_t)0x354d9057, (q31_t)0x8ba0622f, (q31_t)0x3547d9e2, (q31_t)0x8b9dc480, (q31_t)0x3542234c, (q31_t)0x8b9b2718, (q31_t)0x353c6c95, (q31_t)0x8b9889f8, + (q31_t)0x3536b5be, (q31_t)0x8b95ed21, (q31_t)0x3530fec6, (q31_t)0x8b935090, (q31_t)0x352b47ad, (q31_t)0x8b90b448, (q31_t)0x35259073, (q31_t)0x8b8e1848, + (q31_t)0x351fd918, (q31_t)0x8b8b7c8f, (q31_t)0x351a219c, (q31_t)0x8b88e11e, (q31_t)0x35146a00, (q31_t)0x8b8645f5, (q31_t)0x350eb243, (q31_t)0x8b83ab14, + (q31_t)0x3508fa66, (q31_t)0x8b81107b, (q31_t)0x35034267, (q31_t)0x8b7e7629, (q31_t)0x34fd8a48, (q31_t)0x8b7bdc20, (q31_t)0x34f7d208, (q31_t)0x8b79425e, + (q31_t)0x34f219a8, (q31_t)0x8b76a8e4, (q31_t)0x34ec6127, (q31_t)0x8b740fb3, (q31_t)0x34e6a885, (q31_t)0x8b7176c8, (q31_t)0x34e0efc2, (q31_t)0x8b6ede26, + (q31_t)0x34db36df, (q31_t)0x8b6c45cc, (q31_t)0x34d57ddc, (q31_t)0x8b69adba, (q31_t)0x34cfc4b7, (q31_t)0x8b6715ef, (q31_t)0x34ca0b73, (q31_t)0x8b647e6d, + (q31_t)0x34c4520d, (q31_t)0x8b61e733, (q31_t)0x34be9887, (q31_t)0x8b5f5040, (q31_t)0x34b8dee1, (q31_t)0x8b5cb995, (q31_t)0x34b3251a, (q31_t)0x8b5a2333, + (q31_t)0x34ad6b32, (q31_t)0x8b578d18, (q31_t)0x34a7b12a, (q31_t)0x8b54f745, (q31_t)0x34a1f702, (q31_t)0x8b5261ba, (q31_t)0x349c3cb9, (q31_t)0x8b4fcc77, + (q31_t)0x34968250, (q31_t)0x8b4d377c, (q31_t)0x3490c7c6, (q31_t)0x8b4aa2ca, (q31_t)0x348b0d1c, (q31_t)0x8b480e5f, (q31_t)0x34855251, (q31_t)0x8b457a3c, + (q31_t)0x347f9766, (q31_t)0x8b42e661, (q31_t)0x3479dc5b, (q31_t)0x8b4052ce, (q31_t)0x3474212f, (q31_t)0x8b3dbf83, (q31_t)0x346e65e3, (q31_t)0x8b3b2c80, + (q31_t)0x3468aa76, (q31_t)0x8b3899c6, (q31_t)0x3462eee9, (q31_t)0x8b360753, (q31_t)0x345d333c, (q31_t)0x8b337528, (q31_t)0x3457776f, (q31_t)0x8b30e345, + (q31_t)0x3451bb81, (q31_t)0x8b2e51ab, (q31_t)0x344bff73, (q31_t)0x8b2bc058, (q31_t)0x34464345, (q31_t)0x8b292f4e, (q31_t)0x344086f6, (q31_t)0x8b269e8b, + (q31_t)0x343aca87, (q31_t)0x8b240e11, (q31_t)0x34350df8, (q31_t)0x8b217ddf, (q31_t)0x342f5149, (q31_t)0x8b1eedf4, (q31_t)0x3429947a, (q31_t)0x8b1c5e52, + (q31_t)0x3423d78a, (q31_t)0x8b19cef8, (q31_t)0x341e1a7b, (q31_t)0x8b173fe6, (q31_t)0x34185d4b, (q31_t)0x8b14b11d, (q31_t)0x34129ffb, (q31_t)0x8b12229b, + (q31_t)0x340ce28b, (q31_t)0x8b0f9462, (q31_t)0x340724fb, (q31_t)0x8b0d0670, (q31_t)0x3401674a, (q31_t)0x8b0a78c7, (q31_t)0x33fba97a, (q31_t)0x8b07eb66, + (q31_t)0x33f5eb89, (q31_t)0x8b055e4d, (q31_t)0x33f02d79, (q31_t)0x8b02d17c, (q31_t)0x33ea6f48, (q31_t)0x8b0044f3, (q31_t)0x33e4b0f8, (q31_t)0x8afdb8b3, + (q31_t)0x33def287, (q31_t)0x8afb2cbb, (q31_t)0x33d933f7, (q31_t)0x8af8a10b, (q31_t)0x33d37546, (q31_t)0x8af615a3, (q31_t)0x33cdb676, (q31_t)0x8af38a83, + (q31_t)0x33c7f785, (q31_t)0x8af0ffac, (q31_t)0x33c23875, (q31_t)0x8aee751c, (q31_t)0x33bc7944, (q31_t)0x8aebead5, (q31_t)0x33b6b9f4, (q31_t)0x8ae960d6, + (q31_t)0x33b0fa84, (q31_t)0x8ae6d720, (q31_t)0x33ab3af4, (q31_t)0x8ae44db1, (q31_t)0x33a57b44, (q31_t)0x8ae1c48b, (q31_t)0x339fbb74, (q31_t)0x8adf3bad, + (q31_t)0x3399fb85, (q31_t)0x8adcb318, (q31_t)0x33943b75, (q31_t)0x8ada2aca, (q31_t)0x338e7b46, (q31_t)0x8ad7a2c5, (q31_t)0x3388baf7, (q31_t)0x8ad51b08, + (q31_t)0x3382fa88, (q31_t)0x8ad29394, (q31_t)0x337d39f9, (q31_t)0x8ad00c67, (q31_t)0x3377794b, (q31_t)0x8acd8583, (q31_t)0x3371b87d, (q31_t)0x8acafee8, + (q31_t)0x336bf78f, (q31_t)0x8ac87894, (q31_t)0x33663682, (q31_t)0x8ac5f289, (q31_t)0x33607554, (q31_t)0x8ac36cc6, (q31_t)0x335ab407, (q31_t)0x8ac0e74c, + (q31_t)0x3354f29b, (q31_t)0x8abe6219, (q31_t)0x334f310e, (q31_t)0x8abbdd30, (q31_t)0x33496f62, (q31_t)0x8ab9588e, (q31_t)0x3343ad97, (q31_t)0x8ab6d435, + (q31_t)0x333debab, (q31_t)0x8ab45024, (q31_t)0x333829a1, (q31_t)0x8ab1cc5c, (q31_t)0x33326776, (q31_t)0x8aaf48db, (q31_t)0x332ca52c, (q31_t)0x8aacc5a4, + (q31_t)0x3326e2c3, (q31_t)0x8aaa42b4, (q31_t)0x33212039, (q31_t)0x8aa7c00d, (q31_t)0x331b5d91, (q31_t)0x8aa53daf, (q31_t)0x33159ac8, (q31_t)0x8aa2bb99, + (q31_t)0x330fd7e1, (q31_t)0x8aa039cb, (q31_t)0x330a14da, (q31_t)0x8a9db845, (q31_t)0x330451b3, (q31_t)0x8a9b3708, (q31_t)0x32fe8e6d, (q31_t)0x8a98b614, + (q31_t)0x32f8cb07, (q31_t)0x8a963567, (q31_t)0x32f30782, (q31_t)0x8a93b504, (q31_t)0x32ed43de, (q31_t)0x8a9134e8, (q31_t)0x32e7801a, (q31_t)0x8a8eb516, + (q31_t)0x32e1bc36, (q31_t)0x8a8c358b, (q31_t)0x32dbf834, (q31_t)0x8a89b649, (q31_t)0x32d63412, (q31_t)0x8a873750, (q31_t)0x32d06fd0, (q31_t)0x8a84b89e, + (q31_t)0x32caab6f, (q31_t)0x8a823a36, (q31_t)0x32c4e6ef, (q31_t)0x8a7fbc16, (q31_t)0x32bf2250, (q31_t)0x8a7d3e3e, (q31_t)0x32b95d91, (q31_t)0x8a7ac0af, + (q31_t)0x32b398b3, (q31_t)0x8a784368, (q31_t)0x32add3b6, (q31_t)0x8a75c66a, (q31_t)0x32a80e99, (q31_t)0x8a7349b4, (q31_t)0x32a2495d, (q31_t)0x8a70cd47, + (q31_t)0x329c8402, (q31_t)0x8a6e5123, (q31_t)0x3296be88, (q31_t)0x8a6bd547, (q31_t)0x3290f8ef, (q31_t)0x8a6959b3, (q31_t)0x328b3336, (q31_t)0x8a66de68, + (q31_t)0x32856d5e, (q31_t)0x8a646365, (q31_t)0x327fa767, (q31_t)0x8a61e8ab, (q31_t)0x3279e151, (q31_t)0x8a5f6e3a, (q31_t)0x32741b1c, (q31_t)0x8a5cf411, + (q31_t)0x326e54c7, (q31_t)0x8a5a7a31, (q31_t)0x32688e54, (q31_t)0x8a580099, (q31_t)0x3262c7c1, (q31_t)0x8a55874a, (q31_t)0x325d0110, (q31_t)0x8a530e43, + (q31_t)0x32573a3f, (q31_t)0x8a509585, (q31_t)0x3251734f, (q31_t)0x8a4e1d10, (q31_t)0x324bac40, (q31_t)0x8a4ba4e3, (q31_t)0x3245e512, (q31_t)0x8a492cff, + (q31_t)0x32401dc6, (q31_t)0x8a46b564, (q31_t)0x323a565a, (q31_t)0x8a443e11, (q31_t)0x32348ecf, (q31_t)0x8a41c706, (q31_t)0x322ec725, (q31_t)0x8a3f5045, + (q31_t)0x3228ff5c, (q31_t)0x8a3cd9cc, (q31_t)0x32233775, (q31_t)0x8a3a639b, (q31_t)0x321d6f6e, (q31_t)0x8a37edb3, (q31_t)0x3217a748, (q31_t)0x8a357814, + (q31_t)0x3211df04, (q31_t)0x8a3302be, (q31_t)0x320c16a1, (q31_t)0x8a308db0, (q31_t)0x32064e1e, (q31_t)0x8a2e18eb, (q31_t)0x3200857d, (q31_t)0x8a2ba46e, + (q31_t)0x31fabcbd, (q31_t)0x8a29303b, (q31_t)0x31f4f3df, (q31_t)0x8a26bc50, (q31_t)0x31ef2ae1, (q31_t)0x8a2448ad, (q31_t)0x31e961c5, (q31_t)0x8a21d554, + (q31_t)0x31e39889, (q31_t)0x8a1f6243, (q31_t)0x31ddcf30, (q31_t)0x8a1cef7a, (q31_t)0x31d805b7, (q31_t)0x8a1a7cfb, (q31_t)0x31d23c1f, (q31_t)0x8a180ac4, + (q31_t)0x31cc7269, (q31_t)0x8a1598d6, (q31_t)0x31c6a894, (q31_t)0x8a132731, (q31_t)0x31c0dea1, (q31_t)0x8a10b5d4, (q31_t)0x31bb148f, (q31_t)0x8a0e44c0, + (q31_t)0x31b54a5e, (q31_t)0x8a0bd3f5, (q31_t)0x31af800e, (q31_t)0x8a096373, (q31_t)0x31a9b5a0, (q31_t)0x8a06f339, (q31_t)0x31a3eb13, (q31_t)0x8a048348, + (q31_t)0x319e2067, (q31_t)0x8a0213a0, (q31_t)0x3198559d, (q31_t)0x89ffa441, (q31_t)0x31928ab4, (q31_t)0x89fd352b, (q31_t)0x318cbfad, (q31_t)0x89fac65d, + (q31_t)0x3186f487, (q31_t)0x89f857d8, (q31_t)0x31812943, (q31_t)0x89f5e99c, (q31_t)0x317b5de0, (q31_t)0x89f37ba9, (q31_t)0x3175925e, (q31_t)0x89f10dff, + (q31_t)0x316fc6be, (q31_t)0x89eea09d, (q31_t)0x3169fb00, (q31_t)0x89ec3384, (q31_t)0x31642f23, (q31_t)0x89e9c6b4, (q31_t)0x315e6328, (q31_t)0x89e75a2d, + (q31_t)0x3158970e, (q31_t)0x89e4edef, (q31_t)0x3152cad5, (q31_t)0x89e281fa, (q31_t)0x314cfe7f, (q31_t)0x89e0164d, (q31_t)0x31473209, (q31_t)0x89ddaae9, + (q31_t)0x31416576, (q31_t)0x89db3fcf, (q31_t)0x313b98c4, (q31_t)0x89d8d4fd, (q31_t)0x3135cbf4, (q31_t)0x89d66a74, (q31_t)0x312fff05, (q31_t)0x89d40033, + (q31_t)0x312a31f8, (q31_t)0x89d1963c, (q31_t)0x312464cd, (q31_t)0x89cf2c8e, (q31_t)0x311e9783, (q31_t)0x89ccc328, (q31_t)0x3118ca1b, (q31_t)0x89ca5a0c, + (q31_t)0x3112fc95, (q31_t)0x89c7f138, (q31_t)0x310d2ef0, (q31_t)0x89c588ae, (q31_t)0x3107612e, (q31_t)0x89c3206c, (q31_t)0x3101934d, (q31_t)0x89c0b873, + (q31_t)0x30fbc54d, (q31_t)0x89be50c3, (q31_t)0x30f5f730, (q31_t)0x89bbe95c, (q31_t)0x30f028f4, (q31_t)0x89b9823e, (q31_t)0x30ea5a9a, (q31_t)0x89b71b69, + (q31_t)0x30e48c22, (q31_t)0x89b4b4dd, (q31_t)0x30debd8c, (q31_t)0x89b24e9a, (q31_t)0x30d8eed8, (q31_t)0x89afe8a0, (q31_t)0x30d32006, (q31_t)0x89ad82ef, + (q31_t)0x30cd5115, (q31_t)0x89ab1d87, (q31_t)0x30c78206, (q31_t)0x89a8b868, (q31_t)0x30c1b2da, (q31_t)0x89a65391, (q31_t)0x30bbe38f, (q31_t)0x89a3ef04, + (q31_t)0x30b61426, (q31_t)0x89a18ac0, (q31_t)0x30b0449f, (q31_t)0x899f26c5, (q31_t)0x30aa74fa, (q31_t)0x899cc313, (q31_t)0x30a4a537, (q31_t)0x899a5faa, + (q31_t)0x309ed556, (q31_t)0x8997fc8a, (q31_t)0x30990557, (q31_t)0x899599b3, (q31_t)0x3093353a, (q31_t)0x89933725, (q31_t)0x308d64ff, (q31_t)0x8990d4e0, + (q31_t)0x308794a6, (q31_t)0x898e72e4, (q31_t)0x3081c42f, (q31_t)0x898c1131, (q31_t)0x307bf39b, (q31_t)0x8989afc8, (q31_t)0x307622e8, (q31_t)0x89874ea7, + (q31_t)0x30705217, (q31_t)0x8984edcf, (q31_t)0x306a8129, (q31_t)0x89828d41, (q31_t)0x3064b01d, (q31_t)0x89802cfc, (q31_t)0x305edef3, (q31_t)0x897dccff, + (q31_t)0x30590dab, (q31_t)0x897b6d4c, (q31_t)0x30533c45, (q31_t)0x89790de2, (q31_t)0x304d6ac1, (q31_t)0x8976aec1, (q31_t)0x30479920, (q31_t)0x89744fe9, + (q31_t)0x3041c761, (q31_t)0x8971f15a, (q31_t)0x303bf584, (q31_t)0x896f9315, (q31_t)0x30362389, (q31_t)0x896d3518, (q31_t)0x30305171, (q31_t)0x896ad765, + (q31_t)0x302a7f3a, (q31_t)0x896879fb, (q31_t)0x3024ace6, (q31_t)0x89661cda, (q31_t)0x301eda75, (q31_t)0x8963c002, (q31_t)0x301907e6, (q31_t)0x89616373, + (q31_t)0x30133539, (q31_t)0x895f072e, (q31_t)0x300d626e, (q31_t)0x895cab31, (q31_t)0x30078f86, (q31_t)0x895a4f7e, (q31_t)0x3001bc80, (q31_t)0x8957f414, + (q31_t)0x2ffbe95d, (q31_t)0x895598f3, (q31_t)0x2ff6161c, (q31_t)0x89533e1c, (q31_t)0x2ff042bd, (q31_t)0x8950e38e, (q31_t)0x2fea6f41, (q31_t)0x894e8948, + (q31_t)0x2fe49ba7, (q31_t)0x894c2f4c, (q31_t)0x2fdec7f0, (q31_t)0x8949d59a, (q31_t)0x2fd8f41b, (q31_t)0x89477c30, (q31_t)0x2fd32028, (q31_t)0x89452310, + (q31_t)0x2fcd4c19, (q31_t)0x8942ca39, (q31_t)0x2fc777eb, (q31_t)0x894071ab, (q31_t)0x2fc1a3a0, (q31_t)0x893e1967, (q31_t)0x2fbbcf38, (q31_t)0x893bc16b, + (q31_t)0x2fb5fab2, (q31_t)0x893969b9, (q31_t)0x2fb0260f, (q31_t)0x89371250, (q31_t)0x2faa514f, (q31_t)0x8934bb31, (q31_t)0x2fa47c71, (q31_t)0x8932645b, + (q31_t)0x2f9ea775, (q31_t)0x89300dce, (q31_t)0x2f98d25d, (q31_t)0x892db78a, (q31_t)0x2f92fd26, (q31_t)0x892b6190, (q31_t)0x2f8d27d3, (q31_t)0x89290bdf, + (q31_t)0x2f875262, (q31_t)0x8926b677, (q31_t)0x2f817cd4, (q31_t)0x89246159, (q31_t)0x2f7ba729, (q31_t)0x89220c84, (q31_t)0x2f75d160, (q31_t)0x891fb7f8, + (q31_t)0x2f6ffb7a, (q31_t)0x891d63b5, (q31_t)0x2f6a2577, (q31_t)0x891b0fbc, (q31_t)0x2f644f56, (q31_t)0x8918bc0c, (q31_t)0x2f5e7919, (q31_t)0x891668a6, + (q31_t)0x2f58a2be, (q31_t)0x89141589, (q31_t)0x2f52cc46, (q31_t)0x8911c2b5, (q31_t)0x2f4cf5b0, (q31_t)0x890f702b, (q31_t)0x2f471efe, (q31_t)0x890d1dea, + (q31_t)0x2f41482e, (q31_t)0x890acbf2, (q31_t)0x2f3b7141, (q31_t)0x89087a44, (q31_t)0x2f359a37, (q31_t)0x890628df, (q31_t)0x2f2fc310, (q31_t)0x8903d7c4, + (q31_t)0x2f29ebcc, (q31_t)0x890186f2, (q31_t)0x2f24146b, (q31_t)0x88ff3669, (q31_t)0x2f1e3ced, (q31_t)0x88fce62a, (q31_t)0x2f186551, (q31_t)0x88fa9634, + (q31_t)0x2f128d99, (q31_t)0x88f84687, (q31_t)0x2f0cb5c3, (q31_t)0x88f5f724, (q31_t)0x2f06ddd1, (q31_t)0x88f3a80b, (q31_t)0x2f0105c1, (q31_t)0x88f1593b, + (q31_t)0x2efb2d95, (q31_t)0x88ef0ab4, (q31_t)0x2ef5554b, (q31_t)0x88ecbc77, (q31_t)0x2eef7ce5, (q31_t)0x88ea6e83, (q31_t)0x2ee9a461, (q31_t)0x88e820d9, + (q31_t)0x2ee3cbc1, (q31_t)0x88e5d378, (q31_t)0x2eddf304, (q31_t)0x88e38660, (q31_t)0x2ed81a29, (q31_t)0x88e13992, (q31_t)0x2ed24132, (q31_t)0x88deed0e, + (q31_t)0x2ecc681e, (q31_t)0x88dca0d3, (q31_t)0x2ec68eed, (q31_t)0x88da54e1, (q31_t)0x2ec0b5a0, (q31_t)0x88d8093a, (q31_t)0x2ebadc35, (q31_t)0x88d5bddb, + (q31_t)0x2eb502ae, (q31_t)0x88d372c6, (q31_t)0x2eaf290a, (q31_t)0x88d127fb, (q31_t)0x2ea94f49, (q31_t)0x88cedd79, (q31_t)0x2ea3756b, (q31_t)0x88cc9340, + (q31_t)0x2e9d9b70, (q31_t)0x88ca4951, (q31_t)0x2e97c159, (q31_t)0x88c7ffac, (q31_t)0x2e91e725, (q31_t)0x88c5b650, (q31_t)0x2e8c0cd4, (q31_t)0x88c36d3e, + (q31_t)0x2e863267, (q31_t)0x88c12475, (q31_t)0x2e8057dd, (q31_t)0x88bedbf6, (q31_t)0x2e7a7d36, (q31_t)0x88bc93c0, (q31_t)0x2e74a272, (q31_t)0x88ba4bd4, + (q31_t)0x2e6ec792, (q31_t)0x88b80432, (q31_t)0x2e68ec95, (q31_t)0x88b5bcd9, (q31_t)0x2e63117c, (q31_t)0x88b375ca, (q31_t)0x2e5d3646, (q31_t)0x88b12f04, + (q31_t)0x2e575af3, (q31_t)0x88aee888, (q31_t)0x2e517f84, (q31_t)0x88aca255, (q31_t)0x2e4ba3f8, (q31_t)0x88aa5c6c, (q31_t)0x2e45c850, (q31_t)0x88a816cd, + (q31_t)0x2e3fec8b, (q31_t)0x88a5d177, (q31_t)0x2e3a10aa, (q31_t)0x88a38c6b, (q31_t)0x2e3434ac, (q31_t)0x88a147a9, (q31_t)0x2e2e5891, (q31_t)0x889f0330, + (q31_t)0x2e287c5a, (q31_t)0x889cbf01, (q31_t)0x2e22a007, (q31_t)0x889a7b1b, (q31_t)0x2e1cc397, (q31_t)0x88983780, (q31_t)0x2e16e70b, (q31_t)0x8895f42d, + (q31_t)0x2e110a62, (q31_t)0x8893b125, (q31_t)0x2e0b2d9d, (q31_t)0x88916e66, (q31_t)0x2e0550bb, (q31_t)0x888f2bf1, (q31_t)0x2dff73bd, (q31_t)0x888ce9c5, + (q31_t)0x2df996a3, (q31_t)0x888aa7e3, (q31_t)0x2df3b96c, (q31_t)0x8888664b, (q31_t)0x2deddc19, (q31_t)0x888624fd, (q31_t)0x2de7feaa, (q31_t)0x8883e3f8, + (q31_t)0x2de2211e, (q31_t)0x8881a33d, (q31_t)0x2ddc4376, (q31_t)0x887f62cb, (q31_t)0x2dd665b2, (q31_t)0x887d22a4, (q31_t)0x2dd087d1, (q31_t)0x887ae2c6, + (q31_t)0x2dcaa9d5, (q31_t)0x8878a332, (q31_t)0x2dc4cbbc, (q31_t)0x887663e7, (q31_t)0x2dbeed86, (q31_t)0x887424e7, (q31_t)0x2db90f35, (q31_t)0x8871e630, + (q31_t)0x2db330c7, (q31_t)0x886fa7c2, (q31_t)0x2dad523d, (q31_t)0x886d699f, (q31_t)0x2da77397, (q31_t)0x886b2bc5, (q31_t)0x2da194d5, (q31_t)0x8868ee35, + (q31_t)0x2d9bb5f6, (q31_t)0x8866b0ef, (q31_t)0x2d95d6fc, (q31_t)0x886473f2, (q31_t)0x2d8ff7e5, (q31_t)0x88623740, (q31_t)0x2d8a18b3, (q31_t)0x885ffad7, + (q31_t)0x2d843964, (q31_t)0x885dbeb8, (q31_t)0x2d7e59f9, (q31_t)0x885b82e3, (q31_t)0x2d787a72, (q31_t)0x88594757, (q31_t)0x2d729acf, (q31_t)0x88570c16, + (q31_t)0x2d6cbb10, (q31_t)0x8854d11e, (q31_t)0x2d66db35, (q31_t)0x88529670, (q31_t)0x2d60fb3e, (q31_t)0x88505c0b, (q31_t)0x2d5b1b2b, (q31_t)0x884e21f1, + (q31_t)0x2d553afc, (q31_t)0x884be821, (q31_t)0x2d4f5ab1, (q31_t)0x8849ae9a, (q31_t)0x2d497a4a, (q31_t)0x8847755d, (q31_t)0x2d4399c7, (q31_t)0x88453c6a, + (q31_t)0x2d3db928, (q31_t)0x884303c1, (q31_t)0x2d37d86d, (q31_t)0x8840cb61, (q31_t)0x2d31f797, (q31_t)0x883e934c, (q31_t)0x2d2c16a4, (q31_t)0x883c5b81, + (q31_t)0x2d263596, (q31_t)0x883a23ff, (q31_t)0x2d20546b, (q31_t)0x8837ecc7, (q31_t)0x2d1a7325, (q31_t)0x8835b5d9, (q31_t)0x2d1491c4, (q31_t)0x88337f35, + (q31_t)0x2d0eb046, (q31_t)0x883148db, (q31_t)0x2d08ceac, (q31_t)0x882f12cb, (q31_t)0x2d02ecf7, (q31_t)0x882cdd04, (q31_t)0x2cfd0b26, (q31_t)0x882aa788, + (q31_t)0x2cf72939, (q31_t)0x88287256, (q31_t)0x2cf14731, (q31_t)0x88263d6d, (q31_t)0x2ceb650d, (q31_t)0x882408ce, (q31_t)0x2ce582cd, (q31_t)0x8821d47a, + (q31_t)0x2cdfa071, (q31_t)0x881fa06f, (q31_t)0x2cd9bdfa, (q31_t)0x881d6cae, (q31_t)0x2cd3db67, (q31_t)0x881b3937, (q31_t)0x2ccdf8b8, (q31_t)0x8819060a, + (q31_t)0x2cc815ee, (q31_t)0x8816d327, (q31_t)0x2cc23308, (q31_t)0x8814a08f, (q31_t)0x2cbc5006, (q31_t)0x88126e40, (q31_t)0x2cb66ce9, (q31_t)0x88103c3b, + (q31_t)0x2cb089b1, (q31_t)0x880e0a7f, (q31_t)0x2caaa65c, (q31_t)0x880bd90e, (q31_t)0x2ca4c2ed, (q31_t)0x8809a7e7, (q31_t)0x2c9edf61, (q31_t)0x8807770a, + (q31_t)0x2c98fbba, (q31_t)0x88054677, (q31_t)0x2c9317f8, (q31_t)0x8803162e, (q31_t)0x2c8d341a, (q31_t)0x8800e62f, (q31_t)0x2c875021, (q31_t)0x87feb67a, + (q31_t)0x2c816c0c, (q31_t)0x87fc870f, (q31_t)0x2c7b87dc, (q31_t)0x87fa57ee, (q31_t)0x2c75a390, (q31_t)0x87f82917, (q31_t)0x2c6fbf29, (q31_t)0x87f5fa8b, + (q31_t)0x2c69daa6, (q31_t)0x87f3cc48, (q31_t)0x2c63f609, (q31_t)0x87f19e4f, (q31_t)0x2c5e114f, (q31_t)0x87ef70a0, (q31_t)0x2c582c7b, (q31_t)0x87ed433c, + (q31_t)0x2c52478a, (q31_t)0x87eb1621, (q31_t)0x2c4c627f, (q31_t)0x87e8e950, (q31_t)0x2c467d58, (q31_t)0x87e6bcca, (q31_t)0x2c409816, (q31_t)0x87e4908e, + (q31_t)0x2c3ab2b9, (q31_t)0x87e2649b, (q31_t)0x2c34cd40, (q31_t)0x87e038f3, (q31_t)0x2c2ee7ad, (q31_t)0x87de0d95, (q31_t)0x2c2901fd, (q31_t)0x87dbe281, + (q31_t)0x2c231c33, (q31_t)0x87d9b7b7, (q31_t)0x2c1d364e, (q31_t)0x87d78d38, (q31_t)0x2c17504d, (q31_t)0x87d56302, (q31_t)0x2c116a31, (q31_t)0x87d33916, + (q31_t)0x2c0b83fa, (q31_t)0x87d10f75, (q31_t)0x2c059da7, (q31_t)0x87cee61e, (q31_t)0x2bffb73a, (q31_t)0x87ccbd11, (q31_t)0x2bf9d0b1, (q31_t)0x87ca944e, + (q31_t)0x2bf3ea0d, (q31_t)0x87c86bd5, (q31_t)0x2bee034e, (q31_t)0x87c643a6, (q31_t)0x2be81c74, (q31_t)0x87c41bc2, (q31_t)0x2be2357f, (q31_t)0x87c1f427, + (q31_t)0x2bdc4e6f, (q31_t)0x87bfccd7, (q31_t)0x2bd66744, (q31_t)0x87bda5d1, (q31_t)0x2bd07ffe, (q31_t)0x87bb7f16, (q31_t)0x2bca989d, (q31_t)0x87b958a4, + (q31_t)0x2bc4b120, (q31_t)0x87b7327d, (q31_t)0x2bbec989, (q31_t)0x87b50c9f, (q31_t)0x2bb8e1d7, (q31_t)0x87b2e70c, (q31_t)0x2bb2fa0a, (q31_t)0x87b0c1c4, + (q31_t)0x2bad1221, (q31_t)0x87ae9cc5, (q31_t)0x2ba72a1e, (q31_t)0x87ac7811, (q31_t)0x2ba14200, (q31_t)0x87aa53a6, (q31_t)0x2b9b59c7, (q31_t)0x87a82f87, + (q31_t)0x2b957173, (q31_t)0x87a60bb1, (q31_t)0x2b8f8905, (q31_t)0x87a3e825, (q31_t)0x2b89a07b, (q31_t)0x87a1c4e4, (q31_t)0x2b83b7d7, (q31_t)0x879fa1ed, + (q31_t)0x2b7dcf17, (q31_t)0x879d7f41, (q31_t)0x2b77e63d, (q31_t)0x879b5cde, (q31_t)0x2b71fd48, (q31_t)0x87993ac6, (q31_t)0x2b6c1438, (q31_t)0x879718f8, + (q31_t)0x2b662b0e, (q31_t)0x8794f774, (q31_t)0x2b6041c9, (q31_t)0x8792d63b, (q31_t)0x2b5a5868, (q31_t)0x8790b54c, (q31_t)0x2b546eee, (q31_t)0x878e94a7, + (q31_t)0x2b4e8558, (q31_t)0x878c744d, (q31_t)0x2b489ba8, (q31_t)0x878a543d, (q31_t)0x2b42b1dd, (q31_t)0x87883477, (q31_t)0x2b3cc7f7, (q31_t)0x878614fb, + (q31_t)0x2b36ddf7, (q31_t)0x8783f5ca, (q31_t)0x2b30f3dc, (q31_t)0x8781d6e3, (q31_t)0x2b2b09a6, (q31_t)0x877fb846, (q31_t)0x2b251f56, (q31_t)0x877d99f4, + (q31_t)0x2b1f34eb, (q31_t)0x877b7bec, (q31_t)0x2b194a66, (q31_t)0x87795e2f, (q31_t)0x2b135fc6, (q31_t)0x877740bb, (q31_t)0x2b0d750b, (q31_t)0x87752392, + (q31_t)0x2b078a36, (q31_t)0x877306b4, (q31_t)0x2b019f46, (q31_t)0x8770ea20, (q31_t)0x2afbb43c, (q31_t)0x876ecdd6, (q31_t)0x2af5c917, (q31_t)0x876cb1d6, + (q31_t)0x2aefddd8, (q31_t)0x876a9621, (q31_t)0x2ae9f27e, (q31_t)0x87687ab7, (q31_t)0x2ae4070a, (q31_t)0x87665f96, (q31_t)0x2ade1b7c, (q31_t)0x876444c1, + (q31_t)0x2ad82fd2, (q31_t)0x87622a35, (q31_t)0x2ad2440f, (q31_t)0x87600ff4, (q31_t)0x2acc5831, (q31_t)0x875df5fd, (q31_t)0x2ac66c39, (q31_t)0x875bdc51, + (q31_t)0x2ac08026, (q31_t)0x8759c2ef, (q31_t)0x2aba93f9, (q31_t)0x8757a9d8, (q31_t)0x2ab4a7b1, (q31_t)0x8755910b, (q31_t)0x2aaebb50, (q31_t)0x87537888, + (q31_t)0x2aa8ced3, (q31_t)0x87516050, (q31_t)0x2aa2e23d, (q31_t)0x874f4862, (q31_t)0x2a9cf58c, (q31_t)0x874d30bf, (q31_t)0x2a9708c1, (q31_t)0x874b1966, + (q31_t)0x2a911bdc, (q31_t)0x87490258, (q31_t)0x2a8b2edc, (q31_t)0x8746eb94, (q31_t)0x2a8541c3, (q31_t)0x8744d51b, (q31_t)0x2a7f548e, (q31_t)0x8742beec, + (q31_t)0x2a796740, (q31_t)0x8740a907, (q31_t)0x2a7379d8, (q31_t)0x873e936d, (q31_t)0x2a6d8c55, (q31_t)0x873c7e1e, (q31_t)0x2a679eb8, (q31_t)0x873a6919, + (q31_t)0x2a61b101, (q31_t)0x8738545e, (q31_t)0x2a5bc330, (q31_t)0x87363fee, (q31_t)0x2a55d545, (q31_t)0x87342bc9, (q31_t)0x2a4fe740, (q31_t)0x873217ee, + (q31_t)0x2a49f920, (q31_t)0x8730045d, (q31_t)0x2a440ae7, (q31_t)0x872df117, (q31_t)0x2a3e1c93, (q31_t)0x872bde1c, (q31_t)0x2a382e25, (q31_t)0x8729cb6b, + (q31_t)0x2a323f9e, (q31_t)0x8727b905, (q31_t)0x2a2c50fc, (q31_t)0x8725a6e9, (q31_t)0x2a266240, (q31_t)0x87239518, (q31_t)0x2a20736a, (q31_t)0x87218391, + (q31_t)0x2a1a847b, (q31_t)0x871f7255, (q31_t)0x2a149571, (q31_t)0x871d6163, (q31_t)0x2a0ea64d, (q31_t)0x871b50bc, (q31_t)0x2a08b710, (q31_t)0x87194060, + (q31_t)0x2a02c7b8, (q31_t)0x8717304e, (q31_t)0x29fcd847, (q31_t)0x87152087, (q31_t)0x29f6e8bb, (q31_t)0x8713110a, (q31_t)0x29f0f916, (q31_t)0x871101d8, + (q31_t)0x29eb0957, (q31_t)0x870ef2f1, (q31_t)0x29e5197e, (q31_t)0x870ce454, (q31_t)0x29df298b, (q31_t)0x870ad602, (q31_t)0x29d9397f, (q31_t)0x8708c7fa, + (q31_t)0x29d34958, (q31_t)0x8706ba3d, (q31_t)0x29cd5918, (q31_t)0x8704acca, (q31_t)0x29c768be, (q31_t)0x87029fa3, (q31_t)0x29c1784a, (q31_t)0x870092c5, + (q31_t)0x29bb87bc, (q31_t)0x86fe8633, (q31_t)0x29b59715, (q31_t)0x86fc79eb, (q31_t)0x29afa654, (q31_t)0x86fa6dee, (q31_t)0x29a9b579, (q31_t)0x86f8623b, + (q31_t)0x29a3c485, (q31_t)0x86f656d3, (q31_t)0x299dd377, (q31_t)0x86f44bb6, (q31_t)0x2997e24f, (q31_t)0x86f240e3, (q31_t)0x2991f10e, (q31_t)0x86f0365c, + (q31_t)0x298bffb2, (q31_t)0x86ee2c1e, (q31_t)0x29860e3e, (q31_t)0x86ec222c, (q31_t)0x29801caf, (q31_t)0x86ea1884, (q31_t)0x297a2b07, (q31_t)0x86e80f27, + (q31_t)0x29743946, (q31_t)0x86e60614, (q31_t)0x296e476b, (q31_t)0x86e3fd4c, (q31_t)0x29685576, (q31_t)0x86e1f4cf, (q31_t)0x29626368, (q31_t)0x86dfec9d, + (q31_t)0x295c7140, (q31_t)0x86dde4b5, (q31_t)0x29567eff, (q31_t)0x86dbdd18, (q31_t)0x29508ca4, (q31_t)0x86d9d5c6, (q31_t)0x294a9a30, (q31_t)0x86d7cebf, + (q31_t)0x2944a7a2, (q31_t)0x86d5c802, (q31_t)0x293eb4fb, (q31_t)0x86d3c190, (q31_t)0x2938c23a, (q31_t)0x86d1bb69, (q31_t)0x2932cf60, (q31_t)0x86cfb58c, + (q31_t)0x292cdc6d, (q31_t)0x86cdaffa, (q31_t)0x2926e960, (q31_t)0x86cbaab3, (q31_t)0x2920f63a, (q31_t)0x86c9a5b7, (q31_t)0x291b02fa, (q31_t)0x86c7a106, + (q31_t)0x29150fa1, (q31_t)0x86c59c9f, (q31_t)0x290f1c2f, (q31_t)0x86c39883, (q31_t)0x290928a3, (q31_t)0x86c194b2, (q31_t)0x290334ff, (q31_t)0x86bf912c, + (q31_t)0x28fd4140, (q31_t)0x86bd8df0, (q31_t)0x28f74d69, (q31_t)0x86bb8b00, (q31_t)0x28f15978, (q31_t)0x86b9885a, (q31_t)0x28eb656e, (q31_t)0x86b785ff, + (q31_t)0x28e5714b, (q31_t)0x86b583ee, (q31_t)0x28df7d0e, (q31_t)0x86b38229, (q31_t)0x28d988b8, (q31_t)0x86b180ae, (q31_t)0x28d3944a, (q31_t)0x86af7f7e, + (q31_t)0x28cd9fc1, (q31_t)0x86ad7e99, (q31_t)0x28c7ab20, (q31_t)0x86ab7dff, (q31_t)0x28c1b666, (q31_t)0x86a97db0, (q31_t)0x28bbc192, (q31_t)0x86a77dab, + (q31_t)0x28b5cca5, (q31_t)0x86a57df2, (q31_t)0x28afd7a0, (q31_t)0x86a37e83, (q31_t)0x28a9e281, (q31_t)0x86a17f5f, (q31_t)0x28a3ed49, (q31_t)0x869f8086, + (q31_t)0x289df7f8, (q31_t)0x869d81f8, (q31_t)0x2898028e, (q31_t)0x869b83b4, (q31_t)0x28920d0a, (q31_t)0x869985bc, (q31_t)0x288c176e, (q31_t)0x8697880f, + (q31_t)0x288621b9, (q31_t)0x86958aac, (q31_t)0x28802beb, (q31_t)0x86938d94, (q31_t)0x287a3604, (q31_t)0x869190c7, (q31_t)0x28744004, (q31_t)0x868f9445, + (q31_t)0x286e49ea, (q31_t)0x868d980e, (q31_t)0x286853b8, (q31_t)0x868b9c22, (q31_t)0x28625d6d, (q31_t)0x8689a081, (q31_t)0x285c670a, (q31_t)0x8687a52b, + (q31_t)0x2856708d, (q31_t)0x8685aa20, (q31_t)0x285079f7, (q31_t)0x8683af5f, (q31_t)0x284a8349, (q31_t)0x8681b4ea, (q31_t)0x28448c81, (q31_t)0x867fbabf, + (q31_t)0x283e95a1, (q31_t)0x867dc0e0, (q31_t)0x28389ea8, (q31_t)0x867bc74b, (q31_t)0x2832a796, (q31_t)0x8679ce01, (q31_t)0x282cb06c, (q31_t)0x8677d503, + (q31_t)0x2826b928, (q31_t)0x8675dc4f, (q31_t)0x2820c1cc, (q31_t)0x8673e3e6, (q31_t)0x281aca57, (q31_t)0x8671ebc8, (q31_t)0x2814d2c9, (q31_t)0x866ff3f6, + (q31_t)0x280edb23, (q31_t)0x866dfc6e, (q31_t)0x2808e364, (q31_t)0x866c0531, (q31_t)0x2802eb8c, (q31_t)0x866a0e3f, (q31_t)0x27fcf39c, (q31_t)0x86681798, + (q31_t)0x27f6fb92, (q31_t)0x8666213c, (q31_t)0x27f10371, (q31_t)0x86642b2c, (q31_t)0x27eb0b36, (q31_t)0x86623566, (q31_t)0x27e512e3, (q31_t)0x86603feb, + (q31_t)0x27df1a77, (q31_t)0x865e4abb, (q31_t)0x27d921f3, (q31_t)0x865c55d7, (q31_t)0x27d32956, (q31_t)0x865a613d, (q31_t)0x27cd30a1, (q31_t)0x86586cee, + (q31_t)0x27c737d3, (q31_t)0x865678eb, (q31_t)0x27c13eec, (q31_t)0x86548532, (q31_t)0x27bb45ed, (q31_t)0x865291c4, (q31_t)0x27b54cd6, (q31_t)0x86509ea2, + (q31_t)0x27af53a6, (q31_t)0x864eabcb, (q31_t)0x27a95a5d, (q31_t)0x864cb93e, (q31_t)0x27a360fc, (q31_t)0x864ac6fd, (q31_t)0x279d6783, (q31_t)0x8648d507, + (q31_t)0x27976df1, (q31_t)0x8646e35c, (q31_t)0x27917447, (q31_t)0x8644f1fc, (q31_t)0x278b7a84, (q31_t)0x864300e7, (q31_t)0x278580a9, (q31_t)0x8641101d, + (q31_t)0x277f86b5, (q31_t)0x863f1f9e, (q31_t)0x27798caa, (q31_t)0x863d2f6b, (q31_t)0x27739285, (q31_t)0x863b3f82, (q31_t)0x276d9849, (q31_t)0x86394fe5, + (q31_t)0x27679df4, (q31_t)0x86376092, (q31_t)0x2761a387, (q31_t)0x8635718b, (q31_t)0x275ba901, (q31_t)0x863382cf, (q31_t)0x2755ae64, (q31_t)0x8631945e, + (q31_t)0x274fb3ae, (q31_t)0x862fa638, (q31_t)0x2749b8e0, (q31_t)0x862db85e, (q31_t)0x2743bdf9, (q31_t)0x862bcace, (q31_t)0x273dc2fa, (q31_t)0x8629dd8a, + (q31_t)0x2737c7e3, (q31_t)0x8627f091, (q31_t)0x2731ccb4, (q31_t)0x862603e3, (q31_t)0x272bd16d, (q31_t)0x86241780, (q31_t)0x2725d60e, (q31_t)0x86222b68, + (q31_t)0x271fda96, (q31_t)0x86203f9c, (q31_t)0x2719df06, (q31_t)0x861e541a, (q31_t)0x2713e35f, (q31_t)0x861c68e4, (q31_t)0x270de79f, (q31_t)0x861a7df9, + (q31_t)0x2707ebc7, (q31_t)0x86189359, (q31_t)0x2701efd7, (q31_t)0x8616a905, (q31_t)0x26fbf3ce, (q31_t)0x8614befb, (q31_t)0x26f5f7ae, (q31_t)0x8612d53d, + (q31_t)0x26effb76, (q31_t)0x8610ebca, (q31_t)0x26e9ff26, (q31_t)0x860f02a3, (q31_t)0x26e402bd, (q31_t)0x860d19c6, (q31_t)0x26de063d, (q31_t)0x860b3135, + (q31_t)0x26d809a5, (q31_t)0x860948ef, (q31_t)0x26d20cf5, (q31_t)0x860760f4, (q31_t)0x26cc102d, (q31_t)0x86057944, (q31_t)0x26c6134d, (q31_t)0x860391e0, + (q31_t)0x26c01655, (q31_t)0x8601aac7, (q31_t)0x26ba1945, (q31_t)0x85ffc3f9, (q31_t)0x26b41c1d, (q31_t)0x85fddd76, (q31_t)0x26ae1edd, (q31_t)0x85fbf73f, + (q31_t)0x26a82186, (q31_t)0x85fa1153, (q31_t)0x26a22416, (q31_t)0x85f82bb2, (q31_t)0x269c268f, (q31_t)0x85f6465c, (q31_t)0x269628f0, (q31_t)0x85f46152, + (q31_t)0x26902b39, (q31_t)0x85f27c93, (q31_t)0x268a2d6b, (q31_t)0x85f09820, (q31_t)0x26842f84, (q31_t)0x85eeb3f7, (q31_t)0x267e3186, (q31_t)0x85ecd01a, + (q31_t)0x26783370, (q31_t)0x85eaec88, (q31_t)0x26723543, (q31_t)0x85e90942, (q31_t)0x266c36fe, (q31_t)0x85e72647, (q31_t)0x266638a1, (q31_t)0x85e54397, + (q31_t)0x26603a2c, (q31_t)0x85e36132, (q31_t)0x265a3b9f, (q31_t)0x85e17f19, (q31_t)0x26543cfb, (q31_t)0x85df9d4b, (q31_t)0x264e3e40, (q31_t)0x85ddbbc9, + (q31_t)0x26483f6c, (q31_t)0x85dbda91, (q31_t)0x26424082, (q31_t)0x85d9f9a5, (q31_t)0x263c417f, (q31_t)0x85d81905, (q31_t)0x26364265, (q31_t)0x85d638b0, + (q31_t)0x26304333, (q31_t)0x85d458a6, (q31_t)0x262a43ea, (q31_t)0x85d278e7, (q31_t)0x26244489, (q31_t)0x85d09974, (q31_t)0x261e4511, (q31_t)0x85ceba4d, + (q31_t)0x26184581, (q31_t)0x85ccdb70, (q31_t)0x261245da, (q31_t)0x85cafcdf, (q31_t)0x260c461b, (q31_t)0x85c91e9a, (q31_t)0x26064645, (q31_t)0x85c740a0, + (q31_t)0x26004657, (q31_t)0x85c562f1, (q31_t)0x25fa4652, (q31_t)0x85c3858d, (q31_t)0x25f44635, (q31_t)0x85c1a875, (q31_t)0x25ee4601, (q31_t)0x85bfcba9, + (q31_t)0x25e845b6, (q31_t)0x85bdef28, (q31_t)0x25e24553, (q31_t)0x85bc12f2, (q31_t)0x25dc44d9, (q31_t)0x85ba3707, (q31_t)0x25d64447, (q31_t)0x85b85b68, + (q31_t)0x25d0439f, (q31_t)0x85b68015, (q31_t)0x25ca42de, (q31_t)0x85b4a50d, (q31_t)0x25c44207, (q31_t)0x85b2ca50, (q31_t)0x25be4118, (q31_t)0x85b0efdf, + (q31_t)0x25b84012, (q31_t)0x85af15b9, (q31_t)0x25b23ef5, (q31_t)0x85ad3bdf, (q31_t)0x25ac3dc0, (q31_t)0x85ab6250, (q31_t)0x25a63c74, (q31_t)0x85a9890d, + (q31_t)0x25a03b11, (q31_t)0x85a7b015, (q31_t)0x259a3997, (q31_t)0x85a5d768, (q31_t)0x25943806, (q31_t)0x85a3ff07, (q31_t)0x258e365d, (q31_t)0x85a226f2, + (q31_t)0x2588349d, (q31_t)0x85a04f28, (q31_t)0x258232c6, (q31_t)0x859e77a9, (q31_t)0x257c30d8, (q31_t)0x859ca076, (q31_t)0x25762ed3, (q31_t)0x859ac98f, + (q31_t)0x25702cb7, (q31_t)0x8598f2f3, (q31_t)0x256a2a83, (q31_t)0x85971ca2, (q31_t)0x25642839, (q31_t)0x8595469d, (q31_t)0x255e25d7, (q31_t)0x859370e4, + (q31_t)0x2558235f, (q31_t)0x85919b76, (q31_t)0x255220cf, (q31_t)0x858fc653, (q31_t)0x254c1e28, (q31_t)0x858df17c, (q31_t)0x25461b6b, (q31_t)0x858c1cf1, + (q31_t)0x25401896, (q31_t)0x858a48b1, (q31_t)0x253a15aa, (q31_t)0x858874bd, (q31_t)0x253412a8, (q31_t)0x8586a114, (q31_t)0x252e0f8e, (q31_t)0x8584cdb7, + (q31_t)0x25280c5e, (q31_t)0x8582faa5, (q31_t)0x25220916, (q31_t)0x858127df, (q31_t)0x251c05b8, (q31_t)0x857f5564, (q31_t)0x25160243, (q31_t)0x857d8335, + (q31_t)0x250ffeb7, (q31_t)0x857bb152, (q31_t)0x2509fb14, (q31_t)0x8579dfba, (q31_t)0x2503f75a, (q31_t)0x85780e6e, (q31_t)0x24fdf389, (q31_t)0x85763d6d, + (q31_t)0x24f7efa2, (q31_t)0x85746cb8, (q31_t)0x24f1eba4, (q31_t)0x85729c4e, (q31_t)0x24ebe78f, (q31_t)0x8570cc30, (q31_t)0x24e5e363, (q31_t)0x856efc5e, + (q31_t)0x24dfdf20, (q31_t)0x856d2cd7, (q31_t)0x24d9dac7, (q31_t)0x856b5d9c, (q31_t)0x24d3d657, (q31_t)0x85698ead, (q31_t)0x24cdd1d0, (q31_t)0x8567c009, + (q31_t)0x24c7cd33, (q31_t)0x8565f1b0, (q31_t)0x24c1c87f, (q31_t)0x856423a4, (q31_t)0x24bbc3b4, (q31_t)0x856255e3, (q31_t)0x24b5bed2, (q31_t)0x8560886d, + (q31_t)0x24afb9da, (q31_t)0x855ebb44, (q31_t)0x24a9b4cb, (q31_t)0x855cee66, (q31_t)0x24a3afa6, (q31_t)0x855b21d3, (q31_t)0x249daa6a, (q31_t)0x8559558c, + (q31_t)0x2497a517, (q31_t)0x85578991, (q31_t)0x24919fae, (q31_t)0x8555bde2, (q31_t)0x248b9a2f, (q31_t)0x8553f27e, (q31_t)0x24859498, (q31_t)0x85522766, + (q31_t)0x247f8eec, (q31_t)0x85505c99, (q31_t)0x24798928, (q31_t)0x854e9219, (q31_t)0x2473834f, (q31_t)0x854cc7e3, (q31_t)0x246d7d5e, (q31_t)0x854afdfa, + (q31_t)0x24677758, (q31_t)0x8549345c, (q31_t)0x2461713a, (q31_t)0x85476b0a, (q31_t)0x245b6b07, (q31_t)0x8545a204, (q31_t)0x245564bd, (q31_t)0x8543d949, + (q31_t)0x244f5e5c, (q31_t)0x854210db, (q31_t)0x244957e5, (q31_t)0x854048b7, (q31_t)0x24435158, (q31_t)0x853e80e0, (q31_t)0x243d4ab4, (q31_t)0x853cb954, + (q31_t)0x243743fa, (q31_t)0x853af214, (q31_t)0x24313d2a, (q31_t)0x85392b20, (q31_t)0x242b3644, (q31_t)0x85376477, (q31_t)0x24252f47, (q31_t)0x85359e1a, + (q31_t)0x241f2833, (q31_t)0x8533d809, (q31_t)0x2419210a, (q31_t)0x85321244, (q31_t)0x241319ca, (q31_t)0x85304cca, (q31_t)0x240d1274, (q31_t)0x852e879d, + (q31_t)0x24070b08, (q31_t)0x852cc2bb, (q31_t)0x24010385, (q31_t)0x852afe24, (q31_t)0x23fafbec, (q31_t)0x852939da, (q31_t)0x23f4f43e, (q31_t)0x852775db, + (q31_t)0x23eeec78, (q31_t)0x8525b228, (q31_t)0x23e8e49d, (q31_t)0x8523eec1, (q31_t)0x23e2dcac, (q31_t)0x85222ba5, (q31_t)0x23dcd4a4, (q31_t)0x852068d6, + (q31_t)0x23d6cc87, (q31_t)0x851ea652, (q31_t)0x23d0c453, (q31_t)0x851ce41a, (q31_t)0x23cabc09, (q31_t)0x851b222e, (q31_t)0x23c4b3a9, (q31_t)0x8519608d, + (q31_t)0x23beab33, (q31_t)0x85179f39, (q31_t)0x23b8a2a7, (q31_t)0x8515de30, (q31_t)0x23b29a05, (q31_t)0x85141d73, (q31_t)0x23ac914d, (q31_t)0x85125d02, + (q31_t)0x23a6887f, (q31_t)0x85109cdd, (q31_t)0x23a07f9a, (q31_t)0x850edd03, (q31_t)0x239a76a0, (q31_t)0x850d1d75, (q31_t)0x23946d90, (q31_t)0x850b5e34, + (q31_t)0x238e646a, (q31_t)0x85099f3e, (q31_t)0x23885b2e, (q31_t)0x8507e094, (q31_t)0x238251dd, (q31_t)0x85062235, (q31_t)0x237c4875, (q31_t)0x85046423, + (q31_t)0x23763ef7, (q31_t)0x8502a65c, (q31_t)0x23703564, (q31_t)0x8500e8e2, (q31_t)0x236a2bba, (q31_t)0x84ff2bb3, (q31_t)0x236421fb, (q31_t)0x84fd6ed0, + (q31_t)0x235e1826, (q31_t)0x84fbb239, (q31_t)0x23580e3b, (q31_t)0x84f9f5ee, (q31_t)0x2352043b, (q31_t)0x84f839ee, (q31_t)0x234bfa24, (q31_t)0x84f67e3b, + (q31_t)0x2345eff8, (q31_t)0x84f4c2d4, (q31_t)0x233fe5b6, (q31_t)0x84f307b8, (q31_t)0x2339db5e, (q31_t)0x84f14ce8, (q31_t)0x2333d0f1, (q31_t)0x84ef9265, + (q31_t)0x232dc66d, (q31_t)0x84edd82d, (q31_t)0x2327bbd5, (q31_t)0x84ec1e41, (q31_t)0x2321b126, (q31_t)0x84ea64a1, (q31_t)0x231ba662, (q31_t)0x84e8ab4d, + (q31_t)0x23159b88, (q31_t)0x84e6f244, (q31_t)0x230f9098, (q31_t)0x84e53988, (q31_t)0x23098593, (q31_t)0x84e38118, (q31_t)0x23037a78, (q31_t)0x84e1c8f3, + (q31_t)0x22fd6f48, (q31_t)0x84e0111b, (q31_t)0x22f76402, (q31_t)0x84de598f, (q31_t)0x22f158a7, (q31_t)0x84dca24e, (q31_t)0x22eb4d36, (q31_t)0x84daeb5a, + (q31_t)0x22e541af, (q31_t)0x84d934b1, (q31_t)0x22df3613, (q31_t)0x84d77e54, (q31_t)0x22d92a61, (q31_t)0x84d5c844, (q31_t)0x22d31e9a, (q31_t)0x84d4127f, + (q31_t)0x22cd12bd, (q31_t)0x84d25d06, (q31_t)0x22c706cb, (q31_t)0x84d0a7da, (q31_t)0x22c0fac4, (q31_t)0x84cef2f9, (q31_t)0x22baeea7, (q31_t)0x84cd3e64, + (q31_t)0x22b4e274, (q31_t)0x84cb8a1b, (q31_t)0x22aed62c, (q31_t)0x84c9d61f, (q31_t)0x22a8c9cf, (q31_t)0x84c8226e, (q31_t)0x22a2bd5d, (q31_t)0x84c66f09, + (q31_t)0x229cb0d5, (q31_t)0x84c4bbf0, (q31_t)0x2296a437, (q31_t)0x84c30924, (q31_t)0x22909785, (q31_t)0x84c156a3, (q31_t)0x228a8abd, (q31_t)0x84bfa46e, + (q31_t)0x22847de0, (q31_t)0x84bdf286, (q31_t)0x227e70ed, (q31_t)0x84bc40e9, (q31_t)0x227863e5, (q31_t)0x84ba8f98, (q31_t)0x227256c8, (q31_t)0x84b8de94, + (q31_t)0x226c4996, (q31_t)0x84b72ddb, (q31_t)0x22663c4e, (q31_t)0x84b57d6f, (q31_t)0x22602ef1, (q31_t)0x84b3cd4f, (q31_t)0x225a217f, (q31_t)0x84b21d7a, + (q31_t)0x225413f8, (q31_t)0x84b06df2, (q31_t)0x224e065c, (q31_t)0x84aebeb6, (q31_t)0x2247f8aa, (q31_t)0x84ad0fc6, (q31_t)0x2241eae3, (q31_t)0x84ab6122, + (q31_t)0x223bdd08, (q31_t)0x84a9b2ca, (q31_t)0x2235cf17, (q31_t)0x84a804be, (q31_t)0x222fc111, (q31_t)0x84a656fe, (q31_t)0x2229b2f6, (q31_t)0x84a4a98a, + (q31_t)0x2223a4c5, (q31_t)0x84a2fc62, (q31_t)0x221d9680, (q31_t)0x84a14f87, (q31_t)0x22178826, (q31_t)0x849fa2f7, (q31_t)0x221179b7, (q31_t)0x849df6b4, + (q31_t)0x220b6b32, (q31_t)0x849c4abd, (q31_t)0x22055c99, (q31_t)0x849a9f12, (q31_t)0x21ff4dea, (q31_t)0x8498f3b3, (q31_t)0x21f93f27, (q31_t)0x849748a0, + (q31_t)0x21f3304f, (q31_t)0x84959dd9, (q31_t)0x21ed2162, (q31_t)0x8493f35e, (q31_t)0x21e71260, (q31_t)0x84924930, (q31_t)0x21e10349, (q31_t)0x84909f4e, + (q31_t)0x21daf41d, (q31_t)0x848ef5b7, (q31_t)0x21d4e4dc, (q31_t)0x848d4c6d, (q31_t)0x21ced586, (q31_t)0x848ba36f, (q31_t)0x21c8c61c, (q31_t)0x8489fabe, + (q31_t)0x21c2b69c, (q31_t)0x84885258, (q31_t)0x21bca708, (q31_t)0x8486aa3e, (q31_t)0x21b6975f, (q31_t)0x84850271, (q31_t)0x21b087a1, (q31_t)0x84835af0, + (q31_t)0x21aa77cf, (q31_t)0x8481b3bb, (q31_t)0x21a467e7, (q31_t)0x84800cd2, (q31_t)0x219e57eb, (q31_t)0x847e6636, (q31_t)0x219847da, (q31_t)0x847cbfe5, + (q31_t)0x219237b5, (q31_t)0x847b19e1, (q31_t)0x218c277a, (q31_t)0x84797429, (q31_t)0x2186172b, (q31_t)0x8477cebd, (q31_t)0x218006c8, (q31_t)0x8476299e, + (q31_t)0x2179f64f, (q31_t)0x847484ca, (q31_t)0x2173e5c2, (q31_t)0x8472e043, (q31_t)0x216dd521, (q31_t)0x84713c08, (q31_t)0x2167c46b, (q31_t)0x846f9819, + (q31_t)0x2161b3a0, (q31_t)0x846df477, (q31_t)0x215ba2c0, (q31_t)0x846c5120, (q31_t)0x215591cc, (q31_t)0x846aae16, (q31_t)0x214f80c4, (q31_t)0x84690b58, + (q31_t)0x21496fa7, (q31_t)0x846768e7, (q31_t)0x21435e75, (q31_t)0x8465c6c1, (q31_t)0x213d4d2f, (q31_t)0x846424e8, (q31_t)0x21373bd4, (q31_t)0x8462835b, + (q31_t)0x21312a65, (q31_t)0x8460e21a, (q31_t)0x212b18e1, (q31_t)0x845f4126, (q31_t)0x21250749, (q31_t)0x845da07e, (q31_t)0x211ef59d, (q31_t)0x845c0022, + (q31_t)0x2118e3dc, (q31_t)0x845a6012, (q31_t)0x2112d206, (q31_t)0x8458c04f, (q31_t)0x210cc01d, (q31_t)0x845720d8, (q31_t)0x2106ae1e, (q31_t)0x845581ad, + (q31_t)0x21009c0c, (q31_t)0x8453e2cf, (q31_t)0x20fa89e5, (q31_t)0x8452443d, (q31_t)0x20f477aa, (q31_t)0x8450a5f7, (q31_t)0x20ee655a, (q31_t)0x844f07fd, + (q31_t)0x20e852f6, (q31_t)0x844d6a50, (q31_t)0x20e2407e, (q31_t)0x844bccef, (q31_t)0x20dc2df2, (q31_t)0x844a2fda, (q31_t)0x20d61b51, (q31_t)0x84489311, + (q31_t)0x20d0089c, (q31_t)0x8446f695, (q31_t)0x20c9f5d3, (q31_t)0x84455a66, (q31_t)0x20c3e2f5, (q31_t)0x8443be82, (q31_t)0x20bdd003, (q31_t)0x844222eb, + (q31_t)0x20b7bcfe, (q31_t)0x844087a0, (q31_t)0x20b1a9e4, (q31_t)0x843eeca2, (q31_t)0x20ab96b5, (q31_t)0x843d51f0, (q31_t)0x20a58373, (q31_t)0x843bb78a, + (q31_t)0x209f701c, (q31_t)0x843a1d70, (q31_t)0x20995cb2, (q31_t)0x843883a3, (q31_t)0x20934933, (q31_t)0x8436ea23, (q31_t)0x208d35a0, (q31_t)0x843550ee, + (q31_t)0x208721f9, (q31_t)0x8433b806, (q31_t)0x20810e3e, (q31_t)0x84321f6b, (q31_t)0x207afa6f, (q31_t)0x8430871b, (q31_t)0x2074e68c, (q31_t)0x842eef18, + (q31_t)0x206ed295, (q31_t)0x842d5762, (q31_t)0x2068be8a, (q31_t)0x842bbff8, (q31_t)0x2062aa6b, (q31_t)0x842a28da, (q31_t)0x205c9638, (q31_t)0x84289209, + (q31_t)0x205681f1, (q31_t)0x8426fb84, (q31_t)0x20506d96, (q31_t)0x8425654b, (q31_t)0x204a5927, (q31_t)0x8423cf5f, (q31_t)0x204444a4, (q31_t)0x842239bf, + (q31_t)0x203e300d, (q31_t)0x8420a46c, (q31_t)0x20381b63, (q31_t)0x841f0f65, (q31_t)0x203206a4, (q31_t)0x841d7aaa, (q31_t)0x202bf1d2, (q31_t)0x841be63c, + (q31_t)0x2025dcec, (q31_t)0x841a521a, (q31_t)0x201fc7f2, (q31_t)0x8418be45, (q31_t)0x2019b2e4, (q31_t)0x84172abc, (q31_t)0x20139dc2, (q31_t)0x84159780, + (q31_t)0x200d888d, (q31_t)0x84140490, (q31_t)0x20077344, (q31_t)0x841271ec, (q31_t)0x20015de7, (q31_t)0x8410df95, (q31_t)0x1ffb4876, (q31_t)0x840f4d8a, + (q31_t)0x1ff532f2, (q31_t)0x840dbbcc, (q31_t)0x1fef1d59, (q31_t)0x840c2a5a, (q31_t)0x1fe907ae, (q31_t)0x840a9935, (q31_t)0x1fe2f1ee, (q31_t)0x8409085c, + (q31_t)0x1fdcdc1b, (q31_t)0x840777d0, (q31_t)0x1fd6c634, (q31_t)0x8405e790, (q31_t)0x1fd0b03a, (q31_t)0x8404579d, (q31_t)0x1fca9a2b, (q31_t)0x8402c7f6, + (q31_t)0x1fc4840a, (q31_t)0x8401389b, (q31_t)0x1fbe6dd4, (q31_t)0x83ffa98d, (q31_t)0x1fb8578b, (q31_t)0x83fe1acc, (q31_t)0x1fb2412f, (q31_t)0x83fc8c57, + (q31_t)0x1fac2abf, (q31_t)0x83fafe2e, (q31_t)0x1fa6143b, (q31_t)0x83f97052, (q31_t)0x1f9ffda4, (q31_t)0x83f7e2c3, (q31_t)0x1f99e6fa, (q31_t)0x83f65580, + (q31_t)0x1f93d03c, (q31_t)0x83f4c889, (q31_t)0x1f8db96a, (q31_t)0x83f33bdf, (q31_t)0x1f87a285, (q31_t)0x83f1af82, (q31_t)0x1f818b8d, (q31_t)0x83f02371, + (q31_t)0x1f7b7481, (q31_t)0x83ee97ad, (q31_t)0x1f755d61, (q31_t)0x83ed0c35, (q31_t)0x1f6f462f, (q31_t)0x83eb810a, (q31_t)0x1f692ee9, (q31_t)0x83e9f62b, + (q31_t)0x1f63178f, (q31_t)0x83e86b99, (q31_t)0x1f5d0022, (q31_t)0x83e6e153, (q31_t)0x1f56e8a2, (q31_t)0x83e5575a, (q31_t)0x1f50d10e, (q31_t)0x83e3cdad, + (q31_t)0x1f4ab968, (q31_t)0x83e2444d, (q31_t)0x1f44a1ad, (q31_t)0x83e0bb3a, (q31_t)0x1f3e89e0, (q31_t)0x83df3273, (q31_t)0x1f3871ff, (q31_t)0x83dda9f9, + (q31_t)0x1f325a0b, (q31_t)0x83dc21cb, (q31_t)0x1f2c4204, (q31_t)0x83da99ea, (q31_t)0x1f2629ea, (q31_t)0x83d91255, (q31_t)0x1f2011bc, (q31_t)0x83d78b0d, + (q31_t)0x1f19f97b, (q31_t)0x83d60412, (q31_t)0x1f13e127, (q31_t)0x83d47d63, (q31_t)0x1f0dc8c0, (q31_t)0x83d2f701, (q31_t)0x1f07b045, (q31_t)0x83d170eb, + (q31_t)0x1f0197b8, (q31_t)0x83cfeb22, (q31_t)0x1efb7f17, (q31_t)0x83ce65a6, (q31_t)0x1ef56664, (q31_t)0x83cce076, (q31_t)0x1eef4d9d, (q31_t)0x83cb5b93, + (q31_t)0x1ee934c3, (q31_t)0x83c9d6fc, (q31_t)0x1ee31bd6, (q31_t)0x83c852b2, (q31_t)0x1edd02d6, (q31_t)0x83c6ceb5, (q31_t)0x1ed6e9c3, (q31_t)0x83c54b04, + (q31_t)0x1ed0d09d, (q31_t)0x83c3c7a0, (q31_t)0x1ecab763, (q31_t)0x83c24488, (q31_t)0x1ec49e17, (q31_t)0x83c0c1be, (q31_t)0x1ebe84b8, (q31_t)0x83bf3f3f, + (q31_t)0x1eb86b46, (q31_t)0x83bdbd0e, (q31_t)0x1eb251c1, (q31_t)0x83bc3b29, (q31_t)0x1eac3829, (q31_t)0x83bab991, (q31_t)0x1ea61e7e, (q31_t)0x83b93845, + (q31_t)0x1ea004c1, (q31_t)0x83b7b746, (q31_t)0x1e99eaf0, (q31_t)0x83b63694, (q31_t)0x1e93d10c, (q31_t)0x83b4b62e, (q31_t)0x1e8db716, (q31_t)0x83b33616, + (q31_t)0x1e879d0d, (q31_t)0x83b1b649, (q31_t)0x1e8182f1, (q31_t)0x83b036ca, (q31_t)0x1e7b68c2, (q31_t)0x83aeb797, (q31_t)0x1e754e80, (q31_t)0x83ad38b1, + (q31_t)0x1e6f342c, (q31_t)0x83abba17, (q31_t)0x1e6919c4, (q31_t)0x83aa3bca, (q31_t)0x1e62ff4a, (q31_t)0x83a8bdca, (q31_t)0x1e5ce4be, (q31_t)0x83a74017, + (q31_t)0x1e56ca1e, (q31_t)0x83a5c2b0, (q31_t)0x1e50af6c, (q31_t)0x83a44596, (q31_t)0x1e4a94a7, (q31_t)0x83a2c8c9, (q31_t)0x1e4479cf, (q31_t)0x83a14c48, + (q31_t)0x1e3e5ee5, (q31_t)0x839fd014, (q31_t)0x1e3843e8, (q31_t)0x839e542d, (q31_t)0x1e3228d9, (q31_t)0x839cd893, (q31_t)0x1e2c0db6, (q31_t)0x839b5d45, + (q31_t)0x1e25f282, (q31_t)0x8399e244, (q31_t)0x1e1fd73a, (q31_t)0x83986790, (q31_t)0x1e19bbe0, (q31_t)0x8396ed29, (q31_t)0x1e13a074, (q31_t)0x8395730e, + (q31_t)0x1e0d84f5, (q31_t)0x8393f940, (q31_t)0x1e076963, (q31_t)0x83927fbf, (q31_t)0x1e014dbf, (q31_t)0x8391068a, (q31_t)0x1dfb3208, (q31_t)0x838f8da2, + (q31_t)0x1df5163f, (q31_t)0x838e1507, (q31_t)0x1deefa63, (q31_t)0x838c9cb9, (q31_t)0x1de8de75, (q31_t)0x838b24b8, (q31_t)0x1de2c275, (q31_t)0x8389ad03, + (q31_t)0x1ddca662, (q31_t)0x8388359b, (q31_t)0x1dd68a3c, (q31_t)0x8386be80, (q31_t)0x1dd06e04, (q31_t)0x838547b2, (q31_t)0x1dca51ba, (q31_t)0x8383d130, + (q31_t)0x1dc4355e, (q31_t)0x83825afb, (q31_t)0x1dbe18ef, (q31_t)0x8380e513, (q31_t)0x1db7fc6d, (q31_t)0x837f6f78, (q31_t)0x1db1dfda, (q31_t)0x837dfa2a, + (q31_t)0x1dabc334, (q31_t)0x837c8528, (q31_t)0x1da5a67c, (q31_t)0x837b1074, (q31_t)0x1d9f89b1, (q31_t)0x83799c0c, (q31_t)0x1d996cd4, (q31_t)0x837827f0, + (q31_t)0x1d934fe5, (q31_t)0x8376b422, (q31_t)0x1d8d32e4, (q31_t)0x837540a1, (q31_t)0x1d8715d0, (q31_t)0x8373cd6c, (q31_t)0x1d80f8ab, (q31_t)0x83725a84, + (q31_t)0x1d7adb73, (q31_t)0x8370e7e9, (q31_t)0x1d74be29, (q31_t)0x836f759b, (q31_t)0x1d6ea0cc, (q31_t)0x836e039a, (q31_t)0x1d68835e, (q31_t)0x836c91e5, + (q31_t)0x1d6265dd, (q31_t)0x836b207d, (q31_t)0x1d5c484b, (q31_t)0x8369af63, (q31_t)0x1d562aa6, (q31_t)0x83683e95, (q31_t)0x1d500cef, (q31_t)0x8366ce14, + (q31_t)0x1d49ef26, (q31_t)0x83655ddf, (q31_t)0x1d43d14b, (q31_t)0x8363edf8, (q31_t)0x1d3db35e, (q31_t)0x83627e5d, (q31_t)0x1d37955e, (q31_t)0x83610f10, + (q31_t)0x1d31774d, (q31_t)0x835fa00f, (q31_t)0x1d2b592a, (q31_t)0x835e315b, (q31_t)0x1d253af5, (q31_t)0x835cc2f4, (q31_t)0x1d1f1cae, (q31_t)0x835b54da, + (q31_t)0x1d18fe54, (q31_t)0x8359e70d, (q31_t)0x1d12dfe9, (q31_t)0x8358798c, (q31_t)0x1d0cc16c, (q31_t)0x83570c59, (q31_t)0x1d06a2dd, (q31_t)0x83559f72, + (q31_t)0x1d00843d, (q31_t)0x835432d8, (q31_t)0x1cfa658a, (q31_t)0x8352c68c, (q31_t)0x1cf446c5, (q31_t)0x83515a8c, (q31_t)0x1cee27ef, (q31_t)0x834feed9, + (q31_t)0x1ce80906, (q31_t)0x834e8373, (q31_t)0x1ce1ea0c, (q31_t)0x834d185a, (q31_t)0x1cdbcb00, (q31_t)0x834bad8e, (q31_t)0x1cd5abe3, (q31_t)0x834a430e, + (q31_t)0x1ccf8cb3, (q31_t)0x8348d8dc, (q31_t)0x1cc96d72, (q31_t)0x83476ef6, (q31_t)0x1cc34e1f, (q31_t)0x8346055e, (q31_t)0x1cbd2eba, (q31_t)0x83449c12, + (q31_t)0x1cb70f43, (q31_t)0x83433314, (q31_t)0x1cb0efbb, (q31_t)0x8341ca62, (q31_t)0x1caad021, (q31_t)0x834061fd, (q31_t)0x1ca4b075, (q31_t)0x833ef9e6, + (q31_t)0x1c9e90b8, (q31_t)0x833d921b, (q31_t)0x1c9870e9, (q31_t)0x833c2a9d, (q31_t)0x1c925109, (q31_t)0x833ac36c, (q31_t)0x1c8c3116, (q31_t)0x83395c88, + (q31_t)0x1c861113, (q31_t)0x8337f5f1, (q31_t)0x1c7ff0fd, (q31_t)0x83368fa7, (q31_t)0x1c79d0d6, (q31_t)0x833529aa, (q31_t)0x1c73b09d, (q31_t)0x8333c3fa, + (q31_t)0x1c6d9053, (q31_t)0x83325e97, (q31_t)0x1c676ff8, (q31_t)0x8330f981, (q31_t)0x1c614f8b, (q31_t)0x832f94b8, (q31_t)0x1c5b2f0c, (q31_t)0x832e303c, + (q31_t)0x1c550e7c, (q31_t)0x832ccc0d, (q31_t)0x1c4eedda, (q31_t)0x832b682b, (q31_t)0x1c48cd27, (q31_t)0x832a0496, (q31_t)0x1c42ac62, (q31_t)0x8328a14d, + (q31_t)0x1c3c8b8c, (q31_t)0x83273e52, (q31_t)0x1c366aa5, (q31_t)0x8325dba4, (q31_t)0x1c3049ac, (q31_t)0x83247943, (q31_t)0x1c2a28a2, (q31_t)0x8323172f, + (q31_t)0x1c240786, (q31_t)0x8321b568, (q31_t)0x1c1de659, (q31_t)0x832053ee, (q31_t)0x1c17c51b, (q31_t)0x831ef2c1, (q31_t)0x1c11a3cb, (q31_t)0x831d91e1, + (q31_t)0x1c0b826a, (q31_t)0x831c314e, (q31_t)0x1c0560f8, (q31_t)0x831ad109, (q31_t)0x1bff3f75, (q31_t)0x83197110, (q31_t)0x1bf91de0, (q31_t)0x83181164, + (q31_t)0x1bf2fc3a, (q31_t)0x8316b205, (q31_t)0x1becda83, (q31_t)0x831552f4, (q31_t)0x1be6b8ba, (q31_t)0x8313f42f, (q31_t)0x1be096e0, (q31_t)0x831295b7, + (q31_t)0x1bda74f6, (q31_t)0x8311378d, (q31_t)0x1bd452f9, (q31_t)0x830fd9af, (q31_t)0x1bce30ec, (q31_t)0x830e7c1f, (q31_t)0x1bc80ece, (q31_t)0x830d1edc, + (q31_t)0x1bc1ec9e, (q31_t)0x830bc1e6, (q31_t)0x1bbbca5e, (q31_t)0x830a653c, (q31_t)0x1bb5a80c, (q31_t)0x830908e0, (q31_t)0x1baf85a9, (q31_t)0x8307acd1, + (q31_t)0x1ba96335, (q31_t)0x83065110, (q31_t)0x1ba340b0, (q31_t)0x8304f59b, (q31_t)0x1b9d1e1a, (q31_t)0x83039a73, (q31_t)0x1b96fb73, (q31_t)0x83023f98, + (q31_t)0x1b90d8bb, (q31_t)0x8300e50b, (q31_t)0x1b8ab5f2, (q31_t)0x82ff8acb, (q31_t)0x1b849317, (q31_t)0x82fe30d7, (q31_t)0x1b7e702c, (q31_t)0x82fcd731, + (q31_t)0x1b784d30, (q31_t)0x82fb7dd8, (q31_t)0x1b722a23, (q31_t)0x82fa24cc, (q31_t)0x1b6c0705, (q31_t)0x82f8cc0d, (q31_t)0x1b65e3d7, (q31_t)0x82f7739c, + (q31_t)0x1b5fc097, (q31_t)0x82f61b77, (q31_t)0x1b599d46, (q31_t)0x82f4c3a0, (q31_t)0x1b5379e5, (q31_t)0x82f36c15, (q31_t)0x1b4d5672, (q31_t)0x82f214d8, + (q31_t)0x1b4732ef, (q31_t)0x82f0bde8, (q31_t)0x1b410f5b, (q31_t)0x82ef6745, (q31_t)0x1b3aebb6, (q31_t)0x82ee10ef, (q31_t)0x1b34c801, (q31_t)0x82ecbae7, + (q31_t)0x1b2ea43a, (q31_t)0x82eb652b, (q31_t)0x1b288063, (q31_t)0x82ea0fbd, (q31_t)0x1b225c7b, (q31_t)0x82e8ba9c, (q31_t)0x1b1c3883, (q31_t)0x82e765c8, + (q31_t)0x1b161479, (q31_t)0x82e61141, (q31_t)0x1b0ff05f, (q31_t)0x82e4bd07, (q31_t)0x1b09cc34, (q31_t)0x82e3691b, (q31_t)0x1b03a7f9, (q31_t)0x82e2157c, + (q31_t)0x1afd83ad, (q31_t)0x82e0c22a, (q31_t)0x1af75f50, (q31_t)0x82df6f25, (q31_t)0x1af13ae3, (q31_t)0x82de1c6d, (q31_t)0x1aeb1665, (q31_t)0x82dcca02, + (q31_t)0x1ae4f1d6, (q31_t)0x82db77e5, (q31_t)0x1adecd37, (q31_t)0x82da2615, (q31_t)0x1ad8a887, (q31_t)0x82d8d492, (q31_t)0x1ad283c7, (q31_t)0x82d7835c, + (q31_t)0x1acc5ef6, (q31_t)0x82d63274, (q31_t)0x1ac63a14, (q31_t)0x82d4e1d8, (q31_t)0x1ac01522, (q31_t)0x82d3918a, (q31_t)0x1ab9f020, (q31_t)0x82d24189, + (q31_t)0x1ab3cb0d, (q31_t)0x82d0f1d5, (q31_t)0x1aada5e9, (q31_t)0x82cfa26f, (q31_t)0x1aa780b6, (q31_t)0x82ce5356, (q31_t)0x1aa15b71, (q31_t)0x82cd048a, + (q31_t)0x1a9b361d, (q31_t)0x82cbb60b, (q31_t)0x1a9510b7, (q31_t)0x82ca67d9, (q31_t)0x1a8eeb42, (q31_t)0x82c919f5, (q31_t)0x1a88c5bc, (q31_t)0x82c7cc5e, + (q31_t)0x1a82a026, (q31_t)0x82c67f14, (q31_t)0x1a7c7a7f, (q31_t)0x82c53217, (q31_t)0x1a7654c8, (q31_t)0x82c3e568, (q31_t)0x1a702f01, (q31_t)0x82c29906, + (q31_t)0x1a6a0929, (q31_t)0x82c14cf1, (q31_t)0x1a63e341, (q31_t)0x82c00129, (q31_t)0x1a5dbd49, (q31_t)0x82beb5af, (q31_t)0x1a579741, (q31_t)0x82bd6a82, + (q31_t)0x1a517128, (q31_t)0x82bc1fa2, (q31_t)0x1a4b4aff, (q31_t)0x82bad50f, (q31_t)0x1a4524c6, (q31_t)0x82b98aca, (q31_t)0x1a3efe7c, (q31_t)0x82b840d2, + (q31_t)0x1a38d823, (q31_t)0x82b6f727, (q31_t)0x1a32b1b9, (q31_t)0x82b5adca, (q31_t)0x1a2c8b3f, (q31_t)0x82b464ba, (q31_t)0x1a2664b5, (q31_t)0x82b31bf7, + (q31_t)0x1a203e1b, (q31_t)0x82b1d381, (q31_t)0x1a1a1771, (q31_t)0x82b08b59, (q31_t)0x1a13f0b6, (q31_t)0x82af437e, (q31_t)0x1a0dc9ec, (q31_t)0x82adfbf0, + (q31_t)0x1a07a311, (q31_t)0x82acb4b0, (q31_t)0x1a017c27, (q31_t)0x82ab6dbd, (q31_t)0x19fb552c, (q31_t)0x82aa2717, (q31_t)0x19f52e22, (q31_t)0x82a8e0bf, + (q31_t)0x19ef0707, (q31_t)0x82a79ab3, (q31_t)0x19e8dfdc, (q31_t)0x82a654f6, (q31_t)0x19e2b8a2, (q31_t)0x82a50f85, (q31_t)0x19dc9157, (q31_t)0x82a3ca62, + (q31_t)0x19d669fc, (q31_t)0x82a2858c, (q31_t)0x19d04292, (q31_t)0x82a14104, (q31_t)0x19ca1b17, (q31_t)0x829ffcc8, (q31_t)0x19c3f38d, (q31_t)0x829eb8db, + (q31_t)0x19bdcbf3, (q31_t)0x829d753a, (q31_t)0x19b7a449, (q31_t)0x829c31e7, (q31_t)0x19b17c8f, (q31_t)0x829aeee1, (q31_t)0x19ab54c5, (q31_t)0x8299ac29, + (q31_t)0x19a52ceb, (q31_t)0x829869be, (q31_t)0x199f0502, (q31_t)0x829727a0, (q31_t)0x1998dd09, (q31_t)0x8295e5cf, (q31_t)0x1992b4ff, (q31_t)0x8294a44c, + (q31_t)0x198c8ce7, (q31_t)0x82936317, (q31_t)0x198664be, (q31_t)0x8292222e, (q31_t)0x19803c86, (q31_t)0x8290e194, (q31_t)0x197a143e, (q31_t)0x828fa146, + (q31_t)0x1973ebe6, (q31_t)0x828e6146, (q31_t)0x196dc37e, (q31_t)0x828d2193, (q31_t)0x19679b07, (q31_t)0x828be22e, (q31_t)0x19617280, (q31_t)0x828aa316, + (q31_t)0x195b49ea, (q31_t)0x8289644b, (q31_t)0x19552144, (q31_t)0x828825ce, (q31_t)0x194ef88e, (q31_t)0x8286e79e, (q31_t)0x1948cfc8, (q31_t)0x8285a9bb, + (q31_t)0x1942a6f3, (q31_t)0x82846c26, (q31_t)0x193c7e0f, (q31_t)0x82832edf, (q31_t)0x1936551b, (q31_t)0x8281f1e4, (q31_t)0x19302c17, (q31_t)0x8280b538, + (q31_t)0x192a0304, (q31_t)0x827f78d8, (q31_t)0x1923d9e1, (q31_t)0x827e3cc6, (q31_t)0x191db0af, (q31_t)0x827d0102, (q31_t)0x1917876d, (q31_t)0x827bc58a, + (q31_t)0x19115e1c, (q31_t)0x827a8a61, (q31_t)0x190b34bb, (q31_t)0x82794f84, (q31_t)0x19050b4b, (q31_t)0x827814f6, (q31_t)0x18fee1cb, (q31_t)0x8276dab4, + (q31_t)0x18f8b83c, (q31_t)0x8275a0c0, (q31_t)0x18f28e9e, (q31_t)0x8274671a, (q31_t)0x18ec64f0, (q31_t)0x82732dc0, (q31_t)0x18e63b33, (q31_t)0x8271f4b5, + (q31_t)0x18e01167, (q31_t)0x8270bbf7, (q31_t)0x18d9e78b, (q31_t)0x826f8386, (q31_t)0x18d3bda0, (q31_t)0x826e4b62, (q31_t)0x18cd93a5, (q31_t)0x826d138d, + (q31_t)0x18c7699b, (q31_t)0x826bdc04, (q31_t)0x18c13f82, (q31_t)0x826aa4c9, (q31_t)0x18bb155a, (q31_t)0x82696ddc, (q31_t)0x18b4eb22, (q31_t)0x8268373c, + (q31_t)0x18aec0db, (q31_t)0x826700e9, (q31_t)0x18a89685, (q31_t)0x8265cae4, (q31_t)0x18a26c20, (q31_t)0x8264952d, (q31_t)0x189c41ab, (q31_t)0x82635fc2, + (q31_t)0x18961728, (q31_t)0x82622aa6, (q31_t)0x188fec95, (q31_t)0x8260f5d7, (q31_t)0x1889c1f3, (q31_t)0x825fc155, (q31_t)0x18839742, (q31_t)0x825e8d21, + (q31_t)0x187d6c82, (q31_t)0x825d593a, (q31_t)0x187741b2, (q31_t)0x825c25a1, (q31_t)0x187116d4, (q31_t)0x825af255, (q31_t)0x186aebe6, (q31_t)0x8259bf57, + (q31_t)0x1864c0ea, (q31_t)0x82588ca7, (q31_t)0x185e95de, (q31_t)0x82575a44, (q31_t)0x18586ac3, (q31_t)0x8256282e, (q31_t)0x18523f9a, (q31_t)0x8254f666, + (q31_t)0x184c1461, (q31_t)0x8253c4eb, (q31_t)0x1845e919, (q31_t)0x825293be, (q31_t)0x183fbdc3, (q31_t)0x825162df, (q31_t)0x1839925d, (q31_t)0x8250324d, + (q31_t)0x183366e9, (q31_t)0x824f0208, (q31_t)0x182d3b65, (q31_t)0x824dd211, (q31_t)0x18270fd3, (q31_t)0x824ca268, (q31_t)0x1820e431, (q31_t)0x824b730c, + (q31_t)0x181ab881, (q31_t)0x824a43fe, (q31_t)0x18148cc2, (q31_t)0x8249153d, (q31_t)0x180e60f4, (q31_t)0x8247e6ca, (q31_t)0x18083518, (q31_t)0x8246b8a4, + (q31_t)0x1802092c, (q31_t)0x82458acc, (q31_t)0x17fbdd32, (q31_t)0x82445d41, (q31_t)0x17f5b129, (q31_t)0x82433004, (q31_t)0x17ef8511, (q31_t)0x82420315, + (q31_t)0x17e958ea, (q31_t)0x8240d673, (q31_t)0x17e32cb5, (q31_t)0x823faa1e, (q31_t)0x17dd0070, (q31_t)0x823e7e18, (q31_t)0x17d6d41d, (q31_t)0x823d525e, + (q31_t)0x17d0a7bc, (q31_t)0x823c26f3, (q31_t)0x17ca7b4c, (q31_t)0x823afbd5, (q31_t)0x17c44ecd, (q31_t)0x8239d104, (q31_t)0x17be223f, (q31_t)0x8238a681, + (q31_t)0x17b7f5a3, (q31_t)0x82377c4c, (q31_t)0x17b1c8f8, (q31_t)0x82365264, (q31_t)0x17ab9c3e, (q31_t)0x823528ca, (q31_t)0x17a56f76, (q31_t)0x8233ff7e, + (q31_t)0x179f429f, (q31_t)0x8232d67f, (q31_t)0x179915ba, (q31_t)0x8231adce, (q31_t)0x1792e8c6, (q31_t)0x8230856a, (q31_t)0x178cbbc4, (q31_t)0x822f5d54, + (q31_t)0x17868eb3, (q31_t)0x822e358b, (q31_t)0x17806194, (q31_t)0x822d0e10, (q31_t)0x177a3466, (q31_t)0x822be6e3, (q31_t)0x17740729, (q31_t)0x822ac004, + (q31_t)0x176dd9de, (q31_t)0x82299971, (q31_t)0x1767ac85, (q31_t)0x8228732d, (q31_t)0x17617f1d, (q31_t)0x82274d36, (q31_t)0x175b51a7, (q31_t)0x8226278d, + (q31_t)0x17552422, (q31_t)0x82250232, (q31_t)0x174ef68f, (q31_t)0x8223dd24, (q31_t)0x1748c8ee, (q31_t)0x8222b863, (q31_t)0x17429b3e, (q31_t)0x822193f1, + (q31_t)0x173c6d80, (q31_t)0x82206fcc, (q31_t)0x17363fb4, (q31_t)0x821f4bf5, (q31_t)0x173011d9, (q31_t)0x821e286b, (q31_t)0x1729e3f0, (q31_t)0x821d052f, + (q31_t)0x1723b5f9, (q31_t)0x821be240, (q31_t)0x171d87f3, (q31_t)0x821abfa0, (q31_t)0x171759df, (q31_t)0x82199d4d, (q31_t)0x17112bbd, (q31_t)0x82187b47, + (q31_t)0x170afd8d, (q31_t)0x82175990, (q31_t)0x1704cf4f, (q31_t)0x82163826, (q31_t)0x16fea102, (q31_t)0x82151709, (q31_t)0x16f872a7, (q31_t)0x8213f63a, + (q31_t)0x16f2443e, (q31_t)0x8212d5b9, (q31_t)0x16ec15c7, (q31_t)0x8211b586, (q31_t)0x16e5e741, (q31_t)0x821095a0, (q31_t)0x16dfb8ae, (q31_t)0x820f7608, + (q31_t)0x16d98a0c, (q31_t)0x820e56be, (q31_t)0x16d35b5c, (q31_t)0x820d37c1, (q31_t)0x16cd2c9f, (q31_t)0x820c1912, (q31_t)0x16c6fdd3, (q31_t)0x820afab1, + (q31_t)0x16c0cef9, (q31_t)0x8209dc9e, (q31_t)0x16baa011, (q31_t)0x8208bed8, (q31_t)0x16b4711b, (q31_t)0x8207a160, (q31_t)0x16ae4217, (q31_t)0x82068435, + (q31_t)0x16a81305, (q31_t)0x82056758, (q31_t)0x16a1e3e5, (q31_t)0x82044ac9, (q31_t)0x169bb4b7, (q31_t)0x82032e88, (q31_t)0x1695857b, (q31_t)0x82021294, + (q31_t)0x168f5632, (q31_t)0x8200f6ef, (q31_t)0x168926da, (q31_t)0x81ffdb96, (q31_t)0x1682f774, (q31_t)0x81fec08c, (q31_t)0x167cc801, (q31_t)0x81fda5cf, + (q31_t)0x1676987f, (q31_t)0x81fc8b60, (q31_t)0x167068f0, (q31_t)0x81fb713f, (q31_t)0x166a3953, (q31_t)0x81fa576c, (q31_t)0x166409a8, (q31_t)0x81f93de6, + (q31_t)0x165dd9f0, (q31_t)0x81f824ae, (q31_t)0x1657aa29, (q31_t)0x81f70bc3, (q31_t)0x16517a55, (q31_t)0x81f5f327, (q31_t)0x164b4a73, (q31_t)0x81f4dad8, + (q31_t)0x16451a83, (q31_t)0x81f3c2d7, (q31_t)0x163eea86, (q31_t)0x81f2ab24, (q31_t)0x1638ba7a, (q31_t)0x81f193be, (q31_t)0x16328a61, (q31_t)0x81f07ca6, + (q31_t)0x162c5a3b, (q31_t)0x81ef65dc, (q31_t)0x16262a06, (q31_t)0x81ee4f60, (q31_t)0x161ff9c4, (q31_t)0x81ed3932, (q31_t)0x1619c975, (q31_t)0x81ec2351, + (q31_t)0x16139918, (q31_t)0x81eb0dbe, (q31_t)0x160d68ad, (q31_t)0x81e9f879, (q31_t)0x16073834, (q31_t)0x81e8e381, (q31_t)0x160107ae, (q31_t)0x81e7ced8, + (q31_t)0x15fad71b, (q31_t)0x81e6ba7c, (q31_t)0x15f4a679, (q31_t)0x81e5a66e, (q31_t)0x15ee75cb, (q31_t)0x81e492ad, (q31_t)0x15e8450e, (q31_t)0x81e37f3b, + (q31_t)0x15e21445, (q31_t)0x81e26c16, (q31_t)0x15dbe36d, (q31_t)0x81e1593f, (q31_t)0x15d5b288, (q31_t)0x81e046b6, (q31_t)0x15cf8196, (q31_t)0x81df347b, + (q31_t)0x15c95097, (q31_t)0x81de228d, (q31_t)0x15c31f89, (q31_t)0x81dd10ee, (q31_t)0x15bcee6f, (q31_t)0x81dbff9c, (q31_t)0x15b6bd47, (q31_t)0x81daee98, + (q31_t)0x15b08c12, (q31_t)0x81d9dde1, (q31_t)0x15aa5acf, (q31_t)0x81d8cd79, (q31_t)0x15a4297f, (q31_t)0x81d7bd5e, (q31_t)0x159df821, (q31_t)0x81d6ad92, + (q31_t)0x1597c6b7, (q31_t)0x81d59e13, (q31_t)0x1591953e, (q31_t)0x81d48ee1, (q31_t)0x158b63b9, (q31_t)0x81d37ffe, (q31_t)0x15853226, (q31_t)0x81d27169, + (q31_t)0x157f0086, (q31_t)0x81d16321, (q31_t)0x1578ced9, (q31_t)0x81d05527, (q31_t)0x15729d1f, (q31_t)0x81cf477b, (q31_t)0x156c6b57, (q31_t)0x81ce3a1d, + (q31_t)0x15663982, (q31_t)0x81cd2d0c, (q31_t)0x156007a0, (q31_t)0x81cc204a, (q31_t)0x1559d5b1, (q31_t)0x81cb13d5, (q31_t)0x1553a3b4, (q31_t)0x81ca07af, + (q31_t)0x154d71aa, (q31_t)0x81c8fbd6, (q31_t)0x15473f94, (q31_t)0x81c7f04b, (q31_t)0x15410d70, (q31_t)0x81c6e50d, (q31_t)0x153adb3f, (q31_t)0x81c5da1e, + (q31_t)0x1534a901, (q31_t)0x81c4cf7d, (q31_t)0x152e76b5, (q31_t)0x81c3c529, (q31_t)0x1528445d, (q31_t)0x81c2bb23, (q31_t)0x152211f8, (q31_t)0x81c1b16b, + (q31_t)0x151bdf86, (q31_t)0x81c0a801, (q31_t)0x1515ad06, (q31_t)0x81bf9ee5, (q31_t)0x150f7a7a, (q31_t)0x81be9617, (q31_t)0x150947e1, (q31_t)0x81bd8d97, + (q31_t)0x1503153a, (q31_t)0x81bc8564, (q31_t)0x14fce287, (q31_t)0x81bb7d7f, (q31_t)0x14f6afc7, (q31_t)0x81ba75e9, (q31_t)0x14f07cf9, (q31_t)0x81b96ea0, + (q31_t)0x14ea4a1f, (q31_t)0x81b867a5, (q31_t)0x14e41738, (q31_t)0x81b760f8, (q31_t)0x14dde445, (q31_t)0x81b65a99, (q31_t)0x14d7b144, (q31_t)0x81b55488, + (q31_t)0x14d17e36, (q31_t)0x81b44ec4, (q31_t)0x14cb4b1c, (q31_t)0x81b3494f, (q31_t)0x14c517f4, (q31_t)0x81b24427, (q31_t)0x14bee4c0, (q31_t)0x81b13f4e, + (q31_t)0x14b8b17f, (q31_t)0x81b03ac2, (q31_t)0x14b27e32, (q31_t)0x81af3684, (q31_t)0x14ac4ad7, (q31_t)0x81ae3294, (q31_t)0x14a61770, (q31_t)0x81ad2ef2, + (q31_t)0x149fe3fc, (q31_t)0x81ac2b9e, (q31_t)0x1499b07c, (q31_t)0x81ab2898, (q31_t)0x14937cee, (q31_t)0x81aa25e0, (q31_t)0x148d4954, (q31_t)0x81a92376, + (q31_t)0x148715ae, (q31_t)0x81a82159, (q31_t)0x1480e1fa, (q31_t)0x81a71f8b, (q31_t)0x147aae3a, (q31_t)0x81a61e0b, (q31_t)0x14747a6d, (q31_t)0x81a51cd8, + (q31_t)0x146e4694, (q31_t)0x81a41bf4, (q31_t)0x146812ae, (q31_t)0x81a31b5d, (q31_t)0x1461debc, (q31_t)0x81a21b14, (q31_t)0x145baabd, (q31_t)0x81a11b1a, + (q31_t)0x145576b1, (q31_t)0x81a01b6d, (q31_t)0x144f4299, (q31_t)0x819f1c0e, (q31_t)0x14490e74, (q31_t)0x819e1cfd, (q31_t)0x1442da43, (q31_t)0x819d1e3a, + (q31_t)0x143ca605, (q31_t)0x819c1fc5, (q31_t)0x143671bb, (q31_t)0x819b219e, (q31_t)0x14303d65, (q31_t)0x819a23c5, (q31_t)0x142a0902, (q31_t)0x8199263a, + (q31_t)0x1423d492, (q31_t)0x819828fd, (q31_t)0x141da016, (q31_t)0x81972c0e, (q31_t)0x14176b8e, (q31_t)0x81962f6d, (q31_t)0x141136f9, (q31_t)0x8195331a, + (q31_t)0x140b0258, (q31_t)0x81943715, (q31_t)0x1404cdaa, (q31_t)0x81933b5e, (q31_t)0x13fe98f1, (q31_t)0x81923ff4, (q31_t)0x13f8642a, (q31_t)0x819144d9, + (q31_t)0x13f22f58, (q31_t)0x81904a0c, (q31_t)0x13ebfa79, (q31_t)0x818f4f8d, (q31_t)0x13e5c58e, (q31_t)0x818e555c, (q31_t)0x13df9097, (q31_t)0x818d5b78, + (q31_t)0x13d95b93, (q31_t)0x818c61e3, (q31_t)0x13d32683, (q31_t)0x818b689c, (q31_t)0x13ccf167, (q31_t)0x818a6fa3, (q31_t)0x13c6bc3f, (q31_t)0x818976f8, + (q31_t)0x13c0870a, (q31_t)0x81887e9a, (q31_t)0x13ba51ca, (q31_t)0x8187868b, (q31_t)0x13b41c7d, (q31_t)0x81868eca, (q31_t)0x13ade724, (q31_t)0x81859757, + (q31_t)0x13a7b1bf, (q31_t)0x8184a032, (q31_t)0x13a17c4d, (q31_t)0x8183a95b, (q31_t)0x139b46d0, (q31_t)0x8182b2d1, (q31_t)0x13951146, (q31_t)0x8181bc96, + (q31_t)0x138edbb1, (q31_t)0x8180c6a9, (q31_t)0x1388a60f, (q31_t)0x817fd10a, (q31_t)0x13827062, (q31_t)0x817edbb9, (q31_t)0x137c3aa8, (q31_t)0x817de6b6, + (q31_t)0x137604e2, (q31_t)0x817cf201, (q31_t)0x136fcf10, (q31_t)0x817bfd9b, (q31_t)0x13699933, (q31_t)0x817b0982, (q31_t)0x13636349, (q31_t)0x817a15b7, + (q31_t)0x135d2d53, (q31_t)0x8179223a, (q31_t)0x1356f752, (q31_t)0x81782f0b, (q31_t)0x1350c144, (q31_t)0x81773c2b, (q31_t)0x134a8b2b, (q31_t)0x81764998, + (q31_t)0x13445505, (q31_t)0x81755754, (q31_t)0x133e1ed4, (q31_t)0x8174655d, (q31_t)0x1337e897, (q31_t)0x817373b5, (q31_t)0x1331b24e, (q31_t)0x8172825a, + (q31_t)0x132b7bf9, (q31_t)0x8171914e, (q31_t)0x13254599, (q31_t)0x8170a090, (q31_t)0x131f0f2c, (q31_t)0x816fb020, (q31_t)0x1318d8b4, (q31_t)0x816ebffe, + (q31_t)0x1312a230, (q31_t)0x816dd02a, (q31_t)0x130c6ba0, (q31_t)0x816ce0a4, (q31_t)0x13063505, (q31_t)0x816bf16c, (q31_t)0x12fffe5d, (q31_t)0x816b0282, + (q31_t)0x12f9c7aa, (q31_t)0x816a13e6, (q31_t)0x12f390ec, (q31_t)0x81692599, (q31_t)0x12ed5a21, (q31_t)0x81683799, (q31_t)0x12e7234b, (q31_t)0x816749e8, + (q31_t)0x12e0ec6a, (q31_t)0x81665c84, (q31_t)0x12dab57c, (q31_t)0x81656f6f, (q31_t)0x12d47e83, (q31_t)0x816482a8, (q31_t)0x12ce477f, (q31_t)0x8163962f, + (q31_t)0x12c8106f, (q31_t)0x8162aa04, (q31_t)0x12c1d953, (q31_t)0x8161be27, (q31_t)0x12bba22b, (q31_t)0x8160d298, (q31_t)0x12b56af9, (q31_t)0x815fe758, + (q31_t)0x12af33ba, (q31_t)0x815efc65, (q31_t)0x12a8fc70, (q31_t)0x815e11c1, (q31_t)0x12a2c51b, (q31_t)0x815d276a, (q31_t)0x129c8dba, (q31_t)0x815c3d62, + (q31_t)0x1296564d, (q31_t)0x815b53a8, (q31_t)0x12901ed5, (q31_t)0x815a6a3c, (q31_t)0x1289e752, (q31_t)0x8159811e, (q31_t)0x1283afc3, (q31_t)0x8158984e, + (q31_t)0x127d7829, (q31_t)0x8157afcd, (q31_t)0x12774083, (q31_t)0x8156c799, (q31_t)0x127108d2, (q31_t)0x8155dfb4, (q31_t)0x126ad116, (q31_t)0x8154f81d, + (q31_t)0x1264994e, (q31_t)0x815410d4, (q31_t)0x125e617b, (q31_t)0x815329d9, (q31_t)0x1258299c, (q31_t)0x8152432c, (q31_t)0x1251f1b3, (q31_t)0x81515ccd, + (q31_t)0x124bb9be, (q31_t)0x815076bd, (q31_t)0x124581bd, (q31_t)0x814f90fb, (q31_t)0x123f49b2, (q31_t)0x814eab86, (q31_t)0x1239119b, (q31_t)0x814dc660, + (q31_t)0x1232d979, (q31_t)0x814ce188, (q31_t)0x122ca14b, (q31_t)0x814bfcff, (q31_t)0x12266913, (q31_t)0x814b18c3, (q31_t)0x122030cf, (q31_t)0x814a34d6, + (q31_t)0x1219f880, (q31_t)0x81495136, (q31_t)0x1213c026, (q31_t)0x81486de5, (q31_t)0x120d87c1, (q31_t)0x81478ae2, (q31_t)0x12074f50, (q31_t)0x8146a82e, + (q31_t)0x120116d5, (q31_t)0x8145c5c7, (q31_t)0x11fade4e, (q31_t)0x8144e3ae, (q31_t)0x11f4a5bd, (q31_t)0x814401e4, (q31_t)0x11ee6d20, (q31_t)0x81432068, + (q31_t)0x11e83478, (q31_t)0x81423f3a, (q31_t)0x11e1fbc5, (q31_t)0x81415e5a, (q31_t)0x11dbc307, (q31_t)0x81407dc9, (q31_t)0x11d58a3e, (q31_t)0x813f9d86, + (q31_t)0x11cf516a, (q31_t)0x813ebd90, (q31_t)0x11c9188b, (q31_t)0x813ddde9, (q31_t)0x11c2dfa2, (q31_t)0x813cfe91, (q31_t)0x11bca6ad, (q31_t)0x813c1f86, + (q31_t)0x11b66dad, (q31_t)0x813b40ca, (q31_t)0x11b034a2, (q31_t)0x813a625b, (q31_t)0x11a9fb8d, (q31_t)0x8139843b, (q31_t)0x11a3c26c, (q31_t)0x8138a66a, + (q31_t)0x119d8941, (q31_t)0x8137c8e6, (q31_t)0x1197500a, (q31_t)0x8136ebb1, (q31_t)0x119116c9, (q31_t)0x81360ec9, (q31_t)0x118add7d, (q31_t)0x81353230, + (q31_t)0x1184a427, (q31_t)0x813455e6, (q31_t)0x117e6ac5, (q31_t)0x813379e9, (q31_t)0x11783159, (q31_t)0x81329e3b, (q31_t)0x1171f7e2, (q31_t)0x8131c2db, + (q31_t)0x116bbe60, (q31_t)0x8130e7c9, (q31_t)0x116584d3, (q31_t)0x81300d05, (q31_t)0x115f4b3c, (q31_t)0x812f3290, (q31_t)0x1159119a, (q31_t)0x812e5868, + (q31_t)0x1152d7ed, (q31_t)0x812d7e8f, (q31_t)0x114c9e35, (q31_t)0x812ca505, (q31_t)0x11466473, (q31_t)0x812bcbc8, (q31_t)0x11402aa6, (q31_t)0x812af2da, + (q31_t)0x1139f0cf, (q31_t)0x812a1a3a, (q31_t)0x1133b6ed, (q31_t)0x812941e8, (q31_t)0x112d7d00, (q31_t)0x812869e4, (q31_t)0x11274309, (q31_t)0x8127922f, + (q31_t)0x11210907, (q31_t)0x8126bac8, (q31_t)0x111acefb, (q31_t)0x8125e3af, (q31_t)0x111494e4, (q31_t)0x81250ce4, (q31_t)0x110e5ac2, (q31_t)0x81243668, + (q31_t)0x11082096, (q31_t)0x8123603a, (q31_t)0x1101e65f, (q31_t)0x81228a5a, (q31_t)0x10fbac1e, (q31_t)0x8121b4c8, (q31_t)0x10f571d3, (q31_t)0x8120df85, + (q31_t)0x10ef377d, (q31_t)0x81200a90, (q31_t)0x10e8fd1c, (q31_t)0x811f35e9, (q31_t)0x10e2c2b2, (q31_t)0x811e6191, (q31_t)0x10dc883c, (q31_t)0x811d8d86, + (q31_t)0x10d64dbd, (q31_t)0x811cb9ca, (q31_t)0x10d01333, (q31_t)0x811be65d, (q31_t)0x10c9d89e, (q31_t)0x811b133d, (q31_t)0x10c39dff, (q31_t)0x811a406c, + (q31_t)0x10bd6356, (q31_t)0x81196de9, (q31_t)0x10b728a3, (q31_t)0x81189bb4, (q31_t)0x10b0ede5, (q31_t)0x8117c9ce, (q31_t)0x10aab31d, (q31_t)0x8116f836, + (q31_t)0x10a4784b, (q31_t)0x811626ec, (q31_t)0x109e3d6e, (q31_t)0x811555f1, (q31_t)0x10980287, (q31_t)0x81148544, (q31_t)0x1091c796, (q31_t)0x8113b4e5, + (q31_t)0x108b8c9b, (q31_t)0x8112e4d4, (q31_t)0x10855195, (q31_t)0x81121512, (q31_t)0x107f1686, (q31_t)0x8111459e, (q31_t)0x1078db6c, (q31_t)0x81107678, + (q31_t)0x1072a048, (q31_t)0x810fa7a0, (q31_t)0x106c651a, (q31_t)0x810ed917, (q31_t)0x106629e1, (q31_t)0x810e0adc, (q31_t)0x105fee9f, (q31_t)0x810d3cf0, + (q31_t)0x1059b352, (q31_t)0x810c6f52, (q31_t)0x105377fc, (q31_t)0x810ba202, (q31_t)0x104d3c9b, (q31_t)0x810ad500, (q31_t)0x10470130, (q31_t)0x810a084d, + (q31_t)0x1040c5bb, (q31_t)0x81093be8, (q31_t)0x103a8a3d, (q31_t)0x81086fd1, (q31_t)0x10344eb4, (q31_t)0x8107a409, (q31_t)0x102e1321, (q31_t)0x8106d88f, + (q31_t)0x1027d784, (q31_t)0x81060d63, (q31_t)0x10219bdd, (q31_t)0x81054286, (q31_t)0x101b602d, (q31_t)0x810477f7, (q31_t)0x10152472, (q31_t)0x8103adb6, + (q31_t)0x100ee8ad, (q31_t)0x8102e3c4, (q31_t)0x1008acdf, (q31_t)0x81021a20, (q31_t)0x10027107, (q31_t)0x810150ca, (q31_t)0xffc3524, (q31_t)0x810087c3, + (q31_t)0xff5f938, (q31_t)0x80ffbf0a, (q31_t)0xfefbd42, (q31_t)0x80fef69f, (q31_t)0xfe98143, (q31_t)0x80fe2e83, (q31_t)0xfe34539, (q31_t)0x80fd66b5, + (q31_t)0xfdd0926, (q31_t)0x80fc9f35, (q31_t)0xfd6cd08, (q31_t)0x80fbd804, (q31_t)0xfd090e1, (q31_t)0x80fb1121, (q31_t)0xfca54b1, (q31_t)0x80fa4a8c, + (q31_t)0xfc41876, (q31_t)0x80f98446, (q31_t)0xfbddc32, (q31_t)0x80f8be4e, (q31_t)0xfb79fe4, (q31_t)0x80f7f8a4, (q31_t)0xfb1638d, (q31_t)0x80f73349, + (q31_t)0xfab272b, (q31_t)0x80f66e3c, (q31_t)0xfa4eac0, (q31_t)0x80f5a97e, (q31_t)0xf9eae4c, (q31_t)0x80f4e50e, (q31_t)0xf9871ce, (q31_t)0x80f420ec, + (q31_t)0xf923546, (q31_t)0x80f35d19, (q31_t)0xf8bf8b4, (q31_t)0x80f29994, (q31_t)0xf85bc19, (q31_t)0x80f1d65d, (q31_t)0xf7f7f75, (q31_t)0x80f11375, + (q31_t)0xf7942c7, (q31_t)0x80f050db, (q31_t)0xf73060f, (q31_t)0x80ef8e90, (q31_t)0xf6cc94e, (q31_t)0x80eecc93, (q31_t)0xf668c83, (q31_t)0x80ee0ae4, + (q31_t)0xf604faf, (q31_t)0x80ed4984, (q31_t)0xf5a12d1, (q31_t)0x80ec8872, (q31_t)0xf53d5ea, (q31_t)0x80ebc7ae, (q31_t)0xf4d98f9, (q31_t)0x80eb0739, + (q31_t)0xf475bff, (q31_t)0x80ea4712, (q31_t)0xf411efb, (q31_t)0x80e9873a, (q31_t)0xf3ae1ee, (q31_t)0x80e8c7b0, (q31_t)0xf34a4d8, (q31_t)0x80e80874, + (q31_t)0xf2e67b8, (q31_t)0x80e74987, (q31_t)0xf282a8f, (q31_t)0x80e68ae8, (q31_t)0xf21ed5d, (q31_t)0x80e5cc98, (q31_t)0xf1bb021, (q31_t)0x80e50e96, + (q31_t)0xf1572dc, (q31_t)0x80e450e2, (q31_t)0xf0f358e, (q31_t)0x80e3937d, (q31_t)0xf08f836, (q31_t)0x80e2d666, (q31_t)0xf02bad5, (q31_t)0x80e2199e, + (q31_t)0xefc7d6b, (q31_t)0x80e15d24, (q31_t)0xef63ff7, (q31_t)0x80e0a0f8, (q31_t)0xef0027b, (q31_t)0x80dfe51b, (q31_t)0xee9c4f5, (q31_t)0x80df298c, + (q31_t)0xee38766, (q31_t)0x80de6e4c, (q31_t)0xedd49ce, (q31_t)0x80ddb35a, (q31_t)0xed70c2c, (q31_t)0x80dcf8b7, (q31_t)0xed0ce82, (q31_t)0x80dc3e62, + (q31_t)0xeca90ce, (q31_t)0x80db845b, (q31_t)0xec45311, (q31_t)0x80dacaa3, (q31_t)0xebe154b, (q31_t)0x80da1139, (q31_t)0xeb7d77c, (q31_t)0x80d9581e, + (q31_t)0xeb199a4, (q31_t)0x80d89f51, (q31_t)0xeab5bc3, (q31_t)0x80d7e6d3, (q31_t)0xea51dd8, (q31_t)0x80d72ea3, (q31_t)0xe9edfe5, (q31_t)0x80d676c1, + (q31_t)0xe98a1e9, (q31_t)0x80d5bf2e, (q31_t)0xe9263e3, (q31_t)0x80d507e9, (q31_t)0xe8c25d5, (q31_t)0x80d450f3, (q31_t)0xe85e7be, (q31_t)0x80d39a4b, + (q31_t)0xe7fa99e, (q31_t)0x80d2e3f2, (q31_t)0xe796b74, (q31_t)0x80d22de7, (q31_t)0xe732d42, (q31_t)0x80d1782a, (q31_t)0xe6cef07, (q31_t)0x80d0c2bc, + (q31_t)0xe66b0c3, (q31_t)0x80d00d9d, (q31_t)0xe607277, (q31_t)0x80cf58cc, (q31_t)0xe5a3421, (q31_t)0x80cea449, (q31_t)0xe53f5c2, (q31_t)0x80cdf015, + (q31_t)0xe4db75b, (q31_t)0x80cd3c2f, (q31_t)0xe4778eb, (q31_t)0x80cc8898, (q31_t)0xe413a72, (q31_t)0x80cbd54f, (q31_t)0xe3afbf0, (q31_t)0x80cb2255, + (q31_t)0xe34bd66, (q31_t)0x80ca6fa9, (q31_t)0xe2e7ed2, (q31_t)0x80c9bd4c, (q31_t)0xe284036, (q31_t)0x80c90b3d, (q31_t)0xe220191, (q31_t)0x80c8597c, + (q31_t)0xe1bc2e4, (q31_t)0x80c7a80a, (q31_t)0xe15842e, (q31_t)0x80c6f6e7, (q31_t)0xe0f456f, (q31_t)0x80c64612, (q31_t)0xe0906a7, (q31_t)0x80c5958b, + (q31_t)0xe02c7d7, (q31_t)0x80c4e553, (q31_t)0xdfc88fe, (q31_t)0x80c4356a, (q31_t)0xdf64a1c, (q31_t)0x80c385cf, (q31_t)0xdf00b32, (q31_t)0x80c2d682, + (q31_t)0xde9cc40, (q31_t)0x80c22784, (q31_t)0xde38d44, (q31_t)0x80c178d4, (q31_t)0xddd4e40, (q31_t)0x80c0ca73, (q31_t)0xdd70f34, (q31_t)0x80c01c60, + (q31_t)0xdd0d01f, (q31_t)0x80bf6e9c, (q31_t)0xdca9102, (q31_t)0x80bec127, (q31_t)0xdc451dc, (q31_t)0x80be13ff, (q31_t)0xdbe12ad, (q31_t)0x80bd6727, + (q31_t)0xdb7d376, (q31_t)0x80bcba9d, (q31_t)0xdb19437, (q31_t)0x80bc0e61, (q31_t)0xdab54ef, (q31_t)0x80bb6274, (q31_t)0xda5159f, (q31_t)0x80bab6d5, + (q31_t)0xd9ed646, (q31_t)0x80ba0b85, (q31_t)0xd9896e5, (q31_t)0x80b96083, (q31_t)0xd92577b, (q31_t)0x80b8b5d0, (q31_t)0xd8c1809, (q31_t)0x80b80b6c, + (q31_t)0xd85d88f, (q31_t)0x80b76156, (q31_t)0xd7f990c, (q31_t)0x80b6b78e, (q31_t)0xd795982, (q31_t)0x80b60e15, (q31_t)0xd7319ee, (q31_t)0x80b564ea, + (q31_t)0xd6cda53, (q31_t)0x80b4bc0e, (q31_t)0xd669aaf, (q31_t)0x80b41381, (q31_t)0xd605b03, (q31_t)0x80b36b42, (q31_t)0xd5a1b4f, (q31_t)0x80b2c351, + (q31_t)0xd53db92, (q31_t)0x80b21baf, (q31_t)0xd4d9bcd, (q31_t)0x80b1745c, (q31_t)0xd475c00, (q31_t)0x80b0cd57, (q31_t)0xd411c2b, (q31_t)0x80b026a1, + (q31_t)0xd3adc4e, (q31_t)0x80af8039, (q31_t)0xd349c68, (q31_t)0x80aeda20, (q31_t)0xd2e5c7b, (q31_t)0x80ae3455, (q31_t)0xd281c85, (q31_t)0x80ad8ed9, + (q31_t)0xd21dc87, (q31_t)0x80ace9ab, (q31_t)0xd1b9c81, (q31_t)0x80ac44cc, (q31_t)0xd155c73, (q31_t)0x80aba03b, (q31_t)0xd0f1c5d, (q31_t)0x80aafbf9, + (q31_t)0xd08dc3f, (q31_t)0x80aa5806, (q31_t)0xd029c18, (q31_t)0x80a9b461, (q31_t)0xcfc5bea, (q31_t)0x80a9110b, (q31_t)0xcf61bb4, (q31_t)0x80a86e03, + (q31_t)0xcefdb76, (q31_t)0x80a7cb49, (q31_t)0xce99b2f, (q31_t)0x80a728df, (q31_t)0xce35ae1, (q31_t)0x80a686c2, (q31_t)0xcdd1a8b, (q31_t)0x80a5e4f5, + (q31_t)0xcd6da2d, (q31_t)0x80a54376, (q31_t)0xcd099c7, (q31_t)0x80a4a245, (q31_t)0xcca5959, (q31_t)0x80a40163, (q31_t)0xcc418e3, (q31_t)0x80a360d0, + (q31_t)0xcbdd865, (q31_t)0x80a2c08b, (q31_t)0xcb797e0, (q31_t)0x80a22095, (q31_t)0xcb15752, (q31_t)0x80a180ed, (q31_t)0xcab16bd, (q31_t)0x80a0e194, + (q31_t)0xca4d620, (q31_t)0x80a04289, (q31_t)0xc9e957b, (q31_t)0x809fa3cd, (q31_t)0xc9854cf, (q31_t)0x809f0560, (q31_t)0xc92141a, (q31_t)0x809e6741, + (q31_t)0xc8bd35e, (q31_t)0x809dc971, (q31_t)0xc85929a, (q31_t)0x809d2bef, (q31_t)0xc7f51cf, (q31_t)0x809c8ebc, (q31_t)0xc7910fb, (q31_t)0x809bf1d7, + (q31_t)0xc72d020, (q31_t)0x809b5541, (q31_t)0xc6c8f3e, (q31_t)0x809ab8fa, (q31_t)0xc664e53, (q31_t)0x809a1d01, (q31_t)0xc600d61, (q31_t)0x80998157, + (q31_t)0xc59cc68, (q31_t)0x8098e5fb, (q31_t)0xc538b66, (q31_t)0x80984aee, (q31_t)0xc4d4a5d, (q31_t)0x8097b030, (q31_t)0xc47094d, (q31_t)0x809715c0, + (q31_t)0xc40c835, (q31_t)0x80967b9f, (q31_t)0xc3a8715, (q31_t)0x8095e1cc, (q31_t)0xc3445ee, (q31_t)0x80954848, (q31_t)0xc2e04c0, (q31_t)0x8094af13, + (q31_t)0xc27c389, (q31_t)0x8094162c, (q31_t)0xc21824c, (q31_t)0x80937d93, (q31_t)0xc1b4107, (q31_t)0x8092e54a, (q31_t)0xc14ffba, (q31_t)0x80924d4f, + (q31_t)0xc0ebe66, (q31_t)0x8091b5a2, (q31_t)0xc087d0a, (q31_t)0x80911e44, (q31_t)0xc023ba7, (q31_t)0x80908735, (q31_t)0xbfbfa3d, (q31_t)0x808ff074, + (q31_t)0xbf5b8cb, (q31_t)0x808f5a02, (q31_t)0xbef7752, (q31_t)0x808ec3df, (q31_t)0xbe935d2, (q31_t)0x808e2e0a, (q31_t)0xbe2f44a, (q31_t)0x808d9884, + (q31_t)0xbdcb2bb, (q31_t)0x808d034c, (q31_t)0xbd67124, (q31_t)0x808c6e63, (q31_t)0xbd02f87, (q31_t)0x808bd9c9, (q31_t)0xbc9ede2, (q31_t)0x808b457d, + (q31_t)0xbc3ac35, (q31_t)0x808ab180, (q31_t)0xbbd6a82, (q31_t)0x808a1dd2, (q31_t)0xbb728c7, (q31_t)0x80898a72, (q31_t)0xbb0e705, (q31_t)0x8088f761, + (q31_t)0xbaaa53b, (q31_t)0x8088649e, (q31_t)0xba4636b, (q31_t)0x8087d22a, (q31_t)0xb9e2193, (q31_t)0x80874005, (q31_t)0xb97dfb5, (q31_t)0x8086ae2e, + (q31_t)0xb919dcf, (q31_t)0x80861ca6, (q31_t)0xb8b5be1, (q31_t)0x80858b6c, (q31_t)0xb8519ed, (q31_t)0x8084fa82, (q31_t)0xb7ed7f2, (q31_t)0x808469e5, + (q31_t)0xb7895f0, (q31_t)0x8083d998, (q31_t)0xb7253e6, (q31_t)0x80834999, (q31_t)0xb6c11d5, (q31_t)0x8082b9e9, (q31_t)0xb65cfbe, (q31_t)0x80822a87, + (q31_t)0xb5f8d9f, (q31_t)0x80819b74, (q31_t)0xb594b7a, (q31_t)0x80810cb0, (q31_t)0xb53094d, (q31_t)0x80807e3a, (q31_t)0xb4cc719, (q31_t)0x807ff013, + (q31_t)0xb4684df, (q31_t)0x807f623b, (q31_t)0xb40429d, (q31_t)0x807ed4b1, (q31_t)0xb3a0055, (q31_t)0x807e4776, (q31_t)0xb33be05, (q31_t)0x807dba89, + (q31_t)0xb2d7baf, (q31_t)0x807d2dec, (q31_t)0xb273952, (q31_t)0x807ca19c, (q31_t)0xb20f6ee, (q31_t)0x807c159c, (q31_t)0xb1ab483, (q31_t)0x807b89ea, + (q31_t)0xb147211, (q31_t)0x807afe87, (q31_t)0xb0e2f98, (q31_t)0x807a7373, (q31_t)0xb07ed19, (q31_t)0x8079e8ad, (q31_t)0xb01aa92, (q31_t)0x80795e36, + (q31_t)0xafb6805, (q31_t)0x8078d40d, (q31_t)0xaf52571, (q31_t)0x80784a33, (q31_t)0xaeee2d7, (q31_t)0x8077c0a8, (q31_t)0xae8a036, (q31_t)0x8077376c, + (q31_t)0xae25d8d, (q31_t)0x8076ae7e, (q31_t)0xadc1adf, (q31_t)0x807625df, (q31_t)0xad5d829, (q31_t)0x80759d8e, (q31_t)0xacf956d, (q31_t)0x8075158c, + (q31_t)0xac952aa, (q31_t)0x80748dd9, (q31_t)0xac30fe1, (q31_t)0x80740675, (q31_t)0xabccd11, (q31_t)0x80737f5f, (q31_t)0xab68a3a, (q31_t)0x8072f898, + (q31_t)0xab0475c, (q31_t)0x8072721f, (q31_t)0xaaa0478, (q31_t)0x8071ebf6, (q31_t)0xaa3c18e, (q31_t)0x8071661a, (q31_t)0xa9d7e9d, (q31_t)0x8070e08e, + (q31_t)0xa973ba5, (q31_t)0x80705b50, (q31_t)0xa90f8a7, (q31_t)0x806fd661, (q31_t)0xa8ab5a2, (q31_t)0x806f51c1, (q31_t)0xa847297, (q31_t)0x806ecd6f, + (q31_t)0xa7e2f85, (q31_t)0x806e496c, (q31_t)0xa77ec6d, (q31_t)0x806dc5b8, (q31_t)0xa71a94f, (q31_t)0x806d4253, (q31_t)0xa6b662a, (q31_t)0x806cbf3c, + (q31_t)0xa6522fe, (q31_t)0x806c3c74, (q31_t)0xa5edfcc, (q31_t)0x806bb9fa, (q31_t)0xa589c94, (q31_t)0x806b37cf, (q31_t)0xa525955, (q31_t)0x806ab5f3, + (q31_t)0xa4c1610, (q31_t)0x806a3466, (q31_t)0xa45d2c5, (q31_t)0x8069b327, (q31_t)0xa3f8f73, (q31_t)0x80693237, (q31_t)0xa394c1b, (q31_t)0x8068b196, + (q31_t)0xa3308bd, (q31_t)0x80683143, (q31_t)0xa2cc558, (q31_t)0x8067b13f, (q31_t)0xa2681ed, (q31_t)0x8067318a, (q31_t)0xa203e7c, (q31_t)0x8066b224, + (q31_t)0xa19fb04, (q31_t)0x8066330c, (q31_t)0xa13b787, (q31_t)0x8065b443, (q31_t)0xa0d7403, (q31_t)0x806535c9, (q31_t)0xa073079, (q31_t)0x8064b79d, + (q31_t)0xa00ece8, (q31_t)0x806439c0, (q31_t)0x9faa952, (q31_t)0x8063bc32, (q31_t)0x9f465b5, (q31_t)0x80633ef3, (q31_t)0x9ee2213, (q31_t)0x8062c202, + (q31_t)0x9e7de6a, (q31_t)0x80624560, (q31_t)0x9e19abb, (q31_t)0x8061c90c, (q31_t)0x9db5706, (q31_t)0x80614d08, (q31_t)0x9d5134b, (q31_t)0x8060d152, + (q31_t)0x9cecf89, (q31_t)0x806055eb, (q31_t)0x9c88bc2, (q31_t)0x805fdad2, (q31_t)0x9c247f5, (q31_t)0x805f6009, (q31_t)0x9bc0421, (q31_t)0x805ee58e, + (q31_t)0x9b5c048, (q31_t)0x805e6b62, (q31_t)0x9af7c69, (q31_t)0x805df184, (q31_t)0x9a93884, (q31_t)0x805d77f5, (q31_t)0x9a2f498, (q31_t)0x805cfeb5, + (q31_t)0x99cb0a7, (q31_t)0x805c85c4, (q31_t)0x9966cb0, (q31_t)0x805c0d21, (q31_t)0x99028b3, (q31_t)0x805b94ce, (q31_t)0x989e4b0, (q31_t)0x805b1cc8, + (q31_t)0x983a0a7, (q31_t)0x805aa512, (q31_t)0x97d5c99, (q31_t)0x805a2daa, (q31_t)0x9771884, (q31_t)0x8059b692, (q31_t)0x970d46a, (q31_t)0x80593fc7, + (q31_t)0x96a9049, (q31_t)0x8058c94c, (q31_t)0x9644c23, (q31_t)0x8058531f, (q31_t)0x95e07f8, (q31_t)0x8057dd41, (q31_t)0x957c3c6, (q31_t)0x805767b2, + (q31_t)0x9517f8f, (q31_t)0x8056f272, (q31_t)0x94b3b52, (q31_t)0x80567d80, (q31_t)0x944f70f, (q31_t)0x805608dd, (q31_t)0x93eb2c6, (q31_t)0x80559489, + (q31_t)0x9386e78, (q31_t)0x80552084, (q31_t)0x9322a24, (q31_t)0x8054accd, (q31_t)0x92be5ca, (q31_t)0x80543965, (q31_t)0x925a16b, (q31_t)0x8053c64c, + (q31_t)0x91f5d06, (q31_t)0x80535381, (q31_t)0x919189c, (q31_t)0x8052e106, (q31_t)0x912d42c, (q31_t)0x80526ed9, (q31_t)0x90c8fb6, (q31_t)0x8051fcfb, + (q31_t)0x9064b3a, (q31_t)0x80518b6b, (q31_t)0x90006ba, (q31_t)0x80511a2b, (q31_t)0x8f9c233, (q31_t)0x8050a939, (q31_t)0x8f37da7, (q31_t)0x80503896, + (q31_t)0x8ed3916, (q31_t)0x804fc841, (q31_t)0x8e6f47f, (q31_t)0x804f583c, (q31_t)0x8e0afe2, (q31_t)0x804ee885, (q31_t)0x8da6b40, (q31_t)0x804e791d, + (q31_t)0x8d42699, (q31_t)0x804e0a04, (q31_t)0x8cde1ec, (q31_t)0x804d9b39, (q31_t)0x8c79d3a, (q31_t)0x804d2cbd, (q31_t)0x8c15882, (q31_t)0x804cbe90, + (q31_t)0x8bb13c5, (q31_t)0x804c50b2, (q31_t)0x8b4cf02, (q31_t)0x804be323, (q31_t)0x8ae8a3a, (q31_t)0x804b75e2, (q31_t)0x8a8456d, (q31_t)0x804b08f0, + (q31_t)0x8a2009a, (q31_t)0x804a9c4d, (q31_t)0x89bbbc3, (q31_t)0x804a2ff9, (q31_t)0x89576e5, (q31_t)0x8049c3f3, (q31_t)0x88f3203, (q31_t)0x8049583d, + (q31_t)0x888ed1b, (q31_t)0x8048ecd5, (q31_t)0x882a82e, (q31_t)0x804881bb, (q31_t)0x87c633c, (q31_t)0x804816f1, (q31_t)0x8761e44, (q31_t)0x8047ac75, + (q31_t)0x86fd947, (q31_t)0x80474248, (q31_t)0x8699445, (q31_t)0x8046d86a, (q31_t)0x8634f3e, (q31_t)0x80466edb, (q31_t)0x85d0a32, (q31_t)0x8046059b, + (q31_t)0x856c520, (q31_t)0x80459ca9, (q31_t)0x850800a, (q31_t)0x80453406, (q31_t)0x84a3aee, (q31_t)0x8044cbb2, (q31_t)0x843f5cd, (q31_t)0x804463ad, + (q31_t)0x83db0a7, (q31_t)0x8043fbf6, (q31_t)0x8376b7c, (q31_t)0x8043948e, (q31_t)0x831264c, (q31_t)0x80432d75, (q31_t)0x82ae117, (q31_t)0x8042c6ab, + (q31_t)0x8249bdd, (q31_t)0x80426030, (q31_t)0x81e569d, (q31_t)0x8041fa03, (q31_t)0x8181159, (q31_t)0x80419425, (q31_t)0x811cc10, (q31_t)0x80412e96, + (q31_t)0x80b86c2, (q31_t)0x8040c956, (q31_t)0x805416e, (q31_t)0x80406465, (q31_t)0x7fefc16, (q31_t)0x803fffc2, (q31_t)0x7f8b6b9, (q31_t)0x803f9b6f, + (q31_t)0x7f27157, (q31_t)0x803f376a, (q31_t)0x7ec2bf0, (q31_t)0x803ed3b3, (q31_t)0x7e5e685, (q31_t)0x803e704c, (q31_t)0x7dfa114, (q31_t)0x803e0d34, + (q31_t)0x7d95b9e, (q31_t)0x803daa6a, (q31_t)0x7d31624, (q31_t)0x803d47ef, (q31_t)0x7ccd0a5, (q31_t)0x803ce5c3, (q31_t)0x7c68b21, (q31_t)0x803c83e5, + (q31_t)0x7c04598, (q31_t)0x803c2257, (q31_t)0x7ba000b, (q31_t)0x803bc117, (q31_t)0x7b3ba78, (q31_t)0x803b6026, (q31_t)0x7ad74e1, (q31_t)0x803aff84, + (q31_t)0x7a72f45, (q31_t)0x803a9f31, (q31_t)0x7a0e9a5, (q31_t)0x803a3f2d, (q31_t)0x79aa400, (q31_t)0x8039df77, (q31_t)0x7945e56, (q31_t)0x80398010, + (q31_t)0x78e18a7, (q31_t)0x803920f8, (q31_t)0x787d2f4, (q31_t)0x8038c22f, (q31_t)0x7818d3c, (q31_t)0x803863b5, (q31_t)0x77b4780, (q31_t)0x80380589, + (q31_t)0x77501be, (q31_t)0x8037a7ac, (q31_t)0x76ebbf9, (q31_t)0x80374a1f, (q31_t)0x768762e, (q31_t)0x8036ece0, (q31_t)0x762305f, (q31_t)0x80368fef, + (q31_t)0x75bea8c, (q31_t)0x8036334e, (q31_t)0x755a4b4, (q31_t)0x8035d6fb, (q31_t)0x74f5ed7, (q31_t)0x80357af8, (q31_t)0x74918f6, (q31_t)0x80351f43, + (q31_t)0x742d311, (q31_t)0x8034c3dd, (q31_t)0x73c8d27, (q31_t)0x803468c5, (q31_t)0x7364738, (q31_t)0x80340dfd, (q31_t)0x7300145, (q31_t)0x8033b383, + (q31_t)0x729bb4e, (q31_t)0x80335959, (q31_t)0x7237552, (q31_t)0x8032ff7d, (q31_t)0x71d2f52, (q31_t)0x8032a5ef, (q31_t)0x716e94e, (q31_t)0x80324cb1, + (q31_t)0x710a345, (q31_t)0x8031f3c2, (q31_t)0x70a5d37, (q31_t)0x80319b21, (q31_t)0x7041726, (q31_t)0x803142cf, (q31_t)0x6fdd110, (q31_t)0x8030eacd, + (q31_t)0x6f78af6, (q31_t)0x80309318, (q31_t)0x6f144d7, (q31_t)0x80303bb3, (q31_t)0x6eafeb4, (q31_t)0x802fe49d, (q31_t)0x6e4b88d, (q31_t)0x802f8dd5, + (q31_t)0x6de7262, (q31_t)0x802f375d, (q31_t)0x6d82c32, (q31_t)0x802ee133, (q31_t)0x6d1e5fe, (q31_t)0x802e8b58, (q31_t)0x6cb9fc6, (q31_t)0x802e35cb, + (q31_t)0x6c5598a, (q31_t)0x802de08e, (q31_t)0x6bf1349, (q31_t)0x802d8ba0, (q31_t)0x6b8cd05, (q31_t)0x802d3700, (q31_t)0x6b286bc, (q31_t)0x802ce2af, + (q31_t)0x6ac406f, (q31_t)0x802c8ead, (q31_t)0x6a5fa1e, (q31_t)0x802c3afa, (q31_t)0x69fb3c9, (q31_t)0x802be796, (q31_t)0x6996d70, (q31_t)0x802b9480, + (q31_t)0x6932713, (q31_t)0x802b41ba, (q31_t)0x68ce0b2, (q31_t)0x802aef42, (q31_t)0x6869a4c, (q31_t)0x802a9d19, (q31_t)0x68053e3, (q31_t)0x802a4b3f, + (q31_t)0x67a0d76, (q31_t)0x8029f9b4, (q31_t)0x673c704, (q31_t)0x8029a878, (q31_t)0x66d808f, (q31_t)0x8029578b, (q31_t)0x6673a16, (q31_t)0x802906ec, + (q31_t)0x660f398, (q31_t)0x8028b69c, (q31_t)0x65aad17, (q31_t)0x8028669b, (q31_t)0x6546692, (q31_t)0x802816e9, (q31_t)0x64e2009, (q31_t)0x8027c786, + (q31_t)0x647d97c, (q31_t)0x80277872, (q31_t)0x64192eb, (q31_t)0x802729ad, (q31_t)0x63b4c57, (q31_t)0x8026db36, (q31_t)0x63505be, (q31_t)0x80268d0e, + (q31_t)0x62ebf22, (q31_t)0x80263f36, (q31_t)0x6287882, (q31_t)0x8025f1ac, (q31_t)0x62231de, (q31_t)0x8025a471, (q31_t)0x61beb36, (q31_t)0x80255784, + (q31_t)0x615a48b, (q31_t)0x80250ae7, (q31_t)0x60f5ddc, (q31_t)0x8024be99, (q31_t)0x6091729, (q31_t)0x80247299, (q31_t)0x602d072, (q31_t)0x802426e8, + (q31_t)0x5fc89b8, (q31_t)0x8023db86, (q31_t)0x5f642fa, (q31_t)0x80239073, (q31_t)0x5effc38, (q31_t)0x802345af, (q31_t)0x5e9b572, (q31_t)0x8022fb3a, + (q31_t)0x5e36ea9, (q31_t)0x8022b114, (q31_t)0x5dd27dd, (q31_t)0x8022673c, (q31_t)0x5d6e10c, (q31_t)0x80221db3, (q31_t)0x5d09a38, (q31_t)0x8021d47a, + (q31_t)0x5ca5361, (q31_t)0x80218b8f, (q31_t)0x5c40c86, (q31_t)0x802142f3, (q31_t)0x5bdc5a7, (q31_t)0x8020faa6, (q31_t)0x5b77ec5, (q31_t)0x8020b2a7, + (q31_t)0x5b137df, (q31_t)0x80206af8, (q31_t)0x5aaf0f6, (q31_t)0x80202397, (q31_t)0x5a4aa09, (q31_t)0x801fdc86, (q31_t)0x59e6319, (q31_t)0x801f95c3, + (q31_t)0x5981c26, (q31_t)0x801f4f4f, (q31_t)0x591d52f, (q31_t)0x801f092a, (q31_t)0x58b8e34, (q31_t)0x801ec354, (q31_t)0x5854736, (q31_t)0x801e7dcd, + (q31_t)0x57f0035, (q31_t)0x801e3895, (q31_t)0x578b930, (q31_t)0x801df3ab, (q31_t)0x5727228, (q31_t)0x801daf11, (q31_t)0x56c2b1c, (q31_t)0x801d6ac5, + (q31_t)0x565e40d, (q31_t)0x801d26c8, (q31_t)0x55f9cfb, (q31_t)0x801ce31a, (q31_t)0x55955e6, (q31_t)0x801c9fbb, (q31_t)0x5530ecd, (q31_t)0x801c5cab, + (q31_t)0x54cc7b1, (q31_t)0x801c19ea, (q31_t)0x5468092, (q31_t)0x801bd777, (q31_t)0x540396f, (q31_t)0x801b9554, (q31_t)0x539f249, (q31_t)0x801b537f, + (q31_t)0x533ab20, (q31_t)0x801b11fa, (q31_t)0x52d63f4, (q31_t)0x801ad0c3, (q31_t)0x5271cc4, (q31_t)0x801a8fdb, (q31_t)0x520d592, (q31_t)0x801a4f42, + (q31_t)0x51a8e5c, (q31_t)0x801a0ef8, (q31_t)0x5144723, (q31_t)0x8019cefd, (q31_t)0x50dffe7, (q31_t)0x80198f50, (q31_t)0x507b8a8, (q31_t)0x80194ff3, + (q31_t)0x5017165, (q31_t)0x801910e4, (q31_t)0x4fb2a20, (q31_t)0x8018d225, (q31_t)0x4f4e2d8, (q31_t)0x801893b4, (q31_t)0x4ee9b8c, (q31_t)0x80185592, + (q31_t)0x4e8543e, (q31_t)0x801817bf, (q31_t)0x4e20cec, (q31_t)0x8017da3b, (q31_t)0x4dbc597, (q31_t)0x80179d06, (q31_t)0x4d57e40, (q31_t)0x80176020, + (q31_t)0x4cf36e5, (q31_t)0x80172388, (q31_t)0x4c8ef88, (q31_t)0x8016e740, (q31_t)0x4c2a827, (q31_t)0x8016ab46, (q31_t)0x4bc60c4, (q31_t)0x80166f9c, + (q31_t)0x4b6195d, (q31_t)0x80163440, (q31_t)0x4afd1f4, (q31_t)0x8015f933, (q31_t)0x4a98a88, (q31_t)0x8015be75, (q31_t)0x4a34319, (q31_t)0x80158406, + (q31_t)0x49cfba7, (q31_t)0x801549e6, (q31_t)0x496b432, (q31_t)0x80151015, (q31_t)0x4906cbb, (q31_t)0x8014d693, (q31_t)0x48a2540, (q31_t)0x80149d5f, + (q31_t)0x483ddc3, (q31_t)0x8014647b, (q31_t)0x47d9643, (q31_t)0x80142be5, (q31_t)0x4774ec1, (q31_t)0x8013f39e, (q31_t)0x471073b, (q31_t)0x8013bba7, + (q31_t)0x46abfb3, (q31_t)0x801383fe, (q31_t)0x4647828, (q31_t)0x80134ca4, (q31_t)0x45e309a, (q31_t)0x80131599, (q31_t)0x457e90a, (q31_t)0x8012dedd, + (q31_t)0x451a177, (q31_t)0x8012a86f, (q31_t)0x44b59e1, (q31_t)0x80127251, (q31_t)0x4451249, (q31_t)0x80123c82, (q31_t)0x43ecaae, (q31_t)0x80120701, + (q31_t)0x4388310, (q31_t)0x8011d1d0, (q31_t)0x4323b70, (q31_t)0x80119ced, (q31_t)0x42bf3cd, (q31_t)0x80116859, (q31_t)0x425ac28, (q31_t)0x80113414, + (q31_t)0x41f6480, (q31_t)0x8011001f, (q31_t)0x4191cd5, (q31_t)0x8010cc78, (q31_t)0x412d528, (q31_t)0x8010991f, (q31_t)0x40c8d79, (q31_t)0x80106616, + (q31_t)0x40645c7, (q31_t)0x8010335c, (q31_t)0x3fffe12, (q31_t)0x801000f1, (q31_t)0x3f9b65b, (q31_t)0x800fced4, (q31_t)0x3f36ea2, (q31_t)0x800f9d07, + (q31_t)0x3ed26e6, (q31_t)0x800f6b88, (q31_t)0x3e6df28, (q31_t)0x800f3a59, (q31_t)0x3e09767, (q31_t)0x800f0978, (q31_t)0x3da4fa4, (q31_t)0x800ed8e6, + (q31_t)0x3d407df, (q31_t)0x800ea8a3, (q31_t)0x3cdc017, (q31_t)0x800e78af, (q31_t)0x3c7784d, (q31_t)0x800e490a, (q31_t)0x3c13080, (q31_t)0x800e19b4, + (q31_t)0x3bae8b2, (q31_t)0x800deaad, (q31_t)0x3b4a0e0, (q31_t)0x800dbbf5, (q31_t)0x3ae590d, (q31_t)0x800d8d8b, (q31_t)0x3a81137, (q31_t)0x800d5f71, + (q31_t)0x3a1c960, (q31_t)0x800d31a5, (q31_t)0x39b8185, (q31_t)0x800d0429, (q31_t)0x39539a9, (q31_t)0x800cd6fb, (q31_t)0x38ef1ca, (q31_t)0x800caa1c, + (q31_t)0x388a9ea, (q31_t)0x800c7d8c, (q31_t)0x3826207, (q31_t)0x800c514c, (q31_t)0x37c1a22, (q31_t)0x800c255a, (q31_t)0x375d23a, (q31_t)0x800bf9b7, + (q31_t)0x36f8a51, (q31_t)0x800bce63, (q31_t)0x3694265, (q31_t)0x800ba35d, (q31_t)0x362fa78, (q31_t)0x800b78a7, (q31_t)0x35cb288, (q31_t)0x800b4e40, + (q31_t)0x3566a96, (q31_t)0x800b2427, (q31_t)0x35022a2, (q31_t)0x800afa5e, (q31_t)0x349daac, (q31_t)0x800ad0e3, (q31_t)0x34392b4, (q31_t)0x800aa7b8, + (q31_t)0x33d4abb, (q31_t)0x800a7edb, (q31_t)0x33702bf, (q31_t)0x800a564e, (q31_t)0x330bac1, (q31_t)0x800a2e0f, (q31_t)0x32a72c1, (q31_t)0x800a061f, + (q31_t)0x3242abf, (q31_t)0x8009de7e, (q31_t)0x31de2bb, (q31_t)0x8009b72c, (q31_t)0x3179ab5, (q31_t)0x80099029, (q31_t)0x31152ae, (q31_t)0x80096975, + (q31_t)0x30b0aa4, (q31_t)0x80094310, (q31_t)0x304c299, (q31_t)0x80091cf9, (q31_t)0x2fe7a8c, (q31_t)0x8008f732, (q31_t)0x2f8327d, (q31_t)0x8008d1ba, + (q31_t)0x2f1ea6c, (q31_t)0x8008ac90, (q31_t)0x2eba259, (q31_t)0x800887b6, (q31_t)0x2e55a44, (q31_t)0x8008632a, (q31_t)0x2df122e, (q31_t)0x80083eed, + (q31_t)0x2d8ca16, (q31_t)0x80081b00, (q31_t)0x2d281fc, (q31_t)0x8007f761, (q31_t)0x2cc39e1, (q31_t)0x8007d411, (q31_t)0x2c5f1c3, (q31_t)0x8007b110, + (q31_t)0x2bfa9a4, (q31_t)0x80078e5e, (q31_t)0x2b96184, (q31_t)0x80076bfb, (q31_t)0x2b31961, (q31_t)0x800749e7, (q31_t)0x2acd13d, (q31_t)0x80072822, + (q31_t)0x2a68917, (q31_t)0x800706ac, (q31_t)0x2a040f0, (q31_t)0x8006e585, (q31_t)0x299f8c7, (q31_t)0x8006c4ac, (q31_t)0x293b09c, (q31_t)0x8006a423, + (q31_t)0x28d6870, (q31_t)0x800683e8, (q31_t)0x2872043, (q31_t)0x800663fd, (q31_t)0x280d813, (q31_t)0x80064460, (q31_t)0x27a8fe2, (q31_t)0x80062513, + (q31_t)0x27447b0, (q31_t)0x80060614, (q31_t)0x26dff7c, (q31_t)0x8005e764, (q31_t)0x267b747, (q31_t)0x8005c904, (q31_t)0x2616f10, (q31_t)0x8005aaf2, + (q31_t)0x25b26d7, (q31_t)0x80058d2f, (q31_t)0x254de9e, (q31_t)0x80056fbb, (q31_t)0x24e9662, (q31_t)0x80055296, (q31_t)0x2484e26, (q31_t)0x800535c0, + (q31_t)0x24205e8, (q31_t)0x80051939, (q31_t)0x23bbda8, (q31_t)0x8004fd00, (q31_t)0x2357567, (q31_t)0x8004e117, (q31_t)0x22f2d25, (q31_t)0x8004c57d, + (q31_t)0x228e4e2, (q31_t)0x8004aa32, (q31_t)0x2229c9d, (q31_t)0x80048f35, (q31_t)0x21c5457, (q31_t)0x80047488, (q31_t)0x2160c0f, (q31_t)0x80045a29, + (q31_t)0x20fc3c6, (q31_t)0x8004401a, (q31_t)0x2097b7c, (q31_t)0x80042659, (q31_t)0x2033331, (q31_t)0x80040ce7, (q31_t)0x1fceae4, (q31_t)0x8003f3c5, + (q31_t)0x1f6a297, (q31_t)0x8003daf1, (q31_t)0x1f05a48, (q31_t)0x8003c26c, (q31_t)0x1ea11f7, (q31_t)0x8003aa36, (q31_t)0x1e3c9a6, (q31_t)0x8003924f, + (q31_t)0x1dd8154, (q31_t)0x80037ab7, (q31_t)0x1d73900, (q31_t)0x8003636e, (q31_t)0x1d0f0ab, (q31_t)0x80034c74, (q31_t)0x1caa855, (q31_t)0x800335c9, + (q31_t)0x1c45ffe, (q31_t)0x80031f6d, (q31_t)0x1be17a6, (q31_t)0x80030960, (q31_t)0x1b7cf4d, (q31_t)0x8002f3a1, (q31_t)0x1b186f3, (q31_t)0x8002de32, + (q31_t)0x1ab3e97, (q31_t)0x8002c912, (q31_t)0x1a4f63b, (q31_t)0x8002b440, (q31_t)0x19eaddd, (q31_t)0x80029fbe, (q31_t)0x198657f, (q31_t)0x80028b8a, + (q31_t)0x1921d20, (q31_t)0x800277a6, (q31_t)0x18bd4bf, (q31_t)0x80026410, (q31_t)0x1858c5e, (q31_t)0x800250c9, (q31_t)0x17f43fc, (q31_t)0x80023dd2, + (q31_t)0x178fb99, (q31_t)0x80022b29, (q31_t)0x172b335, (q31_t)0x800218cf, (q31_t)0x16c6ad0, (q31_t)0x800206c4, (q31_t)0x166226a, (q31_t)0x8001f508, + (q31_t)0x15fda03, (q31_t)0x8001e39b, (q31_t)0x159919c, (q31_t)0x8001d27d, (q31_t)0x1534934, (q31_t)0x8001c1ae, (q31_t)0x14d00ca, (q31_t)0x8001b12e, + (q31_t)0x146b860, (q31_t)0x8001a0fd, (q31_t)0x1406ff6, (q31_t)0x8001911b, (q31_t)0x13a278a, (q31_t)0x80018187, (q31_t)0x133df1e, (q31_t)0x80017243, + (q31_t)0x12d96b1, (q31_t)0x8001634e, (q31_t)0x1274e43, (q31_t)0x800154a7, (q31_t)0x12105d5, (q31_t)0x80014650, (q31_t)0x11abd66, (q31_t)0x80013847, + (q31_t)0x11474f6, (q31_t)0x80012a8e, (q31_t)0x10e2c85, (q31_t)0x80011d23, (q31_t)0x107e414, (q31_t)0x80011008, (q31_t)0x1019ba2, (q31_t)0x8001033b, + (q31_t)0x0fb5330, (q31_t)0x8000f6bd, (q31_t)0x0f50abd, (q31_t)0x8000ea8e, (q31_t)0x0eec249, (q31_t)0x8000deaf, (q31_t)0x0e879d5, (q31_t)0x8000d31e, + (q31_t)0x0e23160, (q31_t)0x8000c7dc, (q31_t)0x0dbe8eb, (q31_t)0x8000bce9, (q31_t)0x0d5a075, (q31_t)0x8000b245, (q31_t)0x0cf57ff, (q31_t)0x8000a7f0, + (q31_t)0x0c90f88, (q31_t)0x80009dea, (q31_t)0x0c2c711, (q31_t)0x80009433, (q31_t)0x0bc7e99, (q31_t)0x80008aca, (q31_t)0x0b63621, (q31_t)0x800081b1, + (q31_t)0x0afeda8, (q31_t)0x800078e7, (q31_t)0x0a9a52f, (q31_t)0x8000706c, (q31_t)0x0a35cb5, (q31_t)0x8000683f, (q31_t)0x09d143b, (q31_t)0x80006062, + (q31_t)0x096cbc1, (q31_t)0x800058d4, (q31_t)0x0908346, (q31_t)0x80005194, (q31_t)0x08a3acb, (q31_t)0x80004aa4, (q31_t)0x083f250, (q31_t)0x80004402, + (q31_t)0x07da9d4, (q31_t)0x80003daf, (q31_t)0x0776159, (q31_t)0x800037ac, (q31_t)0x07118dc, (q31_t)0x800031f7, (q31_t)0x06ad060, (q31_t)0x80002c91, + (q31_t)0x06487e3, (q31_t)0x8000277a, (q31_t)0x05e3f66, (q31_t)0x800022b3, (q31_t)0x057f6e9, (q31_t)0x80001e3a, (q31_t)0x051ae6b, (q31_t)0x80001a10, + (q31_t)0x04b65ee, (q31_t)0x80001635, (q31_t)0x0451d70, (q31_t)0x800012a9, (q31_t)0x03ed4f2, (q31_t)0x80000f6c, (q31_t)0x0388c74, (q31_t)0x80000c7e, + (q31_t)0x03243f5, (q31_t)0x800009df, (q31_t)0x02bfb77, (q31_t)0x8000078e, (q31_t)0x025b2f8, (q31_t)0x8000058d, (q31_t)0x01f6a7a, (q31_t)0x800003db, + (q31_t)0x01921fb, (q31_t)0x80000278, (q31_t)0x012d97c, (q31_t)0x80000163, (q31_t)0x00c90fe, (q31_t)0x8000009e, (q31_t)0x006487f, (q31_t)0x80000027 +}; + +/** + @par + cosFactor tables are generated using the formula :
cos_factors[n] = 2 * cos((2n+1)*pi/(4*N))
+ @par + C command to generate the table +
+  for (i = 0; i< N; i++)
+  {
+    cos_factors[i] = 2 * cos((2*i+1)*c/2);
+  } 
+ @par + where N is the number of factors to generate and c is pi/(2*N) + @par + Then converted to q31 format by multiplying with 2^31 and saturated if required. +*/ + + +static const q31_t cos_factorsQ31_128[128] = { + (q31_t)0x7fff6216, (q31_t)0x7ffa72d1, (q31_t)0x7ff09478, (q31_t)0x7fe1c76b, (q31_t)0x7fce0c3e, (q31_t)0x7fb563b3, + (q31_t)0x7f97cebd, (q31_t)0x7f754e80, + (q31_t)0x7f4de451, (q31_t)0x7f2191b4, (q31_t)0x7ef05860, (q31_t)0x7eba3a39, (q31_t)0x7e7f3957, (q31_t)0x7e3f57ff, + (q31_t)0x7dfa98a8, (q31_t)0x7db0fdf8, + (q31_t)0x7d628ac6, (q31_t)0x7d0f4218, (q31_t)0x7cb72724, (q31_t)0x7c5a3d50, (q31_t)0x7bf88830, (q31_t)0x7b920b89, + (q31_t)0x7b26cb4f, (q31_t)0x7ab6cba4, + (q31_t)0x7a4210d8, (q31_t)0x79c89f6e, (q31_t)0x794a7c12, (q31_t)0x78c7aba2, (q31_t)0x78403329, (q31_t)0x77b417df, + (q31_t)0x77235f2d, (q31_t)0x768e0ea6, + (q31_t)0x75f42c0b, (q31_t)0x7555bd4c, (q31_t)0x74b2c884, (q31_t)0x740b53fb, (q31_t)0x735f6626, (q31_t)0x72af05a7, + (q31_t)0x71fa3949, (q31_t)0x71410805, + (q31_t)0x708378ff, (q31_t)0x6fc19385, (q31_t)0x6efb5f12, (q31_t)0x6e30e34a, (q31_t)0x6d6227fa, (q31_t)0x6c8f351c, + (q31_t)0x6bb812d1, (q31_t)0x6adcc964, + (q31_t)0x69fd614a, (q31_t)0x6919e320, (q31_t)0x683257ab, (q31_t)0x6746c7d8, (q31_t)0x66573cbb, (q31_t)0x6563bf92, + (q31_t)0x646c59bf, (q31_t)0x637114cc, + (q31_t)0x6271fa69, (q31_t)0x616f146c, (q31_t)0x60686ccf, (q31_t)0x5f5e0db3, (q31_t)0x5e50015d, (q31_t)0x5d3e5237, + (q31_t)0x5c290acc, (q31_t)0x5b1035cf, + (q31_t)0x59f3de12, (q31_t)0x58d40e8c, (q31_t)0x57b0d256, (q31_t)0x568a34a9, (q31_t)0x556040e2, (q31_t)0x5433027d, + (q31_t)0x53028518, (q31_t)0x51ced46e, + (q31_t)0x5097fc5e, (q31_t)0x4f5e08e3, (q31_t)0x4e210617, (q31_t)0x4ce10034, (q31_t)0x4b9e0390, (q31_t)0x4a581c9e, + (q31_t)0x490f57ee, (q31_t)0x47c3c22f, + (q31_t)0x46756828, (q31_t)0x452456bd, (q31_t)0x43d09aed, (q31_t)0x427a41d0, (q31_t)0x4121589b, (q31_t)0x3fc5ec98, + (q31_t)0x3e680b2c, (q31_t)0x3d07c1d6, + (q31_t)0x3ba51e29, (q31_t)0x3a402dd2, (q31_t)0x38d8fe93, (q31_t)0x376f9e46, (q31_t)0x36041ad9, (q31_t)0x34968250, + (q31_t)0x3326e2c3, (q31_t)0x31b54a5e, + (q31_t)0x3041c761, (q31_t)0x2ecc681e, (q31_t)0x2d553afc, (q31_t)0x2bdc4e6f, (q31_t)0x2a61b101, (q31_t)0x28e5714b, + (q31_t)0x27679df4, (q31_t)0x25e845b6, + (q31_t)0x24677758, (q31_t)0x22e541af, (q31_t)0x2161b3a0, (q31_t)0x1fdcdc1b, (q31_t)0x1e56ca1e, (q31_t)0x1ccf8cb3, + (q31_t)0x1b4732ef, (q31_t)0x19bdcbf3, + (q31_t)0x183366e9, (q31_t)0x16a81305, (q31_t)0x151bdf86, (q31_t)0x138edbb1, (q31_t)0x120116d5, (q31_t)0x1072a048, + (q31_t)0xee38766, (q31_t)0xd53db92, + (q31_t)0xbc3ac35, (q31_t)0xa3308bd, (q31_t)0x8a2009a, (q31_t)0x710a345, (q31_t)0x57f0035, (q31_t)0x3ed26e6, (q31_t)0x25b26d7, + (q31_t)0xc90f88 +}; + +static const q31_t cos_factorsQ31_512[512] = { + (q31_t)0x7ffff621, (q31_t)0x7fffa72c, (q31_t)0x7fff0943, (q31_t)0x7ffe1c65, (q31_t)0x7ffce093, (q31_t)0x7ffb55ce, + (q31_t)0x7ff97c18, (q31_t)0x7ff75370, + (q31_t)0x7ff4dbd9, (q31_t)0x7ff21553, (q31_t)0x7feeffe1, (q31_t)0x7feb9b85, (q31_t)0x7fe7e841, (q31_t)0x7fe3e616, + (q31_t)0x7fdf9508, (q31_t)0x7fdaf519, + (q31_t)0x7fd6064c, (q31_t)0x7fd0c8a3, (q31_t)0x7fcb3c23, (q31_t)0x7fc560cf, (q31_t)0x7fbf36aa, (q31_t)0x7fb8bdb8, + (q31_t)0x7fb1f5fc, (q31_t)0x7faadf7c, + (q31_t)0x7fa37a3c, (q31_t)0x7f9bc640, (q31_t)0x7f93c38c, (q31_t)0x7f8b7227, (q31_t)0x7f82d214, (q31_t)0x7f79e35a, + (q31_t)0x7f70a5fe, (q31_t)0x7f671a05, + (q31_t)0x7f5d3f75, (q31_t)0x7f531655, (q31_t)0x7f489eaa, (q31_t)0x7f3dd87c, (q31_t)0x7f32c3d1, (q31_t)0x7f2760af, + (q31_t)0x7f1baf1e, (q31_t)0x7f0faf25, + (q31_t)0x7f0360cb, (q31_t)0x7ef6c418, (q31_t)0x7ee9d914, (q31_t)0x7edc9fc6, (q31_t)0x7ecf1837, (q31_t)0x7ec14270, + (q31_t)0x7eb31e78, (q31_t)0x7ea4ac58, + (q31_t)0x7e95ec1a, (q31_t)0x7e86ddc6, (q31_t)0x7e778166, (q31_t)0x7e67d703, (q31_t)0x7e57dea7, (q31_t)0x7e47985b, + (q31_t)0x7e37042a, (q31_t)0x7e26221f, + (q31_t)0x7e14f242, (q31_t)0x7e0374a0, (q31_t)0x7df1a942, (q31_t)0x7ddf9034, (q31_t)0x7dcd2981, (q31_t)0x7dba7534, + (q31_t)0x7da77359, (q31_t)0x7d9423fc, + (q31_t)0x7d808728, (q31_t)0x7d6c9ce9, (q31_t)0x7d58654d, (q31_t)0x7d43e05e, (q31_t)0x7d2f0e2b, (q31_t)0x7d19eebf, + (q31_t)0x7d048228, (q31_t)0x7ceec873, + (q31_t)0x7cd8c1ae, (q31_t)0x7cc26de5, (q31_t)0x7cabcd28, (q31_t)0x7c94df83, (q31_t)0x7c7da505, (q31_t)0x7c661dbc, + (q31_t)0x7c4e49b7, (q31_t)0x7c362904, + (q31_t)0x7c1dbbb3, (q31_t)0x7c0501d2, (q31_t)0x7bebfb70, (q31_t)0x7bd2a89e, (q31_t)0x7bb9096b, (q31_t)0x7b9f1de6, + (q31_t)0x7b84e61f, (q31_t)0x7b6a6227, + (q31_t)0x7b4f920e, (q31_t)0x7b3475e5, (q31_t)0x7b190dbc, (q31_t)0x7afd59a4, (q31_t)0x7ae159ae, (q31_t)0x7ac50dec, + (q31_t)0x7aa8766f, (q31_t)0x7a8b9348, + (q31_t)0x7a6e648a, (q31_t)0x7a50ea47, (q31_t)0x7a332490, (q31_t)0x7a151378, (q31_t)0x79f6b711, (q31_t)0x79d80f6f, + (q31_t)0x79b91ca4, (q31_t)0x7999dec4, + (q31_t)0x797a55e0, (q31_t)0x795a820e, (q31_t)0x793a6361, (q31_t)0x7919f9ec, (q31_t)0x78f945c3, (q31_t)0x78d846fb, + (q31_t)0x78b6fda8, (q31_t)0x789569df, + (q31_t)0x78738bb3, (q31_t)0x7851633b, (q31_t)0x782ef08b, (q31_t)0x780c33b8, (q31_t)0x77e92cd9, (q31_t)0x77c5dc01, + (q31_t)0x77a24148, (q31_t)0x777e5cc3, + (q31_t)0x775a2e89, (q31_t)0x7735b6af, (q31_t)0x7710f54c, (q31_t)0x76ebea77, (q31_t)0x76c69647, (q31_t)0x76a0f8d2, + (q31_t)0x767b1231, (q31_t)0x7654e279, + (q31_t)0x762e69c4, (q31_t)0x7607a828, (q31_t)0x75e09dbd, (q31_t)0x75b94a9c, (q31_t)0x7591aedd, (q31_t)0x7569ca99, + (q31_t)0x75419de7, (q31_t)0x751928e0, + (q31_t)0x74f06b9e, (q31_t)0x74c7663a, (q31_t)0x749e18cd, (q31_t)0x74748371, (q31_t)0x744aa63f, (q31_t)0x74208150, + (q31_t)0x73f614c0, (q31_t)0x73cb60a8, + (q31_t)0x73a06522, (q31_t)0x73752249, (q31_t)0x73499838, (q31_t)0x731dc70a, (q31_t)0x72f1aed9, (q31_t)0x72c54fc1, + (q31_t)0x7298a9dd, (q31_t)0x726bbd48, + (q31_t)0x723e8a20, (q31_t)0x7211107e, (q31_t)0x71e35080, (q31_t)0x71b54a41, (q31_t)0x7186fdde, (q31_t)0x71586b74, + (q31_t)0x7129931f, (q31_t)0x70fa74fc, + (q31_t)0x70cb1128, (q31_t)0x709b67c0, (q31_t)0x706b78e3, (q31_t)0x703b44ad, (q31_t)0x700acb3c, (q31_t)0x6fda0cae, + (q31_t)0x6fa90921, (q31_t)0x6f77c0b3, + (q31_t)0x6f463383, (q31_t)0x6f1461b0, (q31_t)0x6ee24b57, (q31_t)0x6eaff099, (q31_t)0x6e7d5193, (q31_t)0x6e4a6e66, + (q31_t)0x6e174730, (q31_t)0x6de3dc11, + (q31_t)0x6db02d29, (q31_t)0x6d7c3a98, (q31_t)0x6d48047e, (q31_t)0x6d138afb, (q31_t)0x6cdece2f, (q31_t)0x6ca9ce3b, + (q31_t)0x6c748b3f, (q31_t)0x6c3f055d, + (q31_t)0x6c093cb6, (q31_t)0x6bd3316a, (q31_t)0x6b9ce39b, (q31_t)0x6b66536b, (q31_t)0x6b2f80fb, (q31_t)0x6af86c6c, + (q31_t)0x6ac115e2, (q31_t)0x6a897d7d, + (q31_t)0x6a51a361, (q31_t)0x6a1987b0, (q31_t)0x69e12a8c, (q31_t)0x69a88c19, (q31_t)0x696fac78, (q31_t)0x69368bce, + (q31_t)0x68fd2a3d, (q31_t)0x68c387e9, + (q31_t)0x6889a4f6, (q31_t)0x684f8186, (q31_t)0x68151dbe, (q31_t)0x67da79c3, (q31_t)0x679f95b7, (q31_t)0x676471c0, + (q31_t)0x67290e02, (q31_t)0x66ed6aa1, + (q31_t)0x66b187c3, (q31_t)0x6675658c, (q31_t)0x66390422, (q31_t)0x65fc63a9, (q31_t)0x65bf8447, (q31_t)0x65826622, + (q31_t)0x6545095f, (q31_t)0x65076e25, + (q31_t)0x64c99498, (q31_t)0x648b7ce0, (q31_t)0x644d2722, (q31_t)0x640e9386, (q31_t)0x63cfc231, (q31_t)0x6390b34a, + (q31_t)0x635166f9, (q31_t)0x6311dd64, + (q31_t)0x62d216b3, (q31_t)0x6292130c, (q31_t)0x6251d298, (q31_t)0x6211557e, (q31_t)0x61d09be5, (q31_t)0x618fa5f7, + (q31_t)0x614e73da, (q31_t)0x610d05b7, + (q31_t)0x60cb5bb7, (q31_t)0x60897601, (q31_t)0x604754bf, (q31_t)0x6004f819, (q31_t)0x5fc26038, (q31_t)0x5f7f8d46, + (q31_t)0x5f3c7f6b, (q31_t)0x5ef936d1, + (q31_t)0x5eb5b3a2, (q31_t)0x5e71f606, (q31_t)0x5e2dfe29, (q31_t)0x5de9cc33, (q31_t)0x5da5604f, (q31_t)0x5d60baa7, + (q31_t)0x5d1bdb65, (q31_t)0x5cd6c2b5, + (q31_t)0x5c9170bf, (q31_t)0x5c4be5b0, (q31_t)0x5c0621b2, (q31_t)0x5bc024f0, (q31_t)0x5b79ef96, (q31_t)0x5b3381ce, + (q31_t)0x5aecdbc5, (q31_t)0x5aa5fda5, + (q31_t)0x5a5ee79a, (q31_t)0x5a1799d1, (q31_t)0x59d01475, (q31_t)0x598857b2, (q31_t)0x594063b5, (q31_t)0x58f838a9, + (q31_t)0x58afd6bd, (q31_t)0x58673e1b, + (q31_t)0x581e6ef1, (q31_t)0x57d5696d, (q31_t)0x578c2dba, (q31_t)0x5742bc06, (q31_t)0x56f9147e, (q31_t)0x56af3750, + (q31_t)0x566524aa, (q31_t)0x561adcb9, + (q31_t)0x55d05faa, (q31_t)0x5585adad, (q31_t)0x553ac6ee, (q31_t)0x54efab9c, (q31_t)0x54a45be6, (q31_t)0x5458d7f9, + (q31_t)0x540d2005, (q31_t)0x53c13439, + (q31_t)0x537514c2, (q31_t)0x5328c1d0, (q31_t)0x52dc3b92, (q31_t)0x528f8238, (q31_t)0x524295f0, (q31_t)0x51f576ea, + (q31_t)0x51a82555, (q31_t)0x515aa162, + (q31_t)0x510ceb40, (q31_t)0x50bf031f, (q31_t)0x5070e92f, (q31_t)0x50229da1, (q31_t)0x4fd420a4, (q31_t)0x4f857269, + (q31_t)0x4f369320, (q31_t)0x4ee782fb, + (q31_t)0x4e984229, (q31_t)0x4e48d0dd, (q31_t)0x4df92f46, (q31_t)0x4da95d96, (q31_t)0x4d595bfe, (q31_t)0x4d092ab0, + (q31_t)0x4cb8c9dd, (q31_t)0x4c6839b7, + (q31_t)0x4c177a6e, (q31_t)0x4bc68c36, (q31_t)0x4b756f40, (q31_t)0x4b2423be, (q31_t)0x4ad2a9e2, (q31_t)0x4a8101de, + (q31_t)0x4a2f2be6, (q31_t)0x49dd282a, + (q31_t)0x498af6df, (q31_t)0x49389836, (q31_t)0x48e60c62, (q31_t)0x48935397, (q31_t)0x48406e08, (q31_t)0x47ed5be6, + (q31_t)0x479a1d67, (q31_t)0x4746b2bc, + (q31_t)0x46f31c1a, (q31_t)0x469f59b4, (q31_t)0x464b6bbe, (q31_t)0x45f7526b, (q31_t)0x45a30df0, (q31_t)0x454e9e80, + (q31_t)0x44fa0450, (q31_t)0x44a53f93, + (q31_t)0x4450507e, (q31_t)0x43fb3746, (q31_t)0x43a5f41e, (q31_t)0x4350873c, (q31_t)0x42faf0d4, (q31_t)0x42a5311b, + (q31_t)0x424f4845, (q31_t)0x41f93689, + (q31_t)0x41a2fc1a, (q31_t)0x414c992f, (q31_t)0x40f60dfb, (q31_t)0x409f5ab6, (q31_t)0x40487f94, (q31_t)0x3ff17cca, + (q31_t)0x3f9a5290, (q31_t)0x3f430119, + (q31_t)0x3eeb889c, (q31_t)0x3e93e950, (q31_t)0x3e3c2369, (q31_t)0x3de4371f, (q31_t)0x3d8c24a8, (q31_t)0x3d33ec39, + (q31_t)0x3cdb8e09, (q31_t)0x3c830a50, + (q31_t)0x3c2a6142, (q31_t)0x3bd19318, (q31_t)0x3b78a007, (q31_t)0x3b1f8848, (q31_t)0x3ac64c0f, (q31_t)0x3a6ceb96, + (q31_t)0x3a136712, (q31_t)0x39b9bebc, + (q31_t)0x395ff2c9, (q31_t)0x39060373, (q31_t)0x38abf0ef, (q31_t)0x3851bb77, (q31_t)0x37f76341, (q31_t)0x379ce885, + (q31_t)0x37424b7b, (q31_t)0x36e78c5b, + (q31_t)0x368cab5c, (q31_t)0x3631a8b8, (q31_t)0x35d684a6, (q31_t)0x357b3f5d, (q31_t)0x351fd918, (q31_t)0x34c4520d, + (q31_t)0x3468aa76, (q31_t)0x340ce28b, + (q31_t)0x33b0fa84, (q31_t)0x3354f29b, (q31_t)0x32f8cb07, (q31_t)0x329c8402, (q31_t)0x32401dc6, (q31_t)0x31e39889, + (q31_t)0x3186f487, (q31_t)0x312a31f8, + (q31_t)0x30cd5115, (q31_t)0x30705217, (q31_t)0x30133539, (q31_t)0x2fb5fab2, (q31_t)0x2f58a2be, (q31_t)0x2efb2d95, + (q31_t)0x2e9d9b70, (q31_t)0x2e3fec8b, + (q31_t)0x2de2211e, (q31_t)0x2d843964, (q31_t)0x2d263596, (q31_t)0x2cc815ee, (q31_t)0x2c69daa6, (q31_t)0x2c0b83fa, + (q31_t)0x2bad1221, (q31_t)0x2b4e8558, + (q31_t)0x2aefddd8, (q31_t)0x2a911bdc, (q31_t)0x2a323f9e, (q31_t)0x29d34958, (q31_t)0x29743946, (q31_t)0x29150fa1, + (q31_t)0x28b5cca5, (q31_t)0x2856708d, + (q31_t)0x27f6fb92, (q31_t)0x27976df1, (q31_t)0x2737c7e3, (q31_t)0x26d809a5, (q31_t)0x26783370, (q31_t)0x26184581, + (q31_t)0x25b84012, (q31_t)0x2558235f, + (q31_t)0x24f7efa2, (q31_t)0x2497a517, (q31_t)0x243743fa, (q31_t)0x23d6cc87, (q31_t)0x23763ef7, (q31_t)0x23159b88, + (q31_t)0x22b4e274, (q31_t)0x225413f8, + (q31_t)0x21f3304f, (q31_t)0x219237b5, (q31_t)0x21312a65, (q31_t)0x20d0089c, (q31_t)0x206ed295, (q31_t)0x200d888d, + (q31_t)0x1fac2abf, (q31_t)0x1f4ab968, + (q31_t)0x1ee934c3, (q31_t)0x1e879d0d, (q31_t)0x1e25f282, (q31_t)0x1dc4355e, (q31_t)0x1d6265dd, (q31_t)0x1d00843d, + (q31_t)0x1c9e90b8, (q31_t)0x1c3c8b8c, + (q31_t)0x1bda74f6, (q31_t)0x1b784d30, (q31_t)0x1b161479, (q31_t)0x1ab3cb0d, (q31_t)0x1a517128, (q31_t)0x19ef0707, + (q31_t)0x198c8ce7, (q31_t)0x192a0304, + (q31_t)0x18c7699b, (q31_t)0x1864c0ea, (q31_t)0x1802092c, (q31_t)0x179f429f, (q31_t)0x173c6d80, (q31_t)0x16d98a0c, + (q31_t)0x1676987f, (q31_t)0x16139918, + (q31_t)0x15b08c12, (q31_t)0x154d71aa, (q31_t)0x14ea4a1f, (q31_t)0x148715ae, (q31_t)0x1423d492, (q31_t)0x13c0870a, + (q31_t)0x135d2d53, (q31_t)0x12f9c7aa, + (q31_t)0x1296564d, (q31_t)0x1232d979, (q31_t)0x11cf516a, (q31_t)0x116bbe60, (q31_t)0x11082096, (q31_t)0x10a4784b, + (q31_t)0x1040c5bb, (q31_t)0xfdd0926, + (q31_t)0xf7942c7, (q31_t)0xf1572dc, (q31_t)0xeb199a4, (q31_t)0xe4db75b, (q31_t)0xde9cc40, (q31_t)0xd85d88f, (q31_t)0xd21dc87, + (q31_t)0xcbdd865, + (q31_t)0xc59cc68, (q31_t)0xbf5b8cb, (q31_t)0xb919dcf, (q31_t)0xb2d7baf, (q31_t)0xac952aa, (q31_t)0xa6522fe, (q31_t)0xa00ece8, + (q31_t)0x99cb0a7, + (q31_t)0x9386e78, (q31_t)0x8d42699, (q31_t)0x86fd947, (q31_t)0x80b86c2, (q31_t)0x7a72f45, (q31_t)0x742d311, (q31_t)0x6de7262, + (q31_t)0x67a0d76, + (q31_t)0x615a48b, (q31_t)0x5b137df, (q31_t)0x54cc7b1, (q31_t)0x4e8543e, (q31_t)0x483ddc3, (q31_t)0x41f6480, (q31_t)0x3bae8b2, + (q31_t)0x3566a96, + (q31_t)0x2f1ea6c, (q31_t)0x28d6870, (q31_t)0x228e4e2, (q31_t)0x1c45ffe, (q31_t)0x15fda03, (q31_t)0xfb5330, (q31_t)0x96cbc1, + (q31_t)0x3243f5 +}; + +static const q31_t cos_factorsQ31_2048[2048] = { + (q31_t)0x7fffff62, (q31_t)0x7ffffa73, (q31_t)0x7ffff094, (q31_t)0x7fffe1c6, (q31_t)0x7fffce09, (q31_t)0x7fffb55c, + (q31_t)0x7fff97c1, (q31_t)0x7fff7536, + (q31_t)0x7fff4dbb, (q31_t)0x7fff2151, (q31_t)0x7ffeeff8, (q31_t)0x7ffeb9b0, (q31_t)0x7ffe7e79, (q31_t)0x7ffe3e52, + (q31_t)0x7ffdf93c, (q31_t)0x7ffdaf37, + (q31_t)0x7ffd6042, (q31_t)0x7ffd0c5f, (q31_t)0x7ffcb38c, (q31_t)0x7ffc55ca, (q31_t)0x7ffbf319, (q31_t)0x7ffb8b78, + (q31_t)0x7ffb1ee9, (q31_t)0x7ffaad6a, + (q31_t)0x7ffa36fc, (q31_t)0x7ff9bba0, (q31_t)0x7ff93b54, (q31_t)0x7ff8b619, (q31_t)0x7ff82bef, (q31_t)0x7ff79cd6, + (q31_t)0x7ff708ce, (q31_t)0x7ff66fd7, + (q31_t)0x7ff5d1f1, (q31_t)0x7ff52f1d, (q31_t)0x7ff48759, (q31_t)0x7ff3daa6, (q31_t)0x7ff32905, (q31_t)0x7ff27275, + (q31_t)0x7ff1b6f6, (q31_t)0x7ff0f688, + (q31_t)0x7ff0312c, (q31_t)0x7fef66e1, (q31_t)0x7fee97a7, (q31_t)0x7fedc37e, (q31_t)0x7fecea67, (q31_t)0x7fec0c62, + (q31_t)0x7feb296d, (q31_t)0x7fea418b, + (q31_t)0x7fe954ba, (q31_t)0x7fe862fa, (q31_t)0x7fe76c4c, (q31_t)0x7fe670b0, (q31_t)0x7fe57025, (q31_t)0x7fe46aac, + (q31_t)0x7fe36045, (q31_t)0x7fe250ef, + (q31_t)0x7fe13cac, (q31_t)0x7fe0237a, (q31_t)0x7fdf055a, (q31_t)0x7fdde24d, (q31_t)0x7fdcba51, (q31_t)0x7fdb8d67, + (q31_t)0x7fda5b8f, (q31_t)0x7fd924ca, + (q31_t)0x7fd7e917, (q31_t)0x7fd6a875, (q31_t)0x7fd562e7, (q31_t)0x7fd4186a, (q31_t)0x7fd2c900, (q31_t)0x7fd174a8, + (q31_t)0x7fd01b63, (q31_t)0x7fcebd31, + (q31_t)0x7fcd5a11, (q31_t)0x7fcbf203, (q31_t)0x7fca8508, (q31_t)0x7fc91320, (q31_t)0x7fc79c4b, (q31_t)0x7fc62089, + (q31_t)0x7fc49fda, (q31_t)0x7fc31a3d, + (q31_t)0x7fc18fb4, (q31_t)0x7fc0003e, (q31_t)0x7fbe6bdb, (q31_t)0x7fbcd28b, (q31_t)0x7fbb344e, (q31_t)0x7fb99125, + (q31_t)0x7fb7e90f, (q31_t)0x7fb63c0d, + (q31_t)0x7fb48a1e, (q31_t)0x7fb2d343, (q31_t)0x7fb1177b, (q31_t)0x7faf56c7, (q31_t)0x7fad9127, (q31_t)0x7fabc69b, + (q31_t)0x7fa9f723, (q31_t)0x7fa822bf, + (q31_t)0x7fa6496e, (q31_t)0x7fa46b32, (q31_t)0x7fa2880b, (q31_t)0x7fa09ff7, (q31_t)0x7f9eb2f8, (q31_t)0x7f9cc10d, + (q31_t)0x7f9aca37, (q31_t)0x7f98ce76, + (q31_t)0x7f96cdc9, (q31_t)0x7f94c831, (q31_t)0x7f92bdad, (q31_t)0x7f90ae3f, (q31_t)0x7f8e99e6, (q31_t)0x7f8c80a1, + (q31_t)0x7f8a6272, (q31_t)0x7f883f58, + (q31_t)0x7f861753, (q31_t)0x7f83ea64, (q31_t)0x7f81b88a, (q31_t)0x7f7f81c6, (q31_t)0x7f7d4617, (q31_t)0x7f7b057e, + (q31_t)0x7f78bffb, (q31_t)0x7f76758e, + (q31_t)0x7f742637, (q31_t)0x7f71d1f6, (q31_t)0x7f6f78cb, (q31_t)0x7f6d1ab6, (q31_t)0x7f6ab7b8, (q31_t)0x7f684fd0, + (q31_t)0x7f65e2ff, (q31_t)0x7f637144, + (q31_t)0x7f60faa0, (q31_t)0x7f5e7f13, (q31_t)0x7f5bfe9d, (q31_t)0x7f59793e, (q31_t)0x7f56eef5, (q31_t)0x7f545fc5, + (q31_t)0x7f51cbab, (q31_t)0x7f4f32a9, + (q31_t)0x7f4c94be, (q31_t)0x7f49f1eb, (q31_t)0x7f474a30, (q31_t)0x7f449d8c, (q31_t)0x7f41ec01, (q31_t)0x7f3f358d, + (q31_t)0x7f3c7a31, (q31_t)0x7f39b9ee, + (q31_t)0x7f36f4c3, (q31_t)0x7f342ab1, (q31_t)0x7f315bb7, (q31_t)0x7f2e87d6, (q31_t)0x7f2baf0d, (q31_t)0x7f28d15d, + (q31_t)0x7f25eec7, (q31_t)0x7f230749, + (q31_t)0x7f201ae5, (q31_t)0x7f1d299a, (q31_t)0x7f1a3368, (q31_t)0x7f173850, (q31_t)0x7f143852, (q31_t)0x7f11336d, + (q31_t)0x7f0e29a3, (q31_t)0x7f0b1af2, + (q31_t)0x7f08075c, (q31_t)0x7f04eedf, (q31_t)0x7f01d17d, (q31_t)0x7efeaf36, (q31_t)0x7efb8809, (q31_t)0x7ef85bf7, + (q31_t)0x7ef52b00, (q31_t)0x7ef1f524, + (q31_t)0x7eeeba62, (q31_t)0x7eeb7abc, (q31_t)0x7ee83632, (q31_t)0x7ee4ecc3, (q31_t)0x7ee19e6f, (q31_t)0x7ede4b38, + (q31_t)0x7edaf31c, (q31_t)0x7ed7961c, + (q31_t)0x7ed43438, (q31_t)0x7ed0cd70, (q31_t)0x7ecd61c5, (q31_t)0x7ec9f137, (q31_t)0x7ec67bc5, (q31_t)0x7ec3016f, + (q31_t)0x7ebf8237, (q31_t)0x7ebbfe1c, + (q31_t)0x7eb8751e, (q31_t)0x7eb4e73d, (q31_t)0x7eb1547a, (q31_t)0x7eadbcd4, (q31_t)0x7eaa204c, (q31_t)0x7ea67ee2, + (q31_t)0x7ea2d896, (q31_t)0x7e9f2d68, + (q31_t)0x7e9b7d58, (q31_t)0x7e97c867, (q31_t)0x7e940e94, (q31_t)0x7e904fe0, (q31_t)0x7e8c8c4b, (q31_t)0x7e88c3d5, + (q31_t)0x7e84f67e, (q31_t)0x7e812447, + (q31_t)0x7e7d4d2f, (q31_t)0x7e797136, (q31_t)0x7e75905d, (q31_t)0x7e71aaa4, (q31_t)0x7e6dc00c, (q31_t)0x7e69d093, + (q31_t)0x7e65dc3b, (q31_t)0x7e61e303, + (q31_t)0x7e5de4ec, (q31_t)0x7e59e1f5, (q31_t)0x7e55da20, (q31_t)0x7e51cd6c, (q31_t)0x7e4dbbd9, (q31_t)0x7e49a567, + (q31_t)0x7e458a17, (q31_t)0x7e4169e9, + (q31_t)0x7e3d44dd, (q31_t)0x7e391af3, (q31_t)0x7e34ec2b, (q31_t)0x7e30b885, (q31_t)0x7e2c8002, (q31_t)0x7e2842a2, + (q31_t)0x7e240064, (q31_t)0x7e1fb94a, + (q31_t)0x7e1b6d53, (q31_t)0x7e171c7f, (q31_t)0x7e12c6ce, (q31_t)0x7e0e6c42, (q31_t)0x7e0a0cd9, (q31_t)0x7e05a894, + (q31_t)0x7e013f74, (q31_t)0x7dfcd178, + (q31_t)0x7df85ea0, (q31_t)0x7df3e6ee, (q31_t)0x7def6a60, (q31_t)0x7deae8f7, (q31_t)0x7de662b3, (q31_t)0x7de1d795, + (q31_t)0x7ddd479d, (q31_t)0x7dd8b2ca, + (q31_t)0x7dd4191d, (q31_t)0x7dcf7a96, (q31_t)0x7dcad736, (q31_t)0x7dc62efc, (q31_t)0x7dc181e8, (q31_t)0x7dbccffc, + (q31_t)0x7db81936, (q31_t)0x7db35d98, + (q31_t)0x7dae9d21, (q31_t)0x7da9d7d2, (q31_t)0x7da50dab, (q31_t)0x7da03eab, (q31_t)0x7d9b6ad3, (q31_t)0x7d969224, + (q31_t)0x7d91b49e, (q31_t)0x7d8cd240, + (q31_t)0x7d87eb0a, (q31_t)0x7d82fefe, (q31_t)0x7d7e0e1c, (q31_t)0x7d791862, (q31_t)0x7d741dd2, (q31_t)0x7d6f1e6c, + (q31_t)0x7d6a1a31, (q31_t)0x7d65111f, + (q31_t)0x7d600338, (q31_t)0x7d5af07b, (q31_t)0x7d55d8e9, (q31_t)0x7d50bc82, (q31_t)0x7d4b9b46, (q31_t)0x7d467536, + (q31_t)0x7d414a51, (q31_t)0x7d3c1a98, + (q31_t)0x7d36e60b, (q31_t)0x7d31acaa, (q31_t)0x7d2c6e76, (q31_t)0x7d272b6e, (q31_t)0x7d21e393, (q31_t)0x7d1c96e5, + (q31_t)0x7d174564, (q31_t)0x7d11ef11, + (q31_t)0x7d0c93eb, (q31_t)0x7d0733f3, (q31_t)0x7d01cf29, (q31_t)0x7cfc658d, (q31_t)0x7cf6f720, (q31_t)0x7cf183e1, + (q31_t)0x7cec0bd1, (q31_t)0x7ce68ef0, + (q31_t)0x7ce10d3f, (q31_t)0x7cdb86bd, (q31_t)0x7cd5fb6a, (q31_t)0x7cd06b48, (q31_t)0x7ccad656, (q31_t)0x7cc53c94, + (q31_t)0x7cbf9e03, (q31_t)0x7cb9faa2, + (q31_t)0x7cb45272, (q31_t)0x7caea574, (q31_t)0x7ca8f3a7, (q31_t)0x7ca33d0c, (q31_t)0x7c9d81a3, (q31_t)0x7c97c16b, + (q31_t)0x7c91fc66, (q31_t)0x7c8c3294, + (q31_t)0x7c8663f4, (q31_t)0x7c809088, (q31_t)0x7c7ab84e, (q31_t)0x7c74db48, (q31_t)0x7c6ef976, (q31_t)0x7c6912d7, + (q31_t)0x7c63276d, (q31_t)0x7c5d3737, + (q31_t)0x7c574236, (q31_t)0x7c514869, (q31_t)0x7c4b49d2, (q31_t)0x7c45466f, (q31_t)0x7c3f3e42, (q31_t)0x7c39314b, + (q31_t)0x7c331f8a, (q31_t)0x7c2d08ff, + (q31_t)0x7c26edab, (q31_t)0x7c20cd8d, (q31_t)0x7c1aa8a6, (q31_t)0x7c147ef6, (q31_t)0x7c0e507e, (q31_t)0x7c081d3d, + (q31_t)0x7c01e534, (q31_t)0x7bfba863, + (q31_t)0x7bf566cb, (q31_t)0x7bef206b, (q31_t)0x7be8d544, (q31_t)0x7be28556, (q31_t)0x7bdc30a1, (q31_t)0x7bd5d726, + (q31_t)0x7bcf78e5, (q31_t)0x7bc915dd, + (q31_t)0x7bc2ae10, (q31_t)0x7bbc417e, (q31_t)0x7bb5d026, (q31_t)0x7baf5a09, (q31_t)0x7ba8df28, (q31_t)0x7ba25f82, + (q31_t)0x7b9bdb18, (q31_t)0x7b9551ea, + (q31_t)0x7b8ec3f8, (q31_t)0x7b883143, (q31_t)0x7b8199ca, (q31_t)0x7b7afd8f, (q31_t)0x7b745c91, (q31_t)0x7b6db6d0, + (q31_t)0x7b670c4d, (q31_t)0x7b605d09, + (q31_t)0x7b59a902, (q31_t)0x7b52f03a, (q31_t)0x7b4c32b1, (q31_t)0x7b457068, (q31_t)0x7b3ea95d, (q31_t)0x7b37dd92, + (q31_t)0x7b310d07, (q31_t)0x7b2a37bc, + (q31_t)0x7b235db2, (q31_t)0x7b1c7ee8, (q31_t)0x7b159b5f, (q31_t)0x7b0eb318, (q31_t)0x7b07c612, (q31_t)0x7b00d44d, + (q31_t)0x7af9ddcb, (q31_t)0x7af2e28b, + (q31_t)0x7aebe28d, (q31_t)0x7ae4ddd2, (q31_t)0x7addd45b, (q31_t)0x7ad6c626, (q31_t)0x7acfb336, (q31_t)0x7ac89b89, + (q31_t)0x7ac17f20, (q31_t)0x7aba5dfc, + (q31_t)0x7ab3381d, (q31_t)0x7aac0d82, (q31_t)0x7aa4de2d, (q31_t)0x7a9daa1d, (q31_t)0x7a967153, (q31_t)0x7a8f33d0, + (q31_t)0x7a87f192, (q31_t)0x7a80aa9c, + (q31_t)0x7a795eec, (q31_t)0x7a720e84, (q31_t)0x7a6ab963, (q31_t)0x7a635f8a, (q31_t)0x7a5c00f9, (q31_t)0x7a549db0, + (q31_t)0x7a4d35b0, (q31_t)0x7a45c8f9, + (q31_t)0x7a3e578b, (q31_t)0x7a36e166, (q31_t)0x7a2f668c, (q31_t)0x7a27e6fb, (q31_t)0x7a2062b5, (q31_t)0x7a18d9b9, + (q31_t)0x7a114c09, (q31_t)0x7a09b9a4, + (q31_t)0x7a02228a, (q31_t)0x79fa86bc, (q31_t)0x79f2e63a, (q31_t)0x79eb4105, (q31_t)0x79e3971c, (q31_t)0x79dbe880, + (q31_t)0x79d43532, (q31_t)0x79cc7d31, + (q31_t)0x79c4c07e, (q31_t)0x79bcff19, (q31_t)0x79b53903, (q31_t)0x79ad6e3c, (q31_t)0x79a59ec3, (q31_t)0x799dca9a, + (q31_t)0x7995f1c1, (q31_t)0x798e1438, + (q31_t)0x798631ff, (q31_t)0x797e4b16, (q31_t)0x79765f7f, (q31_t)0x796e6f39, (q31_t)0x79667a44, (q31_t)0x795e80a1, + (q31_t)0x79568250, (q31_t)0x794e7f52, + (q31_t)0x794677a6, (q31_t)0x793e6b4e, (q31_t)0x79365a49, (q31_t)0x792e4497, (q31_t)0x79262a3a, (q31_t)0x791e0b31, + (q31_t)0x7915e77c, (q31_t)0x790dbf1d, + (q31_t)0x79059212, (q31_t)0x78fd605d, (q31_t)0x78f529fe, (q31_t)0x78eceef6, (q31_t)0x78e4af44, (q31_t)0x78dc6ae8, + (q31_t)0x78d421e4, (q31_t)0x78cbd437, + (q31_t)0x78c381e2, (q31_t)0x78bb2ae5, (q31_t)0x78b2cf41, (q31_t)0x78aa6ef5, (q31_t)0x78a20a03, (q31_t)0x7899a06a, + (q31_t)0x7891322a, (q31_t)0x7888bf45, + (q31_t)0x788047ba, (q31_t)0x7877cb89, (q31_t)0x786f4ab4, (q31_t)0x7866c53a, (q31_t)0x785e3b1c, (q31_t)0x7855ac5a, + (q31_t)0x784d18f4, (q31_t)0x784480ea, + (q31_t)0x783be43e, (q31_t)0x783342ef, (q31_t)0x782a9cfe, (q31_t)0x7821f26b, (q31_t)0x78194336, (q31_t)0x78108f60, + (q31_t)0x7807d6e9, (q31_t)0x77ff19d1, + (q31_t)0x77f65819, (q31_t)0x77ed91c0, (q31_t)0x77e4c6c9, (q31_t)0x77dbf732, (q31_t)0x77d322fc, (q31_t)0x77ca4a27, + (q31_t)0x77c16cb4, (q31_t)0x77b88aa3, + (q31_t)0x77afa3f5, (q31_t)0x77a6b8a9, (q31_t)0x779dc8c0, (q31_t)0x7794d43b, (q31_t)0x778bdb19, (q31_t)0x7782dd5c, + (q31_t)0x7779db03, (q31_t)0x7770d40f, + (q31_t)0x7767c880, (q31_t)0x775eb857, (q31_t)0x7755a394, (q31_t)0x774c8a36, (q31_t)0x77436c40, (q31_t)0x773a49b0, + (q31_t)0x77312287, (q31_t)0x7727f6c6, + (q31_t)0x771ec66e, (q31_t)0x7715917d, (q31_t)0x770c57f5, (q31_t)0x770319d6, (q31_t)0x76f9d721, (q31_t)0x76f08fd5, + (q31_t)0x76e743f4, (q31_t)0x76ddf37c, + (q31_t)0x76d49e70, (q31_t)0x76cb44cf, (q31_t)0x76c1e699, (q31_t)0x76b883d0, (q31_t)0x76af1c72, (q31_t)0x76a5b082, + (q31_t)0x769c3ffe, (q31_t)0x7692cae8, + (q31_t)0x7689513f, (q31_t)0x767fd304, (q31_t)0x76765038, (q31_t)0x766cc8db, (q31_t)0x76633ced, (q31_t)0x7659ac6f, + (q31_t)0x76501760, (q31_t)0x76467dc2, + (q31_t)0x763cdf94, (q31_t)0x76333cd8, (q31_t)0x7629958c, (q31_t)0x761fe9b3, (q31_t)0x7616394c, (q31_t)0x760c8457, + (q31_t)0x7602cad5, (q31_t)0x75f90cc7, + (q31_t)0x75ef4a2c, (q31_t)0x75e58305, (q31_t)0x75dbb753, (q31_t)0x75d1e715, (q31_t)0x75c8124d, (q31_t)0x75be38fa, + (q31_t)0x75b45b1d, (q31_t)0x75aa78b6, + (q31_t)0x75a091c6, (q31_t)0x7596a64d, (q31_t)0x758cb64c, (q31_t)0x7582c1c2, (q31_t)0x7578c8b0, (q31_t)0x756ecb18, + (q31_t)0x7564c8f8, (q31_t)0x755ac251, + (q31_t)0x7550b725, (q31_t)0x7546a772, (q31_t)0x753c933a, (q31_t)0x75327a7d, (q31_t)0x75285d3b, (q31_t)0x751e3b75, + (q31_t)0x7514152b, (q31_t)0x7509ea5d, + (q31_t)0x74ffbb0d, (q31_t)0x74f58739, (q31_t)0x74eb4ee3, (q31_t)0x74e1120c, (q31_t)0x74d6d0b2, (q31_t)0x74cc8ad8, + (q31_t)0x74c2407d, (q31_t)0x74b7f1a1, + (q31_t)0x74ad9e46, (q31_t)0x74a3466b, (q31_t)0x7498ea11, (q31_t)0x748e8938, (q31_t)0x748423e0, (q31_t)0x7479ba0b, + (q31_t)0x746f4bb8, (q31_t)0x7464d8e8, + (q31_t)0x745a619b, (q31_t)0x744fe5d2, (q31_t)0x7445658d, (q31_t)0x743ae0cc, (q31_t)0x74305790, (q31_t)0x7425c9da, + (q31_t)0x741b37a9, (q31_t)0x7410a0fe, + (q31_t)0x740605d9, (q31_t)0x73fb663c, (q31_t)0x73f0c226, (q31_t)0x73e61997, (q31_t)0x73db6c91, (q31_t)0x73d0bb13, + (q31_t)0x73c6051f, (q31_t)0x73bb4ab3, + (q31_t)0x73b08bd1, (q31_t)0x73a5c87a, (q31_t)0x739b00ad, (q31_t)0x7390346b, (q31_t)0x738563b5, (q31_t)0x737a8e8a, + (q31_t)0x736fb4ec, (q31_t)0x7364d6da, + (q31_t)0x7359f456, (q31_t)0x734f0d5f, (q31_t)0x734421f6, (q31_t)0x7339321b, (q31_t)0x732e3dcf, (q31_t)0x73234512, + (q31_t)0x731847e5, (q31_t)0x730d4648, + (q31_t)0x7302403c, (q31_t)0x72f735c0, (q31_t)0x72ec26d6, (q31_t)0x72e1137d, (q31_t)0x72d5fbb7, (q31_t)0x72cadf83, + (q31_t)0x72bfbee3, (q31_t)0x72b499d6, + (q31_t)0x72a9705c, (q31_t)0x729e4277, (q31_t)0x72931027, (q31_t)0x7287d96c, (q31_t)0x727c9e47, (q31_t)0x72715eb8, + (q31_t)0x72661abf, (q31_t)0x725ad25d, + (q31_t)0x724f8593, (q31_t)0x72443460, (q31_t)0x7238dec5, (q31_t)0x722d84c4, (q31_t)0x7222265b, (q31_t)0x7216c38c, + (q31_t)0x720b5c57, (q31_t)0x71fff0bc, + (q31_t)0x71f480bc, (q31_t)0x71e90c57, (q31_t)0x71dd938f, (q31_t)0x71d21662, (q31_t)0x71c694d2, (q31_t)0x71bb0edf, + (q31_t)0x71af848a, (q31_t)0x71a3f5d2, + (q31_t)0x719862b9, (q31_t)0x718ccb3f, (q31_t)0x71812f65, (q31_t)0x71758f29, (q31_t)0x7169ea8f, (q31_t)0x715e4194, + (q31_t)0x7152943b, (q31_t)0x7146e284, + (q31_t)0x713b2c6e, (q31_t)0x712f71fb, (q31_t)0x7123b32b, (q31_t)0x7117effe, (q31_t)0x710c2875, (q31_t)0x71005c90, + (q31_t)0x70f48c50, (q31_t)0x70e8b7b5, + (q31_t)0x70dcdec0, (q31_t)0x70d10171, (q31_t)0x70c51fc8, (q31_t)0x70b939c7, (q31_t)0x70ad4f6d, (q31_t)0x70a160ba, + (q31_t)0x70956db1, (q31_t)0x70897650, + (q31_t)0x707d7a98, (q31_t)0x70717a8a, (q31_t)0x70657626, (q31_t)0x70596d6d, (q31_t)0x704d6060, (q31_t)0x70414efd, + (q31_t)0x70353947, (q31_t)0x70291f3e, + (q31_t)0x701d00e1, (q31_t)0x7010de32, (q31_t)0x7004b731, (q31_t)0x6ff88bde, (q31_t)0x6fec5c3b, (q31_t)0x6fe02846, + (q31_t)0x6fd3f001, (q31_t)0x6fc7b36d, + (q31_t)0x6fbb728a, (q31_t)0x6faf2d57, (q31_t)0x6fa2e3d7, (q31_t)0x6f969608, (q31_t)0x6f8a43ed, (q31_t)0x6f7ded84, + (q31_t)0x6f7192cf, (q31_t)0x6f6533ce, + (q31_t)0x6f58d082, (q31_t)0x6f4c68eb, (q31_t)0x6f3ffd09, (q31_t)0x6f338cde, (q31_t)0x6f271868, (q31_t)0x6f1a9faa, + (q31_t)0x6f0e22a3, (q31_t)0x6f01a155, + (q31_t)0x6ef51bbe, (q31_t)0x6ee891e1, (q31_t)0x6edc03bc, (q31_t)0x6ecf7152, (q31_t)0x6ec2daa2, (q31_t)0x6eb63fad, + (q31_t)0x6ea9a073, (q31_t)0x6e9cfcf5, + (q31_t)0x6e905534, (q31_t)0x6e83a92f, (q31_t)0x6e76f8e7, (q31_t)0x6e6a445d, (q31_t)0x6e5d8b91, (q31_t)0x6e50ce84, + (q31_t)0x6e440d37, (q31_t)0x6e3747a9, + (q31_t)0x6e2a7ddb, (q31_t)0x6e1dafce, (q31_t)0x6e10dd82, (q31_t)0x6e0406f8, (q31_t)0x6df72c30, (q31_t)0x6dea4d2b, + (q31_t)0x6ddd69e9, (q31_t)0x6dd0826a, + (q31_t)0x6dc396b0, (q31_t)0x6db6a6ba, (q31_t)0x6da9b28a, (q31_t)0x6d9cba1f, (q31_t)0x6d8fbd7a, (q31_t)0x6d82bc9d, + (q31_t)0x6d75b786, (q31_t)0x6d68ae37, + (q31_t)0x6d5ba0b0, (q31_t)0x6d4e8ef2, (q31_t)0x6d4178fd, (q31_t)0x6d345ed1, (q31_t)0x6d274070, (q31_t)0x6d1a1dda, + (q31_t)0x6d0cf70f, (q31_t)0x6cffcc0f, + (q31_t)0x6cf29cdc, (q31_t)0x6ce56975, (q31_t)0x6cd831dc, (q31_t)0x6ccaf610, (q31_t)0x6cbdb613, (q31_t)0x6cb071e4, + (q31_t)0x6ca32985, (q31_t)0x6c95dcf6, + (q31_t)0x6c888c36, (q31_t)0x6c7b3748, (q31_t)0x6c6dde2b, (q31_t)0x6c6080e0, (q31_t)0x6c531f67, (q31_t)0x6c45b9c1, + (q31_t)0x6c384fef, (q31_t)0x6c2ae1f0, + (q31_t)0x6c1d6fc6, (q31_t)0x6c0ff971, (q31_t)0x6c027ef1, (q31_t)0x6bf50047, (q31_t)0x6be77d74, (q31_t)0x6bd9f677, + (q31_t)0x6bcc6b53, (q31_t)0x6bbedc06, + (q31_t)0x6bb14892, (q31_t)0x6ba3b0f7, (q31_t)0x6b961536, (q31_t)0x6b88754f, (q31_t)0x6b7ad142, (q31_t)0x6b6d2911, + (q31_t)0x6b5f7cbc, (q31_t)0x6b51cc42, + (q31_t)0x6b4417a6, (q31_t)0x6b365ee7, (q31_t)0x6b28a206, (q31_t)0x6b1ae103, (q31_t)0x6b0d1bdf, (q31_t)0x6aff529a, + (q31_t)0x6af18536, (q31_t)0x6ae3b3b2, + (q31_t)0x6ad5de0f, (q31_t)0x6ac8044e, (q31_t)0x6aba266e, (q31_t)0x6aac4472, (q31_t)0x6a9e5e58, (q31_t)0x6a907423, + (q31_t)0x6a8285d1, (q31_t)0x6a749365, + (q31_t)0x6a669cdd, (q31_t)0x6a58a23c, (q31_t)0x6a4aa381, (q31_t)0x6a3ca0ad, (q31_t)0x6a2e99c0, (q31_t)0x6a208ebb, + (q31_t)0x6a127f9f, (q31_t)0x6a046c6c, + (q31_t)0x69f65523, (q31_t)0x69e839c4, (q31_t)0x69da1a50, (q31_t)0x69cbf6c7, (q31_t)0x69bdcf29, (q31_t)0x69afa378, + (q31_t)0x69a173b5, (q31_t)0x69933fde, + (q31_t)0x698507f6, (q31_t)0x6976cbfc, (q31_t)0x69688bf1, (q31_t)0x695a47d6, (q31_t)0x694bffab, (q31_t)0x693db371, + (q31_t)0x692f6328, (q31_t)0x69210ed1, + (q31_t)0x6912b66c, (q31_t)0x690459fb, (q31_t)0x68f5f97d, (q31_t)0x68e794f3, (q31_t)0x68d92c5d, (q31_t)0x68cabfbd, + (q31_t)0x68bc4f13, (q31_t)0x68adda5f, + (q31_t)0x689f61a1, (q31_t)0x6890e4dc, (q31_t)0x6882640e, (q31_t)0x6873df38, (q31_t)0x6865565c, (q31_t)0x6856c979, + (q31_t)0x68483891, (q31_t)0x6839a3a4, + (q31_t)0x682b0ab1, (q31_t)0x681c6dbb, (q31_t)0x680dccc1, (q31_t)0x67ff27c4, (q31_t)0x67f07ec5, (q31_t)0x67e1d1c4, + (q31_t)0x67d320c1, (q31_t)0x67c46bbe, + (q31_t)0x67b5b2bb, (q31_t)0x67a6f5b8, (q31_t)0x679834b6, (q31_t)0x67896fb6, (q31_t)0x677aa6b8, (q31_t)0x676bd9bd, + (q31_t)0x675d08c4, (q31_t)0x674e33d0, + (q31_t)0x673f5ae0, (q31_t)0x67307df5, (q31_t)0x67219d10, (q31_t)0x6712b831, (q31_t)0x6703cf58, (q31_t)0x66f4e287, + (q31_t)0x66e5f1be, (q31_t)0x66d6fcfd, + (q31_t)0x66c80445, (q31_t)0x66b90797, (q31_t)0x66aa06f3, (q31_t)0x669b0259, (q31_t)0x668bf9cb, (q31_t)0x667ced49, + (q31_t)0x666ddcd3, (q31_t)0x665ec86b, + (q31_t)0x664fb010, (q31_t)0x664093c3, (q31_t)0x66317385, (q31_t)0x66224f56, (q31_t)0x66132738, (q31_t)0x6603fb2a, + (q31_t)0x65f4cb2d, (q31_t)0x65e59742, + (q31_t)0x65d65f69, (q31_t)0x65c723a3, (q31_t)0x65b7e3f1, (q31_t)0x65a8a052, (q31_t)0x659958c9, (q31_t)0x658a0d54, + (q31_t)0x657abdf6, (q31_t)0x656b6aae, + (q31_t)0x655c137d, (q31_t)0x654cb863, (q31_t)0x653d5962, (q31_t)0x652df679, (q31_t)0x651e8faa, (q31_t)0x650f24f5, + (q31_t)0x64ffb65b, (q31_t)0x64f043dc, + (q31_t)0x64e0cd78, (q31_t)0x64d15331, (q31_t)0x64c1d507, (q31_t)0x64b252fa, (q31_t)0x64a2cd0c, (q31_t)0x6493433c, + (q31_t)0x6483b58c, (q31_t)0x647423fb, + (q31_t)0x64648e8c, (q31_t)0x6454f53d, (q31_t)0x64455810, (q31_t)0x6435b706, (q31_t)0x6426121e, (q31_t)0x6416695a, + (q31_t)0x6406bcba, (q31_t)0x63f70c3f, + (q31_t)0x63e757ea, (q31_t)0x63d79fba, (q31_t)0x63c7e3b1, (q31_t)0x63b823cf, (q31_t)0x63a86015, (q31_t)0x63989884, + (q31_t)0x6388cd1b, (q31_t)0x6378fddc, + (q31_t)0x63692ac7, (q31_t)0x635953dd, (q31_t)0x6349791f, (q31_t)0x63399a8d, (q31_t)0x6329b827, (q31_t)0x6319d1ef, + (q31_t)0x6309e7e4, (q31_t)0x62f9fa09, + (q31_t)0x62ea085c, (q31_t)0x62da12df, (q31_t)0x62ca1992, (q31_t)0x62ba1c77, (q31_t)0x62aa1b8d, (q31_t)0x629a16d5, + (q31_t)0x628a0e50, (q31_t)0x627a01fe, + (q31_t)0x6269f1e1, (q31_t)0x6259ddf8, (q31_t)0x6249c645, (q31_t)0x6239aac7, (q31_t)0x62298b81, (q31_t)0x62196871, + (q31_t)0x62094199, (q31_t)0x61f916f9, + (q31_t)0x61e8e893, (q31_t)0x61d8b666, (q31_t)0x61c88074, (q31_t)0x61b846bc, (q31_t)0x61a80940, (q31_t)0x6197c800, + (q31_t)0x618782fd, (q31_t)0x61773a37, + (q31_t)0x6166edb0, (q31_t)0x61569d67, (q31_t)0x6146495d, (q31_t)0x6135f193, (q31_t)0x6125960a, (q31_t)0x611536c2, + (q31_t)0x6104d3bc, (q31_t)0x60f46cf9, + (q31_t)0x60e40278, (q31_t)0x60d3943b, (q31_t)0x60c32243, (q31_t)0x60b2ac8f, (q31_t)0x60a23322, (q31_t)0x6091b5fa, + (q31_t)0x60813519, (q31_t)0x6070b080, + (q31_t)0x6060282f, (q31_t)0x604f9c27, (q31_t)0x603f0c69, (q31_t)0x602e78f4, (q31_t)0x601de1ca, (q31_t)0x600d46ec, + (q31_t)0x5ffca859, (q31_t)0x5fec0613, + (q31_t)0x5fdb601b, (q31_t)0x5fcab670, (q31_t)0x5fba0914, (q31_t)0x5fa95807, (q31_t)0x5f98a34a, (q31_t)0x5f87eade, + (q31_t)0x5f772ec2, (q31_t)0x5f666ef9, + (q31_t)0x5f55ab82, (q31_t)0x5f44e45e, (q31_t)0x5f34198e, (q31_t)0x5f234b12, (q31_t)0x5f1278eb, (q31_t)0x5f01a31a, + (q31_t)0x5ef0c99f, (q31_t)0x5edfec7b, + (q31_t)0x5ecf0baf, (q31_t)0x5ebe273b, (q31_t)0x5ead3f1f, (q31_t)0x5e9c535e, (q31_t)0x5e8b63f7, (q31_t)0x5e7a70ea, + (q31_t)0x5e697a39, (q31_t)0x5e587fe5, + (q31_t)0x5e4781ed, (q31_t)0x5e368053, (q31_t)0x5e257b17, (q31_t)0x5e147239, (q31_t)0x5e0365bb, (q31_t)0x5df2559e, + (q31_t)0x5de141e1, (q31_t)0x5dd02a85, + (q31_t)0x5dbf0f8c, (q31_t)0x5dadf0f5, (q31_t)0x5d9ccec2, (q31_t)0x5d8ba8f3, (q31_t)0x5d7a7f88, (q31_t)0x5d695283, + (q31_t)0x5d5821e4, (q31_t)0x5d46edac, + (q31_t)0x5d35b5db, (q31_t)0x5d247a72, (q31_t)0x5d133b72, (q31_t)0x5d01f8dc, (q31_t)0x5cf0b2af, (q31_t)0x5cdf68ed, + (q31_t)0x5cce1b97, (q31_t)0x5cbccaac, + (q31_t)0x5cab762f, (q31_t)0x5c9a1e1e, (q31_t)0x5c88c27c, (q31_t)0x5c776348, (q31_t)0x5c660084, (q31_t)0x5c549a30, + (q31_t)0x5c43304d, (q31_t)0x5c31c2db, + (q31_t)0x5c2051db, (q31_t)0x5c0edd4e, (q31_t)0x5bfd6534, (q31_t)0x5bebe98e, (q31_t)0x5bda6a5d, (q31_t)0x5bc8e7a2, + (q31_t)0x5bb7615d, (q31_t)0x5ba5d78e, + (q31_t)0x5b944a37, (q31_t)0x5b82b958, (q31_t)0x5b7124f2, (q31_t)0x5b5f8d06, (q31_t)0x5b4df193, (q31_t)0x5b3c529c, + (q31_t)0x5b2ab020, (q31_t)0x5b190a20, + (q31_t)0x5b07609d, (q31_t)0x5af5b398, (q31_t)0x5ae40311, (q31_t)0x5ad24f09, (q31_t)0x5ac09781, (q31_t)0x5aaedc78, + (q31_t)0x5a9d1df1, (q31_t)0x5a8b5bec, + (q31_t)0x5a799669, (q31_t)0x5a67cd69, (q31_t)0x5a5600ec, (q31_t)0x5a4430f5, (q31_t)0x5a325d82, (q31_t)0x5a208695, + (q31_t)0x5a0eac2e, (q31_t)0x59fcce4f, + (q31_t)0x59eaecf8, (q31_t)0x59d90829, (q31_t)0x59c71fe3, (q31_t)0x59b53427, (q31_t)0x59a344f6, (q31_t)0x59915250, + (q31_t)0x597f5c36, (q31_t)0x596d62a9, + (q31_t)0x595b65aa, (q31_t)0x59496538, (q31_t)0x59376155, (q31_t)0x59255a02, (q31_t)0x59134f3e, (q31_t)0x5901410c, + (q31_t)0x58ef2f6b, (q31_t)0x58dd1a5d, + (q31_t)0x58cb01e1, (q31_t)0x58b8e5f9, (q31_t)0x58a6c6a5, (q31_t)0x5894a3e7, (q31_t)0x58827dbe, (q31_t)0x5870542c, + (q31_t)0x585e2730, (q31_t)0x584bf6cd, + (q31_t)0x5839c302, (q31_t)0x58278bd1, (q31_t)0x58155139, (q31_t)0x5803133c, (q31_t)0x57f0d1da, (q31_t)0x57de8d15, + (q31_t)0x57cc44ec, (q31_t)0x57b9f960, + (q31_t)0x57a7aa73, (q31_t)0x57955825, (q31_t)0x57830276, (q31_t)0x5770a968, (q31_t)0x575e4cfa, (q31_t)0x574bed2f, + (q31_t)0x57398a05, (q31_t)0x5727237f, + (q31_t)0x5714b99d, (q31_t)0x57024c5f, (q31_t)0x56efdbc7, (q31_t)0x56dd67d4, (q31_t)0x56caf088, (q31_t)0x56b875e4, + (q31_t)0x56a5f7e7, (q31_t)0x56937694, + (q31_t)0x5680f1ea, (q31_t)0x566e69ea, (q31_t)0x565bde95, (q31_t)0x56494fec, (q31_t)0x5636bdef, (q31_t)0x5624289f, + (q31_t)0x56118ffe, (q31_t)0x55fef40a, + (q31_t)0x55ec54c6, (q31_t)0x55d9b232, (q31_t)0x55c70c4f, (q31_t)0x55b4631d, (q31_t)0x55a1b69d, (q31_t)0x558f06d0, + (q31_t)0x557c53b6, (q31_t)0x55699d51, + (q31_t)0x5556e3a1, (q31_t)0x554426a7, (q31_t)0x55316663, (q31_t)0x551ea2d6, (q31_t)0x550bdc01, (q31_t)0x54f911e5, + (q31_t)0x54e64482, (q31_t)0x54d373d9, + (q31_t)0x54c09feb, (q31_t)0x54adc8b8, (q31_t)0x549aee42, (q31_t)0x54881089, (q31_t)0x54752f8d, (q31_t)0x54624b50, + (q31_t)0x544f63d2, (q31_t)0x543c7914, + (q31_t)0x54298b17, (q31_t)0x541699db, (q31_t)0x5403a561, (q31_t)0x53f0adaa, (q31_t)0x53ddb2b6, (q31_t)0x53cab486, + (q31_t)0x53b7b31c, (q31_t)0x53a4ae77, + (q31_t)0x5391a699, (q31_t)0x537e9b82, (q31_t)0x536b8d33, (q31_t)0x53587bad, (q31_t)0x534566f0, (q31_t)0x53324efd, + (q31_t)0x531f33d5, (q31_t)0x530c1579, + (q31_t)0x52f8f3e9, (q31_t)0x52e5cf27, (q31_t)0x52d2a732, (q31_t)0x52bf7c0b, (q31_t)0x52ac4db4, (q31_t)0x52991c2d, + (q31_t)0x5285e777, (q31_t)0x5272af92, + (q31_t)0x525f7480, (q31_t)0x524c3640, (q31_t)0x5238f4d4, (q31_t)0x5225b03d, (q31_t)0x5212687b, (q31_t)0x51ff1d8f, + (q31_t)0x51ebcf7a, (q31_t)0x51d87e3c, + (q31_t)0x51c529d7, (q31_t)0x51b1d24a, (q31_t)0x519e7797, (q31_t)0x518b19bf, (q31_t)0x5177b8c2, (q31_t)0x516454a0, + (q31_t)0x5150ed5c, (q31_t)0x513d82f4, + (q31_t)0x512a156b, (q31_t)0x5116a4c1, (q31_t)0x510330f7, (q31_t)0x50efba0d, (q31_t)0x50dc4005, (q31_t)0x50c8c2de, + (q31_t)0x50b5429a, (q31_t)0x50a1bf39, + (q31_t)0x508e38bd, (q31_t)0x507aaf25, (q31_t)0x50672273, (q31_t)0x505392a8, (q31_t)0x503fffc4, (q31_t)0x502c69c8, + (q31_t)0x5018d0b4, (q31_t)0x5005348a, + (q31_t)0x4ff1954b, (q31_t)0x4fddf2f6, (q31_t)0x4fca4d8d, (q31_t)0x4fb6a510, (q31_t)0x4fa2f981, (q31_t)0x4f8f4ae0, + (q31_t)0x4f7b992d, (q31_t)0x4f67e46a, + (q31_t)0x4f542c98, (q31_t)0x4f4071b6, (q31_t)0x4f2cb3c7, (q31_t)0x4f18f2c9, (q31_t)0x4f052ec0, (q31_t)0x4ef167aa, + (q31_t)0x4edd9d89, (q31_t)0x4ec9d05e, + (q31_t)0x4eb60029, (q31_t)0x4ea22ceb, (q31_t)0x4e8e56a5, (q31_t)0x4e7a7d58, (q31_t)0x4e66a105, (q31_t)0x4e52c1ab, + (q31_t)0x4e3edf4d, (q31_t)0x4e2af9ea, + (q31_t)0x4e171184, (q31_t)0x4e03261b, (q31_t)0x4def37b0, (q31_t)0x4ddb4644, (q31_t)0x4dc751d8, (q31_t)0x4db35a6c, + (q31_t)0x4d9f6001, (q31_t)0x4d8b6298, + (q31_t)0x4d776231, (q31_t)0x4d635ece, (q31_t)0x4d4f5870, (q31_t)0x4d3b4f16, (q31_t)0x4d2742c2, (q31_t)0x4d133374, + (q31_t)0x4cff212e, (q31_t)0x4ceb0bf0, + (q31_t)0x4cd6f3bb, (q31_t)0x4cc2d88f, (q31_t)0x4caeba6e, (q31_t)0x4c9a9958, (q31_t)0x4c86754e, (q31_t)0x4c724e50, + (q31_t)0x4c5e2460, (q31_t)0x4c49f77f, + (q31_t)0x4c35c7ac, (q31_t)0x4c2194e9, (q31_t)0x4c0d5f37, (q31_t)0x4bf92697, (q31_t)0x4be4eb08, (q31_t)0x4bd0ac8d, + (q31_t)0x4bbc6b25, (q31_t)0x4ba826d1, + (q31_t)0x4b93df93, (q31_t)0x4b7f956b, (q31_t)0x4b6b485a, (q31_t)0x4b56f861, (q31_t)0x4b42a580, (q31_t)0x4b2e4fb8, + (q31_t)0x4b19f70a, (q31_t)0x4b059b77, + (q31_t)0x4af13d00, (q31_t)0x4adcdba5, (q31_t)0x4ac87767, (q31_t)0x4ab41046, (q31_t)0x4a9fa645, (q31_t)0x4a8b3963, + (q31_t)0x4a76c9a2, (q31_t)0x4a625701, + (q31_t)0x4a4de182, (q31_t)0x4a396926, (q31_t)0x4a24edee, (q31_t)0x4a106fda, (q31_t)0x49fbeeea, (q31_t)0x49e76b21, + (q31_t)0x49d2e47e, (q31_t)0x49be5b02, + (q31_t)0x49a9ceaf, (q31_t)0x49953f84, (q31_t)0x4980ad84, (q31_t)0x496c18ae, (q31_t)0x49578103, (q31_t)0x4942e684, + (q31_t)0x492e4933, (q31_t)0x4919a90f, + (q31_t)0x4905061a, (q31_t)0x48f06054, (q31_t)0x48dbb7be, (q31_t)0x48c70c59, (q31_t)0x48b25e25, (q31_t)0x489dad25, + (q31_t)0x4888f957, (q31_t)0x487442be, + (q31_t)0x485f8959, (q31_t)0x484acd2a, (q31_t)0x48360e32, (q31_t)0x48214c71, (q31_t)0x480c87e8, (q31_t)0x47f7c099, + (q31_t)0x47e2f682, (q31_t)0x47ce29a7, + (q31_t)0x47b95a06, (q31_t)0x47a487a2, (q31_t)0x478fb27b, (q31_t)0x477ada91, (q31_t)0x4765ffe6, (q31_t)0x4751227a, + (q31_t)0x473c424e, (q31_t)0x47275f63, + (q31_t)0x471279ba, (q31_t)0x46fd9154, (q31_t)0x46e8a631, (q31_t)0x46d3b852, (q31_t)0x46bec7b8, (q31_t)0x46a9d464, + (q31_t)0x4694de56, (q31_t)0x467fe590, + (q31_t)0x466aea12, (q31_t)0x4655ebdd, (q31_t)0x4640eaf2, (q31_t)0x462be751, (q31_t)0x4616e0fc, (q31_t)0x4601d7f3, + (q31_t)0x45eccc37, (q31_t)0x45d7bdc9, + (q31_t)0x45c2acaa, (q31_t)0x45ad98da, (q31_t)0x4598825a, (q31_t)0x4583692c, (q31_t)0x456e4d4f, (q31_t)0x45592ec6, + (q31_t)0x45440d90, (q31_t)0x452ee9ae, + (q31_t)0x4519c321, (q31_t)0x450499eb, (q31_t)0x44ef6e0b, (q31_t)0x44da3f83, (q31_t)0x44c50e53, (q31_t)0x44afda7d, + (q31_t)0x449aa400, (q31_t)0x44856adf, + (q31_t)0x44702f19, (q31_t)0x445af0b0, (q31_t)0x4445afa4, (q31_t)0x44306bf6, (q31_t)0x441b25a8, (q31_t)0x4405dcb9, + (q31_t)0x43f0912b, (q31_t)0x43db42fe, + (q31_t)0x43c5f234, (q31_t)0x43b09ecc, (q31_t)0x439b48c9, (q31_t)0x4385f02a, (q31_t)0x437094f1, (q31_t)0x435b371f, + (q31_t)0x4345d6b3, (q31_t)0x433073b0, + (q31_t)0x431b0e15, (q31_t)0x4305a5e5, (q31_t)0x42f03b1e, (q31_t)0x42dacdc3, (q31_t)0x42c55dd4, (q31_t)0x42afeb53, + (q31_t)0x429a763f, (q31_t)0x4284fe99, + (q31_t)0x426f8463, (q31_t)0x425a079e, (q31_t)0x42448849, (q31_t)0x422f0667, (q31_t)0x421981f7, (q31_t)0x4203fafb, + (q31_t)0x41ee7174, (q31_t)0x41d8e561, + (q31_t)0x41c356c5, (q31_t)0x41adc5a0, (q31_t)0x419831f3, (q31_t)0x41829bbe, (q31_t)0x416d0302, (q31_t)0x415767c1, + (q31_t)0x4141c9fb, (q31_t)0x412c29b1, + (q31_t)0x411686e4, (q31_t)0x4100e194, (q31_t)0x40eb39c3, (q31_t)0x40d58f71, (q31_t)0x40bfe29f, (q31_t)0x40aa334e, + (q31_t)0x4094817f, (q31_t)0x407ecd32, + (q31_t)0x40691669, (q31_t)0x40535d24, (q31_t)0x403da165, (q31_t)0x4027e32b, (q31_t)0x40122278, (q31_t)0x3ffc5f4d, + (q31_t)0x3fe699aa, (q31_t)0x3fd0d191, + (q31_t)0x3fbb0702, (q31_t)0x3fa539fd, (q31_t)0x3f8f6a85, (q31_t)0x3f799899, (q31_t)0x3f63c43b, (q31_t)0x3f4ded6b, + (q31_t)0x3f38142a, (q31_t)0x3f22387a, + (q31_t)0x3f0c5a5a, (q31_t)0x3ef679cc, (q31_t)0x3ee096d1, (q31_t)0x3ecab169, (q31_t)0x3eb4c995, (q31_t)0x3e9edf57, + (q31_t)0x3e88f2ae, (q31_t)0x3e73039d, + (q31_t)0x3e5d1222, (q31_t)0x3e471e41, (q31_t)0x3e3127f9, (q31_t)0x3e1b2f4a, (q31_t)0x3e053437, (q31_t)0x3def36c0, + (q31_t)0x3dd936e6, (q31_t)0x3dc334a9, + (q31_t)0x3dad300b, (q31_t)0x3d97290b, (q31_t)0x3d811fac, (q31_t)0x3d6b13ee, (q31_t)0x3d5505d2, (q31_t)0x3d3ef559, + (q31_t)0x3d28e282, (q31_t)0x3d12cd51, + (q31_t)0x3cfcb5c4, (q31_t)0x3ce69bde, (q31_t)0x3cd07f9f, (q31_t)0x3cba6107, (q31_t)0x3ca44018, (q31_t)0x3c8e1cd3, + (q31_t)0x3c77f737, (q31_t)0x3c61cf48, + (q31_t)0x3c4ba504, (q31_t)0x3c35786d, (q31_t)0x3c1f4983, (q31_t)0x3c091849, (q31_t)0x3bf2e4be, (q31_t)0x3bdcaee3, + (q31_t)0x3bc676b9, (q31_t)0x3bb03c42, + (q31_t)0x3b99ff7d, (q31_t)0x3b83c06c, (q31_t)0x3b6d7f10, (q31_t)0x3b573b69, (q31_t)0x3b40f579, (q31_t)0x3b2aad3f, + (q31_t)0x3b1462be, (q31_t)0x3afe15f6, + (q31_t)0x3ae7c6e7, (q31_t)0x3ad17593, (q31_t)0x3abb21fb, (q31_t)0x3aa4cc1e, (q31_t)0x3a8e7400, (q31_t)0x3a78199f, + (q31_t)0x3a61bcfd, (q31_t)0x3a4b5e1b, + (q31_t)0x3a34fcf9, (q31_t)0x3a1e9999, (q31_t)0x3a0833fc, (q31_t)0x39f1cc21, (q31_t)0x39db620b, (q31_t)0x39c4f5ba, + (q31_t)0x39ae872f, (q31_t)0x3998166a, + (q31_t)0x3981a36d, (q31_t)0x396b2e38, (q31_t)0x3954b6cd, (q31_t)0x393e3d2c, (q31_t)0x3927c155, (q31_t)0x3911434b, + (q31_t)0x38fac30e, (q31_t)0x38e4409e, + (q31_t)0x38cdbbfc, (q31_t)0x38b7352a, (q31_t)0x38a0ac29, (q31_t)0x388a20f8, (q31_t)0x38739399, (q31_t)0x385d040d, + (q31_t)0x38467255, (q31_t)0x382fde72, + (q31_t)0x38194864, (q31_t)0x3802b02c, (q31_t)0x37ec15cb, (q31_t)0x37d57943, (q31_t)0x37beda93, (q31_t)0x37a839be, + (q31_t)0x379196c3, (q31_t)0x377af1a3, + (q31_t)0x37644a60, (q31_t)0x374da0fa, (q31_t)0x3736f573, (q31_t)0x372047ca, (q31_t)0x37099802, (q31_t)0x36f2e61a, + (q31_t)0x36dc3214, (q31_t)0x36c57bf0, + (q31_t)0x36aec3b0, (q31_t)0x36980954, (q31_t)0x36814cde, (q31_t)0x366a8e4d, (q31_t)0x3653cda3, (q31_t)0x363d0ae2, + (q31_t)0x36264609, (q31_t)0x360f7f19, + (q31_t)0x35f8b614, (q31_t)0x35e1eafa, (q31_t)0x35cb1dcc, (q31_t)0x35b44e8c, (q31_t)0x359d7d39, (q31_t)0x3586a9d5, + (q31_t)0x356fd461, (q31_t)0x3558fcde, + (q31_t)0x3542234c, (q31_t)0x352b47ad, (q31_t)0x35146a00, (q31_t)0x34fd8a48, (q31_t)0x34e6a885, (q31_t)0x34cfc4b7, + (q31_t)0x34b8dee1, (q31_t)0x34a1f702, + (q31_t)0x348b0d1c, (q31_t)0x3474212f, (q31_t)0x345d333c, (q31_t)0x34464345, (q31_t)0x342f5149, (q31_t)0x34185d4b, + (q31_t)0x3401674a, (q31_t)0x33ea6f48, + (q31_t)0x33d37546, (q31_t)0x33bc7944, (q31_t)0x33a57b44, (q31_t)0x338e7b46, (q31_t)0x3377794b, (q31_t)0x33607554, + (q31_t)0x33496f62, (q31_t)0x33326776, + (q31_t)0x331b5d91, (q31_t)0x330451b3, (q31_t)0x32ed43de, (q31_t)0x32d63412, (q31_t)0x32bf2250, (q31_t)0x32a80e99, + (q31_t)0x3290f8ef, (q31_t)0x3279e151, + (q31_t)0x3262c7c1, (q31_t)0x324bac40, (q31_t)0x32348ecf, (q31_t)0x321d6f6e, (q31_t)0x32064e1e, (q31_t)0x31ef2ae1, + (q31_t)0x31d805b7, (q31_t)0x31c0dea1, + (q31_t)0x31a9b5a0, (q31_t)0x31928ab4, (q31_t)0x317b5de0, (q31_t)0x31642f23, (q31_t)0x314cfe7f, (q31_t)0x3135cbf4, + (q31_t)0x311e9783, (q31_t)0x3107612e, + (q31_t)0x30f028f4, (q31_t)0x30d8eed8, (q31_t)0x30c1b2da, (q31_t)0x30aa74fa, (q31_t)0x3093353a, (q31_t)0x307bf39b, + (q31_t)0x3064b01d, (q31_t)0x304d6ac1, + (q31_t)0x30362389, (q31_t)0x301eda75, (q31_t)0x30078f86, (q31_t)0x2ff042bd, (q31_t)0x2fd8f41b, (q31_t)0x2fc1a3a0, + (q31_t)0x2faa514f, (q31_t)0x2f92fd26, + (q31_t)0x2f7ba729, (q31_t)0x2f644f56, (q31_t)0x2f4cf5b0, (q31_t)0x2f359a37, (q31_t)0x2f1e3ced, (q31_t)0x2f06ddd1, + (q31_t)0x2eef7ce5, (q31_t)0x2ed81a29, + (q31_t)0x2ec0b5a0, (q31_t)0x2ea94f49, (q31_t)0x2e91e725, (q31_t)0x2e7a7d36, (q31_t)0x2e63117c, (q31_t)0x2e4ba3f8, + (q31_t)0x2e3434ac, (q31_t)0x2e1cc397, + (q31_t)0x2e0550bb, (q31_t)0x2deddc19, (q31_t)0x2dd665b2, (q31_t)0x2dbeed86, (q31_t)0x2da77397, (q31_t)0x2d8ff7e5, + (q31_t)0x2d787a72, (q31_t)0x2d60fb3e, + (q31_t)0x2d497a4a, (q31_t)0x2d31f797, (q31_t)0x2d1a7325, (q31_t)0x2d02ecf7, (q31_t)0x2ceb650d, (q31_t)0x2cd3db67, + (q31_t)0x2cbc5006, (q31_t)0x2ca4c2ed, + (q31_t)0x2c8d341a, (q31_t)0x2c75a390, (q31_t)0x2c5e114f, (q31_t)0x2c467d58, (q31_t)0x2c2ee7ad, (q31_t)0x2c17504d, + (q31_t)0x2bffb73a, (q31_t)0x2be81c74, + (q31_t)0x2bd07ffe, (q31_t)0x2bb8e1d7, (q31_t)0x2ba14200, (q31_t)0x2b89a07b, (q31_t)0x2b71fd48, (q31_t)0x2b5a5868, + (q31_t)0x2b42b1dd, (q31_t)0x2b2b09a6, + (q31_t)0x2b135fc6, (q31_t)0x2afbb43c, (q31_t)0x2ae4070a, (q31_t)0x2acc5831, (q31_t)0x2ab4a7b1, (q31_t)0x2a9cf58c, + (q31_t)0x2a8541c3, (q31_t)0x2a6d8c55, + (q31_t)0x2a55d545, (q31_t)0x2a3e1c93, (q31_t)0x2a266240, (q31_t)0x2a0ea64d, (q31_t)0x29f6e8bb, (q31_t)0x29df298b, + (q31_t)0x29c768be, (q31_t)0x29afa654, + (q31_t)0x2997e24f, (q31_t)0x29801caf, (q31_t)0x29685576, (q31_t)0x29508ca4, (q31_t)0x2938c23a, (q31_t)0x2920f63a, + (q31_t)0x290928a3, (q31_t)0x28f15978, + (q31_t)0x28d988b8, (q31_t)0x28c1b666, (q31_t)0x28a9e281, (q31_t)0x28920d0a, (q31_t)0x287a3604, (q31_t)0x28625d6d, + (q31_t)0x284a8349, (q31_t)0x2832a796, + (q31_t)0x281aca57, (q31_t)0x2802eb8c, (q31_t)0x27eb0b36, (q31_t)0x27d32956, (q31_t)0x27bb45ed, (q31_t)0x27a360fc, + (q31_t)0x278b7a84, (q31_t)0x27739285, + (q31_t)0x275ba901, (q31_t)0x2743bdf9, (q31_t)0x272bd16d, (q31_t)0x2713e35f, (q31_t)0x26fbf3ce, (q31_t)0x26e402bd, + (q31_t)0x26cc102d, (q31_t)0x26b41c1d, + (q31_t)0x269c268f, (q31_t)0x26842f84, (q31_t)0x266c36fe, (q31_t)0x26543cfb, (q31_t)0x263c417f, (q31_t)0x26244489, + (q31_t)0x260c461b, (q31_t)0x25f44635, + (q31_t)0x25dc44d9, (q31_t)0x25c44207, (q31_t)0x25ac3dc0, (q31_t)0x25943806, (q31_t)0x257c30d8, (q31_t)0x25642839, + (q31_t)0x254c1e28, (q31_t)0x253412a8, + (q31_t)0x251c05b8, (q31_t)0x2503f75a, (q31_t)0x24ebe78f, (q31_t)0x24d3d657, (q31_t)0x24bbc3b4, (q31_t)0x24a3afa6, + (q31_t)0x248b9a2f, (q31_t)0x2473834f, + (q31_t)0x245b6b07, (q31_t)0x24435158, (q31_t)0x242b3644, (q31_t)0x241319ca, (q31_t)0x23fafbec, (q31_t)0x23e2dcac, + (q31_t)0x23cabc09, (q31_t)0x23b29a05, + (q31_t)0x239a76a0, (q31_t)0x238251dd, (q31_t)0x236a2bba, (q31_t)0x2352043b, (q31_t)0x2339db5e, (q31_t)0x2321b126, + (q31_t)0x23098593, (q31_t)0x22f158a7, + (q31_t)0x22d92a61, (q31_t)0x22c0fac4, (q31_t)0x22a8c9cf, (q31_t)0x22909785, (q31_t)0x227863e5, (q31_t)0x22602ef1, + (q31_t)0x2247f8aa, (q31_t)0x222fc111, + (q31_t)0x22178826, (q31_t)0x21ff4dea, (q31_t)0x21e71260, (q31_t)0x21ced586, (q31_t)0x21b6975f, (q31_t)0x219e57eb, + (q31_t)0x2186172b, (q31_t)0x216dd521, + (q31_t)0x215591cc, (q31_t)0x213d4d2f, (q31_t)0x21250749, (q31_t)0x210cc01d, (q31_t)0x20f477aa, (q31_t)0x20dc2df2, + (q31_t)0x20c3e2f5, (q31_t)0x20ab96b5, + (q31_t)0x20934933, (q31_t)0x207afa6f, (q31_t)0x2062aa6b, (q31_t)0x204a5927, (q31_t)0x203206a4, (q31_t)0x2019b2e4, + (q31_t)0x20015de7, (q31_t)0x1fe907ae, + (q31_t)0x1fd0b03a, (q31_t)0x1fb8578b, (q31_t)0x1f9ffda4, (q31_t)0x1f87a285, (q31_t)0x1f6f462f, (q31_t)0x1f56e8a2, + (q31_t)0x1f3e89e0, (q31_t)0x1f2629ea, + (q31_t)0x1f0dc8c0, (q31_t)0x1ef56664, (q31_t)0x1edd02d6, (q31_t)0x1ec49e17, (q31_t)0x1eac3829, (q31_t)0x1e93d10c, + (q31_t)0x1e7b68c2, (q31_t)0x1e62ff4a, + (q31_t)0x1e4a94a7, (q31_t)0x1e3228d9, (q31_t)0x1e19bbe0, (q31_t)0x1e014dbf, (q31_t)0x1de8de75, (q31_t)0x1dd06e04, + (q31_t)0x1db7fc6d, (q31_t)0x1d9f89b1, + (q31_t)0x1d8715d0, (q31_t)0x1d6ea0cc, (q31_t)0x1d562aa6, (q31_t)0x1d3db35e, (q31_t)0x1d253af5, (q31_t)0x1d0cc16c, + (q31_t)0x1cf446c5, (q31_t)0x1cdbcb00, + (q31_t)0x1cc34e1f, (q31_t)0x1caad021, (q31_t)0x1c925109, (q31_t)0x1c79d0d6, (q31_t)0x1c614f8b, (q31_t)0x1c48cd27, + (q31_t)0x1c3049ac, (q31_t)0x1c17c51b, + (q31_t)0x1bff3f75, (q31_t)0x1be6b8ba, (q31_t)0x1bce30ec, (q31_t)0x1bb5a80c, (q31_t)0x1b9d1e1a, (q31_t)0x1b849317, + (q31_t)0x1b6c0705, (q31_t)0x1b5379e5, + (q31_t)0x1b3aebb6, (q31_t)0x1b225c7b, (q31_t)0x1b09cc34, (q31_t)0x1af13ae3, (q31_t)0x1ad8a887, (q31_t)0x1ac01522, + (q31_t)0x1aa780b6, (q31_t)0x1a8eeb42, + (q31_t)0x1a7654c8, (q31_t)0x1a5dbd49, (q31_t)0x1a4524c6, (q31_t)0x1a2c8b3f, (q31_t)0x1a13f0b6, (q31_t)0x19fb552c, + (q31_t)0x19e2b8a2, (q31_t)0x19ca1b17, + (q31_t)0x19b17c8f, (q31_t)0x1998dd09, (q31_t)0x19803c86, (q31_t)0x19679b07, (q31_t)0x194ef88e, (q31_t)0x1936551b, + (q31_t)0x191db0af, (q31_t)0x19050b4b, + (q31_t)0x18ec64f0, (q31_t)0x18d3bda0, (q31_t)0x18bb155a, (q31_t)0x18a26c20, (q31_t)0x1889c1f3, (q31_t)0x187116d4, + (q31_t)0x18586ac3, (q31_t)0x183fbdc3, + (q31_t)0x18270fd3, (q31_t)0x180e60f4, (q31_t)0x17f5b129, (q31_t)0x17dd0070, (q31_t)0x17c44ecd, (q31_t)0x17ab9c3e, + (q31_t)0x1792e8c6, (q31_t)0x177a3466, + (q31_t)0x17617f1d, (q31_t)0x1748c8ee, (q31_t)0x173011d9, (q31_t)0x171759df, (q31_t)0x16fea102, (q31_t)0x16e5e741, + (q31_t)0x16cd2c9f, (q31_t)0x16b4711b, + (q31_t)0x169bb4b7, (q31_t)0x1682f774, (q31_t)0x166a3953, (q31_t)0x16517a55, (q31_t)0x1638ba7a, (q31_t)0x161ff9c4, + (q31_t)0x16073834, (q31_t)0x15ee75cb, + (q31_t)0x15d5b288, (q31_t)0x15bcee6f, (q31_t)0x15a4297f, (q31_t)0x158b63b9, (q31_t)0x15729d1f, (q31_t)0x1559d5b1, + (q31_t)0x15410d70, (q31_t)0x1528445d, + (q31_t)0x150f7a7a, (q31_t)0x14f6afc7, (q31_t)0x14dde445, (q31_t)0x14c517f4, (q31_t)0x14ac4ad7, (q31_t)0x14937cee, + (q31_t)0x147aae3a, (q31_t)0x1461debc, + (q31_t)0x14490e74, (q31_t)0x14303d65, (q31_t)0x14176b8e, (q31_t)0x13fe98f1, (q31_t)0x13e5c58e, (q31_t)0x13ccf167, + (q31_t)0x13b41c7d, (q31_t)0x139b46d0, + (q31_t)0x13827062, (q31_t)0x13699933, (q31_t)0x1350c144, (q31_t)0x1337e897, (q31_t)0x131f0f2c, (q31_t)0x13063505, + (q31_t)0x12ed5a21, (q31_t)0x12d47e83, + (q31_t)0x12bba22b, (q31_t)0x12a2c51b, (q31_t)0x1289e752, (q31_t)0x127108d2, (q31_t)0x1258299c, (q31_t)0x123f49b2, + (q31_t)0x12266913, (q31_t)0x120d87c1, + (q31_t)0x11f4a5bd, (q31_t)0x11dbc307, (q31_t)0x11c2dfa2, (q31_t)0x11a9fb8d, (q31_t)0x119116c9, (q31_t)0x11783159, + (q31_t)0x115f4b3c, (q31_t)0x11466473, + (q31_t)0x112d7d00, (q31_t)0x111494e4, (q31_t)0x10fbac1e, (q31_t)0x10e2c2b2, (q31_t)0x10c9d89e, (q31_t)0x10b0ede5, + (q31_t)0x10980287, (q31_t)0x107f1686, + (q31_t)0x106629e1, (q31_t)0x104d3c9b, (q31_t)0x10344eb4, (q31_t)0x101b602d, (q31_t)0x10027107, (q31_t)0xfe98143, + (q31_t)0xfd090e1, (q31_t)0xfb79fe4, + (q31_t)0xf9eae4c, (q31_t)0xf85bc19, (q31_t)0xf6cc94e, (q31_t)0xf53d5ea, (q31_t)0xf3ae1ee, (q31_t)0xf21ed5d, (q31_t)0xf08f836, + (q31_t)0xef0027b, + (q31_t)0xed70c2c, (q31_t)0xebe154b, (q31_t)0xea51dd8, (q31_t)0xe8c25d5, (q31_t)0xe732d42, (q31_t)0xe5a3421, (q31_t)0xe413a72, + (q31_t)0xe284036, + (q31_t)0xe0f456f, (q31_t)0xdf64a1c, (q31_t)0xddd4e40, (q31_t)0xdc451dc, (q31_t)0xdab54ef, (q31_t)0xd92577b, (q31_t)0xd795982, + (q31_t)0xd605b03, + (q31_t)0xd475c00, (q31_t)0xd2e5c7b, (q31_t)0xd155c73, (q31_t)0xcfc5bea, (q31_t)0xce35ae1, (q31_t)0xcca5959, (q31_t)0xcb15752, + (q31_t)0xc9854cf, + (q31_t)0xc7f51cf, (q31_t)0xc664e53, (q31_t)0xc4d4a5d, (q31_t)0xc3445ee, (q31_t)0xc1b4107, (q31_t)0xc023ba7, (q31_t)0xbe935d2, + (q31_t)0xbd02f87, + (q31_t)0xbb728c7, (q31_t)0xb9e2193, (q31_t)0xb8519ed, (q31_t)0xb6c11d5, (q31_t)0xb53094d, (q31_t)0xb3a0055, (q31_t)0xb20f6ee, + (q31_t)0xb07ed19, + (q31_t)0xaeee2d7, (q31_t)0xad5d829, (q31_t)0xabccd11, (q31_t)0xaa3c18e, (q31_t)0xa8ab5a2, (q31_t)0xa71a94f, (q31_t)0xa589c94, + (q31_t)0xa3f8f73, + (q31_t)0xa2681ed, (q31_t)0xa0d7403, (q31_t)0x9f465b5, (q31_t)0x9db5706, (q31_t)0x9c247f5, (q31_t)0x9a93884, (q31_t)0x99028b3, + (q31_t)0x9771884, + (q31_t)0x95e07f8, (q31_t)0x944f70f, (q31_t)0x92be5ca, (q31_t)0x912d42c, (q31_t)0x8f9c233, (q31_t)0x8e0afe2, (q31_t)0x8c79d3a, + (q31_t)0x8ae8a3a, + (q31_t)0x89576e5, (q31_t)0x87c633c, (q31_t)0x8634f3e, (q31_t)0x84a3aee, (q31_t)0x831264c, (q31_t)0x8181159, (q31_t)0x7fefc16, + (q31_t)0x7e5e685, + (q31_t)0x7ccd0a5, (q31_t)0x7b3ba78, (q31_t)0x79aa400, (q31_t)0x7818d3c, (q31_t)0x768762e, (q31_t)0x74f5ed7, (q31_t)0x7364738, + (q31_t)0x71d2f52, + (q31_t)0x7041726, (q31_t)0x6eafeb4, (q31_t)0x6d1e5fe, (q31_t)0x6b8cd05, (q31_t)0x69fb3c9, (q31_t)0x6869a4c, (q31_t)0x66d808f, + (q31_t)0x6546692, + (q31_t)0x63b4c57, (q31_t)0x62231de, (q31_t)0x6091729, (q31_t)0x5effc38, (q31_t)0x5d6e10c, (q31_t)0x5bdc5a7, (q31_t)0x5a4aa09, + (q31_t)0x58b8e34, + (q31_t)0x5727228, (q31_t)0x55955e6, (q31_t)0x540396f, (q31_t)0x5271cc4, (q31_t)0x50dffe7, (q31_t)0x4f4e2d8, (q31_t)0x4dbc597, + (q31_t)0x4c2a827, + (q31_t)0x4a98a88, (q31_t)0x4906cbb, (q31_t)0x4774ec1, (q31_t)0x45e309a, (q31_t)0x4451249, (q31_t)0x42bf3cd, (q31_t)0x412d528, + (q31_t)0x3f9b65b, + (q31_t)0x3e09767, (q31_t)0x3c7784d, (q31_t)0x3ae590d, (q31_t)0x39539a9, (q31_t)0x37c1a22, (q31_t)0x362fa78, (q31_t)0x349daac, + (q31_t)0x330bac1, + (q31_t)0x3179ab5, (q31_t)0x2fe7a8c, (q31_t)0x2e55a44, (q31_t)0x2cc39e1, (q31_t)0x2b31961, (q31_t)0x299f8c7, (q31_t)0x280d813, + (q31_t)0x267b747, + (q31_t)0x24e9662, (q31_t)0x2357567, (q31_t)0x21c5457, (q31_t)0x2033331, (q31_t)0x1ea11f7, (q31_t)0x1d0f0ab, (q31_t)0x1b7cf4d, + (q31_t)0x19eaddd, + (q31_t)0x1858c5e, (q31_t)0x16c6ad0, (q31_t)0x1534934, (q31_t)0x13a278a, (q31_t)0x12105d5, (q31_t)0x107e414, (q31_t)0xeec249, + (q31_t)0xd5a075, + (q31_t)0xbc7e99, (q31_t)0xa35cb5, (q31_t)0x8a3acb, (q31_t)0x7118dc, (q31_t)0x57f6e9, (q31_t)0x3ed4f2, (q31_t)0x25b2f8, + (q31_t)0xc90fe +}; + +static const q31_t cos_factorsQ31_8192[8192] = { + (q31_t)0x7ffffff6, (q31_t)0x7fffffa7, (q31_t)0x7fffff09, (q31_t)0x7ffffe1c, (q31_t)0x7ffffce1, (q31_t)0x7ffffb56, (q31_t)0x7ffff97c, (q31_t)0x7ffff753, + (q31_t)0x7ffff4dc, (q31_t)0x7ffff215, (q31_t)0x7fffef00, (q31_t)0x7fffeb9b, (q31_t)0x7fffe7e8, (q31_t)0x7fffe3e5, (q31_t)0x7fffdf94, (q31_t)0x7fffdaf3, + (q31_t)0x7fffd604, (q31_t)0x7fffd0c6, (q31_t)0x7fffcb39, (q31_t)0x7fffc55c, (q31_t)0x7fffbf31, (q31_t)0x7fffb8b7, (q31_t)0x7fffb1ee, (q31_t)0x7fffaad6, + (q31_t)0x7fffa36f, (q31_t)0x7fff9bb9, (q31_t)0x7fff93b4, (q31_t)0x7fff8b61, (q31_t)0x7fff82be, (q31_t)0x7fff79cc, (q31_t)0x7fff708b, (q31_t)0x7fff66fc, + (q31_t)0x7fff5d1d, (q31_t)0x7fff52ef, (q31_t)0x7fff4873, (q31_t)0x7fff3da8, (q31_t)0x7fff328d, (q31_t)0x7fff2724, (q31_t)0x7fff1b6b, (q31_t)0x7fff0f64, + (q31_t)0x7fff030e, (q31_t)0x7ffef669, (q31_t)0x7ffee975, (q31_t)0x7ffedc31, (q31_t)0x7ffece9f, (q31_t)0x7ffec0be, (q31_t)0x7ffeb28e, (q31_t)0x7ffea40f, + (q31_t)0x7ffe9542, (q31_t)0x7ffe8625, (q31_t)0x7ffe76b9, (q31_t)0x7ffe66fe, (q31_t)0x7ffe56f5, (q31_t)0x7ffe469c, (q31_t)0x7ffe35f4, (q31_t)0x7ffe24fe, + (q31_t)0x7ffe13b8, (q31_t)0x7ffe0224, (q31_t)0x7ffdf040, (q31_t)0x7ffdde0e, (q31_t)0x7ffdcb8d, (q31_t)0x7ffdb8bc, (q31_t)0x7ffda59d, (q31_t)0x7ffd922f, + (q31_t)0x7ffd7e72, (q31_t)0x7ffd6a66, (q31_t)0x7ffd560b, (q31_t)0x7ffd4161, (q31_t)0x7ffd2c68, (q31_t)0x7ffd1720, (q31_t)0x7ffd0189, (q31_t)0x7ffceba4, + (q31_t)0x7ffcd56f, (q31_t)0x7ffcbeeb, (q31_t)0x7ffca819, (q31_t)0x7ffc90f7, (q31_t)0x7ffc7987, (q31_t)0x7ffc61c7, (q31_t)0x7ffc49b9, (q31_t)0x7ffc315b, + (q31_t)0x7ffc18af, (q31_t)0x7ffbffb4, (q31_t)0x7ffbe66a, (q31_t)0x7ffbccd0, (q31_t)0x7ffbb2e8, (q31_t)0x7ffb98b1, (q31_t)0x7ffb7e2b, (q31_t)0x7ffb6356, + (q31_t)0x7ffb4833, (q31_t)0x7ffb2cc0, (q31_t)0x7ffb10fe, (q31_t)0x7ffaf4ed, (q31_t)0x7ffad88e, (q31_t)0x7ffabbdf, (q31_t)0x7ffa9ee2, (q31_t)0x7ffa8195, + (q31_t)0x7ffa63fa, (q31_t)0x7ffa460f, (q31_t)0x7ffa27d6, (q31_t)0x7ffa094e, (q31_t)0x7ff9ea76, (q31_t)0x7ff9cb50, (q31_t)0x7ff9abdb, (q31_t)0x7ff98c17, + (q31_t)0x7ff96c04, (q31_t)0x7ff94ba2, (q31_t)0x7ff92af1, (q31_t)0x7ff909f2, (q31_t)0x7ff8e8a3, (q31_t)0x7ff8c705, (q31_t)0x7ff8a519, (q31_t)0x7ff882dd, + (q31_t)0x7ff86053, (q31_t)0x7ff83d79, (q31_t)0x7ff81a51, (q31_t)0x7ff7f6da, (q31_t)0x7ff7d313, (q31_t)0x7ff7aefe, (q31_t)0x7ff78a9a, (q31_t)0x7ff765e7, + (q31_t)0x7ff740e5, (q31_t)0x7ff71b94, (q31_t)0x7ff6f5f4, (q31_t)0x7ff6d005, (q31_t)0x7ff6a9c8, (q31_t)0x7ff6833b, (q31_t)0x7ff65c5f, (q31_t)0x7ff63535, + (q31_t)0x7ff60dbb, (q31_t)0x7ff5e5f3, (q31_t)0x7ff5bddc, (q31_t)0x7ff59576, (q31_t)0x7ff56cc0, (q31_t)0x7ff543bc, (q31_t)0x7ff51a69, (q31_t)0x7ff4f0c7, + (q31_t)0x7ff4c6d6, (q31_t)0x7ff49c96, (q31_t)0x7ff47208, (q31_t)0x7ff4472a, (q31_t)0x7ff41bfd, (q31_t)0x7ff3f082, (q31_t)0x7ff3c4b7, (q31_t)0x7ff3989e, + (q31_t)0x7ff36c36, (q31_t)0x7ff33f7e, (q31_t)0x7ff31278, (q31_t)0x7ff2e523, (q31_t)0x7ff2b77f, (q31_t)0x7ff2898c, (q31_t)0x7ff25b4a, (q31_t)0x7ff22cb9, + (q31_t)0x7ff1fdd9, (q31_t)0x7ff1ceab, (q31_t)0x7ff19f2d, (q31_t)0x7ff16f61, (q31_t)0x7ff13f45, (q31_t)0x7ff10edb, (q31_t)0x7ff0de22, (q31_t)0x7ff0ad19, + (q31_t)0x7ff07bc2, (q31_t)0x7ff04a1c, (q31_t)0x7ff01827, (q31_t)0x7fefe5e4, (q31_t)0x7fefb351, (q31_t)0x7fef806f, (q31_t)0x7fef4d3e, (q31_t)0x7fef19bf, + (q31_t)0x7feee5f0, (q31_t)0x7feeb1d3, (q31_t)0x7fee7d67, (q31_t)0x7fee48ac, (q31_t)0x7fee13a1, (q31_t)0x7fedde48, (q31_t)0x7feda8a0, (q31_t)0x7fed72aa, + (q31_t)0x7fed3c64, (q31_t)0x7fed05cf, (q31_t)0x7fecceec, (q31_t)0x7fec97b9, (q31_t)0x7fec6038, (q31_t)0x7fec2867, (q31_t)0x7febf048, (q31_t)0x7febb7da, + (q31_t)0x7feb7f1d, (q31_t)0x7feb4611, (q31_t)0x7feb0cb6, (q31_t)0x7fead30c, (q31_t)0x7fea9914, (q31_t)0x7fea5ecc, (q31_t)0x7fea2436, (q31_t)0x7fe9e950, + (q31_t)0x7fe9ae1c, (q31_t)0x7fe97299, (q31_t)0x7fe936c7, (q31_t)0x7fe8faa6, (q31_t)0x7fe8be36, (q31_t)0x7fe88177, (q31_t)0x7fe84469, (q31_t)0x7fe8070d, + (q31_t)0x7fe7c961, (q31_t)0x7fe78b67, (q31_t)0x7fe74d1e, (q31_t)0x7fe70e85, (q31_t)0x7fe6cf9e, (q31_t)0x7fe69068, (q31_t)0x7fe650e3, (q31_t)0x7fe61110, + (q31_t)0x7fe5d0ed, (q31_t)0x7fe5907b, (q31_t)0x7fe54fbb, (q31_t)0x7fe50eac, (q31_t)0x7fe4cd4d, (q31_t)0x7fe48ba0, (q31_t)0x7fe449a4, (q31_t)0x7fe40759, + (q31_t)0x7fe3c4bf, (q31_t)0x7fe381d7, (q31_t)0x7fe33e9f, (q31_t)0x7fe2fb19, (q31_t)0x7fe2b743, (q31_t)0x7fe2731f, (q31_t)0x7fe22eac, (q31_t)0x7fe1e9ea, + (q31_t)0x7fe1a4d9, (q31_t)0x7fe15f79, (q31_t)0x7fe119cb, (q31_t)0x7fe0d3cd, (q31_t)0x7fe08d81, (q31_t)0x7fe046e5, (q31_t)0x7fdffffb, (q31_t)0x7fdfb8c2, + (q31_t)0x7fdf713a, (q31_t)0x7fdf2963, (q31_t)0x7fdee13e, (q31_t)0x7fde98c9, (q31_t)0x7fde5006, (q31_t)0x7fde06f3, (q31_t)0x7fddbd92, (q31_t)0x7fdd73e2, + (q31_t)0x7fdd29e3, (q31_t)0x7fdcdf95, (q31_t)0x7fdc94f9, (q31_t)0x7fdc4a0d, (q31_t)0x7fdbfed3, (q31_t)0x7fdbb349, (q31_t)0x7fdb6771, (q31_t)0x7fdb1b4a, + (q31_t)0x7fdaced4, (q31_t)0x7fda820f, (q31_t)0x7fda34fc, (q31_t)0x7fd9e799, (q31_t)0x7fd999e8, (q31_t)0x7fd94be8, (q31_t)0x7fd8fd98, (q31_t)0x7fd8aefa, + (q31_t)0x7fd8600e, (q31_t)0x7fd810d2, (q31_t)0x7fd7c147, (q31_t)0x7fd7716e, (q31_t)0x7fd72146, (q31_t)0x7fd6d0cf, (q31_t)0x7fd68009, (q31_t)0x7fd62ef4, + (q31_t)0x7fd5dd90, (q31_t)0x7fd58bdd, (q31_t)0x7fd539dc, (q31_t)0x7fd4e78c, (q31_t)0x7fd494ed, (q31_t)0x7fd441ff, (q31_t)0x7fd3eec2, (q31_t)0x7fd39b36, + (q31_t)0x7fd3475c, (q31_t)0x7fd2f332, (q31_t)0x7fd29eba, (q31_t)0x7fd249f3, (q31_t)0x7fd1f4dd, (q31_t)0x7fd19f78, (q31_t)0x7fd149c5, (q31_t)0x7fd0f3c2, + (q31_t)0x7fd09d71, (q31_t)0x7fd046d1, (q31_t)0x7fcfefe2, (q31_t)0x7fcf98a4, (q31_t)0x7fcf4117, (q31_t)0x7fcee93c, (q31_t)0x7fce9112, (q31_t)0x7fce3898, + (q31_t)0x7fcddfd0, (q31_t)0x7fcd86b9, (q31_t)0x7fcd2d54, (q31_t)0x7fccd39f, (q31_t)0x7fcc799c, (q31_t)0x7fcc1f4a, (q31_t)0x7fcbc4a9, (q31_t)0x7fcb69b9, + (q31_t)0x7fcb0e7a, (q31_t)0x7fcab2ed, (q31_t)0x7fca5710, (q31_t)0x7fc9fae5, (q31_t)0x7fc99e6b, (q31_t)0x7fc941a2, (q31_t)0x7fc8e48b, (q31_t)0x7fc88724, + (q31_t)0x7fc8296f, (q31_t)0x7fc7cb6b, (q31_t)0x7fc76d18, (q31_t)0x7fc70e76, (q31_t)0x7fc6af86, (q31_t)0x7fc65046, (q31_t)0x7fc5f0b8, (q31_t)0x7fc590db, + (q31_t)0x7fc530af, (q31_t)0x7fc4d035, (q31_t)0x7fc46f6b, (q31_t)0x7fc40e53, (q31_t)0x7fc3acec, (q31_t)0x7fc34b36, (q31_t)0x7fc2e931, (q31_t)0x7fc286de, + (q31_t)0x7fc2243b, (q31_t)0x7fc1c14a, (q31_t)0x7fc15e0a, (q31_t)0x7fc0fa7b, (q31_t)0x7fc0969e, (q31_t)0x7fc03271, (q31_t)0x7fbfcdf6, (q31_t)0x7fbf692c, + (q31_t)0x7fbf0414, (q31_t)0x7fbe9eac, (q31_t)0x7fbe38f6, (q31_t)0x7fbdd2f0, (q31_t)0x7fbd6c9c, (q31_t)0x7fbd05fa, (q31_t)0x7fbc9f08, (q31_t)0x7fbc37c8, + (q31_t)0x7fbbd039, (q31_t)0x7fbb685b, (q31_t)0x7fbb002e, (q31_t)0x7fba97b2, (q31_t)0x7fba2ee8, (q31_t)0x7fb9c5cf, (q31_t)0x7fb95c67, (q31_t)0x7fb8f2b0, + (q31_t)0x7fb888ab, (q31_t)0x7fb81e57, (q31_t)0x7fb7b3b4, (q31_t)0x7fb748c2, (q31_t)0x7fb6dd81, (q31_t)0x7fb671f2, (q31_t)0x7fb60614, (q31_t)0x7fb599e7, + (q31_t)0x7fb52d6b, (q31_t)0x7fb4c0a1, (q31_t)0x7fb45387, (q31_t)0x7fb3e61f, (q31_t)0x7fb37869, (q31_t)0x7fb30a63, (q31_t)0x7fb29c0f, (q31_t)0x7fb22d6c, + (q31_t)0x7fb1be7a, (q31_t)0x7fb14f39, (q31_t)0x7fb0dfaa, (q31_t)0x7fb06fcb, (q31_t)0x7fafff9e, (q31_t)0x7faf8f23, (q31_t)0x7faf1e58, (q31_t)0x7faead3f, + (q31_t)0x7fae3bd7, (q31_t)0x7fadca20, (q31_t)0x7fad581b, (q31_t)0x7face5c6, (q31_t)0x7fac7323, (q31_t)0x7fac0031, (q31_t)0x7fab8cf1, (q31_t)0x7fab1962, + (q31_t)0x7faaa584, (q31_t)0x7faa3157, (q31_t)0x7fa9bcdb, (q31_t)0x7fa94811, (q31_t)0x7fa8d2f8, (q31_t)0x7fa85d90, (q31_t)0x7fa7e7d9, (q31_t)0x7fa771d4, + (q31_t)0x7fa6fb80, (q31_t)0x7fa684dd, (q31_t)0x7fa60dec, (q31_t)0x7fa596ac, (q31_t)0x7fa51f1d, (q31_t)0x7fa4a73f, (q31_t)0x7fa42f12, (q31_t)0x7fa3b697, + (q31_t)0x7fa33dcd, (q31_t)0x7fa2c4b5, (q31_t)0x7fa24b4d, (q31_t)0x7fa1d197, (q31_t)0x7fa15792, (q31_t)0x7fa0dd3f, (q31_t)0x7fa0629c, (q31_t)0x7f9fe7ab, + (q31_t)0x7f9f6c6b, (q31_t)0x7f9ef0dd, (q31_t)0x7f9e7500, (q31_t)0x7f9df8d4, (q31_t)0x7f9d7c59, (q31_t)0x7f9cff90, (q31_t)0x7f9c8278, (q31_t)0x7f9c0511, + (q31_t)0x7f9b875b, (q31_t)0x7f9b0957, (q31_t)0x7f9a8b04, (q31_t)0x7f9a0c62, (q31_t)0x7f998d72, (q31_t)0x7f990e33, (q31_t)0x7f988ea5, (q31_t)0x7f980ec8, + (q31_t)0x7f978e9d, (q31_t)0x7f970e23, (q31_t)0x7f968d5b, (q31_t)0x7f960c43, (q31_t)0x7f958add, (q31_t)0x7f950929, (q31_t)0x7f948725, (q31_t)0x7f9404d3, + (q31_t)0x7f938232, (q31_t)0x7f92ff43, (q31_t)0x7f927c04, (q31_t)0x7f91f878, (q31_t)0x7f91749c, (q31_t)0x7f90f072, (q31_t)0x7f906bf9, (q31_t)0x7f8fe731, + (q31_t)0x7f8f621b, (q31_t)0x7f8edcb6, (q31_t)0x7f8e5702, (q31_t)0x7f8dd0ff, (q31_t)0x7f8d4aae, (q31_t)0x7f8cc40f, (q31_t)0x7f8c3d20, (q31_t)0x7f8bb5e3, + (q31_t)0x7f8b2e57, (q31_t)0x7f8aa67d, (q31_t)0x7f8a1e54, (q31_t)0x7f8995dc, (q31_t)0x7f890d15, (q31_t)0x7f888400, (q31_t)0x7f87fa9c, (q31_t)0x7f8770ea, + (q31_t)0x7f86e6e9, (q31_t)0x7f865c99, (q31_t)0x7f85d1fa, (q31_t)0x7f85470d, (q31_t)0x7f84bbd1, (q31_t)0x7f843047, (q31_t)0x7f83a46e, (q31_t)0x7f831846, + (q31_t)0x7f828bcf, (q31_t)0x7f81ff0a, (q31_t)0x7f8171f6, (q31_t)0x7f80e494, (q31_t)0x7f8056e3, (q31_t)0x7f7fc8e3, (q31_t)0x7f7f3a95, (q31_t)0x7f7eabf8, + (q31_t)0x7f7e1d0c, (q31_t)0x7f7d8dd2, (q31_t)0x7f7cfe49, (q31_t)0x7f7c6e71, (q31_t)0x7f7bde4b, (q31_t)0x7f7b4dd6, (q31_t)0x7f7abd13, (q31_t)0x7f7a2c01, + (q31_t)0x7f799aa0, (q31_t)0x7f7908f0, (q31_t)0x7f7876f2, (q31_t)0x7f77e4a6, (q31_t)0x7f77520a, (q31_t)0x7f76bf21, (q31_t)0x7f762be8, (q31_t)0x7f759861, + (q31_t)0x7f75048b, (q31_t)0x7f747067, (q31_t)0x7f73dbf4, (q31_t)0x7f734732, (q31_t)0x7f72b222, (q31_t)0x7f721cc3, (q31_t)0x7f718715, (q31_t)0x7f70f119, + (q31_t)0x7f705ace, (q31_t)0x7f6fc435, (q31_t)0x7f6f2d4d, (q31_t)0x7f6e9617, (q31_t)0x7f6dfe91, (q31_t)0x7f6d66be, (q31_t)0x7f6cce9b, (q31_t)0x7f6c362a, + (q31_t)0x7f6b9d6b, (q31_t)0x7f6b045d, (q31_t)0x7f6a6b00, (q31_t)0x7f69d154, (q31_t)0x7f69375a, (q31_t)0x7f689d12, (q31_t)0x7f68027b, (q31_t)0x7f676795, + (q31_t)0x7f66cc61, (q31_t)0x7f6630de, (q31_t)0x7f65950c, (q31_t)0x7f64f8ec, (q31_t)0x7f645c7d, (q31_t)0x7f63bfc0, (q31_t)0x7f6322b4, (q31_t)0x7f62855a, + (q31_t)0x7f61e7b1, (q31_t)0x7f6149b9, (q31_t)0x7f60ab73, (q31_t)0x7f600cdf, (q31_t)0x7f5f6dfb, (q31_t)0x7f5ecec9, (q31_t)0x7f5e2f49, (q31_t)0x7f5d8f7a, + (q31_t)0x7f5cef5c, (q31_t)0x7f5c4ef0, (q31_t)0x7f5bae36, (q31_t)0x7f5b0d2c, (q31_t)0x7f5a6bd5, (q31_t)0x7f59ca2e, (q31_t)0x7f592839, (q31_t)0x7f5885f6, + (q31_t)0x7f57e364, (q31_t)0x7f574083, (q31_t)0x7f569d54, (q31_t)0x7f55f9d6, (q31_t)0x7f55560a, (q31_t)0x7f54b1ef, (q31_t)0x7f540d86, (q31_t)0x7f5368ce, + (q31_t)0x7f52c3c8, (q31_t)0x7f521e73, (q31_t)0x7f5178cf, (q31_t)0x7f50d2dd, (q31_t)0x7f502c9d, (q31_t)0x7f4f860e, (q31_t)0x7f4edf30, (q31_t)0x7f4e3804, + (q31_t)0x7f4d9089, (q31_t)0x7f4ce8c0, (q31_t)0x7f4c40a8, (q31_t)0x7f4b9842, (q31_t)0x7f4aef8d, (q31_t)0x7f4a468a, (q31_t)0x7f499d38, (q31_t)0x7f48f398, + (q31_t)0x7f4849a9, (q31_t)0x7f479f6c, (q31_t)0x7f46f4e0, (q31_t)0x7f464a06, (q31_t)0x7f459edd, (q31_t)0x7f44f365, (q31_t)0x7f44479f, (q31_t)0x7f439b8b, + (q31_t)0x7f42ef28, (q31_t)0x7f424277, (q31_t)0x7f419577, (q31_t)0x7f40e828, (q31_t)0x7f403a8b, (q31_t)0x7f3f8ca0, (q31_t)0x7f3ede66, (q31_t)0x7f3e2fde, + (q31_t)0x7f3d8107, (q31_t)0x7f3cd1e2, (q31_t)0x7f3c226e, (q31_t)0x7f3b72ab, (q31_t)0x7f3ac29b, (q31_t)0x7f3a123b, (q31_t)0x7f39618e, (q31_t)0x7f38b091, + (q31_t)0x7f37ff47, (q31_t)0x7f374dad, (q31_t)0x7f369bc6, (q31_t)0x7f35e990, (q31_t)0x7f35370b, (q31_t)0x7f348438, (q31_t)0x7f33d116, (q31_t)0x7f331da6, + (q31_t)0x7f3269e8, (q31_t)0x7f31b5db, (q31_t)0x7f31017f, (q31_t)0x7f304cd6, (q31_t)0x7f2f97dd, (q31_t)0x7f2ee296, (q31_t)0x7f2e2d01, (q31_t)0x7f2d771e, + (q31_t)0x7f2cc0eb, (q31_t)0x7f2c0a6b, (q31_t)0x7f2b539c, (q31_t)0x7f2a9c7e, (q31_t)0x7f29e512, (q31_t)0x7f292d58, (q31_t)0x7f28754f, (q31_t)0x7f27bcf8, + (q31_t)0x7f270452, (q31_t)0x7f264b5e, (q31_t)0x7f25921c, (q31_t)0x7f24d88b, (q31_t)0x7f241eab, (q31_t)0x7f23647e, (q31_t)0x7f22aa01, (q31_t)0x7f21ef37, + (q31_t)0x7f21341e, (q31_t)0x7f2078b6, (q31_t)0x7f1fbd00, (q31_t)0x7f1f00fc, (q31_t)0x7f1e44a9, (q31_t)0x7f1d8808, (q31_t)0x7f1ccb18, (q31_t)0x7f1c0dda, + (q31_t)0x7f1b504e, (q31_t)0x7f1a9273, (q31_t)0x7f19d44a, (q31_t)0x7f1915d2, (q31_t)0x7f18570c, (q31_t)0x7f1797f8, (q31_t)0x7f16d895, (q31_t)0x7f1618e4, + (q31_t)0x7f1558e4, (q31_t)0x7f149896, (q31_t)0x7f13d7fa, (q31_t)0x7f13170f, (q31_t)0x7f1255d6, (q31_t)0x7f11944f, (q31_t)0x7f10d279, (q31_t)0x7f101054, + (q31_t)0x7f0f4de2, (q31_t)0x7f0e8b21, (q31_t)0x7f0dc811, (q31_t)0x7f0d04b3, (q31_t)0x7f0c4107, (q31_t)0x7f0b7d0d, (q31_t)0x7f0ab8c4, (q31_t)0x7f09f42d, + (q31_t)0x7f092f47, (q31_t)0x7f086a13, (q31_t)0x7f07a491, (q31_t)0x7f06dec0, (q31_t)0x7f0618a1, (q31_t)0x7f055233, (q31_t)0x7f048b78, (q31_t)0x7f03c46d, + (q31_t)0x7f02fd15, (q31_t)0x7f02356e, (q31_t)0x7f016d79, (q31_t)0x7f00a535, (q31_t)0x7effdca4, (q31_t)0x7eff13c3, (q31_t)0x7efe4a95, (q31_t)0x7efd8118, + (q31_t)0x7efcb74d, (q31_t)0x7efbed33, (q31_t)0x7efb22cb, (q31_t)0x7efa5815, (q31_t)0x7ef98d11, (q31_t)0x7ef8c1be, (q31_t)0x7ef7f61d, (q31_t)0x7ef72a2d, + (q31_t)0x7ef65def, (q31_t)0x7ef59163, (q31_t)0x7ef4c489, (q31_t)0x7ef3f760, (q31_t)0x7ef329e9, (q31_t)0x7ef25c24, (q31_t)0x7ef18e10, (q31_t)0x7ef0bfae, + (q31_t)0x7eeff0fe, (q31_t)0x7eef21ff, (q31_t)0x7eee52b2, (q31_t)0x7eed8317, (q31_t)0x7eecb32d, (q31_t)0x7eebe2f6, (q31_t)0x7eeb1270, (q31_t)0x7eea419b, + (q31_t)0x7ee97079, (q31_t)0x7ee89f08, (q31_t)0x7ee7cd49, (q31_t)0x7ee6fb3b, (q31_t)0x7ee628df, (q31_t)0x7ee55635, (q31_t)0x7ee4833d, (q31_t)0x7ee3aff6, + (q31_t)0x7ee2dc61, (q31_t)0x7ee2087e, (q31_t)0x7ee1344d, (q31_t)0x7ee05fcd, (q31_t)0x7edf8aff, (q31_t)0x7edeb5e3, (q31_t)0x7edde079, (q31_t)0x7edd0ac0, + (q31_t)0x7edc34b9, (q31_t)0x7edb5e64, (q31_t)0x7eda87c0, (q31_t)0x7ed9b0ce, (q31_t)0x7ed8d98e, (q31_t)0x7ed80200, (q31_t)0x7ed72a24, (q31_t)0x7ed651f9, + (q31_t)0x7ed57980, (q31_t)0x7ed4a0b9, (q31_t)0x7ed3c7a3, (q31_t)0x7ed2ee40, (q31_t)0x7ed2148e, (q31_t)0x7ed13a8e, (q31_t)0x7ed0603f, (q31_t)0x7ecf85a3, + (q31_t)0x7eceaab8, (q31_t)0x7ecdcf7f, (q31_t)0x7eccf3f8, (q31_t)0x7ecc1822, (q31_t)0x7ecb3bff, (q31_t)0x7eca5f8d, (q31_t)0x7ec982cd, (q31_t)0x7ec8a5bf, + (q31_t)0x7ec7c862, (q31_t)0x7ec6eab7, (q31_t)0x7ec60cbe, (q31_t)0x7ec52e77, (q31_t)0x7ec44fe2, (q31_t)0x7ec370fe, (q31_t)0x7ec291cd, (q31_t)0x7ec1b24d, + (q31_t)0x7ec0d27f, (q31_t)0x7ebff263, (q31_t)0x7ebf11f8, (q31_t)0x7ebe313f, (q31_t)0x7ebd5039, (q31_t)0x7ebc6ee4, (q31_t)0x7ebb8d40, (q31_t)0x7ebaab4f, + (q31_t)0x7eb9c910, (q31_t)0x7eb8e682, (q31_t)0x7eb803a6, (q31_t)0x7eb7207c, (q31_t)0x7eb63d04, (q31_t)0x7eb5593d, (q31_t)0x7eb47529, (q31_t)0x7eb390c6, + (q31_t)0x7eb2ac15, (q31_t)0x7eb1c716, (q31_t)0x7eb0e1c9, (q31_t)0x7eaffc2e, (q31_t)0x7eaf1645, (q31_t)0x7eae300d, (q31_t)0x7ead4987, (q31_t)0x7eac62b3, + (q31_t)0x7eab7b91, (q31_t)0x7eaa9421, (q31_t)0x7ea9ac63, (q31_t)0x7ea8c457, (q31_t)0x7ea7dbfc, (q31_t)0x7ea6f353, (q31_t)0x7ea60a5d, (q31_t)0x7ea52118, + (q31_t)0x7ea43785, (q31_t)0x7ea34da4, (q31_t)0x7ea26374, (q31_t)0x7ea178f7, (q31_t)0x7ea08e2b, (q31_t)0x7e9fa312, (q31_t)0x7e9eb7aa, (q31_t)0x7e9dcbf4, + (q31_t)0x7e9cdff0, (q31_t)0x7e9bf39e, (q31_t)0x7e9b06fe, (q31_t)0x7e9a1a10, (q31_t)0x7e992cd4, (q31_t)0x7e983f49, (q31_t)0x7e975171, (q31_t)0x7e96634a, + (q31_t)0x7e9574d6, (q31_t)0x7e948613, (q31_t)0x7e939702, (q31_t)0x7e92a7a3, (q31_t)0x7e91b7f6, (q31_t)0x7e90c7fb, (q31_t)0x7e8fd7b2, (q31_t)0x7e8ee71b, + (q31_t)0x7e8df636, (q31_t)0x7e8d0502, (q31_t)0x7e8c1381, (q31_t)0x7e8b21b1, (q31_t)0x7e8a2f94, (q31_t)0x7e893d28, (q31_t)0x7e884a6f, (q31_t)0x7e875767, + (q31_t)0x7e866411, (q31_t)0x7e85706d, (q31_t)0x7e847c7c, (q31_t)0x7e83883c, (q31_t)0x7e8293ae, (q31_t)0x7e819ed2, (q31_t)0x7e80a9a8, (q31_t)0x7e7fb430, + (q31_t)0x7e7ebe6a, (q31_t)0x7e7dc856, (q31_t)0x7e7cd1f4, (q31_t)0x7e7bdb44, (q31_t)0x7e7ae446, (q31_t)0x7e79ecf9, (q31_t)0x7e78f55f, (q31_t)0x7e77fd77, + (q31_t)0x7e770541, (q31_t)0x7e760cbd, (q31_t)0x7e7513ea, (q31_t)0x7e741aca, (q31_t)0x7e73215c, (q31_t)0x7e7227a0, (q31_t)0x7e712d96, (q31_t)0x7e70333d, + (q31_t)0x7e6f3897, (q31_t)0x7e6e3da3, (q31_t)0x7e6d4261, (q31_t)0x7e6c46d1, (q31_t)0x7e6b4af2, (q31_t)0x7e6a4ec6, (q31_t)0x7e69524c, (q31_t)0x7e685584, + (q31_t)0x7e67586e, (q31_t)0x7e665b0a, (q31_t)0x7e655d58, (q31_t)0x7e645f58, (q31_t)0x7e63610a, (q31_t)0x7e62626e, (q31_t)0x7e616384, (q31_t)0x7e60644c, + (q31_t)0x7e5f64c7, (q31_t)0x7e5e64f3, (q31_t)0x7e5d64d1, (q31_t)0x7e5c6461, (q31_t)0x7e5b63a4, (q31_t)0x7e5a6298, (q31_t)0x7e59613f, (q31_t)0x7e585f97, + (q31_t)0x7e575da2, (q31_t)0x7e565b5f, (q31_t)0x7e5558ce, (q31_t)0x7e5455ef, (q31_t)0x7e5352c1, (q31_t)0x7e524f46, (q31_t)0x7e514b7e, (q31_t)0x7e504767, + (q31_t)0x7e4f4302, (q31_t)0x7e4e3e4f, (q31_t)0x7e4d394f, (q31_t)0x7e4c3400, (q31_t)0x7e4b2e64, (q31_t)0x7e4a287a, (q31_t)0x7e492241, (q31_t)0x7e481bbb, + (q31_t)0x7e4714e7, (q31_t)0x7e460dc5, (q31_t)0x7e450656, (q31_t)0x7e43fe98, (q31_t)0x7e42f68c, (q31_t)0x7e41ee33, (q31_t)0x7e40e58c, (q31_t)0x7e3fdc97, + (q31_t)0x7e3ed353, (q31_t)0x7e3dc9c3, (q31_t)0x7e3cbfe4, (q31_t)0x7e3bb5b7, (q31_t)0x7e3aab3c, (q31_t)0x7e39a074, (q31_t)0x7e38955e, (q31_t)0x7e3789fa, + (q31_t)0x7e367e48, (q31_t)0x7e357248, (q31_t)0x7e3465fa, (q31_t)0x7e33595e, (q31_t)0x7e324c75, (q31_t)0x7e313f3e, (q31_t)0x7e3031b9, (q31_t)0x7e2f23e6, + (q31_t)0x7e2e15c5, (q31_t)0x7e2d0756, (q31_t)0x7e2bf89a, (q31_t)0x7e2ae990, (q31_t)0x7e29da38, (q31_t)0x7e28ca92, (q31_t)0x7e27ba9e, (q31_t)0x7e26aa5d, + (q31_t)0x7e2599cd, (q31_t)0x7e2488f0, (q31_t)0x7e2377c5, (q31_t)0x7e22664c, (q31_t)0x7e215486, (q31_t)0x7e204271, (q31_t)0x7e1f300f, (q31_t)0x7e1e1d5f, + (q31_t)0x7e1d0a61, (q31_t)0x7e1bf716, (q31_t)0x7e1ae37c, (q31_t)0x7e19cf95, (q31_t)0x7e18bb60, (q31_t)0x7e17a6dd, (q31_t)0x7e16920d, (q31_t)0x7e157cee, + (q31_t)0x7e146782, (q31_t)0x7e1351c9, (q31_t)0x7e123bc1, (q31_t)0x7e11256c, (q31_t)0x7e100ec8, (q31_t)0x7e0ef7d7, (q31_t)0x7e0de099, (q31_t)0x7e0cc90c, + (q31_t)0x7e0bb132, (q31_t)0x7e0a990a, (q31_t)0x7e098095, (q31_t)0x7e0867d1, (q31_t)0x7e074ec0, (q31_t)0x7e063561, (q31_t)0x7e051bb4, (q31_t)0x7e0401ba, + (q31_t)0x7e02e772, (q31_t)0x7e01ccdc, (q31_t)0x7e00b1f9, (q31_t)0x7dff96c7, (q31_t)0x7dfe7b48, (q31_t)0x7dfd5f7b, (q31_t)0x7dfc4361, (q31_t)0x7dfb26f9, + (q31_t)0x7dfa0a43, (q31_t)0x7df8ed3f, (q31_t)0x7df7cfee, (q31_t)0x7df6b24f, (q31_t)0x7df59462, (q31_t)0x7df47628, (q31_t)0x7df357a0, (q31_t)0x7df238ca, + (q31_t)0x7df119a7, (q31_t)0x7deffa35, (q31_t)0x7deeda77, (q31_t)0x7dedba6a, (q31_t)0x7dec9a10, (q31_t)0x7deb7968, (q31_t)0x7dea5872, (q31_t)0x7de9372f, + (q31_t)0x7de8159e, (q31_t)0x7de6f3c0, (q31_t)0x7de5d193, (q31_t)0x7de4af1a, (q31_t)0x7de38c52, (q31_t)0x7de2693d, (q31_t)0x7de145da, (q31_t)0x7de02229, + (q31_t)0x7ddefe2b, (q31_t)0x7dddd9e0, (q31_t)0x7ddcb546, (q31_t)0x7ddb905f, (q31_t)0x7dda6b2a, (q31_t)0x7dd945a8, (q31_t)0x7dd81fd8, (q31_t)0x7dd6f9ba, + (q31_t)0x7dd5d34f, (q31_t)0x7dd4ac96, (q31_t)0x7dd38590, (q31_t)0x7dd25e3c, (q31_t)0x7dd1369a, (q31_t)0x7dd00eab, (q31_t)0x7dcee66e, (q31_t)0x7dcdbde3, + (q31_t)0x7dcc950b, (q31_t)0x7dcb6be6, (q31_t)0x7dca4272, (q31_t)0x7dc918b1, (q31_t)0x7dc7eea3, (q31_t)0x7dc6c447, (q31_t)0x7dc5999d, (q31_t)0x7dc46ea6, + (q31_t)0x7dc34361, (q31_t)0x7dc217cf, (q31_t)0x7dc0ebef, (q31_t)0x7dbfbfc1, (q31_t)0x7dbe9346, (q31_t)0x7dbd667d, (q31_t)0x7dbc3967, (q31_t)0x7dbb0c03, + (q31_t)0x7db9de52, (q31_t)0x7db8b053, (q31_t)0x7db78207, (q31_t)0x7db6536d, (q31_t)0x7db52485, (q31_t)0x7db3f550, (q31_t)0x7db2c5cd, (q31_t)0x7db195fd, + (q31_t)0x7db065df, (q31_t)0x7daf3574, (q31_t)0x7dae04bb, (q31_t)0x7dacd3b5, (q31_t)0x7daba261, (q31_t)0x7daa70c0, (q31_t)0x7da93ed1, (q31_t)0x7da80c95, + (q31_t)0x7da6da0b, (q31_t)0x7da5a733, (q31_t)0x7da4740e, (q31_t)0x7da3409c, (q31_t)0x7da20cdc, (q31_t)0x7da0d8cf, (q31_t)0x7d9fa474, (q31_t)0x7d9e6fcb, + (q31_t)0x7d9d3ad6, (q31_t)0x7d9c0592, (q31_t)0x7d9ad001, (q31_t)0x7d999a23, (q31_t)0x7d9863f7, (q31_t)0x7d972d7e, (q31_t)0x7d95f6b7, (q31_t)0x7d94bfa3, + (q31_t)0x7d938841, (q31_t)0x7d925092, (q31_t)0x7d911896, (q31_t)0x7d8fe04c, (q31_t)0x7d8ea7b4, (q31_t)0x7d8d6ecf, (q31_t)0x7d8c359d, (q31_t)0x7d8afc1d, + (q31_t)0x7d89c250, (q31_t)0x7d888835, (q31_t)0x7d874dcd, (q31_t)0x7d861317, (q31_t)0x7d84d814, (q31_t)0x7d839cc4, (q31_t)0x7d826126, (q31_t)0x7d81253a, + (q31_t)0x7d7fe902, (q31_t)0x7d7eac7c, (q31_t)0x7d7d6fa8, (q31_t)0x7d7c3287, (q31_t)0x7d7af519, (q31_t)0x7d79b75d, (q31_t)0x7d787954, (q31_t)0x7d773afd, + (q31_t)0x7d75fc59, (q31_t)0x7d74bd68, (q31_t)0x7d737e29, (q31_t)0x7d723e9d, (q31_t)0x7d70fec4, (q31_t)0x7d6fbe9d, (q31_t)0x7d6e7e29, (q31_t)0x7d6d3d67, + (q31_t)0x7d6bfc58, (q31_t)0x7d6abafc, (q31_t)0x7d697952, (q31_t)0x7d68375b, (q31_t)0x7d66f517, (q31_t)0x7d65b285, (q31_t)0x7d646fa6, (q31_t)0x7d632c79, + (q31_t)0x7d61e8ff, (q31_t)0x7d60a538, (q31_t)0x7d5f6124, (q31_t)0x7d5e1cc2, (q31_t)0x7d5cd813, (q31_t)0x7d5b9316, (q31_t)0x7d5a4dcc, (q31_t)0x7d590835, + (q31_t)0x7d57c251, (q31_t)0x7d567c1f, (q31_t)0x7d5535a0, (q31_t)0x7d53eed3, (q31_t)0x7d52a7ba, (q31_t)0x7d516053, (q31_t)0x7d50189e, (q31_t)0x7d4ed09d, + (q31_t)0x7d4d884e, (q31_t)0x7d4c3fb1, (q31_t)0x7d4af6c8, (q31_t)0x7d49ad91, (q31_t)0x7d48640d, (q31_t)0x7d471a3c, (q31_t)0x7d45d01d, (q31_t)0x7d4485b1, + (q31_t)0x7d433af8, (q31_t)0x7d41eff1, (q31_t)0x7d40a49e, (q31_t)0x7d3f58fd, (q31_t)0x7d3e0d0e, (q31_t)0x7d3cc0d3, (q31_t)0x7d3b744a, (q31_t)0x7d3a2774, + (q31_t)0x7d38da51, (q31_t)0x7d378ce0, (q31_t)0x7d363f23, (q31_t)0x7d34f118, (q31_t)0x7d33a2bf, (q31_t)0x7d32541a, (q31_t)0x7d310527, (q31_t)0x7d2fb5e7, + (q31_t)0x7d2e665a, (q31_t)0x7d2d1680, (q31_t)0x7d2bc659, (q31_t)0x7d2a75e4, (q31_t)0x7d292522, (q31_t)0x7d27d413, (q31_t)0x7d2682b6, (q31_t)0x7d25310d, + (q31_t)0x7d23df16, (q31_t)0x7d228cd2, (q31_t)0x7d213a41, (q31_t)0x7d1fe762, (q31_t)0x7d1e9437, (q31_t)0x7d1d40be, (q31_t)0x7d1becf8, (q31_t)0x7d1a98e5, + (q31_t)0x7d194485, (q31_t)0x7d17efd8, (q31_t)0x7d169add, (q31_t)0x7d154595, (q31_t)0x7d13f001, (q31_t)0x7d129a1f, (q31_t)0x7d1143ef, (q31_t)0x7d0fed73, + (q31_t)0x7d0e96aa, (q31_t)0x7d0d3f93, (q31_t)0x7d0be82f, (q31_t)0x7d0a907e, (q31_t)0x7d093880, (q31_t)0x7d07e035, (q31_t)0x7d06879d, (q31_t)0x7d052eb8, + (q31_t)0x7d03d585, (q31_t)0x7d027c05, (q31_t)0x7d012239, (q31_t)0x7cffc81f, (q31_t)0x7cfe6db8, (q31_t)0x7cfd1304, (q31_t)0x7cfbb803, (q31_t)0x7cfa5cb4, + (q31_t)0x7cf90119, (q31_t)0x7cf7a531, (q31_t)0x7cf648fb, (q31_t)0x7cf4ec79, (q31_t)0x7cf38fa9, (q31_t)0x7cf2328c, (q31_t)0x7cf0d522, (q31_t)0x7cef776b, + (q31_t)0x7cee1967, (q31_t)0x7cecbb16, (q31_t)0x7ceb5c78, (q31_t)0x7ce9fd8d, (q31_t)0x7ce89e55, (q31_t)0x7ce73ed0, (q31_t)0x7ce5defd, (q31_t)0x7ce47ede, + (q31_t)0x7ce31e72, (q31_t)0x7ce1bdb8, (q31_t)0x7ce05cb2, (q31_t)0x7cdefb5e, (q31_t)0x7cdd99be, (q31_t)0x7cdc37d0, (q31_t)0x7cdad596, (q31_t)0x7cd9730e, + (q31_t)0x7cd8103a, (q31_t)0x7cd6ad18, (q31_t)0x7cd549aa, (q31_t)0x7cd3e5ee, (q31_t)0x7cd281e5, (q31_t)0x7cd11d90, (q31_t)0x7ccfb8ed, (q31_t)0x7cce53fe, + (q31_t)0x7ccceec1, (q31_t)0x7ccb8937, (q31_t)0x7cca2361, (q31_t)0x7cc8bd3d, (q31_t)0x7cc756cd, (q31_t)0x7cc5f010, (q31_t)0x7cc48905, (q31_t)0x7cc321ae, + (q31_t)0x7cc1ba09, (q31_t)0x7cc05218, (q31_t)0x7cbee9da, (q31_t)0x7cbd814f, (q31_t)0x7cbc1877, (q31_t)0x7cbaaf51, (q31_t)0x7cb945df, (q31_t)0x7cb7dc20, + (q31_t)0x7cb67215, (q31_t)0x7cb507bc, (q31_t)0x7cb39d16, (q31_t)0x7cb23223, (q31_t)0x7cb0c6e4, (q31_t)0x7caf5b57, (q31_t)0x7cadef7e, (q31_t)0x7cac8358, + (q31_t)0x7cab16e4, (q31_t)0x7ca9aa24, (q31_t)0x7ca83d17, (q31_t)0x7ca6cfbd, (q31_t)0x7ca56216, (q31_t)0x7ca3f423, (q31_t)0x7ca285e2, (q31_t)0x7ca11755, + (q31_t)0x7c9fa87a, (q31_t)0x7c9e3953, (q31_t)0x7c9cc9df, (q31_t)0x7c9b5a1e, (q31_t)0x7c99ea10, (q31_t)0x7c9879b6, (q31_t)0x7c97090e, (q31_t)0x7c95981a, + (q31_t)0x7c9426d8, (q31_t)0x7c92b54a, (q31_t)0x7c91436f, (q31_t)0x7c8fd148, (q31_t)0x7c8e5ed3, (q31_t)0x7c8cec12, (q31_t)0x7c8b7903, (q31_t)0x7c8a05a8, + (q31_t)0x7c889200, (q31_t)0x7c871e0c, (q31_t)0x7c85a9ca, (q31_t)0x7c84353c, (q31_t)0x7c82c060, (q31_t)0x7c814b39, (q31_t)0x7c7fd5c4, (q31_t)0x7c7e6002, + (q31_t)0x7c7ce9f4, (q31_t)0x7c7b7399, (q31_t)0x7c79fcf1, (q31_t)0x7c7885fc, (q31_t)0x7c770eba, (q31_t)0x7c75972c, (q31_t)0x7c741f51, (q31_t)0x7c72a729, + (q31_t)0x7c712eb5, (q31_t)0x7c6fb5f3, (q31_t)0x7c6e3ce5, (q31_t)0x7c6cc38a, (q31_t)0x7c6b49e3, (q31_t)0x7c69cfee, (q31_t)0x7c6855ad, (q31_t)0x7c66db1f, + (q31_t)0x7c656045, (q31_t)0x7c63e51e, (q31_t)0x7c6269aa, (q31_t)0x7c60ede9, (q31_t)0x7c5f71db, (q31_t)0x7c5df581, (q31_t)0x7c5c78da, (q31_t)0x7c5afbe6, + (q31_t)0x7c597ea6, (q31_t)0x7c580119, (q31_t)0x7c56833f, (q31_t)0x7c550519, (q31_t)0x7c5386a6, (q31_t)0x7c5207e6, (q31_t)0x7c5088d9, (q31_t)0x7c4f0980, + (q31_t)0x7c4d89da, (q31_t)0x7c4c09e8, (q31_t)0x7c4a89a8, (q31_t)0x7c49091c, (q31_t)0x7c478844, (q31_t)0x7c46071f, (q31_t)0x7c4485ad, (q31_t)0x7c4303ee, + (q31_t)0x7c4181e3, (q31_t)0x7c3fff8b, (q31_t)0x7c3e7ce7, (q31_t)0x7c3cf9f5, (q31_t)0x7c3b76b8, (q31_t)0x7c39f32d, (q31_t)0x7c386f56, (q31_t)0x7c36eb33, + (q31_t)0x7c3566c2, (q31_t)0x7c33e205, (q31_t)0x7c325cfc, (q31_t)0x7c30d7a6, (q31_t)0x7c2f5203, (q31_t)0x7c2dcc14, (q31_t)0x7c2c45d8, (q31_t)0x7c2abf4f, + (q31_t)0x7c29387a, (q31_t)0x7c27b158, (q31_t)0x7c2629ea, (q31_t)0x7c24a22f, (q31_t)0x7c231a28, (q31_t)0x7c2191d4, (q31_t)0x7c200933, (q31_t)0x7c1e8046, + (q31_t)0x7c1cf70c, (q31_t)0x7c1b6d86, (q31_t)0x7c19e3b3, (q31_t)0x7c185994, (q31_t)0x7c16cf28, (q31_t)0x7c15446f, (q31_t)0x7c13b96a, (q31_t)0x7c122e19, + (q31_t)0x7c10a27b, (q31_t)0x7c0f1690, (q31_t)0x7c0d8a59, (q31_t)0x7c0bfdd5, (q31_t)0x7c0a7105, (q31_t)0x7c08e3e8, (q31_t)0x7c07567f, (q31_t)0x7c05c8c9, + (q31_t)0x7c043ac7, (q31_t)0x7c02ac78, (q31_t)0x7c011ddd, (q31_t)0x7bff8ef5, (q31_t)0x7bfdffc1, (q31_t)0x7bfc7041, (q31_t)0x7bfae073, (q31_t)0x7bf9505a, + (q31_t)0x7bf7bff4, (q31_t)0x7bf62f41, (q31_t)0x7bf49e42, (q31_t)0x7bf30cf6, (q31_t)0x7bf17b5e, (q31_t)0x7befe97a, (q31_t)0x7bee5749, (q31_t)0x7becc4cc, + (q31_t)0x7beb3202, (q31_t)0x7be99eec, (q31_t)0x7be80b89, (q31_t)0x7be677da, (q31_t)0x7be4e3df, (q31_t)0x7be34f97, (q31_t)0x7be1bb02, (q31_t)0x7be02621, + (q31_t)0x7bde90f4, (q31_t)0x7bdcfb7b, (q31_t)0x7bdb65b5, (q31_t)0x7bd9cfa2, (q31_t)0x7bd83944, (q31_t)0x7bd6a298, (q31_t)0x7bd50ba1, (q31_t)0x7bd3745d, + (q31_t)0x7bd1dccc, (q31_t)0x7bd044f0, (q31_t)0x7bceacc7, (q31_t)0x7bcd1451, (q31_t)0x7bcb7b8f, (q31_t)0x7bc9e281, (q31_t)0x7bc84927, (q31_t)0x7bc6af80, + (q31_t)0x7bc5158c, (q31_t)0x7bc37b4d, (q31_t)0x7bc1e0c1, (q31_t)0x7bc045e9, (q31_t)0x7bbeaac4, (q31_t)0x7bbd0f53, (q31_t)0x7bbb7396, (q31_t)0x7bb9d78c, + (q31_t)0x7bb83b36, (q31_t)0x7bb69e94, (q31_t)0x7bb501a5, (q31_t)0x7bb3646a, (q31_t)0x7bb1c6e3, (q31_t)0x7bb02910, (q31_t)0x7bae8af0, (q31_t)0x7bacec84, + (q31_t)0x7bab4dcc, (q31_t)0x7ba9aec7, (q31_t)0x7ba80f76, (q31_t)0x7ba66fd9, (q31_t)0x7ba4cfef, (q31_t)0x7ba32fba, (q31_t)0x7ba18f38, (q31_t)0x7b9fee69, + (q31_t)0x7b9e4d4f, (q31_t)0x7b9cabe8, (q31_t)0x7b9b0a35, (q31_t)0x7b996836, (q31_t)0x7b97c5ea, (q31_t)0x7b962352, (q31_t)0x7b94806e, (q31_t)0x7b92dd3e, + (q31_t)0x7b9139c2, (q31_t)0x7b8f95f9, (q31_t)0x7b8df1e4, (q31_t)0x7b8c4d83, (q31_t)0x7b8aa8d6, (q31_t)0x7b8903dc, (q31_t)0x7b875e96, (q31_t)0x7b85b904, + (q31_t)0x7b841326, (q31_t)0x7b826cfc, (q31_t)0x7b80c686, (q31_t)0x7b7f1fc3, (q31_t)0x7b7d78b4, (q31_t)0x7b7bd159, (q31_t)0x7b7a29b2, (q31_t)0x7b7881be, + (q31_t)0x7b76d97f, (q31_t)0x7b7530f3, (q31_t)0x7b73881b, (q31_t)0x7b71def7, (q31_t)0x7b703587, (q31_t)0x7b6e8bcb, (q31_t)0x7b6ce1c2, (q31_t)0x7b6b376e, + (q31_t)0x7b698ccd, (q31_t)0x7b67e1e0, (q31_t)0x7b6636a7, (q31_t)0x7b648b22, (q31_t)0x7b62df51, (q31_t)0x7b613334, (q31_t)0x7b5f86ca, (q31_t)0x7b5dda15, + (q31_t)0x7b5c2d13, (q31_t)0x7b5a7fc6, (q31_t)0x7b58d22c, (q31_t)0x7b572446, (q31_t)0x7b557614, (q31_t)0x7b53c796, (q31_t)0x7b5218cc, (q31_t)0x7b5069b6, + (q31_t)0x7b4eba53, (q31_t)0x7b4d0aa5, (q31_t)0x7b4b5aab, (q31_t)0x7b49aa64, (q31_t)0x7b47f9d2, (q31_t)0x7b4648f3, (q31_t)0x7b4497c9, (q31_t)0x7b42e652, + (q31_t)0x7b413490, (q31_t)0x7b3f8281, (q31_t)0x7b3dd026, (q31_t)0x7b3c1d80, (q31_t)0x7b3a6a8d, (q31_t)0x7b38b74e, (q31_t)0x7b3703c3, (q31_t)0x7b354fed, + (q31_t)0x7b339bca, (q31_t)0x7b31e75b, (q31_t)0x7b3032a0, (q31_t)0x7b2e7d9a, (q31_t)0x7b2cc847, (q31_t)0x7b2b12a8, (q31_t)0x7b295cbe, (q31_t)0x7b27a687, + (q31_t)0x7b25f004, (q31_t)0x7b243936, (q31_t)0x7b22821b, (q31_t)0x7b20cab5, (q31_t)0x7b1f1302, (q31_t)0x7b1d5b04, (q31_t)0x7b1ba2b9, (q31_t)0x7b19ea23, + (q31_t)0x7b183141, (q31_t)0x7b167813, (q31_t)0x7b14be99, (q31_t)0x7b1304d3, (q31_t)0x7b114ac1, (q31_t)0x7b0f9063, (q31_t)0x7b0dd5b9, (q31_t)0x7b0c1ac4, + (q31_t)0x7b0a5f82, (q31_t)0x7b08a3f5, (q31_t)0x7b06e81b, (q31_t)0x7b052bf6, (q31_t)0x7b036f85, (q31_t)0x7b01b2c8, (q31_t)0x7afff5bf, (q31_t)0x7afe386a, + (q31_t)0x7afc7aca, (q31_t)0x7afabcdd, (q31_t)0x7af8fea5, (q31_t)0x7af74021, (q31_t)0x7af58151, (q31_t)0x7af3c235, (q31_t)0x7af202cd, (q31_t)0x7af0431a, + (q31_t)0x7aee831a, (q31_t)0x7aecc2cf, (q31_t)0x7aeb0238, (q31_t)0x7ae94155, (q31_t)0x7ae78026, (q31_t)0x7ae5beac, (q31_t)0x7ae3fce6, (q31_t)0x7ae23ad4, + (q31_t)0x7ae07876, (q31_t)0x7adeb5cc, (q31_t)0x7adcf2d6, (q31_t)0x7adb2f95, (q31_t)0x7ad96c08, (q31_t)0x7ad7a82f, (q31_t)0x7ad5e40a, (q31_t)0x7ad41f9a, + (q31_t)0x7ad25ade, (q31_t)0x7ad095d6, (q31_t)0x7aced082, (q31_t)0x7acd0ae3, (q31_t)0x7acb44f8, (q31_t)0x7ac97ec1, (q31_t)0x7ac7b83e, (q31_t)0x7ac5f170, + (q31_t)0x7ac42a55, (q31_t)0x7ac262ef, (q31_t)0x7ac09b3e, (q31_t)0x7abed341, (q31_t)0x7abd0af7, (q31_t)0x7abb4263, (q31_t)0x7ab97982, (q31_t)0x7ab7b056, + (q31_t)0x7ab5e6de, (q31_t)0x7ab41d1b, (q31_t)0x7ab2530b, (q31_t)0x7ab088b0, (q31_t)0x7aaebe0a, (q31_t)0x7aacf318, (q31_t)0x7aab27da, (q31_t)0x7aa95c50, + (q31_t)0x7aa7907b, (q31_t)0x7aa5c45a, (q31_t)0x7aa3f7ed, (q31_t)0x7aa22b35, (q31_t)0x7aa05e31, (q31_t)0x7a9e90e1, (q31_t)0x7a9cc346, (q31_t)0x7a9af55f, + (q31_t)0x7a99272d, (q31_t)0x7a9758af, (q31_t)0x7a9589e5, (q31_t)0x7a93bad0, (q31_t)0x7a91eb6f, (q31_t)0x7a901bc2, (q31_t)0x7a8e4bca, (q31_t)0x7a8c7b87, + (q31_t)0x7a8aaaf7, (q31_t)0x7a88da1c, (q31_t)0x7a8708f6, (q31_t)0x7a853784, (q31_t)0x7a8365c6, (q31_t)0x7a8193bd, (q31_t)0x7a7fc168, (q31_t)0x7a7deec8, + (q31_t)0x7a7c1bdc, (q31_t)0x7a7a48a4, (q31_t)0x7a787521, (q31_t)0x7a76a153, (q31_t)0x7a74cd38, (q31_t)0x7a72f8d3, (q31_t)0x7a712422, (q31_t)0x7a6f4f25, + (q31_t)0x7a6d79dd, (q31_t)0x7a6ba449, (q31_t)0x7a69ce6a, (q31_t)0x7a67f83f, (q31_t)0x7a6621c9, (q31_t)0x7a644b07, (q31_t)0x7a6273fa, (q31_t)0x7a609ca1, + (q31_t)0x7a5ec4fc, (q31_t)0x7a5ced0d, (q31_t)0x7a5b14d1, (q31_t)0x7a593c4b, (q31_t)0x7a576379, (q31_t)0x7a558a5b, (q31_t)0x7a53b0f2, (q31_t)0x7a51d73d, + (q31_t)0x7a4ffd3d, (q31_t)0x7a4e22f2, (q31_t)0x7a4c485b, (q31_t)0x7a4a6d78, (q31_t)0x7a48924b, (q31_t)0x7a46b6d1, (q31_t)0x7a44db0d, (q31_t)0x7a42fefd, + (q31_t)0x7a4122a1, (q31_t)0x7a3f45fa, (q31_t)0x7a3d6908, (q31_t)0x7a3b8bca, (q31_t)0x7a39ae41, (q31_t)0x7a37d06d, (q31_t)0x7a35f24d, (q31_t)0x7a3413e2, + (q31_t)0x7a32352b, (q31_t)0x7a305629, (q31_t)0x7a2e76dc, (q31_t)0x7a2c9743, (q31_t)0x7a2ab75f, (q31_t)0x7a28d72f, (q31_t)0x7a26f6b4, (q31_t)0x7a2515ee, + (q31_t)0x7a2334dd, (q31_t)0x7a215380, (q31_t)0x7a1f71d7, (q31_t)0x7a1d8fe4, (q31_t)0x7a1bada5, (q31_t)0x7a19cb1b, (q31_t)0x7a17e845, (q31_t)0x7a160524, + (q31_t)0x7a1421b8, (q31_t)0x7a123e01, (q31_t)0x7a1059fe, (q31_t)0x7a0e75b0, (q31_t)0x7a0c9117, (q31_t)0x7a0aac32, (q31_t)0x7a08c702, (q31_t)0x7a06e187, + (q31_t)0x7a04fbc1, (q31_t)0x7a0315af, (q31_t)0x7a012f52, (q31_t)0x79ff48aa, (q31_t)0x79fd61b6, (q31_t)0x79fb7a77, (q31_t)0x79f992ed, (q31_t)0x79f7ab18, + (q31_t)0x79f5c2f8, (q31_t)0x79f3da8c, (q31_t)0x79f1f1d5, (q31_t)0x79f008d3, (q31_t)0x79ee1f86, (q31_t)0x79ec35ed, (q31_t)0x79ea4c09, (q31_t)0x79e861da, + (q31_t)0x79e67760, (q31_t)0x79e48c9b, (q31_t)0x79e2a18a, (q31_t)0x79e0b62e, (q31_t)0x79deca87, (q31_t)0x79dcde95, (q31_t)0x79daf258, (q31_t)0x79d905d0, + (q31_t)0x79d718fc, (q31_t)0x79d52bdd, (q31_t)0x79d33e73, (q31_t)0x79d150be, (q31_t)0x79cf62be, (q31_t)0x79cd7473, (q31_t)0x79cb85dc, (q31_t)0x79c996fb, + (q31_t)0x79c7a7ce, (q31_t)0x79c5b856, (q31_t)0x79c3c893, (q31_t)0x79c1d885, (q31_t)0x79bfe82c, (q31_t)0x79bdf788, (q31_t)0x79bc0698, (q31_t)0x79ba155e, + (q31_t)0x79b823d8, (q31_t)0x79b63207, (q31_t)0x79b43fec, (q31_t)0x79b24d85, (q31_t)0x79b05ad3, (q31_t)0x79ae67d6, (q31_t)0x79ac748e, (q31_t)0x79aa80fb, + (q31_t)0x79a88d1d, (q31_t)0x79a698f4, (q31_t)0x79a4a480, (q31_t)0x79a2afc1, (q31_t)0x79a0bab6, (q31_t)0x799ec561, (q31_t)0x799ccfc1, (q31_t)0x799ad9d5, + (q31_t)0x7998e39f, (q31_t)0x7996ed1e, (q31_t)0x7994f651, (q31_t)0x7992ff3a, (q31_t)0x799107d8, (q31_t)0x798f102a, (q31_t)0x798d1832, (q31_t)0x798b1fef, + (q31_t)0x79892761, (q31_t)0x79872e87, (q31_t)0x79853563, (q31_t)0x79833bf4, (q31_t)0x7981423a, (q31_t)0x797f4835, (q31_t)0x797d4de5, (q31_t)0x797b534a, + (q31_t)0x79795864, (q31_t)0x79775d33, (q31_t)0x797561b8, (q31_t)0x797365f1, (q31_t)0x797169df, (q31_t)0x796f6d83, (q31_t)0x796d70dc, (q31_t)0x796b73e9, + (q31_t)0x796976ac, (q31_t)0x79677924, (q31_t)0x79657b51, (q31_t)0x79637d33, (q31_t)0x79617eca, (q31_t)0x795f8017, (q31_t)0x795d8118, (q31_t)0x795b81cf, + (q31_t)0x7959823b, (q31_t)0x7957825c, (q31_t)0x79558232, (q31_t)0x795381bd, (q31_t)0x795180fe, (q31_t)0x794f7ff3, (q31_t)0x794d7e9e, (q31_t)0x794b7cfe, + (q31_t)0x79497b13, (q31_t)0x794778dd, (q31_t)0x7945765d, (q31_t)0x79437391, (q31_t)0x7941707b, (q31_t)0x793f6d1a, (q31_t)0x793d696f, (q31_t)0x793b6578, + (q31_t)0x79396137, (q31_t)0x79375cab, (q31_t)0x793557d4, (q31_t)0x793352b2, (q31_t)0x79314d46, (q31_t)0x792f478f, (q31_t)0x792d418d, (q31_t)0x792b3b40, + (q31_t)0x792934a9, (q31_t)0x79272dc7, (q31_t)0x7925269a, (q31_t)0x79231f22, (q31_t)0x79211760, (q31_t)0x791f0f53, (q31_t)0x791d06fb, (q31_t)0x791afe59, + (q31_t)0x7918f56c, (q31_t)0x7916ec34, (q31_t)0x7914e2b2, (q31_t)0x7912d8e4, (q31_t)0x7910cecc, (q31_t)0x790ec46a, (q31_t)0x790cb9bd, (q31_t)0x790aaec5, + (q31_t)0x7908a382, (q31_t)0x790697f5, (q31_t)0x79048c1d, (q31_t)0x79027ffa, (q31_t)0x7900738d, (q31_t)0x78fe66d5, (q31_t)0x78fc59d3, (q31_t)0x78fa4c86, + (q31_t)0x78f83eee, (q31_t)0x78f6310c, (q31_t)0x78f422df, (q31_t)0x78f21467, (q31_t)0x78f005a5, (q31_t)0x78edf698, (q31_t)0x78ebe741, (q31_t)0x78e9d79f, + (q31_t)0x78e7c7b2, (q31_t)0x78e5b77b, (q31_t)0x78e3a6f9, (q31_t)0x78e1962d, (q31_t)0x78df8516, (q31_t)0x78dd73b5, (q31_t)0x78db6209, (q31_t)0x78d95012, + (q31_t)0x78d73dd1, (q31_t)0x78d52b46, (q31_t)0x78d31870, (q31_t)0x78d1054f, (q31_t)0x78cef1e4, (q31_t)0x78ccde2e, (q31_t)0x78caca2e, (q31_t)0x78c8b5e3, + (q31_t)0x78c6a14e, (q31_t)0x78c48c6e, (q31_t)0x78c27744, (q31_t)0x78c061cf, (q31_t)0x78be4c10, (q31_t)0x78bc3606, (q31_t)0x78ba1fb2, (q31_t)0x78b80913, + (q31_t)0x78b5f22a, (q31_t)0x78b3daf7, (q31_t)0x78b1c379, (q31_t)0x78afabb0, (q31_t)0x78ad939d, (q31_t)0x78ab7b40, (q31_t)0x78a96298, (q31_t)0x78a749a6, + (q31_t)0x78a53069, (q31_t)0x78a316e2, (q31_t)0x78a0fd11, (q31_t)0x789ee2f5, (q31_t)0x789cc88f, (q31_t)0x789aadde, (q31_t)0x789892e3, (q31_t)0x7896779d, + (q31_t)0x78945c0d, (q31_t)0x78924033, (q31_t)0x7890240e, (q31_t)0x788e07a0, (q31_t)0x788beae6, (q31_t)0x7889cde2, (q31_t)0x7887b094, (q31_t)0x788592fc, + (q31_t)0x78837519, (q31_t)0x788156ec, (q31_t)0x787f3875, (q31_t)0x787d19b3, (q31_t)0x787afaa7, (q31_t)0x7878db50, (q31_t)0x7876bbb0, (q31_t)0x78749bc5, + (q31_t)0x78727b8f, (q31_t)0x78705b10, (q31_t)0x786e3a46, (q31_t)0x786c1932, (q31_t)0x7869f7d3, (q31_t)0x7867d62a, (q31_t)0x7865b437, (q31_t)0x786391fa, + (q31_t)0x78616f72, (q31_t)0x785f4ca1, (q31_t)0x785d2984, (q31_t)0x785b061e, (q31_t)0x7858e26e, (q31_t)0x7856be73, (q31_t)0x78549a2e, (q31_t)0x7852759e, + (q31_t)0x785050c5, (q31_t)0x784e2ba1, (q31_t)0x784c0633, (q31_t)0x7849e07b, (q31_t)0x7847ba79, (q31_t)0x7845942c, (q31_t)0x78436d96, (q31_t)0x784146b5, + (q31_t)0x783f1f8a, (q31_t)0x783cf815, (q31_t)0x783ad055, (q31_t)0x7838a84c, (q31_t)0x78367ff8, (q31_t)0x7834575a, (q31_t)0x78322e72, (q31_t)0x78300540, + (q31_t)0x782ddbc4, (q31_t)0x782bb1fd, (q31_t)0x782987ed, (q31_t)0x78275d92, (q31_t)0x782532ed, (q31_t)0x782307fe, (q31_t)0x7820dcc5, (q31_t)0x781eb142, + (q31_t)0x781c8575, (q31_t)0x781a595d, (q31_t)0x78182cfc, (q31_t)0x78160051, (q31_t)0x7813d35b, (q31_t)0x7811a61b, (q31_t)0x780f7892, (q31_t)0x780d4abe, + (q31_t)0x780b1ca0, (q31_t)0x7808ee38, (q31_t)0x7806bf86, (q31_t)0x7804908a, (q31_t)0x78026145, (q31_t)0x780031b5, (q31_t)0x77fe01db, (q31_t)0x77fbd1b6, + (q31_t)0x77f9a148, (q31_t)0x77f77090, (q31_t)0x77f53f8e, (q31_t)0x77f30e42, (q31_t)0x77f0dcac, (q31_t)0x77eeaacc, (q31_t)0x77ec78a2, (q31_t)0x77ea462e, + (q31_t)0x77e81370, (q31_t)0x77e5e068, (q31_t)0x77e3ad17, (q31_t)0x77e1797b, (q31_t)0x77df4595, (q31_t)0x77dd1165, (q31_t)0x77dadcec, (q31_t)0x77d8a828, + (q31_t)0x77d6731a, (q31_t)0x77d43dc3, (q31_t)0x77d20822, (q31_t)0x77cfd236, (q31_t)0x77cd9c01, (q31_t)0x77cb6582, (q31_t)0x77c92eb9, (q31_t)0x77c6f7a6, + (q31_t)0x77c4c04a, (q31_t)0x77c288a3, (q31_t)0x77c050b2, (q31_t)0x77be1878, (q31_t)0x77bbdff4, (q31_t)0x77b9a726, (q31_t)0x77b76e0e, (q31_t)0x77b534ac, + (q31_t)0x77b2fb00, (q31_t)0x77b0c10b, (q31_t)0x77ae86cc, (q31_t)0x77ac4c43, (q31_t)0x77aa1170, (q31_t)0x77a7d653, (q31_t)0x77a59aec, (q31_t)0x77a35f3c, + (q31_t)0x77a12342, (q31_t)0x779ee6fe, (q31_t)0x779caa70, (q31_t)0x779a6d99, (q31_t)0x77983077, (q31_t)0x7795f30c, (q31_t)0x7793b557, (q31_t)0x77917759, + (q31_t)0x778f3910, (q31_t)0x778cfa7e, (q31_t)0x778abba2, (q31_t)0x77887c7d, (q31_t)0x77863d0d, (q31_t)0x7783fd54, (q31_t)0x7781bd52, (q31_t)0x777f7d05, + (q31_t)0x777d3c6f, (q31_t)0x777afb8f, (q31_t)0x7778ba65, (q31_t)0x777678f2, (q31_t)0x77743735, (q31_t)0x7771f52e, (q31_t)0x776fb2de, (q31_t)0x776d7044, + (q31_t)0x776b2d60, (q31_t)0x7768ea33, (q31_t)0x7766a6bc, (q31_t)0x776462fb, (q31_t)0x77621ef1, (q31_t)0x775fda9d, (q31_t)0x775d95ff, (q31_t)0x775b5118, + (q31_t)0x77590be7, (q31_t)0x7756c66c, (q31_t)0x775480a8, (q31_t)0x77523a9b, (q31_t)0x774ff443, (q31_t)0x774dada2, (q31_t)0x774b66b8, (q31_t)0x77491f84, + (q31_t)0x7746d806, (q31_t)0x7744903f, (q31_t)0x7742482e, (q31_t)0x773fffd4, (q31_t)0x773db730, (q31_t)0x773b6e42, (q31_t)0x7739250b, (q31_t)0x7736db8b, + (q31_t)0x773491c0, (q31_t)0x773247ad, (q31_t)0x772ffd50, (q31_t)0x772db2a9, (q31_t)0x772b67b9, (q31_t)0x77291c7f, (q31_t)0x7726d0fc, (q31_t)0x7724852f, + (q31_t)0x77223919, (q31_t)0x771fecb9, (q31_t)0x771da010, (q31_t)0x771b531d, (q31_t)0x771905e1, (q31_t)0x7716b85b, (q31_t)0x77146a8c, (q31_t)0x77121c74, + (q31_t)0x770fce12, (q31_t)0x770d7f66, (q31_t)0x770b3072, (q31_t)0x7708e133, (q31_t)0x770691ab, (q31_t)0x770441da, (q31_t)0x7701f1c0, (q31_t)0x76ffa15c, + (q31_t)0x76fd50ae, (q31_t)0x76faffb8, (q31_t)0x76f8ae78, (q31_t)0x76f65cee, (q31_t)0x76f40b1b, (q31_t)0x76f1b8ff, (q31_t)0x76ef6699, (q31_t)0x76ed13ea, + (q31_t)0x76eac0f2, (q31_t)0x76e86db0, (q31_t)0x76e61a25, (q31_t)0x76e3c650, (q31_t)0x76e17233, (q31_t)0x76df1dcb, (q31_t)0x76dcc91b, (q31_t)0x76da7421, + (q31_t)0x76d81ede, (q31_t)0x76d5c952, (q31_t)0x76d3737c, (q31_t)0x76d11d5d, (q31_t)0x76cec6f5, (q31_t)0x76cc7043, (q31_t)0x76ca1948, (q31_t)0x76c7c204, + (q31_t)0x76c56a77, (q31_t)0x76c312a0, (q31_t)0x76c0ba80, (q31_t)0x76be6217, (q31_t)0x76bc0965, (q31_t)0x76b9b069, (q31_t)0x76b75724, (q31_t)0x76b4fd96, + (q31_t)0x76b2a3bf, (q31_t)0x76b0499e, (q31_t)0x76adef34, (q31_t)0x76ab9481, (q31_t)0x76a93985, (q31_t)0x76a6de40, (q31_t)0x76a482b1, (q31_t)0x76a226da, + (q31_t)0x769fcab9, (q31_t)0x769d6e4f, (q31_t)0x769b119b, (q31_t)0x7698b49f, (q31_t)0x76965759, (q31_t)0x7693f9ca, (q31_t)0x76919bf3, (q31_t)0x768f3dd2, + (q31_t)0x768cdf67, (q31_t)0x768a80b4, (q31_t)0x768821b8, (q31_t)0x7685c272, (q31_t)0x768362e4, (q31_t)0x7681030c, (q31_t)0x767ea2eb, (q31_t)0x767c4281, + (q31_t)0x7679e1ce, (q31_t)0x767780d2, (q31_t)0x76751f8d, (q31_t)0x7672bdfe, (q31_t)0x76705c27, (q31_t)0x766dfa07, (q31_t)0x766b979d, (q31_t)0x766934eb, + (q31_t)0x7666d1ef, (q31_t)0x76646eab, (q31_t)0x76620b1d, (q31_t)0x765fa747, (q31_t)0x765d4327, (q31_t)0x765adebe, (q31_t)0x76587a0d, (q31_t)0x76561512, + (q31_t)0x7653afce, (q31_t)0x76514a42, (q31_t)0x764ee46c, (q31_t)0x764c7e4d, (q31_t)0x764a17e6, (q31_t)0x7647b135, (q31_t)0x76454a3c, (q31_t)0x7642e2f9, + (q31_t)0x76407b6e, (q31_t)0x763e139a, (q31_t)0x763bab7c, (q31_t)0x76394316, (q31_t)0x7636da67, (q31_t)0x7634716f, (q31_t)0x7632082e, (q31_t)0x762f9ea4, + (q31_t)0x762d34d1, (q31_t)0x762acab6, (q31_t)0x76286051, (q31_t)0x7625f5a3, (q31_t)0x76238aad, (q31_t)0x76211f6e, (q31_t)0x761eb3e6, (q31_t)0x761c4815, + (q31_t)0x7619dbfb, (q31_t)0x76176f98, (q31_t)0x761502ed, (q31_t)0x761295f9, (q31_t)0x761028bb, (q31_t)0x760dbb35, (q31_t)0x760b4d67, (q31_t)0x7608df4f, + (q31_t)0x760670ee, (q31_t)0x76040245, (q31_t)0x76019353, (q31_t)0x75ff2418, (q31_t)0x75fcb495, (q31_t)0x75fa44c8, (q31_t)0x75f7d4b3, (q31_t)0x75f56455, + (q31_t)0x75f2f3ae, (q31_t)0x75f082bf, (q31_t)0x75ee1187, (q31_t)0x75eba006, (q31_t)0x75e92e3c, (q31_t)0x75e6bc2a, (q31_t)0x75e449ce, (q31_t)0x75e1d72b, + (q31_t)0x75df643e, (q31_t)0x75dcf109, (q31_t)0x75da7d8b, (q31_t)0x75d809c4, (q31_t)0x75d595b4, (q31_t)0x75d3215c, (q31_t)0x75d0acbc, (q31_t)0x75ce37d2, + (q31_t)0x75cbc2a0, (q31_t)0x75c94d25, (q31_t)0x75c6d762, (q31_t)0x75c46156, (q31_t)0x75c1eb01, (q31_t)0x75bf7464, (q31_t)0x75bcfd7e, (q31_t)0x75ba864f, + (q31_t)0x75b80ed8, (q31_t)0x75b59718, (q31_t)0x75b31f0f, (q31_t)0x75b0a6be, (q31_t)0x75ae2e25, (q31_t)0x75abb542, (q31_t)0x75a93c18, (q31_t)0x75a6c2a4, + (q31_t)0x75a448e8, (q31_t)0x75a1cee4, (q31_t)0x759f5496, (q31_t)0x759cda01, (q31_t)0x759a5f22, (q31_t)0x7597e3fc, (q31_t)0x7595688c, (q31_t)0x7592ecd4, + (q31_t)0x759070d4, (q31_t)0x758df48b, (q31_t)0x758b77fa, (q31_t)0x7588fb20, (q31_t)0x75867dfd, (q31_t)0x75840093, (q31_t)0x758182df, (q31_t)0x757f04e3, + (q31_t)0x757c869f, (q31_t)0x757a0812, (q31_t)0x7577893d, (q31_t)0x75750a1f, (q31_t)0x75728ab9, (q31_t)0x75700b0a, (q31_t)0x756d8b13, (q31_t)0x756b0ad3, + (q31_t)0x75688a4b, (q31_t)0x7566097b, (q31_t)0x75638862, (q31_t)0x75610701, (q31_t)0x755e8557, (q31_t)0x755c0365, (q31_t)0x7559812b, (q31_t)0x7556fea8, + (q31_t)0x75547bdd, (q31_t)0x7551f8c9, (q31_t)0x754f756e, (q31_t)0x754cf1c9, (q31_t)0x754a6ddd, (q31_t)0x7547e9a8, (q31_t)0x7545652a, (q31_t)0x7542e065, + (q31_t)0x75405b57, (q31_t)0x753dd600, (q31_t)0x753b5061, (q31_t)0x7538ca7b, (q31_t)0x7536444b, (q31_t)0x7533bdd4, (q31_t)0x75313714, (q31_t)0x752eb00c, + (q31_t)0x752c28bb, (q31_t)0x7529a122, (q31_t)0x75271941, (q31_t)0x75249118, (q31_t)0x752208a7, (q31_t)0x751f7fed, (q31_t)0x751cf6eb, (q31_t)0x751a6da0, + (q31_t)0x7517e40e, (q31_t)0x75155a33, (q31_t)0x7512d010, (q31_t)0x751045a5, (q31_t)0x750dbaf2, (q31_t)0x750b2ff6, (q31_t)0x7508a4b2, (q31_t)0x75061926, + (q31_t)0x75038d52, (q31_t)0x75010136, (q31_t)0x74fe74d1, (q31_t)0x74fbe825, (q31_t)0x74f95b30, (q31_t)0x74f6cdf3, (q31_t)0x74f4406d, (q31_t)0x74f1b2a0, + (q31_t)0x74ef248b, (q31_t)0x74ec962d, (q31_t)0x74ea0787, (q31_t)0x74e7789a, (q31_t)0x74e4e964, (q31_t)0x74e259e6, (q31_t)0x74dfca20, (q31_t)0x74dd3a11, + (q31_t)0x74daa9bb, (q31_t)0x74d8191d, (q31_t)0x74d58836, (q31_t)0x74d2f708, (q31_t)0x74d06591, (q31_t)0x74cdd3d2, (q31_t)0x74cb41cc, (q31_t)0x74c8af7d, + (q31_t)0x74c61ce6, (q31_t)0x74c38a07, (q31_t)0x74c0f6e0, (q31_t)0x74be6372, (q31_t)0x74bbcfbb, (q31_t)0x74b93bbc, (q31_t)0x74b6a775, (q31_t)0x74b412e6, + (q31_t)0x74b17e0f, (q31_t)0x74aee8f0, (q31_t)0x74ac5389, (q31_t)0x74a9bddb, (q31_t)0x74a727e4, (q31_t)0x74a491a5, (q31_t)0x74a1fb1e, (q31_t)0x749f6450, + (q31_t)0x749ccd39, (q31_t)0x749a35db, (q31_t)0x74979e34, (q31_t)0x74950646, (q31_t)0x74926e10, (q31_t)0x748fd592, (q31_t)0x748d3ccb, (q31_t)0x748aa3be, + (q31_t)0x74880a68, (q31_t)0x748570ca, (q31_t)0x7482d6e4, (q31_t)0x74803cb7, (q31_t)0x747da242, (q31_t)0x747b0784, (q31_t)0x74786c7f, (q31_t)0x7475d132, + (q31_t)0x7473359e, (q31_t)0x747099c1, (q31_t)0x746dfd9d, (q31_t)0x746b6131, (q31_t)0x7468c47c, (q31_t)0x74662781, (q31_t)0x74638a3d, (q31_t)0x7460ecb2, + (q31_t)0x745e4ede, (q31_t)0x745bb0c3, (q31_t)0x74591261, (q31_t)0x745673b6, (q31_t)0x7453d4c4, (q31_t)0x7451358a, (q31_t)0x744e9608, (q31_t)0x744bf63e, + (q31_t)0x7449562d, (q31_t)0x7446b5d4, (q31_t)0x74441533, (q31_t)0x7441744b, (q31_t)0x743ed31b, (q31_t)0x743c31a3, (q31_t)0x74398fe3, (q31_t)0x7436eddc, + (q31_t)0x74344b8d, (q31_t)0x7431a8f6, (q31_t)0x742f0618, (q31_t)0x742c62f2, (q31_t)0x7429bf84, (q31_t)0x74271bcf, (q31_t)0x742477d2, (q31_t)0x7421d38e, + (q31_t)0x741f2f01, (q31_t)0x741c8a2d, (q31_t)0x7419e512, (q31_t)0x74173faf, (q31_t)0x74149a04, (q31_t)0x7411f412, (q31_t)0x740f4dd8, (q31_t)0x740ca756, + (q31_t)0x740a008d, (q31_t)0x7407597d, (q31_t)0x7404b224, (q31_t)0x74020a85, (q31_t)0x73ff629d, (q31_t)0x73fcba6e, (q31_t)0x73fa11f8, (q31_t)0x73f7693a, + (q31_t)0x73f4c034, (q31_t)0x73f216e7, (q31_t)0x73ef6d53, (q31_t)0x73ecc377, (q31_t)0x73ea1953, (q31_t)0x73e76ee8, (q31_t)0x73e4c435, (q31_t)0x73e2193b, + (q31_t)0x73df6df9, (q31_t)0x73dcc270, (q31_t)0x73da16a0, (q31_t)0x73d76a88, (q31_t)0x73d4be28, (q31_t)0x73d21182, (q31_t)0x73cf6493, (q31_t)0x73ccb75d, + (q31_t)0x73ca09e0, (q31_t)0x73c75c1c, (q31_t)0x73c4ae10, (q31_t)0x73c1ffbc, (q31_t)0x73bf5121, (q31_t)0x73bca23f, (q31_t)0x73b9f315, (q31_t)0x73b743a4, + (q31_t)0x73b493ec, (q31_t)0x73b1e3ec, (q31_t)0x73af33a5, (q31_t)0x73ac8316, (q31_t)0x73a9d240, (q31_t)0x73a72123, (q31_t)0x73a46fbf, (q31_t)0x73a1be13, + (q31_t)0x739f0c20, (q31_t)0x739c59e5, (q31_t)0x7399a763, (q31_t)0x7396f49a, (q31_t)0x73944189, (q31_t)0x73918e32, (q31_t)0x738eda93, (q31_t)0x738c26ac, + (q31_t)0x7389727f, (q31_t)0x7386be0a, (q31_t)0x7384094e, (q31_t)0x7381544a, (q31_t)0x737e9f00, (q31_t)0x737be96e, (q31_t)0x73793395, (q31_t)0x73767d74, + (q31_t)0x7373c70d, (q31_t)0x7371105e, (q31_t)0x736e5968, (q31_t)0x736ba22b, (q31_t)0x7368eaa6, (q31_t)0x736632db, (q31_t)0x73637ac8, (q31_t)0x7360c26e, + (q31_t)0x735e09cd, (q31_t)0x735b50e4, (q31_t)0x735897b5, (q31_t)0x7355de3e, (q31_t)0x73532481, (q31_t)0x73506a7c, (q31_t)0x734db030, (q31_t)0x734af59d, + (q31_t)0x73483ac2, (q31_t)0x73457fa1, (q31_t)0x7342c438, (q31_t)0x73400889, (q31_t)0x733d4c92, (q31_t)0x733a9054, (q31_t)0x7337d3d0, (q31_t)0x73351704, + (q31_t)0x733259f1, (q31_t)0x732f9c97, (q31_t)0x732cdef6, (q31_t)0x732a210d, (q31_t)0x732762de, (q31_t)0x7324a468, (q31_t)0x7321e5ab, (q31_t)0x731f26a7, + (q31_t)0x731c675b, (q31_t)0x7319a7c9, (q31_t)0x7316e7f0, (q31_t)0x731427cf, (q31_t)0x73116768, (q31_t)0x730ea6ba, (q31_t)0x730be5c5, (q31_t)0x73092489, + (q31_t)0x73066306, (q31_t)0x7303a13b, (q31_t)0x7300df2a, (q31_t)0x72fe1cd2, (q31_t)0x72fb5a34, (q31_t)0x72f8974e, (q31_t)0x72f5d421, (q31_t)0x72f310ad, + (q31_t)0x72f04cf3, (q31_t)0x72ed88f1, (q31_t)0x72eac4a9, (q31_t)0x72e8001a, (q31_t)0x72e53b44, (q31_t)0x72e27627, (q31_t)0x72dfb0c3, (q31_t)0x72dceb18, + (q31_t)0x72da2526, (q31_t)0x72d75eee, (q31_t)0x72d4986f, (q31_t)0x72d1d1a9, (q31_t)0x72cf0a9c, (q31_t)0x72cc4348, (q31_t)0x72c97bad, (q31_t)0x72c6b3cc, + (q31_t)0x72c3eba4, (q31_t)0x72c12335, (q31_t)0x72be5a7f, (q31_t)0x72bb9183, (q31_t)0x72b8c83f, (q31_t)0x72b5feb5, (q31_t)0x72b334e4, (q31_t)0x72b06acd, + (q31_t)0x72ada06f, (q31_t)0x72aad5c9, (q31_t)0x72a80ade, (q31_t)0x72a53fab, (q31_t)0x72a27432, (q31_t)0x729fa872, (q31_t)0x729cdc6b, (q31_t)0x729a101e, + (q31_t)0x7297438a, (q31_t)0x729476af, (q31_t)0x7291a98e, (q31_t)0x728edc26, (q31_t)0x728c0e77, (q31_t)0x72894082, (q31_t)0x72867245, (q31_t)0x7283a3c3, + (q31_t)0x7280d4f9, (q31_t)0x727e05e9, (q31_t)0x727b3693, (q31_t)0x727866f6, (q31_t)0x72759712, (q31_t)0x7272c6e7, (q31_t)0x726ff676, (q31_t)0x726d25bf, + (q31_t)0x726a54c1, (q31_t)0x7267837c, (q31_t)0x7264b1f0, (q31_t)0x7261e01e, (q31_t)0x725f0e06, (q31_t)0x725c3ba7, (q31_t)0x72596901, (q31_t)0x72569615, + (q31_t)0x7253c2e3, (q31_t)0x7250ef6a, (q31_t)0x724e1baa, (q31_t)0x724b47a4, (q31_t)0x72487357, (q31_t)0x72459ec4, (q31_t)0x7242c9ea, (q31_t)0x723ff4ca, + (q31_t)0x723d1f63, (q31_t)0x723a49b6, (q31_t)0x723773c3, (q31_t)0x72349d89, (q31_t)0x7231c708, (q31_t)0x722ef041, (q31_t)0x722c1934, (q31_t)0x722941e0, + (q31_t)0x72266a46, (q31_t)0x72239266, (q31_t)0x7220ba3f, (q31_t)0x721de1d1, (q31_t)0x721b091d, (q31_t)0x72183023, (q31_t)0x721556e3, (q31_t)0x72127d5c, + (q31_t)0x720fa38e, (q31_t)0x720cc97b, (q31_t)0x7209ef21, (q31_t)0x72071480, (q31_t)0x7204399a, (q31_t)0x72015e6d, (q31_t)0x71fe82f9, (q31_t)0x71fba740, + (q31_t)0x71f8cb40, (q31_t)0x71f5eefa, (q31_t)0x71f3126d, (q31_t)0x71f0359a, (q31_t)0x71ed5881, (q31_t)0x71ea7b22, (q31_t)0x71e79d7c, (q31_t)0x71e4bf90, + (q31_t)0x71e1e15e, (q31_t)0x71df02e5, (q31_t)0x71dc2427, (q31_t)0x71d94522, (q31_t)0x71d665d6, (q31_t)0x71d38645, (q31_t)0x71d0a66d, (q31_t)0x71cdc650, + (q31_t)0x71cae5ec, (q31_t)0x71c80542, (q31_t)0x71c52451, (q31_t)0x71c2431b, (q31_t)0x71bf619e, (q31_t)0x71bc7fdb, (q31_t)0x71b99dd2, (q31_t)0x71b6bb83, + (q31_t)0x71b3d8ed, (q31_t)0x71b0f612, (q31_t)0x71ae12f0, (q31_t)0x71ab2f89, (q31_t)0x71a84bdb, (q31_t)0x71a567e7, (q31_t)0x71a283ad, (q31_t)0x719f9f2c, + (q31_t)0x719cba66, (q31_t)0x7199d55a, (q31_t)0x7196f008, (q31_t)0x71940a6f, (q31_t)0x71912490, (q31_t)0x718e3e6c, (q31_t)0x718b5801, (q31_t)0x71887151, + (q31_t)0x71858a5a, (q31_t)0x7182a31d, (q31_t)0x717fbb9a, (q31_t)0x717cd3d2, (q31_t)0x7179ebc3, (q31_t)0x7177036e, (q31_t)0x71741ad3, (q31_t)0x717131f3, + (q31_t)0x716e48cc, (q31_t)0x716b5f5f, (q31_t)0x716875ad, (q31_t)0x71658bb4, (q31_t)0x7162a175, (q31_t)0x715fb6f1, (q31_t)0x715ccc26, (q31_t)0x7159e116, + (q31_t)0x7156f5c0, (q31_t)0x71540a24, (q31_t)0x71511e42, (q31_t)0x714e321a, (q31_t)0x714b45ac, (q31_t)0x714858f8, (q31_t)0x71456bfe, (q31_t)0x71427ebf, + (q31_t)0x713f9139, (q31_t)0x713ca36e, (q31_t)0x7139b55d, (q31_t)0x7136c706, (q31_t)0x7133d869, (q31_t)0x7130e987, (q31_t)0x712dfa5e, (q31_t)0x712b0af0, + (q31_t)0x71281b3c, (q31_t)0x71252b42, (q31_t)0x71223b02, (q31_t)0x711f4a7d, (q31_t)0x711c59b2, (q31_t)0x711968a1, (q31_t)0x7116774a, (q31_t)0x711385ad, + (q31_t)0x711093cb, (q31_t)0x710da1a3, (q31_t)0x710aaf35, (q31_t)0x7107bc82, (q31_t)0x7104c989, (q31_t)0x7101d64a, (q31_t)0x70fee2c5, (q31_t)0x70fbeefb, + (q31_t)0x70f8faeb, (q31_t)0x70f60695, (q31_t)0x70f311fa, (q31_t)0x70f01d19, (q31_t)0x70ed27f2, (q31_t)0x70ea3286, (q31_t)0x70e73cd4, (q31_t)0x70e446dc, + (q31_t)0x70e1509f, (q31_t)0x70de5a1c, (q31_t)0x70db6353, (q31_t)0x70d86c45, (q31_t)0x70d574f1, (q31_t)0x70d27d58, (q31_t)0x70cf8579, (q31_t)0x70cc8d54, + (q31_t)0x70c994ea, (q31_t)0x70c69c3a, (q31_t)0x70c3a345, (q31_t)0x70c0aa0a, (q31_t)0x70bdb08a, (q31_t)0x70bab6c4, (q31_t)0x70b7bcb8, (q31_t)0x70b4c267, + (q31_t)0x70b1c7d1, (q31_t)0x70aeccf5, (q31_t)0x70abd1d3, (q31_t)0x70a8d66c, (q31_t)0x70a5dac0, (q31_t)0x70a2dece, (q31_t)0x709fe296, (q31_t)0x709ce619, + (q31_t)0x7099e957, (q31_t)0x7096ec4f, (q31_t)0x7093ef01, (q31_t)0x7090f16e, (q31_t)0x708df396, (q31_t)0x708af579, (q31_t)0x7087f715, (q31_t)0x7084f86d, + (q31_t)0x7081f97f, (q31_t)0x707efa4c, (q31_t)0x707bfad3, (q31_t)0x7078fb15, (q31_t)0x7075fb11, (q31_t)0x7072fac9, (q31_t)0x706ffa3a, (q31_t)0x706cf967, + (q31_t)0x7069f84e, (q31_t)0x7066f6f0, (q31_t)0x7063f54c, (q31_t)0x7060f363, (q31_t)0x705df135, (q31_t)0x705aeec1, (q31_t)0x7057ec08, (q31_t)0x7054e90a, + (q31_t)0x7051e5c7, (q31_t)0x704ee23e, (q31_t)0x704bde70, (q31_t)0x7048da5d, (q31_t)0x7045d604, (q31_t)0x7042d166, (q31_t)0x703fcc83, (q31_t)0x703cc75b, + (q31_t)0x7039c1ed, (q31_t)0x7036bc3b, (q31_t)0x7033b643, (q31_t)0x7030b005, (q31_t)0x702da983, (q31_t)0x702aa2bb, (q31_t)0x70279baf, (q31_t)0x7024945d, + (q31_t)0x70218cc6, (q31_t)0x701e84e9, (q31_t)0x701b7cc8, (q31_t)0x70187461, (q31_t)0x70156bb5, (q31_t)0x701262c4, (q31_t)0x700f598e, (q31_t)0x700c5013, + (q31_t)0x70094653, (q31_t)0x70063c4e, (q31_t)0x70033203, (q31_t)0x70002774, (q31_t)0x6ffd1c9f, (q31_t)0x6ffa1185, (q31_t)0x6ff70626, (q31_t)0x6ff3fa82, + (q31_t)0x6ff0ee99, (q31_t)0x6fede26b, (q31_t)0x6fead5f8, (q31_t)0x6fe7c940, (q31_t)0x6fe4bc43, (q31_t)0x6fe1af01, (q31_t)0x6fdea17a, (q31_t)0x6fdb93ae, + (q31_t)0x6fd8859d, (q31_t)0x6fd57746, (q31_t)0x6fd268ab, (q31_t)0x6fcf59cb, (q31_t)0x6fcc4aa6, (q31_t)0x6fc93b3c, (q31_t)0x6fc62b8d, (q31_t)0x6fc31b99, + (q31_t)0x6fc00b60, (q31_t)0x6fbcfae2, (q31_t)0x6fb9ea20, (q31_t)0x6fb6d918, (q31_t)0x6fb3c7cb, (q31_t)0x6fb0b63a, (q31_t)0x6fada464, (q31_t)0x6faa9248, + (q31_t)0x6fa77fe8, (q31_t)0x6fa46d43, (q31_t)0x6fa15a59, (q31_t)0x6f9e472b, (q31_t)0x6f9b33b7, (q31_t)0x6f981fff, (q31_t)0x6f950c01, (q31_t)0x6f91f7bf, + (q31_t)0x6f8ee338, (q31_t)0x6f8bce6c, (q31_t)0x6f88b95c, (q31_t)0x6f85a407, (q31_t)0x6f828e6c, (q31_t)0x6f7f788d, (q31_t)0x6f7c626a, (q31_t)0x6f794c01, + (q31_t)0x6f763554, (q31_t)0x6f731e62, (q31_t)0x6f70072b, (q31_t)0x6f6cefb0, (q31_t)0x6f69d7f0, (q31_t)0x6f66bfeb, (q31_t)0x6f63a7a1, (q31_t)0x6f608f13, + (q31_t)0x6f5d7640, (q31_t)0x6f5a5d28, (q31_t)0x6f5743cb, (q31_t)0x6f542a2a, (q31_t)0x6f511044, (q31_t)0x6f4df61a, (q31_t)0x6f4adbab, (q31_t)0x6f47c0f7, + (q31_t)0x6f44a5ff, (q31_t)0x6f418ac2, (q31_t)0x6f3e6f40, (q31_t)0x6f3b537a, (q31_t)0x6f38376f, (q31_t)0x6f351b1f, (q31_t)0x6f31fe8b, (q31_t)0x6f2ee1b2, + (q31_t)0x6f2bc495, (q31_t)0x6f28a733, (q31_t)0x6f25898d, (q31_t)0x6f226ba2, (q31_t)0x6f1f4d72, (q31_t)0x6f1c2efe, (q31_t)0x6f191045, (q31_t)0x6f15f148, + (q31_t)0x6f12d206, (q31_t)0x6f0fb280, (q31_t)0x6f0c92b6, (q31_t)0x6f0972a6, (q31_t)0x6f065253, (q31_t)0x6f0331ba, (q31_t)0x6f0010de, (q31_t)0x6efcefbd, + (q31_t)0x6ef9ce57, (q31_t)0x6ef6acad, (q31_t)0x6ef38abe, (q31_t)0x6ef0688b, (q31_t)0x6eed4614, (q31_t)0x6eea2358, (q31_t)0x6ee70058, (q31_t)0x6ee3dd13, + (q31_t)0x6ee0b98a, (q31_t)0x6edd95bd, (q31_t)0x6eda71ab, (q31_t)0x6ed74d55, (q31_t)0x6ed428ba, (q31_t)0x6ed103db, (q31_t)0x6ecddeb8, (q31_t)0x6ecab950, + (q31_t)0x6ec793a4, (q31_t)0x6ec46db4, (q31_t)0x6ec1477f, (q31_t)0x6ebe2106, (q31_t)0x6ebafa49, (q31_t)0x6eb7d347, (q31_t)0x6eb4ac02, (q31_t)0x6eb18477, + (q31_t)0x6eae5ca9, (q31_t)0x6eab3496, (q31_t)0x6ea80c3f, (q31_t)0x6ea4e3a4, (q31_t)0x6ea1bac4, (q31_t)0x6e9e91a1, (q31_t)0x6e9b6839, (q31_t)0x6e983e8d, + (q31_t)0x6e95149c, (q31_t)0x6e91ea67, (q31_t)0x6e8ebfef, (q31_t)0x6e8b9532, (q31_t)0x6e886a30, (q31_t)0x6e853eeb, (q31_t)0x6e821361, (q31_t)0x6e7ee794, + (q31_t)0x6e7bbb82, (q31_t)0x6e788f2c, (q31_t)0x6e756291, (q31_t)0x6e7235b3, (q31_t)0x6e6f0890, (q31_t)0x6e6bdb2a, (q31_t)0x6e68ad7f, (q31_t)0x6e657f90, + (q31_t)0x6e62515d, (q31_t)0x6e5f22e6, (q31_t)0x6e5bf42b, (q31_t)0x6e58c52c, (q31_t)0x6e5595e9, (q31_t)0x6e526662, (q31_t)0x6e4f3696, (q31_t)0x6e4c0687, + (q31_t)0x6e48d633, (q31_t)0x6e45a59c, (q31_t)0x6e4274c1, (q31_t)0x6e3f43a1, (q31_t)0x6e3c123e, (q31_t)0x6e38e096, (q31_t)0x6e35aeab, (q31_t)0x6e327c7b, + (q31_t)0x6e2f4a08, (q31_t)0x6e2c1750, (q31_t)0x6e28e455, (q31_t)0x6e25b115, (q31_t)0x6e227d92, (q31_t)0x6e1f49cb, (q31_t)0x6e1c15c0, (q31_t)0x6e18e171, + (q31_t)0x6e15acde, (q31_t)0x6e127807, (q31_t)0x6e0f42ec, (q31_t)0x6e0c0d8e, (q31_t)0x6e08d7eb, (q31_t)0x6e05a205, (q31_t)0x6e026bda, (q31_t)0x6dff356c, + (q31_t)0x6dfbfeba, (q31_t)0x6df8c7c4, (q31_t)0x6df5908b, (q31_t)0x6df2590d, (q31_t)0x6def214c, (q31_t)0x6debe947, (q31_t)0x6de8b0fe, (q31_t)0x6de57871, + (q31_t)0x6de23fa0, (q31_t)0x6ddf068c, (q31_t)0x6ddbcd34, (q31_t)0x6dd89398, (q31_t)0x6dd559b9, (q31_t)0x6dd21f95, (q31_t)0x6dcee52e, (q31_t)0x6dcbaa83, + (q31_t)0x6dc86f95, (q31_t)0x6dc53462, (q31_t)0x6dc1f8ec, (q31_t)0x6dbebd33, (q31_t)0x6dbb8135, (q31_t)0x6db844f4, (q31_t)0x6db5086f, (q31_t)0x6db1cba7, + (q31_t)0x6dae8e9b, (q31_t)0x6dab514b, (q31_t)0x6da813b8, (q31_t)0x6da4d5e1, (q31_t)0x6da197c6, (q31_t)0x6d9e5968, (q31_t)0x6d9b1ac6, (q31_t)0x6d97dbe0, + (q31_t)0x6d949cb7, (q31_t)0x6d915d4a, (q31_t)0x6d8e1d9a, (q31_t)0x6d8adda6, (q31_t)0x6d879d6e, (q31_t)0x6d845cf3, (q31_t)0x6d811c35, (q31_t)0x6d7ddb33, + (q31_t)0x6d7a99ed, (q31_t)0x6d775864, (q31_t)0x6d741697, (q31_t)0x6d70d487, (q31_t)0x6d6d9233, (q31_t)0x6d6a4f9c, (q31_t)0x6d670cc1, (q31_t)0x6d63c9a3, + (q31_t)0x6d608641, (q31_t)0x6d5d429c, (q31_t)0x6d59feb3, (q31_t)0x6d56ba87, (q31_t)0x6d537617, (q31_t)0x6d503164, (q31_t)0x6d4cec6e, (q31_t)0x6d49a734, + (q31_t)0x6d4661b7, (q31_t)0x6d431bf6, (q31_t)0x6d3fd5f2, (q31_t)0x6d3c8fab, (q31_t)0x6d394920, (q31_t)0x6d360252, (q31_t)0x6d32bb40, (q31_t)0x6d2f73eb, + (q31_t)0x6d2c2c53, (q31_t)0x6d28e477, (q31_t)0x6d259c58, (q31_t)0x6d2253f6, (q31_t)0x6d1f0b50, (q31_t)0x6d1bc267, (q31_t)0x6d18793b, (q31_t)0x6d152fcc, + (q31_t)0x6d11e619, (q31_t)0x6d0e9c23, (q31_t)0x6d0b51e9, (q31_t)0x6d08076d, (q31_t)0x6d04bcad, (q31_t)0x6d0171aa, (q31_t)0x6cfe2663, (q31_t)0x6cfadada, + (q31_t)0x6cf78f0d, (q31_t)0x6cf442fd, (q31_t)0x6cf0f6aa, (q31_t)0x6cedaa13, (q31_t)0x6cea5d3a, (q31_t)0x6ce7101d, (q31_t)0x6ce3c2bd, (q31_t)0x6ce0751a, + (q31_t)0x6cdd2733, (q31_t)0x6cd9d90a, (q31_t)0x6cd68a9d, (q31_t)0x6cd33bed, (q31_t)0x6ccfecfa, (q31_t)0x6ccc9dc4, (q31_t)0x6cc94e4b, (q31_t)0x6cc5fe8f, + (q31_t)0x6cc2ae90, (q31_t)0x6cbf5e4d, (q31_t)0x6cbc0dc8, (q31_t)0x6cb8bcff, (q31_t)0x6cb56bf4, (q31_t)0x6cb21aa5, (q31_t)0x6caec913, (q31_t)0x6cab773e, + (q31_t)0x6ca82527, (q31_t)0x6ca4d2cc, (q31_t)0x6ca1802e, (q31_t)0x6c9e2d4d, (q31_t)0x6c9ada29, (q31_t)0x6c9786c2, (q31_t)0x6c943318, (q31_t)0x6c90df2c, + (q31_t)0x6c8d8afc, (q31_t)0x6c8a3689, (q31_t)0x6c86e1d3, (q31_t)0x6c838cdb, (q31_t)0x6c80379f, (q31_t)0x6c7ce220, (q31_t)0x6c798c5f, (q31_t)0x6c76365b, + (q31_t)0x6c72e013, (q31_t)0x6c6f8989, (q31_t)0x6c6c32bc, (q31_t)0x6c68dbac, (q31_t)0x6c658459, (q31_t)0x6c622cc4, (q31_t)0x6c5ed4eb, (q31_t)0x6c5b7cd0, + (q31_t)0x6c582472, (q31_t)0x6c54cbd1, (q31_t)0x6c5172ed, (q31_t)0x6c4e19c6, (q31_t)0x6c4ac05d, (q31_t)0x6c4766b0, (q31_t)0x6c440cc1, (q31_t)0x6c40b28f, + (q31_t)0x6c3d581b, (q31_t)0x6c39fd63, (q31_t)0x6c36a269, (q31_t)0x6c33472c, (q31_t)0x6c2febad, (q31_t)0x6c2c8fea, (q31_t)0x6c2933e5, (q31_t)0x6c25d79d, + (q31_t)0x6c227b13, (q31_t)0x6c1f1e45, (q31_t)0x6c1bc136, (q31_t)0x6c1863e3, (q31_t)0x6c15064e, (q31_t)0x6c11a876, (q31_t)0x6c0e4a5b, (q31_t)0x6c0aebfe, + (q31_t)0x6c078d5e, (q31_t)0x6c042e7b, (q31_t)0x6c00cf56, (q31_t)0x6bfd6fee, (q31_t)0x6bfa1044, (q31_t)0x6bf6b056, (q31_t)0x6bf35027, (q31_t)0x6befefb5, + (q31_t)0x6bec8f00, (q31_t)0x6be92e08, (q31_t)0x6be5ccce, (q31_t)0x6be26b52, (q31_t)0x6bdf0993, (q31_t)0x6bdba791, (q31_t)0x6bd8454d, (q31_t)0x6bd4e2c6, + (q31_t)0x6bd17ffd, (q31_t)0x6bce1cf1, (q31_t)0x6bcab9a3, (q31_t)0x6bc75613, (q31_t)0x6bc3f23f, (q31_t)0x6bc08e2a, (q31_t)0x6bbd29d2, (q31_t)0x6bb9c537, + (q31_t)0x6bb6605a, (q31_t)0x6bb2fb3b, (q31_t)0x6baf95d9, (q31_t)0x6bac3034, (q31_t)0x6ba8ca4e, (q31_t)0x6ba56425, (q31_t)0x6ba1fdb9, (q31_t)0x6b9e970b, + (q31_t)0x6b9b301b, (q31_t)0x6b97c8e8, (q31_t)0x6b946173, (q31_t)0x6b90f9bc, (q31_t)0x6b8d91c2, (q31_t)0x6b8a2986, (q31_t)0x6b86c107, (q31_t)0x6b835846, + (q31_t)0x6b7fef43, (q31_t)0x6b7c85fe, (q31_t)0x6b791c76, (q31_t)0x6b75b2ac, (q31_t)0x6b7248a0, (q31_t)0x6b6ede51, (q31_t)0x6b6b73c0, (q31_t)0x6b6808ed, + (q31_t)0x6b649dd8, (q31_t)0x6b613280, (q31_t)0x6b5dc6e6, (q31_t)0x6b5a5b0a, (q31_t)0x6b56eeec, (q31_t)0x6b53828b, (q31_t)0x6b5015e9, (q31_t)0x6b4ca904, + (q31_t)0x6b493bdd, (q31_t)0x6b45ce73, (q31_t)0x6b4260c8, (q31_t)0x6b3ef2da, (q31_t)0x6b3b84ab, (q31_t)0x6b381639, (q31_t)0x6b34a785, (q31_t)0x6b31388e, + (q31_t)0x6b2dc956, (q31_t)0x6b2a59dc, (q31_t)0x6b26ea1f, (q31_t)0x6b237a21, (q31_t)0x6b2009e0, (q31_t)0x6b1c995d, (q31_t)0x6b192898, (q31_t)0x6b15b791, + (q31_t)0x6b124648, (q31_t)0x6b0ed4bd, (q31_t)0x6b0b62f0, (q31_t)0x6b07f0e1, (q31_t)0x6b047e90, (q31_t)0x6b010bfd, (q31_t)0x6afd9928, (q31_t)0x6afa2610, + (q31_t)0x6af6b2b7, (q31_t)0x6af33f1c, (q31_t)0x6aefcb3f, (q31_t)0x6aec5720, (q31_t)0x6ae8e2bf, (q31_t)0x6ae56e1c, (q31_t)0x6ae1f937, (q31_t)0x6ade8410, + (q31_t)0x6adb0ea8, (q31_t)0x6ad798fd, (q31_t)0x6ad42311, (q31_t)0x6ad0ace2, (q31_t)0x6acd3672, (q31_t)0x6ac9bfc0, (q31_t)0x6ac648cb, (q31_t)0x6ac2d195, + (q31_t)0x6abf5a1e, (q31_t)0x6abbe264, (q31_t)0x6ab86a68, (q31_t)0x6ab4f22b, (q31_t)0x6ab179ac, (q31_t)0x6aae00eb, (q31_t)0x6aaa87e8, (q31_t)0x6aa70ea4, + (q31_t)0x6aa3951d, (q31_t)0x6aa01b55, (q31_t)0x6a9ca14b, (q31_t)0x6a992700, (q31_t)0x6a95ac72, (q31_t)0x6a9231a3, (q31_t)0x6a8eb692, (q31_t)0x6a8b3b3f, + (q31_t)0x6a87bfab, (q31_t)0x6a8443d5, (q31_t)0x6a80c7bd, (q31_t)0x6a7d4b64, (q31_t)0x6a79cec8, (q31_t)0x6a7651ec, (q31_t)0x6a72d4cd, (q31_t)0x6a6f576d, + (q31_t)0x6a6bd9cb, (q31_t)0x6a685be8, (q31_t)0x6a64ddc2, (q31_t)0x6a615f5c, (q31_t)0x6a5de0b3, (q31_t)0x6a5a61c9, (q31_t)0x6a56e29e, (q31_t)0x6a536331, + (q31_t)0x6a4fe382, (q31_t)0x6a4c6391, (q31_t)0x6a48e360, (q31_t)0x6a4562ec, (q31_t)0x6a41e237, (q31_t)0x6a3e6140, (q31_t)0x6a3ae008, (q31_t)0x6a375e8f, + (q31_t)0x6a33dcd4, (q31_t)0x6a305ad7, (q31_t)0x6a2cd899, (q31_t)0x6a295619, (q31_t)0x6a25d358, (q31_t)0x6a225055, (q31_t)0x6a1ecd11, (q31_t)0x6a1b498c, + (q31_t)0x6a17c5c5, (q31_t)0x6a1441bc, (q31_t)0x6a10bd72, (q31_t)0x6a0d38e7, (q31_t)0x6a09b41a, (q31_t)0x6a062f0c, (q31_t)0x6a02a9bc, (q31_t)0x69ff242b, + (q31_t)0x69fb9e59, (q31_t)0x69f81845, (q31_t)0x69f491f0, (q31_t)0x69f10b5a, (q31_t)0x69ed8482, (q31_t)0x69e9fd69, (q31_t)0x69e6760f, (q31_t)0x69e2ee73, + (q31_t)0x69df6696, (q31_t)0x69dbde77, (q31_t)0x69d85618, (q31_t)0x69d4cd77, (q31_t)0x69d14494, (q31_t)0x69cdbb71, (q31_t)0x69ca320c, (q31_t)0x69c6a866, + (q31_t)0x69c31e7f, (q31_t)0x69bf9456, (q31_t)0x69bc09ec, (q31_t)0x69b87f41, (q31_t)0x69b4f455, (q31_t)0x69b16928, (q31_t)0x69adddb9, (q31_t)0x69aa5209, + (q31_t)0x69a6c618, (q31_t)0x69a339e6, (q31_t)0x699fad73, (q31_t)0x699c20be, (q31_t)0x699893c9, (q31_t)0x69950692, (q31_t)0x6991791a, (q31_t)0x698deb61, + (q31_t)0x698a5d67, (q31_t)0x6986cf2c, (q31_t)0x698340af, (q31_t)0x697fb1f2, (q31_t)0x697c22f3, (q31_t)0x697893b4, (q31_t)0x69750433, (q31_t)0x69717472, + (q31_t)0x696de46f, (q31_t)0x696a542b, (q31_t)0x6966c3a6, (q31_t)0x696332e1, (q31_t)0x695fa1da, (q31_t)0x695c1092, (q31_t)0x69587f09, (q31_t)0x6954ed40, + (q31_t)0x69515b35, (q31_t)0x694dc8e9, (q31_t)0x694a365c, (q31_t)0x6946a38f, (q31_t)0x69431080, (q31_t)0x693f7d31, (q31_t)0x693be9a0, (q31_t)0x693855cf, + (q31_t)0x6934c1bd, (q31_t)0x69312d6a, (q31_t)0x692d98d6, (q31_t)0x692a0401, (q31_t)0x69266eeb, (q31_t)0x6922d995, (q31_t)0x691f43fd, (q31_t)0x691bae25, + (q31_t)0x6918180c, (q31_t)0x691481b2, (q31_t)0x6910eb17, (q31_t)0x690d543b, (q31_t)0x6909bd1f, (q31_t)0x690625c2, (q31_t)0x69028e24, (q31_t)0x68fef645, + (q31_t)0x68fb5e25, (q31_t)0x68f7c5c5, (q31_t)0x68f42d24, (q31_t)0x68f09442, (q31_t)0x68ecfb20, (q31_t)0x68e961bd, (q31_t)0x68e5c819, (q31_t)0x68e22e34, + (q31_t)0x68de940f, (q31_t)0x68daf9a9, (q31_t)0x68d75f02, (q31_t)0x68d3c41b, (q31_t)0x68d028f2, (q31_t)0x68cc8d8a, (q31_t)0x68c8f1e0, (q31_t)0x68c555f6, + (q31_t)0x68c1b9cc, (q31_t)0x68be1d61, (q31_t)0x68ba80b5, (q31_t)0x68b6e3c8, (q31_t)0x68b3469b, (q31_t)0x68afa92e, (q31_t)0x68ac0b7f, (q31_t)0x68a86d91, + (q31_t)0x68a4cf61, (q31_t)0x68a130f1, (q31_t)0x689d9241, (q31_t)0x6899f350, (q31_t)0x6896541f, (q31_t)0x6892b4ad, (q31_t)0x688f14fa, (q31_t)0x688b7507, + (q31_t)0x6887d4d4, (q31_t)0x68843460, (q31_t)0x688093ab, (q31_t)0x687cf2b6, (q31_t)0x68795181, (q31_t)0x6875b00b, (q31_t)0x68720e55, (q31_t)0x686e6c5e, + (q31_t)0x686aca27, (q31_t)0x686727b0, (q31_t)0x686384f8, (q31_t)0x685fe200, (q31_t)0x685c3ec7, (q31_t)0x68589b4e, (q31_t)0x6854f795, (q31_t)0x6851539b, + (q31_t)0x684daf61, (q31_t)0x684a0ae6, (q31_t)0x6846662c, (q31_t)0x6842c131, (q31_t)0x683f1bf5, (q31_t)0x683b7679, (q31_t)0x6837d0bd, (q31_t)0x68342ac1, + (q31_t)0x68308485, (q31_t)0x682cde08, (q31_t)0x6829374b, (q31_t)0x6825904d, (q31_t)0x6821e910, (q31_t)0x681e4192, (q31_t)0x681a99d4, (q31_t)0x6816f1d6, + (q31_t)0x68134997, (q31_t)0x680fa118, (q31_t)0x680bf85a, (q31_t)0x68084f5a, (q31_t)0x6804a61b, (q31_t)0x6800fc9c, (q31_t)0x67fd52dc, (q31_t)0x67f9a8dd, + (q31_t)0x67f5fe9d, (q31_t)0x67f2541d, (q31_t)0x67eea95d, (q31_t)0x67eafe5d, (q31_t)0x67e7531c, (q31_t)0x67e3a79c, (q31_t)0x67dffbdc, (q31_t)0x67dc4fdb, + (q31_t)0x67d8a39a, (q31_t)0x67d4f71a, (q31_t)0x67d14a59, (q31_t)0x67cd9d58, (q31_t)0x67c9f017, (q31_t)0x67c64297, (q31_t)0x67c294d6, (q31_t)0x67bee6d5, + (q31_t)0x67bb3894, (q31_t)0x67b78a13, (q31_t)0x67b3db53, (q31_t)0x67b02c52, (q31_t)0x67ac7d11, (q31_t)0x67a8cd91, (q31_t)0x67a51dd0, (q31_t)0x67a16dcf, + (q31_t)0x679dbd8f, (q31_t)0x679a0d0f, (q31_t)0x67965c4e, (q31_t)0x6792ab4e, (q31_t)0x678efa0e, (q31_t)0x678b488e, (q31_t)0x678796ce, (q31_t)0x6783e4cf, + (q31_t)0x6780328f, (q31_t)0x677c8010, (q31_t)0x6778cd50, (q31_t)0x67751a51, (q31_t)0x67716713, (q31_t)0x676db394, (q31_t)0x6769ffd5, (q31_t)0x67664bd7, + (q31_t)0x67629799, (q31_t)0x675ee31b, (q31_t)0x675b2e5e, (q31_t)0x67577960, (q31_t)0x6753c423, (q31_t)0x67500ea7, (q31_t)0x674c58ea, (q31_t)0x6748a2ee, + (q31_t)0x6744ecb2, (q31_t)0x67413636, (q31_t)0x673d7f7b, (q31_t)0x6739c880, (q31_t)0x67361145, (q31_t)0x673259ca, (q31_t)0x672ea210, (q31_t)0x672aea17, + (q31_t)0x672731dd, (q31_t)0x67237964, (q31_t)0x671fc0ac, (q31_t)0x671c07b4, (q31_t)0x67184e7c, (q31_t)0x67149504, (q31_t)0x6710db4d, (q31_t)0x670d2157, + (q31_t)0x67096721, (q31_t)0x6705acab, (q31_t)0x6701f1f6, (q31_t)0x66fe3701, (q31_t)0x66fa7bcd, (q31_t)0x66f6c059, (q31_t)0x66f304a6, (q31_t)0x66ef48b3, + (q31_t)0x66eb8c80, (q31_t)0x66e7d00f, (q31_t)0x66e4135d, (q31_t)0x66e0566c, (q31_t)0x66dc993c, (q31_t)0x66d8dbcd, (q31_t)0x66d51e1d, (q31_t)0x66d1602f, + (q31_t)0x66cda201, (q31_t)0x66c9e393, (q31_t)0x66c624e7, (q31_t)0x66c265fa, (q31_t)0x66bea6cf, (q31_t)0x66bae764, (q31_t)0x66b727ba, (q31_t)0x66b367d0, + (q31_t)0x66afa7a7, (q31_t)0x66abe73f, (q31_t)0x66a82697, (q31_t)0x66a465b0, (q31_t)0x66a0a489, (q31_t)0x669ce324, (q31_t)0x6699217f, (q31_t)0x66955f9b, + (q31_t)0x66919d77, (q31_t)0x668ddb14, (q31_t)0x668a1872, (q31_t)0x66865591, (q31_t)0x66829270, (q31_t)0x667ecf11, (q31_t)0x667b0b72, (q31_t)0x66774793, + (q31_t)0x66738376, (q31_t)0x666fbf19, (q31_t)0x666bfa7d, (q31_t)0x666835a2, (q31_t)0x66647088, (q31_t)0x6660ab2f, (q31_t)0x665ce596, (q31_t)0x66591fbf, + (q31_t)0x665559a8, (q31_t)0x66519352, (q31_t)0x664dccbd, (q31_t)0x664a05e9, (q31_t)0x66463ed6, (q31_t)0x66427784, (q31_t)0x663eaff2, (q31_t)0x663ae822, + (q31_t)0x66372012, (q31_t)0x663357c4, (q31_t)0x662f8f36, (q31_t)0x662bc66a, (q31_t)0x6627fd5e, (q31_t)0x66243413, (q31_t)0x66206a8a, (q31_t)0x661ca0c1, + (q31_t)0x6618d6b9, (q31_t)0x66150c73, (q31_t)0x661141ed, (q31_t)0x660d7729, (q31_t)0x6609ac25, (q31_t)0x6605e0e3, (q31_t)0x66021561, (q31_t)0x65fe49a1, + (q31_t)0x65fa7da2, (q31_t)0x65f6b164, (q31_t)0x65f2e4e7, (q31_t)0x65ef182b, (q31_t)0x65eb4b30, (q31_t)0x65e77df6, (q31_t)0x65e3b07e, (q31_t)0x65dfe2c6, + (q31_t)0x65dc14d0, (q31_t)0x65d8469b, (q31_t)0x65d47827, (q31_t)0x65d0a975, (q31_t)0x65ccda83, (q31_t)0x65c90b53, (q31_t)0x65c53be4, (q31_t)0x65c16c36, + (q31_t)0x65bd9c49, (q31_t)0x65b9cc1e, (q31_t)0x65b5fbb4, (q31_t)0x65b22b0b, (q31_t)0x65ae5a23, (q31_t)0x65aa88fd, (q31_t)0x65a6b798, (q31_t)0x65a2e5f4, + (q31_t)0x659f1412, (q31_t)0x659b41f1, (q31_t)0x65976f91, (q31_t)0x65939cf3, (q31_t)0x658fca15, (q31_t)0x658bf6fa, (q31_t)0x6588239f, (q31_t)0x65845006, + (q31_t)0x65807c2f, (q31_t)0x657ca818, (q31_t)0x6578d3c4, (q31_t)0x6574ff30, (q31_t)0x65712a5e, (q31_t)0x656d554d, (q31_t)0x65697ffe, (q31_t)0x6565aa71, + (q31_t)0x6561d4a4, (q31_t)0x655dfe99, (q31_t)0x655a2850, (q31_t)0x655651c8, (q31_t)0x65527b02, (q31_t)0x654ea3fd, (q31_t)0x654accba, (q31_t)0x6546f538, + (q31_t)0x65431d77, (q31_t)0x653f4579, (q31_t)0x653b6d3b, (q31_t)0x653794c0, (q31_t)0x6533bc06, (q31_t)0x652fe30d, (q31_t)0x652c09d6, (q31_t)0x65283061, + (q31_t)0x652456ad, (q31_t)0x65207cbb, (q31_t)0x651ca28a, (q31_t)0x6518c81b, (q31_t)0x6514ed6e, (q31_t)0x65111283, (q31_t)0x650d3759, (q31_t)0x65095bf0, + (q31_t)0x6505804a, (q31_t)0x6501a465, (q31_t)0x64fdc841, (q31_t)0x64f9ebe0, (q31_t)0x64f60f40, (q31_t)0x64f23262, (q31_t)0x64ee5546, (q31_t)0x64ea77eb, + (q31_t)0x64e69a52, (q31_t)0x64e2bc7b, (q31_t)0x64dede66, (q31_t)0x64db0012, (q31_t)0x64d72180, (q31_t)0x64d342b0, (q31_t)0x64cf63a2, (q31_t)0x64cb8456, + (q31_t)0x64c7a4cb, (q31_t)0x64c3c502, (q31_t)0x64bfe4fc, (q31_t)0x64bc04b6, (q31_t)0x64b82433, (q31_t)0x64b44372, (q31_t)0x64b06273, (q31_t)0x64ac8135, + (q31_t)0x64a89fba, (q31_t)0x64a4be00, (q31_t)0x64a0dc08, (q31_t)0x649cf9d2, (q31_t)0x6499175e, (q31_t)0x649534ac, (q31_t)0x649151bc, (q31_t)0x648d6e8e, + (q31_t)0x64898b22, (q31_t)0x6485a778, (q31_t)0x6481c390, (q31_t)0x647ddf6a, (q31_t)0x6479fb06, (q31_t)0x64761664, (q31_t)0x64723184, (q31_t)0x646e4c66, + (q31_t)0x646a670a, (q31_t)0x64668170, (q31_t)0x64629b98, (q31_t)0x645eb582, (q31_t)0x645acf2e, (q31_t)0x6456e89d, (q31_t)0x645301cd, (q31_t)0x644f1ac0, + (q31_t)0x644b3375, (q31_t)0x64474bec, (q31_t)0x64436425, (q31_t)0x643f7c20, (q31_t)0x643b93dd, (q31_t)0x6437ab5d, (q31_t)0x6433c29f, (q31_t)0x642fd9a3, + (q31_t)0x642bf069, (q31_t)0x642806f1, (q31_t)0x64241d3c, (q31_t)0x64203348, (q31_t)0x641c4917, (q31_t)0x64185ea9, (q31_t)0x641473fc, (q31_t)0x64108912, + (q31_t)0x640c9dea, (q31_t)0x6408b284, (q31_t)0x6404c6e1, (q31_t)0x6400db00, (q31_t)0x63fceee1, (q31_t)0x63f90285, (q31_t)0x63f515eb, (q31_t)0x63f12913, + (q31_t)0x63ed3bfd, (q31_t)0x63e94eaa, (q31_t)0x63e5611a, (q31_t)0x63e1734b, (q31_t)0x63dd853f, (q31_t)0x63d996f6, (q31_t)0x63d5a86f, (q31_t)0x63d1b9aa, + (q31_t)0x63cdcaa8, (q31_t)0x63c9db68, (q31_t)0x63c5ebeb, (q31_t)0x63c1fc30, (q31_t)0x63be0c37, (q31_t)0x63ba1c01, (q31_t)0x63b62b8e, (q31_t)0x63b23add, + (q31_t)0x63ae49ee, (q31_t)0x63aa58c2, (q31_t)0x63a66759, (q31_t)0x63a275b2, (q31_t)0x639e83cd, (q31_t)0x639a91ac, (q31_t)0x63969f4c, (q31_t)0x6392acaf, + (q31_t)0x638eb9d5, (q31_t)0x638ac6be, (q31_t)0x6386d369, (q31_t)0x6382dfd6, (q31_t)0x637eec07, (q31_t)0x637af7fa, (q31_t)0x637703af, (q31_t)0x63730f27, + (q31_t)0x636f1a62, (q31_t)0x636b2560, (q31_t)0x63673020, (q31_t)0x63633aa3, (q31_t)0x635f44e8, (q31_t)0x635b4ef0, (q31_t)0x635758bb, (q31_t)0x63536249, + (q31_t)0x634f6b99, (q31_t)0x634b74ad, (q31_t)0x63477d82, (q31_t)0x6343861b, (q31_t)0x633f8e76, (q31_t)0x633b9695, (q31_t)0x63379e76, (q31_t)0x6333a619, + (q31_t)0x632fad80, (q31_t)0x632bb4a9, (q31_t)0x6327bb96, (q31_t)0x6323c245, (q31_t)0x631fc8b7, (q31_t)0x631bceeb, (q31_t)0x6317d4e3, (q31_t)0x6313da9e, + (q31_t)0x630fe01b, (q31_t)0x630be55b, (q31_t)0x6307ea5e, (q31_t)0x6303ef25, (q31_t)0x62fff3ae, (q31_t)0x62fbf7fa, (q31_t)0x62f7fc08, (q31_t)0x62f3ffda, + (q31_t)0x62f0036f, (q31_t)0x62ec06c7, (q31_t)0x62e809e2, (q31_t)0x62e40cbf, (q31_t)0x62e00f60, (q31_t)0x62dc11c4, (q31_t)0x62d813eb, (q31_t)0x62d415d4, + (q31_t)0x62d01781, (q31_t)0x62cc18f1, (q31_t)0x62c81a24, (q31_t)0x62c41b1a, (q31_t)0x62c01bd3, (q31_t)0x62bc1c4f, (q31_t)0x62b81c8f, (q31_t)0x62b41c91, + (q31_t)0x62b01c57, (q31_t)0x62ac1bdf, (q31_t)0x62a81b2b, (q31_t)0x62a41a3a, (q31_t)0x62a0190c, (q31_t)0x629c17a1, (q31_t)0x629815fa, (q31_t)0x62941415, + (q31_t)0x629011f4, (q31_t)0x628c0f96, (q31_t)0x62880cfb, (q31_t)0x62840a23, (q31_t)0x6280070f, (q31_t)0x627c03be, (q31_t)0x62780030, (q31_t)0x6273fc65, + (q31_t)0x626ff85e, (q31_t)0x626bf41a, (q31_t)0x6267ef99, (q31_t)0x6263eadc, (q31_t)0x625fe5e1, (q31_t)0x625be0ab, (q31_t)0x6257db37, (q31_t)0x6253d587, + (q31_t)0x624fcf9a, (q31_t)0x624bc970, (q31_t)0x6247c30a, (q31_t)0x6243bc68, (q31_t)0x623fb588, (q31_t)0x623bae6c, (q31_t)0x6237a714, (q31_t)0x62339f7e, + (q31_t)0x622f97ad, (q31_t)0x622b8f9e, (q31_t)0x62278754, (q31_t)0x62237ecc, (q31_t)0x621f7608, (q31_t)0x621b6d08, (q31_t)0x621763cb, (q31_t)0x62135a51, + (q31_t)0x620f509b, (q31_t)0x620b46a9, (q31_t)0x62073c7a, (q31_t)0x6203320e, (q31_t)0x61ff2766, (q31_t)0x61fb1c82, (q31_t)0x61f71161, (q31_t)0x61f30604, + (q31_t)0x61eefa6b, (q31_t)0x61eaee95, (q31_t)0x61e6e282, (q31_t)0x61e2d633, (q31_t)0x61dec9a8, (q31_t)0x61dabce0, (q31_t)0x61d6afdd, (q31_t)0x61d2a29c, + (q31_t)0x61ce9520, (q31_t)0x61ca8767, (q31_t)0x61c67971, (q31_t)0x61c26b40, (q31_t)0x61be5cd2, (q31_t)0x61ba4e28, (q31_t)0x61b63f41, (q31_t)0x61b2301e, + (q31_t)0x61ae20bf, (q31_t)0x61aa1124, (q31_t)0x61a6014d, (q31_t)0x61a1f139, (q31_t)0x619de0e9, (q31_t)0x6199d05d, (q31_t)0x6195bf94, (q31_t)0x6191ae90, + (q31_t)0x618d9d4f, (q31_t)0x61898bd2, (q31_t)0x61857a19, (q31_t)0x61816824, (q31_t)0x617d55f2, (q31_t)0x61794385, (q31_t)0x617530db, (q31_t)0x61711df5, + (q31_t)0x616d0ad3, (q31_t)0x6168f775, (q31_t)0x6164e3db, (q31_t)0x6160d005, (q31_t)0x615cbbf3, (q31_t)0x6158a7a4, (q31_t)0x6154931a, (q31_t)0x61507e54, + (q31_t)0x614c6951, (q31_t)0x61485413, (q31_t)0x61443e98, (q31_t)0x614028e2, (q31_t)0x613c12f0, (q31_t)0x6137fcc1, (q31_t)0x6133e657, (q31_t)0x612fcfb0, + (q31_t)0x612bb8ce, (q31_t)0x6127a1b0, (q31_t)0x61238a56, (q31_t)0x611f72c0, (q31_t)0x611b5aee, (q31_t)0x611742e0, (q31_t)0x61132a96, (q31_t)0x610f1210, + (q31_t)0x610af94f, (q31_t)0x6106e051, (q31_t)0x6102c718, (q31_t)0x60feada3, (q31_t)0x60fa93f2, (q31_t)0x60f67a05, (q31_t)0x60f25fdd, (q31_t)0x60ee4579, + (q31_t)0x60ea2ad8, (q31_t)0x60e60ffd, (q31_t)0x60e1f4e5, (q31_t)0x60ddd991, (q31_t)0x60d9be02, (q31_t)0x60d5a237, (q31_t)0x60d18631, (q31_t)0x60cd69ee, + (q31_t)0x60c94d70, (q31_t)0x60c530b6, (q31_t)0x60c113c1, (q31_t)0x60bcf690, (q31_t)0x60b8d923, (q31_t)0x60b4bb7a, (q31_t)0x60b09d96, (q31_t)0x60ac7f76, + (q31_t)0x60a8611b, (q31_t)0x60a44284, (q31_t)0x60a023b1, (q31_t)0x609c04a3, (q31_t)0x6097e559, (q31_t)0x6093c5d3, (q31_t)0x608fa612, (q31_t)0x608b8616, + (q31_t)0x608765dd, (q31_t)0x6083456a, (q31_t)0x607f24ba, (q31_t)0x607b03d0, (q31_t)0x6076e2a9, (q31_t)0x6072c148, (q31_t)0x606e9faa, (q31_t)0x606a7dd2, + (q31_t)0x60665bbd, (q31_t)0x6062396e, (q31_t)0x605e16e2, (q31_t)0x6059f41c, (q31_t)0x6055d11a, (q31_t)0x6051addc, (q31_t)0x604d8a63, (q31_t)0x604966af, + (q31_t)0x604542bf, (q31_t)0x60411e94, (q31_t)0x603cfa2e, (q31_t)0x6038d58c, (q31_t)0x6034b0af, (q31_t)0x60308b97, (q31_t)0x602c6643, (q31_t)0x602840b4, + (q31_t)0x60241ae9, (q31_t)0x601ff4e3, (q31_t)0x601bcea2, (q31_t)0x6017a826, (q31_t)0x6013816e, (q31_t)0x600f5a7b, (q31_t)0x600b334d, (q31_t)0x60070be4, + (q31_t)0x6002e43f, (q31_t)0x5ffebc5f, (q31_t)0x5ffa9444, (q31_t)0x5ff66bee, (q31_t)0x5ff2435d, (q31_t)0x5fee1a90, (q31_t)0x5fe9f188, (q31_t)0x5fe5c845, + (q31_t)0x5fe19ec7, (q31_t)0x5fdd750e, (q31_t)0x5fd94b19, (q31_t)0x5fd520ea, (q31_t)0x5fd0f67f, (q31_t)0x5fcccbd9, (q31_t)0x5fc8a0f8, (q31_t)0x5fc475dc, + (q31_t)0x5fc04a85, (q31_t)0x5fbc1ef3, (q31_t)0x5fb7f326, (q31_t)0x5fb3c71e, (q31_t)0x5faf9adb, (q31_t)0x5fab6e5d, (q31_t)0x5fa741a3, (q31_t)0x5fa314af, + (q31_t)0x5f9ee780, (q31_t)0x5f9aba16, (q31_t)0x5f968c70, (q31_t)0x5f925e90, (q31_t)0x5f8e3075, (q31_t)0x5f8a021f, (q31_t)0x5f85d38e, (q31_t)0x5f81a4c2, + (q31_t)0x5f7d75bb, (q31_t)0x5f794679, (q31_t)0x5f7516fd, (q31_t)0x5f70e745, (q31_t)0x5f6cb753, (q31_t)0x5f688726, (q31_t)0x5f6456be, (q31_t)0x5f60261b, + (q31_t)0x5f5bf53d, (q31_t)0x5f57c424, (q31_t)0x5f5392d1, (q31_t)0x5f4f6143, (q31_t)0x5f4b2f7a, (q31_t)0x5f46fd76, (q31_t)0x5f42cb37, (q31_t)0x5f3e98be, + (q31_t)0x5f3a660a, (q31_t)0x5f36331b, (q31_t)0x5f31fff1, (q31_t)0x5f2dcc8d, (q31_t)0x5f2998ee, (q31_t)0x5f256515, (q31_t)0x5f213100, (q31_t)0x5f1cfcb1, + (q31_t)0x5f18c827, (q31_t)0x5f149363, (q31_t)0x5f105e64, (q31_t)0x5f0c292a, (q31_t)0x5f07f3b6, (q31_t)0x5f03be07, (q31_t)0x5eff881d, (q31_t)0x5efb51f9, + (q31_t)0x5ef71b9b, (q31_t)0x5ef2e501, (q31_t)0x5eeeae2d, (q31_t)0x5eea771f, (q31_t)0x5ee63fd6, (q31_t)0x5ee20853, (q31_t)0x5eddd094, (q31_t)0x5ed9989c, + (q31_t)0x5ed56069, (q31_t)0x5ed127fb, (q31_t)0x5eccef53, (q31_t)0x5ec8b671, (q31_t)0x5ec47d54, (q31_t)0x5ec043fc, (q31_t)0x5ebc0a6a, (q31_t)0x5eb7d09e, + (q31_t)0x5eb39697, (q31_t)0x5eaf5c56, (q31_t)0x5eab21da, (q31_t)0x5ea6e724, (q31_t)0x5ea2ac34, (q31_t)0x5e9e7109, (q31_t)0x5e9a35a4, (q31_t)0x5e95fa05, + (q31_t)0x5e91be2b, (q31_t)0x5e8d8217, (q31_t)0x5e8945c8, (q31_t)0x5e85093f, (q31_t)0x5e80cc7c, (q31_t)0x5e7c8f7f, (q31_t)0x5e785247, (q31_t)0x5e7414d5, + (q31_t)0x5e6fd729, (q31_t)0x5e6b9943, (q31_t)0x5e675b22, (q31_t)0x5e631cc7, (q31_t)0x5e5ede32, (q31_t)0x5e5a9f62, (q31_t)0x5e566059, (q31_t)0x5e522115, + (q31_t)0x5e4de197, (q31_t)0x5e49a1df, (q31_t)0x5e4561ed, (q31_t)0x5e4121c0, (q31_t)0x5e3ce15a, (q31_t)0x5e38a0b9, (q31_t)0x5e345fde, (q31_t)0x5e301ec9, + (q31_t)0x5e2bdd7a, (q31_t)0x5e279bf1, (q31_t)0x5e235a2e, (q31_t)0x5e1f1830, (q31_t)0x5e1ad5f9, (q31_t)0x5e169388, (q31_t)0x5e1250dc, (q31_t)0x5e0e0df7, + (q31_t)0x5e09cad7, (q31_t)0x5e05877e, (q31_t)0x5e0143ea, (q31_t)0x5dfd001d, (q31_t)0x5df8bc15, (q31_t)0x5df477d4, (q31_t)0x5df03359, (q31_t)0x5debeea3, + (q31_t)0x5de7a9b4, (q31_t)0x5de3648b, (q31_t)0x5ddf1f28, (q31_t)0x5ddad98b, (q31_t)0x5dd693b4, (q31_t)0x5dd24da3, (q31_t)0x5dce0759, (q31_t)0x5dc9c0d4, + (q31_t)0x5dc57a16, (q31_t)0x5dc1331d, (q31_t)0x5dbcebeb, (q31_t)0x5db8a480, (q31_t)0x5db45cda, (q31_t)0x5db014fa, (q31_t)0x5dabcce1, (q31_t)0x5da7848e, + (q31_t)0x5da33c01, (q31_t)0x5d9ef33b, (q31_t)0x5d9aaa3a, (q31_t)0x5d966100, (q31_t)0x5d92178d, (q31_t)0x5d8dcddf, (q31_t)0x5d8983f8, (q31_t)0x5d8539d7, + (q31_t)0x5d80ef7c, (q31_t)0x5d7ca4e8, (q31_t)0x5d785a1a, (q31_t)0x5d740f12, (q31_t)0x5d6fc3d1, (q31_t)0x5d6b7856, (q31_t)0x5d672ca2, (q31_t)0x5d62e0b4, + (q31_t)0x5d5e948c, (q31_t)0x5d5a482a, (q31_t)0x5d55fb90, (q31_t)0x5d51aebb, (q31_t)0x5d4d61ad, (q31_t)0x5d491465, (q31_t)0x5d44c6e4, (q31_t)0x5d40792a, + (q31_t)0x5d3c2b35, (q31_t)0x5d37dd08, (q31_t)0x5d338ea0, (q31_t)0x5d2f4000, (q31_t)0x5d2af125, (q31_t)0x5d26a212, (q31_t)0x5d2252c5, (q31_t)0x5d1e033e, + (q31_t)0x5d19b37e, (q31_t)0x5d156385, (q31_t)0x5d111352, (q31_t)0x5d0cc2e5, (q31_t)0x5d087240, (q31_t)0x5d042161, (q31_t)0x5cffd048, (q31_t)0x5cfb7ef7, + (q31_t)0x5cf72d6b, (q31_t)0x5cf2dba7, (q31_t)0x5cee89a9, (q31_t)0x5cea3772, (q31_t)0x5ce5e501, (q31_t)0x5ce19258, (q31_t)0x5cdd3f75, (q31_t)0x5cd8ec58, + (q31_t)0x5cd49903, (q31_t)0x5cd04574, (q31_t)0x5ccbf1ab, (q31_t)0x5cc79daa, (q31_t)0x5cc3496f, (q31_t)0x5cbef4fc, (q31_t)0x5cbaa04f, (q31_t)0x5cb64b68, + (q31_t)0x5cb1f649, (q31_t)0x5cada0f0, (q31_t)0x5ca94b5e, (q31_t)0x5ca4f594, (q31_t)0x5ca09f8f, (q31_t)0x5c9c4952, (q31_t)0x5c97f2dc, (q31_t)0x5c939c2c, + (q31_t)0x5c8f4544, (q31_t)0x5c8aee22, (q31_t)0x5c8696c7, (q31_t)0x5c823f34, (q31_t)0x5c7de767, (q31_t)0x5c798f61, (q31_t)0x5c753722, (q31_t)0x5c70deaa, + (q31_t)0x5c6c85f9, (q31_t)0x5c682d0f, (q31_t)0x5c63d3eb, (q31_t)0x5c5f7a8f, (q31_t)0x5c5b20fa, (q31_t)0x5c56c72c, (q31_t)0x5c526d25, (q31_t)0x5c4e12e5, + (q31_t)0x5c49b86d, (q31_t)0x5c455dbb, (q31_t)0x5c4102d0, (q31_t)0x5c3ca7ad, (q31_t)0x5c384c50, (q31_t)0x5c33f0bb, (q31_t)0x5c2f94ec, (q31_t)0x5c2b38e5, + (q31_t)0x5c26dca5, (q31_t)0x5c22802c, (q31_t)0x5c1e237b, (q31_t)0x5c19c690, (q31_t)0x5c15696d, (q31_t)0x5c110c11, (q31_t)0x5c0cae7c, (q31_t)0x5c0850ae, + (q31_t)0x5c03f2a8, (q31_t)0x5bff9469, (q31_t)0x5bfb35f1, (q31_t)0x5bf6d740, (q31_t)0x5bf27857, (q31_t)0x5bee1935, (q31_t)0x5be9b9da, (q31_t)0x5be55a46, + (q31_t)0x5be0fa7a, (q31_t)0x5bdc9a75, (q31_t)0x5bd83a37, (q31_t)0x5bd3d9c1, (q31_t)0x5bcf7912, (q31_t)0x5bcb182b, (q31_t)0x5bc6b70b, (q31_t)0x5bc255b2, + (q31_t)0x5bbdf421, (q31_t)0x5bb99257, (q31_t)0x5bb53054, (q31_t)0x5bb0ce19, (q31_t)0x5bac6ba6, (q31_t)0x5ba808f9, (q31_t)0x5ba3a615, (q31_t)0x5b9f42f7, + (q31_t)0x5b9adfa2, (q31_t)0x5b967c13, (q31_t)0x5b92184d, (q31_t)0x5b8db44d, (q31_t)0x5b895016, (q31_t)0x5b84eba6, (q31_t)0x5b8086fd, (q31_t)0x5b7c221c, + (q31_t)0x5b77bd02, (q31_t)0x5b7357b0, (q31_t)0x5b6ef226, (q31_t)0x5b6a8c63, (q31_t)0x5b662668, (q31_t)0x5b61c035, (q31_t)0x5b5d59c9, (q31_t)0x5b58f324, + (q31_t)0x5b548c48, (q31_t)0x5b502533, (q31_t)0x5b4bbde6, (q31_t)0x5b475660, (q31_t)0x5b42eea2, (q31_t)0x5b3e86ac, (q31_t)0x5b3a1e7e, (q31_t)0x5b35b617, + (q31_t)0x5b314d78, (q31_t)0x5b2ce4a1, (q31_t)0x5b287b91, (q31_t)0x5b241249, (q31_t)0x5b1fa8c9, (q31_t)0x5b1b3f11, (q31_t)0x5b16d521, (q31_t)0x5b126af8, + (q31_t)0x5b0e0098, (q31_t)0x5b0995ff, (q31_t)0x5b052b2e, (q31_t)0x5b00c025, (q31_t)0x5afc54e3, (q31_t)0x5af7e96a, (q31_t)0x5af37db8, (q31_t)0x5aef11cf, + (q31_t)0x5aeaa5ad, (q31_t)0x5ae63953, (q31_t)0x5ae1ccc1, (q31_t)0x5add5ff7, (q31_t)0x5ad8f2f5, (q31_t)0x5ad485bb, (q31_t)0x5ad01849, (q31_t)0x5acbaa9f, + (q31_t)0x5ac73cbd, (q31_t)0x5ac2cea3, (q31_t)0x5abe6050, (q31_t)0x5ab9f1c6, (q31_t)0x5ab58304, (q31_t)0x5ab1140a, (q31_t)0x5aaca4d8, (q31_t)0x5aa8356f, + (q31_t)0x5aa3c5cd, (q31_t)0x5a9f55f3, (q31_t)0x5a9ae5e2, (q31_t)0x5a967598, (q31_t)0x5a920517, (q31_t)0x5a8d945d, (q31_t)0x5a89236c, (q31_t)0x5a84b243, + (q31_t)0x5a8040e3, (q31_t)0x5a7bcf4a, (q31_t)0x5a775d7a, (q31_t)0x5a72eb71, (q31_t)0x5a6e7931, (q31_t)0x5a6a06ba, (q31_t)0x5a65940a, (q31_t)0x5a612123, + (q31_t)0x5a5cae04, (q31_t)0x5a583aad, (q31_t)0x5a53c71e, (q31_t)0x5a4f5358, (q31_t)0x5a4adf5a, (q31_t)0x5a466b24, (q31_t)0x5a41f6b7, (q31_t)0x5a3d8212, + (q31_t)0x5a390d35, (q31_t)0x5a349821, (q31_t)0x5a3022d5, (q31_t)0x5a2bad51, (q31_t)0x5a273796, (q31_t)0x5a22c1a3, (q31_t)0x5a1e4b79, (q31_t)0x5a19d517, + (q31_t)0x5a155e7d, (q31_t)0x5a10e7ac, (q31_t)0x5a0c70a3, (q31_t)0x5a07f963, (q31_t)0x5a0381eb, (q31_t)0x59ff0a3c, (q31_t)0x59fa9255, (q31_t)0x59f61a36, + (q31_t)0x59f1a1e0, (q31_t)0x59ed2953, (q31_t)0x59e8b08e, (q31_t)0x59e43792, (q31_t)0x59dfbe5e, (q31_t)0x59db44f3, (q31_t)0x59d6cb50, (q31_t)0x59d25176, + (q31_t)0x59cdd765, (q31_t)0x59c95d1c, (q31_t)0x59c4e29c, (q31_t)0x59c067e4, (q31_t)0x59bbecf5, (q31_t)0x59b771cf, (q31_t)0x59b2f671, (q31_t)0x59ae7add, + (q31_t)0x59a9ff10, (q31_t)0x59a5830d, (q31_t)0x59a106d2, (q31_t)0x599c8a60, (q31_t)0x59980db6, (q31_t)0x599390d5, (q31_t)0x598f13bd, (q31_t)0x598a966e, + (q31_t)0x598618e8, (q31_t)0x59819b2a, (q31_t)0x597d1d35, (q31_t)0x59789f09, (q31_t)0x597420a6, (q31_t)0x596fa20b, (q31_t)0x596b233a, (q31_t)0x5966a431, + (q31_t)0x596224f1, (q31_t)0x595da57a, (q31_t)0x595925cc, (q31_t)0x5954a5e6, (q31_t)0x595025ca, (q31_t)0x594ba576, (q31_t)0x594724ec, (q31_t)0x5942a42a, + (q31_t)0x593e2331, (q31_t)0x5939a202, (q31_t)0x5935209b, (q31_t)0x59309efd, (q31_t)0x592c1d28, (q31_t)0x59279b1c, (q31_t)0x592318d9, (q31_t)0x591e9660, + (q31_t)0x591a13af, (q31_t)0x591590c7, (q31_t)0x59110da8, (q31_t)0x590c8a53, (q31_t)0x590806c6, (q31_t)0x59038302, (q31_t)0x58feff08, (q31_t)0x58fa7ad7, + (q31_t)0x58f5f66e, (q31_t)0x58f171cf, (q31_t)0x58ececf9, (q31_t)0x58e867ed, (q31_t)0x58e3e2a9, (q31_t)0x58df5d2e, (q31_t)0x58dad77d, (q31_t)0x58d65195, + (q31_t)0x58d1cb76, (q31_t)0x58cd4520, (q31_t)0x58c8be94, (q31_t)0x58c437d1, (q31_t)0x58bfb0d7, (q31_t)0x58bb29a6, (q31_t)0x58b6a23e, (q31_t)0x58b21aa0, + (q31_t)0x58ad92cb, (q31_t)0x58a90ac0, (q31_t)0x58a4827d, (q31_t)0x589ffa04, (q31_t)0x589b7155, (q31_t)0x5896e86f, (q31_t)0x58925f52, (q31_t)0x588dd5fe, + (q31_t)0x58894c74, (q31_t)0x5884c2b3, (q31_t)0x588038bb, (q31_t)0x587bae8d, (q31_t)0x58772429, (q31_t)0x5872998e, (q31_t)0x586e0ebc, (q31_t)0x586983b4, + (q31_t)0x5864f875, (q31_t)0x58606d00, (q31_t)0x585be154, (q31_t)0x58575571, (q31_t)0x5852c958, (q31_t)0x584e3d09, (q31_t)0x5849b083, (q31_t)0x584523c7, + (q31_t)0x584096d4, (q31_t)0x583c09ab, (q31_t)0x58377c4c, (q31_t)0x5832eeb6, (q31_t)0x582e60e9, (q31_t)0x5829d2e6, (q31_t)0x582544ad, (q31_t)0x5820b63e, + (q31_t)0x581c2798, (q31_t)0x581798bb, (q31_t)0x581309a9, (q31_t)0x580e7a60, (q31_t)0x5809eae1, (q31_t)0x58055b2b, (q31_t)0x5800cb3f, (q31_t)0x57fc3b1d, + (q31_t)0x57f7aac5, (q31_t)0x57f31a36, (q31_t)0x57ee8971, (q31_t)0x57e9f876, (q31_t)0x57e56744, (q31_t)0x57e0d5dd, (q31_t)0x57dc443f, (q31_t)0x57d7b26b, + (q31_t)0x57d32061, (q31_t)0x57ce8e20, (q31_t)0x57c9fbaa, (q31_t)0x57c568fd, (q31_t)0x57c0d61a, (q31_t)0x57bc4301, (q31_t)0x57b7afb2, (q31_t)0x57b31c2d, + (q31_t)0x57ae8872, (q31_t)0x57a9f480, (q31_t)0x57a56059, (q31_t)0x57a0cbfb, (q31_t)0x579c3768, (q31_t)0x5797a29e, (q31_t)0x57930d9e, (q31_t)0x578e7869, + (q31_t)0x5789e2fd, (q31_t)0x57854d5b, (q31_t)0x5780b784, (q31_t)0x577c2176, (q31_t)0x57778b32, (q31_t)0x5772f4b9, (q31_t)0x576e5e09, (q31_t)0x5769c724, + (q31_t)0x57653009, (q31_t)0x576098b7, (q31_t)0x575c0130, (q31_t)0x57576973, (q31_t)0x5752d180, (q31_t)0x574e3957, (q31_t)0x5749a0f9, (q31_t)0x57450864, + (q31_t)0x57406f9a, (q31_t)0x573bd69a, (q31_t)0x57373d64, (q31_t)0x5732a3f8, (q31_t)0x572e0a56, (q31_t)0x5729707f, (q31_t)0x5724d672, (q31_t)0x57203c2f, + (q31_t)0x571ba1b7, (q31_t)0x57170708, (q31_t)0x57126c24, (q31_t)0x570dd10a, (q31_t)0x570935bb, (q31_t)0x57049a36, (q31_t)0x56fffe7b, (q31_t)0x56fb628b, + (q31_t)0x56f6c664, (q31_t)0x56f22a09, (q31_t)0x56ed8d77, (q31_t)0x56e8f0b0, (q31_t)0x56e453b4, (q31_t)0x56dfb681, (q31_t)0x56db1919, (q31_t)0x56d67b7c, + (q31_t)0x56d1dda9, (q31_t)0x56cd3fa1, (q31_t)0x56c8a162, (q31_t)0x56c402ef, (q31_t)0x56bf6446, (q31_t)0x56bac567, (q31_t)0x56b62653, (q31_t)0x56b18709, + (q31_t)0x56ace78a, (q31_t)0x56a847d6, (q31_t)0x56a3a7ec, (q31_t)0x569f07cc, (q31_t)0x569a6777, (q31_t)0x5695c6ed, (q31_t)0x5691262d, (q31_t)0x568c8538, + (q31_t)0x5687e40e, (q31_t)0x568342ae, (q31_t)0x567ea118, (q31_t)0x5679ff4e, (q31_t)0x56755d4e, (q31_t)0x5670bb19, (q31_t)0x566c18ae, (q31_t)0x5667760e, + (q31_t)0x5662d339, (q31_t)0x565e302e, (q31_t)0x56598cee, (q31_t)0x5654e979, (q31_t)0x565045cf, (q31_t)0x564ba1f0, (q31_t)0x5646fddb, (q31_t)0x56425991, + (q31_t)0x563db512, (q31_t)0x5639105d, (q31_t)0x56346b74, (q31_t)0x562fc655, (q31_t)0x562b2101, (q31_t)0x56267b78, (q31_t)0x5621d5ba, (q31_t)0x561d2fc6, + (q31_t)0x5618899e, (q31_t)0x5613e340, (q31_t)0x560f3cae, (q31_t)0x560a95e6, (q31_t)0x5605eee9, (q31_t)0x560147b7, (q31_t)0x55fca050, (q31_t)0x55f7f8b4, + (q31_t)0x55f350e3, (q31_t)0x55eea8dd, (q31_t)0x55ea00a2, (q31_t)0x55e55832, (q31_t)0x55e0af8d, (q31_t)0x55dc06b3, (q31_t)0x55d75da4, (q31_t)0x55d2b460, + (q31_t)0x55ce0ae7, (q31_t)0x55c96139, (q31_t)0x55c4b757, (q31_t)0x55c00d3f, (q31_t)0x55bb62f3, (q31_t)0x55b6b871, (q31_t)0x55b20dbb, (q31_t)0x55ad62d0, + (q31_t)0x55a8b7b0, (q31_t)0x55a40c5b, (q31_t)0x559f60d1, (q31_t)0x559ab513, (q31_t)0x55960920, (q31_t)0x55915cf8, (q31_t)0x558cb09b, (q31_t)0x55880409, + (q31_t)0x55835743, (q31_t)0x557eaa48, (q31_t)0x5579fd18, (q31_t)0x55754fb3, (q31_t)0x5570a21a, (q31_t)0x556bf44c, (q31_t)0x55674649, (q31_t)0x55629812, + (q31_t)0x555de9a6, (q31_t)0x55593b05, (q31_t)0x55548c30, (q31_t)0x554fdd26, (q31_t)0x554b2de7, (q31_t)0x55467e74, (q31_t)0x5541cecc, (q31_t)0x553d1ef0, + (q31_t)0x55386edf, (q31_t)0x5533be99, (q31_t)0x552f0e1f, (q31_t)0x552a5d70, (q31_t)0x5525ac8d, (q31_t)0x5520fb75, (q31_t)0x551c4a29, (q31_t)0x551798a8, + (q31_t)0x5512e6f3, (q31_t)0x550e3509, (q31_t)0x550982eb, (q31_t)0x5504d099, (q31_t)0x55001e12, (q31_t)0x54fb6b56, (q31_t)0x54f6b866, (q31_t)0x54f20542, + (q31_t)0x54ed51e9, (q31_t)0x54e89e5c, (q31_t)0x54e3ea9a, (q31_t)0x54df36a5, (q31_t)0x54da827a, (q31_t)0x54d5ce1c, (q31_t)0x54d11989, (q31_t)0x54cc64c2, + (q31_t)0x54c7afc6, (q31_t)0x54c2fa96, (q31_t)0x54be4532, (q31_t)0x54b98f9a, (q31_t)0x54b4d9cd, (q31_t)0x54b023cc, (q31_t)0x54ab6d97, (q31_t)0x54a6b72e, + (q31_t)0x54a20090, (q31_t)0x549d49bf, (q31_t)0x549892b9, (q31_t)0x5493db7f, (q31_t)0x548f2410, (q31_t)0x548a6c6e, (q31_t)0x5485b497, (q31_t)0x5480fc8c, + (q31_t)0x547c444d, (q31_t)0x54778bda, (q31_t)0x5472d333, (q31_t)0x546e1a58, (q31_t)0x54696149, (q31_t)0x5464a805, (q31_t)0x545fee8e, (q31_t)0x545b34e3, + (q31_t)0x54567b03, (q31_t)0x5451c0f0, (q31_t)0x544d06a8, (q31_t)0x54484c2d, (q31_t)0x5443917d, (q31_t)0x543ed699, (q31_t)0x543a1b82, (q31_t)0x54356037, + (q31_t)0x5430a4b7, (q31_t)0x542be904, (q31_t)0x54272d1d, (q31_t)0x54227102, (q31_t)0x541db4b3, (q31_t)0x5418f830, (q31_t)0x54143b79, (q31_t)0x540f7e8e, + (q31_t)0x540ac170, (q31_t)0x5406041d, (q31_t)0x54014697, (q31_t)0x53fc88dd, (q31_t)0x53f7caef, (q31_t)0x53f30cce, (q31_t)0x53ee4e78, (q31_t)0x53e98fef, + (q31_t)0x53e4d132, (q31_t)0x53e01242, (q31_t)0x53db531d, (q31_t)0x53d693c5, (q31_t)0x53d1d439, (q31_t)0x53cd147a, (q31_t)0x53c85486, (q31_t)0x53c3945f, + (q31_t)0x53bed405, (q31_t)0x53ba1377, (q31_t)0x53b552b5, (q31_t)0x53b091bf, (q31_t)0x53abd096, (q31_t)0x53a70f39, (q31_t)0x53a24da9, (q31_t)0x539d8be5, + (q31_t)0x5398c9ed, (q31_t)0x539407c2, (q31_t)0x538f4564, (q31_t)0x538a82d1, (q31_t)0x5385c00c, (q31_t)0x5380fd12, (q31_t)0x537c39e6, (q31_t)0x53777685, + (q31_t)0x5372b2f2, (q31_t)0x536def2a, (q31_t)0x53692b30, (q31_t)0x53646701, (q31_t)0x535fa2a0, (q31_t)0x535ade0b, (q31_t)0x53561942, (q31_t)0x53515447, + (q31_t)0x534c8f17, (q31_t)0x5347c9b5, (q31_t)0x5343041f, (q31_t)0x533e3e55, (q31_t)0x53397859, (q31_t)0x5334b229, (q31_t)0x532febc5, (q31_t)0x532b252f, + (q31_t)0x53265e65, (q31_t)0x53219767, (q31_t)0x531cd037, (q31_t)0x531808d3, (q31_t)0x5313413c, (q31_t)0x530e7972, (q31_t)0x5309b174, (q31_t)0x5304e943, + (q31_t)0x530020df, (q31_t)0x52fb5848, (q31_t)0x52f68f7e, (q31_t)0x52f1c680, (q31_t)0x52ecfd4f, (q31_t)0x52e833ec, (q31_t)0x52e36a55, (q31_t)0x52dea08a, + (q31_t)0x52d9d68d, (q31_t)0x52d50c5d, (q31_t)0x52d041f9, (q31_t)0x52cb7763, (q31_t)0x52c6ac99, (q31_t)0x52c1e19d, (q31_t)0x52bd166d, (q31_t)0x52b84b0a, + (q31_t)0x52b37f74, (q31_t)0x52aeb3ac, (q31_t)0x52a9e7b0, (q31_t)0x52a51b81, (q31_t)0x52a04f1f, (q31_t)0x529b828a, (q31_t)0x5296b5c3, (q31_t)0x5291e8c8, + (q31_t)0x528d1b9b, (q31_t)0x52884e3a, (q31_t)0x528380a7, (q31_t)0x527eb2e0, (q31_t)0x5279e4e7, (q31_t)0x527516bb, (q31_t)0x5270485c, (q31_t)0x526b79ca, + (q31_t)0x5266ab06, (q31_t)0x5261dc0e, (q31_t)0x525d0ce4, (q31_t)0x52583d87, (q31_t)0x52536df7, (q31_t)0x524e9e34, (q31_t)0x5249ce3f, (q31_t)0x5244fe17, + (q31_t)0x52402dbc, (q31_t)0x523b5d2e, (q31_t)0x52368c6e, (q31_t)0x5231bb7b, (q31_t)0x522cea55, (q31_t)0x522818fc, (q31_t)0x52234771, (q31_t)0x521e75b3, + (q31_t)0x5219a3c3, (q31_t)0x5214d1a0, (q31_t)0x520fff4a, (q31_t)0x520b2cc2, (q31_t)0x52065a07, (q31_t)0x52018719, (q31_t)0x51fcb3f9, (q31_t)0x51f7e0a6, + (q31_t)0x51f30d21, (q31_t)0x51ee3969, (q31_t)0x51e9657e, (q31_t)0x51e49162, (q31_t)0x51dfbd12, (q31_t)0x51dae890, (q31_t)0x51d613dc, (q31_t)0x51d13ef5, + (q31_t)0x51cc69db, (q31_t)0x51c79490, (q31_t)0x51c2bf11, (q31_t)0x51bde960, (q31_t)0x51b9137d, (q31_t)0x51b43d68, (q31_t)0x51af6720, (q31_t)0x51aa90a5, + (q31_t)0x51a5b9f9, (q31_t)0x51a0e31a, (q31_t)0x519c0c08, (q31_t)0x519734c4, (q31_t)0x51925d4e, (q31_t)0x518d85a6, (q31_t)0x5188adcb, (q31_t)0x5183d5be, + (q31_t)0x517efd7f, (q31_t)0x517a250d, (q31_t)0x51754c69, (q31_t)0x51707393, (q31_t)0x516b9a8b, (q31_t)0x5166c150, (q31_t)0x5161e7e4, (q31_t)0x515d0e45, + (q31_t)0x51583473, (q31_t)0x51535a70, (q31_t)0x514e803b, (q31_t)0x5149a5d3, (q31_t)0x5144cb39, (q31_t)0x513ff06d, (q31_t)0x513b156f, (q31_t)0x51363a3f, + (q31_t)0x51315edd, (q31_t)0x512c8348, (q31_t)0x5127a782, (q31_t)0x5122cb8a, (q31_t)0x511def5f, (q31_t)0x51191302, (q31_t)0x51143674, (q31_t)0x510f59b3, + (q31_t)0x510a7cc1, (q31_t)0x51059f9c, (q31_t)0x5100c246, (q31_t)0x50fbe4bd, (q31_t)0x50f70703, (q31_t)0x50f22916, (q31_t)0x50ed4af8, (q31_t)0x50e86ca8, + (q31_t)0x50e38e25, (q31_t)0x50deaf71, (q31_t)0x50d9d08b, (q31_t)0x50d4f173, (q31_t)0x50d0122a, (q31_t)0x50cb32ae, (q31_t)0x50c65301, (q31_t)0x50c17322, + (q31_t)0x50bc9311, (q31_t)0x50b7b2ce, (q31_t)0x50b2d259, (q31_t)0x50adf1b3, (q31_t)0x50a910db, (q31_t)0x50a42fd1, (q31_t)0x509f4e95, (q31_t)0x509a6d28, + (q31_t)0x50958b88, (q31_t)0x5090a9b8, (q31_t)0x508bc7b5, (q31_t)0x5086e581, (q31_t)0x5082031b, (q31_t)0x507d2083, (q31_t)0x50783dba, (q31_t)0x50735abf, + (q31_t)0x506e7793, (q31_t)0x50699435, (q31_t)0x5064b0a5, (q31_t)0x505fcce4, (q31_t)0x505ae8f1, (q31_t)0x505604cd, (q31_t)0x50512077, (q31_t)0x504c3bef, + (q31_t)0x50475736, (q31_t)0x5042724c, (q31_t)0x503d8d30, (q31_t)0x5038a7e2, (q31_t)0x5033c263, (q31_t)0x502edcb2, (q31_t)0x5029f6d1, (q31_t)0x502510bd, + (q31_t)0x50202a78, (q31_t)0x501b4402, (q31_t)0x50165d5a, (q31_t)0x50117681, (q31_t)0x500c8f77, (q31_t)0x5007a83b, (q31_t)0x5002c0cd, (q31_t)0x4ffdd92f, + (q31_t)0x4ff8f15f, (q31_t)0x4ff4095e, (q31_t)0x4fef212b, (q31_t)0x4fea38c7, (q31_t)0x4fe55032, (q31_t)0x4fe0676c, (q31_t)0x4fdb7e74, (q31_t)0x4fd6954b, + (q31_t)0x4fd1abf0, (q31_t)0x4fccc265, (q31_t)0x4fc7d8a8, (q31_t)0x4fc2eeba, (q31_t)0x4fbe049b, (q31_t)0x4fb91a4b, (q31_t)0x4fb42fc9, (q31_t)0x4faf4517, + (q31_t)0x4faa5a33, (q31_t)0x4fa56f1e, (q31_t)0x4fa083d8, (q31_t)0x4f9b9861, (q31_t)0x4f96acb8, (q31_t)0x4f91c0df, (q31_t)0x4f8cd4d4, (q31_t)0x4f87e899, + (q31_t)0x4f82fc2c, (q31_t)0x4f7e0f8f, (q31_t)0x4f7922c0, (q31_t)0x4f7435c0, (q31_t)0x4f6f488f, (q31_t)0x4f6a5b2e, (q31_t)0x4f656d9b, (q31_t)0x4f607fd7, + (q31_t)0x4f5b91e3, (q31_t)0x4f56a3bd, (q31_t)0x4f51b566, (q31_t)0x4f4cc6df, (q31_t)0x4f47d827, (q31_t)0x4f42e93d, (q31_t)0x4f3dfa23, (q31_t)0x4f390ad8, + (q31_t)0x4f341b5c, (q31_t)0x4f2f2baf, (q31_t)0x4f2a3bd2, (q31_t)0x4f254bc3, (q31_t)0x4f205b84, (q31_t)0x4f1b6b14, (q31_t)0x4f167a73, (q31_t)0x4f1189a1, + (q31_t)0x4f0c989f, (q31_t)0x4f07a76b, (q31_t)0x4f02b608, (q31_t)0x4efdc473, (q31_t)0x4ef8d2ad, (q31_t)0x4ef3e0b7, (q31_t)0x4eeeee90, (q31_t)0x4ee9fc39, + (q31_t)0x4ee509b1, (q31_t)0x4ee016f8, (q31_t)0x4edb240e, (q31_t)0x4ed630f4, (q31_t)0x4ed13da9, (q31_t)0x4ecc4a2e, (q31_t)0x4ec75682, (q31_t)0x4ec262a5, + (q31_t)0x4ebd6e98, (q31_t)0x4eb87a5a, (q31_t)0x4eb385ec, (q31_t)0x4eae914d, (q31_t)0x4ea99c7d, (q31_t)0x4ea4a77d, (q31_t)0x4e9fb24d, (q31_t)0x4e9abcec, + (q31_t)0x4e95c75b, (q31_t)0x4e90d199, (q31_t)0x4e8bdba6, (q31_t)0x4e86e583, (q31_t)0x4e81ef30, (q31_t)0x4e7cf8ac, (q31_t)0x4e7801f8, (q31_t)0x4e730b14, + (q31_t)0x4e6e13ff, (q31_t)0x4e691cba, (q31_t)0x4e642544, (q31_t)0x4e5f2d9e, (q31_t)0x4e5a35c7, (q31_t)0x4e553dc1, (q31_t)0x4e50458a, (q31_t)0x4e4b4d22, + (q31_t)0x4e46548b, (q31_t)0x4e415bc3, (q31_t)0x4e3c62cb, (q31_t)0x4e3769a2, (q31_t)0x4e32704a, (q31_t)0x4e2d76c1, (q31_t)0x4e287d08, (q31_t)0x4e23831e, + (q31_t)0x4e1e8905, (q31_t)0x4e198ebb, (q31_t)0x4e149441, (q31_t)0x4e0f9997, (q31_t)0x4e0a9ebd, (q31_t)0x4e05a3b2, (q31_t)0x4e00a878, (q31_t)0x4dfbad0d, + (q31_t)0x4df6b173, (q31_t)0x4df1b5a8, (q31_t)0x4decb9ad, (q31_t)0x4de7bd82, (q31_t)0x4de2c127, (q31_t)0x4dddc49c, (q31_t)0x4dd8c7e1, (q31_t)0x4dd3caf6, + (q31_t)0x4dcecdda, (q31_t)0x4dc9d08f, (q31_t)0x4dc4d314, (q31_t)0x4dbfd569, (q31_t)0x4dbad78e, (q31_t)0x4db5d983, (q31_t)0x4db0db48, (q31_t)0x4dabdcdd, + (q31_t)0x4da6de43, (q31_t)0x4da1df78, (q31_t)0x4d9ce07d, (q31_t)0x4d97e153, (q31_t)0x4d92e1f9, (q31_t)0x4d8de26f, (q31_t)0x4d88e2b5, (q31_t)0x4d83e2cb, + (q31_t)0x4d7ee2b1, (q31_t)0x4d79e268, (q31_t)0x4d74e1ef, (q31_t)0x4d6fe146, (q31_t)0x4d6ae06d, (q31_t)0x4d65df64, (q31_t)0x4d60de2c, (q31_t)0x4d5bdcc4, + (q31_t)0x4d56db2d, (q31_t)0x4d51d965, (q31_t)0x4d4cd76e, (q31_t)0x4d47d547, (q31_t)0x4d42d2f1, (q31_t)0x4d3dd06b, (q31_t)0x4d38cdb5, (q31_t)0x4d33cad0, + (q31_t)0x4d2ec7bb, (q31_t)0x4d29c476, (q31_t)0x4d24c102, (q31_t)0x4d1fbd5e, (q31_t)0x4d1ab98b, (q31_t)0x4d15b588, (q31_t)0x4d10b155, (q31_t)0x4d0bacf3, + (q31_t)0x4d06a862, (q31_t)0x4d01a3a0, (q31_t)0x4cfc9eb0, (q31_t)0x4cf79990, (q31_t)0x4cf29440, (q31_t)0x4ced8ec1, (q31_t)0x4ce88913, (q31_t)0x4ce38335, + (q31_t)0x4cde7d28, (q31_t)0x4cd976eb, (q31_t)0x4cd4707f, (q31_t)0x4ccf69e3, (q31_t)0x4cca6318, (q31_t)0x4cc55c1e, (q31_t)0x4cc054f4, (q31_t)0x4cbb4d9b, + (q31_t)0x4cb64613, (q31_t)0x4cb13e5b, (q31_t)0x4cac3674, (q31_t)0x4ca72e5e, (q31_t)0x4ca22619, (q31_t)0x4c9d1da4, (q31_t)0x4c981500, (q31_t)0x4c930c2d, + (q31_t)0x4c8e032a, (q31_t)0x4c88f9f8, (q31_t)0x4c83f097, (q31_t)0x4c7ee707, (q31_t)0x4c79dd48, (q31_t)0x4c74d359, (q31_t)0x4c6fc93b, (q31_t)0x4c6abeef, + (q31_t)0x4c65b473, (q31_t)0x4c60a9c8, (q31_t)0x4c5b9eed, (q31_t)0x4c5693e4, (q31_t)0x4c5188ac, (q31_t)0x4c4c7d44, (q31_t)0x4c4771ae, (q31_t)0x4c4265e8, + (q31_t)0x4c3d59f3, (q31_t)0x4c384dd0, (q31_t)0x4c33417d, (q31_t)0x4c2e34fb, (q31_t)0x4c29284b, (q31_t)0x4c241b6b, (q31_t)0x4c1f0e5c, (q31_t)0x4c1a011f, + (q31_t)0x4c14f3b2, (q31_t)0x4c0fe617, (q31_t)0x4c0ad84c, (q31_t)0x4c05ca53, (q31_t)0x4c00bc2b, (q31_t)0x4bfbadd4, (q31_t)0x4bf69f4e, (q31_t)0x4bf19099, + (q31_t)0x4bec81b5, (q31_t)0x4be772a3, (q31_t)0x4be26362, (q31_t)0x4bdd53f2, (q31_t)0x4bd84453, (q31_t)0x4bd33485, (q31_t)0x4bce2488, (q31_t)0x4bc9145d, + (q31_t)0x4bc40403, (q31_t)0x4bbef37b, (q31_t)0x4bb9e2c3, (q31_t)0x4bb4d1dd, (q31_t)0x4bafc0c8, (q31_t)0x4baaaf85, (q31_t)0x4ba59e12, (q31_t)0x4ba08c72, + (q31_t)0x4b9b7aa2, (q31_t)0x4b9668a4, (q31_t)0x4b915677, (q31_t)0x4b8c441c, (q31_t)0x4b873192, (q31_t)0x4b821ed9, (q31_t)0x4b7d0bf2, (q31_t)0x4b77f8dc, + (q31_t)0x4b72e598, (q31_t)0x4b6dd225, (q31_t)0x4b68be84, (q31_t)0x4b63aab4, (q31_t)0x4b5e96b6, (q31_t)0x4b598289, (q31_t)0x4b546e2d, (q31_t)0x4b4f59a4, + (q31_t)0x4b4a44eb, (q31_t)0x4b453005, (q31_t)0x4b401aef, (q31_t)0x4b3b05ac, (q31_t)0x4b35f03a, (q31_t)0x4b30da9a, (q31_t)0x4b2bc4cb, (q31_t)0x4b26aece, + (q31_t)0x4b2198a2, (q31_t)0x4b1c8248, (q31_t)0x4b176bc0, (q31_t)0x4b12550a, (q31_t)0x4b0d3e25, (q31_t)0x4b082712, (q31_t)0x4b030fd1, (q31_t)0x4afdf861, + (q31_t)0x4af8e0c3, (q31_t)0x4af3c8f7, (q31_t)0x4aeeb0fd, (q31_t)0x4ae998d4, (q31_t)0x4ae4807d, (q31_t)0x4adf67f8, (q31_t)0x4ada4f45, (q31_t)0x4ad53664, + (q31_t)0x4ad01d54, (q31_t)0x4acb0417, (q31_t)0x4ac5eaab, (q31_t)0x4ac0d111, (q31_t)0x4abbb749, (q31_t)0x4ab69d53, (q31_t)0x4ab1832f, (q31_t)0x4aac68dc, + (q31_t)0x4aa74e5c, (q31_t)0x4aa233ae, (q31_t)0x4a9d18d1, (q31_t)0x4a97fdc7, (q31_t)0x4a92e28e, (q31_t)0x4a8dc728, (q31_t)0x4a88ab93, (q31_t)0x4a838fd1, + (q31_t)0x4a7e73e0, (q31_t)0x4a7957c2, (q31_t)0x4a743b76, (q31_t)0x4a6f1efc, (q31_t)0x4a6a0253, (q31_t)0x4a64e57d, (q31_t)0x4a5fc879, (q31_t)0x4a5aab48, + (q31_t)0x4a558de8, (q31_t)0x4a50705a, (q31_t)0x4a4b529f, (q31_t)0x4a4634b6, (q31_t)0x4a41169f, (q31_t)0x4a3bf85a, (q31_t)0x4a36d9e7, (q31_t)0x4a31bb47, + (q31_t)0x4a2c9c79, (q31_t)0x4a277d7d, (q31_t)0x4a225e53, (q31_t)0x4a1d3efc, (q31_t)0x4a181f77, (q31_t)0x4a12ffc4, (q31_t)0x4a0ddfe4, (q31_t)0x4a08bfd5, + (q31_t)0x4a039f9a, (q31_t)0x49fe7f30, (q31_t)0x49f95e99, (q31_t)0x49f43dd4, (q31_t)0x49ef1ce2, (q31_t)0x49e9fbc2, (q31_t)0x49e4da74, (q31_t)0x49dfb8f9, + (q31_t)0x49da9750, (q31_t)0x49d5757a, (q31_t)0x49d05376, (q31_t)0x49cb3145, (q31_t)0x49c60ee6, (q31_t)0x49c0ec59, (q31_t)0x49bbc9a0, (q31_t)0x49b6a6b8, + (q31_t)0x49b183a3, (q31_t)0x49ac6061, (q31_t)0x49a73cf1, (q31_t)0x49a21954, (q31_t)0x499cf589, (q31_t)0x4997d191, (q31_t)0x4992ad6c, (q31_t)0x498d8919, + (q31_t)0x49886499, (q31_t)0x49833fec, (q31_t)0x497e1b11, (q31_t)0x4978f609, (q31_t)0x4973d0d3, (q31_t)0x496eab70, (q31_t)0x496985e0, (q31_t)0x49646023, + (q31_t)0x495f3a38, (q31_t)0x495a1420, (q31_t)0x4954eddb, (q31_t)0x494fc768, (q31_t)0x494aa0c9, (q31_t)0x494579fc, (q31_t)0x49405302, (q31_t)0x493b2bdb, + (q31_t)0x49360486, (q31_t)0x4930dd05, (q31_t)0x492bb556, (q31_t)0x49268d7a, (q31_t)0x49216571, (q31_t)0x491c3d3b, (q31_t)0x491714d8, (q31_t)0x4911ec47, + (q31_t)0x490cc38a, (q31_t)0x49079aa0, (q31_t)0x49027188, (q31_t)0x48fd4844, (q31_t)0x48f81ed2, (q31_t)0x48f2f534, (q31_t)0x48edcb68, (q31_t)0x48e8a170, + (q31_t)0x48e3774a, (q31_t)0x48de4cf8, (q31_t)0x48d92278, (q31_t)0x48d3f7cc, (q31_t)0x48ceccf3, (q31_t)0x48c9a1ed, (q31_t)0x48c476b9, (q31_t)0x48bf4b59, + (q31_t)0x48ba1fcd, (q31_t)0x48b4f413, (q31_t)0x48afc82c, (q31_t)0x48aa9c19, (q31_t)0x48a56fd9, (q31_t)0x48a0436c, (q31_t)0x489b16d2, (q31_t)0x4895ea0b, + (q31_t)0x4890bd18, (q31_t)0x488b8ff8, (q31_t)0x488662ab, (q31_t)0x48813531, (q31_t)0x487c078b, (q31_t)0x4876d9b8, (q31_t)0x4871abb8, (q31_t)0x486c7d8c, + (q31_t)0x48674f33, (q31_t)0x486220ad, (q31_t)0x485cf1fa, (q31_t)0x4857c31b, (q31_t)0x48529410, (q31_t)0x484d64d7, (q31_t)0x48483572, (q31_t)0x484305e1, + (q31_t)0x483dd623, (q31_t)0x4838a638, (q31_t)0x48337621, (q31_t)0x482e45dd, (q31_t)0x4829156d, (q31_t)0x4823e4d0, (q31_t)0x481eb407, (q31_t)0x48198311, + (q31_t)0x481451ef, (q31_t)0x480f20a0, (q31_t)0x4809ef25, (q31_t)0x4804bd7e, (q31_t)0x47ff8baa, (q31_t)0x47fa59a9, (q31_t)0x47f5277d, (q31_t)0x47eff523, + (q31_t)0x47eac29e, (q31_t)0x47e58fec, (q31_t)0x47e05d0e, (q31_t)0x47db2a03, (q31_t)0x47d5f6cc, (q31_t)0x47d0c369, (q31_t)0x47cb8fd9, (q31_t)0x47c65c1d, + (q31_t)0x47c12835, (q31_t)0x47bbf421, (q31_t)0x47b6bfe0, (q31_t)0x47b18b74, (q31_t)0x47ac56da, (q31_t)0x47a72215, (q31_t)0x47a1ed24, (q31_t)0x479cb806, + (q31_t)0x479782bc, (q31_t)0x47924d46, (q31_t)0x478d17a4, (q31_t)0x4787e1d6, (q31_t)0x4782abdb, (q31_t)0x477d75b5, (q31_t)0x47783f62, (q31_t)0x477308e3, + (q31_t)0x476dd239, (q31_t)0x47689b62, (q31_t)0x4763645f, (q31_t)0x475e2d30, (q31_t)0x4758f5d5, (q31_t)0x4753be4e, (q31_t)0x474e869b, (q31_t)0x47494ebc, + (q31_t)0x474416b1, (q31_t)0x473ede7a, (q31_t)0x4739a617, (q31_t)0x47346d89, (q31_t)0x472f34ce, (q31_t)0x4729fbe7, (q31_t)0x4724c2d5, (q31_t)0x471f8996, + (q31_t)0x471a502c, (q31_t)0x47151696, (q31_t)0x470fdcd4, (q31_t)0x470aa2e6, (q31_t)0x470568cd, (q31_t)0x47002e87, (q31_t)0x46faf416, (q31_t)0x46f5b979, + (q31_t)0x46f07eb0, (q31_t)0x46eb43bc, (q31_t)0x46e6089b, (q31_t)0x46e0cd4f, (q31_t)0x46db91d8, (q31_t)0x46d65634, (q31_t)0x46d11a65, (q31_t)0x46cbde6a, + (q31_t)0x46c6a244, (q31_t)0x46c165f1, (q31_t)0x46bc2974, (q31_t)0x46b6ecca, (q31_t)0x46b1aff5, (q31_t)0x46ac72f4, (q31_t)0x46a735c8, (q31_t)0x46a1f870, + (q31_t)0x469cbaed, (q31_t)0x46977d3e, (q31_t)0x46923f63, (q31_t)0x468d015d, (q31_t)0x4687c32c, (q31_t)0x468284cf, (q31_t)0x467d4646, (q31_t)0x46780792, + (q31_t)0x4672c8b3, (q31_t)0x466d89a8, (q31_t)0x46684a71, (q31_t)0x46630b0f, (q31_t)0x465dcb82, (q31_t)0x46588bc9, (q31_t)0x46534be5, (q31_t)0x464e0bd6, + (q31_t)0x4648cb9b, (q31_t)0x46438b35, (q31_t)0x463e4aa3, (q31_t)0x463909e7, (q31_t)0x4633c8fe, (q31_t)0x462e87eb, (q31_t)0x462946ac, (q31_t)0x46240542, + (q31_t)0x461ec3ad, (q31_t)0x461981ec, (q31_t)0x46144001, (q31_t)0x460efde9, (q31_t)0x4609bba7, (q31_t)0x4604793a, (q31_t)0x45ff36a1, (q31_t)0x45f9f3dd, + (q31_t)0x45f4b0ee, (q31_t)0x45ef6dd4, (q31_t)0x45ea2a8f, (q31_t)0x45e4e71f, (q31_t)0x45dfa383, (q31_t)0x45da5fbc, (q31_t)0x45d51bcb, (q31_t)0x45cfd7ae, + (q31_t)0x45ca9366, (q31_t)0x45c54ef3, (q31_t)0x45c00a55, (q31_t)0x45bac58c, (q31_t)0x45b58098, (q31_t)0x45b03b79, (q31_t)0x45aaf630, (q31_t)0x45a5b0bb, + (q31_t)0x45a06b1b, (q31_t)0x459b2550, (q31_t)0x4595df5a, (q31_t)0x45909939, (q31_t)0x458b52ee, (q31_t)0x45860c77, (q31_t)0x4580c5d6, (q31_t)0x457b7f0a, + (q31_t)0x45763813, (q31_t)0x4570f0f1, (q31_t)0x456ba9a4, (q31_t)0x4566622c, (q31_t)0x45611a8a, (q31_t)0x455bd2bc, (q31_t)0x45568ac4, (q31_t)0x455142a2, + (q31_t)0x454bfa54, (q31_t)0x4546b1dc, (q31_t)0x45416939, (q31_t)0x453c206b, (q31_t)0x4536d773, (q31_t)0x45318e4f, (q31_t)0x452c4502, (q31_t)0x4526fb89, + (q31_t)0x4521b1e6, (q31_t)0x451c6818, (q31_t)0x45171e20, (q31_t)0x4511d3fd, (q31_t)0x450c89af, (q31_t)0x45073f37, (q31_t)0x4501f494, (q31_t)0x44fca9c6, + (q31_t)0x44f75ecf, (q31_t)0x44f213ac, (q31_t)0x44ecc85f, (q31_t)0x44e77ce7, (q31_t)0x44e23145, (q31_t)0x44dce579, (q31_t)0x44d79982, (q31_t)0x44d24d60, + (q31_t)0x44cd0114, (q31_t)0x44c7b49e, (q31_t)0x44c267fd, (q31_t)0x44bd1b32, (q31_t)0x44b7ce3c, (q31_t)0x44b2811c, (q31_t)0x44ad33d2, (q31_t)0x44a7e65d, + (q31_t)0x44a298be, (q31_t)0x449d4af5, (q31_t)0x4497fd01, (q31_t)0x4492aee3, (q31_t)0x448d609b, (q31_t)0x44881228, (q31_t)0x4482c38b, (q31_t)0x447d74c4, + (q31_t)0x447825d2, (q31_t)0x4472d6b7, (q31_t)0x446d8771, (q31_t)0x44683801, (q31_t)0x4462e866, (q31_t)0x445d98a2, (q31_t)0x445848b3, (q31_t)0x4452f89b, + (q31_t)0x444da858, (q31_t)0x444857ea, (q31_t)0x44430753, (q31_t)0x443db692, (q31_t)0x443865a7, (q31_t)0x44331491, (q31_t)0x442dc351, (q31_t)0x442871e8, + (q31_t)0x44232054, (q31_t)0x441dce96, (q31_t)0x44187caf, (q31_t)0x44132a9d, (q31_t)0x440dd861, (q31_t)0x440885fc, (q31_t)0x4403336c, (q31_t)0x43fde0b2, + (q31_t)0x43f88dcf, (q31_t)0x43f33ac1, (q31_t)0x43ede78a, (q31_t)0x43e89429, (q31_t)0x43e3409d, (q31_t)0x43ddece8, (q31_t)0x43d8990a, (q31_t)0x43d34501, + (q31_t)0x43cdf0ce, (q31_t)0x43c89c72, (q31_t)0x43c347eb, (q31_t)0x43bdf33b, (q31_t)0x43b89e62, (q31_t)0x43b3495e, (q31_t)0x43adf431, (q31_t)0x43a89ed9, + (q31_t)0x43a34959, (q31_t)0x439df3ae, (q31_t)0x43989dda, (q31_t)0x439347dc, (q31_t)0x438df1b4, (q31_t)0x43889b63, (q31_t)0x438344e8, (q31_t)0x437dee43, + (q31_t)0x43789775, (q31_t)0x4373407d, (q31_t)0x436de95b, (q31_t)0x43689210, (q31_t)0x43633a9c, (q31_t)0x435de2fd, (q31_t)0x43588b36, (q31_t)0x43533344, + (q31_t)0x434ddb29, (q31_t)0x434882e5, (q31_t)0x43432a77, (q31_t)0x433dd1e0, (q31_t)0x4338791f, (q31_t)0x43332035, (q31_t)0x432dc721, (q31_t)0x43286de4, + (q31_t)0x4323147d, (q31_t)0x431dbaed, (q31_t)0x43186133, (q31_t)0x43130751, (q31_t)0x430dad44, (q31_t)0x4308530f, (q31_t)0x4302f8b0, (q31_t)0x42fd9e28, + (q31_t)0x42f84376, (q31_t)0x42f2e89b, (q31_t)0x42ed8d97, (q31_t)0x42e83269, (q31_t)0x42e2d713, (q31_t)0x42dd7b93, (q31_t)0x42d81fe9, (q31_t)0x42d2c417, + (q31_t)0x42cd681b, (q31_t)0x42c80bf6, (q31_t)0x42c2afa8, (q31_t)0x42bd5331, (q31_t)0x42b7f690, (q31_t)0x42b299c7, (q31_t)0x42ad3cd4, (q31_t)0x42a7dfb8, + (q31_t)0x42a28273, (q31_t)0x429d2505, (q31_t)0x4297c76e, (q31_t)0x429269ae, (q31_t)0x428d0bc4, (q31_t)0x4287adb2, (q31_t)0x42824f76, (q31_t)0x427cf112, + (q31_t)0x42779285, (q31_t)0x427233ce, (q31_t)0x426cd4ef, (q31_t)0x426775e6, (q31_t)0x426216b5, (q31_t)0x425cb75a, (q31_t)0x425757d7, (q31_t)0x4251f82b, + (q31_t)0x424c9856, (q31_t)0x42473858, (q31_t)0x4241d831, (q31_t)0x423c77e1, (q31_t)0x42371769, (q31_t)0x4231b6c7, (q31_t)0x422c55fd, (q31_t)0x4226f50a, + (q31_t)0x422193ee, (q31_t)0x421c32a9, (q31_t)0x4216d13c, (q31_t)0x42116fa5, (q31_t)0x420c0de6, (q31_t)0x4206abfe, (q31_t)0x420149ee, (q31_t)0x41fbe7b5, + (q31_t)0x41f68553, (q31_t)0x41f122c8, (q31_t)0x41ebc015, (q31_t)0x41e65d39, (q31_t)0x41e0fa35, (q31_t)0x41db9707, (q31_t)0x41d633b1, (q31_t)0x41d0d033, + (q31_t)0x41cb6c8c, (q31_t)0x41c608bc, (q31_t)0x41c0a4c4, (q31_t)0x41bb40a3, (q31_t)0x41b5dc5a, (q31_t)0x41b077e8, (q31_t)0x41ab134e, (q31_t)0x41a5ae8b, + (q31_t)0x41a049a0, (q31_t)0x419ae48c, (q31_t)0x41957f4f, (q31_t)0x419019eb, (q31_t)0x418ab45d, (q31_t)0x41854ea8, (q31_t)0x417fe8ca, (q31_t)0x417a82c3, + (q31_t)0x41751c94, (q31_t)0x416fb63d, (q31_t)0x416a4fbd, (q31_t)0x4164e916, (q31_t)0x415f8245, (q31_t)0x415a1b4d, (q31_t)0x4154b42c, (q31_t)0x414f4ce2, + (q31_t)0x4149e571, (q31_t)0x41447dd7, (q31_t)0x413f1615, (q31_t)0x4139ae2b, (q31_t)0x41344618, (q31_t)0x412edddd, (q31_t)0x4129757b, (q31_t)0x41240cef, + (q31_t)0x411ea43c, (q31_t)0x41193b61, (q31_t)0x4113d25d, (q31_t)0x410e6931, (q31_t)0x4108ffdd, (q31_t)0x41039661, (q31_t)0x40fe2cbd, (q31_t)0x40f8c2f1, + (q31_t)0x40f358fc, (q31_t)0x40edeee0, (q31_t)0x40e8849b, (q31_t)0x40e31a2f, (q31_t)0x40ddaf9b, (q31_t)0x40d844de, (q31_t)0x40d2d9f9, (q31_t)0x40cd6eed, + (q31_t)0x40c803b8, (q31_t)0x40c2985c, (q31_t)0x40bd2cd8, (q31_t)0x40b7c12b, (q31_t)0x40b25557, (q31_t)0x40ace95b, (q31_t)0x40a77d37, (q31_t)0x40a210eb, + (q31_t)0x409ca477, (q31_t)0x409737dc, (q31_t)0x4091cb18, (q31_t)0x408c5e2d, (q31_t)0x4086f11a, (q31_t)0x408183df, (q31_t)0x407c167c, (q31_t)0x4076a8f1, + (q31_t)0x40713b3f, (q31_t)0x406bcd65, (q31_t)0x40665f63, (q31_t)0x4060f13a, (q31_t)0x405b82e9, (q31_t)0x40561470, (q31_t)0x4050a5cf, (q31_t)0x404b3707, + (q31_t)0x4045c817, (q31_t)0x404058ff, (q31_t)0x403ae9c0, (q31_t)0x40357a59, (q31_t)0x40300acb, (q31_t)0x402a9b15, (q31_t)0x40252b37, (q31_t)0x401fbb32, + (q31_t)0x401a4b05, (q31_t)0x4014dab1, (q31_t)0x400f6a35, (q31_t)0x4009f992, (q31_t)0x400488c7, (q31_t)0x3fff17d5, (q31_t)0x3ff9a6bb, (q31_t)0x3ff4357a, + (q31_t)0x3feec411, (q31_t)0x3fe95281, (q31_t)0x3fe3e0c9, (q31_t)0x3fde6eeb, (q31_t)0x3fd8fce4, (q31_t)0x3fd38ab6, (q31_t)0x3fce1861, (q31_t)0x3fc8a5e5, + (q31_t)0x3fc33341, (q31_t)0x3fbdc076, (q31_t)0x3fb84d83, (q31_t)0x3fb2da6a, (q31_t)0x3fad6729, (q31_t)0x3fa7f3c0, (q31_t)0x3fa28031, (q31_t)0x3f9d0c7a, + (q31_t)0x3f97989c, (q31_t)0x3f922496, (q31_t)0x3f8cb06a, (q31_t)0x3f873c16, (q31_t)0x3f81c79b, (q31_t)0x3f7c52f9, (q31_t)0x3f76de30, (q31_t)0x3f71693f, + (q31_t)0x3f6bf428, (q31_t)0x3f667ee9, (q31_t)0x3f610983, (q31_t)0x3f5b93f6, (q31_t)0x3f561e42, (q31_t)0x3f50a867, (q31_t)0x3f4b3265, (q31_t)0x3f45bc3c, + (q31_t)0x3f4045ec, (q31_t)0x3f3acf75, (q31_t)0x3f3558d7, (q31_t)0x3f2fe211, (q31_t)0x3f2a6b25, (q31_t)0x3f24f412, (q31_t)0x3f1f7cd8, (q31_t)0x3f1a0577, + (q31_t)0x3f148def, (q31_t)0x3f0f1640, (q31_t)0x3f099e6b, (q31_t)0x3f04266e, (q31_t)0x3efeae4a, (q31_t)0x3ef93600, (q31_t)0x3ef3bd8f, (q31_t)0x3eee44f7, + (q31_t)0x3ee8cc38, (q31_t)0x3ee35352, (q31_t)0x3eddda46, (q31_t)0x3ed86113, (q31_t)0x3ed2e7b9, (q31_t)0x3ecd6e38, (q31_t)0x3ec7f491, (q31_t)0x3ec27ac2, + (q31_t)0x3ebd00cd, (q31_t)0x3eb786b2, (q31_t)0x3eb20c6f, (q31_t)0x3eac9206, (q31_t)0x3ea71777, (q31_t)0x3ea19cc1, (q31_t)0x3e9c21e4, (q31_t)0x3e96a6e0, + (q31_t)0x3e912bb6, (q31_t)0x3e8bb065, (q31_t)0x3e8634ee, (q31_t)0x3e80b950, (q31_t)0x3e7b3d8c, (q31_t)0x3e75c1a1, (q31_t)0x3e70458f, (q31_t)0x3e6ac957, + (q31_t)0x3e654cf8, (q31_t)0x3e5fd073, (q31_t)0x3e5a53c8, (q31_t)0x3e54d6f6, (q31_t)0x3e4f59fe, (q31_t)0x3e49dcdf, (q31_t)0x3e445f99, (q31_t)0x3e3ee22e, + (q31_t)0x3e39649c, (q31_t)0x3e33e6e3, (q31_t)0x3e2e6904, (q31_t)0x3e28eaff, (q31_t)0x3e236cd4, (q31_t)0x3e1dee82, (q31_t)0x3e18700a, (q31_t)0x3e12f16b, + (q31_t)0x3e0d72a6, (q31_t)0x3e07f3bb, (q31_t)0x3e0274aa, (q31_t)0x3dfcf572, (q31_t)0x3df77615, (q31_t)0x3df1f691, (q31_t)0x3dec76e6, (q31_t)0x3de6f716, + (q31_t)0x3de1771f, (q31_t)0x3ddbf703, (q31_t)0x3dd676c0, (q31_t)0x3dd0f656, (q31_t)0x3dcb75c7, (q31_t)0x3dc5f512, (q31_t)0x3dc07436, (q31_t)0x3dbaf335, + (q31_t)0x3db5720d, (q31_t)0x3daff0c0, (q31_t)0x3daa6f4c, (q31_t)0x3da4edb2, (q31_t)0x3d9f6bf2, (q31_t)0x3d99ea0d, (q31_t)0x3d946801, (q31_t)0x3d8ee5cf, + (q31_t)0x3d896377, (q31_t)0x3d83e0f9, (q31_t)0x3d7e5e56, (q31_t)0x3d78db8c, (q31_t)0x3d73589d, (q31_t)0x3d6dd587, (q31_t)0x3d68524c, (q31_t)0x3d62ceeb, + (q31_t)0x3d5d4b64, (q31_t)0x3d57c7b7, (q31_t)0x3d5243e4, (q31_t)0x3d4cbfeb, (q31_t)0x3d473bcd, (q31_t)0x3d41b789, (q31_t)0x3d3c331f, (q31_t)0x3d36ae8f, + (q31_t)0x3d3129da, (q31_t)0x3d2ba4fe, (q31_t)0x3d261ffd, (q31_t)0x3d209ad7, (q31_t)0x3d1b158a, (q31_t)0x3d159018, (q31_t)0x3d100a80, (q31_t)0x3d0a84c3, + (q31_t)0x3d04fee0, (q31_t)0x3cff78d7, (q31_t)0x3cf9f2a9, (q31_t)0x3cf46c55, (q31_t)0x3ceee5db, (q31_t)0x3ce95f3c, (q31_t)0x3ce3d877, (q31_t)0x3cde518d, + (q31_t)0x3cd8ca7d, (q31_t)0x3cd34347, (q31_t)0x3ccdbbed, (q31_t)0x3cc8346c, (q31_t)0x3cc2acc6, (q31_t)0x3cbd24fb, (q31_t)0x3cb79d0a, (q31_t)0x3cb214f4, + (q31_t)0x3cac8cb8, (q31_t)0x3ca70457, (q31_t)0x3ca17bd0, (q31_t)0x3c9bf324, (q31_t)0x3c966a53, (q31_t)0x3c90e15c, (q31_t)0x3c8b5840, (q31_t)0x3c85cefe, + (q31_t)0x3c804598, (q31_t)0x3c7abc0c, (q31_t)0x3c75325a, (q31_t)0x3c6fa883, (q31_t)0x3c6a1e87, (q31_t)0x3c649466, (q31_t)0x3c5f0a20, (q31_t)0x3c597fb4, + (q31_t)0x3c53f523, (q31_t)0x3c4e6a6d, (q31_t)0x3c48df91, (q31_t)0x3c435491, (q31_t)0x3c3dc96b, (q31_t)0x3c383e20, (q31_t)0x3c32b2b0, (q31_t)0x3c2d271b, + (q31_t)0x3c279b61, (q31_t)0x3c220f81, (q31_t)0x3c1c837d, (q31_t)0x3c16f753, (q31_t)0x3c116b04, (q31_t)0x3c0bde91, (q31_t)0x3c0651f8, (q31_t)0x3c00c53a, + (q31_t)0x3bfb3857, (q31_t)0x3bf5ab50, (q31_t)0x3bf01e23, (q31_t)0x3bea90d1, (q31_t)0x3be5035a, (q31_t)0x3bdf75bf, (q31_t)0x3bd9e7fe, (q31_t)0x3bd45a19, + (q31_t)0x3bcecc0e, (q31_t)0x3bc93ddf, (q31_t)0x3bc3af8b, (q31_t)0x3bbe2112, (q31_t)0x3bb89274, (q31_t)0x3bb303b1, (q31_t)0x3bad74c9, (q31_t)0x3ba7e5bd, + (q31_t)0x3ba2568c, (q31_t)0x3b9cc736, (q31_t)0x3b9737bb, (q31_t)0x3b91a81c, (q31_t)0x3b8c1857, (q31_t)0x3b86886e, (q31_t)0x3b80f861, (q31_t)0x3b7b682e, + (q31_t)0x3b75d7d7, (q31_t)0x3b70475c, (q31_t)0x3b6ab6bb, (q31_t)0x3b6525f6, (q31_t)0x3b5f950c, (q31_t)0x3b5a03fe, (q31_t)0x3b5472cb, (q31_t)0x3b4ee173, + (q31_t)0x3b494ff7, (q31_t)0x3b43be57, (q31_t)0x3b3e2c91, (q31_t)0x3b389aa8, (q31_t)0x3b330899, (q31_t)0x3b2d7666, (q31_t)0x3b27e40f, (q31_t)0x3b225193, + (q31_t)0x3b1cbef3, (q31_t)0x3b172c2e, (q31_t)0x3b119945, (q31_t)0x3b0c0637, (q31_t)0x3b067305, (q31_t)0x3b00dfaf, (q31_t)0x3afb4c34, (q31_t)0x3af5b894, + (q31_t)0x3af024d1, (q31_t)0x3aea90e9, (q31_t)0x3ae4fcdc, (q31_t)0x3adf68ac, (q31_t)0x3ad9d457, (q31_t)0x3ad43fdd, (q31_t)0x3aceab40, (q31_t)0x3ac9167e, + (q31_t)0x3ac38198, (q31_t)0x3abdec8d, (q31_t)0x3ab8575f, (q31_t)0x3ab2c20c, (q31_t)0x3aad2c95, (q31_t)0x3aa796fa, (q31_t)0x3aa2013a, (q31_t)0x3a9c6b57, + (q31_t)0x3a96d54f, (q31_t)0x3a913f23, (q31_t)0x3a8ba8d3, (q31_t)0x3a86125f, (q31_t)0x3a807bc7, (q31_t)0x3a7ae50a, (q31_t)0x3a754e2a, (q31_t)0x3a6fb726, + (q31_t)0x3a6a1ffd, (q31_t)0x3a6488b1, (q31_t)0x3a5ef140, (q31_t)0x3a5959ab, (q31_t)0x3a53c1f3, (q31_t)0x3a4e2a16, (q31_t)0x3a489216, (q31_t)0x3a42f9f2, + (q31_t)0x3a3d61a9, (q31_t)0x3a37c93d, (q31_t)0x3a3230ad, (q31_t)0x3a2c97f9, (q31_t)0x3a26ff21, (q31_t)0x3a216625, (q31_t)0x3a1bcd05, (q31_t)0x3a1633c1, + (q31_t)0x3a109a5a, (q31_t)0x3a0b00cf, (q31_t)0x3a056720, (q31_t)0x39ffcd4d, (q31_t)0x39fa3356, (q31_t)0x39f4993c, (q31_t)0x39eefefe, (q31_t)0x39e9649c, + (q31_t)0x39e3ca17, (q31_t)0x39de2f6d, (q31_t)0x39d894a0, (q31_t)0x39d2f9b0, (q31_t)0x39cd5e9b, (q31_t)0x39c7c363, (q31_t)0x39c22808, (q31_t)0x39bc8c89, + (q31_t)0x39b6f0e6, (q31_t)0x39b1551f, (q31_t)0x39abb935, (q31_t)0x39a61d28, (q31_t)0x39a080f6, (q31_t)0x399ae4a2, (q31_t)0x39954829, (q31_t)0x398fab8e, + (q31_t)0x398a0ece, (q31_t)0x398471ec, (q31_t)0x397ed4e5, (q31_t)0x397937bc, (q31_t)0x39739a6e, (q31_t)0x396dfcfe, (q31_t)0x39685f6a, (q31_t)0x3962c1b2, + (q31_t)0x395d23d7, (q31_t)0x395785d9, (q31_t)0x3951e7b8, (q31_t)0x394c4973, (q31_t)0x3946ab0a, (q31_t)0x39410c7f, (q31_t)0x393b6dd0, (q31_t)0x3935cefd, + (q31_t)0x39303008, (q31_t)0x392a90ef, (q31_t)0x3924f1b3, (q31_t)0x391f5254, (q31_t)0x3919b2d1, (q31_t)0x3914132b, (q31_t)0x390e7362, (q31_t)0x3908d376, + (q31_t)0x39033367, (q31_t)0x38fd9334, (q31_t)0x38f7f2de, (q31_t)0x38f25266, (q31_t)0x38ecb1ca, (q31_t)0x38e7110a, (q31_t)0x38e17028, (q31_t)0x38dbcf23, + (q31_t)0x38d62dfb, (q31_t)0x38d08caf, (q31_t)0x38caeb41, (q31_t)0x38c549af, (q31_t)0x38bfa7fb, (q31_t)0x38ba0623, (q31_t)0x38b46429, (q31_t)0x38aec20b, + (q31_t)0x38a91fcb, (q31_t)0x38a37d67, (q31_t)0x389ddae1, (q31_t)0x38983838, (q31_t)0x3892956c, (q31_t)0x388cf27d, (q31_t)0x38874f6b, (q31_t)0x3881ac36, + (q31_t)0x387c08de, (q31_t)0x38766564, (q31_t)0x3870c1c6, (q31_t)0x386b1e06, (q31_t)0x38657a23, (q31_t)0x385fd61d, (q31_t)0x385a31f5, (q31_t)0x38548daa, + (q31_t)0x384ee93b, (q31_t)0x384944ab, (q31_t)0x38439ff7, (q31_t)0x383dfb21, (q31_t)0x38385628, (q31_t)0x3832b10d, (q31_t)0x382d0bce, (q31_t)0x3827666d, + (q31_t)0x3821c0ea, (q31_t)0x381c1b44, (q31_t)0x3816757b, (q31_t)0x3810cf90, (q31_t)0x380b2982, (q31_t)0x38058351, (q31_t)0x37ffdcfe, (q31_t)0x37fa3688, + (q31_t)0x37f48ff0, (q31_t)0x37eee936, (q31_t)0x37e94259, (q31_t)0x37e39b59, (q31_t)0x37ddf437, (q31_t)0x37d84cf2, (q31_t)0x37d2a58b, (q31_t)0x37ccfe02, + (q31_t)0x37c75656, (q31_t)0x37c1ae87, (q31_t)0x37bc0697, (q31_t)0x37b65e84, (q31_t)0x37b0b64e, (q31_t)0x37ab0df6, (q31_t)0x37a5657c, (q31_t)0x379fbce0, + (q31_t)0x379a1421, (q31_t)0x37946b40, (q31_t)0x378ec23d, (q31_t)0x37891917, (q31_t)0x37836fcf, (q31_t)0x377dc665, (q31_t)0x37781cd9, (q31_t)0x3772732a, + (q31_t)0x376cc959, (q31_t)0x37671f66, (q31_t)0x37617551, (q31_t)0x375bcb1a, (q31_t)0x375620c1, (q31_t)0x37507645, (q31_t)0x374acba7, (q31_t)0x374520e7, + (q31_t)0x373f7606, (q31_t)0x3739cb02, (q31_t)0x37341fdc, (q31_t)0x372e7493, (q31_t)0x3728c929, (q31_t)0x37231d9d, (q31_t)0x371d71ef, (q31_t)0x3717c61f, + (q31_t)0x37121a2d, (q31_t)0x370c6e19, (q31_t)0x3706c1e2, (q31_t)0x3701158a, (q31_t)0x36fb6910, (q31_t)0x36f5bc75, (q31_t)0x36f00fb7, (q31_t)0x36ea62d7, + (q31_t)0x36e4b5d6, (q31_t)0x36df08b2, (q31_t)0x36d95b6d, (q31_t)0x36d3ae06, (q31_t)0x36ce007d, (q31_t)0x36c852d2, (q31_t)0x36c2a506, (q31_t)0x36bcf718, + (q31_t)0x36b74908, (q31_t)0x36b19ad6, (q31_t)0x36abec82, (q31_t)0x36a63e0d, (q31_t)0x36a08f76, (q31_t)0x369ae0bd, (q31_t)0x369531e3, (q31_t)0x368f82e7, + (q31_t)0x3689d3c9, (q31_t)0x3684248a, (q31_t)0x367e7529, (q31_t)0x3678c5a7, (q31_t)0x36731602, (q31_t)0x366d663d, (q31_t)0x3667b655, (q31_t)0x3662064c, + (q31_t)0x365c5622, (q31_t)0x3656a5d6, (q31_t)0x3650f569, (q31_t)0x364b44da, (q31_t)0x36459429, (q31_t)0x363fe357, (q31_t)0x363a3264, (q31_t)0x3634814f, + (q31_t)0x362ed019, (q31_t)0x36291ec1, (q31_t)0x36236d48, (q31_t)0x361dbbad, (q31_t)0x361809f1, (q31_t)0x36125814, (q31_t)0x360ca615, (q31_t)0x3606f3f5, + (q31_t)0x360141b4, (q31_t)0x35fb8f52, (q31_t)0x35f5dcce, (q31_t)0x35f02a28, (q31_t)0x35ea7762, (q31_t)0x35e4c47a, (q31_t)0x35df1171, (q31_t)0x35d95e47, + (q31_t)0x35d3aafc, (q31_t)0x35cdf78f, (q31_t)0x35c84401, (q31_t)0x35c29052, (q31_t)0x35bcdc82, (q31_t)0x35b72891, (q31_t)0x35b1747e, (q31_t)0x35abc04b, + (q31_t)0x35a60bf6, (q31_t)0x35a05781, (q31_t)0x359aa2ea, (q31_t)0x3594ee32, (q31_t)0x358f3959, (q31_t)0x3589845f, (q31_t)0x3583cf44, (q31_t)0x357e1a08, + (q31_t)0x357864ab, (q31_t)0x3572af2d, (q31_t)0x356cf98e, (q31_t)0x356743ce, (q31_t)0x35618ded, (q31_t)0x355bd7eb, (q31_t)0x355621c9, (q31_t)0x35506b85, + (q31_t)0x354ab520, (q31_t)0x3544fe9b, (q31_t)0x353f47f5, (q31_t)0x3539912e, (q31_t)0x3533da46, (q31_t)0x352e233d, (q31_t)0x35286c14, (q31_t)0x3522b4c9, + (q31_t)0x351cfd5e, (q31_t)0x351745d2, (q31_t)0x35118e26, (q31_t)0x350bd658, (q31_t)0x35061e6a, (q31_t)0x3500665c, (q31_t)0x34faae2c, (q31_t)0x34f4f5dc, + (q31_t)0x34ef3d6b, (q31_t)0x34e984da, (q31_t)0x34e3cc28, (q31_t)0x34de1355, (q31_t)0x34d85a62, (q31_t)0x34d2a14e, (q31_t)0x34cce819, (q31_t)0x34c72ec4, + (q31_t)0x34c1754e, (q31_t)0x34bbbbb8, (q31_t)0x34b60202, (q31_t)0x34b0482a, (q31_t)0x34aa8e33, (q31_t)0x34a4d41a, (q31_t)0x349f19e2, (q31_t)0x34995f88, + (q31_t)0x3493a50f, (q31_t)0x348dea75, (q31_t)0x34882fba, (q31_t)0x348274e0, (q31_t)0x347cb9e4, (q31_t)0x3476fec9, (q31_t)0x3471438d, (q31_t)0x346b8830, + (q31_t)0x3465ccb4, (q31_t)0x34601117, (q31_t)0x345a5559, (q31_t)0x3454997c, (q31_t)0x344edd7e, (q31_t)0x34492160, (q31_t)0x34436521, (q31_t)0x343da8c3, + (q31_t)0x3437ec44, (q31_t)0x34322fa5, (q31_t)0x342c72e6, (q31_t)0x3426b606, (q31_t)0x3420f907, (q31_t)0x341b3be7, (q31_t)0x34157ea7, (q31_t)0x340fc147, + (q31_t)0x340a03c7, (q31_t)0x34044626, (q31_t)0x33fe8866, (q31_t)0x33f8ca86, (q31_t)0x33f30c85, (q31_t)0x33ed4e65, (q31_t)0x33e79024, (q31_t)0x33e1d1c4, + (q31_t)0x33dc1343, (q31_t)0x33d654a2, (q31_t)0x33d095e2, (q31_t)0x33cad701, (q31_t)0x33c51801, (q31_t)0x33bf58e1, (q31_t)0x33b999a0, (q31_t)0x33b3da40, + (q31_t)0x33ae1ac0, (q31_t)0x33a85b20, (q31_t)0x33a29b60, (q31_t)0x339cdb81, (q31_t)0x33971b81, (q31_t)0x33915b62, (q31_t)0x338b9b22, (q31_t)0x3385dac4, + (q31_t)0x33801a45, (q31_t)0x337a59a6, (q31_t)0x337498e8, (q31_t)0x336ed80a, (q31_t)0x3369170c, (q31_t)0x336355ef, (q31_t)0x335d94b2, (q31_t)0x3357d355, + (q31_t)0x335211d8, (q31_t)0x334c503c, (q31_t)0x33468e80, (q31_t)0x3340cca5, (q31_t)0x333b0aaa, (q31_t)0x3335488f, (q31_t)0x332f8655, (q31_t)0x3329c3fb, + (q31_t)0x33240182, (q31_t)0x331e3ee9, (q31_t)0x33187c31, (q31_t)0x3312b959, (q31_t)0x330cf661, (q31_t)0x3307334a, (q31_t)0x33017014, (q31_t)0x32fbacbe, + (q31_t)0x32f5e948, (q31_t)0x32f025b4, (q31_t)0x32ea61ff, (q31_t)0x32e49e2c, (q31_t)0x32deda39, (q31_t)0x32d91626, (q31_t)0x32d351f5, (q31_t)0x32cd8da4, + (q31_t)0x32c7c933, (q31_t)0x32c204a3, (q31_t)0x32bc3ff4, (q31_t)0x32b67b26, (q31_t)0x32b0b638, (q31_t)0x32aaf12b, (q31_t)0x32a52bff, (q31_t)0x329f66b4, + (q31_t)0x3299a149, (q31_t)0x3293dbbf, (q31_t)0x328e1616, (q31_t)0x3288504e, (q31_t)0x32828a67, (q31_t)0x327cc460, (q31_t)0x3276fe3a, (q31_t)0x327137f6, + (q31_t)0x326b7192, (q31_t)0x3265ab0f, (q31_t)0x325fe46c, (q31_t)0x325a1dab, (q31_t)0x325456cb, (q31_t)0x324e8fcc, (q31_t)0x3248c8ad, (q31_t)0x32430170, + (q31_t)0x323d3a14, (q31_t)0x32377298, (q31_t)0x3231aafe, (q31_t)0x322be345, (q31_t)0x32261b6c, (q31_t)0x32205375, (q31_t)0x321a8b5f, (q31_t)0x3214c32a, + (q31_t)0x320efad6, (q31_t)0x32093263, (q31_t)0x320369d2, (q31_t)0x31fda121, (q31_t)0x31f7d852, (q31_t)0x31f20f64, (q31_t)0x31ec4657, (q31_t)0x31e67d2b, + (q31_t)0x31e0b3e0, (q31_t)0x31daea77, (q31_t)0x31d520ef, (q31_t)0x31cf5748, (q31_t)0x31c98d83, (q31_t)0x31c3c39e, (q31_t)0x31bdf99b, (q31_t)0x31b82f7a, + (q31_t)0x31b2653a, (q31_t)0x31ac9adb, (q31_t)0x31a6d05d, (q31_t)0x31a105c1, (q31_t)0x319b3b06, (q31_t)0x3195702d, (q31_t)0x318fa535, (q31_t)0x3189da1e, + (q31_t)0x31840ee9, (q31_t)0x317e4395, (q31_t)0x31787823, (q31_t)0x3172ac92, (q31_t)0x316ce0e3, (q31_t)0x31671515, (q31_t)0x31614929, (q31_t)0x315b7d1e, + (q31_t)0x3155b0f5, (q31_t)0x314fe4ae, (q31_t)0x314a1848, (q31_t)0x31444bc3, (q31_t)0x313e7f21, (q31_t)0x3138b260, (q31_t)0x3132e580, (q31_t)0x312d1882, + (q31_t)0x31274b66, (q31_t)0x31217e2c, (q31_t)0x311bb0d3, (q31_t)0x3115e35c, (q31_t)0x311015c6, (q31_t)0x310a4813, (q31_t)0x31047a41, (q31_t)0x30feac51, + (q31_t)0x30f8de42, (q31_t)0x30f31016, (q31_t)0x30ed41cb, (q31_t)0x30e77362, (q31_t)0x30e1a4db, (q31_t)0x30dbd636, (q31_t)0x30d60772, (q31_t)0x30d03891, + (q31_t)0x30ca6991, (q31_t)0x30c49a74, (q31_t)0x30becb38, (q31_t)0x30b8fbde, (q31_t)0x30b32c66, (q31_t)0x30ad5cd0, (q31_t)0x30a78d1c, (q31_t)0x30a1bd4a, + (q31_t)0x309bed5a, (q31_t)0x30961d4c, (q31_t)0x30904d20, (q31_t)0x308a7cd6, (q31_t)0x3084ac6e, (q31_t)0x307edbe9, (q31_t)0x30790b45, (q31_t)0x30733a83, + (q31_t)0x306d69a4, (q31_t)0x306798a7, (q31_t)0x3061c78b, (q31_t)0x305bf652, (q31_t)0x305624fb, (q31_t)0x30505387, (q31_t)0x304a81f4, (q31_t)0x3044b044, + (q31_t)0x303ede76, (q31_t)0x30390c8a, (q31_t)0x30333a80, (q31_t)0x302d6859, (q31_t)0x30279614, (q31_t)0x3021c3b1, (q31_t)0x301bf131, (q31_t)0x30161e93, + (q31_t)0x30104bd7, (q31_t)0x300a78fe, (q31_t)0x3004a607, (q31_t)0x2ffed2f2, (q31_t)0x2ff8ffc0, (q31_t)0x2ff32c70, (q31_t)0x2fed5902, (q31_t)0x2fe78577, + (q31_t)0x2fe1b1cf, (q31_t)0x2fdbde09, (q31_t)0x2fd60a25, (q31_t)0x2fd03624, (q31_t)0x2fca6206, (q31_t)0x2fc48dc9, (q31_t)0x2fbeb970, (q31_t)0x2fb8e4f9, + (q31_t)0x2fb31064, (q31_t)0x2fad3bb3, (q31_t)0x2fa766e3, (q31_t)0x2fa191f7, (q31_t)0x2f9bbced, (q31_t)0x2f95e7c5, (q31_t)0x2f901280, (q31_t)0x2f8a3d1e, + (q31_t)0x2f84679f, (q31_t)0x2f7e9202, (q31_t)0x2f78bc48, (q31_t)0x2f72e671, (q31_t)0x2f6d107c, (q31_t)0x2f673a6a, (q31_t)0x2f61643b, (q31_t)0x2f5b8def, + (q31_t)0x2f55b785, (q31_t)0x2f4fe0ff, (q31_t)0x2f4a0a5b, (q31_t)0x2f44339a, (q31_t)0x2f3e5cbb, (q31_t)0x2f3885c0, (q31_t)0x2f32aea8, (q31_t)0x2f2cd772, + (q31_t)0x2f27001f, (q31_t)0x2f2128af, (q31_t)0x2f1b5122, (q31_t)0x2f157979, (q31_t)0x2f0fa1b2, (q31_t)0x2f09c9ce, (q31_t)0x2f03f1cd, (q31_t)0x2efe19ae, + (q31_t)0x2ef84173, (q31_t)0x2ef2691b, (q31_t)0x2eec90a7, (q31_t)0x2ee6b815, (q31_t)0x2ee0df66, (q31_t)0x2edb069a, (q31_t)0x2ed52db1, (q31_t)0x2ecf54ac, + (q31_t)0x2ec97b89, (q31_t)0x2ec3a24a, (q31_t)0x2ebdc8ee, (q31_t)0x2eb7ef75, (q31_t)0x2eb215df, (q31_t)0x2eac3c2d, (q31_t)0x2ea6625d, (q31_t)0x2ea08871, + (q31_t)0x2e9aae68, (q31_t)0x2e94d443, (q31_t)0x2e8efa00, (q31_t)0x2e891fa1, (q31_t)0x2e834525, (q31_t)0x2e7d6a8d, (q31_t)0x2e778fd8, (q31_t)0x2e71b506, + (q31_t)0x2e6bda17, (q31_t)0x2e65ff0c, (q31_t)0x2e6023e5, (q31_t)0x2e5a48a0, (q31_t)0x2e546d3f, (q31_t)0x2e4e91c2, (q31_t)0x2e48b628, (q31_t)0x2e42da71, + (q31_t)0x2e3cfe9e, (q31_t)0x2e3722ae, (q31_t)0x2e3146a2, (q31_t)0x2e2b6a79, (q31_t)0x2e258e34, (q31_t)0x2e1fb1d3, (q31_t)0x2e19d554, (q31_t)0x2e13f8ba, + (q31_t)0x2e0e1c03, (q31_t)0x2e083f30, (q31_t)0x2e026240, (q31_t)0x2dfc8534, (q31_t)0x2df6a80b, (q31_t)0x2df0cac6, (q31_t)0x2deaed65, (q31_t)0x2de50fe8, + (q31_t)0x2ddf324e, (q31_t)0x2dd95498, (q31_t)0x2dd376c5, (q31_t)0x2dcd98d7, (q31_t)0x2dc7bacc, (q31_t)0x2dc1dca4, (q31_t)0x2dbbfe61, (q31_t)0x2db62001, + (q31_t)0x2db04186, (q31_t)0x2daa62ee, (q31_t)0x2da4843a, (q31_t)0x2d9ea569, (q31_t)0x2d98c67d, (q31_t)0x2d92e774, (q31_t)0x2d8d084f, (q31_t)0x2d87290f, + (q31_t)0x2d8149b2, (q31_t)0x2d7b6a39, (q31_t)0x2d758aa4, (q31_t)0x2d6faaf3, (q31_t)0x2d69cb26, (q31_t)0x2d63eb3d, (q31_t)0x2d5e0b38, (q31_t)0x2d582b17, + (q31_t)0x2d524ada, (q31_t)0x2d4c6a81, (q31_t)0x2d468a0c, (q31_t)0x2d40a97b, (q31_t)0x2d3ac8ce, (q31_t)0x2d34e805, (q31_t)0x2d2f0721, (q31_t)0x2d292620, + (q31_t)0x2d234504, (q31_t)0x2d1d63cc, (q31_t)0x2d178278, (q31_t)0x2d11a108, (q31_t)0x2d0bbf7d, (q31_t)0x2d05ddd5, (q31_t)0x2cfffc12, (q31_t)0x2cfa1a33, + (q31_t)0x2cf43839, (q31_t)0x2cee5622, (q31_t)0x2ce873f0, (q31_t)0x2ce291a2, (q31_t)0x2cdcaf39, (q31_t)0x2cd6ccb4, (q31_t)0x2cd0ea13, (q31_t)0x2ccb0756, + (q31_t)0x2cc5247e, (q31_t)0x2cbf418b, (q31_t)0x2cb95e7b, (q31_t)0x2cb37b51, (q31_t)0x2cad980a, (q31_t)0x2ca7b4a8, (q31_t)0x2ca1d12a, (q31_t)0x2c9bed91, + (q31_t)0x2c9609dd, (q31_t)0x2c90260d, (q31_t)0x2c8a4221, (q31_t)0x2c845e1a, (q31_t)0x2c7e79f7, (q31_t)0x2c7895b9, (q31_t)0x2c72b160, (q31_t)0x2c6ccceb, + (q31_t)0x2c66e85b, (q31_t)0x2c6103af, (q31_t)0x2c5b1ee8, (q31_t)0x2c553a06, (q31_t)0x2c4f5508, (q31_t)0x2c496fef, (q31_t)0x2c438abb, (q31_t)0x2c3da56b, + (q31_t)0x2c37c000, (q31_t)0x2c31da7a, (q31_t)0x2c2bf4d8, (q31_t)0x2c260f1c, (q31_t)0x2c202944, (q31_t)0x2c1a4351, (q31_t)0x2c145d42, (q31_t)0x2c0e7719, + (q31_t)0x2c0890d4, (q31_t)0x2c02aa74, (q31_t)0x2bfcc3f9, (q31_t)0x2bf6dd63, (q31_t)0x2bf0f6b1, (q31_t)0x2beb0fe5, (q31_t)0x2be528fd, (q31_t)0x2bdf41fb, + (q31_t)0x2bd95add, (q31_t)0x2bd373a4, (q31_t)0x2bcd8c51, (q31_t)0x2bc7a4e2, (q31_t)0x2bc1bd58, (q31_t)0x2bbbd5b3, (q31_t)0x2bb5edf4, (q31_t)0x2bb00619, + (q31_t)0x2baa1e23, (q31_t)0x2ba43613, (q31_t)0x2b9e4de7, (q31_t)0x2b9865a1, (q31_t)0x2b927d3f, (q31_t)0x2b8c94c3, (q31_t)0x2b86ac2c, (q31_t)0x2b80c37a, + (q31_t)0x2b7adaae, (q31_t)0x2b74f1c6, (q31_t)0x2b6f08c4, (q31_t)0x2b691fa6, (q31_t)0x2b63366f, (q31_t)0x2b5d4d1c, (q31_t)0x2b5763ae, (q31_t)0x2b517a26, + (q31_t)0x2b4b9083, (q31_t)0x2b45a6c6, (q31_t)0x2b3fbced, (q31_t)0x2b39d2fa, (q31_t)0x2b33e8ed, (q31_t)0x2b2dfec5, (q31_t)0x2b281482, (q31_t)0x2b222a24, + (q31_t)0x2b1c3fac, (q31_t)0x2b165519, (q31_t)0x2b106a6c, (q31_t)0x2b0a7fa4, (q31_t)0x2b0494c2, (q31_t)0x2afea9c5, (q31_t)0x2af8bead, (q31_t)0x2af2d37b, + (q31_t)0x2aece82f, (q31_t)0x2ae6fcc8, (q31_t)0x2ae11146, (q31_t)0x2adb25aa, (q31_t)0x2ad539f4, (q31_t)0x2acf4e23, (q31_t)0x2ac96238, (q31_t)0x2ac37633, + (q31_t)0x2abd8a13, (q31_t)0x2ab79dd8, (q31_t)0x2ab1b184, (q31_t)0x2aabc515, (q31_t)0x2aa5d88b, (q31_t)0x2a9febe8, (q31_t)0x2a99ff2a, (q31_t)0x2a941252, + (q31_t)0x2a8e255f, (q31_t)0x2a883853, (q31_t)0x2a824b2c, (q31_t)0x2a7c5deb, (q31_t)0x2a76708f, (q31_t)0x2a70831a, (q31_t)0x2a6a958a, (q31_t)0x2a64a7e0, + (q31_t)0x2a5eba1c, (q31_t)0x2a58cc3e, (q31_t)0x2a52de46, (q31_t)0x2a4cf033, (q31_t)0x2a470207, (q31_t)0x2a4113c0, (q31_t)0x2a3b2560, (q31_t)0x2a3536e5, + (q31_t)0x2a2f4850, (q31_t)0x2a2959a1, (q31_t)0x2a236ad9, (q31_t)0x2a1d7bf6, (q31_t)0x2a178cf9, (q31_t)0x2a119de2, (q31_t)0x2a0baeb2, (q31_t)0x2a05bf67, + (q31_t)0x29ffd003, (q31_t)0x29f9e084, (q31_t)0x29f3f0ec, (q31_t)0x29ee013a, (q31_t)0x29e8116e, (q31_t)0x29e22188, (q31_t)0x29dc3188, (q31_t)0x29d6416f, + (q31_t)0x29d0513b, (q31_t)0x29ca60ee, (q31_t)0x29c47087, (q31_t)0x29be8007, (q31_t)0x29b88f6c, (q31_t)0x29b29eb8, (q31_t)0x29acadea, (q31_t)0x29a6bd02, + (q31_t)0x29a0cc01, (q31_t)0x299adae6, (q31_t)0x2994e9b1, (q31_t)0x298ef863, (q31_t)0x298906fb, (q31_t)0x2983157a, (q31_t)0x297d23df, (q31_t)0x2977322a, + (q31_t)0x2971405b, (q31_t)0x296b4e74, (q31_t)0x29655c72, (q31_t)0x295f6a57, (q31_t)0x29597823, (q31_t)0x295385d5, (q31_t)0x294d936d, (q31_t)0x2947a0ec, + (q31_t)0x2941ae52, (q31_t)0x293bbb9e, (q31_t)0x2935c8d1, (q31_t)0x292fd5ea, (q31_t)0x2929e2ea, (q31_t)0x2923efd0, (q31_t)0x291dfc9d, (q31_t)0x29180951, + (q31_t)0x291215eb, (q31_t)0x290c226c, (q31_t)0x29062ed4, (q31_t)0x29003b23, (q31_t)0x28fa4758, (q31_t)0x28f45374, (q31_t)0x28ee5f76, (q31_t)0x28e86b5f, + (q31_t)0x28e27730, (q31_t)0x28dc82e6, (q31_t)0x28d68e84, (q31_t)0x28d09a09, (q31_t)0x28caa574, (q31_t)0x28c4b0c6, (q31_t)0x28bebbff, (q31_t)0x28b8c71f, + (q31_t)0x28b2d226, (q31_t)0x28acdd13, (q31_t)0x28a6e7e8, (q31_t)0x28a0f2a3, (q31_t)0x289afd46, (q31_t)0x289507cf, (q31_t)0x288f123f, (q31_t)0x28891c97, + (q31_t)0x288326d5, (q31_t)0x287d30fa, (q31_t)0x28773b07, (q31_t)0x287144fa, (q31_t)0x286b4ed5, (q31_t)0x28655896, (q31_t)0x285f623f, (q31_t)0x28596bce, + (q31_t)0x28537545, (q31_t)0x284d7ea3, (q31_t)0x284787e8, (q31_t)0x28419114, (q31_t)0x283b9a28, (q31_t)0x2835a322, (q31_t)0x282fac04, (q31_t)0x2829b4cd, + (q31_t)0x2823bd7d, (q31_t)0x281dc615, (q31_t)0x2817ce93, (q31_t)0x2811d6f9, (q31_t)0x280bdf46, (q31_t)0x2805e77b, (q31_t)0x27ffef97, (q31_t)0x27f9f79a, + (q31_t)0x27f3ff85, (q31_t)0x27ee0756, (q31_t)0x27e80f10, (q31_t)0x27e216b0, (q31_t)0x27dc1e38, (q31_t)0x27d625a8, (q31_t)0x27d02cff, (q31_t)0x27ca343d, + (q31_t)0x27c43b63, (q31_t)0x27be4270, (q31_t)0x27b84965, (q31_t)0x27b25041, (q31_t)0x27ac5705, (q31_t)0x27a65db0, (q31_t)0x27a06443, (q31_t)0x279a6abd, + (q31_t)0x2794711f, (q31_t)0x278e7768, (q31_t)0x27887d99, (q31_t)0x278283b2, (q31_t)0x277c89b3, (q31_t)0x27768f9b, (q31_t)0x2770956a, (q31_t)0x276a9b21, + (q31_t)0x2764a0c0, (q31_t)0x275ea647, (q31_t)0x2758abb6, (q31_t)0x2752b10c, (q31_t)0x274cb64a, (q31_t)0x2746bb6f, (q31_t)0x2740c07d, (q31_t)0x273ac572, + (q31_t)0x2734ca4f, (q31_t)0x272ecf14, (q31_t)0x2728d3c0, (q31_t)0x2722d855, (q31_t)0x271cdcd1, (q31_t)0x2716e136, (q31_t)0x2710e582, (q31_t)0x270ae9b6, + (q31_t)0x2704edd2, (q31_t)0x26fef1d5, (q31_t)0x26f8f5c1, (q31_t)0x26f2f995, (q31_t)0x26ecfd51, (q31_t)0x26e700f5, (q31_t)0x26e10480, (q31_t)0x26db07f4, + (q31_t)0x26d50b50, (q31_t)0x26cf0e94, (q31_t)0x26c911c0, (q31_t)0x26c314d4, (q31_t)0x26bd17d0, (q31_t)0x26b71ab4, (q31_t)0x26b11d80, (q31_t)0x26ab2034, + (q31_t)0x26a522d1, (q31_t)0x269f2556, (q31_t)0x269927c3, (q31_t)0x26932a18, (q31_t)0x268d2c55, (q31_t)0x26872e7b, (q31_t)0x26813088, (q31_t)0x267b327e, + (q31_t)0x2675345d, (q31_t)0x266f3623, (q31_t)0x266937d2, (q31_t)0x26633969, (q31_t)0x265d3ae9, (q31_t)0x26573c50, (q31_t)0x26513da1, (q31_t)0x264b3ed9, + (q31_t)0x26453ffa, (q31_t)0x263f4103, (q31_t)0x263941f5, (q31_t)0x263342cf, (q31_t)0x262d4392, (q31_t)0x2627443d, (q31_t)0x262144d0, (q31_t)0x261b454c, + (q31_t)0x261545b0, (q31_t)0x260f45fd, (q31_t)0x26094633, (q31_t)0x26034651, (q31_t)0x25fd4657, (q31_t)0x25f74646, (q31_t)0x25f1461e, (q31_t)0x25eb45de, + (q31_t)0x25e54587, (q31_t)0x25df4519, (q31_t)0x25d94493, (q31_t)0x25d343f6, (q31_t)0x25cd4341, (q31_t)0x25c74276, (q31_t)0x25c14192, (q31_t)0x25bb4098, + (q31_t)0x25b53f86, (q31_t)0x25af3e5d, (q31_t)0x25a93d1d, (q31_t)0x25a33bc6, (q31_t)0x259d3a57, (q31_t)0x259738d1, (q31_t)0x25913734, (q31_t)0x258b3580, + (q31_t)0x258533b5, (q31_t)0x257f31d2, (q31_t)0x25792fd8, (q31_t)0x25732dc8, (q31_t)0x256d2ba0, (q31_t)0x25672961, (q31_t)0x2561270b, (q31_t)0x255b249e, + (q31_t)0x2555221a, (q31_t)0x254f1f7e, (q31_t)0x25491ccc, (q31_t)0x25431a03, (q31_t)0x253d1723, (q31_t)0x2537142c, (q31_t)0x2531111e, (q31_t)0x252b0df9, + (q31_t)0x25250abd, (q31_t)0x251f076a, (q31_t)0x25190400, (q31_t)0x25130080, (q31_t)0x250cfce8, (q31_t)0x2506f93a, (q31_t)0x2500f574, (q31_t)0x24faf198, + (q31_t)0x24f4eda6, (q31_t)0x24eee99c, (q31_t)0x24e8e57c, (q31_t)0x24e2e144, (q31_t)0x24dcdcf6, (q31_t)0x24d6d892, (q31_t)0x24d0d416, (q31_t)0x24cacf84, + (q31_t)0x24c4cadb, (q31_t)0x24bec61c, (q31_t)0x24b8c146, (q31_t)0x24b2bc59, (q31_t)0x24acb756, (q31_t)0x24a6b23b, (q31_t)0x24a0ad0b, (q31_t)0x249aa7c4, + (q31_t)0x2494a266, (q31_t)0x248e9cf1, (q31_t)0x24889766, (q31_t)0x248291c5, (q31_t)0x247c8c0d, (q31_t)0x2476863e, (q31_t)0x24708059, (q31_t)0x246a7a5e, + (q31_t)0x2464744c, (q31_t)0x245e6e23, (q31_t)0x245867e4, (q31_t)0x2452618f, (q31_t)0x244c5b24, (q31_t)0x244654a1, (q31_t)0x24404e09, (q31_t)0x243a475a, + (q31_t)0x24344095, (q31_t)0x242e39ba, (q31_t)0x242832c8, (q31_t)0x24222bc0, (q31_t)0x241c24a1, (q31_t)0x24161d6d, (q31_t)0x24101622, (q31_t)0x240a0ec1, + (q31_t)0x24040749, (q31_t)0x23fdffbc, (q31_t)0x23f7f818, (q31_t)0x23f1f05e, (q31_t)0x23ebe88e, (q31_t)0x23e5e0a7, (q31_t)0x23dfd8ab, (q31_t)0x23d9d098, + (q31_t)0x23d3c86f, (q31_t)0x23cdc031, (q31_t)0x23c7b7dc, (q31_t)0x23c1af71, (q31_t)0x23bba6f0, (q31_t)0x23b59e59, (q31_t)0x23af95ac, (q31_t)0x23a98ce8, + (q31_t)0x23a3840f, (q31_t)0x239d7b20, (q31_t)0x2397721b, (q31_t)0x23916900, (q31_t)0x238b5fcf, (q31_t)0x23855688, (q31_t)0x237f4d2b, (q31_t)0x237943b9, + (q31_t)0x23733a30, (q31_t)0x236d3092, (q31_t)0x236726dd, (q31_t)0x23611d13, (q31_t)0x235b1333, (q31_t)0x2355093e, (q31_t)0x234eff32, (q31_t)0x2348f511, + (q31_t)0x2342eada, (q31_t)0x233ce08d, (q31_t)0x2336d62a, (q31_t)0x2330cbb2, (q31_t)0x232ac124, (q31_t)0x2324b680, (q31_t)0x231eabc7, (q31_t)0x2318a0f8, + (q31_t)0x23129613, (q31_t)0x230c8b19, (q31_t)0x23068009, (q31_t)0x230074e3, (q31_t)0x22fa69a8, (q31_t)0x22f45e57, (q31_t)0x22ee52f1, (q31_t)0x22e84775, + (q31_t)0x22e23be4, (q31_t)0x22dc303d, (q31_t)0x22d62480, (q31_t)0x22d018ae, (q31_t)0x22ca0cc7, (q31_t)0x22c400ca, (q31_t)0x22bdf4b8, (q31_t)0x22b7e890, + (q31_t)0x22b1dc53, (q31_t)0x22abd001, (q31_t)0x22a5c399, (q31_t)0x229fb71b, (q31_t)0x2299aa89, (q31_t)0x22939de1, (q31_t)0x228d9123, (q31_t)0x22878451, + (q31_t)0x22817769, (q31_t)0x227b6a6c, (q31_t)0x22755d59, (q31_t)0x226f5032, (q31_t)0x226942f5, (q31_t)0x226335a2, (q31_t)0x225d283b, (q31_t)0x22571abe, + (q31_t)0x22510d2d, (q31_t)0x224aff86, (q31_t)0x2244f1c9, (q31_t)0x223ee3f8, (q31_t)0x2238d612, (q31_t)0x2232c816, (q31_t)0x222cba06, (q31_t)0x2226abe0, + (q31_t)0x22209da5, (q31_t)0x221a8f56, (q31_t)0x221480f1, (q31_t)0x220e7277, (q31_t)0x220863e8, (q31_t)0x22025544, (q31_t)0x21fc468b, (q31_t)0x21f637be, + (q31_t)0x21f028db, (q31_t)0x21ea19e3, (q31_t)0x21e40ad7, (q31_t)0x21ddfbb5, (q31_t)0x21d7ec7f, (q31_t)0x21d1dd34, (q31_t)0x21cbcdd3, (q31_t)0x21c5be5e, + (q31_t)0x21bfaed5, (q31_t)0x21b99f36, (q31_t)0x21b38f83, (q31_t)0x21ad7fba, (q31_t)0x21a76fdd, (q31_t)0x21a15fec, (q31_t)0x219b4fe5, (q31_t)0x21953fca, + (q31_t)0x218f2f9a, (q31_t)0x21891f55, (q31_t)0x21830efc, (q31_t)0x217cfe8e, (q31_t)0x2176ee0b, (q31_t)0x2170dd74, (q31_t)0x216accc8, (q31_t)0x2164bc08, + (q31_t)0x215eab33, (q31_t)0x21589a49, (q31_t)0x2152894b, (q31_t)0x214c7838, (q31_t)0x21466710, (q31_t)0x214055d4, (q31_t)0x213a4484, (q31_t)0x2134331f, + (q31_t)0x212e21a6, (q31_t)0x21281018, (q31_t)0x2121fe76, (q31_t)0x211becbf, (q31_t)0x2115daf4, (q31_t)0x210fc914, (q31_t)0x2109b720, (q31_t)0x2103a518, + (q31_t)0x20fd92fb, (q31_t)0x20f780ca, (q31_t)0x20f16e84, (q31_t)0x20eb5c2b, (q31_t)0x20e549bd, (q31_t)0x20df373a, (q31_t)0x20d924a4, (q31_t)0x20d311f9, + (q31_t)0x20ccff3a, (q31_t)0x20c6ec66, (q31_t)0x20c0d97f, (q31_t)0x20bac683, (q31_t)0x20b4b373, (q31_t)0x20aea04f, (q31_t)0x20a88d17, (q31_t)0x20a279ca, + (q31_t)0x209c666a, (q31_t)0x209652f5, (q31_t)0x20903f6c, (q31_t)0x208a2bcf, (q31_t)0x2084181e, (q31_t)0x207e0459, (q31_t)0x2077f080, (q31_t)0x2071dc93, + (q31_t)0x206bc892, (q31_t)0x2065b47d, (q31_t)0x205fa054, (q31_t)0x20598c17, (q31_t)0x205377c6, (q31_t)0x204d6361, (q31_t)0x20474ee8, (q31_t)0x20413a5b, + (q31_t)0x203b25bb, (q31_t)0x20351106, (q31_t)0x202efc3e, (q31_t)0x2028e761, (q31_t)0x2022d271, (q31_t)0x201cbd6d, (q31_t)0x2016a856, (q31_t)0x2010932a, + (q31_t)0x200a7deb, (q31_t)0x20046898, (q31_t)0x1ffe5331, (q31_t)0x1ff83db6, (q31_t)0x1ff22828, (q31_t)0x1fec1286, (q31_t)0x1fe5fcd0, (q31_t)0x1fdfe707, + (q31_t)0x1fd9d12a, (q31_t)0x1fd3bb39, (q31_t)0x1fcda535, (q31_t)0x1fc78f1d, (q31_t)0x1fc178f1, (q31_t)0x1fbb62b2, (q31_t)0x1fb54c60, (q31_t)0x1faf35f9, + (q31_t)0x1fa91f80, (q31_t)0x1fa308f2, (q31_t)0x1f9cf252, (q31_t)0x1f96db9d, (q31_t)0x1f90c4d5, (q31_t)0x1f8aadfa, (q31_t)0x1f84970b, (q31_t)0x1f7e8009, + (q31_t)0x1f7868f4, (q31_t)0x1f7251ca, (q31_t)0x1f6c3a8e, (q31_t)0x1f66233e, (q31_t)0x1f600bdb, (q31_t)0x1f59f465, (q31_t)0x1f53dcdb, (q31_t)0x1f4dc53d, + (q31_t)0x1f47ad8d, (q31_t)0x1f4195c9, (q31_t)0x1f3b7df2, (q31_t)0x1f356608, (q31_t)0x1f2f4e0a, (q31_t)0x1f2935f9, (q31_t)0x1f231dd5, (q31_t)0x1f1d059e, + (q31_t)0x1f16ed54, (q31_t)0x1f10d4f6, (q31_t)0x1f0abc85, (q31_t)0x1f04a401, (q31_t)0x1efe8b6a, (q31_t)0x1ef872c0, (q31_t)0x1ef25a03, (q31_t)0x1eec4132, + (q31_t)0x1ee6284f, (q31_t)0x1ee00f58, (q31_t)0x1ed9f64f, (q31_t)0x1ed3dd32, (q31_t)0x1ecdc402, (q31_t)0x1ec7aac0, (q31_t)0x1ec1916a, (q31_t)0x1ebb7802, + (q31_t)0x1eb55e86, (q31_t)0x1eaf44f8, (q31_t)0x1ea92b56, (q31_t)0x1ea311a2, (q31_t)0x1e9cf7db, (q31_t)0x1e96de01, (q31_t)0x1e90c414, (q31_t)0x1e8aaa14, + (q31_t)0x1e849001, (q31_t)0x1e7e75dc, (q31_t)0x1e785ba3, (q31_t)0x1e724158, (q31_t)0x1e6c26fa, (q31_t)0x1e660c8a, (q31_t)0x1e5ff206, (q31_t)0x1e59d770, + (q31_t)0x1e53bcc7, (q31_t)0x1e4da20c, (q31_t)0x1e47873d, (q31_t)0x1e416c5d, (q31_t)0x1e3b5169, (q31_t)0x1e353663, (q31_t)0x1e2f1b4a, (q31_t)0x1e29001e, + (q31_t)0x1e22e4e0, (q31_t)0x1e1cc990, (q31_t)0x1e16ae2c, (q31_t)0x1e1092b6, (q31_t)0x1e0a772e, (q31_t)0x1e045b93, (q31_t)0x1dfe3fe6, (q31_t)0x1df82426, + (q31_t)0x1df20853, (q31_t)0x1debec6f, (q31_t)0x1de5d077, (q31_t)0x1ddfb46e, (q31_t)0x1dd99851, (q31_t)0x1dd37c23, (q31_t)0x1dcd5fe2, (q31_t)0x1dc7438e, + (q31_t)0x1dc12729, (q31_t)0x1dbb0ab0, (q31_t)0x1db4ee26, (q31_t)0x1daed189, (q31_t)0x1da8b4da, (q31_t)0x1da29819, (q31_t)0x1d9c7b45, (q31_t)0x1d965e5f, + (q31_t)0x1d904167, (q31_t)0x1d8a245c, (q31_t)0x1d840740, (q31_t)0x1d7dea11, (q31_t)0x1d77ccd0, (q31_t)0x1d71af7d, (q31_t)0x1d6b9217, (q31_t)0x1d6574a0, + (q31_t)0x1d5f5716, (q31_t)0x1d59397a, (q31_t)0x1d531bcc, (q31_t)0x1d4cfe0d, (q31_t)0x1d46e03a, (q31_t)0x1d40c256, (q31_t)0x1d3aa460, (q31_t)0x1d348658, + (q31_t)0x1d2e683e, (q31_t)0x1d284a12, (q31_t)0x1d222bd3, (q31_t)0x1d1c0d83, (q31_t)0x1d15ef21, (q31_t)0x1d0fd0ad, (q31_t)0x1d09b227, (q31_t)0x1d03938f, + (q31_t)0x1cfd74e5, (q31_t)0x1cf7562a, (q31_t)0x1cf1375c, (q31_t)0x1ceb187d, (q31_t)0x1ce4f98c, (q31_t)0x1cdeda89, (q31_t)0x1cd8bb74, (q31_t)0x1cd29c4d, + (q31_t)0x1ccc7d15, (q31_t)0x1cc65dca, (q31_t)0x1cc03e6e, (q31_t)0x1cba1f01, (q31_t)0x1cb3ff81, (q31_t)0x1caddff0, (q31_t)0x1ca7c04d, (q31_t)0x1ca1a099, + (q31_t)0x1c9b80d3, (q31_t)0x1c9560fb, (q31_t)0x1c8f4112, (q31_t)0x1c892117, (q31_t)0x1c83010a, (q31_t)0x1c7ce0ec, (q31_t)0x1c76c0bc, (q31_t)0x1c70a07b, + (q31_t)0x1c6a8028, (q31_t)0x1c645fc3, (q31_t)0x1c5e3f4d, (q31_t)0x1c581ec6, (q31_t)0x1c51fe2d, (q31_t)0x1c4bdd83, (q31_t)0x1c45bcc7, (q31_t)0x1c3f9bf9, + (q31_t)0x1c397b1b, (q31_t)0x1c335a2b, (q31_t)0x1c2d3929, (q31_t)0x1c271816, (q31_t)0x1c20f6f2, (q31_t)0x1c1ad5bc, (q31_t)0x1c14b475, (q31_t)0x1c0e931d, + (q31_t)0x1c0871b4, (q31_t)0x1c025039, (q31_t)0x1bfc2ead, (q31_t)0x1bf60d0f, (q31_t)0x1befeb60, (q31_t)0x1be9c9a1, (q31_t)0x1be3a7cf, (q31_t)0x1bdd85ed, + (q31_t)0x1bd763fa, (q31_t)0x1bd141f5, (q31_t)0x1bcb1fdf, (q31_t)0x1bc4fdb8, (q31_t)0x1bbedb80, (q31_t)0x1bb8b937, (q31_t)0x1bb296dc, (q31_t)0x1bac7471, + (q31_t)0x1ba651f5, (q31_t)0x1ba02f67, (q31_t)0x1b9a0cc8, (q31_t)0x1b93ea19, (q31_t)0x1b8dc758, (q31_t)0x1b87a487, (q31_t)0x1b8181a4, (q31_t)0x1b7b5eb0, + (q31_t)0x1b753bac, (q31_t)0x1b6f1897, (q31_t)0x1b68f570, (q31_t)0x1b62d239, (q31_t)0x1b5caef1, (q31_t)0x1b568b98, (q31_t)0x1b50682e, (q31_t)0x1b4a44b3, + (q31_t)0x1b442127, (q31_t)0x1b3dfd8b, (q31_t)0x1b37d9de, (q31_t)0x1b31b620, (q31_t)0x1b2b9251, (q31_t)0x1b256e71, (q31_t)0x1b1f4a81, (q31_t)0x1b192680, + (q31_t)0x1b13026e, (q31_t)0x1b0cde4c, (q31_t)0x1b06ba19, (q31_t)0x1b0095d5, (q31_t)0x1afa7180, (q31_t)0x1af44d1b, (q31_t)0x1aee28a6, (q31_t)0x1ae8041f, + (q31_t)0x1ae1df88, (q31_t)0x1adbbae1, (q31_t)0x1ad59629, (q31_t)0x1acf7160, (q31_t)0x1ac94c87, (q31_t)0x1ac3279d, (q31_t)0x1abd02a3, (q31_t)0x1ab6dd98, + (q31_t)0x1ab0b87d, (q31_t)0x1aaa9352, (q31_t)0x1aa46e16, (q31_t)0x1a9e48c9, (q31_t)0x1a98236c, (q31_t)0x1a91fdff, (q31_t)0x1a8bd881, (q31_t)0x1a85b2f3, + (q31_t)0x1a7f8d54, (q31_t)0x1a7967a6, (q31_t)0x1a7341e6, (q31_t)0x1a6d1c17, (q31_t)0x1a66f637, (q31_t)0x1a60d047, (q31_t)0x1a5aaa47, (q31_t)0x1a548436, + (q31_t)0x1a4e5e15, (q31_t)0x1a4837e4, (q31_t)0x1a4211a3, (q31_t)0x1a3beb52, (q31_t)0x1a35c4f0, (q31_t)0x1a2f9e7e, (q31_t)0x1a2977fc, (q31_t)0x1a23516a, + (q31_t)0x1a1d2ac8, (q31_t)0x1a170416, (q31_t)0x1a10dd53, (q31_t)0x1a0ab681, (q31_t)0x1a048f9e, (q31_t)0x19fe68ac, (q31_t)0x19f841a9, (q31_t)0x19f21a96, + (q31_t)0x19ebf374, (q31_t)0x19e5cc41, (q31_t)0x19dfa4fe, (q31_t)0x19d97dac, (q31_t)0x19d35649, (q31_t)0x19cd2ed7, (q31_t)0x19c70754, (q31_t)0x19c0dfc2, + (q31_t)0x19bab820, (q31_t)0x19b4906e, (q31_t)0x19ae68ac, (q31_t)0x19a840da, (q31_t)0x19a218f9, (q31_t)0x199bf107, (q31_t)0x1995c906, (q31_t)0x198fa0f5, + (q31_t)0x198978d4, (q31_t)0x198350a4, (q31_t)0x197d2864, (q31_t)0x19770014, (q31_t)0x1970d7b4, (q31_t)0x196aaf45, (q31_t)0x196486c6, (q31_t)0x195e5e37, + (q31_t)0x19583599, (q31_t)0x19520ceb, (q31_t)0x194be42d, (q31_t)0x1945bb60, (q31_t)0x193f9283, (q31_t)0x19396997, (q31_t)0x1933409b, (q31_t)0x192d178f, + (q31_t)0x1926ee74, (q31_t)0x1920c54a, (q31_t)0x191a9c10, (q31_t)0x191472c6, (q31_t)0x190e496d, (q31_t)0x19082005, (q31_t)0x1901f68d, (q31_t)0x18fbcd06, + (q31_t)0x18f5a36f, (q31_t)0x18ef79c9, (q31_t)0x18e95014, (q31_t)0x18e3264f, (q31_t)0x18dcfc7b, (q31_t)0x18d6d297, (q31_t)0x18d0a8a4, (q31_t)0x18ca7ea2, + (q31_t)0x18c45491, (q31_t)0x18be2a70, (q31_t)0x18b80040, (q31_t)0x18b1d601, (q31_t)0x18ababb2, (q31_t)0x18a58154, (q31_t)0x189f56e8, (q31_t)0x18992c6b, + (q31_t)0x189301e0, (q31_t)0x188cd746, (q31_t)0x1886ac9c, (q31_t)0x188081e4, (q31_t)0x187a571c, (q31_t)0x18742c45, (q31_t)0x186e015f, (q31_t)0x1867d66a, + (q31_t)0x1861ab66, (q31_t)0x185b8053, (q31_t)0x18555530, (q31_t)0x184f29ff, (q31_t)0x1848febf, (q31_t)0x1842d370, (q31_t)0x183ca812, (q31_t)0x18367ca5, + (q31_t)0x18305129, (q31_t)0x182a259e, (q31_t)0x1823fa04, (q31_t)0x181dce5b, (q31_t)0x1817a2a4, (q31_t)0x181176dd, (q31_t)0x180b4b08, (q31_t)0x18051f24, + (q31_t)0x17fef331, (q31_t)0x17f8c72f, (q31_t)0x17f29b1e, (q31_t)0x17ec6eff, (q31_t)0x17e642d1, (q31_t)0x17e01694, (q31_t)0x17d9ea49, (q31_t)0x17d3bdee, + (q31_t)0x17cd9186, (q31_t)0x17c7650e, (q31_t)0x17c13888, (q31_t)0x17bb0bf3, (q31_t)0x17b4df4f, (q31_t)0x17aeb29d, (q31_t)0x17a885dc, (q31_t)0x17a2590d, + (q31_t)0x179c2c2f, (q31_t)0x1795ff42, (q31_t)0x178fd247, (q31_t)0x1789a53d, (q31_t)0x17837825, (q31_t)0x177d4afe, (q31_t)0x17771dc9, (q31_t)0x1770f086, + (q31_t)0x176ac333, (q31_t)0x176495d3, (q31_t)0x175e6864, (q31_t)0x17583ae7, (q31_t)0x17520d5b, (q31_t)0x174bdfc1, (q31_t)0x1745b218, (q31_t)0x173f8461, + (q31_t)0x1739569c, (q31_t)0x173328c8, (q31_t)0x172cfae6, (q31_t)0x1726ccf6, (q31_t)0x17209ef8, (q31_t)0x171a70eb, (q31_t)0x171442d0, (q31_t)0x170e14a7, + (q31_t)0x1707e670, (q31_t)0x1701b82a, (q31_t)0x16fb89d6, (q31_t)0x16f55b74, (q31_t)0x16ef2d04, (q31_t)0x16e8fe86, (q31_t)0x16e2cff9, (q31_t)0x16dca15f, + (q31_t)0x16d672b6, (q31_t)0x16d043ff, (q31_t)0x16ca153a, (q31_t)0x16c3e667, (q31_t)0x16bdb787, (q31_t)0x16b78898, (q31_t)0x16b1599b, (q31_t)0x16ab2a90, + (q31_t)0x16a4fb77, (q31_t)0x169ecc50, (q31_t)0x16989d1b, (q31_t)0x16926dd8, (q31_t)0x168c3e87, (q31_t)0x16860f29, (q31_t)0x167fdfbc, (q31_t)0x1679b042, + (q31_t)0x167380ba, (q31_t)0x166d5123, (q31_t)0x1667217f, (q31_t)0x1660f1ce, (q31_t)0x165ac20e, (q31_t)0x16549241, (q31_t)0x164e6266, (q31_t)0x1648327d, + (q31_t)0x16420286, (q31_t)0x163bd282, (q31_t)0x1635a270, (q31_t)0x162f7250, (q31_t)0x16294222, (q31_t)0x162311e7, (q31_t)0x161ce19e, (q31_t)0x1616b148, + (q31_t)0x161080e4, (q31_t)0x160a5072, (q31_t)0x16041ff3, (q31_t)0x15fdef66, (q31_t)0x15f7becc, (q31_t)0x15f18e24, (q31_t)0x15eb5d6e, (q31_t)0x15e52cab, + (q31_t)0x15defbdb, (q31_t)0x15d8cafd, (q31_t)0x15d29a11, (q31_t)0x15cc6918, (q31_t)0x15c63812, (q31_t)0x15c006fe, (q31_t)0x15b9d5dd, (q31_t)0x15b3a4ae, + (q31_t)0x15ad7372, (q31_t)0x15a74228, (q31_t)0x15a110d2, (q31_t)0x159adf6e, (q31_t)0x1594adfc, (q31_t)0x158e7c7d, (q31_t)0x15884af1, (q31_t)0x15821958, + (q31_t)0x157be7b1, (q31_t)0x1575b5fe, (q31_t)0x156f843c, (q31_t)0x1569526e, (q31_t)0x15632093, (q31_t)0x155ceeaa, (q31_t)0x1556bcb4, (q31_t)0x15508ab1, + (q31_t)0x154a58a1, (q31_t)0x15442683, (q31_t)0x153df459, (q31_t)0x1537c221, (q31_t)0x15318fdd, (q31_t)0x152b5d8b, (q31_t)0x15252b2c, (q31_t)0x151ef8c0, + (q31_t)0x1518c648, (q31_t)0x151293c2, (q31_t)0x150c612f, (q31_t)0x15062e8f, (q31_t)0x14fffbe2, (q31_t)0x14f9c928, (q31_t)0x14f39662, (q31_t)0x14ed638e, + (q31_t)0x14e730ae, (q31_t)0x14e0fdc0, (q31_t)0x14dacac6, (q31_t)0x14d497bf, (q31_t)0x14ce64ab, (q31_t)0x14c8318a, (q31_t)0x14c1fe5c, (q31_t)0x14bbcb22, + (q31_t)0x14b597da, (q31_t)0x14af6486, (q31_t)0x14a93125, (q31_t)0x14a2fdb8, (q31_t)0x149cca3e, (q31_t)0x149696b7, (q31_t)0x14906323, (q31_t)0x148a2f82, + (q31_t)0x1483fbd5, (q31_t)0x147dc81c, (q31_t)0x14779455, (q31_t)0x14716082, (q31_t)0x146b2ca3, (q31_t)0x1464f8b7, (q31_t)0x145ec4be, (q31_t)0x145890b9, + (q31_t)0x14525ca7, (q31_t)0x144c2888, (q31_t)0x1445f45d, (q31_t)0x143fc026, (q31_t)0x14398be2, (q31_t)0x14335792, (q31_t)0x142d2335, (q31_t)0x1426eecb, + (q31_t)0x1420ba56, (q31_t)0x141a85d3, (q31_t)0x14145145, (q31_t)0x140e1caa, (q31_t)0x1407e803, (q31_t)0x1401b34f, (q31_t)0x13fb7e8f, (q31_t)0x13f549c3, + (q31_t)0x13ef14ea, (q31_t)0x13e8e005, (q31_t)0x13e2ab14, (q31_t)0x13dc7616, (q31_t)0x13d6410d, (q31_t)0x13d00bf7, (q31_t)0x13c9d6d4, (q31_t)0x13c3a1a6, + (q31_t)0x13bd6c6b, (q31_t)0x13b73725, (q31_t)0x13b101d2, (q31_t)0x13aacc73, (q31_t)0x13a49707, (q31_t)0x139e6190, (q31_t)0x13982c0d, (q31_t)0x1391f67d, + (q31_t)0x138bc0e1, (q31_t)0x13858b3a, (q31_t)0x137f5586, (q31_t)0x13791fc6, (q31_t)0x1372e9fb, (q31_t)0x136cb423, (q31_t)0x13667e3f, (q31_t)0x13604850, + (q31_t)0x135a1254, (q31_t)0x1353dc4c, (q31_t)0x134da639, (q31_t)0x1347701a, (q31_t)0x134139ee, (q31_t)0x133b03b7, (q31_t)0x1334cd74, (q31_t)0x132e9725, + (q31_t)0x132860ca, (q31_t)0x13222a64, (q31_t)0x131bf3f2, (q31_t)0x1315bd73, (q31_t)0x130f86ea, (q31_t)0x13095054, (q31_t)0x130319b3, (q31_t)0x12fce305, + (q31_t)0x12f6ac4d, (q31_t)0x12f07588, (q31_t)0x12ea3eb8, (q31_t)0x12e407dc, (q31_t)0x12ddd0f4, (q31_t)0x12d79a01, (q31_t)0x12d16303, (q31_t)0x12cb2bf8, + (q31_t)0x12c4f4e2, (q31_t)0x12bebdc1, (q31_t)0x12b88693, (q31_t)0x12b24f5b, (q31_t)0x12ac1817, (q31_t)0x12a5e0c7, (q31_t)0x129fa96c, (q31_t)0x12997205, + (q31_t)0x12933a93, (q31_t)0x128d0315, (q31_t)0x1286cb8c, (q31_t)0x128093f7, (q31_t)0x127a5c57, (q31_t)0x127424ac, (q31_t)0x126decf5, (q31_t)0x1267b533, + (q31_t)0x12617d66, (q31_t)0x125b458d, (q31_t)0x12550da9, (q31_t)0x124ed5ba, (q31_t)0x12489dbf, (q31_t)0x124265b9, (q31_t)0x123c2da8, (q31_t)0x1235f58b, + (q31_t)0x122fbd63, (q31_t)0x12298530, (q31_t)0x12234cf2, (q31_t)0x121d14a9, (q31_t)0x1216dc54, (q31_t)0x1210a3f5, (q31_t)0x120a6b8a, (q31_t)0x12043314, + (q31_t)0x11fdfa93, (q31_t)0x11f7c207, (q31_t)0x11f18970, (q31_t)0x11eb50cd, (q31_t)0x11e51820, (q31_t)0x11dedf68, (q31_t)0x11d8a6a4, (q31_t)0x11d26dd6, + (q31_t)0x11cc34fc, (q31_t)0x11c5fc18, (q31_t)0x11bfc329, (q31_t)0x11b98a2e, (q31_t)0x11b35129, (q31_t)0x11ad1819, (q31_t)0x11a6defe, (q31_t)0x11a0a5d8, + (q31_t)0x119a6ca7, (q31_t)0x1194336b, (q31_t)0x118dfa25, (q31_t)0x1187c0d3, (q31_t)0x11818777, (q31_t)0x117b4e10, (q31_t)0x1175149e, (q31_t)0x116edb22, + (q31_t)0x1168a19b, (q31_t)0x11626809, (q31_t)0x115c2e6c, (q31_t)0x1155f4c4, (q31_t)0x114fbb12, (q31_t)0x11498156, (q31_t)0x1143478e, (q31_t)0x113d0dbc, + (q31_t)0x1136d3df, (q31_t)0x113099f8, (q31_t)0x112a6006, (q31_t)0x11242609, (q31_t)0x111dec02, (q31_t)0x1117b1f0, (q31_t)0x111177d4, (q31_t)0x110b3dad, + (q31_t)0x1105037c, (q31_t)0x10fec940, (q31_t)0x10f88efa, (q31_t)0x10f254a9, (q31_t)0x10ec1a4e, (q31_t)0x10e5dfe8, (q31_t)0x10dfa578, (q31_t)0x10d96afe, + (q31_t)0x10d33079, (q31_t)0x10ccf5ea, (q31_t)0x10c6bb50, (q31_t)0x10c080ac, (q31_t)0x10ba45fe, (q31_t)0x10b40b45, (q31_t)0x10add082, (q31_t)0x10a795b5, + (q31_t)0x10a15ade, (q31_t)0x109b1ffc, (q31_t)0x1094e510, (q31_t)0x108eaa1a, (q31_t)0x10886f19, (q31_t)0x1082340f, (q31_t)0x107bf8fa, (q31_t)0x1075bddb, + (q31_t)0x106f82b2, (q31_t)0x1069477f, (q31_t)0x10630c41, (q31_t)0x105cd0fa, (q31_t)0x105695a8, (q31_t)0x10505a4d, (q31_t)0x104a1ee7, (q31_t)0x1043e377, + (q31_t)0x103da7fd, (q31_t)0x10376c79, (q31_t)0x103130ec, (q31_t)0x102af554, (q31_t)0x1024b9b2, (q31_t)0x101e7e06, (q31_t)0x10184251, (q31_t)0x10120691, + (q31_t)0x100bcac7, (q31_t)0x10058ef4, (q31_t)0xfff5317, (q31_t)0xff91730, (q31_t)0xff2db3e, (q31_t)0xfec9f44, (q31_t)0xfe6633f, (q31_t)0xfe02730, + (q31_t)0xfd9eb18, (q31_t)0xfd3aef6, (q31_t)0xfcd72ca, (q31_t)0xfc73695, (q31_t)0xfc0fa55, (q31_t)0xfbabe0c, (q31_t)0xfb481ba, (q31_t)0xfae455d, + (q31_t)0xfa808f7, (q31_t)0xfa1cc87, (q31_t)0xf9b900e, (q31_t)0xf95538b, (q31_t)0xf8f16fe, (q31_t)0xf88da68, (q31_t)0xf829dc8, (q31_t)0xf7c611f, + (q31_t)0xf76246c, (q31_t)0xf6fe7af, (q31_t)0xf69aae9, (q31_t)0xf636e1a, (q31_t)0xf5d3141, (q31_t)0xf56f45e, (q31_t)0xf50b773, (q31_t)0xf4a7a7d, + (q31_t)0xf443d7e, (q31_t)0xf3e0076, (q31_t)0xf37c365, (q31_t)0xf318649, (q31_t)0xf2b4925, (q31_t)0xf250bf7, (q31_t)0xf1ecec0, (q31_t)0xf189180, + (q31_t)0xf125436, (q31_t)0xf0c16e3, (q31_t)0xf05d987, (q31_t)0xeff9c21, (q31_t)0xef95eb2, (q31_t)0xef3213a, (q31_t)0xeece3b9, (q31_t)0xee6a62f, + (q31_t)0xee0689b, (q31_t)0xeda2afe, (q31_t)0xed3ed58, (q31_t)0xecdafa9, (q31_t)0xec771f1, (q31_t)0xec1342f, (q31_t)0xebaf665, (q31_t)0xeb4b891, + (q31_t)0xeae7ab4, (q31_t)0xea83ccf, (q31_t)0xea1fee0, (q31_t)0xe9bc0e8, (q31_t)0xe9582e7, (q31_t)0xe8f44dd, (q31_t)0xe8906cb, (q31_t)0xe82c8af, + (q31_t)0xe7c8a8a, (q31_t)0xe764c5c, (q31_t)0xe700e26, (q31_t)0xe69cfe6, (q31_t)0xe63919e, (q31_t)0xe5d534d, (q31_t)0xe5714f3, (q31_t)0xe50d690, + (q31_t)0xe4a9824, (q31_t)0xe4459af, (q31_t)0xe3e1b32, (q31_t)0xe37dcac, (q31_t)0xe319e1d, (q31_t)0xe2b5f85, (q31_t)0xe2520e5, (q31_t)0xe1ee23c, + (q31_t)0xe18a38a, (q31_t)0xe1264cf, (q31_t)0xe0c260c, (q31_t)0xe05e740, (q31_t)0xdffa86b, (q31_t)0xdf9698e, (q31_t)0xdf32aa8, (q31_t)0xdecebba, + (q31_t)0xde6acc3, (q31_t)0xde06dc3, (q31_t)0xdda2ebb, (q31_t)0xdd3efab, (q31_t)0xdcdb091, (q31_t)0xdc77170, (q31_t)0xdc13245, (q31_t)0xdbaf313, + (q31_t)0xdb4b3d7, (q31_t)0xdae7494, (q31_t)0xda83548, (q31_t)0xda1f5f3, (q31_t)0xd9bb696, (q31_t)0xd957731, (q31_t)0xd8f37c3, (q31_t)0xd88f84d, + (q31_t)0xd82b8cf, (q31_t)0xd7c7948, (q31_t)0xd7639b9, (q31_t)0xd6ffa22, (q31_t)0xd69ba82, (q31_t)0xd637ada, (q31_t)0xd5d3b2a, (q31_t)0xd56fb71, + (q31_t)0xd50bbb1, (q31_t)0xd4a7be8, (q31_t)0xd443c17, (q31_t)0xd3dfc3e, (q31_t)0xd37bc5c, (q31_t)0xd317c73, (q31_t)0xd2b3c81, (q31_t)0xd24fc87, + (q31_t)0xd1ebc85, (q31_t)0xd187c7b, (q31_t)0xd123c69, (q31_t)0xd0bfc4f, (q31_t)0xd05bc2d, (q31_t)0xcff7c02, (q31_t)0xcf93bd0, (q31_t)0xcf2fb96, + (q31_t)0xcecbb53, (q31_t)0xce67b09, (q31_t)0xce03ab7, (q31_t)0xcd9fa5d, (q31_t)0xcd3b9fb, (q31_t)0xccd7991, (q31_t)0xcc7391f, (q31_t)0xcc0f8a5, + (q31_t)0xcbab824, (q31_t)0xcb4779a, (q31_t)0xcae3709, (q31_t)0xca7f670, (q31_t)0xca1b5cf, (q31_t)0xc9b7526, (q31_t)0xc953475, (q31_t)0xc8ef3bd, + (q31_t)0xc88b2fd, (q31_t)0xc827235, (q31_t)0xc7c3166, (q31_t)0xc75f08f, (q31_t)0xc6fafb0, (q31_t)0xc696ec9, (q31_t)0xc632ddb, (q31_t)0xc5cece5, + (q31_t)0xc56abe8, (q31_t)0xc506ae3, (q31_t)0xc4a29d6, (q31_t)0xc43e8c2, (q31_t)0xc3da7a6, (q31_t)0xc376683, (q31_t)0xc312558, (q31_t)0xc2ae425, + (q31_t)0xc24a2eb, (q31_t)0xc1e61aa, (q31_t)0xc182061, (q31_t)0xc11df11, (q31_t)0xc0b9db9, (q31_t)0xc055c5a, (q31_t)0xbff1af3, (q31_t)0xbf8d985, + (q31_t)0xbf29810, (q31_t)0xbec5693, (q31_t)0xbe6150f, (q31_t)0xbdfd383, (q31_t)0xbd991f0, (q31_t)0xbd35056, (q31_t)0xbcd0eb5, (q31_t)0xbc6cd0c, + (q31_t)0xbc08b5c, (q31_t)0xbba49a5, (q31_t)0xbb407e7, (q31_t)0xbadc621, (q31_t)0xba78454, (q31_t)0xba14280, (q31_t)0xb9b00a5, (q31_t)0xb94bec2, + (q31_t)0xb8e7cd9, (q31_t)0xb883ae8, (q31_t)0xb81f8f0, (q31_t)0xb7bb6f2, (q31_t)0xb7574ec, (q31_t)0xb6f32df, (q31_t)0xb68f0cb, (q31_t)0xb62aeaf, + (q31_t)0xb5c6c8d, (q31_t)0xb562a64, (q31_t)0xb4fe834, (q31_t)0xb49a5fd, (q31_t)0xb4363bf, (q31_t)0xb3d217a, (q31_t)0xb36df2e, (q31_t)0xb309cdb, + (q31_t)0xb2a5a81, (q31_t)0xb241820, (q31_t)0xb1dd5b9, (q31_t)0xb17934b, (q31_t)0xb1150d5, (q31_t)0xb0b0e59, (q31_t)0xb04cbd6, (q31_t)0xafe894d, + (q31_t)0xaf846bc, (q31_t)0xaf20425, (q31_t)0xaebc187, (q31_t)0xae57ee2, (q31_t)0xadf3c37, (q31_t)0xad8f985, (q31_t)0xad2b6cc, (q31_t)0xacc740c, + (q31_t)0xac63146, (q31_t)0xabfee79, (q31_t)0xab9aba6, (q31_t)0xab368cc, (q31_t)0xaad25eb, (q31_t)0xaa6e304, (q31_t)0xaa0a016, (q31_t)0xa9a5d22, + (q31_t)0xa941a27, (q31_t)0xa8dd725, (q31_t)0xa87941d, (q31_t)0xa81510f, (q31_t)0xa7b0dfa, (q31_t)0xa74cadf, (q31_t)0xa6e87bd, (q31_t)0xa684495, + (q31_t)0xa620166, (q31_t)0xa5bbe31, (q31_t)0xa557af5, (q31_t)0xa4f37b3, (q31_t)0xa48f46b, (q31_t)0xa42b11d, (q31_t)0xa3c6dc8, (q31_t)0xa362a6d, + (q31_t)0xa2fe70b, (q31_t)0xa29a3a3, (q31_t)0xa236035, (q31_t)0xa1d1cc1, (q31_t)0xa16d946, (q31_t)0xa1095c6, (q31_t)0xa0a523f, (q31_t)0xa040eb1, + (q31_t)0x9fdcb1e, (q31_t)0x9f78784, (q31_t)0x9f143e5, (q31_t)0x9eb003f, (q31_t)0x9e4bc93, (q31_t)0x9de78e1, (q31_t)0x9d83529, (q31_t)0x9d1f16b, + (q31_t)0x9cbada7, (q31_t)0x9c569dc, (q31_t)0x9bf260c, (q31_t)0x9b8e236, (q31_t)0x9b29e59, (q31_t)0x9ac5a77, (q31_t)0x9a6168f, (q31_t)0x99fd2a0, + (q31_t)0x9998eac, (q31_t)0x9934ab2, (q31_t)0x98d06b2, (q31_t)0x986c2ac, (q31_t)0x9807ea1, (q31_t)0x97a3a8f, (q31_t)0x973f678, (q31_t)0x96db25a, + (q31_t)0x9676e37, (q31_t)0x9612a0e, (q31_t)0x95ae5e0, (q31_t)0x954a1ab, (q31_t)0x94e5d71, (q31_t)0x9481931, (q31_t)0x941d4eb, (q31_t)0x93b90a0, + (q31_t)0x9354c4f, (q31_t)0x92f07f8, (q31_t)0x928c39b, (q31_t)0x9227f39, (q31_t)0x91c3ad2, (q31_t)0x915f664, (q31_t)0x90fb1f1, (q31_t)0x9096d79, + (q31_t)0x90328fb, (q31_t)0x8fce477, (q31_t)0x8f69fee, (q31_t)0x8f05b5f, (q31_t)0x8ea16cb, (q31_t)0x8e3d231, (q31_t)0x8dd8d92, (q31_t)0x8d748ed, + (q31_t)0x8d10443, (q31_t)0x8cabf93, (q31_t)0x8c47ade, (q31_t)0x8be3624, (q31_t)0x8b7f164, (q31_t)0x8b1ac9f, (q31_t)0x8ab67d4, (q31_t)0x8a52304, + (q31_t)0x89ede2f, (q31_t)0x8989955, (q31_t)0x8925475, (q31_t)0x88c0f90, (q31_t)0x885caa5, (q31_t)0x87f85b5, (q31_t)0x87940c1, (q31_t)0x872fbc6, + (q31_t)0x86cb6c7, (q31_t)0x86671c2, (q31_t)0x8602cb9, (q31_t)0x859e7aa, (q31_t)0x853a296, (q31_t)0x84d5d7d, (q31_t)0x847185e, (q31_t)0x840d33b, + (q31_t)0x83a8e12, (q31_t)0x83448e5, (q31_t)0x82e03b2, (q31_t)0x827be7a, (q31_t)0x821793e, (q31_t)0x81b33fc, (q31_t)0x814eeb5, (q31_t)0x80ea969, + (q31_t)0x8086419, (q31_t)0x8021ec3, (q31_t)0x7fbd968, (q31_t)0x7f59409, (q31_t)0x7ef4ea4, (q31_t)0x7e9093b, (q31_t)0x7e2c3cd, (q31_t)0x7dc7e5a, + (q31_t)0x7d638e2, (q31_t)0x7cff365, (q31_t)0x7c9ade4, (q31_t)0x7c3685d, (q31_t)0x7bd22d2, (q31_t)0x7b6dd42, (q31_t)0x7b097ad, (q31_t)0x7aa5214, + (q31_t)0x7a40c76, (q31_t)0x79dc6d3, (q31_t)0x797812b, (q31_t)0x7913b7f, (q31_t)0x78af5ce, (q31_t)0x784b019, (q31_t)0x77e6a5e, (q31_t)0x77824a0, + (q31_t)0x771dedc, (q31_t)0x76b9914, (q31_t)0x7655347, (q31_t)0x75f0d76, (q31_t)0x758c7a1, (q31_t)0x75281c6, (q31_t)0x74c3be7, (q31_t)0x745f604, + (q31_t)0x73fb01c, (q31_t)0x7396a30, (q31_t)0x733243f, (q31_t)0x72cde4a, (q31_t)0x7269851, (q31_t)0x7205253, (q31_t)0x71a0c50, (q31_t)0x713c64a, + (q31_t)0x70d803f, (q31_t)0x7073a2f, (q31_t)0x700f41b, (q31_t)0x6faae03, (q31_t)0x6f467e7, (q31_t)0x6ee21c6, (q31_t)0x6e7dba1, (q31_t)0x6e19578, + (q31_t)0x6db4f4a, (q31_t)0x6d50919, (q31_t)0x6cec2e3, (q31_t)0x6c87ca9, (q31_t)0x6c2366a, (q31_t)0x6bbf028, (q31_t)0x6b5a9e1, (q31_t)0x6af6396, + (q31_t)0x6a91d47, (q31_t)0x6a2d6f4, (q31_t)0x69c909d, (q31_t)0x6964a42, (q31_t)0x69003e3, (q31_t)0x689bd80, (q31_t)0x6837718, (q31_t)0x67d30ad, + (q31_t)0x676ea3d, (q31_t)0x670a3ca, (q31_t)0x66a5d53, (q31_t)0x66416d8, (q31_t)0x65dd058, (q31_t)0x65789d5, (q31_t)0x651434e, (q31_t)0x64afcc3, + (q31_t)0x644b634, (q31_t)0x63e6fa2, (q31_t)0x638290b, (q31_t)0x631e271, (q31_t)0x62b9bd3, (q31_t)0x6255531, (q31_t)0x61f0e8b, (q31_t)0x618c7e1, + (q31_t)0x6128134, (q31_t)0x60c3a83, (q31_t)0x605f3ce, (q31_t)0x5ffad15, (q31_t)0x5f96659, (q31_t)0x5f31f99, (q31_t)0x5ecd8d6, (q31_t)0x5e6920e, + (q31_t)0x5e04b43, (q31_t)0x5da0475, (q31_t)0x5d3bda3, (q31_t)0x5cd76cd, (q31_t)0x5c72ff4, (q31_t)0x5c0e917, (q31_t)0x5baa237, (q31_t)0x5b45b53, + (q31_t)0x5ae146b, (q31_t)0x5a7cd80, (q31_t)0x5a18692, (q31_t)0x59b3fa0, (q31_t)0x594f8aa, (q31_t)0x58eb1b2, (q31_t)0x5886ab5, (q31_t)0x58223b6, + (q31_t)0x57bdcb3, (q31_t)0x57595ac, (q31_t)0x56f4ea2, (q31_t)0x5690795, (q31_t)0x562c085, (q31_t)0x55c7971, (q31_t)0x556325a, (q31_t)0x54feb3f, + (q31_t)0x549a422, (q31_t)0x5435d01, (q31_t)0x53d15dd, (q31_t)0x536ceb5, (q31_t)0x530878a, (q31_t)0x52a405d, (q31_t)0x523f92c, (q31_t)0x51db1f7, + (q31_t)0x5176ac0, (q31_t)0x5112385, (q31_t)0x50adc48, (q31_t)0x5049507, (q31_t)0x4fe4dc3, (q31_t)0x4f8067c, (q31_t)0x4f1bf32, (q31_t)0x4eb77e5, + (q31_t)0x4e53095, (q31_t)0x4dee942, (q31_t)0x4d8a1ec, (q31_t)0x4d25a93, (q31_t)0x4cc1337, (q31_t)0x4c5cbd8, (q31_t)0x4bf8476, (q31_t)0x4b93d11, + (q31_t)0x4b2f5a9, (q31_t)0x4acae3e, (q31_t)0x4a666d1, (q31_t)0x4a01f60, (q31_t)0x499d7ed, (q31_t)0x4939077, (q31_t)0x48d48fe, (q31_t)0x4870182, + (q31_t)0x480ba04, (q31_t)0x47a7282, (q31_t)0x4742afe, (q31_t)0x46de377, (q31_t)0x4679bee, (q31_t)0x4615461, (q31_t)0x45b0cd2, (q31_t)0x454c541, + (q31_t)0x44e7dac, (q31_t)0x4483615, (q31_t)0x441ee7c, (q31_t)0x43ba6df, (q31_t)0x4355f40, (q31_t)0x42f179f, (q31_t)0x428cffb, (q31_t)0x4228854, + (q31_t)0x41c40ab, (q31_t)0x415f8ff, (q31_t)0x40fb151, (q31_t)0x40969a0, (q31_t)0x40321ed, (q31_t)0x3fcda37, (q31_t)0x3f6927f, (q31_t)0x3f04ac4, + (q31_t)0x3ea0307, (q31_t)0x3e3bb48, (q31_t)0x3dd7386, (q31_t)0x3d72bc2, (q31_t)0x3d0e3fb, (q31_t)0x3ca9c32, (q31_t)0x3c45467, (q31_t)0x3be0c99, + (q31_t)0x3b7c4c9, (q31_t)0x3b17cf7, (q31_t)0x3ab3523, (q31_t)0x3a4ed4c, (q31_t)0x39ea573, (q31_t)0x3985d97, (q31_t)0x39215ba, (q31_t)0x38bcdda, + (q31_t)0x38585f8, (q31_t)0x37f3e14, (q31_t)0x378f62e, (q31_t)0x372ae46, (q31_t)0x36c665b, (q31_t)0x3661e6f, (q31_t)0x35fd680, (q31_t)0x3598e8f, + (q31_t)0x353469c, (q31_t)0x34cfea8, (q31_t)0x346b6b1, (q31_t)0x3406eb8, (q31_t)0x33a26bd, (q31_t)0x333dec0, (q31_t)0x32d96c1, (q31_t)0x3274ec0, + (q31_t)0x32106bd, (q31_t)0x31abeb9, (q31_t)0x31476b2, (q31_t)0x30e2ea9, (q31_t)0x307e69f, (q31_t)0x3019e93, (q31_t)0x2fb5684, (q31_t)0x2f50e74, + (q31_t)0x2eec663, (q31_t)0x2e87e4f, (q31_t)0x2e2363a, (q31_t)0x2dbee22, (q31_t)0x2d5a609, (q31_t)0x2cf5def, (q31_t)0x2c915d2, (q31_t)0x2c2cdb4, + (q31_t)0x2bc8594, (q31_t)0x2b63d73, (q31_t)0x2aff54f, (q31_t)0x2a9ad2a, (q31_t)0x2a36504, (q31_t)0x29d1cdc, (q31_t)0x296d4b2, (q31_t)0x2908c87, + (q31_t)0x28a445a, (q31_t)0x283fc2b, (q31_t)0x27db3fb, (q31_t)0x2776bc9, (q31_t)0x2712396, (q31_t)0x26adb62, (q31_t)0x264932b, (q31_t)0x25e4af4, + (q31_t)0x25802bb, (q31_t)0x251ba80, (q31_t)0x24b7244, (q31_t)0x2452a07, (q31_t)0x23ee1c8, (q31_t)0x2389988, (q31_t)0x2325147, (q31_t)0x22c0904, + (q31_t)0x225c0bf, (q31_t)0x21f787a, (q31_t)0x2193033, (q31_t)0x212e7eb, (q31_t)0x20c9fa1, (q31_t)0x2065757, (q31_t)0x2000f0b, (q31_t)0x1f9c6be, + (q31_t)0x1f37e6f, (q31_t)0x1ed3620, (q31_t)0x1e6edcf, (q31_t)0x1e0a57d, (q31_t)0x1da5d2a, (q31_t)0x1d414d6, (q31_t)0x1cdcc80, (q31_t)0x1c7842a, + (q31_t)0x1c13bd2, (q31_t)0x1baf37a, (q31_t)0x1b4ab20, (q31_t)0x1ae62c5, (q31_t)0x1a81a69, (q31_t)0x1a1d20c, (q31_t)0x19b89ae, (q31_t)0x1954150, + (q31_t)0x18ef8f0, (q31_t)0x188b08f, (q31_t)0x182682d, (q31_t)0x17c1fcb, (q31_t)0x175d767, (q31_t)0x16f8f03, (q31_t)0x169469d, (q31_t)0x162fe37, + (q31_t)0x15cb5d0, (q31_t)0x1566d68, (q31_t)0x15024ff, (q31_t)0x149dc96, (q31_t)0x143942b, (q31_t)0x13d4bc0, (q31_t)0x1370354, (q31_t)0x130bae7, + (q31_t)0x12a727a, (q31_t)0x1242a0c, (q31_t)0x11de19d, (q31_t)0x117992e, (q31_t)0x11150be, (q31_t)0x10b084d, (q31_t)0x104bfdb, (q31_t)0xfe7769, + (q31_t)0xf82ef6, (q31_t)0xf1e683, (q31_t)0xeb9e0f, (q31_t)0xe5559b, (q31_t)0xdf0d26, (q31_t)0xd8c4b0, (q31_t)0xd27c3a, (q31_t)0xcc33c3, + (q31_t)0xc5eb4c, (q31_t)0xbfa2d5, (q31_t)0xb95a5d, (q31_t)0xb311e4, (q31_t)0xacc96b, (q31_t)0xa680f2, (q31_t)0xa03878, (q31_t)0x99effe, + (q31_t)0x93a784, (q31_t)0x8d5f09, (q31_t)0x87168e, (q31_t)0x80ce12, (q31_t)0x7a8597, (q31_t)0x743d1a, (q31_t)0x6df49e, (q31_t)0x67ac21, + (q31_t)0x6163a5, (q31_t)0x5b1b27, (q31_t)0x54d2aa, (q31_t)0x4e8a2c, (q31_t)0x4841af, (q31_t)0x41f931, (q31_t)0x3bb0b3, (q31_t)0x356835, + (q31_t)0x2f1fb6, (q31_t)0x28d738, (q31_t)0x228eb9, (q31_t)0x1c463b, (q31_t)0x15fdbc, (q31_t)0xfb53d, (q31_t)0x96cbe, (q31_t)0x3243f +}; + +/** + @} end of DCT4_IDCT4_Table group + */ + +/** + @addtogroup DCT4_IDCT4 + @{ + */ + +/** + @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 execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : N is not a supported transform length + + @par Normalizing factor: + The normalizing factor is sqrt(2/N), which depends on the size of transform N. + Normalizing factors in 1.31 format are mentioned in the table below for different DCT sizes: + + \image html dct4NormalizingQ31Table.gif + */ + +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) +{ + /* Initialize the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + + /* Initializing the pointer array with the weight table base addresses of different lengths */ + q31_t *twiddlePtr[4] = + { (q31_t *) WeightsQ31_128, (q31_t *) WeightsQ31_512, + (q31_t *) WeightsQ31_2048, (q31_t *) WeightsQ31_8192 + }; + + /* Initializing the pointer array with the cos factor table base addresses of different lengths */ + q31_t *pCosFactor[4] = + { (q31_t *) cos_factorsQ31_128, (q31_t *) cos_factorsQ31_512, + (q31_t *) cos_factorsQ31_2048, (q31_t *) cos_factorsQ31_8192 + }; + + /* Initialize the DCT4 length */ + S->N = N; + + /* Initialize the half of DCT4 length */ + S->Nby2 = Nby2; + + /* Initialize the DCT4 Normalizing factor */ + S->normalize = normalize; + + /* Initialize Real FFT Instance */ + S->pRfft = S_RFFT; + + /* Initialize Complex FFT Instance */ + S->pCfft = S_CFFT; + + switch (N) + { + /* Initialize the table modifier values */ + case 8192U: + S->pTwiddle = twiddlePtr[3]; + S->pCosFactor = pCosFactor[3]; + break; + case 2048U: + S->pTwiddle = twiddlePtr[2]; + S->pCosFactor = pCosFactor[2]; + break; + case 512U: + S->pTwiddle = twiddlePtr[1]; + S->pCosFactor = pCosFactor[1]; + break; + case 128U: + S->pTwiddle = twiddlePtr[0]; + S->pCosFactor = pCosFactor[0]; + break; + default: + status = ARM_MATH_ARGUMENT_ERROR; + } + + /* Initialize the RFFT/RIFFT Function */ + arm_rfft_init_q31(S->pRfft, S->N, 0U, 1U); + + /* return the status of DCT4 Init function */ + return (status); +} + +/** + @} end of DCT4_IDCT4 group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_q15.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_q15.c new file mode 100644 index 0000000..f926a1d --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_q15.c @@ -0,0 +1,381 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_dct4_q15.c + * Description: Processing function of DCT4 & IDCT4 Q15 + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @addtogroup DCT4_IDCT4 + @{ + */ + +/** + @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. + @return none + + @par Input an output formats + Internally inputs are downscaled in the RFFT process function to avoid overflows. + Number of bits downscaled, depends on the size of the transform. The input and output + formats for different DCT sizes and number of bits to upscale are mentioned in the table below: + + \image html dct4FormatsQ15Table.gif + */ + +void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer) +{ + const q15_t *weights = S->pTwiddle; /* Pointer to the Weights table */ + const q15_t *cosFact = S->pCosFactor; /* Pointer to the cos factors table */ + q15_t *pS1, *pS2, *pbuff; /* Temporary pointers for input buffer and pState buffer */ + q15_t in; /* Temporary variable */ + uint32_t i; /* Loop counter */ + + + /* DCT4 computation involves DCT2 (which is calculated using RFFT) + * along with some pre-processing and post-processing. + * Computational procedure is explained as follows: + * (a) Pre-processing involves multiplying input with cos factor, + * r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n)) + * where, + * r(n) -- output of preprocessing + * u(n) -- input to preprocessing(actual Source buffer) + * (b) Calculation of DCT2 using FFT is divided into three steps: + * Step1: Re-ordering of even and odd elements of input. + * Step2: Calculating FFT of the re-ordered input. + * Step3: Taking the real part of the product of FFT output and weights. + * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation: + * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0) + * where, + * Y4 -- DCT4 output, Y2 -- DCT2 output + * (d) Multiplying the output with the normalizing factor sqrt(2/N). + */ + + /*-------- Pre-processing ------------*/ + /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */ + arm_mult_q15 (pInlineBuffer, cosFact, pInlineBuffer, S->N); + arm_shift_q15 (pInlineBuffer, 1, pInlineBuffer, S->N); + + /* ---------------------------------------------------------------- + * Step1: Re-ordering of even and odd elements as + * pState[i] = pInlineBuffer[2*i] and + * pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2 + ---------------------------------------------------------------------*/ + + /* pS1 initialized to pState */ + pS1 = pState; + + /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */ + pS2 = pState + (S->N - 1U); + + /* pbuff initialized to input buffer */ + pbuff = pInlineBuffer; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */ + i = S->Nby2 >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + do + { + /* Re-ordering of even and odd elements */ + /* pState[i] = pInlineBuffer[2*i] */ + *pS1++ = *pbuff++; + /* pState[N-i-1] = pInlineBuffer[2*i+1] */ + *pS2-- = *pbuff++; + + *pS1++ = *pbuff++; + *pS2-- = *pbuff++; + + *pS1++ = *pbuff++; + *pS2-- = *pbuff++; + + *pS1++ = *pbuff++; + *pS2-- = *pbuff++; + + /* Decrement loop counter */ + i--; + } while (i > 0U); + + /* pbuff initialized to input buffer */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Initializing the loop counter to N/4 instead of N for loop unrolling */ + i = S->N >> 2U; + + /* Processing with loop unrolling 4 times as N is always multiple of 4. + * Compute 4 outputs at a time */ + do + { + /* Writing the re-ordered output back to inplace input buffer */ + *pbuff++ = *pS1++; + *pbuff++ = *pS1++; + *pbuff++ = *pS1++; + *pbuff++ = *pS1++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + + /* --------------------------------------------------------- + * Step2: Calculate RFFT for N-point input + * ---------------------------------------------------------- */ + /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */ + arm_rfft_q15 (S->pRfft, pInlineBuffer, pState); + + /*---------------------------------------------------------------------- + * Step3: Multiply the FFT output with the weights. + *----------------------------------------------------------------------*/ + arm_cmplx_mult_cmplx_q15 (pState, weights, pState, S->N); + + /* The output of complex multiplication is in 3.13 format. + * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.15 format by shifting left by 2 bits. */ + arm_shift_q15 (pState, 2, pState, S->N * 2); + + /* ----------- Post-processing ---------- */ + /* DCT-IV can be obtained from DCT-II by the equation, + * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0) + * Hence, Y4(0) = Y2(0)/2 */ + /* Getting only real part from the output and Converting to DCT-IV */ + + /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */ + i = (S->N - 1U) >> 2U; + + /* pbuff initialized to input buffer. */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */ + in = *pS1++ >> 1U; + /* input buffer acts as inplace, so output values are stored in the input itself. */ + *pbuff++ = in; + + /* pState pointer is incremented twice as the real values are located alternatively in the array */ + pS1++; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + do + { + /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */ + /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */ + in = *pS1++ - in; + *pbuff++ = in; + /* points to the next real value */ + pS1++; + + in = *pS1++ - in; + *pbuff++ = in; + pS1++; + + in = *pS1++ - in; + *pbuff++ = in; + pS1++; + + in = *pS1++ - in; + *pbuff++ = in; + pS1++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + i = (S->N - 1U) % 0x4U; + + while (i > 0U) + { + /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */ + /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */ + in = *pS1++ - in; + *pbuff++ = in; + + /* points to the next real value */ + pS1++; + + /* Decrement loop counter */ + i--; + } + + + /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/ + + /* Initializing the loop counter to N/4 instead of N for loop unrolling */ + i = S->N >> 2U; + + /* pbuff initialized to the pInlineBuffer(now contains the output values) */ + pbuff = pInlineBuffer; + + /* Processing with loop unrolling 4 times as N is always multiple of 4. Compute 4 outputs at a time */ + do + { + /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */ + in = *pbuff; + *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15)); + + in = *pbuff; + *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15)); + + in = *pbuff; + *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15)); + + in = *pbuff; + *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15)); + + /* Decrement loop counter */ + i--; + } while (i > 0U); + + +#else + + /* Initializing the loop counter to N/2 */ + i = S->Nby2; + + do + { + /* Re-ordering of even and odd elements */ + /* pState[i] = pInlineBuffer[2*i] */ + *pS1++ = *pbuff++; + /* pState[N-i-1] = pInlineBuffer[2*i+1] */ + *pS2-- = *pbuff++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + /* pbuff initialized to input buffer */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Initializing the loop counter */ + i = S->N; + + do + { + /* Writing the re-ordered output back to inplace input buffer */ + *pbuff++ = *pS1++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + + /* --------------------------------------------------------- + * Step2: Calculate RFFT for N-point input + * ---------------------------------------------------------- */ + /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */ + arm_rfft_q15 (S->pRfft, pInlineBuffer, pState); + + /*---------------------------------------------------------------------- + * Step3: Multiply the FFT output with the weights. + *----------------------------------------------------------------------*/ + arm_cmplx_mult_cmplx_q15 (pState, weights, pState, S->N); + + /* The output of complex multiplication is in 3.13 format. + * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.15 format by shifting left by 2 bits. */ + arm_shift_q15 (pState, 2, pState, S->N * 2); + + /* ----------- Post-processing ---------- */ + /* DCT-IV can be obtained from DCT-II by the equation, + * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0) + * Hence, Y4(0) = Y2(0)/2 */ + /* Getting only real part from the output and Converting to DCT-IV */ + + /* pbuff initialized to input buffer. */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */ + in = *pS1++ >> 1U; + /* input buffer acts as inplace, so output values are stored in the input itself. */ + *pbuff++ = in; + + /* pState pointer is incremented twice as the real values are located alternatively in the array */ + pS1++; + + /* Initializing the loop counter */ + i = (S->N - 1U); + + do + { + /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */ + /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */ + in = *pS1++ - in; + *pbuff++ = in; + + /* points to the next real value */ + pS1++; + + /* Decrement loop counter */ + i--; + } while (i > 0U); + + /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/ + + /* Initializing loop counter */ + i = S->N; + + /* pbuff initialized to the pInlineBuffer (now contains the output values) */ + pbuff = pInlineBuffer; + + do + { + /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */ + in = *pbuff; + *pbuff++ = ((q15_t) (((q31_t) in * S->normalize) >> 15)); + + /* Decrement loop counter */ + i--; + + } while (i > 0U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + +} + +/** + @} end of DCT4_IDCT4 group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_q31.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_q31.c new file mode 100644 index 0000000..369a5c3 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_dct4_q31.c @@ -0,0 +1,383 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_dct4_q31.c + * Description: Processing function of DCT4 & IDCT4 Q31 + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @addtogroup DCT4_IDCT4 + @{ + */ + +/** + @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. + @return none + + @par Input an output formats + Input samples need to be downscaled by 1 bit to avoid saturations in the Q31 DCT process, + as the conversion from DCT2 to DCT4 involves one subtraction. + Internally inputs are downscaled in the RFFT process function to avoid overflows. + Number of bits downscaled, depends on the size of the transform. + The input and output formats for different DCT sizes and number of bits to upscale are + mentioned in the table below: + + \image html dct4FormatsQ31Table.gif + */ + +void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer) +{ + const q31_t *weights = S->pTwiddle; /* Pointer to the Weights table */ + const q31_t *cosFact = S->pCosFactor; /* Pointer to the cos factors table */ + q31_t *pS1, *pS2, *pbuff; /* Temporary pointers for input buffer and pState buffer */ + q31_t in; /* Temporary variable */ + uint32_t i; /* Loop counter */ + + + /* DCT4 computation involves DCT2 (which is calculated using RFFT) + * along with some pre-processing and post-processing. + * Computational procedure is explained as follows: + * (a) Pre-processing involves multiplying input with cos factor, + * r(n) = 2 * u(n) * cos(pi*(2*n+1)/(4*n)) + * where, + * r(n) -- output of preprocessing + * u(n) -- input to preprocessing(actual Source buffer) + * (b) Calculation of DCT2 using FFT is divided into three steps: + * Step1: Re-ordering of even and odd elements of input. + * Step2: Calculating FFT of the re-ordered input. + * Step3: Taking the real part of the product of FFT output and weights. + * (c) Post-processing - DCT4 can be obtained from DCT2 output using the following equation: + * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0) + * where, + * Y4 -- DCT4 output, Y2 -- DCT2 output + * (d) Multiplying the output with the normalizing factor sqrt(2/N). + */ + + /*-------- Pre-processing ------------*/ + /* Multiplying input with cos factor i.e. r(n) = 2 * x(n) * cos(pi*(2*n+1)/(4*n)) */ + arm_mult_q31 (pInlineBuffer, cosFact, pInlineBuffer, S->N); + arm_shift_q31 (pInlineBuffer, 1, pInlineBuffer, S->N); + + /* ---------------------------------------------------------------- + * Step1: Re-ordering of even and odd elements as + * pState[i] = pInlineBuffer[2*i] and + * pState[N-i-1] = pInlineBuffer[2*i+1] where i = 0 to N/2 + ---------------------------------------------------------------------*/ + + /* pS1 initialized to pState */ + pS1 = pState; + + /* pS2 initialized to pState+N-1, so that it points to the end of the state buffer */ + pS2 = pState + (S->N - 1U); + + /* pbuff initialized to input buffer */ + pbuff = pInlineBuffer; + + +#if defined (ARM_MATH_LOOPUNROLL) + + /* Initializing the loop counter to N/2 >> 2 for loop unrolling by 4 */ + i = S->Nby2 >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + do + { + /* Re-ordering of even and odd elements */ + /* pState[i] = pInlineBuffer[2*i] */ + *pS1++ = *pbuff++; + /* pState[N-i-1] = pInlineBuffer[2*i+1] */ + *pS2-- = *pbuff++; + + *pS1++ = *pbuff++; + *pS2-- = *pbuff++; + + *pS1++ = *pbuff++; + *pS2-- = *pbuff++; + + *pS1++ = *pbuff++; + *pS2-- = *pbuff++; + + /* Decrement loop counter */ + i--; + } while (i > 0U); + + /* pbuff initialized to input buffer */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Initializing the loop counter to N/4 instead of N for loop unrolling */ + i = S->N >> 2U; + + /* Processing with loop unrolling 4 times as N is always multiple of 4. + * Compute 4 outputs at a time */ + do + { + /* Writing the re-ordered output back to inplace input buffer */ + *pbuff++ = *pS1++; + *pbuff++ = *pS1++; + *pbuff++ = *pS1++; + *pbuff++ = *pS1++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + + /* --------------------------------------------------------- + * Step2: Calculate RFFT for N-point input + * ---------------------------------------------------------- */ + /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */ + arm_rfft_q31 (S->pRfft, pInlineBuffer, pState); + + /*---------------------------------------------------------------------- + * Step3: Multiply the FFT output with the weights. + *----------------------------------------------------------------------*/ + arm_cmplx_mult_cmplx_q31 (pState, weights, pState, S->N); + + /* The output of complex multiplication is in 3.29 format. + * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.31 format by shifting left by 2 bits. */ + arm_shift_q31 (pState, 2, pState, S->N * 2); + + /* ----------- Post-processing ---------- */ + /* DCT-IV can be obtained from DCT-II by the equation, + * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0) + * Hence, Y4(0) = Y2(0)/2 */ + /* Getting only real part from the output and Converting to DCT-IV */ + + /* Initializing the loop counter to N >> 2 for loop unrolling by 4 */ + i = (S->N - 1U) >> 2U; + + /* pbuff initialized to input buffer. */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */ + in = *pS1++ >> 1U; + /* input buffer acts as inplace, so output values are stored in the input itself. */ + *pbuff++ = in; + + /* pState pointer is incremented twice as the real values are located alternatively in the array */ + pS1++; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + do + { + /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */ + /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */ + in = *pS1++ - in; + *pbuff++ = in; + /* points to the next real value */ + pS1++; + + in = *pS1++ - in; + *pbuff++ = in; + pS1++; + + in = *pS1++ - in; + *pbuff++ = in; + pS1++; + + in = *pS1++ - in; + *pbuff++ = in; + pS1++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + i = (S->N - 1U) % 0x4U; + + while (i > 0U) + { + /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */ + /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */ + in = *pS1++ - in; + *pbuff++ = in; + + /* points to the next real value */ + pS1++; + + /* Decrement loop counter */ + i--; + } + + + /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/ + + /* Initializing the loop counter to N/4 instead of N for loop unrolling */ + i = S->N >> 2U; + + /* pbuff initialized to the pInlineBuffer(now contains the output values) */ + pbuff = pInlineBuffer; + + /* Processing with loop unrolling 4 times as N is always multiple of 4. Compute 4 outputs at a time */ + do + { + /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */ + in = *pbuff; + *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31)); + + in = *pbuff; + *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31)); + + in = *pbuff; + *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31)); + + in = *pbuff; + *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31)); + + /* Decrement loop counter */ + i--; + } while (i > 0U); + + +#else + + /* Initializing the loop counter to N/2 */ + i = S->Nby2; + + do + { + /* Re-ordering of even and odd elements */ + /* pState[i] = pInlineBuffer[2*i] */ + *pS1++ = *pbuff++; + /* pState[N-i-1] = pInlineBuffer[2*i+1] */ + *pS2-- = *pbuff++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + /* pbuff initialized to input buffer */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Initializing the loop counter */ + i = S->N; + + do + { + /* Writing the re-ordered output back to inplace input buffer */ + *pbuff++ = *pS1++; + + /* Decrement the loop counter */ + i--; + } while (i > 0U); + + + /* --------------------------------------------------------- + * Step2: Calculate RFFT for N-point input + * ---------------------------------------------------------- */ + /* pInlineBuffer is real input of length N , pState is the complex output of length 2N */ + arm_rfft_q31 (S->pRfft, pInlineBuffer, pState); + + /*---------------------------------------------------------------------- + * Step3: Multiply the FFT output with the weights. + *----------------------------------------------------------------------*/ + arm_cmplx_mult_cmplx_q31 (pState, weights, pState, S->N); + + /* The output of complex multiplication is in 3.29 format. + * Hence changing the format of N (i.e. 2*N elements) complex numbers to 1.31 format by shifting left by 2 bits. */ + arm_shift_q31(pState, 2, pState, S->N * 2); + + /* ----------- Post-processing ---------- */ + /* DCT-IV can be obtained from DCT-II by the equation, + * Y4(k) = Y2(k) - Y4(k-1) and Y4(-1) = Y4(0) + * Hence, Y4(0) = Y2(0)/2 */ + /* Getting only real part from the output and Converting to DCT-IV */ + + /* pbuff initialized to input buffer. */ + pbuff = pInlineBuffer; + + /* pS1 initialized to pState */ + pS1 = pState; + + /* Calculating Y4(0) from Y2(0) using Y4(0) = Y2(0)/2 */ + in = *pS1++ >> 1U; + /* input buffer acts as inplace, so output values are stored in the input itself. */ + *pbuff++ = in; + + /* pState pointer is incremented twice as the real values are located alternatively in the array */ + pS1++; + + /* Initializing the loop counter */ + i = (S->N - 1U); + + while (i > 0U) + { + /* Calculating Y4(1) to Y4(N-1) from Y2 using equation Y4(k) = Y2(k) - Y4(k-1) */ + /* pState pointer (pS1) is incremented twice as the real values are located alternatively in the array */ + in = *pS1++ - in; + *pbuff++ = in; + + /* points to the next real value */ + pS1++; + + /* Decrement loop counter */ + i--; + } + + /*------------ Normalizing the output by multiplying with the normalizing factor ----------*/ + + /* Initializing loop counter */ + i = S->N; + + /* pbuff initialized to the pInlineBuffer (now contains the output values) */ + pbuff = pInlineBuffer; + + do + { + /* Multiplying pInlineBuffer with the normalizing factor sqrt(2/N) */ + in = *pbuff; + *pbuff++ = ((q31_t) (((q63_t) in * S->normalize) >> 31)); + + /* Decrement loop counter */ + i--; + } while (i > 0U); + +#endif /* #if defined (ARM_MATH_LOOPUNROLL) */ + +} + +/** + @} end of DCT4_IDCT4 group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_f32.c new file mode 100644 index 0000000..b5d0a66 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_f32.c @@ -0,0 +1,309 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_rfft_f32.c + * Description: RFFT & RIFFT Floating point process function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/* ---------------------------------------------------------------------- + * Internal functions prototypes + * -------------------------------------------------------------------- */ + +extern void arm_radix4_butterfly_f32( + float32_t * pSrc, + uint16_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier); + +extern void arm_radix4_butterfly_inverse_f32( + float32_t * pSrc, + uint16_t fftLen, + const float32_t * pCoef, + uint16_t twidCoefModifier, + float32_t onebyfftLen); + +extern void arm_bitreversal_f32( + float32_t * pSrc, + uint16_t fftSize, + uint16_t bitRevFactor, + const uint16_t * pBitRevTab); + +void arm_split_rfft_f32( + float32_t * pSrc, + uint32_t fftLen, + const float32_t * pATable, + const float32_t * pBTable, + float32_t * pDst, + uint32_t modifier); + +void arm_split_rifft_f32( + float32_t * pSrc, + uint32_t fftLen, + const float32_t * pATable, + const float32_t * pBTable, + float32_t * pDst, + uint32_t modifier); + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup RealFFT + @{ + */ + +/** + @brief Processing function for the floating-point RFFT/RIFFT. + @deprecated Do not use this function. It has been superceded by \ref arm_rfft_fast_f32 and will be removed in the future. + @param[in] S points to an instance of the floating-point RFFT/RIFFT structure + @param[in] pSrc points to the input buffer + @param[out] pDst points to the output buffer + @return none + */ + +void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst) +{ + const arm_cfft_radix4_instance_f32 *S_CFFT = S->pCfft; + + /* Calculation of Real IFFT of input */ + if (S->ifftFlagR == 1U) + { + /* Real IFFT core process */ + arm_split_rifft_f32 (pSrc, S->fftLenBy2, S->pTwiddleAReal, S->pTwiddleBReal, pDst, S->twidCoefRModifier); + + + /* Complex radix-4 IFFT process */ + arm_radix4_butterfly_inverse_f32 (pDst, S_CFFT->fftLen, S_CFFT->pTwiddle, S_CFFT->twidCoefModifier, S_CFFT->onebyfftLen); + + /* Bit reversal process */ + if (S->bitReverseFlagR == 1U) + { + arm_bitreversal_f32 (pDst, S_CFFT->fftLen, S_CFFT->bitRevFactor, S_CFFT->pBitRevTable); + } + } + else + { + /* Calculation of RFFT of input */ + + /* Complex radix-4 FFT process */ + arm_radix4_butterfly_f32 (pSrc, S_CFFT->fftLen, S_CFFT->pTwiddle, S_CFFT->twidCoefModifier); + + /* Bit reversal process */ + if (S->bitReverseFlagR == 1U) + { + arm_bitreversal_f32 (pSrc, S_CFFT->fftLen, S_CFFT->bitRevFactor, S_CFFT->pBitRevTable); + } + + /* Real FFT core process */ + arm_split_rfft_f32 (pSrc, S->fftLenBy2, S->pTwiddleAReal, S->pTwiddleBReal, pDst, S->twidCoefRModifier); + } + +} + +/** + @} end of RealFFT group + */ + +/** + @brief Core Real FFT process + @param[in] pSrc points to input buffer + @param[in] fftLen length of FFT + @param[in] pATable points to twiddle Coef A buffer + @param[in] pBTable points to twiddle Coef B buffer + @param[out] pDst points to output buffer + @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table + @return none + */ + +void arm_split_rfft_f32( + float32_t * pSrc, + uint32_t fftLen, + const float32_t * pATable, + const float32_t * pBTable, + float32_t * pDst, + uint32_t modifier) +{ + uint32_t i; /* Loop Counter */ + float32_t outR, outI; /* Temporary variables for output */ + const float32_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ + float32_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ + float32_t *pDst1 = &pDst[2], *pDst2 = &pDst[(4U * fftLen) - 1U]; /* temp pointers for output buffer */ + float32_t *pSrc1 = &pSrc[2], *pSrc2 = &pSrc[(2U * fftLen) - 1U]; /* temp pointers for input buffer */ + + /* Init coefficient pointers */ + pCoefA = &pATable[modifier * 2]; + pCoefB = &pBTable[modifier * 2]; + + i = fftLen - 1U; + + while (i > 0U) + { + /* + outR = ( pSrc[2 * i] * pATable[2 * i] + - pSrc[2 * i + 1] * pATable[2 * i + 1] + + pSrc[2 * n - 2 * i] * pBTable[2 * i] + + pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); + + outI = ( pIn[2 * i + 1] * pATable[2 * i] + + pIn[2 * i] * pATable[2 * i + 1] + + pIn[2 * n - 2 * i] * pBTable[2 * i + 1] + - pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); + */ + + /* read pATable[2 * i] */ + CoefA1 = *pCoefA++; + /* pATable[2 * i + 1] */ + CoefA2 = *pCoefA; + + /* pSrc[2 * i] * pATable[2 * i] */ + outR = *pSrc1 * CoefA1; + /* pSrc[2 * i] * CoefA2 */ + outI = *pSrc1++ * CoefA2; + + /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */ + outR -= (*pSrc1 + *pSrc2) * CoefA2; + /* pSrc[2 * i + 1] * CoefA1 */ + outI += *pSrc1++ * CoefA1; + + CoefB1 = *pCoefB; + + /* pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */ + outI -= *pSrc2-- * CoefB1; + /* pSrc[2 * fftLen - 2 * i] * CoefA2 */ + outI -= *pSrc2 * CoefA2; + + /* pSrc[2 * fftLen - 2 * i] * CoefB1 */ + outR += *pSrc2-- * CoefB1; + + /* write output */ + *pDst1++ = outR; + *pDst1++ = outI; + + /* write complex conjugate output */ + *pDst2-- = -outI; + *pDst2-- = outR; + + /* update coefficient pointer */ + pCoefB = pCoefB + (modifier * 2U); + pCoefA = pCoefA + ((modifier * 2U) - 1U); + + i--; + + } + + pDst[2U * fftLen] = pSrc[0] - pSrc[1]; + pDst[(2U * fftLen) + 1U] = 0.0f; + + pDst[0] = pSrc[0] + pSrc[1]; + pDst[1] = 0.0f; + +} + + +/** + @brief Core Real IFFT process + @param[in] pSrc points to input buffer + @param[in] fftLen length of FFT + @param[in] pATable points to twiddle Coef A buffer + @param[in] pBTable points to twiddle Coef B buffer + @param[out] pDst points to output buffer + @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table + @return none + */ + +void arm_split_rifft_f32( + float32_t * pSrc, + uint32_t fftLen, + const float32_t * pATable, + const float32_t * pBTable, + float32_t * pDst, + uint32_t modifier) +{ + float32_t outR, outI; /* Temporary variables for output */ + const float32_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ + float32_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ + float32_t *pSrc1 = &pSrc[0], *pSrc2 = &pSrc[(2U * fftLen) + 1U]; + + pCoefA = &pATable[0]; + pCoefB = &pBTable[0]; + + while (fftLen > 0U) + { + /* + outR = ( pIn[2 * i] * pATable[2 * i] + + pIn[2 * i + 1] * pATable[2 * i + 1] + + pIn[2 * n - 2 * i] * pBTable[2 * i] + - pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); + + outI = ( pIn[2 * i + 1] * pATable[2 * i] + - pIn[2 * i] * pATable[2 * i + 1] + - pIn[2 * n - 2 * i] * pBTable[2 * i + 1] + - pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); + */ + + CoefA1 = *pCoefA++; + CoefA2 = *pCoefA; + + /* outR = (pSrc[2 * i] * CoefA1 */ + outR = *pSrc1 * CoefA1; + + /* - pSrc[2 * i] * CoefA2 */ + outI = -(*pSrc1++) * CoefA2; + + /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */ + outR += (*pSrc1 + *pSrc2) * CoefA2; + + /* pSrc[2 * i + 1] * CoefA1 */ + outI += (*pSrc1++) * CoefA1; + + CoefB1 = *pCoefB; + + /* - pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */ + outI -= *pSrc2-- * CoefB1; + + /* pSrc[2 * fftLen - 2 * i] * CoefB1 */ + outR += *pSrc2 * CoefB1; + + /* pSrc[2 * fftLen - 2 * i] * CoefA2 */ + outI += *pSrc2-- * CoefA2; + + /* write output */ + *pDst++ = outR; + *pDst++ = outI; + + /* update coefficient pointer */ + pCoefB = pCoefB + (modifier * 2); + pCoefA = pCoefA + (modifier * 2 - 1); + + /* Decrement loop count */ + fftLen--; + } + +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_fast_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_fast_f32.c new file mode 100644 index 0000000..7a1af14 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_fast_f32.c @@ -0,0 +1,320 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_rfft_f32.c + * Description: RFFT & RIFFT Floating point process function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +void stage_rfft_f32( + const arm_rfft_fast_instance_f32 * S, + float32_t * p, + float32_t * pOut) +{ + uint32_t k; /* Loop Counter */ + float32_t twR, twI; /* RFFT Twiddle coefficients */ + const float32_t * pCoeff = S->pTwiddleRFFT; /* Points to RFFT Twiddle factors */ + float32_t *pA = p; /* increasing pointer */ + float32_t *pB = p; /* decreasing pointer */ + float32_t xAR, xAI, xBR, xBI; /* temporary variables */ + float32_t t1a, t1b; /* temporary variables */ + float32_t p0, p1, p2, p3; /* temporary variables */ + + + k = (S->Sint).fftLen - 1; + + /* Pack first and last sample of the frequency domain together */ + + xBR = pB[0]; + xBI = pB[1]; + xAR = pA[0]; + xAI = pA[1]; + + twR = *pCoeff++ ; + twI = *pCoeff++ ; + + // U1 = XA(1) + XB(1); % It is real + t1a = xBR + xAR ; + + // U2 = XB(1) - XA(1); % It is imaginary + t1b = xBI + xAI ; + + // real(tw * (xB - xA)) = twR * (xBR - xAR) - twI * (xBI - xAI); + // imag(tw * (xB - xA)) = twI * (xBR - xAR) + twR * (xBI - xAI); + *pOut++ = 0.5f * ( t1a + t1b ); + *pOut++ = 0.5f * ( t1a - t1b ); + + // XA(1) = 1/2*( U1 - imag(U2) + i*( U1 +imag(U2) )); + pB = p + 2*k; + pA += 2; + + do + { + /* + function X = my_split_rfft(X, ifftFlag) + % X is a series of real numbers + L = length(X); + XC = X(1:2:end) +i*X(2:2:end); + XA = fft(XC); + XB = conj(XA([1 end:-1:2])); + TW = i*exp(-2*pi*i*[0:L/2-1]/L).'; + for l = 2:L/2 + XA(l) = 1/2 * (XA(l) + XB(l) + TW(l) * (XB(l) - XA(l))); + end + XA(1) = 1/2* (XA(1) + XB(1) + TW(1) * (XB(1) - XA(1))) + i*( 1/2*( XA(1) + XB(1) + i*( XA(1) - XB(1)))); + X = XA; + */ + + xBI = pB[1]; + xBR = pB[0]; + xAR = pA[0]; + xAI = pA[1]; + + twR = *pCoeff++; + twI = *pCoeff++; + + t1a = xBR - xAR ; + t1b = xBI + xAI ; + + // real(tw * (xB - xA)) = twR * (xBR - xAR) - twI * (xBI - xAI); + // imag(tw * (xB - xA)) = twI * (xBR - xAR) + twR * (xBI - xAI); + p0 = twR * t1a; + p1 = twI * t1a; + p2 = twR * t1b; + p3 = twI * t1b; + + *pOut++ = 0.5f * (xAR + xBR + p0 + p3 ); //xAR + *pOut++ = 0.5f * (xAI - xBI + p1 - p2 ); //xAI + + pA += 2; + pB -= 2; + k--; + } while (k > 0U); +} + +/* Prepares data for inverse cfft */ +void merge_rfft_f32( + const arm_rfft_fast_instance_f32 * S, + float32_t * p, + float32_t * pOut) +{ + uint32_t k; /* Loop Counter */ + float32_t twR, twI; /* RFFT Twiddle coefficients */ + const float32_t *pCoeff = S->pTwiddleRFFT; /* Points to RFFT Twiddle factors */ + float32_t *pA = p; /* increasing pointer */ + float32_t *pB = p; /* decreasing pointer */ + float32_t xAR, xAI, xBR, xBI; /* temporary variables */ + float32_t t1a, t1b, r, s, t, u; /* temporary variables */ + + k = (S->Sint).fftLen - 1; + + xAR = pA[0]; + xAI = pA[1]; + + pCoeff += 2 ; + + *pOut++ = 0.5f * ( xAR + xAI ); + *pOut++ = 0.5f * ( xAR - xAI ); + + pB = p + 2*k ; + pA += 2 ; + + while (k > 0U) + { + /* G is half of the frequency complex spectrum */ + //for k = 2:N + // Xk(k) = 1/2 * (G(k) + conj(G(N-k+2)) + Tw(k)*( G(k) - conj(G(N-k+2)))); + xBI = pB[1] ; + xBR = pB[0] ; + xAR = pA[0]; + xAI = pA[1]; + + twR = *pCoeff++; + twI = *pCoeff++; + + t1a = xAR - xBR ; + t1b = xAI + xBI ; + + r = twR * t1a; + s = twI * t1b; + t = twI * t1a; + u = twR * t1b; + + // real(tw * (xA - xB)) = twR * (xAR - xBR) - twI * (xAI - xBI); + // imag(tw * (xA - xB)) = twI * (xAR - xBR) + twR * (xAI - xBI); + *pOut++ = 0.5f * (xAR + xBR - r - s ); //xAR + *pOut++ = 0.5f * (xAI - xBI + t - u ); //xAI + + pA += 2; + pB -= 2; + k--; + } + +} + +/** + @ingroup groupTransforms +*/ + +/** + @defgroup RealFFT Real FFT Functions + + @par + The CMSIS DSP library includes specialized algorithms for computing the + FFT of real data sequences. The FFT is defined over complex data but + in many applications the input is real. Real FFT algorithms take advantage + of the symmetry properties of the FFT and have a speed advantage over complex + algorithms of the same length. + @par + The Fast RFFT algorith relays on the mixed radix CFFT that save processor usage. + @par + The real length N forward FFT of a sequence is computed using the steps shown below. + @par + \image html RFFT.gif "Real Fast Fourier Transform" + @par + The real sequence is initially treated as if it were complex to perform a CFFT. + Later, a processing stage reshapes the data to obtain half of the frequency spectrum + in complex format. Except the first complex number that contains the two real numbers + X[0] and X[N/2] all the data is complex. In other words, the first complex sample + contains two real values packed. + @par + The input for the inverse RFFT should keep the same format as the output of the + forward RFFT. A first processing stage pre-process the data to later perform an + inverse CFFT. + @par + \image html RIFFT.gif "Real Inverse Fast Fourier Transform" + @par + The algorithms for floating-point, Q15, and Q31 data are slightly different + and we describe each algorithm in turn. + @par Floating-point + The main functions are \ref arm_rfft_fast_f32() and \ref arm_rfft_fast_init_f32(). + The older functions \ref arm_rfft_f32() and \ref arm_rfft_init_f32() have been deprecated + but are still documented. + @par + The FFT of a real N-point sequence has even symmetry in the frequency domain. + The second half of the data equals the conjugate of the first half flipped in frequency. + Looking at the data, we see that we can uniquely represent the FFT using only N/2 complex numbers. + These are packed into the output array in alternating real and imaginary components: + @par + X = { real[0], imag[0], real[1], imag[1], real[2], imag[2] ... + real[(N/2)-1], imag[(N/2)-1 } + @par + It happens that the first complex number (real[0], imag[0]) is actually + all real. real[0] represents the DC offset, and imag[0] should be 0. + (real[1], imag[1]) is the fundamental frequency, (real[2], imag[2]) is + the first harmonic and so on. + @par + The real FFT functions pack the frequency domain data in this fashion. + The forward transform outputs the data in this form and the inverse + transform expects input data in this form. The function always performs + the needed bitreversal so that the input and output data is always in + normal order. The functions support lengths of [32, 64, 128, ..., 4096] + samples. + @par Q15 and Q31 + The real algorithms are defined in a similar manner and utilize N/2 complex + transforms behind the scenes. + @par + The complex transforms used internally include scaling to prevent fixed-point + overflows. The overall scaling equals 1/(fftLen/2). + @par + A separate instance structure must be defined for each transform used but + twiddle factor and bit reversal tables can be reused. + @par + There is also an associated initialization function for each data type. + The initialization function performs the following operations: + - Sets the values of the internal structure fields. + - Initializes twiddle factor table and bit reversal table pointers. + - Initializes the internal complex FFT data structure. + @par + Use of the initialization function is optional. + However, if the initialization function is used, then the instance structure + cannot be placed into a const data section. To place an instance structure + into a const data section, the instance structure should be manually + initialized as follows: +
+      arm_rfft_instance_q31 S = {fftLenReal, fftLenBy2, ifftFlagR, bitReverseFlagR, twidCoefRModifier, pTwiddleAReal, pTwiddleBReal, pCfft};
+      arm_rfft_instance_q15 S = {fftLenReal, fftLenBy2, ifftFlagR, bitReverseFlagR, twidCoefRModifier, pTwiddleAReal, pTwiddleBReal, pCfft};
+  
+ where fftLenReal is the length of the real transform; + fftLenBy2 length of the internal complex transform. + ifftFlagR Selects forward (=0) or inverse (=1) transform. + bitReverseFlagR Selects bit reversed output (=0) or normal order + output (=1). + twidCoefRModifier stride modifier for the twiddle factor table. + The value is based on the FFT length; + pTwiddleARealpoints to the A array of twiddle coefficients; + pTwiddleBRealpoints to the B array of twiddle coefficients; + pCfft points to the CFFT Instance structure. The CFFT structure + must also be initialized. Refer to arm_cfft_radix4_f32() for details regarding + static initialization of the complex FFT instance structure. + */ + +/** + @addtogroup RealFFT + @{ +*/ + +/** + @brief Processing function for the floating-point real FFT. + @param[in] S points to an arm_rfft_fast_instance_f32 structure + @param[in] p points to input buffer + @param[in] pOut points to output buffer + @param[in] ifftFlag + - value = 0: RFFT + - value = 1: RIFFT + @return none +*/ + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, + float32_t * pOut, + uint8_t ifftFlag) +{ + arm_cfft_instance_f32 * Sint = &(S->Sint); + Sint->fftLen = S->fftLenRFFT / 2; + + /* Calculation of Real FFT */ + if (ifftFlag) + { + /* Real FFT compression */ + merge_rfft_f32(S, p, pOut); + + /* Complex radix-4 IFFT process */ + arm_cfft_f32( Sint, pOut, ifftFlag, 1); + } + else + { + /* Calculation of RFFT of input */ + arm_cfft_f32( Sint, p, ifftFlag, 1); + + /* Real FFT extraction */ + stage_rfft_f32(S, p, pOut); + } +} + +/** +* @} end of RealFFT group +*/ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_fast_init_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_fast_init_f32.c new file mode 100644 index 0000000..ff70329 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_fast_init_f32.c @@ -0,0 +1,312 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_cfft_init_f32.c + * Description: Split Radix Decimation in Frequency CFFT Floating point processing function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" + +/** + @ingroup groupTransforms + */ + +/** + @addtogroup RealFFT + @{ + */ + + +/** + @brief Initialization function for the 32pt floating-point real FFT. + @param[in,out] S points to an arm_rfft_fast_instance_f32 structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : an error is detected + */ + +arm_status arm_rfft_32_fast_init_f32( arm_rfft_fast_instance_f32 * S ) { + + arm_cfft_instance_f32 * Sint; + + if( !S ) return ARM_MATH_ARGUMENT_ERROR; + + Sint = &(S->Sint); + Sint->fftLen = 16U; + S->fftLenRFFT = 32U; + + Sint->bitRevLength = ARMBITREVINDEXTABLE_16_TABLE_LENGTH; + Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable16; + Sint->pTwiddle = (float32_t *) twiddleCoef_16; + S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_32; + + return ARM_MATH_SUCCESS; +} + +/** + @brief Initialization function for the 64pt floating-point real FFT. + @param[in,out] S points to an arm_rfft_fast_instance_f32 structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : an error is detected + */ + +arm_status arm_rfft_64_fast_init_f32( arm_rfft_fast_instance_f32 * S ) { + + arm_cfft_instance_f32 * Sint; + + if( !S ) return ARM_MATH_ARGUMENT_ERROR; + + Sint = &(S->Sint); + Sint->fftLen = 32U; + S->fftLenRFFT = 64U; + + Sint->bitRevLength = ARMBITREVINDEXTABLE_32_TABLE_LENGTH; + Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable32; + Sint->pTwiddle = (float32_t *) twiddleCoef_32; + S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_64; + + return ARM_MATH_SUCCESS; +} + +/** + @brief Initialization function for the 128pt floating-point real FFT. + @param[in,out] S points to an arm_rfft_fast_instance_f32 structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : an error is detected + */ + +arm_status arm_rfft_128_fast_init_f32( arm_rfft_fast_instance_f32 * S ) { + + arm_cfft_instance_f32 * Sint; + + if( !S ) return ARM_MATH_ARGUMENT_ERROR; + + Sint = &(S->Sint); + Sint->fftLen = 64U; + S->fftLenRFFT = 128U; + + Sint->bitRevLength = ARMBITREVINDEXTABLE_64_TABLE_LENGTH; + Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable64; + Sint->pTwiddle = (float32_t *) twiddleCoef_64; + S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_128; + + return ARM_MATH_SUCCESS; +} + +/** + @brief Initialization function for the 256pt floating-point real FFT. + @param[in,out] S points to an arm_rfft_fast_instance_f32 structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : an error is detected +*/ + +arm_status arm_rfft_256_fast_init_f32( arm_rfft_fast_instance_f32 * S ) { + + arm_cfft_instance_f32 * Sint; + + if( !S ) return ARM_MATH_ARGUMENT_ERROR; + + Sint = &(S->Sint); + Sint->fftLen = 128U; + S->fftLenRFFT = 256U; + + Sint->bitRevLength = ARMBITREVINDEXTABLE_128_TABLE_LENGTH; + Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable128; + Sint->pTwiddle = (float32_t *) twiddleCoef_128; + S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_256; + + return ARM_MATH_SUCCESS; +} + +/** + @brief Initialization function for the 512pt floating-point real FFT. + @param[in,out] S points to an arm_rfft_fast_instance_f32 structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : an error is detected + */ + +arm_status arm_rfft_512_fast_init_f32( arm_rfft_fast_instance_f32 * S ) { + + arm_cfft_instance_f32 * Sint; + + if( !S ) return ARM_MATH_ARGUMENT_ERROR; + + Sint = &(S->Sint); + Sint->fftLen = 256U; + S->fftLenRFFT = 512U; + + Sint->bitRevLength = ARMBITREVINDEXTABLE_256_TABLE_LENGTH; + Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable256; + Sint->pTwiddle = (float32_t *) twiddleCoef_256; + S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_512; + + return ARM_MATH_SUCCESS; +} + +/** + @brief Initialization function for the 1024pt floating-point real FFT. + @param[in,out] S points to an arm_rfft_fast_instance_f32 structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : an error is detected + */ + +arm_status arm_rfft_1024_fast_init_f32( arm_rfft_fast_instance_f32 * S ) { + + arm_cfft_instance_f32 * Sint; + + if( !S ) return ARM_MATH_ARGUMENT_ERROR; + + Sint = &(S->Sint); + Sint->fftLen = 512U; + S->fftLenRFFT = 1024U; + + Sint->bitRevLength = ARMBITREVINDEXTABLE_512_TABLE_LENGTH; + Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable512; + Sint->pTwiddle = (float32_t *) twiddleCoef_512; + S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_1024; + + return ARM_MATH_SUCCESS; +} + +/** + @brief Initialization function for the 2048pt floating-point real FFT. + @param[in,out] S points to an arm_rfft_fast_instance_f32 structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : an error is detected + */ +arm_status arm_rfft_2048_fast_init_f32( arm_rfft_fast_instance_f32 * S ) { + + arm_cfft_instance_f32 * Sint; + + if( !S ) return ARM_MATH_ARGUMENT_ERROR; + + Sint = &(S->Sint); + Sint->fftLen = 1024U; + S->fftLenRFFT = 2048U; + + Sint->bitRevLength = ARMBITREVINDEXTABLE_1024_TABLE_LENGTH; + Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable1024; + Sint->pTwiddle = (float32_t *) twiddleCoef_1024; + S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_2048; + + return ARM_MATH_SUCCESS; +} + +/** +* @brief Initialization function for the 4096pt floating-point real FFT. +* @param[in,out] S points to an arm_rfft_fast_instance_f32 structure + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : an error is detected + */ + +arm_status arm_rfft_4096_fast_init_f32( arm_rfft_fast_instance_f32 * S ) { + + arm_cfft_instance_f32 * Sint; + + if( !S ) return ARM_MATH_ARGUMENT_ERROR; + + Sint = &(S->Sint); + Sint->fftLen = 2048U; + S->fftLenRFFT = 4096U; + + Sint->bitRevLength = ARMBITREVINDEXTABLE_2048_TABLE_LENGTH; + Sint->pBitRevTable = (uint16_t *)armBitRevIndexTable2048; + Sint->pTwiddle = (float32_t *) twiddleCoef_2048; + S->pTwiddleRFFT = (float32_t *) twiddleCoef_rfft_4096; + + return ARM_MATH_SUCCESS; +} + +/** + @brief Initialization function for the floating-point real FFT. + @param[in,out] S points to an arm_rfft_fast_instance_f32 structure + @param[in] fftLen length of the Real Sequence + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : fftLen is not a supported length + + @par Description + The parameter fftLen specifies the length of RFFT/CIFFT process. + Supported FFT Lengths are 32, 64, 128, 256, 512, 1024, 2048, 4096. + @par + This Function also initializes Twiddle factor table pointer and Bit reversal table pointer. + */ + +arm_status arm_rfft_fast_init_f32( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen) +{ + typedef arm_status(*fft_init_ptr)( arm_rfft_fast_instance_f32 *); + fft_init_ptr fptr = 0x0; + + switch (fftLen) + { +#ifdef ENABLE_ARM_RFFT_F32_4096 + case 4096U: + fptr = arm_rfft_4096_fast_init_f32; + break; +#endif +#ifdef ENABLE_ARM_RFFT_F32_4096 + case 2048U: + fptr = arm_rfft_2048_fast_init_f32; + break; +#endif + case 1024U: + fptr = arm_rfft_1024_fast_init_f32; + break; + case 512U: + fptr = arm_rfft_512_fast_init_f32; + break; + case 256U: + fptr = arm_rfft_256_fast_init_f32; + break; + case 128U: + fptr = arm_rfft_128_fast_init_f32; + break; + case 64U: + fptr = arm_rfft_64_fast_init_f32; + break; + case 32U: + fptr = arm_rfft_32_fast_init_f32; + break; + default: + return ARM_MATH_ARGUMENT_ERROR; + } + + if( ! fptr ) return ARM_MATH_ARGUMENT_ERROR; + return fptr( S ); + +} + +/** + @} end of RealFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_f32.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_f32.c new file mode 100644 index 0000000..57a6c4d --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_f32.c @@ -0,0 +1,4279 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_rfft_init_f32.c + * Description: RFFT & RIFFT Floating point initialisation function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/** + @ingroup RealFFT + */ + +/** + @addtogroup RealFFT_Table Real FFT Tables + @{ + */ + +/** + @par + Generation of realCoefA array: + @par + n = 4096 +
for (i = 0; i < n; i++)
+  {
+     pATable[2 * i]     = 0.5 * ( 1.0 - sin (2 * PI / (double) (2 * n) * (double) i));
+     pATable[2 * i + 1] = 0.5 * (-1.0 * cos (2 * PI / (double) (2 * n) * (double) i));
+  }
+ */ + +static const float32_t realCoefA[8192] = { + 0.500000000000000f, -0.500000000000000f, 0.499616503715515f, -0.499999850988388f, + 0.499233007431030f, -0.499999403953552f, 0.498849511146545f, -0.499998688697815f, + 0.498466014862061f, -0.499997645616531f, 0.498082518577576f, -0.499996334314346f, + 0.497699022293091f, -0.499994695186615f, 0.497315555810928f, -0.499992787837982f, + 0.496932059526443f, -0.499990582466125f, 0.496548563241959f, -0.499988079071045f, + 0.496165096759796f, -0.499985307455063f, 0.495781600475311f, -0.499982208013535f, + 0.495398133993149f, -0.499978810548782f, 0.495014637708664f, -0.499975144863129f, + 0.494631171226501f, -0.499971181154251f, 0.494247704744339f, -0.499966919422150f, + 0.493864238262177f, -0.499962359666824f, 0.493480771780014f, -0.499957501888275f, + 0.493097305297852f, -0.499952346086502f, 0.492713838815689f, -0.499946922063828f, + 0.492330402135849f, -0.499941170215607f, 0.491946935653687f, -0.499935150146484f, + 0.491563498973846f, -0.499928832054138f, 0.491180062294006f, -0.499922215938568f, + 0.490796625614166f, -0.499915301799774f, 0.490413218736649f, -0.499908089637756f, + 0.490029782056808f, -0.499900579452515f, 0.489646375179291f, -0.499892801046371f, + 0.489262968301773f, -0.499884694814682f, 0.488879561424255f, -0.499876320362091f, + 0.488496154546738f, -0.499867647886276f, 0.488112777471542f, -0.499858677387238f, + 0.487729400396347f, -0.499849408864975f, 0.487346023321152f, -0.499839842319489f, + 0.486962646245956f, -0.499830007553101f, 0.486579269170761f, -0.499819844961166f, + 0.486195921897888f, -0.499809414148331f, 0.485812574625015f, -0.499798685312271f, + 0.485429257154465f, -0.499787658452988f, 0.485045909881592f, -0.499776333570480f, + 0.484662592411041f, -0.499764710664749f, 0.484279274940491f, -0.499752789735794f, + 0.483895987272263f, -0.499740600585938f, 0.483512699604034f, -0.499728083610535f, + 0.483129411935806f, -0.499715298414230f, 0.482746154069901f, -0.499702215194702f, + 0.482362866401672f, -0.499688833951950f, 0.481979638338089f, -0.499675154685974f, + 0.481596380472183f, -0.499661177396774f, 0.481213152408600f, -0.499646931886673f, + 0.480829954147339f, -0.499632388353348f, 0.480446726083755f, -0.499617516994476f, + 0.480063527822495f, -0.499602377414703f, 0.479680359363556f, -0.499586939811707f, + 0.479297190904617f, -0.499571204185486f, 0.478914022445679f, -0.499555170536041f, + 0.478530883789063f, -0.499538868665695f, 0.478147745132446f, -0.499522238969803f, + 0.477764606475830f, -0.499505341053009f, 0.477381497621536f, -0.499488145112991f, + 0.476998418569565f, -0.499470651149750f, 0.476615339517593f, -0.499452859163284f, + 0.476232260465622f, -0.499434769153595f, 0.475849211215973f, -0.499416410923004f, + 0.475466161966324f, -0.499397724866867f, 0.475083142518997f, -0.499378770589828f, + 0.474700123071671f, -0.499359518289566f, 0.474317133426666f, -0.499339967966080f, + 0.473934143781662f, -0.499320119619370f, 0.473551183938980f, -0.499299973249435f, + 0.473168224096298f, -0.499279528856277f, 0.472785294055939f, -0.499258816242218f, + 0.472402364015579f, -0.499237775802612f, 0.472019463777542f, -0.499216467142105f, + 0.471636593341827f, -0.499194860458374f, 0.471253722906113f, -0.499172955751419f, + 0.470870882272720f, -0.499150782823563f, 0.470488041639328f, -0.499128282070160f, + 0.470105201005936f, -0.499105513095856f, 0.469722419977188f, -0.499082416296005f, + 0.469339638948441f, -0.499059051275253f, 0.468956857919693f, -0.499035388231277f, + 0.468574106693268f, -0.499011427164078f, 0.468191385269165f, -0.498987197875977f, + 0.467808693647385f, -0.498962640762329f, 0.467426002025604f, -0.498937815427780f, + 0.467043310403824f, -0.498912662267685f, 0.466660678386688f, -0.498887240886688f, + 0.466278046369553f, -0.498861521482468f, 0.465895414352417f, -0.498835533857346f, + 0.465512841939926f, -0.498809218406677f, 0.465130269527435f, -0.498782604932785f, + 0.464747726917267f, -0.498755723237991f, 0.464365184307098f, -0.498728543519974f, + 0.463982671499252f, -0.498701065778732f, 0.463600188493729f, -0.498673290014267f, + 0.463217705488205f, -0.498645216226578f, 0.462835282087326f, -0.498616874217987f, + 0.462452858686447f, -0.498588204383850f, 0.462070435285568f, -0.498559266328812f, + 0.461688071489334f, -0.498530030250549f, 0.461305707693100f, -0.498500496149063f, + 0.460923373699188f, -0.498470664024353f, 0.460541069507599f, -0.498440563678741f, + 0.460158795118332f, -0.498410135507584f, 0.459776520729065f, -0.498379439115524f, + 0.459394276142120f, -0.498348444700241f, 0.459012061357498f, -0.498317152261734f, + 0.458629876375198f, -0.498285561800003f, 0.458247691392899f, -0.498253703117371f, + 0.457865566015244f, -0.498221516609192f, 0.457483440637589f, -0.498189061880112f, + 0.457101345062256f, -0.498156309127808f, 0.456719279289246f, -0.498123258352280f, + 0.456337243318558f, -0.498089909553528f, 0.455955207347870f, -0.498056292533875f, + 0.455573230981827f, -0.498022347688675f, 0.455191254615784f, -0.497988134622574f, + 0.454809308052063f, -0.497953623533249f, 0.454427421092987f, -0.497918814420700f, + 0.454045534133911f, -0.497883707284927f, 0.453663676977158f, -0.497848302125931f, + 0.453281819820404f, -0.497812628746033f, 0.452900022268295f, -0.497776657342911f, + 0.452518254518509f, -0.497740387916565f, 0.452136516571045f, -0.497703820466995f, + 0.451754778623581f, -0.497666954994202f, 0.451373100280762f, -0.497629791498184f, + 0.450991421937943f, -0.497592359781265f, 0.450609803199768f, -0.497554630041122f, + 0.450228184461594f, -0.497516602277756f, 0.449846625328064f, -0.497478276491165f, + 0.449465066194534f, -0.497439652681351f, 0.449083566665649f, -0.497400760650635f, + 0.448702067136765f, -0.497361570596695f, 0.448320597410202f, -0.497322082519531f, + 0.447939187288284f, -0.497282296419144f, 0.447557777166367f, -0.497242212295532f, + 0.447176426649094f, -0.497201830148697f, 0.446795076131821f, -0.497161179780960f, + 0.446413785219193f, -0.497120231389999f, 0.446032524108887f, -0.497078984975815f, + 0.445651292800903f, -0.497037440538406f, 0.445270061492920f, -0.496995598077774f, + 0.444888889789581f, -0.496953487396240f, 0.444507747888565f, -0.496911078691483f, + 0.444126635789871f, -0.496868371963501f, 0.443745553493500f, -0.496825367212296f, + 0.443364530801773f, -0.496782064437866f, 0.442983508110046f, -0.496738493442535f, + 0.442602545022964f, -0.496694594621658f, 0.442221581935883f, -0.496650427579880f, + 0.441840678453445f, -0.496605962514877f, 0.441459804773331f, -0.496561229228973f, + 0.441078960895538f, -0.496516168117523f, 0.440698176622391f, -0.496470838785172f, + 0.440317392349243f, -0.496425211429596f, 0.439936667680740f, -0.496379286050797f, + 0.439555943012238f, -0.496333062648773f, 0.439175277948380f, -0.496286571025848f, + 0.438794672489166f, -0.496239781379700f, 0.438414067029953f, -0.496192663908005f, + 0.438033521175385f, -0.496145308017731f, 0.437653005123138f, -0.496097624301910f, + 0.437272518873215f, -0.496049642562866f, 0.436892062425613f, -0.496001392602921f, + 0.436511665582657f, -0.495952844619751f, 0.436131268739700f, -0.495903998613358f, + 0.435750931501389f, -0.495854884386063f, 0.435370653867722f, -0.495805442333221f, + 0.434990376234055f, -0.495755732059479f, 0.434610158205032f, -0.495705723762512f, + 0.434229999780655f, -0.495655417442322f, 0.433849841356277f, -0.495604842901230f, + 0.433469742536545f, -0.495553970336914f, 0.433089673519135f, -0.495502769947052f, + 0.432709634304047f, -0.495451331138611f, 0.432329654693604f, -0.495399564504623f, + 0.431949704885483f, -0.495347499847412f, 0.431569814682007f, -0.495295166969299f, + 0.431189924478531f, -0.495242536067963f, 0.430810123682022f, -0.495189607143402f, + 0.430430322885513f, -0.495136409997940f, 0.430050581693649f, -0.495082914829254f, + 0.429670870304108f, -0.495029091835022f, 0.429291218519211f, -0.494975030422211f, + 0.428911596536636f, -0.494920641183853f, 0.428532034158707f, -0.494865983724594f, + 0.428152471780777f, -0.494810998439789f, 0.427772998809814f, -0.494755744934082f, + 0.427393525838852f, -0.494700223207474f, 0.427014142274857f, -0.494644373655319f, + 0.426634758710861f, -0.494588255882263f, 0.426255434751511f, -0.494531840085983f, + 0.425876170396805f, -0.494475126266479f, 0.425496935844421f, -0.494418144226074f, + 0.425117731094360f, -0.494360834360123f, 0.424738585948944f, -0.494303256273270f, + 0.424359470605850f, -0.494245409965515f, 0.423980414867401f, -0.494187235832214f, + 0.423601418733597f, -0.494128793478012f, 0.423222452402115f, -0.494070053100586f, + 0.422843515872955f, -0.494011014699936f, 0.422464638948441f, -0.493951678276062f, + 0.422085791826248f, -0.493892073631287f, 0.421707004308701f, -0.493832170963287f, + 0.421328276395798f, -0.493771970272064f, 0.420949578285217f, -0.493711471557617f, + 0.420570939779282f, -0.493650704622269f, 0.420192331075668f, -0.493589639663696f, + 0.419813781976700f, -0.493528276681900f, 0.419435262680054f, -0.493466645479202f, + 0.419056802988052f, -0.493404686450958f, 0.418678402900696f, -0.493342459201813f, + 0.418300032615662f, -0.493279963731766f, 0.417921721935272f, -0.493217140436172f, + 0.417543441057205f, -0.493154048919678f, 0.417165219783783f, -0.493090659379959f, + 0.416787058115005f, -0.493026971817017f, 0.416408926248550f, -0.492963016033173f, + 0.416030853986740f, -0.492898762226105f, 0.415652841329575f, -0.492834210395813f, + 0.415274858474731f, -0.492769360542297f, 0.414896935224533f, -0.492704242467880f, + 0.414519041776657f, -0.492638826370239f, 0.414141237735748f, -0.492573112249374f, + 0.413763463497162f, -0.492507129907608f, 0.413385748863220f, -0.492440819740295f, + 0.413008064031601f, -0.492374241352081f, 0.412630438804626f, -0.492307394742966f, + 0.412252873182297f, -0.492240220308304f, 0.411875367164612f, -0.492172777652740f, + 0.411497890949249f, -0.492105036973953f, 0.411120474338531f, -0.492037028074265f, + 0.410743117332459f, -0.491968721151352f, 0.410365819931030f, -0.491900116205215f, + 0.409988552331924f, -0.491831213235855f, 0.409611344337463f, -0.491762012243271f, + 0.409234195947647f, -0.491692543029785f, 0.408857107162476f, -0.491622805595398f, + 0.408480048179626f, -0.491552740335464f, 0.408103078603745f, -0.491482406854630f, + 0.407726138830185f, -0.491411775350571f, 0.407349258661270f, -0.491340845823288f, + 0.406972438097000f, -0.491269648075104f, 0.406595647335052f, -0.491198152303696f, + 0.406218945980072f, -0.491126358509064f, 0.405842274427414f, -0.491054296493530f, + 0.405465662479401f, -0.490981936454773f, 0.405089110136032f, -0.490909278392792f, + 0.404712617397308f, -0.490836352109909f, 0.404336184263229f, -0.490763127803802f, + 0.403959810733795f, -0.490689605474472f, 0.403583467006683f, -0.490615785121918f, + 0.403207212686539f, -0.490541696548462f, 0.402830988168716f, -0.490467309951782f, + 0.402454853057861f, -0.490392625331879f, 0.402078747749329f, -0.490317672491074f, + 0.401702702045441f, -0.490242421627045f, 0.401326715946198f, -0.490166902542114f, + 0.400950789451599f, -0.490091055631638f, 0.400574922561646f, -0.490014940500259f, + 0.400199115276337f, -0.489938557147980f, 0.399823367595673f, -0.489861875772476f, + 0.399447679519653f, -0.489784896373749f, 0.399072051048279f, -0.489707618951797f, + 0.398696482181549f, -0.489630073308945f, 0.398320972919464f, -0.489552229642868f, + 0.397945523262024f, -0.489474087953568f, 0.397570133209229f, -0.489395678043365f, + 0.397194802761078f, -0.489316970109940f, 0.396819531917572f, -0.489237964153290f, + 0.396444320678711f, -0.489158689975739f, 0.396069169044495f, -0.489079117774963f, + 0.395694077014923f, -0.488999247550964f, 0.395319044589996f, -0.488919109106064f, + 0.394944071769714f, -0.488838672637939f, 0.394569188356400f, -0.488757967948914f, + 0.394194334745407f, -0.488676935434341f, 0.393819570541382f, -0.488595664501190f, + 0.393444836139679f, -0.488514065742493f, 0.393070191144943f, -0.488432198762894f, + 0.392695605754852f, -0.488350033760071f, 0.392321079969406f, -0.488267600536346f, + 0.391946613788605f, -0.488184869289398f, 0.391572207212448f, -0.488101840019226f, + 0.391197860240936f, -0.488018542528152f, 0.390823602676392f, -0.487934947013855f, + 0.390449374914169f, -0.487851053476334f, 0.390075236558914f, -0.487766891717911f, + 0.389701157808304f, -0.487682431936264f, 0.389327138662338f, -0.487597703933716f, + 0.388953179121017f, -0.487512677907944f, 0.388579308986664f, -0.487427353858948f, + 0.388205498456955f, -0.487341761589050f, 0.387831717729568f, -0.487255871295929f, + 0.387458056211472f, -0.487169682979584f, 0.387084424495697f, -0.487083226442337f, + 0.386710882186890f, -0.486996471881866f, 0.386337369680405f, -0.486909449100494f, + 0.385963946580887f, -0.486822128295898f, 0.385590612888336f, -0.486734509468079f, + 0.385217308998108f, -0.486646622419357f, 0.384844094514847f, -0.486558437347412f, + 0.384470939636230f, -0.486469984054565f, 0.384097874164581f, -0.486381232738495f, + 0.383724838495255f, -0.486292183399200f, 0.383351892232895f, -0.486202865839005f, + 0.382979035377502f, -0.486113250255585f, 0.382606208324432f, -0.486023366451263f, + 0.382233470678329f, -0.485933154821396f, 0.381860792636871f, -0.485842704772949f, + 0.381488204002380f, -0.485751956701279f, 0.381115674972534f, -0.485660910606384f, + 0.380743205547333f, -0.485569566488266f, 0.380370795726776f, -0.485477954149246f, + 0.379998475313187f, -0.485386073589325f, 0.379626244306564f, -0.485293895006180f, + 0.379254043102264f, -0.485201418399811f, 0.378881961107254f, -0.485108673572540f, + 0.378509908914566f, -0.485015630722046f, 0.378137946128845f, -0.484922289848328f, + 0.377766042947769f, -0.484828680753708f, 0.377394229173660f, -0.484734803438187f, + 0.377022475004196f, -0.484640628099442f, 0.376650810241699f, -0.484546154737473f, + 0.376279205083847f, -0.484451413154602f, 0.375907659530640f, -0.484356373548508f, + 0.375536203384399f, -0.484261035919189f, 0.375164806842804f, -0.484165430068970f, + 0.374793499708176f, -0.484069555997849f, 0.374422252178192f, -0.483973383903503f, + 0.374051094055176f, -0.483876913785934f, 0.373679995536804f, -0.483780175447464f, + 0.373308986425400f, -0.483683139085770f, 0.372938036918640f, -0.483585834503174f, + 0.372567176818848f, -0.483488231897354f, 0.372196376323700f, -0.483390361070633f, + 0.371825665235519f, -0.483292192220688f, 0.371455013751984f, -0.483193725347519f, + 0.371084451675415f, -0.483094990253448f, 0.370713949203491f, -0.482995986938477f, + 0.370343536138535f, -0.482896685600281f, 0.369973212480545f, -0.482797086238861f, + 0.369602948427200f, -0.482697218656540f, 0.369232743978500f, -0.482597053050995f, + 0.368862658739090f, -0.482496619224548f, 0.368492603302002f, -0.482395917177200f, + 0.368122667074203f, -0.482294887304306f, 0.367752790451050f, -0.482193619012833f, + 0.367382973432541f, -0.482092022895813f, 0.367013275623322f, -0.481990188360214f, + 0.366643607616425f, -0.481888025999069f, 0.366274058818817f, -0.481785595417023f, + 0.365904569625854f, -0.481682896614075f, 0.365535169839859f, -0.481579899787903f, + 0.365165829658508f, -0.481476634740829f, 0.364796578884125f, -0.481373071670532f, + 0.364427417516708f, -0.481269240379334f, 0.364058345556259f, -0.481165111064911f, + 0.363689333200455f, -0.481060713529587f, 0.363320380449295f, -0.480956017971039f, + 0.362951546907425f, -0.480851024389267f, 0.362582772970200f, -0.480745792388916f, + 0.362214088439941f, -0.480640232563019f, 0.361845493316650f, -0.480534434318542f, + 0.361476957798004f, -0.480428308248520f, 0.361108511686325f, -0.480321943759918f, + 0.360740154981613f, -0.480215251445770f, 0.360371887683868f, -0.480108320713043f, + 0.360003679990768f, -0.480001062154770f, 0.359635561704636f, -0.479893565177917f, + 0.359267532825470f, -0.479785770177841f, 0.358899593353271f, -0.479677677154541f, + 0.358531713485718f, -0.479569315910339f, 0.358163923025131f, -0.479460656642914f, + 0.357796221971512f, -0.479351729154587f, 0.357428610324860f, -0.479242533445358f, + 0.357061088085175f, -0.479133039712906f, 0.356693625450134f, -0.479023247957230f, + 0.356326282024384f, -0.478913217782974f, 0.355958998203278f, -0.478802859783173f, + 0.355591803789139f, -0.478692263364792f, 0.355224698781967f, -0.478581339120865f, + 0.354857653379440f, -0.478470176458359f, 0.354490727186203f, -0.478358715772629f, + 0.354123860597610f, -0.478246957063675f, 0.353757113218308f, -0.478134930133820f, + 0.353390425443649f, -0.478022634983063f, 0.353023827075958f, -0.477910041809082f, + 0.352657318115234f, -0.477797180414200f, 0.352290898561478f, -0.477684020996094f, + 0.351924568414688f, -0.477570593357086f, 0.351558297872543f, -0.477456867694855f, + 0.351192146539688f, -0.477342873811722f, 0.350826084613800f, -0.477228611707687f, + 0.350460082292557f, -0.477114051580429f, 0.350094199180603f, -0.476999223232269f, + 0.349728375673294f, -0.476884096860886f, 0.349362671375275f, -0.476768702268600f, + 0.348997026681900f, -0.476653009653091f, 0.348631471395493f, -0.476537048816681f, + 0.348266035318375f, -0.476420819759369f, 0.347900658845901f, -0.476304292678833f, + 0.347535371780396f, -0.476187497377396f, 0.347170203924179f, -0.476070433855057f, + 0.346805095672607f, -0.475953072309494f, 0.346440106630325f, -0.475835442543030f, + 0.346075177192688f, -0.475717514753342f, 0.345710366964340f, -0.475599318742752f, + 0.345345616340637f, -0.475480824708939f, 0.344980984926224f, -0.475362062454224f, + 0.344616413116455f, -0.475243031978607f, 0.344251960515976f, -0.475123733282089f, + 0.343887597322464f, -0.475004136562347f, 0.343523323535919f, -0.474884241819382f, + 0.343159139156342f, -0.474764078855515f, 0.342795044183731f, -0.474643647670746f, + 0.342431038618088f, -0.474522948265076f, 0.342067122459412f, -0.474401950836182f, + 0.341703325510025f, -0.474280685186386f, 0.341339588165283f, -0.474159121513367f, + 0.340975970029831f, -0.474037289619446f, 0.340612411499023f, -0.473915189504623f, + 0.340248972177505f, -0.473792791366577f, 0.339885622262955f, -0.473670125007629f, + 0.339522391557693f, -0.473547190427780f, 0.339159220457077f, -0.473423957824707f, + 0.338796168565750f, -0.473300457000732f, 0.338433176279068f, -0.473176687955856f, + 0.338070303201675f, -0.473052620887756f, 0.337707549333572f, -0.472928285598755f, + 0.337344855070114f, -0.472803652286530f, 0.336982280015945f, -0.472678780555725f, + 0.336619764566422f, -0.472553610801697f, 0.336257368326187f, -0.472428143024445f, + 0.335895091295242f, -0.472302407026291f, 0.335532873868942f, -0.472176402807236f, + 0.335170775651932f, -0.472050130367279f, 0.334808766841888f, -0.471923559904099f, + 0.334446847438812f, -0.471796721220016f, 0.334085017442703f, -0.471669614315033f, + 0.333723306655884f, -0.471542209386826f, 0.333361685276031f, -0.471414536237717f, + 0.333000183105469f, -0.471286594867706f, 0.332638740539551f, -0.471158385276794f, + 0.332277417182922f, -0.471029877662659f, 0.331916213035584f, -0.470901101827621f, + 0.331555068492889f, -0.470772027969360f, 0.331194043159485f, -0.470642685890198f, + 0.330833107233047f, -0.470513075590134f, 0.330472290515900f, -0.470383197069168f, + 0.330111563205719f, -0.470253020524979f, 0.329750925302505f, -0.470122605562210f, + 0.329390406608582f, -0.469991862773895f, 0.329029977321625f, -0.469860881567001f, + 0.328669637441635f, -0.469729602336884f, 0.328309416770935f, -0.469598054885864f, + 0.327949285507202f, -0.469466239213943f, 0.327589273452759f, -0.469334155321121f, + 0.327229350805283f, -0.469201773405075f, 0.326869517564774f, -0.469069123268127f, + 0.326509803533554f, -0.468936175107956f, 0.326150178909302f, -0.468802988529205f, + 0.325790673494339f, -0.468669503927231f, 0.325431257486343f, -0.468535751104355f, + 0.325071930885315f, -0.468401730060577f, 0.324712723493576f, -0.468267410993576f, + 0.324353635311127f, -0.468132823705673f, 0.323994606733322f, -0.467997968196869f, + 0.323635727167130f, -0.467862844467163f, 0.323276937007904f, -0.467727422714233f, + 0.322918236255646f, -0.467591762542725f, 0.322559654712677f, -0.467455804347992f, + 0.322201162576675f, -0.467319577932358f, 0.321842789649963f, -0.467183053493500f, + 0.321484506130219f, -0.467046260833740f, 0.321126341819763f, -0.466909229755402f, + 0.320768296718597f, -0.466771900653839f, 0.320410341024399f, -0.466634273529053f, + 0.320052474737167f, -0.466496407985687f, 0.319694727659225f, -0.466358244419098f, + 0.319337099790573f, -0.466219812631607f, 0.318979561328888f, -0.466081112623215f, + 0.318622142076492f, -0.465942144393921f, 0.318264812231064f, -0.465802878141403f, + 0.317907601594925f, -0.465663343667984f, 0.317550510168076f, -0.465523540973663f, + 0.317193508148193f, -0.465383470058441f, 0.316836595535278f, -0.465243130922318f, + 0.316479831933975f, -0.465102523565292f, 0.316123157739639f, -0.464961618185043f, + 0.315766572952271f, -0.464820444583893f, 0.315410137176514f, -0.464679002761841f, + 0.315053790807724f, -0.464537292718887f, 0.314697533845901f, -0.464395314455032f, + 0.314341396093369f, -0.464253038167953f, 0.313985377550125f, -0.464110493659973f, + 0.313629478216171f, -0.463967710733414f, 0.313273668289185f, -0.463824629783630f, + 0.312917977571487f, -0.463681250810623f, 0.312562376260757f, -0.463537633419037f, + 0.312206923961639f, -0.463393747806549f, 0.311851561069489f, -0.463249564170837f, + 0.311496287584305f, -0.463105112314224f, 0.311141163110733f, -0.462960392236710f, + 0.310786128044128f, -0.462815403938293f, 0.310431212186813f, -0.462670147418976f, + 0.310076385736465f, -0.462524622678757f, 0.309721708297729f, -0.462378799915314f, + 0.309367120265961f, -0.462232738733292f, 0.309012651443481f, -0.462086379528046f, + 0.308658272027969f, -0.461939752101898f, 0.308304041624069f, -0.461792886257172f, + 0.307949900627136f, -0.461645722389221f, 0.307595878839493f, -0.461498260498047f, + 0.307241976261139f, -0.461350560188293f, 0.306888192892075f, -0.461202591657639f, + 0.306534498929977f, -0.461054325103760f, 0.306180924177170f, -0.460905820131302f, + 0.305827468633652f, -0.460757017135620f, 0.305474132299423f, -0.460607945919037f, + 0.305120915174484f, -0.460458606481552f, 0.304767817258835f, -0.460309028625488f, + 0.304414808750153f, -0.460159152746201f, 0.304061919450760f, -0.460008978843689f, + 0.303709149360657f, -0.459858566522598f, 0.303356528282166f, -0.459707885980606f, + 0.303003966808319f, -0.459556937217712f, 0.302651554346085f, -0.459405690431595f, + 0.302299261093140f, -0.459254205226898f, 0.301947087049484f, -0.459102421998978f, + 0.301595002412796f, -0.458950400352478f, 0.301243066787720f, -0.458798080682755f, + 0.300891220569611f, -0.458645492792130f, 0.300539493560791f, -0.458492636680603f, + 0.300187885761261f, -0.458339542150497f, 0.299836426973343f, -0.458186149597168f, + 0.299485057592392f, -0.458032488822937f, 0.299133807420731f, -0.457878559827805f, + 0.298782676458359f, -0.457724362611771f, 0.298431664705276f, -0.457569897174835f, + 0.298080772161484f, -0.457415163516998f, 0.297729998826981f, -0.457260161638260f, + 0.297379344701767f, -0.457104891538620f, 0.297028809785843f, -0.456949323415756f, + 0.296678394079208f, -0.456793516874313f, 0.296328097581863f, -0.456637442111969f, + 0.295977920293808f, -0.456481099128723f, 0.295627862215042f, -0.456324487924576f, + 0.295277923345566f, -0.456167578697205f, 0.294928103685379f, -0.456010431051254f, + 0.294578403234482f, -0.455853015184402f, 0.294228851795197f, -0.455695331096649f, + 0.293879389762878f, -0.455537378787994f, 0.293530046939850f, -0.455379128456116f, + 0.293180853128433f, -0.455220639705658f, 0.292831748723984f, -0.455061882734299f, + 0.292482793331146f, -0.454902857542038f, 0.292133957147598f, -0.454743564128876f, + 0.291785210371017f, -0.454584002494812f, 0.291436612606049f, -0.454424172639847f, + 0.291088134050369f, -0.454264044761658f, 0.290739774703979f, -0.454103678464890f, + 0.290391564369202f, -0.453943043947220f, 0.290043443441391f, -0.453782171010971f, + 0.289695471525192f, -0.453621000051498f, 0.289347589015961f, -0.453459560871124f, + 0.288999855518341f, -0.453297853469849f, 0.288652241230011f, -0.453135877847672f, + 0.288304775953293f, -0.452973634004593f, 0.287957400083542f, -0.452811151742935f, + 0.287610173225403f, -0.452648371458054f, 0.287263035774231f, -0.452485352754593f, + 0.286916047334671f, -0.452322036027908f, 0.286569178104401f, -0.452158480882645f, + 0.286222457885742f, -0.451994657516479f, 0.285875827074051f, -0.451830536127090f, + 0.285529345273972f, -0.451666176319122f, 0.285182982683182f, -0.451501548290253f, + 0.284836769104004f, -0.451336652040482f, 0.284490644931793f, -0.451171487569809f, + 0.284144669771194f, -0.451006084680557f, 0.283798813819885f, -0.450840383768082f, + 0.283453077077866f, -0.450674414634705f, 0.283107489347458f, -0.450508207082748f, + 0.282762020826340f, -0.450341701507568f, 0.282416671514511f, -0.450174957513809f, + 0.282071471214294f, -0.450007945299149f, 0.281726360321045f, -0.449840664863586f, + 0.281381398439407f, -0.449673116207123f, 0.281036585569382f, -0.449505299329758f, + 0.280691891908646f, -0.449337244033813f, 0.280347317457199f, -0.449168890714645f, + 0.280002862215042f, -0.449000298976898f, 0.279658555984497f, -0.448831409215927f, + 0.279314368963242f, -0.448662281036377f, 0.278970301151276f, -0.448492884635925f, + 0.278626382350922f, -0.448323249816895f, 0.278282582759857f, -0.448153316974640f, + 0.277938932180405f, -0.447983115911484f, 0.277595400810242f, -0.447812676429749f, + 0.277251988649368f, -0.447641968727112f, 0.276908725500107f, -0.447470992803574f, + 0.276565581560135f, -0.447299748659134f, 0.276222556829453f, -0.447128236293793f, + 0.275879681110382f, -0.446956485509872f, 0.275536954402924f, -0.446784436702728f, + 0.275194346904755f, -0.446612149477005f, 0.274851858615875f, -0.446439594030380f, + 0.274509519338608f, -0.446266770362854f, 0.274167299270630f, -0.446093708276749f, + 0.273825198411942f, -0.445920348167419f, 0.273483246564865f, -0.445746749639511f, + 0.273141443729401f, -0.445572882890701f, 0.272799760103226f, -0.445398747920990f, + 0.272458195686340f, -0.445224374532700f, 0.272116780281067f, -0.445049703121185f, + 0.271775513887405f, -0.444874793291092f, 0.271434366703033f, -0.444699615240097f, + 0.271093338727951f, -0.444524168968201f, 0.270752459764481f, -0.444348484277725f, + 0.270411729812622f, -0.444172531366348f, 0.270071119070053f, -0.443996280431747f, + 0.269730657339096f, -0.443819820880890f, 0.269390314817429f, -0.443643063306808f, + 0.269050091505051f, -0.443466067314148f, 0.268710047006607f, -0.443288803100586f, + 0.268370121717453f, -0.443111270666122f, 0.268030315637589f, -0.442933470010757f, + 0.267690658569336f, -0.442755430936813f, 0.267351150512695f, -0.442577123641968f, + 0.267011761665344f, -0.442398548126221f, 0.266672492027283f, -0.442219734191895f, + 0.266333401203156f, -0.442040622234344f, 0.265994429588318f, -0.441861271858215f, + 0.265655577182770f, -0.441681683063507f, 0.265316903591156f, -0.441501796245575f, + 0.264978319406509f, -0.441321671009064f, 0.264639914035797f, -0.441141277551651f, + 0.264301627874374f, -0.440960645675659f, 0.263963490724564f, -0.440779715776443f, + 0.263625472784042f, -0.440598547458649f, 0.263287603855133f, -0.440417140722275f, + 0.262949883937836f, -0.440235435962677f, 0.262612313032150f, -0.440053492784500f, + 0.262274861335754f, -0.439871311187744f, 0.261937558650970f, -0.439688831567764f, + 0.261600375175476f, -0.439506113529205f, 0.261263370513916f, -0.439323127269745f, + 0.260926485061646f, -0.439139902591705f, 0.260589718818665f, -0.438956409692764f, + 0.260253131389618f, -0.438772648572922f, 0.259916663169861f, -0.438588619232178f, + 0.259580343961716f, -0.438404351472855f, 0.259244143962860f, -0.438219845294952f, + 0.258908122777939f, -0.438035041093826f, 0.258572220802307f, -0.437849998474121f, + 0.258236467838287f, -0.437664687633514f, 0.257900834083557f, -0.437479138374329f, + 0.257565379142761f, -0.437293320894241f, 0.257230043411255f, -0.437107264995575f, + 0.256894856691360f, -0.436920911073685f, 0.256559818983078f, -0.436734348535538f, + 0.256224930286407f, -0.436547487974167f, 0.255890160799026f, -0.436360388994217f, + 0.255555540323257f, -0.436173021793365f, 0.255221068859100f, -0.435985416173935f, + 0.254886746406555f, -0.435797542333603f, 0.254552572965622f, -0.435609430074692f, + 0.254218548536301f, -0.435421019792557f, 0.253884643316269f, -0.435232400894165f, + 0.253550916910172f, -0.435043483972549f, 0.253217309713364f, -0.434854328632355f, + 0.252883851528168f, -0.434664934873581f, 0.252550542354584f, -0.434475272893906f, + 0.252217382192612f, -0.434285342693329f, 0.251884341239929f, -0.434095174074173f, + 0.251551479101181f, -0.433904737234116f, 0.251218736171722f, -0.433714061975479f, + 0.250886172056198f, -0.433523118495941f, 0.250553727149963f, -0.433331936597824f, + 0.250221431255341f, -0.433140486478806f, 0.249889299273491f, -0.432948768138886f, + 0.249557301402092f, -0.432756811380386f, 0.249225467443466f, -0.432564586400986f, + 0.248893767595291f, -0.432372123003006f, 0.248562216758728f, -0.432179391384125f, + 0.248230814933777f, -0.431986421346664f, 0.247899547219276f, -0.431793183088303f, + 0.247568443417549f, -0.431599706411362f, 0.247237488627434f, -0.431405961513519f, + 0.246906682848930f, -0.431211978197098f, 0.246576011180878f, -0.431017726659775f, + 0.246245503425598f, -0.430823236703873f, 0.245915144681931f, -0.430628478527069f, + 0.245584934949875f, -0.430433481931686f, 0.245254859328270f, -0.430238217115402f, + 0.244924947619438f, -0.430042684078217f, 0.244595184922218f, -0.429846942424774f, + 0.244265571236610f, -0.429650902748108f, 0.243936106562614f, -0.429454624652863f, + 0.243606805801392f, -0.429258108139038f, 0.243277639150620f, -0.429061323404312f, + 0.242948621511459f, -0.428864300251007f, 0.242619767785072f, -0.428667008876801f, + 0.242291063070297f, -0.428469479084015f, 0.241962507367134f, -0.428271710872650f, + 0.241634100675583f, -0.428073674440384f, 0.241305842995644f, -0.427875369787216f, + 0.240977749228477f, -0.427676826715469f, 0.240649804472923f, -0.427478045225143f, + 0.240322008728981f, -0.427278995513916f, 0.239994361996651f, -0.427079707384110f, + 0.239666879177094f, -0.426880151033401f, 0.239339530467987f, -0.426680356264114f, + 0.239012360572815f, -0.426480293273926f, 0.238685324788094f, -0.426279991865158f, + 0.238358452916145f, -0.426079452037811f, 0.238031730055809f, -0.425878643989563f, + 0.237705156207085f, -0.425677597522736f, 0.237378746271133f, -0.425476282835007f, + 0.237052485346794f, -0.425274729728699f, 0.236726388335228f, -0.425072938203812f, + 0.236400425434113f, -0.424870878458023f, 0.236074641346931f, -0.424668580293655f, + 0.235749006271362f, -0.424466013908386f, 0.235423520207405f, -0.424263238906860f, + 0.235098183155060f, -0.424060165882111f, 0.234773010015488f, -0.423856884241104f, + 0.234448000788689f, -0.423653304576874f, 0.234123140573502f, -0.423449516296387f, + 0.233798429369926f, -0.423245459794998f, 0.233473882079124f, -0.423041164875031f, + 0.233149498701096f, -0.422836631536484f, 0.232825264334679f, -0.422631829977036f, + 0.232501193881035f, -0.422426789999008f, 0.232177272439003f, -0.422221481800079f, + 0.231853514909744f, -0.422015935182571f, 0.231529906392097f, -0.421810150146484f, + 0.231206461787224f, -0.421604126691818f, 0.230883181095123f, -0.421397835016251f, + 0.230560049414635f, -0.421191304922104f, 0.230237081646919f, -0.420984506607056f, + 0.229914262890816f, -0.420777499675751f, 0.229591608047485f, -0.420570224523544f, + 0.229269117116928f, -0.420362681150436f, 0.228946775197983f, -0.420154929161072f, + 0.228624612092972f, -0.419946908950806f, 0.228302597999573f, -0.419738620519638f, + 0.227980732917786f, -0.419530123472214f, 0.227659046649933f, -0.419321358203888f, + 0.227337509393692f, -0.419112354516983f, 0.227016136050224f, -0.418903112411499f, + 0.226694911718369f, -0.418693602085114f, 0.226373866200447f, -0.418483853340149f, + 0.226052969694138f, -0.418273866176605f, 0.225732237100601f, -0.418063640594482f, + 0.225411668419838f, -0.417853146791458f, 0.225091263651848f, -0.417642414569855f, + 0.224771007895470f, -0.417431443929672f, 0.224450930953026f, -0.417220205068588f, + 0.224131003022194f, -0.417008757591248f, 0.223811239004135f, -0.416797041893005f, + 0.223491653800011f, -0.416585087776184f, 0.223172217607498f, -0.416372895240784f, + 0.222852945327759f, -0.416160434484482f, 0.222533836960793f, -0.415947735309601f, + 0.222214877605438f, -0.415734797716141f, 0.221896097064018f, -0.415521621704102f, + 0.221577480435371f, -0.415308207273483f, 0.221259027719498f, -0.415094524621964f, + 0.220940738916397f, -0.414880603551865f, 0.220622614026070f, -0.414666473865509f, + 0.220304638147354f, -0.414452046155930f, 0.219986841082573f, -0.414237409830093f, + 0.219669207930565f, -0.414022535085678f, 0.219351738691330f, -0.413807392120361f, + 0.219034433364868f, -0.413592010736465f, 0.218717306852341f, -0.413376390933990f, + 0.218400329351425f, -0.413160532712936f, 0.218083515763283f, -0.412944436073303f, + 0.217766880989075f, -0.412728071212769f, 0.217450410127640f, -0.412511497735977f, + 0.217134088277817f, -0.412294656038284f, 0.216817945241928f, -0.412077575922012f, + 0.216501981019974f, -0.411860257387161f, 0.216186165809631f, -0.411642700433731f, + 0.215870529413223f, -0.411424905061722f, 0.215555042028427f, -0.411206841468811f, + 0.215239733457565f, -0.410988569259644f, 0.214924603700638f, -0.410770028829575f, + 0.214609622955322f, -0.410551249980927f, 0.214294821023941f, -0.410332232713699f, + 0.213980183005333f, -0.410112977027893f, 0.213665723800659f, -0.409893482923508f, + 0.213351413607597f, -0.409673750400543f, 0.213037282228470f, -0.409453779459000f, + 0.212723329663277f, -0.409233570098877f, 0.212409526109695f, -0.409013092517853f, + 0.212095901370049f, -0.408792406320572f, 0.211782455444336f, -0.408571451902390f, + 0.211469158530235f, -0.408350288867950f, 0.211156040430069f, -0.408128857612610f, + 0.210843101143837f, -0.407907217741013f, 0.210530325770378f, -0.407685309648514f, + 0.210217714309692f, -0.407463163137436f, 0.209905281662941f, -0.407240778207779f, + 0.209593027830124f, -0.407018154859543f, 0.209280923008919f, -0.406795293092728f, + 0.208969011902809f, -0.406572192907333f, 0.208657249808311f, -0.406348884105682f, + 0.208345666527748f, -0.406125307083130f, 0.208034262061119f, -0.405901491641998f, + 0.207723021507263f, -0.405677437782288f, 0.207411959767342f, -0.405453115701675f, + 0.207101076841354f, -0.405228585004807f, 0.206790357828140f, -0.405003815889359f, + 0.206479802727699f, -0.404778808355331f, 0.206169426441193f, -0.404553562402725f, + 0.205859228968620f, -0.404328078031540f, 0.205549195408821f, -0.404102355241776f, + 0.205239340662956f, -0.403876423835754f, 0.204929664731026f, -0.403650224208832f, + 0.204620152711868f, -0.403423786163330f, 0.204310819506645f, -0.403197109699249f, + 0.204001650214195f, -0.402970194816589f, 0.203692659735680f, -0.402743041515350f, + 0.203383848071098f, -0.402515679597855f, 0.203075215220451f, -0.402288049459457f, + 0.202766746282578f, -0.402060180902481f, 0.202458456158638f, -0.401832103729248f, + 0.202150344848633f, -0.401603758335114f, 0.201842412352562f, -0.401375204324722f, + 0.201534643769264f, -0.401146411895752f, 0.201227053999901f, -0.400917351245880f, + 0.200919643044472f, -0.400688081979752f, 0.200612410902977f, -0.400458574295044f, + 0.200305357575417f, -0.400228828191757f, 0.199998468160629f, -0.399998843669891f, + 0.199691757559776f, -0.399768620729446f, 0.199385225772858f, -0.399538189172745f, + 0.199078872799873f, -0.399307489395142f, 0.198772698640823f, -0.399076581001282f, + 0.198466703295708f, -0.398845434188843f, 0.198160871863365f, -0.398614019155502f, + 0.197855234146118f, -0.398382395505905f, 0.197549775242805f, -0.398150533437729f, + 0.197244480252266f, -0.397918462753296f, 0.196939364075661f, -0.397686123847961f, + 0.196634441614151f, -0.397453576326370f, 0.196329683065414f, -0.397220760583878f, + 0.196025103330612f, -0.396987736225128f, 0.195720717310905f, -0.396754473447800f, + 0.195416495203972f, -0.396520972251892f, 0.195112451910973f, -0.396287262439728f, + 0.194808602333069f, -0.396053284406662f, 0.194504916667938f, -0.395819097757339f, + 0.194201424717903f, -0.395584672689438f, 0.193898096680641f, -0.395350009202957f, + 0.193594962358475f, -0.395115107297897f, 0.193292006850243f, -0.394879996776581f, + 0.192989215254784f, -0.394644618034363f, 0.192686617374420f, -0.394409030675888f, + 0.192384198307991f, -0.394173204898834f, 0.192081972956657f, -0.393937170505524f, + 0.191779911518097f, -0.393700867891312f, 0.191478043794632f, -0.393464356660843f, + 0.191176339983940f, -0.393227607011795f, 0.190874829888344f, -0.392990618944168f, + 0.190573498606682f, -0.392753422260284f, 0.190272361040115f, -0.392515957355499f, + 0.189971387386322f, -0.392278283834457f, 0.189670607447624f, -0.392040401697159f, + 0.189370006322861f, -0.391802251338959f, 0.189069598913193f, -0.391563892364502f, + 0.188769355416298f, -0.391325294971466f, 0.188469305634499f, -0.391086459159851f, + 0.188169434666634f, -0.390847414731979f, 0.187869757413864f, -0.390608131885529f, + 0.187570258975029f, -0.390368610620499f, 0.187270939350128f, -0.390128880739212f, + 0.186971798539162f, -0.389888882637024f, 0.186672851443291f, -0.389648675918579f, + 0.186374098062515f, -0.389408260583878f, 0.186075508594513f, -0.389167606830597f, + 0.185777112841606f, -0.388926714658737f, 0.185478910803795f, -0.388685584068298f, + 0.185180887579918f, -0.388444244861603f, 0.184883043169975f, -0.388202667236328f, + 0.184585392475128f, -0.387960851192474f, 0.184287920594215f, -0.387718826532364f, + 0.183990627527237f, -0.387476563453674f, 0.183693528175354f, -0.387234061956406f, + 0.183396622538567f, -0.386991351842880f, 0.183099895715714f, -0.386748403310776f, + 0.182803362607956f, -0.386505216360092f, 0.182507008314133f, -0.386261820793152f, + 0.182210832834244f, -0.386018186807632f, 0.181914865970612f, -0.385774344205856f, + 0.181619063019753f, -0.385530263185501f, 0.181323468685150f, -0.385285943746567f, + 0.181028053164482f, -0.385041415691376f, 0.180732816457748f, -0.384796649217606f, + 0.180437773466110f, -0.384551674127579f, 0.180142924189568f, -0.384306460618973f, + 0.179848253726959f, -0.384061008691788f, 0.179553776979446f, -0.383815348148346f, + 0.179259493947029f, -0.383569449186325f, 0.178965389728546f, -0.383323341608047f, + 0.178671479225159f, -0.383076995611191f, 0.178377762436867f, -0.382830440998077f, + 0.178084224462509f, -0.382583618164063f, 0.177790880203247f, -0.382336616516113f, + 0.177497729659081f, -0.382089376449585f, 0.177204772830009f, -0.381841897964478f, + 0.176911994814873f, -0.381594210863113f, 0.176619410514832f, -0.381346285343170f, + 0.176327019929886f, -0.381098151206970f, 0.176034808158875f, -0.380849778652191f, + 0.175742805004120f, -0.380601197481155f, 0.175450980663300f, -0.380352377891541f, + 0.175159350037575f, -0.380103349685669f, 0.174867913126946f, -0.379854083061218f, + 0.174576655030251f, -0.379604607820511f, 0.174285605549812f, -0.379354894161224f, + 0.173994734883308f, -0.379104942083359f, 0.173704057931900f, -0.378854811191559f, + 0.173413574695587f, -0.378604412078857f, 0.173123285174370f, -0.378353834152222f, + 0.172833189368248f, -0.378102988004684f, 0.172543287277222f, -0.377851963043213f, + 0.172253578901291f, -0.377600699663162f, 0.171964049339294f, -0.377349197864532f, + 0.171674728393555f, -0.377097487449646f, 0.171385586261749f, -0.376845568418503f, + 0.171096652746201f, -0.376593410968781f, 0.170807912945747f, -0.376341015100479f, + 0.170519351959229f, -0.376088410615921f, 0.170230999588966f, -0.375835597515106f, + 0.169942826032639f, -0.375582575798035f, 0.169654861092567f, -0.375329315662384f, + 0.169367074966431f, -0.375075817108154f, 0.169079497456551f, -0.374822109937668f, + 0.168792113661766f, -0.374568194150925f, 0.168504923582077f, -0.374314039945602f, + 0.168217927217484f, -0.374059677124023f, 0.167931124567986f, -0.373805105686188f, + 0.167644515633583f, -0.373550295829773f, 0.167358100414276f, -0.373295277357101f, + 0.167071878910065f, -0.373040050268173f, 0.166785866022110f, -0.372784584760666f, + 0.166500031948090f, -0.372528880834579f, 0.166214406490326f, -0.372272998094559f, + 0.165928974747658f, -0.372016876935959f, 0.165643751621246f, -0.371760547161102f, + 0.165358707308769f, -0.371503978967667f, 0.165073871612549f, -0.371247202157974f, + 0.164789214730263f, -0.370990216732025f, 0.164504766464233f, -0.370732992887497f, + 0.164220526814461f, -0.370475560426712f, 0.163936465978622f, -0.370217919349670f, + 0.163652613759041f, -0.369960039854050f, 0.163368955254555f, -0.369701951742172f, + 0.163085505366325f, -0.369443655014038f, 0.162802234292030f, -0.369185149669647f, + 0.162519171833992f, -0.368926405906677f, 0.162236317992210f, -0.368667453527451f, + 0.161953642964363f, -0.368408292531967f, 0.161671176552773f, -0.368148893117905f, + 0.161388918757439f, -0.367889285087585f, 0.161106839776039f, -0.367629468441010f, + 0.160824984312058f, -0.367369443178177f, 0.160543307662010f, -0.367109179496765f, + 0.160261839628220f, -0.366848707199097f, 0.159980565309525f, -0.366588026285172f, + 0.159699499607086f, -0.366327136754990f, 0.159418627619743f, -0.366066008806229f, + 0.159137964248657f, -0.365804702043533f, 0.158857494592667f, -0.365543156862259f, + 0.158577233552933f, -0.365281373262405f, 0.158297166228294f, -0.365019410848618f, + 0.158017292618752f, -0.364757210016251f, 0.157737627625465f, -0.364494800567627f, + 0.157458171248436f, -0.364232182502747f, 0.157178908586502f, -0.363969355821610f, + 0.156899839639664f, -0.363706320524216f, 0.156620979309082f, -0.363443046808243f, + 0.156342327594757f, -0.363179564476013f, 0.156063869595528f, -0.362915903329849f, + 0.155785620212555f, -0.362651973962784f, 0.155507579445839f, -0.362387865781784f, + 0.155229732394218f, -0.362123548984528f, 0.154952079057693f, -0.361858993768692f, + 0.154674649238586f, -0.361594229936600f, 0.154397398233414f, -0.361329287290573f, + 0.154120370745659f, -0.361064106225967f, 0.153843536973000f, -0.360798716545105f, + 0.153566911816597f, -0.360533088445663f, 0.153290495276451f, -0.360267281532288f, + 0.153014272451401f, -0.360001266002655f, 0.152738258242607f, -0.359735012054443f, + 0.152462437748909f, -0.359468549489975f, 0.152186840772629f, -0.359201908111572f, + 0.151911437511444f, -0.358935028314590f, 0.151636242866516f, -0.358667939901352f, + 0.151361241936684f, -0.358400642871857f, 0.151086464524269f, -0.358133137226105f, + 0.150811880826950f, -0.357865422964096f, 0.150537505745888f, -0.357597470283508f, + 0.150263324379921f, -0.357329338788986f, 0.149989366531372f, -0.357060998678207f, + 0.149715602397919f, -0.356792420148849f, 0.149442046880722f, -0.356523662805557f, + 0.149168699979782f, -0.356254696846008f, 0.148895561695099f, -0.355985492467880f, + 0.148622632026672f, -0.355716109275818f, 0.148349896073341f, -0.355446487665176f, + 0.148077383637428f, -0.355176687240601f, 0.147805064916611f, -0.354906648397446f, + 0.147532954812050f, -0.354636400938034f, 0.147261068224907f, -0.354365974664688f, + 0.146989375352860f, -0.354095309972763f, 0.146717891097069f, -0.353824466466904f, + 0.146446615457535f, -0.353553384542465f, 0.146175548434258f, -0.353282123804092f, + 0.145904675126076f, -0.353010624647141f, 0.145634025335312f, -0.352738946676254f, + 0.145363584160805f, -0.352467030286789f, 0.145093351602554f, -0.352194935083389f, + 0.144823327660561f, -0.351922631263733f, 0.144553512334824f, -0.351650089025497f, + 0.144283905625343f, -0.351377367973328f, 0.144014507532120f, -0.351104438304901f, + 0.143745318055153f, -0.350831300020218f, 0.143476337194443f, -0.350557953119278f, + 0.143207564949989f, -0.350284397602081f, 0.142939001321793f, -0.350010633468628f, + 0.142670661211014f, -0.349736660718918f, 0.142402514815331f, -0.349462509155273f, + 0.142134591937065f, -0.349188119173050f, 0.141866862773895f, -0.348913550376892f, + 0.141599357128143f, -0.348638743162155f, 0.141332060098648f, -0.348363757133484f, + 0.141064971685410f, -0.348088562488556f, 0.140798106789589f, -0.347813159227371f, + 0.140531435608864f, -0.347537547349930f, 0.140264987945557f, -0.347261756658554f, + 0.139998748898506f, -0.346985727548599f, 0.139732718467712f, -0.346709519624710f, + 0.139466896653175f, -0.346433073282242f, 0.139201298356056f, -0.346156448125839f, + 0.138935908675194f, -0.345879614353180f, 0.138670727610588f, -0.345602601766586f, + 0.138405755162239f, -0.345325350761414f, 0.138141006231308f, -0.345047920942307f, + 0.137876465916634f, -0.344770282506943f, 0.137612134218216f, -0.344492435455322f, + 0.137348011136055f, -0.344214379787445f, 0.137084111571312f, -0.343936115503311f, + 0.136820420622826f, -0.343657672405243f, 0.136556953191757f, -0.343379020690918f, + 0.136293679475784f, -0.343100160360336f, 0.136030644178391f, -0.342821091413498f, + 0.135767802596092f, -0.342541843652725f, 0.135505184531212f, -0.342262357473373f, + 0.135242775082588f, -0.341982692480087f, 0.134980589151382f, -0.341702848672867f, + 0.134718611836433f, -0.341422766447067f, 0.134456858038902f, -0.341142505407333f, + 0.134195312857628f, -0.340862035751343f, 0.133933976292610f, -0.340581357479095f, + 0.133672863245010f, -0.340300500392914f, 0.133411958813667f, -0.340019434690475f, + 0.133151277899742f, -0.339738160371780f, 0.132890805602074f, -0.339456677436829f, + 0.132630556821823f, -0.339175015687943f, 0.132370531558990f, -0.338893145322800f, + 0.132110700011253f, -0.338611096143723f, 0.131851106882095f, -0.338328808546066f, + 0.131591722369194f, -0.338046342134476f, 0.131332546472549f, -0.337763696908951f, + 0.131073594093323f, -0.337480813264847f, 0.130814850330353f, -0.337197750806808f, + 0.130556344985962f, -0.336914509534836f, 0.130298033356667f, -0.336631029844284f, + 0.130039945244789f, -0.336347371339798f, 0.129782080650330f, -0.336063534021378f, + 0.129524439573288f, -0.335779488086700f, 0.129267007112503f, -0.335495233535767f, + 0.129009798169136f, -0.335210770368576f, 0.128752797842026f, -0.334926128387451f, + 0.128496021032333f, -0.334641307592392f, 0.128239467740059f, -0.334356248378754f, + 0.127983123064041f, -0.334071010351181f, 0.127727001905441f, -0.333785593509674f, + 0.127471104264259f, -0.333499968051910f, 0.127215430140495f, -0.333214133977890f, + 0.126959964632988f, -0.332928121089935f, 0.126704722642899f, -0.332641899585724f, + 0.126449704170227f, -0.332355499267578f, 0.126194894313812f, -0.332068890333176f, + 0.125940307974815f, -0.331782072782516f, 0.125685945153236f, -0.331495076417923f, + 0.125431805849075f, -0.331207901239395f, 0.125177875161171f, -0.330920487642288f, + 0.124924175441265f, -0.330632925033569f, 0.124670691788197f, -0.330345153808594f, + 0.124417431652546f, -0.330057173967361f, 0.124164395034313f, -0.329769015312195f, + 0.123911574482918f, -0.329480648040771f, 0.123658977448940f, -0.329192101955414f, + 0.123406603932381f, -0.328903347253799f, 0.123154446482658f, -0.328614413738251f, + 0.122902512550354f, -0.328325271606445f, 0.122650802135468f, -0.328035950660706f, + 0.122399315237999f, -0.327746421098709f, 0.122148044407368f, -0.327456712722778f, + 0.121896997094154f, -0.327166795730591f, 0.121646173298359f, -0.326876699924469f, + 0.121395580470562f, -0.326586425304413f, 0.121145196259022f, -0.326295942068100f, + 0.120895043015480f, -0.326005280017853f, 0.120645113289356f, -0.325714409351349f, + 0.120395407080650f, -0.325423330068588f, 0.120145916938782f, -0.325132101774216f, + 0.119896657764912f, -0.324840664863586f, 0.119647622108459f, -0.324549019336700f, + 0.119398809969425f, -0.324257194995880f, 0.119150213897228f, -0.323965191841125f, + 0.118901848793030f, -0.323672980070114f, 0.118653707206249f, -0.323380589485168f, + 0.118405789136887f, -0.323088020086288f, 0.118158094584942f, -0.322795242071152f, + 0.117910631000996f, -0.322502255439758f, 0.117663383483887f, -0.322209119796753f, + 0.117416366934776f, -0.321915775537491f, 0.117169573903084f, -0.321622252464294f, + 0.116923004388809f, -0.321328520774841f, 0.116676658391953f, -0.321034610271454f, + 0.116430543363094f, -0.320740520954132f, 0.116184651851654f, -0.320446223020554f, + 0.115938983857632f, -0.320151746273041f, 0.115693546831608f, -0.319857090711594f, + 0.115448333323002f, -0.319562226533890f, 0.115203343331814f, -0.319267183542252f, + 0.114958584308624f, -0.318971961736679f, 0.114714048802853f, -0.318676531314850f, + 0.114469736814499f, -0.318380922079086f, 0.114225655794144f, -0.318085134029388f, + 0.113981798291206f, -0.317789167165756f, 0.113738171756268f, -0.317492991685867f, + 0.113494776189327f, -0.317196637392044f, 0.113251596689224f, -0.316900104284287f, + 0.113008655607700f, -0.316603392362595f, 0.112765938043594f, -0.316306471824646f, + 0.112523443996906f, -0.316009372472763f, 0.112281180918217f, -0.315712094306946f, + 0.112039148807526f, -0.315414607524872f, 0.111797347664833f, -0.315116971731186f, + 0.111555770039558f, -0.314819127321243f, 0.111314415931702f, -0.314521104097366f, + 0.111073300242424f, -0.314222872257233f, 0.110832408070564f, -0.313924491405487f, + 0.110591746866703f, -0.313625901937485f, 0.110351309180260f, -0.313327133655548f, + 0.110111102461815f, -0.313028186559677f, 0.109871134161949f, -0.312729060649872f, + 0.109631389379501f, -0.312429755926132f, 0.109391868114471f, -0.312130242586136f, + 0.109152585268021f, -0.311830550432205f, 0.108913525938988f, -0.311530679464340f, + 0.108674705028534f, -0.311230629682541f, 0.108436107635498f, -0.310930401086807f, + 0.108197741210461f, -0.310629993677139f, 0.107959605753422f, -0.310329377651215f, + 0.107721701264381f, -0.310028612613678f, 0.107484027743340f, -0.309727638959885f, + 0.107246585190296f, -0.309426486492157f, 0.107009373605251f, -0.309125155210495f, + 0.106772392988205f, -0.308823645114899f, 0.106535643339157f, -0.308521956205368f, + 0.106299124658108f, -0.308220088481903f, 0.106062836945057f, -0.307918041944504f, + 0.105826787650585f, -0.307615786790848f, 0.105590961873531f, -0.307313382625580f, + 0.105355374515057f, -0.307010769844055f, 0.105120018124580f, -0.306708008050919f, + 0.104884892702103f, -0.306405037641525f, 0.104649998247623f, -0.306101888418198f, + 0.104415334761143f, -0.305798590183258f, 0.104180909693241f, -0.305495083332062f, + 0.103946708142757f, -0.305191397666931f, 0.103712752461433f, -0.304887533187866f, + 0.103479020297527f, -0.304583519697189f, 0.103245526552200f, -0.304279297590256f, + 0.103012263774872f, -0.303974896669388f, 0.102779231965542f, -0.303670316934586f, + 0.102546438574791f, -0.303365558385849f, 0.102313876152039f, -0.303060621023178f, + 0.102081544697285f, -0.302755534648895f, 0.101849451661110f, -0.302450239658356f, + 0.101617597043514f, -0.302144765853882f, 0.101385973393917f, -0.301839113235474f, + 0.101154580712318f, -0.301533311605453f, 0.100923426449299f, -0.301227301359177f, + 0.100692503154278f, -0.300921112298965f, 0.100461818277836f, -0.300614774227142f, + 0.100231364369392f, -0.300308227539063f, 0.100001148879528f, -0.300001531839371f, + 0.099771171808243f, -0.299694657325745f, 0.099541425704956f, -0.299387603998184f, + 0.099311910569668f, -0.299080342054367f, 0.099082641303539f, -0.298772931098938f, + 0.098853603005409f, -0.298465341329575f, 0.098624803125858f, -0.298157602548599f, + 0.098396234214306f, -0.297849655151367f, 0.098167903721333f, -0.297541528940201f, + 0.097939811646938f, -0.297233253717422f, 0.097711957991123f, -0.296924799680710f, + 0.097484335303307f, -0.296616137027740f, 0.097256951034069f, -0.296307325363159f, + 0.097029805183411f, -0.295998334884644f, 0.096802897751331f, -0.295689195394516f, + 0.096576221287251f, -0.295379847288132f, 0.096349790692329f, -0.295070350170136f, + 0.096123591065407f, -0.294760644435883f, 0.095897629857063f, -0.294450789690018f, + 0.095671907067299f, -0.294140785932541f, 0.095446422696114f, -0.293830573558807f, + 0.095221176743507f, -0.293520182371140f, 0.094996169209480f, -0.293209642171860f, + 0.094771400094032f, -0.292898923158646f, 0.094546869397163f, -0.292588025331497f, + 0.094322577118874f, -0.292276978492737f, 0.094098523259163f, -0.291965723037720f, + 0.093874707818031f, -0.291654318571091f, 0.093651130795479f, -0.291342735290527f, + 0.093427792191505f, -0.291031002998352f, 0.093204692006111f, -0.290719062089920f, + 0.092981837689877f, -0.290406972169876f, 0.092759214341640f, -0.290094703435898f, + 0.092536836862564f, -0.289782285690308f, 0.092314697802067f, -0.289469659328461f, + 0.092092797160149f, -0.289156883955002f, 0.091871134936810f, -0.288843959569931f, + 0.091649711132050f, -0.288530826568604f, 0.091428533196449f, -0.288217544555664f, + 0.091207593679428f, -0.287904083728790f, 0.090986892580986f, -0.287590473890305f, + 0.090766437351704f, -0.287276685237885f, 0.090546220541000f, -0.286962717771530f, + 0.090326242148876f, -0.286648571491241f, 0.090106502175331f, -0.286334276199341f, + 0.089887008070946f, -0.286019802093506f, 0.089667752385139f, -0.285705178976059f, + 0.089448742568493f, -0.285390377044678f, 0.089229971170425f, -0.285075396299362f, + 0.089011445641518f, -0.284760266542435f, 0.088793158531189f, -0.284444957971573f, + 0.088575109839439f, -0.284129470586777f, 0.088357307016850f, -0.283813834190369f, + 0.088139742612839f, -0.283498018980026f, 0.087922424077988f, -0.283182054758072f, + 0.087705351412296f, -0.282865911722183f, 0.087488517165184f, -0.282549589872360f, + 0.087271921336651f, -0.282233119010925f, 0.087055571377277f, -0.281916469335556f, + 0.086839467287064f, -0.281599670648575f, 0.086623609066010f, -0.281282693147659f, + 0.086407989263535f, -0.280965566635132f, 0.086192607879639f, -0.280648261308670f, + 0.085977479815483f, -0.280330777168274f, 0.085762590169907f, -0.280013144016266f, + 0.085547938942909f, -0.279695361852646f, 0.085333541035652f, -0.279377400875092f, + 0.085119381546974f, -0.279059261083603f, 0.084905467927456f, -0.278740972280502f, + 0.084691800177097f, -0.278422504663467f, 0.084478378295898f, -0.278103888034821f, + 0.084265194833279f, -0.277785122394562f, 0.084052257239819f, -0.277466177940369f, + 0.083839565515518f, -0.277147054672241f, 0.083627119660378f, -0.276827782392502f, + 0.083414919674397f, -0.276508361101151f, 0.083202958106995f, -0.276188760995865f, + 0.082991249859333f, -0.275868982076645f, 0.082779780030251f, -0.275549083948135f, + 0.082568563520908f, -0.275228977203369f, 0.082357585430145f, -0.274908751249313f, + 0.082146860659122f, -0.274588316679001f, 0.081936374306679f, -0.274267762899399f, + 0.081726133823395f, -0.273947030305862f, 0.081516146659851f, -0.273626148700714f, + 0.081306397914886f, -0.273305088281631f, 0.081096902489662f, -0.272983878850937f, + 0.080887645483017f, -0.272662490606308f, 0.080678641796112f, -0.272340953350067f, + 0.080469883978367f, -0.272019267082214f, 0.080261372029781f, -0.271697402000427f, + 0.080053105950356f, -0.271375387907028f, 0.079845085740089f, -0.271053224802017f, + 0.079637311398983f, -0.270730882883072f, 0.079429790377617f, -0.270408391952515f, + 0.079222507774830f, -0.270085722208023f, 0.079015478491783f, -0.269762933254242f, + 0.078808702528477f, -0.269439965486526f, 0.078602164983749f, -0.269116818904877f, + 0.078395880758762f, -0.268793523311615f, 0.078189842402935f, -0.268470078706741f, + 0.077984049916267f, -0.268146485090256f, 0.077778510749340f, -0.267822742462158f, + 0.077573217451572f, -0.267498821020126f, 0.077368170022964f, -0.267174720764160f, + 0.077163375914097f, -0.266850501298904f, 0.076958827674389f, -0.266526103019714f, + 0.076754532754421f, -0.266201555728912f, 0.076550483703613f, -0.265876859426498f, + 0.076346680521965f, -0.265552014112473f, 0.076143130660057f, -0.265226989984512f, + 0.075939826667309f, -0.264901816844940f, 0.075736775994301f, -0.264576494693756f, + 0.075533971190453f, -0.264250993728638f, 0.075331419706345f, -0.263925373554230f, + 0.075129114091396f, -0.263599574565887f, 0.074927061796188f, -0.263273626565933f, + 0.074725262820721f, -0.262947499752045f, 0.074523709714413f, -0.262621253728867f, + 0.074322402477264f, -0.262294828891754f, 0.074121348559856f, -0.261968284845352f, + 0.073920547962189f, -0.261641561985016f, 0.073720000684261f, -0.261314690113068f, + 0.073519699275494f, -0.260987639427185f, 0.073319651186466f, -0.260660469532013f, + 0.073119848966599f, -0.260333120822906f, 0.072920300066471f, -0.260005623102188f, + 0.072721004486084f, -0.259678006172180f, 0.072521962225437f, -0.259350210428238f, + 0.072323165833950f, -0.259022265672684f, 0.072124622762203f, -0.258694142103195f, + 0.071926333010197f, -0.258365899324417f, 0.071728296577930f, -0.258037507534027f, + 0.071530513465405f, -0.257708936929703f, 0.071332976222038f, -0.257380217313766f, + 0.071135692298412f, -0.257051378488541f, 0.070938661694527f, -0.256722360849380f, + 0.070741884410381f, -0.256393194198608f, 0.070545360445976f, -0.256063878536224f, + 0.070349089801311f, -0.255734413862228f, 0.070153072476387f, -0.255404800176620f, + 0.069957308471203f, -0.255075037479401f, 0.069761790335178f, -0.254745125770569f, + 0.069566532969475f, -0.254415065050125f, 0.069371521472931f, -0.254084855318069f, + 0.069176770746708f, -0.253754496574402f, 0.068982265889645f, -0.253423988819122f, + 0.068788021802902f, -0.253093332052231f, 0.068594031035900f, -0.252762526273727f, + 0.068400286138058f, -0.252431541681290f, 0.068206802010536f, -0.252100437879562f, + 0.068013571202755f, -0.251769185066223f, 0.067820593714714f, -0.251437783241272f, + 0.067627869546413f, -0.251106232404709f, 0.067435398697853f, -0.250774532556534f, + 0.067243188619614f, -0.250442683696747f, 0.067051224410534f, -0.250110685825348f, + 0.066859520971775f, -0.249778553843498f, 0.066668070852757f, -0.249446272850037f, + 0.066476874053478f, -0.249113827943802f, 0.066285938024521f, -0.248781248927116f, + 0.066095255315304f, -0.248448520898819f, 0.065904818475246f, -0.248115643858910f, + 0.065714649856091f, -0.247782632708550f, 0.065524727106094f, -0.247449472546577f, + 0.065335065126419f, -0.247116148471832f, 0.065145656466484f, -0.246782705187798f, + 0.064956501126289f, -0.246449097990990f, 0.064767606556416f, -0.246115356683731f, + 0.064578965306282f, -0.245781451463699f, 0.064390584826469f, -0.245447427034378f, + 0.064202457666397f, -0.245113238692284f, 0.064014583826065f, -0.244778916239738f, + 0.063826970756054f, -0.244444444775581f, 0.063639611005783f, -0.244109839200974f, + 0.063452512025833f, -0.243775084614754f, 0.063265666365623f, -0.243440181016922f, + 0.063079081475735f, -0.243105143308640f, 0.062892749905586f, -0.242769956588745f, + 0.062706671655178f, -0.242434620857239f, 0.062520854175091f, -0.242099151015282f, + 0.062335297465324f, -0.241763532161713f, 0.062149997800589f, -0.241427779197693f, + 0.061964951455593f, -0.241091892123222f, 0.061780165880919f, -0.240755841135979f, + 0.061595637351274f, -0.240419670939446f, 0.061411365866661f, -0.240083336830139f, + 0.061227355152369f, -0.239746883511543f, 0.061043601483107f, -0.239410281181335f, + 0.060860104858875f, -0.239073529839516f, 0.060676865279675f, -0.238736644387245f, + 0.060493886470795f, -0.238399609923363f, 0.060311164706945f, -0.238062441349030f, + 0.060128703713417f, -0.237725138664246f, 0.059946499764919f, -0.237387686967850f, + 0.059764556586742f, -0.237050101161003f, 0.059582870453596f, -0.236712381243706f, + 0.059401445090771f, -0.236374512314796f, 0.059220276772976f, -0.236036509275436f, + 0.059039369225502f, -0.235698372125626f, 0.058858718723059f, -0.235360085964203f, + 0.058678328990936f, -0.235021665692329f, 0.058498200029135f, -0.234683111310005f, + 0.058318331837654f, -0.234344407916069f, 0.058138720691204f, -0.234005570411682f, + 0.057959370315075f, -0.233666598796844f, 0.057780280709267f, -0.233327493071556f, + 0.057601451873779f, -0.232988253235817f, 0.057422880083323f, -0.232648864388466f, + 0.057244572788477f, -0.232309341430664f, 0.057066522538662f, -0.231969684362412f, + 0.056888736784458f, -0.231629893183708f, 0.056711208075285f, -0.231289967894554f, + 0.056533940136433f, -0.230949893593788f, 0.056356932967901f, -0.230609700083733f, + 0.056180190294981f, -0.230269357562065f, 0.056003704667091f, -0.229928880929947f, + 0.055827483534813f, -0.229588270187378f, 0.055651523172855f, -0.229247525334358f, + 0.055475823581219f, -0.228906646370888f, 0.055300384759903f, -0.228565633296967f, + 0.055125206708908f, -0.228224486112595f, 0.054950293153524f, -0.227883204817772f, + 0.054775636643171f, -0.227541789412498f, 0.054601248353720f, -0.227200239896774f, + 0.054427117109299f, -0.226858556270599f, 0.054253250360489f, -0.226516738533974f, + 0.054079644382000f, -0.226174786686897f, 0.053906302899122f, -0.225832715630531f, + 0.053733222186565f, -0.225490495562553f, 0.053560405969620f, -0.225148141384125f, + 0.053387850522995f, -0.224805667996407f, 0.053215555846691f, -0.224463045597076f, + 0.053043525665998f, -0.224120303988457f, 0.052871759980917f, -0.223777428269386f, + 0.052700258791447f, -0.223434418439865f, 0.052529018372297f, -0.223091274499893f, + 0.052358038723469f, -0.222748011350632f, 0.052187327295542f, -0.222404599189758f, + 0.052016876637936f, -0.222061067819595f, 0.051846686750650f, -0.221717402338982f, + 0.051676765084267f, -0.221373617649078f, 0.051507104188204f, -0.221029683947563f, + 0.051337707787752f, -0.220685631036758f, 0.051168579608202f, -0.220341444015503f, + 0.050999708473682f, -0.219997137784958f, 0.050831105560064f, -0.219652697443962f, + 0.050662767142057f, -0.219308122992516f, 0.050494693219662f, -0.218963414430618f, + 0.050326880067587f, -0.218618586659431f, 0.050159335136414f, -0.218273624777794f, + 0.049992054700851f, -0.217928543686867f, 0.049825038760900f, -0.217583328485489f, + 0.049658283591270f, -0.217237979173660f, 0.049491796642542f, -0.216892510652542f, + 0.049325577914715f, -0.216546908020973f, 0.049159619957209f, -0.216201186180115f, + 0.048993926495314f, -0.215855330228806f, 0.048828501254320f, -0.215509355068207f, + 0.048663340508938f, -0.215163245797157f, 0.048498444259167f, -0.214817002415657f, + 0.048333816230297f, -0.214470639824867f, 0.048169452697039f, -0.214124158024788f, + 0.048005353659391f, -0.213777542114258f, 0.047841522842646f, -0.213430806994438f, + 0.047677956521511f, -0.213083937764168f, 0.047514654695988f, -0.212736949324608f, + 0.047351621091366f, -0.212389841675758f, 0.047188851982355f, -0.212042599916458f, + 0.047026351094246f, -0.211695238947868f, 0.046864114701748f, -0.211347743868828f, + 0.046702146530151f, -0.211000129580498f, 0.046540446579456f, -0.210652396082878f, + 0.046379011124372f, -0.210304543375969f, 0.046217843890190f, -0.209956556558609f, + 0.046056941151619f, -0.209608450531960f, 0.045896306633949f, -0.209260210394859f, + 0.045735940337181f, -0.208911851048470f, 0.045575842261314f, -0.208563387393951f, + 0.045416008681059f, -0.208214774727821f, 0.045256443321705f, -0.207866057753563f, + 0.045097146183252f, -0.207517206668854f, 0.044938117265701f, -0.207168251276016f, + 0.044779352843761f, -0.206819161772728f, 0.044620860368013f, -0.206469938158989f, + 0.044462632387877f, -0.206120610237122f, 0.044304672628641f, -0.205771163105965f, + 0.044146984815598f, -0.205421581864357f, 0.043989561498165f, -0.205071896314621f, + 0.043832406401634f, -0.204722076654434f, 0.043675523251295f, -0.204372137784958f, + 0.043518904596567f, -0.204022079706192f, 0.043362557888031f, -0.203671902418137f, + 0.043206475675106f, -0.203321605920792f, 0.043050665408373f, -0.202971190214157f, + 0.042895123362541f, -0.202620655298233f, 0.042739849537611f, -0.202270001173019f, + 0.042584843933582f, -0.201919227838516f, 0.042430106550455f, -0.201568335294724f, + 0.042275641113520f, -0.201217323541641f, 0.042121443897486f, -0.200866192579269f, + 0.041967518627644f, -0.200514942407608f, 0.041813857853413f, -0.200163587927818f, + 0.041660469025373f, -0.199812099337578f, 0.041507352143526f, -0.199460506439209f, + 0.041354499757290f, -0.199108779430389f, 0.041201923042536f, -0.198756948113441f, + 0.041049610823393f, -0.198404997587204f, 0.040897574275732f, -0.198052927851677f, + 0.040745802223682f, -0.197700738906860f, 0.040594302117825f, -0.197348430752754f, + 0.040443073958158f, -0.196996018290520f, 0.040292114019394f, -0.196643486618996f, + 0.040141426026821f, -0.196290835738182f, 0.039991009980440f, -0.195938065648079f, + 0.039840862154961f, -0.195585191249847f, 0.039690986275673f, -0.195232197642326f, + 0.039541378617287f, -0.194879084825516f, 0.039392042905092f, -0.194525867700577f, + 0.039242979139090f, -0.194172516465187f, 0.039094187319279f, -0.193819075822830f, + 0.038945667445660f, -0.193465501070023f, 0.038797415792942f, -0.193111822009087f, + 0.038649436086416f, -0.192758023738861f, 0.038501728326082f, -0.192404121160507f, + 0.038354292511940f, -0.192050099372864f, 0.038207128643990f, -0.191695958375931f, + 0.038060232996941f, -0.191341713070869f, 0.037913613021374f, -0.190987363457680f, + 0.037767261266708f, -0.190632879734039f, 0.037621185183525f, -0.190278306603432f, + 0.037475381046534f, -0.189923599362373f, 0.037329845130444f, -0.189568802714348f, + 0.037184584885836f, -0.189213871955872f, 0.037039596587420f, -0.188858851790428f, + 0.036894880235195f, -0.188503712415695f, 0.036750435829163f, -0.188148453831673f, + 0.036606263369322f, -0.187793090939522f, 0.036462362855673f, -0.187437608838081f, + 0.036318738013506f, -0.187082037329674f, 0.036175385117531f, -0.186726331710815f, + 0.036032304167747f, -0.186370536684990f, 0.035889495164156f, -0.186014622449875f, + 0.035746958106756f, -0.185658603906631f, 0.035604696720839f, -0.185302466154099f, + 0.035462711006403f, -0.184946224093437f, 0.035320993512869f, -0.184589877724648f, + 0.035179551690817f, -0.184233412146568f, 0.035038381814957f, -0.183876842260361f, + 0.034897487610579f, -0.183520168066025f, 0.034756865352392f, -0.183163389563560f, + 0.034616518765688f, -0.182806491851807f, 0.034476444125175f, -0.182449504733086f, + 0.034336645156145f, -0.182092398405075f, 0.034197118133307f, -0.181735187768936f, + 0.034057866781950f, -0.181377857923508f, 0.033918887376785f, -0.181020438671112f, + 0.033780183643103f, -0.180662900209427f, 0.033641755580902f, -0.180305257439613f, + 0.033503599464893f, -0.179947525262833f, 0.033365719020367f, -0.179589673876762f, + 0.033228114247322f, -0.179231703281403f, 0.033090781420469f, -0.178873643279076f, + 0.032953724265099f, -0.178515478968620f, 0.032816942781210f, -0.178157210350037f, + 0.032680433243513f, -0.177798837423325f, 0.032544203102589f, -0.177440345287323f, + 0.032408244907856f, -0.177081763744354f, 0.032272562384605f, -0.176723077893257f, + 0.032137155532837f, -0.176364272832870f, 0.032002024352551f, -0.176005378365517f, + 0.031867165118456f, -0.175646379590034f, 0.031732585281134f, -0.175287276506424f, + 0.031598277390003f, -0.174928069114685f, 0.031464248895645f, -0.174568757414818f, + 0.031330492347479f, -0.174209341406822f, 0.031197015196085f, -0.173849821090698f, + 0.031063811853528f, -0.173490211367607f, 0.030930884182453f, -0.173130482435226f, + 0.030798232182860f, -0.172770664095879f, 0.030665857717395f, -0.172410741448402f, + 0.030533758923411f, -0.172050714492798f, 0.030401935800910f, -0.171690583229065f, + 0.030270388349891f, -0.171330362558365f, 0.030139118432999f, -0.170970037579536f, + 0.030008124187589f, -0.170609608292580f, 0.029877405613661f, -0.170249074697495f, + 0.029746964573860f, -0.169888436794281f, 0.029616801068187f, -0.169527709484100f, + 0.029486913233995f, -0.169166877865791f, 0.029357301071286f, -0.168805956840515f, + 0.029227968305349f, -0.168444931507111f, 0.029098909348249f, -0.168083801865578f, + 0.028970129787922f, -0.167722567915916f, 0.028841627761722f, -0.167361244559288f, + 0.028713401407003f, -0.166999831795692f, 0.028585452586412f, -0.166638299822807f, + 0.028457781299949f, -0.166276678442955f, 0.028330387547612f, -0.165914967656136f, + 0.028203271329403f, -0.165553152561188f, 0.028076432645321f, -0.165191248059273f, + 0.027949871495366f, -0.164829224348068f, 0.027823587879539f, -0.164467126131058f, + 0.027697581797838f, -0.164104923605919f, 0.027571853250265f, -0.163742616772652f, + 0.027446404099464f, -0.163380220532417f, 0.027321230620146f, -0.163017734885216f, + 0.027196336537600f, -0.162655144929886f, 0.027071721851826f, -0.162292465567589f, + 0.026947384700179f, -0.161929681897163f, 0.026823325082660f, -0.161566808819771f, + 0.026699542999268f, -0.161203846335411f, 0.026576040312648f, -0.160840779542923f, + 0.026452817022800f, -0.160477623343468f, 0.026329871267080f, -0.160114362835884f, + 0.026207204908133f, -0.159751012921333f, 0.026084816083312f, -0.159387573599815f, + 0.025962706655264f, -0.159024044871330f, 0.025840876623988f, -0.158660411834717f, + 0.025719324126840f, -0.158296689391136f, 0.025598052889109f, -0.157932877540588f, + 0.025477059185505f, -0.157568961381912f, 0.025356344878674f, -0.157204970717430f, + 0.025235909968615f, -0.156840875744820f, 0.025115754455328f, -0.156476691365242f, + 0.024995878338814f, -0.156112402677536f, 0.024876279756427f, -0.155748039484024f, + 0.024756962433457f, -0.155383571982384f, 0.024637924507260f, -0.155019029974937f, + 0.024519165977836f, -0.154654383659363f, 0.024400688707829f, -0.154289647936821f, + 0.024282488971949f, -0.153924822807312f, 0.024164570495486f, -0.153559908270836f, + 0.024046931415796f, -0.153194904327393f, 0.023929571732879f, -0.152829796075821f, + 0.023812493309379f, -0.152464613318443f, 0.023695694282651f, -0.152099341154099f, + 0.023579176515341f, -0.151733979582787f, 0.023462938144803f, -0.151368513703346f, + 0.023346979171038f, -0.151002973318100f, 0.023231301456690f, -0.150637343525887f, + 0.023115905001760f, -0.150271624326706f, 0.023000787943602f, -0.149905815720558f, + 0.022885952144861f, -0.149539917707443f, 0.022771397605538f, -0.149173930287361f, + 0.022657122462988f, -0.148807853460312f, 0.022543128579855f, -0.148441687226295f, + 0.022429415956140f, -0.148075446486473f, 0.022315984591842f, -0.147709101438522f, + 0.022202832624316f, -0.147342681884766f, 0.022089963778853f, -0.146976172924042f, + 0.021977374330163f, -0.146609574556351f, 0.021865066140890f, -0.146242901682854f, + 0.021753041073680f, -0.145876124501228f, 0.021641295403242f, -0.145509272813797f, + 0.021529832854867f, -0.145142331719399f, 0.021418649703264f, -0.144775316119194f, + 0.021307749673724f, -0.144408211112022f, 0.021197130903602f, -0.144041016697884f, + 0.021086793392897f, -0.143673732876778f, 0.020976737141609f, -0.143306359648705f, + 0.020866964012384f, -0.142938911914825f, 0.020757472142577f, -0.142571389675140f, + 0.020648263394833f, -0.142203763127327f, 0.020539334043860f, -0.141836062073708f, + 0.020430689677596f, -0.141468286514282f, 0.020322324708104f, -0.141100421547890f, + 0.020214242860675f, -0.140732467174530f, 0.020106444135308f, -0.140364438295364f, + 0.019998926669359f, -0.139996320009232f, 0.019891692325473f, -0.139628127217293f, + 0.019784741103649f, -0.139259845018387f, 0.019678071141243f, -0.138891488313675f, + 0.019571684300900f, -0.138523042201996f, 0.019465578719974f, -0.138154521584511f, + 0.019359756261110f, -0.137785911560059f, 0.019254218786955f, -0.137417227029800f, + 0.019148962572217f, -0.137048453092575f, 0.019043987616897f, -0.136679604649544f, + 0.018939297646284f, -0.136310681700706f, 0.018834890797734f, -0.135941669344902f, + 0.018730765208602f, -0.135572582483292f, 0.018626924604177f, -0.135203406214714f, + 0.018523367121816f, -0.134834155440331f, 0.018420090898871f, -0.134464830160141f, + 0.018317099660635f, -0.134095430374146f, 0.018214391544461f, -0.133725941181183f, + 0.018111966550350f, -0.133356377482414f, 0.018009826540947f, -0.132986739277840f, + 0.017907967790961f, -0.132617011666298f, 0.017806394025683f, -0.132247209548950f, + 0.017705103382468f, -0.131877332925797f, 0.017604095861316f, -0.131507381796837f, + 0.017503373324871f, -0.131137356162071f, 0.017402933910489f, -0.130767241120338f, + 0.017302779480815f, -0.130397051572800f, 0.017202908173203f, -0.130026802420616f, + 0.017103319987655f, -0.129656463861465f, 0.017004016786814f, -0.129286035895348f, + 0.016904998570681f, -0.128915548324585f, 0.016806263476610f, -0.128544986248016f, + 0.016707813367248f, -0.128174334764481f, 0.016609646379948f, -0.127803623676300f, + 0.016511764377356f, -0.127432823181152f, 0.016414167359471f, -0.127061963081360f, + 0.016316853463650f, -0.126691013574600f, 0.016219824552536f, -0.126320004463196f, + 0.016123080626130f, -0.125948905944824f, 0.016026621684432f, -0.125577747821808f, + 0.015930447727442f, -0.125206500291824f, 0.015834558755159f, -0.124835193157196f, + 0.015738952904940f, -0.124463804066181f, 0.015643632039428f, -0.124092340469360f, + 0.015548598021269f, -0.123720809817314f, 0.015453847125173f, -0.123349204659462f, + 0.015359382145107f, -0.122977524995804f, 0.015265202149749f, -0.122605770826340f, + 0.015171307139099f, -0.122233949601650f, 0.015077698044479f, -0.121862053871155f, + 0.014984373003244f, -0.121490091085434f, 0.014891333878040f, -0.121118053793907f, + 0.014798580668867f, -0.120745941996574f, 0.014706112444401f, -0.120373763144016f, + 0.014613929204643f, -0.120001509785652f, 0.014522032812238f, -0.119629189372063f, + 0.014430420473218f, -0.119256794452667f, 0.014339094981551f, -0.118884332478046f, + 0.014248054474592f, -0.118511803448200f, 0.014157299883664f, -0.118139199912548f, + 0.014066831208766f, -0.117766529321671f, 0.013976648449898f, -0.117393791675568f, + 0.013886751607060f, -0.117020979523659f, 0.013797140680254f, -0.116648100316525f, + 0.013707815669477f, -0.116275154054165f, 0.013618776574731f, -0.115902140736580f, + 0.013530024327338f, -0.115529052913189f, 0.013441557064652f, -0.115155905485153f, + 0.013353376649320f, -0.114782683551311f, 0.013265483081341f, -0.114409394562244f, + 0.013177875429392f, -0.114036038517952f, 0.013090553693473f, -0.113662622869015f, + 0.013003518804908f, -0.113289132714272f, 0.012916770763695f, -0.112915575504303f, + 0.012830308638513f, -0.112541958689690f, 0.012744133360684f, -0.112168267369270f, + 0.012658244930208f, -0.111794516444206f, 0.012572642415762f, -0.111420698463917f, + 0.012487327679992f, -0.111046813428402f, 0.012402298860252f, -0.110672861337662f, + 0.012317557819188f, -0.110298842191696f, 0.012233102694154f, -0.109924763441086f, + 0.012148935347795f, -0.109550617635250f, 0.012065053917468f, -0.109176412224770f, + 0.011981460265815f, -0.108802139759064f, 0.011898153461516f, -0.108427800238132f, + 0.011815134435892f, -0.108053401112556f, 0.011732402257621f, -0.107678934931755f, + 0.011649956926703f, -0.107304409146309f, 0.011567799374461f, -0.106929816305637f, + 0.011485928669572f, -0.106555156409740f, 0.011404345743358f, -0.106180444359779f, + 0.011323049664497f, -0.105805665254593f, 0.011242041364312f, -0.105430819094181f, + 0.011161320842803f, -0.105055920779705f, 0.011080888099968f, -0.104680955410004f, + 0.011000742204487f, -0.104305922985077f, 0.010920885019004f, -0.103930838406086f, + 0.010841314680874f, -0.103555686771870f, 0.010762032121420f, -0.103180475533009f, + 0.010683037340641f, -0.102805204689503f, 0.010604331269860f, -0.102429874241352f, + 0.010525912046432f, -0.102054484188557f, 0.010447781533003f, -0.101679034531116f, + 0.010369938798249f, -0.101303517818451f, 0.010292383842170f, -0.100927948951721f, + 0.010215117596090f, -0.100552320480347f, 0.010138138197362f, -0.100176624953747f, + 0.010061448439956f, -0.099800877273083f, 0.009985045529902f, -0.099425069987774f, + 0.009908932261169f, -0.099049203097820f, 0.009833106771111f, -0.098673284053802f, + 0.009757569059730f, -0.098297297954559f, 0.009682320058346f, -0.097921259701252f, + 0.009607359766960f, -0.097545161843300f, 0.009532688185573f, -0.097169004380703f, + 0.009458304382861f, -0.096792794764042f, 0.009384209290147f, -0.096416525542736f, + 0.009310402907431f, -0.096040196716785f, 0.009236886166036f, -0.095663815736771f, + 0.009163657203317f, -0.095287375152111f, 0.009090716950595f, -0.094910882413387f, + 0.009018065407872f, -0.094534330070019f, 0.008945702575147f, -0.094157725572586f, + 0.008873629383743f, -0.093781061470509f, 0.008801844902337f, -0.093404345214367f, + 0.008730349130929f, -0.093027576804161f, 0.008659142069519f, -0.092650748789310f, + 0.008588224649429f, -0.092273868620396f, 0.008517595939338f, -0.091896936297417f, + 0.008447255939245f, -0.091519944369793f, 0.008377205580473f, -0.091142900288105f, + 0.008307444863021f, -0.090765804052353f, 0.008237972855568f, -0.090388655662537f, + 0.008168790489435f, -0.090011447668076f, 0.008099896833301f, -0.089634194970131f, + 0.008031292818487f, -0.089256882667542f, 0.007962978444993f, -0.088879525661469f, + 0.007894953712821f, -0.088502109050751f, 0.007827218621969f, -0.088124647736549f, + 0.007759772241116f, -0.087747126817703f, 0.007692615967244f, -0.087369553744793f, + 0.007625748869032f, -0.086991935968399f, 0.007559171877801f, -0.086614266037941f, + 0.007492884527892f, -0.086236543953419f, 0.007426886819303f, -0.085858769714832f, + 0.007361178752035f, -0.085480943322182f, 0.007295760791749f, -0.085103072226048f, + 0.007230632472783f, -0.084725148975849f, 0.007165793795139f, -0.084347173571587f, + 0.007101245224476f, -0.083969146013260f, 0.007036986760795f, -0.083591073751450f, + 0.006973018404096f, -0.083212949335575f, 0.006909339688718f, -0.082834780216217f, + 0.006845951545984f, -0.082456558942795f, 0.006782853044569f, -0.082078292965889f, + 0.006720044650137f, -0.081699974834919f, 0.006657526828349f, -0.081321612000465f, + 0.006595299113542f, -0.080943197011948f, 0.006533361505717f, -0.080564737319946f, + 0.006471714470536f, -0.080186225473881f, 0.006410357542336f, -0.079807676374912f, + 0.006349290721118f, -0.079429075121880f, 0.006288514938205f, -0.079050421714783f, + 0.006228029262275f, -0.078671731054783f, 0.006167833693326f, -0.078292988240719f, + 0.006107929162681f, -0.077914200723171f, 0.006048315204680f, -0.077535368502140f, + 0.005988991353661f, -0.077156484127045f, 0.005929958540946f, -0.076777562499046f, + 0.005871216300875f, -0.076398596167564f, 0.005812764633447f, -0.076019577682018f, + 0.005754603538662f, -0.075640521943569f, 0.005696733482182f, -0.075261414051056f, + 0.005639153998345f, -0.074882268905640f, 0.005581865552813f, -0.074503071606159f, + 0.005524867679924f, -0.074123837053776f, 0.005468160845339f, -0.073744557797909f, + 0.005411745049059f, -0.073365233838558f, 0.005355620291084f, -0.072985872626305f, + 0.005299786105752f, -0.072606459259987f, 0.005244242958724f, -0.072227008640766f, + 0.005188991315663f, -0.071847513318062f, 0.005134030245245f, -0.071467980742455f, + 0.005079360678792f, -0.071088403463364f, 0.005024982150644f, -0.070708781480789f, + 0.004970894660801f, -0.070329122245312f, 0.004917098674923f, -0.069949418306351f, + 0.004863593727350f, -0.069569669663906f, 0.004810380283743f, -0.069189883768559f, + 0.004757457878441f, -0.068810060620308f, 0.004704826977104f, -0.068430192768574f, + 0.004652487114072f, -0.068050287663937f, 0.004600439220667f, -0.067670337855816f, + 0.004548682365566f, -0.067290350794792f, 0.004497217014432f, -0.066910326480865f, + 0.004446043167263f, -0.066530264914036f, 0.004395160824060f, -0.066150158643723f, + 0.004344569984823f, -0.065770015120506f, 0.004294271115214f, -0.065389834344387f, + 0.004244263283908f, -0.065009608864784f, 0.004194547422230f, -0.064629353582859f, + 0.004145123064518f, -0.064249053597450f, 0.004095990676433f, -0.063868723809719f, + 0.004047149792314f, -0.063488349318504f, 0.003998600877821f, -0.063107937574387f, + 0.003950343467295f, -0.062727488577366f, 0.003902378026396f, -0.062347009778023f, + 0.003854704322293f, -0.061966486275196f, 0.003807322587818f, -0.061585929244757f, + 0.003760232590139f, -0.061205338686705f, 0.003713434794918f, -0.060824707150459f, + 0.003666928736493f, -0.060444042086601f, 0.003620714880526f, -0.060063343495131f, + 0.003574792761356f, -0.059682607650757f, 0.003529162844643f, -0.059301838278770f, + 0.003483824897557f, -0.058921031653881f, 0.003438779152930f, -0.058540191501379f, + 0.003394025377929f, -0.058159314095974f, 0.003349563805386f, -0.057778406888247f, + 0.003305394435301f, -0.057397462427616f, 0.003261517267674f, -0.057016488164663f, + 0.003217932302505f, -0.056635476648808f, 0.003174639539793f, -0.056254431605339f, + 0.003131638979539f, -0.055873356759548f, 0.003088930854574f, -0.055492244660854f, + 0.003046514932066f, -0.055111102759838f, 0.003004391444847f, -0.054729927331209f, + 0.002962560392916f, -0.054348722100258f, 0.002921021543443f, -0.053967483341694f, + 0.002879775362089f, -0.053586211055517f, 0.002838821383193f, -0.053204908967018f, + 0.002798160072416f, -0.052823577076197f, 0.002757790964097f, -0.052442211657763f, + 0.002717714523897f, -0.052060816437006f, 0.002677930751815f, -0.051679391413927f, + 0.002638439415023f, -0.051297932863235f, 0.002599240746349f, -0.050916448235512f, + 0.002560334512964f, -0.050534930080175f, 0.002521721180528f, -0.050153385847807f, + 0.002483400283381f, -0.049771808087826f, 0.002445372054353f, -0.049390204250813f, + 0.002407636726275f, -0.049008570611477f, 0.002370193833485f, -0.048626907169819f, + 0.002333043841645f, -0.048245213925838f, 0.002296186750755f, -0.047863494604826f, + 0.002259622327983f, -0.047481749206781f, 0.002223350573331f, -0.047099970281124f, + 0.002187371719629f, -0.046718169003725f, 0.002151685766876f, -0.046336337924004f, + 0.002116292715073f, -0.045954477041960f, 0.002081192564219f, -0.045572593808174f, + 0.002046385314316f, -0.045190680772066f, 0.002011870965362f, -0.044808741658926f, + 0.001977649517357f, -0.044426776468754f, 0.001943721086718f, -0.044044785201550f, + 0.001910085673444f, -0.043662767857313f, 0.001876743277535f, -0.043280724436045f, + 0.001843693898991f, -0.042898654937744f, 0.001810937537812f, -0.042516563087702f, + 0.001778474310413f, -0.042134445160627f, 0.001746304216795f, -0.041752301156521f, + 0.001714427140541f, -0.041370131075382f, 0.001682843198068f, -0.040987938642502f, + 0.001651552389376f, -0.040605723857880f, 0.001620554830879f, -0.040223482996225f, + 0.001589850406162f, -0.039841219782829f, 0.001559439115226f, -0.039458930492401f, + 0.001529321074486f, -0.039076622575521f, 0.001499496400356f, -0.038694288581610f, + 0.001469964860007f, -0.038311932235956f, 0.001440726569854f, -0.037929553538561f, + 0.001411781646311f, -0.037547148764133f, 0.001383129972965f, -0.037164725363255f, + 0.001354771666229f, -0.036782283335924f, 0.001326706726104f, -0.036399815231562f, + 0.001298935036175f, -0.036017324775457f, 0.001271456829272f, -0.035634815692902f, + 0.001244271872565f, -0.035252287983894f, 0.001217380515300f, -0.034869734197855f, + 0.001190782408230f, -0.034487165510654f, 0.001164477784187f, -0.034104570746422f, + 0.001138466643170f, -0.033721961081028f, 0.001112748985179f, -0.033339329063892f, + 0.001087324810214f, -0.032956674695015f, 0.001062194118276f, -0.032574005424976f, + 0.001037356909364f, -0.032191313803196f, 0.001012813183479f, -0.031808607280254f, + 0.000988563057035f, -0.031425878405571f, 0.000964606530033f, -0.031043132767081f, + 0.000940943544265f, -0.030660368502140f, 0.000917574157938f, -0.030277585610747f, + 0.000894498312846f, -0.029894785955548f, 0.000871716125403f, -0.029511967673898f, + 0.000849227537401f, -0.029129132628441f, 0.000827032607049f, -0.028746278956532f, + 0.000805131276138f, -0.028363410383463f, 0.000783523661084f, -0.027980525046587f, + 0.000762209703680f, -0.027597622945905f, 0.000741189462133f, -0.027214704081416f, + 0.000720462878235f, -0.026831768453121f, 0.000700030010194f, -0.026448817923665f, + 0.000679890916217f, -0.026065852493048f, 0.000660045538098f, -0.025682870298624f, + 0.000640493875835f, -0.025299875065684f, 0.000621235987637f, -0.024916863068938f, + 0.000602271873504f, -0.024533838033676f, 0.000583601591643f, -0.024150796234608f, + 0.000565225025639f, -0.023767741397023f, 0.000547142291907f, -0.023384673520923f, + 0.000529353390448f, -0.023001590743661f, 0.000511858321261f, -0.022618494927883f, + 0.000494657084346f, -0.022235386073589f, 0.000477749679703f, -0.021852264180779f, + 0.000461136136437f, -0.021469129249454f, 0.000444816454547f, -0.021085981279612f, + 0.000428790634032f, -0.020702820271254f, 0.000413058703998f, -0.020319648087025f, + 0.000397620693548f, -0.019936462864280f, 0.000382476573577f, -0.019553268328309f, + 0.000367626344087f, -0.019170060753822f, 0.000353070063284f, -0.018786842003465f, + 0.000338807702065f, -0.018403612077236f, 0.000324839289533f, -0.018020370975137f, + 0.000311164796585f, -0.017637118697166f, 0.000297784281429f, -0.017253857105970f, + 0.000284697714960f, -0.016870586201549f, 0.000271905126283f, -0.016487304121256f, + 0.000259406515397f, -0.016104012727737f, 0.000247201882303f, -0.015720712020993f, + 0.000235291256104f, -0.015337402001023f, 0.000223674607696f, -0.014954082667828f, + 0.000212351980736f, -0.014570754021406f, 0.000201323360670f, -0.014187417924404f, + 0.000190588747500f, -0.013804072514176f, 0.000180148170330f, -0.013420719653368f, + 0.000170001629158f, -0.013037359341979f, 0.000160149123985f, -0.012653990648687f, + 0.000150590654812f, -0.012270614504814f, 0.000141326236189f, -0.011887230910361f, + 0.000132355868118f, -0.011503840796649f, 0.000123679565149f, -0.011120444163680f, + 0.000115297327284f, -0.010737040080130f, 0.000107209154521f, -0.010353630408645f, + 0.000099415054137f, -0.009970214217901f, 0.000091915040684f, -0.009586792439222f, + 0.000084709099610f, -0.009203365072608f, 0.000077797252743f, -0.008819932118058f, + 0.000071179500083f, -0.008436493575573f, 0.000064855834353f, -0.008053051307797f, + 0.000058826273744f, -0.007669602986425f, 0.000053090810979f, -0.007286150939763f, + 0.000047649456974f, -0.006902694236487f, 0.000042502211727f, -0.006519233807921f, + 0.000037649078877f, -0.006135769188404f, 0.000033090062061f, -0.005752300843596f, + 0.000028825161280f, -0.005368829704821f, 0.000024854381991f, -0.004985354840755f, + 0.000021177724193f, -0.004601877182722f, 0.000017795191525f, -0.004218397196382f, + 0.000014706784896f, -0.003834914416075f, 0.000011912506125f, -0.003451429307461f, + 0.000009412358850f, -0.003067942336202f, 0.000007206342616f, -0.002684453502297f, + 0.000005294459243f, -0.002300963038579f, 0.000003676709639f, -0.001917471294291f, + 0.000002353095169f, -0.001533978385851f, 0.000001323616516f, -0.001150484546088f, + 0.000000588274133f, -0.000766990066040f, 0.000000147068562f, -0.000383495149435f, + 0.000000000000000f, -0.000000000000023f, 0.000000147068562f, 0.000383495149435f, + 0.000000588274133f, 0.000766990066040f, 0.000001323616516f, 0.001150484546088f, + 0.000002353095169f, 0.001533978385851f, 0.000003676709639f, 0.001917471294291f, + 0.000005294459243f, 0.002300963038579f, 0.000007206342616f, 0.002684453502297f, + 0.000009412358850f, 0.003067942336202f, 0.000011912506125f, 0.003451429307461f, + 0.000014706784896f, 0.003834914416075f, 0.000017795191525f, 0.004218397196382f, + 0.000021177724193f, 0.004601877182722f, 0.000024854381991f, 0.004985354840755f, + 0.000028825161280f, 0.005368829704821f, 0.000033090062061f, 0.005752300843596f, + 0.000037649078877f, 0.006135769188404f, 0.000042502211727f, 0.006519233807921f, + 0.000047649456974f, 0.006902694236487f, 0.000053090810979f, 0.007286150939763f, + 0.000058826273744f, 0.007669602986425f, 0.000064855834353f, 0.008053051307797f, + 0.000071179500083f, 0.008436493575573f, 0.000077797252743f, 0.008819932118058f, + 0.000084709099610f, 0.009203365072608f, 0.000091915040684f, 0.009586792439222f, + 0.000099415054137f, 0.009970214217901f, 0.000107209154521f, 0.010353630408645f, + 0.000115297327284f, 0.010737040080130f, 0.000123679565149f, 0.011120444163680f, + 0.000132355868118f, 0.011503840796649f, 0.000141326236189f, 0.011887230910361f, + 0.000150590654812f, 0.012270614504814f, 0.000160149123985f, 0.012653990648687f, + 0.000170001629158f, 0.013037359341979f, 0.000180148170330f, 0.013420719653368f, + 0.000190588747500f, 0.013804072514176f, 0.000201323360670f, 0.014187417924404f, + 0.000212351980736f, 0.014570754021406f, 0.000223674607696f, 0.014954082667828f, + 0.000235291256104f, 0.015337402001023f, 0.000247201882303f, 0.015720712020993f, + 0.000259406515397f, 0.016104012727737f, 0.000271905126283f, 0.016487304121256f, + 0.000284697714960f, 0.016870586201549f, 0.000297784281429f, 0.017253857105970f, + 0.000311164796585f, 0.017637118697166f, 0.000324839289533f, 0.018020370975137f, + 0.000338807702065f, 0.018403612077236f, 0.000353070063284f, 0.018786842003465f, + 0.000367626344087f, 0.019170060753822f, 0.000382476573577f, 0.019553268328309f, + 0.000397620693548f, 0.019936462864280f, 0.000413058703998f, 0.020319648087025f, + 0.000428790634032f, 0.020702820271254f, 0.000444816454547f, 0.021085981279612f, + 0.000461136136437f, 0.021469129249454f, 0.000477749679703f, 0.021852264180779f, + 0.000494657084346f, 0.022235386073589f, 0.000511858321261f, 0.022618494927883f, + 0.000529353390448f, 0.023001590743661f, 0.000547142291907f, 0.023384673520923f, + 0.000565225025639f, 0.023767741397023f, 0.000583601591643f, 0.024150796234608f, + 0.000602271873504f, 0.024533838033676f, 0.000621235987637f, 0.024916863068938f, + 0.000640493875835f, 0.025299875065684f, 0.000660045538098f, 0.025682870298624f, + 0.000679890916217f, 0.026065852493048f, 0.000700030010194f, 0.026448817923665f, + 0.000720462878235f, 0.026831768453121f, 0.000741189462133f, 0.027214704081416f, + 0.000762209703680f, 0.027597622945905f, 0.000783523661084f, 0.027980525046587f, + 0.000805131276138f, 0.028363410383463f, 0.000827032607049f, 0.028746278956532f, + 0.000849227537401f, 0.029129132628441f, 0.000871716125403f, 0.029511967673898f, + 0.000894498312846f, 0.029894785955548f, 0.000917574157938f, 0.030277585610747f, + 0.000940943544265f, 0.030660368502140f, 0.000964606530033f, 0.031043132767081f, + 0.000988563057035f, 0.031425878405571f, 0.001012813183479f, 0.031808607280254f, + 0.001037356909364f, 0.032191313803196f, 0.001062194118276f, 0.032574005424976f, + 0.001087324810214f, 0.032956674695015f, 0.001112748985179f, 0.033339329063892f, + 0.001138466643170f, 0.033721961081028f, 0.001164477784187f, 0.034104570746422f, + 0.001190782408230f, 0.034487165510654f, 0.001217380515300f, 0.034869734197855f, + 0.001244271872565f, 0.035252287983894f, 0.001271456829272f, 0.035634815692902f, + 0.001298935036175f, 0.036017324775457f, 0.001326706726104f, 0.036399815231562f, + 0.001354771666229f, 0.036782283335924f, 0.001383129972965f, 0.037164725363255f, + 0.001411781646311f, 0.037547148764133f, 0.001440726569854f, 0.037929553538561f, + 0.001469964860007f, 0.038311932235956f, 0.001499496400356f, 0.038694288581610f, + 0.001529321074486f, 0.039076622575521f, 0.001559439115226f, 0.039458930492401f, + 0.001589850406162f, 0.039841219782829f, 0.001620554830879f, 0.040223482996225f, + 0.001651552389376f, 0.040605723857880f, 0.001682843198068f, 0.040987938642502f, + 0.001714427140541f, 0.041370131075382f, 0.001746304216795f, 0.041752301156521f, + 0.001778474310413f, 0.042134445160627f, 0.001810937537812f, 0.042516563087702f, + 0.001843693898991f, 0.042898654937744f, 0.001876743277535f, 0.043280724436045f, + 0.001910085673444f, 0.043662767857313f, 0.001943721086718f, 0.044044785201550f, + 0.001977649517357f, 0.044426776468754f, 0.002011870965362f, 0.044808741658926f, + 0.002046385314316f, 0.045190680772066f, 0.002081192564219f, 0.045572593808174f, + 0.002116292715073f, 0.045954477041960f, 0.002151685766876f, 0.046336337924004f, + 0.002187371719629f, 0.046718169003725f, 0.002223350573331f, 0.047099970281124f, + 0.002259622327983f, 0.047481749206781f, 0.002296186750755f, 0.047863494604826f, + 0.002333043841645f, 0.048245213925838f, 0.002370193833485f, 0.048626907169819f, + 0.002407636726275f, 0.049008570611477f, 0.002445372054353f, 0.049390204250813f, + 0.002483400283381f, 0.049771808087826f, 0.002521721180528f, 0.050153385847807f, + 0.002560334512964f, 0.050534930080175f, 0.002599240746349f, 0.050916448235512f, + 0.002638439415023f, 0.051297932863235f, 0.002677930751815f, 0.051679391413927f, + 0.002717714523897f, 0.052060816437006f, 0.002757790964097f, 0.052442211657763f, + 0.002798160072416f, 0.052823577076197f, 0.002838821383193f, 0.053204908967018f, + 0.002879775362089f, 0.053586211055517f, 0.002921021543443f, 0.053967483341694f, + 0.002962560392916f, 0.054348722100258f, 0.003004391444847f, 0.054729927331209f, + 0.003046514932066f, 0.055111102759838f, 0.003088930854574f, 0.055492244660854f, + 0.003131638979539f, 0.055873356759548f, 0.003174639539793f, 0.056254431605339f, + 0.003217932302505f, 0.056635476648808f, 0.003261517267674f, 0.057016488164663f, + 0.003305394435301f, 0.057397462427616f, 0.003349563805386f, 0.057778406888247f, + 0.003394025377929f, 0.058159314095974f, 0.003438779152930f, 0.058540191501379f, + 0.003483824897557f, 0.058921031653881f, 0.003529162844643f, 0.059301838278770f, + 0.003574792761356f, 0.059682607650757f, 0.003620714880526f, 0.060063343495131f, + 0.003666928736493f, 0.060444042086601f, 0.003713434794918f, 0.060824707150459f, + 0.003760232590139f, 0.061205338686705f, 0.003807322587818f, 0.061585929244757f, + 0.003854704322293f, 0.061966486275196f, 0.003902378026396f, 0.062347009778023f, + 0.003950343467295f, 0.062727488577366f, 0.003998600877821f, 0.063107937574387f, + 0.004047149792314f, 0.063488349318504f, 0.004095990676433f, 0.063868723809719f, + 0.004145123064518f, 0.064249053597450f, 0.004194547422230f, 0.064629353582859f, + 0.004244263283908f, 0.065009608864784f, 0.004294271115214f, 0.065389834344387f, + 0.004344569984823f, 0.065770015120506f, 0.004395160824060f, 0.066150158643723f, + 0.004446043167263f, 0.066530264914036f, 0.004497217014432f, 0.066910326480865f, + 0.004548682365566f, 0.067290350794792f, 0.004600439220667f, 0.067670337855816f, + 0.004652487114072f, 0.068050287663937f, 0.004704826977104f, 0.068430192768574f, + 0.004757457878441f, 0.068810060620308f, 0.004810380283743f, 0.069189883768559f, + 0.004863593727350f, 0.069569669663906f, 0.004917098674923f, 0.069949418306351f, + 0.004970894660801f, 0.070329122245312f, 0.005024982150644f, 0.070708781480789f, + 0.005079360678792f, 0.071088403463364f, 0.005134030245245f, 0.071467980742455f, + 0.005188991315663f, 0.071847513318062f, 0.005244242958724f, 0.072227008640766f, + 0.005299786105752f, 0.072606459259987f, 0.005355620291084f, 0.072985872626305f, + 0.005411745049059f, 0.073365233838558f, 0.005468160845339f, 0.073744557797909f, + 0.005524867679924f, 0.074123837053776f, 0.005581865552813f, 0.074503071606159f, + 0.005639153998345f, 0.074882268905640f, 0.005696733482182f, 0.075261414051056f, + 0.005754603538662f, 0.075640521943569f, 0.005812764633447f, 0.076019577682018f, + 0.005871216300875f, 0.076398596167564f, 0.005929958540946f, 0.076777562499046f, + 0.005988991353661f, 0.077156484127045f, 0.006048315204680f, 0.077535368502140f, + 0.006107929162681f, 0.077914200723171f, 0.006167833693326f, 0.078292988240719f, + 0.006228029262275f, 0.078671731054783f, 0.006288514938205f, 0.079050421714783f, + 0.006349290721118f, 0.079429075121880f, 0.006410357542336f, 0.079807676374912f, + 0.006471714470536f, 0.080186225473881f, 0.006533361505717f, 0.080564737319946f, + 0.006595299113542f, 0.080943197011948f, 0.006657526828349f, 0.081321612000465f, + 0.006720044650137f, 0.081699974834919f, 0.006782853044569f, 0.082078292965889f, + 0.006845951545984f, 0.082456558942795f, 0.006909339688718f, 0.082834780216217f, + 0.006973018404096f, 0.083212949335575f, 0.007036986760795f, 0.083591073751450f, + 0.007101245224476f, 0.083969146013260f, 0.007165793795139f, 0.084347173571587f, + 0.007230632472783f, 0.084725148975849f, 0.007295760791749f, 0.085103072226048f, + 0.007361178752035f, 0.085480943322182f, 0.007426886819303f, 0.085858769714832f, + 0.007492884527892f, 0.086236543953419f, 0.007559171877801f, 0.086614266037941f, + 0.007625748869032f, 0.086991935968399f, 0.007692615967244f, 0.087369553744793f, + 0.007759772241116f, 0.087747126817703f, 0.007827218621969f, 0.088124647736549f, + 0.007894953712821f, 0.088502109050751f, 0.007962978444993f, 0.088879525661469f, + 0.008031292818487f, 0.089256882667542f, 0.008099896833301f, 0.089634194970131f, + 0.008168790489435f, 0.090011447668076f, 0.008237972855568f, 0.090388655662537f, + 0.008307444863021f, 0.090765804052353f, 0.008377205580473f, 0.091142900288105f, + 0.008447255939245f, 0.091519944369793f, 0.008517595939338f, 0.091896936297417f, + 0.008588224649429f, 0.092273868620396f, 0.008659142069519f, 0.092650748789310f, + 0.008730349130929f, 0.093027576804161f, 0.008801844902337f, 0.093404345214367f, + 0.008873629383743f, 0.093781061470509f, 0.008945702575147f, 0.094157725572586f, + 0.009018065407872f, 0.094534330070019f, 0.009090716950595f, 0.094910882413387f, + 0.009163657203317f, 0.095287375152111f, 0.009236886166036f, 0.095663815736771f, + 0.009310402907431f, 0.096040196716785f, 0.009384209290147f, 0.096416525542736f, + 0.009458304382861f, 0.096792794764042f, 0.009532688185573f, 0.097169004380703f, + 0.009607359766960f, 0.097545161843300f, 0.009682320058346f, 0.097921259701252f, + 0.009757569059730f, 0.098297297954559f, 0.009833106771111f, 0.098673284053802f, + 0.009908932261169f, 0.099049203097820f, 0.009985045529902f, 0.099425069987774f, + 0.010061448439956f, 0.099800877273083f, 0.010138138197362f, 0.100176624953747f, + 0.010215117596090f, 0.100552320480347f, 0.010292383842170f, 0.100927948951721f, + 0.010369938798249f, 0.101303517818451f, 0.010447781533003f, 0.101679034531116f, + 0.010525912046432f, 0.102054484188557f, 0.010604331269860f, 0.102429874241352f, + 0.010683037340641f, 0.102805204689503f, 0.010762032121420f, 0.103180475533009f, + 0.010841314680874f, 0.103555686771870f, 0.010920885019004f, 0.103930838406086f, + 0.011000742204487f, 0.104305922985077f, 0.011080888099968f, 0.104680955410004f, + 0.011161320842803f, 0.105055920779705f, 0.011242041364312f, 0.105430819094181f, + 0.011323049664497f, 0.105805665254593f, 0.011404345743358f, 0.106180444359779f, + 0.011485928669572f, 0.106555156409740f, 0.011567799374461f, 0.106929816305637f, + 0.011649956926703f, 0.107304409146309f, 0.011732402257621f, 0.107678934931755f, + 0.011815134435892f, 0.108053401112556f, 0.011898153461516f, 0.108427800238132f, + 0.011981460265815f, 0.108802139759064f, 0.012065053917468f, 0.109176412224770f, + 0.012148935347795f, 0.109550617635250f, 0.012233102694154f, 0.109924763441086f, + 0.012317557819188f, 0.110298842191696f, 0.012402298860252f, 0.110672861337662f, + 0.012487327679992f, 0.111046813428402f, 0.012572642415762f, 0.111420698463917f, + 0.012658244930208f, 0.111794516444206f, 0.012744133360684f, 0.112168267369270f, + 0.012830308638513f, 0.112541958689690f, 0.012916770763695f, 0.112915575504303f, + 0.013003518804908f, 0.113289132714272f, 0.013090553693473f, 0.113662622869015f, + 0.013177875429392f, 0.114036038517952f, 0.013265483081341f, 0.114409394562244f, + 0.013353376649320f, 0.114782683551311f, 0.013441557064652f, 0.115155905485153f, + 0.013530024327338f, 0.115529052913189f, 0.013618776574731f, 0.115902140736580f, + 0.013707815669477f, 0.116275154054165f, 0.013797140680254f, 0.116648100316525f, + 0.013886751607060f, 0.117020979523659f, 0.013976648449898f, 0.117393791675568f, + 0.014066831208766f, 0.117766529321671f, 0.014157299883664f, 0.118139199912548f, + 0.014248054474592f, 0.118511803448200f, 0.014339094981551f, 0.118884332478046f, + 0.014430420473218f, 0.119256794452667f, 0.014522032812238f, 0.119629189372063f, + 0.014613929204643f, 0.120001509785652f, 0.014706112444401f, 0.120373763144016f, + 0.014798580668867f, 0.120745941996574f, 0.014891333878040f, 0.121118053793907f, + 0.014984373003244f, 0.121490091085434f, 0.015077698044479f, 0.121862053871155f, + 0.015171307139099f, 0.122233949601650f, 0.015265202149749f, 0.122605770826340f, + 0.015359382145107f, 0.122977524995804f, 0.015453847125173f, 0.123349204659462f, + 0.015548598021269f, 0.123720809817314f, 0.015643632039428f, 0.124092340469360f, + 0.015738952904940f, 0.124463804066181f, 0.015834558755159f, 0.124835193157196f, + 0.015930447727442f, 0.125206500291824f, 0.016026621684432f, 0.125577747821808f, + 0.016123080626130f, 0.125948905944824f, 0.016219824552536f, 0.126320004463196f, + 0.016316853463650f, 0.126691013574600f, 0.016414167359471f, 0.127061963081360f, + 0.016511764377356f, 0.127432823181152f, 0.016609646379948f, 0.127803623676300f, + 0.016707813367248f, 0.128174334764481f, 0.016806263476610f, 0.128544986248016f, + 0.016904998570681f, 0.128915548324585f, 0.017004016786814f, 0.129286035895348f, + 0.017103319987655f, 0.129656463861465f, 0.017202908173203f, 0.130026802420616f, + 0.017302779480815f, 0.130397051572800f, 0.017402933910489f, 0.130767241120338f, + 0.017503373324871f, 0.131137356162071f, 0.017604095861316f, 0.131507381796837f, + 0.017705103382468f, 0.131877332925797f, 0.017806394025683f, 0.132247209548950f, + 0.017907967790961f, 0.132617011666298f, 0.018009826540947f, 0.132986739277840f, + 0.018111966550350f, 0.133356377482414f, 0.018214391544461f, 0.133725941181183f, + 0.018317099660635f, 0.134095430374146f, 0.018420090898871f, 0.134464830160141f, + 0.018523367121816f, 0.134834155440331f, 0.018626924604177f, 0.135203406214714f, + 0.018730765208602f, 0.135572582483292f, 0.018834890797734f, 0.135941669344902f, + 0.018939297646284f, 0.136310681700706f, 0.019043987616897f, 0.136679604649544f, + 0.019148962572217f, 0.137048453092575f, 0.019254218786955f, 0.137417227029800f, + 0.019359756261110f, 0.137785911560059f, 0.019465578719974f, 0.138154521584511f, + 0.019571684300900f, 0.138523042201996f, 0.019678071141243f, 0.138891488313675f, + 0.019784741103649f, 0.139259845018387f, 0.019891692325473f, 0.139628127217293f, + 0.019998926669359f, 0.139996320009232f, 0.020106444135308f, 0.140364438295364f, + 0.020214242860675f, 0.140732467174530f, 0.020322324708104f, 0.141100421547890f, + 0.020430689677596f, 0.141468286514282f, 0.020539334043860f, 0.141836062073708f, + 0.020648263394833f, 0.142203763127327f, 0.020757472142577f, 0.142571389675140f, + 0.020866964012384f, 0.142938911914825f, 0.020976737141609f, 0.143306359648705f, + 0.021086793392897f, 0.143673732876778f, 0.021197130903602f, 0.144041016697884f, + 0.021307749673724f, 0.144408211112022f, 0.021418649703264f, 0.144775316119194f, + 0.021529832854867f, 0.145142331719399f, 0.021641295403242f, 0.145509272813797f, + 0.021753041073680f, 0.145876124501228f, 0.021865066140890f, 0.146242901682854f, + 0.021977374330163f, 0.146609574556351f, 0.022089963778853f, 0.146976172924042f, + 0.022202832624316f, 0.147342681884766f, 0.022315984591842f, 0.147709101438522f, + 0.022429415956140f, 0.148075446486473f, 0.022543128579855f, 0.148441687226295f, + 0.022657122462988f, 0.148807853460312f, 0.022771397605538f, 0.149173930287361f, + 0.022885952144861f, 0.149539917707443f, 0.023000787943602f, 0.149905815720558f, + 0.023115905001760f, 0.150271624326706f, 0.023231301456690f, 0.150637343525887f, + 0.023346979171038f, 0.151002973318100f, 0.023462938144803f, 0.151368513703346f, + 0.023579176515341f, 0.151733979582787f, 0.023695694282651f, 0.152099341154099f, + 0.023812493309379f, 0.152464613318443f, 0.023929571732879f, 0.152829796075821f, + 0.024046931415796f, 0.153194904327393f, 0.024164570495486f, 0.153559908270836f, + 0.024282488971949f, 0.153924822807312f, 0.024400688707829f, 0.154289647936821f, + 0.024519165977836f, 0.154654383659363f, 0.024637924507260f, 0.155019029974937f, + 0.024756962433457f, 0.155383571982384f, 0.024876279756427f, 0.155748039484024f, + 0.024995878338814f, 0.156112402677536f, 0.025115754455328f, 0.156476691365242f, + 0.025235909968615f, 0.156840875744820f, 0.025356344878674f, 0.157204970717430f, + 0.025477059185505f, 0.157568961381912f, 0.025598052889109f, 0.157932877540588f, + 0.025719324126840f, 0.158296689391136f, 0.025840876623988f, 0.158660411834717f, + 0.025962706655264f, 0.159024044871330f, 0.026084816083312f, 0.159387573599815f, + 0.026207204908133f, 0.159751012921333f, 0.026329871267080f, 0.160114362835884f, + 0.026452817022800f, 0.160477623343468f, 0.026576040312648f, 0.160840779542923f, + 0.026699542999268f, 0.161203846335411f, 0.026823325082660f, 0.161566808819771f, + 0.026947384700179f, 0.161929681897163f, 0.027071721851826f, 0.162292465567589f, + 0.027196336537600f, 0.162655144929886f, 0.027321230620146f, 0.163017734885216f, + 0.027446404099464f, 0.163380220532417f, 0.027571853250265f, 0.163742616772652f, + 0.027697581797838f, 0.164104923605919f, 0.027823587879539f, 0.164467126131058f, + 0.027949871495366f, 0.164829224348068f, 0.028076432645321f, 0.165191248059273f, + 0.028203271329403f, 0.165553152561188f, 0.028330387547612f, 0.165914967656136f, + 0.028457781299949f, 0.166276678442955f, 0.028585452586412f, 0.166638299822807f, + 0.028713401407003f, 0.166999831795692f, 0.028841627761722f, 0.167361244559288f, + 0.028970129787922f, 0.167722567915916f, 0.029098909348249f, 0.168083801865578f, + 0.029227968305349f, 0.168444931507111f, 0.029357301071286f, 0.168805956840515f, + 0.029486913233995f, 0.169166877865791f, 0.029616801068187f, 0.169527709484100f, + 0.029746964573860f, 0.169888436794281f, 0.029877405613661f, 0.170249074697495f, + 0.030008124187589f, 0.170609608292580f, 0.030139118432999f, 0.170970037579536f, + 0.030270388349891f, 0.171330362558365f, 0.030401935800910f, 0.171690583229065f, + 0.030533758923411f, 0.172050714492798f, 0.030665857717395f, 0.172410741448402f, + 0.030798232182860f, 0.172770664095879f, 0.030930884182453f, 0.173130482435226f, + 0.031063811853528f, 0.173490211367607f, 0.031197015196085f, 0.173849821090698f, + 0.031330492347479f, 0.174209341406822f, 0.031464248895645f, 0.174568757414818f, + 0.031598277390003f, 0.174928069114685f, 0.031732585281134f, 0.175287276506424f, + 0.031867165118456f, 0.175646379590034f, 0.032002024352551f, 0.176005378365517f, + 0.032137155532837f, 0.176364272832870f, 0.032272562384605f, 0.176723077893257f, + 0.032408244907856f, 0.177081763744354f, 0.032544203102589f, 0.177440345287323f, + 0.032680433243513f, 0.177798837423325f, 0.032816942781210f, 0.178157210350037f, + 0.032953724265099f, 0.178515478968620f, 0.033090781420469f, 0.178873643279076f, + 0.033228114247322f, 0.179231703281403f, 0.033365719020367f, 0.179589673876762f, + 0.033503599464893f, 0.179947525262833f, 0.033641755580902f, 0.180305257439613f, + 0.033780183643103f, 0.180662900209427f, 0.033918887376785f, 0.181020438671112f, + 0.034057866781950f, 0.181377857923508f, 0.034197118133307f, 0.181735187768936f, + 0.034336645156145f, 0.182092398405075f, 0.034476444125175f, 0.182449504733086f, + 0.034616518765688f, 0.182806491851807f, 0.034756865352392f, 0.183163389563560f, + 0.034897487610579f, 0.183520168066025f, 0.035038381814957f, 0.183876842260361f, + 0.035179551690817f, 0.184233412146568f, 0.035320993512869f, 0.184589877724648f, + 0.035462711006403f, 0.184946224093437f, 0.035604696720839f, 0.185302466154099f, + 0.035746958106756f, 0.185658603906631f, 0.035889495164156f, 0.186014622449875f, + 0.036032304167747f, 0.186370536684990f, 0.036175385117531f, 0.186726331710815f, + 0.036318738013506f, 0.187082037329674f, 0.036462362855673f, 0.187437608838081f, + 0.036606263369322f, 0.187793090939522f, 0.036750435829163f, 0.188148453831673f, + 0.036894880235195f, 0.188503712415695f, 0.037039596587420f, 0.188858851790428f, + 0.037184584885836f, 0.189213871955872f, 0.037329845130444f, 0.189568802714348f, + 0.037475381046534f, 0.189923599362373f, 0.037621185183525f, 0.190278306603432f, + 0.037767261266708f, 0.190632879734039f, 0.037913613021374f, 0.190987363457680f, + 0.038060232996941f, 0.191341713070869f, 0.038207128643990f, 0.191695958375931f, + 0.038354292511940f, 0.192050099372864f, 0.038501728326082f, 0.192404121160507f, + 0.038649436086416f, 0.192758023738861f, 0.038797415792942f, 0.193111822009087f, + 0.038945667445660f, 0.193465501070023f, 0.039094187319279f, 0.193819075822830f, + 0.039242979139090f, 0.194172516465187f, 0.039392042905092f, 0.194525867700577f, + 0.039541378617287f, 0.194879084825516f, 0.039690986275673f, 0.195232197642326f, + 0.039840862154961f, 0.195585191249847f, 0.039991009980440f, 0.195938065648079f, + 0.040141426026821f, 0.196290835738182f, 0.040292114019394f, 0.196643486618996f, + 0.040443073958158f, 0.196996018290520f, 0.040594302117825f, 0.197348430752754f, + 0.040745802223682f, 0.197700738906860f, 0.040897574275732f, 0.198052927851677f, + 0.041049610823393f, 0.198404997587204f, 0.041201923042536f, 0.198756948113441f, + 0.041354499757290f, 0.199108779430389f, 0.041507352143526f, 0.199460506439209f, + 0.041660469025373f, 0.199812099337578f, 0.041813857853413f, 0.200163587927818f, + 0.041967518627644f, 0.200514942407608f, 0.042121443897486f, 0.200866192579269f, + 0.042275641113520f, 0.201217323541641f, 0.042430106550455f, 0.201568335294724f, + 0.042584843933582f, 0.201919227838516f, 0.042739849537611f, 0.202270001173019f, + 0.042895123362541f, 0.202620655298233f, 0.043050665408373f, 0.202971190214157f, + 0.043206475675106f, 0.203321605920792f, 0.043362557888031f, 0.203671902418137f, + 0.043518904596567f, 0.204022079706192f, 0.043675523251295f, 0.204372137784958f, + 0.043832406401634f, 0.204722076654434f, 0.043989561498165f, 0.205071896314621f, + 0.044146984815598f, 0.205421581864357f, 0.044304672628641f, 0.205771163105965f, + 0.044462632387877f, 0.206120610237122f, 0.044620860368013f, 0.206469938158989f, + 0.044779352843761f, 0.206819161772728f, 0.044938117265701f, 0.207168251276016f, + 0.045097146183252f, 0.207517206668854f, 0.045256443321705f, 0.207866057753563f, + 0.045416008681059f, 0.208214774727821f, 0.045575842261314f, 0.208563387393951f, + 0.045735940337181f, 0.208911851048470f, 0.045896306633949f, 0.209260210394859f, + 0.046056941151619f, 0.209608450531960f, 0.046217843890190f, 0.209956556558609f, + 0.046379011124372f, 0.210304543375969f, 0.046540446579456f, 0.210652396082878f, + 0.046702146530151f, 0.211000129580498f, 0.046864114701748f, 0.211347743868828f, + 0.047026351094246f, 0.211695238947868f, 0.047188851982355f, 0.212042599916458f, + 0.047351621091366f, 0.212389841675758f, 0.047514654695988f, 0.212736949324608f, + 0.047677956521511f, 0.213083937764168f, 0.047841522842646f, 0.213430806994438f, + 0.048005353659391f, 0.213777542114258f, 0.048169452697039f, 0.214124158024788f, + 0.048333816230297f, 0.214470639824867f, 0.048498444259167f, 0.214817002415657f, + 0.048663340508938f, 0.215163245797157f, 0.048828501254320f, 0.215509355068207f, + 0.048993926495314f, 0.215855330228806f, 0.049159619957209f, 0.216201186180115f, + 0.049325577914715f, 0.216546908020973f, 0.049491796642542f, 0.216892510652542f, + 0.049658283591270f, 0.217237979173660f, 0.049825038760900f, 0.217583328485489f, + 0.049992054700851f, 0.217928543686867f, 0.050159335136414f, 0.218273624777794f, + 0.050326880067587f, 0.218618586659431f, 0.050494693219662f, 0.218963414430618f, + 0.050662767142057f, 0.219308122992516f, 0.050831105560064f, 0.219652697443962f, + 0.050999708473682f, 0.219997137784958f, 0.051168579608202f, 0.220341444015503f, + 0.051337707787752f, 0.220685631036758f, 0.051507104188204f, 0.221029683947563f, + 0.051676765084267f, 0.221373617649078f, 0.051846686750650f, 0.221717402338982f, + 0.052016876637936f, 0.222061067819595f, 0.052187327295542f, 0.222404599189758f, + 0.052358038723469f, 0.222748011350632f, 0.052529018372297f, 0.223091274499893f, + 0.052700258791447f, 0.223434418439865f, 0.052871759980917f, 0.223777428269386f, + 0.053043525665998f, 0.224120303988457f, 0.053215555846691f, 0.224463045597076f, + 0.053387850522995f, 0.224805667996407f, 0.053560405969620f, 0.225148141384125f, + 0.053733222186565f, 0.225490495562553f, 0.053906302899122f, 0.225832715630531f, + 0.054079644382000f, 0.226174786686897f, 0.054253250360489f, 0.226516738533974f, + 0.054427117109299f, 0.226858556270599f, 0.054601248353720f, 0.227200239896774f, + 0.054775636643171f, 0.227541789412498f, 0.054950293153524f, 0.227883204817772f, + 0.055125206708908f, 0.228224486112595f, 0.055300384759903f, 0.228565633296967f, + 0.055475823581219f, 0.228906646370888f, 0.055651523172855f, 0.229247525334358f, + 0.055827483534813f, 0.229588270187378f, 0.056003704667091f, 0.229928880929947f, + 0.056180190294981f, 0.230269357562065f, 0.056356932967901f, 0.230609700083733f, + 0.056533940136433f, 0.230949893593788f, 0.056711208075285f, 0.231289967894554f, + 0.056888736784458f, 0.231629893183708f, 0.057066522538662f, 0.231969684362412f, + 0.057244572788477f, 0.232309341430664f, 0.057422880083323f, 0.232648864388466f, + 0.057601451873779f, 0.232988253235817f, 0.057780280709267f, 0.233327493071556f, + 0.057959370315075f, 0.233666598796844f, 0.058138720691204f, 0.234005570411682f, + 0.058318331837654f, 0.234344407916069f, 0.058498200029135f, 0.234683111310005f, + 0.058678328990936f, 0.235021665692329f, 0.058858718723059f, 0.235360085964203f, + 0.059039369225502f, 0.235698372125626f, 0.059220276772976f, 0.236036509275436f, + 0.059401445090771f, 0.236374512314796f, 0.059582870453596f, 0.236712381243706f, + 0.059764556586742f, 0.237050101161003f, 0.059946499764919f, 0.237387686967850f, + 0.060128703713417f, 0.237725138664246f, 0.060311164706945f, 0.238062441349030f, + 0.060493886470795f, 0.238399609923363f, 0.060676865279675f, 0.238736644387245f, + 0.060860104858875f, 0.239073529839516f, 0.061043601483107f, 0.239410281181335f, + 0.061227355152369f, 0.239746883511543f, 0.061411365866661f, 0.240083336830139f, + 0.061595637351274f, 0.240419670939446f, 0.061780165880919f, 0.240755841135979f, + 0.061964951455593f, 0.241091892123222f, 0.062149997800589f, 0.241427779197693f, + 0.062335297465324f, 0.241763532161713f, 0.062520854175091f, 0.242099151015282f, + 0.062706671655178f, 0.242434620857239f, 0.062892749905586f, 0.242769956588745f, + 0.063079081475735f, 0.243105143308640f, 0.063265666365623f, 0.243440181016922f, + 0.063452512025833f, 0.243775084614754f, 0.063639611005783f, 0.244109839200974f, + 0.063826970756054f, 0.244444444775581f, 0.064014583826065f, 0.244778916239738f, + 0.064202457666397f, 0.245113238692284f, 0.064390584826469f, 0.245447427034378f, + 0.064578965306282f, 0.245781451463699f, 0.064767606556416f, 0.246115356683731f, + 0.064956501126289f, 0.246449097990990f, 0.065145656466484f, 0.246782705187798f, + 0.065335065126419f, 0.247116148471832f, 0.065524727106094f, 0.247449472546577f, + 0.065714649856091f, 0.247782632708550f, 0.065904818475246f, 0.248115643858910f, + 0.066095255315304f, 0.248448520898819f, 0.066285938024521f, 0.248781248927116f, + 0.066476874053478f, 0.249113827943802f, 0.066668070852757f, 0.249446272850037f, + 0.066859520971775f, 0.249778553843498f, 0.067051224410534f, 0.250110685825348f, + 0.067243188619614f, 0.250442683696747f, 0.067435398697853f, 0.250774532556534f, + 0.067627869546413f, 0.251106232404709f, 0.067820593714714f, 0.251437783241272f, + 0.068013571202755f, 0.251769185066223f, 0.068206802010536f, 0.252100437879562f, + 0.068400286138058f, 0.252431541681290f, 0.068594031035900f, 0.252762526273727f, + 0.068788021802902f, 0.253093332052231f, 0.068982265889645f, 0.253423988819122f, + 0.069176770746708f, 0.253754496574402f, 0.069371521472931f, 0.254084855318069f, + 0.069566532969475f, 0.254415065050125f, 0.069761790335178f, 0.254745125770569f, + 0.069957308471203f, 0.255075037479401f, 0.070153072476387f, 0.255404800176620f, + 0.070349089801311f, 0.255734413862228f, 0.070545360445976f, 0.256063878536224f, + 0.070741884410381f, 0.256393194198608f, 0.070938661694527f, 0.256722360849380f, + 0.071135692298412f, 0.257051378488541f, 0.071332976222038f, 0.257380217313766f, + 0.071530513465405f, 0.257708936929703f, 0.071728296577930f, 0.258037507534027f, + 0.071926333010197f, 0.258365899324417f, 0.072124622762203f, 0.258694142103195f, + 0.072323165833950f, 0.259022265672684f, 0.072521962225437f, 0.259350210428238f, + 0.072721004486084f, 0.259678006172180f, 0.072920300066471f, 0.260005623102188f, + 0.073119848966599f, 0.260333120822906f, 0.073319651186466f, 0.260660469532013f, + 0.073519699275494f, 0.260987639427185f, 0.073720000684261f, 0.261314690113068f, + 0.073920547962189f, 0.261641561985016f, 0.074121348559856f, 0.261968284845352f, + 0.074322402477264f, 0.262294828891754f, 0.074523709714413f, 0.262621253728867f, + 0.074725262820721f, 0.262947499752045f, 0.074927061796188f, 0.263273626565933f, + 0.075129114091396f, 0.263599574565887f, 0.075331419706345f, 0.263925373554230f, + 0.075533971190453f, 0.264250993728638f, 0.075736775994301f, 0.264576494693756f, + 0.075939826667309f, 0.264901816844940f, 0.076143130660057f, 0.265226989984512f, + 0.076346680521965f, 0.265552014112473f, 0.076550483703613f, 0.265876859426498f, + 0.076754532754421f, 0.266201555728912f, 0.076958827674389f, 0.266526103019714f, + 0.077163375914097f, 0.266850501298904f, 0.077368170022964f, 0.267174720764160f, + 0.077573217451572f, 0.267498821020126f, 0.077778510749340f, 0.267822742462158f, + 0.077984049916267f, 0.268146485090256f, 0.078189842402935f, 0.268470078706741f, + 0.078395880758762f, 0.268793523311615f, 0.078602164983749f, 0.269116818904877f, + 0.078808702528477f, 0.269439965486526f, 0.079015478491783f, 0.269762933254242f, + 0.079222507774830f, 0.270085722208023f, 0.079429790377617f, 0.270408391952515f, + 0.079637311398983f, 0.270730882883072f, 0.079845085740089f, 0.271053224802017f, + 0.080053105950356f, 0.271375387907028f, 0.080261372029781f, 0.271697402000427f, + 0.080469883978367f, 0.272019267082214f, 0.080678641796112f, 0.272340953350067f, + 0.080887645483017f, 0.272662490606308f, 0.081096902489662f, 0.272983878850937f, + 0.081306397914886f, 0.273305088281631f, 0.081516146659851f, 0.273626148700714f, + 0.081726133823395f, 0.273947030305862f, 0.081936374306679f, 0.274267762899399f, + 0.082146860659122f, 0.274588316679001f, 0.082357585430145f, 0.274908751249313f, + 0.082568563520908f, 0.275228977203369f, 0.082779780030251f, 0.275549083948135f, + 0.082991249859333f, 0.275868982076645f, 0.083202958106995f, 0.276188760995865f, + 0.083414919674397f, 0.276508361101151f, 0.083627119660378f, 0.276827782392502f, + 0.083839565515518f, 0.277147054672241f, 0.084052257239819f, 0.277466177940369f, + 0.084265194833279f, 0.277785122394562f, 0.084478378295898f, 0.278103888034821f, + 0.084691800177097f, 0.278422504663467f, 0.084905467927456f, 0.278740972280502f, + 0.085119381546974f, 0.279059261083603f, 0.085333541035652f, 0.279377400875092f, + 0.085547938942909f, 0.279695361852646f, 0.085762590169907f, 0.280013144016266f, + 0.085977479815483f, 0.280330777168274f, 0.086192607879639f, 0.280648261308670f, + 0.086407989263535f, 0.280965566635132f, 0.086623609066010f, 0.281282693147659f, + 0.086839467287064f, 0.281599670648575f, 0.087055571377277f, 0.281916469335556f, + 0.087271921336651f, 0.282233119010925f, 0.087488517165184f, 0.282549589872360f, + 0.087705351412296f, 0.282865911722183f, 0.087922424077988f, 0.283182054758072f, + 0.088139742612839f, 0.283498018980026f, 0.088357307016850f, 0.283813834190369f, + 0.088575109839439f, 0.284129470586777f, 0.088793158531189f, 0.284444957971573f, + 0.089011445641518f, 0.284760266542435f, 0.089229971170425f, 0.285075396299362f, + 0.089448742568493f, 0.285390377044678f, 0.089667752385139f, 0.285705178976059f, + 0.089887008070946f, 0.286019802093506f, 0.090106502175331f, 0.286334276199341f, + 0.090326242148876f, 0.286648571491241f, 0.090546220541000f, 0.286962717771530f, + 0.090766437351704f, 0.287276685237885f, 0.090986892580986f, 0.287590473890305f, + 0.091207593679428f, 0.287904083728790f, 0.091428533196449f, 0.288217544555664f, + 0.091649711132050f, 0.288530826568604f, 0.091871134936810f, 0.288843959569931f, + 0.092092797160149f, 0.289156883955002f, 0.092314697802067f, 0.289469659328461f, + 0.092536836862564f, 0.289782285690308f, 0.092759214341640f, 0.290094703435898f, + 0.092981837689877f, 0.290406972169876f, 0.093204692006111f, 0.290719062089920f, + 0.093427792191505f, 0.291031002998352f, 0.093651130795479f, 0.291342735290527f, + 0.093874707818031f, 0.291654318571091f, 0.094098523259163f, 0.291965723037720f, + 0.094322577118874f, 0.292276978492737f, 0.094546869397163f, 0.292588025331497f, + 0.094771400094032f, 0.292898923158646f, 0.094996169209480f, 0.293209642171860f, + 0.095221176743507f, 0.293520182371140f, 0.095446422696114f, 0.293830573558807f, + 0.095671907067299f, 0.294140785932541f, 0.095897629857063f, 0.294450789690018f, + 0.096123591065407f, 0.294760644435883f, 0.096349790692329f, 0.295070350170136f, + 0.096576221287251f, 0.295379847288132f, 0.096802897751331f, 0.295689195394516f, + 0.097029805183411f, 0.295998334884644f, 0.097256951034069f, 0.296307325363159f, + 0.097484335303307f, 0.296616137027740f, 0.097711957991123f, 0.296924799680710f, + 0.097939811646938f, 0.297233253717422f, 0.098167903721333f, 0.297541528940201f, + 0.098396234214306f, 0.297849655151367f, 0.098624803125858f, 0.298157602548599f, + 0.098853603005409f, 0.298465341329575f, 0.099082641303539f, 0.298772931098938f, + 0.099311910569668f, 0.299080342054367f, 0.099541425704956f, 0.299387603998184f, + 0.099771171808243f, 0.299694657325745f, 0.100001148879528f, 0.300001531839371f, + 0.100231364369392f, 0.300308227539063f, 0.100461818277836f, 0.300614774227142f, + 0.100692503154278f, 0.300921112298965f, 0.100923426449299f, 0.301227301359177f, + 0.101154580712318f, 0.301533311605453f, 0.101385973393917f, 0.301839113235474f, + 0.101617597043514f, 0.302144765853882f, 0.101849451661110f, 0.302450239658356f, + 0.102081544697285f, 0.302755534648895f, 0.102313876152039f, 0.303060621023178f, + 0.102546438574791f, 0.303365558385849f, 0.102779231965542f, 0.303670316934586f, + 0.103012263774872f, 0.303974896669388f, 0.103245526552200f, 0.304279297590256f, + 0.103479020297527f, 0.304583519697189f, 0.103712752461433f, 0.304887533187866f, + 0.103946708142757f, 0.305191397666931f, 0.104180909693241f, 0.305495083332062f, + 0.104415334761143f, 0.305798590183258f, 0.104649998247623f, 0.306101888418198f, + 0.104884892702103f, 0.306405037641525f, 0.105120018124580f, 0.306708008050919f, + 0.105355374515057f, 0.307010769844055f, 0.105590961873531f, 0.307313382625580f, + 0.105826787650585f, 0.307615786790848f, 0.106062836945057f, 0.307918041944504f, + 0.106299124658108f, 0.308220088481903f, 0.106535643339157f, 0.308521956205368f, + 0.106772392988205f, 0.308823645114899f, 0.107009373605251f, 0.309125155210495f, + 0.107246585190296f, 0.309426486492157f, 0.107484027743340f, 0.309727638959885f, + 0.107721701264381f, 0.310028612613678f, 0.107959605753422f, 0.310329377651215f, + 0.108197741210461f, 0.310629993677139f, 0.108436107635498f, 0.310930401086807f, + 0.108674705028534f, 0.311230629682541f, 0.108913525938988f, 0.311530679464340f, + 0.109152585268021f, 0.311830550432205f, 0.109391868114471f, 0.312130242586136f, + 0.109631389379501f, 0.312429755926132f, 0.109871134161949f, 0.312729060649872f, + 0.110111102461815f, 0.313028186559677f, 0.110351309180260f, 0.313327133655548f, + 0.110591746866703f, 0.313625901937485f, 0.110832408070564f, 0.313924491405487f, + 0.111073300242424f, 0.314222872257233f, 0.111314415931702f, 0.314521104097366f, + 0.111555770039558f, 0.314819127321243f, 0.111797347664833f, 0.315116971731186f, + 0.112039148807526f, 0.315414607524872f, 0.112281180918217f, 0.315712094306946f, + 0.112523443996906f, 0.316009372472763f, 0.112765938043594f, 0.316306471824646f, + 0.113008655607700f, 0.316603392362595f, 0.113251596689224f, 0.316900104284287f, + 0.113494776189327f, 0.317196637392044f, 0.113738171756268f, 0.317492991685867f, + 0.113981798291206f, 0.317789167165756f, 0.114225655794144f, 0.318085134029388f, + 0.114469736814499f, 0.318380922079086f, 0.114714048802853f, 0.318676531314850f, + 0.114958584308624f, 0.318971961736679f, 0.115203343331814f, 0.319267183542252f, + 0.115448333323002f, 0.319562226533890f, 0.115693546831608f, 0.319857090711594f, + 0.115938983857632f, 0.320151746273041f, 0.116184651851654f, 0.320446223020554f, + 0.116430543363094f, 0.320740520954132f, 0.116676658391953f, 0.321034610271454f, + 0.116923004388809f, 0.321328520774841f, 0.117169573903084f, 0.321622252464294f, + 0.117416366934776f, 0.321915775537491f, 0.117663383483887f, 0.322209119796753f, + 0.117910631000996f, 0.322502255439758f, 0.118158094584942f, 0.322795242071152f, + 0.118405789136887f, 0.323088020086288f, 0.118653707206249f, 0.323380589485168f, + 0.118901848793030f, 0.323672980070114f, 0.119150213897228f, 0.323965191841125f, + 0.119398809969425f, 0.324257194995880f, 0.119647622108459f, 0.324549019336700f, + 0.119896657764912f, 0.324840664863586f, 0.120145916938782f, 0.325132101774216f, + 0.120395407080650f, 0.325423330068588f, 0.120645113289356f, 0.325714409351349f, + 0.120895043015480f, 0.326005280017853f, 0.121145196259022f, 0.326295942068100f, + 0.121395580470562f, 0.326586425304413f, 0.121646173298359f, 0.326876699924469f, + 0.121896997094154f, 0.327166795730591f, 0.122148044407368f, 0.327456712722778f, + 0.122399315237999f, 0.327746421098709f, 0.122650802135468f, 0.328035950660706f, + 0.122902512550354f, 0.328325271606445f, 0.123154446482658f, 0.328614413738251f, + 0.123406603932381f, 0.328903347253799f, 0.123658977448940f, 0.329192101955414f, + 0.123911574482918f, 0.329480648040771f, 0.124164395034313f, 0.329769015312195f, + 0.124417431652546f, 0.330057173967361f, 0.124670691788197f, 0.330345153808594f, + 0.124924175441265f, 0.330632925033569f, 0.125177875161171f, 0.330920487642288f, + 0.125431805849075f, 0.331207901239395f, 0.125685945153236f, 0.331495076417923f, + 0.125940307974815f, 0.331782072782516f, 0.126194894313812f, 0.332068890333176f, + 0.126449704170227f, 0.332355499267578f, 0.126704722642899f, 0.332641899585724f, + 0.126959964632988f, 0.332928121089935f, 0.127215430140495f, 0.333214133977890f, + 0.127471104264259f, 0.333499968051910f, 0.127727001905441f, 0.333785593509674f, + 0.127983123064041f, 0.334071010351181f, 0.128239467740059f, 0.334356248378754f, + 0.128496021032333f, 0.334641307592392f, 0.128752797842026f, 0.334926128387451f, + 0.129009798169136f, 0.335210770368576f, 0.129267007112503f, 0.335495233535767f, + 0.129524439573288f, 0.335779488086700f, 0.129782080650330f, 0.336063534021378f, + 0.130039945244789f, 0.336347371339798f, 0.130298033356667f, 0.336631029844284f, + 0.130556344985962f, 0.336914509534836f, 0.130814850330353f, 0.337197750806808f, + 0.131073594093323f, 0.337480813264847f, 0.131332546472549f, 0.337763696908951f, + 0.131591722369194f, 0.338046342134476f, 0.131851106882095f, 0.338328808546066f, + 0.132110700011253f, 0.338611096143723f, 0.132370531558990f, 0.338893145322800f, + 0.132630556821823f, 0.339175015687943f, 0.132890805602074f, 0.339456677436829f, + 0.133151277899742f, 0.339738160371780f, 0.133411958813667f, 0.340019434690475f, + 0.133672863245010f, 0.340300500392914f, 0.133933976292610f, 0.340581357479095f, + 0.134195312857628f, 0.340862035751343f, 0.134456858038902f, 0.341142505407333f, + 0.134718611836433f, 0.341422766447067f, 0.134980589151382f, 0.341702848672867f, + 0.135242775082588f, 0.341982692480087f, 0.135505184531212f, 0.342262357473373f, + 0.135767802596092f, 0.342541843652725f, 0.136030644178391f, 0.342821091413498f, + 0.136293679475784f, 0.343100160360336f, 0.136556953191757f, 0.343379020690918f, + 0.136820420622826f, 0.343657672405243f, 0.137084111571312f, 0.343936115503311f, + 0.137348011136055f, 0.344214379787445f, 0.137612134218216f, 0.344492435455322f, + 0.137876465916634f, 0.344770282506943f, 0.138141006231308f, 0.345047920942307f, + 0.138405755162239f, 0.345325350761414f, 0.138670727610588f, 0.345602601766586f, + 0.138935908675194f, 0.345879614353180f, 0.139201298356056f, 0.346156448125839f, + 0.139466896653175f, 0.346433073282242f, 0.139732718467712f, 0.346709519624710f, + 0.139998748898506f, 0.346985727548599f, 0.140264987945557f, 0.347261756658554f, + 0.140531435608864f, 0.347537547349930f, 0.140798106789589f, 0.347813159227371f, + 0.141064971685410f, 0.348088562488556f, 0.141332060098648f, 0.348363757133484f, + 0.141599357128143f, 0.348638743162155f, 0.141866862773895f, 0.348913550376892f, + 0.142134591937065f, 0.349188119173050f, 0.142402514815331f, 0.349462509155273f, + 0.142670661211014f, 0.349736660718918f, 0.142939001321793f, 0.350010633468628f, + 0.143207564949989f, 0.350284397602081f, 0.143476337194443f, 0.350557953119278f, + 0.143745318055153f, 0.350831300020218f, 0.144014507532120f, 0.351104438304901f, + 0.144283905625343f, 0.351377367973328f, 0.144553512334824f, 0.351650089025497f, + 0.144823327660561f, 0.351922631263733f, 0.145093351602554f, 0.352194935083389f, + 0.145363584160805f, 0.352467030286789f, 0.145634025335312f, 0.352738946676254f, + 0.145904675126076f, 0.353010624647141f, 0.146175548434258f, 0.353282123804092f, + 0.146446615457535f, 0.353553384542465f, 0.146717891097069f, 0.353824466466904f, + 0.146989375352860f, 0.354095309972763f, 0.147261068224907f, 0.354365974664688f, + 0.147532954812050f, 0.354636400938034f, 0.147805064916611f, 0.354906648397446f, + 0.148077383637428f, 0.355176687240601f, 0.148349896073341f, 0.355446487665176f, + 0.148622632026672f, 0.355716109275818f, 0.148895561695099f, 0.355985492467880f, + 0.149168699979782f, 0.356254696846008f, 0.149442046880722f, 0.356523662805557f, + 0.149715602397919f, 0.356792420148849f, 0.149989366531372f, 0.357060998678207f, + 0.150263324379921f, 0.357329338788986f, 0.150537505745888f, 0.357597470283508f, + 0.150811880826950f, 0.357865422964096f, 0.151086464524269f, 0.358133137226105f, + 0.151361241936684f, 0.358400642871857f, 0.151636242866516f, 0.358667939901352f, + 0.151911437511444f, 0.358935028314590f, 0.152186840772629f, 0.359201908111572f, + 0.152462437748909f, 0.359468549489975f, 0.152738258242607f, 0.359735012054443f, + 0.153014272451401f, 0.360001266002655f, 0.153290495276451f, 0.360267281532288f, + 0.153566911816597f, 0.360533088445663f, 0.153843536973000f, 0.360798716545105f, + 0.154120370745659f, 0.361064106225967f, 0.154397398233414f, 0.361329287290573f, + 0.154674649238586f, 0.361594229936600f, 0.154952079057693f, 0.361858993768692f, + 0.155229732394218f, 0.362123548984528f, 0.155507579445839f, 0.362387865781784f, + 0.155785620212555f, 0.362651973962784f, 0.156063869595528f, 0.362915903329849f, + 0.156342327594757f, 0.363179564476013f, 0.156620979309082f, 0.363443046808243f, + 0.156899839639664f, 0.363706320524216f, 0.157178908586502f, 0.363969355821610f, + 0.157458171248436f, 0.364232182502747f, 0.157737627625465f, 0.364494800567627f, + 0.158017292618752f, 0.364757210016251f, 0.158297166228294f, 0.365019410848618f, + 0.158577233552933f, 0.365281373262405f, 0.158857494592667f, 0.365543156862259f, + 0.159137964248657f, 0.365804702043533f, 0.159418627619743f, 0.366066008806229f, + 0.159699499607086f, 0.366327136754990f, 0.159980565309525f, 0.366588026285172f, + 0.160261839628220f, 0.366848707199097f, 0.160543307662010f, 0.367109179496765f, + 0.160824984312058f, 0.367369443178177f, 0.161106839776039f, 0.367629468441010f, + 0.161388918757439f, 0.367889285087585f, 0.161671176552773f, 0.368148893117905f, + 0.161953642964363f, 0.368408292531967f, 0.162236317992210f, 0.368667453527451f, + 0.162519171833992f, 0.368926405906677f, 0.162802234292030f, 0.369185149669647f, + 0.163085505366325f, 0.369443655014038f, 0.163368955254555f, 0.369701951742172f, + 0.163652613759041f, 0.369960039854050f, 0.163936465978622f, 0.370217919349670f, + 0.164220526814461f, 0.370475560426712f, 0.164504766464233f, 0.370732992887497f, + 0.164789214730263f, 0.370990216732025f, 0.165073871612549f, 0.371247202157974f, + 0.165358707308769f, 0.371503978967667f, 0.165643751621246f, 0.371760547161102f, + 0.165928974747658f, 0.372016876935959f, 0.166214406490326f, 0.372272998094559f, + 0.166500031948090f, 0.372528880834579f, 0.166785866022110f, 0.372784584760666f, + 0.167071878910065f, 0.373040050268173f, 0.167358100414276f, 0.373295277357101f, + 0.167644515633583f, 0.373550295829773f, 0.167931124567986f, 0.373805105686188f, + 0.168217927217484f, 0.374059677124023f, 0.168504923582077f, 0.374314039945602f, + 0.168792113661766f, 0.374568194150925f, 0.169079497456551f, 0.374822109937668f, + 0.169367074966431f, 0.375075817108154f, 0.169654861092567f, 0.375329315662384f, + 0.169942826032639f, 0.375582575798035f, 0.170230999588966f, 0.375835597515106f, + 0.170519351959229f, 0.376088410615921f, 0.170807912945747f, 0.376341015100479f, + 0.171096652746201f, 0.376593410968781f, 0.171385586261749f, 0.376845568418503f, + 0.171674728393555f, 0.377097487449646f, 0.171964049339294f, 0.377349197864532f, + 0.172253578901291f, 0.377600699663162f, 0.172543287277222f, 0.377851963043213f, + 0.172833189368248f, 0.378102988004684f, 0.173123285174370f, 0.378353834152222f, + 0.173413574695587f, 0.378604412078857f, 0.173704057931900f, 0.378854811191559f, + 0.173994734883308f, 0.379104942083359f, 0.174285605549812f, 0.379354894161224f, + 0.174576655030251f, 0.379604607820511f, 0.174867913126946f, 0.379854083061218f, + 0.175159350037575f, 0.380103349685669f, 0.175450980663300f, 0.380352377891541f, + 0.175742805004120f, 0.380601197481155f, 0.176034808158875f, 0.380849778652191f, + 0.176327019929886f, 0.381098151206970f, 0.176619410514832f, 0.381346285343170f, + 0.176911994814873f, 0.381594210863113f, 0.177204772830009f, 0.381841897964478f, + 0.177497729659081f, 0.382089376449585f, 0.177790880203247f, 0.382336616516113f, + 0.178084224462509f, 0.382583618164063f, 0.178377762436867f, 0.382830440998077f, + 0.178671479225159f, 0.383076995611191f, 0.178965389728546f, 0.383323341608047f, + 0.179259493947029f, 0.383569449186325f, 0.179553776979446f, 0.383815348148346f, + 0.179848253726959f, 0.384061008691788f, 0.180142924189568f, 0.384306460618973f, + 0.180437773466110f, 0.384551674127579f, 0.180732816457748f, 0.384796649217606f, + 0.181028053164482f, 0.385041415691376f, 0.181323468685150f, 0.385285943746567f, + 0.181619063019753f, 0.385530263185501f, 0.181914865970612f, 0.385774344205856f, + 0.182210832834244f, 0.386018186807632f, 0.182507008314133f, 0.386261820793152f, + 0.182803362607956f, 0.386505216360092f, 0.183099895715714f, 0.386748403310776f, + 0.183396622538567f, 0.386991351842880f, 0.183693528175354f, 0.387234061956406f, + 0.183990627527237f, 0.387476563453674f, 0.184287920594215f, 0.387718826532364f, + 0.184585392475128f, 0.387960851192474f, 0.184883043169975f, 0.388202667236328f, + 0.185180887579918f, 0.388444244861603f, 0.185478910803795f, 0.388685584068298f, + 0.185777112841606f, 0.388926714658737f, 0.186075508594513f, 0.389167606830597f, + 0.186374098062515f, 0.389408260583878f, 0.186672851443291f, 0.389648675918579f, + 0.186971798539162f, 0.389888882637024f, 0.187270939350128f, 0.390128880739212f, + 0.187570258975029f, 0.390368610620499f, 0.187869757413864f, 0.390608131885529f, + 0.188169434666634f, 0.390847414731979f, 0.188469305634499f, 0.391086459159851f, + 0.188769355416298f, 0.391325294971466f, 0.189069598913193f, 0.391563892364502f, + 0.189370006322861f, 0.391802251338959f, 0.189670607447624f, 0.392040401697159f, + 0.189971387386322f, 0.392278283834457f, 0.190272361040115f, 0.392515957355499f, + 0.190573498606682f, 0.392753422260284f, 0.190874829888344f, 0.392990618944168f, + 0.191176339983940f, 0.393227607011795f, 0.191478043794632f, 0.393464356660843f, + 0.191779911518097f, 0.393700867891312f, 0.192081972956657f, 0.393937170505524f, + 0.192384198307991f, 0.394173204898834f, 0.192686617374420f, 0.394409030675888f, + 0.192989215254784f, 0.394644618034363f, 0.193292006850243f, 0.394879996776581f, + 0.193594962358475f, 0.395115107297897f, 0.193898096680641f, 0.395350009202957f, + 0.194201424717903f, 0.395584672689438f, 0.194504916667938f, 0.395819097757339f, + 0.194808602333069f, 0.396053284406662f, 0.195112451910973f, 0.396287262439728f, + 0.195416495203972f, 0.396520972251892f, 0.195720717310905f, 0.396754473447800f, + 0.196025103330612f, 0.396987736225128f, 0.196329683065414f, 0.397220760583878f, + 0.196634441614151f, 0.397453576326370f, 0.196939364075661f, 0.397686123847961f, + 0.197244480252266f, 0.397918462753296f, 0.197549775242805f, 0.398150533437729f, + 0.197855234146118f, 0.398382395505905f, 0.198160871863365f, 0.398614019155502f, + 0.198466703295708f, 0.398845434188843f, 0.198772698640823f, 0.399076581001282f, + 0.199078872799873f, 0.399307489395142f, 0.199385225772858f, 0.399538189172745f, + 0.199691757559776f, 0.399768620729446f, 0.199998468160629f, 0.399998843669891f, + 0.200305357575417f, 0.400228828191757f, 0.200612410902977f, 0.400458574295044f, + 0.200919643044472f, 0.400688081979752f, 0.201227053999901f, 0.400917351245880f, + 0.201534643769264f, 0.401146411895752f, 0.201842412352562f, 0.401375204324722f, + 0.202150344848633f, 0.401603758335114f, 0.202458456158638f, 0.401832103729248f, + 0.202766746282578f, 0.402060180902481f, 0.203075215220451f, 0.402288049459457f, + 0.203383848071098f, 0.402515679597855f, 0.203692659735680f, 0.402743041515350f, + 0.204001650214195f, 0.402970194816589f, 0.204310819506645f, 0.403197109699249f, + 0.204620152711868f, 0.403423786163330f, 0.204929664731026f, 0.403650224208832f, + 0.205239340662956f, 0.403876423835754f, 0.205549195408821f, 0.404102355241776f, + 0.205859228968620f, 0.404328078031540f, 0.206169426441193f, 0.404553562402725f, + 0.206479802727699f, 0.404778808355331f, 0.206790357828140f, 0.405003815889359f, + 0.207101076841354f, 0.405228585004807f, 0.207411959767342f, 0.405453115701675f, + 0.207723021507263f, 0.405677437782288f, 0.208034262061119f, 0.405901491641998f, + 0.208345666527748f, 0.406125307083130f, 0.208657249808311f, 0.406348884105682f, + 0.208969011902809f, 0.406572192907333f, 0.209280923008919f, 0.406795293092728f, + 0.209593027830124f, 0.407018154859543f, 0.209905281662941f, 0.407240778207779f, + 0.210217714309692f, 0.407463163137436f, 0.210530325770378f, 0.407685309648514f, + 0.210843101143837f, 0.407907217741013f, 0.211156040430069f, 0.408128857612610f, + 0.211469158530235f, 0.408350288867950f, 0.211782455444336f, 0.408571451902390f, + 0.212095901370049f, 0.408792406320572f, 0.212409526109695f, 0.409013092517853f, + 0.212723329663277f, 0.409233570098877f, 0.213037282228470f, 0.409453779459000f, + 0.213351413607597f, 0.409673750400543f, 0.213665723800659f, 0.409893482923508f, + 0.213980183005333f, 0.410112977027893f, 0.214294821023941f, 0.410332232713699f, + 0.214609622955322f, 0.410551249980927f, 0.214924603700638f, 0.410770028829575f, + 0.215239733457565f, 0.410988569259644f, 0.215555042028427f, 0.411206841468811f, + 0.215870529413223f, 0.411424905061722f, 0.216186165809631f, 0.411642700433731f, + 0.216501981019974f, 0.411860257387161f, 0.216817945241928f, 0.412077575922012f, + 0.217134088277817f, 0.412294656038284f, 0.217450410127640f, 0.412511497735977f, + 0.217766880989075f, 0.412728071212769f, 0.218083515763283f, 0.412944436073303f, + 0.218400329351425f, 0.413160532712936f, 0.218717306852341f, 0.413376390933990f, + 0.219034433364868f, 0.413592010736465f, 0.219351738691330f, 0.413807392120361f, + 0.219669207930565f, 0.414022535085678f, 0.219986841082573f, 0.414237409830093f, + 0.220304638147354f, 0.414452046155930f, 0.220622614026070f, 0.414666473865509f, + 0.220940738916397f, 0.414880603551865f, 0.221259027719498f, 0.415094524621964f, + 0.221577480435371f, 0.415308207273483f, 0.221896097064018f, 0.415521621704102f, + 0.222214877605438f, 0.415734797716141f, 0.222533836960793f, 0.415947735309601f, + 0.222852945327759f, 0.416160434484482f, 0.223172217607498f, 0.416372895240784f, + 0.223491653800011f, 0.416585087776184f, 0.223811239004135f, 0.416797041893005f, + 0.224131003022194f, 0.417008757591248f, 0.224450930953026f, 0.417220205068588f, + 0.224771007895470f, 0.417431443929672f, 0.225091263651848f, 0.417642414569855f, + 0.225411668419838f, 0.417853146791458f, 0.225732237100601f, 0.418063640594482f, + 0.226052969694138f, 0.418273866176605f, 0.226373866200447f, 0.418483853340149f, + 0.226694911718369f, 0.418693602085114f, 0.227016136050224f, 0.418903112411499f, + 0.227337509393692f, 0.419112354516983f, 0.227659046649933f, 0.419321358203888f, + 0.227980732917786f, 0.419530123472214f, 0.228302597999573f, 0.419738620519638f, + 0.228624612092972f, 0.419946908950806f, 0.228946775197983f, 0.420154929161072f, + 0.229269117116928f, 0.420362681150436f, 0.229591608047485f, 0.420570224523544f, + 0.229914262890816f, 0.420777499675751f, 0.230237081646919f, 0.420984506607056f, + 0.230560049414635f, 0.421191304922104f, 0.230883181095123f, 0.421397835016251f, + 0.231206461787224f, 0.421604126691818f, 0.231529906392097f, 0.421810150146484f, + 0.231853514909744f, 0.422015935182571f, 0.232177272439003f, 0.422221481800079f, + 0.232501193881035f, 0.422426789999008f, 0.232825264334679f, 0.422631829977036f, + 0.233149498701096f, 0.422836631536484f, 0.233473882079124f, 0.423041164875031f, + 0.233798429369926f, 0.423245459794998f, 0.234123140573502f, 0.423449516296387f, + 0.234448000788689f, 0.423653304576874f, 0.234773010015488f, 0.423856884241104f, + 0.235098183155060f, 0.424060165882111f, 0.235423520207405f, 0.424263238906860f, + 0.235749006271362f, 0.424466013908386f, 0.236074641346931f, 0.424668580293655f, + 0.236400425434113f, 0.424870878458023f, 0.236726388335228f, 0.425072938203812f, + 0.237052485346794f, 0.425274729728699f, 0.237378746271133f, 0.425476282835007f, + 0.237705156207085f, 0.425677597522736f, 0.238031730055809f, 0.425878643989563f, + 0.238358452916145f, 0.426079452037811f, 0.238685324788094f, 0.426279991865158f, + 0.239012360572815f, 0.426480293273926f, 0.239339530467987f, 0.426680356264114f, + 0.239666879177094f, 0.426880151033401f, 0.239994361996651f, 0.427079707384110f, + 0.240322008728981f, 0.427278995513916f, 0.240649804472923f, 0.427478045225143f, + 0.240977749228477f, 0.427676826715469f, 0.241305842995644f, 0.427875369787216f, + 0.241634100675583f, 0.428073674440384f, 0.241962507367134f, 0.428271710872650f, + 0.242291063070297f, 0.428469479084015f, 0.242619767785072f, 0.428667008876801f, + 0.242948621511459f, 0.428864300251007f, 0.243277639150620f, 0.429061323404312f, + 0.243606805801392f, 0.429258108139038f, 0.243936106562614f, 0.429454624652863f, + 0.244265571236610f, 0.429650902748108f, 0.244595184922218f, 0.429846942424774f, + 0.244924947619438f, 0.430042684078217f, 0.245254859328270f, 0.430238217115402f, + 0.245584934949875f, 0.430433481931686f, 0.245915144681931f, 0.430628478527069f, + 0.246245503425598f, 0.430823236703873f, 0.246576011180878f, 0.431017726659775f, + 0.246906682848930f, 0.431211978197098f, 0.247237488627434f, 0.431405961513519f, + 0.247568443417549f, 0.431599706411362f, 0.247899547219276f, 0.431793183088303f, + 0.248230814933777f, 0.431986421346664f, 0.248562216758728f, 0.432179391384125f, + 0.248893767595291f, 0.432372123003006f, 0.249225467443466f, 0.432564586400986f, + 0.249557301402092f, 0.432756811380386f, 0.249889299273491f, 0.432948768138886f, + 0.250221431255341f, 0.433140486478806f, 0.250553727149963f, 0.433331936597824f, + 0.250886172056198f, 0.433523118495941f, 0.251218736171722f, 0.433714061975479f, + 0.251551479101181f, 0.433904737234116f, 0.251884341239929f, 0.434095174074173f, + 0.252217382192612f, 0.434285342693329f, 0.252550542354584f, 0.434475272893906f, + 0.252883851528168f, 0.434664934873581f, 0.253217309713364f, 0.434854328632355f, + 0.253550916910172f, 0.435043483972549f, 0.253884643316269f, 0.435232400894165f, + 0.254218548536301f, 0.435421019792557f, 0.254552572965622f, 0.435609430074692f, + 0.254886746406555f, 0.435797542333603f, 0.255221068859100f, 0.435985416173935f, + 0.255555540323257f, 0.436173021793365f, 0.255890160799026f, 0.436360388994217f, + 0.256224930286407f, 0.436547487974167f, 0.256559818983078f, 0.436734348535538f, + 0.256894856691360f, 0.436920911073685f, 0.257230043411255f, 0.437107264995575f, + 0.257565379142761f, 0.437293320894241f, 0.257900834083557f, 0.437479138374329f, + 0.258236467838287f, 0.437664687633514f, 0.258572220802307f, 0.437849998474121f, + 0.258908122777939f, 0.438035041093826f, 0.259244143962860f, 0.438219845294952f, + 0.259580343961716f, 0.438404351472855f, 0.259916663169861f, 0.438588619232178f, + 0.260253131389618f, 0.438772648572922f, 0.260589718818665f, 0.438956409692764f, + 0.260926485061646f, 0.439139902591705f, 0.261263370513916f, 0.439323127269745f, + 0.261600375175476f, 0.439506113529205f, 0.261937558650970f, 0.439688831567764f, + 0.262274861335754f, 0.439871311187744f, 0.262612313032150f, 0.440053492784500f, + 0.262949883937836f, 0.440235435962677f, 0.263287603855133f, 0.440417140722275f, + 0.263625472784042f, 0.440598547458649f, 0.263963490724564f, 0.440779715776443f, + 0.264301627874374f, 0.440960645675659f, 0.264639914035797f, 0.441141277551651f, + 0.264978319406509f, 0.441321671009064f, 0.265316903591156f, 0.441501796245575f, + 0.265655577182770f, 0.441681683063507f, 0.265994429588318f, 0.441861271858215f, + 0.266333401203156f, 0.442040622234344f, 0.266672492027283f, 0.442219734191895f, + 0.267011761665344f, 0.442398548126221f, 0.267351150512695f, 0.442577123641968f, + 0.267690658569336f, 0.442755430936813f, 0.268030315637589f, 0.442933470010757f, + 0.268370121717453f, 0.443111270666122f, 0.268710047006607f, 0.443288803100586f, + 0.269050091505051f, 0.443466067314148f, 0.269390314817429f, 0.443643063306808f, + 0.269730657339096f, 0.443819820880890f, 0.270071119070053f, 0.443996280431747f, + 0.270411729812622f, 0.444172531366348f, 0.270752459764481f, 0.444348484277725f, + 0.271093338727951f, 0.444524168968201f, 0.271434366703033f, 0.444699615240097f, + 0.271775513887405f, 0.444874793291092f, 0.272116780281067f, 0.445049703121185f, + 0.272458195686340f, 0.445224374532700f, 0.272799760103226f, 0.445398747920990f, + 0.273141443729401f, 0.445572882890701f, 0.273483246564865f, 0.445746749639511f, + 0.273825198411942f, 0.445920348167419f, 0.274167299270630f, 0.446093708276749f, + 0.274509519338608f, 0.446266770362854f, 0.274851858615875f, 0.446439594030380f, + 0.275194346904755f, 0.446612149477005f, 0.275536954402924f, 0.446784436702728f, + 0.275879681110382f, 0.446956485509872f, 0.276222556829453f, 0.447128236293793f, + 0.276565581560135f, 0.447299748659134f, 0.276908725500107f, 0.447470992803574f, + 0.277251988649368f, 0.447641968727112f, 0.277595400810242f, 0.447812676429749f, + 0.277938932180405f, 0.447983115911484f, 0.278282582759857f, 0.448153316974640f, + 0.278626382350922f, 0.448323249816895f, 0.278970301151276f, 0.448492884635925f, + 0.279314368963242f, 0.448662281036377f, 0.279658555984497f, 0.448831409215927f, + 0.280002862215042f, 0.449000298976898f, 0.280347317457199f, 0.449168890714645f, + 0.280691891908646f, 0.449337244033813f, 0.281036585569382f, 0.449505299329758f, + 0.281381398439407f, 0.449673116207123f, 0.281726360321045f, 0.449840664863586f, + 0.282071471214294f, 0.450007945299149f, 0.282416671514511f, 0.450174957513809f, + 0.282762020826340f, 0.450341701507568f, 0.283107489347458f, 0.450508207082748f, + 0.283453077077866f, 0.450674414634705f, 0.283798813819885f, 0.450840383768082f, + 0.284144669771194f, 0.451006084680557f, 0.284490644931793f, 0.451171487569809f, + 0.284836769104004f, 0.451336652040482f, 0.285182982683182f, 0.451501548290253f, + 0.285529345273972f, 0.451666176319122f, 0.285875827074051f, 0.451830536127090f, + 0.286222457885742f, 0.451994657516479f, 0.286569178104401f, 0.452158480882645f, + 0.286916047334671f, 0.452322036027908f, 0.287263035774231f, 0.452485352754593f, + 0.287610173225403f, 0.452648371458054f, 0.287957400083542f, 0.452811151742935f, + 0.288304775953293f, 0.452973634004593f, 0.288652241230011f, 0.453135877847672f, + 0.288999855518341f, 0.453297853469849f, 0.289347589015961f, 0.453459560871124f, + 0.289695471525192f, 0.453621000051498f, 0.290043443441391f, 0.453782171010971f, + 0.290391564369202f, 0.453943043947220f, 0.290739774703979f, 0.454103678464890f, + 0.291088134050369f, 0.454264044761658f, 0.291436612606049f, 0.454424172639847f, + 0.291785210371017f, 0.454584002494812f, 0.292133957147598f, 0.454743564128876f, + 0.292482793331146f, 0.454902857542038f, 0.292831748723984f, 0.455061882734299f, + 0.293180853128433f, 0.455220639705658f, 0.293530046939850f, 0.455379128456116f, + 0.293879389762878f, 0.455537378787994f, 0.294228851795197f, 0.455695331096649f, + 0.294578403234482f, 0.455853015184402f, 0.294928103685379f, 0.456010431051254f, + 0.295277923345566f, 0.456167578697205f, 0.295627862215042f, 0.456324487924576f, + 0.295977920293808f, 0.456481099128723f, 0.296328097581863f, 0.456637442111969f, + 0.296678394079208f, 0.456793516874313f, 0.297028809785843f, 0.456949323415756f, + 0.297379344701767f, 0.457104891538620f, 0.297729998826981f, 0.457260161638260f, + 0.298080772161484f, 0.457415163516998f, 0.298431664705276f, 0.457569897174835f, + 0.298782676458359f, 0.457724362611771f, 0.299133807420731f, 0.457878559827805f, + 0.299485057592392f, 0.458032488822937f, 0.299836426973343f, 0.458186149597168f, + 0.300187885761261f, 0.458339542150497f, 0.300539493560791f, 0.458492636680603f, + 0.300891220569611f, 0.458645492792130f, 0.301243066787720f, 0.458798080682755f, + 0.301595002412796f, 0.458950400352478f, 0.301947087049484f, 0.459102421998978f, + 0.302299261093140f, 0.459254205226898f, 0.302651554346085f, 0.459405690431595f, + 0.303003966808319f, 0.459556937217712f, 0.303356528282166f, 0.459707885980606f, + 0.303709149360657f, 0.459858566522598f, 0.304061919450760f, 0.460008978843689f, + 0.304414808750153f, 0.460159152746201f, 0.304767817258835f, 0.460309028625488f, + 0.305120915174484f, 0.460458606481552f, 0.305474132299423f, 0.460607945919037f, + 0.305827468633652f, 0.460757017135620f, 0.306180924177170f, 0.460905820131302f, + 0.306534498929977f, 0.461054325103760f, 0.306888192892075f, 0.461202591657639f, + 0.307241976261139f, 0.461350560188293f, 0.307595878839493f, 0.461498260498047f, + 0.307949900627136f, 0.461645722389221f, 0.308304041624069f, 0.461792886257172f, + 0.308658272027969f, 0.461939752101898f, 0.309012651443481f, 0.462086379528046f, + 0.309367120265961f, 0.462232738733292f, 0.309721708297729f, 0.462378799915314f, + 0.310076385736465f, 0.462524622678757f, 0.310431212186813f, 0.462670147418976f, + 0.310786128044128f, 0.462815403938293f, 0.311141163110733f, 0.462960392236710f, + 0.311496287584305f, 0.463105112314224f, 0.311851561069489f, 0.463249564170837f, + 0.312206923961639f, 0.463393747806549f, 0.312562376260757f, 0.463537633419037f, + 0.312917977571487f, 0.463681250810623f, 0.313273668289185f, 0.463824629783630f, + 0.313629478216171f, 0.463967710733414f, 0.313985377550125f, 0.464110493659973f, + 0.314341396093369f, 0.464253038167953f, 0.314697533845901f, 0.464395314455032f, + 0.315053790807724f, 0.464537292718887f, 0.315410137176514f, 0.464679002761841f, + 0.315766572952271f, 0.464820444583893f, 0.316123157739639f, 0.464961618185043f, + 0.316479831933975f, 0.465102523565292f, 0.316836595535278f, 0.465243130922318f, + 0.317193508148193f, 0.465383470058441f, 0.317550510168076f, 0.465523540973663f, + 0.317907601594925f, 0.465663343667984f, 0.318264812231064f, 0.465802878141403f, + 0.318622142076492f, 0.465942144393921f, 0.318979561328888f, 0.466081112623215f, + 0.319337099790573f, 0.466219812631607f, 0.319694727659225f, 0.466358244419098f, + 0.320052474737167f, 0.466496407985687f, 0.320410341024399f, 0.466634273529053f, + 0.320768296718597f, 0.466771900653839f, 0.321126341819763f, 0.466909229755402f, + 0.321484506130219f, 0.467046260833740f, 0.321842789649963f, 0.467183053493500f, + 0.322201162576675f, 0.467319577932358f, 0.322559654712677f, 0.467455804347992f, + 0.322918236255646f, 0.467591762542725f, 0.323276937007904f, 0.467727422714233f, + 0.323635727167130f, 0.467862844467163f, 0.323994606733322f, 0.467997968196869f, + 0.324353635311127f, 0.468132823705673f, 0.324712723493576f, 0.468267410993576f, + 0.325071930885315f, 0.468401730060577f, 0.325431257486343f, 0.468535751104355f, + 0.325790673494339f, 0.468669503927231f, 0.326150178909302f, 0.468802988529205f, + 0.326509803533554f, 0.468936175107956f, 0.326869517564774f, 0.469069123268127f, + 0.327229350805283f, 0.469201773405075f, 0.327589273452759f, 0.469334155321121f, + 0.327949285507202f, 0.469466239213943f, 0.328309416770935f, 0.469598054885864f, + 0.328669637441635f, 0.469729602336884f, 0.329029977321625f, 0.469860881567001f, + 0.329390406608582f, 0.469991862773895f, 0.329750925302505f, 0.470122605562210f, + 0.330111563205719f, 0.470253020524979f, 0.330472290515900f, 0.470383197069168f, + 0.330833107233047f, 0.470513075590134f, 0.331194043159485f, 0.470642685890198f, + 0.331555068492889f, 0.470772027969360f, 0.331916213035584f, 0.470901101827621f, + 0.332277417182922f, 0.471029877662659f, 0.332638740539551f, 0.471158385276794f, + 0.333000183105469f, 0.471286594867706f, 0.333361685276031f, 0.471414536237717f, + 0.333723306655884f, 0.471542209386826f, 0.334085017442703f, 0.471669614315033f, + 0.334446847438812f, 0.471796721220016f, 0.334808766841888f, 0.471923559904099f, + 0.335170775651932f, 0.472050130367279f, 0.335532873868942f, 0.472176402807236f, + 0.335895091295242f, 0.472302407026291f, 0.336257368326187f, 0.472428143024445f, + 0.336619764566422f, 0.472553610801697f, 0.336982280015945f, 0.472678780555725f, + 0.337344855070114f, 0.472803652286530f, 0.337707549333572f, 0.472928285598755f, + 0.338070303201675f, 0.473052620887756f, 0.338433176279068f, 0.473176687955856f, + 0.338796168565750f, 0.473300457000732f, 0.339159220457077f, 0.473423957824707f, + 0.339522391557693f, 0.473547190427780f, 0.339885622262955f, 0.473670125007629f, + 0.340248972177505f, 0.473792791366577f, 0.340612411499023f, 0.473915189504623f, + 0.340975970029831f, 0.474037289619446f, 0.341339588165283f, 0.474159121513367f, + 0.341703325510025f, 0.474280685186386f, 0.342067122459412f, 0.474401950836182f, + 0.342431038618088f, 0.474522948265076f, 0.342795044183731f, 0.474643647670746f, + 0.343159139156342f, 0.474764078855515f, 0.343523323535919f, 0.474884241819382f, + 0.343887597322464f, 0.475004136562347f, 0.344251960515976f, 0.475123733282089f, + 0.344616413116455f, 0.475243031978607f, 0.344980984926224f, 0.475362062454224f, + 0.345345616340637f, 0.475480824708939f, 0.345710366964340f, 0.475599318742752f, + 0.346075177192688f, 0.475717514753342f, 0.346440106630325f, 0.475835442543030f, + 0.346805095672607f, 0.475953072309494f, 0.347170203924179f, 0.476070433855057f, + 0.347535371780396f, 0.476187497377396f, 0.347900658845901f, 0.476304292678833f, + 0.348266035318375f, 0.476420819759369f, 0.348631471395493f, 0.476537048816681f, + 0.348997026681900f, 0.476653009653091f, 0.349362671375275f, 0.476768702268600f, + 0.349728375673294f, 0.476884096860886f, 0.350094199180603f, 0.476999223232269f, + 0.350460082292557f, 0.477114051580429f, 0.350826084613800f, 0.477228611707687f, + 0.351192146539688f, 0.477342873811722f, 0.351558297872543f, 0.477456867694855f, + 0.351924568414688f, 0.477570593357086f, 0.352290898561478f, 0.477684020996094f, + 0.352657318115234f, 0.477797180414200f, 0.353023827075958f, 0.477910041809082f, + 0.353390425443649f, 0.478022634983063f, 0.353757113218308f, 0.478134930133820f, + 0.354123860597610f, 0.478246957063675f, 0.354490727186203f, 0.478358715772629f, + 0.354857653379440f, 0.478470176458359f, 0.355224698781967f, 0.478581339120865f, + 0.355591803789139f, 0.478692263364792f, 0.355958998203278f, 0.478802859783173f, + 0.356326282024384f, 0.478913217782974f, 0.356693625450134f, 0.479023247957230f, + 0.357061088085175f, 0.479133039712906f, 0.357428610324860f, 0.479242533445358f, + 0.357796221971512f, 0.479351729154587f, 0.358163923025131f, 0.479460656642914f, + 0.358531713485718f, 0.479569315910339f, 0.358899593353271f, 0.479677677154541f, + 0.359267532825470f, 0.479785770177841f, 0.359635561704636f, 0.479893565177917f, + 0.360003679990768f, 0.480001062154770f, 0.360371887683868f, 0.480108320713043f, + 0.360740154981613f, 0.480215251445770f, 0.361108511686325f, 0.480321943759918f, + 0.361476957798004f, 0.480428308248520f, 0.361845493316650f, 0.480534434318542f, + 0.362214088439941f, 0.480640232563019f, 0.362582772970200f, 0.480745792388916f, + 0.362951546907425f, 0.480851024389267f, 0.363320380449295f, 0.480956017971039f, + 0.363689333200455f, 0.481060713529587f, 0.364058345556259f, 0.481165111064911f, + 0.364427417516708f, 0.481269240379334f, 0.364796578884125f, 0.481373071670532f, + 0.365165829658508f, 0.481476634740829f, 0.365535169839859f, 0.481579899787903f, + 0.365904569625854f, 0.481682896614075f, 0.366274058818817f, 0.481785595417023f, + 0.366643607616425f, 0.481888025999069f, 0.367013275623322f, 0.481990188360214f, + 0.367382973432541f, 0.482092022895813f, 0.367752790451050f, 0.482193619012833f, + 0.368122667074203f, 0.482294887304306f, 0.368492603302002f, 0.482395917177200f, + 0.368862658739090f, 0.482496619224548f, 0.369232743978500f, 0.482597053050995f, + 0.369602948427200f, 0.482697218656540f, 0.369973212480545f, 0.482797086238861f, + 0.370343536138535f, 0.482896685600281f, 0.370713949203491f, 0.482995986938477f, + 0.371084451675415f, 0.483094990253448f, 0.371455013751984f, 0.483193725347519f, + 0.371825665235519f, 0.483292192220688f, 0.372196376323700f, 0.483390361070633f, + 0.372567176818848f, 0.483488231897354f, 0.372938036918640f, 0.483585834503174f, + 0.373308986425400f, 0.483683139085770f, 0.373679995536804f, 0.483780175447464f, + 0.374051094055176f, 0.483876913785934f, 0.374422252178192f, 0.483973383903503f, + 0.374793499708176f, 0.484069555997849f, 0.375164806842804f, 0.484165430068970f, + 0.375536203384399f, 0.484261035919189f, 0.375907659530640f, 0.484356373548508f, + 0.376279205083847f, 0.484451413154602f, 0.376650810241699f, 0.484546154737473f, + 0.377022475004196f, 0.484640628099442f, 0.377394229173660f, 0.484734803438187f, + 0.377766042947769f, 0.484828680753708f, 0.378137946128845f, 0.484922289848328f, + 0.378509908914566f, 0.485015630722046f, 0.378881961107254f, 0.485108673572540f, + 0.379254043102264f, 0.485201418399811f, 0.379626244306564f, 0.485293895006180f, + 0.379998475313187f, 0.485386073589325f, 0.380370795726776f, 0.485477954149246f, + 0.380743205547333f, 0.485569566488266f, 0.381115674972534f, 0.485660910606384f, + 0.381488204002380f, 0.485751956701279f, 0.381860792636871f, 0.485842704772949f, + 0.382233470678329f, 0.485933154821396f, 0.382606208324432f, 0.486023366451263f, + 0.382979035377502f, 0.486113250255585f, 0.383351892232895f, 0.486202865839005f, + 0.383724838495255f, 0.486292183399200f, 0.384097874164581f, 0.486381232738495f, + 0.384470939636230f, 0.486469984054565f, 0.384844094514847f, 0.486558437347412f, + 0.385217308998108f, 0.486646622419357f, 0.385590612888336f, 0.486734509468079f, + 0.385963946580887f, 0.486822128295898f, 0.386337369680405f, 0.486909449100494f, + 0.386710882186890f, 0.486996471881866f, 0.387084424495697f, 0.487083226442337f, + 0.387458056211472f, 0.487169682979584f, 0.387831717729568f, 0.487255871295929f, + 0.388205498456955f, 0.487341761589050f, 0.388579308986664f, 0.487427353858948f, + 0.388953179121017f, 0.487512677907944f, 0.389327138662338f, 0.487597703933716f, + 0.389701157808304f, 0.487682431936264f, 0.390075236558914f, 0.487766891717911f, + 0.390449374914169f, 0.487851053476334f, 0.390823602676392f, 0.487934947013855f, + 0.391197860240936f, 0.488018542528152f, 0.391572207212448f, 0.488101840019226f, + 0.391946613788605f, 0.488184869289398f, 0.392321079969406f, 0.488267600536346f, + 0.392695605754852f, 0.488350033760071f, 0.393070191144943f, 0.488432198762894f, + 0.393444836139679f, 0.488514065742493f, 0.393819570541382f, 0.488595664501190f, + 0.394194334745407f, 0.488676935434341f, 0.394569188356400f, 0.488757967948914f, + 0.394944071769714f, 0.488838672637939f, 0.395319044589996f, 0.488919109106064f, + 0.395694077014923f, 0.488999247550964f, 0.396069169044495f, 0.489079117774963f, + 0.396444320678711f, 0.489158689975739f, 0.396819531917572f, 0.489237964153290f, + 0.397194802761078f, 0.489316970109940f, 0.397570133209229f, 0.489395678043365f, + 0.397945523262024f, 0.489474087953568f, 0.398320972919464f, 0.489552229642868f, + 0.398696482181549f, 0.489630073308945f, 0.399072051048279f, 0.489707618951797f, + 0.399447679519653f, 0.489784896373749f, 0.399823367595673f, 0.489861875772476f, + 0.400199115276337f, 0.489938557147980f, 0.400574922561646f, 0.490014940500259f, + 0.400950789451599f, 0.490091055631638f, 0.401326715946198f, 0.490166902542114f, + 0.401702702045441f, 0.490242421627045f, 0.402078747749329f, 0.490317672491074f, + 0.402454853057861f, 0.490392625331879f, 0.402830988168716f, 0.490467309951782f, + 0.403207212686539f, 0.490541696548462f, 0.403583467006683f, 0.490615785121918f, + 0.403959810733795f, 0.490689605474472f, 0.404336184263229f, 0.490763127803802f, + 0.404712617397308f, 0.490836352109909f, 0.405089110136032f, 0.490909278392792f, + 0.405465662479401f, 0.490981936454773f, 0.405842274427414f, 0.491054296493530f, + 0.406218945980072f, 0.491126358509064f, 0.406595647335052f, 0.491198152303696f, + 0.406972438097000f, 0.491269648075104f, 0.407349258661270f, 0.491340845823288f, + 0.407726138830185f, 0.491411775350571f, 0.408103078603745f, 0.491482406854630f, + 0.408480048179626f, 0.491552740335464f, 0.408857107162476f, 0.491622805595398f, + 0.409234195947647f, 0.491692543029785f, 0.409611344337463f, 0.491762012243271f, + 0.409988552331924f, 0.491831213235855f, 0.410365819931030f, 0.491900116205215f, + 0.410743117332459f, 0.491968721151352f, 0.411120474338531f, 0.492037028074265f, + 0.411497890949249f, 0.492105036973953f, 0.411875367164612f, 0.492172777652740f, + 0.412252873182297f, 0.492240220308304f, 0.412630438804626f, 0.492307394742966f, + 0.413008064031601f, 0.492374241352081f, 0.413385748863220f, 0.492440819740295f, + 0.413763463497162f, 0.492507129907608f, 0.414141237735748f, 0.492573112249374f, + 0.414519041776657f, 0.492638826370239f, 0.414896935224533f, 0.492704242467880f, + 0.415274858474731f, 0.492769360542297f, 0.415652841329575f, 0.492834210395813f, + 0.416030853986740f, 0.492898762226105f, 0.416408926248550f, 0.492963016033173f, + 0.416787058115005f, 0.493026971817017f, 0.417165219783783f, 0.493090659379959f, + 0.417543441057205f, 0.493154048919678f, 0.417921721935272f, 0.493217140436172f, + 0.418300032615662f, 0.493279963731766f, 0.418678402900696f, 0.493342459201813f, + 0.419056802988052f, 0.493404686450958f, 0.419435262680054f, 0.493466645479202f, + 0.419813781976700f, 0.493528276681900f, 0.420192331075668f, 0.493589639663696f, + 0.420570939779282f, 0.493650704622269f, 0.420949578285217f, 0.493711471557617f, + 0.421328276395798f, 0.493771970272064f, 0.421707004308701f, 0.493832170963287f, + 0.422085791826248f, 0.493892073631287f, 0.422464638948441f, 0.493951678276062f, + 0.422843515872955f, 0.494011014699936f, 0.423222452402115f, 0.494070053100586f, + 0.423601418733597f, 0.494128793478012f, 0.423980414867401f, 0.494187235832214f, + 0.424359470605850f, 0.494245409965515f, 0.424738585948944f, 0.494303256273270f, + 0.425117731094360f, 0.494360834360123f, 0.425496935844421f, 0.494418144226074f, + 0.425876170396805f, 0.494475126266479f, 0.426255434751511f, 0.494531840085983f, + 0.426634758710861f, 0.494588255882263f, 0.427014142274857f, 0.494644373655319f, + 0.427393525838852f, 0.494700223207474f, 0.427772998809814f, 0.494755744934082f, + 0.428152471780777f, 0.494810998439789f, 0.428532034158707f, 0.494865983724594f, + 0.428911596536636f, 0.494920641183853f, 0.429291218519211f, 0.494975030422211f, + 0.429670870304108f, 0.495029091835022f, 0.430050581693649f, 0.495082914829254f, + 0.430430322885513f, 0.495136409997940f, 0.430810123682022f, 0.495189607143402f, + 0.431189924478531f, 0.495242536067963f, 0.431569814682007f, 0.495295166969299f, + 0.431949704885483f, 0.495347499847412f, 0.432329654693604f, 0.495399564504623f, + 0.432709634304047f, 0.495451331138611f, 0.433089673519135f, 0.495502769947052f, + 0.433469742536545f, 0.495553970336914f, 0.433849841356277f, 0.495604842901230f, + 0.434229999780655f, 0.495655417442322f, 0.434610158205032f, 0.495705723762512f, + 0.434990376234055f, 0.495755732059479f, 0.435370653867722f, 0.495805442333221f, + 0.435750931501389f, 0.495854884386063f, 0.436131268739700f, 0.495903998613358f, + 0.436511665582657f, 0.495952844619751f, 0.436892062425613f, 0.496001392602921f, + 0.437272518873215f, 0.496049642562866f, 0.437653005123138f, 0.496097624301910f, + 0.438033521175385f, 0.496145308017731f, 0.438414067029953f, 0.496192663908005f, + 0.438794672489166f, 0.496239781379700f, 0.439175277948380f, 0.496286571025848f, + 0.439555943012238f, 0.496333062648773f, 0.439936667680740f, 0.496379286050797f, + 0.440317392349243f, 0.496425211429596f, 0.440698176622391f, 0.496470838785172f, + 0.441078960895538f, 0.496516168117523f, 0.441459804773331f, 0.496561229228973f, + 0.441840678453445f, 0.496605962514877f, 0.442221581935883f, 0.496650427579880f, + 0.442602545022964f, 0.496694594621658f, 0.442983508110046f, 0.496738493442535f, + 0.443364530801773f, 0.496782064437866f, 0.443745553493500f, 0.496825367212296f, + 0.444126635789871f, 0.496868371963501f, 0.444507747888565f, 0.496911078691483f, + 0.444888889789581f, 0.496953487396240f, 0.445270061492920f, 0.496995598077774f, + 0.445651292800903f, 0.497037440538406f, 0.446032524108887f, 0.497078984975815f, + 0.446413785219193f, 0.497120231389999f, 0.446795076131821f, 0.497161179780960f, + 0.447176426649094f, 0.497201830148697f, 0.447557777166367f, 0.497242212295532f, + 0.447939187288284f, 0.497282296419144f, 0.448320597410202f, 0.497322082519531f, + 0.448702067136765f, 0.497361570596695f, 0.449083566665649f, 0.497400760650635f, + 0.449465066194534f, 0.497439652681351f, 0.449846625328064f, 0.497478276491165f, + 0.450228184461594f, 0.497516602277756f, 0.450609803199768f, 0.497554630041122f, + 0.450991421937943f, 0.497592359781265f, 0.451373100280762f, 0.497629791498184f, + 0.451754778623581f, 0.497666954994202f, 0.452136516571045f, 0.497703820466995f, + 0.452518254518509f, 0.497740387916565f, 0.452900022268295f, 0.497776657342911f, + 0.453281819820404f, 0.497812628746033f, 0.453663676977158f, 0.497848302125931f, + 0.454045534133911f, 0.497883707284927f, 0.454427421092987f, 0.497918814420700f, + 0.454809308052063f, 0.497953623533249f, 0.455191254615784f, 0.497988134622574f, + 0.455573230981827f, 0.498022347688675f, 0.455955207347870f, 0.498056292533875f, + 0.456337243318558f, 0.498089909553528f, 0.456719279289246f, 0.498123258352280f, + 0.457101345062256f, 0.498156309127808f, 0.457483440637589f, 0.498189061880112f, + 0.457865566015244f, 0.498221516609192f, 0.458247691392899f, 0.498253703117371f, + 0.458629876375198f, 0.498285561800003f, 0.459012061357498f, 0.498317152261734f, + 0.459394276142120f, 0.498348444700241f, 0.459776520729065f, 0.498379439115524f, + 0.460158795118332f, 0.498410135507584f, 0.460541069507599f, 0.498440563678741f, + 0.460923373699188f, 0.498470664024353f, 0.461305707693100f, 0.498500496149063f, + 0.461688071489334f, 0.498530030250549f, 0.462070435285568f, 0.498559266328812f, + 0.462452858686447f, 0.498588204383850f, 0.462835282087326f, 0.498616874217987f, + 0.463217705488205f, 0.498645216226578f, 0.463600188493729f, 0.498673290014267f, + 0.463982671499252f, 0.498701065778732f, 0.464365184307098f, 0.498728543519974f, + 0.464747726917267f, 0.498755723237991f, 0.465130269527435f, 0.498782604932785f, + 0.465512841939926f, 0.498809218406677f, 0.465895414352417f, 0.498835533857346f, + 0.466278046369553f, 0.498861521482468f, 0.466660678386688f, 0.498887240886688f, + 0.467043310403824f, 0.498912662267685f, 0.467426002025604f, 0.498937815427780f, + 0.467808693647385f, 0.498962640762329f, 0.468191385269165f, 0.498987197875977f, + 0.468574106693268f, 0.499011427164078f, 0.468956857919693f, 0.499035388231277f, + 0.469339638948441f, 0.499059051275253f, 0.469722419977188f, 0.499082416296005f, + 0.470105201005936f, 0.499105513095856f, 0.470488041639328f, 0.499128282070160f, + 0.470870882272720f, 0.499150782823563f, 0.471253722906113f, 0.499172955751419f, + 0.471636593341827f, 0.499194860458374f, 0.472019463777542f, 0.499216467142105f, + 0.472402364015579f, 0.499237775802612f, 0.472785294055939f, 0.499258816242218f, + 0.473168224096298f, 0.499279528856277f, 0.473551183938980f, 0.499299973249435f, + 0.473934143781662f, 0.499320119619370f, 0.474317133426666f, 0.499339967966080f, + 0.474700123071671f, 0.499359518289566f, 0.475083142518997f, 0.499378770589828f, + 0.475466161966324f, 0.499397724866867f, 0.475849211215973f, 0.499416410923004f, + 0.476232260465622f, 0.499434769153595f, 0.476615339517593f, 0.499452859163284f, + 0.476998418569565f, 0.499470651149750f, 0.477381497621536f, 0.499488145112991f, + 0.477764606475830f, 0.499505341053009f, 0.478147745132446f, 0.499522238969803f, + 0.478530883789063f, 0.499538868665695f, 0.478914022445679f, 0.499555170536041f, + 0.479297190904617f, 0.499571204185486f, 0.479680359363556f, 0.499586939811707f, + 0.480063527822495f, 0.499602377414703f, 0.480446726083755f, 0.499617516994476f, + 0.480829954147339f, 0.499632388353348f, 0.481213152408600f, 0.499646931886673f, + 0.481596380472183f, 0.499661177396774f, 0.481979638338089f, 0.499675154685974f, + 0.482362866401672f, 0.499688833951950f, 0.482746154069901f, 0.499702215194702f, + 0.483129411935806f, 0.499715298414230f, 0.483512699604034f, 0.499728083610535f, + 0.483895987272263f, 0.499740600585938f, 0.484279274940491f, 0.499752789735794f, + 0.484662592411041f, 0.499764710664749f, 0.485045909881592f, 0.499776333570480f, + 0.485429257154465f, 0.499787658452988f, 0.485812574625015f, 0.499798685312271f, + 0.486195921897888f, 0.499809414148331f, 0.486579269170761f, 0.499819844961166f, + 0.486962646245956f, 0.499830007553101f, 0.487346023321152f, 0.499839842319489f, + 0.487729400396347f, 0.499849408864975f, 0.488112777471542f, 0.499858677387238f, + 0.488496154546738f, 0.499867647886276f, 0.488879561424255f, 0.499876320362091f, + 0.489262968301773f, 0.499884694814682f, 0.489646375179291f, 0.499892801046371f, + 0.490029782056808f, 0.499900579452515f, 0.490413218736649f, 0.499908089637756f, + 0.490796625614166f, 0.499915301799774f, 0.491180062294006f, 0.499922215938568f, + 0.491563498973846f, 0.499928832054138f, 0.491946935653687f, 0.499935150146484f, + 0.492330402135849f, 0.499941170215607f, 0.492713838815689f, 0.499946922063828f, + 0.493097305297852f, 0.499952346086502f, 0.493480771780014f, 0.499957501888275f, + 0.493864238262177f, 0.499962359666824f, 0.494247704744339f, 0.499966919422150f, + 0.494631171226501f, 0.499971181154251f, 0.495014637708664f, 0.499975144863129f, + 0.495398133993149f, 0.499978810548782f, 0.495781600475311f, 0.499982208013535f, + 0.496165096759796f, 0.499985307455063f, 0.496548563241959f, 0.499988079071045f, + 0.496932059526443f, 0.499990582466125f, 0.497315555810928f, 0.499992787837982f, + 0.497699022293091f, 0.499994695186615f, 0.498082518577576f, 0.499996334314346f, + 0.498466014862061f, 0.499997645616531f, 0.498849511146545f, 0.499998688697815f, + 0.499233007431030f, 0.499999403953552f, 0.499616503715515f, 0.499999850988388f, +}; + + +/** + @par + Generation of realCoefB array: + @par + n = 4096 +
for (i = 0; i < n; i++)
+  {
+     pBTable[2 * i]     = 0.5 * (1.0 + sin (2 * PI / (double) (2 * n) * (double) i));
+     pBTable[2 * i + 1] = 0.5 * (1.0 * cos (2 * PI / (double) (2 * n) * (double) i));
+  }
+ */ + +static const float32_t realCoefB[8192] = { + 0.500000000000000f, 0.500000000000000f, 0.500383496284485f, 0.499999850988388f, + 0.500766992568970f, 0.499999403953552f, 0.501150488853455f, 0.499998688697815f, + 0.501533985137939f, 0.499997645616531f, 0.501917481422424f, 0.499996334314346f, + 0.502300977706909f, 0.499994695186615f, 0.502684473991394f, 0.499992787837982f, + 0.503067970275879f, 0.499990582466125f, 0.503451406955719f, 0.499988079071045f, + 0.503834903240204f, 0.499985307455063f, 0.504218399524689f, 0.499982208013535f, + 0.504601895809174f, 0.499978810548782f, 0.504985332489014f, 0.499975144863129f, + 0.505368828773499f, 0.499971181154251f, 0.505752325057983f, 0.499966919422150f, + 0.506135761737823f, 0.499962359666824f, 0.506519258022308f, 0.499957501888275f, + 0.506902694702148f, 0.499952346086502f, 0.507286131381989f, 0.499946922063828f, + 0.507669627666473f, 0.499941170215607f, 0.508053064346313f, 0.499935150146484f, + 0.508436501026154f, 0.499928832054138f, 0.508819937705994f, 0.499922215938568f, + 0.509203374385834f, 0.499915301799774f, 0.509586811065674f, 0.499908089637756f, + 0.509970188140869f, 0.499900579452515f, 0.510353624820709f, 0.499892801046371f, + 0.510737061500549f, 0.499884694814682f, 0.511120438575745f, 0.499876320362091f, + 0.511503815650940f, 0.499867647886276f, 0.511887252330780f, 0.499858677387238f, + 0.512270629405975f, 0.499849408864975f, 0.512654006481171f, 0.499839842319489f, + 0.513037383556366f, 0.499830007553101f, 0.513420701026917f, 0.499819844961166f, + 0.513804078102112f, 0.499809414148331f, 0.514187395572662f, 0.499798685312271f, + 0.514570772647858f, 0.499787658452988f, 0.514954090118408f, 0.499776333570480f, + 0.515337407588959f, 0.499764710664749f, 0.515720725059509f, 0.499752789735794f, + 0.516103982925415f, 0.499740600585938f, 0.516487300395966f, 0.499728083610535f, + 0.516870558261871f, 0.499715298414230f, 0.517253875732422f, 0.499702215194702f, + 0.517637133598328f, 0.499688833951950f, 0.518020391464233f, 0.499675154685974f, + 0.518403589725494f, 0.499661177396774f, 0.518786847591400f, 0.499646931886673f, + 0.519170045852661f, 0.499632388353348f, 0.519553244113922f, 0.499617516994476f, + 0.519936442375183f, 0.499602377414703f, 0.520319640636444f, 0.499586939811707f, + 0.520702838897705f, 0.499571204185486f, 0.521085977554321f, 0.499555170536041f, + 0.521469116210938f, 0.499538868665695f, 0.521852254867554f, 0.499522238969803f, + 0.522235393524170f, 0.499505341053009f, 0.522618472576141f, 0.499488145112991f, + 0.523001611232758f, 0.499470651149750f, 0.523384690284729f, 0.499452859163284f, + 0.523767769336700f, 0.499434769153595f, 0.524150788784027f, 0.499416410923004f, + 0.524533808231354f, 0.499397724866867f, 0.524916887283325f, 0.499378770589828f, + 0.525299847126007f, 0.499359518289566f, 0.525682866573334f, 0.499339967966080f, + 0.526065826416016f, 0.499320119619370f, 0.526448845863342f, 0.499299973249435f, + 0.526831746101379f, 0.499279528856277f, 0.527214705944061f, 0.499258816242218f, + 0.527597606182098f, 0.499237775802612f, 0.527980506420136f, 0.499216467142105f, + 0.528363406658173f, 0.499194860458374f, 0.528746306896210f, 0.499172955751419f, + 0.529129147529602f, 0.499150782823563f, 0.529511988162994f, 0.499128282070160f, + 0.529894769191742f, 0.499105513095856f, 0.530277609825134f, 0.499082416296005f, + 0.530660390853882f, 0.499059051275253f, 0.531043112277985f, 0.499035388231277f, + 0.531425893306732f, 0.499011427164078f, 0.531808614730835f, 0.498987197875977f, + 0.532191336154938f, 0.498962640762329f, 0.532573997974396f, 0.498937815427780f, + 0.532956659793854f, 0.498912662267685f, 0.533339321613312f, 0.498887240886688f, + 0.533721983432770f, 0.498861521482468f, 0.534104585647583f, 0.498835533857346f, + 0.534487187862396f, 0.498809218406677f, 0.534869730472565f, 0.498782604932785f, + 0.535252273082733f, 0.498755723237991f, 0.535634815692902f, 0.498728543519974f, + 0.536017298698425f, 0.498701065778732f, 0.536399841308594f, 0.498673290014267f, + 0.536782264709473f, 0.498645216226578f, 0.537164747714996f, 0.498616874217987f, + 0.537547171115875f, 0.498588204383850f, 0.537929534912109f, 0.498559266328812f, + 0.538311958312988f, 0.498530030250549f, 0.538694262504578f, 0.498500496149063f, + 0.539076626300812f, 0.498470664024353f, 0.539458930492401f, 0.498440563678741f, + 0.539841234683990f, 0.498410135507584f, 0.540223479270935f, 0.498379439115524f, + 0.540605723857880f, 0.498348444700241f, 0.540987968444824f, 0.498317152261734f, + 0.541370153427124f, 0.498285561800003f, 0.541752278804779f, 0.498253703117371f, + 0.542134463787079f, 0.498221516609192f, 0.542516589164734f, 0.498189061880112f, + 0.542898654937744f, 0.498156309127808f, 0.543280720710754f, 0.498123258352280f, + 0.543662786483765f, 0.498089909553528f, 0.544044792652130f, 0.498056292533875f, + 0.544426798820496f, 0.498022347688675f, 0.544808745384216f, 0.497988134622574f, + 0.545190691947937f, 0.497953623533249f, 0.545572578907013f, 0.497918814420700f, + 0.545954465866089f, 0.497883707284927f, 0.546336352825165f, 0.497848302125931f, + 0.546718180179596f, 0.497812628746033f, 0.547099947929382f, 0.497776657342911f, + 0.547481775283813f, 0.497740387916565f, 0.547863483428955f, 0.497703820466995f, + 0.548245191574097f, 0.497666954994202f, 0.548626899719238f, 0.497629791498184f, + 0.549008548259735f, 0.497592359781265f, 0.549390196800232f, 0.497554630041122f, + 0.549771785736084f, 0.497516602277756f, 0.550153374671936f, 0.497478276491165f, + 0.550534904003143f, 0.497439652681351f, 0.550916433334351f, 0.497400760650635f, + 0.551297962665558f, 0.497361570596695f, 0.551679372787476f, 0.497322082519531f, + 0.552060842514038f, 0.497282296419144f, 0.552442193031311f, 0.497242212295532f, + 0.552823603153229f, 0.497201830148697f, 0.553204894065857f, 0.497161179780960f, + 0.553586184978485f, 0.497120231389999f, 0.553967475891113f, 0.497078984975815f, + 0.554348707199097f, 0.497037440538406f, 0.554729938507080f, 0.496995598077774f, + 0.555111110210419f, 0.496953487396240f, 0.555492222309113f, 0.496911078691483f, + 0.555873334407806f, 0.496868371963501f, 0.556254446506500f, 0.496825367212296f, + 0.556635499000549f, 0.496782064437866f, 0.557016491889954f, 0.496738493442535f, + 0.557397484779358f, 0.496694594621658f, 0.557778418064117f, 0.496650427579880f, + 0.558159291744232f, 0.496605962514877f, 0.558540165424347f, 0.496561229228973f, + 0.558921039104462f, 0.496516168117523f, 0.559301853179932f, 0.496470838785172f, + 0.559682607650757f, 0.496425211429596f, 0.560063362121582f, 0.496379286050797f, + 0.560444056987762f, 0.496333062648773f, 0.560824692249298f, 0.496286571025848f, + 0.561205327510834f, 0.496239781379700f, 0.561585903167725f, 0.496192663908005f, + 0.561966478824615f, 0.496145308017731f, 0.562346994876862f, 0.496097624301910f, + 0.562727510929108f, 0.496049642562866f, 0.563107967376709f, 0.496001392602921f, + 0.563488364219666f, 0.495952844619751f, 0.563868701457977f, 0.495903998613358f, + 0.564249038696289f, 0.495854884386063f, 0.564629375934601f, 0.495805442333221f, + 0.565009593963623f, 0.495755732059479f, 0.565389811992645f, 0.495705723762512f, + 0.565770030021667f, 0.495655417442322f, 0.566150128841400f, 0.495604842901230f, + 0.566530287265778f, 0.495553970336914f, 0.566910326480865f, 0.495502769947052f, + 0.567290365695953f, 0.495451331138611f, 0.567670345306396f, 0.495399564504623f, + 0.568050265312195f, 0.495347499847412f, 0.568430185317993f, 0.495295166969299f, + 0.568810045719147f, 0.495242536067963f, 0.569189906120300f, 0.495189607143402f, + 0.569569647312164f, 0.495136409997940f, 0.569949388504028f, 0.495082914829254f, + 0.570329129695892f, 0.495029091835022f, 0.570708811283112f, 0.494975030422211f, + 0.571088373661041f, 0.494920641183853f, 0.571467995643616f, 0.494865983724594f, + 0.571847498416901f, 0.494810998439789f, 0.572227001190186f, 0.494755744934082f, + 0.572606444358826f, 0.494700223207474f, 0.572985887527466f, 0.494644373655319f, + 0.573365211486816f, 0.494588255882263f, 0.573744535446167f, 0.494531840085983f, + 0.574123859405518f, 0.494475126266479f, 0.574503064155579f, 0.494418144226074f, + 0.574882268905640f, 0.494360834360123f, 0.575261414051056f, 0.494303256273270f, + 0.575640499591827f, 0.494245409965515f, 0.576019585132599f, 0.494187235832214f, + 0.576398611068726f, 0.494128793478012f, 0.576777577400208f, 0.494070053100586f, + 0.577156484127045f, 0.494011014699936f, 0.577535390853882f, 0.493951678276062f, + 0.577914178371429f, 0.493892073631287f, 0.578292965888977f, 0.493832170963287f, + 0.578671753406525f, 0.493771970272064f, 0.579050421714783f, 0.493711471557617f, + 0.579429090023041f, 0.493650704622269f, 0.579807698726654f, 0.493589639663696f, + 0.580186247825623f, 0.493528276681900f, 0.580564737319946f, 0.493466645479202f, + 0.580943167209625f, 0.493404686450958f, 0.581321597099304f, 0.493342459201813f, + 0.581699967384338f, 0.493279963731766f, 0.582078278064728f, 0.493217140436172f, + 0.582456588745117f, 0.493154048919678f, 0.582834780216217f, 0.493090659379959f, + 0.583212971687317f, 0.493026971817017f, 0.583591103553772f, 0.492963016033173f, + 0.583969175815582f, 0.492898762226105f, 0.584347188472748f, 0.492834210395813f, + 0.584725141525269f, 0.492769360542297f, 0.585103094577789f, 0.492704242467880f, + 0.585480928421021f, 0.492638826370239f, 0.585858762264252f, 0.492573112249374f, + 0.586236536502838f, 0.492507129907608f, 0.586614251136780f, 0.492440819740295f, + 0.586991965770721f, 0.492374241352081f, 0.587369561195374f, 0.492307394742966f, + 0.587747097015381f, 0.492240220308304f, 0.588124632835388f, 0.492172777652740f, + 0.588502109050751f, 0.492105036973953f, 0.588879525661469f, 0.492037028074265f, + 0.589256882667542f, 0.491968721151352f, 0.589634180068970f, 0.491900116205215f, + 0.590011477470398f, 0.491831213235855f, 0.590388655662537f, 0.491762012243271f, + 0.590765833854675f, 0.491692543029785f, 0.591142892837524f, 0.491622805595398f, + 0.591519951820374f, 0.491552740335464f, 0.591896951198578f, 0.491482406854630f, + 0.592273890972137f, 0.491411775350571f, 0.592650771141052f, 0.491340845823288f, + 0.593027591705322f, 0.491269648075104f, 0.593404352664948f, 0.491198152303696f, + 0.593781054019928f, 0.491126358509064f, 0.594157755374908f, 0.491054296493530f, + 0.594534337520599f, 0.490981936454773f, 0.594910860061646f, 0.490909278392792f, + 0.595287382602692f, 0.490836352109909f, 0.595663845539093f, 0.490763127803802f, + 0.596040189266205f, 0.490689605474472f, 0.596416532993317f, 0.490615785121918f, + 0.596792817115784f, 0.490541696548462f, 0.597168982028961f, 0.490467309951782f, + 0.597545146942139f, 0.490392625331879f, 0.597921252250671f, 0.490317672491074f, + 0.598297297954559f, 0.490242421627045f, 0.598673284053802f, 0.490166902542114f, + 0.599049210548401f, 0.490091055631638f, 0.599425077438354f, 0.490014940500259f, + 0.599800884723663f, 0.489938557147980f, 0.600176632404327f, 0.489861875772476f, + 0.600552320480347f, 0.489784896373749f, 0.600927948951721f, 0.489707618951797f, + 0.601303517818451f, 0.489630073308945f, 0.601679027080536f, 0.489552229642868f, + 0.602054476737976f, 0.489474087953568f, 0.602429866790771f, 0.489395678043365f, + 0.602805197238922f, 0.489316970109940f, 0.603180468082428f, 0.489237964153290f, + 0.603555679321289f, 0.489158689975739f, 0.603930830955505f, 0.489079117774963f, + 0.604305922985077f, 0.488999247550964f, 0.604680955410004f, 0.488919109106064f, + 0.605055928230286f, 0.488838672637939f, 0.605430841445923f, 0.488757967948914f, + 0.605805635452271f, 0.488676935434341f, 0.606180429458618f, 0.488595664501190f, + 0.606555163860321f, 0.488514065742493f, 0.606929838657379f, 0.488432198762894f, + 0.607304394245148f, 0.488350033760071f, 0.607678949832916f, 0.488267600536346f, + 0.608053386211395f, 0.488184869289398f, 0.608427822589874f, 0.488101840019226f, + 0.608802139759064f, 0.488018542528152f, 0.609176397323608f, 0.487934947013855f, + 0.609550595283508f, 0.487851053476334f, 0.609924793243408f, 0.487766891717911f, + 0.610298871994019f, 0.487682431936264f, 0.610672831535339f, 0.487597703933716f, + 0.611046791076660f, 0.487512677907944f, 0.611420691013336f, 0.487427353858948f, + 0.611794531345367f, 0.487341761589050f, 0.612168252468109f, 0.487255871295929f, + 0.612541973590851f, 0.487169682979584f, 0.612915575504303f, 0.487083226442337f, + 0.613289117813110f, 0.486996471881866f, 0.613662600517273f, 0.486909449100494f, + 0.614036023616791f, 0.486822128295898f, 0.614409387111664f, 0.486734509468079f, + 0.614782691001892f, 0.486646622419357f, 0.615155875682831f, 0.486558437347412f, + 0.615529060363770f, 0.486469984054565f, 0.615902125835419f, 0.486381232738495f, + 0.616275131702423f, 0.486292183399200f, 0.616648077964783f, 0.486202865839005f, + 0.617020964622498f, 0.486113250255585f, 0.617393791675568f, 0.486023366451263f, + 0.617766559123993f, 0.485933154821396f, 0.618139207363129f, 0.485842704772949f, + 0.618511795997620f, 0.485751956701279f, 0.618884325027466f, 0.485660910606384f, + 0.619256794452667f, 0.485569566488266f, 0.619629204273224f, 0.485477954149246f, + 0.620001494884491f, 0.485386073589325f, 0.620373785495758f, 0.485293895006180f, + 0.620745956897736f, 0.485201418399811f, 0.621118068695068f, 0.485108673572540f, + 0.621490061283112f, 0.485015630722046f, 0.621862053871155f, 0.484922289848328f, + 0.622233927249908f, 0.484828680753708f, 0.622605800628662f, 0.484734803438187f, + 0.622977554798126f, 0.484640628099442f, 0.623349189758301f, 0.484546154737473f, + 0.623720824718475f, 0.484451413154602f, 0.624092340469360f, 0.484356373548508f, + 0.624463796615601f, 0.484261035919189f, 0.624835193157196f, 0.484165430068970f, + 0.625206530094147f, 0.484069555997849f, 0.625577747821808f, 0.483973383903503f, + 0.625948905944824f, 0.483876913785934f, 0.626320004463196f, 0.483780175447464f, + 0.626691043376923f, 0.483683139085770f, 0.627061963081360f, 0.483585834503174f, + 0.627432823181152f, 0.483488231897354f, 0.627803623676300f, 0.483390361070633f, + 0.628174364566803f, 0.483292192220688f, 0.628544986248016f, 0.483193725347519f, + 0.628915548324585f, 0.483094990253448f, 0.629286050796509f, 0.482995986938477f, + 0.629656434059143f, 0.482896685600281f, 0.630026817321777f, 0.482797086238861f, + 0.630397081375122f, 0.482697218656540f, 0.630767226219177f, 0.482597053050995f, + 0.631137371063232f, 0.482496619224548f, 0.631507396697998f, 0.482395917177200f, + 0.631877362728119f, 0.482294887304306f, 0.632247209548950f, 0.482193619012833f, + 0.632616996765137f, 0.482092022895813f, 0.632986724376678f, 0.481990188360214f, + 0.633356392383575f, 0.481888025999069f, 0.633725941181183f, 0.481785595417023f, + 0.634095430374146f, 0.481682896614075f, 0.634464859962463f, 0.481579899787903f, + 0.634834170341492f, 0.481476634740829f, 0.635203421115875f, 0.481373071670532f, + 0.635572552680969f, 0.481269240379334f, 0.635941684246063f, 0.481165111064911f, + 0.636310696601868f, 0.481060713529587f, 0.636679589748383f, 0.480956017971039f, + 0.637048482894897f, 0.480851024389267f, 0.637417197227478f, 0.480745792388916f, + 0.637785911560059f, 0.480640232563019f, 0.638154506683350f, 0.480534434318542f, + 0.638523042201996f, 0.480428308248520f, 0.638891458511353f, 0.480321943759918f, + 0.639259815216064f, 0.480215251445770f, 0.639628112316132f, 0.480108320713043f, + 0.639996349811554f, 0.480001062154770f, 0.640364408493042f, 0.479893565177917f, + 0.640732467174530f, 0.479785770177841f, 0.641100406646729f, 0.479677677154541f, + 0.641468286514282f, 0.479569315910339f, 0.641836047172546f, 0.479460656642914f, + 0.642203748226166f, 0.479351729154587f, 0.642571389675140f, 0.479242533445358f, + 0.642938911914825f, 0.479133039712906f, 0.643306374549866f, 0.479023247957230f, + 0.643673717975616f, 0.478913217782974f, 0.644041001796722f, 0.478802859783173f, + 0.644408226013184f, 0.478692263364792f, 0.644775331020355f, 0.478581339120865f, + 0.645142316818237f, 0.478470176458359f, 0.645509302616119f, 0.478358715772629f, + 0.645876109600067f, 0.478246957063675f, 0.646242916584015f, 0.478134930133820f, + 0.646609604358673f, 0.478022634983063f, 0.646976172924042f, 0.477910041809082f, + 0.647342681884766f, 0.477797180414200f, 0.647709131240845f, 0.477684020996094f, + 0.648075461387634f, 0.477570593357086f, 0.648441672325134f, 0.477456867694855f, + 0.648807883262634f, 0.477342873811722f, 0.649173915386200f, 0.477228611707687f, + 0.649539887905121f, 0.477114051580429f, 0.649905800819397f, 0.476999223232269f, + 0.650271594524384f, 0.476884096860886f, 0.650637328624725f, 0.476768702268600f, + 0.651003003120422f, 0.476653009653091f, 0.651368498802185f, 0.476537048816681f, + 0.651733994483948f, 0.476420819759369f, 0.652099311351776f, 0.476304292678833f, + 0.652464628219604f, 0.476187497377396f, 0.652829825878143f, 0.476070433855057f, + 0.653194904327393f, 0.475953072309494f, 0.653559923171997f, 0.475835442543030f, + 0.653924822807312f, 0.475717514753342f, 0.654289662837982f, 0.475599318742752f, + 0.654654383659363f, 0.475480824708939f, 0.655019044876099f, 0.475362062454224f, + 0.655383586883545f, 0.475243031978607f, 0.655748009681702f, 0.475123733282089f, + 0.656112432479858f, 0.475004136562347f, 0.656476676464081f, 0.474884241819382f, + 0.656840860843658f, 0.474764078855515f, 0.657204985618591f, 0.474643647670746f, + 0.657568991184235f, 0.474522948265076f, 0.657932877540588f, 0.474401950836182f, + 0.658296704292297f, 0.474280685186386f, 0.658660411834717f, 0.474159121513367f, + 0.659024059772491f, 0.474037289619446f, 0.659387588500977f, 0.473915189504623f, + 0.659750998020172f, 0.473792791366577f, 0.660114347934723f, 0.473670125007629f, + 0.660477638244629f, 0.473547190427780f, 0.660840749740601f, 0.473423957824707f, + 0.661203861236572f, 0.473300457000732f, 0.661566793918610f, 0.473176687955856f, + 0.661929666996002f, 0.473052620887756f, 0.662292480468750f, 0.472928285598755f, + 0.662655174732208f, 0.472803652286530f, 0.663017749786377f, 0.472678780555725f, + 0.663380205631256f, 0.472553610801697f, 0.663742601871490f, 0.472428143024445f, + 0.664104938507080f, 0.472302407026291f, 0.664467096328735f, 0.472176402807236f, + 0.664829254150391f, 0.472050130367279f, 0.665191233158112f, 0.471923559904099f, + 0.665553152561188f, 0.471796721220016f, 0.665914952754974f, 0.471669614315033f, + 0.666276693344116f, 0.471542209386826f, 0.666638314723969f, 0.471414536237717f, + 0.666999816894531f, 0.471286594867706f, 0.667361259460449f, 0.471158385276794f, + 0.667722582817078f, 0.471029877662659f, 0.668083786964417f, 0.470901101827621f, + 0.668444931507111f, 0.470772027969360f, 0.668805956840515f, 0.470642685890198f, + 0.669166862964630f, 0.470513075590134f, 0.669527709484100f, 0.470383197069168f, + 0.669888436794281f, 0.470253020524979f, 0.670249044895172f, 0.470122605562210f, + 0.670609593391418f, 0.469991862773895f, 0.670970022678375f, 0.469860881567001f, + 0.671330332756042f, 0.469729602336884f, 0.671690583229065f, 0.469598054885864f, + 0.672050714492798f, 0.469466239213943f, 0.672410726547241f, 0.469334155321121f, + 0.672770678997040f, 0.469201773405075f, 0.673130512237549f, 0.469069123268127f, + 0.673490226268768f, 0.468936175107956f, 0.673849821090698f, 0.468802988529205f, + 0.674209356307983f, 0.468669503927231f, 0.674568772315979f, 0.468535751104355f, + 0.674928069114685f, 0.468401730060577f, 0.675287246704102f, 0.468267410993576f, + 0.675646364688873f, 0.468132823705673f, 0.676005363464355f, 0.467997968196869f, + 0.676364302635193f, 0.467862844467163f, 0.676723062992096f, 0.467727422714233f, + 0.677081763744354f, 0.467591762542725f, 0.677440345287323f, 0.467455804347992f, + 0.677798807621002f, 0.467319577932358f, 0.678157210350037f, 0.467183053493500f, + 0.678515493869781f, 0.467046260833740f, 0.678873658180237f, 0.466909229755402f, + 0.679231703281403f, 0.466771900653839f, 0.679589688777924f, 0.466634273529053f, + 0.679947495460510f, 0.466496407985687f, 0.680305242538452f, 0.466358244419098f, + 0.680662930011749f, 0.466219812631607f, 0.681020438671112f, 0.466081112623215f, + 0.681377887725830f, 0.465942144393921f, 0.681735157966614f, 0.465802878141403f, + 0.682092368602753f, 0.465663343667984f, 0.682449519634247f, 0.465523540973663f, + 0.682806491851807f, 0.465383470058441f, 0.683163404464722f, 0.465243130922318f, + 0.683520197868347f, 0.465102523565292f, 0.683876872062683f, 0.464961618185043f, + 0.684233427047729f, 0.464820444583893f, 0.684589862823486f, 0.464679002761841f, + 0.684946238994598f, 0.464537292718887f, 0.685302436351776f, 0.464395314455032f, + 0.685658574104309f, 0.464253038167953f, 0.686014592647552f, 0.464110493659973f, + 0.686370551586151f, 0.463967710733414f, 0.686726331710815f, 0.463824629783630f, + 0.687082052230835f, 0.463681250810623f, 0.687437593936920f, 0.463537633419037f, + 0.687793076038361f, 0.463393747806549f, 0.688148438930511f, 0.463249564170837f, + 0.688503682613373f, 0.463105112314224f, 0.688858866691589f, 0.462960392236710f, + 0.689213871955872f, 0.462815403938293f, 0.689568817615509f, 0.462670147418976f, + 0.689923584461212f, 0.462524622678757f, 0.690278291702271f, 0.462378799915314f, + 0.690632879734039f, 0.462232738733292f, 0.690987348556519f, 0.462086379528046f, + 0.691341698169708f, 0.461939752101898f, 0.691695988178253f, 0.461792886257172f, + 0.692050099372864f, 0.461645722389221f, 0.692404091358185f, 0.461498260498047f, + 0.692758023738861f, 0.461350560188293f, 0.693111836910248f, 0.461202591657639f, + 0.693465530872345f, 0.461054325103760f, 0.693819046020508f, 0.460905820131302f, + 0.694172501564026f, 0.460757017135620f, 0.694525837898254f, 0.460607945919037f, + 0.694879114627838f, 0.460458606481552f, 0.695232212543488f, 0.460309028625488f, + 0.695585191249847f, 0.460159152746201f, 0.695938050746918f, 0.460008978843689f, + 0.696290850639343f, 0.459858566522598f, 0.696643471717834f, 0.459707885980606f, + 0.696996033191681f, 0.459556937217712f, 0.697348415851593f, 0.459405690431595f, + 0.697700738906860f, 0.459254205226898f, 0.698052942752838f, 0.459102421998978f, + 0.698404967784882f, 0.458950400352478f, 0.698756933212280f, 0.458798080682755f, + 0.699108779430389f, 0.458645492792130f, 0.699460506439209f, 0.458492636680603f, + 0.699812114238739f, 0.458339542150497f, 0.700163602828979f, 0.458186149597168f, + 0.700514972209930f, 0.458032488822937f, 0.700866222381592f, 0.457878559827805f, + 0.701217353343964f, 0.457724362611771f, 0.701568365097046f, 0.457569897174835f, + 0.701919257640839f, 0.457415163516998f, 0.702270030975342f, 0.457260161638260f, + 0.702620685100555f, 0.457104891538620f, 0.702971220016479f, 0.456949323415756f, + 0.703321635723114f, 0.456793516874313f, 0.703671932220459f, 0.456637442111969f, + 0.704022109508514f, 0.456481099128723f, 0.704372167587280f, 0.456324487924576f, + 0.704722046852112f, 0.456167578697205f, 0.705071866512299f, 0.456010431051254f, + 0.705421566963196f, 0.455853015184402f, 0.705771148204803f, 0.455695331096649f, + 0.706120610237122f, 0.455537378787994f, 0.706469953060150f, 0.455379128456116f, + 0.706819176673889f, 0.455220639705658f, 0.707168221473694f, 0.455061882734299f, + 0.707517206668854f, 0.454902857542038f, 0.707866072654724f, 0.454743564128876f, + 0.708214759826660f, 0.454584002494812f, 0.708563387393951f, 0.454424172639847f, + 0.708911836147308f, 0.454264044761658f, 0.709260225296021f, 0.454103678464890f, + 0.709608435630798f, 0.453943043947220f, 0.709956526756287f, 0.453782171010971f, + 0.710304558277130f, 0.453621000051498f, 0.710652410984039f, 0.453459560871124f, + 0.711000144481659f, 0.453297853469849f, 0.711347758769989f, 0.453135877847672f, + 0.711695253849030f, 0.452973634004593f, 0.712042629718781f, 0.452811151742935f, + 0.712389826774597f, 0.452648371458054f, 0.712736964225769f, 0.452485352754593f, + 0.713083922863007f, 0.452322036027908f, 0.713430821895599f, 0.452158480882645f, + 0.713777542114258f, 0.451994657516479f, 0.714124143123627f, 0.451830536127090f, + 0.714470624923706f, 0.451666176319122f, 0.714816987514496f, 0.451501548290253f, + 0.715163230895996f, 0.451336652040482f, 0.715509355068207f, 0.451171487569809f, + 0.715855300426483f, 0.451006084680557f, 0.716201186180115f, 0.450840383768082f, + 0.716546893119812f, 0.450674414634705f, 0.716892480850220f, 0.450508207082748f, + 0.717238008975983f, 0.450341701507568f, 0.717583298683167f, 0.450174957513809f, + 0.717928528785706f, 0.450007945299149f, 0.718273639678955f, 0.449840664863586f, + 0.718618571758270f, 0.449673116207123f, 0.718963444232941f, 0.449505299329758f, + 0.719308137893677f, 0.449337244033813f, 0.719652712345123f, 0.449168890714645f, + 0.719997107982636f, 0.449000298976898f, 0.720341444015503f, 0.448831409215927f, + 0.720685660839081f, 0.448662281036377f, 0.721029698848724f, 0.448492884635925f, + 0.721373617649078f, 0.448323249816895f, 0.721717417240143f, 0.448153316974640f, + 0.722061097621918f, 0.447983115911484f, 0.722404599189758f, 0.447812676429749f, + 0.722747981548309f, 0.447641968727112f, 0.723091304302216f, 0.447470992803574f, + 0.723434448242188f, 0.447299748659134f, 0.723777413368225f, 0.447128236293793f, + 0.724120318889618f, 0.446956485509872f, 0.724463045597076f, 0.446784436702728f, + 0.724805653095245f, 0.446612149477005f, 0.725148141384125f, 0.446439594030380f, + 0.725490510463715f, 0.446266770362854f, 0.725832700729370f, 0.446093708276749f, + 0.726174771785736f, 0.445920348167419f, 0.726516723632813f, 0.445746749639511f, + 0.726858556270599f, 0.445572882890701f, 0.727200269699097f, 0.445398747920990f, + 0.727541804313660f, 0.445224374532700f, 0.727883219718933f, 0.445049703121185f, + 0.728224515914917f, 0.444874793291092f, 0.728565633296967f, 0.444699615240097f, + 0.728906631469727f, 0.444524168968201f, 0.729247510433197f, 0.444348484277725f, + 0.729588270187378f, 0.444172531366348f, 0.729928910732269f, 0.443996280431747f, + 0.730269372463226f, 0.443819820880890f, 0.730609714984894f, 0.443643063306808f, + 0.730949878692627f, 0.443466067314148f, 0.731289982795715f, 0.443288803100586f, + 0.731629908084869f, 0.443111270666122f, 0.731969714164734f, 0.442933470010757f, + 0.732309341430664f, 0.442755430936813f, 0.732648849487305f, 0.442577123641968f, + 0.732988238334656f, 0.442398548126221f, 0.733327507972717f, 0.442219734191895f, + 0.733666598796844f, 0.442040622234344f, 0.734005570411682f, 0.441861271858215f, + 0.734344422817230f, 0.441681683063507f, 0.734683096408844f, 0.441501796245575f, + 0.735021650791168f, 0.441321671009064f, 0.735360085964203f, 0.441141277551651f, + 0.735698342323303f, 0.440960645675659f, 0.736036539077759f, 0.440779715776443f, + 0.736374497413635f, 0.440598547458649f, 0.736712396144867f, 0.440417140722275f, + 0.737050116062164f, 0.440235435962677f, 0.737387716770172f, 0.440053492784500f, + 0.737725138664246f, 0.439871311187744f, 0.738062441349030f, 0.439688831567764f, + 0.738399624824524f, 0.439506113529205f, 0.738736629486084f, 0.439323127269745f, + 0.739073514938354f, 0.439139902591705f, 0.739410281181335f, 0.438956409692764f, + 0.739746868610382f, 0.438772648572922f, 0.740083336830139f, 0.438588619232178f, + 0.740419685840607f, 0.438404351472855f, 0.740755856037140f, 0.438219845294952f, + 0.741091907024384f, 0.438035041093826f, 0.741427779197693f, 0.437849998474121f, + 0.741763532161713f, 0.437664687633514f, 0.742099165916443f, 0.437479138374329f, + 0.742434620857239f, 0.437293320894241f, 0.742769956588745f, 0.437107264995575f, + 0.743105113506317f, 0.436920911073685f, 0.743440151214600f, 0.436734348535538f, + 0.743775069713593f, 0.436547487974167f, 0.744109809398651f, 0.436360388994217f, + 0.744444429874420f, 0.436173021793365f, 0.744778931140900f, 0.435985416173935f, + 0.745113253593445f, 0.435797542333603f, 0.745447397232056f, 0.435609430074692f, + 0.745781481266022f, 0.435421019792557f, 0.746115326881409f, 0.435232400894165f, + 0.746449112892151f, 0.435043483972549f, 0.746782720088959f, 0.434854328632355f, + 0.747116148471832f, 0.434664934873581f, 0.747449457645416f, 0.434475272893906f, + 0.747782647609711f, 0.434285342693329f, 0.748115658760071f, 0.434095174074173f, + 0.748448550701141f, 0.433904737234116f, 0.748781263828278f, 0.433714061975479f, + 0.749113857746124f, 0.433523118495941f, 0.749446272850037f, 0.433331936597824f, + 0.749778568744659f, 0.433140486478806f, 0.750110685825348f, 0.432948768138886f, + 0.750442683696747f, 0.432756811380386f, 0.750774562358856f, 0.432564586400986f, + 0.751106262207031f, 0.432372123003006f, 0.751437783241272f, 0.432179391384125f, + 0.751769185066223f, 0.431986421346664f, 0.752100467681885f, 0.431793183088303f, + 0.752431571483612f, 0.431599706411362f, 0.752762496471405f, 0.431405961513519f, + 0.753093302249908f, 0.431211978197098f, 0.753423988819122f, 0.431017726659775f, + 0.753754496574402f, 0.430823236703873f, 0.754084885120392f, 0.430628478527069f, + 0.754415094852448f, 0.430433481931686f, 0.754745125770569f, 0.430238217115402f, + 0.755075037479401f, 0.430042684078217f, 0.755404829978943f, 0.429846942424774f, + 0.755734443664551f, 0.429650902748108f, 0.756063878536224f, 0.429454624652863f, + 0.756393194198608f, 0.429258108139038f, 0.756722390651703f, 0.429061323404312f, + 0.757051348686218f, 0.428864300251007f, 0.757380247116089f, 0.428667008876801f, + 0.757708966732025f, 0.428469479084015f, 0.758037507534027f, 0.428271710872650f, + 0.758365929126740f, 0.428073674440384f, 0.758694171905518f, 0.427875369787216f, + 0.759022235870361f, 0.427676826715469f, 0.759350180625916f, 0.427478045225143f, + 0.759678006172180f, 0.427278995513916f, 0.760005652904511f, 0.427079707384110f, + 0.760333120822906f, 0.426880151033401f, 0.760660469532013f, 0.426680356264114f, + 0.760987639427185f, 0.426480293273926f, 0.761314690113068f, 0.426279991865158f, + 0.761641561985016f, 0.426079452037811f, 0.761968255043030f, 0.425878643989563f, + 0.762294828891754f, 0.425677597522736f, 0.762621283531189f, 0.425476282835007f, + 0.762947499752045f, 0.425274729728699f, 0.763273596763611f, 0.425072938203812f, + 0.763599574565887f, 0.424870878458023f, 0.763925373554230f, 0.424668580293655f, + 0.764250993728638f, 0.424466013908386f, 0.764576494693756f, 0.424263238906860f, + 0.764901816844940f, 0.424060165882111f, 0.765226960182190f, 0.423856884241104f, + 0.765551984310150f, 0.423653304576874f, 0.765876889228821f, 0.423449516296387f, + 0.766201555728912f, 0.423245459794998f, 0.766526103019714f, 0.423041164875031f, + 0.766850471496582f, 0.422836631536484f, 0.767174720764160f, 0.422631829977036f, + 0.767498791217804f, 0.422426789999008f, 0.767822742462158f, 0.422221481800079f, + 0.768146514892578f, 0.422015935182571f, 0.768470108509064f, 0.421810150146484f, + 0.768793523311615f, 0.421604126691818f, 0.769116818904877f, 0.421397835016251f, + 0.769439935684204f, 0.421191304922104f, 0.769762933254242f, 0.420984506607056f, + 0.770085752010345f, 0.420777499675751f, 0.770408391952515f, 0.420570224523544f, + 0.770730912685394f, 0.420362681150436f, 0.771053194999695f, 0.420154929161072f, + 0.771375417709351f, 0.419946908950806f, 0.771697402000427f, 0.419738620519638f, + 0.772019267082214f, 0.419530123472214f, 0.772340953350067f, 0.419321358203888f, + 0.772662520408630f, 0.419112354516983f, 0.772983849048615f, 0.418903112411499f, + 0.773305058479309f, 0.418693602085114f, 0.773626148700714f, 0.418483853340149f, + 0.773947000503540f, 0.418273866176605f, 0.774267733097076f, 0.418063640594482f, + 0.774588346481323f, 0.417853146791458f, 0.774908721446991f, 0.417642414569855f, + 0.775228977203369f, 0.417431443929672f, 0.775549054145813f, 0.417220205068588f, + 0.775869011878967f, 0.417008757591248f, 0.776188731193542f, 0.416797041893005f, + 0.776508331298828f, 0.416585087776184f, 0.776827812194824f, 0.416372895240784f, + 0.777147054672241f, 0.416160434484482f, 0.777466177940369f, 0.415947735309601f, + 0.777785122394562f, 0.415734797716141f, 0.778103888034821f, 0.415521621704102f, + 0.778422534465790f, 0.415308207273483f, 0.778741002082825f, 0.415094524621964f, + 0.779059290885925f, 0.414880603551865f, 0.779377400875092f, 0.414666473865509f, + 0.779695332050323f, 0.414452046155930f, 0.780013144016266f, 0.414237409830093f, + 0.780330777168274f, 0.414022535085678f, 0.780648231506348f, 0.413807392120361f, + 0.780965566635132f, 0.413592010736465f, 0.781282722949982f, 0.413376390933990f, + 0.781599700450897f, 0.413160532712936f, 0.781916499137878f, 0.412944436073303f, + 0.782233119010925f, 0.412728071212769f, 0.782549619674683f, 0.412511497735977f, + 0.782865881919861f, 0.412294656038284f, 0.783182024955750f, 0.412077575922012f, + 0.783498048782349f, 0.411860257387161f, 0.783813834190369f, 0.411642700433731f, + 0.784129500389099f, 0.411424905061722f, 0.784444928169250f, 0.411206841468811f, + 0.784760236740112f, 0.410988569259644f, 0.785075426101685f, 0.410770028829575f, + 0.785390377044678f, 0.410551249980927f, 0.785705149173737f, 0.410332232713699f, + 0.786019802093506f, 0.410112977027893f, 0.786334276199341f, 0.409893482923508f, + 0.786648571491241f, 0.409673750400543f, 0.786962687969208f, 0.409453779459000f, + 0.787276685237885f, 0.409233570098877f, 0.787590444087982f, 0.409013092517853f, + 0.787904083728790f, 0.408792406320572f, 0.788217544555664f, 0.408571451902390f, + 0.788530826568604f, 0.408350288867950f, 0.788843929767609f, 0.408128857612610f, + 0.789156913757324f, 0.407907217741013f, 0.789469659328461f, 0.407685309648514f, + 0.789782285690308f, 0.407463163137436f, 0.790094733238220f, 0.407240778207779f, + 0.790407001972198f, 0.407018154859543f, 0.790719091892242f, 0.406795293092728f, + 0.791031002998352f, 0.406572192907333f, 0.791342735290527f, 0.406348884105682f, + 0.791654348373413f, 0.406125307083130f, 0.791965723037720f, 0.405901491641998f, + 0.792276978492737f, 0.405677437782288f, 0.792588055133820f, 0.405453115701675f, + 0.792898952960968f, 0.405228585004807f, 0.793209671974182f, 0.405003815889359f, + 0.793520212173462f, 0.404778808355331f, 0.793830573558807f, 0.404553562402725f, + 0.794140756130219f, 0.404328078031540f, 0.794450819492340f, 0.404102355241776f, + 0.794760644435883f, 0.403876423835754f, 0.795070350170136f, 0.403650224208832f, + 0.795379877090454f, 0.403423786163330f, 0.795689165592194f, 0.403197109699249f, + 0.795998334884644f, 0.402970194816589f, 0.796307325363159f, 0.402743041515350f, + 0.796616137027740f, 0.402515679597855f, 0.796924769878387f, 0.402288049459457f, + 0.797233223915100f, 0.402060180902481f, 0.797541558742523f, 0.401832103729248f, + 0.797849655151367f, 0.401603758335114f, 0.798157572746277f, 0.401375204324722f, + 0.798465371131897f, 0.401146411895752f, 0.798772931098938f, 0.400917351245880f, + 0.799080371856689f, 0.400688081979752f, 0.799387574195862f, 0.400458574295044f, + 0.799694657325745f, 0.400228828191757f, 0.800001561641693f, 0.399998843669891f, + 0.800308227539063f, 0.399768620729446f, 0.800614774227142f, 0.399538189172745f, + 0.800921142101288f, 0.399307489395142f, 0.801227271556854f, 0.399076581001282f, + 0.801533281803131f, 0.398845434188843f, 0.801839113235474f, 0.398614019155502f, + 0.802144765853882f, 0.398382395505905f, 0.802450239658356f, 0.398150533437729f, + 0.802755534648895f, 0.397918462753296f, 0.803060650825500f, 0.397686123847961f, + 0.803365588188171f, 0.397453576326370f, 0.803670346736908f, 0.397220760583878f, + 0.803974866867065f, 0.396987736225128f, 0.804279267787933f, 0.396754473447800f, + 0.804583489894867f, 0.396520972251892f, 0.804887533187866f, 0.396287262439728f, + 0.805191397666931f, 0.396053284406662f, 0.805495083332062f, 0.395819097757339f, + 0.805798590183258f, 0.395584672689438f, 0.806101918220520f, 0.395350009202957f, + 0.806405067443848f, 0.395115107297897f, 0.806707978248596f, 0.394879996776581f, + 0.807010769844055f, 0.394644618034363f, 0.807313382625580f, 0.394409030675888f, + 0.807615816593170f, 0.394173204898834f, 0.807918012142181f, 0.393937170505524f, + 0.808220088481903f, 0.393700867891312f, 0.808521986007690f, 0.393464356660843f, + 0.808823645114899f, 0.393227607011795f, 0.809125185012817f, 0.392990618944168f, + 0.809426486492157f, 0.392753422260284f, 0.809727668762207f, 0.392515957355499f, + 0.810028612613678f, 0.392278283834457f, 0.810329377651215f, 0.392040401697159f, + 0.810629963874817f, 0.391802251338959f, 0.810930430889130f, 0.391563892364502f, + 0.811230659484863f, 0.391325294971466f, 0.811530709266663f, 0.391086459159851f, + 0.811830580234528f, 0.390847414731979f, 0.812130272388458f, 0.390608131885529f, + 0.812429726123810f, 0.390368610620499f, 0.812729060649872f, 0.390128880739212f, + 0.813028216362000f, 0.389888882637024f, 0.813327133655548f, 0.389648675918579f, + 0.813625931739807f, 0.389408260583878f, 0.813924491405487f, 0.389167606830597f, + 0.814222872257233f, 0.388926714658737f, 0.814521074295044f, 0.388685584068298f, + 0.814819097518921f, 0.388444244861603f, 0.815116941928864f, 0.388202667236328f, + 0.815414607524872f, 0.387960851192474f, 0.815712094306946f, 0.387718826532364f, + 0.816009342670441f, 0.387476563453674f, 0.816306471824646f, 0.387234061956406f, + 0.816603362560272f, 0.386991351842880f, 0.816900074481964f, 0.386748403310776f, + 0.817196667194366f, 0.386505216360092f, 0.817493021488190f, 0.386261820793152f, + 0.817789137363434f, 0.386018186807632f, 0.818085134029388f, 0.385774344205856f, + 0.818380951881409f, 0.385530263185501f, 0.818676531314850f, 0.385285943746567f, + 0.818971931934357f, 0.385041415691376f, 0.819267153739929f, 0.384796649217606f, + 0.819562196731567f, 0.384551674127579f, 0.819857060909271f, 0.384306460618973f, + 0.820151746273041f, 0.384061008691788f, 0.820446193218231f, 0.383815348148346f, + 0.820740520954132f, 0.383569449186325f, 0.821034610271454f, 0.383323341608047f, + 0.821328520774841f, 0.383076995611191f, 0.821622252464294f, 0.382830440998077f, + 0.821915745735168f, 0.382583618164063f, 0.822209119796753f, 0.382336616516113f, + 0.822502255439758f, 0.382089376449585f, 0.822795212268829f, 0.381841897964478f, + 0.823087990283966f, 0.381594210863113f, 0.823380589485168f, 0.381346285343170f, + 0.823673009872437f, 0.381098151206970f, 0.823965191841125f, 0.380849778652191f, + 0.824257194995880f, 0.380601197481155f, 0.824549019336700f, 0.380352377891541f, + 0.824840664863586f, 0.380103349685669f, 0.825132071971893f, 0.379854083061218f, + 0.825423359870911f, 0.379604607820511f, 0.825714409351349f, 0.379354894161224f, + 0.826005280017853f, 0.379104942083359f, 0.826295912265778f, 0.378854811191559f, + 0.826586425304413f, 0.378604412078857f, 0.826876699924469f, 0.378353834152222f, + 0.827166795730591f, 0.378102988004684f, 0.827456712722778f, 0.377851963043213f, + 0.827746450901031f, 0.377600699663162f, 0.828035950660706f, 0.377349197864532f, + 0.828325271606445f, 0.377097487449646f, 0.828614413738251f, 0.376845568418503f, + 0.828903317451477f, 0.376593410968781f, 0.829192101955414f, 0.376341015100479f, + 0.829480648040771f, 0.376088410615921f, 0.829769015312195f, 0.375835597515106f, + 0.830057144165039f, 0.375582575798035f, 0.830345153808594f, 0.375329315662384f, + 0.830632925033569f, 0.375075817108154f, 0.830920517444611f, 0.374822109937668f, + 0.831207871437073f, 0.374568194150925f, 0.831495106220245f, 0.374314039945602f, + 0.831782102584839f, 0.374059677124023f, 0.832068860530853f, 0.373805105686188f, + 0.832355499267578f, 0.373550295829773f, 0.832641899585724f, 0.373295277357101f, + 0.832928121089935f, 0.373040050268173f, 0.833214163780212f, 0.372784584760666f, + 0.833499968051910f, 0.372528880834579f, 0.833785593509674f, 0.372272998094559f, + 0.834071040153503f, 0.372016876935959f, 0.834356248378754f, 0.371760547161102f, + 0.834641277790070f, 0.371503978967667f, 0.834926128387451f, 0.371247202157974f, + 0.835210800170898f, 0.370990216732025f, 0.835495233535767f, 0.370732992887497f, + 0.835779488086700f, 0.370475560426712f, 0.836063504219055f, 0.370217919349670f, + 0.836347401142120f, 0.369960039854050f, 0.836631059646606f, 0.369701951742172f, + 0.836914479732513f, 0.369443655014038f, 0.837197780609131f, 0.369185149669647f, + 0.837480843067169f, 0.368926405906677f, 0.837763667106628f, 0.368667453527451f, + 0.838046371936798f, 0.368408292531967f, 0.838328838348389f, 0.368148893117905f, + 0.838611066341400f, 0.367889285087585f, 0.838893175125122f, 0.367629468441010f, + 0.839175045490265f, 0.367369443178177f, 0.839456677436829f, 0.367109179496765f, + 0.839738130569458f, 0.366848707199097f, 0.840019404888153f, 0.366588026285172f, + 0.840300500392914f, 0.366327136754990f, 0.840581357479095f, 0.366066008806229f, + 0.840862035751343f, 0.365804702043533f, 0.841142535209656f, 0.365543156862259f, + 0.841422796249390f, 0.365281373262405f, 0.841702818870544f, 0.365019410848618f, + 0.841982722282410f, 0.364757210016251f, 0.842262387275696f, 0.364494800567627f, + 0.842541813850403f, 0.364232182502747f, 0.842821121215820f, 0.363969355821610f, + 0.843100130558014f, 0.363706320524216f, 0.843379020690918f, 0.363443046808243f, + 0.843657672405243f, 0.363179564476013f, 0.843936145305634f, 0.362915903329849f, + 0.844214379787445f, 0.362651973962784f, 0.844492435455322f, 0.362387865781784f, + 0.844770252704620f, 0.362123548984528f, 0.845047891139984f, 0.361858993768692f, + 0.845325350761414f, 0.361594229936600f, 0.845602571964264f, 0.361329287290573f, + 0.845879614353180f, 0.361064106225967f, 0.846156477928162f, 0.360798716545105f, + 0.846433103084564f, 0.360533088445663f, 0.846709489822388f, 0.360267281532288f, + 0.846985757350922f, 0.360001266002655f, 0.847261726856232f, 0.359735012054443f, + 0.847537577152252f, 0.359468549489975f, 0.847813189029694f, 0.359201908111572f, + 0.848088562488556f, 0.358935028314590f, 0.848363757133484f, 0.358667939901352f, + 0.848638772964478f, 0.358400642871857f, 0.848913550376892f, 0.358133137226105f, + 0.849188148975372f, 0.357865422964096f, 0.849462509155273f, 0.357597470283508f, + 0.849736690521240f, 0.357329338788986f, 0.850010633468628f, 0.357060998678207f, + 0.850284397602081f, 0.356792420148849f, 0.850557923316956f, 0.356523662805557f, + 0.850831270217896f, 0.356254696846008f, 0.851104438304901f, 0.355985492467880f, + 0.851377367973328f, 0.355716109275818f, 0.851650118827820f, 0.355446487665176f, + 0.851922631263733f, 0.355176687240601f, 0.852194905281067f, 0.354906648397446f, + 0.852467060089111f, 0.354636400938034f, 0.852738916873932f, 0.354365974664688f, + 0.853010654449463f, 0.354095309972763f, 0.853282094001770f, 0.353824466466904f, + 0.853553414344788f, 0.353553384542465f, 0.853824436664581f, 0.353282123804092f, + 0.854095339775085f, 0.353010624647141f, 0.854365944862366f, 0.352738946676254f, + 0.854636430740356f, 0.352467030286789f, 0.854906618595123f, 0.352194935083389f, + 0.855176687240601f, 0.351922631263733f, 0.855446517467499f, 0.351650089025497f, + 0.855716109275818f, 0.351377367973328f, 0.855985522270203f, 0.351104438304901f, + 0.856254696846008f, 0.350831300020218f, 0.856523692607880f, 0.350557953119278f, + 0.856792449951172f, 0.350284397602081f, 0.857060968875885f, 0.350010633468628f, + 0.857329368591309f, 0.349736660718918f, 0.857597470283508f, 0.349462509155273f, + 0.857865393161774f, 0.349188119173050f, 0.858133137226105f, 0.348913550376892f, + 0.858400642871857f, 0.348638743162155f, 0.858667910099030f, 0.348363757133484f, + 0.858934998512268f, 0.348088562488556f, 0.859201908111572f, 0.347813159227371f, + 0.859468579292297f, 0.347537547349930f, 0.859735012054443f, 0.347261756658554f, + 0.860001266002655f, 0.346985727548599f, 0.860267281532288f, 0.346709519624710f, + 0.860533118247986f, 0.346433073282242f, 0.860798716545105f, 0.346156448125839f, + 0.861064076423645f, 0.345879614353180f, 0.861329257488251f, 0.345602601766586f, + 0.861594259738922f, 0.345325350761414f, 0.861859023571014f, 0.345047920942307f, + 0.862123548984528f, 0.344770282506943f, 0.862387895584106f, 0.344492435455322f, + 0.862652003765106f, 0.344214379787445f, 0.862915873527527f, 0.343936115503311f, + 0.863179564476013f, 0.343657672405243f, 0.863443076610565f, 0.343379020690918f, + 0.863706290721893f, 0.343100160360336f, 0.863969385623932f, 0.342821091413498f, + 0.864232182502747f, 0.342541843652725f, 0.864494800567627f, 0.342262357473373f, + 0.864757239818573f, 0.341982692480087f, 0.865019381046295f, 0.341702848672867f, + 0.865281403064728f, 0.341422766447067f, 0.865543127059937f, 0.341142505407333f, + 0.865804672241211f, 0.340862035751343f, 0.866066038608551f, 0.340581357479095f, + 0.866327106952667f, 0.340300500392914f, 0.866588056087494f, 0.340019434690475f, + 0.866848707199097f, 0.339738160371780f, 0.867109179496765f, 0.339456677436829f, + 0.867369413375854f, 0.339175015687943f, 0.867629468441010f, 0.338893145322800f, + 0.867889285087585f, 0.338611096143723f, 0.868148922920227f, 0.338328808546066f, + 0.868408262729645f, 0.338046342134476f, 0.868667483329773f, 0.337763696908951f, + 0.868926405906677f, 0.337480813264847f, 0.869185149669647f, 0.337197750806808f, + 0.869443655014038f, 0.336914509534836f, 0.869701981544495f, 0.336631029844284f, + 0.869960069656372f, 0.336347371339798f, 0.870217919349670f, 0.336063534021378f, + 0.870475590229034f, 0.335779488086700f, 0.870733022689819f, 0.335495233535767f, + 0.870990216732025f, 0.335210770368576f, 0.871247172355652f, 0.334926128387451f, + 0.871503949165344f, 0.334641307592392f, 0.871760547161102f, 0.334356248378754f, + 0.872016847133636f, 0.334071010351181f, 0.872272968292236f, 0.333785593509674f, + 0.872528910636902f, 0.333499968051910f, 0.872784554958344f, 0.333214133977890f, + 0.873040020465851f, 0.332928121089935f, 0.873295307159424f, 0.332641899585724f, + 0.873550295829773f, 0.332355499267578f, 0.873805105686188f, 0.332068890333176f, + 0.874059677124023f, 0.331782072782516f, 0.874314069747925f, 0.331495076417923f, + 0.874568223953247f, 0.331207901239395f, 0.874822139739990f, 0.330920487642288f, + 0.875075817108154f, 0.330632925033569f, 0.875329315662384f, 0.330345153808594f, + 0.875582575798035f, 0.330057173967361f, 0.875835597515106f, 0.329769015312195f, + 0.876088440418243f, 0.329480648040771f, 0.876341044902802f, 0.329192101955414f, + 0.876593410968781f, 0.328903347253799f, 0.876845538616180f, 0.328614413738251f, + 0.877097487449646f, 0.328325271606445f, 0.877349197864532f, 0.328035950660706f, + 0.877600669860840f, 0.327746421098709f, 0.877851963043213f, 0.327456712722778f, + 0.878103017807007f, 0.327166795730591f, 0.878353834152222f, 0.326876699924469f, + 0.878604412078857f, 0.326586425304413f, 0.878854811191559f, 0.326295942068100f, + 0.879104971885681f, 0.326005280017853f, 0.879354894161224f, 0.325714409351349f, + 0.879604578018188f, 0.325423330068588f, 0.879854083061218f, 0.325132101774216f, + 0.880103349685669f, 0.324840664863586f, 0.880352377891541f, 0.324549019336700f, + 0.880601167678833f, 0.324257194995880f, 0.880849778652191f, 0.323965191841125f, + 0.881098151206970f, 0.323672980070114f, 0.881346285343170f, 0.323380589485168f, + 0.881594181060791f, 0.323088020086288f, 0.881841897964478f, 0.322795242071152f, + 0.882089376449585f, 0.322502255439758f, 0.882336616516113f, 0.322209119796753f, + 0.882583618164063f, 0.321915775537491f, 0.882830440998077f, 0.321622252464294f, + 0.883076965808868f, 0.321328520774841f, 0.883323311805725f, 0.321034610271454f, + 0.883569478988647f, 0.320740520954132f, 0.883815348148346f, 0.320446223020554f, + 0.884061038494110f, 0.320151746273041f, 0.884306430816650f, 0.319857090711594f, + 0.884551644325256f, 0.319562226533890f, 0.884796679019928f, 0.319267183542252f, + 0.885041415691376f, 0.318971961736679f, 0.885285973548889f, 0.318676531314850f, + 0.885530233383179f, 0.318380922079086f, 0.885774314403534f, 0.318085134029388f, + 0.886018216609955f, 0.317789167165756f, 0.886261820793152f, 0.317492991685867f, + 0.886505246162415f, 0.317196637392044f, 0.886748373508453f, 0.316900104284287f, + 0.886991322040558f, 0.316603392362595f, 0.887234091758728f, 0.316306471824646f, + 0.887476563453674f, 0.316009372472763f, 0.887718796730042f, 0.315712094306946f, + 0.887960851192474f, 0.315414607524872f, 0.888202667236328f, 0.315116971731186f, + 0.888444244861603f, 0.314819127321243f, 0.888685584068298f, 0.314521104097366f, + 0.888926684856415f, 0.314222872257233f, 0.889167606830597f, 0.313924491405487f, + 0.889408230781555f, 0.313625901937485f, 0.889648675918579f, 0.313327133655548f, + 0.889888882637024f, 0.313028186559677f, 0.890128850936890f, 0.312729060649872f, + 0.890368640422821f, 0.312429755926132f, 0.890608131885529f, 0.312130242586136f, + 0.890847444534302f, 0.311830550432205f, 0.891086459159851f, 0.311530679464340f, + 0.891325294971466f, 0.311230629682541f, 0.891563892364502f, 0.310930401086807f, + 0.891802251338959f, 0.310629993677139f, 0.892040371894836f, 0.310329377651215f, + 0.892278313636780f, 0.310028612613678f, 0.892515957355499f, 0.309727638959885f, + 0.892753422260284f, 0.309426486492157f, 0.892990648746490f, 0.309125155210495f, + 0.893227577209473f, 0.308823645114899f, 0.893464326858521f, 0.308521956205368f, + 0.893700897693634f, 0.308220088481903f, 0.893937170505524f, 0.307918041944504f, + 0.894173204898834f, 0.307615786790848f, 0.894409060478210f, 0.307313382625580f, + 0.894644618034363f, 0.307010769844055f, 0.894879996776581f, 0.306708008050919f, + 0.895115137100220f, 0.306405037641525f, 0.895349979400635f, 0.306101888418198f, + 0.895584642887115f, 0.305798590183258f, 0.895819067955017f, 0.305495083332062f, + 0.896053314208984f, 0.305191397666931f, 0.896287262439728f, 0.304887533187866f, + 0.896520972251892f, 0.304583519697189f, 0.896754503250122f, 0.304279297590256f, + 0.896987736225128f, 0.303974896669388f, 0.897220790386200f, 0.303670316934586f, + 0.897453546524048f, 0.303365558385849f, 0.897686123847961f, 0.303060621023178f, + 0.897918462753296f, 0.302755534648895f, 0.898150563240051f, 0.302450239658356f, + 0.898382425308228f, 0.302144765853882f, 0.898614048957825f, 0.301839113235474f, + 0.898845434188843f, 0.301533311605453f, 0.899076581001282f, 0.301227301359177f, + 0.899307489395142f, 0.300921112298965f, 0.899538159370422f, 0.300614774227142f, + 0.899768650531769f, 0.300308227539063f, 0.899998843669891f, 0.300001531839371f, + 0.900228857994080f, 0.299694657325745f, 0.900458574295044f, 0.299387603998184f, + 0.900688111782074f, 0.299080342054367f, 0.900917351245880f, 0.298772931098938f, + 0.901146411895752f, 0.298465341329575f, 0.901375174522400f, 0.298157602548599f, + 0.901603758335114f, 0.297849655151367f, 0.901832103729248f, 0.297541528940201f, + 0.902060210704803f, 0.297233253717422f, 0.902288019657135f, 0.296924799680710f, + 0.902515649795532f, 0.296616137027740f, 0.902743041515350f, 0.296307325363159f, + 0.902970194816589f, 0.295998334884644f, 0.903197109699249f, 0.295689195394516f, + 0.903423786163330f, 0.295379847288132f, 0.903650224208832f, 0.295070350170136f, + 0.903876423835754f, 0.294760644435883f, 0.904102385044098f, 0.294450789690018f, + 0.904328107833862f, 0.294140785932541f, 0.904553592205048f, 0.293830573558807f, + 0.904778838157654f, 0.293520182371140f, 0.905003845691681f, 0.293209642171860f, + 0.905228614807129f, 0.292898923158646f, 0.905453145503998f, 0.292588025331497f, + 0.905677437782288f, 0.292276978492737f, 0.905901491641998f, 0.291965723037720f, + 0.906125307083130f, 0.291654318571091f, 0.906348884105682f, 0.291342735290527f, + 0.906572222709656f, 0.291031002998352f, 0.906795322895050f, 0.290719062089920f, + 0.907018184661865f, 0.290406972169876f, 0.907240808010101f, 0.290094703435898f, + 0.907463192939758f, 0.289782285690308f, 0.907685279846191f, 0.289469659328461f, + 0.907907187938690f, 0.289156883955002f, 0.908128857612610f, 0.288843959569931f, + 0.908350288867950f, 0.288530826568604f, 0.908571481704712f, 0.288217544555664f, + 0.908792436122894f, 0.287904083728790f, 0.909013092517853f, 0.287590473890305f, + 0.909233570098877f, 0.287276685237885f, 0.909453809261322f, 0.286962717771530f, + 0.909673750400543f, 0.286648571491241f, 0.909893512725830f, 0.286334276199341f, + 0.910112977027893f, 0.286019802093506f, 0.910332262516022f, 0.285705178976059f, + 0.910551249980927f, 0.285390377044678f, 0.910769999027252f, 0.285075396299362f, + 0.910988569259644f, 0.284760266542435f, 0.911206841468811f, 0.284444957971573f, + 0.911424875259399f, 0.284129470586777f, 0.911642670631409f, 0.283813834190369f, + 0.911860227584839f, 0.283498018980026f, 0.912077546119690f, 0.283182054758072f, + 0.912294626235962f, 0.282865911722183f, 0.912511467933655f, 0.282549589872360f, + 0.912728071212769f, 0.282233119010925f, 0.912944436073303f, 0.281916469335556f, + 0.913160502910614f, 0.281599670648575f, 0.913376390933990f, 0.281282693147659f, + 0.913592040538788f, 0.280965566635132f, 0.913807392120361f, 0.280648261308670f, + 0.914022505283356f, 0.280330777168274f, 0.914237439632416f, 0.280013144016266f, + 0.914452075958252f, 0.279695361852646f, 0.914666473865509f, 0.279377400875092f, + 0.914880633354187f, 0.279059261083603f, 0.915094554424286f, 0.278740972280502f, + 0.915308177471161f, 0.278422504663467f, 0.915521621704102f, 0.278103888034821f, + 0.915734827518463f, 0.277785122394562f, 0.915947735309601f, 0.277466177940369f, + 0.916160404682159f, 0.277147054672241f, 0.916372895240784f, 0.276827782392502f, + 0.916585087776184f, 0.276508361101151f, 0.916797041893005f, 0.276188760995865f, + 0.917008757591248f, 0.275868982076645f, 0.917220234870911f, 0.275549083948135f, + 0.917431414127350f, 0.275228977203369f, 0.917642414569855f, 0.274908751249313f, + 0.917853116989136f, 0.274588316679001f, 0.918063640594482f, 0.274267762899399f, + 0.918273866176605f, 0.273947030305862f, 0.918483853340149f, 0.273626148700714f, + 0.918693602085114f, 0.273305088281631f, 0.918903112411499f, 0.272983878850937f, + 0.919112324714661f, 0.272662490606308f, 0.919321358203888f, 0.272340953350067f, + 0.919530093669891f, 0.272019267082214f, 0.919738650321960f, 0.271697402000427f, + 0.919946908950806f, 0.271375387907028f, 0.920154929161072f, 0.271053224802017f, + 0.920362710952759f, 0.270730882883072f, 0.920570194721222f, 0.270408391952515f, + 0.920777499675751f, 0.270085722208023f, 0.920984506607056f, 0.269762933254242f, + 0.921191275119781f, 0.269439965486526f, 0.921397805213928f, 0.269116818904877f, + 0.921604096889496f, 0.268793523311615f, 0.921810150146484f, 0.268470078706741f, + 0.922015964984894f, 0.268146485090256f, 0.922221481800079f, 0.267822742462158f, + 0.922426760196686f, 0.267498821020126f, 0.922631800174713f, 0.267174720764160f, + 0.922836601734161f, 0.266850501298904f, 0.923041164875031f, 0.266526103019714f, + 0.923245489597321f, 0.266201555728912f, 0.923449516296387f, 0.265876859426498f, + 0.923653304576874f, 0.265552014112473f, 0.923856854438782f, 0.265226989984512f, + 0.924060165882111f, 0.264901816844940f, 0.924263238906860f, 0.264576494693756f, + 0.924466013908386f, 0.264250993728638f, 0.924668610095978f, 0.263925373554230f, + 0.924870908260345f, 0.263599574565887f, 0.925072908401489f, 0.263273626565933f, + 0.925274729728699f, 0.262947499752045f, 0.925476312637329f, 0.262621253728867f, + 0.925677597522736f, 0.262294828891754f, 0.925878643989563f, 0.261968284845352f, + 0.926079452037811f, 0.261641561985016f, 0.926280021667480f, 0.261314690113068f, + 0.926480293273926f, 0.260987639427185f, 0.926680326461792f, 0.260660469532013f, + 0.926880121231079f, 0.260333120822906f, 0.927079677581787f, 0.260005623102188f, + 0.927278995513916f, 0.259678006172180f, 0.927478015422821f, 0.259350210428238f, + 0.927676856517792f, 0.259022265672684f, 0.927875399589539f, 0.258694142103195f, + 0.928073644638062f, 0.258365899324417f, 0.928271710872650f, 0.258037507534027f, + 0.928469479084015f, 0.257708936929703f, 0.928667008876801f, 0.257380217313766f, + 0.928864300251007f, 0.257051378488541f, 0.929061353206635f, 0.256722360849380f, + 0.929258108139038f, 0.256393194198608f, 0.929454624652863f, 0.256063878536224f, + 0.929650902748108f, 0.255734413862228f, 0.929846942424774f, 0.255404800176620f, + 0.930042684078217f, 0.255075037479401f, 0.930238187313080f, 0.254745125770569f, + 0.930433452129364f, 0.254415065050125f, 0.930628478527069f, 0.254084855318069f, + 0.930823206901550f, 0.253754496574402f, 0.931017756462097f, 0.253423988819122f, + 0.931211948394775f, 0.253093332052231f, 0.931405961513519f, 0.252762526273727f, + 0.931599736213684f, 0.252431541681290f, 0.931793212890625f, 0.252100437879562f, + 0.931986451148987f, 0.251769185066223f, 0.932179391384125f, 0.251437783241272f, + 0.932372152805328f, 0.251106232404709f, 0.932564616203308f, 0.250774532556534f, + 0.932756841182709f, 0.250442683696747f, 0.932948768138886f, 0.250110685825348f, + 0.933140456676483f, 0.249778553843498f, 0.933331906795502f, 0.249446272850037f, + 0.933523118495941f, 0.249113827943802f, 0.933714091777802f, 0.248781248927116f, + 0.933904767036438f, 0.248448520898819f, 0.934095203876495f, 0.248115643858910f, + 0.934285342693329f, 0.247782632708550f, 0.934475243091583f, 0.247449472546577f, + 0.934664964675903f, 0.247116148471832f, 0.934854328632355f, 0.246782705187798f, + 0.935043513774872f, 0.246449097990990f, 0.935232400894165f, 0.246115356683731f, + 0.935421049594879f, 0.245781451463699f, 0.935609400272369f, 0.245447427034378f, + 0.935797572135925f, 0.245113238692284f, 0.935985386371613f, 0.244778916239738f, + 0.936173021793365f, 0.244444444775581f, 0.936360359191895f, 0.244109839200974f, + 0.936547517776489f, 0.243775084614754f, 0.936734318733215f, 0.243440181016922f, + 0.936920940876007f, 0.243105143308640f, 0.937107264995575f, 0.242769956588745f, + 0.937293350696564f, 0.242434620857239f, 0.937479138374329f, 0.242099151015282f, + 0.937664687633514f, 0.241763532161713f, 0.937849998474121f, 0.241427779197693f, + 0.938035070896149f, 0.241091892123222f, 0.938219845294952f, 0.240755841135979f, + 0.938404381275177f, 0.240419670939446f, 0.938588619232178f, 0.240083336830139f, + 0.938772618770599f, 0.239746883511543f, 0.938956379890442f, 0.239410281181335f, + 0.939139902591705f, 0.239073529839516f, 0.939323127269745f, 0.238736644387245f, + 0.939506113529205f, 0.238399609923363f, 0.939688861370087f, 0.238062441349030f, + 0.939871311187744f, 0.237725138664246f, 0.940053522586823f, 0.237387686967850f, + 0.940235435962677f, 0.237050101161003f, 0.940417110919952f, 0.236712381243706f, + 0.940598547458649f, 0.236374512314796f, 0.940779745578766f, 0.236036509275436f, + 0.940960645675659f, 0.235698372125626f, 0.941141307353973f, 0.235360085964203f, + 0.941321671009064f, 0.235021665692329f, 0.941501796245575f, 0.234683111310005f, + 0.941681683063507f, 0.234344407916069f, 0.941861271858215f, 0.234005570411682f, + 0.942040622234344f, 0.233666598796844f, 0.942219734191895f, 0.233327493071556f, + 0.942398548126221f, 0.232988253235817f, 0.942577123641968f, 0.232648864388466f, + 0.942755401134491f, 0.232309341430664f, 0.942933499813080f, 0.231969684362412f, + 0.943111240863800f, 0.231629893183708f, 0.943288803100586f, 0.231289967894554f, + 0.943466067314148f, 0.230949893593788f, 0.943643093109131f, 0.230609700083733f, + 0.943819820880890f, 0.230269357562065f, 0.943996310234070f, 0.229928880929947f, + 0.944172501564026f, 0.229588270187378f, 0.944348454475403f, 0.229247525334358f, + 0.944524168968201f, 0.228906646370888f, 0.944699645042419f, 0.228565633296967f, + 0.944874763488770f, 0.228224486112595f, 0.945049703121185f, 0.227883204817772f, + 0.945224344730377f, 0.227541789412498f, 0.945398747920990f, 0.227200239896774f, + 0.945572853088379f, 0.226858556270599f, 0.945746779441834f, 0.226516738533974f, + 0.945920348167419f, 0.226174786686897f, 0.946093678474426f, 0.225832715630531f, + 0.946266770362854f, 0.225490495562553f, 0.946439623832703f, 0.225148141384125f, + 0.946612179279327f, 0.224805667996407f, 0.946784436702728f, 0.224463045597076f, + 0.946956455707550f, 0.224120303988457f, 0.947128236293793f, 0.223777428269386f, + 0.947299718856812f, 0.223434418439865f, 0.947470963001251f, 0.223091274499893f, + 0.947641968727112f, 0.222748011350632f, 0.947812676429749f, 0.222404599189758f, + 0.947983145713806f, 0.222061067819595f, 0.948153316974640f, 0.221717402338982f, + 0.948323249816895f, 0.221373617649078f, 0.948492884635925f, 0.221029683947563f, + 0.948662281036377f, 0.220685631036758f, 0.948831439018250f, 0.220341444015503f, + 0.949000298976898f, 0.219997137784958f, 0.949168920516968f, 0.219652697443962f, + 0.949337244033813f, 0.219308122992516f, 0.949505329132080f, 0.218963414430618f, + 0.949673116207123f, 0.218618586659431f, 0.949840664863586f, 0.218273624777794f, + 0.950007975101471f, 0.217928543686867f, 0.950174987316132f, 0.217583328485489f, + 0.950341701507568f, 0.217237979173660f, 0.950508177280426f, 0.216892510652542f, + 0.950674414634705f, 0.216546908020973f, 0.950840353965759f, 0.216201186180115f, + 0.951006054878235f, 0.215855330228806f, 0.951171517372131f, 0.215509355068207f, + 0.951336681842804f, 0.215163245797157f, 0.951501548290253f, 0.214817002415657f, + 0.951666176319122f, 0.214470639824867f, 0.951830565929413f, 0.214124158024788f, + 0.951994657516479f, 0.213777542114258f, 0.952158451080322f, 0.213430806994438f, + 0.952322065830231f, 0.213083937764168f, 0.952485322952271f, 0.212736949324608f, + 0.952648401260376f, 0.212389841675758f, 0.952811121940613f, 0.212042599916458f, + 0.952973663806915f, 0.211695238947868f, 0.953135907649994f, 0.211347743868828f, + 0.953297853469849f, 0.211000129580498f, 0.953459560871124f, 0.210652396082878f, + 0.953620970249176f, 0.210304543375969f, 0.953782141208649f, 0.209956556558609f, + 0.953943073749542f, 0.209608450531960f, 0.954103708267212f, 0.209260210394859f, + 0.954264044761658f, 0.208911851048470f, 0.954424142837524f, 0.208563387393951f, + 0.954584002494812f, 0.208214774727821f, 0.954743564128876f, 0.207866057753563f, + 0.954902827739716f, 0.207517206668854f, 0.955061912536621f, 0.207168251276016f, + 0.955220639705658f, 0.206819161772728f, 0.955379128456116f, 0.206469938158989f, + 0.955537378787994f, 0.206120610237122f, 0.955695331096649f, 0.205771163105965f, + 0.955853044986725f, 0.205421581864357f, 0.956010460853577f, 0.205071896314621f, + 0.956167578697205f, 0.204722076654434f, 0.956324458122253f, 0.204372137784958f, + 0.956481099128723f, 0.204022079706192f, 0.956637442111969f, 0.203671902418137f, + 0.956793546676636f, 0.203321605920792f, 0.956949353218079f, 0.202971190214157f, + 0.957104861736298f, 0.202620655298233f, 0.957260131835938f, 0.202270001173019f, + 0.957415163516998f, 0.201919227838516f, 0.957569897174835f, 0.201568335294724f, + 0.957724332809448f, 0.201217323541641f, 0.957878530025482f, 0.200866192579269f, + 0.958032488822937f, 0.200514942407608f, 0.958186149597168f, 0.200163587927818f, + 0.958339512348175f, 0.199812099337578f, 0.958492636680603f, 0.199460506439209f, + 0.958645522594452f, 0.199108779430389f, 0.958798050880432f, 0.198756948113441f, + 0.958950400352478f, 0.198404997587204f, 0.959102451801300f, 0.198052927851677f, + 0.959254205226898f, 0.197700738906860f, 0.959405720233917f, 0.197348430752754f, + 0.959556937217712f, 0.196996018290520f, 0.959707856178284f, 0.196643486618996f, + 0.959858596324921f, 0.196290835738182f, 0.960008978843689f, 0.195938065648079f, + 0.960159122943878f, 0.195585191249847f, 0.960309028625488f, 0.195232197642326f, + 0.960458636283875f, 0.194879084825516f, 0.960607945919037f, 0.194525867700577f, + 0.960757017135620f, 0.194172516465187f, 0.960905790328979f, 0.193819075822830f, + 0.961054325103760f, 0.193465501070023f, 0.961202561855316f, 0.193111822009087f, + 0.961350560188293f, 0.192758023738861f, 0.961498260498047f, 0.192404121160507f, + 0.961645722389221f, 0.192050099372864f, 0.961792886257172f, 0.191695958375931f, + 0.961939752101898f, 0.191341713070869f, 0.962086379528046f, 0.190987363457680f, + 0.962232708930969f, 0.190632879734039f, 0.962378799915314f, 0.190278306603432f, + 0.962524592876434f, 0.189923599362373f, 0.962670147418976f, 0.189568802714348f, + 0.962815403938293f, 0.189213871955872f, 0.962960422039032f, 0.188858851790428f, + 0.963105142116547f, 0.188503712415695f, 0.963249564170837f, 0.188148453831673f, + 0.963393747806549f, 0.187793090939522f, 0.963537633419037f, 0.187437608838081f, + 0.963681280612946f, 0.187082037329674f, 0.963824629783630f, 0.186726331710815f, + 0.963967680931091f, 0.186370536684990f, 0.964110493659973f, 0.186014622449875f, + 0.964253067970276f, 0.185658603906631f, 0.964395284652710f, 0.185302466154099f, + 0.964537262916565f, 0.184946224093437f, 0.964679002761841f, 0.184589877724648f, + 0.964820444583893f, 0.184233412146568f, 0.964961588382721f, 0.183876842260361f, + 0.965102493762970f, 0.183520168066025f, 0.965243160724640f, 0.183163389563560f, + 0.965383470058441f, 0.182806491851807f, 0.965523540973663f, 0.182449504733086f, + 0.965663373470306f, 0.182092398405075f, 0.965802907943726f, 0.181735187768936f, + 0.965942144393921f, 0.181377857923508f, 0.966081082820892f, 0.181020438671112f, + 0.966219842433929f, 0.180662900209427f, 0.966358244419098f, 0.180305257439613f, + 0.966496407985687f, 0.179947525262833f, 0.966634273529053f, 0.179589673876762f, + 0.966771900653839f, 0.179231703281403f, 0.966909229755402f, 0.178873643279076f, + 0.967046260833740f, 0.178515478968620f, 0.967183053493500f, 0.178157210350037f, + 0.967319548130035f, 0.177798837423325f, 0.967455804347992f, 0.177440345287323f, + 0.967591762542725f, 0.177081763744354f, 0.967727422714233f, 0.176723077893257f, + 0.967862844467163f, 0.176364272832870f, 0.967997968196869f, 0.176005378365517f, + 0.968132853507996f, 0.175646379590034f, 0.968267440795898f, 0.175287276506424f, + 0.968401730060577f, 0.174928069114685f, 0.968535780906677f, 0.174568757414818f, + 0.968669533729553f, 0.174209341406822f, 0.968802988529205f, 0.173849821090698f, + 0.968936204910278f, 0.173490211367607f, 0.969069123268127f, 0.173130482435226f, + 0.969201743602753f, 0.172770664095879f, 0.969334125518799f, 0.172410741448402f, + 0.969466269016266f, 0.172050714492798f, 0.969598054885864f, 0.171690583229065f, + 0.969729602336884f, 0.171330362558365f, 0.969860911369324f, 0.170970037579536f, + 0.969991862773895f, 0.170609608292580f, 0.970122575759888f, 0.170249074697495f, + 0.970253050327301f, 0.169888436794281f, 0.970383226871490f, 0.169527709484100f, + 0.970513105392456f, 0.169166877865791f, 0.970642685890198f, 0.168805956840515f, + 0.970772027969360f, 0.168444931507111f, 0.970901072025299f, 0.168083801865578f, + 0.971029877662659f, 0.167722567915916f, 0.971158385276794f, 0.167361244559288f, + 0.971286594867706f, 0.166999831795692f, 0.971414566040039f, 0.166638299822807f, + 0.971542239189148f, 0.166276678442955f, 0.971669614315033f, 0.165914967656136f, + 0.971796751022339f, 0.165553152561188f, 0.971923589706421f, 0.165191248059273f, + 0.972050130367279f, 0.164829224348068f, 0.972176432609558f, 0.164467126131058f, + 0.972302436828613f, 0.164104923605919f, 0.972428143024445f, 0.163742616772652f, + 0.972553610801697f, 0.163380220532417f, 0.972678780555725f, 0.163017734885216f, + 0.972803652286530f, 0.162655144929886f, 0.972928285598755f, 0.162292465567589f, + 0.973052620887756f, 0.161929681897163f, 0.973176658153534f, 0.161566808819771f, + 0.973300457000732f, 0.161203846335411f, 0.973423957824707f, 0.160840779542923f, + 0.973547160625458f, 0.160477623343468f, 0.973670125007629f, 0.160114362835884f, + 0.973792791366577f, 0.159751012921333f, 0.973915159702301f, 0.159387573599815f, + 0.974037289619446f, 0.159024044871330f, 0.974159121513367f, 0.158660411834717f, + 0.974280655384064f, 0.158296689391136f, 0.974401950836182f, 0.157932877540588f, + 0.974522948265076f, 0.157568961381912f, 0.974643647670746f, 0.157204970717430f, + 0.974764108657837f, 0.156840875744820f, 0.974884271621704f, 0.156476691365242f, + 0.975004136562347f, 0.156112402677536f, 0.975123703479767f, 0.155748039484024f, + 0.975243031978607f, 0.155383571982384f, 0.975362062454224f, 0.155019029974937f, + 0.975480854511261f, 0.154654383659363f, 0.975599288940430f, 0.154289647936821f, + 0.975717484951019f, 0.153924822807312f, 0.975835442543030f, 0.153559908270836f, + 0.975953042507172f, 0.153194904327393f, 0.976070404052734f, 0.152829796075821f, + 0.976187527179718f, 0.152464613318443f, 0.976304292678833f, 0.152099341154099f, + 0.976420819759369f, 0.151733979582787f, 0.976537048816681f, 0.151368513703346f, + 0.976653039455414f, 0.151002973318100f, 0.976768672466278f, 0.150637343525887f, + 0.976884067058563f, 0.150271624326706f, 0.976999223232269f, 0.149905815720558f, + 0.977114021778107f, 0.149539917707443f, 0.977228581905365f, 0.149173930287361f, + 0.977342903614044f, 0.148807853460312f, 0.977456867694855f, 0.148441687226295f, + 0.977570593357086f, 0.148075446486473f, 0.977684020996094f, 0.147709101438522f, + 0.977797150611877f, 0.147342681884766f, 0.977910041809082f, 0.146976172924042f, + 0.978022634983063f, 0.146609574556351f, 0.978134930133820f, 0.146242901682854f, + 0.978246986865997f, 0.145876124501228f, 0.978358685970306f, 0.145509272813797f, + 0.978470146656036f, 0.145142331719399f, 0.978581368923187f, 0.144775316119194f, + 0.978692233562469f, 0.144408211112022f, 0.978802859783173f, 0.144041016697884f, + 0.978913187980652f, 0.143673732876778f, 0.979023277759552f, 0.143306359648705f, + 0.979133009910584f, 0.142938911914825f, 0.979242503643036f, 0.142571389675140f, + 0.979351758956909f, 0.142203763127327f, 0.979460656642914f, 0.141836062073708f, + 0.979569315910339f, 0.141468286514282f, 0.979677677154541f, 0.141100421547890f, + 0.979785740375519f, 0.140732467174530f, 0.979893565177917f, 0.140364438295364f, + 0.980001091957092f, 0.139996320009232f, 0.980108320713043f, 0.139628127217293f, + 0.980215251445770f, 0.139259845018387f, 0.980321943759918f, 0.138891488313675f, + 0.980428338050842f, 0.138523042201996f, 0.980534434318542f, 0.138154521584511f, + 0.980640232563019f, 0.137785911560059f, 0.980745792388916f, 0.137417227029800f, + 0.980851054191589f, 0.137048453092575f, 0.980956017971039f, 0.136679604649544f, + 0.981060683727264f, 0.136310681700706f, 0.981165111064911f, 0.135941669344902f, + 0.981269240379334f, 0.135572582483292f, 0.981373071670532f, 0.135203406214714f, + 0.981476604938507f, 0.134834155440331f, 0.981579899787903f, 0.134464830160141f, + 0.981682896614075f, 0.134095430374146f, 0.981785595417023f, 0.133725941181183f, + 0.981888055801392f, 0.133356377482414f, 0.981990158557892f, 0.132986739277840f, + 0.982092022895813f, 0.132617011666298f, 0.982193589210510f, 0.132247209548950f, + 0.982294917106628f, 0.131877332925797f, 0.982395887374878f, 0.131507381796837f, + 0.982496619224548f, 0.131137356162071f, 0.982597053050995f, 0.130767241120338f, + 0.982697248458862f, 0.130397051572800f, 0.982797086238861f, 0.130026802420616f, + 0.982896685600281f, 0.129656463861465f, 0.982995986938477f, 0.129286035895348f, + 0.983094990253448f, 0.128915548324585f, 0.983193755149841f, 0.128544986248016f, + 0.983292162418365f, 0.128174334764481f, 0.983390331268311f, 0.127803623676300f, + 0.983488261699677f, 0.127432823181152f, 0.983585834503174f, 0.127061963081360f, + 0.983683168888092f, 0.126691013574600f, 0.983780145645142f, 0.126320004463196f, + 0.983876943588257f, 0.125948905944824f, 0.983973383903503f, 0.125577747821808f, + 0.984069526195526f, 0.125206500291824f, 0.984165430068970f, 0.124835193157196f, + 0.984261035919189f, 0.124463804066181f, 0.984356343746185f, 0.124092340469360f, + 0.984451413154602f, 0.123720809817314f, 0.984546124935150f, 0.123349204659462f, + 0.984640598297119f, 0.122977524995804f, 0.984734773635864f, 0.122605770826340f, + 0.984828710556030f, 0.122233949601650f, 0.984922289848328f, 0.121862053871155f, + 0.985015630722046f, 0.121490091085434f, 0.985108673572540f, 0.121118053793907f, + 0.985201418399811f, 0.120745941996574f, 0.985293865203857f, 0.120373763144016f, + 0.985386073589325f, 0.120001509785652f, 0.985477983951569f, 0.119629189372063f, + 0.985569596290588f, 0.119256794452667f, 0.985660910606384f, 0.118884332478046f, + 0.985751926898956f, 0.118511803448200f, 0.985842704772949f, 0.118139199912548f, + 0.985933184623718f, 0.117766529321671f, 0.986023366451263f, 0.117393791675568f, + 0.986113250255585f, 0.117020979523659f, 0.986202836036682f, 0.116648100316525f, + 0.986292183399200f, 0.116275154054165f, 0.986381232738495f, 0.115902140736580f, + 0.986469984054565f, 0.115529052913189f, 0.986558437347412f, 0.115155905485153f, + 0.986646652221680f, 0.114782683551311f, 0.986734509468079f, 0.114409394562244f, + 0.986822128295898f, 0.114036038517952f, 0.986909449100494f, 0.113662622869015f, + 0.986996471881866f, 0.113289132714272f, 0.987083256244659f, 0.112915575504303f, + 0.987169682979584f, 0.112541958689690f, 0.987255871295929f, 0.112168267369270f, + 0.987341761589050f, 0.111794516444206f, 0.987427353858948f, 0.111420698463917f, + 0.987512648105621f, 0.111046813428402f, 0.987597703933716f, 0.110672861337662f, + 0.987682461738586f, 0.110298842191696f, 0.987766921520233f, 0.109924763441086f, + 0.987851083278656f, 0.109550617635250f, 0.987934947013855f, 0.109176412224770f, + 0.988018512725830f, 0.108802139759064f, 0.988101840019226f, 0.108427800238132f, + 0.988184869289398f, 0.108053401112556f, 0.988267600536346f, 0.107678934931755f, + 0.988350033760071f, 0.107304409146309f, 0.988432228565216f, 0.106929816305637f, + 0.988514065742493f, 0.106555156409740f, 0.988595664501190f, 0.106180444359779f, + 0.988676965236664f, 0.105805665254593f, 0.988757967948914f, 0.105430819094181f, + 0.988838672637939f, 0.105055920779705f, 0.988919138908386f, 0.104680955410004f, + 0.988999247550964f, 0.104305922985077f, 0.989079117774963f, 0.103930838406086f, + 0.989158689975739f, 0.103555686771870f, 0.989237964153290f, 0.103180475533009f, + 0.989316940307617f, 0.102805204689503f, 0.989395678043365f, 0.102429874241352f, + 0.989474058151245f, 0.102054484188557f, 0.989552199840546f, 0.101679034531116f, + 0.989630043506622f, 0.101303517818451f, 0.989707589149475f, 0.100927948951721f, + 0.989784896373749f, 0.100552320480347f, 0.989861845970154f, 0.100176624953747f, + 0.989938557147980f, 0.099800877273083f, 0.990014970302582f, 0.099425069987774f, + 0.990091085433960f, 0.099049203097820f, 0.990166902542114f, 0.098673284053802f, + 0.990242421627045f, 0.098297297954559f, 0.990317702293396f, 0.097921259701252f, + 0.990392625331879f, 0.097545161843300f, 0.990467309951782f, 0.097169004380703f, + 0.990541696548462f, 0.096792794764042f, 0.990615785121918f, 0.096416525542736f, + 0.990689575672150f, 0.096040196716785f, 0.990763127803802f, 0.095663815736771f, + 0.990836322307587f, 0.095287375152111f, 0.990909278392792f, 0.094910882413387f, + 0.990981936454773f, 0.094534330070019f, 0.991054296493530f, 0.094157725572586f, + 0.991126358509064f, 0.093781061470509f, 0.991198182106018f, 0.093404345214367f, + 0.991269648075104f, 0.093027576804161f, 0.991340875625610f, 0.092650748789310f, + 0.991411805152893f, 0.092273868620396f, 0.991482377052307f, 0.091896936297417f, + 0.991552770137787f, 0.091519944369793f, 0.991622805595398f, 0.091142900288105f, + 0.991692543029785f, 0.090765804052353f, 0.991762042045593f, 0.090388655662537f, + 0.991831183433533f, 0.090011447668076f, 0.991900086402893f, 0.089634194970131f, + 0.991968691349030f, 0.089256882667542f, 0.992036998271942f, 0.088879525661469f, + 0.992105066776276f, 0.088502109050751f, 0.992172777652740f, 0.088124647736549f, + 0.992240250110626f, 0.087747126817703f, 0.992307364940643f, 0.087369553744793f, + 0.992374241352081f, 0.086991935968399f, 0.992440819740295f, 0.086614266037941f, + 0.992507100105286f, 0.086236543953419f, 0.992573142051697f, 0.085858769714832f, + 0.992638826370239f, 0.085480943322182f, 0.992704212665558f, 0.085103072226048f, + 0.992769360542297f, 0.084725148975849f, 0.992834210395813f, 0.084347173571587f, + 0.992898762226105f, 0.083969146013260f, 0.992963016033173f, 0.083591073751450f, + 0.993026971817017f, 0.083212949335575f, 0.993090689182281f, 0.082834780216217f, + 0.993154048919678f, 0.082456558942795f, 0.993217170238495f, 0.082078292965889f, + 0.993279933929443f, 0.081699974834919f, 0.993342459201813f, 0.081321612000465f, + 0.993404686450958f, 0.080943197011948f, 0.993466615676880f, 0.080564737319946f, + 0.993528306484222f, 0.080186225473881f, 0.993589639663696f, 0.079807676374912f, + 0.993650734424591f, 0.079429075121880f, 0.993711471557617f, 0.079050421714783f, + 0.993771970272064f, 0.078671731054783f, 0.993832170963287f, 0.078292988240719f, + 0.993892073631287f, 0.077914200723171f, 0.993951678276062f, 0.077535368502140f, + 0.994010984897614f, 0.077156484127045f, 0.994070053100586f, 0.076777562499046f, + 0.994128763675690f, 0.076398596167564f, 0.994187235832214f, 0.076019577682018f, + 0.994245409965515f, 0.075640521943569f, 0.994303286075592f, 0.075261414051056f, + 0.994360864162445f, 0.074882268905640f, 0.994418144226074f, 0.074503071606159f, + 0.994475126266479f, 0.074123837053776f, 0.994531810283661f, 0.073744557797909f, + 0.994588255882263f, 0.073365233838558f, 0.994644403457642f, 0.072985872626305f, + 0.994700193405151f, 0.072606459259987f, 0.994755744934082f, 0.072227008640766f, + 0.994810998439789f, 0.071847513318062f, 0.994865953922272f, 0.071467980742455f, + 0.994920611381531f, 0.071088403463364f, 0.994975030422211f, 0.070708781480789f, + 0.995029091835022f, 0.070329122245312f, 0.995082914829254f, 0.069949418306351f, + 0.995136380195618f, 0.069569669663906f, 0.995189607143402f, 0.069189883768559f, + 0.995242536067963f, 0.068810060620308f, 0.995295166969299f, 0.068430192768574f, + 0.995347499847412f, 0.068050287663937f, 0.995399534702301f, 0.067670337855816f, + 0.995451331138611f, 0.067290350794792f, 0.995502769947052f, 0.066910326480865f, + 0.995553970336914f, 0.066530264914036f, 0.995604813098907f, 0.066150158643723f, + 0.995655417442322f, 0.065770015120506f, 0.995705723762512f, 0.065389834344387f, + 0.995755732059479f, 0.065009608864784f, 0.995805442333221f, 0.064629353582859f, + 0.995854854583740f, 0.064249053597450f, 0.995904028415680f, 0.063868723809719f, + 0.995952844619751f, 0.063488349318504f, 0.996001422405243f, 0.063107937574387f, + 0.996049642562866f, 0.062727488577366f, 0.996097624301910f, 0.062347009778023f, + 0.996145308017731f, 0.061966486275196f, 0.996192693710327f, 0.061585929244757f, + 0.996239781379700f, 0.061205338686705f, 0.996286571025848f, 0.060824707150459f, + 0.996333062648773f, 0.060444042086601f, 0.996379256248474f, 0.060063343495131f, + 0.996425211429596f, 0.059682607650757f, 0.996470808982849f, 0.059301838278770f, + 0.996516168117523f, 0.058921031653881f, 0.996561229228973f, 0.058540191501379f, + 0.996605992317200f, 0.058159314095974f, 0.996650457382202f, 0.057778406888247f, + 0.996694624423981f, 0.057397462427616f, 0.996738493442535f, 0.057016488164663f, + 0.996782064437866f, 0.056635476648808f, 0.996825337409973f, 0.056254431605339f, + 0.996868371963501f, 0.055873356759548f, 0.996911048889160f, 0.055492244660854f, + 0.996953487396240f, 0.055111102759838f, 0.996995627880096f, 0.054729927331209f, + 0.997037410736084f, 0.054348722100258f, 0.997078955173492f, 0.053967483341694f, + 0.997120201587677f, 0.053586211055517f, 0.997161149978638f, 0.053204908967018f, + 0.997201859951019f, 0.052823577076197f, 0.997242212295532f, 0.052442211657763f, + 0.997282266616821f, 0.052060816437006f, 0.997322082519531f, 0.051679391413927f, + 0.997361540794373f, 0.051297932863235f, 0.997400760650635f, 0.050916448235512f, + 0.997439682483673f, 0.050534930080175f, 0.997478306293488f, 0.050153385847807f, + 0.997516572475433f, 0.049771808087826f, 0.997554600238800f, 0.049390204250813f, + 0.997592389583588f, 0.049008570611477f, 0.997629821300507f, 0.048626907169819f, + 0.997666954994202f, 0.048245213925838f, 0.997703790664673f, 0.047863494604826f, + 0.997740387916565f, 0.047481749206781f, 0.997776627540588f, 0.047099970281124f, + 0.997812628746033f, 0.046718169003725f, 0.997848331928253f, 0.046336337924004f, + 0.997883677482605f, 0.045954477041960f, 0.997918784618378f, 0.045572593808174f, + 0.997953593730927f, 0.045190680772066f, 0.997988104820251f, 0.044808741658926f, + 0.998022377490997f, 0.044426776468754f, 0.998056292533875f, 0.044044785201550f, + 0.998089909553528f, 0.043662767857313f, 0.998123228549957f, 0.043280724436045f, + 0.998156309127808f, 0.042898654937744f, 0.998189091682434f, 0.042516563087702f, + 0.998221516609192f, 0.042134445160627f, 0.998253703117371f, 0.041752301156521f, + 0.998285591602325f, 0.041370131075382f, 0.998317182064056f, 0.040987938642502f, + 0.998348474502563f, 0.040605723857880f, 0.998379468917847f, 0.040223482996225f, + 0.998410165309906f, 0.039841219782829f, 0.998440563678741f, 0.039458930492401f, + 0.998470664024353f, 0.039076622575521f, 0.998500525951386f, 0.038694288581610f, + 0.998530030250549f, 0.038311932235956f, 0.998559296131134f, 0.037929553538561f, + 0.998588204383850f, 0.037547148764133f, 0.998616874217987f, 0.037164725363255f, + 0.998645246028900f, 0.036782283335924f, 0.998673319816589f, 0.036399815231562f, + 0.998701035976410f, 0.036017324775457f, 0.998728513717651f, 0.035634815692902f, + 0.998755753040314f, 0.035252287983894f, 0.998782634735107f, 0.034869734197855f, + 0.998809218406677f, 0.034487165510654f, 0.998835504055023f, 0.034104570746422f, + 0.998861551284790f, 0.033721961081028f, 0.998887240886688f, 0.033339329063892f, + 0.998912692070007f, 0.032956674695015f, 0.998937785625458f, 0.032574005424976f, + 0.998962640762329f, 0.032191313803196f, 0.998987197875977f, 0.031808607280254f, + 0.999011456966400f, 0.031425878405571f, 0.999035418033600f, 0.031043132767081f, + 0.999059081077576f, 0.030660368502140f, 0.999082446098328f, 0.030277585610747f, + 0.999105513095856f, 0.029894785955548f, 0.999128282070160f, 0.029511967673898f, + 0.999150753021240f, 0.029129132628441f, 0.999172985553741f, 0.028746278956532f, + 0.999194860458374f, 0.028363410383463f, 0.999216496944427f, 0.027980525046587f, + 0.999237775802612f, 0.027597622945905f, 0.999258816242218f, 0.027214704081416f, + 0.999279558658600f, 0.026831768453121f, 0.999299943447113f, 0.026448817923665f, + 0.999320089817047f, 0.026065852493048f, 0.999339938163757f, 0.025682870298624f, + 0.999359488487244f, 0.025299875065684f, 0.999378740787506f, 0.024916863068938f, + 0.999397754669189f, 0.024533838033676f, 0.999416410923004f, 0.024150796234608f, + 0.999434769153595f, 0.023767741397023f, 0.999452829360962f, 0.023384673520923f, + 0.999470651149750f, 0.023001590743661f, 0.999488115310669f, 0.022618494927883f, + 0.999505341053009f, 0.022235386073589f, 0.999522268772125f, 0.021852264180779f, + 0.999538838863373f, 0.021469129249454f, 0.999555170536041f, 0.021085981279612f, + 0.999571204185486f, 0.020702820271254f, 0.999586939811707f, 0.020319648087025f, + 0.999602377414703f, 0.019936462864280f, 0.999617516994476f, 0.019553268328309f, + 0.999632358551025f, 0.019170060753822f, 0.999646902084351f, 0.018786842003465f, + 0.999661207199097f, 0.018403612077236f, 0.999675154685974f, 0.018020370975137f, + 0.999688863754272f, 0.017637118697166f, 0.999702215194702f, 0.017253857105970f, + 0.999715328216553f, 0.016870586201549f, 0.999728083610535f, 0.016487304121256f, + 0.999740600585938f, 0.016104012727737f, 0.999752819538116f, 0.015720712020993f, + 0.999764680862427f, 0.015337402001023f, 0.999776303768158f, 0.014954082667828f, + 0.999787628650665f, 0.014570754021406f, 0.999798655509949f, 0.014187417924404f, + 0.999809384346008f, 0.013804072514176f, 0.999819874763489f, 0.013420719653368f, + 0.999830007553101f, 0.013037359341979f, 0.999839842319489f, 0.012653990648687f, + 0.999849438667297f, 0.012270614504814f, 0.999858677387238f, 0.011887230910361f, + 0.999867618083954f, 0.011503840796649f, 0.999876320362091f, 0.011120444163680f, + 0.999884724617004f, 0.010737040080130f, 0.999892771244049f, 0.010353630408645f, + 0.999900579452515f, 0.009970214217901f, 0.999908089637756f, 0.009586792439222f, + 0.999915301799774f, 0.009203365072608f, 0.999922215938568f, 0.008819932118058f, + 0.999928832054138f, 0.008436493575573f, 0.999935150146484f, 0.008053051307797f, + 0.999941170215607f, 0.007669602986425f, 0.999946892261505f, 0.007286150939763f, + 0.999952375888824f, 0.006902694236487f, 0.999957501888275f, 0.006519233807921f, + 0.999962329864502f, 0.006135769188404f, 0.999966919422150f, 0.005752300843596f, + 0.999971151351929f, 0.005368829704821f, 0.999975144863129f, 0.004985354840755f, + 0.999978840351105f, 0.004601877182722f, 0.999982178211212f, 0.004218397196382f, + 0.999985277652740f, 0.003834914416075f, 0.999988079071045f, 0.003451429307461f, + 0.999990582466125f, 0.003067942336202f, 0.999992787837982f, 0.002684453502297f, + 0.999994695186615f, 0.002300963038579f, 0.999996304512024f, 0.001917471294291f, + 0.999997675418854f, 0.001533978385851f, 0.999998688697815f, 0.001150484546088f, + 0.999999403953552f, 0.000766990066040f, 0.999999880790710f, 0.000383495149435f, + 1.000000000000000f, 0.000000000000023f, 0.999999880790710f, -0.000383495149435f, + 0.999999403953552f, -0.000766990066040f, 0.999998688697815f, -0.001150484546088f, + 0.999997675418854f, -0.001533978385851f, 0.999996304512024f, -0.001917471294291f, + 0.999994695186615f, -0.002300963038579f, 0.999992787837982f, -0.002684453502297f, + 0.999990582466125f, -0.003067942336202f, 0.999988079071045f, -0.003451429307461f, + 0.999985277652740f, -0.003834914416075f, 0.999982178211212f, -0.004218397196382f, + 0.999978840351105f, -0.004601877182722f, 0.999975144863129f, -0.004985354840755f, + 0.999971151351929f, -0.005368829704821f, 0.999966919422150f, -0.005752300843596f, + 0.999962329864502f, -0.006135769188404f, 0.999957501888275f, -0.006519233807921f, + 0.999952375888824f, -0.006902694236487f, 0.999946892261505f, -0.007286150939763f, + 0.999941170215607f, -0.007669602986425f, 0.999935150146484f, -0.008053051307797f, + 0.999928832054138f, -0.008436493575573f, 0.999922215938568f, -0.008819932118058f, + 0.999915301799774f, -0.009203365072608f, 0.999908089637756f, -0.009586792439222f, + 0.999900579452515f, -0.009970214217901f, 0.999892771244049f, -0.010353630408645f, + 0.999884724617004f, -0.010737040080130f, 0.999876320362091f, -0.011120444163680f, + 0.999867618083954f, -0.011503840796649f, 0.999858677387238f, -0.011887230910361f, + 0.999849438667297f, -0.012270614504814f, 0.999839842319489f, -0.012653990648687f, + 0.999830007553101f, -0.013037359341979f, 0.999819874763489f, -0.013420719653368f, + 0.999809384346008f, -0.013804072514176f, 0.999798655509949f, -0.014187417924404f, + 0.999787628650665f, -0.014570754021406f, 0.999776303768158f, -0.014954082667828f, + 0.999764680862427f, -0.015337402001023f, 0.999752819538116f, -0.015720712020993f, + 0.999740600585938f, -0.016104012727737f, 0.999728083610535f, -0.016487304121256f, + 0.999715328216553f, -0.016870586201549f, 0.999702215194702f, -0.017253857105970f, + 0.999688863754272f, -0.017637118697166f, 0.999675154685974f, -0.018020370975137f, + 0.999661207199097f, -0.018403612077236f, 0.999646902084351f, -0.018786842003465f, + 0.999632358551025f, -0.019170060753822f, 0.999617516994476f, -0.019553268328309f, + 0.999602377414703f, -0.019936462864280f, 0.999586939811707f, -0.020319648087025f, + 0.999571204185486f, -0.020702820271254f, 0.999555170536041f, -0.021085981279612f, + 0.999538838863373f, -0.021469129249454f, 0.999522268772125f, -0.021852264180779f, + 0.999505341053009f, -0.022235386073589f, 0.999488115310669f, -0.022618494927883f, + 0.999470651149750f, -0.023001590743661f, 0.999452829360962f, -0.023384673520923f, + 0.999434769153595f, -0.023767741397023f, 0.999416410923004f, -0.024150796234608f, + 0.999397754669189f, -0.024533838033676f, 0.999378740787506f, -0.024916863068938f, + 0.999359488487244f, -0.025299875065684f, 0.999339938163757f, -0.025682870298624f, + 0.999320089817047f, -0.026065852493048f, 0.999299943447113f, -0.026448817923665f, + 0.999279558658600f, -0.026831768453121f, 0.999258816242218f, -0.027214704081416f, + 0.999237775802612f, -0.027597622945905f, 0.999216496944427f, -0.027980525046587f, + 0.999194860458374f, -0.028363410383463f, 0.999172985553741f, -0.028746278956532f, + 0.999150753021240f, -0.029129132628441f, 0.999128282070160f, -0.029511967673898f, + 0.999105513095856f, -0.029894785955548f, 0.999082446098328f, -0.030277585610747f, + 0.999059081077576f, -0.030660368502140f, 0.999035418033600f, -0.031043132767081f, + 0.999011456966400f, -0.031425878405571f, 0.998987197875977f, -0.031808607280254f, + 0.998962640762329f, -0.032191313803196f, 0.998937785625458f, -0.032574005424976f, + 0.998912692070007f, -0.032956674695015f, 0.998887240886688f, -0.033339329063892f, + 0.998861551284790f, -0.033721961081028f, 0.998835504055023f, -0.034104570746422f, + 0.998809218406677f, -0.034487165510654f, 0.998782634735107f, -0.034869734197855f, + 0.998755753040314f, -0.035252287983894f, 0.998728513717651f, -0.035634815692902f, + 0.998701035976410f, -0.036017324775457f, 0.998673319816589f, -0.036399815231562f, + 0.998645246028900f, -0.036782283335924f, 0.998616874217987f, -0.037164725363255f, + 0.998588204383850f, -0.037547148764133f, 0.998559296131134f, -0.037929553538561f, + 0.998530030250549f, -0.038311932235956f, 0.998500525951386f, -0.038694288581610f, + 0.998470664024353f, -0.039076622575521f, 0.998440563678741f, -0.039458930492401f, + 0.998410165309906f, -0.039841219782829f, 0.998379468917847f, -0.040223482996225f, + 0.998348474502563f, -0.040605723857880f, 0.998317182064056f, -0.040987938642502f, + 0.998285591602325f, -0.041370131075382f, 0.998253703117371f, -0.041752301156521f, + 0.998221516609192f, -0.042134445160627f, 0.998189091682434f, -0.042516563087702f, + 0.998156309127808f, -0.042898654937744f, 0.998123228549957f, -0.043280724436045f, + 0.998089909553528f, -0.043662767857313f, 0.998056292533875f, -0.044044785201550f, + 0.998022377490997f, -0.044426776468754f, 0.997988104820251f, -0.044808741658926f, + 0.997953593730927f, -0.045190680772066f, 0.997918784618378f, -0.045572593808174f, + 0.997883677482605f, -0.045954477041960f, 0.997848331928253f, -0.046336337924004f, + 0.997812628746033f, -0.046718169003725f, 0.997776627540588f, -0.047099970281124f, + 0.997740387916565f, -0.047481749206781f, 0.997703790664673f, -0.047863494604826f, + 0.997666954994202f, -0.048245213925838f, 0.997629821300507f, -0.048626907169819f, + 0.997592389583588f, -0.049008570611477f, 0.997554600238800f, -0.049390204250813f, + 0.997516572475433f, -0.049771808087826f, 0.997478306293488f, -0.050153385847807f, + 0.997439682483673f, -0.050534930080175f, 0.997400760650635f, -0.050916448235512f, + 0.997361540794373f, -0.051297932863235f, 0.997322082519531f, -0.051679391413927f, + 0.997282266616821f, -0.052060816437006f, 0.997242212295532f, -0.052442211657763f, + 0.997201859951019f, -0.052823577076197f, 0.997161149978638f, -0.053204908967018f, + 0.997120201587677f, -0.053586211055517f, 0.997078955173492f, -0.053967483341694f, + 0.997037410736084f, -0.054348722100258f, 0.996995627880096f, -0.054729927331209f, + 0.996953487396240f, -0.055111102759838f, 0.996911048889160f, -0.055492244660854f, + 0.996868371963501f, -0.055873356759548f, 0.996825337409973f, -0.056254431605339f, + 0.996782064437866f, -0.056635476648808f, 0.996738493442535f, -0.057016488164663f, + 0.996694624423981f, -0.057397462427616f, 0.996650457382202f, -0.057778406888247f, + 0.996605992317200f, -0.058159314095974f, 0.996561229228973f, -0.058540191501379f, + 0.996516168117523f, -0.058921031653881f, 0.996470808982849f, -0.059301838278770f, + 0.996425211429596f, -0.059682607650757f, 0.996379256248474f, -0.060063343495131f, + 0.996333062648773f, -0.060444042086601f, 0.996286571025848f, -0.060824707150459f, + 0.996239781379700f, -0.061205338686705f, 0.996192693710327f, -0.061585929244757f, + 0.996145308017731f, -0.061966486275196f, 0.996097624301910f, -0.062347009778023f, + 0.996049642562866f, -0.062727488577366f, 0.996001422405243f, -0.063107937574387f, + 0.995952844619751f, -0.063488349318504f, 0.995904028415680f, -0.063868723809719f, + 0.995854854583740f, -0.064249053597450f, 0.995805442333221f, -0.064629353582859f, + 0.995755732059479f, -0.065009608864784f, 0.995705723762512f, -0.065389834344387f, + 0.995655417442322f, -0.065770015120506f, 0.995604813098907f, -0.066150158643723f, + 0.995553970336914f, -0.066530264914036f, 0.995502769947052f, -0.066910326480865f, + 0.995451331138611f, -0.067290350794792f, 0.995399534702301f, -0.067670337855816f, + 0.995347499847412f, -0.068050287663937f, 0.995295166969299f, -0.068430192768574f, + 0.995242536067963f, -0.068810060620308f, 0.995189607143402f, -0.069189883768559f, + 0.995136380195618f, -0.069569669663906f, 0.995082914829254f, -0.069949418306351f, + 0.995029091835022f, -0.070329122245312f, 0.994975030422211f, -0.070708781480789f, + 0.994920611381531f, -0.071088403463364f, 0.994865953922272f, -0.071467980742455f, + 0.994810998439789f, -0.071847513318062f, 0.994755744934082f, -0.072227008640766f, + 0.994700193405151f, -0.072606459259987f, 0.994644403457642f, -0.072985872626305f, + 0.994588255882263f, -0.073365233838558f, 0.994531810283661f, -0.073744557797909f, + 0.994475126266479f, -0.074123837053776f, 0.994418144226074f, -0.074503071606159f, + 0.994360864162445f, -0.074882268905640f, 0.994303286075592f, -0.075261414051056f, + 0.994245409965515f, -0.075640521943569f, 0.994187235832214f, -0.076019577682018f, + 0.994128763675690f, -0.076398596167564f, 0.994070053100586f, -0.076777562499046f, + 0.994010984897614f, -0.077156484127045f, 0.993951678276062f, -0.077535368502140f, + 0.993892073631287f, -0.077914200723171f, 0.993832170963287f, -0.078292988240719f, + 0.993771970272064f, -0.078671731054783f, 0.993711471557617f, -0.079050421714783f, + 0.993650734424591f, -0.079429075121880f, 0.993589639663696f, -0.079807676374912f, + 0.993528306484222f, -0.080186225473881f, 0.993466615676880f, -0.080564737319946f, + 0.993404686450958f, -0.080943197011948f, 0.993342459201813f, -0.081321612000465f, + 0.993279933929443f, -0.081699974834919f, 0.993217170238495f, -0.082078292965889f, + 0.993154048919678f, -0.082456558942795f, 0.993090689182281f, -0.082834780216217f, + 0.993026971817017f, -0.083212949335575f, 0.992963016033173f, -0.083591073751450f, + 0.992898762226105f, -0.083969146013260f, 0.992834210395813f, -0.084347173571587f, + 0.992769360542297f, -0.084725148975849f, 0.992704212665558f, -0.085103072226048f, + 0.992638826370239f, -0.085480943322182f, 0.992573142051697f, -0.085858769714832f, + 0.992507100105286f, -0.086236543953419f, 0.992440819740295f, -0.086614266037941f, + 0.992374241352081f, -0.086991935968399f, 0.992307364940643f, -0.087369553744793f, + 0.992240250110626f, -0.087747126817703f, 0.992172777652740f, -0.088124647736549f, + 0.992105066776276f, -0.088502109050751f, 0.992036998271942f, -0.088879525661469f, + 0.991968691349030f, -0.089256882667542f, 0.991900086402893f, -0.089634194970131f, + 0.991831183433533f, -0.090011447668076f, 0.991762042045593f, -0.090388655662537f, + 0.991692543029785f, -0.090765804052353f, 0.991622805595398f, -0.091142900288105f, + 0.991552770137787f, -0.091519944369793f, 0.991482377052307f, -0.091896936297417f, + 0.991411805152893f, -0.092273868620396f, 0.991340875625610f, -0.092650748789310f, + 0.991269648075104f, -0.093027576804161f, 0.991198182106018f, -0.093404345214367f, + 0.991126358509064f, -0.093781061470509f, 0.991054296493530f, -0.094157725572586f, + 0.990981936454773f, -0.094534330070019f, 0.990909278392792f, -0.094910882413387f, + 0.990836322307587f, -0.095287375152111f, 0.990763127803802f, -0.095663815736771f, + 0.990689575672150f, -0.096040196716785f, 0.990615785121918f, -0.096416525542736f, + 0.990541696548462f, -0.096792794764042f, 0.990467309951782f, -0.097169004380703f, + 0.990392625331879f, -0.097545161843300f, 0.990317702293396f, -0.097921259701252f, + 0.990242421627045f, -0.098297297954559f, 0.990166902542114f, -0.098673284053802f, + 0.990091085433960f, -0.099049203097820f, 0.990014970302582f, -0.099425069987774f, + 0.989938557147980f, -0.099800877273083f, 0.989861845970154f, -0.100176624953747f, + 0.989784896373749f, -0.100552320480347f, 0.989707589149475f, -0.100927948951721f, + 0.989630043506622f, -0.101303517818451f, 0.989552199840546f, -0.101679034531116f, + 0.989474058151245f, -0.102054484188557f, 0.989395678043365f, -0.102429874241352f, + 0.989316940307617f, -0.102805204689503f, 0.989237964153290f, -0.103180475533009f, + 0.989158689975739f, -0.103555686771870f, 0.989079117774963f, -0.103930838406086f, + 0.988999247550964f, -0.104305922985077f, 0.988919138908386f, -0.104680955410004f, + 0.988838672637939f, -0.105055920779705f, 0.988757967948914f, -0.105430819094181f, + 0.988676965236664f, -0.105805665254593f, 0.988595664501190f, -0.106180444359779f, + 0.988514065742493f, -0.106555156409740f, 0.988432228565216f, -0.106929816305637f, + 0.988350033760071f, -0.107304409146309f, 0.988267600536346f, -0.107678934931755f, + 0.988184869289398f, -0.108053401112556f, 0.988101840019226f, -0.108427800238132f, + 0.988018512725830f, -0.108802139759064f, 0.987934947013855f, -0.109176412224770f, + 0.987851083278656f, -0.109550617635250f, 0.987766921520233f, -0.109924763441086f, + 0.987682461738586f, -0.110298842191696f, 0.987597703933716f, -0.110672861337662f, + 0.987512648105621f, -0.111046813428402f, 0.987427353858948f, -0.111420698463917f, + 0.987341761589050f, -0.111794516444206f, 0.987255871295929f, -0.112168267369270f, + 0.987169682979584f, -0.112541958689690f, 0.987083256244659f, -0.112915575504303f, + 0.986996471881866f, -0.113289132714272f, 0.986909449100494f, -0.113662622869015f, + 0.986822128295898f, -0.114036038517952f, 0.986734509468079f, -0.114409394562244f, + 0.986646652221680f, -0.114782683551311f, 0.986558437347412f, -0.115155905485153f, + 0.986469984054565f, -0.115529052913189f, 0.986381232738495f, -0.115902140736580f, + 0.986292183399200f, -0.116275154054165f, 0.986202836036682f, -0.116648100316525f, + 0.986113250255585f, -0.117020979523659f, 0.986023366451263f, -0.117393791675568f, + 0.985933184623718f, -0.117766529321671f, 0.985842704772949f, -0.118139199912548f, + 0.985751926898956f, -0.118511803448200f, 0.985660910606384f, -0.118884332478046f, + 0.985569596290588f, -0.119256794452667f, 0.985477983951569f, -0.119629189372063f, + 0.985386073589325f, -0.120001509785652f, 0.985293865203857f, -0.120373763144016f, + 0.985201418399811f, -0.120745941996574f, 0.985108673572540f, -0.121118053793907f, + 0.985015630722046f, -0.121490091085434f, 0.984922289848328f, -0.121862053871155f, + 0.984828710556030f, -0.122233949601650f, 0.984734773635864f, -0.122605770826340f, + 0.984640598297119f, -0.122977524995804f, 0.984546124935150f, -0.123349204659462f, + 0.984451413154602f, -0.123720809817314f, 0.984356343746185f, -0.124092340469360f, + 0.984261035919189f, -0.124463804066181f, 0.984165430068970f, -0.124835193157196f, + 0.984069526195526f, -0.125206500291824f, 0.983973383903503f, -0.125577747821808f, + 0.983876943588257f, -0.125948905944824f, 0.983780145645142f, -0.126320004463196f, + 0.983683168888092f, -0.126691013574600f, 0.983585834503174f, -0.127061963081360f, + 0.983488261699677f, -0.127432823181152f, 0.983390331268311f, -0.127803623676300f, + 0.983292162418365f, -0.128174334764481f, 0.983193755149841f, -0.128544986248016f, + 0.983094990253448f, -0.128915548324585f, 0.982995986938477f, -0.129286035895348f, + 0.982896685600281f, -0.129656463861465f, 0.982797086238861f, -0.130026802420616f, + 0.982697248458862f, -0.130397051572800f, 0.982597053050995f, -0.130767241120338f, + 0.982496619224548f, -0.131137356162071f, 0.982395887374878f, -0.131507381796837f, + 0.982294917106628f, -0.131877332925797f, 0.982193589210510f, -0.132247209548950f, + 0.982092022895813f, -0.132617011666298f, 0.981990158557892f, -0.132986739277840f, + 0.981888055801392f, -0.133356377482414f, 0.981785595417023f, -0.133725941181183f, + 0.981682896614075f, -0.134095430374146f, 0.981579899787903f, -0.134464830160141f, + 0.981476604938507f, -0.134834155440331f, 0.981373071670532f, -0.135203406214714f, + 0.981269240379334f, -0.135572582483292f, 0.981165111064911f, -0.135941669344902f, + 0.981060683727264f, -0.136310681700706f, 0.980956017971039f, -0.136679604649544f, + 0.980851054191589f, -0.137048453092575f, 0.980745792388916f, -0.137417227029800f, + 0.980640232563019f, -0.137785911560059f, 0.980534434318542f, -0.138154521584511f, + 0.980428338050842f, -0.138523042201996f, 0.980321943759918f, -0.138891488313675f, + 0.980215251445770f, -0.139259845018387f, 0.980108320713043f, -0.139628127217293f, + 0.980001091957092f, -0.139996320009232f, 0.979893565177917f, -0.140364438295364f, + 0.979785740375519f, -0.140732467174530f, 0.979677677154541f, -0.141100421547890f, + 0.979569315910339f, -0.141468286514282f, 0.979460656642914f, -0.141836062073708f, + 0.979351758956909f, -0.142203763127327f, 0.979242503643036f, -0.142571389675140f, + 0.979133009910584f, -0.142938911914825f, 0.979023277759552f, -0.143306359648705f, + 0.978913187980652f, -0.143673732876778f, 0.978802859783173f, -0.144041016697884f, + 0.978692233562469f, -0.144408211112022f, 0.978581368923187f, -0.144775316119194f, + 0.978470146656036f, -0.145142331719399f, 0.978358685970306f, -0.145509272813797f, + 0.978246986865997f, -0.145876124501228f, 0.978134930133820f, -0.146242901682854f, + 0.978022634983063f, -0.146609574556351f, 0.977910041809082f, -0.146976172924042f, + 0.977797150611877f, -0.147342681884766f, 0.977684020996094f, -0.147709101438522f, + 0.977570593357086f, -0.148075446486473f, 0.977456867694855f, -0.148441687226295f, + 0.977342903614044f, -0.148807853460312f, 0.977228581905365f, -0.149173930287361f, + 0.977114021778107f, -0.149539917707443f, 0.976999223232269f, -0.149905815720558f, + 0.976884067058563f, -0.150271624326706f, 0.976768672466278f, -0.150637343525887f, + 0.976653039455414f, -0.151002973318100f, 0.976537048816681f, -0.151368513703346f, + 0.976420819759369f, -0.151733979582787f, 0.976304292678833f, -0.152099341154099f, + 0.976187527179718f, -0.152464613318443f, 0.976070404052734f, -0.152829796075821f, + 0.975953042507172f, -0.153194904327393f, 0.975835442543030f, -0.153559908270836f, + 0.975717484951019f, -0.153924822807312f, 0.975599288940430f, -0.154289647936821f, + 0.975480854511261f, -0.154654383659363f, 0.975362062454224f, -0.155019029974937f, + 0.975243031978607f, -0.155383571982384f, 0.975123703479767f, -0.155748039484024f, + 0.975004136562347f, -0.156112402677536f, 0.974884271621704f, -0.156476691365242f, + 0.974764108657837f, -0.156840875744820f, 0.974643647670746f, -0.157204970717430f, + 0.974522948265076f, -0.157568961381912f, 0.974401950836182f, -0.157932877540588f, + 0.974280655384064f, -0.158296689391136f, 0.974159121513367f, -0.158660411834717f, + 0.974037289619446f, -0.159024044871330f, 0.973915159702301f, -0.159387573599815f, + 0.973792791366577f, -0.159751012921333f, 0.973670125007629f, -0.160114362835884f, + 0.973547160625458f, -0.160477623343468f, 0.973423957824707f, -0.160840779542923f, + 0.973300457000732f, -0.161203846335411f, 0.973176658153534f, -0.161566808819771f, + 0.973052620887756f, -0.161929681897163f, 0.972928285598755f, -0.162292465567589f, + 0.972803652286530f, -0.162655144929886f, 0.972678780555725f, -0.163017734885216f, + 0.972553610801697f, -0.163380220532417f, 0.972428143024445f, -0.163742616772652f, + 0.972302436828613f, -0.164104923605919f, 0.972176432609558f, -0.164467126131058f, + 0.972050130367279f, -0.164829224348068f, 0.971923589706421f, -0.165191248059273f, + 0.971796751022339f, -0.165553152561188f, 0.971669614315033f, -0.165914967656136f, + 0.971542239189148f, -0.166276678442955f, 0.971414566040039f, -0.166638299822807f, + 0.971286594867706f, -0.166999831795692f, 0.971158385276794f, -0.167361244559288f, + 0.971029877662659f, -0.167722567915916f, 0.970901072025299f, -0.168083801865578f, + 0.970772027969360f, -0.168444931507111f, 0.970642685890198f, -0.168805956840515f, + 0.970513105392456f, -0.169166877865791f, 0.970383226871490f, -0.169527709484100f, + 0.970253050327301f, -0.169888436794281f, 0.970122575759888f, -0.170249074697495f, + 0.969991862773895f, -0.170609608292580f, 0.969860911369324f, -0.170970037579536f, + 0.969729602336884f, -0.171330362558365f, 0.969598054885864f, -0.171690583229065f, + 0.969466269016266f, -0.172050714492798f, 0.969334125518799f, -0.172410741448402f, + 0.969201743602753f, -0.172770664095879f, 0.969069123268127f, -0.173130482435226f, + 0.968936204910278f, -0.173490211367607f, 0.968802988529205f, -0.173849821090698f, + 0.968669533729553f, -0.174209341406822f, 0.968535780906677f, -0.174568757414818f, + 0.968401730060577f, -0.174928069114685f, 0.968267440795898f, -0.175287276506424f, + 0.968132853507996f, -0.175646379590034f, 0.967997968196869f, -0.176005378365517f, + 0.967862844467163f, -0.176364272832870f, 0.967727422714233f, -0.176723077893257f, + 0.967591762542725f, -0.177081763744354f, 0.967455804347992f, -0.177440345287323f, + 0.967319548130035f, -0.177798837423325f, 0.967183053493500f, -0.178157210350037f, + 0.967046260833740f, -0.178515478968620f, 0.966909229755402f, -0.178873643279076f, + 0.966771900653839f, -0.179231703281403f, 0.966634273529053f, -0.179589673876762f, + 0.966496407985687f, -0.179947525262833f, 0.966358244419098f, -0.180305257439613f, + 0.966219842433929f, -0.180662900209427f, 0.966081082820892f, -0.181020438671112f, + 0.965942144393921f, -0.181377857923508f, 0.965802907943726f, -0.181735187768936f, + 0.965663373470306f, -0.182092398405075f, 0.965523540973663f, -0.182449504733086f, + 0.965383470058441f, -0.182806491851807f, 0.965243160724640f, -0.183163389563560f, + 0.965102493762970f, -0.183520168066025f, 0.964961588382721f, -0.183876842260361f, + 0.964820444583893f, -0.184233412146568f, 0.964679002761841f, -0.184589877724648f, + 0.964537262916565f, -0.184946224093437f, 0.964395284652710f, -0.185302466154099f, + 0.964253067970276f, -0.185658603906631f, 0.964110493659973f, -0.186014622449875f, + 0.963967680931091f, -0.186370536684990f, 0.963824629783630f, -0.186726331710815f, + 0.963681280612946f, -0.187082037329674f, 0.963537633419037f, -0.187437608838081f, + 0.963393747806549f, -0.187793090939522f, 0.963249564170837f, -0.188148453831673f, + 0.963105142116547f, -0.188503712415695f, 0.962960422039032f, -0.188858851790428f, + 0.962815403938293f, -0.189213871955872f, 0.962670147418976f, -0.189568802714348f, + 0.962524592876434f, -0.189923599362373f, 0.962378799915314f, -0.190278306603432f, + 0.962232708930969f, -0.190632879734039f, 0.962086379528046f, -0.190987363457680f, + 0.961939752101898f, -0.191341713070869f, 0.961792886257172f, -0.191695958375931f, + 0.961645722389221f, -0.192050099372864f, 0.961498260498047f, -0.192404121160507f, + 0.961350560188293f, -0.192758023738861f, 0.961202561855316f, -0.193111822009087f, + 0.961054325103760f, -0.193465501070023f, 0.960905790328979f, -0.193819075822830f, + 0.960757017135620f, -0.194172516465187f, 0.960607945919037f, -0.194525867700577f, + 0.960458636283875f, -0.194879084825516f, 0.960309028625488f, -0.195232197642326f, + 0.960159122943878f, -0.195585191249847f, 0.960008978843689f, -0.195938065648079f, + 0.959858596324921f, -0.196290835738182f, 0.959707856178284f, -0.196643486618996f, + 0.959556937217712f, -0.196996018290520f, 0.959405720233917f, -0.197348430752754f, + 0.959254205226898f, -0.197700738906860f, 0.959102451801300f, -0.198052927851677f, + 0.958950400352478f, -0.198404997587204f, 0.958798050880432f, -0.198756948113441f, + 0.958645522594452f, -0.199108779430389f, 0.958492636680603f, -0.199460506439209f, + 0.958339512348175f, -0.199812099337578f, 0.958186149597168f, -0.200163587927818f, + 0.958032488822937f, -0.200514942407608f, 0.957878530025482f, -0.200866192579269f, + 0.957724332809448f, -0.201217323541641f, 0.957569897174835f, -0.201568335294724f, + 0.957415163516998f, -0.201919227838516f, 0.957260131835938f, -0.202270001173019f, + 0.957104861736298f, -0.202620655298233f, 0.956949353218079f, -0.202971190214157f, + 0.956793546676636f, -0.203321605920792f, 0.956637442111969f, -0.203671902418137f, + 0.956481099128723f, -0.204022079706192f, 0.956324458122253f, -0.204372137784958f, + 0.956167578697205f, -0.204722076654434f, 0.956010460853577f, -0.205071896314621f, + 0.955853044986725f, -0.205421581864357f, 0.955695331096649f, -0.205771163105965f, + 0.955537378787994f, -0.206120610237122f, 0.955379128456116f, -0.206469938158989f, + 0.955220639705658f, -0.206819161772728f, 0.955061912536621f, -0.207168251276016f, + 0.954902827739716f, -0.207517206668854f, 0.954743564128876f, -0.207866057753563f, + 0.954584002494812f, -0.208214774727821f, 0.954424142837524f, -0.208563387393951f, + 0.954264044761658f, -0.208911851048470f, 0.954103708267212f, -0.209260210394859f, + 0.953943073749542f, -0.209608450531960f, 0.953782141208649f, -0.209956556558609f, + 0.953620970249176f, -0.210304543375969f, 0.953459560871124f, -0.210652396082878f, + 0.953297853469849f, -0.211000129580498f, 0.953135907649994f, -0.211347743868828f, + 0.952973663806915f, -0.211695238947868f, 0.952811121940613f, -0.212042599916458f, + 0.952648401260376f, -0.212389841675758f, 0.952485322952271f, -0.212736949324608f, + 0.952322065830231f, -0.213083937764168f, 0.952158451080322f, -0.213430806994438f, + 0.951994657516479f, -0.213777542114258f, 0.951830565929413f, -0.214124158024788f, + 0.951666176319122f, -0.214470639824867f, 0.951501548290253f, -0.214817002415657f, + 0.951336681842804f, -0.215163245797157f, 0.951171517372131f, -0.215509355068207f, + 0.951006054878235f, -0.215855330228806f, 0.950840353965759f, -0.216201186180115f, + 0.950674414634705f, -0.216546908020973f, 0.950508177280426f, -0.216892510652542f, + 0.950341701507568f, -0.217237979173660f, 0.950174987316132f, -0.217583328485489f, + 0.950007975101471f, -0.217928543686867f, 0.949840664863586f, -0.218273624777794f, + 0.949673116207123f, -0.218618586659431f, 0.949505329132080f, -0.218963414430618f, + 0.949337244033813f, -0.219308122992516f, 0.949168920516968f, -0.219652697443962f, + 0.949000298976898f, -0.219997137784958f, 0.948831439018250f, -0.220341444015503f, + 0.948662281036377f, -0.220685631036758f, 0.948492884635925f, -0.221029683947563f, + 0.948323249816895f, -0.221373617649078f, 0.948153316974640f, -0.221717402338982f, + 0.947983145713806f, -0.222061067819595f, 0.947812676429749f, -0.222404599189758f, + 0.947641968727112f, -0.222748011350632f, 0.947470963001251f, -0.223091274499893f, + 0.947299718856812f, -0.223434418439865f, 0.947128236293793f, -0.223777428269386f, + 0.946956455707550f, -0.224120303988457f, 0.946784436702728f, -0.224463045597076f, + 0.946612179279327f, -0.224805667996407f, 0.946439623832703f, -0.225148141384125f, + 0.946266770362854f, -0.225490495562553f, 0.946093678474426f, -0.225832715630531f, + 0.945920348167419f, -0.226174786686897f, 0.945746779441834f, -0.226516738533974f, + 0.945572853088379f, -0.226858556270599f, 0.945398747920990f, -0.227200239896774f, + 0.945224344730377f, -0.227541789412498f, 0.945049703121185f, -0.227883204817772f, + 0.944874763488770f, -0.228224486112595f, 0.944699645042419f, -0.228565633296967f, + 0.944524168968201f, -0.228906646370888f, 0.944348454475403f, -0.229247525334358f, + 0.944172501564026f, -0.229588270187378f, 0.943996310234070f, -0.229928880929947f, + 0.943819820880890f, -0.230269357562065f, 0.943643093109131f, -0.230609700083733f, + 0.943466067314148f, -0.230949893593788f, 0.943288803100586f, -0.231289967894554f, + 0.943111240863800f, -0.231629893183708f, 0.942933499813080f, -0.231969684362412f, + 0.942755401134491f, -0.232309341430664f, 0.942577123641968f, -0.232648864388466f, + 0.942398548126221f, -0.232988253235817f, 0.942219734191895f, -0.233327493071556f, + 0.942040622234344f, -0.233666598796844f, 0.941861271858215f, -0.234005570411682f, + 0.941681683063507f, -0.234344407916069f, 0.941501796245575f, -0.234683111310005f, + 0.941321671009064f, -0.235021665692329f, 0.941141307353973f, -0.235360085964203f, + 0.940960645675659f, -0.235698372125626f, 0.940779745578766f, -0.236036509275436f, + 0.940598547458649f, -0.236374512314796f, 0.940417110919952f, -0.236712381243706f, + 0.940235435962677f, -0.237050101161003f, 0.940053522586823f, -0.237387686967850f, + 0.939871311187744f, -0.237725138664246f, 0.939688861370087f, -0.238062441349030f, + 0.939506113529205f, -0.238399609923363f, 0.939323127269745f, -0.238736644387245f, + 0.939139902591705f, -0.239073529839516f, 0.938956379890442f, -0.239410281181335f, + 0.938772618770599f, -0.239746883511543f, 0.938588619232178f, -0.240083336830139f, + 0.938404381275177f, -0.240419670939446f, 0.938219845294952f, -0.240755841135979f, + 0.938035070896149f, -0.241091892123222f, 0.937849998474121f, -0.241427779197693f, + 0.937664687633514f, -0.241763532161713f, 0.937479138374329f, -0.242099151015282f, + 0.937293350696564f, -0.242434620857239f, 0.937107264995575f, -0.242769956588745f, + 0.936920940876007f, -0.243105143308640f, 0.936734318733215f, -0.243440181016922f, + 0.936547517776489f, -0.243775084614754f, 0.936360359191895f, -0.244109839200974f, + 0.936173021793365f, -0.244444444775581f, 0.935985386371613f, -0.244778916239738f, + 0.935797572135925f, -0.245113238692284f, 0.935609400272369f, -0.245447427034378f, + 0.935421049594879f, -0.245781451463699f, 0.935232400894165f, -0.246115356683731f, + 0.935043513774872f, -0.246449097990990f, 0.934854328632355f, -0.246782705187798f, + 0.934664964675903f, -0.247116148471832f, 0.934475243091583f, -0.247449472546577f, + 0.934285342693329f, -0.247782632708550f, 0.934095203876495f, -0.248115643858910f, + 0.933904767036438f, -0.248448520898819f, 0.933714091777802f, -0.248781248927116f, + 0.933523118495941f, -0.249113827943802f, 0.933331906795502f, -0.249446272850037f, + 0.933140456676483f, -0.249778553843498f, 0.932948768138886f, -0.250110685825348f, + 0.932756841182709f, -0.250442683696747f, 0.932564616203308f, -0.250774532556534f, + 0.932372152805328f, -0.251106232404709f, 0.932179391384125f, -0.251437783241272f, + 0.931986451148987f, -0.251769185066223f, 0.931793212890625f, -0.252100437879562f, + 0.931599736213684f, -0.252431541681290f, 0.931405961513519f, -0.252762526273727f, + 0.931211948394775f, -0.253093332052231f, 0.931017756462097f, -0.253423988819122f, + 0.930823206901550f, -0.253754496574402f, 0.930628478527069f, -0.254084855318069f, + 0.930433452129364f, -0.254415065050125f, 0.930238187313080f, -0.254745125770569f, + 0.930042684078217f, -0.255075037479401f, 0.929846942424774f, -0.255404800176620f, + 0.929650902748108f, -0.255734413862228f, 0.929454624652863f, -0.256063878536224f, + 0.929258108139038f, -0.256393194198608f, 0.929061353206635f, -0.256722360849380f, + 0.928864300251007f, -0.257051378488541f, 0.928667008876801f, -0.257380217313766f, + 0.928469479084015f, -0.257708936929703f, 0.928271710872650f, -0.258037507534027f, + 0.928073644638062f, -0.258365899324417f, 0.927875399589539f, -0.258694142103195f, + 0.927676856517792f, -0.259022265672684f, 0.927478015422821f, -0.259350210428238f, + 0.927278995513916f, -0.259678006172180f, 0.927079677581787f, -0.260005623102188f, + 0.926880121231079f, -0.260333120822906f, 0.926680326461792f, -0.260660469532013f, + 0.926480293273926f, -0.260987639427185f, 0.926280021667480f, -0.261314690113068f, + 0.926079452037811f, -0.261641561985016f, 0.925878643989563f, -0.261968284845352f, + 0.925677597522736f, -0.262294828891754f, 0.925476312637329f, -0.262621253728867f, + 0.925274729728699f, -0.262947499752045f, 0.925072908401489f, -0.263273626565933f, + 0.924870908260345f, -0.263599574565887f, 0.924668610095978f, -0.263925373554230f, + 0.924466013908386f, -0.264250993728638f, 0.924263238906860f, -0.264576494693756f, + 0.924060165882111f, -0.264901816844940f, 0.923856854438782f, -0.265226989984512f, + 0.923653304576874f, -0.265552014112473f, 0.923449516296387f, -0.265876859426498f, + 0.923245489597321f, -0.266201555728912f, 0.923041164875031f, -0.266526103019714f, + 0.922836601734161f, -0.266850501298904f, 0.922631800174713f, -0.267174720764160f, + 0.922426760196686f, -0.267498821020126f, 0.922221481800079f, -0.267822742462158f, + 0.922015964984894f, -0.268146485090256f, 0.921810150146484f, -0.268470078706741f, + 0.921604096889496f, -0.268793523311615f, 0.921397805213928f, -0.269116818904877f, + 0.921191275119781f, -0.269439965486526f, 0.920984506607056f, -0.269762933254242f, + 0.920777499675751f, -0.270085722208023f, 0.920570194721222f, -0.270408391952515f, + 0.920362710952759f, -0.270730882883072f, 0.920154929161072f, -0.271053224802017f, + 0.919946908950806f, -0.271375387907028f, 0.919738650321960f, -0.271697402000427f, + 0.919530093669891f, -0.272019267082214f, 0.919321358203888f, -0.272340953350067f, + 0.919112324714661f, -0.272662490606308f, 0.918903112411499f, -0.272983878850937f, + 0.918693602085114f, -0.273305088281631f, 0.918483853340149f, -0.273626148700714f, + 0.918273866176605f, -0.273947030305862f, 0.918063640594482f, -0.274267762899399f, + 0.917853116989136f, -0.274588316679001f, 0.917642414569855f, -0.274908751249313f, + 0.917431414127350f, -0.275228977203369f, 0.917220234870911f, -0.275549083948135f, + 0.917008757591248f, -0.275868982076645f, 0.916797041893005f, -0.276188760995865f, + 0.916585087776184f, -0.276508361101151f, 0.916372895240784f, -0.276827782392502f, + 0.916160404682159f, -0.277147054672241f, 0.915947735309601f, -0.277466177940369f, + 0.915734827518463f, -0.277785122394562f, 0.915521621704102f, -0.278103888034821f, + 0.915308177471161f, -0.278422504663467f, 0.915094554424286f, -0.278740972280502f, + 0.914880633354187f, -0.279059261083603f, 0.914666473865509f, -0.279377400875092f, + 0.914452075958252f, -0.279695361852646f, 0.914237439632416f, -0.280013144016266f, + 0.914022505283356f, -0.280330777168274f, 0.913807392120361f, -0.280648261308670f, + 0.913592040538788f, -0.280965566635132f, 0.913376390933990f, -0.281282693147659f, + 0.913160502910614f, -0.281599670648575f, 0.912944436073303f, -0.281916469335556f, + 0.912728071212769f, -0.282233119010925f, 0.912511467933655f, -0.282549589872360f, + 0.912294626235962f, -0.282865911722183f, 0.912077546119690f, -0.283182054758072f, + 0.911860227584839f, -0.283498018980026f, 0.911642670631409f, -0.283813834190369f, + 0.911424875259399f, -0.284129470586777f, 0.911206841468811f, -0.284444957971573f, + 0.910988569259644f, -0.284760266542435f, 0.910769999027252f, -0.285075396299362f, + 0.910551249980927f, -0.285390377044678f, 0.910332262516022f, -0.285705178976059f, + 0.910112977027893f, -0.286019802093506f, 0.909893512725830f, -0.286334276199341f, + 0.909673750400543f, -0.286648571491241f, 0.909453809261322f, -0.286962717771530f, + 0.909233570098877f, -0.287276685237885f, 0.909013092517853f, -0.287590473890305f, + 0.908792436122894f, -0.287904083728790f, 0.908571481704712f, -0.288217544555664f, + 0.908350288867950f, -0.288530826568604f, 0.908128857612610f, -0.288843959569931f, + 0.907907187938690f, -0.289156883955002f, 0.907685279846191f, -0.289469659328461f, + 0.907463192939758f, -0.289782285690308f, 0.907240808010101f, -0.290094703435898f, + 0.907018184661865f, -0.290406972169876f, 0.906795322895050f, -0.290719062089920f, + 0.906572222709656f, -0.291031002998352f, 0.906348884105682f, -0.291342735290527f, + 0.906125307083130f, -0.291654318571091f, 0.905901491641998f, -0.291965723037720f, + 0.905677437782288f, -0.292276978492737f, 0.905453145503998f, -0.292588025331497f, + 0.905228614807129f, -0.292898923158646f, 0.905003845691681f, -0.293209642171860f, + 0.904778838157654f, -0.293520182371140f, 0.904553592205048f, -0.293830573558807f, + 0.904328107833862f, -0.294140785932541f, 0.904102385044098f, -0.294450789690018f, + 0.903876423835754f, -0.294760644435883f, 0.903650224208832f, -0.295070350170136f, + 0.903423786163330f, -0.295379847288132f, 0.903197109699249f, -0.295689195394516f, + 0.902970194816589f, -0.295998334884644f, 0.902743041515350f, -0.296307325363159f, + 0.902515649795532f, -0.296616137027740f, 0.902288019657135f, -0.296924799680710f, + 0.902060210704803f, -0.297233253717422f, 0.901832103729248f, -0.297541528940201f, + 0.901603758335114f, -0.297849655151367f, 0.901375174522400f, -0.298157602548599f, + 0.901146411895752f, -0.298465341329575f, 0.900917351245880f, -0.298772931098938f, + 0.900688111782074f, -0.299080342054367f, 0.900458574295044f, -0.299387603998184f, + 0.900228857994080f, -0.299694657325745f, 0.899998843669891f, -0.300001531839371f, + 0.899768650531769f, -0.300308227539063f, 0.899538159370422f, -0.300614774227142f, + 0.899307489395142f, -0.300921112298965f, 0.899076581001282f, -0.301227301359177f, + 0.898845434188843f, -0.301533311605453f, 0.898614048957825f, -0.301839113235474f, + 0.898382425308228f, -0.302144765853882f, 0.898150563240051f, -0.302450239658356f, + 0.897918462753296f, -0.302755534648895f, 0.897686123847961f, -0.303060621023178f, + 0.897453546524048f, -0.303365558385849f, 0.897220790386200f, -0.303670316934586f, + 0.896987736225128f, -0.303974896669388f, 0.896754503250122f, -0.304279297590256f, + 0.896520972251892f, -0.304583519697189f, 0.896287262439728f, -0.304887533187866f, + 0.896053314208984f, -0.305191397666931f, 0.895819067955017f, -0.305495083332062f, + 0.895584642887115f, -0.305798590183258f, 0.895349979400635f, -0.306101888418198f, + 0.895115137100220f, -0.306405037641525f, 0.894879996776581f, -0.306708008050919f, + 0.894644618034363f, -0.307010769844055f, 0.894409060478210f, -0.307313382625580f, + 0.894173204898834f, -0.307615786790848f, 0.893937170505524f, -0.307918041944504f, + 0.893700897693634f, -0.308220088481903f, 0.893464326858521f, -0.308521956205368f, + 0.893227577209473f, -0.308823645114899f, 0.892990648746490f, -0.309125155210495f, + 0.892753422260284f, -0.309426486492157f, 0.892515957355499f, -0.309727638959885f, + 0.892278313636780f, -0.310028612613678f, 0.892040371894836f, -0.310329377651215f, + 0.891802251338959f, -0.310629993677139f, 0.891563892364502f, -0.310930401086807f, + 0.891325294971466f, -0.311230629682541f, 0.891086459159851f, -0.311530679464340f, + 0.890847444534302f, -0.311830550432205f, 0.890608131885529f, -0.312130242586136f, + 0.890368640422821f, -0.312429755926132f, 0.890128850936890f, -0.312729060649872f, + 0.889888882637024f, -0.313028186559677f, 0.889648675918579f, -0.313327133655548f, + 0.889408230781555f, -0.313625901937485f, 0.889167606830597f, -0.313924491405487f, + 0.888926684856415f, -0.314222872257233f, 0.888685584068298f, -0.314521104097366f, + 0.888444244861603f, -0.314819127321243f, 0.888202667236328f, -0.315116971731186f, + 0.887960851192474f, -0.315414607524872f, 0.887718796730042f, -0.315712094306946f, + 0.887476563453674f, -0.316009372472763f, 0.887234091758728f, -0.316306471824646f, + 0.886991322040558f, -0.316603392362595f, 0.886748373508453f, -0.316900104284287f, + 0.886505246162415f, -0.317196637392044f, 0.886261820793152f, -0.317492991685867f, + 0.886018216609955f, -0.317789167165756f, 0.885774314403534f, -0.318085134029388f, + 0.885530233383179f, -0.318380922079086f, 0.885285973548889f, -0.318676531314850f, + 0.885041415691376f, -0.318971961736679f, 0.884796679019928f, -0.319267183542252f, + 0.884551644325256f, -0.319562226533890f, 0.884306430816650f, -0.319857090711594f, + 0.884061038494110f, -0.320151746273041f, 0.883815348148346f, -0.320446223020554f, + 0.883569478988647f, -0.320740520954132f, 0.883323311805725f, -0.321034610271454f, + 0.883076965808868f, -0.321328520774841f, 0.882830440998077f, -0.321622252464294f, + 0.882583618164063f, -0.321915775537491f, 0.882336616516113f, -0.322209119796753f, + 0.882089376449585f, -0.322502255439758f, 0.881841897964478f, -0.322795242071152f, + 0.881594181060791f, -0.323088020086288f, 0.881346285343170f, -0.323380589485168f, + 0.881098151206970f, -0.323672980070114f, 0.880849778652191f, -0.323965191841125f, + 0.880601167678833f, -0.324257194995880f, 0.880352377891541f, -0.324549019336700f, + 0.880103349685669f, -0.324840664863586f, 0.879854083061218f, -0.325132101774216f, + 0.879604578018188f, -0.325423330068588f, 0.879354894161224f, -0.325714409351349f, + 0.879104971885681f, -0.326005280017853f, 0.878854811191559f, -0.326295942068100f, + 0.878604412078857f, -0.326586425304413f, 0.878353834152222f, -0.326876699924469f, + 0.878103017807007f, -0.327166795730591f, 0.877851963043213f, -0.327456712722778f, + 0.877600669860840f, -0.327746421098709f, 0.877349197864532f, -0.328035950660706f, + 0.877097487449646f, -0.328325271606445f, 0.876845538616180f, -0.328614413738251f, + 0.876593410968781f, -0.328903347253799f, 0.876341044902802f, -0.329192101955414f, + 0.876088440418243f, -0.329480648040771f, 0.875835597515106f, -0.329769015312195f, + 0.875582575798035f, -0.330057173967361f, 0.875329315662384f, -0.330345153808594f, + 0.875075817108154f, -0.330632925033569f, 0.874822139739990f, -0.330920487642288f, + 0.874568223953247f, -0.331207901239395f, 0.874314069747925f, -0.331495076417923f, + 0.874059677124023f, -0.331782072782516f, 0.873805105686188f, -0.332068890333176f, + 0.873550295829773f, -0.332355499267578f, 0.873295307159424f, -0.332641899585724f, + 0.873040020465851f, -0.332928121089935f, 0.872784554958344f, -0.333214133977890f, + 0.872528910636902f, -0.333499968051910f, 0.872272968292236f, -0.333785593509674f, + 0.872016847133636f, -0.334071010351181f, 0.871760547161102f, -0.334356248378754f, + 0.871503949165344f, -0.334641307592392f, 0.871247172355652f, -0.334926128387451f, + 0.870990216732025f, -0.335210770368576f, 0.870733022689819f, -0.335495233535767f, + 0.870475590229034f, -0.335779488086700f, 0.870217919349670f, -0.336063534021378f, + 0.869960069656372f, -0.336347371339798f, 0.869701981544495f, -0.336631029844284f, + 0.869443655014038f, -0.336914509534836f, 0.869185149669647f, -0.337197750806808f, + 0.868926405906677f, -0.337480813264847f, 0.868667483329773f, -0.337763696908951f, + 0.868408262729645f, -0.338046342134476f, 0.868148922920227f, -0.338328808546066f, + 0.867889285087585f, -0.338611096143723f, 0.867629468441010f, -0.338893145322800f, + 0.867369413375854f, -0.339175015687943f, 0.867109179496765f, -0.339456677436829f, + 0.866848707199097f, -0.339738160371780f, 0.866588056087494f, -0.340019434690475f, + 0.866327106952667f, -0.340300500392914f, 0.866066038608551f, -0.340581357479095f, + 0.865804672241211f, -0.340862035751343f, 0.865543127059937f, -0.341142505407333f, + 0.865281403064728f, -0.341422766447067f, 0.865019381046295f, -0.341702848672867f, + 0.864757239818573f, -0.341982692480087f, 0.864494800567627f, -0.342262357473373f, + 0.864232182502747f, -0.342541843652725f, 0.863969385623932f, -0.342821091413498f, + 0.863706290721893f, -0.343100160360336f, 0.863443076610565f, -0.343379020690918f, + 0.863179564476013f, -0.343657672405243f, 0.862915873527527f, -0.343936115503311f, + 0.862652003765106f, -0.344214379787445f, 0.862387895584106f, -0.344492435455322f, + 0.862123548984528f, -0.344770282506943f, 0.861859023571014f, -0.345047920942307f, + 0.861594259738922f, -0.345325350761414f, 0.861329257488251f, -0.345602601766586f, + 0.861064076423645f, -0.345879614353180f, 0.860798716545105f, -0.346156448125839f, + 0.860533118247986f, -0.346433073282242f, 0.860267281532288f, -0.346709519624710f, + 0.860001266002655f, -0.346985727548599f, 0.859735012054443f, -0.347261756658554f, + 0.859468579292297f, -0.347537547349930f, 0.859201908111572f, -0.347813159227371f, + 0.858934998512268f, -0.348088562488556f, 0.858667910099030f, -0.348363757133484f, + 0.858400642871857f, -0.348638743162155f, 0.858133137226105f, -0.348913550376892f, + 0.857865393161774f, -0.349188119173050f, 0.857597470283508f, -0.349462509155273f, + 0.857329368591309f, -0.349736660718918f, 0.857060968875885f, -0.350010633468628f, + 0.856792449951172f, -0.350284397602081f, 0.856523692607880f, -0.350557953119278f, + 0.856254696846008f, -0.350831300020218f, 0.855985522270203f, -0.351104438304901f, + 0.855716109275818f, -0.351377367973328f, 0.855446517467499f, -0.351650089025497f, + 0.855176687240601f, -0.351922631263733f, 0.854906618595123f, -0.352194935083389f, + 0.854636430740356f, -0.352467030286789f, 0.854365944862366f, -0.352738946676254f, + 0.854095339775085f, -0.353010624647141f, 0.853824436664581f, -0.353282123804092f, + 0.853553414344788f, -0.353553384542465f, 0.853282094001770f, -0.353824466466904f, + 0.853010654449463f, -0.354095309972763f, 0.852738916873932f, -0.354365974664688f, + 0.852467060089111f, -0.354636400938034f, 0.852194905281067f, -0.354906648397446f, + 0.851922631263733f, -0.355176687240601f, 0.851650118827820f, -0.355446487665176f, + 0.851377367973328f, -0.355716109275818f, 0.851104438304901f, -0.355985492467880f, + 0.850831270217896f, -0.356254696846008f, 0.850557923316956f, -0.356523662805557f, + 0.850284397602081f, -0.356792420148849f, 0.850010633468628f, -0.357060998678207f, + 0.849736690521240f, -0.357329338788986f, 0.849462509155273f, -0.357597470283508f, + 0.849188148975372f, -0.357865422964096f, 0.848913550376892f, -0.358133137226105f, + 0.848638772964478f, -0.358400642871857f, 0.848363757133484f, -0.358667939901352f, + 0.848088562488556f, -0.358935028314590f, 0.847813189029694f, -0.359201908111572f, + 0.847537577152252f, -0.359468549489975f, 0.847261726856232f, -0.359735012054443f, + 0.846985757350922f, -0.360001266002655f, 0.846709489822388f, -0.360267281532288f, + 0.846433103084564f, -0.360533088445663f, 0.846156477928162f, -0.360798716545105f, + 0.845879614353180f, -0.361064106225967f, 0.845602571964264f, -0.361329287290573f, + 0.845325350761414f, -0.361594229936600f, 0.845047891139984f, -0.361858993768692f, + 0.844770252704620f, -0.362123548984528f, 0.844492435455322f, -0.362387865781784f, + 0.844214379787445f, -0.362651973962784f, 0.843936145305634f, -0.362915903329849f, + 0.843657672405243f, -0.363179564476013f, 0.843379020690918f, -0.363443046808243f, + 0.843100130558014f, -0.363706320524216f, 0.842821121215820f, -0.363969355821610f, + 0.842541813850403f, -0.364232182502747f, 0.842262387275696f, -0.364494800567627f, + 0.841982722282410f, -0.364757210016251f, 0.841702818870544f, -0.365019410848618f, + 0.841422796249390f, -0.365281373262405f, 0.841142535209656f, -0.365543156862259f, + 0.840862035751343f, -0.365804702043533f, 0.840581357479095f, -0.366066008806229f, + 0.840300500392914f, -0.366327136754990f, 0.840019404888153f, -0.366588026285172f, + 0.839738130569458f, -0.366848707199097f, 0.839456677436829f, -0.367109179496765f, + 0.839175045490265f, -0.367369443178177f, 0.838893175125122f, -0.367629468441010f, + 0.838611066341400f, -0.367889285087585f, 0.838328838348389f, -0.368148893117905f, + 0.838046371936798f, -0.368408292531967f, 0.837763667106628f, -0.368667453527451f, + 0.837480843067169f, -0.368926405906677f, 0.837197780609131f, -0.369185149669647f, + 0.836914479732513f, -0.369443655014038f, 0.836631059646606f, -0.369701951742172f, + 0.836347401142120f, -0.369960039854050f, 0.836063504219055f, -0.370217919349670f, + 0.835779488086700f, -0.370475560426712f, 0.835495233535767f, -0.370732992887497f, + 0.835210800170898f, -0.370990216732025f, 0.834926128387451f, -0.371247202157974f, + 0.834641277790070f, -0.371503978967667f, 0.834356248378754f, -0.371760547161102f, + 0.834071040153503f, -0.372016876935959f, 0.833785593509674f, -0.372272998094559f, + 0.833499968051910f, -0.372528880834579f, 0.833214163780212f, -0.372784584760666f, + 0.832928121089935f, -0.373040050268173f, 0.832641899585724f, -0.373295277357101f, + 0.832355499267578f, -0.373550295829773f, 0.832068860530853f, -0.373805105686188f, + 0.831782102584839f, -0.374059677124023f, 0.831495106220245f, -0.374314039945602f, + 0.831207871437073f, -0.374568194150925f, 0.830920517444611f, -0.374822109937668f, + 0.830632925033569f, -0.375075817108154f, 0.830345153808594f, -0.375329315662384f, + 0.830057144165039f, -0.375582575798035f, 0.829769015312195f, -0.375835597515106f, + 0.829480648040771f, -0.376088410615921f, 0.829192101955414f, -0.376341015100479f, + 0.828903317451477f, -0.376593410968781f, 0.828614413738251f, -0.376845568418503f, + 0.828325271606445f, -0.377097487449646f, 0.828035950660706f, -0.377349197864532f, + 0.827746450901031f, -0.377600699663162f, 0.827456712722778f, -0.377851963043213f, + 0.827166795730591f, -0.378102988004684f, 0.826876699924469f, -0.378353834152222f, + 0.826586425304413f, -0.378604412078857f, 0.826295912265778f, -0.378854811191559f, + 0.826005280017853f, -0.379104942083359f, 0.825714409351349f, -0.379354894161224f, + 0.825423359870911f, -0.379604607820511f, 0.825132071971893f, -0.379854083061218f, + 0.824840664863586f, -0.380103349685669f, 0.824549019336700f, -0.380352377891541f, + 0.824257194995880f, -0.380601197481155f, 0.823965191841125f, -0.380849778652191f, + 0.823673009872437f, -0.381098151206970f, 0.823380589485168f, -0.381346285343170f, + 0.823087990283966f, -0.381594210863113f, 0.822795212268829f, -0.381841897964478f, + 0.822502255439758f, -0.382089376449585f, 0.822209119796753f, -0.382336616516113f, + 0.821915745735168f, -0.382583618164063f, 0.821622252464294f, -0.382830440998077f, + 0.821328520774841f, -0.383076995611191f, 0.821034610271454f, -0.383323341608047f, + 0.820740520954132f, -0.383569449186325f, 0.820446193218231f, -0.383815348148346f, + 0.820151746273041f, -0.384061008691788f, 0.819857060909271f, -0.384306460618973f, + 0.819562196731567f, -0.384551674127579f, 0.819267153739929f, -0.384796649217606f, + 0.818971931934357f, -0.385041415691376f, 0.818676531314850f, -0.385285943746567f, + 0.818380951881409f, -0.385530263185501f, 0.818085134029388f, -0.385774344205856f, + 0.817789137363434f, -0.386018186807632f, 0.817493021488190f, -0.386261820793152f, + 0.817196667194366f, -0.386505216360092f, 0.816900074481964f, -0.386748403310776f, + 0.816603362560272f, -0.386991351842880f, 0.816306471824646f, -0.387234061956406f, + 0.816009342670441f, -0.387476563453674f, 0.815712094306946f, -0.387718826532364f, + 0.815414607524872f, -0.387960851192474f, 0.815116941928864f, -0.388202667236328f, + 0.814819097518921f, -0.388444244861603f, 0.814521074295044f, -0.388685584068298f, + 0.814222872257233f, -0.388926714658737f, 0.813924491405487f, -0.389167606830597f, + 0.813625931739807f, -0.389408260583878f, 0.813327133655548f, -0.389648675918579f, + 0.813028216362000f, -0.389888882637024f, 0.812729060649872f, -0.390128880739212f, + 0.812429726123810f, -0.390368610620499f, 0.812130272388458f, -0.390608131885529f, + 0.811830580234528f, -0.390847414731979f, 0.811530709266663f, -0.391086459159851f, + 0.811230659484863f, -0.391325294971466f, 0.810930430889130f, -0.391563892364502f, + 0.810629963874817f, -0.391802251338959f, 0.810329377651215f, -0.392040401697159f, + 0.810028612613678f, -0.392278283834457f, 0.809727668762207f, -0.392515957355499f, + 0.809426486492157f, -0.392753422260284f, 0.809125185012817f, -0.392990618944168f, + 0.808823645114899f, -0.393227607011795f, 0.808521986007690f, -0.393464356660843f, + 0.808220088481903f, -0.393700867891312f, 0.807918012142181f, -0.393937170505524f, + 0.807615816593170f, -0.394173204898834f, 0.807313382625580f, -0.394409030675888f, + 0.807010769844055f, -0.394644618034363f, 0.806707978248596f, -0.394879996776581f, + 0.806405067443848f, -0.395115107297897f, 0.806101918220520f, -0.395350009202957f, + 0.805798590183258f, -0.395584672689438f, 0.805495083332062f, -0.395819097757339f, + 0.805191397666931f, -0.396053284406662f, 0.804887533187866f, -0.396287262439728f, + 0.804583489894867f, -0.396520972251892f, 0.804279267787933f, -0.396754473447800f, + 0.803974866867065f, -0.396987736225128f, 0.803670346736908f, -0.397220760583878f, + 0.803365588188171f, -0.397453576326370f, 0.803060650825500f, -0.397686123847961f, + 0.802755534648895f, -0.397918462753296f, 0.802450239658356f, -0.398150533437729f, + 0.802144765853882f, -0.398382395505905f, 0.801839113235474f, -0.398614019155502f, + 0.801533281803131f, -0.398845434188843f, 0.801227271556854f, -0.399076581001282f, + 0.800921142101288f, -0.399307489395142f, 0.800614774227142f, -0.399538189172745f, + 0.800308227539063f, -0.399768620729446f, 0.800001561641693f, -0.399998843669891f, + 0.799694657325745f, -0.400228828191757f, 0.799387574195862f, -0.400458574295044f, + 0.799080371856689f, -0.400688081979752f, 0.798772931098938f, -0.400917351245880f, + 0.798465371131897f, -0.401146411895752f, 0.798157572746277f, -0.401375204324722f, + 0.797849655151367f, -0.401603758335114f, 0.797541558742523f, -0.401832103729248f, + 0.797233223915100f, -0.402060180902481f, 0.796924769878387f, -0.402288049459457f, + 0.796616137027740f, -0.402515679597855f, 0.796307325363159f, -0.402743041515350f, + 0.795998334884644f, -0.402970194816589f, 0.795689165592194f, -0.403197109699249f, + 0.795379877090454f, -0.403423786163330f, 0.795070350170136f, -0.403650224208832f, + 0.794760644435883f, -0.403876423835754f, 0.794450819492340f, -0.404102355241776f, + 0.794140756130219f, -0.404328078031540f, 0.793830573558807f, -0.404553562402725f, + 0.793520212173462f, -0.404778808355331f, 0.793209671974182f, -0.405003815889359f, + 0.792898952960968f, -0.405228585004807f, 0.792588055133820f, -0.405453115701675f, + 0.792276978492737f, -0.405677437782288f, 0.791965723037720f, -0.405901491641998f, + 0.791654348373413f, -0.406125307083130f, 0.791342735290527f, -0.406348884105682f, + 0.791031002998352f, -0.406572192907333f, 0.790719091892242f, -0.406795293092728f, + 0.790407001972198f, -0.407018154859543f, 0.790094733238220f, -0.407240778207779f, + 0.789782285690308f, -0.407463163137436f, 0.789469659328461f, -0.407685309648514f, + 0.789156913757324f, -0.407907217741013f, 0.788843929767609f, -0.408128857612610f, + 0.788530826568604f, -0.408350288867950f, 0.788217544555664f, -0.408571451902390f, + 0.787904083728790f, -0.408792406320572f, 0.787590444087982f, -0.409013092517853f, + 0.787276685237885f, -0.409233570098877f, 0.786962687969208f, -0.409453779459000f, + 0.786648571491241f, -0.409673750400543f, 0.786334276199341f, -0.409893482923508f, + 0.786019802093506f, -0.410112977027893f, 0.785705149173737f, -0.410332232713699f, + 0.785390377044678f, -0.410551249980927f, 0.785075426101685f, -0.410770028829575f, + 0.784760236740112f, -0.410988569259644f, 0.784444928169250f, -0.411206841468811f, + 0.784129500389099f, -0.411424905061722f, 0.783813834190369f, -0.411642700433731f, + 0.783498048782349f, -0.411860257387161f, 0.783182024955750f, -0.412077575922012f, + 0.782865881919861f, -0.412294656038284f, 0.782549619674683f, -0.412511497735977f, + 0.782233119010925f, -0.412728071212769f, 0.781916499137878f, -0.412944436073303f, + 0.781599700450897f, -0.413160532712936f, 0.781282722949982f, -0.413376390933990f, + 0.780965566635132f, -0.413592010736465f, 0.780648231506348f, -0.413807392120361f, + 0.780330777168274f, -0.414022535085678f, 0.780013144016266f, -0.414237409830093f, + 0.779695332050323f, -0.414452046155930f, 0.779377400875092f, -0.414666473865509f, + 0.779059290885925f, -0.414880603551865f, 0.778741002082825f, -0.415094524621964f, + 0.778422534465790f, -0.415308207273483f, 0.778103888034821f, -0.415521621704102f, + 0.777785122394562f, -0.415734797716141f, 0.777466177940369f, -0.415947735309601f, + 0.777147054672241f, -0.416160434484482f, 0.776827812194824f, -0.416372895240784f, + 0.776508331298828f, -0.416585087776184f, 0.776188731193542f, -0.416797041893005f, + 0.775869011878967f, -0.417008757591248f, 0.775549054145813f, -0.417220205068588f, + 0.775228977203369f, -0.417431443929672f, 0.774908721446991f, -0.417642414569855f, + 0.774588346481323f, -0.417853146791458f, 0.774267733097076f, -0.418063640594482f, + 0.773947000503540f, -0.418273866176605f, 0.773626148700714f, -0.418483853340149f, + 0.773305058479309f, -0.418693602085114f, 0.772983849048615f, -0.418903112411499f, + 0.772662520408630f, -0.419112354516983f, 0.772340953350067f, -0.419321358203888f, + 0.772019267082214f, -0.419530123472214f, 0.771697402000427f, -0.419738620519638f, + 0.771375417709351f, -0.419946908950806f, 0.771053194999695f, -0.420154929161072f, + 0.770730912685394f, -0.420362681150436f, 0.770408391952515f, -0.420570224523544f, + 0.770085752010345f, -0.420777499675751f, 0.769762933254242f, -0.420984506607056f, + 0.769439935684204f, -0.421191304922104f, 0.769116818904877f, -0.421397835016251f, + 0.768793523311615f, -0.421604126691818f, 0.768470108509064f, -0.421810150146484f, + 0.768146514892578f, -0.422015935182571f, 0.767822742462158f, -0.422221481800079f, + 0.767498791217804f, -0.422426789999008f, 0.767174720764160f, -0.422631829977036f, + 0.766850471496582f, -0.422836631536484f, 0.766526103019714f, -0.423041164875031f, + 0.766201555728912f, -0.423245459794998f, 0.765876889228821f, -0.423449516296387f, + 0.765551984310150f, -0.423653304576874f, 0.765226960182190f, -0.423856884241104f, + 0.764901816844940f, -0.424060165882111f, 0.764576494693756f, -0.424263238906860f, + 0.764250993728638f, -0.424466013908386f, 0.763925373554230f, -0.424668580293655f, + 0.763599574565887f, -0.424870878458023f, 0.763273596763611f, -0.425072938203812f, + 0.762947499752045f, -0.425274729728699f, 0.762621283531189f, -0.425476282835007f, + 0.762294828891754f, -0.425677597522736f, 0.761968255043030f, -0.425878643989563f, + 0.761641561985016f, -0.426079452037811f, 0.761314690113068f, -0.426279991865158f, + 0.760987639427185f, -0.426480293273926f, 0.760660469532013f, -0.426680356264114f, + 0.760333120822906f, -0.426880151033401f, 0.760005652904511f, -0.427079707384110f, + 0.759678006172180f, -0.427278995513916f, 0.759350180625916f, -0.427478045225143f, + 0.759022235870361f, -0.427676826715469f, 0.758694171905518f, -0.427875369787216f, + 0.758365929126740f, -0.428073674440384f, 0.758037507534027f, -0.428271710872650f, + 0.757708966732025f, -0.428469479084015f, 0.757380247116089f, -0.428667008876801f, + 0.757051348686218f, -0.428864300251007f, 0.756722390651703f, -0.429061323404312f, + 0.756393194198608f, -0.429258108139038f, 0.756063878536224f, -0.429454624652863f, + 0.755734443664551f, -0.429650902748108f, 0.755404829978943f, -0.429846942424774f, + 0.755075037479401f, -0.430042684078217f, 0.754745125770569f, -0.430238217115402f, + 0.754415094852448f, -0.430433481931686f, 0.754084885120392f, -0.430628478527069f, + 0.753754496574402f, -0.430823236703873f, 0.753423988819122f, -0.431017726659775f, + 0.753093302249908f, -0.431211978197098f, 0.752762496471405f, -0.431405961513519f, + 0.752431571483612f, -0.431599706411362f, 0.752100467681885f, -0.431793183088303f, + 0.751769185066223f, -0.431986421346664f, 0.751437783241272f, -0.432179391384125f, + 0.751106262207031f, -0.432372123003006f, 0.750774562358856f, -0.432564586400986f, + 0.750442683696747f, -0.432756811380386f, 0.750110685825348f, -0.432948768138886f, + 0.749778568744659f, -0.433140486478806f, 0.749446272850037f, -0.433331936597824f, + 0.749113857746124f, -0.433523118495941f, 0.748781263828278f, -0.433714061975479f, + 0.748448550701141f, -0.433904737234116f, 0.748115658760071f, -0.434095174074173f, + 0.747782647609711f, -0.434285342693329f, 0.747449457645416f, -0.434475272893906f, + 0.747116148471832f, -0.434664934873581f, 0.746782720088959f, -0.434854328632355f, + 0.746449112892151f, -0.435043483972549f, 0.746115326881409f, -0.435232400894165f, + 0.745781481266022f, -0.435421019792557f, 0.745447397232056f, -0.435609430074692f, + 0.745113253593445f, -0.435797542333603f, 0.744778931140900f, -0.435985416173935f, + 0.744444429874420f, -0.436173021793365f, 0.744109809398651f, -0.436360388994217f, + 0.743775069713593f, -0.436547487974167f, 0.743440151214600f, -0.436734348535538f, + 0.743105113506317f, -0.436920911073685f, 0.742769956588745f, -0.437107264995575f, + 0.742434620857239f, -0.437293320894241f, 0.742099165916443f, -0.437479138374329f, + 0.741763532161713f, -0.437664687633514f, 0.741427779197693f, -0.437849998474121f, + 0.741091907024384f, -0.438035041093826f, 0.740755856037140f, -0.438219845294952f, + 0.740419685840607f, -0.438404351472855f, 0.740083336830139f, -0.438588619232178f, + 0.739746868610382f, -0.438772648572922f, 0.739410281181335f, -0.438956409692764f, + 0.739073514938354f, -0.439139902591705f, 0.738736629486084f, -0.439323127269745f, + 0.738399624824524f, -0.439506113529205f, 0.738062441349030f, -0.439688831567764f, + 0.737725138664246f, -0.439871311187744f, 0.737387716770172f, -0.440053492784500f, + 0.737050116062164f, -0.440235435962677f, 0.736712396144867f, -0.440417140722275f, + 0.736374497413635f, -0.440598547458649f, 0.736036539077759f, -0.440779715776443f, + 0.735698342323303f, -0.440960645675659f, 0.735360085964203f, -0.441141277551651f, + 0.735021650791168f, -0.441321671009064f, 0.734683096408844f, -0.441501796245575f, + 0.734344422817230f, -0.441681683063507f, 0.734005570411682f, -0.441861271858215f, + 0.733666598796844f, -0.442040622234344f, 0.733327507972717f, -0.442219734191895f, + 0.732988238334656f, -0.442398548126221f, 0.732648849487305f, -0.442577123641968f, + 0.732309341430664f, -0.442755430936813f, 0.731969714164734f, -0.442933470010757f, + 0.731629908084869f, -0.443111270666122f, 0.731289982795715f, -0.443288803100586f, + 0.730949878692627f, -0.443466067314148f, 0.730609714984894f, -0.443643063306808f, + 0.730269372463226f, -0.443819820880890f, 0.729928910732269f, -0.443996280431747f, + 0.729588270187378f, -0.444172531366348f, 0.729247510433197f, -0.444348484277725f, + 0.728906631469727f, -0.444524168968201f, 0.728565633296967f, -0.444699615240097f, + 0.728224515914917f, -0.444874793291092f, 0.727883219718933f, -0.445049703121185f, + 0.727541804313660f, -0.445224374532700f, 0.727200269699097f, -0.445398747920990f, + 0.726858556270599f, -0.445572882890701f, 0.726516723632813f, -0.445746749639511f, + 0.726174771785736f, -0.445920348167419f, 0.725832700729370f, -0.446093708276749f, + 0.725490510463715f, -0.446266770362854f, 0.725148141384125f, -0.446439594030380f, + 0.724805653095245f, -0.446612149477005f, 0.724463045597076f, -0.446784436702728f, + 0.724120318889618f, -0.446956485509872f, 0.723777413368225f, -0.447128236293793f, + 0.723434448242188f, -0.447299748659134f, 0.723091304302216f, -0.447470992803574f, + 0.722747981548309f, -0.447641968727112f, 0.722404599189758f, -0.447812676429749f, + 0.722061097621918f, -0.447983115911484f, 0.721717417240143f, -0.448153316974640f, + 0.721373617649078f, -0.448323249816895f, 0.721029698848724f, -0.448492884635925f, + 0.720685660839081f, -0.448662281036377f, 0.720341444015503f, -0.448831409215927f, + 0.719997107982636f, -0.449000298976898f, 0.719652712345123f, -0.449168890714645f, + 0.719308137893677f, -0.449337244033813f, 0.718963444232941f, -0.449505299329758f, + 0.718618571758270f, -0.449673116207123f, 0.718273639678955f, -0.449840664863586f, + 0.717928528785706f, -0.450007945299149f, 0.717583298683167f, -0.450174957513809f, + 0.717238008975983f, -0.450341701507568f, 0.716892480850220f, -0.450508207082748f, + 0.716546893119812f, -0.450674414634705f, 0.716201186180115f, -0.450840383768082f, + 0.715855300426483f, -0.451006084680557f, 0.715509355068207f, -0.451171487569809f, + 0.715163230895996f, -0.451336652040482f, 0.714816987514496f, -0.451501548290253f, + 0.714470624923706f, -0.451666176319122f, 0.714124143123627f, -0.451830536127090f, + 0.713777542114258f, -0.451994657516479f, 0.713430821895599f, -0.452158480882645f, + 0.713083922863007f, -0.452322036027908f, 0.712736964225769f, -0.452485352754593f, + 0.712389826774597f, -0.452648371458054f, 0.712042629718781f, -0.452811151742935f, + 0.711695253849030f, -0.452973634004593f, 0.711347758769989f, -0.453135877847672f, + 0.711000144481659f, -0.453297853469849f, 0.710652410984039f, -0.453459560871124f, + 0.710304558277130f, -0.453621000051498f, 0.709956526756287f, -0.453782171010971f, + 0.709608435630798f, -0.453943043947220f, 0.709260225296021f, -0.454103678464890f, + 0.708911836147308f, -0.454264044761658f, 0.708563387393951f, -0.454424172639847f, + 0.708214759826660f, -0.454584002494812f, 0.707866072654724f, -0.454743564128876f, + 0.707517206668854f, -0.454902857542038f, 0.707168221473694f, -0.455061882734299f, + 0.706819176673889f, -0.455220639705658f, 0.706469953060150f, -0.455379128456116f, + 0.706120610237122f, -0.455537378787994f, 0.705771148204803f, -0.455695331096649f, + 0.705421566963196f, -0.455853015184402f, 0.705071866512299f, -0.456010431051254f, + 0.704722046852112f, -0.456167578697205f, 0.704372167587280f, -0.456324487924576f, + 0.704022109508514f, -0.456481099128723f, 0.703671932220459f, -0.456637442111969f, + 0.703321635723114f, -0.456793516874313f, 0.702971220016479f, -0.456949323415756f, + 0.702620685100555f, -0.457104891538620f, 0.702270030975342f, -0.457260161638260f, + 0.701919257640839f, -0.457415163516998f, 0.701568365097046f, -0.457569897174835f, + 0.701217353343964f, -0.457724362611771f, 0.700866222381592f, -0.457878559827805f, + 0.700514972209930f, -0.458032488822937f, 0.700163602828979f, -0.458186149597168f, + 0.699812114238739f, -0.458339542150497f, 0.699460506439209f, -0.458492636680603f, + 0.699108779430389f, -0.458645492792130f, 0.698756933212280f, -0.458798080682755f, + 0.698404967784882f, -0.458950400352478f, 0.698052942752838f, -0.459102421998978f, + 0.697700738906860f, -0.459254205226898f, 0.697348415851593f, -0.459405690431595f, + 0.696996033191681f, -0.459556937217712f, 0.696643471717834f, -0.459707885980606f, + 0.696290850639343f, -0.459858566522598f, 0.695938050746918f, -0.460008978843689f, + 0.695585191249847f, -0.460159152746201f, 0.695232212543488f, -0.460309028625488f, + 0.694879114627838f, -0.460458606481552f, 0.694525837898254f, -0.460607945919037f, + 0.694172501564026f, -0.460757017135620f, 0.693819046020508f, -0.460905820131302f, + 0.693465530872345f, -0.461054325103760f, 0.693111836910248f, -0.461202591657639f, + 0.692758023738861f, -0.461350560188293f, 0.692404091358185f, -0.461498260498047f, + 0.692050099372864f, -0.461645722389221f, 0.691695988178253f, -0.461792886257172f, + 0.691341698169708f, -0.461939752101898f, 0.690987348556519f, -0.462086379528046f, + 0.690632879734039f, -0.462232738733292f, 0.690278291702271f, -0.462378799915314f, + 0.689923584461212f, -0.462524622678757f, 0.689568817615509f, -0.462670147418976f, + 0.689213871955872f, -0.462815403938293f, 0.688858866691589f, -0.462960392236710f, + 0.688503682613373f, -0.463105112314224f, 0.688148438930511f, -0.463249564170837f, + 0.687793076038361f, -0.463393747806549f, 0.687437593936920f, -0.463537633419037f, + 0.687082052230835f, -0.463681250810623f, 0.686726331710815f, -0.463824629783630f, + 0.686370551586151f, -0.463967710733414f, 0.686014592647552f, -0.464110493659973f, + 0.685658574104309f, -0.464253038167953f, 0.685302436351776f, -0.464395314455032f, + 0.684946238994598f, -0.464537292718887f, 0.684589862823486f, -0.464679002761841f, + 0.684233427047729f, -0.464820444583893f, 0.683876872062683f, -0.464961618185043f, + 0.683520197868347f, -0.465102523565292f, 0.683163404464722f, -0.465243130922318f, + 0.682806491851807f, -0.465383470058441f, 0.682449519634247f, -0.465523540973663f, + 0.682092368602753f, -0.465663343667984f, 0.681735157966614f, -0.465802878141403f, + 0.681377887725830f, -0.465942144393921f, 0.681020438671112f, -0.466081112623215f, + 0.680662930011749f, -0.466219812631607f, 0.680305242538452f, -0.466358244419098f, + 0.679947495460510f, -0.466496407985687f, 0.679589688777924f, -0.466634273529053f, + 0.679231703281403f, -0.466771900653839f, 0.678873658180237f, -0.466909229755402f, + 0.678515493869781f, -0.467046260833740f, 0.678157210350037f, -0.467183053493500f, + 0.677798807621002f, -0.467319577932358f, 0.677440345287323f, -0.467455804347992f, + 0.677081763744354f, -0.467591762542725f, 0.676723062992096f, -0.467727422714233f, + 0.676364302635193f, -0.467862844467163f, 0.676005363464355f, -0.467997968196869f, + 0.675646364688873f, -0.468132823705673f, 0.675287246704102f, -0.468267410993576f, + 0.674928069114685f, -0.468401730060577f, 0.674568772315979f, -0.468535751104355f, + 0.674209356307983f, -0.468669503927231f, 0.673849821090698f, -0.468802988529205f, + 0.673490226268768f, -0.468936175107956f, 0.673130512237549f, -0.469069123268127f, + 0.672770678997040f, -0.469201773405075f, 0.672410726547241f, -0.469334155321121f, + 0.672050714492798f, -0.469466239213943f, 0.671690583229065f, -0.469598054885864f, + 0.671330332756042f, -0.469729602336884f, 0.670970022678375f, -0.469860881567001f, + 0.670609593391418f, -0.469991862773895f, 0.670249044895172f, -0.470122605562210f, + 0.669888436794281f, -0.470253020524979f, 0.669527709484100f, -0.470383197069168f, + 0.669166862964630f, -0.470513075590134f, 0.668805956840515f, -0.470642685890198f, + 0.668444931507111f, -0.470772027969360f, 0.668083786964417f, -0.470901101827621f, + 0.667722582817078f, -0.471029877662659f, 0.667361259460449f, -0.471158385276794f, + 0.666999816894531f, -0.471286594867706f, 0.666638314723969f, -0.471414536237717f, + 0.666276693344116f, -0.471542209386826f, 0.665914952754974f, -0.471669614315033f, + 0.665553152561188f, -0.471796721220016f, 0.665191233158112f, -0.471923559904099f, + 0.664829254150391f, -0.472050130367279f, 0.664467096328735f, -0.472176402807236f, + 0.664104938507080f, -0.472302407026291f, 0.663742601871490f, -0.472428143024445f, + 0.663380205631256f, -0.472553610801697f, 0.663017749786377f, -0.472678780555725f, + 0.662655174732208f, -0.472803652286530f, 0.662292480468750f, -0.472928285598755f, + 0.661929666996002f, -0.473052620887756f, 0.661566793918610f, -0.473176687955856f, + 0.661203861236572f, -0.473300457000732f, 0.660840749740601f, -0.473423957824707f, + 0.660477638244629f, -0.473547190427780f, 0.660114347934723f, -0.473670125007629f, + 0.659750998020172f, -0.473792791366577f, 0.659387588500977f, -0.473915189504623f, + 0.659024059772491f, -0.474037289619446f, 0.658660411834717f, -0.474159121513367f, + 0.658296704292297f, -0.474280685186386f, 0.657932877540588f, -0.474401950836182f, + 0.657568991184235f, -0.474522948265076f, 0.657204985618591f, -0.474643647670746f, + 0.656840860843658f, -0.474764078855515f, 0.656476676464081f, -0.474884241819382f, + 0.656112432479858f, -0.475004136562347f, 0.655748009681702f, -0.475123733282089f, + 0.655383586883545f, -0.475243031978607f, 0.655019044876099f, -0.475362062454224f, + 0.654654383659363f, -0.475480824708939f, 0.654289662837982f, -0.475599318742752f, + 0.653924822807312f, -0.475717514753342f, 0.653559923171997f, -0.475835442543030f, + 0.653194904327393f, -0.475953072309494f, 0.652829825878143f, -0.476070433855057f, + 0.652464628219604f, -0.476187497377396f, 0.652099311351776f, -0.476304292678833f, + 0.651733994483948f, -0.476420819759369f, 0.651368498802185f, -0.476537048816681f, + 0.651003003120422f, -0.476653009653091f, 0.650637328624725f, -0.476768702268600f, + 0.650271594524384f, -0.476884096860886f, 0.649905800819397f, -0.476999223232269f, + 0.649539887905121f, -0.477114051580429f, 0.649173915386200f, -0.477228611707687f, + 0.648807883262634f, -0.477342873811722f, 0.648441672325134f, -0.477456867694855f, + 0.648075461387634f, -0.477570593357086f, 0.647709131240845f, -0.477684020996094f, + 0.647342681884766f, -0.477797180414200f, 0.646976172924042f, -0.477910041809082f, + 0.646609604358673f, -0.478022634983063f, 0.646242916584015f, -0.478134930133820f, + 0.645876109600067f, -0.478246957063675f, 0.645509302616119f, -0.478358715772629f, + 0.645142316818237f, -0.478470176458359f, 0.644775331020355f, -0.478581339120865f, + 0.644408226013184f, -0.478692263364792f, 0.644041001796722f, -0.478802859783173f, + 0.643673717975616f, -0.478913217782974f, 0.643306374549866f, -0.479023247957230f, + 0.642938911914825f, -0.479133039712906f, 0.642571389675140f, -0.479242533445358f, + 0.642203748226166f, -0.479351729154587f, 0.641836047172546f, -0.479460656642914f, + 0.641468286514282f, -0.479569315910339f, 0.641100406646729f, -0.479677677154541f, + 0.640732467174530f, -0.479785770177841f, 0.640364408493042f, -0.479893565177917f, + 0.639996349811554f, -0.480001062154770f, 0.639628112316132f, -0.480108320713043f, + 0.639259815216064f, -0.480215251445770f, 0.638891458511353f, -0.480321943759918f, + 0.638523042201996f, -0.480428308248520f, 0.638154506683350f, -0.480534434318542f, + 0.637785911560059f, -0.480640232563019f, 0.637417197227478f, -0.480745792388916f, + 0.637048482894897f, -0.480851024389267f, 0.636679589748383f, -0.480956017971039f, + 0.636310696601868f, -0.481060713529587f, 0.635941684246063f, -0.481165111064911f, + 0.635572552680969f, -0.481269240379334f, 0.635203421115875f, -0.481373071670532f, + 0.634834170341492f, -0.481476634740829f, 0.634464859962463f, -0.481579899787903f, + 0.634095430374146f, -0.481682896614075f, 0.633725941181183f, -0.481785595417023f, + 0.633356392383575f, -0.481888025999069f, 0.632986724376678f, -0.481990188360214f, + 0.632616996765137f, -0.482092022895813f, 0.632247209548950f, -0.482193619012833f, + 0.631877362728119f, -0.482294887304306f, 0.631507396697998f, -0.482395917177200f, + 0.631137371063232f, -0.482496619224548f, 0.630767226219177f, -0.482597053050995f, + 0.630397081375122f, -0.482697218656540f, 0.630026817321777f, -0.482797086238861f, + 0.629656434059143f, -0.482896685600281f, 0.629286050796509f, -0.482995986938477f, + 0.628915548324585f, -0.483094990253448f, 0.628544986248016f, -0.483193725347519f, + 0.628174364566803f, -0.483292192220688f, 0.627803623676300f, -0.483390361070633f, + 0.627432823181152f, -0.483488231897354f, 0.627061963081360f, -0.483585834503174f, + 0.626691043376923f, -0.483683139085770f, 0.626320004463196f, -0.483780175447464f, + 0.625948905944824f, -0.483876913785934f, 0.625577747821808f, -0.483973383903503f, + 0.625206530094147f, -0.484069555997849f, 0.624835193157196f, -0.484165430068970f, + 0.624463796615601f, -0.484261035919189f, 0.624092340469360f, -0.484356373548508f, + 0.623720824718475f, -0.484451413154602f, 0.623349189758301f, -0.484546154737473f, + 0.622977554798126f, -0.484640628099442f, 0.622605800628662f, -0.484734803438187f, + 0.622233927249908f, -0.484828680753708f, 0.621862053871155f, -0.484922289848328f, + 0.621490061283112f, -0.485015630722046f, 0.621118068695068f, -0.485108673572540f, + 0.620745956897736f, -0.485201418399811f, 0.620373785495758f, -0.485293895006180f, + 0.620001494884491f, -0.485386073589325f, 0.619629204273224f, -0.485477954149246f, + 0.619256794452667f, -0.485569566488266f, 0.618884325027466f, -0.485660910606384f, + 0.618511795997620f, -0.485751956701279f, 0.618139207363129f, -0.485842704772949f, + 0.617766559123993f, -0.485933154821396f, 0.617393791675568f, -0.486023366451263f, + 0.617020964622498f, -0.486113250255585f, 0.616648077964783f, -0.486202865839005f, + 0.616275131702423f, -0.486292183399200f, 0.615902125835419f, -0.486381232738495f, + 0.615529060363770f, -0.486469984054565f, 0.615155875682831f, -0.486558437347412f, + 0.614782691001892f, -0.486646622419357f, 0.614409387111664f, -0.486734509468079f, + 0.614036023616791f, -0.486822128295898f, 0.613662600517273f, -0.486909449100494f, + 0.613289117813110f, -0.486996471881866f, 0.612915575504303f, -0.487083226442337f, + 0.612541973590851f, -0.487169682979584f, 0.612168252468109f, -0.487255871295929f, + 0.611794531345367f, -0.487341761589050f, 0.611420691013336f, -0.487427353858948f, + 0.611046791076660f, -0.487512677907944f, 0.610672831535339f, -0.487597703933716f, + 0.610298871994019f, -0.487682431936264f, 0.609924793243408f, -0.487766891717911f, + 0.609550595283508f, -0.487851053476334f, 0.609176397323608f, -0.487934947013855f, + 0.608802139759064f, -0.488018542528152f, 0.608427822589874f, -0.488101840019226f, + 0.608053386211395f, -0.488184869289398f, 0.607678949832916f, -0.488267600536346f, + 0.607304394245148f, -0.488350033760071f, 0.606929838657379f, -0.488432198762894f, + 0.606555163860321f, -0.488514065742493f, 0.606180429458618f, -0.488595664501190f, + 0.605805635452271f, -0.488676935434341f, 0.605430841445923f, -0.488757967948914f, + 0.605055928230286f, -0.488838672637939f, 0.604680955410004f, -0.488919109106064f, + 0.604305922985077f, -0.488999247550964f, 0.603930830955505f, -0.489079117774963f, + 0.603555679321289f, -0.489158689975739f, 0.603180468082428f, -0.489237964153290f, + 0.602805197238922f, -0.489316970109940f, 0.602429866790771f, -0.489395678043365f, + 0.602054476737976f, -0.489474087953568f, 0.601679027080536f, -0.489552229642868f, + 0.601303517818451f, -0.489630073308945f, 0.600927948951721f, -0.489707618951797f, + 0.600552320480347f, -0.489784896373749f, 0.600176632404327f, -0.489861875772476f, + 0.599800884723663f, -0.489938557147980f, 0.599425077438354f, -0.490014940500259f, + 0.599049210548401f, -0.490091055631638f, 0.598673284053802f, -0.490166902542114f, + 0.598297297954559f, -0.490242421627045f, 0.597921252250671f, -0.490317672491074f, + 0.597545146942139f, -0.490392625331879f, 0.597168982028961f, -0.490467309951782f, + 0.596792817115784f, -0.490541696548462f, 0.596416532993317f, -0.490615785121918f, + 0.596040189266205f, -0.490689605474472f, 0.595663845539093f, -0.490763127803802f, + 0.595287382602692f, -0.490836352109909f, 0.594910860061646f, -0.490909278392792f, + 0.594534337520599f, -0.490981936454773f, 0.594157755374908f, -0.491054296493530f, + 0.593781054019928f, -0.491126358509064f, 0.593404352664948f, -0.491198152303696f, + 0.593027591705322f, -0.491269648075104f, 0.592650771141052f, -0.491340845823288f, + 0.592273890972137f, -0.491411775350571f, 0.591896951198578f, -0.491482406854630f, + 0.591519951820374f, -0.491552740335464f, 0.591142892837524f, -0.491622805595398f, + 0.590765833854675f, -0.491692543029785f, 0.590388655662537f, -0.491762012243271f, + 0.590011477470398f, -0.491831213235855f, 0.589634180068970f, -0.491900116205215f, + 0.589256882667542f, -0.491968721151352f, 0.588879525661469f, -0.492037028074265f, + 0.588502109050751f, -0.492105036973953f, 0.588124632835388f, -0.492172777652740f, + 0.587747097015381f, -0.492240220308304f, 0.587369561195374f, -0.492307394742966f, + 0.586991965770721f, -0.492374241352081f, 0.586614251136780f, -0.492440819740295f, + 0.586236536502838f, -0.492507129907608f, 0.585858762264252f, -0.492573112249374f, + 0.585480928421021f, -0.492638826370239f, 0.585103094577789f, -0.492704242467880f, + 0.584725141525269f, -0.492769360542297f, 0.584347188472748f, -0.492834210395813f, + 0.583969175815582f, -0.492898762226105f, 0.583591103553772f, -0.492963016033173f, + 0.583212971687317f, -0.493026971817017f, 0.582834780216217f, -0.493090659379959f, + 0.582456588745117f, -0.493154048919678f, 0.582078278064728f, -0.493217140436172f, + 0.581699967384338f, -0.493279963731766f, 0.581321597099304f, -0.493342459201813f, + 0.580943167209625f, -0.493404686450958f, 0.580564737319946f, -0.493466645479202f, + 0.580186247825623f, -0.493528276681900f, 0.579807698726654f, -0.493589639663696f, + 0.579429090023041f, -0.493650704622269f, 0.579050421714783f, -0.493711471557617f, + 0.578671753406525f, -0.493771970272064f, 0.578292965888977f, -0.493832170963287f, + 0.577914178371429f, -0.493892073631287f, 0.577535390853882f, -0.493951678276062f, + 0.577156484127045f, -0.494011014699936f, 0.576777577400208f, -0.494070053100586f, + 0.576398611068726f, -0.494128793478012f, 0.576019585132599f, -0.494187235832214f, + 0.575640499591827f, -0.494245409965515f, 0.575261414051056f, -0.494303256273270f, + 0.574882268905640f, -0.494360834360123f, 0.574503064155579f, -0.494418144226074f, + 0.574123859405518f, -0.494475126266479f, 0.573744535446167f, -0.494531840085983f, + 0.573365211486816f, -0.494588255882263f, 0.572985887527466f, -0.494644373655319f, + 0.572606444358826f, -0.494700223207474f, 0.572227001190186f, -0.494755744934082f, + 0.571847498416901f, -0.494810998439789f, 0.571467995643616f, -0.494865983724594f, + 0.571088373661041f, -0.494920641183853f, 0.570708811283112f, -0.494975030422211f, + 0.570329129695892f, -0.495029091835022f, 0.569949388504028f, -0.495082914829254f, + 0.569569647312164f, -0.495136409997940f, 0.569189906120300f, -0.495189607143402f, + 0.568810045719147f, -0.495242536067963f, 0.568430185317993f, -0.495295166969299f, + 0.568050265312195f, -0.495347499847412f, 0.567670345306396f, -0.495399564504623f, + 0.567290365695953f, -0.495451331138611f, 0.566910326480865f, -0.495502769947052f, + 0.566530287265778f, -0.495553970336914f, 0.566150128841400f, -0.495604842901230f, + 0.565770030021667f, -0.495655417442322f, 0.565389811992645f, -0.495705723762512f, + 0.565009593963623f, -0.495755732059479f, 0.564629375934601f, -0.495805442333221f, + 0.564249038696289f, -0.495854884386063f, 0.563868701457977f, -0.495903998613358f, + 0.563488364219666f, -0.495952844619751f, 0.563107967376709f, -0.496001392602921f, + 0.562727510929108f, -0.496049642562866f, 0.562346994876862f, -0.496097624301910f, + 0.561966478824615f, -0.496145308017731f, 0.561585903167725f, -0.496192663908005f, + 0.561205327510834f, -0.496239781379700f, 0.560824692249298f, -0.496286571025848f, + 0.560444056987762f, -0.496333062648773f, 0.560063362121582f, -0.496379286050797f, + 0.559682607650757f, -0.496425211429596f, 0.559301853179932f, -0.496470838785172f, + 0.558921039104462f, -0.496516168117523f, 0.558540165424347f, -0.496561229228973f, + 0.558159291744232f, -0.496605962514877f, 0.557778418064117f, -0.496650427579880f, + 0.557397484779358f, -0.496694594621658f, 0.557016491889954f, -0.496738493442535f, + 0.556635499000549f, -0.496782064437866f, 0.556254446506500f, -0.496825367212296f, + 0.555873334407806f, -0.496868371963501f, 0.555492222309113f, -0.496911078691483f, + 0.555111110210419f, -0.496953487396240f, 0.554729938507080f, -0.496995598077774f, + 0.554348707199097f, -0.497037440538406f, 0.553967475891113f, -0.497078984975815f, + 0.553586184978485f, -0.497120231389999f, 0.553204894065857f, -0.497161179780960f, + 0.552823603153229f, -0.497201830148697f, 0.552442193031311f, -0.497242212295532f, + 0.552060842514038f, -0.497282296419144f, 0.551679372787476f, -0.497322082519531f, + 0.551297962665558f, -0.497361570596695f, 0.550916433334351f, -0.497400760650635f, + 0.550534904003143f, -0.497439652681351f, 0.550153374671936f, -0.497478276491165f, + 0.549771785736084f, -0.497516602277756f, 0.549390196800232f, -0.497554630041122f, + 0.549008548259735f, -0.497592359781265f, 0.548626899719238f, -0.497629791498184f, + 0.548245191574097f, -0.497666954994202f, 0.547863483428955f, -0.497703820466995f, + 0.547481775283813f, -0.497740387916565f, 0.547099947929382f, -0.497776657342911f, + 0.546718180179596f, -0.497812628746033f, 0.546336352825165f, -0.497848302125931f, + 0.545954465866089f, -0.497883707284927f, 0.545572578907013f, -0.497918814420700f, + 0.545190691947937f, -0.497953623533249f, 0.544808745384216f, -0.497988134622574f, + 0.544426798820496f, -0.498022347688675f, 0.544044792652130f, -0.498056292533875f, + 0.543662786483765f, -0.498089909553528f, 0.543280720710754f, -0.498123258352280f, + 0.542898654937744f, -0.498156309127808f, 0.542516589164734f, -0.498189061880112f, + 0.542134463787079f, -0.498221516609192f, 0.541752278804779f, -0.498253703117371f, + 0.541370153427124f, -0.498285561800003f, 0.540987968444824f, -0.498317152261734f, + 0.540605723857880f, -0.498348444700241f, 0.540223479270935f, -0.498379439115524f, + 0.539841234683990f, -0.498410135507584f, 0.539458930492401f, -0.498440563678741f, + 0.539076626300812f, -0.498470664024353f, 0.538694262504578f, -0.498500496149063f, + 0.538311958312988f, -0.498530030250549f, 0.537929534912109f, -0.498559266328812f, + 0.537547171115875f, -0.498588204383850f, 0.537164747714996f, -0.498616874217987f, + 0.536782264709473f, -0.498645216226578f, 0.536399841308594f, -0.498673290014267f, + 0.536017298698425f, -0.498701065778732f, 0.535634815692902f, -0.498728543519974f, + 0.535252273082733f, -0.498755723237991f, 0.534869730472565f, -0.498782604932785f, + 0.534487187862396f, -0.498809218406677f, 0.534104585647583f, -0.498835533857346f, + 0.533721983432770f, -0.498861521482468f, 0.533339321613312f, -0.498887240886688f, + 0.532956659793854f, -0.498912662267685f, 0.532573997974396f, -0.498937815427780f, + 0.532191336154938f, -0.498962640762329f, 0.531808614730835f, -0.498987197875977f, + 0.531425893306732f, -0.499011427164078f, 0.531043112277985f, -0.499035388231277f, + 0.530660390853882f, -0.499059051275253f, 0.530277609825134f, -0.499082416296005f, + 0.529894769191742f, -0.499105513095856f, 0.529511988162994f, -0.499128282070160f, + 0.529129147529602f, -0.499150782823563f, 0.528746306896210f, -0.499172955751419f, + 0.528363406658173f, -0.499194860458374f, 0.527980506420136f, -0.499216467142105f, + 0.527597606182098f, -0.499237775802612f, 0.527214705944061f, -0.499258816242218f, + 0.526831746101379f, -0.499279528856277f, 0.526448845863342f, -0.499299973249435f, + 0.526065826416016f, -0.499320119619370f, 0.525682866573334f, -0.499339967966080f, + 0.525299847126007f, -0.499359518289566f, 0.524916887283325f, -0.499378770589828f, + 0.524533808231354f, -0.499397724866867f, 0.524150788784027f, -0.499416410923004f, + 0.523767769336700f, -0.499434769153595f, 0.523384690284729f, -0.499452859163284f, + 0.523001611232758f, -0.499470651149750f, 0.522618472576141f, -0.499488145112991f, + 0.522235393524170f, -0.499505341053009f, 0.521852254867554f, -0.499522238969803f, + 0.521469116210938f, -0.499538868665695f, 0.521085977554321f, -0.499555170536041f, + 0.520702838897705f, -0.499571204185486f, 0.520319640636444f, -0.499586939811707f, + 0.519936442375183f, -0.499602377414703f, 0.519553244113922f, -0.499617516994476f, + 0.519170045852661f, -0.499632388353348f, 0.518786847591400f, -0.499646931886673f, + 0.518403589725494f, -0.499661177396774f, 0.518020391464233f, -0.499675154685974f, + 0.517637133598328f, -0.499688833951950f, 0.517253875732422f, -0.499702215194702f, + 0.516870558261871f, -0.499715298414230f, 0.516487300395966f, -0.499728083610535f, + 0.516103982925415f, -0.499740600585938f, 0.515720725059509f, -0.499752789735794f, + 0.515337407588959f, -0.499764710664749f, 0.514954090118408f, -0.499776333570480f, + 0.514570772647858f, -0.499787658452988f, 0.514187395572662f, -0.499798685312271f, + 0.513804078102112f, -0.499809414148331f, 0.513420701026917f, -0.499819844961166f, + 0.513037383556366f, -0.499830007553101f, 0.512654006481171f, -0.499839842319489f, + 0.512270629405975f, -0.499849408864975f, 0.511887252330780f, -0.499858677387238f, + 0.511503815650940f, -0.499867647886276f, 0.511120438575745f, -0.499876320362091f, + 0.510737061500549f, -0.499884694814682f, 0.510353624820709f, -0.499892801046371f, + 0.509970188140869f, -0.499900579452515f, 0.509586811065674f, -0.499908089637756f, + 0.509203374385834f, -0.499915301799774f, 0.508819937705994f, -0.499922215938568f, + 0.508436501026154f, -0.499928832054138f, 0.508053064346313f, -0.499935150146484f, + 0.507669627666473f, -0.499941170215607f, 0.507286131381989f, -0.499946922063828f, + 0.506902694702148f, -0.499952346086502f, 0.506519258022308f, -0.499957501888275f, + 0.506135761737823f, -0.499962359666824f, 0.505752325057983f, -0.499966919422150f, + 0.505368828773499f, -0.499971181154251f, 0.504985332489014f, -0.499975144863129f, + 0.504601895809174f, -0.499978810548782f, 0.504218399524689f, -0.499982208013535f, + 0.503834903240204f, -0.499985307455063f, 0.503451406955719f, -0.499988079071045f, + 0.503067970275879f, -0.499990582466125f, 0.502684473991394f, -0.499992787837982f, + 0.502300977706909f, -0.499994695186615f, 0.501917481422424f, -0.499996334314346f, + 0.501533985137939f, -0.499997645616531f, 0.501150488853455f, -0.499998688697815f, + 0.500766992568970f, -0.499999403953552f, 0.500383496284485f, -0.499999850988388f, +}; + + + +/** + @} end of RealFFT_Table group + */ + +/** + @addtogroup RealFFT + @{ + */ + +/** + @brief Initialization function for the floating-point RFFT/RIFFT. + @deprecated Do not use this function. It has been superceded by \ref arm_rfft_fast_init_f32 and will be removed in the future. + @param[in,out] S points to an instance of the floating-point RFFT/RIFFT structure + @param[in,out] S_CFFT points to an instance of the floating-point CFFT/CIFFT structure + @param[in] fftLenReal length of the FFT. + @param[in] ifftFlagR flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : fftLenReal is not a supported length + + @par Description + The parameter fftLenRealspecifies length of RFFT/RIFFT Process. + Supported FFT Lengths are 128, 512, 2048. + @par + The parameter ifftFlagR controls whether a forward or inverse transform is computed. + Set(=1) ifftFlagR to calculate RIFFT, otherwise RFFT is calculated. + @par + The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. + Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. + @par + This function also initializes Twiddle factor table. + */ + +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) +{ + + /* Initialise the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + + /* Initialize the Real FFT length */ + S->fftLenReal = (uint16_t) fftLenReal; + + /* Initialize the Complex FFT length */ + S->fftLenBy2 = (uint16_t) fftLenReal / 2U; + + /* Initialize the Twiddle coefficientA pointer */ + S->pTwiddleAReal = (float32_t *) realCoefA; + + /* Initialize the Twiddle coefficientB pointer */ + S->pTwiddleBReal = (float32_t *) realCoefB; + + /* Initialize the Flag for selection of RFFT or RIFFT */ + S->ifftFlagR = (uint8_t) ifftFlagR; + + /* Initialize the Flag for calculation Bit reversal or not */ + S->bitReverseFlagR = (uint8_t) bitReverseFlag; + + /* Initializations of structure parameters depending on the FFT length */ + switch (S->fftLenReal) + { + /* Init table modifier value */ + case 8192U: + S->twidCoefRModifier = 1U; + break; + case 2048U: + S->twidCoefRModifier = 4U; + break; + case 512U: + S->twidCoefRModifier = 16U; + break; + case 128U: + S->twidCoefRModifier = 64U; + break; + default: + /* Reporting argument error if rfftSize is not valid value */ + status = ARM_MATH_ARGUMENT_ERROR; + break; + } + + /* Init Complex FFT Instance */ + S->pCfft = S_CFFT; + + if (S->ifftFlagR) + { + /* Initializes the CIFFT Module for fftLenreal/2 length */ + arm_cfft_radix4_init_f32(S->pCfft, S->fftLenBy2, 1U, 0U); + } + else + { + /* Initializes the CFFT Module for fftLenreal/2 length */ + arm_cfft_radix4_init_f32(S->pCfft, S->fftLenBy2, 0U, 0U); + } + + /* return the status of RFFT Init function */ + return (status); + +} + +/** + @} end of RealFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_q15.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_q15.c new file mode 100644 index 0000000..2abdd33 --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_q15.c @@ -0,0 +1,2235 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_rfft_init_q15.c + * Description: RFFT & RIFFT Q15 initialisation function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" +#include "arm_const_structs.h" + +/** + @ingroup RealFFT + */ + +/** + @addtogroup RealFFT_Table Real FFT Tables + @{ + */ + +/** + @par + Generation fixed-point realCoefAQ15 array in Q15 format: + @par + n = 4096 +
for (i = 0; i < n; i++)
+  {
+     pATable[2 * i]     = 0.5 * ( 1.0 - sin (2 * PI / (double) (2 * n) * (double) i));
+     pATable[2 * i + 1] = 0.5 * (-1.0 * cos (2 * PI / (double) (2 * n) * (double) i));
+  }
+ @par + Convert to fixed point Q15 format + round(pATable[i] * pow(2, 15)) + */ +const q15_t __ALIGNED(4) realCoefAQ15[8192] = { + (q15_t)0x4000, (q15_t)0xc000, (q15_t)0x3ff3, (q15_t)0xc000, (q15_t)0x3fe7, (q15_t)0xc000, (q15_t)0x3fda, (q15_t)0xc000, + (q15_t)0x3fce, (q15_t)0xc000, (q15_t)0x3fc1, (q15_t)0xc000, (q15_t)0x3fb5, (q15_t)0xc000, (q15_t)0x3fa8, (q15_t)0xc000, + (q15_t)0x3f9b, (q15_t)0xc000, (q15_t)0x3f8f, (q15_t)0xc000, (q15_t)0x3f82, (q15_t)0xc000, (q15_t)0x3f76, (q15_t)0xc001, + (q15_t)0x3f69, (q15_t)0xc001, (q15_t)0x3f5d, (q15_t)0xc001, (q15_t)0x3f50, (q15_t)0xc001, (q15_t)0x3f44, (q15_t)0xc001, + (q15_t)0x3f37, (q15_t)0xc001, (q15_t)0x3f2a, (q15_t)0xc001, (q15_t)0x3f1e, (q15_t)0xc002, (q15_t)0x3f11, (q15_t)0xc002, + (q15_t)0x3f05, (q15_t)0xc002, (q15_t)0x3ef8, (q15_t)0xc002, (q15_t)0x3eec, (q15_t)0xc002, (q15_t)0x3edf, (q15_t)0xc003, + (q15_t)0x3ed2, (q15_t)0xc003, (q15_t)0x3ec6, (q15_t)0xc003, (q15_t)0x3eb9, (q15_t)0xc003, (q15_t)0x3ead, (q15_t)0xc004, + (q15_t)0x3ea0, (q15_t)0xc004, (q15_t)0x3e94, (q15_t)0xc004, (q15_t)0x3e87, (q15_t)0xc004, (q15_t)0x3e7a, (q15_t)0xc005, + (q15_t)0x3e6e, (q15_t)0xc005, (q15_t)0x3e61, (q15_t)0xc005, (q15_t)0x3e55, (q15_t)0xc006, (q15_t)0x3e48, (q15_t)0xc006, + (q15_t)0x3e3c, (q15_t)0xc006, (q15_t)0x3e2f, (q15_t)0xc007, (q15_t)0x3e23, (q15_t)0xc007, (q15_t)0x3e16, (q15_t)0xc007, + (q15_t)0x3e09, (q15_t)0xc008, (q15_t)0x3dfd, (q15_t)0xc008, (q15_t)0x3df0, (q15_t)0xc009, (q15_t)0x3de4, (q15_t)0xc009, + (q15_t)0x3dd7, (q15_t)0xc009, (q15_t)0x3dcb, (q15_t)0xc00a, (q15_t)0x3dbe, (q15_t)0xc00a, (q15_t)0x3db2, (q15_t)0xc00b, + (q15_t)0x3da5, (q15_t)0xc00b, (q15_t)0x3d98, (q15_t)0xc00c, (q15_t)0x3d8c, (q15_t)0xc00c, (q15_t)0x3d7f, (q15_t)0xc00d, + (q15_t)0x3d73, (q15_t)0xc00d, (q15_t)0x3d66, (q15_t)0xc00e, (q15_t)0x3d5a, (q15_t)0xc00e, (q15_t)0x3d4d, (q15_t)0xc00f, + (q15_t)0x3d40, (q15_t)0xc00f, (q15_t)0x3d34, (q15_t)0xc010, (q15_t)0x3d27, (q15_t)0xc010, (q15_t)0x3d1b, (q15_t)0xc011, + (q15_t)0x3d0e, (q15_t)0xc011, (q15_t)0x3d02, (q15_t)0xc012, (q15_t)0x3cf5, (q15_t)0xc013, (q15_t)0x3ce9, (q15_t)0xc013, + (q15_t)0x3cdc, (q15_t)0xc014, (q15_t)0x3cd0, (q15_t)0xc014, (q15_t)0x3cc3, (q15_t)0xc015, (q15_t)0x3cb6, (q15_t)0xc016, + (q15_t)0x3caa, (q15_t)0xc016, (q15_t)0x3c9d, (q15_t)0xc017, (q15_t)0x3c91, (q15_t)0xc018, (q15_t)0x3c84, (q15_t)0xc018, + (q15_t)0x3c78, (q15_t)0xc019, (q15_t)0x3c6b, (q15_t)0xc01a, (q15_t)0x3c5f, (q15_t)0xc01a, (q15_t)0x3c52, (q15_t)0xc01b, + (q15_t)0x3c45, (q15_t)0xc01c, (q15_t)0x3c39, (q15_t)0xc01d, (q15_t)0x3c2c, (q15_t)0xc01d, (q15_t)0x3c20, (q15_t)0xc01e, + (q15_t)0x3c13, (q15_t)0xc01f, (q15_t)0x3c07, (q15_t)0xc020, (q15_t)0x3bfa, (q15_t)0xc020, (q15_t)0x3bee, (q15_t)0xc021, + (q15_t)0x3be1, (q15_t)0xc022, (q15_t)0x3bd5, (q15_t)0xc023, (q15_t)0x3bc8, (q15_t)0xc024, (q15_t)0x3bbc, (q15_t)0xc024, + (q15_t)0x3baf, (q15_t)0xc025, (q15_t)0x3ba2, (q15_t)0xc026, (q15_t)0x3b96, (q15_t)0xc027, (q15_t)0x3b89, (q15_t)0xc028, + (q15_t)0x3b7d, (q15_t)0xc029, (q15_t)0x3b70, (q15_t)0xc02a, (q15_t)0x3b64, (q15_t)0xc02b, (q15_t)0x3b57, (q15_t)0xc02b, + (q15_t)0x3b4b, (q15_t)0xc02c, (q15_t)0x3b3e, (q15_t)0xc02d, (q15_t)0x3b32, (q15_t)0xc02e, (q15_t)0x3b25, (q15_t)0xc02f, + (q15_t)0x3b19, (q15_t)0xc030, (q15_t)0x3b0c, (q15_t)0xc031, (q15_t)0x3b00, (q15_t)0xc032, (q15_t)0x3af3, (q15_t)0xc033, + (q15_t)0x3ae6, (q15_t)0xc034, (q15_t)0x3ada, (q15_t)0xc035, (q15_t)0x3acd, (q15_t)0xc036, (q15_t)0x3ac1, (q15_t)0xc037, + (q15_t)0x3ab4, (q15_t)0xc038, (q15_t)0x3aa8, (q15_t)0xc039, (q15_t)0x3a9b, (q15_t)0xc03a, (q15_t)0x3a8f, (q15_t)0xc03b, + (q15_t)0x3a82, (q15_t)0xc03c, (q15_t)0x3a76, (q15_t)0xc03d, (q15_t)0x3a69, (q15_t)0xc03f, (q15_t)0x3a5d, (q15_t)0xc040, + (q15_t)0x3a50, (q15_t)0xc041, (q15_t)0x3a44, (q15_t)0xc042, (q15_t)0x3a37, (q15_t)0xc043, (q15_t)0x3a2b, (q15_t)0xc044, + (q15_t)0x3a1e, (q15_t)0xc045, (q15_t)0x3a12, (q15_t)0xc047, (q15_t)0x3a05, (q15_t)0xc048, (q15_t)0x39f9, (q15_t)0xc049, + (q15_t)0x39ec, (q15_t)0xc04a, (q15_t)0x39e0, (q15_t)0xc04b, (q15_t)0x39d3, (q15_t)0xc04c, (q15_t)0x39c7, (q15_t)0xc04e, + (q15_t)0x39ba, (q15_t)0xc04f, (q15_t)0x39ae, (q15_t)0xc050, (q15_t)0x39a1, (q15_t)0xc051, (q15_t)0x3995, (q15_t)0xc053, + (q15_t)0x3988, (q15_t)0xc054, (q15_t)0x397c, (q15_t)0xc055, (q15_t)0x396f, (q15_t)0xc056, (q15_t)0x3963, (q15_t)0xc058, + (q15_t)0x3956, (q15_t)0xc059, (q15_t)0x394a, (q15_t)0xc05a, (q15_t)0x393d, (q15_t)0xc05c, (q15_t)0x3931, (q15_t)0xc05d, + (q15_t)0x3924, (q15_t)0xc05e, (q15_t)0x3918, (q15_t)0xc060, (q15_t)0x390b, (q15_t)0xc061, (q15_t)0x38ff, (q15_t)0xc062, + (q15_t)0x38f2, (q15_t)0xc064, (q15_t)0x38e6, (q15_t)0xc065, (q15_t)0x38d9, (q15_t)0xc067, (q15_t)0x38cd, (q15_t)0xc068, + (q15_t)0x38c0, (q15_t)0xc069, (q15_t)0x38b4, (q15_t)0xc06b, (q15_t)0x38a7, (q15_t)0xc06c, (q15_t)0x389b, (q15_t)0xc06e, + (q15_t)0x388e, (q15_t)0xc06f, (q15_t)0x3882, (q15_t)0xc071, (q15_t)0x3875, (q15_t)0xc072, (q15_t)0x3869, (q15_t)0xc074, + (q15_t)0x385c, (q15_t)0xc075, (q15_t)0x3850, (q15_t)0xc077, (q15_t)0x3843, (q15_t)0xc078, (q15_t)0x3837, (q15_t)0xc07a, + (q15_t)0x382a, (q15_t)0xc07b, (q15_t)0x381e, (q15_t)0xc07d, (q15_t)0x3811, (q15_t)0xc07e, (q15_t)0x3805, (q15_t)0xc080, + (q15_t)0x37f9, (q15_t)0xc081, (q15_t)0x37ec, (q15_t)0xc083, (q15_t)0x37e0, (q15_t)0xc085, (q15_t)0x37d3, (q15_t)0xc086, + (q15_t)0x37c7, (q15_t)0xc088, (q15_t)0x37ba, (q15_t)0xc089, (q15_t)0x37ae, (q15_t)0xc08b, (q15_t)0x37a1, (q15_t)0xc08d, + (q15_t)0x3795, (q15_t)0xc08e, (q15_t)0x3788, (q15_t)0xc090, (q15_t)0x377c, (q15_t)0xc092, (q15_t)0x376f, (q15_t)0xc093, + (q15_t)0x3763, (q15_t)0xc095, (q15_t)0x3757, (q15_t)0xc097, (q15_t)0x374a, (q15_t)0xc098, (q15_t)0x373e, (q15_t)0xc09a, + (q15_t)0x3731, (q15_t)0xc09c, (q15_t)0x3725, (q15_t)0xc09e, (q15_t)0x3718, (q15_t)0xc09f, (q15_t)0x370c, (q15_t)0xc0a1, + (q15_t)0x36ff, (q15_t)0xc0a3, (q15_t)0x36f3, (q15_t)0xc0a5, (q15_t)0x36e7, (q15_t)0xc0a6, (q15_t)0x36da, (q15_t)0xc0a8, + (q15_t)0x36ce, (q15_t)0xc0aa, (q15_t)0x36c1, (q15_t)0xc0ac, (q15_t)0x36b5, (q15_t)0xc0ae, (q15_t)0x36a8, (q15_t)0xc0af, + (q15_t)0x369c, (q15_t)0xc0b1, (q15_t)0x3690, (q15_t)0xc0b3, (q15_t)0x3683, (q15_t)0xc0b5, (q15_t)0x3677, (q15_t)0xc0b7, + (q15_t)0x366a, (q15_t)0xc0b9, (q15_t)0x365e, (q15_t)0xc0bb, (q15_t)0x3651, (q15_t)0xc0bd, (q15_t)0x3645, (q15_t)0xc0be, + (q15_t)0x3639, (q15_t)0xc0c0, (q15_t)0x362c, (q15_t)0xc0c2, (q15_t)0x3620, (q15_t)0xc0c4, (q15_t)0x3613, (q15_t)0xc0c6, + (q15_t)0x3607, (q15_t)0xc0c8, (q15_t)0x35fa, (q15_t)0xc0ca, (q15_t)0x35ee, (q15_t)0xc0cc, (q15_t)0x35e2, (q15_t)0xc0ce, + (q15_t)0x35d5, (q15_t)0xc0d0, (q15_t)0x35c9, (q15_t)0xc0d2, (q15_t)0x35bc, (q15_t)0xc0d4, (q15_t)0x35b0, (q15_t)0xc0d6, + (q15_t)0x35a4, (q15_t)0xc0d8, (q15_t)0x3597, (q15_t)0xc0da, (q15_t)0x358b, (q15_t)0xc0dc, (q15_t)0x357e, (q15_t)0xc0de, + (q15_t)0x3572, (q15_t)0xc0e0, (q15_t)0x3566, (q15_t)0xc0e2, (q15_t)0x3559, (q15_t)0xc0e4, (q15_t)0x354d, (q15_t)0xc0e7, + (q15_t)0x3540, (q15_t)0xc0e9, (q15_t)0x3534, (q15_t)0xc0eb, (q15_t)0x3528, (q15_t)0xc0ed, (q15_t)0x351b, (q15_t)0xc0ef, + (q15_t)0x350f, (q15_t)0xc0f1, (q15_t)0x3503, (q15_t)0xc0f3, (q15_t)0x34f6, (q15_t)0xc0f6, (q15_t)0x34ea, (q15_t)0xc0f8, + (q15_t)0x34dd, (q15_t)0xc0fa, (q15_t)0x34d1, (q15_t)0xc0fc, (q15_t)0x34c5, (q15_t)0xc0fe, (q15_t)0x34b8, (q15_t)0xc100, + (q15_t)0x34ac, (q15_t)0xc103, (q15_t)0x34a0, (q15_t)0xc105, (q15_t)0x3493, (q15_t)0xc107, (q15_t)0x3487, (q15_t)0xc109, + (q15_t)0x347b, (q15_t)0xc10c, (q15_t)0x346e, (q15_t)0xc10e, (q15_t)0x3462, (q15_t)0xc110, (q15_t)0x3455, (q15_t)0xc113, + (q15_t)0x3449, (q15_t)0xc115, (q15_t)0x343d, (q15_t)0xc117, (q15_t)0x3430, (q15_t)0xc119, (q15_t)0x3424, (q15_t)0xc11c, + (q15_t)0x3418, (q15_t)0xc11e, (q15_t)0x340b, (q15_t)0xc120, (q15_t)0x33ff, (q15_t)0xc123, (q15_t)0x33f3, (q15_t)0xc125, + (q15_t)0x33e6, (q15_t)0xc128, (q15_t)0x33da, (q15_t)0xc12a, (q15_t)0x33ce, (q15_t)0xc12c, (q15_t)0x33c1, (q15_t)0xc12f, + (q15_t)0x33b5, (q15_t)0xc131, (q15_t)0x33a9, (q15_t)0xc134, (q15_t)0x339c, (q15_t)0xc136, (q15_t)0x3390, (q15_t)0xc138, + (q15_t)0x3384, (q15_t)0xc13b, (q15_t)0x3377, (q15_t)0xc13d, (q15_t)0x336b, (q15_t)0xc140, (q15_t)0x335f, (q15_t)0xc142, + (q15_t)0x3352, (q15_t)0xc145, (q15_t)0x3346, (q15_t)0xc147, (q15_t)0x333a, (q15_t)0xc14a, (q15_t)0x332d, (q15_t)0xc14c, + (q15_t)0x3321, (q15_t)0xc14f, (q15_t)0x3315, (q15_t)0xc151, (q15_t)0x3308, (q15_t)0xc154, (q15_t)0x32fc, (q15_t)0xc156, + (q15_t)0x32f0, (q15_t)0xc159, (q15_t)0x32e4, (q15_t)0xc15b, (q15_t)0x32d7, (q15_t)0xc15e, (q15_t)0x32cb, (q15_t)0xc161, + (q15_t)0x32bf, (q15_t)0xc163, (q15_t)0x32b2, (q15_t)0xc166, (q15_t)0x32a6, (q15_t)0xc168, (q15_t)0x329a, (q15_t)0xc16b, + (q15_t)0x328e, (q15_t)0xc16e, (q15_t)0x3281, (q15_t)0xc170, (q15_t)0x3275, (q15_t)0xc173, (q15_t)0x3269, (q15_t)0xc176, + (q15_t)0x325c, (q15_t)0xc178, (q15_t)0x3250, (q15_t)0xc17b, (q15_t)0x3244, (q15_t)0xc17e, (q15_t)0x3238, (q15_t)0xc180, + (q15_t)0x322b, (q15_t)0xc183, (q15_t)0x321f, (q15_t)0xc186, (q15_t)0x3213, (q15_t)0xc189, (q15_t)0x3207, (q15_t)0xc18b, + (q15_t)0x31fa, (q15_t)0xc18e, (q15_t)0x31ee, (q15_t)0xc191, (q15_t)0x31e2, (q15_t)0xc194, (q15_t)0x31d5, (q15_t)0xc196, + (q15_t)0x31c9, (q15_t)0xc199, (q15_t)0x31bd, (q15_t)0xc19c, (q15_t)0x31b1, (q15_t)0xc19f, (q15_t)0x31a4, (q15_t)0xc1a2, + (q15_t)0x3198, (q15_t)0xc1a4, (q15_t)0x318c, (q15_t)0xc1a7, (q15_t)0x3180, (q15_t)0xc1aa, (q15_t)0x3174, (q15_t)0xc1ad, + (q15_t)0x3167, (q15_t)0xc1b0, (q15_t)0x315b, (q15_t)0xc1b3, (q15_t)0x314f, (q15_t)0xc1b6, (q15_t)0x3143, (q15_t)0xc1b8, + (q15_t)0x3136, (q15_t)0xc1bb, (q15_t)0x312a, (q15_t)0xc1be, (q15_t)0x311e, (q15_t)0xc1c1, (q15_t)0x3112, (q15_t)0xc1c4, + (q15_t)0x3105, (q15_t)0xc1c7, (q15_t)0x30f9, (q15_t)0xc1ca, (q15_t)0x30ed, (q15_t)0xc1cd, (q15_t)0x30e1, (q15_t)0xc1d0, + (q15_t)0x30d5, (q15_t)0xc1d3, (q15_t)0x30c8, (q15_t)0xc1d6, (q15_t)0x30bc, (q15_t)0xc1d9, (q15_t)0x30b0, (q15_t)0xc1dc, + (q15_t)0x30a4, (q15_t)0xc1df, (q15_t)0x3098, (q15_t)0xc1e2, (q15_t)0x308b, (q15_t)0xc1e5, (q15_t)0x307f, (q15_t)0xc1e8, + (q15_t)0x3073, (q15_t)0xc1eb, (q15_t)0x3067, (q15_t)0xc1ee, (q15_t)0x305b, (q15_t)0xc1f1, (q15_t)0x304e, (q15_t)0xc1f4, + (q15_t)0x3042, (q15_t)0xc1f7, (q15_t)0x3036, (q15_t)0xc1fa, (q15_t)0x302a, (q15_t)0xc1fd, (q15_t)0x301e, (q15_t)0xc201, + (q15_t)0x3012, (q15_t)0xc204, (q15_t)0x3005, (q15_t)0xc207, (q15_t)0x2ff9, (q15_t)0xc20a, (q15_t)0x2fed, (q15_t)0xc20d, + (q15_t)0x2fe1, (q15_t)0xc210, (q15_t)0x2fd5, (q15_t)0xc213, (q15_t)0x2fc9, (q15_t)0xc217, (q15_t)0x2fbc, (q15_t)0xc21a, + (q15_t)0x2fb0, (q15_t)0xc21d, (q15_t)0x2fa4, (q15_t)0xc220, (q15_t)0x2f98, (q15_t)0xc223, (q15_t)0x2f8c, (q15_t)0xc227, + (q15_t)0x2f80, (q15_t)0xc22a, (q15_t)0x2f74, (q15_t)0xc22d, (q15_t)0x2f67, (q15_t)0xc230, (q15_t)0x2f5b, (q15_t)0xc234, + (q15_t)0x2f4f, (q15_t)0xc237, (q15_t)0x2f43, (q15_t)0xc23a, (q15_t)0x2f37, (q15_t)0xc23e, (q15_t)0x2f2b, (q15_t)0xc241, + (q15_t)0x2f1f, (q15_t)0xc244, (q15_t)0x2f13, (q15_t)0xc247, (q15_t)0x2f06, (q15_t)0xc24b, (q15_t)0x2efa, (q15_t)0xc24e, + (q15_t)0x2eee, (q15_t)0xc251, (q15_t)0x2ee2, (q15_t)0xc255, (q15_t)0x2ed6, (q15_t)0xc258, (q15_t)0x2eca, (q15_t)0xc25c, + (q15_t)0x2ebe, (q15_t)0xc25f, (q15_t)0x2eb2, (q15_t)0xc262, (q15_t)0x2ea6, (q15_t)0xc266, (q15_t)0x2e99, (q15_t)0xc269, + (q15_t)0x2e8d, (q15_t)0xc26d, (q15_t)0x2e81, (q15_t)0xc270, (q15_t)0x2e75, (q15_t)0xc273, (q15_t)0x2e69, (q15_t)0xc277, + (q15_t)0x2e5d, (q15_t)0xc27a, (q15_t)0x2e51, (q15_t)0xc27e, (q15_t)0x2e45, (q15_t)0xc281, (q15_t)0x2e39, (q15_t)0xc285, + (q15_t)0x2e2d, (q15_t)0xc288, (q15_t)0x2e21, (q15_t)0xc28c, (q15_t)0x2e15, (q15_t)0xc28f, (q15_t)0x2e09, (q15_t)0xc293, + (q15_t)0x2dfc, (q15_t)0xc296, (q15_t)0x2df0, (q15_t)0xc29a, (q15_t)0x2de4, (q15_t)0xc29d, (q15_t)0x2dd8, (q15_t)0xc2a1, + (q15_t)0x2dcc, (q15_t)0xc2a5, (q15_t)0x2dc0, (q15_t)0xc2a8, (q15_t)0x2db4, (q15_t)0xc2ac, (q15_t)0x2da8, (q15_t)0xc2af, + (q15_t)0x2d9c, (q15_t)0xc2b3, (q15_t)0x2d90, (q15_t)0xc2b7, (q15_t)0x2d84, (q15_t)0xc2ba, (q15_t)0x2d78, (q15_t)0xc2be, + (q15_t)0x2d6c, (q15_t)0xc2c1, (q15_t)0x2d60, (q15_t)0xc2c5, (q15_t)0x2d54, (q15_t)0xc2c9, (q15_t)0x2d48, (q15_t)0xc2cc, + (q15_t)0x2d3c, (q15_t)0xc2d0, (q15_t)0x2d30, (q15_t)0xc2d4, (q15_t)0x2d24, (q15_t)0xc2d8, (q15_t)0x2d18, (q15_t)0xc2db, + (q15_t)0x2d0c, (q15_t)0xc2df, (q15_t)0x2d00, (q15_t)0xc2e3, (q15_t)0x2cf4, (q15_t)0xc2e6, (q15_t)0x2ce8, (q15_t)0xc2ea, + (q15_t)0x2cdc, (q15_t)0xc2ee, (q15_t)0x2cd0, (q15_t)0xc2f2, (q15_t)0x2cc4, (q15_t)0xc2f5, (q15_t)0x2cb8, (q15_t)0xc2f9, + (q15_t)0x2cac, (q15_t)0xc2fd, (q15_t)0x2ca0, (q15_t)0xc301, (q15_t)0x2c94, (q15_t)0xc305, (q15_t)0x2c88, (q15_t)0xc308, + (q15_t)0x2c7c, (q15_t)0xc30c, (q15_t)0x2c70, (q15_t)0xc310, (q15_t)0x2c64, (q15_t)0xc314, (q15_t)0x2c58, (q15_t)0xc318, + (q15_t)0x2c4c, (q15_t)0xc31c, (q15_t)0x2c40, (q15_t)0xc320, (q15_t)0x2c34, (q15_t)0xc323, (q15_t)0x2c28, (q15_t)0xc327, + (q15_t)0x2c1c, (q15_t)0xc32b, (q15_t)0x2c10, (q15_t)0xc32f, (q15_t)0x2c05, (q15_t)0xc333, (q15_t)0x2bf9, (q15_t)0xc337, + (q15_t)0x2bed, (q15_t)0xc33b, (q15_t)0x2be1, (q15_t)0xc33f, (q15_t)0x2bd5, (q15_t)0xc343, (q15_t)0x2bc9, (q15_t)0xc347, + (q15_t)0x2bbd, (q15_t)0xc34b, (q15_t)0x2bb1, (q15_t)0xc34f, (q15_t)0x2ba5, (q15_t)0xc353, (q15_t)0x2b99, (q15_t)0xc357, + (q15_t)0x2b8d, (q15_t)0xc35b, (q15_t)0x2b81, (q15_t)0xc35f, (q15_t)0x2b75, (q15_t)0xc363, (q15_t)0x2b6a, (q15_t)0xc367, + (q15_t)0x2b5e, (q15_t)0xc36b, (q15_t)0x2b52, (q15_t)0xc36f, (q15_t)0x2b46, (q15_t)0xc373, (q15_t)0x2b3a, (q15_t)0xc377, + (q15_t)0x2b2e, (q15_t)0xc37b, (q15_t)0x2b22, (q15_t)0xc37f, (q15_t)0x2b16, (q15_t)0xc383, (q15_t)0x2b0a, (q15_t)0xc387, + (q15_t)0x2aff, (q15_t)0xc38c, (q15_t)0x2af3, (q15_t)0xc390, (q15_t)0x2ae7, (q15_t)0xc394, (q15_t)0x2adb, (q15_t)0xc398, + (q15_t)0x2acf, (q15_t)0xc39c, (q15_t)0x2ac3, (q15_t)0xc3a0, (q15_t)0x2ab7, (q15_t)0xc3a5, (q15_t)0x2aac, (q15_t)0xc3a9, + (q15_t)0x2aa0, (q15_t)0xc3ad, (q15_t)0x2a94, (q15_t)0xc3b1, (q15_t)0x2a88, (q15_t)0xc3b5, (q15_t)0x2a7c, (q15_t)0xc3ba, + (q15_t)0x2a70, (q15_t)0xc3be, (q15_t)0x2a65, (q15_t)0xc3c2, (q15_t)0x2a59, (q15_t)0xc3c6, (q15_t)0x2a4d, (q15_t)0xc3ca, + (q15_t)0x2a41, (q15_t)0xc3cf, (q15_t)0x2a35, (q15_t)0xc3d3, (q15_t)0x2a29, (q15_t)0xc3d7, (q15_t)0x2a1e, (q15_t)0xc3dc, + (q15_t)0x2a12, (q15_t)0xc3e0, (q15_t)0x2a06, (q15_t)0xc3e4, (q15_t)0x29fa, (q15_t)0xc3e9, (q15_t)0x29ee, (q15_t)0xc3ed, + (q15_t)0x29e3, (q15_t)0xc3f1, (q15_t)0x29d7, (q15_t)0xc3f6, (q15_t)0x29cb, (q15_t)0xc3fa, (q15_t)0x29bf, (q15_t)0xc3fe, + (q15_t)0x29b4, (q15_t)0xc403, (q15_t)0x29a8, (q15_t)0xc407, (q15_t)0x299c, (q15_t)0xc40b, (q15_t)0x2990, (q15_t)0xc410, + (q15_t)0x2984, (q15_t)0xc414, (q15_t)0x2979, (q15_t)0xc419, (q15_t)0x296d, (q15_t)0xc41d, (q15_t)0x2961, (q15_t)0xc422, + (q15_t)0x2955, (q15_t)0xc426, (q15_t)0x294a, (q15_t)0xc42a, (q15_t)0x293e, (q15_t)0xc42f, (q15_t)0x2932, (q15_t)0xc433, + (q15_t)0x2926, (q15_t)0xc438, (q15_t)0x291b, (q15_t)0xc43c, (q15_t)0x290f, (q15_t)0xc441, (q15_t)0x2903, (q15_t)0xc445, + (q15_t)0x28f7, (q15_t)0xc44a, (q15_t)0x28ec, (q15_t)0xc44e, (q15_t)0x28e0, (q15_t)0xc453, (q15_t)0x28d4, (q15_t)0xc457, + (q15_t)0x28c9, (q15_t)0xc45c, (q15_t)0x28bd, (q15_t)0xc461, (q15_t)0x28b1, (q15_t)0xc465, (q15_t)0x28a5, (q15_t)0xc46a, + (q15_t)0x289a, (q15_t)0xc46e, (q15_t)0x288e, (q15_t)0xc473, (q15_t)0x2882, (q15_t)0xc478, (q15_t)0x2877, (q15_t)0xc47c, + (q15_t)0x286b, (q15_t)0xc481, (q15_t)0x285f, (q15_t)0xc485, (q15_t)0x2854, (q15_t)0xc48a, (q15_t)0x2848, (q15_t)0xc48f, + (q15_t)0x283c, (q15_t)0xc493, (q15_t)0x2831, (q15_t)0xc498, (q15_t)0x2825, (q15_t)0xc49d, (q15_t)0x2819, (q15_t)0xc4a1, + (q15_t)0x280e, (q15_t)0xc4a6, (q15_t)0x2802, (q15_t)0xc4ab, (q15_t)0x27f6, (q15_t)0xc4b0, (q15_t)0x27eb, (q15_t)0xc4b4, + (q15_t)0x27df, (q15_t)0xc4b9, (q15_t)0x27d3, (q15_t)0xc4be, (q15_t)0x27c8, (q15_t)0xc4c2, (q15_t)0x27bc, (q15_t)0xc4c7, + (q15_t)0x27b1, (q15_t)0xc4cc, (q15_t)0x27a5, (q15_t)0xc4d1, (q15_t)0x2799, (q15_t)0xc4d6, (q15_t)0x278e, (q15_t)0xc4da, + (q15_t)0x2782, (q15_t)0xc4df, (q15_t)0x2777, (q15_t)0xc4e4, (q15_t)0x276b, (q15_t)0xc4e9, (q15_t)0x275f, (q15_t)0xc4ee, + (q15_t)0x2754, (q15_t)0xc4f2, (q15_t)0x2748, (q15_t)0xc4f7, (q15_t)0x273d, (q15_t)0xc4fc, (q15_t)0x2731, (q15_t)0xc501, + (q15_t)0x2725, (q15_t)0xc506, (q15_t)0x271a, (q15_t)0xc50b, (q15_t)0x270e, (q15_t)0xc510, (q15_t)0x2703, (q15_t)0xc515, + (q15_t)0x26f7, (q15_t)0xc51a, (q15_t)0x26ec, (q15_t)0xc51e, (q15_t)0x26e0, (q15_t)0xc523, (q15_t)0x26d4, (q15_t)0xc528, + (q15_t)0x26c9, (q15_t)0xc52d, (q15_t)0x26bd, (q15_t)0xc532, (q15_t)0x26b2, (q15_t)0xc537, (q15_t)0x26a6, (q15_t)0xc53c, + (q15_t)0x269b, (q15_t)0xc541, (q15_t)0x268f, (q15_t)0xc546, (q15_t)0x2684, (q15_t)0xc54b, (q15_t)0x2678, (q15_t)0xc550, + (q15_t)0x266d, (q15_t)0xc555, (q15_t)0x2661, (q15_t)0xc55a, (q15_t)0x2656, (q15_t)0xc55f, (q15_t)0x264a, (q15_t)0xc564, + (q15_t)0x263f, (q15_t)0xc569, (q15_t)0x2633, (q15_t)0xc56e, (q15_t)0x2628, (q15_t)0xc573, (q15_t)0x261c, (q15_t)0xc578, + (q15_t)0x2611, (q15_t)0xc57e, (q15_t)0x2605, (q15_t)0xc583, (q15_t)0x25fa, (q15_t)0xc588, (q15_t)0x25ee, (q15_t)0xc58d, + (q15_t)0x25e3, (q15_t)0xc592, (q15_t)0x25d7, (q15_t)0xc597, (q15_t)0x25cc, (q15_t)0xc59c, (q15_t)0x25c0, (q15_t)0xc5a1, + (q15_t)0x25b5, (q15_t)0xc5a7, (q15_t)0x25a9, (q15_t)0xc5ac, (q15_t)0x259e, (q15_t)0xc5b1, (q15_t)0x2592, (q15_t)0xc5b6, + (q15_t)0x2587, (q15_t)0xc5bb, (q15_t)0x257c, (q15_t)0xc5c1, (q15_t)0x2570, (q15_t)0xc5c6, (q15_t)0x2565, (q15_t)0xc5cb, + (q15_t)0x2559, (q15_t)0xc5d0, (q15_t)0x254e, (q15_t)0xc5d5, (q15_t)0x2542, (q15_t)0xc5db, (q15_t)0x2537, (q15_t)0xc5e0, + (q15_t)0x252c, (q15_t)0xc5e5, (q15_t)0x2520, (q15_t)0xc5ea, (q15_t)0x2515, (q15_t)0xc5f0, (q15_t)0x2509, (q15_t)0xc5f5, + (q15_t)0x24fe, (q15_t)0xc5fa, (q15_t)0x24f3, (q15_t)0xc600, (q15_t)0x24e7, (q15_t)0xc605, (q15_t)0x24dc, (q15_t)0xc60a, + (q15_t)0x24d0, (q15_t)0xc610, (q15_t)0x24c5, (q15_t)0xc615, (q15_t)0x24ba, (q15_t)0xc61a, (q15_t)0x24ae, (q15_t)0xc620, + (q15_t)0x24a3, (q15_t)0xc625, (q15_t)0x2498, (q15_t)0xc62a, (q15_t)0x248c, (q15_t)0xc630, (q15_t)0x2481, (q15_t)0xc635, + (q15_t)0x2476, (q15_t)0xc63b, (q15_t)0x246a, (q15_t)0xc640, (q15_t)0x245f, (q15_t)0xc645, (q15_t)0x2454, (q15_t)0xc64b, + (q15_t)0x2448, (q15_t)0xc650, (q15_t)0x243d, (q15_t)0xc656, (q15_t)0x2432, (q15_t)0xc65b, (q15_t)0x2426, (q15_t)0xc661, + (q15_t)0x241b, (q15_t)0xc666, (q15_t)0x2410, (q15_t)0xc66c, (q15_t)0x2404, (q15_t)0xc671, (q15_t)0x23f9, (q15_t)0xc677, + (q15_t)0x23ee, (q15_t)0xc67c, (q15_t)0x23e2, (q15_t)0xc682, (q15_t)0x23d7, (q15_t)0xc687, (q15_t)0x23cc, (q15_t)0xc68d, + (q15_t)0x23c1, (q15_t)0xc692, (q15_t)0x23b5, (q15_t)0xc698, (q15_t)0x23aa, (q15_t)0xc69d, (q15_t)0x239f, (q15_t)0xc6a3, + (q15_t)0x2394, (q15_t)0xc6a8, (q15_t)0x2388, (q15_t)0xc6ae, (q15_t)0x237d, (q15_t)0xc6b4, (q15_t)0x2372, (q15_t)0xc6b9, + (q15_t)0x2367, (q15_t)0xc6bf, (q15_t)0x235b, (q15_t)0xc6c5, (q15_t)0x2350, (q15_t)0xc6ca, (q15_t)0x2345, (q15_t)0xc6d0, + (q15_t)0x233a, (q15_t)0xc6d5, (q15_t)0x232e, (q15_t)0xc6db, (q15_t)0x2323, (q15_t)0xc6e1, (q15_t)0x2318, (q15_t)0xc6e6, + (q15_t)0x230d, (q15_t)0xc6ec, (q15_t)0x2301, (q15_t)0xc6f2, (q15_t)0x22f6, (q15_t)0xc6f7, (q15_t)0x22eb, (q15_t)0xc6fd, + (q15_t)0x22e0, (q15_t)0xc703, (q15_t)0x22d5, (q15_t)0xc709, (q15_t)0x22ca, (q15_t)0xc70e, (q15_t)0x22be, (q15_t)0xc714, + (q15_t)0x22b3, (q15_t)0xc71a, (q15_t)0x22a8, (q15_t)0xc720, (q15_t)0x229d, (q15_t)0xc725, (q15_t)0x2292, (q15_t)0xc72b, + (q15_t)0x2287, (q15_t)0xc731, (q15_t)0x227b, (q15_t)0xc737, (q15_t)0x2270, (q15_t)0xc73d, (q15_t)0x2265, (q15_t)0xc742, + (q15_t)0x225a, (q15_t)0xc748, (q15_t)0x224f, (q15_t)0xc74e, (q15_t)0x2244, (q15_t)0xc754, (q15_t)0x2239, (q15_t)0xc75a, + (q15_t)0x222d, (q15_t)0xc75f, (q15_t)0x2222, (q15_t)0xc765, (q15_t)0x2217, (q15_t)0xc76b, (q15_t)0x220c, (q15_t)0xc771, + (q15_t)0x2201, (q15_t)0xc777, (q15_t)0x21f6, (q15_t)0xc77d, (q15_t)0x21eb, (q15_t)0xc783, (q15_t)0x21e0, (q15_t)0xc789, + (q15_t)0x21d5, (q15_t)0xc78f, (q15_t)0x21ca, (q15_t)0xc795, (q15_t)0x21be, (q15_t)0xc79a, (q15_t)0x21b3, (q15_t)0xc7a0, + (q15_t)0x21a8, (q15_t)0xc7a6, (q15_t)0x219d, (q15_t)0xc7ac, (q15_t)0x2192, (q15_t)0xc7b2, (q15_t)0x2187, (q15_t)0xc7b8, + (q15_t)0x217c, (q15_t)0xc7be, (q15_t)0x2171, (q15_t)0xc7c4, (q15_t)0x2166, (q15_t)0xc7ca, (q15_t)0x215b, (q15_t)0xc7d0, + (q15_t)0x2150, (q15_t)0xc7d6, (q15_t)0x2145, (q15_t)0xc7dc, (q15_t)0x213a, (q15_t)0xc7e2, (q15_t)0x212f, (q15_t)0xc7e8, + (q15_t)0x2124, (q15_t)0xc7ee, (q15_t)0x2119, (q15_t)0xc7f5, (q15_t)0x210e, (q15_t)0xc7fb, (q15_t)0x2103, (q15_t)0xc801, + (q15_t)0x20f8, (q15_t)0xc807, (q15_t)0x20ed, (q15_t)0xc80d, (q15_t)0x20e2, (q15_t)0xc813, (q15_t)0x20d7, (q15_t)0xc819, + (q15_t)0x20cc, (q15_t)0xc81f, (q15_t)0x20c1, (q15_t)0xc825, (q15_t)0x20b6, (q15_t)0xc82b, (q15_t)0x20ab, (q15_t)0xc832, + (q15_t)0x20a0, (q15_t)0xc838, (q15_t)0x2095, (q15_t)0xc83e, (q15_t)0x208a, (q15_t)0xc844, (q15_t)0x207f, (q15_t)0xc84a, + (q15_t)0x2074, (q15_t)0xc850, (q15_t)0x2069, (q15_t)0xc857, (q15_t)0x205e, (q15_t)0xc85d, (q15_t)0x2054, (q15_t)0xc863, + (q15_t)0x2049, (q15_t)0xc869, (q15_t)0x203e, (q15_t)0xc870, (q15_t)0x2033, (q15_t)0xc876, (q15_t)0x2028, (q15_t)0xc87c, + (q15_t)0x201d, (q15_t)0xc882, (q15_t)0x2012, (q15_t)0xc889, (q15_t)0x2007, (q15_t)0xc88f, (q15_t)0x1ffc, (q15_t)0xc895, + (q15_t)0x1ff1, (q15_t)0xc89b, (q15_t)0x1fe7, (q15_t)0xc8a2, (q15_t)0x1fdc, (q15_t)0xc8a8, (q15_t)0x1fd1, (q15_t)0xc8ae, + (q15_t)0x1fc6, (q15_t)0xc8b5, (q15_t)0x1fbb, (q15_t)0xc8bb, (q15_t)0x1fb0, (q15_t)0xc8c1, (q15_t)0x1fa5, (q15_t)0xc8c8, + (q15_t)0x1f9b, (q15_t)0xc8ce, (q15_t)0x1f90, (q15_t)0xc8d4, (q15_t)0x1f85, (q15_t)0xc8db, (q15_t)0x1f7a, (q15_t)0xc8e1, + (q15_t)0x1f6f, (q15_t)0xc8e8, (q15_t)0x1f65, (q15_t)0xc8ee, (q15_t)0x1f5a, (q15_t)0xc8f4, (q15_t)0x1f4f, (q15_t)0xc8fb, + (q15_t)0x1f44, (q15_t)0xc901, (q15_t)0x1f39, (q15_t)0xc908, (q15_t)0x1f2f, (q15_t)0xc90e, (q15_t)0x1f24, (q15_t)0xc915, + (q15_t)0x1f19, (q15_t)0xc91b, (q15_t)0x1f0e, (q15_t)0xc921, (q15_t)0x1f03, (q15_t)0xc928, (q15_t)0x1ef9, (q15_t)0xc92e, + (q15_t)0x1eee, (q15_t)0xc935, (q15_t)0x1ee3, (q15_t)0xc93b, (q15_t)0x1ed8, (q15_t)0xc942, (q15_t)0x1ece, (q15_t)0xc948, + (q15_t)0x1ec3, (q15_t)0xc94f, (q15_t)0x1eb8, (q15_t)0xc955, (q15_t)0x1ead, (q15_t)0xc95c, (q15_t)0x1ea3, (q15_t)0xc963, + (q15_t)0x1e98, (q15_t)0xc969, (q15_t)0x1e8d, (q15_t)0xc970, (q15_t)0x1e83, (q15_t)0xc976, (q15_t)0x1e78, (q15_t)0xc97d, + (q15_t)0x1e6d, (q15_t)0xc983, (q15_t)0x1e62, (q15_t)0xc98a, (q15_t)0x1e58, (q15_t)0xc991, (q15_t)0x1e4d, (q15_t)0xc997, + (q15_t)0x1e42, (q15_t)0xc99e, (q15_t)0x1e38, (q15_t)0xc9a4, (q15_t)0x1e2d, (q15_t)0xc9ab, (q15_t)0x1e22, (q15_t)0xc9b2, + (q15_t)0x1e18, (q15_t)0xc9b8, (q15_t)0x1e0d, (q15_t)0xc9bf, (q15_t)0x1e02, (q15_t)0xc9c6, (q15_t)0x1df8, (q15_t)0xc9cc, + (q15_t)0x1ded, (q15_t)0xc9d3, (q15_t)0x1de2, (q15_t)0xc9da, (q15_t)0x1dd8, (q15_t)0xc9e0, (q15_t)0x1dcd, (q15_t)0xc9e7, + (q15_t)0x1dc3, (q15_t)0xc9ee, (q15_t)0x1db8, (q15_t)0xc9f5, (q15_t)0x1dad, (q15_t)0xc9fb, (q15_t)0x1da3, (q15_t)0xca02, + (q15_t)0x1d98, (q15_t)0xca09, (q15_t)0x1d8e, (q15_t)0xca10, (q15_t)0x1d83, (q15_t)0xca16, (q15_t)0x1d78, (q15_t)0xca1d, + (q15_t)0x1d6e, (q15_t)0xca24, (q15_t)0x1d63, (q15_t)0xca2b, (q15_t)0x1d59, (q15_t)0xca32, (q15_t)0x1d4e, (q15_t)0xca38, + (q15_t)0x1d44, (q15_t)0xca3f, (q15_t)0x1d39, (q15_t)0xca46, (q15_t)0x1d2e, (q15_t)0xca4d, (q15_t)0x1d24, (q15_t)0xca54, + (q15_t)0x1d19, (q15_t)0xca5b, (q15_t)0x1d0f, (q15_t)0xca61, (q15_t)0x1d04, (q15_t)0xca68, (q15_t)0x1cfa, (q15_t)0xca6f, + (q15_t)0x1cef, (q15_t)0xca76, (q15_t)0x1ce5, (q15_t)0xca7d, (q15_t)0x1cda, (q15_t)0xca84, (q15_t)0x1cd0, (q15_t)0xca8b, + (q15_t)0x1cc5, (q15_t)0xca92, (q15_t)0x1cbb, (q15_t)0xca99, (q15_t)0x1cb0, (q15_t)0xca9f, (q15_t)0x1ca6, (q15_t)0xcaa6, + (q15_t)0x1c9b, (q15_t)0xcaad, (q15_t)0x1c91, (q15_t)0xcab4, (q15_t)0x1c86, (q15_t)0xcabb, (q15_t)0x1c7c, (q15_t)0xcac2, + (q15_t)0x1c72, (q15_t)0xcac9, (q15_t)0x1c67, (q15_t)0xcad0, (q15_t)0x1c5d, (q15_t)0xcad7, (q15_t)0x1c52, (q15_t)0xcade, + (q15_t)0x1c48, (q15_t)0xcae5, (q15_t)0x1c3d, (q15_t)0xcaec, (q15_t)0x1c33, (q15_t)0xcaf3, (q15_t)0x1c29, (q15_t)0xcafa, + (q15_t)0x1c1e, (q15_t)0xcb01, (q15_t)0x1c14, (q15_t)0xcb08, (q15_t)0x1c09, (q15_t)0xcb0f, (q15_t)0x1bff, (q15_t)0xcb16, + (q15_t)0x1bf5, (q15_t)0xcb1e, (q15_t)0x1bea, (q15_t)0xcb25, (q15_t)0x1be0, (q15_t)0xcb2c, (q15_t)0x1bd5, (q15_t)0xcb33, + (q15_t)0x1bcb, (q15_t)0xcb3a, (q15_t)0x1bc1, (q15_t)0xcb41, (q15_t)0x1bb6, (q15_t)0xcb48, (q15_t)0x1bac, (q15_t)0xcb4f, + (q15_t)0x1ba2, (q15_t)0xcb56, (q15_t)0x1b97, (q15_t)0xcb5e, (q15_t)0x1b8d, (q15_t)0xcb65, (q15_t)0x1b83, (q15_t)0xcb6c, + (q15_t)0x1b78, (q15_t)0xcb73, (q15_t)0x1b6e, (q15_t)0xcb7a, (q15_t)0x1b64, (q15_t)0xcb81, (q15_t)0x1b59, (q15_t)0xcb89, + (q15_t)0x1b4f, (q15_t)0xcb90, (q15_t)0x1b45, (q15_t)0xcb97, (q15_t)0x1b3b, (q15_t)0xcb9e, (q15_t)0x1b30, (q15_t)0xcba5, + (q15_t)0x1b26, (q15_t)0xcbad, (q15_t)0x1b1c, (q15_t)0xcbb4, (q15_t)0x1b11, (q15_t)0xcbbb, (q15_t)0x1b07, (q15_t)0xcbc2, + (q15_t)0x1afd, (q15_t)0xcbca, (q15_t)0x1af3, (q15_t)0xcbd1, (q15_t)0x1ae8, (q15_t)0xcbd8, (q15_t)0x1ade, (q15_t)0xcbe0, + (q15_t)0x1ad4, (q15_t)0xcbe7, (q15_t)0x1aca, (q15_t)0xcbee, (q15_t)0x1abf, (q15_t)0xcbf5, (q15_t)0x1ab5, (q15_t)0xcbfd, + (q15_t)0x1aab, (q15_t)0xcc04, (q15_t)0x1aa1, (q15_t)0xcc0b, (q15_t)0x1a97, (q15_t)0xcc13, (q15_t)0x1a8c, (q15_t)0xcc1a, + (q15_t)0x1a82, (q15_t)0xcc21, (q15_t)0x1a78, (q15_t)0xcc29, (q15_t)0x1a6e, (q15_t)0xcc30, (q15_t)0x1a64, (q15_t)0xcc38, + (q15_t)0x1a5a, (q15_t)0xcc3f, (q15_t)0x1a4f, (q15_t)0xcc46, (q15_t)0x1a45, (q15_t)0xcc4e, (q15_t)0x1a3b, (q15_t)0xcc55, + (q15_t)0x1a31, (q15_t)0xcc5d, (q15_t)0x1a27, (q15_t)0xcc64, (q15_t)0x1a1d, (q15_t)0xcc6b, (q15_t)0x1a13, (q15_t)0xcc73, + (q15_t)0x1a08, (q15_t)0xcc7a, (q15_t)0x19fe, (q15_t)0xcc82, (q15_t)0x19f4, (q15_t)0xcc89, (q15_t)0x19ea, (q15_t)0xcc91, + (q15_t)0x19e0, (q15_t)0xcc98, (q15_t)0x19d6, (q15_t)0xcca0, (q15_t)0x19cc, (q15_t)0xcca7, (q15_t)0x19c2, (q15_t)0xccaf, + (q15_t)0x19b8, (q15_t)0xccb6, (q15_t)0x19ae, (q15_t)0xccbe, (q15_t)0x19a4, (q15_t)0xccc5, (q15_t)0x199a, (q15_t)0xcccd, + (q15_t)0x198f, (q15_t)0xccd4, (q15_t)0x1985, (q15_t)0xccdc, (q15_t)0x197b, (q15_t)0xcce3, (q15_t)0x1971, (q15_t)0xcceb, + (q15_t)0x1967, (q15_t)0xccf3, (q15_t)0x195d, (q15_t)0xccfa, (q15_t)0x1953, (q15_t)0xcd02, (q15_t)0x1949, (q15_t)0xcd09, + (q15_t)0x193f, (q15_t)0xcd11, (q15_t)0x1935, (q15_t)0xcd19, (q15_t)0x192b, (q15_t)0xcd20, (q15_t)0x1921, (q15_t)0xcd28, + (q15_t)0x1917, (q15_t)0xcd30, (q15_t)0x190d, (q15_t)0xcd37, (q15_t)0x1903, (q15_t)0xcd3f, (q15_t)0x18f9, (q15_t)0xcd46, + (q15_t)0x18ef, (q15_t)0xcd4e, (q15_t)0x18e6, (q15_t)0xcd56, (q15_t)0x18dc, (q15_t)0xcd5d, (q15_t)0x18d2, (q15_t)0xcd65, + (q15_t)0x18c8, (q15_t)0xcd6d, (q15_t)0x18be, (q15_t)0xcd75, (q15_t)0x18b4, (q15_t)0xcd7c, (q15_t)0x18aa, (q15_t)0xcd84, + (q15_t)0x18a0, (q15_t)0xcd8c, (q15_t)0x1896, (q15_t)0xcd93, (q15_t)0x188c, (q15_t)0xcd9b, (q15_t)0x1882, (q15_t)0xcda3, + (q15_t)0x1878, (q15_t)0xcdab, (q15_t)0x186f, (q15_t)0xcdb2, (q15_t)0x1865, (q15_t)0xcdba, (q15_t)0x185b, (q15_t)0xcdc2, + (q15_t)0x1851, (q15_t)0xcdca, (q15_t)0x1847, (q15_t)0xcdd2, (q15_t)0x183d, (q15_t)0xcdd9, (q15_t)0x1833, (q15_t)0xcde1, + (q15_t)0x182a, (q15_t)0xcde9, (q15_t)0x1820, (q15_t)0xcdf1, (q15_t)0x1816, (q15_t)0xcdf9, (q15_t)0x180c, (q15_t)0xce01, + (q15_t)0x1802, (q15_t)0xce08, (q15_t)0x17f8, (q15_t)0xce10, (q15_t)0x17ef, (q15_t)0xce18, (q15_t)0x17e5, (q15_t)0xce20, + (q15_t)0x17db, (q15_t)0xce28, (q15_t)0x17d1, (q15_t)0xce30, (q15_t)0x17c8, (q15_t)0xce38, (q15_t)0x17be, (q15_t)0xce40, + (q15_t)0x17b4, (q15_t)0xce47, (q15_t)0x17aa, (q15_t)0xce4f, (q15_t)0x17a0, (q15_t)0xce57, (q15_t)0x1797, (q15_t)0xce5f, + (q15_t)0x178d, (q15_t)0xce67, (q15_t)0x1783, (q15_t)0xce6f, (q15_t)0x177a, (q15_t)0xce77, (q15_t)0x1770, (q15_t)0xce7f, + (q15_t)0x1766, (q15_t)0xce87, (q15_t)0x175c, (q15_t)0xce8f, (q15_t)0x1753, (q15_t)0xce97, (q15_t)0x1749, (q15_t)0xce9f, + (q15_t)0x173f, (q15_t)0xcea7, (q15_t)0x1736, (q15_t)0xceaf, (q15_t)0x172c, (q15_t)0xceb7, (q15_t)0x1722, (q15_t)0xcebf, + (q15_t)0x1719, (q15_t)0xcec7, (q15_t)0x170f, (q15_t)0xcecf, (q15_t)0x1705, (q15_t)0xced7, (q15_t)0x16fc, (q15_t)0xcedf, + (q15_t)0x16f2, (q15_t)0xcee7, (q15_t)0x16e8, (q15_t)0xceef, (q15_t)0x16df, (q15_t)0xcef7, (q15_t)0x16d5, (q15_t)0xceff, + (q15_t)0x16cb, (q15_t)0xcf07, (q15_t)0x16c2, (q15_t)0xcf10, (q15_t)0x16b8, (q15_t)0xcf18, (q15_t)0x16af, (q15_t)0xcf20, + (q15_t)0x16a5, (q15_t)0xcf28, (q15_t)0x169b, (q15_t)0xcf30, (q15_t)0x1692, (q15_t)0xcf38, (q15_t)0x1688, (q15_t)0xcf40, + (q15_t)0x167f, (q15_t)0xcf48, (q15_t)0x1675, (q15_t)0xcf51, (q15_t)0x166c, (q15_t)0xcf59, (q15_t)0x1662, (q15_t)0xcf61, + (q15_t)0x1659, (q15_t)0xcf69, (q15_t)0x164f, (q15_t)0xcf71, (q15_t)0x1645, (q15_t)0xcf79, (q15_t)0x163c, (q15_t)0xcf82, + (q15_t)0x1632, (q15_t)0xcf8a, (q15_t)0x1629, (q15_t)0xcf92, (q15_t)0x161f, (q15_t)0xcf9a, (q15_t)0x1616, (q15_t)0xcfa3, + (q15_t)0x160c, (q15_t)0xcfab, (q15_t)0x1603, (q15_t)0xcfb3, (q15_t)0x15f9, (q15_t)0xcfbb, (q15_t)0x15f0, (q15_t)0xcfc4, + (q15_t)0x15e6, (q15_t)0xcfcc, (q15_t)0x15dd, (q15_t)0xcfd4, (q15_t)0x15d4, (q15_t)0xcfdc, (q15_t)0x15ca, (q15_t)0xcfe5, + (q15_t)0x15c1, (q15_t)0xcfed, (q15_t)0x15b7, (q15_t)0xcff5, (q15_t)0x15ae, (q15_t)0xcffe, (q15_t)0x15a4, (q15_t)0xd006, + (q15_t)0x159b, (q15_t)0xd00e, (q15_t)0x1592, (q15_t)0xd016, (q15_t)0x1588, (q15_t)0xd01f, (q15_t)0x157f, (q15_t)0xd027, + (q15_t)0x1575, (q15_t)0xd030, (q15_t)0x156c, (q15_t)0xd038, (q15_t)0x1563, (q15_t)0xd040, (q15_t)0x1559, (q15_t)0xd049, + (q15_t)0x1550, (q15_t)0xd051, (q15_t)0x1547, (q15_t)0xd059, (q15_t)0x153d, (q15_t)0xd062, (q15_t)0x1534, (q15_t)0xd06a, + (q15_t)0x152a, (q15_t)0xd073, (q15_t)0x1521, (q15_t)0xd07b, (q15_t)0x1518, (q15_t)0xd083, (q15_t)0x150e, (q15_t)0xd08c, + (q15_t)0x1505, (q15_t)0xd094, (q15_t)0x14fc, (q15_t)0xd09d, (q15_t)0x14f3, (q15_t)0xd0a5, (q15_t)0x14e9, (q15_t)0xd0ae, + (q15_t)0x14e0, (q15_t)0xd0b6, (q15_t)0x14d7, (q15_t)0xd0bf, (q15_t)0x14cd, (q15_t)0xd0c7, (q15_t)0x14c4, (q15_t)0xd0d0, + (q15_t)0x14bb, (q15_t)0xd0d8, (q15_t)0x14b2, (q15_t)0xd0e0, (q15_t)0x14a8, (q15_t)0xd0e9, (q15_t)0x149f, (q15_t)0xd0f2, + (q15_t)0x1496, (q15_t)0xd0fa, (q15_t)0x148d, (q15_t)0xd103, (q15_t)0x1483, (q15_t)0xd10b, (q15_t)0x147a, (q15_t)0xd114, + (q15_t)0x1471, (q15_t)0xd11c, (q15_t)0x1468, (q15_t)0xd125, (q15_t)0x145f, (q15_t)0xd12d, (q15_t)0x1455, (q15_t)0xd136, + (q15_t)0x144c, (q15_t)0xd13e, (q15_t)0x1443, (q15_t)0xd147, (q15_t)0x143a, (q15_t)0xd150, (q15_t)0x1431, (q15_t)0xd158, + (q15_t)0x1428, (q15_t)0xd161, (q15_t)0x141e, (q15_t)0xd169, (q15_t)0x1415, (q15_t)0xd172, (q15_t)0x140c, (q15_t)0xd17b, + (q15_t)0x1403, (q15_t)0xd183, (q15_t)0x13fa, (q15_t)0xd18c, (q15_t)0x13f1, (q15_t)0xd195, (q15_t)0x13e8, (q15_t)0xd19d, + (q15_t)0x13df, (q15_t)0xd1a6, (q15_t)0x13d5, (q15_t)0xd1af, (q15_t)0x13cc, (q15_t)0xd1b7, (q15_t)0x13c3, (q15_t)0xd1c0, + (q15_t)0x13ba, (q15_t)0xd1c9, (q15_t)0x13b1, (q15_t)0xd1d1, (q15_t)0x13a8, (q15_t)0xd1da, (q15_t)0x139f, (q15_t)0xd1e3, + (q15_t)0x1396, (q15_t)0xd1eb, (q15_t)0x138d, (q15_t)0xd1f4, (q15_t)0x1384, (q15_t)0xd1fd, (q15_t)0x137b, (q15_t)0xd206, + (q15_t)0x1372, (q15_t)0xd20e, (q15_t)0x1369, (q15_t)0xd217, (q15_t)0x1360, (q15_t)0xd220, (q15_t)0x1357, (q15_t)0xd229, + (q15_t)0x134e, (q15_t)0xd231, (q15_t)0x1345, (q15_t)0xd23a, (q15_t)0x133c, (q15_t)0xd243, (q15_t)0x1333, (q15_t)0xd24c, + (q15_t)0x132a, (q15_t)0xd255, (q15_t)0x1321, (q15_t)0xd25d, (q15_t)0x1318, (q15_t)0xd266, (q15_t)0x130f, (q15_t)0xd26f, + (q15_t)0x1306, (q15_t)0xd278, (q15_t)0x12fd, (q15_t)0xd281, (q15_t)0x12f4, (q15_t)0xd28a, (q15_t)0x12eb, (q15_t)0xd292, + (q15_t)0x12e2, (q15_t)0xd29b, (q15_t)0x12d9, (q15_t)0xd2a4, (q15_t)0x12d1, (q15_t)0xd2ad, (q15_t)0x12c8, (q15_t)0xd2b6, + (q15_t)0x12bf, (q15_t)0xd2bf, (q15_t)0x12b6, (q15_t)0xd2c8, (q15_t)0x12ad, (q15_t)0xd2d1, (q15_t)0x12a4, (q15_t)0xd2d9, + (q15_t)0x129b, (q15_t)0xd2e2, (q15_t)0x1292, (q15_t)0xd2eb, (q15_t)0x128a, (q15_t)0xd2f4, (q15_t)0x1281, (q15_t)0xd2fd, + (q15_t)0x1278, (q15_t)0xd306, (q15_t)0x126f, (q15_t)0xd30f, (q15_t)0x1266, (q15_t)0xd318, (q15_t)0x125d, (q15_t)0xd321, + (q15_t)0x1255, (q15_t)0xd32a, (q15_t)0x124c, (q15_t)0xd333, (q15_t)0x1243, (q15_t)0xd33c, (q15_t)0x123a, (q15_t)0xd345, + (q15_t)0x1231, (q15_t)0xd34e, (q15_t)0x1229, (q15_t)0xd357, (q15_t)0x1220, (q15_t)0xd360, (q15_t)0x1217, (q15_t)0xd369, + (q15_t)0x120e, (q15_t)0xd372, (q15_t)0x1206, (q15_t)0xd37b, (q15_t)0x11fd, (q15_t)0xd384, (q15_t)0x11f4, (q15_t)0xd38d, + (q15_t)0x11eb, (q15_t)0xd396, (q15_t)0x11e3, (q15_t)0xd39f, (q15_t)0x11da, (q15_t)0xd3a8, (q15_t)0x11d1, (q15_t)0xd3b1, + (q15_t)0x11c9, (q15_t)0xd3ba, (q15_t)0x11c0, (q15_t)0xd3c3, (q15_t)0x11b7, (q15_t)0xd3cc, (q15_t)0x11af, (q15_t)0xd3d5, + (q15_t)0x11a6, (q15_t)0xd3df, (q15_t)0x119d, (q15_t)0xd3e8, (q15_t)0x1195, (q15_t)0xd3f1, (q15_t)0x118c, (q15_t)0xd3fa, + (q15_t)0x1183, (q15_t)0xd403, (q15_t)0x117b, (q15_t)0xd40c, (q15_t)0x1172, (q15_t)0xd415, (q15_t)0x1169, (q15_t)0xd41e, + (q15_t)0x1161, (q15_t)0xd428, (q15_t)0x1158, (q15_t)0xd431, (q15_t)0x1150, (q15_t)0xd43a, (q15_t)0x1147, (q15_t)0xd443, + (q15_t)0x113e, (q15_t)0xd44c, (q15_t)0x1136, (q15_t)0xd455, (q15_t)0x112d, (q15_t)0xd45f, (q15_t)0x1125, (q15_t)0xd468, + (q15_t)0x111c, (q15_t)0xd471, (q15_t)0x1114, (q15_t)0xd47a, (q15_t)0x110b, (q15_t)0xd483, (q15_t)0x1103, (q15_t)0xd48d, + (q15_t)0x10fa, (q15_t)0xd496, (q15_t)0x10f2, (q15_t)0xd49f, (q15_t)0x10e9, (q15_t)0xd4a8, (q15_t)0x10e0, (q15_t)0xd4b2, + (q15_t)0x10d8, (q15_t)0xd4bb, (q15_t)0x10d0, (q15_t)0xd4c4, (q15_t)0x10c7, (q15_t)0xd4cd, (q15_t)0x10bf, (q15_t)0xd4d7, + (q15_t)0x10b6, (q15_t)0xd4e0, (q15_t)0x10ae, (q15_t)0xd4e9, (q15_t)0x10a5, (q15_t)0xd4f3, (q15_t)0x109d, (q15_t)0xd4fc, + (q15_t)0x1094, (q15_t)0xd505, (q15_t)0x108c, (q15_t)0xd50e, (q15_t)0x1083, (q15_t)0xd518, (q15_t)0x107b, (q15_t)0xd521, + (q15_t)0x1073, (q15_t)0xd52a, (q15_t)0x106a, (q15_t)0xd534, (q15_t)0x1062, (q15_t)0xd53d, (q15_t)0x1059, (q15_t)0xd547, + (q15_t)0x1051, (q15_t)0xd550, (q15_t)0x1049, (q15_t)0xd559, (q15_t)0x1040, (q15_t)0xd563, (q15_t)0x1038, (q15_t)0xd56c, + (q15_t)0x1030, (q15_t)0xd575, (q15_t)0x1027, (q15_t)0xd57f, (q15_t)0x101f, (q15_t)0xd588, (q15_t)0x1016, (q15_t)0xd592, + (q15_t)0x100e, (q15_t)0xd59b, (q15_t)0x1006, (q15_t)0xd5a4, (q15_t)0xffe, (q15_t)0xd5ae, (q15_t)0xff5, (q15_t)0xd5b7, + (q15_t)0xfed, (q15_t)0xd5c1, (q15_t)0xfe5, (q15_t)0xd5ca, (q15_t)0xfdc, (q15_t)0xd5d4, (q15_t)0xfd4, (q15_t)0xd5dd, + (q15_t)0xfcc, (q15_t)0xd5e6, (q15_t)0xfc4, (q15_t)0xd5f0, (q15_t)0xfbb, (q15_t)0xd5f9, (q15_t)0xfb3, (q15_t)0xd603, + (q15_t)0xfab, (q15_t)0xd60c, (q15_t)0xfa3, (q15_t)0xd616, (q15_t)0xf9a, (q15_t)0xd61f, (q15_t)0xf92, (q15_t)0xd629, + (q15_t)0xf8a, (q15_t)0xd632, (q15_t)0xf82, (q15_t)0xd63c, (q15_t)0xf79, (q15_t)0xd645, (q15_t)0xf71, (q15_t)0xd64f, + (q15_t)0xf69, (q15_t)0xd659, (q15_t)0xf61, (q15_t)0xd662, (q15_t)0xf59, (q15_t)0xd66c, (q15_t)0xf51, (q15_t)0xd675, + (q15_t)0xf48, (q15_t)0xd67f, (q15_t)0xf40, (q15_t)0xd688, (q15_t)0xf38, (q15_t)0xd692, (q15_t)0xf30, (q15_t)0xd69b, + (q15_t)0xf28, (q15_t)0xd6a5, (q15_t)0xf20, (q15_t)0xd6af, (q15_t)0xf18, (q15_t)0xd6b8, (q15_t)0xf10, (q15_t)0xd6c2, + (q15_t)0xf07, (q15_t)0xd6cb, (q15_t)0xeff, (q15_t)0xd6d5, (q15_t)0xef7, (q15_t)0xd6df, (q15_t)0xeef, (q15_t)0xd6e8, + (q15_t)0xee7, (q15_t)0xd6f2, (q15_t)0xedf, (q15_t)0xd6fc, (q15_t)0xed7, (q15_t)0xd705, (q15_t)0xecf, (q15_t)0xd70f, + (q15_t)0xec7, (q15_t)0xd719, (q15_t)0xebf, (q15_t)0xd722, (q15_t)0xeb7, (q15_t)0xd72c, (q15_t)0xeaf, (q15_t)0xd736, + (q15_t)0xea7, (q15_t)0xd73f, (q15_t)0xe9f, (q15_t)0xd749, (q15_t)0xe97, (q15_t)0xd753, (q15_t)0xe8f, (q15_t)0xd75c, + (q15_t)0xe87, (q15_t)0xd766, (q15_t)0xe7f, (q15_t)0xd770, (q15_t)0xe77, (q15_t)0xd77a, (q15_t)0xe6f, (q15_t)0xd783, + (q15_t)0xe67, (q15_t)0xd78d, (q15_t)0xe5f, (q15_t)0xd797, (q15_t)0xe57, (q15_t)0xd7a0, (q15_t)0xe4f, (q15_t)0xd7aa, + (q15_t)0xe47, (q15_t)0xd7b4, (q15_t)0xe40, (q15_t)0xd7be, (q15_t)0xe38, (q15_t)0xd7c8, (q15_t)0xe30, (q15_t)0xd7d1, + (q15_t)0xe28, (q15_t)0xd7db, (q15_t)0xe20, (q15_t)0xd7e5, (q15_t)0xe18, (q15_t)0xd7ef, (q15_t)0xe10, (q15_t)0xd7f8, + (q15_t)0xe08, (q15_t)0xd802, (q15_t)0xe01, (q15_t)0xd80c, (q15_t)0xdf9, (q15_t)0xd816, (q15_t)0xdf1, (q15_t)0xd820, + (q15_t)0xde9, (q15_t)0xd82a, (q15_t)0xde1, (q15_t)0xd833, (q15_t)0xdd9, (q15_t)0xd83d, (q15_t)0xdd2, (q15_t)0xd847, + (q15_t)0xdca, (q15_t)0xd851, (q15_t)0xdc2, (q15_t)0xd85b, (q15_t)0xdba, (q15_t)0xd865, (q15_t)0xdb2, (q15_t)0xd86f, + (q15_t)0xdab, (q15_t)0xd878, (q15_t)0xda3, (q15_t)0xd882, (q15_t)0xd9b, (q15_t)0xd88c, (q15_t)0xd93, (q15_t)0xd896, + (q15_t)0xd8c, (q15_t)0xd8a0, (q15_t)0xd84, (q15_t)0xd8aa, (q15_t)0xd7c, (q15_t)0xd8b4, (q15_t)0xd75, (q15_t)0xd8be, + (q15_t)0xd6d, (q15_t)0xd8c8, (q15_t)0xd65, (q15_t)0xd8d2, (q15_t)0xd5d, (q15_t)0xd8dc, (q15_t)0xd56, (q15_t)0xd8e6, + (q15_t)0xd4e, (q15_t)0xd8ef, (q15_t)0xd46, (q15_t)0xd8f9, (q15_t)0xd3f, (q15_t)0xd903, (q15_t)0xd37, (q15_t)0xd90d, + (q15_t)0xd30, (q15_t)0xd917, (q15_t)0xd28, (q15_t)0xd921, (q15_t)0xd20, (q15_t)0xd92b, (q15_t)0xd19, (q15_t)0xd935, + (q15_t)0xd11, (q15_t)0xd93f, (q15_t)0xd09, (q15_t)0xd949, (q15_t)0xd02, (q15_t)0xd953, (q15_t)0xcfa, (q15_t)0xd95d, + (q15_t)0xcf3, (q15_t)0xd967, (q15_t)0xceb, (q15_t)0xd971, (q15_t)0xce3, (q15_t)0xd97b, (q15_t)0xcdc, (q15_t)0xd985, + (q15_t)0xcd4, (q15_t)0xd98f, (q15_t)0xccd, (q15_t)0xd99a, (q15_t)0xcc5, (q15_t)0xd9a4, (q15_t)0xcbe, (q15_t)0xd9ae, + (q15_t)0xcb6, (q15_t)0xd9b8, (q15_t)0xcaf, (q15_t)0xd9c2, (q15_t)0xca7, (q15_t)0xd9cc, (q15_t)0xca0, (q15_t)0xd9d6, + (q15_t)0xc98, (q15_t)0xd9e0, (q15_t)0xc91, (q15_t)0xd9ea, (q15_t)0xc89, (q15_t)0xd9f4, (q15_t)0xc82, (q15_t)0xd9fe, + (q15_t)0xc7a, (q15_t)0xda08, (q15_t)0xc73, (q15_t)0xda13, (q15_t)0xc6b, (q15_t)0xda1d, (q15_t)0xc64, (q15_t)0xda27, + (q15_t)0xc5d, (q15_t)0xda31, (q15_t)0xc55, (q15_t)0xda3b, (q15_t)0xc4e, (q15_t)0xda45, (q15_t)0xc46, (q15_t)0xda4f, + (q15_t)0xc3f, (q15_t)0xda5a, (q15_t)0xc38, (q15_t)0xda64, (q15_t)0xc30, (q15_t)0xda6e, (q15_t)0xc29, (q15_t)0xda78, + (q15_t)0xc21, (q15_t)0xda82, (q15_t)0xc1a, (q15_t)0xda8c, (q15_t)0xc13, (q15_t)0xda97, (q15_t)0xc0b, (q15_t)0xdaa1, + (q15_t)0xc04, (q15_t)0xdaab, (q15_t)0xbfd, (q15_t)0xdab5, (q15_t)0xbf5, (q15_t)0xdabf, (q15_t)0xbee, (q15_t)0xdaca, + (q15_t)0xbe7, (q15_t)0xdad4, (q15_t)0xbe0, (q15_t)0xdade, (q15_t)0xbd8, (q15_t)0xdae8, (q15_t)0xbd1, (q15_t)0xdaf3, + (q15_t)0xbca, (q15_t)0xdafd, (q15_t)0xbc2, (q15_t)0xdb07, (q15_t)0xbbb, (q15_t)0xdb11, (q15_t)0xbb4, (q15_t)0xdb1c, + (q15_t)0xbad, (q15_t)0xdb26, (q15_t)0xba5, (q15_t)0xdb30, (q15_t)0xb9e, (q15_t)0xdb3b, (q15_t)0xb97, (q15_t)0xdb45, + (q15_t)0xb90, (q15_t)0xdb4f, (q15_t)0xb89, (q15_t)0xdb59, (q15_t)0xb81, (q15_t)0xdb64, (q15_t)0xb7a, (q15_t)0xdb6e, + (q15_t)0xb73, (q15_t)0xdb78, (q15_t)0xb6c, (q15_t)0xdb83, (q15_t)0xb65, (q15_t)0xdb8d, (q15_t)0xb5e, (q15_t)0xdb97, + (q15_t)0xb56, (q15_t)0xdba2, (q15_t)0xb4f, (q15_t)0xdbac, (q15_t)0xb48, (q15_t)0xdbb6, (q15_t)0xb41, (q15_t)0xdbc1, + (q15_t)0xb3a, (q15_t)0xdbcb, (q15_t)0xb33, (q15_t)0xdbd5, (q15_t)0xb2c, (q15_t)0xdbe0, (q15_t)0xb25, (q15_t)0xdbea, + (q15_t)0xb1e, (q15_t)0xdbf5, (q15_t)0xb16, (q15_t)0xdbff, (q15_t)0xb0f, (q15_t)0xdc09, (q15_t)0xb08, (q15_t)0xdc14, + (q15_t)0xb01, (q15_t)0xdc1e, (q15_t)0xafa, (q15_t)0xdc29, (q15_t)0xaf3, (q15_t)0xdc33, (q15_t)0xaec, (q15_t)0xdc3d, + (q15_t)0xae5, (q15_t)0xdc48, (q15_t)0xade, (q15_t)0xdc52, (q15_t)0xad7, (q15_t)0xdc5d, (q15_t)0xad0, (q15_t)0xdc67, + (q15_t)0xac9, (q15_t)0xdc72, (q15_t)0xac2, (q15_t)0xdc7c, (q15_t)0xabb, (q15_t)0xdc86, (q15_t)0xab4, (q15_t)0xdc91, + (q15_t)0xaad, (q15_t)0xdc9b, (q15_t)0xaa6, (q15_t)0xdca6, (q15_t)0xa9f, (q15_t)0xdcb0, (q15_t)0xa99, (q15_t)0xdcbb, + (q15_t)0xa92, (q15_t)0xdcc5, (q15_t)0xa8b, (q15_t)0xdcd0, (q15_t)0xa84, (q15_t)0xdcda, (q15_t)0xa7d, (q15_t)0xdce5, + (q15_t)0xa76, (q15_t)0xdcef, (q15_t)0xa6f, (q15_t)0xdcfa, (q15_t)0xa68, (q15_t)0xdd04, (q15_t)0xa61, (q15_t)0xdd0f, + (q15_t)0xa5b, (q15_t)0xdd19, (q15_t)0xa54, (q15_t)0xdd24, (q15_t)0xa4d, (q15_t)0xdd2e, (q15_t)0xa46, (q15_t)0xdd39, + (q15_t)0xa3f, (q15_t)0xdd44, (q15_t)0xa38, (q15_t)0xdd4e, (q15_t)0xa32, (q15_t)0xdd59, (q15_t)0xa2b, (q15_t)0xdd63, + (q15_t)0xa24, (q15_t)0xdd6e, (q15_t)0xa1d, (q15_t)0xdd78, (q15_t)0xa16, (q15_t)0xdd83, (q15_t)0xa10, (q15_t)0xdd8e, + (q15_t)0xa09, (q15_t)0xdd98, (q15_t)0xa02, (q15_t)0xdda3, (q15_t)0x9fb, (q15_t)0xddad, (q15_t)0x9f5, (q15_t)0xddb8, + (q15_t)0x9ee, (q15_t)0xddc3, (q15_t)0x9e7, (q15_t)0xddcd, (q15_t)0x9e0, (q15_t)0xddd8, (q15_t)0x9da, (q15_t)0xdde2, + (q15_t)0x9d3, (q15_t)0xdded, (q15_t)0x9cc, (q15_t)0xddf8, (q15_t)0x9c6, (q15_t)0xde02, (q15_t)0x9bf, (q15_t)0xde0d, + (q15_t)0x9b8, (q15_t)0xde18, (q15_t)0x9b2, (q15_t)0xde22, (q15_t)0x9ab, (q15_t)0xde2d, (q15_t)0x9a4, (q15_t)0xde38, + (q15_t)0x99e, (q15_t)0xde42, (q15_t)0x997, (q15_t)0xde4d, (q15_t)0x991, (q15_t)0xde58, (q15_t)0x98a, (q15_t)0xde62, + (q15_t)0x983, (q15_t)0xde6d, (q15_t)0x97d, (q15_t)0xde78, (q15_t)0x976, (q15_t)0xde83, (q15_t)0x970, (q15_t)0xde8d, + (q15_t)0x969, (q15_t)0xde98, (q15_t)0x963, (q15_t)0xdea3, (q15_t)0x95c, (q15_t)0xdead, (q15_t)0x955, (q15_t)0xdeb8, + (q15_t)0x94f, (q15_t)0xdec3, (q15_t)0x948, (q15_t)0xdece, (q15_t)0x942, (q15_t)0xded8, (q15_t)0x93b, (q15_t)0xdee3, + (q15_t)0x935, (q15_t)0xdeee, (q15_t)0x92e, (q15_t)0xdef9, (q15_t)0x928, (q15_t)0xdf03, (q15_t)0x921, (q15_t)0xdf0e, + (q15_t)0x91b, (q15_t)0xdf19, (q15_t)0x915, (q15_t)0xdf24, (q15_t)0x90e, (q15_t)0xdf2f, (q15_t)0x908, (q15_t)0xdf39, + (q15_t)0x901, (q15_t)0xdf44, (q15_t)0x8fb, (q15_t)0xdf4f, (q15_t)0x8f4, (q15_t)0xdf5a, (q15_t)0x8ee, (q15_t)0xdf65, + (q15_t)0x8e8, (q15_t)0xdf6f, (q15_t)0x8e1, (q15_t)0xdf7a, (q15_t)0x8db, (q15_t)0xdf85, (q15_t)0x8d4, (q15_t)0xdf90, + (q15_t)0x8ce, (q15_t)0xdf9b, (q15_t)0x8c8, (q15_t)0xdfa5, (q15_t)0x8c1, (q15_t)0xdfb0, (q15_t)0x8bb, (q15_t)0xdfbb, + (q15_t)0x8b5, (q15_t)0xdfc6, (q15_t)0x8ae, (q15_t)0xdfd1, (q15_t)0x8a8, (q15_t)0xdfdc, (q15_t)0x8a2, (q15_t)0xdfe7, + (q15_t)0x89b, (q15_t)0xdff1, (q15_t)0x895, (q15_t)0xdffc, (q15_t)0x88f, (q15_t)0xe007, (q15_t)0x889, (q15_t)0xe012, + (q15_t)0x882, (q15_t)0xe01d, (q15_t)0x87c, (q15_t)0xe028, (q15_t)0x876, (q15_t)0xe033, (q15_t)0x870, (q15_t)0xe03e, + (q15_t)0x869, (q15_t)0xe049, (q15_t)0x863, (q15_t)0xe054, (q15_t)0x85d, (q15_t)0xe05e, (q15_t)0x857, (q15_t)0xe069, + (q15_t)0x850, (q15_t)0xe074, (q15_t)0x84a, (q15_t)0xe07f, (q15_t)0x844, (q15_t)0xe08a, (q15_t)0x83e, (q15_t)0xe095, + (q15_t)0x838, (q15_t)0xe0a0, (q15_t)0x832, (q15_t)0xe0ab, (q15_t)0x82b, (q15_t)0xe0b6, (q15_t)0x825, (q15_t)0xe0c1, + (q15_t)0x81f, (q15_t)0xe0cc, (q15_t)0x819, (q15_t)0xe0d7, (q15_t)0x813, (q15_t)0xe0e2, (q15_t)0x80d, (q15_t)0xe0ed, + (q15_t)0x807, (q15_t)0xe0f8, (q15_t)0x801, (q15_t)0xe103, (q15_t)0x7fb, (q15_t)0xe10e, (q15_t)0x7f5, (q15_t)0xe119, + (q15_t)0x7ee, (q15_t)0xe124, (q15_t)0x7e8, (q15_t)0xe12f, (q15_t)0x7e2, (q15_t)0xe13a, (q15_t)0x7dc, (q15_t)0xe145, + (q15_t)0x7d6, (q15_t)0xe150, (q15_t)0x7d0, (q15_t)0xe15b, (q15_t)0x7ca, (q15_t)0xe166, (q15_t)0x7c4, (q15_t)0xe171, + (q15_t)0x7be, (q15_t)0xe17c, (q15_t)0x7b8, (q15_t)0xe187, (q15_t)0x7b2, (q15_t)0xe192, (q15_t)0x7ac, (q15_t)0xe19d, + (q15_t)0x7a6, (q15_t)0xe1a8, (q15_t)0x7a0, (q15_t)0xe1b3, (q15_t)0x79a, (q15_t)0xe1be, (q15_t)0x795, (q15_t)0xe1ca, + (q15_t)0x78f, (q15_t)0xe1d5, (q15_t)0x789, (q15_t)0xe1e0, (q15_t)0x783, (q15_t)0xe1eb, (q15_t)0x77d, (q15_t)0xe1f6, + (q15_t)0x777, (q15_t)0xe201, (q15_t)0x771, (q15_t)0xe20c, (q15_t)0x76b, (q15_t)0xe217, (q15_t)0x765, (q15_t)0xe222, + (q15_t)0x75f, (q15_t)0xe22d, (q15_t)0x75a, (q15_t)0xe239, (q15_t)0x754, (q15_t)0xe244, (q15_t)0x74e, (q15_t)0xe24f, + (q15_t)0x748, (q15_t)0xe25a, (q15_t)0x742, (q15_t)0xe265, (q15_t)0x73d, (q15_t)0xe270, (q15_t)0x737, (q15_t)0xe27b, + (q15_t)0x731, (q15_t)0xe287, (q15_t)0x72b, (q15_t)0xe292, (q15_t)0x725, (q15_t)0xe29d, (q15_t)0x720, (q15_t)0xe2a8, + (q15_t)0x71a, (q15_t)0xe2b3, (q15_t)0x714, (q15_t)0xe2be, (q15_t)0x70e, (q15_t)0xe2ca, (q15_t)0x709, (q15_t)0xe2d5, + (q15_t)0x703, (q15_t)0xe2e0, (q15_t)0x6fd, (q15_t)0xe2eb, (q15_t)0x6f7, (q15_t)0xe2f6, (q15_t)0x6f2, (q15_t)0xe301, + (q15_t)0x6ec, (q15_t)0xe30d, (q15_t)0x6e6, (q15_t)0xe318, (q15_t)0x6e1, (q15_t)0xe323, (q15_t)0x6db, (q15_t)0xe32e, + (q15_t)0x6d5, (q15_t)0xe33a, (q15_t)0x6d0, (q15_t)0xe345, (q15_t)0x6ca, (q15_t)0xe350, (q15_t)0x6c5, (q15_t)0xe35b, + (q15_t)0x6bf, (q15_t)0xe367, (q15_t)0x6b9, (q15_t)0xe372, (q15_t)0x6b4, (q15_t)0xe37d, (q15_t)0x6ae, (q15_t)0xe388, + (q15_t)0x6a8, (q15_t)0xe394, (q15_t)0x6a3, (q15_t)0xe39f, (q15_t)0x69d, (q15_t)0xe3aa, (q15_t)0x698, (q15_t)0xe3b5, + (q15_t)0x692, (q15_t)0xe3c1, (q15_t)0x68d, (q15_t)0xe3cc, (q15_t)0x687, (q15_t)0xe3d7, (q15_t)0x682, (q15_t)0xe3e2, + (q15_t)0x67c, (q15_t)0xe3ee, (q15_t)0x677, (q15_t)0xe3f9, (q15_t)0x671, (q15_t)0xe404, (q15_t)0x66c, (q15_t)0xe410, + (q15_t)0x666, (q15_t)0xe41b, (q15_t)0x661, (q15_t)0xe426, (q15_t)0x65b, (q15_t)0xe432, (q15_t)0x656, (q15_t)0xe43d, + (q15_t)0x650, (q15_t)0xe448, (q15_t)0x64b, (q15_t)0xe454, (q15_t)0x645, (q15_t)0xe45f, (q15_t)0x640, (q15_t)0xe46a, + (q15_t)0x63b, (q15_t)0xe476, (q15_t)0x635, (q15_t)0xe481, (q15_t)0x630, (q15_t)0xe48c, (q15_t)0x62a, (q15_t)0xe498, + (q15_t)0x625, (q15_t)0xe4a3, (q15_t)0x620, (q15_t)0xe4ae, (q15_t)0x61a, (q15_t)0xe4ba, (q15_t)0x615, (q15_t)0xe4c5, + (q15_t)0x610, (q15_t)0xe4d0, (q15_t)0x60a, (q15_t)0xe4dc, (q15_t)0x605, (q15_t)0xe4e7, (q15_t)0x600, (q15_t)0xe4f3, + (q15_t)0x5fa, (q15_t)0xe4fe, (q15_t)0x5f5, (q15_t)0xe509, (q15_t)0x5f0, (q15_t)0xe515, (q15_t)0x5ea, (q15_t)0xe520, + (q15_t)0x5e5, (q15_t)0xe52c, (q15_t)0x5e0, (q15_t)0xe537, (q15_t)0x5db, (q15_t)0xe542, (q15_t)0x5d5, (q15_t)0xe54e, + (q15_t)0x5d0, (q15_t)0xe559, (q15_t)0x5cb, (q15_t)0xe565, (q15_t)0x5c6, (q15_t)0xe570, (q15_t)0x5c1, (q15_t)0xe57c, + (q15_t)0x5bb, (q15_t)0xe587, (q15_t)0x5b6, (q15_t)0xe592, (q15_t)0x5b1, (q15_t)0xe59e, (q15_t)0x5ac, (q15_t)0xe5a9, + (q15_t)0x5a7, (q15_t)0xe5b5, (q15_t)0x5a1, (q15_t)0xe5c0, (q15_t)0x59c, (q15_t)0xe5cc, (q15_t)0x597, (q15_t)0xe5d7, + (q15_t)0x592, (q15_t)0xe5e3, (q15_t)0x58d, (q15_t)0xe5ee, (q15_t)0x588, (q15_t)0xe5fa, (q15_t)0x583, (q15_t)0xe605, + (q15_t)0x57e, (q15_t)0xe611, (q15_t)0x578, (q15_t)0xe61c, (q15_t)0x573, (q15_t)0xe628, (q15_t)0x56e, (q15_t)0xe633, + (q15_t)0x569, (q15_t)0xe63f, (q15_t)0x564, (q15_t)0xe64a, (q15_t)0x55f, (q15_t)0xe656, (q15_t)0x55a, (q15_t)0xe661, + (q15_t)0x555, (q15_t)0xe66d, (q15_t)0x550, (q15_t)0xe678, (q15_t)0x54b, (q15_t)0xe684, (q15_t)0x546, (q15_t)0xe68f, + (q15_t)0x541, (q15_t)0xe69b, (q15_t)0x53c, (q15_t)0xe6a6, (q15_t)0x537, (q15_t)0xe6b2, (q15_t)0x532, (q15_t)0xe6bd, + (q15_t)0x52d, (q15_t)0xe6c9, (q15_t)0x528, (q15_t)0xe6d4, (q15_t)0x523, (q15_t)0xe6e0, (q15_t)0x51e, (q15_t)0xe6ec, + (q15_t)0x51a, (q15_t)0xe6f7, (q15_t)0x515, (q15_t)0xe703, (q15_t)0x510, (q15_t)0xe70e, (q15_t)0x50b, (q15_t)0xe71a, + (q15_t)0x506, (q15_t)0xe725, (q15_t)0x501, (q15_t)0xe731, (q15_t)0x4fc, (q15_t)0xe73d, (q15_t)0x4f7, (q15_t)0xe748, + (q15_t)0x4f2, (q15_t)0xe754, (q15_t)0x4ee, (q15_t)0xe75f, (q15_t)0x4e9, (q15_t)0xe76b, (q15_t)0x4e4, (q15_t)0xe777, + (q15_t)0x4df, (q15_t)0xe782, (q15_t)0x4da, (q15_t)0xe78e, (q15_t)0x4d6, (q15_t)0xe799, (q15_t)0x4d1, (q15_t)0xe7a5, + (q15_t)0x4cc, (q15_t)0xe7b1, (q15_t)0x4c7, (q15_t)0xe7bc, (q15_t)0x4c2, (q15_t)0xe7c8, (q15_t)0x4be, (q15_t)0xe7d3, + (q15_t)0x4b9, (q15_t)0xe7df, (q15_t)0x4b4, (q15_t)0xe7eb, (q15_t)0x4b0, (q15_t)0xe7f6, (q15_t)0x4ab, (q15_t)0xe802, + (q15_t)0x4a6, (q15_t)0xe80e, (q15_t)0x4a1, (q15_t)0xe819, (q15_t)0x49d, (q15_t)0xe825, (q15_t)0x498, (q15_t)0xe831, + (q15_t)0x493, (q15_t)0xe83c, (q15_t)0x48f, (q15_t)0xe848, (q15_t)0x48a, (q15_t)0xe854, (q15_t)0x485, (q15_t)0xe85f, + (q15_t)0x481, (q15_t)0xe86b, (q15_t)0x47c, (q15_t)0xe877, (q15_t)0x478, (q15_t)0xe882, (q15_t)0x473, (q15_t)0xe88e, + (q15_t)0x46e, (q15_t)0xe89a, (q15_t)0x46a, (q15_t)0xe8a5, (q15_t)0x465, (q15_t)0xe8b1, (q15_t)0x461, (q15_t)0xe8bd, + (q15_t)0x45c, (q15_t)0xe8c9, (q15_t)0x457, (q15_t)0xe8d4, (q15_t)0x453, (q15_t)0xe8e0, (q15_t)0x44e, (q15_t)0xe8ec, + (q15_t)0x44a, (q15_t)0xe8f7, (q15_t)0x445, (q15_t)0xe903, (q15_t)0x441, (q15_t)0xe90f, (q15_t)0x43c, (q15_t)0xe91b, + (q15_t)0x438, (q15_t)0xe926, (q15_t)0x433, (q15_t)0xe932, (q15_t)0x42f, (q15_t)0xe93e, (q15_t)0x42a, (q15_t)0xe94a, + (q15_t)0x426, (q15_t)0xe955, (q15_t)0x422, (q15_t)0xe961, (q15_t)0x41d, (q15_t)0xe96d, (q15_t)0x419, (q15_t)0xe979, + (q15_t)0x414, (q15_t)0xe984, (q15_t)0x410, (q15_t)0xe990, (q15_t)0x40b, (q15_t)0xe99c, (q15_t)0x407, (q15_t)0xe9a8, + (q15_t)0x403, (q15_t)0xe9b4, (q15_t)0x3fe, (q15_t)0xe9bf, (q15_t)0x3fa, (q15_t)0xe9cb, (q15_t)0x3f6, (q15_t)0xe9d7, + (q15_t)0x3f1, (q15_t)0xe9e3, (q15_t)0x3ed, (q15_t)0xe9ee, (q15_t)0x3e9, (q15_t)0xe9fa, (q15_t)0x3e4, (q15_t)0xea06, + (q15_t)0x3e0, (q15_t)0xea12, (q15_t)0x3dc, (q15_t)0xea1e, (q15_t)0x3d7, (q15_t)0xea29, (q15_t)0x3d3, (q15_t)0xea35, + (q15_t)0x3cf, (q15_t)0xea41, (q15_t)0x3ca, (q15_t)0xea4d, (q15_t)0x3c6, (q15_t)0xea59, (q15_t)0x3c2, (q15_t)0xea65, + (q15_t)0x3be, (q15_t)0xea70, (q15_t)0x3ba, (q15_t)0xea7c, (q15_t)0x3b5, (q15_t)0xea88, (q15_t)0x3b1, (q15_t)0xea94, + (q15_t)0x3ad, (q15_t)0xeaa0, (q15_t)0x3a9, (q15_t)0xeaac, (q15_t)0x3a5, (q15_t)0xeab7, (q15_t)0x3a0, (q15_t)0xeac3, + (q15_t)0x39c, (q15_t)0xeacf, (q15_t)0x398, (q15_t)0xeadb, (q15_t)0x394, (q15_t)0xeae7, (q15_t)0x390, (q15_t)0xeaf3, + (q15_t)0x38c, (q15_t)0xeaff, (q15_t)0x387, (q15_t)0xeb0a, (q15_t)0x383, (q15_t)0xeb16, (q15_t)0x37f, (q15_t)0xeb22, + (q15_t)0x37b, (q15_t)0xeb2e, (q15_t)0x377, (q15_t)0xeb3a, (q15_t)0x373, (q15_t)0xeb46, (q15_t)0x36f, (q15_t)0xeb52, + (q15_t)0x36b, (q15_t)0xeb5e, (q15_t)0x367, (q15_t)0xeb6a, (q15_t)0x363, (q15_t)0xeb75, (q15_t)0x35f, (q15_t)0xeb81, + (q15_t)0x35b, (q15_t)0xeb8d, (q15_t)0x357, (q15_t)0xeb99, (q15_t)0x353, (q15_t)0xeba5, (q15_t)0x34f, (q15_t)0xebb1, + (q15_t)0x34b, (q15_t)0xebbd, (q15_t)0x347, (q15_t)0xebc9, (q15_t)0x343, (q15_t)0xebd5, (q15_t)0x33f, (q15_t)0xebe1, + (q15_t)0x33b, (q15_t)0xebed, (q15_t)0x337, (q15_t)0xebf9, (q15_t)0x333, (q15_t)0xec05, (q15_t)0x32f, (q15_t)0xec10, + (q15_t)0x32b, (q15_t)0xec1c, (q15_t)0x327, (q15_t)0xec28, (q15_t)0x323, (q15_t)0xec34, (q15_t)0x320, (q15_t)0xec40, + (q15_t)0x31c, (q15_t)0xec4c, (q15_t)0x318, (q15_t)0xec58, (q15_t)0x314, (q15_t)0xec64, (q15_t)0x310, (q15_t)0xec70, + (q15_t)0x30c, (q15_t)0xec7c, (q15_t)0x308, (q15_t)0xec88, (q15_t)0x305, (q15_t)0xec94, (q15_t)0x301, (q15_t)0xeca0, + (q15_t)0x2fd, (q15_t)0xecac, (q15_t)0x2f9, (q15_t)0xecb8, (q15_t)0x2f5, (q15_t)0xecc4, (q15_t)0x2f2, (q15_t)0xecd0, + (q15_t)0x2ee, (q15_t)0xecdc, (q15_t)0x2ea, (q15_t)0xece8, (q15_t)0x2e6, (q15_t)0xecf4, (q15_t)0x2e3, (q15_t)0xed00, + (q15_t)0x2df, (q15_t)0xed0c, (q15_t)0x2db, (q15_t)0xed18, (q15_t)0x2d8, (q15_t)0xed24, (q15_t)0x2d4, (q15_t)0xed30, + (q15_t)0x2d0, (q15_t)0xed3c, (q15_t)0x2cc, (q15_t)0xed48, (q15_t)0x2c9, (q15_t)0xed54, (q15_t)0x2c5, (q15_t)0xed60, + (q15_t)0x2c1, (q15_t)0xed6c, (q15_t)0x2be, (q15_t)0xed78, (q15_t)0x2ba, (q15_t)0xed84, (q15_t)0x2b7, (q15_t)0xed90, + (q15_t)0x2b3, (q15_t)0xed9c, (q15_t)0x2af, (q15_t)0xeda8, (q15_t)0x2ac, (q15_t)0xedb4, (q15_t)0x2a8, (q15_t)0xedc0, + (q15_t)0x2a5, (q15_t)0xedcc, (q15_t)0x2a1, (q15_t)0xedd8, (q15_t)0x29d, (q15_t)0xede4, (q15_t)0x29a, (q15_t)0xedf0, + (q15_t)0x296, (q15_t)0xedfc, (q15_t)0x293, (q15_t)0xee09, (q15_t)0x28f, (q15_t)0xee15, (q15_t)0x28c, (q15_t)0xee21, + (q15_t)0x288, (q15_t)0xee2d, (q15_t)0x285, (q15_t)0xee39, (q15_t)0x281, (q15_t)0xee45, (q15_t)0x27e, (q15_t)0xee51, + (q15_t)0x27a, (q15_t)0xee5d, (q15_t)0x277, (q15_t)0xee69, (q15_t)0x273, (q15_t)0xee75, (q15_t)0x270, (q15_t)0xee81, + (q15_t)0x26d, (q15_t)0xee8d, (q15_t)0x269, (q15_t)0xee99, (q15_t)0x266, (q15_t)0xeea6, (q15_t)0x262, (q15_t)0xeeb2, + (q15_t)0x25f, (q15_t)0xeebe, (q15_t)0x25c, (q15_t)0xeeca, (q15_t)0x258, (q15_t)0xeed6, (q15_t)0x255, (q15_t)0xeee2, + (q15_t)0x251, (q15_t)0xeeee, (q15_t)0x24e, (q15_t)0xeefa, (q15_t)0x24b, (q15_t)0xef06, (q15_t)0x247, (q15_t)0xef13, + (q15_t)0x244, (q15_t)0xef1f, (q15_t)0x241, (q15_t)0xef2b, (q15_t)0x23e, (q15_t)0xef37, (q15_t)0x23a, (q15_t)0xef43, + (q15_t)0x237, (q15_t)0xef4f, (q15_t)0x234, (q15_t)0xef5b, (q15_t)0x230, (q15_t)0xef67, (q15_t)0x22d, (q15_t)0xef74, + (q15_t)0x22a, (q15_t)0xef80, (q15_t)0x227, (q15_t)0xef8c, (q15_t)0x223, (q15_t)0xef98, (q15_t)0x220, (q15_t)0xefa4, + (q15_t)0x21d, (q15_t)0xefb0, (q15_t)0x21a, (q15_t)0xefbc, (q15_t)0x217, (q15_t)0xefc9, (q15_t)0x213, (q15_t)0xefd5, + (q15_t)0x210, (q15_t)0xefe1, (q15_t)0x20d, (q15_t)0xefed, (q15_t)0x20a, (q15_t)0xeff9, (q15_t)0x207, (q15_t)0xf005, + (q15_t)0x204, (q15_t)0xf012, (q15_t)0x201, (q15_t)0xf01e, (q15_t)0x1fd, (q15_t)0xf02a, (q15_t)0x1fa, (q15_t)0xf036, + (q15_t)0x1f7, (q15_t)0xf042, (q15_t)0x1f4, (q15_t)0xf04e, (q15_t)0x1f1, (q15_t)0xf05b, (q15_t)0x1ee, (q15_t)0xf067, + (q15_t)0x1eb, (q15_t)0xf073, (q15_t)0x1e8, (q15_t)0xf07f, (q15_t)0x1e5, (q15_t)0xf08b, (q15_t)0x1e2, (q15_t)0xf098, + (q15_t)0x1df, (q15_t)0xf0a4, (q15_t)0x1dc, (q15_t)0xf0b0, (q15_t)0x1d9, (q15_t)0xf0bc, (q15_t)0x1d6, (q15_t)0xf0c8, + (q15_t)0x1d3, (q15_t)0xf0d5, (q15_t)0x1d0, (q15_t)0xf0e1, (q15_t)0x1cd, (q15_t)0xf0ed, (q15_t)0x1ca, (q15_t)0xf0f9, + (q15_t)0x1c7, (q15_t)0xf105, (q15_t)0x1c4, (q15_t)0xf112, (q15_t)0x1c1, (q15_t)0xf11e, (q15_t)0x1be, (q15_t)0xf12a, + (q15_t)0x1bb, (q15_t)0xf136, (q15_t)0x1b8, (q15_t)0xf143, (q15_t)0x1b6, (q15_t)0xf14f, (q15_t)0x1b3, (q15_t)0xf15b, + (q15_t)0x1b0, (q15_t)0xf167, (q15_t)0x1ad, (q15_t)0xf174, (q15_t)0x1aa, (q15_t)0xf180, (q15_t)0x1a7, (q15_t)0xf18c, + (q15_t)0x1a4, (q15_t)0xf198, (q15_t)0x1a2, (q15_t)0xf1a4, (q15_t)0x19f, (q15_t)0xf1b1, (q15_t)0x19c, (q15_t)0xf1bd, + (q15_t)0x199, (q15_t)0xf1c9, (q15_t)0x196, (q15_t)0xf1d5, (q15_t)0x194, (q15_t)0xf1e2, (q15_t)0x191, (q15_t)0xf1ee, + (q15_t)0x18e, (q15_t)0xf1fa, (q15_t)0x18b, (q15_t)0xf207, (q15_t)0x189, (q15_t)0xf213, (q15_t)0x186, (q15_t)0xf21f, + (q15_t)0x183, (q15_t)0xf22b, (q15_t)0x180, (q15_t)0xf238, (q15_t)0x17e, (q15_t)0xf244, (q15_t)0x17b, (q15_t)0xf250, + (q15_t)0x178, (q15_t)0xf25c, (q15_t)0x176, (q15_t)0xf269, (q15_t)0x173, (q15_t)0xf275, (q15_t)0x170, (q15_t)0xf281, + (q15_t)0x16e, (q15_t)0xf28e, (q15_t)0x16b, (q15_t)0xf29a, (q15_t)0x168, (q15_t)0xf2a6, (q15_t)0x166, (q15_t)0xf2b2, + (q15_t)0x163, (q15_t)0xf2bf, (q15_t)0x161, (q15_t)0xf2cb, (q15_t)0x15e, (q15_t)0xf2d7, (q15_t)0x15b, (q15_t)0xf2e4, + (q15_t)0x159, (q15_t)0xf2f0, (q15_t)0x156, (q15_t)0xf2fc, (q15_t)0x154, (q15_t)0xf308, (q15_t)0x151, (q15_t)0xf315, + (q15_t)0x14f, (q15_t)0xf321, (q15_t)0x14c, (q15_t)0xf32d, (q15_t)0x14a, (q15_t)0xf33a, (q15_t)0x147, (q15_t)0xf346, + (q15_t)0x145, (q15_t)0xf352, (q15_t)0x142, (q15_t)0xf35f, (q15_t)0x140, (q15_t)0xf36b, (q15_t)0x13d, (q15_t)0xf377, + (q15_t)0x13b, (q15_t)0xf384, (q15_t)0x138, (q15_t)0xf390, (q15_t)0x136, (q15_t)0xf39c, (q15_t)0x134, (q15_t)0xf3a9, + (q15_t)0x131, (q15_t)0xf3b5, (q15_t)0x12f, (q15_t)0xf3c1, (q15_t)0x12c, (q15_t)0xf3ce, (q15_t)0x12a, (q15_t)0xf3da, + (q15_t)0x128, (q15_t)0xf3e6, (q15_t)0x125, (q15_t)0xf3f3, (q15_t)0x123, (q15_t)0xf3ff, (q15_t)0x120, (q15_t)0xf40b, + (q15_t)0x11e, (q15_t)0xf418, (q15_t)0x11c, (q15_t)0xf424, (q15_t)0x119, (q15_t)0xf430, (q15_t)0x117, (q15_t)0xf43d, + (q15_t)0x115, (q15_t)0xf449, (q15_t)0x113, (q15_t)0xf455, (q15_t)0x110, (q15_t)0xf462, (q15_t)0x10e, (q15_t)0xf46e, + (q15_t)0x10c, (q15_t)0xf47b, (q15_t)0x109, (q15_t)0xf487, (q15_t)0x107, (q15_t)0xf493, (q15_t)0x105, (q15_t)0xf4a0, + (q15_t)0x103, (q15_t)0xf4ac, (q15_t)0x100, (q15_t)0xf4b8, (q15_t)0xfe, (q15_t)0xf4c5, (q15_t)0xfc, (q15_t)0xf4d1, + (q15_t)0xfa, (q15_t)0xf4dd, (q15_t)0xf8, (q15_t)0xf4ea, (q15_t)0xf6, (q15_t)0xf4f6, (q15_t)0xf3, (q15_t)0xf503, + (q15_t)0xf1, (q15_t)0xf50f, (q15_t)0xef, (q15_t)0xf51b, (q15_t)0xed, (q15_t)0xf528, (q15_t)0xeb, (q15_t)0xf534, + (q15_t)0xe9, (q15_t)0xf540, (q15_t)0xe7, (q15_t)0xf54d, (q15_t)0xe4, (q15_t)0xf559, (q15_t)0xe2, (q15_t)0xf566, + (q15_t)0xe0, (q15_t)0xf572, (q15_t)0xde, (q15_t)0xf57e, (q15_t)0xdc, (q15_t)0xf58b, (q15_t)0xda, (q15_t)0xf597, + (q15_t)0xd8, (q15_t)0xf5a4, (q15_t)0xd6, (q15_t)0xf5b0, (q15_t)0xd4, (q15_t)0xf5bc, (q15_t)0xd2, (q15_t)0xf5c9, + (q15_t)0xd0, (q15_t)0xf5d5, (q15_t)0xce, (q15_t)0xf5e2, (q15_t)0xcc, (q15_t)0xf5ee, (q15_t)0xca, (q15_t)0xf5fa, + (q15_t)0xc8, (q15_t)0xf607, (q15_t)0xc6, (q15_t)0xf613, (q15_t)0xc4, (q15_t)0xf620, (q15_t)0xc2, (q15_t)0xf62c, + (q15_t)0xc0, (q15_t)0xf639, (q15_t)0xbe, (q15_t)0xf645, (q15_t)0xbd, (q15_t)0xf651, (q15_t)0xbb, (q15_t)0xf65e, + (q15_t)0xb9, (q15_t)0xf66a, (q15_t)0xb7, (q15_t)0xf677, (q15_t)0xb5, (q15_t)0xf683, (q15_t)0xb3, (q15_t)0xf690, + (q15_t)0xb1, (q15_t)0xf69c, (q15_t)0xaf, (q15_t)0xf6a8, (q15_t)0xae, (q15_t)0xf6b5, (q15_t)0xac, (q15_t)0xf6c1, + (q15_t)0xaa, (q15_t)0xf6ce, (q15_t)0xa8, (q15_t)0xf6da, (q15_t)0xa6, (q15_t)0xf6e7, (q15_t)0xa5, (q15_t)0xf6f3, + (q15_t)0xa3, (q15_t)0xf6ff, (q15_t)0xa1, (q15_t)0xf70c, (q15_t)0x9f, (q15_t)0xf718, (q15_t)0x9e, (q15_t)0xf725, + (q15_t)0x9c, (q15_t)0xf731, (q15_t)0x9a, (q15_t)0xf73e, (q15_t)0x98, (q15_t)0xf74a, (q15_t)0x97, (q15_t)0xf757, + (q15_t)0x95, (q15_t)0xf763, (q15_t)0x93, (q15_t)0xf76f, (q15_t)0x92, (q15_t)0xf77c, (q15_t)0x90, (q15_t)0xf788, + (q15_t)0x8e, (q15_t)0xf795, (q15_t)0x8d, (q15_t)0xf7a1, (q15_t)0x8b, (q15_t)0xf7ae, (q15_t)0x89, (q15_t)0xf7ba, + (q15_t)0x88, (q15_t)0xf7c7, (q15_t)0x86, (q15_t)0xf7d3, (q15_t)0x85, (q15_t)0xf7e0, (q15_t)0x83, (q15_t)0xf7ec, + (q15_t)0x81, (q15_t)0xf7f9, (q15_t)0x80, (q15_t)0xf805, (q15_t)0x7e, (q15_t)0xf811, (q15_t)0x7d, (q15_t)0xf81e, + (q15_t)0x7b, (q15_t)0xf82a, (q15_t)0x7a, (q15_t)0xf837, (q15_t)0x78, (q15_t)0xf843, (q15_t)0x77, (q15_t)0xf850, + (q15_t)0x75, (q15_t)0xf85c, (q15_t)0x74, (q15_t)0xf869, (q15_t)0x72, (q15_t)0xf875, (q15_t)0x71, (q15_t)0xf882, + (q15_t)0x6f, (q15_t)0xf88e, (q15_t)0x6e, (q15_t)0xf89b, (q15_t)0x6c, (q15_t)0xf8a7, (q15_t)0x6b, (q15_t)0xf8b4, + (q15_t)0x69, (q15_t)0xf8c0, (q15_t)0x68, (q15_t)0xf8cd, (q15_t)0x67, (q15_t)0xf8d9, (q15_t)0x65, (q15_t)0xf8e6, + (q15_t)0x64, (q15_t)0xf8f2, (q15_t)0x62, (q15_t)0xf8ff, (q15_t)0x61, (q15_t)0xf90b, (q15_t)0x60, (q15_t)0xf918, + (q15_t)0x5e, (q15_t)0xf924, (q15_t)0x5d, (q15_t)0xf931, (q15_t)0x5c, (q15_t)0xf93d, (q15_t)0x5a, (q15_t)0xf94a, + (q15_t)0x59, (q15_t)0xf956, (q15_t)0x58, (q15_t)0xf963, (q15_t)0x56, (q15_t)0xf96f, (q15_t)0x55, (q15_t)0xf97c, + (q15_t)0x54, (q15_t)0xf988, (q15_t)0x53, (q15_t)0xf995, (q15_t)0x51, (q15_t)0xf9a1, (q15_t)0x50, (q15_t)0xf9ae, + (q15_t)0x4f, (q15_t)0xf9ba, (q15_t)0x4e, (q15_t)0xf9c7, (q15_t)0x4c, (q15_t)0xf9d3, (q15_t)0x4b, (q15_t)0xf9e0, + (q15_t)0x4a, (q15_t)0xf9ec, (q15_t)0x49, (q15_t)0xf9f9, (q15_t)0x48, (q15_t)0xfa05, (q15_t)0x47, (q15_t)0xfa12, + (q15_t)0x45, (q15_t)0xfa1e, (q15_t)0x44, (q15_t)0xfa2b, (q15_t)0x43, (q15_t)0xfa37, (q15_t)0x42, (q15_t)0xfa44, + (q15_t)0x41, (q15_t)0xfa50, (q15_t)0x40, (q15_t)0xfa5d, (q15_t)0x3f, (q15_t)0xfa69, (q15_t)0x3d, (q15_t)0xfa76, + (q15_t)0x3c, (q15_t)0xfa82, (q15_t)0x3b, (q15_t)0xfa8f, (q15_t)0x3a, (q15_t)0xfa9b, (q15_t)0x39, (q15_t)0xfaa8, + (q15_t)0x38, (q15_t)0xfab4, (q15_t)0x37, (q15_t)0xfac1, (q15_t)0x36, (q15_t)0xfacd, (q15_t)0x35, (q15_t)0xfada, + (q15_t)0x34, (q15_t)0xfae6, (q15_t)0x33, (q15_t)0xfaf3, (q15_t)0x32, (q15_t)0xfb00, (q15_t)0x31, (q15_t)0xfb0c, + (q15_t)0x30, (q15_t)0xfb19, (q15_t)0x2f, (q15_t)0xfb25, (q15_t)0x2e, (q15_t)0xfb32, (q15_t)0x2d, (q15_t)0xfb3e, + (q15_t)0x2c, (q15_t)0xfb4b, (q15_t)0x2b, (q15_t)0xfb57, (q15_t)0x2b, (q15_t)0xfb64, (q15_t)0x2a, (q15_t)0xfb70, + (q15_t)0x29, (q15_t)0xfb7d, (q15_t)0x28, (q15_t)0xfb89, (q15_t)0x27, (q15_t)0xfb96, (q15_t)0x26, (q15_t)0xfba2, + (q15_t)0x25, (q15_t)0xfbaf, (q15_t)0x24, (q15_t)0xfbbc, (q15_t)0x24, (q15_t)0xfbc8, (q15_t)0x23, (q15_t)0xfbd5, + (q15_t)0x22, (q15_t)0xfbe1, (q15_t)0x21, (q15_t)0xfbee, (q15_t)0x20, (q15_t)0xfbfa, (q15_t)0x20, (q15_t)0xfc07, + (q15_t)0x1f, (q15_t)0xfc13, (q15_t)0x1e, (q15_t)0xfc20, (q15_t)0x1d, (q15_t)0xfc2c, (q15_t)0x1d, (q15_t)0xfc39, + (q15_t)0x1c, (q15_t)0xfc45, (q15_t)0x1b, (q15_t)0xfc52, (q15_t)0x1a, (q15_t)0xfc5f, (q15_t)0x1a, (q15_t)0xfc6b, + (q15_t)0x19, (q15_t)0xfc78, (q15_t)0x18, (q15_t)0xfc84, (q15_t)0x18, (q15_t)0xfc91, (q15_t)0x17, (q15_t)0xfc9d, + (q15_t)0x16, (q15_t)0xfcaa, (q15_t)0x16, (q15_t)0xfcb6, (q15_t)0x15, (q15_t)0xfcc3, (q15_t)0x14, (q15_t)0xfcd0, + (q15_t)0x14, (q15_t)0xfcdc, (q15_t)0x13, (q15_t)0xfce9, (q15_t)0x13, (q15_t)0xfcf5, (q15_t)0x12, (q15_t)0xfd02, + (q15_t)0x11, (q15_t)0xfd0e, (q15_t)0x11, (q15_t)0xfd1b, (q15_t)0x10, (q15_t)0xfd27, (q15_t)0x10, (q15_t)0xfd34, + (q15_t)0xf, (q15_t)0xfd40, (q15_t)0xf, (q15_t)0xfd4d, (q15_t)0xe, (q15_t)0xfd5a, (q15_t)0xe, (q15_t)0xfd66, + (q15_t)0xd, (q15_t)0xfd73, (q15_t)0xd, (q15_t)0xfd7f, (q15_t)0xc, (q15_t)0xfd8c, (q15_t)0xc, (q15_t)0xfd98, + (q15_t)0xb, (q15_t)0xfda5, (q15_t)0xb, (q15_t)0xfdb2, (q15_t)0xa, (q15_t)0xfdbe, (q15_t)0xa, (q15_t)0xfdcb, + (q15_t)0x9, (q15_t)0xfdd7, (q15_t)0x9, (q15_t)0xfde4, (q15_t)0x9, (q15_t)0xfdf0, (q15_t)0x8, (q15_t)0xfdfd, + (q15_t)0x8, (q15_t)0xfe09, (q15_t)0x7, (q15_t)0xfe16, (q15_t)0x7, (q15_t)0xfe23, (q15_t)0x7, (q15_t)0xfe2f, + (q15_t)0x6, (q15_t)0xfe3c, (q15_t)0x6, (q15_t)0xfe48, (q15_t)0x6, (q15_t)0xfe55, (q15_t)0x5, (q15_t)0xfe61, + (q15_t)0x5, (q15_t)0xfe6e, (q15_t)0x5, (q15_t)0xfe7a, (q15_t)0x4, (q15_t)0xfe87, (q15_t)0x4, (q15_t)0xfe94, + (q15_t)0x4, (q15_t)0xfea0, (q15_t)0x4, (q15_t)0xfead, (q15_t)0x3, (q15_t)0xfeb9, (q15_t)0x3, (q15_t)0xfec6, + (q15_t)0x3, (q15_t)0xfed2, (q15_t)0x3, (q15_t)0xfedf, (q15_t)0x2, (q15_t)0xfeec, (q15_t)0x2, (q15_t)0xfef8, + (q15_t)0x2, (q15_t)0xff05, (q15_t)0x2, (q15_t)0xff11, (q15_t)0x2, (q15_t)0xff1e, (q15_t)0x1, (q15_t)0xff2a, + (q15_t)0x1, (q15_t)0xff37, (q15_t)0x1, (q15_t)0xff44, (q15_t)0x1, (q15_t)0xff50, (q15_t)0x1, (q15_t)0xff5d, + (q15_t)0x1, (q15_t)0xff69, (q15_t)0x1, (q15_t)0xff76, (q15_t)0x0, (q15_t)0xff82, (q15_t)0x0, (q15_t)0xff8f, + (q15_t)0x0, (q15_t)0xff9b, (q15_t)0x0, (q15_t)0xffa8, (q15_t)0x0, (q15_t)0xffb5, (q15_t)0x0, (q15_t)0xffc1, + (q15_t)0x0, (q15_t)0xffce, (q15_t)0x0, (q15_t)0xffda, (q15_t)0x0, (q15_t)0xffe7, (q15_t)0x0, (q15_t)0xfff3, + (q15_t)0x0, (q15_t)0x0, (q15_t)0x0, (q15_t)0xd, (q15_t)0x0, (q15_t)0x19, (q15_t)0x0, (q15_t)0x26, + (q15_t)0x0, (q15_t)0x32, (q15_t)0x0, (q15_t)0x3f, (q15_t)0x0, (q15_t)0x4b, (q15_t)0x0, (q15_t)0x58, + (q15_t)0x0, (q15_t)0x65, (q15_t)0x0, (q15_t)0x71, (q15_t)0x0, (q15_t)0x7e, (q15_t)0x1, (q15_t)0x8a, + (q15_t)0x1, (q15_t)0x97, (q15_t)0x1, (q15_t)0xa3, (q15_t)0x1, (q15_t)0xb0, (q15_t)0x1, (q15_t)0xbc, + (q15_t)0x1, (q15_t)0xc9, (q15_t)0x1, (q15_t)0xd6, (q15_t)0x2, (q15_t)0xe2, (q15_t)0x2, (q15_t)0xef, + (q15_t)0x2, (q15_t)0xfb, (q15_t)0x2, (q15_t)0x108, (q15_t)0x2, (q15_t)0x114, (q15_t)0x3, (q15_t)0x121, + (q15_t)0x3, (q15_t)0x12e, (q15_t)0x3, (q15_t)0x13a, (q15_t)0x3, (q15_t)0x147, (q15_t)0x4, (q15_t)0x153, + (q15_t)0x4, (q15_t)0x160, (q15_t)0x4, (q15_t)0x16c, (q15_t)0x4, (q15_t)0x179, (q15_t)0x5, (q15_t)0x186, + (q15_t)0x5, (q15_t)0x192, (q15_t)0x5, (q15_t)0x19f, (q15_t)0x6, (q15_t)0x1ab, (q15_t)0x6, (q15_t)0x1b8, + (q15_t)0x6, (q15_t)0x1c4, (q15_t)0x7, (q15_t)0x1d1, (q15_t)0x7, (q15_t)0x1dd, (q15_t)0x7, (q15_t)0x1ea, + (q15_t)0x8, (q15_t)0x1f7, (q15_t)0x8, (q15_t)0x203, (q15_t)0x9, (q15_t)0x210, (q15_t)0x9, (q15_t)0x21c, + (q15_t)0x9, (q15_t)0x229, (q15_t)0xa, (q15_t)0x235, (q15_t)0xa, (q15_t)0x242, (q15_t)0xb, (q15_t)0x24e, + (q15_t)0xb, (q15_t)0x25b, (q15_t)0xc, (q15_t)0x268, (q15_t)0xc, (q15_t)0x274, (q15_t)0xd, (q15_t)0x281, + (q15_t)0xd, (q15_t)0x28d, (q15_t)0xe, (q15_t)0x29a, (q15_t)0xe, (q15_t)0x2a6, (q15_t)0xf, (q15_t)0x2b3, + (q15_t)0xf, (q15_t)0x2c0, (q15_t)0x10, (q15_t)0x2cc, (q15_t)0x10, (q15_t)0x2d9, (q15_t)0x11, (q15_t)0x2e5, + (q15_t)0x11, (q15_t)0x2f2, (q15_t)0x12, (q15_t)0x2fe, (q15_t)0x13, (q15_t)0x30b, (q15_t)0x13, (q15_t)0x317, + (q15_t)0x14, (q15_t)0x324, (q15_t)0x14, (q15_t)0x330, (q15_t)0x15, (q15_t)0x33d, (q15_t)0x16, (q15_t)0x34a, + (q15_t)0x16, (q15_t)0x356, (q15_t)0x17, (q15_t)0x363, (q15_t)0x18, (q15_t)0x36f, (q15_t)0x18, (q15_t)0x37c, + (q15_t)0x19, (q15_t)0x388, (q15_t)0x1a, (q15_t)0x395, (q15_t)0x1a, (q15_t)0x3a1, (q15_t)0x1b, (q15_t)0x3ae, + (q15_t)0x1c, (q15_t)0x3bb, (q15_t)0x1d, (q15_t)0x3c7, (q15_t)0x1d, (q15_t)0x3d4, (q15_t)0x1e, (q15_t)0x3e0, + (q15_t)0x1f, (q15_t)0x3ed, (q15_t)0x20, (q15_t)0x3f9, (q15_t)0x20, (q15_t)0x406, (q15_t)0x21, (q15_t)0x412, + (q15_t)0x22, (q15_t)0x41f, (q15_t)0x23, (q15_t)0x42b, (q15_t)0x24, (q15_t)0x438, (q15_t)0x24, (q15_t)0x444, + (q15_t)0x25, (q15_t)0x451, (q15_t)0x26, (q15_t)0x45e, (q15_t)0x27, (q15_t)0x46a, (q15_t)0x28, (q15_t)0x477, + (q15_t)0x29, (q15_t)0x483, (q15_t)0x2a, (q15_t)0x490, (q15_t)0x2b, (q15_t)0x49c, (q15_t)0x2b, (q15_t)0x4a9, + (q15_t)0x2c, (q15_t)0x4b5, (q15_t)0x2d, (q15_t)0x4c2, (q15_t)0x2e, (q15_t)0x4ce, (q15_t)0x2f, (q15_t)0x4db, + (q15_t)0x30, (q15_t)0x4e7, (q15_t)0x31, (q15_t)0x4f4, (q15_t)0x32, (q15_t)0x500, (q15_t)0x33, (q15_t)0x50d, + (q15_t)0x34, (q15_t)0x51a, (q15_t)0x35, (q15_t)0x526, (q15_t)0x36, (q15_t)0x533, (q15_t)0x37, (q15_t)0x53f, + (q15_t)0x38, (q15_t)0x54c, (q15_t)0x39, (q15_t)0x558, (q15_t)0x3a, (q15_t)0x565, (q15_t)0x3b, (q15_t)0x571, + (q15_t)0x3c, (q15_t)0x57e, (q15_t)0x3d, (q15_t)0x58a, (q15_t)0x3f, (q15_t)0x597, (q15_t)0x40, (q15_t)0x5a3, + (q15_t)0x41, (q15_t)0x5b0, (q15_t)0x42, (q15_t)0x5bc, (q15_t)0x43, (q15_t)0x5c9, (q15_t)0x44, (q15_t)0x5d5, + (q15_t)0x45, (q15_t)0x5e2, (q15_t)0x47, (q15_t)0x5ee, (q15_t)0x48, (q15_t)0x5fb, (q15_t)0x49, (q15_t)0x607, + (q15_t)0x4a, (q15_t)0x614, (q15_t)0x4b, (q15_t)0x620, (q15_t)0x4c, (q15_t)0x62d, (q15_t)0x4e, (q15_t)0x639, + (q15_t)0x4f, (q15_t)0x646, (q15_t)0x50, (q15_t)0x652, (q15_t)0x51, (q15_t)0x65f, (q15_t)0x53, (q15_t)0x66b, + (q15_t)0x54, (q15_t)0x678, (q15_t)0x55, (q15_t)0x684, (q15_t)0x56, (q15_t)0x691, (q15_t)0x58, (q15_t)0x69d, + (q15_t)0x59, (q15_t)0x6aa, (q15_t)0x5a, (q15_t)0x6b6, (q15_t)0x5c, (q15_t)0x6c3, (q15_t)0x5d, (q15_t)0x6cf, + (q15_t)0x5e, (q15_t)0x6dc, (q15_t)0x60, (q15_t)0x6e8, (q15_t)0x61, (q15_t)0x6f5, (q15_t)0x62, (q15_t)0x701, + (q15_t)0x64, (q15_t)0x70e, (q15_t)0x65, (q15_t)0x71a, (q15_t)0x67, (q15_t)0x727, (q15_t)0x68, (q15_t)0x733, + (q15_t)0x69, (q15_t)0x740, (q15_t)0x6b, (q15_t)0x74c, (q15_t)0x6c, (q15_t)0x759, (q15_t)0x6e, (q15_t)0x765, + (q15_t)0x6f, (q15_t)0x772, (q15_t)0x71, (q15_t)0x77e, (q15_t)0x72, (q15_t)0x78b, (q15_t)0x74, (q15_t)0x797, + (q15_t)0x75, (q15_t)0x7a4, (q15_t)0x77, (q15_t)0x7b0, (q15_t)0x78, (q15_t)0x7bd, (q15_t)0x7a, (q15_t)0x7c9, + (q15_t)0x7b, (q15_t)0x7d6, (q15_t)0x7d, (q15_t)0x7e2, (q15_t)0x7e, (q15_t)0x7ef, (q15_t)0x80, (q15_t)0x7fb, + (q15_t)0x81, (q15_t)0x807, (q15_t)0x83, (q15_t)0x814, (q15_t)0x85, (q15_t)0x820, (q15_t)0x86, (q15_t)0x82d, + (q15_t)0x88, (q15_t)0x839, (q15_t)0x89, (q15_t)0x846, (q15_t)0x8b, (q15_t)0x852, (q15_t)0x8d, (q15_t)0x85f, + (q15_t)0x8e, (q15_t)0x86b, (q15_t)0x90, (q15_t)0x878, (q15_t)0x92, (q15_t)0x884, (q15_t)0x93, (q15_t)0x891, + (q15_t)0x95, (q15_t)0x89d, (q15_t)0x97, (q15_t)0x8a9, (q15_t)0x98, (q15_t)0x8b6, (q15_t)0x9a, (q15_t)0x8c2, + (q15_t)0x9c, (q15_t)0x8cf, (q15_t)0x9e, (q15_t)0x8db, (q15_t)0x9f, (q15_t)0x8e8, (q15_t)0xa1, (q15_t)0x8f4, + (q15_t)0xa3, (q15_t)0x901, (q15_t)0xa5, (q15_t)0x90d, (q15_t)0xa6, (q15_t)0x919, (q15_t)0xa8, (q15_t)0x926, + (q15_t)0xaa, (q15_t)0x932, (q15_t)0xac, (q15_t)0x93f, (q15_t)0xae, (q15_t)0x94b, (q15_t)0xaf, (q15_t)0x958, + (q15_t)0xb1, (q15_t)0x964, (q15_t)0xb3, (q15_t)0x970, (q15_t)0xb5, (q15_t)0x97d, (q15_t)0xb7, (q15_t)0x989, + (q15_t)0xb9, (q15_t)0x996, (q15_t)0xbb, (q15_t)0x9a2, (q15_t)0xbd, (q15_t)0x9af, (q15_t)0xbe, (q15_t)0x9bb, + (q15_t)0xc0, (q15_t)0x9c7, (q15_t)0xc2, (q15_t)0x9d4, (q15_t)0xc4, (q15_t)0x9e0, (q15_t)0xc6, (q15_t)0x9ed, + (q15_t)0xc8, (q15_t)0x9f9, (q15_t)0xca, (q15_t)0xa06, (q15_t)0xcc, (q15_t)0xa12, (q15_t)0xce, (q15_t)0xa1e, + (q15_t)0xd0, (q15_t)0xa2b, (q15_t)0xd2, (q15_t)0xa37, (q15_t)0xd4, (q15_t)0xa44, (q15_t)0xd6, (q15_t)0xa50, + (q15_t)0xd8, (q15_t)0xa5c, (q15_t)0xda, (q15_t)0xa69, (q15_t)0xdc, (q15_t)0xa75, (q15_t)0xde, (q15_t)0xa82, + (q15_t)0xe0, (q15_t)0xa8e, (q15_t)0xe2, (q15_t)0xa9a, (q15_t)0xe4, (q15_t)0xaa7, (q15_t)0xe7, (q15_t)0xab3, + (q15_t)0xe9, (q15_t)0xac0, (q15_t)0xeb, (q15_t)0xacc, (q15_t)0xed, (q15_t)0xad8, (q15_t)0xef, (q15_t)0xae5, + (q15_t)0xf1, (q15_t)0xaf1, (q15_t)0xf3, (q15_t)0xafd, (q15_t)0xf6, (q15_t)0xb0a, (q15_t)0xf8, (q15_t)0xb16, + (q15_t)0xfa, (q15_t)0xb23, (q15_t)0xfc, (q15_t)0xb2f, (q15_t)0xfe, (q15_t)0xb3b, (q15_t)0x100, (q15_t)0xb48, + (q15_t)0x103, (q15_t)0xb54, (q15_t)0x105, (q15_t)0xb60, (q15_t)0x107, (q15_t)0xb6d, (q15_t)0x109, (q15_t)0xb79, + (q15_t)0x10c, (q15_t)0xb85, (q15_t)0x10e, (q15_t)0xb92, (q15_t)0x110, (q15_t)0xb9e, (q15_t)0x113, (q15_t)0xbab, + (q15_t)0x115, (q15_t)0xbb7, (q15_t)0x117, (q15_t)0xbc3, (q15_t)0x119, (q15_t)0xbd0, (q15_t)0x11c, (q15_t)0xbdc, + (q15_t)0x11e, (q15_t)0xbe8, (q15_t)0x120, (q15_t)0xbf5, (q15_t)0x123, (q15_t)0xc01, (q15_t)0x125, (q15_t)0xc0d, + (q15_t)0x128, (q15_t)0xc1a, (q15_t)0x12a, (q15_t)0xc26, (q15_t)0x12c, (q15_t)0xc32, (q15_t)0x12f, (q15_t)0xc3f, + (q15_t)0x131, (q15_t)0xc4b, (q15_t)0x134, (q15_t)0xc57, (q15_t)0x136, (q15_t)0xc64, (q15_t)0x138, (q15_t)0xc70, + (q15_t)0x13b, (q15_t)0xc7c, (q15_t)0x13d, (q15_t)0xc89, (q15_t)0x140, (q15_t)0xc95, (q15_t)0x142, (q15_t)0xca1, + (q15_t)0x145, (q15_t)0xcae, (q15_t)0x147, (q15_t)0xcba, (q15_t)0x14a, (q15_t)0xcc6, (q15_t)0x14c, (q15_t)0xcd3, + (q15_t)0x14f, (q15_t)0xcdf, (q15_t)0x151, (q15_t)0xceb, (q15_t)0x154, (q15_t)0xcf8, (q15_t)0x156, (q15_t)0xd04, + (q15_t)0x159, (q15_t)0xd10, (q15_t)0x15b, (q15_t)0xd1c, (q15_t)0x15e, (q15_t)0xd29, (q15_t)0x161, (q15_t)0xd35, + (q15_t)0x163, (q15_t)0xd41, (q15_t)0x166, (q15_t)0xd4e, (q15_t)0x168, (q15_t)0xd5a, (q15_t)0x16b, (q15_t)0xd66, + (q15_t)0x16e, (q15_t)0xd72, (q15_t)0x170, (q15_t)0xd7f, (q15_t)0x173, (q15_t)0xd8b, (q15_t)0x176, (q15_t)0xd97, + (q15_t)0x178, (q15_t)0xda4, (q15_t)0x17b, (q15_t)0xdb0, (q15_t)0x17e, (q15_t)0xdbc, (q15_t)0x180, (q15_t)0xdc8, + (q15_t)0x183, (q15_t)0xdd5, (q15_t)0x186, (q15_t)0xde1, (q15_t)0x189, (q15_t)0xded, (q15_t)0x18b, (q15_t)0xdf9, + (q15_t)0x18e, (q15_t)0xe06, (q15_t)0x191, (q15_t)0xe12, (q15_t)0x194, (q15_t)0xe1e, (q15_t)0x196, (q15_t)0xe2b, + (q15_t)0x199, (q15_t)0xe37, (q15_t)0x19c, (q15_t)0xe43, (q15_t)0x19f, (q15_t)0xe4f, (q15_t)0x1a2, (q15_t)0xe5c, + (q15_t)0x1a4, (q15_t)0xe68, (q15_t)0x1a7, (q15_t)0xe74, (q15_t)0x1aa, (q15_t)0xe80, (q15_t)0x1ad, (q15_t)0xe8c, + (q15_t)0x1b0, (q15_t)0xe99, (q15_t)0x1b3, (q15_t)0xea5, (q15_t)0x1b6, (q15_t)0xeb1, (q15_t)0x1b8, (q15_t)0xebd, + (q15_t)0x1bb, (q15_t)0xeca, (q15_t)0x1be, (q15_t)0xed6, (q15_t)0x1c1, (q15_t)0xee2, (q15_t)0x1c4, (q15_t)0xeee, + (q15_t)0x1c7, (q15_t)0xefb, (q15_t)0x1ca, (q15_t)0xf07, (q15_t)0x1cd, (q15_t)0xf13, (q15_t)0x1d0, (q15_t)0xf1f, + (q15_t)0x1d3, (q15_t)0xf2b, (q15_t)0x1d6, (q15_t)0xf38, (q15_t)0x1d9, (q15_t)0xf44, (q15_t)0x1dc, (q15_t)0xf50, + (q15_t)0x1df, (q15_t)0xf5c, (q15_t)0x1e2, (q15_t)0xf68, (q15_t)0x1e5, (q15_t)0xf75, (q15_t)0x1e8, (q15_t)0xf81, + (q15_t)0x1eb, (q15_t)0xf8d, (q15_t)0x1ee, (q15_t)0xf99, (q15_t)0x1f1, (q15_t)0xfa5, (q15_t)0x1f4, (q15_t)0xfb2, + (q15_t)0x1f7, (q15_t)0xfbe, (q15_t)0x1fa, (q15_t)0xfca, (q15_t)0x1fd, (q15_t)0xfd6, (q15_t)0x201, (q15_t)0xfe2, + (q15_t)0x204, (q15_t)0xfee, (q15_t)0x207, (q15_t)0xffb, (q15_t)0x20a, (q15_t)0x1007, (q15_t)0x20d, (q15_t)0x1013, + (q15_t)0x210, (q15_t)0x101f, (q15_t)0x213, (q15_t)0x102b, (q15_t)0x217, (q15_t)0x1037, (q15_t)0x21a, (q15_t)0x1044, + (q15_t)0x21d, (q15_t)0x1050, (q15_t)0x220, (q15_t)0x105c, (q15_t)0x223, (q15_t)0x1068, (q15_t)0x227, (q15_t)0x1074, + (q15_t)0x22a, (q15_t)0x1080, (q15_t)0x22d, (q15_t)0x108c, (q15_t)0x230, (q15_t)0x1099, (q15_t)0x234, (q15_t)0x10a5, + (q15_t)0x237, (q15_t)0x10b1, (q15_t)0x23a, (q15_t)0x10bd, (q15_t)0x23e, (q15_t)0x10c9, (q15_t)0x241, (q15_t)0x10d5, + (q15_t)0x244, (q15_t)0x10e1, (q15_t)0x247, (q15_t)0x10ed, (q15_t)0x24b, (q15_t)0x10fa, (q15_t)0x24e, (q15_t)0x1106, + (q15_t)0x251, (q15_t)0x1112, (q15_t)0x255, (q15_t)0x111e, (q15_t)0x258, (q15_t)0x112a, (q15_t)0x25c, (q15_t)0x1136, + (q15_t)0x25f, (q15_t)0x1142, (q15_t)0x262, (q15_t)0x114e, (q15_t)0x266, (q15_t)0x115a, (q15_t)0x269, (q15_t)0x1167, + (q15_t)0x26d, (q15_t)0x1173, (q15_t)0x270, (q15_t)0x117f, (q15_t)0x273, (q15_t)0x118b, (q15_t)0x277, (q15_t)0x1197, + (q15_t)0x27a, (q15_t)0x11a3, (q15_t)0x27e, (q15_t)0x11af, (q15_t)0x281, (q15_t)0x11bb, (q15_t)0x285, (q15_t)0x11c7, + (q15_t)0x288, (q15_t)0x11d3, (q15_t)0x28c, (q15_t)0x11df, (q15_t)0x28f, (q15_t)0x11eb, (q15_t)0x293, (q15_t)0x11f7, + (q15_t)0x296, (q15_t)0x1204, (q15_t)0x29a, (q15_t)0x1210, (q15_t)0x29d, (q15_t)0x121c, (q15_t)0x2a1, (q15_t)0x1228, + (q15_t)0x2a5, (q15_t)0x1234, (q15_t)0x2a8, (q15_t)0x1240, (q15_t)0x2ac, (q15_t)0x124c, (q15_t)0x2af, (q15_t)0x1258, + (q15_t)0x2b3, (q15_t)0x1264, (q15_t)0x2b7, (q15_t)0x1270, (q15_t)0x2ba, (q15_t)0x127c, (q15_t)0x2be, (q15_t)0x1288, + (q15_t)0x2c1, (q15_t)0x1294, (q15_t)0x2c5, (q15_t)0x12a0, (q15_t)0x2c9, (q15_t)0x12ac, (q15_t)0x2cc, (q15_t)0x12b8, + (q15_t)0x2d0, (q15_t)0x12c4, (q15_t)0x2d4, (q15_t)0x12d0, (q15_t)0x2d8, (q15_t)0x12dc, (q15_t)0x2db, (q15_t)0x12e8, + (q15_t)0x2df, (q15_t)0x12f4, (q15_t)0x2e3, (q15_t)0x1300, (q15_t)0x2e6, (q15_t)0x130c, (q15_t)0x2ea, (q15_t)0x1318, + (q15_t)0x2ee, (q15_t)0x1324, (q15_t)0x2f2, (q15_t)0x1330, (q15_t)0x2f5, (q15_t)0x133c, (q15_t)0x2f9, (q15_t)0x1348, + (q15_t)0x2fd, (q15_t)0x1354, (q15_t)0x301, (q15_t)0x1360, (q15_t)0x305, (q15_t)0x136c, (q15_t)0x308, (q15_t)0x1378, + (q15_t)0x30c, (q15_t)0x1384, (q15_t)0x310, (q15_t)0x1390, (q15_t)0x314, (q15_t)0x139c, (q15_t)0x318, (q15_t)0x13a8, + (q15_t)0x31c, (q15_t)0x13b4, (q15_t)0x320, (q15_t)0x13c0, (q15_t)0x323, (q15_t)0x13cc, (q15_t)0x327, (q15_t)0x13d8, + (q15_t)0x32b, (q15_t)0x13e4, (q15_t)0x32f, (q15_t)0x13f0, (q15_t)0x333, (q15_t)0x13fb, (q15_t)0x337, (q15_t)0x1407, + (q15_t)0x33b, (q15_t)0x1413, (q15_t)0x33f, (q15_t)0x141f, (q15_t)0x343, (q15_t)0x142b, (q15_t)0x347, (q15_t)0x1437, + (q15_t)0x34b, (q15_t)0x1443, (q15_t)0x34f, (q15_t)0x144f, (q15_t)0x353, (q15_t)0x145b, (q15_t)0x357, (q15_t)0x1467, + (q15_t)0x35b, (q15_t)0x1473, (q15_t)0x35f, (q15_t)0x147f, (q15_t)0x363, (q15_t)0x148b, (q15_t)0x367, (q15_t)0x1496, + (q15_t)0x36b, (q15_t)0x14a2, (q15_t)0x36f, (q15_t)0x14ae, (q15_t)0x373, (q15_t)0x14ba, (q15_t)0x377, (q15_t)0x14c6, + (q15_t)0x37b, (q15_t)0x14d2, (q15_t)0x37f, (q15_t)0x14de, (q15_t)0x383, (q15_t)0x14ea, (q15_t)0x387, (q15_t)0x14f6, + (q15_t)0x38c, (q15_t)0x1501, (q15_t)0x390, (q15_t)0x150d, (q15_t)0x394, (q15_t)0x1519, (q15_t)0x398, (q15_t)0x1525, + (q15_t)0x39c, (q15_t)0x1531, (q15_t)0x3a0, (q15_t)0x153d, (q15_t)0x3a5, (q15_t)0x1549, (q15_t)0x3a9, (q15_t)0x1554, + (q15_t)0x3ad, (q15_t)0x1560, (q15_t)0x3b1, (q15_t)0x156c, (q15_t)0x3b5, (q15_t)0x1578, (q15_t)0x3ba, (q15_t)0x1584, + (q15_t)0x3be, (q15_t)0x1590, (q15_t)0x3c2, (q15_t)0x159b, (q15_t)0x3c6, (q15_t)0x15a7, (q15_t)0x3ca, (q15_t)0x15b3, + (q15_t)0x3cf, (q15_t)0x15bf, (q15_t)0x3d3, (q15_t)0x15cb, (q15_t)0x3d7, (q15_t)0x15d7, (q15_t)0x3dc, (q15_t)0x15e2, + (q15_t)0x3e0, (q15_t)0x15ee, (q15_t)0x3e4, (q15_t)0x15fa, (q15_t)0x3e9, (q15_t)0x1606, (q15_t)0x3ed, (q15_t)0x1612, + (q15_t)0x3f1, (q15_t)0x161d, (q15_t)0x3f6, (q15_t)0x1629, (q15_t)0x3fa, (q15_t)0x1635, (q15_t)0x3fe, (q15_t)0x1641, + (q15_t)0x403, (q15_t)0x164c, (q15_t)0x407, (q15_t)0x1658, (q15_t)0x40b, (q15_t)0x1664, (q15_t)0x410, (q15_t)0x1670, + (q15_t)0x414, (q15_t)0x167c, (q15_t)0x419, (q15_t)0x1687, (q15_t)0x41d, (q15_t)0x1693, (q15_t)0x422, (q15_t)0x169f, + (q15_t)0x426, (q15_t)0x16ab, (q15_t)0x42a, (q15_t)0x16b6, (q15_t)0x42f, (q15_t)0x16c2, (q15_t)0x433, (q15_t)0x16ce, + (q15_t)0x438, (q15_t)0x16da, (q15_t)0x43c, (q15_t)0x16e5, (q15_t)0x441, (q15_t)0x16f1, (q15_t)0x445, (q15_t)0x16fd, + (q15_t)0x44a, (q15_t)0x1709, (q15_t)0x44e, (q15_t)0x1714, (q15_t)0x453, (q15_t)0x1720, (q15_t)0x457, (q15_t)0x172c, + (q15_t)0x45c, (q15_t)0x1737, (q15_t)0x461, (q15_t)0x1743, (q15_t)0x465, (q15_t)0x174f, (q15_t)0x46a, (q15_t)0x175b, + (q15_t)0x46e, (q15_t)0x1766, (q15_t)0x473, (q15_t)0x1772, (q15_t)0x478, (q15_t)0x177e, (q15_t)0x47c, (q15_t)0x1789, + (q15_t)0x481, (q15_t)0x1795, (q15_t)0x485, (q15_t)0x17a1, (q15_t)0x48a, (q15_t)0x17ac, (q15_t)0x48f, (q15_t)0x17b8, + (q15_t)0x493, (q15_t)0x17c4, (q15_t)0x498, (q15_t)0x17cf, (q15_t)0x49d, (q15_t)0x17db, (q15_t)0x4a1, (q15_t)0x17e7, + (q15_t)0x4a6, (q15_t)0x17f2, (q15_t)0x4ab, (q15_t)0x17fe, (q15_t)0x4b0, (q15_t)0x180a, (q15_t)0x4b4, (q15_t)0x1815, + (q15_t)0x4b9, (q15_t)0x1821, (q15_t)0x4be, (q15_t)0x182d, (q15_t)0x4c2, (q15_t)0x1838, (q15_t)0x4c7, (q15_t)0x1844, + (q15_t)0x4cc, (q15_t)0x184f, (q15_t)0x4d1, (q15_t)0x185b, (q15_t)0x4d6, (q15_t)0x1867, (q15_t)0x4da, (q15_t)0x1872, + (q15_t)0x4df, (q15_t)0x187e, (q15_t)0x4e4, (q15_t)0x1889, (q15_t)0x4e9, (q15_t)0x1895, (q15_t)0x4ee, (q15_t)0x18a1, + (q15_t)0x4f2, (q15_t)0x18ac, (q15_t)0x4f7, (q15_t)0x18b8, (q15_t)0x4fc, (q15_t)0x18c3, (q15_t)0x501, (q15_t)0x18cf, + (q15_t)0x506, (q15_t)0x18db, (q15_t)0x50b, (q15_t)0x18e6, (q15_t)0x510, (q15_t)0x18f2, (q15_t)0x515, (q15_t)0x18fd, + (q15_t)0x51a, (q15_t)0x1909, (q15_t)0x51e, (q15_t)0x1914, (q15_t)0x523, (q15_t)0x1920, (q15_t)0x528, (q15_t)0x192c, + (q15_t)0x52d, (q15_t)0x1937, (q15_t)0x532, (q15_t)0x1943, (q15_t)0x537, (q15_t)0x194e, (q15_t)0x53c, (q15_t)0x195a, + (q15_t)0x541, (q15_t)0x1965, (q15_t)0x546, (q15_t)0x1971, (q15_t)0x54b, (q15_t)0x197c, (q15_t)0x550, (q15_t)0x1988, + (q15_t)0x555, (q15_t)0x1993, (q15_t)0x55a, (q15_t)0x199f, (q15_t)0x55f, (q15_t)0x19aa, (q15_t)0x564, (q15_t)0x19b6, + (q15_t)0x569, (q15_t)0x19c1, (q15_t)0x56e, (q15_t)0x19cd, (q15_t)0x573, (q15_t)0x19d8, (q15_t)0x578, (q15_t)0x19e4, + (q15_t)0x57e, (q15_t)0x19ef, (q15_t)0x583, (q15_t)0x19fb, (q15_t)0x588, (q15_t)0x1a06, (q15_t)0x58d, (q15_t)0x1a12, + (q15_t)0x592, (q15_t)0x1a1d, (q15_t)0x597, (q15_t)0x1a29, (q15_t)0x59c, (q15_t)0x1a34, (q15_t)0x5a1, (q15_t)0x1a40, + (q15_t)0x5a7, (q15_t)0x1a4b, (q15_t)0x5ac, (q15_t)0x1a57, (q15_t)0x5b1, (q15_t)0x1a62, (q15_t)0x5b6, (q15_t)0x1a6e, + (q15_t)0x5bb, (q15_t)0x1a79, (q15_t)0x5c1, (q15_t)0x1a84, (q15_t)0x5c6, (q15_t)0x1a90, (q15_t)0x5cb, (q15_t)0x1a9b, + (q15_t)0x5d0, (q15_t)0x1aa7, (q15_t)0x5d5, (q15_t)0x1ab2, (q15_t)0x5db, (q15_t)0x1abe, (q15_t)0x5e0, (q15_t)0x1ac9, + (q15_t)0x5e5, (q15_t)0x1ad4, (q15_t)0x5ea, (q15_t)0x1ae0, (q15_t)0x5f0, (q15_t)0x1aeb, (q15_t)0x5f5, (q15_t)0x1af7, + (q15_t)0x5fa, (q15_t)0x1b02, (q15_t)0x600, (q15_t)0x1b0d, (q15_t)0x605, (q15_t)0x1b19, (q15_t)0x60a, (q15_t)0x1b24, + (q15_t)0x610, (q15_t)0x1b30, (q15_t)0x615, (q15_t)0x1b3b, (q15_t)0x61a, (q15_t)0x1b46, (q15_t)0x620, (q15_t)0x1b52, + (q15_t)0x625, (q15_t)0x1b5d, (q15_t)0x62a, (q15_t)0x1b68, (q15_t)0x630, (q15_t)0x1b74, (q15_t)0x635, (q15_t)0x1b7f, + (q15_t)0x63b, (q15_t)0x1b8a, (q15_t)0x640, (q15_t)0x1b96, (q15_t)0x645, (q15_t)0x1ba1, (q15_t)0x64b, (q15_t)0x1bac, + (q15_t)0x650, (q15_t)0x1bb8, (q15_t)0x656, (q15_t)0x1bc3, (q15_t)0x65b, (q15_t)0x1bce, (q15_t)0x661, (q15_t)0x1bda, + (q15_t)0x666, (q15_t)0x1be5, (q15_t)0x66c, (q15_t)0x1bf0, (q15_t)0x671, (q15_t)0x1bfc, (q15_t)0x677, (q15_t)0x1c07, + (q15_t)0x67c, (q15_t)0x1c12, (q15_t)0x682, (q15_t)0x1c1e, (q15_t)0x687, (q15_t)0x1c29, (q15_t)0x68d, (q15_t)0x1c34, + (q15_t)0x692, (q15_t)0x1c3f, (q15_t)0x698, (q15_t)0x1c4b, (q15_t)0x69d, (q15_t)0x1c56, (q15_t)0x6a3, (q15_t)0x1c61, + (q15_t)0x6a8, (q15_t)0x1c6c, (q15_t)0x6ae, (q15_t)0x1c78, (q15_t)0x6b4, (q15_t)0x1c83, (q15_t)0x6b9, (q15_t)0x1c8e, + (q15_t)0x6bf, (q15_t)0x1c99, (q15_t)0x6c5, (q15_t)0x1ca5, (q15_t)0x6ca, (q15_t)0x1cb0, (q15_t)0x6d0, (q15_t)0x1cbb, + (q15_t)0x6d5, (q15_t)0x1cc6, (q15_t)0x6db, (q15_t)0x1cd2, (q15_t)0x6e1, (q15_t)0x1cdd, (q15_t)0x6e6, (q15_t)0x1ce8, + (q15_t)0x6ec, (q15_t)0x1cf3, (q15_t)0x6f2, (q15_t)0x1cff, (q15_t)0x6f7, (q15_t)0x1d0a, (q15_t)0x6fd, (q15_t)0x1d15, + (q15_t)0x703, (q15_t)0x1d20, (q15_t)0x709, (q15_t)0x1d2b, (q15_t)0x70e, (q15_t)0x1d36, (q15_t)0x714, (q15_t)0x1d42, + (q15_t)0x71a, (q15_t)0x1d4d, (q15_t)0x720, (q15_t)0x1d58, (q15_t)0x725, (q15_t)0x1d63, (q15_t)0x72b, (q15_t)0x1d6e, + (q15_t)0x731, (q15_t)0x1d79, (q15_t)0x737, (q15_t)0x1d85, (q15_t)0x73d, (q15_t)0x1d90, (q15_t)0x742, (q15_t)0x1d9b, + (q15_t)0x748, (q15_t)0x1da6, (q15_t)0x74e, (q15_t)0x1db1, (q15_t)0x754, (q15_t)0x1dbc, (q15_t)0x75a, (q15_t)0x1dc7, + (q15_t)0x75f, (q15_t)0x1dd3, (q15_t)0x765, (q15_t)0x1dde, (q15_t)0x76b, (q15_t)0x1de9, (q15_t)0x771, (q15_t)0x1df4, + (q15_t)0x777, (q15_t)0x1dff, (q15_t)0x77d, (q15_t)0x1e0a, (q15_t)0x783, (q15_t)0x1e15, (q15_t)0x789, (q15_t)0x1e20, + (q15_t)0x78f, (q15_t)0x1e2b, (q15_t)0x795, (q15_t)0x1e36, (q15_t)0x79a, (q15_t)0x1e42, (q15_t)0x7a0, (q15_t)0x1e4d, + (q15_t)0x7a6, (q15_t)0x1e58, (q15_t)0x7ac, (q15_t)0x1e63, (q15_t)0x7b2, (q15_t)0x1e6e, (q15_t)0x7b8, (q15_t)0x1e79, + (q15_t)0x7be, (q15_t)0x1e84, (q15_t)0x7c4, (q15_t)0x1e8f, (q15_t)0x7ca, (q15_t)0x1e9a, (q15_t)0x7d0, (q15_t)0x1ea5, + (q15_t)0x7d6, (q15_t)0x1eb0, (q15_t)0x7dc, (q15_t)0x1ebb, (q15_t)0x7e2, (q15_t)0x1ec6, (q15_t)0x7e8, (q15_t)0x1ed1, + (q15_t)0x7ee, (q15_t)0x1edc, (q15_t)0x7f5, (q15_t)0x1ee7, (q15_t)0x7fb, (q15_t)0x1ef2, (q15_t)0x801, (q15_t)0x1efd, + (q15_t)0x807, (q15_t)0x1f08, (q15_t)0x80d, (q15_t)0x1f13, (q15_t)0x813, (q15_t)0x1f1e, (q15_t)0x819, (q15_t)0x1f29, + (q15_t)0x81f, (q15_t)0x1f34, (q15_t)0x825, (q15_t)0x1f3f, (q15_t)0x82b, (q15_t)0x1f4a, (q15_t)0x832, (q15_t)0x1f55, + (q15_t)0x838, (q15_t)0x1f60, (q15_t)0x83e, (q15_t)0x1f6b, (q15_t)0x844, (q15_t)0x1f76, (q15_t)0x84a, (q15_t)0x1f81, + (q15_t)0x850, (q15_t)0x1f8c, (q15_t)0x857, (q15_t)0x1f97, (q15_t)0x85d, (q15_t)0x1fa2, (q15_t)0x863, (q15_t)0x1fac, + (q15_t)0x869, (q15_t)0x1fb7, (q15_t)0x870, (q15_t)0x1fc2, (q15_t)0x876, (q15_t)0x1fcd, (q15_t)0x87c, (q15_t)0x1fd8, + (q15_t)0x882, (q15_t)0x1fe3, (q15_t)0x889, (q15_t)0x1fee, (q15_t)0x88f, (q15_t)0x1ff9, (q15_t)0x895, (q15_t)0x2004, + (q15_t)0x89b, (q15_t)0x200f, (q15_t)0x8a2, (q15_t)0x2019, (q15_t)0x8a8, (q15_t)0x2024, (q15_t)0x8ae, (q15_t)0x202f, + (q15_t)0x8b5, (q15_t)0x203a, (q15_t)0x8bb, (q15_t)0x2045, (q15_t)0x8c1, (q15_t)0x2050, (q15_t)0x8c8, (q15_t)0x205b, + (q15_t)0x8ce, (q15_t)0x2065, (q15_t)0x8d4, (q15_t)0x2070, (q15_t)0x8db, (q15_t)0x207b, (q15_t)0x8e1, (q15_t)0x2086, + (q15_t)0x8e8, (q15_t)0x2091, (q15_t)0x8ee, (q15_t)0x209b, (q15_t)0x8f4, (q15_t)0x20a6, (q15_t)0x8fb, (q15_t)0x20b1, + (q15_t)0x901, (q15_t)0x20bc, (q15_t)0x908, (q15_t)0x20c7, (q15_t)0x90e, (q15_t)0x20d1, (q15_t)0x915, (q15_t)0x20dc, + (q15_t)0x91b, (q15_t)0x20e7, (q15_t)0x921, (q15_t)0x20f2, (q15_t)0x928, (q15_t)0x20fd, (q15_t)0x92e, (q15_t)0x2107, + (q15_t)0x935, (q15_t)0x2112, (q15_t)0x93b, (q15_t)0x211d, (q15_t)0x942, (q15_t)0x2128, (q15_t)0x948, (q15_t)0x2132, + (q15_t)0x94f, (q15_t)0x213d, (q15_t)0x955, (q15_t)0x2148, (q15_t)0x95c, (q15_t)0x2153, (q15_t)0x963, (q15_t)0x215d, + (q15_t)0x969, (q15_t)0x2168, (q15_t)0x970, (q15_t)0x2173, (q15_t)0x976, (q15_t)0x217d, (q15_t)0x97d, (q15_t)0x2188, + (q15_t)0x983, (q15_t)0x2193, (q15_t)0x98a, (q15_t)0x219e, (q15_t)0x991, (q15_t)0x21a8, (q15_t)0x997, (q15_t)0x21b3, + (q15_t)0x99e, (q15_t)0x21be, (q15_t)0x9a4, (q15_t)0x21c8, (q15_t)0x9ab, (q15_t)0x21d3, (q15_t)0x9b2, (q15_t)0x21de, + (q15_t)0x9b8, (q15_t)0x21e8, (q15_t)0x9bf, (q15_t)0x21f3, (q15_t)0x9c6, (q15_t)0x21fe, (q15_t)0x9cc, (q15_t)0x2208, + (q15_t)0x9d3, (q15_t)0x2213, (q15_t)0x9da, (q15_t)0x221e, (q15_t)0x9e0, (q15_t)0x2228, (q15_t)0x9e7, (q15_t)0x2233, + (q15_t)0x9ee, (q15_t)0x223d, (q15_t)0x9f5, (q15_t)0x2248, (q15_t)0x9fb, (q15_t)0x2253, (q15_t)0xa02, (q15_t)0x225d, + (q15_t)0xa09, (q15_t)0x2268, (q15_t)0xa10, (q15_t)0x2272, (q15_t)0xa16, (q15_t)0x227d, (q15_t)0xa1d, (q15_t)0x2288, + (q15_t)0xa24, (q15_t)0x2292, (q15_t)0xa2b, (q15_t)0x229d, (q15_t)0xa32, (q15_t)0x22a7, (q15_t)0xa38, (q15_t)0x22b2, + (q15_t)0xa3f, (q15_t)0x22bc, (q15_t)0xa46, (q15_t)0x22c7, (q15_t)0xa4d, (q15_t)0x22d2, (q15_t)0xa54, (q15_t)0x22dc, + (q15_t)0xa5b, (q15_t)0x22e7, (q15_t)0xa61, (q15_t)0x22f1, (q15_t)0xa68, (q15_t)0x22fc, (q15_t)0xa6f, (q15_t)0x2306, + (q15_t)0xa76, (q15_t)0x2311, (q15_t)0xa7d, (q15_t)0x231b, (q15_t)0xa84, (q15_t)0x2326, (q15_t)0xa8b, (q15_t)0x2330, + (q15_t)0xa92, (q15_t)0x233b, (q15_t)0xa99, (q15_t)0x2345, (q15_t)0xa9f, (q15_t)0x2350, (q15_t)0xaa6, (q15_t)0x235a, + (q15_t)0xaad, (q15_t)0x2365, (q15_t)0xab4, (q15_t)0x236f, (q15_t)0xabb, (q15_t)0x237a, (q15_t)0xac2, (q15_t)0x2384, + (q15_t)0xac9, (q15_t)0x238e, (q15_t)0xad0, (q15_t)0x2399, (q15_t)0xad7, (q15_t)0x23a3, (q15_t)0xade, (q15_t)0x23ae, + (q15_t)0xae5, (q15_t)0x23b8, (q15_t)0xaec, (q15_t)0x23c3, (q15_t)0xaf3, (q15_t)0x23cd, (q15_t)0xafa, (q15_t)0x23d7, + (q15_t)0xb01, (q15_t)0x23e2, (q15_t)0xb08, (q15_t)0x23ec, (q15_t)0xb0f, (q15_t)0x23f7, (q15_t)0xb16, (q15_t)0x2401, + (q15_t)0xb1e, (q15_t)0x240b, (q15_t)0xb25, (q15_t)0x2416, (q15_t)0xb2c, (q15_t)0x2420, (q15_t)0xb33, (q15_t)0x242b, + (q15_t)0xb3a, (q15_t)0x2435, (q15_t)0xb41, (q15_t)0x243f, (q15_t)0xb48, (q15_t)0x244a, (q15_t)0xb4f, (q15_t)0x2454, + (q15_t)0xb56, (q15_t)0x245e, (q15_t)0xb5e, (q15_t)0x2469, (q15_t)0xb65, (q15_t)0x2473, (q15_t)0xb6c, (q15_t)0x247d, + (q15_t)0xb73, (q15_t)0x2488, (q15_t)0xb7a, (q15_t)0x2492, (q15_t)0xb81, (q15_t)0x249c, (q15_t)0xb89, (q15_t)0x24a7, + (q15_t)0xb90, (q15_t)0x24b1, (q15_t)0xb97, (q15_t)0x24bb, (q15_t)0xb9e, (q15_t)0x24c5, (q15_t)0xba5, (q15_t)0x24d0, + (q15_t)0xbad, (q15_t)0x24da, (q15_t)0xbb4, (q15_t)0x24e4, (q15_t)0xbbb, (q15_t)0x24ef, (q15_t)0xbc2, (q15_t)0x24f9, + (q15_t)0xbca, (q15_t)0x2503, (q15_t)0xbd1, (q15_t)0x250d, (q15_t)0xbd8, (q15_t)0x2518, (q15_t)0xbe0, (q15_t)0x2522, + (q15_t)0xbe7, (q15_t)0x252c, (q15_t)0xbee, (q15_t)0x2536, (q15_t)0xbf5, (q15_t)0x2541, (q15_t)0xbfd, (q15_t)0x254b, + (q15_t)0xc04, (q15_t)0x2555, (q15_t)0xc0b, (q15_t)0x255f, (q15_t)0xc13, (q15_t)0x2569, (q15_t)0xc1a, (q15_t)0x2574, + (q15_t)0xc21, (q15_t)0x257e, (q15_t)0xc29, (q15_t)0x2588, (q15_t)0xc30, (q15_t)0x2592, (q15_t)0xc38, (q15_t)0x259c, + (q15_t)0xc3f, (q15_t)0x25a6, (q15_t)0xc46, (q15_t)0x25b1, (q15_t)0xc4e, (q15_t)0x25bb, (q15_t)0xc55, (q15_t)0x25c5, + (q15_t)0xc5d, (q15_t)0x25cf, (q15_t)0xc64, (q15_t)0x25d9, (q15_t)0xc6b, (q15_t)0x25e3, (q15_t)0xc73, (q15_t)0x25ed, + (q15_t)0xc7a, (q15_t)0x25f8, (q15_t)0xc82, (q15_t)0x2602, (q15_t)0xc89, (q15_t)0x260c, (q15_t)0xc91, (q15_t)0x2616, + (q15_t)0xc98, (q15_t)0x2620, (q15_t)0xca0, (q15_t)0x262a, (q15_t)0xca7, (q15_t)0x2634, (q15_t)0xcaf, (q15_t)0x263e, + (q15_t)0xcb6, (q15_t)0x2648, (q15_t)0xcbe, (q15_t)0x2652, (q15_t)0xcc5, (q15_t)0x265c, (q15_t)0xccd, (q15_t)0x2666, + (q15_t)0xcd4, (q15_t)0x2671, (q15_t)0xcdc, (q15_t)0x267b, (q15_t)0xce3, (q15_t)0x2685, (q15_t)0xceb, (q15_t)0x268f, + (q15_t)0xcf3, (q15_t)0x2699, (q15_t)0xcfa, (q15_t)0x26a3, (q15_t)0xd02, (q15_t)0x26ad, (q15_t)0xd09, (q15_t)0x26b7, + (q15_t)0xd11, (q15_t)0x26c1, (q15_t)0xd19, (q15_t)0x26cb, (q15_t)0xd20, (q15_t)0x26d5, (q15_t)0xd28, (q15_t)0x26df, + (q15_t)0xd30, (q15_t)0x26e9, (q15_t)0xd37, (q15_t)0x26f3, (q15_t)0xd3f, (q15_t)0x26fd, (q15_t)0xd46, (q15_t)0x2707, + (q15_t)0xd4e, (q15_t)0x2711, (q15_t)0xd56, (q15_t)0x271a, (q15_t)0xd5d, (q15_t)0x2724, (q15_t)0xd65, (q15_t)0x272e, + (q15_t)0xd6d, (q15_t)0x2738, (q15_t)0xd75, (q15_t)0x2742, (q15_t)0xd7c, (q15_t)0x274c, (q15_t)0xd84, (q15_t)0x2756, + (q15_t)0xd8c, (q15_t)0x2760, (q15_t)0xd93, (q15_t)0x276a, (q15_t)0xd9b, (q15_t)0x2774, (q15_t)0xda3, (q15_t)0x277e, + (q15_t)0xdab, (q15_t)0x2788, (q15_t)0xdb2, (q15_t)0x2791, (q15_t)0xdba, (q15_t)0x279b, (q15_t)0xdc2, (q15_t)0x27a5, + (q15_t)0xdca, (q15_t)0x27af, (q15_t)0xdd2, (q15_t)0x27b9, (q15_t)0xdd9, (q15_t)0x27c3, (q15_t)0xde1, (q15_t)0x27cd, + (q15_t)0xde9, (q15_t)0x27d6, (q15_t)0xdf1, (q15_t)0x27e0, (q15_t)0xdf9, (q15_t)0x27ea, (q15_t)0xe01, (q15_t)0x27f4, + (q15_t)0xe08, (q15_t)0x27fe, (q15_t)0xe10, (q15_t)0x2808, (q15_t)0xe18, (q15_t)0x2811, (q15_t)0xe20, (q15_t)0x281b, + (q15_t)0xe28, (q15_t)0x2825, (q15_t)0xe30, (q15_t)0x282f, (q15_t)0xe38, (q15_t)0x2838, (q15_t)0xe40, (q15_t)0x2842, + (q15_t)0xe47, (q15_t)0x284c, (q15_t)0xe4f, (q15_t)0x2856, (q15_t)0xe57, (q15_t)0x2860, (q15_t)0xe5f, (q15_t)0x2869, + (q15_t)0xe67, (q15_t)0x2873, (q15_t)0xe6f, (q15_t)0x287d, (q15_t)0xe77, (q15_t)0x2886, (q15_t)0xe7f, (q15_t)0x2890, + (q15_t)0xe87, (q15_t)0x289a, (q15_t)0xe8f, (q15_t)0x28a4, (q15_t)0xe97, (q15_t)0x28ad, (q15_t)0xe9f, (q15_t)0x28b7, + (q15_t)0xea7, (q15_t)0x28c1, (q15_t)0xeaf, (q15_t)0x28ca, (q15_t)0xeb7, (q15_t)0x28d4, (q15_t)0xebf, (q15_t)0x28de, + (q15_t)0xec7, (q15_t)0x28e7, (q15_t)0xecf, (q15_t)0x28f1, (q15_t)0xed7, (q15_t)0x28fb, (q15_t)0xedf, (q15_t)0x2904, + (q15_t)0xee7, (q15_t)0x290e, (q15_t)0xeef, (q15_t)0x2918, (q15_t)0xef7, (q15_t)0x2921, (q15_t)0xeff, (q15_t)0x292b, + (q15_t)0xf07, (q15_t)0x2935, (q15_t)0xf10, (q15_t)0x293e, (q15_t)0xf18, (q15_t)0x2948, (q15_t)0xf20, (q15_t)0x2951, + (q15_t)0xf28, (q15_t)0x295b, (q15_t)0xf30, (q15_t)0x2965, (q15_t)0xf38, (q15_t)0x296e, (q15_t)0xf40, (q15_t)0x2978, + (q15_t)0xf48, (q15_t)0x2981, (q15_t)0xf51, (q15_t)0x298b, (q15_t)0xf59, (q15_t)0x2994, (q15_t)0xf61, (q15_t)0x299e, + (q15_t)0xf69, (q15_t)0x29a7, (q15_t)0xf71, (q15_t)0x29b1, (q15_t)0xf79, (q15_t)0x29bb, (q15_t)0xf82, (q15_t)0x29c4, + (q15_t)0xf8a, (q15_t)0x29ce, (q15_t)0xf92, (q15_t)0x29d7, (q15_t)0xf9a, (q15_t)0x29e1, (q15_t)0xfa3, (q15_t)0x29ea, + (q15_t)0xfab, (q15_t)0x29f4, (q15_t)0xfb3, (q15_t)0x29fd, (q15_t)0xfbb, (q15_t)0x2a07, (q15_t)0xfc4, (q15_t)0x2a10, + (q15_t)0xfcc, (q15_t)0x2a1a, (q15_t)0xfd4, (q15_t)0x2a23, (q15_t)0xfdc, (q15_t)0x2a2c, (q15_t)0xfe5, (q15_t)0x2a36, + (q15_t)0xfed, (q15_t)0x2a3f, (q15_t)0xff5, (q15_t)0x2a49, (q15_t)0xffe, (q15_t)0x2a52, (q15_t)0x1006, (q15_t)0x2a5c, + (q15_t)0x100e, (q15_t)0x2a65, (q15_t)0x1016, (q15_t)0x2a6e, (q15_t)0x101f, (q15_t)0x2a78, (q15_t)0x1027, (q15_t)0x2a81, + (q15_t)0x1030, (q15_t)0x2a8b, (q15_t)0x1038, (q15_t)0x2a94, (q15_t)0x1040, (q15_t)0x2a9d, (q15_t)0x1049, (q15_t)0x2aa7, + (q15_t)0x1051, (q15_t)0x2ab0, (q15_t)0x1059, (q15_t)0x2ab9, (q15_t)0x1062, (q15_t)0x2ac3, (q15_t)0x106a, (q15_t)0x2acc, + (q15_t)0x1073, (q15_t)0x2ad6, (q15_t)0x107b, (q15_t)0x2adf, (q15_t)0x1083, (q15_t)0x2ae8, (q15_t)0x108c, (q15_t)0x2af2, + (q15_t)0x1094, (q15_t)0x2afb, (q15_t)0x109d, (q15_t)0x2b04, (q15_t)0x10a5, (q15_t)0x2b0d, (q15_t)0x10ae, (q15_t)0x2b17, + (q15_t)0x10b6, (q15_t)0x2b20, (q15_t)0x10bf, (q15_t)0x2b29, (q15_t)0x10c7, (q15_t)0x2b33, (q15_t)0x10d0, (q15_t)0x2b3c, + (q15_t)0x10d8, (q15_t)0x2b45, (q15_t)0x10e0, (q15_t)0x2b4e, (q15_t)0x10e9, (q15_t)0x2b58, (q15_t)0x10f2, (q15_t)0x2b61, + (q15_t)0x10fa, (q15_t)0x2b6a, (q15_t)0x1103, (q15_t)0x2b73, (q15_t)0x110b, (q15_t)0x2b7d, (q15_t)0x1114, (q15_t)0x2b86, + (q15_t)0x111c, (q15_t)0x2b8f, (q15_t)0x1125, (q15_t)0x2b98, (q15_t)0x112d, (q15_t)0x2ba1, (q15_t)0x1136, (q15_t)0x2bab, + (q15_t)0x113e, (q15_t)0x2bb4, (q15_t)0x1147, (q15_t)0x2bbd, (q15_t)0x1150, (q15_t)0x2bc6, (q15_t)0x1158, (q15_t)0x2bcf, + (q15_t)0x1161, (q15_t)0x2bd8, (q15_t)0x1169, (q15_t)0x2be2, (q15_t)0x1172, (q15_t)0x2beb, (q15_t)0x117b, (q15_t)0x2bf4, + (q15_t)0x1183, (q15_t)0x2bfd, (q15_t)0x118c, (q15_t)0x2c06, (q15_t)0x1195, (q15_t)0x2c0f, (q15_t)0x119d, (q15_t)0x2c18, + (q15_t)0x11a6, (q15_t)0x2c21, (q15_t)0x11af, (q15_t)0x2c2b, (q15_t)0x11b7, (q15_t)0x2c34, (q15_t)0x11c0, (q15_t)0x2c3d, + (q15_t)0x11c9, (q15_t)0x2c46, (q15_t)0x11d1, (q15_t)0x2c4f, (q15_t)0x11da, (q15_t)0x2c58, (q15_t)0x11e3, (q15_t)0x2c61, + (q15_t)0x11eb, (q15_t)0x2c6a, (q15_t)0x11f4, (q15_t)0x2c73, (q15_t)0x11fd, (q15_t)0x2c7c, (q15_t)0x1206, (q15_t)0x2c85, + (q15_t)0x120e, (q15_t)0x2c8e, (q15_t)0x1217, (q15_t)0x2c97, (q15_t)0x1220, (q15_t)0x2ca0, (q15_t)0x1229, (q15_t)0x2ca9, + (q15_t)0x1231, (q15_t)0x2cb2, (q15_t)0x123a, (q15_t)0x2cbb, (q15_t)0x1243, (q15_t)0x2cc4, (q15_t)0x124c, (q15_t)0x2ccd, + (q15_t)0x1255, (q15_t)0x2cd6, (q15_t)0x125d, (q15_t)0x2cdf, (q15_t)0x1266, (q15_t)0x2ce8, (q15_t)0x126f, (q15_t)0x2cf1, + (q15_t)0x1278, (q15_t)0x2cfa, (q15_t)0x1281, (q15_t)0x2d03, (q15_t)0x128a, (q15_t)0x2d0c, (q15_t)0x1292, (q15_t)0x2d15, + (q15_t)0x129b, (q15_t)0x2d1e, (q15_t)0x12a4, (q15_t)0x2d27, (q15_t)0x12ad, (q15_t)0x2d2f, (q15_t)0x12b6, (q15_t)0x2d38, + (q15_t)0x12bf, (q15_t)0x2d41, (q15_t)0x12c8, (q15_t)0x2d4a, (q15_t)0x12d1, (q15_t)0x2d53, (q15_t)0x12d9, (q15_t)0x2d5c, + (q15_t)0x12e2, (q15_t)0x2d65, (q15_t)0x12eb, (q15_t)0x2d6e, (q15_t)0x12f4, (q15_t)0x2d76, (q15_t)0x12fd, (q15_t)0x2d7f, + (q15_t)0x1306, (q15_t)0x2d88, (q15_t)0x130f, (q15_t)0x2d91, (q15_t)0x1318, (q15_t)0x2d9a, (q15_t)0x1321, (q15_t)0x2da3, + (q15_t)0x132a, (q15_t)0x2dab, (q15_t)0x1333, (q15_t)0x2db4, (q15_t)0x133c, (q15_t)0x2dbd, (q15_t)0x1345, (q15_t)0x2dc6, + (q15_t)0x134e, (q15_t)0x2dcf, (q15_t)0x1357, (q15_t)0x2dd7, (q15_t)0x1360, (q15_t)0x2de0, (q15_t)0x1369, (q15_t)0x2de9, + (q15_t)0x1372, (q15_t)0x2df2, (q15_t)0x137b, (q15_t)0x2dfa, (q15_t)0x1384, (q15_t)0x2e03, (q15_t)0x138d, (q15_t)0x2e0c, + (q15_t)0x1396, (q15_t)0x2e15, (q15_t)0x139f, (q15_t)0x2e1d, (q15_t)0x13a8, (q15_t)0x2e26, (q15_t)0x13b1, (q15_t)0x2e2f, + (q15_t)0x13ba, (q15_t)0x2e37, (q15_t)0x13c3, (q15_t)0x2e40, (q15_t)0x13cc, (q15_t)0x2e49, (q15_t)0x13d5, (q15_t)0x2e51, + (q15_t)0x13df, (q15_t)0x2e5a, (q15_t)0x13e8, (q15_t)0x2e63, (q15_t)0x13f1, (q15_t)0x2e6b, (q15_t)0x13fa, (q15_t)0x2e74, + (q15_t)0x1403, (q15_t)0x2e7d, (q15_t)0x140c, (q15_t)0x2e85, (q15_t)0x1415, (q15_t)0x2e8e, (q15_t)0x141e, (q15_t)0x2e97, + (q15_t)0x1428, (q15_t)0x2e9f, (q15_t)0x1431, (q15_t)0x2ea8, (q15_t)0x143a, (q15_t)0x2eb0, (q15_t)0x1443, (q15_t)0x2eb9, + (q15_t)0x144c, (q15_t)0x2ec2, (q15_t)0x1455, (q15_t)0x2eca, (q15_t)0x145f, (q15_t)0x2ed3, (q15_t)0x1468, (q15_t)0x2edb, + (q15_t)0x1471, (q15_t)0x2ee4, (q15_t)0x147a, (q15_t)0x2eec, (q15_t)0x1483, (q15_t)0x2ef5, (q15_t)0x148d, (q15_t)0x2efd, + (q15_t)0x1496, (q15_t)0x2f06, (q15_t)0x149f, (q15_t)0x2f0e, (q15_t)0x14a8, (q15_t)0x2f17, (q15_t)0x14b2, (q15_t)0x2f20, + (q15_t)0x14bb, (q15_t)0x2f28, (q15_t)0x14c4, (q15_t)0x2f30, (q15_t)0x14cd, (q15_t)0x2f39, (q15_t)0x14d7, (q15_t)0x2f41, + (q15_t)0x14e0, (q15_t)0x2f4a, (q15_t)0x14e9, (q15_t)0x2f52, (q15_t)0x14f3, (q15_t)0x2f5b, (q15_t)0x14fc, (q15_t)0x2f63, + (q15_t)0x1505, (q15_t)0x2f6c, (q15_t)0x150e, (q15_t)0x2f74, (q15_t)0x1518, (q15_t)0x2f7d, (q15_t)0x1521, (q15_t)0x2f85, + (q15_t)0x152a, (q15_t)0x2f8d, (q15_t)0x1534, (q15_t)0x2f96, (q15_t)0x153d, (q15_t)0x2f9e, (q15_t)0x1547, (q15_t)0x2fa7, + (q15_t)0x1550, (q15_t)0x2faf, (q15_t)0x1559, (q15_t)0x2fb7, (q15_t)0x1563, (q15_t)0x2fc0, (q15_t)0x156c, (q15_t)0x2fc8, + (q15_t)0x1575, (q15_t)0x2fd0, (q15_t)0x157f, (q15_t)0x2fd9, (q15_t)0x1588, (q15_t)0x2fe1, (q15_t)0x1592, (q15_t)0x2fea, + (q15_t)0x159b, (q15_t)0x2ff2, (q15_t)0x15a4, (q15_t)0x2ffa, (q15_t)0x15ae, (q15_t)0x3002, (q15_t)0x15b7, (q15_t)0x300b, + (q15_t)0x15c1, (q15_t)0x3013, (q15_t)0x15ca, (q15_t)0x301b, (q15_t)0x15d4, (q15_t)0x3024, (q15_t)0x15dd, (q15_t)0x302c, + (q15_t)0x15e6, (q15_t)0x3034, (q15_t)0x15f0, (q15_t)0x303c, (q15_t)0x15f9, (q15_t)0x3045, (q15_t)0x1603, (q15_t)0x304d, + (q15_t)0x160c, (q15_t)0x3055, (q15_t)0x1616, (q15_t)0x305d, (q15_t)0x161f, (q15_t)0x3066, (q15_t)0x1629, (q15_t)0x306e, + (q15_t)0x1632, (q15_t)0x3076, (q15_t)0x163c, (q15_t)0x307e, (q15_t)0x1645, (q15_t)0x3087, (q15_t)0x164f, (q15_t)0x308f, + (q15_t)0x1659, (q15_t)0x3097, (q15_t)0x1662, (q15_t)0x309f, (q15_t)0x166c, (q15_t)0x30a7, (q15_t)0x1675, (q15_t)0x30af, + (q15_t)0x167f, (q15_t)0x30b8, (q15_t)0x1688, (q15_t)0x30c0, (q15_t)0x1692, (q15_t)0x30c8, (q15_t)0x169b, (q15_t)0x30d0, + (q15_t)0x16a5, (q15_t)0x30d8, (q15_t)0x16af, (q15_t)0x30e0, (q15_t)0x16b8, (q15_t)0x30e8, (q15_t)0x16c2, (q15_t)0x30f0, + (q15_t)0x16cb, (q15_t)0x30f9, (q15_t)0x16d5, (q15_t)0x3101, (q15_t)0x16df, (q15_t)0x3109, (q15_t)0x16e8, (q15_t)0x3111, + (q15_t)0x16f2, (q15_t)0x3119, (q15_t)0x16fc, (q15_t)0x3121, (q15_t)0x1705, (q15_t)0x3129, (q15_t)0x170f, (q15_t)0x3131, + (q15_t)0x1719, (q15_t)0x3139, (q15_t)0x1722, (q15_t)0x3141, (q15_t)0x172c, (q15_t)0x3149, (q15_t)0x1736, (q15_t)0x3151, + (q15_t)0x173f, (q15_t)0x3159, (q15_t)0x1749, (q15_t)0x3161, (q15_t)0x1753, (q15_t)0x3169, (q15_t)0x175c, (q15_t)0x3171, + (q15_t)0x1766, (q15_t)0x3179, (q15_t)0x1770, (q15_t)0x3181, (q15_t)0x177a, (q15_t)0x3189, (q15_t)0x1783, (q15_t)0x3191, + (q15_t)0x178d, (q15_t)0x3199, (q15_t)0x1797, (q15_t)0x31a1, (q15_t)0x17a0, (q15_t)0x31a9, (q15_t)0x17aa, (q15_t)0x31b1, + (q15_t)0x17b4, (q15_t)0x31b9, (q15_t)0x17be, (q15_t)0x31c0, (q15_t)0x17c8, (q15_t)0x31c8, (q15_t)0x17d1, (q15_t)0x31d0, + (q15_t)0x17db, (q15_t)0x31d8, (q15_t)0x17e5, (q15_t)0x31e0, (q15_t)0x17ef, (q15_t)0x31e8, (q15_t)0x17f8, (q15_t)0x31f0, + (q15_t)0x1802, (q15_t)0x31f8, (q15_t)0x180c, (q15_t)0x31ff, (q15_t)0x1816, (q15_t)0x3207, (q15_t)0x1820, (q15_t)0x320f, + (q15_t)0x182a, (q15_t)0x3217, (q15_t)0x1833, (q15_t)0x321f, (q15_t)0x183d, (q15_t)0x3227, (q15_t)0x1847, (q15_t)0x322e, + (q15_t)0x1851, (q15_t)0x3236, (q15_t)0x185b, (q15_t)0x323e, (q15_t)0x1865, (q15_t)0x3246, (q15_t)0x186f, (q15_t)0x324e, + (q15_t)0x1878, (q15_t)0x3255, (q15_t)0x1882, (q15_t)0x325d, (q15_t)0x188c, (q15_t)0x3265, (q15_t)0x1896, (q15_t)0x326d, + (q15_t)0x18a0, (q15_t)0x3274, (q15_t)0x18aa, (q15_t)0x327c, (q15_t)0x18b4, (q15_t)0x3284, (q15_t)0x18be, (q15_t)0x328b, + (q15_t)0x18c8, (q15_t)0x3293, (q15_t)0x18d2, (q15_t)0x329b, (q15_t)0x18dc, (q15_t)0x32a3, (q15_t)0x18e6, (q15_t)0x32aa, + (q15_t)0x18ef, (q15_t)0x32b2, (q15_t)0x18f9, (q15_t)0x32ba, (q15_t)0x1903, (q15_t)0x32c1, (q15_t)0x190d, (q15_t)0x32c9, + (q15_t)0x1917, (q15_t)0x32d0, (q15_t)0x1921, (q15_t)0x32d8, (q15_t)0x192b, (q15_t)0x32e0, (q15_t)0x1935, (q15_t)0x32e7, + (q15_t)0x193f, (q15_t)0x32ef, (q15_t)0x1949, (q15_t)0x32f7, (q15_t)0x1953, (q15_t)0x32fe, (q15_t)0x195d, (q15_t)0x3306, + (q15_t)0x1967, (q15_t)0x330d, (q15_t)0x1971, (q15_t)0x3315, (q15_t)0x197b, (q15_t)0x331d, (q15_t)0x1985, (q15_t)0x3324, + (q15_t)0x198f, (q15_t)0x332c, (q15_t)0x199a, (q15_t)0x3333, (q15_t)0x19a4, (q15_t)0x333b, (q15_t)0x19ae, (q15_t)0x3342, + (q15_t)0x19b8, (q15_t)0x334a, (q15_t)0x19c2, (q15_t)0x3351, (q15_t)0x19cc, (q15_t)0x3359, (q15_t)0x19d6, (q15_t)0x3360, + (q15_t)0x19e0, (q15_t)0x3368, (q15_t)0x19ea, (q15_t)0x336f, (q15_t)0x19f4, (q15_t)0x3377, (q15_t)0x19fe, (q15_t)0x337e, + (q15_t)0x1a08, (q15_t)0x3386, (q15_t)0x1a13, (q15_t)0x338d, (q15_t)0x1a1d, (q15_t)0x3395, (q15_t)0x1a27, (q15_t)0x339c, + (q15_t)0x1a31, (q15_t)0x33a3, (q15_t)0x1a3b, (q15_t)0x33ab, (q15_t)0x1a45, (q15_t)0x33b2, (q15_t)0x1a4f, (q15_t)0x33ba, + (q15_t)0x1a5a, (q15_t)0x33c1, (q15_t)0x1a64, (q15_t)0x33c8, (q15_t)0x1a6e, (q15_t)0x33d0, (q15_t)0x1a78, (q15_t)0x33d7, + (q15_t)0x1a82, (q15_t)0x33df, (q15_t)0x1a8c, (q15_t)0x33e6, (q15_t)0x1a97, (q15_t)0x33ed, (q15_t)0x1aa1, (q15_t)0x33f5, + (q15_t)0x1aab, (q15_t)0x33fc, (q15_t)0x1ab5, (q15_t)0x3403, (q15_t)0x1abf, (q15_t)0x340b, (q15_t)0x1aca, (q15_t)0x3412, + (q15_t)0x1ad4, (q15_t)0x3419, (q15_t)0x1ade, (q15_t)0x3420, (q15_t)0x1ae8, (q15_t)0x3428, (q15_t)0x1af3, (q15_t)0x342f, + (q15_t)0x1afd, (q15_t)0x3436, (q15_t)0x1b07, (q15_t)0x343e, (q15_t)0x1b11, (q15_t)0x3445, (q15_t)0x1b1c, (q15_t)0x344c, + (q15_t)0x1b26, (q15_t)0x3453, (q15_t)0x1b30, (q15_t)0x345b, (q15_t)0x1b3b, (q15_t)0x3462, (q15_t)0x1b45, (q15_t)0x3469, + (q15_t)0x1b4f, (q15_t)0x3470, (q15_t)0x1b59, (q15_t)0x3477, (q15_t)0x1b64, (q15_t)0x347f, (q15_t)0x1b6e, (q15_t)0x3486, + (q15_t)0x1b78, (q15_t)0x348d, (q15_t)0x1b83, (q15_t)0x3494, (q15_t)0x1b8d, (q15_t)0x349b, (q15_t)0x1b97, (q15_t)0x34a2, + (q15_t)0x1ba2, (q15_t)0x34aa, (q15_t)0x1bac, (q15_t)0x34b1, (q15_t)0x1bb6, (q15_t)0x34b8, (q15_t)0x1bc1, (q15_t)0x34bf, + (q15_t)0x1bcb, (q15_t)0x34c6, (q15_t)0x1bd5, (q15_t)0x34cd, (q15_t)0x1be0, (q15_t)0x34d4, (q15_t)0x1bea, (q15_t)0x34db, + (q15_t)0x1bf5, (q15_t)0x34e2, (q15_t)0x1bff, (q15_t)0x34ea, (q15_t)0x1c09, (q15_t)0x34f1, (q15_t)0x1c14, (q15_t)0x34f8, + (q15_t)0x1c1e, (q15_t)0x34ff, (q15_t)0x1c29, (q15_t)0x3506, (q15_t)0x1c33, (q15_t)0x350d, (q15_t)0x1c3d, (q15_t)0x3514, + (q15_t)0x1c48, (q15_t)0x351b, (q15_t)0x1c52, (q15_t)0x3522, (q15_t)0x1c5d, (q15_t)0x3529, (q15_t)0x1c67, (q15_t)0x3530, + (q15_t)0x1c72, (q15_t)0x3537, (q15_t)0x1c7c, (q15_t)0x353e, (q15_t)0x1c86, (q15_t)0x3545, (q15_t)0x1c91, (q15_t)0x354c, + (q15_t)0x1c9b, (q15_t)0x3553, (q15_t)0x1ca6, (q15_t)0x355a, (q15_t)0x1cb0, (q15_t)0x3561, (q15_t)0x1cbb, (q15_t)0x3567, + (q15_t)0x1cc5, (q15_t)0x356e, (q15_t)0x1cd0, (q15_t)0x3575, (q15_t)0x1cda, (q15_t)0x357c, (q15_t)0x1ce5, (q15_t)0x3583, + (q15_t)0x1cef, (q15_t)0x358a, (q15_t)0x1cfa, (q15_t)0x3591, (q15_t)0x1d04, (q15_t)0x3598, (q15_t)0x1d0f, (q15_t)0x359f, + (q15_t)0x1d19, (q15_t)0x35a5, (q15_t)0x1d24, (q15_t)0x35ac, (q15_t)0x1d2e, (q15_t)0x35b3, (q15_t)0x1d39, (q15_t)0x35ba, + (q15_t)0x1d44, (q15_t)0x35c1, (q15_t)0x1d4e, (q15_t)0x35c8, (q15_t)0x1d59, (q15_t)0x35ce, (q15_t)0x1d63, (q15_t)0x35d5, + (q15_t)0x1d6e, (q15_t)0x35dc, (q15_t)0x1d78, (q15_t)0x35e3, (q15_t)0x1d83, (q15_t)0x35ea, (q15_t)0x1d8e, (q15_t)0x35f0, + (q15_t)0x1d98, (q15_t)0x35f7, (q15_t)0x1da3, (q15_t)0x35fe, (q15_t)0x1dad, (q15_t)0x3605, (q15_t)0x1db8, (q15_t)0x360b, + (q15_t)0x1dc3, (q15_t)0x3612, (q15_t)0x1dcd, (q15_t)0x3619, (q15_t)0x1dd8, (q15_t)0x3620, (q15_t)0x1de2, (q15_t)0x3626, + (q15_t)0x1ded, (q15_t)0x362d, (q15_t)0x1df8, (q15_t)0x3634, (q15_t)0x1e02, (q15_t)0x363a, (q15_t)0x1e0d, (q15_t)0x3641, + (q15_t)0x1e18, (q15_t)0x3648, (q15_t)0x1e22, (q15_t)0x364e, (q15_t)0x1e2d, (q15_t)0x3655, (q15_t)0x1e38, (q15_t)0x365c, + (q15_t)0x1e42, (q15_t)0x3662, (q15_t)0x1e4d, (q15_t)0x3669, (q15_t)0x1e58, (q15_t)0x366f, (q15_t)0x1e62, (q15_t)0x3676, + (q15_t)0x1e6d, (q15_t)0x367d, (q15_t)0x1e78, (q15_t)0x3683, (q15_t)0x1e83, (q15_t)0x368a, (q15_t)0x1e8d, (q15_t)0x3690, + (q15_t)0x1e98, (q15_t)0x3697, (q15_t)0x1ea3, (q15_t)0x369d, (q15_t)0x1ead, (q15_t)0x36a4, (q15_t)0x1eb8, (q15_t)0x36ab, + (q15_t)0x1ec3, (q15_t)0x36b1, (q15_t)0x1ece, (q15_t)0x36b8, (q15_t)0x1ed8, (q15_t)0x36be, (q15_t)0x1ee3, (q15_t)0x36c5, + (q15_t)0x1eee, (q15_t)0x36cb, (q15_t)0x1ef9, (q15_t)0x36d2, (q15_t)0x1f03, (q15_t)0x36d8, (q15_t)0x1f0e, (q15_t)0x36df, + (q15_t)0x1f19, (q15_t)0x36e5, (q15_t)0x1f24, (q15_t)0x36eb, (q15_t)0x1f2f, (q15_t)0x36f2, (q15_t)0x1f39, (q15_t)0x36f8, + (q15_t)0x1f44, (q15_t)0x36ff, (q15_t)0x1f4f, (q15_t)0x3705, (q15_t)0x1f5a, (q15_t)0x370c, (q15_t)0x1f65, (q15_t)0x3712, + (q15_t)0x1f6f, (q15_t)0x3718, (q15_t)0x1f7a, (q15_t)0x371f, (q15_t)0x1f85, (q15_t)0x3725, (q15_t)0x1f90, (q15_t)0x372c, + (q15_t)0x1f9b, (q15_t)0x3732, (q15_t)0x1fa5, (q15_t)0x3738, (q15_t)0x1fb0, (q15_t)0x373f, (q15_t)0x1fbb, (q15_t)0x3745, + (q15_t)0x1fc6, (q15_t)0x374b, (q15_t)0x1fd1, (q15_t)0x3752, (q15_t)0x1fdc, (q15_t)0x3758, (q15_t)0x1fe7, (q15_t)0x375e, + (q15_t)0x1ff1, (q15_t)0x3765, (q15_t)0x1ffc, (q15_t)0x376b, (q15_t)0x2007, (q15_t)0x3771, (q15_t)0x2012, (q15_t)0x3777, + (q15_t)0x201d, (q15_t)0x377e, (q15_t)0x2028, (q15_t)0x3784, (q15_t)0x2033, (q15_t)0x378a, (q15_t)0x203e, (q15_t)0x3790, + (q15_t)0x2049, (q15_t)0x3797, (q15_t)0x2054, (q15_t)0x379d, (q15_t)0x205e, (q15_t)0x37a3, (q15_t)0x2069, (q15_t)0x37a9, + (q15_t)0x2074, (q15_t)0x37b0, (q15_t)0x207f, (q15_t)0x37b6, (q15_t)0x208a, (q15_t)0x37bc, (q15_t)0x2095, (q15_t)0x37c2, + (q15_t)0x20a0, (q15_t)0x37c8, (q15_t)0x20ab, (q15_t)0x37ce, (q15_t)0x20b6, (q15_t)0x37d5, (q15_t)0x20c1, (q15_t)0x37db, + (q15_t)0x20cc, (q15_t)0x37e1, (q15_t)0x20d7, (q15_t)0x37e7, (q15_t)0x20e2, (q15_t)0x37ed, (q15_t)0x20ed, (q15_t)0x37f3, + (q15_t)0x20f8, (q15_t)0x37f9, (q15_t)0x2103, (q15_t)0x37ff, (q15_t)0x210e, (q15_t)0x3805, (q15_t)0x2119, (q15_t)0x380b, + (q15_t)0x2124, (q15_t)0x3812, (q15_t)0x212f, (q15_t)0x3818, (q15_t)0x213a, (q15_t)0x381e, (q15_t)0x2145, (q15_t)0x3824, + (q15_t)0x2150, (q15_t)0x382a, (q15_t)0x215b, (q15_t)0x3830, (q15_t)0x2166, (q15_t)0x3836, (q15_t)0x2171, (q15_t)0x383c, + (q15_t)0x217c, (q15_t)0x3842, (q15_t)0x2187, (q15_t)0x3848, (q15_t)0x2192, (q15_t)0x384e, (q15_t)0x219d, (q15_t)0x3854, + (q15_t)0x21a8, (q15_t)0x385a, (q15_t)0x21b3, (q15_t)0x3860, (q15_t)0x21be, (q15_t)0x3866, (q15_t)0x21ca, (q15_t)0x386b, + (q15_t)0x21d5, (q15_t)0x3871, (q15_t)0x21e0, (q15_t)0x3877, (q15_t)0x21eb, (q15_t)0x387d, (q15_t)0x21f6, (q15_t)0x3883, + (q15_t)0x2201, (q15_t)0x3889, (q15_t)0x220c, (q15_t)0x388f, (q15_t)0x2217, (q15_t)0x3895, (q15_t)0x2222, (q15_t)0x389b, + (q15_t)0x222d, (q15_t)0x38a1, (q15_t)0x2239, (q15_t)0x38a6, (q15_t)0x2244, (q15_t)0x38ac, (q15_t)0x224f, (q15_t)0x38b2, + (q15_t)0x225a, (q15_t)0x38b8, (q15_t)0x2265, (q15_t)0x38be, (q15_t)0x2270, (q15_t)0x38c3, (q15_t)0x227b, (q15_t)0x38c9, + (q15_t)0x2287, (q15_t)0x38cf, (q15_t)0x2292, (q15_t)0x38d5, (q15_t)0x229d, (q15_t)0x38db, (q15_t)0x22a8, (q15_t)0x38e0, + (q15_t)0x22b3, (q15_t)0x38e6, (q15_t)0x22be, (q15_t)0x38ec, (q15_t)0x22ca, (q15_t)0x38f2, (q15_t)0x22d5, (q15_t)0x38f7, + (q15_t)0x22e0, (q15_t)0x38fd, (q15_t)0x22eb, (q15_t)0x3903, (q15_t)0x22f6, (q15_t)0x3909, (q15_t)0x2301, (q15_t)0x390e, + (q15_t)0x230d, (q15_t)0x3914, (q15_t)0x2318, (q15_t)0x391a, (q15_t)0x2323, (q15_t)0x391f, (q15_t)0x232e, (q15_t)0x3925, + (q15_t)0x233a, (q15_t)0x392b, (q15_t)0x2345, (q15_t)0x3930, (q15_t)0x2350, (q15_t)0x3936, (q15_t)0x235b, (q15_t)0x393b, + (q15_t)0x2367, (q15_t)0x3941, (q15_t)0x2372, (q15_t)0x3947, (q15_t)0x237d, (q15_t)0x394c, (q15_t)0x2388, (q15_t)0x3952, + (q15_t)0x2394, (q15_t)0x3958, (q15_t)0x239f, (q15_t)0x395d, (q15_t)0x23aa, (q15_t)0x3963, (q15_t)0x23b5, (q15_t)0x3968, + (q15_t)0x23c1, (q15_t)0x396e, (q15_t)0x23cc, (q15_t)0x3973, (q15_t)0x23d7, (q15_t)0x3979, (q15_t)0x23e2, (q15_t)0x397e, + (q15_t)0x23ee, (q15_t)0x3984, (q15_t)0x23f9, (q15_t)0x3989, (q15_t)0x2404, (q15_t)0x398f, (q15_t)0x2410, (q15_t)0x3994, + (q15_t)0x241b, (q15_t)0x399a, (q15_t)0x2426, (q15_t)0x399f, (q15_t)0x2432, (q15_t)0x39a5, (q15_t)0x243d, (q15_t)0x39aa, + (q15_t)0x2448, (q15_t)0x39b0, (q15_t)0x2454, (q15_t)0x39b5, (q15_t)0x245f, (q15_t)0x39bb, (q15_t)0x246a, (q15_t)0x39c0, + (q15_t)0x2476, (q15_t)0x39c5, (q15_t)0x2481, (q15_t)0x39cb, (q15_t)0x248c, (q15_t)0x39d0, (q15_t)0x2498, (q15_t)0x39d6, + (q15_t)0x24a3, (q15_t)0x39db, (q15_t)0x24ae, (q15_t)0x39e0, (q15_t)0x24ba, (q15_t)0x39e6, (q15_t)0x24c5, (q15_t)0x39eb, + (q15_t)0x24d0, (q15_t)0x39f0, (q15_t)0x24dc, (q15_t)0x39f6, (q15_t)0x24e7, (q15_t)0x39fb, (q15_t)0x24f3, (q15_t)0x3a00, + (q15_t)0x24fe, (q15_t)0x3a06, (q15_t)0x2509, (q15_t)0x3a0b, (q15_t)0x2515, (q15_t)0x3a10, (q15_t)0x2520, (q15_t)0x3a16, + (q15_t)0x252c, (q15_t)0x3a1b, (q15_t)0x2537, (q15_t)0x3a20, (q15_t)0x2542, (q15_t)0x3a25, (q15_t)0x254e, (q15_t)0x3a2b, + (q15_t)0x2559, (q15_t)0x3a30, (q15_t)0x2565, (q15_t)0x3a35, (q15_t)0x2570, (q15_t)0x3a3a, (q15_t)0x257c, (q15_t)0x3a3f, + (q15_t)0x2587, (q15_t)0x3a45, (q15_t)0x2592, (q15_t)0x3a4a, (q15_t)0x259e, (q15_t)0x3a4f, (q15_t)0x25a9, (q15_t)0x3a54, + (q15_t)0x25b5, (q15_t)0x3a59, (q15_t)0x25c0, (q15_t)0x3a5f, (q15_t)0x25cc, (q15_t)0x3a64, (q15_t)0x25d7, (q15_t)0x3a69, + (q15_t)0x25e3, (q15_t)0x3a6e, (q15_t)0x25ee, (q15_t)0x3a73, (q15_t)0x25fa, (q15_t)0x3a78, (q15_t)0x2605, (q15_t)0x3a7d, + (q15_t)0x2611, (q15_t)0x3a82, (q15_t)0x261c, (q15_t)0x3a88, (q15_t)0x2628, (q15_t)0x3a8d, (q15_t)0x2633, (q15_t)0x3a92, + (q15_t)0x263f, (q15_t)0x3a97, (q15_t)0x264a, (q15_t)0x3a9c, (q15_t)0x2656, (q15_t)0x3aa1, (q15_t)0x2661, (q15_t)0x3aa6, + (q15_t)0x266d, (q15_t)0x3aab, (q15_t)0x2678, (q15_t)0x3ab0, (q15_t)0x2684, (q15_t)0x3ab5, (q15_t)0x268f, (q15_t)0x3aba, + (q15_t)0x269b, (q15_t)0x3abf, (q15_t)0x26a6, (q15_t)0x3ac4, (q15_t)0x26b2, (q15_t)0x3ac9, (q15_t)0x26bd, (q15_t)0x3ace, + (q15_t)0x26c9, (q15_t)0x3ad3, (q15_t)0x26d4, (q15_t)0x3ad8, (q15_t)0x26e0, (q15_t)0x3add, (q15_t)0x26ec, (q15_t)0x3ae2, + (q15_t)0x26f7, (q15_t)0x3ae6, (q15_t)0x2703, (q15_t)0x3aeb, (q15_t)0x270e, (q15_t)0x3af0, (q15_t)0x271a, (q15_t)0x3af5, + (q15_t)0x2725, (q15_t)0x3afa, (q15_t)0x2731, (q15_t)0x3aff, (q15_t)0x273d, (q15_t)0x3b04, (q15_t)0x2748, (q15_t)0x3b09, + (q15_t)0x2754, (q15_t)0x3b0e, (q15_t)0x275f, (q15_t)0x3b12, (q15_t)0x276b, (q15_t)0x3b17, (q15_t)0x2777, (q15_t)0x3b1c, + (q15_t)0x2782, (q15_t)0x3b21, (q15_t)0x278e, (q15_t)0x3b26, (q15_t)0x2799, (q15_t)0x3b2a, (q15_t)0x27a5, (q15_t)0x3b2f, + (q15_t)0x27b1, (q15_t)0x3b34, (q15_t)0x27bc, (q15_t)0x3b39, (q15_t)0x27c8, (q15_t)0x3b3e, (q15_t)0x27d3, (q15_t)0x3b42, + (q15_t)0x27df, (q15_t)0x3b47, (q15_t)0x27eb, (q15_t)0x3b4c, (q15_t)0x27f6, (q15_t)0x3b50, (q15_t)0x2802, (q15_t)0x3b55, + (q15_t)0x280e, (q15_t)0x3b5a, (q15_t)0x2819, (q15_t)0x3b5f, (q15_t)0x2825, (q15_t)0x3b63, (q15_t)0x2831, (q15_t)0x3b68, + (q15_t)0x283c, (q15_t)0x3b6d, (q15_t)0x2848, (q15_t)0x3b71, (q15_t)0x2854, (q15_t)0x3b76, (q15_t)0x285f, (q15_t)0x3b7b, + (q15_t)0x286b, (q15_t)0x3b7f, (q15_t)0x2877, (q15_t)0x3b84, (q15_t)0x2882, (q15_t)0x3b88, (q15_t)0x288e, (q15_t)0x3b8d, + (q15_t)0x289a, (q15_t)0x3b92, (q15_t)0x28a5, (q15_t)0x3b96, (q15_t)0x28b1, (q15_t)0x3b9b, (q15_t)0x28bd, (q15_t)0x3b9f, + (q15_t)0x28c9, (q15_t)0x3ba4, (q15_t)0x28d4, (q15_t)0x3ba9, (q15_t)0x28e0, (q15_t)0x3bad, (q15_t)0x28ec, (q15_t)0x3bb2, + (q15_t)0x28f7, (q15_t)0x3bb6, (q15_t)0x2903, (q15_t)0x3bbb, (q15_t)0x290f, (q15_t)0x3bbf, (q15_t)0x291b, (q15_t)0x3bc4, + (q15_t)0x2926, (q15_t)0x3bc8, (q15_t)0x2932, (q15_t)0x3bcd, (q15_t)0x293e, (q15_t)0x3bd1, (q15_t)0x294a, (q15_t)0x3bd6, + (q15_t)0x2955, (q15_t)0x3bda, (q15_t)0x2961, (q15_t)0x3bde, (q15_t)0x296d, (q15_t)0x3be3, (q15_t)0x2979, (q15_t)0x3be7, + (q15_t)0x2984, (q15_t)0x3bec, (q15_t)0x2990, (q15_t)0x3bf0, (q15_t)0x299c, (q15_t)0x3bf5, (q15_t)0x29a8, (q15_t)0x3bf9, + (q15_t)0x29b4, (q15_t)0x3bfd, (q15_t)0x29bf, (q15_t)0x3c02, (q15_t)0x29cb, (q15_t)0x3c06, (q15_t)0x29d7, (q15_t)0x3c0a, + (q15_t)0x29e3, (q15_t)0x3c0f, (q15_t)0x29ee, (q15_t)0x3c13, (q15_t)0x29fa, (q15_t)0x3c17, (q15_t)0x2a06, (q15_t)0x3c1c, + (q15_t)0x2a12, (q15_t)0x3c20, (q15_t)0x2a1e, (q15_t)0x3c24, (q15_t)0x2a29, (q15_t)0x3c29, (q15_t)0x2a35, (q15_t)0x3c2d, + (q15_t)0x2a41, (q15_t)0x3c31, (q15_t)0x2a4d, (q15_t)0x3c36, (q15_t)0x2a59, (q15_t)0x3c3a, (q15_t)0x2a65, (q15_t)0x3c3e, + (q15_t)0x2a70, (q15_t)0x3c42, (q15_t)0x2a7c, (q15_t)0x3c46, (q15_t)0x2a88, (q15_t)0x3c4b, (q15_t)0x2a94, (q15_t)0x3c4f, + (q15_t)0x2aa0, (q15_t)0x3c53, (q15_t)0x2aac, (q15_t)0x3c57, (q15_t)0x2ab7, (q15_t)0x3c5b, (q15_t)0x2ac3, (q15_t)0x3c60, + (q15_t)0x2acf, (q15_t)0x3c64, (q15_t)0x2adb, (q15_t)0x3c68, (q15_t)0x2ae7, (q15_t)0x3c6c, (q15_t)0x2af3, (q15_t)0x3c70, + (q15_t)0x2aff, (q15_t)0x3c74, (q15_t)0x2b0a, (q15_t)0x3c79, (q15_t)0x2b16, (q15_t)0x3c7d, (q15_t)0x2b22, (q15_t)0x3c81, + (q15_t)0x2b2e, (q15_t)0x3c85, (q15_t)0x2b3a, (q15_t)0x3c89, (q15_t)0x2b46, (q15_t)0x3c8d, (q15_t)0x2b52, (q15_t)0x3c91, + (q15_t)0x2b5e, (q15_t)0x3c95, (q15_t)0x2b6a, (q15_t)0x3c99, (q15_t)0x2b75, (q15_t)0x3c9d, (q15_t)0x2b81, (q15_t)0x3ca1, + (q15_t)0x2b8d, (q15_t)0x3ca5, (q15_t)0x2b99, (q15_t)0x3ca9, (q15_t)0x2ba5, (q15_t)0x3cad, (q15_t)0x2bb1, (q15_t)0x3cb1, + (q15_t)0x2bbd, (q15_t)0x3cb5, (q15_t)0x2bc9, (q15_t)0x3cb9, (q15_t)0x2bd5, (q15_t)0x3cbd, (q15_t)0x2be1, (q15_t)0x3cc1, + (q15_t)0x2bed, (q15_t)0x3cc5, (q15_t)0x2bf9, (q15_t)0x3cc9, (q15_t)0x2c05, (q15_t)0x3ccd, (q15_t)0x2c10, (q15_t)0x3cd1, + (q15_t)0x2c1c, (q15_t)0x3cd5, (q15_t)0x2c28, (q15_t)0x3cd9, (q15_t)0x2c34, (q15_t)0x3cdd, (q15_t)0x2c40, (q15_t)0x3ce0, + (q15_t)0x2c4c, (q15_t)0x3ce4, (q15_t)0x2c58, (q15_t)0x3ce8, (q15_t)0x2c64, (q15_t)0x3cec, (q15_t)0x2c70, (q15_t)0x3cf0, + (q15_t)0x2c7c, (q15_t)0x3cf4, (q15_t)0x2c88, (q15_t)0x3cf8, (q15_t)0x2c94, (q15_t)0x3cfb, (q15_t)0x2ca0, (q15_t)0x3cff, + (q15_t)0x2cac, (q15_t)0x3d03, (q15_t)0x2cb8, (q15_t)0x3d07, (q15_t)0x2cc4, (q15_t)0x3d0b, (q15_t)0x2cd0, (q15_t)0x3d0e, + (q15_t)0x2cdc, (q15_t)0x3d12, (q15_t)0x2ce8, (q15_t)0x3d16, (q15_t)0x2cf4, (q15_t)0x3d1a, (q15_t)0x2d00, (q15_t)0x3d1d, + (q15_t)0x2d0c, (q15_t)0x3d21, (q15_t)0x2d18, (q15_t)0x3d25, (q15_t)0x2d24, (q15_t)0x3d28, (q15_t)0x2d30, (q15_t)0x3d2c, + (q15_t)0x2d3c, (q15_t)0x3d30, (q15_t)0x2d48, (q15_t)0x3d34, (q15_t)0x2d54, (q15_t)0x3d37, (q15_t)0x2d60, (q15_t)0x3d3b, + (q15_t)0x2d6c, (q15_t)0x3d3f, (q15_t)0x2d78, (q15_t)0x3d42, (q15_t)0x2d84, (q15_t)0x3d46, (q15_t)0x2d90, (q15_t)0x3d49, + (q15_t)0x2d9c, (q15_t)0x3d4d, (q15_t)0x2da8, (q15_t)0x3d51, (q15_t)0x2db4, (q15_t)0x3d54, (q15_t)0x2dc0, (q15_t)0x3d58, + (q15_t)0x2dcc, (q15_t)0x3d5b, (q15_t)0x2dd8, (q15_t)0x3d5f, (q15_t)0x2de4, (q15_t)0x3d63, (q15_t)0x2df0, (q15_t)0x3d66, + (q15_t)0x2dfc, (q15_t)0x3d6a, (q15_t)0x2e09, (q15_t)0x3d6d, (q15_t)0x2e15, (q15_t)0x3d71, (q15_t)0x2e21, (q15_t)0x3d74, + (q15_t)0x2e2d, (q15_t)0x3d78, (q15_t)0x2e39, (q15_t)0x3d7b, (q15_t)0x2e45, (q15_t)0x3d7f, (q15_t)0x2e51, (q15_t)0x3d82, + (q15_t)0x2e5d, (q15_t)0x3d86, (q15_t)0x2e69, (q15_t)0x3d89, (q15_t)0x2e75, (q15_t)0x3d8d, (q15_t)0x2e81, (q15_t)0x3d90, + (q15_t)0x2e8d, (q15_t)0x3d93, (q15_t)0x2e99, (q15_t)0x3d97, (q15_t)0x2ea6, (q15_t)0x3d9a, (q15_t)0x2eb2, (q15_t)0x3d9e, + (q15_t)0x2ebe, (q15_t)0x3da1, (q15_t)0x2eca, (q15_t)0x3da4, (q15_t)0x2ed6, (q15_t)0x3da8, (q15_t)0x2ee2, (q15_t)0x3dab, + (q15_t)0x2eee, (q15_t)0x3daf, (q15_t)0x2efa, (q15_t)0x3db2, (q15_t)0x2f06, (q15_t)0x3db5, (q15_t)0x2f13, (q15_t)0x3db9, + (q15_t)0x2f1f, (q15_t)0x3dbc, (q15_t)0x2f2b, (q15_t)0x3dbf, (q15_t)0x2f37, (q15_t)0x3dc2, (q15_t)0x2f43, (q15_t)0x3dc6, + (q15_t)0x2f4f, (q15_t)0x3dc9, (q15_t)0x2f5b, (q15_t)0x3dcc, (q15_t)0x2f67, (q15_t)0x3dd0, (q15_t)0x2f74, (q15_t)0x3dd3, + (q15_t)0x2f80, (q15_t)0x3dd6, (q15_t)0x2f8c, (q15_t)0x3dd9, (q15_t)0x2f98, (q15_t)0x3ddd, (q15_t)0x2fa4, (q15_t)0x3de0, + (q15_t)0x2fb0, (q15_t)0x3de3, (q15_t)0x2fbc, (q15_t)0x3de6, (q15_t)0x2fc9, (q15_t)0x3de9, (q15_t)0x2fd5, (q15_t)0x3ded, + (q15_t)0x2fe1, (q15_t)0x3df0, (q15_t)0x2fed, (q15_t)0x3df3, (q15_t)0x2ff9, (q15_t)0x3df6, (q15_t)0x3005, (q15_t)0x3df9, + (q15_t)0x3012, (q15_t)0x3dfc, (q15_t)0x301e, (q15_t)0x3dff, (q15_t)0x302a, (q15_t)0x3e03, (q15_t)0x3036, (q15_t)0x3e06, + (q15_t)0x3042, (q15_t)0x3e09, (q15_t)0x304e, (q15_t)0x3e0c, (q15_t)0x305b, (q15_t)0x3e0f, (q15_t)0x3067, (q15_t)0x3e12, + (q15_t)0x3073, (q15_t)0x3e15, (q15_t)0x307f, (q15_t)0x3e18, (q15_t)0x308b, (q15_t)0x3e1b, (q15_t)0x3098, (q15_t)0x3e1e, + (q15_t)0x30a4, (q15_t)0x3e21, (q15_t)0x30b0, (q15_t)0x3e24, (q15_t)0x30bc, (q15_t)0x3e27, (q15_t)0x30c8, (q15_t)0x3e2a, + (q15_t)0x30d5, (q15_t)0x3e2d, (q15_t)0x30e1, (q15_t)0x3e30, (q15_t)0x30ed, (q15_t)0x3e33, (q15_t)0x30f9, (q15_t)0x3e36, + (q15_t)0x3105, (q15_t)0x3e39, (q15_t)0x3112, (q15_t)0x3e3c, (q15_t)0x311e, (q15_t)0x3e3f, (q15_t)0x312a, (q15_t)0x3e42, + (q15_t)0x3136, (q15_t)0x3e45, (q15_t)0x3143, (q15_t)0x3e48, (q15_t)0x314f, (q15_t)0x3e4a, (q15_t)0x315b, (q15_t)0x3e4d, + (q15_t)0x3167, (q15_t)0x3e50, (q15_t)0x3174, (q15_t)0x3e53, (q15_t)0x3180, (q15_t)0x3e56, (q15_t)0x318c, (q15_t)0x3e59, + (q15_t)0x3198, (q15_t)0x3e5c, (q15_t)0x31a4, (q15_t)0x3e5e, (q15_t)0x31b1, (q15_t)0x3e61, (q15_t)0x31bd, (q15_t)0x3e64, + (q15_t)0x31c9, (q15_t)0x3e67, (q15_t)0x31d5, (q15_t)0x3e6a, (q15_t)0x31e2, (q15_t)0x3e6c, (q15_t)0x31ee, (q15_t)0x3e6f, + (q15_t)0x31fa, (q15_t)0x3e72, (q15_t)0x3207, (q15_t)0x3e75, (q15_t)0x3213, (q15_t)0x3e77, (q15_t)0x321f, (q15_t)0x3e7a, + (q15_t)0x322b, (q15_t)0x3e7d, (q15_t)0x3238, (q15_t)0x3e80, (q15_t)0x3244, (q15_t)0x3e82, (q15_t)0x3250, (q15_t)0x3e85, + (q15_t)0x325c, (q15_t)0x3e88, (q15_t)0x3269, (q15_t)0x3e8a, (q15_t)0x3275, (q15_t)0x3e8d, (q15_t)0x3281, (q15_t)0x3e90, + (q15_t)0x328e, (q15_t)0x3e92, (q15_t)0x329a, (q15_t)0x3e95, (q15_t)0x32a6, (q15_t)0x3e98, (q15_t)0x32b2, (q15_t)0x3e9a, + (q15_t)0x32bf, (q15_t)0x3e9d, (q15_t)0x32cb, (q15_t)0x3e9f, (q15_t)0x32d7, (q15_t)0x3ea2, (q15_t)0x32e4, (q15_t)0x3ea5, + (q15_t)0x32f0, (q15_t)0x3ea7, (q15_t)0x32fc, (q15_t)0x3eaa, (q15_t)0x3308, (q15_t)0x3eac, (q15_t)0x3315, (q15_t)0x3eaf, + (q15_t)0x3321, (q15_t)0x3eb1, (q15_t)0x332d, (q15_t)0x3eb4, (q15_t)0x333a, (q15_t)0x3eb6, (q15_t)0x3346, (q15_t)0x3eb9, + (q15_t)0x3352, (q15_t)0x3ebb, (q15_t)0x335f, (q15_t)0x3ebe, (q15_t)0x336b, (q15_t)0x3ec0, (q15_t)0x3377, (q15_t)0x3ec3, + (q15_t)0x3384, (q15_t)0x3ec5, (q15_t)0x3390, (q15_t)0x3ec8, (q15_t)0x339c, (q15_t)0x3eca, (q15_t)0x33a9, (q15_t)0x3ecc, + (q15_t)0x33b5, (q15_t)0x3ecf, (q15_t)0x33c1, (q15_t)0x3ed1, (q15_t)0x33ce, (q15_t)0x3ed4, (q15_t)0x33da, (q15_t)0x3ed6, + (q15_t)0x33e6, (q15_t)0x3ed8, (q15_t)0x33f3, (q15_t)0x3edb, (q15_t)0x33ff, (q15_t)0x3edd, (q15_t)0x340b, (q15_t)0x3ee0, + (q15_t)0x3418, (q15_t)0x3ee2, (q15_t)0x3424, (q15_t)0x3ee4, (q15_t)0x3430, (q15_t)0x3ee7, (q15_t)0x343d, (q15_t)0x3ee9, + (q15_t)0x3449, (q15_t)0x3eeb, (q15_t)0x3455, (q15_t)0x3eed, (q15_t)0x3462, (q15_t)0x3ef0, (q15_t)0x346e, (q15_t)0x3ef2, + (q15_t)0x347b, (q15_t)0x3ef4, (q15_t)0x3487, (q15_t)0x3ef7, (q15_t)0x3493, (q15_t)0x3ef9, (q15_t)0x34a0, (q15_t)0x3efb, + (q15_t)0x34ac, (q15_t)0x3efd, (q15_t)0x34b8, (q15_t)0x3f00, (q15_t)0x34c5, (q15_t)0x3f02, (q15_t)0x34d1, (q15_t)0x3f04, + (q15_t)0x34dd, (q15_t)0x3f06, (q15_t)0x34ea, (q15_t)0x3f08, (q15_t)0x34f6, (q15_t)0x3f0a, (q15_t)0x3503, (q15_t)0x3f0d, + (q15_t)0x350f, (q15_t)0x3f0f, (q15_t)0x351b, (q15_t)0x3f11, (q15_t)0x3528, (q15_t)0x3f13, (q15_t)0x3534, (q15_t)0x3f15, + (q15_t)0x3540, (q15_t)0x3f17, (q15_t)0x354d, (q15_t)0x3f19, (q15_t)0x3559, (q15_t)0x3f1c, (q15_t)0x3566, (q15_t)0x3f1e, + (q15_t)0x3572, (q15_t)0x3f20, (q15_t)0x357e, (q15_t)0x3f22, (q15_t)0x358b, (q15_t)0x3f24, (q15_t)0x3597, (q15_t)0x3f26, + (q15_t)0x35a4, (q15_t)0x3f28, (q15_t)0x35b0, (q15_t)0x3f2a, (q15_t)0x35bc, (q15_t)0x3f2c, (q15_t)0x35c9, (q15_t)0x3f2e, + (q15_t)0x35d5, (q15_t)0x3f30, (q15_t)0x35e2, (q15_t)0x3f32, (q15_t)0x35ee, (q15_t)0x3f34, (q15_t)0x35fa, (q15_t)0x3f36, + (q15_t)0x3607, (q15_t)0x3f38, (q15_t)0x3613, (q15_t)0x3f3a, (q15_t)0x3620, (q15_t)0x3f3c, (q15_t)0x362c, (q15_t)0x3f3e, + (q15_t)0x3639, (q15_t)0x3f40, (q15_t)0x3645, (q15_t)0x3f42, (q15_t)0x3651, (q15_t)0x3f43, (q15_t)0x365e, (q15_t)0x3f45, + (q15_t)0x366a, (q15_t)0x3f47, (q15_t)0x3677, (q15_t)0x3f49, (q15_t)0x3683, (q15_t)0x3f4b, (q15_t)0x3690, (q15_t)0x3f4d, + (q15_t)0x369c, (q15_t)0x3f4f, (q15_t)0x36a8, (q15_t)0x3f51, (q15_t)0x36b5, (q15_t)0x3f52, (q15_t)0x36c1, (q15_t)0x3f54, + (q15_t)0x36ce, (q15_t)0x3f56, (q15_t)0x36da, (q15_t)0x3f58, (q15_t)0x36e7, (q15_t)0x3f5a, (q15_t)0x36f3, (q15_t)0x3f5b, + (q15_t)0x36ff, (q15_t)0x3f5d, (q15_t)0x370c, (q15_t)0x3f5f, (q15_t)0x3718, (q15_t)0x3f61, (q15_t)0x3725, (q15_t)0x3f62, + (q15_t)0x3731, (q15_t)0x3f64, (q15_t)0x373e, (q15_t)0x3f66, (q15_t)0x374a, (q15_t)0x3f68, (q15_t)0x3757, (q15_t)0x3f69, + (q15_t)0x3763, (q15_t)0x3f6b, (q15_t)0x376f, (q15_t)0x3f6d, (q15_t)0x377c, (q15_t)0x3f6e, (q15_t)0x3788, (q15_t)0x3f70, + (q15_t)0x3795, (q15_t)0x3f72, (q15_t)0x37a1, (q15_t)0x3f73, (q15_t)0x37ae, (q15_t)0x3f75, (q15_t)0x37ba, (q15_t)0x3f77, + (q15_t)0x37c7, (q15_t)0x3f78, (q15_t)0x37d3, (q15_t)0x3f7a, (q15_t)0x37e0, (q15_t)0x3f7b, (q15_t)0x37ec, (q15_t)0x3f7d, + (q15_t)0x37f9, (q15_t)0x3f7f, (q15_t)0x3805, (q15_t)0x3f80, (q15_t)0x3811, (q15_t)0x3f82, (q15_t)0x381e, (q15_t)0x3f83, + (q15_t)0x382a, (q15_t)0x3f85, (q15_t)0x3837, (q15_t)0x3f86, (q15_t)0x3843, (q15_t)0x3f88, (q15_t)0x3850, (q15_t)0x3f89, + (q15_t)0x385c, (q15_t)0x3f8b, (q15_t)0x3869, (q15_t)0x3f8c, (q15_t)0x3875, (q15_t)0x3f8e, (q15_t)0x3882, (q15_t)0x3f8f, + (q15_t)0x388e, (q15_t)0x3f91, (q15_t)0x389b, (q15_t)0x3f92, (q15_t)0x38a7, (q15_t)0x3f94, (q15_t)0x38b4, (q15_t)0x3f95, + (q15_t)0x38c0, (q15_t)0x3f97, (q15_t)0x38cd, (q15_t)0x3f98, (q15_t)0x38d9, (q15_t)0x3f99, (q15_t)0x38e6, (q15_t)0x3f9b, + (q15_t)0x38f2, (q15_t)0x3f9c, (q15_t)0x38ff, (q15_t)0x3f9e, (q15_t)0x390b, (q15_t)0x3f9f, (q15_t)0x3918, (q15_t)0x3fa0, + (q15_t)0x3924, (q15_t)0x3fa2, (q15_t)0x3931, (q15_t)0x3fa3, (q15_t)0x393d, (q15_t)0x3fa4, (q15_t)0x394a, (q15_t)0x3fa6, + (q15_t)0x3956, (q15_t)0x3fa7, (q15_t)0x3963, (q15_t)0x3fa8, (q15_t)0x396f, (q15_t)0x3faa, (q15_t)0x397c, (q15_t)0x3fab, + (q15_t)0x3988, (q15_t)0x3fac, (q15_t)0x3995, (q15_t)0x3fad, (q15_t)0x39a1, (q15_t)0x3faf, (q15_t)0x39ae, (q15_t)0x3fb0, + (q15_t)0x39ba, (q15_t)0x3fb1, (q15_t)0x39c7, (q15_t)0x3fb2, (q15_t)0x39d3, (q15_t)0x3fb4, (q15_t)0x39e0, (q15_t)0x3fb5, + (q15_t)0x39ec, (q15_t)0x3fb6, (q15_t)0x39f9, (q15_t)0x3fb7, (q15_t)0x3a05, (q15_t)0x3fb8, (q15_t)0x3a12, (q15_t)0x3fb9, + (q15_t)0x3a1e, (q15_t)0x3fbb, (q15_t)0x3a2b, (q15_t)0x3fbc, (q15_t)0x3a37, (q15_t)0x3fbd, (q15_t)0x3a44, (q15_t)0x3fbe, + (q15_t)0x3a50, (q15_t)0x3fbf, (q15_t)0x3a5d, (q15_t)0x3fc0, (q15_t)0x3a69, (q15_t)0x3fc1, (q15_t)0x3a76, (q15_t)0x3fc3, + (q15_t)0x3a82, (q15_t)0x3fc4, (q15_t)0x3a8f, (q15_t)0x3fc5, (q15_t)0x3a9b, (q15_t)0x3fc6, (q15_t)0x3aa8, (q15_t)0x3fc7, + (q15_t)0x3ab4, (q15_t)0x3fc8, (q15_t)0x3ac1, (q15_t)0x3fc9, (q15_t)0x3acd, (q15_t)0x3fca, (q15_t)0x3ada, (q15_t)0x3fcb, + (q15_t)0x3ae6, (q15_t)0x3fcc, (q15_t)0x3af3, (q15_t)0x3fcd, (q15_t)0x3b00, (q15_t)0x3fce, (q15_t)0x3b0c, (q15_t)0x3fcf, + (q15_t)0x3b19, (q15_t)0x3fd0, (q15_t)0x3b25, (q15_t)0x3fd1, (q15_t)0x3b32, (q15_t)0x3fd2, (q15_t)0x3b3e, (q15_t)0x3fd3, + (q15_t)0x3b4b, (q15_t)0x3fd4, (q15_t)0x3b57, (q15_t)0x3fd5, (q15_t)0x3b64, (q15_t)0x3fd5, (q15_t)0x3b70, (q15_t)0x3fd6, + (q15_t)0x3b7d, (q15_t)0x3fd7, (q15_t)0x3b89, (q15_t)0x3fd8, (q15_t)0x3b96, (q15_t)0x3fd9, (q15_t)0x3ba2, (q15_t)0x3fda, + (q15_t)0x3baf, (q15_t)0x3fdb, (q15_t)0x3bbc, (q15_t)0x3fdc, (q15_t)0x3bc8, (q15_t)0x3fdc, (q15_t)0x3bd5, (q15_t)0x3fdd, + (q15_t)0x3be1, (q15_t)0x3fde, (q15_t)0x3bee, (q15_t)0x3fdf, (q15_t)0x3bfa, (q15_t)0x3fe0, (q15_t)0x3c07, (q15_t)0x3fe0, + (q15_t)0x3c13, (q15_t)0x3fe1, (q15_t)0x3c20, (q15_t)0x3fe2, (q15_t)0x3c2c, (q15_t)0x3fe3, (q15_t)0x3c39, (q15_t)0x3fe3, + (q15_t)0x3c45, (q15_t)0x3fe4, (q15_t)0x3c52, (q15_t)0x3fe5, (q15_t)0x3c5f, (q15_t)0x3fe6, (q15_t)0x3c6b, (q15_t)0x3fe6, + (q15_t)0x3c78, (q15_t)0x3fe7, (q15_t)0x3c84, (q15_t)0x3fe8, (q15_t)0x3c91, (q15_t)0x3fe8, (q15_t)0x3c9d, (q15_t)0x3fe9, + (q15_t)0x3caa, (q15_t)0x3fea, (q15_t)0x3cb6, (q15_t)0x3fea, (q15_t)0x3cc3, (q15_t)0x3feb, (q15_t)0x3cd0, (q15_t)0x3fec, + (q15_t)0x3cdc, (q15_t)0x3fec, (q15_t)0x3ce9, (q15_t)0x3fed, (q15_t)0x3cf5, (q15_t)0x3fed, (q15_t)0x3d02, (q15_t)0x3fee, + (q15_t)0x3d0e, (q15_t)0x3fef, (q15_t)0x3d1b, (q15_t)0x3fef, (q15_t)0x3d27, (q15_t)0x3ff0, (q15_t)0x3d34, (q15_t)0x3ff0, + (q15_t)0x3d40, (q15_t)0x3ff1, (q15_t)0x3d4d, (q15_t)0x3ff1, (q15_t)0x3d5a, (q15_t)0x3ff2, (q15_t)0x3d66, (q15_t)0x3ff2, + (q15_t)0x3d73, (q15_t)0x3ff3, (q15_t)0x3d7f, (q15_t)0x3ff3, (q15_t)0x3d8c, (q15_t)0x3ff4, (q15_t)0x3d98, (q15_t)0x3ff4, + (q15_t)0x3da5, (q15_t)0x3ff5, (q15_t)0x3db2, (q15_t)0x3ff5, (q15_t)0x3dbe, (q15_t)0x3ff6, (q15_t)0x3dcb, (q15_t)0x3ff6, + (q15_t)0x3dd7, (q15_t)0x3ff7, (q15_t)0x3de4, (q15_t)0x3ff7, (q15_t)0x3df0, (q15_t)0x3ff7, (q15_t)0x3dfd, (q15_t)0x3ff8, + (q15_t)0x3e09, (q15_t)0x3ff8, (q15_t)0x3e16, (q15_t)0x3ff9, (q15_t)0x3e23, (q15_t)0x3ff9, (q15_t)0x3e2f, (q15_t)0x3ff9, + (q15_t)0x3e3c, (q15_t)0x3ffa, (q15_t)0x3e48, (q15_t)0x3ffa, (q15_t)0x3e55, (q15_t)0x3ffa, (q15_t)0x3e61, (q15_t)0x3ffb, + (q15_t)0x3e6e, (q15_t)0x3ffb, (q15_t)0x3e7a, (q15_t)0x3ffb, (q15_t)0x3e87, (q15_t)0x3ffc, (q15_t)0x3e94, (q15_t)0x3ffc, + (q15_t)0x3ea0, (q15_t)0x3ffc, (q15_t)0x3ead, (q15_t)0x3ffc, (q15_t)0x3eb9, (q15_t)0x3ffd, (q15_t)0x3ec6, (q15_t)0x3ffd, + (q15_t)0x3ed2, (q15_t)0x3ffd, (q15_t)0x3edf, (q15_t)0x3ffd, (q15_t)0x3eec, (q15_t)0x3ffe, (q15_t)0x3ef8, (q15_t)0x3ffe, + (q15_t)0x3f05, (q15_t)0x3ffe, (q15_t)0x3f11, (q15_t)0x3ffe, (q15_t)0x3f1e, (q15_t)0x3ffe, (q15_t)0x3f2a, (q15_t)0x3fff, + (q15_t)0x3f37, (q15_t)0x3fff, (q15_t)0x3f44, (q15_t)0x3fff, (q15_t)0x3f50, (q15_t)0x3fff, (q15_t)0x3f5d, (q15_t)0x3fff, + (q15_t)0x3f69, (q15_t)0x3fff, (q15_t)0x3f76, (q15_t)0x3fff, (q15_t)0x3f82, (q15_t)0x4000, (q15_t)0x3f8f, (q15_t)0x4000, + (q15_t)0x3f9b, (q15_t)0x4000, (q15_t)0x3fa8, (q15_t)0x4000, (q15_t)0x3fb5, (q15_t)0x4000, (q15_t)0x3fc1, (q15_t)0x4000, + (q15_t)0x3fce, (q15_t)0x4000, (q15_t)0x3fda, (q15_t)0x4000, (q15_t)0x3fe7, (q15_t)0x4000, (q15_t)0x3ff3, (q15_t)0x4000, +}; + +/** + @par + Generation of real_CoefB array: + @par + n = 4096 +
for (i = 0; i < n; i++)
+  {
+     pBTable[2 * i]     = 0.5 * (1.0 + sin (2 * PI / (double) (2 * n) * (double) i));
+     pBTable[2 * i + 1] = 0.5 * (1.0 * cos (2 * PI / (double) (2 * n) * (double) i));
+  }
+ @par + Convert to fixed point Q15 format + round(pBTable[i] * pow(2, 15)) +*/ +const q15_t __ALIGNED(4) realCoefBQ15[8192] = { + (q15_t)0x4000, (q15_t)0x4000, (q15_t)0x400d, (q15_t)0x4000, (q15_t)0x4019, (q15_t)0x4000, (q15_t)0x4026, (q15_t)0x4000, + (q15_t)0x4032, (q15_t)0x4000, (q15_t)0x403f, (q15_t)0x4000, (q15_t)0x404b, (q15_t)0x4000, (q15_t)0x4058, (q15_t)0x4000, + (q15_t)0x4065, (q15_t)0x4000, (q15_t)0x4071, (q15_t)0x4000, (q15_t)0x407e, (q15_t)0x4000, (q15_t)0x408a, (q15_t)0x3fff, + (q15_t)0x4097, (q15_t)0x3fff, (q15_t)0x40a3, (q15_t)0x3fff, (q15_t)0x40b0, (q15_t)0x3fff, (q15_t)0x40bc, (q15_t)0x3fff, + (q15_t)0x40c9, (q15_t)0x3fff, (q15_t)0x40d6, (q15_t)0x3fff, (q15_t)0x40e2, (q15_t)0x3ffe, (q15_t)0x40ef, (q15_t)0x3ffe, + (q15_t)0x40fb, (q15_t)0x3ffe, (q15_t)0x4108, (q15_t)0x3ffe, (q15_t)0x4114, (q15_t)0x3ffe, (q15_t)0x4121, (q15_t)0x3ffd, + (q15_t)0x412e, (q15_t)0x3ffd, (q15_t)0x413a, (q15_t)0x3ffd, (q15_t)0x4147, (q15_t)0x3ffd, (q15_t)0x4153, (q15_t)0x3ffc, + (q15_t)0x4160, (q15_t)0x3ffc, (q15_t)0x416c, (q15_t)0x3ffc, (q15_t)0x4179, (q15_t)0x3ffc, (q15_t)0x4186, (q15_t)0x3ffb, + (q15_t)0x4192, (q15_t)0x3ffb, (q15_t)0x419f, (q15_t)0x3ffb, (q15_t)0x41ab, (q15_t)0x3ffa, (q15_t)0x41b8, (q15_t)0x3ffa, + (q15_t)0x41c4, (q15_t)0x3ffa, (q15_t)0x41d1, (q15_t)0x3ff9, (q15_t)0x41dd, (q15_t)0x3ff9, (q15_t)0x41ea, (q15_t)0x3ff9, + (q15_t)0x41f7, (q15_t)0x3ff8, (q15_t)0x4203, (q15_t)0x3ff8, (q15_t)0x4210, (q15_t)0x3ff7, (q15_t)0x421c, (q15_t)0x3ff7, + (q15_t)0x4229, (q15_t)0x3ff7, (q15_t)0x4235, (q15_t)0x3ff6, (q15_t)0x4242, (q15_t)0x3ff6, (q15_t)0x424e, (q15_t)0x3ff5, + (q15_t)0x425b, (q15_t)0x3ff5, (q15_t)0x4268, (q15_t)0x3ff4, (q15_t)0x4274, (q15_t)0x3ff4, (q15_t)0x4281, (q15_t)0x3ff3, + (q15_t)0x428d, (q15_t)0x3ff3, (q15_t)0x429a, (q15_t)0x3ff2, (q15_t)0x42a6, (q15_t)0x3ff2, (q15_t)0x42b3, (q15_t)0x3ff1, + (q15_t)0x42c0, (q15_t)0x3ff1, (q15_t)0x42cc, (q15_t)0x3ff0, (q15_t)0x42d9, (q15_t)0x3ff0, (q15_t)0x42e5, (q15_t)0x3fef, + (q15_t)0x42f2, (q15_t)0x3fef, (q15_t)0x42fe, (q15_t)0x3fee, (q15_t)0x430b, (q15_t)0x3fed, (q15_t)0x4317, (q15_t)0x3fed, + (q15_t)0x4324, (q15_t)0x3fec, (q15_t)0x4330, (q15_t)0x3fec, (q15_t)0x433d, (q15_t)0x3feb, (q15_t)0x434a, (q15_t)0x3fea, + (q15_t)0x4356, (q15_t)0x3fea, (q15_t)0x4363, (q15_t)0x3fe9, (q15_t)0x436f, (q15_t)0x3fe8, (q15_t)0x437c, (q15_t)0x3fe8, + (q15_t)0x4388, (q15_t)0x3fe7, (q15_t)0x4395, (q15_t)0x3fe6, (q15_t)0x43a1, (q15_t)0x3fe6, (q15_t)0x43ae, (q15_t)0x3fe5, + (q15_t)0x43bb, (q15_t)0x3fe4, (q15_t)0x43c7, (q15_t)0x3fe3, (q15_t)0x43d4, (q15_t)0x3fe3, (q15_t)0x43e0, (q15_t)0x3fe2, + (q15_t)0x43ed, (q15_t)0x3fe1, (q15_t)0x43f9, (q15_t)0x3fe0, (q15_t)0x4406, (q15_t)0x3fe0, (q15_t)0x4412, (q15_t)0x3fdf, + (q15_t)0x441f, (q15_t)0x3fde, (q15_t)0x442b, (q15_t)0x3fdd, (q15_t)0x4438, (q15_t)0x3fdc, (q15_t)0x4444, (q15_t)0x3fdc, + (q15_t)0x4451, (q15_t)0x3fdb, (q15_t)0x445e, (q15_t)0x3fda, (q15_t)0x446a, (q15_t)0x3fd9, (q15_t)0x4477, (q15_t)0x3fd8, + (q15_t)0x4483, (q15_t)0x3fd7, (q15_t)0x4490, (q15_t)0x3fd6, (q15_t)0x449c, (q15_t)0x3fd5, (q15_t)0x44a9, (q15_t)0x3fd5, + (q15_t)0x44b5, (q15_t)0x3fd4, (q15_t)0x44c2, (q15_t)0x3fd3, (q15_t)0x44ce, (q15_t)0x3fd2, (q15_t)0x44db, (q15_t)0x3fd1, + (q15_t)0x44e7, (q15_t)0x3fd0, (q15_t)0x44f4, (q15_t)0x3fcf, (q15_t)0x4500, (q15_t)0x3fce, (q15_t)0x450d, (q15_t)0x3fcd, + (q15_t)0x451a, (q15_t)0x3fcc, (q15_t)0x4526, (q15_t)0x3fcb, (q15_t)0x4533, (q15_t)0x3fca, (q15_t)0x453f, (q15_t)0x3fc9, + (q15_t)0x454c, (q15_t)0x3fc8, (q15_t)0x4558, (q15_t)0x3fc7, (q15_t)0x4565, (q15_t)0x3fc6, (q15_t)0x4571, (q15_t)0x3fc5, + (q15_t)0x457e, (q15_t)0x3fc4, (q15_t)0x458a, (q15_t)0x3fc3, (q15_t)0x4597, (q15_t)0x3fc1, (q15_t)0x45a3, (q15_t)0x3fc0, + (q15_t)0x45b0, (q15_t)0x3fbf, (q15_t)0x45bc, (q15_t)0x3fbe, (q15_t)0x45c9, (q15_t)0x3fbd, (q15_t)0x45d5, (q15_t)0x3fbc, + (q15_t)0x45e2, (q15_t)0x3fbb, (q15_t)0x45ee, (q15_t)0x3fb9, (q15_t)0x45fb, (q15_t)0x3fb8, (q15_t)0x4607, (q15_t)0x3fb7, + (q15_t)0x4614, (q15_t)0x3fb6, (q15_t)0x4620, (q15_t)0x3fb5, (q15_t)0x462d, (q15_t)0x3fb4, (q15_t)0x4639, (q15_t)0x3fb2, + (q15_t)0x4646, (q15_t)0x3fb1, (q15_t)0x4652, (q15_t)0x3fb0, (q15_t)0x465f, (q15_t)0x3faf, (q15_t)0x466b, (q15_t)0x3fad, + (q15_t)0x4678, (q15_t)0x3fac, (q15_t)0x4684, (q15_t)0x3fab, (q15_t)0x4691, (q15_t)0x3faa, (q15_t)0x469d, (q15_t)0x3fa8, + (q15_t)0x46aa, (q15_t)0x3fa7, (q15_t)0x46b6, (q15_t)0x3fa6, (q15_t)0x46c3, (q15_t)0x3fa4, (q15_t)0x46cf, (q15_t)0x3fa3, + (q15_t)0x46dc, (q15_t)0x3fa2, (q15_t)0x46e8, (q15_t)0x3fa0, (q15_t)0x46f5, (q15_t)0x3f9f, (q15_t)0x4701, (q15_t)0x3f9e, + (q15_t)0x470e, (q15_t)0x3f9c, (q15_t)0x471a, (q15_t)0x3f9b, (q15_t)0x4727, (q15_t)0x3f99, (q15_t)0x4733, (q15_t)0x3f98, + (q15_t)0x4740, (q15_t)0x3f97, (q15_t)0x474c, (q15_t)0x3f95, (q15_t)0x4759, (q15_t)0x3f94, (q15_t)0x4765, (q15_t)0x3f92, + (q15_t)0x4772, (q15_t)0x3f91, (q15_t)0x477e, (q15_t)0x3f8f, (q15_t)0x478b, (q15_t)0x3f8e, (q15_t)0x4797, (q15_t)0x3f8c, + (q15_t)0x47a4, (q15_t)0x3f8b, (q15_t)0x47b0, (q15_t)0x3f89, (q15_t)0x47bd, (q15_t)0x3f88, (q15_t)0x47c9, (q15_t)0x3f86, + (q15_t)0x47d6, (q15_t)0x3f85, (q15_t)0x47e2, (q15_t)0x3f83, (q15_t)0x47ef, (q15_t)0x3f82, (q15_t)0x47fb, (q15_t)0x3f80, + (q15_t)0x4807, (q15_t)0x3f7f, (q15_t)0x4814, (q15_t)0x3f7d, (q15_t)0x4820, (q15_t)0x3f7b, (q15_t)0x482d, (q15_t)0x3f7a, + (q15_t)0x4839, (q15_t)0x3f78, (q15_t)0x4846, (q15_t)0x3f77, (q15_t)0x4852, (q15_t)0x3f75, (q15_t)0x485f, (q15_t)0x3f73, + (q15_t)0x486b, (q15_t)0x3f72, (q15_t)0x4878, (q15_t)0x3f70, (q15_t)0x4884, (q15_t)0x3f6e, (q15_t)0x4891, (q15_t)0x3f6d, + (q15_t)0x489d, (q15_t)0x3f6b, (q15_t)0x48a9, (q15_t)0x3f69, (q15_t)0x48b6, (q15_t)0x3f68, (q15_t)0x48c2, (q15_t)0x3f66, + (q15_t)0x48cf, (q15_t)0x3f64, (q15_t)0x48db, (q15_t)0x3f62, (q15_t)0x48e8, (q15_t)0x3f61, (q15_t)0x48f4, (q15_t)0x3f5f, + (q15_t)0x4901, (q15_t)0x3f5d, (q15_t)0x490d, (q15_t)0x3f5b, (q15_t)0x4919, (q15_t)0x3f5a, (q15_t)0x4926, (q15_t)0x3f58, + (q15_t)0x4932, (q15_t)0x3f56, (q15_t)0x493f, (q15_t)0x3f54, (q15_t)0x494b, (q15_t)0x3f52, (q15_t)0x4958, (q15_t)0x3f51, + (q15_t)0x4964, (q15_t)0x3f4f, (q15_t)0x4970, (q15_t)0x3f4d, (q15_t)0x497d, (q15_t)0x3f4b, (q15_t)0x4989, (q15_t)0x3f49, + (q15_t)0x4996, (q15_t)0x3f47, (q15_t)0x49a2, (q15_t)0x3f45, (q15_t)0x49af, (q15_t)0x3f43, (q15_t)0x49bb, (q15_t)0x3f42, + (q15_t)0x49c7, (q15_t)0x3f40, (q15_t)0x49d4, (q15_t)0x3f3e, (q15_t)0x49e0, (q15_t)0x3f3c, (q15_t)0x49ed, (q15_t)0x3f3a, + (q15_t)0x49f9, (q15_t)0x3f38, (q15_t)0x4a06, (q15_t)0x3f36, (q15_t)0x4a12, (q15_t)0x3f34, (q15_t)0x4a1e, (q15_t)0x3f32, + (q15_t)0x4a2b, (q15_t)0x3f30, (q15_t)0x4a37, (q15_t)0x3f2e, (q15_t)0x4a44, (q15_t)0x3f2c, (q15_t)0x4a50, (q15_t)0x3f2a, + (q15_t)0x4a5c, (q15_t)0x3f28, (q15_t)0x4a69, (q15_t)0x3f26, (q15_t)0x4a75, (q15_t)0x3f24, (q15_t)0x4a82, (q15_t)0x3f22, + (q15_t)0x4a8e, (q15_t)0x3f20, (q15_t)0x4a9a, (q15_t)0x3f1e, (q15_t)0x4aa7, (q15_t)0x3f1c, (q15_t)0x4ab3, (q15_t)0x3f19, + (q15_t)0x4ac0, (q15_t)0x3f17, (q15_t)0x4acc, (q15_t)0x3f15, (q15_t)0x4ad8, (q15_t)0x3f13, (q15_t)0x4ae5, (q15_t)0x3f11, + (q15_t)0x4af1, (q15_t)0x3f0f, (q15_t)0x4afd, (q15_t)0x3f0d, (q15_t)0x4b0a, (q15_t)0x3f0a, (q15_t)0x4b16, (q15_t)0x3f08, + (q15_t)0x4b23, (q15_t)0x3f06, (q15_t)0x4b2f, (q15_t)0x3f04, (q15_t)0x4b3b, (q15_t)0x3f02, (q15_t)0x4b48, (q15_t)0x3f00, + (q15_t)0x4b54, (q15_t)0x3efd, (q15_t)0x4b60, (q15_t)0x3efb, (q15_t)0x4b6d, (q15_t)0x3ef9, (q15_t)0x4b79, (q15_t)0x3ef7, + (q15_t)0x4b85, (q15_t)0x3ef4, (q15_t)0x4b92, (q15_t)0x3ef2, (q15_t)0x4b9e, (q15_t)0x3ef0, (q15_t)0x4bab, (q15_t)0x3eed, + (q15_t)0x4bb7, (q15_t)0x3eeb, (q15_t)0x4bc3, (q15_t)0x3ee9, (q15_t)0x4bd0, (q15_t)0x3ee7, (q15_t)0x4bdc, (q15_t)0x3ee4, + (q15_t)0x4be8, (q15_t)0x3ee2, (q15_t)0x4bf5, (q15_t)0x3ee0, (q15_t)0x4c01, (q15_t)0x3edd, (q15_t)0x4c0d, (q15_t)0x3edb, + (q15_t)0x4c1a, (q15_t)0x3ed8, (q15_t)0x4c26, (q15_t)0x3ed6, (q15_t)0x4c32, (q15_t)0x3ed4, (q15_t)0x4c3f, (q15_t)0x3ed1, + (q15_t)0x4c4b, (q15_t)0x3ecf, (q15_t)0x4c57, (q15_t)0x3ecc, (q15_t)0x4c64, (q15_t)0x3eca, (q15_t)0x4c70, (q15_t)0x3ec8, + (q15_t)0x4c7c, (q15_t)0x3ec5, (q15_t)0x4c89, (q15_t)0x3ec3, (q15_t)0x4c95, (q15_t)0x3ec0, (q15_t)0x4ca1, (q15_t)0x3ebe, + (q15_t)0x4cae, (q15_t)0x3ebb, (q15_t)0x4cba, (q15_t)0x3eb9, (q15_t)0x4cc6, (q15_t)0x3eb6, (q15_t)0x4cd3, (q15_t)0x3eb4, + (q15_t)0x4cdf, (q15_t)0x3eb1, (q15_t)0x4ceb, (q15_t)0x3eaf, (q15_t)0x4cf8, (q15_t)0x3eac, (q15_t)0x4d04, (q15_t)0x3eaa, + (q15_t)0x4d10, (q15_t)0x3ea7, (q15_t)0x4d1c, (q15_t)0x3ea5, (q15_t)0x4d29, (q15_t)0x3ea2, (q15_t)0x4d35, (q15_t)0x3e9f, + (q15_t)0x4d41, (q15_t)0x3e9d, (q15_t)0x4d4e, (q15_t)0x3e9a, (q15_t)0x4d5a, (q15_t)0x3e98, (q15_t)0x4d66, (q15_t)0x3e95, + (q15_t)0x4d72, (q15_t)0x3e92, (q15_t)0x4d7f, (q15_t)0x3e90, (q15_t)0x4d8b, (q15_t)0x3e8d, (q15_t)0x4d97, (q15_t)0x3e8a, + (q15_t)0x4da4, (q15_t)0x3e88, (q15_t)0x4db0, (q15_t)0x3e85, (q15_t)0x4dbc, (q15_t)0x3e82, (q15_t)0x4dc8, (q15_t)0x3e80, + (q15_t)0x4dd5, (q15_t)0x3e7d, (q15_t)0x4de1, (q15_t)0x3e7a, (q15_t)0x4ded, (q15_t)0x3e77, (q15_t)0x4df9, (q15_t)0x3e75, + (q15_t)0x4e06, (q15_t)0x3e72, (q15_t)0x4e12, (q15_t)0x3e6f, (q15_t)0x4e1e, (q15_t)0x3e6c, (q15_t)0x4e2b, (q15_t)0x3e6a, + (q15_t)0x4e37, (q15_t)0x3e67, (q15_t)0x4e43, (q15_t)0x3e64, (q15_t)0x4e4f, (q15_t)0x3e61, (q15_t)0x4e5c, (q15_t)0x3e5e, + (q15_t)0x4e68, (q15_t)0x3e5c, (q15_t)0x4e74, (q15_t)0x3e59, (q15_t)0x4e80, (q15_t)0x3e56, (q15_t)0x4e8c, (q15_t)0x3e53, + (q15_t)0x4e99, (q15_t)0x3e50, (q15_t)0x4ea5, (q15_t)0x3e4d, (q15_t)0x4eb1, (q15_t)0x3e4a, (q15_t)0x4ebd, (q15_t)0x3e48, + (q15_t)0x4eca, (q15_t)0x3e45, (q15_t)0x4ed6, (q15_t)0x3e42, (q15_t)0x4ee2, (q15_t)0x3e3f, (q15_t)0x4eee, (q15_t)0x3e3c, + (q15_t)0x4efb, (q15_t)0x3e39, (q15_t)0x4f07, (q15_t)0x3e36, (q15_t)0x4f13, (q15_t)0x3e33, (q15_t)0x4f1f, (q15_t)0x3e30, + (q15_t)0x4f2b, (q15_t)0x3e2d, (q15_t)0x4f38, (q15_t)0x3e2a, (q15_t)0x4f44, (q15_t)0x3e27, (q15_t)0x4f50, (q15_t)0x3e24, + (q15_t)0x4f5c, (q15_t)0x3e21, (q15_t)0x4f68, (q15_t)0x3e1e, (q15_t)0x4f75, (q15_t)0x3e1b, (q15_t)0x4f81, (q15_t)0x3e18, + (q15_t)0x4f8d, (q15_t)0x3e15, (q15_t)0x4f99, (q15_t)0x3e12, (q15_t)0x4fa5, (q15_t)0x3e0f, (q15_t)0x4fb2, (q15_t)0x3e0c, + (q15_t)0x4fbe, (q15_t)0x3e09, (q15_t)0x4fca, (q15_t)0x3e06, (q15_t)0x4fd6, (q15_t)0x3e03, (q15_t)0x4fe2, (q15_t)0x3dff, + (q15_t)0x4fee, (q15_t)0x3dfc, (q15_t)0x4ffb, (q15_t)0x3df9, (q15_t)0x5007, (q15_t)0x3df6, (q15_t)0x5013, (q15_t)0x3df3, + (q15_t)0x501f, (q15_t)0x3df0, (q15_t)0x502b, (q15_t)0x3ded, (q15_t)0x5037, (q15_t)0x3de9, (q15_t)0x5044, (q15_t)0x3de6, + (q15_t)0x5050, (q15_t)0x3de3, (q15_t)0x505c, (q15_t)0x3de0, (q15_t)0x5068, (q15_t)0x3ddd, (q15_t)0x5074, (q15_t)0x3dd9, + (q15_t)0x5080, (q15_t)0x3dd6, (q15_t)0x508c, (q15_t)0x3dd3, (q15_t)0x5099, (q15_t)0x3dd0, (q15_t)0x50a5, (q15_t)0x3dcc, + (q15_t)0x50b1, (q15_t)0x3dc9, (q15_t)0x50bd, (q15_t)0x3dc6, (q15_t)0x50c9, (q15_t)0x3dc2, (q15_t)0x50d5, (q15_t)0x3dbf, + (q15_t)0x50e1, (q15_t)0x3dbc, (q15_t)0x50ed, (q15_t)0x3db9, (q15_t)0x50fa, (q15_t)0x3db5, (q15_t)0x5106, (q15_t)0x3db2, + (q15_t)0x5112, (q15_t)0x3daf, (q15_t)0x511e, (q15_t)0x3dab, (q15_t)0x512a, (q15_t)0x3da8, (q15_t)0x5136, (q15_t)0x3da4, + (q15_t)0x5142, (q15_t)0x3da1, (q15_t)0x514e, (q15_t)0x3d9e, (q15_t)0x515a, (q15_t)0x3d9a, (q15_t)0x5167, (q15_t)0x3d97, + (q15_t)0x5173, (q15_t)0x3d93, (q15_t)0x517f, (q15_t)0x3d90, (q15_t)0x518b, (q15_t)0x3d8d, (q15_t)0x5197, (q15_t)0x3d89, + (q15_t)0x51a3, (q15_t)0x3d86, (q15_t)0x51af, (q15_t)0x3d82, (q15_t)0x51bb, (q15_t)0x3d7f, (q15_t)0x51c7, (q15_t)0x3d7b, + (q15_t)0x51d3, (q15_t)0x3d78, (q15_t)0x51df, (q15_t)0x3d74, (q15_t)0x51eb, (q15_t)0x3d71, (q15_t)0x51f7, (q15_t)0x3d6d, + (q15_t)0x5204, (q15_t)0x3d6a, (q15_t)0x5210, (q15_t)0x3d66, (q15_t)0x521c, (q15_t)0x3d63, (q15_t)0x5228, (q15_t)0x3d5f, + (q15_t)0x5234, (q15_t)0x3d5b, (q15_t)0x5240, (q15_t)0x3d58, (q15_t)0x524c, (q15_t)0x3d54, (q15_t)0x5258, (q15_t)0x3d51, + (q15_t)0x5264, (q15_t)0x3d4d, (q15_t)0x5270, (q15_t)0x3d49, (q15_t)0x527c, (q15_t)0x3d46, (q15_t)0x5288, (q15_t)0x3d42, + (q15_t)0x5294, (q15_t)0x3d3f, (q15_t)0x52a0, (q15_t)0x3d3b, (q15_t)0x52ac, (q15_t)0x3d37, (q15_t)0x52b8, (q15_t)0x3d34, + (q15_t)0x52c4, (q15_t)0x3d30, (q15_t)0x52d0, (q15_t)0x3d2c, (q15_t)0x52dc, (q15_t)0x3d28, (q15_t)0x52e8, (q15_t)0x3d25, + (q15_t)0x52f4, (q15_t)0x3d21, (q15_t)0x5300, (q15_t)0x3d1d, (q15_t)0x530c, (q15_t)0x3d1a, (q15_t)0x5318, (q15_t)0x3d16, + (q15_t)0x5324, (q15_t)0x3d12, (q15_t)0x5330, (q15_t)0x3d0e, (q15_t)0x533c, (q15_t)0x3d0b, (q15_t)0x5348, (q15_t)0x3d07, + (q15_t)0x5354, (q15_t)0x3d03, (q15_t)0x5360, (q15_t)0x3cff, (q15_t)0x536c, (q15_t)0x3cfb, (q15_t)0x5378, (q15_t)0x3cf8, + (q15_t)0x5384, (q15_t)0x3cf4, (q15_t)0x5390, (q15_t)0x3cf0, (q15_t)0x539c, (q15_t)0x3cec, (q15_t)0x53a8, (q15_t)0x3ce8, + (q15_t)0x53b4, (q15_t)0x3ce4, (q15_t)0x53c0, (q15_t)0x3ce0, (q15_t)0x53cc, (q15_t)0x3cdd, (q15_t)0x53d8, (q15_t)0x3cd9, + (q15_t)0x53e4, (q15_t)0x3cd5, (q15_t)0x53f0, (q15_t)0x3cd1, (q15_t)0x53fb, (q15_t)0x3ccd, (q15_t)0x5407, (q15_t)0x3cc9, + (q15_t)0x5413, (q15_t)0x3cc5, (q15_t)0x541f, (q15_t)0x3cc1, (q15_t)0x542b, (q15_t)0x3cbd, (q15_t)0x5437, (q15_t)0x3cb9, + (q15_t)0x5443, (q15_t)0x3cb5, (q15_t)0x544f, (q15_t)0x3cb1, (q15_t)0x545b, (q15_t)0x3cad, (q15_t)0x5467, (q15_t)0x3ca9, + (q15_t)0x5473, (q15_t)0x3ca5, (q15_t)0x547f, (q15_t)0x3ca1, (q15_t)0x548b, (q15_t)0x3c9d, (q15_t)0x5496, (q15_t)0x3c99, + (q15_t)0x54a2, (q15_t)0x3c95, (q15_t)0x54ae, (q15_t)0x3c91, (q15_t)0x54ba, (q15_t)0x3c8d, (q15_t)0x54c6, (q15_t)0x3c89, + (q15_t)0x54d2, (q15_t)0x3c85, (q15_t)0x54de, (q15_t)0x3c81, (q15_t)0x54ea, (q15_t)0x3c7d, (q15_t)0x54f6, (q15_t)0x3c79, + (q15_t)0x5501, (q15_t)0x3c74, (q15_t)0x550d, (q15_t)0x3c70, (q15_t)0x5519, (q15_t)0x3c6c, (q15_t)0x5525, (q15_t)0x3c68, + (q15_t)0x5531, (q15_t)0x3c64, (q15_t)0x553d, (q15_t)0x3c60, (q15_t)0x5549, (q15_t)0x3c5b, (q15_t)0x5554, (q15_t)0x3c57, + (q15_t)0x5560, (q15_t)0x3c53, (q15_t)0x556c, (q15_t)0x3c4f, (q15_t)0x5578, (q15_t)0x3c4b, (q15_t)0x5584, (q15_t)0x3c46, + (q15_t)0x5590, (q15_t)0x3c42, (q15_t)0x559b, (q15_t)0x3c3e, (q15_t)0x55a7, (q15_t)0x3c3a, (q15_t)0x55b3, (q15_t)0x3c36, + (q15_t)0x55bf, (q15_t)0x3c31, (q15_t)0x55cb, (q15_t)0x3c2d, (q15_t)0x55d7, (q15_t)0x3c29, (q15_t)0x55e2, (q15_t)0x3c24, + (q15_t)0x55ee, (q15_t)0x3c20, (q15_t)0x55fa, (q15_t)0x3c1c, (q15_t)0x5606, (q15_t)0x3c17, (q15_t)0x5612, (q15_t)0x3c13, + (q15_t)0x561d, (q15_t)0x3c0f, (q15_t)0x5629, (q15_t)0x3c0a, (q15_t)0x5635, (q15_t)0x3c06, (q15_t)0x5641, (q15_t)0x3c02, + (q15_t)0x564c, (q15_t)0x3bfd, (q15_t)0x5658, (q15_t)0x3bf9, (q15_t)0x5664, (q15_t)0x3bf5, (q15_t)0x5670, (q15_t)0x3bf0, + (q15_t)0x567c, (q15_t)0x3bec, (q15_t)0x5687, (q15_t)0x3be7, (q15_t)0x5693, (q15_t)0x3be3, (q15_t)0x569f, (q15_t)0x3bde, + (q15_t)0x56ab, (q15_t)0x3bda, (q15_t)0x56b6, (q15_t)0x3bd6, (q15_t)0x56c2, (q15_t)0x3bd1, (q15_t)0x56ce, (q15_t)0x3bcd, + (q15_t)0x56da, (q15_t)0x3bc8, (q15_t)0x56e5, (q15_t)0x3bc4, (q15_t)0x56f1, (q15_t)0x3bbf, (q15_t)0x56fd, (q15_t)0x3bbb, + (q15_t)0x5709, (q15_t)0x3bb6, (q15_t)0x5714, (q15_t)0x3bb2, (q15_t)0x5720, (q15_t)0x3bad, (q15_t)0x572c, (q15_t)0x3ba9, + (q15_t)0x5737, (q15_t)0x3ba4, (q15_t)0x5743, (q15_t)0x3b9f, (q15_t)0x574f, (q15_t)0x3b9b, (q15_t)0x575b, (q15_t)0x3b96, + (q15_t)0x5766, (q15_t)0x3b92, (q15_t)0x5772, (q15_t)0x3b8d, (q15_t)0x577e, (q15_t)0x3b88, (q15_t)0x5789, (q15_t)0x3b84, + (q15_t)0x5795, (q15_t)0x3b7f, (q15_t)0x57a1, (q15_t)0x3b7b, (q15_t)0x57ac, (q15_t)0x3b76, (q15_t)0x57b8, (q15_t)0x3b71, + (q15_t)0x57c4, (q15_t)0x3b6d, (q15_t)0x57cf, (q15_t)0x3b68, (q15_t)0x57db, (q15_t)0x3b63, (q15_t)0x57e7, (q15_t)0x3b5f, + (q15_t)0x57f2, (q15_t)0x3b5a, (q15_t)0x57fe, (q15_t)0x3b55, (q15_t)0x580a, (q15_t)0x3b50, (q15_t)0x5815, (q15_t)0x3b4c, + (q15_t)0x5821, (q15_t)0x3b47, (q15_t)0x582d, (q15_t)0x3b42, (q15_t)0x5838, (q15_t)0x3b3e, (q15_t)0x5844, (q15_t)0x3b39, + (q15_t)0x584f, (q15_t)0x3b34, (q15_t)0x585b, (q15_t)0x3b2f, (q15_t)0x5867, (q15_t)0x3b2a, (q15_t)0x5872, (q15_t)0x3b26, + (q15_t)0x587e, (q15_t)0x3b21, (q15_t)0x5889, (q15_t)0x3b1c, (q15_t)0x5895, (q15_t)0x3b17, (q15_t)0x58a1, (q15_t)0x3b12, + (q15_t)0x58ac, (q15_t)0x3b0e, (q15_t)0x58b8, (q15_t)0x3b09, (q15_t)0x58c3, (q15_t)0x3b04, (q15_t)0x58cf, (q15_t)0x3aff, + (q15_t)0x58db, (q15_t)0x3afa, (q15_t)0x58e6, (q15_t)0x3af5, (q15_t)0x58f2, (q15_t)0x3af0, (q15_t)0x58fd, (q15_t)0x3aeb, + (q15_t)0x5909, (q15_t)0x3ae6, (q15_t)0x5914, (q15_t)0x3ae2, (q15_t)0x5920, (q15_t)0x3add, (q15_t)0x592c, (q15_t)0x3ad8, + (q15_t)0x5937, (q15_t)0x3ad3, (q15_t)0x5943, (q15_t)0x3ace, (q15_t)0x594e, (q15_t)0x3ac9, (q15_t)0x595a, (q15_t)0x3ac4, + (q15_t)0x5965, (q15_t)0x3abf, (q15_t)0x5971, (q15_t)0x3aba, (q15_t)0x597c, (q15_t)0x3ab5, (q15_t)0x5988, (q15_t)0x3ab0, + (q15_t)0x5993, (q15_t)0x3aab, (q15_t)0x599f, (q15_t)0x3aa6, (q15_t)0x59aa, (q15_t)0x3aa1, (q15_t)0x59b6, (q15_t)0x3a9c, + (q15_t)0x59c1, (q15_t)0x3a97, (q15_t)0x59cd, (q15_t)0x3a92, (q15_t)0x59d8, (q15_t)0x3a8d, (q15_t)0x59e4, (q15_t)0x3a88, + (q15_t)0x59ef, (q15_t)0x3a82, (q15_t)0x59fb, (q15_t)0x3a7d, (q15_t)0x5a06, (q15_t)0x3a78, (q15_t)0x5a12, (q15_t)0x3a73, + (q15_t)0x5a1d, (q15_t)0x3a6e, (q15_t)0x5a29, (q15_t)0x3a69, (q15_t)0x5a34, (q15_t)0x3a64, (q15_t)0x5a40, (q15_t)0x3a5f, + (q15_t)0x5a4b, (q15_t)0x3a59, (q15_t)0x5a57, (q15_t)0x3a54, (q15_t)0x5a62, (q15_t)0x3a4f, (q15_t)0x5a6e, (q15_t)0x3a4a, + (q15_t)0x5a79, (q15_t)0x3a45, (q15_t)0x5a84, (q15_t)0x3a3f, (q15_t)0x5a90, (q15_t)0x3a3a, (q15_t)0x5a9b, (q15_t)0x3a35, + (q15_t)0x5aa7, (q15_t)0x3a30, (q15_t)0x5ab2, (q15_t)0x3a2b, (q15_t)0x5abe, (q15_t)0x3a25, (q15_t)0x5ac9, (q15_t)0x3a20, + (q15_t)0x5ad4, (q15_t)0x3a1b, (q15_t)0x5ae0, (q15_t)0x3a16, (q15_t)0x5aeb, (q15_t)0x3a10, (q15_t)0x5af7, (q15_t)0x3a0b, + (q15_t)0x5b02, (q15_t)0x3a06, (q15_t)0x5b0d, (q15_t)0x3a00, (q15_t)0x5b19, (q15_t)0x39fb, (q15_t)0x5b24, (q15_t)0x39f6, + (q15_t)0x5b30, (q15_t)0x39f0, (q15_t)0x5b3b, (q15_t)0x39eb, (q15_t)0x5b46, (q15_t)0x39e6, (q15_t)0x5b52, (q15_t)0x39e0, + (q15_t)0x5b5d, (q15_t)0x39db, (q15_t)0x5b68, (q15_t)0x39d6, (q15_t)0x5b74, (q15_t)0x39d0, (q15_t)0x5b7f, (q15_t)0x39cb, + (q15_t)0x5b8a, (q15_t)0x39c5, (q15_t)0x5b96, (q15_t)0x39c0, (q15_t)0x5ba1, (q15_t)0x39bb, (q15_t)0x5bac, (q15_t)0x39b5, + (q15_t)0x5bb8, (q15_t)0x39b0, (q15_t)0x5bc3, (q15_t)0x39aa, (q15_t)0x5bce, (q15_t)0x39a5, (q15_t)0x5bda, (q15_t)0x399f, + (q15_t)0x5be5, (q15_t)0x399a, (q15_t)0x5bf0, (q15_t)0x3994, (q15_t)0x5bfc, (q15_t)0x398f, (q15_t)0x5c07, (q15_t)0x3989, + (q15_t)0x5c12, (q15_t)0x3984, (q15_t)0x5c1e, (q15_t)0x397e, (q15_t)0x5c29, (q15_t)0x3979, (q15_t)0x5c34, (q15_t)0x3973, + (q15_t)0x5c3f, (q15_t)0x396e, (q15_t)0x5c4b, (q15_t)0x3968, (q15_t)0x5c56, (q15_t)0x3963, (q15_t)0x5c61, (q15_t)0x395d, + (q15_t)0x5c6c, (q15_t)0x3958, (q15_t)0x5c78, (q15_t)0x3952, (q15_t)0x5c83, (q15_t)0x394c, (q15_t)0x5c8e, (q15_t)0x3947, + (q15_t)0x5c99, (q15_t)0x3941, (q15_t)0x5ca5, (q15_t)0x393b, (q15_t)0x5cb0, (q15_t)0x3936, (q15_t)0x5cbb, (q15_t)0x3930, + (q15_t)0x5cc6, (q15_t)0x392b, (q15_t)0x5cd2, (q15_t)0x3925, (q15_t)0x5cdd, (q15_t)0x391f, (q15_t)0x5ce8, (q15_t)0x391a, + (q15_t)0x5cf3, (q15_t)0x3914, (q15_t)0x5cff, (q15_t)0x390e, (q15_t)0x5d0a, (q15_t)0x3909, (q15_t)0x5d15, (q15_t)0x3903, + (q15_t)0x5d20, (q15_t)0x38fd, (q15_t)0x5d2b, (q15_t)0x38f7, (q15_t)0x5d36, (q15_t)0x38f2, (q15_t)0x5d42, (q15_t)0x38ec, + (q15_t)0x5d4d, (q15_t)0x38e6, (q15_t)0x5d58, (q15_t)0x38e0, (q15_t)0x5d63, (q15_t)0x38db, (q15_t)0x5d6e, (q15_t)0x38d5, + (q15_t)0x5d79, (q15_t)0x38cf, (q15_t)0x5d85, (q15_t)0x38c9, (q15_t)0x5d90, (q15_t)0x38c3, (q15_t)0x5d9b, (q15_t)0x38be, + (q15_t)0x5da6, (q15_t)0x38b8, (q15_t)0x5db1, (q15_t)0x38b2, (q15_t)0x5dbc, (q15_t)0x38ac, (q15_t)0x5dc7, (q15_t)0x38a6, + (q15_t)0x5dd3, (q15_t)0x38a1, (q15_t)0x5dde, (q15_t)0x389b, (q15_t)0x5de9, (q15_t)0x3895, (q15_t)0x5df4, (q15_t)0x388f, + (q15_t)0x5dff, (q15_t)0x3889, (q15_t)0x5e0a, (q15_t)0x3883, (q15_t)0x5e15, (q15_t)0x387d, (q15_t)0x5e20, (q15_t)0x3877, + (q15_t)0x5e2b, (q15_t)0x3871, (q15_t)0x5e36, (q15_t)0x386b, (q15_t)0x5e42, (q15_t)0x3866, (q15_t)0x5e4d, (q15_t)0x3860, + (q15_t)0x5e58, (q15_t)0x385a, (q15_t)0x5e63, (q15_t)0x3854, (q15_t)0x5e6e, (q15_t)0x384e, (q15_t)0x5e79, (q15_t)0x3848, + (q15_t)0x5e84, (q15_t)0x3842, (q15_t)0x5e8f, (q15_t)0x383c, (q15_t)0x5e9a, (q15_t)0x3836, (q15_t)0x5ea5, (q15_t)0x3830, + (q15_t)0x5eb0, (q15_t)0x382a, (q15_t)0x5ebb, (q15_t)0x3824, (q15_t)0x5ec6, (q15_t)0x381e, (q15_t)0x5ed1, (q15_t)0x3818, + (q15_t)0x5edc, (q15_t)0x3812, (q15_t)0x5ee7, (q15_t)0x380b, (q15_t)0x5ef2, (q15_t)0x3805, (q15_t)0x5efd, (q15_t)0x37ff, + (q15_t)0x5f08, (q15_t)0x37f9, (q15_t)0x5f13, (q15_t)0x37f3, (q15_t)0x5f1e, (q15_t)0x37ed, (q15_t)0x5f29, (q15_t)0x37e7, + (q15_t)0x5f34, (q15_t)0x37e1, (q15_t)0x5f3f, (q15_t)0x37db, (q15_t)0x5f4a, (q15_t)0x37d5, (q15_t)0x5f55, (q15_t)0x37ce, + (q15_t)0x5f60, (q15_t)0x37c8, (q15_t)0x5f6b, (q15_t)0x37c2, (q15_t)0x5f76, (q15_t)0x37bc, (q15_t)0x5f81, (q15_t)0x37b6, + (q15_t)0x5f8c, (q15_t)0x37b0, (q15_t)0x5f97, (q15_t)0x37a9, (q15_t)0x5fa2, (q15_t)0x37a3, (q15_t)0x5fac, (q15_t)0x379d, + (q15_t)0x5fb7, (q15_t)0x3797, (q15_t)0x5fc2, (q15_t)0x3790, (q15_t)0x5fcd, (q15_t)0x378a, (q15_t)0x5fd8, (q15_t)0x3784, + (q15_t)0x5fe3, (q15_t)0x377e, (q15_t)0x5fee, (q15_t)0x3777, (q15_t)0x5ff9, (q15_t)0x3771, (q15_t)0x6004, (q15_t)0x376b, + (q15_t)0x600f, (q15_t)0x3765, (q15_t)0x6019, (q15_t)0x375e, (q15_t)0x6024, (q15_t)0x3758, (q15_t)0x602f, (q15_t)0x3752, + (q15_t)0x603a, (q15_t)0x374b, (q15_t)0x6045, (q15_t)0x3745, (q15_t)0x6050, (q15_t)0x373f, (q15_t)0x605b, (q15_t)0x3738, + (q15_t)0x6065, (q15_t)0x3732, (q15_t)0x6070, (q15_t)0x372c, (q15_t)0x607b, (q15_t)0x3725, (q15_t)0x6086, (q15_t)0x371f, + (q15_t)0x6091, (q15_t)0x3718, (q15_t)0x609b, (q15_t)0x3712, (q15_t)0x60a6, (q15_t)0x370c, (q15_t)0x60b1, (q15_t)0x3705, + (q15_t)0x60bc, (q15_t)0x36ff, (q15_t)0x60c7, (q15_t)0x36f8, (q15_t)0x60d1, (q15_t)0x36f2, (q15_t)0x60dc, (q15_t)0x36eb, + (q15_t)0x60e7, (q15_t)0x36e5, (q15_t)0x60f2, (q15_t)0x36df, (q15_t)0x60fd, (q15_t)0x36d8, (q15_t)0x6107, (q15_t)0x36d2, + (q15_t)0x6112, (q15_t)0x36cb, (q15_t)0x611d, (q15_t)0x36c5, (q15_t)0x6128, (q15_t)0x36be, (q15_t)0x6132, (q15_t)0x36b8, + (q15_t)0x613d, (q15_t)0x36b1, (q15_t)0x6148, (q15_t)0x36ab, (q15_t)0x6153, (q15_t)0x36a4, (q15_t)0x615d, (q15_t)0x369d, + (q15_t)0x6168, (q15_t)0x3697, (q15_t)0x6173, (q15_t)0x3690, (q15_t)0x617d, (q15_t)0x368a, (q15_t)0x6188, (q15_t)0x3683, + (q15_t)0x6193, (q15_t)0x367d, (q15_t)0x619e, (q15_t)0x3676, (q15_t)0x61a8, (q15_t)0x366f, (q15_t)0x61b3, (q15_t)0x3669, + (q15_t)0x61be, (q15_t)0x3662, (q15_t)0x61c8, (q15_t)0x365c, (q15_t)0x61d3, (q15_t)0x3655, (q15_t)0x61de, (q15_t)0x364e, + (q15_t)0x61e8, (q15_t)0x3648, (q15_t)0x61f3, (q15_t)0x3641, (q15_t)0x61fe, (q15_t)0x363a, (q15_t)0x6208, (q15_t)0x3634, + (q15_t)0x6213, (q15_t)0x362d, (q15_t)0x621e, (q15_t)0x3626, (q15_t)0x6228, (q15_t)0x3620, (q15_t)0x6233, (q15_t)0x3619, + (q15_t)0x623d, (q15_t)0x3612, (q15_t)0x6248, (q15_t)0x360b, (q15_t)0x6253, (q15_t)0x3605, (q15_t)0x625d, (q15_t)0x35fe, + (q15_t)0x6268, (q15_t)0x35f7, (q15_t)0x6272, (q15_t)0x35f0, (q15_t)0x627d, (q15_t)0x35ea, (q15_t)0x6288, (q15_t)0x35e3, + (q15_t)0x6292, (q15_t)0x35dc, (q15_t)0x629d, (q15_t)0x35d5, (q15_t)0x62a7, (q15_t)0x35ce, (q15_t)0x62b2, (q15_t)0x35c8, + (q15_t)0x62bc, (q15_t)0x35c1, (q15_t)0x62c7, (q15_t)0x35ba, (q15_t)0x62d2, (q15_t)0x35b3, (q15_t)0x62dc, (q15_t)0x35ac, + (q15_t)0x62e7, (q15_t)0x35a5, (q15_t)0x62f1, (q15_t)0x359f, (q15_t)0x62fc, (q15_t)0x3598, (q15_t)0x6306, (q15_t)0x3591, + (q15_t)0x6311, (q15_t)0x358a, (q15_t)0x631b, (q15_t)0x3583, (q15_t)0x6326, (q15_t)0x357c, (q15_t)0x6330, (q15_t)0x3575, + (q15_t)0x633b, (q15_t)0x356e, (q15_t)0x6345, (q15_t)0x3567, (q15_t)0x6350, (q15_t)0x3561, (q15_t)0x635a, (q15_t)0x355a, + (q15_t)0x6365, (q15_t)0x3553, (q15_t)0x636f, (q15_t)0x354c, (q15_t)0x637a, (q15_t)0x3545, (q15_t)0x6384, (q15_t)0x353e, + (q15_t)0x638e, (q15_t)0x3537, (q15_t)0x6399, (q15_t)0x3530, (q15_t)0x63a3, (q15_t)0x3529, (q15_t)0x63ae, (q15_t)0x3522, + (q15_t)0x63b8, (q15_t)0x351b, (q15_t)0x63c3, (q15_t)0x3514, (q15_t)0x63cd, (q15_t)0x350d, (q15_t)0x63d7, (q15_t)0x3506, + (q15_t)0x63e2, (q15_t)0x34ff, (q15_t)0x63ec, (q15_t)0x34f8, (q15_t)0x63f7, (q15_t)0x34f1, (q15_t)0x6401, (q15_t)0x34ea, + (q15_t)0x640b, (q15_t)0x34e2, (q15_t)0x6416, (q15_t)0x34db, (q15_t)0x6420, (q15_t)0x34d4, (q15_t)0x642b, (q15_t)0x34cd, + (q15_t)0x6435, (q15_t)0x34c6, (q15_t)0x643f, (q15_t)0x34bf, (q15_t)0x644a, (q15_t)0x34b8, (q15_t)0x6454, (q15_t)0x34b1, + (q15_t)0x645e, (q15_t)0x34aa, (q15_t)0x6469, (q15_t)0x34a2, (q15_t)0x6473, (q15_t)0x349b, (q15_t)0x647d, (q15_t)0x3494, + (q15_t)0x6488, (q15_t)0x348d, (q15_t)0x6492, (q15_t)0x3486, (q15_t)0x649c, (q15_t)0x347f, (q15_t)0x64a7, (q15_t)0x3477, + (q15_t)0x64b1, (q15_t)0x3470, (q15_t)0x64bb, (q15_t)0x3469, (q15_t)0x64c5, (q15_t)0x3462, (q15_t)0x64d0, (q15_t)0x345b, + (q15_t)0x64da, (q15_t)0x3453, (q15_t)0x64e4, (q15_t)0x344c, (q15_t)0x64ef, (q15_t)0x3445, (q15_t)0x64f9, (q15_t)0x343e, + (q15_t)0x6503, (q15_t)0x3436, (q15_t)0x650d, (q15_t)0x342f, (q15_t)0x6518, (q15_t)0x3428, (q15_t)0x6522, (q15_t)0x3420, + (q15_t)0x652c, (q15_t)0x3419, (q15_t)0x6536, (q15_t)0x3412, (q15_t)0x6541, (q15_t)0x340b, (q15_t)0x654b, (q15_t)0x3403, + (q15_t)0x6555, (q15_t)0x33fc, (q15_t)0x655f, (q15_t)0x33f5, (q15_t)0x6569, (q15_t)0x33ed, (q15_t)0x6574, (q15_t)0x33e6, + (q15_t)0x657e, (q15_t)0x33df, (q15_t)0x6588, (q15_t)0x33d7, (q15_t)0x6592, (q15_t)0x33d0, (q15_t)0x659c, (q15_t)0x33c8, + (q15_t)0x65a6, (q15_t)0x33c1, (q15_t)0x65b1, (q15_t)0x33ba, (q15_t)0x65bb, (q15_t)0x33b2, (q15_t)0x65c5, (q15_t)0x33ab, + (q15_t)0x65cf, (q15_t)0x33a3, (q15_t)0x65d9, (q15_t)0x339c, (q15_t)0x65e3, (q15_t)0x3395, (q15_t)0x65ed, (q15_t)0x338d, + (q15_t)0x65f8, (q15_t)0x3386, (q15_t)0x6602, (q15_t)0x337e, (q15_t)0x660c, (q15_t)0x3377, (q15_t)0x6616, (q15_t)0x336f, + (q15_t)0x6620, (q15_t)0x3368, (q15_t)0x662a, (q15_t)0x3360, (q15_t)0x6634, (q15_t)0x3359, (q15_t)0x663e, (q15_t)0x3351, + (q15_t)0x6648, (q15_t)0x334a, (q15_t)0x6652, (q15_t)0x3342, (q15_t)0x665c, (q15_t)0x333b, (q15_t)0x6666, (q15_t)0x3333, + (q15_t)0x6671, (q15_t)0x332c, (q15_t)0x667b, (q15_t)0x3324, (q15_t)0x6685, (q15_t)0x331d, (q15_t)0x668f, (q15_t)0x3315, + (q15_t)0x6699, (q15_t)0x330d, (q15_t)0x66a3, (q15_t)0x3306, (q15_t)0x66ad, (q15_t)0x32fe, (q15_t)0x66b7, (q15_t)0x32f7, + (q15_t)0x66c1, (q15_t)0x32ef, (q15_t)0x66cb, (q15_t)0x32e7, (q15_t)0x66d5, (q15_t)0x32e0, (q15_t)0x66df, (q15_t)0x32d8, + (q15_t)0x66e9, (q15_t)0x32d0, (q15_t)0x66f3, (q15_t)0x32c9, (q15_t)0x66fd, (q15_t)0x32c1, (q15_t)0x6707, (q15_t)0x32ba, + (q15_t)0x6711, (q15_t)0x32b2, (q15_t)0x671a, (q15_t)0x32aa, (q15_t)0x6724, (q15_t)0x32a3, (q15_t)0x672e, (q15_t)0x329b, + (q15_t)0x6738, (q15_t)0x3293, (q15_t)0x6742, (q15_t)0x328b, (q15_t)0x674c, (q15_t)0x3284, (q15_t)0x6756, (q15_t)0x327c, + (q15_t)0x6760, (q15_t)0x3274, (q15_t)0x676a, (q15_t)0x326d, (q15_t)0x6774, (q15_t)0x3265, (q15_t)0x677e, (q15_t)0x325d, + (q15_t)0x6788, (q15_t)0x3255, (q15_t)0x6791, (q15_t)0x324e, (q15_t)0x679b, (q15_t)0x3246, (q15_t)0x67a5, (q15_t)0x323e, + (q15_t)0x67af, (q15_t)0x3236, (q15_t)0x67b9, (q15_t)0x322e, (q15_t)0x67c3, (q15_t)0x3227, (q15_t)0x67cd, (q15_t)0x321f, + (q15_t)0x67d6, (q15_t)0x3217, (q15_t)0x67e0, (q15_t)0x320f, (q15_t)0x67ea, (q15_t)0x3207, (q15_t)0x67f4, (q15_t)0x31ff, + (q15_t)0x67fe, (q15_t)0x31f8, (q15_t)0x6808, (q15_t)0x31f0, (q15_t)0x6811, (q15_t)0x31e8, (q15_t)0x681b, (q15_t)0x31e0, + (q15_t)0x6825, (q15_t)0x31d8, (q15_t)0x682f, (q15_t)0x31d0, (q15_t)0x6838, (q15_t)0x31c8, (q15_t)0x6842, (q15_t)0x31c0, + (q15_t)0x684c, (q15_t)0x31b9, (q15_t)0x6856, (q15_t)0x31b1, (q15_t)0x6860, (q15_t)0x31a9, (q15_t)0x6869, (q15_t)0x31a1, + (q15_t)0x6873, (q15_t)0x3199, (q15_t)0x687d, (q15_t)0x3191, (q15_t)0x6886, (q15_t)0x3189, (q15_t)0x6890, (q15_t)0x3181, + (q15_t)0x689a, (q15_t)0x3179, (q15_t)0x68a4, (q15_t)0x3171, (q15_t)0x68ad, (q15_t)0x3169, (q15_t)0x68b7, (q15_t)0x3161, + (q15_t)0x68c1, (q15_t)0x3159, (q15_t)0x68ca, (q15_t)0x3151, (q15_t)0x68d4, (q15_t)0x3149, (q15_t)0x68de, (q15_t)0x3141, + (q15_t)0x68e7, (q15_t)0x3139, (q15_t)0x68f1, (q15_t)0x3131, (q15_t)0x68fb, (q15_t)0x3129, (q15_t)0x6904, (q15_t)0x3121, + (q15_t)0x690e, (q15_t)0x3119, (q15_t)0x6918, (q15_t)0x3111, (q15_t)0x6921, (q15_t)0x3109, (q15_t)0x692b, (q15_t)0x3101, + (q15_t)0x6935, (q15_t)0x30f9, (q15_t)0x693e, (q15_t)0x30f0, (q15_t)0x6948, (q15_t)0x30e8, (q15_t)0x6951, (q15_t)0x30e0, + (q15_t)0x695b, (q15_t)0x30d8, (q15_t)0x6965, (q15_t)0x30d0, (q15_t)0x696e, (q15_t)0x30c8, (q15_t)0x6978, (q15_t)0x30c0, + (q15_t)0x6981, (q15_t)0x30b8, (q15_t)0x698b, (q15_t)0x30af, (q15_t)0x6994, (q15_t)0x30a7, (q15_t)0x699e, (q15_t)0x309f, + (q15_t)0x69a7, (q15_t)0x3097, (q15_t)0x69b1, (q15_t)0x308f, (q15_t)0x69bb, (q15_t)0x3087, (q15_t)0x69c4, (q15_t)0x307e, + (q15_t)0x69ce, (q15_t)0x3076, (q15_t)0x69d7, (q15_t)0x306e, (q15_t)0x69e1, (q15_t)0x3066, (q15_t)0x69ea, (q15_t)0x305d, + (q15_t)0x69f4, (q15_t)0x3055, (q15_t)0x69fd, (q15_t)0x304d, (q15_t)0x6a07, (q15_t)0x3045, (q15_t)0x6a10, (q15_t)0x303c, + (q15_t)0x6a1a, (q15_t)0x3034, (q15_t)0x6a23, (q15_t)0x302c, (q15_t)0x6a2c, (q15_t)0x3024, (q15_t)0x6a36, (q15_t)0x301b, + (q15_t)0x6a3f, (q15_t)0x3013, (q15_t)0x6a49, (q15_t)0x300b, (q15_t)0x6a52, (q15_t)0x3002, (q15_t)0x6a5c, (q15_t)0x2ffa, + (q15_t)0x6a65, (q15_t)0x2ff2, (q15_t)0x6a6e, (q15_t)0x2fea, (q15_t)0x6a78, (q15_t)0x2fe1, (q15_t)0x6a81, (q15_t)0x2fd9, + (q15_t)0x6a8b, (q15_t)0x2fd0, (q15_t)0x6a94, (q15_t)0x2fc8, (q15_t)0x6a9d, (q15_t)0x2fc0, (q15_t)0x6aa7, (q15_t)0x2fb7, + (q15_t)0x6ab0, (q15_t)0x2faf, (q15_t)0x6ab9, (q15_t)0x2fa7, (q15_t)0x6ac3, (q15_t)0x2f9e, (q15_t)0x6acc, (q15_t)0x2f96, + (q15_t)0x6ad6, (q15_t)0x2f8d, (q15_t)0x6adf, (q15_t)0x2f85, (q15_t)0x6ae8, (q15_t)0x2f7d, (q15_t)0x6af2, (q15_t)0x2f74, + (q15_t)0x6afb, (q15_t)0x2f6c, (q15_t)0x6b04, (q15_t)0x2f63, (q15_t)0x6b0d, (q15_t)0x2f5b, (q15_t)0x6b17, (q15_t)0x2f52, + (q15_t)0x6b20, (q15_t)0x2f4a, (q15_t)0x6b29, (q15_t)0x2f41, (q15_t)0x6b33, (q15_t)0x2f39, (q15_t)0x6b3c, (q15_t)0x2f30, + (q15_t)0x6b45, (q15_t)0x2f28, (q15_t)0x6b4e, (q15_t)0x2f20, (q15_t)0x6b58, (q15_t)0x2f17, (q15_t)0x6b61, (q15_t)0x2f0e, + (q15_t)0x6b6a, (q15_t)0x2f06, (q15_t)0x6b73, (q15_t)0x2efd, (q15_t)0x6b7d, (q15_t)0x2ef5, (q15_t)0x6b86, (q15_t)0x2eec, + (q15_t)0x6b8f, (q15_t)0x2ee4, (q15_t)0x6b98, (q15_t)0x2edb, (q15_t)0x6ba1, (q15_t)0x2ed3, (q15_t)0x6bab, (q15_t)0x2eca, + (q15_t)0x6bb4, (q15_t)0x2ec2, (q15_t)0x6bbd, (q15_t)0x2eb9, (q15_t)0x6bc6, (q15_t)0x2eb0, (q15_t)0x6bcf, (q15_t)0x2ea8, + (q15_t)0x6bd8, (q15_t)0x2e9f, (q15_t)0x6be2, (q15_t)0x2e97, (q15_t)0x6beb, (q15_t)0x2e8e, (q15_t)0x6bf4, (q15_t)0x2e85, + (q15_t)0x6bfd, (q15_t)0x2e7d, (q15_t)0x6c06, (q15_t)0x2e74, (q15_t)0x6c0f, (q15_t)0x2e6b, (q15_t)0x6c18, (q15_t)0x2e63, + (q15_t)0x6c21, (q15_t)0x2e5a, (q15_t)0x6c2b, (q15_t)0x2e51, (q15_t)0x6c34, (q15_t)0x2e49, (q15_t)0x6c3d, (q15_t)0x2e40, + (q15_t)0x6c46, (q15_t)0x2e37, (q15_t)0x6c4f, (q15_t)0x2e2f, (q15_t)0x6c58, (q15_t)0x2e26, (q15_t)0x6c61, (q15_t)0x2e1d, + (q15_t)0x6c6a, (q15_t)0x2e15, (q15_t)0x6c73, (q15_t)0x2e0c, (q15_t)0x6c7c, (q15_t)0x2e03, (q15_t)0x6c85, (q15_t)0x2dfa, + (q15_t)0x6c8e, (q15_t)0x2df2, (q15_t)0x6c97, (q15_t)0x2de9, (q15_t)0x6ca0, (q15_t)0x2de0, (q15_t)0x6ca9, (q15_t)0x2dd7, + (q15_t)0x6cb2, (q15_t)0x2dcf, (q15_t)0x6cbb, (q15_t)0x2dc6, (q15_t)0x6cc4, (q15_t)0x2dbd, (q15_t)0x6ccd, (q15_t)0x2db4, + (q15_t)0x6cd6, (q15_t)0x2dab, (q15_t)0x6cdf, (q15_t)0x2da3, (q15_t)0x6ce8, (q15_t)0x2d9a, (q15_t)0x6cf1, (q15_t)0x2d91, + (q15_t)0x6cfa, (q15_t)0x2d88, (q15_t)0x6d03, (q15_t)0x2d7f, (q15_t)0x6d0c, (q15_t)0x2d76, (q15_t)0x6d15, (q15_t)0x2d6e, + (q15_t)0x6d1e, (q15_t)0x2d65, (q15_t)0x6d27, (q15_t)0x2d5c, (q15_t)0x6d2f, (q15_t)0x2d53, (q15_t)0x6d38, (q15_t)0x2d4a, + (q15_t)0x6d41, (q15_t)0x2d41, (q15_t)0x6d4a, (q15_t)0x2d38, (q15_t)0x6d53, (q15_t)0x2d2f, (q15_t)0x6d5c, (q15_t)0x2d27, + (q15_t)0x6d65, (q15_t)0x2d1e, (q15_t)0x6d6e, (q15_t)0x2d15, (q15_t)0x6d76, (q15_t)0x2d0c, (q15_t)0x6d7f, (q15_t)0x2d03, + (q15_t)0x6d88, (q15_t)0x2cfa, (q15_t)0x6d91, (q15_t)0x2cf1, (q15_t)0x6d9a, (q15_t)0x2ce8, (q15_t)0x6da3, (q15_t)0x2cdf, + (q15_t)0x6dab, (q15_t)0x2cd6, (q15_t)0x6db4, (q15_t)0x2ccd, (q15_t)0x6dbd, (q15_t)0x2cc4, (q15_t)0x6dc6, (q15_t)0x2cbb, + (q15_t)0x6dcf, (q15_t)0x2cb2, (q15_t)0x6dd7, (q15_t)0x2ca9, (q15_t)0x6de0, (q15_t)0x2ca0, (q15_t)0x6de9, (q15_t)0x2c97, + (q15_t)0x6df2, (q15_t)0x2c8e, (q15_t)0x6dfa, (q15_t)0x2c85, (q15_t)0x6e03, (q15_t)0x2c7c, (q15_t)0x6e0c, (q15_t)0x2c73, + (q15_t)0x6e15, (q15_t)0x2c6a, (q15_t)0x6e1d, (q15_t)0x2c61, (q15_t)0x6e26, (q15_t)0x2c58, (q15_t)0x6e2f, (q15_t)0x2c4f, + (q15_t)0x6e37, (q15_t)0x2c46, (q15_t)0x6e40, (q15_t)0x2c3d, (q15_t)0x6e49, (q15_t)0x2c34, (q15_t)0x6e51, (q15_t)0x2c2b, + (q15_t)0x6e5a, (q15_t)0x2c21, (q15_t)0x6e63, (q15_t)0x2c18, (q15_t)0x6e6b, (q15_t)0x2c0f, (q15_t)0x6e74, (q15_t)0x2c06, + (q15_t)0x6e7d, (q15_t)0x2bfd, (q15_t)0x6e85, (q15_t)0x2bf4, (q15_t)0x6e8e, (q15_t)0x2beb, (q15_t)0x6e97, (q15_t)0x2be2, + (q15_t)0x6e9f, (q15_t)0x2bd8, (q15_t)0x6ea8, (q15_t)0x2bcf, (q15_t)0x6eb0, (q15_t)0x2bc6, (q15_t)0x6eb9, (q15_t)0x2bbd, + (q15_t)0x6ec2, (q15_t)0x2bb4, (q15_t)0x6eca, (q15_t)0x2bab, (q15_t)0x6ed3, (q15_t)0x2ba1, (q15_t)0x6edb, (q15_t)0x2b98, + (q15_t)0x6ee4, (q15_t)0x2b8f, (q15_t)0x6eec, (q15_t)0x2b86, (q15_t)0x6ef5, (q15_t)0x2b7d, (q15_t)0x6efd, (q15_t)0x2b73, + (q15_t)0x6f06, (q15_t)0x2b6a, (q15_t)0x6f0e, (q15_t)0x2b61, (q15_t)0x6f17, (q15_t)0x2b58, (q15_t)0x6f20, (q15_t)0x2b4e, + (q15_t)0x6f28, (q15_t)0x2b45, (q15_t)0x6f30, (q15_t)0x2b3c, (q15_t)0x6f39, (q15_t)0x2b33, (q15_t)0x6f41, (q15_t)0x2b29, + (q15_t)0x6f4a, (q15_t)0x2b20, (q15_t)0x6f52, (q15_t)0x2b17, (q15_t)0x6f5b, (q15_t)0x2b0d, (q15_t)0x6f63, (q15_t)0x2b04, + (q15_t)0x6f6c, (q15_t)0x2afb, (q15_t)0x6f74, (q15_t)0x2af2, (q15_t)0x6f7d, (q15_t)0x2ae8, (q15_t)0x6f85, (q15_t)0x2adf, + (q15_t)0x6f8d, (q15_t)0x2ad6, (q15_t)0x6f96, (q15_t)0x2acc, (q15_t)0x6f9e, (q15_t)0x2ac3, (q15_t)0x6fa7, (q15_t)0x2ab9, + (q15_t)0x6faf, (q15_t)0x2ab0, (q15_t)0x6fb7, (q15_t)0x2aa7, (q15_t)0x6fc0, (q15_t)0x2a9d, (q15_t)0x6fc8, (q15_t)0x2a94, + (q15_t)0x6fd0, (q15_t)0x2a8b, (q15_t)0x6fd9, (q15_t)0x2a81, (q15_t)0x6fe1, (q15_t)0x2a78, (q15_t)0x6fea, (q15_t)0x2a6e, + (q15_t)0x6ff2, (q15_t)0x2a65, (q15_t)0x6ffa, (q15_t)0x2a5c, (q15_t)0x7002, (q15_t)0x2a52, (q15_t)0x700b, (q15_t)0x2a49, + (q15_t)0x7013, (q15_t)0x2a3f, (q15_t)0x701b, (q15_t)0x2a36, (q15_t)0x7024, (q15_t)0x2a2c, (q15_t)0x702c, (q15_t)0x2a23, + (q15_t)0x7034, (q15_t)0x2a1a, (q15_t)0x703c, (q15_t)0x2a10, (q15_t)0x7045, (q15_t)0x2a07, (q15_t)0x704d, (q15_t)0x29fd, + (q15_t)0x7055, (q15_t)0x29f4, (q15_t)0x705d, (q15_t)0x29ea, (q15_t)0x7066, (q15_t)0x29e1, (q15_t)0x706e, (q15_t)0x29d7, + (q15_t)0x7076, (q15_t)0x29ce, (q15_t)0x707e, (q15_t)0x29c4, (q15_t)0x7087, (q15_t)0x29bb, (q15_t)0x708f, (q15_t)0x29b1, + (q15_t)0x7097, (q15_t)0x29a7, (q15_t)0x709f, (q15_t)0x299e, (q15_t)0x70a7, (q15_t)0x2994, (q15_t)0x70af, (q15_t)0x298b, + (q15_t)0x70b8, (q15_t)0x2981, (q15_t)0x70c0, (q15_t)0x2978, (q15_t)0x70c8, (q15_t)0x296e, (q15_t)0x70d0, (q15_t)0x2965, + (q15_t)0x70d8, (q15_t)0x295b, (q15_t)0x70e0, (q15_t)0x2951, (q15_t)0x70e8, (q15_t)0x2948, (q15_t)0x70f0, (q15_t)0x293e, + (q15_t)0x70f9, (q15_t)0x2935, (q15_t)0x7101, (q15_t)0x292b, (q15_t)0x7109, (q15_t)0x2921, (q15_t)0x7111, (q15_t)0x2918, + (q15_t)0x7119, (q15_t)0x290e, (q15_t)0x7121, (q15_t)0x2904, (q15_t)0x7129, (q15_t)0x28fb, (q15_t)0x7131, (q15_t)0x28f1, + (q15_t)0x7139, (q15_t)0x28e7, (q15_t)0x7141, (q15_t)0x28de, (q15_t)0x7149, (q15_t)0x28d4, (q15_t)0x7151, (q15_t)0x28ca, + (q15_t)0x7159, (q15_t)0x28c1, (q15_t)0x7161, (q15_t)0x28b7, (q15_t)0x7169, (q15_t)0x28ad, (q15_t)0x7171, (q15_t)0x28a4, + (q15_t)0x7179, (q15_t)0x289a, (q15_t)0x7181, (q15_t)0x2890, (q15_t)0x7189, (q15_t)0x2886, (q15_t)0x7191, (q15_t)0x287d, + (q15_t)0x7199, (q15_t)0x2873, (q15_t)0x71a1, (q15_t)0x2869, (q15_t)0x71a9, (q15_t)0x2860, (q15_t)0x71b1, (q15_t)0x2856, + (q15_t)0x71b9, (q15_t)0x284c, (q15_t)0x71c0, (q15_t)0x2842, (q15_t)0x71c8, (q15_t)0x2838, (q15_t)0x71d0, (q15_t)0x282f, + (q15_t)0x71d8, (q15_t)0x2825, (q15_t)0x71e0, (q15_t)0x281b, (q15_t)0x71e8, (q15_t)0x2811, (q15_t)0x71f0, (q15_t)0x2808, + (q15_t)0x71f8, (q15_t)0x27fe, (q15_t)0x71ff, (q15_t)0x27f4, (q15_t)0x7207, (q15_t)0x27ea, (q15_t)0x720f, (q15_t)0x27e0, + (q15_t)0x7217, (q15_t)0x27d6, (q15_t)0x721f, (q15_t)0x27cd, (q15_t)0x7227, (q15_t)0x27c3, (q15_t)0x722e, (q15_t)0x27b9, + (q15_t)0x7236, (q15_t)0x27af, (q15_t)0x723e, (q15_t)0x27a5, (q15_t)0x7246, (q15_t)0x279b, (q15_t)0x724e, (q15_t)0x2791, + (q15_t)0x7255, (q15_t)0x2788, (q15_t)0x725d, (q15_t)0x277e, (q15_t)0x7265, (q15_t)0x2774, (q15_t)0x726d, (q15_t)0x276a, + (q15_t)0x7274, (q15_t)0x2760, (q15_t)0x727c, (q15_t)0x2756, (q15_t)0x7284, (q15_t)0x274c, (q15_t)0x728b, (q15_t)0x2742, + (q15_t)0x7293, (q15_t)0x2738, (q15_t)0x729b, (q15_t)0x272e, (q15_t)0x72a3, (q15_t)0x2724, (q15_t)0x72aa, (q15_t)0x271a, + (q15_t)0x72b2, (q15_t)0x2711, (q15_t)0x72ba, (q15_t)0x2707, (q15_t)0x72c1, (q15_t)0x26fd, (q15_t)0x72c9, (q15_t)0x26f3, + (q15_t)0x72d0, (q15_t)0x26e9, (q15_t)0x72d8, (q15_t)0x26df, (q15_t)0x72e0, (q15_t)0x26d5, (q15_t)0x72e7, (q15_t)0x26cb, + (q15_t)0x72ef, (q15_t)0x26c1, (q15_t)0x72f7, (q15_t)0x26b7, (q15_t)0x72fe, (q15_t)0x26ad, (q15_t)0x7306, (q15_t)0x26a3, + (q15_t)0x730d, (q15_t)0x2699, (q15_t)0x7315, (q15_t)0x268f, (q15_t)0x731d, (q15_t)0x2685, (q15_t)0x7324, (q15_t)0x267b, + (q15_t)0x732c, (q15_t)0x2671, (q15_t)0x7333, (q15_t)0x2666, (q15_t)0x733b, (q15_t)0x265c, (q15_t)0x7342, (q15_t)0x2652, + (q15_t)0x734a, (q15_t)0x2648, (q15_t)0x7351, (q15_t)0x263e, (q15_t)0x7359, (q15_t)0x2634, (q15_t)0x7360, (q15_t)0x262a, + (q15_t)0x7368, (q15_t)0x2620, (q15_t)0x736f, (q15_t)0x2616, (q15_t)0x7377, (q15_t)0x260c, (q15_t)0x737e, (q15_t)0x2602, + (q15_t)0x7386, (q15_t)0x25f8, (q15_t)0x738d, (q15_t)0x25ed, (q15_t)0x7395, (q15_t)0x25e3, (q15_t)0x739c, (q15_t)0x25d9, + (q15_t)0x73a3, (q15_t)0x25cf, (q15_t)0x73ab, (q15_t)0x25c5, (q15_t)0x73b2, (q15_t)0x25bb, (q15_t)0x73ba, (q15_t)0x25b1, + (q15_t)0x73c1, (q15_t)0x25a6, (q15_t)0x73c8, (q15_t)0x259c, (q15_t)0x73d0, (q15_t)0x2592, (q15_t)0x73d7, (q15_t)0x2588, + (q15_t)0x73df, (q15_t)0x257e, (q15_t)0x73e6, (q15_t)0x2574, (q15_t)0x73ed, (q15_t)0x2569, (q15_t)0x73f5, (q15_t)0x255f, + (q15_t)0x73fc, (q15_t)0x2555, (q15_t)0x7403, (q15_t)0x254b, (q15_t)0x740b, (q15_t)0x2541, (q15_t)0x7412, (q15_t)0x2536, + (q15_t)0x7419, (q15_t)0x252c, (q15_t)0x7420, (q15_t)0x2522, (q15_t)0x7428, (q15_t)0x2518, (q15_t)0x742f, (q15_t)0x250d, + (q15_t)0x7436, (q15_t)0x2503, (q15_t)0x743e, (q15_t)0x24f9, (q15_t)0x7445, (q15_t)0x24ef, (q15_t)0x744c, (q15_t)0x24e4, + (q15_t)0x7453, (q15_t)0x24da, (q15_t)0x745b, (q15_t)0x24d0, (q15_t)0x7462, (q15_t)0x24c5, (q15_t)0x7469, (q15_t)0x24bb, + (q15_t)0x7470, (q15_t)0x24b1, (q15_t)0x7477, (q15_t)0x24a7, (q15_t)0x747f, (q15_t)0x249c, (q15_t)0x7486, (q15_t)0x2492, + (q15_t)0x748d, (q15_t)0x2488, (q15_t)0x7494, (q15_t)0x247d, (q15_t)0x749b, (q15_t)0x2473, (q15_t)0x74a2, (q15_t)0x2469, + (q15_t)0x74aa, (q15_t)0x245e, (q15_t)0x74b1, (q15_t)0x2454, (q15_t)0x74b8, (q15_t)0x244a, (q15_t)0x74bf, (q15_t)0x243f, + (q15_t)0x74c6, (q15_t)0x2435, (q15_t)0x74cd, (q15_t)0x242b, (q15_t)0x74d4, (q15_t)0x2420, (q15_t)0x74db, (q15_t)0x2416, + (q15_t)0x74e2, (q15_t)0x240b, (q15_t)0x74ea, (q15_t)0x2401, (q15_t)0x74f1, (q15_t)0x23f7, (q15_t)0x74f8, (q15_t)0x23ec, + (q15_t)0x74ff, (q15_t)0x23e2, (q15_t)0x7506, (q15_t)0x23d7, (q15_t)0x750d, (q15_t)0x23cd, (q15_t)0x7514, (q15_t)0x23c3, + (q15_t)0x751b, (q15_t)0x23b8, (q15_t)0x7522, (q15_t)0x23ae, (q15_t)0x7529, (q15_t)0x23a3, (q15_t)0x7530, (q15_t)0x2399, + (q15_t)0x7537, (q15_t)0x238e, (q15_t)0x753e, (q15_t)0x2384, (q15_t)0x7545, (q15_t)0x237a, (q15_t)0x754c, (q15_t)0x236f, + (q15_t)0x7553, (q15_t)0x2365, (q15_t)0x755a, (q15_t)0x235a, (q15_t)0x7561, (q15_t)0x2350, (q15_t)0x7567, (q15_t)0x2345, + (q15_t)0x756e, (q15_t)0x233b, (q15_t)0x7575, (q15_t)0x2330, (q15_t)0x757c, (q15_t)0x2326, (q15_t)0x7583, (q15_t)0x231b, + (q15_t)0x758a, (q15_t)0x2311, (q15_t)0x7591, (q15_t)0x2306, (q15_t)0x7598, (q15_t)0x22fc, (q15_t)0x759f, (q15_t)0x22f1, + (q15_t)0x75a5, (q15_t)0x22e7, (q15_t)0x75ac, (q15_t)0x22dc, (q15_t)0x75b3, (q15_t)0x22d2, (q15_t)0x75ba, (q15_t)0x22c7, + (q15_t)0x75c1, (q15_t)0x22bc, (q15_t)0x75c8, (q15_t)0x22b2, (q15_t)0x75ce, (q15_t)0x22a7, (q15_t)0x75d5, (q15_t)0x229d, + (q15_t)0x75dc, (q15_t)0x2292, (q15_t)0x75e3, (q15_t)0x2288, (q15_t)0x75ea, (q15_t)0x227d, (q15_t)0x75f0, (q15_t)0x2272, + (q15_t)0x75f7, (q15_t)0x2268, (q15_t)0x75fe, (q15_t)0x225d, (q15_t)0x7605, (q15_t)0x2253, (q15_t)0x760b, (q15_t)0x2248, + (q15_t)0x7612, (q15_t)0x223d, (q15_t)0x7619, (q15_t)0x2233, (q15_t)0x7620, (q15_t)0x2228, (q15_t)0x7626, (q15_t)0x221e, + (q15_t)0x762d, (q15_t)0x2213, (q15_t)0x7634, (q15_t)0x2208, (q15_t)0x763a, (q15_t)0x21fe, (q15_t)0x7641, (q15_t)0x21f3, + (q15_t)0x7648, (q15_t)0x21e8, (q15_t)0x764e, (q15_t)0x21de, (q15_t)0x7655, (q15_t)0x21d3, (q15_t)0x765c, (q15_t)0x21c8, + (q15_t)0x7662, (q15_t)0x21be, (q15_t)0x7669, (q15_t)0x21b3, (q15_t)0x766f, (q15_t)0x21a8, (q15_t)0x7676, (q15_t)0x219e, + (q15_t)0x767d, (q15_t)0x2193, (q15_t)0x7683, (q15_t)0x2188, (q15_t)0x768a, (q15_t)0x217d, (q15_t)0x7690, (q15_t)0x2173, + (q15_t)0x7697, (q15_t)0x2168, (q15_t)0x769d, (q15_t)0x215d, (q15_t)0x76a4, (q15_t)0x2153, (q15_t)0x76ab, (q15_t)0x2148, + (q15_t)0x76b1, (q15_t)0x213d, (q15_t)0x76b8, (q15_t)0x2132, (q15_t)0x76be, (q15_t)0x2128, (q15_t)0x76c5, (q15_t)0x211d, + (q15_t)0x76cb, (q15_t)0x2112, (q15_t)0x76d2, (q15_t)0x2107, (q15_t)0x76d8, (q15_t)0x20fd, (q15_t)0x76df, (q15_t)0x20f2, + (q15_t)0x76e5, (q15_t)0x20e7, (q15_t)0x76eb, (q15_t)0x20dc, (q15_t)0x76f2, (q15_t)0x20d1, (q15_t)0x76f8, (q15_t)0x20c7, + (q15_t)0x76ff, (q15_t)0x20bc, (q15_t)0x7705, (q15_t)0x20b1, (q15_t)0x770c, (q15_t)0x20a6, (q15_t)0x7712, (q15_t)0x209b, + (q15_t)0x7718, (q15_t)0x2091, (q15_t)0x771f, (q15_t)0x2086, (q15_t)0x7725, (q15_t)0x207b, (q15_t)0x772c, (q15_t)0x2070, + (q15_t)0x7732, (q15_t)0x2065, (q15_t)0x7738, (q15_t)0x205b, (q15_t)0x773f, (q15_t)0x2050, (q15_t)0x7745, (q15_t)0x2045, + (q15_t)0x774b, (q15_t)0x203a, (q15_t)0x7752, (q15_t)0x202f, (q15_t)0x7758, (q15_t)0x2024, (q15_t)0x775e, (q15_t)0x2019, + (q15_t)0x7765, (q15_t)0x200f, (q15_t)0x776b, (q15_t)0x2004, (q15_t)0x7771, (q15_t)0x1ff9, (q15_t)0x7777, (q15_t)0x1fee, + (q15_t)0x777e, (q15_t)0x1fe3, (q15_t)0x7784, (q15_t)0x1fd8, (q15_t)0x778a, (q15_t)0x1fcd, (q15_t)0x7790, (q15_t)0x1fc2, + (q15_t)0x7797, (q15_t)0x1fb7, (q15_t)0x779d, (q15_t)0x1fac, (q15_t)0x77a3, (q15_t)0x1fa2, (q15_t)0x77a9, (q15_t)0x1f97, + (q15_t)0x77b0, (q15_t)0x1f8c, (q15_t)0x77b6, (q15_t)0x1f81, (q15_t)0x77bc, (q15_t)0x1f76, (q15_t)0x77c2, (q15_t)0x1f6b, + (q15_t)0x77c8, (q15_t)0x1f60, (q15_t)0x77ce, (q15_t)0x1f55, (q15_t)0x77d5, (q15_t)0x1f4a, (q15_t)0x77db, (q15_t)0x1f3f, + (q15_t)0x77e1, (q15_t)0x1f34, (q15_t)0x77e7, (q15_t)0x1f29, (q15_t)0x77ed, (q15_t)0x1f1e, (q15_t)0x77f3, (q15_t)0x1f13, + (q15_t)0x77f9, (q15_t)0x1f08, (q15_t)0x77ff, (q15_t)0x1efd, (q15_t)0x7805, (q15_t)0x1ef2, (q15_t)0x780b, (q15_t)0x1ee7, + (q15_t)0x7812, (q15_t)0x1edc, (q15_t)0x7818, (q15_t)0x1ed1, (q15_t)0x781e, (q15_t)0x1ec6, (q15_t)0x7824, (q15_t)0x1ebb, + (q15_t)0x782a, (q15_t)0x1eb0, (q15_t)0x7830, (q15_t)0x1ea5, (q15_t)0x7836, (q15_t)0x1e9a, (q15_t)0x783c, (q15_t)0x1e8f, + (q15_t)0x7842, (q15_t)0x1e84, (q15_t)0x7848, (q15_t)0x1e79, (q15_t)0x784e, (q15_t)0x1e6e, (q15_t)0x7854, (q15_t)0x1e63, + (q15_t)0x785a, (q15_t)0x1e58, (q15_t)0x7860, (q15_t)0x1e4d, (q15_t)0x7866, (q15_t)0x1e42, (q15_t)0x786b, (q15_t)0x1e36, + (q15_t)0x7871, (q15_t)0x1e2b, (q15_t)0x7877, (q15_t)0x1e20, (q15_t)0x787d, (q15_t)0x1e15, (q15_t)0x7883, (q15_t)0x1e0a, + (q15_t)0x7889, (q15_t)0x1dff, (q15_t)0x788f, (q15_t)0x1df4, (q15_t)0x7895, (q15_t)0x1de9, (q15_t)0x789b, (q15_t)0x1dde, + (q15_t)0x78a1, (q15_t)0x1dd3, (q15_t)0x78a6, (q15_t)0x1dc7, (q15_t)0x78ac, (q15_t)0x1dbc, (q15_t)0x78b2, (q15_t)0x1db1, + (q15_t)0x78b8, (q15_t)0x1da6, (q15_t)0x78be, (q15_t)0x1d9b, (q15_t)0x78c3, (q15_t)0x1d90, (q15_t)0x78c9, (q15_t)0x1d85, + (q15_t)0x78cf, (q15_t)0x1d79, (q15_t)0x78d5, (q15_t)0x1d6e, (q15_t)0x78db, (q15_t)0x1d63, (q15_t)0x78e0, (q15_t)0x1d58, + (q15_t)0x78e6, (q15_t)0x1d4d, (q15_t)0x78ec, (q15_t)0x1d42, (q15_t)0x78f2, (q15_t)0x1d36, (q15_t)0x78f7, (q15_t)0x1d2b, + (q15_t)0x78fd, (q15_t)0x1d20, (q15_t)0x7903, (q15_t)0x1d15, (q15_t)0x7909, (q15_t)0x1d0a, (q15_t)0x790e, (q15_t)0x1cff, + (q15_t)0x7914, (q15_t)0x1cf3, (q15_t)0x791a, (q15_t)0x1ce8, (q15_t)0x791f, (q15_t)0x1cdd, (q15_t)0x7925, (q15_t)0x1cd2, + (q15_t)0x792b, (q15_t)0x1cc6, (q15_t)0x7930, (q15_t)0x1cbb, (q15_t)0x7936, (q15_t)0x1cb0, (q15_t)0x793b, (q15_t)0x1ca5, + (q15_t)0x7941, (q15_t)0x1c99, (q15_t)0x7947, (q15_t)0x1c8e, (q15_t)0x794c, (q15_t)0x1c83, (q15_t)0x7952, (q15_t)0x1c78, + (q15_t)0x7958, (q15_t)0x1c6c, (q15_t)0x795d, (q15_t)0x1c61, (q15_t)0x7963, (q15_t)0x1c56, (q15_t)0x7968, (q15_t)0x1c4b, + (q15_t)0x796e, (q15_t)0x1c3f, (q15_t)0x7973, (q15_t)0x1c34, (q15_t)0x7979, (q15_t)0x1c29, (q15_t)0x797e, (q15_t)0x1c1e, + (q15_t)0x7984, (q15_t)0x1c12, (q15_t)0x7989, (q15_t)0x1c07, (q15_t)0x798f, (q15_t)0x1bfc, (q15_t)0x7994, (q15_t)0x1bf0, + (q15_t)0x799a, (q15_t)0x1be5, (q15_t)0x799f, (q15_t)0x1bda, (q15_t)0x79a5, (q15_t)0x1bce, (q15_t)0x79aa, (q15_t)0x1bc3, + (q15_t)0x79b0, (q15_t)0x1bb8, (q15_t)0x79b5, (q15_t)0x1bac, (q15_t)0x79bb, (q15_t)0x1ba1, (q15_t)0x79c0, (q15_t)0x1b96, + (q15_t)0x79c5, (q15_t)0x1b8a, (q15_t)0x79cb, (q15_t)0x1b7f, (q15_t)0x79d0, (q15_t)0x1b74, (q15_t)0x79d6, (q15_t)0x1b68, + (q15_t)0x79db, (q15_t)0x1b5d, (q15_t)0x79e0, (q15_t)0x1b52, (q15_t)0x79e6, (q15_t)0x1b46, (q15_t)0x79eb, (q15_t)0x1b3b, + (q15_t)0x79f0, (q15_t)0x1b30, (q15_t)0x79f6, (q15_t)0x1b24, (q15_t)0x79fb, (q15_t)0x1b19, (q15_t)0x7a00, (q15_t)0x1b0d, + (q15_t)0x7a06, (q15_t)0x1b02, (q15_t)0x7a0b, (q15_t)0x1af7, (q15_t)0x7a10, (q15_t)0x1aeb, (q15_t)0x7a16, (q15_t)0x1ae0, + (q15_t)0x7a1b, (q15_t)0x1ad4, (q15_t)0x7a20, (q15_t)0x1ac9, (q15_t)0x7a25, (q15_t)0x1abe, (q15_t)0x7a2b, (q15_t)0x1ab2, + (q15_t)0x7a30, (q15_t)0x1aa7, (q15_t)0x7a35, (q15_t)0x1a9b, (q15_t)0x7a3a, (q15_t)0x1a90, (q15_t)0x7a3f, (q15_t)0x1a84, + (q15_t)0x7a45, (q15_t)0x1a79, (q15_t)0x7a4a, (q15_t)0x1a6e, (q15_t)0x7a4f, (q15_t)0x1a62, (q15_t)0x7a54, (q15_t)0x1a57, + (q15_t)0x7a59, (q15_t)0x1a4b, (q15_t)0x7a5f, (q15_t)0x1a40, (q15_t)0x7a64, (q15_t)0x1a34, (q15_t)0x7a69, (q15_t)0x1a29, + (q15_t)0x7a6e, (q15_t)0x1a1d, (q15_t)0x7a73, (q15_t)0x1a12, (q15_t)0x7a78, (q15_t)0x1a06, (q15_t)0x7a7d, (q15_t)0x19fb, + (q15_t)0x7a82, (q15_t)0x19ef, (q15_t)0x7a88, (q15_t)0x19e4, (q15_t)0x7a8d, (q15_t)0x19d8, (q15_t)0x7a92, (q15_t)0x19cd, + (q15_t)0x7a97, (q15_t)0x19c1, (q15_t)0x7a9c, (q15_t)0x19b6, (q15_t)0x7aa1, (q15_t)0x19aa, (q15_t)0x7aa6, (q15_t)0x199f, + (q15_t)0x7aab, (q15_t)0x1993, (q15_t)0x7ab0, (q15_t)0x1988, (q15_t)0x7ab5, (q15_t)0x197c, (q15_t)0x7aba, (q15_t)0x1971, + (q15_t)0x7abf, (q15_t)0x1965, (q15_t)0x7ac4, (q15_t)0x195a, (q15_t)0x7ac9, (q15_t)0x194e, (q15_t)0x7ace, (q15_t)0x1943, + (q15_t)0x7ad3, (q15_t)0x1937, (q15_t)0x7ad8, (q15_t)0x192c, (q15_t)0x7add, (q15_t)0x1920, (q15_t)0x7ae2, (q15_t)0x1914, + (q15_t)0x7ae6, (q15_t)0x1909, (q15_t)0x7aeb, (q15_t)0x18fd, (q15_t)0x7af0, (q15_t)0x18f2, (q15_t)0x7af5, (q15_t)0x18e6, + (q15_t)0x7afa, (q15_t)0x18db, (q15_t)0x7aff, (q15_t)0x18cf, (q15_t)0x7b04, (q15_t)0x18c3, (q15_t)0x7b09, (q15_t)0x18b8, + (q15_t)0x7b0e, (q15_t)0x18ac, (q15_t)0x7b12, (q15_t)0x18a1, (q15_t)0x7b17, (q15_t)0x1895, (q15_t)0x7b1c, (q15_t)0x1889, + (q15_t)0x7b21, (q15_t)0x187e, (q15_t)0x7b26, (q15_t)0x1872, (q15_t)0x7b2a, (q15_t)0x1867, (q15_t)0x7b2f, (q15_t)0x185b, + (q15_t)0x7b34, (q15_t)0x184f, (q15_t)0x7b39, (q15_t)0x1844, (q15_t)0x7b3e, (q15_t)0x1838, (q15_t)0x7b42, (q15_t)0x182d, + (q15_t)0x7b47, (q15_t)0x1821, (q15_t)0x7b4c, (q15_t)0x1815, (q15_t)0x7b50, (q15_t)0x180a, (q15_t)0x7b55, (q15_t)0x17fe, + (q15_t)0x7b5a, (q15_t)0x17f2, (q15_t)0x7b5f, (q15_t)0x17e7, (q15_t)0x7b63, (q15_t)0x17db, (q15_t)0x7b68, (q15_t)0x17cf, + (q15_t)0x7b6d, (q15_t)0x17c4, (q15_t)0x7b71, (q15_t)0x17b8, (q15_t)0x7b76, (q15_t)0x17ac, (q15_t)0x7b7b, (q15_t)0x17a1, + (q15_t)0x7b7f, (q15_t)0x1795, (q15_t)0x7b84, (q15_t)0x1789, (q15_t)0x7b88, (q15_t)0x177e, (q15_t)0x7b8d, (q15_t)0x1772, + (q15_t)0x7b92, (q15_t)0x1766, (q15_t)0x7b96, (q15_t)0x175b, (q15_t)0x7b9b, (q15_t)0x174f, (q15_t)0x7b9f, (q15_t)0x1743, + (q15_t)0x7ba4, (q15_t)0x1737, (q15_t)0x7ba9, (q15_t)0x172c, (q15_t)0x7bad, (q15_t)0x1720, (q15_t)0x7bb2, (q15_t)0x1714, + (q15_t)0x7bb6, (q15_t)0x1709, (q15_t)0x7bbb, (q15_t)0x16fd, (q15_t)0x7bbf, (q15_t)0x16f1, (q15_t)0x7bc4, (q15_t)0x16e5, + (q15_t)0x7bc8, (q15_t)0x16da, (q15_t)0x7bcd, (q15_t)0x16ce, (q15_t)0x7bd1, (q15_t)0x16c2, (q15_t)0x7bd6, (q15_t)0x16b6, + (q15_t)0x7bda, (q15_t)0x16ab, (q15_t)0x7bde, (q15_t)0x169f, (q15_t)0x7be3, (q15_t)0x1693, (q15_t)0x7be7, (q15_t)0x1687, + (q15_t)0x7bec, (q15_t)0x167c, (q15_t)0x7bf0, (q15_t)0x1670, (q15_t)0x7bf5, (q15_t)0x1664, (q15_t)0x7bf9, (q15_t)0x1658, + (q15_t)0x7bfd, (q15_t)0x164c, (q15_t)0x7c02, (q15_t)0x1641, (q15_t)0x7c06, (q15_t)0x1635, (q15_t)0x7c0a, (q15_t)0x1629, + (q15_t)0x7c0f, (q15_t)0x161d, (q15_t)0x7c13, (q15_t)0x1612, (q15_t)0x7c17, (q15_t)0x1606, (q15_t)0x7c1c, (q15_t)0x15fa, + (q15_t)0x7c20, (q15_t)0x15ee, (q15_t)0x7c24, (q15_t)0x15e2, (q15_t)0x7c29, (q15_t)0x15d7, (q15_t)0x7c2d, (q15_t)0x15cb, + (q15_t)0x7c31, (q15_t)0x15bf, (q15_t)0x7c36, (q15_t)0x15b3, (q15_t)0x7c3a, (q15_t)0x15a7, (q15_t)0x7c3e, (q15_t)0x159b, + (q15_t)0x7c42, (q15_t)0x1590, (q15_t)0x7c46, (q15_t)0x1584, (q15_t)0x7c4b, (q15_t)0x1578, (q15_t)0x7c4f, (q15_t)0x156c, + (q15_t)0x7c53, (q15_t)0x1560, (q15_t)0x7c57, (q15_t)0x1554, (q15_t)0x7c5b, (q15_t)0x1549, (q15_t)0x7c60, (q15_t)0x153d, + (q15_t)0x7c64, (q15_t)0x1531, (q15_t)0x7c68, (q15_t)0x1525, (q15_t)0x7c6c, (q15_t)0x1519, (q15_t)0x7c70, (q15_t)0x150d, + (q15_t)0x7c74, (q15_t)0x1501, (q15_t)0x7c79, (q15_t)0x14f6, (q15_t)0x7c7d, (q15_t)0x14ea, (q15_t)0x7c81, (q15_t)0x14de, + (q15_t)0x7c85, (q15_t)0x14d2, (q15_t)0x7c89, (q15_t)0x14c6, (q15_t)0x7c8d, (q15_t)0x14ba, (q15_t)0x7c91, (q15_t)0x14ae, + (q15_t)0x7c95, (q15_t)0x14a2, (q15_t)0x7c99, (q15_t)0x1496, (q15_t)0x7c9d, (q15_t)0x148b, (q15_t)0x7ca1, (q15_t)0x147f, + (q15_t)0x7ca5, (q15_t)0x1473, (q15_t)0x7ca9, (q15_t)0x1467, (q15_t)0x7cad, (q15_t)0x145b, (q15_t)0x7cb1, (q15_t)0x144f, + (q15_t)0x7cb5, (q15_t)0x1443, (q15_t)0x7cb9, (q15_t)0x1437, (q15_t)0x7cbd, (q15_t)0x142b, (q15_t)0x7cc1, (q15_t)0x141f, + (q15_t)0x7cc5, (q15_t)0x1413, (q15_t)0x7cc9, (q15_t)0x1407, (q15_t)0x7ccd, (q15_t)0x13fb, (q15_t)0x7cd1, (q15_t)0x13f0, + (q15_t)0x7cd5, (q15_t)0x13e4, (q15_t)0x7cd9, (q15_t)0x13d8, (q15_t)0x7cdd, (q15_t)0x13cc, (q15_t)0x7ce0, (q15_t)0x13c0, + (q15_t)0x7ce4, (q15_t)0x13b4, (q15_t)0x7ce8, (q15_t)0x13a8, (q15_t)0x7cec, (q15_t)0x139c, (q15_t)0x7cf0, (q15_t)0x1390, + (q15_t)0x7cf4, (q15_t)0x1384, (q15_t)0x7cf8, (q15_t)0x1378, (q15_t)0x7cfb, (q15_t)0x136c, (q15_t)0x7cff, (q15_t)0x1360, + (q15_t)0x7d03, (q15_t)0x1354, (q15_t)0x7d07, (q15_t)0x1348, (q15_t)0x7d0b, (q15_t)0x133c, (q15_t)0x7d0e, (q15_t)0x1330, + (q15_t)0x7d12, (q15_t)0x1324, (q15_t)0x7d16, (q15_t)0x1318, (q15_t)0x7d1a, (q15_t)0x130c, (q15_t)0x7d1d, (q15_t)0x1300, + (q15_t)0x7d21, (q15_t)0x12f4, (q15_t)0x7d25, (q15_t)0x12e8, (q15_t)0x7d28, (q15_t)0x12dc, (q15_t)0x7d2c, (q15_t)0x12d0, + (q15_t)0x7d30, (q15_t)0x12c4, (q15_t)0x7d34, (q15_t)0x12b8, (q15_t)0x7d37, (q15_t)0x12ac, (q15_t)0x7d3b, (q15_t)0x12a0, + (q15_t)0x7d3f, (q15_t)0x1294, (q15_t)0x7d42, (q15_t)0x1288, (q15_t)0x7d46, (q15_t)0x127c, (q15_t)0x7d49, (q15_t)0x1270, + (q15_t)0x7d4d, (q15_t)0x1264, (q15_t)0x7d51, (q15_t)0x1258, (q15_t)0x7d54, (q15_t)0x124c, (q15_t)0x7d58, (q15_t)0x1240, + (q15_t)0x7d5b, (q15_t)0x1234, (q15_t)0x7d5f, (q15_t)0x1228, (q15_t)0x7d63, (q15_t)0x121c, (q15_t)0x7d66, (q15_t)0x1210, + (q15_t)0x7d6a, (q15_t)0x1204, (q15_t)0x7d6d, (q15_t)0x11f7, (q15_t)0x7d71, (q15_t)0x11eb, (q15_t)0x7d74, (q15_t)0x11df, + (q15_t)0x7d78, (q15_t)0x11d3, (q15_t)0x7d7b, (q15_t)0x11c7, (q15_t)0x7d7f, (q15_t)0x11bb, (q15_t)0x7d82, (q15_t)0x11af, + (q15_t)0x7d86, (q15_t)0x11a3, (q15_t)0x7d89, (q15_t)0x1197, (q15_t)0x7d8d, (q15_t)0x118b, (q15_t)0x7d90, (q15_t)0x117f, + (q15_t)0x7d93, (q15_t)0x1173, (q15_t)0x7d97, (q15_t)0x1167, (q15_t)0x7d9a, (q15_t)0x115a, (q15_t)0x7d9e, (q15_t)0x114e, + (q15_t)0x7da1, (q15_t)0x1142, (q15_t)0x7da4, (q15_t)0x1136, (q15_t)0x7da8, (q15_t)0x112a, (q15_t)0x7dab, (q15_t)0x111e, + (q15_t)0x7daf, (q15_t)0x1112, (q15_t)0x7db2, (q15_t)0x1106, (q15_t)0x7db5, (q15_t)0x10fa, (q15_t)0x7db9, (q15_t)0x10ed, + (q15_t)0x7dbc, (q15_t)0x10e1, (q15_t)0x7dbf, (q15_t)0x10d5, (q15_t)0x7dc2, (q15_t)0x10c9, (q15_t)0x7dc6, (q15_t)0x10bd, + (q15_t)0x7dc9, (q15_t)0x10b1, (q15_t)0x7dcc, (q15_t)0x10a5, (q15_t)0x7dd0, (q15_t)0x1099, (q15_t)0x7dd3, (q15_t)0x108c, + (q15_t)0x7dd6, (q15_t)0x1080, (q15_t)0x7dd9, (q15_t)0x1074, (q15_t)0x7ddd, (q15_t)0x1068, (q15_t)0x7de0, (q15_t)0x105c, + (q15_t)0x7de3, (q15_t)0x1050, (q15_t)0x7de6, (q15_t)0x1044, (q15_t)0x7de9, (q15_t)0x1037, (q15_t)0x7ded, (q15_t)0x102b, + (q15_t)0x7df0, (q15_t)0x101f, (q15_t)0x7df3, (q15_t)0x1013, (q15_t)0x7df6, (q15_t)0x1007, (q15_t)0x7df9, (q15_t)0xffb, + (q15_t)0x7dfc, (q15_t)0xfee, (q15_t)0x7dff, (q15_t)0xfe2, (q15_t)0x7e03, (q15_t)0xfd6, (q15_t)0x7e06, (q15_t)0xfca, + (q15_t)0x7e09, (q15_t)0xfbe, (q15_t)0x7e0c, (q15_t)0xfb2, (q15_t)0x7e0f, (q15_t)0xfa5, (q15_t)0x7e12, (q15_t)0xf99, + (q15_t)0x7e15, (q15_t)0xf8d, (q15_t)0x7e18, (q15_t)0xf81, (q15_t)0x7e1b, (q15_t)0xf75, (q15_t)0x7e1e, (q15_t)0xf68, + (q15_t)0x7e21, (q15_t)0xf5c, (q15_t)0x7e24, (q15_t)0xf50, (q15_t)0x7e27, (q15_t)0xf44, (q15_t)0x7e2a, (q15_t)0xf38, + (q15_t)0x7e2d, (q15_t)0xf2b, (q15_t)0x7e30, (q15_t)0xf1f, (q15_t)0x7e33, (q15_t)0xf13, (q15_t)0x7e36, (q15_t)0xf07, + (q15_t)0x7e39, (q15_t)0xefb, (q15_t)0x7e3c, (q15_t)0xeee, (q15_t)0x7e3f, (q15_t)0xee2, (q15_t)0x7e42, (q15_t)0xed6, + (q15_t)0x7e45, (q15_t)0xeca, (q15_t)0x7e48, (q15_t)0xebd, (q15_t)0x7e4a, (q15_t)0xeb1, (q15_t)0x7e4d, (q15_t)0xea5, + (q15_t)0x7e50, (q15_t)0xe99, (q15_t)0x7e53, (q15_t)0xe8c, (q15_t)0x7e56, (q15_t)0xe80, (q15_t)0x7e59, (q15_t)0xe74, + (q15_t)0x7e5c, (q15_t)0xe68, (q15_t)0x7e5e, (q15_t)0xe5c, (q15_t)0x7e61, (q15_t)0xe4f, (q15_t)0x7e64, (q15_t)0xe43, + (q15_t)0x7e67, (q15_t)0xe37, (q15_t)0x7e6a, (q15_t)0xe2b, (q15_t)0x7e6c, (q15_t)0xe1e, (q15_t)0x7e6f, (q15_t)0xe12, + (q15_t)0x7e72, (q15_t)0xe06, (q15_t)0x7e75, (q15_t)0xdf9, (q15_t)0x7e77, (q15_t)0xded, (q15_t)0x7e7a, (q15_t)0xde1, + (q15_t)0x7e7d, (q15_t)0xdd5, (q15_t)0x7e80, (q15_t)0xdc8, (q15_t)0x7e82, (q15_t)0xdbc, (q15_t)0x7e85, (q15_t)0xdb0, + (q15_t)0x7e88, (q15_t)0xda4, (q15_t)0x7e8a, (q15_t)0xd97, (q15_t)0x7e8d, (q15_t)0xd8b, (q15_t)0x7e90, (q15_t)0xd7f, + (q15_t)0x7e92, (q15_t)0xd72, (q15_t)0x7e95, (q15_t)0xd66, (q15_t)0x7e98, (q15_t)0xd5a, (q15_t)0x7e9a, (q15_t)0xd4e, + (q15_t)0x7e9d, (q15_t)0xd41, (q15_t)0x7e9f, (q15_t)0xd35, (q15_t)0x7ea2, (q15_t)0xd29, (q15_t)0x7ea5, (q15_t)0xd1c, + (q15_t)0x7ea7, (q15_t)0xd10, (q15_t)0x7eaa, (q15_t)0xd04, (q15_t)0x7eac, (q15_t)0xcf8, (q15_t)0x7eaf, (q15_t)0xceb, + (q15_t)0x7eb1, (q15_t)0xcdf, (q15_t)0x7eb4, (q15_t)0xcd3, (q15_t)0x7eb6, (q15_t)0xcc6, (q15_t)0x7eb9, (q15_t)0xcba, + (q15_t)0x7ebb, (q15_t)0xcae, (q15_t)0x7ebe, (q15_t)0xca1, (q15_t)0x7ec0, (q15_t)0xc95, (q15_t)0x7ec3, (q15_t)0xc89, + (q15_t)0x7ec5, (q15_t)0xc7c, (q15_t)0x7ec8, (q15_t)0xc70, (q15_t)0x7eca, (q15_t)0xc64, (q15_t)0x7ecc, (q15_t)0xc57, + (q15_t)0x7ecf, (q15_t)0xc4b, (q15_t)0x7ed1, (q15_t)0xc3f, (q15_t)0x7ed4, (q15_t)0xc32, (q15_t)0x7ed6, (q15_t)0xc26, + (q15_t)0x7ed8, (q15_t)0xc1a, (q15_t)0x7edb, (q15_t)0xc0d, (q15_t)0x7edd, (q15_t)0xc01, (q15_t)0x7ee0, (q15_t)0xbf5, + (q15_t)0x7ee2, (q15_t)0xbe8, (q15_t)0x7ee4, (q15_t)0xbdc, (q15_t)0x7ee7, (q15_t)0xbd0, (q15_t)0x7ee9, (q15_t)0xbc3, + (q15_t)0x7eeb, (q15_t)0xbb7, (q15_t)0x7eed, (q15_t)0xbab, (q15_t)0x7ef0, (q15_t)0xb9e, (q15_t)0x7ef2, (q15_t)0xb92, + (q15_t)0x7ef4, (q15_t)0xb85, (q15_t)0x7ef7, (q15_t)0xb79, (q15_t)0x7ef9, (q15_t)0xb6d, (q15_t)0x7efb, (q15_t)0xb60, + (q15_t)0x7efd, (q15_t)0xb54, (q15_t)0x7f00, (q15_t)0xb48, (q15_t)0x7f02, (q15_t)0xb3b, (q15_t)0x7f04, (q15_t)0xb2f, + (q15_t)0x7f06, (q15_t)0xb23, (q15_t)0x7f08, (q15_t)0xb16, (q15_t)0x7f0a, (q15_t)0xb0a, (q15_t)0x7f0d, (q15_t)0xafd, + (q15_t)0x7f0f, (q15_t)0xaf1, (q15_t)0x7f11, (q15_t)0xae5, (q15_t)0x7f13, (q15_t)0xad8, (q15_t)0x7f15, (q15_t)0xacc, + (q15_t)0x7f17, (q15_t)0xac0, (q15_t)0x7f19, (q15_t)0xab3, (q15_t)0x7f1c, (q15_t)0xaa7, (q15_t)0x7f1e, (q15_t)0xa9a, + (q15_t)0x7f20, (q15_t)0xa8e, (q15_t)0x7f22, (q15_t)0xa82, (q15_t)0x7f24, (q15_t)0xa75, (q15_t)0x7f26, (q15_t)0xa69, + (q15_t)0x7f28, (q15_t)0xa5c, (q15_t)0x7f2a, (q15_t)0xa50, (q15_t)0x7f2c, (q15_t)0xa44, (q15_t)0x7f2e, (q15_t)0xa37, + (q15_t)0x7f30, (q15_t)0xa2b, (q15_t)0x7f32, (q15_t)0xa1e, (q15_t)0x7f34, (q15_t)0xa12, (q15_t)0x7f36, (q15_t)0xa06, + (q15_t)0x7f38, (q15_t)0x9f9, (q15_t)0x7f3a, (q15_t)0x9ed, (q15_t)0x7f3c, (q15_t)0x9e0, (q15_t)0x7f3e, (q15_t)0x9d4, + (q15_t)0x7f40, (q15_t)0x9c7, (q15_t)0x7f42, (q15_t)0x9bb, (q15_t)0x7f43, (q15_t)0x9af, (q15_t)0x7f45, (q15_t)0x9a2, + (q15_t)0x7f47, (q15_t)0x996, (q15_t)0x7f49, (q15_t)0x989, (q15_t)0x7f4b, (q15_t)0x97d, (q15_t)0x7f4d, (q15_t)0x970, + (q15_t)0x7f4f, (q15_t)0x964, (q15_t)0x7f51, (q15_t)0x958, (q15_t)0x7f52, (q15_t)0x94b, (q15_t)0x7f54, (q15_t)0x93f, + (q15_t)0x7f56, (q15_t)0x932, (q15_t)0x7f58, (q15_t)0x926, (q15_t)0x7f5a, (q15_t)0x919, (q15_t)0x7f5b, (q15_t)0x90d, + (q15_t)0x7f5d, (q15_t)0x901, (q15_t)0x7f5f, (q15_t)0x8f4, (q15_t)0x7f61, (q15_t)0x8e8, (q15_t)0x7f62, (q15_t)0x8db, + (q15_t)0x7f64, (q15_t)0x8cf, (q15_t)0x7f66, (q15_t)0x8c2, (q15_t)0x7f68, (q15_t)0x8b6, (q15_t)0x7f69, (q15_t)0x8a9, + (q15_t)0x7f6b, (q15_t)0x89d, (q15_t)0x7f6d, (q15_t)0x891, (q15_t)0x7f6e, (q15_t)0x884, (q15_t)0x7f70, (q15_t)0x878, + (q15_t)0x7f72, (q15_t)0x86b, (q15_t)0x7f73, (q15_t)0x85f, (q15_t)0x7f75, (q15_t)0x852, (q15_t)0x7f77, (q15_t)0x846, + (q15_t)0x7f78, (q15_t)0x839, (q15_t)0x7f7a, (q15_t)0x82d, (q15_t)0x7f7b, (q15_t)0x820, (q15_t)0x7f7d, (q15_t)0x814, + (q15_t)0x7f7f, (q15_t)0x807, (q15_t)0x7f80, (q15_t)0x7fb, (q15_t)0x7f82, (q15_t)0x7ef, (q15_t)0x7f83, (q15_t)0x7e2, + (q15_t)0x7f85, (q15_t)0x7d6, (q15_t)0x7f86, (q15_t)0x7c9, (q15_t)0x7f88, (q15_t)0x7bd, (q15_t)0x7f89, (q15_t)0x7b0, + (q15_t)0x7f8b, (q15_t)0x7a4, (q15_t)0x7f8c, (q15_t)0x797, (q15_t)0x7f8e, (q15_t)0x78b, (q15_t)0x7f8f, (q15_t)0x77e, + (q15_t)0x7f91, (q15_t)0x772, (q15_t)0x7f92, (q15_t)0x765, (q15_t)0x7f94, (q15_t)0x759, (q15_t)0x7f95, (q15_t)0x74c, + (q15_t)0x7f97, (q15_t)0x740, (q15_t)0x7f98, (q15_t)0x733, (q15_t)0x7f99, (q15_t)0x727, (q15_t)0x7f9b, (q15_t)0x71a, + (q15_t)0x7f9c, (q15_t)0x70e, (q15_t)0x7f9e, (q15_t)0x701, (q15_t)0x7f9f, (q15_t)0x6f5, (q15_t)0x7fa0, (q15_t)0x6e8, + (q15_t)0x7fa2, (q15_t)0x6dc, (q15_t)0x7fa3, (q15_t)0x6cf, (q15_t)0x7fa4, (q15_t)0x6c3, (q15_t)0x7fa6, (q15_t)0x6b6, + (q15_t)0x7fa7, (q15_t)0x6aa, (q15_t)0x7fa8, (q15_t)0x69d, (q15_t)0x7faa, (q15_t)0x691, (q15_t)0x7fab, (q15_t)0x684, + (q15_t)0x7fac, (q15_t)0x678, (q15_t)0x7fad, (q15_t)0x66b, (q15_t)0x7faf, (q15_t)0x65f, (q15_t)0x7fb0, (q15_t)0x652, + (q15_t)0x7fb1, (q15_t)0x646, (q15_t)0x7fb2, (q15_t)0x639, (q15_t)0x7fb4, (q15_t)0x62d, (q15_t)0x7fb5, (q15_t)0x620, + (q15_t)0x7fb6, (q15_t)0x614, (q15_t)0x7fb7, (q15_t)0x607, (q15_t)0x7fb8, (q15_t)0x5fb, (q15_t)0x7fb9, (q15_t)0x5ee, + (q15_t)0x7fbb, (q15_t)0x5e2, (q15_t)0x7fbc, (q15_t)0x5d5, (q15_t)0x7fbd, (q15_t)0x5c9, (q15_t)0x7fbe, (q15_t)0x5bc, + (q15_t)0x7fbf, (q15_t)0x5b0, (q15_t)0x7fc0, (q15_t)0x5a3, (q15_t)0x7fc1, (q15_t)0x597, (q15_t)0x7fc3, (q15_t)0x58a, + (q15_t)0x7fc4, (q15_t)0x57e, (q15_t)0x7fc5, (q15_t)0x571, (q15_t)0x7fc6, (q15_t)0x565, (q15_t)0x7fc7, (q15_t)0x558, + (q15_t)0x7fc8, (q15_t)0x54c, (q15_t)0x7fc9, (q15_t)0x53f, (q15_t)0x7fca, (q15_t)0x533, (q15_t)0x7fcb, (q15_t)0x526, + (q15_t)0x7fcc, (q15_t)0x51a, (q15_t)0x7fcd, (q15_t)0x50d, (q15_t)0x7fce, (q15_t)0x500, (q15_t)0x7fcf, (q15_t)0x4f4, + (q15_t)0x7fd0, (q15_t)0x4e7, (q15_t)0x7fd1, (q15_t)0x4db, (q15_t)0x7fd2, (q15_t)0x4ce, (q15_t)0x7fd3, (q15_t)0x4c2, + (q15_t)0x7fd4, (q15_t)0x4b5, (q15_t)0x7fd5, (q15_t)0x4a9, (q15_t)0x7fd5, (q15_t)0x49c, (q15_t)0x7fd6, (q15_t)0x490, + (q15_t)0x7fd7, (q15_t)0x483, (q15_t)0x7fd8, (q15_t)0x477, (q15_t)0x7fd9, (q15_t)0x46a, (q15_t)0x7fda, (q15_t)0x45e, + (q15_t)0x7fdb, (q15_t)0x451, (q15_t)0x7fdc, (q15_t)0x444, (q15_t)0x7fdc, (q15_t)0x438, (q15_t)0x7fdd, (q15_t)0x42b, + (q15_t)0x7fde, (q15_t)0x41f, (q15_t)0x7fdf, (q15_t)0x412, (q15_t)0x7fe0, (q15_t)0x406, (q15_t)0x7fe0, (q15_t)0x3f9, + (q15_t)0x7fe1, (q15_t)0x3ed, (q15_t)0x7fe2, (q15_t)0x3e0, (q15_t)0x7fe3, (q15_t)0x3d4, (q15_t)0x7fe3, (q15_t)0x3c7, + (q15_t)0x7fe4, (q15_t)0x3bb, (q15_t)0x7fe5, (q15_t)0x3ae, (q15_t)0x7fe6, (q15_t)0x3a1, (q15_t)0x7fe6, (q15_t)0x395, + (q15_t)0x7fe7, (q15_t)0x388, (q15_t)0x7fe8, (q15_t)0x37c, (q15_t)0x7fe8, (q15_t)0x36f, (q15_t)0x7fe9, (q15_t)0x363, + (q15_t)0x7fea, (q15_t)0x356, (q15_t)0x7fea, (q15_t)0x34a, (q15_t)0x7feb, (q15_t)0x33d, (q15_t)0x7fec, (q15_t)0x330, + (q15_t)0x7fec, (q15_t)0x324, (q15_t)0x7fed, (q15_t)0x317, (q15_t)0x7fed, (q15_t)0x30b, (q15_t)0x7fee, (q15_t)0x2fe, + (q15_t)0x7fef, (q15_t)0x2f2, (q15_t)0x7fef, (q15_t)0x2e5, (q15_t)0x7ff0, (q15_t)0x2d9, (q15_t)0x7ff0, (q15_t)0x2cc, + (q15_t)0x7ff1, (q15_t)0x2c0, (q15_t)0x7ff1, (q15_t)0x2b3, (q15_t)0x7ff2, (q15_t)0x2a6, (q15_t)0x7ff2, (q15_t)0x29a, + (q15_t)0x7ff3, (q15_t)0x28d, (q15_t)0x7ff3, (q15_t)0x281, (q15_t)0x7ff4, (q15_t)0x274, (q15_t)0x7ff4, (q15_t)0x268, + (q15_t)0x7ff5, (q15_t)0x25b, (q15_t)0x7ff5, (q15_t)0x24e, (q15_t)0x7ff6, (q15_t)0x242, (q15_t)0x7ff6, (q15_t)0x235, + (q15_t)0x7ff7, (q15_t)0x229, (q15_t)0x7ff7, (q15_t)0x21c, (q15_t)0x7ff7, (q15_t)0x210, (q15_t)0x7ff8, (q15_t)0x203, + (q15_t)0x7ff8, (q15_t)0x1f7, (q15_t)0x7ff9, (q15_t)0x1ea, (q15_t)0x7ff9, (q15_t)0x1dd, (q15_t)0x7ff9, (q15_t)0x1d1, + (q15_t)0x7ffa, (q15_t)0x1c4, (q15_t)0x7ffa, (q15_t)0x1b8, (q15_t)0x7ffa, (q15_t)0x1ab, (q15_t)0x7ffb, (q15_t)0x19f, + (q15_t)0x7ffb, (q15_t)0x192, (q15_t)0x7ffb, (q15_t)0x186, (q15_t)0x7ffc, (q15_t)0x179, (q15_t)0x7ffc, (q15_t)0x16c, + (q15_t)0x7ffc, (q15_t)0x160, (q15_t)0x7ffc, (q15_t)0x153, (q15_t)0x7ffd, (q15_t)0x147, (q15_t)0x7ffd, (q15_t)0x13a, + (q15_t)0x7ffd, (q15_t)0x12e, (q15_t)0x7ffd, (q15_t)0x121, (q15_t)0x7ffe, (q15_t)0x114, (q15_t)0x7ffe, (q15_t)0x108, + (q15_t)0x7ffe, (q15_t)0xfb, (q15_t)0x7ffe, (q15_t)0xef, (q15_t)0x7ffe, (q15_t)0xe2, (q15_t)0x7fff, (q15_t)0xd6, + (q15_t)0x7fff, (q15_t)0xc9, (q15_t)0x7fff, (q15_t)0xbc, (q15_t)0x7fff, (q15_t)0xb0, (q15_t)0x7fff, (q15_t)0xa3, + (q15_t)0x7fff, (q15_t)0x97, (q15_t)0x7fff, (q15_t)0x8a, (q15_t)0x7fff, (q15_t)0x7e, (q15_t)0x7fff, (q15_t)0x71, + (q15_t)0x7fff, (q15_t)0x65, (q15_t)0x7fff, (q15_t)0x58, (q15_t)0x7fff, (q15_t)0x4b, (q15_t)0x7fff, (q15_t)0x3f, + (q15_t)0x7fff, (q15_t)0x32, (q15_t)0x7fff, (q15_t)0x26, (q15_t)0x7fff, (q15_t)0x19, (q15_t)0x7fff, (q15_t)0xd, + (q15_t)0x7fff, (q15_t)0x0, (q15_t)0x7fff, (q15_t)0xfff3, (q15_t)0x7fff, (q15_t)0xffe7, (q15_t)0x7fff, (q15_t)0xffda, + (q15_t)0x7fff, (q15_t)0xffce, (q15_t)0x7fff, (q15_t)0xffc1, (q15_t)0x7fff, (q15_t)0xffb5, (q15_t)0x7fff, (q15_t)0xffa8, + (q15_t)0x7fff, (q15_t)0xff9b, (q15_t)0x7fff, (q15_t)0xff8f, (q15_t)0x7fff, (q15_t)0xff82, (q15_t)0x7fff, (q15_t)0xff76, + (q15_t)0x7fff, (q15_t)0xff69, (q15_t)0x7fff, (q15_t)0xff5d, (q15_t)0x7fff, (q15_t)0xff50, (q15_t)0x7fff, (q15_t)0xff44, + (q15_t)0x7fff, (q15_t)0xff37, (q15_t)0x7fff, (q15_t)0xff2a, (q15_t)0x7ffe, (q15_t)0xff1e, (q15_t)0x7ffe, (q15_t)0xff11, + (q15_t)0x7ffe, (q15_t)0xff05, (q15_t)0x7ffe, (q15_t)0xfef8, (q15_t)0x7ffe, (q15_t)0xfeec, (q15_t)0x7ffd, (q15_t)0xfedf, + (q15_t)0x7ffd, (q15_t)0xfed2, (q15_t)0x7ffd, (q15_t)0xfec6, (q15_t)0x7ffd, (q15_t)0xfeb9, (q15_t)0x7ffc, (q15_t)0xfead, + (q15_t)0x7ffc, (q15_t)0xfea0, (q15_t)0x7ffc, (q15_t)0xfe94, (q15_t)0x7ffc, (q15_t)0xfe87, (q15_t)0x7ffb, (q15_t)0xfe7a, + (q15_t)0x7ffb, (q15_t)0xfe6e, (q15_t)0x7ffb, (q15_t)0xfe61, (q15_t)0x7ffa, (q15_t)0xfe55, (q15_t)0x7ffa, (q15_t)0xfe48, + (q15_t)0x7ffa, (q15_t)0xfe3c, (q15_t)0x7ff9, (q15_t)0xfe2f, (q15_t)0x7ff9, (q15_t)0xfe23, (q15_t)0x7ff9, (q15_t)0xfe16, + (q15_t)0x7ff8, (q15_t)0xfe09, (q15_t)0x7ff8, (q15_t)0xfdfd, (q15_t)0x7ff7, (q15_t)0xfdf0, (q15_t)0x7ff7, (q15_t)0xfde4, + (q15_t)0x7ff7, (q15_t)0xfdd7, (q15_t)0x7ff6, (q15_t)0xfdcb, (q15_t)0x7ff6, (q15_t)0xfdbe, (q15_t)0x7ff5, (q15_t)0xfdb2, + (q15_t)0x7ff5, (q15_t)0xfda5, (q15_t)0x7ff4, (q15_t)0xfd98, (q15_t)0x7ff4, (q15_t)0xfd8c, (q15_t)0x7ff3, (q15_t)0xfd7f, + (q15_t)0x7ff3, (q15_t)0xfd73, (q15_t)0x7ff2, (q15_t)0xfd66, (q15_t)0x7ff2, (q15_t)0xfd5a, (q15_t)0x7ff1, (q15_t)0xfd4d, + (q15_t)0x7ff1, (q15_t)0xfd40, (q15_t)0x7ff0, (q15_t)0xfd34, (q15_t)0x7ff0, (q15_t)0xfd27, (q15_t)0x7fef, (q15_t)0xfd1b, + (q15_t)0x7fef, (q15_t)0xfd0e, (q15_t)0x7fee, (q15_t)0xfd02, (q15_t)0x7fed, (q15_t)0xfcf5, (q15_t)0x7fed, (q15_t)0xfce9, + (q15_t)0x7fec, (q15_t)0xfcdc, (q15_t)0x7fec, (q15_t)0xfcd0, (q15_t)0x7feb, (q15_t)0xfcc3, (q15_t)0x7fea, (q15_t)0xfcb6, + (q15_t)0x7fea, (q15_t)0xfcaa, (q15_t)0x7fe9, (q15_t)0xfc9d, (q15_t)0x7fe8, (q15_t)0xfc91, (q15_t)0x7fe8, (q15_t)0xfc84, + (q15_t)0x7fe7, (q15_t)0xfc78, (q15_t)0x7fe6, (q15_t)0xfc6b, (q15_t)0x7fe6, (q15_t)0xfc5f, (q15_t)0x7fe5, (q15_t)0xfc52, + (q15_t)0x7fe4, (q15_t)0xfc45, (q15_t)0x7fe3, (q15_t)0xfc39, (q15_t)0x7fe3, (q15_t)0xfc2c, (q15_t)0x7fe2, (q15_t)0xfc20, + (q15_t)0x7fe1, (q15_t)0xfc13, (q15_t)0x7fe0, (q15_t)0xfc07, (q15_t)0x7fe0, (q15_t)0xfbfa, (q15_t)0x7fdf, (q15_t)0xfbee, + (q15_t)0x7fde, (q15_t)0xfbe1, (q15_t)0x7fdd, (q15_t)0xfbd5, (q15_t)0x7fdc, (q15_t)0xfbc8, (q15_t)0x7fdc, (q15_t)0xfbbc, + (q15_t)0x7fdb, (q15_t)0xfbaf, (q15_t)0x7fda, (q15_t)0xfba2, (q15_t)0x7fd9, (q15_t)0xfb96, (q15_t)0x7fd8, (q15_t)0xfb89, + (q15_t)0x7fd7, (q15_t)0xfb7d, (q15_t)0x7fd6, (q15_t)0xfb70, (q15_t)0x7fd5, (q15_t)0xfb64, (q15_t)0x7fd5, (q15_t)0xfb57, + (q15_t)0x7fd4, (q15_t)0xfb4b, (q15_t)0x7fd3, (q15_t)0xfb3e, (q15_t)0x7fd2, (q15_t)0xfb32, (q15_t)0x7fd1, (q15_t)0xfb25, + (q15_t)0x7fd0, (q15_t)0xfb19, (q15_t)0x7fcf, (q15_t)0xfb0c, (q15_t)0x7fce, (q15_t)0xfb00, (q15_t)0x7fcd, (q15_t)0xfaf3, + (q15_t)0x7fcc, (q15_t)0xfae6, (q15_t)0x7fcb, (q15_t)0xfada, (q15_t)0x7fca, (q15_t)0xfacd, (q15_t)0x7fc9, (q15_t)0xfac1, + (q15_t)0x7fc8, (q15_t)0xfab4, (q15_t)0x7fc7, (q15_t)0xfaa8, (q15_t)0x7fc6, (q15_t)0xfa9b, (q15_t)0x7fc5, (q15_t)0xfa8f, + (q15_t)0x7fc4, (q15_t)0xfa82, (q15_t)0x7fc3, (q15_t)0xfa76, (q15_t)0x7fc1, (q15_t)0xfa69, (q15_t)0x7fc0, (q15_t)0xfa5d, + (q15_t)0x7fbf, (q15_t)0xfa50, (q15_t)0x7fbe, (q15_t)0xfa44, (q15_t)0x7fbd, (q15_t)0xfa37, (q15_t)0x7fbc, (q15_t)0xfa2b, + (q15_t)0x7fbb, (q15_t)0xfa1e, (q15_t)0x7fb9, (q15_t)0xfa12, (q15_t)0x7fb8, (q15_t)0xfa05, (q15_t)0x7fb7, (q15_t)0xf9f9, + (q15_t)0x7fb6, (q15_t)0xf9ec, (q15_t)0x7fb5, (q15_t)0xf9e0, (q15_t)0x7fb4, (q15_t)0xf9d3, (q15_t)0x7fb2, (q15_t)0xf9c7, + (q15_t)0x7fb1, (q15_t)0xf9ba, (q15_t)0x7fb0, (q15_t)0xf9ae, (q15_t)0x7faf, (q15_t)0xf9a1, (q15_t)0x7fad, (q15_t)0xf995, + (q15_t)0x7fac, (q15_t)0xf988, (q15_t)0x7fab, (q15_t)0xf97c, (q15_t)0x7faa, (q15_t)0xf96f, (q15_t)0x7fa8, (q15_t)0xf963, + (q15_t)0x7fa7, (q15_t)0xf956, (q15_t)0x7fa6, (q15_t)0xf94a, (q15_t)0x7fa4, (q15_t)0xf93d, (q15_t)0x7fa3, (q15_t)0xf931, + (q15_t)0x7fa2, (q15_t)0xf924, (q15_t)0x7fa0, (q15_t)0xf918, (q15_t)0x7f9f, (q15_t)0xf90b, (q15_t)0x7f9e, (q15_t)0xf8ff, + (q15_t)0x7f9c, (q15_t)0xf8f2, (q15_t)0x7f9b, (q15_t)0xf8e6, (q15_t)0x7f99, (q15_t)0xf8d9, (q15_t)0x7f98, (q15_t)0xf8cd, + (q15_t)0x7f97, (q15_t)0xf8c0, (q15_t)0x7f95, (q15_t)0xf8b4, (q15_t)0x7f94, (q15_t)0xf8a7, (q15_t)0x7f92, (q15_t)0xf89b, + (q15_t)0x7f91, (q15_t)0xf88e, (q15_t)0x7f8f, (q15_t)0xf882, (q15_t)0x7f8e, (q15_t)0xf875, (q15_t)0x7f8c, (q15_t)0xf869, + (q15_t)0x7f8b, (q15_t)0xf85c, (q15_t)0x7f89, (q15_t)0xf850, (q15_t)0x7f88, (q15_t)0xf843, (q15_t)0x7f86, (q15_t)0xf837, + (q15_t)0x7f85, (q15_t)0xf82a, (q15_t)0x7f83, (q15_t)0xf81e, (q15_t)0x7f82, (q15_t)0xf811, (q15_t)0x7f80, (q15_t)0xf805, + (q15_t)0x7f7f, (q15_t)0xf7f9, (q15_t)0x7f7d, (q15_t)0xf7ec, (q15_t)0x7f7b, (q15_t)0xf7e0, (q15_t)0x7f7a, (q15_t)0xf7d3, + (q15_t)0x7f78, (q15_t)0xf7c7, (q15_t)0x7f77, (q15_t)0xf7ba, (q15_t)0x7f75, (q15_t)0xf7ae, (q15_t)0x7f73, (q15_t)0xf7a1, + (q15_t)0x7f72, (q15_t)0xf795, (q15_t)0x7f70, (q15_t)0xf788, (q15_t)0x7f6e, (q15_t)0xf77c, (q15_t)0x7f6d, (q15_t)0xf76f, + (q15_t)0x7f6b, (q15_t)0xf763, (q15_t)0x7f69, (q15_t)0xf757, (q15_t)0x7f68, (q15_t)0xf74a, (q15_t)0x7f66, (q15_t)0xf73e, + (q15_t)0x7f64, (q15_t)0xf731, (q15_t)0x7f62, (q15_t)0xf725, (q15_t)0x7f61, (q15_t)0xf718, (q15_t)0x7f5f, (q15_t)0xf70c, + (q15_t)0x7f5d, (q15_t)0xf6ff, (q15_t)0x7f5b, (q15_t)0xf6f3, (q15_t)0x7f5a, (q15_t)0xf6e7, (q15_t)0x7f58, (q15_t)0xf6da, + (q15_t)0x7f56, (q15_t)0xf6ce, (q15_t)0x7f54, (q15_t)0xf6c1, (q15_t)0x7f52, (q15_t)0xf6b5, (q15_t)0x7f51, (q15_t)0xf6a8, + (q15_t)0x7f4f, (q15_t)0xf69c, (q15_t)0x7f4d, (q15_t)0xf690, (q15_t)0x7f4b, (q15_t)0xf683, (q15_t)0x7f49, (q15_t)0xf677, + (q15_t)0x7f47, (q15_t)0xf66a, (q15_t)0x7f45, (q15_t)0xf65e, (q15_t)0x7f43, (q15_t)0xf651, (q15_t)0x7f42, (q15_t)0xf645, + (q15_t)0x7f40, (q15_t)0xf639, (q15_t)0x7f3e, (q15_t)0xf62c, (q15_t)0x7f3c, (q15_t)0xf620, (q15_t)0x7f3a, (q15_t)0xf613, + (q15_t)0x7f38, (q15_t)0xf607, (q15_t)0x7f36, (q15_t)0xf5fa, (q15_t)0x7f34, (q15_t)0xf5ee, (q15_t)0x7f32, (q15_t)0xf5e2, + (q15_t)0x7f30, (q15_t)0xf5d5, (q15_t)0x7f2e, (q15_t)0xf5c9, (q15_t)0x7f2c, (q15_t)0xf5bc, (q15_t)0x7f2a, (q15_t)0xf5b0, + (q15_t)0x7f28, (q15_t)0xf5a4, (q15_t)0x7f26, (q15_t)0xf597, (q15_t)0x7f24, (q15_t)0xf58b, (q15_t)0x7f22, (q15_t)0xf57e, + (q15_t)0x7f20, (q15_t)0xf572, (q15_t)0x7f1e, (q15_t)0xf566, (q15_t)0x7f1c, (q15_t)0xf559, (q15_t)0x7f19, (q15_t)0xf54d, + (q15_t)0x7f17, (q15_t)0xf540, (q15_t)0x7f15, (q15_t)0xf534, (q15_t)0x7f13, (q15_t)0xf528, (q15_t)0x7f11, (q15_t)0xf51b, + (q15_t)0x7f0f, (q15_t)0xf50f, (q15_t)0x7f0d, (q15_t)0xf503, (q15_t)0x7f0a, (q15_t)0xf4f6, (q15_t)0x7f08, (q15_t)0xf4ea, + (q15_t)0x7f06, (q15_t)0xf4dd, (q15_t)0x7f04, (q15_t)0xf4d1, (q15_t)0x7f02, (q15_t)0xf4c5, (q15_t)0x7f00, (q15_t)0xf4b8, + (q15_t)0x7efd, (q15_t)0xf4ac, (q15_t)0x7efb, (q15_t)0xf4a0, (q15_t)0x7ef9, (q15_t)0xf493, (q15_t)0x7ef7, (q15_t)0xf487, + (q15_t)0x7ef4, (q15_t)0xf47b, (q15_t)0x7ef2, (q15_t)0xf46e, (q15_t)0x7ef0, (q15_t)0xf462, (q15_t)0x7eed, (q15_t)0xf455, + (q15_t)0x7eeb, (q15_t)0xf449, (q15_t)0x7ee9, (q15_t)0xf43d, (q15_t)0x7ee7, (q15_t)0xf430, (q15_t)0x7ee4, (q15_t)0xf424, + (q15_t)0x7ee2, (q15_t)0xf418, (q15_t)0x7ee0, (q15_t)0xf40b, (q15_t)0x7edd, (q15_t)0xf3ff, (q15_t)0x7edb, (q15_t)0xf3f3, + (q15_t)0x7ed8, (q15_t)0xf3e6, (q15_t)0x7ed6, (q15_t)0xf3da, (q15_t)0x7ed4, (q15_t)0xf3ce, (q15_t)0x7ed1, (q15_t)0xf3c1, + (q15_t)0x7ecf, (q15_t)0xf3b5, (q15_t)0x7ecc, (q15_t)0xf3a9, (q15_t)0x7eca, (q15_t)0xf39c, (q15_t)0x7ec8, (q15_t)0xf390, + (q15_t)0x7ec5, (q15_t)0xf384, (q15_t)0x7ec3, (q15_t)0xf377, (q15_t)0x7ec0, (q15_t)0xf36b, (q15_t)0x7ebe, (q15_t)0xf35f, + (q15_t)0x7ebb, (q15_t)0xf352, (q15_t)0x7eb9, (q15_t)0xf346, (q15_t)0x7eb6, (q15_t)0xf33a, (q15_t)0x7eb4, (q15_t)0xf32d, + (q15_t)0x7eb1, (q15_t)0xf321, (q15_t)0x7eaf, (q15_t)0xf315, (q15_t)0x7eac, (q15_t)0xf308, (q15_t)0x7eaa, (q15_t)0xf2fc, + (q15_t)0x7ea7, (q15_t)0xf2f0, (q15_t)0x7ea5, (q15_t)0xf2e4, (q15_t)0x7ea2, (q15_t)0xf2d7, (q15_t)0x7e9f, (q15_t)0xf2cb, + (q15_t)0x7e9d, (q15_t)0xf2bf, (q15_t)0x7e9a, (q15_t)0xf2b2, (q15_t)0x7e98, (q15_t)0xf2a6, (q15_t)0x7e95, (q15_t)0xf29a, + (q15_t)0x7e92, (q15_t)0xf28e, (q15_t)0x7e90, (q15_t)0xf281, (q15_t)0x7e8d, (q15_t)0xf275, (q15_t)0x7e8a, (q15_t)0xf269, + (q15_t)0x7e88, (q15_t)0xf25c, (q15_t)0x7e85, (q15_t)0xf250, (q15_t)0x7e82, (q15_t)0xf244, (q15_t)0x7e80, (q15_t)0xf238, + (q15_t)0x7e7d, (q15_t)0xf22b, (q15_t)0x7e7a, (q15_t)0xf21f, (q15_t)0x7e77, (q15_t)0xf213, (q15_t)0x7e75, (q15_t)0xf207, + (q15_t)0x7e72, (q15_t)0xf1fa, (q15_t)0x7e6f, (q15_t)0xf1ee, (q15_t)0x7e6c, (q15_t)0xf1e2, (q15_t)0x7e6a, (q15_t)0xf1d5, + (q15_t)0x7e67, (q15_t)0xf1c9, (q15_t)0x7e64, (q15_t)0xf1bd, (q15_t)0x7e61, (q15_t)0xf1b1, (q15_t)0x7e5e, (q15_t)0xf1a4, + (q15_t)0x7e5c, (q15_t)0xf198, (q15_t)0x7e59, (q15_t)0xf18c, (q15_t)0x7e56, (q15_t)0xf180, (q15_t)0x7e53, (q15_t)0xf174, + (q15_t)0x7e50, (q15_t)0xf167, (q15_t)0x7e4d, (q15_t)0xf15b, (q15_t)0x7e4a, (q15_t)0xf14f, (q15_t)0x7e48, (q15_t)0xf143, + (q15_t)0x7e45, (q15_t)0xf136, (q15_t)0x7e42, (q15_t)0xf12a, (q15_t)0x7e3f, (q15_t)0xf11e, (q15_t)0x7e3c, (q15_t)0xf112, + (q15_t)0x7e39, (q15_t)0xf105, (q15_t)0x7e36, (q15_t)0xf0f9, (q15_t)0x7e33, (q15_t)0xf0ed, (q15_t)0x7e30, (q15_t)0xf0e1, + (q15_t)0x7e2d, (q15_t)0xf0d5, (q15_t)0x7e2a, (q15_t)0xf0c8, (q15_t)0x7e27, (q15_t)0xf0bc, (q15_t)0x7e24, (q15_t)0xf0b0, + (q15_t)0x7e21, (q15_t)0xf0a4, (q15_t)0x7e1e, (q15_t)0xf098, (q15_t)0x7e1b, (q15_t)0xf08b, (q15_t)0x7e18, (q15_t)0xf07f, + (q15_t)0x7e15, (q15_t)0xf073, (q15_t)0x7e12, (q15_t)0xf067, (q15_t)0x7e0f, (q15_t)0xf05b, (q15_t)0x7e0c, (q15_t)0xf04e, + (q15_t)0x7e09, (q15_t)0xf042, (q15_t)0x7e06, (q15_t)0xf036, (q15_t)0x7e03, (q15_t)0xf02a, (q15_t)0x7dff, (q15_t)0xf01e, + (q15_t)0x7dfc, (q15_t)0xf012, (q15_t)0x7df9, (q15_t)0xf005, (q15_t)0x7df6, (q15_t)0xeff9, (q15_t)0x7df3, (q15_t)0xefed, + (q15_t)0x7df0, (q15_t)0xefe1, (q15_t)0x7ded, (q15_t)0xefd5, (q15_t)0x7de9, (q15_t)0xefc9, (q15_t)0x7de6, (q15_t)0xefbc, + (q15_t)0x7de3, (q15_t)0xefb0, (q15_t)0x7de0, (q15_t)0xefa4, (q15_t)0x7ddd, (q15_t)0xef98, (q15_t)0x7dd9, (q15_t)0xef8c, + (q15_t)0x7dd6, (q15_t)0xef80, (q15_t)0x7dd3, (q15_t)0xef74, (q15_t)0x7dd0, (q15_t)0xef67, (q15_t)0x7dcc, (q15_t)0xef5b, + (q15_t)0x7dc9, (q15_t)0xef4f, (q15_t)0x7dc6, (q15_t)0xef43, (q15_t)0x7dc2, (q15_t)0xef37, (q15_t)0x7dbf, (q15_t)0xef2b, + (q15_t)0x7dbc, (q15_t)0xef1f, (q15_t)0x7db9, (q15_t)0xef13, (q15_t)0x7db5, (q15_t)0xef06, (q15_t)0x7db2, (q15_t)0xeefa, + (q15_t)0x7daf, (q15_t)0xeeee, (q15_t)0x7dab, (q15_t)0xeee2, (q15_t)0x7da8, (q15_t)0xeed6, (q15_t)0x7da4, (q15_t)0xeeca, + (q15_t)0x7da1, (q15_t)0xeebe, (q15_t)0x7d9e, (q15_t)0xeeb2, (q15_t)0x7d9a, (q15_t)0xeea6, (q15_t)0x7d97, (q15_t)0xee99, + (q15_t)0x7d93, (q15_t)0xee8d, (q15_t)0x7d90, (q15_t)0xee81, (q15_t)0x7d8d, (q15_t)0xee75, (q15_t)0x7d89, (q15_t)0xee69, + (q15_t)0x7d86, (q15_t)0xee5d, (q15_t)0x7d82, (q15_t)0xee51, (q15_t)0x7d7f, (q15_t)0xee45, (q15_t)0x7d7b, (q15_t)0xee39, + (q15_t)0x7d78, (q15_t)0xee2d, (q15_t)0x7d74, (q15_t)0xee21, (q15_t)0x7d71, (q15_t)0xee15, (q15_t)0x7d6d, (q15_t)0xee09, + (q15_t)0x7d6a, (q15_t)0xedfc, (q15_t)0x7d66, (q15_t)0xedf0, (q15_t)0x7d63, (q15_t)0xede4, (q15_t)0x7d5f, (q15_t)0xedd8, + (q15_t)0x7d5b, (q15_t)0xedcc, (q15_t)0x7d58, (q15_t)0xedc0, (q15_t)0x7d54, (q15_t)0xedb4, (q15_t)0x7d51, (q15_t)0xeda8, + (q15_t)0x7d4d, (q15_t)0xed9c, (q15_t)0x7d49, (q15_t)0xed90, (q15_t)0x7d46, (q15_t)0xed84, (q15_t)0x7d42, (q15_t)0xed78, + (q15_t)0x7d3f, (q15_t)0xed6c, (q15_t)0x7d3b, (q15_t)0xed60, (q15_t)0x7d37, (q15_t)0xed54, (q15_t)0x7d34, (q15_t)0xed48, + (q15_t)0x7d30, (q15_t)0xed3c, (q15_t)0x7d2c, (q15_t)0xed30, (q15_t)0x7d28, (q15_t)0xed24, (q15_t)0x7d25, (q15_t)0xed18, + (q15_t)0x7d21, (q15_t)0xed0c, (q15_t)0x7d1d, (q15_t)0xed00, (q15_t)0x7d1a, (q15_t)0xecf4, (q15_t)0x7d16, (q15_t)0xece8, + (q15_t)0x7d12, (q15_t)0xecdc, (q15_t)0x7d0e, (q15_t)0xecd0, (q15_t)0x7d0b, (q15_t)0xecc4, (q15_t)0x7d07, (q15_t)0xecb8, + (q15_t)0x7d03, (q15_t)0xecac, (q15_t)0x7cff, (q15_t)0xeca0, (q15_t)0x7cfb, (q15_t)0xec94, (q15_t)0x7cf8, (q15_t)0xec88, + (q15_t)0x7cf4, (q15_t)0xec7c, (q15_t)0x7cf0, (q15_t)0xec70, (q15_t)0x7cec, (q15_t)0xec64, (q15_t)0x7ce8, (q15_t)0xec58, + (q15_t)0x7ce4, (q15_t)0xec4c, (q15_t)0x7ce0, (q15_t)0xec40, (q15_t)0x7cdd, (q15_t)0xec34, (q15_t)0x7cd9, (q15_t)0xec28, + (q15_t)0x7cd5, (q15_t)0xec1c, (q15_t)0x7cd1, (q15_t)0xec10, (q15_t)0x7ccd, (q15_t)0xec05, (q15_t)0x7cc9, (q15_t)0xebf9, + (q15_t)0x7cc5, (q15_t)0xebed, (q15_t)0x7cc1, (q15_t)0xebe1, (q15_t)0x7cbd, (q15_t)0xebd5, (q15_t)0x7cb9, (q15_t)0xebc9, + (q15_t)0x7cb5, (q15_t)0xebbd, (q15_t)0x7cb1, (q15_t)0xebb1, (q15_t)0x7cad, (q15_t)0xeba5, (q15_t)0x7ca9, (q15_t)0xeb99, + (q15_t)0x7ca5, (q15_t)0xeb8d, (q15_t)0x7ca1, (q15_t)0xeb81, (q15_t)0x7c9d, (q15_t)0xeb75, (q15_t)0x7c99, (q15_t)0xeb6a, + (q15_t)0x7c95, (q15_t)0xeb5e, (q15_t)0x7c91, (q15_t)0xeb52, (q15_t)0x7c8d, (q15_t)0xeb46, (q15_t)0x7c89, (q15_t)0xeb3a, + (q15_t)0x7c85, (q15_t)0xeb2e, (q15_t)0x7c81, (q15_t)0xeb22, (q15_t)0x7c7d, (q15_t)0xeb16, (q15_t)0x7c79, (q15_t)0xeb0a, + (q15_t)0x7c74, (q15_t)0xeaff, (q15_t)0x7c70, (q15_t)0xeaf3, (q15_t)0x7c6c, (q15_t)0xeae7, (q15_t)0x7c68, (q15_t)0xeadb, + (q15_t)0x7c64, (q15_t)0xeacf, (q15_t)0x7c60, (q15_t)0xeac3, (q15_t)0x7c5b, (q15_t)0xeab7, (q15_t)0x7c57, (q15_t)0xeaac, + (q15_t)0x7c53, (q15_t)0xeaa0, (q15_t)0x7c4f, (q15_t)0xea94, (q15_t)0x7c4b, (q15_t)0xea88, (q15_t)0x7c46, (q15_t)0xea7c, + (q15_t)0x7c42, (q15_t)0xea70, (q15_t)0x7c3e, (q15_t)0xea65, (q15_t)0x7c3a, (q15_t)0xea59, (q15_t)0x7c36, (q15_t)0xea4d, + (q15_t)0x7c31, (q15_t)0xea41, (q15_t)0x7c2d, (q15_t)0xea35, (q15_t)0x7c29, (q15_t)0xea29, (q15_t)0x7c24, (q15_t)0xea1e, + (q15_t)0x7c20, (q15_t)0xea12, (q15_t)0x7c1c, (q15_t)0xea06, (q15_t)0x7c17, (q15_t)0xe9fa, (q15_t)0x7c13, (q15_t)0xe9ee, + (q15_t)0x7c0f, (q15_t)0xe9e3, (q15_t)0x7c0a, (q15_t)0xe9d7, (q15_t)0x7c06, (q15_t)0xe9cb, (q15_t)0x7c02, (q15_t)0xe9bf, + (q15_t)0x7bfd, (q15_t)0xe9b4, (q15_t)0x7bf9, (q15_t)0xe9a8, (q15_t)0x7bf5, (q15_t)0xe99c, (q15_t)0x7bf0, (q15_t)0xe990, + (q15_t)0x7bec, (q15_t)0xe984, (q15_t)0x7be7, (q15_t)0xe979, (q15_t)0x7be3, (q15_t)0xe96d, (q15_t)0x7bde, (q15_t)0xe961, + (q15_t)0x7bda, (q15_t)0xe955, (q15_t)0x7bd6, (q15_t)0xe94a, (q15_t)0x7bd1, (q15_t)0xe93e, (q15_t)0x7bcd, (q15_t)0xe932, + (q15_t)0x7bc8, (q15_t)0xe926, (q15_t)0x7bc4, (q15_t)0xe91b, (q15_t)0x7bbf, (q15_t)0xe90f, (q15_t)0x7bbb, (q15_t)0xe903, + (q15_t)0x7bb6, (q15_t)0xe8f7, (q15_t)0x7bb2, (q15_t)0xe8ec, (q15_t)0x7bad, (q15_t)0xe8e0, (q15_t)0x7ba9, (q15_t)0xe8d4, + (q15_t)0x7ba4, (q15_t)0xe8c9, (q15_t)0x7b9f, (q15_t)0xe8bd, (q15_t)0x7b9b, (q15_t)0xe8b1, (q15_t)0x7b96, (q15_t)0xe8a5, + (q15_t)0x7b92, (q15_t)0xe89a, (q15_t)0x7b8d, (q15_t)0xe88e, (q15_t)0x7b88, (q15_t)0xe882, (q15_t)0x7b84, (q15_t)0xe877, + (q15_t)0x7b7f, (q15_t)0xe86b, (q15_t)0x7b7b, (q15_t)0xe85f, (q15_t)0x7b76, (q15_t)0xe854, (q15_t)0x7b71, (q15_t)0xe848, + (q15_t)0x7b6d, (q15_t)0xe83c, (q15_t)0x7b68, (q15_t)0xe831, (q15_t)0x7b63, (q15_t)0xe825, (q15_t)0x7b5f, (q15_t)0xe819, + (q15_t)0x7b5a, (q15_t)0xe80e, (q15_t)0x7b55, (q15_t)0xe802, (q15_t)0x7b50, (q15_t)0xe7f6, (q15_t)0x7b4c, (q15_t)0xe7eb, + (q15_t)0x7b47, (q15_t)0xe7df, (q15_t)0x7b42, (q15_t)0xe7d3, (q15_t)0x7b3e, (q15_t)0xe7c8, (q15_t)0x7b39, (q15_t)0xe7bc, + (q15_t)0x7b34, (q15_t)0xe7b1, (q15_t)0x7b2f, (q15_t)0xe7a5, (q15_t)0x7b2a, (q15_t)0xe799, (q15_t)0x7b26, (q15_t)0xe78e, + (q15_t)0x7b21, (q15_t)0xe782, (q15_t)0x7b1c, (q15_t)0xe777, (q15_t)0x7b17, (q15_t)0xe76b, (q15_t)0x7b12, (q15_t)0xe75f, + (q15_t)0x7b0e, (q15_t)0xe754, (q15_t)0x7b09, (q15_t)0xe748, (q15_t)0x7b04, (q15_t)0xe73d, (q15_t)0x7aff, (q15_t)0xe731, + (q15_t)0x7afa, (q15_t)0xe725, (q15_t)0x7af5, (q15_t)0xe71a, (q15_t)0x7af0, (q15_t)0xe70e, (q15_t)0x7aeb, (q15_t)0xe703, + (q15_t)0x7ae6, (q15_t)0xe6f7, (q15_t)0x7ae2, (q15_t)0xe6ec, (q15_t)0x7add, (q15_t)0xe6e0, (q15_t)0x7ad8, (q15_t)0xe6d4, + (q15_t)0x7ad3, (q15_t)0xe6c9, (q15_t)0x7ace, (q15_t)0xe6bd, (q15_t)0x7ac9, (q15_t)0xe6b2, (q15_t)0x7ac4, (q15_t)0xe6a6, + (q15_t)0x7abf, (q15_t)0xe69b, (q15_t)0x7aba, (q15_t)0xe68f, (q15_t)0x7ab5, (q15_t)0xe684, (q15_t)0x7ab0, (q15_t)0xe678, + (q15_t)0x7aab, (q15_t)0xe66d, (q15_t)0x7aa6, (q15_t)0xe661, (q15_t)0x7aa1, (q15_t)0xe656, (q15_t)0x7a9c, (q15_t)0xe64a, + (q15_t)0x7a97, (q15_t)0xe63f, (q15_t)0x7a92, (q15_t)0xe633, (q15_t)0x7a8d, (q15_t)0xe628, (q15_t)0x7a88, (q15_t)0xe61c, + (q15_t)0x7a82, (q15_t)0xe611, (q15_t)0x7a7d, (q15_t)0xe605, (q15_t)0x7a78, (q15_t)0xe5fa, (q15_t)0x7a73, (q15_t)0xe5ee, + (q15_t)0x7a6e, (q15_t)0xe5e3, (q15_t)0x7a69, (q15_t)0xe5d7, (q15_t)0x7a64, (q15_t)0xe5cc, (q15_t)0x7a5f, (q15_t)0xe5c0, + (q15_t)0x7a59, (q15_t)0xe5b5, (q15_t)0x7a54, (q15_t)0xe5a9, (q15_t)0x7a4f, (q15_t)0xe59e, (q15_t)0x7a4a, (q15_t)0xe592, + (q15_t)0x7a45, (q15_t)0xe587, (q15_t)0x7a3f, (q15_t)0xe57c, (q15_t)0x7a3a, (q15_t)0xe570, (q15_t)0x7a35, (q15_t)0xe565, + (q15_t)0x7a30, (q15_t)0xe559, (q15_t)0x7a2b, (q15_t)0xe54e, (q15_t)0x7a25, (q15_t)0xe542, (q15_t)0x7a20, (q15_t)0xe537, + (q15_t)0x7a1b, (q15_t)0xe52c, (q15_t)0x7a16, (q15_t)0xe520, (q15_t)0x7a10, (q15_t)0xe515, (q15_t)0x7a0b, (q15_t)0xe509, + (q15_t)0x7a06, (q15_t)0xe4fe, (q15_t)0x7a00, (q15_t)0xe4f3, (q15_t)0x79fb, (q15_t)0xe4e7, (q15_t)0x79f6, (q15_t)0xe4dc, + (q15_t)0x79f0, (q15_t)0xe4d0, (q15_t)0x79eb, (q15_t)0xe4c5, (q15_t)0x79e6, (q15_t)0xe4ba, (q15_t)0x79e0, (q15_t)0xe4ae, + (q15_t)0x79db, (q15_t)0xe4a3, (q15_t)0x79d6, (q15_t)0xe498, (q15_t)0x79d0, (q15_t)0xe48c, (q15_t)0x79cb, (q15_t)0xe481, + (q15_t)0x79c5, (q15_t)0xe476, (q15_t)0x79c0, (q15_t)0xe46a, (q15_t)0x79bb, (q15_t)0xe45f, (q15_t)0x79b5, (q15_t)0xe454, + (q15_t)0x79b0, (q15_t)0xe448, (q15_t)0x79aa, (q15_t)0xe43d, (q15_t)0x79a5, (q15_t)0xe432, (q15_t)0x799f, (q15_t)0xe426, + (q15_t)0x799a, (q15_t)0xe41b, (q15_t)0x7994, (q15_t)0xe410, (q15_t)0x798f, (q15_t)0xe404, (q15_t)0x7989, (q15_t)0xe3f9, + (q15_t)0x7984, (q15_t)0xe3ee, (q15_t)0x797e, (q15_t)0xe3e2, (q15_t)0x7979, (q15_t)0xe3d7, (q15_t)0x7973, (q15_t)0xe3cc, + (q15_t)0x796e, (q15_t)0xe3c1, (q15_t)0x7968, (q15_t)0xe3b5, (q15_t)0x7963, (q15_t)0xe3aa, (q15_t)0x795d, (q15_t)0xe39f, + (q15_t)0x7958, (q15_t)0xe394, (q15_t)0x7952, (q15_t)0xe388, (q15_t)0x794c, (q15_t)0xe37d, (q15_t)0x7947, (q15_t)0xe372, + (q15_t)0x7941, (q15_t)0xe367, (q15_t)0x793b, (q15_t)0xe35b, (q15_t)0x7936, (q15_t)0xe350, (q15_t)0x7930, (q15_t)0xe345, + (q15_t)0x792b, (q15_t)0xe33a, (q15_t)0x7925, (q15_t)0xe32e, (q15_t)0x791f, (q15_t)0xe323, (q15_t)0x791a, (q15_t)0xe318, + (q15_t)0x7914, (q15_t)0xe30d, (q15_t)0x790e, (q15_t)0xe301, (q15_t)0x7909, (q15_t)0xe2f6, (q15_t)0x7903, (q15_t)0xe2eb, + (q15_t)0x78fd, (q15_t)0xe2e0, (q15_t)0x78f7, (q15_t)0xe2d5, (q15_t)0x78f2, (q15_t)0xe2ca, (q15_t)0x78ec, (q15_t)0xe2be, + (q15_t)0x78e6, (q15_t)0xe2b3, (q15_t)0x78e0, (q15_t)0xe2a8, (q15_t)0x78db, (q15_t)0xe29d, (q15_t)0x78d5, (q15_t)0xe292, + (q15_t)0x78cf, (q15_t)0xe287, (q15_t)0x78c9, (q15_t)0xe27b, (q15_t)0x78c3, (q15_t)0xe270, (q15_t)0x78be, (q15_t)0xe265, + (q15_t)0x78b8, (q15_t)0xe25a, (q15_t)0x78b2, (q15_t)0xe24f, (q15_t)0x78ac, (q15_t)0xe244, (q15_t)0x78a6, (q15_t)0xe239, + (q15_t)0x78a1, (q15_t)0xe22d, (q15_t)0x789b, (q15_t)0xe222, (q15_t)0x7895, (q15_t)0xe217, (q15_t)0x788f, (q15_t)0xe20c, + (q15_t)0x7889, (q15_t)0xe201, (q15_t)0x7883, (q15_t)0xe1f6, (q15_t)0x787d, (q15_t)0xe1eb, (q15_t)0x7877, (q15_t)0xe1e0, + (q15_t)0x7871, (q15_t)0xe1d5, (q15_t)0x786b, (q15_t)0xe1ca, (q15_t)0x7866, (q15_t)0xe1be, (q15_t)0x7860, (q15_t)0xe1b3, + (q15_t)0x785a, (q15_t)0xe1a8, (q15_t)0x7854, (q15_t)0xe19d, (q15_t)0x784e, (q15_t)0xe192, (q15_t)0x7848, (q15_t)0xe187, + (q15_t)0x7842, (q15_t)0xe17c, (q15_t)0x783c, (q15_t)0xe171, (q15_t)0x7836, (q15_t)0xe166, (q15_t)0x7830, (q15_t)0xe15b, + (q15_t)0x782a, (q15_t)0xe150, (q15_t)0x7824, (q15_t)0xe145, (q15_t)0x781e, (q15_t)0xe13a, (q15_t)0x7818, (q15_t)0xe12f, + (q15_t)0x7812, (q15_t)0xe124, (q15_t)0x780b, (q15_t)0xe119, (q15_t)0x7805, (q15_t)0xe10e, (q15_t)0x77ff, (q15_t)0xe103, + (q15_t)0x77f9, (q15_t)0xe0f8, (q15_t)0x77f3, (q15_t)0xe0ed, (q15_t)0x77ed, (q15_t)0xe0e2, (q15_t)0x77e7, (q15_t)0xe0d7, + (q15_t)0x77e1, (q15_t)0xe0cc, (q15_t)0x77db, (q15_t)0xe0c1, (q15_t)0x77d5, (q15_t)0xe0b6, (q15_t)0x77ce, (q15_t)0xe0ab, + (q15_t)0x77c8, (q15_t)0xe0a0, (q15_t)0x77c2, (q15_t)0xe095, (q15_t)0x77bc, (q15_t)0xe08a, (q15_t)0x77b6, (q15_t)0xe07f, + (q15_t)0x77b0, (q15_t)0xe074, (q15_t)0x77a9, (q15_t)0xe069, (q15_t)0x77a3, (q15_t)0xe05e, (q15_t)0x779d, (q15_t)0xe054, + (q15_t)0x7797, (q15_t)0xe049, (q15_t)0x7790, (q15_t)0xe03e, (q15_t)0x778a, (q15_t)0xe033, (q15_t)0x7784, (q15_t)0xe028, + (q15_t)0x777e, (q15_t)0xe01d, (q15_t)0x7777, (q15_t)0xe012, (q15_t)0x7771, (q15_t)0xe007, (q15_t)0x776b, (q15_t)0xdffc, + (q15_t)0x7765, (q15_t)0xdff1, (q15_t)0x775e, (q15_t)0xdfe7, (q15_t)0x7758, (q15_t)0xdfdc, (q15_t)0x7752, (q15_t)0xdfd1, + (q15_t)0x774b, (q15_t)0xdfc6, (q15_t)0x7745, (q15_t)0xdfbb, (q15_t)0x773f, (q15_t)0xdfb0, (q15_t)0x7738, (q15_t)0xdfa5, + (q15_t)0x7732, (q15_t)0xdf9b, (q15_t)0x772c, (q15_t)0xdf90, (q15_t)0x7725, (q15_t)0xdf85, (q15_t)0x771f, (q15_t)0xdf7a, + (q15_t)0x7718, (q15_t)0xdf6f, (q15_t)0x7712, (q15_t)0xdf65, (q15_t)0x770c, (q15_t)0xdf5a, (q15_t)0x7705, (q15_t)0xdf4f, + (q15_t)0x76ff, (q15_t)0xdf44, (q15_t)0x76f8, (q15_t)0xdf39, (q15_t)0x76f2, (q15_t)0xdf2f, (q15_t)0x76eb, (q15_t)0xdf24, + (q15_t)0x76e5, (q15_t)0xdf19, (q15_t)0x76df, (q15_t)0xdf0e, (q15_t)0x76d8, (q15_t)0xdf03, (q15_t)0x76d2, (q15_t)0xdef9, + (q15_t)0x76cb, (q15_t)0xdeee, (q15_t)0x76c5, (q15_t)0xdee3, (q15_t)0x76be, (q15_t)0xded8, (q15_t)0x76b8, (q15_t)0xdece, + (q15_t)0x76b1, (q15_t)0xdec3, (q15_t)0x76ab, (q15_t)0xdeb8, (q15_t)0x76a4, (q15_t)0xdead, (q15_t)0x769d, (q15_t)0xdea3, + (q15_t)0x7697, (q15_t)0xde98, (q15_t)0x7690, (q15_t)0xde8d, (q15_t)0x768a, (q15_t)0xde83, (q15_t)0x7683, (q15_t)0xde78, + (q15_t)0x767d, (q15_t)0xde6d, (q15_t)0x7676, (q15_t)0xde62, (q15_t)0x766f, (q15_t)0xde58, (q15_t)0x7669, (q15_t)0xde4d, + (q15_t)0x7662, (q15_t)0xde42, (q15_t)0x765c, (q15_t)0xde38, (q15_t)0x7655, (q15_t)0xde2d, (q15_t)0x764e, (q15_t)0xde22, + (q15_t)0x7648, (q15_t)0xde18, (q15_t)0x7641, (q15_t)0xde0d, (q15_t)0x763a, (q15_t)0xde02, (q15_t)0x7634, (q15_t)0xddf8, + (q15_t)0x762d, (q15_t)0xdded, (q15_t)0x7626, (q15_t)0xdde2, (q15_t)0x7620, (q15_t)0xddd8, (q15_t)0x7619, (q15_t)0xddcd, + (q15_t)0x7612, (q15_t)0xddc3, (q15_t)0x760b, (q15_t)0xddb8, (q15_t)0x7605, (q15_t)0xddad, (q15_t)0x75fe, (q15_t)0xdda3, + (q15_t)0x75f7, (q15_t)0xdd98, (q15_t)0x75f0, (q15_t)0xdd8e, (q15_t)0x75ea, (q15_t)0xdd83, (q15_t)0x75e3, (q15_t)0xdd78, + (q15_t)0x75dc, (q15_t)0xdd6e, (q15_t)0x75d5, (q15_t)0xdd63, (q15_t)0x75ce, (q15_t)0xdd59, (q15_t)0x75c8, (q15_t)0xdd4e, + (q15_t)0x75c1, (q15_t)0xdd44, (q15_t)0x75ba, (q15_t)0xdd39, (q15_t)0x75b3, (q15_t)0xdd2e, (q15_t)0x75ac, (q15_t)0xdd24, + (q15_t)0x75a5, (q15_t)0xdd19, (q15_t)0x759f, (q15_t)0xdd0f, (q15_t)0x7598, (q15_t)0xdd04, (q15_t)0x7591, (q15_t)0xdcfa, + (q15_t)0x758a, (q15_t)0xdcef, (q15_t)0x7583, (q15_t)0xdce5, (q15_t)0x757c, (q15_t)0xdcda, (q15_t)0x7575, (q15_t)0xdcd0, + (q15_t)0x756e, (q15_t)0xdcc5, (q15_t)0x7567, (q15_t)0xdcbb, (q15_t)0x7561, (q15_t)0xdcb0, (q15_t)0x755a, (q15_t)0xdca6, + (q15_t)0x7553, (q15_t)0xdc9b, (q15_t)0x754c, (q15_t)0xdc91, (q15_t)0x7545, (q15_t)0xdc86, (q15_t)0x753e, (q15_t)0xdc7c, + (q15_t)0x7537, (q15_t)0xdc72, (q15_t)0x7530, (q15_t)0xdc67, (q15_t)0x7529, (q15_t)0xdc5d, (q15_t)0x7522, (q15_t)0xdc52, + (q15_t)0x751b, (q15_t)0xdc48, (q15_t)0x7514, (q15_t)0xdc3d, (q15_t)0x750d, (q15_t)0xdc33, (q15_t)0x7506, (q15_t)0xdc29, + (q15_t)0x74ff, (q15_t)0xdc1e, (q15_t)0x74f8, (q15_t)0xdc14, (q15_t)0x74f1, (q15_t)0xdc09, (q15_t)0x74ea, (q15_t)0xdbff, + (q15_t)0x74e2, (q15_t)0xdbf5, (q15_t)0x74db, (q15_t)0xdbea, (q15_t)0x74d4, (q15_t)0xdbe0, (q15_t)0x74cd, (q15_t)0xdbd5, + (q15_t)0x74c6, (q15_t)0xdbcb, (q15_t)0x74bf, (q15_t)0xdbc1, (q15_t)0x74b8, (q15_t)0xdbb6, (q15_t)0x74b1, (q15_t)0xdbac, + (q15_t)0x74aa, (q15_t)0xdba2, (q15_t)0x74a2, (q15_t)0xdb97, (q15_t)0x749b, (q15_t)0xdb8d, (q15_t)0x7494, (q15_t)0xdb83, + (q15_t)0x748d, (q15_t)0xdb78, (q15_t)0x7486, (q15_t)0xdb6e, (q15_t)0x747f, (q15_t)0xdb64, (q15_t)0x7477, (q15_t)0xdb59, + (q15_t)0x7470, (q15_t)0xdb4f, (q15_t)0x7469, (q15_t)0xdb45, (q15_t)0x7462, (q15_t)0xdb3b, (q15_t)0x745b, (q15_t)0xdb30, + (q15_t)0x7453, (q15_t)0xdb26, (q15_t)0x744c, (q15_t)0xdb1c, (q15_t)0x7445, (q15_t)0xdb11, (q15_t)0x743e, (q15_t)0xdb07, + (q15_t)0x7436, (q15_t)0xdafd, (q15_t)0x742f, (q15_t)0xdaf3, (q15_t)0x7428, (q15_t)0xdae8, (q15_t)0x7420, (q15_t)0xdade, + (q15_t)0x7419, (q15_t)0xdad4, (q15_t)0x7412, (q15_t)0xdaca, (q15_t)0x740b, (q15_t)0xdabf, (q15_t)0x7403, (q15_t)0xdab5, + (q15_t)0x73fc, (q15_t)0xdaab, (q15_t)0x73f5, (q15_t)0xdaa1, (q15_t)0x73ed, (q15_t)0xda97, (q15_t)0x73e6, (q15_t)0xda8c, + (q15_t)0x73df, (q15_t)0xda82, (q15_t)0x73d7, (q15_t)0xda78, (q15_t)0x73d0, (q15_t)0xda6e, (q15_t)0x73c8, (q15_t)0xda64, + (q15_t)0x73c1, (q15_t)0xda5a, (q15_t)0x73ba, (q15_t)0xda4f, (q15_t)0x73b2, (q15_t)0xda45, (q15_t)0x73ab, (q15_t)0xda3b, + (q15_t)0x73a3, (q15_t)0xda31, (q15_t)0x739c, (q15_t)0xda27, (q15_t)0x7395, (q15_t)0xda1d, (q15_t)0x738d, (q15_t)0xda13, + (q15_t)0x7386, (q15_t)0xda08, (q15_t)0x737e, (q15_t)0xd9fe, (q15_t)0x7377, (q15_t)0xd9f4, (q15_t)0x736f, (q15_t)0xd9ea, + (q15_t)0x7368, (q15_t)0xd9e0, (q15_t)0x7360, (q15_t)0xd9d6, (q15_t)0x7359, (q15_t)0xd9cc, (q15_t)0x7351, (q15_t)0xd9c2, + (q15_t)0x734a, (q15_t)0xd9b8, (q15_t)0x7342, (q15_t)0xd9ae, (q15_t)0x733b, (q15_t)0xd9a4, (q15_t)0x7333, (q15_t)0xd99a, + (q15_t)0x732c, (q15_t)0xd98f, (q15_t)0x7324, (q15_t)0xd985, (q15_t)0x731d, (q15_t)0xd97b, (q15_t)0x7315, (q15_t)0xd971, + (q15_t)0x730d, (q15_t)0xd967, (q15_t)0x7306, (q15_t)0xd95d, (q15_t)0x72fe, (q15_t)0xd953, (q15_t)0x72f7, (q15_t)0xd949, + (q15_t)0x72ef, (q15_t)0xd93f, (q15_t)0x72e7, (q15_t)0xd935, (q15_t)0x72e0, (q15_t)0xd92b, (q15_t)0x72d8, (q15_t)0xd921, + (q15_t)0x72d0, (q15_t)0xd917, (q15_t)0x72c9, (q15_t)0xd90d, (q15_t)0x72c1, (q15_t)0xd903, (q15_t)0x72ba, (q15_t)0xd8f9, + (q15_t)0x72b2, (q15_t)0xd8ef, (q15_t)0x72aa, (q15_t)0xd8e6, (q15_t)0x72a3, (q15_t)0xd8dc, (q15_t)0x729b, (q15_t)0xd8d2, + (q15_t)0x7293, (q15_t)0xd8c8, (q15_t)0x728b, (q15_t)0xd8be, (q15_t)0x7284, (q15_t)0xd8b4, (q15_t)0x727c, (q15_t)0xd8aa, + (q15_t)0x7274, (q15_t)0xd8a0, (q15_t)0x726d, (q15_t)0xd896, (q15_t)0x7265, (q15_t)0xd88c, (q15_t)0x725d, (q15_t)0xd882, + (q15_t)0x7255, (q15_t)0xd878, (q15_t)0x724e, (q15_t)0xd86f, (q15_t)0x7246, (q15_t)0xd865, (q15_t)0x723e, (q15_t)0xd85b, + (q15_t)0x7236, (q15_t)0xd851, (q15_t)0x722e, (q15_t)0xd847, (q15_t)0x7227, (q15_t)0xd83d, (q15_t)0x721f, (q15_t)0xd833, + (q15_t)0x7217, (q15_t)0xd82a, (q15_t)0x720f, (q15_t)0xd820, (q15_t)0x7207, (q15_t)0xd816, (q15_t)0x71ff, (q15_t)0xd80c, + (q15_t)0x71f8, (q15_t)0xd802, (q15_t)0x71f0, (q15_t)0xd7f8, (q15_t)0x71e8, (q15_t)0xd7ef, (q15_t)0x71e0, (q15_t)0xd7e5, + (q15_t)0x71d8, (q15_t)0xd7db, (q15_t)0x71d0, (q15_t)0xd7d1, (q15_t)0x71c8, (q15_t)0xd7c8, (q15_t)0x71c0, (q15_t)0xd7be, + (q15_t)0x71b9, (q15_t)0xd7b4, (q15_t)0x71b1, (q15_t)0xd7aa, (q15_t)0x71a9, (q15_t)0xd7a0, (q15_t)0x71a1, (q15_t)0xd797, + (q15_t)0x7199, (q15_t)0xd78d, (q15_t)0x7191, (q15_t)0xd783, (q15_t)0x7189, (q15_t)0xd77a, (q15_t)0x7181, (q15_t)0xd770, + (q15_t)0x7179, (q15_t)0xd766, (q15_t)0x7171, (q15_t)0xd75c, (q15_t)0x7169, (q15_t)0xd753, (q15_t)0x7161, (q15_t)0xd749, + (q15_t)0x7159, (q15_t)0xd73f, (q15_t)0x7151, (q15_t)0xd736, (q15_t)0x7149, (q15_t)0xd72c, (q15_t)0x7141, (q15_t)0xd722, + (q15_t)0x7139, (q15_t)0xd719, (q15_t)0x7131, (q15_t)0xd70f, (q15_t)0x7129, (q15_t)0xd705, (q15_t)0x7121, (q15_t)0xd6fc, + (q15_t)0x7119, (q15_t)0xd6f2, (q15_t)0x7111, (q15_t)0xd6e8, (q15_t)0x7109, (q15_t)0xd6df, (q15_t)0x7101, (q15_t)0xd6d5, + (q15_t)0x70f9, (q15_t)0xd6cb, (q15_t)0x70f0, (q15_t)0xd6c2, (q15_t)0x70e8, (q15_t)0xd6b8, (q15_t)0x70e0, (q15_t)0xd6af, + (q15_t)0x70d8, (q15_t)0xd6a5, (q15_t)0x70d0, (q15_t)0xd69b, (q15_t)0x70c8, (q15_t)0xd692, (q15_t)0x70c0, (q15_t)0xd688, + (q15_t)0x70b8, (q15_t)0xd67f, (q15_t)0x70af, (q15_t)0xd675, (q15_t)0x70a7, (q15_t)0xd66c, (q15_t)0x709f, (q15_t)0xd662, + (q15_t)0x7097, (q15_t)0xd659, (q15_t)0x708f, (q15_t)0xd64f, (q15_t)0x7087, (q15_t)0xd645, (q15_t)0x707e, (q15_t)0xd63c, + (q15_t)0x7076, (q15_t)0xd632, (q15_t)0x706e, (q15_t)0xd629, (q15_t)0x7066, (q15_t)0xd61f, (q15_t)0x705d, (q15_t)0xd616, + (q15_t)0x7055, (q15_t)0xd60c, (q15_t)0x704d, (q15_t)0xd603, (q15_t)0x7045, (q15_t)0xd5f9, (q15_t)0x703c, (q15_t)0xd5f0, + (q15_t)0x7034, (q15_t)0xd5e6, (q15_t)0x702c, (q15_t)0xd5dd, (q15_t)0x7024, (q15_t)0xd5d4, (q15_t)0x701b, (q15_t)0xd5ca, + (q15_t)0x7013, (q15_t)0xd5c1, (q15_t)0x700b, (q15_t)0xd5b7, (q15_t)0x7002, (q15_t)0xd5ae, (q15_t)0x6ffa, (q15_t)0xd5a4, + (q15_t)0x6ff2, (q15_t)0xd59b, (q15_t)0x6fea, (q15_t)0xd592, (q15_t)0x6fe1, (q15_t)0xd588, (q15_t)0x6fd9, (q15_t)0xd57f, + (q15_t)0x6fd0, (q15_t)0xd575, (q15_t)0x6fc8, (q15_t)0xd56c, (q15_t)0x6fc0, (q15_t)0xd563, (q15_t)0x6fb7, (q15_t)0xd559, + (q15_t)0x6faf, (q15_t)0xd550, (q15_t)0x6fa7, (q15_t)0xd547, (q15_t)0x6f9e, (q15_t)0xd53d, (q15_t)0x6f96, (q15_t)0xd534, + (q15_t)0x6f8d, (q15_t)0xd52a, (q15_t)0x6f85, (q15_t)0xd521, (q15_t)0x6f7d, (q15_t)0xd518, (q15_t)0x6f74, (q15_t)0xd50e, + (q15_t)0x6f6c, (q15_t)0xd505, (q15_t)0x6f63, (q15_t)0xd4fc, (q15_t)0x6f5b, (q15_t)0xd4f3, (q15_t)0x6f52, (q15_t)0xd4e9, + (q15_t)0x6f4a, (q15_t)0xd4e0, (q15_t)0x6f41, (q15_t)0xd4d7, (q15_t)0x6f39, (q15_t)0xd4cd, (q15_t)0x6f30, (q15_t)0xd4c4, + (q15_t)0x6f28, (q15_t)0xd4bb, (q15_t)0x6f20, (q15_t)0xd4b2, (q15_t)0x6f17, (q15_t)0xd4a8, (q15_t)0x6f0e, (q15_t)0xd49f, + (q15_t)0x6f06, (q15_t)0xd496, (q15_t)0x6efd, (q15_t)0xd48d, (q15_t)0x6ef5, (q15_t)0xd483, (q15_t)0x6eec, (q15_t)0xd47a, + (q15_t)0x6ee4, (q15_t)0xd471, (q15_t)0x6edb, (q15_t)0xd468, (q15_t)0x6ed3, (q15_t)0xd45f, (q15_t)0x6eca, (q15_t)0xd455, + (q15_t)0x6ec2, (q15_t)0xd44c, (q15_t)0x6eb9, (q15_t)0xd443, (q15_t)0x6eb0, (q15_t)0xd43a, (q15_t)0x6ea8, (q15_t)0xd431, + (q15_t)0x6e9f, (q15_t)0xd428, (q15_t)0x6e97, (q15_t)0xd41e, (q15_t)0x6e8e, (q15_t)0xd415, (q15_t)0x6e85, (q15_t)0xd40c, + (q15_t)0x6e7d, (q15_t)0xd403, (q15_t)0x6e74, (q15_t)0xd3fa, (q15_t)0x6e6b, (q15_t)0xd3f1, (q15_t)0x6e63, (q15_t)0xd3e8, + (q15_t)0x6e5a, (q15_t)0xd3df, (q15_t)0x6e51, (q15_t)0xd3d5, (q15_t)0x6e49, (q15_t)0xd3cc, (q15_t)0x6e40, (q15_t)0xd3c3, + (q15_t)0x6e37, (q15_t)0xd3ba, (q15_t)0x6e2f, (q15_t)0xd3b1, (q15_t)0x6e26, (q15_t)0xd3a8, (q15_t)0x6e1d, (q15_t)0xd39f, + (q15_t)0x6e15, (q15_t)0xd396, (q15_t)0x6e0c, (q15_t)0xd38d, (q15_t)0x6e03, (q15_t)0xd384, (q15_t)0x6dfa, (q15_t)0xd37b, + (q15_t)0x6df2, (q15_t)0xd372, (q15_t)0x6de9, (q15_t)0xd369, (q15_t)0x6de0, (q15_t)0xd360, (q15_t)0x6dd7, (q15_t)0xd357, + (q15_t)0x6dcf, (q15_t)0xd34e, (q15_t)0x6dc6, (q15_t)0xd345, (q15_t)0x6dbd, (q15_t)0xd33c, (q15_t)0x6db4, (q15_t)0xd333, + (q15_t)0x6dab, (q15_t)0xd32a, (q15_t)0x6da3, (q15_t)0xd321, (q15_t)0x6d9a, (q15_t)0xd318, (q15_t)0x6d91, (q15_t)0xd30f, + (q15_t)0x6d88, (q15_t)0xd306, (q15_t)0x6d7f, (q15_t)0xd2fd, (q15_t)0x6d76, (q15_t)0xd2f4, (q15_t)0x6d6e, (q15_t)0xd2eb, + (q15_t)0x6d65, (q15_t)0xd2e2, (q15_t)0x6d5c, (q15_t)0xd2d9, (q15_t)0x6d53, (q15_t)0xd2d1, (q15_t)0x6d4a, (q15_t)0xd2c8, + (q15_t)0x6d41, (q15_t)0xd2bf, (q15_t)0x6d38, (q15_t)0xd2b6, (q15_t)0x6d2f, (q15_t)0xd2ad, (q15_t)0x6d27, (q15_t)0xd2a4, + (q15_t)0x6d1e, (q15_t)0xd29b, (q15_t)0x6d15, (q15_t)0xd292, (q15_t)0x6d0c, (q15_t)0xd28a, (q15_t)0x6d03, (q15_t)0xd281, + (q15_t)0x6cfa, (q15_t)0xd278, (q15_t)0x6cf1, (q15_t)0xd26f, (q15_t)0x6ce8, (q15_t)0xd266, (q15_t)0x6cdf, (q15_t)0xd25d, + (q15_t)0x6cd6, (q15_t)0xd255, (q15_t)0x6ccd, (q15_t)0xd24c, (q15_t)0x6cc4, (q15_t)0xd243, (q15_t)0x6cbb, (q15_t)0xd23a, + (q15_t)0x6cb2, (q15_t)0xd231, (q15_t)0x6ca9, (q15_t)0xd229, (q15_t)0x6ca0, (q15_t)0xd220, (q15_t)0x6c97, (q15_t)0xd217, + (q15_t)0x6c8e, (q15_t)0xd20e, (q15_t)0x6c85, (q15_t)0xd206, (q15_t)0x6c7c, (q15_t)0xd1fd, (q15_t)0x6c73, (q15_t)0xd1f4, + (q15_t)0x6c6a, (q15_t)0xd1eb, (q15_t)0x6c61, (q15_t)0xd1e3, (q15_t)0x6c58, (q15_t)0xd1da, (q15_t)0x6c4f, (q15_t)0xd1d1, + (q15_t)0x6c46, (q15_t)0xd1c9, (q15_t)0x6c3d, (q15_t)0xd1c0, (q15_t)0x6c34, (q15_t)0xd1b7, (q15_t)0x6c2b, (q15_t)0xd1af, + (q15_t)0x6c21, (q15_t)0xd1a6, (q15_t)0x6c18, (q15_t)0xd19d, (q15_t)0x6c0f, (q15_t)0xd195, (q15_t)0x6c06, (q15_t)0xd18c, + (q15_t)0x6bfd, (q15_t)0xd183, (q15_t)0x6bf4, (q15_t)0xd17b, (q15_t)0x6beb, (q15_t)0xd172, (q15_t)0x6be2, (q15_t)0xd169, + (q15_t)0x6bd8, (q15_t)0xd161, (q15_t)0x6bcf, (q15_t)0xd158, (q15_t)0x6bc6, (q15_t)0xd150, (q15_t)0x6bbd, (q15_t)0xd147, + (q15_t)0x6bb4, (q15_t)0xd13e, (q15_t)0x6bab, (q15_t)0xd136, (q15_t)0x6ba1, (q15_t)0xd12d, (q15_t)0x6b98, (q15_t)0xd125, + (q15_t)0x6b8f, (q15_t)0xd11c, (q15_t)0x6b86, (q15_t)0xd114, (q15_t)0x6b7d, (q15_t)0xd10b, (q15_t)0x6b73, (q15_t)0xd103, + (q15_t)0x6b6a, (q15_t)0xd0fa, (q15_t)0x6b61, (q15_t)0xd0f2, (q15_t)0x6b58, (q15_t)0xd0e9, (q15_t)0x6b4e, (q15_t)0xd0e0, + (q15_t)0x6b45, (q15_t)0xd0d8, (q15_t)0x6b3c, (q15_t)0xd0d0, (q15_t)0x6b33, (q15_t)0xd0c7, (q15_t)0x6b29, (q15_t)0xd0bf, + (q15_t)0x6b20, (q15_t)0xd0b6, (q15_t)0x6b17, (q15_t)0xd0ae, (q15_t)0x6b0d, (q15_t)0xd0a5, (q15_t)0x6b04, (q15_t)0xd09d, + (q15_t)0x6afb, (q15_t)0xd094, (q15_t)0x6af2, (q15_t)0xd08c, (q15_t)0x6ae8, (q15_t)0xd083, (q15_t)0x6adf, (q15_t)0xd07b, + (q15_t)0x6ad6, (q15_t)0xd073, (q15_t)0x6acc, (q15_t)0xd06a, (q15_t)0x6ac3, (q15_t)0xd062, (q15_t)0x6ab9, (q15_t)0xd059, + (q15_t)0x6ab0, (q15_t)0xd051, (q15_t)0x6aa7, (q15_t)0xd049, (q15_t)0x6a9d, (q15_t)0xd040, (q15_t)0x6a94, (q15_t)0xd038, + (q15_t)0x6a8b, (q15_t)0xd030, (q15_t)0x6a81, (q15_t)0xd027, (q15_t)0x6a78, (q15_t)0xd01f, (q15_t)0x6a6e, (q15_t)0xd016, + (q15_t)0x6a65, (q15_t)0xd00e, (q15_t)0x6a5c, (q15_t)0xd006, (q15_t)0x6a52, (q15_t)0xcffe, (q15_t)0x6a49, (q15_t)0xcff5, + (q15_t)0x6a3f, (q15_t)0xcfed, (q15_t)0x6a36, (q15_t)0xcfe5, (q15_t)0x6a2c, (q15_t)0xcfdc, (q15_t)0x6a23, (q15_t)0xcfd4, + (q15_t)0x6a1a, (q15_t)0xcfcc, (q15_t)0x6a10, (q15_t)0xcfc4, (q15_t)0x6a07, (q15_t)0xcfbb, (q15_t)0x69fd, (q15_t)0xcfb3, + (q15_t)0x69f4, (q15_t)0xcfab, (q15_t)0x69ea, (q15_t)0xcfa3, (q15_t)0x69e1, (q15_t)0xcf9a, (q15_t)0x69d7, (q15_t)0xcf92, + (q15_t)0x69ce, (q15_t)0xcf8a, (q15_t)0x69c4, (q15_t)0xcf82, (q15_t)0x69bb, (q15_t)0xcf79, (q15_t)0x69b1, (q15_t)0xcf71, + (q15_t)0x69a7, (q15_t)0xcf69, (q15_t)0x699e, (q15_t)0xcf61, (q15_t)0x6994, (q15_t)0xcf59, (q15_t)0x698b, (q15_t)0xcf51, + (q15_t)0x6981, (q15_t)0xcf48, (q15_t)0x6978, (q15_t)0xcf40, (q15_t)0x696e, (q15_t)0xcf38, (q15_t)0x6965, (q15_t)0xcf30, + (q15_t)0x695b, (q15_t)0xcf28, (q15_t)0x6951, (q15_t)0xcf20, (q15_t)0x6948, (q15_t)0xcf18, (q15_t)0x693e, (q15_t)0xcf10, + (q15_t)0x6935, (q15_t)0xcf07, (q15_t)0x692b, (q15_t)0xceff, (q15_t)0x6921, (q15_t)0xcef7, (q15_t)0x6918, (q15_t)0xceef, + (q15_t)0x690e, (q15_t)0xcee7, (q15_t)0x6904, (q15_t)0xcedf, (q15_t)0x68fb, (q15_t)0xced7, (q15_t)0x68f1, (q15_t)0xcecf, + (q15_t)0x68e7, (q15_t)0xcec7, (q15_t)0x68de, (q15_t)0xcebf, (q15_t)0x68d4, (q15_t)0xceb7, (q15_t)0x68ca, (q15_t)0xceaf, + (q15_t)0x68c1, (q15_t)0xcea7, (q15_t)0x68b7, (q15_t)0xce9f, (q15_t)0x68ad, (q15_t)0xce97, (q15_t)0x68a4, (q15_t)0xce8f, + (q15_t)0x689a, (q15_t)0xce87, (q15_t)0x6890, (q15_t)0xce7f, (q15_t)0x6886, (q15_t)0xce77, (q15_t)0x687d, (q15_t)0xce6f, + (q15_t)0x6873, (q15_t)0xce67, (q15_t)0x6869, (q15_t)0xce5f, (q15_t)0x6860, (q15_t)0xce57, (q15_t)0x6856, (q15_t)0xce4f, + (q15_t)0x684c, (q15_t)0xce47, (q15_t)0x6842, (q15_t)0xce40, (q15_t)0x6838, (q15_t)0xce38, (q15_t)0x682f, (q15_t)0xce30, + (q15_t)0x6825, (q15_t)0xce28, (q15_t)0x681b, (q15_t)0xce20, (q15_t)0x6811, (q15_t)0xce18, (q15_t)0x6808, (q15_t)0xce10, + (q15_t)0x67fe, (q15_t)0xce08, (q15_t)0x67f4, (q15_t)0xce01, (q15_t)0x67ea, (q15_t)0xcdf9, (q15_t)0x67e0, (q15_t)0xcdf1, + (q15_t)0x67d6, (q15_t)0xcde9, (q15_t)0x67cd, (q15_t)0xcde1, (q15_t)0x67c3, (q15_t)0xcdd9, (q15_t)0x67b9, (q15_t)0xcdd2, + (q15_t)0x67af, (q15_t)0xcdca, (q15_t)0x67a5, (q15_t)0xcdc2, (q15_t)0x679b, (q15_t)0xcdba, (q15_t)0x6791, (q15_t)0xcdb2, + (q15_t)0x6788, (q15_t)0xcdab, (q15_t)0x677e, (q15_t)0xcda3, (q15_t)0x6774, (q15_t)0xcd9b, (q15_t)0x676a, (q15_t)0xcd93, + (q15_t)0x6760, (q15_t)0xcd8c, (q15_t)0x6756, (q15_t)0xcd84, (q15_t)0x674c, (q15_t)0xcd7c, (q15_t)0x6742, (q15_t)0xcd75, + (q15_t)0x6738, (q15_t)0xcd6d, (q15_t)0x672e, (q15_t)0xcd65, (q15_t)0x6724, (q15_t)0xcd5d, (q15_t)0x671a, (q15_t)0xcd56, + (q15_t)0x6711, (q15_t)0xcd4e, (q15_t)0x6707, (q15_t)0xcd46, (q15_t)0x66fd, (q15_t)0xcd3f, (q15_t)0x66f3, (q15_t)0xcd37, + (q15_t)0x66e9, (q15_t)0xcd30, (q15_t)0x66df, (q15_t)0xcd28, (q15_t)0x66d5, (q15_t)0xcd20, (q15_t)0x66cb, (q15_t)0xcd19, + (q15_t)0x66c1, (q15_t)0xcd11, (q15_t)0x66b7, (q15_t)0xcd09, (q15_t)0x66ad, (q15_t)0xcd02, (q15_t)0x66a3, (q15_t)0xccfa, + (q15_t)0x6699, (q15_t)0xccf3, (q15_t)0x668f, (q15_t)0xcceb, (q15_t)0x6685, (q15_t)0xcce3, (q15_t)0x667b, (q15_t)0xccdc, + (q15_t)0x6671, (q15_t)0xccd4, (q15_t)0x6666, (q15_t)0xcccd, (q15_t)0x665c, (q15_t)0xccc5, (q15_t)0x6652, (q15_t)0xccbe, + (q15_t)0x6648, (q15_t)0xccb6, (q15_t)0x663e, (q15_t)0xccaf, (q15_t)0x6634, (q15_t)0xcca7, (q15_t)0x662a, (q15_t)0xcca0, + (q15_t)0x6620, (q15_t)0xcc98, (q15_t)0x6616, (q15_t)0xcc91, (q15_t)0x660c, (q15_t)0xcc89, (q15_t)0x6602, (q15_t)0xcc82, + (q15_t)0x65f8, (q15_t)0xcc7a, (q15_t)0x65ed, (q15_t)0xcc73, (q15_t)0x65e3, (q15_t)0xcc6b, (q15_t)0x65d9, (q15_t)0xcc64, + (q15_t)0x65cf, (q15_t)0xcc5d, (q15_t)0x65c5, (q15_t)0xcc55, (q15_t)0x65bb, (q15_t)0xcc4e, (q15_t)0x65b1, (q15_t)0xcc46, + (q15_t)0x65a6, (q15_t)0xcc3f, (q15_t)0x659c, (q15_t)0xcc38, (q15_t)0x6592, (q15_t)0xcc30, (q15_t)0x6588, (q15_t)0xcc29, + (q15_t)0x657e, (q15_t)0xcc21, (q15_t)0x6574, (q15_t)0xcc1a, (q15_t)0x6569, (q15_t)0xcc13, (q15_t)0x655f, (q15_t)0xcc0b, + (q15_t)0x6555, (q15_t)0xcc04, (q15_t)0x654b, (q15_t)0xcbfd, (q15_t)0x6541, (q15_t)0xcbf5, (q15_t)0x6536, (q15_t)0xcbee, + (q15_t)0x652c, (q15_t)0xcbe7, (q15_t)0x6522, (q15_t)0xcbe0, (q15_t)0x6518, (q15_t)0xcbd8, (q15_t)0x650d, (q15_t)0xcbd1, + (q15_t)0x6503, (q15_t)0xcbca, (q15_t)0x64f9, (q15_t)0xcbc2, (q15_t)0x64ef, (q15_t)0xcbbb, (q15_t)0x64e4, (q15_t)0xcbb4, + (q15_t)0x64da, (q15_t)0xcbad, (q15_t)0x64d0, (q15_t)0xcba5, (q15_t)0x64c5, (q15_t)0xcb9e, (q15_t)0x64bb, (q15_t)0xcb97, + (q15_t)0x64b1, (q15_t)0xcb90, (q15_t)0x64a7, (q15_t)0xcb89, (q15_t)0x649c, (q15_t)0xcb81, (q15_t)0x6492, (q15_t)0xcb7a, + (q15_t)0x6488, (q15_t)0xcb73, (q15_t)0x647d, (q15_t)0xcb6c, (q15_t)0x6473, (q15_t)0xcb65, (q15_t)0x6469, (q15_t)0xcb5e, + (q15_t)0x645e, (q15_t)0xcb56, (q15_t)0x6454, (q15_t)0xcb4f, (q15_t)0x644a, (q15_t)0xcb48, (q15_t)0x643f, (q15_t)0xcb41, + (q15_t)0x6435, (q15_t)0xcb3a, (q15_t)0x642b, (q15_t)0xcb33, (q15_t)0x6420, (q15_t)0xcb2c, (q15_t)0x6416, (q15_t)0xcb25, + (q15_t)0x640b, (q15_t)0xcb1e, (q15_t)0x6401, (q15_t)0xcb16, (q15_t)0x63f7, (q15_t)0xcb0f, (q15_t)0x63ec, (q15_t)0xcb08, + (q15_t)0x63e2, (q15_t)0xcb01, (q15_t)0x63d7, (q15_t)0xcafa, (q15_t)0x63cd, (q15_t)0xcaf3, (q15_t)0x63c3, (q15_t)0xcaec, + (q15_t)0x63b8, (q15_t)0xcae5, (q15_t)0x63ae, (q15_t)0xcade, (q15_t)0x63a3, (q15_t)0xcad7, (q15_t)0x6399, (q15_t)0xcad0, + (q15_t)0x638e, (q15_t)0xcac9, (q15_t)0x6384, (q15_t)0xcac2, (q15_t)0x637a, (q15_t)0xcabb, (q15_t)0x636f, (q15_t)0xcab4, + (q15_t)0x6365, (q15_t)0xcaad, (q15_t)0x635a, (q15_t)0xcaa6, (q15_t)0x6350, (q15_t)0xca9f, (q15_t)0x6345, (q15_t)0xca99, + (q15_t)0x633b, (q15_t)0xca92, (q15_t)0x6330, (q15_t)0xca8b, (q15_t)0x6326, (q15_t)0xca84, (q15_t)0x631b, (q15_t)0xca7d, + (q15_t)0x6311, (q15_t)0xca76, (q15_t)0x6306, (q15_t)0xca6f, (q15_t)0x62fc, (q15_t)0xca68, (q15_t)0x62f1, (q15_t)0xca61, + (q15_t)0x62e7, (q15_t)0xca5b, (q15_t)0x62dc, (q15_t)0xca54, (q15_t)0x62d2, (q15_t)0xca4d, (q15_t)0x62c7, (q15_t)0xca46, + (q15_t)0x62bc, (q15_t)0xca3f, (q15_t)0x62b2, (q15_t)0xca38, (q15_t)0x62a7, (q15_t)0xca32, (q15_t)0x629d, (q15_t)0xca2b, + (q15_t)0x6292, (q15_t)0xca24, (q15_t)0x6288, (q15_t)0xca1d, (q15_t)0x627d, (q15_t)0xca16, (q15_t)0x6272, (q15_t)0xca10, + (q15_t)0x6268, (q15_t)0xca09, (q15_t)0x625d, (q15_t)0xca02, (q15_t)0x6253, (q15_t)0xc9fb, (q15_t)0x6248, (q15_t)0xc9f5, + (q15_t)0x623d, (q15_t)0xc9ee, (q15_t)0x6233, (q15_t)0xc9e7, (q15_t)0x6228, (q15_t)0xc9e0, (q15_t)0x621e, (q15_t)0xc9da, + (q15_t)0x6213, (q15_t)0xc9d3, (q15_t)0x6208, (q15_t)0xc9cc, (q15_t)0x61fe, (q15_t)0xc9c6, (q15_t)0x61f3, (q15_t)0xc9bf, + (q15_t)0x61e8, (q15_t)0xc9b8, (q15_t)0x61de, (q15_t)0xc9b2, (q15_t)0x61d3, (q15_t)0xc9ab, (q15_t)0x61c8, (q15_t)0xc9a4, + (q15_t)0x61be, (q15_t)0xc99e, (q15_t)0x61b3, (q15_t)0xc997, (q15_t)0x61a8, (q15_t)0xc991, (q15_t)0x619e, (q15_t)0xc98a, + (q15_t)0x6193, (q15_t)0xc983, (q15_t)0x6188, (q15_t)0xc97d, (q15_t)0x617d, (q15_t)0xc976, (q15_t)0x6173, (q15_t)0xc970, + (q15_t)0x6168, (q15_t)0xc969, (q15_t)0x615d, (q15_t)0xc963, (q15_t)0x6153, (q15_t)0xc95c, (q15_t)0x6148, (q15_t)0xc955, + (q15_t)0x613d, (q15_t)0xc94f, (q15_t)0x6132, (q15_t)0xc948, (q15_t)0x6128, (q15_t)0xc942, (q15_t)0x611d, (q15_t)0xc93b, + (q15_t)0x6112, (q15_t)0xc935, (q15_t)0x6107, (q15_t)0xc92e, (q15_t)0x60fd, (q15_t)0xc928, (q15_t)0x60f2, (q15_t)0xc921, + (q15_t)0x60e7, (q15_t)0xc91b, (q15_t)0x60dc, (q15_t)0xc915, (q15_t)0x60d1, (q15_t)0xc90e, (q15_t)0x60c7, (q15_t)0xc908, + (q15_t)0x60bc, (q15_t)0xc901, (q15_t)0x60b1, (q15_t)0xc8fb, (q15_t)0x60a6, (q15_t)0xc8f4, (q15_t)0x609b, (q15_t)0xc8ee, + (q15_t)0x6091, (q15_t)0xc8e8, (q15_t)0x6086, (q15_t)0xc8e1, (q15_t)0x607b, (q15_t)0xc8db, (q15_t)0x6070, (q15_t)0xc8d4, + (q15_t)0x6065, (q15_t)0xc8ce, (q15_t)0x605b, (q15_t)0xc8c8, (q15_t)0x6050, (q15_t)0xc8c1, (q15_t)0x6045, (q15_t)0xc8bb, + (q15_t)0x603a, (q15_t)0xc8b5, (q15_t)0x602f, (q15_t)0xc8ae, (q15_t)0x6024, (q15_t)0xc8a8, (q15_t)0x6019, (q15_t)0xc8a2, + (q15_t)0x600f, (q15_t)0xc89b, (q15_t)0x6004, (q15_t)0xc895, (q15_t)0x5ff9, (q15_t)0xc88f, (q15_t)0x5fee, (q15_t)0xc889, + (q15_t)0x5fe3, (q15_t)0xc882, (q15_t)0x5fd8, (q15_t)0xc87c, (q15_t)0x5fcd, (q15_t)0xc876, (q15_t)0x5fc2, (q15_t)0xc870, + (q15_t)0x5fb7, (q15_t)0xc869, (q15_t)0x5fac, (q15_t)0xc863, (q15_t)0x5fa2, (q15_t)0xc85d, (q15_t)0x5f97, (q15_t)0xc857, + (q15_t)0x5f8c, (q15_t)0xc850, (q15_t)0x5f81, (q15_t)0xc84a, (q15_t)0x5f76, (q15_t)0xc844, (q15_t)0x5f6b, (q15_t)0xc83e, + (q15_t)0x5f60, (q15_t)0xc838, (q15_t)0x5f55, (q15_t)0xc832, (q15_t)0x5f4a, (q15_t)0xc82b, (q15_t)0x5f3f, (q15_t)0xc825, + (q15_t)0x5f34, (q15_t)0xc81f, (q15_t)0x5f29, (q15_t)0xc819, (q15_t)0x5f1e, (q15_t)0xc813, (q15_t)0x5f13, (q15_t)0xc80d, + (q15_t)0x5f08, (q15_t)0xc807, (q15_t)0x5efd, (q15_t)0xc801, (q15_t)0x5ef2, (q15_t)0xc7fb, (q15_t)0x5ee7, (q15_t)0xc7f5, + (q15_t)0x5edc, (q15_t)0xc7ee, (q15_t)0x5ed1, (q15_t)0xc7e8, (q15_t)0x5ec6, (q15_t)0xc7e2, (q15_t)0x5ebb, (q15_t)0xc7dc, + (q15_t)0x5eb0, (q15_t)0xc7d6, (q15_t)0x5ea5, (q15_t)0xc7d0, (q15_t)0x5e9a, (q15_t)0xc7ca, (q15_t)0x5e8f, (q15_t)0xc7c4, + (q15_t)0x5e84, (q15_t)0xc7be, (q15_t)0x5e79, (q15_t)0xc7b8, (q15_t)0x5e6e, (q15_t)0xc7b2, (q15_t)0x5e63, (q15_t)0xc7ac, + (q15_t)0x5e58, (q15_t)0xc7a6, (q15_t)0x5e4d, (q15_t)0xc7a0, (q15_t)0x5e42, (q15_t)0xc79a, (q15_t)0x5e36, (q15_t)0xc795, + (q15_t)0x5e2b, (q15_t)0xc78f, (q15_t)0x5e20, (q15_t)0xc789, (q15_t)0x5e15, (q15_t)0xc783, (q15_t)0x5e0a, (q15_t)0xc77d, + (q15_t)0x5dff, (q15_t)0xc777, (q15_t)0x5df4, (q15_t)0xc771, (q15_t)0x5de9, (q15_t)0xc76b, (q15_t)0x5dde, (q15_t)0xc765, + (q15_t)0x5dd3, (q15_t)0xc75f, (q15_t)0x5dc7, (q15_t)0xc75a, (q15_t)0x5dbc, (q15_t)0xc754, (q15_t)0x5db1, (q15_t)0xc74e, + (q15_t)0x5da6, (q15_t)0xc748, (q15_t)0x5d9b, (q15_t)0xc742, (q15_t)0x5d90, (q15_t)0xc73d, (q15_t)0x5d85, (q15_t)0xc737, + (q15_t)0x5d79, (q15_t)0xc731, (q15_t)0x5d6e, (q15_t)0xc72b, (q15_t)0x5d63, (q15_t)0xc725, (q15_t)0x5d58, (q15_t)0xc720, + (q15_t)0x5d4d, (q15_t)0xc71a, (q15_t)0x5d42, (q15_t)0xc714, (q15_t)0x5d36, (q15_t)0xc70e, (q15_t)0x5d2b, (q15_t)0xc709, + (q15_t)0x5d20, (q15_t)0xc703, (q15_t)0x5d15, (q15_t)0xc6fd, (q15_t)0x5d0a, (q15_t)0xc6f7, (q15_t)0x5cff, (q15_t)0xc6f2, + (q15_t)0x5cf3, (q15_t)0xc6ec, (q15_t)0x5ce8, (q15_t)0xc6e6, (q15_t)0x5cdd, (q15_t)0xc6e1, (q15_t)0x5cd2, (q15_t)0xc6db, + (q15_t)0x5cc6, (q15_t)0xc6d5, (q15_t)0x5cbb, (q15_t)0xc6d0, (q15_t)0x5cb0, (q15_t)0xc6ca, (q15_t)0x5ca5, (q15_t)0xc6c5, + (q15_t)0x5c99, (q15_t)0xc6bf, (q15_t)0x5c8e, (q15_t)0xc6b9, (q15_t)0x5c83, (q15_t)0xc6b4, (q15_t)0x5c78, (q15_t)0xc6ae, + (q15_t)0x5c6c, (q15_t)0xc6a8, (q15_t)0x5c61, (q15_t)0xc6a3, (q15_t)0x5c56, (q15_t)0xc69d, (q15_t)0x5c4b, (q15_t)0xc698, + (q15_t)0x5c3f, (q15_t)0xc692, (q15_t)0x5c34, (q15_t)0xc68d, (q15_t)0x5c29, (q15_t)0xc687, (q15_t)0x5c1e, (q15_t)0xc682, + (q15_t)0x5c12, (q15_t)0xc67c, (q15_t)0x5c07, (q15_t)0xc677, (q15_t)0x5bfc, (q15_t)0xc671, (q15_t)0x5bf0, (q15_t)0xc66c, + (q15_t)0x5be5, (q15_t)0xc666, (q15_t)0x5bda, (q15_t)0xc661, (q15_t)0x5bce, (q15_t)0xc65b, (q15_t)0x5bc3, (q15_t)0xc656, + (q15_t)0x5bb8, (q15_t)0xc650, (q15_t)0x5bac, (q15_t)0xc64b, (q15_t)0x5ba1, (q15_t)0xc645, (q15_t)0x5b96, (q15_t)0xc640, + (q15_t)0x5b8a, (q15_t)0xc63b, (q15_t)0x5b7f, (q15_t)0xc635, (q15_t)0x5b74, (q15_t)0xc630, (q15_t)0x5b68, (q15_t)0xc62a, + (q15_t)0x5b5d, (q15_t)0xc625, (q15_t)0x5b52, (q15_t)0xc620, (q15_t)0x5b46, (q15_t)0xc61a, (q15_t)0x5b3b, (q15_t)0xc615, + (q15_t)0x5b30, (q15_t)0xc610, (q15_t)0x5b24, (q15_t)0xc60a, (q15_t)0x5b19, (q15_t)0xc605, (q15_t)0x5b0d, (q15_t)0xc600, + (q15_t)0x5b02, (q15_t)0xc5fa, (q15_t)0x5af7, (q15_t)0xc5f5, (q15_t)0x5aeb, (q15_t)0xc5f0, (q15_t)0x5ae0, (q15_t)0xc5ea, + (q15_t)0x5ad4, (q15_t)0xc5e5, (q15_t)0x5ac9, (q15_t)0xc5e0, (q15_t)0x5abe, (q15_t)0xc5db, (q15_t)0x5ab2, (q15_t)0xc5d5, + (q15_t)0x5aa7, (q15_t)0xc5d0, (q15_t)0x5a9b, (q15_t)0xc5cb, (q15_t)0x5a90, (q15_t)0xc5c6, (q15_t)0x5a84, (q15_t)0xc5c1, + (q15_t)0x5a79, (q15_t)0xc5bb, (q15_t)0x5a6e, (q15_t)0xc5b6, (q15_t)0x5a62, (q15_t)0xc5b1, (q15_t)0x5a57, (q15_t)0xc5ac, + (q15_t)0x5a4b, (q15_t)0xc5a7, (q15_t)0x5a40, (q15_t)0xc5a1, (q15_t)0x5a34, (q15_t)0xc59c, (q15_t)0x5a29, (q15_t)0xc597, + (q15_t)0x5a1d, (q15_t)0xc592, (q15_t)0x5a12, (q15_t)0xc58d, (q15_t)0x5a06, (q15_t)0xc588, (q15_t)0x59fb, (q15_t)0xc583, + (q15_t)0x59ef, (q15_t)0xc57e, (q15_t)0x59e4, (q15_t)0xc578, (q15_t)0x59d8, (q15_t)0xc573, (q15_t)0x59cd, (q15_t)0xc56e, + (q15_t)0x59c1, (q15_t)0xc569, (q15_t)0x59b6, (q15_t)0xc564, (q15_t)0x59aa, (q15_t)0xc55f, (q15_t)0x599f, (q15_t)0xc55a, + (q15_t)0x5993, (q15_t)0xc555, (q15_t)0x5988, (q15_t)0xc550, (q15_t)0x597c, (q15_t)0xc54b, (q15_t)0x5971, (q15_t)0xc546, + (q15_t)0x5965, (q15_t)0xc541, (q15_t)0x595a, (q15_t)0xc53c, (q15_t)0x594e, (q15_t)0xc537, (q15_t)0x5943, (q15_t)0xc532, + (q15_t)0x5937, (q15_t)0xc52d, (q15_t)0x592c, (q15_t)0xc528, (q15_t)0x5920, (q15_t)0xc523, (q15_t)0x5914, (q15_t)0xc51e, + (q15_t)0x5909, (q15_t)0xc51a, (q15_t)0x58fd, (q15_t)0xc515, (q15_t)0x58f2, (q15_t)0xc510, (q15_t)0x58e6, (q15_t)0xc50b, + (q15_t)0x58db, (q15_t)0xc506, (q15_t)0x58cf, (q15_t)0xc501, (q15_t)0x58c3, (q15_t)0xc4fc, (q15_t)0x58b8, (q15_t)0xc4f7, + (q15_t)0x58ac, (q15_t)0xc4f2, (q15_t)0x58a1, (q15_t)0xc4ee, (q15_t)0x5895, (q15_t)0xc4e9, (q15_t)0x5889, (q15_t)0xc4e4, + (q15_t)0x587e, (q15_t)0xc4df, (q15_t)0x5872, (q15_t)0xc4da, (q15_t)0x5867, (q15_t)0xc4d6, (q15_t)0x585b, (q15_t)0xc4d1, + (q15_t)0x584f, (q15_t)0xc4cc, (q15_t)0x5844, (q15_t)0xc4c7, (q15_t)0x5838, (q15_t)0xc4c2, (q15_t)0x582d, (q15_t)0xc4be, + (q15_t)0x5821, (q15_t)0xc4b9, (q15_t)0x5815, (q15_t)0xc4b4, (q15_t)0x580a, (q15_t)0xc4b0, (q15_t)0x57fe, (q15_t)0xc4ab, + (q15_t)0x57f2, (q15_t)0xc4a6, (q15_t)0x57e7, (q15_t)0xc4a1, (q15_t)0x57db, (q15_t)0xc49d, (q15_t)0x57cf, (q15_t)0xc498, + (q15_t)0x57c4, (q15_t)0xc493, (q15_t)0x57b8, (q15_t)0xc48f, (q15_t)0x57ac, (q15_t)0xc48a, (q15_t)0x57a1, (q15_t)0xc485, + (q15_t)0x5795, (q15_t)0xc481, (q15_t)0x5789, (q15_t)0xc47c, (q15_t)0x577e, (q15_t)0xc478, (q15_t)0x5772, (q15_t)0xc473, + (q15_t)0x5766, (q15_t)0xc46e, (q15_t)0x575b, (q15_t)0xc46a, (q15_t)0x574f, (q15_t)0xc465, (q15_t)0x5743, (q15_t)0xc461, + (q15_t)0x5737, (q15_t)0xc45c, (q15_t)0x572c, (q15_t)0xc457, (q15_t)0x5720, (q15_t)0xc453, (q15_t)0x5714, (q15_t)0xc44e, + (q15_t)0x5709, (q15_t)0xc44a, (q15_t)0x56fd, (q15_t)0xc445, (q15_t)0x56f1, (q15_t)0xc441, (q15_t)0x56e5, (q15_t)0xc43c, + (q15_t)0x56da, (q15_t)0xc438, (q15_t)0x56ce, (q15_t)0xc433, (q15_t)0x56c2, (q15_t)0xc42f, (q15_t)0x56b6, (q15_t)0xc42a, + (q15_t)0x56ab, (q15_t)0xc426, (q15_t)0x569f, (q15_t)0xc422, (q15_t)0x5693, (q15_t)0xc41d, (q15_t)0x5687, (q15_t)0xc419, + (q15_t)0x567c, (q15_t)0xc414, (q15_t)0x5670, (q15_t)0xc410, (q15_t)0x5664, (q15_t)0xc40b, (q15_t)0x5658, (q15_t)0xc407, + (q15_t)0x564c, (q15_t)0xc403, (q15_t)0x5641, (q15_t)0xc3fe, (q15_t)0x5635, (q15_t)0xc3fa, (q15_t)0x5629, (q15_t)0xc3f6, + (q15_t)0x561d, (q15_t)0xc3f1, (q15_t)0x5612, (q15_t)0xc3ed, (q15_t)0x5606, (q15_t)0xc3e9, (q15_t)0x55fa, (q15_t)0xc3e4, + (q15_t)0x55ee, (q15_t)0xc3e0, (q15_t)0x55e2, (q15_t)0xc3dc, (q15_t)0x55d7, (q15_t)0xc3d7, (q15_t)0x55cb, (q15_t)0xc3d3, + (q15_t)0x55bf, (q15_t)0xc3cf, (q15_t)0x55b3, (q15_t)0xc3ca, (q15_t)0x55a7, (q15_t)0xc3c6, (q15_t)0x559b, (q15_t)0xc3c2, + (q15_t)0x5590, (q15_t)0xc3be, (q15_t)0x5584, (q15_t)0xc3ba, (q15_t)0x5578, (q15_t)0xc3b5, (q15_t)0x556c, (q15_t)0xc3b1, + (q15_t)0x5560, (q15_t)0xc3ad, (q15_t)0x5554, (q15_t)0xc3a9, (q15_t)0x5549, (q15_t)0xc3a5, (q15_t)0x553d, (q15_t)0xc3a0, + (q15_t)0x5531, (q15_t)0xc39c, (q15_t)0x5525, (q15_t)0xc398, (q15_t)0x5519, (q15_t)0xc394, (q15_t)0x550d, (q15_t)0xc390, + (q15_t)0x5501, (q15_t)0xc38c, (q15_t)0x54f6, (q15_t)0xc387, (q15_t)0x54ea, (q15_t)0xc383, (q15_t)0x54de, (q15_t)0xc37f, + (q15_t)0x54d2, (q15_t)0xc37b, (q15_t)0x54c6, (q15_t)0xc377, (q15_t)0x54ba, (q15_t)0xc373, (q15_t)0x54ae, (q15_t)0xc36f, + (q15_t)0x54a2, (q15_t)0xc36b, (q15_t)0x5496, (q15_t)0xc367, (q15_t)0x548b, (q15_t)0xc363, (q15_t)0x547f, (q15_t)0xc35f, + (q15_t)0x5473, (q15_t)0xc35b, (q15_t)0x5467, (q15_t)0xc357, (q15_t)0x545b, (q15_t)0xc353, (q15_t)0x544f, (q15_t)0xc34f, + (q15_t)0x5443, (q15_t)0xc34b, (q15_t)0x5437, (q15_t)0xc347, (q15_t)0x542b, (q15_t)0xc343, (q15_t)0x541f, (q15_t)0xc33f, + (q15_t)0x5413, (q15_t)0xc33b, (q15_t)0x5407, (q15_t)0xc337, (q15_t)0x53fb, (q15_t)0xc333, (q15_t)0x53f0, (q15_t)0xc32f, + (q15_t)0x53e4, (q15_t)0xc32b, (q15_t)0x53d8, (q15_t)0xc327, (q15_t)0x53cc, (q15_t)0xc323, (q15_t)0x53c0, (q15_t)0xc320, + (q15_t)0x53b4, (q15_t)0xc31c, (q15_t)0x53a8, (q15_t)0xc318, (q15_t)0x539c, (q15_t)0xc314, (q15_t)0x5390, (q15_t)0xc310, + (q15_t)0x5384, (q15_t)0xc30c, (q15_t)0x5378, (q15_t)0xc308, (q15_t)0x536c, (q15_t)0xc305, (q15_t)0x5360, (q15_t)0xc301, + (q15_t)0x5354, (q15_t)0xc2fd, (q15_t)0x5348, (q15_t)0xc2f9, (q15_t)0x533c, (q15_t)0xc2f5, (q15_t)0x5330, (q15_t)0xc2f2, + (q15_t)0x5324, (q15_t)0xc2ee, (q15_t)0x5318, (q15_t)0xc2ea, (q15_t)0x530c, (q15_t)0xc2e6, (q15_t)0x5300, (q15_t)0xc2e3, + (q15_t)0x52f4, (q15_t)0xc2df, (q15_t)0x52e8, (q15_t)0xc2db, (q15_t)0x52dc, (q15_t)0xc2d8, (q15_t)0x52d0, (q15_t)0xc2d4, + (q15_t)0x52c4, (q15_t)0xc2d0, (q15_t)0x52b8, (q15_t)0xc2cc, (q15_t)0x52ac, (q15_t)0xc2c9, (q15_t)0x52a0, (q15_t)0xc2c5, + (q15_t)0x5294, (q15_t)0xc2c1, (q15_t)0x5288, (q15_t)0xc2be, (q15_t)0x527c, (q15_t)0xc2ba, (q15_t)0x5270, (q15_t)0xc2b7, + (q15_t)0x5264, (q15_t)0xc2b3, (q15_t)0x5258, (q15_t)0xc2af, (q15_t)0x524c, (q15_t)0xc2ac, (q15_t)0x5240, (q15_t)0xc2a8, + (q15_t)0x5234, (q15_t)0xc2a5, (q15_t)0x5228, (q15_t)0xc2a1, (q15_t)0x521c, (q15_t)0xc29d, (q15_t)0x5210, (q15_t)0xc29a, + (q15_t)0x5204, (q15_t)0xc296, (q15_t)0x51f7, (q15_t)0xc293, (q15_t)0x51eb, (q15_t)0xc28f, (q15_t)0x51df, (q15_t)0xc28c, + (q15_t)0x51d3, (q15_t)0xc288, (q15_t)0x51c7, (q15_t)0xc285, (q15_t)0x51bb, (q15_t)0xc281, (q15_t)0x51af, (q15_t)0xc27e, + (q15_t)0x51a3, (q15_t)0xc27a, (q15_t)0x5197, (q15_t)0xc277, (q15_t)0x518b, (q15_t)0xc273, (q15_t)0x517f, (q15_t)0xc270, + (q15_t)0x5173, (q15_t)0xc26d, (q15_t)0x5167, (q15_t)0xc269, (q15_t)0x515a, (q15_t)0xc266, (q15_t)0x514e, (q15_t)0xc262, + (q15_t)0x5142, (q15_t)0xc25f, (q15_t)0x5136, (q15_t)0xc25c, (q15_t)0x512a, (q15_t)0xc258, (q15_t)0x511e, (q15_t)0xc255, + (q15_t)0x5112, (q15_t)0xc251, (q15_t)0x5106, (q15_t)0xc24e, (q15_t)0x50fa, (q15_t)0xc24b, (q15_t)0x50ed, (q15_t)0xc247, + (q15_t)0x50e1, (q15_t)0xc244, (q15_t)0x50d5, (q15_t)0xc241, (q15_t)0x50c9, (q15_t)0xc23e, (q15_t)0x50bd, (q15_t)0xc23a, + (q15_t)0x50b1, (q15_t)0xc237, (q15_t)0x50a5, (q15_t)0xc234, (q15_t)0x5099, (q15_t)0xc230, (q15_t)0x508c, (q15_t)0xc22d, + (q15_t)0x5080, (q15_t)0xc22a, (q15_t)0x5074, (q15_t)0xc227, (q15_t)0x5068, (q15_t)0xc223, (q15_t)0x505c, (q15_t)0xc220, + (q15_t)0x5050, (q15_t)0xc21d, (q15_t)0x5044, (q15_t)0xc21a, (q15_t)0x5037, (q15_t)0xc217, (q15_t)0x502b, (q15_t)0xc213, + (q15_t)0x501f, (q15_t)0xc210, (q15_t)0x5013, (q15_t)0xc20d, (q15_t)0x5007, (q15_t)0xc20a, (q15_t)0x4ffb, (q15_t)0xc207, + (q15_t)0x4fee, (q15_t)0xc204, (q15_t)0x4fe2, (q15_t)0xc201, (q15_t)0x4fd6, (q15_t)0xc1fd, (q15_t)0x4fca, (q15_t)0xc1fa, + (q15_t)0x4fbe, (q15_t)0xc1f7, (q15_t)0x4fb2, (q15_t)0xc1f4, (q15_t)0x4fa5, (q15_t)0xc1f1, (q15_t)0x4f99, (q15_t)0xc1ee, + (q15_t)0x4f8d, (q15_t)0xc1eb, (q15_t)0x4f81, (q15_t)0xc1e8, (q15_t)0x4f75, (q15_t)0xc1e5, (q15_t)0x4f68, (q15_t)0xc1e2, + (q15_t)0x4f5c, (q15_t)0xc1df, (q15_t)0x4f50, (q15_t)0xc1dc, (q15_t)0x4f44, (q15_t)0xc1d9, (q15_t)0x4f38, (q15_t)0xc1d6, + (q15_t)0x4f2b, (q15_t)0xc1d3, (q15_t)0x4f1f, (q15_t)0xc1d0, (q15_t)0x4f13, (q15_t)0xc1cd, (q15_t)0x4f07, (q15_t)0xc1ca, + (q15_t)0x4efb, (q15_t)0xc1c7, (q15_t)0x4eee, (q15_t)0xc1c4, (q15_t)0x4ee2, (q15_t)0xc1c1, (q15_t)0x4ed6, (q15_t)0xc1be, + (q15_t)0x4eca, (q15_t)0xc1bb, (q15_t)0x4ebd, (q15_t)0xc1b8, (q15_t)0x4eb1, (q15_t)0xc1b6, (q15_t)0x4ea5, (q15_t)0xc1b3, + (q15_t)0x4e99, (q15_t)0xc1b0, (q15_t)0x4e8c, (q15_t)0xc1ad, (q15_t)0x4e80, (q15_t)0xc1aa, (q15_t)0x4e74, (q15_t)0xc1a7, + (q15_t)0x4e68, (q15_t)0xc1a4, (q15_t)0x4e5c, (q15_t)0xc1a2, (q15_t)0x4e4f, (q15_t)0xc19f, (q15_t)0x4e43, (q15_t)0xc19c, + (q15_t)0x4e37, (q15_t)0xc199, (q15_t)0x4e2b, (q15_t)0xc196, (q15_t)0x4e1e, (q15_t)0xc194, (q15_t)0x4e12, (q15_t)0xc191, + (q15_t)0x4e06, (q15_t)0xc18e, (q15_t)0x4df9, (q15_t)0xc18b, (q15_t)0x4ded, (q15_t)0xc189, (q15_t)0x4de1, (q15_t)0xc186, + (q15_t)0x4dd5, (q15_t)0xc183, (q15_t)0x4dc8, (q15_t)0xc180, (q15_t)0x4dbc, (q15_t)0xc17e, (q15_t)0x4db0, (q15_t)0xc17b, + (q15_t)0x4da4, (q15_t)0xc178, (q15_t)0x4d97, (q15_t)0xc176, (q15_t)0x4d8b, (q15_t)0xc173, (q15_t)0x4d7f, (q15_t)0xc170, + (q15_t)0x4d72, (q15_t)0xc16e, (q15_t)0x4d66, (q15_t)0xc16b, (q15_t)0x4d5a, (q15_t)0xc168, (q15_t)0x4d4e, (q15_t)0xc166, + (q15_t)0x4d41, (q15_t)0xc163, (q15_t)0x4d35, (q15_t)0xc161, (q15_t)0x4d29, (q15_t)0xc15e, (q15_t)0x4d1c, (q15_t)0xc15b, + (q15_t)0x4d10, (q15_t)0xc159, (q15_t)0x4d04, (q15_t)0xc156, (q15_t)0x4cf8, (q15_t)0xc154, (q15_t)0x4ceb, (q15_t)0xc151, + (q15_t)0x4cdf, (q15_t)0xc14f, (q15_t)0x4cd3, (q15_t)0xc14c, (q15_t)0x4cc6, (q15_t)0xc14a, (q15_t)0x4cba, (q15_t)0xc147, + (q15_t)0x4cae, (q15_t)0xc145, (q15_t)0x4ca1, (q15_t)0xc142, (q15_t)0x4c95, (q15_t)0xc140, (q15_t)0x4c89, (q15_t)0xc13d, + (q15_t)0x4c7c, (q15_t)0xc13b, (q15_t)0x4c70, (q15_t)0xc138, (q15_t)0x4c64, (q15_t)0xc136, (q15_t)0x4c57, (q15_t)0xc134, + (q15_t)0x4c4b, (q15_t)0xc131, (q15_t)0x4c3f, (q15_t)0xc12f, (q15_t)0x4c32, (q15_t)0xc12c, (q15_t)0x4c26, (q15_t)0xc12a, + (q15_t)0x4c1a, (q15_t)0xc128, (q15_t)0x4c0d, (q15_t)0xc125, (q15_t)0x4c01, (q15_t)0xc123, (q15_t)0x4bf5, (q15_t)0xc120, + (q15_t)0x4be8, (q15_t)0xc11e, (q15_t)0x4bdc, (q15_t)0xc11c, (q15_t)0x4bd0, (q15_t)0xc119, (q15_t)0x4bc3, (q15_t)0xc117, + (q15_t)0x4bb7, (q15_t)0xc115, (q15_t)0x4bab, (q15_t)0xc113, (q15_t)0x4b9e, (q15_t)0xc110, (q15_t)0x4b92, (q15_t)0xc10e, + (q15_t)0x4b85, (q15_t)0xc10c, (q15_t)0x4b79, (q15_t)0xc109, (q15_t)0x4b6d, (q15_t)0xc107, (q15_t)0x4b60, (q15_t)0xc105, + (q15_t)0x4b54, (q15_t)0xc103, (q15_t)0x4b48, (q15_t)0xc100, (q15_t)0x4b3b, (q15_t)0xc0fe, (q15_t)0x4b2f, (q15_t)0xc0fc, + (q15_t)0x4b23, (q15_t)0xc0fa, (q15_t)0x4b16, (q15_t)0xc0f8, (q15_t)0x4b0a, (q15_t)0xc0f6, (q15_t)0x4afd, (q15_t)0xc0f3, + (q15_t)0x4af1, (q15_t)0xc0f1, (q15_t)0x4ae5, (q15_t)0xc0ef, (q15_t)0x4ad8, (q15_t)0xc0ed, (q15_t)0x4acc, (q15_t)0xc0eb, + (q15_t)0x4ac0, (q15_t)0xc0e9, (q15_t)0x4ab3, (q15_t)0xc0e7, (q15_t)0x4aa7, (q15_t)0xc0e4, (q15_t)0x4a9a, (q15_t)0xc0e2, + (q15_t)0x4a8e, (q15_t)0xc0e0, (q15_t)0x4a82, (q15_t)0xc0de, (q15_t)0x4a75, (q15_t)0xc0dc, (q15_t)0x4a69, (q15_t)0xc0da, + (q15_t)0x4a5c, (q15_t)0xc0d8, (q15_t)0x4a50, (q15_t)0xc0d6, (q15_t)0x4a44, (q15_t)0xc0d4, (q15_t)0x4a37, (q15_t)0xc0d2, + (q15_t)0x4a2b, (q15_t)0xc0d0, (q15_t)0x4a1e, (q15_t)0xc0ce, (q15_t)0x4a12, (q15_t)0xc0cc, (q15_t)0x4a06, (q15_t)0xc0ca, + (q15_t)0x49f9, (q15_t)0xc0c8, (q15_t)0x49ed, (q15_t)0xc0c6, (q15_t)0x49e0, (q15_t)0xc0c4, (q15_t)0x49d4, (q15_t)0xc0c2, + (q15_t)0x49c7, (q15_t)0xc0c0, (q15_t)0x49bb, (q15_t)0xc0be, (q15_t)0x49af, (q15_t)0xc0bd, (q15_t)0x49a2, (q15_t)0xc0bb, + (q15_t)0x4996, (q15_t)0xc0b9, (q15_t)0x4989, (q15_t)0xc0b7, (q15_t)0x497d, (q15_t)0xc0b5, (q15_t)0x4970, (q15_t)0xc0b3, + (q15_t)0x4964, (q15_t)0xc0b1, (q15_t)0x4958, (q15_t)0xc0af, (q15_t)0x494b, (q15_t)0xc0ae, (q15_t)0x493f, (q15_t)0xc0ac, + (q15_t)0x4932, (q15_t)0xc0aa, (q15_t)0x4926, (q15_t)0xc0a8, (q15_t)0x4919, (q15_t)0xc0a6, (q15_t)0x490d, (q15_t)0xc0a5, + (q15_t)0x4901, (q15_t)0xc0a3, (q15_t)0x48f4, (q15_t)0xc0a1, (q15_t)0x48e8, (q15_t)0xc09f, (q15_t)0x48db, (q15_t)0xc09e, + (q15_t)0x48cf, (q15_t)0xc09c, (q15_t)0x48c2, (q15_t)0xc09a, (q15_t)0x48b6, (q15_t)0xc098, (q15_t)0x48a9, (q15_t)0xc097, + (q15_t)0x489d, (q15_t)0xc095, (q15_t)0x4891, (q15_t)0xc093, (q15_t)0x4884, (q15_t)0xc092, (q15_t)0x4878, (q15_t)0xc090, + (q15_t)0x486b, (q15_t)0xc08e, (q15_t)0x485f, (q15_t)0xc08d, (q15_t)0x4852, (q15_t)0xc08b, (q15_t)0x4846, (q15_t)0xc089, + (q15_t)0x4839, (q15_t)0xc088, (q15_t)0x482d, (q15_t)0xc086, (q15_t)0x4820, (q15_t)0xc085, (q15_t)0x4814, (q15_t)0xc083, + (q15_t)0x4807, (q15_t)0xc081, (q15_t)0x47fb, (q15_t)0xc080, (q15_t)0x47ef, (q15_t)0xc07e, (q15_t)0x47e2, (q15_t)0xc07d, + (q15_t)0x47d6, (q15_t)0xc07b, (q15_t)0x47c9, (q15_t)0xc07a, (q15_t)0x47bd, (q15_t)0xc078, (q15_t)0x47b0, (q15_t)0xc077, + (q15_t)0x47a4, (q15_t)0xc075, (q15_t)0x4797, (q15_t)0xc074, (q15_t)0x478b, (q15_t)0xc072, (q15_t)0x477e, (q15_t)0xc071, + (q15_t)0x4772, (q15_t)0xc06f, (q15_t)0x4765, (q15_t)0xc06e, (q15_t)0x4759, (q15_t)0xc06c, (q15_t)0x474c, (q15_t)0xc06b, + (q15_t)0x4740, (q15_t)0xc069, (q15_t)0x4733, (q15_t)0xc068, (q15_t)0x4727, (q15_t)0xc067, (q15_t)0x471a, (q15_t)0xc065, + (q15_t)0x470e, (q15_t)0xc064, (q15_t)0x4701, (q15_t)0xc062, (q15_t)0x46f5, (q15_t)0xc061, (q15_t)0x46e8, (q15_t)0xc060, + (q15_t)0x46dc, (q15_t)0xc05e, (q15_t)0x46cf, (q15_t)0xc05d, (q15_t)0x46c3, (q15_t)0xc05c, (q15_t)0x46b6, (q15_t)0xc05a, + (q15_t)0x46aa, (q15_t)0xc059, (q15_t)0x469d, (q15_t)0xc058, (q15_t)0x4691, (q15_t)0xc056, (q15_t)0x4684, (q15_t)0xc055, + (q15_t)0x4678, (q15_t)0xc054, (q15_t)0x466b, (q15_t)0xc053, (q15_t)0x465f, (q15_t)0xc051, (q15_t)0x4652, (q15_t)0xc050, + (q15_t)0x4646, (q15_t)0xc04f, (q15_t)0x4639, (q15_t)0xc04e, (q15_t)0x462d, (q15_t)0xc04c, (q15_t)0x4620, (q15_t)0xc04b, + (q15_t)0x4614, (q15_t)0xc04a, (q15_t)0x4607, (q15_t)0xc049, (q15_t)0x45fb, (q15_t)0xc048, (q15_t)0x45ee, (q15_t)0xc047, + (q15_t)0x45e2, (q15_t)0xc045, (q15_t)0x45d5, (q15_t)0xc044, (q15_t)0x45c9, (q15_t)0xc043, (q15_t)0x45bc, (q15_t)0xc042, + (q15_t)0x45b0, (q15_t)0xc041, (q15_t)0x45a3, (q15_t)0xc040, (q15_t)0x4597, (q15_t)0xc03f, (q15_t)0x458a, (q15_t)0xc03d, + (q15_t)0x457e, (q15_t)0xc03c, (q15_t)0x4571, (q15_t)0xc03b, (q15_t)0x4565, (q15_t)0xc03a, (q15_t)0x4558, (q15_t)0xc039, + (q15_t)0x454c, (q15_t)0xc038, (q15_t)0x453f, (q15_t)0xc037, (q15_t)0x4533, (q15_t)0xc036, (q15_t)0x4526, (q15_t)0xc035, + (q15_t)0x451a, (q15_t)0xc034, (q15_t)0x450d, (q15_t)0xc033, (q15_t)0x4500, (q15_t)0xc032, (q15_t)0x44f4, (q15_t)0xc031, + (q15_t)0x44e7, (q15_t)0xc030, (q15_t)0x44db, (q15_t)0xc02f, (q15_t)0x44ce, (q15_t)0xc02e, (q15_t)0x44c2, (q15_t)0xc02d, + (q15_t)0x44b5, (q15_t)0xc02c, (q15_t)0x44a9, (q15_t)0xc02b, (q15_t)0x449c, (q15_t)0xc02b, (q15_t)0x4490, (q15_t)0xc02a, + (q15_t)0x4483, (q15_t)0xc029, (q15_t)0x4477, (q15_t)0xc028, (q15_t)0x446a, (q15_t)0xc027, (q15_t)0x445e, (q15_t)0xc026, + (q15_t)0x4451, (q15_t)0xc025, (q15_t)0x4444, (q15_t)0xc024, (q15_t)0x4438, (q15_t)0xc024, (q15_t)0x442b, (q15_t)0xc023, + (q15_t)0x441f, (q15_t)0xc022, (q15_t)0x4412, (q15_t)0xc021, (q15_t)0x4406, (q15_t)0xc020, (q15_t)0x43f9, (q15_t)0xc020, + (q15_t)0x43ed, (q15_t)0xc01f, (q15_t)0x43e0, (q15_t)0xc01e, (q15_t)0x43d4, (q15_t)0xc01d, (q15_t)0x43c7, (q15_t)0xc01d, + (q15_t)0x43bb, (q15_t)0xc01c, (q15_t)0x43ae, (q15_t)0xc01b, (q15_t)0x43a1, (q15_t)0xc01a, (q15_t)0x4395, (q15_t)0xc01a, + (q15_t)0x4388, (q15_t)0xc019, (q15_t)0x437c, (q15_t)0xc018, (q15_t)0x436f, (q15_t)0xc018, (q15_t)0x4363, (q15_t)0xc017, + (q15_t)0x4356, (q15_t)0xc016, (q15_t)0x434a, (q15_t)0xc016, (q15_t)0x433d, (q15_t)0xc015, (q15_t)0x4330, (q15_t)0xc014, + (q15_t)0x4324, (q15_t)0xc014, (q15_t)0x4317, (q15_t)0xc013, (q15_t)0x430b, (q15_t)0xc013, (q15_t)0x42fe, (q15_t)0xc012, + (q15_t)0x42f2, (q15_t)0xc011, (q15_t)0x42e5, (q15_t)0xc011, (q15_t)0x42d9, (q15_t)0xc010, (q15_t)0x42cc, (q15_t)0xc010, + (q15_t)0x42c0, (q15_t)0xc00f, (q15_t)0x42b3, (q15_t)0xc00f, (q15_t)0x42a6, (q15_t)0xc00e, (q15_t)0x429a, (q15_t)0xc00e, + (q15_t)0x428d, (q15_t)0xc00d, (q15_t)0x4281, (q15_t)0xc00d, (q15_t)0x4274, (q15_t)0xc00c, (q15_t)0x4268, (q15_t)0xc00c, + (q15_t)0x425b, (q15_t)0xc00b, (q15_t)0x424e, (q15_t)0xc00b, (q15_t)0x4242, (q15_t)0xc00a, (q15_t)0x4235, (q15_t)0xc00a, + (q15_t)0x4229, (q15_t)0xc009, (q15_t)0x421c, (q15_t)0xc009, (q15_t)0x4210, (q15_t)0xc009, (q15_t)0x4203, (q15_t)0xc008, + (q15_t)0x41f7, (q15_t)0xc008, (q15_t)0x41ea, (q15_t)0xc007, (q15_t)0x41dd, (q15_t)0xc007, (q15_t)0x41d1, (q15_t)0xc007, + (q15_t)0x41c4, (q15_t)0xc006, (q15_t)0x41b8, (q15_t)0xc006, (q15_t)0x41ab, (q15_t)0xc006, (q15_t)0x419f, (q15_t)0xc005, + (q15_t)0x4192, (q15_t)0xc005, (q15_t)0x4186, (q15_t)0xc005, (q15_t)0x4179, (q15_t)0xc004, (q15_t)0x416c, (q15_t)0xc004, + (q15_t)0x4160, (q15_t)0xc004, (q15_t)0x4153, (q15_t)0xc004, (q15_t)0x4147, (q15_t)0xc003, (q15_t)0x413a, (q15_t)0xc003, + (q15_t)0x412e, (q15_t)0xc003, (q15_t)0x4121, (q15_t)0xc003, (q15_t)0x4114, (q15_t)0xc002, (q15_t)0x4108, (q15_t)0xc002, + (q15_t)0x40fb, (q15_t)0xc002, (q15_t)0x40ef, (q15_t)0xc002, (q15_t)0x40e2, (q15_t)0xc002, (q15_t)0x40d6, (q15_t)0xc001, + (q15_t)0x40c9, (q15_t)0xc001, (q15_t)0x40bc, (q15_t)0xc001, (q15_t)0x40b0, (q15_t)0xc001, (q15_t)0x40a3, (q15_t)0xc001, + (q15_t)0x4097, (q15_t)0xc001, (q15_t)0x408a, (q15_t)0xc001, (q15_t)0x407e, (q15_t)0xc000, (q15_t)0x4071, (q15_t)0xc000, + (q15_t)0x4065, (q15_t)0xc000, (q15_t)0x4058, (q15_t)0xc000, (q15_t)0x404b, (q15_t)0xc000, (q15_t)0x403f, (q15_t)0xc000, + (q15_t)0x4032, (q15_t)0xc000, (q15_t)0x4026, (q15_t)0xc000, (q15_t)0x4019, (q15_t)0xc000, (q15_t)0x400d, (q15_t)0xc000, +}; + +/** + @} end of RealFFT_Table group + */ + +/** + @addtogroup RealFFT + @{ + */ + +/** + @brief Initialization function for the Q15 RFFT/RIFFT. + @param[in,out] S points to an instance of the Q15 RFFT/RIFFT structure + @param[in] fftLenReal length of the FFT + @param[in] ifftFlagR flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : fftLenReal is not a supported length + + @par Details + The parameter fftLenReal specifies length of RFFT/RIFFT Process. + Supported FFT Lengths are 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192. + @par + The parameter ifftFlagR controls whether a forward or inverse transform is computed. + Set(=1) ifftFlagR to calculate RIFFT, otherwise RFFT is calculated. + @par + The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. + Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. + @par + This function also initializes Twiddle factor table. + */ + +arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag) +{ + /* Initialise the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + + /* Initialize the Real FFT length */ + S->fftLenReal = (uint16_t) fftLenReal; + + /* Initialize the Twiddle coefficientA pointer */ + S->pTwiddleAReal = (q15_t *) realCoefAQ15; + + /* Initialize the Twiddle coefficientB pointer */ + S->pTwiddleBReal = (q15_t *) realCoefBQ15; + + /* Initialize the Flag for selection of RFFT or RIFFT */ + S->ifftFlagR = (uint8_t) ifftFlagR; + + /* Initialize the Flag for calculation Bit reversal or not */ + S->bitReverseFlagR = (uint8_t) bitReverseFlag; + + /* Initialization of coef modifier depending on the FFT length */ + switch (S->fftLenReal) + { + case 8192U: + S->twidCoefRModifier = 1U; + S->pCfft = &arm_cfft_sR_q15_len4096; + break; + case 4096U: + S->twidCoefRModifier = 2U; + S->pCfft = &arm_cfft_sR_q15_len2048; + break; + case 2048U: + S->twidCoefRModifier = 4U; + S->pCfft = &arm_cfft_sR_q15_len1024; + break; + case 1024U: + S->twidCoefRModifier = 8U; + S->pCfft = &arm_cfft_sR_q15_len512; + break; + case 512U: + S->twidCoefRModifier = 16U; + S->pCfft = &arm_cfft_sR_q15_len256; + break; + case 256U: + S->twidCoefRModifier = 32U; + S->pCfft = &arm_cfft_sR_q15_len128; + break; + case 128U: + S->twidCoefRModifier = 64U; + S->pCfft = &arm_cfft_sR_q15_len64; + break; + case 64U: + S->twidCoefRModifier = 128U; + S->pCfft = &arm_cfft_sR_q15_len32; + break; + case 32U: + S->twidCoefRModifier = 256U; + S->pCfft = &arm_cfft_sR_q15_len16; + break; + default: + /* Reporting argument error if rfftSize is not valid value */ + status = ARM_MATH_ARGUMENT_ERROR; + break; + } + + /* return the status of RFFT Init function */ + return (status); +} + +/** + @} end of RealFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_q31.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_q31.c new file mode 100644 index 0000000..34cb63d --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_init_q31.c @@ -0,0 +1,4285 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_rfft_init_q31.c + * Description: RFFT & RIFFT Q31 initialisation function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" +#include "arm_common_tables.h" +#include "arm_const_structs.h" + +/** + @ingroup RealFFT + */ + +/** + @addtogroup RealFFT_Table Real FFT Tables + @{ + */ + +/** + @par + Generation fixed-point realCoefAQ31 array in Q31 format: + @par + n = 4096 +
for (i = 0; i < n; i++)
+  {
+     pATable[2 * i]     = 0.5 * ( 1.0 - sin (2 * PI / (double) (2 * n) * (double) i));
+     pATable[2 * i + 1] = 0.5 * (-1.0 * cos (2 * PI / (double) (2 * n) * (double) i));
+  }
+ @par + Convert to fixed point Q31 format + round(pATable[i] * pow(2, 31)) +*/ +const q31_t realCoefAQ31[8192] = { + (q31_t)0x40000000, (q31_t)0xc0000000, (q31_t)0x3ff36f02, (q31_t)0xc000013c, + (q31_t)0x3fe6de05, (q31_t)0xc00004ef, (q31_t)0x3fda4d09, (q31_t)0xc0000b1a, + (q31_t)0x3fcdbc0f, (q31_t)0xc00013bd, (q31_t)0x3fc12b16, (q31_t)0xc0001ed8, + (q31_t)0x3fb49a1f, (q31_t)0xc0002c6a, (q31_t)0x3fa8092c, (q31_t)0xc0003c74, + (q31_t)0x3f9b783c, (q31_t)0xc0004ef5, (q31_t)0x3f8ee750, (q31_t)0xc00063ee, + (q31_t)0x3f825668, (q31_t)0xc0007b5f, (q31_t)0x3f75c585, (q31_t)0xc0009547, + (q31_t)0x3f6934a8, (q31_t)0xc000b1a7, (q31_t)0x3f5ca3d0, (q31_t)0xc000d07e, + (q31_t)0x3f5012fe, (q31_t)0xc000f1ce, (q31_t)0x3f438234, (q31_t)0xc0011594, + (q31_t)0x3f36f170, (q31_t)0xc0013bd3, (q31_t)0x3f2a60b4, (q31_t)0xc0016489, + (q31_t)0x3f1dd001, (q31_t)0xc0018fb6, (q31_t)0x3f113f56, (q31_t)0xc001bd5c, + (q31_t)0x3f04aeb5, (q31_t)0xc001ed78, (q31_t)0x3ef81e1d, (q31_t)0xc002200d, + (q31_t)0x3eeb8d8f, (q31_t)0xc0025519, (q31_t)0x3edefd0c, (q31_t)0xc0028c9c, + (q31_t)0x3ed26c94, (q31_t)0xc002c697, (q31_t)0x3ec5dc28, (q31_t)0xc003030a, + (q31_t)0x3eb94bc8, (q31_t)0xc00341f4, (q31_t)0x3eacbb74, (q31_t)0xc0038356, + (q31_t)0x3ea02b2e, (q31_t)0xc003c72f, (q31_t)0x3e939af5, (q31_t)0xc0040d80, + (q31_t)0x3e870aca, (q31_t)0xc0045648, (q31_t)0x3e7a7aae, (q31_t)0xc004a188, + (q31_t)0x3e6deaa1, (q31_t)0xc004ef3f, (q31_t)0x3e615aa3, (q31_t)0xc0053f6e, + (q31_t)0x3e54cab5, (q31_t)0xc0059214, (q31_t)0x3e483ad8, (q31_t)0xc005e731, + (q31_t)0x3e3bab0b, (q31_t)0xc0063ec6, (q31_t)0x3e2f1b50, (q31_t)0xc00698d3, + (q31_t)0x3e228ba7, (q31_t)0xc006f556, (q31_t)0x3e15fc11, (q31_t)0xc0075452, + (q31_t)0x3e096c8d, (q31_t)0xc007b5c4, (q31_t)0x3dfcdd1d, (q31_t)0xc00819ae, + (q31_t)0x3df04dc0, (q31_t)0xc008800f, (q31_t)0x3de3be78, (q31_t)0xc008e8e8, + (q31_t)0x3dd72f45, (q31_t)0xc0095438, (q31_t)0x3dcaa027, (q31_t)0xc009c1ff, + (q31_t)0x3dbe111e, (q31_t)0xc00a323d, (q31_t)0x3db1822c, (q31_t)0xc00aa4f3, + (q31_t)0x3da4f351, (q31_t)0xc00b1a20, (q31_t)0x3d98648d, (q31_t)0xc00b91c4, + (q31_t)0x3d8bd5e1, (q31_t)0xc00c0be0, (q31_t)0x3d7f474d, (q31_t)0xc00c8872, + (q31_t)0x3d72b8d2, (q31_t)0xc00d077c, (q31_t)0x3d662a70, (q31_t)0xc00d88fd, + (q31_t)0x3d599c28, (q31_t)0xc00e0cf5, (q31_t)0x3d4d0df9, (q31_t)0xc00e9364, + (q31_t)0x3d407fe6, (q31_t)0xc00f1c4a, (q31_t)0x3d33f1ed, (q31_t)0xc00fa7a8, + (q31_t)0x3d276410, (q31_t)0xc010357c, (q31_t)0x3d1ad650, (q31_t)0xc010c5c7, + (q31_t)0x3d0e48ab, (q31_t)0xc011588a, (q31_t)0x3d01bb24, (q31_t)0xc011edc3, + (q31_t)0x3cf52dbb, (q31_t)0xc0128574, (q31_t)0x3ce8a06f, (q31_t)0xc0131f9b, + (q31_t)0x3cdc1342, (q31_t)0xc013bc39, (q31_t)0x3ccf8634, (q31_t)0xc0145b4e, + (q31_t)0x3cc2f945, (q31_t)0xc014fcda, (q31_t)0x3cb66c77, (q31_t)0xc015a0dd, + (q31_t)0x3ca9dfc8, (q31_t)0xc0164757, (q31_t)0x3c9d533b, (q31_t)0xc016f047, + (q31_t)0x3c90c6cf, (q31_t)0xc0179bae, (q31_t)0x3c843a85, (q31_t)0xc018498c, + (q31_t)0x3c77ae5e, (q31_t)0xc018f9e1, (q31_t)0x3c6b2259, (q31_t)0xc019acac, + (q31_t)0x3c5e9678, (q31_t)0xc01a61ee, (q31_t)0x3c520aba, (q31_t)0xc01b19a7, + (q31_t)0x3c457f21, (q31_t)0xc01bd3d6, (q31_t)0x3c38f3ac, (q31_t)0xc01c907c, + (q31_t)0x3c2c685d, (q31_t)0xc01d4f99, (q31_t)0x3c1fdd34, (q31_t)0xc01e112b, + (q31_t)0x3c135231, (q31_t)0xc01ed535, (q31_t)0x3c06c754, (q31_t)0xc01f9bb5, + (q31_t)0x3bfa3c9f, (q31_t)0xc02064ab, (q31_t)0x3bedb212, (q31_t)0xc0213018, + (q31_t)0x3be127ac, (q31_t)0xc021fdfb, (q31_t)0x3bd49d70, (q31_t)0xc022ce54, + (q31_t)0x3bc8135c, (q31_t)0xc023a124, (q31_t)0x3bbb8973, (q31_t)0xc024766a, + (q31_t)0x3baeffb3, (q31_t)0xc0254e27, (q31_t)0x3ba2761e, (q31_t)0xc0262859, + (q31_t)0x3b95ecb4, (q31_t)0xc0270502, (q31_t)0x3b896375, (q31_t)0xc027e421, + (q31_t)0x3b7cda63, (q31_t)0xc028c5b6, (q31_t)0x3b70517d, (q31_t)0xc029a9c1, + (q31_t)0x3b63c8c4, (q31_t)0xc02a9042, (q31_t)0x3b574039, (q31_t)0xc02b7939, + (q31_t)0x3b4ab7db, (q31_t)0xc02c64a6, (q31_t)0x3b3e2fac, (q31_t)0xc02d5289, + (q31_t)0x3b31a7ac, (q31_t)0xc02e42e2, (q31_t)0x3b251fdc, (q31_t)0xc02f35b1, + (q31_t)0x3b18983b, (q31_t)0xc0302af5, (q31_t)0x3b0c10cb, (q31_t)0xc03122b0, + (q31_t)0x3aff898c, (q31_t)0xc0321ce0, (q31_t)0x3af3027e, (q31_t)0xc0331986, + (q31_t)0x3ae67ba2, (q31_t)0xc03418a2, (q31_t)0x3ad9f4f8, (q31_t)0xc0351a33, + (q31_t)0x3acd6e81, (q31_t)0xc0361e3a, (q31_t)0x3ac0e83d, (q31_t)0xc03724b6, + (q31_t)0x3ab4622d, (q31_t)0xc0382da8, (q31_t)0x3aa7dc52, (q31_t)0xc0393910, + (q31_t)0x3a9b56ab, (q31_t)0xc03a46ed, (q31_t)0x3a8ed139, (q31_t)0xc03b573f, + (q31_t)0x3a824bfd, (q31_t)0xc03c6a07, (q31_t)0x3a75c6f8, (q31_t)0xc03d7f44, + (q31_t)0x3a694229, (q31_t)0xc03e96f6, (q31_t)0x3a5cbd91, (q31_t)0xc03fb11d, + (q31_t)0x3a503930, (q31_t)0xc040cdba, (q31_t)0x3a43b508, (q31_t)0xc041eccc, + (q31_t)0x3a373119, (q31_t)0xc0430e53, (q31_t)0x3a2aad62, (q31_t)0xc044324f, + (q31_t)0x3a1e29e5, (q31_t)0xc04558c0, (q31_t)0x3a11a6a3, (q31_t)0xc04681a6, + (q31_t)0x3a05239a, (q31_t)0xc047ad01, (q31_t)0x39f8a0cd, (q31_t)0xc048dad1, + (q31_t)0x39ec1e3b, (q31_t)0xc04a0b16, (q31_t)0x39df9be6, (q31_t)0xc04b3dcf, + (q31_t)0x39d319cc, (q31_t)0xc04c72fe, (q31_t)0x39c697f0, (q31_t)0xc04daaa1, + (q31_t)0x39ba1651, (q31_t)0xc04ee4b8, (q31_t)0x39ad94f0, (q31_t)0xc0502145, + (q31_t)0x39a113cd, (q31_t)0xc0516045, (q31_t)0x399492ea, (q31_t)0xc052a1bb, + (q31_t)0x39881245, (q31_t)0xc053e5a5, (q31_t)0x397b91e1, (q31_t)0xc0552c03, + (q31_t)0x396f11bc, (q31_t)0xc05674d6, (q31_t)0x396291d9, (q31_t)0xc057c01d, + (q31_t)0x39561237, (q31_t)0xc0590dd8, (q31_t)0x394992d7, (q31_t)0xc05a5e07, + (q31_t)0x393d13b8, (q31_t)0xc05bb0ab, (q31_t)0x393094dd, (q31_t)0xc05d05c3, + (q31_t)0x39241645, (q31_t)0xc05e5d4e, (q31_t)0x391797f0, (q31_t)0xc05fb74e, + (q31_t)0x390b19e0, (q31_t)0xc06113c2, (q31_t)0x38fe9c15, (q31_t)0xc06272aa, + (q31_t)0x38f21e8e, (q31_t)0xc063d405, (q31_t)0x38e5a14d, (q31_t)0xc06537d4, + (q31_t)0x38d92452, (q31_t)0xc0669e18, (q31_t)0x38cca79e, (q31_t)0xc06806ce, + (q31_t)0x38c02b31, (q31_t)0xc06971f9, (q31_t)0x38b3af0c, (q31_t)0xc06adf97, + (q31_t)0x38a7332e, (q31_t)0xc06c4fa8, (q31_t)0x389ab799, (q31_t)0xc06dc22e, + (q31_t)0x388e3c4d, (q31_t)0xc06f3726, (q31_t)0x3881c14b, (q31_t)0xc070ae92, + (q31_t)0x38754692, (q31_t)0xc0722871, (q31_t)0x3868cc24, (q31_t)0xc073a4c3, + (q31_t)0x385c5201, (q31_t)0xc0752389, (q31_t)0x384fd829, (q31_t)0xc076a4c2, + (q31_t)0x38435e9d, (q31_t)0xc078286e, (q31_t)0x3836e55d, (q31_t)0xc079ae8c, + (q31_t)0x382a6c6a, (q31_t)0xc07b371e, (q31_t)0x381df3c5, (q31_t)0xc07cc223, + (q31_t)0x38117b6d, (q31_t)0xc07e4f9b, (q31_t)0x38050364, (q31_t)0xc07fdf85, + (q31_t)0x37f88ba9, (q31_t)0xc08171e2, (q31_t)0x37ec143e, (q31_t)0xc08306b2, + (q31_t)0x37df9d22, (q31_t)0xc0849df4, (q31_t)0x37d32657, (q31_t)0xc08637a9, + (q31_t)0x37c6afdc, (q31_t)0xc087d3d0, (q31_t)0x37ba39b3, (q31_t)0xc089726a, + (q31_t)0x37adc3db, (q31_t)0xc08b1376, (q31_t)0x37a14e55, (q31_t)0xc08cb6f5, + (q31_t)0x3794d922, (q31_t)0xc08e5ce5, (q31_t)0x37886442, (q31_t)0xc0900548, + (q31_t)0x377befb5, (q31_t)0xc091b01d, (q31_t)0x376f7b7d, (q31_t)0xc0935d64, + (q31_t)0x37630799, (q31_t)0xc0950d1d, (q31_t)0x3756940a, (q31_t)0xc096bf48, + (q31_t)0x374a20d0, (q31_t)0xc09873e4, (q31_t)0x373daded, (q31_t)0xc09a2af3, + (q31_t)0x37313b60, (q31_t)0xc09be473, (q31_t)0x3724c92a, (q31_t)0xc09da065, + (q31_t)0x3718574b, (q31_t)0xc09f5ec8, (q31_t)0x370be5c4, (q31_t)0xc0a11f9d, + (q31_t)0x36ff7496, (q31_t)0xc0a2e2e3, (q31_t)0x36f303c0, (q31_t)0xc0a4a89b, + (q31_t)0x36e69344, (q31_t)0xc0a670c4, (q31_t)0x36da2321, (q31_t)0xc0a83b5e, + (q31_t)0x36cdb359, (q31_t)0xc0aa086a, (q31_t)0x36c143ec, (q31_t)0xc0abd7e6, + (q31_t)0x36b4d4d9, (q31_t)0xc0ada9d4, (q31_t)0x36a86623, (q31_t)0xc0af7e33, + (q31_t)0x369bf7c9, (q31_t)0xc0b15502, (q31_t)0x368f89cb, (q31_t)0xc0b32e42, + (q31_t)0x36831c2b, (q31_t)0xc0b509f3, (q31_t)0x3676aee8, (q31_t)0xc0b6e815, + (q31_t)0x366a4203, (q31_t)0xc0b8c8a7, (q31_t)0x365dd57d, (q31_t)0xc0baabaa, + (q31_t)0x36516956, (q31_t)0xc0bc911d, (q31_t)0x3644fd8f, (q31_t)0xc0be7901, + (q31_t)0x36389228, (q31_t)0xc0c06355, (q31_t)0x362c2721, (q31_t)0xc0c25019, + (q31_t)0x361fbc7b, (q31_t)0xc0c43f4d, (q31_t)0x36135237, (q31_t)0xc0c630f2, + (q31_t)0x3606e854, (q31_t)0xc0c82506, (q31_t)0x35fa7ed4, (q31_t)0xc0ca1b8a, + (q31_t)0x35ee15b7, (q31_t)0xc0cc147f, (q31_t)0x35e1acfd, (q31_t)0xc0ce0fe3, + (q31_t)0x35d544a7, (q31_t)0xc0d00db6, (q31_t)0x35c8dcb6, (q31_t)0xc0d20dfa, + (q31_t)0x35bc7529, (q31_t)0xc0d410ad, (q31_t)0x35b00e02, (q31_t)0xc0d615cf, + (q31_t)0x35a3a740, (q31_t)0xc0d81d61, (q31_t)0x359740e5, (q31_t)0xc0da2762, + (q31_t)0x358adaf0, (q31_t)0xc0dc33d2, (q31_t)0x357e7563, (q31_t)0xc0de42b2, + (q31_t)0x3572103d, (q31_t)0xc0e05401, (q31_t)0x3565ab80, (q31_t)0xc0e267be, + (q31_t)0x3559472b, (q31_t)0xc0e47deb, (q31_t)0x354ce33f, (q31_t)0xc0e69686, + (q31_t)0x35407fbd, (q31_t)0xc0e8b190, (q31_t)0x35341ca5, (q31_t)0xc0eacf09, + (q31_t)0x3527b9f7, (q31_t)0xc0eceef1, (q31_t)0x351b57b5, (q31_t)0xc0ef1147, + (q31_t)0x350ef5de, (q31_t)0xc0f1360b, (q31_t)0x35029473, (q31_t)0xc0f35d3e, + (q31_t)0x34f63374, (q31_t)0xc0f586df, (q31_t)0x34e9d2e3, (q31_t)0xc0f7b2ee, + (q31_t)0x34dd72be, (q31_t)0xc0f9e16b, (q31_t)0x34d11308, (q31_t)0xc0fc1257, + (q31_t)0x34c4b3c0, (q31_t)0xc0fe45b0, (q31_t)0x34b854e7, (q31_t)0xc1007b77, + (q31_t)0x34abf67e, (q31_t)0xc102b3ac, (q31_t)0x349f9884, (q31_t)0xc104ee4f, + (q31_t)0x34933afa, (q31_t)0xc1072b5f, (q31_t)0x3486dde1, (q31_t)0xc1096add, + (q31_t)0x347a8139, (q31_t)0xc10bacc8, (q31_t)0x346e2504, (q31_t)0xc10df120, + (q31_t)0x3461c940, (q31_t)0xc11037e6, (q31_t)0x34556def, (q31_t)0xc1128119, + (q31_t)0x34491311, (q31_t)0xc114ccb9, (q31_t)0x343cb8a7, (q31_t)0xc1171ac6, + (q31_t)0x34305eb0, (q31_t)0xc1196b3f, (q31_t)0x3424052f, (q31_t)0xc11bbe26, + (q31_t)0x3417ac22, (q31_t)0xc11e1379, (q31_t)0x340b538b, (q31_t)0xc1206b39, + (q31_t)0x33fefb6a, (q31_t)0xc122c566, (q31_t)0x33f2a3bf, (q31_t)0xc12521ff, + (q31_t)0x33e64c8c, (q31_t)0xc1278104, (q31_t)0x33d9f5cf, (q31_t)0xc129e276, + (q31_t)0x33cd9f8b, (q31_t)0xc12c4653, (q31_t)0x33c149bf, (q31_t)0xc12eac9d, + (q31_t)0x33b4f46c, (q31_t)0xc1311553, (q31_t)0x33a89f92, (q31_t)0xc1338075, + (q31_t)0x339c4b32, (q31_t)0xc135ee02, (q31_t)0x338ff74d, (q31_t)0xc1385dfb, + (q31_t)0x3383a3e2, (q31_t)0xc13ad060, (q31_t)0x337750f2, (q31_t)0xc13d4530, + (q31_t)0x336afe7e, (q31_t)0xc13fbc6c, (q31_t)0x335eac86, (q31_t)0xc1423613, + (q31_t)0x33525b0b, (q31_t)0xc144b225, (q31_t)0x33460a0d, (q31_t)0xc14730a3, + (q31_t)0x3339b98d, (q31_t)0xc149b18b, (q31_t)0x332d698a, (q31_t)0xc14c34df, + (q31_t)0x33211a07, (q31_t)0xc14eba9d, (q31_t)0x3314cb02, (q31_t)0xc15142c6, + (q31_t)0x33087c7d, (q31_t)0xc153cd5a, (q31_t)0x32fc2e77, (q31_t)0xc1565a58, + (q31_t)0x32efe0f2, (q31_t)0xc158e9c1, (q31_t)0x32e393ef, (q31_t)0xc15b7b94, + (q31_t)0x32d7476c, (q31_t)0xc15e0fd1, (q31_t)0x32cafb6b, (q31_t)0xc160a678, + (q31_t)0x32beafed, (q31_t)0xc1633f8a, (q31_t)0x32b264f2, (q31_t)0xc165db05, + (q31_t)0x32a61a7a, (q31_t)0xc16878eb, (q31_t)0x3299d085, (q31_t)0xc16b193a, + (q31_t)0x328d8715, (q31_t)0xc16dbbf3, (q31_t)0x32813e2a, (q31_t)0xc1706115, + (q31_t)0x3274f5c3, (q31_t)0xc17308a1, (q31_t)0x3268ade3, (q31_t)0xc175b296, + (q31_t)0x325c6688, (q31_t)0xc1785ef4, (q31_t)0x32501fb5, (q31_t)0xc17b0dbb, + (q31_t)0x3243d968, (q31_t)0xc17dbeec, (q31_t)0x323793a3, (q31_t)0xc1807285, + (q31_t)0x322b4e66, (q31_t)0xc1832888, (q31_t)0x321f09b1, (q31_t)0xc185e0f3, + (q31_t)0x3212c585, (q31_t)0xc1889bc6, (q31_t)0x320681e3, (q31_t)0xc18b5903, + (q31_t)0x31fa3ecb, (q31_t)0xc18e18a7, (q31_t)0x31edfc3d, (q31_t)0xc190dab4, + (q31_t)0x31e1ba3a, (q31_t)0xc1939f29, (q31_t)0x31d578c2, (q31_t)0xc1966606, + (q31_t)0x31c937d6, (q31_t)0xc1992f4c, (q31_t)0x31bcf777, (q31_t)0xc19bfaf9, + (q31_t)0x31b0b7a4, (q31_t)0xc19ec90d, (q31_t)0x31a4785e, (q31_t)0xc1a1998a, + (q31_t)0x319839a6, (q31_t)0xc1a46c6e, (q31_t)0x318bfb7d, (q31_t)0xc1a741b9, + (q31_t)0x317fbde2, (q31_t)0xc1aa196c, (q31_t)0x317380d6, (q31_t)0xc1acf386, + (q31_t)0x31674459, (q31_t)0xc1afd007, (q31_t)0x315b086d, (q31_t)0xc1b2aef0, + (q31_t)0x314ecd11, (q31_t)0xc1b5903f, (q31_t)0x31429247, (q31_t)0xc1b873f5, + (q31_t)0x3136580d, (q31_t)0xc1bb5a11, (q31_t)0x312a1e66, (q31_t)0xc1be4294, + (q31_t)0x311de551, (q31_t)0xc1c12d7e, (q31_t)0x3111accf, (q31_t)0xc1c41ace, + (q31_t)0x310574e0, (q31_t)0xc1c70a84, (q31_t)0x30f93d86, (q31_t)0xc1c9fca0, + (q31_t)0x30ed06bf, (q31_t)0xc1ccf122, (q31_t)0x30e0d08d, (q31_t)0xc1cfe80a, + (q31_t)0x30d49af1, (q31_t)0xc1d2e158, (q31_t)0x30c865ea, (q31_t)0xc1d5dd0c, + (q31_t)0x30bc317a, (q31_t)0xc1d8db25, (q31_t)0x30affda0, (q31_t)0xc1dbdba3, + (q31_t)0x30a3ca5d, (q31_t)0xc1dede87, (q31_t)0x309797b2, (q31_t)0xc1e1e3d0, + (q31_t)0x308b659f, (q31_t)0xc1e4eb7e, (q31_t)0x307f3424, (q31_t)0xc1e7f591, + (q31_t)0x30730342, (q31_t)0xc1eb0209, (q31_t)0x3066d2fa, (q31_t)0xc1ee10e5, + (q31_t)0x305aa34c, (q31_t)0xc1f12227, (q31_t)0x304e7438, (q31_t)0xc1f435cc, + (q31_t)0x304245c0, (q31_t)0xc1f74bd6, (q31_t)0x303617e2, (q31_t)0xc1fa6445, + (q31_t)0x3029eaa1, (q31_t)0xc1fd7f17, (q31_t)0x301dbdfb, (q31_t)0xc2009c4e, + (q31_t)0x301191f3, (q31_t)0xc203bbe8, (q31_t)0x30056687, (q31_t)0xc206dde6, + (q31_t)0x2ff93bba, (q31_t)0xc20a0248, (q31_t)0x2fed118a, (q31_t)0xc20d290d, + (q31_t)0x2fe0e7f9, (q31_t)0xc2105236, (q31_t)0x2fd4bf08, (q31_t)0xc2137dc2, + (q31_t)0x2fc896b5, (q31_t)0xc216abb1, (q31_t)0x2fbc6f03, (q31_t)0xc219dc03, + (q31_t)0x2fb047f2, (q31_t)0xc21d0eb8, (q31_t)0x2fa42181, (q31_t)0xc22043d0, + (q31_t)0x2f97fbb2, (q31_t)0xc2237b4b, (q31_t)0x2f8bd685, (q31_t)0xc226b528, + (q31_t)0x2f7fb1fa, (q31_t)0xc229f167, (q31_t)0x2f738e12, (q31_t)0xc22d3009, + (q31_t)0x2f676ace, (q31_t)0xc230710d, (q31_t)0x2f5b482d, (q31_t)0xc233b473, + (q31_t)0x2f4f2630, (q31_t)0xc236fa3b, (q31_t)0x2f4304d8, (q31_t)0xc23a4265, + (q31_t)0x2f36e426, (q31_t)0xc23d8cf1, (q31_t)0x2f2ac419, (q31_t)0xc240d9de, + (q31_t)0x2f1ea4b2, (q31_t)0xc244292c, (q31_t)0x2f1285f2, (q31_t)0xc2477adc, + (q31_t)0x2f0667d9, (q31_t)0xc24aceed, (q31_t)0x2efa4a67, (q31_t)0xc24e255e, + (q31_t)0x2eee2d9d, (q31_t)0xc2517e31, (q31_t)0x2ee2117c, (q31_t)0xc254d965, + (q31_t)0x2ed5f604, (q31_t)0xc25836f9, (q31_t)0x2ec9db35, (q31_t)0xc25b96ee, + (q31_t)0x2ebdc110, (q31_t)0xc25ef943, (q31_t)0x2eb1a796, (q31_t)0xc2625df8, + (q31_t)0x2ea58ec6, (q31_t)0xc265c50e, (q31_t)0x2e9976a1, (q31_t)0xc2692e83, + (q31_t)0x2e8d5f29, (q31_t)0xc26c9a58, (q31_t)0x2e81485c, (q31_t)0xc270088e, + (q31_t)0x2e75323c, (q31_t)0xc2737922, (q31_t)0x2e691cc9, (q31_t)0xc276ec16, + (q31_t)0x2e5d0804, (q31_t)0xc27a616a, (q31_t)0x2e50f3ed, (q31_t)0xc27dd91c, + (q31_t)0x2e44e084, (q31_t)0xc281532e, (q31_t)0x2e38cdcb, (q31_t)0xc284cf9f, + (q31_t)0x2e2cbbc1, (q31_t)0xc2884e6e, (q31_t)0x2e20aa67, (q31_t)0xc28bcf9c, + (q31_t)0x2e1499bd, (q31_t)0xc28f5329, (q31_t)0x2e0889c4, (q31_t)0xc292d914, + (q31_t)0x2dfc7a7c, (q31_t)0xc296615d, (q31_t)0x2df06be6, (q31_t)0xc299ec05, + (q31_t)0x2de45e03, (q31_t)0xc29d790a, (q31_t)0x2dd850d2, (q31_t)0xc2a1086d, + (q31_t)0x2dcc4454, (q31_t)0xc2a49a2e, (q31_t)0x2dc0388a, (q31_t)0xc2a82e4d, + (q31_t)0x2db42d74, (q31_t)0xc2abc4c9, (q31_t)0x2da82313, (q31_t)0xc2af5da2, + (q31_t)0x2d9c1967, (q31_t)0xc2b2f8d8, (q31_t)0x2d901070, (q31_t)0xc2b6966c, + (q31_t)0x2d84082f, (q31_t)0xc2ba365c, (q31_t)0x2d7800a5, (q31_t)0xc2bdd8a9, + (q31_t)0x2d6bf9d1, (q31_t)0xc2c17d52, (q31_t)0x2d5ff3b5, (q31_t)0xc2c52459, + (q31_t)0x2d53ee51, (q31_t)0xc2c8cdbb, (q31_t)0x2d47e9a5, (q31_t)0xc2cc7979, + (q31_t)0x2d3be5b1, (q31_t)0xc2d02794, (q31_t)0x2d2fe277, (q31_t)0xc2d3d80a, + (q31_t)0x2d23dff7, (q31_t)0xc2d78add, (q31_t)0x2d17de31, (q31_t)0xc2db400a, + (q31_t)0x2d0bdd25, (q31_t)0xc2def794, (q31_t)0x2cffdcd4, (q31_t)0xc2e2b178, + (q31_t)0x2cf3dd3f, (q31_t)0xc2e66db8, (q31_t)0x2ce7de66, (q31_t)0xc2ea2c53, + (q31_t)0x2cdbe04a, (q31_t)0xc2eded49, (q31_t)0x2ccfe2ea, (q31_t)0xc2f1b099, + (q31_t)0x2cc3e648, (q31_t)0xc2f57644, (q31_t)0x2cb7ea63, (q31_t)0xc2f93e4a, + (q31_t)0x2cabef3d, (q31_t)0xc2fd08a9, (q31_t)0x2c9ff4d6, (q31_t)0xc300d563, + (q31_t)0x2c93fb2e, (q31_t)0xc304a477, (q31_t)0x2c880245, (q31_t)0xc30875e5, + (q31_t)0x2c7c0a1d, (q31_t)0xc30c49ad, (q31_t)0x2c7012b5, (q31_t)0xc3101fce, + (q31_t)0x2c641c0e, (q31_t)0xc313f848, (q31_t)0x2c582629, (q31_t)0xc317d31c, + (q31_t)0x2c4c3106, (q31_t)0xc31bb049, (q31_t)0x2c403ca5, (q31_t)0xc31f8fcf, + (q31_t)0x2c344908, (q31_t)0xc32371ae, (q31_t)0x2c28562d, (q31_t)0xc32755e5, + (q31_t)0x2c1c6417, (q31_t)0xc32b3c75, (q31_t)0x2c1072c4, (q31_t)0xc32f255e, + (q31_t)0x2c048237, (q31_t)0xc333109e, (q31_t)0x2bf8926f, (q31_t)0xc336fe37, + (q31_t)0x2beca36c, (q31_t)0xc33aee27, (q31_t)0x2be0b52f, (q31_t)0xc33ee070, + (q31_t)0x2bd4c7ba, (q31_t)0xc342d510, (q31_t)0x2bc8db0b, (q31_t)0xc346cc07, + (q31_t)0x2bbcef23, (q31_t)0xc34ac556, (q31_t)0x2bb10404, (q31_t)0xc34ec0fc, + (q31_t)0x2ba519ad, (q31_t)0xc352bef9, (q31_t)0x2b99301f, (q31_t)0xc356bf4d, + (q31_t)0x2b8d475b, (q31_t)0xc35ac1f7, (q31_t)0x2b815f60, (q31_t)0xc35ec6f8, + (q31_t)0x2b75782f, (q31_t)0xc362ce50, (q31_t)0x2b6991ca, (q31_t)0xc366d7fd, + (q31_t)0x2b5dac2f, (q31_t)0xc36ae401, (q31_t)0x2b51c760, (q31_t)0xc36ef25b, + (q31_t)0x2b45e35d, (q31_t)0xc373030a, (q31_t)0x2b3a0027, (q31_t)0xc377160f, + (q31_t)0x2b2e1dbe, (q31_t)0xc37b2b6a, (q31_t)0x2b223c22, (q31_t)0xc37f4319, + (q31_t)0x2b165b54, (q31_t)0xc3835d1e, (q31_t)0x2b0a7b54, (q31_t)0xc3877978, + (q31_t)0x2afe9c24, (q31_t)0xc38b9827, (q31_t)0x2af2bdc3, (q31_t)0xc38fb92a, + (q31_t)0x2ae6e031, (q31_t)0xc393dc82, (q31_t)0x2adb0370, (q31_t)0xc398022f, + (q31_t)0x2acf277f, (q31_t)0xc39c2a2f, (q31_t)0x2ac34c60, (q31_t)0xc3a05484, + (q31_t)0x2ab77212, (q31_t)0xc3a4812c, (q31_t)0x2aab9896, (q31_t)0xc3a8b028, + (q31_t)0x2a9fbfed, (q31_t)0xc3ace178, (q31_t)0x2a93e817, (q31_t)0xc3b1151b, + (q31_t)0x2a881114, (q31_t)0xc3b54b11, (q31_t)0x2a7c3ae5, (q31_t)0xc3b9835a, + (q31_t)0x2a70658a, (q31_t)0xc3bdbdf6, (q31_t)0x2a649105, (q31_t)0xc3c1fae5, + (q31_t)0x2a58bd54, (q31_t)0xc3c63a26, (q31_t)0x2a4cea79, (q31_t)0xc3ca7bba, + (q31_t)0x2a411874, (q31_t)0xc3cebfa0, (q31_t)0x2a354746, (q31_t)0xc3d305d8, + (q31_t)0x2a2976ef, (q31_t)0xc3d74e62, (q31_t)0x2a1da770, (q31_t)0xc3db993e, + (q31_t)0x2a11d8c8, (q31_t)0xc3dfe66c, (q31_t)0x2a060af9, (q31_t)0xc3e435ea, + (q31_t)0x29fa3e03, (q31_t)0xc3e887bb, (q31_t)0x29ee71e6, (q31_t)0xc3ecdbdc, + (q31_t)0x29e2a6a3, (q31_t)0xc3f1324e, (q31_t)0x29d6dc3b, (q31_t)0xc3f58b10, + (q31_t)0x29cb12ad, (q31_t)0xc3f9e624, (q31_t)0x29bf49fa, (q31_t)0xc3fe4388, + (q31_t)0x29b38223, (q31_t)0xc402a33c, (q31_t)0x29a7bb28, (q31_t)0xc4070540, + (q31_t)0x299bf509, (q31_t)0xc40b6994, (q31_t)0x29902fc7, (q31_t)0xc40fd037, + (q31_t)0x29846b63, (q31_t)0xc414392b, (q31_t)0x2978a7dd, (q31_t)0xc418a46d, + (q31_t)0x296ce535, (q31_t)0xc41d11ff, (q31_t)0x2961236c, (q31_t)0xc42181e0, + (q31_t)0x29556282, (q31_t)0xc425f410, (q31_t)0x2949a278, (q31_t)0xc42a688f, + (q31_t)0x293de34e, (q31_t)0xc42edf5c, (q31_t)0x29322505, (q31_t)0xc4335877, + (q31_t)0x2926679c, (q31_t)0xc437d3e1, (q31_t)0x291aab16, (q31_t)0xc43c5199, + (q31_t)0x290eef71, (q31_t)0xc440d19e, (q31_t)0x290334af, (q31_t)0xc44553f2, + (q31_t)0x28f77acf, (q31_t)0xc449d892, (q31_t)0x28ebc1d3, (q31_t)0xc44e5f80, + (q31_t)0x28e009ba, (q31_t)0xc452e8bc, (q31_t)0x28d45286, (q31_t)0xc4577444, + (q31_t)0x28c89c37, (q31_t)0xc45c0219, (q31_t)0x28bce6cd, (q31_t)0xc460923b, + (q31_t)0x28b13248, (q31_t)0xc46524a9, (q31_t)0x28a57ea9, (q31_t)0xc469b963, + (q31_t)0x2899cbf1, (q31_t)0xc46e5069, (q31_t)0x288e1a20, (q31_t)0xc472e9bc, + (q31_t)0x28826936, (q31_t)0xc477855a, (q31_t)0x2876b934, (q31_t)0xc47c2344, + (q31_t)0x286b0a1a, (q31_t)0xc480c379, (q31_t)0x285f5be9, (q31_t)0xc48565f9, + (q31_t)0x2853aea1, (q31_t)0xc48a0ac4, (q31_t)0x28480243, (q31_t)0xc48eb1db, + (q31_t)0x283c56cf, (q31_t)0xc4935b3c, (q31_t)0x2830ac45, (q31_t)0xc49806e7, + (q31_t)0x282502a7, (q31_t)0xc49cb4dd, (q31_t)0x281959f4, (q31_t)0xc4a1651c, + (q31_t)0x280db22d, (q31_t)0xc4a617a6, (q31_t)0x28020b52, (q31_t)0xc4aacc7a, + (q31_t)0x27f66564, (q31_t)0xc4af8397, (q31_t)0x27eac063, (q31_t)0xc4b43cfd, + (q31_t)0x27df1c50, (q31_t)0xc4b8f8ad, (q31_t)0x27d3792b, (q31_t)0xc4bdb6a6, + (q31_t)0x27c7d6f4, (q31_t)0xc4c276e8, (q31_t)0x27bc35ad, (q31_t)0xc4c73972, + (q31_t)0x27b09555, (q31_t)0xc4cbfe45, (q31_t)0x27a4f5ed, (q31_t)0xc4d0c560, + (q31_t)0x27995776, (q31_t)0xc4d58ec3, (q31_t)0x278db9ef, (q31_t)0xc4da5a6f, + (q31_t)0x27821d59, (q31_t)0xc4df2862, (q31_t)0x277681b6, (q31_t)0xc4e3f89c, + (q31_t)0x276ae704, (q31_t)0xc4e8cb1e, (q31_t)0x275f4d45, (q31_t)0xc4ed9fe7, + (q31_t)0x2753b479, (q31_t)0xc4f276f7, (q31_t)0x27481ca1, (q31_t)0xc4f7504e, + (q31_t)0x273c85bc, (q31_t)0xc4fc2bec, (q31_t)0x2730efcc, (q31_t)0xc50109d0, + (q31_t)0x27255ad1, (q31_t)0xc505e9fb, (q31_t)0x2719c6cb, (q31_t)0xc50acc6b, + (q31_t)0x270e33bb, (q31_t)0xc50fb121, (q31_t)0x2702a1a1, (q31_t)0xc514981d, + (q31_t)0x26f7107e, (q31_t)0xc519815f, (q31_t)0x26eb8052, (q31_t)0xc51e6ce6, + (q31_t)0x26dff11d, (q31_t)0xc5235ab2, (q31_t)0x26d462e1, (q31_t)0xc5284ac3, + (q31_t)0x26c8d59c, (q31_t)0xc52d3d18, (q31_t)0x26bd4951, (q31_t)0xc53231b3, + (q31_t)0x26b1bdff, (q31_t)0xc5372891, (q31_t)0x26a633a6, (q31_t)0xc53c21b4, + (q31_t)0x269aaa48, (q31_t)0xc5411d1b, (q31_t)0x268f21e5, (q31_t)0xc5461ac6, + (q31_t)0x26839a7c, (q31_t)0xc54b1ab4, (q31_t)0x26781410, (q31_t)0xc5501ce5, + (q31_t)0x266c8e9f, (q31_t)0xc555215a, (q31_t)0x26610a2a, (q31_t)0xc55a2812, + (q31_t)0x265586b3, (q31_t)0xc55f310d, (q31_t)0x264a0438, (q31_t)0xc5643c4a, + (q31_t)0x263e82bc, (q31_t)0xc56949ca, (q31_t)0x2633023e, (q31_t)0xc56e598c, + (q31_t)0x262782be, (q31_t)0xc5736b90, (q31_t)0x261c043d, (q31_t)0xc5787fd6, + (q31_t)0x261086bc, (q31_t)0xc57d965d, (q31_t)0x26050a3b, (q31_t)0xc582af26, + (q31_t)0x25f98ebb, (q31_t)0xc587ca31, (q31_t)0x25ee143b, (q31_t)0xc58ce77c, + (q31_t)0x25e29abc, (q31_t)0xc5920708, (q31_t)0x25d72240, (q31_t)0xc59728d5, + (q31_t)0x25cbaac5, (q31_t)0xc59c4ce3, (q31_t)0x25c0344d, (q31_t)0xc5a17330, + (q31_t)0x25b4bed8, (q31_t)0xc5a69bbe, (q31_t)0x25a94a67, (q31_t)0xc5abc68c, + (q31_t)0x259dd6f9, (q31_t)0xc5b0f399, (q31_t)0x25926490, (q31_t)0xc5b622e6, + (q31_t)0x2586f32c, (q31_t)0xc5bb5472, (q31_t)0x257b82cd, (q31_t)0xc5c0883d, + (q31_t)0x25701374, (q31_t)0xc5c5be47, (q31_t)0x2564a521, (q31_t)0xc5caf690, + (q31_t)0x255937d5, (q31_t)0xc5d03118, (q31_t)0x254dcb8f, (q31_t)0xc5d56ddd, + (q31_t)0x25426051, (q31_t)0xc5daace1, (q31_t)0x2536f61b, (q31_t)0xc5dfee22, + (q31_t)0x252b8cee, (q31_t)0xc5e531a1, (q31_t)0x252024c9, (q31_t)0xc5ea775e, + (q31_t)0x2514bdad, (q31_t)0xc5efbf58, (q31_t)0x2509579b, (q31_t)0xc5f5098f, + (q31_t)0x24fdf294, (q31_t)0xc5fa5603, (q31_t)0x24f28e96, (q31_t)0xc5ffa4b3, + (q31_t)0x24e72ba4, (q31_t)0xc604f5a0, (q31_t)0x24dbc9bd, (q31_t)0xc60a48c9, + (q31_t)0x24d068e2, (q31_t)0xc60f9e2e, (q31_t)0x24c50914, (q31_t)0xc614f5cf, + (q31_t)0x24b9aa52, (q31_t)0xc61a4fac, (q31_t)0x24ae4c9d, (q31_t)0xc61fabc4, + (q31_t)0x24a2eff6, (q31_t)0xc6250a18, (q31_t)0x2497945d, (q31_t)0xc62a6aa6, + (q31_t)0x248c39d3, (q31_t)0xc62fcd6f, (q31_t)0x2480e057, (q31_t)0xc6353273, + (q31_t)0x247587eb, (q31_t)0xc63a99b1, (q31_t)0x246a308f, (q31_t)0xc6400329, + (q31_t)0x245eda43, (q31_t)0xc6456edb, (q31_t)0x24538507, (q31_t)0xc64adcc7, + (q31_t)0x244830dd, (q31_t)0xc6504ced, (q31_t)0x243cddc4, (q31_t)0xc655bf4c, + (q31_t)0x24318bbe, (q31_t)0xc65b33e4, (q31_t)0x24263ac9, (q31_t)0xc660aab5, + (q31_t)0x241aeae8, (q31_t)0xc66623be, (q31_t)0x240f9c1a, (q31_t)0xc66b9f01, + (q31_t)0x24044e60, (q31_t)0xc6711c7b, (q31_t)0x23f901ba, (q31_t)0xc6769c2e, + (q31_t)0x23edb628, (q31_t)0xc67c1e18, (q31_t)0x23e26bac, (q31_t)0xc681a23a, + (q31_t)0x23d72245, (q31_t)0xc6872894, (q31_t)0x23cbd9f4, (q31_t)0xc68cb124, + (q31_t)0x23c092b9, (q31_t)0xc6923bec, (q31_t)0x23b54c95, (q31_t)0xc697c8eb, + (q31_t)0x23aa0788, (q31_t)0xc69d5820, (q31_t)0x239ec393, (q31_t)0xc6a2e98b, + (q31_t)0x239380b6, (q31_t)0xc6a87d2d, (q31_t)0x23883ef2, (q31_t)0xc6ae1304, + (q31_t)0x237cfe47, (q31_t)0xc6b3ab12, (q31_t)0x2371beb5, (q31_t)0xc6b94554, + (q31_t)0x2366803c, (q31_t)0xc6bee1cd, (q31_t)0x235b42df, (q31_t)0xc6c4807a, + (q31_t)0x2350069b, (q31_t)0xc6ca215c, (q31_t)0x2344cb73, (q31_t)0xc6cfc472, + (q31_t)0x23399167, (q31_t)0xc6d569be, (q31_t)0x232e5876, (q31_t)0xc6db113d, + (q31_t)0x232320a2, (q31_t)0xc6e0baf0, (q31_t)0x2317e9eb, (q31_t)0xc6e666d7, + (q31_t)0x230cb451, (q31_t)0xc6ec14f2, (q31_t)0x23017fd5, (q31_t)0xc6f1c540, + (q31_t)0x22f64c77, (q31_t)0xc6f777c1, (q31_t)0x22eb1a37, (q31_t)0xc6fd2c75, + (q31_t)0x22dfe917, (q31_t)0xc702e35c, (q31_t)0x22d4b916, (q31_t)0xc7089c75, + (q31_t)0x22c98a35, (q31_t)0xc70e57c0, (q31_t)0x22be5c74, (q31_t)0xc714153e, + (q31_t)0x22b32fd4, (q31_t)0xc719d4ed, (q31_t)0x22a80456, (q31_t)0xc71f96ce, + (q31_t)0x229cd9f8, (q31_t)0xc7255ae0, (q31_t)0x2291b0bd, (q31_t)0xc72b2123, + (q31_t)0x228688a4, (q31_t)0xc730e997, (q31_t)0x227b61af, (q31_t)0xc736b43c, + (q31_t)0x22703bdc, (q31_t)0xc73c8111, (q31_t)0x2265172e, (q31_t)0xc7425016, + (q31_t)0x2259f3a3, (q31_t)0xc748214c, (q31_t)0x224ed13d, (q31_t)0xc74df4b1, + (q31_t)0x2243affc, (q31_t)0xc753ca46, (q31_t)0x22388fe1, (q31_t)0xc759a20a, + (q31_t)0x222d70eb, (q31_t)0xc75f7bfe, (q31_t)0x2222531c, (q31_t)0xc7655820, + (q31_t)0x22173674, (q31_t)0xc76b3671, (q31_t)0x220c1af3, (q31_t)0xc77116f0, + (q31_t)0x22010099, (q31_t)0xc776f99d, (q31_t)0x21f5e768, (q31_t)0xc77cde79, + (q31_t)0x21eacf5f, (q31_t)0xc782c582, (q31_t)0x21dfb87f, (q31_t)0xc788aeb9, + (q31_t)0x21d4a2c8, (q31_t)0xc78e9a1d, (q31_t)0x21c98e3b, (q31_t)0xc79487ae, + (q31_t)0x21be7ad8, (q31_t)0xc79a776c, (q31_t)0x21b368a0, (q31_t)0xc7a06957, + (q31_t)0x21a85793, (q31_t)0xc7a65d6e, (q31_t)0x219d47b1, (q31_t)0xc7ac53b1, + (q31_t)0x219238fb, (q31_t)0xc7b24c20, (q31_t)0x21872b72, (q31_t)0xc7b846ba, + (q31_t)0x217c1f15, (q31_t)0xc7be4381, (q31_t)0x217113e5, (q31_t)0xc7c44272, + (q31_t)0x216609e3, (q31_t)0xc7ca438f, (q31_t)0x215b0110, (q31_t)0xc7d046d6, + (q31_t)0x214ff96a, (q31_t)0xc7d64c47, (q31_t)0x2144f2f3, (q31_t)0xc7dc53e3, + (q31_t)0x2139edac, (q31_t)0xc7e25daa, (q31_t)0x212ee995, (q31_t)0xc7e8699a, + (q31_t)0x2123e6ad, (q31_t)0xc7ee77b3, (q31_t)0x2118e4f6, (q31_t)0xc7f487f6, + (q31_t)0x210de470, (q31_t)0xc7fa9a62, (q31_t)0x2102e51c, (q31_t)0xc800aef7, + (q31_t)0x20f7e6f9, (q31_t)0xc806c5b5, (q31_t)0x20ecea09, (q31_t)0xc80cde9b, + (q31_t)0x20e1ee4b, (q31_t)0xc812f9a9, (q31_t)0x20d6f3c1, (q31_t)0xc81916df, + (q31_t)0x20cbfa6a, (q31_t)0xc81f363d, (q31_t)0x20c10247, (q31_t)0xc82557c3, + (q31_t)0x20b60b58, (q31_t)0xc82b7b70, (q31_t)0x20ab159e, (q31_t)0xc831a143, + (q31_t)0x20a0211a, (q31_t)0xc837c93e, (q31_t)0x20952dcb, (q31_t)0xc83df35f, + (q31_t)0x208a3bb2, (q31_t)0xc8441fa6, (q31_t)0x207f4acf, (q31_t)0xc84a4e14, + (q31_t)0x20745b24, (q31_t)0xc8507ea7, (q31_t)0x20696cb0, (q31_t)0xc856b160, + (q31_t)0x205e7f74, (q31_t)0xc85ce63e, (q31_t)0x2053936f, (q31_t)0xc8631d42, + (q31_t)0x2048a8a4, (q31_t)0xc869566a, (q31_t)0x203dbf11, (q31_t)0xc86f91b7, + (q31_t)0x2032d6b8, (q31_t)0xc875cf28, (q31_t)0x2027ef99, (q31_t)0xc87c0ebd, + (q31_t)0x201d09b4, (q31_t)0xc8825077, (q31_t)0x2012250a, (q31_t)0xc8889454, + (q31_t)0x2007419b, (q31_t)0xc88eda54, (q31_t)0x1ffc5f67, (q31_t)0xc8952278, + (q31_t)0x1ff17e70, (q31_t)0xc89b6cbf, (q31_t)0x1fe69eb4, (q31_t)0xc8a1b928, + (q31_t)0x1fdbc036, (q31_t)0xc8a807b4, (q31_t)0x1fd0e2f5, (q31_t)0xc8ae5862, + (q31_t)0x1fc606f1, (q31_t)0xc8b4ab32, (q31_t)0x1fbb2c2c, (q31_t)0xc8bb0023, + (q31_t)0x1fb052a5, (q31_t)0xc8c15736, (q31_t)0x1fa57a5d, (q31_t)0xc8c7b06b, + (q31_t)0x1f9aa354, (q31_t)0xc8ce0bc0, (q31_t)0x1f8fcd8b, (q31_t)0xc8d46936, + (q31_t)0x1f84f902, (q31_t)0xc8dac8cd, (q31_t)0x1f7a25ba, (q31_t)0xc8e12a84, + (q31_t)0x1f6f53b3, (q31_t)0xc8e78e5b, (q31_t)0x1f6482ed, (q31_t)0xc8edf452, + (q31_t)0x1f59b369, (q31_t)0xc8f45c68, (q31_t)0x1f4ee527, (q31_t)0xc8fac69e, + (q31_t)0x1f441828, (q31_t)0xc90132f2, (q31_t)0x1f394c6b, (q31_t)0xc907a166, + (q31_t)0x1f2e81f3, (q31_t)0xc90e11f7, (q31_t)0x1f23b8be, (q31_t)0xc91484a8, + (q31_t)0x1f18f0ce, (q31_t)0xc91af976, (q31_t)0x1f0e2a22, (q31_t)0xc9217062, + (q31_t)0x1f0364bc, (q31_t)0xc927e96b, (q31_t)0x1ef8a09b, (q31_t)0xc92e6492, + (q31_t)0x1eedddc0, (q31_t)0xc934e1d6, (q31_t)0x1ee31c2b, (q31_t)0xc93b6137, + (q31_t)0x1ed85bdd, (q31_t)0xc941e2b4, (q31_t)0x1ecd9cd7, (q31_t)0xc948664d, + (q31_t)0x1ec2df18, (q31_t)0xc94eec03, (q31_t)0x1eb822a1, (q31_t)0xc95573d4, + (q31_t)0x1ead6773, (q31_t)0xc95bfdc1, (q31_t)0x1ea2ad8d, (q31_t)0xc96289c9, + (q31_t)0x1e97f4f1, (q31_t)0xc96917ec, (q31_t)0x1e8d3d9e, (q31_t)0xc96fa82a, + (q31_t)0x1e828796, (q31_t)0xc9763a83, (q31_t)0x1e77d2d8, (q31_t)0xc97ccef5, + (q31_t)0x1e6d1f65, (q31_t)0xc9836582, (q31_t)0x1e626d3e, (q31_t)0xc989fe29, + (q31_t)0x1e57bc62, (q31_t)0xc99098e9, (q31_t)0x1e4d0cd2, (q31_t)0xc99735c2, + (q31_t)0x1e425e8f, (q31_t)0xc99dd4b4, (q31_t)0x1e37b199, (q31_t)0xc9a475bf, + (q31_t)0x1e2d05f1, (q31_t)0xc9ab18e3, (q31_t)0x1e225b96, (q31_t)0xc9b1be1e, + (q31_t)0x1e17b28a, (q31_t)0xc9b86572, (q31_t)0x1e0d0acc, (q31_t)0xc9bf0edd, + (q31_t)0x1e02645d, (q31_t)0xc9c5ba60, (q31_t)0x1df7bf3e, (q31_t)0xc9cc67fa, + (q31_t)0x1ded1b6e, (q31_t)0xc9d317ab, (q31_t)0x1de278ef, (q31_t)0xc9d9c973, + (q31_t)0x1dd7d7c1, (q31_t)0xc9e07d51, (q31_t)0x1dcd37e4, (q31_t)0xc9e73346, + (q31_t)0x1dc29958, (q31_t)0xc9edeb50, (q31_t)0x1db7fc1e, (q31_t)0xc9f4a570, + (q31_t)0x1dad6036, (q31_t)0xc9fb61a5, (q31_t)0x1da2c5a2, (q31_t)0xca021fef, + (q31_t)0x1d982c60, (q31_t)0xca08e04f, (q31_t)0x1d8d9472, (q31_t)0xca0fa2c3, + (q31_t)0x1d82fdd8, (q31_t)0xca16674b, (q31_t)0x1d786892, (q31_t)0xca1d2de7, + (q31_t)0x1d6dd4a2, (q31_t)0xca23f698, (q31_t)0x1d634206, (q31_t)0xca2ac15b, + (q31_t)0x1d58b0c0, (q31_t)0xca318e32, (q31_t)0x1d4e20d0, (q31_t)0xca385d1d, + (q31_t)0x1d439236, (q31_t)0xca3f2e19, (q31_t)0x1d3904f4, (q31_t)0xca460129, + (q31_t)0x1d2e7908, (q31_t)0xca4cd64b, (q31_t)0x1d23ee74, (q31_t)0xca53ad7e, + (q31_t)0x1d196538, (q31_t)0xca5a86c4, (q31_t)0x1d0edd55, (q31_t)0xca61621b, + (q31_t)0x1d0456ca, (q31_t)0xca683f83, (q31_t)0x1cf9d199, (q31_t)0xca6f1efc, + (q31_t)0x1cef4dc2, (q31_t)0xca760086, (q31_t)0x1ce4cb44, (q31_t)0xca7ce420, + (q31_t)0x1cda4a21, (q31_t)0xca83c9ca, (q31_t)0x1ccfca59, (q31_t)0xca8ab184, + (q31_t)0x1cc54bec, (q31_t)0xca919b4e, (q31_t)0x1cbacedb, (q31_t)0xca988727, + (q31_t)0x1cb05326, (q31_t)0xca9f750f, (q31_t)0x1ca5d8cd, (q31_t)0xcaa66506, + (q31_t)0x1c9b5fd2, (q31_t)0xcaad570c, (q31_t)0x1c90e834, (q31_t)0xcab44b1f, + (q31_t)0x1c8671f3, (q31_t)0xcabb4141, (q31_t)0x1c7bfd11, (q31_t)0xcac23971, + (q31_t)0x1c71898d, (q31_t)0xcac933ae, (q31_t)0x1c671768, (q31_t)0xcad02ff8, + (q31_t)0x1c5ca6a2, (q31_t)0xcad72e4f, (q31_t)0x1c52373c, (q31_t)0xcade2eb3, + (q31_t)0x1c47c936, (q31_t)0xcae53123, (q31_t)0x1c3d5c91, (q31_t)0xcaec35a0, + (q31_t)0x1c32f14d, (q31_t)0xcaf33c28, (q31_t)0x1c28876a, (q31_t)0xcafa44bc, + (q31_t)0x1c1e1ee9, (q31_t)0xcb014f5b, (q31_t)0x1c13b7c9, (q31_t)0xcb085c05, + (q31_t)0x1c09520d, (q31_t)0xcb0f6aba, (q31_t)0x1bfeedb3, (q31_t)0xcb167b79, + (q31_t)0x1bf48abd, (q31_t)0xcb1d8e43, (q31_t)0x1bea292b, (q31_t)0xcb24a316, + (q31_t)0x1bdfc8fc, (q31_t)0xcb2bb9f4, (q31_t)0x1bd56a32, (q31_t)0xcb32d2da, + (q31_t)0x1bcb0cce, (q31_t)0xcb39edca, (q31_t)0x1bc0b0ce, (q31_t)0xcb410ac3, + (q31_t)0x1bb65634, (q31_t)0xcb4829c4, (q31_t)0x1babfd01, (q31_t)0xcb4f4acd, + (q31_t)0x1ba1a534, (q31_t)0xcb566ddf, (q31_t)0x1b974ece, (q31_t)0xcb5d92f8, + (q31_t)0x1b8cf9cf, (q31_t)0xcb64ba19, (q31_t)0x1b82a638, (q31_t)0xcb6be341, + (q31_t)0x1b785409, (q31_t)0xcb730e70, (q31_t)0x1b6e0342, (q31_t)0xcb7a3ba5, + (q31_t)0x1b63b3e5, (q31_t)0xcb816ae1, (q31_t)0x1b5965f1, (q31_t)0xcb889c23, + (q31_t)0x1b4f1967, (q31_t)0xcb8fcf6b, (q31_t)0x1b44ce46, (q31_t)0xcb9704b9, + (q31_t)0x1b3a8491, (q31_t)0xcb9e3c0b, (q31_t)0x1b303c46, (q31_t)0xcba57563, + (q31_t)0x1b25f566, (q31_t)0xcbacb0bf, (q31_t)0x1b1baff2, (q31_t)0xcbb3ee20, + (q31_t)0x1b116beb, (q31_t)0xcbbb2d85, (q31_t)0x1b072950, (q31_t)0xcbc26eee, + (q31_t)0x1afce821, (q31_t)0xcbc9b25a, (q31_t)0x1af2a860, (q31_t)0xcbd0f7ca, + (q31_t)0x1ae86a0d, (q31_t)0xcbd83f3d, (q31_t)0x1ade2d28, (q31_t)0xcbdf88b3, + (q31_t)0x1ad3f1b1, (q31_t)0xcbe6d42b, (q31_t)0x1ac9b7a9, (q31_t)0xcbee21a5, + (q31_t)0x1abf7f11, (q31_t)0xcbf57121, (q31_t)0x1ab547e8, (q31_t)0xcbfcc29f, + (q31_t)0x1aab122f, (q31_t)0xcc04161e, (q31_t)0x1aa0dde7, (q31_t)0xcc0b6b9e, + (q31_t)0x1a96ab0f, (q31_t)0xcc12c31f, (q31_t)0x1a8c79a9, (q31_t)0xcc1a1ca0, + (q31_t)0x1a8249b4, (q31_t)0xcc217822, (q31_t)0x1a781b31, (q31_t)0xcc28d5a3, + (q31_t)0x1a6dee21, (q31_t)0xcc303524, (q31_t)0x1a63c284, (q31_t)0xcc3796a5, + (q31_t)0x1a599859, (q31_t)0xcc3efa25, (q31_t)0x1a4f6fa3, (q31_t)0xcc465fa3, + (q31_t)0x1a454860, (q31_t)0xcc4dc720, (q31_t)0x1a3b2292, (q31_t)0xcc55309b, + (q31_t)0x1a30fe38, (q31_t)0xcc5c9c14, (q31_t)0x1a26db54, (q31_t)0xcc64098b, + (q31_t)0x1a1cb9e5, (q31_t)0xcc6b78ff, (q31_t)0x1a1299ec, (q31_t)0xcc72ea70, + (q31_t)0x1a087b69, (q31_t)0xcc7a5dde, (q31_t)0x19fe5e5e, (q31_t)0xcc81d349, + (q31_t)0x19f442c9, (q31_t)0xcc894aaf, (q31_t)0x19ea28ac, (q31_t)0xcc90c412, + (q31_t)0x19e01006, (q31_t)0xcc983f70, (q31_t)0x19d5f8d9, (q31_t)0xcc9fbcca, + (q31_t)0x19cbe325, (q31_t)0xcca73c1e, (q31_t)0x19c1cee9, (q31_t)0xccaebd6e, + (q31_t)0x19b7bc27, (q31_t)0xccb640b8, (q31_t)0x19adaadf, (q31_t)0xccbdc5fc, + (q31_t)0x19a39b11, (q31_t)0xccc54d3a, (q31_t)0x19998cbe, (q31_t)0xccccd671, + (q31_t)0x198f7fe6, (q31_t)0xccd461a2, (q31_t)0x19857489, (q31_t)0xccdbeecc, + (q31_t)0x197b6aa8, (q31_t)0xcce37def, (q31_t)0x19716243, (q31_t)0xcceb0f0a, + (q31_t)0x19675b5a, (q31_t)0xccf2a21d, (q31_t)0x195d55ef, (q31_t)0xccfa3729, + (q31_t)0x19535201, (q31_t)0xcd01ce2b, (q31_t)0x19494f90, (q31_t)0xcd096725, + (q31_t)0x193f4e9e, (q31_t)0xcd110216, (q31_t)0x19354f2a, (q31_t)0xcd189efe, + (q31_t)0x192b5135, (q31_t)0xcd203ddc, (q31_t)0x192154bf, (q31_t)0xcd27deb0, + (q31_t)0x191759c9, (q31_t)0xcd2f817b, (q31_t)0x190d6053, (q31_t)0xcd37263a, + (q31_t)0x1903685d, (q31_t)0xcd3eccef, (q31_t)0x18f971e8, (q31_t)0xcd467599, + (q31_t)0x18ef7cf4, (q31_t)0xcd4e2037, (q31_t)0x18e58982, (q31_t)0xcd55ccca, + (q31_t)0x18db9792, (q31_t)0xcd5d7b50, (q31_t)0x18d1a724, (q31_t)0xcd652bcb, + (q31_t)0x18c7b838, (q31_t)0xcd6cde39, (q31_t)0x18bdcad0, (q31_t)0xcd74929a, + (q31_t)0x18b3deeb, (q31_t)0xcd7c48ee, (q31_t)0x18a9f48a, (q31_t)0xcd840134, + (q31_t)0x18a00bae, (q31_t)0xcd8bbb6d, (q31_t)0x18962456, (q31_t)0xcd937798, + (q31_t)0x188c3e83, (q31_t)0xcd9b35b4, (q31_t)0x18825a35, (q31_t)0xcda2f5c2, + (q31_t)0x1878776d, (q31_t)0xcdaab7c0, (q31_t)0x186e962b, (q31_t)0xcdb27bb0, + (q31_t)0x1864b670, (q31_t)0xcdba4190, (q31_t)0x185ad83c, (q31_t)0xcdc20960, + (q31_t)0x1850fb8e, (q31_t)0xcdc9d320, (q31_t)0x18472069, (q31_t)0xcdd19ed0, + (q31_t)0x183d46cc, (q31_t)0xcdd96c6f, (q31_t)0x18336eb7, (q31_t)0xcde13bfd, + (q31_t)0x1829982b, (q31_t)0xcde90d79, (q31_t)0x181fc328, (q31_t)0xcdf0e0e4, + (q31_t)0x1815efae, (q31_t)0xcdf8b63d, (q31_t)0x180c1dbf, (q31_t)0xce008d84, + (q31_t)0x18024d59, (q31_t)0xce0866b8, (q31_t)0x17f87e7f, (q31_t)0xce1041d9, + (q31_t)0x17eeb130, (q31_t)0xce181ee8, (q31_t)0x17e4e56c, (q31_t)0xce1ffde2, + (q31_t)0x17db1b34, (q31_t)0xce27dec9, (q31_t)0x17d15288, (q31_t)0xce2fc19c, + (q31_t)0x17c78b68, (q31_t)0xce37a65b, (q31_t)0x17bdc5d6, (q31_t)0xce3f8d05, + (q31_t)0x17b401d1, (q31_t)0xce47759a, (q31_t)0x17aa3f5a, (q31_t)0xce4f6019, + (q31_t)0x17a07e70, (q31_t)0xce574c84, (q31_t)0x1796bf16, (q31_t)0xce5f3ad8, + (q31_t)0x178d014a, (q31_t)0xce672b16, (q31_t)0x1783450d, (q31_t)0xce6f1d3d, + (q31_t)0x17798a60, (q31_t)0xce77114e, (q31_t)0x176fd143, (q31_t)0xce7f0748, + (q31_t)0x176619b6, (q31_t)0xce86ff2a, (q31_t)0x175c63ba, (q31_t)0xce8ef8f4, + (q31_t)0x1752af4f, (q31_t)0xce96f4a7, (q31_t)0x1748fc75, (q31_t)0xce9ef241, + (q31_t)0x173f4b2e, (q31_t)0xcea6f1c2, (q31_t)0x17359b78, (q31_t)0xceaef32b, + (q31_t)0x172bed55, (q31_t)0xceb6f67a, (q31_t)0x172240c5, (q31_t)0xcebefbb0, + (q31_t)0x171895c9, (q31_t)0xcec702cb, (q31_t)0x170eec60, (q31_t)0xcecf0bcd, + (q31_t)0x1705448b, (q31_t)0xced716b4, (q31_t)0x16fb9e4b, (q31_t)0xcedf2380, + (q31_t)0x16f1f99f, (q31_t)0xcee73231, (q31_t)0x16e85689, (q31_t)0xceef42c7, + (q31_t)0x16deb508, (q31_t)0xcef75541, (q31_t)0x16d5151d, (q31_t)0xceff699f, + (q31_t)0x16cb76c9, (q31_t)0xcf077fe1, (q31_t)0x16c1da0b, (q31_t)0xcf0f9805, + (q31_t)0x16b83ee4, (q31_t)0xcf17b20d, (q31_t)0x16aea555, (q31_t)0xcf1fcdf8, + (q31_t)0x16a50d5d, (q31_t)0xcf27ebc5, (q31_t)0x169b76fe, (q31_t)0xcf300b74, + (q31_t)0x1691e237, (q31_t)0xcf382d05, (q31_t)0x16884f09, (q31_t)0xcf405077, + (q31_t)0x167ebd74, (q31_t)0xcf4875ca, (q31_t)0x16752d79, (q31_t)0xcf509cfe, + (q31_t)0x166b9f18, (q31_t)0xcf58c613, (q31_t)0x16621251, (q31_t)0xcf60f108, + (q31_t)0x16588725, (q31_t)0xcf691ddd, (q31_t)0x164efd94, (q31_t)0xcf714c91, + (q31_t)0x1645759f, (q31_t)0xcf797d24, (q31_t)0x163bef46, (q31_t)0xcf81af97, + (q31_t)0x16326a88, (q31_t)0xcf89e3e8, (q31_t)0x1628e767, (q31_t)0xcf921a17, + (q31_t)0x161f65e4, (q31_t)0xcf9a5225, (q31_t)0x1615e5fd, (q31_t)0xcfa28c10, + (q31_t)0x160c67b4, (q31_t)0xcfaac7d8, (q31_t)0x1602eb0a, (q31_t)0xcfb3057d, + (q31_t)0x15f96ffd, (q31_t)0xcfbb4500, (q31_t)0x15eff690, (q31_t)0xcfc3865e, + (q31_t)0x15e67ec1, (q31_t)0xcfcbc999, (q31_t)0x15dd0892, (q31_t)0xcfd40eaf, + (q31_t)0x15d39403, (q31_t)0xcfdc55a1, (q31_t)0x15ca2115, (q31_t)0xcfe49e6d, + (q31_t)0x15c0afc6, (q31_t)0xcfece915, (q31_t)0x15b74019, (q31_t)0xcff53597, + (q31_t)0x15add20d, (q31_t)0xcffd83f4, (q31_t)0x15a465a3, (q31_t)0xd005d42a, + (q31_t)0x159afadb, (q31_t)0xd00e2639, (q31_t)0x159191b5, (q31_t)0xd0167a22, + (q31_t)0x15882a32, (q31_t)0xd01ecfe4, (q31_t)0x157ec452, (q31_t)0xd027277e, + (q31_t)0x15756016, (q31_t)0xd02f80f1, (q31_t)0x156bfd7d, (q31_t)0xd037dc3b, + (q31_t)0x15629c89, (q31_t)0xd040395d, (q31_t)0x15593d3a, (q31_t)0xd0489856, + (q31_t)0x154fdf8f, (q31_t)0xd050f926, (q31_t)0x15468389, (q31_t)0xd0595bcd, + (q31_t)0x153d292a, (q31_t)0xd061c04a, (q31_t)0x1533d070, (q31_t)0xd06a269d, + (q31_t)0x152a795d, (q31_t)0xd0728ec6, (q31_t)0x152123f0, (q31_t)0xd07af8c4, + (q31_t)0x1517d02b, (q31_t)0xd0836497, (q31_t)0x150e7e0d, (q31_t)0xd08bd23f, + (q31_t)0x15052d97, (q31_t)0xd09441bb, (q31_t)0x14fbdec9, (q31_t)0xd09cb30b, + (q31_t)0x14f291a4, (q31_t)0xd0a5262f, (q31_t)0x14e94627, (q31_t)0xd0ad9b26, + (q31_t)0x14dffc54, (q31_t)0xd0b611f1, (q31_t)0x14d6b42b, (q31_t)0xd0be8a8d, + (q31_t)0x14cd6dab, (q31_t)0xd0c704fd, (q31_t)0x14c428d6, (q31_t)0xd0cf813e, + (q31_t)0x14bae5ab, (q31_t)0xd0d7ff51, (q31_t)0x14b1a42c, (q31_t)0xd0e07f36, + (q31_t)0x14a86458, (q31_t)0xd0e900ec, (q31_t)0x149f2630, (q31_t)0xd0f18472, + (q31_t)0x1495e9b3, (q31_t)0xd0fa09c9, (q31_t)0x148caee4, (q31_t)0xd10290f0, + (q31_t)0x148375c1, (q31_t)0xd10b19e7, (q31_t)0x147a3e4b, (q31_t)0xd113a4ad, + (q31_t)0x14710883, (q31_t)0xd11c3142, (q31_t)0x1467d469, (q31_t)0xd124bfa6, + (q31_t)0x145ea1fd, (q31_t)0xd12d4fd9, (q31_t)0x14557140, (q31_t)0xd135e1d9, + (q31_t)0x144c4232, (q31_t)0xd13e75a8, (q31_t)0x144314d3, (q31_t)0xd1470b44, + (q31_t)0x1439e923, (q31_t)0xd14fa2ad, (q31_t)0x1430bf24, (q31_t)0xd1583be2, + (q31_t)0x142796d5, (q31_t)0xd160d6e5, (q31_t)0x141e7037, (q31_t)0xd16973b3, + (q31_t)0x14154b4a, (q31_t)0xd172124d, (q31_t)0x140c280e, (q31_t)0xd17ab2b3, + (q31_t)0x14030684, (q31_t)0xd18354e4, (q31_t)0x13f9e6ad, (q31_t)0xd18bf8e0, + (q31_t)0x13f0c887, (q31_t)0xd1949ea6, (q31_t)0x13e7ac15, (q31_t)0xd19d4636, + (q31_t)0x13de9156, (q31_t)0xd1a5ef90, (q31_t)0x13d5784a, (q31_t)0xd1ae9ab4, + (q31_t)0x13cc60f2, (q31_t)0xd1b747a0, (q31_t)0x13c34b4f, (q31_t)0xd1bff656, + (q31_t)0x13ba3760, (q31_t)0xd1c8a6d4, (q31_t)0x13b12526, (q31_t)0xd1d1591a, + (q31_t)0x13a814a2, (q31_t)0xd1da0d28, (q31_t)0x139f05d3, (q31_t)0xd1e2c2fd, + (q31_t)0x1395f8ba, (q31_t)0xd1eb7a9a, (q31_t)0x138ced57, (q31_t)0xd1f433fd, + (q31_t)0x1383e3ab, (q31_t)0xd1fcef27, (q31_t)0x137adbb6, (q31_t)0xd205ac17, + (q31_t)0x1371d579, (q31_t)0xd20e6acc, (q31_t)0x1368d0f3, (q31_t)0xd2172b48, + (q31_t)0x135fce26, (q31_t)0xd21fed88, (q31_t)0x1356cd11, (q31_t)0xd228b18d, + (q31_t)0x134dcdb4, (q31_t)0xd2317756, (q31_t)0x1344d011, (q31_t)0xd23a3ee4, + (q31_t)0x133bd427, (q31_t)0xd2430835, (q31_t)0x1332d9f7, (q31_t)0xd24bd34a, + (q31_t)0x1329e181, (q31_t)0xd254a021, (q31_t)0x1320eac6, (q31_t)0xd25d6ebc, + (q31_t)0x1317f5c6, (q31_t)0xd2663f19, (q31_t)0x130f0280, (q31_t)0xd26f1138, + (q31_t)0x130610f7, (q31_t)0xd277e518, (q31_t)0x12fd2129, (q31_t)0xd280babb, + (q31_t)0x12f43318, (q31_t)0xd289921e, (q31_t)0x12eb46c3, (q31_t)0xd2926b41, + (q31_t)0x12e25c2b, (q31_t)0xd29b4626, (q31_t)0x12d97350, (q31_t)0xd2a422ca, + (q31_t)0x12d08c33, (q31_t)0xd2ad012e, (q31_t)0x12c7a6d4, (q31_t)0xd2b5e151, + (q31_t)0x12bec333, (q31_t)0xd2bec333, (q31_t)0x12b5e151, (q31_t)0xd2c7a6d4, + (q31_t)0x12ad012e, (q31_t)0xd2d08c33, (q31_t)0x12a422ca, (q31_t)0xd2d97350, + (q31_t)0x129b4626, (q31_t)0xd2e25c2b, (q31_t)0x12926b41, (q31_t)0xd2eb46c3, + (q31_t)0x1289921e, (q31_t)0xd2f43318, (q31_t)0x1280babb, (q31_t)0xd2fd2129, + (q31_t)0x1277e518, (q31_t)0xd30610f7, (q31_t)0x126f1138, (q31_t)0xd30f0280, + (q31_t)0x12663f19, (q31_t)0xd317f5c6, (q31_t)0x125d6ebc, (q31_t)0xd320eac6, + (q31_t)0x1254a021, (q31_t)0xd329e181, (q31_t)0x124bd34a, (q31_t)0xd332d9f7, + (q31_t)0x12430835, (q31_t)0xd33bd427, (q31_t)0x123a3ee4, (q31_t)0xd344d011, + (q31_t)0x12317756, (q31_t)0xd34dcdb4, (q31_t)0x1228b18d, (q31_t)0xd356cd11, + (q31_t)0x121fed88, (q31_t)0xd35fce26, (q31_t)0x12172b48, (q31_t)0xd368d0f3, + (q31_t)0x120e6acc, (q31_t)0xd371d579, (q31_t)0x1205ac17, (q31_t)0xd37adbb6, + (q31_t)0x11fcef27, (q31_t)0xd383e3ab, (q31_t)0x11f433fd, (q31_t)0xd38ced57, + (q31_t)0x11eb7a9a, (q31_t)0xd395f8ba, (q31_t)0x11e2c2fd, (q31_t)0xd39f05d3, + (q31_t)0x11da0d28, (q31_t)0xd3a814a2, (q31_t)0x11d1591a, (q31_t)0xd3b12526, + (q31_t)0x11c8a6d4, (q31_t)0xd3ba3760, (q31_t)0x11bff656, (q31_t)0xd3c34b4f, + (q31_t)0x11b747a0, (q31_t)0xd3cc60f2, (q31_t)0x11ae9ab4, (q31_t)0xd3d5784a, + (q31_t)0x11a5ef90, (q31_t)0xd3de9156, (q31_t)0x119d4636, (q31_t)0xd3e7ac15, + (q31_t)0x11949ea6, (q31_t)0xd3f0c887, (q31_t)0x118bf8e0, (q31_t)0xd3f9e6ad, + (q31_t)0x118354e4, (q31_t)0xd4030684, (q31_t)0x117ab2b3, (q31_t)0xd40c280e, + (q31_t)0x1172124d, (q31_t)0xd4154b4a, (q31_t)0x116973b3, (q31_t)0xd41e7037, + (q31_t)0x1160d6e5, (q31_t)0xd42796d5, (q31_t)0x11583be2, (q31_t)0xd430bf24, + (q31_t)0x114fa2ad, (q31_t)0xd439e923, (q31_t)0x11470b44, (q31_t)0xd44314d3, + (q31_t)0x113e75a8, (q31_t)0xd44c4232, (q31_t)0x1135e1d9, (q31_t)0xd4557140, + (q31_t)0x112d4fd9, (q31_t)0xd45ea1fd, (q31_t)0x1124bfa6, (q31_t)0xd467d469, + (q31_t)0x111c3142, (q31_t)0xd4710883, (q31_t)0x1113a4ad, (q31_t)0xd47a3e4b, + (q31_t)0x110b19e7, (q31_t)0xd48375c1, (q31_t)0x110290f0, (q31_t)0xd48caee4, + (q31_t)0x10fa09c9, (q31_t)0xd495e9b3, (q31_t)0x10f18472, (q31_t)0xd49f2630, + (q31_t)0x10e900ec, (q31_t)0xd4a86458, (q31_t)0x10e07f36, (q31_t)0xd4b1a42c, + (q31_t)0x10d7ff51, (q31_t)0xd4bae5ab, (q31_t)0x10cf813e, (q31_t)0xd4c428d6, + (q31_t)0x10c704fd, (q31_t)0xd4cd6dab, (q31_t)0x10be8a8d, (q31_t)0xd4d6b42b, + (q31_t)0x10b611f1, (q31_t)0xd4dffc54, (q31_t)0x10ad9b26, (q31_t)0xd4e94627, + (q31_t)0x10a5262f, (q31_t)0xd4f291a4, (q31_t)0x109cb30b, (q31_t)0xd4fbdec9, + (q31_t)0x109441bb, (q31_t)0xd5052d97, (q31_t)0x108bd23f, (q31_t)0xd50e7e0d, + (q31_t)0x10836497, (q31_t)0xd517d02b, (q31_t)0x107af8c4, (q31_t)0xd52123f0, + (q31_t)0x10728ec6, (q31_t)0xd52a795d, (q31_t)0x106a269d, (q31_t)0xd533d070, + (q31_t)0x1061c04a, (q31_t)0xd53d292a, (q31_t)0x10595bcd, (q31_t)0xd5468389, + (q31_t)0x1050f926, (q31_t)0xd54fdf8f, (q31_t)0x10489856, (q31_t)0xd5593d3a, + (q31_t)0x1040395d, (q31_t)0xd5629c89, (q31_t)0x1037dc3b, (q31_t)0xd56bfd7d, + (q31_t)0x102f80f1, (q31_t)0xd5756016, (q31_t)0x1027277e, (q31_t)0xd57ec452, + (q31_t)0x101ecfe4, (q31_t)0xd5882a32, (q31_t)0x10167a22, (q31_t)0xd59191b5, + (q31_t)0x100e2639, (q31_t)0xd59afadb, (q31_t)0x1005d42a, (q31_t)0xd5a465a3, + (q31_t)0xffd83f4, (q31_t)0xd5add20d, (q31_t)0xff53597, (q31_t)0xd5b74019, + (q31_t)0xfece915, (q31_t)0xd5c0afc6, (q31_t)0xfe49e6d, (q31_t)0xd5ca2115, + (q31_t)0xfdc55a1, (q31_t)0xd5d39403, (q31_t)0xfd40eaf, (q31_t)0xd5dd0892, + (q31_t)0xfcbc999, (q31_t)0xd5e67ec1, (q31_t)0xfc3865e, (q31_t)0xd5eff690, + (q31_t)0xfbb4500, (q31_t)0xd5f96ffd, (q31_t)0xfb3057d, (q31_t)0xd602eb0a, + (q31_t)0xfaac7d8, (q31_t)0xd60c67b4, (q31_t)0xfa28c10, (q31_t)0xd615e5fd, + (q31_t)0xf9a5225, (q31_t)0xd61f65e4, (q31_t)0xf921a17, (q31_t)0xd628e767, + (q31_t)0xf89e3e8, (q31_t)0xd6326a88, (q31_t)0xf81af97, (q31_t)0xd63bef46, + (q31_t)0xf797d24, (q31_t)0xd645759f, (q31_t)0xf714c91, (q31_t)0xd64efd94, + (q31_t)0xf691ddd, (q31_t)0xd6588725, (q31_t)0xf60f108, (q31_t)0xd6621251, + (q31_t)0xf58c613, (q31_t)0xd66b9f18, (q31_t)0xf509cfe, (q31_t)0xd6752d79, + (q31_t)0xf4875ca, (q31_t)0xd67ebd74, (q31_t)0xf405077, (q31_t)0xd6884f09, + (q31_t)0xf382d05, (q31_t)0xd691e237, (q31_t)0xf300b74, (q31_t)0xd69b76fe, + (q31_t)0xf27ebc5, (q31_t)0xd6a50d5d, (q31_t)0xf1fcdf8, (q31_t)0xd6aea555, + (q31_t)0xf17b20d, (q31_t)0xd6b83ee4, (q31_t)0xf0f9805, (q31_t)0xd6c1da0b, + (q31_t)0xf077fe1, (q31_t)0xd6cb76c9, (q31_t)0xeff699f, (q31_t)0xd6d5151d, + (q31_t)0xef75541, (q31_t)0xd6deb508, (q31_t)0xeef42c7, (q31_t)0xd6e85689, + (q31_t)0xee73231, (q31_t)0xd6f1f99f, (q31_t)0xedf2380, (q31_t)0xd6fb9e4b, + (q31_t)0xed716b4, (q31_t)0xd705448b, (q31_t)0xecf0bcd, (q31_t)0xd70eec60, + (q31_t)0xec702cb, (q31_t)0xd71895c9, (q31_t)0xebefbb0, (q31_t)0xd72240c5, + (q31_t)0xeb6f67a, (q31_t)0xd72bed55, (q31_t)0xeaef32b, (q31_t)0xd7359b78, + (q31_t)0xea6f1c2, (q31_t)0xd73f4b2e, (q31_t)0xe9ef241, (q31_t)0xd748fc75, + (q31_t)0xe96f4a7, (q31_t)0xd752af4f, (q31_t)0xe8ef8f4, (q31_t)0xd75c63ba, + (q31_t)0xe86ff2a, (q31_t)0xd76619b6, (q31_t)0xe7f0748, (q31_t)0xd76fd143, + (q31_t)0xe77114e, (q31_t)0xd7798a60, (q31_t)0xe6f1d3d, (q31_t)0xd783450d, + (q31_t)0xe672b16, (q31_t)0xd78d014a, (q31_t)0xe5f3ad8, (q31_t)0xd796bf16, + (q31_t)0xe574c84, (q31_t)0xd7a07e70, (q31_t)0xe4f6019, (q31_t)0xd7aa3f5a, + (q31_t)0xe47759a, (q31_t)0xd7b401d1, (q31_t)0xe3f8d05, (q31_t)0xd7bdc5d6, + (q31_t)0xe37a65b, (q31_t)0xd7c78b68, (q31_t)0xe2fc19c, (q31_t)0xd7d15288, + (q31_t)0xe27dec9, (q31_t)0xd7db1b34, (q31_t)0xe1ffde2, (q31_t)0xd7e4e56c, + (q31_t)0xe181ee8, (q31_t)0xd7eeb130, (q31_t)0xe1041d9, (q31_t)0xd7f87e7f, + (q31_t)0xe0866b8, (q31_t)0xd8024d59, (q31_t)0xe008d84, (q31_t)0xd80c1dbf, + (q31_t)0xdf8b63d, (q31_t)0xd815efae, (q31_t)0xdf0e0e4, (q31_t)0xd81fc328, + (q31_t)0xde90d79, (q31_t)0xd829982b, (q31_t)0xde13bfd, (q31_t)0xd8336eb7, + (q31_t)0xdd96c6f, (q31_t)0xd83d46cc, (q31_t)0xdd19ed0, (q31_t)0xd8472069, + (q31_t)0xdc9d320, (q31_t)0xd850fb8e, (q31_t)0xdc20960, (q31_t)0xd85ad83c, + (q31_t)0xdba4190, (q31_t)0xd864b670, (q31_t)0xdb27bb0, (q31_t)0xd86e962b, + (q31_t)0xdaab7c0, (q31_t)0xd878776d, (q31_t)0xda2f5c2, (q31_t)0xd8825a35, + (q31_t)0xd9b35b4, (q31_t)0xd88c3e83, (q31_t)0xd937798, (q31_t)0xd8962456, + (q31_t)0xd8bbb6d, (q31_t)0xd8a00bae, (q31_t)0xd840134, (q31_t)0xd8a9f48a, + (q31_t)0xd7c48ee, (q31_t)0xd8b3deeb, (q31_t)0xd74929a, (q31_t)0xd8bdcad0, + (q31_t)0xd6cde39, (q31_t)0xd8c7b838, (q31_t)0xd652bcb, (q31_t)0xd8d1a724, + (q31_t)0xd5d7b50, (q31_t)0xd8db9792, (q31_t)0xd55ccca, (q31_t)0xd8e58982, + (q31_t)0xd4e2037, (q31_t)0xd8ef7cf4, (q31_t)0xd467599, (q31_t)0xd8f971e8, + (q31_t)0xd3eccef, (q31_t)0xd903685d, (q31_t)0xd37263a, (q31_t)0xd90d6053, + (q31_t)0xd2f817b, (q31_t)0xd91759c9, (q31_t)0xd27deb0, (q31_t)0xd92154bf, + (q31_t)0xd203ddc, (q31_t)0xd92b5135, (q31_t)0xd189efe, (q31_t)0xd9354f2a, + (q31_t)0xd110216, (q31_t)0xd93f4e9e, (q31_t)0xd096725, (q31_t)0xd9494f90, + (q31_t)0xd01ce2b, (q31_t)0xd9535201, (q31_t)0xcfa3729, (q31_t)0xd95d55ef, + (q31_t)0xcf2a21d, (q31_t)0xd9675b5a, (q31_t)0xceb0f0a, (q31_t)0xd9716243, + (q31_t)0xce37def, (q31_t)0xd97b6aa8, (q31_t)0xcdbeecc, (q31_t)0xd9857489, + (q31_t)0xcd461a2, (q31_t)0xd98f7fe6, (q31_t)0xcccd671, (q31_t)0xd9998cbe, + (q31_t)0xcc54d3a, (q31_t)0xd9a39b11, (q31_t)0xcbdc5fc, (q31_t)0xd9adaadf, + (q31_t)0xcb640b8, (q31_t)0xd9b7bc27, (q31_t)0xcaebd6e, (q31_t)0xd9c1cee9, + (q31_t)0xca73c1e, (q31_t)0xd9cbe325, (q31_t)0xc9fbcca, (q31_t)0xd9d5f8d9, + (q31_t)0xc983f70, (q31_t)0xd9e01006, (q31_t)0xc90c412, (q31_t)0xd9ea28ac, + (q31_t)0xc894aaf, (q31_t)0xd9f442c9, (q31_t)0xc81d349, (q31_t)0xd9fe5e5e, + (q31_t)0xc7a5dde, (q31_t)0xda087b69, (q31_t)0xc72ea70, (q31_t)0xda1299ec, + (q31_t)0xc6b78ff, (q31_t)0xda1cb9e5, (q31_t)0xc64098b, (q31_t)0xda26db54, + (q31_t)0xc5c9c14, (q31_t)0xda30fe38, (q31_t)0xc55309b, (q31_t)0xda3b2292, + (q31_t)0xc4dc720, (q31_t)0xda454860, (q31_t)0xc465fa3, (q31_t)0xda4f6fa3, + (q31_t)0xc3efa25, (q31_t)0xda599859, (q31_t)0xc3796a5, (q31_t)0xda63c284, + (q31_t)0xc303524, (q31_t)0xda6dee21, (q31_t)0xc28d5a3, (q31_t)0xda781b31, + (q31_t)0xc217822, (q31_t)0xda8249b4, (q31_t)0xc1a1ca0, (q31_t)0xda8c79a9, + (q31_t)0xc12c31f, (q31_t)0xda96ab0f, (q31_t)0xc0b6b9e, (q31_t)0xdaa0dde7, + (q31_t)0xc04161e, (q31_t)0xdaab122f, (q31_t)0xbfcc29f, (q31_t)0xdab547e8, + (q31_t)0xbf57121, (q31_t)0xdabf7f11, (q31_t)0xbee21a5, (q31_t)0xdac9b7a9, + (q31_t)0xbe6d42b, (q31_t)0xdad3f1b1, (q31_t)0xbdf88b3, (q31_t)0xdade2d28, + (q31_t)0xbd83f3d, (q31_t)0xdae86a0d, (q31_t)0xbd0f7ca, (q31_t)0xdaf2a860, + (q31_t)0xbc9b25a, (q31_t)0xdafce821, (q31_t)0xbc26eee, (q31_t)0xdb072950, + (q31_t)0xbbb2d85, (q31_t)0xdb116beb, (q31_t)0xbb3ee20, (q31_t)0xdb1baff2, + (q31_t)0xbacb0bf, (q31_t)0xdb25f566, (q31_t)0xba57563, (q31_t)0xdb303c46, + (q31_t)0xb9e3c0b, (q31_t)0xdb3a8491, (q31_t)0xb9704b9, (q31_t)0xdb44ce46, + (q31_t)0xb8fcf6b, (q31_t)0xdb4f1967, (q31_t)0xb889c23, (q31_t)0xdb5965f1, + (q31_t)0xb816ae1, (q31_t)0xdb63b3e5, (q31_t)0xb7a3ba5, (q31_t)0xdb6e0342, + (q31_t)0xb730e70, (q31_t)0xdb785409, (q31_t)0xb6be341, (q31_t)0xdb82a638, + (q31_t)0xb64ba19, (q31_t)0xdb8cf9cf, (q31_t)0xb5d92f8, (q31_t)0xdb974ece, + (q31_t)0xb566ddf, (q31_t)0xdba1a534, (q31_t)0xb4f4acd, (q31_t)0xdbabfd01, + (q31_t)0xb4829c4, (q31_t)0xdbb65634, (q31_t)0xb410ac3, (q31_t)0xdbc0b0ce, + (q31_t)0xb39edca, (q31_t)0xdbcb0cce, (q31_t)0xb32d2da, (q31_t)0xdbd56a32, + (q31_t)0xb2bb9f4, (q31_t)0xdbdfc8fc, (q31_t)0xb24a316, (q31_t)0xdbea292b, + (q31_t)0xb1d8e43, (q31_t)0xdbf48abd, (q31_t)0xb167b79, (q31_t)0xdbfeedb3, + (q31_t)0xb0f6aba, (q31_t)0xdc09520d, (q31_t)0xb085c05, (q31_t)0xdc13b7c9, + (q31_t)0xb014f5b, (q31_t)0xdc1e1ee9, (q31_t)0xafa44bc, (q31_t)0xdc28876a, + (q31_t)0xaf33c28, (q31_t)0xdc32f14d, (q31_t)0xaec35a0, (q31_t)0xdc3d5c91, + (q31_t)0xae53123, (q31_t)0xdc47c936, (q31_t)0xade2eb3, (q31_t)0xdc52373c, + (q31_t)0xad72e4f, (q31_t)0xdc5ca6a2, (q31_t)0xad02ff8, (q31_t)0xdc671768, + (q31_t)0xac933ae, (q31_t)0xdc71898d, (q31_t)0xac23971, (q31_t)0xdc7bfd11, + (q31_t)0xabb4141, (q31_t)0xdc8671f3, (q31_t)0xab44b1f, (q31_t)0xdc90e834, + (q31_t)0xaad570c, (q31_t)0xdc9b5fd2, (q31_t)0xaa66506, (q31_t)0xdca5d8cd, + (q31_t)0xa9f750f, (q31_t)0xdcb05326, (q31_t)0xa988727, (q31_t)0xdcbacedb, + (q31_t)0xa919b4e, (q31_t)0xdcc54bec, (q31_t)0xa8ab184, (q31_t)0xdccfca59, + (q31_t)0xa83c9ca, (q31_t)0xdcda4a21, (q31_t)0xa7ce420, (q31_t)0xdce4cb44, + (q31_t)0xa760086, (q31_t)0xdcef4dc2, (q31_t)0xa6f1efc, (q31_t)0xdcf9d199, + (q31_t)0xa683f83, (q31_t)0xdd0456ca, (q31_t)0xa61621b, (q31_t)0xdd0edd55, + (q31_t)0xa5a86c4, (q31_t)0xdd196538, (q31_t)0xa53ad7e, (q31_t)0xdd23ee74, + (q31_t)0xa4cd64b, (q31_t)0xdd2e7908, (q31_t)0xa460129, (q31_t)0xdd3904f4, + (q31_t)0xa3f2e19, (q31_t)0xdd439236, (q31_t)0xa385d1d, (q31_t)0xdd4e20d0, + (q31_t)0xa318e32, (q31_t)0xdd58b0c0, (q31_t)0xa2ac15b, (q31_t)0xdd634206, + (q31_t)0xa23f698, (q31_t)0xdd6dd4a2, (q31_t)0xa1d2de7, (q31_t)0xdd786892, + (q31_t)0xa16674b, (q31_t)0xdd82fdd8, (q31_t)0xa0fa2c3, (q31_t)0xdd8d9472, + (q31_t)0xa08e04f, (q31_t)0xdd982c60, (q31_t)0xa021fef, (q31_t)0xdda2c5a2, + (q31_t)0x9fb61a5, (q31_t)0xddad6036, (q31_t)0x9f4a570, (q31_t)0xddb7fc1e, + (q31_t)0x9edeb50, (q31_t)0xddc29958, (q31_t)0x9e73346, (q31_t)0xddcd37e4, + (q31_t)0x9e07d51, (q31_t)0xddd7d7c1, (q31_t)0x9d9c973, (q31_t)0xdde278ef, + (q31_t)0x9d317ab, (q31_t)0xdded1b6e, (q31_t)0x9cc67fa, (q31_t)0xddf7bf3e, + (q31_t)0x9c5ba60, (q31_t)0xde02645d, (q31_t)0x9bf0edd, (q31_t)0xde0d0acc, + (q31_t)0x9b86572, (q31_t)0xde17b28a, (q31_t)0x9b1be1e, (q31_t)0xde225b96, + (q31_t)0x9ab18e3, (q31_t)0xde2d05f1, (q31_t)0x9a475bf, (q31_t)0xde37b199, + (q31_t)0x99dd4b4, (q31_t)0xde425e8f, (q31_t)0x99735c2, (q31_t)0xde4d0cd2, + (q31_t)0x99098e9, (q31_t)0xde57bc62, (q31_t)0x989fe29, (q31_t)0xde626d3e, + (q31_t)0x9836582, (q31_t)0xde6d1f65, (q31_t)0x97ccef5, (q31_t)0xde77d2d8, + (q31_t)0x9763a83, (q31_t)0xde828796, (q31_t)0x96fa82a, (q31_t)0xde8d3d9e, + (q31_t)0x96917ec, (q31_t)0xde97f4f1, (q31_t)0x96289c9, (q31_t)0xdea2ad8d, + (q31_t)0x95bfdc1, (q31_t)0xdead6773, (q31_t)0x95573d4, (q31_t)0xdeb822a1, + (q31_t)0x94eec03, (q31_t)0xdec2df18, (q31_t)0x948664d, (q31_t)0xdecd9cd7, + (q31_t)0x941e2b4, (q31_t)0xded85bdd, (q31_t)0x93b6137, (q31_t)0xdee31c2b, + (q31_t)0x934e1d6, (q31_t)0xdeedddc0, (q31_t)0x92e6492, (q31_t)0xdef8a09b, + (q31_t)0x927e96b, (q31_t)0xdf0364bc, (q31_t)0x9217062, (q31_t)0xdf0e2a22, + (q31_t)0x91af976, (q31_t)0xdf18f0ce, (q31_t)0x91484a8, (q31_t)0xdf23b8be, + (q31_t)0x90e11f7, (q31_t)0xdf2e81f3, (q31_t)0x907a166, (q31_t)0xdf394c6b, + (q31_t)0x90132f2, (q31_t)0xdf441828, (q31_t)0x8fac69e, (q31_t)0xdf4ee527, + (q31_t)0x8f45c68, (q31_t)0xdf59b369, (q31_t)0x8edf452, (q31_t)0xdf6482ed, + (q31_t)0x8e78e5b, (q31_t)0xdf6f53b3, (q31_t)0x8e12a84, (q31_t)0xdf7a25ba, + (q31_t)0x8dac8cd, (q31_t)0xdf84f902, (q31_t)0x8d46936, (q31_t)0xdf8fcd8b, + (q31_t)0x8ce0bc0, (q31_t)0xdf9aa354, (q31_t)0x8c7b06b, (q31_t)0xdfa57a5d, + (q31_t)0x8c15736, (q31_t)0xdfb052a5, (q31_t)0x8bb0023, (q31_t)0xdfbb2c2c, + (q31_t)0x8b4ab32, (q31_t)0xdfc606f1, (q31_t)0x8ae5862, (q31_t)0xdfd0e2f5, + (q31_t)0x8a807b4, (q31_t)0xdfdbc036, (q31_t)0x8a1b928, (q31_t)0xdfe69eb4, + (q31_t)0x89b6cbf, (q31_t)0xdff17e70, (q31_t)0x8952278, (q31_t)0xdffc5f67, + (q31_t)0x88eda54, (q31_t)0xe007419b, (q31_t)0x8889454, (q31_t)0xe012250a, + (q31_t)0x8825077, (q31_t)0xe01d09b4, (q31_t)0x87c0ebd, (q31_t)0xe027ef99, + (q31_t)0x875cf28, (q31_t)0xe032d6b8, (q31_t)0x86f91b7, (q31_t)0xe03dbf11, + (q31_t)0x869566a, (q31_t)0xe048a8a4, (q31_t)0x8631d42, (q31_t)0xe053936f, + (q31_t)0x85ce63e, (q31_t)0xe05e7f74, (q31_t)0x856b160, (q31_t)0xe0696cb0, + (q31_t)0x8507ea7, (q31_t)0xe0745b24, (q31_t)0x84a4e14, (q31_t)0xe07f4acf, + (q31_t)0x8441fa6, (q31_t)0xe08a3bb2, (q31_t)0x83df35f, (q31_t)0xe0952dcb, + (q31_t)0x837c93e, (q31_t)0xe0a0211a, (q31_t)0x831a143, (q31_t)0xe0ab159e, + (q31_t)0x82b7b70, (q31_t)0xe0b60b58, (q31_t)0x82557c3, (q31_t)0xe0c10247, + (q31_t)0x81f363d, (q31_t)0xe0cbfa6a, (q31_t)0x81916df, (q31_t)0xe0d6f3c1, + (q31_t)0x812f9a9, (q31_t)0xe0e1ee4b, (q31_t)0x80cde9b, (q31_t)0xe0ecea09, + (q31_t)0x806c5b5, (q31_t)0xe0f7e6f9, (q31_t)0x800aef7, (q31_t)0xe102e51c, + (q31_t)0x7fa9a62, (q31_t)0xe10de470, (q31_t)0x7f487f6, (q31_t)0xe118e4f6, + (q31_t)0x7ee77b3, (q31_t)0xe123e6ad, (q31_t)0x7e8699a, (q31_t)0xe12ee995, + (q31_t)0x7e25daa, (q31_t)0xe139edac, (q31_t)0x7dc53e3, (q31_t)0xe144f2f3, + (q31_t)0x7d64c47, (q31_t)0xe14ff96a, (q31_t)0x7d046d6, (q31_t)0xe15b0110, + (q31_t)0x7ca438f, (q31_t)0xe16609e3, (q31_t)0x7c44272, (q31_t)0xe17113e5, + (q31_t)0x7be4381, (q31_t)0xe17c1f15, (q31_t)0x7b846ba, (q31_t)0xe1872b72, + (q31_t)0x7b24c20, (q31_t)0xe19238fb, (q31_t)0x7ac53b1, (q31_t)0xe19d47b1, + (q31_t)0x7a65d6e, (q31_t)0xe1a85793, (q31_t)0x7a06957, (q31_t)0xe1b368a0, + (q31_t)0x79a776c, (q31_t)0xe1be7ad8, (q31_t)0x79487ae, (q31_t)0xe1c98e3b, + (q31_t)0x78e9a1d, (q31_t)0xe1d4a2c8, (q31_t)0x788aeb9, (q31_t)0xe1dfb87f, + (q31_t)0x782c582, (q31_t)0xe1eacf5f, (q31_t)0x77cde79, (q31_t)0xe1f5e768, + (q31_t)0x776f99d, (q31_t)0xe2010099, (q31_t)0x77116f0, (q31_t)0xe20c1af3, + (q31_t)0x76b3671, (q31_t)0xe2173674, (q31_t)0x7655820, (q31_t)0xe222531c, + (q31_t)0x75f7bfe, (q31_t)0xe22d70eb, (q31_t)0x759a20a, (q31_t)0xe2388fe1, + (q31_t)0x753ca46, (q31_t)0xe243affc, (q31_t)0x74df4b1, (q31_t)0xe24ed13d, + (q31_t)0x748214c, (q31_t)0xe259f3a3, (q31_t)0x7425016, (q31_t)0xe265172e, + (q31_t)0x73c8111, (q31_t)0xe2703bdc, (q31_t)0x736b43c, (q31_t)0xe27b61af, + (q31_t)0x730e997, (q31_t)0xe28688a4, (q31_t)0x72b2123, (q31_t)0xe291b0bd, + (q31_t)0x7255ae0, (q31_t)0xe29cd9f8, (q31_t)0x71f96ce, (q31_t)0xe2a80456, + (q31_t)0x719d4ed, (q31_t)0xe2b32fd4, (q31_t)0x714153e, (q31_t)0xe2be5c74, + (q31_t)0x70e57c0, (q31_t)0xe2c98a35, (q31_t)0x7089c75, (q31_t)0xe2d4b916, + (q31_t)0x702e35c, (q31_t)0xe2dfe917, (q31_t)0x6fd2c75, (q31_t)0xe2eb1a37, + (q31_t)0x6f777c1, (q31_t)0xe2f64c77, (q31_t)0x6f1c540, (q31_t)0xe3017fd5, + (q31_t)0x6ec14f2, (q31_t)0xe30cb451, (q31_t)0x6e666d7, (q31_t)0xe317e9eb, + (q31_t)0x6e0baf0, (q31_t)0xe32320a2, (q31_t)0x6db113d, (q31_t)0xe32e5876, + (q31_t)0x6d569be, (q31_t)0xe3399167, (q31_t)0x6cfc472, (q31_t)0xe344cb73, + (q31_t)0x6ca215c, (q31_t)0xe350069b, (q31_t)0x6c4807a, (q31_t)0xe35b42df, + (q31_t)0x6bee1cd, (q31_t)0xe366803c, (q31_t)0x6b94554, (q31_t)0xe371beb5, + (q31_t)0x6b3ab12, (q31_t)0xe37cfe47, (q31_t)0x6ae1304, (q31_t)0xe3883ef2, + (q31_t)0x6a87d2d, (q31_t)0xe39380b6, (q31_t)0x6a2e98b, (q31_t)0xe39ec393, + (q31_t)0x69d5820, (q31_t)0xe3aa0788, (q31_t)0x697c8eb, (q31_t)0xe3b54c95, + (q31_t)0x6923bec, (q31_t)0xe3c092b9, (q31_t)0x68cb124, (q31_t)0xe3cbd9f4, + (q31_t)0x6872894, (q31_t)0xe3d72245, (q31_t)0x681a23a, (q31_t)0xe3e26bac, + (q31_t)0x67c1e18, (q31_t)0xe3edb628, (q31_t)0x6769c2e, (q31_t)0xe3f901ba, + (q31_t)0x6711c7b, (q31_t)0xe4044e60, (q31_t)0x66b9f01, (q31_t)0xe40f9c1a, + (q31_t)0x66623be, (q31_t)0xe41aeae8, (q31_t)0x660aab5, (q31_t)0xe4263ac9, + (q31_t)0x65b33e4, (q31_t)0xe4318bbe, (q31_t)0x655bf4c, (q31_t)0xe43cddc4, + (q31_t)0x6504ced, (q31_t)0xe44830dd, (q31_t)0x64adcc7, (q31_t)0xe4538507, + (q31_t)0x6456edb, (q31_t)0xe45eda43, (q31_t)0x6400329, (q31_t)0xe46a308f, + (q31_t)0x63a99b1, (q31_t)0xe47587eb, (q31_t)0x6353273, (q31_t)0xe480e057, + (q31_t)0x62fcd6f, (q31_t)0xe48c39d3, (q31_t)0x62a6aa6, (q31_t)0xe497945d, + (q31_t)0x6250a18, (q31_t)0xe4a2eff6, (q31_t)0x61fabc4, (q31_t)0xe4ae4c9d, + (q31_t)0x61a4fac, (q31_t)0xe4b9aa52, (q31_t)0x614f5cf, (q31_t)0xe4c50914, + (q31_t)0x60f9e2e, (q31_t)0xe4d068e2, (q31_t)0x60a48c9, (q31_t)0xe4dbc9bd, + (q31_t)0x604f5a0, (q31_t)0xe4e72ba4, (q31_t)0x5ffa4b3, (q31_t)0xe4f28e96, + (q31_t)0x5fa5603, (q31_t)0xe4fdf294, (q31_t)0x5f5098f, (q31_t)0xe509579b, + (q31_t)0x5efbf58, (q31_t)0xe514bdad, (q31_t)0x5ea775e, (q31_t)0xe52024c9, + (q31_t)0x5e531a1, (q31_t)0xe52b8cee, (q31_t)0x5dfee22, (q31_t)0xe536f61b, + (q31_t)0x5daace1, (q31_t)0xe5426051, (q31_t)0x5d56ddd, (q31_t)0xe54dcb8f, + (q31_t)0x5d03118, (q31_t)0xe55937d5, (q31_t)0x5caf690, (q31_t)0xe564a521, + (q31_t)0x5c5be47, (q31_t)0xe5701374, (q31_t)0x5c0883d, (q31_t)0xe57b82cd, + (q31_t)0x5bb5472, (q31_t)0xe586f32c, (q31_t)0x5b622e6, (q31_t)0xe5926490, + (q31_t)0x5b0f399, (q31_t)0xe59dd6f9, (q31_t)0x5abc68c, (q31_t)0xe5a94a67, + (q31_t)0x5a69bbe, (q31_t)0xe5b4bed8, (q31_t)0x5a17330, (q31_t)0xe5c0344d, + (q31_t)0x59c4ce3, (q31_t)0xe5cbaac5, (q31_t)0x59728d5, (q31_t)0xe5d72240, + (q31_t)0x5920708, (q31_t)0xe5e29abc, (q31_t)0x58ce77c, (q31_t)0xe5ee143b, + (q31_t)0x587ca31, (q31_t)0xe5f98ebb, (q31_t)0x582af26, (q31_t)0xe6050a3b, + (q31_t)0x57d965d, (q31_t)0xe61086bc, (q31_t)0x5787fd6, (q31_t)0xe61c043d, + (q31_t)0x5736b90, (q31_t)0xe62782be, (q31_t)0x56e598c, (q31_t)0xe633023e, + (q31_t)0x56949ca, (q31_t)0xe63e82bc, (q31_t)0x5643c4a, (q31_t)0xe64a0438, + (q31_t)0x55f310d, (q31_t)0xe65586b3, (q31_t)0x55a2812, (q31_t)0xe6610a2a, + (q31_t)0x555215a, (q31_t)0xe66c8e9f, (q31_t)0x5501ce5, (q31_t)0xe6781410, + (q31_t)0x54b1ab4, (q31_t)0xe6839a7c, (q31_t)0x5461ac6, (q31_t)0xe68f21e5, + (q31_t)0x5411d1b, (q31_t)0xe69aaa48, (q31_t)0x53c21b4, (q31_t)0xe6a633a6, + (q31_t)0x5372891, (q31_t)0xe6b1bdff, (q31_t)0x53231b3, (q31_t)0xe6bd4951, + (q31_t)0x52d3d18, (q31_t)0xe6c8d59c, (q31_t)0x5284ac3, (q31_t)0xe6d462e1, + (q31_t)0x5235ab2, (q31_t)0xe6dff11d, (q31_t)0x51e6ce6, (q31_t)0xe6eb8052, + (q31_t)0x519815f, (q31_t)0xe6f7107e, (q31_t)0x514981d, (q31_t)0xe702a1a1, + (q31_t)0x50fb121, (q31_t)0xe70e33bb, (q31_t)0x50acc6b, (q31_t)0xe719c6cb, + (q31_t)0x505e9fb, (q31_t)0xe7255ad1, (q31_t)0x50109d0, (q31_t)0xe730efcc, + (q31_t)0x4fc2bec, (q31_t)0xe73c85bc, (q31_t)0x4f7504e, (q31_t)0xe7481ca1, + (q31_t)0x4f276f7, (q31_t)0xe753b479, (q31_t)0x4ed9fe7, (q31_t)0xe75f4d45, + (q31_t)0x4e8cb1e, (q31_t)0xe76ae704, (q31_t)0x4e3f89c, (q31_t)0xe77681b6, + (q31_t)0x4df2862, (q31_t)0xe7821d59, (q31_t)0x4da5a6f, (q31_t)0xe78db9ef, + (q31_t)0x4d58ec3, (q31_t)0xe7995776, (q31_t)0x4d0c560, (q31_t)0xe7a4f5ed, + (q31_t)0x4cbfe45, (q31_t)0xe7b09555, (q31_t)0x4c73972, (q31_t)0xe7bc35ad, + (q31_t)0x4c276e8, (q31_t)0xe7c7d6f4, (q31_t)0x4bdb6a6, (q31_t)0xe7d3792b, + (q31_t)0x4b8f8ad, (q31_t)0xe7df1c50, (q31_t)0x4b43cfd, (q31_t)0xe7eac063, + (q31_t)0x4af8397, (q31_t)0xe7f66564, (q31_t)0x4aacc7a, (q31_t)0xe8020b52, + (q31_t)0x4a617a6, (q31_t)0xe80db22d, (q31_t)0x4a1651c, (q31_t)0xe81959f4, + (q31_t)0x49cb4dd, (q31_t)0xe82502a7, (q31_t)0x49806e7, (q31_t)0xe830ac45, + (q31_t)0x4935b3c, (q31_t)0xe83c56cf, (q31_t)0x48eb1db, (q31_t)0xe8480243, + (q31_t)0x48a0ac4, (q31_t)0xe853aea1, (q31_t)0x48565f9, (q31_t)0xe85f5be9, + (q31_t)0x480c379, (q31_t)0xe86b0a1a, (q31_t)0x47c2344, (q31_t)0xe876b934, + (q31_t)0x477855a, (q31_t)0xe8826936, (q31_t)0x472e9bc, (q31_t)0xe88e1a20, + (q31_t)0x46e5069, (q31_t)0xe899cbf1, (q31_t)0x469b963, (q31_t)0xe8a57ea9, + (q31_t)0x46524a9, (q31_t)0xe8b13248, (q31_t)0x460923b, (q31_t)0xe8bce6cd, + (q31_t)0x45c0219, (q31_t)0xe8c89c37, (q31_t)0x4577444, (q31_t)0xe8d45286, + (q31_t)0x452e8bc, (q31_t)0xe8e009ba, (q31_t)0x44e5f80, (q31_t)0xe8ebc1d3, + (q31_t)0x449d892, (q31_t)0xe8f77acf, (q31_t)0x44553f2, (q31_t)0xe90334af, + (q31_t)0x440d19e, (q31_t)0xe90eef71, (q31_t)0x43c5199, (q31_t)0xe91aab16, + (q31_t)0x437d3e1, (q31_t)0xe926679c, (q31_t)0x4335877, (q31_t)0xe9322505, + (q31_t)0x42edf5c, (q31_t)0xe93de34e, (q31_t)0x42a688f, (q31_t)0xe949a278, + (q31_t)0x425f410, (q31_t)0xe9556282, (q31_t)0x42181e0, (q31_t)0xe961236c, + (q31_t)0x41d11ff, (q31_t)0xe96ce535, (q31_t)0x418a46d, (q31_t)0xe978a7dd, + (q31_t)0x414392b, (q31_t)0xe9846b63, (q31_t)0x40fd037, (q31_t)0xe9902fc7, + (q31_t)0x40b6994, (q31_t)0xe99bf509, (q31_t)0x4070540, (q31_t)0xe9a7bb28, + (q31_t)0x402a33c, (q31_t)0xe9b38223, (q31_t)0x3fe4388, (q31_t)0xe9bf49fa, + (q31_t)0x3f9e624, (q31_t)0xe9cb12ad, (q31_t)0x3f58b10, (q31_t)0xe9d6dc3b, + (q31_t)0x3f1324e, (q31_t)0xe9e2a6a3, (q31_t)0x3ecdbdc, (q31_t)0xe9ee71e6, + (q31_t)0x3e887bb, (q31_t)0xe9fa3e03, (q31_t)0x3e435ea, (q31_t)0xea060af9, + (q31_t)0x3dfe66c, (q31_t)0xea11d8c8, (q31_t)0x3db993e, (q31_t)0xea1da770, + (q31_t)0x3d74e62, (q31_t)0xea2976ef, (q31_t)0x3d305d8, (q31_t)0xea354746, + (q31_t)0x3cebfa0, (q31_t)0xea411874, (q31_t)0x3ca7bba, (q31_t)0xea4cea79, + (q31_t)0x3c63a26, (q31_t)0xea58bd54, (q31_t)0x3c1fae5, (q31_t)0xea649105, + (q31_t)0x3bdbdf6, (q31_t)0xea70658a, (q31_t)0x3b9835a, (q31_t)0xea7c3ae5, + (q31_t)0x3b54b11, (q31_t)0xea881114, (q31_t)0x3b1151b, (q31_t)0xea93e817, + (q31_t)0x3ace178, (q31_t)0xea9fbfed, (q31_t)0x3a8b028, (q31_t)0xeaab9896, + (q31_t)0x3a4812c, (q31_t)0xeab77212, (q31_t)0x3a05484, (q31_t)0xeac34c60, + (q31_t)0x39c2a2f, (q31_t)0xeacf277f, (q31_t)0x398022f, (q31_t)0xeadb0370, + (q31_t)0x393dc82, (q31_t)0xeae6e031, (q31_t)0x38fb92a, (q31_t)0xeaf2bdc3, + (q31_t)0x38b9827, (q31_t)0xeafe9c24, (q31_t)0x3877978, (q31_t)0xeb0a7b54, + (q31_t)0x3835d1e, (q31_t)0xeb165b54, (q31_t)0x37f4319, (q31_t)0xeb223c22, + (q31_t)0x37b2b6a, (q31_t)0xeb2e1dbe, (q31_t)0x377160f, (q31_t)0xeb3a0027, + (q31_t)0x373030a, (q31_t)0xeb45e35d, (q31_t)0x36ef25b, (q31_t)0xeb51c760, + (q31_t)0x36ae401, (q31_t)0xeb5dac2f, (q31_t)0x366d7fd, (q31_t)0xeb6991ca, + (q31_t)0x362ce50, (q31_t)0xeb75782f, (q31_t)0x35ec6f8, (q31_t)0xeb815f60, + (q31_t)0x35ac1f7, (q31_t)0xeb8d475b, (q31_t)0x356bf4d, (q31_t)0xeb99301f, + (q31_t)0x352bef9, (q31_t)0xeba519ad, (q31_t)0x34ec0fc, (q31_t)0xebb10404, + (q31_t)0x34ac556, (q31_t)0xebbcef23, (q31_t)0x346cc07, (q31_t)0xebc8db0b, + (q31_t)0x342d510, (q31_t)0xebd4c7ba, (q31_t)0x33ee070, (q31_t)0xebe0b52f, + (q31_t)0x33aee27, (q31_t)0xebeca36c, (q31_t)0x336fe37, (q31_t)0xebf8926f, + (q31_t)0x333109e, (q31_t)0xec048237, (q31_t)0x32f255e, (q31_t)0xec1072c4, + (q31_t)0x32b3c75, (q31_t)0xec1c6417, (q31_t)0x32755e5, (q31_t)0xec28562d, + (q31_t)0x32371ae, (q31_t)0xec344908, (q31_t)0x31f8fcf, (q31_t)0xec403ca5, + (q31_t)0x31bb049, (q31_t)0xec4c3106, (q31_t)0x317d31c, (q31_t)0xec582629, + (q31_t)0x313f848, (q31_t)0xec641c0e, (q31_t)0x3101fce, (q31_t)0xec7012b5, + (q31_t)0x30c49ad, (q31_t)0xec7c0a1d, (q31_t)0x30875e5, (q31_t)0xec880245, + (q31_t)0x304a477, (q31_t)0xec93fb2e, (q31_t)0x300d563, (q31_t)0xec9ff4d6, + (q31_t)0x2fd08a9, (q31_t)0xecabef3d, (q31_t)0x2f93e4a, (q31_t)0xecb7ea63, + (q31_t)0x2f57644, (q31_t)0xecc3e648, (q31_t)0x2f1b099, (q31_t)0xeccfe2ea, + (q31_t)0x2eded49, (q31_t)0xecdbe04a, (q31_t)0x2ea2c53, (q31_t)0xece7de66, + (q31_t)0x2e66db8, (q31_t)0xecf3dd3f, (q31_t)0x2e2b178, (q31_t)0xecffdcd4, + (q31_t)0x2def794, (q31_t)0xed0bdd25, (q31_t)0x2db400a, (q31_t)0xed17de31, + (q31_t)0x2d78add, (q31_t)0xed23dff7, (q31_t)0x2d3d80a, (q31_t)0xed2fe277, + (q31_t)0x2d02794, (q31_t)0xed3be5b1, (q31_t)0x2cc7979, (q31_t)0xed47e9a5, + (q31_t)0x2c8cdbb, (q31_t)0xed53ee51, (q31_t)0x2c52459, (q31_t)0xed5ff3b5, + (q31_t)0x2c17d52, (q31_t)0xed6bf9d1, (q31_t)0x2bdd8a9, (q31_t)0xed7800a5, + (q31_t)0x2ba365c, (q31_t)0xed84082f, (q31_t)0x2b6966c, (q31_t)0xed901070, + (q31_t)0x2b2f8d8, (q31_t)0xed9c1967, (q31_t)0x2af5da2, (q31_t)0xeda82313, + (q31_t)0x2abc4c9, (q31_t)0xedb42d74, (q31_t)0x2a82e4d, (q31_t)0xedc0388a, + (q31_t)0x2a49a2e, (q31_t)0xedcc4454, (q31_t)0x2a1086d, (q31_t)0xedd850d2, + (q31_t)0x29d790a, (q31_t)0xede45e03, (q31_t)0x299ec05, (q31_t)0xedf06be6, + (q31_t)0x296615d, (q31_t)0xedfc7a7c, (q31_t)0x292d914, (q31_t)0xee0889c4, + (q31_t)0x28f5329, (q31_t)0xee1499bd, (q31_t)0x28bcf9c, (q31_t)0xee20aa67, + (q31_t)0x2884e6e, (q31_t)0xee2cbbc1, (q31_t)0x284cf9f, (q31_t)0xee38cdcb, + (q31_t)0x281532e, (q31_t)0xee44e084, (q31_t)0x27dd91c, (q31_t)0xee50f3ed, + (q31_t)0x27a616a, (q31_t)0xee5d0804, (q31_t)0x276ec16, (q31_t)0xee691cc9, + (q31_t)0x2737922, (q31_t)0xee75323c, (q31_t)0x270088e, (q31_t)0xee81485c, + (q31_t)0x26c9a58, (q31_t)0xee8d5f29, (q31_t)0x2692e83, (q31_t)0xee9976a1, + (q31_t)0x265c50e, (q31_t)0xeea58ec6, (q31_t)0x2625df8, (q31_t)0xeeb1a796, + (q31_t)0x25ef943, (q31_t)0xeebdc110, (q31_t)0x25b96ee, (q31_t)0xeec9db35, + (q31_t)0x25836f9, (q31_t)0xeed5f604, (q31_t)0x254d965, (q31_t)0xeee2117c, + (q31_t)0x2517e31, (q31_t)0xeeee2d9d, (q31_t)0x24e255e, (q31_t)0xeefa4a67, + (q31_t)0x24aceed, (q31_t)0xef0667d9, (q31_t)0x2477adc, (q31_t)0xef1285f2, + (q31_t)0x244292c, (q31_t)0xef1ea4b2, (q31_t)0x240d9de, (q31_t)0xef2ac419, + (q31_t)0x23d8cf1, (q31_t)0xef36e426, (q31_t)0x23a4265, (q31_t)0xef4304d8, + (q31_t)0x236fa3b, (q31_t)0xef4f2630, (q31_t)0x233b473, (q31_t)0xef5b482d, + (q31_t)0x230710d, (q31_t)0xef676ace, (q31_t)0x22d3009, (q31_t)0xef738e12, + (q31_t)0x229f167, (q31_t)0xef7fb1fa, (q31_t)0x226b528, (q31_t)0xef8bd685, + (q31_t)0x2237b4b, (q31_t)0xef97fbb2, (q31_t)0x22043d0, (q31_t)0xefa42181, + (q31_t)0x21d0eb8, (q31_t)0xefb047f2, (q31_t)0x219dc03, (q31_t)0xefbc6f03, + (q31_t)0x216abb1, (q31_t)0xefc896b5, (q31_t)0x2137dc2, (q31_t)0xefd4bf08, + (q31_t)0x2105236, (q31_t)0xefe0e7f9, (q31_t)0x20d290d, (q31_t)0xefed118a, + (q31_t)0x20a0248, (q31_t)0xeff93bba, (q31_t)0x206dde6, (q31_t)0xf0056687, + (q31_t)0x203bbe8, (q31_t)0xf01191f3, (q31_t)0x2009c4e, (q31_t)0xf01dbdfb, + (q31_t)0x1fd7f17, (q31_t)0xf029eaa1, (q31_t)0x1fa6445, (q31_t)0xf03617e2, + (q31_t)0x1f74bd6, (q31_t)0xf04245c0, (q31_t)0x1f435cc, (q31_t)0xf04e7438, + (q31_t)0x1f12227, (q31_t)0xf05aa34c, (q31_t)0x1ee10e5, (q31_t)0xf066d2fa, + (q31_t)0x1eb0209, (q31_t)0xf0730342, (q31_t)0x1e7f591, (q31_t)0xf07f3424, + (q31_t)0x1e4eb7e, (q31_t)0xf08b659f, (q31_t)0x1e1e3d0, (q31_t)0xf09797b2, + (q31_t)0x1dede87, (q31_t)0xf0a3ca5d, (q31_t)0x1dbdba3, (q31_t)0xf0affda0, + (q31_t)0x1d8db25, (q31_t)0xf0bc317a, (q31_t)0x1d5dd0c, (q31_t)0xf0c865ea, + (q31_t)0x1d2e158, (q31_t)0xf0d49af1, (q31_t)0x1cfe80a, (q31_t)0xf0e0d08d, + (q31_t)0x1ccf122, (q31_t)0xf0ed06bf, (q31_t)0x1c9fca0, (q31_t)0xf0f93d86, + (q31_t)0x1c70a84, (q31_t)0xf10574e0, (q31_t)0x1c41ace, (q31_t)0xf111accf, + (q31_t)0x1c12d7e, (q31_t)0xf11de551, (q31_t)0x1be4294, (q31_t)0xf12a1e66, + (q31_t)0x1bb5a11, (q31_t)0xf136580d, (q31_t)0x1b873f5, (q31_t)0xf1429247, + (q31_t)0x1b5903f, (q31_t)0xf14ecd11, (q31_t)0x1b2aef0, (q31_t)0xf15b086d, + (q31_t)0x1afd007, (q31_t)0xf1674459, (q31_t)0x1acf386, (q31_t)0xf17380d6, + (q31_t)0x1aa196c, (q31_t)0xf17fbde2, (q31_t)0x1a741b9, (q31_t)0xf18bfb7d, + (q31_t)0x1a46c6e, (q31_t)0xf19839a6, (q31_t)0x1a1998a, (q31_t)0xf1a4785e, + (q31_t)0x19ec90d, (q31_t)0xf1b0b7a4, (q31_t)0x19bfaf9, (q31_t)0xf1bcf777, + (q31_t)0x1992f4c, (q31_t)0xf1c937d6, (q31_t)0x1966606, (q31_t)0xf1d578c2, + (q31_t)0x1939f29, (q31_t)0xf1e1ba3a, (q31_t)0x190dab4, (q31_t)0xf1edfc3d, + (q31_t)0x18e18a7, (q31_t)0xf1fa3ecb, (q31_t)0x18b5903, (q31_t)0xf20681e3, + (q31_t)0x1889bc6, (q31_t)0xf212c585, (q31_t)0x185e0f3, (q31_t)0xf21f09b1, + (q31_t)0x1832888, (q31_t)0xf22b4e66, (q31_t)0x1807285, (q31_t)0xf23793a3, + (q31_t)0x17dbeec, (q31_t)0xf243d968, (q31_t)0x17b0dbb, (q31_t)0xf2501fb5, + (q31_t)0x1785ef4, (q31_t)0xf25c6688, (q31_t)0x175b296, (q31_t)0xf268ade3, + (q31_t)0x17308a1, (q31_t)0xf274f5c3, (q31_t)0x1706115, (q31_t)0xf2813e2a, + (q31_t)0x16dbbf3, (q31_t)0xf28d8715, (q31_t)0x16b193a, (q31_t)0xf299d085, + (q31_t)0x16878eb, (q31_t)0xf2a61a7a, (q31_t)0x165db05, (q31_t)0xf2b264f2, + (q31_t)0x1633f8a, (q31_t)0xf2beafed, (q31_t)0x160a678, (q31_t)0xf2cafb6b, + (q31_t)0x15e0fd1, (q31_t)0xf2d7476c, (q31_t)0x15b7b94, (q31_t)0xf2e393ef, + (q31_t)0x158e9c1, (q31_t)0xf2efe0f2, (q31_t)0x1565a58, (q31_t)0xf2fc2e77, + (q31_t)0x153cd5a, (q31_t)0xf3087c7d, (q31_t)0x15142c6, (q31_t)0xf314cb02, + (q31_t)0x14eba9d, (q31_t)0xf3211a07, (q31_t)0x14c34df, (q31_t)0xf32d698a, + (q31_t)0x149b18b, (q31_t)0xf339b98d, (q31_t)0x14730a3, (q31_t)0xf3460a0d, + (q31_t)0x144b225, (q31_t)0xf3525b0b, (q31_t)0x1423613, (q31_t)0xf35eac86, + (q31_t)0x13fbc6c, (q31_t)0xf36afe7e, (q31_t)0x13d4530, (q31_t)0xf37750f2, + (q31_t)0x13ad060, (q31_t)0xf383a3e2, (q31_t)0x1385dfb, (q31_t)0xf38ff74d, + (q31_t)0x135ee02, (q31_t)0xf39c4b32, (q31_t)0x1338075, (q31_t)0xf3a89f92, + (q31_t)0x1311553, (q31_t)0xf3b4f46c, (q31_t)0x12eac9d, (q31_t)0xf3c149bf, + (q31_t)0x12c4653, (q31_t)0xf3cd9f8b, (q31_t)0x129e276, (q31_t)0xf3d9f5cf, + (q31_t)0x1278104, (q31_t)0xf3e64c8c, (q31_t)0x12521ff, (q31_t)0xf3f2a3bf, + (q31_t)0x122c566, (q31_t)0xf3fefb6a, (q31_t)0x1206b39, (q31_t)0xf40b538b, + (q31_t)0x11e1379, (q31_t)0xf417ac22, (q31_t)0x11bbe26, (q31_t)0xf424052f, + (q31_t)0x1196b3f, (q31_t)0xf4305eb0, (q31_t)0x1171ac6, (q31_t)0xf43cb8a7, + (q31_t)0x114ccb9, (q31_t)0xf4491311, (q31_t)0x1128119, (q31_t)0xf4556def, + (q31_t)0x11037e6, (q31_t)0xf461c940, (q31_t)0x10df120, (q31_t)0xf46e2504, + (q31_t)0x10bacc8, (q31_t)0xf47a8139, (q31_t)0x1096add, (q31_t)0xf486dde1, + (q31_t)0x1072b5f, (q31_t)0xf4933afa, (q31_t)0x104ee4f, (q31_t)0xf49f9884, + (q31_t)0x102b3ac, (q31_t)0xf4abf67e, (q31_t)0x1007b77, (q31_t)0xf4b854e7, + (q31_t)0xfe45b0, (q31_t)0xf4c4b3c0, (q31_t)0xfc1257, (q31_t)0xf4d11308, + (q31_t)0xf9e16b, (q31_t)0xf4dd72be, (q31_t)0xf7b2ee, (q31_t)0xf4e9d2e3, + (q31_t)0xf586df, (q31_t)0xf4f63374, (q31_t)0xf35d3e, (q31_t)0xf5029473, + (q31_t)0xf1360b, (q31_t)0xf50ef5de, (q31_t)0xef1147, (q31_t)0xf51b57b5, + (q31_t)0xeceef1, (q31_t)0xf527b9f7, (q31_t)0xeacf09, (q31_t)0xf5341ca5, + (q31_t)0xe8b190, (q31_t)0xf5407fbd, (q31_t)0xe69686, (q31_t)0xf54ce33f, + (q31_t)0xe47deb, (q31_t)0xf559472b, (q31_t)0xe267be, (q31_t)0xf565ab80, + (q31_t)0xe05401, (q31_t)0xf572103d, (q31_t)0xde42b2, (q31_t)0xf57e7563, + (q31_t)0xdc33d2, (q31_t)0xf58adaf0, (q31_t)0xda2762, (q31_t)0xf59740e5, + (q31_t)0xd81d61, (q31_t)0xf5a3a740, (q31_t)0xd615cf, (q31_t)0xf5b00e02, + (q31_t)0xd410ad, (q31_t)0xf5bc7529, (q31_t)0xd20dfa, (q31_t)0xf5c8dcb6, + (q31_t)0xd00db6, (q31_t)0xf5d544a7, (q31_t)0xce0fe3, (q31_t)0xf5e1acfd, + (q31_t)0xcc147f, (q31_t)0xf5ee15b7, (q31_t)0xca1b8a, (q31_t)0xf5fa7ed4, + (q31_t)0xc82506, (q31_t)0xf606e854, (q31_t)0xc630f2, (q31_t)0xf6135237, + (q31_t)0xc43f4d, (q31_t)0xf61fbc7b, (q31_t)0xc25019, (q31_t)0xf62c2721, + (q31_t)0xc06355, (q31_t)0xf6389228, (q31_t)0xbe7901, (q31_t)0xf644fd8f, + (q31_t)0xbc911d, (q31_t)0xf6516956, (q31_t)0xbaabaa, (q31_t)0xf65dd57d, + (q31_t)0xb8c8a7, (q31_t)0xf66a4203, (q31_t)0xb6e815, (q31_t)0xf676aee8, + (q31_t)0xb509f3, (q31_t)0xf6831c2b, (q31_t)0xb32e42, (q31_t)0xf68f89cb, + (q31_t)0xb15502, (q31_t)0xf69bf7c9, (q31_t)0xaf7e33, (q31_t)0xf6a86623, + (q31_t)0xada9d4, (q31_t)0xf6b4d4d9, (q31_t)0xabd7e6, (q31_t)0xf6c143ec, + (q31_t)0xaa086a, (q31_t)0xf6cdb359, (q31_t)0xa83b5e, (q31_t)0xf6da2321, + (q31_t)0xa670c4, (q31_t)0xf6e69344, (q31_t)0xa4a89b, (q31_t)0xf6f303c0, + (q31_t)0xa2e2e3, (q31_t)0xf6ff7496, (q31_t)0xa11f9d, (q31_t)0xf70be5c4, + (q31_t)0x9f5ec8, (q31_t)0xf718574b, (q31_t)0x9da065, (q31_t)0xf724c92a, + (q31_t)0x9be473, (q31_t)0xf7313b60, (q31_t)0x9a2af3, (q31_t)0xf73daded, + (q31_t)0x9873e4, (q31_t)0xf74a20d0, (q31_t)0x96bf48, (q31_t)0xf756940a, + (q31_t)0x950d1d, (q31_t)0xf7630799, (q31_t)0x935d64, (q31_t)0xf76f7b7d, + (q31_t)0x91b01d, (q31_t)0xf77befb5, (q31_t)0x900548, (q31_t)0xf7886442, + (q31_t)0x8e5ce5, (q31_t)0xf794d922, (q31_t)0x8cb6f5, (q31_t)0xf7a14e55, + (q31_t)0x8b1376, (q31_t)0xf7adc3db, (q31_t)0x89726a, (q31_t)0xf7ba39b3, + (q31_t)0x87d3d0, (q31_t)0xf7c6afdc, (q31_t)0x8637a9, (q31_t)0xf7d32657, + (q31_t)0x849df4, (q31_t)0xf7df9d22, (q31_t)0x8306b2, (q31_t)0xf7ec143e, + (q31_t)0x8171e2, (q31_t)0xf7f88ba9, (q31_t)0x7fdf85, (q31_t)0xf8050364, + (q31_t)0x7e4f9b, (q31_t)0xf8117b6d, (q31_t)0x7cc223, (q31_t)0xf81df3c5, + (q31_t)0x7b371e, (q31_t)0xf82a6c6a, (q31_t)0x79ae8c, (q31_t)0xf836e55d, + (q31_t)0x78286e, (q31_t)0xf8435e9d, (q31_t)0x76a4c2, (q31_t)0xf84fd829, + (q31_t)0x752389, (q31_t)0xf85c5201, (q31_t)0x73a4c3, (q31_t)0xf868cc24, + (q31_t)0x722871, (q31_t)0xf8754692, (q31_t)0x70ae92, (q31_t)0xf881c14b, + (q31_t)0x6f3726, (q31_t)0xf88e3c4d, (q31_t)0x6dc22e, (q31_t)0xf89ab799, + (q31_t)0x6c4fa8, (q31_t)0xf8a7332e, (q31_t)0x6adf97, (q31_t)0xf8b3af0c, + (q31_t)0x6971f9, (q31_t)0xf8c02b31, (q31_t)0x6806ce, (q31_t)0xf8cca79e, + (q31_t)0x669e18, (q31_t)0xf8d92452, (q31_t)0x6537d4, (q31_t)0xf8e5a14d, + (q31_t)0x63d405, (q31_t)0xf8f21e8e, (q31_t)0x6272aa, (q31_t)0xf8fe9c15, + (q31_t)0x6113c2, (q31_t)0xf90b19e0, (q31_t)0x5fb74e, (q31_t)0xf91797f0, + (q31_t)0x5e5d4e, (q31_t)0xf9241645, (q31_t)0x5d05c3, (q31_t)0xf93094dd, + (q31_t)0x5bb0ab, (q31_t)0xf93d13b8, (q31_t)0x5a5e07, (q31_t)0xf94992d7, + (q31_t)0x590dd8, (q31_t)0xf9561237, (q31_t)0x57c01d, (q31_t)0xf96291d9, + (q31_t)0x5674d6, (q31_t)0xf96f11bc, (q31_t)0x552c03, (q31_t)0xf97b91e1, + (q31_t)0x53e5a5, (q31_t)0xf9881245, (q31_t)0x52a1bb, (q31_t)0xf99492ea, + (q31_t)0x516045, (q31_t)0xf9a113cd, (q31_t)0x502145, (q31_t)0xf9ad94f0, + (q31_t)0x4ee4b8, (q31_t)0xf9ba1651, (q31_t)0x4daaa1, (q31_t)0xf9c697f0, + (q31_t)0x4c72fe, (q31_t)0xf9d319cc, (q31_t)0x4b3dcf, (q31_t)0xf9df9be6, + (q31_t)0x4a0b16, (q31_t)0xf9ec1e3b, (q31_t)0x48dad1, (q31_t)0xf9f8a0cd, + (q31_t)0x47ad01, (q31_t)0xfa05239a, (q31_t)0x4681a6, (q31_t)0xfa11a6a3, + (q31_t)0x4558c0, (q31_t)0xfa1e29e5, (q31_t)0x44324f, (q31_t)0xfa2aad62, + (q31_t)0x430e53, (q31_t)0xfa373119, (q31_t)0x41eccc, (q31_t)0xfa43b508, + (q31_t)0x40cdba, (q31_t)0xfa503930, (q31_t)0x3fb11d, (q31_t)0xfa5cbd91, + (q31_t)0x3e96f6, (q31_t)0xfa694229, (q31_t)0x3d7f44, (q31_t)0xfa75c6f8, + (q31_t)0x3c6a07, (q31_t)0xfa824bfd, (q31_t)0x3b573f, (q31_t)0xfa8ed139, + (q31_t)0x3a46ed, (q31_t)0xfa9b56ab, (q31_t)0x393910, (q31_t)0xfaa7dc52, + (q31_t)0x382da8, (q31_t)0xfab4622d, (q31_t)0x3724b6, (q31_t)0xfac0e83d, + (q31_t)0x361e3a, (q31_t)0xfacd6e81, (q31_t)0x351a33, (q31_t)0xfad9f4f8, + (q31_t)0x3418a2, (q31_t)0xfae67ba2, (q31_t)0x331986, (q31_t)0xfaf3027e, + (q31_t)0x321ce0, (q31_t)0xfaff898c, (q31_t)0x3122b0, (q31_t)0xfb0c10cb, + (q31_t)0x302af5, (q31_t)0xfb18983b, (q31_t)0x2f35b1, (q31_t)0xfb251fdc, + (q31_t)0x2e42e2, (q31_t)0xfb31a7ac, (q31_t)0x2d5289, (q31_t)0xfb3e2fac, + (q31_t)0x2c64a6, (q31_t)0xfb4ab7db, (q31_t)0x2b7939, (q31_t)0xfb574039, + (q31_t)0x2a9042, (q31_t)0xfb63c8c4, (q31_t)0x29a9c1, (q31_t)0xfb70517d, + (q31_t)0x28c5b6, (q31_t)0xfb7cda63, (q31_t)0x27e421, (q31_t)0xfb896375, + (q31_t)0x270502, (q31_t)0xfb95ecb4, (q31_t)0x262859, (q31_t)0xfba2761e, + (q31_t)0x254e27, (q31_t)0xfbaeffb3, (q31_t)0x24766a, (q31_t)0xfbbb8973, + (q31_t)0x23a124, (q31_t)0xfbc8135c, (q31_t)0x22ce54, (q31_t)0xfbd49d70, + (q31_t)0x21fdfb, (q31_t)0xfbe127ac, (q31_t)0x213018, (q31_t)0xfbedb212, + (q31_t)0x2064ab, (q31_t)0xfbfa3c9f, (q31_t)0x1f9bb5, (q31_t)0xfc06c754, + (q31_t)0x1ed535, (q31_t)0xfc135231, (q31_t)0x1e112b, (q31_t)0xfc1fdd34, + (q31_t)0x1d4f99, (q31_t)0xfc2c685d, (q31_t)0x1c907c, (q31_t)0xfc38f3ac, + (q31_t)0x1bd3d6, (q31_t)0xfc457f21, (q31_t)0x1b19a7, (q31_t)0xfc520aba, + (q31_t)0x1a61ee, (q31_t)0xfc5e9678, (q31_t)0x19acac, (q31_t)0xfc6b2259, + (q31_t)0x18f9e1, (q31_t)0xfc77ae5e, (q31_t)0x18498c, (q31_t)0xfc843a85, + (q31_t)0x179bae, (q31_t)0xfc90c6cf, (q31_t)0x16f047, (q31_t)0xfc9d533b, + (q31_t)0x164757, (q31_t)0xfca9dfc8, (q31_t)0x15a0dd, (q31_t)0xfcb66c77, + (q31_t)0x14fcda, (q31_t)0xfcc2f945, (q31_t)0x145b4e, (q31_t)0xfccf8634, + (q31_t)0x13bc39, (q31_t)0xfcdc1342, (q31_t)0x131f9b, (q31_t)0xfce8a06f, + (q31_t)0x128574, (q31_t)0xfcf52dbb, (q31_t)0x11edc3, (q31_t)0xfd01bb24, + (q31_t)0x11588a, (q31_t)0xfd0e48ab, (q31_t)0x10c5c7, (q31_t)0xfd1ad650, + (q31_t)0x10357c, (q31_t)0xfd276410, (q31_t)0xfa7a8, (q31_t)0xfd33f1ed, + (q31_t)0xf1c4a, (q31_t)0xfd407fe6, (q31_t)0xe9364, (q31_t)0xfd4d0df9, + (q31_t)0xe0cf5, (q31_t)0xfd599c28, (q31_t)0xd88fd, (q31_t)0xfd662a70, + (q31_t)0xd077c, (q31_t)0xfd72b8d2, (q31_t)0xc8872, (q31_t)0xfd7f474d, + (q31_t)0xc0be0, (q31_t)0xfd8bd5e1, (q31_t)0xb91c4, (q31_t)0xfd98648d, + (q31_t)0xb1a20, (q31_t)0xfda4f351, (q31_t)0xaa4f3, (q31_t)0xfdb1822c, + (q31_t)0xa323d, (q31_t)0xfdbe111e, (q31_t)0x9c1ff, (q31_t)0xfdcaa027, + (q31_t)0x95438, (q31_t)0xfdd72f45, (q31_t)0x8e8e8, (q31_t)0xfde3be78, + (q31_t)0x8800f, (q31_t)0xfdf04dc0, (q31_t)0x819ae, (q31_t)0xfdfcdd1d, + (q31_t)0x7b5c4, (q31_t)0xfe096c8d, (q31_t)0x75452, (q31_t)0xfe15fc11, + (q31_t)0x6f556, (q31_t)0xfe228ba7, (q31_t)0x698d3, (q31_t)0xfe2f1b50, + (q31_t)0x63ec6, (q31_t)0xfe3bab0b, (q31_t)0x5e731, (q31_t)0xfe483ad8, + (q31_t)0x59214, (q31_t)0xfe54cab5, (q31_t)0x53f6e, (q31_t)0xfe615aa3, + (q31_t)0x4ef3f, (q31_t)0xfe6deaa1, (q31_t)0x4a188, (q31_t)0xfe7a7aae, + (q31_t)0x45648, (q31_t)0xfe870aca, (q31_t)0x40d80, (q31_t)0xfe939af5, + (q31_t)0x3c72f, (q31_t)0xfea02b2e, (q31_t)0x38356, (q31_t)0xfeacbb74, + (q31_t)0x341f4, (q31_t)0xfeb94bc8, (q31_t)0x3030a, (q31_t)0xfec5dc28, + (q31_t)0x2c697, (q31_t)0xfed26c94, (q31_t)0x28c9c, (q31_t)0xfedefd0c, + (q31_t)0x25519, (q31_t)0xfeeb8d8f, (q31_t)0x2200d, (q31_t)0xfef81e1d, + (q31_t)0x1ed78, (q31_t)0xff04aeb5, (q31_t)0x1bd5c, (q31_t)0xff113f56, + (q31_t)0x18fb6, (q31_t)0xff1dd001, (q31_t)0x16489, (q31_t)0xff2a60b4, + (q31_t)0x13bd3, (q31_t)0xff36f170, (q31_t)0x11594, (q31_t)0xff438234, + (q31_t)0xf1ce, (q31_t)0xff5012fe, (q31_t)0xd07e, (q31_t)0xff5ca3d0, + (q31_t)0xb1a7, (q31_t)0xff6934a8, (q31_t)0x9547, (q31_t)0xff75c585, + (q31_t)0x7b5f, (q31_t)0xff825668, (q31_t)0x63ee, (q31_t)0xff8ee750, + (q31_t)0x4ef5, (q31_t)0xff9b783c, (q31_t)0x3c74, (q31_t)0xffa8092c, + (q31_t)0x2c6a, (q31_t)0xffb49a1f, (q31_t)0x1ed8, (q31_t)0xffc12b16, + (q31_t)0x13bd, (q31_t)0xffcdbc0f, (q31_t)0xb1a, (q31_t)0xffda4d09, + (q31_t)0x4ef, (q31_t)0xffe6de05, (q31_t)0x13c, (q31_t)0xfff36f02, + (q31_t)0x0, (q31_t)0x0, (q31_t)0x13c, (q31_t)0xc90fe, + (q31_t)0x4ef, (q31_t)0x1921fb, (q31_t)0xb1a, (q31_t)0x25b2f7, + (q31_t)0x13bd, (q31_t)0x3243f1, (q31_t)0x1ed8, (q31_t)0x3ed4ea, + (q31_t)0x2c6a, (q31_t)0x4b65e1, (q31_t)0x3c74, (q31_t)0x57f6d4, + (q31_t)0x4ef5, (q31_t)0x6487c4, (q31_t)0x63ee, (q31_t)0x7118b0, + (q31_t)0x7b5f, (q31_t)0x7da998, (q31_t)0x9547, (q31_t)0x8a3a7b, + (q31_t)0xb1a7, (q31_t)0x96cb58, (q31_t)0xd07e, (q31_t)0xa35c30, + (q31_t)0xf1ce, (q31_t)0xafed02, (q31_t)0x11594, (q31_t)0xbc7dcc, + (q31_t)0x13bd3, (q31_t)0xc90e90, (q31_t)0x16489, (q31_t)0xd59f4c, + (q31_t)0x18fb6, (q31_t)0xe22fff, (q31_t)0x1bd5c, (q31_t)0xeec0aa, + (q31_t)0x1ed78, (q31_t)0xfb514b, (q31_t)0x2200d, (q31_t)0x107e1e3, + (q31_t)0x25519, (q31_t)0x1147271, (q31_t)0x28c9c, (q31_t)0x12102f4, + (q31_t)0x2c697, (q31_t)0x12d936c, (q31_t)0x3030a, (q31_t)0x13a23d8, + (q31_t)0x341f4, (q31_t)0x146b438, (q31_t)0x38356, (q31_t)0x153448c, + (q31_t)0x3c72f, (q31_t)0x15fd4d2, (q31_t)0x40d80, (q31_t)0x16c650b, + (q31_t)0x45648, (q31_t)0x178f536, (q31_t)0x4a188, (q31_t)0x1858552, + (q31_t)0x4ef3f, (q31_t)0x192155f, (q31_t)0x53f6e, (q31_t)0x19ea55d, + (q31_t)0x59214, (q31_t)0x1ab354b, (q31_t)0x5e731, (q31_t)0x1b7c528, + (q31_t)0x63ec6, (q31_t)0x1c454f5, (q31_t)0x698d3, (q31_t)0x1d0e4b0, + (q31_t)0x6f556, (q31_t)0x1dd7459, (q31_t)0x75452, (q31_t)0x1ea03ef, + (q31_t)0x7b5c4, (q31_t)0x1f69373, (q31_t)0x819ae, (q31_t)0x20322e3, + (q31_t)0x8800f, (q31_t)0x20fb240, (q31_t)0x8e8e8, (q31_t)0x21c4188, + (q31_t)0x95438, (q31_t)0x228d0bb, (q31_t)0x9c1ff, (q31_t)0x2355fd9, + (q31_t)0xa323d, (q31_t)0x241eee2, (q31_t)0xaa4f3, (q31_t)0x24e7dd4, + (q31_t)0xb1a20, (q31_t)0x25b0caf, (q31_t)0xb91c4, (q31_t)0x2679b73, + (q31_t)0xc0be0, (q31_t)0x2742a1f, (q31_t)0xc8872, (q31_t)0x280b8b3, + (q31_t)0xd077c, (q31_t)0x28d472e, (q31_t)0xd88fd, (q31_t)0x299d590, + (q31_t)0xe0cf5, (q31_t)0x2a663d8, (q31_t)0xe9364, (q31_t)0x2b2f207, + (q31_t)0xf1c4a, (q31_t)0x2bf801a, (q31_t)0xfa7a8, (q31_t)0x2cc0e13, + (q31_t)0x10357c, (q31_t)0x2d89bf0, (q31_t)0x10c5c7, (q31_t)0x2e529b0, + (q31_t)0x11588a, (q31_t)0x2f1b755, (q31_t)0x11edc3, (q31_t)0x2fe44dc, + (q31_t)0x128574, (q31_t)0x30ad245, (q31_t)0x131f9b, (q31_t)0x3175f91, + (q31_t)0x13bc39, (q31_t)0x323ecbe, (q31_t)0x145b4e, (q31_t)0x33079cc, + (q31_t)0x14fcda, (q31_t)0x33d06bb, (q31_t)0x15a0dd, (q31_t)0x3499389, + (q31_t)0x164757, (q31_t)0x3562038, (q31_t)0x16f047, (q31_t)0x362acc5, + (q31_t)0x179bae, (q31_t)0x36f3931, (q31_t)0x18498c, (q31_t)0x37bc57b, + (q31_t)0x18f9e1, (q31_t)0x38851a2, (q31_t)0x19acac, (q31_t)0x394dda7, + (q31_t)0x1a61ee, (q31_t)0x3a16988, (q31_t)0x1b19a7, (q31_t)0x3adf546, + (q31_t)0x1bd3d6, (q31_t)0x3ba80df, (q31_t)0x1c907c, (q31_t)0x3c70c54, + (q31_t)0x1d4f99, (q31_t)0x3d397a3, (q31_t)0x1e112b, (q31_t)0x3e022cc, + (q31_t)0x1ed535, (q31_t)0x3ecadcf, (q31_t)0x1f9bb5, (q31_t)0x3f938ac, + (q31_t)0x2064ab, (q31_t)0x405c361, (q31_t)0x213018, (q31_t)0x4124dee, + (q31_t)0x21fdfb, (q31_t)0x41ed854, (q31_t)0x22ce54, (q31_t)0x42b6290, + (q31_t)0x23a124, (q31_t)0x437eca4, (q31_t)0x24766a, (q31_t)0x444768d, + (q31_t)0x254e27, (q31_t)0x451004d, (q31_t)0x262859, (q31_t)0x45d89e2, + (q31_t)0x270502, (q31_t)0x46a134c, (q31_t)0x27e421, (q31_t)0x4769c8b, + (q31_t)0x28c5b6, (q31_t)0x483259d, (q31_t)0x29a9c1, (q31_t)0x48fae83, + (q31_t)0x2a9042, (q31_t)0x49c373c, (q31_t)0x2b7939, (q31_t)0x4a8bfc7, + (q31_t)0x2c64a6, (q31_t)0x4b54825, (q31_t)0x2d5289, (q31_t)0x4c1d054, + (q31_t)0x2e42e2, (q31_t)0x4ce5854, (q31_t)0x2f35b1, (q31_t)0x4dae024, + (q31_t)0x302af5, (q31_t)0x4e767c5, (q31_t)0x3122b0, (q31_t)0x4f3ef35, + (q31_t)0x321ce0, (q31_t)0x5007674, (q31_t)0x331986, (q31_t)0x50cfd82, + (q31_t)0x3418a2, (q31_t)0x519845e, (q31_t)0x351a33, (q31_t)0x5260b08, + (q31_t)0x361e3a, (q31_t)0x532917f, (q31_t)0x3724b6, (q31_t)0x53f17c3, + (q31_t)0x382da8, (q31_t)0x54b9dd3, (q31_t)0x393910, (q31_t)0x55823ae, + (q31_t)0x3a46ed, (q31_t)0x564a955, (q31_t)0x3b573f, (q31_t)0x5712ec7, + (q31_t)0x3c6a07, (q31_t)0x57db403, (q31_t)0x3d7f44, (q31_t)0x58a3908, + (q31_t)0x3e96f6, (q31_t)0x596bdd7, (q31_t)0x3fb11d, (q31_t)0x5a3426f, + (q31_t)0x40cdba, (q31_t)0x5afc6d0, (q31_t)0x41eccc, (q31_t)0x5bc4af8, + (q31_t)0x430e53, (q31_t)0x5c8cee7, (q31_t)0x44324f, (q31_t)0x5d5529e, + (q31_t)0x4558c0, (q31_t)0x5e1d61b, (q31_t)0x4681a6, (q31_t)0x5ee595d, + (q31_t)0x47ad01, (q31_t)0x5fadc66, (q31_t)0x48dad1, (q31_t)0x6075f33, + (q31_t)0x4a0b16, (q31_t)0x613e1c5, (q31_t)0x4b3dcf, (q31_t)0x620641a, + (q31_t)0x4c72fe, (q31_t)0x62ce634, (q31_t)0x4daaa1, (q31_t)0x6396810, + (q31_t)0x4ee4b8, (q31_t)0x645e9af, (q31_t)0x502145, (q31_t)0x6526b10, + (q31_t)0x516045, (q31_t)0x65eec33, (q31_t)0x52a1bb, (q31_t)0x66b6d16, + (q31_t)0x53e5a5, (q31_t)0x677edbb, (q31_t)0x552c03, (q31_t)0x6846e1f, + (q31_t)0x5674d6, (q31_t)0x690ee44, (q31_t)0x57c01d, (q31_t)0x69d6e27, + (q31_t)0x590dd8, (q31_t)0x6a9edc9, (q31_t)0x5a5e07, (q31_t)0x6b66d29, + (q31_t)0x5bb0ab, (q31_t)0x6c2ec48, (q31_t)0x5d05c3, (q31_t)0x6cf6b23, + (q31_t)0x5e5d4e, (q31_t)0x6dbe9bb, (q31_t)0x5fb74e, (q31_t)0x6e86810, + (q31_t)0x6113c2, (q31_t)0x6f4e620, (q31_t)0x6272aa, (q31_t)0x70163eb, + (q31_t)0x63d405, (q31_t)0x70de172, (q31_t)0x6537d4, (q31_t)0x71a5eb3, + (q31_t)0x669e18, (q31_t)0x726dbae, (q31_t)0x6806ce, (q31_t)0x7335862, + (q31_t)0x6971f9, (q31_t)0x73fd4cf, (q31_t)0x6adf97, (q31_t)0x74c50f4, + (q31_t)0x6c4fa8, (q31_t)0x758ccd2, (q31_t)0x6dc22e, (q31_t)0x7654867, + (q31_t)0x6f3726, (q31_t)0x771c3b3, (q31_t)0x70ae92, (q31_t)0x77e3eb5, + (q31_t)0x722871, (q31_t)0x78ab96e, (q31_t)0x73a4c3, (q31_t)0x79733dc, + (q31_t)0x752389, (q31_t)0x7a3adff, (q31_t)0x76a4c2, (q31_t)0x7b027d7, + (q31_t)0x78286e, (q31_t)0x7bca163, (q31_t)0x79ae8c, (q31_t)0x7c91aa3, + (q31_t)0x7b371e, (q31_t)0x7d59396, (q31_t)0x7cc223, (q31_t)0x7e20c3b, + (q31_t)0x7e4f9b, (q31_t)0x7ee8493, (q31_t)0x7fdf85, (q31_t)0x7fafc9c, + (q31_t)0x8171e2, (q31_t)0x8077457, (q31_t)0x8306b2, (q31_t)0x813ebc2, + (q31_t)0x849df4, (q31_t)0x82062de, (q31_t)0x8637a9, (q31_t)0x82cd9a9, + (q31_t)0x87d3d0, (q31_t)0x8395024, (q31_t)0x89726a, (q31_t)0x845c64d, + (q31_t)0x8b1376, (q31_t)0x8523c25, (q31_t)0x8cb6f5, (q31_t)0x85eb1ab, + (q31_t)0x8e5ce5, (q31_t)0x86b26de, (q31_t)0x900548, (q31_t)0x8779bbe, + (q31_t)0x91b01d, (q31_t)0x884104b, (q31_t)0x935d64, (q31_t)0x8908483, + (q31_t)0x950d1d, (q31_t)0x89cf867, (q31_t)0x96bf48, (q31_t)0x8a96bf6, + (q31_t)0x9873e4, (q31_t)0x8b5df30, (q31_t)0x9a2af3, (q31_t)0x8c25213, + (q31_t)0x9be473, (q31_t)0x8cec4a0, (q31_t)0x9da065, (q31_t)0x8db36d6, + (q31_t)0x9f5ec8, (q31_t)0x8e7a8b5, (q31_t)0xa11f9d, (q31_t)0x8f41a3c, + (q31_t)0xa2e2e3, (q31_t)0x9008b6a, (q31_t)0xa4a89b, (q31_t)0x90cfc40, + (q31_t)0xa670c4, (q31_t)0x9196cbc, (q31_t)0xa83b5e, (q31_t)0x925dcdf, + (q31_t)0xaa086a, (q31_t)0x9324ca7, (q31_t)0xabd7e6, (q31_t)0x93ebc14, + (q31_t)0xada9d4, (q31_t)0x94b2b27, (q31_t)0xaf7e33, (q31_t)0x95799dd, + (q31_t)0xb15502, (q31_t)0x9640837, (q31_t)0xb32e42, (q31_t)0x9707635, + (q31_t)0xb509f3, (q31_t)0x97ce3d5, (q31_t)0xb6e815, (q31_t)0x9895118, + (q31_t)0xb8c8a7, (q31_t)0x995bdfd, (q31_t)0xbaabaa, (q31_t)0x9a22a83, + (q31_t)0xbc911d, (q31_t)0x9ae96aa, (q31_t)0xbe7901, (q31_t)0x9bb0271, + (q31_t)0xc06355, (q31_t)0x9c76dd8, (q31_t)0xc25019, (q31_t)0x9d3d8df, + (q31_t)0xc43f4d, (q31_t)0x9e04385, (q31_t)0xc630f2, (q31_t)0x9ecadc9, + (q31_t)0xc82506, (q31_t)0x9f917ac, (q31_t)0xca1b8a, (q31_t)0xa05812c, + (q31_t)0xcc147f, (q31_t)0xa11ea49, (q31_t)0xce0fe3, (q31_t)0xa1e5303, + (q31_t)0xd00db6, (q31_t)0xa2abb59, (q31_t)0xd20dfa, (q31_t)0xa37234a, + (q31_t)0xd410ad, (q31_t)0xa438ad7, (q31_t)0xd615cf, (q31_t)0xa4ff1fe, + (q31_t)0xd81d61, (q31_t)0xa5c58c0, (q31_t)0xda2762, (q31_t)0xa68bf1b, + (q31_t)0xdc33d2, (q31_t)0xa752510, (q31_t)0xde42b2, (q31_t)0xa818a9d, + (q31_t)0xe05401, (q31_t)0xa8defc3, (q31_t)0xe267be, (q31_t)0xa9a5480, + (q31_t)0xe47deb, (q31_t)0xaa6b8d5, (q31_t)0xe69686, (q31_t)0xab31cc1, + (q31_t)0xe8b190, (q31_t)0xabf8043, (q31_t)0xeacf09, (q31_t)0xacbe35b, + (q31_t)0xeceef1, (q31_t)0xad84609, (q31_t)0xef1147, (q31_t)0xae4a84b, + (q31_t)0xf1360b, (q31_t)0xaf10a22, (q31_t)0xf35d3e, (q31_t)0xafd6b8d, + (q31_t)0xf586df, (q31_t)0xb09cc8c, (q31_t)0xf7b2ee, (q31_t)0xb162d1d, + (q31_t)0xf9e16b, (q31_t)0xb228d42, (q31_t)0xfc1257, (q31_t)0xb2eecf8, + (q31_t)0xfe45b0, (q31_t)0xb3b4c40, (q31_t)0x1007b77, (q31_t)0xb47ab19, + (q31_t)0x102b3ac, (q31_t)0xb540982, (q31_t)0x104ee4f, (q31_t)0xb60677c, + (q31_t)0x1072b5f, (q31_t)0xb6cc506, (q31_t)0x1096add, (q31_t)0xb79221f, + (q31_t)0x10bacc8, (q31_t)0xb857ec7, (q31_t)0x10df120, (q31_t)0xb91dafc, + (q31_t)0x11037e6, (q31_t)0xb9e36c0, (q31_t)0x1128119, (q31_t)0xbaa9211, + (q31_t)0x114ccb9, (q31_t)0xbb6ecef, (q31_t)0x1171ac6, (q31_t)0xbc34759, + (q31_t)0x1196b3f, (q31_t)0xbcfa150, (q31_t)0x11bbe26, (q31_t)0xbdbfad1, + (q31_t)0x11e1379, (q31_t)0xbe853de, (q31_t)0x1206b39, (q31_t)0xbf4ac75, + (q31_t)0x122c566, (q31_t)0xc010496, (q31_t)0x12521ff, (q31_t)0xc0d5c41, + (q31_t)0x1278104, (q31_t)0xc19b374, (q31_t)0x129e276, (q31_t)0xc260a31, + (q31_t)0x12c4653, (q31_t)0xc326075, (q31_t)0x12eac9d, (q31_t)0xc3eb641, + (q31_t)0x1311553, (q31_t)0xc4b0b94, (q31_t)0x1338075, (q31_t)0xc57606e, + (q31_t)0x135ee02, (q31_t)0xc63b4ce, (q31_t)0x1385dfb, (q31_t)0xc7008b3, + (q31_t)0x13ad060, (q31_t)0xc7c5c1e, (q31_t)0x13d4530, (q31_t)0xc88af0e, + (q31_t)0x13fbc6c, (q31_t)0xc950182, (q31_t)0x1423613, (q31_t)0xca1537a, + (q31_t)0x144b225, (q31_t)0xcada4f5, (q31_t)0x14730a3, (q31_t)0xcb9f5f3, + (q31_t)0x149b18b, (q31_t)0xcc64673, (q31_t)0x14c34df, (q31_t)0xcd29676, + (q31_t)0x14eba9d, (q31_t)0xcdee5f9, (q31_t)0x15142c6, (q31_t)0xceb34fe, + (q31_t)0x153cd5a, (q31_t)0xcf78383, (q31_t)0x1565a58, (q31_t)0xd03d189, + (q31_t)0x158e9c1, (q31_t)0xd101f0e, (q31_t)0x15b7b94, (q31_t)0xd1c6c11, + (q31_t)0x15e0fd1, (q31_t)0xd28b894, (q31_t)0x160a678, (q31_t)0xd350495, + (q31_t)0x1633f8a, (q31_t)0xd415013, (q31_t)0x165db05, (q31_t)0xd4d9b0e, + (q31_t)0x16878eb, (q31_t)0xd59e586, (q31_t)0x16b193a, (q31_t)0xd662f7b, + (q31_t)0x16dbbf3, (q31_t)0xd7278eb, (q31_t)0x1706115, (q31_t)0xd7ec1d6, + (q31_t)0x17308a1, (q31_t)0xd8b0a3d, (q31_t)0x175b296, (q31_t)0xd97521d, + (q31_t)0x1785ef4, (q31_t)0xda39978, (q31_t)0x17b0dbb, (q31_t)0xdafe04b, + (q31_t)0x17dbeec, (q31_t)0xdbc2698, (q31_t)0x1807285, (q31_t)0xdc86c5d, + (q31_t)0x1832888, (q31_t)0xdd4b19a, (q31_t)0x185e0f3, (q31_t)0xde0f64f, + (q31_t)0x1889bc6, (q31_t)0xded3a7b, (q31_t)0x18b5903, (q31_t)0xdf97e1d, + (q31_t)0x18e18a7, (q31_t)0xe05c135, (q31_t)0x190dab4, (q31_t)0xe1203c3, + (q31_t)0x1939f29, (q31_t)0xe1e45c6, (q31_t)0x1966606, (q31_t)0xe2a873e, + (q31_t)0x1992f4c, (q31_t)0xe36c82a, (q31_t)0x19bfaf9, (q31_t)0xe430889, + (q31_t)0x19ec90d, (q31_t)0xe4f485c, (q31_t)0x1a1998a, (q31_t)0xe5b87a2, + (q31_t)0x1a46c6e, (q31_t)0xe67c65a, (q31_t)0x1a741b9, (q31_t)0xe740483, + (q31_t)0x1aa196c, (q31_t)0xe80421e, (q31_t)0x1acf386, (q31_t)0xe8c7f2a, + (q31_t)0x1afd007, (q31_t)0xe98bba7, (q31_t)0x1b2aef0, (q31_t)0xea4f793, + (q31_t)0x1b5903f, (q31_t)0xeb132ef, (q31_t)0x1b873f5, (q31_t)0xebd6db9, + (q31_t)0x1bb5a11, (q31_t)0xec9a7f3, (q31_t)0x1be4294, (q31_t)0xed5e19a, + (q31_t)0x1c12d7e, (q31_t)0xee21aaf, (q31_t)0x1c41ace, (q31_t)0xeee5331, + (q31_t)0x1c70a84, (q31_t)0xefa8b20, (q31_t)0x1c9fca0, (q31_t)0xf06c27a, + (q31_t)0x1ccf122, (q31_t)0xf12f941, (q31_t)0x1cfe80a, (q31_t)0xf1f2f73, + (q31_t)0x1d2e158, (q31_t)0xf2b650f, (q31_t)0x1d5dd0c, (q31_t)0xf379a16, + (q31_t)0x1d8db25, (q31_t)0xf43ce86, (q31_t)0x1dbdba3, (q31_t)0xf500260, + (q31_t)0x1dede87, (q31_t)0xf5c35a3, (q31_t)0x1e1e3d0, (q31_t)0xf68684e, + (q31_t)0x1e4eb7e, (q31_t)0xf749a61, (q31_t)0x1e7f591, (q31_t)0xf80cbdc, + (q31_t)0x1eb0209, (q31_t)0xf8cfcbe, (q31_t)0x1ee10e5, (q31_t)0xf992d06, + (q31_t)0x1f12227, (q31_t)0xfa55cb4, (q31_t)0x1f435cc, (q31_t)0xfb18bc8, + (q31_t)0x1f74bd6, (q31_t)0xfbdba40, (q31_t)0x1fa6445, (q31_t)0xfc9e81e, + (q31_t)0x1fd7f17, (q31_t)0xfd6155f, (q31_t)0x2009c4e, (q31_t)0xfe24205, + (q31_t)0x203bbe8, (q31_t)0xfee6e0d, (q31_t)0x206dde6, (q31_t)0xffa9979, + (q31_t)0x20a0248, (q31_t)0x1006c446, (q31_t)0x20d290d, (q31_t)0x1012ee76, + (q31_t)0x2105236, (q31_t)0x101f1807, (q31_t)0x2137dc2, (q31_t)0x102b40f8, + (q31_t)0x216abb1, (q31_t)0x1037694b, (q31_t)0x219dc03, (q31_t)0x104390fd, + (q31_t)0x21d0eb8, (q31_t)0x104fb80e, (q31_t)0x22043d0, (q31_t)0x105bde7f, + (q31_t)0x2237b4b, (q31_t)0x1068044e, (q31_t)0x226b528, (q31_t)0x1074297b, + (q31_t)0x229f167, (q31_t)0x10804e06, (q31_t)0x22d3009, (q31_t)0x108c71ee, + (q31_t)0x230710d, (q31_t)0x10989532, (q31_t)0x233b473, (q31_t)0x10a4b7d3, + (q31_t)0x236fa3b, (q31_t)0x10b0d9d0, (q31_t)0x23a4265, (q31_t)0x10bcfb28, + (q31_t)0x23d8cf1, (q31_t)0x10c91bda, (q31_t)0x240d9de, (q31_t)0x10d53be7, + (q31_t)0x244292c, (q31_t)0x10e15b4e, (q31_t)0x2477adc, (q31_t)0x10ed7a0e, + (q31_t)0x24aceed, (q31_t)0x10f99827, (q31_t)0x24e255e, (q31_t)0x1105b599, + (q31_t)0x2517e31, (q31_t)0x1111d263, (q31_t)0x254d965, (q31_t)0x111dee84, + (q31_t)0x25836f9, (q31_t)0x112a09fc, (q31_t)0x25b96ee, (q31_t)0x113624cb, + (q31_t)0x25ef943, (q31_t)0x11423ef0, (q31_t)0x2625df8, (q31_t)0x114e586a, + (q31_t)0x265c50e, (q31_t)0x115a713a, (q31_t)0x2692e83, (q31_t)0x1166895f, + (q31_t)0x26c9a58, (q31_t)0x1172a0d7, (q31_t)0x270088e, (q31_t)0x117eb7a4, + (q31_t)0x2737922, (q31_t)0x118acdc4, (q31_t)0x276ec16, (q31_t)0x1196e337, + (q31_t)0x27a616a, (q31_t)0x11a2f7fc, (q31_t)0x27dd91c, (q31_t)0x11af0c13, + (q31_t)0x281532e, (q31_t)0x11bb1f7c, (q31_t)0x284cf9f, (q31_t)0x11c73235, + (q31_t)0x2884e6e, (q31_t)0x11d3443f, (q31_t)0x28bcf9c, (q31_t)0x11df5599, + (q31_t)0x28f5329, (q31_t)0x11eb6643, (q31_t)0x292d914, (q31_t)0x11f7763c, + (q31_t)0x296615d, (q31_t)0x12038584, (q31_t)0x299ec05, (q31_t)0x120f941a, + (q31_t)0x29d790a, (q31_t)0x121ba1fd, (q31_t)0x2a1086d, (q31_t)0x1227af2e, + (q31_t)0x2a49a2e, (q31_t)0x1233bbac, (q31_t)0x2a82e4d, (q31_t)0x123fc776, + (q31_t)0x2abc4c9, (q31_t)0x124bd28c, (q31_t)0x2af5da2, (q31_t)0x1257dced, + (q31_t)0x2b2f8d8, (q31_t)0x1263e699, (q31_t)0x2b6966c, (q31_t)0x126fef90, + (q31_t)0x2ba365c, (q31_t)0x127bf7d1, (q31_t)0x2bdd8a9, (q31_t)0x1287ff5b, + (q31_t)0x2c17d52, (q31_t)0x1294062f, (q31_t)0x2c52459, (q31_t)0x12a00c4b, + (q31_t)0x2c8cdbb, (q31_t)0x12ac11af, (q31_t)0x2cc7979, (q31_t)0x12b8165b, + (q31_t)0x2d02794, (q31_t)0x12c41a4f, (q31_t)0x2d3d80a, (q31_t)0x12d01d89, + (q31_t)0x2d78add, (q31_t)0x12dc2009, (q31_t)0x2db400a, (q31_t)0x12e821cf, + (q31_t)0x2def794, (q31_t)0x12f422db, (q31_t)0x2e2b178, (q31_t)0x1300232c, + (q31_t)0x2e66db8, (q31_t)0x130c22c1, (q31_t)0x2ea2c53, (q31_t)0x1318219a, + (q31_t)0x2eded49, (q31_t)0x13241fb6, (q31_t)0x2f1b099, (q31_t)0x13301d16, + (q31_t)0x2f57644, (q31_t)0x133c19b8, (q31_t)0x2f93e4a, (q31_t)0x1348159d, + (q31_t)0x2fd08a9, (q31_t)0x135410c3, (q31_t)0x300d563, (q31_t)0x13600b2a, + (q31_t)0x304a477, (q31_t)0x136c04d2, (q31_t)0x30875e5, (q31_t)0x1377fdbb, + (q31_t)0x30c49ad, (q31_t)0x1383f5e3, (q31_t)0x3101fce, (q31_t)0x138fed4b, + (q31_t)0x313f848, (q31_t)0x139be3f2, (q31_t)0x317d31c, (q31_t)0x13a7d9d7, + (q31_t)0x31bb049, (q31_t)0x13b3cefa, (q31_t)0x31f8fcf, (q31_t)0x13bfc35b, + (q31_t)0x32371ae, (q31_t)0x13cbb6f8, (q31_t)0x32755e5, (q31_t)0x13d7a9d3, + (q31_t)0x32b3c75, (q31_t)0x13e39be9, (q31_t)0x32f255e, (q31_t)0x13ef8d3c, + (q31_t)0x333109e, (q31_t)0x13fb7dc9, (q31_t)0x336fe37, (q31_t)0x14076d91, + (q31_t)0x33aee27, (q31_t)0x14135c94, (q31_t)0x33ee070, (q31_t)0x141f4ad1, + (q31_t)0x342d510, (q31_t)0x142b3846, (q31_t)0x346cc07, (q31_t)0x143724f5, + (q31_t)0x34ac556, (q31_t)0x144310dd, (q31_t)0x34ec0fc, (q31_t)0x144efbfc, + (q31_t)0x352bef9, (q31_t)0x145ae653, (q31_t)0x356bf4d, (q31_t)0x1466cfe1, + (q31_t)0x35ac1f7, (q31_t)0x1472b8a5, (q31_t)0x35ec6f8, (q31_t)0x147ea0a0, + (q31_t)0x362ce50, (q31_t)0x148a87d1, (q31_t)0x366d7fd, (q31_t)0x14966e36, + (q31_t)0x36ae401, (q31_t)0x14a253d1, (q31_t)0x36ef25b, (q31_t)0x14ae38a0, + (q31_t)0x373030a, (q31_t)0x14ba1ca3, (q31_t)0x377160f, (q31_t)0x14c5ffd9, + (q31_t)0x37b2b6a, (q31_t)0x14d1e242, (q31_t)0x37f4319, (q31_t)0x14ddc3de, + (q31_t)0x3835d1e, (q31_t)0x14e9a4ac, (q31_t)0x3877978, (q31_t)0x14f584ac, + (q31_t)0x38b9827, (q31_t)0x150163dc, (q31_t)0x38fb92a, (q31_t)0x150d423d, + (q31_t)0x393dc82, (q31_t)0x15191fcf, (q31_t)0x398022f, (q31_t)0x1524fc90, + (q31_t)0x39c2a2f, (q31_t)0x1530d881, (q31_t)0x3a05484, (q31_t)0x153cb3a0, + (q31_t)0x3a4812c, (q31_t)0x15488dee, (q31_t)0x3a8b028, (q31_t)0x1554676a, + (q31_t)0x3ace178, (q31_t)0x15604013, (q31_t)0x3b1151b, (q31_t)0x156c17e9, + (q31_t)0x3b54b11, (q31_t)0x1577eeec, (q31_t)0x3b9835a, (q31_t)0x1583c51b, + (q31_t)0x3bdbdf6, (q31_t)0x158f9a76, (q31_t)0x3c1fae5, (q31_t)0x159b6efb, + (q31_t)0x3c63a26, (q31_t)0x15a742ac, (q31_t)0x3ca7bba, (q31_t)0x15b31587, + (q31_t)0x3cebfa0, (q31_t)0x15bee78c, (q31_t)0x3d305d8, (q31_t)0x15cab8ba, + (q31_t)0x3d74e62, (q31_t)0x15d68911, (q31_t)0x3db993e, (q31_t)0x15e25890, + (q31_t)0x3dfe66c, (q31_t)0x15ee2738, (q31_t)0x3e435ea, (q31_t)0x15f9f507, + (q31_t)0x3e887bb, (q31_t)0x1605c1fd, (q31_t)0x3ecdbdc, (q31_t)0x16118e1a, + (q31_t)0x3f1324e, (q31_t)0x161d595d, (q31_t)0x3f58b10, (q31_t)0x162923c5, + (q31_t)0x3f9e624, (q31_t)0x1634ed53, (q31_t)0x3fe4388, (q31_t)0x1640b606, + (q31_t)0x402a33c, (q31_t)0x164c7ddd, (q31_t)0x4070540, (q31_t)0x165844d8, + (q31_t)0x40b6994, (q31_t)0x16640af7, (q31_t)0x40fd037, (q31_t)0x166fd039, + (q31_t)0x414392b, (q31_t)0x167b949d, (q31_t)0x418a46d, (q31_t)0x16875823, + (q31_t)0x41d11ff, (q31_t)0x16931acb, (q31_t)0x42181e0, (q31_t)0x169edc94, + (q31_t)0x425f410, (q31_t)0x16aa9d7e, (q31_t)0x42a688f, (q31_t)0x16b65d88, + (q31_t)0x42edf5c, (q31_t)0x16c21cb2, (q31_t)0x4335877, (q31_t)0x16cddafb, + (q31_t)0x437d3e1, (q31_t)0x16d99864, (q31_t)0x43c5199, (q31_t)0x16e554ea, + (q31_t)0x440d19e, (q31_t)0x16f1108f, (q31_t)0x44553f2, (q31_t)0x16fccb51, + (q31_t)0x449d892, (q31_t)0x17088531, (q31_t)0x44e5f80, (q31_t)0x17143e2d, + (q31_t)0x452e8bc, (q31_t)0x171ff646, (q31_t)0x4577444, (q31_t)0x172bad7a, + (q31_t)0x45c0219, (q31_t)0x173763c9, (q31_t)0x460923b, (q31_t)0x17431933, + (q31_t)0x46524a9, (q31_t)0x174ecdb8, (q31_t)0x469b963, (q31_t)0x175a8157, + (q31_t)0x46e5069, (q31_t)0x1766340f, (q31_t)0x472e9bc, (q31_t)0x1771e5e0, + (q31_t)0x477855a, (q31_t)0x177d96ca, (q31_t)0x47c2344, (q31_t)0x178946cc, + (q31_t)0x480c379, (q31_t)0x1794f5e6, (q31_t)0x48565f9, (q31_t)0x17a0a417, + (q31_t)0x48a0ac4, (q31_t)0x17ac515f, (q31_t)0x48eb1db, (q31_t)0x17b7fdbd, + (q31_t)0x4935b3c, (q31_t)0x17c3a931, (q31_t)0x49806e7, (q31_t)0x17cf53bb, + (q31_t)0x49cb4dd, (q31_t)0x17dafd59, (q31_t)0x4a1651c, (q31_t)0x17e6a60c, + (q31_t)0x4a617a6, (q31_t)0x17f24dd3, (q31_t)0x4aacc7a, (q31_t)0x17fdf4ae, + (q31_t)0x4af8397, (q31_t)0x18099a9c, (q31_t)0x4b43cfd, (q31_t)0x18153f9d, + (q31_t)0x4b8f8ad, (q31_t)0x1820e3b0, (q31_t)0x4bdb6a6, (q31_t)0x182c86d5, + (q31_t)0x4c276e8, (q31_t)0x1838290c, (q31_t)0x4c73972, (q31_t)0x1843ca53, + (q31_t)0x4cbfe45, (q31_t)0x184f6aab, (q31_t)0x4d0c560, (q31_t)0x185b0a13, + (q31_t)0x4d58ec3, (q31_t)0x1866a88a, (q31_t)0x4da5a6f, (q31_t)0x18724611, + (q31_t)0x4df2862, (q31_t)0x187de2a7, (q31_t)0x4e3f89c, (q31_t)0x18897e4a, + (q31_t)0x4e8cb1e, (q31_t)0x189518fc, (q31_t)0x4ed9fe7, (q31_t)0x18a0b2bb, + (q31_t)0x4f276f7, (q31_t)0x18ac4b87, (q31_t)0x4f7504e, (q31_t)0x18b7e35f, + (q31_t)0x4fc2bec, (q31_t)0x18c37a44, (q31_t)0x50109d0, (q31_t)0x18cf1034, + (q31_t)0x505e9fb, (q31_t)0x18daa52f, (q31_t)0x50acc6b, (q31_t)0x18e63935, + (q31_t)0x50fb121, (q31_t)0x18f1cc45, (q31_t)0x514981d, (q31_t)0x18fd5e5f, + (q31_t)0x519815f, (q31_t)0x1908ef82, (q31_t)0x51e6ce6, (q31_t)0x19147fae, + (q31_t)0x5235ab2, (q31_t)0x19200ee3, (q31_t)0x5284ac3, (q31_t)0x192b9d1f, + (q31_t)0x52d3d18, (q31_t)0x19372a64, (q31_t)0x53231b3, (q31_t)0x1942b6af, + (q31_t)0x5372891, (q31_t)0x194e4201, (q31_t)0x53c21b4, (q31_t)0x1959cc5a, + (q31_t)0x5411d1b, (q31_t)0x196555b8, (q31_t)0x5461ac6, (q31_t)0x1970de1b, + (q31_t)0x54b1ab4, (q31_t)0x197c6584, (q31_t)0x5501ce5, (q31_t)0x1987ebf0, + (q31_t)0x555215a, (q31_t)0x19937161, (q31_t)0x55a2812, (q31_t)0x199ef5d6, + (q31_t)0x55f310d, (q31_t)0x19aa794d, (q31_t)0x5643c4a, (q31_t)0x19b5fbc8, + (q31_t)0x56949ca, (q31_t)0x19c17d44, (q31_t)0x56e598c, (q31_t)0x19ccfdc2, + (q31_t)0x5736b90, (q31_t)0x19d87d42, (q31_t)0x5787fd6, (q31_t)0x19e3fbc3, + (q31_t)0x57d965d, (q31_t)0x19ef7944, (q31_t)0x582af26, (q31_t)0x19faf5c5, + (q31_t)0x587ca31, (q31_t)0x1a067145, (q31_t)0x58ce77c, (q31_t)0x1a11ebc5, + (q31_t)0x5920708, (q31_t)0x1a1d6544, (q31_t)0x59728d5, (q31_t)0x1a28ddc0, + (q31_t)0x59c4ce3, (q31_t)0x1a34553b, (q31_t)0x5a17330, (q31_t)0x1a3fcbb3, + (q31_t)0x5a69bbe, (q31_t)0x1a4b4128, (q31_t)0x5abc68c, (q31_t)0x1a56b599, + (q31_t)0x5b0f399, (q31_t)0x1a622907, (q31_t)0x5b622e6, (q31_t)0x1a6d9b70, + (q31_t)0x5bb5472, (q31_t)0x1a790cd4, (q31_t)0x5c0883d, (q31_t)0x1a847d33, + (q31_t)0x5c5be47, (q31_t)0x1a8fec8c, (q31_t)0x5caf690, (q31_t)0x1a9b5adf, + (q31_t)0x5d03118, (q31_t)0x1aa6c82b, (q31_t)0x5d56ddd, (q31_t)0x1ab23471, + (q31_t)0x5daace1, (q31_t)0x1abd9faf, (q31_t)0x5dfee22, (q31_t)0x1ac909e5, + (q31_t)0x5e531a1, (q31_t)0x1ad47312, (q31_t)0x5ea775e, (q31_t)0x1adfdb37, + (q31_t)0x5efbf58, (q31_t)0x1aeb4253, (q31_t)0x5f5098f, (q31_t)0x1af6a865, + (q31_t)0x5fa5603, (q31_t)0x1b020d6c, (q31_t)0x5ffa4b3, (q31_t)0x1b0d716a, + (q31_t)0x604f5a0, (q31_t)0x1b18d45c, (q31_t)0x60a48c9, (q31_t)0x1b243643, + (q31_t)0x60f9e2e, (q31_t)0x1b2f971e, (q31_t)0x614f5cf, (q31_t)0x1b3af6ec, + (q31_t)0x61a4fac, (q31_t)0x1b4655ae, (q31_t)0x61fabc4, (q31_t)0x1b51b363, + (q31_t)0x6250a18, (q31_t)0x1b5d100a, (q31_t)0x62a6aa6, (q31_t)0x1b686ba3, + (q31_t)0x62fcd6f, (q31_t)0x1b73c62d, (q31_t)0x6353273, (q31_t)0x1b7f1fa9, + (q31_t)0x63a99b1, (q31_t)0x1b8a7815, (q31_t)0x6400329, (q31_t)0x1b95cf71, + (q31_t)0x6456edb, (q31_t)0x1ba125bd, (q31_t)0x64adcc7, (q31_t)0x1bac7af9, + (q31_t)0x6504ced, (q31_t)0x1bb7cf23, (q31_t)0x655bf4c, (q31_t)0x1bc3223c, + (q31_t)0x65b33e4, (q31_t)0x1bce7442, (q31_t)0x660aab5, (q31_t)0x1bd9c537, + (q31_t)0x66623be, (q31_t)0x1be51518, (q31_t)0x66b9f01, (q31_t)0x1bf063e6, + (q31_t)0x6711c7b, (q31_t)0x1bfbb1a0, (q31_t)0x6769c2e, (q31_t)0x1c06fe46, + (q31_t)0x67c1e18, (q31_t)0x1c1249d8, (q31_t)0x681a23a, (q31_t)0x1c1d9454, + (q31_t)0x6872894, (q31_t)0x1c28ddbb, (q31_t)0x68cb124, (q31_t)0x1c34260c, + (q31_t)0x6923bec, (q31_t)0x1c3f6d47, (q31_t)0x697c8eb, (q31_t)0x1c4ab36b, + (q31_t)0x69d5820, (q31_t)0x1c55f878, (q31_t)0x6a2e98b, (q31_t)0x1c613c6d, + (q31_t)0x6a87d2d, (q31_t)0x1c6c7f4a, (q31_t)0x6ae1304, (q31_t)0x1c77c10e, + (q31_t)0x6b3ab12, (q31_t)0x1c8301b9, (q31_t)0x6b94554, (q31_t)0x1c8e414b, + (q31_t)0x6bee1cd, (q31_t)0x1c997fc4, (q31_t)0x6c4807a, (q31_t)0x1ca4bd21, + (q31_t)0x6ca215c, (q31_t)0x1caff965, (q31_t)0x6cfc472, (q31_t)0x1cbb348d, + (q31_t)0x6d569be, (q31_t)0x1cc66e99, (q31_t)0x6db113d, (q31_t)0x1cd1a78a, + (q31_t)0x6e0baf0, (q31_t)0x1cdcdf5e, (q31_t)0x6e666d7, (q31_t)0x1ce81615, + (q31_t)0x6ec14f2, (q31_t)0x1cf34baf, (q31_t)0x6f1c540, (q31_t)0x1cfe802b, + (q31_t)0x6f777c1, (q31_t)0x1d09b389, (q31_t)0x6fd2c75, (q31_t)0x1d14e5c9, + (q31_t)0x702e35c, (q31_t)0x1d2016e9, (q31_t)0x7089c75, (q31_t)0x1d2b46ea, + (q31_t)0x70e57c0, (q31_t)0x1d3675cb, (q31_t)0x714153e, (q31_t)0x1d41a38c, + (q31_t)0x719d4ed, (q31_t)0x1d4cd02c, (q31_t)0x71f96ce, (q31_t)0x1d57fbaa, + (q31_t)0x7255ae0, (q31_t)0x1d632608, (q31_t)0x72b2123, (q31_t)0x1d6e4f43, + (q31_t)0x730e997, (q31_t)0x1d79775c, (q31_t)0x736b43c, (q31_t)0x1d849e51, + (q31_t)0x73c8111, (q31_t)0x1d8fc424, (q31_t)0x7425016, (q31_t)0x1d9ae8d2, + (q31_t)0x748214c, (q31_t)0x1da60c5d, (q31_t)0x74df4b1, (q31_t)0x1db12ec3, + (q31_t)0x753ca46, (q31_t)0x1dbc5004, (q31_t)0x759a20a, (q31_t)0x1dc7701f, + (q31_t)0x75f7bfe, (q31_t)0x1dd28f15, (q31_t)0x7655820, (q31_t)0x1dddace4, + (q31_t)0x76b3671, (q31_t)0x1de8c98c, (q31_t)0x77116f0, (q31_t)0x1df3e50d, + (q31_t)0x776f99d, (q31_t)0x1dfeff67, (q31_t)0x77cde79, (q31_t)0x1e0a1898, + (q31_t)0x782c582, (q31_t)0x1e1530a1, (q31_t)0x788aeb9, (q31_t)0x1e204781, + (q31_t)0x78e9a1d, (q31_t)0x1e2b5d38, (q31_t)0x79487ae, (q31_t)0x1e3671c5, + (q31_t)0x79a776c, (q31_t)0x1e418528, (q31_t)0x7a06957, (q31_t)0x1e4c9760, + (q31_t)0x7a65d6e, (q31_t)0x1e57a86d, (q31_t)0x7ac53b1, (q31_t)0x1e62b84f, + (q31_t)0x7b24c20, (q31_t)0x1e6dc705, (q31_t)0x7b846ba, (q31_t)0x1e78d48e, + (q31_t)0x7be4381, (q31_t)0x1e83e0eb, (q31_t)0x7c44272, (q31_t)0x1e8eec1b, + (q31_t)0x7ca438f, (q31_t)0x1e99f61d, (q31_t)0x7d046d6, (q31_t)0x1ea4fef0, + (q31_t)0x7d64c47, (q31_t)0x1eb00696, (q31_t)0x7dc53e3, (q31_t)0x1ebb0d0d, + (q31_t)0x7e25daa, (q31_t)0x1ec61254, (q31_t)0x7e8699a, (q31_t)0x1ed1166b, + (q31_t)0x7ee77b3, (q31_t)0x1edc1953, (q31_t)0x7f487f6, (q31_t)0x1ee71b0a, + (q31_t)0x7fa9a62, (q31_t)0x1ef21b90, (q31_t)0x800aef7, (q31_t)0x1efd1ae4, + (q31_t)0x806c5b5, (q31_t)0x1f081907, (q31_t)0x80cde9b, (q31_t)0x1f1315f7, + (q31_t)0x812f9a9, (q31_t)0x1f1e11b5, (q31_t)0x81916df, (q31_t)0x1f290c3f, + (q31_t)0x81f363d, (q31_t)0x1f340596, (q31_t)0x82557c3, (q31_t)0x1f3efdb9, + (q31_t)0x82b7b70, (q31_t)0x1f49f4a8, (q31_t)0x831a143, (q31_t)0x1f54ea62, + (q31_t)0x837c93e, (q31_t)0x1f5fdee6, (q31_t)0x83df35f, (q31_t)0x1f6ad235, + (q31_t)0x8441fa6, (q31_t)0x1f75c44e, (q31_t)0x84a4e14, (q31_t)0x1f80b531, + (q31_t)0x8507ea7, (q31_t)0x1f8ba4dc, (q31_t)0x856b160, (q31_t)0x1f969350, + (q31_t)0x85ce63e, (q31_t)0x1fa1808c, (q31_t)0x8631d42, (q31_t)0x1fac6c91, + (q31_t)0x869566a, (q31_t)0x1fb7575c, (q31_t)0x86f91b7, (q31_t)0x1fc240ef, + (q31_t)0x875cf28, (q31_t)0x1fcd2948, (q31_t)0x87c0ebd, (q31_t)0x1fd81067, + (q31_t)0x8825077, (q31_t)0x1fe2f64c, (q31_t)0x8889454, (q31_t)0x1feddaf6, + (q31_t)0x88eda54, (q31_t)0x1ff8be65, (q31_t)0x8952278, (q31_t)0x2003a099, + (q31_t)0x89b6cbf, (q31_t)0x200e8190, (q31_t)0x8a1b928, (q31_t)0x2019614c, + (q31_t)0x8a807b4, (q31_t)0x20243fca, (q31_t)0x8ae5862, (q31_t)0x202f1d0b, + (q31_t)0x8b4ab32, (q31_t)0x2039f90f, (q31_t)0x8bb0023, (q31_t)0x2044d3d4, + (q31_t)0x8c15736, (q31_t)0x204fad5b, (q31_t)0x8c7b06b, (q31_t)0x205a85a3, + (q31_t)0x8ce0bc0, (q31_t)0x20655cac, (q31_t)0x8d46936, (q31_t)0x20703275, + (q31_t)0x8dac8cd, (q31_t)0x207b06fe, (q31_t)0x8e12a84, (q31_t)0x2085da46, + (q31_t)0x8e78e5b, (q31_t)0x2090ac4d, (q31_t)0x8edf452, (q31_t)0x209b7d13, + (q31_t)0x8f45c68, (q31_t)0x20a64c97, (q31_t)0x8fac69e, (q31_t)0x20b11ad9, + (q31_t)0x90132f2, (q31_t)0x20bbe7d8, (q31_t)0x907a166, (q31_t)0x20c6b395, + (q31_t)0x90e11f7, (q31_t)0x20d17e0d, (q31_t)0x91484a8, (q31_t)0x20dc4742, + (q31_t)0x91af976, (q31_t)0x20e70f32, (q31_t)0x9217062, (q31_t)0x20f1d5de, + (q31_t)0x927e96b, (q31_t)0x20fc9b44, (q31_t)0x92e6492, (q31_t)0x21075f65, + (q31_t)0x934e1d6, (q31_t)0x21122240, (q31_t)0x93b6137, (q31_t)0x211ce3d5, + (q31_t)0x941e2b4, (q31_t)0x2127a423, (q31_t)0x948664d, (q31_t)0x21326329, + (q31_t)0x94eec03, (q31_t)0x213d20e8, (q31_t)0x95573d4, (q31_t)0x2147dd5f, + (q31_t)0x95bfdc1, (q31_t)0x2152988d, (q31_t)0x96289c9, (q31_t)0x215d5273, + (q31_t)0x96917ec, (q31_t)0x21680b0f, (q31_t)0x96fa82a, (q31_t)0x2172c262, + (q31_t)0x9763a83, (q31_t)0x217d786a, (q31_t)0x97ccef5, (q31_t)0x21882d28, + (q31_t)0x9836582, (q31_t)0x2192e09b, (q31_t)0x989fe29, (q31_t)0x219d92c2, + (q31_t)0x99098e9, (q31_t)0x21a8439e, (q31_t)0x99735c2, (q31_t)0x21b2f32e, + (q31_t)0x99dd4b4, (q31_t)0x21bda171, (q31_t)0x9a475bf, (q31_t)0x21c84e67, + (q31_t)0x9ab18e3, (q31_t)0x21d2fa0f, (q31_t)0x9b1be1e, (q31_t)0x21dda46a, + (q31_t)0x9b86572, (q31_t)0x21e84d76, (q31_t)0x9bf0edd, (q31_t)0x21f2f534, + (q31_t)0x9c5ba60, (q31_t)0x21fd9ba3, (q31_t)0x9cc67fa, (q31_t)0x220840c2, + (q31_t)0x9d317ab, (q31_t)0x2212e492, (q31_t)0x9d9c973, (q31_t)0x221d8711, + (q31_t)0x9e07d51, (q31_t)0x2228283f, (q31_t)0x9e73346, (q31_t)0x2232c81c, + (q31_t)0x9edeb50, (q31_t)0x223d66a8, (q31_t)0x9f4a570, (q31_t)0x224803e2, + (q31_t)0x9fb61a5, (q31_t)0x22529fca, (q31_t)0xa021fef, (q31_t)0x225d3a5e, + (q31_t)0xa08e04f, (q31_t)0x2267d3a0, (q31_t)0xa0fa2c3, (q31_t)0x22726b8e, + (q31_t)0xa16674b, (q31_t)0x227d0228, (q31_t)0xa1d2de7, (q31_t)0x2287976e, + (q31_t)0xa23f698, (q31_t)0x22922b5e, (q31_t)0xa2ac15b, (q31_t)0x229cbdfa, + (q31_t)0xa318e32, (q31_t)0x22a74f40, (q31_t)0xa385d1d, (q31_t)0x22b1df30, + (q31_t)0xa3f2e19, (q31_t)0x22bc6dca, (q31_t)0xa460129, (q31_t)0x22c6fb0c, + (q31_t)0xa4cd64b, (q31_t)0x22d186f8, (q31_t)0xa53ad7e, (q31_t)0x22dc118c, + (q31_t)0xa5a86c4, (q31_t)0x22e69ac8, (q31_t)0xa61621b, (q31_t)0x22f122ab, + (q31_t)0xa683f83, (q31_t)0x22fba936, (q31_t)0xa6f1efc, (q31_t)0x23062e67, + (q31_t)0xa760086, (q31_t)0x2310b23e, (q31_t)0xa7ce420, (q31_t)0x231b34bc, + (q31_t)0xa83c9ca, (q31_t)0x2325b5df, (q31_t)0xa8ab184, (q31_t)0x233035a7, + (q31_t)0xa919b4e, (q31_t)0x233ab414, (q31_t)0xa988727, (q31_t)0x23453125, + (q31_t)0xa9f750f, (q31_t)0x234facda, (q31_t)0xaa66506, (q31_t)0x235a2733, + (q31_t)0xaad570c, (q31_t)0x2364a02e, (q31_t)0xab44b1f, (q31_t)0x236f17cc, + (q31_t)0xabb4141, (q31_t)0x23798e0d, (q31_t)0xac23971, (q31_t)0x238402ef, + (q31_t)0xac933ae, (q31_t)0x238e7673, (q31_t)0xad02ff8, (q31_t)0x2398e898, + (q31_t)0xad72e4f, (q31_t)0x23a3595e, (q31_t)0xade2eb3, (q31_t)0x23adc8c4, + (q31_t)0xae53123, (q31_t)0x23b836ca, (q31_t)0xaec35a0, (q31_t)0x23c2a36f, + (q31_t)0xaf33c28, (q31_t)0x23cd0eb3, (q31_t)0xafa44bc, (q31_t)0x23d77896, + (q31_t)0xb014f5b, (q31_t)0x23e1e117, (q31_t)0xb085c05, (q31_t)0x23ec4837, + (q31_t)0xb0f6aba, (q31_t)0x23f6adf3, (q31_t)0xb167b79, (q31_t)0x2401124d, + (q31_t)0xb1d8e43, (q31_t)0x240b7543, (q31_t)0xb24a316, (q31_t)0x2415d6d5, + (q31_t)0xb2bb9f4, (q31_t)0x24203704, (q31_t)0xb32d2da, (q31_t)0x242a95ce, + (q31_t)0xb39edca, (q31_t)0x2434f332, (q31_t)0xb410ac3, (q31_t)0x243f4f32, + (q31_t)0xb4829c4, (q31_t)0x2449a9cc, (q31_t)0xb4f4acd, (q31_t)0x245402ff, + (q31_t)0xb566ddf, (q31_t)0x245e5acc, (q31_t)0xb5d92f8, (q31_t)0x2468b132, + (q31_t)0xb64ba19, (q31_t)0x24730631, (q31_t)0xb6be341, (q31_t)0x247d59c8, + (q31_t)0xb730e70, (q31_t)0x2487abf7, (q31_t)0xb7a3ba5, (q31_t)0x2491fcbe, + (q31_t)0xb816ae1, (q31_t)0x249c4c1b, (q31_t)0xb889c23, (q31_t)0x24a69a0f, + (q31_t)0xb8fcf6b, (q31_t)0x24b0e699, (q31_t)0xb9704b9, (q31_t)0x24bb31ba, + (q31_t)0xb9e3c0b, (q31_t)0x24c57b6f, (q31_t)0xba57563, (q31_t)0x24cfc3ba, + (q31_t)0xbacb0bf, (q31_t)0x24da0a9a, (q31_t)0xbb3ee20, (q31_t)0x24e4500e, + (q31_t)0xbbb2d85, (q31_t)0x24ee9415, (q31_t)0xbc26eee, (q31_t)0x24f8d6b0, + (q31_t)0xbc9b25a, (q31_t)0x250317df, (q31_t)0xbd0f7ca, (q31_t)0x250d57a0, + (q31_t)0xbd83f3d, (q31_t)0x251795f3, (q31_t)0xbdf88b3, (q31_t)0x2521d2d8, + (q31_t)0xbe6d42b, (q31_t)0x252c0e4f, (q31_t)0xbee21a5, (q31_t)0x25364857, + (q31_t)0xbf57121, (q31_t)0x254080ef, (q31_t)0xbfcc29f, (q31_t)0x254ab818, + (q31_t)0xc04161e, (q31_t)0x2554edd1, (q31_t)0xc0b6b9e, (q31_t)0x255f2219, + (q31_t)0xc12c31f, (q31_t)0x256954f1, (q31_t)0xc1a1ca0, (q31_t)0x25738657, + (q31_t)0xc217822, (q31_t)0x257db64c, (q31_t)0xc28d5a3, (q31_t)0x2587e4cf, + (q31_t)0xc303524, (q31_t)0x259211df, (q31_t)0xc3796a5, (q31_t)0x259c3d7c, + (q31_t)0xc3efa25, (q31_t)0x25a667a7, (q31_t)0xc465fa3, (q31_t)0x25b0905d, + (q31_t)0xc4dc720, (q31_t)0x25bab7a0, (q31_t)0xc55309b, (q31_t)0x25c4dd6e, + (q31_t)0xc5c9c14, (q31_t)0x25cf01c8, (q31_t)0xc64098b, (q31_t)0x25d924ac, + (q31_t)0xc6b78ff, (q31_t)0x25e3461b, (q31_t)0xc72ea70, (q31_t)0x25ed6614, + (q31_t)0xc7a5dde, (q31_t)0x25f78497, (q31_t)0xc81d349, (q31_t)0x2601a1a2, + (q31_t)0xc894aaf, (q31_t)0x260bbd37, (q31_t)0xc90c412, (q31_t)0x2615d754, + (q31_t)0xc983f70, (q31_t)0x261feffa, (q31_t)0xc9fbcca, (q31_t)0x262a0727, + (q31_t)0xca73c1e, (q31_t)0x26341cdb, (q31_t)0xcaebd6e, (q31_t)0x263e3117, + (q31_t)0xcb640b8, (q31_t)0x264843d9, (q31_t)0xcbdc5fc, (q31_t)0x26525521, + (q31_t)0xcc54d3a, (q31_t)0x265c64ef, (q31_t)0xcccd671, (q31_t)0x26667342, + (q31_t)0xcd461a2, (q31_t)0x2670801a, (q31_t)0xcdbeecc, (q31_t)0x267a8b77, + (q31_t)0xce37def, (q31_t)0x26849558, (q31_t)0xceb0f0a, (q31_t)0x268e9dbd, + (q31_t)0xcf2a21d, (q31_t)0x2698a4a6, (q31_t)0xcfa3729, (q31_t)0x26a2aa11, + (q31_t)0xd01ce2b, (q31_t)0x26acadff, (q31_t)0xd096725, (q31_t)0x26b6b070, + (q31_t)0xd110216, (q31_t)0x26c0b162, (q31_t)0xd189efe, (q31_t)0x26cab0d6, + (q31_t)0xd203ddc, (q31_t)0x26d4aecb, (q31_t)0xd27deb0, (q31_t)0x26deab41, + (q31_t)0xd2f817b, (q31_t)0x26e8a637, (q31_t)0xd37263a, (q31_t)0x26f29fad, + (q31_t)0xd3eccef, (q31_t)0x26fc97a3, (q31_t)0xd467599, (q31_t)0x27068e18, + (q31_t)0xd4e2037, (q31_t)0x2710830c, (q31_t)0xd55ccca, (q31_t)0x271a767e, + (q31_t)0xd5d7b50, (q31_t)0x2724686e, (q31_t)0xd652bcb, (q31_t)0x272e58dc, + (q31_t)0xd6cde39, (q31_t)0x273847c8, (q31_t)0xd74929a, (q31_t)0x27423530, + (q31_t)0xd7c48ee, (q31_t)0x274c2115, (q31_t)0xd840134, (q31_t)0x27560b76, + (q31_t)0xd8bbb6d, (q31_t)0x275ff452, (q31_t)0xd937798, (q31_t)0x2769dbaa, + (q31_t)0xd9b35b4, (q31_t)0x2773c17d, (q31_t)0xda2f5c2, (q31_t)0x277da5cb, + (q31_t)0xdaab7c0, (q31_t)0x27878893, (q31_t)0xdb27bb0, (q31_t)0x279169d5, + (q31_t)0xdba4190, (q31_t)0x279b4990, (q31_t)0xdc20960, (q31_t)0x27a527c4, + (q31_t)0xdc9d320, (q31_t)0x27af0472, (q31_t)0xdd19ed0, (q31_t)0x27b8df97, + (q31_t)0xdd96c6f, (q31_t)0x27c2b934, (q31_t)0xde13bfd, (q31_t)0x27cc9149, + (q31_t)0xde90d79, (q31_t)0x27d667d5, (q31_t)0xdf0e0e4, (q31_t)0x27e03cd8, + (q31_t)0xdf8b63d, (q31_t)0x27ea1052, (q31_t)0xe008d84, (q31_t)0x27f3e241, + (q31_t)0xe0866b8, (q31_t)0x27fdb2a7, (q31_t)0xe1041d9, (q31_t)0x28078181, + (q31_t)0xe181ee8, (q31_t)0x28114ed0, (q31_t)0xe1ffde2, (q31_t)0x281b1a94, + (q31_t)0xe27dec9, (q31_t)0x2824e4cc, (q31_t)0xe2fc19c, (q31_t)0x282ead78, + (q31_t)0xe37a65b, (q31_t)0x28387498, (q31_t)0xe3f8d05, (q31_t)0x28423a2a, + (q31_t)0xe47759a, (q31_t)0x284bfe2f, (q31_t)0xe4f6019, (q31_t)0x2855c0a6, + (q31_t)0xe574c84, (q31_t)0x285f8190, (q31_t)0xe5f3ad8, (q31_t)0x286940ea, + (q31_t)0xe672b16, (q31_t)0x2872feb6, (q31_t)0xe6f1d3d, (q31_t)0x287cbaf3, + (q31_t)0xe77114e, (q31_t)0x288675a0, (q31_t)0xe7f0748, (q31_t)0x28902ebd, + (q31_t)0xe86ff2a, (q31_t)0x2899e64a, (q31_t)0xe8ef8f4, (q31_t)0x28a39c46, + (q31_t)0xe96f4a7, (q31_t)0x28ad50b1, (q31_t)0xe9ef241, (q31_t)0x28b7038b, + (q31_t)0xea6f1c2, (q31_t)0x28c0b4d2, (q31_t)0xeaef32b, (q31_t)0x28ca6488, + (q31_t)0xeb6f67a, (q31_t)0x28d412ab, (q31_t)0xebefbb0, (q31_t)0x28ddbf3b, + (q31_t)0xec702cb, (q31_t)0x28e76a37, (q31_t)0xecf0bcd, (q31_t)0x28f113a0, + (q31_t)0xed716b4, (q31_t)0x28fabb75, (q31_t)0xedf2380, (q31_t)0x290461b5, + (q31_t)0xee73231, (q31_t)0x290e0661, (q31_t)0xeef42c7, (q31_t)0x2917a977, + (q31_t)0xef75541, (q31_t)0x29214af8, (q31_t)0xeff699f, (q31_t)0x292aeae3, + (q31_t)0xf077fe1, (q31_t)0x29348937, (q31_t)0xf0f9805, (q31_t)0x293e25f5, + (q31_t)0xf17b20d, (q31_t)0x2947c11c, (q31_t)0xf1fcdf8, (q31_t)0x29515aab, + (q31_t)0xf27ebc5, (q31_t)0x295af2a3, (q31_t)0xf300b74, (q31_t)0x29648902, + (q31_t)0xf382d05, (q31_t)0x296e1dc9, (q31_t)0xf405077, (q31_t)0x2977b0f7, + (q31_t)0xf4875ca, (q31_t)0x2981428c, (q31_t)0xf509cfe, (q31_t)0x298ad287, + (q31_t)0xf58c613, (q31_t)0x299460e8, (q31_t)0xf60f108, (q31_t)0x299dedaf, + (q31_t)0xf691ddd, (q31_t)0x29a778db, (q31_t)0xf714c91, (q31_t)0x29b1026c, + (q31_t)0xf797d24, (q31_t)0x29ba8a61, (q31_t)0xf81af97, (q31_t)0x29c410ba, + (q31_t)0xf89e3e8, (q31_t)0x29cd9578, (q31_t)0xf921a17, (q31_t)0x29d71899, + (q31_t)0xf9a5225, (q31_t)0x29e09a1c, (q31_t)0xfa28c10, (q31_t)0x29ea1a03, + (q31_t)0xfaac7d8, (q31_t)0x29f3984c, (q31_t)0xfb3057d, (q31_t)0x29fd14f6, + (q31_t)0xfbb4500, (q31_t)0x2a069003, (q31_t)0xfc3865e, (q31_t)0x2a100970, + (q31_t)0xfcbc999, (q31_t)0x2a19813f, (q31_t)0xfd40eaf, (q31_t)0x2a22f76e, + (q31_t)0xfdc55a1, (q31_t)0x2a2c6bfd, (q31_t)0xfe49e6d, (q31_t)0x2a35deeb, + (q31_t)0xfece915, (q31_t)0x2a3f503a, (q31_t)0xff53597, (q31_t)0x2a48bfe7, + (q31_t)0xffd83f4, (q31_t)0x2a522df3, (q31_t)0x1005d42a, (q31_t)0x2a5b9a5d, + (q31_t)0x100e2639, (q31_t)0x2a650525, (q31_t)0x10167a22, (q31_t)0x2a6e6e4b, + (q31_t)0x101ecfe4, (q31_t)0x2a77d5ce, (q31_t)0x1027277e, (q31_t)0x2a813bae, + (q31_t)0x102f80f1, (q31_t)0x2a8a9fea, (q31_t)0x1037dc3b, (q31_t)0x2a940283, + (q31_t)0x1040395d, (q31_t)0x2a9d6377, (q31_t)0x10489856, (q31_t)0x2aa6c2c6, + (q31_t)0x1050f926, (q31_t)0x2ab02071, (q31_t)0x10595bcd, (q31_t)0x2ab97c77, + (q31_t)0x1061c04a, (q31_t)0x2ac2d6d6, (q31_t)0x106a269d, (q31_t)0x2acc2f90, + (q31_t)0x10728ec6, (q31_t)0x2ad586a3, (q31_t)0x107af8c4, (q31_t)0x2adedc10, + (q31_t)0x10836497, (q31_t)0x2ae82fd5, (q31_t)0x108bd23f, (q31_t)0x2af181f3, + (q31_t)0x109441bb, (q31_t)0x2afad269, (q31_t)0x109cb30b, (q31_t)0x2b042137, + (q31_t)0x10a5262f, (q31_t)0x2b0d6e5c, (q31_t)0x10ad9b26, (q31_t)0x2b16b9d9, + (q31_t)0x10b611f1, (q31_t)0x2b2003ac, (q31_t)0x10be8a8d, (q31_t)0x2b294bd5, + (q31_t)0x10c704fd, (q31_t)0x2b329255, (q31_t)0x10cf813e, (q31_t)0x2b3bd72a, + (q31_t)0x10d7ff51, (q31_t)0x2b451a55, (q31_t)0x10e07f36, (q31_t)0x2b4e5bd4, + (q31_t)0x10e900ec, (q31_t)0x2b579ba8, (q31_t)0x10f18472, (q31_t)0x2b60d9d0, + (q31_t)0x10fa09c9, (q31_t)0x2b6a164d, (q31_t)0x110290f0, (q31_t)0x2b73511c, + (q31_t)0x110b19e7, (q31_t)0x2b7c8a3f, (q31_t)0x1113a4ad, (q31_t)0x2b85c1b5, + (q31_t)0x111c3142, (q31_t)0x2b8ef77d, (q31_t)0x1124bfa6, (q31_t)0x2b982b97, + (q31_t)0x112d4fd9, (q31_t)0x2ba15e03, (q31_t)0x1135e1d9, (q31_t)0x2baa8ec0, + (q31_t)0x113e75a8, (q31_t)0x2bb3bdce, (q31_t)0x11470b44, (q31_t)0x2bbceb2d, + (q31_t)0x114fa2ad, (q31_t)0x2bc616dd, (q31_t)0x11583be2, (q31_t)0x2bcf40dc, + (q31_t)0x1160d6e5, (q31_t)0x2bd8692b, (q31_t)0x116973b3, (q31_t)0x2be18fc9, + (q31_t)0x1172124d, (q31_t)0x2beab4b6, (q31_t)0x117ab2b3, (q31_t)0x2bf3d7f2, + (q31_t)0x118354e4, (q31_t)0x2bfcf97c, (q31_t)0x118bf8e0, (q31_t)0x2c061953, + (q31_t)0x11949ea6, (q31_t)0x2c0f3779, (q31_t)0x119d4636, (q31_t)0x2c1853eb, + (q31_t)0x11a5ef90, (q31_t)0x2c216eaa, (q31_t)0x11ae9ab4, (q31_t)0x2c2a87b6, + (q31_t)0x11b747a0, (q31_t)0x2c339f0e, (q31_t)0x11bff656, (q31_t)0x2c3cb4b1, + (q31_t)0x11c8a6d4, (q31_t)0x2c45c8a0, (q31_t)0x11d1591a, (q31_t)0x2c4edada, + (q31_t)0x11da0d28, (q31_t)0x2c57eb5e, (q31_t)0x11e2c2fd, (q31_t)0x2c60fa2d, + (q31_t)0x11eb7a9a, (q31_t)0x2c6a0746, (q31_t)0x11f433fd, (q31_t)0x2c7312a9, + (q31_t)0x11fcef27, (q31_t)0x2c7c1c55, (q31_t)0x1205ac17, (q31_t)0x2c85244a, + (q31_t)0x120e6acc, (q31_t)0x2c8e2a87, (q31_t)0x12172b48, (q31_t)0x2c972f0d, + (q31_t)0x121fed88, (q31_t)0x2ca031da, (q31_t)0x1228b18d, (q31_t)0x2ca932ef, + (q31_t)0x12317756, (q31_t)0x2cb2324c, (q31_t)0x123a3ee4, (q31_t)0x2cbb2fef, + (q31_t)0x12430835, (q31_t)0x2cc42bd9, (q31_t)0x124bd34a, (q31_t)0x2ccd2609, + (q31_t)0x1254a021, (q31_t)0x2cd61e7f, (q31_t)0x125d6ebc, (q31_t)0x2cdf153a, + (q31_t)0x12663f19, (q31_t)0x2ce80a3a, (q31_t)0x126f1138, (q31_t)0x2cf0fd80, + (q31_t)0x1277e518, (q31_t)0x2cf9ef09, (q31_t)0x1280babb, (q31_t)0x2d02ded7, + (q31_t)0x1289921e, (q31_t)0x2d0bcce8, (q31_t)0x12926b41, (q31_t)0x2d14b93d, + (q31_t)0x129b4626, (q31_t)0x2d1da3d5, (q31_t)0x12a422ca, (q31_t)0x2d268cb0, + (q31_t)0x12ad012e, (q31_t)0x2d2f73cd, (q31_t)0x12b5e151, (q31_t)0x2d38592c, + (q31_t)0x12bec333, (q31_t)0x2d413ccd, (q31_t)0x12c7a6d4, (q31_t)0x2d4a1eaf, + (q31_t)0x12d08c33, (q31_t)0x2d52fed2, (q31_t)0x12d97350, (q31_t)0x2d5bdd36, + (q31_t)0x12e25c2b, (q31_t)0x2d64b9da, (q31_t)0x12eb46c3, (q31_t)0x2d6d94bf, + (q31_t)0x12f43318, (q31_t)0x2d766de2, (q31_t)0x12fd2129, (q31_t)0x2d7f4545, + (q31_t)0x130610f7, (q31_t)0x2d881ae8, (q31_t)0x130f0280, (q31_t)0x2d90eec8, + (q31_t)0x1317f5c6, (q31_t)0x2d99c0e7, (q31_t)0x1320eac6, (q31_t)0x2da29144, + (q31_t)0x1329e181, (q31_t)0x2dab5fdf, (q31_t)0x1332d9f7, (q31_t)0x2db42cb6, + (q31_t)0x133bd427, (q31_t)0x2dbcf7cb, (q31_t)0x1344d011, (q31_t)0x2dc5c11c, + (q31_t)0x134dcdb4, (q31_t)0x2dce88aa, (q31_t)0x1356cd11, (q31_t)0x2dd74e73, + (q31_t)0x135fce26, (q31_t)0x2de01278, (q31_t)0x1368d0f3, (q31_t)0x2de8d4b8, + (q31_t)0x1371d579, (q31_t)0x2df19534, (q31_t)0x137adbb6, (q31_t)0x2dfa53e9, + (q31_t)0x1383e3ab, (q31_t)0x2e0310d9, (q31_t)0x138ced57, (q31_t)0x2e0bcc03, + (q31_t)0x1395f8ba, (q31_t)0x2e148566, (q31_t)0x139f05d3, (q31_t)0x2e1d3d03, + (q31_t)0x13a814a2, (q31_t)0x2e25f2d8, (q31_t)0x13b12526, (q31_t)0x2e2ea6e6, + (q31_t)0x13ba3760, (q31_t)0x2e37592c, (q31_t)0x13c34b4f, (q31_t)0x2e4009aa, + (q31_t)0x13cc60f2, (q31_t)0x2e48b860, (q31_t)0x13d5784a, (q31_t)0x2e51654c, + (q31_t)0x13de9156, (q31_t)0x2e5a1070, (q31_t)0x13e7ac15, (q31_t)0x2e62b9ca, + (q31_t)0x13f0c887, (q31_t)0x2e6b615a, (q31_t)0x13f9e6ad, (q31_t)0x2e740720, + (q31_t)0x14030684, (q31_t)0x2e7cab1c, (q31_t)0x140c280e, (q31_t)0x2e854d4d, + (q31_t)0x14154b4a, (q31_t)0x2e8dedb3, (q31_t)0x141e7037, (q31_t)0x2e968c4d, + (q31_t)0x142796d5, (q31_t)0x2e9f291b, (q31_t)0x1430bf24, (q31_t)0x2ea7c41e, + (q31_t)0x1439e923, (q31_t)0x2eb05d53, (q31_t)0x144314d3, (q31_t)0x2eb8f4bc, + (q31_t)0x144c4232, (q31_t)0x2ec18a58, (q31_t)0x14557140, (q31_t)0x2eca1e27, + (q31_t)0x145ea1fd, (q31_t)0x2ed2b027, (q31_t)0x1467d469, (q31_t)0x2edb405a, + (q31_t)0x14710883, (q31_t)0x2ee3cebe, (q31_t)0x147a3e4b, (q31_t)0x2eec5b53, + (q31_t)0x148375c1, (q31_t)0x2ef4e619, (q31_t)0x148caee4, (q31_t)0x2efd6f10, + (q31_t)0x1495e9b3, (q31_t)0x2f05f637, (q31_t)0x149f2630, (q31_t)0x2f0e7b8e, + (q31_t)0x14a86458, (q31_t)0x2f16ff14, (q31_t)0x14b1a42c, (q31_t)0x2f1f80ca, + (q31_t)0x14bae5ab, (q31_t)0x2f2800af, (q31_t)0x14c428d6, (q31_t)0x2f307ec2, + (q31_t)0x14cd6dab, (q31_t)0x2f38fb03, (q31_t)0x14d6b42b, (q31_t)0x2f417573, + (q31_t)0x14dffc54, (q31_t)0x2f49ee0f, (q31_t)0x14e94627, (q31_t)0x2f5264da, + (q31_t)0x14f291a4, (q31_t)0x2f5ad9d1, (q31_t)0x14fbdec9, (q31_t)0x2f634cf5, + (q31_t)0x15052d97, (q31_t)0x2f6bbe45, (q31_t)0x150e7e0d, (q31_t)0x2f742dc1, + (q31_t)0x1517d02b, (q31_t)0x2f7c9b69, (q31_t)0x152123f0, (q31_t)0x2f85073c, + (q31_t)0x152a795d, (q31_t)0x2f8d713a, (q31_t)0x1533d070, (q31_t)0x2f95d963, + (q31_t)0x153d292a, (q31_t)0x2f9e3fb6, (q31_t)0x15468389, (q31_t)0x2fa6a433, + (q31_t)0x154fdf8f, (q31_t)0x2faf06da, (q31_t)0x15593d3a, (q31_t)0x2fb767aa, + (q31_t)0x15629c89, (q31_t)0x2fbfc6a3, (q31_t)0x156bfd7d, (q31_t)0x2fc823c5, + (q31_t)0x15756016, (q31_t)0x2fd07f0f, (q31_t)0x157ec452, (q31_t)0x2fd8d882, + (q31_t)0x15882a32, (q31_t)0x2fe1301c, (q31_t)0x159191b5, (q31_t)0x2fe985de, + (q31_t)0x159afadb, (q31_t)0x2ff1d9c7, (q31_t)0x15a465a3, (q31_t)0x2ffa2bd6, + (q31_t)0x15add20d, (q31_t)0x30027c0c, (q31_t)0x15b74019, (q31_t)0x300aca69, + (q31_t)0x15c0afc6, (q31_t)0x301316eb, (q31_t)0x15ca2115, (q31_t)0x301b6193, + (q31_t)0x15d39403, (q31_t)0x3023aa5f, (q31_t)0x15dd0892, (q31_t)0x302bf151, + (q31_t)0x15e67ec1, (q31_t)0x30343667, (q31_t)0x15eff690, (q31_t)0x303c79a2, + (q31_t)0x15f96ffd, (q31_t)0x3044bb00, (q31_t)0x1602eb0a, (q31_t)0x304cfa83, + (q31_t)0x160c67b4, (q31_t)0x30553828, (q31_t)0x1615e5fd, (q31_t)0x305d73f0, + (q31_t)0x161f65e4, (q31_t)0x3065addb, (q31_t)0x1628e767, (q31_t)0x306de5e9, + (q31_t)0x16326a88, (q31_t)0x30761c18, (q31_t)0x163bef46, (q31_t)0x307e5069, + (q31_t)0x1645759f, (q31_t)0x308682dc, (q31_t)0x164efd94, (q31_t)0x308eb36f, + (q31_t)0x16588725, (q31_t)0x3096e223, (q31_t)0x16621251, (q31_t)0x309f0ef8, + (q31_t)0x166b9f18, (q31_t)0x30a739ed, (q31_t)0x16752d79, (q31_t)0x30af6302, + (q31_t)0x167ebd74, (q31_t)0x30b78a36, (q31_t)0x16884f09, (q31_t)0x30bfaf89, + (q31_t)0x1691e237, (q31_t)0x30c7d2fb, (q31_t)0x169b76fe, (q31_t)0x30cff48c, + (q31_t)0x16a50d5d, (q31_t)0x30d8143b, (q31_t)0x16aea555, (q31_t)0x30e03208, + (q31_t)0x16b83ee4, (q31_t)0x30e84df3, (q31_t)0x16c1da0b, (q31_t)0x30f067fb, + (q31_t)0x16cb76c9, (q31_t)0x30f8801f, (q31_t)0x16d5151d, (q31_t)0x31009661, + (q31_t)0x16deb508, (q31_t)0x3108aabf, (q31_t)0x16e85689, (q31_t)0x3110bd39, + (q31_t)0x16f1f99f, (q31_t)0x3118cdcf, (q31_t)0x16fb9e4b, (q31_t)0x3120dc80, + (q31_t)0x1705448b, (q31_t)0x3128e94c, (q31_t)0x170eec60, (q31_t)0x3130f433, + (q31_t)0x171895c9, (q31_t)0x3138fd35, (q31_t)0x172240c5, (q31_t)0x31410450, + (q31_t)0x172bed55, (q31_t)0x31490986, (q31_t)0x17359b78, (q31_t)0x31510cd5, + (q31_t)0x173f4b2e, (q31_t)0x31590e3e, (q31_t)0x1748fc75, (q31_t)0x31610dbf, + (q31_t)0x1752af4f, (q31_t)0x31690b59, (q31_t)0x175c63ba, (q31_t)0x3171070c, + (q31_t)0x176619b6, (q31_t)0x317900d6, (q31_t)0x176fd143, (q31_t)0x3180f8b8, + (q31_t)0x17798a60, (q31_t)0x3188eeb2, (q31_t)0x1783450d, (q31_t)0x3190e2c3, + (q31_t)0x178d014a, (q31_t)0x3198d4ea, (q31_t)0x1796bf16, (q31_t)0x31a0c528, + (q31_t)0x17a07e70, (q31_t)0x31a8b37c, (q31_t)0x17aa3f5a, (q31_t)0x31b09fe7, + (q31_t)0x17b401d1, (q31_t)0x31b88a66, (q31_t)0x17bdc5d6, (q31_t)0x31c072fb, + (q31_t)0x17c78b68, (q31_t)0x31c859a5, (q31_t)0x17d15288, (q31_t)0x31d03e64, + (q31_t)0x17db1b34, (q31_t)0x31d82137, (q31_t)0x17e4e56c, (q31_t)0x31e0021e, + (q31_t)0x17eeb130, (q31_t)0x31e7e118, (q31_t)0x17f87e7f, (q31_t)0x31efbe27, + (q31_t)0x18024d59, (q31_t)0x31f79948, (q31_t)0x180c1dbf, (q31_t)0x31ff727c, + (q31_t)0x1815efae, (q31_t)0x320749c3, (q31_t)0x181fc328, (q31_t)0x320f1f1c, + (q31_t)0x1829982b, (q31_t)0x3216f287, (q31_t)0x18336eb7, (q31_t)0x321ec403, + (q31_t)0x183d46cc, (q31_t)0x32269391, (q31_t)0x18472069, (q31_t)0x322e6130, + (q31_t)0x1850fb8e, (q31_t)0x32362ce0, (q31_t)0x185ad83c, (q31_t)0x323df6a0, + (q31_t)0x1864b670, (q31_t)0x3245be70, (q31_t)0x186e962b, (q31_t)0x324d8450, + (q31_t)0x1878776d, (q31_t)0x32554840, (q31_t)0x18825a35, (q31_t)0x325d0a3e, + (q31_t)0x188c3e83, (q31_t)0x3264ca4c, (q31_t)0x18962456, (q31_t)0x326c8868, + (q31_t)0x18a00bae, (q31_t)0x32744493, (q31_t)0x18a9f48a, (q31_t)0x327bfecc, + (q31_t)0x18b3deeb, (q31_t)0x3283b712, (q31_t)0x18bdcad0, (q31_t)0x328b6d66, + (q31_t)0x18c7b838, (q31_t)0x329321c7, (q31_t)0x18d1a724, (q31_t)0x329ad435, + (q31_t)0x18db9792, (q31_t)0x32a284b0, (q31_t)0x18e58982, (q31_t)0x32aa3336, + (q31_t)0x18ef7cf4, (q31_t)0x32b1dfc9, (q31_t)0x18f971e8, (q31_t)0x32b98a67, + (q31_t)0x1903685d, (q31_t)0x32c13311, (q31_t)0x190d6053, (q31_t)0x32c8d9c6, + (q31_t)0x191759c9, (q31_t)0x32d07e85, (q31_t)0x192154bf, (q31_t)0x32d82150, + (q31_t)0x192b5135, (q31_t)0x32dfc224, (q31_t)0x19354f2a, (q31_t)0x32e76102, + (q31_t)0x193f4e9e, (q31_t)0x32eefdea, (q31_t)0x19494f90, (q31_t)0x32f698db, + (q31_t)0x19535201, (q31_t)0x32fe31d5, (q31_t)0x195d55ef, (q31_t)0x3305c8d7, + (q31_t)0x19675b5a, (q31_t)0x330d5de3, (q31_t)0x19716243, (q31_t)0x3314f0f6, + (q31_t)0x197b6aa8, (q31_t)0x331c8211, (q31_t)0x19857489, (q31_t)0x33241134, + (q31_t)0x198f7fe6, (q31_t)0x332b9e5e, (q31_t)0x19998cbe, (q31_t)0x3333298f, + (q31_t)0x19a39b11, (q31_t)0x333ab2c6, (q31_t)0x19adaadf, (q31_t)0x33423a04, + (q31_t)0x19b7bc27, (q31_t)0x3349bf48, (q31_t)0x19c1cee9, (q31_t)0x33514292, + (q31_t)0x19cbe325, (q31_t)0x3358c3e2, (q31_t)0x19d5f8d9, (q31_t)0x33604336, + (q31_t)0x19e01006, (q31_t)0x3367c090, (q31_t)0x19ea28ac, (q31_t)0x336f3bee, + (q31_t)0x19f442c9, (q31_t)0x3376b551, (q31_t)0x19fe5e5e, (q31_t)0x337e2cb7, + (q31_t)0x1a087b69, (q31_t)0x3385a222, (q31_t)0x1a1299ec, (q31_t)0x338d1590, + (q31_t)0x1a1cb9e5, (q31_t)0x33948701, (q31_t)0x1a26db54, (q31_t)0x339bf675, + (q31_t)0x1a30fe38, (q31_t)0x33a363ec, (q31_t)0x1a3b2292, (q31_t)0x33aacf65, + (q31_t)0x1a454860, (q31_t)0x33b238e0, (q31_t)0x1a4f6fa3, (q31_t)0x33b9a05d, + (q31_t)0x1a599859, (q31_t)0x33c105db, (q31_t)0x1a63c284, (q31_t)0x33c8695b, + (q31_t)0x1a6dee21, (q31_t)0x33cfcadc, (q31_t)0x1a781b31, (q31_t)0x33d72a5d, + (q31_t)0x1a8249b4, (q31_t)0x33de87de, (q31_t)0x1a8c79a9, (q31_t)0x33e5e360, + (q31_t)0x1a96ab0f, (q31_t)0x33ed3ce1, (q31_t)0x1aa0dde7, (q31_t)0x33f49462, + (q31_t)0x1aab122f, (q31_t)0x33fbe9e2, (q31_t)0x1ab547e8, (q31_t)0x34033d61, + (q31_t)0x1abf7f11, (q31_t)0x340a8edf, (q31_t)0x1ac9b7a9, (q31_t)0x3411de5b, + (q31_t)0x1ad3f1b1, (q31_t)0x34192bd5, (q31_t)0x1ade2d28, (q31_t)0x3420774d, + (q31_t)0x1ae86a0d, (q31_t)0x3427c0c3, (q31_t)0x1af2a860, (q31_t)0x342f0836, + (q31_t)0x1afce821, (q31_t)0x34364da6, (q31_t)0x1b072950, (q31_t)0x343d9112, + (q31_t)0x1b116beb, (q31_t)0x3444d27b, (q31_t)0x1b1baff2, (q31_t)0x344c11e0, + (q31_t)0x1b25f566, (q31_t)0x34534f41, (q31_t)0x1b303c46, (q31_t)0x345a8a9d, + (q31_t)0x1b3a8491, (q31_t)0x3461c3f5, (q31_t)0x1b44ce46, (q31_t)0x3468fb47, + (q31_t)0x1b4f1967, (q31_t)0x34703095, (q31_t)0x1b5965f1, (q31_t)0x347763dd, + (q31_t)0x1b63b3e5, (q31_t)0x347e951f, (q31_t)0x1b6e0342, (q31_t)0x3485c45b, + (q31_t)0x1b785409, (q31_t)0x348cf190, (q31_t)0x1b82a638, (q31_t)0x34941cbf, + (q31_t)0x1b8cf9cf, (q31_t)0x349b45e7, (q31_t)0x1b974ece, (q31_t)0x34a26d08, + (q31_t)0x1ba1a534, (q31_t)0x34a99221, (q31_t)0x1babfd01, (q31_t)0x34b0b533, + (q31_t)0x1bb65634, (q31_t)0x34b7d63c, (q31_t)0x1bc0b0ce, (q31_t)0x34bef53d, + (q31_t)0x1bcb0cce, (q31_t)0x34c61236, (q31_t)0x1bd56a32, (q31_t)0x34cd2d26, + (q31_t)0x1bdfc8fc, (q31_t)0x34d4460c, (q31_t)0x1bea292b, (q31_t)0x34db5cea, + (q31_t)0x1bf48abd, (q31_t)0x34e271bd, (q31_t)0x1bfeedb3, (q31_t)0x34e98487, + (q31_t)0x1c09520d, (q31_t)0x34f09546, (q31_t)0x1c13b7c9, (q31_t)0x34f7a3fb, + (q31_t)0x1c1e1ee9, (q31_t)0x34feb0a5, (q31_t)0x1c28876a, (q31_t)0x3505bb44, + (q31_t)0x1c32f14d, (q31_t)0x350cc3d8, (q31_t)0x1c3d5c91, (q31_t)0x3513ca60, + (q31_t)0x1c47c936, (q31_t)0x351acedd, (q31_t)0x1c52373c, (q31_t)0x3521d14d, + (q31_t)0x1c5ca6a2, (q31_t)0x3528d1b1, (q31_t)0x1c671768, (q31_t)0x352fd008, + (q31_t)0x1c71898d, (q31_t)0x3536cc52, (q31_t)0x1c7bfd11, (q31_t)0x353dc68f, + (q31_t)0x1c8671f3, (q31_t)0x3544bebf, (q31_t)0x1c90e834, (q31_t)0x354bb4e1, + (q31_t)0x1c9b5fd2, (q31_t)0x3552a8f4, (q31_t)0x1ca5d8cd, (q31_t)0x35599afa, + (q31_t)0x1cb05326, (q31_t)0x35608af1, (q31_t)0x1cbacedb, (q31_t)0x356778d9, + (q31_t)0x1cc54bec, (q31_t)0x356e64b2, (q31_t)0x1ccfca59, (q31_t)0x35754e7c, + (q31_t)0x1cda4a21, (q31_t)0x357c3636, (q31_t)0x1ce4cb44, (q31_t)0x35831be0, + (q31_t)0x1cef4dc2, (q31_t)0x3589ff7a, (q31_t)0x1cf9d199, (q31_t)0x3590e104, + (q31_t)0x1d0456ca, (q31_t)0x3597c07d, (q31_t)0x1d0edd55, (q31_t)0x359e9de5, + (q31_t)0x1d196538, (q31_t)0x35a5793c, (q31_t)0x1d23ee74, (q31_t)0x35ac5282, + (q31_t)0x1d2e7908, (q31_t)0x35b329b5, (q31_t)0x1d3904f4, (q31_t)0x35b9fed7, + (q31_t)0x1d439236, (q31_t)0x35c0d1e7, (q31_t)0x1d4e20d0, (q31_t)0x35c7a2e3, + (q31_t)0x1d58b0c0, (q31_t)0x35ce71ce, (q31_t)0x1d634206, (q31_t)0x35d53ea5, + (q31_t)0x1d6dd4a2, (q31_t)0x35dc0968, (q31_t)0x1d786892, (q31_t)0x35e2d219, + (q31_t)0x1d82fdd8, (q31_t)0x35e998b5, (q31_t)0x1d8d9472, (q31_t)0x35f05d3d, + (q31_t)0x1d982c60, (q31_t)0x35f71fb1, (q31_t)0x1da2c5a2, (q31_t)0x35fde011, + (q31_t)0x1dad6036, (q31_t)0x36049e5b, (q31_t)0x1db7fc1e, (q31_t)0x360b5a90, + (q31_t)0x1dc29958, (q31_t)0x361214b0, (q31_t)0x1dcd37e4, (q31_t)0x3618ccba, + (q31_t)0x1dd7d7c1, (q31_t)0x361f82af, (q31_t)0x1de278ef, (q31_t)0x3626368d, + (q31_t)0x1ded1b6e, (q31_t)0x362ce855, (q31_t)0x1df7bf3e, (q31_t)0x36339806, + (q31_t)0x1e02645d, (q31_t)0x363a45a0, (q31_t)0x1e0d0acc, (q31_t)0x3640f123, + (q31_t)0x1e17b28a, (q31_t)0x36479a8e, (q31_t)0x1e225b96, (q31_t)0x364e41e2, + (q31_t)0x1e2d05f1, (q31_t)0x3654e71d, (q31_t)0x1e37b199, (q31_t)0x365b8a41, + (q31_t)0x1e425e8f, (q31_t)0x36622b4c, (q31_t)0x1e4d0cd2, (q31_t)0x3668ca3e, + (q31_t)0x1e57bc62, (q31_t)0x366f6717, (q31_t)0x1e626d3e, (q31_t)0x367601d7, + (q31_t)0x1e6d1f65, (q31_t)0x367c9a7e, (q31_t)0x1e77d2d8, (q31_t)0x3683310b, + (q31_t)0x1e828796, (q31_t)0x3689c57d, (q31_t)0x1e8d3d9e, (q31_t)0x369057d6, + (q31_t)0x1e97f4f1, (q31_t)0x3696e814, (q31_t)0x1ea2ad8d, (q31_t)0x369d7637, + (q31_t)0x1ead6773, (q31_t)0x36a4023f, (q31_t)0x1eb822a1, (q31_t)0x36aa8c2c, + (q31_t)0x1ec2df18, (q31_t)0x36b113fd, (q31_t)0x1ecd9cd7, (q31_t)0x36b799b3, + (q31_t)0x1ed85bdd, (q31_t)0x36be1d4c, (q31_t)0x1ee31c2b, (q31_t)0x36c49ec9, + (q31_t)0x1eedddc0, (q31_t)0x36cb1e2a, (q31_t)0x1ef8a09b, (q31_t)0x36d19b6e, + (q31_t)0x1f0364bc, (q31_t)0x36d81695, (q31_t)0x1f0e2a22, (q31_t)0x36de8f9e, + (q31_t)0x1f18f0ce, (q31_t)0x36e5068a, (q31_t)0x1f23b8be, (q31_t)0x36eb7b58, + (q31_t)0x1f2e81f3, (q31_t)0x36f1ee09, (q31_t)0x1f394c6b, (q31_t)0x36f85e9a, + (q31_t)0x1f441828, (q31_t)0x36fecd0e, (q31_t)0x1f4ee527, (q31_t)0x37053962, + (q31_t)0x1f59b369, (q31_t)0x370ba398, (q31_t)0x1f6482ed, (q31_t)0x37120bae, + (q31_t)0x1f6f53b3, (q31_t)0x371871a5, (q31_t)0x1f7a25ba, (q31_t)0x371ed57c, + (q31_t)0x1f84f902, (q31_t)0x37253733, (q31_t)0x1f8fcd8b, (q31_t)0x372b96ca, + (q31_t)0x1f9aa354, (q31_t)0x3731f440, (q31_t)0x1fa57a5d, (q31_t)0x37384f95, + (q31_t)0x1fb052a5, (q31_t)0x373ea8ca, (q31_t)0x1fbb2c2c, (q31_t)0x3744ffdd, + (q31_t)0x1fc606f1, (q31_t)0x374b54ce, (q31_t)0x1fd0e2f5, (q31_t)0x3751a79e, + (q31_t)0x1fdbc036, (q31_t)0x3757f84c, (q31_t)0x1fe69eb4, (q31_t)0x375e46d8, + (q31_t)0x1ff17e70, (q31_t)0x37649341, (q31_t)0x1ffc5f67, (q31_t)0x376add88, + (q31_t)0x2007419b, (q31_t)0x377125ac, (q31_t)0x2012250a, (q31_t)0x37776bac, + (q31_t)0x201d09b4, (q31_t)0x377daf89, (q31_t)0x2027ef99, (q31_t)0x3783f143, + (q31_t)0x2032d6b8, (q31_t)0x378a30d8, (q31_t)0x203dbf11, (q31_t)0x37906e49, + (q31_t)0x2048a8a4, (q31_t)0x3796a996, (q31_t)0x2053936f, (q31_t)0x379ce2be, + (q31_t)0x205e7f74, (q31_t)0x37a319c2, (q31_t)0x20696cb0, (q31_t)0x37a94ea0, + (q31_t)0x20745b24, (q31_t)0x37af8159, (q31_t)0x207f4acf, (q31_t)0x37b5b1ec, + (q31_t)0x208a3bb2, (q31_t)0x37bbe05a, (q31_t)0x20952dcb, (q31_t)0x37c20ca1, + (q31_t)0x20a0211a, (q31_t)0x37c836c2, (q31_t)0x20ab159e, (q31_t)0x37ce5ebd, + (q31_t)0x20b60b58, (q31_t)0x37d48490, (q31_t)0x20c10247, (q31_t)0x37daa83d, + (q31_t)0x20cbfa6a, (q31_t)0x37e0c9c3, (q31_t)0x20d6f3c1, (q31_t)0x37e6e921, + (q31_t)0x20e1ee4b, (q31_t)0x37ed0657, (q31_t)0x20ecea09, (q31_t)0x37f32165, + (q31_t)0x20f7e6f9, (q31_t)0x37f93a4b, (q31_t)0x2102e51c, (q31_t)0x37ff5109, + (q31_t)0x210de470, (q31_t)0x3805659e, (q31_t)0x2118e4f6, (q31_t)0x380b780a, + (q31_t)0x2123e6ad, (q31_t)0x3811884d, (q31_t)0x212ee995, (q31_t)0x38179666, + (q31_t)0x2139edac, (q31_t)0x381da256, (q31_t)0x2144f2f3, (q31_t)0x3823ac1d, + (q31_t)0x214ff96a, (q31_t)0x3829b3b9, (q31_t)0x215b0110, (q31_t)0x382fb92a, + (q31_t)0x216609e3, (q31_t)0x3835bc71, (q31_t)0x217113e5, (q31_t)0x383bbd8e, + (q31_t)0x217c1f15, (q31_t)0x3841bc7f, (q31_t)0x21872b72, (q31_t)0x3847b946, + (q31_t)0x219238fb, (q31_t)0x384db3e0, (q31_t)0x219d47b1, (q31_t)0x3853ac4f, + (q31_t)0x21a85793, (q31_t)0x3859a292, (q31_t)0x21b368a0, (q31_t)0x385f96a9, + (q31_t)0x21be7ad8, (q31_t)0x38658894, (q31_t)0x21c98e3b, (q31_t)0x386b7852, + (q31_t)0x21d4a2c8, (q31_t)0x387165e3, (q31_t)0x21dfb87f, (q31_t)0x38775147, + (q31_t)0x21eacf5f, (q31_t)0x387d3a7e, (q31_t)0x21f5e768, (q31_t)0x38832187, + (q31_t)0x22010099, (q31_t)0x38890663, (q31_t)0x220c1af3, (q31_t)0x388ee910, + (q31_t)0x22173674, (q31_t)0x3894c98f, (q31_t)0x2222531c, (q31_t)0x389aa7e0, + (q31_t)0x222d70eb, (q31_t)0x38a08402, (q31_t)0x22388fe1, (q31_t)0x38a65df6, + (q31_t)0x2243affc, (q31_t)0x38ac35ba, (q31_t)0x224ed13d, (q31_t)0x38b20b4f, + (q31_t)0x2259f3a3, (q31_t)0x38b7deb4, (q31_t)0x2265172e, (q31_t)0x38bdafea, + (q31_t)0x22703bdc, (q31_t)0x38c37eef, (q31_t)0x227b61af, (q31_t)0x38c94bc4, + (q31_t)0x228688a4, (q31_t)0x38cf1669, (q31_t)0x2291b0bd, (q31_t)0x38d4dedd, + (q31_t)0x229cd9f8, (q31_t)0x38daa520, (q31_t)0x22a80456, (q31_t)0x38e06932, + (q31_t)0x22b32fd4, (q31_t)0x38e62b13, (q31_t)0x22be5c74, (q31_t)0x38ebeac2, + (q31_t)0x22c98a35, (q31_t)0x38f1a840, (q31_t)0x22d4b916, (q31_t)0x38f7638b, + (q31_t)0x22dfe917, (q31_t)0x38fd1ca4, (q31_t)0x22eb1a37, (q31_t)0x3902d38b, + (q31_t)0x22f64c77, (q31_t)0x3908883f, (q31_t)0x23017fd5, (q31_t)0x390e3ac0, + (q31_t)0x230cb451, (q31_t)0x3913eb0e, (q31_t)0x2317e9eb, (q31_t)0x39199929, + (q31_t)0x232320a2, (q31_t)0x391f4510, (q31_t)0x232e5876, (q31_t)0x3924eec3, + (q31_t)0x23399167, (q31_t)0x392a9642, (q31_t)0x2344cb73, (q31_t)0x39303b8e, + (q31_t)0x2350069b, (q31_t)0x3935dea4, (q31_t)0x235b42df, (q31_t)0x393b7f86, + (q31_t)0x2366803c, (q31_t)0x39411e33, (q31_t)0x2371beb5, (q31_t)0x3946baac, + (q31_t)0x237cfe47, (q31_t)0x394c54ee, (q31_t)0x23883ef2, (q31_t)0x3951ecfc, + (q31_t)0x239380b6, (q31_t)0x395782d3, (q31_t)0x239ec393, (q31_t)0x395d1675, + (q31_t)0x23aa0788, (q31_t)0x3962a7e0, (q31_t)0x23b54c95, (q31_t)0x39683715, + (q31_t)0x23c092b9, (q31_t)0x396dc414, (q31_t)0x23cbd9f4, (q31_t)0x39734edc, + (q31_t)0x23d72245, (q31_t)0x3978d76c, (q31_t)0x23e26bac, (q31_t)0x397e5dc6, + (q31_t)0x23edb628, (q31_t)0x3983e1e8, (q31_t)0x23f901ba, (q31_t)0x398963d2, + (q31_t)0x24044e60, (q31_t)0x398ee385, (q31_t)0x240f9c1a, (q31_t)0x399460ff, + (q31_t)0x241aeae8, (q31_t)0x3999dc42, (q31_t)0x24263ac9, (q31_t)0x399f554b, + (q31_t)0x24318bbe, (q31_t)0x39a4cc1c, (q31_t)0x243cddc4, (q31_t)0x39aa40b4, + (q31_t)0x244830dd, (q31_t)0x39afb313, (q31_t)0x24538507, (q31_t)0x39b52339, + (q31_t)0x245eda43, (q31_t)0x39ba9125, (q31_t)0x246a308f, (q31_t)0x39bffcd7, + (q31_t)0x247587eb, (q31_t)0x39c5664f, (q31_t)0x2480e057, (q31_t)0x39cacd8d, + (q31_t)0x248c39d3, (q31_t)0x39d03291, (q31_t)0x2497945d, (q31_t)0x39d5955a, + (q31_t)0x24a2eff6, (q31_t)0x39daf5e8, (q31_t)0x24ae4c9d, (q31_t)0x39e0543c, + (q31_t)0x24b9aa52, (q31_t)0x39e5b054, (q31_t)0x24c50914, (q31_t)0x39eb0a31, + (q31_t)0x24d068e2, (q31_t)0x39f061d2, (q31_t)0x24dbc9bd, (q31_t)0x39f5b737, + (q31_t)0x24e72ba4, (q31_t)0x39fb0a60, (q31_t)0x24f28e96, (q31_t)0x3a005b4d, + (q31_t)0x24fdf294, (q31_t)0x3a05a9fd, (q31_t)0x2509579b, (q31_t)0x3a0af671, + (q31_t)0x2514bdad, (q31_t)0x3a1040a8, (q31_t)0x252024c9, (q31_t)0x3a1588a2, + (q31_t)0x252b8cee, (q31_t)0x3a1ace5f, (q31_t)0x2536f61b, (q31_t)0x3a2011de, + (q31_t)0x25426051, (q31_t)0x3a25531f, (q31_t)0x254dcb8f, (q31_t)0x3a2a9223, + (q31_t)0x255937d5, (q31_t)0x3a2fcee8, (q31_t)0x2564a521, (q31_t)0x3a350970, + (q31_t)0x25701374, (q31_t)0x3a3a41b9, (q31_t)0x257b82cd, (q31_t)0x3a3f77c3, + (q31_t)0x2586f32c, (q31_t)0x3a44ab8e, (q31_t)0x25926490, (q31_t)0x3a49dd1a, + (q31_t)0x259dd6f9, (q31_t)0x3a4f0c67, (q31_t)0x25a94a67, (q31_t)0x3a543974, + (q31_t)0x25b4bed8, (q31_t)0x3a596442, (q31_t)0x25c0344d, (q31_t)0x3a5e8cd0, + (q31_t)0x25cbaac5, (q31_t)0x3a63b31d, (q31_t)0x25d72240, (q31_t)0x3a68d72b, + (q31_t)0x25e29abc, (q31_t)0x3a6df8f8, (q31_t)0x25ee143b, (q31_t)0x3a731884, + (q31_t)0x25f98ebb, (q31_t)0x3a7835cf, (q31_t)0x26050a3b, (q31_t)0x3a7d50da, + (q31_t)0x261086bc, (q31_t)0x3a8269a3, (q31_t)0x261c043d, (q31_t)0x3a87802a, + (q31_t)0x262782be, (q31_t)0x3a8c9470, (q31_t)0x2633023e, (q31_t)0x3a91a674, + (q31_t)0x263e82bc, (q31_t)0x3a96b636, (q31_t)0x264a0438, (q31_t)0x3a9bc3b6, + (q31_t)0x265586b3, (q31_t)0x3aa0cef3, (q31_t)0x26610a2a, (q31_t)0x3aa5d7ee, + (q31_t)0x266c8e9f, (q31_t)0x3aaadea6, (q31_t)0x26781410, (q31_t)0x3aafe31b, + (q31_t)0x26839a7c, (q31_t)0x3ab4e54c, (q31_t)0x268f21e5, (q31_t)0x3ab9e53a, + (q31_t)0x269aaa48, (q31_t)0x3abee2e5, (q31_t)0x26a633a6, (q31_t)0x3ac3de4c, + (q31_t)0x26b1bdff, (q31_t)0x3ac8d76f, (q31_t)0x26bd4951, (q31_t)0x3acdce4d, + (q31_t)0x26c8d59c, (q31_t)0x3ad2c2e8, (q31_t)0x26d462e1, (q31_t)0x3ad7b53d, + (q31_t)0x26dff11d, (q31_t)0x3adca54e, (q31_t)0x26eb8052, (q31_t)0x3ae1931a, + (q31_t)0x26f7107e, (q31_t)0x3ae67ea1, (q31_t)0x2702a1a1, (q31_t)0x3aeb67e3, + (q31_t)0x270e33bb, (q31_t)0x3af04edf, (q31_t)0x2719c6cb, (q31_t)0x3af53395, + (q31_t)0x27255ad1, (q31_t)0x3afa1605, (q31_t)0x2730efcc, (q31_t)0x3afef630, + (q31_t)0x273c85bc, (q31_t)0x3b03d414, (q31_t)0x27481ca1, (q31_t)0x3b08afb2, + (q31_t)0x2753b479, (q31_t)0x3b0d8909, (q31_t)0x275f4d45, (q31_t)0x3b126019, + (q31_t)0x276ae704, (q31_t)0x3b1734e2, (q31_t)0x277681b6, (q31_t)0x3b1c0764, + (q31_t)0x27821d59, (q31_t)0x3b20d79e, (q31_t)0x278db9ef, (q31_t)0x3b25a591, + (q31_t)0x27995776, (q31_t)0x3b2a713d, (q31_t)0x27a4f5ed, (q31_t)0x3b2f3aa0, + (q31_t)0x27b09555, (q31_t)0x3b3401bb, (q31_t)0x27bc35ad, (q31_t)0x3b38c68e, + (q31_t)0x27c7d6f4, (q31_t)0x3b3d8918, (q31_t)0x27d3792b, (q31_t)0x3b42495a, + (q31_t)0x27df1c50, (q31_t)0x3b470753, (q31_t)0x27eac063, (q31_t)0x3b4bc303, + (q31_t)0x27f66564, (q31_t)0x3b507c69, (q31_t)0x28020b52, (q31_t)0x3b553386, + (q31_t)0x280db22d, (q31_t)0x3b59e85a, (q31_t)0x281959f4, (q31_t)0x3b5e9ae4, + (q31_t)0x282502a7, (q31_t)0x3b634b23, (q31_t)0x2830ac45, (q31_t)0x3b67f919, + (q31_t)0x283c56cf, (q31_t)0x3b6ca4c4, (q31_t)0x28480243, (q31_t)0x3b714e25, + (q31_t)0x2853aea1, (q31_t)0x3b75f53c, (q31_t)0x285f5be9, (q31_t)0x3b7a9a07, + (q31_t)0x286b0a1a, (q31_t)0x3b7f3c87, (q31_t)0x2876b934, (q31_t)0x3b83dcbc, + (q31_t)0x28826936, (q31_t)0x3b887aa6, (q31_t)0x288e1a20, (q31_t)0x3b8d1644, + (q31_t)0x2899cbf1, (q31_t)0x3b91af97, (q31_t)0x28a57ea9, (q31_t)0x3b96469d, + (q31_t)0x28b13248, (q31_t)0x3b9adb57, (q31_t)0x28bce6cd, (q31_t)0x3b9f6dc5, + (q31_t)0x28c89c37, (q31_t)0x3ba3fde7, (q31_t)0x28d45286, (q31_t)0x3ba88bbc, + (q31_t)0x28e009ba, (q31_t)0x3bad1744, (q31_t)0x28ebc1d3, (q31_t)0x3bb1a080, + (q31_t)0x28f77acf, (q31_t)0x3bb6276e, (q31_t)0x290334af, (q31_t)0x3bbaac0e, + (q31_t)0x290eef71, (q31_t)0x3bbf2e62, (q31_t)0x291aab16, (q31_t)0x3bc3ae67, + (q31_t)0x2926679c, (q31_t)0x3bc82c1f, (q31_t)0x29322505, (q31_t)0x3bcca789, + (q31_t)0x293de34e, (q31_t)0x3bd120a4, (q31_t)0x2949a278, (q31_t)0x3bd59771, + (q31_t)0x29556282, (q31_t)0x3bda0bf0, (q31_t)0x2961236c, (q31_t)0x3bde7e20, + (q31_t)0x296ce535, (q31_t)0x3be2ee01, (q31_t)0x2978a7dd, (q31_t)0x3be75b93, + (q31_t)0x29846b63, (q31_t)0x3bebc6d5, (q31_t)0x29902fc7, (q31_t)0x3bf02fc9, + (q31_t)0x299bf509, (q31_t)0x3bf4966c, (q31_t)0x29a7bb28, (q31_t)0x3bf8fac0, + (q31_t)0x29b38223, (q31_t)0x3bfd5cc4, (q31_t)0x29bf49fa, (q31_t)0x3c01bc78, + (q31_t)0x29cb12ad, (q31_t)0x3c0619dc, (q31_t)0x29d6dc3b, (q31_t)0x3c0a74f0, + (q31_t)0x29e2a6a3, (q31_t)0x3c0ecdb2, (q31_t)0x29ee71e6, (q31_t)0x3c132424, + (q31_t)0x29fa3e03, (q31_t)0x3c177845, (q31_t)0x2a060af9, (q31_t)0x3c1bca16, + (q31_t)0x2a11d8c8, (q31_t)0x3c201994, (q31_t)0x2a1da770, (q31_t)0x3c2466c2, + (q31_t)0x2a2976ef, (q31_t)0x3c28b19e, (q31_t)0x2a354746, (q31_t)0x3c2cfa28, + (q31_t)0x2a411874, (q31_t)0x3c314060, (q31_t)0x2a4cea79, (q31_t)0x3c358446, + (q31_t)0x2a58bd54, (q31_t)0x3c39c5da, (q31_t)0x2a649105, (q31_t)0x3c3e051b, + (q31_t)0x2a70658a, (q31_t)0x3c42420a, (q31_t)0x2a7c3ae5, (q31_t)0x3c467ca6, + (q31_t)0x2a881114, (q31_t)0x3c4ab4ef, (q31_t)0x2a93e817, (q31_t)0x3c4eeae5, + (q31_t)0x2a9fbfed, (q31_t)0x3c531e88, (q31_t)0x2aab9896, (q31_t)0x3c574fd8, + (q31_t)0x2ab77212, (q31_t)0x3c5b7ed4, (q31_t)0x2ac34c60, (q31_t)0x3c5fab7c, + (q31_t)0x2acf277f, (q31_t)0x3c63d5d1, (q31_t)0x2adb0370, (q31_t)0x3c67fdd1, + (q31_t)0x2ae6e031, (q31_t)0x3c6c237e, (q31_t)0x2af2bdc3, (q31_t)0x3c7046d6, + (q31_t)0x2afe9c24, (q31_t)0x3c7467d9, (q31_t)0x2b0a7b54, (q31_t)0x3c788688, + (q31_t)0x2b165b54, (q31_t)0x3c7ca2e2, (q31_t)0x2b223c22, (q31_t)0x3c80bce7, + (q31_t)0x2b2e1dbe, (q31_t)0x3c84d496, (q31_t)0x2b3a0027, (q31_t)0x3c88e9f1, + (q31_t)0x2b45e35d, (q31_t)0x3c8cfcf6, (q31_t)0x2b51c760, (q31_t)0x3c910da5, + (q31_t)0x2b5dac2f, (q31_t)0x3c951bff, (q31_t)0x2b6991ca, (q31_t)0x3c992803, + (q31_t)0x2b75782f, (q31_t)0x3c9d31b0, (q31_t)0x2b815f60, (q31_t)0x3ca13908, + (q31_t)0x2b8d475b, (q31_t)0x3ca53e09, (q31_t)0x2b99301f, (q31_t)0x3ca940b3, + (q31_t)0x2ba519ad, (q31_t)0x3cad4107, (q31_t)0x2bb10404, (q31_t)0x3cb13f04, + (q31_t)0x2bbcef23, (q31_t)0x3cb53aaa, (q31_t)0x2bc8db0b, (q31_t)0x3cb933f9, + (q31_t)0x2bd4c7ba, (q31_t)0x3cbd2af0, (q31_t)0x2be0b52f, (q31_t)0x3cc11f90, + (q31_t)0x2beca36c, (q31_t)0x3cc511d9, (q31_t)0x2bf8926f, (q31_t)0x3cc901c9, + (q31_t)0x2c048237, (q31_t)0x3cccef62, (q31_t)0x2c1072c4, (q31_t)0x3cd0daa2, + (q31_t)0x2c1c6417, (q31_t)0x3cd4c38b, (q31_t)0x2c28562d, (q31_t)0x3cd8aa1b, + (q31_t)0x2c344908, (q31_t)0x3cdc8e52, (q31_t)0x2c403ca5, (q31_t)0x3ce07031, + (q31_t)0x2c4c3106, (q31_t)0x3ce44fb7, (q31_t)0x2c582629, (q31_t)0x3ce82ce4, + (q31_t)0x2c641c0e, (q31_t)0x3cec07b8, (q31_t)0x2c7012b5, (q31_t)0x3cefe032, + (q31_t)0x2c7c0a1d, (q31_t)0x3cf3b653, (q31_t)0x2c880245, (q31_t)0x3cf78a1b, + (q31_t)0x2c93fb2e, (q31_t)0x3cfb5b89, (q31_t)0x2c9ff4d6, (q31_t)0x3cff2a9d, + (q31_t)0x2cabef3d, (q31_t)0x3d02f757, (q31_t)0x2cb7ea63, (q31_t)0x3d06c1b6, + (q31_t)0x2cc3e648, (q31_t)0x3d0a89bc, (q31_t)0x2ccfe2ea, (q31_t)0x3d0e4f67, + (q31_t)0x2cdbe04a, (q31_t)0x3d1212b7, (q31_t)0x2ce7de66, (q31_t)0x3d15d3ad, + (q31_t)0x2cf3dd3f, (q31_t)0x3d199248, (q31_t)0x2cffdcd4, (q31_t)0x3d1d4e88, + (q31_t)0x2d0bdd25, (q31_t)0x3d21086c, (q31_t)0x2d17de31, (q31_t)0x3d24bff6, + (q31_t)0x2d23dff7, (q31_t)0x3d287523, (q31_t)0x2d2fe277, (q31_t)0x3d2c27f6, + (q31_t)0x2d3be5b1, (q31_t)0x3d2fd86c, (q31_t)0x2d47e9a5, (q31_t)0x3d338687, + (q31_t)0x2d53ee51, (q31_t)0x3d373245, (q31_t)0x2d5ff3b5, (q31_t)0x3d3adba7, + (q31_t)0x2d6bf9d1, (q31_t)0x3d3e82ae, (q31_t)0x2d7800a5, (q31_t)0x3d422757, + (q31_t)0x2d84082f, (q31_t)0x3d45c9a4, (q31_t)0x2d901070, (q31_t)0x3d496994, + (q31_t)0x2d9c1967, (q31_t)0x3d4d0728, (q31_t)0x2da82313, (q31_t)0x3d50a25e, + (q31_t)0x2db42d74, (q31_t)0x3d543b37, (q31_t)0x2dc0388a, (q31_t)0x3d57d1b3, + (q31_t)0x2dcc4454, (q31_t)0x3d5b65d2, (q31_t)0x2dd850d2, (q31_t)0x3d5ef793, + (q31_t)0x2de45e03, (q31_t)0x3d6286f6, (q31_t)0x2df06be6, (q31_t)0x3d6613fb, + (q31_t)0x2dfc7a7c, (q31_t)0x3d699ea3, (q31_t)0x2e0889c4, (q31_t)0x3d6d26ec, + (q31_t)0x2e1499bd, (q31_t)0x3d70acd7, (q31_t)0x2e20aa67, (q31_t)0x3d743064, + (q31_t)0x2e2cbbc1, (q31_t)0x3d77b192, (q31_t)0x2e38cdcb, (q31_t)0x3d7b3061, + (q31_t)0x2e44e084, (q31_t)0x3d7eacd2, (q31_t)0x2e50f3ed, (q31_t)0x3d8226e4, + (q31_t)0x2e5d0804, (q31_t)0x3d859e96, (q31_t)0x2e691cc9, (q31_t)0x3d8913ea, + (q31_t)0x2e75323c, (q31_t)0x3d8c86de, (q31_t)0x2e81485c, (q31_t)0x3d8ff772, + (q31_t)0x2e8d5f29, (q31_t)0x3d9365a8, (q31_t)0x2e9976a1, (q31_t)0x3d96d17d, + (q31_t)0x2ea58ec6, (q31_t)0x3d9a3af2, (q31_t)0x2eb1a796, (q31_t)0x3d9da208, + (q31_t)0x2ebdc110, (q31_t)0x3da106bd, (q31_t)0x2ec9db35, (q31_t)0x3da46912, + (q31_t)0x2ed5f604, (q31_t)0x3da7c907, (q31_t)0x2ee2117c, (q31_t)0x3dab269b, + (q31_t)0x2eee2d9d, (q31_t)0x3dae81cf, (q31_t)0x2efa4a67, (q31_t)0x3db1daa2, + (q31_t)0x2f0667d9, (q31_t)0x3db53113, (q31_t)0x2f1285f2, (q31_t)0x3db88524, + (q31_t)0x2f1ea4b2, (q31_t)0x3dbbd6d4, (q31_t)0x2f2ac419, (q31_t)0x3dbf2622, + (q31_t)0x2f36e426, (q31_t)0x3dc2730f, (q31_t)0x2f4304d8, (q31_t)0x3dc5bd9b, + (q31_t)0x2f4f2630, (q31_t)0x3dc905c5, (q31_t)0x2f5b482d, (q31_t)0x3dcc4b8d, + (q31_t)0x2f676ace, (q31_t)0x3dcf8ef3, (q31_t)0x2f738e12, (q31_t)0x3dd2cff7, + (q31_t)0x2f7fb1fa, (q31_t)0x3dd60e99, (q31_t)0x2f8bd685, (q31_t)0x3dd94ad8, + (q31_t)0x2f97fbb2, (q31_t)0x3ddc84b5, (q31_t)0x2fa42181, (q31_t)0x3ddfbc30, + (q31_t)0x2fb047f2, (q31_t)0x3de2f148, (q31_t)0x2fbc6f03, (q31_t)0x3de623fd, + (q31_t)0x2fc896b5, (q31_t)0x3de9544f, (q31_t)0x2fd4bf08, (q31_t)0x3dec823e, + (q31_t)0x2fe0e7f9, (q31_t)0x3defadca, (q31_t)0x2fed118a, (q31_t)0x3df2d6f3, + (q31_t)0x2ff93bba, (q31_t)0x3df5fdb8, (q31_t)0x30056687, (q31_t)0x3df9221a, + (q31_t)0x301191f3, (q31_t)0x3dfc4418, (q31_t)0x301dbdfb, (q31_t)0x3dff63b2, + (q31_t)0x3029eaa1, (q31_t)0x3e0280e9, (q31_t)0x303617e2, (q31_t)0x3e059bbb, + (q31_t)0x304245c0, (q31_t)0x3e08b42a, (q31_t)0x304e7438, (q31_t)0x3e0bca34, + (q31_t)0x305aa34c, (q31_t)0x3e0eddd9, (q31_t)0x3066d2fa, (q31_t)0x3e11ef1b, + (q31_t)0x30730342, (q31_t)0x3e14fdf7, (q31_t)0x307f3424, (q31_t)0x3e180a6f, + (q31_t)0x308b659f, (q31_t)0x3e1b1482, (q31_t)0x309797b2, (q31_t)0x3e1e1c30, + (q31_t)0x30a3ca5d, (q31_t)0x3e212179, (q31_t)0x30affda0, (q31_t)0x3e24245d, + (q31_t)0x30bc317a, (q31_t)0x3e2724db, (q31_t)0x30c865ea, (q31_t)0x3e2a22f4, + (q31_t)0x30d49af1, (q31_t)0x3e2d1ea8, (q31_t)0x30e0d08d, (q31_t)0x3e3017f6, + (q31_t)0x30ed06bf, (q31_t)0x3e330ede, (q31_t)0x30f93d86, (q31_t)0x3e360360, + (q31_t)0x310574e0, (q31_t)0x3e38f57c, (q31_t)0x3111accf, (q31_t)0x3e3be532, + (q31_t)0x311de551, (q31_t)0x3e3ed282, (q31_t)0x312a1e66, (q31_t)0x3e41bd6c, + (q31_t)0x3136580d, (q31_t)0x3e44a5ef, (q31_t)0x31429247, (q31_t)0x3e478c0b, + (q31_t)0x314ecd11, (q31_t)0x3e4a6fc1, (q31_t)0x315b086d, (q31_t)0x3e4d5110, + (q31_t)0x31674459, (q31_t)0x3e502ff9, (q31_t)0x317380d6, (q31_t)0x3e530c7a, + (q31_t)0x317fbde2, (q31_t)0x3e55e694, (q31_t)0x318bfb7d, (q31_t)0x3e58be47, + (q31_t)0x319839a6, (q31_t)0x3e5b9392, (q31_t)0x31a4785e, (q31_t)0x3e5e6676, + (q31_t)0x31b0b7a4, (q31_t)0x3e6136f3, (q31_t)0x31bcf777, (q31_t)0x3e640507, + (q31_t)0x31c937d6, (q31_t)0x3e66d0b4, (q31_t)0x31d578c2, (q31_t)0x3e6999fa, + (q31_t)0x31e1ba3a, (q31_t)0x3e6c60d7, (q31_t)0x31edfc3d, (q31_t)0x3e6f254c, + (q31_t)0x31fa3ecb, (q31_t)0x3e71e759, (q31_t)0x320681e3, (q31_t)0x3e74a6fd, + (q31_t)0x3212c585, (q31_t)0x3e77643a, (q31_t)0x321f09b1, (q31_t)0x3e7a1f0d, + (q31_t)0x322b4e66, (q31_t)0x3e7cd778, (q31_t)0x323793a3, (q31_t)0x3e7f8d7b, + (q31_t)0x3243d968, (q31_t)0x3e824114, (q31_t)0x32501fb5, (q31_t)0x3e84f245, + (q31_t)0x325c6688, (q31_t)0x3e87a10c, (q31_t)0x3268ade3, (q31_t)0x3e8a4d6a, + (q31_t)0x3274f5c3, (q31_t)0x3e8cf75f, (q31_t)0x32813e2a, (q31_t)0x3e8f9eeb, + (q31_t)0x328d8715, (q31_t)0x3e92440d, (q31_t)0x3299d085, (q31_t)0x3e94e6c6, + (q31_t)0x32a61a7a, (q31_t)0x3e978715, (q31_t)0x32b264f2, (q31_t)0x3e9a24fb, + (q31_t)0x32beafed, (q31_t)0x3e9cc076, (q31_t)0x32cafb6b, (q31_t)0x3e9f5988, + (q31_t)0x32d7476c, (q31_t)0x3ea1f02f, (q31_t)0x32e393ef, (q31_t)0x3ea4846c, + (q31_t)0x32efe0f2, (q31_t)0x3ea7163f, (q31_t)0x32fc2e77, (q31_t)0x3ea9a5a8, + (q31_t)0x33087c7d, (q31_t)0x3eac32a6, (q31_t)0x3314cb02, (q31_t)0x3eaebd3a, + (q31_t)0x33211a07, (q31_t)0x3eb14563, (q31_t)0x332d698a, (q31_t)0x3eb3cb21, + (q31_t)0x3339b98d, (q31_t)0x3eb64e75, (q31_t)0x33460a0d, (q31_t)0x3eb8cf5d, + (q31_t)0x33525b0b, (q31_t)0x3ebb4ddb, (q31_t)0x335eac86, (q31_t)0x3ebdc9ed, + (q31_t)0x336afe7e, (q31_t)0x3ec04394, (q31_t)0x337750f2, (q31_t)0x3ec2bad0, + (q31_t)0x3383a3e2, (q31_t)0x3ec52fa0, (q31_t)0x338ff74d, (q31_t)0x3ec7a205, + (q31_t)0x339c4b32, (q31_t)0x3eca11fe, (q31_t)0x33a89f92, (q31_t)0x3ecc7f8b, + (q31_t)0x33b4f46c, (q31_t)0x3eceeaad, (q31_t)0x33c149bf, (q31_t)0x3ed15363, + (q31_t)0x33cd9f8b, (q31_t)0x3ed3b9ad, (q31_t)0x33d9f5cf, (q31_t)0x3ed61d8a, + (q31_t)0x33e64c8c, (q31_t)0x3ed87efc, (q31_t)0x33f2a3bf, (q31_t)0x3edade01, + (q31_t)0x33fefb6a, (q31_t)0x3edd3a9a, (q31_t)0x340b538b, (q31_t)0x3edf94c7, + (q31_t)0x3417ac22, (q31_t)0x3ee1ec87, (q31_t)0x3424052f, (q31_t)0x3ee441da, + (q31_t)0x34305eb0, (q31_t)0x3ee694c1, (q31_t)0x343cb8a7, (q31_t)0x3ee8e53a, + (q31_t)0x34491311, (q31_t)0x3eeb3347, (q31_t)0x34556def, (q31_t)0x3eed7ee7, + (q31_t)0x3461c940, (q31_t)0x3eefc81a, (q31_t)0x346e2504, (q31_t)0x3ef20ee0, + (q31_t)0x347a8139, (q31_t)0x3ef45338, (q31_t)0x3486dde1, (q31_t)0x3ef69523, + (q31_t)0x34933afa, (q31_t)0x3ef8d4a1, (q31_t)0x349f9884, (q31_t)0x3efb11b1, + (q31_t)0x34abf67e, (q31_t)0x3efd4c54, (q31_t)0x34b854e7, (q31_t)0x3eff8489, + (q31_t)0x34c4b3c0, (q31_t)0x3f01ba50, (q31_t)0x34d11308, (q31_t)0x3f03eda9, + (q31_t)0x34dd72be, (q31_t)0x3f061e95, (q31_t)0x34e9d2e3, (q31_t)0x3f084d12, + (q31_t)0x34f63374, (q31_t)0x3f0a7921, (q31_t)0x35029473, (q31_t)0x3f0ca2c2, + (q31_t)0x350ef5de, (q31_t)0x3f0ec9f5, (q31_t)0x351b57b5, (q31_t)0x3f10eeb9, + (q31_t)0x3527b9f7, (q31_t)0x3f13110f, (q31_t)0x35341ca5, (q31_t)0x3f1530f7, + (q31_t)0x35407fbd, (q31_t)0x3f174e70, (q31_t)0x354ce33f, (q31_t)0x3f19697a, + (q31_t)0x3559472b, (q31_t)0x3f1b8215, (q31_t)0x3565ab80, (q31_t)0x3f1d9842, + (q31_t)0x3572103d, (q31_t)0x3f1fabff, (q31_t)0x357e7563, (q31_t)0x3f21bd4e, + (q31_t)0x358adaf0, (q31_t)0x3f23cc2e, (q31_t)0x359740e5, (q31_t)0x3f25d89e, + (q31_t)0x35a3a740, (q31_t)0x3f27e29f, (q31_t)0x35b00e02, (q31_t)0x3f29ea31, + (q31_t)0x35bc7529, (q31_t)0x3f2bef53, (q31_t)0x35c8dcb6, (q31_t)0x3f2df206, + (q31_t)0x35d544a7, (q31_t)0x3f2ff24a, (q31_t)0x35e1acfd, (q31_t)0x3f31f01d, + (q31_t)0x35ee15b7, (q31_t)0x3f33eb81, (q31_t)0x35fa7ed4, (q31_t)0x3f35e476, + (q31_t)0x3606e854, (q31_t)0x3f37dafa, (q31_t)0x36135237, (q31_t)0x3f39cf0e, + (q31_t)0x361fbc7b, (q31_t)0x3f3bc0b3, (q31_t)0x362c2721, (q31_t)0x3f3dafe7, + (q31_t)0x36389228, (q31_t)0x3f3f9cab, (q31_t)0x3644fd8f, (q31_t)0x3f4186ff, + (q31_t)0x36516956, (q31_t)0x3f436ee3, (q31_t)0x365dd57d, (q31_t)0x3f455456, + (q31_t)0x366a4203, (q31_t)0x3f473759, (q31_t)0x3676aee8, (q31_t)0x3f4917eb, + (q31_t)0x36831c2b, (q31_t)0x3f4af60d, (q31_t)0x368f89cb, (q31_t)0x3f4cd1be, + (q31_t)0x369bf7c9, (q31_t)0x3f4eaafe, (q31_t)0x36a86623, (q31_t)0x3f5081cd, + (q31_t)0x36b4d4d9, (q31_t)0x3f52562c, (q31_t)0x36c143ec, (q31_t)0x3f54281a, + (q31_t)0x36cdb359, (q31_t)0x3f55f796, (q31_t)0x36da2321, (q31_t)0x3f57c4a2, + (q31_t)0x36e69344, (q31_t)0x3f598f3c, (q31_t)0x36f303c0, (q31_t)0x3f5b5765, + (q31_t)0x36ff7496, (q31_t)0x3f5d1d1d, (q31_t)0x370be5c4, (q31_t)0x3f5ee063, + (q31_t)0x3718574b, (q31_t)0x3f60a138, (q31_t)0x3724c92a, (q31_t)0x3f625f9b, + (q31_t)0x37313b60, (q31_t)0x3f641b8d, (q31_t)0x373daded, (q31_t)0x3f65d50d, + (q31_t)0x374a20d0, (q31_t)0x3f678c1c, (q31_t)0x3756940a, (q31_t)0x3f6940b8, + (q31_t)0x37630799, (q31_t)0x3f6af2e3, (q31_t)0x376f7b7d, (q31_t)0x3f6ca29c, + (q31_t)0x377befb5, (q31_t)0x3f6e4fe3, (q31_t)0x37886442, (q31_t)0x3f6ffab8, + (q31_t)0x3794d922, (q31_t)0x3f71a31b, (q31_t)0x37a14e55, (q31_t)0x3f73490b, + (q31_t)0x37adc3db, (q31_t)0x3f74ec8a, (q31_t)0x37ba39b3, (q31_t)0x3f768d96, + (q31_t)0x37c6afdc, (q31_t)0x3f782c30, (q31_t)0x37d32657, (q31_t)0x3f79c857, + (q31_t)0x37df9d22, (q31_t)0x3f7b620c, (q31_t)0x37ec143e, (q31_t)0x3f7cf94e, + (q31_t)0x37f88ba9, (q31_t)0x3f7e8e1e, (q31_t)0x38050364, (q31_t)0x3f80207b, + (q31_t)0x38117b6d, (q31_t)0x3f81b065, (q31_t)0x381df3c5, (q31_t)0x3f833ddd, + (q31_t)0x382a6c6a, (q31_t)0x3f84c8e2, (q31_t)0x3836e55d, (q31_t)0x3f865174, + (q31_t)0x38435e9d, (q31_t)0x3f87d792, (q31_t)0x384fd829, (q31_t)0x3f895b3e, + (q31_t)0x385c5201, (q31_t)0x3f8adc77, (q31_t)0x3868cc24, (q31_t)0x3f8c5b3d, + (q31_t)0x38754692, (q31_t)0x3f8dd78f, (q31_t)0x3881c14b, (q31_t)0x3f8f516e, + (q31_t)0x388e3c4d, (q31_t)0x3f90c8da, (q31_t)0x389ab799, (q31_t)0x3f923dd2, + (q31_t)0x38a7332e, (q31_t)0x3f93b058, (q31_t)0x38b3af0c, (q31_t)0x3f952069, + (q31_t)0x38c02b31, (q31_t)0x3f968e07, (q31_t)0x38cca79e, (q31_t)0x3f97f932, + (q31_t)0x38d92452, (q31_t)0x3f9961e8, (q31_t)0x38e5a14d, (q31_t)0x3f9ac82c, + (q31_t)0x38f21e8e, (q31_t)0x3f9c2bfb, (q31_t)0x38fe9c15, (q31_t)0x3f9d8d56, + (q31_t)0x390b19e0, (q31_t)0x3f9eec3e, (q31_t)0x391797f0, (q31_t)0x3fa048b2, + (q31_t)0x39241645, (q31_t)0x3fa1a2b2, (q31_t)0x393094dd, (q31_t)0x3fa2fa3d, + (q31_t)0x393d13b8, (q31_t)0x3fa44f55, (q31_t)0x394992d7, (q31_t)0x3fa5a1f9, + (q31_t)0x39561237, (q31_t)0x3fa6f228, (q31_t)0x396291d9, (q31_t)0x3fa83fe3, + (q31_t)0x396f11bc, (q31_t)0x3fa98b2a, (q31_t)0x397b91e1, (q31_t)0x3faad3fd, + (q31_t)0x39881245, (q31_t)0x3fac1a5b, (q31_t)0x399492ea, (q31_t)0x3fad5e45, + (q31_t)0x39a113cd, (q31_t)0x3fae9fbb, (q31_t)0x39ad94f0, (q31_t)0x3fafdebb, + (q31_t)0x39ba1651, (q31_t)0x3fb11b48, (q31_t)0x39c697f0, (q31_t)0x3fb2555f, + (q31_t)0x39d319cc, (q31_t)0x3fb38d02, (q31_t)0x39df9be6, (q31_t)0x3fb4c231, + (q31_t)0x39ec1e3b, (q31_t)0x3fb5f4ea, (q31_t)0x39f8a0cd, (q31_t)0x3fb7252f, + (q31_t)0x3a05239a, (q31_t)0x3fb852ff, (q31_t)0x3a11a6a3, (q31_t)0x3fb97e5a, + (q31_t)0x3a1e29e5, (q31_t)0x3fbaa740, (q31_t)0x3a2aad62, (q31_t)0x3fbbcdb1, + (q31_t)0x3a373119, (q31_t)0x3fbcf1ad, (q31_t)0x3a43b508, (q31_t)0x3fbe1334, + (q31_t)0x3a503930, (q31_t)0x3fbf3246, (q31_t)0x3a5cbd91, (q31_t)0x3fc04ee3, + (q31_t)0x3a694229, (q31_t)0x3fc1690a, (q31_t)0x3a75c6f8, (q31_t)0x3fc280bc, + (q31_t)0x3a824bfd, (q31_t)0x3fc395f9, (q31_t)0x3a8ed139, (q31_t)0x3fc4a8c1, + (q31_t)0x3a9b56ab, (q31_t)0x3fc5b913, (q31_t)0x3aa7dc52, (q31_t)0x3fc6c6f0, + (q31_t)0x3ab4622d, (q31_t)0x3fc7d258, (q31_t)0x3ac0e83d, (q31_t)0x3fc8db4a, + (q31_t)0x3acd6e81, (q31_t)0x3fc9e1c6, (q31_t)0x3ad9f4f8, (q31_t)0x3fcae5cd, + (q31_t)0x3ae67ba2, (q31_t)0x3fcbe75e, (q31_t)0x3af3027e, (q31_t)0x3fcce67a, + (q31_t)0x3aff898c, (q31_t)0x3fcde320, (q31_t)0x3b0c10cb, (q31_t)0x3fcedd50, + (q31_t)0x3b18983b, (q31_t)0x3fcfd50b, (q31_t)0x3b251fdc, (q31_t)0x3fd0ca4f, + (q31_t)0x3b31a7ac, (q31_t)0x3fd1bd1e, (q31_t)0x3b3e2fac, (q31_t)0x3fd2ad77, + (q31_t)0x3b4ab7db, (q31_t)0x3fd39b5a, (q31_t)0x3b574039, (q31_t)0x3fd486c7, + (q31_t)0x3b63c8c4, (q31_t)0x3fd56fbe, (q31_t)0x3b70517d, (q31_t)0x3fd6563f, + (q31_t)0x3b7cda63, (q31_t)0x3fd73a4a, (q31_t)0x3b896375, (q31_t)0x3fd81bdf, + (q31_t)0x3b95ecb4, (q31_t)0x3fd8fafe, (q31_t)0x3ba2761e, (q31_t)0x3fd9d7a7, + (q31_t)0x3baeffb3, (q31_t)0x3fdab1d9, (q31_t)0x3bbb8973, (q31_t)0x3fdb8996, + (q31_t)0x3bc8135c, (q31_t)0x3fdc5edc, (q31_t)0x3bd49d70, (q31_t)0x3fdd31ac, + (q31_t)0x3be127ac, (q31_t)0x3fde0205, (q31_t)0x3bedb212, (q31_t)0x3fdecfe8, + (q31_t)0x3bfa3c9f, (q31_t)0x3fdf9b55, (q31_t)0x3c06c754, (q31_t)0x3fe0644b, + (q31_t)0x3c135231, (q31_t)0x3fe12acb, (q31_t)0x3c1fdd34, (q31_t)0x3fe1eed5, + (q31_t)0x3c2c685d, (q31_t)0x3fe2b067, (q31_t)0x3c38f3ac, (q31_t)0x3fe36f84, + (q31_t)0x3c457f21, (q31_t)0x3fe42c2a, (q31_t)0x3c520aba, (q31_t)0x3fe4e659, + (q31_t)0x3c5e9678, (q31_t)0x3fe59e12, (q31_t)0x3c6b2259, (q31_t)0x3fe65354, + (q31_t)0x3c77ae5e, (q31_t)0x3fe7061f, (q31_t)0x3c843a85, (q31_t)0x3fe7b674, + (q31_t)0x3c90c6cf, (q31_t)0x3fe86452, (q31_t)0x3c9d533b, (q31_t)0x3fe90fb9, + (q31_t)0x3ca9dfc8, (q31_t)0x3fe9b8a9, (q31_t)0x3cb66c77, (q31_t)0x3fea5f23, + (q31_t)0x3cc2f945, (q31_t)0x3feb0326, (q31_t)0x3ccf8634, (q31_t)0x3feba4b2, + (q31_t)0x3cdc1342, (q31_t)0x3fec43c7, (q31_t)0x3ce8a06f, (q31_t)0x3fece065, + (q31_t)0x3cf52dbb, (q31_t)0x3fed7a8c, (q31_t)0x3d01bb24, (q31_t)0x3fee123d, + (q31_t)0x3d0e48ab, (q31_t)0x3feea776, (q31_t)0x3d1ad650, (q31_t)0x3fef3a39, + (q31_t)0x3d276410, (q31_t)0x3fefca84, (q31_t)0x3d33f1ed, (q31_t)0x3ff05858, + (q31_t)0x3d407fe6, (q31_t)0x3ff0e3b6, (q31_t)0x3d4d0df9, (q31_t)0x3ff16c9c, + (q31_t)0x3d599c28, (q31_t)0x3ff1f30b, (q31_t)0x3d662a70, (q31_t)0x3ff27703, + (q31_t)0x3d72b8d2, (q31_t)0x3ff2f884, (q31_t)0x3d7f474d, (q31_t)0x3ff3778e, + (q31_t)0x3d8bd5e1, (q31_t)0x3ff3f420, (q31_t)0x3d98648d, (q31_t)0x3ff46e3c, + (q31_t)0x3da4f351, (q31_t)0x3ff4e5e0, (q31_t)0x3db1822c, (q31_t)0x3ff55b0d, + (q31_t)0x3dbe111e, (q31_t)0x3ff5cdc3, (q31_t)0x3dcaa027, (q31_t)0x3ff63e01, + (q31_t)0x3dd72f45, (q31_t)0x3ff6abc8, (q31_t)0x3de3be78, (q31_t)0x3ff71718, + (q31_t)0x3df04dc0, (q31_t)0x3ff77ff1, (q31_t)0x3dfcdd1d, (q31_t)0x3ff7e652, + (q31_t)0x3e096c8d, (q31_t)0x3ff84a3c, (q31_t)0x3e15fc11, (q31_t)0x3ff8abae, + (q31_t)0x3e228ba7, (q31_t)0x3ff90aaa, (q31_t)0x3e2f1b50, (q31_t)0x3ff9672d, + (q31_t)0x3e3bab0b, (q31_t)0x3ff9c13a, (q31_t)0x3e483ad8, (q31_t)0x3ffa18cf, + (q31_t)0x3e54cab5, (q31_t)0x3ffa6dec, (q31_t)0x3e615aa3, (q31_t)0x3ffac092, + (q31_t)0x3e6deaa1, (q31_t)0x3ffb10c1, (q31_t)0x3e7a7aae, (q31_t)0x3ffb5e78, + (q31_t)0x3e870aca, (q31_t)0x3ffba9b8, (q31_t)0x3e939af5, (q31_t)0x3ffbf280, + (q31_t)0x3ea02b2e, (q31_t)0x3ffc38d1, (q31_t)0x3eacbb74, (q31_t)0x3ffc7caa, + (q31_t)0x3eb94bc8, (q31_t)0x3ffcbe0c, (q31_t)0x3ec5dc28, (q31_t)0x3ffcfcf6, + (q31_t)0x3ed26c94, (q31_t)0x3ffd3969, (q31_t)0x3edefd0c, (q31_t)0x3ffd7364, + (q31_t)0x3eeb8d8f, (q31_t)0x3ffdaae7, (q31_t)0x3ef81e1d, (q31_t)0x3ffddff3, + (q31_t)0x3f04aeb5, (q31_t)0x3ffe1288, (q31_t)0x3f113f56, (q31_t)0x3ffe42a4, + (q31_t)0x3f1dd001, (q31_t)0x3ffe704a, (q31_t)0x3f2a60b4, (q31_t)0x3ffe9b77, + (q31_t)0x3f36f170, (q31_t)0x3ffec42d, (q31_t)0x3f438234, (q31_t)0x3ffeea6c, + (q31_t)0x3f5012fe, (q31_t)0x3fff0e32, (q31_t)0x3f5ca3d0, (q31_t)0x3fff2f82, + (q31_t)0x3f6934a8, (q31_t)0x3fff4e59, (q31_t)0x3f75c585, (q31_t)0x3fff6ab9, + (q31_t)0x3f825668, (q31_t)0x3fff84a1, (q31_t)0x3f8ee750, (q31_t)0x3fff9c12, + (q31_t)0x3f9b783c, (q31_t)0x3fffb10b, (q31_t)0x3fa8092c, (q31_t)0x3fffc38c, + (q31_t)0x3fb49a1f, (q31_t)0x3fffd396, (q31_t)0x3fc12b16, (q31_t)0x3fffe128, + (q31_t)0x3fcdbc0f, (q31_t)0x3fffec43, (q31_t)0x3fda4d09, (q31_t)0x3ffff4e6, + (q31_t)0x3fe6de05, (q31_t)0x3ffffb11, (q31_t)0x3ff36f02, (q31_t)0x3ffffec4, +}; + + +/** + @par + Generation of realCoefBQ31 array: + @par + n = 4096 +
for (i = 0; i < n; i++)
+  {
+     pBTable[2 * i]     = 0.5 * (1.0 + sin (2 * PI / (double) (2 * n) * (double) i));
+     pBTable[2 * i + 1] = 0.5 * (1.0 * cos (2 * PI / (double) (2 * n) * (double) i));
+  } 
+ @par + Convert to fixed point Q31 format + round(pBTable[i] * pow(2, 31)) + */ + +const q31_t realCoefBQ31[8192] = { + (q31_t)0x40000000, (q31_t)0x40000000, (q31_t)0x400c90fe, (q31_t)0x3ffffec4, + (q31_t)0x401921fb, (q31_t)0x3ffffb11, (q31_t)0x4025b2f7, (q31_t)0x3ffff4e6, + (q31_t)0x403243f1, (q31_t)0x3fffec43, (q31_t)0x403ed4ea, (q31_t)0x3fffe128, + (q31_t)0x404b65e1, (q31_t)0x3fffd396, (q31_t)0x4057f6d4, (q31_t)0x3fffc38c, + (q31_t)0x406487c4, (q31_t)0x3fffb10b, (q31_t)0x407118b0, (q31_t)0x3fff9c12, + (q31_t)0x407da998, (q31_t)0x3fff84a1, (q31_t)0x408a3a7b, (q31_t)0x3fff6ab9, + (q31_t)0x4096cb58, (q31_t)0x3fff4e59, (q31_t)0x40a35c30, (q31_t)0x3fff2f82, + (q31_t)0x40afed02, (q31_t)0x3fff0e32, (q31_t)0x40bc7dcc, (q31_t)0x3ffeea6c, + (q31_t)0x40c90e90, (q31_t)0x3ffec42d, (q31_t)0x40d59f4c, (q31_t)0x3ffe9b77, + (q31_t)0x40e22fff, (q31_t)0x3ffe704a, (q31_t)0x40eec0aa, (q31_t)0x3ffe42a4, + (q31_t)0x40fb514b, (q31_t)0x3ffe1288, (q31_t)0x4107e1e3, (q31_t)0x3ffddff3, + (q31_t)0x41147271, (q31_t)0x3ffdaae7, (q31_t)0x412102f4, (q31_t)0x3ffd7364, + (q31_t)0x412d936c, (q31_t)0x3ffd3969, (q31_t)0x413a23d8, (q31_t)0x3ffcfcf6, + (q31_t)0x4146b438, (q31_t)0x3ffcbe0c, (q31_t)0x4153448c, (q31_t)0x3ffc7caa, + (q31_t)0x415fd4d2, (q31_t)0x3ffc38d1, (q31_t)0x416c650b, (q31_t)0x3ffbf280, + (q31_t)0x4178f536, (q31_t)0x3ffba9b8, (q31_t)0x41858552, (q31_t)0x3ffb5e78, + (q31_t)0x4192155f, (q31_t)0x3ffb10c1, (q31_t)0x419ea55d, (q31_t)0x3ffac092, + (q31_t)0x41ab354b, (q31_t)0x3ffa6dec, (q31_t)0x41b7c528, (q31_t)0x3ffa18cf, + (q31_t)0x41c454f5, (q31_t)0x3ff9c13a, (q31_t)0x41d0e4b0, (q31_t)0x3ff9672d, + (q31_t)0x41dd7459, (q31_t)0x3ff90aaa, (q31_t)0x41ea03ef, (q31_t)0x3ff8abae, + (q31_t)0x41f69373, (q31_t)0x3ff84a3c, (q31_t)0x420322e3, (q31_t)0x3ff7e652, + (q31_t)0x420fb240, (q31_t)0x3ff77ff1, (q31_t)0x421c4188, (q31_t)0x3ff71718, + (q31_t)0x4228d0bb, (q31_t)0x3ff6abc8, (q31_t)0x42355fd9, (q31_t)0x3ff63e01, + (q31_t)0x4241eee2, (q31_t)0x3ff5cdc3, (q31_t)0x424e7dd4, (q31_t)0x3ff55b0d, + (q31_t)0x425b0caf, (q31_t)0x3ff4e5e0, (q31_t)0x42679b73, (q31_t)0x3ff46e3c, + (q31_t)0x42742a1f, (q31_t)0x3ff3f420, (q31_t)0x4280b8b3, (q31_t)0x3ff3778e, + (q31_t)0x428d472e, (q31_t)0x3ff2f884, (q31_t)0x4299d590, (q31_t)0x3ff27703, + (q31_t)0x42a663d8, (q31_t)0x3ff1f30b, (q31_t)0x42b2f207, (q31_t)0x3ff16c9c, + (q31_t)0x42bf801a, (q31_t)0x3ff0e3b6, (q31_t)0x42cc0e13, (q31_t)0x3ff05858, + (q31_t)0x42d89bf0, (q31_t)0x3fefca84, (q31_t)0x42e529b0, (q31_t)0x3fef3a39, + (q31_t)0x42f1b755, (q31_t)0x3feea776, (q31_t)0x42fe44dc, (q31_t)0x3fee123d, + (q31_t)0x430ad245, (q31_t)0x3fed7a8c, (q31_t)0x43175f91, (q31_t)0x3fece065, + (q31_t)0x4323ecbe, (q31_t)0x3fec43c7, (q31_t)0x433079cc, (q31_t)0x3feba4b2, + (q31_t)0x433d06bb, (q31_t)0x3feb0326, (q31_t)0x43499389, (q31_t)0x3fea5f23, + (q31_t)0x43562038, (q31_t)0x3fe9b8a9, (q31_t)0x4362acc5, (q31_t)0x3fe90fb9, + (q31_t)0x436f3931, (q31_t)0x3fe86452, (q31_t)0x437bc57b, (q31_t)0x3fe7b674, + (q31_t)0x438851a2, (q31_t)0x3fe7061f, (q31_t)0x4394dda7, (q31_t)0x3fe65354, + (q31_t)0x43a16988, (q31_t)0x3fe59e12, (q31_t)0x43adf546, (q31_t)0x3fe4e659, + (q31_t)0x43ba80df, (q31_t)0x3fe42c2a, (q31_t)0x43c70c54, (q31_t)0x3fe36f84, + (q31_t)0x43d397a3, (q31_t)0x3fe2b067, (q31_t)0x43e022cc, (q31_t)0x3fe1eed5, + (q31_t)0x43ecadcf, (q31_t)0x3fe12acb, (q31_t)0x43f938ac, (q31_t)0x3fe0644b, + (q31_t)0x4405c361, (q31_t)0x3fdf9b55, (q31_t)0x44124dee, (q31_t)0x3fdecfe8, + (q31_t)0x441ed854, (q31_t)0x3fde0205, (q31_t)0x442b6290, (q31_t)0x3fdd31ac, + (q31_t)0x4437eca4, (q31_t)0x3fdc5edc, (q31_t)0x4444768d, (q31_t)0x3fdb8996, + (q31_t)0x4451004d, (q31_t)0x3fdab1d9, (q31_t)0x445d89e2, (q31_t)0x3fd9d7a7, + (q31_t)0x446a134c, (q31_t)0x3fd8fafe, (q31_t)0x44769c8b, (q31_t)0x3fd81bdf, + (q31_t)0x4483259d, (q31_t)0x3fd73a4a, (q31_t)0x448fae83, (q31_t)0x3fd6563f, + (q31_t)0x449c373c, (q31_t)0x3fd56fbe, (q31_t)0x44a8bfc7, (q31_t)0x3fd486c7, + (q31_t)0x44b54825, (q31_t)0x3fd39b5a, (q31_t)0x44c1d054, (q31_t)0x3fd2ad77, + (q31_t)0x44ce5854, (q31_t)0x3fd1bd1e, (q31_t)0x44dae024, (q31_t)0x3fd0ca4f, + (q31_t)0x44e767c5, (q31_t)0x3fcfd50b, (q31_t)0x44f3ef35, (q31_t)0x3fcedd50, + (q31_t)0x45007674, (q31_t)0x3fcde320, (q31_t)0x450cfd82, (q31_t)0x3fcce67a, + (q31_t)0x4519845e, (q31_t)0x3fcbe75e, (q31_t)0x45260b08, (q31_t)0x3fcae5cd, + (q31_t)0x4532917f, (q31_t)0x3fc9e1c6, (q31_t)0x453f17c3, (q31_t)0x3fc8db4a, + (q31_t)0x454b9dd3, (q31_t)0x3fc7d258, (q31_t)0x455823ae, (q31_t)0x3fc6c6f0, + (q31_t)0x4564a955, (q31_t)0x3fc5b913, (q31_t)0x45712ec7, (q31_t)0x3fc4a8c1, + (q31_t)0x457db403, (q31_t)0x3fc395f9, (q31_t)0x458a3908, (q31_t)0x3fc280bc, + (q31_t)0x4596bdd7, (q31_t)0x3fc1690a, (q31_t)0x45a3426f, (q31_t)0x3fc04ee3, + (q31_t)0x45afc6d0, (q31_t)0x3fbf3246, (q31_t)0x45bc4af8, (q31_t)0x3fbe1334, + (q31_t)0x45c8cee7, (q31_t)0x3fbcf1ad, (q31_t)0x45d5529e, (q31_t)0x3fbbcdb1, + (q31_t)0x45e1d61b, (q31_t)0x3fbaa740, (q31_t)0x45ee595d, (q31_t)0x3fb97e5a, + (q31_t)0x45fadc66, (q31_t)0x3fb852ff, (q31_t)0x46075f33, (q31_t)0x3fb7252f, + (q31_t)0x4613e1c5, (q31_t)0x3fb5f4ea, (q31_t)0x4620641a, (q31_t)0x3fb4c231, + (q31_t)0x462ce634, (q31_t)0x3fb38d02, (q31_t)0x46396810, (q31_t)0x3fb2555f, + (q31_t)0x4645e9af, (q31_t)0x3fb11b48, (q31_t)0x46526b10, (q31_t)0x3fafdebb, + (q31_t)0x465eec33, (q31_t)0x3fae9fbb, (q31_t)0x466b6d16, (q31_t)0x3fad5e45, + (q31_t)0x4677edbb, (q31_t)0x3fac1a5b, (q31_t)0x46846e1f, (q31_t)0x3faad3fd, + (q31_t)0x4690ee44, (q31_t)0x3fa98b2a, (q31_t)0x469d6e27, (q31_t)0x3fa83fe3, + (q31_t)0x46a9edc9, (q31_t)0x3fa6f228, (q31_t)0x46b66d29, (q31_t)0x3fa5a1f9, + (q31_t)0x46c2ec48, (q31_t)0x3fa44f55, (q31_t)0x46cf6b23, (q31_t)0x3fa2fa3d, + (q31_t)0x46dbe9bb, (q31_t)0x3fa1a2b2, (q31_t)0x46e86810, (q31_t)0x3fa048b2, + (q31_t)0x46f4e620, (q31_t)0x3f9eec3e, (q31_t)0x470163eb, (q31_t)0x3f9d8d56, + (q31_t)0x470de172, (q31_t)0x3f9c2bfb, (q31_t)0x471a5eb3, (q31_t)0x3f9ac82c, + (q31_t)0x4726dbae, (q31_t)0x3f9961e8, (q31_t)0x47335862, (q31_t)0x3f97f932, + (q31_t)0x473fd4cf, (q31_t)0x3f968e07, (q31_t)0x474c50f4, (q31_t)0x3f952069, + (q31_t)0x4758ccd2, (q31_t)0x3f93b058, (q31_t)0x47654867, (q31_t)0x3f923dd2, + (q31_t)0x4771c3b3, (q31_t)0x3f90c8da, (q31_t)0x477e3eb5, (q31_t)0x3f8f516e, + (q31_t)0x478ab96e, (q31_t)0x3f8dd78f, (q31_t)0x479733dc, (q31_t)0x3f8c5b3d, + (q31_t)0x47a3adff, (q31_t)0x3f8adc77, (q31_t)0x47b027d7, (q31_t)0x3f895b3e, + (q31_t)0x47bca163, (q31_t)0x3f87d792, (q31_t)0x47c91aa3, (q31_t)0x3f865174, + (q31_t)0x47d59396, (q31_t)0x3f84c8e2, (q31_t)0x47e20c3b, (q31_t)0x3f833ddd, + (q31_t)0x47ee8493, (q31_t)0x3f81b065, (q31_t)0x47fafc9c, (q31_t)0x3f80207b, + (q31_t)0x48077457, (q31_t)0x3f7e8e1e, (q31_t)0x4813ebc2, (q31_t)0x3f7cf94e, + (q31_t)0x482062de, (q31_t)0x3f7b620c, (q31_t)0x482cd9a9, (q31_t)0x3f79c857, + (q31_t)0x48395024, (q31_t)0x3f782c30, (q31_t)0x4845c64d, (q31_t)0x3f768d96, + (q31_t)0x48523c25, (q31_t)0x3f74ec8a, (q31_t)0x485eb1ab, (q31_t)0x3f73490b, + (q31_t)0x486b26de, (q31_t)0x3f71a31b, (q31_t)0x48779bbe, (q31_t)0x3f6ffab8, + (q31_t)0x4884104b, (q31_t)0x3f6e4fe3, (q31_t)0x48908483, (q31_t)0x3f6ca29c, + (q31_t)0x489cf867, (q31_t)0x3f6af2e3, (q31_t)0x48a96bf6, (q31_t)0x3f6940b8, + (q31_t)0x48b5df30, (q31_t)0x3f678c1c, (q31_t)0x48c25213, (q31_t)0x3f65d50d, + (q31_t)0x48cec4a0, (q31_t)0x3f641b8d, (q31_t)0x48db36d6, (q31_t)0x3f625f9b, + (q31_t)0x48e7a8b5, (q31_t)0x3f60a138, (q31_t)0x48f41a3c, (q31_t)0x3f5ee063, + (q31_t)0x49008b6a, (q31_t)0x3f5d1d1d, (q31_t)0x490cfc40, (q31_t)0x3f5b5765, + (q31_t)0x49196cbc, (q31_t)0x3f598f3c, (q31_t)0x4925dcdf, (q31_t)0x3f57c4a2, + (q31_t)0x49324ca7, (q31_t)0x3f55f796, (q31_t)0x493ebc14, (q31_t)0x3f54281a, + (q31_t)0x494b2b27, (q31_t)0x3f52562c, (q31_t)0x495799dd, (q31_t)0x3f5081cd, + (q31_t)0x49640837, (q31_t)0x3f4eaafe, (q31_t)0x49707635, (q31_t)0x3f4cd1be, + (q31_t)0x497ce3d5, (q31_t)0x3f4af60d, (q31_t)0x49895118, (q31_t)0x3f4917eb, + (q31_t)0x4995bdfd, (q31_t)0x3f473759, (q31_t)0x49a22a83, (q31_t)0x3f455456, + (q31_t)0x49ae96aa, (q31_t)0x3f436ee3, (q31_t)0x49bb0271, (q31_t)0x3f4186ff, + (q31_t)0x49c76dd8, (q31_t)0x3f3f9cab, (q31_t)0x49d3d8df, (q31_t)0x3f3dafe7, + (q31_t)0x49e04385, (q31_t)0x3f3bc0b3, (q31_t)0x49ecadc9, (q31_t)0x3f39cf0e, + (q31_t)0x49f917ac, (q31_t)0x3f37dafa, (q31_t)0x4a05812c, (q31_t)0x3f35e476, + (q31_t)0x4a11ea49, (q31_t)0x3f33eb81, (q31_t)0x4a1e5303, (q31_t)0x3f31f01d, + (q31_t)0x4a2abb59, (q31_t)0x3f2ff24a, (q31_t)0x4a37234a, (q31_t)0x3f2df206, + (q31_t)0x4a438ad7, (q31_t)0x3f2bef53, (q31_t)0x4a4ff1fe, (q31_t)0x3f29ea31, + (q31_t)0x4a5c58c0, (q31_t)0x3f27e29f, (q31_t)0x4a68bf1b, (q31_t)0x3f25d89e, + (q31_t)0x4a752510, (q31_t)0x3f23cc2e, (q31_t)0x4a818a9d, (q31_t)0x3f21bd4e, + (q31_t)0x4a8defc3, (q31_t)0x3f1fabff, (q31_t)0x4a9a5480, (q31_t)0x3f1d9842, + (q31_t)0x4aa6b8d5, (q31_t)0x3f1b8215, (q31_t)0x4ab31cc1, (q31_t)0x3f19697a, + (q31_t)0x4abf8043, (q31_t)0x3f174e70, (q31_t)0x4acbe35b, (q31_t)0x3f1530f7, + (q31_t)0x4ad84609, (q31_t)0x3f13110f, (q31_t)0x4ae4a84b, (q31_t)0x3f10eeb9, + (q31_t)0x4af10a22, (q31_t)0x3f0ec9f5, (q31_t)0x4afd6b8d, (q31_t)0x3f0ca2c2, + (q31_t)0x4b09cc8c, (q31_t)0x3f0a7921, (q31_t)0x4b162d1d, (q31_t)0x3f084d12, + (q31_t)0x4b228d42, (q31_t)0x3f061e95, (q31_t)0x4b2eecf8, (q31_t)0x3f03eda9, + (q31_t)0x4b3b4c40, (q31_t)0x3f01ba50, (q31_t)0x4b47ab19, (q31_t)0x3eff8489, + (q31_t)0x4b540982, (q31_t)0x3efd4c54, (q31_t)0x4b60677c, (q31_t)0x3efb11b1, + (q31_t)0x4b6cc506, (q31_t)0x3ef8d4a1, (q31_t)0x4b79221f, (q31_t)0x3ef69523, + (q31_t)0x4b857ec7, (q31_t)0x3ef45338, (q31_t)0x4b91dafc, (q31_t)0x3ef20ee0, + (q31_t)0x4b9e36c0, (q31_t)0x3eefc81a, (q31_t)0x4baa9211, (q31_t)0x3eed7ee7, + (q31_t)0x4bb6ecef, (q31_t)0x3eeb3347, (q31_t)0x4bc34759, (q31_t)0x3ee8e53a, + (q31_t)0x4bcfa150, (q31_t)0x3ee694c1, (q31_t)0x4bdbfad1, (q31_t)0x3ee441da, + (q31_t)0x4be853de, (q31_t)0x3ee1ec87, (q31_t)0x4bf4ac75, (q31_t)0x3edf94c7, + (q31_t)0x4c010496, (q31_t)0x3edd3a9a, (q31_t)0x4c0d5c41, (q31_t)0x3edade01, + (q31_t)0x4c19b374, (q31_t)0x3ed87efc, (q31_t)0x4c260a31, (q31_t)0x3ed61d8a, + (q31_t)0x4c326075, (q31_t)0x3ed3b9ad, (q31_t)0x4c3eb641, (q31_t)0x3ed15363, + (q31_t)0x4c4b0b94, (q31_t)0x3eceeaad, (q31_t)0x4c57606e, (q31_t)0x3ecc7f8b, + (q31_t)0x4c63b4ce, (q31_t)0x3eca11fe, (q31_t)0x4c7008b3, (q31_t)0x3ec7a205, + (q31_t)0x4c7c5c1e, (q31_t)0x3ec52fa0, (q31_t)0x4c88af0e, (q31_t)0x3ec2bad0, + (q31_t)0x4c950182, (q31_t)0x3ec04394, (q31_t)0x4ca1537a, (q31_t)0x3ebdc9ed, + (q31_t)0x4cada4f5, (q31_t)0x3ebb4ddb, (q31_t)0x4cb9f5f3, (q31_t)0x3eb8cf5d, + (q31_t)0x4cc64673, (q31_t)0x3eb64e75, (q31_t)0x4cd29676, (q31_t)0x3eb3cb21, + (q31_t)0x4cdee5f9, (q31_t)0x3eb14563, (q31_t)0x4ceb34fe, (q31_t)0x3eaebd3a, + (q31_t)0x4cf78383, (q31_t)0x3eac32a6, (q31_t)0x4d03d189, (q31_t)0x3ea9a5a8, + (q31_t)0x4d101f0e, (q31_t)0x3ea7163f, (q31_t)0x4d1c6c11, (q31_t)0x3ea4846c, + (q31_t)0x4d28b894, (q31_t)0x3ea1f02f, (q31_t)0x4d350495, (q31_t)0x3e9f5988, + (q31_t)0x4d415013, (q31_t)0x3e9cc076, (q31_t)0x4d4d9b0e, (q31_t)0x3e9a24fb, + (q31_t)0x4d59e586, (q31_t)0x3e978715, (q31_t)0x4d662f7b, (q31_t)0x3e94e6c6, + (q31_t)0x4d7278eb, (q31_t)0x3e92440d, (q31_t)0x4d7ec1d6, (q31_t)0x3e8f9eeb, + (q31_t)0x4d8b0a3d, (q31_t)0x3e8cf75f, (q31_t)0x4d97521d, (q31_t)0x3e8a4d6a, + (q31_t)0x4da39978, (q31_t)0x3e87a10c, (q31_t)0x4dafe04b, (q31_t)0x3e84f245, + (q31_t)0x4dbc2698, (q31_t)0x3e824114, (q31_t)0x4dc86c5d, (q31_t)0x3e7f8d7b, + (q31_t)0x4dd4b19a, (q31_t)0x3e7cd778, (q31_t)0x4de0f64f, (q31_t)0x3e7a1f0d, + (q31_t)0x4ded3a7b, (q31_t)0x3e77643a, (q31_t)0x4df97e1d, (q31_t)0x3e74a6fd, + (q31_t)0x4e05c135, (q31_t)0x3e71e759, (q31_t)0x4e1203c3, (q31_t)0x3e6f254c, + (q31_t)0x4e1e45c6, (q31_t)0x3e6c60d7, (q31_t)0x4e2a873e, (q31_t)0x3e6999fa, + (q31_t)0x4e36c82a, (q31_t)0x3e66d0b4, (q31_t)0x4e430889, (q31_t)0x3e640507, + (q31_t)0x4e4f485c, (q31_t)0x3e6136f3, (q31_t)0x4e5b87a2, (q31_t)0x3e5e6676, + (q31_t)0x4e67c65a, (q31_t)0x3e5b9392, (q31_t)0x4e740483, (q31_t)0x3e58be47, + (q31_t)0x4e80421e, (q31_t)0x3e55e694, (q31_t)0x4e8c7f2a, (q31_t)0x3e530c7a, + (q31_t)0x4e98bba7, (q31_t)0x3e502ff9, (q31_t)0x4ea4f793, (q31_t)0x3e4d5110, + (q31_t)0x4eb132ef, (q31_t)0x3e4a6fc1, (q31_t)0x4ebd6db9, (q31_t)0x3e478c0b, + (q31_t)0x4ec9a7f3, (q31_t)0x3e44a5ef, (q31_t)0x4ed5e19a, (q31_t)0x3e41bd6c, + (q31_t)0x4ee21aaf, (q31_t)0x3e3ed282, (q31_t)0x4eee5331, (q31_t)0x3e3be532, + (q31_t)0x4efa8b20, (q31_t)0x3e38f57c, (q31_t)0x4f06c27a, (q31_t)0x3e360360, + (q31_t)0x4f12f941, (q31_t)0x3e330ede, (q31_t)0x4f1f2f73, (q31_t)0x3e3017f6, + (q31_t)0x4f2b650f, (q31_t)0x3e2d1ea8, (q31_t)0x4f379a16, (q31_t)0x3e2a22f4, + (q31_t)0x4f43ce86, (q31_t)0x3e2724db, (q31_t)0x4f500260, (q31_t)0x3e24245d, + (q31_t)0x4f5c35a3, (q31_t)0x3e212179, (q31_t)0x4f68684e, (q31_t)0x3e1e1c30, + (q31_t)0x4f749a61, (q31_t)0x3e1b1482, (q31_t)0x4f80cbdc, (q31_t)0x3e180a6f, + (q31_t)0x4f8cfcbe, (q31_t)0x3e14fdf7, (q31_t)0x4f992d06, (q31_t)0x3e11ef1b, + (q31_t)0x4fa55cb4, (q31_t)0x3e0eddd9, (q31_t)0x4fb18bc8, (q31_t)0x3e0bca34, + (q31_t)0x4fbdba40, (q31_t)0x3e08b42a, (q31_t)0x4fc9e81e, (q31_t)0x3e059bbb, + (q31_t)0x4fd6155f, (q31_t)0x3e0280e9, (q31_t)0x4fe24205, (q31_t)0x3dff63b2, + (q31_t)0x4fee6e0d, (q31_t)0x3dfc4418, (q31_t)0x4ffa9979, (q31_t)0x3df9221a, + (q31_t)0x5006c446, (q31_t)0x3df5fdb8, (q31_t)0x5012ee76, (q31_t)0x3df2d6f3, + (q31_t)0x501f1807, (q31_t)0x3defadca, (q31_t)0x502b40f8, (q31_t)0x3dec823e, + (q31_t)0x5037694b, (q31_t)0x3de9544f, (q31_t)0x504390fd, (q31_t)0x3de623fd, + (q31_t)0x504fb80e, (q31_t)0x3de2f148, (q31_t)0x505bde7f, (q31_t)0x3ddfbc30, + (q31_t)0x5068044e, (q31_t)0x3ddc84b5, (q31_t)0x5074297b, (q31_t)0x3dd94ad8, + (q31_t)0x50804e06, (q31_t)0x3dd60e99, (q31_t)0x508c71ee, (q31_t)0x3dd2cff7, + (q31_t)0x50989532, (q31_t)0x3dcf8ef3, (q31_t)0x50a4b7d3, (q31_t)0x3dcc4b8d, + (q31_t)0x50b0d9d0, (q31_t)0x3dc905c5, (q31_t)0x50bcfb28, (q31_t)0x3dc5bd9b, + (q31_t)0x50c91bda, (q31_t)0x3dc2730f, (q31_t)0x50d53be7, (q31_t)0x3dbf2622, + (q31_t)0x50e15b4e, (q31_t)0x3dbbd6d4, (q31_t)0x50ed7a0e, (q31_t)0x3db88524, + (q31_t)0x50f99827, (q31_t)0x3db53113, (q31_t)0x5105b599, (q31_t)0x3db1daa2, + (q31_t)0x5111d263, (q31_t)0x3dae81cf, (q31_t)0x511dee84, (q31_t)0x3dab269b, + (q31_t)0x512a09fc, (q31_t)0x3da7c907, (q31_t)0x513624cb, (q31_t)0x3da46912, + (q31_t)0x51423ef0, (q31_t)0x3da106bd, (q31_t)0x514e586a, (q31_t)0x3d9da208, + (q31_t)0x515a713a, (q31_t)0x3d9a3af2, (q31_t)0x5166895f, (q31_t)0x3d96d17d, + (q31_t)0x5172a0d7, (q31_t)0x3d9365a8, (q31_t)0x517eb7a4, (q31_t)0x3d8ff772, + (q31_t)0x518acdc4, (q31_t)0x3d8c86de, (q31_t)0x5196e337, (q31_t)0x3d8913ea, + (q31_t)0x51a2f7fc, (q31_t)0x3d859e96, (q31_t)0x51af0c13, (q31_t)0x3d8226e4, + (q31_t)0x51bb1f7c, (q31_t)0x3d7eacd2, (q31_t)0x51c73235, (q31_t)0x3d7b3061, + (q31_t)0x51d3443f, (q31_t)0x3d77b192, (q31_t)0x51df5599, (q31_t)0x3d743064, + (q31_t)0x51eb6643, (q31_t)0x3d70acd7, (q31_t)0x51f7763c, (q31_t)0x3d6d26ec, + (q31_t)0x52038584, (q31_t)0x3d699ea3, (q31_t)0x520f941a, (q31_t)0x3d6613fb, + (q31_t)0x521ba1fd, (q31_t)0x3d6286f6, (q31_t)0x5227af2e, (q31_t)0x3d5ef793, + (q31_t)0x5233bbac, (q31_t)0x3d5b65d2, (q31_t)0x523fc776, (q31_t)0x3d57d1b3, + (q31_t)0x524bd28c, (q31_t)0x3d543b37, (q31_t)0x5257dced, (q31_t)0x3d50a25e, + (q31_t)0x5263e699, (q31_t)0x3d4d0728, (q31_t)0x526fef90, (q31_t)0x3d496994, + (q31_t)0x527bf7d1, (q31_t)0x3d45c9a4, (q31_t)0x5287ff5b, (q31_t)0x3d422757, + (q31_t)0x5294062f, (q31_t)0x3d3e82ae, (q31_t)0x52a00c4b, (q31_t)0x3d3adba7, + (q31_t)0x52ac11af, (q31_t)0x3d373245, (q31_t)0x52b8165b, (q31_t)0x3d338687, + (q31_t)0x52c41a4f, (q31_t)0x3d2fd86c, (q31_t)0x52d01d89, (q31_t)0x3d2c27f6, + (q31_t)0x52dc2009, (q31_t)0x3d287523, (q31_t)0x52e821cf, (q31_t)0x3d24bff6, + (q31_t)0x52f422db, (q31_t)0x3d21086c, (q31_t)0x5300232c, (q31_t)0x3d1d4e88, + (q31_t)0x530c22c1, (q31_t)0x3d199248, (q31_t)0x5318219a, (q31_t)0x3d15d3ad, + (q31_t)0x53241fb6, (q31_t)0x3d1212b7, (q31_t)0x53301d16, (q31_t)0x3d0e4f67, + (q31_t)0x533c19b8, (q31_t)0x3d0a89bc, (q31_t)0x5348159d, (q31_t)0x3d06c1b6, + (q31_t)0x535410c3, (q31_t)0x3d02f757, (q31_t)0x53600b2a, (q31_t)0x3cff2a9d, + (q31_t)0x536c04d2, (q31_t)0x3cfb5b89, (q31_t)0x5377fdbb, (q31_t)0x3cf78a1b, + (q31_t)0x5383f5e3, (q31_t)0x3cf3b653, (q31_t)0x538fed4b, (q31_t)0x3cefe032, + (q31_t)0x539be3f2, (q31_t)0x3cec07b8, (q31_t)0x53a7d9d7, (q31_t)0x3ce82ce4, + (q31_t)0x53b3cefa, (q31_t)0x3ce44fb7, (q31_t)0x53bfc35b, (q31_t)0x3ce07031, + (q31_t)0x53cbb6f8, (q31_t)0x3cdc8e52, (q31_t)0x53d7a9d3, (q31_t)0x3cd8aa1b, + (q31_t)0x53e39be9, (q31_t)0x3cd4c38b, (q31_t)0x53ef8d3c, (q31_t)0x3cd0daa2, + (q31_t)0x53fb7dc9, (q31_t)0x3cccef62, (q31_t)0x54076d91, (q31_t)0x3cc901c9, + (q31_t)0x54135c94, (q31_t)0x3cc511d9, (q31_t)0x541f4ad1, (q31_t)0x3cc11f90, + (q31_t)0x542b3846, (q31_t)0x3cbd2af0, (q31_t)0x543724f5, (q31_t)0x3cb933f9, + (q31_t)0x544310dd, (q31_t)0x3cb53aaa, (q31_t)0x544efbfc, (q31_t)0x3cb13f04, + (q31_t)0x545ae653, (q31_t)0x3cad4107, (q31_t)0x5466cfe1, (q31_t)0x3ca940b3, + (q31_t)0x5472b8a5, (q31_t)0x3ca53e09, (q31_t)0x547ea0a0, (q31_t)0x3ca13908, + (q31_t)0x548a87d1, (q31_t)0x3c9d31b0, (q31_t)0x54966e36, (q31_t)0x3c992803, + (q31_t)0x54a253d1, (q31_t)0x3c951bff, (q31_t)0x54ae38a0, (q31_t)0x3c910da5, + (q31_t)0x54ba1ca3, (q31_t)0x3c8cfcf6, (q31_t)0x54c5ffd9, (q31_t)0x3c88e9f1, + (q31_t)0x54d1e242, (q31_t)0x3c84d496, (q31_t)0x54ddc3de, (q31_t)0x3c80bce7, + (q31_t)0x54e9a4ac, (q31_t)0x3c7ca2e2, (q31_t)0x54f584ac, (q31_t)0x3c788688, + (q31_t)0x550163dc, (q31_t)0x3c7467d9, (q31_t)0x550d423d, (q31_t)0x3c7046d6, + (q31_t)0x55191fcf, (q31_t)0x3c6c237e, (q31_t)0x5524fc90, (q31_t)0x3c67fdd1, + (q31_t)0x5530d881, (q31_t)0x3c63d5d1, (q31_t)0x553cb3a0, (q31_t)0x3c5fab7c, + (q31_t)0x55488dee, (q31_t)0x3c5b7ed4, (q31_t)0x5554676a, (q31_t)0x3c574fd8, + (q31_t)0x55604013, (q31_t)0x3c531e88, (q31_t)0x556c17e9, (q31_t)0x3c4eeae5, + (q31_t)0x5577eeec, (q31_t)0x3c4ab4ef, (q31_t)0x5583c51b, (q31_t)0x3c467ca6, + (q31_t)0x558f9a76, (q31_t)0x3c42420a, (q31_t)0x559b6efb, (q31_t)0x3c3e051b, + (q31_t)0x55a742ac, (q31_t)0x3c39c5da, (q31_t)0x55b31587, (q31_t)0x3c358446, + (q31_t)0x55bee78c, (q31_t)0x3c314060, (q31_t)0x55cab8ba, (q31_t)0x3c2cfa28, + (q31_t)0x55d68911, (q31_t)0x3c28b19e, (q31_t)0x55e25890, (q31_t)0x3c2466c2, + (q31_t)0x55ee2738, (q31_t)0x3c201994, (q31_t)0x55f9f507, (q31_t)0x3c1bca16, + (q31_t)0x5605c1fd, (q31_t)0x3c177845, (q31_t)0x56118e1a, (q31_t)0x3c132424, + (q31_t)0x561d595d, (q31_t)0x3c0ecdb2, (q31_t)0x562923c5, (q31_t)0x3c0a74f0, + (q31_t)0x5634ed53, (q31_t)0x3c0619dc, (q31_t)0x5640b606, (q31_t)0x3c01bc78, + (q31_t)0x564c7ddd, (q31_t)0x3bfd5cc4, (q31_t)0x565844d8, (q31_t)0x3bf8fac0, + (q31_t)0x56640af7, (q31_t)0x3bf4966c, (q31_t)0x566fd039, (q31_t)0x3bf02fc9, + (q31_t)0x567b949d, (q31_t)0x3bebc6d5, (q31_t)0x56875823, (q31_t)0x3be75b93, + (q31_t)0x56931acb, (q31_t)0x3be2ee01, (q31_t)0x569edc94, (q31_t)0x3bde7e20, + (q31_t)0x56aa9d7e, (q31_t)0x3bda0bf0, (q31_t)0x56b65d88, (q31_t)0x3bd59771, + (q31_t)0x56c21cb2, (q31_t)0x3bd120a4, (q31_t)0x56cddafb, (q31_t)0x3bcca789, + (q31_t)0x56d99864, (q31_t)0x3bc82c1f, (q31_t)0x56e554ea, (q31_t)0x3bc3ae67, + (q31_t)0x56f1108f, (q31_t)0x3bbf2e62, (q31_t)0x56fccb51, (q31_t)0x3bbaac0e, + (q31_t)0x57088531, (q31_t)0x3bb6276e, (q31_t)0x57143e2d, (q31_t)0x3bb1a080, + (q31_t)0x571ff646, (q31_t)0x3bad1744, (q31_t)0x572bad7a, (q31_t)0x3ba88bbc, + (q31_t)0x573763c9, (q31_t)0x3ba3fde7, (q31_t)0x57431933, (q31_t)0x3b9f6dc5, + (q31_t)0x574ecdb8, (q31_t)0x3b9adb57, (q31_t)0x575a8157, (q31_t)0x3b96469d, + (q31_t)0x5766340f, (q31_t)0x3b91af97, (q31_t)0x5771e5e0, (q31_t)0x3b8d1644, + (q31_t)0x577d96ca, (q31_t)0x3b887aa6, (q31_t)0x578946cc, (q31_t)0x3b83dcbc, + (q31_t)0x5794f5e6, (q31_t)0x3b7f3c87, (q31_t)0x57a0a417, (q31_t)0x3b7a9a07, + (q31_t)0x57ac515f, (q31_t)0x3b75f53c, (q31_t)0x57b7fdbd, (q31_t)0x3b714e25, + (q31_t)0x57c3a931, (q31_t)0x3b6ca4c4, (q31_t)0x57cf53bb, (q31_t)0x3b67f919, + (q31_t)0x57dafd59, (q31_t)0x3b634b23, (q31_t)0x57e6a60c, (q31_t)0x3b5e9ae4, + (q31_t)0x57f24dd3, (q31_t)0x3b59e85a, (q31_t)0x57fdf4ae, (q31_t)0x3b553386, + (q31_t)0x58099a9c, (q31_t)0x3b507c69, (q31_t)0x58153f9d, (q31_t)0x3b4bc303, + (q31_t)0x5820e3b0, (q31_t)0x3b470753, (q31_t)0x582c86d5, (q31_t)0x3b42495a, + (q31_t)0x5838290c, (q31_t)0x3b3d8918, (q31_t)0x5843ca53, (q31_t)0x3b38c68e, + (q31_t)0x584f6aab, (q31_t)0x3b3401bb, (q31_t)0x585b0a13, (q31_t)0x3b2f3aa0, + (q31_t)0x5866a88a, (q31_t)0x3b2a713d, (q31_t)0x58724611, (q31_t)0x3b25a591, + (q31_t)0x587de2a7, (q31_t)0x3b20d79e, (q31_t)0x58897e4a, (q31_t)0x3b1c0764, + (q31_t)0x589518fc, (q31_t)0x3b1734e2, (q31_t)0x58a0b2bb, (q31_t)0x3b126019, + (q31_t)0x58ac4b87, (q31_t)0x3b0d8909, (q31_t)0x58b7e35f, (q31_t)0x3b08afb2, + (q31_t)0x58c37a44, (q31_t)0x3b03d414, (q31_t)0x58cf1034, (q31_t)0x3afef630, + (q31_t)0x58daa52f, (q31_t)0x3afa1605, (q31_t)0x58e63935, (q31_t)0x3af53395, + (q31_t)0x58f1cc45, (q31_t)0x3af04edf, (q31_t)0x58fd5e5f, (q31_t)0x3aeb67e3, + (q31_t)0x5908ef82, (q31_t)0x3ae67ea1, (q31_t)0x59147fae, (q31_t)0x3ae1931a, + (q31_t)0x59200ee3, (q31_t)0x3adca54e, (q31_t)0x592b9d1f, (q31_t)0x3ad7b53d, + (q31_t)0x59372a64, (q31_t)0x3ad2c2e8, (q31_t)0x5942b6af, (q31_t)0x3acdce4d, + (q31_t)0x594e4201, (q31_t)0x3ac8d76f, (q31_t)0x5959cc5a, (q31_t)0x3ac3de4c, + (q31_t)0x596555b8, (q31_t)0x3abee2e5, (q31_t)0x5970de1b, (q31_t)0x3ab9e53a, + (q31_t)0x597c6584, (q31_t)0x3ab4e54c, (q31_t)0x5987ebf0, (q31_t)0x3aafe31b, + (q31_t)0x59937161, (q31_t)0x3aaadea6, (q31_t)0x599ef5d6, (q31_t)0x3aa5d7ee, + (q31_t)0x59aa794d, (q31_t)0x3aa0cef3, (q31_t)0x59b5fbc8, (q31_t)0x3a9bc3b6, + (q31_t)0x59c17d44, (q31_t)0x3a96b636, (q31_t)0x59ccfdc2, (q31_t)0x3a91a674, + (q31_t)0x59d87d42, (q31_t)0x3a8c9470, (q31_t)0x59e3fbc3, (q31_t)0x3a87802a, + (q31_t)0x59ef7944, (q31_t)0x3a8269a3, (q31_t)0x59faf5c5, (q31_t)0x3a7d50da, + (q31_t)0x5a067145, (q31_t)0x3a7835cf, (q31_t)0x5a11ebc5, (q31_t)0x3a731884, + (q31_t)0x5a1d6544, (q31_t)0x3a6df8f8, (q31_t)0x5a28ddc0, (q31_t)0x3a68d72b, + (q31_t)0x5a34553b, (q31_t)0x3a63b31d, (q31_t)0x5a3fcbb3, (q31_t)0x3a5e8cd0, + (q31_t)0x5a4b4128, (q31_t)0x3a596442, (q31_t)0x5a56b599, (q31_t)0x3a543974, + (q31_t)0x5a622907, (q31_t)0x3a4f0c67, (q31_t)0x5a6d9b70, (q31_t)0x3a49dd1a, + (q31_t)0x5a790cd4, (q31_t)0x3a44ab8e, (q31_t)0x5a847d33, (q31_t)0x3a3f77c3, + (q31_t)0x5a8fec8c, (q31_t)0x3a3a41b9, (q31_t)0x5a9b5adf, (q31_t)0x3a350970, + (q31_t)0x5aa6c82b, (q31_t)0x3a2fcee8, (q31_t)0x5ab23471, (q31_t)0x3a2a9223, + (q31_t)0x5abd9faf, (q31_t)0x3a25531f, (q31_t)0x5ac909e5, (q31_t)0x3a2011de, + (q31_t)0x5ad47312, (q31_t)0x3a1ace5f, (q31_t)0x5adfdb37, (q31_t)0x3a1588a2, + (q31_t)0x5aeb4253, (q31_t)0x3a1040a8, (q31_t)0x5af6a865, (q31_t)0x3a0af671, + (q31_t)0x5b020d6c, (q31_t)0x3a05a9fd, (q31_t)0x5b0d716a, (q31_t)0x3a005b4d, + (q31_t)0x5b18d45c, (q31_t)0x39fb0a60, (q31_t)0x5b243643, (q31_t)0x39f5b737, + (q31_t)0x5b2f971e, (q31_t)0x39f061d2, (q31_t)0x5b3af6ec, (q31_t)0x39eb0a31, + (q31_t)0x5b4655ae, (q31_t)0x39e5b054, (q31_t)0x5b51b363, (q31_t)0x39e0543c, + (q31_t)0x5b5d100a, (q31_t)0x39daf5e8, (q31_t)0x5b686ba3, (q31_t)0x39d5955a, + (q31_t)0x5b73c62d, (q31_t)0x39d03291, (q31_t)0x5b7f1fa9, (q31_t)0x39cacd8d, + (q31_t)0x5b8a7815, (q31_t)0x39c5664f, (q31_t)0x5b95cf71, (q31_t)0x39bffcd7, + (q31_t)0x5ba125bd, (q31_t)0x39ba9125, (q31_t)0x5bac7af9, (q31_t)0x39b52339, + (q31_t)0x5bb7cf23, (q31_t)0x39afb313, (q31_t)0x5bc3223c, (q31_t)0x39aa40b4, + (q31_t)0x5bce7442, (q31_t)0x39a4cc1c, (q31_t)0x5bd9c537, (q31_t)0x399f554b, + (q31_t)0x5be51518, (q31_t)0x3999dc42, (q31_t)0x5bf063e6, (q31_t)0x399460ff, + (q31_t)0x5bfbb1a0, (q31_t)0x398ee385, (q31_t)0x5c06fe46, (q31_t)0x398963d2, + (q31_t)0x5c1249d8, (q31_t)0x3983e1e8, (q31_t)0x5c1d9454, (q31_t)0x397e5dc6, + (q31_t)0x5c28ddbb, (q31_t)0x3978d76c, (q31_t)0x5c34260c, (q31_t)0x39734edc, + (q31_t)0x5c3f6d47, (q31_t)0x396dc414, (q31_t)0x5c4ab36b, (q31_t)0x39683715, + (q31_t)0x5c55f878, (q31_t)0x3962a7e0, (q31_t)0x5c613c6d, (q31_t)0x395d1675, + (q31_t)0x5c6c7f4a, (q31_t)0x395782d3, (q31_t)0x5c77c10e, (q31_t)0x3951ecfc, + (q31_t)0x5c8301b9, (q31_t)0x394c54ee, (q31_t)0x5c8e414b, (q31_t)0x3946baac, + (q31_t)0x5c997fc4, (q31_t)0x39411e33, (q31_t)0x5ca4bd21, (q31_t)0x393b7f86, + (q31_t)0x5caff965, (q31_t)0x3935dea4, (q31_t)0x5cbb348d, (q31_t)0x39303b8e, + (q31_t)0x5cc66e99, (q31_t)0x392a9642, (q31_t)0x5cd1a78a, (q31_t)0x3924eec3, + (q31_t)0x5cdcdf5e, (q31_t)0x391f4510, (q31_t)0x5ce81615, (q31_t)0x39199929, + (q31_t)0x5cf34baf, (q31_t)0x3913eb0e, (q31_t)0x5cfe802b, (q31_t)0x390e3ac0, + (q31_t)0x5d09b389, (q31_t)0x3908883f, (q31_t)0x5d14e5c9, (q31_t)0x3902d38b, + (q31_t)0x5d2016e9, (q31_t)0x38fd1ca4, (q31_t)0x5d2b46ea, (q31_t)0x38f7638b, + (q31_t)0x5d3675cb, (q31_t)0x38f1a840, (q31_t)0x5d41a38c, (q31_t)0x38ebeac2, + (q31_t)0x5d4cd02c, (q31_t)0x38e62b13, (q31_t)0x5d57fbaa, (q31_t)0x38e06932, + (q31_t)0x5d632608, (q31_t)0x38daa520, (q31_t)0x5d6e4f43, (q31_t)0x38d4dedd, + (q31_t)0x5d79775c, (q31_t)0x38cf1669, (q31_t)0x5d849e51, (q31_t)0x38c94bc4, + (q31_t)0x5d8fc424, (q31_t)0x38c37eef, (q31_t)0x5d9ae8d2, (q31_t)0x38bdafea, + (q31_t)0x5da60c5d, (q31_t)0x38b7deb4, (q31_t)0x5db12ec3, (q31_t)0x38b20b4f, + (q31_t)0x5dbc5004, (q31_t)0x38ac35ba, (q31_t)0x5dc7701f, (q31_t)0x38a65df6, + (q31_t)0x5dd28f15, (q31_t)0x38a08402, (q31_t)0x5dddace4, (q31_t)0x389aa7e0, + (q31_t)0x5de8c98c, (q31_t)0x3894c98f, (q31_t)0x5df3e50d, (q31_t)0x388ee910, + (q31_t)0x5dfeff67, (q31_t)0x38890663, (q31_t)0x5e0a1898, (q31_t)0x38832187, + (q31_t)0x5e1530a1, (q31_t)0x387d3a7e, (q31_t)0x5e204781, (q31_t)0x38775147, + (q31_t)0x5e2b5d38, (q31_t)0x387165e3, (q31_t)0x5e3671c5, (q31_t)0x386b7852, + (q31_t)0x5e418528, (q31_t)0x38658894, (q31_t)0x5e4c9760, (q31_t)0x385f96a9, + (q31_t)0x5e57a86d, (q31_t)0x3859a292, (q31_t)0x5e62b84f, (q31_t)0x3853ac4f, + (q31_t)0x5e6dc705, (q31_t)0x384db3e0, (q31_t)0x5e78d48e, (q31_t)0x3847b946, + (q31_t)0x5e83e0eb, (q31_t)0x3841bc7f, (q31_t)0x5e8eec1b, (q31_t)0x383bbd8e, + (q31_t)0x5e99f61d, (q31_t)0x3835bc71, (q31_t)0x5ea4fef0, (q31_t)0x382fb92a, + (q31_t)0x5eb00696, (q31_t)0x3829b3b9, (q31_t)0x5ebb0d0d, (q31_t)0x3823ac1d, + (q31_t)0x5ec61254, (q31_t)0x381da256, (q31_t)0x5ed1166b, (q31_t)0x38179666, + (q31_t)0x5edc1953, (q31_t)0x3811884d, (q31_t)0x5ee71b0a, (q31_t)0x380b780a, + (q31_t)0x5ef21b90, (q31_t)0x3805659e, (q31_t)0x5efd1ae4, (q31_t)0x37ff5109, + (q31_t)0x5f081907, (q31_t)0x37f93a4b, (q31_t)0x5f1315f7, (q31_t)0x37f32165, + (q31_t)0x5f1e11b5, (q31_t)0x37ed0657, (q31_t)0x5f290c3f, (q31_t)0x37e6e921, + (q31_t)0x5f340596, (q31_t)0x37e0c9c3, (q31_t)0x5f3efdb9, (q31_t)0x37daa83d, + (q31_t)0x5f49f4a8, (q31_t)0x37d48490, (q31_t)0x5f54ea62, (q31_t)0x37ce5ebd, + (q31_t)0x5f5fdee6, (q31_t)0x37c836c2, (q31_t)0x5f6ad235, (q31_t)0x37c20ca1, + (q31_t)0x5f75c44e, (q31_t)0x37bbe05a, (q31_t)0x5f80b531, (q31_t)0x37b5b1ec, + (q31_t)0x5f8ba4dc, (q31_t)0x37af8159, (q31_t)0x5f969350, (q31_t)0x37a94ea0, + (q31_t)0x5fa1808c, (q31_t)0x37a319c2, (q31_t)0x5fac6c91, (q31_t)0x379ce2be, + (q31_t)0x5fb7575c, (q31_t)0x3796a996, (q31_t)0x5fc240ef, (q31_t)0x37906e49, + (q31_t)0x5fcd2948, (q31_t)0x378a30d8, (q31_t)0x5fd81067, (q31_t)0x3783f143, + (q31_t)0x5fe2f64c, (q31_t)0x377daf89, (q31_t)0x5feddaf6, (q31_t)0x37776bac, + (q31_t)0x5ff8be65, (q31_t)0x377125ac, (q31_t)0x6003a099, (q31_t)0x376add88, + (q31_t)0x600e8190, (q31_t)0x37649341, (q31_t)0x6019614c, (q31_t)0x375e46d8, + (q31_t)0x60243fca, (q31_t)0x3757f84c, (q31_t)0x602f1d0b, (q31_t)0x3751a79e, + (q31_t)0x6039f90f, (q31_t)0x374b54ce, (q31_t)0x6044d3d4, (q31_t)0x3744ffdd, + (q31_t)0x604fad5b, (q31_t)0x373ea8ca, (q31_t)0x605a85a3, (q31_t)0x37384f95, + (q31_t)0x60655cac, (q31_t)0x3731f440, (q31_t)0x60703275, (q31_t)0x372b96ca, + (q31_t)0x607b06fe, (q31_t)0x37253733, (q31_t)0x6085da46, (q31_t)0x371ed57c, + (q31_t)0x6090ac4d, (q31_t)0x371871a5, (q31_t)0x609b7d13, (q31_t)0x37120bae, + (q31_t)0x60a64c97, (q31_t)0x370ba398, (q31_t)0x60b11ad9, (q31_t)0x37053962, + (q31_t)0x60bbe7d8, (q31_t)0x36fecd0e, (q31_t)0x60c6b395, (q31_t)0x36f85e9a, + (q31_t)0x60d17e0d, (q31_t)0x36f1ee09, (q31_t)0x60dc4742, (q31_t)0x36eb7b58, + (q31_t)0x60e70f32, (q31_t)0x36e5068a, (q31_t)0x60f1d5de, (q31_t)0x36de8f9e, + (q31_t)0x60fc9b44, (q31_t)0x36d81695, (q31_t)0x61075f65, (q31_t)0x36d19b6e, + (q31_t)0x61122240, (q31_t)0x36cb1e2a, (q31_t)0x611ce3d5, (q31_t)0x36c49ec9, + (q31_t)0x6127a423, (q31_t)0x36be1d4c, (q31_t)0x61326329, (q31_t)0x36b799b3, + (q31_t)0x613d20e8, (q31_t)0x36b113fd, (q31_t)0x6147dd5f, (q31_t)0x36aa8c2c, + (q31_t)0x6152988d, (q31_t)0x36a4023f, (q31_t)0x615d5273, (q31_t)0x369d7637, + (q31_t)0x61680b0f, (q31_t)0x3696e814, (q31_t)0x6172c262, (q31_t)0x369057d6, + (q31_t)0x617d786a, (q31_t)0x3689c57d, (q31_t)0x61882d28, (q31_t)0x3683310b, + (q31_t)0x6192e09b, (q31_t)0x367c9a7e, (q31_t)0x619d92c2, (q31_t)0x367601d7, + (q31_t)0x61a8439e, (q31_t)0x366f6717, (q31_t)0x61b2f32e, (q31_t)0x3668ca3e, + (q31_t)0x61bda171, (q31_t)0x36622b4c, (q31_t)0x61c84e67, (q31_t)0x365b8a41, + (q31_t)0x61d2fa0f, (q31_t)0x3654e71d, (q31_t)0x61dda46a, (q31_t)0x364e41e2, + (q31_t)0x61e84d76, (q31_t)0x36479a8e, (q31_t)0x61f2f534, (q31_t)0x3640f123, + (q31_t)0x61fd9ba3, (q31_t)0x363a45a0, (q31_t)0x620840c2, (q31_t)0x36339806, + (q31_t)0x6212e492, (q31_t)0x362ce855, (q31_t)0x621d8711, (q31_t)0x3626368d, + (q31_t)0x6228283f, (q31_t)0x361f82af, (q31_t)0x6232c81c, (q31_t)0x3618ccba, + (q31_t)0x623d66a8, (q31_t)0x361214b0, (q31_t)0x624803e2, (q31_t)0x360b5a90, + (q31_t)0x62529fca, (q31_t)0x36049e5b, (q31_t)0x625d3a5e, (q31_t)0x35fde011, + (q31_t)0x6267d3a0, (q31_t)0x35f71fb1, (q31_t)0x62726b8e, (q31_t)0x35f05d3d, + (q31_t)0x627d0228, (q31_t)0x35e998b5, (q31_t)0x6287976e, (q31_t)0x35e2d219, + (q31_t)0x62922b5e, (q31_t)0x35dc0968, (q31_t)0x629cbdfa, (q31_t)0x35d53ea5, + (q31_t)0x62a74f40, (q31_t)0x35ce71ce, (q31_t)0x62b1df30, (q31_t)0x35c7a2e3, + (q31_t)0x62bc6dca, (q31_t)0x35c0d1e7, (q31_t)0x62c6fb0c, (q31_t)0x35b9fed7, + (q31_t)0x62d186f8, (q31_t)0x35b329b5, (q31_t)0x62dc118c, (q31_t)0x35ac5282, + (q31_t)0x62e69ac8, (q31_t)0x35a5793c, (q31_t)0x62f122ab, (q31_t)0x359e9de5, + (q31_t)0x62fba936, (q31_t)0x3597c07d, (q31_t)0x63062e67, (q31_t)0x3590e104, + (q31_t)0x6310b23e, (q31_t)0x3589ff7a, (q31_t)0x631b34bc, (q31_t)0x35831be0, + (q31_t)0x6325b5df, (q31_t)0x357c3636, (q31_t)0x633035a7, (q31_t)0x35754e7c, + (q31_t)0x633ab414, (q31_t)0x356e64b2, (q31_t)0x63453125, (q31_t)0x356778d9, + (q31_t)0x634facda, (q31_t)0x35608af1, (q31_t)0x635a2733, (q31_t)0x35599afa, + (q31_t)0x6364a02e, (q31_t)0x3552a8f4, (q31_t)0x636f17cc, (q31_t)0x354bb4e1, + (q31_t)0x63798e0d, (q31_t)0x3544bebf, (q31_t)0x638402ef, (q31_t)0x353dc68f, + (q31_t)0x638e7673, (q31_t)0x3536cc52, (q31_t)0x6398e898, (q31_t)0x352fd008, + (q31_t)0x63a3595e, (q31_t)0x3528d1b1, (q31_t)0x63adc8c4, (q31_t)0x3521d14d, + (q31_t)0x63b836ca, (q31_t)0x351acedd, (q31_t)0x63c2a36f, (q31_t)0x3513ca60, + (q31_t)0x63cd0eb3, (q31_t)0x350cc3d8, (q31_t)0x63d77896, (q31_t)0x3505bb44, + (q31_t)0x63e1e117, (q31_t)0x34feb0a5, (q31_t)0x63ec4837, (q31_t)0x34f7a3fb, + (q31_t)0x63f6adf3, (q31_t)0x34f09546, (q31_t)0x6401124d, (q31_t)0x34e98487, + (q31_t)0x640b7543, (q31_t)0x34e271bd, (q31_t)0x6415d6d5, (q31_t)0x34db5cea, + (q31_t)0x64203704, (q31_t)0x34d4460c, (q31_t)0x642a95ce, (q31_t)0x34cd2d26, + (q31_t)0x6434f332, (q31_t)0x34c61236, (q31_t)0x643f4f32, (q31_t)0x34bef53d, + (q31_t)0x6449a9cc, (q31_t)0x34b7d63c, (q31_t)0x645402ff, (q31_t)0x34b0b533, + (q31_t)0x645e5acc, (q31_t)0x34a99221, (q31_t)0x6468b132, (q31_t)0x34a26d08, + (q31_t)0x64730631, (q31_t)0x349b45e7, (q31_t)0x647d59c8, (q31_t)0x34941cbf, + (q31_t)0x6487abf7, (q31_t)0x348cf190, (q31_t)0x6491fcbe, (q31_t)0x3485c45b, + (q31_t)0x649c4c1b, (q31_t)0x347e951f, (q31_t)0x64a69a0f, (q31_t)0x347763dd, + (q31_t)0x64b0e699, (q31_t)0x34703095, (q31_t)0x64bb31ba, (q31_t)0x3468fb47, + (q31_t)0x64c57b6f, (q31_t)0x3461c3f5, (q31_t)0x64cfc3ba, (q31_t)0x345a8a9d, + (q31_t)0x64da0a9a, (q31_t)0x34534f41, (q31_t)0x64e4500e, (q31_t)0x344c11e0, + (q31_t)0x64ee9415, (q31_t)0x3444d27b, (q31_t)0x64f8d6b0, (q31_t)0x343d9112, + (q31_t)0x650317df, (q31_t)0x34364da6, (q31_t)0x650d57a0, (q31_t)0x342f0836, + (q31_t)0x651795f3, (q31_t)0x3427c0c3, (q31_t)0x6521d2d8, (q31_t)0x3420774d, + (q31_t)0x652c0e4f, (q31_t)0x34192bd5, (q31_t)0x65364857, (q31_t)0x3411de5b, + (q31_t)0x654080ef, (q31_t)0x340a8edf, (q31_t)0x654ab818, (q31_t)0x34033d61, + (q31_t)0x6554edd1, (q31_t)0x33fbe9e2, (q31_t)0x655f2219, (q31_t)0x33f49462, + (q31_t)0x656954f1, (q31_t)0x33ed3ce1, (q31_t)0x65738657, (q31_t)0x33e5e360, + (q31_t)0x657db64c, (q31_t)0x33de87de, (q31_t)0x6587e4cf, (q31_t)0x33d72a5d, + (q31_t)0x659211df, (q31_t)0x33cfcadc, (q31_t)0x659c3d7c, (q31_t)0x33c8695b, + (q31_t)0x65a667a7, (q31_t)0x33c105db, (q31_t)0x65b0905d, (q31_t)0x33b9a05d, + (q31_t)0x65bab7a0, (q31_t)0x33b238e0, (q31_t)0x65c4dd6e, (q31_t)0x33aacf65, + (q31_t)0x65cf01c8, (q31_t)0x33a363ec, (q31_t)0x65d924ac, (q31_t)0x339bf675, + (q31_t)0x65e3461b, (q31_t)0x33948701, (q31_t)0x65ed6614, (q31_t)0x338d1590, + (q31_t)0x65f78497, (q31_t)0x3385a222, (q31_t)0x6601a1a2, (q31_t)0x337e2cb7, + (q31_t)0x660bbd37, (q31_t)0x3376b551, (q31_t)0x6615d754, (q31_t)0x336f3bee, + (q31_t)0x661feffa, (q31_t)0x3367c090, (q31_t)0x662a0727, (q31_t)0x33604336, + (q31_t)0x66341cdb, (q31_t)0x3358c3e2, (q31_t)0x663e3117, (q31_t)0x33514292, + (q31_t)0x664843d9, (q31_t)0x3349bf48, (q31_t)0x66525521, (q31_t)0x33423a04, + (q31_t)0x665c64ef, (q31_t)0x333ab2c6, (q31_t)0x66667342, (q31_t)0x3333298f, + (q31_t)0x6670801a, (q31_t)0x332b9e5e, (q31_t)0x667a8b77, (q31_t)0x33241134, + (q31_t)0x66849558, (q31_t)0x331c8211, (q31_t)0x668e9dbd, (q31_t)0x3314f0f6, + (q31_t)0x6698a4a6, (q31_t)0x330d5de3, (q31_t)0x66a2aa11, (q31_t)0x3305c8d7, + (q31_t)0x66acadff, (q31_t)0x32fe31d5, (q31_t)0x66b6b070, (q31_t)0x32f698db, + (q31_t)0x66c0b162, (q31_t)0x32eefdea, (q31_t)0x66cab0d6, (q31_t)0x32e76102, + (q31_t)0x66d4aecb, (q31_t)0x32dfc224, (q31_t)0x66deab41, (q31_t)0x32d82150, + (q31_t)0x66e8a637, (q31_t)0x32d07e85, (q31_t)0x66f29fad, (q31_t)0x32c8d9c6, + (q31_t)0x66fc97a3, (q31_t)0x32c13311, (q31_t)0x67068e18, (q31_t)0x32b98a67, + (q31_t)0x6710830c, (q31_t)0x32b1dfc9, (q31_t)0x671a767e, (q31_t)0x32aa3336, + (q31_t)0x6724686e, (q31_t)0x32a284b0, (q31_t)0x672e58dc, (q31_t)0x329ad435, + (q31_t)0x673847c8, (q31_t)0x329321c7, (q31_t)0x67423530, (q31_t)0x328b6d66, + (q31_t)0x674c2115, (q31_t)0x3283b712, (q31_t)0x67560b76, (q31_t)0x327bfecc, + (q31_t)0x675ff452, (q31_t)0x32744493, (q31_t)0x6769dbaa, (q31_t)0x326c8868, + (q31_t)0x6773c17d, (q31_t)0x3264ca4c, (q31_t)0x677da5cb, (q31_t)0x325d0a3e, + (q31_t)0x67878893, (q31_t)0x32554840, (q31_t)0x679169d5, (q31_t)0x324d8450, + (q31_t)0x679b4990, (q31_t)0x3245be70, (q31_t)0x67a527c4, (q31_t)0x323df6a0, + (q31_t)0x67af0472, (q31_t)0x32362ce0, (q31_t)0x67b8df97, (q31_t)0x322e6130, + (q31_t)0x67c2b934, (q31_t)0x32269391, (q31_t)0x67cc9149, (q31_t)0x321ec403, + (q31_t)0x67d667d5, (q31_t)0x3216f287, (q31_t)0x67e03cd8, (q31_t)0x320f1f1c, + (q31_t)0x67ea1052, (q31_t)0x320749c3, (q31_t)0x67f3e241, (q31_t)0x31ff727c, + (q31_t)0x67fdb2a7, (q31_t)0x31f79948, (q31_t)0x68078181, (q31_t)0x31efbe27, + (q31_t)0x68114ed0, (q31_t)0x31e7e118, (q31_t)0x681b1a94, (q31_t)0x31e0021e, + (q31_t)0x6824e4cc, (q31_t)0x31d82137, (q31_t)0x682ead78, (q31_t)0x31d03e64, + (q31_t)0x68387498, (q31_t)0x31c859a5, (q31_t)0x68423a2a, (q31_t)0x31c072fb, + (q31_t)0x684bfe2f, (q31_t)0x31b88a66, (q31_t)0x6855c0a6, (q31_t)0x31b09fe7, + (q31_t)0x685f8190, (q31_t)0x31a8b37c, (q31_t)0x686940ea, (q31_t)0x31a0c528, + (q31_t)0x6872feb6, (q31_t)0x3198d4ea, (q31_t)0x687cbaf3, (q31_t)0x3190e2c3, + (q31_t)0x688675a0, (q31_t)0x3188eeb2, (q31_t)0x68902ebd, (q31_t)0x3180f8b8, + (q31_t)0x6899e64a, (q31_t)0x317900d6, (q31_t)0x68a39c46, (q31_t)0x3171070c, + (q31_t)0x68ad50b1, (q31_t)0x31690b59, (q31_t)0x68b7038b, (q31_t)0x31610dbf, + (q31_t)0x68c0b4d2, (q31_t)0x31590e3e, (q31_t)0x68ca6488, (q31_t)0x31510cd5, + (q31_t)0x68d412ab, (q31_t)0x31490986, (q31_t)0x68ddbf3b, (q31_t)0x31410450, + (q31_t)0x68e76a37, (q31_t)0x3138fd35, (q31_t)0x68f113a0, (q31_t)0x3130f433, + (q31_t)0x68fabb75, (q31_t)0x3128e94c, (q31_t)0x690461b5, (q31_t)0x3120dc80, + (q31_t)0x690e0661, (q31_t)0x3118cdcf, (q31_t)0x6917a977, (q31_t)0x3110bd39, + (q31_t)0x69214af8, (q31_t)0x3108aabf, (q31_t)0x692aeae3, (q31_t)0x31009661, + (q31_t)0x69348937, (q31_t)0x30f8801f, (q31_t)0x693e25f5, (q31_t)0x30f067fb, + (q31_t)0x6947c11c, (q31_t)0x30e84df3, (q31_t)0x69515aab, (q31_t)0x30e03208, + (q31_t)0x695af2a3, (q31_t)0x30d8143b, (q31_t)0x69648902, (q31_t)0x30cff48c, + (q31_t)0x696e1dc9, (q31_t)0x30c7d2fb, (q31_t)0x6977b0f7, (q31_t)0x30bfaf89, + (q31_t)0x6981428c, (q31_t)0x30b78a36, (q31_t)0x698ad287, (q31_t)0x30af6302, + (q31_t)0x699460e8, (q31_t)0x30a739ed, (q31_t)0x699dedaf, (q31_t)0x309f0ef8, + (q31_t)0x69a778db, (q31_t)0x3096e223, (q31_t)0x69b1026c, (q31_t)0x308eb36f, + (q31_t)0x69ba8a61, (q31_t)0x308682dc, (q31_t)0x69c410ba, (q31_t)0x307e5069, + (q31_t)0x69cd9578, (q31_t)0x30761c18, (q31_t)0x69d71899, (q31_t)0x306de5e9, + (q31_t)0x69e09a1c, (q31_t)0x3065addb, (q31_t)0x69ea1a03, (q31_t)0x305d73f0, + (q31_t)0x69f3984c, (q31_t)0x30553828, (q31_t)0x69fd14f6, (q31_t)0x304cfa83, + (q31_t)0x6a069003, (q31_t)0x3044bb00, (q31_t)0x6a100970, (q31_t)0x303c79a2, + (q31_t)0x6a19813f, (q31_t)0x30343667, (q31_t)0x6a22f76e, (q31_t)0x302bf151, + (q31_t)0x6a2c6bfd, (q31_t)0x3023aa5f, (q31_t)0x6a35deeb, (q31_t)0x301b6193, + (q31_t)0x6a3f503a, (q31_t)0x301316eb, (q31_t)0x6a48bfe7, (q31_t)0x300aca69, + (q31_t)0x6a522df3, (q31_t)0x30027c0c, (q31_t)0x6a5b9a5d, (q31_t)0x2ffa2bd6, + (q31_t)0x6a650525, (q31_t)0x2ff1d9c7, (q31_t)0x6a6e6e4b, (q31_t)0x2fe985de, + (q31_t)0x6a77d5ce, (q31_t)0x2fe1301c, (q31_t)0x6a813bae, (q31_t)0x2fd8d882, + (q31_t)0x6a8a9fea, (q31_t)0x2fd07f0f, (q31_t)0x6a940283, (q31_t)0x2fc823c5, + (q31_t)0x6a9d6377, (q31_t)0x2fbfc6a3, (q31_t)0x6aa6c2c6, (q31_t)0x2fb767aa, + (q31_t)0x6ab02071, (q31_t)0x2faf06da, (q31_t)0x6ab97c77, (q31_t)0x2fa6a433, + (q31_t)0x6ac2d6d6, (q31_t)0x2f9e3fb6, (q31_t)0x6acc2f90, (q31_t)0x2f95d963, + (q31_t)0x6ad586a3, (q31_t)0x2f8d713a, (q31_t)0x6adedc10, (q31_t)0x2f85073c, + (q31_t)0x6ae82fd5, (q31_t)0x2f7c9b69, (q31_t)0x6af181f3, (q31_t)0x2f742dc1, + (q31_t)0x6afad269, (q31_t)0x2f6bbe45, (q31_t)0x6b042137, (q31_t)0x2f634cf5, + (q31_t)0x6b0d6e5c, (q31_t)0x2f5ad9d1, (q31_t)0x6b16b9d9, (q31_t)0x2f5264da, + (q31_t)0x6b2003ac, (q31_t)0x2f49ee0f, (q31_t)0x6b294bd5, (q31_t)0x2f417573, + (q31_t)0x6b329255, (q31_t)0x2f38fb03, (q31_t)0x6b3bd72a, (q31_t)0x2f307ec2, + (q31_t)0x6b451a55, (q31_t)0x2f2800af, (q31_t)0x6b4e5bd4, (q31_t)0x2f1f80ca, + (q31_t)0x6b579ba8, (q31_t)0x2f16ff14, (q31_t)0x6b60d9d0, (q31_t)0x2f0e7b8e, + (q31_t)0x6b6a164d, (q31_t)0x2f05f637, (q31_t)0x6b73511c, (q31_t)0x2efd6f10, + (q31_t)0x6b7c8a3f, (q31_t)0x2ef4e619, (q31_t)0x6b85c1b5, (q31_t)0x2eec5b53, + (q31_t)0x6b8ef77d, (q31_t)0x2ee3cebe, (q31_t)0x6b982b97, (q31_t)0x2edb405a, + (q31_t)0x6ba15e03, (q31_t)0x2ed2b027, (q31_t)0x6baa8ec0, (q31_t)0x2eca1e27, + (q31_t)0x6bb3bdce, (q31_t)0x2ec18a58, (q31_t)0x6bbceb2d, (q31_t)0x2eb8f4bc, + (q31_t)0x6bc616dd, (q31_t)0x2eb05d53, (q31_t)0x6bcf40dc, (q31_t)0x2ea7c41e, + (q31_t)0x6bd8692b, (q31_t)0x2e9f291b, (q31_t)0x6be18fc9, (q31_t)0x2e968c4d, + (q31_t)0x6beab4b6, (q31_t)0x2e8dedb3, (q31_t)0x6bf3d7f2, (q31_t)0x2e854d4d, + (q31_t)0x6bfcf97c, (q31_t)0x2e7cab1c, (q31_t)0x6c061953, (q31_t)0x2e740720, + (q31_t)0x6c0f3779, (q31_t)0x2e6b615a, (q31_t)0x6c1853eb, (q31_t)0x2e62b9ca, + (q31_t)0x6c216eaa, (q31_t)0x2e5a1070, (q31_t)0x6c2a87b6, (q31_t)0x2e51654c, + (q31_t)0x6c339f0e, (q31_t)0x2e48b860, (q31_t)0x6c3cb4b1, (q31_t)0x2e4009aa, + (q31_t)0x6c45c8a0, (q31_t)0x2e37592c, (q31_t)0x6c4edada, (q31_t)0x2e2ea6e6, + (q31_t)0x6c57eb5e, (q31_t)0x2e25f2d8, (q31_t)0x6c60fa2d, (q31_t)0x2e1d3d03, + (q31_t)0x6c6a0746, (q31_t)0x2e148566, (q31_t)0x6c7312a9, (q31_t)0x2e0bcc03, + (q31_t)0x6c7c1c55, (q31_t)0x2e0310d9, (q31_t)0x6c85244a, (q31_t)0x2dfa53e9, + (q31_t)0x6c8e2a87, (q31_t)0x2df19534, (q31_t)0x6c972f0d, (q31_t)0x2de8d4b8, + (q31_t)0x6ca031da, (q31_t)0x2de01278, (q31_t)0x6ca932ef, (q31_t)0x2dd74e73, + (q31_t)0x6cb2324c, (q31_t)0x2dce88aa, (q31_t)0x6cbb2fef, (q31_t)0x2dc5c11c, + (q31_t)0x6cc42bd9, (q31_t)0x2dbcf7cb, (q31_t)0x6ccd2609, (q31_t)0x2db42cb6, + (q31_t)0x6cd61e7f, (q31_t)0x2dab5fdf, (q31_t)0x6cdf153a, (q31_t)0x2da29144, + (q31_t)0x6ce80a3a, (q31_t)0x2d99c0e7, (q31_t)0x6cf0fd80, (q31_t)0x2d90eec8, + (q31_t)0x6cf9ef09, (q31_t)0x2d881ae8, (q31_t)0x6d02ded7, (q31_t)0x2d7f4545, + (q31_t)0x6d0bcce8, (q31_t)0x2d766de2, (q31_t)0x6d14b93d, (q31_t)0x2d6d94bf, + (q31_t)0x6d1da3d5, (q31_t)0x2d64b9da, (q31_t)0x6d268cb0, (q31_t)0x2d5bdd36, + (q31_t)0x6d2f73cd, (q31_t)0x2d52fed2, (q31_t)0x6d38592c, (q31_t)0x2d4a1eaf, + (q31_t)0x6d413ccd, (q31_t)0x2d413ccd, (q31_t)0x6d4a1eaf, (q31_t)0x2d38592c, + (q31_t)0x6d52fed2, (q31_t)0x2d2f73cd, (q31_t)0x6d5bdd36, (q31_t)0x2d268cb0, + (q31_t)0x6d64b9da, (q31_t)0x2d1da3d5, (q31_t)0x6d6d94bf, (q31_t)0x2d14b93d, + (q31_t)0x6d766de2, (q31_t)0x2d0bcce8, (q31_t)0x6d7f4545, (q31_t)0x2d02ded7, + (q31_t)0x6d881ae8, (q31_t)0x2cf9ef09, (q31_t)0x6d90eec8, (q31_t)0x2cf0fd80, + (q31_t)0x6d99c0e7, (q31_t)0x2ce80a3a, (q31_t)0x6da29144, (q31_t)0x2cdf153a, + (q31_t)0x6dab5fdf, (q31_t)0x2cd61e7f, (q31_t)0x6db42cb6, (q31_t)0x2ccd2609, + (q31_t)0x6dbcf7cb, (q31_t)0x2cc42bd9, (q31_t)0x6dc5c11c, (q31_t)0x2cbb2fef, + (q31_t)0x6dce88aa, (q31_t)0x2cb2324c, (q31_t)0x6dd74e73, (q31_t)0x2ca932ef, + (q31_t)0x6de01278, (q31_t)0x2ca031da, (q31_t)0x6de8d4b8, (q31_t)0x2c972f0d, + (q31_t)0x6df19534, (q31_t)0x2c8e2a87, (q31_t)0x6dfa53e9, (q31_t)0x2c85244a, + (q31_t)0x6e0310d9, (q31_t)0x2c7c1c55, (q31_t)0x6e0bcc03, (q31_t)0x2c7312a9, + (q31_t)0x6e148566, (q31_t)0x2c6a0746, (q31_t)0x6e1d3d03, (q31_t)0x2c60fa2d, + (q31_t)0x6e25f2d8, (q31_t)0x2c57eb5e, (q31_t)0x6e2ea6e6, (q31_t)0x2c4edada, + (q31_t)0x6e37592c, (q31_t)0x2c45c8a0, (q31_t)0x6e4009aa, (q31_t)0x2c3cb4b1, + (q31_t)0x6e48b860, (q31_t)0x2c339f0e, (q31_t)0x6e51654c, (q31_t)0x2c2a87b6, + (q31_t)0x6e5a1070, (q31_t)0x2c216eaa, (q31_t)0x6e62b9ca, (q31_t)0x2c1853eb, + (q31_t)0x6e6b615a, (q31_t)0x2c0f3779, (q31_t)0x6e740720, (q31_t)0x2c061953, + (q31_t)0x6e7cab1c, (q31_t)0x2bfcf97c, (q31_t)0x6e854d4d, (q31_t)0x2bf3d7f2, + (q31_t)0x6e8dedb3, (q31_t)0x2beab4b6, (q31_t)0x6e968c4d, (q31_t)0x2be18fc9, + (q31_t)0x6e9f291b, (q31_t)0x2bd8692b, (q31_t)0x6ea7c41e, (q31_t)0x2bcf40dc, + (q31_t)0x6eb05d53, (q31_t)0x2bc616dd, (q31_t)0x6eb8f4bc, (q31_t)0x2bbceb2d, + (q31_t)0x6ec18a58, (q31_t)0x2bb3bdce, (q31_t)0x6eca1e27, (q31_t)0x2baa8ec0, + (q31_t)0x6ed2b027, (q31_t)0x2ba15e03, (q31_t)0x6edb405a, (q31_t)0x2b982b97, + (q31_t)0x6ee3cebe, (q31_t)0x2b8ef77d, (q31_t)0x6eec5b53, (q31_t)0x2b85c1b5, + (q31_t)0x6ef4e619, (q31_t)0x2b7c8a3f, (q31_t)0x6efd6f10, (q31_t)0x2b73511c, + (q31_t)0x6f05f637, (q31_t)0x2b6a164d, (q31_t)0x6f0e7b8e, (q31_t)0x2b60d9d0, + (q31_t)0x6f16ff14, (q31_t)0x2b579ba8, (q31_t)0x6f1f80ca, (q31_t)0x2b4e5bd4, + (q31_t)0x6f2800af, (q31_t)0x2b451a55, (q31_t)0x6f307ec2, (q31_t)0x2b3bd72a, + (q31_t)0x6f38fb03, (q31_t)0x2b329255, (q31_t)0x6f417573, (q31_t)0x2b294bd5, + (q31_t)0x6f49ee0f, (q31_t)0x2b2003ac, (q31_t)0x6f5264da, (q31_t)0x2b16b9d9, + (q31_t)0x6f5ad9d1, (q31_t)0x2b0d6e5c, (q31_t)0x6f634cf5, (q31_t)0x2b042137, + (q31_t)0x6f6bbe45, (q31_t)0x2afad269, (q31_t)0x6f742dc1, (q31_t)0x2af181f3, + (q31_t)0x6f7c9b69, (q31_t)0x2ae82fd5, (q31_t)0x6f85073c, (q31_t)0x2adedc10, + (q31_t)0x6f8d713a, (q31_t)0x2ad586a3, (q31_t)0x6f95d963, (q31_t)0x2acc2f90, + (q31_t)0x6f9e3fb6, (q31_t)0x2ac2d6d6, (q31_t)0x6fa6a433, (q31_t)0x2ab97c77, + (q31_t)0x6faf06da, (q31_t)0x2ab02071, (q31_t)0x6fb767aa, (q31_t)0x2aa6c2c6, + (q31_t)0x6fbfc6a3, (q31_t)0x2a9d6377, (q31_t)0x6fc823c5, (q31_t)0x2a940283, + (q31_t)0x6fd07f0f, (q31_t)0x2a8a9fea, (q31_t)0x6fd8d882, (q31_t)0x2a813bae, + (q31_t)0x6fe1301c, (q31_t)0x2a77d5ce, (q31_t)0x6fe985de, (q31_t)0x2a6e6e4b, + (q31_t)0x6ff1d9c7, (q31_t)0x2a650525, (q31_t)0x6ffa2bd6, (q31_t)0x2a5b9a5d, + (q31_t)0x70027c0c, (q31_t)0x2a522df3, (q31_t)0x700aca69, (q31_t)0x2a48bfe7, + (q31_t)0x701316eb, (q31_t)0x2a3f503a, (q31_t)0x701b6193, (q31_t)0x2a35deeb, + (q31_t)0x7023aa5f, (q31_t)0x2a2c6bfd, (q31_t)0x702bf151, (q31_t)0x2a22f76e, + (q31_t)0x70343667, (q31_t)0x2a19813f, (q31_t)0x703c79a2, (q31_t)0x2a100970, + (q31_t)0x7044bb00, (q31_t)0x2a069003, (q31_t)0x704cfa83, (q31_t)0x29fd14f6, + (q31_t)0x70553828, (q31_t)0x29f3984c, (q31_t)0x705d73f0, (q31_t)0x29ea1a03, + (q31_t)0x7065addb, (q31_t)0x29e09a1c, (q31_t)0x706de5e9, (q31_t)0x29d71899, + (q31_t)0x70761c18, (q31_t)0x29cd9578, (q31_t)0x707e5069, (q31_t)0x29c410ba, + (q31_t)0x708682dc, (q31_t)0x29ba8a61, (q31_t)0x708eb36f, (q31_t)0x29b1026c, + (q31_t)0x7096e223, (q31_t)0x29a778db, (q31_t)0x709f0ef8, (q31_t)0x299dedaf, + (q31_t)0x70a739ed, (q31_t)0x299460e8, (q31_t)0x70af6302, (q31_t)0x298ad287, + (q31_t)0x70b78a36, (q31_t)0x2981428c, (q31_t)0x70bfaf89, (q31_t)0x2977b0f7, + (q31_t)0x70c7d2fb, (q31_t)0x296e1dc9, (q31_t)0x70cff48c, (q31_t)0x29648902, + (q31_t)0x70d8143b, (q31_t)0x295af2a3, (q31_t)0x70e03208, (q31_t)0x29515aab, + (q31_t)0x70e84df3, (q31_t)0x2947c11c, (q31_t)0x70f067fb, (q31_t)0x293e25f5, + (q31_t)0x70f8801f, (q31_t)0x29348937, (q31_t)0x71009661, (q31_t)0x292aeae3, + (q31_t)0x7108aabf, (q31_t)0x29214af8, (q31_t)0x7110bd39, (q31_t)0x2917a977, + (q31_t)0x7118cdcf, (q31_t)0x290e0661, (q31_t)0x7120dc80, (q31_t)0x290461b5, + (q31_t)0x7128e94c, (q31_t)0x28fabb75, (q31_t)0x7130f433, (q31_t)0x28f113a0, + (q31_t)0x7138fd35, (q31_t)0x28e76a37, (q31_t)0x71410450, (q31_t)0x28ddbf3b, + (q31_t)0x71490986, (q31_t)0x28d412ab, (q31_t)0x71510cd5, (q31_t)0x28ca6488, + (q31_t)0x71590e3e, (q31_t)0x28c0b4d2, (q31_t)0x71610dbf, (q31_t)0x28b7038b, + (q31_t)0x71690b59, (q31_t)0x28ad50b1, (q31_t)0x7171070c, (q31_t)0x28a39c46, + (q31_t)0x717900d6, (q31_t)0x2899e64a, (q31_t)0x7180f8b8, (q31_t)0x28902ebd, + (q31_t)0x7188eeb2, (q31_t)0x288675a0, (q31_t)0x7190e2c3, (q31_t)0x287cbaf3, + (q31_t)0x7198d4ea, (q31_t)0x2872feb6, (q31_t)0x71a0c528, (q31_t)0x286940ea, + (q31_t)0x71a8b37c, (q31_t)0x285f8190, (q31_t)0x71b09fe7, (q31_t)0x2855c0a6, + (q31_t)0x71b88a66, (q31_t)0x284bfe2f, (q31_t)0x71c072fb, (q31_t)0x28423a2a, + (q31_t)0x71c859a5, (q31_t)0x28387498, (q31_t)0x71d03e64, (q31_t)0x282ead78, + (q31_t)0x71d82137, (q31_t)0x2824e4cc, (q31_t)0x71e0021e, (q31_t)0x281b1a94, + (q31_t)0x71e7e118, (q31_t)0x28114ed0, (q31_t)0x71efbe27, (q31_t)0x28078181, + (q31_t)0x71f79948, (q31_t)0x27fdb2a7, (q31_t)0x71ff727c, (q31_t)0x27f3e241, + (q31_t)0x720749c3, (q31_t)0x27ea1052, (q31_t)0x720f1f1c, (q31_t)0x27e03cd8, + (q31_t)0x7216f287, (q31_t)0x27d667d5, (q31_t)0x721ec403, (q31_t)0x27cc9149, + (q31_t)0x72269391, (q31_t)0x27c2b934, (q31_t)0x722e6130, (q31_t)0x27b8df97, + (q31_t)0x72362ce0, (q31_t)0x27af0472, (q31_t)0x723df6a0, (q31_t)0x27a527c4, + (q31_t)0x7245be70, (q31_t)0x279b4990, (q31_t)0x724d8450, (q31_t)0x279169d5, + (q31_t)0x72554840, (q31_t)0x27878893, (q31_t)0x725d0a3e, (q31_t)0x277da5cb, + (q31_t)0x7264ca4c, (q31_t)0x2773c17d, (q31_t)0x726c8868, (q31_t)0x2769dbaa, + (q31_t)0x72744493, (q31_t)0x275ff452, (q31_t)0x727bfecc, (q31_t)0x27560b76, + (q31_t)0x7283b712, (q31_t)0x274c2115, (q31_t)0x728b6d66, (q31_t)0x27423530, + (q31_t)0x729321c7, (q31_t)0x273847c8, (q31_t)0x729ad435, (q31_t)0x272e58dc, + (q31_t)0x72a284b0, (q31_t)0x2724686e, (q31_t)0x72aa3336, (q31_t)0x271a767e, + (q31_t)0x72b1dfc9, (q31_t)0x2710830c, (q31_t)0x72b98a67, (q31_t)0x27068e18, + (q31_t)0x72c13311, (q31_t)0x26fc97a3, (q31_t)0x72c8d9c6, (q31_t)0x26f29fad, + (q31_t)0x72d07e85, (q31_t)0x26e8a637, (q31_t)0x72d82150, (q31_t)0x26deab41, + (q31_t)0x72dfc224, (q31_t)0x26d4aecb, (q31_t)0x72e76102, (q31_t)0x26cab0d6, + (q31_t)0x72eefdea, (q31_t)0x26c0b162, (q31_t)0x72f698db, (q31_t)0x26b6b070, + (q31_t)0x72fe31d5, (q31_t)0x26acadff, (q31_t)0x7305c8d7, (q31_t)0x26a2aa11, + (q31_t)0x730d5de3, (q31_t)0x2698a4a6, (q31_t)0x7314f0f6, (q31_t)0x268e9dbd, + (q31_t)0x731c8211, (q31_t)0x26849558, (q31_t)0x73241134, (q31_t)0x267a8b77, + (q31_t)0x732b9e5e, (q31_t)0x2670801a, (q31_t)0x7333298f, (q31_t)0x26667342, + (q31_t)0x733ab2c6, (q31_t)0x265c64ef, (q31_t)0x73423a04, (q31_t)0x26525521, + (q31_t)0x7349bf48, (q31_t)0x264843d9, (q31_t)0x73514292, (q31_t)0x263e3117, + (q31_t)0x7358c3e2, (q31_t)0x26341cdb, (q31_t)0x73604336, (q31_t)0x262a0727, + (q31_t)0x7367c090, (q31_t)0x261feffa, (q31_t)0x736f3bee, (q31_t)0x2615d754, + (q31_t)0x7376b551, (q31_t)0x260bbd37, (q31_t)0x737e2cb7, (q31_t)0x2601a1a2, + (q31_t)0x7385a222, (q31_t)0x25f78497, (q31_t)0x738d1590, (q31_t)0x25ed6614, + (q31_t)0x73948701, (q31_t)0x25e3461b, (q31_t)0x739bf675, (q31_t)0x25d924ac, + (q31_t)0x73a363ec, (q31_t)0x25cf01c8, (q31_t)0x73aacf65, (q31_t)0x25c4dd6e, + (q31_t)0x73b238e0, (q31_t)0x25bab7a0, (q31_t)0x73b9a05d, (q31_t)0x25b0905d, + (q31_t)0x73c105db, (q31_t)0x25a667a7, (q31_t)0x73c8695b, (q31_t)0x259c3d7c, + (q31_t)0x73cfcadc, (q31_t)0x259211df, (q31_t)0x73d72a5d, (q31_t)0x2587e4cf, + (q31_t)0x73de87de, (q31_t)0x257db64c, (q31_t)0x73e5e360, (q31_t)0x25738657, + (q31_t)0x73ed3ce1, (q31_t)0x256954f1, (q31_t)0x73f49462, (q31_t)0x255f2219, + (q31_t)0x73fbe9e2, (q31_t)0x2554edd1, (q31_t)0x74033d61, (q31_t)0x254ab818, + (q31_t)0x740a8edf, (q31_t)0x254080ef, (q31_t)0x7411de5b, (q31_t)0x25364857, + (q31_t)0x74192bd5, (q31_t)0x252c0e4f, (q31_t)0x7420774d, (q31_t)0x2521d2d8, + (q31_t)0x7427c0c3, (q31_t)0x251795f3, (q31_t)0x742f0836, (q31_t)0x250d57a0, + (q31_t)0x74364da6, (q31_t)0x250317df, (q31_t)0x743d9112, (q31_t)0x24f8d6b0, + (q31_t)0x7444d27b, (q31_t)0x24ee9415, (q31_t)0x744c11e0, (q31_t)0x24e4500e, + (q31_t)0x74534f41, (q31_t)0x24da0a9a, (q31_t)0x745a8a9d, (q31_t)0x24cfc3ba, + (q31_t)0x7461c3f5, (q31_t)0x24c57b6f, (q31_t)0x7468fb47, (q31_t)0x24bb31ba, + (q31_t)0x74703095, (q31_t)0x24b0e699, (q31_t)0x747763dd, (q31_t)0x24a69a0f, + (q31_t)0x747e951f, (q31_t)0x249c4c1b, (q31_t)0x7485c45b, (q31_t)0x2491fcbe, + (q31_t)0x748cf190, (q31_t)0x2487abf7, (q31_t)0x74941cbf, (q31_t)0x247d59c8, + (q31_t)0x749b45e7, (q31_t)0x24730631, (q31_t)0x74a26d08, (q31_t)0x2468b132, + (q31_t)0x74a99221, (q31_t)0x245e5acc, (q31_t)0x74b0b533, (q31_t)0x245402ff, + (q31_t)0x74b7d63c, (q31_t)0x2449a9cc, (q31_t)0x74bef53d, (q31_t)0x243f4f32, + (q31_t)0x74c61236, (q31_t)0x2434f332, (q31_t)0x74cd2d26, (q31_t)0x242a95ce, + (q31_t)0x74d4460c, (q31_t)0x24203704, (q31_t)0x74db5cea, (q31_t)0x2415d6d5, + (q31_t)0x74e271bd, (q31_t)0x240b7543, (q31_t)0x74e98487, (q31_t)0x2401124d, + (q31_t)0x74f09546, (q31_t)0x23f6adf3, (q31_t)0x74f7a3fb, (q31_t)0x23ec4837, + (q31_t)0x74feb0a5, (q31_t)0x23e1e117, (q31_t)0x7505bb44, (q31_t)0x23d77896, + (q31_t)0x750cc3d8, (q31_t)0x23cd0eb3, (q31_t)0x7513ca60, (q31_t)0x23c2a36f, + (q31_t)0x751acedd, (q31_t)0x23b836ca, (q31_t)0x7521d14d, (q31_t)0x23adc8c4, + (q31_t)0x7528d1b1, (q31_t)0x23a3595e, (q31_t)0x752fd008, (q31_t)0x2398e898, + (q31_t)0x7536cc52, (q31_t)0x238e7673, (q31_t)0x753dc68f, (q31_t)0x238402ef, + (q31_t)0x7544bebf, (q31_t)0x23798e0d, (q31_t)0x754bb4e1, (q31_t)0x236f17cc, + (q31_t)0x7552a8f4, (q31_t)0x2364a02e, (q31_t)0x75599afa, (q31_t)0x235a2733, + (q31_t)0x75608af1, (q31_t)0x234facda, (q31_t)0x756778d9, (q31_t)0x23453125, + (q31_t)0x756e64b2, (q31_t)0x233ab414, (q31_t)0x75754e7c, (q31_t)0x233035a7, + (q31_t)0x757c3636, (q31_t)0x2325b5df, (q31_t)0x75831be0, (q31_t)0x231b34bc, + (q31_t)0x7589ff7a, (q31_t)0x2310b23e, (q31_t)0x7590e104, (q31_t)0x23062e67, + (q31_t)0x7597c07d, (q31_t)0x22fba936, (q31_t)0x759e9de5, (q31_t)0x22f122ab, + (q31_t)0x75a5793c, (q31_t)0x22e69ac8, (q31_t)0x75ac5282, (q31_t)0x22dc118c, + (q31_t)0x75b329b5, (q31_t)0x22d186f8, (q31_t)0x75b9fed7, (q31_t)0x22c6fb0c, + (q31_t)0x75c0d1e7, (q31_t)0x22bc6dca, (q31_t)0x75c7a2e3, (q31_t)0x22b1df30, + (q31_t)0x75ce71ce, (q31_t)0x22a74f40, (q31_t)0x75d53ea5, (q31_t)0x229cbdfa, + (q31_t)0x75dc0968, (q31_t)0x22922b5e, (q31_t)0x75e2d219, (q31_t)0x2287976e, + (q31_t)0x75e998b5, (q31_t)0x227d0228, (q31_t)0x75f05d3d, (q31_t)0x22726b8e, + (q31_t)0x75f71fb1, (q31_t)0x2267d3a0, (q31_t)0x75fde011, (q31_t)0x225d3a5e, + (q31_t)0x76049e5b, (q31_t)0x22529fca, (q31_t)0x760b5a90, (q31_t)0x224803e2, + (q31_t)0x761214b0, (q31_t)0x223d66a8, (q31_t)0x7618ccba, (q31_t)0x2232c81c, + (q31_t)0x761f82af, (q31_t)0x2228283f, (q31_t)0x7626368d, (q31_t)0x221d8711, + (q31_t)0x762ce855, (q31_t)0x2212e492, (q31_t)0x76339806, (q31_t)0x220840c2, + (q31_t)0x763a45a0, (q31_t)0x21fd9ba3, (q31_t)0x7640f123, (q31_t)0x21f2f534, + (q31_t)0x76479a8e, (q31_t)0x21e84d76, (q31_t)0x764e41e2, (q31_t)0x21dda46a, + (q31_t)0x7654e71d, (q31_t)0x21d2fa0f, (q31_t)0x765b8a41, (q31_t)0x21c84e67, + (q31_t)0x76622b4c, (q31_t)0x21bda171, (q31_t)0x7668ca3e, (q31_t)0x21b2f32e, + (q31_t)0x766f6717, (q31_t)0x21a8439e, (q31_t)0x767601d7, (q31_t)0x219d92c2, + (q31_t)0x767c9a7e, (q31_t)0x2192e09b, (q31_t)0x7683310b, (q31_t)0x21882d28, + (q31_t)0x7689c57d, (q31_t)0x217d786a, (q31_t)0x769057d6, (q31_t)0x2172c262, + (q31_t)0x7696e814, (q31_t)0x21680b0f, (q31_t)0x769d7637, (q31_t)0x215d5273, + (q31_t)0x76a4023f, (q31_t)0x2152988d, (q31_t)0x76aa8c2c, (q31_t)0x2147dd5f, + (q31_t)0x76b113fd, (q31_t)0x213d20e8, (q31_t)0x76b799b3, (q31_t)0x21326329, + (q31_t)0x76be1d4c, (q31_t)0x2127a423, (q31_t)0x76c49ec9, (q31_t)0x211ce3d5, + (q31_t)0x76cb1e2a, (q31_t)0x21122240, (q31_t)0x76d19b6e, (q31_t)0x21075f65, + (q31_t)0x76d81695, (q31_t)0x20fc9b44, (q31_t)0x76de8f9e, (q31_t)0x20f1d5de, + (q31_t)0x76e5068a, (q31_t)0x20e70f32, (q31_t)0x76eb7b58, (q31_t)0x20dc4742, + (q31_t)0x76f1ee09, (q31_t)0x20d17e0d, (q31_t)0x76f85e9a, (q31_t)0x20c6b395, + (q31_t)0x76fecd0e, (q31_t)0x20bbe7d8, (q31_t)0x77053962, (q31_t)0x20b11ad9, + (q31_t)0x770ba398, (q31_t)0x20a64c97, (q31_t)0x77120bae, (q31_t)0x209b7d13, + (q31_t)0x771871a5, (q31_t)0x2090ac4d, (q31_t)0x771ed57c, (q31_t)0x2085da46, + (q31_t)0x77253733, (q31_t)0x207b06fe, (q31_t)0x772b96ca, (q31_t)0x20703275, + (q31_t)0x7731f440, (q31_t)0x20655cac, (q31_t)0x77384f95, (q31_t)0x205a85a3, + (q31_t)0x773ea8ca, (q31_t)0x204fad5b, (q31_t)0x7744ffdd, (q31_t)0x2044d3d4, + (q31_t)0x774b54ce, (q31_t)0x2039f90f, (q31_t)0x7751a79e, (q31_t)0x202f1d0b, + (q31_t)0x7757f84c, (q31_t)0x20243fca, (q31_t)0x775e46d8, (q31_t)0x2019614c, + (q31_t)0x77649341, (q31_t)0x200e8190, (q31_t)0x776add88, (q31_t)0x2003a099, + (q31_t)0x777125ac, (q31_t)0x1ff8be65, (q31_t)0x77776bac, (q31_t)0x1feddaf6, + (q31_t)0x777daf89, (q31_t)0x1fe2f64c, (q31_t)0x7783f143, (q31_t)0x1fd81067, + (q31_t)0x778a30d8, (q31_t)0x1fcd2948, (q31_t)0x77906e49, (q31_t)0x1fc240ef, + (q31_t)0x7796a996, (q31_t)0x1fb7575c, (q31_t)0x779ce2be, (q31_t)0x1fac6c91, + (q31_t)0x77a319c2, (q31_t)0x1fa1808c, (q31_t)0x77a94ea0, (q31_t)0x1f969350, + (q31_t)0x77af8159, (q31_t)0x1f8ba4dc, (q31_t)0x77b5b1ec, (q31_t)0x1f80b531, + (q31_t)0x77bbe05a, (q31_t)0x1f75c44e, (q31_t)0x77c20ca1, (q31_t)0x1f6ad235, + (q31_t)0x77c836c2, (q31_t)0x1f5fdee6, (q31_t)0x77ce5ebd, (q31_t)0x1f54ea62, + (q31_t)0x77d48490, (q31_t)0x1f49f4a8, (q31_t)0x77daa83d, (q31_t)0x1f3efdb9, + (q31_t)0x77e0c9c3, (q31_t)0x1f340596, (q31_t)0x77e6e921, (q31_t)0x1f290c3f, + (q31_t)0x77ed0657, (q31_t)0x1f1e11b5, (q31_t)0x77f32165, (q31_t)0x1f1315f7, + (q31_t)0x77f93a4b, (q31_t)0x1f081907, (q31_t)0x77ff5109, (q31_t)0x1efd1ae4, + (q31_t)0x7805659e, (q31_t)0x1ef21b90, (q31_t)0x780b780a, (q31_t)0x1ee71b0a, + (q31_t)0x7811884d, (q31_t)0x1edc1953, (q31_t)0x78179666, (q31_t)0x1ed1166b, + (q31_t)0x781da256, (q31_t)0x1ec61254, (q31_t)0x7823ac1d, (q31_t)0x1ebb0d0d, + (q31_t)0x7829b3b9, (q31_t)0x1eb00696, (q31_t)0x782fb92a, (q31_t)0x1ea4fef0, + (q31_t)0x7835bc71, (q31_t)0x1e99f61d, (q31_t)0x783bbd8e, (q31_t)0x1e8eec1b, + (q31_t)0x7841bc7f, (q31_t)0x1e83e0eb, (q31_t)0x7847b946, (q31_t)0x1e78d48e, + (q31_t)0x784db3e0, (q31_t)0x1e6dc705, (q31_t)0x7853ac4f, (q31_t)0x1e62b84f, + (q31_t)0x7859a292, (q31_t)0x1e57a86d, (q31_t)0x785f96a9, (q31_t)0x1e4c9760, + (q31_t)0x78658894, (q31_t)0x1e418528, (q31_t)0x786b7852, (q31_t)0x1e3671c5, + (q31_t)0x787165e3, (q31_t)0x1e2b5d38, (q31_t)0x78775147, (q31_t)0x1e204781, + (q31_t)0x787d3a7e, (q31_t)0x1e1530a1, (q31_t)0x78832187, (q31_t)0x1e0a1898, + (q31_t)0x78890663, (q31_t)0x1dfeff67, (q31_t)0x788ee910, (q31_t)0x1df3e50d, + (q31_t)0x7894c98f, (q31_t)0x1de8c98c, (q31_t)0x789aa7e0, (q31_t)0x1dddace4, + (q31_t)0x78a08402, (q31_t)0x1dd28f15, (q31_t)0x78a65df6, (q31_t)0x1dc7701f, + (q31_t)0x78ac35ba, (q31_t)0x1dbc5004, (q31_t)0x78b20b4f, (q31_t)0x1db12ec3, + (q31_t)0x78b7deb4, (q31_t)0x1da60c5d, (q31_t)0x78bdafea, (q31_t)0x1d9ae8d2, + (q31_t)0x78c37eef, (q31_t)0x1d8fc424, (q31_t)0x78c94bc4, (q31_t)0x1d849e51, + (q31_t)0x78cf1669, (q31_t)0x1d79775c, (q31_t)0x78d4dedd, (q31_t)0x1d6e4f43, + (q31_t)0x78daa520, (q31_t)0x1d632608, (q31_t)0x78e06932, (q31_t)0x1d57fbaa, + (q31_t)0x78e62b13, (q31_t)0x1d4cd02c, (q31_t)0x78ebeac2, (q31_t)0x1d41a38c, + (q31_t)0x78f1a840, (q31_t)0x1d3675cb, (q31_t)0x78f7638b, (q31_t)0x1d2b46ea, + (q31_t)0x78fd1ca4, (q31_t)0x1d2016e9, (q31_t)0x7902d38b, (q31_t)0x1d14e5c9, + (q31_t)0x7908883f, (q31_t)0x1d09b389, (q31_t)0x790e3ac0, (q31_t)0x1cfe802b, + (q31_t)0x7913eb0e, (q31_t)0x1cf34baf, (q31_t)0x79199929, (q31_t)0x1ce81615, + (q31_t)0x791f4510, (q31_t)0x1cdcdf5e, (q31_t)0x7924eec3, (q31_t)0x1cd1a78a, + (q31_t)0x792a9642, (q31_t)0x1cc66e99, (q31_t)0x79303b8e, (q31_t)0x1cbb348d, + (q31_t)0x7935dea4, (q31_t)0x1caff965, (q31_t)0x793b7f86, (q31_t)0x1ca4bd21, + (q31_t)0x79411e33, (q31_t)0x1c997fc4, (q31_t)0x7946baac, (q31_t)0x1c8e414b, + (q31_t)0x794c54ee, (q31_t)0x1c8301b9, (q31_t)0x7951ecfc, (q31_t)0x1c77c10e, + (q31_t)0x795782d3, (q31_t)0x1c6c7f4a, (q31_t)0x795d1675, (q31_t)0x1c613c6d, + (q31_t)0x7962a7e0, (q31_t)0x1c55f878, (q31_t)0x79683715, (q31_t)0x1c4ab36b, + (q31_t)0x796dc414, (q31_t)0x1c3f6d47, (q31_t)0x79734edc, (q31_t)0x1c34260c, + (q31_t)0x7978d76c, (q31_t)0x1c28ddbb, (q31_t)0x797e5dc6, (q31_t)0x1c1d9454, + (q31_t)0x7983e1e8, (q31_t)0x1c1249d8, (q31_t)0x798963d2, (q31_t)0x1c06fe46, + (q31_t)0x798ee385, (q31_t)0x1bfbb1a0, (q31_t)0x799460ff, (q31_t)0x1bf063e6, + (q31_t)0x7999dc42, (q31_t)0x1be51518, (q31_t)0x799f554b, (q31_t)0x1bd9c537, + (q31_t)0x79a4cc1c, (q31_t)0x1bce7442, (q31_t)0x79aa40b4, (q31_t)0x1bc3223c, + (q31_t)0x79afb313, (q31_t)0x1bb7cf23, (q31_t)0x79b52339, (q31_t)0x1bac7af9, + (q31_t)0x79ba9125, (q31_t)0x1ba125bd, (q31_t)0x79bffcd7, (q31_t)0x1b95cf71, + (q31_t)0x79c5664f, (q31_t)0x1b8a7815, (q31_t)0x79cacd8d, (q31_t)0x1b7f1fa9, + (q31_t)0x79d03291, (q31_t)0x1b73c62d, (q31_t)0x79d5955a, (q31_t)0x1b686ba3, + (q31_t)0x79daf5e8, (q31_t)0x1b5d100a, (q31_t)0x79e0543c, (q31_t)0x1b51b363, + (q31_t)0x79e5b054, (q31_t)0x1b4655ae, (q31_t)0x79eb0a31, (q31_t)0x1b3af6ec, + (q31_t)0x79f061d2, (q31_t)0x1b2f971e, (q31_t)0x79f5b737, (q31_t)0x1b243643, + (q31_t)0x79fb0a60, (q31_t)0x1b18d45c, (q31_t)0x7a005b4d, (q31_t)0x1b0d716a, + (q31_t)0x7a05a9fd, (q31_t)0x1b020d6c, (q31_t)0x7a0af671, (q31_t)0x1af6a865, + (q31_t)0x7a1040a8, (q31_t)0x1aeb4253, (q31_t)0x7a1588a2, (q31_t)0x1adfdb37, + (q31_t)0x7a1ace5f, (q31_t)0x1ad47312, (q31_t)0x7a2011de, (q31_t)0x1ac909e5, + (q31_t)0x7a25531f, (q31_t)0x1abd9faf, (q31_t)0x7a2a9223, (q31_t)0x1ab23471, + (q31_t)0x7a2fcee8, (q31_t)0x1aa6c82b, (q31_t)0x7a350970, (q31_t)0x1a9b5adf, + (q31_t)0x7a3a41b9, (q31_t)0x1a8fec8c, (q31_t)0x7a3f77c3, (q31_t)0x1a847d33, + (q31_t)0x7a44ab8e, (q31_t)0x1a790cd4, (q31_t)0x7a49dd1a, (q31_t)0x1a6d9b70, + (q31_t)0x7a4f0c67, (q31_t)0x1a622907, (q31_t)0x7a543974, (q31_t)0x1a56b599, + (q31_t)0x7a596442, (q31_t)0x1a4b4128, (q31_t)0x7a5e8cd0, (q31_t)0x1a3fcbb3, + (q31_t)0x7a63b31d, (q31_t)0x1a34553b, (q31_t)0x7a68d72b, (q31_t)0x1a28ddc0, + (q31_t)0x7a6df8f8, (q31_t)0x1a1d6544, (q31_t)0x7a731884, (q31_t)0x1a11ebc5, + (q31_t)0x7a7835cf, (q31_t)0x1a067145, (q31_t)0x7a7d50da, (q31_t)0x19faf5c5, + (q31_t)0x7a8269a3, (q31_t)0x19ef7944, (q31_t)0x7a87802a, (q31_t)0x19e3fbc3, + (q31_t)0x7a8c9470, (q31_t)0x19d87d42, (q31_t)0x7a91a674, (q31_t)0x19ccfdc2, + (q31_t)0x7a96b636, (q31_t)0x19c17d44, (q31_t)0x7a9bc3b6, (q31_t)0x19b5fbc8, + (q31_t)0x7aa0cef3, (q31_t)0x19aa794d, (q31_t)0x7aa5d7ee, (q31_t)0x199ef5d6, + (q31_t)0x7aaadea6, (q31_t)0x19937161, (q31_t)0x7aafe31b, (q31_t)0x1987ebf0, + (q31_t)0x7ab4e54c, (q31_t)0x197c6584, (q31_t)0x7ab9e53a, (q31_t)0x1970de1b, + (q31_t)0x7abee2e5, (q31_t)0x196555b8, (q31_t)0x7ac3de4c, (q31_t)0x1959cc5a, + (q31_t)0x7ac8d76f, (q31_t)0x194e4201, (q31_t)0x7acdce4d, (q31_t)0x1942b6af, + (q31_t)0x7ad2c2e8, (q31_t)0x19372a64, (q31_t)0x7ad7b53d, (q31_t)0x192b9d1f, + (q31_t)0x7adca54e, (q31_t)0x19200ee3, (q31_t)0x7ae1931a, (q31_t)0x19147fae, + (q31_t)0x7ae67ea1, (q31_t)0x1908ef82, (q31_t)0x7aeb67e3, (q31_t)0x18fd5e5f, + (q31_t)0x7af04edf, (q31_t)0x18f1cc45, (q31_t)0x7af53395, (q31_t)0x18e63935, + (q31_t)0x7afa1605, (q31_t)0x18daa52f, (q31_t)0x7afef630, (q31_t)0x18cf1034, + (q31_t)0x7b03d414, (q31_t)0x18c37a44, (q31_t)0x7b08afb2, (q31_t)0x18b7e35f, + (q31_t)0x7b0d8909, (q31_t)0x18ac4b87, (q31_t)0x7b126019, (q31_t)0x18a0b2bb, + (q31_t)0x7b1734e2, (q31_t)0x189518fc, (q31_t)0x7b1c0764, (q31_t)0x18897e4a, + (q31_t)0x7b20d79e, (q31_t)0x187de2a7, (q31_t)0x7b25a591, (q31_t)0x18724611, + (q31_t)0x7b2a713d, (q31_t)0x1866a88a, (q31_t)0x7b2f3aa0, (q31_t)0x185b0a13, + (q31_t)0x7b3401bb, (q31_t)0x184f6aab, (q31_t)0x7b38c68e, (q31_t)0x1843ca53, + (q31_t)0x7b3d8918, (q31_t)0x1838290c, (q31_t)0x7b42495a, (q31_t)0x182c86d5, + (q31_t)0x7b470753, (q31_t)0x1820e3b0, (q31_t)0x7b4bc303, (q31_t)0x18153f9d, + (q31_t)0x7b507c69, (q31_t)0x18099a9c, (q31_t)0x7b553386, (q31_t)0x17fdf4ae, + (q31_t)0x7b59e85a, (q31_t)0x17f24dd3, (q31_t)0x7b5e9ae4, (q31_t)0x17e6a60c, + (q31_t)0x7b634b23, (q31_t)0x17dafd59, (q31_t)0x7b67f919, (q31_t)0x17cf53bb, + (q31_t)0x7b6ca4c4, (q31_t)0x17c3a931, (q31_t)0x7b714e25, (q31_t)0x17b7fdbd, + (q31_t)0x7b75f53c, (q31_t)0x17ac515f, (q31_t)0x7b7a9a07, (q31_t)0x17a0a417, + (q31_t)0x7b7f3c87, (q31_t)0x1794f5e6, (q31_t)0x7b83dcbc, (q31_t)0x178946cc, + (q31_t)0x7b887aa6, (q31_t)0x177d96ca, (q31_t)0x7b8d1644, (q31_t)0x1771e5e0, + (q31_t)0x7b91af97, (q31_t)0x1766340f, (q31_t)0x7b96469d, (q31_t)0x175a8157, + (q31_t)0x7b9adb57, (q31_t)0x174ecdb8, (q31_t)0x7b9f6dc5, (q31_t)0x17431933, + (q31_t)0x7ba3fde7, (q31_t)0x173763c9, (q31_t)0x7ba88bbc, (q31_t)0x172bad7a, + (q31_t)0x7bad1744, (q31_t)0x171ff646, (q31_t)0x7bb1a080, (q31_t)0x17143e2d, + (q31_t)0x7bb6276e, (q31_t)0x17088531, (q31_t)0x7bbaac0e, (q31_t)0x16fccb51, + (q31_t)0x7bbf2e62, (q31_t)0x16f1108f, (q31_t)0x7bc3ae67, (q31_t)0x16e554ea, + (q31_t)0x7bc82c1f, (q31_t)0x16d99864, (q31_t)0x7bcca789, (q31_t)0x16cddafb, + (q31_t)0x7bd120a4, (q31_t)0x16c21cb2, (q31_t)0x7bd59771, (q31_t)0x16b65d88, + (q31_t)0x7bda0bf0, (q31_t)0x16aa9d7e, (q31_t)0x7bde7e20, (q31_t)0x169edc94, + (q31_t)0x7be2ee01, (q31_t)0x16931acb, (q31_t)0x7be75b93, (q31_t)0x16875823, + (q31_t)0x7bebc6d5, (q31_t)0x167b949d, (q31_t)0x7bf02fc9, (q31_t)0x166fd039, + (q31_t)0x7bf4966c, (q31_t)0x16640af7, (q31_t)0x7bf8fac0, (q31_t)0x165844d8, + (q31_t)0x7bfd5cc4, (q31_t)0x164c7ddd, (q31_t)0x7c01bc78, (q31_t)0x1640b606, + (q31_t)0x7c0619dc, (q31_t)0x1634ed53, (q31_t)0x7c0a74f0, (q31_t)0x162923c5, + (q31_t)0x7c0ecdb2, (q31_t)0x161d595d, (q31_t)0x7c132424, (q31_t)0x16118e1a, + (q31_t)0x7c177845, (q31_t)0x1605c1fd, (q31_t)0x7c1bca16, (q31_t)0x15f9f507, + (q31_t)0x7c201994, (q31_t)0x15ee2738, (q31_t)0x7c2466c2, (q31_t)0x15e25890, + (q31_t)0x7c28b19e, (q31_t)0x15d68911, (q31_t)0x7c2cfa28, (q31_t)0x15cab8ba, + (q31_t)0x7c314060, (q31_t)0x15bee78c, (q31_t)0x7c358446, (q31_t)0x15b31587, + (q31_t)0x7c39c5da, (q31_t)0x15a742ac, (q31_t)0x7c3e051b, (q31_t)0x159b6efb, + (q31_t)0x7c42420a, (q31_t)0x158f9a76, (q31_t)0x7c467ca6, (q31_t)0x1583c51b, + (q31_t)0x7c4ab4ef, (q31_t)0x1577eeec, (q31_t)0x7c4eeae5, (q31_t)0x156c17e9, + (q31_t)0x7c531e88, (q31_t)0x15604013, (q31_t)0x7c574fd8, (q31_t)0x1554676a, + (q31_t)0x7c5b7ed4, (q31_t)0x15488dee, (q31_t)0x7c5fab7c, (q31_t)0x153cb3a0, + (q31_t)0x7c63d5d1, (q31_t)0x1530d881, (q31_t)0x7c67fdd1, (q31_t)0x1524fc90, + (q31_t)0x7c6c237e, (q31_t)0x15191fcf, (q31_t)0x7c7046d6, (q31_t)0x150d423d, + (q31_t)0x7c7467d9, (q31_t)0x150163dc, (q31_t)0x7c788688, (q31_t)0x14f584ac, + (q31_t)0x7c7ca2e2, (q31_t)0x14e9a4ac, (q31_t)0x7c80bce7, (q31_t)0x14ddc3de, + (q31_t)0x7c84d496, (q31_t)0x14d1e242, (q31_t)0x7c88e9f1, (q31_t)0x14c5ffd9, + (q31_t)0x7c8cfcf6, (q31_t)0x14ba1ca3, (q31_t)0x7c910da5, (q31_t)0x14ae38a0, + (q31_t)0x7c951bff, (q31_t)0x14a253d1, (q31_t)0x7c992803, (q31_t)0x14966e36, + (q31_t)0x7c9d31b0, (q31_t)0x148a87d1, (q31_t)0x7ca13908, (q31_t)0x147ea0a0, + (q31_t)0x7ca53e09, (q31_t)0x1472b8a5, (q31_t)0x7ca940b3, (q31_t)0x1466cfe1, + (q31_t)0x7cad4107, (q31_t)0x145ae653, (q31_t)0x7cb13f04, (q31_t)0x144efbfc, + (q31_t)0x7cb53aaa, (q31_t)0x144310dd, (q31_t)0x7cb933f9, (q31_t)0x143724f5, + (q31_t)0x7cbd2af0, (q31_t)0x142b3846, (q31_t)0x7cc11f90, (q31_t)0x141f4ad1, + (q31_t)0x7cc511d9, (q31_t)0x14135c94, (q31_t)0x7cc901c9, (q31_t)0x14076d91, + (q31_t)0x7cccef62, (q31_t)0x13fb7dc9, (q31_t)0x7cd0daa2, (q31_t)0x13ef8d3c, + (q31_t)0x7cd4c38b, (q31_t)0x13e39be9, (q31_t)0x7cd8aa1b, (q31_t)0x13d7a9d3, + (q31_t)0x7cdc8e52, (q31_t)0x13cbb6f8, (q31_t)0x7ce07031, (q31_t)0x13bfc35b, + (q31_t)0x7ce44fb7, (q31_t)0x13b3cefa, (q31_t)0x7ce82ce4, (q31_t)0x13a7d9d7, + (q31_t)0x7cec07b8, (q31_t)0x139be3f2, (q31_t)0x7cefe032, (q31_t)0x138fed4b, + (q31_t)0x7cf3b653, (q31_t)0x1383f5e3, (q31_t)0x7cf78a1b, (q31_t)0x1377fdbb, + (q31_t)0x7cfb5b89, (q31_t)0x136c04d2, (q31_t)0x7cff2a9d, (q31_t)0x13600b2a, + (q31_t)0x7d02f757, (q31_t)0x135410c3, (q31_t)0x7d06c1b6, (q31_t)0x1348159d, + (q31_t)0x7d0a89bc, (q31_t)0x133c19b8, (q31_t)0x7d0e4f67, (q31_t)0x13301d16, + (q31_t)0x7d1212b7, (q31_t)0x13241fb6, (q31_t)0x7d15d3ad, (q31_t)0x1318219a, + (q31_t)0x7d199248, (q31_t)0x130c22c1, (q31_t)0x7d1d4e88, (q31_t)0x1300232c, + (q31_t)0x7d21086c, (q31_t)0x12f422db, (q31_t)0x7d24bff6, (q31_t)0x12e821cf, + (q31_t)0x7d287523, (q31_t)0x12dc2009, (q31_t)0x7d2c27f6, (q31_t)0x12d01d89, + (q31_t)0x7d2fd86c, (q31_t)0x12c41a4f, (q31_t)0x7d338687, (q31_t)0x12b8165b, + (q31_t)0x7d373245, (q31_t)0x12ac11af, (q31_t)0x7d3adba7, (q31_t)0x12a00c4b, + (q31_t)0x7d3e82ae, (q31_t)0x1294062f, (q31_t)0x7d422757, (q31_t)0x1287ff5b, + (q31_t)0x7d45c9a4, (q31_t)0x127bf7d1, (q31_t)0x7d496994, (q31_t)0x126fef90, + (q31_t)0x7d4d0728, (q31_t)0x1263e699, (q31_t)0x7d50a25e, (q31_t)0x1257dced, + (q31_t)0x7d543b37, (q31_t)0x124bd28c, (q31_t)0x7d57d1b3, (q31_t)0x123fc776, + (q31_t)0x7d5b65d2, (q31_t)0x1233bbac, (q31_t)0x7d5ef793, (q31_t)0x1227af2e, + (q31_t)0x7d6286f6, (q31_t)0x121ba1fd, (q31_t)0x7d6613fb, (q31_t)0x120f941a, + (q31_t)0x7d699ea3, (q31_t)0x12038584, (q31_t)0x7d6d26ec, (q31_t)0x11f7763c, + (q31_t)0x7d70acd7, (q31_t)0x11eb6643, (q31_t)0x7d743064, (q31_t)0x11df5599, + (q31_t)0x7d77b192, (q31_t)0x11d3443f, (q31_t)0x7d7b3061, (q31_t)0x11c73235, + (q31_t)0x7d7eacd2, (q31_t)0x11bb1f7c, (q31_t)0x7d8226e4, (q31_t)0x11af0c13, + (q31_t)0x7d859e96, (q31_t)0x11a2f7fc, (q31_t)0x7d8913ea, (q31_t)0x1196e337, + (q31_t)0x7d8c86de, (q31_t)0x118acdc4, (q31_t)0x7d8ff772, (q31_t)0x117eb7a4, + (q31_t)0x7d9365a8, (q31_t)0x1172a0d7, (q31_t)0x7d96d17d, (q31_t)0x1166895f, + (q31_t)0x7d9a3af2, (q31_t)0x115a713a, (q31_t)0x7d9da208, (q31_t)0x114e586a, + (q31_t)0x7da106bd, (q31_t)0x11423ef0, (q31_t)0x7da46912, (q31_t)0x113624cb, + (q31_t)0x7da7c907, (q31_t)0x112a09fc, (q31_t)0x7dab269b, (q31_t)0x111dee84, + (q31_t)0x7dae81cf, (q31_t)0x1111d263, (q31_t)0x7db1daa2, (q31_t)0x1105b599, + (q31_t)0x7db53113, (q31_t)0x10f99827, (q31_t)0x7db88524, (q31_t)0x10ed7a0e, + (q31_t)0x7dbbd6d4, (q31_t)0x10e15b4e, (q31_t)0x7dbf2622, (q31_t)0x10d53be7, + (q31_t)0x7dc2730f, (q31_t)0x10c91bda, (q31_t)0x7dc5bd9b, (q31_t)0x10bcfb28, + (q31_t)0x7dc905c5, (q31_t)0x10b0d9d0, (q31_t)0x7dcc4b8d, (q31_t)0x10a4b7d3, + (q31_t)0x7dcf8ef3, (q31_t)0x10989532, (q31_t)0x7dd2cff7, (q31_t)0x108c71ee, + (q31_t)0x7dd60e99, (q31_t)0x10804e06, (q31_t)0x7dd94ad8, (q31_t)0x1074297b, + (q31_t)0x7ddc84b5, (q31_t)0x1068044e, (q31_t)0x7ddfbc30, (q31_t)0x105bde7f, + (q31_t)0x7de2f148, (q31_t)0x104fb80e, (q31_t)0x7de623fd, (q31_t)0x104390fd, + (q31_t)0x7de9544f, (q31_t)0x1037694b, (q31_t)0x7dec823e, (q31_t)0x102b40f8, + (q31_t)0x7defadca, (q31_t)0x101f1807, (q31_t)0x7df2d6f3, (q31_t)0x1012ee76, + (q31_t)0x7df5fdb8, (q31_t)0x1006c446, (q31_t)0x7df9221a, (q31_t)0xffa9979, + (q31_t)0x7dfc4418, (q31_t)0xfee6e0d, (q31_t)0x7dff63b2, (q31_t)0xfe24205, + (q31_t)0x7e0280e9, (q31_t)0xfd6155f, (q31_t)0x7e059bbb, (q31_t)0xfc9e81e, + (q31_t)0x7e08b42a, (q31_t)0xfbdba40, (q31_t)0x7e0bca34, (q31_t)0xfb18bc8, + (q31_t)0x7e0eddd9, (q31_t)0xfa55cb4, (q31_t)0x7e11ef1b, (q31_t)0xf992d06, + (q31_t)0x7e14fdf7, (q31_t)0xf8cfcbe, (q31_t)0x7e180a6f, (q31_t)0xf80cbdc, + (q31_t)0x7e1b1482, (q31_t)0xf749a61, (q31_t)0x7e1e1c30, (q31_t)0xf68684e, + (q31_t)0x7e212179, (q31_t)0xf5c35a3, (q31_t)0x7e24245d, (q31_t)0xf500260, + (q31_t)0x7e2724db, (q31_t)0xf43ce86, (q31_t)0x7e2a22f4, (q31_t)0xf379a16, + (q31_t)0x7e2d1ea8, (q31_t)0xf2b650f, (q31_t)0x7e3017f6, (q31_t)0xf1f2f73, + (q31_t)0x7e330ede, (q31_t)0xf12f941, (q31_t)0x7e360360, (q31_t)0xf06c27a, + (q31_t)0x7e38f57c, (q31_t)0xefa8b20, (q31_t)0x7e3be532, (q31_t)0xeee5331, + (q31_t)0x7e3ed282, (q31_t)0xee21aaf, (q31_t)0x7e41bd6c, (q31_t)0xed5e19a, + (q31_t)0x7e44a5ef, (q31_t)0xec9a7f3, (q31_t)0x7e478c0b, (q31_t)0xebd6db9, + (q31_t)0x7e4a6fc1, (q31_t)0xeb132ef, (q31_t)0x7e4d5110, (q31_t)0xea4f793, + (q31_t)0x7e502ff9, (q31_t)0xe98bba7, (q31_t)0x7e530c7a, (q31_t)0xe8c7f2a, + (q31_t)0x7e55e694, (q31_t)0xe80421e, (q31_t)0x7e58be47, (q31_t)0xe740483, + (q31_t)0x7e5b9392, (q31_t)0xe67c65a, (q31_t)0x7e5e6676, (q31_t)0xe5b87a2, + (q31_t)0x7e6136f3, (q31_t)0xe4f485c, (q31_t)0x7e640507, (q31_t)0xe430889, + (q31_t)0x7e66d0b4, (q31_t)0xe36c82a, (q31_t)0x7e6999fa, (q31_t)0xe2a873e, + (q31_t)0x7e6c60d7, (q31_t)0xe1e45c6, (q31_t)0x7e6f254c, (q31_t)0xe1203c3, + (q31_t)0x7e71e759, (q31_t)0xe05c135, (q31_t)0x7e74a6fd, (q31_t)0xdf97e1d, + (q31_t)0x7e77643a, (q31_t)0xded3a7b, (q31_t)0x7e7a1f0d, (q31_t)0xde0f64f, + (q31_t)0x7e7cd778, (q31_t)0xdd4b19a, (q31_t)0x7e7f8d7b, (q31_t)0xdc86c5d, + (q31_t)0x7e824114, (q31_t)0xdbc2698, (q31_t)0x7e84f245, (q31_t)0xdafe04b, + (q31_t)0x7e87a10c, (q31_t)0xda39978, (q31_t)0x7e8a4d6a, (q31_t)0xd97521d, + (q31_t)0x7e8cf75f, (q31_t)0xd8b0a3d, (q31_t)0x7e8f9eeb, (q31_t)0xd7ec1d6, + (q31_t)0x7e92440d, (q31_t)0xd7278eb, (q31_t)0x7e94e6c6, (q31_t)0xd662f7b, + (q31_t)0x7e978715, (q31_t)0xd59e586, (q31_t)0x7e9a24fb, (q31_t)0xd4d9b0e, + (q31_t)0x7e9cc076, (q31_t)0xd415013, (q31_t)0x7e9f5988, (q31_t)0xd350495, + (q31_t)0x7ea1f02f, (q31_t)0xd28b894, (q31_t)0x7ea4846c, (q31_t)0xd1c6c11, + (q31_t)0x7ea7163f, (q31_t)0xd101f0e, (q31_t)0x7ea9a5a8, (q31_t)0xd03d189, + (q31_t)0x7eac32a6, (q31_t)0xcf78383, (q31_t)0x7eaebd3a, (q31_t)0xceb34fe, + (q31_t)0x7eb14563, (q31_t)0xcdee5f9, (q31_t)0x7eb3cb21, (q31_t)0xcd29676, + (q31_t)0x7eb64e75, (q31_t)0xcc64673, (q31_t)0x7eb8cf5d, (q31_t)0xcb9f5f3, + (q31_t)0x7ebb4ddb, (q31_t)0xcada4f5, (q31_t)0x7ebdc9ed, (q31_t)0xca1537a, + (q31_t)0x7ec04394, (q31_t)0xc950182, (q31_t)0x7ec2bad0, (q31_t)0xc88af0e, + (q31_t)0x7ec52fa0, (q31_t)0xc7c5c1e, (q31_t)0x7ec7a205, (q31_t)0xc7008b3, + (q31_t)0x7eca11fe, (q31_t)0xc63b4ce, (q31_t)0x7ecc7f8b, (q31_t)0xc57606e, + (q31_t)0x7eceeaad, (q31_t)0xc4b0b94, (q31_t)0x7ed15363, (q31_t)0xc3eb641, + (q31_t)0x7ed3b9ad, (q31_t)0xc326075, (q31_t)0x7ed61d8a, (q31_t)0xc260a31, + (q31_t)0x7ed87efc, (q31_t)0xc19b374, (q31_t)0x7edade01, (q31_t)0xc0d5c41, + (q31_t)0x7edd3a9a, (q31_t)0xc010496, (q31_t)0x7edf94c7, (q31_t)0xbf4ac75, + (q31_t)0x7ee1ec87, (q31_t)0xbe853de, (q31_t)0x7ee441da, (q31_t)0xbdbfad1, + (q31_t)0x7ee694c1, (q31_t)0xbcfa150, (q31_t)0x7ee8e53a, (q31_t)0xbc34759, + (q31_t)0x7eeb3347, (q31_t)0xbb6ecef, (q31_t)0x7eed7ee7, (q31_t)0xbaa9211, + (q31_t)0x7eefc81a, (q31_t)0xb9e36c0, (q31_t)0x7ef20ee0, (q31_t)0xb91dafc, + (q31_t)0x7ef45338, (q31_t)0xb857ec7, (q31_t)0x7ef69523, (q31_t)0xb79221f, + (q31_t)0x7ef8d4a1, (q31_t)0xb6cc506, (q31_t)0x7efb11b1, (q31_t)0xb60677c, + (q31_t)0x7efd4c54, (q31_t)0xb540982, (q31_t)0x7eff8489, (q31_t)0xb47ab19, + (q31_t)0x7f01ba50, (q31_t)0xb3b4c40, (q31_t)0x7f03eda9, (q31_t)0xb2eecf8, + (q31_t)0x7f061e95, (q31_t)0xb228d42, (q31_t)0x7f084d12, (q31_t)0xb162d1d, + (q31_t)0x7f0a7921, (q31_t)0xb09cc8c, (q31_t)0x7f0ca2c2, (q31_t)0xafd6b8d, + (q31_t)0x7f0ec9f5, (q31_t)0xaf10a22, (q31_t)0x7f10eeb9, (q31_t)0xae4a84b, + (q31_t)0x7f13110f, (q31_t)0xad84609, (q31_t)0x7f1530f7, (q31_t)0xacbe35b, + (q31_t)0x7f174e70, (q31_t)0xabf8043, (q31_t)0x7f19697a, (q31_t)0xab31cc1, + (q31_t)0x7f1b8215, (q31_t)0xaa6b8d5, (q31_t)0x7f1d9842, (q31_t)0xa9a5480, + (q31_t)0x7f1fabff, (q31_t)0xa8defc3, (q31_t)0x7f21bd4e, (q31_t)0xa818a9d, + (q31_t)0x7f23cc2e, (q31_t)0xa752510, (q31_t)0x7f25d89e, (q31_t)0xa68bf1b, + (q31_t)0x7f27e29f, (q31_t)0xa5c58c0, (q31_t)0x7f29ea31, (q31_t)0xa4ff1fe, + (q31_t)0x7f2bef53, (q31_t)0xa438ad7, (q31_t)0x7f2df206, (q31_t)0xa37234a, + (q31_t)0x7f2ff24a, (q31_t)0xa2abb59, (q31_t)0x7f31f01d, (q31_t)0xa1e5303, + (q31_t)0x7f33eb81, (q31_t)0xa11ea49, (q31_t)0x7f35e476, (q31_t)0xa05812c, + (q31_t)0x7f37dafa, (q31_t)0x9f917ac, (q31_t)0x7f39cf0e, (q31_t)0x9ecadc9, + (q31_t)0x7f3bc0b3, (q31_t)0x9e04385, (q31_t)0x7f3dafe7, (q31_t)0x9d3d8df, + (q31_t)0x7f3f9cab, (q31_t)0x9c76dd8, (q31_t)0x7f4186ff, (q31_t)0x9bb0271, + (q31_t)0x7f436ee3, (q31_t)0x9ae96aa, (q31_t)0x7f455456, (q31_t)0x9a22a83, + (q31_t)0x7f473759, (q31_t)0x995bdfd, (q31_t)0x7f4917eb, (q31_t)0x9895118, + (q31_t)0x7f4af60d, (q31_t)0x97ce3d5, (q31_t)0x7f4cd1be, (q31_t)0x9707635, + (q31_t)0x7f4eaafe, (q31_t)0x9640837, (q31_t)0x7f5081cd, (q31_t)0x95799dd, + (q31_t)0x7f52562c, (q31_t)0x94b2b27, (q31_t)0x7f54281a, (q31_t)0x93ebc14, + (q31_t)0x7f55f796, (q31_t)0x9324ca7, (q31_t)0x7f57c4a2, (q31_t)0x925dcdf, + (q31_t)0x7f598f3c, (q31_t)0x9196cbc, (q31_t)0x7f5b5765, (q31_t)0x90cfc40, + (q31_t)0x7f5d1d1d, (q31_t)0x9008b6a, (q31_t)0x7f5ee063, (q31_t)0x8f41a3c, + (q31_t)0x7f60a138, (q31_t)0x8e7a8b5, (q31_t)0x7f625f9b, (q31_t)0x8db36d6, + (q31_t)0x7f641b8d, (q31_t)0x8cec4a0, (q31_t)0x7f65d50d, (q31_t)0x8c25213, + (q31_t)0x7f678c1c, (q31_t)0x8b5df30, (q31_t)0x7f6940b8, (q31_t)0x8a96bf6, + (q31_t)0x7f6af2e3, (q31_t)0x89cf867, (q31_t)0x7f6ca29c, (q31_t)0x8908483, + (q31_t)0x7f6e4fe3, (q31_t)0x884104b, (q31_t)0x7f6ffab8, (q31_t)0x8779bbe, + (q31_t)0x7f71a31b, (q31_t)0x86b26de, (q31_t)0x7f73490b, (q31_t)0x85eb1ab, + (q31_t)0x7f74ec8a, (q31_t)0x8523c25, (q31_t)0x7f768d96, (q31_t)0x845c64d, + (q31_t)0x7f782c30, (q31_t)0x8395024, (q31_t)0x7f79c857, (q31_t)0x82cd9a9, + (q31_t)0x7f7b620c, (q31_t)0x82062de, (q31_t)0x7f7cf94e, (q31_t)0x813ebc2, + (q31_t)0x7f7e8e1e, (q31_t)0x8077457, (q31_t)0x7f80207b, (q31_t)0x7fafc9c, + (q31_t)0x7f81b065, (q31_t)0x7ee8493, (q31_t)0x7f833ddd, (q31_t)0x7e20c3b, + (q31_t)0x7f84c8e2, (q31_t)0x7d59396, (q31_t)0x7f865174, (q31_t)0x7c91aa3, + (q31_t)0x7f87d792, (q31_t)0x7bca163, (q31_t)0x7f895b3e, (q31_t)0x7b027d7, + (q31_t)0x7f8adc77, (q31_t)0x7a3adff, (q31_t)0x7f8c5b3d, (q31_t)0x79733dc, + (q31_t)0x7f8dd78f, (q31_t)0x78ab96e, (q31_t)0x7f8f516e, (q31_t)0x77e3eb5, + (q31_t)0x7f90c8da, (q31_t)0x771c3b3, (q31_t)0x7f923dd2, (q31_t)0x7654867, + (q31_t)0x7f93b058, (q31_t)0x758ccd2, (q31_t)0x7f952069, (q31_t)0x74c50f4, + (q31_t)0x7f968e07, (q31_t)0x73fd4cf, (q31_t)0x7f97f932, (q31_t)0x7335862, + (q31_t)0x7f9961e8, (q31_t)0x726dbae, (q31_t)0x7f9ac82c, (q31_t)0x71a5eb3, + (q31_t)0x7f9c2bfb, (q31_t)0x70de172, (q31_t)0x7f9d8d56, (q31_t)0x70163eb, + (q31_t)0x7f9eec3e, (q31_t)0x6f4e620, (q31_t)0x7fa048b2, (q31_t)0x6e86810, + (q31_t)0x7fa1a2b2, (q31_t)0x6dbe9bb, (q31_t)0x7fa2fa3d, (q31_t)0x6cf6b23, + (q31_t)0x7fa44f55, (q31_t)0x6c2ec48, (q31_t)0x7fa5a1f9, (q31_t)0x6b66d29, + (q31_t)0x7fa6f228, (q31_t)0x6a9edc9, (q31_t)0x7fa83fe3, (q31_t)0x69d6e27, + (q31_t)0x7fa98b2a, (q31_t)0x690ee44, (q31_t)0x7faad3fd, (q31_t)0x6846e1f, + (q31_t)0x7fac1a5b, (q31_t)0x677edbb, (q31_t)0x7fad5e45, (q31_t)0x66b6d16, + (q31_t)0x7fae9fbb, (q31_t)0x65eec33, (q31_t)0x7fafdebb, (q31_t)0x6526b10, + (q31_t)0x7fb11b48, (q31_t)0x645e9af, (q31_t)0x7fb2555f, (q31_t)0x6396810, + (q31_t)0x7fb38d02, (q31_t)0x62ce634, (q31_t)0x7fb4c231, (q31_t)0x620641a, + (q31_t)0x7fb5f4ea, (q31_t)0x613e1c5, (q31_t)0x7fb7252f, (q31_t)0x6075f33, + (q31_t)0x7fb852ff, (q31_t)0x5fadc66, (q31_t)0x7fb97e5a, (q31_t)0x5ee595d, + (q31_t)0x7fbaa740, (q31_t)0x5e1d61b, (q31_t)0x7fbbcdb1, (q31_t)0x5d5529e, + (q31_t)0x7fbcf1ad, (q31_t)0x5c8cee7, (q31_t)0x7fbe1334, (q31_t)0x5bc4af8, + (q31_t)0x7fbf3246, (q31_t)0x5afc6d0, (q31_t)0x7fc04ee3, (q31_t)0x5a3426f, + (q31_t)0x7fc1690a, (q31_t)0x596bdd7, (q31_t)0x7fc280bc, (q31_t)0x58a3908, + (q31_t)0x7fc395f9, (q31_t)0x57db403, (q31_t)0x7fc4a8c1, (q31_t)0x5712ec7, + (q31_t)0x7fc5b913, (q31_t)0x564a955, (q31_t)0x7fc6c6f0, (q31_t)0x55823ae, + (q31_t)0x7fc7d258, (q31_t)0x54b9dd3, (q31_t)0x7fc8db4a, (q31_t)0x53f17c3, + (q31_t)0x7fc9e1c6, (q31_t)0x532917f, (q31_t)0x7fcae5cd, (q31_t)0x5260b08, + (q31_t)0x7fcbe75e, (q31_t)0x519845e, (q31_t)0x7fcce67a, (q31_t)0x50cfd82, + (q31_t)0x7fcde320, (q31_t)0x5007674, (q31_t)0x7fcedd50, (q31_t)0x4f3ef35, + (q31_t)0x7fcfd50b, (q31_t)0x4e767c5, (q31_t)0x7fd0ca4f, (q31_t)0x4dae024, + (q31_t)0x7fd1bd1e, (q31_t)0x4ce5854, (q31_t)0x7fd2ad77, (q31_t)0x4c1d054, + (q31_t)0x7fd39b5a, (q31_t)0x4b54825, (q31_t)0x7fd486c7, (q31_t)0x4a8bfc7, + (q31_t)0x7fd56fbe, (q31_t)0x49c373c, (q31_t)0x7fd6563f, (q31_t)0x48fae83, + (q31_t)0x7fd73a4a, (q31_t)0x483259d, (q31_t)0x7fd81bdf, (q31_t)0x4769c8b, + (q31_t)0x7fd8fafe, (q31_t)0x46a134c, (q31_t)0x7fd9d7a7, (q31_t)0x45d89e2, + (q31_t)0x7fdab1d9, (q31_t)0x451004d, (q31_t)0x7fdb8996, (q31_t)0x444768d, + (q31_t)0x7fdc5edc, (q31_t)0x437eca4, (q31_t)0x7fdd31ac, (q31_t)0x42b6290, + (q31_t)0x7fde0205, (q31_t)0x41ed854, (q31_t)0x7fdecfe8, (q31_t)0x4124dee, + (q31_t)0x7fdf9b55, (q31_t)0x405c361, (q31_t)0x7fe0644b, (q31_t)0x3f938ac, + (q31_t)0x7fe12acb, (q31_t)0x3ecadcf, (q31_t)0x7fe1eed5, (q31_t)0x3e022cc, + (q31_t)0x7fe2b067, (q31_t)0x3d397a3, (q31_t)0x7fe36f84, (q31_t)0x3c70c54, + (q31_t)0x7fe42c2a, (q31_t)0x3ba80df, (q31_t)0x7fe4e659, (q31_t)0x3adf546, + (q31_t)0x7fe59e12, (q31_t)0x3a16988, (q31_t)0x7fe65354, (q31_t)0x394dda7, + (q31_t)0x7fe7061f, (q31_t)0x38851a2, (q31_t)0x7fe7b674, (q31_t)0x37bc57b, + (q31_t)0x7fe86452, (q31_t)0x36f3931, (q31_t)0x7fe90fb9, (q31_t)0x362acc5, + (q31_t)0x7fe9b8a9, (q31_t)0x3562038, (q31_t)0x7fea5f23, (q31_t)0x3499389, + (q31_t)0x7feb0326, (q31_t)0x33d06bb, (q31_t)0x7feba4b2, (q31_t)0x33079cc, + (q31_t)0x7fec43c7, (q31_t)0x323ecbe, (q31_t)0x7fece065, (q31_t)0x3175f91, + (q31_t)0x7fed7a8c, (q31_t)0x30ad245, (q31_t)0x7fee123d, (q31_t)0x2fe44dc, + (q31_t)0x7feea776, (q31_t)0x2f1b755, (q31_t)0x7fef3a39, (q31_t)0x2e529b0, + (q31_t)0x7fefca84, (q31_t)0x2d89bf0, (q31_t)0x7ff05858, (q31_t)0x2cc0e13, + (q31_t)0x7ff0e3b6, (q31_t)0x2bf801a, (q31_t)0x7ff16c9c, (q31_t)0x2b2f207, + (q31_t)0x7ff1f30b, (q31_t)0x2a663d8, (q31_t)0x7ff27703, (q31_t)0x299d590, + (q31_t)0x7ff2f884, (q31_t)0x28d472e, (q31_t)0x7ff3778e, (q31_t)0x280b8b3, + (q31_t)0x7ff3f420, (q31_t)0x2742a1f, (q31_t)0x7ff46e3c, (q31_t)0x2679b73, + (q31_t)0x7ff4e5e0, (q31_t)0x25b0caf, (q31_t)0x7ff55b0d, (q31_t)0x24e7dd4, + (q31_t)0x7ff5cdc3, (q31_t)0x241eee2, (q31_t)0x7ff63e01, (q31_t)0x2355fd9, + (q31_t)0x7ff6abc8, (q31_t)0x228d0bb, (q31_t)0x7ff71718, (q31_t)0x21c4188, + (q31_t)0x7ff77ff1, (q31_t)0x20fb240, (q31_t)0x7ff7e652, (q31_t)0x20322e3, + (q31_t)0x7ff84a3c, (q31_t)0x1f69373, (q31_t)0x7ff8abae, (q31_t)0x1ea03ef, + (q31_t)0x7ff90aaa, (q31_t)0x1dd7459, (q31_t)0x7ff9672d, (q31_t)0x1d0e4b0, + (q31_t)0x7ff9c13a, (q31_t)0x1c454f5, (q31_t)0x7ffa18cf, (q31_t)0x1b7c528, + (q31_t)0x7ffa6dec, (q31_t)0x1ab354b, (q31_t)0x7ffac092, (q31_t)0x19ea55d, + (q31_t)0x7ffb10c1, (q31_t)0x192155f, (q31_t)0x7ffb5e78, (q31_t)0x1858552, + (q31_t)0x7ffba9b8, (q31_t)0x178f536, (q31_t)0x7ffbf280, (q31_t)0x16c650b, + (q31_t)0x7ffc38d1, (q31_t)0x15fd4d2, (q31_t)0x7ffc7caa, (q31_t)0x153448c, + (q31_t)0x7ffcbe0c, (q31_t)0x146b438, (q31_t)0x7ffcfcf6, (q31_t)0x13a23d8, + (q31_t)0x7ffd3969, (q31_t)0x12d936c, (q31_t)0x7ffd7364, (q31_t)0x12102f4, + (q31_t)0x7ffdaae7, (q31_t)0x1147271, (q31_t)0x7ffddff3, (q31_t)0x107e1e3, + (q31_t)0x7ffe1288, (q31_t)0xfb514b, (q31_t)0x7ffe42a4, (q31_t)0xeec0aa, + (q31_t)0x7ffe704a, (q31_t)0xe22fff, (q31_t)0x7ffe9b77, (q31_t)0xd59f4c, + (q31_t)0x7ffec42d, (q31_t)0xc90e90, (q31_t)0x7ffeea6c, (q31_t)0xbc7dcc, + (q31_t)0x7fff0e32, (q31_t)0xafed02, (q31_t)0x7fff2f82, (q31_t)0xa35c30, + (q31_t)0x7fff4e59, (q31_t)0x96cb58, (q31_t)0x7fff6ab9, (q31_t)0x8a3a7b, + (q31_t)0x7fff84a1, (q31_t)0x7da998, (q31_t)0x7fff9c12, (q31_t)0x7118b0, + (q31_t)0x7fffb10b, (q31_t)0x6487c4, (q31_t)0x7fffc38c, (q31_t)0x57f6d4, + (q31_t)0x7fffd396, (q31_t)0x4b65e1, (q31_t)0x7fffe128, (q31_t)0x3ed4ea, + (q31_t)0x7fffec43, (q31_t)0x3243f1, (q31_t)0x7ffff4e6, (q31_t)0x25b2f7, + (q31_t)0x7ffffb11, (q31_t)0x1921fb, (q31_t)0x7ffffec4, (q31_t)0xc90fe, + (q31_t)0x7fffffff, (q31_t)0x0, (q31_t)0x7ffffec4, (q31_t)0xfff36f02, + (q31_t)0x7ffffb11, (q31_t)0xffe6de05, (q31_t)0x7ffff4e6, (q31_t)0xffda4d09, + (q31_t)0x7fffec43, (q31_t)0xffcdbc0f, (q31_t)0x7fffe128, (q31_t)0xffc12b16, + (q31_t)0x7fffd396, (q31_t)0xffb49a1f, (q31_t)0x7fffc38c, (q31_t)0xffa8092c, + (q31_t)0x7fffb10b, (q31_t)0xff9b783c, (q31_t)0x7fff9c12, (q31_t)0xff8ee750, + (q31_t)0x7fff84a1, (q31_t)0xff825668, (q31_t)0x7fff6ab9, (q31_t)0xff75c585, + (q31_t)0x7fff4e59, (q31_t)0xff6934a8, (q31_t)0x7fff2f82, (q31_t)0xff5ca3d0, + (q31_t)0x7fff0e32, (q31_t)0xff5012fe, (q31_t)0x7ffeea6c, (q31_t)0xff438234, + (q31_t)0x7ffec42d, (q31_t)0xff36f170, (q31_t)0x7ffe9b77, (q31_t)0xff2a60b4, + (q31_t)0x7ffe704a, (q31_t)0xff1dd001, (q31_t)0x7ffe42a4, (q31_t)0xff113f56, + (q31_t)0x7ffe1288, (q31_t)0xff04aeb5, (q31_t)0x7ffddff3, (q31_t)0xfef81e1d, + (q31_t)0x7ffdaae7, (q31_t)0xfeeb8d8f, (q31_t)0x7ffd7364, (q31_t)0xfedefd0c, + (q31_t)0x7ffd3969, (q31_t)0xfed26c94, (q31_t)0x7ffcfcf6, (q31_t)0xfec5dc28, + (q31_t)0x7ffcbe0c, (q31_t)0xfeb94bc8, (q31_t)0x7ffc7caa, (q31_t)0xfeacbb74, + (q31_t)0x7ffc38d1, (q31_t)0xfea02b2e, (q31_t)0x7ffbf280, (q31_t)0xfe939af5, + (q31_t)0x7ffba9b8, (q31_t)0xfe870aca, (q31_t)0x7ffb5e78, (q31_t)0xfe7a7aae, + (q31_t)0x7ffb10c1, (q31_t)0xfe6deaa1, (q31_t)0x7ffac092, (q31_t)0xfe615aa3, + (q31_t)0x7ffa6dec, (q31_t)0xfe54cab5, (q31_t)0x7ffa18cf, (q31_t)0xfe483ad8, + (q31_t)0x7ff9c13a, (q31_t)0xfe3bab0b, (q31_t)0x7ff9672d, (q31_t)0xfe2f1b50, + (q31_t)0x7ff90aaa, (q31_t)0xfe228ba7, (q31_t)0x7ff8abae, (q31_t)0xfe15fc11, + (q31_t)0x7ff84a3c, (q31_t)0xfe096c8d, (q31_t)0x7ff7e652, (q31_t)0xfdfcdd1d, + (q31_t)0x7ff77ff1, (q31_t)0xfdf04dc0, (q31_t)0x7ff71718, (q31_t)0xfde3be78, + (q31_t)0x7ff6abc8, (q31_t)0xfdd72f45, (q31_t)0x7ff63e01, (q31_t)0xfdcaa027, + (q31_t)0x7ff5cdc3, (q31_t)0xfdbe111e, (q31_t)0x7ff55b0d, (q31_t)0xfdb1822c, + (q31_t)0x7ff4e5e0, (q31_t)0xfda4f351, (q31_t)0x7ff46e3c, (q31_t)0xfd98648d, + (q31_t)0x7ff3f420, (q31_t)0xfd8bd5e1, (q31_t)0x7ff3778e, (q31_t)0xfd7f474d, + (q31_t)0x7ff2f884, (q31_t)0xfd72b8d2, (q31_t)0x7ff27703, (q31_t)0xfd662a70, + (q31_t)0x7ff1f30b, (q31_t)0xfd599c28, (q31_t)0x7ff16c9c, (q31_t)0xfd4d0df9, + (q31_t)0x7ff0e3b6, (q31_t)0xfd407fe6, (q31_t)0x7ff05858, (q31_t)0xfd33f1ed, + (q31_t)0x7fefca84, (q31_t)0xfd276410, (q31_t)0x7fef3a39, (q31_t)0xfd1ad650, + (q31_t)0x7feea776, (q31_t)0xfd0e48ab, (q31_t)0x7fee123d, (q31_t)0xfd01bb24, + (q31_t)0x7fed7a8c, (q31_t)0xfcf52dbb, (q31_t)0x7fece065, (q31_t)0xfce8a06f, + (q31_t)0x7fec43c7, (q31_t)0xfcdc1342, (q31_t)0x7feba4b2, (q31_t)0xfccf8634, + (q31_t)0x7feb0326, (q31_t)0xfcc2f945, (q31_t)0x7fea5f23, (q31_t)0xfcb66c77, + (q31_t)0x7fe9b8a9, (q31_t)0xfca9dfc8, (q31_t)0x7fe90fb9, (q31_t)0xfc9d533b, + (q31_t)0x7fe86452, (q31_t)0xfc90c6cf, (q31_t)0x7fe7b674, (q31_t)0xfc843a85, + (q31_t)0x7fe7061f, (q31_t)0xfc77ae5e, (q31_t)0x7fe65354, (q31_t)0xfc6b2259, + (q31_t)0x7fe59e12, (q31_t)0xfc5e9678, (q31_t)0x7fe4e659, (q31_t)0xfc520aba, + (q31_t)0x7fe42c2a, (q31_t)0xfc457f21, (q31_t)0x7fe36f84, (q31_t)0xfc38f3ac, + (q31_t)0x7fe2b067, (q31_t)0xfc2c685d, (q31_t)0x7fe1eed5, (q31_t)0xfc1fdd34, + (q31_t)0x7fe12acb, (q31_t)0xfc135231, (q31_t)0x7fe0644b, (q31_t)0xfc06c754, + (q31_t)0x7fdf9b55, (q31_t)0xfbfa3c9f, (q31_t)0x7fdecfe8, (q31_t)0xfbedb212, + (q31_t)0x7fde0205, (q31_t)0xfbe127ac, (q31_t)0x7fdd31ac, (q31_t)0xfbd49d70, + (q31_t)0x7fdc5edc, (q31_t)0xfbc8135c, (q31_t)0x7fdb8996, (q31_t)0xfbbb8973, + (q31_t)0x7fdab1d9, (q31_t)0xfbaeffb3, (q31_t)0x7fd9d7a7, (q31_t)0xfba2761e, + (q31_t)0x7fd8fafe, (q31_t)0xfb95ecb4, (q31_t)0x7fd81bdf, (q31_t)0xfb896375, + (q31_t)0x7fd73a4a, (q31_t)0xfb7cda63, (q31_t)0x7fd6563f, (q31_t)0xfb70517d, + (q31_t)0x7fd56fbe, (q31_t)0xfb63c8c4, (q31_t)0x7fd486c7, (q31_t)0xfb574039, + (q31_t)0x7fd39b5a, (q31_t)0xfb4ab7db, (q31_t)0x7fd2ad77, (q31_t)0xfb3e2fac, + (q31_t)0x7fd1bd1e, (q31_t)0xfb31a7ac, (q31_t)0x7fd0ca4f, (q31_t)0xfb251fdc, + (q31_t)0x7fcfd50b, (q31_t)0xfb18983b, (q31_t)0x7fcedd50, (q31_t)0xfb0c10cb, + (q31_t)0x7fcde320, (q31_t)0xfaff898c, (q31_t)0x7fcce67a, (q31_t)0xfaf3027e, + (q31_t)0x7fcbe75e, (q31_t)0xfae67ba2, (q31_t)0x7fcae5cd, (q31_t)0xfad9f4f8, + (q31_t)0x7fc9e1c6, (q31_t)0xfacd6e81, (q31_t)0x7fc8db4a, (q31_t)0xfac0e83d, + (q31_t)0x7fc7d258, (q31_t)0xfab4622d, (q31_t)0x7fc6c6f0, (q31_t)0xfaa7dc52, + (q31_t)0x7fc5b913, (q31_t)0xfa9b56ab, (q31_t)0x7fc4a8c1, (q31_t)0xfa8ed139, + (q31_t)0x7fc395f9, (q31_t)0xfa824bfd, (q31_t)0x7fc280bc, (q31_t)0xfa75c6f8, + (q31_t)0x7fc1690a, (q31_t)0xfa694229, (q31_t)0x7fc04ee3, (q31_t)0xfa5cbd91, + (q31_t)0x7fbf3246, (q31_t)0xfa503930, (q31_t)0x7fbe1334, (q31_t)0xfa43b508, + (q31_t)0x7fbcf1ad, (q31_t)0xfa373119, (q31_t)0x7fbbcdb1, (q31_t)0xfa2aad62, + (q31_t)0x7fbaa740, (q31_t)0xfa1e29e5, (q31_t)0x7fb97e5a, (q31_t)0xfa11a6a3, + (q31_t)0x7fb852ff, (q31_t)0xfa05239a, (q31_t)0x7fb7252f, (q31_t)0xf9f8a0cd, + (q31_t)0x7fb5f4ea, (q31_t)0xf9ec1e3b, (q31_t)0x7fb4c231, (q31_t)0xf9df9be6, + (q31_t)0x7fb38d02, (q31_t)0xf9d319cc, (q31_t)0x7fb2555f, (q31_t)0xf9c697f0, + (q31_t)0x7fb11b48, (q31_t)0xf9ba1651, (q31_t)0x7fafdebb, (q31_t)0xf9ad94f0, + (q31_t)0x7fae9fbb, (q31_t)0xf9a113cd, (q31_t)0x7fad5e45, (q31_t)0xf99492ea, + (q31_t)0x7fac1a5b, (q31_t)0xf9881245, (q31_t)0x7faad3fd, (q31_t)0xf97b91e1, + (q31_t)0x7fa98b2a, (q31_t)0xf96f11bc, (q31_t)0x7fa83fe3, (q31_t)0xf96291d9, + (q31_t)0x7fa6f228, (q31_t)0xf9561237, (q31_t)0x7fa5a1f9, (q31_t)0xf94992d7, + (q31_t)0x7fa44f55, (q31_t)0xf93d13b8, (q31_t)0x7fa2fa3d, (q31_t)0xf93094dd, + (q31_t)0x7fa1a2b2, (q31_t)0xf9241645, (q31_t)0x7fa048b2, (q31_t)0xf91797f0, + (q31_t)0x7f9eec3e, (q31_t)0xf90b19e0, (q31_t)0x7f9d8d56, (q31_t)0xf8fe9c15, + (q31_t)0x7f9c2bfb, (q31_t)0xf8f21e8e, (q31_t)0x7f9ac82c, (q31_t)0xf8e5a14d, + (q31_t)0x7f9961e8, (q31_t)0xf8d92452, (q31_t)0x7f97f932, (q31_t)0xf8cca79e, + (q31_t)0x7f968e07, (q31_t)0xf8c02b31, (q31_t)0x7f952069, (q31_t)0xf8b3af0c, + (q31_t)0x7f93b058, (q31_t)0xf8a7332e, (q31_t)0x7f923dd2, (q31_t)0xf89ab799, + (q31_t)0x7f90c8da, (q31_t)0xf88e3c4d, (q31_t)0x7f8f516e, (q31_t)0xf881c14b, + (q31_t)0x7f8dd78f, (q31_t)0xf8754692, (q31_t)0x7f8c5b3d, (q31_t)0xf868cc24, + (q31_t)0x7f8adc77, (q31_t)0xf85c5201, (q31_t)0x7f895b3e, (q31_t)0xf84fd829, + (q31_t)0x7f87d792, (q31_t)0xf8435e9d, (q31_t)0x7f865174, (q31_t)0xf836e55d, + (q31_t)0x7f84c8e2, (q31_t)0xf82a6c6a, (q31_t)0x7f833ddd, (q31_t)0xf81df3c5, + (q31_t)0x7f81b065, (q31_t)0xf8117b6d, (q31_t)0x7f80207b, (q31_t)0xf8050364, + (q31_t)0x7f7e8e1e, (q31_t)0xf7f88ba9, (q31_t)0x7f7cf94e, (q31_t)0xf7ec143e, + (q31_t)0x7f7b620c, (q31_t)0xf7df9d22, (q31_t)0x7f79c857, (q31_t)0xf7d32657, + (q31_t)0x7f782c30, (q31_t)0xf7c6afdc, (q31_t)0x7f768d96, (q31_t)0xf7ba39b3, + (q31_t)0x7f74ec8a, (q31_t)0xf7adc3db, (q31_t)0x7f73490b, (q31_t)0xf7a14e55, + (q31_t)0x7f71a31b, (q31_t)0xf794d922, (q31_t)0x7f6ffab8, (q31_t)0xf7886442, + (q31_t)0x7f6e4fe3, (q31_t)0xf77befb5, (q31_t)0x7f6ca29c, (q31_t)0xf76f7b7d, + (q31_t)0x7f6af2e3, (q31_t)0xf7630799, (q31_t)0x7f6940b8, (q31_t)0xf756940a, + (q31_t)0x7f678c1c, (q31_t)0xf74a20d0, (q31_t)0x7f65d50d, (q31_t)0xf73daded, + (q31_t)0x7f641b8d, (q31_t)0xf7313b60, (q31_t)0x7f625f9b, (q31_t)0xf724c92a, + (q31_t)0x7f60a138, (q31_t)0xf718574b, (q31_t)0x7f5ee063, (q31_t)0xf70be5c4, + (q31_t)0x7f5d1d1d, (q31_t)0xf6ff7496, (q31_t)0x7f5b5765, (q31_t)0xf6f303c0, + (q31_t)0x7f598f3c, (q31_t)0xf6e69344, (q31_t)0x7f57c4a2, (q31_t)0xf6da2321, + (q31_t)0x7f55f796, (q31_t)0xf6cdb359, (q31_t)0x7f54281a, (q31_t)0xf6c143ec, + (q31_t)0x7f52562c, (q31_t)0xf6b4d4d9, (q31_t)0x7f5081cd, (q31_t)0xf6a86623, + (q31_t)0x7f4eaafe, (q31_t)0xf69bf7c9, (q31_t)0x7f4cd1be, (q31_t)0xf68f89cb, + (q31_t)0x7f4af60d, (q31_t)0xf6831c2b, (q31_t)0x7f4917eb, (q31_t)0xf676aee8, + (q31_t)0x7f473759, (q31_t)0xf66a4203, (q31_t)0x7f455456, (q31_t)0xf65dd57d, + (q31_t)0x7f436ee3, (q31_t)0xf6516956, (q31_t)0x7f4186ff, (q31_t)0xf644fd8f, + (q31_t)0x7f3f9cab, (q31_t)0xf6389228, (q31_t)0x7f3dafe7, (q31_t)0xf62c2721, + (q31_t)0x7f3bc0b3, (q31_t)0xf61fbc7b, (q31_t)0x7f39cf0e, (q31_t)0xf6135237, + (q31_t)0x7f37dafa, (q31_t)0xf606e854, (q31_t)0x7f35e476, (q31_t)0xf5fa7ed4, + (q31_t)0x7f33eb81, (q31_t)0xf5ee15b7, (q31_t)0x7f31f01d, (q31_t)0xf5e1acfd, + (q31_t)0x7f2ff24a, (q31_t)0xf5d544a7, (q31_t)0x7f2df206, (q31_t)0xf5c8dcb6, + (q31_t)0x7f2bef53, (q31_t)0xf5bc7529, (q31_t)0x7f29ea31, (q31_t)0xf5b00e02, + (q31_t)0x7f27e29f, (q31_t)0xf5a3a740, (q31_t)0x7f25d89e, (q31_t)0xf59740e5, + (q31_t)0x7f23cc2e, (q31_t)0xf58adaf0, (q31_t)0x7f21bd4e, (q31_t)0xf57e7563, + (q31_t)0x7f1fabff, (q31_t)0xf572103d, (q31_t)0x7f1d9842, (q31_t)0xf565ab80, + (q31_t)0x7f1b8215, (q31_t)0xf559472b, (q31_t)0x7f19697a, (q31_t)0xf54ce33f, + (q31_t)0x7f174e70, (q31_t)0xf5407fbd, (q31_t)0x7f1530f7, (q31_t)0xf5341ca5, + (q31_t)0x7f13110f, (q31_t)0xf527b9f7, (q31_t)0x7f10eeb9, (q31_t)0xf51b57b5, + (q31_t)0x7f0ec9f5, (q31_t)0xf50ef5de, (q31_t)0x7f0ca2c2, (q31_t)0xf5029473, + (q31_t)0x7f0a7921, (q31_t)0xf4f63374, (q31_t)0x7f084d12, (q31_t)0xf4e9d2e3, + (q31_t)0x7f061e95, (q31_t)0xf4dd72be, (q31_t)0x7f03eda9, (q31_t)0xf4d11308, + (q31_t)0x7f01ba50, (q31_t)0xf4c4b3c0, (q31_t)0x7eff8489, (q31_t)0xf4b854e7, + (q31_t)0x7efd4c54, (q31_t)0xf4abf67e, (q31_t)0x7efb11b1, (q31_t)0xf49f9884, + (q31_t)0x7ef8d4a1, (q31_t)0xf4933afa, (q31_t)0x7ef69523, (q31_t)0xf486dde1, + (q31_t)0x7ef45338, (q31_t)0xf47a8139, (q31_t)0x7ef20ee0, (q31_t)0xf46e2504, + (q31_t)0x7eefc81a, (q31_t)0xf461c940, (q31_t)0x7eed7ee7, (q31_t)0xf4556def, + (q31_t)0x7eeb3347, (q31_t)0xf4491311, (q31_t)0x7ee8e53a, (q31_t)0xf43cb8a7, + (q31_t)0x7ee694c1, (q31_t)0xf4305eb0, (q31_t)0x7ee441da, (q31_t)0xf424052f, + (q31_t)0x7ee1ec87, (q31_t)0xf417ac22, (q31_t)0x7edf94c7, (q31_t)0xf40b538b, + (q31_t)0x7edd3a9a, (q31_t)0xf3fefb6a, (q31_t)0x7edade01, (q31_t)0xf3f2a3bf, + (q31_t)0x7ed87efc, (q31_t)0xf3e64c8c, (q31_t)0x7ed61d8a, (q31_t)0xf3d9f5cf, + (q31_t)0x7ed3b9ad, (q31_t)0xf3cd9f8b, (q31_t)0x7ed15363, (q31_t)0xf3c149bf, + (q31_t)0x7eceeaad, (q31_t)0xf3b4f46c, (q31_t)0x7ecc7f8b, (q31_t)0xf3a89f92, + (q31_t)0x7eca11fe, (q31_t)0xf39c4b32, (q31_t)0x7ec7a205, (q31_t)0xf38ff74d, + (q31_t)0x7ec52fa0, (q31_t)0xf383a3e2, (q31_t)0x7ec2bad0, (q31_t)0xf37750f2, + (q31_t)0x7ec04394, (q31_t)0xf36afe7e, (q31_t)0x7ebdc9ed, (q31_t)0xf35eac86, + (q31_t)0x7ebb4ddb, (q31_t)0xf3525b0b, (q31_t)0x7eb8cf5d, (q31_t)0xf3460a0d, + (q31_t)0x7eb64e75, (q31_t)0xf339b98d, (q31_t)0x7eb3cb21, (q31_t)0xf32d698a, + (q31_t)0x7eb14563, (q31_t)0xf3211a07, (q31_t)0x7eaebd3a, (q31_t)0xf314cb02, + (q31_t)0x7eac32a6, (q31_t)0xf3087c7d, (q31_t)0x7ea9a5a8, (q31_t)0xf2fc2e77, + (q31_t)0x7ea7163f, (q31_t)0xf2efe0f2, (q31_t)0x7ea4846c, (q31_t)0xf2e393ef, + (q31_t)0x7ea1f02f, (q31_t)0xf2d7476c, (q31_t)0x7e9f5988, (q31_t)0xf2cafb6b, + (q31_t)0x7e9cc076, (q31_t)0xf2beafed, (q31_t)0x7e9a24fb, (q31_t)0xf2b264f2, + (q31_t)0x7e978715, (q31_t)0xf2a61a7a, (q31_t)0x7e94e6c6, (q31_t)0xf299d085, + (q31_t)0x7e92440d, (q31_t)0xf28d8715, (q31_t)0x7e8f9eeb, (q31_t)0xf2813e2a, + (q31_t)0x7e8cf75f, (q31_t)0xf274f5c3, (q31_t)0x7e8a4d6a, (q31_t)0xf268ade3, + (q31_t)0x7e87a10c, (q31_t)0xf25c6688, (q31_t)0x7e84f245, (q31_t)0xf2501fb5, + (q31_t)0x7e824114, (q31_t)0xf243d968, (q31_t)0x7e7f8d7b, (q31_t)0xf23793a3, + (q31_t)0x7e7cd778, (q31_t)0xf22b4e66, (q31_t)0x7e7a1f0d, (q31_t)0xf21f09b1, + (q31_t)0x7e77643a, (q31_t)0xf212c585, (q31_t)0x7e74a6fd, (q31_t)0xf20681e3, + (q31_t)0x7e71e759, (q31_t)0xf1fa3ecb, (q31_t)0x7e6f254c, (q31_t)0xf1edfc3d, + (q31_t)0x7e6c60d7, (q31_t)0xf1e1ba3a, (q31_t)0x7e6999fa, (q31_t)0xf1d578c2, + (q31_t)0x7e66d0b4, (q31_t)0xf1c937d6, (q31_t)0x7e640507, (q31_t)0xf1bcf777, + (q31_t)0x7e6136f3, (q31_t)0xf1b0b7a4, (q31_t)0x7e5e6676, (q31_t)0xf1a4785e, + (q31_t)0x7e5b9392, (q31_t)0xf19839a6, (q31_t)0x7e58be47, (q31_t)0xf18bfb7d, + (q31_t)0x7e55e694, (q31_t)0xf17fbde2, (q31_t)0x7e530c7a, (q31_t)0xf17380d6, + (q31_t)0x7e502ff9, (q31_t)0xf1674459, (q31_t)0x7e4d5110, (q31_t)0xf15b086d, + (q31_t)0x7e4a6fc1, (q31_t)0xf14ecd11, (q31_t)0x7e478c0b, (q31_t)0xf1429247, + (q31_t)0x7e44a5ef, (q31_t)0xf136580d, (q31_t)0x7e41bd6c, (q31_t)0xf12a1e66, + (q31_t)0x7e3ed282, (q31_t)0xf11de551, (q31_t)0x7e3be532, (q31_t)0xf111accf, + (q31_t)0x7e38f57c, (q31_t)0xf10574e0, (q31_t)0x7e360360, (q31_t)0xf0f93d86, + (q31_t)0x7e330ede, (q31_t)0xf0ed06bf, (q31_t)0x7e3017f6, (q31_t)0xf0e0d08d, + (q31_t)0x7e2d1ea8, (q31_t)0xf0d49af1, (q31_t)0x7e2a22f4, (q31_t)0xf0c865ea, + (q31_t)0x7e2724db, (q31_t)0xf0bc317a, (q31_t)0x7e24245d, (q31_t)0xf0affda0, + (q31_t)0x7e212179, (q31_t)0xf0a3ca5d, (q31_t)0x7e1e1c30, (q31_t)0xf09797b2, + (q31_t)0x7e1b1482, (q31_t)0xf08b659f, (q31_t)0x7e180a6f, (q31_t)0xf07f3424, + (q31_t)0x7e14fdf7, (q31_t)0xf0730342, (q31_t)0x7e11ef1b, (q31_t)0xf066d2fa, + (q31_t)0x7e0eddd9, (q31_t)0xf05aa34c, (q31_t)0x7e0bca34, (q31_t)0xf04e7438, + (q31_t)0x7e08b42a, (q31_t)0xf04245c0, (q31_t)0x7e059bbb, (q31_t)0xf03617e2, + (q31_t)0x7e0280e9, (q31_t)0xf029eaa1, (q31_t)0x7dff63b2, (q31_t)0xf01dbdfb, + (q31_t)0x7dfc4418, (q31_t)0xf01191f3, (q31_t)0x7df9221a, (q31_t)0xf0056687, + (q31_t)0x7df5fdb8, (q31_t)0xeff93bba, (q31_t)0x7df2d6f3, (q31_t)0xefed118a, + (q31_t)0x7defadca, (q31_t)0xefe0e7f9, (q31_t)0x7dec823e, (q31_t)0xefd4bf08, + (q31_t)0x7de9544f, (q31_t)0xefc896b5, (q31_t)0x7de623fd, (q31_t)0xefbc6f03, + (q31_t)0x7de2f148, (q31_t)0xefb047f2, (q31_t)0x7ddfbc30, (q31_t)0xefa42181, + (q31_t)0x7ddc84b5, (q31_t)0xef97fbb2, (q31_t)0x7dd94ad8, (q31_t)0xef8bd685, + (q31_t)0x7dd60e99, (q31_t)0xef7fb1fa, (q31_t)0x7dd2cff7, (q31_t)0xef738e12, + (q31_t)0x7dcf8ef3, (q31_t)0xef676ace, (q31_t)0x7dcc4b8d, (q31_t)0xef5b482d, + (q31_t)0x7dc905c5, (q31_t)0xef4f2630, (q31_t)0x7dc5bd9b, (q31_t)0xef4304d8, + (q31_t)0x7dc2730f, (q31_t)0xef36e426, (q31_t)0x7dbf2622, (q31_t)0xef2ac419, + (q31_t)0x7dbbd6d4, (q31_t)0xef1ea4b2, (q31_t)0x7db88524, (q31_t)0xef1285f2, + (q31_t)0x7db53113, (q31_t)0xef0667d9, (q31_t)0x7db1daa2, (q31_t)0xeefa4a67, + (q31_t)0x7dae81cf, (q31_t)0xeeee2d9d, (q31_t)0x7dab269b, (q31_t)0xeee2117c, + (q31_t)0x7da7c907, (q31_t)0xeed5f604, (q31_t)0x7da46912, (q31_t)0xeec9db35, + (q31_t)0x7da106bd, (q31_t)0xeebdc110, (q31_t)0x7d9da208, (q31_t)0xeeb1a796, + (q31_t)0x7d9a3af2, (q31_t)0xeea58ec6, (q31_t)0x7d96d17d, (q31_t)0xee9976a1, + (q31_t)0x7d9365a8, (q31_t)0xee8d5f29, (q31_t)0x7d8ff772, (q31_t)0xee81485c, + (q31_t)0x7d8c86de, (q31_t)0xee75323c, (q31_t)0x7d8913ea, (q31_t)0xee691cc9, + (q31_t)0x7d859e96, (q31_t)0xee5d0804, (q31_t)0x7d8226e4, (q31_t)0xee50f3ed, + (q31_t)0x7d7eacd2, (q31_t)0xee44e084, (q31_t)0x7d7b3061, (q31_t)0xee38cdcb, + (q31_t)0x7d77b192, (q31_t)0xee2cbbc1, (q31_t)0x7d743064, (q31_t)0xee20aa67, + (q31_t)0x7d70acd7, (q31_t)0xee1499bd, (q31_t)0x7d6d26ec, (q31_t)0xee0889c4, + (q31_t)0x7d699ea3, (q31_t)0xedfc7a7c, (q31_t)0x7d6613fb, (q31_t)0xedf06be6, + (q31_t)0x7d6286f6, (q31_t)0xede45e03, (q31_t)0x7d5ef793, (q31_t)0xedd850d2, + (q31_t)0x7d5b65d2, (q31_t)0xedcc4454, (q31_t)0x7d57d1b3, (q31_t)0xedc0388a, + (q31_t)0x7d543b37, (q31_t)0xedb42d74, (q31_t)0x7d50a25e, (q31_t)0xeda82313, + (q31_t)0x7d4d0728, (q31_t)0xed9c1967, (q31_t)0x7d496994, (q31_t)0xed901070, + (q31_t)0x7d45c9a4, (q31_t)0xed84082f, (q31_t)0x7d422757, (q31_t)0xed7800a5, + (q31_t)0x7d3e82ae, (q31_t)0xed6bf9d1, (q31_t)0x7d3adba7, (q31_t)0xed5ff3b5, + (q31_t)0x7d373245, (q31_t)0xed53ee51, (q31_t)0x7d338687, (q31_t)0xed47e9a5, + (q31_t)0x7d2fd86c, (q31_t)0xed3be5b1, (q31_t)0x7d2c27f6, (q31_t)0xed2fe277, + (q31_t)0x7d287523, (q31_t)0xed23dff7, (q31_t)0x7d24bff6, (q31_t)0xed17de31, + (q31_t)0x7d21086c, (q31_t)0xed0bdd25, (q31_t)0x7d1d4e88, (q31_t)0xecffdcd4, + (q31_t)0x7d199248, (q31_t)0xecf3dd3f, (q31_t)0x7d15d3ad, (q31_t)0xece7de66, + (q31_t)0x7d1212b7, (q31_t)0xecdbe04a, (q31_t)0x7d0e4f67, (q31_t)0xeccfe2ea, + (q31_t)0x7d0a89bc, (q31_t)0xecc3e648, (q31_t)0x7d06c1b6, (q31_t)0xecb7ea63, + (q31_t)0x7d02f757, (q31_t)0xecabef3d, (q31_t)0x7cff2a9d, (q31_t)0xec9ff4d6, + (q31_t)0x7cfb5b89, (q31_t)0xec93fb2e, (q31_t)0x7cf78a1b, (q31_t)0xec880245, + (q31_t)0x7cf3b653, (q31_t)0xec7c0a1d, (q31_t)0x7cefe032, (q31_t)0xec7012b5, + (q31_t)0x7cec07b8, (q31_t)0xec641c0e, (q31_t)0x7ce82ce4, (q31_t)0xec582629, + (q31_t)0x7ce44fb7, (q31_t)0xec4c3106, (q31_t)0x7ce07031, (q31_t)0xec403ca5, + (q31_t)0x7cdc8e52, (q31_t)0xec344908, (q31_t)0x7cd8aa1b, (q31_t)0xec28562d, + (q31_t)0x7cd4c38b, (q31_t)0xec1c6417, (q31_t)0x7cd0daa2, (q31_t)0xec1072c4, + (q31_t)0x7cccef62, (q31_t)0xec048237, (q31_t)0x7cc901c9, (q31_t)0xebf8926f, + (q31_t)0x7cc511d9, (q31_t)0xebeca36c, (q31_t)0x7cc11f90, (q31_t)0xebe0b52f, + (q31_t)0x7cbd2af0, (q31_t)0xebd4c7ba, (q31_t)0x7cb933f9, (q31_t)0xebc8db0b, + (q31_t)0x7cb53aaa, (q31_t)0xebbcef23, (q31_t)0x7cb13f04, (q31_t)0xebb10404, + (q31_t)0x7cad4107, (q31_t)0xeba519ad, (q31_t)0x7ca940b3, (q31_t)0xeb99301f, + (q31_t)0x7ca53e09, (q31_t)0xeb8d475b, (q31_t)0x7ca13908, (q31_t)0xeb815f60, + (q31_t)0x7c9d31b0, (q31_t)0xeb75782f, (q31_t)0x7c992803, (q31_t)0xeb6991ca, + (q31_t)0x7c951bff, (q31_t)0xeb5dac2f, (q31_t)0x7c910da5, (q31_t)0xeb51c760, + (q31_t)0x7c8cfcf6, (q31_t)0xeb45e35d, (q31_t)0x7c88e9f1, (q31_t)0xeb3a0027, + (q31_t)0x7c84d496, (q31_t)0xeb2e1dbe, (q31_t)0x7c80bce7, (q31_t)0xeb223c22, + (q31_t)0x7c7ca2e2, (q31_t)0xeb165b54, (q31_t)0x7c788688, (q31_t)0xeb0a7b54, + (q31_t)0x7c7467d9, (q31_t)0xeafe9c24, (q31_t)0x7c7046d6, (q31_t)0xeaf2bdc3, + (q31_t)0x7c6c237e, (q31_t)0xeae6e031, (q31_t)0x7c67fdd1, (q31_t)0xeadb0370, + (q31_t)0x7c63d5d1, (q31_t)0xeacf277f, (q31_t)0x7c5fab7c, (q31_t)0xeac34c60, + (q31_t)0x7c5b7ed4, (q31_t)0xeab77212, (q31_t)0x7c574fd8, (q31_t)0xeaab9896, + (q31_t)0x7c531e88, (q31_t)0xea9fbfed, (q31_t)0x7c4eeae5, (q31_t)0xea93e817, + (q31_t)0x7c4ab4ef, (q31_t)0xea881114, (q31_t)0x7c467ca6, (q31_t)0xea7c3ae5, + (q31_t)0x7c42420a, (q31_t)0xea70658a, (q31_t)0x7c3e051b, (q31_t)0xea649105, + (q31_t)0x7c39c5da, (q31_t)0xea58bd54, (q31_t)0x7c358446, (q31_t)0xea4cea79, + (q31_t)0x7c314060, (q31_t)0xea411874, (q31_t)0x7c2cfa28, (q31_t)0xea354746, + (q31_t)0x7c28b19e, (q31_t)0xea2976ef, (q31_t)0x7c2466c2, (q31_t)0xea1da770, + (q31_t)0x7c201994, (q31_t)0xea11d8c8, (q31_t)0x7c1bca16, (q31_t)0xea060af9, + (q31_t)0x7c177845, (q31_t)0xe9fa3e03, (q31_t)0x7c132424, (q31_t)0xe9ee71e6, + (q31_t)0x7c0ecdb2, (q31_t)0xe9e2a6a3, (q31_t)0x7c0a74f0, (q31_t)0xe9d6dc3b, + (q31_t)0x7c0619dc, (q31_t)0xe9cb12ad, (q31_t)0x7c01bc78, (q31_t)0xe9bf49fa, + (q31_t)0x7bfd5cc4, (q31_t)0xe9b38223, (q31_t)0x7bf8fac0, (q31_t)0xe9a7bb28, + (q31_t)0x7bf4966c, (q31_t)0xe99bf509, (q31_t)0x7bf02fc9, (q31_t)0xe9902fc7, + (q31_t)0x7bebc6d5, (q31_t)0xe9846b63, (q31_t)0x7be75b93, (q31_t)0xe978a7dd, + (q31_t)0x7be2ee01, (q31_t)0xe96ce535, (q31_t)0x7bde7e20, (q31_t)0xe961236c, + (q31_t)0x7bda0bf0, (q31_t)0xe9556282, (q31_t)0x7bd59771, (q31_t)0xe949a278, + (q31_t)0x7bd120a4, (q31_t)0xe93de34e, (q31_t)0x7bcca789, (q31_t)0xe9322505, + (q31_t)0x7bc82c1f, (q31_t)0xe926679c, (q31_t)0x7bc3ae67, (q31_t)0xe91aab16, + (q31_t)0x7bbf2e62, (q31_t)0xe90eef71, (q31_t)0x7bbaac0e, (q31_t)0xe90334af, + (q31_t)0x7bb6276e, (q31_t)0xe8f77acf, (q31_t)0x7bb1a080, (q31_t)0xe8ebc1d3, + (q31_t)0x7bad1744, (q31_t)0xe8e009ba, (q31_t)0x7ba88bbc, (q31_t)0xe8d45286, + (q31_t)0x7ba3fde7, (q31_t)0xe8c89c37, (q31_t)0x7b9f6dc5, (q31_t)0xe8bce6cd, + (q31_t)0x7b9adb57, (q31_t)0xe8b13248, (q31_t)0x7b96469d, (q31_t)0xe8a57ea9, + (q31_t)0x7b91af97, (q31_t)0xe899cbf1, (q31_t)0x7b8d1644, (q31_t)0xe88e1a20, + (q31_t)0x7b887aa6, (q31_t)0xe8826936, (q31_t)0x7b83dcbc, (q31_t)0xe876b934, + (q31_t)0x7b7f3c87, (q31_t)0xe86b0a1a, (q31_t)0x7b7a9a07, (q31_t)0xe85f5be9, + (q31_t)0x7b75f53c, (q31_t)0xe853aea1, (q31_t)0x7b714e25, (q31_t)0xe8480243, + (q31_t)0x7b6ca4c4, (q31_t)0xe83c56cf, (q31_t)0x7b67f919, (q31_t)0xe830ac45, + (q31_t)0x7b634b23, (q31_t)0xe82502a7, (q31_t)0x7b5e9ae4, (q31_t)0xe81959f4, + (q31_t)0x7b59e85a, (q31_t)0xe80db22d, (q31_t)0x7b553386, (q31_t)0xe8020b52, + (q31_t)0x7b507c69, (q31_t)0xe7f66564, (q31_t)0x7b4bc303, (q31_t)0xe7eac063, + (q31_t)0x7b470753, (q31_t)0xe7df1c50, (q31_t)0x7b42495a, (q31_t)0xe7d3792b, + (q31_t)0x7b3d8918, (q31_t)0xe7c7d6f4, (q31_t)0x7b38c68e, (q31_t)0xe7bc35ad, + (q31_t)0x7b3401bb, (q31_t)0xe7b09555, (q31_t)0x7b2f3aa0, (q31_t)0xe7a4f5ed, + (q31_t)0x7b2a713d, (q31_t)0xe7995776, (q31_t)0x7b25a591, (q31_t)0xe78db9ef, + (q31_t)0x7b20d79e, (q31_t)0xe7821d59, (q31_t)0x7b1c0764, (q31_t)0xe77681b6, + (q31_t)0x7b1734e2, (q31_t)0xe76ae704, (q31_t)0x7b126019, (q31_t)0xe75f4d45, + (q31_t)0x7b0d8909, (q31_t)0xe753b479, (q31_t)0x7b08afb2, (q31_t)0xe7481ca1, + (q31_t)0x7b03d414, (q31_t)0xe73c85bc, (q31_t)0x7afef630, (q31_t)0xe730efcc, + (q31_t)0x7afa1605, (q31_t)0xe7255ad1, (q31_t)0x7af53395, (q31_t)0xe719c6cb, + (q31_t)0x7af04edf, (q31_t)0xe70e33bb, (q31_t)0x7aeb67e3, (q31_t)0xe702a1a1, + (q31_t)0x7ae67ea1, (q31_t)0xe6f7107e, (q31_t)0x7ae1931a, (q31_t)0xe6eb8052, + (q31_t)0x7adca54e, (q31_t)0xe6dff11d, (q31_t)0x7ad7b53d, (q31_t)0xe6d462e1, + (q31_t)0x7ad2c2e8, (q31_t)0xe6c8d59c, (q31_t)0x7acdce4d, (q31_t)0xe6bd4951, + (q31_t)0x7ac8d76f, (q31_t)0xe6b1bdff, (q31_t)0x7ac3de4c, (q31_t)0xe6a633a6, + (q31_t)0x7abee2e5, (q31_t)0xe69aaa48, (q31_t)0x7ab9e53a, (q31_t)0xe68f21e5, + (q31_t)0x7ab4e54c, (q31_t)0xe6839a7c, (q31_t)0x7aafe31b, (q31_t)0xe6781410, + (q31_t)0x7aaadea6, (q31_t)0xe66c8e9f, (q31_t)0x7aa5d7ee, (q31_t)0xe6610a2a, + (q31_t)0x7aa0cef3, (q31_t)0xe65586b3, (q31_t)0x7a9bc3b6, (q31_t)0xe64a0438, + (q31_t)0x7a96b636, (q31_t)0xe63e82bc, (q31_t)0x7a91a674, (q31_t)0xe633023e, + (q31_t)0x7a8c9470, (q31_t)0xe62782be, (q31_t)0x7a87802a, (q31_t)0xe61c043d, + (q31_t)0x7a8269a3, (q31_t)0xe61086bc, (q31_t)0x7a7d50da, (q31_t)0xe6050a3b, + (q31_t)0x7a7835cf, (q31_t)0xe5f98ebb, (q31_t)0x7a731884, (q31_t)0xe5ee143b, + (q31_t)0x7a6df8f8, (q31_t)0xe5e29abc, (q31_t)0x7a68d72b, (q31_t)0xe5d72240, + (q31_t)0x7a63b31d, (q31_t)0xe5cbaac5, (q31_t)0x7a5e8cd0, (q31_t)0xe5c0344d, + (q31_t)0x7a596442, (q31_t)0xe5b4bed8, (q31_t)0x7a543974, (q31_t)0xe5a94a67, + (q31_t)0x7a4f0c67, (q31_t)0xe59dd6f9, (q31_t)0x7a49dd1a, (q31_t)0xe5926490, + (q31_t)0x7a44ab8e, (q31_t)0xe586f32c, (q31_t)0x7a3f77c3, (q31_t)0xe57b82cd, + (q31_t)0x7a3a41b9, (q31_t)0xe5701374, (q31_t)0x7a350970, (q31_t)0xe564a521, + (q31_t)0x7a2fcee8, (q31_t)0xe55937d5, (q31_t)0x7a2a9223, (q31_t)0xe54dcb8f, + (q31_t)0x7a25531f, (q31_t)0xe5426051, (q31_t)0x7a2011de, (q31_t)0xe536f61b, + (q31_t)0x7a1ace5f, (q31_t)0xe52b8cee, (q31_t)0x7a1588a2, (q31_t)0xe52024c9, + (q31_t)0x7a1040a8, (q31_t)0xe514bdad, (q31_t)0x7a0af671, (q31_t)0xe509579b, + (q31_t)0x7a05a9fd, (q31_t)0xe4fdf294, (q31_t)0x7a005b4d, (q31_t)0xe4f28e96, + (q31_t)0x79fb0a60, (q31_t)0xe4e72ba4, (q31_t)0x79f5b737, (q31_t)0xe4dbc9bd, + (q31_t)0x79f061d2, (q31_t)0xe4d068e2, (q31_t)0x79eb0a31, (q31_t)0xe4c50914, + (q31_t)0x79e5b054, (q31_t)0xe4b9aa52, (q31_t)0x79e0543c, (q31_t)0xe4ae4c9d, + (q31_t)0x79daf5e8, (q31_t)0xe4a2eff6, (q31_t)0x79d5955a, (q31_t)0xe497945d, + (q31_t)0x79d03291, (q31_t)0xe48c39d3, (q31_t)0x79cacd8d, (q31_t)0xe480e057, + (q31_t)0x79c5664f, (q31_t)0xe47587eb, (q31_t)0x79bffcd7, (q31_t)0xe46a308f, + (q31_t)0x79ba9125, (q31_t)0xe45eda43, (q31_t)0x79b52339, (q31_t)0xe4538507, + (q31_t)0x79afb313, (q31_t)0xe44830dd, (q31_t)0x79aa40b4, (q31_t)0xe43cddc4, + (q31_t)0x79a4cc1c, (q31_t)0xe4318bbe, (q31_t)0x799f554b, (q31_t)0xe4263ac9, + (q31_t)0x7999dc42, (q31_t)0xe41aeae8, (q31_t)0x799460ff, (q31_t)0xe40f9c1a, + (q31_t)0x798ee385, (q31_t)0xe4044e60, (q31_t)0x798963d2, (q31_t)0xe3f901ba, + (q31_t)0x7983e1e8, (q31_t)0xe3edb628, (q31_t)0x797e5dc6, (q31_t)0xe3e26bac, + (q31_t)0x7978d76c, (q31_t)0xe3d72245, (q31_t)0x79734edc, (q31_t)0xe3cbd9f4, + (q31_t)0x796dc414, (q31_t)0xe3c092b9, (q31_t)0x79683715, (q31_t)0xe3b54c95, + (q31_t)0x7962a7e0, (q31_t)0xe3aa0788, (q31_t)0x795d1675, (q31_t)0xe39ec393, + (q31_t)0x795782d3, (q31_t)0xe39380b6, (q31_t)0x7951ecfc, (q31_t)0xe3883ef2, + (q31_t)0x794c54ee, (q31_t)0xe37cfe47, (q31_t)0x7946baac, (q31_t)0xe371beb5, + (q31_t)0x79411e33, (q31_t)0xe366803c, (q31_t)0x793b7f86, (q31_t)0xe35b42df, + (q31_t)0x7935dea4, (q31_t)0xe350069b, (q31_t)0x79303b8e, (q31_t)0xe344cb73, + (q31_t)0x792a9642, (q31_t)0xe3399167, (q31_t)0x7924eec3, (q31_t)0xe32e5876, + (q31_t)0x791f4510, (q31_t)0xe32320a2, (q31_t)0x79199929, (q31_t)0xe317e9eb, + (q31_t)0x7913eb0e, (q31_t)0xe30cb451, (q31_t)0x790e3ac0, (q31_t)0xe3017fd5, + (q31_t)0x7908883f, (q31_t)0xe2f64c77, (q31_t)0x7902d38b, (q31_t)0xe2eb1a37, + (q31_t)0x78fd1ca4, (q31_t)0xe2dfe917, (q31_t)0x78f7638b, (q31_t)0xe2d4b916, + (q31_t)0x78f1a840, (q31_t)0xe2c98a35, (q31_t)0x78ebeac2, (q31_t)0xe2be5c74, + (q31_t)0x78e62b13, (q31_t)0xe2b32fd4, (q31_t)0x78e06932, (q31_t)0xe2a80456, + (q31_t)0x78daa520, (q31_t)0xe29cd9f8, (q31_t)0x78d4dedd, (q31_t)0xe291b0bd, + (q31_t)0x78cf1669, (q31_t)0xe28688a4, (q31_t)0x78c94bc4, (q31_t)0xe27b61af, + (q31_t)0x78c37eef, (q31_t)0xe2703bdc, (q31_t)0x78bdafea, (q31_t)0xe265172e, + (q31_t)0x78b7deb4, (q31_t)0xe259f3a3, (q31_t)0x78b20b4f, (q31_t)0xe24ed13d, + (q31_t)0x78ac35ba, (q31_t)0xe243affc, (q31_t)0x78a65df6, (q31_t)0xe2388fe1, + (q31_t)0x78a08402, (q31_t)0xe22d70eb, (q31_t)0x789aa7e0, (q31_t)0xe222531c, + (q31_t)0x7894c98f, (q31_t)0xe2173674, (q31_t)0x788ee910, (q31_t)0xe20c1af3, + (q31_t)0x78890663, (q31_t)0xe2010099, (q31_t)0x78832187, (q31_t)0xe1f5e768, + (q31_t)0x787d3a7e, (q31_t)0xe1eacf5f, (q31_t)0x78775147, (q31_t)0xe1dfb87f, + (q31_t)0x787165e3, (q31_t)0xe1d4a2c8, (q31_t)0x786b7852, (q31_t)0xe1c98e3b, + (q31_t)0x78658894, (q31_t)0xe1be7ad8, (q31_t)0x785f96a9, (q31_t)0xe1b368a0, + (q31_t)0x7859a292, (q31_t)0xe1a85793, (q31_t)0x7853ac4f, (q31_t)0xe19d47b1, + (q31_t)0x784db3e0, (q31_t)0xe19238fb, (q31_t)0x7847b946, (q31_t)0xe1872b72, + (q31_t)0x7841bc7f, (q31_t)0xe17c1f15, (q31_t)0x783bbd8e, (q31_t)0xe17113e5, + (q31_t)0x7835bc71, (q31_t)0xe16609e3, (q31_t)0x782fb92a, (q31_t)0xe15b0110, + (q31_t)0x7829b3b9, (q31_t)0xe14ff96a, (q31_t)0x7823ac1d, (q31_t)0xe144f2f3, + (q31_t)0x781da256, (q31_t)0xe139edac, (q31_t)0x78179666, (q31_t)0xe12ee995, + (q31_t)0x7811884d, (q31_t)0xe123e6ad, (q31_t)0x780b780a, (q31_t)0xe118e4f6, + (q31_t)0x7805659e, (q31_t)0xe10de470, (q31_t)0x77ff5109, (q31_t)0xe102e51c, + (q31_t)0x77f93a4b, (q31_t)0xe0f7e6f9, (q31_t)0x77f32165, (q31_t)0xe0ecea09, + (q31_t)0x77ed0657, (q31_t)0xe0e1ee4b, (q31_t)0x77e6e921, (q31_t)0xe0d6f3c1, + (q31_t)0x77e0c9c3, (q31_t)0xe0cbfa6a, (q31_t)0x77daa83d, (q31_t)0xe0c10247, + (q31_t)0x77d48490, (q31_t)0xe0b60b58, (q31_t)0x77ce5ebd, (q31_t)0xe0ab159e, + (q31_t)0x77c836c2, (q31_t)0xe0a0211a, (q31_t)0x77c20ca1, (q31_t)0xe0952dcb, + (q31_t)0x77bbe05a, (q31_t)0xe08a3bb2, (q31_t)0x77b5b1ec, (q31_t)0xe07f4acf, + (q31_t)0x77af8159, (q31_t)0xe0745b24, (q31_t)0x77a94ea0, (q31_t)0xe0696cb0, + (q31_t)0x77a319c2, (q31_t)0xe05e7f74, (q31_t)0x779ce2be, (q31_t)0xe053936f, + (q31_t)0x7796a996, (q31_t)0xe048a8a4, (q31_t)0x77906e49, (q31_t)0xe03dbf11, + (q31_t)0x778a30d8, (q31_t)0xe032d6b8, (q31_t)0x7783f143, (q31_t)0xe027ef99, + (q31_t)0x777daf89, (q31_t)0xe01d09b4, (q31_t)0x77776bac, (q31_t)0xe012250a, + (q31_t)0x777125ac, (q31_t)0xe007419b, (q31_t)0x776add88, (q31_t)0xdffc5f67, + (q31_t)0x77649341, (q31_t)0xdff17e70, (q31_t)0x775e46d8, (q31_t)0xdfe69eb4, + (q31_t)0x7757f84c, (q31_t)0xdfdbc036, (q31_t)0x7751a79e, (q31_t)0xdfd0e2f5, + (q31_t)0x774b54ce, (q31_t)0xdfc606f1, (q31_t)0x7744ffdd, (q31_t)0xdfbb2c2c, + (q31_t)0x773ea8ca, (q31_t)0xdfb052a5, (q31_t)0x77384f95, (q31_t)0xdfa57a5d, + (q31_t)0x7731f440, (q31_t)0xdf9aa354, (q31_t)0x772b96ca, (q31_t)0xdf8fcd8b, + (q31_t)0x77253733, (q31_t)0xdf84f902, (q31_t)0x771ed57c, (q31_t)0xdf7a25ba, + (q31_t)0x771871a5, (q31_t)0xdf6f53b3, (q31_t)0x77120bae, (q31_t)0xdf6482ed, + (q31_t)0x770ba398, (q31_t)0xdf59b369, (q31_t)0x77053962, (q31_t)0xdf4ee527, + (q31_t)0x76fecd0e, (q31_t)0xdf441828, (q31_t)0x76f85e9a, (q31_t)0xdf394c6b, + (q31_t)0x76f1ee09, (q31_t)0xdf2e81f3, (q31_t)0x76eb7b58, (q31_t)0xdf23b8be, + (q31_t)0x76e5068a, (q31_t)0xdf18f0ce, (q31_t)0x76de8f9e, (q31_t)0xdf0e2a22, + (q31_t)0x76d81695, (q31_t)0xdf0364bc, (q31_t)0x76d19b6e, (q31_t)0xdef8a09b, + (q31_t)0x76cb1e2a, (q31_t)0xdeedddc0, (q31_t)0x76c49ec9, (q31_t)0xdee31c2b, + (q31_t)0x76be1d4c, (q31_t)0xded85bdd, (q31_t)0x76b799b3, (q31_t)0xdecd9cd7, + (q31_t)0x76b113fd, (q31_t)0xdec2df18, (q31_t)0x76aa8c2c, (q31_t)0xdeb822a1, + (q31_t)0x76a4023f, (q31_t)0xdead6773, (q31_t)0x769d7637, (q31_t)0xdea2ad8d, + (q31_t)0x7696e814, (q31_t)0xde97f4f1, (q31_t)0x769057d6, (q31_t)0xde8d3d9e, + (q31_t)0x7689c57d, (q31_t)0xde828796, (q31_t)0x7683310b, (q31_t)0xde77d2d8, + (q31_t)0x767c9a7e, (q31_t)0xde6d1f65, (q31_t)0x767601d7, (q31_t)0xde626d3e, + (q31_t)0x766f6717, (q31_t)0xde57bc62, (q31_t)0x7668ca3e, (q31_t)0xde4d0cd2, + (q31_t)0x76622b4c, (q31_t)0xde425e8f, (q31_t)0x765b8a41, (q31_t)0xde37b199, + (q31_t)0x7654e71d, (q31_t)0xde2d05f1, (q31_t)0x764e41e2, (q31_t)0xde225b96, + (q31_t)0x76479a8e, (q31_t)0xde17b28a, (q31_t)0x7640f123, (q31_t)0xde0d0acc, + (q31_t)0x763a45a0, (q31_t)0xde02645d, (q31_t)0x76339806, (q31_t)0xddf7bf3e, + (q31_t)0x762ce855, (q31_t)0xdded1b6e, (q31_t)0x7626368d, (q31_t)0xdde278ef, + (q31_t)0x761f82af, (q31_t)0xddd7d7c1, (q31_t)0x7618ccba, (q31_t)0xddcd37e4, + (q31_t)0x761214b0, (q31_t)0xddc29958, (q31_t)0x760b5a90, (q31_t)0xddb7fc1e, + (q31_t)0x76049e5b, (q31_t)0xddad6036, (q31_t)0x75fde011, (q31_t)0xdda2c5a2, + (q31_t)0x75f71fb1, (q31_t)0xdd982c60, (q31_t)0x75f05d3d, (q31_t)0xdd8d9472, + (q31_t)0x75e998b5, (q31_t)0xdd82fdd8, (q31_t)0x75e2d219, (q31_t)0xdd786892, + (q31_t)0x75dc0968, (q31_t)0xdd6dd4a2, (q31_t)0x75d53ea5, (q31_t)0xdd634206, + (q31_t)0x75ce71ce, (q31_t)0xdd58b0c0, (q31_t)0x75c7a2e3, (q31_t)0xdd4e20d0, + (q31_t)0x75c0d1e7, (q31_t)0xdd439236, (q31_t)0x75b9fed7, (q31_t)0xdd3904f4, + (q31_t)0x75b329b5, (q31_t)0xdd2e7908, (q31_t)0x75ac5282, (q31_t)0xdd23ee74, + (q31_t)0x75a5793c, (q31_t)0xdd196538, (q31_t)0x759e9de5, (q31_t)0xdd0edd55, + (q31_t)0x7597c07d, (q31_t)0xdd0456ca, (q31_t)0x7590e104, (q31_t)0xdcf9d199, + (q31_t)0x7589ff7a, (q31_t)0xdcef4dc2, (q31_t)0x75831be0, (q31_t)0xdce4cb44, + (q31_t)0x757c3636, (q31_t)0xdcda4a21, (q31_t)0x75754e7c, (q31_t)0xdccfca59, + (q31_t)0x756e64b2, (q31_t)0xdcc54bec, (q31_t)0x756778d9, (q31_t)0xdcbacedb, + (q31_t)0x75608af1, (q31_t)0xdcb05326, (q31_t)0x75599afa, (q31_t)0xdca5d8cd, + (q31_t)0x7552a8f4, (q31_t)0xdc9b5fd2, (q31_t)0x754bb4e1, (q31_t)0xdc90e834, + (q31_t)0x7544bebf, (q31_t)0xdc8671f3, (q31_t)0x753dc68f, (q31_t)0xdc7bfd11, + (q31_t)0x7536cc52, (q31_t)0xdc71898d, (q31_t)0x752fd008, (q31_t)0xdc671768, + (q31_t)0x7528d1b1, (q31_t)0xdc5ca6a2, (q31_t)0x7521d14d, (q31_t)0xdc52373c, + (q31_t)0x751acedd, (q31_t)0xdc47c936, (q31_t)0x7513ca60, (q31_t)0xdc3d5c91, + (q31_t)0x750cc3d8, (q31_t)0xdc32f14d, (q31_t)0x7505bb44, (q31_t)0xdc28876a, + (q31_t)0x74feb0a5, (q31_t)0xdc1e1ee9, (q31_t)0x74f7a3fb, (q31_t)0xdc13b7c9, + (q31_t)0x74f09546, (q31_t)0xdc09520d, (q31_t)0x74e98487, (q31_t)0xdbfeedb3, + (q31_t)0x74e271bd, (q31_t)0xdbf48abd, (q31_t)0x74db5cea, (q31_t)0xdbea292b, + (q31_t)0x74d4460c, (q31_t)0xdbdfc8fc, (q31_t)0x74cd2d26, (q31_t)0xdbd56a32, + (q31_t)0x74c61236, (q31_t)0xdbcb0cce, (q31_t)0x74bef53d, (q31_t)0xdbc0b0ce, + (q31_t)0x74b7d63c, (q31_t)0xdbb65634, (q31_t)0x74b0b533, (q31_t)0xdbabfd01, + (q31_t)0x74a99221, (q31_t)0xdba1a534, (q31_t)0x74a26d08, (q31_t)0xdb974ece, + (q31_t)0x749b45e7, (q31_t)0xdb8cf9cf, (q31_t)0x74941cbf, (q31_t)0xdb82a638, + (q31_t)0x748cf190, (q31_t)0xdb785409, (q31_t)0x7485c45b, (q31_t)0xdb6e0342, + (q31_t)0x747e951f, (q31_t)0xdb63b3e5, (q31_t)0x747763dd, (q31_t)0xdb5965f1, + (q31_t)0x74703095, (q31_t)0xdb4f1967, (q31_t)0x7468fb47, (q31_t)0xdb44ce46, + (q31_t)0x7461c3f5, (q31_t)0xdb3a8491, (q31_t)0x745a8a9d, (q31_t)0xdb303c46, + (q31_t)0x74534f41, (q31_t)0xdb25f566, (q31_t)0x744c11e0, (q31_t)0xdb1baff2, + (q31_t)0x7444d27b, (q31_t)0xdb116beb, (q31_t)0x743d9112, (q31_t)0xdb072950, + (q31_t)0x74364da6, (q31_t)0xdafce821, (q31_t)0x742f0836, (q31_t)0xdaf2a860, + (q31_t)0x7427c0c3, (q31_t)0xdae86a0d, (q31_t)0x7420774d, (q31_t)0xdade2d28, + (q31_t)0x74192bd5, (q31_t)0xdad3f1b1, (q31_t)0x7411de5b, (q31_t)0xdac9b7a9, + (q31_t)0x740a8edf, (q31_t)0xdabf7f11, (q31_t)0x74033d61, (q31_t)0xdab547e8, + (q31_t)0x73fbe9e2, (q31_t)0xdaab122f, (q31_t)0x73f49462, (q31_t)0xdaa0dde7, + (q31_t)0x73ed3ce1, (q31_t)0xda96ab0f, (q31_t)0x73e5e360, (q31_t)0xda8c79a9, + (q31_t)0x73de87de, (q31_t)0xda8249b4, (q31_t)0x73d72a5d, (q31_t)0xda781b31, + (q31_t)0x73cfcadc, (q31_t)0xda6dee21, (q31_t)0x73c8695b, (q31_t)0xda63c284, + (q31_t)0x73c105db, (q31_t)0xda599859, (q31_t)0x73b9a05d, (q31_t)0xda4f6fa3, + (q31_t)0x73b238e0, (q31_t)0xda454860, (q31_t)0x73aacf65, (q31_t)0xda3b2292, + (q31_t)0x73a363ec, (q31_t)0xda30fe38, (q31_t)0x739bf675, (q31_t)0xda26db54, + (q31_t)0x73948701, (q31_t)0xda1cb9e5, (q31_t)0x738d1590, (q31_t)0xda1299ec, + (q31_t)0x7385a222, (q31_t)0xda087b69, (q31_t)0x737e2cb7, (q31_t)0xd9fe5e5e, + (q31_t)0x7376b551, (q31_t)0xd9f442c9, (q31_t)0x736f3bee, (q31_t)0xd9ea28ac, + (q31_t)0x7367c090, (q31_t)0xd9e01006, (q31_t)0x73604336, (q31_t)0xd9d5f8d9, + (q31_t)0x7358c3e2, (q31_t)0xd9cbe325, (q31_t)0x73514292, (q31_t)0xd9c1cee9, + (q31_t)0x7349bf48, (q31_t)0xd9b7bc27, (q31_t)0x73423a04, (q31_t)0xd9adaadf, + (q31_t)0x733ab2c6, (q31_t)0xd9a39b11, (q31_t)0x7333298f, (q31_t)0xd9998cbe, + (q31_t)0x732b9e5e, (q31_t)0xd98f7fe6, (q31_t)0x73241134, (q31_t)0xd9857489, + (q31_t)0x731c8211, (q31_t)0xd97b6aa8, (q31_t)0x7314f0f6, (q31_t)0xd9716243, + (q31_t)0x730d5de3, (q31_t)0xd9675b5a, (q31_t)0x7305c8d7, (q31_t)0xd95d55ef, + (q31_t)0x72fe31d5, (q31_t)0xd9535201, (q31_t)0x72f698db, (q31_t)0xd9494f90, + (q31_t)0x72eefdea, (q31_t)0xd93f4e9e, (q31_t)0x72e76102, (q31_t)0xd9354f2a, + (q31_t)0x72dfc224, (q31_t)0xd92b5135, (q31_t)0x72d82150, (q31_t)0xd92154bf, + (q31_t)0x72d07e85, (q31_t)0xd91759c9, (q31_t)0x72c8d9c6, (q31_t)0xd90d6053, + (q31_t)0x72c13311, (q31_t)0xd903685d, (q31_t)0x72b98a67, (q31_t)0xd8f971e8, + (q31_t)0x72b1dfc9, (q31_t)0xd8ef7cf4, (q31_t)0x72aa3336, (q31_t)0xd8e58982, + (q31_t)0x72a284b0, (q31_t)0xd8db9792, (q31_t)0x729ad435, (q31_t)0xd8d1a724, + (q31_t)0x729321c7, (q31_t)0xd8c7b838, (q31_t)0x728b6d66, (q31_t)0xd8bdcad0, + (q31_t)0x7283b712, (q31_t)0xd8b3deeb, (q31_t)0x727bfecc, (q31_t)0xd8a9f48a, + (q31_t)0x72744493, (q31_t)0xd8a00bae, (q31_t)0x726c8868, (q31_t)0xd8962456, + (q31_t)0x7264ca4c, (q31_t)0xd88c3e83, (q31_t)0x725d0a3e, (q31_t)0xd8825a35, + (q31_t)0x72554840, (q31_t)0xd878776d, (q31_t)0x724d8450, (q31_t)0xd86e962b, + (q31_t)0x7245be70, (q31_t)0xd864b670, (q31_t)0x723df6a0, (q31_t)0xd85ad83c, + (q31_t)0x72362ce0, (q31_t)0xd850fb8e, (q31_t)0x722e6130, (q31_t)0xd8472069, + (q31_t)0x72269391, (q31_t)0xd83d46cc, (q31_t)0x721ec403, (q31_t)0xd8336eb7, + (q31_t)0x7216f287, (q31_t)0xd829982b, (q31_t)0x720f1f1c, (q31_t)0xd81fc328, + (q31_t)0x720749c3, (q31_t)0xd815efae, (q31_t)0x71ff727c, (q31_t)0xd80c1dbf, + (q31_t)0x71f79948, (q31_t)0xd8024d59, (q31_t)0x71efbe27, (q31_t)0xd7f87e7f, + (q31_t)0x71e7e118, (q31_t)0xd7eeb130, (q31_t)0x71e0021e, (q31_t)0xd7e4e56c, + (q31_t)0x71d82137, (q31_t)0xd7db1b34, (q31_t)0x71d03e64, (q31_t)0xd7d15288, + (q31_t)0x71c859a5, (q31_t)0xd7c78b68, (q31_t)0x71c072fb, (q31_t)0xd7bdc5d6, + (q31_t)0x71b88a66, (q31_t)0xd7b401d1, (q31_t)0x71b09fe7, (q31_t)0xd7aa3f5a, + (q31_t)0x71a8b37c, (q31_t)0xd7a07e70, (q31_t)0x71a0c528, (q31_t)0xd796bf16, + (q31_t)0x7198d4ea, (q31_t)0xd78d014a, (q31_t)0x7190e2c3, (q31_t)0xd783450d, + (q31_t)0x7188eeb2, (q31_t)0xd7798a60, (q31_t)0x7180f8b8, (q31_t)0xd76fd143, + (q31_t)0x717900d6, (q31_t)0xd76619b6, (q31_t)0x7171070c, (q31_t)0xd75c63ba, + (q31_t)0x71690b59, (q31_t)0xd752af4f, (q31_t)0x71610dbf, (q31_t)0xd748fc75, + (q31_t)0x71590e3e, (q31_t)0xd73f4b2e, (q31_t)0x71510cd5, (q31_t)0xd7359b78, + (q31_t)0x71490986, (q31_t)0xd72bed55, (q31_t)0x71410450, (q31_t)0xd72240c5, + (q31_t)0x7138fd35, (q31_t)0xd71895c9, (q31_t)0x7130f433, (q31_t)0xd70eec60, + (q31_t)0x7128e94c, (q31_t)0xd705448b, (q31_t)0x7120dc80, (q31_t)0xd6fb9e4b, + (q31_t)0x7118cdcf, (q31_t)0xd6f1f99f, (q31_t)0x7110bd39, (q31_t)0xd6e85689, + (q31_t)0x7108aabf, (q31_t)0xd6deb508, (q31_t)0x71009661, (q31_t)0xd6d5151d, + (q31_t)0x70f8801f, (q31_t)0xd6cb76c9, (q31_t)0x70f067fb, (q31_t)0xd6c1da0b, + (q31_t)0x70e84df3, (q31_t)0xd6b83ee4, (q31_t)0x70e03208, (q31_t)0xd6aea555, + (q31_t)0x70d8143b, (q31_t)0xd6a50d5d, (q31_t)0x70cff48c, (q31_t)0xd69b76fe, + (q31_t)0x70c7d2fb, (q31_t)0xd691e237, (q31_t)0x70bfaf89, (q31_t)0xd6884f09, + (q31_t)0x70b78a36, (q31_t)0xd67ebd74, (q31_t)0x70af6302, (q31_t)0xd6752d79, + (q31_t)0x70a739ed, (q31_t)0xd66b9f18, (q31_t)0x709f0ef8, (q31_t)0xd6621251, + (q31_t)0x7096e223, (q31_t)0xd6588725, (q31_t)0x708eb36f, (q31_t)0xd64efd94, + (q31_t)0x708682dc, (q31_t)0xd645759f, (q31_t)0x707e5069, (q31_t)0xd63bef46, + (q31_t)0x70761c18, (q31_t)0xd6326a88, (q31_t)0x706de5e9, (q31_t)0xd628e767, + (q31_t)0x7065addb, (q31_t)0xd61f65e4, (q31_t)0x705d73f0, (q31_t)0xd615e5fd, + (q31_t)0x70553828, (q31_t)0xd60c67b4, (q31_t)0x704cfa83, (q31_t)0xd602eb0a, + (q31_t)0x7044bb00, (q31_t)0xd5f96ffd, (q31_t)0x703c79a2, (q31_t)0xd5eff690, + (q31_t)0x70343667, (q31_t)0xd5e67ec1, (q31_t)0x702bf151, (q31_t)0xd5dd0892, + (q31_t)0x7023aa5f, (q31_t)0xd5d39403, (q31_t)0x701b6193, (q31_t)0xd5ca2115, + (q31_t)0x701316eb, (q31_t)0xd5c0afc6, (q31_t)0x700aca69, (q31_t)0xd5b74019, + (q31_t)0x70027c0c, (q31_t)0xd5add20d, (q31_t)0x6ffa2bd6, (q31_t)0xd5a465a3, + (q31_t)0x6ff1d9c7, (q31_t)0xd59afadb, (q31_t)0x6fe985de, (q31_t)0xd59191b5, + (q31_t)0x6fe1301c, (q31_t)0xd5882a32, (q31_t)0x6fd8d882, (q31_t)0xd57ec452, + (q31_t)0x6fd07f0f, (q31_t)0xd5756016, (q31_t)0x6fc823c5, (q31_t)0xd56bfd7d, + (q31_t)0x6fbfc6a3, (q31_t)0xd5629c89, (q31_t)0x6fb767aa, (q31_t)0xd5593d3a, + (q31_t)0x6faf06da, (q31_t)0xd54fdf8f, (q31_t)0x6fa6a433, (q31_t)0xd5468389, + (q31_t)0x6f9e3fb6, (q31_t)0xd53d292a, (q31_t)0x6f95d963, (q31_t)0xd533d070, + (q31_t)0x6f8d713a, (q31_t)0xd52a795d, (q31_t)0x6f85073c, (q31_t)0xd52123f0, + (q31_t)0x6f7c9b69, (q31_t)0xd517d02b, (q31_t)0x6f742dc1, (q31_t)0xd50e7e0d, + (q31_t)0x6f6bbe45, (q31_t)0xd5052d97, (q31_t)0x6f634cf5, (q31_t)0xd4fbdec9, + (q31_t)0x6f5ad9d1, (q31_t)0xd4f291a4, (q31_t)0x6f5264da, (q31_t)0xd4e94627, + (q31_t)0x6f49ee0f, (q31_t)0xd4dffc54, (q31_t)0x6f417573, (q31_t)0xd4d6b42b, + (q31_t)0x6f38fb03, (q31_t)0xd4cd6dab, (q31_t)0x6f307ec2, (q31_t)0xd4c428d6, + (q31_t)0x6f2800af, (q31_t)0xd4bae5ab, (q31_t)0x6f1f80ca, (q31_t)0xd4b1a42c, + (q31_t)0x6f16ff14, (q31_t)0xd4a86458, (q31_t)0x6f0e7b8e, (q31_t)0xd49f2630, + (q31_t)0x6f05f637, (q31_t)0xd495e9b3, (q31_t)0x6efd6f10, (q31_t)0xd48caee4, + (q31_t)0x6ef4e619, (q31_t)0xd48375c1, (q31_t)0x6eec5b53, (q31_t)0xd47a3e4b, + (q31_t)0x6ee3cebe, (q31_t)0xd4710883, (q31_t)0x6edb405a, (q31_t)0xd467d469, + (q31_t)0x6ed2b027, (q31_t)0xd45ea1fd, (q31_t)0x6eca1e27, (q31_t)0xd4557140, + (q31_t)0x6ec18a58, (q31_t)0xd44c4232, (q31_t)0x6eb8f4bc, (q31_t)0xd44314d3, + (q31_t)0x6eb05d53, (q31_t)0xd439e923, (q31_t)0x6ea7c41e, (q31_t)0xd430bf24, + (q31_t)0x6e9f291b, (q31_t)0xd42796d5, (q31_t)0x6e968c4d, (q31_t)0xd41e7037, + (q31_t)0x6e8dedb3, (q31_t)0xd4154b4a, (q31_t)0x6e854d4d, (q31_t)0xd40c280e, + (q31_t)0x6e7cab1c, (q31_t)0xd4030684, (q31_t)0x6e740720, (q31_t)0xd3f9e6ad, + (q31_t)0x6e6b615a, (q31_t)0xd3f0c887, (q31_t)0x6e62b9ca, (q31_t)0xd3e7ac15, + (q31_t)0x6e5a1070, (q31_t)0xd3de9156, (q31_t)0x6e51654c, (q31_t)0xd3d5784a, + (q31_t)0x6e48b860, (q31_t)0xd3cc60f2, (q31_t)0x6e4009aa, (q31_t)0xd3c34b4f, + (q31_t)0x6e37592c, (q31_t)0xd3ba3760, (q31_t)0x6e2ea6e6, (q31_t)0xd3b12526, + (q31_t)0x6e25f2d8, (q31_t)0xd3a814a2, (q31_t)0x6e1d3d03, (q31_t)0xd39f05d3, + (q31_t)0x6e148566, (q31_t)0xd395f8ba, (q31_t)0x6e0bcc03, (q31_t)0xd38ced57, + (q31_t)0x6e0310d9, (q31_t)0xd383e3ab, (q31_t)0x6dfa53e9, (q31_t)0xd37adbb6, + (q31_t)0x6df19534, (q31_t)0xd371d579, (q31_t)0x6de8d4b8, (q31_t)0xd368d0f3, + (q31_t)0x6de01278, (q31_t)0xd35fce26, (q31_t)0x6dd74e73, (q31_t)0xd356cd11, + (q31_t)0x6dce88aa, (q31_t)0xd34dcdb4, (q31_t)0x6dc5c11c, (q31_t)0xd344d011, + (q31_t)0x6dbcf7cb, (q31_t)0xd33bd427, (q31_t)0x6db42cb6, (q31_t)0xd332d9f7, + (q31_t)0x6dab5fdf, (q31_t)0xd329e181, (q31_t)0x6da29144, (q31_t)0xd320eac6, + (q31_t)0x6d99c0e7, (q31_t)0xd317f5c6, (q31_t)0x6d90eec8, (q31_t)0xd30f0280, + (q31_t)0x6d881ae8, (q31_t)0xd30610f7, (q31_t)0x6d7f4545, (q31_t)0xd2fd2129, + (q31_t)0x6d766de2, (q31_t)0xd2f43318, (q31_t)0x6d6d94bf, (q31_t)0xd2eb46c3, + (q31_t)0x6d64b9da, (q31_t)0xd2e25c2b, (q31_t)0x6d5bdd36, (q31_t)0xd2d97350, + (q31_t)0x6d52fed2, (q31_t)0xd2d08c33, (q31_t)0x6d4a1eaf, (q31_t)0xd2c7a6d4, + (q31_t)0x6d413ccd, (q31_t)0xd2bec333, (q31_t)0x6d38592c, (q31_t)0xd2b5e151, + (q31_t)0x6d2f73cd, (q31_t)0xd2ad012e, (q31_t)0x6d268cb0, (q31_t)0xd2a422ca, + (q31_t)0x6d1da3d5, (q31_t)0xd29b4626, (q31_t)0x6d14b93d, (q31_t)0xd2926b41, + (q31_t)0x6d0bcce8, (q31_t)0xd289921e, (q31_t)0x6d02ded7, (q31_t)0xd280babb, + (q31_t)0x6cf9ef09, (q31_t)0xd277e518, (q31_t)0x6cf0fd80, (q31_t)0xd26f1138, + (q31_t)0x6ce80a3a, (q31_t)0xd2663f19, (q31_t)0x6cdf153a, (q31_t)0xd25d6ebc, + (q31_t)0x6cd61e7f, (q31_t)0xd254a021, (q31_t)0x6ccd2609, (q31_t)0xd24bd34a, + (q31_t)0x6cc42bd9, (q31_t)0xd2430835, (q31_t)0x6cbb2fef, (q31_t)0xd23a3ee4, + (q31_t)0x6cb2324c, (q31_t)0xd2317756, (q31_t)0x6ca932ef, (q31_t)0xd228b18d, + (q31_t)0x6ca031da, (q31_t)0xd21fed88, (q31_t)0x6c972f0d, (q31_t)0xd2172b48, + (q31_t)0x6c8e2a87, (q31_t)0xd20e6acc, (q31_t)0x6c85244a, (q31_t)0xd205ac17, + (q31_t)0x6c7c1c55, (q31_t)0xd1fcef27, (q31_t)0x6c7312a9, (q31_t)0xd1f433fd, + (q31_t)0x6c6a0746, (q31_t)0xd1eb7a9a, (q31_t)0x6c60fa2d, (q31_t)0xd1e2c2fd, + (q31_t)0x6c57eb5e, (q31_t)0xd1da0d28, (q31_t)0x6c4edada, (q31_t)0xd1d1591a, + (q31_t)0x6c45c8a0, (q31_t)0xd1c8a6d4, (q31_t)0x6c3cb4b1, (q31_t)0xd1bff656, + (q31_t)0x6c339f0e, (q31_t)0xd1b747a0, (q31_t)0x6c2a87b6, (q31_t)0xd1ae9ab4, + (q31_t)0x6c216eaa, (q31_t)0xd1a5ef90, (q31_t)0x6c1853eb, (q31_t)0xd19d4636, + (q31_t)0x6c0f3779, (q31_t)0xd1949ea6, (q31_t)0x6c061953, (q31_t)0xd18bf8e0, + (q31_t)0x6bfcf97c, (q31_t)0xd18354e4, (q31_t)0x6bf3d7f2, (q31_t)0xd17ab2b3, + (q31_t)0x6beab4b6, (q31_t)0xd172124d, (q31_t)0x6be18fc9, (q31_t)0xd16973b3, + (q31_t)0x6bd8692b, (q31_t)0xd160d6e5, (q31_t)0x6bcf40dc, (q31_t)0xd1583be2, + (q31_t)0x6bc616dd, (q31_t)0xd14fa2ad, (q31_t)0x6bbceb2d, (q31_t)0xd1470b44, + (q31_t)0x6bb3bdce, (q31_t)0xd13e75a8, (q31_t)0x6baa8ec0, (q31_t)0xd135e1d9, + (q31_t)0x6ba15e03, (q31_t)0xd12d4fd9, (q31_t)0x6b982b97, (q31_t)0xd124bfa6, + (q31_t)0x6b8ef77d, (q31_t)0xd11c3142, (q31_t)0x6b85c1b5, (q31_t)0xd113a4ad, + (q31_t)0x6b7c8a3f, (q31_t)0xd10b19e7, (q31_t)0x6b73511c, (q31_t)0xd10290f0, + (q31_t)0x6b6a164d, (q31_t)0xd0fa09c9, (q31_t)0x6b60d9d0, (q31_t)0xd0f18472, + (q31_t)0x6b579ba8, (q31_t)0xd0e900ec, (q31_t)0x6b4e5bd4, (q31_t)0xd0e07f36, + (q31_t)0x6b451a55, (q31_t)0xd0d7ff51, (q31_t)0x6b3bd72a, (q31_t)0xd0cf813e, + (q31_t)0x6b329255, (q31_t)0xd0c704fd, (q31_t)0x6b294bd5, (q31_t)0xd0be8a8d, + (q31_t)0x6b2003ac, (q31_t)0xd0b611f1, (q31_t)0x6b16b9d9, (q31_t)0xd0ad9b26, + (q31_t)0x6b0d6e5c, (q31_t)0xd0a5262f, (q31_t)0x6b042137, (q31_t)0xd09cb30b, + (q31_t)0x6afad269, (q31_t)0xd09441bb, (q31_t)0x6af181f3, (q31_t)0xd08bd23f, + (q31_t)0x6ae82fd5, (q31_t)0xd0836497, (q31_t)0x6adedc10, (q31_t)0xd07af8c4, + (q31_t)0x6ad586a3, (q31_t)0xd0728ec6, (q31_t)0x6acc2f90, (q31_t)0xd06a269d, + (q31_t)0x6ac2d6d6, (q31_t)0xd061c04a, (q31_t)0x6ab97c77, (q31_t)0xd0595bcd, + (q31_t)0x6ab02071, (q31_t)0xd050f926, (q31_t)0x6aa6c2c6, (q31_t)0xd0489856, + (q31_t)0x6a9d6377, (q31_t)0xd040395d, (q31_t)0x6a940283, (q31_t)0xd037dc3b, + (q31_t)0x6a8a9fea, (q31_t)0xd02f80f1, (q31_t)0x6a813bae, (q31_t)0xd027277e, + (q31_t)0x6a77d5ce, (q31_t)0xd01ecfe4, (q31_t)0x6a6e6e4b, (q31_t)0xd0167a22, + (q31_t)0x6a650525, (q31_t)0xd00e2639, (q31_t)0x6a5b9a5d, (q31_t)0xd005d42a, + (q31_t)0x6a522df3, (q31_t)0xcffd83f4, (q31_t)0x6a48bfe7, (q31_t)0xcff53597, + (q31_t)0x6a3f503a, (q31_t)0xcfece915, (q31_t)0x6a35deeb, (q31_t)0xcfe49e6d, + (q31_t)0x6a2c6bfd, (q31_t)0xcfdc55a1, (q31_t)0x6a22f76e, (q31_t)0xcfd40eaf, + (q31_t)0x6a19813f, (q31_t)0xcfcbc999, (q31_t)0x6a100970, (q31_t)0xcfc3865e, + (q31_t)0x6a069003, (q31_t)0xcfbb4500, (q31_t)0x69fd14f6, (q31_t)0xcfb3057d, + (q31_t)0x69f3984c, (q31_t)0xcfaac7d8, (q31_t)0x69ea1a03, (q31_t)0xcfa28c10, + (q31_t)0x69e09a1c, (q31_t)0xcf9a5225, (q31_t)0x69d71899, (q31_t)0xcf921a17, + (q31_t)0x69cd9578, (q31_t)0xcf89e3e8, (q31_t)0x69c410ba, (q31_t)0xcf81af97, + (q31_t)0x69ba8a61, (q31_t)0xcf797d24, (q31_t)0x69b1026c, (q31_t)0xcf714c91, + (q31_t)0x69a778db, (q31_t)0xcf691ddd, (q31_t)0x699dedaf, (q31_t)0xcf60f108, + (q31_t)0x699460e8, (q31_t)0xcf58c613, (q31_t)0x698ad287, (q31_t)0xcf509cfe, + (q31_t)0x6981428c, (q31_t)0xcf4875ca, (q31_t)0x6977b0f7, (q31_t)0xcf405077, + (q31_t)0x696e1dc9, (q31_t)0xcf382d05, (q31_t)0x69648902, (q31_t)0xcf300b74, + (q31_t)0x695af2a3, (q31_t)0xcf27ebc5, (q31_t)0x69515aab, (q31_t)0xcf1fcdf8, + (q31_t)0x6947c11c, (q31_t)0xcf17b20d, (q31_t)0x693e25f5, (q31_t)0xcf0f9805, + (q31_t)0x69348937, (q31_t)0xcf077fe1, (q31_t)0x692aeae3, (q31_t)0xceff699f, + (q31_t)0x69214af8, (q31_t)0xcef75541, (q31_t)0x6917a977, (q31_t)0xceef42c7, + (q31_t)0x690e0661, (q31_t)0xcee73231, (q31_t)0x690461b5, (q31_t)0xcedf2380, + (q31_t)0x68fabb75, (q31_t)0xced716b4, (q31_t)0x68f113a0, (q31_t)0xcecf0bcd, + (q31_t)0x68e76a37, (q31_t)0xcec702cb, (q31_t)0x68ddbf3b, (q31_t)0xcebefbb0, + (q31_t)0x68d412ab, (q31_t)0xceb6f67a, (q31_t)0x68ca6488, (q31_t)0xceaef32b, + (q31_t)0x68c0b4d2, (q31_t)0xcea6f1c2, (q31_t)0x68b7038b, (q31_t)0xce9ef241, + (q31_t)0x68ad50b1, (q31_t)0xce96f4a7, (q31_t)0x68a39c46, (q31_t)0xce8ef8f4, + (q31_t)0x6899e64a, (q31_t)0xce86ff2a, (q31_t)0x68902ebd, (q31_t)0xce7f0748, + (q31_t)0x688675a0, (q31_t)0xce77114e, (q31_t)0x687cbaf3, (q31_t)0xce6f1d3d, + (q31_t)0x6872feb6, (q31_t)0xce672b16, (q31_t)0x686940ea, (q31_t)0xce5f3ad8, + (q31_t)0x685f8190, (q31_t)0xce574c84, (q31_t)0x6855c0a6, (q31_t)0xce4f6019, + (q31_t)0x684bfe2f, (q31_t)0xce47759a, (q31_t)0x68423a2a, (q31_t)0xce3f8d05, + (q31_t)0x68387498, (q31_t)0xce37a65b, (q31_t)0x682ead78, (q31_t)0xce2fc19c, + (q31_t)0x6824e4cc, (q31_t)0xce27dec9, (q31_t)0x681b1a94, (q31_t)0xce1ffde2, + (q31_t)0x68114ed0, (q31_t)0xce181ee8, (q31_t)0x68078181, (q31_t)0xce1041d9, + (q31_t)0x67fdb2a7, (q31_t)0xce0866b8, (q31_t)0x67f3e241, (q31_t)0xce008d84, + (q31_t)0x67ea1052, (q31_t)0xcdf8b63d, (q31_t)0x67e03cd8, (q31_t)0xcdf0e0e4, + (q31_t)0x67d667d5, (q31_t)0xcde90d79, (q31_t)0x67cc9149, (q31_t)0xcde13bfd, + (q31_t)0x67c2b934, (q31_t)0xcdd96c6f, (q31_t)0x67b8df97, (q31_t)0xcdd19ed0, + (q31_t)0x67af0472, (q31_t)0xcdc9d320, (q31_t)0x67a527c4, (q31_t)0xcdc20960, + (q31_t)0x679b4990, (q31_t)0xcdba4190, (q31_t)0x679169d5, (q31_t)0xcdb27bb0, + (q31_t)0x67878893, (q31_t)0xcdaab7c0, (q31_t)0x677da5cb, (q31_t)0xcda2f5c2, + (q31_t)0x6773c17d, (q31_t)0xcd9b35b4, (q31_t)0x6769dbaa, (q31_t)0xcd937798, + (q31_t)0x675ff452, (q31_t)0xcd8bbb6d, (q31_t)0x67560b76, (q31_t)0xcd840134, + (q31_t)0x674c2115, (q31_t)0xcd7c48ee, (q31_t)0x67423530, (q31_t)0xcd74929a, + (q31_t)0x673847c8, (q31_t)0xcd6cde39, (q31_t)0x672e58dc, (q31_t)0xcd652bcb, + (q31_t)0x6724686e, (q31_t)0xcd5d7b50, (q31_t)0x671a767e, (q31_t)0xcd55ccca, + (q31_t)0x6710830c, (q31_t)0xcd4e2037, (q31_t)0x67068e18, (q31_t)0xcd467599, + (q31_t)0x66fc97a3, (q31_t)0xcd3eccef, (q31_t)0x66f29fad, (q31_t)0xcd37263a, + (q31_t)0x66e8a637, (q31_t)0xcd2f817b, (q31_t)0x66deab41, (q31_t)0xcd27deb0, + (q31_t)0x66d4aecb, (q31_t)0xcd203ddc, (q31_t)0x66cab0d6, (q31_t)0xcd189efe, + (q31_t)0x66c0b162, (q31_t)0xcd110216, (q31_t)0x66b6b070, (q31_t)0xcd096725, + (q31_t)0x66acadff, (q31_t)0xcd01ce2b, (q31_t)0x66a2aa11, (q31_t)0xccfa3729, + (q31_t)0x6698a4a6, (q31_t)0xccf2a21d, (q31_t)0x668e9dbd, (q31_t)0xcceb0f0a, + (q31_t)0x66849558, (q31_t)0xcce37def, (q31_t)0x667a8b77, (q31_t)0xccdbeecc, + (q31_t)0x6670801a, (q31_t)0xccd461a2, (q31_t)0x66667342, (q31_t)0xccccd671, + (q31_t)0x665c64ef, (q31_t)0xccc54d3a, (q31_t)0x66525521, (q31_t)0xccbdc5fc, + (q31_t)0x664843d9, (q31_t)0xccb640b8, (q31_t)0x663e3117, (q31_t)0xccaebd6e, + (q31_t)0x66341cdb, (q31_t)0xcca73c1e, (q31_t)0x662a0727, (q31_t)0xcc9fbcca, + (q31_t)0x661feffa, (q31_t)0xcc983f70, (q31_t)0x6615d754, (q31_t)0xcc90c412, + (q31_t)0x660bbd37, (q31_t)0xcc894aaf, (q31_t)0x6601a1a2, (q31_t)0xcc81d349, + (q31_t)0x65f78497, (q31_t)0xcc7a5dde, (q31_t)0x65ed6614, (q31_t)0xcc72ea70, + (q31_t)0x65e3461b, (q31_t)0xcc6b78ff, (q31_t)0x65d924ac, (q31_t)0xcc64098b, + (q31_t)0x65cf01c8, (q31_t)0xcc5c9c14, (q31_t)0x65c4dd6e, (q31_t)0xcc55309b, + (q31_t)0x65bab7a0, (q31_t)0xcc4dc720, (q31_t)0x65b0905d, (q31_t)0xcc465fa3, + (q31_t)0x65a667a7, (q31_t)0xcc3efa25, (q31_t)0x659c3d7c, (q31_t)0xcc3796a5, + (q31_t)0x659211df, (q31_t)0xcc303524, (q31_t)0x6587e4cf, (q31_t)0xcc28d5a3, + (q31_t)0x657db64c, (q31_t)0xcc217822, (q31_t)0x65738657, (q31_t)0xcc1a1ca0, + (q31_t)0x656954f1, (q31_t)0xcc12c31f, (q31_t)0x655f2219, (q31_t)0xcc0b6b9e, + (q31_t)0x6554edd1, (q31_t)0xcc04161e, (q31_t)0x654ab818, (q31_t)0xcbfcc29f, + (q31_t)0x654080ef, (q31_t)0xcbf57121, (q31_t)0x65364857, (q31_t)0xcbee21a5, + (q31_t)0x652c0e4f, (q31_t)0xcbe6d42b, (q31_t)0x6521d2d8, (q31_t)0xcbdf88b3, + (q31_t)0x651795f3, (q31_t)0xcbd83f3d, (q31_t)0x650d57a0, (q31_t)0xcbd0f7ca, + (q31_t)0x650317df, (q31_t)0xcbc9b25a, (q31_t)0x64f8d6b0, (q31_t)0xcbc26eee, + (q31_t)0x64ee9415, (q31_t)0xcbbb2d85, (q31_t)0x64e4500e, (q31_t)0xcbb3ee20, + (q31_t)0x64da0a9a, (q31_t)0xcbacb0bf, (q31_t)0x64cfc3ba, (q31_t)0xcba57563, + (q31_t)0x64c57b6f, (q31_t)0xcb9e3c0b, (q31_t)0x64bb31ba, (q31_t)0xcb9704b9, + (q31_t)0x64b0e699, (q31_t)0xcb8fcf6b, (q31_t)0x64a69a0f, (q31_t)0xcb889c23, + (q31_t)0x649c4c1b, (q31_t)0xcb816ae1, (q31_t)0x6491fcbe, (q31_t)0xcb7a3ba5, + (q31_t)0x6487abf7, (q31_t)0xcb730e70, (q31_t)0x647d59c8, (q31_t)0xcb6be341, + (q31_t)0x64730631, (q31_t)0xcb64ba19, (q31_t)0x6468b132, (q31_t)0xcb5d92f8, + (q31_t)0x645e5acc, (q31_t)0xcb566ddf, (q31_t)0x645402ff, (q31_t)0xcb4f4acd, + (q31_t)0x6449a9cc, (q31_t)0xcb4829c4, (q31_t)0x643f4f32, (q31_t)0xcb410ac3, + (q31_t)0x6434f332, (q31_t)0xcb39edca, (q31_t)0x642a95ce, (q31_t)0xcb32d2da, + (q31_t)0x64203704, (q31_t)0xcb2bb9f4, (q31_t)0x6415d6d5, (q31_t)0xcb24a316, + (q31_t)0x640b7543, (q31_t)0xcb1d8e43, (q31_t)0x6401124d, (q31_t)0xcb167b79, + (q31_t)0x63f6adf3, (q31_t)0xcb0f6aba, (q31_t)0x63ec4837, (q31_t)0xcb085c05, + (q31_t)0x63e1e117, (q31_t)0xcb014f5b, (q31_t)0x63d77896, (q31_t)0xcafa44bc, + (q31_t)0x63cd0eb3, (q31_t)0xcaf33c28, (q31_t)0x63c2a36f, (q31_t)0xcaec35a0, + (q31_t)0x63b836ca, (q31_t)0xcae53123, (q31_t)0x63adc8c4, (q31_t)0xcade2eb3, + (q31_t)0x63a3595e, (q31_t)0xcad72e4f, (q31_t)0x6398e898, (q31_t)0xcad02ff8, + (q31_t)0x638e7673, (q31_t)0xcac933ae, (q31_t)0x638402ef, (q31_t)0xcac23971, + (q31_t)0x63798e0d, (q31_t)0xcabb4141, (q31_t)0x636f17cc, (q31_t)0xcab44b1f, + (q31_t)0x6364a02e, (q31_t)0xcaad570c, (q31_t)0x635a2733, (q31_t)0xcaa66506, + (q31_t)0x634facda, (q31_t)0xca9f750f, (q31_t)0x63453125, (q31_t)0xca988727, + (q31_t)0x633ab414, (q31_t)0xca919b4e, (q31_t)0x633035a7, (q31_t)0xca8ab184, + (q31_t)0x6325b5df, (q31_t)0xca83c9ca, (q31_t)0x631b34bc, (q31_t)0xca7ce420, + (q31_t)0x6310b23e, (q31_t)0xca760086, (q31_t)0x63062e67, (q31_t)0xca6f1efc, + (q31_t)0x62fba936, (q31_t)0xca683f83, (q31_t)0x62f122ab, (q31_t)0xca61621b, + (q31_t)0x62e69ac8, (q31_t)0xca5a86c4, (q31_t)0x62dc118c, (q31_t)0xca53ad7e, + (q31_t)0x62d186f8, (q31_t)0xca4cd64b, (q31_t)0x62c6fb0c, (q31_t)0xca460129, + (q31_t)0x62bc6dca, (q31_t)0xca3f2e19, (q31_t)0x62b1df30, (q31_t)0xca385d1d, + (q31_t)0x62a74f40, (q31_t)0xca318e32, (q31_t)0x629cbdfa, (q31_t)0xca2ac15b, + (q31_t)0x62922b5e, (q31_t)0xca23f698, (q31_t)0x6287976e, (q31_t)0xca1d2de7, + (q31_t)0x627d0228, (q31_t)0xca16674b, (q31_t)0x62726b8e, (q31_t)0xca0fa2c3, + (q31_t)0x6267d3a0, (q31_t)0xca08e04f, (q31_t)0x625d3a5e, (q31_t)0xca021fef, + (q31_t)0x62529fca, (q31_t)0xc9fb61a5, (q31_t)0x624803e2, (q31_t)0xc9f4a570, + (q31_t)0x623d66a8, (q31_t)0xc9edeb50, (q31_t)0x6232c81c, (q31_t)0xc9e73346, + (q31_t)0x6228283f, (q31_t)0xc9e07d51, (q31_t)0x621d8711, (q31_t)0xc9d9c973, + (q31_t)0x6212e492, (q31_t)0xc9d317ab, (q31_t)0x620840c2, (q31_t)0xc9cc67fa, + (q31_t)0x61fd9ba3, (q31_t)0xc9c5ba60, (q31_t)0x61f2f534, (q31_t)0xc9bf0edd, + (q31_t)0x61e84d76, (q31_t)0xc9b86572, (q31_t)0x61dda46a, (q31_t)0xc9b1be1e, + (q31_t)0x61d2fa0f, (q31_t)0xc9ab18e3, (q31_t)0x61c84e67, (q31_t)0xc9a475bf, + (q31_t)0x61bda171, (q31_t)0xc99dd4b4, (q31_t)0x61b2f32e, (q31_t)0xc99735c2, + (q31_t)0x61a8439e, (q31_t)0xc99098e9, (q31_t)0x619d92c2, (q31_t)0xc989fe29, + (q31_t)0x6192e09b, (q31_t)0xc9836582, (q31_t)0x61882d28, (q31_t)0xc97ccef5, + (q31_t)0x617d786a, (q31_t)0xc9763a83, (q31_t)0x6172c262, (q31_t)0xc96fa82a, + (q31_t)0x61680b0f, (q31_t)0xc96917ec, (q31_t)0x615d5273, (q31_t)0xc96289c9, + (q31_t)0x6152988d, (q31_t)0xc95bfdc1, (q31_t)0x6147dd5f, (q31_t)0xc95573d4, + (q31_t)0x613d20e8, (q31_t)0xc94eec03, (q31_t)0x61326329, (q31_t)0xc948664d, + (q31_t)0x6127a423, (q31_t)0xc941e2b4, (q31_t)0x611ce3d5, (q31_t)0xc93b6137, + (q31_t)0x61122240, (q31_t)0xc934e1d6, (q31_t)0x61075f65, (q31_t)0xc92e6492, + (q31_t)0x60fc9b44, (q31_t)0xc927e96b, (q31_t)0x60f1d5de, (q31_t)0xc9217062, + (q31_t)0x60e70f32, (q31_t)0xc91af976, (q31_t)0x60dc4742, (q31_t)0xc91484a8, + (q31_t)0x60d17e0d, (q31_t)0xc90e11f7, (q31_t)0x60c6b395, (q31_t)0xc907a166, + (q31_t)0x60bbe7d8, (q31_t)0xc90132f2, (q31_t)0x60b11ad9, (q31_t)0xc8fac69e, + (q31_t)0x60a64c97, (q31_t)0xc8f45c68, (q31_t)0x609b7d13, (q31_t)0xc8edf452, + (q31_t)0x6090ac4d, (q31_t)0xc8e78e5b, (q31_t)0x6085da46, (q31_t)0xc8e12a84, + (q31_t)0x607b06fe, (q31_t)0xc8dac8cd, (q31_t)0x60703275, (q31_t)0xc8d46936, + (q31_t)0x60655cac, (q31_t)0xc8ce0bc0, (q31_t)0x605a85a3, (q31_t)0xc8c7b06b, + (q31_t)0x604fad5b, (q31_t)0xc8c15736, (q31_t)0x6044d3d4, (q31_t)0xc8bb0023, + (q31_t)0x6039f90f, (q31_t)0xc8b4ab32, (q31_t)0x602f1d0b, (q31_t)0xc8ae5862, + (q31_t)0x60243fca, (q31_t)0xc8a807b4, (q31_t)0x6019614c, (q31_t)0xc8a1b928, + (q31_t)0x600e8190, (q31_t)0xc89b6cbf, (q31_t)0x6003a099, (q31_t)0xc8952278, + (q31_t)0x5ff8be65, (q31_t)0xc88eda54, (q31_t)0x5feddaf6, (q31_t)0xc8889454, + (q31_t)0x5fe2f64c, (q31_t)0xc8825077, (q31_t)0x5fd81067, (q31_t)0xc87c0ebd, + (q31_t)0x5fcd2948, (q31_t)0xc875cf28, (q31_t)0x5fc240ef, (q31_t)0xc86f91b7, + (q31_t)0x5fb7575c, (q31_t)0xc869566a, (q31_t)0x5fac6c91, (q31_t)0xc8631d42, + (q31_t)0x5fa1808c, (q31_t)0xc85ce63e, (q31_t)0x5f969350, (q31_t)0xc856b160, + (q31_t)0x5f8ba4dc, (q31_t)0xc8507ea7, (q31_t)0x5f80b531, (q31_t)0xc84a4e14, + (q31_t)0x5f75c44e, (q31_t)0xc8441fa6, (q31_t)0x5f6ad235, (q31_t)0xc83df35f, + (q31_t)0x5f5fdee6, (q31_t)0xc837c93e, (q31_t)0x5f54ea62, (q31_t)0xc831a143, + (q31_t)0x5f49f4a8, (q31_t)0xc82b7b70, (q31_t)0x5f3efdb9, (q31_t)0xc82557c3, + (q31_t)0x5f340596, (q31_t)0xc81f363d, (q31_t)0x5f290c3f, (q31_t)0xc81916df, + (q31_t)0x5f1e11b5, (q31_t)0xc812f9a9, (q31_t)0x5f1315f7, (q31_t)0xc80cde9b, + (q31_t)0x5f081907, (q31_t)0xc806c5b5, (q31_t)0x5efd1ae4, (q31_t)0xc800aef7, + (q31_t)0x5ef21b90, (q31_t)0xc7fa9a62, (q31_t)0x5ee71b0a, (q31_t)0xc7f487f6, + (q31_t)0x5edc1953, (q31_t)0xc7ee77b3, (q31_t)0x5ed1166b, (q31_t)0xc7e8699a, + (q31_t)0x5ec61254, (q31_t)0xc7e25daa, (q31_t)0x5ebb0d0d, (q31_t)0xc7dc53e3, + (q31_t)0x5eb00696, (q31_t)0xc7d64c47, (q31_t)0x5ea4fef0, (q31_t)0xc7d046d6, + (q31_t)0x5e99f61d, (q31_t)0xc7ca438f, (q31_t)0x5e8eec1b, (q31_t)0xc7c44272, + (q31_t)0x5e83e0eb, (q31_t)0xc7be4381, (q31_t)0x5e78d48e, (q31_t)0xc7b846ba, + (q31_t)0x5e6dc705, (q31_t)0xc7b24c20, (q31_t)0x5e62b84f, (q31_t)0xc7ac53b1, + (q31_t)0x5e57a86d, (q31_t)0xc7a65d6e, (q31_t)0x5e4c9760, (q31_t)0xc7a06957, + (q31_t)0x5e418528, (q31_t)0xc79a776c, (q31_t)0x5e3671c5, (q31_t)0xc79487ae, + (q31_t)0x5e2b5d38, (q31_t)0xc78e9a1d, (q31_t)0x5e204781, (q31_t)0xc788aeb9, + (q31_t)0x5e1530a1, (q31_t)0xc782c582, (q31_t)0x5e0a1898, (q31_t)0xc77cde79, + (q31_t)0x5dfeff67, (q31_t)0xc776f99d, (q31_t)0x5df3e50d, (q31_t)0xc77116f0, + (q31_t)0x5de8c98c, (q31_t)0xc76b3671, (q31_t)0x5dddace4, (q31_t)0xc7655820, + (q31_t)0x5dd28f15, (q31_t)0xc75f7bfe, (q31_t)0x5dc7701f, (q31_t)0xc759a20a, + (q31_t)0x5dbc5004, (q31_t)0xc753ca46, (q31_t)0x5db12ec3, (q31_t)0xc74df4b1, + (q31_t)0x5da60c5d, (q31_t)0xc748214c, (q31_t)0x5d9ae8d2, (q31_t)0xc7425016, + (q31_t)0x5d8fc424, (q31_t)0xc73c8111, (q31_t)0x5d849e51, (q31_t)0xc736b43c, + (q31_t)0x5d79775c, (q31_t)0xc730e997, (q31_t)0x5d6e4f43, (q31_t)0xc72b2123, + (q31_t)0x5d632608, (q31_t)0xc7255ae0, (q31_t)0x5d57fbaa, (q31_t)0xc71f96ce, + (q31_t)0x5d4cd02c, (q31_t)0xc719d4ed, (q31_t)0x5d41a38c, (q31_t)0xc714153e, + (q31_t)0x5d3675cb, (q31_t)0xc70e57c0, (q31_t)0x5d2b46ea, (q31_t)0xc7089c75, + (q31_t)0x5d2016e9, (q31_t)0xc702e35c, (q31_t)0x5d14e5c9, (q31_t)0xc6fd2c75, + (q31_t)0x5d09b389, (q31_t)0xc6f777c1, (q31_t)0x5cfe802b, (q31_t)0xc6f1c540, + (q31_t)0x5cf34baf, (q31_t)0xc6ec14f2, (q31_t)0x5ce81615, (q31_t)0xc6e666d7, + (q31_t)0x5cdcdf5e, (q31_t)0xc6e0baf0, (q31_t)0x5cd1a78a, (q31_t)0xc6db113d, + (q31_t)0x5cc66e99, (q31_t)0xc6d569be, (q31_t)0x5cbb348d, (q31_t)0xc6cfc472, + (q31_t)0x5caff965, (q31_t)0xc6ca215c, (q31_t)0x5ca4bd21, (q31_t)0xc6c4807a, + (q31_t)0x5c997fc4, (q31_t)0xc6bee1cd, (q31_t)0x5c8e414b, (q31_t)0xc6b94554, + (q31_t)0x5c8301b9, (q31_t)0xc6b3ab12, (q31_t)0x5c77c10e, (q31_t)0xc6ae1304, + (q31_t)0x5c6c7f4a, (q31_t)0xc6a87d2d, (q31_t)0x5c613c6d, (q31_t)0xc6a2e98b, + (q31_t)0x5c55f878, (q31_t)0xc69d5820, (q31_t)0x5c4ab36b, (q31_t)0xc697c8eb, + (q31_t)0x5c3f6d47, (q31_t)0xc6923bec, (q31_t)0x5c34260c, (q31_t)0xc68cb124, + (q31_t)0x5c28ddbb, (q31_t)0xc6872894, (q31_t)0x5c1d9454, (q31_t)0xc681a23a, + (q31_t)0x5c1249d8, (q31_t)0xc67c1e18, (q31_t)0x5c06fe46, (q31_t)0xc6769c2e, + (q31_t)0x5bfbb1a0, (q31_t)0xc6711c7b, (q31_t)0x5bf063e6, (q31_t)0xc66b9f01, + (q31_t)0x5be51518, (q31_t)0xc66623be, (q31_t)0x5bd9c537, (q31_t)0xc660aab5, + (q31_t)0x5bce7442, (q31_t)0xc65b33e4, (q31_t)0x5bc3223c, (q31_t)0xc655bf4c, + (q31_t)0x5bb7cf23, (q31_t)0xc6504ced, (q31_t)0x5bac7af9, (q31_t)0xc64adcc7, + (q31_t)0x5ba125bd, (q31_t)0xc6456edb, (q31_t)0x5b95cf71, (q31_t)0xc6400329, + (q31_t)0x5b8a7815, (q31_t)0xc63a99b1, (q31_t)0x5b7f1fa9, (q31_t)0xc6353273, + (q31_t)0x5b73c62d, (q31_t)0xc62fcd6f, (q31_t)0x5b686ba3, (q31_t)0xc62a6aa6, + (q31_t)0x5b5d100a, (q31_t)0xc6250a18, (q31_t)0x5b51b363, (q31_t)0xc61fabc4, + (q31_t)0x5b4655ae, (q31_t)0xc61a4fac, (q31_t)0x5b3af6ec, (q31_t)0xc614f5cf, + (q31_t)0x5b2f971e, (q31_t)0xc60f9e2e, (q31_t)0x5b243643, (q31_t)0xc60a48c9, + (q31_t)0x5b18d45c, (q31_t)0xc604f5a0, (q31_t)0x5b0d716a, (q31_t)0xc5ffa4b3, + (q31_t)0x5b020d6c, (q31_t)0xc5fa5603, (q31_t)0x5af6a865, (q31_t)0xc5f5098f, + (q31_t)0x5aeb4253, (q31_t)0xc5efbf58, (q31_t)0x5adfdb37, (q31_t)0xc5ea775e, + (q31_t)0x5ad47312, (q31_t)0xc5e531a1, (q31_t)0x5ac909e5, (q31_t)0xc5dfee22, + (q31_t)0x5abd9faf, (q31_t)0xc5daace1, (q31_t)0x5ab23471, (q31_t)0xc5d56ddd, + (q31_t)0x5aa6c82b, (q31_t)0xc5d03118, (q31_t)0x5a9b5adf, (q31_t)0xc5caf690, + (q31_t)0x5a8fec8c, (q31_t)0xc5c5be47, (q31_t)0x5a847d33, (q31_t)0xc5c0883d, + (q31_t)0x5a790cd4, (q31_t)0xc5bb5472, (q31_t)0x5a6d9b70, (q31_t)0xc5b622e6, + (q31_t)0x5a622907, (q31_t)0xc5b0f399, (q31_t)0x5a56b599, (q31_t)0xc5abc68c, + (q31_t)0x5a4b4128, (q31_t)0xc5a69bbe, (q31_t)0x5a3fcbb3, (q31_t)0xc5a17330, + (q31_t)0x5a34553b, (q31_t)0xc59c4ce3, (q31_t)0x5a28ddc0, (q31_t)0xc59728d5, + (q31_t)0x5a1d6544, (q31_t)0xc5920708, (q31_t)0x5a11ebc5, (q31_t)0xc58ce77c, + (q31_t)0x5a067145, (q31_t)0xc587ca31, (q31_t)0x59faf5c5, (q31_t)0xc582af26, + (q31_t)0x59ef7944, (q31_t)0xc57d965d, (q31_t)0x59e3fbc3, (q31_t)0xc5787fd6, + (q31_t)0x59d87d42, (q31_t)0xc5736b90, (q31_t)0x59ccfdc2, (q31_t)0xc56e598c, + (q31_t)0x59c17d44, (q31_t)0xc56949ca, (q31_t)0x59b5fbc8, (q31_t)0xc5643c4a, + (q31_t)0x59aa794d, (q31_t)0xc55f310d, (q31_t)0x599ef5d6, (q31_t)0xc55a2812, + (q31_t)0x59937161, (q31_t)0xc555215a, (q31_t)0x5987ebf0, (q31_t)0xc5501ce5, + (q31_t)0x597c6584, (q31_t)0xc54b1ab4, (q31_t)0x5970de1b, (q31_t)0xc5461ac6, + (q31_t)0x596555b8, (q31_t)0xc5411d1b, (q31_t)0x5959cc5a, (q31_t)0xc53c21b4, + (q31_t)0x594e4201, (q31_t)0xc5372891, (q31_t)0x5942b6af, (q31_t)0xc53231b3, + (q31_t)0x59372a64, (q31_t)0xc52d3d18, (q31_t)0x592b9d1f, (q31_t)0xc5284ac3, + (q31_t)0x59200ee3, (q31_t)0xc5235ab2, (q31_t)0x59147fae, (q31_t)0xc51e6ce6, + (q31_t)0x5908ef82, (q31_t)0xc519815f, (q31_t)0x58fd5e5f, (q31_t)0xc514981d, + (q31_t)0x58f1cc45, (q31_t)0xc50fb121, (q31_t)0x58e63935, (q31_t)0xc50acc6b, + (q31_t)0x58daa52f, (q31_t)0xc505e9fb, (q31_t)0x58cf1034, (q31_t)0xc50109d0, + (q31_t)0x58c37a44, (q31_t)0xc4fc2bec, (q31_t)0x58b7e35f, (q31_t)0xc4f7504e, + (q31_t)0x58ac4b87, (q31_t)0xc4f276f7, (q31_t)0x58a0b2bb, (q31_t)0xc4ed9fe7, + (q31_t)0x589518fc, (q31_t)0xc4e8cb1e, (q31_t)0x58897e4a, (q31_t)0xc4e3f89c, + (q31_t)0x587de2a7, (q31_t)0xc4df2862, (q31_t)0x58724611, (q31_t)0xc4da5a6f, + (q31_t)0x5866a88a, (q31_t)0xc4d58ec3, (q31_t)0x585b0a13, (q31_t)0xc4d0c560, + (q31_t)0x584f6aab, (q31_t)0xc4cbfe45, (q31_t)0x5843ca53, (q31_t)0xc4c73972, + (q31_t)0x5838290c, (q31_t)0xc4c276e8, (q31_t)0x582c86d5, (q31_t)0xc4bdb6a6, + (q31_t)0x5820e3b0, (q31_t)0xc4b8f8ad, (q31_t)0x58153f9d, (q31_t)0xc4b43cfd, + (q31_t)0x58099a9c, (q31_t)0xc4af8397, (q31_t)0x57fdf4ae, (q31_t)0xc4aacc7a, + (q31_t)0x57f24dd3, (q31_t)0xc4a617a6, (q31_t)0x57e6a60c, (q31_t)0xc4a1651c, + (q31_t)0x57dafd59, (q31_t)0xc49cb4dd, (q31_t)0x57cf53bb, (q31_t)0xc49806e7, + (q31_t)0x57c3a931, (q31_t)0xc4935b3c, (q31_t)0x57b7fdbd, (q31_t)0xc48eb1db, + (q31_t)0x57ac515f, (q31_t)0xc48a0ac4, (q31_t)0x57a0a417, (q31_t)0xc48565f9, + (q31_t)0x5794f5e6, (q31_t)0xc480c379, (q31_t)0x578946cc, (q31_t)0xc47c2344, + (q31_t)0x577d96ca, (q31_t)0xc477855a, (q31_t)0x5771e5e0, (q31_t)0xc472e9bc, + (q31_t)0x5766340f, (q31_t)0xc46e5069, (q31_t)0x575a8157, (q31_t)0xc469b963, + (q31_t)0x574ecdb8, (q31_t)0xc46524a9, (q31_t)0x57431933, (q31_t)0xc460923b, + (q31_t)0x573763c9, (q31_t)0xc45c0219, (q31_t)0x572bad7a, (q31_t)0xc4577444, + (q31_t)0x571ff646, (q31_t)0xc452e8bc, (q31_t)0x57143e2d, (q31_t)0xc44e5f80, + (q31_t)0x57088531, (q31_t)0xc449d892, (q31_t)0x56fccb51, (q31_t)0xc44553f2, + (q31_t)0x56f1108f, (q31_t)0xc440d19e, (q31_t)0x56e554ea, (q31_t)0xc43c5199, + (q31_t)0x56d99864, (q31_t)0xc437d3e1, (q31_t)0x56cddafb, (q31_t)0xc4335877, + (q31_t)0x56c21cb2, (q31_t)0xc42edf5c, (q31_t)0x56b65d88, (q31_t)0xc42a688f, + (q31_t)0x56aa9d7e, (q31_t)0xc425f410, (q31_t)0x569edc94, (q31_t)0xc42181e0, + (q31_t)0x56931acb, (q31_t)0xc41d11ff, (q31_t)0x56875823, (q31_t)0xc418a46d, + (q31_t)0x567b949d, (q31_t)0xc414392b, (q31_t)0x566fd039, (q31_t)0xc40fd037, + (q31_t)0x56640af7, (q31_t)0xc40b6994, (q31_t)0x565844d8, (q31_t)0xc4070540, + (q31_t)0x564c7ddd, (q31_t)0xc402a33c, (q31_t)0x5640b606, (q31_t)0xc3fe4388, + (q31_t)0x5634ed53, (q31_t)0xc3f9e624, (q31_t)0x562923c5, (q31_t)0xc3f58b10, + (q31_t)0x561d595d, (q31_t)0xc3f1324e, (q31_t)0x56118e1a, (q31_t)0xc3ecdbdc, + (q31_t)0x5605c1fd, (q31_t)0xc3e887bb, (q31_t)0x55f9f507, (q31_t)0xc3e435ea, + (q31_t)0x55ee2738, (q31_t)0xc3dfe66c, (q31_t)0x55e25890, (q31_t)0xc3db993e, + (q31_t)0x55d68911, (q31_t)0xc3d74e62, (q31_t)0x55cab8ba, (q31_t)0xc3d305d8, + (q31_t)0x55bee78c, (q31_t)0xc3cebfa0, (q31_t)0x55b31587, (q31_t)0xc3ca7bba, + (q31_t)0x55a742ac, (q31_t)0xc3c63a26, (q31_t)0x559b6efb, (q31_t)0xc3c1fae5, + (q31_t)0x558f9a76, (q31_t)0xc3bdbdf6, (q31_t)0x5583c51b, (q31_t)0xc3b9835a, + (q31_t)0x5577eeec, (q31_t)0xc3b54b11, (q31_t)0x556c17e9, (q31_t)0xc3b1151b, + (q31_t)0x55604013, (q31_t)0xc3ace178, (q31_t)0x5554676a, (q31_t)0xc3a8b028, + (q31_t)0x55488dee, (q31_t)0xc3a4812c, (q31_t)0x553cb3a0, (q31_t)0xc3a05484, + (q31_t)0x5530d881, (q31_t)0xc39c2a2f, (q31_t)0x5524fc90, (q31_t)0xc398022f, + (q31_t)0x55191fcf, (q31_t)0xc393dc82, (q31_t)0x550d423d, (q31_t)0xc38fb92a, + (q31_t)0x550163dc, (q31_t)0xc38b9827, (q31_t)0x54f584ac, (q31_t)0xc3877978, + (q31_t)0x54e9a4ac, (q31_t)0xc3835d1e, (q31_t)0x54ddc3de, (q31_t)0xc37f4319, + (q31_t)0x54d1e242, (q31_t)0xc37b2b6a, (q31_t)0x54c5ffd9, (q31_t)0xc377160f, + (q31_t)0x54ba1ca3, (q31_t)0xc373030a, (q31_t)0x54ae38a0, (q31_t)0xc36ef25b, + (q31_t)0x54a253d1, (q31_t)0xc36ae401, (q31_t)0x54966e36, (q31_t)0xc366d7fd, + (q31_t)0x548a87d1, (q31_t)0xc362ce50, (q31_t)0x547ea0a0, (q31_t)0xc35ec6f8, + (q31_t)0x5472b8a5, (q31_t)0xc35ac1f7, (q31_t)0x5466cfe1, (q31_t)0xc356bf4d, + (q31_t)0x545ae653, (q31_t)0xc352bef9, (q31_t)0x544efbfc, (q31_t)0xc34ec0fc, + (q31_t)0x544310dd, (q31_t)0xc34ac556, (q31_t)0x543724f5, (q31_t)0xc346cc07, + (q31_t)0x542b3846, (q31_t)0xc342d510, (q31_t)0x541f4ad1, (q31_t)0xc33ee070, + (q31_t)0x54135c94, (q31_t)0xc33aee27, (q31_t)0x54076d91, (q31_t)0xc336fe37, + (q31_t)0x53fb7dc9, (q31_t)0xc333109e, (q31_t)0x53ef8d3c, (q31_t)0xc32f255e, + (q31_t)0x53e39be9, (q31_t)0xc32b3c75, (q31_t)0x53d7a9d3, (q31_t)0xc32755e5, + (q31_t)0x53cbb6f8, (q31_t)0xc32371ae, (q31_t)0x53bfc35b, (q31_t)0xc31f8fcf, + (q31_t)0x53b3cefa, (q31_t)0xc31bb049, (q31_t)0x53a7d9d7, (q31_t)0xc317d31c, + (q31_t)0x539be3f2, (q31_t)0xc313f848, (q31_t)0x538fed4b, (q31_t)0xc3101fce, + (q31_t)0x5383f5e3, (q31_t)0xc30c49ad, (q31_t)0x5377fdbb, (q31_t)0xc30875e5, + (q31_t)0x536c04d2, (q31_t)0xc304a477, (q31_t)0x53600b2a, (q31_t)0xc300d563, + (q31_t)0x535410c3, (q31_t)0xc2fd08a9, (q31_t)0x5348159d, (q31_t)0xc2f93e4a, + (q31_t)0x533c19b8, (q31_t)0xc2f57644, (q31_t)0x53301d16, (q31_t)0xc2f1b099, + (q31_t)0x53241fb6, (q31_t)0xc2eded49, (q31_t)0x5318219a, (q31_t)0xc2ea2c53, + (q31_t)0x530c22c1, (q31_t)0xc2e66db8, (q31_t)0x5300232c, (q31_t)0xc2e2b178, + (q31_t)0x52f422db, (q31_t)0xc2def794, (q31_t)0x52e821cf, (q31_t)0xc2db400a, + (q31_t)0x52dc2009, (q31_t)0xc2d78add, (q31_t)0x52d01d89, (q31_t)0xc2d3d80a, + (q31_t)0x52c41a4f, (q31_t)0xc2d02794, (q31_t)0x52b8165b, (q31_t)0xc2cc7979, + (q31_t)0x52ac11af, (q31_t)0xc2c8cdbb, (q31_t)0x52a00c4b, (q31_t)0xc2c52459, + (q31_t)0x5294062f, (q31_t)0xc2c17d52, (q31_t)0x5287ff5b, (q31_t)0xc2bdd8a9, + (q31_t)0x527bf7d1, (q31_t)0xc2ba365c, (q31_t)0x526fef90, (q31_t)0xc2b6966c, + (q31_t)0x5263e699, (q31_t)0xc2b2f8d8, (q31_t)0x5257dced, (q31_t)0xc2af5da2, + (q31_t)0x524bd28c, (q31_t)0xc2abc4c9, (q31_t)0x523fc776, (q31_t)0xc2a82e4d, + (q31_t)0x5233bbac, (q31_t)0xc2a49a2e, (q31_t)0x5227af2e, (q31_t)0xc2a1086d, + (q31_t)0x521ba1fd, (q31_t)0xc29d790a, (q31_t)0x520f941a, (q31_t)0xc299ec05, + (q31_t)0x52038584, (q31_t)0xc296615d, (q31_t)0x51f7763c, (q31_t)0xc292d914, + (q31_t)0x51eb6643, (q31_t)0xc28f5329, (q31_t)0x51df5599, (q31_t)0xc28bcf9c, + (q31_t)0x51d3443f, (q31_t)0xc2884e6e, (q31_t)0x51c73235, (q31_t)0xc284cf9f, + (q31_t)0x51bb1f7c, (q31_t)0xc281532e, (q31_t)0x51af0c13, (q31_t)0xc27dd91c, + (q31_t)0x51a2f7fc, (q31_t)0xc27a616a, (q31_t)0x5196e337, (q31_t)0xc276ec16, + (q31_t)0x518acdc4, (q31_t)0xc2737922, (q31_t)0x517eb7a4, (q31_t)0xc270088e, + (q31_t)0x5172a0d7, (q31_t)0xc26c9a58, (q31_t)0x5166895f, (q31_t)0xc2692e83, + (q31_t)0x515a713a, (q31_t)0xc265c50e, (q31_t)0x514e586a, (q31_t)0xc2625df8, + (q31_t)0x51423ef0, (q31_t)0xc25ef943, (q31_t)0x513624cb, (q31_t)0xc25b96ee, + (q31_t)0x512a09fc, (q31_t)0xc25836f9, (q31_t)0x511dee84, (q31_t)0xc254d965, + (q31_t)0x5111d263, (q31_t)0xc2517e31, (q31_t)0x5105b599, (q31_t)0xc24e255e, + (q31_t)0x50f99827, (q31_t)0xc24aceed, (q31_t)0x50ed7a0e, (q31_t)0xc2477adc, + (q31_t)0x50e15b4e, (q31_t)0xc244292c, (q31_t)0x50d53be7, (q31_t)0xc240d9de, + (q31_t)0x50c91bda, (q31_t)0xc23d8cf1, (q31_t)0x50bcfb28, (q31_t)0xc23a4265, + (q31_t)0x50b0d9d0, (q31_t)0xc236fa3b, (q31_t)0x50a4b7d3, (q31_t)0xc233b473, + (q31_t)0x50989532, (q31_t)0xc230710d, (q31_t)0x508c71ee, (q31_t)0xc22d3009, + (q31_t)0x50804e06, (q31_t)0xc229f167, (q31_t)0x5074297b, (q31_t)0xc226b528, + (q31_t)0x5068044e, (q31_t)0xc2237b4b, (q31_t)0x505bde7f, (q31_t)0xc22043d0, + (q31_t)0x504fb80e, (q31_t)0xc21d0eb8, (q31_t)0x504390fd, (q31_t)0xc219dc03, + (q31_t)0x5037694b, (q31_t)0xc216abb1, (q31_t)0x502b40f8, (q31_t)0xc2137dc2, + (q31_t)0x501f1807, (q31_t)0xc2105236, (q31_t)0x5012ee76, (q31_t)0xc20d290d, + (q31_t)0x5006c446, (q31_t)0xc20a0248, (q31_t)0x4ffa9979, (q31_t)0xc206dde6, + (q31_t)0x4fee6e0d, (q31_t)0xc203bbe8, (q31_t)0x4fe24205, (q31_t)0xc2009c4e, + (q31_t)0x4fd6155f, (q31_t)0xc1fd7f17, (q31_t)0x4fc9e81e, (q31_t)0xc1fa6445, + (q31_t)0x4fbdba40, (q31_t)0xc1f74bd6, (q31_t)0x4fb18bc8, (q31_t)0xc1f435cc, + (q31_t)0x4fa55cb4, (q31_t)0xc1f12227, (q31_t)0x4f992d06, (q31_t)0xc1ee10e5, + (q31_t)0x4f8cfcbe, (q31_t)0xc1eb0209, (q31_t)0x4f80cbdc, (q31_t)0xc1e7f591, + (q31_t)0x4f749a61, (q31_t)0xc1e4eb7e, (q31_t)0x4f68684e, (q31_t)0xc1e1e3d0, + (q31_t)0x4f5c35a3, (q31_t)0xc1dede87, (q31_t)0x4f500260, (q31_t)0xc1dbdba3, + (q31_t)0x4f43ce86, (q31_t)0xc1d8db25, (q31_t)0x4f379a16, (q31_t)0xc1d5dd0c, + (q31_t)0x4f2b650f, (q31_t)0xc1d2e158, (q31_t)0x4f1f2f73, (q31_t)0xc1cfe80a, + (q31_t)0x4f12f941, (q31_t)0xc1ccf122, (q31_t)0x4f06c27a, (q31_t)0xc1c9fca0, + (q31_t)0x4efa8b20, (q31_t)0xc1c70a84, (q31_t)0x4eee5331, (q31_t)0xc1c41ace, + (q31_t)0x4ee21aaf, (q31_t)0xc1c12d7e, (q31_t)0x4ed5e19a, (q31_t)0xc1be4294, + (q31_t)0x4ec9a7f3, (q31_t)0xc1bb5a11, (q31_t)0x4ebd6db9, (q31_t)0xc1b873f5, + (q31_t)0x4eb132ef, (q31_t)0xc1b5903f, (q31_t)0x4ea4f793, (q31_t)0xc1b2aef0, + (q31_t)0x4e98bba7, (q31_t)0xc1afd007, (q31_t)0x4e8c7f2a, (q31_t)0xc1acf386, + (q31_t)0x4e80421e, (q31_t)0xc1aa196c, (q31_t)0x4e740483, (q31_t)0xc1a741b9, + (q31_t)0x4e67c65a, (q31_t)0xc1a46c6e, (q31_t)0x4e5b87a2, (q31_t)0xc1a1998a, + (q31_t)0x4e4f485c, (q31_t)0xc19ec90d, (q31_t)0x4e430889, (q31_t)0xc19bfaf9, + (q31_t)0x4e36c82a, (q31_t)0xc1992f4c, (q31_t)0x4e2a873e, (q31_t)0xc1966606, + (q31_t)0x4e1e45c6, (q31_t)0xc1939f29, (q31_t)0x4e1203c3, (q31_t)0xc190dab4, + (q31_t)0x4e05c135, (q31_t)0xc18e18a7, (q31_t)0x4df97e1d, (q31_t)0xc18b5903, + (q31_t)0x4ded3a7b, (q31_t)0xc1889bc6, (q31_t)0x4de0f64f, (q31_t)0xc185e0f3, + (q31_t)0x4dd4b19a, (q31_t)0xc1832888, (q31_t)0x4dc86c5d, (q31_t)0xc1807285, + (q31_t)0x4dbc2698, (q31_t)0xc17dbeec, (q31_t)0x4dafe04b, (q31_t)0xc17b0dbb, + (q31_t)0x4da39978, (q31_t)0xc1785ef4, (q31_t)0x4d97521d, (q31_t)0xc175b296, + (q31_t)0x4d8b0a3d, (q31_t)0xc17308a1, (q31_t)0x4d7ec1d6, (q31_t)0xc1706115, + (q31_t)0x4d7278eb, (q31_t)0xc16dbbf3, (q31_t)0x4d662f7b, (q31_t)0xc16b193a, + (q31_t)0x4d59e586, (q31_t)0xc16878eb, (q31_t)0x4d4d9b0e, (q31_t)0xc165db05, + (q31_t)0x4d415013, (q31_t)0xc1633f8a, (q31_t)0x4d350495, (q31_t)0xc160a678, + (q31_t)0x4d28b894, (q31_t)0xc15e0fd1, (q31_t)0x4d1c6c11, (q31_t)0xc15b7b94, + (q31_t)0x4d101f0e, (q31_t)0xc158e9c1, (q31_t)0x4d03d189, (q31_t)0xc1565a58, + (q31_t)0x4cf78383, (q31_t)0xc153cd5a, (q31_t)0x4ceb34fe, (q31_t)0xc15142c6, + (q31_t)0x4cdee5f9, (q31_t)0xc14eba9d, (q31_t)0x4cd29676, (q31_t)0xc14c34df, + (q31_t)0x4cc64673, (q31_t)0xc149b18b, (q31_t)0x4cb9f5f3, (q31_t)0xc14730a3, + (q31_t)0x4cada4f5, (q31_t)0xc144b225, (q31_t)0x4ca1537a, (q31_t)0xc1423613, + (q31_t)0x4c950182, (q31_t)0xc13fbc6c, (q31_t)0x4c88af0e, (q31_t)0xc13d4530, + (q31_t)0x4c7c5c1e, (q31_t)0xc13ad060, (q31_t)0x4c7008b3, (q31_t)0xc1385dfb, + (q31_t)0x4c63b4ce, (q31_t)0xc135ee02, (q31_t)0x4c57606e, (q31_t)0xc1338075, + (q31_t)0x4c4b0b94, (q31_t)0xc1311553, (q31_t)0x4c3eb641, (q31_t)0xc12eac9d, + (q31_t)0x4c326075, (q31_t)0xc12c4653, (q31_t)0x4c260a31, (q31_t)0xc129e276, + (q31_t)0x4c19b374, (q31_t)0xc1278104, (q31_t)0x4c0d5c41, (q31_t)0xc12521ff, + (q31_t)0x4c010496, (q31_t)0xc122c566, (q31_t)0x4bf4ac75, (q31_t)0xc1206b39, + (q31_t)0x4be853de, (q31_t)0xc11e1379, (q31_t)0x4bdbfad1, (q31_t)0xc11bbe26, + (q31_t)0x4bcfa150, (q31_t)0xc1196b3f, (q31_t)0x4bc34759, (q31_t)0xc1171ac6, + (q31_t)0x4bb6ecef, (q31_t)0xc114ccb9, (q31_t)0x4baa9211, (q31_t)0xc1128119, + (q31_t)0x4b9e36c0, (q31_t)0xc11037e6, (q31_t)0x4b91dafc, (q31_t)0xc10df120, + (q31_t)0x4b857ec7, (q31_t)0xc10bacc8, (q31_t)0x4b79221f, (q31_t)0xc1096add, + (q31_t)0x4b6cc506, (q31_t)0xc1072b5f, (q31_t)0x4b60677c, (q31_t)0xc104ee4f, + (q31_t)0x4b540982, (q31_t)0xc102b3ac, (q31_t)0x4b47ab19, (q31_t)0xc1007b77, + (q31_t)0x4b3b4c40, (q31_t)0xc0fe45b0, (q31_t)0x4b2eecf8, (q31_t)0xc0fc1257, + (q31_t)0x4b228d42, (q31_t)0xc0f9e16b, (q31_t)0x4b162d1d, (q31_t)0xc0f7b2ee, + (q31_t)0x4b09cc8c, (q31_t)0xc0f586df, (q31_t)0x4afd6b8d, (q31_t)0xc0f35d3e, + (q31_t)0x4af10a22, (q31_t)0xc0f1360b, (q31_t)0x4ae4a84b, (q31_t)0xc0ef1147, + (q31_t)0x4ad84609, (q31_t)0xc0eceef1, (q31_t)0x4acbe35b, (q31_t)0xc0eacf09, + (q31_t)0x4abf8043, (q31_t)0xc0e8b190, (q31_t)0x4ab31cc1, (q31_t)0xc0e69686, + (q31_t)0x4aa6b8d5, (q31_t)0xc0e47deb, (q31_t)0x4a9a5480, (q31_t)0xc0e267be, + (q31_t)0x4a8defc3, (q31_t)0xc0e05401, (q31_t)0x4a818a9d, (q31_t)0xc0de42b2, + (q31_t)0x4a752510, (q31_t)0xc0dc33d2, (q31_t)0x4a68bf1b, (q31_t)0xc0da2762, + (q31_t)0x4a5c58c0, (q31_t)0xc0d81d61, (q31_t)0x4a4ff1fe, (q31_t)0xc0d615cf, + (q31_t)0x4a438ad7, (q31_t)0xc0d410ad, (q31_t)0x4a37234a, (q31_t)0xc0d20dfa, + (q31_t)0x4a2abb59, (q31_t)0xc0d00db6, (q31_t)0x4a1e5303, (q31_t)0xc0ce0fe3, + (q31_t)0x4a11ea49, (q31_t)0xc0cc147f, (q31_t)0x4a05812c, (q31_t)0xc0ca1b8a, + (q31_t)0x49f917ac, (q31_t)0xc0c82506, (q31_t)0x49ecadc9, (q31_t)0xc0c630f2, + (q31_t)0x49e04385, (q31_t)0xc0c43f4d, (q31_t)0x49d3d8df, (q31_t)0xc0c25019, + (q31_t)0x49c76dd8, (q31_t)0xc0c06355, (q31_t)0x49bb0271, (q31_t)0xc0be7901, + (q31_t)0x49ae96aa, (q31_t)0xc0bc911d, (q31_t)0x49a22a83, (q31_t)0xc0baabaa, + (q31_t)0x4995bdfd, (q31_t)0xc0b8c8a7, (q31_t)0x49895118, (q31_t)0xc0b6e815, + (q31_t)0x497ce3d5, (q31_t)0xc0b509f3, (q31_t)0x49707635, (q31_t)0xc0b32e42, + (q31_t)0x49640837, (q31_t)0xc0b15502, (q31_t)0x495799dd, (q31_t)0xc0af7e33, + (q31_t)0x494b2b27, (q31_t)0xc0ada9d4, (q31_t)0x493ebc14, (q31_t)0xc0abd7e6, + (q31_t)0x49324ca7, (q31_t)0xc0aa086a, (q31_t)0x4925dcdf, (q31_t)0xc0a83b5e, + (q31_t)0x49196cbc, (q31_t)0xc0a670c4, (q31_t)0x490cfc40, (q31_t)0xc0a4a89b, + (q31_t)0x49008b6a, (q31_t)0xc0a2e2e3, (q31_t)0x48f41a3c, (q31_t)0xc0a11f9d, + (q31_t)0x48e7a8b5, (q31_t)0xc09f5ec8, (q31_t)0x48db36d6, (q31_t)0xc09da065, + (q31_t)0x48cec4a0, (q31_t)0xc09be473, (q31_t)0x48c25213, (q31_t)0xc09a2af3, + (q31_t)0x48b5df30, (q31_t)0xc09873e4, (q31_t)0x48a96bf6, (q31_t)0xc096bf48, + (q31_t)0x489cf867, (q31_t)0xc0950d1d, (q31_t)0x48908483, (q31_t)0xc0935d64, + (q31_t)0x4884104b, (q31_t)0xc091b01d, (q31_t)0x48779bbe, (q31_t)0xc0900548, + (q31_t)0x486b26de, (q31_t)0xc08e5ce5, (q31_t)0x485eb1ab, (q31_t)0xc08cb6f5, + (q31_t)0x48523c25, (q31_t)0xc08b1376, (q31_t)0x4845c64d, (q31_t)0xc089726a, + (q31_t)0x48395024, (q31_t)0xc087d3d0, (q31_t)0x482cd9a9, (q31_t)0xc08637a9, + (q31_t)0x482062de, (q31_t)0xc0849df4, (q31_t)0x4813ebc2, (q31_t)0xc08306b2, + (q31_t)0x48077457, (q31_t)0xc08171e2, (q31_t)0x47fafc9c, (q31_t)0xc07fdf85, + (q31_t)0x47ee8493, (q31_t)0xc07e4f9b, (q31_t)0x47e20c3b, (q31_t)0xc07cc223, + (q31_t)0x47d59396, (q31_t)0xc07b371e, (q31_t)0x47c91aa3, (q31_t)0xc079ae8c, + (q31_t)0x47bca163, (q31_t)0xc078286e, (q31_t)0x47b027d7, (q31_t)0xc076a4c2, + (q31_t)0x47a3adff, (q31_t)0xc0752389, (q31_t)0x479733dc, (q31_t)0xc073a4c3, + (q31_t)0x478ab96e, (q31_t)0xc0722871, (q31_t)0x477e3eb5, (q31_t)0xc070ae92, + (q31_t)0x4771c3b3, (q31_t)0xc06f3726, (q31_t)0x47654867, (q31_t)0xc06dc22e, + (q31_t)0x4758ccd2, (q31_t)0xc06c4fa8, (q31_t)0x474c50f4, (q31_t)0xc06adf97, + (q31_t)0x473fd4cf, (q31_t)0xc06971f9, (q31_t)0x47335862, (q31_t)0xc06806ce, + (q31_t)0x4726dbae, (q31_t)0xc0669e18, (q31_t)0x471a5eb3, (q31_t)0xc06537d4, + (q31_t)0x470de172, (q31_t)0xc063d405, (q31_t)0x470163eb, (q31_t)0xc06272aa, + (q31_t)0x46f4e620, (q31_t)0xc06113c2, (q31_t)0x46e86810, (q31_t)0xc05fb74e, + (q31_t)0x46dbe9bb, (q31_t)0xc05e5d4e, (q31_t)0x46cf6b23, (q31_t)0xc05d05c3, + (q31_t)0x46c2ec48, (q31_t)0xc05bb0ab, (q31_t)0x46b66d29, (q31_t)0xc05a5e07, + (q31_t)0x46a9edc9, (q31_t)0xc0590dd8, (q31_t)0x469d6e27, (q31_t)0xc057c01d, + (q31_t)0x4690ee44, (q31_t)0xc05674d6, (q31_t)0x46846e1f, (q31_t)0xc0552c03, + (q31_t)0x4677edbb, (q31_t)0xc053e5a5, (q31_t)0x466b6d16, (q31_t)0xc052a1bb, + (q31_t)0x465eec33, (q31_t)0xc0516045, (q31_t)0x46526b10, (q31_t)0xc0502145, + (q31_t)0x4645e9af, (q31_t)0xc04ee4b8, (q31_t)0x46396810, (q31_t)0xc04daaa1, + (q31_t)0x462ce634, (q31_t)0xc04c72fe, (q31_t)0x4620641a, (q31_t)0xc04b3dcf, + (q31_t)0x4613e1c5, (q31_t)0xc04a0b16, (q31_t)0x46075f33, (q31_t)0xc048dad1, + (q31_t)0x45fadc66, (q31_t)0xc047ad01, (q31_t)0x45ee595d, (q31_t)0xc04681a6, + (q31_t)0x45e1d61b, (q31_t)0xc04558c0, (q31_t)0x45d5529e, (q31_t)0xc044324f, + (q31_t)0x45c8cee7, (q31_t)0xc0430e53, (q31_t)0x45bc4af8, (q31_t)0xc041eccc, + (q31_t)0x45afc6d0, (q31_t)0xc040cdba, (q31_t)0x45a3426f, (q31_t)0xc03fb11d, + (q31_t)0x4596bdd7, (q31_t)0xc03e96f6, (q31_t)0x458a3908, (q31_t)0xc03d7f44, + (q31_t)0x457db403, (q31_t)0xc03c6a07, (q31_t)0x45712ec7, (q31_t)0xc03b573f, + (q31_t)0x4564a955, (q31_t)0xc03a46ed, (q31_t)0x455823ae, (q31_t)0xc0393910, + (q31_t)0x454b9dd3, (q31_t)0xc0382da8, (q31_t)0x453f17c3, (q31_t)0xc03724b6, + (q31_t)0x4532917f, (q31_t)0xc0361e3a, (q31_t)0x45260b08, (q31_t)0xc0351a33, + (q31_t)0x4519845e, (q31_t)0xc03418a2, (q31_t)0x450cfd82, (q31_t)0xc0331986, + (q31_t)0x45007674, (q31_t)0xc0321ce0, (q31_t)0x44f3ef35, (q31_t)0xc03122b0, + (q31_t)0x44e767c5, (q31_t)0xc0302af5, (q31_t)0x44dae024, (q31_t)0xc02f35b1, + (q31_t)0x44ce5854, (q31_t)0xc02e42e2, (q31_t)0x44c1d054, (q31_t)0xc02d5289, + (q31_t)0x44b54825, (q31_t)0xc02c64a6, (q31_t)0x44a8bfc7, (q31_t)0xc02b7939, + (q31_t)0x449c373c, (q31_t)0xc02a9042, (q31_t)0x448fae83, (q31_t)0xc029a9c1, + (q31_t)0x4483259d, (q31_t)0xc028c5b6, (q31_t)0x44769c8b, (q31_t)0xc027e421, + (q31_t)0x446a134c, (q31_t)0xc0270502, (q31_t)0x445d89e2, (q31_t)0xc0262859, + (q31_t)0x4451004d, (q31_t)0xc0254e27, (q31_t)0x4444768d, (q31_t)0xc024766a, + (q31_t)0x4437eca4, (q31_t)0xc023a124, (q31_t)0x442b6290, (q31_t)0xc022ce54, + (q31_t)0x441ed854, (q31_t)0xc021fdfb, (q31_t)0x44124dee, (q31_t)0xc0213018, + (q31_t)0x4405c361, (q31_t)0xc02064ab, (q31_t)0x43f938ac, (q31_t)0xc01f9bb5, + (q31_t)0x43ecadcf, (q31_t)0xc01ed535, (q31_t)0x43e022cc, (q31_t)0xc01e112b, + (q31_t)0x43d397a3, (q31_t)0xc01d4f99, (q31_t)0x43c70c54, (q31_t)0xc01c907c, + (q31_t)0x43ba80df, (q31_t)0xc01bd3d6, (q31_t)0x43adf546, (q31_t)0xc01b19a7, + (q31_t)0x43a16988, (q31_t)0xc01a61ee, (q31_t)0x4394dda7, (q31_t)0xc019acac, + (q31_t)0x438851a2, (q31_t)0xc018f9e1, (q31_t)0x437bc57b, (q31_t)0xc018498c, + (q31_t)0x436f3931, (q31_t)0xc0179bae, (q31_t)0x4362acc5, (q31_t)0xc016f047, + (q31_t)0x43562038, (q31_t)0xc0164757, (q31_t)0x43499389, (q31_t)0xc015a0dd, + (q31_t)0x433d06bb, (q31_t)0xc014fcda, (q31_t)0x433079cc, (q31_t)0xc0145b4e, + (q31_t)0x4323ecbe, (q31_t)0xc013bc39, (q31_t)0x43175f91, (q31_t)0xc0131f9b, + (q31_t)0x430ad245, (q31_t)0xc0128574, (q31_t)0x42fe44dc, (q31_t)0xc011edc3, + (q31_t)0x42f1b755, (q31_t)0xc011588a, (q31_t)0x42e529b0, (q31_t)0xc010c5c7, + (q31_t)0x42d89bf0, (q31_t)0xc010357c, (q31_t)0x42cc0e13, (q31_t)0xc00fa7a8, + (q31_t)0x42bf801a, (q31_t)0xc00f1c4a, (q31_t)0x42b2f207, (q31_t)0xc00e9364, + (q31_t)0x42a663d8, (q31_t)0xc00e0cf5, (q31_t)0x4299d590, (q31_t)0xc00d88fd, + (q31_t)0x428d472e, (q31_t)0xc00d077c, (q31_t)0x4280b8b3, (q31_t)0xc00c8872, + (q31_t)0x42742a1f, (q31_t)0xc00c0be0, (q31_t)0x42679b73, (q31_t)0xc00b91c4, + (q31_t)0x425b0caf, (q31_t)0xc00b1a20, (q31_t)0x424e7dd4, (q31_t)0xc00aa4f3, + (q31_t)0x4241eee2, (q31_t)0xc00a323d, (q31_t)0x42355fd9, (q31_t)0xc009c1ff, + (q31_t)0x4228d0bb, (q31_t)0xc0095438, (q31_t)0x421c4188, (q31_t)0xc008e8e8, + (q31_t)0x420fb240, (q31_t)0xc008800f, (q31_t)0x420322e3, (q31_t)0xc00819ae, + (q31_t)0x41f69373, (q31_t)0xc007b5c4, (q31_t)0x41ea03ef, (q31_t)0xc0075452, + (q31_t)0x41dd7459, (q31_t)0xc006f556, (q31_t)0x41d0e4b0, (q31_t)0xc00698d3, + (q31_t)0x41c454f5, (q31_t)0xc0063ec6, (q31_t)0x41b7c528, (q31_t)0xc005e731, + (q31_t)0x41ab354b, (q31_t)0xc0059214, (q31_t)0x419ea55d, (q31_t)0xc0053f6e, + (q31_t)0x4192155f, (q31_t)0xc004ef3f, (q31_t)0x41858552, (q31_t)0xc004a188, + (q31_t)0x4178f536, (q31_t)0xc0045648, (q31_t)0x416c650b, (q31_t)0xc0040d80, + (q31_t)0x415fd4d2, (q31_t)0xc003c72f, (q31_t)0x4153448c, (q31_t)0xc0038356, + (q31_t)0x4146b438, (q31_t)0xc00341f4, (q31_t)0x413a23d8, (q31_t)0xc003030a, + (q31_t)0x412d936c, (q31_t)0xc002c697, (q31_t)0x412102f4, (q31_t)0xc0028c9c, + (q31_t)0x41147271, (q31_t)0xc0025519, (q31_t)0x4107e1e3, (q31_t)0xc002200d, + (q31_t)0x40fb514b, (q31_t)0xc001ed78, (q31_t)0x40eec0aa, (q31_t)0xc001bd5c, + (q31_t)0x40e22fff, (q31_t)0xc0018fb6, (q31_t)0x40d59f4c, (q31_t)0xc0016489, + (q31_t)0x40c90e90, (q31_t)0xc0013bd3, (q31_t)0x40bc7dcc, (q31_t)0xc0011594, + (q31_t)0x40afed02, (q31_t)0xc000f1ce, (q31_t)0x40a35c30, (q31_t)0xc000d07e, + (q31_t)0x4096cb58, (q31_t)0xc000b1a7, (q31_t)0x408a3a7b, (q31_t)0xc0009547, + (q31_t)0x407da998, (q31_t)0xc0007b5f, (q31_t)0x407118b0, (q31_t)0xc00063ee, + (q31_t)0x406487c4, (q31_t)0xc0004ef5, (q31_t)0x4057f6d4, (q31_t)0xc0003c74, + (q31_t)0x404b65e1, (q31_t)0xc0002c6a, (q31_t)0x403ed4ea, (q31_t)0xc0001ed8, + (q31_t)0x403243f1, (q31_t)0xc00013bd, (q31_t)0x4025b2f7, (q31_t)0xc0000b1a, + (q31_t)0x401921fb, (q31_t)0xc00004ef, (q31_t)0x400c90fe, (q31_t)0xc000013c, +}; + +/** + @} end of RealFFT_Table group + */ + +/** + @addtogroup RealFFT + @{ + */ + +/** + @brief Initialization function for the Q31 RFFT/RIFFT. + @param[in,out] S points to an instance of the Q31 RFFT/RIFFT structure + @param[in] fftLenReal length of the FFT + @param[in] ifftFlagR flag that selects transform direction + - value = 0: forward transform + - value = 1: inverse transform + @param[in] bitReverseFlag flag that enables / disables bit reversal of output + - value = 0: disables bit reversal of output + - value = 1: enables bit reversal of output + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_ARGUMENT_ERROR : fftLenReal is not a supported length + + @par Details + The parameter fftLenReal specifies length of RFFT/RIFFT Process. + Supported FFT Lengths are 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192. + @par + The parameter ifftFlagR controls whether a forward or inverse transform is computed. + Set(=1) ifftFlagR to calculate RIFFT, otherwise RFFT is calculated. + @par + The parameter bitReverseFlag controls whether output is in normal order or bit reversed order. + Set(=1) bitReverseFlag for output to be in normal order otherwise output is in bit reversed order. + @par + This function also initializes Twiddle factor table. +*/ + +arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag) +{ + /* Initialise the default arm status */ + arm_status status = ARM_MATH_SUCCESS; + + /* Initialize the Real FFT length */ + S->fftLenReal = (uint16_t) fftLenReal; + + /* Initialize the Twiddle coefficientA pointer */ + S->pTwiddleAReal = (q31_t *) realCoefAQ31; + + /* Initialize the Twiddle coefficientB pointer */ + S->pTwiddleBReal = (q31_t *) realCoefBQ31; + + /* Initialize the Flag for selection of RFFT or RIFFT */ + S->ifftFlagR = (uint8_t) ifftFlagR; + + /* Initialize the Flag for calculation Bit reversal or not */ + S->bitReverseFlagR = (uint8_t) bitReverseFlag; + + /* Initialization of coef modifier depending on the FFT length */ + switch (S->fftLenReal) + { + case 8192U: + S->twidCoefRModifier = 1U; + S->pCfft = &arm_cfft_sR_q31_len4096; + break; + case 4096U: + S->twidCoefRModifier = 2U; + S->pCfft = &arm_cfft_sR_q31_len2048; + break; + case 2048U: + S->twidCoefRModifier = 4U; + S->pCfft = &arm_cfft_sR_q31_len1024; + break; + case 1024U: + S->twidCoefRModifier = 8U; + S->pCfft = &arm_cfft_sR_q31_len512; + break; + case 512U: + S->twidCoefRModifier = 16U; + S->pCfft = &arm_cfft_sR_q31_len256; + break; + case 256U: + S->twidCoefRModifier = 32U; + S->pCfft = &arm_cfft_sR_q31_len128; + break; + case 128U: + S->twidCoefRModifier = 64U; + S->pCfft = &arm_cfft_sR_q31_len64; + break; + case 64U: + S->twidCoefRModifier = 128U; + S->pCfft = &arm_cfft_sR_q31_len32; + break; + case 32U: + S->twidCoefRModifier = 256U; + S->pCfft = &arm_cfft_sR_q31_len16; + break; + default: + /* Reporting argument error if rfftSize is not valid value */ + status = ARM_MATH_ARGUMENT_ERROR; + break; + } + + /* return the status of RFFT Init function */ + return (status); +} + +/** + @} end of RealFFT group + */ diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_q15.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_q15.c new file mode 100644 index 0000000..fdc9bab --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_q15.c @@ -0,0 +1,380 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_rfft_q15.c + * Description: RFFT & RIFFT Q15 process function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/* ---------------------------------------------------------------------- + * Internal functions prototypes + * -------------------------------------------------------------------- */ + +void arm_split_rfft_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pATable, + const q15_t * pBTable, + q15_t * pDst, + uint32_t modifier); + +void arm_split_rifft_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pATable, + const q15_t * pBTable, + q15_t * pDst, + uint32_t modifier); + +/** + @addtogroup RealFFT + @{ + */ + +/** + @brief Processing function for the Q15 RFFT/RIFFT. + @param[in] S points to an instance of the Q15 RFFT/RIFFT structure + @param[in] pSrc points to input buffer + @param[out] pDst points to output buffer + @return none + + @par Input an output formats + Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process. + Hence the output format is different for different RFFT sizes. + The input and output formats for different RFFT sizes and number of bits to upscale are mentioned in the tables below for RFFT and RIFFT: + @par + \image html RFFTQ15.gif "Input and Output Formats for Q15 RFFT" + @par + \image html RIFFTQ15.gif "Input and Output Formats for Q15 RIFFT" + */ + +void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst) +{ + const arm_cfft_instance_q15 *S_CFFT = S->pCfft; + uint32_t L2 = S->fftLenReal >> 1U; + uint32_t i; + + /* Calculation of RIFFT of input */ + if (S->ifftFlagR == 1U) + { + /* Real IFFT core process */ + arm_split_rifft_q15 (pSrc, L2, S->pTwiddleAReal, S->pTwiddleBReal, pDst, S->twidCoefRModifier); + + /* Complex IFFT process */ + arm_cfft_q15 (S_CFFT, pDst, S->ifftFlagR, S->bitReverseFlagR); + + for(i = 0; i < S->fftLenReal; i++) + { + pDst[i] = pDst[i] << 1U; + } + } + else + { + /* Calculation of RFFT of input */ + + /* Complex FFT process */ + arm_cfft_q15 (S_CFFT, pSrc, S->ifftFlagR, S->bitReverseFlagR); + + /* Real FFT core process */ + arm_split_rfft_q15 (pSrc, L2, S->pTwiddleAReal, S->pTwiddleBReal, pDst, S->twidCoefRModifier); + } + +} + +/** + @} end of RealFFT group + */ + +/** + @brief Core Real FFT process + @param[in] pSrc points to input buffer + @param[in] fftLen length of FFT + @param[in] pATable points to twiddle Coef A buffer + @param[in] pBTable points to twiddle Coef B buffer + @param[out] pDst points to output buffer + @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table + @return none + + @par + The function implements a Real FFT + */ + +void arm_split_rfft_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pATable, + const q15_t * pBTable, + q15_t * pDst, + uint32_t modifier) +{ + uint32_t i; /* Loop Counter */ + q31_t outR, outI; /* Temporary variables for output */ + const q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ + q15_t *pSrc1, *pSrc2; +#if defined (ARM_MATH_DSP) + q15_t *pD1, *pD2; +#endif + + /* Init coefficient pointers */ + pCoefA = &pATable[modifier * 2]; + pCoefB = &pBTable[modifier * 2]; + + pSrc1 = &pSrc[2]; + pSrc2 = &pSrc[(2U * fftLen) - 2U]; + +#if defined (ARM_MATH_DSP) + + i = 1U; + pD1 = pDst + 2; + pD2 = pDst + (4U * fftLen) - 2; + + for (i = fftLen - 1; i > 0; i--) + { + /* + outR = ( pSrc[2 * i] * pATable[2 * i] + - pSrc[2 * i + 1] * pATable[2 * i + 1] + + pSrc[2 * n - 2 * i] * pBTable[2 * i] + + pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); + + outI = ( pIn[2 * i + 1] * pATable[2 * i] + + pIn[2 * i] * pATable[2 * i + 1] + + pIn[2 * n - 2 * i] * pBTable[2 * i + 1] + - pIn[2 * n - 2 * i + 1] * pBTable[2 * i]) + */ + + +#ifndef ARM_MATH_BIG_ENDIAN + /* pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] */ + outR = __SMUSD(read_q15x2 (pSrc1), read_q15x2((q15_t *) pCoefA)); +#else + /* -(pSrc[2 * i + 1] * pATable[2 * i + 1] - pSrc[2 * i] * pATable[2 * i]) */ + outR = -(__SMUSD(read_q15x2 (pSrc1), read_q15x2((q15_t *) pCoefA))); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* pSrc[2 * n - 2 * i] * pBTable[2 * i] + pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */ + outR = __SMLAD(read_q15x2 (pSrc2), read_q15x2((q15_t *) pCoefB), outR) >> 16U; + + /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */ +#ifndef ARM_MATH_BIG_ENDIAN + outI = __SMUSDX(read_q15x2_da (&pSrc2), read_q15x2((q15_t *) pCoefB)); +#else + outI = __SMUSDX(read_q15x2 ((q15_t *) pCoefB), read_q15x2_da (&pSrc2)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] */ + outI = __SMLADX(read_q15x2_ia (&pSrc1), read_q15x2 ((q15_t *) pCoefA), outI); + + /* write output */ + *pD1++ = (q15_t) outR; + *pD1++ = outI >> 16U; + + /* write complex conjugate output */ + pD2[0] = (q15_t) outR; + pD2[1] = -(outI >> 16U); + pD2 -= 2; + + /* update coefficient pointer */ + pCoefB = pCoefB + (2U * modifier); + pCoefA = pCoefA + (2U * modifier); + } + + pDst[2U * fftLen] = (pSrc[0] - pSrc[1]) >> 1U; + pDst[2U * fftLen + 1U] = 0; + + pDst[0] = (pSrc[0] + pSrc[1]) >> 1U; + pDst[1] = 0; + +#else + + i = 1U; + + while (i < fftLen) + { + /* + outR = ( pSrc[2 * i] * pATable[2 * i] + - pSrc[2 * i + 1] * pATable[2 * i + 1] + + pSrc[2 * n - 2 * i] * pBTable[2 * i] + + pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); + */ + + outR = *pSrc1 * *pCoefA; + outR = outR - (*(pSrc1 + 1) * *(pCoefA + 1)); + outR = outR + (*pSrc2 * *pCoefB); + outR = (outR + (*(pSrc2 + 1) * *(pCoefB + 1))) >> 16; + + /* + outI = ( pIn[2 * i + 1] * pATable[2 * i] + + pIn[2 * i] * pATable[2 * i + 1] + + pIn[2 * n - 2 * i] * pBTable[2 * i + 1] + - pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); + */ + + outI = *pSrc2 * *(pCoefB + 1); + outI = outI - (*(pSrc2 + 1) * *pCoefB); + outI = outI + (*(pSrc1 + 1) * *pCoefA); + outI = outI + (*pSrc1 * *(pCoefA + 1)); + + /* update input pointers */ + pSrc1 += 2U; + pSrc2 -= 2U; + + /* write output */ + pDst[2U * i] = (q15_t) outR; + pDst[2U * i + 1U] = outI >> 16U; + + /* write complex conjugate output */ + pDst[(4U * fftLen) - (2U * i)] = (q15_t) outR; + pDst[((4U * fftLen) - (2U * i)) + 1U] = -(outI >> 16U); + + /* update coefficient pointer */ + pCoefB = pCoefB + (2U * modifier); + pCoefA = pCoefA + (2U * modifier); + + i++; + } + + pDst[2U * fftLen] = (pSrc[0] - pSrc[1]) >> 1; + pDst[2U * fftLen + 1U] = 0; + + pDst[0] = (pSrc[0] + pSrc[1]) >> 1; + pDst[1] = 0; + +#endif /* #if defined (ARM_MATH_DSP) */ +} + + +/** + @brief Core Real IFFT process + @param[in] pSrc points to input buffer + @param[in] fftLen length of FFT + @param[in] pATable points to twiddle Coef A buffer + @param[in] pBTable points to twiddle Coef B buffer + @param[out] pDst points to output buffer + @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table + @return none + + @par + The function implements a Real IFFT + */ + +void arm_split_rifft_q15( + q15_t * pSrc, + uint32_t fftLen, + const q15_t * pATable, + const q15_t * pBTable, + q15_t * pDst, + uint32_t modifier) +{ + uint32_t i; /* Loop Counter */ + q31_t outR, outI; /* Temporary variables for output */ + const q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ + q15_t *pSrc1, *pSrc2; + q15_t *pDst1 = &pDst[0]; + + pCoefA = &pATable[0]; + pCoefB = &pBTable[0]; + + pSrc1 = &pSrc[0]; + pSrc2 = &pSrc[2 * fftLen]; + + i = fftLen; + while (i > 0U) + { + /* + outR = ( pIn[2 * i] * pATable[2 * i] + + pIn[2 * i + 1] * pATable[2 * i + 1] + + pIn[2 * n - 2 * i] * pBTable[2 * i] + - pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); + + outI = ( pIn[2 * i + 1] * pATable[2 * i] + - pIn[2 * i] * pATable[2 * i + 1] + - pIn[2 * n - 2 * i] * pBTable[2 * i + 1] + - pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); + */ + +#if defined (ARM_MATH_DSP) + +#ifndef ARM_MATH_BIG_ENDIAN + /* pIn[2 * n - 2 * i] * pBTable[2 * i] - pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */ + outR = __SMUSD(read_q15x2(pSrc2), read_q15x2((q15_t *) pCoefB)); +#else + /* -(-pIn[2 * n - 2 * i] * pBTable[2 * i] + pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1])) */ + outR = -(__SMUSD(read_q15x2(pSrc2), read_q15x2((q15_t *) pCoefB))); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] + pIn[2 * n - 2 * i] * pBTable[2 * i] */ + outR = __SMLAD(read_q15x2(pSrc1), read_q15x2 ((q15_t *) pCoefA), outR) >> 16U; + + /* -pIn[2 * n - 2 * i] * pBTable[2 * i + 1] + pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */ + outI = __SMUADX(read_q15x2_da (&pSrc2), read_q15x2((q15_t *) pCoefB)); + + /* pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] */ +#ifndef ARM_MATH_BIG_ENDIAN + outI = __SMLSDX(read_q15x2 ((q15_t *) pCoefA), read_q15x2_ia (&pSrc1), -outI); +#else + outI = __SMLSDX(read_q15x2_ia (&pSrc1), read_q15x2 ((q15_t *) pCoefA), -outI); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* write output */ +#ifndef ARM_MATH_BIG_ENDIAN + write_q15x2_ia (&pDst1, __PKHBT(outR, (outI >> 16U), 16)); +#else + write_q15x2_ia (&pDst1, __PKHBT((outI >> 16U), outR, 16)); +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + +#else /* #if defined (ARM_MATH_DSP) */ + + outR = *pSrc2 * *pCoefB; + outR = outR - (*(pSrc2 + 1) * *(pCoefB + 1)); + outR = outR + (*pSrc1 * *pCoefA); + outR = (outR + (*(pSrc1 + 1) * *(pCoefA + 1))) >> 16; + + outI = *(pSrc1 + 1) * *pCoefA; + outI = outI - (*pSrc1 * *(pCoefA + 1)); + outI = outI - (*pSrc2 * *(pCoefB + 1)); + outI = outI - (*(pSrc2 + 1) * *(pCoefB)); + + /* update input pointers */ + pSrc1 += 2U; + pSrc2 -= 2U; + + /* write output */ + *pDst1++ = (q15_t) outR; + *pDst1++ = (q15_t) (outI >> 16); + +#endif /* #if defined (ARM_MATH_DSP) */ + + /* update coefficient pointer */ + pCoefB = pCoefB + (2 * modifier); + pCoefA = pCoefA + (2 * modifier); + + i--; + } + +} diff --git a/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_q31.c b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_q31.c new file mode 100644 index 0000000..d16600d --- /dev/null +++ b/platform/cmsis/DSP_Lib/TransformFunctions/arm_rfft_q31.c @@ -0,0 +1,292 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_rfft_q31.c + * Description: FFT & RIFFT Q31 process function + * + * $Date: 18. March 2019 + * $Revision: V1.6.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * 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. + */ + +#include "arm_math.h" + +/* ---------------------------------------------------------------------- + * Internal functions prototypes + * -------------------------------------------------------------------- */ + +void arm_split_rfft_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pATable, + const q31_t * pBTable, + q31_t * pDst, + uint32_t modifier); + +void arm_split_rifft_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pATable, + const q31_t * pBTable, + q31_t * pDst, + uint32_t modifier); + +/** + @addtogroup RealFFT + @{ + */ + +/** + @brief Processing function for the Q31 RFFT/RIFFT. + @param[in] S points to an instance of the Q31 RFFT/RIFFT structure + @param[in] pSrc points to input buffer + @param[out] pDst points to output buffer + @return none + + @par Input an output formats + Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process. + Hence the output format is different for different RFFT sizes. + The input and output formats for different RFFT sizes and number of bits to upscale are mentioned in the tables below for RFFT and RIFFT: + @par + \image html RFFTQ31.gif "Input and Output Formats for Q31 RFFT" + @par + \image html RIFFTQ31.gif "Input and Output Formats for Q31 RIFFT" + */ + +void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst) +{ + const arm_cfft_instance_q31 *S_CFFT = S->pCfft; + uint32_t L2 = S->fftLenReal >> 1U; + uint32_t i; + + /* Calculation of RIFFT of input */ + if (S->ifftFlagR == 1U) + { + /* Real IFFT core process */ + arm_split_rifft_q31 (pSrc, L2, S->pTwiddleAReal, S->pTwiddleBReal, pDst, S->twidCoefRModifier); + + /* Complex IFFT process */ + arm_cfft_q31 (S_CFFT, pDst, S->ifftFlagR, S->bitReverseFlagR); + + for(i = 0; i < S->fftLenReal; i++) + { + pDst[i] = pDst[i] << 1U; + } + } + else + { + /* Calculation of RFFT of input */ + + /* Complex FFT process */ + arm_cfft_q31 (S_CFFT, pSrc, S->ifftFlagR, S->bitReverseFlagR); + + /* Real FFT core process */ + arm_split_rfft_q31 (pSrc, L2, S->pTwiddleAReal, S->pTwiddleBReal, pDst, S->twidCoefRModifier); + } + +} + +/** + @} end of RealFFT group + */ + +/** + @brief Core Real FFT process + @param[in] pSrc points to input buffer + @param[in] fftLen length of FFT + @param[in] pATable points to twiddle Coef A buffer + @param[in] pBTable points to twiddle Coef B buffer + @param[out] pDst points to output buffer + @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table + @return none + */ + +void arm_split_rfft_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pATable, + const q31_t * pBTable, + q31_t * pDst, + uint32_t modifier) +{ + uint32_t i; /* Loop Counter */ + q31_t outR, outI; /* Temporary variables for output */ + const q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ + q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ + q31_t *pOut1 = &pDst[2], *pOut2 = &pDst[4 * fftLen - 1]; + q31_t *pIn1 = &pSrc[2], *pIn2 = &pSrc[2 * fftLen - 1]; + + /* Init coefficient pointers */ + pCoefA = &pATable[modifier * 2]; + pCoefB = &pBTable[modifier * 2]; + + i = fftLen - 1U; + + while (i > 0U) + { + /* + outR = ( pSrc[2 * i] * pATable[2 * i] + - pSrc[2 * i + 1] * pATable[2 * i + 1] + + pSrc[2 * n - 2 * i] * pBTable[2 * i] + + pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); + + outI = ( pIn[2 * i + 1] * pATable[2 * i] + + pIn[2 * i] * pATable[2 * i + 1] + + pIn[2 * n - 2 * i] * pBTable[2 * i + 1] + - pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); + */ + + CoefA1 = *pCoefA++; + CoefA2 = *pCoefA; + + /* outR = (pSrc[2 * i] * pATable[2 * i] */ + mult_32x32_keep32_R (outR, *pIn1, CoefA1); + + /* outI = pIn[2 * i] * pATable[2 * i + 1] */ + mult_32x32_keep32_R (outI, *pIn1++, CoefA2); + + /* - pSrc[2 * i + 1] * pATable[2 * i + 1] */ + multSub_32x32_keep32_R (outR, *pIn1, CoefA2); + + /* (pIn[2 * i + 1] * pATable[2 * i] */ + multAcc_32x32_keep32_R (outI, *pIn1++, CoefA1); + + /* pSrc[2 * n - 2 * i] * pBTable[2 * i] */ + multSub_32x32_keep32_R (outR, *pIn2, CoefA2); + CoefB1 = *pCoefB; + + /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */ + multSub_32x32_keep32_R (outI, *pIn2--, CoefB1); + + /* pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */ + multAcc_32x32_keep32_R (outR, *pIn2, CoefB1); + + /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */ + multSub_32x32_keep32_R (outI, *pIn2--, CoefA2); + + /* write output */ + *pOut1++ = outR; + *pOut1++ = outI; + + /* write complex conjugate output */ + *pOut2-- = -outI; + *pOut2-- = outR; + + /* update coefficient pointer */ + pCoefB = pCoefB + (2 * modifier); + pCoefA = pCoefA + (2 * modifier - 1); + + /* Decrement loop count */ + i--; + } + + pDst[2 * fftLen] = (pSrc[0] - pSrc[1]) >> 1U; + pDst[2 * fftLen + 1] = 0; + + pDst[0] = (pSrc[0] + pSrc[1]) >> 1U; + pDst[1] = 0; +} + + +/** + @brief Core Real IFFT process + @param[in] pSrc points to input buffer + @param[in] fftLen length of FFT + @param[in] pATable points to twiddle Coef A buffer + @param[in] pBTable points to twiddle Coef B buffer + @param[out] pDst points to output buffer + @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table + @return none + */ + +void arm_split_rifft_q31( + q31_t * pSrc, + uint32_t fftLen, + const q31_t * pATable, + const q31_t * pBTable, + q31_t * pDst, + uint32_t modifier) +{ + q31_t outR, outI; /* Temporary variables for output */ + const q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ + q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ + q31_t *pIn1 = &pSrc[0], *pIn2 = &pSrc[2 * fftLen + 1]; + + pCoefA = &pATable[0]; + pCoefB = &pBTable[0]; + + while (fftLen > 0U) + { + /* + outR = ( pIn[2 * i] * pATable[2 * i] + + pIn[2 * i + 1] * pATable[2 * i + 1] + + pIn[2 * n - 2 * i] * pBTable[2 * i] + - pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); + + outI = ( pIn[2 * i + 1] * pATable[2 * i] + - pIn[2 * i] * pATable[2 * i + 1] + - pIn[2 * n - 2 * i] * pBTable[2 * i + 1] + - pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); + */ + + CoefA1 = *pCoefA++; + CoefA2 = *pCoefA; + + /* outR = (pIn[2 * i] * pATable[2 * i] */ + mult_32x32_keep32_R (outR, *pIn1, CoefA1); + + /* - pIn[2 * i] * pATable[2 * i + 1] */ + mult_32x32_keep32_R (outI, *pIn1++, -CoefA2); + + /* pIn[2 * i + 1] * pATable[2 * i + 1] */ + multAcc_32x32_keep32_R (outR, *pIn1, CoefA2); + + /* pIn[2 * i + 1] * pATable[2 * i] */ + multAcc_32x32_keep32_R (outI, *pIn1++, CoefA1); + + /* pIn[2 * n - 2 * i] * pBTable[2 * i] */ + multAcc_32x32_keep32_R (outR, *pIn2, CoefA2); + CoefB1 = *pCoefB; + + /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */ + multSub_32x32_keep32_R (outI, *pIn2--, CoefB1); + + /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */ + multAcc_32x32_keep32_R (outR, *pIn2, CoefB1); + + /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */ + multAcc_32x32_keep32_R (outI, *pIn2--, CoefA2); + + /* write output */ + *pDst++ = outR; + *pDst++ = outI; + + /* update coefficient pointer */ + pCoefB = pCoefB + (modifier * 2); + pCoefA = pCoefA + (modifier * 2 - 1); + + /* Decrement loop count */ + fftLen--; + } + +} diff --git a/platform/cmsis/LICENSE.txt b/platform/cmsis/LICENSE.txt new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/platform/cmsis/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/platform/cmsis/Makefile b/platform/cmsis/Makefile new file mode 100644 index 0000000..f5f748f --- /dev/null +++ b/platform/cmsis/Makefile @@ -0,0 +1,67 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := cmsis_nvic.o patch.o patch_armv7m.o retarget_armclang_asm.o retarget_armclang.o \ + retarget_gcc.o system_ARMCM.o system_cp.o system_utils.o \ + stack_protector.o + +ifeq ($(CPU),m4) +obj-y += mpu_armv7m.o +else +obj-y += mpu_armv8m.o +endif + +ifeq ($(DSP_LIB),1) +obj-y += DSP_Lib/ +endif + +ifneq ($(filter a%,$(CPU)),) +obj-y += ca/ +endif + +ccflags-y := -I$(obj)/inc + +FAULT_FLAGS := +USAGE_FAULT ?= 1 +ifeq ($(USAGE_FAULT),1) +FAULT_FLAGS += -DUSAGE_FAULT +endif +BUS_FAULT ?= 1 +ifeq ($(BUS_FAULT),1) +FAULT_FLAGS += -DBUS_FAULT +endif +MEM_FAULT ?= 1 +ifeq ($(MEM_FAULT),1) +FAULT_FLAGS += -DMEM_FAULT +endif +CFLAGS_system_ARMCM.o += $(FAULT_FLAGS) +CFLAGS_system_cp.o += $(FAULT_FLAGS) + +ifeq ($(ACCURATE_DB_TO_FLOAT),1) +CFLAGS_system_utils.o += -DACCURATE_DB_TO_FLOAT +endif +ifeq ($(BOOT_CODE_IN_RAM),1) +CFLAGS_system_utils.o += -DBOOT_CODE_IN_RAM +endif + +ifeq ($(CHIP_HAS_PSRAM),1) +CFLAGS_system_utils.o += -DCHIP_HAS_PSRAM +endif +ifeq ($(PSRAM_ENABLE),1) +CFLAGS_system_utils.o += -DPSRAM_ENABLE +endif +ifeq ($(CHIP_HAS_PSRAMUHS),1) +CFLAGS_system_utils.o += -DCHIP_HAS_PSRAMUHS +endif +ifeq ($(PSRAMUHS_ENABLE),1) +CFLAGS_system_utils.o += -DPSRAMUHS_ENABLE +endif + +CFLAGS_retarget_armclang.o += \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/codec \ + -Iplatform/drivers/norflash + +ifeq ($(SPI_ROM_ONLY),1) +CFLAGS_retarget_armclang.o += -DSPI_ROM_ONLY +endif + diff --git a/platform/cmsis/ca/Makefile b/platform/cmsis/ca/Makefile new file mode 100644 index 0000000..1a9a5fc --- /dev/null +++ b/platform/cmsis/ca/Makefile @@ -0,0 +1,23 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S $(cur_dir)*.cpp)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) +obj-y := $(obj-y:.cpp=.o) + +ccflags-y := -I$(obj)/../inc/ca + +CFLAGS_mmu_ARMCA.o += -DFLASH_SIZE=$(FLASH_SIZE) +ifneq ($(PSRAM_SIZE),) +CFLAGS_mmu_ARMCA.o += -DPSRAM_SIZE=$(PSRAM_SIZE) +endif +ifneq ($(PSRAMUHS_SIZE),) +CFLAGS_mmu_ARMCA.o += -DPSRAMUHS_SIZE=$(PSRAMUHS_SIZE) +endif + +ifeq ($(CHIP_HAS_PSRAMUHS),1) +CFLAGS_system_ARMCA.o += -DCHIP_HAS_PSRAMUHS +ifeq ($(PSRAMUHS_ENABLE),1) +CFLAGS_system_ARMCA.o += -DPSRAMUHS_ENABLE +endif +endif diff --git a/platform/cmsis/ca/cmsis_gic.c b/platform/cmsis/ca/cmsis_gic.c new file mode 100644 index 0000000..3a345e7 --- /dev/null +++ b/platform/cmsis/ca/cmsis_gic.c @@ -0,0 +1,192 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis.h" + +#if defined(__GIC_PRESENT) && (__GIC_PRESENT) + +#include "cmsis_nvic.h" +#include "plat_types.h" +#include "plat_addr_map.h" +#include "hal_location.h" + +extern void Reset_Handler(void); +extern void Undef_Handler(void); +extern void SVC_Handler(void); +extern void PAbt_Handler(void); +extern void DAbt_Handler(void); +extern void IRQ_Handler(void); +extern void FIQ_Handler(void); + +struct VECTOR_HDLR_T { + uint32_t reset_hdlr; + uint32_t undef_hdlr; + uint32_t svc_hdlr; + uint32_t pabt_hdlr; + uint32_t dabt_hdlr; + uint32_t hyp_hdlr; + uint32_t irq_hdlr; + uint32_t fiq_hdlr; +}; + +static struct VECTOR_HDLR_T * const exc_vector = (struct VECTOR_HDLR_T *)(DSP_BOOT_REG + 0x20); + +static IRQn_ID_t cur_act_irq = EXCEPTION_NONE; +static uint32_t cur_irq_level; + +static GIC_FAULT_DUMP_HANDLER_T dump_hdlr; + +void c_irq_handler(void) +{ + const IRQn_ID_t irqn = IRQ_GetActiveIRQ(); + const IRQn_ID_t old_irq = cur_act_irq; + + cur_irq_level++; + cur_act_irq = irqn; + + IRQHandler_t const handler = IRQ_GetHandler(irqn); + if (handler != NULL) { + __enable_irq(); + handler(); + __disable_irq(); + } + IRQ_EndOfInterrupt(irqn); + + cur_act_irq = old_irq; + cur_irq_level--; +} + +void c_undef_handler(uint32_t opcode, uint32_t state, const struct FAULT_REGS_T *regs) +{ + const IRQn_ID_t old_irq = cur_act_irq; + cur_act_irq = EXCEPTION_UNDEF; + + if (dump_hdlr) { + struct UNDEF_FAULT_INFO_T info; + + info.id = cur_act_irq; + info.opcode = opcode; + info.state = state; + dump_hdlr((uint32_t *)regs, (uint32_t *)&info, sizeof(info)); + } + //ASSERT(false, "Undefined Instruction!"); + + cur_act_irq = old_irq; +} + +void c_svc_handler(uint32_t svc_num, const struct FAULT_REGS_T *regs) +{ + const IRQn_ID_t old_irq = cur_act_irq; + cur_act_irq = EXCEPTION_SVC; + + if (dump_hdlr) { + struct SVC_FAULT_INFO_T info; + + info.id = cur_act_irq; + info.svc_num = svc_num; + dump_hdlr((uint32_t *)regs, (uint32_t *)&info, sizeof(info)); + } + //ASSERT(false, "SVC!"); + + cur_act_irq = old_irq; +} + +void c_pabt_handler(uint32_t IFSR, uint32_t IFAR, const struct FAULT_REGS_T *regs) +{ + const IRQn_ID_t old_irq = cur_act_irq; + cur_act_irq = EXCEPTION_PABT; + + if (dump_hdlr) { + struct PABT_FAULT_INFO_T info; + + info.id = cur_act_irq; + info.IFSR = IFSR; + info.IFAR = IFAR; + dump_hdlr((uint32_t *)regs, (uint32_t *)&info, sizeof(info)); + } + //ASSERT(false, "Prefetch Abort!"); + + cur_act_irq = old_irq; +} + +void c_dabt_handler(uint32_t DFSR, uint32_t DFAR, const struct FAULT_REGS_T *regs) +{ + const IRQn_ID_t old_irq = cur_act_irq; + cur_act_irq = EXCEPTION_DABT; + + if (dump_hdlr) { + struct DABT_FAULT_INFO_T info; + + info.id = cur_act_irq; + info.DFSR = DFSR; + info.DFAR = DFAR; + dump_hdlr((uint32_t *)regs, (uint32_t *)&info, sizeof(info)); + } + //ASSERT(false, "Data Abort!"); + + cur_act_irq = old_irq; +} + +void c_fiq_handler(void) +{ + c_irq_handler(); +} + +void GIC_DisableAllIRQs(void) +{ + int i; + + for (i = 0; i < (USER_IRQn_QTY + 31) / 32; i++) { + GICDistributor->ICENABLER[i] = ~0UL; + } +} +void NVIC_DisableAllIRQs(void) __attribute__((alias("GIC_DisableAllIRQs"))); + +void GIC_InitVectors(void) +{ + volatile uint32_t *boot = (volatile uint32_t *)DSP_BOOT_REG; + + // Unlock + boot[32] = 0xCAFE0001; + __DMB(); + + exc_vector->reset_hdlr = (uint32_t)Reset_Handler; + exc_vector->undef_hdlr = (uint32_t)Undef_Handler; + exc_vector->svc_hdlr = (uint32_t)SVC_Handler; + exc_vector->pabt_hdlr = (uint32_t)PAbt_Handler; + exc_vector->dabt_hdlr = (uint32_t)DAbt_Handler; + exc_vector->irq_hdlr = (uint32_t)IRQ_Handler; + exc_vector->fiq_hdlr = (uint32_t)FIQ_Handler; + + // Lock + __DMB(); + boot[32] = 0xCAFE0000; + __DMB(); +} +void NVIC_InitVectors(void) __attribute__((alias("GIC_InitVectors"))); + +void GIC_SetFaultDumpHandler(GIC_FAULT_DUMP_HANDLER_T handler) +{ + dump_hdlr = handler; +} + +IRQn_Type IRQ_GetCurrentActiveIRQ(void) +{ + return cur_act_irq; +} +IRQn_Type NVIC_GetCurrentActiveIRQ(void) __attribute__((alias("IRQ_GetCurrentActiveIRQ"))); + +#endif + diff --git a/platform/cmsis/ca/default_irq_ca.S b/platform/cmsis/ca/default_irq_ca.S new file mode 100644 index 0000000..d7fb921 --- /dev/null +++ b/platform/cmsis/ca/default_irq_ca.S @@ -0,0 +1,290 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + .syntax unified + .align 4 + + .equ MODE_USR, 0x10 + .equ MODE_FIQ, 0x11 + .equ MODE_IRQ, 0x12 + .equ MODE_SVC, 0x13 + .equ MODE_ABT, 0x17 + .equ MODE_UND, 0x1B + .equ MODE_SYS, 0x1F + .equ MODE_MASK, 0x1F + + .equ CPSR_BIT_T, 0x20 + + .equ SAVED_REG_NUM, 17 + +//------------------------------------------------------- + .section ".text.IRQ_Handler" + .type IRQ_Handler, %function + .global IRQ_Handler + .weak IRQ_Handler + .fnstart + .cantunwind +IRQ_Handler: + SUB LR, LR, #4 // Pre-adjust LR + SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack + CPS #MODE_SVC // Change to SVC mode + PUSH {R0-R3, R12, LR} // Save APCS corruptible registers + + MOV R3, SP // Move SP into R3 + AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R3 // Adjust stack + PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4) + + BLX c_irq_handler + + POP {R3, R4} // Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 // Unadjust stack + + CLREX // Clear exclusive monitor for interrupted code + POP {R0-R3, R12, LR} // Restore stacked APCS registers + RFEFD SP! // Return from IRQ handler + + .fnend + .size IRQ_Handler, .-IRQ_Handler + +//------------------------------------------------------- + .section ".text.Save_Registers" + .type Save_Registers, %function + .fnstart + .cantunwind +Save_Registers: + PUSH {R12} + SUB SP, SP, #SAVED_REG_NUM*4 + + // Save r0-r7 + STMFD SP, {R0-R7} + + // Switch to the mode in SPSR + LDR R12,[SP, #(SAVED_REG_NUM+2)*4] + MRS R1, CPSR + AND R2, R1, #MODE_MASK + BIC R3, R1, #MODE_MASK + AND R0, R12, #MODE_MASK + CMP R0, #MODE_USR + MOVEQ R0, #MODE_SYS + ORR R3, R3, R0 + MSR CPSR, R3 + + // Save r8-r14 + ADD R0, SP, #8*4 + STMFD R0, {R8-R14} + + // Switch back to the original CPSR + MSR CPSR, R1 + + // LR already saved by SRSFD + LDR R2, [SP, #(SAVED_REG_NUM+1)*4] + + // Save pc, spsr + STR R2, [SP, #15*4] + STR R12,[SP, #16*4] + + BX LR + + .fnend + .size Save_Registers, .-Save_Registers + +//------------------------------------------------------- + .section ".text.Restore_Registers" + .type Restore_Registers, %function + .fnstart + .cantunwind +Restore_Registers: + // Restore APCS corruptible registers + LDMFD SP, {R0-R3} + ADD SP, SP, #SAVED_REG_NUM*4 + POP {R12} + BX LR + + .fnend + .size Restore_Registers, .-Restore_Registers + +//------------------------------------------------------- + .section ".text.SVC_Handler" + .type SVC_Handler, %function + .global SVC_Handler + .weak SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + SRSFD SP!, #MODE_SVC // Store SPSR_svc and LR_svc onto SVC stack + + BLX Save_Registers + + MRS R12, SPSR // Load SPSR + TST R12, #CPSR_BIT_T // Thumb bit set? + LDRHNE R12, [LR,#-2] // Thumb: load halfword + BICNE R12, R12, #0xFF00 // extract SVC number + LDREQ R12, [LR,#-4] // ARM: load word + BICEQ R12, R12, #0xFF000000 // extract SVC number + MOV R0, R12 // Save SVC number + + MOV R1, SP + + MOV R3, SP // Move SP into R3 + AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R3 // Adjust stack + PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4) + + BLX c_svc_handler // Call SVC Function + + POP {R3, R4} // Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 // Unadjust stack + + BLX Restore_Registers + CLREX // Clear exclusive monitor + RFEFD SP! // Return from exception + + .fnend + .size SVC_Handler, .-SVC_Handler + +//------------------------------------------------------- + .section ".text.Undef_Handler" + .type Undef_Handler, %function + .global Undef_Handler + .weak Undef_Handler + .fnstart + .cantunwind +Undef_Handler: + SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack + CPS #MODE_SVC // Change to SVC mode + + BLX Save_Registers + + TST R12,#CPSR_BIT_T // Check mode + MOVEQ R1, #4 // R1 = 4 ARM mode + MOVNE R1, #2 // R1 = 2 Thumb mode + + // Get offending instruction address + LDR LR, [SP, #15*4] + SUB LR, LR, R1 + STR LR, [SP, #15*4] + + SUB R0, LR, R1 + CMP R1, 4 + LDREQ R0, [R0] // ARM mode - R0 points to offending instruction + BEQ Undef_Cont + + // Thumb instruction + // Determine if it is a 32-bit Thumb instruction + LDRH R0, [R0] + MOV R2, #0x1C + CMP R2, R0, LSR #11 + BHS Undef_Cont // 16-bit Thumb instruction + + // 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction + LDRH R2, [LR] + ORR R0, R2, R0, LSL #16 +Undef_Cont: + MOV R2, SP // Set SP to third argument + + AND R12, SP, #4 // Ensure stack is 8-byte aligned + SUB SP, SP, R12 // Adjust stack + PUSH {R12, LR} // Store stack adjustment and dummy LR + + // R0 =Offending instruction, R1 =2(Thumb) or =4(ARM) + BLX c_undef_handler + + POP {R12, LR} // Get stack adjustment & discard dummy LR + ADD SP, SP, R12 // Unadjust stack + + LDR LR, [SP, #15*4] // Restore stacked LR and possibly adjust for retry + PUSH {LR} + BLX Restore_Registers + POP {LR} + STR LR, [SP] + CLREX // Clear exclusive monitor + RFEFD SP! // Return from exception + + .fnend + .size Undef_Handler, .-Undef_Handler + +//------------------------------------------------------- + .section ".text.PAbt_Handler" + .type PAbt_Handler, %function + .global PAbt_Handler + .weak PAbt_Handler + .fnstart + .cantunwind +PAbt_Handler: + SUB LR, LR, #4 // Pre-adjust LR + SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack + CPS #MODE_SVC // Change to SVC mode + + BLX Save_Registers + + MRC p15, 0, R0, c5, c0, 1 // IFSR + MRC p15, 0, R1, c6, c0, 2 // IFAR + + MOV R2, SP // Set SP to third argument + + AND R12, SP, #4 // Ensure stack is 8-byte aligned + SUB SP, SP, R12 // Adjust stack + PUSH {R12, LR} // Store stack adjustment and dummy LR + + BLX c_pabt_handler + + POP {R12, LR} // Get stack adjustment & discard dummy LR + ADD SP, SP, R12 // Unadjust stack + + CLREX // Clear exclusive monitor + BLX Restore_Registers + RFEFD SP! // Return from exception + + .fnend + .size PAbt_Handler, .-PAbt_Handler + +//------------------------------------------------------- + .section ".text.DAbt_Handler" + .type DAbt_Handler, %function + .global DAbt_Handler + .weak DAbt_Handler + .fnstart + .cantunwind +DAbt_Handler: + SUB LR, LR, #8 // Pre-adjust LR + SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack + CPS #MODE_SVC // Change to SVC mode + + BLX Save_Registers + + MRC p15, 0, R0, c5, c0, 0 // DFSR + MRC p15, 0, R1, c6, c0, 0 // DFAR + + MOV R2, SP // Set SP to third argument + + AND R12, SP, #4 // Ensure stack is 8-byte aligned + SUB SP, SP, R12 // Adjust stack + PUSH {R12, LR} // Store stack adjustment and dummy LR + + BLX c_dabt_handler + + POP {R12, LR} // Get stack adjustment & discard dummy LR + ADD SP, SP, R12 // Unadjust stack + + CLREX // Clear exclusive monitor + BLX Restore_Registers + RFEFD SP! // Return from exception + + .fnend + .size DAbt_Handler, .-DAbt_Handler + + .end diff --git a/platform/cmsis/ca/irq_ctrl_gic.c b/platform/cmsis/ca/irq_ctrl_gic.c new file mode 100644 index 0000000..ea39380 --- /dev/null +++ b/platform/cmsis/ca/irq_ctrl_gic.c @@ -0,0 +1,405 @@ +/**************************************************************************//** + * @file irq_ctrl_gic.c + * @brief Interrupt controller handling implementation for GIC + * @version V1.0.1 + * @date 9. April 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017 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 "cmsis.h" +#include "irq_ctrl.h" + +#if defined(__GIC_PRESENT) && (__GIC_PRESENT == 1U) + +/// Number of implemented interrupt lines +#define IRQ_GIC_LINE_COUNT USER_IRQn_QTY + +static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U }; +static uint32_t IRQ_ID0; + +/// Initialize interrupt controller. +__WEAK int32_t IRQ_Initialize (void) { + uint32_t i; + + for (i = 0U; i < IRQ_GIC_LINE_COUNT; i++) { + IRQTable[i] = (IRQHandler_t)NULL; + } + GIC_Enable(); + return (0); +} + + +/// Register interrupt handler. +__WEAK int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + IRQTable[irqn] = handler; + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get the registered interrupt handler. +__WEAK IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) { + IRQHandler_t h; + + // Ignore CPUID field (software generated interrupts) + irqn &= 0x3FFU; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + h = IRQTable[irqn]; + } else { + h = (IRQHandler_t)0; + } + + return (h); +} + + +/// Enable interrupt. +__WEAK int32_t IRQ_Enable (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_EnableIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Disable interrupt. +__WEAK int32_t IRQ_Disable (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_DisableIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get interrupt enable state. +__WEAK uint32_t IRQ_GetEnableState (IRQn_ID_t irqn) { + uint32_t enable; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + enable = GIC_GetEnableIRQ((IRQn_Type)irqn); + } else { + enable = 0U; + } + + return (enable); +} + + +/// Configure interrupt request mode. +__WEAK int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode) { + uint32_t val; + uint8_t cfg; + uint8_t secure; + uint8_t cpu; + int32_t status = 0; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + // Check triggering mode + val = (mode & IRQ_MODE_TRIG_Msk); + + if (val == IRQ_MODE_TRIG_LEVEL) { + cfg = 0x00U; + } else if (val == IRQ_MODE_TRIG_EDGE) { + cfg = 0x02U; + } else { + cfg = 0x00U; + status = -1; + } + + // Check interrupt type + val = mode & IRQ_MODE_TYPE_Msk; + + if (val != IRQ_MODE_TYPE_IRQ) { + status = -1; + } + + // Check interrupt domain + val = mode & IRQ_MODE_DOMAIN_Msk; + + if (val == IRQ_MODE_DOMAIN_NONSECURE) { + secure = 0U; + } else { + // Check security extensions support + val = GIC_DistributorInfo() & (1UL << 10U); + + if (val != 0U) { + // Security extensions are supported + secure = 1U; + } else { + secure = 0U; + status = -1; + } + } + + // Check interrupt CPU targets + val = mode & IRQ_MODE_CPU_Msk; + + if (val == IRQ_MODE_CPU_ALL) { + cpu = 0xFFU; + } else { + cpu = val >> IRQ_MODE_CPU_Pos; + } + + // Apply configuration if no mode error + if (status == 0) { + GIC_SetConfiguration((IRQn_Type)irqn, cfg); + GIC_SetTarget ((IRQn_Type)irqn, cpu); + + if (secure != 0U) { + GIC_SetGroup ((IRQn_Type)irqn, secure); + } + } + } + + return (status); +} + + +/// Get interrupt mode configuration. +__WEAK uint32_t IRQ_GetMode (IRQn_ID_t irqn) { + uint32_t mode; + uint32_t val; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + mode = IRQ_MODE_TYPE_IRQ; + + // Get trigger mode + val = GIC_GetConfiguration((IRQn_Type)irqn); + + if ((val & 2U) != 0U) { + // Corresponding interrupt is edge triggered + mode |= IRQ_MODE_TRIG_EDGE; + } else { + // Corresponding interrupt is level triggered + mode |= IRQ_MODE_TRIG_LEVEL; + } + + // Get interrupt CPU targets + mode |= GIC_GetTarget ((IRQn_Type)irqn) << IRQ_MODE_CPU_Pos; + + } else { + mode = IRQ_MODE_ERROR; + } + + return (mode); +} + + +/// Get ID number of current interrupt request (IRQ). +__WEAK IRQn_ID_t IRQ_GetActiveIRQ (void) { + IRQn_ID_t irqn; + uint32_t prio; + + /* Dummy read to avoid GIC 390 errata 801120 */ + GIC_GetHighPendingIRQ(); + + irqn = GIC_AcknowledgePending(); + + __DSB(); + + /* Workaround GIC 390 errata 733075 (GIC-390_Errata_Notice_v6.pdf, 09-Jul-2014) */ + /* The following workaround code is for a single-core system. It would be */ + /* different in a multi-core system. */ + /* If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up */ + /* so unlock it, otherwise service the interrupt as normal. */ + /* Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 */ + /* so will not occur here. */ + + if ((irqn == 0) || (irqn >= 0x3FE)) { + /* Unlock the CPU interface with a dummy write to Interrupt Priority Register */ + prio = GIC_GetPriority((IRQn_Type)0); + GIC_SetPriority ((IRQn_Type)0, prio); + + __DSB(); + + if ((irqn == 0U) && ((GIC_GetIRQStatus ((IRQn_Type)irqn) & 1U) != 0U) && (IRQ_ID0 == 0U)) { + /* If the ID is 0, is active and has not been seen before */ + IRQ_ID0 = 1U; + } + /* End of Workaround GIC 390 errata 733075 */ + } + + return (irqn); +} + + +/// Get ID number of current fast interrupt request (FIQ). +__WEAK IRQn_ID_t IRQ_GetActiveFIQ (void) { + return ((IRQn_ID_t)-1); +} + + +/// Signal end of interrupt processing. +__WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) { + int32_t status; + IRQn_Type irq = (IRQn_Type)irqn; + + irqn &= 0x3FFU; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_EndInterrupt (irq); + + if (irqn == 0) { + IRQ_ID0 = 0U; + } + + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Set interrupt pending flag. +__WEAK int32_t IRQ_SetPending (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_SetPendingIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + +/// Get interrupt pending flag. +__WEAK uint32_t IRQ_GetPending (IRQn_ID_t irqn) { + uint32_t pending; + + if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + pending = GIC_GetPendingIRQ ((IRQn_Type)irqn); + } else { + pending = 0U; + } + + return (pending & 1U); +} + + +/// Clear interrupt pending flag. +__WEAK int32_t IRQ_ClearPending (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_ClearPendingIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Set interrupt priority value. +__WEAK int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_SetPriority ((IRQn_Type)irqn, priority); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get interrupt priority. +__WEAK uint32_t IRQ_GetPriority (IRQn_ID_t irqn) { + uint32_t priority; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + priority = GIC_GetPriority ((IRQn_Type)irqn); + } else { + priority = IRQ_PRIORITY_ERROR; + } + + return (priority); +} + + +/// Set priority masking threshold. +__WEAK int32_t IRQ_SetPriorityMask (uint32_t priority) { + GIC_SetInterfacePriorityMask (priority); + return (0); +} + + +/// Get priority masking threshold +__WEAK uint32_t IRQ_GetPriorityMask (void) { + return GIC_GetInterfacePriorityMask(); +} + + +/// Set priority grouping field split point +__WEAK int32_t IRQ_SetPriorityGroupBits (uint32_t bits) { + int32_t status; + + if (bits == IRQ_PRIORITY_Msk) { + bits = 7U; + } + + if (bits < 8U) { + GIC_SetBinaryPoint (7U - bits); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get priority grouping field split point +__WEAK uint32_t IRQ_GetPriorityGroupBits (void) { + uint32_t bp; + + bp = GIC_GetBinaryPoint() & 0x07U; + + return (7U - bp); +} + +#endif diff --git a/platform/cmsis/ca/mmu_ARMCA.c b/platform/cmsis/ca/mmu_ARMCA.c new file mode 100644 index 0000000..4cbc705 --- /dev/null +++ b/platform/cmsis/ca/mmu_ARMCA.c @@ -0,0 +1,323 @@ +/**************************************************************************//** + * @file mmu_ARMCA7.c + * @brief MMU Configuration for Arm Cortex-A7 Device Series + * @version V1.2.0 + * @date 15. May 2019 + * + * @note + * + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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. + */ + +/* Memory map description from: DUI0447G_v2m_p1_trm.pdf 4.2.2 Arm Cortex-A Series memory map + + Memory Type +0xffffffff |--------------------------| ------------ + | FLAG SYNC | Device Memory +0xfffff000 |--------------------------| ------------ + | Fault | Fault +0xfff00000 |--------------------------| ------------ + | | Normal + | | + | Daughterboard | + | memory | + | | +0x80505000 |--------------------------| ------------ + |TTB (L2 Sync Flags ) 4k | Normal +0x80504C00 |--------------------------| ------------ + |TTB (L2 Peripherals-B) 16k| Normal +0x80504800 |--------------------------| ------------ + |TTB (L2 Peripherals-A) 16k| Normal +0x80504400 |--------------------------| ------------ + |TTB (L2 Priv Periphs) 4k | Normal +0x80504000 |--------------------------| ------------ + | TTB (L1 Descriptors) | Normal +0x80500000 |--------------------------| ------------ + | Stack | Normal + |--------------------------| ------------ + | Heap | Normal +0x80400000 |--------------------------| ------------ + | ZI Data | Normal +0x80300000 |--------------------------| ------------ + | RW Data | Normal +0x80200000 |--------------------------| ------------ + | RO Data | Normal + |--------------------------| ------------ + | RO Code | USH Normal +0x80000000 |--------------------------| ------------ + | Daughterboard | Fault + | HSB AXI buses | +0x40000000 |--------------------------| ------------ + | Daughterboard | Fault + | test chips peripherals | +0x2c002000 |--------------------------| ------------ + | Private Address | Device Memory +0x2c000000 |--------------------------| ------------ + | Daughterboard | Fault + | test chips peripherals | +0x20000000 |--------------------------| ------------ + | Peripherals | Device Memory RW/RO + | | & Fault +0x00000000 |--------------------------| +*/ + +// L1 Cache info and restrictions about architecture of the caches (CCSIR register): +// Write-Through support *not* available +// Write-Back support available. +// Read allocation support available. +// Write allocation support available. + +//Note: You should use the Shareable attribute carefully. +//For cores without coherency logic (such as SCU) marking a region as shareable forces the processor to not cache that region regardless of the inner cache settings. +//Cortex-A versions of RTX use LDREX/STREX instructions relying on Local monitors. Local monitors will be used only when the region gets cached, regions that are not cached will use the Global Monitor. +//Some Cortex-A implementations do not include Global Monitors, so wrongly setting the attribute Shareable may cause STREX to fail. + +//Recall: When the Shareable attribute is applied to a memory region that is not Write-Back, Normal memory, data held in this region is treated as Non-cacheable. +//When SMP bit = 0, Inner WB/WA Cacheable Shareable attributes are treated as Non-cacheable. +//When SMP bit = 1, Inner WB/WA Cacheable Shareable attributes are treated as Cacheable. + + +//Following MMU configuration is expected +//SCTLR.AFE == 1 (Simplified access permissions model - AP[2:1] define access permissions, AP[0] is an access flag) +//SCTLR.TRE == 0 (TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor) +//Domain 0 is always the Client domain +//Descriptors should place all memory in domain 0 + +#include "cmsis.h" +#include "mem_ARMCA.h" +#include "plat_types.h" + +extern uint32_t __sync_flags_start[]; +extern uint32_t __sync_flags_end[]; + +#define SECTION_SIZE 0x00100000 +#define SECTION_ADDR(n) ((n) & 0xFFF00000) +#define SECTION_CNT(n) (((n) + SECTION_SIZE - 1) / SECTION_SIZE) + +#define PAGE16K_SIZE 0x00004000 +#define PAGE16K_ADDR(n) ((n) & 0xFFFFC000) +#define PAGE16K_CNT(n) (((n) + PAGE16K_SIZE - 1) / PAGE16K_SIZE) + +#define PAGE4K_SIZE 0x00001000 +#define PAGE4K_ADDR(n) ((n) & 0xFFFFF000) +#define PAGE4K_CNT(n) (((n) + PAGE4K_SIZE - 1) / PAGE4K_SIZE) + +// TTB base address +#define TTB_BASE (l1) + +// L2 table pointers +//---------------------------------------- +#define TTB_L1_SIZE (0x00004000) // The L1 translation table divides the full 4GB address space of a 32-bit core + // into 4096 equally sized sections, each of which describes 1MB of virtual memory space. + // The L1 translation table therefore contains 4096 32-bit (word-sized) entries. + +#define PRIVATE_TABLE_L2_4K_SIZE (0x400) +#define PERIPHERAL_A_TABLE_L2_4K_SIZE (0x400) +#define PERIPHERAL_B_TABLE_L2_64K_SIZE (0x400) +#define SYNC_FLAGS_TABLE_L2_4K_SIZE (0x400) + +#define PRIVATE_TABLE_L2_BASE_4k (l2.pri) // Map 4k Private Address space +#define PERIPHERAL_A_TABLE_L2_BASE_4k (l2.periph_a) // Map 64k Peripheral #1 0x1C000000 - 0x1C00FFFFF +#define PERIPHERAL_B_TABLE_L2_BASE_64k (l2.periph_b) // Map 64k Peripheral #2 0x1C100000 - 0x1C1FFFFFF +#define SYNC_FLAGS_TABLE_L2_BASE_4k (l2.sync) // Map 4k Flag synchronization + +//--------------------- PERIPHERALS ------------------- +//#define PERIPHERAL_A_FAULT (0x00000000 + 0x1c000000) //0x1C000000-0x1C00FFFF (1M) +//#define PERIPHERAL_B_FAULT (0x00100000 + 0x1c000000) //0x1C100000-0x1C10FFFF (1M) + +//--------------------- SYNC FLAGS -------------------- +//#define FLAG_SYNC 0xFFFFF000 +//#define F_SYNC_BASE 0xFFF00000 //1M aligned +#define SYNC_FLAG_SIZE ((uint32_t)__sync_flags_end - (uint32_t)__sync_flags_start) +#define FLAG_SYNC ((uint32_t)__sync_flags_start) + +static uint32_t Sect_Normal; //outer & inner wb/wa, non-shareable, executable, rw, domain 0, base addr 0 +static uint32_t Sect_Normal_Cod; //outer & inner wb/wa, non-shareable, executable, ro, domain 0, base addr 0 +static uint32_t Sect_Normal_RO; //as Sect_Normal_Cod, but not executable +static uint32_t Sect_Normal_RW; //as Sect_Normal_Cod, but writeable and not executable +static uint32_t Sect_Device_RO; //device, non-shareable, non-executable, ro, domain 0, base addr 0 +static uint32_t Sect_Device_RW; //as Sect_Device_RO, but writeable + +static uint32_t Sect_Normal_NC; //outer & inner uncached, non-shareable, executable, rw, domain 0, base addr 0 +static uint32_t Sect_Normal_RO_NC; //outer & inner uncached, non-shareable, executable, ro, domain 0, base addr 0 + +/* Define global descriptors */ +static uint32_t Page_L1_4k = 0x0; //generic +static uint32_t Page_L1_64k = 0x0; //generic +static uint32_t Page_4k_Device_RW; //Shared device, not executable, rw, domain 0 +static uint32_t Page_64k_Device_RW; //Shared device, not executable, rw, domain 0 + +static uint32_t Page_4k_Normal; //outer & inner wb/wa, non-shareable, executable, rw, domain 0 + +struct TTB_L2_T { + uint32_t pri[PRIVATE_TABLE_L2_4K_SIZE / 4]; + uint32_t periph_a[PERIPHERAL_A_TABLE_L2_4K_SIZE / 4]; + uint32_t periph_b[PERIPHERAL_B_TABLE_L2_64K_SIZE / 4]; + uint32_t sync[SYNC_FLAGS_TABLE_L2_4K_SIZE / 4]; +}; + +__attribute__((section(".ttb_l1"), aligned(0x4000))) +static uint32_t l1[TTB_L1_SIZE / 4]; +__attribute__((section(".ttb_l2"), aligned(0x400))) +static struct TTB_L2_T l2; + +void MMU_CreateTranslationTable(void) +{ + mmu_region_attributes_Type region; + + //Create 4GB of faulting entries + MMU_TTSection (TTB_BASE, 0, 4096, DESCRIPTOR_FAULT); + + /* + * Generate descriptors. Refer to core_ca.h to get information about attributes + * + */ + //Create descriptors for Vectors, RO, RW, ZI sections + section_normal(Sect_Normal, region); + section_normal_cod(Sect_Normal_Cod, region); + section_normal_ro(Sect_Normal_RO, region); + section_normal_rw(Sect_Normal_RW, region); + //Create descriptors for peripherals + section_device_ro(Sect_Device_RO, region); + section_device_rw(Sect_Device_RW, region); + //Create descriptors for 64k pages + page64k_device_rw(Page_L1_64k, Page_64k_Device_RW, region); + //Create descriptors for 4k pages + page4k_device_rw(Page_L1_4k, Page_4k_Device_RW, region); + page4k_normal(Page_L1_4k, Page_4k_Normal, region); + + section_normal_nc(Sect_Normal_NC, region); + section_normal_ro_nc(Sect_Normal_RO_NC, region); + + /* + * Define MMU flat-map regions and attributes + * + */ + + //Define Image + MMU_TTSection (TTB_BASE, FLASH_BASE , SECTION_CNT(FLASH_SIZE) , Sect_Normal_Cod); // multiple of 1MB sections + MMU_TTSection (TTB_BASE, FLASH_NC_BASE , SECTION_CNT(FLASH_SIZE) , Sect_Normal_RO_NC); // multiple of 1MB sections +#ifdef PSRAM_SIZE + MMU_TTSection (TTB_BASE, PSRAM_BASE , SECTION_CNT(PSRAM_SIZE) , Sect_Normal); // multiple of 1MB sections + MMU_TTSection (TTB_BASE, PSRAM_NC_BASE , SECTION_CNT(PSRAM_SIZE) , Sect_Normal_NC); // multiple of 1MB sections +#endif +#ifdef PSRAMUHS_SIZE + MMU_TTSection (TTB_BASE, PSRAMUHS_BASE , SECTION_CNT(PSRAMUHS_SIZE) , Sect_Normal); // multiple of 1MB sections + MMU_TTSection (TTB_BASE, PSRAMUHS_NC_BASE , SECTION_CNT(PSRAMUHS_SIZE) , Sect_Normal_NC); // multiple of 1MB sections + MMU_TTSection (TTB_BASE, PSRAMUHSX_BASE , SECTION_CNT(PSRAMUHS_SIZE) , Sect_Normal_Cod); // multiple of 1MB sections +#endif + + MMU_TTSection (TTB_BASE, DSP_RAM_BASE , SECTION_CNT(MAX_DSP_RAM_SIZE) , Sect_Normal); // multiple of 1MB sections + + MMU_TTSection (TTB_BASE, ROMD_BASE , 1 , Sect_Normal_Cod); // multiple of 1MB sections + MMU_TTSection (TTB_BASE, RAM_BASE , SECTION_CNT(MAX_RAM_SIZE) , Sect_Normal_NC); // multiple of 1MB sections + + + //--------------------- PERIPHERALS ------------------- + // Create (256 * 4k)=1MB faulting entries to cover peripheral range A + MMU_TTPage4k(TTB_BASE, SECTION_ADDR(DSP_BOOT_REG),256, Page_L1_4k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, DESCRIPTOR_FAULT); + // Define peripheral range A + MMU_TTPage4k(TTB_BASE, DSP_BOOT_REG , 1, Page_L1_4k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_4k_Normal); + MMU_TTPage4k(TTB_BASE, DSP_TRANSQM_BASE , 1, Page_L1_4k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_4k_Device_RW); + MMU_TTPage4k(TTB_BASE, DSP_TIMER0_BASE , 1, Page_L1_4k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_4k_Device_RW); + MMU_TTPage4k(TTB_BASE, DSP_TIMER1_BASE , 1, Page_L1_4k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_4k_Device_RW); + MMU_TTPage4k(TTB_BASE, DSP_WDT_BASE , 1, Page_L1_4k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_4k_Device_RW); + MMU_TTPage4k(TTB_BASE, DSP_DEBUGSYS_APB_BASE , 1, Page_L1_4k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_4k_Device_RW); + + MMU_TTSection (TTB_BASE, DSP_XDMA_BASE , 1, Sect_Device_RW); // multiple of 1MB sections + + MMU_TTSection (TTB_BASE, CMU_BASE , 1, Sect_Device_RW); // AHB0/APB0 + MMU_TTSection (TTB_BASE, CHECKSUM_BASE , 1, Sect_Device_RW); // AHB1 + MMU_TTSection (TTB_BASE, CODEC_BASE , 1, Sect_Device_RW); // CODEC + + MMU_TTSection (TTB_BASE, BT_RAM_BASE , 1, Sect_Device_RW); + MMU_TTSection (TTB_BASE, BT_CMU_BASE , 1, Sect_Device_RW); + + MMU_TTSection (TTB_BASE, WIFI_RAM_BASE , 1, Sect_Device_RW); + MMU_TTSection (TTB_BASE, WIFI_PAS_BASE , 1, Sect_Device_RW); + MMU_TTSection (TTB_BASE, WIFI_TRANSQM_BASE , 1, Sect_Device_RW); + +#if 0 + MMU_TTSection (TTB_BASE, VE_A7_MP_FLASH_BASE0 , 64, Sect_Device_RO); // 64MB NOR + MMU_TTSection (TTB_BASE, VE_A7_MP_FLASH_BASE1 , 64, Sect_Device_RO); // 64MB NOR + MMU_TTSection (TTB_BASE, VE_A7_MP_SRAM_BASE , 32, Sect_Device_RW); // 32MB RAM + MMU_TTSection (TTB_BASE, VE_A7_MP_VRAM_BASE , 32, Sect_Device_RW); // 32MB RAM + MMU_TTSection (TTB_BASE, VE_A7_MP_ETHERNET_BASE , 16, Sect_Device_RW); + MMU_TTSection (TTB_BASE, VE_A7_MP_USB_BASE , 16, Sect_Device_RW); + + // Create (16 * 64k)=1MB faulting entries to cover peripheral range 0x1C000000-0x1C00FFFF + MMU_TTPage64k(TTB_BASE, PERIPHERAL_A_FAULT , 16, Page_L1_64k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, DESCRIPTOR_FAULT); + // Define peripheral range 0x1C000000-0x1C00FFFF + MMU_TTPage64k(TTB_BASE, VE_A7_MP_DAP_BASE , 1, Page_L1_64k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_SYSTEM_REG_BASE, 1, Page_L1_64k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_SERIAL_BASE , 1, Page_L1_64k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_AACI_BASE , 1, Page_L1_64k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_MMCI_BASE , 1, Page_L1_64k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_KMI0_BASE , 2, Page_L1_64k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_UART_BASE , 4, Page_L1_64k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_WDT_BASE , 1, Page_L1_64k, (uint32_t *)PERIPHERAL_A_TABLE_L2_BASE_4k, Page_64k_Device_RW); + + // Create (16 * 64k)=1MB faulting entries to cover peripheral range 0x1C100000-0x1C10FFFF + MMU_TTPage64k(TTB_BASE, PERIPHERAL_B_FAULT , 16, Page_L1_64k, (uint32_t *)PERIPHERAL_B_TABLE_L2_BASE_64k, DESCRIPTOR_FAULT); + // Define peripheral range 0x1C100000-0x1C10FFFF + MMU_TTPage64k(TTB_BASE, VE_A7_MP_TIMER_BASE , 2, Page_L1_64k, (uint32_t *)PERIPHERAL_B_TABLE_L2_BASE_64k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_DVI_BASE , 1, Page_L1_64k, (uint32_t *)PERIPHERAL_B_TABLE_L2_BASE_64k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_RTC_BASE , 1, Page_L1_64k, (uint32_t *)PERIPHERAL_B_TABLE_L2_BASE_64k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_UART4_BASE , 1, Page_L1_64k, (uint32_t *)PERIPHERAL_B_TABLE_L2_BASE_64k, Page_64k_Device_RW); + MMU_TTPage64k(TTB_BASE, VE_A7_MP_CLCD_BASE , 1, Page_L1_64k, (uint32_t *)PERIPHERAL_B_TABLE_L2_BASE_64k, Page_64k_Device_RW); +#endif + + // Create (256 * 4k)=1MB faulting entries to cover private address space. Needs to be marked as Device memory + MMU_TTPage4k (TTB_BASE, __get_CBAR() ,256, Page_L1_4k, (uint32_t *)PRIVATE_TABLE_L2_BASE_4k, DESCRIPTOR_FAULT); + // Define private address space entry. + MMU_TTPage4k (TTB_BASE, __get_CBAR() , 3, Page_L1_4k, (uint32_t *)PRIVATE_TABLE_L2_BASE_4k, Page_4k_Device_RW); +#if 0 //defined(__L2C_PRESENT) && (__L2C_PRESENT) + // Define L2CC entry. Uncomment if PL310 is present + MMU_TTPage4k (TTB_BASE, VE_A5_MP_PL310_BASE , 1, Page_L1_4k, (uint32_t *)PRIVATE_TABLE_L2_BASE_4k, Page_4k_Device_RW); +#endif + +#if 0 + // Create (256 * 4k)=1MB faulting entries to synchronization space (Useful if some non-cacheable DMA agent is present in the SoC) + MMU_TTPage4k (TTB_BASE, F_SYNC_BASE , 256, Page_L1_4k, (uint32_t *)SYNC_FLAGS_TABLE_L2_BASE_4k, DESCRIPTOR_FAULT); + // Define synchronization space entry. + MMU_TTPage4k (TTB_BASE, FLAG_SYNC , 1, Page_L1_4k, (uint32_t *)SYNC_FLAGS_TABLE_L2_BASE_4k, Page_4k_Device_RW); +#endif + // Define synchronization space entry. + MMU_TTPage4k (TTB_BASE, SECTION_ADDR(FLAG_SYNC) , 256, Page_L1_4k, (uint32_t *)SYNC_FLAGS_TABLE_L2_BASE_4k, Page_4k_Normal); + // Define synchronization space entry. + MMU_TTPage4k (TTB_BASE, FLAG_SYNC , PAGE4K_CNT(SYNC_FLAG_SIZE), Page_L1_4k, (uint32_t *)SYNC_FLAGS_TABLE_L2_BASE_4k, Page_4k_Device_RW); + + /* Set location of level 1 page table + ; 31:14 - Translation table base addr (31:14-TTBCR.N, TTBCR.N is 0 out of reset) + ; 13:7 - 0x0 + ; 6 - IRGN[0] 0x1 (Inner WB WA) + ; 5 - NOS 0x0 (Non-shared) + ; 4:3 - RGN 0x01 (Outer WB WA) + ; 2 - IMP 0x0 (Implementation Defined) + ; 1 - S 0x0 (Non-shared) + ; 0 - IRGN[1] 0x0 (Inner WB WA) */ + __set_TTBR0((uint32_t)TTB_BASE | 0x48); + __ISB(); + + /* Set up domain access control register + ; We set domain 0 to Client and all other domains to No Access. + ; All translation table entries specify domain 0 */ + __set_DACR(1); + __ISB(); +} diff --git a/platform/cmsis/ca/startup_ARMCA.c b/platform/cmsis/ca/startup_ARMCA.c new file mode 100644 index 0000000..2779022 --- /dev/null +++ b/platform/cmsis/ca/startup_ARMCA.c @@ -0,0 +1,151 @@ +/****************************************************************************** + * @file startup_ARMCA7.c + * @brief CMSIS Device System Source File for Arm Cortex-A9 Device Series + * @version V1.00 + * @date 10. January 2018 + * + * @note + * + ******************************************************************************/ +/* + * 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. + */ + +#include "cmsis.h" +#include "plat_addr_map.h" + +/*---------------------------------------------------------------------------- + Definitions + *----------------------------------------------------------------------------*/ +#define USR_MODE 0x10 // User mode +#define FIQ_MODE 0x11 // Fast Interrupt Request mode +#define IRQ_MODE 0x12 // Interrupt Request mode +#define SVC_MODE 0x13 // Supervisor mode +#define ABT_MODE 0x17 // Abort mode +#define UND_MODE 0x1B // Undefined Instruction mode +#define SYS_MODE 0x1F // System mode + +/*---------------------------------------------------------------------------- + Internal References + *----------------------------------------------------------------------------*/ +void Vectors (void) __attribute__ ((naked, target("arm"), section(".vectors"))); +void Reset_Handler (void) __attribute__ ((naked, section(".boot_loader"))); + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler + *----------------------------------------------------------------------------*/ +void Undef_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void PAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void DAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void IRQ_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); +void FIQ_Handler (void) __attribute__ ((weak, alias("Default_Handler"))); + +/*---------------------------------------------------------------------------- + Exception / Interrupt Vector Table + *----------------------------------------------------------------------------*/ +void Vectors(void) { + __ASM volatile( + "LDR PC, ResetVectorPtr \n" + "LDR PC, UndefVectorPtr \n" + "LDR PC, SVCVectorPtr \n" + "LDR PC, PAbtVectorPtr \n" + "LDR PC, DAbtVectorPtr \n" + "LDR PC, HypVectorPtr \n" + "LDR PC, IRQVectorPtr \n" + "LDR PC, FIQVectorPtr \n" + "ResetVectorPtr: .LONG Init_Handler \n" + "UndefVectorPtr: .LONG Init_Handler \n" + "SVCVectorPtr: .LONG Init_Handler \n" + "PAbtVectorPtr: .LONG Init_Handler \n" + "DAbtVectorPtr: .LONG Init_Handler \n" + "HypVectorPtr: .LONG Init_Handler \n" + "IRQVectorPtr: .LONG Init_Handler \n" + "FIQVectorPtr: .LONG Init_Handler \n" + "Init_Handler: b Init_Handler \n" + ); +} + +/*---------------------------------------------------------------------------- + Reset Handler called on controller reset + *----------------------------------------------------------------------------*/ +void Reset_Handler(void) { + __ASM volatile( + + // Mask interrupts + "CPSID if \n" + + // Put any cores other than 0 to sleep + "MRC p15, 0, R0, c0, c0, 5 \n" // Read MPIDR + "ANDS R0, R0, #3 \n" + "goToSleep: \n" + "IT NE \n" + "WFINE \n" + "BNE goToSleep \n" + + // Reset SCTLR Settings + "MRC p15, 0, R0, c1, c0, 0 \n" // Read CP15 System Control register + "BIC R0, R0, #(0x1 << 12) \n" // Clear I bit 12 to disable I Cache + "BIC R0, R0, #(0x1 << 2) \n" // Clear C bit 2 to disable D Cache + "BIC R0, R0, #0x1 \n" // Clear M bit 0 to disable MMU + "BIC R0, R0, #(0x1 << 11) \n" // Clear Z bit 11 to disable branch prediction + "BIC R0, R0, #(0x1 << 13) \n" // Clear V bit 13 to disable hivecs + "MCR p15, 0, R0, c1, c0, 0 \n" // Write value back to CP15 System Control register + "ISB \n" + + // Configure ACTLR + "MRC p15, 0, r0, c1, c0, 1 \n" // Read CP15 Auxiliary Control Register + //"ORR r0, r0, #(1 << 1) \n" // Enable L2 prefetch hint (UNK/WI since r4p1) + "ORR r0, r0, #(1 << 6) \n" // Enable SMP + "MCR p15, 0, r0, c1, c0, 1 \n" // Write CP15 Auxiliary Control Register + + // Set Vector Base Address Register (VBAR) to point to this application's vector table + //"LDR R0, =Vectors \n" + "LDR R0, =" _TO_STRING(DSP_BOOT_REG) " \n" + "MCR p15, 0, R0, c12, c0, 0 \n" + + // Setup Stack for each exceptional mode + "CPS #0x11 \n" + "LDR SP, =Image$$FIQ_STACK$$ZI$$Limit \n" + "CPS #0x12 \n" + "LDR SP, =Image$$IRQ_STACK$$ZI$$Limit \n" + "CPS #0x13 \n" + "LDR SP, =Image$$SVC_STACK$$ZI$$Limit \n" + "CPS #0x17 \n" + "LDR SP, =Image$$ABT_STACK$$ZI$$Limit \n" + "CPS #0x1B \n" + "LDR SP, =Image$$UND_STACK$$ZI$$Limit \n" + "CPS #0x1F \n" + "LDR SP, =Image$$SYS_STACK$$ZI$$Limit \n" + + // Call SystemInit + "BL SystemInit \n" + + // Unmask interrupts + "CPSIE if \n" + + // Call __main + "BL _start \n" + ); +} + +/*---------------------------------------------------------------------------- + Default Handler for Exceptions / Interrupts + *----------------------------------------------------------------------------*/ +void Default_Handler(void) { + while(1); +} diff --git a/platform/cmsis/ca/system_ARMCA.c b/platform/cmsis/ca/system_ARMCA.c new file mode 100644 index 0000000..eef3457 --- /dev/null +++ b/platform/cmsis/ca/system_ARMCA.c @@ -0,0 +1,136 @@ +/****************************************************************************** + * @file system_ARMCA7.c + * @brief CMSIS Device System Source File for Arm Cortex-A7 Device Series + * @version V1.0.1 + * @date 13. February 2019 + * + * @note + * + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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 "cmsis_nvic.h" +#include "ca/system_ARMCA.h" +#include "ca/irq_ctrl.h" +#include "hal_location.h" +#include "hal_cmu.h" + +extern uint32_t __sram_text_data_start_load__[]; +extern uint32_t __sram_text_data_end_load__[]; +extern uint32_t __sram_text_data_start__[]; +extern uint32_t __sram_bss_start__[]; +extern uint32_t __sram_bss_end__[]; +extern uint32_t __bss_start__[]; +extern uint32_t __bss_end__[]; +extern uint32_t __sync_flags_start[]; +extern uint32_t __sync_flags_end[]; +extern uint32_t __psramuhs_text_data_start_load__[]; +extern uint32_t __psramuhs_text_data_end_load__[]; +extern uint32_t __psramuhs_text_start[]; + +/*---------------------------------------------------------------------------- + System Initialization + *----------------------------------------------------------------------------*/ +void SystemInit (void) +{ + uint32_t *dst, *src; + + if (__sram_text_data_start__ != __sram_text_data_start_load__) { + for (dst = __sram_text_data_start__, src = __sram_text_data_start_load__; + src < __sram_text_data_end_load__; + dst++, src++) { + *dst = *src; + } + } + + hal_cmu_dsp_setup(); + /*psramhus_test load region covers sram_bss, and it needs to be copyed first*/ +#if defined(CHIP_HAS_PSRAMUHS) && defined(PSRAMUHS_ENABLE) + for (dst = __psramuhs_text_start, src = __psramuhs_text_data_start_load__; + src < __psramuhs_text_data_end_load__; + dst++, src++) { + *dst = *src; + } +#endif + + for (dst = __sram_bss_start__; dst < __sram_bss_end__; dst++) { + *dst = 0; + } + +#ifdef NOSTD + for (dst = __bss_start__; dst < __bss_end__; dst++) { + *dst = 0; + } +#endif + + for (dst = __sync_flags_start; dst < __sync_flags_end; dst++) { + *dst = 0; + } + +/* do not use global variables because this function is called before + reaching pre-main. RW section may be overwritten afterwards. */ + + // Init exception vectors + GIC_InitVectors(); + + // Invalidate entire Unified TLB + __set_TLBIALL(0); + + // Invalidate entire branch predictor array + __set_BPIALL(0); + __DSB(); + __ISB(); + + // Invalidate instruction cache and flush branch target cache + __set_ICIALLU(0); + __DSB(); + __ISB(); + + // Invalidate data cache + L1C_InvalidateDCacheAll(); + +#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) + // Enable FPU + __FPU_Enable(); +#endif + + // Create Translation Table + MMU_CreateTranslationTable(); + + // Enable MMU + MMU_Enable(); + + // Enable Caches + L1C_EnableCaches(); + L1C_EnableBTAC(); + +#if (__L2C_PRESENT == 1) + // Enable GIC + L2C_Enable(); +#endif + + // IRQ Initialize + IRQ_Initialize(); +} + +uint32_t BOOT_TEXT_SRAM_DEF(get_cpu_id) (void) +{ + return __get_MPIDR() & 3; +} + diff --git a/platform/cmsis/cmsis_nvic.c b/platform/cmsis/cmsis_nvic.c new file mode 100644 index 0000000..468a72c --- /dev/null +++ b/platform/cmsis/cmsis_nvic.c @@ -0,0 +1,221 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2011 ARM Limited. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of ARM Limited nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef __ARM_ARCH_ISA_ARM + +#include "cmsis_nvic.h" +#include "plat_types.h" +#include "plat_addr_map.h" +#include "hal_location.h" +#ifdef __ARMCC_VERSION +#include "link_sym_armclang.h" +#endif + +STATIC_ASSERT(NVIC_NUM_VECTORS * 4 <= VECTOR_SECTION_SIZE, "ERROR: VECTOR_SECTION_SIZE too small!"); + +// The vector table must be aligned to NVIC_NUM_VECTORS-word boundary, rounding up to the next power of two +// -- 0x100 for 33~64 vectors, and 0x200 for 65~128 vectors +#ifdef __ARMCC_VERSION +#define VECTOR_LOC __attribute__((section(".bss.vector_table"))) +#else +#define VECTOR_LOC __attribute__((section(".vector_table"))) +#endif + +#define FAULT_HANDLER __attribute__((weak,alias("NVIC_default_handler"))) + +static uint32_t VECTOR_LOC vector_table[NVIC_NUM_VECTORS]; + +void NVIC_DisableAllIRQs(void) +{ + int i; + + for (i = 0; i < (USER_IRQn_QTY + 31) / 32; i++) { + NVIC->ICER[i] = ~0UL; + } + SCB->VTOR = 0; +} + +static void NAKED BOOT_TEXT_FLASH_LOC NVIC_default_handler(void) +{ + asm volatile("_loop:; nop; nop; nop; nop; b _loop;"); +} + +void FAULT_HANDLER Reset_Handler(void); +void FAULT_HANDLER NMI_Handler(void); +void FAULT_HANDLER HardFault_Handler(void); +void FAULT_HANDLER MemManage_Handler(void); +void FAULT_HANDLER BusFault_Handler(void); +void FAULT_HANDLER UsageFault_Handler(void); +void FAULT_HANDLER SecureFault_Handler(void); +void FAULT_HANDLER SVC_Handler(void); +void FAULT_HANDLER DebugMon_Handler(void); +void FAULT_HANDLER PendSV_Handler(void); +void FAULT_HANDLER SysTick_Handler(void); +extern uint32_t __rom_stack[]; +extern uint32_t __stack[]; + +static const uint32_t BOOT_RODATA_FLASH_LOC fault_handlers[NVIC_USER_IRQ_OFFSET] = { +#if defined(ROM_BUILD) && !defined(ROM_IN_FLASH) + (uint32_t)__rom_stack, +#else + (uint32_t)__stack, +#endif + (uint32_t)Reset_Handler, + (uint32_t)NMI_Handler, + (uint32_t)HardFault_Handler, + (uint32_t)MemManage_Handler, + (uint32_t)BusFault_Handler, + (uint32_t)UsageFault_Handler, + (uint32_t)SecureFault_Handler, + (uint32_t)NVIC_default_handler, + (uint32_t)NVIC_default_handler, + (uint32_t)NVIC_default_handler, + (uint32_t)SVC_Handler, + (uint32_t)DebugMon_Handler, + (uint32_t)NVIC_default_handler, + (uint32_t)PendSV_Handler, + (uint32_t)SysTick_Handler, +}; + +void BOOT_TEXT_FLASH_LOC NVIC_InitVectors(void) +{ + int i; + + for (i = 0; i < NVIC_NUM_VECTORS; i++) { + vector_table[i] = (i < ARRAY_SIZE(fault_handlers)) ? + fault_handlers[i] : (uint32_t)NVIC_default_handler; + } + + SCB->VTOR = (uint32_t)vector_table; + __DSB(); +} + +void NVIC_SetDefaultFaultHandler(NVIC_DEFAULT_FAULT_HANDLER_T handler) +{ + int i; + + for (i = 1; i < ARRAY_SIZE(fault_handlers); i++) { + if (vector_table[i] == (uint32_t)NVIC_default_handler) { + vector_table[i] = (uint32_t)handler; + } + } +} + +IRQn_Type NVIC_GetCurrentActiveIRQ(void) +{ + IRQn_Type irq = (__get_IPSR() & IPSR_ISR_Msk) - NVIC_USER_IRQ_OFFSET; + return irq; +} + +#ifdef CORE_SLEEP_POWER_DOWN + +void SRAM_TEXT_LOC NVIC_PowerDownSleep(uint32_t *buf, uint32_t cnt) +{ + int i; + uint32_t idx; + __IO uint32_t *regs; + + idx = 0; + for (i = 0; i < (NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET + 31) / 32; i++) { + buf[idx++] = NVIC->ISER[i]; + } +#if (__CORTEX_M <= 4) + regs = (__IO uint32_t *)&NVIC->IP[0]; +#else + regs = (__IO uint32_t *)&NVIC->IPR[0]; +#endif + for (i = 0; i < (NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET + 3) / 4; i++) { + buf[idx++] = regs[i]; + } + buf[idx++] = SCnSCB->ACTLR; + buf[idx++] = SCB->ICSR; + buf[idx++] = SCB->AIRCR; + buf[idx++] = SCB->SCR; + buf[idx++] = SCB->CCR; +#if (__CORTEX_M <= 4) + regs = (__IO uint32_t *)&SCB->SHP[0]; +#else + regs = (__IO uint32_t *)&SCB->SHPR[0]; +#endif + buf[idx++] = regs[0]; + buf[idx++] = regs[1]; + buf[idx++] = regs[2]; + buf[idx++] = SCB->SHCSR; + buf[idx++] = SysTick->CTRL; + buf[idx++] = SysTick->LOAD; + + if (idx > cnt) { + do { asm volatile("nop \n nop \n nop \n nop"); } while (1); + } +} + +void SRAM_TEXT_LOC NVIC_PowerDownWakeup(uint32_t *buf, uint32_t cnt) +{ + int i; + uint32_t idx; + __IO uint32_t *regs; + + idx = 0; + for (i = 0; i < (NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET + 31) / 32; i++) { + NVIC->ISER[i] = buf[idx++]; + } +#if (__CORTEX_M <= 4) + regs = (__IO uint32_t *)&NVIC->IP[0]; +#else + regs = (__IO uint32_t *)&NVIC->IPR[0]; +#endif + for (i = 0; i < (NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET + 3) / 4; i++) { + regs[i] = buf[idx++]; + } + SCnSCB->ACTLR = buf[idx++]; + SCB->ICSR = buf[idx++]; + SCB->AIRCR = buf[idx++]; + SCB->SCR = buf[idx++]; + SCB->CCR = buf[idx++]; +#if (__CORTEX_M <= 4) + regs = (__IO uint32_t *)&SCB->SHP[0]; +#else + regs = (__IO uint32_t *)&SCB->SHPR[0]; +#endif + regs[0] = buf[idx++]; + regs[1] = buf[idx++]; + regs[2] = buf[idx++]; + SCB->SHCSR = buf[idx++]; + SysTick->CTRL = buf[idx++]; + SysTick->LOAD = buf[idx++]; + + SCB->VTOR = (uint32_t)vector_table; + SysTick->VAL = 0; +} + +#endif + +#endif + diff --git a/platform/cmsis/inc/arm_common_tables.h b/platform/cmsis/inc/arm_common_tables.h new file mode 100644 index 0000000..dfea746 --- /dev/null +++ b/platform/cmsis/inc/arm_common_tables.h @@ -0,0 +1,121 @@ +/* ---------------------------------------------------------------------- + * 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" + +extern const uint16_t armBitRevTable[1024]; +extern const q15_t armRecipTableQ15[64]; +extern const q31_t armRecipTableQ31[64]; +extern const float32_t twiddleCoef_16[32]; +extern const float32_t twiddleCoef_32[64]; +extern const float32_t twiddleCoef_64[128]; +extern const float32_t twiddleCoef_128[256]; +extern const float32_t twiddleCoef_256[512]; +extern const float32_t twiddleCoef_512[1024]; +extern const float32_t twiddleCoef_1024[2048]; +extern const float32_t twiddleCoef_2048[4096]; +extern const float32_t twiddleCoef_4096[8192]; +#define twiddleCoef twiddleCoef_4096 +extern const q31_t twiddleCoef_16_q31[24]; +extern const q31_t twiddleCoef_32_q31[48]; +extern const q31_t twiddleCoef_64_q31[96]; +extern const q31_t twiddleCoef_128_q31[192]; +extern const q31_t twiddleCoef_256_q31[384]; +extern const q31_t twiddleCoef_512_q31[768]; +extern const q31_t twiddleCoef_1024_q31[1536]; +extern const q31_t twiddleCoef_2048_q31[3072]; +extern const q31_t twiddleCoef_4096_q31[6144]; +extern const q15_t twiddleCoef_16_q15[24]; +extern const q15_t twiddleCoef_32_q15[48]; +extern const q15_t twiddleCoef_64_q15[96]; +extern const q15_t twiddleCoef_128_q15[192]; +extern const q15_t twiddleCoef_256_q15[384]; +extern const q15_t twiddleCoef_512_q15[768]; +extern const q15_t twiddleCoef_1024_q15[1536]; +extern const q15_t twiddleCoef_2048_q15[3072]; +extern const q15_t twiddleCoef_4096_q15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; + +/* floating-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20) +#define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48) +#define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56) +#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208) +#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440) +#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448) +#define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) +#define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) +#define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH]; + +/* fixed-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12) +#define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24) +#define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56) +#define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112) +#define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240) +#define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480) +#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992) +#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) +#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + +/* Tables for Fast Math Sine and Cosine */ +extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; +extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; +extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/platform/cmsis/inc/arm_const_structs.h b/platform/cmsis/inc/arm_const_structs.h new file mode 100644 index 0000000..80a3e8b --- /dev/null +++ b/platform/cmsis/inc/arm_const_structs.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------- + * 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_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/platform/cmsis/inc/arm_math.h b/platform/cmsis/inc/arm_math.h new file mode 100644 index 0000000..3288e37 --- /dev/null +++ b/platform/cmsis/inc/arm_math.h @@ -0,0 +1,7210 @@ +/****************************************************************************** + * @file arm_math.h + * @brief Public header file for CMSIS DSP Library + * @version V1.6.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 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 + * - Filters + * - Matrix functions + * - Transform functions + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has 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. + * - 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 has been developed and tested with MDK version 5.14.0.0 + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * 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. + * + * 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 + * + *
+ * 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 + */ + + +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +/* 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__ ) + +#else + #error Unknown compiler +#endif + + +#include "cmsis_compiler.h" +#include "string.h" +#include "math.h" + +/* evaluate ARM architecture */ +#if defined (__ARM_ARCH_6M__) + #define ARM_MATH_CM0_FAMILY 1 +#elif defined (__ARM_ARCH_7M__) +//#define ARM_MATH_CM0_FAMILY 0 +#elif defined (__ARM_ARCH_7EM__) +//#define ARM_MATH_CM0_FAMILY 0 +#elif defined (__ARM_ARCH_8M_BASE__) + #define ARM_MATH_CM0_FAMILY 1 +#elif defined (__ARM_ARCH_8M_MAIN__) +//#define ARM_MATH_CM0_FAMILY 0 +#else + #error "Unknown Arm Architecture!" +#endif + +/* evaluate ARM DSP feature */ +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + #define ARM_MATH_DSP 1 +#endif + + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 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 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 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 __unaligned 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)) + +/* 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; + + memcpy (&val, pQ15, 4); + + 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; + + memcpy (&val, *pQ15, 4); + *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; + + memcpy (&val, *pQ15, 4); + *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; + + memcpy (*pQ15, &val, 4); + *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; + + memcpy (pQ15, &val, 4); +} + + +/** + @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; + + memcpy (&val, *pQ7, 4); + *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; + + memcpy (&val, *pQ7, 4); + *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; + + memcpy (*pQ7, &val, 4); + *pQ7 += 4; +} + + +#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 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; + + /** + * @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] pState points to the state buffer. + */ + 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 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. */ + } arm_cfft_instance_q15; + +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. */ + } arm_cfft_instance_q31; + +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. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_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. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } 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. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } 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 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); + +arm_status arm_rfft_32_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_64_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_128_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_256_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_512_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_1024_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_2048_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + +arm_status arm_rfft_4096_fast_init_f32 ( arm_rfft_fast_instance_f32 * S ); + + + void arm_rfft_fast_f32( + 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, + 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. */ + 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, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + + /** + * @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, + 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((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) + { + /* 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); + + + /** + * @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); + + /** + * @} 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 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); + + + /** + * @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->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * 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 - 1) + (yIndex) * 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->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + 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->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + 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 * (0xFFFFF - xfract)) >> 4U); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4U); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - 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->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + 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 + +#endif + + +#ifdef __cplusplus +} +#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__ ) + +#else + #error Unknown compiler +#endif + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/platform/cmsis/inc/best1000.h b/platform/cmsis/inc/best1000.h new file mode 100644 index 0000000..9a78f07 --- /dev/null +++ b/platform/cmsis/inc/best1000.h @@ -0,0 +1,175 @@ +/**************************************************************************//** + * @file best1000.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * ARMCM4 Device Series + * @version V2.02 + * @date 10. September 2014 + * + * @note configured for CM4 with FPU + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM 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 __BEST1000_H__ +#define __BEST1000_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/* ------------------- Cortex-M4 Processor Exceptions Numbers ------------------- */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/* ---------------------- BEST1000 Specific Interrupt Numbers --------------------- */ + FPU_IRQn = 0, /*!< FPU Interrupt */ + SDIO_IRQn = 1, /*!< SDIO Interrupt */ + SDMMC_IRQn = 2, /*!< SDMMC Interrupt */ + AUDMA_IRQn = 3, /*!< Audio DMA Interrupt */ + GPDMA_IRQn = 4, /*!< General Purpose DMA Interrupt */ + DPDRX_IRQn = 5, /*!< DPD RX Interrupt */ + DPDTX_IRQn = 6, /*!< DPD TX Interrupt */ + USB_IRQn = 7, /*!< USB Interrupt */ + WAKEUP_IRQn = 8, /*!< Reserved Interrupt */ + GPIO_IRQn = 9, /*!< GPIO Interrupt */ + WDT_IRQn = 10, /*!< Watchdog Timer Interrupt */ + RTC_IRQn = 11, /*!< RTC Interrupt */ + TIMER00_IRQn = 12, /*!< Timer00 Interrupt */ + TIMER01_IRQn = 13, /*!< Timer01 Interrupt */ + I2C0_IRQn = 14, /*!< I2C0 Interrupt */ + SPI0_IRQn = 15, /*!< SPI0 Interrupt */ + SPILCD_IRQn = 16, /*!< SPILCD Interrupt */ + UART0_IRQn = 17, /*!< UART0 Interrupt */ + UART1_IRQn = 18, /*!< UART1 Interrupt */ + CODEC_IRQn = 19, /*!< CODEC Interrupt */ + BTPCM_IRQn = 20, /*!< BTPCM Interrupt */ + I2S0_IRQn = 21, /*!< I2S0 Interrupt */ + SPDIF_IRQn = 22, /*!< SPDIF Interrupt */ + ITNSPI_IRQn = 23, /*!< Reserved Interrupt */ + BT_IRQn = 24, /*!< Reserved Interrupt */ + GPADC_IRQn = 25, /*!< Reserved Interrupt */ + NONE4_IRQn = 26, /*!< Reserved Interrupt */ + USB_PIN_IRQn = 27, /*!< Reserved Interrupt */ + ISDONE_IRQn = 28, /*!< Intersys MCU2BT Data Done Interrupt */ + ISDONE1_IRQn = 29, /*!< Intersys MCU2BT Data1 Done Interrupt */ + ISDATA_IRQn = 30, /*!< Intersys BT2MCU Data Indication Interrupt */ + ISDATA1_IRQn = 31, /*!< Intersys BT2MCU Data1 Indication Interrupt */ + CHARGER_IRQn = 32, /*!< Charger IRQ */ + PWRKEY_IRQn = 33, /*!< Power key IRQ */ + + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#endif + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the Cortex-M4 Processor and Core Peripherals ------- */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3 /*!< 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 */ +#define __NUM_CODE_PATCH 32 +#define __NUM_LIT_PATCH 32 + +#include "core_cm4.h" /* Processor and core peripherals */ + +#ifndef __ASSEMBLER__ + +#include "system_ARMCM.h" /* System Header */ + +#endif + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#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 + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (defined(__ARMCC_VERSION) && (__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 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/best1400.h b/platform/cmsis/inc/best1400.h new file mode 100644 index 0000000..5705e71 --- /dev/null +++ b/platform/cmsis/inc/best1400.h @@ -0,0 +1,191 @@ +/**************************************************************************//** + * @file best1400.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * ARMCM4 Device Series + * @version V2.02 + * @date 10. September 2014 + * + * @note configured for CM4 with FPU + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM 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 __BEST1400_H__ +#define __BEST1400_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/* ------------------- Cortex-M4 Processor Exceptions Numbers ------------------- */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/* ---------------------- BEST1400 Specific Interrupt Numbers --------------------- */ + FPU_IRQn = 0, /*!< FPU Interrupt */ + RESERVED01_IRQn = 1, /*!< Reserved Interrupt */ + RESERVED02_IRQn = 2, /*!< Reserved Interrupt */ + RESERVED03_IRQn = 3, /*!< Reserved Interrupt */ + AUDMA_IRQn = 4, /*!< General Purpose DMA Interrupt */ + MCU_TIMER1_IRQ2n = 5, /*!< MCU Timer1 Interrupt1 */ + MCU_TIMER1_IRQ1n = 6, /*!< MCU Timer1 Interrupt2 */ + USB_IRQn = 7, /*!< USB Interrupt */ + WAKEUP_IRQn = 8, /*!< Wakeup Interrupt */ + GPIO_IRQn = 9, /*!< GPIO Interrupt */ + WDT_IRQn = 10, /*!< Watchdog Timer Interrupt */ + RTC_IRQn = 11, /*!< RTC Interrupt */ + MCU_TIMER00_IRQn = 12, /*!< MCU Timer0 Interrupt */ + MCU_TIMER01_IRQn = 13, /*!< MCU Timer0 Interrupt */ + I2C0_IRQn = 14, /*!< I2C0 Interrupt */ + SPI0_IRQn = 15, /*!< SPI0 Interrupt */ + UART2_IRQn = 16, /*!< Reserved Interrupt */ + UART0_IRQn = 17, /*!< UART0 Interrupt */ + UART1_IRQn = 18, /*!< UART1 Interrupt */ + CODEC_IRQn = 19, /*!< CODEC Interrupt */ + PCM_IRQn = 20, /*!< PCM Interrupt */ + I2S0_IRQn = 21, /*!< I2S0 Interrupt */ + RESERVED22_IRQn = 22, /*!< SPDIF0 Interrupt */ + SPI_ITN_IRQn = 23, /*!< Internal SPI Interrupt */ + RESERVED24_IRQn = 24, /*!< Reserved Interrupt */ + GPADC_IRQn = 25, /*!< GPADC Interrupt */ + RESERVED26_IRQn = 26, /*!< Reserved Interrupt */ + USB_PIN_IRQn = 27, /*!< PMU USB Interrupt */ + RESERVED28_IRQn = 28, /*!< Reserved Interrupt */ + RESERVED29_IRQn = 29, /*!< Reserved Interrupt */ + USB_CALIB_IRQn = 30, /*!< USB CALIB Interrupt */ + USB_SOF_IRQn = 31, /*!< USB SOF Interrupt */ + CHARGER_IRQn = 32, /*!< Charger Interrupt */ + PWRKEY_IRQn = 33, /*!< POWER KEY Interrupt */ + DUMP_IRQn = 34, /*!< DUMP Interrupt */ + BT2MCU_IRQn = 35, /*!< BT2MCU Interrupt */ + ISDONE_IRQn = 36, /*!< MCU2BT Data0 Done Interrupt */ + ISDONE1_IRQn = 37, /*!< MCU2BT Data1 Done Interrupt */ + ISDATA_IRQn = 38, /*!< BT2MCU Data0 Ind Interrupt */ + ISDATA1_IRQn = 39, /*!< BT2MCU Data1 Ind Interrupt */ + RESERVED40_IRQn = 40, /*!< Reserved Interrupt */ + RESERVED41_IRQn = 41, /*!< Reserved Interrupt */ + RESERVED42_IRQn = 42, /*!< Reserved Interrupt */ + RESERVED43_IRQn = 43, /*!< Reserved Interrupt */ + RESERVED44_IRQn = 44, /*!< Reserved Interrupt */ + RESERVED45_IRQn = 45, /*!< Reserved Interrupt */ + RESERVED46_IRQn = 46, /*!< Reserved Interrupt */ + RESERVED47_IRQn = 47, /*!< Reserved Interrupt */ + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#define TIMER00_IRQn MCU_TIMER00_IRQn +#define TIMER01_IRQn MCU_TIMER01_IRQn + +#endif + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the Cortex-M4 Processor and Core Peripherals ------- */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3 /*!< 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 */ +#define __NUM_CODE_PATCH 6 +#define __NUM_LIT_PATCH 2 + +#include "core_cm4.h" /* Processor and core peripherals */ + +#ifndef __ASSEMBLER__ + +#include "system_ARMCM.h" /* System Header */ + +#endif + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#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 + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (defined(__ARMCC_VERSION) && (__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 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/best2000.h b/platform/cmsis/inc/best2000.h new file mode 100644 index 0000000..b68d28c --- /dev/null +++ b/platform/cmsis/inc/best2000.h @@ -0,0 +1,192 @@ +/**************************************************************************//** + * @file best2000.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * ARMCM4 Device Series + * @version V2.02 + * @date 10. September 2014 + * + * @note configured for CM4 with FPU + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM 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 __BEST2000_H__ +#define __BEST2000_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/* ------------------- Cortex-M4 Processor Exceptions Numbers ------------------- */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/* ---------------------- BEST1000 Specific Interrupt Numbers --------------------- */ + FPU_IRQn = 0, /*!< FPU Interrupt */ + SDIO_IRQn = 1, /*!< SDIO Interrupt */ + SDMMC_IRQn = 2, /*!< SDMMC Interrupt */ + AUDMA_IRQn = 3, /*!< Audio DMA Interrupt */ + GPDMA_IRQn = 4, /*!< General Purpose DMA Interrupt */ + RESERVED5_IRQn = 5, /*!< Reserved Interrupt */ + RESERVED6_IRQn = 6, /*!< Reserved Interrupt */ + USB_IRQn = 7, /*!< USB Interrupt */ + WAKEUP_IRQn = 8, /*!< Wakeup Interrupt */ + GPIO_IRQn = 9, /*!< GPIO Interrupt */ + MCU_WDT_IRQn = 10, /*!< Watchdog Timer Interrupt */ + RTC_IRQn = 11, /*!< RTC Interrupt */ + TIMER00_IRQn = 12, /*!< Timer00 Interrupt */ + TIMER01_IRQn = 13, /*!< Timer01 Interrupt */ + I2C0_IRQn = 14, /*!< I2C0 Interrupt */ + SPI0_IRQn = 15, /*!< SPI0 Interrupt */ + SPILCD_IRQn = 16, /*!< SPILCD Interrupt */ + UART0_IRQn = 17, /*!< UART0 Interrupt */ + UART1_IRQn = 18, /*!< UART1 Interrupt */ + CODEC_IRQn = 19, /*!< CODEC Interrupt */ + BTPCM_IRQn = 20, /*!< BTPCM Interrupt */ + I2S0_IRQn = 21, /*!< I2S0 Interrupt */ + SPDIF0_IRQn = 22, /*!< SPDIF0 Interrupt */ + ITNSPI_IRQn = 23, /*!< Internal SPI Interrupt */ + BT_IRQn = 24, /*!< BT to MCU Interrupt */ + GPADC_IRQn = 25, /*!< GPADC Interrupt */ + UART2_IRQn = 26, /*!< UART2 Interrupt */ + SPDIF1_IRQn = 27, /*!< SPDIF1 Interrupt */ + CAM_IRQn = 28, /*!< CAM Interrupt */ + DSDIF_IRQn = 29, /*!< DSDIF Interrupt */ + GPIOAUX_IRQn = 30, /*!< GPIO AUX Interrupt */ + RESERVED31_IRQn = 31, /*!< Reserved Interrupt */ + ISDONE_IRQn = 32, /*!< Intersys MCU2BT Data Done Interrupt */ + ISDONE1_IRQn = 33, /*!< Intersys MCU2BT Data1 Done Interrupt */ + ISDATA_IRQn = 34, /*!< Intersys BT2MCU Data Indication Interrupt */ + ISDATA1_IRQn = 35, /*!< Intersys BT2MCU Data1 Indication Interrupt */ + WIFI_IRQn = 36, /*!< WIFI to MCU Interrupt */ + TRANSQW_LCL_IRQn = 37, /*!< TRANSQ-WIFI Local Interrupt */ + TRANSQW_RMT_IRQn = 38, /*!< TRANSQ-WIFI Peer Remote Interrupt */ + RESERVED39_IRQn = 39, /*!< Reserved Interrupt */ + RESERVED40_IRQn = 40, /*!< Reserved Interrupt */ + USB_PIN_IRQn = 41, /*!< USB Pin Interrupt */ + CHARGER_IRQn = 42, /*!< Charger Interrupt */ + PWRKEY_IRQn = 43, /*!< Power key Interrupt */ + AON_IRQn = 44, /*!< AON Interrupt */ + RESERVED45_IRQn = 45, /*!< Reserved Interrupt */ + + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#define WDT_IRQn AON_IRQn + +#define TRANSQ0_RMT_IRQn TRANSQW_RMT_IRQn +#define TRANSQ0_LCL_IRQn TRANSQW_LCL_IRQn + +#endif + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the Cortex-M4 Processor and Core Peripherals ------- */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3 /*!< 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 */ +#define __NUM_CODE_PATCH 32 +#define __NUM_LIT_PATCH 32 + +#include "core_cm4.h" /* Processor and core peripherals */ + +#ifndef __ASSEMBLER__ + +#include "system_ARMCM.h" /* System Header */ + +#endif + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#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 + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (defined(__ARMCC_VERSION) && (__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 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/best2001.h b/platform/cmsis/inc/best2001.h new file mode 100644 index 0000000..299fcc0 --- /dev/null +++ b/platform/cmsis/inc/best2001.h @@ -0,0 +1,236 @@ +/**************************************************************************//** + * @file best2001.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * ARMCM4 Device Series + * @version V2.02 + * @date 10. September 2014 + * + * @note configured for CM4 with FPU + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM 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 __BEST2001_H__ +#define __BEST2001_H__ + +#ifdef CHIP_BEST2001_DSP + +#include "ca/best2001_dsp.h" + +#else + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/* ------------------- Cortex-M33 Processor Exceptions Numbers ------------------ */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/* ---------------------- Chip Specific Interrupt Numbers ----------------------- */ + FPU_IRQn = 0, /*!< FPU Interrupt */ + WAKEUP_IRQn = 1, /*!< Wakeup Interrupt */ + CODEC_IRQn = 2, /*!< CODEC Interrupt */ + CODEC_TX_PEAK_IRQn = 3, /*!< CODEC TX PEAK Interrupt */ + SDMMC_IRQn = 4, /*!< SDMMC Interrupt */ + BES2001_AUDMA_IRQn = 5, /*!< Audio DMA Interrupt */ + BES2001_GPDMA_IRQn = 6, /*!< General Purpose DMA Interrupt */ + USB_IRQn = 7, /*!< USB Interrupt */ + USB_PHY_IRQn = 8, /*!< USB PHY Interrupt */ + USB_CAL_IRQn = 9, /*!< USB Calibration Interrupt */ + USB_PIN_IRQn = 10, /*!< USB Pin Interrupt */ + SEC_ENG_IRQn = 11, /*!< Security Engine Interrupt */ + SEDMA_IRQn = 12, /*!< Security Engine DMA Interrupt */ + DUMP_IRQn = 13, /*!< DUMP Interrupt */ + MCU_WDT_IRQn = 14, /*!< Watchdog Timer Interrupt */ + MCU_TIMER00_IRQn = 15, /*!< Timer00 Interrupt */ + MCU_TIMER01_IRQn = 16, /*!< Timer01 Interrupt */ + MCU_TIMER10_IRQn = 17, /*!< Timer10 Interrupt */ + MCU_TIMER11_IRQn = 18, /*!< Timer11 Interrupt */ + MCU_TIMER20_IRQn = 19, /*!< Timer20 Interrupt */ + MCU_TIMER21_IRQn = 20, /*!< Timer21 Interrupt */ + I2C0_IRQn = 21, /*!< I2C0 Interrupt */ + I2C1_IRQn = 22, /*!< I2C1 Interrupt */ + SPI0_IRQn = 23, /*!< SPI0 Interrupt */ + SPILCD_IRQn = 24, /*!< SPILCD Interrupt */ + ITNSPI_IRQn = 25, /*!< Internal SPI Interrupt */ + SPIPHY_IRQn = 26, /*!< SPIPHY Interrupt */ + UART0_IRQn = 27, /*!< UART0 Interrupt */ + UART1_IRQn = 28, /*!< UART1 Interrupt */ + UART2_IRQn = 29, /*!< UART2 Interrupt */ + BTPCM_IRQn = 30, /*!< BTPCM Interrupt */ + I2S0_IRQn = 31, /*!< I2S0 Interrupt */ + SPDIF0_IRQn = 32, /*!< SPDIF0 Interrupt */ + TRNG_IRQn = 33, /*!< TRNG Interrupt */ + AON_GPIO_IRQn = 34, /*!< AON GPIO Interrupt */ + AON_GPIOAUX_IRQn = 35, /*!< AON GPIOAUX Interrupt */ + AON_WDT_IRQn = 36, /*!< AON Watchdog Timer Interrupt */ + AON_TIMER00_IRQn = 37, /*!< AON Timer00 Interrupt */ + AON_TIMER01_IRQn = 38, /*!< AON Timer01 Interrupt */ + MCU2CP_DONE_IRQn = 39, /*!< Intersys MCU2CP Data Done Interrupt */ + MCU2CP_DONE1_IRQn = 40, /*!< Intersys MCU2CP Data Done Interrupt */ + MCU2CP_DONE2_IRQn = 41, /*!< Intersys MCU2CP Data Done Interrupt */ + MCU2CP_DONE3_IRQn = 42, /*!< Intersys MCU2CP Data Done Interrupt */ + CP2MCU_DATA_IRQn = 43, /*!< Intersys CP2MCU Data Indication Interrupt */ + CP2MCU_DATA1_IRQn = 44, /*!< Intersys CP2MCU Data1 Indication Interrupt */ + CP2MCU_DATA2_IRQn = 45, /*!< Intersys CP2MCU Data Indication Interrupt */ + CP2MCU_DATA3_IRQn = 46, /*!< Intersys CP2MCU Data1 Indication Interrupt */ + TRANSQD_LCL_IRQn = 47, /*!< TRANSQ-DSP Local Interrupt */ + TRANSQD_RMT_IRQn = 48, /*!< TRANSQ-DSP Peer Remote Interrupt */ + DSP_IRQn = 49, /*!< DSP to MCU Interrupt */ + TRANSQW_LCL_IRQn = 50, /*!< TRANSQ-WIFI Local Interrupt */ + TRANSQW_RMT_IRQn = 51, /*!< TRANSQ-WIFI Peer Remote Interrupt */ + WIFI_IRQn = 52, /*!< DSP to MCU Interrupt */ + ISDONE_IRQn = 53, /*!< Intersys MCU2BT Data Done Interrupt */ + ISDONE1_IRQn = 54, /*!< Intersys MCU2BT Data1 Done Interrupt */ + ISDATA_IRQn = 55, /*!< Intersys BT2MCU Data Indication Interrupt */ + ISDATA1_IRQn = 56, /*!< Intersys BT2MCU Data1 Indication Interrupt */ + BT_IRQn = 57, /*!< BT to MCU Interrupt */ + RESERVED58_IRQn = 58, /*!< Reserved Interrupt */ + RTC_IRQn = 59, /*!< RTC Interrupt */ + GPADC_IRQn = 60, /*!< GPADC Interrupt */ + CHARGER_IRQn = 61, /*!< Charger Interrupt */ + PWRKEY_IRQn = 62, /*!< Power key Interrupt */ + WIFIDUMP_IRQn = 63, /*!< WIFIDUMP Interrupt */ + CHKSUM_IRQn = 64, /*!< Checksum Interrupt */ + CRC_IRQn = 65, /*!< CRC Interrupt */ + CP_DSLP_IRQn = 66, /*!< CP Deep Sleep Interrupt */ + AON_SPIDPD_IRQn = 67, /*!< AON SPIDPD Interrupt */ + TRUSTZONE_IRQn = 68, /*!< TrustZone Interrupt */ + + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#ifndef DSP_USE_AUDMA +#define AUDMA_IRQn BES2001_AUDMA_IRQn +#define GPDMA_IRQn BES2001_GPDMA_IRQn +#else +#define AUDMA_IRQn BES2001_GPDMA_IRQn //MCU use GPDMA +#endif + +#define GPIO_IRQn AON_GPIO_IRQn +#define GPIOAUX_IRQn AON_GPIOAUX_IRQn +#define TIMER00_IRQn MCU_TIMER00_IRQn +#define TIMER01_IRQn MCU_TIMER01_IRQn +#define WDT_IRQn AON_WDT_IRQn + +#define TRANSQ0_RMT_IRQn TRANSQW_RMT_IRQn +#define TRANSQ0_LCL_IRQn TRANSQW_LCL_IRQn +#define TRANSQ1_RMT_IRQn TRANSQD_RMT_IRQn +#define TRANSQ1_LCL_IRQn TRANSQD_LCL_IRQn + +#endif + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of Core Peripherals ----------------------------------- */ +#define __CM33_REV 0x0000U /* Core revision r0p1 */ +#define __SAUREGION_PRESENT 0U /* SAU regions present */ +#define __MPU_PRESENT 1U /* MPU present */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3U /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /* FPU present */ +#define __DSP_PRESENT 1U /* DSP extension present */ + +#include "core_cm33.h" /* Processor and core peripherals */ + +#ifndef __ASSEMBLER__ + +#include "system_ARMCM.h" /* System Header */ + +#endif + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#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 + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (defined(__ARMCC_VERSION) && (__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 + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/platform/cmsis/inc/best2300.h b/platform/cmsis/inc/best2300.h new file mode 100644 index 0000000..9caffce --- /dev/null +++ b/platform/cmsis/inc/best2300.h @@ -0,0 +1,202 @@ +/**************************************************************************//** + * @file best2300.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * ARMCM4 Device Series + * @version V2.02 + * @date 10. September 2014 + * + * @note configured for CM4 with FPU + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM 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 __BEST2300_H__ +#define __BEST2300_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/* ------------------- Cortex-M4 Processor Exceptions Numbers ------------------- */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/* ---------------------- BEST1000 Specific Interrupt Numbers --------------------- */ + FPU_IRQn = 0, /*!< FPU Interrupt */ + SENSOR_WKUP_IRQn = 1, /*!< SENSOR Wakeup Interrupt */ + SDMMC_IRQn = 2, /*!< SDMMC Interrupt */ + AUDMA_IRQn = 3, /*!< Audio DMA Interrupt */ + GPDMA_IRQn = 4, /*!< General Purpose DMA Interrupt */ + AON_WDT_IRQn = 5, /*!< AON Watchdog Timer Interrupt */ + USB_PHY_IRQn = 6, /*!< USB PHY Interrupt */ + USB_IRQn = 7, /*!< USB Interrupt */ + WAKEUP_IRQn = 8, /*!< Wakeup Interrupt */ + AON_GPIO_IRQn = 9, /*!< AON GPIO Interrupt */ + MCU_WDT_IRQn = 10, /*!< Watchdog Timer Interrupt */ + RESERVED11_IRQn = 11, /*!< Reserved Interrupt */ + MCU_TIMER00_IRQn = 12, /*!< Timer00 Interrupt */ + MCU_TIMER01_IRQn = 13, /*!< Timer01 Interrupt */ + I2C0_IRQn = 14, /*!< I2C0 Interrupt */ + SPI0_IRQn = 15, /*!< SPI0 Interrupt */ + SPILCD_IRQn = 16, /*!< SPILCD Interrupt */ + UART0_IRQn = 17, /*!< UART0 Interrupt */ + UART1_IRQn = 18, /*!< UART1 Interrupt */ + CODEC_IRQn = 19, /*!< CODEC Interrupt */ + BTPCM_IRQn = 20, /*!< BTPCM Interrupt */ + I2S0_IRQn = 21, /*!< I2S0 Interrupt */ + SPDIF0_IRQn = 22, /*!< SPDIF0 Interrupt */ + ITNSPI_IRQn = 23, /*!< Internal SPI Interrupt */ + BT_IRQn = 24, /*!< BT to MCU Interrupt */ + RESERVED25_IRQn = 25, /*!< Reserved Interrupt */ + UART2_IRQn = 26, /*!< UART2 Interrupt */ + MCU_TIMER10_IRQn = 27, /*!< Timer10 Interrupt */ + MCU_TIMER11_IRQn = 28, /*!< Timer11 Interrupt */ + I2C1_IRQn = 29, /*!< I2C1 Interrupt */ + DUMP_IRQn = 30, /*!< DUMP Interrupt */ + SPIPHY_IRQn = 31, /*!< SPIPHY Interrupt */ + ISDONE_IRQn = 32, /*!< Intersys MCU2BT Data Done Interrupt */ + ISDONE1_IRQn = 33, /*!< Intersys MCU2BT Data1 Done Interrupt */ + ISDATA_IRQn = 34, /*!< Intersys BT2MCU Data Indication Interrupt */ + ISDATA1_IRQn = 35, /*!< Intersys BT2MCU Data1 Indication Interrupt */ + SENSOR0_IRQn = 36, /*!< SENSOR0 Interrupt */ + SENSOR1_IRQn = 37, /*!< SENSOR1 Interrupt */ + SENSOR2_IRQn = 38, /*!< SENSOR2 Interrupt */ + SENSOR3_IRQn = 39, /*!< SENSOR3 Interrupt */ + USB_CAL_IRQn = 40, /*!< USB Calibration Interrupt */ + USB_PIN_IRQn = 41, /*!< USB Pin Interrupt */ + PMU_IRQn = 42, /*!< PMU Interrupt */ + RESERVED43_IRQn = 43, /*!< Reserved Interrupt */ + AON_IRQn = 44, /*!< AON Interrupt */ + AON_TIMER00_IRQn = 45, /*!< AON Timer00 Interrupt */ + AON_TIMER01_IRQn = 46, /*!< AON Timer01 Interrupt */ + RESERVED47_IRQn = 47, /*!< Reserved Interrupt */ + + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#define GPIO_IRQn AON_GPIO_IRQn +#define GPADC_IRQn INVALID_IRQn +#define PWRKEY_IRQn INVALID_IRQn +#ifdef MCU_SLEEP_POWER_DOWN +#define TIMER00_IRQn AON_TIMER00_IRQn +#define TIMER01_IRQn AON_TIMER01_IRQn +#else +#define TIMER00_IRQn MCU_TIMER00_IRQn +#define TIMER01_IRQn MCU_TIMER01_IRQn +#endif +#define WDT_IRQn AON_WDT_IRQn + +#endif + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the Cortex-M4 Processor and Core Peripherals ------- */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3 /*!< 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 */ +#define __NUM_CODE_PATCH 56 +#define __NUM_LIT_PATCH 8 + +#include "core_cm4.h" /* Processor and core peripherals */ + +#ifndef __ASSEMBLER__ + +#include "system_ARMCM.h" /* System Header */ + +#endif + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#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 + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (defined(__ARMCC_VERSION) && (__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 + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/best2300a.h b/platform/cmsis/inc/best2300a.h new file mode 100644 index 0000000..f831d6e --- /dev/null +++ b/platform/cmsis/inc/best2300a.h @@ -0,0 +1,211 @@ +/**************************************************************************//** + * @file best2300a.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * ARMCM4 Device Series + * @version V2.02 + * @date 10. September 2014 + * + * @note configured for CM4 with FPU + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM 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 __BEST2300A_H__ +#define __BEST2300A_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/* ------------------- Cortex-M33 Processor Exceptions Numbers ------------------ */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/* -------------------- BEST2300A Specific Interrupt Numbers -------------------- */ + FPU_IRQn = 0, /*!< FPU Interrupt */ + SENSOR_WKUP_IRQn = 1, /*!< SENSOR Wakeup Interrupt */ + SDMMC_IRQn = 2, /*!< SDMMC Interrupt */ + AUDMA_IRQn = 3, /*!< Audio DMA Interrupt */ + GPDMA_IRQn = 4, /*!< General Purpose DMA Interrupt */ + AON_WDT_IRQn = 5, /*!< AON Watchdog Timer Interrupt */ + USB_PHY_IRQn = 6, /*!< USB PHY Interrupt */ + USB_IRQn = 7, /*!< USB Interrupt */ + WAKEUP_IRQn = 8, /*!< Wakeup Interrupt */ + AON_GPIO_IRQn = 9, /*!< AON GPIO Interrupt */ + MCU_WDT_IRQn = 10, /*!< Watchdog Timer Interrupt */ + SENSOR_ENG_IRQn = 11, /*!< Sensor Engine Interrupt */ + MCU_TIMER00_IRQn = 12, /*!< Timer00 Interrupt */ + MCU_TIMER01_IRQn = 13, /*!< Timer01 Interrupt */ + I2C0_IRQn = 14, /*!< I2C0 Interrupt */ + SPI0_IRQn = 15, /*!< SPI0 Interrupt */ + SPILCD_IRQn = 16, /*!< SPILCD Interrupt */ + UART0_IRQn = 17, /*!< UART0 Interrupt */ + UART1_IRQn = 18, /*!< UART1 Interrupt */ + CODEC_IRQn = 19, /*!< CODEC Interrupt */ + BTPCM_IRQn = 20, /*!< BTPCM Interrupt */ + I2S0_IRQn = 21, /*!< I2S0 Interrupt */ + SPDIF0_IRQn = 22, /*!< SPDIF0 Interrupt */ + I2S1_IRQn = 23, /*!< I2S1 Interrupt */ + BT_IRQn = 24, /*!< BT to MCU Interrupt */ + CODEC_TX_PEAK_IRQn = 25, /*!< CODEC TX PEAK Interrupt */ + UART2_IRQn = 26, /*!< UART2 Interrupt */ + MCU_TIMER10_IRQn = 27, /*!< Timer10 Interrupt */ + MCU_TIMER11_IRQn = 28, /*!< Timer11 Interrupt */ + I2C1_IRQn = 29, /*!< I2C1 Interrupt */ + DUMP_IRQn = 30, /*!< DUMP Interrupt */ + SPIPHY_IRQn = 31, /*!< SPIPHY Interrupt */ + ISDONE_IRQn = 32, /*!< Intersys MCU2BT Data Done Interrupt */ + ISDONE1_IRQn = 33, /*!< Intersys MCU2BT Data1 Done Interrupt */ + ISDATA_IRQn = 34, /*!< Intersys BT2MCU Data Indication Interrupt */ + ISDATA1_IRQn = 35, /*!< Intersys BT2MCU Data1 Indication Interrupt */ + CP2MCU_DATA_IRQn = 36, /*!< Intersys CP2MCU Data Indication Interrupt */ + CP2MCU_DATA1_IRQn = 37, /*!< Intersys CP2MCU Data1 Indication Interrupt */ + CP2MCU_DATA2_IRQn = 38, /*!< Intersys CP2MCU Data Indication Interrupt */ + CP2MCU_DATA3_IRQn = 39, /*!< Intersys CP2MCU Data1 Indication Interrupt */ + USB_CAL_IRQn = 40, /*!< USB Calibration Interrupt */ + USB_PIN_IRQn = 41, /*!< USB Pin Interrupt */ + PMU_IRQn = 42, /*!< PMU Interrupt */ + SEC_ENG_IRQn = 43, /*!< Security Engine Interrupt */ + AON_IRQn = 44, /*!< AON Interrupt */ + AON_TIMER00_IRQn = 45, /*!< AON Timer00 Interrupt */ + AON_TIMER01_IRQn = 46, /*!< AON Timer01 Interrupt */ + SEDMA_IRQn = 47, /*!< Security Engine DMA Interrupt */ + MCU2CP_DONE_IRQn = 48, /*!< Intersys MCU2CP Data Done Interrupt */ + MCU2CP_DONE1_IRQn = 49, /*!< Intersys MCU2CP Data Done Interrupt */ + MCU2CP_DONE2_IRQn = 50, /*!< Intersys MCU2CP Data Done Interrupt */ + MCU2CP_DONE3_IRQn = 51, /*!< Intersys MCU2CP Data Done Interrupt */ + TRNG_IRQn = 52, /*!< TRNG Interrupt */ + BT_STAMP_IRQn = 53, /*!< BT Playtime Stamp Interrupt */ + I2S_HS_SLAVE_IRQn = 54, /*!< I2S HS Slave Interrupt */ + PWRKEY_IRQn = 55, /*!< Power Key Interrupt */ + ITNPMU_IRQn = 56, /*!< Internal PMU Interrupt */ + I2C2_IRQn = 57, /*!< I2C2 Interrupt */ + + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#define GPIO_IRQn AON_GPIO_IRQn +#define GPADC_IRQn INVALID_IRQn +#define PWRKEY_IRQn INVALID_IRQn +#ifdef CORE_SLEEP_POWER_DOWN +#define TIMER00_IRQn AON_TIMER00_IRQn +#define TIMER01_IRQn AON_TIMER01_IRQn +#else +#define TIMER00_IRQn MCU_TIMER00_IRQn +#define TIMER01_IRQn MCU_TIMER01_IRQn +#endif +#define WDT_IRQn AON_WDT_IRQn + +#endif + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of Core Peripherals ----------------------------------- */ +#define __CM33_REV 0x0000U /* Core revision r0p1 */ +#define __SAUREGION_PRESENT 0U /* SAU regions present */ +#define __MPU_PRESENT 1U /* MPU present */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3U /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /* FPU present */ +#define __DSP_PRESENT 1U /* DSP extension present */ + +#include "core_cm33.h" /* Processor and core peripherals */ + +#ifndef __ASSEMBLER__ + +#include "system_ARMCM.h" /* System Header */ + +#endif + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#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 + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (defined(__ARMCC_VERSION) && (__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 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/best2300p.h b/platform/cmsis/inc/best2300p.h new file mode 100644 index 0000000..32941d0 --- /dev/null +++ b/platform/cmsis/inc/best2300p.h @@ -0,0 +1,205 @@ +/**************************************************************************//** + * @file best2300p.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * ARMCM4 Device Series + * @version V2.02 + * @date 10. September 2014 + * + * @note configured for CM4 with FPU + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM 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 __BEST2300P_H__ +#define __BEST2300P_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/* ------------------- Cortex-M4 Processor Exceptions Numbers ------------------- */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/* ---------------------- BEST1000 Specific Interrupt Numbers --------------------- */ + FPU_IRQn = 0, /*!< FPU Interrupt */ + SENSOR_WKUP_IRQn = 1, /*!< SENSOR Wakeup Interrupt */ + SDMMC_IRQn = 2, /*!< SDMMC Interrupt */ + AUDMA_IRQn = 3, /*!< Audio DMA Interrupt */ + GPDMA_IRQn = 4, /*!< General Purpose DMA Interrupt */ + AON_WDT_IRQn = 5, /*!< AON Watchdog Timer Interrupt */ + USB_PHY_IRQn = 6, /*!< USB PHY Interrupt */ + USB_IRQn = 7, /*!< USB Interrupt */ + WAKEUP_IRQn = 8, /*!< Wakeup Interrupt */ + AON_GPIO_IRQn = 9, /*!< AON GPIO Interrupt */ + MCU_WDT_IRQn = 10, /*!< Watchdog Timer Interrupt */ + SENSOR_ENG_IRQn = 11, /*!< Sensor Engine Interrupt */ + MCU_TIMER00_IRQn = 12, /*!< Timer00 Interrupt */ + MCU_TIMER01_IRQn = 13, /*!< Timer01 Interrupt */ + I2C0_IRQn = 14, /*!< I2C0 Interrupt */ + SPI0_IRQn = 15, /*!< SPI0 Interrupt */ + SPILCD_IRQn = 16, /*!< SPILCD Interrupt */ + UART0_IRQn = 17, /*!< UART0 Interrupt */ + UART1_IRQn = 18, /*!< UART1 Interrupt */ + CODEC_IRQn = 19, /*!< CODEC Interrupt */ + BTPCM_IRQn = 20, /*!< BTPCM Interrupt */ + I2S0_IRQn = 21, /*!< I2S0 Interrupt */ + SPDIF0_IRQn = 22, /*!< SPDIF0 Interrupt */ + I2S1_IRQn = 23, /*!< I2S1 Interrupt */ + BT_IRQn = 24, /*!< BT to MCU Interrupt */ + CODEC_TX_PEAK_IRQn = 25, /*!< CODEC TX PEAK Interrupt */ + UART2_IRQn = 26, /*!< UART2 Interrupt */ + MCU_TIMER10_IRQn = 27, /*!< Timer10 Interrupt */ + MCU_TIMER11_IRQn = 28, /*!< Timer11 Interrupt */ + I2C1_IRQn = 29, /*!< I2C1 Interrupt */ + DUMP_IRQn = 30, /*!< DUMP Interrupt */ + SPIPHY_IRQn = 31, /*!< SPIPHY Interrupt */ + ISDONE_IRQn = 32, /*!< Intersys MCU2BT Data Done Interrupt */ + ISDONE1_IRQn = 33, /*!< Intersys MCU2BT Data1 Done Interrupt */ + ISDATA_IRQn = 34, /*!< Intersys BT2MCU Data Indication Interrupt */ + ISDATA1_IRQn = 35, /*!< Intersys BT2MCU Data1 Indication Interrupt */ + CP2MCU_DATA_IRQn = 36, /*!< Intersys CP2MCU Data Indication Interrupt */ + CP2MCU_DATA1_IRQn = 37, /*!< Intersys CP2MCU Data1 Indication Interrupt */ + CP2MCU_DATA2_IRQn = 38, /*!< Intersys CP2MCU Data Indication Interrupt */ + CP2MCU_DATA3_IRQn = 39, /*!< Intersys CP2MCU Data1 Indication Interrupt */ + USB_CAL_IRQn = 40, /*!< USB Calibration Interrupt */ + USB_PIN_IRQn = 41, /*!< USB Pin Interrupt */ + PMU_IRQn = 42, /*!< PMU Interrupt */ + SEC_ENG_IRQn = 43, /*!< Security Engine Interrupt */ + AON_IRQn = 44, /*!< AON Interrupt */ + AON_TIMER00_IRQn = 45, /*!< AON Timer00 Interrupt */ + AON_TIMER01_IRQn = 46, /*!< AON Timer01 Interrupt */ + SEDMA_IRQn = 47, /*!< Security Engine DMA Interrupt */ + MCU2CP_DONE_IRQn = 48, /*!< Intersys MCU2CP Data Done Interrupt */ + MCU2CP_DONE1_IRQn = 49, /*!< Intersys MCU2CP Data Done Interrupt */ + MCU2CP_DONE2_IRQn = 50, /*!< Intersys MCU2CP Data Done Interrupt */ + MCU2CP_DONE3_IRQn = 51, /*!< Intersys MCU2CP Data Done Interrupt */ + + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#define GPIO_IRQn AON_GPIO_IRQn +#define GPADC_IRQn INVALID_IRQn +#define PWRKEY_IRQn INVALID_IRQn +#ifdef CORE_SLEEP_POWER_DOWN +#define TIMER00_IRQn AON_TIMER00_IRQn +#define TIMER01_IRQn AON_TIMER01_IRQn +#else +#define TIMER00_IRQn MCU_TIMER00_IRQn +#define TIMER01_IRQn MCU_TIMER01_IRQn +#endif +#define WDT_IRQn AON_WDT_IRQn + +#endif + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the Cortex-M4 Processor and Core Peripherals ------- */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3 /*!< 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 */ +#define __NUM_CODE_PATCH 6 +#define __NUM_LIT_PATCH 2 + +#include "core_cm4.h" /* Processor and core peripherals */ + +#ifndef __ASSEMBLER__ + +#include "system_ARMCM.h" /* System Header */ + +#endif + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#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 + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (defined(__ARMCC_VERSION) && (__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 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/best3001.h b/platform/cmsis/inc/best3001.h new file mode 100644 index 0000000..3d67a5f --- /dev/null +++ b/platform/cmsis/inc/best3001.h @@ -0,0 +1,181 @@ +/**************************************************************************//** + * @file best3001.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * ARMCM4 Device Series + * @version V2.02 + * @date 10. September 2014 + * + * @note configured for CM4 with FPU + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM 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 __BEST3001_H__ +#define __BEST3001_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/* ------------------- Cortex-M4 Processor Exceptions Numbers ------------------- */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/* ---------------------- BEST1000 Specific Interrupt Numbers --------------------- */ + FPU_IRQn = 0, /*!< FPU Interrupt */ + RESERVED01_IRQn = 1, /*!< Reserved Interrupt */ + RESERVED02_IRQn = 2, /*!< Reserved Interrupt */ + RESERVED03_IRQn = 3, /*!< Reserved Interrupt */ + AUDMA_IRQn = 4, /*!< General Purpose DMA Interrupt */ + MCU_TIMER1_IRQ2n = 5, /*!< MCU Timer1 Interrupt1 */ + MCU_TIMER1_IRQ1n = 6, /*!< MCU Timer1 Interrupt2 */ + USB_IRQn = 7, /*!< USB Interrupt */ + WAKEUP_IRQn = 8, /*!< Wakeup Interrupt */ + GPIO_IRQn = 9, /*!< GPIO Interrupt */ + WDT_IRQn = 10, /*!< Watchdog Timer Interrupt */ + RTC_IRQn = 11, /*!< RTC Interrupt */ + MCU_TIMER00_IRQn = 12, /*!< MCU Timer0 Interrupt */ + MCU_TIMER01_IRQn = 13, /*!< MCU Timer0 Interrupt */ + I2C0_IRQn = 14, /*!< I2C0 Interrupt */ + SPI0_IRQn = 15, /*!< SPI0 Interrupt */ + RESERVED16_IRQn = 16, /*!< Reserved Interrupt */ + UART0_IRQn = 17, /*!< UART0 Interrupt */ + UART1_IRQn = 18, /*!< UART1 Interrupt */ + CODEC_IRQn = 19, /*!< CODEC Interrupt */ + RESERVED20_IRQn = 20, /*!< Reserved Interrupt */ + I2S0_IRQn = 21, /*!< I2S0 Interrupt */ + SPDIF0_IRQn = 22, /*!< SPDIF0 Interrupt */ + SPI_ITN_IRQn = 23, /*!< Internal SPI Interrupt */ + RESERVED24_IRQn = 24, /*!< Reserved Interrupt */ + GPADC_IRQn = 25, /*!< GPADC Interrupt */ + RESERVED26_IRQn = 26, /*!< Reserved Interrupt */ + USB_PIN_IRQn = 27, /*!< PMU USB Interrupt */ + RESERVED28_IRQn = 28, /*!< Reserved Interrupt */ + RESERVED29_IRQn = 29, /*!< Reserved Interrupt */ + USB_CALIB_IRQn = 30, /*!< Reserved Interrupt */ + USB_SOF_IRQn = 31, /*!< Reserved Interrupt */ + CHARGER_IRQn = 32, /*!< Charger Interrupt */ + PWRKEY_IRQn = 33, /*!< POWER KEY Interrupt */ + RESERVED34_IRQn = 34, /*!< Reserved Interrupt */ + RESERVED35_IRQn = 35, /*!< Reserved Interrupt */ + RESERVED36_IRQn = 36, /*!< Reserved Interrupt */ + + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#define TIMER00_IRQn MCU_TIMER00_IRQn +#define TIMER01_IRQn MCU_TIMER01_IRQn + +#endif + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the Cortex-M4 Processor and Core Peripherals ------- */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3 /*!< 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 */ +#define __NUM_CODE_PATCH 56 +#define __NUM_LIT_PATCH 8 + +#include "core_cm4.h" /* Processor and core peripherals */ + +#ifndef __ASSEMBLER__ + +#include "system_ARMCM.h" /* System Header */ + +#endif + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#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 + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (defined(__ARMCC_VERSION) && (__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 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/best3003.h b/platform/cmsis/inc/best3003.h new file mode 100644 index 0000000..9f36c9c --- /dev/null +++ b/platform/cmsis/inc/best3003.h @@ -0,0 +1,169 @@ +/**************************************************************************//** + * @file best3003.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * ARMCM33 Device (configured for ARMCM33 with FPU, with DSP extension) + * @version V5.3.1 + * @date 09. July 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 __BEST3003_H__ +#define __BEST3003_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/* ------------------- Cortex-M33 Processor Exceptions Numbers ------------------ */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/* ---------------------- Chip Specific Interrupt Numbers ----------------------- */ + FPU_IRQn = 0, /*!< FPU Interrupt */ + RESERVED01_IRQn = 1, /*!< Reserved Interrupt */ + RESERVED02_IRQn = 2, /*!< Reserved Interrupt */ + GPDMA_IRQn = 3, /*!< General Purpose DMA Interrupt */ + AUDMA_IRQn = 4, /*!< Audio DMA Interrupt */ + MCU_TIMER1_IRQ2n = 5, /*!< MCU Timer1 Interrupt1 */ + MCU_TIMER1_IRQ1n = 6, /*!< MCU Timer1 Interrupt2 */ + USB_IRQn = 7, /*!< USB Interrupt */ + WAKEUP_IRQn = 8, /*!< Wakeup Interrupt */ + GPIO_IRQn = 9, /*!< GPIO Interrupt */ + WDT_IRQn = 10, /*!< Watchdog Timer Interrupt */ + RTC_IRQn = 11, /*!< RTC Interrupt */ + MCU_TIMER00_IRQn = 12, /*!< MCU Timer0 Interrupt */ + MCU_TIMER01_IRQn = 13, /*!< MCU Timer0 Interrupt */ + I2C0_IRQn = 14, /*!< I2C0 Interrupt */ + SPI0_IRQn = 15, /*!< SPI0 Interrupt */ + FMDUMP0_IRQn = 16, /*!< FM DUMP0 Interrupt */ + UART0_IRQn = 17, /*!< UART0 Interrupt */ + UART1_IRQn = 18, /*!< UART1 Interrupt */ + CODEC_IRQn = 19, /*!< CODEC Interrupt */ + FMDUMP1_IRQn = 20, /*!< FM DUMP1 Interrupt */ + I2S0_IRQn = 21, /*!< I2S0 Interrupt */ + SPDIF0_IRQn = 22, /*!< SPDIF0 Interrupt */ + SPI_ITN_IRQn = 23, /*!< Internal SPI Interrupt */ + RESERVED24_IRQn = 24, /*!< Reserved Interrupt */ + GPADC_IRQn = 25, /*!< GPADC Interrupt */ + RESERVED26_IRQn = 26, /*!< Reserved Interrupt */ + USB_PIN_IRQn = 27, /*!< PMU USB Interrupt */ + RESERVED28_IRQn = 28, /*!< Reserved Interrupt */ + RESERVED29_IRQn = 29, /*!< Reserved Interrupt */ + USB_CALIB_IRQn = 30, /*!< Reserved Interrupt */ + USB_SOF_IRQn = 31, /*!< Reserved Interrupt */ + CHARGER_IRQn = 32, /*!< Charger Interrupt */ + PWRKEY_IRQn = 33, /*!< POWER KEY Interrupt */ + EARDET_IRQn = 34, /*!< EAR DET Interrupt */ + RESERVED35_IRQn = 35, /*!< Reserved Interrupt */ + RESERVED36_IRQn = 36, /*!< Reserved Interrupt */ + + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#define TIMER00_IRQn MCU_TIMER00_IRQn +#define TIMER01_IRQn MCU_TIMER01_IRQn + +#endif + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of Core Peripherals ----------------------------------- */ +#define __CM33_REV 0x0000U /* Core revision r0p1 */ +#define __SAUREGION_PRESENT 0U /* SAU regions present */ +#define __MPU_PRESENT 1U /* MPU present */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3U /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /* FPU present */ +#define __DSP_PRESENT 1U /* DSP extension present */ + +#include "core_cm33.h" /* Processor and core peripherals */ + +#ifndef __ASSEMBLER__ + +#include "system_ARMCM.h" /* System Header */ + +#endif + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#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 + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (defined(__ARMCC_VERSION) && (__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 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/ca/best2001_dsp.h b/platform/cmsis/inc/ca/best2001_dsp.h new file mode 100644 index 0000000..5daca8b --- /dev/null +++ b/platform/cmsis/inc/ca/best2001_dsp.h @@ -0,0 +1,209 @@ +/****************************************************************************** + * @file ARMCA7.h + * @brief CMSIS Cortex-A7 Core Peripheral Access Layer Header File + * @version V1.1.0 + * @date 15. May 2019 + * + * @note + * + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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 __BEST2001_DSP_H__ +#define __BEST2001_DSP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ + +/* ------------------------- Interrupt Number Definition ------------------------ */ + +/** Device specific Interrupt IDs */ +typedef enum IRQn +{ + /****** SGI Interrupts Numbers ****************************************/ + SGI0_IRQn = 0, /*!< Software Generated Interrupt 0 */ + SGI1_IRQn = 1, /*!< Software Generated Interrupt 1 */ + SGI2_IRQn = 2, /*!< Software Generated Interrupt 2 */ + SGI3_IRQn = 3, /*!< Software Generated Interrupt 3 */ + SGI4_IRQn = 4, /*!< Software Generated Interrupt 4 */ + SGI5_IRQn = 5, /*!< Software Generated Interrupt 5 */ + SGI6_IRQn = 6, /*!< Software Generated Interrupt 6 */ + SGI7_IRQn = 7, /*!< Software Generated Interrupt 7 */ + SGI8_IRQn = 8, /*!< Software Generated Interrupt 8 */ + SGI9_IRQn = 9, /*!< Software Generated Interrupt 9 */ + SGI10_IRQn = 10, /*!< Software Generated Interrupt 10 */ + SGI11_IRQn = 11, /*!< Software Generated Interrupt 11 */ + SGI12_IRQn = 12, /*!< Software Generated Interrupt 12 */ + SGI13_IRQn = 13, /*!< Software Generated Interrupt 13 */ + SGI14_IRQn = 14, /*!< Software Generated Interrupt 14 */ + SGI15_IRQn = 15, /*!< Software Generated Interrupt 15 */ + + /****** Cortex-A7 Processor Exceptions Numbers ****************************************/ + SecurePhyTimer_IRQn = 29, /*!< Physical Timer Interrupt */ + + /****** Platform Exceptions Numbers ***************************************************/ + WAKEUP_IRQn = 32, /*!< Wakeup Interrupt */ + CODEC_IRQn = 33, /*!< CODEC Interrupt */ + CODEC_TX_PEAK_IRQn = 34, /*!< CODEC TX PEAK Interrupt */ + SDMMC_IRQn = 35, /*!< SDMMC Interrupt */ + BES2001_AUDMA_IRQn = 36, /*!< Audio DMA Interrupt */ + BES2001_GPDMA_IRQn = 37, /*!< General Purpose DMA Interrupt */ + USB_IRQn = 38, /*!< USB Interrupt */ + USB_PHY_IRQn = 39, /*!< USB PHY Interrupt */ + USB_CAL_IRQn = 40, /*!< USB Calibration Interrupt */ + USB_PIN_IRQn = 41, /*!< USB Pin Interrupt */ + SEC_ENG_IRQn = 42, /*!< Security Engine Interrupt */ + SEDMA_IRQn = 43, /*!< SEDMA Interrupt */ + DUMP_IRQn = 44, /*!< DUMP Interrupt */ + MCU_WDT_IRQn = 45, /*!< Watchdog Timer Interrupt */ + MCU_TIMER00_IRQn = 46, /*!< Timer00 Interrupt */ + MCU_TIMER01_IRQn = 47, /*!< Timer01 Interrupt */ + MCU_TIMER10_IRQn = 48, /*!< Timer10 Interrupt */ + MCU_TIMER11_IRQn = 49, /*!< Timer11 Interrupt */ + MCU_TIMER20_IRQn = 50, /*!< Timer20 Interrupt */ + MCU_TIMER21_IRQn = 51, /*!< Timer21 Interrupt */ + I2C0_IRQn = 52, /*!< I2C0 Interrupt */ + I2C1_IRQn = 53, /*!< I2C1 Interrupt */ + SPI0_IRQn = 54, /*!< SPI0 Interrupt */ + SPILCD_IRQn = 55, /*!< SPILCD Interrupt */ + ITNSPI_IRQn = 56, /*!< Internal SPI Interrupt */ + SPIPHY_IRQn = 57, /*!< SPIPHY Interrupt */ + UART0_IRQn = 58, /*!< UART0 Interrupt */ + UART1_IRQn = 59, /*!< UART1 Interrupt */ + UART2_IRQn = 60, /*!< UART2 Interrupt */ + BTPCM_IRQn = 61, /*!< BTPCM Interrupt */ + I2S0_IRQn = 62, /*!< I2S0 Interrupt */ + SPDIF0_IRQn = 63, /*!< SPDIF0 Interrupt */ + TRNG_IRQn = 64, /*!< TRNG Interrupt */ + AON_GPIO_IRQn = 65, /*!< AON GPIO Interrupt */ + AON_GPIOAUX_IRQn = 66, /*!< AON GPIOAUX Interrupt */ + AON_WDT_IRQn = 67, /*!< AON Watchdog Timer Interrupt */ + AON_TIMER00_IRQn = 68, /*!< AON Timer00 Interrupt */ + AON_TIMER01_IRQn = 69, /*!< AON Timer01 Interrupt */ + TRANSQW_LCL_IRQn = 70, /*!< TRANSQ-WIFI Local Interrupt */ + TRANSQW_RMT_IRQn = 71, /*!< TRANSQ-WIFI Peer Remote Interrupt */ + WIFI_IRQn = 72, /*!< DSP to MCU Interrupt */ + ISDONE_IRQn = 73, /*!< Intersys MCU2BT Data Done Interrupt */ + ISDONE1_IRQn = 74, /*!< Intersys MCU2BT Data1 Done Interrupt */ + ISDATA_IRQn = 75, /*!< Intersys BT2MCU Data Indication Interrupt */ + ISDATA1_IRQn = 76, /*!< Intersys BT2MCU Data1 Indication Interrupt */ + BT_IRQn = 77, /*!< BT to MCU Interrupt */ + RESERVED58_IRQn = 78, /*!< Reserved Interrupt */ + RTC_IRQn = 79, /*!< RTC Interrupt */ + GPADC_IRQn = 80, /*!< GPADC Interrupt */ + CHARGER_IRQn = 81, /*!< Charger Interrupt */ + PWRKEY_IRQn = 82, /*!< Power key Interrupt */ + WIFIDUMP_IRQn = 83, /*!< WIFIDUMP Interrupt */ + CHKSUM_IRQn = 84, /*!< Checksum Interrupt */ + CRC_IRQn = 85, /*!< CRC Interrupt */ + AON_SPIDPD_IRQn = 86, /*!< AON SPIDPD Interrupt */ + TRUSTZONE_IRQn = 87, /*!< TrustZone Interrupt */ + TRANSQM_LCL_IRQn = 88, /*!< TRANSQ-MCU Local Interrupt */ + TRANSQM_RMT_IRQn = 89, /*!< TRANSQ-MCU Peer Remote Interrupt */ + MCU_IRQn = 90, /*!< MCU to DSP Interrupt */ + DSP_WDT_IRQn = 91, /*!< Watchdog Timer Interrupt */ + DSP_TIMER00_IRQn = 92, /*!< Timer00 Interrupt */ + DSP_TIMER01_IRQn = 93, /*!< Timer01 Interrupt */ + DSP_TIMER10_IRQn = 94, /*!< Timer10 Interrupt */ + DSP_TIMER11_IRQn = DSP_TIMER10_IRQn, /*!< Timer11 Interrupt */ + XDMA_IRQn = 95, /*!< DSP XDMA Interrupt */ + + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#define AUDMA_IRQn BES2001_AUDMA_IRQn //A7 use AUDMA + +#define GPIO_IRQn AON_GPIO_IRQn +#define GPIOAUX_IRQn AON_GPIOAUX_IRQn +#define TIMER00_IRQn DSP_TIMER00_IRQn +#define TIMER01_IRQn DSP_TIMER01_IRQn +#define WDT_IRQn AON_WDT_IRQn + +#define TRANSQ0_RMT_IRQn TRANSQW_RMT_IRQn//use MCU's transq +#define TRANSQ0_LCL_IRQn TRANSQW_LCL_IRQn +#define TRANSQ1_RMT_IRQn TRANSQM_RMT_IRQn +#define TRANSQ1_LCL_IRQn TRANSQM_LCL_IRQn + +#endif + +#if 0 +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ + +/* Peripheral and RAM base address */ +#define VE_A7_MP_FLASH_BASE0 (0x00000000UL) /*!< (FLASH0 ) Base Address */ +#define VE_A7_MP_FLASH_BASE1 (0x0C000000UL) /*!< (FLASH1 ) Base Address */ +#define VE_A7_MP_SRAM_BASE (0x14000000UL) /*!< (SRAM ) Base Address */ +#define VE_A7_MP_PERIPH_BASE_CS2 (0x18000000UL) /*!< (Peripheral ) Base Address */ +#define VE_A7_MP_VRAM_BASE (0x00000000UL + VE_A7_MP_PERIPH_BASE_CS2) /*!< (VRAM ) Base Address */ +#define VE_A7_MP_ETHERNET_BASE (0x02000000UL + VE_A7_MP_PERIPH_BASE_CS2) /*!< (ETHERNET ) Base Address */ +#define VE_A7_MP_USB_BASE (0x03000000UL + VE_A7_MP_PERIPH_BASE_CS2) /*!< (USB ) Base Address */ +#define VE_A7_MP_PERIPH_BASE_CS3 (0x1C000000UL) /*!< (Peripheral ) Base Address */ +#define VE_A7_MP_DAP_BASE (0x00000000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (LOCAL DAP ) Base Address */ +#define VE_A7_MP_SYSTEM_REG_BASE (0x00010000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (SYSTEM REG ) Base Address */ +#define VE_A7_MP_SERIAL_BASE (0x00030000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (SERIAL ) Base Address */ +#define VE_A7_MP_AACI_BASE (0x00040000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (AACI ) Base Address */ +#define VE_A7_MP_MMCI_BASE (0x00050000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (MMCI ) Base Address */ +#define VE_A7_MP_KMI0_BASE (0x00060000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (KMI0 ) Base Address */ +#define VE_A7_MP_UART_BASE (0x00090000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (UART ) Base Address */ +#define VE_A7_MP_WDT_BASE (0x000F0000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (WDT ) Base Address */ +#define VE_A7_MP_TIMER_BASE (0x00110000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (TIMER ) Base Address */ +#define VE_A7_MP_DVI_BASE (0x00160000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (DVI ) Base Address */ +#define VE_A7_MP_RTC_BASE (0x00170000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (RTC ) Base Address */ +#define VE_A7_MP_UART4_BASE (0x001B0000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (UART4 ) Base Address */ +#define VE_A7_MP_CLCD_BASE (0x001F0000UL + VE_A7_MP_PERIPH_BASE_CS3) /*!< (CLCD ) Base Address */ +#define VE_A7_MP_PRIVATE_PERIPH_BASE (0x2C000000UL) /*!< (Peripheral ) Base Address */ +#define VE_A7_MP_GIC_DISTRIBUTOR_BASE (0x00001000UL + VE_A7_MP_PRIVATE_PERIPH_BASE) /*!< (GIC DIST ) Base Address */ +#define VE_A7_MP_GIC_INTERFACE_BASE (0x00002000UL + VE_A7_MP_PRIVATE_PERIPH_BASE) /*!< (GIC CPU IF ) Base Address */ +#define VE_A7_MP_PL310_BASE (0x000F0000UL + VE_A7_MP_PRIVATE_PERIPH_BASE) /*!< (L2C-310 ) Base Address */ +#define VE_A7_MP_SSRAM_BASE (0x2E000000UL) /*!< (System SRAM) Base Address */ +#define VE_A7_MP_DRAM_BASE (0x80000000UL) /*!< (DRAM ) Base Address */ +#define GIC_DISTRIBUTOR_BASE VE_A7_MP_GIC_DISTRIBUTOR_BASE +#define GIC_INTERFACE_BASE VE_A7_MP_GIC_INTERFACE_BASE + +//The VE-A7 model implements L1 cache as architecturally defined, but does not implement L2 cache. +//Do not enable the L2 cache if you are running RTX on a VE-A7 model as it may cause a data abort. +#define L2C_310_BASE VE_A7_MP_PL310_BASE +#endif + +/* -------- Configuration of the Cortex-A7 Processor and Core Peripherals ------- */ +#define __CA_REV 0x0000U /* Core revision r0p0 */ +#define __CORTEX_A 7U /* Cortex-A7 Core */ +#define __FPU_PRESENT 1U /* FPU present */ +#define __GIC_PRESENT 1U /* GIC present */ +#define __TIM_PRESENT 1U /* TIM present */ +#define __L2C_PRESENT 0U /* L2C present */ +#define __GIC_PRIO_BITS 3U /* Number of Bits used for Priority Levels */ + +#include "ca/core_ca.h" + +#ifndef __ASSEMBLER__ +#include "ca/system_ARMCA.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/ca/cmsis_armcc_ca.h b/platform/cmsis/inc/ca/cmsis_armcc_ca.h new file mode 100644 index 0000000..44eeb47 --- /dev/null +++ b/platform/cmsis/inc/ca/cmsis_armcc_ca.h @@ -0,0 +1,547 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.3 + * @date 15. May 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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_ARMCC_CA_H +#define __CMSIS_ARMCC_CA_H + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if (defined (__TARGET_ARCH_7_A ) && (__TARGET_ARCH_7_A == 1)) + #define __ARM_ARCH_7A__ 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __forceinline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#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 __packed struct +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __memory_changed() +#endif + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP __nop + +/** + \brief Wait For Interrupt + */ +#define __WFI __wfi + +/** + \brief Wait For Event + */ +#define __WFE __wfe + +/** + \brief Send Event + */ +#define __SEV __sev + +/** + \brief Instruction Synchronization Barrier + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \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 + */ +#define __REV __rev + +/** + \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 + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** + \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 + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + +/** + \brief Rotate Right in unsigned value (32 bit) + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + +/** + \brief Breakpoint + \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) __breakpoint(value) + +/** + \brief Reverse bit order of value + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + +/** + \brief Count leading zeros + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +/** + \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) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \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) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \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) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \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 + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \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 + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \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 + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \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 + */ +#define __SSAT __ssat + +/** + \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 + */ +#define __USAT __usat + +/* ########################### Core Function Access ########################### */ + +/** + \brief Get FPSCR (Floating Point Status/Control) + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + +/** + \brief Set FPSCR (Floating Point Status/Control) + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + +/** \brief Get CPSR (Current Program Status Register) + \return CPSR Register value + */ +__STATIC_INLINE uint32_t __get_CPSR(void) +{ + register uint32_t __regCPSR __ASM("cpsr"); + return(__regCPSR); +} + + +/** \brief Set CPSR (Current Program Status Register) + \param [in] cpsr CPSR value to set + */ +__STATIC_INLINE void __set_CPSR(uint32_t cpsr) +{ + register uint32_t __regCPSR __ASM("cpsr"); + __regCPSR = cpsr; +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_INLINE uint32_t __get_mode(void) +{ + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_INLINE __ASM void __set_mode(uint32_t mode) +{ + MOV r1, lr + MSR CPSR_C, r0 + BX r1 +} + +/** \brief Get Stack Pointer + \return Stack Pointer + */ +__STATIC_INLINE __ASM uint32_t __get_SP(void) +{ + MOV r0, sp + BX lr +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_INLINE __ASM void __set_SP(uint32_t stack) +{ + MOV sp, r0 + BX lr +} + + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYSStack Pointer + */ +__STATIC_INLINE __ASM uint32_t __get_SP_usr(void) +{ + ARM + PRESERVE8 + + MRS R1, CPSR + CPS #0x1F ;no effect in USR mode + MOV R0, SP + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR +} + +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_INLINE __ASM void __set_SP_usr(uint32_t topOfProcStack) +{ + ARM + PRESERVE8 + + MRS R1, CPSR + CPS #0x1F ;no effect in USR mode + MOV SP, R0 + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR +} + +/** \brief Get FPEXC (Floating Point Exception Control Register) + \return Floating Point Exception Control Register value + */ +__STATIC_INLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + register uint32_t __regfpexc __ASM("fpexc"); + return(__regfpexc); +#else + return(0); +#endif +} + +/** \brief Set FPEXC (Floating Point Exception Control Register) + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_INLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + register uint32_t __regfpexc __ASM("fpexc"); + __regfpexc = (fpexc); +#endif +} + +/* + * Include common core functions to access Coprocessor 15 registers + */ + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); (Rt) = tmp; } while(0) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); tmp = (Rt); } while(0) +#define __get_CP64(cp, op1, Rt, CRm) \ + do { \ + uint32_t ltmp, htmp; \ + __ASM volatile("MRRC p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \ + (Rt) = ((((uint64_t)htmp) << 32U) | ((uint64_t)ltmp)); \ + } while(0) + +#define __set_CP64(cp, op1, Rt, CRm) \ + do { \ + const uint64_t tmp = (Rt); \ + const uint32_t ltmp = (uint32_t)(tmp); \ + const uint32_t htmp = (uint32_t)(tmp >> 32U); \ + __ASM volatile("MCRR p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \ + } while(0) + +#include "ca/cmsis_cp15_ca.h" + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE __ASM void __FPU_Enable(void) +{ + ARM + + //Permit access to VFP/NEON, registers by modifying CPACR + MRC p15,0,R1,c1,c0,2 + ORR R1,R1,#0x00F00000 + MCR p15,0,R1,c1,c0,2 + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + ISB + + //Enable VFP/NEON + VMRS R1,FPEXC + ORR R1,R1,#0x40000000 + VMSR FPEXC,R1 + + //Initialise VFP/NEON registers to 0 + MOV R2,#0 + + //Initialise D16 registers to 0 + VMOV D0, R2,R2 + VMOV D1, R2,R2 + VMOV D2, R2,R2 + VMOV D3, R2,R2 + VMOV D4, R2,R2 + VMOV D5, R2,R2 + VMOV D6, R2,R2 + VMOV D7, R2,R2 + VMOV D8, R2,R2 + VMOV D9, R2,R2 + VMOV D10,R2,R2 + VMOV D11,R2,R2 + VMOV D12,R2,R2 + VMOV D13,R2,R2 + VMOV D14,R2,R2 + VMOV D15,R2,R2 + + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + //Initialise D32 registers to 0 + VMOV D16,R2,R2 + VMOV D17,R2,R2 + VMOV D18,R2,R2 + VMOV D19,R2,R2 + VMOV D20,R2,R2 + VMOV D21,R2,R2 + VMOV D22,R2,R2 + VMOV D23,R2,R2 + VMOV D24,R2,R2 + VMOV D25,R2,R2 + VMOV D26,R2,R2 + VMOV D27,R2,R2 + VMOV D28,R2,R2 + VMOV D29,R2,R2 + VMOV D30,R2,R2 + VMOV D31,R2,R2 + ENDIF + + //Initialise FPSCR to a known state + VMRS R1,FPSCR + LDR R2,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + AND R1,R1,R2 + VMSR FPSCR,R1 + + BX LR +} + +#endif /* __CMSIS_ARMCC_CA_H */ diff --git a/platform/cmsis/inc/ca/cmsis_armclang_ca.h b/platform/cmsis/inc/ca/cmsis_armclang_ca.h new file mode 100644 index 0000000..2568ffe --- /dev/null +++ b/platform/cmsis/inc/ca/cmsis_armclang_ca.h @@ -0,0 +1,585 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.1.1 + * @date 15. May 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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_ARMCLANG_CA_H +#define __CMSIS_ARMCLANG_CA_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_CA_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __attribute__((always_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 CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#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 __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang 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 __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + */ +#define __WFI __builtin_arm_wfi + +/** + \brief Wait For Event + */ +#define __WFE __builtin_arm_wfe + +/** + \brief Send Event + */ +#define __SEV __builtin_arm_sev + +/** + \brief Instruction Synchronization Barrier + */ +#define __ISB() do {\ + __schedule_barrier();\ + __builtin_arm_isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + */ +#define __DSB() do {\ + __schedule_barrier();\ + __builtin_arm_dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + */ +#define __DMB() do {\ + __schedule_barrier();\ + __builtin_arm_dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \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 + */ +#define __REV(value) __builtin_bswap32(value) + +/** + \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 + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \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 + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \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 + \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 + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \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 Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + +/** + \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) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \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) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + +/** + \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) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + +/** + \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 + */ +#define __STREXB (uint32_t)__builtin_arm_strex + +/** + \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 + */ +#define __STREXH (uint32_t)__builtin_arm_strex + +/** + \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 + */ +#define __STREXW (uint32_t)__builtin_arm_strex + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +/** + \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 + */ +#define __SSAT __builtin_arm_ssat + +/** + \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 + */ +#define __USAT __builtin_arm_usat + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __QADD8 __builtin_arm_qadd8 +#define __QSUB8 __builtin_arm_qsub8 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __SXTB16 __builtin_arm_sxtb16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSDX __builtin_arm_smlsdx + + + +__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) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ + +/* ########################### Core Function Access ########################### */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#define __get_FPSCR __builtin_arm_get_fpscr + +/** + \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 + */ +#define __set_FPSCR __builtin_arm_set_fpscr + +/** \brief Get CPSR Register + \return CPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPSR(void) +{ + uint32_t result; + __ASM volatile("MRS %0, cpsr" : "=r" (result) ); + return(result); +} + +/** \brief Set CPSR Register + \param [in] cpsr CPSR value to set + */ +__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr) +{ +__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory"); +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_FORCEINLINE uint32_t __get_mode(void) +{ + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_FORCEINLINE void __set_mode(uint32_t mode) +{ + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); +} + +/** \brief Get Stack Pointer + \return Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP() +{ + uint32_t result; + __ASM volatile("MOV %0, sp" : "=r" (result) : : "memory"); + return result; +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP(uint32_t stack) +{ + __ASM volatile("MOV sp, %0" : : "r" (stack) : "memory"); +} + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYS Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP_usr() +{ + uint32_t cpsr; + uint32_t result; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV %1, sp \n" + "MSR cpsr_c, %0 \n" // no effect in USR mode + "ISB" : "=r"(cpsr), "=r"(result) : : "memory" + ); + return result; +} + +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV sp, %1 \n" + "MSR cpsr_c, %0 \n" // no effect in USR mode + "ISB" : "=r"(cpsr) : "r" (topOfProcStack) : "memory" + ); +} + +/** \brief Get FPEXC + \return Floating Point Exception Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); + return(result); +#else + return(0); +#endif +} + +/** \brief Set FPEXC + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); +#endif +} + +/* + * Include common core functions to access Coprocessor 15 registers + */ + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) +#define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) +#define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + +#include "ca/cmsis_cp15_ca.h" + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE void __FPU_Enable(void) +{ + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" + +#if __ARM_NEON == 1 + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" +#endif + + //Initialise FPSCR to a known state + " VMRS R1,FPSCR \n" + " LDR R2,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R1,R1,R2 \n" + " VMSR FPSCR,R1 " + : : : "cc", "r1", "r2" + ); +} + +#endif /* __CMSIS_ARMCLANG_CA_H */ diff --git a/platform/cmsis/inc/ca/cmsis_compiler_ca.h b/platform/cmsis/inc/ca/cmsis_compiler_ca.h new file mode 100644 index 0000000..2c2cbc5 --- /dev/null +++ b/platform/cmsis/inc/ca/cmsis_compiler_ca.h @@ -0,0 +1,213 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.2 + * @date 10. January 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_CA_H +#define __CMSIS_COMPILER_CA_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "ca/cmsis_armcc_ca.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "ca/cmsis_armclang_ca.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "ca/cmsis_gcc_ca.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include "ca/cmsis_iccarm_ca.h" + + +/* + * 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_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 CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __UNALIGNED_UINT32 + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #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 CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __UNALIGNED_UINT32 + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #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 CMSIS_DEPRECATED + #warning No compiler specific solution for CMSIS_DEPRECATED. CMSIS_DEPRECATED is ignored. + #define CMSIS_DEPRECATED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __UNALIGNED_UINT32 + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __PACKED + #define __PACKED @packed + #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_CA_H */ + diff --git a/platform/cmsis/inc/ca/cmsis_cp15_ca.h b/platform/cmsis/inc/ca/cmsis_cp15_ca.h new file mode 100644 index 0000000..f273b53 --- /dev/null +++ b/platform/cmsis/inc/ca/cmsis_cp15_ca.h @@ -0,0 +1,514 @@ +/**************************************************************************//** + * @file cmsis_cp15.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.1 + * @date 07. Sep 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 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_CP15_CA_H +#define __CMSIS_CP15_CA_H + +/** \brief Get ACTLR + \return Auxiliary Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_ACTLR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 1); + return(result); +} + +/** \brief Set ACTLR + \param [in] actlr Auxiliary Control value to set + */ +__STATIC_FORCEINLINE void __set_ACTLR(uint32_t actlr) +{ + __set_CP(15, 0, actlr, 1, 0, 1); +} + +/** \brief Get CPACR + \return Coprocessor Access Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPACR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 2); + return result; +} + +/** \brief Set CPACR + \param [in] cpacr Coprocessor Access Control value to set + */ +__STATIC_FORCEINLINE void __set_CPACR(uint32_t cpacr) +{ + __set_CP(15, 0, cpacr, 1, 0, 2); +} + +/** \brief Get DFSR + \return Data Fault Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_DFSR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 5, 0, 0); + return result; +} + +/** \brief Set DFSR + \param [in] dfsr Data Fault Status value to set + */ +__STATIC_FORCEINLINE void __set_DFSR(uint32_t dfsr) +{ + __set_CP(15, 0, dfsr, 5, 0, 0); +} + +/** \brief Get IFSR + \return Instruction Fault Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IFSR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 5, 0, 1); + return result; +} + +/** \brief Set IFSR + \param [in] ifsr Instruction Fault Status value to set + */ +__STATIC_FORCEINLINE void __set_IFSR(uint32_t ifsr) +{ + __set_CP(15, 0, ifsr, 5, 0, 1); +} + +/** \brief Get ISR + \return Interrupt Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_ISR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 12, 1, 0); + return result; +} + +/** \brief Get CBAR + \return Configuration Base Address register value + */ +__STATIC_FORCEINLINE uint32_t __get_CBAR(void) +{ + uint32_t result; + __get_CP(15, 4, result, 15, 0, 0); + return result; +} + +/** \brief Get TTBR0 + + This function returns the value of the Translation Table Base Register 0. + + \return Translation Table Base Register 0 value + */ +__STATIC_FORCEINLINE uint32_t __get_TTBR0(void) +{ + uint32_t result; + __get_CP(15, 0, result, 2, 0, 0); + return result; +} + +/** \brief Set TTBR0 + + This function assigns the given value to the Translation Table Base Register 0. + + \param [in] ttbr0 Translation Table Base Register 0 value to set + */ +__STATIC_FORCEINLINE void __set_TTBR0(uint32_t ttbr0) +{ + __set_CP(15, 0, ttbr0, 2, 0, 0); +} + +/** \brief Get DACR + + This function returns the value of the Domain Access Control Register. + + \return Domain Access Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_DACR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 3, 0, 0); + return result; +} + +/** \brief Set DACR + + This function assigns the given value to the Domain Access Control Register. + + \param [in] dacr Domain Access Control Register value to set + */ +__STATIC_FORCEINLINE void __set_DACR(uint32_t dacr) +{ + __set_CP(15, 0, dacr, 3, 0, 0); +} + +/** \brief Set SCTLR + + This function assigns the given value to the System Control Register. + + \param [in] sctlr System Control Register value to set + */ +__STATIC_FORCEINLINE void __set_SCTLR(uint32_t sctlr) +{ + __set_CP(15, 0, sctlr, 1, 0, 0); +} + +/** \brief Get SCTLR + \return System Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_SCTLR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 0); + return result; +} + +/** \brief Set ACTRL + \param [in] actrl Auxiliary Control Register value to set + */ +__STATIC_FORCEINLINE void __set_ACTRL(uint32_t actrl) +{ + __set_CP(15, 0, actrl, 1, 0, 1); +} + +/** \brief Get ACTRL + \return Auxiliary Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_ACTRL(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 1); + return result; +} + +/** \brief Get MPIDR + + This function returns the value of the Multiprocessor Affinity Register. + + \return Multiprocessor Affinity Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MPIDR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 0, 0, 5); + return result; +} + +/** \brief Get VBAR + + This function returns the value of the Vector Base Address Register. + + \return Vector Base Address Register + */ +__STATIC_FORCEINLINE uint32_t __get_VBAR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 12, 0, 0); + return result; +} + +/** \brief Set VBAR + + This function assigns the given value to the Vector Base Address Register. + + \param [in] vbar Vector Base Address Register value to set + */ +__STATIC_FORCEINLINE void __set_VBAR(uint32_t vbar) +{ + __set_CP(15, 0, vbar, 12, 0, 0); +} + +/** \brief Get MVBAR + + This function returns the value of the Monitor Vector Base Address Register. + + \return Monitor Vector Base Address Register + */ +__STATIC_FORCEINLINE uint32_t __get_MVBAR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 12, 0, 1); + return result; +} + +/** \brief Set MVBAR + + This function assigns the given value to the Monitor Vector Base Address Register. + + \param [in] mvbar Monitor Vector Base Address Register value to set + */ +__STATIC_FORCEINLINE void __set_MVBAR(uint32_t mvbar) +{ + __set_CP(15, 0, mvbar, 12, 0, 1); +} + +#if (defined(__CORTEX_A) && (__CORTEX_A == 7U) && \ + defined(__TIM_PRESENT) && (__TIM_PRESENT == 1U)) || \ + defined(DOXYGEN) + +/** \brief Set CNTFRQ + + This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ). + + \param [in] value CNTFRQ Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTFRQ(uint32_t value) +{ + __set_CP(15, 0, value, 14, 0, 0); +} + +/** \brief Get CNTFRQ + + This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ). + + \return CNTFRQ Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTFRQ(void) +{ + uint32_t result; + __get_CP(15, 0, result, 14, 0 , 0); + return result; +} + +/** \brief Set CNTP_TVAL + + This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL). + + \param [in] value CNTP_TVAL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_TVAL(uint32_t value) +{ + __set_CP(15, 0, value, 14, 2, 0); +} + +/** \brief Get CNTP_TVAL + + This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL). + + \return CNTP_TVAL Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTP_TVAL(void) +{ + uint32_t result; + __get_CP(15, 0, result, 14, 2, 0); + return result; +} + +/** \brief Get CNTPCT + + This function returns the value of the 64 bits PL1 Physical Count Register (CNTPCT). + + \return CNTPCT Register value + */ +__STATIC_FORCEINLINE uint64_t __get_CNTPCT(void) +{ + uint64_t result; + __get_CP64(15, 0, result, 14); + return result; +} + +/** \brief Set CNTP_CVAL + + This function assigns the given value to 64bits PL1 Physical Timer CompareValue Register (CNTP_CVAL). + + \param [in] value CNTP_CVAL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_CVAL(uint64_t value) +{ + __set_CP64(15, 2, value, 14); +} + +/** \brief Get CNTP_CVAL + + This function returns the value of the 64 bits PL1 Physical Timer CompareValue Register (CNTP_CVAL). + + \return CNTP_CVAL Register value + */ +__STATIC_FORCEINLINE uint64_t __get_CNTP_CVAL(void) +{ + uint64_t result; + __get_CP64(15, 2, result, 14); + return result; +} + +/** \brief Set CNTP_CTL + + This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL). + + \param [in] value CNTP_CTL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_CTL(uint32_t value) +{ + __set_CP(15, 0, value, 14, 2, 1); +} + +/** \brief Get CNTP_CTL register + \return CNTP_CTL Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTP_CTL(void) +{ + uint32_t result; + __get_CP(15, 0, result, 14, 2, 1); + return result; +} + +#endif + +/** \brief Set TLBIALL + + TLB Invalidate All + */ +__STATIC_FORCEINLINE void __set_TLBIALL(uint32_t value) +{ + __set_CP(15, 0, value, 8, 7, 0); +} + +/** \brief Set BPIALL. + + Branch Predictor Invalidate All + */ +__STATIC_FORCEINLINE void __set_BPIALL(uint32_t value) +{ + __set_CP(15, 0, value, 7, 5, 6); +} + +/** \brief Set ICIALLU + + Instruction Cache Invalidate All + */ +__STATIC_FORCEINLINE void __set_ICIALLU(uint32_t value) +{ + __set_CP(15, 0, value, 7, 5, 0); +} + +/** \brief Set DCCMVAC + + Data cache clean + */ +__STATIC_FORCEINLINE void __set_DCCMVAC(uint32_t value) +{ + __set_CP(15, 0, value, 7, 10, 1); +} + +/** \brief Set DCIMVAC + + Data cache invalidate + */ +__STATIC_FORCEINLINE void __set_DCIMVAC(uint32_t value) +{ + __set_CP(15, 0, value, 7, 6, 1); +} + +/** \brief Set DCCIMVAC + + Data cache clean and invalidate + */ +__STATIC_FORCEINLINE void __set_DCCIMVAC(uint32_t value) +{ + __set_CP(15, 0, value, 7, 14, 1); +} + +/** \brief Set CSSELR + */ +__STATIC_FORCEINLINE void __set_CSSELR(uint32_t value) +{ +// __ASM volatile("MCR p15, 2, %0, c0, c0, 0" : : "r"(value) : "memory"); + __set_CP(15, 2, value, 0, 0, 0); +} + +/** \brief Get CSSELR + \return CSSELR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CSSELR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 2, %0, c0, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 2, result, 0, 0, 0); + return result; +} + +/** \brief Set CCSIDR + \deprecated CCSIDR itself is read-only. Use __set_CSSELR to select cache level instead. + */ +CMSIS_DEPRECATED +__STATIC_FORCEINLINE void __set_CCSIDR(uint32_t value) +{ + __set_CSSELR(value); +} + +/** \brief Get CCSIDR + \return CCSIDR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CCSIDR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 1, %0, c0, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 1, result, 0, 0, 0); + return result; +} + +/** \brief Get CLIDR + \return CLIDR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CLIDR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 1, %0, c0, c0, 1" : "=r"(result) : : "memory"); + __get_CP(15, 1, result, 0, 0, 1); + return result; +} + +/** \brief Set DCISW + */ +__STATIC_FORCEINLINE void __set_DCISW(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c6, 2" : : "r"(value) : "memory") + __set_CP(15, 0, value, 7, 6, 2); +} + +/** \brief Set DCCSW + */ +__STATIC_FORCEINLINE void __set_DCCSW(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c10, 2" : : "r"(value) : "memory") + __set_CP(15, 0, value, 7, 10, 2); +} + +/** \brief Set DCCISW + */ +__STATIC_FORCEINLINE void __set_DCCISW(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c14, 2" : : "r"(value) : "memory") + __set_CP(15, 0, value, 7, 14, 2); +} + +#endif diff --git a/platform/cmsis/inc/ca/cmsis_gcc_ca.h b/platform/cmsis/inc/ca/cmsis_gcc_ca.h new file mode 100644 index 0000000..44ee6d6 --- /dev/null +++ b/platform/cmsis/inc/ca/cmsis_gcc_ca.h @@ -0,0 +1,814 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.2.0 + * @date 17. May 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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_CA_H +#define __CMSIS_GCC_CA_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 __FORCEINLINE + #define __FORCEINLINE __attribute__((always_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 CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#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 __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __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" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __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" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __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" + __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 __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %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 volatile ("qadd16 %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 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 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); +} + +__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); +} + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +__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 __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 __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 __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 int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + + + + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + */ +#define __WFI() __ASM volatile ("wfi") + +/** + \brief Wait For Event + */ +#define __WFE() __ASM volatile ("wfe") + +/** + \brief Send Event + */ +#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 volatile ("rev %0, %1" : "=r" (result) : "r" (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 + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + __ASM volatile("rev16 %0, %1" : "=r" (result) : "r" (value)); + return result; +} +#endif + +/** + \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 volatile ("revsh %0, %1" : "=r" (result) : "r" (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 + \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 volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_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; 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 + \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); +} + +/** + \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"); +} + +/** + \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 + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \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 + */ +#define __USAT(ARG1,ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +/* ########################### Core Function Access ########################### */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + 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 the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + +/** + \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 +} + +/** \brief Get CPSR Register + \return CPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPSR(void) +{ + uint32_t result; + __ASM volatile("MRS %0, cpsr" : "=r" (result) ); + return(result); +} + +/** \brief Set CPSR Register + \param [in] cpsr CPSR value to set + */ +__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr) +{ +__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory"); +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_FORCEINLINE uint32_t __get_mode(void) +{ + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_FORCEINLINE void __set_mode(uint32_t mode) +{ + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); +} + +/** \brief Get Stack Pointer + \return Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP(void) +{ + uint32_t result; + __ASM volatile("MOV %0, sp" : "=r" (result) : : "memory"); + return result; +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP(uint32_t stack) +{ + __ASM volatile("MOV sp, %0" : : "r" (stack) : "memory"); +} + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYS Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP_usr(void) +{ + uint32_t cpsr = __get_CPSR(); + uint32_t result; + __ASM volatile( + "CPS #0x1F \n" + "MOV %0, sp " : "=r"(result) : : "memory" + ); + __set_CPSR(cpsr); + __ISB(); + return result; +} + +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr = __get_CPSR(); + __ASM volatile( + "CPS #0x1F \n" + "MOV sp, %0 " : : "r" (topOfProcStack) : "memory" + ); + __set_CPSR(cpsr); + __ISB(); +} + +/** \brief Get FPEXC + \return Floating Point Exception Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) ); + return(result); +#else + return(0); +#endif +} + +/** \brief Set FPEXC + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); +#endif +} + +/* + * Include common core functions to access Coprocessor 15 registers + */ + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) +#define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) +#define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + +#include "ca/cmsis_cp15_ca.h" + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE void __FPU_Enable(void) +{ + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" + +#if (defined(__ARM_NEON) && (__ARM_NEON == 1)) + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" +#endif + + //Initialise FPSCR to a known state + " VMRS R1,FPSCR \n" + " LDR R2,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R1,R1,R2 \n" + " VMSR FPSCR,R1 " + : : : "cc", "r1", "r2" + ); +} + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_CA_H */ diff --git a/platform/cmsis/inc/ca/cmsis_iccarm_ca.h b/platform/cmsis/inc/ca/cmsis_iccarm_ca.h new file mode 100644 index 0000000..2472406 --- /dev/null +++ b/platform/cmsis/inc/ca/cmsis_iccarm_ca.h @@ -0,0 +1,571 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.7 + * @date 15. May 2019 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// Copyright (c) 2018-2019 Arm Limited +// +// 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. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_CA_H__ +#define __CMSIS_ICCARM_CA_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#pragma language=extended + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_7A__ +/* Macro already defined */ +#else + #if defined(__ARM7A__) + #define __ARM_ARCH_7A__ 1 + #endif +#endif + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #if __ICCARM_V8 + #define __RESTRICT __restrict + #else + /* Needs IAR language extensions */ + #define __RESTRICT restrict + #endif +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#endif + +#ifndef __UNALIGNED_UINT16_READ + #pragma language=save + #pragma language=extended + __IAR_FT uint16_t __iar_uint16_read(void const *ptr) + { + return *(__packed uint16_t*)(ptr); + } + #pragma language=restore + #define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE + #pragma language=save + #pragma language=extended + __IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) + { + *(__packed uint16_t*)(ptr) = val;; + } + #pragma language=restore + #define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ + #pragma language=save + #pragma language=extended + __IAR_FT uint32_t __iar_uint32_read(void const *ptr) + { + return *(__packed uint32_t*)(ptr); + } + #pragma language=restore + #define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE + #pragma language=save + #pragma language=extended + __IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) + { + *(__packed uint32_t*)(ptr) = val;; + } + #pragma language=restore + #define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#if 0 +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma language=save + #pragma language=extended + __packed struct __iar_u32 { uint32_t v; }; + #pragma language=restore + #define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __enable_irq __iar_builtin_enable_interrupt + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + #if __FPU_PRESENT + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #else + #define __get_FPSCR() ( 0 ) + #endif + + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", VALUE)) + + #define __get_CPSR() (__arm_rsr("CPSR")) + #define __get_mode() (__get_CPSR() & 0x1FU) + + #define __set_CPSR(VALUE) (__arm_wsr("CPSR", (VALUE))) + #define __set_mode(VALUE) (__arm_wsr("CPSR_c", (VALUE))) + + + #define __get_FPEXC() (__arm_rsr("FPEXC")) + #define __set_FPEXC(VALUE) (__arm_wsr("FPEXC", VALUE)) + + #define __get_CP(cp, op1, RT, CRn, CRm, op2) \ + ((RT) = __arm_rsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2)) + + #define __set_CP(cp, op1, RT, CRn, CRm, op2) \ + (__arm_wsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2, (RT))) + + #define __get_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) + + #define __set_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + + #include "ca/cmsis_cp15_ca.h" + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #define __SSAT __iar_builtin_SSAT + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #define __USAT __iar_builtin_USAT + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if !__FPU_PRESENT + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if !__FPU_PRESENT + #define __get_FPSCR() (0) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + __IAR_FT void __set_mode(uint32_t mode) + { + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); + } + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + __IAR_FT uint32_t __get_FPEXC(void) + { + #if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); + return(result); + #else + return(0); + #endif + } + + __IAR_FT void __set_FPEXC(uint32_t fpexc) + { + #if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); + #endif + } + + + #define __get_CP(cp, op1, Rt, CRn, CRm, op2) \ + __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) + #define __set_CP(cp, op1, Rt, CRn, CRm, op2) \ + __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) + #define __get_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) + #define __set_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + + #include "ca/cmsis_cp15_ca.h" + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + + +__IAR_FT uint32_t __get_SP_usr(void) +{ + uint32_t cpsr; + uint32_t result; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV %1, sp \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory" + ); + return result; +} + +__IAR_FT void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV sp, %1 \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory" + ); +} + +#define __get_mode() (__get_CPSR() & 0x1FU) + +__STATIC_INLINE +void __FPU_Enable(void) +{ + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" + +#ifdef __ARM_ADVANCED_SIMD__ + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" +#endif + + //Initialise FPSCR to a known state + " VMRS R1,FPSCR \n" + " MOV32 R2,#0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R1,R1,R2 \n" + " VMSR FPSCR,R1 \n" + : : : "cc", "r1", "r2" + ); +} + + + +#undef __IAR_FT +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_CA_H__ */ diff --git a/platform/cmsis/inc/ca/core_ca.h b/platform/cmsis/inc/ca/core_ca.h new file mode 100644 index 0000000..bd7d258 --- /dev/null +++ b/platform/cmsis/inc/ca/core_ca.h @@ -0,0 +1,2726 @@ +/**************************************************************************//** + * @file core_ca.h + * @brief CMSIS Cortex-A Core Peripheral Access Layer Header File + * @version V1.0.2 + * @date 12. November 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. + */ + +#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_CA_H_GENERIC +#define __CORE_CA_H_GENERIC + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __ASSEMBLER__ +#define NVIC_SetPriority(irq, prio) GIC_SetPriority(irq, ((prio) << (8 - __GIC_PRIO_BITS))) +#define NVIC_ClearPendingIRQ(irq) GIC_ClearPendingIRQ(irq) +#define NVIC_EnableIRQ(irq) GIC_EnableIRQ(irq) +#define NVIC_DisableIRQ(irq) GIC_DisableIRQ(irq) +//#define NVIC_GetActive(irq) (GIC_GetIRQStatus(irq) & (1 << 1)) +#define NVIC_GetActive(irq) (((GICDistributor->ISACTIVER[(irq) / 32U]) >> ((irq) % 32U)) & 1UL) + +#include "ca/irq_ctrl.h" +#define NVIC_SetVector(irq, vector) IRQ_SetHandler(irq, (IRQHandler_t)(vector)) + +uint32_t __get_SPSR(void); +void __set_SPSR(uint32_t spsr); +#endif + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ + +/* CMSIS CA definitions */ +#define __CA_CMSIS_VERSION_MAIN (1U) /*!< \brief [31:16] CMSIS-Core(A) main version */ +#define __CA_CMSIS_VERSION_SUB (1U) /*!< \brief [15:0] CMSIS-Core(A) sub version */ +#define __CA_CMSIS_VERSION ((__CA_CMSIS_VERSION_MAIN << 16U) | \ + __CA_CMSIS_VERSION_SUB ) /*!< \brief CMSIS-Core(A) version number */ + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #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 (__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 ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #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 ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #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 (__FPU_PRESENT == 1) + #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 ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #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 + +#ifndef __ASSEMBLER__ +#include "ca/cmsis_compiler_ca.h" /* CMSIS compiler specific defines */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CA_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CA_H_DEPENDANT +#define __CORE_CA_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + + /* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CA_REV + #define __CA_REV 0x0000U + #warning "__CA_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 __GIC_PRESENT + #define __GIC_PRESENT 1U + #warning "__GIC_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __TIM_PRESENT + #define __TIM_PRESENT 1U + #warning "__TIM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __L2C_PRESENT + #define __L2C_PRESENT 0U + #warning "__L2C_PRESENT not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +#ifdef __cplusplus + #define __I volatile /*!< \brief Defines 'read only' permissions */ +#else + #define __I volatile const /*!< \brief Defines 'read only' permissions */ +#endif +#define __O volatile /*!< \brief Defines 'write only' permissions */ +#define __IO volatile /*!< \brief Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*!< \brief Defines 'read only' structure member permissions */ +#define __OM volatile /*!< \brief Defines 'write only' structure member permissions */ +#define __IOM volatile /*!< \brief Defines 'read / write' structure member permissions */ +#define RESERVED(N, T) T RESERVED##N; // placeholder struct members used for "reserved" areas + +#ifndef __ASSEMBLER__ + + /******************************************************************************* + * Register Abstraction + Core Register contain: + - CPSR + - CP15 Registers + - L2C-310 Cache Controller + - Generic Interrupt Controller Distributor + - Generic Interrupt Controller Interface + ******************************************************************************/ + +/* Core Register CPSR */ +typedef union +{ + struct + { + uint32_t M:5; /*!< \brief bit: 0.. 4 Mode field */ + uint32_t T:1; /*!< \brief bit: 5 Thumb execution state bit */ + uint32_t F:1; /*!< \brief bit: 6 FIQ mask bit */ + uint32_t I:1; /*!< \brief bit: 7 IRQ mask bit */ + uint32_t A:1; /*!< \brief bit: 8 Asynchronous abort mask bit */ + uint32_t E:1; /*!< \brief bit: 9 Endianness execution state bit */ + uint32_t IT1:6; /*!< \brief bit: 10..15 If-Then execution state bits 2-7 */ + uint32_t GE:4; /*!< \brief bit: 16..19 Greater than or Equal flags */ + RESERVED(0:4, uint32_t) + uint32_t J:1; /*!< \brief bit: 24 Jazelle bit */ + uint32_t IT0:2; /*!< \brief bit: 25..26 If-Then execution state bits 0-1 */ + uint32_t Q:1; /*!< \brief bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< \brief bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< \brief bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< \brief bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< \brief bit: 31 Negative condition code flag */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CPSR_Type; + + + +/* CPSR Register Definitions */ +#define CPSR_N_Pos 31U /*!< \brief CPSR: N Position */ +#define CPSR_N_Msk (1UL << CPSR_N_Pos) /*!< \brief CPSR: N Mask */ + +#define CPSR_Z_Pos 30U /*!< \brief CPSR: Z Position */ +#define CPSR_Z_Msk (1UL << CPSR_Z_Pos) /*!< \brief CPSR: Z Mask */ + +#define CPSR_C_Pos 29U /*!< \brief CPSR: C Position */ +#define CPSR_C_Msk (1UL << CPSR_C_Pos) /*!< \brief CPSR: C Mask */ + +#define CPSR_V_Pos 28U /*!< \brief CPSR: V Position */ +#define CPSR_V_Msk (1UL << CPSR_V_Pos) /*!< \brief CPSR: V Mask */ + +#define CPSR_Q_Pos 27U /*!< \brief CPSR: Q Position */ +#define CPSR_Q_Msk (1UL << CPSR_Q_Pos) /*!< \brief CPSR: Q Mask */ + +#define CPSR_IT0_Pos 25U /*!< \brief CPSR: IT0 Position */ +#define CPSR_IT0_Msk (3UL << CPSR_IT0_Pos) /*!< \brief CPSR: IT0 Mask */ + +#define CPSR_J_Pos 24U /*!< \brief CPSR: J Position */ +#define CPSR_J_Msk (1UL << CPSR_J_Pos) /*!< \brief CPSR: J Mask */ + +#define CPSR_GE_Pos 16U /*!< \brief CPSR: GE Position */ +#define CPSR_GE_Msk (0xFUL << CPSR_GE_Pos) /*!< \brief CPSR: GE Mask */ + +#define CPSR_IT1_Pos 10U /*!< \brief CPSR: IT1 Position */ +#define CPSR_IT1_Msk (0x3FUL << CPSR_IT1_Pos) /*!< \brief CPSR: IT1 Mask */ + +#define CPSR_E_Pos 9U /*!< \brief CPSR: E Position */ +#define CPSR_E_Msk (1UL << CPSR_E_Pos) /*!< \brief CPSR: E Mask */ + +#define CPSR_A_Pos 8U /*!< \brief CPSR: A Position */ +#define CPSR_A_Msk (1UL << CPSR_A_Pos) /*!< \brief CPSR: A Mask */ + +#define CPSR_I_Pos 7U /*!< \brief CPSR: I Position */ +#define CPSR_I_Msk (1UL << CPSR_I_Pos) /*!< \brief CPSR: I Mask */ + +#define CPSR_F_Pos 6U /*!< \brief CPSR: F Position */ +#define CPSR_F_Msk (1UL << CPSR_F_Pos) /*!< \brief CPSR: F Mask */ + +#define CPSR_T_Pos 5U /*!< \brief CPSR: T Position */ +#define CPSR_T_Msk (1UL << CPSR_T_Pos) /*!< \brief CPSR: T Mask */ + +#define CPSR_M_Pos 0U /*!< \brief CPSR: M Position */ +#define CPSR_M_Msk (0x1FUL << CPSR_M_Pos) /*!< \brief CPSR: M Mask */ + +#define CPSR_M_USR 0x10U /*!< \brief CPSR: M User mode (PL0) */ +#define CPSR_M_FIQ 0x11U /*!< \brief CPSR: M Fast Interrupt mode (PL1) */ +#define CPSR_M_IRQ 0x12U /*!< \brief CPSR: M Interrupt mode (PL1) */ +#define CPSR_M_SVC 0x13U /*!< \brief CPSR: M Supervisor mode (PL1) */ +#define CPSR_M_MON 0x16U /*!< \brief CPSR: M Monitor mode (PL1) */ +#define CPSR_M_ABT 0x17U /*!< \brief CPSR: M Abort mode (PL1) */ +#define CPSR_M_HYP 0x1AU /*!< \brief CPSR: M Hypervisor mode (PL2) */ +#define CPSR_M_UND 0x1BU /*!< \brief CPSR: M Undefined mode (PL1) */ +#define CPSR_M_SYS 0x1FU /*!< \brief CPSR: M System mode (PL1) */ + +/* CP15 Register SCTLR */ +typedef union +{ + struct + { + uint32_t M:1; /*!< \brief bit: 0 MMU enable */ + uint32_t A:1; /*!< \brief bit: 1 Alignment check enable */ + uint32_t C:1; /*!< \brief bit: 2 Cache enable */ + RESERVED(0:2, uint32_t) + uint32_t CP15BEN:1; /*!< \brief bit: 5 CP15 barrier enable */ + RESERVED(1:1, uint32_t) + uint32_t B:1; /*!< \brief bit: 7 Endianness model */ + RESERVED(2:2, uint32_t) + uint32_t SW:1; /*!< \brief bit: 10 SWP and SWPB enable */ + uint32_t Z:1; /*!< \brief bit: 11 Branch prediction enable */ + uint32_t I:1; /*!< \brief bit: 12 Instruction cache enable */ + uint32_t V:1; /*!< \brief bit: 13 Vectors bit */ + uint32_t RR:1; /*!< \brief bit: 14 Round Robin select */ + RESERVED(3:2, uint32_t) + uint32_t HA:1; /*!< \brief bit: 17 Hardware Access flag enable */ + RESERVED(4:1, uint32_t) + uint32_t WXN:1; /*!< \brief bit: 19 Write permission implies XN */ + uint32_t UWXN:1; /*!< \brief bit: 20 Unprivileged write permission implies PL1 XN */ + uint32_t FI:1; /*!< \brief bit: 21 Fast interrupts configuration enable */ + uint32_t U:1; /*!< \brief bit: 22 Alignment model */ + RESERVED(5:1, uint32_t) + uint32_t VE:1; /*!< \brief bit: 24 Interrupt Vectors Enable */ + uint32_t EE:1; /*!< \brief bit: 25 Exception Endianness */ + RESERVED(6:1, uint32_t) + uint32_t NMFI:1; /*!< \brief bit: 27 Non-maskable FIQ (NMFI) support */ + uint32_t TRE:1; /*!< \brief bit: 28 TEX remap enable. */ + uint32_t AFE:1; /*!< \brief bit: 29 Access flag enable */ + uint32_t TE:1; /*!< \brief bit: 30 Thumb Exception enable */ + RESERVED(7:1, uint32_t) + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} SCTLR_Type; + +#define SCTLR_TE_Pos 30U /*!< \brief SCTLR: TE Position */ +#define SCTLR_TE_Msk (1UL << SCTLR_TE_Pos) /*!< \brief SCTLR: TE Mask */ + +#define SCTLR_AFE_Pos 29U /*!< \brief SCTLR: AFE Position */ +#define SCTLR_AFE_Msk (1UL << SCTLR_AFE_Pos) /*!< \brief SCTLR: AFE Mask */ + +#define SCTLR_TRE_Pos 28U /*!< \brief SCTLR: TRE Position */ +#define SCTLR_TRE_Msk (1UL << SCTLR_TRE_Pos) /*!< \brief SCTLR: TRE Mask */ + +#define SCTLR_NMFI_Pos 27U /*!< \brief SCTLR: NMFI Position */ +#define SCTLR_NMFI_Msk (1UL << SCTLR_NMFI_Pos) /*!< \brief SCTLR: NMFI Mask */ + +#define SCTLR_EE_Pos 25U /*!< \brief SCTLR: EE Position */ +#define SCTLR_EE_Msk (1UL << SCTLR_EE_Pos) /*!< \brief SCTLR: EE Mask */ + +#define SCTLR_VE_Pos 24U /*!< \brief SCTLR: VE Position */ +#define SCTLR_VE_Msk (1UL << SCTLR_VE_Pos) /*!< \brief SCTLR: VE Mask */ + +#define SCTLR_U_Pos 22U /*!< \brief SCTLR: U Position */ +#define SCTLR_U_Msk (1UL << SCTLR_U_Pos) /*!< \brief SCTLR: U Mask */ + +#define SCTLR_FI_Pos 21U /*!< \brief SCTLR: FI Position */ +#define SCTLR_FI_Msk (1UL << SCTLR_FI_Pos) /*!< \brief SCTLR: FI Mask */ + +#define SCTLR_UWXN_Pos 20U /*!< \brief SCTLR: UWXN Position */ +#define SCTLR_UWXN_Msk (1UL << SCTLR_UWXN_Pos) /*!< \brief SCTLR: UWXN Mask */ + +#define SCTLR_WXN_Pos 19U /*!< \brief SCTLR: WXN Position */ +#define SCTLR_WXN_Msk (1UL << SCTLR_WXN_Pos) /*!< \brief SCTLR: WXN Mask */ + +#define SCTLR_HA_Pos 17U /*!< \brief SCTLR: HA Position */ +#define SCTLR_HA_Msk (1UL << SCTLR_HA_Pos) /*!< \brief SCTLR: HA Mask */ + +#define SCTLR_RR_Pos 14U /*!< \brief SCTLR: RR Position */ +#define SCTLR_RR_Msk (1UL << SCTLR_RR_Pos) /*!< \brief SCTLR: RR Mask */ + +#define SCTLR_V_Pos 13U /*!< \brief SCTLR: V Position */ +#define SCTLR_V_Msk (1UL << SCTLR_V_Pos) /*!< \brief SCTLR: V Mask */ + +#define SCTLR_I_Pos 12U /*!< \brief SCTLR: I Position */ +#define SCTLR_I_Msk (1UL << SCTLR_I_Pos) /*!< \brief SCTLR: I Mask */ + +#define SCTLR_Z_Pos 11U /*!< \brief SCTLR: Z Position */ +#define SCTLR_Z_Msk (1UL << SCTLR_Z_Pos) /*!< \brief SCTLR: Z Mask */ + +#define SCTLR_SW_Pos 10U /*!< \brief SCTLR: SW Position */ +#define SCTLR_SW_Msk (1UL << SCTLR_SW_Pos) /*!< \brief SCTLR: SW Mask */ + +#define SCTLR_B_Pos 7U /*!< \brief SCTLR: B Position */ +#define SCTLR_B_Msk (1UL << SCTLR_B_Pos) /*!< \brief SCTLR: B Mask */ + +#define SCTLR_CP15BEN_Pos 5U /*!< \brief SCTLR: CP15BEN Position */ +#define SCTLR_CP15BEN_Msk (1UL << SCTLR_CP15BEN_Pos) /*!< \brief SCTLR: CP15BEN Mask */ + +#define SCTLR_C_Pos 2U /*!< \brief SCTLR: C Position */ +#define SCTLR_C_Msk (1UL << SCTLR_C_Pos) /*!< \brief SCTLR: C Mask */ + +#define SCTLR_A_Pos 1U /*!< \brief SCTLR: A Position */ +#define SCTLR_A_Msk (1UL << SCTLR_A_Pos) /*!< \brief SCTLR: A Mask */ + +#define SCTLR_M_Pos 0U /*!< \brief SCTLR: M Position */ +#define SCTLR_M_Msk (1UL << SCTLR_M_Pos) /*!< \brief SCTLR: M Mask */ + +/* CP15 Register ACTLR */ +typedef union +{ +#if __CORTEX_A == 5 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A5 */ + struct + { + uint32_t FW:1; /*!< \brief bit: 0 Cache and TLB maintenance broadcast */ + RESERVED(0:5, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + uint32_t EXCL:1; /*!< \brief bit: 7 Exclusive L1/L2 cache control */ + RESERVED(1:2, uint32_t) + uint32_t DODMBS:1; /*!< \brief bit: 10 Disable optimized data memory barrier behavior */ + uint32_t DWBST:1; /*!< \brief bit: 11 AXI data write bursts to Normal memory */ + uint32_t RADIS:1; /*!< \brief bit: 12 L1 Data Cache read-allocate mode disable */ + uint32_t L1PCTL:2; /*!< \brief bit:13..14 L1 Data prefetch control */ + uint32_t BP:2; /*!< \brief bit:16..15 Branch prediction policy */ + uint32_t RSDIS:1; /*!< \brief bit: 17 Disable return stack operation */ + uint32_t BTDIS:1; /*!< \brief bit: 18 Disable indirect Branch Target Address Cache (BTAC) */ + RESERVED(3:9, uint32_t) + uint32_t DBDI:1; /*!< \brief bit: 28 Disable branch dual issue */ + RESERVED(7:3, uint32_t) + } b; +#endif +#if __CORTEX_A == 7 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A7 */ + struct + { + RESERVED(0:6, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + RESERVED(1:3, uint32_t) + uint32_t DODMBS:1; /*!< \brief bit: 10 Disable optimized data memory barrier behavior */ + uint32_t L2RADIS:1; /*!< \brief bit: 11 L2 Data Cache read-allocate mode disable */ + uint32_t L1RADIS:1; /*!< \brief bit: 12 L1 Data Cache read-allocate mode disable */ + uint32_t L1PCTL:2; /*!< \brief bit:13..14 L1 Data prefetch control */ + uint32_t DDVM:1; /*!< \brief bit: 15 Disable Distributed Virtual Memory (DVM) transactions */ + RESERVED(3:12, uint32_t) + uint32_t DDI:1; /*!< \brief bit: 28 Disable dual issue */ + RESERVED(7:3, uint32_t) + } b; +#endif +#if __CORTEX_A == 9 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A9 */ + struct + { + uint32_t FW:1; /*!< \brief bit: 0 Cache and TLB maintenance broadcast */ + RESERVED(0:1, uint32_t) + uint32_t L1PE:1; /*!< \brief bit: 2 Dside prefetch */ + uint32_t WFLZM:1; /*!< \brief bit: 3 Cache and TLB maintenance broadcast */ + RESERVED(1:2, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + uint32_t EXCL:1; /*!< \brief bit: 7 Exclusive L1/L2 cache control */ + uint32_t AOW:1; /*!< \brief bit: 8 Enable allocation in one cache way only */ + uint32_t PARITY:1; /*!< \brief bit: 9 Support for parity checking, if implemented */ + RESERVED(7:22, uint32_t) + } b; +#endif + uint32_t w; /*!< \brief Type used for word access */ +} ACTLR_Type; + +#define ACTLR_DDI_Pos 28U /*!< \brief ACTLR: DDI Position */ +#define ACTLR_DDI_Msk (1UL << ACTLR_DDI_Pos) /*!< \brief ACTLR: DDI Mask */ + +#define ACTLR_DBDI_Pos 28U /*!< \brief ACTLR: DBDI Position */ +#define ACTLR_DBDI_Msk (1UL << ACTLR_DBDI_Pos) /*!< \brief ACTLR: DBDI Mask */ + +#define ACTLR_BTDIS_Pos 18U /*!< \brief ACTLR: BTDIS Position */ +#define ACTLR_BTDIS_Msk (1UL << ACTLR_BTDIS_Pos) /*!< \brief ACTLR: BTDIS Mask */ + +#define ACTLR_RSDIS_Pos 17U /*!< \brief ACTLR: RSDIS Position */ +#define ACTLR_RSDIS_Msk (1UL << ACTLR_RSDIS_Pos) /*!< \brief ACTLR: RSDIS Mask */ + +#define ACTLR_BP_Pos 15U /*!< \brief ACTLR: BP Position */ +#define ACTLR_BP_Msk (3UL << ACTLR_BP_Pos) /*!< \brief ACTLR: BP Mask */ + +#define ACTLR_DDVM_Pos 15U /*!< \brief ACTLR: DDVM Position */ +#define ACTLR_DDVM_Msk (1UL << ACTLR_DDVM_Pos) /*!< \brief ACTLR: DDVM Mask */ + +#define ACTLR_L1PCTL_Pos 13U /*!< \brief ACTLR: L1PCTL Position */ +#define ACTLR_L1PCTL_Msk (3UL << ACTLR_L1PCTL_Pos) /*!< \brief ACTLR: L1PCTL Mask */ + +#define ACTLR_RADIS_Pos 12U /*!< \brief ACTLR: RADIS Position */ +#define ACTLR_RADIS_Msk (1UL << ACTLR_RADIS_Pos) /*!< \brief ACTLR: RADIS Mask */ + +#define ACTLR_L1RADIS_Pos 12U /*!< \brief ACTLR: L1RADIS Position */ +#define ACTLR_L1RADIS_Msk (1UL << ACTLR_L1RADIS_Pos) /*!< \brief ACTLR: L1RADIS Mask */ + +#define ACTLR_DWBST_Pos 11U /*!< \brief ACTLR: DWBST Position */ +#define ACTLR_DWBST_Msk (1UL << ACTLR_DWBST_Pos) /*!< \brief ACTLR: DWBST Mask */ + +#define ACTLR_L2RADIS_Pos 11U /*!< \brief ACTLR: L2RADIS Position */ +#define ACTLR_L2RADIS_Msk (1UL << ACTLR_L2RADIS_Pos) /*!< \brief ACTLR: L2RADIS Mask */ + +#define ACTLR_DODMBS_Pos 10U /*!< \brief ACTLR: DODMBS Position */ +#define ACTLR_DODMBS_Msk (1UL << ACTLR_DODMBS_Pos) /*!< \brief ACTLR: DODMBS Mask */ + +#define ACTLR_PARITY_Pos 9U /*!< \brief ACTLR: PARITY Position */ +#define ACTLR_PARITY_Msk (1UL << ACTLR_PARITY_Pos) /*!< \brief ACTLR: PARITY Mask */ + +#define ACTLR_AOW_Pos 8U /*!< \brief ACTLR: AOW Position */ +#define ACTLR_AOW_Msk (1UL << ACTLR_AOW_Pos) /*!< \brief ACTLR: AOW Mask */ + +#define ACTLR_EXCL_Pos 7U /*!< \brief ACTLR: EXCL Position */ +#define ACTLR_EXCL_Msk (1UL << ACTLR_EXCL_Pos) /*!< \brief ACTLR: EXCL Mask */ + +#define ACTLR_SMP_Pos 6U /*!< \brief ACTLR: SMP Position */ +#define ACTLR_SMP_Msk (1UL << ACTLR_SMP_Pos) /*!< \brief ACTLR: SMP Mask */ + +#define ACTLR_WFLZM_Pos 3U /*!< \brief ACTLR: WFLZM Position */ +#define ACTLR_WFLZM_Msk (1UL << ACTLR_WFLZM_Pos) /*!< \brief ACTLR: WFLZM Mask */ + +#define ACTLR_L1PE_Pos 2U /*!< \brief ACTLR: L1PE Position */ +#define ACTLR_L1PE_Msk (1UL << ACTLR_L1PE_Pos) /*!< \brief ACTLR: L1PE Mask */ + +#define ACTLR_FW_Pos 0U /*!< \brief ACTLR: FW Position */ +#define ACTLR_FW_Msk (1UL << ACTLR_FW_Pos) /*!< \brief ACTLR: FW Mask */ + +/* CP15 Register CPACR */ +typedef union +{ + struct + { + uint32_t CP0:2; /*!< \brief bit: 0..1 Access rights for coprocessor 0 */ + uint32_t CP1:2; /*!< \brief bit: 2..3 Access rights for coprocessor 1 */ + uint32_t CP2:2; /*!< \brief bit: 4..5 Access rights for coprocessor 2 */ + uint32_t CP3:2; /*!< \brief bit: 6..7 Access rights for coprocessor 3 */ + uint32_t CP4:2; /*!< \brief bit: 8..9 Access rights for coprocessor 4 */ + uint32_t CP5:2; /*!< \brief bit:10..11 Access rights for coprocessor 5 */ + uint32_t CP6:2; /*!< \brief bit:12..13 Access rights for coprocessor 6 */ + uint32_t CP7:2; /*!< \brief bit:14..15 Access rights for coprocessor 7 */ + uint32_t CP8:2; /*!< \brief bit:16..17 Access rights for coprocessor 8 */ + uint32_t CP9:2; /*!< \brief bit:18..19 Access rights for coprocessor 9 */ + uint32_t CP10:2; /*!< \brief bit:20..21 Access rights for coprocessor 10 */ + uint32_t CP11:2; /*!< \brief bit:22..23 Access rights for coprocessor 11 */ + uint32_t CP12:2; /*!< \brief bit:24..25 Access rights for coprocessor 11 */ + uint32_t CP13:2; /*!< \brief bit:26..27 Access rights for coprocessor 11 */ + uint32_t TRCDIS:1; /*!< \brief bit: 28 Disable CP14 access to trace registers */ + RESERVED(0:1, uint32_t) + uint32_t D32DIS:1; /*!< \brief bit: 30 Disable use of registers D16-D31 of the VFP register file */ + uint32_t ASEDIS:1; /*!< \brief bit: 31 Disable Advanced SIMD Functionality */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CPACR_Type; + +#define CPACR_ASEDIS_Pos 31U /*!< \brief CPACR: ASEDIS Position */ +#define CPACR_ASEDIS_Msk (1UL << CPACR_ASEDIS_Pos) /*!< \brief CPACR: ASEDIS Mask */ + +#define CPACR_D32DIS_Pos 30U /*!< \brief CPACR: D32DIS Position */ +#define CPACR_D32DIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< \brief CPACR: D32DIS Mask */ + +#define CPACR_TRCDIS_Pos 28U /*!< \brief CPACR: D32DIS Position */ +#define CPACR_TRCDIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< \brief CPACR: D32DIS Mask */ + +#define CPACR_CP_Pos_(n) (n*2U) /*!< \brief CPACR: CPn Position */ +#define CPACR_CP_Msk_(n) (3UL << CPACR_CP_Pos_(n)) /*!< \brief CPACR: CPn Mask */ + +#define CPACR_CP_NA 0U /*!< \brief CPACR CPn field: Access denied. */ +#define CPACR_CP_PL1 1U /*!< \brief CPACR CPn field: Accessible from PL1 only. */ +#define CPACR_CP_FA 3U /*!< \brief CPACR CPn field: Full access. */ + +/* CP15 Register DFSR */ +typedef union +{ + struct + { + uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ + uint32_t Domain:4; /*!< \brief bit: 4.. 7 Fault on which domain */ + RESERVED(0:1, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ + uint32_t WnR:1; /*!< \brief bit: 11 Write not Read bit */ + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + uint32_t CM:1; /*!< \brief bit: 13 Cache maintenance fault */ + RESERVED(1:18, uint32_t) + } s; /*!< \brief Structure used for bit access in short format */ + struct + { + uint32_t STATUS:5; /*!< \brief bit: 0.. 5 Fault Status bits */ + RESERVED(0:3, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + RESERVED(1:1, uint32_t) + uint32_t WnR:1; /*!< \brief bit: 11 Write not Read bit */ + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + uint32_t CM:1; /*!< \brief bit: 13 Cache maintenance fault */ + RESERVED(2:18, uint32_t) + } l; /*!< \brief Structure used for bit access in long format */ + uint32_t w; /*!< \brief Type used for word access */ +} DFSR_Type; + +#define DFSR_CM_Pos 13U /*!< \brief DFSR: CM Position */ +#define DFSR_CM_Msk (1UL << DFSR_CM_Pos) /*!< \brief DFSR: CM Mask */ + +#define DFSR_Ext_Pos 12U /*!< \brief DFSR: Ext Position */ +#define DFSR_Ext_Msk (1UL << DFSR_Ext_Pos) /*!< \brief DFSR: Ext Mask */ + +#define DFSR_WnR_Pos 11U /*!< \brief DFSR: WnR Position */ +#define DFSR_WnR_Msk (1UL << DFSR_WnR_Pos) /*!< \brief DFSR: WnR Mask */ + +#define DFSR_FS1_Pos 10U /*!< \brief DFSR: FS1 Position */ +#define DFSR_FS1_Msk (1UL << DFSR_FS1_Pos) /*!< \brief DFSR: FS1 Mask */ + +#define DFSR_LPAE_Pos 9U /*!< \brief DFSR: LPAE Position */ +#define DFSR_LPAE_Msk (1UL << DFSR_LPAE_Pos) /*!< \brief DFSR: LPAE Mask */ + +#define DFSR_Domain_Pos 4U /*!< \brief DFSR: Domain Position */ +#define DFSR_Domain_Msk (0xFUL << DFSR_Domain_Pos) /*!< \brief DFSR: Domain Mask */ + +#define DFSR_FS0_Pos 0U /*!< \brief DFSR: FS0 Position */ +#define DFSR_FS0_Msk (0xFUL << DFSR_FS0_Pos) /*!< \brief DFSR: FS0 Mask */ + +#define DFSR_STATUS_Pos 0U /*!< \brief DFSR: STATUS Position */ +#define DFSR_STATUS_Msk (0x3FUL << DFSR_STATUS_Pos) /*!< \brief DFSR: STATUS Mask */ + +/* CP15 Register IFSR */ +typedef union +{ + struct + { + uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ + RESERVED(0:5, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ + RESERVED(1:1, uint32_t) + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + RESERVED(2:19, uint32_t) + } s; /*!< \brief Structure used for bit access in short format */ + struct + { + uint32_t STATUS:6; /*!< \brief bit: 0.. 5 Fault Status bits */ + RESERVED(0:3, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + RESERVED(1:2, uint32_t) + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + RESERVED(2:19, uint32_t) + } l; /*!< \brief Structure used for bit access in long format */ + uint32_t w; /*!< \brief Type used for word access */ +} IFSR_Type; + +#define IFSR_ExT_Pos 12U /*!< \brief IFSR: ExT Position */ +#define IFSR_ExT_Msk (1UL << IFSR_ExT_Pos) /*!< \brief IFSR: ExT Mask */ + +#define IFSR_FS1_Pos 10U /*!< \brief IFSR: FS1 Position */ +#define IFSR_FS1_Msk (1UL << IFSR_FS1_Pos) /*!< \brief IFSR: FS1 Mask */ + +#define IFSR_LPAE_Pos 9U /*!< \brief IFSR: LPAE Position */ +#define IFSR_LPAE_Msk (0x1UL << IFSR_LPAE_Pos) /*!< \brief IFSR: LPAE Mask */ + +#define IFSR_FS0_Pos 0U /*!< \brief IFSR: FS0 Position */ +#define IFSR_FS0_Msk (0xFUL << IFSR_FS0_Pos) /*!< \brief IFSR: FS0 Mask */ + +#define IFSR_STATUS_Pos 0U /*!< \brief IFSR: STATUS Position */ +#define IFSR_STATUS_Msk (0x3FUL << IFSR_STATUS_Pos) /*!< \brief IFSR: STATUS Mask */ + +/* CP15 Register ISR */ +typedef union +{ + struct + { + RESERVED(0:6, uint32_t) + uint32_t F:1; /*!< \brief bit: 6 FIQ pending bit */ + uint32_t I:1; /*!< \brief bit: 7 IRQ pending bit */ + uint32_t A:1; /*!< \brief bit: 8 External abort pending bit */ + RESERVED(1:23, uint32_t) + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} ISR_Type; + +#define ISR_A_Pos 13U /*!< \brief ISR: A Position */ +#define ISR_A_Msk (1UL << ISR_A_Pos) /*!< \brief ISR: A Mask */ + +#define ISR_I_Pos 12U /*!< \brief ISR: I Position */ +#define ISR_I_Msk (1UL << ISR_I_Pos) /*!< \brief ISR: I Mask */ + +#define ISR_F_Pos 11U /*!< \brief ISR: F Position */ +#define ISR_F_Msk (1UL << ISR_F_Pos) /*!< \brief ISR: F Mask */ + +/* DACR Register */ +#define DACR_D_Pos_(n) (2U*n) /*!< \brief DACR: Dn Position */ +#define DACR_D_Msk_(n) (3UL << DACR_D_Pos_(n)) /*!< \brief DACR: Dn Mask */ +#define DACR_Dn_NOACCESS 0U /*!< \brief DACR Dn field: No access */ +#define DACR_Dn_CLIENT 1U /*!< \brief DACR Dn field: Client */ +#define DACR_Dn_MANAGER 3U /*!< \brief DACR Dn field: Manager */ + +/** + \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) + + +/** + \brief Union type to access the L2C_310 Cache Controller. +*/ +#if (__L2C_PRESENT == 1U) || defined(DOXYGEN) +typedef struct +{ + __IM uint32_t CACHE_ID; /*!< \brief Offset: 0x0000 (R/ ) Cache ID Register */ + __IM uint32_t CACHE_TYPE; /*!< \brief Offset: 0x0004 (R/ ) Cache Type Register */ + RESERVED(0[0x3e], uint32_t) + __IOM uint32_t CONTROL; /*!< \brief Offset: 0x0100 (R/W) Control Register */ + __IOM uint32_t AUX_CNT; /*!< \brief Offset: 0x0104 (R/W) Auxiliary Control */ + RESERVED(1[0x3e], uint32_t) + __IOM uint32_t EVENT_CONTROL; /*!< \brief Offset: 0x0200 (R/W) Event Counter Control */ + __IOM uint32_t EVENT_COUNTER1_CONF; /*!< \brief Offset: 0x0204 (R/W) Event Counter 1 Configuration */ + __IOM uint32_t EVENT_COUNTER0_CONF; /*!< \brief Offset: 0x0208 (R/W) Event Counter 1 Configuration */ + RESERVED(2[0x2], uint32_t) + __IOM uint32_t INTERRUPT_MASK; /*!< \brief Offset: 0x0214 (R/W) Interrupt Mask */ + __IM uint32_t MASKED_INT_STATUS; /*!< \brief Offset: 0x0218 (R/ ) Masked Interrupt Status */ + __IM uint32_t RAW_INT_STATUS; /*!< \brief Offset: 0x021c (R/ ) Raw Interrupt Status */ + __OM uint32_t INTERRUPT_CLEAR; /*!< \brief Offset: 0x0220 ( /W) Interrupt Clear */ + RESERVED(3[0x143], uint32_t) + __IOM uint32_t CACHE_SYNC; /*!< \brief Offset: 0x0730 (R/W) Cache Sync */ + RESERVED(4[0xf], uint32_t) + __IOM uint32_t INV_LINE_PA; /*!< \brief Offset: 0x0770 (R/W) Invalidate Line By PA */ + RESERVED(6[2], uint32_t) + __IOM uint32_t INV_WAY; /*!< \brief Offset: 0x077c (R/W) Invalidate by Way */ + RESERVED(5[0xc], uint32_t) + __IOM uint32_t CLEAN_LINE_PA; /*!< \brief Offset: 0x07b0 (R/W) Clean Line by PA */ + RESERVED(7[1], uint32_t) + __IOM uint32_t CLEAN_LINE_INDEX_WAY; /*!< \brief Offset: 0x07b8 (R/W) Clean Line by Index/Way */ + __IOM uint32_t CLEAN_WAY; /*!< \brief Offset: 0x07bc (R/W) Clean by Way */ + RESERVED(8[0xc], uint32_t) + __IOM uint32_t CLEAN_INV_LINE_PA; /*!< \brief Offset: 0x07f0 (R/W) Clean and Invalidate Line by PA */ + RESERVED(9[1], uint32_t) + __IOM uint32_t CLEAN_INV_LINE_INDEX_WAY; /*!< \brief Offset: 0x07f8 (R/W) Clean and Invalidate Line by Index/Way */ + __IOM uint32_t CLEAN_INV_WAY; /*!< \brief Offset: 0x07fc (R/W) Clean and Invalidate by Way */ + RESERVED(10[0x40], uint32_t) + __IOM uint32_t DATA_LOCK_0_WAY; /*!< \brief Offset: 0x0900 (R/W) Data Lockdown 0 by Way */ + __IOM uint32_t INST_LOCK_0_WAY; /*!< \brief Offset: 0x0904 (R/W) Instruction Lockdown 0 by Way */ + __IOM uint32_t DATA_LOCK_1_WAY; /*!< \brief Offset: 0x0908 (R/W) Data Lockdown 1 by Way */ + __IOM uint32_t INST_LOCK_1_WAY; /*!< \brief Offset: 0x090c (R/W) Instruction Lockdown 1 by Way */ + __IOM uint32_t DATA_LOCK_2_WAY; /*!< \brief Offset: 0x0910 (R/W) Data Lockdown 2 by Way */ + __IOM uint32_t INST_LOCK_2_WAY; /*!< \brief Offset: 0x0914 (R/W) Instruction Lockdown 2 by Way */ + __IOM uint32_t DATA_LOCK_3_WAY; /*!< \brief Offset: 0x0918 (R/W) Data Lockdown 3 by Way */ + __IOM uint32_t INST_LOCK_3_WAY; /*!< \brief Offset: 0x091c (R/W) Instruction Lockdown 3 by Way */ + __IOM uint32_t DATA_LOCK_4_WAY; /*!< \brief Offset: 0x0920 (R/W) Data Lockdown 4 by Way */ + __IOM uint32_t INST_LOCK_4_WAY; /*!< \brief Offset: 0x0924 (R/W) Instruction Lockdown 4 by Way */ + __IOM uint32_t DATA_LOCK_5_WAY; /*!< \brief Offset: 0x0928 (R/W) Data Lockdown 5 by Way */ + __IOM uint32_t INST_LOCK_5_WAY; /*!< \brief Offset: 0x092c (R/W) Instruction Lockdown 5 by Way */ + __IOM uint32_t DATA_LOCK_6_WAY; /*!< \brief Offset: 0x0930 (R/W) Data Lockdown 5 by Way */ + __IOM uint32_t INST_LOCK_6_WAY; /*!< \brief Offset: 0x0934 (R/W) Instruction Lockdown 5 by Way */ + __IOM uint32_t DATA_LOCK_7_WAY; /*!< \brief Offset: 0x0938 (R/W) Data Lockdown 6 by Way */ + __IOM uint32_t INST_LOCK_7_WAY; /*!< \brief Offset: 0x093c (R/W) Instruction Lockdown 6 by Way */ + RESERVED(11[0x4], uint32_t) + __IOM uint32_t LOCK_LINE_EN; /*!< \brief Offset: 0x0950 (R/W) Lockdown by Line Enable */ + __IOM uint32_t UNLOCK_ALL_BY_WAY; /*!< \brief Offset: 0x0954 (R/W) Unlock All Lines by Way */ + RESERVED(12[0xaa], uint32_t) + __IOM uint32_t ADDRESS_FILTER_START; /*!< \brief Offset: 0x0c00 (R/W) Address Filtering Start */ + __IOM uint32_t ADDRESS_FILTER_END; /*!< \brief Offset: 0x0c04 (R/W) Address Filtering End */ + RESERVED(13[0xce], uint32_t) + __IOM uint32_t DEBUG_CONTROL; /*!< \brief Offset: 0x0f40 (R/W) Debug Control Register */ +} L2C_310_TypeDef; + +#define L2C_310 ((L2C_310_TypeDef *)L2C_310_BASE) /*!< \brief L2C_310 register set access pointer */ +#endif + +#if (__GIC_PRESENT == 1U) || defined(DOXYGEN) + +/** \brief Structure type to access the Generic Interrupt Controller Distributor (GICD) +*/ +typedef struct +{ + __IOM uint32_t CTLR; /*!< \brief Offset: 0x000 (R/W) Distributor Control Register */ + __IM uint32_t TYPER; /*!< \brief Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IM uint32_t IIDR; /*!< \brief Offset: 0x008 (R/ ) Distributor Implementer Identification Register */ + RESERVED(0, uint32_t) + __IOM uint32_t STATUSR; /*!< \brief Offset: 0x010 (R/W) Error Reporting Status Register, optional */ + RESERVED(1[11], uint32_t) + __OM uint32_t SETSPI_NSR; /*!< \brief Offset: 0x040 ( /W) Set SPI Register */ + RESERVED(2, uint32_t) + __OM uint32_t CLRSPI_NSR; /*!< \brief Offset: 0x048 ( /W) Clear SPI Register */ + RESERVED(3, uint32_t) + __OM uint32_t SETSPI_SR; /*!< \brief Offset: 0x050 ( /W) Set SPI, Secure Register */ + RESERVED(4, uint32_t) + __OM uint32_t CLRSPI_SR; /*!< \brief Offset: 0x058 ( /W) Clear SPI, Secure Register */ + RESERVED(5[9], uint32_t) + __IOM uint32_t IGROUPR[32]; /*!< \brief Offset: 0x080 (R/W) Interrupt Group Registers */ + __IOM uint32_t ISENABLER[32]; /*!< \brief Offset: 0x100 (R/W) Interrupt Set-Enable Registers */ + __IOM uint32_t ICENABLER[32]; /*!< \brief Offset: 0x180 (R/W) Interrupt Clear-Enable Registers */ + __IOM uint32_t ISPENDR[32]; /*!< \brief Offset: 0x200 (R/W) Interrupt Set-Pending Registers */ + __IOM uint32_t ICPENDR[32]; /*!< \brief Offset: 0x280 (R/W) Interrupt Clear-Pending Registers */ + __IOM uint32_t ISACTIVER[32]; /*!< \brief Offset: 0x300 (R/W) Interrupt Set-Active Registers */ + __IOM uint32_t ICACTIVER[32]; /*!< \brief Offset: 0x380 (R/W) Interrupt Clear-Active Registers */ + __IOM uint32_t IPRIORITYR[255]; /*!< \brief Offset: 0x400 (R/W) Interrupt Priority Registers */ + RESERVED(6, uint32_t) + __IOM uint32_t ITARGETSR[255]; /*!< \brief Offset: 0x800 (R/W) Interrupt Targets Registers */ + RESERVED(7, uint32_t) + __IOM uint32_t ICFGR[64]; /*!< \brief Offset: 0xC00 (R/W) Interrupt Configuration Registers */ + __IOM uint32_t IGRPMODR[32]; /*!< \brief Offset: 0xD00 (R/W) Interrupt Group Modifier Registers */ + RESERVED(8[32], uint32_t) + __IOM uint32_t NSACR[64]; /*!< \brief Offset: 0xE00 (R/W) Non-secure Access Control Registers */ + __OM uint32_t SGIR; /*!< \brief Offset: 0xF00 ( /W) Software Generated Interrupt Register */ + RESERVED(9[3], uint32_t) + __IOM uint32_t CPENDSGIR[4]; /*!< \brief Offset: 0xF10 (R/W) SGI Clear-Pending Registers */ + __IOM uint32_t SPENDSGIR[4]; /*!< \brief Offset: 0xF20 (R/W) SGI Set-Pending Registers */ + RESERVED(10[5236], uint32_t) + __IOM uint64_t IROUTER[988]; /*!< \brief Offset: 0x6100(R/W) Interrupt Routing Registers */ +} GICDistributor_Type; + +#define GICDistributor ((GICDistributor_Type *) GIC_DISTRIBUTOR_BASE ) /*!< \brief GIC Distributor register set access pointer */ + +/** \brief Structure type to access the Generic Interrupt Controller Interface (GICC) +*/ +typedef struct +{ + __IOM uint32_t CTLR; /*!< \brief Offset: 0x000 (R/W) CPU Interface Control Register */ + __IOM uint32_t PMR; /*!< \brief Offset: 0x004 (R/W) Interrupt Priority Mask Register */ + __IOM uint32_t BPR; /*!< \brief Offset: 0x008 (R/W) Binary Point Register */ + __IM uint32_t IAR; /*!< \brief Offset: 0x00C (R/ ) Interrupt Acknowledge Register */ + __OM uint32_t EOIR; /*!< \brief Offset: 0x010 ( /W) End Of Interrupt Register */ + __IM uint32_t RPR; /*!< \brief Offset: 0x014 (R/ ) Running Priority Register */ + __IM uint32_t HPPIR; /*!< \brief Offset: 0x018 (R/ ) Highest Priority Pending Interrupt Register */ + __IOM uint32_t ABPR; /*!< \brief Offset: 0x01C (R/W) Aliased Binary Point Register */ + __IM uint32_t AIAR; /*!< \brief Offset: 0x020 (R/ ) Aliased Interrupt Acknowledge Register */ + __OM uint32_t AEOIR; /*!< \brief Offset: 0x024 ( /W) Aliased End Of Interrupt Register */ + __IM uint32_t AHPPIR; /*!< \brief Offset: 0x028 (R/ ) Aliased Highest Priority Pending Interrupt Register */ + __IOM uint32_t STATUSR; /*!< \brief Offset: 0x02C (R/W) Error Reporting Status Register, optional */ + RESERVED(1[40], uint32_t) + __IOM uint32_t APR[4]; /*!< \brief Offset: 0x0D0 (R/W) Active Priority Register */ + __IOM uint32_t NSAPR[4]; /*!< \brief Offset: 0x0E0 (R/W) Non-secure Active Priority Register */ + RESERVED(2[3], uint32_t) + __IM uint32_t IIDR; /*!< \brief Offset: 0x0FC (R/ ) CPU Interface Identification Register */ + RESERVED(3[960], uint32_t) + __OM uint32_t DIR; /*!< \brief Offset: 0x1000( /W) Deactivate Interrupt Register */ +} GICInterface_Type; + +#define GICInterface ((GICInterface_Type *) GIC_INTERFACE_BASE ) /*!< \brief GIC Interface register set access pointer */ +#endif + +#if (__TIM_PRESENT == 1U) || defined(DOXYGEN) +#if ((__CORTEX_A == 5U) || (__CORTEX_A == 9U)) || defined(DOXYGEN) +/** \brief Structure type to access the Private Timer +*/ +typedef struct +{ + __IOM uint32_t LOAD; //!< \brief Offset: 0x000 (R/W) Private Timer Load Register + __IOM uint32_t COUNTER; //!< \brief Offset: 0x004 (R/W) Private Timer Counter Register + __IOM uint32_t CONTROL; //!< \brief Offset: 0x008 (R/W) Private Timer Control Register + __IOM uint32_t ISR; //!< \brief Offset: 0x00C (R/W) Private Timer Interrupt Status Register + RESERVED(0[4], uint32_t) + __IOM uint32_t WLOAD; //!< \brief Offset: 0x020 (R/W) Watchdog Load Register + __IOM uint32_t WCOUNTER; //!< \brief Offset: 0x024 (R/W) Watchdog Counter Register + __IOM uint32_t WCONTROL; //!< \brief Offset: 0x028 (R/W) Watchdog Control Register + __IOM uint32_t WISR; //!< \brief Offset: 0x02C (R/W) Watchdog Interrupt Status Register + __IOM uint32_t WRESET; //!< \brief Offset: 0x030 (R/W) Watchdog Reset Status Register + __OM uint32_t WDISABLE; //!< \brief Offset: 0x034 ( /W) Watchdog Disable Register +} Timer_Type; +#define PTIM ((Timer_Type *) TIMER_BASE ) /*!< \brief Timer register struct */ +#endif +#endif + + /******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - L1 Cache Functions + - L2C-310 Cache Controller Functions + - PL1 Timer Functions + - GIC Functions + - MMU Functions + ******************************************************************************/ + +/* ########################## L1 Cache functions ################################# */ + +/** \brief Enable Caches by setting I and C bits in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_EnableCaches(void) { + __set_SCTLR( __get_SCTLR() | SCTLR_I_Msk | SCTLR_C_Msk); + __ISB(); +} + +/** \brief Disable Caches by clearing I and C bits in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_DisableCaches(void) { + __set_SCTLR( __get_SCTLR() & (~SCTLR_I_Msk) & (~SCTLR_C_Msk)); + __ISB(); +} + +/** \brief Enable Branch Prediction by setting Z bit in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_EnableBTAC(void) { + __set_SCTLR( __get_SCTLR() | SCTLR_Z_Msk); + __ISB(); +} + +/** \brief Disable Branch Prediction by clearing Z bit in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_DisableBTAC(void) { + __set_SCTLR( __get_SCTLR() & (~SCTLR_Z_Msk)); + __ISB(); +} + +/** \brief Invalidate entire branch predictor array +*/ +__STATIC_FORCEINLINE void L1C_InvalidateBTAC(void) { + __set_BPIALL(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new state +} + +/** \brief Invalidate the whole instruction cache +*/ +__STATIC_FORCEINLINE void L1C_InvalidateICacheAll(void) { + __set_ICIALLU(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new I cache state +} + +/** \brief Clean data cache line by address. +* \param [in] va Pointer to data to clear the cache for. +*/ +__STATIC_FORCEINLINE void L1C_CleanDCacheMVA(void *va) { + __set_DCCMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Invalidate data cache line by address. +* \param [in] va Pointer to data to invalidate the cache for. +*/ +__STATIC_FORCEINLINE void L1C_InvalidateDCacheMVA(void *va) { + __set_DCIMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Clean and Invalidate data cache by address. +* \param [in] va Pointer to data to invalidate the cache for. +*/ +__STATIC_FORCEINLINE void L1C_CleanInvalidateDCacheMVA(void *va) { + __set_DCCIMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Calculate log2 rounded up +* - log(0) => 0 +* - log(1) => 0 +* - log(2) => 1 +* - log(3) => 2 +* - log(4) => 2 +* - log(5) => 3 +* : : +* - log(16) => 4 +* - log(32) => 5 +* : : +* \param [in] n input value parameter +* \return log2(n) +*/ +__STATIC_FORCEINLINE uint8_t __log2_up(uint32_t n) +{ + if (n < 2U) { + return 0U; + } + uint8_t log = 0U; + uint32_t t = n; + while(t > 1U) + { + log++; + t >>= 1U; + } + if (n & 1U) { log++; } + return log; +} + +/** \brief Apply cache maintenance to given cache level. +* \param [in] level cache level to be maintained +* \param [in] maint 0 - invalidate, 1 - clean, otherwise - invalidate and clean +*/ +__STATIC_FORCEINLINE void __L1C_MaintainDCacheSetWay(uint32_t level, uint32_t maint) +{ + uint32_t Dummy; + uint32_t ccsidr; + uint32_t num_sets; + uint32_t num_ways; + uint32_t shift_way; + uint32_t log2_linesize; + int32_t log2_num_ways; + + Dummy = level << 1U; + /* set csselr, select ccsidr register */ + __set_CSSELR(Dummy); + /* get current ccsidr register */ + ccsidr = __get_CCSIDR(); + num_sets = ((ccsidr & 0x0FFFE000U) >> 13U) + 1U; + num_ways = ((ccsidr & 0x00001FF8U) >> 3U) + 1U; + log2_linesize = (ccsidr & 0x00000007U) + 2U + 2U; + log2_num_ways = __log2_up(num_ways); + if ((log2_num_ways < 0) || (log2_num_ways > 32)) { + return; // FATAL ERROR + } + shift_way = 32U - (uint32_t)log2_num_ways; + for(int32_t way = num_ways-1; way >= 0; way--) + { + for(int32_t set = num_sets-1; set >= 0; set--) + { + Dummy = (level << 1U) | (((uint32_t)set) << log2_linesize) | (((uint32_t)way) << shift_way); + switch (maint) + { + case 0U: __set_DCISW(Dummy); break; + case 1U: __set_DCCSW(Dummy); break; + default: __set_DCCISW(Dummy); break; + } + } + } + __DMB(); +} + +/** \brief Clean and Invalidate the entire data or unified cache +* Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency +* \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean +*/ +__STATIC_FORCEINLINE void L1C_CleanInvalidateCache(uint32_t op) { + uint32_t clidr; + uint32_t cache_type; + clidr = __get_CLIDR(); + for(uint32_t i = 0U; i<7U; i++) + { + cache_type = (clidr >> i*3U) & 0x7UL; + if ((cache_type >= 2U) && (cache_type <= 4U)) + { + __L1C_MaintainDCacheSetWay(i, op); + } + } +} + +/** \brief Clean and Invalidate the entire data or unified cache +* Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency +* \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean +* \deprecated Use generic L1C_CleanInvalidateCache instead. +*/ +CMSIS_DEPRECATED +__STATIC_FORCEINLINE void __L1C_CleanInvalidateCache(uint32_t op) { + L1C_CleanInvalidateCache(op); +} + +/** \brief Invalidate the whole data cache. +*/ +__STATIC_FORCEINLINE void L1C_InvalidateDCacheAll(void) { + L1C_CleanInvalidateCache(0); +} + +/** \brief Clean the whole data cache. + */ +__STATIC_FORCEINLINE void L1C_CleanDCacheAll(void) { + L1C_CleanInvalidateCache(1); +} + +/** \brief Clean and invalidate the whole data cache. + */ +__STATIC_FORCEINLINE void L1C_CleanInvalidateDCacheAll(void) { + L1C_CleanInvalidateCache(2); +} + +/* ########################## L2 Cache functions ################################# */ +#if (__L2C_PRESENT == 1U) || defined(DOXYGEN) +/** \brief Cache Sync operation by writing CACHE_SYNC register. +*/ +__STATIC_INLINE void L2C_Sync(void) +{ + L2C_310->CACHE_SYNC = 0x0; +} + +/** \brief Read cache controller cache ID from CACHE_ID register. + * \return L2C_310_TypeDef::CACHE_ID + */ +__STATIC_INLINE int L2C_GetID (void) +{ + return L2C_310->CACHE_ID; +} + +/** \brief Read cache controller cache type from CACHE_TYPE register. +* \return L2C_310_TypeDef::CACHE_TYPE +*/ +__STATIC_INLINE int L2C_GetType (void) +{ + return L2C_310->CACHE_TYPE; +} + +/** \brief Invalidate all cache by way +*/ +__STATIC_INLINE void L2C_InvAllByWay (void) +{ + unsigned int assoc; + + if (L2C_310->AUX_CNT & (1U << 16U)) { + assoc = 16U; + } else { + assoc = 8U; + } + + L2C_310->INV_WAY = (1U << assoc) - 1U; + while(L2C_310->INV_WAY & ((1U << assoc) - 1U)); //poll invalidate + + L2C_Sync(); +} + +/** \brief Clean and Invalidate all cache by way +*/ +__STATIC_INLINE void L2C_CleanInvAllByWay (void) +{ + unsigned int assoc; + + if (L2C_310->AUX_CNT & (1U << 16U)) { + assoc = 16U; + } else { + assoc = 8U; + } + + L2C_310->CLEAN_INV_WAY = (1U << assoc) - 1U; + while(L2C_310->CLEAN_INV_WAY & ((1U << assoc) - 1U)); //poll invalidate + + L2C_Sync(); +} + +/** \brief Enable Level 2 Cache +*/ +__STATIC_INLINE void L2C_Enable(void) +{ + L2C_310->CONTROL = 0; + L2C_310->INTERRUPT_CLEAR = 0x000001FFuL; + L2C_310->DEBUG_CONTROL = 0; + L2C_310->DATA_LOCK_0_WAY = 0; + L2C_310->CACHE_SYNC = 0; + L2C_310->CONTROL = 0x01; + L2C_Sync(); +} + +/** \brief Disable Level 2 Cache +*/ +__STATIC_INLINE void L2C_Disable(void) +{ + L2C_310->CONTROL = 0x00; + L2C_Sync(); +} + +/** \brief Invalidate cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ +__STATIC_INLINE void L2C_InvPa (void *pa) +{ + L2C_310->INV_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} + +/** \brief Clean cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ +__STATIC_INLINE void L2C_CleanPa (void *pa) +{ + L2C_310->CLEAN_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} + +/** \brief Clean and invalidate cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ +__STATIC_INLINE void L2C_CleanInvPa (void *pa) +{ + L2C_310->CLEAN_INV_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} +#endif + +/* ########################## GIC functions ###################################### */ +#if (__GIC_PRESENT == 1U) || defined(DOXYGEN) + +/** \brief Enable the interrupt distributor using the GIC's CTLR register. +*/ +__STATIC_INLINE void GIC_EnableDistributor(void) +{ + GICDistributor->CTLR |= 1U; +} + +/** \brief Disable the interrupt distributor using the GIC's CTLR register. +*/ +__STATIC_INLINE void GIC_DisableDistributor(void) +{ + GICDistributor->CTLR &=~1U; +} + +/** \brief Read the GIC's TYPER register. +* \return GICDistributor_Type::TYPER +*/ +__STATIC_INLINE uint32_t GIC_DistributorInfo(void) +{ + return (GICDistributor->TYPER); +} + +/** \brief Reads the GIC's IIDR register. +* \return GICDistributor_Type::IIDR +*/ +__STATIC_INLINE uint32_t GIC_DistributorImplementer(void) +{ + return (GICDistributor->IIDR); +} + +/** \brief Sets the GIC's ITARGETSR register for the given interrupt. +* \param [in] IRQn Interrupt to be configured. +* \param [in] cpu_target CPU interfaces to assign this interrupt to. +*/ +__STATIC_INLINE void GIC_SetTarget(IRQn_Type IRQn, uint32_t cpu_target) +{ + uint32_t mask = GICDistributor->ITARGETSR[IRQn / 4U] & ~(0xFFUL << ((IRQn % 4U) * 8U)); + GICDistributor->ITARGETSR[IRQn / 4U] = mask | ((cpu_target & 0xFFUL) << ((IRQn % 4U) * 8U)); +} + +/** \brief Read the GIC's ITARGETSR register. +* \param [in] IRQn Interrupt to acquire the configuration for. +* \return GICDistributor_Type::ITARGETSR +*/ +__STATIC_INLINE uint32_t GIC_GetTarget(IRQn_Type IRQn) +{ + return (GICDistributor->ITARGETSR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; +} + +/** \brief Enable the CPU's interrupt interface. +*/ +__STATIC_INLINE void GIC_EnableInterface(void) +{ + GICInterface->CTLR |= 1U; //enable interface +} + +/** \brief Disable the CPU's interrupt interface. +*/ +__STATIC_INLINE void GIC_DisableInterface(void) +{ + GICInterface->CTLR &=~1U; //disable distributor +} + +/** \brief Read the CPU's IAR register. +* \return GICInterface_Type::IAR +*/ +__STATIC_INLINE IRQn_Type GIC_AcknowledgePending(void) +{ + return (IRQn_Type)(GICInterface->IAR); +} + +/** \brief Writes the given interrupt number to the CPU's EOIR register. +* \param [in] IRQn The interrupt to be signaled as finished. +*/ +__STATIC_INLINE void GIC_EndInterrupt(IRQn_Type IRQn) +{ + GICInterface->EOIR = IRQn; +} + +/** \brief Enables the given interrupt using GIC's ISENABLER register. +* \param [in] IRQn The interrupt to be enabled. +*/ +__STATIC_INLINE void GIC_EnableIRQ(IRQn_Type IRQn) +{ + GICDistributor->ISENABLER[IRQn / 32U] = 1U << (IRQn % 32U); +} + +/** \brief Get interrupt enable status using GIC's ISENABLER register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - interrupt is not enabled, 1 - interrupt is enabled. +*/ +__STATIC_INLINE uint32_t GIC_GetEnableIRQ(IRQn_Type IRQn) +{ + return (GICDistributor->ISENABLER[IRQn / 32U] >> (IRQn % 32U)) & 1UL; +} + +/** \brief Disables the given interrupt using GIC's ICENABLER register. +* \param [in] IRQn The interrupt to be disabled. +*/ +__STATIC_INLINE void GIC_DisableIRQ(IRQn_Type IRQn) +{ + GICDistributor->ICENABLER[IRQn / 32U] = 1U << (IRQn % 32U); +} + +/** \brief Get interrupt pending status from GIC's ISPENDR register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - interrupt is not pending, 1 - interrupt is pendig. +*/ +__STATIC_INLINE uint32_t GIC_GetPendingIRQ(IRQn_Type IRQn) +{ + uint32_t pend; + + if (IRQn >= 16U) { + pend = (GICDistributor->ISPENDR[IRQn / 32U] >> (IRQn % 32U)) & 1UL; + } else { + // INTID 0-15 Software Generated Interrupt + pend = (GICDistributor->SPENDSGIR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; + // No CPU identification offered + if (pend != 0U) { + pend = 1U; + } else { + pend = 0U; + } + } + + return (pend); +} + +/** \brief Sets the given interrupt as pending using GIC's ISPENDR register. +* \param [in] IRQn The interrupt to be enabled. +*/ +__STATIC_INLINE void GIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if (IRQn >= 16U) { + GICDistributor->ISPENDR[IRQn / 32U] = 1U << (IRQn % 32U); + } else { + // INTID 0-15 Software Generated Interrupt + GICDistributor->SPENDSGIR[IRQn / 4U] = 1U << ((IRQn % 4U) * 8U); + } +} + +/** \brief Clears the given interrupt from being pending using GIC's ICPENDR register. +* \param [in] IRQn The interrupt to be enabled. +*/ +__STATIC_INLINE void GIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if (IRQn >= 16U) { + GICDistributor->ICPENDR[IRQn / 32U] = 1U << (IRQn % 32U); + } else { + // INTID 0-15 Software Generated Interrupt + GICDistributor->CPENDSGIR[IRQn / 4U] = 1U << ((IRQn % 4U) * 8U); + } +} + +/** \brief Sets the interrupt configuration using GIC's ICFGR register. +* \param [in] IRQn The interrupt to be configured. +* \param [in] int_config Int_config field value. Bit 0: Reserved (0 - N-N model, 1 - 1-N model for some GIC before v1) +* Bit 1: 0 - level sensitive, 1 - edge triggered +*/ +__STATIC_INLINE void GIC_SetConfiguration(IRQn_Type IRQn, uint32_t int_config) +{ + uint32_t icfgr = GICDistributor->ICFGR[IRQn / 16U]; + uint32_t shift = (IRQn % 16U) << 1U; + + icfgr &= (~(3U << shift)); + icfgr |= ( int_config << shift); + + GICDistributor->ICFGR[IRQn / 16U] = icfgr; +} + +/** \brief Get the interrupt configuration from the GIC's ICFGR register. +* \param [in] IRQn Interrupt to acquire the configuration for. +* \return Int_config field value. Bit 0: Reserved (0 - N-N model, 1 - 1-N model for some GIC before v1) +* Bit 1: 0 - level sensitive, 1 - edge triggered +*/ +__STATIC_INLINE uint32_t GIC_GetConfiguration(IRQn_Type IRQn) +{ + return (GICDistributor->ICFGR[IRQn / 16U] >> ((IRQn % 16U) >> 1U)); +} + +/** \brief Set the priority for the given interrupt in the GIC's IPRIORITYR register. +* \param [in] IRQn The interrupt to be configured. +* \param [in] priority The priority for the interrupt, lower values denote higher priorities. +*/ +__STATIC_INLINE void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + uint32_t mask = GICDistributor->IPRIORITYR[IRQn / 4U] & ~(0xFFUL << ((IRQn % 4U) * 8U)); + GICDistributor->IPRIORITYR[IRQn / 4U] = mask | ((priority & 0xFFUL) << ((IRQn % 4U) * 8U)); +} + +/** \brief Read the current interrupt priority from GIC's IPRIORITYR register. +* \param [in] IRQn The interrupt to be queried. +*/ +__STATIC_INLINE uint32_t GIC_GetPriority(IRQn_Type IRQn) +{ + return (GICDistributor->IPRIORITYR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; +} + +/** \brief Set the interrupt priority mask using CPU's PMR register. +* \param [in] priority Priority mask to be set. +*/ +__STATIC_INLINE void GIC_SetInterfacePriorityMask(uint32_t priority) +{ + GICInterface->PMR = priority & 0xFFUL; //set priority mask +} + +/** \brief Read the current interrupt priority mask from CPU's PMR register. +* \result GICInterface_Type::PMR +*/ +__STATIC_INLINE uint32_t GIC_GetInterfacePriorityMask(void) +{ + return GICInterface->PMR; +} + +/** \brief Configures the group priority and subpriority split point using CPU's BPR register. +* \param [in] binary_point Amount of bits used as subpriority. +*/ +__STATIC_INLINE void GIC_SetBinaryPoint(uint32_t binary_point) +{ + GICInterface->BPR = binary_point & 7U; //set binary point +} + +/** \brief Read the current group priority and subpriority split point from CPU's BPR register. +* \return GICInterface_Type::BPR +*/ +__STATIC_INLINE uint32_t GIC_GetBinaryPoint(void) +{ + return GICInterface->BPR; +} + +/** \brief Get the status for a given interrupt. +* \param [in] IRQn The interrupt to get status for. +* \return 0 - not pending/active, 1 - pending, 2 - active, 3 - pending and active +*/ +__STATIC_INLINE uint32_t GIC_GetIRQStatus(IRQn_Type IRQn) +{ + uint32_t pending, active; + + active = ((GICDistributor->ISACTIVER[IRQn / 32U]) >> (IRQn % 32U)) & 1UL; + pending = ((GICDistributor->ISPENDR[IRQn / 32U]) >> (IRQn % 32U)) & 1UL; + + return ((active<<1U) | pending); +} + +/** \brief Generate a software interrupt using GIC's SGIR register. +* \param [in] IRQn Software interrupt to be generated. +* \param [in] target_list List of CPUs the software interrupt should be forwarded to. +* \param [in] filter_list Filter to be applied to determine interrupt receivers. +*/ +__STATIC_INLINE void GIC_SendSGI(IRQn_Type IRQn, uint32_t target_list, uint32_t filter_list) +{ + GICDistributor->SGIR = ((filter_list & 3U) << 24U) | ((target_list & 0xFFUL) << 16U) | (IRQn & 0x0FUL); +} + +/** \brief Get the interrupt number of the highest interrupt pending from CPU's HPPIR register. +* \return GICInterface_Type::HPPIR +*/ +__STATIC_INLINE uint32_t GIC_GetHighPendingIRQ(void) +{ + return GICInterface->HPPIR; +} + +/** \brief Provides information about the implementer and revision of the CPU interface. +* \return GICInterface_Type::IIDR +*/ +__STATIC_INLINE uint32_t GIC_GetInterfaceId(void) +{ + return GICInterface->IIDR; +} + +/** \brief Set the interrupt group from the GIC's IGROUPR register. +* \param [in] IRQn The interrupt to be queried. +* \param [in] group Interrupt group number: 0 - Group 0, 1 - Group 1 +*/ +__STATIC_INLINE void GIC_SetGroup(IRQn_Type IRQn, uint32_t group) +{ + uint32_t igroupr = GICDistributor->IGROUPR[IRQn / 32U]; + uint32_t shift = (IRQn % 32U); + + igroupr &= (~(1U << shift)); + igroupr |= ( (group & 1U) << shift); + + GICDistributor->IGROUPR[IRQn / 32U] = igroupr; +} +#define GIC_SetSecurity GIC_SetGroup + +/** \brief Get the interrupt group from the GIC's IGROUPR register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - Group 0, 1 - Group 1 +*/ +__STATIC_INLINE uint32_t GIC_GetGroup(IRQn_Type IRQn) +{ + return (GICDistributor->IGROUPR[IRQn / 32U] >> (IRQn % 32U)) & 1UL; +} +#define GIC_GetSecurity GIC_GetGroup + +/** \brief Initialize the interrupt distributor. +*/ +__STATIC_INLINE void GIC_DistInit(void) +{ + uint32_t i; + uint32_t num_irq = 0U; + uint32_t priority_field; + + //A reset sets all bits in the IGROUPRs corresponding to the SPIs to 0, + //configuring all of the interrupts as Secure. + + //Disable interrupt forwarding + GIC_DisableDistributor(); + //Get the maximum number of interrupts that the GIC supports + num_irq = 32U * ((GIC_DistributorInfo() & 0x1FU) + 1U); + + /* Priority level is implementation defined. + To determine the number of priority bits implemented write 0xFF to an IPRIORITYR + priority field and read back the value stored.*/ + GIC_SetPriority((IRQn_Type)0U, 0xFFU); + priority_field = GIC_GetPriority((IRQn_Type)0U); + + for (i = 32U; i < num_irq; i++) + { + //Disable the SPI interrupt + GIC_DisableIRQ((IRQn_Type)i); + //Set level-sensitive (and N-N model) + GIC_SetConfiguration((IRQn_Type)i, 0U); + //Set priority + GIC_SetPriority((IRQn_Type)i, priority_field/2U); + //Set target list to CPU0 + GIC_SetTarget((IRQn_Type)i, 1U); + } + //Enable distributor + GIC_EnableDistributor(); +} + +/** \brief Initialize the CPU's interrupt interface +*/ +__STATIC_INLINE void GIC_CPUInterfaceInit(void) +{ + uint32_t i; + uint32_t priority_field; + + //A reset sets all bits in the IGROUPRs corresponding to the SPIs to 0, + //configuring all of the interrupts as Secure. + + //Disable interrupt forwarding + GIC_DisableInterface(); + + /* Priority level is implementation defined. + To determine the number of priority bits implemented write 0xFF to an IPRIORITYR + priority field and read back the value stored.*/ + GIC_SetPriority((IRQn_Type)0U, 0xFFU); + priority_field = GIC_GetPriority((IRQn_Type)0U); + + //SGI and PPI + for (i = 0U; i < 32U; i++) + { + if(i > 15U) { + //Set level-sensitive (and N-N model) for PPI + GIC_SetConfiguration((IRQn_Type)i, 0U); + } + //Disable SGI and PPI interrupts + GIC_DisableIRQ((IRQn_Type)i); + //Set priority + GIC_SetPriority((IRQn_Type)i, priority_field/2U); + } + //Enable interface + GIC_EnableInterface(); + //Set binary point to 0 + GIC_SetBinaryPoint(0U); + //Set priority mask + GIC_SetInterfacePriorityMask(0xFFU); +} + +/** \brief Initialize and enable the GIC +*/ +__STATIC_INLINE void GIC_Enable(void) +{ + GIC_DistInit(); + GIC_CPUInterfaceInit(); //per CPU +} +#endif + +/* ########################## Generic Timer functions ############################ */ +#if (__TIM_PRESENT == 1U) || defined(DOXYGEN) + +/* PL1 Physical Timer */ +#if (__CORTEX_A == 7U) || defined(DOXYGEN) + +/** \brief Physical Timer Control register */ +typedef union +{ + struct + { + uint32_t ENABLE:1; /*!< \brief bit: 0 Enables the timer. */ + uint32_t IMASK:1; /*!< \brief bit: 1 Timer output signal mask bit. */ + uint32_t ISTATUS:1; /*!< \brief bit: 2 The status of the timer. */ + RESERVED(0:29, uint32_t) + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CNTP_CTL_Type; + +/** \brief Configures the frequency the timer shall run at. +* \param [in] value The timer frequency in Hz. +*/ +__STATIC_INLINE void PL1_SetCounterFrequency(uint32_t value) +{ + __set_CNTFRQ(value); + __ISB(); +} + +/** \brief Sets the reset value of the timer. +* \param [in] value The value the timer is loaded with. +*/ +__STATIC_INLINE void PL1_SetLoadValue(uint32_t value) +{ + __set_CNTP_TVAL(value); + __ISB(); +} + +/** \brief Get the current counter value. +* \return Current counter value. +*/ +__STATIC_INLINE uint32_t PL1_GetCurrentValue(void) +{ + return(__get_CNTP_TVAL()); +} + +/** \brief Get the current physical counter value. +* \return Current physical counter value. +*/ +__STATIC_INLINE uint64_t PL1_GetCurrentPhysicalValue(void) +{ + return(__get_CNTPCT()); +} + +/** \brief Set the physical compare value. +* \param [in] value New physical timer compare value. +*/ +__STATIC_INLINE void PL1_SetPhysicalCompareValue(uint64_t value) +{ + __set_CNTP_CVAL(value); + __ISB(); +} + +/** \brief Get the physical compare value. +* \return Physical compare value. +*/ +__STATIC_INLINE uint64_t PL1_GetPhysicalCompareValue(void) +{ + return(__get_CNTP_CVAL()); +} + +/** \brief Configure the timer by setting the control value. +* \param [in] value New timer control value. +*/ +__STATIC_INLINE void PL1_SetControl(uint32_t value) +{ + __set_CNTP_CTL(value); + __ISB(); +} + +/** \brief Get the control value. +* \return Control value. +*/ +__STATIC_INLINE uint32_t PL1_GetControl(void) +{ + return(__get_CNTP_CTL()); +} +#endif + +/* Private Timer */ +#if ((__CORTEX_A == 5U) || (__CORTEX_A == 9U)) || defined(DOXYGEN) +/** \brief Set the load value to timers LOAD register. +* \param [in] value The load value to be set. +*/ +__STATIC_INLINE void PTIM_SetLoadValue(uint32_t value) +{ + PTIM->LOAD = value; +} + +/** \brief Get the load value from timers LOAD register. +* \return Timer_Type::LOAD +*/ +__STATIC_INLINE uint32_t PTIM_GetLoadValue(void) +{ + return(PTIM->LOAD); +} + +/** \brief Set current counter value from its COUNTER register. +*/ +__STATIC_INLINE void PTIM_SetCurrentValue(uint32_t value) +{ + PTIM->COUNTER = value; +} + +/** \brief Get current counter value from timers COUNTER register. +* \result Timer_Type::COUNTER +*/ +__STATIC_INLINE uint32_t PTIM_GetCurrentValue(void) +{ + return(PTIM->COUNTER); +} + +/** \brief Configure the timer using its CONTROL register. +* \param [in] value The new configuration value to be set. +*/ +__STATIC_INLINE void PTIM_SetControl(uint32_t value) +{ + PTIM->CONTROL = value; +} + +/** ref Timer_Type::CONTROL Get the current timer configuration from its CONTROL register. +* \return Timer_Type::CONTROL +*/ +__STATIC_INLINE uint32_t PTIM_GetControl(void) +{ + return(PTIM->CONTROL); +} + +/** ref Timer_Type::CONTROL Get the event flag in timers ISR register. +* \return 0 - flag is not set, 1- flag is set +*/ +__STATIC_INLINE uint32_t PTIM_GetEventFlag(void) +{ + return (PTIM->ISR & 1UL); +} + +/** ref Timer_Type::CONTROL Clears the event flag in timers ISR register. +*/ +__STATIC_INLINE void PTIM_ClearEventFlag(void) +{ + PTIM->ISR = 1; +} +#endif +#endif + +/* ########################## MMU functions ###################################### */ + +#define SECTION_DESCRIPTOR (0x2) +#define SECTION_MASK (0xFFFFFFFC) + +#define SECTION_TEXCB_MASK (0xFFFF8FF3) +#define SECTION_B_SHIFT (2) +#define SECTION_C_SHIFT (3) +#define SECTION_TEX0_SHIFT (12) +#define SECTION_TEX1_SHIFT (13) +#define SECTION_TEX2_SHIFT (14) + +#define SECTION_XN_MASK (0xFFFFFFEF) +#define SECTION_XN_SHIFT (4) + +#define SECTION_DOMAIN_MASK (0xFFFFFE1F) +#define SECTION_DOMAIN_SHIFT (5) + +#define SECTION_P_MASK (0xFFFFFDFF) +#define SECTION_P_SHIFT (9) + +#define SECTION_AP_MASK (0xFFFF73FF) +#define SECTION_AP_SHIFT (10) +#define SECTION_AP2_SHIFT (15) + +#define SECTION_S_MASK (0xFFFEFFFF) +#define SECTION_S_SHIFT (16) + +#define SECTION_NG_MASK (0xFFFDFFFF) +#define SECTION_NG_SHIFT (17) + +#define SECTION_SUPER_MASK (0xFFF7FFFF) +#define SECTION_SUPER_SHIFT (18) + +#define SECTION_NS_MASK (0xFFF7FFFF) +#define SECTION_NS_SHIFT (19) + +#define PAGE_L1_DESCRIPTOR (0x1) +#define PAGE_L1_MASK (0xFFFFFFFC) + +#define PAGE_L2_4K_DESC (0x2) +#define PAGE_L2_4K_MASK (0xFFFFFFFD) + +#define PAGE_L2_64K_DESC (0x1) +#define PAGE_L2_64K_MASK (0xFFFFFFFC) + +#define PAGE_4K_TEXCB_MASK (0xFFFFFE33) +#define PAGE_4K_B_SHIFT (2) +#define PAGE_4K_C_SHIFT (3) +#define PAGE_4K_TEX0_SHIFT (6) +#define PAGE_4K_TEX1_SHIFT (7) +#define PAGE_4K_TEX2_SHIFT (8) + +#define PAGE_64K_TEXCB_MASK (0xFFFF8FF3) +#define PAGE_64K_B_SHIFT (2) +#define PAGE_64K_C_SHIFT (3) +#define PAGE_64K_TEX0_SHIFT (12) +#define PAGE_64K_TEX1_SHIFT (13) +#define PAGE_64K_TEX2_SHIFT (14) + +#define PAGE_TEXCB_MASK (0xFFFF8FF3) +#define PAGE_B_SHIFT (2) +#define PAGE_C_SHIFT (3) +#define PAGE_TEX_SHIFT (12) + +#define PAGE_XN_4K_MASK (0xFFFFFFFE) +#define PAGE_XN_4K_SHIFT (0) +#define PAGE_XN_64K_MASK (0xFFFF7FFF) +#define PAGE_XN_64K_SHIFT (15) + +#define PAGE_DOMAIN_MASK (0xFFFFFE1F) +#define PAGE_DOMAIN_SHIFT (5) + +#define PAGE_P_MASK (0xFFFFFDFF) +#define PAGE_P_SHIFT (9) + +#define PAGE_AP_MASK (0xFFFFFDCF) +#define PAGE_AP_SHIFT (4) +#define PAGE_AP2_SHIFT (9) + +#define PAGE_S_MASK (0xFFFFFBFF) +#define PAGE_S_SHIFT (10) + +#define PAGE_NG_MASK (0xFFFFF7FF) +#define PAGE_NG_SHIFT (11) + +#define PAGE_NS_MASK (0xFFFFFFF7) +#define PAGE_NS_SHIFT (3) + +#define OFFSET_1M (0x00100000) +#define OFFSET_64K (0x00010000) +#define OFFSET_4K (0x00001000) + +#define DESCRIPTOR_FAULT (0x00000000) + +/* Attributes enumerations */ + +/* Region size attributes */ +typedef enum +{ + SECTION, + PAGE_4k, + PAGE_64k, +} mmu_region_size_Type; + +/* Region type attributes */ +typedef enum +{ + NORMAL, + DEVICE, + SHARED_DEVICE, + NON_SHARED_DEVICE, + STRONGLY_ORDERED +} mmu_memory_Type; + +/* Region cacheability attributes */ +typedef enum +{ + NON_CACHEABLE, + WB_WA, + WT, + WB_NO_WA, +} mmu_cacheability_Type; + +/* Region parity check attributes */ +typedef enum +{ + ECC_DISABLED, + ECC_ENABLED, +} mmu_ecc_check_Type; + +/* Region execution attributes */ +typedef enum +{ + EXECUTE, + NON_EXECUTE, +} mmu_execute_Type; + +/* Region global attributes */ +typedef enum +{ + GLOBAL, + NON_GLOBAL, +} mmu_global_Type; + +/* Region shareability attributes */ +typedef enum +{ + NON_SHARED, + SHARED, +} mmu_shared_Type; + +/* Region security attributes */ +typedef enum +{ + SECURE, + NON_SECURE, +} mmu_secure_Type; + +/* Region access attributes */ +typedef enum +{ + NO_ACCESS, + RW, + READ, +} mmu_access_Type; + +/* Memory Region definition */ +typedef struct RegionStruct { + mmu_region_size_Type rg_t; + mmu_memory_Type mem_t; + uint8_t domain; + mmu_cacheability_Type inner_norm_t; + mmu_cacheability_Type outer_norm_t; + mmu_ecc_check_Type e_t; + mmu_execute_Type xn_t; + mmu_global_Type g_t; + mmu_secure_Type sec_t; + mmu_access_Type priv_t; + mmu_access_Type user_t; + mmu_shared_Type sh_t; + +} mmu_region_attributes_Type; + +//Following macros define the descriptors and attributes +//Sect_Normal. Outer & inner wb/wa, non-shareable, executable, rw, domain 0 +#define section_normal(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_NC. Outer & inner non-cacheable, non-shareable, executable, rw, domain 0 +#define section_normal_nc(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_RO_NC. Outer & inner non-cacheable, non-shareable, executable, ro, domain 0 +#define section_normal_ro_nc(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_Cod. Outer & inner wb/wa, non-shareable, executable, ro, domain 0 +#define section_normal_cod(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_RO. Sect_Normal_Cod, but not executable +#define section_normal_ro(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_RW. Sect_Normal_Cod, but writeable and not executable +#define section_normal_rw(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); +//Sect_SO. Strongly-ordered (therefore shareable), not executable, rw, domain 0, base addr 0 +#define section_so(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +#if 0 +//Sect_Device_RO. Device, non-shareable, non-executable, ro, domain 0, base addr 0 +#define section_device_ro(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Device_RW. Sect_Device_RO, but writeable +#define section_device_rw(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); +#else +//Sect_Device_RO. Device, non-shareable, non-executable, ro, domain 0, base addr 0 +#define section_device_ro(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = SHARED_DEVICE; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Device_RW. Sect_Device_RO, but writeable +#define section_device_rw(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = SHARED_DEVICE; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); +#endif + +//Page_4k_Device_RW. Shared device, not executable, rw, domain 0 +#define page4k_device_rw(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_4k; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = SHARED_DEVICE; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); + +//Page_4k_Normal. Outer & inner wb/wa, non-shareable, executable, rw, domain 0 +#define page4k_normal(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_4k; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); + +//Page_64k_Device_RW. Shared device, not executable, rw, domain 0 +#define page64k_device_rw(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_64k; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = SHARED_DEVICE; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); + +/** \brief Set section execution-never attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] xn Section execution-never attribute : EXECUTE , NON_EXECUTE. + + \return 0 +*/ +__STATIC_INLINE int MMU_XNSection(uint32_t *descriptor_l1, mmu_execute_Type xn) +{ + *descriptor_l1 &= SECTION_XN_MASK; + *descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT); + return 0; +} + +/** \brief Set section domain + + \param [out] descriptor_l1 L1 descriptor. + \param [in] domain Section domain + + \return 0 +*/ +__STATIC_INLINE int MMU_DomainSection(uint32_t *descriptor_l1, uint8_t domain) +{ + *descriptor_l1 &= SECTION_DOMAIN_MASK; + *descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT); + return 0; +} + +/** \brief Set section parity check + + \param [out] descriptor_l1 L1 descriptor. + \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED + + \return 0 +*/ +__STATIC_INLINE int MMU_PSection(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) +{ + *descriptor_l1 &= SECTION_P_MASK; + *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); + return 0; +} + +/** \brief Set section access privileges + + \param [out] descriptor_l1 L1 descriptor. + \param [in] user User Level Access: NO_ACCESS, RW, READ + \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ + \param [in] afe Access flag enable + + \return 0 +*/ +__STATIC_INLINE int MMU_APSection(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) +{ + uint32_t ap = 0; + + if (afe == 0) { //full access + if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } + else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == READ)) { ap = 0x2; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + else { //Simplified access + if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + *descriptor_l1 &= SECTION_AP_MASK; + *descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT; + *descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT; + + return 0; +} + +/** \brief Set section shareability + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit Section shareability: NON_SHARED, SHARED + + \return 0 +*/ +__STATIC_INLINE int MMU_SharedSection(uint32_t *descriptor_l1, mmu_shared_Type s_bit) +{ + *descriptor_l1 &= SECTION_S_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT); + return 0; +} + +/** \brief Set section Global attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] g_bit Section attribute: GLOBAL, NON_GLOBAL + + \return 0 +*/ +__STATIC_INLINE int MMU_GlobalSection(uint32_t *descriptor_l1, mmu_global_Type g_bit) +{ + *descriptor_l1 &= SECTION_NG_MASK; + *descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT); + return 0; +} + +__STATIC_INLINE int MMU_SuperSection(uint32_t *descriptor_l1, mmu_secure_Type s_bit) +{ + *descriptor_l1 &= SECTION_SUPER_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << SECTION_SUPER_SHIFT); + return 0; +} + +/** \brief Set section Security attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit Section Security attribute: SECURE, NON_SECURE + + \return 0 +*/ +__STATIC_INLINE int MMU_SecureSection(uint32_t *descriptor_l1, mmu_secure_Type s_bit) +{ + *descriptor_l1 &= SECTION_NS_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT); + return 0; +} + +/* Page 4k or 64k */ +/** \brief Set 4k/64k page execution-never attribute + + \param [out] descriptor_l2 L2 descriptor. + \param [in] xn Page execution-never attribute : EXECUTE , NON_EXECUTE. + \param [in] page Page size: PAGE_4k, PAGE_64k, + + \return 0 +*/ +__STATIC_INLINE int MMU_XNPage(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page) +{ + if (page == PAGE_4k) + { + *descriptor_l2 &= PAGE_XN_4K_MASK; + *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT); + } + else + { + *descriptor_l2 &= PAGE_XN_64K_MASK; + *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT); + } + return 0; +} + +/** \brief Set 4k/64k page domain + + \param [out] descriptor_l1 L1 descriptor. + \param [in] domain Page domain + + \return 0 +*/ +__STATIC_INLINE int MMU_DomainPage(uint32_t *descriptor_l1, uint8_t domain) +{ + *descriptor_l1 &= PAGE_DOMAIN_MASK; + *descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page parity check + + \param [out] descriptor_l1 L1 descriptor. + \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED + + \return 0 +*/ +__STATIC_INLINE int MMU_PPage(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) +{ + *descriptor_l1 &= SECTION_P_MASK; + *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page access privileges + + \param [out] descriptor_l2 L2 descriptor. + \param [in] user User Level Access: NO_ACCESS, RW, READ + \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ + \param [in] afe Access flag enable + + \return 0 +*/ +__STATIC_INLINE int MMU_APPage(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) +{ + uint32_t ap = 0; + + if (afe == 0) { //full access + if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } + else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == READ)) { ap = 0x2; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x6; } + } + + else { //Simplified access + if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + *descriptor_l2 &= PAGE_AP_MASK; + *descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT; + *descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT; + + return 0; +} + +/** \brief Set 4k/64k page shareability + + \param [out] descriptor_l2 L2 descriptor. + \param [in] s_bit 4k/64k page shareability: NON_SHARED, SHARED + + \return 0 +*/ +__STATIC_INLINE int MMU_SharedPage(uint32_t *descriptor_l2, mmu_shared_Type s_bit) +{ + *descriptor_l2 &= PAGE_S_MASK; + *descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page Global attribute + + \param [out] descriptor_l2 L2 descriptor. + \param [in] g_bit 4k/64k page attribute: GLOBAL, NON_GLOBAL + + \return 0 +*/ +__STATIC_INLINE int MMU_GlobalPage(uint32_t *descriptor_l2, mmu_global_Type g_bit) +{ + *descriptor_l2 &= PAGE_NG_MASK; + *descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page Security attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit 4k/64k page Security attribute: SECURE, NON_SECURE + + \return 0 +*/ +__STATIC_INLINE int MMU_SecurePage(uint32_t *descriptor_l1, mmu_secure_Type s_bit) +{ + *descriptor_l1 &= PAGE_NS_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT); + return 0; +} + +/** \brief Set Section memory attributes + + \param [out] descriptor_l1 L1 descriptor. + \param [in] mem Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED + \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + + \return 0 +*/ +__STATIC_INLINE int MMU_MemorySection(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner) +{ + *descriptor_l1 &= SECTION_TEXCB_MASK; + + if (STRONGLY_ORDERED == mem) + { + return 0; + } + else if (SHARED_DEVICE == mem) + { + *descriptor_l1 |= (1 << SECTION_B_SHIFT); + } + else if (NON_SHARED_DEVICE == mem) + { + *descriptor_l1 |= (1 << SECTION_TEX1_SHIFT); + } + else if (NORMAL == mem) + { + *descriptor_l1 |= 1 << SECTION_TEX2_SHIFT; + switch(inner) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l1 |= (1 << SECTION_B_SHIFT); + break; + case WT: + *descriptor_l1 |= 1 << SECTION_C_SHIFT; + break; + case WB_NO_WA: + *descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT); + break; + } + switch(outer) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT); + break; + case WT: + *descriptor_l1 |= 1 << SECTION_TEX1_SHIFT; + break; + case WB_NO_WA: + *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT); + break; + } + } + return 0; +} + +/** \brief Set 4k/64k page memory attributes + + \param [out] descriptor_l2 L2 descriptor. + \param [in] mem 4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED + \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] page Page size + + \return 0 +*/ +__STATIC_INLINE int MMU_MemoryPage(uint32_t *descriptor_l2, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner, mmu_region_size_Type page) +{ + *descriptor_l2 &= PAGE_4K_TEXCB_MASK; + + if (page == PAGE_64k) + { + //same as section + MMU_MemorySection(descriptor_l2, mem, outer, inner); + } + else + { + if (STRONGLY_ORDERED == mem) + { + return 0; + } + else if (SHARED_DEVICE == mem) + { + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); + } + else if (NON_SHARED_DEVICE == mem) + { + *descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT); + } + else if (NORMAL == mem) + { + *descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT; + switch(inner) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); + break; + case WT: + *descriptor_l2 |= 1 << PAGE_4K_C_SHIFT; + break; + case WB_NO_WA: + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT); + break; + } + switch(outer) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT); + break; + case WT: + *descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT; + break; + case WB_NO_WA: + *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX1_SHIFT); + break; + } + } + } + + return 0; +} + +/** \brief Create a L1 section descriptor + + \param [out] descriptor L1 descriptor + \param [in] reg Section attributes + + \return 0 +*/ +__STATIC_INLINE int MMU_GetSectionDescriptor(uint32_t *descriptor, mmu_region_attributes_Type reg) +{ + *descriptor = 0; + + MMU_MemorySection(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t); + MMU_XNSection(descriptor,reg.xn_t); + MMU_DomainSection(descriptor, reg.domain); + MMU_PSection(descriptor, reg.e_t); + MMU_APSection(descriptor, reg.priv_t, reg.user_t, 1); + MMU_SharedSection(descriptor,reg.sh_t); + MMU_GlobalSection(descriptor,reg.g_t); + MMU_SecureSection(descriptor,reg.sec_t); + *descriptor &= SECTION_MASK; + *descriptor |= SECTION_DESCRIPTOR; + + return 0; +} + +/** \brief Create a L1 and L2 4k/64k page descriptor + + \param [out] descriptor L1 descriptor + \param [out] descriptor2 L2 descriptor + \param [in] reg 4k/64k page attributes + + \return 0 +*/ +__STATIC_INLINE int MMU_GetPageDescriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg) +{ + *descriptor = 0; + *descriptor2 = 0; + + switch (reg.rg_t) + { + case PAGE_4k: + MMU_MemoryPage(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k); + MMU_XNPage(descriptor2, reg.xn_t, PAGE_4k); + MMU_DomainPage(descriptor, reg.domain); + MMU_PPage(descriptor, reg.e_t); + MMU_APPage(descriptor2, reg.priv_t, reg.user_t, 1); + MMU_SharedPage(descriptor2,reg.sh_t); + MMU_GlobalPage(descriptor2,reg.g_t); + MMU_SecurePage(descriptor,reg.sec_t); + *descriptor &= PAGE_L1_MASK; + *descriptor |= PAGE_L1_DESCRIPTOR; + *descriptor2 &= PAGE_L2_4K_MASK; + *descriptor2 |= PAGE_L2_4K_DESC; + break; + + case PAGE_64k: + MMU_MemoryPage(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k); + MMU_XNPage(descriptor2, reg.xn_t, PAGE_64k); + MMU_DomainPage(descriptor, reg.domain); + MMU_PPage(descriptor, reg.e_t); + MMU_APPage(descriptor2, reg.priv_t, reg.user_t, 1); + MMU_SharedPage(descriptor2,reg.sh_t); + MMU_GlobalPage(descriptor2,reg.g_t); + MMU_SecurePage(descriptor,reg.sec_t); + *descriptor &= PAGE_L1_MASK; + *descriptor |= PAGE_L1_DESCRIPTOR; + *descriptor2 &= PAGE_L2_64K_MASK; + *descriptor2 |= PAGE_L2_64K_DESC; + break; + + case SECTION: + //error + break; + } + + return 0; +} + +/** \brief Create a 1MB Section + + \param [in] ttb Translation table base address + \param [in] base_address Section base address + \param [in] count Number of sections to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1) +{ + uint32_t offset; + uint32_t entry; + uint32_t i; + + offset = base_address >> 20; + entry = (base_address & 0xFFF00000) | descriptor_l1; + + //4 bytes aligned + ttb = ttb + offset; + + for (i = 0; i < count; i++ ) + { + //4 bytes aligned + *(volatile uint32_t *)ttb++ = entry; + entry += OFFSET_1M; + } +} + +__STATIC_INLINE void MMU_TTSuperSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1) +{ + uint32_t offset; + uint32_t entry; + uint32_t i; + + offset = base_address >> 20; + entry = (base_address & 0xFF000000) | descriptor_l1 | (1 << SECTION_SUPER_SHIFT); + + //4 bytes aligned + ttb = ttb + offset; + + for (i = 0; i < count; i++ ) + { + //4 bytes aligned + *(volatile uint32_t *)ttb++ = entry; + entry += OFFSET_1M; + } +} + +/** \brief Create a 4k page entry + + \param [in] ttb L1 table base address + \param [in] base_address 4k base address + \param [in] count Number of 4k pages to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + \param [in] ttb_l2 L2 table base address + \param [in] descriptor_l2 L2 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTPage4k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) +{ + + uint32_t offset, offset2; + uint32_t entry, entry2; + uint32_t i; + + offset = base_address >> 20; + entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; + + //4 bytes aligned + ttb += offset; + //create l1_entry + *(volatile uint32_t *)ttb = entry; + + offset2 = (base_address & 0xff000) >> 12; + ttb_l2 += offset2; + entry2 = (base_address & 0xFFFFF000) | descriptor_l2; + for (i = 0; i < count; i++ ) + { + //4 bytes aligned + *(volatile uint32_t *)ttb_l2++ = entry2; + entry2 += OFFSET_4K; + } +} + +/** \brief Create a 64k page entry + + \param [in] ttb L1 table base address + \param [in] base_address 64k base address + \param [in] count Number of 64k pages to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + \param [in] ttb_l2 L2 table base address + \param [in] descriptor_l2 L2 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTPage64k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) +{ + uint32_t offset, offset2; + uint32_t entry, entry2; + uint32_t i,j; + + + offset = base_address >> 20; + entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; + + //4 bytes aligned + ttb += offset; + //create l1_entry + *(volatile uint32_t *)ttb = entry; + + offset2 = (base_address & 0xff000) >> 12; + ttb_l2 += offset2; + entry2 = (base_address & 0xFFFF0000) | descriptor_l2; + for (i = 0; i < count; i++ ) + { + //create 16 entries + for (j = 0; j < 16; j++) + { + //4 bytes aligned + *(volatile uint32_t *)ttb_l2++ = entry2; + } + entry2 += OFFSET_64K; + } +} + +/** \brief Enable MMU +*/ +__STATIC_INLINE void MMU_Enable(void) +{ + // Set M bit 0 to enable the MMU + // Set AFE bit to enable simplified access permissions model + // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking + __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29)); + __ISB(); +} + +/** \brief Disable MMU +*/ +__STATIC_INLINE void MMU_Disable(void) +{ + // Clear M bit 0 to disable the MMU + __set_SCTLR( __get_SCTLR() & ~1); + __ISB(); +} + +/** \brief Invalidate entire unified TLB +*/ + +__STATIC_INLINE void MMU_InvalidateTLB(void) +{ + __set_TLBIALL(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new state +} + + +#endif // !__ASSEMBLER__ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CA_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/ca/irq_ctrl.h b/platform/cmsis/inc/ca/irq_ctrl.h new file mode 100644 index 0000000..b171ef0 --- /dev/null +++ b/platform/cmsis/inc/ca/irq_ctrl.h @@ -0,0 +1,186 @@ +/**************************************************************************//** + * @file irq_ctrl.h + * @brief Interrupt Controller API header file + * @version V1.0.0 + * @date 23. June 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017 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 IRQ_CTRL_H_ +#define IRQ_CTRL_H_ + +#include + +#ifndef IRQHANDLER_T +#define IRQHANDLER_T +/// Interrupt handler data type +typedef void (*IRQHandler_t) (void); +#endif + +#ifndef IRQN_ID_T +#define IRQN_ID_T +/// Interrupt ID number data type +typedef int32_t IRQn_ID_t; +#endif + +/* Interrupt mode bit-masks */ +#define IRQ_MODE_TRIG_Pos (0U) +#define IRQ_MODE_TRIG_Msk (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) +#define IRQ_MODE_TRIG_LEVEL (0x00UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: level triggered interrupt +#define IRQ_MODE_TRIG_LEVEL_LOW (0x01UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: low level triggered interrupt +#define IRQ_MODE_TRIG_LEVEL_HIGH (0x02UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: high level triggered interrupt +#define IRQ_MODE_TRIG_EDGE (0x04UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_RISING (0x05UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_FALLING (0x06UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: falling edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_BOTH (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising and falling edge triggered interrupt + +#define IRQ_MODE_TYPE_Pos (3U) +#define IRQ_MODE_TYPE_Msk (0x01UL << IRQ_MODE_TYPE_Pos) +#define IRQ_MODE_TYPE_IRQ (0x00UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU IRQ line +#define IRQ_MODE_TYPE_FIQ (0x01UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU FIQ line + +#define IRQ_MODE_DOMAIN_Pos (4U) +#define IRQ_MODE_DOMAIN_Msk (0x01UL << IRQ_MODE_DOMAIN_Pos) +#define IRQ_MODE_DOMAIN_NONSECURE (0x00UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting non-secure domain +#define IRQ_MODE_DOMAIN_SECURE (0x01UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting secure domain + +#define IRQ_MODE_CPU_Pos (5U) +#define IRQ_MODE_CPU_Msk (0xFFUL << IRQ_MODE_CPU_Pos) +#define IRQ_MODE_CPU_ALL (0x00UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets all CPUs +#define IRQ_MODE_CPU_0 (0x01UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 0 +#define IRQ_MODE_CPU_1 (0x02UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 1 +#define IRQ_MODE_CPU_2 (0x04UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 2 +#define IRQ_MODE_CPU_3 (0x08UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 3 +#define IRQ_MODE_CPU_4 (0x10UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 4 +#define IRQ_MODE_CPU_5 (0x20UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 5 +#define IRQ_MODE_CPU_6 (0x40UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 6 +#define IRQ_MODE_CPU_7 (0x80UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 7 + +#define IRQ_MODE_ERROR (0x80000000UL) ///< Bit indicating mode value error + +/* Interrupt priority bit-masks */ +#define IRQ_PRIORITY_Msk (0x0000FFFFUL) ///< Interrupt priority value bit-mask +#define IRQ_PRIORITY_ERROR (0x80000000UL) ///< Bit indicating priority value error + +/// Initialize interrupt controller. +/// \return 0 on success, -1 on error. +int32_t IRQ_Initialize (void); + +/// Register interrupt handler. +/// \param[in] irqn interrupt ID number +/// \param[in] handler interrupt handler function address +/// \return 0 on success, -1 on error. +int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler); + +/// Get the registered interrupt handler. +/// \param[in] irqn interrupt ID number +/// \return registered interrupt handler function address. +IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn); + +/// Enable interrupt. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_Enable (IRQn_ID_t irqn); + +/// Disable interrupt. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_Disable (IRQn_ID_t irqn); + +/// Get interrupt enable state. +/// \param[in] irqn interrupt ID number +/// \return 0 - interrupt is disabled, 1 - interrupt is enabled. +uint32_t IRQ_GetEnableState (IRQn_ID_t irqn); + +/// Configure interrupt request mode. +/// \param[in] irqn interrupt ID number +/// \param[in] mode mode configuration +/// \return 0 on success, -1 on error. +int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode); + +/// Get interrupt mode configuration. +/// \param[in] irqn interrupt ID number +/// \return current interrupt mode configuration with optional IRQ_MODE_ERROR bit set. +uint32_t IRQ_GetMode (IRQn_ID_t irqn); + +/// Get ID number of current interrupt request (IRQ). +/// \return interrupt ID number. +IRQn_ID_t IRQ_GetActiveIRQ (void); + +/// Get ID number of current fast interrupt request (FIQ). +/// \return interrupt ID number. +IRQn_ID_t IRQ_GetActiveFIQ (void); + +/// Signal end of interrupt processing. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn); + +/// Set interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPending (IRQn_ID_t irqn); + +/// Get interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 - interrupt is not pending, 1 - interrupt is pending. +uint32_t IRQ_GetPending (IRQn_ID_t irqn); + +/// Clear interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_ClearPending (IRQn_ID_t irqn); + +/// Set interrupt priority value. +/// \param[in] irqn interrupt ID number +/// \param[in] priority interrupt priority value +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority); + +/// Get interrupt priority. +/// \param[in] irqn interrupt ID number +/// \return current interrupt priority value with optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriority (IRQn_ID_t irqn); + +/// Set priority masking threshold. +/// \param[in] priority priority masking threshold value +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriorityMask (uint32_t priority); + +/// Get priority masking threshold +/// \return current priority masking threshold value with optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriorityMask (void); + +/// Set priority grouping field split point +/// \param[in] bits number of MSB bits included in the group priority field comparison +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriorityGroupBits (uint32_t bits); + +/// Get priority grouping field split point +/// \return current number of MSB bits included in the group priority field comparison with +/// optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriorityGroupBits (void); + +#endif // IRQ_CTRL_H_ diff --git a/platform/cmsis/inc/ca/mem_ARMCA.h b/platform/cmsis/inc/ca/mem_ARMCA.h new file mode 100644 index 0000000..4aec7e9 --- /dev/null +++ b/platform/cmsis/inc/ca/mem_ARMCA.h @@ -0,0 +1,103 @@ +/**************************************************************************//** + * @file mem_ARMCA7.h + * @brief Memory base and size definitions (used in scatter file) + * @version V1.1.0 + * @date 15. May 2019 + * + * @note + * + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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 __MEM_ARMCA7_H +#define __MEM_ARMCA7_H + +/*---------------------------------------------------------------------------- + User Stack & Heap size definition + *----------------------------------------------------------------------------*/ +/* +//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +*/ + +#if 0 +/*--------------------- ROM Configuration ------------------------------------ +// +// ROM Configuration +// For compatibility with MMU config the sections must be multiple of 1MB +// ROM Base Address <0x0-0xFFFFFFFF:0x100000> +// ROM Size (in Bytes) <0x0-0xFFFFFFFF:0x100000> +// + *----------------------------------------------------------------------------*/ +#define __ROM_BASE 0x80000000 +#define __ROM_SIZE 0x00200000 + +/*--------------------- RAM Configuration ----------------------------------- +// RAM Configuration +// For compatibility with MMU config the sections must be multiple of 1MB +// RAM Base Address <0x0-0xFFFFFFFF:0x100000> +// RAM Total Size (in Bytes) <0x0-0xFFFFFFFF:0x100000> +// Data Sections +// RW_DATA Size (in Bytes) <0x0-0xFFFFFFFF:8> +// ZI_DATA Size (in Bytes) <0x0-0xFFFFFFFF:8> +// +// Stack / Heap Configuration +// Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +// Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +// Exceptional Modes +// UND Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +// ABT Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +// SVC Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +// IRQ Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +// FIQ Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +// +// +// + *----------------------------------------------------------------------------*/ +#define __RAM_BASE 0x80200000 +#define __RAM_SIZE 0x00200000 + +#define __RW_DATA_SIZE 0x00100000 +#define __ZI_DATA_SIZE 0x000F0000 + +#define __STACK_SIZE 0x00001000 +#define __HEAP_SIZE 0x00008000 + +#define __UND_STACK_SIZE 0x00000100 +#define __ABT_STACK_SIZE 0x00000100 +#define __SVC_STACK_SIZE 0x00000100 +#define __IRQ_STACK_SIZE 0x00000100 +#define __FIQ_STACK_SIZE 0x00000100 + +/*----------------------------------------------------------------------------*/ + +/*--------------------- TTB Configuration ------------------------------------ +// +// TTB Configuration +// The TLB L1 contains 4096 32-bit entries and must be 16kB aligned +// The TLB L2 entries are placed after the L1 in the MMU config +// TTB Base Address <0x0-0xFFFFFFFF:0x4000> +// TTB Size (in Bytes) <0x0-0xFFFFFFFF:8> +// + *----------------------------------------------------------------------------*/ +#define __TTB_BASE 0x80500000 +#define __TTB_SIZE 0x00005000 + +#endif + +#endif /* __MEM_ARMCA7_H */ diff --git a/platform/cmsis/inc/ca/system_ARMCA.h b/platform/cmsis/inc/ca/system_ARMCA.h new file mode 100644 index 0000000..eb89600 --- /dev/null +++ b/platform/cmsis/inc/ca/system_ARMCA.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SYSTEM_ARMCA_H__ +#define __SYSTEM_ARMCA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "system_ARMCM.h" + +void MMU_CreateTranslationTable(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/cmsis.h b/platform/cmsis/inc/cmsis.h new file mode 100644 index 0000000..082e720 --- /dev/null +++ b/platform/cmsis/inc/cmsis.h @@ -0,0 +1,150 @@ +/* mbed Microcontroller Library - CMSIS + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * A generic CMSIS include header, pulling in LPC11U24 specifics + */ + +#ifndef MBED_CMSIS_H +#define MBED_CMSIS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_addr_map.h" +#include _TO_STRING(CONCAT_SUFFIX(CHIP_ID_LITERAL, h)) + +#define IRQ_PRIORITY_REALTIME 0 +#define IRQ_PRIORITY_HIGHPLUSPLUS 1 +#define IRQ_PRIORITY_HIGHPLUS 2 +#define IRQ_PRIORITY_HIGH 3 +#define IRQ_PRIORITY_ABOVENORMAL 4 +#define IRQ_PRIORITY_NORMAL 5 +#define IRQ_PRIORITY_BELOWNORMAL 6 +#define IRQ_PRIORITY_LOW 7 + +#ifdef __ARM_ARCH_ISA_ARM +#define IRQ_LOCK_MASK (CPSR_I_Msk | CPSR_F_Msk) +#else +#define NVIC_USER_IRQ_OFFSET 16 +#define NVIC_NUM_VECTORS (NVIC_USER_IRQ_OFFSET + USER_IRQn_QTY) +#endif + +#ifndef __ASSEMBLER__ + +#ifdef __ARMCC_VERSION +// Stupid armclang +#undef __SSAT +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) +#endif + +__STATIC_FORCEINLINE uint32_t int_lock_global(void) +{ +#ifdef __ARM_ARCH_ISA_ARM + uint32_t cpsr = __get_CPSR(); + uint32_t st = cpsr & IRQ_LOCK_MASK; + if (st != IRQ_LOCK_MASK) { + cpsr |= IRQ_LOCK_MASK; + __set_CPSR(cpsr); + } + return st; +#else + uint32_t pri = __get_PRIMASK(); + if ((pri & 0x1) == 0) { + __disable_irq(); + } + return pri; +#endif +} + +__STATIC_FORCEINLINE void int_unlock_global(uint32_t pri) +{ +#ifdef __ARM_ARCH_ISA_ARM + if (pri != IRQ_LOCK_MASK) { + uint32_t cpsr = __get_CPSR(); + cpsr = (cpsr & ~IRQ_LOCK_MASK) | pri; + __set_CPSR(cpsr); + } +#else + if ((pri & 0x1) == 0) { + __enable_irq(); + } +#endif +} + +__STATIC_FORCEINLINE uint32_t int_lock(void) +{ +#ifdef INT_LOCK_EXCEPTION +#ifdef __ARM_ARCH_ISA_ARM + uint32_t mask = GIC_GetInterfacePriorityMask(); + // Only allow IRQs with priority IRQ_PRIORITY_HIGHPLUSPLUS and IRQ_PRIORITY_REALTIME + GIC_SetInterfacePriorityMask(((IRQ_PRIORITY_HIGHPLUS << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL)); + return mask; +#else + uint32_t pri = __get_BASEPRI(); + // Only allow IRQs with priority IRQ_PRIORITY_HIGHPLUSPLUS and IRQ_PRIORITY_REALTIME + __set_BASEPRI(((IRQ_PRIORITY_HIGHPLUS << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL)); + return pri; +#endif +#else + return int_lock_global(); +#endif +} + +__STATIC_FORCEINLINE void int_unlock(uint32_t pri) +{ +#ifdef INT_LOCK_EXCEPTION +#ifdef __ARM_ARCH_ISA_ARM + GIC_SetInterfacePriorityMask(pri); +#else + __set_BASEPRI(pri); +#endif +#else + int_unlock_global(pri); +#endif +} + +__STATIC_FORCEINLINE int in_isr(void) +{ +#ifdef __ARM_ARCH_ISA_ARM + uint32_t mode = __get_mode(); + return mode != CPSR_M_USR && mode != CPSR_M_SYS; +#else + return __get_IPSR() != 0; +#endif +} + +__STATIC_FORCEINLINE int32_t ftoi_nearest(float f) +{ + return (f >= 0) ? (int32_t)(f + 0.5) : (int32_t)(f - 0.5); +} + +void GotBaseInit(void); + +int set_bool_flag(bool *flag); + +void clear_bool_flag(bool *flag); + +float db_to_float(float db); + +uint32_t get_msb_pos(uint32_t val); + +uint32_t get_lsb_pos(uint32_t val); + +uint32_t integer_sqrt(uint32_t val); + +uint32_t integer_sqrt_nearest(uint32_t val); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/cmsis_armcc.h b/platform/cmsis/inc/cmsis_armcc.h new file mode 100644 index 0000000..174d744 --- /dev/null +++ b/platform/cmsis/inc/cmsis_armcc.h @@ -0,0 +1,869 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.5 + * @date 14. December 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_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + +/* CMSIS compiler control DSP macros */ +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __ARM_FEATURE_DSP 1 +#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 static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(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 __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/* ########################### 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 the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \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_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \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_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \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_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#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_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __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 __wfi + + +/** + \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 __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __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. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \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. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \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 + */ +#define __REV __rev + + +/** + \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 + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \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 + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#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 + */ +#define __ROR __ror + + +/** + \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) __breakpoint(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 + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + 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 */ + return result; +} +#endif + + +/** + \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 + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 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) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \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) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \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) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \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 + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \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 + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \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 + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \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 + */ +#define __SSAT __ssat + + +/** + \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 + */ +#define __USAT __usat + + +/** + \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 + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \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) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \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) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \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) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \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 + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \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 + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \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 + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/platform/cmsis/inc/cmsis_armclang.h b/platform/cmsis/inc/cmsis_armclang.h new file mode 100644 index 0000000..6a8867d --- /dev/null +++ b/platform/cmsis/inc/cmsis_armclang.h @@ -0,0 +1,1420 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.1.0 + * @date 14. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#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 clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang 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 + + +/* ########################### 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 the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \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"); +} + + +#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"); +} +#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 the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \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 in non-secure + mode. + + \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 in non-secure + mode. + + \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. + + \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. + + \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 + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)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 + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## 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 __builtin_arm_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 __builtin_arm_wfi + + +/** + \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 __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_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. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \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. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \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 + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \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 + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \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 + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \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 + */ +#define __RBIT __builtin_arm_rbit + +/** + \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 Compiler 6.10 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) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \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) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \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) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \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 + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \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 + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \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 + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#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] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \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 + */ +#define __USAT __builtin_arm_usat + + +/** + \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; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + 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; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + 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) ); + 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) ); + 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) ); + 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) ); +} + + +/** + \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) ); +} + + +/** + \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) ); +} + + +/** + \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) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \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) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \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) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \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 + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \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 + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \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 + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#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 */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __SADD8 __builtin_arm_sadd8 +#define __QADD8 __builtin_arm_qadd8 +#define __SHADD8 __builtin_arm_shadd8 +#define __UADD8 __builtin_arm_uadd8 +#define __UQADD8 __builtin_arm_uqadd8 +#define __UHADD8 __builtin_arm_uhadd8 +#define __SSUB8 __builtin_arm_ssub8 +#define __QSUB8 __builtin_arm_qsub8 +#define __SHSUB8 __builtin_arm_shsub8 +#define __USUB8 __builtin_arm_usub8 +#define __UQSUB8 __builtin_arm_uqsub8 +#define __UHSUB8 __builtin_arm_uhsub8 +#define __SADD16 __builtin_arm_sadd16 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __UADD16 __builtin_arm_uadd16 +#define __UQADD16 __builtin_arm_uqadd16 +#define __UHADD16 __builtin_arm_uhadd16 +#define __SSUB16 __builtin_arm_ssub16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __USUB16 __builtin_arm_usub16 +#define __UQSUB16 __builtin_arm_uqsub16 +#define __UHSUB16 __builtin_arm_uhsub16 +#define __SASX __builtin_arm_sasx +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __UASX __builtin_arm_uasx +#define __UQASX __builtin_arm_uqasx +#define __UHASX __builtin_arm_uhasx +#define __SSAX __builtin_arm_ssax +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __USAX __builtin_arm_usax +#define __UQSAX __builtin_arm_uqsax +#define __UHSAX __builtin_arm_uhsax +#define __USAD8 __builtin_arm_usad8 +#define __USADA8 __builtin_arm_usada8 +#define __SSAT16 __builtin_arm_ssat16 +#define __USAT16 __builtin_arm_usat16 +#define __UXTB16 __builtin_arm_uxtb16 +#define __UXTAB16 __builtin_arm_uxtab16 +#define __SXTB16 __builtin_arm_sxtb16 +#define __SXTAB16 __builtin_arm_sxtab16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSD __builtin_arm_smlsd +#define __SMLSDX __builtin_arm_smlsdx +#define __SMLSLD __builtin_arm_smlsld +#define __SMLSLDX __builtin_arm_smlsldx +#define __SEL __builtin_arm_sel +#define __QADD __builtin_arm_qadd +#define __QSUB __builtin_arm_qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("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 */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/platform/cmsis/inc/cmsis_armclang_ltm.h b/platform/cmsis/inc/cmsis_armclang_ltm.h new file mode 100644 index 0000000..e4002a3 --- /dev/null +++ b/platform/cmsis/inc/cmsis_armclang_ltm.h @@ -0,0 +1,1866 @@ +/**************************************************************************//** + * @file cmsis_armclang_ltm.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V1.0.1 + * @date 19. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2018-2019 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. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#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 clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang 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 + + +/* ########################### 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 the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \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"); +} + + +#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"); +} +#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 the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \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 in non-secure + mode. + + \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 in non-secure + mode. + + \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. + + \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. + + \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 + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)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 + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## 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_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_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 __builtin_arm_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 __builtin_arm_wfi + + +/** + \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 __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_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. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \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. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \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 + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \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 + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \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 + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \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 + */ +#define __RBIT __builtin_arm_rbit + +/** + \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 Compiler 6.10 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) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \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) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \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) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \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 + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \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 + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \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 + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#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] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \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 + */ +#define __USAT __builtin_arm_usat + + +/** + \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; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + 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; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + 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) ); + 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) ); + 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) ); + 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) ); +} + + +/** + \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) ); +} + + +/** + \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) ); +} + + +/** + \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) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \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) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \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) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \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 + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \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 + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \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 + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#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 */ + + +/* ################### 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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + 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) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("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 */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/platform/cmsis/inc/cmsis_compiler.h b/platform/cmsis/inc/cmsis_compiler.h new file mode 100644 index 0000000..fdb1a97 --- /dev/null +++ b/platform/cmsis/inc/cmsis_compiler.h @@ -0,0 +1,271 @@ +/**************************************************************************//** + * @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 + + +/* + * 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 + + +/* + * 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 + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/platform/cmsis/inc/cmsis_gcc.h b/platform/cmsis/inc/cmsis_gcc.h new file mode 100644 index 0000000..9c2961c --- /dev/null +++ b/platform/cmsis/inc/cmsis_gcc.h @@ -0,0 +1,2101 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.1.0 + * @date 20. December 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_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 + + +/* ########################### 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 the I-bit in the CPSR. + 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 the I-bit in the CPSR. + 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"); +} + + +#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"); +} +#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) :: "memory"); + 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) :: "memory"); + 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 the F-bit in the CPSR. + 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 the F-bit in the CPSR. + 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 */ + + +/* ########################## 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") + + +/** + \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") + + +/** + \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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __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 ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __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) ); + 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) ); + 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) ); + 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) ); +} + + +/** + \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) ); +} + + +/** + \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) ); +} + + +/** + \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) ); + 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) ); + 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) ); + 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) ); + 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) ); + 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) ); + 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 */ + + +/* ################### 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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("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 volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __SXTB16(uint32_t op1) +{ + int32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE int32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + int32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + int32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + int32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + int32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + int32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE int64_t __SMLALD (uint32_t op1, uint32_t op2, int64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + int64_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 int64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + int64_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 int32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + int32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + int32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + int32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + int32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE int64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + int64_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 int64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + int64_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); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + 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) \ +({ \ + 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; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("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/platform/cmsis/inc/cmsis_iccarm.h b/platform/cmsis/inc/cmsis_iccarm.h new file mode 100644 index 0000000..20b50ce --- /dev/null +++ b/platform/cmsis/inc/cmsis_iccarm.h @@ -0,0 +1,940 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.8 + * @date 04. September 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// 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. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #if __ICCARM_V8 + #define __RESTRICT __restrict + #else + /* Needs IAR language extensions */ + #define __RESTRICT restrict + #endif +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #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 + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #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 + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #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 + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #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 + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #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 + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE 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_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #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 + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #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)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #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 + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #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)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #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 + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #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)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE 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_INLINE 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 + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/platform/cmsis/inc/cmsis_nvic.h b/platform/cmsis/inc/cmsis_nvic.h new file mode 100644 index 0000000..b117fcc --- /dev/null +++ b/platform/cmsis/inc/cmsis_nvic.h @@ -0,0 +1,112 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2011 ARM Limited. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of ARM Limited nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*NVIC_DEFAULT_FAULT_HANDLER_T)(void); + +void NVIC_DisableAllIRQs(void); + +void NVIC_InitVectors(void); + +void NVIC_SetDefaultFaultHandler(NVIC_DEFAULT_FAULT_HANDLER_T handler); + +void NVIC_SetDefaultFaultHandler_cp(NVIC_DEFAULT_FAULT_HANDLER_T handler); + +IRQn_Type NVIC_GetCurrentActiveIRQ(void); + +void NVIC_PowerDownSleep(uint32_t *buf, uint32_t cnt); + +void NVIC_PowerDownWakeup(uint32_t *buf, uint32_t cnt); + +#ifdef __ARM_ARCH_ISA_ARM +enum EXCEPTION_ID_T { + EXCEPTION_NONE = -1, + EXCEPTION_UNDEF = -2, + EXCEPTION_SVC = -3, + EXCEPTION_PABT = -4, + EXCEPTION_DABT = -5, + EXCEPTION_HYP = -6, + EXCEPTION_IRQ = -7, + EXCEPTION_FIQ = -8, +}; + +struct FAULT_REGS_T { + uint32_t r[16]; + uint32_t spsr; +}; + +struct UNDEF_FAULT_INFO_T { + enum EXCEPTION_ID_T id; + uint32_t opcode; + uint32_t state; +}; + +struct SVC_FAULT_INFO_T { + enum EXCEPTION_ID_T id; + uint32_t svc_num; +}; + +struct PABT_FAULT_INFO_T { + enum EXCEPTION_ID_T id; + uint32_t IFSR; + uint32_t IFAR; +}; + +struct DABT_FAULT_INFO_T { + enum EXCEPTION_ID_T id; + uint32_t DFSR; + uint32_t DFAR; +}; + +typedef void (*GIC_FAULT_DUMP_HANDLER_T)(const uint32_t *regs, const uint32_t *extra, uint32_t extra_len); + +void GIC_DisableAllIRQs(void); + +void GIC_InitVectors(void); + +void GIC_SetFaultDumpHandler(GIC_FAULT_DUMP_HANDLER_T handler); + +IRQn_Type IRQ_GetCurrentActiveIRQ(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/cmsis_version.h b/platform/cmsis/inc/cmsis_version.h new file mode 100644 index 0000000..660f612 --- /dev/null +++ b/platform/cmsis/inc/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 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 ( 1U) /*!< [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/platform/cmsis/inc/core_armv81mml.h b/platform/cmsis/inc/core_armv81mml.h new file mode 100644 index 0000000..db6d9f2 --- /dev/null +++ b/platform/cmsis/inc/core_armv81mml.h @@ -0,0 +1,2967 @@ +/**************************************************************************//** + * @file core_armv81mml.h + * @brief CMSIS Armv8.1-M Mainline Core Peripheral Access Layer Header File + * @version V1.0.0 + * @date 15. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2018-2019 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_ARMV81MML_H_GENERIC +#define __CORE_ARMV81MML_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_ARMV81MML + @{ + */ + +#include "cmsis_version.h" + +#define __ARM_ARCH_8M_MAIN__ 1 // patching for now +/* CMSIS ARMV81MML definitions */ +#define __ARMv81MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv81MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv81MML_CMSIS_VERSION ((__ARMv81MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv81MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (81U) /*!< 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 + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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_ARMV81MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV81MML_H_DEPENDANT +#define __CORE_ARMV81MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv81MML_REV + #define __ARMv81MML_REV 0x0000U + #warning "__ARMv81MML_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 __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_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 ARMv81MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU 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:7; /*!< bit: 9..15 Reserved */ + 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 (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + 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_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT 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_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-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#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[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __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 SHPR[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 ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status 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_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR 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_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#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_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS 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_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS 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 */ + +/* 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_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS 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_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN 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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#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_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT 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_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT 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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF 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 */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM 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 */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power 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 */ + +/*@} 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[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + 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[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __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 Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< 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_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA 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 Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION 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 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} 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_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS 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 Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#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_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH 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 Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes 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 */ + __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 (0x3UL << 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 (0x3UL << 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_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY 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 (0x3UL << 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 (0x3UL << 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_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< 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_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType 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 Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} 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_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_PXN_Pos 4U /*!< MPU RLAR: PXN Position */ +#define MPU_RLAR_PXN_Msk (0x1UL << MPU_RLAR_PXN_Pos) /*!< MPU RLAR: PXN Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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 */ +} 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_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL 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_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY 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_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context 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 */ + +/*@} 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 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status 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_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST 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 */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN 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 + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * 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 + + + +/** + \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 << 8U) ); /* Insert write key and priorty 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) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((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->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((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; +} + + +/** + \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(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state 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 TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->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 << 8U) ); /* Insert write key and priorty group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \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 TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state 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 TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state 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 TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.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)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else 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 */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## 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 */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, 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 TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#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_ARMV81MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_armv8mbl.h b/platform/cmsis/inc/core_armv8mbl.h new file mode 100644 index 0000000..57d9f66 --- /dev/null +++ b/platform/cmsis/inc/core_armv8mbl.h @@ -0,0 +1,1918 @@ +/**************************************************************************//** + * @file core_armv8mbl.h + * @brief CMSIS Armv8-M Baseline Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 12. November 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. + */ + +#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_ARMV8MBL_H_GENERIC +#define __CORE_ARMV8MBL_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_ARMv8MBL + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M ( 2U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MBL_H_DEPENDANT +#define __CORE_ARMV8MBL_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MBL_REV + #define __ARMv8MBL_REV 0x0000U + #warning "__ARMv8MBL_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 __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #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 + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT 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 ARMv8MBL */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU 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:28; /*!< bit: 0..27 Reserved */ + 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 */ + + +/** + \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:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + 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_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T 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-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#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[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} 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 */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __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 */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State 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_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR 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_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#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 */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* 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 */ +#endif + +/* 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_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS 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 */ + +/* 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_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS 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_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN 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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED 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_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_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \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_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 */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} 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 */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#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_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH 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 Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes 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 */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER 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_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan 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 Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented 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_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth 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 Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* 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_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status 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_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST 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_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 */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA 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_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 */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN 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 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 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 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 + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick 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 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \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) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \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->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (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. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \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) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + 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 = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \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 TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state 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 TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state 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 TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.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) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## 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 */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, 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 TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_armv8mml.h b/platform/cmsis/inc/core_armv8mml.h new file mode 100644 index 0000000..30aab58 --- /dev/null +++ b/platform/cmsis/inc/core_armv8mml.h @@ -0,0 +1,2832 @@ +/**************************************************************************//** + * @file core_armv8mml.h + * @brief CMSIS Armv8-M Mainline Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 12. September 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. + */ + +#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_ARMV8MML_H_GENERIC +#define __CORE_ARMV8MML_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_ARMv8MML + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS Armv8MML definitions */ +#define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (81U) /*!< 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 + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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_ARMV8MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MML_H_DEPENDANT +#define __CORE_ARMV8MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MML_REV + #define __ARMv8MML_REV 0x0000U + #warning "__ARMv8MML_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 __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_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 ARMv8MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU 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:7; /*!< bit: 9..15 Reserved */ + 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 (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + 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_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT 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_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-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#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[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __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 SHPR[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 ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ +} 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_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR 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_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#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_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS 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_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS 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 */ + +/* 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_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS 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_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN 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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#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_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT 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_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT 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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF 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 */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set 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 */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power 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 */ + +/*@} 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[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __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 Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< 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_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA 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 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} 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_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS 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 Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#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_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH 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 Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes 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 */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER 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_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan 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 Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented 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_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth 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 Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} 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_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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 */ +} 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_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL 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_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY 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_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context 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 */ + +/*@} 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 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status 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_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST 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 */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN 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 + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * 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 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \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) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((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->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((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; +} + + +/** + \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(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state 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 TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->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_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \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 TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state 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 TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state 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 TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.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)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else 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 */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## 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 */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, 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 TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#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_ARMV8MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_cm0.h b/platform/cmsis/inc/core_cm0.h new file mode 100644 index 0000000..fcf2757 --- /dev/null +++ b/platform/cmsis/inc/core_cm0.h @@ -0,0 +1,949 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V5.0.6 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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_CM0_H_GENERIC +#define __CORE_CM0_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_M0 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #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_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick 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:28; /*!< bit: 0..27 Reserved */ + 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 */ + + +/** + \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:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + 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_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T 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 _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL 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[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} 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 */ + uint32_t RESERVED0; + __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 */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State 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_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE 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_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 */ + +/* 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_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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \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_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} 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 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 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 */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick 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 not available for Cortex-M0 */ + #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 */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \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) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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[0U] & (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[0U] = (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[0U] & (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[0U] = (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[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \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[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (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. + Address 0 must be mapped to SRAM. + \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 = 0x0U; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \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 = 0x0U; + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \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 = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## 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) +{ + 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 */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_cm0plus.h b/platform/cmsis/inc/core_cm0plus.h new file mode 100644 index 0000000..65ea443 --- /dev/null +++ b/platform/cmsis/inc/core_cm0plus.h @@ -0,0 +1,1082 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 13. March 2019 + ******************************************************************************/ +/* + * 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. + */ + +#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_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_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-M0+ + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV 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 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #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-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU 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:28; /*!< bit: 0..27 Reserved */ + 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 */ + + +/** + \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:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + 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_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T 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 _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#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[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} 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 */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __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 */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State 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_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* 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_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 */ + +/* 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_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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \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 */ + +#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 */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* 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 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << 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 + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} 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 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 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 */ + +#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 + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick 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 not available for Cortex-M0+ */ + #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 */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \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) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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[0U] & (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[0U] = (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[0U] & (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[0U] = (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[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \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[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (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. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t vectors = SCB->VTOR; +#else + uint32_t vectors = 0x0U; +#endif + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \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) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t vectors = SCB->VTOR; +#else + uint32_t vectors = 0x0U; +#endif + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \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 = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __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) +{ + 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 */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_cm1.h b/platform/cmsis/inc/core_cm1.h new file mode 100644 index 0000000..72c515c --- /dev/null +++ b/platform/cmsis/inc/core_cm1.h @@ -0,0 +1,976 @@ +/**************************************************************************//** + * @file core_cm1.h + * @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File + * @version V1.0.1 + * @date 12. November 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. + */ + +#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_CM1_H_GENERIC +#define __CORE_CM1_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_M1 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM1 definitions */ +#define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \ + __CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (1U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM1_H_DEPENDANT +#define __CORE_CM1_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM1_REV + #define __CM1_REV 0x0100U + #warning "__CM1_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #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_M1 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick 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:28; /*!< bit: 0..27 Reserved */ + 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 */ + + +/** + \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:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + 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_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T 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 _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL 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[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} 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 */ + uint32_t RESERVED0; + __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 */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State 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_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE 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_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 */ + +/* 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_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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED 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[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */ + +#define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable 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_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M1 header file. + @{ + */ +/*@} 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 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 */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick 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 not available for Cortex-M1 */ + #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 */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \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) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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[0U] & (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[0U] = (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[0U] & (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[0U] = (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[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \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[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (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. + Address 0 must be mapped to SRAM. + \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 *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \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 *)0x0U; + 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 = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## 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) +{ + 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 */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_cm23.h b/platform/cmsis/inc/core_cm23.h new file mode 100644 index 0000000..26fe163 --- /dev/null +++ b/platform/cmsis/inc/core_cm23.h @@ -0,0 +1,1993 @@ +/**************************************************************************//** + * @file core_cm23.h + * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 12. November 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. + */ + +#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_CM23_H_GENERIC +#define __CORE_CM23_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_M23 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __CM23_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM23_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \ + __CM23_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (23U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM23_H_DEPENDANT +#define __CORE_CM23_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM23_REV + #define __CM23_REV 0x0000U + #warning "__CM23_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 __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #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 + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT 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_M23 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU 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:28; /*!< bit: 0..27 Reserved */ + 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 */ + + +/** + \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:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + 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_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T 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-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#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[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} 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 */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __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 */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State 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_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR 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_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#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 */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* 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 */ +#endif + +/* 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_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS 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 */ + +/* 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_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS 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_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN 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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED 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_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_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \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_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 */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} 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 */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#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_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH 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 */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __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/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} 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_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan 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 Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S 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_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< 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 Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* 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_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status 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_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST 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_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 */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA 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_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 */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN 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 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 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 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 + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick 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 not available for Cortex-M23 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M23 */ + #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 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \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) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \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->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (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. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \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) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + 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 = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \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 TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state 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 TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state 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 TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.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) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## 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 */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, 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 TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_cm3.h b/platform/cmsis/inc/core_cm3.h new file mode 100644 index 0000000..ea54050 --- /dev/null +++ b/platform/cmsis/inc/core_cm3.h @@ -0,0 +1,1934 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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_CM3_H_GENERIC +#define __CORE_CM3_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_M3 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (3U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV 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 __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_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU 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:27; /*!< bit: 0..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 */ + + +/** + \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 _reserved1:8; /*!< bit: 16..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_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 _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#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 */ +#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* 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_SHCSR_MEMFAULTACT_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_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_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 */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1U]; +#endif +} 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 */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) +#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 */ +#endif + +/*@} 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 + + +/** + \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 + +/*@} */ + + + +/******************************************************************************* + * 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 */ + + +/** + \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) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \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 (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \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) +{ + 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_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_cm33.h b/platform/cmsis/inc/core_cm33.h new file mode 100644 index 0000000..fce561c --- /dev/null +++ b/platform/cmsis/inc/core_cm33.h @@ -0,0 +1,2914 @@ +/**************************************************************************//** + * @file core_cm33.h + * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 12. November 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. + */ + +#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_CM33_H_GENERIC +#define __CORE_CM33_H_GENERIC + +#ifndef __ASSEMBLER__ +#include +#endif + +#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_M33 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM33 definitions */ +#define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ + __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (33U) /*!< 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 + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + +#ifndef __ASSEMBLER__ +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM33_H_DEPENDANT +#define __CORE_CM33_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM33_REV + #define __CM33_REV 0x0000U + #warning "__CM33_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 __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_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_M33 */ + + + +#ifndef __ASSEMBLER__ + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU 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:7; /*!< bit: 9..15 Reserved */ + 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 (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + 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_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT 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_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-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#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[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __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 SHPR[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 ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ +} 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_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR 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_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#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_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS 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_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS 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 */ + +/* 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_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS 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_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN 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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#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_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT 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_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT 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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF 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 */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set 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 */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power 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 */ + +/*@} 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[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __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 Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* 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_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA 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 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} 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_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS 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 Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#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_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH 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 */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __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/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} 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_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan 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 Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S 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_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< 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 Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} 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_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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 */ +} 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_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL 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_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY 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_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context 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 */ + +/*@} 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 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status 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_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST 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 */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN 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 + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * 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 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \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) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((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->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((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; +} + + +/** + \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(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state 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 TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->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_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \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 TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state 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 TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state 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 TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.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)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else 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 */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## 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 */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, 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 TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#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 */ + + + +#endif // !__ASSEMBLER__ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_cm35p.h b/platform/cmsis/inc/core_cm35p.h new file mode 100644 index 0000000..c00e54c --- /dev/null +++ b/platform/cmsis/inc/core_cm35p.h @@ -0,0 +1,2907 @@ +/**************************************************************************//** + * @file core_cm35p.h + * @brief CMSIS Cortex-M35P Core Peripheral Access Layer Header File + * @version V1.0.0 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 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. + */ + +#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_CM35P_H_GENERIC +#define __CORE_CM35P_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_M35P + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM35P definitions */ +#define __CM35P_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM35P_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM35P_CMSIS_VERSION ((__CM35P_CMSIS_VERSION_MAIN << 16U) | \ + __CM35P_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (35U) /*!< 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 + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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 + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_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_CM35P_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM35P_H_DEPENDANT +#define __CORE_CM35P_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM35P_REV + #define __CM35P_REV 0x0000U + #warning "__CM35P_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 __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_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_M35P */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU 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:7; /*!< bit: 9..15 Reserved */ + 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 (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + 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_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT 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_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-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#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[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __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 SHPR[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 ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ +} 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_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR 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_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#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_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS 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_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS 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 */ + +/* 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_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS 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_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN 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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#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_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT 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_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT 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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF 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 */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set 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 */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power 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 */ + +/*@} 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[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __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 Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* 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_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA 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 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} 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_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS 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 Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#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_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH 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 */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __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/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} 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_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan 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 Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S 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_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< 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 Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} 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_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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 */ +} 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_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL 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_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY 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_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context 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 */ + +/*@} 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 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status 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_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST 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 */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN 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 + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * 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 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \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) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \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->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((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->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((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; +} + + +/** + \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(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state 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 TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->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_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \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 TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state 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 TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state 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 TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + 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 TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.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)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else 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 */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## 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 */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, 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 TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#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_CM35P_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_cm4.h b/platform/cmsis/inc/core_cm4.h new file mode 100644 index 0000000..a92b642 --- /dev/null +++ b/platform/cmsis/inc/core_cm4.h @@ -0,0 +1,2125 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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 + +#ifndef __ASSEMBLER__ +#include +#endif + +#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 + +#ifndef __ASSEMBLER__ +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ +#endif + +#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 __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 */ + + +#ifndef __ASSEMBLER__ + +/******************************************************************************* + * 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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \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 (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \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 */ + +#endif // !__ASSEMBLER__ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_cm7.h b/platform/cmsis/inc/core_cm7.h new file mode 100644 index 0000000..41f9afb --- /dev/null +++ b/platform/cmsis/inc/core_cm7.h @@ -0,0 +1,2691 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 13. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 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_CM7_H_GENERIC +#define __CORE_CM7_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_M7 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< 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_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_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 __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_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_M7 */ + + + +/******************************************************************************* + * 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 SHPR[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 ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status 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_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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 */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM 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_DISDYNADD_Pos 26U /*!< ACTLR: DISDYNADD Position */ +#define SCnSCB_ACTLR_DISDYNADD_Msk (1UL << SCnSCB_ACTLR_DISDYNADD_Pos) /*!< ACTLR: DISDYNADD Mask */ + +#define SCnSCB_ACTLR_DISISSCH1_Pos 21U /*!< ACTLR: DISISSCH1 Position */ +#define SCnSCB_ACTLR_DISISSCH1_Msk (0x1FUL << SCnSCB_ACTLR_DISISSCH1_Pos) /*!< ACTLR: DISISSCH1 Mask */ + +#define SCnSCB_ACTLR_DISDI_Pos 16U /*!< ACTLR: DISDI Position */ +#define SCnSCB_ACTLR_DISDI_Msk (0x1FUL << SCnSCB_ACTLR_DISDI_Pos) /*!< ACTLR: DISDI Mask */ + +#define SCnSCB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ +#define SCnSCB_ACTLR_DISCRITAXIRUR_Msk (1UL << SCnSCB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ + +#define SCnSCB_ACTLR_DISBTACALLOC_Pos 14U /*!< ACTLR: DISBTACALLOC Position */ +#define SCnSCB_ACTLR_DISBTACALLOC_Msk (1UL << SCnSCB_ACTLR_DISBTACALLOC_Pos) /*!< ACTLR: DISBTACALLOC Mask */ + +#define SCnSCB_ACTLR_DISBTACREAD_Pos 13U /*!< ACTLR: DISBTACREAD Position */ +#define SCnSCB_ACTLR_DISBTACREAD_Msk (1UL << SCnSCB_ACTLR_DISBTACREAD_Pos) /*!< ACTLR: DISBTACREAD Mask */ + +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS 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_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 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} 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) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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->SHPR[(((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->SHPR[(((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; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; +} + + +/** + \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 (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + +/** + \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 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else 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 */ + + + +/* ########################## Cache functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + +#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */ + + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */ + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address. + D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned and invalidated. + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + +/*@} end of CMSIS_Core_CacheFunctions */ + + + +/* ################################## 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_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_sc000.h b/platform/cmsis/inc/core_sc000.h new file mode 100644 index 0000000..389535a --- /dev/null +++ b/platform/cmsis/inc/core_sc000.h @@ -0,0 +1,1022 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V5.0.6 + * @date 12. November 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. + */ + +#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_SC000_H_GENERIC +#define __CORE_SC000_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 SC000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (000U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000U + #warning "__SC000_REV 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 __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #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 SC000 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU 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:28; /*!< bit: 0..27 Reserved */ + 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 */ + + +/** + \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:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + 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_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T 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 _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL 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[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} 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 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features 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_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State 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_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 */ + +/* 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_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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED 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[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#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 */ + +#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 */ +} MPU_Type; + +/* 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 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << 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 + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the SC000 header file. + @{ + */ +/*@} 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 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 */ + +#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 + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick 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 not available for SC000 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for SC000 */ + #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 not available for SC000 */ + #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 */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \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) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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[0U] & (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[0U] = (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[0U] & (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[0U] = (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[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \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[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \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; +} + + +/** + \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 = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## 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) +{ + 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 */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/core_sc300.h b/platform/cmsis/inc/core_sc300.h new file mode 100644 index 0000000..5478ea7 --- /dev/null +++ b/platform/cmsis/inc/core_sc300.h @@ -0,0 +1,1915 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 12. November 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. + */ + +#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_SC300_H_GENERIC +#define __CORE_SC300_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 SC3000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (300U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000U + #warning "__SC300_REV 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 __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 SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU 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:27; /*!< bit: 0..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 */ + + +/** + \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 _reserved1:8; /*!< bit: 16..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_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 _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#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 RSERVED1[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 */ + uint32_t RESERVED1[129U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features 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_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << 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_SHCSR_MEMFAULTACT_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_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_SHCSR_MEMFAULTACT_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_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 */ + uint32_t RESERVED1[1U]; +} 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 */ + +/*@} 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[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + 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 (0xFUL /*<< 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 Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION 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 (0x3UL << 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 (0x3UL << 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 (0x3UL << 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 (0x3UL << 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; + +/* 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 + + +/** + \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 + +/*@} */ + + + +/******************************************************************************* + * 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 */ + + + +/** + \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 << 8U) ); /* Insert write key and priorty 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) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \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; +} + + +/** + \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 */ + + +/* ########################## 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) +{ + 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_SC300_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/cmsis/inc/fpga1000.h b/platform/cmsis/inc/fpga1000.h new file mode 100644 index 0000000..4b56a67 --- /dev/null +++ b/platform/cmsis/inc/fpga1000.h @@ -0,0 +1,175 @@ +/**************************************************************************//** + * @file best1000.h + * @brief CMSIS Core Peripheral Access Layer Header File for + * ARMCM4 Device Series + * @version V2.02 + * @date 10. September 2014 + * + * @note configured for CM4 with FPU + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM 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 __FPGA1000_H__ +#define __FPGA1000_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __ASSEMBLER__ +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ +/* ------------------- Cortex-M4 Processor Exceptions Numbers ------------------- */ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 HardFault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 System Tick Interrupt */ + +/* ---------------------- BEST1000 Specific Interrupt Numbers --------------------- */ + FPU_IRQn = 0, /*!< FPU Interrupt */ + SDIO_IRQn = 1, /*!< SDIO Interrupt */ + SDMMC_IRQn = 2, /*!< SDMMC Interrupt */ + AUDMA_IRQn = 3, /*!< Audio DMA Interrupt */ + GPDMA_IRQn = 4, /*!< General Purpose DMA Interrupt */ + DPDRX_IRQn = 5, /*!< DPD RX Interrupt */ + DPDTX_IRQn = 6, /*!< DPD TX Interrupt */ + USB_IRQn = 7, /*!< USB Interrupt */ + WAKEUP_IRQn = 8, /*!< Reserved Interrupt */ + GPIO_IRQn = 9, /*!< GPIO Interrupt */ + WDT_IRQn = 10, /*!< Watchdog Timer Interrupt */ + RTC_IRQn = 11, /*!< RTC Interrupt */ + TIMER00_IRQn = 12, /*!< Timer00 Interrupt */ + TIMER01_IRQn = 13, /*!< Timer01 Interrupt */ + I2C0_IRQn = 14, /*!< I2C0 Interrupt */ + SPI0_IRQn = 15, /*!< SPI0 Interrupt */ + SPILCD_IRQn = 16, /*!< SPILCD Interrupt */ + UART0_IRQn = 17, /*!< UART0 Interrupt */ + UART1_IRQn = 18, /*!< UART1 Interrupt */ + CODEC_IRQn = 19, /*!< CODEC Interrupt */ + BTPCM_IRQn = 20, /*!< BTPCM Interrupt */ + I2S0_IRQn = 21, /*!< I2S0 Interrupt */ + SPDIF_IRQn = 22, /*!< SPDIF Interrupt */ + ITNSPI_IRQn = 23, /*!< Reserved Interrupt */ + BT_IRQn = 24, /*!< Reserved Interrupt */ + GPADC_IRQn = 25, /*!< Reserved Interrupt */ + NONE4_IRQn = 26, /*!< Reserved Interrupt */ + USB_PIN_IRQn = 27, /*!< Reserved Interrupt */ + ISDONE_IRQn = 28, /*!< Intersys MCU2BT Data Done Interrupt */ + ISDONE1_IRQn = 29, /*!< Intersys MCU2BT Data1 Done Interrupt */ + ISDATA_IRQn = 30, /*!< Intersys BT2MCU Data Indication Interrupt */ + ISDATA1_IRQn = 31, /*!< Intersys BT2MCU Data1 Indication Interrupt */ + CHARGER_IRQn = 32, /*!< Charger IRQ */ + PWRKEY_IRQn = 33, /*!< Power key IRQ */ + + USER_IRQn_QTY, + INVALID_IRQn = USER_IRQn_QTY, +} IRQn_Type; + +#endif + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* -------- Configuration of the Cortex-M4 Processor and Core Peripherals ------- */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 3 /*!< 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 */ +#define __NUM_CODE_PATCH 32 +#define __NUM_LIT_PATCH 32 + +#include "core_cm4.h" /* Processor and core peripherals */ + +#ifndef __ASSEMBLER__ + +#include "system_ARMCM.h" /* System Header */ + +#endif + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------------------- Start of section using anonymous unions ------------------ */ +#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 + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined (__CC_ARM) + #pragma pop +#elif defined (__ICCARM__) + /* leave anonymous unions enabled */ +#elif (defined(__ARMCC_VERSION) && (__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 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/link_sym_armclang.h b/platform/cmsis/inc/link_sym_armclang.h new file mode 100644 index 0000000..b4211dc --- /dev/null +++ b/platform/cmsis/inc/link_sym_armclang.h @@ -0,0 +1,235 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __LINK_SYM_ARMCLANG_H__ +#define __LINK_SYM_ARMCLANG_H__ + +#ifdef __ARMCC_VERSION + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_addr_map.h" + +#ifdef ROM_BUILD + +#define __rom_got_info_start Image$$rom_got_info$$Base +#define __audio_const_rom_start Image$$rom_audio_const$$Base +#define __audio_const_rom_end Image$$rom_audio_const$$Limit +#define __audio_const_rom_size Image$$rom_audio_const$$Length +#define __rom_text0_end Load$$rom_ramx$$Base +#define __rom_ramx_start Image$$rom_ramx$$Base +#define __rom_ramx_end Image$$rom_ramx$$Limit +#define __rom_etext Load$$rom_data$$Base +#define __rom_data_start__ Image$$rom_data$$Base +#define __rom_data_end__ Image$$rom_data$$Limit +#define __rom_bss_start__ Image$$rom_bss$$Base +#define __rom_bss_end__ Image$$rom_bss$$ZI$$Limit +#define __rom_HeapBase Image$$ARM_LIB_HEAP$$Base +#define __rom_HeapLimit Image$$ARM_LIB_HEAP$$ZI$$Limit +#define __rom_StackTop Image$$ARM_LIB_STACK$$ZI$$Limit +#define __rom_stack __rom_StackTop +#define __rom_StackLimit Image$$ARM_LIB_STACK$$Base +#define __cp_ramx_last_dummy_start Image$$cp_ramx_last_dummy$$Base +#define __cp_ram_last_dummy_start Image$$cp_ram_last_dummy$$Base +#define __cp_stack_limit Image$$cp_stack$$Base +#define __cp_stack_top Image$$cp_stack$$ZI$$Limit +#define __export_fn_rom Image$$rom_export_fn$$Base + +#define __boot_sram_start_flash__ __rom_HeapLimit +#define __boot_sram_start__ __rom_HeapLimit +#define __boot_sram_end_flash__ __rom_HeapLimit +#define __boot_bss_sram_start__ __rom_HeapLimit +#define __boot_bss_sram_end__ __rom_HeapLimit +#define __fast_sram_text_data_start_flash__ __rom_HeapLimit +#define __fast_sram_text_data_start__ __rom_HeapLimit +#define __fast_sram_text_data_end__ __rom_HeapLimit +#define __fast_sram_text_data_end_flash__ __rom_HeapLimit +#define __sram_text_data_start_flash__ __rom_HeapLimit +#define __sram_text_data_start__ __rom_HeapLimit +#define __sram_text_data_end_flash__ __rom_HeapLimit +#define __sram_bss_start__ __rom_HeapLimit +#define __sram_bss_end__ __rom_HeapLimit + +#ifndef NOSTD +#define __bss_start__ __rom_bss_start__ +#define __bss_end__ __rom_bss_end__ +#define __end__ __rom_HeapBase +/* +#define end __rom_HeapBase +*/ +#define __StackTop __rom_StackTop +#define __stack __rom_StackTop +#endif + +#elif defined(PROGRAMMER) + +#define __exec_struct_start Image$$exec_struct$$Base +#define __got_info_start Image$$got_info$$Base +#define __cust_cmd_init_tbl_start Image$$cust_cmd_init_tbl$$Base +#define __cust_cmd_init_tbl_end Image$$cust_cmd_init_tbl$$Limit +#define __cust_cmd_hldr_tbl_start Image$$cust_cmd_hdlr_tbl$$Base +#define __cust_cmd_hldr_tbl_end Image$$cust_cmd_hdlr_tbl$$Limit +#define __etext Load$$data$$Base +#define __data_start__ Image$$data$$Base +#define __data_end__ Image$$data$$Limit +#define __bss_start__ Image$$bss$$Base +#define __bss_end__ Image$$bss$$ZI$$Limit +#define __HeapBase Image$$ARM_LIB_HEAP$$Base +#define __end__ __HeapBase +/* +#define end __HeapBase +*/ +#define __HeapLimit Image$$ARM_LIB_HEAP$$ZI$$Limit +#define __StackTop Image$$ARM_LIB_STACK$$ZI$$Limit +#define __stack __StackTop +#define __StackLimit Image$$ARM_LIB_STACK$$Base + +#define __boot_sram_start_flash__ __HeapLimit +#define __boot_sram_start__ __HeapLimit +#define __boot_sram_end_flash__ __HeapLimit +#define __boot_bss_sram_start__ __HeapLimit +#define __boot_bss_sram_end__ __HeapLimit +#define __fast_sram_text_data_start_flash__ __HeapLimit +#define __fast_sram_text_data_start__ __HeapLimit +#define __fast_sram_text_data_end__ __HeapLimit +#define __fast_sram_text_data_end_flash__ __HeapLimit +#define __sram_text_data_start_flash__ __HeapLimit +#define __sram_text_data_start__ __HeapLimit +#define __sram_text_data_end_flash__ __HeapLimit +#define __sram_bss_start__ __HeapLimit +#define __sram_bss_end__ __HeapLimit +#define __cp_stack_limit __HeapLimit +#define __cp_stack_top __HeapLimit + +#else + +#define Boot_Loader __main +#define __flash_start Image$$boot_struct$$Base +#define __userdata_pool_end__ Image$$userdata_pool$$Base +#define __boot_sram_start_flash__ Load$$boot_text_sram$$Base +#define __boot_sram_start__ Image$$boot_text_sram$$Base +#define __boot_sram_end_flash__ Load$$boot_data_sram$$Limit +/* + * CAUTION: + * If the section name of BSS variables has no ".bss." prefix, they will be considered as DATA, not BSS (ZI) ! + */ +#define __boot_bss_sram_start__ Image$$boot_bss_sram$$Base +#define __boot_bss_sram_end__ Image$$boot_bss_sram$$ZI$$Limit +#define __fast_sram_text_data_start_flash__ Load$$fast_text_sram$$Base +#define __fast_sram_text_data_start__ Image$$fast_text_sram$$Base +#define __fast_sram_text_data_end__ Image$$fast_text_sram$$Limit +#define __fast_sram_text_data_end_flash__ Load$$fast_text_sram$$Limit + +#define __cp_text_sram_start_flash__ Load$$cp_text_sram$$Base +#define __cp_text_sram_exec_start__ Image$$cp_text_sram$$Base +#define __cp_text_sram_exec_end__ Image$$cp_text_sram$$Limit +#define __cp_text_sram_start Image$$cp_text_sram_start$$Base +#define __cp_text_sram_end Image$$cp_text_sram_start$$Limit +#define __cp_data_sram_start_flash__ Load$$cp_data_sram$$Base +#define __cp_data_sram_start Image$$cp_data_sram$$Base +#define __cp_data_sram_end Image$$cp_data_sram$$Limit +#define __cp_sram_end_flash__ Load$$cp_data_sram$$Limit +#define __cp_bss_sram_start Image$$cp_bss_sram$$Base +#define __cp_bss_sram_end Image$$cp_bss_sram$$ZI$$Limit +#define __cp_stack_limit Image$$cp_stack$$Base +#define __cp_stack_top Image$$cp_stack$$ZI$$Limit + +#define __overlay_text_start__ Image$$overlay_start$$Base +#define __overlay_text_exec_start__ Image$$overlay_text0$$Base + +#define __load_start_overlay_text0 Load$$overlay_text0$$Base +#define __load_stop_overlay_text0 Load$$overlay_text0$$Limit +#define __load_start_overlay_text1 Load$$overlay_text1$$Base +#define __load_stop_overlay_text1 Load$$overlay_text1$$Limit +#define __load_start_overlay_text2 Load$$overlay_text2$$Base +#define __load_stop_overlay_text2 Load$$overlay_text2$$Limit +#define __load_start_overlay_text3 Load$$overlay_text3$$Base +#define __load_stop_overlay_text3 Load$$overlay_text3$$Limit +#define __load_start_overlay_text4 Load$$overlay_text4$$Base +#define __load_stop_overlay_text4 Load$$overlay_text4$$Limit +#define __load_start_overlay_text5 Load$$overlay_text5$$Base +#define __load_stop_overlay_text5 Load$$overlay_text5$$Limit +#define __load_start_overlay_text6 Load$$overlay_text6$$Base +#define __load_stop_overlay_text6 Load$$overlay_text6$$Limit +#define __load_start_overlay_text7 Load$$overlay_text7$$Base +#define __load_stop_overlay_text7 Load$$overlay_text7$$Limit + +#define __overlay_text_exec_end__ Image$$overlay_text_end$$Base +#define __overlay_data_start__ Image$$overlay_data0$$Base + +#define __load_start_overlay_data0 Load$$overlay_data0$$Base +#define __load_stop_overlay_data0 Load$$overlay_data0$$Limit +#define __load_start_overlay_data1 Load$$overlay_data1$$Base +#define __load_stop_overlay_data1 Load$$overlay_data1$$Limit +#define __load_start_overlay_data2 Load$$overlay_data2$$Base +#define __load_stop_overlay_data2 Load$$overlay_data2$$Limit +#define __load_start_overlay_data3 Load$$overlay_data3$$Base +#define __load_stop_overlay_data3 Load$$overlay_data3$$Limit +#define __load_start_overlay_data4 Load$$overlay_data4$$Base +#define __load_stop_overlay_data4 Load$$overlay_data4$$Limit +#define __load_start_overlay_data5 Load$$overlay_data5$$Base +#define __load_stop_overlay_data5 Load$$overlay_data5$$Limit +#define __load_start_overlay_data6 Load$$overlay_data6$$Base +#define __load_stop_overlay_data6 Load$$overlay_data6$$Limit +#define __load_start_overlay_data7 Load$$overlay_data7$$Base +#define __load_stop_overlay_data7 Load$$overlay_data7$$Limit + +#define __sram_text_data_start_flash__ Load$$sram_text$$Base +#define __sram_text_data_start__ Image$$sram_text$$Base +#define __sram_text_data_end_flash__ Load$$sram_data$$Limit +#define __sram_bss_start__ Image$$sram_bss$$Base +#define __sram_bss_end__ Image$$sram_bss$$ZI$$Limit +#define __etext Load$$data$$Base +#define __data_start__ Image$$data$$Base +#define __data_end__ Image$$data$$Limit +#define __bss_start__ Image$$bss$$Base +#define __bss_end__ Image$$bss$$ZI$$Limit +#define __HeapBase Image$$ARM_LIB_HEAP$$Base +#define __end__ __HeapBase +/* +#define end __HeapBase +*/ +#define __HeapLimit Image$$ARM_LIB_HEAP$$ZI$$Limit +#define __StackTop Image$$ARM_LIB_STACK$$ZI$$Limit +#define __stack __StackTop +#define __StackLimit Image$$ARM_LIB_STACK$$Base +#define __flash_end Image$$code_start_addr$$Limit +#define __custom_parameter_start Image$$custom_parameter$$Base +#define __custom_parameter_end Image$$custom_parameter$$ZI$$Limit +#define __lhdc_license_start Image$$lhdc_license$$Base +#define __lhdc_license_end Image$$lhdc_license$$ZI$$Limit +#define __userdata_start Image$$userdata$$Base +#define __userdata_end Image$$userdata$$ZI$$Limit +#define __aud_start Image$$audio$$Base +#define __aud_end Image$$audio$$ZI$$Limit +#define __reserved_start Image$$reserved$$Base +#define __reserved_end Image$$reserved$$ZI$$Limit +#define __hotword_model_start Image$$hotword_model$$Base +#define __hotword_model_end Image$$hotword_model$$ZI$$Limit +#define __factory_start Image$$factory$$Base +#define __factory_end Image$$factory$$ZI$$Limit + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + diff --git a/platform/cmsis/inc/main_entry.h b/platform/cmsis/inc/main_entry.h new file mode 100644 index 0000000..4306168 --- /dev/null +++ b/platform/cmsis/inc/main_entry.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __MAIN_ENTRY_H__ +#define __MAIN_ENTRY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NOSTD +#define MAIN_ENTRY(...) _start(__VA_ARGS__) +#else +#define MAIN_ENTRY(...) main(__VA_ARGS__) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/mpu.h b/platform/cmsis/inc/mpu.h new file mode 100644 index 0000000..1ec2d88 --- /dev/null +++ b/platform/cmsis/inc/mpu.h @@ -0,0 +1,111 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __MPU_H__ +#define __MPU_H__ + +#include "plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum MPU_ID_T { + MPU_ID_NULL_POINTER = 0, + MPU_ID_1, + MPU_ID_2, + MPU_ID_3, + MPU_ID_4, + MPU_ID_5, + MPU_ID_6, + MPU_ID_7, + + MPU_ID_QTY, +}; + +/*mcu sections */ +#define MPU_ID_USER_DATA_SECTION MPU_ID_1 +#define MPU_ID_FRAM_TEXT1 MPU_ID_2 +#define MPU_ID_FRAM_TEXT2 MPU_ID_3 +#define MPU_ID_CODE MPU_ID_4 +#define MPU_ID_SRAM_TEXT MPU_ID_5 + +/*cp sections */ +#define MPU_ID_CP_FLASHX MPU_ID_2 +#define MPU_ID_CP_FLASH MPU_ID_3 +#define MPU_ID_CP_FLASH_NC MPU_ID_4 + +enum MPU_ATTR_T { + MPU_ATTR_READ_WRITE_EXEC = 0, + MPU_ATTR_READ_EXEC, + MPU_ATTR_EXEC, + MPU_ATTR_READ_WRITE, + MPU_ATTR_READ, + MPU_ATTR_NO_ACCESS, + + MPU_ATTR_QTY, +}; + +#if defined(__ARM_ARCH_8M_MAIN__) + +enum MAIR_ATTR_TYPE_T { + MAIR_ATTR_FLASH, + MAIR_ATTR_INT_SRAM, + MAIR_ATTR_EXT_SRAM, + MAIR_ATTR_DEVICE, + MAIR_ATTR_4, + MAIR_ATTR_5, + MAIR_ATTR_6, + MAIR_ATTR_7, + + MAIR_ATTR_QTY, +}; +#endif + +typedef struct +{ + uint32_t addr; + uint32_t len; + enum MPU_ATTR_T ap_attr; +#if defined(__ARM_ARCH_8M_MAIN__) + enum MAIR_ATTR_TYPE_T mem_attr; +#endif +} mpu_regions_t; + +int mpu_open(void); + +int mpu_close(void); + +// VALID LENGTH: 32, 64, 128, 256, 512, 1K, 2K, ..., 4G +// ADDR must be aligned to len +// Note, srd_bits, mpu subregion bits, which can be divided to 8 sub regions +// per region, if don't need, always set the arguments to 0; +int mpu_set(enum MPU_ID_T id, uint32_t addr, uint32_t len, int srd_bits, + enum MPU_ATTR_T attr); + +int mpu_clear(enum MPU_ID_T id); + +/*mpu setup for mcu */ +int mpu_setup(void); + +/*mpu setup for cp mcu */ +int mpu_setup_cp(const mpu_regions_t *mpu_table, uint32_t region_num); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/cmsis/inc/mpu_armv7.h b/platform/cmsis/inc/mpu_armv7.h new file mode 100644 index 0000000..f2b83e0 --- /dev/null +++ b/platform/cmsis/inc/mpu_armv7.h @@ -0,0 +1,289 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.0 + * @date 08. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2017-2019 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) & 2U), ((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) +{ + 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; +} + +/** 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 rsar Value for RSAR 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 rsar Value for RSAR 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; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetSubRegion(uint32_t rnr, uint32_t subRegion) +{ + uint32_t rasr; + + MPU->RNR = rnr; + rasr = MPU->RASR; + rasr &= ~MPU_RASR_SRD_Msk; + rasr |= (subRegion << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk; + + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \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/platform/cmsis/inc/mpu_armv8.h b/platform/cmsis/inc/mpu_armv8.h new file mode 100644 index 0000000..1b905bd --- /dev/null +++ b/platform/cmsis/inc/mpu_armv8.h @@ -0,0 +1,346 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU + * @version V5.1.0 + * @date 08. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2017-2019 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_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \oaram XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + ((BASE & MPU_RBAR_BASE_Msk) | \ + ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#if defined(MPU_RLAR_PXN_Pos) + +/** \brief Region Limit Address Register with PXN value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((PXN << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#endif + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} 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) +{ + 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; +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + //SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + //SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { + return; // invalid index + } + + mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + mpu->RNR = rnr; + mpu->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + mpu->RNR = rnr; + mpu->RBAR = rbar; + mpu->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \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 to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + table += c; + cnt -= c; + rnrOffset = 0U; + rnrBase += MPU_TYPE_RALIASES; + mpu->RNR = rnrBase; + } + + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif + diff --git a/platform/cmsis/inc/patch.h b/platform/cmsis/inc/patch.h new file mode 100644 index 0000000..8533428 --- /dev/null +++ b/platform/cmsis/inc/patch.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __PATCH_H__ +#define __PATCH_H__ + +#include "plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum PATCH_TYPE_T { + PATCH_TYPE_CODE, + PATCH_TYPE_DATA, + PATCH_TYPE_FUNC, + + PATCH_TYPE_QTY +}; + +typedef int PATCH_ID; + +int patch_open(uint32_t remap_addr); + +PATCH_ID patch_enable(enum PATCH_TYPE_T type, uint32_t addr, uint32_t data); + +int patch_disable(PATCH_ID patch_id); + +void patch_close(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/system_ARMCM.h b/platform/cmsis/inc/system_ARMCM.h new file mode 100644 index 0000000..5a987f1 --- /dev/null +++ b/platform/cmsis/inc/system_ARMCM.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SYSTEM_ARMCM_H__ +#define __SYSTEM_ARMCM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdbool.h" + +void SystemInit (void); + +#ifdef UNALIGNED_ACCESS + +__STATIC_FORCEINLINE bool get_unaligned_access_status(void) { return true; } + +__STATIC_FORCEINLINE bool config_unaligned_access(bool enable) { return true; } + +#else + +bool get_unaligned_access_status(void); + +bool config_unaligned_access(bool enable); + +#endif + +uint32_t get_cpu_id(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/cmsis/inc/system_cp.h b/platform/cmsis/inc/system_cp.h new file mode 100644 index 0000000..aaa5692 --- /dev/null +++ b/platform/cmsis/inc/system_cp.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SYSTEM_CP_H__ +#define __SYSTEM_CP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" + +void system_cp_reset_handler(void); + +void system_cp_init(int load_code); + +void system_cp_term(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/cmsis/inc/tz_context.h b/platform/cmsis/inc/tz_context.h new file mode 100644 index 0000000..0d09749 --- /dev/null +++ b/platform/cmsis/inc/tz_context.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * @file tz_context.h + * @brief Context Management for Armv8-M TrustZone + * @version V1.0.1 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-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. + */ + +#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 TZ_CONTEXT_H +#define TZ_CONTEXT_H + +#include + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + +/// \details TZ Memory ID identifies an allocated memory slot. +typedef uint32_t TZ_MemoryId_t; + +/// Initialize secure context memory system +/// \return execution status (1: success, 0: error) +uint32_t TZ_InitContextSystem_S (void); + +/// Allocate context memory for calling secure software modules in TrustZone +/// \param[in] module identifies software modules called from non-secure mode +/// \return value != 0 id TrustZone memory slot identifier +/// \return value 0 no memory available or internal error +TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); + +/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); + +/// Load secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); + +/// Store secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); + +#endif // TZ_CONTEXT_H diff --git a/platform/cmsis/mpu_armv7m.c b/platform/cmsis/mpu_armv7m.c new file mode 100644 index 0000000..8c72883 --- /dev/null +++ b/platform/cmsis/mpu_armv7m.c @@ -0,0 +1,369 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ARM_ARCH_ISA_ARM + +#include "mpu.h" +#include "cmsis.h" +#include "hal_trace.h" + +int mpu_open(void) +{ + int i; + + if ((MPU->TYPE & MPU_TYPE_DREGION_Msk) == 0) { + return 1; + } + + ARM_MPU_Disable(); + + for (i = 0; i < MPU_ID_QTY; i++) { + ARM_MPU_ClrRegion(i); + } + + ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk); + + return 0; +} + +int mpu_close(void) +{ + ARM_MPU_Disable(); + + return 0; +} + +static int mpu_set_armv7(enum MPU_ID_T id, uint32_t addr, uint32_t len, + int srd_bits, enum MPU_ATTR_T attr) +{ + int ret; + uint32_t rbar; + uint32_t rasr; + uint8_t xn; + uint8_t ap; + uint8_t size; + + if ((MPU->CTRL & MPU_CTRL_ENABLE_Msk) == 0) { + ret = mpu_open(); + if (ret) { + return ret; + } + } + + if (id >= MPU_ID_QTY) { + return 2; + } + if (len < 32 || (len & (len - 1))) { + return 3; + } + if (addr & (len - 1)) { + return 4; + } + if (attr >= MPU_ATTR_QTY) { + return 5; + } + + if (attr == MPU_ATTR_READ_WRITE_EXEC || attr == MPU_ATTR_READ_EXEC || + attr == MPU_ATTR_EXEC) { + xn = 0; + } else { + xn = 1; + } + + ap = ARM_MPU_AP_NONE; + if (attr == MPU_ATTR_READ_WRITE_EXEC || attr == MPU_ATTR_READ_WRITE) { + ap = ARM_MPU_AP_FULL; + } else if (attr == MPU_ATTR_READ_EXEC || attr == MPU_ATTR_READ) { + ap = ARM_MPU_AP_RO; + } + + size = __CLZ(__RBIT(len)) - 1; + + ARM_MPU_Disable(); + rbar = ARM_MPU_RBAR(id, addr); + // Type Extention: 0 + // Shareable: 1 + // Cacheable: 1 + // Bufferable: 1 + // Subregion: 0 + rasr = ARM_MPU_RASR(xn, ap, 0, 1, 1, 1, srd_bits, size); + + ARM_MPU_SetRegion(rbar, rasr); + ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk); + __DSB(); + __ISB(); + + return 0; +} + +/* + * sub region is 8 bits, and if one bits is 1, the sub resion will be + * disabled + * like 0b00011111, the top 3 sub region will be disabled + * if it is 0b11110000, the bottom 4 sub region will be disabled. + */ +static int mpu_get_top_srd(uint32_t rg_end, uint32_t fr_end, + uint32_t sub_rg_sz) +{ + int dis_nums; + uint8_t srd_bits; + + dis_nums = (rg_end - fr_end) / sub_rg_sz; + if ((fr_end & (sub_rg_sz - 1)) != 0) + dis_nums += 1; + + srd_bits = 0xff; + srd_bits &= ~((1UL << (8 - dis_nums)) - 1); + + return srd_bits; +} + +static int mpu_get_bottom_srd(uint32_t rg_start, uint32_t fr_start, + uint32_t sub_rg_sz) +{ + int dis_nums; + uint8_t srd_bits; + + dis_nums = (fr_start - rg_start) / sub_rg_sz; + srd_bits = 0xff; + srd_bits &= ((1UL << dis_nums) - 1); + + return srd_bits; +} + +static int calc_sub_region_size(uint32_t fr_start) +{ + int lsb_bit; + uint32_t sz; + + //sub region size aligned to fram start + lsb_bit = get_lsb_pos(fr_start); + sz = 1 << lsb_bit; + if (sz < 0x80) { + /*cortex-m4 doesn't support sub region size less than 128 */ + TRACE(1,"no mpu region for fram start %x", fr_start); + return -1; + } + if (sz > 0x4000) + sz = 0x4000; + + + return sz; +} + +/* +Allocate two mpu sections to protect the fast ram. The cortext M4 +mpu has a lot of restrict, such as one region's start address must +be aligned to the size of region, and the sub region number is fixed +to 8. +The layout like: + ------------------ + | sub region 8 | + ------------------ + | sub region 7 | + | ..... | + | | + ------------------>fast_ram_end + |////////////////| + |////////////////| + |////////////////| + |////////////////| + ------------------>mpu region2 + |//sub region 8//| + |////////////////| + |////////////////| + |////////////////| + ------------------>fast_ram_start aligned to sub region size + | ..... | + | | + |sub region 1 | + ------------------ + |sub region 0 | + ------------------>mpu region1 + +If the __fast_sram_text_exec_end__ exceed the region2's end, just leave +the rest unprotect. +*/ +static int mpu_fram_protect_armv7(uint32_t fr_start, uint32_t fr_end) +{ + uint32_t fr_sz; + uint32_t sub_rg_sz; + uint32_t rg_sz; + uint32_t rg_start; + uint32_t rg_end; + int ret = 0; + int srd_bits; + int finished = 0; + + fr_sz = fr_end - fr_start; + sub_rg_sz = calc_sub_region_size(fr_start); + if (sub_rg_sz < 0) + return -1; + + /* according to cortex-m4 spec, the region is divived to 8 sub region*/ + rg_sz = sub_rg_sz * 8; + /*now we just protect two region */ + if (fr_sz > (rg_sz * 2)) { + TRACE(0,"Warning fram is too big, mpu can not protect so much"); + TRACE(2,"region_sz %x, fram size %x", rg_sz, fr_sz); + } + + /*aliged the region start to region size according to cortext m4 spec*/ + srd_bits = 0; + rg_start = fr_start & ~(rg_sz - 1); + if (fr_start > rg_start) { + int b_srd_bits = 0; + + b_srd_bits = mpu_get_bottom_srd(rg_start, fr_start, sub_rg_sz); + srd_bits |= b_srd_bits; + } + + rg_end = rg_start + rg_sz; + if (fr_end < rg_end) { + int t_srd_bits = 0; + + t_srd_bits = mpu_get_top_srd(rg_end, fr_end, sub_rg_sz); + srd_bits |= t_srd_bits; + finished = 1; + } + + ret = mpu_set(MPU_ID_FRAM_TEXT1, rg_start, rg_sz, srd_bits, MPU_ATTR_READ); + if (ret || finished) + goto out; + + /* need another section, and start from next region*/ + rg_start += rg_sz; + + srd_bits = 0; + rg_end = rg_start + rg_sz; + if (fr_end < rg_end) { + srd_bits = mpu_get_top_srd(rg_end, fr_end, sub_rg_sz); + } + + ret = mpu_set(MPU_ID_FRAM_TEXT2, rg_start, rg_sz, srd_bits, MPU_ATTR_READ_EXEC); + /* if fr_end large than two section, just pass */ +out: + return ret; +} + +int mpu_set(enum MPU_ID_T id, uint32_t addr, uint32_t len, int srd_bits, + enum MPU_ATTR_T attr) +{ + return mpu_set_armv7(id, addr, len, srd_bits, attr); +} + +int mpu_clear(enum MPU_ID_T id) +{ + uint32_t lock; + + if (id >= MPU_ID_QTY) { + return 2; + } + + lock = int_lock(); + + ARM_MPU_ClrRegion(id); + __DSB(); + __ISB(); + + int_unlock(lock); + + return 0; +} + +static int mpu_null_check_enable(void) +{ +#ifdef CHIP_BEST1000 + uint32_t len = 0x400; +#else + uint32_t len = 0x800; +#endif + + return mpu_set(MPU_ID_NULL_POINTER, 0, len, 0, MPU_ATTR_NO_ACCESS); +} + +extern uint32_t __fast_sram_text_exec_start__[]; +extern uint32_t __fast_sram_text_exec_end__[]; + +static int mpu_fast_ram_protect(void) +{ + uint32_t ramx_start = (uint32_t)__fast_sram_text_exec_start__; + uint32_t ramx_end = (uint32_t)__fast_sram_text_exec_end__; + uint32_t ram_start = RAMX_TO_RAM(ramx_start); + uint32_t ram_end = RAMX_TO_RAM(ramx_end); + + return mpu_fram_protect_armv7(ram_start, ram_end); +} + +#if 0 +int mpu_fram_test(void) +{ + uint32_t ramx_start = (uint32_t)__fast_sram_text_exec_start__; + uint32_t ram_start = RAMX_TO_RAM(ramx_start); + uint32_t test_start = ram_start - 1024; + + for (int i = 0; i < 1024; i++) { + TRACE(1,"test_start %x", test_start); + *(volatile uint32_t *)test_start = 0x1; + test_start += 128; + } + + uint32_t ramx_end = (uint32_t)__fast_sram_text_exec_end__; + uint32_t ram_end = RAMX_TO_RAM(ramx_end); + uint32_t test_end = ram_end + 1024; + for (int i = 0; i < 1024; i++) { + TRACE(1,"test_end %x", test_end); + *(volatile uint32_t *)test_end = 0x1; + test_end -= 128; + } + + return 0; +} +#endif + +int mpu_setup(void) +{ + mpu_null_check_enable(); + mpu_fast_ram_protect(); + + return 0; +} + +int mpu_setup_cp(const mpu_regions_t *mpu_table, uint32_t region_num) +{ + int ret; + int i; + + ret = mpu_open(); + if (ret) { + return ret; + } + + if (region_num > MPU_ID_QTY) { + return -1; + } + + for (i = 0; i < region_num; i++) { + const mpu_regions_t *region; + region = &mpu_table[i]; + ret = mpu_set(i, region->addr, region->len, 0, region->ap_attr); + if (ret) + break; + } + + return ret; +} + +#endif diff --git a/platform/cmsis/mpu_armv8m.c b/platform/cmsis/mpu_armv8m.c new file mode 100644 index 0000000..1334b61 --- /dev/null +++ b/platform/cmsis/mpu_armv8m.c @@ -0,0 +1,281 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ARM_ARCH_ISA_ARM + +#include "mpu.h" +#include "cmsis.h" +#include "hal_trace.h" + +#define NORM_MEM_WT_RA_ATTR ARM_MPU_ATTR_MEMORY_(1, 0, 1, 0) +#define NORM_MEM_WB_WA_ATTR ARM_MPU_ATTR_MEMORY_(1, 1, 1, 1) +#define DEV_MEM_ATTR_OUTER ARM_MPU_ATTR_MEMORY_(0, 0, 0, 0) + +static void init_mair_attr(void) +{ + ARM_MPU_SetMemAttr(MAIR_ATTR_FLASH, ARM_MPU_ATTR(NORM_MEM_WT_RA_ATTR, NORM_MEM_WT_RA_ATTR)); + ARM_MPU_SetMemAttr(MAIR_ATTR_INT_SRAM, ARM_MPU_ATTR(NORM_MEM_WT_RA_ATTR, NORM_MEM_WT_RA_ATTR)); + ARM_MPU_SetMemAttr(MAIR_ATTR_EXT_SRAM, ARM_MPU_ATTR(NORM_MEM_WB_WA_ATTR, NORM_MEM_WB_WA_ATTR)); + ARM_MPU_SetMemAttr(MAIR_ATTR_DEVICE, ARM_MPU_ATTR(DEV_MEM_ATTR_OUTER, ARM_MPU_ATTR_DEVICE_nGnRnE)); +} + +static int mpu_enable(void) +{ + int flags = 0; + + if (get_cpu_id()) { + /* + * if cpu is CP, we will use different mpu maps, that is, every map needed by CP will + * be mapped, and the memory is not mapped will issue abort when access + */ + flags = MPU_CTRL_HFNMIENA_Msk; + } else { + /* + * mpu maps use default map designed by arm, that is, if the memory is not mapped, + * the mpu attibutes will use the default setting by ARM. + */ + flags = MPU_CTRL_PRIVDEFENA_Msk; + } + ARM_MPU_Enable(flags); + __DSB(); + __ISB(); + return 0; +} + +static int mpu_disable(void) +{ + __DMB(); + ARM_MPU_Disable(); + return 0; +} + +int mpu_open(void) +{ + int i; + + if ((MPU->TYPE & MPU_TYPE_DREGION_Msk) == 0) { + return 1; + } + + for (i = 0; i < MPU_ID_QTY; i++) { + ARM_MPU_ClrRegion(i); + } + + init_mair_attr(); + + return 0; +} + +int mpu_close(void) +{ + ARM_MPU_Disable(); + + return 0; +} + +static int mpu_set_armv8(enum MPU_ID_T id, uint32_t addr, uint32_t len, + enum MPU_ATTR_T ap_attr, enum MAIR_ATTR_TYPE_T mem_attr) +{ + uint32_t rbar; + uint32_t rlar; + uint8_t xn; + uint8_t ro; + uint32_t lock; + + if (id >= MPU_ID_QTY) { + return 2; + } + if (len < 32) { + return 3; + } + if (addr & 0x1F) { + return 4; + } + if (ap_attr >= MPU_ATTR_QTY) { + return 5; + } + + if (ap_attr == MPU_ATTR_READ_WRITE_EXEC || ap_attr == MPU_ATTR_READ_EXEC || + ap_attr == MPU_ATTR_EXEC) { + xn = 0; + } else { + xn = 1; + } + + if (ap_attr == MPU_ATTR_READ_WRITE_EXEC || ap_attr == MPU_ATTR_READ_WRITE) { + ro = 0; + } else if (ap_attr == MPU_ATTR_READ_EXEC || ap_attr == MPU_ATTR_READ || ap_attr == MPU_ATTR_EXEC) { + ro = 1; + } else { + // Cannot support no access + return 6; + } + + // Sharebility: Outer Shareable + // Non-privilege Access: Enabled + rbar = ARM_MPU_RBAR(addr, 2, ro, 1, xn); + /* rlar = ARM_MPU_RLAR((addr + len - 1), MAIR_ATTR_INT_SRAM); */ + rlar = ARM_MPU_RLAR((addr + len - 1), mem_attr); + + lock = int_lock(); + + ARM_MPU_SetRegion(id, rbar, rlar); + int_unlock(lock); + + return 0; +} + +static inline int mpu_fram_protect_armv8(uint32_t fr_start, uint32_t fr_end) +{ + uint32_t len = fr_end - fr_start; + int ret; + + if ((fr_start % 32 != 0) || (len % 32 != 0)) + ASSERT(0, "fr_start %x and len %d must be aligned to 32", fr_start, len); + + mpu_disable(); + ret = mpu_set_armv8(MPU_ID_FRAM_TEXT1, fr_start, len, MPU_ATTR_EXEC, MAIR_ATTR_INT_SRAM); + mpu_enable(); + + return ret; +} + +static int mpu_code_region_protect(void) +{ + uint32_t code_start = RAMX_BASE; + uint32_t len = RAM_SIZE; + + return mpu_set(MPU_ID_CODE, code_start, len, 0, MPU_ATTR_EXEC); +} + +extern uint32_t __sram_text_data_start__[]; +extern uint32_t __sram_text_end__[]; +static int mpu_sram_text_protect(void) +{ + int ret; + uint32_t start = (uint32_t)__sram_text_data_start__; + uint32_t end = RAMX_TO_RAM((uint32_t)__sram_text_end__); + uint32_t len = end - start; + + TRACE(1,"sram start %x size %x", start, len); + if ((start % 32 != 0) || (len % 32 != 0)) + ASSERT(0, "sram start %x and len %d must be aligned to 32", start, len); + + ret = mpu_set(MPU_ID_SRAM_TEXT, start, len, 0, MPU_ATTR_READ_EXEC); + return ret; +} + + +int mpu_set(enum MPU_ID_T id, uint32_t addr, uint32_t len, int srd_bits, + enum MPU_ATTR_T attr) +{ + int ret = -1; + uint32_t lock; + + lock = int_lock(); + + mpu_disable(); + ret = mpu_set_armv8(id, addr, len, attr, MAIR_ATTR_INT_SRAM); + mpu_enable(); + + int_unlock(lock); + + return ret; +} + +int mpu_clear(enum MPU_ID_T id) +{ + uint32_t lock; + + if (id >= MPU_ID_QTY) { + return 2; + } + + lock = int_lock(); + + mpu_disable(); + ARM_MPU_ClrRegion(id); + __DSB(); + __ISB(); + mpu_enable(); + + int_unlock(lock); + + return 0; +} + +static int mpu_null_check_enable(void) +{ + return mpu_set(MPU_ID_NULL_POINTER, 0, 0x800, 0, MPU_ATTR_EXEC); +} + +extern uint32_t __fast_sram_text_exec_start__[]; +extern uint32_t __fast_sram_text_exec_end__[]; + +static int mpu_fast_ram_protect(void) +{ + uint32_t ramx_start = (uint32_t)__fast_sram_text_exec_start__; + uint32_t ramx_end = (uint32_t)__fast_sram_text_exec_end__; + uint32_t ram_start = RAMX_TO_RAM(ramx_start); + uint32_t ram_end = RAMX_TO_RAM(ramx_end); + int ret = -1; + + ret = mpu_fram_protect_armv8(ram_start, ram_end); + return ret; +} + +int mpu_setup(void) +{ + mpu_null_check_enable(); + + mpu_code_region_protect(); + mpu_sram_text_protect(); + + mpu_fast_ram_protect(); + return 0; +} + +int mpu_setup_cp(const mpu_regions_t *mpu_table, uint32_t region_num) +{ + int ret; + int i; + uint32_t lock; + + ret = mpu_open(); + if (ret) { + return ret; + } + + if (region_num > MPU_ID_QTY) { + return -1; + } + + lock = int_lock(); + mpu_disable(); + for (i = 0; i < region_num; i++) { + const mpu_regions_t *region; + region = &mpu_table[i]; + ret = mpu_set_armv8(i, region->addr, region->len, region->ap_attr, region->mem_attr); + if (ret) + break; + } + + mpu_enable(); + int_unlock(lock); + + return ret; +} + +#endif diff --git a/platform/cmsis/patch.c b/platform/cmsis/patch.c new file mode 100644 index 0000000..ce95cae --- /dev/null +++ b/platform/cmsis/patch.c @@ -0,0 +1,216 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef __ARM_ARCH_8M_MAIN__ +#include "patch.h" +#include "reg_patch.h" + +#ifdef PATCH_CTRL_BASE + +static struct PATCH_CTRL_T * const patch_ctrl = (struct PATCH_CTRL_T *)PATCH_CTRL_BASE; +static struct PATCH_DATA_T * const patch_data = (struct PATCH_DATA_T *)PATCH_DATA_BASE; + +static uint32_t patch_map[(PATCH_ENTRY_NUM + 31) / 32]; + +int patch_open(uint32_t remap_addr) +{ + patch_ctrl->CTRL[0] |= PATCH_CTRL_GLOBAL_EN; + return 0; +} + +int patch_code_enable_id(uint32_t id, uint32_t addr, uint32_t data) +{ + if (id >= PATCH_ENTRY_NUM) { + return 1; + } + + patch_data->DATA[id] = data; + patch_ctrl->CTRL[id] = (patch_ctrl->CTRL[id] & ~PATCH_CTRL_ADDR_MASK) | PATCH_CTRL_ADDR(addr) | PATCH_CTRL_ENTRY_EN; + return 0; +} + +int patch_code_disable_id(uint32_t id) +{ + if (id >= PATCH_ENTRY_NUM) { + return 1; + } + + patch_ctrl->CTRL[id] &= ~PATCH_CTRL_ENTRY_EN; + return 0; +} + +int patch_data_enable_id(uint32_t id, uint32_t addr, uint32_t data) +{ + return patch_code_enable_id(id, addr, data); +} + +int patch_data_disable_id(uint32_t id) +{ + return patch_code_disable_id(id); +} + +static uint32_t func_patch_ins(uint32_t old_func, uint32_t new_func) +{ +#if defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) + union { + uint32_t d32; + uint16_t d16[2]; + } ins; + uint32_t immd; + uint8_t j1, j2, s; + + ins.d32 = 0x9000F000; + immd = (new_func & ~1) - ((old_func + 4) & ~1); + s = immd >> 31; + j1 = s ^ !((immd >> 23) & 1); + j2 = s ^ !((immd >> 22) & 1); + ins.d16[0] |= (s << 10) | ((immd >> 12) & 0x3FF); + ins.d16[1] |= (j1 << 13) | (j2 << 11) | ((immd >> 1) & 0x7FF); + + return ins.d32; +#else +#error "Only ARMv7-M/ARMv8-M function can be patched" +#endif +} + +PATCH_ID patch_enable(enum PATCH_TYPE_T type, uint32_t addr, uint32_t data) +{ + uint8_t id, idfunc; + uint8_t cnt; + uint32_t bit; + uint32_t offset; + + if (addr < ROM_BASE || addr >= (ROM_BASE + 0x20000000)) { + // Not in code region + return -1; + } + if (type == PATCH_TYPE_FUNC) { + if (data >= addr) { + offset = data - addr; + } else { + offset = addr - data; + } + if (offset >= 0x01000000) { + // Branch distance too long to fit in a 32-bit branch instruction + return -2; + } + } + + if (!(type == PATCH_TYPE_CODE || type == PATCH_TYPE_FUNC || type == PATCH_TYPE_DATA)) { + return -3; + } + + for (id = 0; id < PATCH_ENTRY_NUM; id++) { + cnt = id / 32; + bit = (1 << (id % 32)); + if ((patch_map[cnt] & bit) == 0) { + patch_map[cnt] |= bit; + break; + } + } + if (id >= PATCH_ENTRY_NUM) { + return -4; + } + + idfunc = 0xFF; + + if (type == PATCH_TYPE_FUNC && (addr & 2)) { + for (idfunc = id; idfunc < PATCH_ENTRY_NUM; idfunc++) { + cnt = idfunc / 32; + bit = (1 << (idfunc % 32)); + if ((patch_map[cnt] & bit) == 0) { + patch_map[cnt] |= bit; + break; + } + } + if (idfunc >= PATCH_ENTRY_NUM) { + // Release previous patch + patch_map[cnt] &= ~bit; + return -5; + } + } + + if (type == PATCH_TYPE_CODE) { + patch_code_enable_id(id, addr, data); + } else if (type == PATCH_TYPE_DATA) { + patch_data_enable_id(id, addr, data); + } else if (type == PATCH_TYPE_FUNC) { + uint32_t ins; + + ins = func_patch_ins(addr, data); + + if (addr & 2) { + uint32_t real_addr[2]; + uint32_t real_data[2]; + + real_addr[0] = addr & ~3; + real_addr[1] = (addr + 4) & ~3; + + real_data[0] = *(volatile uint32_t *)real_addr[0]; + real_data[1] = *(volatile uint32_t *)real_addr[1]; + real_data[0] = (real_data[0] & 0x0000FFFF) | ((ins & 0xFFFF) << 16); + real_data[1] = (real_data[1] & 0xFFFF0000) | ((ins >> 16) & 0xFFFF); + + patch_code_enable_id(id, real_addr[0], real_data[0]); + patch_code_enable_id(idfunc, real_addr[1], real_data[1]); + } else { + patch_code_enable_id(id, addr, ins); + } + } + + return ((id + 1) & 0xFF) | (((idfunc + 1) & 0xFF) << 8); +} + +int patch_disable(PATCH_ID patch_id) +{ + uint8_t id; + uint8_t cnt, bit; + int i; + + for (i = 0; i < 2; i++) { + id = (uint8_t)(patch_id >> (8 * i)) - 1; + + if (id == 0xFF) { + return 0; + } else if (id >= PATCH_ENTRY_NUM) { + return -1; + } + + patch_code_disable_id(id); + + cnt = id / 32; + bit = (1 << (id % 32)); + patch_map[cnt] &= ~bit; + } + + return 0; +} + +void patch_close(void) +{ + int i; + + patch_ctrl->CTRL[0] &= ~PATCH_CTRL_GLOBAL_EN; + + for (i = 0; i < PATCH_ENTRY_NUM; i++) { + patch_code_disable_id(i); + } + + for (i = 0; i < ARRAY_SIZE(patch_map); i++) { + patch_map[i] = 0; + } +} +#endif +#endif diff --git a/platform/cmsis/patch_armv7m.c b/platform/cmsis/patch_armv7m.c new file mode 100644 index 0000000..6cd23aa --- /dev/null +++ b/platform/cmsis/patch_armv7m.c @@ -0,0 +1,270 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef __ARM_ARCH_7EM__ + +#include "patch.h" +#include "reg_patch_armv7m.h" +#include "plat_addr_map.h" +#include "cmsis.h" + +static struct PATCH_ARMV7M_T * const patch = (struct PATCH_ARMV7M_T *)0xE0002000; + +static uint32_t patch_map[(__NUM_CODE_PATCH + __NUM_LIT_PATCH + 31) / 32]; + +static uint32_t get_num_code(void) +{ + return __NUM_CODE_PATCH; +} + +static uint32_t get_num_lit(void) +{ + return __NUM_LIT_PATCH; +} + +static uint32_t get_remap_addr(void) +{ + return GET_BITFIELD(patch->FP_REMAP, REMAP_ADDR) | (RAM_BASE & 0xE0000000); +} + +int patch_open(uint32_t remap_addr) +{ + patch->FP_REMAP = REMAP_ADDR(remap_addr); + patch->FP_CTRL = FP_CTRL_KEY | FP_CTRL_ENABLE; + return 0; +} + +int patch_code_enable_id(uint32_t id, uint32_t addr, uint32_t data) +{ + uint32_t *remap_addr; + + if (id >= get_num_code()) { + return 1; + } + + remap_addr = (uint32_t *)get_remap_addr(); + remap_addr[id] = data; + patch->FP_COMP[id] = COMP_REPLACE(0) | COMP_ADDR(addr) | COMP_ENABLE; + return 0; +} + +int patch_code_disable_id(uint32_t id) +{ + if (id >= get_num_code()) { + return 1; + } + + patch->FP_COMP[id] = 0; + return 0; +} + +int patch_data_enable_id(uint32_t id, uint32_t addr, uint32_t data) +{ + uint32_t *remap_addr; + + if (id >= get_num_lit()) { + return 1; + } + id += get_num_code(); + + remap_addr = (uint32_t *)get_remap_addr(); + remap_addr[id] = data; + patch->FP_COMP[id] = COMP_REPLACE(0) | COMP_ADDR(addr) | COMP_ENABLE; + return 0; +} + +int patch_data_disable_id(uint32_t id) +{ + if (id >= get_num_lit()) { + return 1; + } + id += get_num_code(); + + patch->FP_COMP[id] = 0; + return 0; +} + +static uint32_t func_patch_ins(uint32_t old_func, uint32_t new_func) +{ +#ifdef __ARM_ARCH_7EM__ + union { + uint32_t d32; + uint16_t d16[2]; + } ins; + uint32_t immd; + uint8_t j1, j2, s; + + ins.d32 = 0x9000F000; + immd = (new_func & ~1) - ((old_func + 4) & ~1); + s = immd >> 31; + j1 = s ^ !((immd >> 23) & 1); + j2 = s ^ !((immd >> 22) & 1); + ins.d16[0] |= (s << 10) | ((immd >> 12) & 0x3FF); + ins.d16[1] |= (j1 << 13) | (j2 << 11) | ((immd >> 1) & 0x7FF); + + return ins.d32; +#else +#error "Only ARMv7-M function can be patched" +#endif +} + +PATCH_ID patch_enable(enum PATCH_TYPE_T type, uint32_t addr, uint32_t data) +{ + uint8_t start, end; + uint8_t id, idfunc; + uint8_t cnt; + uint32_t bit; + uint32_t offset; + + if (addr < ROM_BASE || addr >= (ROM_BASE + 0x20000000)) { + // Not in code region + return -1; + } + if (type == PATCH_TYPE_FUNC) { + if (data >= addr) { + offset = data - addr; + } else { + offset = addr - data; + } + if (offset >= 0x01000000) { + // Branch distance too long to fit in a 32-bit branch instruction + return -2; + } + } + + if (type == PATCH_TYPE_CODE || type == PATCH_TYPE_FUNC) { + start = 0; + end = start + get_num_code(); + } else if (type == PATCH_TYPE_DATA) { + start = get_num_code(); + end = start + get_num_lit(); + } else { + return -3; + } + + for (id = start; id < end; id++) { + cnt = id / 32; + bit = (1 << (id % 32)); + if ((patch_map[cnt] & bit) == 0) { + patch_map[cnt] |= bit; + break; + } + } + if (id >= end) { + return -4; + } + + idfunc = 0xFF; + + if (type == PATCH_TYPE_FUNC && (addr & 2)) { + for (idfunc = id; idfunc < end; idfunc++) { + cnt = idfunc / 32; + bit = (1 << (idfunc % 32)); + if ((patch_map[cnt] & bit) == 0) { + patch_map[cnt] |= bit; + break; + } + } + if (idfunc >= end) { + // Release previous patch + patch_map[cnt] &= ~bit; + return -5; + } + } + + if (type == PATCH_TYPE_CODE) { + patch_code_enable_id(id - start, addr, data); + } else if (type == PATCH_TYPE_DATA) { + patch_data_enable_id(id - start, addr, data); + } else if (type == PATCH_TYPE_FUNC) { + uint32_t ins; + + ins = func_patch_ins(addr, data); + + if (addr & 2) { + uint32_t real_addr[2]; + uint32_t real_data[2]; + + real_addr[0] = addr & ~3; + real_addr[1] = (addr + 4) & ~3; + + real_data[0] = *(volatile uint32_t *)real_addr[0]; + real_data[1] = *(volatile uint32_t *)real_addr[1]; + real_data[0] = (real_data[0] & 0x0000FFFF) | ((ins & 0xFFFF) << 16); + real_data[1] = (real_data[1] & 0xFFFF0000) | ((ins >> 16) & 0xFFFF); + + patch_code_enable_id(id - start, real_addr[0], real_data[0]); + patch_code_enable_id(idfunc - start, real_addr[1], real_data[1]); + } else { + patch_code_enable_id(id - start, addr, ins); + } + } + + return ((id + 1) & 0xFF) | (((idfunc + 1) & 0xFF) << 8); +} + +int patch_disable(PATCH_ID patch_id) +{ + uint8_t id; + uint8_t code_start, code_end, data_start, data_end; + uint8_t cnt, bit; + int i; + + code_start = 0; + code_end = code_start + get_num_code(); + data_start = code_end; + data_end = data_start + get_num_lit(); + + for (i = 0; i < 2; i++) { + id = (uint8_t)(patch_id >> (8 * i)) - 1; + + if (id == 0xFF) { + return 0; + } else if (id >= code_start && id < code_end) { + patch_code_disable_id(id); + } else if (id >= data_start && id < data_end) { + patch_data_disable_id(id - data_start); + } else { + return -1; + } + + cnt = id / 32; + bit = (1 << (id % 32)); + patch_map[cnt] &= ~bit; + } + + return 0; +} + +void patch_close(void) +{ + int i; + + patch->FP_CTRL = FP_CTRL_KEY; + + for (i = 0; i < get_num_code(); i++) { + patch_code_disable_id(i); + } + + for (i = get_num_code(); i < (get_num_code() + get_num_lit()); i++) { + patch_data_disable_id(i); + } + + for (i = 0; i < ARRAY_SIZE(patch_map); i++) { + patch_map[i] = 0; + } +} + +#endif diff --git a/platform/cmsis/reg_patch.h b/platform/cmsis/reg_patch.h new file mode 100644 index 0000000..3dce91a --- /dev/null +++ b/platform/cmsis/reg_patch.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_PATCH_H__ +#define __REG_PATCH_H__ + +#include "plat_types.h" +#include "plat_addr_map.h" + +#ifdef PATCH_CTRL_BASE + +struct PATCH_CTRL_T { + __IO uint32_t CTRL[PATCH_ENTRY_NUM]; +}; + +struct PATCH_DATA_T { + __IO uint32_t DATA[PATCH_ENTRY_NUM]; +}; + +#define PATCH_CTRL_ENTRY_EN (1 << 0) +#define PATCH_CTRL_ADDR_17_2_SHIFT 2 +#define PATCH_CTRL_ADDR_17_2_MASK (0xFFFF << PATCH_CTRL_ADDR_17_2_SHIFT) +#define PATCH_CTRL_17_2_ADDR(n) BITFIELD_VAL(PATCH_CTRL_30_2_ADDR, n) +// For entry 0 only +#define PATCH_CTRL_GLOBAL_EN (1 << 31) + +#define PATCH_CTRL_ADDR_MASK PATCH_CTRL_ADDR_17_2_MASK +#define PATCH_CTRL_ADDR(n) ((n) & PATCH_CTRL_ADDR_17_2_MASK) + +#endif + +#endif diff --git a/platform/cmsis/reg_patch_armv7m.h b/platform/cmsis/reg_patch_armv7m.h new file mode 100644 index 0000000..1a59c66 --- /dev/null +++ b/platform/cmsis/reg_patch_armv7m.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_PATCH_ARMV7M_H__ +#define __REG_PATCH_ARMV7M_H__ + +#ifdef __ARM_ARCH_7EM__ + +#include "plat_types.h" +#include "cmsis.h" + +struct PATCH_ARMV7M_T { + __IO uint32_t FP_CTRL; + __IO uint32_t FP_REMAP; + __IO uint32_t FP_COMP[512]; +}; + +#define NUM_CODE_6_4_SHIFT 12 +#define NUM_CODE_6_4_MASK (0x7 << NUM_CODE_6_4_SHIFT) +#define NUM_CODE_6_4(n) BITFIELD_VAL(NUM_CODE_6_4, n) +#define NUM_LIT_SHIFT 8 +#define NUM_LIT_MASK (0xF << NUM_LIT_SHIFT) +#define NUM_LIT(n) BITFIELD_VAL(NUM_LIT, n) +#define NUM_CODE_3_0_SHIFT 4 +#define NUM_CODE_3_0_MASK (0xF << NUM_CODE_3_0_SHIFT) +#define NUM_CODE_3_0(n) BITFIELD_VAL(NUM_CODE_3_0, n) +#define FP_CTRL_KEY (1 << 1) +#define FP_CTRL_ENABLE (1 << 0) + +#define REMAP_RMPSPT (1 << 29) +#define REMAP_ADDR_28_5_SHIFT 5 +#define REMAP_ADDR_28_5_MASK (0xFFFFFF << REMAP_ADDR_28_5_SHIFT) +#define REMAP_ADDR_28_5(n) BITFIELD_VAL(REMAP_ADDR_28_5, n) +#define REMAP_ADDR_SHIFT 0 +#define REMAP_ADDR_MASK (0x1FFFFFFF << REMAP_ADDR_SHIFT) +#define REMAP_ADDR(n) BITFIELD_VAL(REMAP_ADDR, n) + +#define COMP_REPLACE_SHIFT 30 +#define COMP_REPLACE_MASK (0x3 << COMP_REPLACE_SHIFT) +#define COMP_REPLACE(n) BITFIELD_VAL(COMP_REPLACE, n) +#define COMP_ADDR_28_2_SHIFT 2 +#define COMP_ADDR_28_2_MASK (0x7FFFFFF << COMP_ADDR_28_2_SHIFT) +#define COMP_ADDR_28_2(n) BITFIELD_VAL(COMP_ADDR_28_2, n) +#define COMP_ADDR_SHIFT 0 +#define COMP_ADDR_MASK (0x1FFFFFFF << COMP_ADDR_SHIFT) +#define COMP_ADDR(n) BITFIELD_VAL(COMP_ADDR, n) +#define COMP_ENABLE (1 << 0) + +#endif + +#endif diff --git a/platform/cmsis/retarget_armclang.cpp b/platform/cmsis/retarget_armclang.cpp new file mode 100644 index 0000000..63b72eb --- /dev/null +++ b/platform/cmsis/retarget_armclang.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef __ARMCC_VERSION + +extern "C" +{ + +#include "analog.h" +#include "hal_codec.h" +#include "hal_trace.h" +#include "codec_int.h" +#include "norflash_drv.h" +#include "pmu.h" + +#ifdef NOSTD + +void __rt_raise(int sig, intptr_t type) +{ + ASSERT(false, "__rt_raise: sig=%d type=%p", sig, type); +} + +#endif + +// Stupid armlink +WEAK void analog_aud_xtal_tune(float ratio) {} +WEAK void hal_codec_dac_gain_m60db_check(enum HAL_CODEC_PERF_TEST_POWER_T type) {} +WEAK void hal_codec_set_noise_reduction(bool enable) {} +WEAK void hal_codec_tune_both_resample_rate(float ratio) {} +WEAK void hal_codec_set_bt_trigger_callback(HAL_CODEC_BT_TRIGGER_CALLBACK callback) {} +WEAK int hal_codec_bt_trigger_start(void) {return 0;} +WEAK int hal_codec_bt_trigger_stop(void) {return 0;} +WEAK void hal_codec_sync_dac_enable(enum HAL_CODEC_SYNC_TYPE_T type) {} +WEAK void hal_codec_sync_dac_disable(void) {} +WEAK void hal_codec_sync_adc_enable(enum HAL_CODEC_SYNC_TYPE_T type) {} +WEAK void hal_codec_sync_adc_disable(void) {} +WEAK void hal_codec_sync_dac_resample_rate_enable(enum HAL_CODEC_SYNC_TYPE_T type) {} +WEAK void hal_codec_sync_dac_resample_rate_disable(void) {} +WEAK void hal_codec_sync_adc_resample_rate_enable(enum HAL_CODEC_SYNC_TYPE_T type) {} +WEAK void hal_codec_sync_adc_resample_rate_disable(void) {} +WEAK void hal_codec_sync_dac_gain_enable(enum HAL_CODEC_SYNC_TYPE_T type) {} +WEAK void hal_codec_sync_dac_gain_disable(void) {} +WEAK void hal_codec_sync_adc_gain_enable(enum HAL_CODEC_SYNC_TYPE_T type) {} +WEAK void hal_codec_sync_adc_gain_disable(void) {} +WEAK int codec_anc_open(enum ANC_TYPE_T type, enum AUD_SAMPRATE_T dac_rate, enum AUD_SAMPRATE_T adc_rate, CODEC_ANC_HANDLER hdlr) {return 0;} +WEAK int codec_anc_close(enum ANC_TYPE_T type) {return 0;} + +#ifdef ROM_BUILD +WEAK void norflash_reset(void) {} +WEAK int norflash_get_size(uint32_t *total_size, uint32_t *block_size, uint32_t *sector_size, uint32_t *page_size) {return HAL_NORFLASH_OK;} +WEAK int norflash_set_mode(uint32_t op) {return HAL_NORFLASH_OK;} +WEAK int norflash_pre_operation(void) {return HAL_NORFLASH_OK;} +WEAK int norflash_post_operation(void) {return HAL_NORFLASH_OK;} +WEAK int norflash_init_sample_delay_by_div(uint32_t div) {return HAL_NORFLASH_OK;} +WEAK void norflash_set_sample_delay(uint32_t index) {} +WEAK int norflash_sample_delay_calib(void) {return HAL_NORFLASH_OK;} +WEAK int norflash_init_div(const struct HAL_NORFLASH_CONFIG_T *cfg) {return HAL_NORFLASH_OK;} +WEAK int norflash_match_chip(const uint8_t *id, uint32_t len) {return HAL_NORFLASH_OK;} +WEAK int norflash_get_id(uint8_t *value, uint32_t len) {return HAL_NORFLASH_OK;} +WEAK int norflash_get_unique_id(uint8_t *value, uint32_t len) {return HAL_NORFLASH_OK;} +WEAK enum HAL_NORFLASH_RET_T norflash_erase(uint32_t start_address, enum DRV_NORFLASH_ERASE_T type, int suspend) {return HAL_NORFLASH_OK;} +WEAK enum HAL_NORFLASH_RET_T norflash_write(uint32_t start_address, const uint8_t *buffer, uint32_t len, int suspend) {return HAL_NORFLASH_OK;} +WEAK int norflash_read(uint32_t start_address, uint8_t *buffer, uint32_t len) {return HAL_NORFLASH_OK;} + +WEAK void pmu_flash_freq_config(uint32_t freq) {} +WEAK void pmu_rs_freq_config(uint32_t freq) {} +WEAK void pmu_led_set_voltage_domains(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt) {} +WEAK void pmu_led_set_pull_select(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_PIN_PULL_SELECT_T pull_sel) {} + +#ifdef SPI_ROM_ONLY +WEAK int hal_ispi_open(const struct HAL_SPI_CFG_T *cfg) {return 0;} +WEAK int hal_ispi_send(const void *data, uint32_t len) {return 0;} +WEAK int hal_ispi_recv(const void *cmd, void *data, uint32_t len) {return 0;} +#endif + +WEAK void analog_aud_freq_pll_config(uint32_t freq, uint32_t div) {} +WEAK void analog_aud_pll_open(enum ANA_AUD_PLL_USER_T user) {} +WEAK void analog_aud_pll_close(enum ANA_AUD_PLL_USER_T user) {} +WEAK void analog_aud_codec_speaker_enable(bool en) {} +WEAK void analog_aud_set_dac_gain(int32_t v) {} +WEAK uint32_t analog_aud_get_max_dre_gain(void) {return 0;} +WEAK void analog_aud_vad_adc_enable(bool en) {} +WEAK void analog_aud_vad_enable(enum AUD_VAD_TYPE_T type, bool en) {} +#endif + +} + +#endif // __ARMCC_VERSION + diff --git a/platform/cmsis/retarget_armclang_asm.S b/platform/cmsis/retarget_armclang_asm.S new file mode 100644 index 0000000..e7c6fc1 --- /dev/null +++ b/platform/cmsis/retarget_armclang_asm.S @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef __ARMCC_VERSION + +#include "plat_addr_map.h" +#include "link_sym_armclang.h" + + .syntax unified + + .text + + .macro def_sym, name:req, val:req + .global \name + .set \name, \val + .endm + + def_sym __export_fn_rom, (ROM_BASE + ROM_SIZE - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE) + + .section .code_start_addr, "a", %progbits + .word BUILD_INFO_MAGIC +#ifdef PROGRAMMER + .word __exec_struct_start +#else + .word __flash_start +#endif + + .end + +#endif // __ARMCC_VERSION + diff --git a/platform/cmsis/retarget_gcc.cpp b/platform/cmsis/retarget_gcc.cpp new file mode 100644 index 0000000..84d6f0a --- /dev/null +++ b/platform/cmsis/retarget_gcc.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if (defined(__GNUC__) && !defined(__ARMCC_VERSION)) + +#if !defined(NOSTD) && !defined(MBED) +#define LIBC_HOOKS +#endif + +#ifdef LIBC_HOOKS + +#include +#include "hal_trace.h" + +#ifndef FILEHANDLE +typedef int FILEHANDLE; +#endif + +#define WEAK __attribute__((weak)) +#define PACKED __attribute__((packed)) + +#include +#include +#include +#define PREFIX(x) x + +extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, + unsigned int length, int mode) +{ + int n = 0; // n is the number of bytes written + if (fh < 3) { + hal_trace_output(buffer, length); + n = length; + } + return n; +} + +extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, + unsigned int length, int mode) +{ + int n = 0; // n is the number of bytes read + if (fh < 3) { + // only read a character at a time from stdin + // TODO: Read from trace uart input + n = 1; + } + return n; +} + +#if defined(__GNUC__) +/* prevents the exception handling name demangling code getting pulled in */ +namespace __gnu_cxx { + void __verbose_terminate_handler() { + ASSERT(0, "Exception"); + } +} +extern "C" WEAK void __cxa_pure_virtual(void); +extern "C" WEAK void __cxa_pure_virtual(void) +{ + _exit(1); +} + +#endif + +// Provide implementation of _sbrk (low-level dynamic memory allocation +// routine) for GCC_ARM which compares new heap pointer with MSP instead of +// SP. This make it compatible with RTX RTOS thread stacks. +#if defined(__GNUC__) && defined(__arm__) +// Linker defined symbol used by _sbrk to indicate where heap should start. +extern "C" int __end__; +extern "C" uint32_t __HeapLimit; + +// Turn off the errno macro and use actual global variable instead. +#undef errno +extern "C" int errno; + +// For ARM7 only +register unsigned char * stack_ptr __asm ("sp"); + +// Dynamic memory allocation related syscall. +extern "C" caddr_t _sbrk(int incr) +{ + static unsigned char* heap = (unsigned char*)&__end__; + unsigned char* prev_heap = heap; + unsigned char* new_heap = heap + incr; + +#if defined(TARGET_ARM7) + if (new_heap >= stack_ptr) { +#elif defined(TARGET_CORTEX_A) + if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */ +#else + if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */ +#endif + ASSERT(false, "_sbrk:Heap overflowed: start=%p end=%p cur=%p incr=%d", + (unsigned char*)&__end__, (unsigned char*)&__HeapLimit, heap, incr); + errno = ENOMEM; + return (caddr_t)-1; + } + + TRACE(2,"_sbrk: incr %d cur=%p\n", incr, heap); + + heap = new_heap; + return (caddr_t) prev_heap; +} +#endif + + +#if defined(__GNUC__) && defined(__arm__) +extern "C" void _exit(int return_code) +{ +#else +namespace std { +extern "C" void exit(int return_code) +{ +#endif + if (return_code) { + ASSERT(false, "system die: %d", return_code); + } + + do { volatile int i = 0; i++; } while (1); +} + +#if !(defined(__GNUC__) && defined(__arm__)) && !defined(TOOLCHAIN_GCC_CW) +} //namespace std +#endif + +#endif /*LIBC_HOOKS*/ + +#endif // __GNUC__ && !__ARMCC_VERSION + diff --git a/platform/cmsis/stack_protector.c b/platform/cmsis/stack_protector.c new file mode 100644 index 0000000..fcda603 --- /dev/null +++ b/platform/cmsis/stack_protector.c @@ -0,0 +1,22 @@ +#include +#include +#include + +uint32_t __stack_chk_guard = 0xdeadbeef; + +void +__attribute__((__constructor__)) +__stack_chk_init (void) +{ + if (__stack_chk_guard != 0) + return; +} + +void +__attribute__((__noreturn__)) +__stack_chk_fail (void) +{ + const char *msg = "*** stack smashing detected ***: terminated\n"; + ASSERT(0, "%s", msg); +} + diff --git a/platform/cmsis/system_ARMCM.c b/platform/cmsis/system_ARMCM.c new file mode 100644 index 0000000..ceef625 --- /dev/null +++ b/platform/cmsis/system_ARMCM.c @@ -0,0 +1,105 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ARM_ARCH_ISA_ARM + +#include "cmsis.h" +#include "hal_location.h" +#include "system_ARMCM.h" + +void BOOT_TEXT_FLASH_LOC SystemInit (void) +{ +#if (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */ + (3UL << 11*2) ); /* set CP11 Full Access */ +#endif + + SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk; +#ifdef __ARM_ARCH_8M_MAIN__ + // Disable stack limit check on hard fault, NMI and reset + // (The check will generate STKOF usage fault) + SCB->CCR |= SCB_CCR_STKOFHFNMIGN_Msk; +#endif +#ifdef UNALIGNED_ACCESS + SCB->CCR &= ~SCB_CCR_UNALIGN_TRP_Msk; +#else + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif +#ifdef USAGE_FAULT + SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk; + NVIC_SetPriority(UsageFault_IRQn, IRQ_PRIORITY_REALTIME); +#else + SCB->SHCSR &= ~SCB_SHCSR_USGFAULTENA_Msk; +#endif +#ifdef BUS_FAULT + SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk; + NVIC_SetPriority(BusFault_IRQn, IRQ_PRIORITY_REALTIME); +#else + SCB->SHCSR &= ~SCB_SHCSR_BUSFAULTENA_Msk; +#endif +#ifdef MEM_FAULT + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + NVIC_SetPriority(MemoryManagement_IRQn, IRQ_PRIORITY_REALTIME); +#else + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + TZ_SAU_Setup(); +#endif +} + +#ifndef UNALIGNED_ACCESS + +bool get_unaligned_access_status(void) +{ + return !(SCB->CCR & SCB_CCR_UNALIGN_TRP_Msk); +} + +bool config_unaligned_access(bool enable) +{ + bool en; + + en = !(SCB->CCR & SCB_CCR_UNALIGN_TRP_Msk); + + if (enable) { + SCB->CCR &= ~SCB_CCR_UNALIGN_TRP_Msk; + } else { + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; + } + + return en; +} + +#endif + +// ----------------------------------------------------------- +// CPU ID +// ----------------------------------------------------------- + +uint32_t BOOT_TEXT_SRAM_DEF(get_cpu_id) (void) +{ +#ifdef CHIP_HAS_CP +#ifdef __ARM_ARCH_8M_MAIN__ + return (SCB->ID_ADR & 3); +#else /*__ARM_ARCH_8M_MAIN__*/ + return (SCB->ADR & 3); +#endif /*__ARM_ARCH_8M_MAIN__*/ +#else + return 0; +#endif +} + +#endif diff --git a/platform/cmsis/system_cp.c b/platform/cmsis/system_cp.c new file mode 100644 index 0000000..217a630 --- /dev/null +++ b/platform/cmsis/system_cp.c @@ -0,0 +1,239 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ARM_ARCH_ISA_ARM +#ifdef CHIP_HAS_CP + +#include "cmsis_nvic.h" +#include "plat_types.h" +#include "plat_addr_map.h" +#include "hal_cache.h" +#include "hal_location.h" +#ifdef __ARMCC_VERSION +#include "link_sym_armclang.h" +#endif + +// The vector table must be aligned to NVIC_NUM_VECTORS-word boundary, rounding up to the next power of two +// -- 0x100 for 33~64 vectors, and 0x200 for 65~128 vectors +#if defined(ROM_BUILD) || defined(PROGRAMMER) || (RAMCP_SIZE <= 0) +#define VECTOR_LOC_CP ALIGNED(0x200) +#else +#define VECTOR_LOC_CP __attribute__((section(".vector_table_cp"))) +#endif + +#define FAULT_HANDLER_CP __attribute__((weak,alias("NVIC_default_handler_cp"))) + +static uint32_t VECTOR_LOC_CP vector_table_cp[NVIC_NUM_VECTORS]; + +static void NAKED NVIC_default_handler_cp(void) +{ + asm volatile("_loop:; nop; nop; nop; nop; b _loop;"); +} + +void FAULT_HANDLER_CP Reset_Handler_cp(void); +void FAULT_HANDLER_CP NMI_Handler_cp(void); +void FAULT_HANDLER_CP HardFault_Handler_cp(void); +void FAULT_HANDLER_CP MemManage_Handler_cp(void); +void FAULT_HANDLER_CP BusFault_Handler_cp(void); +void FAULT_HANDLER_CP UsageFault_Handler_cp(void); +void FAULT_HANDLER_CP SVC_Handler_cp(void); +void FAULT_HANDLER_CP DebugMon_Handler_cp(void); +void FAULT_HANDLER_CP PendSV_Handler_cp(void); +void FAULT_HANDLER_CP SysTick_Handler_cp(void); + +static const uint32_t fault_handlers_cp[NVIC_USER_IRQ_OFFSET] = { + (uint32_t)0, + (uint32_t)Reset_Handler_cp, + (uint32_t)NMI_Handler_cp, + (uint32_t)HardFault_Handler_cp, + (uint32_t)MemManage_Handler_cp, + (uint32_t)BusFault_Handler_cp, + (uint32_t)UsageFault_Handler_cp, + (uint32_t)NVIC_default_handler_cp, + (uint32_t)NVIC_default_handler_cp, + (uint32_t)NVIC_default_handler_cp, + (uint32_t)NVIC_default_handler_cp, + (uint32_t)SVC_Handler_cp, + (uint32_t)DebugMon_Handler_cp, + (uint32_t)NVIC_default_handler_cp, + (uint32_t)PendSV_Handler_cp, + (uint32_t)SysTick_Handler_cp, +}; + +void NVIC_InitVectors_cp(void) +{ + int i; + + for (i = 0; i < NVIC_NUM_VECTORS; i++) { + vector_table_cp[i] = (i < ARRAY_SIZE(fault_handlers_cp)) ? + fault_handlers_cp[i] : (uint32_t)NVIC_default_handler_cp; + } + + SCB->VTOR = (uint32_t)vector_table_cp; +} + +void NVIC_SetDefaultFaultHandler_cp(NVIC_DEFAULT_FAULT_HANDLER_T handler) +{ + int i; + + for (i = 1; i < ARRAY_SIZE(fault_handlers_cp); i++) { + if (vector_table_cp[i] == (uint32_t)NVIC_default_handler_cp) { + vector_table_cp[i] = (uint32_t)handler; + } + } +} + +void SystemInit_cp(void) +{ +#if (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */ + (3UL << 11*2) ); /* set CP11 Full Access */ +#endif + + SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk; +#ifdef __ARM_ARCH_8M_MAIN__ + // Disable stack limit check on hard fault, NMI and reset + // (The check will generate STKOF usage fault) + SCB->CCR |= SCB_CCR_STKOFHFNMIGN_Msk; +#endif +#ifdef UNALIGNED_ACCESS + SCB->CCR &= ~SCB_CCR_UNALIGN_TRP_Msk; +#else + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif +#ifdef USAGE_FAULT + SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk; + NVIC_SetPriority(UsageFault_IRQn, IRQ_PRIORITY_REALTIME); +#else + SCB->SHCSR &= ~SCB_SHCSR_USGFAULTENA_Msk; +#endif +#ifdef BUS_FAULT + SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk; + NVIC_SetPriority(BusFault_IRQn, IRQ_PRIORITY_REALTIME); +#else + SCB->SHCSR &= ~SCB_SHCSR_BUSFAULTENA_Msk; +#endif +#ifdef MEM_FAULT + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + NVIC_SetPriority(MemoryManagement_IRQn, IRQ_PRIORITY_REALTIME); +#else + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +extern uint32_t __cp_text_sram_start_flash__[]; +extern uint32_t __cp_text_sram_start[]; +extern uint32_t __cp_text_sram_end[]; +extern uint32_t __cp_data_sram_start_flash__[]; +extern uint32_t __cp_data_sram_start[]; +extern uint32_t __cp_data_sram_end[]; +extern uint32_t __cp_bss_sram_start[]; +extern uint32_t __cp_bss_sram_end[]; + +void NAKED system_cp_reset_handler(void) +{ + asm volatile ( +#ifdef __ARM_ARCH_8M_MAIN__ + "ldr r0, =" TO_STRING(__cp_stack_limit) ";" + "msr msplim, r0;" +#endif + "ldr r3, =" TO_STRING(__cp_stack_top) ";" + "msr msp, r3;" + "movs r4, 0;" + "mov r5, r4;" + "mov r6, r4;" + "mov r7, r4;" + "mov r8, r4;" + "mov r9, r4;" + "mov r10, r4;" + "mov r11, r4;" + "mov r12, r4;" +#if !defined(__SOFTFP__) && defined(__ARM_FP) && (__ARM_FP >= 4) + "ldr.w r0, =0xE000ED88;" + "ldr r1, [r0];" + "orr r1, r1, #(0xF << 20);" + "str r1, [r0];" + "dsb;" + "isb;" + "vmov s0, s1, r4, r5;" + "vmov s2, s3, r4, r5;" + "vmov s4, s5, r4, r5;" + "vmov s6, s7, r4, r5;" + "vmov s8, s9, r4, r5;" + "vmov s10, s11, r4, r5;" + "vmov s12, s13, r4, r5;" + "vmov s14, s15, r4, r5;" + "vmov s16, s17, r4, r5;" + "vmov s18, s19, r4, r5;" + "vmov s20, s21, r4, r5;" + "vmov s22, s23, r4, r5;" + "vmov s24, s25, r4, r5;" + "vmov s26, s27, r4, r5;" + "vmov s28, s29, r4, r5;" + "vmov s30, s31, r4, r5;" +#endif + "bl hal_cmu_cp_get_entry_addr;" + "blx r0;" + ); +} + +void system_cp_init(int load_code) +{ + NVIC_InitVectors_cp(); + + // Enable icache + hal_cachecp_enable(HAL_CACHE_ID_I_CACHE); + // Enable dcache + hal_cachecp_enable(HAL_CACHE_ID_D_CACHE); + // Enable write back + hal_cachecp_writeback_enable(HAL_CACHE_ID_D_CACHE); + + SystemInit_cp(); + +#if !(defined(ROM_BUILD) || defined(PROGRAMMER)) + uint32_t *dst; + uint32_t *src; + + if (load_code) { + dst = __cp_text_sram_start; + src = __cp_text_sram_start_flash__; + for (; dst < __cp_text_sram_end; dst++, src++) { + *dst = *src; + } + } + + dst = __cp_data_sram_start; + src = __cp_data_sram_start_flash__; + for (; dst < __cp_data_sram_end; dst++, src++) { + *dst = *src; + } + + dst = __cp_bss_sram_start; + for (; dst < __cp_bss_sram_end; dst++) { + *dst = 0; + } +#endif +} + +void system_cp_term(void) +{ + // Disable dcache + hal_cachecp_disable(HAL_CACHE_ID_D_CACHE); + // Disable icache + hal_cachecp_disable(HAL_CACHE_ID_I_CACHE); +} + +#endif +#endif diff --git a/platform/cmsis/system_utils.c b/platform/cmsis/system_utils.c new file mode 100644 index 0000000..885b8a1 --- /dev/null +++ b/platform/cmsis/system_utils.c @@ -0,0 +1,274 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis.h" +#include "hal_cache.h" +#include "hal_cmu.h" +#include "hal_location.h" +#include "hal_psram.h" +#include "hal_psramuhs.h" +#if !defined(NOSTD) && defined(ACCURATE_DB_TO_FLOAT) +#include +#endif +#ifdef __ARMCC_VERSION +#include "link_sym_armclang.h" +#endif + +#ifdef BOOT_CODE_IN_RAM +#define MUTEX_CODE_LOC BOOT_TEXT_SRAM_LOC +#else +#define MUTEX_CODE_LOC +#endif + +extern uint32_t __got_info_start[]; + +void BOOT_TEXT_FLASH_LOC GotBaseInit(void) +{ +#ifndef __ARMCC_VERSION + asm volatile("ldr r9, =__got_info_start"); +#endif +} + +#ifndef __ARM_ARCH_ISA_ARM +// ----------------------------------------------------------- +// Boot initialization +// CAUTION: This function and all the functions it called must +// NOT access global data/bss, for the global data/bss +// is not available at that time. +// ----------------------------------------------------------- +extern uint32_t __boot_sram_start_flash__[]; +extern uint32_t __boot_sram_end_flash__[]; +extern uint32_t __boot_sram_start__[]; +extern uint32_t __boot_bss_sram_start__[]; +extern uint32_t __boot_bss_sram_end__[]; + +extern uint32_t __sram_text_data_start_flash__[]; +extern uint32_t __sram_text_data_end_flash__[]; +extern uint32_t __sram_text_data_start__[]; +extern uint32_t __sram_bss_start__[]; +extern uint32_t __sram_bss_end__[]; +extern uint32_t __fast_sram_text_data_start__[]; +extern uint32_t __fast_sram_text_data_end__[]; +extern uint32_t __fast_sram_text_data_start_flash__[]; +extern uint32_t __fast_sram_text_data_end_flash__[]; + +void BOOT_TEXT_FLASH_LOC BootInit(void) +{ + uint32_t *dst, *src; + + // Enable icache + hal_cache_enable(HAL_CACHE_ID_I_CACHE); + // Enable dcache + hal_cache_enable(HAL_CACHE_ID_D_CACHE); + // Enable write buffer + hal_cache_writebuffer_enable(HAL_CACHE_ID_D_CACHE); + // Enable write back + hal_cache_writeback_enable(HAL_CACHE_ID_D_CACHE); + + // Init GOT base register + GotBaseInit(); + + // Init boot sections + for (dst = __boot_sram_start__, src = __boot_sram_start_flash__; + src < __boot_sram_end_flash__; + dst++, src++) { + *dst = *src; + } + + for (dst = __boot_bss_sram_start__; dst < __boot_bss_sram_end__; dst++) { + *dst = 0; + } + +#ifdef FPGA + hal_cmu_fpga_setup(); +#else + hal_cmu_setup(); +#endif + + for (dst = __sram_text_data_start__, src = __sram_text_data_start_flash__; + src < __sram_text_data_end_flash__; + dst++, src++) { + *dst = *src; + } + + for (dst = __sram_bss_start__; dst < __sram_bss_end__; dst++) { + *dst = 0; + } + + for (dst = __fast_sram_text_data_start__, src = __fast_sram_text_data_start_flash__; + src < __fast_sram_text_data_end_flash__; + dst++, src++) { + *dst = *src; + } + + // Init psram +#if defined(CHIP_HAS_PSRAM) && defined(PSRAM_ENABLE) + hal_psram_init(); +#endif + + // Init psramuhs +#if defined(CHIP_HAS_PSRAMUHS) && defined(PSRAMUHS_ENABLE) + hal_cmu_dsp_clock_enable(); + hal_cmu_dsp_reset_clear(); + hal_psramuhs_init(); +#endif + +} +#endif + +// ----------------------------------------------------------- +// Mutex flag +// ----------------------------------------------------------- + +int MUTEX_CODE_LOC set_bool_flag(bool *flag) +{ + bool busy; + + do { + busy = (bool)__LDREXB((unsigned char *)flag); + if (busy) { + __CLREX(); + return -1; + } + } while (__STREXB(true, (unsigned char *)flag)); + __DMB(); + + return 0; +} + +void MUTEX_CODE_LOC clear_bool_flag(bool *flag) +{ + *flag = false; + __DMB(); +} + +// ----------------------------------------------------------- +// Misc +// ----------------------------------------------------------- + +float db_to_float(float db) +{ + float coef; + +#if !defined(NOSTD) && defined(ACCURATE_DB_TO_FLOAT) + // The math lib will consume 4K+ bytes of space + coef = powf(10, db / 20); +#else + static const float factor_m9db = 0.354813389234; + static const float factor_m3db = 0.707945784384; + static const float factor_m1db = 0.891250938134; + static const float factor_m0p5db = 0.944060876286; + static const float factor_m0p1db = 0.988553094657; + + coef = 1.0; + + if (db < 0) { + while (1) { + if (db <= -9.0) { + db += 9.0; + coef *= factor_m9db; + } else if (db <= -3.0) { + db += 3.0; + coef *= factor_m3db; + } else if (db <= -1.0) { + db += 1.0; + coef *= factor_m1db; + } else if (db <= -0.5) { + db += 0.5; + coef *= factor_m0p5db; + } else if (db <= -0.1 / 2) { + db += 0.1; + coef *= factor_m0p1db; + } else { + break; + } + } + } else if (db > 0) { + while (1) { + if (db >= 9.0) { + db -= 9.0; + coef /= factor_m9db; + } else if (db >= 3.0) { + db -= 3.0; + coef /= factor_m3db; + } else if (db >= 1.0) { + db -= 1.0; + coef /= factor_m1db; + } else if (db >= 0.5) { + db -= 0.5; + coef /= factor_m0p5db; + } else if (db >= 0.1 / 2) { + db -= 0.1; + coef /= factor_m0p1db; + } else { + break; + } + } + } +#endif + + return coef; +} + +uint32_t get_msb_pos(uint32_t val) +{ + uint32_t lead_zero; + + lead_zero = __CLZ(val); + return (lead_zero >= 32) ? 32 : 31 - lead_zero; +} + +uint32_t get_lsb_pos(uint32_t val) +{ + return __CLZ(__RBIT(val)); +} + +uint32_t integer_sqrt(uint32_t val) +{ + unsigned int msb; + unsigned int x; + unsigned int y; + + if (val == 0) { + return 0; + } + + for (msb = 31; msb > 0; msb--) { + if (val & (1 << msb)) { + break; + } + } + + x = ((1 << msb) + 1) / 2; + + while (1) { + y = (x + val / x) / 2; + if (y >= x) { + break; + } + x = y; + } + + return x; +} + +uint32_t integer_sqrt_nearest(uint32_t val) +{ + unsigned int s; + + s = integer_sqrt(val * 4); + return (s + 1) / 2; +} + diff --git a/platform/drivers/Makefile b/platform/drivers/Makefile new file mode 100644 index 0000000..d45fd5a --- /dev/null +++ b/platform/drivers/Makefile @@ -0,0 +1,13 @@ +obj-y := ana/ codec/ norflash/ bt/ btpcm/ sbcacc/ + +ifeq ($(CHIP_HAS_USB),1) +obj-y += usb/ +endif + +subdir-ccflags-y += -Iplatform/drivers/ana \ + -Iplatform/drivers/bt + +VCO_TEST_TOOL ?= 1 +ifeq ($(VCO_TEST_TOOL),1) +subdir-ccflags-y += -DVCO_TEST_TOOL +endif diff --git a/platform/drivers/ana/Makefile b/platform/drivers/ana/Makefile new file mode 100644 index 0000000..d70b467 --- /dev/null +++ b/platform/drivers/ana/Makefile @@ -0,0 +1,200 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) + +obj-y += $(CHIP)/ + +subdir-ccflags-y += -Iplatform/drivers/ana + +# PMU settings +export PMU_CFG_FLAGS := + +# ANALOG settings +export ANA_CFG_FLAGS := + +# USBPHY settings +export USBPHY_CFG_FLAGS := + +export PMU_DCDC_CALIB ?= 1 +ifeq ($(PMU_DCDC_CALIB),1) +PMU_CFG_FLAGS += -DPMU_DCDC_CALIB +endif + +ifeq ($(PMU_FULL_INIT),1) +PMU_CFG_FLAGS += -DPMU_FULL_INIT +PMU_INIT := 1 +endif +ifeq ($(PMU_INIT),1) +PMU_CFG_FLAGS += -DPMU_INIT +endif + +ifeq ($(NO_SLEEP),1) +PMU_CFG_FLAGS += -DNO_SLEEP +endif + +ifeq ($(MCU_HIGH_PERFORMANCE_MODE),1) +PMU_CFG_FLAGS += -DMCU_HIGH_PERFORMANCE_MODE +endif + +ifneq ($(CHIP),best1000) +ifneq ($(PROGRAMMER),1) +VCRYSTAL_OFF ?= 1 +endif +endif +ifeq ($(VCRYSTAL_OFF),1) +PMU_CFG_FLAGS += -DVCRYSTAL_OFF +endif + +ifeq ($(VMEM_ON),1) +PMU_CFG_FLAGS += -DVMEM_ON +endif + +ifeq ($(VUSB_ON),1) +PMU_CFG_FLAGS += -DVUSB_ON +endif + +ifeq ($(ULTRA_LOW_POWER),1) +PMU_CFG_FLAGS += -DULTRA_LOW_POWER +endif + +ifeq ($(DIGMIC_HIGH_VOLT),1) +PMU_CFG_FLAGS += -DDIGMIC_HIGH_VOLT +endif + +ifeq ($(ANA_26M_X4_ENABLE),1) +PMU_CFG_FLAGS += -DANA_26M_X4_ENABLE +endif +ifeq ($(OSC_26M_X4_AUD2BB),1) +PMU_CFG_FLAGS += -DOSC_26M_X4_AUD2BB +endif + +ifeq ($(DIG_OSC_X4_ENABLE),1) +PMU_CFG_FLAGS += -DDIG_OSC_X4_ENABLE +endif + +ifeq ($(RTC_ENABLE),1) +PMU_CFG_FLAGS += -DRTC_ENABLE +endif + +ifeq ($(CLK_32K_FROM_OSC),1) +PMU_CFG_FLAGS += -DCLK_32K_FROM_OSC +endif + +ifeq ($(CHIP_HAS_DCO),1) +PMU_CFG_FLAGS += -DCHIP_HAS_DCO +ANA_CFG_FLAGS += -DCHIP_HAS_DCO +endif + +ifeq ($(USB_HIGH_SPEED),1) +PMU_CFG_FLAGS += -DUSB_HIGH_SPEED +USBPHY_CFG_FLAGS += -DUSB_HIGH_SPEED +endif + +ifeq ($(CHIP_HAS_USBPHY),1) +USBPHY_CFG_FLAGS += -DCHIP_HAS_USBPHY +ifeq ($(CHIP_HAS_SPIPHY),1) +USBPHY_CFG_FLAGS += -DCHIP_HAS_SPIPHY +PMU_CFG_FLAGS += -DCHIP_HAS_SPIPHY +endif +endif + +ifeq ($(USB_HS_LOOPBACK_TEST),1) +USBPHY_CFG_FLAGS += -DUSB_HS_LOOPBACK_TEST +endif + +export PLL_CFG_FLAGS := +ifeq ($(CHIP_HAS_SPIPHY),1) +PLL_CFG_FLAGS += -DCHIP_HAS_SPIPHY +endif + +ifeq ($(POWER_MODE),LDO) +PMU_CFG_FLAGS += -DLDO_MODE +else +ifeq ($(POWER_MODE),DIG_DCDC) +PMU_CFG_FLAGS += -DDIG_DCDC_MODE +else +ifeq ($(POWER_MODE),ANA_DCDC) +PMU_CFG_FLAGS += -DANA_DCDC_MODE +else +ifneq ($(POWER_MODE),) +$(error Invalid POWER_MODE: $(POWER_MODE)) +endif +endif +endif +endif + +ifeq ($(MTEST_ENABLED),1) +PMU_CFG_FLAGS +=-DMTEST_ENABLED +ifneq ($(MTEST_CLK_MHZ),) +PMU_CFG_FLAGS +=-DMTEST_CLK_MHZ=$(MTEST_CLK_MHZ) +endif # MTEST_CLK_MHZ +ifneq ($(MTEST_VOLT),) +VCORE_STEM :=$(subst .,_,$(MTEST_VOLT)) +ifeq ($(POWER_MODE),LDO) +PMU_CFG_FLAGS += -DMTEST_VOLT=PMU_VDIG_$(VCORE_STEM) +else +PMU_CFG_FLAGS += -DMTEST_VOLT=PMU_DCDC_DIG_$(VCORE_STEM) +endif +endif # MTEST_VOLT +endif # MTEST_ENABLED + +ANA_CFG_FLAGS += $(MAX_DAC_OUTPUT_FLAGS) + +ifeq ($(AUDIO_INPUT_CAPLESSMODE),1) +ANA_CFG_FLAGS += -D_MIC_CAPLESSMODE_ +endif + +ifeq ($(AUDIO_INPUT_LARGEGAIN),1) +ANA_CFG_FLAGS += -D_MIC_LARGEGAIN_ +endif + +ifeq ($(AUDIO_OUTPUT_DIFF),1) +ANA_CFG_FLAGS += -DAUDIO_OUTPUT_DIFF +PMU_CFG_FLAGS += -DAUDIO_OUTPUT_DIFF +endif + +ifeq ($(AUDIO_OUTPUT_DC_CALIB),1) +ANA_CFG_FLAGS += -DAUDIO_OUTPUT_DC_CALIB +endif +ifeq ($(AUDIO_OUTPUT_DC_CALIB_ANA),1) +ANA_CFG_FLAGS += -DAUDIO_OUTPUT_DC_CALIB_ANA +endif + +ifeq ($(CODEC_HIGH_QUALITY),1) +ANA_CFG_FLAGS += -DCODEC_HIGH_QUALITY +PMU_CFG_FLAGS += -DCODEC_HIGH_QUALITY +endif + +ifeq ($(AUDIO_RESAMPLE),1) +ANA_CFG_FLAGS += -D__AUDIO_RESAMPLE__ +PMU_CFG_FLAGS += -D__AUDIO_RESAMPLE__ +endif + +ifeq ($(ANC_APP),1) +ANA_CFG_FLAGS += -DANC_APP +PMU_CFG_FLAGS += -DANC_APP +endif + +ifeq ($(ANC_INIT_SPEEDUP),1) +ANA_CFG_FLAGS += -DANC_INIT_SPEEDUP +endif +ifeq ($(ANC_FF_ENABLED),1) +ANA_CFG_FLAGS += -DANC_FF_ENABLED +endif +ifeq ($(ANC_FB_ENABLED),1) +ANA_CFG_FLAGS += -DANC_FB_ENABLED +endif + +ifneq ($(ANA_DC_CALIB_L),) +ANA_CFG_FLAGS += -DANA_DC_CALIB_L=$(ANA_DC_CALIB_L) +endif +ifneq ($(ANA_DC_CALIB_R),) +ANA_CFG_FLAGS += -DANA_DC_CALIB_R=$(ANA_DC_CALIB_R) +endif + +ifeq ($(DYN_ADC_GAIN),1) +ANA_CFG_FLAGS += -DDYN_ADC_GAIN +endif + diff --git a/platform/drivers/ana/analog.h b/platform/drivers/ana/analog.h new file mode 100644 index 0000000..372cf49 --- /dev/null +++ b/platform/drivers/ana/analog.h @@ -0,0 +1,117 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ANALOG_H__ +#define __ANALOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdbool.h" +#include "hal_analogif.h" +#include "hal_cmu.h" +#include "hal_aud.h" +#include "plat_addr_map.h" +#include CHIP_SPECIFIC_HDR(analog) + +#define ANALOG_DEBUG_TRACE(n, s, ...) +//TRACE(n, s, ##__VA_ARGS__) +#define ANALOG_DEBUG_TRACE_IMM(n, s, ...) TRACE_IMM(n, s, ##__VA_ARGS__) +#define ANALOG_INFO_TRACE(n, s, ...) TRACE(n, s, ##__VA_ARGS__) + +#ifndef ISPI_ANA_REG +#define ISPI_ANA_REG(reg) (reg) +#endif +#define analog_read(reg, val) hal_analogif_reg_read(ISPI_ANA_REG(reg), val) +#define analog_write(reg, val) hal_analogif_reg_write(ISPI_ANA_REG(reg), val) + +#define FLOAT_TO_PPB_INT(f) ((int)(f * 1000 * 1000 * 1000)) + +enum ANA_AUD_PLL_USER_T { + ANA_AUD_PLL_USER_CODEC = (1 << 0), + ANA_AUD_PLL_USER_I2S = (1 << 1), + ANA_AUD_PLL_USER_SPDIF = (1 << 2), + ANA_AUD_PLL_USER_PCM = (1 << 3), + + ANA_AUD_PLL_USER_END = (1 << 4), +}; + +void analog_aud_freq_pll_config(uint32_t freq, uint32_t div); + +void analog_aud_get_dc_calib_value(int16_t *dc_l, int16_t *dc_r); + +void analog_open(void); + +void analog_aud_xtal_tune(float ratio); + +void analog_aud_pll_tune(float ratio); + +void analog_aud_pll_open(enum ANA_AUD_PLL_USER_T user); + +void analog_aud_pll_close(enum ANA_AUD_PLL_USER_T user); + +void analog_aud_set_dac_gain(int32_t v); + +uint32_t analog_codec_get_dac_gain(void); + +uint32_t analog_codec_dac_gain_to_db(int32_t gain); + +int32_t analog_codec_dac_max_attn_db(void); + +void analog_aud_apply_anc_adc_gain_offset(enum ANC_TYPE_T type, int16_t offset_l, int16_t offset_r); + +void analog_aud_apply_adc_gain_offset(enum AUD_CHANNEL_MAP_T ch_map, int16_t offset); + +void analog_aud_codec_open(void); + +void analog_aud_codec_close(void); + +void analog_aud_codec_mute(void); + +void analog_aud_codec_nomute(void); + +void analog_aud_codec_adc_enable(enum AUD_IO_PATH_T input_path, enum AUD_CHANNEL_MAP_T ch_map, bool en); + +void analog_aud_codec_dac_enable(bool en); + +void analog_aud_codec_speaker_enable(bool en); + +void analog_aud_codec_anc_enable(enum ANC_TYPE_T type, bool en); + +void analog_aud_mickey_enable(bool en); + +void analog_sleep(void); + +void analog_wakeup(void); + +int analog_debug_config_audio_output(bool diff); + +int analog_debug_config_codec(uint16_t mv); + +int analog_debug_config_low_power_adc(bool enable); + +void analog_debug_config_anc_calib_mode(bool enable); + +bool analog_debug_get_anc_calib_mode(void); + +void analog_productiontest_settings_checker(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/ana/best2300p/Makefile b/platform/drivers/ana/best2300p/Makefile new file mode 100644 index 0000000..ea0e521 --- /dev/null +++ b/platform/drivers/ana/best2300p/Makefile @@ -0,0 +1,99 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) + +ifeq ($(CODEC_HIGH_QUALITY),1) +VCODEC_VOLT ?= 1.95V +else +VCODEC_VOLT ?= 1.7V +endif +ifneq ($(filter-out 1.6V 1.7V 1.8V 1.9V 1.95V,$(VCODEC_VOLT)),) +$(error Invalid VCODEC_VOLT=$(VCODEC_VOLT)) +endif +ifneq ($(VCODEC_VOLT),) +ANA_CFG_FLAGS += -DVCODEC_VOLT=$(subst V,,$(VCODEC_VOLT)) +PMU_CFG_FLAGS += -DVCODEC_VOLT=$(subst V,,$(VCODEC_VOLT)) +ifneq ($(filter 1.6V 1.7V 1.8V 1.9V 1.95V,$(VCODEC_VOLT)),) +VCODEC_OFF ?= 1 +ifeq ($(VHPPA_VOLT),) +VHPPA_VOLT := $(VCODEC_VOLT) +endif +ifneq ($(VCODEC_VOLT),$(VHPPA_VOLT)) +$(error Incompatible VCODEC_VOLT=$(VCODEC_VOLT) with VHPPA_VOLT=$(VHPPA_VOLT)) +endif +endif +endif + +ifeq ($(VCODEC_OFF),1) +PMU_CFG_FLAGS += -DVCODEC_OFF +endif + +ifeq ($(VHPPA2VCODEC),1) +PMU_CFG_FLAGS += -DVHPPA2VCODEC +endif + +ifeq ($(HPPA_LDO_ON),1) +PMU_CFG_FLAGS += -DHPPA_LDO_ON +endif + +VHPPA_VOLT ?= 1.8V +ifneq ($(filter-out 1.6V 1.7V 1.8V 1.9V 1.95V,$(VHPPA_VOLT)),) +$(error Invalid VHPPA_VOLT=$(VHPPA_VOLT)) +endif +ifneq ($(VHPPA_VOLT),) +PMU_CFG_FLAGS += -DVHPPA_VOLT=$(subst V,,$(VHPPA_VOLT)) +endif + +HIGH_VCORE ?= 1 +ifeq ($(HIGH_VCORE),1) +PMU_CFG_FLAGS += -DHIGH_VCORE +endif + +ifeq ($(USE_CYBERON),1) +PMU_CFG_FLAGS += -DUSE_CYBERON +endif + +ifneq ($(EFUSE_BLOCK_NUM),) +PMU_CFG_FLAGS += -DEFUSE_BLOCK_NUM=$(EFUSE_BLOCK_NUM) +endif + +ifeq ($(LBRT),1) +VANA_VOLT ?= 1.4V +else +VANA_VOLT ?= 1.3V +endif +ifneq ($(filter-out 1.2V 1.3V 1.35V 1.4V 1.5V 1.6V,$(VANA_VOLT)),) +$(error Invalid VANA_VOLT=$(VANA_VOLT)) +endif +ifneq ($(VANA_VOLT),) +VANA_STEM := $(subst .,P,$(VANA_VOLT)) +PMU_CFG_FLAGS += -DVANA_$(VANA_STEM) +endif + +LOW_POWER_ADC ?= 1 +ifeq ($(LOW_POWER_ADC),1) +ANA_CFG_FLAGS += -DLOW_POWER_ADC +endif + +ifeq ($(DAC_DRE_GAIN_DC_UPDATE),1) +ANA_CFG_FLAGS += -DDAC_DRE_GAIN_DC_UPDATE +endif + +ifeq ($(AUDIO_USE_BBPLL),1) +ANA_CFG_FLAGS += -DAUDIO_USE_BBPLL +PMU_CFG_FLAGS += -DAUDIO_USE_BBPLL +endif + +ifeq ($(USB_USE_USBPLL),1) +PMU_CFG_FLAGS += -DUSB_USE_USBPLL +USBPHY_CFG_FLAGS += -DUSB_USE_USBPLL +endif + +CFLAGS_pmu_$(CHIP).o += $(PMU_CFG_FLAGS) + +CFLAGS_analog_$(CHIP).o += $(ANA_CFG_FLAGS) + +CFLAGS_usbphy_$(CHIP).o += $(USBPHY_CFG_FLAGS) + diff --git a/platform/drivers/ana/best2300p/analog_best2300p.c b/platform/drivers/ana/best2300p/analog_best2300p.c new file mode 100644 index 0000000..3dda018 --- /dev/null +++ b/platform/drivers/ana/best2300p/analog_best2300p.c @@ -0,0 +1,2297 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "analog.h" +#include "cmsis.h" +#ifdef RTOS +#include "cmsis_os.h" +#endif +#include "hal_chipid.h" +#include "hal_cmu.h" +#include "hal_codec.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "pmu.h" +#include "tgt_hardware.h" + + +#define VCM_ON + +// Not using 1uF +#define VCM_CAP_100NF + +#if defined(CODEC_HIGH_QUALITY) +#undef LOW_CODEC_BIAS +#else +#define LOW_CODEC_BIAS +#endif + +#define DAC_DC_CALIB_BIT_WIDTH 14 + +#define DEFAULT_ANC_FF_ADC_GAIN_DB 6 +#define DEFAULT_ANC_FB_ADC_GAIN_DB 6 +#define DEFAULT_VOICE_ADC_GAIN_DB 12 + +#ifndef ANALOG_ADC_A_GAIN_DB +#if defined(ANC_APP) && defined(ANC_FF_ENABLED) && ((ANC_FF_MIC_CH_L == AUD_CHANNEL_MAP_CH0) || (ANC_FF_MIC_CH_R == AUD_CHANNEL_MAP_CH0)) +#define ANALOG_ADC_A_GAIN_DB DEFAULT_ANC_FF_ADC_GAIN_DB +#elif defined(ANC_APP) && defined(ANC_FB_ENABLED) && ((ANC_FB_MIC_CH_L == AUD_CHANNEL_MAP_CH0) || (ANC_FB_MIC_CH_R == AUD_CHANNEL_MAP_CH0)) +#define ANALOG_ADC_A_GAIN_DB DEFAULT_ANC_FB_ADC_GAIN_DB +#else +#define ANALOG_ADC_A_GAIN_DB DEFAULT_VOICE_ADC_GAIN_DB +#endif +#endif + +#ifndef ANALOG_ADC_B_GAIN_DB +#if defined(ANC_APP) && defined(ANC_FF_ENABLED) && ((ANC_FF_MIC_CH_L == AUD_CHANNEL_MAP_CH1) || (ANC_FF_MIC_CH_R == AUD_CHANNEL_MAP_CH1)) +#define ANALOG_ADC_B_GAIN_DB DEFAULT_ANC_FF_ADC_GAIN_DB +#elif defined(ANC_APP) && defined(ANC_FB_ENABLED) && ((ANC_FB_MIC_CH_L == AUD_CHANNEL_MAP_CH1) || (ANC_FB_MIC_CH_R == AUD_CHANNEL_MAP_CH1)) +#define ANALOG_ADC_B_GAIN_DB DEFAULT_ANC_FB_ADC_GAIN_DB +#else +#define ANALOG_ADC_B_GAIN_DB DEFAULT_VOICE_ADC_GAIN_DB +#endif +#endif + +#ifndef ANALOG_ADC_C_GAIN_DB +#if defined(ANC_APP) && defined(ANC_FF_ENABLED) && ((ANC_FF_MIC_CH_L == AUD_CHANNEL_MAP_CH2) || (ANC_FF_MIC_CH_R == AUD_CHANNEL_MAP_CH2)) +#define ANALOG_ADC_C_GAIN_DB DEFAULT_ANC_FF_ADC_GAIN_DB +#elif defined(ANC_APP) && defined(ANC_FB_ENABLED) && ((ANC_FB_MIC_CH_L == AUD_CHANNEL_MAP_CH2) || (ANC_FB_MIC_CH_R == AUD_CHANNEL_MAP_CH2)) +#define ANALOG_ADC_C_GAIN_DB DEFAULT_ANC_FB_ADC_GAIN_DB +#else +#define ANALOG_ADC_C_GAIN_DB DEFAULT_VOICE_ADC_GAIN_DB +#endif +#endif + +#ifndef ANALOG_ADC_D_GAIN_DB +#if defined(ANC_APP) && defined(ANC_FF_ENABLED) && ((ANC_FF_MIC_CH_L == AUD_CHANNEL_MAP_CH3) || (ANC_FF_MIC_CH_R == AUD_CHANNEL_MAP_CH3)) +#define ANALOG_ADC_D_GAIN_DB DEFAULT_ANC_FF_ADC_GAIN_DB +#elif defined(ANC_APP) && defined(ANC_FB_ENABLED) && ((ANC_FB_MIC_CH_L == AUD_CHANNEL_MAP_CH3) || (ANC_FB_MIC_CH_R == AUD_CHANNEL_MAP_CH3)) +#define ANALOG_ADC_D_GAIN_DB DEFAULT_ANC_FB_ADC_GAIN_DB +#else +#define ANALOG_ADC_D_GAIN_DB DEFAULT_VOICE_ADC_GAIN_DB +#endif +#endif + +#ifndef ANALOG_ADC_E_GAIN_DB +#if defined(ANC_APP) && defined(ANC_FF_ENABLED) && ((ANC_FF_MIC_CH_L == AUD_CHANNEL_MAP_CH4) || (ANC_FF_MIC_CH_R == AUD_CHANNEL_MAP_CH4)) +#define ANALOG_ADC_E_GAIN_DB DEFAULT_ANC_FF_ADC_GAIN_DB +#elif defined(ANC_APP) && defined(ANC_FB_ENABLED) && ((ANC_FB_MIC_CH_L == AUD_CHANNEL_MAP_CH4) || (ANC_FB_MIC_CH_R == AUD_CHANNEL_MAP_CH4)) +#define ANALOG_ADC_E_GAIN_DB DEFAULT_ANC_FB_ADC_GAIN_DB +#else +#define ANALOG_ADC_E_GAIN_DB DEFAULT_VOICE_ADC_GAIN_DB +#endif +#endif + +#ifndef LINEIN_ADC_GAIN_DB +#define LINEIN_ADC_GAIN_DB 0 +#endif + +#ifndef CFG_HW_AUD_MICKEY_DEV +#define CFG_HW_AUD_MICKEY_DEV (AUD_VMIC_MAP_VMIC1) +#endif + +#ifndef ANC_VMIC_CFG +#define ANC_VMIC_CFG (AUD_VMIC_MAP_VMIC1) +#endif + +// 61 +#define REG_CODEC_EN_ADCA (1 << 0) +#define REG_CODEC_EN_ADCB (1 << 1) +#define REG_CODEC_EN_ADCC (1 << 2) +#define REG_CODEC_EN_ADCD (1 << 3) +#define REG_CODEC_ADCA_DITHER_EN (1 << 4) +#define REG_CODEC_ADCB_DITHER_EN (1 << 5) +#define REG_CODEC_ADCC_DITHER_EN (1 << 6) +#define REG_CODEC_ADCD_DITHER_EN (1 << 7) +#define REG_CODEC_ADCA_CH_SEL_SHIFT 8 +#define REG_CODEC_ADCA_CH_SEL_MASK (0x3 << REG_CODEC_ADCA_CH_SEL_SHIFT) +#define REG_CODEC_ADCA_CH_SEL(n) BITFIELD_VAL(REG_CODEC_ADCA_CH_SEL, n) +#define REG_CODEC_ADCB_CH_SEL_SHIFT 10 +#define REG_CODEC_ADCB_CH_SEL_MASK (0x3 << REG_CODEC_ADCB_CH_SEL_SHIFT) +#define REG_CODEC_ADCB_CH_SEL(n) BITFIELD_VAL(REG_CODEC_ADCB_CH_SEL, n) +#define REG_CODEC_ADCC_CH_SEL_SHIFT 12 +#define REG_CODEC_ADCC_CH_SEL_MASK (0x3 << REG_CODEC_ADCC_CH_SEL_SHIFT) +#define REG_CODEC_ADCC_CH_SEL(n) BITFIELD_VAL(REG_CODEC_ADCC_CH_SEL, n) +#define REG_CODEC_ADCD_CH_SEL_SHIFT 14 +#define REG_CODEC_ADCD_CH_SEL_MASK (0x3 << REG_CODEC_ADCD_CH_SEL_SHIFT) +#define REG_CODEC_ADCD_CH_SEL(n) BITFIELD_VAL(REG_CODEC_ADCD_CH_SEL, n) + +// 62 +#define REG_CODEC_RESET_ADCA (1 << 0) +#define REG_CODEC_RESET_ADCB (1 << 1) +#define REG_CODEC_RESET_ADCC (1 << 2) +#define REG_CODEC_RESET_ADCD (1 << 3) +#define CFG_RESET_ADCA_DR (1 << 4) +#define CFG_RESET_ADCB_DR (1 << 5) +#define CFG_RESET_ADCC_DR (1 << 6) +#define CFG_RESET_ADCD_DR (1 << 7) +#define REG_RX_PGAA_RESET (1 << 8) +#define REG_RX_PGAB_RESET (1 << 9) +#define REG_RX_PGAC_RESET (1 << 10) +#define REG_RX_PGAD_RESET (1 << 11) +#define CFG_RESET_PGAA_DR (1 << 12) +#define CFG_RESET_PGAB_DR (1 << 13) +#define CFG_RESET_PGAC_DR (1 << 14) +#define CFG_RESET_PGAD_DR (1 << 15) + +// 63 +#define REG_CODEC_ADCA_GAIN_BIT_SHIFT 0 +#define REG_CODEC_ADCA_GAIN_BIT_MASK (0x7 << REG_CODEC_ADCA_GAIN_BIT_SHIFT) +#define REG_CODEC_ADCA_GAIN_BIT(n) BITFIELD_VAL(REG_CODEC_ADCA_GAIN_BIT, n) +#define REG_CODEC_ADCB_GAIN_BIT_SHIFT 3 +#define REG_CODEC_ADCB_GAIN_BIT_MASK (0x7 << REG_CODEC_ADCB_GAIN_BIT_SHIFT) +#define REG_CODEC_ADCB_GAIN_BIT(n) BITFIELD_VAL(REG_CODEC_ADCB_GAIN_BIT, n) +#define REG_CODEC_ADCC_GAIN_BIT_SHIFT 6 +#define REG_CODEC_ADCC_GAIN_BIT_MASK (0x7 << REG_CODEC_ADCC_GAIN_BIT_SHIFT) +#define REG_CODEC_ADCC_GAIN_BIT(n) BITFIELD_VAL(REG_CODEC_ADCC_GAIN_BIT, n) +#define REG_CODEC_ADCD_GAIN_BIT_SHIFT 9 +#define REG_CODEC_ADCD_GAIN_BIT_MASK (0x7 << REG_CODEC_ADCD_GAIN_BIT_SHIFT) +#define REG_CODEC_ADCD_GAIN_BIT(n) BITFIELD_VAL(REG_CODEC_ADCD_GAIN_BIT, n) +#define REG_CODEC_ADCA_GAIN_UPDATE (1 << 12) +#define REG_CODEC_ADCB_GAIN_UPDATE (1 << 13) +#define REG_CODEC_ADCC_GAIN_UPDATE (1 << 14) +#define REG_CODEC_ADCD_GAIN_UPDATE (1 << 15) + +// 67 +#define REG_CODEC_ADC_IBSEL_REG_SHIFT 0 +#define REG_CODEC_ADC_IBSEL_REG_MASK (0xF << REG_CODEC_ADC_IBSEL_REG_SHIFT) +#define REG_CODEC_ADC_IBSEL_REG(n) BITFIELD_VAL(REG_CODEC_ADC_IBSEL_REG, n) +#define REG_CODEC_ADC_IBSEL_VCOMP_SHIFT 4 +#define REG_CODEC_ADC_IBSEL_VCOMP_MASK (0xF << REG_CODEC_ADC_IBSEL_VCOMP_SHIFT) +#define REG_CODEC_ADC_IBSEL_VCOMP(n) BITFIELD_VAL(REG_CODEC_ADC_IBSEL_VCOMP, n) +#define REG_CODEC_ADC_IBSEL_VREF_SHIFT 8 +#define REG_CODEC_ADC_IBSEL_VREF_MASK (0xF << REG_CODEC_ADC_IBSEL_VREF_SHIFT) +#define REG_CODEC_ADC_IBSEL_VREF(n) BITFIELD_VAL(REG_CODEC_ADC_IBSEL_VREF, n) +#define REG_CODEC_ADC_LPFVCM_SW_SHIFT 12 +#define REG_CODEC_ADC_LPFVCM_SW_MASK (0xF << REG_CODEC_ADC_LPFVCM_SW_SHIFT) +#define REG_CODEC_ADC_LPFVCM_SW(n) BITFIELD_VAL(REG_CODEC_ADC_LPFVCM_SW, n) + +// 68 +#define REG_CODEC_ADC_OP1_IBIT_SHIFT 0 +#define REG_CODEC_ADC_OP1_IBIT_MASK (0x3 << REG_CODEC_ADC_OP1_IBIT_SHIFT) +#define REG_CODEC_ADC_OP1_IBIT(n) BITFIELD_VAL(REG_CODEC_ADC_OP1_IBIT, n) +#define REG_CODEC_ADC_OP1_R_SEL (1 << 2) +#define REG_CODEC_ADC_OP2_IBIT_SHIFT 3 +#define REG_CODEC_ADC_OP2_IBIT_MASK (0x3 << REG_CODEC_ADC_OP2_IBIT_SHIFT) +#define REG_CODEC_ADC_OP2_IBIT(n) BITFIELD_VAL(REG_CODEC_ADC_OP2_IBIT, n) +#define REG_CODEC_ADC_OP2_R_SEL (1 << 5) +#define REG_CODEC_ADC_OP3_IBIT_SHIFT 6 +#define REG_CODEC_ADC_OP3_IBIT_MASK (0x3 << REG_CODEC_ADC_OP3_IBIT_SHIFT) +#define REG_CODEC_ADC_OP3_IBIT(n) BITFIELD_VAL(REG_CODEC_ADC_OP3_IBIT, n) +#define REG_CODEC_ADC_OP3_R_SEL (1 << 8) +#define REG_CODEC_ADC_OP4_IBIT_SHIFT 9 +#define REG_CODEC_ADC_OP4_IBIT_MASK (0x3 << REG_CODEC_ADC_OP4_IBIT_SHIFT) +#define REG_CODEC_ADC_OP4_IBIT(n) BITFIELD_VAL(REG_CODEC_ADC_OP4_IBIT, n) +#define REG_CODEC_ADC_OP4_R_SEL (1 << 11) +#define REG_CODEC_ADC_VREF_SEL_SHIFT 12 +#define REG_CODEC_ADC_VREF_SEL_MASK (0xF << REG_CODEC_ADC_VREF_SEL_SHIFT) +#define REG_CODEC_ADC_VREF_SEL(n) BITFIELD_VAL(REG_CODEC_ADC_VREF_SEL, n) + +// 69 +#define REG_CODEC_BIAS_IBSEL_SHIFT 0 +#define REG_CODEC_BIAS_IBSEL_MASK (0xF << REG_CODEC_BIAS_IBSEL_SHIFT) +#define REG_CODEC_BIAS_IBSEL(n) BITFIELD_VAL(REG_CODEC_BIAS_IBSEL, n) +#define REG_CODEC_BIAS_IBSEL_TX_SHIFT 4 +#define REG_CODEC_BIAS_IBSEL_TX_MASK (0xF << REG_CODEC_BIAS_IBSEL_TX_SHIFT) +#define REG_CODEC_BIAS_IBSEL_TX(n) BITFIELD_VAL(REG_CODEC_BIAS_IBSEL_TX, n) +#define REG_CODEC_BIAS_IBSEL_VOICE_SHIFT 8 +#define REG_CODEC_BIAS_IBSEL_VOICE_MASK (0xF << REG_CODEC_BIAS_IBSEL_VOICE_SHIFT) +#define REG_CODEC_BIAS_IBSEL_VOICE(n) BITFIELD_VAL(REG_CODEC_BIAS_IBSEL_VOICE, n) +#define REG_CODEC_BIAS_LOWV (1 << 12) +#define REG_CODEC_BIAS_LOWV_LP (1 << 13) +#define REG_CODEC_BUF_LOWPOWER (1 << 14) +#define REG_CODEC_BUF_LOWPOWER2 (1 << 15) + +// 6A +#define REG_CODEC_ADC_REG_VSEL_SHIFT 0 +#define REG_CODEC_ADC_REG_VSEL_MASK (0x7 << REG_CODEC_ADC_REG_VSEL_SHIFT) +#define REG_CODEC_ADC_REG_VSEL(n) BITFIELD_VAL(REG_CODEC_ADC_REG_VSEL, n) +#define REG_CODEC_ADC_RES_SEL_SHIFT 3 +#define REG_CODEC_ADC_RES_SEL_MASK (0x7 << REG_CODEC_ADC_RES_SEL_SHIFT) +#define REG_CODEC_ADC_RES_SEL(n) BITFIELD_VAL(REG_CODEC_ADC_RES_SEL, n) +#define REG_CODEC_BUF_LOWVCM_SHIFT 6 +#define REG_CODEC_BUF_LOWVCM_MASK (0x7 << REG_CODEC_BUF_LOWVCM_SHIFT) +#define REG_CODEC_BUF_LOWVCM(n) BITFIELD_VAL(REG_CODEC_BUF_LOWVCM, n) +#define REG_CODEC_EN_BIAS (1 << 9) +#define REG_CODEC_EN_BIAS_LP (1 << 10) +#define REG_CODEC_EN_RX_EXT (1 << 11) +#define REG_CODEC_EN_TX_EXT (1 << 12) +#define REG_CODEC_DAC_CLK_EDGE_SEL (1 << 13) +#define CFG_TX_CH0_MUTE (1 << 14) +#define CFG_TX_CH1_MUTE (1 << 15) + +// 6B +#define REG_CODEC_EN_VCM (1 << 0) +#define REG_CODEC_VCM_EN_LPF (1 << 1) +#define REG_CODEC_LP_VCM (1 << 2) +#define REG_CODEC_VCM_LOW_VCM_SHIFT 3 +#define REG_CODEC_VCM_LOW_VCM_MASK (0xF << REG_CODEC_VCM_LOW_VCM_SHIFT) +#define REG_CODEC_VCM_LOW_VCM(n) BITFIELD_VAL(REG_CODEC_VCM_LOW_VCM, n) +#define REG_CODEC_VCM_LOW_VCM_LP_SHIFT 7 +#define REG_CODEC_VCM_LOW_VCM_LP_MASK (0xF << REG_CODEC_VCM_LOW_VCM_LP_SHIFT) +#define REG_CODEC_VCM_LOW_VCM_LP(n) BITFIELD_VAL(REG_CODEC_VCM_LOW_VCM_LP, n) +#define REG_CODEC_VCM_LOW_VCM_LPF_SHIFT 11 +#define REG_CODEC_VCM_LOW_VCM_LPF_MASK (0xF << REG_CODEC_VCM_LOW_VCM_LPF_SHIFT) +#define REG_CODEC_VCM_LOW_VCM_LPF(n) BITFIELD_VAL(REG_CODEC_VCM_LOW_VCM_LPF, n) +#define REG_CODEC_EN_VCM_BUFFER (1 << 15) + +// 6C +#define REG_CODEC_RX_EN_VTOI (1 << 0) +#define REG_CODEC_RX_VTOI_I_DAC2_SHIFT 1 +#define REG_CODEC_RX_VTOI_I_DAC2_MASK (0x7 << REG_CODEC_RX_VTOI_I_DAC2_SHIFT) +#define REG_CODEC_RX_VTOI_I_DAC2(n) BITFIELD_VAL(REG_CODEC_RX_VTOI_I_DAC2, n) +#define REG_CODEC_RX_VTOI_IDAC_SEL_SHIFT 4 +#define REG_CODEC_RX_VTOI_IDAC_SEL_MASK (0xF << REG_CODEC_RX_VTOI_IDAC_SEL_SHIFT) +#define REG_CODEC_RX_VTOI_IDAC_SEL(n) BITFIELD_VAL(REG_CODEC_RX_VTOI_IDAC_SEL, n) +#define REG_CODEC_RX_VTOI_VCS_SEL_SHIFT 8 +#define REG_CODEC_RX_VTOI_VCS_SEL_MASK (0x1F << REG_CODEC_RX_VTOI_VCS_SEL_SHIFT) +#define REG_CODEC_RX_VTOI_VCS_SEL(n) BITFIELD_VAL(REG_CODEC_RX_VTOI_VCS_SEL, n) +#define REG_CODEC_ADCA_RES_2P5K_DR (1 << 13) +#define REG_CODEC_ADCB_RES_2P5K_DR (1 << 14) +#define REG_CODEC_ADCC_RES_2P5K_DR (1 << 15) + +// 6D +#define REG_CODEC_TX_DAC_MUTEL (1 << 0) +#define REG_CODEC_TX_DAC_MUTER (1 << 1) +#define REG_CODEC_TX_DAC_SWR_SHIFT 2 +#define REG_CODEC_TX_DAC_SWR_MASK (0x3 << REG_CODEC_TX_DAC_SWR_SHIFT) +#define REG_CODEC_TX_DAC_SWR(n) BITFIELD_VAL(REG_CODEC_TX_DAC_SWR, n) +#define REG_CODEC_TX_DAC_VREF_L_SHIFT 4 +#define REG_CODEC_TX_DAC_VREF_L_MASK (0xF << REG_CODEC_TX_DAC_VREF_L_SHIFT) +#define REG_CODEC_TX_DAC_VREF_L(n) BITFIELD_VAL(REG_CODEC_TX_DAC_VREF_L, n) +#define REG_CODEC_TX_DAC_VREF_R_SHIFT 8 +#define REG_CODEC_TX_DAC_VREF_R_MASK (0xF << REG_CODEC_TX_DAC_VREF_R_SHIFT) +#define REG_CODEC_TX_DAC_VREF_R(n) BITFIELD_VAL(REG_CODEC_TX_DAC_VREF_R, n) +#define REG_CODEC_TX_EAR_CAS_BIT_SHIFT 12 +#define REG_CODEC_TX_EAR_CAS_BIT_MASK (0x3 << REG_CODEC_TX_EAR_CAS_BIT_SHIFT) +#define REG_CODEC_TX_EAR_CAS_BIT(n) BITFIELD_VAL(REG_CODEC_TX_EAR_CAS_BIT, n) +#define REG_CODEC_TX_EAR_DIS_SHIFT 14 +#define REG_CODEC_TX_EAR_DIS_MASK (0x3 << REG_CODEC_TX_EAR_DIS_SHIFT) +#define REG_CODEC_TX_EAR_DIS(n) BITFIELD_VAL(REG_CODEC_TX_EAR_DIS, n) + +// 6E +#define REG_CODEC_TX_EAR_COMP_L_SHIFT 0 +#define REG_CODEC_TX_EAR_COMP_L_MASK (0x7 << REG_CODEC_TX_EAR_COMP_L_SHIFT) +#define REG_CODEC_TX_EAR_COMP_L(n) BITFIELD_VAL(REG_CODEC_TX_EAR_COMP_L, n) +#define REG_CODEC_TX_EAR_COMP_R_SHIFT 3 +#define REG_CODEC_TX_EAR_COMP_R_MASK (0x7 << REG_CODEC_TX_EAR_COMP_R_SHIFT) +#define REG_CODEC_TX_EAR_COMP_R(n) BITFIELD_VAL(REG_CODEC_TX_EAR_COMP_R, n) +#define REG_CODEC_TX_EAR_DOUBLEBIAS (1 << 6) +#define REG_CODEC_TX_EAR_DR_EN (1 << 7) +#define REG_CODEC_TX_EAR_DR_ST_SHIFT 8 +#define REG_CODEC_TX_EAR_DR_ST_MASK (0x7 << REG_CODEC_TX_EAR_DR_ST_SHIFT) +#define REG_CODEC_TX_EAR_DR_ST(n) BITFIELD_VAL(REG_CODEC_TX_EAR_DR_ST, n) +#define REG_CODEC_TX_EAR_ENBIAS (1 << 11) +#define REG_CODEC_TX_EAR_FBCAP_SHIFT 12 +#define REG_CODEC_TX_EAR_FBCAP_MASK (0x3 << REG_CODEC_TX_EAR_FBCAP_SHIFT) +#define REG_CODEC_TX_EAR_FBCAP(n) BITFIELD_VAL(REG_CODEC_TX_EAR_FBCAP, n) +#define REG_CODEC_TX_EAR_IBSEL_SHIFT 14 +#define REG_CODEC_TX_EAR_IBSEL_MASK (0x3 << REG_CODEC_TX_EAR_IBSEL_SHIFT) +#define REG_CODEC_TX_EAR_IBSEL(n) BITFIELD_VAL(REG_CODEC_TX_EAR_IBSEL, n) + +// 6F +#define REG_CODEC_TX_EAR_DRE_GAIN_L_SHIFT 0 +#define REG_CODEC_TX_EAR_DRE_GAIN_L_MASK (0x1F << REG_CODEC_TX_EAR_DRE_GAIN_L_SHIFT) +#define REG_CODEC_TX_EAR_DRE_GAIN_L(n) BITFIELD_VAL(REG_CODEC_TX_EAR_DRE_GAIN_L, n) +#define REG_CODEC_TX_EAR_DRE_GAIN_R_SHIFT 5 +#define REG_CODEC_TX_EAR_DRE_GAIN_R_MASK (0x1F << REG_CODEC_TX_EAR_DRE_GAIN_R_SHIFT) +#define REG_CODEC_TX_EAR_DRE_GAIN_R(n) BITFIELD_VAL(REG_CODEC_TX_EAR_DRE_GAIN_R, n) +#define DRE_GAIN_SEL_L (1 << 10) +#define DRE_GAIN_SEL_R (1 << 11) +#define REG_CODEC_TX_EAR_DRE_GAIN_L_UPDATE (1 << 12) +#define REG_CODEC_TX_EAR_DRE_GAIN_R_UPDATE (1 << 13) +#define REG_CODEC_TX_EAR_GAIN_SHIFT 14 +#define REG_CODEC_TX_EAR_GAIN_MASK (0x3 << REG_CODEC_TX_EAR_GAIN_SHIFT) +#define REG_CODEC_TX_EAR_GAIN(n) BITFIELD_VAL(REG_CODEC_TX_EAR_GAIN, n) + +// 70 +#define REG_CODEC_TX_EAR_LCAL (1 << 0) +#define REG_CODEC_TX_EAR_RCAL (1 << 1) +#define REG_CODEC_TX_EAR_LPBIAS (1 << 2) +#define REG_CODEC_TX_EAR_OCEN (1 << 3) +#define REG_CODEC_TX_EAR_OFFEN (1 << 4) +#define REG_CODEC_TX_EAR_OUTPUTSEL_SHIFT 5 +#define REG_CODEC_TX_EAR_OUTPUTSEL_MASK (0xF << REG_CODEC_TX_EAR_OUTPUTSEL_SHIFT) +#define REG_CODEC_TX_EAR_OUTPUTSEL(n) BITFIELD_VAL(REG_CODEC_TX_EAR_OUTPUTSEL, n) +#define REG_CODEC_TX_EAR_SOFTSTART_SHIFT 9 +#define REG_CODEC_TX_EAR_SOFTSTART_MASK (0x3F << REG_CODEC_TX_EAR_SOFTSTART_SHIFT) +#define REG_CODEC_TX_EAR_SOFTSTART(n) BITFIELD_VAL(REG_CODEC_TX_EAR_SOFTSTART, n) +#define CFG_TX_TREE_EN (1 << 15) + +// 71 +#define REG_CODEC_TX_EAR_LOWGAINL_SHIFT 0 +#define REG_CODEC_TX_EAR_LOWGAINL_MASK (0x3 << REG_CODEC_TX_EAR_LOWGAINL_SHIFT) +#define REG_CODEC_TX_EAR_LOWGAINL(n) BITFIELD_VAL(REG_CODEC_TX_EAR_LOWGAINL, n) +#define REG_CODEC_TX_EAR_OFF_BITL_SHIFT 2 +#define REG_CODEC_TX_EAR_OFF_BITL_MASK (0x3FFF << REG_CODEC_TX_EAR_OFF_BITL_SHIFT) +#define REG_CODEC_TX_EAR_OFF_BITL(n) BITFIELD_VAL(REG_CODEC_TX_EAR_OFF_BITL, n) + +// 72 +#define REG_CODEC_TX_EAR_LOWGAINR_SHIFT 0 +#define REG_CODEC_TX_EAR_LOWGAINR_MASK (0x3 << REG_CODEC_TX_EAR_LOWGAINR_SHIFT) +#define REG_CODEC_TX_EAR_LOWGAINR(n) BITFIELD_VAL(REG_CODEC_TX_EAR_LOWGAINR, n) +#define REG_CODEC_TX_EAR_OFF_BITR_SHIFT 2 +#define REG_CODEC_TX_EAR_OFF_BITR_MASK (0x3FFF << REG_CODEC_TX_EAR_OFF_BITR_SHIFT) +#define REG_CODEC_TX_EAR_OFF_BITR(n) BITFIELD_VAL(REG_CODEC_TX_EAR_OFF_BITR, n) + +// 73 +#define REG_CODEC_TX_EN_DACLDO (1 << 0) +#define REG_CODEC_TX_EN_EARPA_L (1 << 1) +#define REG_CODEC_TX_EN_EARPA_R (1 << 2) +#define REG_CODEC_TX_EN_LCLK (1 << 3) +#define REG_CODEC_TX_EN_RCLK (1 << 4) +#define REG_CODEC_TX_EN_LDAC (1 << 5) +#define REG_CODEC_TX_EN_RDAC (1 << 6) +#define REG_CODEC_TX_EN_LPPA (1 << 7) +#define REG_CODEC_TX_EN_S1PA (1 << 8) +#define REG_CODEC_TX_EN_S2PA (1 << 9) +#define REG_CODEC_TX_EN_S3PA (1 << 10) +#define REG_CODEC_TX_EN_S4PA (1 << 11) +#define REG_CODEC_TX_EN_S5PA (1 << 12) +#define REG_IDETLEAR_EN (1 << 13) +#define REG_IDETREAR_EN (1 << 14) +#define REG_CODEC_TX_SW_MODE (1 << 15) + +// 74 +#define REG_CODEC_TX_RVREF_CAP_BIT (1 << 0) +#define REG_DAC_LDO0P9_VSEL_SHIFT 1 +#define REG_DAC_LDO0P9_VSEL_MASK (0x1F << REG_DAC_LDO0P9_VSEL_SHIFT) +#define REG_DAC_LDO0P9_VSEL(n) BITFIELD_VAL(REG_DAC_LDO0P9_VSEL, n) +#define REG_BYPASS_TX_REGULATOR (1 << 6) +#define REG_PU_TX_REGULATOR (1 << 7) +#define REG_TX_REGULATOR_BIT_SHIFT 8 +#define REG_TX_REGULATOR_BIT_MASK (0xF << REG_TX_REGULATOR_BIT_SHIFT) +#define REG_TX_REGULATOR_BIT(n) BITFIELD_VAL(REG_TX_REGULATOR_BIT, n) +#define REG_TX_REG_CAP_BIT (1 << 12) +#define REG_CODEC_TX_EAR_VCM_BIT_SHIFT 13 +#define REG_CODEC_TX_EAR_VCM_BIT_MASK (0x3 << REG_CODEC_TX_EAR_VCM_BIT_SHIFT) +#define REG_CODEC_TX_EAR_VCM_BIT(n) BITFIELD_VAL(REG_CODEC_TX_EAR_VCM_BIT, n) +#define REG_CODEC_TX_EAR_VCM_SEL (1 << 15) + +// 75 +#define REG_CRYSTAL_SEL_LV (1 << 0) +#define REG_EXTPLL_SEL (1 << 1) +#define REG_AUDPLL_CAL_EN (1 << 2) +#define REG_AUDPLL_CP_IEN_SHIFT 3 +#define REG_AUDPLL_CP_IEN_MASK (0xF << REG_AUDPLL_CP_IEN_SHIFT) +#define REG_AUDPLL_CP_IEN(n) BITFIELD_VAL(REG_AUDPLL_CP_IEN, n) +#define REG_AUDPLL_CP_SWRC_SHIFT 7 +#define REG_AUDPLL_CP_SWRC_MASK (0x3 << REG_AUDPLL_CP_SWRC_SHIFT) +#define REG_AUDPLL_CP_SWRC(n) BITFIELD_VAL(REG_AUDPLL_CP_SWRC, n) +#define REG_AUDPLL_DIG_SWRC_SHIFT 9 +#define REG_AUDPLL_DIG_SWRC_MASK (0x3 << REG_AUDPLL_DIG_SWRC_SHIFT) +#define REG_AUDPLL_DIG_SWRC(n) BITFIELD_VAL(REG_AUDPLL_DIG_SWRC, n) +#define REG_AUDPLL_VCO_SPD_SHIFT 11 +#define REG_AUDPLL_VCO_SPD_MASK (0x7 << REG_AUDPLL_VCO_SPD_SHIFT) +#define REG_AUDPLL_VCO_SPD(n) BITFIELD_VAL(REG_AUDPLL_VCO_SPD, n) +#define REG_AUDPLL_VCO_SWRC_SHIFT 14 +#define REG_AUDPLL_VCO_SWRC_MASK (0x3 << REG_AUDPLL_VCO_SWRC_SHIFT) +#define REG_AUDPLL_VCO_SWRC(n) BITFIELD_VAL(REG_AUDPLL_VCO_SWRC, n) + +// 7A +#define REG_PU_OSC (1 << 0) +#define REG_BBPLL_TST_EN (1 << 1) +#define REG_AUDPLL_TRIGGER_EN (1 << 2) +#define REG_AUDPLL_FREQ_EN (1 << 3) +#define REG_AUDPLL_CLK_FBC_EDGE (1 << 4) +#define REG_AUDPLL_INT_DEC_SEL_SHIFT 5 +#define REG_AUDPLL_INT_DEC_SEL_MASK (0x7 << REG_AUDPLL_INT_DEC_SEL_SHIFT) +#define REG_AUDPLL_INT_DEC_SEL(n) BITFIELD_VAL(REG_AUDPLL_INT_DEC_SEL, n) +#define REG_AUDPLL_DITHER_BYPASS (1 << 8) +#define REG_AUDPLL_PRESCALER_DEL_SEL_SHIFT 9 +#define REG_AUDPLL_PRESCALER_DEL_SEL_MASK (0xF << REG_AUDPLL_PRESCALER_DEL_SEL_SHIFT) +#define REG_AUDPLL_PRESCALER_DEL_SEL(n) BITFIELD_VAL(REG_AUDPLL_PRESCALER_DEL_SEL, n) +#define REG_AUDPLL_FREQ_34_32_SHIFT 13 +#define REG_AUDPLL_FREQ_34_32_MASK (0x7 << REG_AUDPLL_FREQ_34_32_SHIFT) +#define REG_AUDPLL_FREQ_34_32(n) BITFIELD_VAL(REG_AUDPLL_FREQ_34_32, n) + +// 7E +#define REG_CLKMUX_DVDD_SEL (1 << 0) +#define REG_CLKMUX_LDO0P9_VSEL_SHIFT 1 +#define REG_CLKMUX_LDO0P9_VSEL_MASK (0x1F << REG_CLKMUX_LDO0P9_VSEL_SHIFT) +#define REG_CLKMUX_LDO0P9_VSEL(n) BITFIELD_VAL(REG_CLKMUX_LDO0P9_VSEL, n) +#define REG_PU_CLKMUX_LDO0P9 (1 << 6) +#define REG_AUDPLL_LDO_VREF_SHIFT 7 +#define REG_AUDPLL_LDO_VREF_MASK (0x7 << REG_AUDPLL_LDO_VREF_SHIFT) +#define REG_AUDPLL_LDO_VREF(n) BITFIELD_VAL(REG_AUDPLL_LDO_VREF, n) +#define REG_AUDPLL_LPF_BW_SEL (1 << 10) +#define REG_CODEC_ADC_DITHER0P5_EN (1 << 11) +#define REG_CODEC_ADC_DITHER0P25_EN (1 << 12) +#define REG_CODEC_ADC_DITHER1_EN (1 << 13) +#define REG_CODEC_ADC_DITHER2_EN (1 << 14) +#define REG_CODEC_ADC_DITHER_PHASE_SEL (1 << 15) + +// 174 +#define CFG_TX_PEAK_OFF_ADC_EN (1 << 0) +#define CFG_TX_PEAK_OFF_DAC_EN (1 << 1) +#define CFG_PEAK_DET_DR (1 << 2) +#define CFG_TX_PEAK_OFF_ADC (1 << 3) +#define CFG_TX_PEAK_OFF_DAC (1 << 4) +#define CFG_PEAK_DET_DB_DELAY_SHIFT 5 +#define CFG_PEAK_DET_DB_DELAY_MASK (0x7 << CFG_PEAK_DET_DB_DELAY_SHIFT) +#define CFG_PEAK_DET_DB_DELAY(n) BITFIELD_VAL(CFG_PEAK_DET_DB_DELAY, n) +#define REG_CODEC_TX_PEAK_DET_BIT (1 << 8) +#define REG_CODEC_TX_PEAK_NL_EN (1 << 9) +#define REG_CODEC_TX_PEAK_NR_EN (1 << 10) +#define REG_CODEC_TX_PEAK_PL_EN (1 << 11) +#define REG_CODEC_TX_PEAK_PR_EN (1 << 12) +#define CFG_TX_CLK_INV (1 << 13) +#define CFG_CODEC_DIN_L_RST (1 << 14) +#define CFG_CODEC_DIN_R_RST (1 << 15) + +// C4 +#define CODEC_RESAMPLE_CLK_BUF_PU (1 << 2) + +// 16A +#define REG_CODEC_EN_ADCE (1 << 0) +#define DIG_CODEC_ADCE_DITHER_EN (1 << 1) +#define DIG_CODEC_ADCE_CH_SEL_SHIFT 2 +#define DIG_CODEC_ADCE_CH_SEL_MASK (0x3 << DIG_CODEC_ADCE_CH_SEL_SHIFT) +#define DIG_CODEC_ADCE_CH_SEL(n) BITFIELD_VAL(DIG_CODEC_ADCE_CH_SEL, n) +#define REG_CODEC_RESET_ADCE (1 << 4) +#define CFG_RESET_ADCE_DR (1 << 5) +#define REG_CODEC_ADCE_GAIN_BIT_SHIFT 6 +#define REG_CODEC_ADCE_GAIN_BIT_MASK (0x7 << REG_CODEC_ADCE_GAIN_BIT_SHIFT) +#define REG_CODEC_ADCE_GAIN_BIT(n) BITFIELD_VAL(REG_CODEC_ADCE_GAIN_BIT, n) +#define REG_CODEC_ADCE_GAIN_UPDATE (1 << 9) +#define REG_CODEC_ADCE_RES_2P5K (1 << 10) +#define REG_CODEC_ADCE_RES_2P5K_UPDATE (1 << 11) +#define DIG_CODEC_ADCE_IDETE_EN (1 << 12) +#define REG_RX_ADCE_ZERO_DET_EN (1 << 13) +#define CFG_ADCE_DITHER_CLK_INV (1 << 14) +#define DIG_CODEC_ADCE_CLK_SEL (1 << 15) + +// 16B +#define DIG_CODEC_ADCE_IBSEL_OP1_SHIFT 0 +#define DIG_CODEC_ADCE_IBSEL_OP1_MASK (0xF << DIG_CODEC_ADCE_IBSEL_OP1_SHIFT) +#define DIG_CODEC_ADCE_IBSEL_OP1(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_OP1, n) +#define DIG_CODEC_ADCE_IBSEL_OP2_SHIFT 4 +#define DIG_CODEC_ADCE_IBSEL_OP2_MASK (0xF << DIG_CODEC_ADCE_IBSEL_OP2_SHIFT) +#define DIG_CODEC_ADCE_IBSEL_OP2(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_OP2, n) +#define DIG_CODEC_ADCE_IBSEL_OP3_SHIFT 8 +#define DIG_CODEC_ADCE_IBSEL_OP3_MASK (0xF << DIG_CODEC_ADCE_IBSEL_OP3_SHIFT) +#define DIG_CODEC_ADCE_IBSEL_OP3(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_OP3, n) +#define DIG_CODEC_ADCE_IBSEL_OP4_SHIFT 12 +#define DIG_CODEC_ADCE_IBSEL_OP4_MASK (0xF << DIG_CODEC_ADCE_IBSEL_OP4_SHIFT) +#define DIG_CODEC_ADCE_IBSEL_OP4(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_OP4, n) + +// 16C +#define DIG_CODEC_ADCE_IBSEL_REG_SHIFT 0 +#define DIG_CODEC_ADCE_IBSEL_REG_MASK (0xF << DIG_CODEC_ADCE_IBSEL_REG_SHIFT) +#define DIG_CODEC_ADCE_IBSEL_REG(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_REG, n) +#define DIG_CODEC_ADCE_IBSEL_VCOMP_SHIFT 4 +#define DIG_CODEC_ADCE_IBSEL_VCOMP_MASK (0xF << DIG_CODEC_ADCE_IBSEL_VCOMP_SHIFT) +#define DIG_CODEC_ADCE_IBSEL_VCOMP(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_VCOMP, n) +#define DIG_CODEC_ADCE_IBSEL_VREF_SHIFT 8 +#define DIG_CODEC_ADCE_IBSEL_VREF_MASK (0xF << DIG_CODEC_ADCE_IBSEL_VREF_SHIFT) +#define DIG_CODEC_ADCE_IBSEL_VREF(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_VREF, n) +#define DIG_CODEC_ADCE_IBSEL_VREFBUF_SHIFT 12 +#define DIG_CODEC_ADCE_IBSEL_VREFBUF_MASK (0xF << DIG_CODEC_ADCE_IBSEL_VREFBUF_SHIFT) +#define DIG_CODEC_ADCE_IBSEL_VREFBUF(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_VREFBUF, n) + +// 16D +#define DIG_CODEC_ADCE_IBSEL_IDAC2_SHIFT 0 +#define DIG_CODEC_ADCE_IBSEL_IDAC2_MASK (0xF << DIG_CODEC_ADCE_IBSEL_IDAC2_SHIFT) +#define DIG_CODEC_ADCE_IBSEL_IDAC2(n) BITFIELD_VAL(DIG_CODEC_ADCE_IBSEL_IDAC2, n) +#define DIG_CODEC_ADCE_OP1_IBIT_SHIFT 4 +#define DIG_CODEC_ADCE_OP1_IBIT_MASK (0x3 << DIG_CODEC_ADCE_OP1_IBIT_SHIFT) +#define DIG_CODEC_ADCE_OP1_IBIT(n) BITFIELD_VAL(DIG_CODEC_ADCE_OP1_IBIT, n) +#define DIG_CODEC_ADCE_OP1_R_SEL (1 << 6) +#define DIG_CODEC_ADCE_OP2_IBIT_SHIFT 7 +#define DIG_CODEC_ADCE_OP2_IBIT_MASK (0x3 << DIG_CODEC_ADCE_OP2_IBIT_SHIFT) +#define DIG_CODEC_ADCE_OP2_IBIT(n) BITFIELD_VAL(DIG_CODEC_ADCE_OP2_IBIT, n) +#define DIG_CODEC_ADCE_OP2_R_SEL (1 << 9) +#define DIG_CODEC_ADCE_OP3_IBIT_SHIFT 10 +#define DIG_CODEC_ADCE_OP3_IBIT_MASK (0x3 << DIG_CODEC_ADCE_OP3_IBIT_SHIFT) +#define DIG_CODEC_ADCE_OP3_IBIT(n) BITFIELD_VAL(DIG_CODEC_ADCE_OP3_IBIT, n) +#define DIG_CODEC_ADCE_OP3_R_SEL (1 << 12) +#define DIG_CODEC_ADCE_OP4_IBIT_SHIFT 13 +#define DIG_CODEC_ADCE_OP4_IBIT_MASK (0x3 << DIG_CODEC_ADCE_OP4_IBIT_SHIFT) +#define DIG_CODEC_ADCE_OP4_IBIT(n) BITFIELD_VAL(DIG_CODEC_ADCE_OP4_IBIT, n) +#define DIG_CODEC_ADCE_OP4_R_SEL (1 << 15) + +// 16E +#define DIG_CODEC_ADCE_VREF_SEL_SHIFT 0 +#define DIG_CODEC_ADCE_VREF_SEL_MASK (0xF << DIG_CODEC_ADCE_VREF_SEL_SHIFT) +#define DIG_CODEC_ADCE_VREF_SEL(n) BITFIELD_VAL(DIG_CODEC_ADCE_VREF_SEL, n) +#define DIG_CODEC_ADCE_VREFBUF_BIT_SHIFT 4 +#define DIG_CODEC_ADCE_VREFBUF_BIT_MASK (0xF << DIG_CODEC_ADCE_VREFBUF_BIT_SHIFT) +#define DIG_CODEC_ADCE_VREFBUF_BIT(n) BITFIELD_VAL(DIG_CODEC_ADCE_VREFBUF_BIT, n) +#define DIG_CODEC_ADCE_REG_VSEL_SHIFT 8 +#define DIG_CODEC_ADCE_REG_VSEL_MASK (0x7 << DIG_CODEC_ADCE_REG_VSEL_SHIFT) +#define DIG_CODEC_ADCE_REG_VSEL(n) BITFIELD_VAL(DIG_CODEC_ADCE_REG_VSEL, n) +#define DIG_CODEC_ADCE_CAP_BIT (1 << 11) +#define REG_VOICE_SEL_VREF_BIN_SHIFT 12 +#define REG_VOICE_SEL_VREF_BIN_MASK (0xF << REG_VOICE_SEL_VREF_BIN_SHIFT) +#define REG_VOICE_SEL_VREF_BIN(n) BITFIELD_VAL(REG_VOICE_SEL_VREF_BIN, n) + +// 16F +#define REG_VOICE_LP_COMP_SHIFT 0 +#define REG_VOICE_LP_COMP_MASK (0x7 << REG_VOICE_LP_COMP_SHIFT) +#define REG_VOICE_LP_COMP(n) BITFIELD_VAL(REG_VOICE_LP_COMP, n) +#define REG_VOICE_LP_AMPA_SHIFT 3 +#define REG_VOICE_LP_AMPA_MASK (0x7 << REG_VOICE_LP_AMPA_SHIFT) +#define REG_VOICE_LP_AMPA(n) BITFIELD_VAL(REG_VOICE_LP_AMPA, n) +#define REG_VOICE_LP_AMPB_SHIFT 6 +#define REG_VOICE_LP_AMPB_MASK (0x7 << REG_VOICE_LP_AMPB_SHIFT) +#define REG_VOICE_LP_AMPB(n) BITFIELD_VAL(REG_VOICE_LP_AMPB, n) +#define REG_VOICE_LP_LDO_SHIFT 9 +#define REG_VOICE_LP_LDO_MASK (0x7 << REG_VOICE_LP_LDO_SHIFT) +#define REG_VOICE_LP_LDO(n) BITFIELD_VAL(REG_VOICE_LP_LDO, n) +#define REG_VOICE_LP_VREF_SHIFT 12 +#define REG_VOICE_LP_VREF_MASK (0x7 << REG_VOICE_LP_VREF_SHIFT) +#define REG_VOICE_LP_VREF(n) BITFIELD_VAL(REG_VOICE_LP_VREF, n) +#define CFG_REG_VOICE_TRIG_ADCE_EN (1 << 15) + +// 170 +#define REG_VOICE_HIGH_TUNE_A_SHIFT 0 +#define REG_VOICE_HIGH_TUNE_A_MASK (0xF << REG_VOICE_HIGH_TUNE_A_SHIFT) +#define REG_VOICE_HIGH_TUNE_A(n) BITFIELD_VAL(REG_VOICE_HIGH_TUNE_A, n) +#define REG_VOICE_HIGH_TUNE_B_SHIFT 4 +#define REG_VOICE_HIGH_TUNE_B_MASK (0xF << REG_VOICE_HIGH_TUNE_B_SHIFT) +#define REG_VOICE_HIGH_TUNE_B(n) BITFIELD_VAL(REG_VOICE_HIGH_TUNE_B, n) +#define REG_VOICE_GAIN_A_SHIFT 8 +#define REG_VOICE_GAIN_A_MASK (0x7 << REG_VOICE_GAIN_A_SHIFT) +#define REG_VOICE_GAIN_A(n) BITFIELD_VAL(REG_VOICE_GAIN_A, n) +#define REG_VOICE_GAIN_B_SHIFT 11 +#define REG_VOICE_GAIN_B_MASK (0x7 << REG_VOICE_GAIN_B_SHIFT) +#define REG_VOICE_GAIN_B(n) BITFIELD_VAL(REG_VOICE_GAIN_B, n) +#define CFG_ADC_START (1 << 14) +#define CFG_VOICE2ADCE (1 << 15) + +// 171 +#define CFG_VOICE_POWER_ON (1 << 0) +#define CFG_VOICE_TRIG_ENABLE (1 << 1) +#define CFG_VOICE_RESET (1 << 2) +#define CFG_VOICE_DR (1 << 3) +#define CFG_VOICE_PU_DELAY_SHIFT 4 +#define CFG_VOICE_PU_DELAY_MASK (0x7 << CFG_VOICE_PU_DELAY_SHIFT) +#define CFG_VOICE_PU_DELAY(n) BITFIELD_VAL(CFG_VOICE_PU_DELAY, n) +#define CFG_VOICE_PRECH_DELAY_SHIFT 7 +#define CFG_VOICE_PRECH_DELAY_MASK (0xFF << CFG_VOICE_PRECH_DELAY_SHIFT) +#define CFG_VOICE_PRECH_DELAY(n) BITFIELD_VAL(CFG_VOICE_PRECH_DELAY, n) +#define REG_VOICE_EN_AGPIO_TEST (1 << 15) + +// 172 +#define REG_VOICE_CLK_EDGE_SEL (1 << 0) +#define REG_VOICE_PRECH (1 << 1) +#define REG_VOICE_PU (1 << 2) +#define REG_VOICE_PU_LDO (1 << 3) +#define REG_VOICE_SEL_VCM0P3_BIN_SHIFT 4 +#define REG_VOICE_SEL_VCM0P3_BIN_MASK (0x7 << REG_VOICE_SEL_VCM0P3_BIN_SHIFT) +#define REG_VOICE_SEL_VCM0P3_BIN(n) BITFIELD_VAL(REG_VOICE_SEL_VCM0P3_BIN, n) +#define REG_VOICE_SEL_VCM_BIN_SHIFT 7 +#define REG_VOICE_SEL_VCM_BIN_MASK (0xF << REG_VOICE_SEL_VCM_BIN_SHIFT) +#define REG_VOICE_SEL_VCM_BIN(n) BITFIELD_VAL(REG_VOICE_SEL_VCM_BIN, n) +#define REG_VOICE_SEL_VCMIN_BIN_SHIFT 11 +#define REG_VOICE_SEL_VCMIN_BIN_MASK (0xF << REG_VOICE_SEL_VCMIN_BIN_SHIFT) +#define REG_VOICE_SEL_VCMIN_BIN(n) BITFIELD_VAL(REG_VOICE_SEL_VCMIN_BIN, n) +#define REG_VOICE_PU_OSC (1 << 15) + +// 173 +#define REG_VOICE_LDO_VBIT_SHIFT 0 +#define REG_VOICE_LDO_VBIT_MASK (0x7 << REG_VOICE_LDO_VBIT_SHIFT) +#define REG_VOICE_LDO_VBIT(n) BITFIELD_VAL(REG_VOICE_LDO_VBIT, n) +#define REG_VOICE_OSC_FR_SHIFT 3 +#define REG_VOICE_OSC_FR_MASK (0x7 << REG_VOICE_OSC_FR_SHIFT) +#define REG_VOICE_OSC_FR(n) BITFIELD_VAL(REG_VOICE_OSC_FR, n) +#define REG_VOICE_OSC_PWR_SHIFT 6 +#define REG_VOICE_OSC_PWR_MASK (0x3 << REG_VOICE_OSC_PWR_SHIFT) +#define REG_VOICE_OSC_PWR(n) BITFIELD_VAL(REG_VOICE_OSC_PWR, n) +#define CFG_VOICE_DET_DELAY_SHIFT 8 +#define CFG_VOICE_DET_DELAY_MASK (0xFF << CFG_VOICE_DET_DELAY_SHIFT) +#define CFG_VOICE_DET_DELAY(n) BITFIELD_VAL(CFG_VOICE_DET_DELAY, n) + +// 174 +#define CFG_TX_PEAK_OFF_ADC_EN (1 << 0) +#define CFG_TX_PEAK_OFF_DAC_EN (1 << 1) +#define CFG_PEAK_DET_DR (1 << 2) +#define CFG_TX_PEAK_OFF_ADC (1 << 3) +#define CFG_TX_PEAK_OFF_DAC (1 << 4) +#define CFG_PEAK_DET_DB_DELAY_SHIFT 5 +#define CFG_PEAK_DET_DB_DELAY_MASK (0x7 << CFG_PEAK_DET_DB_DELAY_SHIFT) +#define CFG_PEAK_DET_DB_DELAY(n) BITFIELD_VAL(CFG_PEAK_DET_DB_DELAY, n) +#define REG_CODEC_TX_PEAK_DET_BIT (1 << 8) +#define REG_CODEC_TX_PEAK_NL_EN (1 << 9) +#define REG_CODEC_TX_PEAK_NR_EN (1 << 10) +#define REG_CODEC_TX_PEAK_PL_EN (1 << 11) +#define REG_CODEC_TX_PEAK_PR_EN (1 << 12) +#define CFG_TX_CLK_INV (1 << 13) +#define CFG_CODEC_DIN_L_RST (1 << 14) +#define CFG_CODEC_DIN_R_RST (1 << 15) + +// 175 +#define CODEC_DIN_L_HI_RSTVAL_SHIFT 0 +#define CODEC_DIN_L_HI_RSTVAL_MASK (0xFFFF << CODEC_DIN_L_HI_RSTVAL_SHIFT) +#define CODEC_DIN_L_HI_RSTVAL(n) BITFIELD_VAL(CODEC_DIN_L_HI_RSTVAL, n) + +// 176 +#define CODEC_DIN_L_LO_RSTVAL_SHIFT 0 +#define CODEC_DIN_L_LO_RSTVAL_MASK (0xFFFF << CODEC_DIN_L_LO_RSTVAL_SHIFT) +#define CODEC_DIN_L_LO_RSTVAL(n) BITFIELD_VAL(CODEC_DIN_L_LO_RSTVAL, n) + +// 177 +#define CODEC_DIN_R_HI_RSTVAL_SHIFT 0 +#define CODEC_DIN_R_HI_RSTVAL_MASK (0xFFFF << CODEC_DIN_R_HI_RSTVAL_SHIFT) +#define CODEC_DIN_R_HI_RSTVAL(n) BITFIELD_VAL(CODEC_DIN_R_HI_RSTVAL, n) + +// 178 +#define CODEC_DIN_R_LO_RSTVAL_SHIFT 0 +#define CODEC_DIN_R_LO_RSTVAL_MASK (0xFFFF << CODEC_DIN_R_LO_RSTVAL_SHIFT) +#define CODEC_DIN_R_LO_RSTVAL(n) BITFIELD_VAL(CODEC_DIN_R_LO_RSTVAL, n) + +// 179 +#define REG_AUDPLL_LDOPRECHG_TIMER_SHIFT 0 +#define REG_AUDPLL_LDOPRECHG_TIMER_MASK (0x1F << REG_AUDPLL_LDOPRECHG_TIMER_SHIFT) +#define REG_AUDPLL_LDOPRECHG_TIMER(n) BITFIELD_VAL(REG_AUDPLL_LDOPRECHG_TIMER, n) +#define REG_AUDPLL_PRECHG_BEGIN_TIMER_SHIFT 5 +#define REG_AUDPLL_PRECHG_BEGIN_TIMER_MASK (0x1F << REG_AUDPLL_PRECHG_BEGIN_TIMER_SHIFT) +#define REG_AUDPLL_PRECHG_BEGIN_TIMER(n) BITFIELD_VAL(REG_AUDPLL_PRECHG_BEGIN_TIMER, n) +#define REG_AUDPLL_PRECHG_END_TIMER_SHIFT 10 +#define REG_AUDPLL_PRECHG_END_TIMER_MASK (0x1F << REG_AUDPLL_PRECHG_END_TIMER_SHIFT) +#define REG_AUDPLL_PRECHG_END_TIMER(n) BITFIELD_VAL(REG_AUDPLL_PRECHG_END_TIMER, n) +#define REG_CODEC_ADCD_RES_2P5K_DR (1 << 15) + +// 17A +#define CFG_PRE_CHARGE_ADCE_DR (1 << 0) +#define REG_CODEC_ADCE_PRE_CHARGE (1 << 1) +#define ADCE_OPEN_TIMER_DLY_SHIFT 2 +#define ADCE_OPEN_TIMER_DLY_MASK (0xF << ADCE_OPEN_TIMER_DLY_SHIFT) +#define ADCE_OPEN_TIMER_DLY(n) BITFIELD_VAL(ADCE_OPEN_TIMER_DLY, n) +#define ADCE_PRE_CHARGE_TIMER_DLY_SHIFT 6 +#define ADCE_PRE_CHARGE_TIMER_DLY_MASK (0xFF << ADCE_PRE_CHARGE_TIMER_DLY_SHIFT) +#define ADCE_PRE_CHARGE_TIMER_DLY(n) BITFIELD_VAL(ADCE_PRE_CHARGE_TIMER_DLY, n) +#define REG_VOICE_LOW_TUNE_SHIFT 14 +#define REG_VOICE_LOW_TUNE_MASK (0x3 << REG_VOICE_LOW_TUNE_SHIFT) +#define REG_VOICE_LOW_TUNE(n) BITFIELD_VAL(REG_VOICE_LOW_TUNE, n) + +// 17B +#define REG_COARSE_EN (1 << 0) +#define REG_XTAL_FREQ_LLC_SFT_RSTN (1 << 1) +#define REG_COARSE_POLAR_SEL (1 << 2) +#define REG_AUDPLL_RSTB_TIMER_SHIFT 3 +#define REG_AUDPLL_RSTB_TIMER_MASK (0x1F << REG_AUDPLL_RSTB_TIMER_SHIFT) +#define REG_AUDPLL_RSTB_TIMER(n) BITFIELD_VAL(REG_AUDPLL_RSTB_TIMER, n) +#define RX_TIMER_RSTN_DLY_SHIFT 8 +#define RX_TIMER_RSTN_DLY_MASK (0xFF << RX_TIMER_RSTN_DLY_SHIFT) +#define RX_TIMER_RSTN_DLY(n) BITFIELD_VAL(RX_TIMER_RSTN_DLY, n) + +// 17C +#define REG_CNT_COARSE_MARK_SHIFT 0 +#define REG_CNT_COARSE_MARK_MASK (0xFFFF << REG_CNT_COARSE_MARK_SHIFT) +#define REG_CNT_COARSE_MARK(n) BITFIELD_VAL(REG_CNT_COARSE_MARK, n) + +// 17D +#define REG_CLK_GOAL_DIV_NUM_SHIFT 0 +#define REG_CLK_GOAL_DIV_NUM_MASK (0x1FF << REG_CLK_GOAL_DIV_NUM_SHIFT) +#define REG_CLK_GOAL_DIV_NUM(n) BITFIELD_VAL(REG_CLK_GOAL_DIV_NUM, n) +#define REG_COARSE_TUN_CODE_SHIFT 9 +#define REG_COARSE_TUN_CODE_MASK (0x3F << REG_COARSE_TUN_CODE_SHIFT) +#define REG_COARSE_TUN_CODE(n) BITFIELD_VAL(REG_COARSE_TUN_CODE, n) +#define REG_COARSE_TUN_CODE_DR (1 << 15) + +// 17E +#define SSC_ENABLE (1 << 0) +#define TRI_FREQ_OFST_SEL_SHIFT 1 +#define TRI_FREQ_OFST_SEL_MASK (0x7 << TRI_FREQ_OFST_SEL_SHIFT) +#define TRI_FREQ_OFST_SEL(n) BITFIELD_VAL(TRI_FREQ_OFST_SEL, n) +#define TRI_FREQ_SEL_SHIFT 4 +#define TRI_FREQ_SEL_MASK (0x3 << TRI_FREQ_SEL_SHIFT) +#define TRI_FREQ_SEL(n) BITFIELD_VAL(TRI_FREQ_SEL, n) +#define REG_VOICE_EN_REF_TEST (1 << 6) +#define REG_VOICE_GAIN_BASE_SHIFT 7 +#define REG_VOICE_GAIN_BASE_MASK (0x7 << REG_VOICE_GAIN_BASE_SHIFT) +#define REG_VOICE_GAIN_BASE(n) BITFIELD_VAL(REG_VOICE_GAIN_BASE, n) +#define CFG_VOICE_PRECH_DONE_DELAY_SHIFT 10 +#define CFG_VOICE_PRECH_DONE_DELAY_MASK (0x1F << CFG_VOICE_PRECH_DONE_DELAY_SHIFT) +#define CFG_VOICE_PRECH_DONE_DELAY(n) BITFIELD_VAL(CFG_VOICE_PRECH_DONE_DELAY, n) +#define REG_CODEC_LP_VCM_DR (1 << 15) + +// 17F +#define TX_PEAK_DET_STATUS (1 << 0) +#define TX_PEAK_DET_NL_STATUS (1 << 1) +#define TX_PEAK_DET_NR_STATUS (1 << 2) +#define TX_PEAK_DET_PL_STATUS (1 << 3) +#define TX_PEAK_DET_PR_STATUS (1 << 4) +#define DBG_STATE_SHIFT 5 +#define DBG_STATE_MASK (0x3 << DBG_STATE_SHIFT) +#define DBG_STATE(n) BITFIELD_VAL(DBG_STATE, n) + +enum ANA_REG_T { + ANA_REG_61 = 0x61, + ANA_REG_62, + ANA_REG_63, + ANA_REG_64, + ANA_REG_65, + ANA_REG_66, + ANA_REG_67, + ANA_REG_68, + ANA_REG_69, + ANA_REG_6A, + ANA_REG_6B, + ANA_REG_6C, + ANA_REG_6D, + ANA_REG_6E, + ANA_REG_6F, + ANA_REG_70, + ANA_REG_71, + ANA_REG_72, + ANA_REG_73, + ANA_REG_74, + ANA_REG_75, + ANA_REG_76, + ANA_REG_77, + ANA_REG_78, + ANA_REG_79, + ANA_REG_7A, + ANA_REG_7B, + ANA_REG_7C, + ANA_REG_7D, + ANA_REG_7E, + ANA_REG_7F, + + ANA_REG_161 = 0x161, + ANA_REG_162, + ANA_REG_163, + ANA_REG_164, + ANA_REG_165, + ANA_REG_166, + ANA_REG_167, + ANA_REG_168, + ANA_REG_169, + ANA_REG_16A, + ANA_REG_16B, + ANA_REG_16C, + ANA_REG_16D, + ANA_REG_16E, + ANA_REG_16F, + ANA_REG_170, + ANA_REG_171, + ANA_REG_172, + ANA_REG_173, + ANA_REG_174, + ANA_REG_175, + ANA_REG_176, + ANA_REG_177, + ANA_REG_178, + ANA_REG_179, + ANA_REG_17A, + ANA_REG_17B, + ANA_REG_17C, + ANA_REG_17D, + ANA_REG_17E, + ANA_REG_17F, + + ANA_REG_RF_C4 = 0xC4, +}; + +enum ANA_CODEC_USER_T { + ANA_CODEC_USER_DAC = (1 << 0), + ANA_CODEC_USER_ADC = (1 << 1), + + ANA_CODEC_USER_CODEC = (1 << 2), + ANA_CODEC_USER_MICKEY = (1 << 3), + + ANA_CODEC_USER_ANC_FF = (1 << 4), + ANA_CODEC_USER_ANC_FB = (1 << 5), + + ANA_CODEC_USER_VAD = (1 << 6), +}; + +struct ANALOG_PLL_CFG_T { + uint32_t freq; + uint8_t div; + uint64_t val; +}; + +#ifdef ANC_PROD_TEST +#define OPT_TYPE +#else +#define OPT_TYPE const +#endif + +static OPT_TYPE uint16_t vcodec_mv = (uint16_t)(VCODEC_VOLT * 1000); + +static bool ana_spk_req; +static bool ana_spk_muted; +static bool ana_spk_enabled; + +static bool anc_calib_mode; + +static enum ANA_CODEC_USER_T adc_map[MAX_ANA_MIC_CH_NUM]; +static enum ANA_CODEC_USER_T vmic_map[MAX_ANA_MIC_CH_NUM]; +static enum ANA_CODEC_USER_T codec_common_map; +static enum ANA_CODEC_USER_T adda_common_map; +static enum ANA_CODEC_USER_T vcodec_map; + +static enum ANA_AUD_PLL_USER_T ana_aud_pll_map; + +#ifdef ANC_APP +#ifndef DYN_ADC_GAIN +#define DYN_ADC_GAIN +#endif +#endif + +#ifdef DYN_ADC_GAIN +static int8_t adc_gain_offset[MAX_ANA_MIC_CH_NUM]; +#endif + +static const int8_t adc_db[] = { -9, -6, -3, 0, 3, 6, 9, 12, }; + +static const int8_t tgt_adc_db[MAX_ANA_MIC_CH_NUM] = { + ANALOG_ADC_A_GAIN_DB, ANALOG_ADC_B_GAIN_DB, + ANALOG_ADC_C_GAIN_DB, ANALOG_ADC_D_GAIN_DB, + ANALOG_ADC_E_GAIN_DB, +}; + +// Max allowed total tune ratio (5000ppm) +#define MAX_TOTAL_TUNE_RATIO 0.005000 + +static struct ANALOG_PLL_CFG_T ana_pll_cfg[2]; +static int pll_cfg_idx; + +void analog_aud_freq_pll_config(uint32_t freq, uint32_t div) +{ + // CODEC_FREQ is likely 24.576M (48K series) or 22.5792M (44.1K series) + // PLL_nominal = CODEC_FREQ * CODEC_DIV + // PLL_cfg_val = ((CODEC_FREQ * CODEC_DIV) / 26M) * (1 << 28) + + int i, j; + uint64_t PLL_cfg_val; + uint16_t high, low, bit34_32; + uint16_t val; + + if (pll_cfg_idx < ARRAY_SIZE(ana_pll_cfg) && + ana_pll_cfg[pll_cfg_idx].freq == freq && + ana_pll_cfg[pll_cfg_idx].div == div) { + return; + } + + j = ARRAY_SIZE(ana_pll_cfg); + for (i = 0; i < ARRAY_SIZE(ana_pll_cfg); i++) { + if (ana_pll_cfg[i].freq == freq && ana_pll_cfg[i].div == div) { + break; + } + if (j == ARRAY_SIZE(ana_pll_cfg) && ana_pll_cfg[i].freq == 0) { + j = i; + } + } + + if (i < ARRAY_SIZE(ana_pll_cfg)) { + pll_cfg_idx = i; + PLL_cfg_val = ana_pll_cfg[pll_cfg_idx].val; + } else { + if (j < ARRAY_SIZE(ana_pll_cfg)) { + pll_cfg_idx = j; + } else { + pll_cfg_idx = 0; + } + + PLL_cfg_val = ((uint64_t)(1 << 28) * freq * div + 26000000 / 2) / 26000000; + + ana_pll_cfg[pll_cfg_idx].freq = freq; + ana_pll_cfg[pll_cfg_idx].div = div; + ana_pll_cfg[pll_cfg_idx].val = PLL_cfg_val; + } + + low = PLL_cfg_val & 0xFFFF; + high = (PLL_cfg_val >> 16) & 0xFFFF; + bit34_32 = (PLL_cfg_val >> 32) & 0xFFFF; + + pmu_pll_div_set(HAL_CMU_PLL_AUD, PMU_PLL_DIV_CODEC, div); + + analog_write(ANA_REG_7C, low); + analog_write(ANA_REG_7B, high); + analog_read(ANA_REG_7A, &val); + val = SET_BITFIELD(val, REG_AUDPLL_FREQ_34_32, bit34_32) | REG_AUDPLL_FREQ_EN; + analog_write(ANA_REG_7A, val); +} + +void analog_aud_pll_tune(float ratio) +{ +#ifdef __AUDIO_RESAMPLE__ + if (hal_cmu_get_audio_resample_status()) { + return; + } +#endif + + // CODEC_FREQ is likely 24.576M (48K series) or 22.5792M (44.1K series) + // PLL_nominal = CODEC_FREQ * CODEC_DIV + // PLL_cfg_val = ((CODEC_FREQ * CODEC_DIV) / 26M) * (1 << 28) + // Delta = ((SampleDiff / Fs) / TimeDiff) * PLL_cfg_val + + int64_t delta, new_pll; + uint16_t new_high, new_low; + uint16_t val, new_bit34_32; + + if (pll_cfg_idx >= ARRAY_SIZE(ana_pll_cfg) || + ana_pll_cfg[pll_cfg_idx].freq == 0) { + ANALOG_INFO_TRACE(1,"%s: WARNING: aud pll config cache invalid. Skip tuning", __FUNCTION__); + return; + } + + if (ABS(ratio) > MAX_TOTAL_TUNE_RATIO) { + ANALOG_INFO_TRACE(1,"\n------\nWARNING: TUNE: ratio=%d is too large and will be cut\n------\n", FLOAT_TO_PPB_INT(ratio)); + if (ratio > 0) { + ratio = MAX_TOTAL_TUNE_RATIO; + } else { + ratio = -MAX_TOTAL_TUNE_RATIO; + } + } + + ANALOG_INFO_TRACE(2,"%s: ratio=%d", __FUNCTION__, FLOAT_TO_PPB_INT(ratio)); + + new_pll = (int64_t)ana_pll_cfg[pll_cfg_idx].val; + delta = (int64_t)(new_pll * ratio); + + new_pll += delta; + + new_low = new_pll & 0xFFFF; + new_high = (new_pll >> 16) & 0xFFFF; + new_bit34_32 = (new_pll >> 32) & 0xFFFF; + + analog_write(ANA_REG_7C, new_low); + analog_write(ANA_REG_7B, new_high); + analog_read(ANA_REG_7A, &val); + val = SET_BITFIELD(val, REG_AUDPLL_FREQ_34_32, new_bit34_32) | REG_AUDPLL_FREQ_EN; + analog_write(ANA_REG_7A, val); +} + +void analog_aud_osc_clk_enable(bool enable) +{ + uint16_t val; + + if (enable) { + analog_read(ANA_REG_RF_C4, &val); + val |= CODEC_RESAMPLE_CLK_BUF_PU; + analog_write(ANA_REG_RF_C4, val); + + analog_read(ANA_REG_7A, &val); + val |= REG_PU_OSC; + analog_write(ANA_REG_7A, val); + + analog_read(ANA_REG_75, &val); + val |= REG_CRYSTAL_SEL_LV; + analog_write(ANA_REG_75, val); +#if 0 + analog_read(ANA_REG_174, &val); + val |= CFG_TX_CLK_INV; + analog_write(ANA_REG_174, val); +#endif + } else { +#if 0 + analog_read(ANA_REG_174, &val); + val &= ~CFG_TX_CLK_INV; + analog_write(ANA_REG_174, val); +#endif + analog_read(ANA_REG_75, &val); + val &= ~REG_CRYSTAL_SEL_LV; + analog_write(ANA_REG_75, val); + + analog_read(ANA_REG_7A, &val); + val &= ~REG_PU_OSC; + analog_write(ANA_REG_7A, val); + + analog_read(ANA_REG_RF_C4, &val); + val &= ~CODEC_RESAMPLE_CLK_BUF_PU; + analog_write(ANA_REG_RF_C4, val); + } +} + +void analog_aud_pll_open(enum ANA_AUD_PLL_USER_T user) +{ + if (user >= ANA_AUD_PLL_USER_END) { + return; + } + +#ifdef __AUDIO_RESAMPLE__ + if (user == ANA_AUD_PLL_USER_CODEC && + hal_cmu_get_audio_resample_status()) { + + analog_aud_osc_clk_enable(true); + return; + } +#endif + + if (ana_aud_pll_map == 0) { + hal_cmu_pll_enable(HAL_CMU_PLL_AUD, HAL_CMU_PLL_USER_AUD); + } + ana_aud_pll_map |= user; +} + +void analog_aud_pll_close(enum ANA_AUD_PLL_USER_T user) +{ + if (user >= ANA_AUD_PLL_USER_END) { + return; + } + +#ifdef __AUDIO_RESAMPLE__ + if (user == ANA_AUD_PLL_USER_CODEC && + hal_cmu_get_audio_resample_status()) { + + analog_aud_osc_clk_enable(false); + return; + } +#endif + + ana_aud_pll_map &= ~user; + if (ana_aud_pll_map == 0) { + hal_cmu_pll_disable(HAL_CMU_PLL_AUD, HAL_CMU_PLL_USER_AUD); + } +} + +static void analog_aud_enable_dac(uint32_t dac) +{ + uint16_t val_6e; + uint16_t val_70; + uint16_t val_73; + + analog_read(ANA_REG_6E, &val_6e); + analog_read(ANA_REG_70, &val_70); + + if (dac & (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1)) { + val_6e |= REG_CODEC_TX_EAR_DR_EN | REG_CODEC_TX_EAR_ENBIAS; + analog_write(ANA_REG_6E, val_6e); + osDelay(1); + val_70 |= CFG_TX_TREE_EN; + analog_write(ANA_REG_70, val_70); + osDelay(1); + + val_73 = 0; + if (dac & AUD_CHANNEL_MAP_CH0) { + val_73 |= REG_CODEC_TX_EN_EARPA_L | REG_CODEC_TX_EN_LCLK | REG_CODEC_TX_EN_LDAC; + } + if (dac & AUD_CHANNEL_MAP_CH1) { + val_73 |= REG_CODEC_TX_EN_EARPA_R | REG_CODEC_TX_EN_RCLK | REG_CODEC_TX_EN_RDAC + | REG_CODEC_TX_EN_LDAC; + } + val_73 |= REG_CODEC_TX_EN_DACLDO | REG_CODEC_TX_EN_LPPA; + analog_write(ANA_REG_73, val_73); + osDelay(1); + val_73 |= REG_CODEC_TX_EN_S1PA; + analog_write(ANA_REG_73, val_73); + // Ensure 1ms delay before enabling dac_pa + osDelay(1); + } else { + // Ensure 1ms delay after disabling dac_pa + osDelay(1); + analog_read(ANA_REG_73, &val_73); + val_73 &= ~REG_CODEC_TX_EN_S1PA; + analog_write(ANA_REG_73, val_73); + osDelay(1); + val_73 = 0; + analog_write(ANA_REG_73, val_73); + osDelay(1); + + val_70 &= ~CFG_TX_TREE_EN; + analog_write(ANA_REG_70, val_70); + osDelay(1); + + val_6e &= ~(REG_CODEC_TX_EAR_DR_EN | REG_CODEC_TX_EAR_ENBIAS); + analog_write(ANA_REG_6E, val_6e); + } +} + +static void analog_aud_enable_dac_pa(uint32_t dac) +{ + uint16_t val_73; + + analog_read(ANA_REG_73, &val_73); + + if (dac & (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1)) { + val_73 |= REG_CODEC_TX_EN_S4PA; + analog_write(ANA_REG_73, val_73); + +#ifdef AUDIO_OUTPUT_DC_CALIB_ANA + hal_codec_dac_sdm_reset_clear(); +#endif + } else { +#ifdef AUDIO_OUTPUT_DC_CALIB_ANA + hal_codec_dac_sdm_reset_set(); +#endif + + val_73 &= ~REG_CODEC_TX_EN_S4PA; + analog_write(ANA_REG_73, val_73); + } +} + +static void analog_aud_enable_adc(enum ANA_CODEC_USER_T user, enum AUD_CHANNEL_MAP_T ch_map, bool en) +{ + int i; + uint16_t val_61, val_6c, val_16a; + enum ANA_CODEC_USER_T old_map; + bool set; + bool global_update; + + ANALOG_DEBUG_TRACE(3,"[%s] user=%d ch_map=0x%x", __func__, user, ch_map); + + global_update = false; + + analog_read(ANA_REG_61, &val_61); + analog_read(ANA_REG_16A, &val_16a); + + for (i = 0; i < MAX_ANA_MIC_CH_NUM; i++) { + if (ch_map & (AUD_CHANNEL_MAP_CH0 << i)) { + set = false; + if (en) { + if (adc_map[i] == 0) { + set = true; + } + adc_map[i] |= user; + } else { + old_map = adc_map[i]; + adc_map[i] &= ~user; + if (old_map != 0 && adc_map[i] == 0) { + set = true; + } + } + if (set) { + global_update = true; + if (i == 4) { + if (adc_map[i]) { + val_16a |= REG_CODEC_EN_ADCE; + } else { + val_16a &= ~REG_CODEC_EN_ADCE; + } + } else { + if (adc_map[i]) { + val_61 |= (REG_CODEC_EN_ADCA << i); + } else { + val_61 &= ~(REG_CODEC_EN_ADCA << i); + } + } + } + } + } + + analog_write(ANA_REG_61, val_61); + analog_write(ANA_REG_16A, val_16a); + + if (global_update) { + for (i = 0; i < MAX_ANA_MIC_CH_NUM; i++) { + if (adc_map[i]) { + break; + } + } + analog_read(ANA_REG_6C, &val_6c); + if (i < MAX_ANA_MIC_CH_NUM) { + val_6c |= REG_CODEC_RX_EN_VTOI; + } else { + val_6c &= ~REG_CODEC_RX_EN_VTOI; + } + analog_write(ANA_REG_6C, val_6c); + } +} + +static uint32_t db_to_adc_gain(int db) +{ + int i; + uint8_t cnt; + const int8_t *list; + + list = adc_db; + cnt = ARRAY_SIZE(adc_db); + + for (i = 0; i < cnt - 1; i++) { + if (db < list[i + 1]) { + break; + } + } + + if (i == cnt - 1) { + return i; + } + else if (db * 2 < list[i] + list[i + 1]) { + return i; + } else { + return i + 1; + } +} + +static int8_t get_chan_adc_gain(uint32_t i) +{ + int8_t gain; + + gain = tgt_adc_db[i]; + +#ifdef DYN_ADC_GAIN + if (adc_gain_offset[i] < 0 && -adc_gain_offset[i] > gain) { + gain = 0; + } else { + gain += adc_gain_offset[i]; + } +#endif + + return gain; +} + +static void analog_aud_set_adc_gain(enum AUD_IO_PATH_T input_path, enum AUD_CHANNEL_MAP_T ch_map) +{ + int i; + int gain; + uint16_t gain_val; + uint16_t val, val_16a; + + analog_read(ANA_REG_63, &val); + if (ch_map & AUD_CHANNEL_MAP_CH4) { + analog_read(ANA_REG_16A, &val_16a); + } else { + val_16a = 0; + } + + for (i = 0; i < MAX_ANA_MIC_CH_NUM; i++) { + if (ch_map & (AUD_CHANNEL_MAP_CH0 << i)) { + if (0) { +#ifdef ANC_APP +#ifdef ANC_FF_ENABLED + } else if ((ANC_FF_MIC_CH_L | ANC_FF_MIC_CH_R) & (AUD_CHANNEL_MAP_CH0 << i)) { + gain = get_chan_adc_gain(i); +#endif +#ifdef ANC_FB_ENABLED + } else if ((ANC_FB_MIC_CH_L | ANC_FB_MIC_CH_R) & (AUD_CHANNEL_MAP_CH0 << i)) { + gain = get_chan_adc_gain(i); +#endif +#endif + } else if (input_path == AUD_INPUT_PATH_LINEIN) { + gain = LINEIN_ADC_GAIN_DB; + } else { + gain = get_chan_adc_gain(i); + } + gain_val = db_to_adc_gain(gain); + if (i < MAX_ANA_MIC_CH_NUM - 1) { + val = (val & ~(REG_CODEC_ADCA_GAIN_BIT_MASK << 3 * i)) | (REG_CODEC_ADCA_GAIN_BIT(gain_val) << 3 * i); + } else { + val_16a = SET_BITFIELD(val_16a, REG_CODEC_ADCE_GAIN_BIT, gain_val); + } + } + } + + analog_write(ANA_REG_63, val); + if (ch_map & AUD_CHANNEL_MAP_CH4) { + analog_write(ANA_REG_16A, val_16a); + } +} + +#ifdef ANC_APP +void analog_aud_apply_anc_adc_gain_offset(enum ANC_TYPE_T type, int16_t offset_l, int16_t offset_r) +{ + enum ANC_TYPE_T single_type; + enum AUD_CHANNEL_MAP_T ch_map; + uint32_t l, r; + int8_t org_l, adj_l; + int8_t org_r, adj_r; + + // qdb to db + offset_l /= 4; + offset_r /= 4; + + while (type) { + l = get_msb_pos(type); + single_type = (1 << l); + type &= ~single_type; + + ch_map = 0; + l = r = 32; + if (0) { +#if defined(ANC_FF_MIC_CH_L) || defined(ANC_FF_MIC_CH_R) + } else if (single_type == ANC_FEEDFORWARD) { + ch_map |= ANC_FF_MIC_CH_L | ANC_FF_MIC_CH_R; + l = get_msb_pos(ANC_FF_MIC_CH_L); + r = get_msb_pos(ANC_FF_MIC_CH_R); +#endif +#if defined(ANC_FB_MIC_CH_L) || defined(ANC_FB_MIC_CH_R) + } else if (single_type == ANC_FEEDBACK) { + ch_map = ANC_FB_MIC_CH_L | ANC_FB_MIC_CH_R; + l = get_msb_pos(ANC_FB_MIC_CH_L); + r = get_msb_pos(ANC_FB_MIC_CH_R); +#endif + } else { + continue; + } + + if ((l >= MAX_ANA_MIC_CH_NUM || adc_gain_offset[l] == offset_l) && + (r >= MAX_ANA_MIC_CH_NUM || adc_gain_offset[r] == offset_r)) { + continue; + } + + ANALOG_INFO_TRACE(0, "ana: apply anc adc gain offset: type=%d offset=%d/%d", single_type, offset_l, offset_r); + + org_l = adj_l = 0; + if (l < MAX_ANA_MIC_CH_NUM) { + adc_gain_offset[l] = 0; + if (offset_l) { + org_l = adc_db[db_to_adc_gain(get_chan_adc_gain(l))]; + adc_gain_offset[l] = offset_l; + adj_l = adc_db[db_to_adc_gain(get_chan_adc_gain(l))]; + } + } + + org_r = adj_r = 0; + if (r < MAX_ANA_MIC_CH_NUM) { + adc_gain_offset[r] = 0; + if (offset_r) { + org_r = adc_db[db_to_adc_gain(get_chan_adc_gain(r))]; + adc_gain_offset[r] = offset_r; + adj_r = adc_db[db_to_adc_gain(get_chan_adc_gain(r))]; + } + } + + hal_codec_apply_anc_adc_gain_offset(single_type, (org_l - adj_l), (org_r - adj_r)); + analog_aud_set_adc_gain(AUD_INPUT_PATH_MAINMIC, ch_map); + } +} +#endif + +#ifdef DYN_ADC_GAIN +void analog_aud_apply_adc_gain_offset(enum AUD_CHANNEL_MAP_T ch_map, int16_t offset) +{ + enum AUD_CHANNEL_MAP_T map; + int i; + +#ifdef ANC_APP +#ifdef ANC_FF_ENABLED + ch_map &= ~(ANC_FF_MIC_CH_L | ANC_FF_MIC_CH_R); +#endif +#ifdef ANC_FB_ENABLED + ch_map &= ~(ANC_FB_MIC_CH_L | ANC_FB_MIC_CH_R); +#endif +#endif + + if (ch_map) { + map = ch_map; + + while (map) { + i = get_msb_pos(map); + map &= ~(1 << i); + if (i < MAX_ANA_MIC_CH_NUM) { + adc_gain_offset[i] = offset; + } + } + + ANALOG_INFO_TRACE(2,"ana: apply adc gain offset: ch_map=0x%X offset=%d", ch_map, offset); + + analog_aud_set_adc_gain(AUD_INPUT_PATH_MAINMIC, ch_map); + } +} +#endif + +void analog_aud_set_dac_gain(int32_t v) +{ +} + +uint32_t analog_codec_get_dac_gain(void) +{ + return 0; +} + +uint32_t analog_codec_dac_gain_to_db(int32_t gain) +{ + return 0; +} + +int32_t analog_codec_dac_max_attn_db(void) +{ + return 0; +} + +static int POSSIBLY_UNUSED dc_calib_checksum_valid(uint32_t efuse) +{ + int i; + uint32_t cnt = 0; + uint32_t chksum_mask = (1 << (16 - DAC_DC_CALIB_BIT_WIDTH)) - 1; + + for (i = 0; i < DAC_DC_CALIB_BIT_WIDTH; i++) { + if (efuse & (1 << i)) { + cnt++; + } + } + + return (((~cnt) & chksum_mask) == ((efuse >> DAC_DC_CALIB_BIT_WIDTH) & chksum_mask)); +} + +static int16_t dc_calib_val_decode(int16_t val) +{ +#ifdef AUDIO_OUTPUT_DC_CALIB_ANA + uint32_t sign_bit = (1 << (DAC_DC_CALIB_BIT_WIDTH - 1)); + uint32_t num_mask = sign_bit - 1; + + if (val & sign_bit) { + val = -(val & num_mask); + } +#endif + return val; +} + +void analog_aud_get_dc_calib_value(int16_t *dc_l, int16_t *dc_r) +{ + static const uint8_t EFUSE_PAGE_DIFF_1P7V[2] = { PMU_EFUSE_PAGE_DCCALIB2_L, PMU_EFUSE_PAGE_DCCALIB2_R, }; + static const uint8_t EFUSE_PAGE_DIFF_1P95V[2] = { PMU_EFUSE_PAGE_DCCALIB_L, PMU_EFUSE_PAGE_DCCALIB_R, }; + const uint8_t *page; + uint16_t efuse; + + union DC_EFUSE_T { + struct DC_VALUE_T { + int16_t dc : DAC_DC_CALIB_BIT_WIDTH; + uint16_t checksum : (16 - DAC_DC_CALIB_BIT_WIDTH); + } val; + uint16_t reg; + }; + union DC_EFUSE_T dc; + + if (vcodec_mv >= 1900) { + page = EFUSE_PAGE_DIFF_1P95V; + } else { + page = EFUSE_PAGE_DIFF_1P7V; + } + + pmu_get_efuse(page[0], &efuse); + if (dc_calib_checksum_valid(efuse)) { + ANALOG_INFO_TRACE(1,"Dc calib L OK: 0x%04x", efuse); + dc.reg = efuse; + *dc_l = dc.val.dc; + } else { + ANALOG_INFO_TRACE(1,"Warning: Bad dc calib efuse L: 0x%04x", efuse); + *dc_l = 0; + } + + pmu_get_efuse(page[1], &efuse); + if (dc_calib_checksum_valid(efuse)) { + ANALOG_INFO_TRACE(1,"Dc calib R OK: 0x%04x", efuse); + dc.reg = efuse; + *dc_r = dc.val.dc; + } else { + ANALOG_INFO_TRACE(1,"Warning: Bad dc calib efuse R: 0x%04x", efuse); + *dc_r = 0; + } + + ANALOG_INFO_TRACE(2,"ANA: DC CALIB L=0x%04hX/%d R=0x%04hX/%d", *dc_l, dc_calib_val_decode(*dc_l), *dc_r, dc_calib_val_decode(*dc_r)); + +#if defined(ANA_DC_CALIB_L) || defined(ANA_DC_CALIB_R) +#ifdef ANA_DC_CALIB_L + *dc_l = ANA_DC_CALIB_L; +#endif +#ifdef ANA_DC_CALIB_R + *dc_r = ANA_DC_CALIB_R; +#endif + ANALOG_INFO_TRACE(2,"ANA: OVERRIDE DC CALIB L=0x%04hX/%d R=0x%04hX/%d", *dc_l, dc_calib_val_decode(*dc_l), *dc_r, dc_calib_val_decode(*dc_r)); +#endif + + return; +} + +#ifdef AUDIO_OUTPUT_DC_CALIB_ANA +static void analog_aud_dc_calib_init(void) +{ + uint16_t val; + int16_t dc_l, dc_r; + + analog_aud_get_dc_calib_value(&dc_l, &dc_r); + + analog_read(ANA_REG_71, &val); + val = SET_BITFIELD(val, REG_CODEC_TX_EAR_OFF_BITL, dc_l); + analog_write(ANA_REG_71, val); + + analog_read(ANA_REG_72, &val); + val = SET_BITFIELD(val, REG_CODEC_TX_EAR_OFF_BITR, dc_r); + analog_write(ANA_REG_72, val); +} + +static void analog_aud_dc_calib_enable(bool en) +{ + uint16_t val; + + analog_read(ANA_REG_70, &val); + val |= REG_CODEC_TX_EAR_OFFEN; + analog_write(ANA_REG_70, val); +} +#endif + +static void analog_aud_vcodec_enable(enum ANA_CODEC_USER_T user, bool en) +{ + uint32_t lock; + bool set = false; + + lock = int_lock(); + if (en) { + if (vcodec_map == 0) { + set = true; + } + vcodec_map |= user; + } else { + vcodec_map &= ~user; + if (vcodec_map == 0) { + set = true; + } + } + int_unlock(lock); + + if (set) { + pmu_codec_config(!!vcodec_map); + } +} + +static void analog_aud_enable_common_internal(enum ANA_CODEC_USER_T user, bool en) +{ + uint32_t lock; + uint16_t val_6b; + bool set = false; + + lock = int_lock(); + if (en) { + if (codec_common_map == 0) { + set = true; + } + codec_common_map |= user; + } else { + codec_common_map &= ~user; + if (codec_common_map == 0) { + set = true; + } + } + int_unlock(lock); + + if (set) { + analog_read(ANA_REG_6B, &val_6b); + if (codec_common_map) { + val_6b |= REG_CODEC_EN_VCM; + } else { + val_6b &= ~(REG_CODEC_EN_VCM | REG_CODEC_VCM_EN_LPF); + } + if (codec_common_map) { + // RTOS application startup time is long enougth for VCM charging +#if !(defined(VCM_ON) && defined(RTOS)) + // VCM fully stable time is about 60ms/1.95V or 150ms/1.7V + // Quick startup: + // 1) Disable VCM LPF and target to a higher voltage than the required one + // 2) Wait for a short time when VCM is in quick charge (high voltage) + // 3) Enable VCM LPF and target to the required VCM LPF voltage + analog_write(ANA_REG_6B, SET_BITFIELD(val_6b, REG_CODEC_VCM_LOW_VCM, 0)); + uint32_t delay; + +#if defined(VCM_CAP_100NF) + if (vcodec_mv >= 1900) { + delay = 6; + } else { + delay = 10; + } +#else + if (vcodec_mv >= 1900) { + delay = 25; + } else { + delay = 100; + } +#endif + osDelay(delay); +#if 0 + // Target to a voltage near the required one + analog_write(ANA_REG_6B, val_6b); + osDelay(10); +#endif +#endif // !(VCM_ON && RTOS) + val_6b |= REG_CODEC_VCM_EN_LPF; + } + analog_write(ANA_REG_6B, val_6b); + } +} + +static void analog_aud_enable_codec_common(enum ANA_CODEC_USER_T user, bool en) +{ +#ifndef VCM_ON + analog_aud_enable_common_internal(user, en); +#endif +} + +static void analog_aud_enable_adda_common(enum ANA_CODEC_USER_T user, bool en) +{ + uint32_t lock; + uint16_t val_6a, val_6b, val_74, val_7e; + bool set = false; + + lock = int_lock(); + if (en) { + if (adda_common_map == 0) { + set = true; + } + adda_common_map |= user; + } else { + adda_common_map &= ~user; + if (adda_common_map == 0) { + set = true; + } + } + int_unlock(lock); + + if (set) { + analog_read(ANA_REG_6A, &val_6a); + analog_read(ANA_REG_6B, &val_6b); + if (vcodec_mv >= 1700) { + analog_read(ANA_REG_74, &val_74); + } else { + val_74 = 0; + } + analog_read(ANA_REG_7E, &val_7e); + if (adda_common_map) { + val_6a |= REG_CODEC_EN_BIAS; + analog_write(ANA_REG_6A, val_6a); + if (vcodec_mv >= 1700) { + val_74 |= REG_PU_TX_REGULATOR; + analog_write(ANA_REG_74, val_74); + hal_sys_timer_delay_us(10); + val_74 &= ~REG_BYPASS_TX_REGULATOR; + analog_write(ANA_REG_74, val_74); + } + val_6b |= REG_CODEC_EN_VCM_BUFFER; + val_7e |= REG_PU_CLKMUX_LDO0P9; + } else { + val_6b &= ~REG_CODEC_EN_VCM_BUFFER; + val_7e &= ~REG_PU_CLKMUX_LDO0P9; + if (vcodec_mv >= 1700) { + val_74 |= REG_BYPASS_TX_REGULATOR; + analog_write(ANA_REG_74, val_74); + val_74 &= ~REG_PU_TX_REGULATOR; + analog_write(ANA_REG_74, val_74); + } + val_6a &= ~REG_CODEC_EN_BIAS; + analog_write(ANA_REG_6A, val_6a); + } + analog_write(ANA_REG_6B, val_6b); + analog_write(ANA_REG_7E, val_7e); + } +} + +static void analog_aud_enable_vmic(enum ANA_CODEC_USER_T user, uint32_t dev) +{ + uint32_t lock; + enum ANA_CODEC_USER_T old_map; + bool set = false; + int i; + uint32_t pmu_map = 0; + + lock = int_lock(); + + for (i = 0; i < MAX_ANA_MIC_CH_NUM; i++) { + if (dev & (AUD_VMIC_MAP_VMIC1 << i)) { + if (vmic_map[i] == 0) { + set = true; + } + vmic_map[i] |= user; + } else { + old_map = vmic_map[i]; + vmic_map[i] &= ~user; + if (old_map != 0 && vmic_map[i] == 0) { + set = true; + } + } + + if (vmic_map[i]) { + pmu_map |= (AUD_VMIC_MAP_VMIC1 << i); + } + } + + int_unlock(lock); + + if (set) { + pmu_codec_mic_bias_enable(pmu_map); +#ifdef VOICE_DETECTOR_EN + pmu_codec_mic_bias_lowpower_mode(pmu_map); +#endif + if (pmu_map) { + osDelay(1); + } + } +} + +uint32_t analog_aud_get_max_dre_gain(void) +{ + if (vcodec_mv >= 1900) { + return 0x11; + } else { + return 0xF; + } +} + +int analog_reset(void) +{ + return 0; +} + +void analog_open(void) +{ + uint16_t val; + + val = REG_CODEC_ADCA_CH_SEL(1) | REG_CODEC_ADCB_CH_SEL(1) | REG_CODEC_ADCC_CH_SEL(1) | REG_CODEC_ADCD_CH_SEL(1); + analog_write(ANA_REG_61, val); + + val = CFG_RESET_PGAA_DR | CFG_RESET_PGAB_DR | CFG_RESET_PGAC_DR | CFG_RESET_PGAD_DR; + analog_write(ANA_REG_62, val); + + val = 0; //REG_CODEC_ADCA_GAIN_UPDATE | REG_CODEC_ADCB_GAIN_UPDATE | REG_CODEC_ADCC_GAIN_UPDATE | REG_CODEC_ADCD_GAIN_UPDATE; + analog_write(ANA_REG_63, val); + + val = REG_CODEC_ADC_IBSEL_REG(8) | REG_CODEC_ADC_IBSEL_VCOMP(8) | REG_CODEC_ADC_IBSEL_VREF(8) | REG_CODEC_ADC_LPFVCM_SW(7); + analog_write(ANA_REG_67, val); + + val = REG_CODEC_ADC_OP1_IBIT(2) | REG_CODEC_ADC_VREF_SEL(4); + analog_write(ANA_REG_68, val); + + val = REG_CODEC_BIAS_IBSEL(8) | REG_CODEC_BIAS_IBSEL_VOICE(8); + if (vcodec_mv >= 1900) { + val |= REG_CODEC_BIAS_IBSEL_TX(5); + } else { +#ifdef LOW_CODEC_BIAS + val |= REG_CODEC_BIAS_IBSEL_TX(1); +#else + val |= REG_CODEC_BIAS_IBSEL_TX(3); +#endif + } + analog_write(ANA_REG_69, val); + + val = REG_CODEC_ADC_REG_VSEL(3) | REG_CODEC_BUF_LOWVCM(4) | REG_CODEC_EN_RX_EXT | REG_CODEC_EN_TX_EXT | REG_CODEC_DAC_CLK_EDGE_SEL; + val |= REG_CODEC_EN_BIAS_LP; + analog_write(ANA_REG_6A, val); + + uint16_t vcm, vcm_lpf; + if (vcodec_mv >= 1900) { + vcm = 7; + vcm_lpf = 0xA; + } else if (vcodec_mv >= 1800) { + vcm = vcm_lpf = 7; + } else { + vcm = vcm_lpf = 7; + } + val = REG_CODEC_VCM_LOW_VCM(vcm) | REG_CODEC_VCM_LOW_VCM_LP(vcm) | REG_CODEC_VCM_LOW_VCM_LPF(vcm_lpf); + analog_write(ANA_REG_6B, val); + + val = REG_CODEC_RX_VTOI_I_DAC2(4) | REG_CODEC_RX_VTOI_IDAC_SEL(8) | REG_CODEC_RX_VTOI_VCS_SEL(0x10); + analog_write(ANA_REG_6C, val); + + if (vcodec_mv > 1900) { + val = REG_CODEC_TX_DAC_VREF_L(9) | REG_CODEC_TX_DAC_VREF_R(9) | REG_CODEC_TX_EAR_CAS_BIT(3); + } else if (vcodec_mv == 1900) { + val = REG_CODEC_TX_DAC_VREF_L(0xA) | REG_CODEC_TX_DAC_VREF_R(0xA) | REG_CODEC_TX_EAR_CAS_BIT(3); + } else { + val = REG_CODEC_TX_DAC_VREF_L(2) | REG_CODEC_TX_DAC_VREF_R(2) | REG_CODEC_TX_EAR_CAS_BIT(1); + } + analog_write(ANA_REG_6D, val); + + val = REG_CODEC_TX_EAR_IBSEL(2); +#ifdef LOW_CODEC_BIAS + if (vcodec_mv < 1900) { + val = REG_CODEC_TX_EAR_IBSEL(0); + } +#endif + val |= REG_CODEC_TX_EAR_COMP_L(7) | REG_CODEC_TX_EAR_COMP_R(7) | REG_CODEC_TX_EAR_DR_ST(1) | REG_CODEC_TX_EAR_FBCAP(3); + analog_write(ANA_REG_6E, val); + + val = REG_CODEC_TX_EAR_DRE_GAIN_L(0xF) | REG_CODEC_TX_EAR_DRE_GAIN_R(0xF) | DRE_GAIN_SEL_L | DRE_GAIN_SEL_R | REG_CODEC_TX_EAR_GAIN(1); +#ifdef DAC_DRE_GAIN_DC_UPDATE + val |= REG_CODEC_TX_EAR_DRE_GAIN_L_UPDATE | REG_CODEC_TX_EAR_DRE_GAIN_R_UPDATE; +#endif + analog_write(ANA_REG_6F, val); + + val = REG_CODEC_TX_EAR_OUTPUTSEL(1) | REG_CODEC_TX_EAR_SOFTSTART(8) | REG_CODEC_TX_EAR_OCEN | REG_CODEC_TX_EAR_LPBIAS; + analog_write(ANA_REG_70, val); + + val = REG_DAC_LDO0P9_VSEL(2) | REG_BYPASS_TX_REGULATOR | REG_CODEC_TX_EAR_VCM_BIT(3) | REG_CODEC_TX_EAR_VCM_SEL; + if (vcodec_mv >= 1900) { + val |= REG_CODEC_TX_RVREF_CAP_BIT | REG_TX_REGULATOR_BIT(0xD); + } else { + val |= REG_TX_REGULATOR_BIT(4); + } + analog_write(ANA_REG_74, val); + + val = REG_CLKMUX_DVDD_SEL | REG_CLKMUX_LDO0P9_VSEL(2) | REG_AUDPLL_LDO_VREF(4) | REG_AUDPLL_LPF_BW_SEL; + analog_write(ANA_REG_7E, val); + + //Optimize bottom noise, dig_codec_adcE_vref_sel[3:0] should be 0x4 ————by jeff 20200916 + analog_read(ANA_REG_16E, &val); + val = SET_BITFIELD(val, DIG_CODEC_ADCE_VREF_SEL, 0x4); + analog_write(ANA_REG_16E, val); + +#ifdef AUDIO_OUTPUT_DC_CALIB_ANA + analog_aud_dc_calib_init(); + analog_aud_dc_calib_enable(true); +#endif + +#ifdef VCM_ON + analog_aud_enable_common_internal(ANA_CODEC_USER_DAC, true); +#endif +} + +void analog_sleep(void) +{ +#ifdef VOICE_DETECTOR_EN + if ((adda_common_map & ANA_CODEC_USER_VAD) && (adc_map[4] & ANA_CODEC_USER_VAD) == 0) { + uint16_t val; + + analog_read(ANA_REG_6B, &val); + val = (val & ~REG_CODEC_EN_VCM_BUFFER) | REG_CODEC_LP_VCM; + analog_write(ANA_REG_6B, val); + } +#endif +} + +void analog_wakeup(void) +{ +#ifdef VOICE_DETECTOR_EN + if ((adda_common_map & ANA_CODEC_USER_VAD) && (adc_map[4] & ANA_CODEC_USER_VAD) == 0) { + uint16_t val; + + analog_read(ANA_REG_6B, &val); + val = (val & ~REG_CODEC_LP_VCM) | REG_CODEC_EN_VCM_BUFFER; + analog_write(ANA_REG_6B, val); + } +#endif +} + +void analog_aud_codec_anc_enable(enum ANC_TYPE_T type, bool en) +{ + enum ANA_CODEC_USER_T user; + enum AUD_CHANNEL_MAP_T ch_map; + + user = 0; + ch_map = 0; +#if defined(ANC_FF_MIC_CH_L) || defined(ANC_FF_MIC_CH_R) + if (type & ANC_FEEDFORWARD) { + user |= ANA_CODEC_USER_ANC_FF; + ch_map |= ANC_FF_MIC_CH_L | ANC_FF_MIC_CH_R; + } +#endif +#if defined(ANC_FB_MIC_CH_L) || defined(ANC_FB_MIC_CH_R) + if (type & ANC_FEEDFORWARD) { + user |= ANA_CODEC_USER_ANC_FB; + ch_map |= ANC_FB_MIC_CH_L | ANC_FB_MIC_CH_R; + } +#endif + + ANALOG_DEBUG_TRACE(0, "%s: type=%d en=%d ch_map=0x%x", __func__, type, en, ch_map); + + if (en) { + analog_aud_enable_vmic(user, ANC_VMIC_CFG); + analog_aud_enable_codec_common(user, true); + analog_aud_enable_adda_common(user, true); + analog_aud_set_adc_gain(AUD_INPUT_PATH_MAINMIC, ch_map); + analog_aud_enable_adc(user, ch_map, true); + } else { + analog_aud_apply_anc_adc_gain_offset(type, 0, 0); + analog_aud_enable_adc(user, ch_map, false); + analog_aud_enable_adda_common(user, false); + analog_aud_enable_codec_common(user, false); + analog_aud_enable_vmic(user, 0); + } +} + +void analog_aud_codec_anc_boost(bool en, ANALOG_ANC_BOOST_DELAY_FUNC delay_func) +{ + uint16_t val; + int ret; + + if (vcodec_mv >= 1800) { + return; + } + + if (delay_func == NULL) { + delay_func = (ANALOG_ANC_BOOST_DELAY_FUNC)osDelay; + } + + if (en) { + // -2.1 dB + hal_codec_set_anc_boost_gain_attn(0.78523563f); + delay_func(1); + } + + analog_read(ANA_REG_6B, &val); + val &= ~REG_CODEC_VCM_EN_LPF; + analog_write(ANA_REG_6B, val); + osDelay(1); + + do { + if (en) { + ret = pmu_codec_volt_ramp_up(); + } else { + ret = pmu_codec_volt_ramp_down(); + } + delay_func(1); + } while (ret); + + analog_read(ANA_REG_6B, &val); + val |= REG_CODEC_VCM_EN_LPF; + analog_write(ANA_REG_6B, val); + + if (!en) { + delay_func(1); + // 0 dB + hal_codec_set_anc_boost_gain_attn(1.0f); + } +} + +void analog_aud_mickey_enable(bool en) +{ + if (en) { + analog_aud_vcodec_enable(ANA_CODEC_USER_MICKEY, true); + analog_aud_enable_vmic(ANA_CODEC_USER_MICKEY, CFG_HW_AUD_MICKEY_DEV); + analog_aud_enable_codec_common(ANA_CODEC_USER_MICKEY, true); + } else { + analog_aud_enable_codec_common(ANA_CODEC_USER_MICKEY, false); + analog_aud_enable_vmic(ANA_CODEC_USER_MICKEY, 0); + analog_aud_vcodec_enable(ANA_CODEC_USER_MICKEY, false); + } +} + +void analog_aud_codec_adc_enable(enum AUD_IO_PATH_T input_path, enum AUD_CHANNEL_MAP_T ch_map, bool en) +{ + uint32_t dev; + + if (en) { + dev = hal_codec_get_input_path_cfg(input_path); + // Enable vmic first to overlap vmic stable time with codec vcm stable time + analog_aud_enable_vmic(ANA_CODEC_USER_ADC, dev); + analog_aud_enable_codec_common(ANA_CODEC_USER_ADC, true); + analog_aud_enable_adda_common(ANA_CODEC_USER_ADC, true); + analog_aud_set_adc_gain(input_path, ch_map); + analog_aud_enable_adc(ANA_CODEC_USER_ADC, ch_map, true); + } else { + analog_aud_enable_adc(ANA_CODEC_USER_ADC, ch_map, false); + analog_aud_enable_adda_common(ANA_CODEC_USER_ADC, false); + analog_aud_enable_codec_common(ANA_CODEC_USER_ADC, false); + analog_aud_enable_vmic(ANA_CODEC_USER_ADC, 0); + } +} + +static void analog_aud_codec_config_speaker(void) +{ + bool en; + + if (ana_spk_req && !ana_spk_muted) { + en = true; + } else { + en = false; + } + + if (ana_spk_enabled != en) { + ana_spk_enabled = en; + if (en) { + analog_aud_enable_dac_pa(CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV); + app_mutetimer_start(); + } else { + analog_aud_enable_dac_pa(0); + app_mute_ctrl(false); + } + } +} + +void analog_aud_codec_speaker_enable(bool en) +{ + ana_spk_req = en; + analog_aud_codec_config_speaker(); +} + +void analog_aud_codec_dac_enable(bool en) +{ + if (en) { + analog_aud_enable_codec_common(ANA_CODEC_USER_DAC, true); + analog_aud_enable_adda_common(ANA_CODEC_USER_DAC, true); + pmu_codec_hppa_enable(1); + analog_aud_enable_dac(CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV); +#if !defined(AUDIO_OUTPUT_DC_CALIB_ANA) && !defined(AUDIO_OUTPUT_DC_CALIB) + osDelay(1); + analog_aud_codec_speaker_enable(true); +#endif + } else { +#if !defined(AUDIO_OUTPUT_DC_CALIB_ANA) && !defined(AUDIO_OUTPUT_DC_CALIB) + analog_aud_codec_speaker_enable(false); + osDelay(1); +#endif + analog_aud_enable_dac(0); + pmu_codec_hppa_enable(0); + analog_aud_enable_adda_common(ANA_CODEC_USER_DAC, false); + analog_aud_enable_codec_common(ANA_CODEC_USER_DAC, false); + } +} + +void analog_aud_codec_open(void) +{ + analog_aud_vcodec_enable(ANA_CODEC_USER_CODEC, true); + +#ifdef _AUTO_SWITCH_POWER_MODE__ + //pmu_mode_change(PMU_POWER_MODE_DIG_DCDC); +#endif +} + +void analog_aud_codec_close(void) +{ + static const enum AUD_CHANNEL_MAP_T all_ch = AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1 | + AUD_CHANNEL_MAP_CH2 | AUD_CHANNEL_MAP_CH3 | AUD_CHANNEL_MAP_CH4; + + analog_aud_codec_speaker_enable(false); + osDelay(1); + analog_aud_codec_dac_enable(false); + + analog_aud_codec_adc_enable(AUD_IO_PATH_NULL, all_ch, false); + +#ifdef _AUTO_SWITCH_POWER_MODE__ + //pmu_mode_change(PMU_POWER_MODE_ANA_DCDC); +#endif + + analog_aud_vcodec_enable(ANA_CODEC_USER_CODEC, false); +} + +void analog_aud_codec_mute(void) +{ +#ifndef AUDIO_OUTPUT_DC_CALIB + //analog_codec_tx_pa_gain_sel(0); +#endif + + ana_spk_muted = true; + analog_aud_codec_config_speaker(); +} + +void analog_aud_codec_nomute(void) +{ + ana_spk_muted = false; + analog_aud_codec_config_speaker(); + +#ifndef AUDIO_OUTPUT_DC_CALIB + //analog_aud_set_dac_gain(dac_gain); +#endif +} + +int analog_debug_config_audio_output(bool diff) +{ + return 0; +} + +int analog_debug_config_codec(uint16_t mv) +{ +#ifdef ANC_PROD_TEST + int ret; + + ret = pmu_debug_config_codec(mv); + if (ret) { + return ret; + } + + vcodec_mv = mv; +#endif + return 0; +} + +int analog_debug_config_low_power_adc(bool enable) +{ + return 0; +} + +void analog_debug_config_anc_calib_mode(bool enable) +{ + anc_calib_mode = enable; +} + +bool analog_debug_get_anc_calib_mode(void) +{ + return anc_calib_mode; +} + +int analog_debug_config_vad_mic(bool enable) +{ + return 0; +} + + +#ifdef VOICE_DETECTOR_EN + +static void analog_aud_codec_vad_ini(void) +{ +#if 1 + unsigned short v; + +#if 0 + //0x6a,0x0503 + analog_read(ANA_REG_6A, &v); + v = SET_BITFIELD(v, REG_CODEC_ADC_REG_VSEL, 0x3); + v = SET_BITFIELD(v, REG_CODEC_BUF_LOWVCM, 0x4); + v |= REG_CODEC_EN_BIAS_LP; + analog_write(ANA_REG_6A, v); + + //0x6b,0x3bbf + analog_read(ANA_REG_6B, &v); +#if 0 + v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM, 0x7); + v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM_LP, 0x7); + v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM_LPF, 0x7); + v &= ~REG_CODEC_EN_VCM_BUFFER; +#else + v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM, 0x6); + v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM_LP, 0x6); + v = SET_BITFIELD(v, REG_CODEC_VCM_LOW_VCM_LPF, 0x6); + v |= REG_CODEC_EN_VCM_BUFFER; +#endif + analog_write(ANA_REG_6B, v); + + //0x74,0xc544 + analog_read(ANA_REG_74, &v); + v &= ~REG_CODEC_TX_RVREF_CAP_BIT; + v = SET_BITFIELD(v, REG_DAC_LDO0P9_VSEL, 0x2); +#if 0 + v |= REG_BYPASS_TX_REGULATOR; + v &= ~REG_PU_TX_REGULATOR; +#else + v &= ~REG_BYPASS_TX_REGULATOR; + v |= REG_PU_TX_REGULATOR; +#endif + v = SET_BITFIELD(v, REG_TX_REGULATOR_BIT, 0x5); + v = SET_BITFIELD(v, REG_CODEC_TX_EAR_VCM_BIT, 0x2); + v |= REG_CODEC_TX_EAR_VCM_SEL; + analog_write(ANA_REG_74, v); +#endif + + //0x173, 0x0805 + v = REG_VOICE_LDO_VBIT(5) + | CFG_VOICE_DET_DELAY(8); + analog_write(ANA_REG_173, v); + + //0x17d,0x817f + v = REG_CLK_GOAL_DIV_NUM(0x17f) + | REG_COARSE_TUN_CODE_DR; + analog_write(ANA_REG_17D, v); + +#if 1 + //0x171,0x1047 + v = CFG_VOICE_RESET + | CFG_VOICE_PU_DELAY(4) + | CFG_VOICE_PRECH_DELAY(0x7f); + analog_write(ANA_REG_171, v); +#endif + + //0x17a + analog_read(ANA_REG_17A, &v); + v = SET_BITFIELD(v, REG_VOICE_LOW_TUNE, 0x3); + analog_write(ANA_REG_17A, v); + + + //0x161[15] = 1; //cfg_reg_clkmux_dvdd_sel + analog_read(ANA_REG_161, &v); + v |= 1 << 15; + analog_write(ANA_REG_161, v); + + //0x170[15] = 1; //cfg_voice2adcE + analog_read(ANA_REG_170, &v); + v = SET_BITFIELD(v, REG_VOICE_GAIN_A, 0x3); + v = SET_BITFIELD(v, REG_VOICE_GAIN_B, 0x3); + v = SET_BITFIELD(v, REG_VOICE_HIGH_TUNE_A, 0xa); + v = SET_BITFIELD(v, REG_VOICE_HIGH_TUNE_B, 0x4); + v |= CFG_VOICE2ADCE; + analog_write(ANA_REG_170, v); + + osDelay(1); +#endif +} + +static void analog_aud_codec_vad_fin(void) +{ + unsigned short v; + + analog_read(ANA_REG_170, &v); + v &= ~CFG_VOICE2ADCE; + analog_write(ANA_REG_170, v); +} + +static void analog_aud_codec_vad_trig_en(bool en) +{ +#if 1 + unsigned short v; + uint32_t lock; + + lock = int_lock(); + analog_read(ANA_REG_171, &v); + if (en) + v |= CFG_VOICE_TRIG_ENABLE; + else + v &= ~CFG_VOICE_TRIG_ENABLE; + + analog_write(ANA_REG_171, v); + + int_unlock(lock); +#endif +} + +static void analog_aud_codec_vad_pu(bool en) +{ +#if 1 + unsigned short v; + uint32_t lock; + + lock = int_lock(); + analog_read(ANA_REG_171, &v); + if (en) + v |= CFG_VOICE_POWER_ON; + else + v &= ~CFG_VOICE_POWER_ON; + + analog_write(ANA_REG_171, v); + int_unlock(lock); +#endif +} + +void analog_aud_vad_enable(enum AUD_VAD_TYPE_T type, bool en) +{ + if (type == AUD_VAD_TYPE_DIG) { + uint32_t dev; + enum AUD_CHANNEL_MAP_T ch_map; + + dev = hal_codec_get_input_path_cfg(AUD_INPUT_PATH_VADMIC); + ch_map = dev & AUD_CHANNEL_MAP_ANA_ALL; + analog_aud_enable_adc(ANA_CODEC_USER_VAD, ch_map, en); + } else if (type == AUD_VAD_TYPE_MIX || type == AUD_VAD_TYPE_ANA) { + if (en) { + analog_aud_codec_vad_ini(); + analog_aud_codec_vad_pu(true); + osDelay(1); + analog_aud_codec_vad_trig_en(true); + //pmu_codec_vad_save_power(); + } else { + //pmu_codec_vad_restore_power(); + // Must power off before disabling trigger + analog_aud_codec_vad_pu(false); + osDelay(1); + analog_aud_codec_vad_trig_en(false); + analog_aud_codec_vad_fin(); + } + } +} + +void analog_aud_vad_adc_enable(bool en) +{ + uint32_t dev; + enum AUD_CHANNEL_MAP_T ch_map; + + dev = hal_codec_get_input_path_cfg(AUD_INPUT_PATH_VADMIC); + ch_map = dev & AUD_CHANNEL_MAP_ANA_ALL; + + if (en) { + // Enable vmic first to overlap vmic stable time with codec vcm stable time + analog_aud_enable_vmic(ANA_CODEC_USER_VAD, dev); + analog_aud_enable_codec_common(ANA_CODEC_USER_VAD, true); + analog_aud_enable_adda_common(ANA_CODEC_USER_VAD, true); + analog_aud_set_adc_gain(AUD_INPUT_PATH_VADMIC, ch_map); + } else { + analog_aud_enable_adda_common(ANA_CODEC_USER_VAD, false); + analog_aud_enable_codec_common(ANA_CODEC_USER_VAD, false); + analog_aud_enable_vmic(ANA_CODEC_USER_VAD, 0); + } +} + +#endif + diff --git a/platform/drivers/ana/best2300p/analog_best2300p.h b/platform/drivers/ana/best2300p/analog_best2300p.h new file mode 100644 index 0000000..239aef7 --- /dev/null +++ b/platform/drivers/ana/best2300p/analog_best2300p.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ANALOG_BEST2300P_H__ +#define __ANALOG_BEST2300P_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_ANA_MIC_CH_NUM 5 + +typedef void (*ANALOG_ANC_BOOST_DELAY_FUNC)(uint32_t ms); + +uint32_t analog_aud_get_max_dre_gain(void); + +void analog_aud_codec_anc_boost(bool en, ANALOG_ANC_BOOST_DELAY_FUNC delay_func); + +int analog_debug_config_vad_mic(bool enable); + +void analog_aud_vad_enable(enum AUD_VAD_TYPE_T type, bool en); + +void analog_aud_vad_adc_enable(bool en); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/ana/best2300p/pmu_best2300p.c b/platform/drivers/ana/best2300p/pmu_best2300p.c new file mode 100644 index 0000000..f4bedd3 --- /dev/null +++ b/platform/drivers/ana/best2300p/pmu_best2300p.c @@ -0,0 +1,4287 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "pmu.h" +#include "analog.h" +#include "cmsis.h" +#include "cmsis_nvic.h" +#include "hal_aud.h" +#include "hal_cache.h" +#include "hal_chipid.h" +#include "hal_cmu.h" +#include "hal_location.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_sysfreq.h" +#include "tgt_hardware.h" +#include "usbphy.h" +#include "hal_psc.h" + +#define PMU_LED_VIA_PWM +#define DCDC_ULP_LP_ON + +// LDO soft start interval is about 1000 us +#define PMU_LDO_PU_STABLE_TIME_US 1800 +#define PMU_DCDC_PU_STABLE_TIME_US 100 +#define PMU_VANA_STABLE_TIME_US 10 +#define PMU_VCORE_STABLE_TIME_US 10 + +#ifdef __PMU_VIO_DYNAMIC_CTRL_MODE__ +#define IO_VOLT_ACTIVE_NORMAL PMU_IO_2_6V +#else +#define IO_VOLT_ACTIVE_NORMAL PMU_IO_2_6V +#endif +#ifdef DIGMIC_HIGH_VOLT +#define IO_VOLT_ACTIVE_RISE PMU_IO_3_0V +#else +#define IO_VOLT_ACTIVE_RISE PMU_IO_2_8V +#endif +#define IO_VOLT_SLEEP PMU_IO_2_6V + +#define HPPA_RAMP_UP_VOLT_MV 1950 + +#define PMU_DCDC_ANA_2_1V 0xF0 +#define PMU_DCDC_ANA_2_0V 0xE0 +#define PMU_DCDC_ANA_1_9V 0xD0 +#define PMU_DCDC_ANA_1_8V 0xC0 +#define PMU_DCDC_ANA_1_7V 0xB0 +#define PMU_DCDC_ANA_1_6V 0xA0 +#define PMU_DCDC_ANA_1_5V 0x90 +#define PMU_DCDC_ANA_1_4V 0x80 +#define PMU_DCDC_ANA_1_35V 0x77 +#define PMU_DCDC_ANA_1_3V 0x70 +#define PMU_DCDC_ANA_1_2V 0x60 +#define PMU_DCDC_ANA_1_1V 0x50 +#define PMU_DCDC_ANA_1_0V 0x40 + +#define PMU_DCDC_ANA_SLEEP_1_3V PMU_DCDC_ANA_1_3V +#define PMU_DCDC_ANA_SLEEP_1_2V PMU_DCDC_ANA_1_2V +#define PMU_DCDC_ANA_SLEEP_1_1V PMU_DCDC_ANA_1_1V +#define PMU_DCDC_ANA_SLEEP_1_0V PMU_DCDC_ANA_1_0V + +#define PMU_VBUCK2ANA_1_5V 0x30 +#define PMU_VBUCK2ANA_1_4V 0x2C +#define PMU_VBUCK2ANA_1_3V 0x28 +#define PMU_VBUCK2ANA_1_2V 0x24 +#define PMU_VBUCK2ANA_1_1V 0x20 +#define PMU_VBUCK2ANA_1_0V 0x1C + +#define PMU_DCDC_DIG_1_1V 0xFF +#define PMU_DCDC_DIG_1_05V 0xF0 +#define PMU_DCDC_DIG_1_0V 0xE0 +#define PMU_DCDC_DIG_0_95V 0xD0 +#define PMU_DCDC_DIG_0_9V 0xC0 +#define PMU_DCDC_DIG_0_85V 0xB0 +#define PMU_DCDC_DIG_0_8V 0xA0 +#define PMU_DCDC_DIG_0_75V 0x90 +#define PMU_DCDC_DIG_0_7V 0x80 +#define PMU_DCDC_DIG_0_65V 0x70 +#define PMU_DCDC_DIG_0_6V 0x60 +#define PMU_DCDC_DIG_0_55V 0x50 +#define PMU_DCDC_DIG_0_5V 0x40 +#define PMU_DCDC_DIG_0_45V 0x30 +#define PMU_DCDC_DIG_0_4V 0x20 + +#define PMU_VDIG_1_2V 0x24 +#define PMU_VDIG_1_1V 0x20 +#define PMU_VDIG_1_05V 0x1E +#define PMU_VDIG_1_0V 0x1C +#define PMU_VDIG_0_95V 0x1A +#define PMU_VDIG_0_9V 0x18 +#define PMU_VDIG_0_85V 0x16 +#define PMU_VDIG_0_8V 0x14 +#define PMU_VDIG_0_75V 0x12 +#define PMU_VDIG_0_7V 0x10 +#define PMU_VDIG_0_65V 0x0E +#define PMU_VDIG_0_6V 0x0C +#define PMU_VDIG_0_55V 0x0A +#define PMU_VDIG_0_5V 0x08 +#define PMU_VDIG_0_45V 0x06 +#define PMU_VDIG_0_4V 0x04 +#define PMU_VDIG_MAX PMU_VDIG_1_2V + +#define PMU_IO_3_3V 0x15 +#define PMU_IO_3_2V 0x14 +#define PMU_IO_3_1V 0x13 +#define PMU_IO_3_0V 0x12 +#define PMU_IO_2_9V 0x11 +#define PMU_IO_2_8V 0x10 +#define PMU_IO_2_7V 0xF +#define PMU_IO_2_6V 0xE +#define PMU_IO_2_5V 0xD +#define PMU_IO_2_4V 0xC +#define PMU_IO_2_3V 0xB +#define PMU_IO_2_2V 0xA +#define PMU_IO_2_1V 0x9 +#define PMU_IO_2_0V 0x8 +#define PMU_IO_1_9V 0x7 +#define PMU_IO_1_8V 0x6 +#define PMU_IO_1_7V 0x5 + +#define PMU_VMEM_2_8V 0x10 +#define PMU_VMEM_2_0V 0x8 +#define PMU_VMEM_1_9V 0x7 +#define PMU_VMEM_1_8V 0x6 +#define PMU_VMEM_1_7V 0x5 +#define PMU_VMEM_1_6V 0x4 + +#define PMU_CODEC_2_7V 0xF +#define PMU_CODEC_2_6V 0xE +#define PMU_CODEC_2_5V 0xD +#define PMU_CODEC_2_4V 0xC +#define PMU_CODEC_2_3V 0xB +#define PMU_CODEC_2_2V 0xA +#define PMU_CODEC_2_1V 0x9 +#define PMU_CODEC_2_0V 0x8 +#define PMU_CODEC_1_9V 0x7 +#define PMU_CODEC_1_8V 0x6 +#define PMU_CODEC_1_7V 0x5 +#define PMU_CODEC_1_6V 0x4 +#define PMU_CODEC_1_5V 0x3 + +#define PMU_HPPA2CODEC_2_3V 0x1C +#define PMU_HPPA2CODEC_2_2V 0x18 +#define PMU_HPPA2CODEC_2_1V 0x14 +#define PMU_HPPA2CODEC_2_0V 0x10 +#define PMU_HPPA2CODEC_1_95V 0xE +#define PMU_HPPA2CODEC_1_9V 0xC +#define PMU_HPPA2CODEC_1_8V 0x8 +#define PMU_HPPA2CODEC_1_7V 0x4 +#define PMU_HPPA2CODEC_1_6V 0x0 + +#define PMU_USB_3_4V 0xA +#define PMU_USB_3_3V 0x9 +#define PMU_USB_3_2V 0x8 +#define PMU_USB_3_1V 0x7 +#define PMU_USB_3_0V 0x6 +#define PMU_USB_2_9V 0x5 +#define PMU_USB_2_8V 0x4 +#define PMU_USB_2_7V 0x3 +#define PMU_USB_2_6V 0x2 + +#define PMU_VHPPA_2_0V 0x8 +#define PMU_VHPPA_1_9V 0x7 +#define PMU_VHPPA_1_8V 0x6 +#define PMU_VHPPA_1_7V 0x5 +#define PMU_VHPPA_1_6V 0x4 +#define PMU_VHPPA_1_5V 0x3 + +#define PMU_DCDC_HPPA_2_1V 0xF0 +#define PMU_DCDC_HPPA_2_0V 0xE0 +#define PMU_DCDC_HPPA_1_95V 0xD8 +#define PMU_DCDC_HPPA_1_9V 0xD0 +#define PMU_DCDC_HPPA_1_8V 0xC0 +#define PMU_DCDC_HPPA_1_7V 0xB0 +#define PMU_DCDC_HPPA_1_6V 0xA0 +#define PMU_DCDC_HPPA_1_5V 0x90 +#define PMU_DCDC_HPPA_1_4V 0x80 +#define PMU_DCDC_HPPA_1_3V 0x70 +#define PMU_DCDC_HPPA_1_2V 0x60 + +#define PMU_VMIC_3_3V 0x14 +#define PMU_VMIC_3_2V 0x13 +#define PMU_VMIC_3_1V 0x12 +#define PMU_VMIC_3_0V 0x11 +#define PMU_VMIC_2_9V 0x10 +#define PMU_VMIC_2_8V 0xF +#define PMU_VMIC_2_7V 0xF +#define PMU_VMIC_2_6V 0xE +#define PMU_VMIC_2_5V 0xD +#define PMU_VMIC_2_4V 0xC +#define PMU_VMIC_2_3V 0xB +#define PMU_VMIC_2_2V 0xA +#define PMU_VMIC_2_1V 0x9 +#define PMU_VMIC_2_0V 0x8 +#define PMU_VMIC_1_9V 0x7 +#define PMU_VMIC_1_8V 0x6 +#define PMU_VMIC_1_7V 0x5 +#define PMU_VMIC_1_6V 0x4 + +#define PMU_VMIC_RES_3_3V 0xF +#define PMU_VMIC_RES_2_8V 0xA +#define PMU_VMIC_RES_2_2V 0x4 + +// 00 PMU_REG_METAL_ID +#define PMU_METAL_ID_SHIFT 0 +#define PMU_METAL_ID_MASK (0xF << PMU_METAL_ID_SHIFT) +#define PMU_METAL_ID(n) (((n) & 0xF) << PMU_METAL_ID_SHIFT) + +// 02 PMU_REG_POWER_KEY_CFG +#define REG_PU_VBAT_DIV (1 << 15) +#define PU_LPO_DR (1 << 14) +#define PU_LPO_REG (1 << 13) +#define POWERKEY_WAKEUP_OSC_EN (1 << 12) +#define RTC_POWER_ON_EN (1 << 11) +#define PU_ALL_REG (1 << 10) +#define CLK_32K_SEL_SHIFT 8 +#define CLK_32K_SEL_MASK (0x3 << CLK_32K_SEL_SHIFT) +#define CLK_32K_SEL(n) BITFIELD_VAL(CLK_32K_SEL, n) +#define DEEPSLEEP_MODE_DIGI_DR (1 << 7) +#define DEEPSLEEP_MODE_DIGI_REG (1 << 6) +#define REG_VCORE_SSTIME_MODE_SHIFT 4 +#define REG_VCORE_SSTIME_MODE_MASK (0x3 << REG_VCORE_SSTIME_MODE_SHIFT) +#define REG_VCORE_SSTIME_MODE(n) BITFIELD_VAL(REG_VCORE_SSTIME_MODE, n) +#define REG_LDO_SS_BIAS_EN_DR (1 << 3) +#define REG_LDO_SS_BIAS_EN (1 << 2) +#define REG_LP_EN_VHPPA_DSLEEP (1 << 1) +#define REG_LP_EN_VHPPA_NORMAL (1 << 0) + +// 03 PMU_REG_BIAS_CFG +#define REG_VSENSE_SEL_VMEM (1 << 15) +#define PU_LP_BIAS_LDO_DSLEEP (1 << 14) +#define PU_LP_BIAS_LDO_DR (1 << 13) +#define PU_LP_BIAS_LDO_REG (1 << 12) +#define PU_BIAS_LDO_DR (1 << 11) +#define PU_BIAS_LDO_REG (1 << 10) +#define BG_VBG_SEL_DR (1 << 9) +#define BG_VBG_SEL_REG (1 << 8) +#define BG_CONSTANT_GM_BIAS_DR (1 << 7) +#define BG_CONSTANT_GM_BIAS_REG (1 << 6) +#define BG_CORE_EN_DR (1 << 5) +#define BG_CORE_EN_REG (1 << 4) +#define REG_PU_LDO_VANA_DR (1 << 3) +#define REG_PU_LDO_VANA (1 << 2) +#define BG_NOTCH_EN_DR (1 << 1) +#define BG_NOTCH_EN_REG (1 << 0) + +#define REG_PU_LDO_VANA_REG REG_PU_LDO_VANA + +// 05 PMU_REG_CHARGER_CFG +#define REG_PU_LDO_VRTC_RF_DSLEEP (1 << 15) +#define REG_PU_LDO_VRTC_RF_DR (1 << 14) +#define REG_PU_LDO_VRTC_RF_REG (1 << 13) +#define REG_CHARGE_OUT_INTR_MSK (1 << 12) +#define REG_CHARGE_IN_INTR_MSK (1 << 11) +#define REG_AC_ON_OUT_EN (1 << 10) +#define REG_AC_ON_IN_EN (1 << 9) +#define REG_CHARGE_INTR_EN (1 << 8) +#define REG_AC_ON_DB_VALUE_SHIFT 0 +#define REG_AC_ON_DB_VALUE_MASK (0xFF << REG_AC_ON_DB_VALUE_SHIFT) +#define REG_AC_ON_DB_VALUE(n) BITFIELD_VAL(REG_AC_ON_DB_VALUE, n) + +// 07 PMU_REG_ANA_CFG +#define REG_LIGHT_LOAD_VANA_BUCK_LDO (1 << 15) +#define REG_PULLDOWN_VANA_LDO (1 << 14) +#define LP_EN_VANA_LDO_DSLEEP (1 << 13) +#define LP_EN_VANA_LDO_DR (1 << 12) +#define LP_EN_VANA_LDO_REG (1 << 11) +#define REG_PU_LDO_VANA_DSLEEP (1 << 10) +#define LDO_ANA_VBIT_DSLEEP_SHIFT 5 +#define LDO_ANA_VBIT_DSLEEP_MASK (0x1F << LDO_ANA_VBIT_DSLEEP_SHIFT) +#define LDO_ANA_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_ANA_VBIT_DSLEEP, n) +#define LDO_ANA_VBIT_NORMAL_SHIFT 0 +#define LDO_ANA_VBIT_NORMAL_MASK (0x1F << LDO_ANA_VBIT_NORMAL_SHIFT) +#define LDO_ANA_VBIT_NORMAL(n) BITFIELD_VAL(LDO_ANA_VBIT_NORMAL, n) + +#define LDO_VANA_VBIT_DSLEEP_SHIFT LDO_ANA_VBIT_DSLEEP_SHIFT +#define LDO_VANA_VBIT_DSLEEP_MASK LDO_ANA_VBIT_DSLEEP_MASK +#define LDO_VANA_VBIT_NORMAL_SHIFT LDO_ANA_VBIT_NORMAL_SHIFT +#define LDO_VANA_VBIT_NORMAL_MASK LDO_ANA_VBIT_NORMAL_MASK + +// 08 PMU_REG_DIG_CFG +#define REG_DCDC_CLK_SE_EN (1 << 15) +#define LP_EN_VCORE_LDO_DSLEEP (1 << 14) +#define LP_EN_VCORE_LDO_DR (1 << 13) +#define LP_EN_VCORE_LDO_REG (1 << 12) +#define LDO_DIG_VBIT_DSLEEP_SHIFT 6 +#define LDO_DIG_VBIT_DSLEEP_MASK (0x3F << LDO_DIG_VBIT_DSLEEP_SHIFT) +#define LDO_DIG_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_DIG_VBIT_DSLEEP, n) +#define LDO_DIG_VBIT_NORMAL_SHIFT 0 +#define LDO_DIG_VBIT_NORMAL_MASK (0x3F << LDO_DIG_VBIT_NORMAL_SHIFT) +#define LDO_DIG_VBIT_NORMAL(n) BITFIELD_VAL(LDO_DIG_VBIT_NORMAL, n) + +#define LDO_VCORE_VBIT_DSLEEP_SHIFT LDO_DIG_VBIT_DSLEEP_SHIFT +#define LDO_VCORE_VBIT_DSLEEP_MASK LDO_DIG_VBIT_DSLEEP_MASK +#define LDO_VCORE_VBIT_NORMAL_SHIFT LDO_DIG_VBIT_NORMAL_SHIFT +#define LDO_VCORE_VBIT_NORMAL_MASK LDO_DIG_VBIT_NORMAL_MASK + +// Real bit is in REG_101 -- but we never change the default value +#define REG_PU_LDO_VCORE_DSLEEP 0 + +// 09 PMU_REG_IO_CFG +#define LP_EN_VIO_LDO_DSLEEP (1 << 15) +#define LP_EN_VIO_LDO_DR (1 << 14) +#define LP_EN_VIO_LDO_REG (1 << 13) +#define REG_PU_LDO_VIO_DSLEEP (1 << 12) +#define REG_PU_LDO_VIO_DR (1 << 11) +#define REG_PU_LDO_VIO (1 << 10) +#define LDO_VIO_VBIT_NORMAL_SHIFT 5 +#define LDO_VIO_VBIT_NORMAL_MASK (0x1F << LDO_VIO_VBIT_NORMAL_SHIFT) +#define LDO_VIO_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VIO_VBIT_NORMAL, n) +#define LDO_VIO_VBIT_DSLEEP_SHIFT 0 +#define LDO_VIO_VBIT_DSLEEP_MASK (0x1F << LDO_VIO_VBIT_DSLEEP_SHIFT) +#define LDO_VIO_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VIO_VBIT_DSLEEP, n) + +#define REG_PU_LDO_VIO_REG REG_PU_LDO_VIO + +// 0A PMU_REG_MEM_CFG +#define LP_EN_VMEM_LDO_DSLEEP (1 << 15) +#define LP_EN_VMEM_LDO_DR (1 << 14) +#define LP_EN_VMEM_LDO_REG (1 << 13) +#define REG_PU_LDO_VMEM_DSLEEP (1 << 12) +#define REG_PU_LDO_VMEM_DR (1 << 11) +#define REG_PU_LDO_VMEM_REG (1 << 10) +#define LDO_VMEM_VBIT_NORMAL_SHIFT 5 +#define LDO_VMEM_VBIT_NORMAL_MASK (0x1F << LDO_VMEM_VBIT_NORMAL_SHIFT) +#define LDO_VMEM_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VMEM_VBIT_NORMAL, n) +#define LDO_VMEM_VBIT_DSLEEP_SHIFT 0 +#define LDO_VMEM_VBIT_DSLEEP_MASK (0x1F << LDO_VMEM_VBIT_DSLEEP_SHIFT) +#define LDO_VMEM_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VMEM_VBIT_DSLEEP, n) + +// 0B PMU_REG_GP_CFG +#define LP_EN_VGP_LDO_DSLEEP (1 << 15) +#define LP_EN_VGP_LDO_DR (1 << 14) +#define LP_EN_VGP_LDO_REG (1 << 13) +#define REG_PU_LDO_VGP_DSLEEP (1 << 12) +#define REG_PU_LDO_VGP_DR (1 << 11) +#define REG_PU_LDO_VGP_REG (1 << 10) +#define LDO_VGP_VBIT_NORMAL_SHIFT 5 +#define LDO_VGP_VBIT_NORMAL_MASK (0x1F << LDO_VGP_VBIT_NORMAL_SHIFT) +#define LDO_VGP_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VGP_VBIT_NORMAL, n) +#define LDO_VGP_VBIT_DSLEEP_SHIFT 0 +#define LDO_VGP_VBIT_DSLEEP_MASK (0x1F << LDO_VGP_VBIT_DSLEEP_SHIFT) +#define LDO_VGP_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VGP_VBIT_DSLEEP, n) + +// 0C PMU_REG_USB_CFG +#define REG_LDO_VANA_LV_MODE (1 << 15) +#define REG_PULLDOWN_VUSB (1 << 14) +#define LP_EN_VUSB_LDO_DSLEEP (1 << 13) +#define LP_EN_VUSB_LDO_DR (1 << 12) +#define LP_EN_VUSB_LDO_REG (1 << 11) +#define PU_LDO_VUSB_DSLEEP (1 << 10) +#define PU_LDO_VUSB_DR (1 << 9) +#define PU_LDO_VUSB_REG (1 << 8) +#define LDO_VUSB_VBIT_NORMAL_SHIFT 4 +#define LDO_VUSB_VBIT_NORMAL_MASK (0xF << LDO_VUSB_VBIT_NORMAL_SHIFT) +#define LDO_VUSB_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VUSB_VBIT_NORMAL, n) +#define LDO_VUSB_VBIT_DSLEEP_SHIFT 0 +#define LDO_VUSB_VBIT_DSLEEP_MASK (0xF << LDO_VUSB_VBIT_DSLEEP_SHIFT) +#define LDO_VUSB_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VUSB_VBIT_DSLEEP, n) + +#define REG_PU_LDO_VUSB_DSLEEP PU_LDO_VUSB_DSLEEP +#define REG_PU_LDO_VUSB_DR PU_LDO_VUSB_DR +#define REG_PU_LDO_VUSB_REG PU_LDO_VUSB_REG + +// 0D PMU_REG_BAT2DIG_CFG +#define LP_EN_VBAT2VCORE_LDO_DR (1 << 15) +#define LP_EN_VBAT2VCORE_LDO (1 << 14) +#define REG_PU_VBAT2VCORE_LDO_DR (1 << 13) +#define REG_PU_VBAT2VCORE_LDO (1 << 12) +#define LDO_VBAT2VCORE_VBIT_DSLEEP_SHIFT 6 +#define LDO_VBAT2VCORE_VBIT_DSLEEP_MASK (0x3F << LDO_VBAT2VCORE_VBIT_DSLEEP_SHIFT) +#define LDO_VBAT2VCORE_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VBAT2VCORE_VBIT_DSLEEP, n) +#define LDO_VBAT2VCORE_VBIT_NORMAL_SHIFT 0 +#define LDO_VBAT2VCORE_VBIT_NORMAL_MASK (0x3F << LDO_VBAT2VCORE_VBIT_NORMAL_SHIFT) +#define LDO_VBAT2VCORE_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VBAT2VCORE_VBIT_NORMAL, n) + +#define LP_EN_VBAT2VCORE_LDO_REG LP_EN_VBAT2VCORE_LDO +#define REG_PU_LDO_VBAT2VCORE_DR REG_PU_VBAT2VCORE_LDO_DR +#define REG_PU_LDO_VBAT2VCORE_REG REG_PU_VBAT2VCORE_LDO +// Real bit is in REG_101 -- but we never change the default value +#define REG_PU_LDO_VBAT2VCORE_DSLEEP 0 + +// 0E PMU_REG_HPPA_LDO_EN +#define REG_PULL_DOWN_VHPPA (1 << 15) +#define REG_PU_LDO_VHPPA_DSLEEP (1 << 14) +#define REG_PU_LDO_VHPPA_EN (1 << 13) +#define REG_RES_SEL_VHPPA_SHIFT 8 +#define REG_RES_SEL_VHPPA_MASK (0x1F << REG_RES_SEL_VHPPA_SHIFT) +#define REG_RES_SEL_VHPPA(n) BITFIELD_VAL(REG_RES_SEL_VHPPA, n) +#define REG_LP_BIAS_SEL_LDO_SHIFT 6 +#define REG_LP_BIAS_SEL_LDO_MASK (0x3 << REG_LP_BIAS_SEL_LDO_SHIFT) +#define REG_LP_BIAS_SEL_LDO(n) BITFIELD_VAL(REG_LP_BIAS_SEL_LDO, n) +#define REG_BYPASS_VBUCK2ANA (1 << 5) +#define REG_PULLDOWN_VBUCK2ANA (1 << 4) +#define REG_PULLDOWN_VIO (1 << 3) +#define REG_PULLDOWN_VMEM (1 << 2) +#define REG_PULLDOWN_VCORE (1 << 1) +#define REG_PULLDOWN_VHPPA2VCODEC (1 << 0) + +// 0F PMU_REG_HPPA2CODEC_CFG +#define PU_LDO_VCODEC_DSLEEP (1 << 15) +#define REG_BYPASS_VCORE (1 << 14) +#define REG_PU_LDO_VHPPA2VCODEC_DR (1 << 13) +#define REG_PU_LDO_VHPPA2VCODEC (1 << 12) +#define LP_EN_VHPPA2VCODEC_LDO_DR (1 << 11) +#define LP_EN_VHPPA2VCODEC_LDO (1 << 10) +#define LDO_VHPPA2VCODEC_VBIT_DSLEEP_SHIFT 5 +#define LDO_VHPPA2VCODEC_VBIT_DSLEEP_MASK (0x1F << LDO_VHPPA2VCODEC_VBIT_DSLEEP_SHIFT) +#define LDO_VHPPA2VCODEC_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VHPPA2VCODEC_VBIT_DSLEEP, n) +#define LDO_VHPPA2VCODEC_VBIT_NORMAL_SHIFT 0 +#define LDO_VHPPA2VCODEC_VBIT_NORMAL_MASK (0x1F << LDO_VHPPA2VCODEC_VBIT_NORMAL_SHIFT) +#define LDO_VHPPA2VCODEC_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VHPPA2VCODEC_VBIT_NORMAL, n) + +#define REG_PU_LDO_VHPPA2VCODEC_REG REG_PU_LDO_VHPPA2VCODEC +#define LP_EN_VHPPA2VCODEC_LDO_REG LP_EN_VHPPA2VCODEC_LDO +#define REG_PU_LDO_VCODEC_DSLEEP PU_LDO_VCODEC_DSLEEP + +// 10 PMU_REG_CODEC_CFG +#define PU_LDO_VCODEC_DR (1 << 15) +#define PU_LDO_VCODEC_REG (1 << 14) +#define LP_EN_VCODEC_LDO_DSLEEP (1 << 13) +#define LP_EN_VCODEC_LDO_DR (1 << 12) +#define LP_EN_VCODEC_LDO_REG (1 << 11) +#define REG_PULLDOWN_VCODEC (1 << 10) +#define LDO_VCODEC_VBIT_NORMAL_SHIFT 5 +#define LDO_VCODEC_VBIT_NORMAL_MASK (0x1F << LDO_VCODEC_VBIT_NORMAL_SHIFT) +#define LDO_VCODEC_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VCODEC_VBIT_NORMAL, n) +#define LDO_VCODEC_VBIT_DSLEEP_SHIFT 0 +#define LDO_VCODEC_VBIT_DSLEEP_MASK (0x1F << LDO_VCODEC_VBIT_DSLEEP_SHIFT) +#define LDO_VCODEC_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VCODEC_VBIT_DSLEEP, n) + +#define REG_PU_LDO_VCODEC_DR PU_LDO_VCODEC_DR +#define REG_PU_LDO_VCODEC_REG PU_LDO_VCODEC_REG + +// 15 PMU_REG_DCDC_DIG_EN +#define REG_UVLO_SEL_SHIFT 14 +#define REG_UVLO_SEL_MASK (0x3 << REG_UVLO_SEL_SHIFT) +#define REG_UVLO_SEL(n) BITFIELD_VAL(REG_UVLO_SEL, n) +#define REG_PU_LDO_DIG_DR (1 << 13) +#define REG_PU_LDO_DIG_REG (1 << 12) +#define REG_DCDC1_PFM_SEL_DSLEEP (1 << 11) +#define REG_DCDC1_PFM_SEL_NORMAL (1 << 10) +#define REG_DCDC1_ULP_MODE_DSLEEP (1 << 9) +#define REG_DCDC1_ULP_MODE_NORMAL (1 << 8) +#define REG_DCDC1_BURST_MODE_SEL_DSLEEP (1 << 7) +#define REG_DCDC1_BURST_MODE_SEL_NORMAL (1 << 6) +#define REG_DCDC1_VREF_SEL_DSLEEP_SHIFT 4 +#define REG_DCDC1_VREF_SEL_DSLEEP_MASK (0x3 << REG_DCDC1_VREF_SEL_DSLEEP_SHIFT) +#define REG_DCDC1_VREF_SEL_DSLEEP(n) BITFIELD_VAL(REG_DCDC1_VREF_SEL_DSLEEP, n) +#define REG_DCDC1_VREF_SEL_NORMAL_SHIFT 2 +#define REG_DCDC1_VREF_SEL_NORMAL_MASK (0x3 << REG_DCDC1_VREF_SEL_NORMAL_SHIFT) +#define REG_DCDC1_VREF_SEL_NORMAL(n) BITFIELD_VAL(REG_DCDC1_VREF_SEL_NORMAL, n) +#define REG_PU_DCDC1_DR (1 << 1) +#define REG_PU_DCDC1 (1 << 0) + +#define REG_PU_LDO_VCORE_DR REG_PU_LDO_DIG_DR +#define REG_PU_LDO_VCORE_REG REG_PU_LDO_DIG_REG + +// 19 PMU_REG_DCDC_ANA_CFG_19 +#define DCDC2_IX2_ERR (1 << 15) +#define DCDC2_IX2_IRCOMP (1 << 14) +#define DCDC2_LP_ERR (1 << 13) +#define DCDC2_LP_VCOMP (1 << 12) +#define DCDC2_PULLDOWN_EN (1 << 11) +#define DCDC2_SLOPE_DOUBLE (1 << 10) +#define DCDC2_SLOPE_EN_BURST (1 << 9) +#define DCDC2_SOFT_START_EN (1 << 8) +#define DCDC2_SS_TIME_SEL (1 << 7) +#define DCDC2_SYNC_DISABLE (1 << 6) +#define DCDC2_TEST_MODE_EN (1 << 5) +#define DCDC2_ZCD_CAL_BIT_SHIFT 1 +#define DCDC2_ZCD_CAL_BIT_MASK (0xF << DCDC2_ZCD_CAL_BIT_SHIFT) +#define DCDC2_ZCD_CAL_BIT(n) BITFIELD_VAL(DCDC2_ZCD_CAL_BIT, n) +#define DCDC2_REG_BYPASS (1 << 0) + +// 1D PMU_REG_DCDC_HPPA_CFG_1D +#define DCDC3_IX2_ERR (1 << 15) +#define DCDC3_IX2_IRCOMP (1 << 14) +#define DCDC3_LP_ERR (1 << 13) +#define DCDC3_LP_VCOMP (1 << 12) +#define DCDC3_PULLDOWN_EN (1 << 11) +#define DCDC3_SLOPE_DOUBLE (1 << 10) +#define DCDC3_SLOPE_EN_BURST (1 << 9) +#define DCDC3_SOFT_START_EN (1 << 8) +#define DCDC3_SS_TIME_SEL (1 << 7) +#define DCDC3_SYNC_DISABLE (1 << 6) +#define DCDC3_TEST_MODE_EN (1 << 5) +#define DCDC3_ZCD_CAL_BIT_SHIFT 1 +#define DCDC3_ZCD_CAL_BIT_MASK (0xF << DCDC3_ZCD_CAL_BIT_SHIFT) +#define DCDC3_ZCD_CAL_BIT(n) BITFIELD_VAL(DCDC3_ZCD_CAL_BIT, n) +#define DCDC3_REG_BYPASS (1 << 0) + +// 21 PMU_REG_PWR_SEL +#define REG_PMU_VSEL1_SHIFT 13 +#define REG_PMU_VSEL1_MASK (0x7 << REG_PMU_VSEL1_SHIFT) +#define REG_PMU_VSEL1(n) BITFIELD_VAL(REG_PMU_VSEL1, n) +#define REG_POWER_SEL_CNT_SHIFT 8 +#define REG_POWER_SEL_CNT_MASK (0x1F << REG_POWER_SEL_CNT_SHIFT) +#define REG_POWER_SEL_CNT(n) BITFIELD_VAL(REG_POWER_SEL_CNT, n) +#define REG_PWR_SEL_DR (1 << 7) +#define REG_PWR_SEL (1 << 6) +#define CLK_BG_EN (1 << 5) +#define CLK_BG_DIV_VALUE_SHIFT 0 +#define CLK_BG_DIV_VALUE_MASK (0x1F << CLK_BG_DIV_VALUE_SHIFT) +#define CLK_BG_DIV_VALUE(n) BITFIELD_VAL(CLK_BG_DIV_VALUE, n) + +// 26 PMU_REG_INT_MASK +#define RESET_EN_VCORE_LOW (1 << 15) +#define RTC_INT1_MSK (1 << 14) +#define RTC_INT0_MSK (1 << 13) +#define KEY_ERR1_INTR_MSK (1 << 12) +#define KEY_ERR0_INTR_MSK (1 << 11) +#define KEY_PRESS_INTR_MSK (1 << 10) +#define KEY_RELEASE_INTR_MSK (1 << 9) +#define SAMPLE_DONE_INTR_MSK (1 << 8) +#define CHAN_DATA_INTR_MSK_SHIFT 0 +#define CHAN_DATA_INTR_MSK_MASK (0xFF << CHAN_DATA_INTR_MSK_SHIFT) +#define CHAN_DATA_INTR_MSK(n) BITFIELD_VAL(CHAN_DATA_INTR_MSK, n) + +// 27 PMU_REG_INT_EN +#define REG_BG_SLEEP_MSK (1 << 15) +#define RTC_INT_EN_1 (1 << 14) +#define RTC_INT_EN_0 (1 << 13) +#define KEY_ERR1_INTR_EN (1 << 12) +#define KEY_ERR0_INTR_EN (1 << 11) +#define KEY_PRESS_INTR_EN (1 << 10) +#define KEY_RELEASE_INTR_EN (1 << 9) +#define SAMPLE_DONE_INTR_EN (1 << 8) +#define CHAN_DATA_INTR_EN_SHIFT 0 +#define CHAN_DATA_INTR_EN_MASK (0xFF << CHAN_DATA_INTR_EN_SHIFT) +#define CHAN_DATA_INTR_EN(n) BITFIELD_VAL(CHAN_DATA_INTR_EN, n) + +// 36 PMU_REG_DCDC_DIG_CFG_36 +#define DCDC1_IX2_ERR (1 << 15) +#define DCDC1_IX2_IRCOMP (1 << 14) +#define DCDC1_LP_ERR (1 << 13) +#define DCDC1_LP_VCOMP (1 << 12) +#define DCDC1_PULLDOWN_EN (1 << 11) +#define DCDC1_SLOPE_DOUBLE (1 << 10) +#define DCDC1_SLOPE_EN_BURST (1 << 9) +#define DCDC1_SOFT_START_EN (1 << 8) +#define DCDC1_SS_TIME_SEL (1 << 7) +#define DCDC1_SYNC_DISABLE (1 << 6) +#define DCDC1_TEST_MODE_EN (1 << 5) +#define DCDC1_ZCD_CAL_BIT_SHIFT 1 +#define DCDC1_ZCD_CAL_BIT_MASK (0xF << DCDC1_ZCD_CAL_BIT_SHIFT) +#define DCDC1_ZCD_CAL_BIT(n) BITFIELD_VAL(DCDC1_ZCD_CAL_BIT, n) +#define DCDC1_REG_BYPASS (1 << 0) + +// 38 PMU_REG_MIC_BIAS_E +#define REG_MIC_BIASE_CHANSEL_SHIFT 14 +#define REG_MIC_BIASE_CHANSEL_MASK (0x3 << REG_MIC_BIASE_CHANSEL_SHIFT) +#define REG_MIC_BIASE_CHANSEL(n) BITFIELD_VAL(REG_MIC_BIASE_CHANSEL, n) +#define REG_MIC_BIASE_EN (1 << 13) +#define REG_MIC_BIASE_ENLPF (1 << 12) +#define REG_MIC_BIASE_LPFSEL_SHIFT 10 +#define REG_MIC_BIASE_LPFSEL_MASK (0x3 << REG_MIC_BIASE_LPFSEL_SHIFT) +#define REG_MIC_BIASE_LPFSEL(n) BITFIELD_VAL(REG_MIC_BIASE_LPFSEL, n) +#define REG_MIC_BIASE_VSEL_SHIFT 5 +#define REG_MIC_BIASE_VSEL_MASK (0x1F << REG_MIC_BIASE_VSEL_SHIFT) +#define REG_MIC_BIASE_VSEL(n) BITFIELD_VAL(REG_MIC_BIASE_VSEL, n) +#define REG_MIC_LDOE_RES_SHIFT 1 +#define REG_MIC_LDOE_RES_MASK (0xF << REG_MIC_LDOE_RES_SHIFT) +#define REG_MIC_LDOE_RES(n) BITFIELD_VAL(REG_MIC_LDOE_RES, n) +#define REG_MIC_LDOE_LOOPCTRL (1 << 0) + +// 39 PMU_REG_MIC_LDO_EN +#define REG_LED_IO1_AIO_EN (1 << 15) +#define REG_LED_IO2_AIO_EN (1 << 14) +#define REG_LED_IO1_RX_EN (1 << 13) +#define REG_LED_IO2_RX_EN (1 << 12) +#define REG_MIC_LDOA_EN (1 << 11) +#define REG_MIC_LDOB_EN (1 << 10) +#define REG_MIC_LDOC_EN (1 << 9) +#define REG_MIC_LDOD_EN (1 << 8) +#define REG_MIC_LDOE_EN (1 << 7) +#define DCDC1_OFFSET_CURRENT_EN (1 << 6) +#define DCDC2_OFFSET_CURRENT_EN (1 << 5) +#define DCDC3_OFFSET_CURRENT_EN (1 << 4) +#define DCDC4_OFFSET_CURRENT_EN (1 << 3) + +// 3A PMU_REG_LED_CFG +#define REG_LED_IO1_IBIT_SHIFT 14 +#define REG_LED_IO1_IBIT_MASK (0x3 << REG_LED_IO1_IBIT_SHIFT) +#define REG_LED_IO1_IBIT(n) BITFIELD_VAL(REG_LED_IO1_IBIT, n) +#define REG_LED_IO1_OENB (1 << 13) +#define REG_LED_IO1_PDEN (1 << 12) +#define REG_LED_IO1_PU (1 << 11) +#define REG_LED_IO1_PUEN (1 << 10) +#define REG_LED_IO1_SEL_SHIFT 8 +#define REG_LED_IO1_SEL_MASK (0x3 << REG_LED_IO1_SEL_SHIFT) +#define REG_LED_IO1_SEL(n) BITFIELD_VAL(REG_LED_IO1_SEL, n) +#define REG_LED_IO2_IBIT_SHIFT 6 +#define REG_LED_IO2_IBIT_MASK (0x3 << REG_LED_IO2_IBIT_SHIFT) +#define REG_LED_IO2_IBIT(n) BITFIELD_VAL(REG_LED_IO2_IBIT, n) +#define REG_LED_IO2_OENB (1 << 5) +#define REG_LED_IO2_PDEN (1 << 4) +#define REG_LED_IO2_PU (1 << 3) +#define REG_LED_IO2_PUEN (1 << 2) +#define REG_LED_IO2_SEL_SHIFT 0 +#define REG_LED_IO2_SEL_MASK (0x3 << REG_LED_IO2_SEL_SHIFT) +#define REG_LED_IO2_SEL(n) BITFIELD_VAL(REG_LED_IO2_SEL, n) + +// 3B PMU_REG_MIC_BIAS_A +#define REG_MIC_BIASA_CHANSEL_SHIFT 14 +#define REG_MIC_BIASA_CHANSEL_MASK (0x3 << REG_MIC_BIASA_CHANSEL_SHIFT) +#define REG_MIC_BIASA_CHANSEL(n) BITFIELD_VAL(REG_MIC_BIASA_CHANSEL, n) +#define REG_MIC_BIASA_EN (1 << 13) +#define REG_MIC_BIASA_ENLPF (1 << 12) +#define REG_MIC_BIASA_LPFSEL_SHIFT 10 +#define REG_MIC_BIASA_LPFSEL_MASK (0x3 << REG_MIC_BIASA_LPFSEL_SHIFT) +#define REG_MIC_BIASA_LPFSEL(n) BITFIELD_VAL(REG_MIC_BIASA_LPFSEL, n) +#define REG_MIC_BIASA_VSEL_SHIFT 5 +#define REG_MIC_BIASA_VSEL_MASK (0x1F << REG_MIC_BIASA_VSEL_SHIFT) +#define REG_MIC_BIASA_VSEL(n) BITFIELD_VAL(REG_MIC_BIASA_VSEL, n) +#define REG_MIC_LDOA_RES_SHIFT 1 +#define REG_MIC_LDOA_RES_MASK (0xF << REG_MIC_LDOA_RES_SHIFT) +#define REG_MIC_LDOA_RES(n) BITFIELD_VAL(REG_MIC_LDOA_RES, n) +#define REG_MIC_LDOA_LOOPCTRL (1 << 0) + +// 3C PMU_REG_MIC_BIAS_B +#define REG_MIC_BIASB_CHANSEL_SHIFT 14 +#define REG_MIC_BIASB_CHANSEL_MASK (0x3 << REG_MIC_BIASB_CHANSEL_SHIFT) +#define REG_MIC_BIASB_CHANSEL(n) BITFIELD_VAL(REG_MIC_BIASB_CHANSEL, n) +#define REG_MIC_BIASB_EN (1 << 13) +#define REG_MIC_BIASB_ENLPF (1 << 12) +#define REG_MIC_BIASB_LPFSEL_SHIFT 10 +#define REG_MIC_BIASB_LPFSEL_MASK (0x3 << REG_MIC_BIASB_LPFSEL_SHIFT) +#define REG_MIC_BIASB_LPFSEL(n) BITFIELD_VAL(REG_MIC_BIASB_LPFSEL, n) +#define REG_MIC_BIASB_VSEL_SHIFT 5 +#define REG_MIC_BIASB_VSEL_MASK (0x1F << REG_MIC_BIASB_VSEL_SHIFT) +#define REG_MIC_BIASB_VSEL(n) BITFIELD_VAL(REG_MIC_BIASB_VSEL, n) +#define REG_MIC_LDOB_RES_SHIFT 1 +#define REG_MIC_LDOB_RES_MASK (0xF << REG_MIC_LDOB_RES_SHIFT) +#define REG_MIC_LDOB_RES(n) BITFIELD_VAL(REG_MIC_LDOB_RES, n) +#define REG_MIC_LDOB_LOOPCTRL (1 << 0) + +// 3D PMU_REG_MIC_BIAS_C +#define REG_MIC_BIASC_CHANSEL_SHIFT 14 +#define REG_MIC_BIASC_CHANSEL_MASK (0x3 << REG_MIC_BIASC_CHANSEL_SHIFT) +#define REG_MIC_BIASC_CHANSEL(n) BITFIELD_VAL(REG_MIC_BIASC_CHANSEL, n) +#define REG_MIC_BIASC_EN (1 << 13) +#define REG_MIC_BIASC_ENLPF (1 << 12) +#define REG_MIC_BIASC_LPFSEL_SHIFT 10 +#define REG_MIC_BIASC_LPFSEL_MASK (0x3 << REG_MIC_BIASC_LPFSEL_SHIFT) +#define REG_MIC_BIASC_LPFSEL(n) BITFIELD_VAL(REG_MIC_BIASC_LPFSEL, n) +#define REG_MIC_BIASC_VSEL_SHIFT 5 +#define REG_MIC_BIASC_VSEL_MASK (0x1F << REG_MIC_BIASC_VSEL_SHIFT) +#define REG_MIC_BIASC_VSEL(n) BITFIELD_VAL(REG_MIC_BIASC_VSEL, n) +#define REG_MIC_LDOC_RES_SHIFT 1 +#define REG_MIC_LDOC_RES_MASK (0xF << REG_MIC_LDOC_RES_SHIFT) +#define REG_MIC_LDOC_RES(n) BITFIELD_VAL(REG_MIC_LDOC_RES, n) +#define REG_MIC_LDOC_LOOPCTRL (1 << 0) + +// 3E PMU_REG_MIC_BIAS_D +#define REG_MIC_BIASD_CHANSEL_SHIFT 14 +#define REG_MIC_BIASD_CHANSEL_MASK (0x3 << REG_MIC_BIASD_CHANSEL_SHIFT) +#define REG_MIC_BIASD_CHANSEL(n) BITFIELD_VAL(REG_MIC_BIASD_CHANSEL, n) +#define REG_MIC_BIASD_EN (1 << 13) +#define REG_MIC_BIASD_ENLPF (1 << 12) +#define REG_MIC_BIASD_LPFSEL_SHIFT 10 +#define REG_MIC_BIASD_LPFSEL_MASK (0x3 << REG_MIC_BIASD_LPFSEL_SHIFT) +#define REG_MIC_BIASD_LPFSEL(n) BITFIELD_VAL(REG_MIC_BIASD_LPFSEL, n) +#define REG_MIC_BIASD_VSEL_SHIFT 5 +#define REG_MIC_BIASD_VSEL_MASK (0x1F << REG_MIC_BIASD_VSEL_SHIFT) +#define REG_MIC_BIASD_VSEL(n) BITFIELD_VAL(REG_MIC_BIASD_VSEL, n) +#define REG_MIC_LDOD_RES_SHIFT 1 +#define REG_MIC_LDOD_RES_MASK (0xF << REG_MIC_LDOD_RES_SHIFT) +#define REG_MIC_LDOD_RES(n) BITFIELD_VAL(REG_MIC_LDOD_RES, n) +#define REG_MIC_LDOD_LOOPCTRL (1 << 0) + +// 3F PMU_REG_EFUSE_CTRL +#define TSMC_EFUSE_A_SHIFT 0 +#define TSMC_EFUSE_A_MASK (0x3F << TSMC_EFUSE_A_SHIFT) +#define TSMC_EFUSE_A(n) BITFIELD_VAL(TSMC_EFUSE_A, n) +#define TSMC_EFUSE_CLK_EN (1 << 8) +#define TSMC_EFUSE_NR (1 << 9) +#define TSMC_EFUSE_MR (1 << 10) +#define MANUAL_MODE (1 << 11) +#define TSMC_EFUSE_PGENB (1 << 12) +#define REG_MARGIN_READ (1 << 13) + +// 40 PMU_REG_EFUSE_SEL +#define TSMC_EFUSE_STROBE_TRIG (1 << 0) +#define TSMC_EFUSE_STROBE_WIDTH_SHIFT 1 +#define TSMC_EFUSE_STROBE_WIDTH_MASK (0xFF << TSMC_EFUSE_STROBE_WIDTH_SHIFT) +#define TSMC_EFUSE_STROBE_WIDTH(n) BITFIELD_VAL(TSMC_EFUSE_STROBE_WIDTH, n) +#define REG_READ_STROBE_WIDTH_SHIFT 9 +#define REG_READ_STROBE_WIDTH_MASK (0xF << REG_READ_STROBE_WIDTH_SHIFT) +#define REG_READ_STROBE_WIDTH(n) BITFIELD_VAL(REG_READ_STROBE_WIDTH, n) +#define EFUSE_SEL_SHIFT 13 +#define EFUSE_SEL_MASK (0x7 << EFUSE_SEL_SHIFT) +#define EFUSE_SEL(n) BITFIELD_VAL(EFUSE_SEL, n) + +// 41 PMU_REG_DCDC1_OFFSET +#define DCDC1_OFFSET_BIT_SHIFT 8 +#define DCDC1_OFFSET_BIT_MASK (0xFF << DCDC1_OFFSET_BIT_SHIFT) +#define DCDC1_OFFSET_BIT(n) BITFIELD_VAL(DCDC1_OFFSET_BIT, n) +#define DCDC2_OFFSET_BIT_SHIFT 0 +#define DCDC2_OFFSET_BIT_MASK (0xFF << DCDC2_OFFSET_BIT_SHIFT) +#define DCDC2_OFFSET_BIT(n) BITFIELD_VAL(DCDC2_OFFSET_BIT, n) + +// 43 PMU_REG_BUCK2ANA_CFG +#define REG_PU_VBUCK2ANA_LDO_DR (1 << 15) +#define REG_PU_VBUCK2ANA_LDO (1 << 14) +#define LP_EN_VBUCK2ANA_LDO_DR (1 << 13) +#define LP_EN_VBUCK2ANA_LDO (1 << 12) +#define LDO_VBUCK2ANA_VBIT_DSLEEP_SHIFT 6 +#define LDO_VBUCK2ANA_VBIT_DSLEEP_MASK (0x3F << LDO_VBUCK2ANA_VBIT_DSLEEP_SHIFT) +#define LDO_VBUCK2ANA_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VBUCK2ANA_VBIT_DSLEEP, n) +#define LDO_VBUCK2ANA_VBIT_NORMAL_SHIFT 0 +#define LDO_VBUCK2ANA_VBIT_NORMAL_MASK (0x3F << LDO_VBUCK2ANA_VBIT_NORMAL_SHIFT) +#define LDO_VBUCK2ANA_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VBUCK2ANA_VBIT_NORMAL, n) + +#define REG_PU_LDO_VBUCK2ANA_DR REG_PU_VBUCK2ANA_LDO_DR +#define REG_PU_LDO_VBUCK2ANA_REG REG_PU_VBUCK2ANA_LDO +#define LP_EN_VBUCK2ANA_LDO_REG LP_EN_VBUCK2ANA_LDO +// No pu dsleep cfg +#define REG_PU_LDO_VBUCK2ANA_DSLEEP 0 + +// 44 PMU_REG_SLEEP_CFG +#define PMIC_TMODE_1300_SHIFT 0 +#define PMIC_TMODE_1300_MASK (0x7 << PMIC_TMODE_1300_SHIFT) +#define PMIC_TMODE_1300(n) BITFIELD_VAL(PMIC_TMODE_1300, n) +#define POWERON_PRESS_EN (1 << 3) +#define POWERON_RELEASE_EN (1 << 4) +#define SLEEP_ALLOW (1 << 5) +#define REG_VHPPA2VCODEC_SLP_ON (1 << 6) + +#define REG_PU_LDO_VHPPA2VCODEC_DSLEEP REG_VHPPA2VCODEC_SLP_ON + +// 46 PMU_REG_DCDC_DIG_VOLT +#define REG_DCDC1_VBIT_DSLEEP_SHIFT 8 +#define REG_DCDC1_VBIT_DSLEEP_MASK (0xFF << REG_DCDC1_VBIT_DSLEEP_SHIFT) +#define REG_DCDC1_VBIT_DSLEEP(n) BITFIELD_VAL(REG_DCDC1_VBIT_DSLEEP, n) +#define REG_DCDC1_VBIT_NORMAL_SHIFT 0 +#define REG_DCDC1_VBIT_NORMAL_MASK (0xFF << REG_DCDC1_VBIT_NORMAL_SHIFT) +#define REG_DCDC1_VBIT_NORMAL(n) BITFIELD_VAL(REG_DCDC1_VBIT_NORMAL, n) +#define MAX_DCDC1_VBIT_VAL (REG_DCDC1_VBIT_NORMAL_MASK >> REG_DCDC1_VBIT_NORMAL_SHIFT) + +// 47 PMU_REG_DCDC_ANA_VOLT +#define REG_DCDC2_VBIT_DSLEEP_SHIFT 8 +#define REG_DCDC2_VBIT_DSLEEP_MASK (0xFF << REG_DCDC2_VBIT_DSLEEP_SHIFT) +#define REG_DCDC2_VBIT_DSLEEP(n) BITFIELD_VAL(REG_DCDC2_VBIT_DSLEEP, n) +#define REG_DCDC2_VBIT_NORMAL_SHIFT 0 +#define REG_DCDC2_VBIT_NORMAL_MASK (0xFF << REG_DCDC2_VBIT_NORMAL_SHIFT) +#define REG_DCDC2_VBIT_NORMAL(n) BITFIELD_VAL(REG_DCDC2_VBIT_NORMAL, n) +#define MAX_DCDC2_VBIT_VAL (REG_DCDC2_VBIT_NORMAL_MASK >> REG_DCDC2_VBIT_NORMAL_SHIFT) + +// 48 PMU_REG_DCDC_HPPA_VOLT +#define REG_DCDC3_VBIT_DSLEEP_SHIFT 8 +#define REG_DCDC3_VBIT_DSLEEP_MASK (0xFF << REG_DCDC3_VBIT_DSLEEP_SHIFT) +#define REG_DCDC3_VBIT_DSLEEP(n) BITFIELD_VAL(REG_DCDC3_VBIT_DSLEEP, n) +#define REG_DCDC3_VBIT_NORMAL_SHIFT 0 +#define REG_DCDC3_VBIT_NORMAL_MASK (0xFF << REG_DCDC3_VBIT_NORMAL_SHIFT) +#define REG_DCDC3_VBIT_NORMAL(n) BITFIELD_VAL(REG_DCDC3_VBIT_NORMAL, n) +#define MAX_DCDC3_VBIT_VAL (REG_DCDC3_VBIT_NORMAL_MASK >> REG_DCDC3_VBIT_NORMAL_SHIFT) + +// 49 PMU_REG_DCDC4_VOLT +#define REG_DCDC4_VBIT_DSLEEP_SHIFT 8 +#define REG_DCDC4_VBIT_DSLEEP_MASK (0xFF << REG_DCDC4_VBIT_DSLEEP_SHIFT) +#define REG_DCDC4_VBIT_DSLEEP(n) BITFIELD_VAL(REG_DCDC4_VBIT_DSLEEP, n) +#define REG_DCDC4_VBIT_NORMAL_SHIFT 0 +#define REG_DCDC4_VBIT_NORMAL_MASK (0xFF << REG_DCDC4_VBIT_NORMAL_SHIFT) +#define REG_DCDC4_VBIT_NORMAL(n) BITFIELD_VAL(REG_DCDC4_VBIT_NORMAL, n) + +// 4A PMU_REG_DCDC_ANA_EN +#define REG_DCDC2_PFM_SEL_DSLEEP (1 << 11) +#define REG_DCDC2_PFM_SEL_NORMAL (1 << 10) +#define REG_DCDC2_ULP_MODE_DSLEEP (1 << 9) +#define REG_DCDC2_ULP_MODE_NORMAL (1 << 8) +#define REG_DCDC2_BURST_MODE_SEL_DSLEEP (1 << 7) +#define REG_DCDC2_BURST_MODE_SEL_NORMAL (1 << 6) +#define REG_DCDC2_VREF_SEL_DSLEEP_SHIFT 4 +#define REG_DCDC2_VREF_SEL_DSLEEP_MASK (0x3 << REG_DCDC2_VREF_SEL_DSLEEP_SHIFT) +#define REG_DCDC2_VREF_SEL_DSLEEP(n) BITFIELD_VAL(REG_DCDC2_VREF_SEL_DSLEEP, n) +#define REG_DCDC2_VREF_SEL_NORMAL_SHIFT 2 +#define REG_DCDC2_VREF_SEL_NORMAL_MASK (0x3 << REG_DCDC2_VREF_SEL_NORMAL_SHIFT) +#define REG_DCDC2_VREF_SEL_NORMAL(n) BITFIELD_VAL(REG_DCDC2_VREF_SEL_NORMAL, n) +#define REG_PU_DCDC2_DR (1 << 1) +#define REG_PU_DCDC2 (1 << 0) + +// 4B PMU_REG_DCDC_HPPA_EN +#define REG_DCDC3_PFM_SEL_DSLEEP (1 << 11) +#define REG_DCDC3_PFM_SEL_NORMAL (1 << 10) +#define REG_DCDC3_ULP_MODE_DSLEEP (1 << 9) +#define REG_DCDC3_ULP_MODE_NORMAL (1 << 8) +#define REG_DCDC3_BURST_MODE_SEL_DSLEEP (1 << 7) +#define REG_DCDC3_BURST_MODE_SEL_NORMAL (1 << 6) +#define REG_DCDC3_VREF_SEL_DSLEEP_SHIFT 4 +#define REG_DCDC3_VREF_SEL_DSLEEP_MASK (0x3 << REG_DCDC3_VREF_SEL_DSLEEP_SHIFT) +#define REG_DCDC3_VREF_SEL_DSLEEP(n) BITFIELD_VAL(REG_DCDC3_VREF_SEL_DSLEEP, n) +#define REG_DCDC3_VREF_SEL_NORMAL_SHIFT 2 +#define REG_DCDC3_VREF_SEL_NORMAL_MASK (0x3 << REG_DCDC3_VREF_SEL_NORMAL_SHIFT) +#define REG_DCDC3_VREF_SEL_NORMAL(n) BITFIELD_VAL(REG_DCDC3_VREF_SEL_NORMAL, n) +#define REG_PU_DCDC3_DR (1 << 1) +#define REG_PU_DCDC3 (1 << 0) + +// 4C PMU_REG_DCDC4_EN +#define REG_DCDC4_PFM_SEL_DSLEEP (1 << 11) +#define REG_DCDC4_PFM_SEL_NORMAL (1 << 10) +#define REG_DCDC4_ULP_MODE_DSLEEP (1 << 9) +#define REG_DCDC4_ULP_MODE_NORMAL (1 << 8) +#define REG_DCDC4_BURST_MODE_SEL_DSLEEP (1 << 7) +#define REG_DCDC4_BURST_MODE_SEL_NORMAL (1 << 6) +#define REG_DCDC4_VREF_SEL_DSLEEP_SHIFT 4 +#define REG_DCDC4_VREF_SEL_DSLEEP_MASK (0x3 << REG_DCDC4_VREF_SEL_DSLEEP_SHIFT) +#define REG_DCDC4_VREF_SEL_DSLEEP(n) BITFIELD_VAL(REG_DCDC4_VREF_SEL_DSLEEP, n) +#define REG_DCDC4_VREF_SEL_NORMAL_SHIFT 2 +#define REG_DCDC4_VREF_SEL_NORMAL_MASK (0x3 << REG_DCDC4_VREF_SEL_NORMAL_SHIFT) +#define REG_DCDC4_VREF_SEL_NORMAL(n) BITFIELD_VAL(REG_DCDC4_VREF_SEL_NORMAL, n) +#define REG_PU_DCDC4_DR (1 << 1) +#define REG_PU_DCDC4 (1 << 0) + +// 4F PMU_REG_POWER_OFF +#define SOFT_POWER_OFF (1 << 0) +#define HARDWARE_POWER_OFF_EN (1 << 1) +#define AC_ON_EN (1 << 2) +#define RC_CAL_READY (1 << 3) +#define KEY_START (1 << 4) +#define GPADC_START (1 << 5) +#define EFUSE_READ_DONE (1 << 6) +#define EFUSE_READ_BUSY (1 << 7) +#define VBAT_OVP (1 << 8) +#define VCORE_LOW (1 << 9) +#define REG_LED_IO1_DATA_IN (1 << 10) +#define REG_LED_IO2_DATA_IN (1 << 11) +#define RD_EFUSE_REG (1 << 12) +#define REG_WDT_LOAD (1 << 13) + +#define EFUSE_READ_TRIG_SHIFT (12) +#define EFUSE_READ_TRIG_MASK (0xF << EFUSE_READ_TRIG_SHIFT) +#define EFUSE_READ_TRIG(n) BITFIELD_VAL(EFUSE_READ_TRIG, n) +#define EFUSE_READ_TRIG_WORD (0xA) + +// 52 PMU_REG_INT_STATUS +#define RD_RES1 (1 << 15) +#define RTC_INT_1 (1 << 14) +#define RTC_INT_0 (1 << 13) +#define KEY_ERR1_INTR (1 << 12) +#define KEY_ERR0_INTR (1 << 11) +#define KEY_PRESS_INTR (1 << 10) +#define KEY_RELEASE_INTR (1 << 9) +#define SAMPLE_PERIOD_DONE_INTR (1 << 8) +#define CHAN_DATA_VALID_INTR_SHIFT 0 +#define CHAN_DATA_VALID_INTR_MASK (0xFF << CHAN_DATA_VALID_INTR_SHIFT) +#define CHAN_DATA_VALID_INTR(n) BITFIELD_VAL(CHAN_DATA_VALID_INTR, n) + +// 53 PMU_REG_INT_MSKED_STATUS +// 51 PMU_REG_INT_CLR +#define PMIC_CODEC_PWM (1 << 15) +#define RTC_INT1_MSKED (1 << 14) +#define RTC_INT0_MSKED (1 << 13) +#define KEY_ERR1_INTR_MSKED (1 << 12) +#define KEY_ERR0_INTR_MSKED (1 << 11) +#define KEY_PRESS_INTR_MSKED (1 << 10) +#define KEY_RELEASE_INTR_MSKED (1 << 9) +#define SAMPLE_DONE_INTR_MSKED (1 << 8) +#define CHAN_DATA_INTR_MSKED_SHIFT 0 +#define CHAN_DATA_INTR_MSKED_MASK (0xFF << CHAN_DATA_INTR_MSKED_SHIFT) +#define CHAN_DATA_INTR_MSKED(n) BITFIELD_VAL(CHAN_DATA_INTR_MSKED, n) + +// 5E PMU_REG_CHARGER_STATUS +#define DIG_PU_VHPPA (1 << 15) +#define DIG_PU_VRTC_RF (1 << 14) +#define DIG_PU_VCODEC (1 << 13) +#define DIG_PU_VUSB (1 << 12) +#define POWER_ON_RELEASE (1 << 11) +#define POWER_ON_PRESS (1 << 10) +#define POWER_ON (1 << 9) +#define DEEPSLEEP_MODE (1 << 8) +//#define PMU_LDO_ON (1 << 7) +#define PU_OSC_OUT (1 << 6) +#define UVLO_LV (1 << 5) +#define AC_ON_DET_OUT_MASKED (1 << 4) +#define AC_ON_DET_IN_MASKED (1 << 3) +#define AC_ON (1 << 2) +#define AC_ON_DET_OUT (1 << 1) +#define AC_ON_DET_IN (1 << 0) + +// 77 PMU_REG_ANA_77 +#define REG_AUDPLL_DIVN_SHIFT 0 +#define REG_AUDPLL_DIVN_MASK (0x1F << REG_AUDPLL_DIVN_SHIFT) +#define REG_AUDPLL_DIVN(n) BITFIELD_VAL(REG_AUDPLL_DIVN, n) +#define REG_AUDPLL_DIVN_RST (1 << 5) +#define REG_AUDPLL_DIV_DR (1 << 6) +#define REG_AUDPLL_EN_CLKA (1 << 7) +#define REG_AUDPLL_EN_CLKD (1 << 8) +#define REG_AUDPLL_FORCE_LK (1 << 9) +#define REG_AUDPLL_LK_ERR23 (1 << 10) +#define REG_AUDPLL_LK_LONG (1 << 11) +#define REG_AUDPLL_LK_RSTB (1 << 12) +#define REG_AUDPLL_LK_WIN_SHIFT 13 +#define REG_AUDPLL_LK_WIN_MASK (0x7 << REG_AUDPLL_LK_WIN_SHIFT) +#define REG_AUDPLL_LK_WIN(n) BITFIELD_VAL(REG_AUDPLL_LK_WIN, n) + +// 101 PMU_REG_DCDC_RAMP_EN +#define REG_MIC_BIASA_IX2 (1 << 15) +#define REG_MIC_BIASB_IX2 (1 << 14) +#define REG_MIC_BIASC_IX2 (1 << 13) +#define REG_MIC_BIASD_IX2 (1 << 12) +#define REG_MIC_BIASE_IX2 (1 << 11) +#define REG_PULLDOWN_VGP (1 << 10) +#define REG_PU_LDO_DIG_DSLEEP (1 << 9) +#define LDO_VHPPA2VCODEC_BYPASS (1 << 8) +#define LDO_VGP_LV_MODE (1 << 7) +#define IPTAT_EN (1 << 6) +#define REG_PU_AVDD25_ANA (1 << 5) +#define REG_DCDC1_RAMP_EN (1 << 4) +#define REG_DCDC2_RAMP_EN (1 << 3) +#define REG_DCDC3_RAMP_EN (1 << 2) +#define REG_PU_VMEM_DELAY_DR (1 << 1) +#define REG_PU_VMEM_DELAY (1 << 0) + +// 107 PMU_REG_SUBCNT_DATA +#define SUBCNT_DATA2_SHIFT 8 +#define SUBCNT_DATA2_MASK (0xFF << SUBCNT_DATA2_SHIFT) +#define SUBCNT_DATA2(n) BITFIELD_VAL(SUBCNT_DATA2, n) +#define SUBCNT_DATA3_SHIFT 0 +#define SUBCNT_DATA3_MASK (0xFF << SUBCNT_DATA3_SHIFT) +#define SUBCNT_DATA3(n) BITFIELD_VAL(SUBCNT_DATA3, n) + +// 108 PMU_REG_PWM_BR_EN +#define TG_SUBCNT_D2_ST_SHIFT 9 +#define TG_SUBCNT_D2_ST_MASK (0x7F << TG_SUBCNT_D2_ST_SHIFT) +#define TG_SUBCNT_D2_ST(n) BITFIELD_VAL(TG_SUBCNT_D2_ST, n) +#define REG_PWM2_BR_EN (1 << 8) +#define TG_SUBCNT_D3_ST_SHIFT 1 +#define TG_SUBCNT_D3_ST_MASK (0x7F << TG_SUBCNT_D3_ST_SHIFT) +#define TG_SUBCNT_D3_ST(n) BITFIELD_VAL(TG_SUBCNT_D3_ST, n) +#define REG_PWM3_BR_EN (1 << 0) + +// 109 PMU_REG_PWM_EN +#define REG_LED0_OUT (1 << 15) +#define REG_LED1_OUT (1 << 14) +#define PWM_SELECT_EN_SHIFT 12 +#define PWM_SELECT_EN_MASK (0x3 << PWM_SELECT_EN_SHIFT) +#define PWM_SELECT_EN(n) BITFIELD_VAL(PWM_SELECT_EN, n) +#define PWM_SELECT_INV_SHIFT 10 +#define PWM_SELECT_INV_MASK (0x3 << PWM_SELECT_INV_SHIFT) +#define PWM_SELECT_INV(n) BITFIELD_VAL(PWM_SELECT_INV, n) +#define REG_CLK_PWM_DIV_SHIFT 5 +#define REG_CLK_PWM_DIV_MASK (0x1F << REG_CLK_PWM_DIV_SHIFT) +#define REG_CLK_PWM_DIV(n) BITFIELD_VAL(REG_CLK_PWM_DIV, n) + +// 10B PMU_REG_WDT_TIMER +#define REG_WDT_TIMER_SHIFT 0 +#define REG_WDT_TIMER_MASK (0xFFFF << REG_WDT_TIMER_SHIFT) +#define REG_WDT_TIMER(n) BITFIELD_VAL(REG_WDT_TIMER, n) + +// 10C PMU_REG_WDT_CFG +#define REG_HW_RESET_TIME_SHIFT 10 +#define REG_HW_RESET_TIME_MASK (0x3F << REG_HW_RESET_TIME_SHIFT) +#define REG_HW_RESET_TIME(n) BITFIELD_VAL(REG_HW_RESET_TIME, n) +#define REG_HW_RESET_EN (1 << 9) +#define REG_WDT_RESET_EN (1 << 8) +#define REG_WDT_EN (1 << 7) +#define BG_R_TEMP_SHIFT 4 +#define BG_R_TEMP_MASK (0x7 << BG_R_TEMP_SHIFT) +#define BG_R_TEMP(n) BITFIELD_VAL(BG_R_TEMP, n) +#define BG_TRIM_VBG_SHIFT 1 +#define BG_TRIM_VBG_MASK (0x7 << BG_TRIM_VBG_SHIFT) +#define BG_TRIM_VBG(n) BITFIELD_VAL(BG_TRIM_VBG, n) +#define SAR_PU_OVP (1 << 0) + +// 80 PMU_REG_RF_80 +#define RF_80_PAGE_IDX (1 << 15) +#define RF_80_S_DONE_SHIFT 4 +#define RF_80_S_DONE_MASK (0x7FF << RF_80_S_DONE_SHIFT) +#define RF_80_S_DONE(n) BITFIELD_VAL(RF_80_S_DONE, n) +#define RF_80_REVID_SHIFT 0 +#define RF_80_REVID_MASK (0xF << RF_80_REVID_SHIFT) +#define RF_80_REVID(n) BITFIELD_VAL(RF_80_REVID, n) + +// BD PMU_REG_RF_BD +#define REG_BBPLL_FREQ_34_32_SHIFT 0 +#define REG_BBPLL_FREQ_34_32_MASK (0x7 << REG_BBPLL_FREQ_34_32_SHIFT) +#define REG_BBPLL_FREQ_34_32(n) BITFIELD_VAL(REG_BBPLL_FREQ_34_32, n) +#define REG_BBPLL_FREQ_EN (1 << 3) + +enum PMU_REG_T { + PMU_REG_METAL_ID = 0x00, + PMU_REG_POWER_KEY_CFG = 0x02, + PMU_REG_BIAS_CFG = 0x03, + PMU_REG_CHARGER_CFG = 0x05, + PMU_REG_ANA_CFG = 0x07, + PMU_REG_DIG_CFG = 0x08, + PMU_REG_IO_CFG = 0x09, + PMU_REG_MEM_CFG = 0x0A, + PMU_REG_GP_CFG = 0x0B, + PMU_REG_USB_CFG = 0x0C, + PMU_REG_BAT2DIG_CFG = 0x0D, + PMU_REG_HPPA_LDO_EN = 0x0E, + PMU_REG_HPPA2CODEC_CFG = 0x0F, + PMU_REG_CODEC_CFG = 0x10, + PMU_REG_DCDC_DIG_EN = 0x15, + PMU_REG_DCDC_ANA_CFG_16 = 0x16, + PMU_REG_DCDC_ANA_CFG_17 = 0x17, + PMU_REG_DCDC_ANA_CFG_18 = 0x18, + PMU_REG_DCDC_ANA_CFG_19 = 0x19, + PMU_REG_DCDC_HPPA_CFG_1A = 0x1A, + PMU_REG_DCDC_HPPA_CFG_1B = 0x1B, + PMU_REG_DCDC_HPPA_CFG_1C = 0x1C, + PMU_REG_DCDC_HPPA_CFG_1D = 0x1D, + PMU_REG_PWR_SEL = 0x21, + PMU_REG_INT_MASK = 0x26, + PMU_REG_INT_EN = 0x27, + PMU_REG_RTC_LOAD_LOW = 0x2D, + PMU_REG_RTC_LOAD_HIGH = 0x2E, + PMU_REG_RTC_MATCH1_LOW = 0x31, + PMU_REG_RTC_MATCH1_HIGH = 0x32, + PMU_REG_DCDC_DIG_CFG_33 = 0x33, + PMU_REG_DCDC_DIG_CFG_34 = 0x34, + PMU_REG_DCDC_DIG_CFG_35 = 0x35, + PMU_REG_DCDC_DIG_CFG_36 = 0x36, + PMU_REG_RTC_DIV_1HZ = 0x37, + PMU_REG_MIC_BIAS_E = 0x38, + PMU_REG_MIC_LDO_EN = 0x39, + PMU_REG_LED_CFG = 0x3A, + PMU_REG_MIC_BIAS_A = 0x3B, + PMU_REG_MIC_BIAS_B = 0x3C, + PMU_REG_MIC_BIAS_C = 0x3D, + PMU_REG_MIC_BIAS_D = 0x3E, + PMU_REG_EFUSE_CTRL = 0x3F, + PMU_REG_EFUSE_SEL = 0x40, + PMU_REG_DCDC1_OFFSET = 0x41, + PMU_REG_BUCK2ANA_CFG = 0x43, + PMU_REG_SLEEP_CFG = 0x44, + PMU_REG_DCDC_DIG_VOLT = 0x46, + PMU_REG_DCDC_ANA_VOLT = 0x47, + PMU_REG_DCDC_HPPA_VOLT = 0x48, + PMU_REG_DCDC4_VOLT = 0x49, + PMU_REG_DCDC_ANA_EN = 0x4A, + PMU_REG_DCDC_HPPA_EN = 0x4B, + PMU_REG_POWER_OFF = 0x4F, + PMU_REG_INT_CLR = 0x51, + PMU_REG_INT_STATUS = 0x52, + PMU_REG_INT_MSKED_STATUS = 0x53, + PMU_REG_RTC_VAL_LOW = 0x54, + PMU_REG_RTC_VAL_HIGH = 0x55, + PMU_REG_CHARGER_STATUS = 0x5E, + + PMU_REG_DCDC_RAMP_EN = 0x101, + + PMU_REG_PWM2_TOGGLE = 0x103, + PMU_REG_PWM3_TOGGLE = 0x104, + PMU_REG_PWM2_ST1 = 0x105, + PMU_REG_PWM3_ST1 = 0x106, + PMU_REG_SUBCNT_DATA = 0x107, + PMU_REG_PWM_BR_EN = 0x108, + PMU_REG_PWM_EN = 0x109, + + PMU_REG_WDT_TIMER = 0x10B, + PMU_REG_WDT_CFG = 0x10C, + + PMU_REG_MODULE_START = PMU_REG_ANA_CFG, + PMU_REG_EFUSE_VAL_START = 0x148, + + PMU_REG_ANA_60 = 0x60, + PMU_REG_ANA_77 = 0x77, + + PMU_REG_RF_80 = 0x80, + PMU_REG_RF_B5 = 0xB5, + PMU_REG_RF_BB = 0xBB, + PMU_REG_RF_BC = 0xBC, + PMU_REG_RF_BD = 0xBD, +}; + +enum PMU_VCORE_REQ_T { + PMU_VCORE_FLASH_WRITE_ENABLED = (1 << 0), + PMU_VCORE_FLASH_FREQ_HIGH = (1 << 1), + PMU_VCORE_PSRAM_FREQ_HIGH = (1 << 2), + PMU_VCORE_USB_HS_ENABLED = (1 << 3), + PMU_VCORE_RS_FREQ_HIGH = (1 << 4), + PMU_VCORE_SYS_FREQ_MEDIUM = (1 << 5), + PMU_VCORE_SYS_FREQ_HIGH = (1 << 6), +}; + +enum PMU_VUSB_REQ_T { + PMU_VUSB_REQ_INIT = (1 << 0), + PMU_VUSB_REQ_USB = (1 << 1), + PMU_VUSB_REQ_LBRT = (1 << 2), +}; + +union BOOT_SETTINGS_T { + struct { + unsigned short usb_dld_dis :1; + unsigned short uart_dld_en :1; + unsigned short uart_trace_en :1; + unsigned short pll_dis :1; + unsigned short uart_baud_div2 :1; + unsigned short sec_freq_div2 :1; + unsigned short crystal_freq :2; + unsigned short reserved :4; + unsigned short chksum :4; + }; + unsigned short reg; +}; + +enum PMU_MODUAL_T { + PMU_ANA, + PMU_DIG, + PMU_IO, + PMU_MEM, + PMU_GP, + PMU_USB, + PMU_BAT2DIG, + PMU_HPPA2CODEC, + PMU_CODEC, + PMU_BUCK2ANA, +}; + +struct PMU_MODULE_CFG_T { + unsigned short pu_dr; + unsigned short pu; + unsigned short lp_en_dr; + unsigned short lp_en; + unsigned short pu_dsleep; + unsigned short vbit_dsleep_mask; + unsigned short vbit_dsleep_shift; + unsigned short vbit_normal_mask; + unsigned short vbit_normal_shift; +}; + +#define PMU_MOD_CFG_VAL(m) { \ + REG_PU_LDO_V##m##_DR, REG_PU_LDO_V##m##_REG, \ + LP_EN_V##m##_LDO_DR, LP_EN_V##m##_LDO_REG, \ + REG_PU_LDO_V##m##_DSLEEP, \ + LDO_V##m##_VBIT_DSLEEP_MASK, LDO_V##m##_VBIT_DSLEEP_SHIFT, \ + LDO_V##m##_VBIT_NORMAL_MASK, LDO_V##m##_VBIT_NORMAL_SHIFT } + +static const struct PMU_MODULE_CFG_T pmu_module_cfg[] = { + PMU_MOD_CFG_VAL(ANA), + PMU_MOD_CFG_VAL(CORE), + PMU_MOD_CFG_VAL(IO), + PMU_MOD_CFG_VAL(MEM), + PMU_MOD_CFG_VAL(GP), + PMU_MOD_CFG_VAL(USB), + PMU_MOD_CFG_VAL(BAT2VCORE), + PMU_MOD_CFG_VAL(HPPA2VCODEC), + PMU_MOD_CFG_VAL(CODEC), + PMU_MOD_CFG_VAL(BUCK2ANA), +}; + +#ifdef ANC_PROD_TEST +#define OPT_TYPE +#else +#define OPT_TYPE const +#endif + +static OPT_TYPE bool vcodec_off = +#ifdef VCODEC_OFF + true; +#else + false; +#endif +static OPT_TYPE uint8_t ana_act_dcdc = +#ifdef VANA_1P2V + PMU_DCDC_ANA_1_2V; +#elif defined(VANA_1P35V) + PMU_DCDC_ANA_1_35V; +#elif defined(VANA_1P4V) + PMU_DCDC_ANA_1_4V; +#elif defined(VANA_1P5V) + PMU_DCDC_ANA_1_5V; +#elif defined(VANA_1P6V) + PMU_DCDC_ANA_1_6V; +#else + PMU_DCDC_ANA_1_3V; +#endif +static OPT_TYPE POSSIBLY_UNUSED uint16_t vcodec_mv = (uint16_t)(VCODEC_VOLT * 1000); +static OPT_TYPE POSSIBLY_UNUSED uint16_t vhppa_mv = (uint16_t)(VHPPA_VOLT * 1000); + +static enum HAL_CHIP_METAL_ID_T BOOT_BSS_LOC pmu_metal_id; + +static enum PMU_POWER_MODE_T BOOT_BSS_LOC pmu_power_mode = PMU_POWER_MODE_NONE; + +static enum PMU_VCORE_REQ_T BOOT_BSS_LOC pmu_vcore_req; + +// Move all the data/bss invovled in pmu_open() to .sram_data/.sram_bss, +// so that pmu_open() can be called at the end of BootInit(), +// for data/bss is initialized after BootInit(). +static enum PMU_VUSB_REQ_T SRAM_BSS_DEF(pmu_vusb_req); + +static uint16_t SRAM_BSS_DEF(dcdc_ramp_map); + +static PMU_CHARGER_IRQ_HANDLER_T charger_irq_handler; + +static PMU_IRQ_UNIFIED_HANDLER_T pmu_irq_hdlrs[PMU_IRQ_TYPE_QTY]; + +static uint8_t SRAM_BSS_DEF(vio_risereq_map); +STATIC_ASSERT(sizeof(vio_risereq_map) * 8 >= PMU_VIORISE_REQ_USER_QTY, "vio_risereq_map size too small"); + +static uint8_t SRAM_DATA_DEF(vio_act_normal) = IO_VOLT_ACTIVE_NORMAL; +static uint8_t SRAM_DATA_DEF(vio_act_rise) = IO_VOLT_ACTIVE_RISE; +static uint8_t SRAM_DATA_DEF(vio_lp) = IO_VOLT_SLEEP; + +static const uint8_t ana_lp_dcdc = PMU_DCDC_ANA_SLEEP_1_3V; + +// BT might have connection drop issues if dig_lp is lower than 0.8V +static const uint8_t dig_lp_ldo = PMU_VDIG_0_8V; +static const uint8_t dig_lp_dcdc = PMU_DCDC_DIG_0_8V; + +static uint8_t BOOT_DATA_DEF(audpll_codec_div) = 16; + +#ifdef HIGH_VCORE +static const bool high_vcore = true; +#else +static bool BOOT_BSS_DEF(high_vcore); +#endif + +static uint16_t wdt_timer; + +#if defined(MCU_HIGH_PERFORMANCE_MODE) +static const uint16_t high_perf_freq_mhz = +#if defined(MTEST_ENABLED) && defined(MTEST_CLK_MHZ) + MTEST_CLK_MHZ; +#else + 300; +#endif +static bool high_perf_on; +#endif + +void pmu_wdt_save_context(void); +void pmu_wdt_restore_context(void); +void pmu_charger_save_context(void); +void pmu_charger_shutdown_config(void); + +#if defined(PMU_INIT) || (!defined(FPGA) && !defined(PROGRAMMER)) +static void pmu_hppa_dcdc_to_ldo(void); +#endif + +#if defined(_AUTO_TEST_) +static bool at_skip_shutdown = false; + +void pmu_at_skip_shutdown(bool enable) +{ + at_skip_shutdown = enable; +} +#endif + +#ifdef RTC_ENABLE +struct PMU_RTC_CTX_T { + bool enabled; + bool alarm_set; + uint32_t alarm_val; +}; + +static struct PMU_RTC_CTX_T BOOT_BSS_LOC rtc_ctx; + +static PMU_RTC_IRQ_HANDLER_T rtc_irq_handler; + +static void BOOT_TEXT_SRAM_LOC pmu_rtc_save_context(void) +{ + if (pmu_rtc_enabled()) { + rtc_ctx.enabled = true; + if (pmu_rtc_alarm_status_set()) { + rtc_ctx.alarm_set = true; + rtc_ctx.alarm_val = pmu_rtc_get_alarm(); + } + } else { + rtc_ctx.enabled = false; + } +} + +static void pmu_rtc_restore_context(void) +{ + uint32_t rtc_val; + + if (rtc_ctx.enabled) { + pmu_rtc_enable(); + if (rtc_ctx.alarm_set) { + rtc_val = pmu_rtc_get(); + if (rtc_val - rtc_ctx.alarm_val <= 1 || rtc_ctx.alarm_val - rtc_val < 5) { + rtc_ctx.alarm_val = rtc_val + 5; + } + pmu_rtc_set_alarm(rtc_ctx.alarm_val); + } + } +} +#endif + +#ifdef PMU_DCDC_CALIB +union VOLT_COMP_T { + struct VOLT_COMP_FIELD_T { + uint16_t dcdc1_v: 5; //bit[4:0]: 0 ~ 31 + uint16_t dcdc1_f: 1; //bit[5] : 1: negative, 0: positive; + uint16_t dcdc2_v: 4; //bit[9:6]: 0 ~ 15 + uint16_t dcdc2_f: 1; //bit[10] : + uint16_t dcdc3_v: 4; //bit[14:11]: 0 ~ 15 + uint16_t dcdc3_f: 1; //bit[15] + } f; + uint16_t v; +}; + +static int8_t pmu_dcdc_dig_comp = 0; +static int8_t pmu_dcdc_ana_comp = 0; +static int8_t pmu_dcdc_hppa_comp = 0; + +static POSSIBLY_UNUSED void pmu_get_dcdc_calib_value(void) +{ + union VOLT_COMP_T cv; + + pmu_get_efuse(PMU_EFUSE_PAGE_RESERVED_7, &cv.v); + if (cv.f.dcdc1_f) { //digital + pmu_dcdc_dig_comp = -(int8_t)(cv.f.dcdc1_v); + } else { + pmu_dcdc_dig_comp = (int8_t)(cv.f.dcdc1_v); + } + if (cv.f.dcdc2_f) { //ana + pmu_dcdc_ana_comp = -(int8_t)(cv.f.dcdc2_v); + } else { + pmu_dcdc_ana_comp = (int8_t)(cv.f.dcdc2_v); + } + if (cv.f.dcdc3_f) { //hppa + pmu_dcdc_hppa_comp = -(int8_t)(cv.f.dcdc3_v); + } else { + pmu_dcdc_hppa_comp = (int8_t)(cv.f.dcdc3_v); + } +} + +static POSSIBLY_UNUSED unsigned short pmu_reg_val_add(unsigned short val, int delta, unsigned short max) +{ + int result = val + delta; + + if (result > max) { + result = max; + } else if (result < 0) { + result = 0; + } + + return (unsigned short)result; +} +#endif + +static unsigned int NOINLINE BOOT_TEXT_SRAM_LOC pmu_count_zeros(unsigned int val, unsigned int bits) +{ + int cnt = 0; + int i; + + for (i = 0; i < bits; i++) { + if ((val & (1 << i)) == 0) { + cnt++; + } + } + + return cnt; +} + +static int BOOT_TEXT_FLASH_LOC pmu_read_efuse_block(unsigned int block) +{ + int ret; + unsigned short val; + uint32_t start; + uint32_t timeout = MS_TO_TICKS(50); + + val = TSMC_EFUSE_PGENB | TSMC_EFUSE_CLK_EN; + ret = pmu_write(PMU_REG_EFUSE_CTRL, val); + if (ret) { + return ret; + } + + val = TSMC_EFUSE_STROBE_WIDTH(20) | REG_READ_STROBE_WIDTH(4) | EFUSE_SEL(block); + ret = pmu_write(PMU_REG_EFUSE_SEL, val); + if (ret) { + return ret; + } + + ret = pmu_read(PMU_REG_POWER_OFF, &val); + if (ret) { + return ret; + } + val = SET_BITFIELD(val, EFUSE_READ_TRIG, EFUSE_READ_TRIG_WORD); + ret = pmu_write(PMU_REG_POWER_OFF, val); + if (ret) { + return ret; + } + + hal_sys_timer_delay(US_TO_TICKS(500)); + + start = hal_sys_timer_get(); + do { + ret = pmu_read(PMU_REG_POWER_OFF, &val); + if (ret) { + return ret; + } + if (hal_sys_timer_get() - start > timeout) { + return -2; + } + } while ((val & (EFUSE_READ_DONE | EFUSE_READ_BUSY)) != EFUSE_READ_DONE); + + val = TSMC_EFUSE_PGENB; + ret = pmu_write(PMU_REG_EFUSE_CTRL, val); + if (ret) { + return ret; + } + + return 0; +} + +void BOOT_TEXT_FLASH_LOC bbpll_freq_pll_config(uint32_t freq) +{ + int ret; + uint64_t PLL_cfg_val; + uint16_t v[3]; + uint16_t val; + uint32_t crystal = hal_cmu_get_crystal_freq(); + + PLL_cfg_val = ((uint64_t)(1 << 28) * (freq / 2) + crystal / 2) / crystal; + v[0] = PLL_cfg_val & 0xFFFF; + v[1] = (PLL_cfg_val >> 16) & 0xFFFF; + v[2] = (PLL_cfg_val >> 32) & 0xFFFF; + + ret = pmu_write(PMU_REG_RF_BB, v[0]); + if (ret) { + return; + } + + ret = pmu_write(PMU_REG_RF_BC, v[1]); + if (ret) { + return; + } + + ret = pmu_read(PMU_REG_RF_BD, &val); + if (ret) { + return; + } + val = SET_BITFIELD(val, REG_BBPLL_FREQ_34_32, v[2]) | REG_BBPLL_FREQ_EN; + ret = pmu_write(PMU_REG_RF_BD, val); + if (ret) { + return; + } + + // Delay at least for 7us + hal_sys_timer_delay(US_TO_TICKS(100)); +} + +uint32_t BOOT_TEXT_FLASH_LOC read_hw_metal_id(void) +{ + int ret; + uint16_t val; + uint32_t metal_id; + int i; + union BOOT_SETTINGS_T boot; + +#ifdef RTC_ENABLE + // RTC will be restored in pmu_open() + pmu_rtc_save_context(); +#endif + + pmu_wdt_save_context(); + + pmu_charger_save_context(); + + // Reset PMU (to recover from a possible insane state, e.g., ESD reset) + pmu_write(PMU_REG_METAL_ID, 0xCAFE); + pmu_write(PMU_REG_METAL_ID, 0x5FEE); + hal_sys_timer_delay(US_TO_TICKS(500)); + +#if defined(PMU_FULL_INIT) || (!defined(FPGA) && !defined(PROGRAMMER)) + // Reset RF + pmu_write(PMU_REG_RF_80, 0xCAFE); + pmu_write(PMU_REG_RF_80, 0x5FEE); + hal_sys_timer_delay(US_TO_TICKS(500)); + + // Reset ANA + pmu_write(PMU_REG_ANA_60, 0xCAFE); + pmu_write(PMU_REG_ANA_60, 0x5FEE); + hal_sys_timer_delay(US_TO_TICKS(500)); +#endif + +#ifdef __WATCHER_DOG_RESET__ + pmu_wdt_restore_context(); +#endif + +#ifndef EFUSE_BLOCK_NUM +#define EFUSE_BLOCK_NUM 6 +#endif + + for (i = 0; i < EFUSE_BLOCK_NUM; i++) { + ret = pmu_read_efuse_block(i); + if (ret) { + SAFE_PROGRAM_STOP(); + } + } + + ret = pmu_get_efuse(PMU_EFUSE_PAGE_BOOT, &boot.reg); + if (ret) { + boot.reg = 0; + } else { + if (pmu_count_zeros(boot.reg, 12) != boot.chksum) { + boot.reg = 0; + } + } + hal_cmu_set_crystal_freq_index(boot.crystal_freq); + // Update ISPI cfg + ret = hal_analogif_open(); + if (ret) { + SAFE_PROGRAM_STOP(); + } + +#if !defined(FPGA) && !defined(PROGRAMMER) && !defined(MCU_HIGH_PERFORMANCE_MODE) + if (hal_cmu_get_crystal_freq() != hal_cmu_get_default_crystal_freq()) { + // Update bbpll freq after resetting RF and getting crystal freq + bbpll_freq_pll_config(384000000); + } +#endif + +#if 0 +#ifndef HIGH_VCORE + pmu_get_efuse(PMU_EFUSE_PAGE_SW_CFG, &val); + if ((val & (3 << 13)) == (3 << 13)) { + high_vcore = true; + } +#endif +#endif + + //enhance xtal drv + pmu_write(0x9d,0x886c); + // Enable 26M doubler (52M) + pmu_write(0xB5, 0x8000); +#ifdef ANA_26M_X4_ENABLE + pmu_write(0xBF, 0x0400); +#endif + + // Power up bbpll and audpll clk buf + // Clk buf bits: + // 0-rfpll 1-bt_dac 2-codec_resample&audpll_prechr 3-bbpll 4-audpll 5-usbhspll 6-lbrt 7-dig + pmu_read(0xC4, &val); + val &= ~0xFF; + val |= (1 << 2) | (1 << 3) | (1 << 4) | (1 << 7); +#if defined(USB_HIGH_SPEED) || defined(USB_USE_USBPLL) + val |= (1 << 5); +#endif + pmu_write(0xC4, val); + + // Cfg bbpll + pmu_write(0x9F, 0xC22F); + pmu_write(0xA0, 0x2788); + + // Cfg audpll + pmu_write(0x79, 0x0011); + pmu_write(0x77, 0x71B1); + + // Set audpll to 24.576M*17 + pmu_write(0x7C, 0x4F16); + pmu_write(0x7B, 0x011A); + pmu_write(0x7A, 0x2008); + + // Clear reg_bt_tst_buf_sel_in/out to avoid impacting P00-P03 and P30-P33 pins + pmu_write(0xA2, 0x01C2); + + // Enable SWD debug mode + pmu_read(PMU_REG_SLEEP_CFG, &val); + val = SET_BITFIELD(val, PMIC_TMODE_1300, 2); + pmu_write(PMU_REG_SLEEP_CFG, val); + + pmu_read(PMU_REG_METAL_ID, &val); + pmu_metal_id = GET_BITFIELD(val, PMU_METAL_ID); + + metal_id = hal_cmu_get_aon_revision_id(); + + if (metal_id == HAL_CHIP_METAL_ID_1) { + uint32_t data; + + hal_psc_bt_enable(); + hal_cmu_bt_clock_enable(); + hal_cmu_bt_reset_clear(); + data = *(volatile uint32_t *)0xA0000004; + hal_cmu_bt_reset_set(); + hal_cmu_bt_clock_disable(); + hal_psc_bt_disable(); + + if (data == 0xA0007471) { + metal_id = HAL_CHIP_METAL_ID_2; + } + } + + // Init pll dividers + pmu_read(PMU_REG_ANA_77, &val); + val = SET_BITFIELD(val, REG_AUDPLL_DIVN, audpll_codec_div); + pmu_write(PMU_REG_ANA_77, val); + + return metal_id; +} + +void BOOT_TEXT_SRAM_LOC pmu_pll_div_reset_set(enum HAL_CMU_PLL_T pll) +{ + uint32_t lock; + uint16_t val; + + lock = int_lock(); + if (pll == HAL_CMU_PLL_AUD) { + pmu_read(PMU_REG_ANA_77, &val); + val |= REG_AUDPLL_DIVN_MASK | REG_AUDPLL_DIVN_RST; + pmu_write(PMU_REG_ANA_77, val); + } else if (pll == HAL_CMU_PLL_USB) { + // In fact bbpll +#ifdef AUDIO_USE_BBPLL + // 0xD2, bit13 (reset) + // 0xF5, bit[4:0] (div) +#endif + } else if (pll == HAL_CMU_PLL_QTY) { + // In fact usbhspll + } + int_unlock(lock); +} + +void BOOT_TEXT_SRAM_LOC pmu_pll_div_reset_clear(enum HAL_CMU_PLL_T pll) +{ + uint32_t lock; + uint16_t val; + + lock = int_lock(); + if (pll == HAL_CMU_PLL_AUD) { + pmu_read(PMU_REG_ANA_77, &val); + val &= ~REG_AUDPLL_DIVN_RST; + pmu_write(PMU_REG_ANA_77, val); + val = SET_BITFIELD(val, REG_AUDPLL_DIVN, audpll_codec_div); + pmu_write(PMU_REG_ANA_77, val); + } else if (pll == HAL_CMU_PLL_USB) { + // In fact bbpll +#ifdef AUDIO_USE_BBPLL +#endif + } else if (pll == HAL_CMU_PLL_QTY) { + // In fact usbhspll + } + int_unlock(lock); +} + +void pmu_pll_div_set(enum HAL_CMU_PLL_T pll, enum PMU_PLL_DIV_TYPE_T type, uint32_t div) +{ + uint32_t lock; + uint16_t val; + + if (type != PMU_PLL_DIV_CODEC) { + return; + } + + lock = int_lock(); + if (pll == HAL_CMU_PLL_AUD) { + if (div != audpll_codec_div) { + audpll_codec_div = div; + pmu_read(PMU_REG_ANA_77, &val); + val |= REG_AUDPLL_DIVN_MASK; + pmu_write(PMU_REG_ANA_77, val); + if (div != (REG_AUDPLL_DIVN_MASK >> REG_AUDPLL_DIVN_SHIFT)) { + val = SET_BITFIELD(val, REG_AUDPLL_DIVN, audpll_codec_div); + pmu_write(PMU_REG_ANA_77, val); + } + } + } else if (pll == HAL_CMU_PLL_USB) { + // In fact bbpll +#ifdef AUDIO_USE_BBPLL +#endif + } else if (pll == HAL_CMU_PLL_QTY) { + // In fact usbhspll + } + int_unlock(lock); +} + +#if defined(USE_CYBERON) +static uint32_t BOOT_BSS_LOC cyb_hack_efuse_check = 0; +void cyb_efuse_check_enable(int enabled) +{ + cyb_hack_efuse_check = enabled; +} + +int cyb_efuse_check_status(void) +{ + return cyb_hack_efuse_check; +} + +#if 1 +int BOOT_TEXT_SRAM_LOC Cyb_pmu_get_efuse(enum PMU_EFUSE_PAGE_T page, unsigned short *efuse) +{ +// PMU_DEBUG_TRACE(2,"page %x, efuse %x", page, efuse); + if(page==0XE){ + *efuse=0x1B9C; + } + if(page==0xF){ + *efuse = 0x098B; + } + + return 0; +} +#endif + +#endif + +int BOOT_TEXT_SRAM_LOC pmu_get_efuse(enum PMU_EFUSE_PAGE_T page, unsigned short *efuse) +{ + int ret; + +//#if defined(USE_CYBERON) +#if 0 + if (cyb_efuse_check_status()) { + PMU_DEBUG_TRACE(2,"page %x, efuse %x", page, efuse); + if((int)page==0xE){ + *efuse=0x1B9C; + return 0; + } + if((int)page==0xF){ + *efuse = 0x098B; + return 0; + } + } +#endif + + ret = pmu_read(PMU_REG_EFUSE_VAL_START + page, efuse); + + return ret; +} + +int pmu_get_security_value(union SECURITY_VALUE_T *val) +{ + int ret; + + ret = pmu_get_efuse(PMU_EFUSE_PAGE_SECURITY, &val->reg); + if (ret) { + // Error + goto _no_security; + } + + if (!val->security_en) { + // OK + goto _no_security; + } + ret = 1; + if (pmu_count_zeros(val->key_id, 3) != val->key_chksum) { + // Error + goto _no_security; + } + if (pmu_count_zeros(val->vendor_id, 6) != val->vendor_chksum) { + // Error + goto _no_security; + } + if ((pmu_count_zeros(val->reg, 15) & 1) != val->chksum) { + // Error + goto _no_security; + } + + // OK + return 0; + +_no_security: + val->reg = 0; + + return ret; +} + +static void pmu_sys_ctrl(bool shutdown) +{ + uint16_t val; + uint32_t lock = int_lock(); + + PMU_INFO_TRACE_IMM(0, "Start pmu %s", shutdown ? "shutdown" : "reboot"); + +#if defined(PMU_INIT) || (!defined(FPGA) && !defined(PROGRAMMER)) +#if defined(MCU_HIGH_PERFORMANCE_MODE) + // Default vcore might not be high enough to support high performance mode + pmu_high_performance_mode_enable(false); + hal_cmu_sys_set_freq(HAL_CMU_FREQ_26M); +#endif + pmu_hppa_dcdc_to_ldo(); + pmu_mode_change(PMU_POWER_MODE_LDO); + hal_sys_timer_delay(MS_TO_TICKS(1)); +#endif + +#ifdef RTC_ENABLE + pmu_rtc_save_context(); +#endif + + // Reset PMU + pmu_write(PMU_REG_METAL_ID, 0xCAFE); + pmu_write(PMU_REG_METAL_ID, 0x5FEE); + hal_sys_timer_delay(4); + +#ifdef RTC_ENABLE + pmu_rtc_restore_context(); +#endif + + if (shutdown) { +#if defined(_AUTO_TEST_) + if (at_skip_shutdown) { + hal_cmu_sys_reboot(); + return; + } +#endif + +#if defined(PMU_INIT) || (!defined(FPGA) && !defined(PROGRAMMER)) + pmu_wdt_config(3*1000,3*1000); + pmu_wdt_start(); + pmu_charger_shutdown_config(); +#endif + + // Power off + pmu_read(PMU_REG_POWER_OFF,&val); + val |= SOFT_POWER_OFF; + for (int i = 0; i < 100; i++) { + pmu_write(PMU_REG_POWER_OFF,val); + hal_sys_timer_delay(MS_TO_TICKS(5)); + } + + hal_sys_timer_delay(MS_TO_TICKS(50)); + + //can't reach here + PMU_INFO_TRACE_IMM(0, "\nError: pmu shutdown failed!\n"); + hal_sys_timer_delay(MS_TO_TICKS(5)); + } else { +#if defined(PMU_FULL_INIT) || (!defined(FPGA) && !defined(PROGRAMMER)) + // CAUTION: + // 1) Never reset RF because system or flash might be using X2/X4, which are off by default + // 2) Never reset RF/ANA because system or flash might be using PLL, and the reset might cause clock glitch + // TODO: + // Restore BBPLL settings in RF +#endif + } + + hal_cmu_sys_reboot(); + + int_unlock(lock); +} + +void pmu_shutdown(void) +{ + pmu_sys_ctrl(true); +} + +void pmu_reboot(void) +{ + pmu_sys_ctrl(false); +} + +static inline uint16_t pmu_get_module_addr(enum PMU_MODUAL_T module) +{ + if (module == PMU_HPPA2CODEC || module == PMU_CODEC) { + return PMU_REG_MODULE_START + module + 1; + } else if (module == PMU_BUCK2ANA) { + return PMU_REG_BUCK2ANA_CFG; + } else { + return PMU_REG_MODULE_START + module; + } +} + +void pmu_module_config(enum PMU_MODUAL_T module,unsigned short is_manual,unsigned short ldo_on,unsigned short lp_mode,unsigned short dpmode) +{ + unsigned short val; + unsigned char module_address; + const struct PMU_MODULE_CFG_T *module_cfg_p = &pmu_module_cfg[module]; + + module_address = pmu_get_module_addr(module); + + if (module == PMU_ANA) { + pmu_read(PMU_REG_BIAS_CFG, &val); + if(is_manual) { + val |= module_cfg_p->pu_dr; + } else { + val &= ~module_cfg_p->pu_dr; + } + + if(ldo_on) { + val |= module_cfg_p->pu; + } else { + val &= ~module_cfg_p->pu; + } + pmu_write(PMU_REG_BIAS_CFG, val); + } else if (module == PMU_DIG) { + pmu_read(PMU_REG_DCDC_DIG_EN, &val); + if(is_manual) { + val |= module_cfg_p->pu_dr; + } else { + val &= ~module_cfg_p->pu_dr; + } + + if(ldo_on) { + val |= module_cfg_p->pu; + } else { + val &= ~module_cfg_p->pu; + } + pmu_write(PMU_REG_DCDC_DIG_EN, val); + } else if (module == PMU_HPPA2CODEC) { + pmu_read(PMU_REG_SLEEP_CFG, &val); + if(dpmode) { + val |= module_cfg_p->pu_dsleep; + } else { + val &= ~module_cfg_p->pu_dsleep; + } + pmu_write(PMU_REG_SLEEP_CFG, val); + } else if (module == PMU_CODEC) { + pmu_read(PMU_REG_HPPA2CODEC_CFG, &val); + if(dpmode) { + val |= module_cfg_p->pu_dsleep; + } else { + val &= ~module_cfg_p->pu_dsleep; + } + pmu_write(PMU_REG_HPPA2CODEC_CFG, val); + } + + pmu_read(module_address, &val); + + if (module != PMU_ANA && module != PMU_DIG) { + if(is_manual) { + val |= module_cfg_p->pu_dr; + } else { + val &= ~module_cfg_p->pu_dr; + } + + if(ldo_on) { + val |= module_cfg_p->pu; + } else { + val &= ~module_cfg_p->pu; + } + } + + if (lp_mode) { + val &= ~module_cfg_p->lp_en_dr; + } else { + val = (val & ~module_cfg_p->lp_en) | module_cfg_p->lp_en_dr; + } + + if (module != PMU_HPPA2CODEC && module != PMU_CODEC) { + if(dpmode) { + val |= module_cfg_p->pu_dsleep; + } else { + val &= ~module_cfg_p->pu_dsleep; + } + } + + pmu_write(module_address, val); +} + +void pmu_module_set_volt(unsigned char module, unsigned short sleep_v,unsigned short normal_v) +{ + unsigned short val; + unsigned char module_address; + const struct PMU_MODULE_CFG_T *module_cfg_p = &pmu_module_cfg[module]; + + module_address = pmu_get_module_addr(module); + + pmu_read(module_address, &val); + val &= ~module_cfg_p->vbit_normal_mask; + val |= (normal_v << module_cfg_p->vbit_normal_shift) & module_cfg_p->vbit_normal_mask; + val &= ~module_cfg_p->vbit_dsleep_mask; + val |= (sleep_v << module_cfg_p->vbit_dsleep_shift) & module_cfg_p->vbit_dsleep_mask; + pmu_write(module_address, val); +} + +int pmu_module_get_volt(unsigned char module, unsigned short *sleep_vp,unsigned short *normal_vp) +{ + unsigned short val; + unsigned char module_address; + const struct PMU_MODULE_CFG_T *module_cfg_p = &pmu_module_cfg[module]; + + module_address = pmu_get_module_addr(module); + + pmu_read(module_address, &val); + if (normal_vp) { + *normal_vp = (val & module_cfg_p->vbit_normal_mask) >> module_cfg_p->vbit_normal_shift; + } + if (sleep_vp) { + *sleep_vp = (val & module_cfg_p->vbit_dsleep_mask) >> module_cfg_p->vbit_dsleep_shift; + } + + return 0; +} + +static void pmu_module_ramp_volt(unsigned char module, unsigned short sleep_v, unsigned short normal_v) +{ + uint16_t old_normal_v; + uint16_t old_sleep_v; + + pmu_module_get_volt(module, &old_sleep_v, &old_normal_v); + + if (old_normal_v < normal_v) { + while (old_normal_v++ < normal_v) { + pmu_module_set_volt(module, sleep_v, old_normal_v); + } + } else if (old_normal_v != normal_v || old_sleep_v != sleep_v) { + pmu_module_set_volt(module, sleep_v, normal_v); + } +} + +static void pmu_dcdc_ana_get_volt(unsigned short *normal_vp, unsigned short *dsleep_vp) +{ + unsigned short val; + + pmu_read(PMU_REG_DCDC_ANA_VOLT, &val); + if (normal_vp) { + *normal_vp = GET_BITFIELD(val, REG_DCDC2_VBIT_NORMAL); + } + if (dsleep_vp) { + *dsleep_vp = GET_BITFIELD(val, REG_DCDC2_VBIT_DSLEEP); + } + +#ifdef PMU_DCDC_CALIB + if (normal_vp) { + *normal_vp = pmu_reg_val_add(*normal_vp, -pmu_dcdc_ana_comp, MAX_DCDC2_VBIT_VAL); + } + if (dsleep_vp) { + *dsleep_vp = pmu_reg_val_add(*dsleep_vp, -pmu_dcdc_ana_comp, MAX_DCDC2_VBIT_VAL); + } +#endif +} + +static void pmu_dcdc_ana_set_volt(unsigned short normal_v,unsigned short dsleep_v) +{ + unsigned short val; + +#ifdef PMU_DCDC_CALIB + normal_v = pmu_reg_val_add(normal_v, pmu_dcdc_ana_comp, MAX_DCDC2_VBIT_VAL); + dsleep_v = pmu_reg_val_add(dsleep_v, pmu_dcdc_ana_comp, MAX_DCDC2_VBIT_VAL); +#endif + + pmu_read(PMU_REG_DCDC_ANA_VOLT, &val); + val &= ~REG_DCDC2_VBIT_DSLEEP_MASK; + val &= ~REG_DCDC2_VBIT_NORMAL_MASK; + val |= REG_DCDC2_VBIT_DSLEEP(dsleep_v); + val |= REG_DCDC2_VBIT_NORMAL(normal_v); + pmu_write(PMU_REG_DCDC_ANA_VOLT, val); + + if (normal_v > dsleep_v) { + dcdc_ramp_map |= REG_DCDC2_RAMP_EN; + } else { + dcdc_ramp_map &= ~REG_DCDC2_RAMP_EN; + } +} + +static void pmu_ana_set_volt(int mode_change, enum PMU_POWER_MODE_T mode) +{ + uint16_t old_act_dcdc; + uint16_t old_lp_dcdc; + uint16_t new_act_dcdc; + + if (mode == PMU_POWER_MODE_ANA_DCDC || mode == PMU_POWER_MODE_DIG_DCDC) { + pmu_dcdc_ana_get_volt(&old_act_dcdc, &old_lp_dcdc); + new_act_dcdc = ana_act_dcdc; + if (old_act_dcdc < new_act_dcdc) { + while (old_act_dcdc++ < new_act_dcdc) { + pmu_dcdc_ana_set_volt(old_act_dcdc, ana_lp_dcdc); + } + hal_sys_timer_delay_us(PMU_VANA_STABLE_TIME_US); + } else if (old_act_dcdc != new_act_dcdc || old_lp_dcdc != ana_lp_dcdc) { + pmu_dcdc_ana_set_volt(new_act_dcdc, ana_lp_dcdc); + } + } +} + +static void pmu_dcdc_dig_get_volt(unsigned short *normal_vp, unsigned short *dsleep_vp) +{ + unsigned short val; + + pmu_read(PMU_REG_DCDC_DIG_VOLT, &val); + if (normal_vp) { + *normal_vp = GET_BITFIELD(val, REG_DCDC1_VBIT_NORMAL); + } + if (dsleep_vp) { + *dsleep_vp = GET_BITFIELD(val, REG_DCDC1_VBIT_DSLEEP); + } + +#ifdef PMU_DCDC_CALIB + if (normal_vp) { + *normal_vp = pmu_reg_val_add(*normal_vp, -pmu_dcdc_dig_comp, MAX_DCDC1_VBIT_VAL); + } + if (dsleep_vp) { + *dsleep_vp = pmu_reg_val_add(*dsleep_vp, -pmu_dcdc_dig_comp, MAX_DCDC1_VBIT_VAL); + } +#endif +} + +static void pmu_dcdc_dig_set_volt(unsigned short normal_v,unsigned short dsleep_v) +{ + unsigned short val; + +#ifdef PMU_DCDC_CALIB + normal_v = pmu_reg_val_add(normal_v, pmu_dcdc_dig_comp, MAX_DCDC1_VBIT_VAL); + dsleep_v = pmu_reg_val_add(dsleep_v, pmu_dcdc_dig_comp, MAX_DCDC1_VBIT_VAL); +#endif + + pmu_read(PMU_REG_DCDC_DIG_VOLT, &val); + val &= ~REG_DCDC1_VBIT_DSLEEP_MASK; + val &= ~REG_DCDC1_VBIT_NORMAL_MASK; + val |= REG_DCDC1_VBIT_DSLEEP(dsleep_v); + val |= REG_DCDC1_VBIT_NORMAL(normal_v); + pmu_write(PMU_REG_DCDC_DIG_VOLT, val); + + if (normal_v > dsleep_v) { + dcdc_ramp_map |= REG_DCDC1_RAMP_EN; + } else { + dcdc_ramp_map &= ~REG_DCDC1_RAMP_EN; + } +} + +static void BOOT_TEXT_SRAM_LOC pmu_dig_get_target_volt(uint16_t *ldo, uint16_t *dcdc) +{ + uint16_t ldo_volt; + uint16_t dcdc_volt; + + if (0) { +#if defined(MCU_HIGH_PERFORMANCE_MODE) + } else if (pmu_vcore_req & (PMU_VCORE_SYS_FREQ_HIGH)) { + if (high_perf_freq_mhz <= 260) { + ldo_volt = PMU_VDIG_1_05V; + dcdc_volt = PMU_DCDC_DIG_1_05V; + } else if (high_perf_freq_mhz <= 300) { + ldo_volt = PMU_VDIG_1_1V; + dcdc_volt = PMU_DCDC_DIG_1_1V; + } else { + ldo_volt = PMU_VDIG_1_2V; + dcdc_volt = PMU_DCDC_DIG_1_1V; + } +#endif + } else if (pmu_vcore_req & (PMU_VCORE_USB_HS_ENABLED | PMU_VCORE_RS_FREQ_HIGH | PMU_VCORE_SYS_FREQ_MEDIUM)) { + ldo_volt = PMU_VDIG_0_9V; + dcdc_volt = PMU_DCDC_DIG_0_9V; + } else if (pmu_vcore_req & (PMU_VCORE_FLASH_FREQ_HIGH | PMU_VCORE_PSRAM_FREQ_HIGH | + PMU_VCORE_FLASH_WRITE_ENABLED)) { + ldo_volt = PMU_VDIG_0_8V; + dcdc_volt = PMU_DCDC_DIG_0_8V; + } else { + // Common cases + if (high_vcore) { + ldo_volt = PMU_VDIG_0_8V; + dcdc_volt = PMU_DCDC_DIG_0_8V; + } else { + ldo_volt = PMU_VDIG_0_75V; + dcdc_volt = PMU_DCDC_DIG_0_75V; + } +#ifdef __SAVE_POWER_MODE__ + ldo_volt = PMU_VDIG_0_75V; + dcdc_volt = PMU_DCDC_DIG_0_75V; +#endif + } + +#if defined(PROGRAMMER) || defined(__BES_OTA_MODE__) && !defined(PMU_FULL_INIT) + // Try to keep the same vcore voltage as ROM (hardware default) + if (ldo_volt < PMU_VDIG_0_9V) { + ldo_volt = PMU_VDIG_0_9V; + } + if (dcdc_volt < PMU_DCDC_DIG_0_9V) { + dcdc_volt = PMU_DCDC_DIG_0_9V; + } +#endif + +#if defined(MTEST_ENABLED) && defined(MTEST_VOLT) +#ifdef DIG_DCDC_MODE + dcdc_volt = MTEST_VOLT; +#else + ldo_volt = MTEST_VOLT; +#endif +#endif + + if (ldo) { + *ldo = ldo_volt; + } + if (dcdc) { + *dcdc = dcdc_volt; + } +} + +static void pmu_dig_set_volt(int mode_change, enum PMU_POWER_MODE_T mode) +{ + uint32_t lock; + uint16_t dcdc_volt, old_act_dcdc, old_lp_dcdc; + uint16_t ldo_volt, old_act_ldo, old_lp_ldo; + uint16_t ldo_real, dcdc_real; + bool volt_inc = false; + + lock = int_lock(); + + if (mode == PMU_POWER_MODE_NONE) { + mode = pmu_power_mode; + } + + pmu_dig_get_target_volt(&ldo_volt, &dcdc_volt); + + pmu_module_get_volt(PMU_DIG, &old_lp_ldo, &old_act_ldo); + pmu_dcdc_dig_get_volt(&old_act_dcdc, &old_lp_dcdc); + + if (mode_change) { + // Both DCDC and LDO might have been enabled + ldo_real = (old_act_ldo - PMU_VDIG_0_4V) / 0x2; + dcdc_real = (old_act_dcdc - PMU_DCDC_DIG_0_4V) / 0x10; + if (dcdc_real < ldo_real) { + dcdc_real = ldo_real; + } + ldo_real = PMU_VDIG_0_4V + dcdc_real * 0x2; + dcdc_real = PMU_DCDC_DIG_0_4V + dcdc_real * 0x10; + + // Set the voltage to current real voltage + if (old_act_ldo < ldo_real) { + old_act_ldo = ldo_real; + old_lp_ldo = dig_lp_ldo; + pmu_module_set_volt(PMU_DIG, old_lp_ldo, old_act_ldo); + } + if (old_act_dcdc < dcdc_real) { + old_act_dcdc = dcdc_real; + old_lp_dcdc = dig_lp_dcdc; + pmu_dcdc_dig_set_volt(old_act_dcdc, old_lp_dcdc); + } + } + + if (mode_change || mode == PMU_POWER_MODE_DIG_DCDC) { + if (old_act_dcdc < dcdc_volt) { + volt_inc = true; + while (old_act_dcdc++ < dcdc_volt) { + pmu_dcdc_dig_set_volt(old_act_dcdc, dig_lp_dcdc); + } + } else if (old_act_dcdc != dcdc_volt || old_lp_dcdc != dig_lp_dcdc) { + pmu_dcdc_dig_set_volt(dcdc_volt, dig_lp_dcdc); + } + } + + if (mode_change || mode != PMU_POWER_MODE_DIG_DCDC) { + if (old_act_ldo < ldo_volt) { + volt_inc = true; + } + pmu_module_ramp_volt(PMU_DIG, dig_lp_ldo, ldo_volt); + } + + if (mode_change == 0) { + // Update the voltage of the other mode + if (mode == PMU_POWER_MODE_DIG_DCDC) { + pmu_module_set_volt(PMU_DIG, dig_lp_ldo, ldo_volt); + } else { + pmu_dcdc_dig_set_volt(dcdc_volt, dig_lp_dcdc); + } + } + + if (volt_inc) { + hal_sys_timer_delay_us(PMU_VCORE_STABLE_TIME_US); + } + + int_unlock(lock); +} + +static void pmu_ldo_mode_en(void) +{ + unsigned short val; + + // Enable vana ldo + pmu_module_config(PMU_ANA,PMU_AUTO_MODE,PMU_LDO_ON,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_ON); + // Enable vcore ldo + pmu_module_config(PMU_DIG,PMU_AUTO_MODE,PMU_LDO_ON,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_ON); + + pmu_ana_set_volt(1, PMU_POWER_MODE_LDO); + pmu_dig_set_volt(1, PMU_POWER_MODE_LDO); + + hal_sys_timer_delay_us(PMU_LDO_PU_STABLE_TIME_US); + + // Disable vcore dcdc + pmu_read(PMU_REG_DCDC_DIG_EN, &val); + val = (val & ~REG_PU_DCDC1) | REG_PU_DCDC1_DR; + pmu_write(PMU_REG_DCDC_DIG_EN, val); + // Disable vana dcdc + pmu_read(PMU_REG_DCDC_ANA_EN, &val); + val = (val & ~REG_PU_DCDC2) | REG_PU_DCDC2_DR; + pmu_write(PMU_REG_DCDC_ANA_EN, val); +} + +static void pmu_dcdc_ana_mode_en(void) +{ + unsigned short val; + + if (pmu_power_mode == PMU_POWER_MODE_DIG_DCDC) { + // Enable vcore ldo + pmu_module_config(PMU_DIG,PMU_AUTO_MODE,PMU_LDO_ON,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_ON); + + pmu_ana_set_volt(1, PMU_POWER_MODE_ANA_DCDC); + pmu_dig_set_volt(1, PMU_POWER_MODE_ANA_DCDC); + + hal_sys_timer_delay_us(PMU_LDO_PU_STABLE_TIME_US); + + // Disable vcore dcdc + pmu_read(PMU_REG_DCDC_DIG_EN, &val); + val = (val & ~REG_PU_DCDC1) | REG_PU_DCDC1_DR; + pmu_write(PMU_REG_DCDC_DIG_EN, val); + } else { + pmu_read(PMU_REG_DCDC_ANA_CFG_19, &val); + val |= DCDC2_REG_BYPASS; + pmu_write(PMU_REG_DCDC_ANA_CFG_19, val); + + // Enable vana dcdc + pmu_read(PMU_REG_DCDC_ANA_EN, &val); +#ifdef DCDC_ULP_LP_ON + val = (val & ~REG_DCDC2_ULP_MODE_NORMAL) | REG_DCDC2_ULP_MODE_DSLEEP | REG_PU_DCDC2_DR | REG_PU_DCDC2; +#else + val = (val & ~REG_DCDC2_ULP_MODE_NORMAL) | REG_PU_DCDC2_DR | REG_PU_DCDC2; +#endif + pmu_write(PMU_REG_DCDC_ANA_EN, val); + + pmu_ana_set_volt(1, PMU_POWER_MODE_ANA_DCDC); + pmu_dig_set_volt(1, PMU_POWER_MODE_ANA_DCDC); + + hal_sys_timer_delay_us(PMU_DCDC_PU_STABLE_TIME_US); + + // Disable vana ldo + pmu_module_config(PMU_ANA,PMU_MANUAL_MODE,PMU_LDO_OFF,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); + + pmu_read(PMU_REG_DCDC_ANA_CFG_19, &val); + val &= ~DCDC2_REG_BYPASS; + pmu_write(PMU_REG_DCDC_ANA_CFG_19, val); + } +} + +static void pmu_dcdc_dual_mode_en(void) +{ + unsigned short val; + + pmu_read(PMU_REG_DCDC_ANA_CFG_19, &val); + val |= DCDC2_REG_BYPASS; + pmu_write(PMU_REG_DCDC_ANA_CFG_19, val); + pmu_read(PMU_REG_DCDC_DIG_CFG_36, &val); + val |= DCDC1_REG_BYPASS; + pmu_write(PMU_REG_DCDC_DIG_CFG_36, val); + + // Enable vana dcdc + pmu_read(PMU_REG_DCDC_ANA_EN, &val); +#ifdef DCDC_ULP_LP_ON + val = (val & ~REG_DCDC2_ULP_MODE_NORMAL) | REG_DCDC2_ULP_MODE_DSLEEP | REG_PU_DCDC2_DR | REG_PU_DCDC2; +#else + val = (val & ~(REG_DCDC2_ULP_MODE_NORMAL | REG_DCDC2_ULP_MODE_DSLEEP)) | REG_PU_DCDC2_DR | REG_PU_DCDC2; +#endif + pmu_write(PMU_REG_DCDC_ANA_EN, val); + // Enable vcore dcdc + pmu_read(PMU_REG_DCDC_DIG_EN, &val); +#ifdef DCDC_ULP_LP_ON + val = (val & ~REG_DCDC1_ULP_MODE_NORMAL) | REG_DCDC1_ULP_MODE_DSLEEP | REG_PU_DCDC1_DR | REG_PU_DCDC1; +#else + val = (val & ~(REG_DCDC1_ULP_MODE_NORMAL | REG_DCDC1_ULP_MODE_DSLEEP)) | REG_PU_DCDC1_DR | REG_PU_DCDC1; +#endif + pmu_write(PMU_REG_DCDC_DIG_EN, val); + + pmu_ana_set_volt(1, PMU_POWER_MODE_DIG_DCDC); + pmu_dig_set_volt(1, PMU_POWER_MODE_DIG_DCDC); + + hal_sys_timer_delay_us(PMU_DCDC_PU_STABLE_TIME_US); + + // Disable vana ldo + pmu_module_config(PMU_ANA,PMU_MANUAL_MODE,PMU_LDO_OFF,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); + // Disable vcore ldo + pmu_module_config(PMU_DIG,PMU_MANUAL_MODE,PMU_LDO_OFF,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); + + pmu_read(PMU_REG_DCDC_ANA_CFG_19, &val); + val &= ~DCDC2_REG_BYPASS; + pmu_write(PMU_REG_DCDC_ANA_CFG_19, val); + pmu_read(PMU_REG_DCDC_DIG_CFG_36, &val); + val &= ~DCDC1_REG_BYPASS; + pmu_write(PMU_REG_DCDC_DIG_CFG_36, val); +} + +void pmu_mode_change(enum PMU_POWER_MODE_T mode) +{ + uint32_t lock; + + if (pmu_power_mode == mode || mode == PMU_POWER_MODE_NONE) { + return; + } + + lock = int_lock(); + + if (mode == PMU_POWER_MODE_ANA_DCDC) { + pmu_dcdc_ana_mode_en(); + } else if (mode == PMU_POWER_MODE_DIG_DCDC) { + pmu_dcdc_dual_mode_en(); + } else if (mode == PMU_POWER_MODE_LDO) { + pmu_ldo_mode_en(); + } + + pmu_power_mode = mode; + + int_unlock(lock); +} + +void pmu_sleep_en(unsigned char sleep_en) +{ + unsigned short val; + + pmu_read(PMU_REG_SLEEP_CFG, &val); + if (sleep_en) { + val |= SLEEP_ALLOW; + } else { + val &= ~SLEEP_ALLOW; + } + pmu_write(PMU_REG_SLEEP_CFG, val); +} + +#if defined(PMU_INIT) || (!defined(FPGA) && !defined(PROGRAMMER)) +static uint32_t pmu_vcodec_mv_to_val(uint16_t mv) +{ + uint32_t val; + +#ifdef VHPPA2VCODEC + if (mv == 1900) { + val = PMU_HPPA2CODEC_1_9V; + } else if (mv >= 1950) { + val = PMU_HPPA2CODEC_1_95V; + } else { + val = PMU_HPPA2CODEC_1_7V; + } +#else + if (mv == 1900) { + val = PMU_CODEC_1_9V; + } else if (mv >= 1950) { + val = PMU_CODEC_1_9V; + } else { + val = PMU_CODEC_1_7V; + } +#endif + + return val; +} + +static uint32_t pmu_ldo_hppa_mv_to_val(uint16_t mv) +{ + uint32_t val; + + if (mv == 1600) { + val = PMU_VHPPA_1_6V; + } else if (mv == 1700) { + val = PMU_VHPPA_1_7V; + } else if (mv >= 1900) { + val = PMU_VHPPA_1_9V; + } else { + val = PMU_VHPPA_1_8V; + } + + return val; +} + +static void POSSIBLY_UNUSED pmu_ldo_hppa_get_volt(unsigned short *normal_vp, unsigned short *dsleep_vp) +{ + uint16_t val; + + pmu_read(PMU_REG_HPPA_LDO_EN, &val); + val = GET_BITFIELD(val, REG_RES_SEL_VHPPA); + if (normal_vp) { + *normal_vp = val; + } + if (dsleep_vp) { + *dsleep_vp = val; + } +} + +static void pmu_ldo_hppa_set_volt(unsigned short normal_v,unsigned short dsleep_v) +{ + uint16_t val; + + pmu_read(PMU_REG_HPPA_LDO_EN, &val); + val = SET_BITFIELD(val, REG_RES_SEL_VHPPA, normal_v); + pmu_write(PMU_REG_HPPA_LDO_EN, val); +} + +static void pmu_ldo_hppa_en(int enable) +{ + uint16_t val; + + pmu_read(PMU_REG_HPPA_LDO_EN, &val); + if (enable) { + val |= (REG_PU_LDO_VHPPA_DSLEEP | REG_PU_LDO_VHPPA_EN); + } else { + val &= ~(REG_PU_LDO_VHPPA_DSLEEP | REG_PU_LDO_VHPPA_EN); + } + pmu_write(PMU_REG_HPPA_LDO_EN, val); +} + +#ifndef HPPA_LDO_ON +static uint32_t pmu_dcdc_hppa_mv_to_val(uint16_t mv) +{ + uint32_t val; + + if (mv == 1600) { + val = PMU_DCDC_HPPA_1_6V; + } else if (mv == 1700) { + val = PMU_DCDC_HPPA_1_7V; + } else if (mv == 1900) { + val = PMU_DCDC_HPPA_1_9V; + } else if (mv >= 1950) { + val = PMU_DCDC_HPPA_1_95V; + } else { + val = PMU_DCDC_HPPA_1_8V; + } + + return val; +} + +static void pmu_dcdc_hppa_get_volt(unsigned short *normal_vp, unsigned short *dsleep_vp) +{ + unsigned short val; + + pmu_read(PMU_REG_DCDC_HPPA_VOLT, &val); + if (normal_vp) { + *normal_vp = GET_BITFIELD(val, REG_DCDC3_VBIT_NORMAL); + } + if (dsleep_vp) { + *dsleep_vp = GET_BITFIELD(val, REG_DCDC3_VBIT_DSLEEP); + } + +#ifdef PMU_DCDC_CALIB + if (normal_vp) { + *normal_vp = pmu_reg_val_add(*normal_vp, -pmu_dcdc_hppa_comp, MAX_DCDC3_VBIT_VAL); + } + if (dsleep_vp) { + *dsleep_vp = pmu_reg_val_add(*dsleep_vp, -pmu_dcdc_hppa_comp, MAX_DCDC3_VBIT_VAL); + } +#endif +} + +static void pmu_dcdc_hppa_set_volt(unsigned short normal_v,unsigned short dsleep_v) +{ + unsigned short val; + +#ifdef PMU_DCDC_CALIB + normal_v = pmu_reg_val_add(normal_v, pmu_dcdc_hppa_comp, MAX_DCDC3_VBIT_VAL); + dsleep_v = pmu_reg_val_add(dsleep_v, pmu_dcdc_hppa_comp, MAX_DCDC3_VBIT_VAL); +#endif + + pmu_read(PMU_REG_DCDC_HPPA_VOLT, &val); + val &= ~REG_DCDC3_VBIT_DSLEEP_MASK; + val &= ~REG_DCDC3_VBIT_NORMAL_MASK; + val |= REG_DCDC3_VBIT_DSLEEP(dsleep_v); + val |= REG_DCDC3_VBIT_NORMAL(normal_v); + pmu_write(PMU_REG_DCDC_HPPA_VOLT, val); + + if (normal_v > dsleep_v) { + dcdc_ramp_map |= REG_DCDC3_RAMP_EN; + } else { + dcdc_ramp_map &= ~REG_DCDC3_RAMP_EN; + } +} + +static void pmu_dcdc_hppa_en(int enable) +{ + uint16_t val; + + if (enable) { + pmu_read(PMU_REG_DCDC_HPPA_CFG_1D, &val); + val |= DCDC3_REG_BYPASS; + pmu_write(PMU_REG_DCDC_HPPA_CFG_1D, val); + } + + pmu_read(PMU_REG_DCDC_HPPA_EN, &val); + if (enable) { +#ifdef DCDC_ULP_LP_ON + val = (val & ~REG_DCDC3_ULP_MODE_NORMAL) | REG_DCDC3_ULP_MODE_DSLEEP | REG_PU_DCDC3_DR | REG_PU_DCDC3; +#else + val = (val & ~REG_DCDC3_ULP_MODE_NORMAL) | REG_PU_DCDC3_DR | REG_PU_DCDC3; +#endif + } else { + val = (val & ~(REG_DCDC3_ULP_MODE_NORMAL | REG_PU_DCDC3)) | REG_PU_DCDC3_DR; + } + pmu_write(PMU_REG_DCDC_HPPA_EN, val); + + if (enable) { + hal_sys_timer_delay_us(PMU_DCDC_PU_STABLE_TIME_US); + pmu_read(PMU_REG_DCDC_HPPA_CFG_1D, &val); + val &= ~DCDC3_REG_BYPASS; + pmu_write(PMU_REG_DCDC_HPPA_CFG_1D, val); + } +} +#endif + +static uint32_t pmu_vhppa_mv_to_val(uint16_t mv) +{ +#ifdef HPPA_LDO_ON + return pmu_ldo_hppa_mv_to_val(mv); +#else + return pmu_dcdc_hppa_mv_to_val(mv); +#endif +} + +static void POSSIBLY_UNUSED pmu_hppa_get_volt(unsigned short *normal_vp, unsigned short *dsleep_vp) +{ +#ifdef HPPA_LDO_ON + pmu_ldo_hppa_get_volt(normal_vp, dsleep_vp); +#else + pmu_dcdc_hppa_get_volt(normal_vp, dsleep_vp); +#endif +} + +static void pmu_hppa_set_volt(unsigned short normal_v,unsigned short dsleep_v) +{ +#ifdef HPPA_LDO_ON + pmu_ldo_hppa_set_volt(normal_v, dsleep_v); +#else + pmu_dcdc_hppa_set_volt(normal_v, dsleep_v); +#endif +} + +static void pmu_hppa_en(int enable) +{ +#ifdef HPPA_LDO_ON + pmu_ldo_hppa_en(enable); +#else + pmu_dcdc_hppa_en(enable); +#endif +} + +static void pmu_hppa_dcdc_to_ldo(void) +{ +#ifndef HPPA_LDO_ON + uint16_t val; + uint16_t act_volt; + + pmu_ldo_hppa_en(true); + + val = pmu_dcdc_hppa_mv_to_val(vhppa_mv); + pmu_dcdc_hppa_get_volt(&act_volt, NULL); + if (val < act_volt) { + val = pmu_ldo_hppa_mv_to_val(HPPA_RAMP_UP_VOLT_MV); + } else { + val = pmu_ldo_hppa_mv_to_val(vhppa_mv); + } + pmu_ldo_hppa_set_volt(val, val); + + hal_sys_timer_delay_us(PMU_LDO_PU_STABLE_TIME_US); +#endif +} + +static void BOOT_TEXT_FLASH_LOC pmu_dig_init_volt(void) +{ + uint16_t ldo_volt; + uint16_t val; + + pmu_dig_get_target_volt(&ldo_volt, NULL); + + pmu_read(PMU_REG_DIG_CFG, &val); + if (GET_BITFIELD(val, LDO_DIG_VBIT_NORMAL) < ldo_volt) { + val = SET_BITFIELD(val, LDO_DIG_VBIT_NORMAL, ldo_volt); + pmu_write(PMU_REG_DIG_CFG, val); + } +} + +int pmu_codec_volt_ramp_up(void) +{ +#ifndef VMEM_ON + unsigned short normal, dsleep; + unsigned short target; + const unsigned short step = +#ifdef HPPA_LDO_ON + 1; +#else + 8; +#endif + + if (vcodec_off) { + target = pmu_vhppa_mv_to_val(HPPA_RAMP_UP_VOLT_MV); + + pmu_hppa_get_volt(&normal, &dsleep); + + if (normal < target) { + if (normal + step < target) { + normal += step; + } else { + normal = target; + } + + pmu_hppa_set_volt(normal, dsleep); + + return 1; + } + } + + return 0; +#endif +} + +int pmu_codec_volt_ramp_down(void) +{ +#ifndef VMEM_ON + unsigned short normal, dsleep; + unsigned short target; + const unsigned short step = +#ifdef HPPA_LDO_ON + 1; +#else + 8; +#endif + + if (vcodec_off) { + target = pmu_vhppa_mv_to_val(vhppa_mv); + + pmu_hppa_get_volt(&normal, &dsleep); + + if (normal > target) { + if (normal - step > target) { + normal -= step; + } else { + normal = target; + } + + pmu_hppa_set_volt(normal, dsleep); + + return 1; + } + } + + return 0; +#endif +} +#endif + +int BOOT_TEXT_FLASH_LOC pmu_open(void) +{ +#if defined(PMU_INIT) || (!defined(FPGA) && !defined(PROGRAMMER)) + + uint16_t val; + enum PMU_POWER_MODE_T mode; + enum PMU_MODUAL_T codec; + + ASSERT(!vcodec_off || vcodec_mv == vhppa_mv, + "Invalid vcodec/vhppa cfg: vcodec_off=%d vcodec_mv=%u vhppa_mv=%u", vcodec_off, vcodec_mv, vhppa_mv); + ASSERT(vcodec_mv == 1600 || vcodec_mv == 1700 || vcodec_mv == 1800 || vcodec_mv == 1900 || vcodec_mv == 1950, + "Invalid vcodec cfg: vcodec_mv=%u", vcodec_mv); + ASSERT(vhppa_mv == 1600 || vhppa_mv == 1700 || vhppa_mv == 1800 || vhppa_mv == 1900 || vhppa_mv == 1950, + "Invalid vhppa cfg: vhppa_mv=%u", vhppa_mv); + + // Disable and clear all PMU irqs by default + pmu_write(PMU_REG_INT_MASK, 0); + pmu_write(PMU_REG_INT_EN, 0); + // PMU irqs cannot be cleared by PMU soft reset + pmu_read(PMU_REG_CHARGER_STATUS, &val); + pmu_write(PMU_REG_CHARGER_STATUS, val); + pmu_read(PMU_REG_INT_STATUS, &val); + pmu_write(PMU_REG_INT_CLR, val); + + pmu_read(PMU_REG_POWER_KEY_CFG, &val); + // Allow PMU to sleep when power key is pressed + val &= ~POWERKEY_WAKEUP_OSC_EN; + // Increase big bandgap startup time (stable time) + val = SET_BITFIELD(val, REG_VCORE_SSTIME_MODE, 2); + pmu_write(PMU_REG_POWER_KEY_CFG, val); + +#ifdef FORCE_BIG_BANDGAP + // Force big bandgap + pmu_read(PMU_REG_INT_EN, &val); + val |= REG_BG_SLEEP_MSK; + pmu_write(PMU_REG_INT_EN, val); + pmu_read(PMU_REG_BIAS_CFG, &val); + val |= BG_CONSTANT_GM_BIAS_DR | BG_CONSTANT_GM_BIAS_REG; + val |= BG_CORE_EN_DR | BG_CORE_EN_REG; + pmu_write(PMU_REG_BIAS_CFG, val); + hal_sys_timer_delay_us(20); + val |= BG_VBG_SEL_DR | BG_VBG_SEL_REG; + pmu_write(PMU_REG_BIAS_CFG, val); +#else + // Allow low power bandgap + pmu_read(PMU_REG_BIAS_CFG, &val); + val &= ~BG_VBG_SEL_DR; + pmu_write(PMU_REG_BIAS_CFG, val); +#endif + + // Init DCDC settings part 1 + if (pmu_metal_id >= HAL_CHIP_METAL_ID_1) { + pmu_write(PMU_REG_DCDC_ANA_CFG_16, 0x8E0F); + pmu_write(PMU_REG_DCDC_ANA_CFG_17, 0x0211); + pmu_write(PMU_REG_DCDC_ANA_CFG_18, 0xA484); + pmu_write(PMU_REG_DCDC_ANA_CFG_19, 0xE210); + + pmu_write(PMU_REG_DCDC_HPPA_CFG_1A, 0x8E0F); + pmu_write(PMU_REG_DCDC_HPPA_CFG_1B, 0x0211); + pmu_write(PMU_REG_DCDC_HPPA_CFG_1C, 0xA484); + pmu_write(PMU_REG_DCDC_HPPA_CFG_1D, 0xE210); + + pmu_write(PMU_REG_DCDC_DIG_CFG_33, 0x8E0F); + pmu_write(PMU_REG_DCDC_DIG_CFG_34, 0x0211); + pmu_write(PMU_REG_DCDC_DIG_CFG_35, 0xA484); + pmu_write(PMU_REG_DCDC_DIG_CFG_36, 0xE210); + + pmu_read(PMU_REG_MIC_LDO_EN, &val); + val |= DCDC1_OFFSET_CURRENT_EN; + pmu_write(PMU_REG_MIC_LDO_EN, val); + + pmu_read(PMU_REG_DCDC1_OFFSET, &val); + val = SET_BITFIELD(val, DCDC1_OFFSET_BIT, 0xE0); + pmu_write(PMU_REG_DCDC1_OFFSET, val); + } + +#ifdef PMU_DCDC_CALIB + pmu_get_dcdc_calib_value(); +#endif + +#ifndef NO_SLEEP + pmu_sleep_en(true); +#endif + + // Disable vbat2vcore + pmu_module_config(PMU_BAT2DIG,PMU_MANUAL_MODE,PMU_LDO_OFF,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); +#ifdef LBRT + // Enable vbuck2ana + pmu_module_config(PMU_BUCK2ANA,PMU_MANUAL_MODE,PMU_LDO_ON,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_ON); + pmu_module_set_volt(PMU_BUCK2ANA, PMU_VBUCK2ANA_1_3V, PMU_VBUCK2ANA_1_3V); + // Disable vana dcdc + pmu_read(PMU_REG_HPPA_LDO_EN, &val); + val &= ~REG_BYPASS_VBUCK2ANA; + pmu_write(PMU_REG_HPPA_LDO_EN, val); +#else + // Disable vbuck2ana + pmu_module_config(PMU_BUCK2ANA,PMU_MANUAL_MODE,PMU_LDO_OFF,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); +#endif + + // Disable vhppa ldo + pmu_ldo_hppa_en(false); + +#ifdef VMEM_ON + pmu_module_config(PMU_MEM,PMU_MANUAL_MODE,PMU_LDO_ON,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_ON); + pmu_module_ramp_volt(PMU_MEM, PMU_VMEM_1_8V, PMU_VMEM_1_8V); + pmu_hppa_en(false); + // VHPPA will be enabled/disabled dynamically. Enable soft start. + pmu_read(PMU_REG_DCDC_HPPA_CFG_1D, &val); + val |= DCDC3_SOFT_START_EN; + pmu_write(PMU_REG_DCDC_HPPA_CFG_1D, val); +#else + // vmem and vhppa is shorted -- enable vhppa dcdc and disable vmem ldo + val = pmu_vhppa_mv_to_val(1800); + pmu_hppa_set_volt(val, val); + pmu_hppa_en(true); + pmu_module_config(PMU_MEM,PMU_MANUAL_MODE,PMU_LDO_OFF,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); +#endif + + pmu_module_config(PMU_GP,PMU_MANUAL_MODE,PMU_LDO_OFF,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); + +#ifndef PROGRAMMER +#ifdef VUSB_ON + pmu_vusb_req |= PMU_VUSB_REQ_INIT; +#endif + // Disable usbphy power, and vusb if possible + pmu_usb_config(PMU_USB_CONFIG_TYPE_NONE); +#ifdef VUSB_ON + pmu_vusb_req &= ~PMU_VUSB_REQ_INIT; +#endif +#endif + +#ifdef __BEST_FLASH_VIA_ANA__ + pmu_module_config(PMU_IO,PMU_AUTO_MODE,PMU_LDO_ON,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); +#else + pmu_module_config(PMU_IO,PMU_AUTO_MODE,PMU_LDO_ON,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_ON); +#endif + pmu_module_ramp_volt(PMU_IO, vio_lp, vio_act_normal); + + // Disable vcodec + pmu_module_config(PMU_CODEC,PMU_MANUAL_MODE,PMU_LDO_OFF,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); + // Disable vhppa2vcodec + pmu_module_config(PMU_HPPA2CODEC,PMU_MANUAL_MODE,PMU_LDO_OFF,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); +#ifdef VHPPA2VCODEC + codec = PMU_HPPA2CODEC; +#else + codec = PMU_CODEC; +#endif + val = pmu_vcodec_mv_to_val(vcodec_mv); + // No need to ramp because the LDO is disabled (and its soft start is enabled) + pmu_module_set_volt(codec, val, val); + + val = pmu_vhppa_mv_to_val(vhppa_mv); +#ifdef VMEM_ON + // No need to ramp because VHPPA is disabled (and its soft start is enabled) + pmu_hppa_set_volt(val, val); +#else + uint16_t old_act_volt; + uint16_t old_lp_volt; + + // VHPPA is on. Ramp is needed. + pmu_hppa_get_volt(&old_act_volt, &old_lp_volt); + if (old_act_volt < val) { + while (old_act_volt++ < val) { + pmu_hppa_set_volt(old_act_volt, val); + } + } else if (old_act_volt != val || old_lp_volt != val) { + pmu_hppa_set_volt(val, val); + } +#endif + +#ifdef DIG_DCDC_MODE + mode = PMU_POWER_MODE_DIG_DCDC; +#elif defined(ANA_DCDC_MODE) + mode = PMU_POWER_MODE_ANA_DCDC; +#else // LDO_MODE + mode = PMU_POWER_MODE_LDO; +#endif + + pmu_mode_change(mode); + +#ifdef RTC_ENABLE + pmu_rtc_restore_context(); +#endif + +#if defined(MCU_HIGH_PERFORMANCE_MODE) + // Increase bbpll voltage + pmu_write(0xA0, 0x3FE8); // div=2 (bit14=0) + pmu_write(0xA1, 0xF918); + + pmu_high_performance_mode_enable(true); +#endif + + // Init DCDC settings part 2 + if (pmu_metal_id >= HAL_CHIP_METAL_ID_1) { + hal_sys_timer_delay_us(5000); + pmu_write(PMU_REG_DCDC_ANA_CFG_16, 0x8E1F); + pmu_write(PMU_REG_DCDC_HPPA_CFG_1A, 0x8E1F); + pmu_write(PMU_REG_DCDC_DIG_CFG_33, 0x8E1F); + } +#endif // PMU_INIT || (!FPGA && !PROGRAMMER) + + return 0; +} + +void pmu_codec_vad_save_power(void) +{ + uint16_t val; + + // reduce ldo power supply + pmu_read(PMU_REG_DCDC_RAMP_EN, &val); + val &= ~REG_MIC_BIASA_IX2; + pmu_write(PMU_REG_DCDC_RAMP_EN, val); + + // enable dcdc1 low power mode + pmu_read(PMU_REG_DCDC_DIG_EN, &val); + val |= REG_DCDC1_ULP_MODE_NORMAL; + pmu_write(PMU_REG_DCDC_DIG_EN, val); + + // enable dcdc2 low power mode + pmu_read(PMU_REG_DCDC_ANA_EN, &val); + val |= REG_DCDC2_ULP_MODE_NORMAL; + pmu_write(PMU_REG_DCDC_ANA_EN, val); + + // enable dcdc3 low power mode + pmu_read(PMU_REG_DCDC_HPPA_EN, &val); + val |= REG_DCDC3_ULP_MODE_NORMAL; + pmu_write(PMU_REG_DCDC_HPPA_EN, val); +} + +void pmu_codec_vad_restore_power(void) +{ + uint16_t val; + + // restore ldo power supply + pmu_read(PMU_REG_DCDC_RAMP_EN, &val); + val |= REG_MIC_BIASA_IX2; + pmu_write(PMU_REG_DCDC_RAMP_EN, val); + + // disable dcdc1 low power mode + pmu_read(PMU_REG_DCDC_DIG_EN, &val); + val &= ~REG_DCDC1_ULP_MODE_NORMAL; + pmu_write(PMU_REG_DCDC_DIG_EN, val); + + // disable dcdc2 low power mode + pmu_read(PMU_REG_DCDC_ANA_EN, &val); + val &= ~REG_DCDC2_ULP_MODE_NORMAL; + pmu_write(PMU_REG_DCDC_ANA_EN, val); + + // disable dcdc3 low power mode + pmu_read(PMU_REG_DCDC_HPPA_EN, &val); + val &= ~REG_DCDC3_ULP_MODE_NORMAL; + pmu_write(PMU_REG_DCDC_HPPA_EN, val); +} + +void pmu_sleep(void) +{ + uint16_t val; + + if (dcdc_ramp_map) { + // Enable DCDC ramp + pmu_read(PMU_REG_DCDC_RAMP_EN, &val); + val |= dcdc_ramp_map; + pmu_write(PMU_REG_DCDC_RAMP_EN, val); + } + + return; +} + +void pmu_wakeup(void) +{ + uint16_t val; + + if (dcdc_ramp_map) { + // Disable DCDC ramp so that s/w can control the voltages freely + pmu_read(PMU_REG_DCDC_RAMP_EN, &val); + val &= ~dcdc_ramp_map; + pmu_write(PMU_REG_DCDC_RAMP_EN, val); + } + + return; +} + +void pmu_codec_config(int enable) +{ + enum PMU_MODUAL_T codec; + +#ifdef VHPPA2VCODEC + codec = PMU_HPPA2CODEC; +#else + codec = PMU_CODEC; +#endif + + if (vcodec_off) { +#ifdef VMEM_ON + pmu_hppa_en(enable); +#endif + } else { + if (enable) { + pmu_module_config(codec,PMU_MANUAL_MODE,PMU_LDO_ON,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); + } else { + pmu_module_config(codec,PMU_MANUAL_MODE,PMU_LDO_OFF,PMU_LP_MODE_ON,PMU_DSLEEP_MODE_OFF); + } + } +} + +void pmu_codec_hppa_enable(int enable) +{ + if (!vcodec_off) { +#ifdef VMEM_ON + pmu_hppa_en(enable); +#endif + } +} + +static uint32_t mic_bias_remap(uint32_t map) +{ + // The vmic1 pin has been replaced by the vmic3 pin in package bonding for all chip models since ver-B + if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { + if (map & AUD_VMIC_MAP_VMIC1) { + map = (map & ~AUD_VMIC_MAP_VMIC1) | AUD_VMIC_MAP_VMIC3; + } + } + + return map; +} + +void pmu_codec_mic_bias_enable(uint32_t map) +{ + uint16_t val; + int i; + enum PMU_REG_T bias_reg; + uint16_t ldo_en; + uint8_t volt; + uint8_t res; + static const uint16_t ldo_mask = REG_MIC_LDOA_EN | REG_MIC_LDOB_EN | REG_MIC_LDOC_EN | REG_MIC_LDOD_EN | REG_MIC_LDOE_EN; + + map = mic_bias_remap(map); + +#ifdef DIGMIC_HIGH_VOLT + volt = PMU_VMIC_3_3V; +#else + volt = PMU_VMIC_2_2V; +#endif + + if (vcodec_mv < 1900) { + if (volt >= 0x1F) { + volt = 0x1F; + } else { + volt += 1; + } + } + + res = PMU_VMIC_RES_3_3V; + + ldo_en = 0; + for (i = 0; i < MAX_ANA_MIC_CH_NUM; i++) { + if (i == MAX_ANA_MIC_CH_NUM - 1) { + bias_reg = PMU_REG_MIC_BIAS_E; + } else { + bias_reg = PMU_REG_MIC_BIAS_A + i; + } + pmu_read(bias_reg, &val); + if (map & (AUD_VMIC_MAP_VMIC1 << i)) { + ldo_en |= (REG_MIC_LDOA_EN >> i); + val = (val & ~(REG_MIC_BIASA_VSEL_MASK | REG_MIC_LDOA_RES_MASK)) | + REG_MIC_BIASA_VSEL(volt) | REG_MIC_LDOA_RES(res) | REG_MIC_BIASA_EN; + } else { + val &= ~REG_MIC_BIASA_EN; + } + pmu_write(bias_reg, val); + } + pmu_read(PMU_REG_MIC_LDO_EN, &val); + val = (val & ~ldo_mask) | ldo_en; + pmu_write(PMU_REG_MIC_LDO_EN, val); +} + +void pmu_codec_mic_bias_lowpower_mode(uint32_t map) +{ + uint16_t val; + + map = mic_bias_remap(map); + + if (map & AUD_VMIC_MAP_VMIC3) { + pmu_read(PMU_REG_DCDC_RAMP_EN, &val); + val &= ~REG_MIC_BIASC_IX2; + pmu_write(PMU_REG_DCDC_RAMP_EN, val); + + pmu_read(PMU_REG_MIC_BIAS_C, &val); + val = SET_BITFIELD(val, REG_MIC_BIASC_CHANSEL, 0x3); + pmu_write(PMU_REG_MIC_BIAS_C, val); + } +} + +void pmu_codec_adc_pre_start(void) +{ +} + +void pmu_codec_adc_post_start(void (*delay_ms)(uint32_t)) +{ +} + +void pmu_codec_dac_pre_start(void) +{ +} + +void pmu_codec_dac_post_start(void (*delay_ms)(uint32_t)) +{ +} + +SRAM_TEXT_LOC void pmu_flash_write_config(void) +{ +#ifdef FLASH_WRITE_AT_HIGH_VCORE + uint32_t lock; + + if (pmu_vcore_req & PMU_VCORE_FLASH_WRITE_ENABLED) { + return; + } + +#if defined(__PMU_VIO_DYNAMIC_CTRL_MODE__) + pmu_viorise_req(PMU_VIORISE_REQ_USER_FLASH, true); +#endif + + lock = int_lock(); + pmu_vcore_req |= PMU_VCORE_FLASH_WRITE_ENABLED; + int_unlock(lock); + + pmu_dig_set_volt(0, PMU_POWER_MODE_NONE); +#endif +} + +SRAM_TEXT_LOC void pmu_flash_read_config(void) +{ +#ifdef FLASH_WRITE_AT_HIGH_VCORE + uint32_t lock; + + if ((pmu_vcore_req & PMU_VCORE_FLASH_WRITE_ENABLED) == 0) { + return; + } + + lock = int_lock(); + pmu_vcore_req &= ~PMU_VCORE_FLASH_WRITE_ENABLED; + int_unlock(lock); + + pmu_dig_set_volt(0, PMU_POWER_MODE_NONE); + +#if defined(__PMU_VIO_DYNAMIC_CTRL_MODE__) + pmu_viorise_req(PMU_VIORISE_REQ_USER_FLASH, false); +#endif +#endif +} + +void BOOT_TEXT_FLASH_LOC pmu_flash_freq_config(uint32_t freq) +{ +#if defined(PMU_INIT) || (!defined(FPGA) && !defined(PROGRAMMER)) + uint32_t lock; + + lock = int_lock(); + if (freq > 52000000) { + // The real max freq is 120M + //pmu_vcore_req |= PMU_VCORE_FLASH_FREQ_HIGH; + } else { + pmu_vcore_req &= ~PMU_VCORE_FLASH_FREQ_HIGH; + } + int_unlock(lock); + + if (pmu_power_mode == PMU_POWER_MODE_NONE) { + // PMU not init yet + pmu_dig_init_volt(); + return; + } + + pmu_dig_set_volt(0, PMU_POWER_MODE_NONE); +#endif +} + +void BOOT_TEXT_FLASH_LOC pmu_psram_freq_config(uint32_t freq) +{ +#if defined(PMU_INIT) || (!defined(FPGA) && !defined(PROGRAMMER)) + uint32_t lock; + + lock = int_lock(); + if (freq > 52000000) { + pmu_vcore_req |= PMU_VCORE_PSRAM_FREQ_HIGH; + } else { + pmu_vcore_req &= ~PMU_VCORE_PSRAM_FREQ_HIGH; + } + int_unlock(lock); + + if (pmu_power_mode == PMU_POWER_MODE_NONE) { + // PMU not init yet + pmu_dig_init_volt(); + return; + } + + pmu_dig_set_volt(0, PMU_POWER_MODE_NONE); +#endif +} + +void pmu_anc_config(int enable) +{ +} + +void pmu_fir_high_speed_config(int enable) +{ +} + +void pmu_iir_freq_config(uint32_t freq) +{ +} + +void pmu_rs_freq_config(uint32_t freq) +{ + uint32_t lock; + + lock = int_lock(); + if (freq >= 60000000) { + pmu_vcore_req |= PMU_VCORE_RS_FREQ_HIGH; + } else { + pmu_vcore_req &= ~PMU_VCORE_RS_FREQ_HIGH; + } + int_unlock(lock); + + pmu_dig_set_volt(0, PMU_POWER_MODE_NONE); +} + +void BOOT_TEXT_SRAM_LOC pmu_sys_freq_config(enum HAL_CMU_FREQ_T freq) +{ +#if defined(PMU_INIT) || (!defined(FPGA) && !defined(PROGRAMMER)) +#if defined(MCU_HIGH_PERFORMANCE_MODE) || defined(ULTRA_LOW_POWER) || !defined(OSC_26M_X4_AUD2BB) + uint32_t lock; + enum PMU_VCORE_REQ_T old_req; + bool update = false; + + lock = int_lock(); + old_req = pmu_vcore_req; + pmu_vcore_req &= ~(PMU_VCORE_SYS_FREQ_HIGH | PMU_VCORE_SYS_FREQ_MEDIUM); +#if defined(MCU_HIGH_PERFORMANCE_MODE) + if (freq > HAL_CMU_FREQ_104M) { + if (high_perf_on) { + // The real freq is 350M + pmu_vcore_req |= PMU_VCORE_SYS_FREQ_HIGH; + } else { + pmu_vcore_req |= PMU_VCORE_SYS_FREQ_MEDIUM; + } + } else { +#ifndef OSC_26M_X4_AUD2BB + if (freq == HAL_CMU_FREQ_104M) { + // The real freq is 200M + pmu_vcore_req |= PMU_VCORE_SYS_FREQ_MEDIUM; + } +#endif + } +#else + if (freq > HAL_CMU_FREQ_104M) { + pmu_vcore_req |= PMU_VCORE_SYS_FREQ_MEDIUM; + } +#endif + if (old_req != pmu_vcore_req) { + update = true; + } + int_unlock(lock); + + if (!update) { + // Nothing changes + return; + } + + if (pmu_power_mode == PMU_POWER_MODE_NONE) { + // PMU not init yet + pmu_dig_init_volt(); + return; + } + + pmu_dig_set_volt(0, PMU_POWER_MODE_NONE); +#endif +#endif +} + +void pmu_high_performance_mode_enable(bool enable) +{ +#if defined(MCU_HIGH_PERFORMANCE_MODE) + uint16_t val; + + if (high_perf_on == enable) { + return; + } + high_perf_on = enable; + + if (!enable) { + if (high_perf_freq_mhz > 300) { + // Switch to 52M to avoid using PLL + hal_cmu_sys_set_freq(HAL_CMU_FREQ_52M); + // Restore the default div + pmu_read(0xA0, &val); + val &= ~(1 << 14); // div=2 (bit14=0) + pmu_write(0xA0, val); + // Restore the sys freq + hal_cmu_sys_set_freq(hal_sysfreq_get_hw_freq()); + } + // Restore the default PLL freq (384M) + bbpll_freq_pll_config(192 * 1000000 * 2); + } + + pmu_sys_freq_config(hal_sysfreq_get_hw_freq()); + + if (enable) { + uint32_t pll_freq; + + // Change freq first, and then change divider. + // Otherwise there will be an instant very high freq sent to digital domain. + + if (high_perf_freq_mhz <= 300) { + pll_freq = high_perf_freq_mhz * 1000000 * 2; + } else { + pll_freq = high_perf_freq_mhz * 1000000; + } + bbpll_freq_pll_config(pll_freq); + + if (high_perf_freq_mhz > 300) { + // Switch to 52M to avoid using PLL + hal_cmu_sys_set_freq(HAL_CMU_FREQ_52M); + pmu_read(0xA0, &val); + val |= (1 << 14); // div=1 (bit14=1) + pmu_write(0xA0, val); + // Restore the sys freq + hal_cmu_sys_set_freq(hal_sysfreq_get_hw_freq()); + } + } +#endif +} + +void pmu_usb_config(enum PMU_USB_CONFIG_TYPE_T type) +{ + uint32_t lock; + bool update; + unsigned short ldo_on, deep_sleep_on; + + update = false; + + if (type == PMU_USB_CONFIG_TYPE_NONE) { + usbphy_ldo_config(false); + + ldo_on = PMU_LDO_OFF; + deep_sleep_on = PMU_DSLEEP_MODE_OFF; + } else { + ldo_on = PMU_LDO_ON; + deep_sleep_on = PMU_DSLEEP_MODE_ON; + } + + lock = int_lock(); + + if (type == PMU_USB_CONFIG_TYPE_NONE) { + pmu_vusb_req &= ~PMU_VUSB_REQ_USB; + if (pmu_vusb_req == 0) { + update = true; + } + } else { + if (pmu_vusb_req == 0) { + update = true; + } + pmu_vusb_req |= PMU_VUSB_REQ_USB; + } + + if (update) { + pmu_module_config(PMU_USB, PMU_MANUAL_MODE, ldo_on, PMU_LP_MODE_ON, deep_sleep_on); + } + +#ifdef USB_HIGH_SPEED + if (type == PMU_USB_CONFIG_TYPE_NONE) { + pmu_vcore_req &= ~PMU_VCORE_USB_HS_ENABLED; + } else { + pmu_vcore_req |= PMU_VCORE_USB_HS_ENABLED; + } +#endif + + int_unlock(lock); + + if (pmu_power_mode != PMU_POWER_MODE_NONE) { + // PMU has been inited + pmu_dig_set_volt(0, PMU_POWER_MODE_NONE); + } + + if (type != PMU_USB_CONFIG_TYPE_NONE) { + usbphy_ldo_config(true); + } +} + +void pmu_lbrt_config(int enable) +{ + uint32_t lock; + bool update; + unsigned short ldo_on, deep_sleep_on; + + update = false; + + if (enable) { + ldo_on = PMU_LDO_ON; + deep_sleep_on = PMU_DSLEEP_MODE_ON; + } else { + ldo_on = PMU_LDO_OFF; + deep_sleep_on = PMU_DSLEEP_MODE_OFF; + } + + lock = int_lock(); + + if (enable) { + if (pmu_vusb_req == 0) { + update = true; + } + pmu_vusb_req |= PMU_VUSB_REQ_LBRT; + } else { + pmu_vusb_req &= ~PMU_VUSB_REQ_LBRT; + if (pmu_vusb_req == 0) { + update = true; + } + } + + if (update) { + pmu_module_config(PMU_USB, PMU_MANUAL_MODE, ldo_on, PMU_LP_MODE_ON, deep_sleep_on); + } + + int_unlock(lock); +} + +struct PMU_CHG_CTX_T { + uint16_t pmu_chg_status; +}; + +struct PMU_CHG_CTX_T BOOT_BSS_LOC pmu_chg_ctx; + +void BOOT_TEXT_SRAM_LOC pmu_charger_save_context(void) +{ + pmu_read(PMU_REG_CHARGER_STATUS, &pmu_chg_ctx.pmu_chg_status); +} + +enum PMU_POWER_ON_CAUSE_T pmu_charger_poweron_status(void) +{ + enum PMU_POWER_ON_CAUSE_T pmu_power_on_cause = PMU_POWER_ON_CAUSE_NONE; + + if (pmu_chg_ctx.pmu_chg_status & AC_ON_DET_OUT){ + pmu_power_on_cause = PMU_POWER_ON_CAUSE_CHARGER_ACOFF; + }else if (pmu_chg_ctx.pmu_chg_status & AC_ON){ + pmu_power_on_cause = PMU_POWER_ON_CAUSE_CHARGER_ACON; + } + return pmu_power_on_cause; +} + +void pmu_charger_init(void) +{ + unsigned short readval_cfg; + uint32_t lock; + + lock = int_lock(); + pmu_read(PMU_REG_CHARGER_CFG, &readval_cfg); + readval_cfg &= ~(REG_CHARGE_IN_INTR_MSK | REG_CHARGE_OUT_INTR_MSK | + REG_AC_ON_OUT_EN | REG_AC_ON_IN_EN | REG_CHARGE_INTR_EN); + pmu_write(PMU_REG_CHARGER_CFG ,readval_cfg); + int_unlock(lock); + + // PMU irqs cannot be cleared by PMU soft reset + pmu_read(PMU_REG_CHARGER_STATUS, &readval_cfg); + pmu_write(PMU_REG_CHARGER_STATUS, readval_cfg); + pmu_read(PMU_REG_INT_STATUS, &readval_cfg); + pmu_write(PMU_REG_INT_CLR, readval_cfg); + + hal_sys_timer_delay(MS_TO_TICKS(1)); + + lock = int_lock(); + pmu_read(PMU_REG_CHARGER_CFG, &readval_cfg); + readval_cfg |= REG_AC_ON_OUT_EN | REG_AC_ON_IN_EN | REG_CHARGE_INTR_EN; + readval_cfg = SET_BITFIELD(readval_cfg, REG_AC_ON_DB_VALUE, 8); + pmu_write(PMU_REG_CHARGER_CFG ,readval_cfg); + int_unlock(lock); + +#ifdef PMU_ACON_CAUSE_POWER_UP + pmu_read(0x102 ,&readval_cfg); + readval_cfg |= 1; + pmu_write(0x102,readval_cfg); +#endif +} + +void pmu_charger_shutdown_config(void) +{ +#ifdef PMU_ACON_CAUSE_POWER_UP + pmu_wdt_stop(); + pmu_charger_init(); +#endif +} + +static void pmu_charger_irq_handler(uint16_t irq_status) +{ + enum PMU_CHARGER_STATUS_T status = PMU_CHARGER_UNKNOWN; + + PMU_DEBUG_TRACE(3,"%s REG_%02X=0x%04X", __func__, PMU_REG_CHARGER_STATUS, irq_status); + + if ((irq_status & (AC_ON_DET_IN_MASKED | AC_ON_DET_OUT_MASKED)) == 0){ + PMU_DEBUG_TRACE(1,"%s SKIP", __func__); + return; + } else if ((irq_status & (AC_ON_DET_IN_MASKED | AC_ON_DET_OUT_MASKED)) == + (AC_ON_DET_IN_MASKED | AC_ON_DET_OUT_MASKED)) { + PMU_DEBUG_TRACE(1,"%s DITHERING", __func__); + hal_sys_timer_delay(2); + } else { + PMU_DEBUG_TRACE(1,"%s NORMAL", __func__); + } + + status = pmu_charger_get_status(); + + if (charger_irq_handler) { + charger_irq_handler(status); + } +} + +void pmu_charger_set_irq_handler(PMU_CHARGER_IRQ_HANDLER_T handler) +{ + uint32_t lock; + uint16_t val; + + charger_irq_handler = handler; + + lock = int_lock(); + pmu_read(PMU_REG_CHARGER_CFG, &val); + if (handler) { + val |= REG_CHARGE_IN_INTR_MSK | REG_CHARGE_OUT_INTR_MSK; + } else { + val &= ~(REG_CHARGE_IN_INTR_MSK | REG_CHARGE_OUT_INTR_MSK); + } + pmu_write(PMU_REG_CHARGER_CFG, val); + pmu_set_irq_unified_handler(PMU_IRQ_TYPE_CHARGER, handler ? pmu_charger_irq_handler : NULL); + int_unlock(lock); +} + +void pmu_charger_plugin_config(void) +{ + if (IO_VOLT_ACTIVE_RISE < PMU_IO_3_1V) { + vio_act_rise = PMU_IO_3_1V; + } + if (IO_VOLT_SLEEP < PMU_IO_3_2V) { + vio_lp = PMU_IO_3_2V; + } + pmu_viorise_req(PMU_VIORISE_REQ_USER_CHARGER, true); +} + +void pmu_charger_plugout_config(void) +{ + vio_act_rise = IO_VOLT_ACTIVE_RISE; + vio_lp = IO_VOLT_SLEEP; + pmu_viorise_req(PMU_VIORISE_REQ_USER_CHARGER, false); +} + +enum PMU_CHARGER_STATUS_T pmu_charger_get_status(void) +{ + unsigned short readval; + enum PMU_CHARGER_STATUS_T status; + + pmu_read(PMU_REG_CHARGER_STATUS, &readval); + if (readval & AC_ON) + status = PMU_CHARGER_PLUGIN; + else + status = PMU_CHARGER_PLUGOUT; + + return status; +} + +#ifdef RTC_ENABLE +void pmu_rtc_enable(void) +{ + uint16_t readval; + uint32_t lock; + +#ifdef SIMU + // Set RTC counter to 1KHz + pmu_write(PMU_REG_RTC_DIV_1HZ, 32 - 2); +#else + // Set RTC counter to 1Hz + pmu_write(PMU_REG_RTC_DIV_1HZ, CONFIG_SYSTICK_HZ * 2 - 2); +#endif + + lock = int_lock(); + pmu_read(PMU_REG_POWER_KEY_CFG, &readval); + readval |= RTC_POWER_ON_EN | PU_LPO_DR | PU_LPO_REG; + pmu_write(PMU_REG_POWER_KEY_CFG, readval); + int_unlock(lock); +} + +void pmu_rtc_disable(void) +{ + uint16_t readval; + uint32_t lock; + + pmu_rtc_clear_alarm(); + + lock = int_lock(); + pmu_read(PMU_REG_POWER_KEY_CFG, &readval); + readval &= ~(RTC_POWER_ON_EN | PU_LPO_DR); + pmu_write(PMU_REG_POWER_KEY_CFG, readval); + int_unlock(lock); +} + +int BOOT_TEXT_SRAM_LOC pmu_rtc_enabled(void) +{ + uint16_t readval; + + pmu_read(PMU_REG_POWER_KEY_CFG, &readval); + + return !!(readval & RTC_POWER_ON_EN); +} + +void pmu_rtc_set(uint32_t seconds) +{ + uint16_t high, low; + + // Need 3 seconds to load a new value + seconds += 3; + + high = seconds >> 16; + low = seconds & 0xFFFF; + + pmu_write(PMU_REG_RTC_LOAD_LOW, low); + pmu_write(PMU_REG_RTC_LOAD_HIGH, high); +} + +uint32_t pmu_rtc_get(void) +{ + uint16_t high, low, high2; + + pmu_read(PMU_REG_RTC_VAL_HIGH, &high); + pmu_read(PMU_REG_RTC_VAL_LOW, &low); + // Handle counter wrap + pmu_read(PMU_REG_RTC_VAL_HIGH, &high2); + if (high != high2) { + high = high2; + pmu_read(PMU_REG_RTC_VAL_LOW, &low); + } + + return (high << 16) | low; +} + +void pmu_rtc_set_alarm(uint32_t seconds) +{ + uint16_t readval; + uint16_t high, low; + uint32_t lock; + + // Need 1 second to raise the interrupt + if (seconds > 0) { + seconds -= 1; + } + + high = seconds >> 16; + low = seconds & 0xFFFF; + + pmu_write(PMU_REG_INT_CLR, RTC_INT1_MSKED); + + pmu_write(PMU_REG_RTC_MATCH1_LOW, low); + pmu_write(PMU_REG_RTC_MATCH1_HIGH, high); + + lock = int_lock(); + pmu_read(PMU_REG_INT_EN, &readval); + readval |= RTC_INT_EN_1; + pmu_write(PMU_REG_INT_EN, readval); + int_unlock(lock); +} + +uint32_t BOOT_TEXT_SRAM_LOC pmu_rtc_get_alarm(void) +{ + uint16_t high, low; + + pmu_read(PMU_REG_RTC_MATCH1_LOW, &low); + pmu_read(PMU_REG_RTC_MATCH1_HIGH, &high); + + // Compensate the alarm offset + return (uint32_t)((high << 16) | low) + 1; +} + +void pmu_rtc_clear_alarm(void) +{ + uint16_t readval; + uint32_t lock; + + lock = int_lock(); + pmu_read(PMU_REG_INT_EN, &readval); + readval &= ~RTC_INT_EN_1; + pmu_write(PMU_REG_INT_EN, readval); + int_unlock(lock); + + pmu_write(PMU_REG_INT_CLR, RTC_INT1_MSKED); +} + +int BOOT_TEXT_SRAM_LOC pmu_rtc_alarm_status_set(void) +{ + uint16_t readval; + + pmu_read(PMU_REG_INT_EN, &readval); + + return !!(readval & RTC_INT_EN_1); +} + +int pmu_rtc_alarm_alerted() +{ + uint16_t readval; + + pmu_read(PMU_REG_INT_STATUS, &readval); + + return !!(readval & RTC_INT_1); +} + +static void pmu_rtc_irq_handler(uint16_t irq_status) +{ + uint32_t seconds; + + if (irq_status & RTC_INT1_MSKED) { + pmu_rtc_clear_alarm(); + + if (rtc_irq_handler) { + seconds = pmu_rtc_get(); + rtc_irq_handler(seconds); + } + } +} + +void pmu_rtc_set_irq_handler(PMU_RTC_IRQ_HANDLER_T handler) +{ + uint16_t readval; + uint32_t lock; + + rtc_irq_handler = handler; + + lock = int_lock(); + pmu_read(PMU_REG_INT_MASK, &readval); + if (handler) { + readval |= RTC_INT1_MSK; + } else { + readval &= ~RTC_INT1_MSK; + } + pmu_write(PMU_REG_INT_MASK, readval); + pmu_set_irq_unified_handler(PMU_IRQ_TYPE_RTC, handler ? pmu_rtc_irq_handler : NULL); + int_unlock(lock); +} +#endif + +int pmu_pwrkey_set_irq(enum HAL_PWRKEY_IRQ_T type) +{ + uint16_t val; + uint16_t int_en; + + if (type == HAL_PWRKEY_IRQ_NONE) { + // Clear existing IRQs + pmu_write(PMU_REG_CHARGER_STATUS, (POWER_ON_PRESS | POWER_ON_RELEASE)); + // Disable future IRQs + int_en = 0; + } else if (type == HAL_PWRKEY_IRQ_FALLING_EDGE) { + int_en = POWERON_PRESS_EN; + } else if (type == HAL_PWRKEY_IRQ_RISING_EDGE) { + int_en = POWERON_RELEASE_EN; + } else if (type == HAL_PWRKEY_IRQ_BOTH_EDGE) { + int_en = POWERON_PRESS_EN | POWERON_RELEASE_EN; + } else { + return 1; + } + + pmu_read(PMU_REG_SLEEP_CFG, &val); + val = (val & ~(POWERON_PRESS_EN | POWERON_RELEASE_EN)) | int_en; + pmu_write(PMU_REG_SLEEP_CFG, val); + + return 0; +} +int hal_pwrkey_set_irq(enum HAL_PWRKEY_IRQ_T type) __attribute__((alias("pmu_pwrkey_set_irq"))); + +bool pmu_pwrkey_pressed(void) +{ + uint16_t val; + + pmu_read(PMU_REG_CHARGER_STATUS, &val); + + return !!(val & POWER_ON); +} +bool hal_pwrkey_pressed(void) __attribute__((alias("pmu_pwrkey_pressed"))); + +enum HAL_PWRKEY_IRQ_T pmu_pwrkey_irq_value_to_state(uint16_t irq_status) +{ + enum HAL_PWRKEY_IRQ_T state = HAL_PWRKEY_IRQ_NONE; + + if (irq_status & POWER_ON_PRESS) { + state |= HAL_PWRKEY_IRQ_FALLING_EDGE; + } + + if (irq_status & POWER_ON_RELEASE) { + state |= HAL_PWRKEY_IRQ_RISING_EDGE; + } + + return state; +} + +static void pmu_general_irq_handler(void) +{ + uint32_t lock; + uint16_t val; + bool pwrkey, charger, gpadc, rtc; + + pwrkey = false; + charger = false; + gpadc = false; + rtc = false; + + lock = int_lock(); + pmu_read(PMU_REG_CHARGER_STATUS, &val); + if (val & (POWER_ON_PRESS | POWER_ON_RELEASE)) { + pwrkey = true; + } + if (val & (AC_ON_DET_OUT_MASKED | AC_ON_DET_IN_MASKED)) { + charger = true; + } + if (pwrkey || charger) { + pmu_write(PMU_REG_CHARGER_STATUS, val); + } + int_unlock(lock); + + if (pwrkey) { + if (pmu_irq_hdlrs[PMU_IRQ_TYPE_PWRKEY]) { + pmu_irq_hdlrs[PMU_IRQ_TYPE_PWRKEY](val); + } + } + if (charger) { + if (pmu_irq_hdlrs[PMU_IRQ_TYPE_CHARGER]) { + pmu_irq_hdlrs[PMU_IRQ_TYPE_CHARGER](val); + } + } + + lock = int_lock(); + pmu_read(PMU_REG_INT_MSKED_STATUS, &val); + if (val & (KEY_ERR1_INTR_MSKED | KEY_ERR0_INTR_MSKED | KEY_PRESS_INTR_MSKED | KEY_RELEASE_INTR_MSKED | + SAMPLE_DONE_INTR_MSKED | CHAN_DATA_INTR_MSKED_MASK)) { + gpadc = true; + } + if (val & (RTC_INT1_MSKED | RTC_INT0_MSKED)) { + rtc = true; + } + if (gpadc || rtc) { + pmu_write(PMU_REG_INT_CLR, val); + } + int_unlock(lock); + + if (gpadc) { + if (pmu_irq_hdlrs[PMU_IRQ_TYPE_GPADC]) { + pmu_irq_hdlrs[PMU_IRQ_TYPE_GPADC](val); + } + } + if (rtc) { + if (pmu_irq_hdlrs[PMU_IRQ_TYPE_RTC]) { + pmu_irq_hdlrs[PMU_IRQ_TYPE_RTC](val); + } + } +} + +int pmu_set_irq_unified_handler(enum PMU_IRQ_TYPE_T type, PMU_IRQ_UNIFIED_HANDLER_T hdlr) +{ + bool update; + uint32_t lock; + int i; + + if (type >= PMU_IRQ_TYPE_QTY) { + return 1; + } + + update = false; + + lock = int_lock(); + + for (i = 0; i < PMU_IRQ_TYPE_QTY; i++) { + if (pmu_irq_hdlrs[i]) { + break; + } + } + + pmu_irq_hdlrs[type] = hdlr; + + if (hdlr) { + update = (i >= PMU_IRQ_TYPE_QTY); + } else { + if (i == type) { + for (; i < PMU_IRQ_TYPE_QTY; i++) { + if (pmu_irq_hdlrs[i]) { + break; + } + } + update = (i >= PMU_IRQ_TYPE_QTY); + } + } + + if (update) { + if (hdlr) { + NVIC_SetVector(PMU_IRQn, (uint32_t)pmu_general_irq_handler); + NVIC_SetPriority(PMU_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(PMU_IRQn); + NVIC_EnableIRQ(PMU_IRQn); + } else { + NVIC_DisableIRQ(PMU_IRQn); + } + } + + int_unlock(lock); + + return 0; +} + +enum PMU_POWER_ON_CAUSE_T pmu_get_power_on_cause(void) +{ + enum PMU_POWER_ON_CAUSE_T pmu_power_on_cause = PMU_POWER_ON_CAUSE_NONE; + + pmu_power_on_cause = pmu_charger_poweron_status(); + if (pmu_power_on_cause == PMU_POWER_ON_CAUSE_NONE){ + pmu_power_on_cause = PMU_POWER_ON_CAUSE_POWER_KEY; + } + + return pmu_power_on_cause; +} + +void pmu_viorise_req(enum PMU_VIORISE_REQ_USER_T user, bool rise) +{ + uint32_t lock; + + lock = int_lock(); + if (rise) { + if (vio_risereq_map == 0) { + pmu_module_ramp_volt(PMU_IO,vio_lp,vio_act_rise); + } + vio_risereq_map |= (1 << user); + } else { + vio_risereq_map &= ~(1 << user); + if (vio_risereq_map == 0) { + pmu_module_ramp_volt(PMU_IO,vio_lp,vio_act_normal); + } + } + int_unlock(lock); +} + +int pmu_debug_config_ana(uint16_t volt) +{ + return 0; +} + +int pmu_debug_config_codec(uint16_t volt) +{ +#ifdef ANC_PROD_TEST + if (volt == 1600 || volt == 1700 || volt == 1800 || volt == 1900 || volt == 1950) { + vhppa_mv = vcodec_mv = volt; + vcodec_off = true; + } else { + vcodec_off = false; + return 1; + } +#endif + return 0; +} + +int pmu_debug_config_vcrystal(bool on) +{ + return 0; +} + +int pmu_debug_config_audio_output(bool diff) +{ + return 0; +} + +void pmu_debug_reliability_test(int stage) +{ + uint16_t volt; + + if (stage == 0) { + volt = PMU_DCDC_ANA_1_2V; + } else { + volt = PMU_DCDC_ANA_1_3V; + } + pmu_dcdc_ana_set_volt(volt, ana_lp_dcdc); +} + +void pmu_led_set_hiz(enum HAL_GPIO_PIN_T pin) +{ + uint16_t val1, val2; + uint32_t lock; + + if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) { + lock = int_lock(); + pmu_read(PMU_REG_MIC_LDO_EN, &val1); + pmu_read(PMU_REG_LED_CFG, &val2); + if (pin == HAL_GPIO_PIN_LED1) { + val1 &= ~REG_LED_IO1_RX_EN; + val2 = (val2 | REG_LED_IO1_PU | REG_LED_IO1_OENB) & ~(REG_LED_IO1_PUEN | REG_LED_IO1_PDEN); + } else { + val1 &= ~REG_LED_IO2_RX_EN; + val2 = (val2 | REG_LED_IO2_PU | REG_LED_IO2_OENB) & ~(REG_LED_IO2_PUEN | REG_LED_IO2_PDEN); + } + pmu_write(PMU_REG_MIC_LDO_EN, val1); + pmu_write(PMU_REG_LED_CFG, val2); + int_unlock(lock); + } +} + +void pmu_led_set_direction(enum HAL_GPIO_PIN_T pin, enum HAL_GPIO_DIR_T dir) +{ + uint16_t val; + uint16_t val_rx; + uint32_t lock; + + if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) { + lock = int_lock(); + pmu_read(PMU_REG_LED_CFG, &val); + pmu_read(PMU_REG_MIC_LDO_EN, &val_rx); + if (pin == HAL_GPIO_PIN_LED1) { + val |= REG_LED_IO1_PU; + if (dir == HAL_GPIO_DIR_IN) { + val |= REG_LED_IO1_OENB; + val_rx |= REG_LED_IO1_RX_EN; + } else { + val &= ~REG_LED_IO1_OENB; + val_rx &= ~REG_LED_IO1_RX_EN; + } + } else { + val |= REG_LED_IO2_PU; + if (dir == HAL_GPIO_DIR_IN) { + val |= REG_LED_IO2_OENB; + val_rx |= REG_LED_IO2_RX_EN; + } else { + val &= ~REG_LED_IO2_OENB; + val_rx &= ~REG_LED_IO2_RX_EN; + } + } + pmu_write(PMU_REG_LED_CFG, val); + pmu_write(PMU_REG_MIC_LDO_EN, val_rx);; + int_unlock(lock); + } +} + +enum HAL_GPIO_DIR_T pmu_led_get_direction(enum HAL_GPIO_PIN_T pin) +{ + uint16_t val; + + if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) { + pmu_read(PMU_REG_LED_CFG, &val); + if (pin == HAL_GPIO_PIN_LED1) { + return (val & REG_LED_IO1_OENB) ? HAL_GPIO_DIR_IN : HAL_GPIO_DIR_OUT; + } else { + return (val & REG_LED_IO2_OENB) ? HAL_GPIO_DIR_IN : HAL_GPIO_DIR_OUT; + } + } else { + return HAL_GPIO_DIR_IN; + } +} + +void pmu_led_set_voltage_domains(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt) +{ + enum PMU_LED_VOLT_T { + PMU_LED_VOLT_VBAT, + PMU_LED_VOLT_VMEM, + PMU_LED_VOLT_VIO, + }; + enum PMU_LED_VOLT_T sel; + uint16_t val; + uint32_t lock; + + if (pin == HAL_IOMUX_PIN_LED1 || pin == HAL_IOMUX_PIN_LED2) { + if (volt == HAL_IOMUX_PIN_VOLTAGE_VIO) { + sel = PMU_LED_VOLT_VIO; + } else if (volt == HAL_IOMUX_PIN_VOLTAGE_MEM) { + sel = PMU_LED_VOLT_VMEM; + } else { + sel = PMU_LED_VOLT_VBAT; + } + + lock = int_lock(); + pmu_read(PMU_REG_LED_CFG, &val); + if (pin == HAL_IOMUX_PIN_LED1) { + val = SET_BITFIELD(val, REG_LED_IO1_SEL, sel); + } else { + val = SET_BITFIELD(val, REG_LED_IO2_SEL, sel); + } + pmu_write(PMU_REG_LED_CFG, val); + int_unlock(lock); + } +} + +void pmu_led_set_pull_select(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_PIN_PULL_SELECT_T pull_sel) +{ + uint16_t val; + uint32_t lock; + + if (pin == HAL_IOMUX_PIN_LED1 || pin == HAL_IOMUX_PIN_LED2) { + lock = int_lock(); + pmu_read(PMU_REG_LED_CFG, &val); + if (pin == HAL_IOMUX_PIN_LED1) { + val &= ~(REG_LED_IO1_PDEN | REG_LED_IO1_PUEN); + if (pull_sel == HAL_IOMUX_PIN_PULLUP_ENABLE) { + val |= REG_LED_IO1_PUEN; + } else if (pull_sel == HAL_IOMUX_PIN_PULLDOWN_ENABLE) { + val |= REG_LED_IO1_PDEN; + } + } else { + val &= ~(REG_LED_IO2_PDEN | REG_LED_IO2_PUEN); + if (pull_sel == HAL_IOMUX_PIN_PULLUP_ENABLE) { + val |= REG_LED_IO2_PUEN; + } else if (pull_sel == HAL_IOMUX_PIN_PULLDOWN_ENABLE) { + val |= REG_LED_IO2_PDEN; + } + } + pmu_write(PMU_REG_LED_CFG, val); + int_unlock(lock); + } +} + +void pmu_led_set_value(enum HAL_GPIO_PIN_T pin, int data) +{ + uint16_t val; + uint32_t lock; +#ifdef PMU_LED_VIA_PWM + uint16_t br_val; +#endif + if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) { + lock = int_lock(); +#ifdef PMU_LED_VIA_PWM + pmu_read(PMU_REG_PWM_BR_EN, &br_val); +#endif + pmu_read(PMU_REG_PWM_EN, &val); + if (pin == HAL_GPIO_PIN_LED1) { +#ifdef PMU_LED_VIA_PWM + pmu_write(PMU_REG_PWM2_TOGGLE, 0xFFFF); + br_val &= ~REG_PWM2_BR_EN; + val |= PWM_SELECT_EN(1 << 0); + if (data) { + val &= ~PWM_SELECT_INV(1 << 0); + } else { + val |= PWM_SELECT_INV(1 << 0); + } +#else + if (data) { + val |= REG_LED0_OUT; + } else { + val &= ~REG_LED0_OUT; + } +#endif + } else { +#ifdef PMU_LED_VIA_PWM + pmu_write(PMU_REG_PWM3_TOGGLE, 0xFFFF); + br_val &= ~REG_PWM3_BR_EN; + val |= PWM_SELECT_EN(1 << 1); + if (data) { + val &= ~PWM_SELECT_INV(1 << 1); + } else { + val |= PWM_SELECT_INV(1 << 1); + } +#else + if (data) { + val |= REG_LED1_OUT; + } else { + val &= ~REG_LED1_OUT; + } +#endif + } +#ifdef PMU_LED_VIA_PWM + pmu_write(PMU_REG_PWM_BR_EN, br_val); +#endif + pmu_write(PMU_REG_PWM_EN, val); + int_unlock(lock); + } +} + +int pmu_led_get_value(enum HAL_GPIO_PIN_T pin) +{ + uint16_t val; + int data = 0; + + if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) { + pmu_read(PMU_REG_POWER_OFF, &val); + if (pin == HAL_GPIO_PIN_LED1) { + data = REG_LED_IO1_DATA_IN; + } else { + data = REG_LED_IO2_DATA_IN; + } + data &= val; + } + + return !!data; +} + +struct PMU_WDT_CTX_T { + bool enabled; + uint16_t wdt_timer; + uint16_t wdt_cfg; +}; + +static struct PMU_WDT_CTX_T BOOT_BSS_LOC wdt_ctx; + +void BOOT_TEXT_SRAM_LOC pmu_wdt_save_context(void) +{ + uint16_t wdt_cfg = 0, wdt_timer = 0; + pmu_read(PMU_REG_WDT_CFG, &wdt_cfg); + if (wdt_cfg & (REG_WDT_RESET_EN | REG_WDT_EN)){ + wdt_ctx.enabled = true; + wdt_ctx.wdt_cfg = wdt_cfg; + pmu_read(PMU_REG_WDT_TIMER, &wdt_timer); + wdt_ctx.wdt_timer = wdt_timer; + } +} + +void BOOT_TEXT_SRAM_LOC pmu_wdt_restore_context(void) +{ + if (wdt_ctx.enabled) { + pmu_write(PMU_REG_WDT_TIMER, wdt_ctx.wdt_timer); + pmu_write(PMU_REG_WDT_CFG, wdt_ctx.wdt_cfg); + } +} + +void pmu_wdt_set_irq_handler(PMU_WDT_IRQ_HANDLER_T handler) +{ +} + +int pmu_wdt_config(uint32_t irq_ms, uint32_t reset_ms) +{ + // No wdt irq on best2300 + if (irq_ms + reset_ms > 0xFFFF) { + return 1; + } + wdt_timer = irq_ms + reset_ms; + + pmu_write(PMU_REG_WDT_TIMER, wdt_timer); + + return 0; +} + +void pmu_wdt_start(void) +{ + uint16_t val; + + if (wdt_timer == 0) { + return; + } + + pmu_read(PMU_REG_WDT_CFG, &val); + val |= (REG_WDT_RESET_EN | REG_WDT_EN); + pmu_write(PMU_REG_WDT_CFG, val); +} + +void pmu_wdt_stop(void) +{ + uint16_t val; + + if (wdt_timer == 0) { + return; + } + + pmu_read(PMU_REG_WDT_CFG, &val); + val &= ~(REG_WDT_RESET_EN | REG_WDT_EN); + pmu_write(PMU_REG_WDT_CFG, val); +} + +void pmu_wdt_feed(void) +{ + if (wdt_timer == 0) { + return; + } + + pmu_write(PMU_REG_WDT_TIMER, wdt_timer); +} + +void pmu_ntc_capture_enable(void) +{ +} + +void pmu_ntc_capture_disable(void) +{ +} + diff --git a/platform/drivers/ana/best2300p/pmu_best2300p.h b/platform/drivers/ana/best2300p/pmu_best2300p.h new file mode 100644 index 0000000..c799135 --- /dev/null +++ b/platform/drivers/ana/best2300p/pmu_best2300p.h @@ -0,0 +1,100 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __PMU_BEST2300P_H__ +#define __PMU_BEST2300P_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_cmu.h" + +enum PMU_EFUSE_PAGE_T { + PMU_EFUSE_PAGE_SECURITY = 0, + PMU_EFUSE_PAGE_BOOT = 1, + PMU_EFUSE_PAGE_FEATURE = 2, + PMU_EFUSE_PAGE_BATTER_LV = 3, + + PMU_EFUSE_PAGE_BATTER_HV = 4, + PMU_EFUSE_PAGE_SW_CFG = 5, + PMU_EFUSE_PAGE_PROD_TEST = 6, + PMU_EFUSE_PAGE_RESERVED_7 = 7, + + PMU_EFUSE_PAGE_BT_POWER = 8, + PMU_EFUSE_PAGE_DCCALIB2_L = 9, + PMU_EFUSE_PAGE_DCCALIB2_R = 10, + PMU_EFUSE_PAGE_DCCALIB_L = 11, + + PMU_EFUSE_PAGE_DCCALIB_R = 12, + PMU_EFUSE_PAGE_RESERVED_13 = 13, + PMU_EFUSE_PAGE_MODEL = 14, + PMU_EFUSE_PAGE_RESERVED_15 = 15, + + PMU_EFUSE_PAGE_BOOT_SIG1 = 16, + PMU_EFUSE_PAGE_BOOT_SIG2 = 17, + PMU_EFUSE_PAGE_BOOT_SIG3 = 18, + PMU_EFUSE_PAGE_RESERVED_19 = 19, + + PMU_EFUSE_PAGE_RESERVED_20 = 20, + PMU_EFUSE_PAGE_RESERVED_21 = 21, + PMU_EFUSE_PAGE_RESERVED_22 = 22, + PMU_EFUSE_PAGE_RESERVED_23 = 23, +}; + +enum PMU_IRQ_TYPE_T { + PMU_IRQ_TYPE_PWRKEY, + PMU_IRQ_TYPE_GPADC, + PMU_IRQ_TYPE_RTC, + PMU_IRQ_TYPE_CHARGER, + + PMU_IRQ_TYPE_QTY +}; + +enum PMU_PLL_DIV_TYPE_T { + PMU_PLL_DIV_DIG, + PMU_PLL_DIV_CODEC, +}; + +void pmu_codec_hppa_enable(int enable); + +void pmu_codec_mic_bias_enable(uint32_t map); + +void pmu_codec_mic_bias_lowpower_mode(uint32_t map); + +int pmu_codec_volt_ramp_up(void); + +int pmu_codec_volt_ramp_down(void); + +void pmu_codec_vad_save_power(void); + +void pmu_codec_vad_restore_power(void); + +void pmu_lbrt_config(int enable); + +void pmu_pll_div_reset_set(enum HAL_CMU_PLL_T pll); + +void pmu_pll_div_reset_clear(enum HAL_CMU_PLL_T pll); + +void pmu_pll_div_set(enum HAL_CMU_PLL_T pll, enum PMU_PLL_DIV_TYPE_T type, uint32_t div); + +void pmu_led_set_hiz(enum HAL_GPIO_PIN_T pin); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/ana/best2300p/reg_usbphy_best2300p.h b/platform/drivers/ana/best2300p/reg_usbphy_best2300p.h new file mode 100644 index 0000000..b4aeac3 --- /dev/null +++ b/platform/drivers/ana/best2300p/reg_usbphy_best2300p.h @@ -0,0 +1,573 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_USBPHY_BEST2300P_H__ +#define __REG_USBPHY_BEST2300P_H__ + +#include "plat_types.h" + +// REG_00 +#define REG_00_REVID_SHIFT 0 +#define REG_00_REVID_MASK (0xF << REG_00_REVID_SHIFT) +#define REG_00_REVID(n) BITFIELD_VAL(REG_00_REVID, n) +#define REG_00_CHIPID_SHIFT 4 +#define REG_00_CHIPID_MASK (0xFFF << REG_00_CHIPID_SHIFT) +#define REG_00_CHIPID(n) BITFIELD_VAL(REG_00_CHIPID, n) + +// REG_01 +#define REG_01_CFG_ANAPHY_RESETN (1 << 0) +#define REG_01_CFG_CKCDR_EN (1 << 1) +#define REG_01_CFG_CKPLL_EN (1 << 2) +#define REG_01_CFG_EN_CLKMAC (1 << 3) +#define REG_01_CFG_POL_CDRCLK (1 << 4) +#define REG_01_CFG_RESETN_MAC (1 << 5) +#define REG_01_CFG_RESETNCDR (1 << 6) +#define REG_01_CFG_RESETNPLL (1 << 7) +#define REG_01_CFG_BYPASS_CDR_ENDRESETN (1 << 8) +#define REG_01_CFG_INTR_EN_ALL (1 << 9) +#define REG_01_CFG_LOW_SPEED_MODE (1 << 10) +#define REG_01_CFG_POL_CLKPLL (1 << 11) +#define REG_01_CFG_BYPASS_RDY (1 << 12) +#define REG_01_CFG_MODE_HS_LINES_TX (1 << 13) +#define REG_01_CFG_MODE_FS_LINES_TX (1 << 14) +#define REG_01_CFG_ENUM_MODE (1 << 15) + +// REG_02 +#define REG_02_CFG_TARGET_SYNC_TOUT_SHIFT 0 +#define REG_02_CFG_TARGET_SYNC_TOUT_MASK (0xF << REG_02_CFG_TARGET_SYNC_TOUT_SHIFT) +#define REG_02_CFG_TARGET_SYNC_TOUT(n) BITFIELD_VAL(REG_02_CFG_TARGET_SYNC_TOUT, n) +#define REG_02_CFG_SEL_SYNCPATTERN_SHIFT 4 +#define REG_02_CFG_SEL_SYNCPATTERN_MASK (0x3 << REG_02_CFG_SEL_SYNCPATTERN_SHIFT) +#define REG_02_CFG_SEL_SYNCPATTERN(n) BITFIELD_VAL(REG_02_CFG_SEL_SYNCPATTERN, n) +#define REG_02_CFG_BYPASS_SQL_VALID (1 << 6) +#define REG_02_CFG_EN_SYNCTOUT (1 << 7) +#define REG_02_CFG_FORCERX (1 << 8) +#define REG_02_CFG_RXRESET (1 << 9) +#define REG_02_CFG_EBUF_THRD_SHIFT 10 +#define REG_02_CFG_EBUF_THRD_MASK (0x1F << REG_02_CFG_EBUF_THRD_SHIFT) +#define REG_02_CFG_EBUF_THRD(n) BITFIELD_VAL(REG_02_CFG_EBUF_THRD, n) +#define REG_02_CFG_EOP_MODE_RX (1 << 15) + +// REG_03 +#define REG_03_CFG_TARGET_TAIL_SHIFT 0 +#define REG_03_CFG_TARGET_TAIL_MASK (0xFF << REG_03_CFG_TARGET_TAIL_SHIFT) +#define REG_03_CFG_TARGET_TAIL(n) BITFIELD_VAL(REG_03_CFG_TARGET_TAIL, n) +#define REG_03_CFG_TXPATTERN_SHIFT 8 +#define REG_03_CFG_TXPATTERN_MASK (0xFF << REG_03_CFG_TXPATTERN_SHIFT) +#define REG_03_CFG_TXPATTERN(n) BITFIELD_VAL(REG_03_CFG_TXPATTERN, n) + +// REG_04 +#define REG_04_CFG_EN_HSTSOF (1 << 0) +#define REG_04_CFG_FORCETX (1 << 1) +#define REG_04_CFG_MODE_BITEN (1 << 2) +#define REG_04_CFG_TXSTATE_RESET (1 << 3) +#define REG_04_CFG_EMPTY_DLY_SEL_SHIFT 4 +#define REG_04_CFG_EMPTY_DLY_SEL_MASK (0x7 << REG_04_CFG_EMPTY_DLY_SEL_SHIFT) +#define REG_04_CFG_EMPTY_DLY_SEL(n) BITFIELD_VAL(REG_04_CFG_EMPTY_DLY_SEL, n) +#define REG_04_RESERVED_0 (1 << 7) +#define REG_04_CFG_TP_SEL_SHIFT 8 +#define REG_04_CFG_TP_SEL_MASK (0xFF << REG_04_CFG_TP_SEL_SHIFT) +#define REG_04_CFG_TP_SEL(n) BITFIELD_VAL(REG_04_CFG_TP_SEL, n) + +// REG_05 +#define REG_05_CFG_ADP_PRB (1 << 0) +#define REG_05_CFG_ADP_SNS (1 << 1) +#define REG_05_CFG_RID_A (1 << 2) +#define REG_05_CFG_RID_B (1 << 3) +#define REG_05_CFG_RID_C (1 << 4) +#define REG_05_CFG_RID_FLOAT (1 << 5) +#define REG_05_CFG_RID_GND (1 << 6) +#define REG_05_CFG_UTMIOTG_AVALID (1 << 7) +#define REG_05_CFG_UTMISRP_BVALID (1 << 8) +#define REG_05_CFG_UTMIOTG_VBUSVALID (1 << 9) +#define REG_05_CFG_UTMISRP_SESSEND (1 << 10) +#define REG_05_RESERVED_5_1_SHIFT 11 +#define REG_05_RESERVED_5_1_MASK (0x1F << REG_05_RESERVED_5_1_SHIFT) +#define REG_05_RESERVED_5_1(n) BITFIELD_VAL(REG_05_RESERVED_5_1, n) + +// REG_06 +#define REG_06_CFG_HS_SRC_SEL (1 << 0) +#define REG_06_CFG_HS_TX_EN (1 << 1) +#define REG_06_CFG_CHIRP_EN (1 << 2) +#define REG_06_CFG_HS_MODE (1 << 3) +#define REG_06_CFG_EN_RHS (1 << 4) +#define REG_06_CFG_HS_DRV_SEL_SHIFT 5 +#define REG_06_CFG_HS_DRV_SEL_MASK (0xF << REG_06_CFG_HS_DRV_SEL_SHIFT) +#define REG_06_CFG_HS_DRV_SEL(n) BITFIELD_VAL(REG_06_CFG_HS_DRV_SEL, n) +#define REG_06_CFG_RHS_TRIM_SHIFT 9 +#define REG_06_CFG_RHS_TRIM_MASK (0xF << REG_06_CFG_RHS_TRIM_SHIFT) +#define REG_06_CFG_RHS_TRIM(n) BITFIELD_VAL(REG_06_CFG_RHS_TRIM, n) +#define REG_06_CFG_HS_RCV_PD (1 << 13) +#define REG_06_CFG_EN_HOLD_LAST (1 << 14) +#define REG_06_CFG_EN_HS_S2P (1 << 15) + +// REG_07 +#define REG_07_CFG_RST_INTP (1 << 0) +#define REG_07_CFG_EN_ZPS (1 << 1) +#define REG_07_CFG_RES_GN_SHIFT 2 +#define REG_07_CFG_RES_GN_MASK (0xF << REG_07_CFG_RES_GN_SHIFT) +#define REG_07_CFG_RES_GN(n) BITFIELD_VAL(REG_07_CFG_RES_GN, n) +#define REG_07_CFG_ISEL_RCV_SHIFT 6 +#define REG_07_CFG_ISEL_RCV_MASK (0x7 << REG_07_CFG_ISEL_RCV_SHIFT) +#define REG_07_CFG_ISEL_RCV(n) BITFIELD_VAL(REG_07_CFG_ISEL_RCV, n) +#define REG_07_CFG_ISEL_SQ_SHIFT 9 +#define REG_07_CFG_ISEL_SQ_MASK (0x7 << REG_07_CFG_ISEL_SQ_SHIFT) +#define REG_07_CFG_ISEL_SQ(n) BITFIELD_VAL(REG_07_CFG_ISEL_SQ, n) +#define REG_07_CFG_INT_FLT_SHIFT 12 +#define REG_07_CFG_INT_FLT_MASK (0x3 << REG_07_CFG_INT_FLT_SHIFT) +#define REG_07_CFG_INT_FLT(n) BITFIELD_VAL(REG_07_CFG_INT_FLT, n) +#define REG_07_CFG_PI_GN_SHIFT 14 +#define REG_07_CFG_PI_GN_MASK (0x3 << REG_07_CFG_PI_GN_SHIFT) +#define REG_07_CFG_PI_GN(n) BITFIELD_VAL(REG_07_CFG_PI_GN, n) + +// REG_08 +#define REG_08_CFG_CDR_GN_SHIFT 0 +#define REG_08_CFG_CDR_GN_MASK (0x3 << REG_08_CFG_CDR_GN_SHIFT) +#define REG_08_CFG_CDR_GN(n) BITFIELD_VAL(REG_08_CFG_CDR_GN, n) +#define REG_08_CFG_SEL_HS_GAIN (1 << 2) +#define REG_08_CFG_SEL_TERR (1 << 3) +#define REG_08_CFG_SEL_HS_LSTATE (1 << 4) +#define REG_08_CFG_LOOP_BACK (1 << 5) +#define REG_08_CFG_XCVR_SELECT (1 << 6) +#define REG_08_CFG_XTERM_SELECT (1 << 7) +#define REG_08_CFG_USPENDM (1 << 8) +#define REG_08_CFG_DISCON_DET_EN (1 << 9) +#define REG_08_CFG_DISCON_VTHSET_SHIFT 10 +#define REG_08_CFG_DISCON_VTHSET_MASK (0x7 << REG_08_CFG_DISCON_VTHSET_SHIFT) +#define REG_08_CFG_DISCON_VTHSET(n) BITFIELD_VAL(REG_08_CFG_DISCON_VTHSET, n) +#define REG_08_CFG_FS_TX_ON (1 << 13) +#define REG_08_CFG_FS_EN_RFS (1 << 14) +#define REG_08_CFG_FS_EN_R15K (1 << 15) + +// REG_09 +#define REG_09_CFG_LS_EN_RLS (1 << 0) +#define REG_09_CFG_LS_MODE (1 << 1) +#define REG_09_CFG_ATEST_EN_REG (1 << 2) +#define REG_09_CFG_ATEST_SELX_REG_SHIFT 3 +#define REG_09_CFG_ATEST_SELX_REG_MASK (0x3 << REG_09_CFG_ATEST_SELX_REG_SHIFT) +#define REG_09_CFG_ATEST_SELX_REG(n) BITFIELD_VAL(REG_09_CFG_ATEST_SELX_REG, n) +#define REG_09_CFG_DTESTEN1_REG (1 << 5) +#define REG_09_CFG_DTESTEN2_REG (1 << 6) +#define REG_09_CFG_DTEST_SEL_REG_SHIFT 7 +#define REG_09_CFG_DTEST_SEL_REG_MASK (0x3 << REG_09_CFG_DTEST_SEL_REG_SHIFT) +#define REG_09_CFG_DTEST_SEL_REG(n) BITFIELD_VAL(REG_09_CFG_DTEST_SEL_REG, n) +#define REG_09_CFG_ATEST_EN_DISCON_REG (1 << 9) +#define REG_09_CFG_ATEST_SELX_DISCON_REG (1 << 10) +#define REG_09_CFG_MODE_LINESTATE (1 << 11) +#define REG_09_RESERVED_8_6_SHIFT 12 +#define REG_09_RESERVED_8_6_MASK (0x7 << REG_09_RESERVED_8_6_SHIFT) +#define REG_09_RESERVED_8_6(n) BITFIELD_VAL(REG_09_RESERVED_8_6, n) +#define REG_09_CFG_BISTEN (1 << 15) + +// REG_0A +#define REG_0A_CFG_DR_HOSTMODE (1 << 0) +#define REG_0A_CFG_DR_FSLS_SEL (1 << 1) +#define REG_0A_CFG_DR_SDATA (1 << 2) +#define REG_0A_CFG_DR_TERMSEL (1 << 3) +#define REG_0A_CFG_DR_XCVRSEL (1 << 4) +#define REG_0A_CFG_DR_SON (1 << 5) +#define REG_0A_CFG_DR_OPMODE (1 << 6) +#define REG_0A_RESERVED_9 (1 << 7) +#define REG_0A_CFG_DR_HS_TXEN (1 << 8) +#define REG_0A_CFG_DR_FSTXEN (1 << 9) +#define REG_0A_CFG_DR_FSTXD (1 << 10) +#define REG_0A_CFG_DR_FSTXDB (1 << 11) +#define REG_0A_CFG_FS_LS_SEL (1 << 12) +#define REG_0A_CFG_CLK480M_EDGE_SEL (1 << 13) +#define REG_0A_RESERVED_13_10_SHIFT 12 +#define REG_0A_RESERVED_13_10_MASK (0xF << REG_0A_RESERVED_13_10_SHIFT) +#define REG_0A_RESERVED_13_10(n) BITFIELD_VAL(REG_0A_RESERVED_13_10, n) + +// REG_0B +#define REG_0B_CFG_REG_HOSTMODE (1 << 0) +#define REG_0B_CFG_REG_FSLS_SEL (1 << 1) +#define REG_0B_CFG_REG_SDATA (1 << 2) +#define REG_0B_CFG_REG_TERM (1 << 3) +#define REG_0B_CFG_REG_XCVRSEL (1 << 4) +#define REG_0B_CFG_REG_SON (1 << 5) +#define REG_0B_CFG_REG_OPMODE_SHIFT 6 +#define REG_0B_CFG_REG_OPMODE_MASK (0x3 << REG_0B_CFG_REG_OPMODE_SHIFT) +#define REG_0B_CFG_REG_OPMODE(n) BITFIELD_VAL(REG_0B_CFG_REG_OPMODE, n) +#define REG_0B_CFG_REG_HS_TXEN (1 << 8) +#define REG_0B_CFG_REG_FSTXEN (1 << 9) +#define REG_0B_CFG_REG_FSTXD (1 << 10) +#define REG_0B_CFG_REG_FSTXDB (1 << 11) +#define REG_0B_RESERVED_17_14_SHIFT 12 +#define REG_0B_RESERVED_17_14_MASK (0xF << REG_0B_RESERVED_17_14_SHIFT) +#define REG_0B_RESERVED_17_14(n) BITFIELD_VAL(REG_0B_RESERVED_17_14, n) + +// REG_0C +#define REG_0C_CFG_RXINTR_MSK_SHIFT 0 +#define REG_0C_CFG_RXINTR_MSK_MASK (0xFFFF << REG_0C_CFG_RXINTR_MSK_SHIFT) +#define REG_0C_CFG_RXINTR_MSK(n) BITFIELD_VAL(REG_0C_CFG_RXINTR_MSK, n) + +// REG_0D +#define REG_0D_CFG_HSHOST_DISC_MSK (1 << 0) +#define REG_0D_CFG_POL_CKSIE60 (1 << 1) +#define REG_0D_CFG_RESETN_HSTXP (1 << 2) +#define REG_0D_CFG_CKSIE60_EN (1 << 3) +#define REG_0D_CFG_TXP_MODE (1 << 4) +#define REG_0D_CFG_CKOSC_EN (1 << 5) +#define REG_0D_CFG_POL_OSC (1 << 6) +#define REG_0D_CFG_CKPRE_EN (1 << 7) +#define REG_0D_CFG_RX_P_SEL (1 << 8) +#define REG_0D_CFG_RERESTN_HSRXP (1 << 9) +#define REG_0D_CFG_POL_RXP (1 << 10) +#define REG_0D_CFG_CKRXP_EN (1 << 11) +#define REG_0D_CFG_PEBUF_THRD_SHIFT 12 +#define REG_0D_CFG_PEBUF_THRD_MASK (0xF << REG_0D_CFG_PEBUF_THRD_SHIFT) +#define REG_0D_CFG_PEBUF_THRD(n) BITFIELD_VAL(REG_0D_CFG_PEBUF_THRD, n) + +// REG_0E +#define REG_0E_RB_RXERRSTATUS_RAW_SHIFT 0 +#define REG_0E_RB_RXERRSTATUS_RAW_MASK (0xFFFF << REG_0E_RB_RXERRSTATUS_RAW_SHIFT) +#define REG_0E_RB_RXERRSTATUS_RAW(n) BITFIELD_VAL(REG_0E_RB_RXERRSTATUS_RAW, n) + +// REG_0F +#define REG_0F_RB_RXERRSTATUS_MSKD_SHIFT 0 +#define REG_0F_RB_RXERRSTATUS_MSKD_MASK (0xFFFF << REG_0F_RB_RXERRSTATUS_MSKD_SHIFT) +#define REG_0F_RB_RXERRSTATUS_MSKD(n) BITFIELD_VAL(REG_0F_RB_RXERRSTATUS_MSKD, n) + +// REG_10 +#define REG_10_RB_HSHOST_DISC_RAW (1 << 0) + +// REG_11 +#define REG_11_RB_HSHOST_DISC_MSKED (1 << 0) + +// REG_12 +#define REG_12_CFG_EN_SETERR_RX_SHIFT 0 +#define REG_12_CFG_EN_SETERR_RX_MASK (0xFFFF << REG_12_CFG_EN_SETERR_RX_SHIFT) +#define REG_12_CFG_EN_SETERR_RX(n) BITFIELD_VAL(REG_12_CFG_EN_SETERR_RX, n) + +// REG_13 +#define REG_13_CFG_TXSTART_DLY_SEL_SHIFT 0 +#define REG_13_CFG_TXSTART_DLY_SEL_MASK (0x7 << REG_13_CFG_TXSTART_DLY_SEL_SHIFT) +#define REG_13_CFG_TXSTART_DLY_SEL(n) BITFIELD_VAL(REG_13_CFG_TXSTART_DLY_SEL, n) +#define REG_13_RESERVED_38_26_SHIFT 3 +#define REG_13_RESERVED_38_26_MASK (0x1FFF << REG_13_RESERVED_38_26_SHIFT) +#define REG_13_RESERVED_38_26(n) BITFIELD_VAL(REG_13_RESERVED_38_26, n) + +// REG_14 +#define REG_14_CALIB_TIME_15_0_SHIFT 0 +#define REG_14_CALIB_TIME_15_0_MASK (0xFFFF << REG_14_CALIB_TIME_15_0_SHIFT) +#define REG_14_CALIB_TIME_15_0(n) BITFIELD_VAL(REG_14_CALIB_TIME_15_0, n) + +// REG_15 +#define REG_15_CALIB_TIME_19_16_SHIFT 0 +#define REG_15_CALIB_TIME_19_16_MASK (0xF << REG_15_CALIB_TIME_19_16_SHIFT) +#define REG_15_CALIB_TIME_19_16(n) BITFIELD_VAL(REG_15_CALIB_TIME_19_16, n) +#define REG_15_RESERVED_49_39_SHIFT 4 +#define REG_15_RESERVED_49_39_MASK (0x7FF << REG_15_RESERVED_49_39_SHIFT) +#define REG_15_RESERVED_49_39(n) BITFIELD_VAL(REG_15_RESERVED_49_39, n) +#define REG_15_CALIB_START (1 << 15) + +// REG_16 +#define REG_16_INTR_MASK_SHIFT 0 +#define REG_16_INTR_MASK_MASK (0x3 << REG_16_INTR_MASK_SHIFT) +#define REG_16_INTR_MASK(n) BITFIELD_VAL(REG_16_INTR_MASK, n) +#define REG_16_RESERVED_63_50_SHIFT 2 +#define REG_16_RESERVED_63_50_MASK (0x3FFF << REG_16_RESERVED_63_50_SHIFT) +#define REG_16_RESERVED_63_50(n) BITFIELD_VAL(REG_16_RESERVED_63_50, n) + +// REG_17 +#define REG_17_O_CNT_PLL_15_0_SHIFT 0 +#define REG_17_O_CNT_PLL_15_0_MASK (0xFFFF << REG_17_O_CNT_PLL_15_0_SHIFT) +#define REG_17_O_CNT_PLL_15_0(n) BITFIELD_VAL(REG_17_O_CNT_PLL_15_0, n) + +// REG_18 +#define REG_18_O_CNT_PLL_24_16_SHIFT 0 +#define REG_18_O_CNT_PLL_24_16_MASK (0x1FF << REG_18_O_CNT_PLL_24_16_SHIFT) +#define REG_18_O_CNT_PLL_24_16(n) BITFIELD_VAL(REG_18_O_CNT_PLL_24_16, n) + +// REG_19 +#define REG_19_O_INTR_STATUS_SHIFT 0 +#define REG_19_O_INTR_STATUS_MASK (0x3 << REG_19_O_INTR_STATUS_SHIFT) +#define REG_19_O_INTR_STATUS(n) BITFIELD_VAL(REG_19_O_INTR_STATUS, n) + +// REG_1A +#define REG_1A_HS_TEST (1 << 0) +#define REG_1A_FS_TEST (1 << 1) +#define REG_1A_USBINSERT_DET_EN (1 << 2) +#define REG_1A_USBINSERT_INTR_EN (1 << 3) +#define REG_1A_INTR_CLR (1 << 4) +#define REG_1A_POL_USB_RX_DP (1 << 5) +#define REG_1A_POL_USB_RX_DM (1 << 6) +#define REG_1A_DEBOUNCE_EN (1 << 7) +#define REG_1A_NOLS_MODE (1 << 8) +#define REG_1A_USB_INSERT_INTR_MSK (1 << 9) +#define REG_1A_PHY_TEST_GOON (1 << 10) + +// REG_1B +#define REG_1B_CFG_HS_PDATA_SHIFT 0 +#define REG_1B_CFG_HS_PDATA_MASK (0xFF << REG_1B_CFG_HS_PDATA_SHIFT) +#define REG_1B_CFG_HS_PDATA(n) BITFIELD_VAL(REG_1B_CFG_HS_PDATA, n) +#define REG_1B_CFG_HS_P_ON_SHIFT 8 +#define REG_1B_CFG_HS_P_ON_MASK (0xFF << REG_1B_CFG_HS_P_ON_SHIFT) +#define REG_1B_CFG_HS_P_ON(n) BITFIELD_VAL(REG_1B_CFG_HS_P_ON, n) + +// REG_20 +#define REG_20_RB_BISTERR_CAUSE_SHIFT 0 +#define REG_20_RB_BISTERR_CAUSE_MASK (0x7 << REG_20_RB_BISTERR_CAUSE_SHIFT) +#define REG_20_RB_BISTERR_CAUSE(n) BITFIELD_VAL(REG_20_RB_BISTERR_CAUSE, n) + +// REG_21 +#define REG_21_RB_BIST_FAIL (1 << 0) +#define REG_21_RB_BIST_DONE (1 << 1) +#define REG_21_RB_CHIRP_ON (1 << 2) +#define REG_21_RB_ADP_SNS_EN (1 << 3) +#define REG_21_RB_ADP_PRB_EN (1 << 4) +#define REG_21_RB_ADP_DISCHRG (1 << 5) +#define REG_21_RB_ADP_CHRG (1 << 6) +#define REG_21_RB_UTMISRP_DISCHRGVBUS (1 << 7) +#define REG_21_RB_UTMISRP_CHRGVBUS (1 << 8) +#define REG_21_RB_UTMIOTG_IDPULLUP (1 << 9) +#define REG_21_RB_UTMIOTG_DPPULLDOWN (1 << 10) +#define REG_21_RB_UTMIOTG_DMPULLDOWN (1 << 11) +#define REG_21_RB_UTMIOTG_DRVVBUS (1 << 12) + +// REG_22 +#define REG_22_CFG_RESETNTX (1 << 0) +#define REG_22_CFG_RESETNRX (1 << 1) +#define REG_22_CFG_CKTX_EN (1 << 2) +#define REG_22_CFG_CKRX_EN (1 << 3) +#define REG_22_CFG_FORCE_TXCK (1 << 4) +#define REG_22_CFG_FORCE_RXCK (1 << 5) +#define REG_22_CFG_FORCE_CDRCK (1 << 6) +#define REG_22_CFG_MODE_S_ON (1 << 7) +#define REG_22_CFG_RESETNFRE (1 << 8) +#define REG_22_CFG_RESETNOSC (1 << 9) +#define REG_22_CFG_DIG_LOOP (1 << 10) +#define REG_22_RESERVED_83_78_SHIFT 11 +#define REG_22_RESERVED_83_78_MASK (0x1F << REG_22_RESERVED_83_78_SHIFT) +#define REG_22_RESERVED_83_78(n) BITFIELD_VAL(REG_22_RESERVED_83_78, n) + +// REG_23 +#define REG_23_O_CNT_OSC_15_0_SHIFT 0 +#define REG_23_O_CNT_OSC_15_0_MASK (0xFFFF << REG_23_O_CNT_OSC_15_0_SHIFT) +#define REG_23_O_CNT_OSC_15_0(n) BITFIELD_VAL(REG_23_O_CNT_OSC_15_0, n) + +// REG_24 +#define REG_24_O_CNT_OSC_19_16_SHIFT 0 +#define REG_24_O_CNT_OSC_19_16_MASK (0x1F << REG_24_O_CNT_OSC_19_16_SHIFT) +#define REG_24_O_CNT_OSC_19_16(n) BITFIELD_VAL(REG_24_O_CNT_OSC_19_16, n) + +// REG_25 +#define REG_25_USB_STATUS_RX_DP (1 << 0) +#define REG_25_USB_STATUS_RX_DM (1 << 1) + +// REG_30 +#define REG_30_REV_REG30_SHIFT 0 +#define REG_30_REV_REG30_MASK (0xFFFF << REG_30_REV_REG30_SHIFT) +#define REG_30_REV_REG30(n) BITFIELD_VAL(REG_30_REV_REG30, n) + +// REG_31 +#define REG_31_REV_REG31_SHIFT 0 +#define REG_31_REV_REG31_MASK (0xFFFF << REG_31_REV_REG31_SHIFT) +#define REG_31_REV_REG31(n) BITFIELD_VAL(REG_31_REV_REG31, n) + +// REG_32 +#define REG_32_REV_REG32_SHIFT 0 +#define REG_32_REV_REG32_MASK (0xFFFF << REG_32_REV_REG32_SHIFT) +#define REG_32_REV_REG32(n) BITFIELD_VAL(REG_32_REV_REG32, n) + +// REG_33 +#define REG_33_CFG_ANA_REV_SHIFT 0 +#define REG_33_CFG_ANA_REV_MASK (0xFFFF << REG_33_CFG_ANA_REV_SHIFT) +#define REG_33_CFG_ANA_REV(n) BITFIELD_VAL(REG_33_CFG_ANA_REV, n) + +// REG_61 +#define REG_61_USB_LDO_VOUT_SET_SHIFT 0 +#define REG_61_USB_LDO_VOUT_SET_MASK (0xF << REG_61_USB_LDO_VOUT_SET_SHIFT) +#define REG_61_USB_LDO_VOUT_SET(n) BITFIELD_VAL(REG_61_USB_LDO_VOUT_SET, n) +#define REG_61_USB_LDO_OCP (1 << 4) +#define REG_61_USB_LDO_SOFT_START (1 << 5) +#define REG_61_USB_LDO_PULL_DOWN (1 << 6) +#define REG_61_USB_LDO_BYPASS (1 << 7) +#define REG_61_USB_LDO_EN (1 << 8) +#define REG_61_USB_LDO_SOFT_CNT_SHIFT 9 +#define REG_61_USB_LDO_SOFT_CNT_MASK (0xF << REG_61_USB_LDO_SOFT_CNT_SHIFT) +#define REG_61_USB_LDO_SOFT_CNT(n) BITFIELD_VAL(REG_61_USB_LDO_SOFT_CNT, n) + +// REG_62 +#define REG_62_PLL_LDO_PU (1 << 0) +#define REG_62_PLL_LDO_VREF_SHIFT 1 +#define REG_62_PLL_LDO_VREF_MASK (0x7 << REG_62_PLL_LDO_VREF_SHIFT) +#define REG_62_PLL_LDO_VREF(n) BITFIELD_VAL(REG_62_PLL_LDO_VREF, n) +#define REG_62_PLL_LDO_PRECHARGE (1 << 4) +#define REG_62_PLL_PFD_DNDLY_SHIFT 5 +#define REG_62_PLL_PFD_DNDLY_MASK (0x7 << REG_62_PLL_PFD_DNDLY_SHIFT) +#define REG_62_PLL_PFD_DNDLY(n) BITFIELD_VAL(REG_62_PLL_PFD_DNDLY, n) +#define REG_62_PLL_PFD_RST (1 << 8) +#define REG_62_PLL_PFD_UPDLY_SHIFT 9 +#define REG_62_PLL_PFD_UPDLY_MASK (0x7 << REG_62_PLL_PFD_UPDLY_SHIFT) +#define REG_62_PLL_PFD_UPDLY(n) BITFIELD_VAL(REG_62_PLL_PFD_UPDLY, n) +#define REG_62_PLL_LPF_BW_SEL (1 << 12) +#define REG_62_PLL_UP_CP (1 << 13) + +// REG_63 +#define REG_63_PLL_CP_REN_SHIFT 0 +#define REG_63_PLL_CP_REN_MASK (0xF << REG_63_PLL_CP_REN_SHIFT) +#define REG_63_PLL_CP_REN(n) BITFIELD_VAL(REG_63_PLL_CP_REN, n) +#define REG_63_PLL_CP_SWRC_SHIFT 4 +#define REG_63_PLL_CP_SWRC_MASK (0x3 << REG_63_PLL_CP_SWRC_SHIFT) +#define REG_63_PLL_CP_SWRC(n) BITFIELD_VAL(REG_63_PLL_CP_SWRC, n) +#define REG_63_PLL_PRECHARGE (1 << 6) +#define REG_63_PLL_PU_VCO (1 << 7) +#define REG_63_PLL_VAA_SWRA_SHIFT 8 +#define REG_63_PLL_VAA_SWRA_MASK (0x3 << REG_63_PLL_VAA_SWRA_SHIFT) +#define REG_63_PLL_VAA_SWRA(n) BITFIELD_VAL(REG_63_PLL_VAA_SWRA, n) +#define REG_63_PLL_VAA_SPD_SHIFT 10 +#define REG_63_PLL_VAA_SPD_MASK (0x7 << REG_63_PLL_VAA_SPD_SHIFT) +#define REG_63_PLL_VAA_SPD(n) BITFIELD_VAL(REG_63_PLL_VAA_SPD, n) +#define REG_63_PLL_PU_DIG (1 << 13) +#define REG_63_PLL_SDM_CLK_SET (1 << 14) +#define REG_63_PLL_TST_EN (1 << 15) + +// REG_64 +#define REG_64_PLL_DIG_SWRC_SHIFT 0 +#define REG_64_PLL_DIG_SWRC_MASK (0x3 << REG_64_PLL_DIG_SWRC_SHIFT) +#define REG_64_PLL_DIG_SWRC(n) BITFIELD_VAL(REG_64_PLL_DIG_SWRC, n) +#define REG_64_PLL_DIV_DELAY_SHIFT 2 +#define REG_64_PLL_DIV_DELAY_MASK (0xF << REG_64_PLL_DIV_DELAY_SHIFT) +#define REG_64_PLL_DIV_DELAY(n) BITFIELD_VAL(REG_64_PLL_DIV_DELAY, n) +#define REG_64_PLL_DIV_FREE_SHIFT 6 +#define REG_64_PLL_DIV_FREE_MASK (0x3 << REG_64_PLL_DIV_FREE_SHIFT) +#define REG_64_PLL_DIV_FREE(n) BITFIELD_VAL(REG_64_PLL_DIV_FREE, n) +#define REG_64_PLL_DIV_INT_SHIFT 8 +#define REG_64_PLL_DIV_INT_MASK (0x7F << REG_64_PLL_DIV_INT_SHIFT) +#define REG_64_PLL_DIV_INT(n) BITFIELD_VAL(REG_64_PLL_DIV_INT, n) + +// REG_65 +#define REG_65_PLL_DIV_SET_SYNCLK_SHIFT 0 +#define REG_65_PLL_DIV_SET_SYNCLK_MASK (0x7 << REG_65_PLL_DIV_SET_SYNCLK_SHIFT) +#define REG_65_PLL_DIV_SET_SYNCLK(n) BITFIELD_VAL(REG_65_PLL_DIV_SET_SYNCLK, n) +#define REG_65_PLL_CAL_EN (1 << 3) +#define REG_65_PLL_RETB (1 << 4) +#define REG_65_PLL_FORCE_1K (1 << 5) +#define REG_65_PLL_1K_ERR23 (1 << 6) +#define REG_65_PLL_1K_LONG (1 << 7) +#define REG_65_PLL_1K_RSTB (1 << 8) +#define REG_65_PLL_1K_WIN_SHIFT 9 +#define REG_65_PLL_1K_WIN_MASK (0x7 << REG_65_PLL_1K_WIN_SHIFT) +#define REG_65_PLL_1K_WIN(n) BITFIELD_VAL(REG_65_PLL_1K_WIN, n) + +// REG_66 +#define REG_66_REG_USBPLL_RSTN_DR (1 << 0) +#define REG_66_REG_USBPLL_RSTN (1 << 1) +#define REG_66_REG_USBPLL_CLK_FBC_EDGE (1 << 2) +#define REG_66_REG_USBPLL_INT_DEC_SEL_SHIFT 3 +#define REG_66_REG_USBPLL_INT_DEC_SEL_MASK (0x7 << REG_66_REG_USBPLL_INT_DEC_SEL_SHIFT) +#define REG_66_REG_USBPLL_INT_DEC_SEL(n) BITFIELD_VAL(REG_66_REG_USBPLL_INT_DEC_SEL, n) +#define REG_66_REG_USBPLL_DITHER_BYPASS (1 << 6) +#define REG_66_REG_USBPLL_PRESCALER_DEL_SEL_SHIFT 7 +#define REG_66_REG_USBPLL_PRESCALER_DEL_SEL_MASK (0xF << REG_66_REG_USBPLL_PRESCALER_DEL_SEL_SHIFT) +#define REG_66_REG_USBPLL_PRESCALER_DEL_SEL(n) BITFIELD_VAL(REG_66_REG_USBPLL_PRESCALER_DEL_SEL, n) +#define REG_66_REG_USBPLL_PU_PLL_DR (1 << 11) +#define REG_66_REG_USBPLL_PU_PLL (1 << 12) + +// REG_67 +#define REG_67_REG_USBPLL_DIV_DR (1 << 0) +#define REG_67_REG_USBPLL_DIV_FRAC_SHIFT 1 +#define REG_67_REG_USBPLL_DIV_FRAC_MASK (0x3 << REG_67_REG_USBPLL_DIV_FRAC_SHIFT) +#define REG_67_REG_USBPLL_DIV_FRAC(n) BITFIELD_VAL(REG_67_REG_USBPLL_DIV_FRAC, n) +#define REG_67_REG_USBPLL_DIV_INT_SHIFT 3 +#define REG_67_REG_USBPLL_DIV_INT_MASK (0x7F << REG_67_REG_USBPLL_DIV_INT_SHIFT) +#define REG_67_REG_USBPLL_DIV_INT(n) BITFIELD_VAL(REG_67_REG_USBPLL_DIV_INT, n) + +// REG_6A +#define REG_6A_REG_USBPLL_FREQ_EN (1 << 3) +#define REG_6A_EN960M_USB (1 << 5) +#define REG_6A_ENUSB_DIG (1 << 6) +#define REG_6A_ENUSB_PS (1 << 7) + +// REG_6B +#define REG_6B_REG_USBPLL_FREQ_OFFSET_SHIFT 0 +#define REG_6B_REG_USBPLL_FREQ_OFFSET_MASK (0x1FFFF << REG_6B_REG_USBPLL_FREQ_OFFSET_SHIFT) +#define REG_6B_REG_USBPLL_FREQ_OFFSET(n) BITFIELD_VAL(REG_6B_REG_USBPLL_FREQ_OFFSET, n) + +// REG_6C +#define REG_6C_CHIP_ADDR_I2C_SHIFT 0 +#define REG_6C_CHIP_ADDR_I2C_MASK (0x7F << REG_6C_CHIP_ADDR_I2C_SHIFT) +#define REG_6C_CHIP_ADDR_I2C(n) BITFIELD_VAL(REG_6C_CHIP_ADDR_I2C, n) + +// REG_6D +#define REG_6D_REG_USBPLL_LDOPRECHG_TIMER_SHIFT 0 +#define REG_6D_REG_USBPLL_LDOPRECHG_TIMER_MASK (0x1F << REG_6D_REG_USBPLL_LDOPRECHG_TIMER_SHIFT) +#define REG_6D_REG_USBPLL_LDOPRECHG_TIMER(n) BITFIELD_VAL(REG_6D_REG_USBPLL_LDOPRECHG_TIMER, n) +#define REG_6D_REG_USBPLL_PRECHG_TIMER_SHIFT 5 +#define REG_6D_REG_USBPLL_PRECHG_TIMER_MASK (0x1F << REG_6D_REG_USBPLL_PRECHG_TIMER_SHIFT) +#define REG_6D_REG_USBPLL_PRECHG_TIMER(n) BITFIELD_VAL(REG_6D_REG_USBPLL_PRECHG_TIMER, n) +#define REG_6D_REG_USBPLL_UP_TIMER_PD_SHIFT 10 +#define REG_6D_REG_USBPLL_UP_TIMER_PD_MASK (0x1F << REG_6D_REG_USBPLL_UP_TIMER_PD_SHIFT) +#define REG_6D_REG_USBPLL_UP_TIMER_PD(n) BITFIELD_VAL(REG_6D_REG_USBPLL_UP_TIMER_PD, n) + +enum USBPHY_REG_T { + USBPHY_REG_00 = 0x00, + USBPHY_REG_01, + USBPHY_REG_02, + USBPHY_REG_03, + USBPHY_REG_04, + USBPHY_REG_05, + USBPHY_REG_06, + USBPHY_REG_07, + USBPHY_REG_08, + USBPHY_REG_09, + USBPHY_REG_0A, + USBPHY_REG_0B, + USBPHY_REG_0C, + USBPHY_REG_0D, + USBPHY_REG_0E, + USBPHY_REG_0F, + USBPHY_REG_10, + USBPHY_REG_11, + USBPHY_REG_12, + USBPHY_REG_13, + USBPHY_REG_14, + USBPHY_REG_15, + USBPHY_REG_16, + USBPHY_REG_17, + USBPHY_REG_18, + USBPHY_REG_19, + USBPHY_REG_1A, + USBPHY_REG_1B, + + USBPHY_REG_20 = 0x20, + USBPHY_REG_21, + USBPHY_REG_22, + USBPHY_REG_23, + USBPHY_REG_24, + USBPHY_REG_25, + + USBPHY_REG_30 = 0x30, + USBPHY_REG_31, + USBPHY_REG_32, + + USBPHY_REG_61 = 0x61, + USBPHY_REG_62, + USBPHY_REG_63, + USBPHY_REG_64, + USBPHY_REG_65, + USBPHY_REG_66, + USBPHY_REG_67, + USBPHY_REG_68, + USBPHY_REG_69, + USBPHY_REG_6A, + USBPHY_REG_6B, + USBPHY_REG_6C, + USBPHY_REG_6D, +}; + +#endif + diff --git a/platform/drivers/ana/best2300p/usbphy_best2300p.c b/platform/drivers/ana/best2300p/usbphy_best2300p.c new file mode 100644 index 0000000..1975859 --- /dev/null +++ b/platform/drivers/ana/best2300p/usbphy_best2300p.c @@ -0,0 +1,410 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "usbphy.h" +#include "cmsis_nvic.h" +#include "hal_cmu.h" +#include "hal_phyif.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "pmu.h" +#include CHIP_SPECIFIC_HDR(reg_usbphy) + +#ifdef CHIP_HAS_SPIPHY + +//#define USBPHY_SERIAL_ITF + +void usbphy_ldo_config(int enable) +{ + int ret; + uint16_t val; + + ret = hal_phyif_open(SPIPHY_USB_CS); + if (ret) { + hal_phyif_close(SPIPHY_USB_CS); + return; + } + + if (enable) { +#ifdef USB_HIGH_SPEED + // USB ldo voltage should match with vcore (now 0.9V) + usbphy_write(0x61, 0x1118); +#else + usbphy_write(0x61, 0x1116); +#endif + usbphy_write(0x62, 0x2229); + usbphy_write(0x63, 0x0D82); + + hal_sys_timer_delay(MS_TO_TICKS(1)); + } else { + usbphy_write(0x63, 0x0000); + usbphy_write(0x62, 0x0000); + + usbphy_read(0x61, &val); + val &= (0x1 << 8); + usbphy_write(0x61, val); + + hal_sys_timer_delay(2); + hal_phyif_close(SPIPHY_USB_CS); + } +} + +void usbphy_open(void) +{ + unsigned short val_01, val; + +#ifdef USB_HIGH_SPEED + + usbphy_read(0x01, &val_01); + val_01 &= ~((1 << 0) | (1 << 11)); + usbphy_write(0x01, val_01); + val_01 |= (1 << 1) | (1 << 2) | (1 << 3) | (1 << 13); +#ifdef USBPHY_SERIAL_ITF + // cdr_clk polariy=1 + val_01 |= (1 << 4); +#else + // cdr_clk polariy=0 + val_01 &= ~(1 << 4); +#endif + usbphy_write(0x01, val_01); + + usbphy_read(0x02, &val); + val = (val & ~(0x1F << 10)) | (0xC << 10); + usbphy_write(0x02, val); + + usbphy_read(0x05, &val); + val |= (1 << 8); + usbphy_write(0x05, val); + +#ifdef USBPHY_SERIAL_ITF + usbphy_write(0x06, 0x4EE9); +#else + usbphy_write(0x06, 0xCEE8); +#endif + + usbphy_write(0x07, 0x9813); + + usbphy_read(0x08, &val); + usbphy_write(0x08, val); + + usbphy_read(0x09, &val); + usbphy_write(0x09, val); + +#ifdef USBPHY_SERIAL_ITF + usbphy_write(0x0D, 0x2B1E); +#else + usbphy_write(0x0D, 0x2A1E); +#endif + + // Disable force clocks, and disable hs son signal + usbphy_write(0x22, 0x030F); + + // Ignore all UTMI errors + usbphy_write(0x12, 0x0003); + + hal_sys_timer_delay(MS_TO_TICKS(1)); + + val_01 |= (1 << 0); + usbphy_write(0x01, val_01); + +#ifdef USB_HS_LOOPBACK_TEST + usbphy_read(0x0A, &val); + val |= (1 << 3) | (1 << 4) | (1 << 6); + usbphy_write(0x0A, val); + usbphy_read(0x0B, &val); + val &= ~((1 << 3) | (1 << 4) | (3 << 6)); + usbphy_write(0x0B, val); + usbphy_read(0x09, &val); + usbphy_write(0x09, val); + usbphy_read(0x06, &val); + usbphy_write(0x06, val); + + hal_sys_timer_delay(MS_TO_TICKS(1)); + +#define LOOPBACK_PATTERN (*(volatile uint8_t *)0x20000004) + + LOOPBACK_PATTERN = 0; + uint8_t pattern = LOOPBACK_PATTERN; + + // Set tx pattern + usbphy_read(0x03, &val); + val = (val & ~(0xFF << 8)) | (pattern << 8); + usbphy_write(0x03, val); + + // Enable force clocks + usbphy_read(0x22, &val); + val |= (1 << 4) | (1 << 5) | (1 << 6); + usbphy_write(0x22, val); + + // Enable tx + usbphy_read(0x04, &val); + val |= (1 << 1); + usbphy_write(0x04, val); + + // Update tx pattern + while (1) { + if (pattern != LOOPBACK_PATTERN) { + pattern = LOOPBACK_PATTERN; + usbphy_read(0x03, &val); + val = (val & ~(0xFF << 8)) | (pattern << 8); + usbphy_write(0x03, val); + } + } +#endif + +#else // !USB_HIGH_SPEED + + usbphy_read(0x01, &val_01); + val_01 &= ~(1 << 0); + usbphy_write(0x01, val_01); + val_01 |= (1 << 3); + usbphy_write(0x01, val_01); + +#ifdef USB_USE_USBPLL + val_01 |= (1 << 2) | (1 << 12); + usbphy_write(0x01, val_01); + + usbphy_read(0x33, &val); + val |= (1 << 0); + usbphy_write(0x33, val); +#endif + + val = 0; + usbphy_write(0x06, val); + + usbphy_read(0x07, &val); + usbphy_write(0x07, val); + + val = 0; + usbphy_write(0x08, val); + + val = 0; + usbphy_write(0x09, val); + + val_01 |= (1 << 0); + usbphy_write(0x01, val_01); + +#endif // USB_HIGH_SPEED + +} + +void usbphy_close(void) +{ +} + +void usbphy_sleep(void) +{ + uint16_t val; + + usbphy_read(0x01, &val); +#ifdef USB_HIGH_SPEED + val &= ~((1 << 1) | (1 << 2) | (1 << 3)); +#elif defined(USB_USE_USBPLL) + val &= ~((1 << 2) | (1 << 3)); +#else + val &= ~(1 << 3); +#endif + usbphy_write(0x01, val); + +#if !defined(USB_HIGH_SPEED) && defined(USB_USE_USBPLL) + usbphy_read(0x33, &val); + val &= ~(1 << 0); + usbphy_write(0x33, val); +#endif + + usbphy_write(0x62, 0x0000); + usbphy_write(0x63, 0x0000); +} + +void usbphy_wakeup(void) +{ + uint16_t val; + + usbphy_write(0x62, 0x2229); + usbphy_write(0x63, 0x0D82); + +#if !defined(USB_HIGH_SPEED) && defined(USB_USE_USBPLL) + usbphy_read(0x33, &val); + val |= (1 << 0); + usbphy_write(0x33, val); +#endif + + usbphy_read(0x01, &val); +#ifdef USB_HIGH_SPEED + val |= (1 << 1) | (1 << 2) | (1 << 3); +#elif defined(USB_USE_USBPLL) + val |= (1 << 2) | (1 << 3); +#else + val |= (1 << 3); +#endif + usbphy_write(0x01, val); +} + +//============================================================================================ +// USB Pin Status Check +//============================================================================================ + +static enum PMU_USB_PIN_CHK_STATUS_T usb_pin_status; + +static PMU_USB_PIN_CHK_CALLBACK usb_pin_callback; + +static int pmu_usb_check_pin_status(enum PMU_USB_PIN_CHK_STATUS_T status) +{ + int dp, dm; + + pmu_usb_get_pin_status(&dp, &dm); + + //TRACE(5,"[%X] %s: status=%d dp=%d dm=%d", hal_sys_timer_get(), __FUNCTION__, status, dp, dm); + + // HOST_RESUME: (resume) dp == 0 && dm == 1, (reset) dp == 0 && dm == 0 + + if ( (status == PMU_USB_PIN_CHK_DEV_CONN && (dp == 1 && dm == 0)) || + (status == PMU_USB_PIN_CHK_DEV_DISCONN && (dp == 0 && dm == 0)) || + (status == PMU_USB_PIN_CHK_HOST_RESUME && dp == 0) ) { + return 1; + } + + return 0; +} + +static void pmu_usb_pin_irq_handler(void) +{ + uint16_t val; + uint32_t lock; + + //TRACE(2,"[%X] %s", hal_sys_timer_get(), __FUNCTION__); + + lock = int_lock(); + usbphy_read(USBPHY_REG_1A, &val); + val |= REG_1A_INTR_CLR; + usbphy_write(USBPHY_REG_1A, val); + int_unlock(lock); + + if (usb_pin_callback) { + if (pmu_usb_check_pin_status(usb_pin_status)) { + pmu_usb_disable_pin_status_check(); + usb_pin_callback(usb_pin_status); + } + } +} + +int pmu_usb_config_pin_status_check(enum PMU_USB_PIN_CHK_STATUS_T status, PMU_USB_PIN_CHK_CALLBACK callback, int enable) +{ + uint16_t val; + uint32_t lock; + + //TRACE(3,"[%X] %s: status=%d", hal_sys_timer_get(), __FUNCTION__, status); + + if (status >= PMU_USB_PIN_CHK_STATUS_QTY) { + return 1; + } + + NVIC_DisableIRQ(USB_PIN_IRQn); + + lock = int_lock(); + + usb_pin_status = status; + usb_pin_callback = callback; + + usbphy_read(USBPHY_REG_1A, &val); + + // Mask the irq + val &= ~REG_1A_USB_INSERT_INTR_MSK; + + // Config pin check + val |= REG_1A_DEBOUNCE_EN | REG_1A_NOLS_MODE | REG_1A_USBINSERT_DET_EN; + + val &= ~(REG_1A_POL_USB_RX_DP | REG_1A_POL_USB_RX_DM); + if (status == PMU_USB_PIN_CHK_DEV_CONN) { + // Check dp 0->1, dm x->0 + } else if (status == PMU_USB_PIN_CHK_DEV_DISCONN) { + // Check dp 1->0, dm x->0 + val |= REG_1A_POL_USB_RX_DP; + } else if (status == PMU_USB_PIN_CHK_HOST_RESUME) { + // Check dp 1->0, dm 0->1 (resume) or dm 0->0 (reset) + val |= REG_1A_POL_USB_RX_DP; + } + + if (status != PMU_USB_PIN_CHK_NONE && callback) { + val |= REG_1A_USBINSERT_INTR_EN | REG_1A_USB_INSERT_INTR_MSK | REG_1A_INTR_CLR; + } + + usbphy_write(USBPHY_REG_1A, val); + + int_unlock(lock); + + if (enable) { + // Wait at least 10 cycles of 32K clock for the new status when signal checking polarity is changed + hal_sys_timer_delay(5); + pmu_usb_enable_pin_status_check(); + } + + return 0; +} + +void pmu_usb_enable_pin_status_check(void) +{ + uint16_t val; + uint32_t lock; + + if (usb_pin_status != PMU_USB_PIN_CHK_NONE && usb_pin_callback) { + lock = int_lock(); + usbphy_read(USBPHY_REG_1A, &val); + val |= REG_1A_INTR_CLR; + usbphy_write(USBPHY_REG_1A, val); + int_unlock(lock); + NVIC_ClearPendingIRQ(USB_PIN_IRQn); + + if (pmu_usb_check_pin_status(usb_pin_status)) { + pmu_usb_disable_pin_status_check(); + usb_pin_callback(usb_pin_status); + return; + } + + NVIC_SetVector(USB_PIN_IRQn, (uint32_t)pmu_usb_pin_irq_handler); + NVIC_SetPriority(USB_PIN_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_EnableIRQ(USB_PIN_IRQn); + } +} + +void pmu_usb_disable_pin_status_check(void) +{ + uint16_t val; + uint32_t lock; + + NVIC_DisableIRQ(USB_PIN_IRQn); + + lock = int_lock(); + + usbphy_read(USBPHY_REG_1A, &val); + val &= ~(REG_1A_USBINSERT_INTR_EN | REG_1A_USBINSERT_DET_EN); + usbphy_write(USBPHY_REG_1A, val); + + int_unlock(lock); +} + +void pmu_usb_get_pin_status(int *dp, int *dm) +{ + uint16_t pol, val; + + usbphy_read(USBPHY_REG_1A, &pol); + usbphy_read(USBPHY_REG_25, &val); + + *dp = (!(pol & REG_1A_POL_USB_RX_DP)) ^ (!(val & REG_25_USB_STATUS_RX_DP)); + *dm = (!(pol & REG_1A_POL_USB_RX_DM)) ^ (!(val & REG_25_USB_STATUS_RX_DM)); +} + +#endif + diff --git a/platform/drivers/ana/best2300p/usbphy_best2300p.h b/platform/drivers/ana/best2300p/usbphy_best2300p.h new file mode 100644 index 0000000..aadcf50 --- /dev/null +++ b/platform/drivers/ana/best2300p/usbphy_best2300p.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __USBPHY_BEST2300P_H__ +#define __USBPHY_BEST2300P_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPIPHY_USB_CS 0 + +#define SPIPHY_USB_REG(reg) (((reg) & 0xFFF) | (SPIPHY_USB_CS << 12)) + +void usbphy_ldo_config(int enable); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/ana/pmu.h b/platform/drivers/ana/pmu.h new file mode 100644 index 0000000..af48ab8 --- /dev/null +++ b/platform/drivers/ana/pmu.h @@ -0,0 +1,259 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __PMU_H__ +#define __PMU_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "hal_analogif.h" +#include "hal_cmu.h" +#include "hal_gpio.h" +#include "plat_addr_map.h" +#include CHIP_SPECIFIC_HDR(pmu) + +#define PMU_DEBUG_TRACE(n, s, ...) LOG_DUMMY(n, s, ##__VA_ARGS__) +#define PMU_DEBUG_TRACE_IMM(n, s, ...) LOG_INFO((n) | LOG_ATTR_IMM, s, ##__VA_ARGS__) +#define PMU_INFO_TRACE_IMM(n, s, ...) LOG_INFO((n) | LOG_ATTR_IMM, s, ##__VA_ARGS__) +#define PMU_INFO_TRACE(n, s, ...) LOG_INFO(n, s, ##__VA_ARGS__) + +#ifndef ISPI_PMU_REG +#define ISPI_PMU_REG(reg) (reg) +#endif +#define pmu_read(reg, val) hal_analogif_reg_read(ISPI_PMU_REG(reg), val) +#define pmu_write(reg, val) hal_analogif_reg_write(ISPI_PMU_REG(reg), val) + +#define PMU_MANUAL_MODE 1 +#define PMU_AUTO_MODE 0 +#define PMU_LDO_ON 1 +#define PMU_LDO_OFF 0 +#define PMU_LP_MODE_ON 1 +#define PMU_LP_MODE_OFF 0 +#define PMU_DSLEEP_MODE_ON 1 +#define PMU_DSLEEP_MODE_OFF 0 + +union SECURITY_VALUE_T { + struct { + unsigned short security_en :1; + unsigned short key_id :3; + unsigned short key_chksum :2; + unsigned short vendor_id :6; + unsigned short vendor_chksum :3; + unsigned short chksum :1; + }; + unsigned short reg; +}; + +enum PMU_CHARGER_STATUS_T { + PMU_CHARGER_PLUGIN, + PMU_CHARGER_PLUGOUT, + PMU_CHARGER_UNKNOWN, +}; + +enum PMU_POWER_ON_CAUSE_T { + PMU_POWER_ON_CAUSE_NONE, + PMU_POWER_ON_CAUSE_POWER_KEY, + PMU_POWER_ON_CAUSE_RTC, + PMU_POWER_ON_CAUSE_CHARGER_ACON, + PMU_POWER_ON_CAUSE_CHARGER_ACOFF, +}; + +enum PMU_USB_PIN_CHK_STATUS_T { + PMU_USB_PIN_CHK_NONE, + // Chip acts as host + PMU_USB_PIN_CHK_DEV_CONN, + // Chip acts as host + PMU_USB_PIN_CHK_DEV_DISCONN, + // Chip acts as device + PMU_USB_PIN_CHK_HOST_RESUME, + + PMU_USB_PIN_CHK_STATUS_QTY +}; + +enum PMU_USB_CONFIG_TYPE_T { + PMU_USB_CONFIG_TYPE_NONE, + PMU_USB_CONFIG_TYPE_DEVICE, + PMU_USB_CONFIG_TYPE_HOST, +}; + +enum PMU_POWER_MODE_T { + PMU_POWER_MODE_NONE, + PMU_POWER_MODE_LDO, + PMU_POWER_MODE_ANA_DCDC, + PMU_POWER_MODE_DIG_DCDC, +}; + +enum PMU_VIORISE_REQ_USER_T { + PMU_VIORISE_REQ_USER_PWL0, + PMU_VIORISE_REQ_USER_PWL1, + PMU_VIORISE_REQ_USER_FLASH, + PMU_VIORISE_REQ_USER_CHARGER, + + PMU_VIORISE_REQ_USER_QTY +}; + +struct PMU_LED_BR_CFG_T { + uint16_t off_time_ms; + uint16_t on_time_ms; + uint16_t fade_time_ms; +}; + +typedef void (*PMU_USB_PIN_CHK_CALLBACK)(enum PMU_USB_PIN_CHK_STATUS_T status); + +typedef void (*PMU_RTC_IRQ_HANDLER_T)(uint32_t seconds); + +typedef void (*PMU_CHARGER_IRQ_HANDLER_T)(enum PMU_CHARGER_STATUS_T status); + +typedef void (*PMU_WDT_IRQ_HANDLER_T)(void); + +typedef void (*PMU_IRQ_UNIFIED_HANDLER_T)(uint16_t irq_status); + +int pmu_open(void); + +void pmu_sleep(void); + +void pmu_wakeup(void); + +void pmu_mode_change(enum PMU_POWER_MODE_T mode); + +int pmu_get_security_value(union SECURITY_VALUE_T *val); + +void pmu_shutdown(void); + +void pmu_reset(void); + +int pmu_get_efuse(enum PMU_EFUSE_PAGE_T page, unsigned short *efuse); + +void pmu_codec_config(int enable); + +void pmu_anc_config(int enable); + +void pmu_usb_config(enum PMU_USB_CONFIG_TYPE_T type); + +void pmu_sleep_en(unsigned char sleep_en); + +void pmu_flash_write_config(void); + +void pmu_flash_read_config(void); + +void pmu_flash_freq_config(uint32_t freq); + +void pmu_psram_freq_config(uint32_t freq); + +void pmu_fir_high_speed_config(int enable); + +void pmu_iir_freq_config(uint32_t freq); + +void pmu_rs_freq_config(uint32_t freq); + +void pmu_sys_freq_config(enum HAL_CMU_FREQ_T freq); + +void pmu_high_performance_mode_enable(bool enable); + +void pmu_charger_init(void); + +void pmu_charger_set_irq_handler(PMU_CHARGER_IRQ_HANDLER_T handler); + +void pmu_charger_plugin_config(void); + +void pmu_charger_plugout_config(void); + +enum PMU_CHARGER_STATUS_T pmu_charger_get_status(void); + +int pmu_usb_config_pin_status_check(enum PMU_USB_PIN_CHK_STATUS_T status, PMU_USB_PIN_CHK_CALLBACK callback, int enable); + +void pmu_usb_enable_pin_status_check(void); + +void pmu_usb_disable_pin_status_check(void); + +void pmu_usb_get_pin_status(int *dp, int *dm); + +void pmu_rtc_enable(void); + +void pmu_rtc_disable(void); + +int pmu_rtc_enabled(void); + +void pmu_rtc_set(uint32_t seconds); + +uint32_t pmu_rtc_get(void); + +void pmu_rtc_set_alarm(uint32_t seconds); + +uint32_t pmu_rtc_get_alarm(void); + +void pmu_rtc_clear_alarm(void); + +int pmu_rtc_alarm_status_set(void); + +int pmu_rtc_alarm_alerted(); + +void pmu_rtc_set_irq_handler(PMU_RTC_IRQ_HANDLER_T handler); + +void pmu_viorise_req(enum PMU_VIORISE_REQ_USER_T user, bool rise); + +enum PMU_POWER_ON_CAUSE_T pmu_get_power_on_cause(void); + +int pmu_debug_config_ana(uint16_t volt); + +int pmu_debug_config_codec(uint16_t volt); + +int pmu_debug_config_audio_output(bool diff); + +int pmu_debug_config_vcrystal(bool on); + +void pmu_debug_reliability_test(int stage); + +void pmu_at_skip_shutdown(bool enable); + +void pmu_led_set_direction(enum HAL_GPIO_PIN_T pin, enum HAL_GPIO_DIR_T dir); + +enum HAL_GPIO_DIR_T pmu_led_get_direction(enum HAL_GPIO_PIN_T pin); + +void pmu_led_set_voltage_domains(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt); + +void pmu_led_set_pull_select(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_PIN_PULL_SELECT_T pull_sel); + +void pmu_led_set_value(enum HAL_GPIO_PIN_T pin, int data); + +int pmu_led_get_value(enum HAL_GPIO_PIN_T pin); + +void pmu_wdt_set_irq_handler(PMU_WDT_IRQ_HANDLER_T handler); + +int pmu_wdt_config(uint32_t irq_ms, uint32_t reset_ms); + +void pmu_wdt_start(void); + +void pmu_wdt_stop(void); + +void pmu_wdt_feed(void); + +void pmu_ntc_capture_enable(void); + +void pmu_ntc_capture_disable(void); + +int pmu_set_irq_unified_handler(enum PMU_IRQ_TYPE_T type, PMU_IRQ_UNIFIED_HANDLER_T hdlr); + +enum HAL_PWRKEY_IRQ_T pmu_pwrkey_irq_value_to_state(uint16_t irq_status); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/ana/psramuhsphy.h b/platform/drivers/ana/psramuhsphy.h new file mode 100644 index 0000000..c6104bf --- /dev/null +++ b/platform/drivers/ana/psramuhsphy.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __PSRAMUHSPHY_H__ +#define __PSRAMUHSPHY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_addr_map.h" +#include CHIP_SPECIFIC_HDR(psramuhsphy) +#include "hal_phyif.h" + +#ifdef SPIPHY_PSRAMUHS0_REG +#define SPI_PSRAMUHSPHY0_REG(reg) SPIPHY_PSRAMUHS0_REG(reg) +#else +#define SPI_PSRAMUHSPHY0_REG(reg) (reg) +#endif + +#ifdef SPIPHY_PSRAMUHS1_REG +#define SPI_PSRAMUHSPHY1_REG(reg) SPIPHY_PSRAMUHS1_REG(reg) +#else +#define SPI_PSRAMUHSPHY1_REG(reg) (reg) +#endif + +#define psramuhsphy0_read(reg, val) hal_phyif_reg_read(SPI_PSRAMUHSPHY0_REG(reg), val) +#define psramuhsphy0_write(reg, val) hal_phyif_reg_write(SPI_PSRAMUHSPHY0_REG(reg), val) + +#define psramuhsphy1_read(reg, val) hal_phyif_reg_read(SPI_PSRAMUHSPHY1_REG(reg), val) +#define psramuhsphy1_write(reg, val) hal_phyif_reg_write(SPI_PSRAMUHSPHY1_REG(reg), val) + +void psramuhsphy_open(uint32_t clk); + +void psramuhsphy_init_calib(void); + +void psramuhsphy_calib(uint32_t clk); + +void psramuhsphy_sleep(void); + +void psramuhsphy_wakeup(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/ana/usbphy.h b/platform/drivers/ana/usbphy.h new file mode 100644 index 0000000..e2dc906 --- /dev/null +++ b/platform/drivers/ana/usbphy.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __USBPHY_H__ +#define __USBPHY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "plat_addr_map.h" +#include CHIP_SPECIFIC_HDR(usbphy) +#include "hal_analogif.h" +#include "hal_phyif.h" + +#ifdef SPIPHY_USB_REG +#define SPI_USBPHY_REG(reg) SPIPHY_USB_REG(reg) +#elif defined(ISPI_USBPHY_REG) +#define SPI_USBPHY_REG(reg) ISPI_USBPHY_REG(reg) +#else +#define SPI_USBPHY_REG(reg) (reg) +#endif + +#ifdef CHIP_HAS_SPIPHY +#define usbphy_read(reg, val) hal_phyif_reg_read(SPI_USBPHY_REG(reg), val) +#define usbphy_write(reg, val) hal_phyif_reg_write(SPI_USBPHY_REG(reg), val) +#else +#define usbphy_read(reg, val) hal_analogif_reg_read(SPI_USBPHY_REG(reg), val) +#define usbphy_write(reg, val) hal_analogif_reg_write(SPI_USBPHY_REG(reg), val) +#endif + +void usbphy_open(void); + +void usbphy_close(void); + +void usbphy_sleep(void); + +void usbphy_wakeup(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/bt/Makefile b/platform/drivers/bt/Makefile new file mode 100644 index 0000000..537b938 --- /dev/null +++ b/platform/drivers/bt/Makefile @@ -0,0 +1,152 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +obj-y += $(CHIP)/ + +subdir-ccflags-y += \ + -Iapps/common \ + -Iplatform/drivers/bt \ + -Iplatform/drivers/ana \ + -Iservices/nvrecord \ + -Iutils/cqueue \ + -Iutils/heap + +ifeq ($(BT_XTAL_SYNC),1) +subdir-ccflags-y += -DBT_XTAL_SYNC +endif + +export BT_DRV_UART_BRIDGE_FLAGS := +ifneq ($(DEBUG_PORT),) +BT_DRV_UART_BRIDGE_FLAGS += -DDEBUG_PORT=$(DEBUG_PORT) +endif + +export BT_DRV_FLAGS := +ifeq ($(NO_SLEEP),1) +BT_DRV_FLAGS += -DNO_SLEEP +endif + +export BT_DRV_CONFIG_FLAGS := +ifeq ($(INTERSYS_NO_THREAD),1) +BT_DRV_CONFIG_FLAGS += -D_INTERSYS_NO_THREAD_ +endif + +VCO_TEST_TOOL ?= 1 +ifeq ($(VCO_TEST_TOOL),1) +subdir-ccflags-y += -DVCO_TEST_TOOL +endif + +LAURENT_ALGORITHM ?= 0 +ifeq ($(LAURENT_ALGORITHM),1) +subdir-ccflags-y += -DLAURENT_ALGORITHM +endif + +FORCE_SCO_MAX_RETX ?= 0 +ifeq ($(FORCE_SCO_MAX_RETX),1) +subdir-ccflags-y += -D__FORCE_SCO_MAX_RETX__ +endif + +CONTROLLER_DUMP_ENABLE ?= 0 +ifeq ($(CONTROLLER_DUMP_ENABLE),1) +subdir-ccflags-y += -DCONTROLLER_DUMP_ENABLE=1 +endif + +BT_UART_LOG ?= 0 +ifeq ($(BT_UART_LOG),1) +subdir-ccflags-y += -DBT_UART_LOG +endif + +BT_UART_LOG_P16 ?= 0 +ifeq ($(BT_UART_LOG_P16),1) +subdir-ccflags-y += -DBT_UART_LOG_P16 +endif + +LL_MONITOR ?= 0 +ifeq ($(LL_MONITOR),1) +subdir-ccflags-y += -DLL_MONITOR=1 +endif + +SOFTBIT_EN ?= 0 +ifeq ($(SOFTBIT_EN),1) +subdir-ccflags-y += -DSOFTBIT_EN=1 +endif + +ACL_DATA_CRC_TEST ?= 0 +ifeq ($(ACL_DATA_CRC_TEST),1) +subdir-ccflags-y += -DACL_DATA_CRC_TEST=1 +endif + +FA_RX_GAIN_CTRL ?= 0 +ifeq ($(FA_RX_GAIN_CTRL),1) +subdir-ccflags-y += -D__FA_RX_GAIN_CTRL__ +endif + +BT_SYSTEM_52M ?= 0 +ifeq ($(BT_SYSTEM_52M),1) +subdir-ccflags-y += -DBT_SYSTEM_52M +endif + +ifeq ($(BT_FA_ECC),1) +subdir-ccflags-y += -D__FASTACK_ECC_ENABLE__ +endif + +ifeq ($(BT_FA_SCO_ECC),1) +subdir-ccflags-y += -D__FASTACK_SCO_ECC_ENABLE__ +endif + +ifeq ($(BT_FA_ACL_ECC),1) +subdir-ccflags-y += -D__FASTACK_ACL_ECC_ENABLE__ +endif + +ifeq ($(BT_FAST_LOCK_ENABLE),1) +subdir-ccflags-y += -DBT_FAST_LOCK_ENABLE +endif + +BT_ECC_CONFIG_BLK ?= 0 +ifneq ($(BT_ECC_CONFIG_BLK),0) +subdir-ccflags-y += -D__FASTACK_ECC_CONFIG_BLOCK__=$(BT_ECC_CONFIG_BLK) +endif + +BES_FA_MODE ?= 0 +ifeq ($(BES_FA_MODE),1) +subdir-ccflags-y += -D__BES_FA_MODE__ +endif + +NEW_SWAGC_MODE ?= 0 +ifeq ($(NEW_SWAGC_MODE),1) +subdir-ccflags-y += -D__NEW_SWAGC_MODE__ +endif + +BLE_NEW_SWAGC_MODE ?= 0 +ifeq ($(BLE_NEW_SWAGC_MODE),1) +subdir-ccflags-y += -D__BLE_NEW_SWAGC_MODE__ +endif + +ifeq ($(BT_EXT_LNA_PA),1) +KBUILD_CPPFLAGS += -DBT_EXT_LNA_PA +ifeq ($(BT_EXT_LNA),1) +KBUILD_CPPFLAGS += -DBT_EXT_LNA +endif + +ifeq ($(BT_EXT_PA),1) +KBUILD_CPPFLAGS += -DBT_EXT_PA +endif +endif + +ifneq ($(BT_DEBUG_TPORTS),0) +subdir-ccflags-y += -DTPORT_TYPE=$(BT_DEBUG_TPORTS) +endif + +export CONTROLLER_DUMP_ENABLE ?= 0 +ifeq ($(CONTROLLER_DUMP_ENABLE),1) + KBUILD_CPPFLAGS += -DCONTROLLER_DUMP_ENABLE=1 +endif + +export CONTROLLER_MEM_LOG_ENABLE ?= 0 +ifeq ($(CONTROLLER_MEM_LOG_ENABLE),1) + KBUILD_CPPFLAGS += -DCONTROLLER_MEM_LOG_ENABLE=1 +endif + diff --git a/platform/drivers/bt/besbt_string.h b/platform/drivers/bt/besbt_string.h new file mode 100644 index 0000000..0502405 --- /dev/null +++ b/platform/drivers/bt/besbt_string.h @@ -0,0 +1,21 @@ +#ifndef BESBT_STRING_H +#define BESBT_STRING_H + +#include "stddef.h" +#include "stdint.h" +#include "plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +size_t memcpy_s(void *dst,size_t dstMax,const void *src, size_t srcMax); +size_t memset_s(void *,size_t,int,size_t); + +#ifdef __cplusplus +} +#endif + + +#endif /* BES_STRING_H */ + diff --git a/platform/drivers/bt/best2300p/Makefile b/platform/drivers/bt/best2300p/Makefile new file mode 100644 index 0000000..16a1c3c --- /dev/null +++ b/platform/drivers/bt/best2300p/Makefile @@ -0,0 +1,23 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +CFLAGS_bt_drv_uart_bridge_intsys.o += $(BT_DRV_UART_BRIDGE_FLAGS) + +CFLAGS_bt_drv.o += $(BT_DRV_FLAGS) + +CFLAGS_bt_drv_patch.o += $(BT_DRV_PATCH_FLAGS) + +CFLAGS_bt_drv_config.o += $(BT_DRV_CONFIG_FLAGS) + +TX_IQ_CAL ?= 0 +ifeq ($(TX_IQ_CAL),1) +subdir-ccflags-y += -DTX_IQ_CAL +endif + +subdir-ccflags-y += -Iutils/crash_catcher/include +subdir-ccflags-y += -Iservices/nv_section/userdata_section +ccflags-y += $(BT_IF_INCLUDES) diff --git a/platform/drivers/bt/best2300p/bt_drv.cpp b/platform/drivers/bt/best2300p/bt_drv.cpp new file mode 100644 index 0000000..10f37f3 --- /dev/null +++ b/platform/drivers/bt/best2300p/bt_drv.cpp @@ -0,0 +1,1391 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "string.h" +#include "plat_types.h" +#include "plat_addr_map.h" +#include "hal_i2c.h" +#include "hal_uart.h" +#include "bt_drv.h" +#include "bt_drv_internal.h" +#include "bt_drv_2300p_internal.h" +#include "bt_drv_reg_op.h" +#include "bt_drv_interface.h" +#include "hal_timer.h" +#include "hal_intersys.h" +#include "hal_trace.h" +#include "hal_psc.h" +#include "hal_cmu.h" +#include "hal_sysfreq.h" +#include "hal_chipid.h" +#include "hal_iomux.h" +#include "hal_gpio.h" +#include "pmu.h" +#include "nvrecord_dev.h" + + +bool btdrv_dut_mode_enable = false; + +static volatile uint32_t btdrv_tx_flag = 1; +void btdrv_tx(const unsigned char *data, unsigned int len) +{ +// HciPacketSent(intersys_tx_pkt); + BT_DRV_TRACE(0,"tx"); +// osSignalSet(btdrv_intersys_tx_thread_id, 0x1); + btdrv_tx_flag = 1; +} + +void btdrv_dut_accessible_mode_manager(const unsigned char *data); + +static unsigned int btdrv_rx(const unsigned char *data, unsigned int len) +{ + hal_intersys_stop_recv(HAL_INTERSYS_ID_0); + + BT_DRV_TRACE(2,"%s len:%d", __func__, len); + BT_DRV_DUMP("%02x ", data, len>7?7:len); + btdrv_dut_accessible_mode_manager(data); + hal_intersys_start_recv(HAL_INTERSYS_ID_0); + + return len; +} + +void btdrv_SendData(const uint8_t *buff,uint8_t len) +{ + btdrv_tx_flag = 0; + + hal_intersys_send(HAL_INTERSYS_ID_0, HAL_INTERSYS_MSG_HCI, buff, len); + BT_DRV_TRACE(1,"%s", __func__); + BT_DRV_DUMP("%02x ", buff, len); +// btdrv_delay(1); + while( (btdrv_dut_mode_enable==0) && btdrv_tx_flag == 0); +} + + + +////open intersys interface for hci data transfer +static bool hci_has_opened = false; + +void btdrv_hciopen(void) +{ + int ret = 0; + + if (hci_has_opened) + { + return; + } + + hci_has_opened = true; + + ret = hal_intersys_open(HAL_INTERSYS_ID_0, HAL_INTERSYS_MSG_HCI, btdrv_rx, btdrv_tx, false); + + if (ret) + { + BT_DRV_TRACE(0,"Failed to open intersys"); + return; + } + + hal_intersys_start_recv(HAL_INTERSYS_ID_0); +} + +////open intersys interface for hci data transfer +void btdrv_hcioff(void) +{ + if (!hci_has_opened) + { + return; + } + hci_has_opened = false; + + hal_intersys_close(HAL_INTERSYS_ID_0,HAL_INTERSYS_MSG_HCI); +} + + + +/* btdrv power on or off the bt controller*/ +void btdrv_poweron(uint8_t en) +{ + //power on bt controller + if(en) + { + hal_psc_bt_enable(); + hal_cmu_bt_clock_enable(); + hal_cmu_bt_reset_clear(); + hal_cmu_bt_module_init(); + btdrv_delay(10); + // BTDM mode 4.2 + BTDIGITAL_REG(0xC0000050) = 0x42; + btdrv_delay(100); + } + else + { + btdrv_delay(10); + hal_cmu_bt_reset_set(); + hal_cmu_bt_clock_disable(); + hal_psc_bt_disable(); + } +} + +void btdrv_rf_init_ext(void) +{ + unsigned int xtal_fcap; + + if (!nvrec_dev_get_xtal_fcap(&xtal_fcap)) + { + btdrv_rf_init_xtal_fcap(xtal_fcap); + btdrv_delay(1); + BT_DRV_TRACE(2,"%s 0xc2=0x%x", __func__, xtal_fcap); + } + else + { + btdrv_rf_init_xtal_fcap(DEFAULT_XTAL_FCAP); + BT_DRV_TRACE(1,"%s failed", __func__); + } +} + +void tx_ramp_new(void) +{ + return; + + +} + +void bt_drv_extra_config_after_init(void) +{ +#ifdef BT_RF_OLD_CORR_MODE + BTDIGITAL_REG(0xD03503A0) &= (~0x01); //clear bit 0 avoid slave lost data +#endif + bt_drv_reg_op_afh_env_reset(); +} + +#ifdef __HW_AGC__ + +uint16_t btdrv_2300_get_10bit_add_val(uint32_t val, uint8_t count) +{ + uint8_t i; + uint32_t new_val[32]; + uint16_t add_val = 0; + + for(i=0; i<32 ; i++) + { + new_val[i] = (val & 1); + val = (val >> 1); + }//get val's each bit to new_val + + for(i=(0+count); i<(10+count) ; i++) + { + add_val |= (new_val[i] << (i-count)); + } + + return add_val; +} + + +uint16_t btdrv_2300_val_get_max_min_num(uint16_t *val) +{ + uint8_t i = 0; + uint8_t j = 0; + uint8_t k = 0; + uint16_t max = val[0]; + uint16_t min = val[0]; + + for(i=1; i<10; i++) + { + if(max < val[i]) + { + max = val[i]; + j = i; + } + else if(min > val[i]) + { + min = val[i]; + k = i; + } + } + BT_DRV_TRACE(2,"The max is:%x, j:%d\n", max,j); + BT_DRV_TRACE(2,"The min is:%x, k:%d\n", min,k); + return ((j<<8) | k); +} + +uint16_t btdrv_2300_get_average_val(uint16_t *val) +{ + uint8_t i=0; + uint16_t num; + uint8_t max_num,min_num; + uint16_t add_val = 0; + uint16_t average_val; + + num = btdrv_2300_val_get_max_min_num(val); + + max_num = (uint8_t)((num & 0xff00)>>8); + min_num = (uint8_t)(num & 0x00ff); + BT_DRV_TRACE(1,"max_num:%d\n", max_num); + BT_DRV_TRACE(1,"min_num:%d\n", min_num); + + for(i=0; i<10 ; i++) + { + BT_DRV_TRACE(2,"val[%x]:%x\n",i,val[i]); + add_val += val[i]; + } + add_val = (add_val-val[max_num]-val[min_num]); + BT_DRV_TRACE(1,"add_val:%x\n",add_val); + + average_val = add_val / 8; + return average_val; +} + +union cal_val +{ + struct + { + int32_t val1 :10; + int32_t val2 :10; + int32_t val3 :10; + uint32_t reverd_bit :2; + }; + volatile uint32_t reg; +}; +void btdrv_2300_hwagc_dc_cal_1(void) +{ + uint32_t first_val; + volatile uint32_t value = 0; +// int16_t bit_value1[10],bit_value2[10],bit_value3[10];//10bit + int32_t bit_average_val1=0,bit_average_val2=0,bit_average_val3=0; + uint32_t real_val; + + union cal_val dccal_val; + + btdrv_write_rf_reg(0xf3,0x2c41);//i2v reset dr=1 + + btdrv_write_rf_reg(0xcf,0xff32);//lna gain dr=1 + btdrv_write_rf_reg(0xdf,0x210f);//lna gain dr=1 //210f + btdrv_write_rf_reg(0xcd,0x0040);//lna pdt gain + + btdrv_write_rf_reg(0xd0,0xf99f);//i2v flt gain dr=1 + + btdrv_write_rf_reg(0xaf, 0x00c0);//rx input pull down + + //BTDIGITAL_REG(0xc000033c) = 0x00000100; + + BTDIGITAL_REG(0xd02201e4) = 0x00000000;//rx continue + btdrv_delay(10); + BTDIGITAL_REG(0xd02201e4) = 0x000a0080; + btdrv_delay(10); + + for(uint8_t i = 0; i < 10; i++) + { + BTDIGITAL_REG(0xd03503b0) = 0x80000000; + btdrv_delay(1); + first_val = BTDIGITAL_REG(0xd03503b4); + BT_DRV_TRACE(1,"first_val:%x\n",first_val); + BTDIGITAL_REG(0xd03503b0) = 0x80000000; + } + + for(uint8_t i = 0; i < 10; i++) + { + BTDIGITAL_REG(0xd03503b0) = 0x80000000; + btdrv_delay(1); + BT_DRV_TRACE(1,"BTDIGITAL_REG(0xd03503b4):%x\n",BTDIGITAL_REG(0xd03503b4)); + value = BTDIGITAL_REG(0xd03503b4); + BT_DRV_TRACE(2,"%x: value:%x\n",i,value); + dccal_val.reg = value; + bit_average_val1 +=dccal_val.val1; + bit_average_val2 +=dccal_val.val2; + bit_average_val3 +=dccal_val.val3; + BT_DRV_TRACE(2,"val1=%d,val3=%d",dccal_val.val1, dccal_val.val3); + } + + bit_average_val1 /= 10; + +#ifdef __HW_AGC_I2V_DISABLE_DC_CAL__ + bit_average_val2 = 0; +#else + bit_average_val2 /=10; +#endif + bit_average_val3 /= 10; + + BT_DRV_TRACE(3,"vaer1=%d,vaer2=%d,vaer3=%d",bit_average_val1, bit_average_val2, bit_average_val3); + + dccal_val.val1 = bit_average_val1; + dccal_val.val2 = bit_average_val2; + dccal_val.val3 = bit_average_val3; + dccal_val.reverd_bit = 0; + // real_val = (bit_average_val1 | (bit_average_val2 << 10) | (bit_average_val3 << 20)); + real_val = dccal_val.reg; + BT_DRV_TRACE(1,"real_val:%x\n",real_val); + BTDIGITAL_REG(0xd03503b0) = real_val; + + BTDIGITAL_REG(0xd02201e4) = 0x00000000; + + btdrv_write_rf_reg(0xaf, 0x0000); + + btdrv_write_rf_reg(0xf3,0x0c41);//i2v reset dr=0 + + btdrv_write_rf_reg(0xcf,0x7f32);//lna gain dr=0 + btdrv_write_rf_reg(0xdf,0x2006);//lna gain dr=0 + btdrv_write_rf_reg(0xd0,0xe91f);//i2v flt gain dr=0 +} + + + +#endif + +void btdrv_2300_rccal(void) +{ + uint16_t value; + uint16_t value_tmp; + uint16_t val_tmp1; + uint16_t val_tmp2; + + btdrv_write_rf_reg(0x80, 0xa010); + btdrv_write_rf_reg(0xc4, 0xffff);//[5:4]=11,open rcosc bias + btdrv_write_rf_reg(0x80, 0xa000); + + btdrv_write_rf_reg(0xb3,0x33f3);//[9:8]=11,pwup rcosc + + btdrv_delay(1); + + BTDIGITAL_REG(0xd02201e4) = 0x00000000; + btdrv_delay(10); + BTDIGITAL_REG(0xd02201e4) = 0x000a0080; + btdrv_delay(10); + + btdrv_write_rf_reg(0x80, 0xa010); + btdrv_write_rf_reg(0xd6,0xf858);//[15]=1,enable clk counter + btdrv_write_rf_reg(0x80, 0xa000); + + btdrv_delay(10); + + btdrv_read_rf_reg(0xc0,&value); + BT_DRV_TRACE(1,"btdrv_rccal 0xc0 value:%x\n",value); + + btdrv_read_rf_reg(0x8b,&val_tmp1); + BT_DRV_TRACE(1,"0x8b val_tmp1=%x\n",val_tmp1); + + btdrv_read_rf_reg(0x8d,&val_tmp2); + BT_DRV_TRACE(1,"0x8d val_tmp2=%x\n",val_tmp2); + + value_tmp = value & 0x0fff; + if((value_tmp < 0x0ff0)&&(value_tmp > 0x0200)&&((value|0xefff)==0xffff)) + { + BT_DRV_TRACE(0,"0xc0 0x200 < value < 0xff0 done \n"); + btdrv_write_rf_reg(0x8b,(((( 0x7c4 * 1000 / (value & 0x0fff)) * 0x90 / 1000) << 8) | (val_tmp1 & 0x00ff))); + BT_DRV_TRACE(1,"0x8b:%x\n",(((( 0x7c4 * 1000 / (value & 0x0fff)) * 0x90 / 1000) << 8) | (val_tmp1 & 0x00ff))); + btdrv_read_rf_reg(0x8b,&val_tmp1); + BT_DRV_TRACE(1,"chk 0x8b val_tmp1=%x\n",val_tmp1); + btdrv_write_rf_reg(0x8d,((((0x7c4 * 1000 / (value & 0x0fff)) * 0x28 / 1000) << 10) | (val_tmp2 & 0x03ff))); + BT_DRV_TRACE(1,"0x8d:%x\n",((((0x7c4 * 1000 / (value & 0x0fff)) * 0x28 / 1000) << 10) | (val_tmp2 & 0x03ff))); + btdrv_read_rf_reg(0x8d,&val_tmp2); + BT_DRV_TRACE(1,"chk 0x8d val_tmp2=%x\n",val_tmp2); + } + else + { + btdrv_write_rf_reg(0x8b,((0x9c << 8) | (val_tmp1 & 0x00ff))); + BT_DRV_TRACE(1,"0x8b:%x\n",((0x9c << 8) | (val_tmp1 & 0x00ff))); + btdrv_write_rf_reg(0x8d,((0x28 << 10) | (val_tmp2 & 0x03ff))); + BT_DRV_TRACE(1,"0x8d:%x\n",((0x28 << 10) | (val_tmp2 & 0x03ff))); + } + + BTDIGITAL_REG(0xd02201e4) = 0x00000000; + + btdrv_write_rf_reg(0x80, 0xa010); + btdrv_write_rf_reg(0xc4, 0xffcf);//[5:4]=00,close rcosc bias + btdrv_write_rf_reg(0x80, 0xa000); + + btdrv_write_rf_reg(0xb3,0x30f3);//[9:8]=00,pwup rcosc +} + + +#ifdef __PWR_FLATNESS__ +#define PWR_FLATNESS_CONST_VAL 0xF +void btdrv_2300p_channel_pwr_flatness(void) +{ + uint16_t read_value; + uint16_t tmp_val; + + btdrv_read_rf_reg(0xc0,&read_value); + BT_DRV_TRACE(1,"btdrv_2300p_channel_pwr_flatness 0xc0=%x\n",read_value); + + read_value = (read_value & 0x0f00)>>8;//[11:8] + int16_t calib_val = PWR_FLATNESS_CONST_VAL - read_value; + if(calib_val<0) + { + BT_DRV_TRACE(2,"calib_val<0 const_val=%d,read_val=%x",PWR_FLATNESS_CONST_VAL,read_value); + btdrv_read_rf_reg(0x92,&tmp_val); + tmp_val &= 0xf0ff;//[11:8] + BT_DRV_TRACE(1,"0x92=%x\n",tmp_val); + btdrv_write_rf_reg(0x92,tmp_val); + return; + } + else + { + BT_DRV_TRACE(2,"const_val=%d,calib_val =%x",PWR_FLATNESS_CONST_VAL,calib_val); + } + + //write calibrated value into 0x92 register + btdrv_read_rf_reg(0x92,&tmp_val); + tmp_val &= 0xf0ff; + tmp_val |= ((calib_val & 0xffff)<<8); + BT_DRV_TRACE(1,"write reg 0x92 val=%x",tmp_val); + btdrv_write_rf_reg(0x92,tmp_val); +} +#endif + + + +void btdrv_enable_jtag(void) +{ + *(uint32_t*)0x400000F8 &= 0x7FFFFFFF;//clear bit31 + + hal_iomux_set_jtag(); + hal_cmu_jtag_enable(); + hal_cmu_jtag_clock_enable(); +} +///start active bt controller + +//#define BT_DRV_ENABLE_LMP_TRACE + +void btdrv_start_bt(void) +{ + hal_sysfreq_req(HAL_SYSFREQ_USER_BT, HAL_CMU_FREQ_26M); + +#if INTERSYS_DEBUG +#ifdef BT_DRV_ENABLE_LMP_TRACE + btdrv_trace_config(BT_CONTROLER_TRACE_TYPE_INTERSYS | + BT_CONTROLER_TRACE_TYPE_CONTROLLER | + BT_CONTROLER_FILTER_TRACE_TYPE_A2DP_STREAM | + BT_CONTROLER_TRACE_TYPE_LMP_TRACE); +#else + btdrv_trace_config(BT_CONTROLER_TRACE_TYPE_INTERSYS | + BT_CONTROLER_TRACE_TYPE_CONTROLLER | + BT_CONTROLER_FILTER_TRACE_TYPE_A2DP_STREAM); +#endif +#endif + +#if defined(BLE_ONLY_ENABLED) + btdrv_enable_sleep_checker(false); +#else + btdrv_enable_sleep_checker(true); +#endif + + hal_iomux_ispi_access_enable(HAL_IOMUX_ISPI_MCU_RF); + +#ifndef NO_SLEEP + pmu_sleep_en(0); +#endif + + bt_drv_reg_op_global_symbols_init(); + + btdrv_poweron(BT_POWERON); + + btdrv_hciopen(); + + btdrv_rf_init(); + + btdrv_rf_init_ext(); + + btdrv_config_init(); + //rom patch init + btdrv_ins_patch_init(); + btdrv_data_patch_init(); + btdrv_patch_en(1); +#ifdef __HW_AGC__ + btdrv_2300_hwagc_dc_cal_1(); +#endif + + btdrv_2300_rccal(); +#ifdef __PWR_FLATNESS__ + btdrv_2300p_channel_pwr_flatness(); +#endif + + btdrv_txpower_calib(); + +#ifdef BT_XTAL_SYNC +// btdrv_bt_spi_xtal_init(); +#endif + btdrv_sync_config(); +#ifdef BT_EXT_LNA_PA + int LNA_flag = 0,PA_flag = 0; +#ifdef BT_EXT_LNA + LNA_flag = 1; +#endif +#ifdef BT_EXT_PA + PA_flag = 1; +#endif + btdrv_enable_rf_sw(LNA_flag,PA_flag); +#endif + bt_drv_reg_op_dgb_link_gain_ctrl_init(); + btdrv_fast_lock_config(0); +#ifdef __FASTACK_ECC_ENABLE__ + btdrv_ecc_config(); +#endif + + //regist bt switch agc cb function + struct bt_cb_tag* bt_drv_func_cb = bt_drv_get_func_cb_ptr(); + bt_drv_func_cb->bt_switch_agc = bt_drv_select_agc_mode; + + //initialize agc mode + if(bt_drv_func_cb->bt_switch_agc != NULL) + { + bt_drv_func_cb->bt_switch_agc(BT_IDLE_MODE); + } + btdrv_hcioff(); + + /*reg controller crash dump*/ + hal_trace_crash_dump_register(HAL_TRACE_CRASH_DUMP_MODULE_BT, bt_drv_reg_op_crash_dump); + +#ifndef NO_SLEEP + pmu_sleep_en(1); +#endif + + hal_iomux_ispi_access_enable(HAL_IOMUX_ISPI_MCU_RF); + + hal_sysfreq_req(HAL_SYSFREQ_USER_BT, HAL_CMU_FREQ_32K); +} + +const uint8_t hci_cmd_enable_dut[] = +{ + 0x01,0x03, 0x18, 0x00 +}; +const uint8_t hci_cmd_enable_allscan[] = +{ + 0x01, 0x1a, 0x0c, 0x01, 0x03 +}; +const uint8_t hci_cmd_disable_scan[] = +{ + 0x01, 0x1a, 0x0c, 0x01, 0x00 +}; +const uint8_t hci_cmd_enable_pagescan[] = +{ + 0x01, 0x1a, 0x0c, 0x01, 0x02 +}; +const uint8_t hci_cmd_autoaccept_connect[] = +{ + 0x01,0x05, 0x0c, 0x03, 0x02, 0x00, 0x02 +}; +const uint8_t hci_cmd_hci_reset[] = +{ + 0x01,0x03,0x0c,0x00 +}; + + +const uint8_t hci_cmd_nonsig_tx_dh1_pn9[] = +{ + 0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x04, 0x04, 0x1b, 0x00 +}; +const uint8_t hci_cmd_nonsig_tx_2dh1_pn9[] = +{ + 0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x04, 0x04, 0x36, 0x00 +}; +const uint8_t hci_cmd_nonsig_tx_3dh1_pn9[] = +{ + 0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x08, 0x04, 0x53, 0x00 +}; +const uint8_t hci_cmd_nonsig_tx_2dh3_pn9[] = +{ + 0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0a, 0x04, 0x6f, 0x01 +}; +const uint8_t hci_cmd_nonsig_tx_3dh3_pn9[] = +{ + 0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0b, 0x04, 0x28, 0x02 +}; + +const uint8_t hci_cmd_nonsig_rx_dh1_pn9[] = +{ + 0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x04, 0x00, 0x1b, 0x00 +}; +const uint8_t hci_cmd_nonsig_rx_2dh1_pn9[] = +{ + 0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x04, 0x00, 0x36, 0x00 +}; +const uint8_t hci_cmd_nonsig_rx_3dh1_pn9[] = +{ + 0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x08, 0x00, 0x53, 0x00 +}; +const uint8_t hci_cmd_nonsig_rx_2dh3_pn9[] = +{ + 0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0a, 0x00, 0x6f, 0x01 +}; +const uint8_t hci_cmd_nonsig_rx_3dh3_pn9[] = +{ + 0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0b, 0x00, 0x28, 0x02 +}; + +const uint8_t hci_cmd_nonsig_tx_dh1_pn9_t2[] = +{ + 0x01, 0x87, 0xfc, 0x1c, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x04, 0x04, 0x1b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; +const uint8_t hci_cmd_nonsig_tx_2dh1_pn9_t2[] = +{ + 0x01, 0x87, 0xfc, 0x1c, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x04, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; +const uint8_t hci_cmd_nonsig_tx_3dh1_pn9_t2[] = +{ + 0x01, 0x87, 0xfc, 0x1c, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x08, 0x04, 0x53, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; +const uint8_t hci_cmd_nonsig_tx_2dh3_pn9_t2[] = +{ + 0x01, 0x87, 0xfc, 0x1c, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0a, 0x04, 0x6f, 0x01, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; +const uint8_t hci_cmd_nonsig_tx_3dh3_pn9_t2[] = +{ + 0x01, 0x87, 0xfc, 0x1c, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0b, 0x04, 0x28, 0x02, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; + +const uint8_t hci_cmd_nonsig_rx_dh1_pn9_t2[] = +{ + 0x01, 0x87, 0xfc, 0x1c, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x04, 0x00, 0x1b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; +const uint8_t hci_cmd_nonsig_rx_2dh1_pn9_t2[] = +{ + 0x01, 0x87, 0xfc, 0x1c, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x04, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; +const uint8_t hci_cmd_nonsig_rx_3dh1_pn9_t2[] = +{ + 0x01, 0x87, 0xfc, 0x1c, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x08, 0x00, 0x53, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; +const uint8_t hci_cmd_nonsig_rx_2dh3_pn9_t2[] = +{ + 0x01, 0x87, 0xfc, 0x1c, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0a, 0x00, 0x6f, 0x01, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; +const uint8_t hci_cmd_nonsig_rx_3dh3_pn9_t2[] = +{ + 0x01, 0x87, 0xfc, 0x1c, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0b, 0x00, 0x28, 0x02, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; + +//vco test +const uint8_t hci_cmd_start_bt_vco_test[] = +{ + 0x01, 0xaa, 0xfc, 0x02, 0x00,0x02 +}; +const uint8_t hci_cmd_stop_bt_vco_test[] = +{ + 0x01, 0xaa, 0xfc, 0x02, 0x00,0x04 +}; + +void btdrv_testmode_start(void) +{ + struct bt_cb_tag* bt_drv_func_cb = bt_drv_get_func_cb_ptr(); + + if(bt_drv_func_cb->bt_switch_agc != NULL) + { + bt_drv_func_cb->bt_switch_agc(BT_A2DP_WORK_MODE); + } + bt_drv_tx_pwr_init_for_testmode(); +} + +void btdrv_write_localinfo(const char *name, uint8_t len, const uint8_t *addr) +{ + uint8_t hci_cmd_write_addr[5+6] = + { + 0x01, 0x72, 0xfc, 0x07, 0x00 + }; + + uint8_t hci_cmd_write_name[248+4] = + { + 0x01, 0x13, 0x0c, 0xF8 + }; + memset(&hci_cmd_write_name[4], 0, sizeof(hci_cmd_write_name)-4); + memcpy(&hci_cmd_write_name[4], name, len); + btdrv_SendData(hci_cmd_write_name, sizeof(hci_cmd_write_name)); + btdrv_delay(50); + memcpy(&hci_cmd_write_addr[5], addr, 6); + btdrv_SendData(hci_cmd_write_addr, sizeof(hci_cmd_write_addr)); + btdrv_delay(20); +} + +void btdrv_enable_dut(void) +{ + btdrv_SendData(hci_cmd_enable_dut, sizeof(hci_cmd_enable_dut)); + btdrv_delay(20); + btdrv_SendData(hci_cmd_enable_allscan, sizeof(hci_cmd_enable_allscan)); + btdrv_delay(20); + btdrv_SendData(hci_cmd_autoaccept_connect, sizeof(hci_cmd_autoaccept_connect)); + btdrv_delay(20); + bt_drv_reg_op_set_accessible_mode(3); +#ifdef LAURENT_ALGORITHM + btdrv_bt_laurent_algorithm_enable(); +#endif + btdrv_dut_mode_enable = true; +} + +void btdrv_disable_scan(void) +{ + btdrv_SendData(hci_cmd_disable_scan, sizeof(hci_cmd_disable_scan)); + btdrv_delay(20); +} + +static uint32_t dut_connect_status = DUT_CONNECT_STATUS_DISCONNECTED; + +uint32_t btdrv_dut_get_connect_status(void) +{ + return dut_connect_status; +} + +void btdrv_dut_accessible_mode_manager(const unsigned char *data) +{ + if(btdrv_dut_mode_enable) + { + if(data[0]==0x04&&data[1]==0x03&&data[2]==0x0b&&data[3]==0x00) + { + bt_drv_reg_op_set_accessible_mode(0); + btdrv_disable_scan(); + dut_connect_status = DUT_CONNECT_STATUS_CONNECTED; + } + else if(data[0]==0x04&&data[1]==0x05&&data[2]==0x04&&data[3]==0x00) + { + btdrv_enable_dut(); + dut_connect_status = DUT_CONNECT_STATUS_DISCONNECTED; + } + } +} + +void btdrv_hci_reset(void) +{ + btdrv_SendData(hci_cmd_hci_reset, sizeof(hci_cmd_hci_reset)); + btdrv_delay(350); +} + +void btdrv_enable_nonsig_tx(uint8_t index) +{ + BT_DRV_TRACE(1,"%s\n", __func__); + + if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_1) + { + if (index == 0) + btdrv_SendData(hci_cmd_nonsig_tx_2dh1_pn9, sizeof(hci_cmd_nonsig_tx_2dh1_pn9)); + else if (index == 1) + btdrv_SendData(hci_cmd_nonsig_tx_3dh1_pn9, sizeof(hci_cmd_nonsig_tx_3dh1_pn9)); + else if (index == 2) + btdrv_SendData(hci_cmd_nonsig_tx_2dh3_pn9, sizeof(hci_cmd_nonsig_tx_2dh1_pn9)); + else if (index == 3) + btdrv_SendData(hci_cmd_nonsig_tx_3dh3_pn9, sizeof(hci_cmd_nonsig_tx_3dh1_pn9)); + else + btdrv_SendData(hci_cmd_nonsig_tx_dh1_pn9, sizeof(hci_cmd_nonsig_tx_dh1_pn9)); + } + else + { + if (index == 0) + btdrv_SendData(hci_cmd_nonsig_tx_2dh1_pn9_t2, sizeof(hci_cmd_nonsig_tx_2dh1_pn9_t2)); + else if (index == 1) + btdrv_SendData(hci_cmd_nonsig_tx_3dh1_pn9_t2, sizeof(hci_cmd_nonsig_tx_3dh1_pn9_t2)); + else if (index == 2) + btdrv_SendData(hci_cmd_nonsig_tx_2dh3_pn9_t2, sizeof(hci_cmd_nonsig_tx_2dh1_pn9_t2)); + else if (index == 3) + btdrv_SendData(hci_cmd_nonsig_tx_3dh3_pn9_t2, sizeof(hci_cmd_nonsig_tx_3dh1_pn9_t2)); + else + btdrv_SendData(hci_cmd_nonsig_tx_dh1_pn9_t2, sizeof(hci_cmd_nonsig_tx_dh1_pn9_t2)); + } + + btdrv_delay(20); + +} + +void btdrv_enable_nonsig_rx(uint8_t index) +{ + BT_DRV_TRACE(1,"%s\n", __func__); + + if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_1) + { + if (index == 0) + btdrv_SendData(hci_cmd_nonsig_rx_2dh1_pn9, sizeof(hci_cmd_nonsig_rx_2dh1_pn9)); + else if (index == 1) + btdrv_SendData(hci_cmd_nonsig_rx_3dh1_pn9, sizeof(hci_cmd_nonsig_rx_3dh1_pn9)); + else if (index == 2) + btdrv_SendData(hci_cmd_nonsig_rx_2dh3_pn9, sizeof(hci_cmd_nonsig_rx_2dh1_pn9)); + else if (index == 3) + btdrv_SendData(hci_cmd_nonsig_rx_3dh3_pn9, sizeof(hci_cmd_nonsig_rx_3dh1_pn9)); + else + btdrv_SendData(hci_cmd_nonsig_rx_dh1_pn9, sizeof(hci_cmd_nonsig_rx_dh1_pn9)); + } + else + { + if (index == 0) + btdrv_SendData(hci_cmd_nonsig_rx_2dh1_pn9_t2, sizeof(hci_cmd_nonsig_rx_2dh1_pn9_t2)); + else if (index == 1) + btdrv_SendData(hci_cmd_nonsig_rx_3dh1_pn9_t2, sizeof(hci_cmd_nonsig_rx_3dh1_pn9_t2)); + else if (index == 2) + btdrv_SendData(hci_cmd_nonsig_rx_2dh3_pn9_t2, sizeof(hci_cmd_nonsig_rx_2dh1_pn9_t2)); + else if (index == 3) + btdrv_SendData(hci_cmd_nonsig_rx_3dh3_pn9_t2, sizeof(hci_cmd_nonsig_rx_3dh1_pn9_t2)); + else + btdrv_SendData(hci_cmd_nonsig_rx_dh1_pn9_t2, sizeof(hci_cmd_nonsig_rx_dh1_pn9_t2)); + } + + btdrv_delay(20); +} + +static bool btdrv_vco_test_running = false; +static unsigned short vco_test_reg_val_b6 = 0; +static unsigned short vco_test_reg_val_1f3 = 0; +#ifdef VCO_TEST_TOOL +static unsigned short vco_test_hack_flag = 0; +static unsigned short vco_test_channel = 0xff; + +unsigned short btdrv_get_vco_test_process_flag(void) +{ + return vco_test_hack_flag; +} + +bool btdrv_vco_test_bridge_intsys_callback(const unsigned char *data) +{ + bool status = false; + if(data[0]==0x01 &&data[1]==0xaa&&data[2]==0xfc &&data[3]==0x02) + { + status = true; + vco_test_hack_flag = data[5]; + vco_test_channel = data[4]; + } + + return status; +} + +void btdrv_vco_test_process(uint8_t op) +{ + if(op == 0x02)//vco test start + { + if(vco_test_channel != 0xff) + btdrv_vco_test_start(vco_test_channel); + } + else if(op ==0x04)//vco test stop + { + btdrv_vco_test_stop(); + } + vco_test_channel =0xff; + vco_test_hack_flag = 0; +} +#endif + +void btdrv_vco_test_start(uint8_t chnl) +{ + if (!btdrv_vco_test_running) + { + btdrv_vco_test_running = true; + hal_analogif_reg_read(0xb6, &vco_test_reg_val_b6); + hal_analogif_reg_read(0x1f3, &vco_test_reg_val_1f3); + hal_analogif_reg_write(0x1f3, 0); + hal_analogif_reg_write(0xb6, vco_test_reg_val_b6|(0x03<<14)); + hal_analogif_reg_write(0x1d7, 0xc4f8); + + BTDIGITAL_REG(0xd02201e4) = (chnl & 0x7f) | 0xa0000; + btdrv_delay(10); + BTDIGITAL_REG(0xd02201e4) = 0; + btdrv_delay(10); + BTDIGITAL_REG(0xd0340020) &= (~0x7); + BTDIGITAL_REG(0xd0340020) |= 6; + btdrv_delay(10); + } +} + +void btdrv_vco_test_stop(void) +{ + if (btdrv_vco_test_running) + { + btdrv_vco_test_running = false; + BTDIGITAL_REG(0xd02201bc) = 0; + BTDIGITAL_REG(0xd0340020) &=(~0x7); + if (vco_test_reg_val_b6 != 0) + { + hal_analogif_reg_write(0xb6, vco_test_reg_val_b6); + } + if (vco_test_reg_val_1f3 != 0) + { + hal_analogif_reg_write(0x1f3, vco_test_reg_val_1f3); + } + btdrv_delay(10); + } +} + +#ifdef LAURENT_ALGORITHM +void btdrv_ble_test_bridge_intsys_callback(const unsigned char *data) +{ + if(data[0]==0x01 &&data[1]==0x03&&data[2]==0x0c &&data[3]==0x00) + { + //reset + btdrv_bt_laurent_algorithm_enable(); + } + else if(data[0]==0x01 &&(data[1]==0x1d || data[1]==0x1e)) + { + //enter ble test mode + btdrv_bt_laurent_algorithm_enable(); + btdrv_ble_laurent_algorithm_enable(); + } + else if(data[0]==0x01 &&data[1]==0x1f) + { + //exit ble tes mode + btdrv_bt_laurent_algorithm_enable(); + } +} +#endif + +void btdrv_stop_bt(void) +{ + btdrv_poweron(BT_POWEROFF); + +} + +void btdrv_write_memory(uint8_t wr_type,uint32_t address,const uint8_t *value,uint8_t length) +{ + uint8_t buff[256]; + if(length ==0 || length >128) + return; + buff[0] = 0x01; + buff[1] = 0x02; + buff[2] = 0xfc; + buff[3] = length + 6; + buff[4] = address & 0xff; + buff[5] = (address &0xff00)>>8; + buff[6] = (address &0xff0000)>>16; + buff[7] = address>>24; + buff[8] = wr_type; + buff[9] = length; + memcpy(&buff[10],value,length); + btdrv_SendData(buff,length+10); + btdrv_delay(2); + + +} + +void btdrv_send_cmd(uint16_t opcode,uint8_t cmdlen,const uint8_t *param) +{ + uint8_t buff[256]; + buff[0] = 0x01; + buff[1] = opcode & 0xff; + buff[2] = (opcode &0xff00)>>8; + buff[3] = cmdlen; + if(cmdlen>0) + memcpy(&buff[4],param,cmdlen); + btdrv_SendData(buff,cmdlen+4); +} + +void btdrv_rxdpd_sample_init(void) +{ +} + +void btdrv_rxdpd_sample_deinit(void) +{ +} + +#define BTTX_PATTEN (1) +#define BTTX_FREQ(freq) ((freq-2402)&0x7f) + +void btdrv_rxdpd_sample_init_tx(void) +{ +} + +void btdrv_rxdpd_sample_enable(uint8_t rxon, uint8_t txon) +{ +} +void btdrv_btcore_extwakeup_irq_enable(bool on) +{ + if (on) + { + *(volatile uint32_t *)(0xd033003c) |= (1<<14); + } + else + { + *(volatile uint32_t *)(0xd033003c) &= ~(1<<14); + } +} + +//[26:0] 0x07ffffff +//[27:0] 0x0fffffff + +uint32_t btdrv_syn_get_curr_ticks(void) +{ + uint32_t value; + + value = BTDIGITAL_REG(0xd0220490) & 0x0fffffff; + return value; +} + +static int32_t btdrv_syn_get_offset_ticks(uint16_t conidx) +{ + int32_t offset; + uint32_t local_offset; + uint16_t offset0; + uint16_t offset1; + offset0 = BTDIGITAL_BT_EM(EM_BT_CLKOFF0_ADDR + conidx*110); + offset1 = BTDIGITAL_BT_EM(EM_BT_CLKOFF1_ADDR + conidx*110); + + local_offset = (offset0 | offset1 << 16) & 0x07ffffff; + offset = local_offset; + offset = (offset << 5)>>5; + + if (offset) + { + return offset*2; + } + else + { + return 0; + } + +} + +// Clear trigger signal with software +void btdrv_syn_clr_trigger(void) +{ + BTDIGITAL_REG(0xd02201f0) = BTDIGITAL_REG(0xd02201f0) | (1<<31); +} + +static void btdrv_syn_set_tg_ticks(uint32_t num, uint8_t mode) +{ + if (mode == BT_TRIG_MASTER_ROLE) + { + BTDIGITAL_REG(0xd02204a4) = 0x80000006; + BTDIGITAL_REG(0xd02201f0) = (BTDIGITAL_REG(0xd02201f0) & 0x70000000) | (num & 0x0fffffff) | 0x10000000; + //BT_DRV_TRACE(1,"master mode d02201f0:0x%x\n",BTDIGITAL_REG(0xd02201f0)); + } + else + { + BTDIGITAL_REG(0xd02204a4) = 0x80000006; + BTDIGITAL_REG(0xd02201f0) = (BTDIGITAL_REG(0xd02201f0) & 0x60000000) | (num & 0x0fffffff); + //BT_DRV_TRACE(1,"slave mode d02201f0:0x%x\n",BTDIGITAL_REG(0xd02201f0)); + } +} + +void btdrv_syn_trigger_codec_en(uint32_t v) +{ +} + + +uint32_t btdrv_get_syn_trigger_codec_en(void) +{ + return BTDIGITAL_REG(0xd02201f0); +} + + +uint32_t btdrv_get_trigger_ticks(void) +{ + return BTDIGITAL_REG(0xd02201f0); +} + + +// Can be used by master or slave +// Ref: Master bt clk +uint32_t bt_syn_get_curr_ticks(uint16_t conhdl) +{ + int32_t curr,offset; + + curr = btdrv_syn_get_curr_ticks(); + + if (btdrv_is_link_index_valid(btdrv_conhdl_to_linkid(conhdl))) + offset = btdrv_syn_get_offset_ticks(btdrv_conhdl_to_linkid(conhdl)); + else + offset = 0; +// BT_DRV_TRACE(4,"[%s] curr(%d) + offset(%d) = %d", __func__, curr , offset,curr + offset); + return (curr + offset) & 0x0fffffff; +} + +int32_t bt_syn_get_offset_ticks(uint16_t conhdl) +{ + int32_t offset; + + if (btdrv_is_link_index_valid(btdrv_conhdl_to_linkid(conhdl))) + offset = btdrv_syn_get_offset_ticks(btdrv_conhdl_to_linkid(conhdl)); + else + offset = 0; +// BT_DRV_TRACE(4,"[%s] curr(%d) + offset(%d) = %d", __func__, curr , offset,curr + offset); + return offset; +} + +void bt_syn_trig_checker(uint16_t conhdl) +{ + int32_t clock_offset; + uint16_t bit_offset; + bt_drv_reg_op_piconet_clk_offset_get(conhdl, &clock_offset, &bit_offset); + + BT_DRV_TRACE(3,"bt_syn_set_tg_tick checker d0220498=0x%08x d02204a4=0x%08x d02201f0=0x%08x", BTDIGITAL_REG(0xd0220498), BTDIGITAL_REG(0xd02204a4), BTDIGITAL_REG(0xd02201f0)); + BT_DRV_TRACE(3,"bt_syn_set_tg_tick checker curr_ticks:0x%08x bitoffset=0x%04x rxbit=0x%04x", btdrv_syn_get_curr_ticks(), + BTDIGITAL_REG(EM_BT_BITOFF_ADDR+(conhdl - 0x80)*BT_EM_SIZE) & 0x3ff, + BTDIGITAL_REG(EM_BT_RXBIT_ADDR+(conhdl - 0x80)*BT_EM_SIZE) & 0x3ff); + BT_DRV_TRACE(2,"bt_syn_set_tg_tick checker clock_offset:0x%08x bit_offset=0x%04x", clock_offset, bit_offset); +} + +// Can be used by master or slave +// Ref: Master bt clk +void bt_syn_set_tg_ticks(uint32_t val,uint16_t conhdl, uint8_t mode) +{ + int32_t offset; + + if (btdrv_is_link_index_valid(btdrv_conhdl_to_linkid(conhdl))) + offset = btdrv_syn_get_offset_ticks(btdrv_conhdl_to_linkid(conhdl)); + else + offset = 0; + + if(conhdl==0x80) + { + BTDIGITAL_REG(0xd0220498)=(BTDIGITAL_REG(0xd0220498)&0xfffffff0)|0x1; + } + else if(conhdl==0x81) + { + BTDIGITAL_REG(0xd0220498)=(BTDIGITAL_REG(0xd0220498)&0xfffffff0)|0x2; + } + else if(conhdl==0x82) + { + BTDIGITAL_REG(0xd0220498)=(BTDIGITAL_REG(0xd0220498)&0xfffffff0)|0x3; + } + + if ((mode == BT_TRIG_MASTER_ROLE) && (offset !=0)) + BT_DRV_TRACE(0,"ERROR OFFSET !!"); + + val = val>>1; + val = val<<1; + val += 1; + + BT_DRV_TRACE(4,"bt_syn_set_tg_ticks val:%d num:%d mode:%d conhdl:%02x", val, val - offset, mode, conhdl); + btdrv_syn_set_tg_ticks(val - offset, mode); + bt_syn_trig_checker(conhdl); +} + +void btdrv_enable_playback_triggler(uint8_t triggle_mode) +{ + if(triggle_mode == ACL_TRIGGLE_MODE) + { + //clear SCO trigger + BTDIGITAL_REG(0xd02201f0) &= (~0x60000000); + //set ACL trigger + BTDIGITAL_REG(0xd02201f0) |= 0x20000000; + } + else if(triggle_mode == SCO_TRIGGLE_MODE) + { + //clear ACL trigger + BTDIGITAL_REG(0xd02201f0) &= (~0x60000000); + //set SCO trigger + BTDIGITAL_REG(0xd02201f0) |= 0x40000000; + } +} + +void btdrv_disable_playback_triggler(void) +{ + //clear ACL and SOC trigger + BTDIGITAL_REG(0xd02201f0) &= (~0x60000000); +} + +/* +bit28 1:master 0:slave +// master mode = 1 +// slave mode = 2 +// local mode = 0 +*/ + +void btdrv_set_tws_role_triggler(uint8_t tws_mode) +{ + BT_DRV_TRACE(1,"btdrv_set_tws_role_triggler tws_mode:%d", tws_mode); + + if(tws_mode == BT_TRIG_MASTER_ROLE) + { + BTDIGITAL_REG(0xd02201f0) |= 0x10000000; + } + else if(tws_mode == BT_TRIG_SLAVE_ROLE) + { + BTDIGITAL_REG(0xd02201f0) &= (~0x10000000); + } + +} + +void btdrv_set_bt_pcm_triggler_en(uint8_t en) +{ + if(en) + { + BTDIGITAL_REG(0xd022046c) &= (~0x1); + } + else + { + BTDIGITAL_REG(0xd022046c) |= 0x1; + } +} + +void btdrv_set_bt_pcm_triggler_delay(uint8_t delay) +{ + if(delay > 0x3f) + { + BT_DRV_TRACE(0,"delay is error value"); + return; + } + BT_DRV_TRACE(1,"0XD022045c=%x",BTDIGITAL_REG(0xd022045c)); + BTDIGITAL_REG(0xd022045c) &= ~0x7f; + BTDIGITAL_REG(0xd022045c) |= (delay); + BT_DRV_TRACE(1,"exit :0XD022045c=%x",BTDIGITAL_REG(0xd022045c)); +} + + +void btdrv_set_bt_pcm_en(uint8_t en) +{ + if(en) + BTDIGITAL_REG(0xd02201b0) |= 1; + else + BTDIGITAL_REG(0xd02201b0) &= (~1); +} + + +void btdrv_set_bt_pcm_triggler_delay_reset(uint8_t delay) +{ + if(delay > 0x3f) + { + BT_DRV_TRACE(0,"delay is error value"); + return; + } + BT_DRV_TRACE(1,"0XD022045c=%x",BTDIGITAL_REG(0xd0224024)); + BTDIGITAL_REG(0XD022045c) &= ~0x3f; + BTDIGITAL_REG(0XD022045c) |= delay|1; + // BTDIGITAL_REG(0xd0224024) |= 6; //bypass sco trig + BT_DRV_TRACE(1,"exit :0xd022045c=%x",BTDIGITAL_REG(0xd022045c)); +} + +void btdrv_set_pcm_data_ignore_crc(void) +{ + + BTDIGITAL_REG(0xD0220144) &= ~0x800000; +} + +//pealse use btdrv_is_link_index_valid() check link index whether valid +uint8_t btdrv_conhdl_to_linkid(uint16_t connect_hdl) +{ + //invalid hci handle,such as link disconnected + if(connect_hdl < HCI_HANDLE_MIN || connect_hdl > HCI_HANDLE_MAX) + { + TRACE(0, "ERROR Connect Handle=0x%x",connect_hdl); + return HCI_LINK_INDEX_INVALID; + } + else + { + return (connect_hdl - HCI_HANDLE_MIN); + } +} + +void btdrv_linear_format_16bit_set(void) +{ + *(volatile uint32_t *)(0xd02201a0) |= 0x00300000; +} + +void btdrv_pcm_enable(void) +{ + *(volatile uint32_t *)(0xd02201b0) |= 0x01; //pcm enable +} + +void btdrv_pcm_disable(void) +{ + *(volatile uint32_t *)(0xd02201b0) &= 0xfffffffe; //pcm disable +} + +// Trace tport +static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_tport[] = +{ + {HAL_IOMUX_PIN_P0_0, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}, +}; + +int btdrv_host_gpio_tport_open(void) +{ + uint32_t i; + + for (i=0; i=HAL_CHIP_METAL_ID_0) + { + BT_DRV_TRACE(0,"pcm fast mode\n"); + *(volatile uint32_t *)(0xd0220464) |= 1<<22;///pcm fast mode en bit22 + *(volatile uint32_t *)(0xd02201b8) = (*(volatile uint32_t *)(0xd02201b8)&0xFFFFFF00)|0x8;///pcm clk [8:0] + *(volatile uint32_t *)(0xd0220460) = (*(volatile uint32_t *)(0xd0220460)&0xFFFE03FF)|0x0000EC00;///sample num in one frame [16:10] + } +} +void btdrv_open_pcm_fast_mode_disable(void) +{ + if(hal_get_chip_metal_id()>=HAL_CHIP_METAL_ID_0) + { + BT_DRV_TRACE(0,"pcm fast mode disable\n"); + *(volatile uint32_t *)(0xd0220464) = (*(volatile uint32_t *)(0xd0220464)&0xFFBFFFFF);///disable pcm fast mode + *(volatile uint32_t *)(0xd02201b8) = (*(volatile uint32_t *)(0xd02201b8)&0xFFFFFF00); + } +} +#endif + +#if defined(CVSD_BYPASS) +void btdrv_cvsd_bypass_enable(uint8_t is_msbc) +{ + BTDIGITAL_REG(0xD0220144) &= ~0xffff; + + BTDIGITAL_REG(0xD0220144) |= 0x5555; + // BTDIGITAL_REG(0xD02201E8) |= 0x04000000; //test sequecy + BTDIGITAL_REG(0xD02201A0) &= ~(1<<7); //soft cvsd + //BTDIGITAL_REG(0xD02201b8) |= (1<<31); //revert clk +} +#endif + +void btdrv_enable_rf_sw(int rx_on, int tx_on) +{ + hal_iomux_set_bt_rf_sw(rx_on, tx_on); + BTDIGITAL_REG(0xD0340000) = (BTDIGITAL_REG(0xD0340000) & ~(1<<24)); + BTDIGITAL_REG(0xD0220050) = (BTDIGITAL_REG(0xD0220050) & ~0xFF) | 0xA6; +} + diff --git a/platform/drivers/bt/best2300p/bt_drv_2300p_internal.h b/platform/drivers/bt/best2300p/bt_drv_2300p_internal.h new file mode 100644 index 0000000..cbe4678 --- /dev/null +++ b/platform/drivers/bt/best2300p/bt_drv_2300p_internal.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BT_DRV_2300P_INTERNAL_H__ +#define __BT_DRV_2300P_INTERNAL_H__ + +/*************************************************************************** + *RF conig macro + ****************************************************************************/ +//#define __HW_AGC__ +#define __HYBIRD_AGC__ //if define __HYBIRD_AGC__ , not define __HW_AGC__ +#define __FANG_HW_AGC_CFG__ +#define __FANG_LNA_CFG__ +#define __PWR_FLATNESS__ + +#ifdef __HYBIRD_AGC__ +#define __HW_AGC__ +#endif + +#ifdef __HW_AGC__ +#define __HW_AGC_I2V_DISABLE_DC_CAL__ +#endif + +#define __1302_8_AGC__ + +#define BT_RF_OLD_CORR_MODE +/*************************************************************************** + *BT clock gate disable + ****************************************************************************/ +#define __CLK_GATE_DISABLE__ + +/*************************************************************************** + *BT read controller rssi + ****************************************************************************/ +#define BT_RSSI_MONITOR 1 + +/*************************************************************************** + *PCM config macro + ****************************************************************************/ +//#define APB_PCM +//#define SW_INSERT_MSBC_TX_OFFSET + +/*************************************************************************** + *BT afh follow function + ****************************************************************************/ +#define BT_AFH_FOLLOW 0 + +#ifdef __cplusplus +extern "C" { +#endif + +void btdrv_rf_rx_gain_adjust_req(uint32_t user, bool lowgain); +#ifdef LAURENT_ALGORITHM +void btdrv_ble_test_bridge_intsys_callback(const unsigned char *data); +void btdrv_bt_laurent_algorithm_enable(void); +void btdrv_ble_laurent_algorithm_enable(void); +#endif +void bt_drv_reg_op_for_test_mode_disable(void); +void bt_drv_reg_op_disable_swagc_nosync_count(void); + +void btdrv_txpower_calib(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/drivers/bt/best2300p/bt_drv_calibration.cpp b/platform/drivers/bt/best2300p/bt_drv_calibration.cpp new file mode 100644 index 0000000..f8f3ba7 --- /dev/null +++ b/platform/drivers/bt/best2300p/bt_drv_calibration.cpp @@ -0,0 +1,549 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef RTOS + +#include "plat_types.h" +#include "bt_drv.h" +#include "bt_drv_2300p_internal.h" +#include "hal_intersys.h" +#include "hal_i2c.h" +#include "hal_uart.h" +#include "hal_iomux.h" +#include "hal_chipid.h" +#include "string.h" +#include "bt_drv_interface.h" + +struct dbg_nonsig_tester_result_tag +{ + uint16_t pkt_counters; + uint16_t head_errors; + uint16_t payload_errors; + int16_t avg_estsw; + int16_t avg_esttpl; + uint32_t payload_bit_errors; +}; + +struct bt_drv_capval_calc_t +{ + int16_t estsw_a; + int16_t estsw_b; + uint8_t cdac_a; + uint8_t cdac_b; +}; + +static struct dbg_nonsig_tester_result_tag nonsig_tester_result; +#ifdef RTOS +static osThreadId calib_thread_tid = NULL; +#else +static bool calib_thread_tid = false; +#endif +static bool calib_running = false; +static struct bt_drv_capval_calc_t capval_calc ={ + .estsw_a = 0, + .estsw_b = 0, + .cdac_a = 0, + .cdac_b = 0, + }; + +#define bt_drv_calib_capval_calc_reset() do{ \ + memset(&capval_calc, 0, sizeof(capval_calc)); \ + }while(0) +#ifdef RTOS +#define BT_DRV_MUTUX_WAIT(evt) do{ \ + if (calib_thread_tid){ \ + osSignalClear(calib_thread_tid, 0x4); \ + evt = osSignalWait(0x4, 4000); \ + }\ + }while(0) + +#define BT_DRV_MUTUX_SET() do{ \ + if (calib_thread_tid){ \ + osSignalSet(calib_thread_tid, 0x4); \ + } \ + }while(0) +#else + +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; + +typedef struct { + osStatus status; ///< status code: event or error information +} osEvent; + +#define BT_DRV_MUTUX_WAIT(evt) do{ \ + uint8_t i=16; \ + evt.status = osErrorOS; \ + do{ \ + if (calib_thread_tid){ \ + calib_thread_tid = false; \ + evt.status = osEventSignal; \ + break; \ + }else{ \ + btdrv_delay(500); \ + } \ + }while(i--);\ + }while(0) + +#define BT_DRV_MUTUX_SET() do{ \ + calib_thread_tid = true; \ + }while(0) +#endif + +#define BT_DRV_CALIB_BTANA_CAPVAL_CALC_BOTTOM (50) +#define BT_DRV_CALIB_BTANA_CAPVAL_CALC_TOP (200) + +#define BT_DRV_CALIB_BTANA_CAPVAL_MIN (20) +#define BT_DRV_CALIB_BTANA_CAPVAL_MAX (255-BT_DRV_CALIB_BTANA_CAPVAL_MIN) +#define BT_DRV_CALIB_BTANA_CAPVAL_STEP_HZ (200) + +#define BT_DRV_CALIB_RETRY_CNT (10) +#define BT_DRV_CALIB_SKIP_RESULT_CNT (2) +#define BT_DRV_CALIB_MDM_FREQ_REFERENCE (-12) +#define BT_DRV_CALIB_MDM_FREQ_STEP_HZ (500) +#define BT_DRV_CALIB_MDM_BIT_TO_FREQ(n, step) ((n)*(step)) +#define BT_DRV_CALIB_MDM_FREQ_TO_BIT(n, step) ((uint32_t)n/step) + +static int16_t calib_mdm_freq_reference = BT_DRV_CALIB_MDM_FREQ_REFERENCE; + +enum HAL_IOMUX_ISPI_ACCESS_T ispi_access; + +static void bt_drv_rfcal_timer_handler(void const *param); +osTimerDef (BT_DRV_RFCAL_TIMER, bt_drv_rfcal_timer_handler); +static osTimerId bt_drv_rfcal_timer = NULL; + +static void bt_drv_calib_stop_timer(void) +{ + if (NULL != bt_drv_rfcal_timer) + { + osTimerStop(bt_drv_rfcal_timer); + } +} + +static void bt_drv_rfcal_timer_handler(void const *start) +{ + static int start_nonsig_rx = 0; + + if (NULL == bt_drv_rfcal_timer) + { + bt_drv_rfcal_timer = osTimerCreate(osTimer(BT_DRV_RFCAL_TIMER), osTimerOnce, NULL); + } + + osTimerStop(bt_drv_rfcal_timer); + + if (start_nonsig_rx || start) { + start_nonsig_rx = 0; + + const uint8_t hci_cmd_hci_reset[] = {0x01, 0x03, 0x0c, 0x00}; + const uint8_t calib_hci_cmd_nonsig_rx_2dh1_pn9_t5[] = { + 0x01, 0x87, 0xfc, 0x1c, 0x01, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, 0x01, 0x04, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff + }; + + /* start nonsig rx again */ + btdrv_SendData(hci_cmd_hci_reset, sizeof(hci_cmd_hci_reset)); + btdrv_delay(2); + btdrv_SendData(calib_hci_cmd_nonsig_rx_2dh1_pn9_t5, sizeof(calib_hci_cmd_nonsig_rx_2dh1_pn9_t5)); + btdrv_delay(100); + + BT_DRV_TRACE(0,"bt_drv_cal start nonsig rx\n"); + + BTDIGITAL_REG(0xd0210040) &= 0xff; + BTDIGITAL_REG(0xd0210040) |= 0x55; + + osTimerStart(bt_drv_rfcal_timer, 1500); + } else { + start_nonsig_rx = 1; + + const uint8_t stop_nonsig_rx_cmd[] = { + 0x01, 0x87, 0xfc, 0x1c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + /* stop nonsig rx and let report cal result */ + btdrv_SendData(stop_nonsig_rx_cmd, sizeof(stop_nonsig_rx_cmd)); + btdrv_delay(2); + + BT_DRV_TRACE(0,"bt_drv_cal stop nonsig rx\n"); + + osTimerStart(bt_drv_rfcal_timer, 300); + } +} + + +void bt_drv_start_calib(void) +{ + if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_1) + { + const uint8_t calib_hci_cmd_nonsig_rx_2dh1_pn9[] = { + 0x01, 0x87, 0xfc, 0x14, 0x01, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, 0x01, 0x04, 0x00, 0x36, 0x00 + }; + + if (!calib_running){ + btdrv_SendData(calib_hci_cmd_nonsig_rx_2dh1_pn9, sizeof(calib_hci_cmd_nonsig_rx_2dh1_pn9)); + btdrv_delay(500); + BTDIGITAL_REG(0xd0210040) &= 0xff; + BTDIGITAL_REG(0xd0210040) |= 0x55; + calib_running = true; + } + } + else + { + bt_drv_rfcal_timer_handler((void*)1); + calib_running = true; + } +} + +void bt_drv_stop_calib(void) +{ + if (calib_running){ + btdrv_hci_reset(); + btdrv_delay(200); + calib_running = false; + } + + if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) + { + bt_drv_calib_stop_timer(); + } +} + +const uint8_t calib_hci_cmd_nonsig_tx_2dh1_pn9_t0[] = { + 0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, 0x01, 0x04, 0x04, 0x36, 0x00 +}; + +const uint8_t calib_hci_cmd_nonsig_tx_2dh1_pn9_t1[] = { + 0x01, 0x87, 0xfc, 0x1c, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x01, 0x01, 0x04, 0x04, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; + +void bt_drv_check_calib(void) +{ + const uint8_t* calib_hci_cmd_nonsig_tx_2dh1_pn9 = NULL; + uint8_t len = 0; + + if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_1) + { + calib_hci_cmd_nonsig_tx_2dh1_pn9 = calib_hci_cmd_nonsig_tx_2dh1_pn9_t0; + len = sizeof(calib_hci_cmd_nonsig_tx_2dh1_pn9_t0); + } + else + { + calib_hci_cmd_nonsig_tx_2dh1_pn9 = calib_hci_cmd_nonsig_tx_2dh1_pn9_t1; + len = sizeof(calib_hci_cmd_nonsig_tx_2dh1_pn9_t1); + } + + btdrv_SendData(calib_hci_cmd_nonsig_tx_2dh1_pn9, len); + btdrv_delay(3000); + BTDIGITAL_REG(0xd0210040) &= 0xff; + BTDIGITAL_REG(0xd0210040) |= 39; +} + +static bool bt_drv_calib_capval_calc_run(uint16_t *capval_step_hz, int16_t estsw, uint8_t cdac) +{ + bool nRet = false; + int16_t estsw_diff; + int16_t cdac_diff; + + if (!capval_calc.estsw_a && + !capval_calc.estsw_b){ + capval_calc.estsw_a = estsw; + }else if (capval_calc.estsw_a && + !capval_calc.estsw_b){ + capval_calc.estsw_b = estsw; + } + + if (!capval_calc.cdac_a && + !capval_calc.cdac_b){ + capval_calc.cdac_a = cdac; + }else if (capval_calc.cdac_a && + !capval_calc.cdac_b){ + capval_calc.cdac_b = cdac; + } + + if (capval_calc.estsw_a && + capval_calc.estsw_b && + capval_calc.cdac_a && + capval_calc.cdac_b){ + + estsw_diff = ABS(capval_calc.estsw_b - capval_calc.estsw_a); + cdac_diff = ABS((int16_t)(capval_calc.cdac_b) - (int16_t)(capval_calc.cdac_a)); + *capval_step_hz = estsw_diff*BT_DRV_CALIB_MDM_FREQ_STEP_HZ/cdac_diff; + BT_DRV_TRACE(7,"%d/%d %d/%d estsw_diff:%d cdac_diff:%d capval_step_hz:%d", + capval_calc.estsw_a, + capval_calc.estsw_b, + capval_calc.cdac_a, + capval_calc.cdac_b, + estsw_diff, + cdac_diff, + *capval_step_hz); + nRet = true; + } + return nRet; +} + +void bt_drv_calib_rxonly_porc(void) +{ + osEvent evt; + + evt.status = os_status_reserved; + /*[set tmx] */ + btdrv_write_rf_reg(0xb0,0x0f00); /* turn off tmx */ + + bt_drv_start_calib(); + + + while(1){ + BT_DRV_MUTUX_WAIT(evt); + if(evt.status != osEventSignal){ + break; + } + btdrv_delay(10); + BT_DRV_TRACE(7,"result cnt:%d head:%d payload:%d estsw:%d esttpl:%d bit:%d est:%d", nonsig_tester_result.pkt_counters, + nonsig_tester_result.head_errors, + nonsig_tester_result.payload_errors, + nonsig_tester_result.avg_estsw, + nonsig_tester_result.avg_esttpl, + nonsig_tester_result.payload_bit_errors, + nonsig_tester_result.avg_estsw+nonsig_tester_result.avg_esttpl); + + + + }; + + bt_drv_stop_calib(); +} + +int bt_drv_calib_result_porc(uint32_t *capval) +{ + osEvent evt; + + uint16_t read_val = 0; + uint8_t cdac = 0; + uint8_t cnt = 0; + uint8_t skip_cnt = 0; + int diff = 0; + int est = 0; + uint8_t next_step = 0; + uint16_t capval_step_hz = BT_DRV_CALIB_BTANA_CAPVAL_STEP_HZ; + int nRet = -1; + int chk_flag = 0; + bool need_capval_calc = true; + evt.status = os_status_reserved; + + /*[set to capval_min] */ + btdrv_read_rf_reg(0xE9, &read_val); + cdac = BT_DRV_CALIB_BTANA_CAPVAL_CALC_BOTTOM; + read_val = (read_val & 0xff00)|(cdac);; + btdrv_write_rf_reg(0xE9,read_val); + + /*[set tmx] */ + btdrv_write_rf_reg(0xb0,0x0f00); /* turn off tmx */ + + bt_drv_calib_capval_calc_reset(); + + bt_drv_start_calib(); + +check_again: + BT_DRV_TRACE(0,"calib run !!!"); + do{ +calib_again: + BT_DRV_MUTUX_WAIT(evt); + if(evt.status != osEventSignal){ + nRet = -1; + BT_DRV_TRACE(1,"evt:%d", evt.status); + goto exit; + } + if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_1) + { + BT_DRV_MUTUX_WAIT(evt); + if(evt.status != osEventSignal) + { + nRet = -1; + BT_DRV_TRACE(1,"evt:%d", evt.status); + goto exit; + } + BT_DRV_MUTUX_WAIT(evt); + if(evt.status != osEventSignal) + { + nRet = -1; + BT_DRV_TRACE(1,"evt:%d", evt.status); + goto exit; + } + } + BT_DRV_TRACE(7,"result cnt:%d head:%d payload:%d estsw:%d esttpl:%d bit:%d est:%d", nonsig_tester_result.pkt_counters, + nonsig_tester_result.head_errors, + nonsig_tester_result.payload_errors, + nonsig_tester_result.avg_estsw, + nonsig_tester_result.avg_esttpl, + nonsig_tester_result.payload_bit_errors, + nonsig_tester_result.avg_estsw+nonsig_tester_result.avg_esttpl); + + + if (nonsig_tester_result.head_errors>15){ + if (++skip_cnt>BT_DRV_CALIB_SKIP_RESULT_CNT) + break; + else + goto calib_again; + } + skip_cnt = 0; + + btdrv_read_rf_reg(0xE9, &read_val); + cdac = read_val & 0x00ff; + + est = nonsig_tester_result.avg_estsw; + diff = est-calib_mdm_freq_reference; + + if (need_capval_calc){ + if (bt_drv_calib_capval_calc_run(&capval_step_hz, est, cdac)){ + need_capval_calc = false; + } + if (cdac == BT_DRV_CALIB_BTANA_CAPVAL_CALC_BOTTOM){ + cdac = BT_DRV_CALIB_BTANA_CAPVAL_CALC_TOP; + read_val = (read_val & 0xff00)|(cdac); + btdrv_write_rf_reg(0xE9,read_val); + } + goto calib_again; + } + + if ((BT_DRV_CALIB_MDM_BIT_TO_FREQ(ABS(diff), BT_DRV_CALIB_MDM_FREQ_STEP_HZ) < 1500) && diff>0){ + if (!chk_flag){ + chk_flag = 1; + cnt = 0; + next_step = 2; + goto check_again; + }else if(chk_flag && cnt>4){ + break; + } + nRet = 0; + break; + }else if (next_step == 2){ + + }else if (BT_DRV_CALIB_MDM_BIT_TO_FREQ(ABS(diff), BT_DRV_CALIB_MDM_FREQ_STEP_HZ) < 2500){ + next_step = 2; + }else{ + next_step = BT_DRV_CALIB_MDM_BIT_TO_FREQ(ABS(diff), BT_DRV_CALIB_MDM_FREQ_STEP_HZ)/capval_step_hz; + if (next_step == 0){ + next_step = 2; + } + if (next_step>200){ + next_step = 200; + } + } + BT_DRV_TRACE(4,"diff:%d read_val:%x cdac:%d next_step:%d", diff,read_val, cdac, next_step); + if (est == calib_mdm_freq_reference){ + if (!chk_flag){ + chk_flag = 1; + cnt = 0; + next_step = 2; + goto check_again; + }else if(chk_flag && cnt>4){ + break; + } + nRet = 0; + break; + }else if (est > calib_mdm_freq_reference){ + if (cdac < (BT_DRV_CALIB_BTANA_CAPVAL_MIN+next_step)){ + if (cdac == BT_DRV_CALIB_BTANA_CAPVAL_MIN) + break; + else + cdac = BT_DRV_CALIB_BTANA_CAPVAL_MIN; + }else{ + cdac -= next_step; + } + read_val = (read_val & 0xff00)|(cdac); + + BT_DRV_TRACE(2,"-----:%x cdac:%d", read_val, cdac); + }else if (est < calib_mdm_freq_reference){ + if (cdac>(BT_DRV_CALIB_BTANA_CAPVAL_MAX-next_step)){ + if (cdac == BT_DRV_CALIB_BTANA_CAPVAL_MAX) + break; + else + cdac = BT_DRV_CALIB_BTANA_CAPVAL_MAX; + }else{ + cdac += next_step; + } + read_val = (read_val & 0xff00)|(cdac); + + BT_DRV_TRACE(2,"+++++:%x cdac:%d", read_val, cdac); + } + + btdrv_write_rf_reg(0xE9,read_val); + }while(cnt++pkt_counters != 0) + { + memcpy(&nonsig_tester_result, pResult, sizeof(nonsig_tester_result)); + BT_DRV_MUTUX_SET(); + } + } + hal_intersys_start_recv(HAL_INTERSYS_ID_0); + + return len; +} + +void btdrv_tx(const unsigned char *data, unsigned int len); +void bt_drv_calib_open(void) +{ + int ret = 0; + BT_DRV_TRACE(1,"%s", __func__); +#ifdef RTOS + if (calib_thread_tid == NULL){ + calib_thread_tid = osThreadGetId(); + } +#endif + + ispi_access = hal_iomux_ispi_access_enable(HAL_IOMUX_ISPI_MCU_RF); + + ret = hal_intersys_open(HAL_INTERSYS_ID_0, HAL_INTERSYS_MSG_HCI, bt_drv_calib_rx, btdrv_tx, false); + + if (ret) { + BT_DRV_TRACE(0,"Failed to open intersys"); + return; + } + hal_intersys_start_recv(HAL_INTERSYS_ID_0); +} + +void bt_drv_calib_close(void) +{ + btdrv_hci_reset(); + btdrv_delay(200); + hal_intersys_close(HAL_INTERSYS_ID_0,HAL_INTERSYS_MSG_HCI); +} + +#endif diff --git a/platform/drivers/bt/best2300p/bt_drv_config.c b/platform/drivers/bt/best2300p/bt_drv_config.c new file mode 100644 index 0000000..fc6a9f8 --- /dev/null +++ b/platform/drivers/bt/best2300p/bt_drv_config.c @@ -0,0 +1,1691 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "plat_types.h" +#include "tgt_hardware.h" +#include "hal_i2c.h" +#include "hal_uart.h" +#include "bt_drv.h" +#include "hal_timer.h" +#include "hal_chipid.h" +#include "bt_drv_2300p_internal.h" +#include "bt_drv_interface.h" +#include "bt_drv_reg_op.h" +#include "bt_drv_internal.h" +//typedef void (*btdrv_config_func_t)(uint8_t parlen, uint8_t *param); + +extern void btdrv_send_cmd(uint16_t opcode,uint8_t cmdlen,const uint8_t *param); +extern void btdrv_write_memory(uint8_t wr_type,uint32_t address,const uint8_t *value,uint8_t length); + +typedef struct +{ +// btdrv_config_func_t func; + uint8_t is_act; + uint16_t opcode; + uint8_t parlen; + const uint8_t *param; + +} BTDRV_CFG_TBL_STRUCT; + + +#define BTDRV_CONFIG_ACTIVE 1 +#define BTDRV_CONFIG_INACTIVE 0 +#define BTDRV_INVALID_TRACE_LEVEL 0xFF +/* +[0][0] = 63, [0][1] = 0,[0][2] = (-80), 472d +[1][0] = 51, [2][1] = 0,[2][2] = (-80), 472b +[2][0] = 42, [4][1] = 0,[4][2] = (-75), 4722 +[3][0] = 36, [6][1] = 0,[6][2] = (-55), c712 +[4][0] = 30, [8][1] = 0,[8][2] = (-40), c802 +[5][0] = 21,[10][1] = 0,[10][2] = 0x7f, c102 +[6][0] = 12,[11][1] = 0,[11][2] = 0x7f, c142 +[7][0] = 3,[13][1] = 0,[13][2] = 0x7f, c1c2 +[8][0] = -3,[14][1] = 0,[14][2] = 0x7f}; c0c2 +*/ +static uint8_t g_controller_trace_level = BTDRV_INVALID_TRACE_LEVEL; +static bool g_lmp_trace_enable = false; +const int8_t btdrv_rf_env_2300p[]= +{ + 0x01,0x00, //rf api + 0x01, //rf env + 185, //rf length + 0x2, //txpwr_max +#ifdef __HW_AGC__ + -1, //high + -2, //low + -100, //interf +#else + -1, ///rssi high thr + -2, //rssi low thr + -100, //rssi interf thr +#endif + 0xf, //rssi interf gain thr + 2, //wakeup delay + 0xe, 0, //skew + 0xe8,0x3, //ble agc inv thr +#ifdef __HW_AGC__ + 0x1,//hw_sw_agc_flag +#else + 0x0,// +#endif + 0xff,//sw gain set + 0xff, //sw gain set + -70,//bt_inq_page_iscan_pscan_dbm + 0x7f,//ble_scan_adv_dbm + 1, //sw gain reset factor + 1, //bt sw gain cntl enable + 0, //ble sw gain cntl en + 1, //bt interfere detector en + 0, //ble interfere detector en + + -21,-27,-19, + -18,-24,-13, + -15,-21,-10, + -12,-18,-10, + -9,-15,-10, + -6,-12,-10, + -3,-9,-10, + 0,-6,0, + 0x7f,-3,0x7f, + 0x7f,0,0x7f, + 0x7f,0x7f,0x7f, + 0x7f,0x7f,0x7f, + 0x7f,0x7f,0x7f, + 0x7f,0x7f,0x7f, + 0x7f,0x7f,0x7f, //rx hwgain tbl ptr + +//zhangzhd agc config use default 1216 + 50,0,-80, + 42,0,-80, + 38,0,-80, + 32,0,-80, + 26,0,-80, + 21,0,-80, + 15,0,-80, + 9,0,-80, +//zhangzhd agc config end + + + 0x7f,0x7f,0x7f, + 0x7f,0x7f,0x7f, + 0x7f,0x7f,0x7f, + 0x7f,0x7f,0x7f, + 0x7f,0x7f,0x7f, + 0x7f,0x7f,0x7f, + 0x7f,0x7f,0x7f, //rx gain tbl ptr +//zhangzhd agc config use default 1216 + -80,-73, + -75,-68, + -70,-63, + -65,-58, + -60,-53, + -55,-48, + -50,-15, +//zhangzhd agc config end + + 0x7f,0x7f, + 0x7f,0x7f, + 0x7f,0x7f, + 0x7f,0x7f, + 0x7f,0x7f, + 0x7f,0x7f, + 0x7f,0x7f, + 0x7f,0x7f, //rx gain ths tbl ptr + + 0,0, + 0,0, + 0,0, + 0,0, + 0,0, + 0,1, + 0,2, + 0,2, + 0,2, + 0x7f,0x7f, + 0x7f,0x7f, + 0x7f,0x7f, + 0x7f,0x7f, + 0x7f,0x7f, + 0x7f,0x7f, //flpha filter factor ptr + -23,-20,-17,-14,-11,-8,-5,-2,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, //tx pw onv tbl ptr +}; + +const int8_t btdrv_afh_env[] = +{ + 0x02,0x00, //afh env + 0x00, //ignore + 33, //length + 5, //nb_reass_chnl + 10, //win_len + -70, //rf_rssi_interf_thr + 10, //per_thres_bad + 20, //reass_int + 20, //n_min + 20, //afh_rep_intv_max + 96, //ths_min + 2, //chnl_assess_report_style + 15, //chnl_assess_diff_thres + 60, // chnl_assess_interfere_per_thres_bad + 9, //chnl_assess_stat_cnt_max + -9, //chnl_assess_stat_cnt_min + 1,2,3,2,1, //chnl_assess_stat_cnt_inc_mask[5] + 1,2,3,2,1, //chnl_assess_stat_cnt_dec_mask + 0xd0,0x7, //chnl_assess_timer + -48, //chnl_assess_min_rssi + 0x64,0, //chnl_assess_nb_pkt + 0x32,0, //chnl_assess_nb_bad_pkt + 6, //chnl_reassess_cnt_val + 0x3c,0, //chnl_assess_interfere_per_thres_bad +}; + +const uint8_t lpclk_drift_jitter[] = +{ + 0xfa,0x00, // drift 250ppm + 0x0a,0x00 //jitter +-10us + +}; + +const uint8_t wakeup_timing[] = +{ + 0xe8,0x3, //exernal_wakeup_time 600us + 0xe8,0x3, //oscillater_wakeup_time 600us + 0xe8,0x3, //radio_wakeup_time 600us + //0xa0,0xf, //wakeup_delay_time +}; + + +uint8_t sleep_param[] = +{ + 1, // sleep_en; + 0, // exwakeup_en; + 0xc8,0, // lpo_calib_interval; lpo calibration interval + 0x32,0,0,0, // lpo_calib_time; lpo count lpc times +}; + +uint8_t unsleep_param[] = +{ + 0, // sleep_en; + 0, // exwakeup_en; + 0xc8,0, // lpo_calib_interval; lpo calibration interval + 0x32,0,0,0, // lpo_calib_time; lpo count lpc times +}; + +static const uint32_t me_init_param[][2] = +{ + {0xffffffff, 0xffffffff}, +}; + +const uint16_t me_bt_default_page_timeout = 0x2000; + +const uint8_t sync_config[] = +{ + 1,1, //sco path config 0:hci 1:pcm + 0, //sync use max buff length 0:sync data length= packet length 1:sync data length = host sync buff len + 0, //cvsd bypass 0:cvsd2pcm 1:cvsd transparent +}; + + +//pcm general ctrl +#define PCM_PCMEN_POS 15 +#define PCM_LOOPBCK_POS 14 +#define PCM_MIXERDSBPOL_POS 11 +#define PCM_MIXERMODE_POS 10 +#define PCM_STUTTERDSBPOL_POS 9 +#define PCM_STUTTERMODE_POS 8 +#define PCM_CHSEL_POS 6 +#define PCM_MSTSLV_POS 5 +#define PCM_PCMIRQEN_POS 4 +#define PCM_DATASRC_POS 0 + + +//pcm phy ctrl +#define PCM_LRCHPOL_POS 15 +#define PCM_CLKINV_POS 14 +#define PCM_IOM_PCM_POS 13 +#define PCM_BUSSPEED_LSB 10 +#define PCM_SLOTEN_MASK ((uint32_t)0x00000380) +#define PCM_SLOTEN_LSB 7 +#define PCM_WORDSIZE_MASK ((uint32_t)0x00000060) +#define PCM_WORDSIZE_LSB 5 +#define PCM_DOUTCFG_MASK ((uint32_t)0x00000018) +#define PCM_DOUTCFG_LSB 3 +#define PCM_FSYNCSHP_MASK ((uint32_t)0x00000007) +#define PCM_FSYNCSHP_LSB 0 + +/// Enumeration of PCM status +enum PCM_STAT +{ + PCM_DISABLE = 0, + PCM_ENABLE +}; + +/// Enumeration of PCM channel selection +enum PCM_CHANNEL +{ + PCM_CH_0 = 0, + PCM_CH_1 +}; + +/// Enumeration of PCM role +enum PCM_MSTSLV +{ + PCM_SLAVE = 0, + PCM_MASTER +}; + +/// Enumeration of PCM data source +enum PCM_SRC +{ + PCM_SRC_DPV = 0, + PCM_SRC_REG +}; + +/// Enumeration of PCM left/right channel selection versus frame sync polarity +enum PCM_LR_CH_POL +{ + PCM_LR_CH_POL_RIGHT_LEFT = 0, + PCM_LR_CH_POL_LEFT_RIGHT +}; + +/// Enumeration of PCM clock inversion +enum PCM_CLK_INV +{ + PCM_CLK_RISING_EDGE = 0, + PCM_CLK_FALLING_EDGE +}; + +/// Enumeration of PCM mode selection +enum PCM_MODE +{ + PCM_MODE_PCM = 0, + PCM_MODE_IOM +}; + +/// Enumeration of PCM bus speed +enum PCM_BUS_SPEED +{ + PCM_BUS_SPEED_128k = 0, + PCM_BUS_SPEED_256k, + PCM_BUS_SPEED_512k, + PCM_BUS_SPEED_1024k, + PCM_BUS_SPEED_2048k +}; + +/// Enumeration of PCM slot enable +enum PCM_SLOT +{ + PCM_SLOT_NONE = 0, + PCM_SLOT_0, + PCM_SLOT_0_1, + PCM_SLOT_0_2, + PCM_SLOT_0_3 +}; + +/// Enumeration of PCM word size +enum PCM_WORD_SIZE +{ + PCM_8_BITS = 0, + PCM_13_BITS, + PCM_14_BITS, + PCM_16_BITS +}; + +/// Enumeration of PCM DOUT pad configuration +enum PCM_DOUT_CFG +{ + PCM_OPEN_DRAIN = 0, + PCM_PUSH_PULL_HZ, + PCM_PUSH_PULL_0 +}; + +/// Enumeration of PCM FSYNC physical shape +enum PCM_FSYNC +{ + PCM_FSYNC_LF = 0, + PCM_FSYNC_FR, + PCM_FSYNC_FF, + PCM_FSYNC_LONG, + PCM_FSYNC_LONG_16 +}; + +const uint32_t pcm_setting[] = +{ +//pcm_general_ctrl + (PCM_DISABLE<= HAL_CHIP_METAL_ID_1) + { + BT_DRV_TRACE(1,"BT_DRV_CONFIG:accept_new_mobile enable=%d", bt_setting_2300p_t2[97]); + ret = bt_setting_2300p_t2[97]; + } + return ret; +} + +bool btdrv_get_page_pscan_coex_enable(void) +{ + bool ret = false; + if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) + { + BT_DRV_TRACE(1,"BT_DRV_CONFIG:page_pscan_coex enable=%d", bt_setting_2300p_t2[96]); + ret = bt_setting_2300p_t2[96]; + } + return ret; +} + +const uint8_t bt_edr_thr[] = +{ + 30,0,60,0,5,0,60,0,0,1, + 30,0,60,0,5,0,60,0,1,1, + 30,0,60,0,5,0,60,0,1,1, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +}; + +const uint8_t bt_edr_algo[]= +{ + 0,0,1, + 8,0,3, + 16,0,0, + 0xff,0xff,0xff, + 0xff,0xff,0xff, + 0xff,0xff,0xff, + 0xff,0xff,0xff, +}; + +const uint8_t bt_rssi_thr[]= +{ + -1, //high + -2, //low + -100, //interf +}; + + +const uint8_t ble_dle_dft_value[]= +{ + 0xfb,0x00, ///tx octets + 0x48,0x08, ///tx time + 0xfb,0x00, ///rx octets + 0x48,0x08, ///rx time +}; + + +uint8_t bt_lmp_record[]= +{ + 0, //en + 0, //only opcode +}; + + +static BTDRV_CFG_TBL_STRUCT btdrv_cfg_tbl[] = +{ + {BTDRV_CONFIG_INACTIVE,HCI_DBG_LMP_MESSAGE_RECORD_CMD_OPCODE,sizeof(bt_lmp_record),(uint8_t *)&bt_lmp_record}, + {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_LOCAL_FEATURE_CMD_OPCODE,sizeof(local_feature),local_feature}, + {BTDRV_CONFIG_INACTIVE,HCI_DBG_SET_BT_SETTING_CMD_OPCODE,sizeof(bt_setting_2300p),bt_setting_2300p}, + {BTDRV_CONFIG_INACTIVE,HCI_DBG_SET_BT_SETTING_CMD_OPCODE,sizeof(bt_setting_2300p_t2),bt_setting_2300p_t2}, + {BTDRV_CONFIG_INACTIVE,HCI_DBG_SET_BT_SETTING_EXT1_CMD_OPCODE,sizeof(bt_setting_ext1_2300p_t3),bt_setting_ext1_2300p_t3}, + {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_SLEEP_SETTING_CMD_OPCODE,sizeof(sleep_param),sleep_param}, + {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_CUSTOM_PARAM_CMD_OPCODE,189,(uint8_t *)&btdrv_rf_env_2300p}, + //{BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_CUSTOM_PARAM_CMD_OPCODE,sizeof(btdrv_afh_env),(uint8_t *)&btdrv_afh_env}, + // {BTDRV_CONFIG_INACTIVE,HCI_DBG_SET_LPCLK_DRIFT_JITTER_CMD_OPCODE,sizeof(lpclk_drift_jitter),(uint8_t *)&lpclk_drift_jitter}, + // {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_WAKEUP_TIME_CMD_OPCODE,sizeof(wakeup_timing),(uint8_t *)&wakeup_timing}, +#ifdef _SCO_BTPCM_CHANNEL_ + {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_SYNC_CONFIG_CMD_OPCODE,sizeof(sync_config),(uint8_t *)&sync_config}, + {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_PCM_SETTING_CMD_OPCODE,sizeof(pcm_setting),(uint8_t *)&pcm_setting}, +#endif + {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_RSSI_THRHLD_CMD_OPCODE,sizeof(bt_rssi_thr),(uint8_t *)&bt_rssi_thr}, + {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_LOCAL_EX_FEATURE_CMD_OPCODE,sizeof(local_ex_feature_page2),(uint8_t *)&local_ex_feature_page2}, + {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_BT_RF_TIMING_CMD_OPCODE,sizeof(bt_rf_timing),(uint8_t *)&bt_rf_timing}, + {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_BLE_RF_TIMING_CMD_OPCODE,sizeof(ble_rf_timing),(uint8_t *)&ble_rf_timing}, +}; + + +const static POSSIBLY_UNUSED BTDRV_CFG_TBL_STRUCT btdrv_cfg_tbl_2[] = +{ + +}; + +const static POSSIBLY_UNUSED uint32_t mem_config_2300p[][2] = +{ + +}; + +void bt_drv_digital_config_for_ble_adv(bool en) +{ +#ifdef __HW_AGC__ + btdrv_hw_agc_stop_mode(BT_SYNCMODE_REQ_USER_BLE,en); +#endif +} + +void btdrv_digital_config_init_2300p_t2(void) +{ + //common + BTDIGITAL_REG(0xd0350370)|= (1<<29);//lowpass flt enable + BTDIGITAL_REG(0xd0330038)|=(1<<11); //sel 26m sys + BTDIGITAL_REG(0xd0330038)&=0xffffff3f; //sel 26m sys + BTDIGITAL_REG(0xd03300f0)&=~0x1; // sel 26m sys + + BTDIGITAL_REG(0xd0350398)=0x6e4ef79c; + BTDIGITAL_REG(0xd03503a8)=0x15A64E88; + + //IBRT + BTDIGITAL_REG(0xd0220464) &= 0xdfffffff;//fast ack 2M mode dis + +#ifdef __FASTACK_ECC_ENABLE__ + BTDIGITAL_REG(0xd0220468)=0x04401914;//fast ack timings & fastlock en +#else + BTDIGITAL_REG(0xd0220468)=0x10423528;//fast ack timings +#endif //__FASTACK_ECC_ENABLE__ + +#ifdef __FA_RX_GAIN_CTRL__ + BTDIGITAL_REG(0xd0220080) &= 0xff00ffff; + BTDIGITAL_REG(0xd0220080) |= 0x00770000;//trx pwrup/dn + BTDIGITAL_REG(0xd02201e8)|=1;//second rf spi en + BTDIGITAL_REG(0xd0220480) = (BTDIGITAL_REG(0xd0220480)&(~0xff))|0xbf; + BTDIGITAL_REG(0xd0220484) = (BTDIGITAL_REG(0xd0220484)&(~0xffff))|0x9403; //lxd 20191102 fixed ecc receive gain to 1 level +#endif +#ifdef __CLK_GATE_DISABLE__ + BTDIGITAL_REG(0xD0330024) &=(~0x00020); + BTDIGITAL_REG(0xD0330024) |=0x40000; + BTDIGITAL_REG(0xD0330038) |=0x200000; +#endif +} + +void btdrv_digital_config_init_2300p_t1(void) +{ +#ifdef BT_RF_OLD_CORR_MODE + BTDIGITAL_REG(0xD03503A0)&=(~0x01); //clear bit 0 avoid slave lost data +#else + BTDIGITAL_REG(0xD03503A0)|=(0x01); +#endif + BTDIGITAL_REG(0x40000074)=0x00003100; + BTDIGITAL_REG(0x400000F0)=0xFFFF0002;//open slot en + + BTDIGITAL_REG(0xd0350240)=0x0001a407; + BTDIGITAL_REG(0xd03502c8)=0x00000080;//for old ramp + BTDIGITAL_REG(0xd03502cc)=0x00000015;//for old ramp + +#ifdef __HW_AGC__ + BTDIGITAL_REG(0xd0350208)=0x7fffffff; + btdrv_delay(10); + BTDIGITAL_REG(0xd0350228)=0x7f7fffff; + BTDIGITAL_REG(0xd03300f0)=0xffff0008;//hwagc config + BTDIGITAL_REG(0xd03503b8)=0x08000d80;//hwagc config +#endif + + BTDIGITAL_REG(0xd02201e8) = (BTDIGITAL_REG(0xd02201e8)&(~0x7c0))|0x380; + BTDIGITAL_REG(0xd0350360)=0x003fe040; + BTDIGITAL_REG(0xd0220470) |=0x40; + +#ifdef __CLK_GATE_DISABLE__ + BTDIGITAL_REG(0xD0330024) &=(~0x00020); + BTDIGITAL_REG(0xD0330024) |=0x40000; + BTDIGITAL_REG(0xD0330038) |=0x200000; +#endif + +#ifdef LBRT + BTDIGITAL_REG(0xd0350300) = 0x00000000; + BTDIGITAL_REG(0xd0350340) = 0x00000000; +#else +#ifdef __BDR_EDR_2DB__ + BTDIGITAL_REG(0xd0350300) = 0x55; + BTDIGITAL_REG(0xd0350308) = 0x00003C0F; +#else + BTDIGITAL_REG(0xd0350300) = 0x11; +#endif + BTDIGITAL_REG(0xd0350340) = 0x1; +#endif + //0x07 will affect Bluetooth sensitivity + //0x06 will lead to LBRT rx bad in close distance + BTDIGITAL_REG(0xd0350280) = 0x00000006; + BTDIGITAL_REG(0xd035031c) = 0x00050004;//modulation factor 17/16 + BTDIGITAL_REG(0xd0350320) = 0x00350011;//added by xrz 2018.10.10 + BTDIGITAL_REG(0xd0220080) = 0x0e571439;//trx pwrup/dn + BTDIGITAL_REG(0xd0220280) = 0x0e471445;//add by luobin 2019/05/23 + + BTDIGITAL_REG(0xd0350210) = 0x00f10040;//add by walker 2018/12/27 + BTDIGITAL_REG(0xd03502c4) = 0x127f02ef;// 2M TE time init + BTDIGITAL_REG(0xd0350284) = 0x02000200; + BTDIGITAL_REG_SET_FIELD(0xd0220200,7,0,3); + + BTDIGITAL_REG(0xd0350398)=0xD25EF79C; + BTDIGITAL_REG(0xd035039c)=0x60C6C061;//hwagc config + + BTDIGITAL_REG(0xd03503a8)=0x14666E88;//hwagc config + BTDIGITAL_REG(0xd0350364)=0x002EB948;//data sign and iq swap + BTDIGITAL_REG(0xd03503a0)=0x1c070055 ;//improve 1M RX sensitivity by jiangpeng + + //for system 2M Band Wide + BTDIGITAL_REG(0x4008003c)|=1; + BTDIGITAL_REG(0x40080018)|=1; + BTDIGITAL_REG(0x40080004)|=(1<<15)|(1<<30);//osc x4 enable + BTDIGITAL_REG(0xd0330038)|=(3<<6)|(1<<11); + BTDIGITAL_REG(0xd03300f0)|=1; + + //for IBRT fast ack + BTDIGITAL_REG(0xd0220464) |= 1<<29;//fast ack 2M mode enable + BTDIGITAL_REG(0xd0220468)=0x00403832;// 2M fast ack timings + BTDIGITAL_REG(0xd022046c)&=~(1<<31);//enable DM1 empty fastack + BTDIGITAL_REG(0xd035020C)=0x00f1002c; + BTDIGITAL_REG(0xD0350210)=0x00f1082c;//tx guard + BTDIGITAL_REG(0xd0220498)=0x00A01991;//fast ack timeout +} + +extern const uint8_t lmp_sniffer_filter_tab[51]; +extern const uint8_t lmp_ext_sniffer_filter_tab[18]; +extern const uint8_t lmp_ext_sniffer_fast_cfm_tab[4]; +void bt_drv_config_lmp_filter_table(void) +{ + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) + { + BTDIGITAL_REG(0xc0000300) = 0xc00070f4; + BT_DRV_TRACE(2,"%s: 0x%x",__func__, BTDIGITAL_REG(0xc0000300)); + memcpy((uint8_t *)(0xc00070f4), lmp_sniffer_filter_tab, sizeof(lmp_sniffer_filter_tab)); + } + else if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + BTDIGITAL_REG(0xc0000314+4) = 0xC0006e40; + memcpy((uint8_t *)(0xC0006e40), lmp_ext_sniffer_filter_tab, sizeof(lmp_ext_sniffer_filter_tab)); + BTDIGITAL_REG(0xc0000314+0xc) = 0xC0006c9c; + BT_DRV_TRACE(3, "%s: 0x%x, 0x%x",__func__, BTDIGITAL_REG(0xc0000314+4),BTDIGITAL_REG(0xc0000314+0xc)); + memcpy((uint8_t *)(0xC0006c9c), lmp_ext_sniffer_fast_cfm_tab, sizeof(lmp_ext_sniffer_fast_cfm_tab)); + } +} + +uint32_t ld_ibrt_sco_req_filter_patch[]= +{ + 0x7981b470,/*76c0*/ + 0xf1034b0b, + 0xe0020410, + 0x42a33304, + 0x785ad00c, + 0xd1f9428a, + 0x789a7a06, + 0xd1f54296, + 0x78da8946, + 0xd1f14296, + 0xe0002001, + 0xbc702000, + 0xbf004770, + 0xc0007450,//sniffer_sco_filter +}; + +void bt_drv_func_ld_ibrt_sco_req_filter(void) +{ + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + memcpy((uint32_t *)(0xc00076c0), ld_ibrt_sco_req_filter_patch, sizeof(ld_ibrt_sco_req_filter_patch)); + } +} + +extern void bt_drv_reg_op_controller_mem_log_config(void); +void btdrv_config_init(void) +{ + BT_DRV_TRACE(1,"%s",__func__); + + if (btdrv_get_lmp_trace_enable()) + { + //enable lmp trace + bt_lmp_record[0] = 1; + bt_lmp_record[1] = 1; + btdrv_cfg_tbl[0].is_act= BTDRV_CONFIG_ACTIVE; + ASSERT((btdrv_cfg_tbl[0].opcode == HCI_DBG_LMP_MESSAGE_RECORD_CMD_OPCODE), "lmp config not match"); + } + + if (btdrv_get_controller_trace_level() != BTDRV_INVALID_TRACE_LEVEL) + { + //enable controller trace + bt_setting_2300p[28] = btdrv_get_controller_trace_level(); + bt_setting_2300p_t2[28] = btdrv_get_controller_trace_level(); + } + + for(uint8_t i=0; i= HAL_CHIP_METAL_ID_1 && btdrv_cfg_tbl[i].parlen == sizeof(bt_setting_2300p_t2)) + { + btdrv_send_cmd(btdrv_cfg_tbl[i].opcode,btdrv_cfg_tbl[i].parlen,btdrv_cfg_tbl[i].param); + btdrv_delay(1); + } + } + + if(btdrv_cfg_tbl[i].opcode == HCI_DBG_SET_BT_SETTING_EXT1_CMD_OPCODE) + { + if(hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2 && btdrv_cfg_tbl[i].parlen == sizeof(bt_setting_ext1_2300p_t3)) + { + btdrv_send_cmd(btdrv_cfg_tbl[i].opcode,btdrv_cfg_tbl[i].parlen,btdrv_cfg_tbl[i].param); + btdrv_delay(1); + } + } + //BT other config + if(btdrv_cfg_tbl[i].is_act == BTDRV_CONFIG_ACTIVE) + { + btdrv_send_cmd(btdrv_cfg_tbl[i].opcode,btdrv_cfg_tbl[i].parlen,btdrv_cfg_tbl[i].param); + btdrv_delay(1); + } + } + + + //BT registers config + for(uint8_t i=0; i= HAL_CHIP_METAL_ID_0) + { + btdrv_digital_config_init_2300p_t1(); + if(hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) + { + btdrv_digital_config_init_2300p_t2(); + } + } + + if(btdrv_get_controller_trace_dump_enable()) + { + bt_drv_reg_op_controller_mem_log_config(); + } + + bt_drv_config_lmp_filter_table(); + bt_drv_func_ld_ibrt_sco_req_filter(); + bt_drv_set_fa_invert_enable(BT_FA_INVERT_EN); +} + +//zhangzhd agc config use default 1216 + +#define RX_GAIN_STEP0 -77 +#define RX_GAIN_STEP1 -72 +#define RX_GAIN_STEP2 -67 +#define RX_GAIN_STEP3 -62 +#define RX_GAIN_STEP4 -57 +#define RX_GAIN_STEP5 -52 +#define RX_GAIN_STEP6 -47 +//zhangzhd agc config use default 1216 end + +void bt_drv_adaptive_fa_rx_gain(int8_t rssi) +{ +#ifdef __FA_RX_GAIN_CTRL__ + uint8_t gain_step = 0xff; + static uint8_t old_step = 0xff; + + if(rssi <= RX_GAIN_STEP0) + { + gain_step = 0; + } + else if(rssi <= RX_GAIN_STEP1) + { + gain_step = 1; + } + else if(rssi <= RX_GAIN_STEP2) + { + gain_step = 2; + } + else if(rssi <= RX_GAIN_STEP3) + { + gain_step = 3; + } + else if(rssi <= RX_GAIN_STEP4) + { + gain_step = 4; + } + else if(rssi <= RX_GAIN_STEP5) + { + gain_step = 5; + } + else if(rssi <= RX_GAIN_STEP6) + { + gain_step = 6; + } + else + { + gain_step = 7; + } + + if(old_step != gain_step) + { + BT_DRV_TRACE(2,"if rssi = %d,then set fa %d level ",rssi,gain_step); + BT_DRV_REG_OP_ENTER(); + bt_drv_reg_op_fa_gain_direct_set(gain_step); + BT_DRV_REG_OP_EXIT(); + old_step = gain_step; + } +#endif +} + +bool btdrv_is_ecc_enable(void) +{ + bool ret = false; +#ifdef __FASTACK_ECC_ENABLE__ + ret = true; +#endif + return ret; +} + +#ifdef LAURENT_ALGORITHM +void btdrv_bt_laurent_algorithm_enable(void) +{ + if(hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) + { + BT_DRV_TRACE(1,"%s",__func__); + BTDIGITAL_REG(0xd03503a8)=0x14664E88; + BTDIGITAL_REG(0xd0350240)= 0x0001A40F; + BTDIGITAL_REG(0xd0350364)= 0x202EB948;//lau_gain + BTDIGITAL_REG(0xd0350374)= 0x00A40DCD;//c1c2 0x06001e0 + BTDIGITAL_REG(0xd0350228)= 0x12040800;//clkmode + BTDIGITAL_REG(0xd03503C8)= 0x00840CCD;//train c1c2 + BTDIGITAL_REG(0xd03503A0)= 0x1C070065;//new corr en + BTDIGITAL_REG(0xd0220460)= 0x039EF088;//mac laurent_en + BTDIGITAL_REG(0xd0350370)= 0x6B240A3D;//laurent_en 0x + BTDIGITAL_REG(0xd0350280)= 0x00000007;//bt_dfe_forcera + BTDIGITAL_REG(0xd03502C4)= 0x127F02E8;//te_timeinit + } +} + +void btdrv_ble_laurent_algorithm_enable(void) +{ + if(hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) + { + BT_DRV_TRACE(1,"%s",__func__); + BTDIGITAL_REG(0xd0350370)= 0x63240A3D;//lp disable + BTDIGITAL_REG(0xd0350280)= 0x00000007;//dfe_forceraw=0 psd_avgen=1 + } +} +#endif + +////////////////////////////////////////test mode//////////////////////////////////////////// + + + + +void btdrv_sleep_config(uint8_t sleep_en) +{ + sleep_param[0] = sleep_en; + btdrv_send_cmd(HCI_DBG_SET_SLEEP_SETTING_CMD_OPCODE,8,sleep_param); + btdrv_delay(1); +} + +void btdrv_feature_default(void) +{ + const uint8_t feature[] = {0xBF, 0xeE, 0xCD,0xFe,0xc3,0xFf,0x7b,0x87}; + btdrv_send_cmd(HCI_DBG_SET_LOCAL_FEATURE_CMD_OPCODE,8,feature); + btdrv_delay(1); +} + +const uint8_t test_mode_addr[6] = {0x77,0x77,0x77,0x77,0x77,0x77}; +void btdrv_test_mode_addr_set(void) +{ + return; + + btdrv_send_cmd(HCI_DBG_SET_BD_ADDR_CMD_OPCODE,sizeof(test_mode_addr),test_mode_addr); + btdrv_delay(1); +} + +uint8_t meInit_param_get_entry_idx = 0; + +int btdrv_meinit_param_init(void) +{ + int size = 0; + if ((me_init_param[0][0] == 0xffffffff) && + (me_init_param[0][1] == 0xffffffff)) + { + size = -1; + } + meInit_param_get_entry_idx = 0; + return size; +} + +int btdrv_meinit_param_remain_size_get(void) +{ + int remain_size; + if ((me_init_param[0][0] == 0xffffffff) && + (me_init_param[0][1] == 0xffffffff)) + { + return -1; + } + remain_size = ARRAY_SIZE(me_init_param) - meInit_param_get_entry_idx; + return remain_size; +} + +int btdrv_meinit_param_next_entry_get(uint32_t *addr, uint32_t *val) +{ + if (meInit_param_get_entry_idx > (ARRAY_SIZE(me_init_param) - 1)) + return -1; + *addr = me_init_param[meInit_param_get_entry_idx][0]; + *val = me_init_param[meInit_param_get_entry_idx][1]; + meInit_param_get_entry_idx++; + return 0; +} + +enum +{ + SYNC_IDLE, + SYNC_64_ORG, + SYNC_68_ORG, + SYNC_72_ORG, + SYNC_64_NEW, + SYNC_68_NEW, + SYNC_72_NEW, +}; + +enum +{ + SYNC_64_BIT, + SYNC_68_BIT, + SYNC_72_BIT, +}; + +uint32_t bt_sync_type = SYNC_IDLE; +void btdrv_sync_config(void) +{ + uint32_t corr_mode = BTDIGITAL_REG(0xd0220460); + uint32_t dfe_mode = BTDIGITAL_REG(0xd0350360); + uint32_t timeinit = BTDIGITAL_REG(0xd03502c4); + if(bt_sync_type == SYNC_IDLE) + return; + + corr_mode = (corr_mode & 0xfffffff8);//bit2: enh dfe; [1:0]: bt_corr_mode + dfe_mode = (dfe_mode & 0xffffffe0);//bit4: dfe_header_mode_bt; [3:0]: dfe_delay_cycle + timeinit = (timeinit & 0xfffff800);//[10:0]: tetimeinit value + + switch(bt_sync_type) + { + case SYNC_64_ORG: + corr_mode |= 0x0; + dfe_mode |= 0x00; + timeinit |= 0x2eb; + break; + case SYNC_68_ORG: + corr_mode |= 0x1; + dfe_mode |= 0x00; + timeinit |= 0x2eb; + break; + case SYNC_72_ORG: + corr_mode |= 0x2; + dfe_mode |= 0x00; + timeinit |= 0x2b7; + break; + case SYNC_64_NEW: + corr_mode |= 0x4; + dfe_mode |= 0x14; + timeinit |= 0x2eb; + break; + case SYNC_68_NEW: + corr_mode |= 0x5; + dfe_mode |= 0x14; + timeinit |= 0x2eb; + break; + case SYNC_72_NEW: + corr_mode |= 0x6; + dfe_mode |= 0x10; + timeinit |= 0x2b7; + break; + } + BTDIGITAL_REG(0xd0220460) = corr_mode; + BTDIGITAL_REG(0xd0350360) = dfe_mode; + BTDIGITAL_REG(0xd03502c4) = timeinit; +} +//HW SPI TRIG + +#define REG_SPI_TRIG_SELECT_LINK0_ADDR EM_BT_BT_EXT1_ADDR //114a+66 +#define REG_SPI_TRIG_SELECT_LINK1_ADDR (EM_BT_BT_EXT1_ADDR+BT_EM_SIZE) //11b8+66 +#define REG_SPI_TRIG_NUM_ADDR 0xd0220400 +#define REG_SPI0_TRIG_POS_ADDR 0xd0220454 +#define REG_SPI1_TRIG_POS_ADDR 0xd0220458 + +struct SPI_TRIG_NUM_T +{ + uint32_t spi0_txon_num:3;//spi0 number of tx rising edge + uint32_t spi0_txoff_num:3;//spi0 number of tx falling edge + uint32_t spi0_rxon_num:2;//spi0 number of rx rising edge + uint32_t spi0_rxoff_num:2;//spi0 number of rx falling edge + uint32_t spi0_fast_mode:1; + uint32_t spi0_gap:4; + uint32_t hwspi0_en:1; + uint32_t spi1_txon_num:3;//spi1 number of tx rising edge + uint32_t spi1_txoff_num:3;//spi1 number of tx falling edge + uint32_t spi1_rxon_num:2;//spi1 number of rx rising edge + uint32_t spi1_rxoff_num:2;//spi1 number of rx falling edge + uint32_t spi1_fast_mode:1; + uint32_t spi1_gap:4; + uint32_t hwspi1_en:1; +}; + +struct SPI_TRIG_POS_T +{ + uint32_t spi_txon_pos:7; + uint32_t spi_txoff_pos:9; + uint32_t spi_rxon_pos:7; + uint32_t spi_rxoff_pos:9; +}; + +struct spi_trig_data +{ + uint32_t reg; + uint32_t value; +}; + +static const struct spi_trig_data spi0_trig_data_tbl[] = +{ + //{addr,data([23:0])} + {0xd0220404,0x8080e9},//spi0_trig_txdata1 + {0xd0220408,0x000000},//spi0_trig_txdata2 + {0xd022040c,0x000000},//spi0_trig_txdata3 + {0xd0220410,0x000000},//spi0_trig_txdata4 +#ifdef __FA_RX_GAIN_CTRL__ + {0xd022041c,0x0094bf},//spi0_trig_rxdata1 +#else + {0xd022041c,0x000000},//spi0_trig_rxdata1 +#endif + {0xd0220420,0x000000},//spi0_trig_rxdata2 + {0xd0220424,0x000000},//spi0_trig_rxdata3 + {0xd0220428,0x000000},//spi0_trig_rxdata4 + {0xd0220414,0x000000},//spi0_trig_trxdata5 + {0xd0220418,0x000000},//spi0_trig_trxdata6 +}; + +static const struct spi_trig_data spi1_trig_data_tbl[] = +{ + //{addr,data([23:0])} +#ifdef __FA_RX_GAIN_CTRL__ + {0xd022042c,0x8080e9},//spi1_trig_txdata1 +#else + {0xd022042c,0x000000},//spi1_trig_txdata1 +#endif + {0xd0220430,0x000000},//spi1_trig_txdata2 + {0xd0220434,0x000000},//spi1_trig_txdata3 + {0xd0220438,0x000000},//spi1_trig_txdata4 +#ifdef __FA_RX_GAIN_CTRL__ + {0xd0220444,0x0094bf},//spi1_trig_rxdata1 +#else + {0xd0220444,0x000000},//spi1_trig_rxdata1 +#endif + {0xd0220448,0x000000},//spi1_trig_rxdata2 + {0xd022044c,0x000000},//spi1_trig_rxdata3 + {0xd0220450,0x000000},//spi1_trig_rxdata4 + {0xd022043c,0x000000},//spi1_trig_trxdata5 + {0xd0220440,0x000000},//spi1_trig_trxdata6 +}; + +void btdrv_spi_trig_data_change(uint8_t spi_sel, uint8_t index, uint32_t value) +{ + if(!spi_sel) + { + BTDIGITAL_REG(spi0_trig_data_tbl[index].reg) = value & 0xFFFFFF; + } + else + { + BTDIGITAL_REG(spi1_trig_data_tbl[index].reg) = value & 0xFFFFFF; + } +} + +void btdrv_spi_trig_data_set(uint8_t spi_sel) +{ + if(!spi_sel) + { + for(uint8_t i = 0; i < ARRAY_SIZE(spi0_trig_data_tbl); i++) + { + BTDIGITAL_REG(spi0_trig_data_tbl[i].reg) = spi0_trig_data_tbl[i].value; + } + } + else + { + for(uint8_t i = 0; i < ARRAY_SIZE(spi1_trig_data_tbl); i++) + { + BTDIGITAL_REG(spi1_trig_data_tbl[i].reg) = spi1_trig_data_tbl[i].value; + } + } +} + +void btdrv_spi_trig_num_set(uint8_t spi_sel, struct SPI_TRIG_NUM_T *spi_trig_num) +{ + uint8_t tx_onoff_total_num; + uint8_t rx_onoff_total_num; + + if(!spi_sel) + { + tx_onoff_total_num = spi_trig_num->spi0_txon_num + spi_trig_num->spi0_txoff_num; + rx_onoff_total_num = spi_trig_num->spi0_rxon_num + spi_trig_num->spi0_rxoff_num; + } + else + { + tx_onoff_total_num = spi_trig_num->spi1_txon_num + spi_trig_num->spi1_txoff_num; + rx_onoff_total_num = spi_trig_num->spi1_rxon_num + spi_trig_num->spi1_rxoff_num; + } + ASSERT((tx_onoff_total_num <= 6), "spi trig tx_onoff_total_num>6"); + ASSERT((rx_onoff_total_num <= 6), "spi trig rx_onoff_total_num>6"); + + BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) = *(uint32_t *)spi_trig_num; +} + +void btdrv_spi_trig_pos_set(uint8_t spi_sel, struct SPI_TRIG_POS_T *spi_trig_pos) +{ + if(!spi_sel) + { + BTDIGITAL_REG(REG_SPI0_TRIG_POS_ADDR) = *(uint32_t *)spi_trig_pos; + } + else + { + BTDIGITAL_REG(REG_SPI1_TRIG_POS_ADDR) = *(uint32_t *)spi_trig_pos; + } +} + +#ifdef __FA_RX_GAIN_CTRL__ +void btdrv_spi_trig_init(void) +{ + struct SPI_TRIG_NUM_T spi_trig_num; + struct SPI_TRIG_POS_T spi0_trig_pos; + struct SPI_TRIG_POS_T spi1_trig_pos; + + spi_trig_num.spi0_txon_num = 0; + spi_trig_num.spi0_txoff_num = 0; + spi_trig_num.spi0_rxon_num = 1; + spi_trig_num.spi0_rxoff_num = 0; + spi_trig_num.spi0_fast_mode = 0; + spi_trig_num.spi0_gap = 4; + spi_trig_num.hwspi0_en = 1; + + spi_trig_num.spi1_txon_num = 0; + spi_trig_num.spi1_txoff_num = 1; + spi_trig_num.spi1_rxon_num = 1; + spi_trig_num.spi1_rxoff_num = 0; + spi_trig_num.spi1_fast_mode = 0; + spi_trig_num.spi1_gap = 4; + spi_trig_num.hwspi1_en = 1; + + btdrv_spi_trig_num_set(0,&spi_trig_num); + btdrv_spi_trig_num_set(1,&spi_trig_num); + + spi0_trig_pos.spi_txon_pos = 0; + spi0_trig_pos.spi_txoff_pos = 0; + spi0_trig_pos.spi_rxon_pos = 25; + spi0_trig_pos.spi_rxoff_pos = 0; + + spi1_trig_pos.spi_txon_pos = 0; + spi1_trig_pos.spi_txoff_pos = 0; + spi1_trig_pos.spi_rxon_pos = 110; + spi1_trig_pos.spi_rxoff_pos = 0; + + btdrv_spi_trig_pos_set(0,&spi0_trig_pos); + btdrv_spi_trig_pos_set(1,&spi1_trig_pos); + + btdrv_spi_trig_data_set(0); + btdrv_spi_trig_data_set(1); +} +#else +void btdrv_spi_trig_init(void) +{ + struct SPI_TRIG_NUM_T spi_trig_num; + struct SPI_TRIG_POS_T spi0_trig_pos; + struct SPI_TRIG_POS_T spi1_trig_pos; + + spi_trig_num.spi0_txon_num = 0; + spi_trig_num.spi0_txoff_num = 1; + spi_trig_num.spi0_rxon_num = 0; + spi_trig_num.spi0_rxoff_num = 0; + spi_trig_num.spi0_fast_mode = 0; + spi_trig_num.spi0_gap = 4; + spi_trig_num.hwspi0_en = 0; + + spi_trig_num.spi1_txon_num = 0; + spi_trig_num.spi1_txoff_num = 0; + spi_trig_num.spi1_rxon_num = 0; + spi_trig_num.spi1_rxoff_num = 0; + spi_trig_num.spi1_fast_mode = 0; + spi_trig_num.spi1_gap = 0; + spi_trig_num.hwspi1_en = 0; + + btdrv_spi_trig_num_set(0,&spi_trig_num); + btdrv_spi_trig_num_set(1,&spi_trig_num); + + spi0_trig_pos.spi_txon_pos = 0; + spi0_trig_pos.spi_txoff_pos = 20; + spi0_trig_pos.spi_rxon_pos = 0; + spi0_trig_pos.spi_rxoff_pos = 0; + + spi1_trig_pos.spi_txon_pos = 0; + spi1_trig_pos.spi_txoff_pos = 0; + spi1_trig_pos.spi_rxon_pos = 0; + spi1_trig_pos.spi_rxoff_pos = 0; + + btdrv_spi_trig_pos_set(0,&spi0_trig_pos); + btdrv_spi_trig_pos_set(1,&spi1_trig_pos); + + btdrv_spi_trig_data_set(0); + btdrv_spi_trig_data_set(1); +} +#endif + +void btdrv_spi_trig_select(uint8_t link_id, bool spi_set) +{ + BTDIGITAL_BT_EM(EM_BT_BT_EXT1_ADDR+link_id*BT_EM_SIZE) |= (spi_set<<14); +} + +uint8_t btdrv_get_spi_trig_enable(uint8_t spi_sel) +{ + if(!spi_sel) + { + return ((BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) & 0x8000) >> 15); + } + else + { + return ((BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) & 0x80000000) >> 31); + } +} + +void btdrv_set_spi_trig_enable(uint8_t spi_sel) +{ + if(!spi_sel) + { + BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) |= (1<<15);//spi0 + } + else + { + BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) |= (1<<31);//spi1 + } +} + +void btdrv_clear_spi_trig_enable(uint8_t spi_sel) +{ + if(!spi_sel) + { + BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) &= ~0x8000; + } + else + { + BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) &= ~0x80000000; + } +} + +bool btdrv_get_lmp_trace_enable(void) +{ + return g_lmp_trace_enable; +} +void btdrv_set_lmp_trace_enable(void) +{ + g_lmp_trace_enable = true; +} +void btdrv_set_controller_trace_enable(uint8_t trace_level) +{ + g_controller_trace_level = trace_level; +} + +uint8_t btdrv_get_controller_trace_level(void) +{ + return g_controller_trace_level; +} + +void btdrv_fast_lock_config(bool fastlock_on) +{ + uint16_t val = 0; + + if (fastlock_on){ + btdrv_read_rf_reg(0x1AE, &val); + btdrv_write_rf_reg(0x1AE, val | (1 << 9) | (1 << 11)); + BTDIGITAL_REG(0xd0220468) |= 1 << 26; //fast lock enable + }else{ + btdrv_read_rf_reg(0x1AE, &val); + btdrv_write_rf_reg(0x1AE, val & (~((1 << 9) | (1 << 11)))); + BTDIGITAL_REG(0xd0220468) &= (~(1 << 26)); //fast lock disable + } +} + +#ifdef __FASTACK_ECC_ENABLE__ +void btdrv_ecc_config(void) +{ + #define INVALID 0xff + #define ECC_8PSK 0 + #define ECC_DPSK 1 + #define ECC_GFSK 2 + + #define ECC_1BLOCK 0 + #define ECC_2BLOCK 1 + #define ECC_3BLOCK 2 + + const uint32_t fa_2m = 0; + const uint32_t fastlock_on = 0; + const uint32_t bt_sys_52m_en = 0; + const uint32_t ecc_mode_enable = 0; + const uint32_t ecc_psk_mode = ECC_DPSK; + const uint32_t ecc_blk_mode = ECC_3BLOCK; + + if (bt_sys_52m_en){ + BTDIGITAL_REG(0x4008003c) |= 1; + BTDIGITAL_REG(0x40080018) |= 1; + BTDIGITAL_REG(0x40080004) |= (1 << 15) | (1 << 30); //osc x4 enable + BTDIGITAL_REG(0xd0330038) |= (3 << 6) | (1 << 11); + BTDIGITAL_REG(0xd03300f0) |= 1; + } + + if (fa_2m){ + BTDIGITAL_REG(0xd0220464) |= 1 << 29; //fast ack 2M mode enable 1, disable 0 + } + else{ + BTDIGITAL_REG(0xd0220464) &= (~(1 << 29)); //fast ack 2M mode enable 1, disable 0 + } + + //1302: RF 0x1AE[9] = 1; + //1402: RF 0x64[15] = 1; + + BTDIGITAL_REG(0xd0330038) |= (1 << 9); //jiangpeng test result ok + btdrv_fast_lock_config(fastlock_on); + if (fastlock_on){ + if (fa_2m) + BTDIGITAL_REG_SET_FIELD(0xd0220468, 0xffff, 0, 0x1914); + else + BTDIGITAL_REG_SET_FIELD(0xd0220468, 0xffff, 0, 0x1e14); + } + else{ + if (fa_2m) + BTDIGITAL_REG_SET_FIELD(0xd0220468, 0xffff, 0, 0x3530); + else + BTDIGITAL_REG_SET_FIELD(0xd0220468, 0xffff, 0, 0x3528); + } + + if (ecc_mode_enable){ + BTDIGITAL_REG(0xd0220464) |= (0x1 << 15); ////enable ecc mode + BTDIGITAL_REG(0xd0220464) &= ~(0x1F << 24); //ecc time adj + BTDIGITAL_REG(0xd0220464) |= (0x1 << 25); ////en ecc time adj + + if (ecc_psk_mode == ECC_8PSK){ + BTDIGITAL_REG_SET_FIELD(0xd02204a8, 3, 13, 3); //ECC 8PSK + } + else if (ecc_psk_mode == ECC_DPSK){ + BTDIGITAL_REG_SET_FIELD(0xd02204a8, 3, 13, 2); //ECC DPSK + } + else if (ecc_psk_mode == ECC_GFSK){ + BTDIGITAL_REG_SET_FIELD(0xd02204a8, 3, 13, 1); //ECC GFSK + } + + if (ecc_blk_mode == ECC_1BLOCK){ + BTDIGITAL_REG(0xd022048c) &= ~0x3ff; + BTDIGITAL_REG(0xd022048c) |= 0xef; //set ecc len ECC 1 block + } + else if (ecc_blk_mode == ECC_2BLOCK){ + BTDIGITAL_REG(0xd022048c) &= ~0x3ff; + BTDIGITAL_REG(0xd022048c) |= 0x1de; //set ecc len, ECC 2 block + } + else if (ecc_blk_mode == ECC_3BLOCK){ + BTDIGITAL_REG(0xd022048c) &= ~0x3ff; + BTDIGITAL_REG(0xd022048c) |= 0x2cd; //set ecc len ECC 3 block + } + } + else{ + BTDIGITAL_REG(0xd0220464) &= (~(0x1 << 15)); ////disable ecc mode + } +} +#endif + +void btdrv_hw_agc_stop_mode(enum BT_SYNCMODE_REQ_USER_T user, bool hw_agc_mode) +{ +#ifdef __HW_AGC__ + static uint8_t bt_syncmode_map = 0; + + uint32_t lock; + + lock = int_lock(); + uint32_t reg_val = BTDIGITAL_REG(0xd03503a8); + + if (hw_agc_mode) { + if (bt_syncmode_map == 0) { + //set bit28 0 : rx win timeout, stop agc + reg_val &= ~(1 << 28); + BTDIGITAL_REG(0xd03503a8) = reg_val; + } + bt_syncmode_map |= (1 << user); + } else { + bt_syncmode_map &= ~(1 << user); + if (bt_syncmode_map == 0) { + //set bit28 1 : sync find, stop agc + reg_val |= (1 << 28); + BTDIGITAL_REG(0xd03503a8) = reg_val; + } + } + int_unlock(lock); + +#endif +} diff --git a/platform/drivers/bt/best2300p/bt_drv_patch.c b/platform/drivers/bt/best2300p/bt_drv_patch.c new file mode 100644 index 0000000..7ddcfd7 --- /dev/null +++ b/platform/drivers/bt/best2300p/bt_drv_patch.c @@ -0,0 +1,7314 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "hal_i2c.h" +#include "hal_uart.h" +#include "hal_chipid.h" +#include "bt_drv.h" +#include "bt_drv_interface.h" +#include "bt_drv_2300p_internal.h" + +extern void btdrv_write_memory(uint8_t wr_type,uint32_t address,const uint8_t *value,uint8_t length); + +///enable m4 patch func +#define BTDRV_PATCH_EN_REG 0xe0002000 + +//set m4 patch remap adress +#define BTDRV_PATCH_REMAP_REG 0xe0002004 + +//instruction patch compare src address +#define BTDRV_PATCH_INS_COMP_ADDR_START 0xe0002008 + +#define BTDRV_PATCH_INS_REMAP_ADDR_START 0xc0000100 + +//data patch compare src address +#define BTDRV_PATCH_DATA_COMP_ADDR_START 0xe00020e8 + +#define BTDRV_PATCH_DATA_REMAP_ADDR_START 0xc00001e0 + + +#define BTDRV_PATCH_ACT 0x1 +#define BTDRV_PATCH_INACT 0x0 + +typedef struct +{ + uint8_t patch_index; //patch position + uint8_t patch_state; //is patch active + uint16_t patch_length; //patch length 0:one instrution replace other:jump to ram to run more instruction + uint32_t patch_remap_address; //patch occured address + uint32_t patch_remap_value; //patch replaced instuction + uint32_t patch_start_address; //ram patch address for lenth>0 + uint8_t *patch_data; //ram patch date for length >0 + +} BTDRV_PATCH_STRUCT; + +#ifdef IBRT +/*************************************************************************** + * + * instruction patch Information + * + * BT ROM Chip Version:1302 T3 (CHIP ID=2) + * + * IBRT function + * + * patch 2: 0xC00069a8--->0xC00069b0 + * patch 4: 0xC00069b8--->0xC00069d0 + * patch 5: 0xC00069d4--->0xC00069f0 + * patch 6: 0xC00069f8--->0xC0006a08 + * patch 7: 0xC0006a10--->0xC0006a24 + * patch 9: 0xC0006a2c--->0xC0006a4c + * patch 10: 0xC0006a54--->0xC0006a64 + * patch 11: 0xC0006a68--->0xC0006a90 + * patch 13: 0xC0006a98--->0xC0006b2c + * patch 15: 0xC0006b3c--->0xC0006b88 + * patch 16: 0xC0006b90--->0xC0006ba0 + * patch 17: 0xC0006ba4--->0xC0006bc0 + * patch 14: 0xC0006bc8--->0xC0006bdc + * patch 0: 0xC0006be4--->0xC0006c04 + * patch 1: 0xC0006c0c--->0xC0006c24 + * patch 2: 0xC0006c34--->0xC0006c80 + * patch 3: 0xC0006c88--->0xC0006c94 + * lmp_ext_sniffer_fast_cfm_tab: 0xC0006c9c --->0xC0006ca4 + + * patch 18: 0xC0006cbc--->0xC0006d10 DEBUG_PATCH + * patch 19: 0xC0006d14--->0xC0006dbc + * patch 20: 0xC0006dc4--->0xC0006df4 + * patch 21: 0xC0006e00--->0xC0006e2c + * patch 22: 0xC0006e34--->0xC0006e38 + * lmp_ext_sniffer_filter_tab: 0xC0006e40 --->0xC0006e54 + * patch 2a: 0xC0006e5c--->0xC0006e70 + * patch 24: 0xC0006e78--->0xC0006e88 + * patch 25: 0xC0006e94--->0xC0006ea4 + * patch 29: 0xC0006eb0--->0xC0006ec4 + * patch 30: 0xC0006ecc--->0xC0006ef0 + * patch 31: 0xC0006ef8--->0xC0006f08 + * patch 32: 0xC0006f0c--->0xC0006f18 + * patch 33: 0xc0006f20--->0xc0006f50 + * patch 34: 0xc0006f58--->0xc0006f64 + * patch 35: 0xc0006f70--->0xc0006f90 + * patch 49: 0xc0006f98--->0xc0006fac + * patch 36: 0xc0006fc0--->0xc0007034 + * patch 37: 0xc0007050--->0xc0007328 + * patch 37: 0xc000732c--->0xc0007348 + * patch 44: 0xc0007460--->0xc0007500 + + patch_ld_ibrt_sco_req_filter: c0007670--->c0007670 + ****************************************************************************/ +//#define BT_CONTROLLER_DEBUG 1 + +const uint32_t bes2300p_patch0_ibrt_ins_data_t3[] = +{ + 0x400fe92d, /*0xc0007758L*/ + 0xf0004630, /*0xc000775cL*/ + 0xe8bdf805, /*0xc0007760L*/ + 0xf634400f, /*0xc0007764L*/ + 0x0000bb51, /*0xc0007768L*/ + 0x4604b510, /*0xc000776cL*/ + 0x47984b0c, /*0xc0007770L*/ + 0x60184b0c, /*0xc0007774L*/ + 0x781b3304, /*0xc0007778L*/ + 0x2b03b2db, /*0xc000777cL*/ + 0x2c02d005, /*0xc0007780L*/ + 0x2c10d009, /*0xc0007784L*/ + 0x2004d10a, /*0xc0007788L*/ + 0x4b07e006, /*0xc000778cL*/ + 0xb2db781b, /*0xc0007790L*/ + 0x70134a06, /*0xc0007794L*/ + 0x2002e7f3, /*0xc0007798L*/ + 0x47984b05, /*0xc000779cL*/ + 0xbf00bd10, /*0xc00077a0L*/ + 0xa0026ded, /*0xc00077a4L*/ + 0xc000653c, /*0xc00077a8L*/ + 0xc00064da, /*0xc00077acL*/ + 0xc0006541, /*0xc00077b0L*/ + 0xa003bcc1, /*0xc00077b4L*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch0 = +{ + 0, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch0_ibrt_ins_data_t3), + 0x0003bdc0, + 0xbccaf1cb, + 0xc0007758, + (uint8_t *)bes2300p_patch0_ibrt_ins_data_t3 +};//ibrt sco auto accept (slave) + +const uint32_t bes2300p_patch1_ibrt_ins_data_t3[] = +{ + 0x681b4b08, + 0xf632b933, + 0x2800ffdb, + 0x2001bf0c, + 0xe0002004, + 0xf6352001, + 0x2000f84d, + 0x60184b01, + 0xb809f60a, + 0xc0007434,/*6c30*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch1 = +{ + 1, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch1_ibrt_ins_data_t3), + 0x00010c3c, + 0xbfe6f1f5, + 0xc0006c0c, + (uint8_t *)bes2300p_patch1_ibrt_ins_data_t3 +};//ibrt sco auto accept (master) + +const uint32_t bes2300p_patch2_ibrt_ins_data_t3[] = +{ + 0x4b04b508, + 0x2b01681b, + 0x2001d102, + 0xfb00f5fa, + 0xbf00bd08, + 0xc0007668, + 0xfd56f60d, + 0xfff0f7ff, + 0xbe7af60f,/*6c58*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch2 = +{ + 2, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch2_ibrt_ins_data_t3), + 0x0001694c, + 0xb980f1f0, + 0xc0006c38, + (uint8_t *)bes2300p_patch2_ibrt_ins_data_t3 +};// tws unsniff update ke state + +const uint32_t bes2300p_patch3_ibrt_ins_data_t3[] = +{ + 0xbf004628, + 0xfdc4f60d, + 0x21144628, + 0xba4af60f,/*6c94*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch3 = +{ + 3, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch3_ibrt_ins_data_t3), + 0x00016128, + 0xbdaef1f0, + 0xc0006c88, + (uint8_t *)bes2300p_patch3_ibrt_ins_data_t3 +};//start lmp to before sending LMP_HostConnectionReq + +const uint32_t bes2300p_patch4_ibrt_ins_data_t3[] = +{ + 0xf633b940,/*69b8*/ + 0x2801f86d, + 0xf633d104, + 0x2800f903, + 0xbf00d102, + 0xbd84f62b, + 0xbe02f62b,/*69d0*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch4 = +{ + 4, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch4_ibrt_ins_data_t3), + 0x000324d4, + 0xba70f1d4, + 0xc00069b8, + (uint8_t *)bes2300p_patch4_ibrt_ins_data_t3 +};//filter afh map + +const uint32_t bes2300p_patch5_ibrt_ins_data_t3[] = +{ + 0x79ab4688,/*69d4*/ + 0x6383ea6f, + 0x4578f023, + 0xf8d39b09, + 0x9906308c, + 0x402b440b, + 0xbf004641, + 0xb8bdf62d,/*69f0*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch5 = +{ + 5, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch5_ibrt_ins_data_t3), + 0x00033b60, + 0xbf38f1d2, + 0xc00069d4, + (uint8_t *)bes2300p_patch5_ibrt_ins_data_t3 +};//sco param init + +const uint32_t bes2300p_patch6_ibrt_ins_data_t3[] = +{ + 0x4a033304,/*69f8*/ + 0xbf008153, + 0x12c4f640, + 0xbeb9f632, + 0xc00062c0,/*6a08*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch6 = +{ + 6, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch6_ibrt_ins_data_t3), + 0x00039770, + 0xb942f1cd, + 0xc00069f8, + (uint8_t *)bes2300p_patch6_ibrt_ins_data_t3 +};//pscan duration + +const uint32_t bes2300p_patch7_ibrt_ins_data_t3[] = +{ + 0x71ab2300,/*6a10*/ + 0x0000f8d9, + 0x380cb110, + 0xf8f6f5fa, + 0xbf002300, + 0xbf3ef608,/*6a24*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch7 = +{ + 7, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch7_ibrt_ins_data_t3), + 0x0000f8a0, + 0xb8b6f1f7, + 0xc0006a10, + (uint8_t *)bes2300p_patch7_ibrt_ins_data_t3 +};//lm_page_scan_end_ind free msg + +const uint32_t bes2300p_patch8_ibrt_ins_data_t3[] = +{ + 0xf8862001, + 0xf8860060, + 0xbf000061, + 0xbba3f611, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch8 = +{ + 8, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch8_ibrt_ins_data_t3), + 0x00018f1c, + 0xbc62f1ee, + 0xc00077e4, + (uint8_t *)bes2300p_patch8_ibrt_ins_data_t3 +};//ignore 0x5d sm + +const uint32_t bes2300p_patch9_ibrt_ins_data_t3[] = +{ + 0xf62a4628,/*6a2c*/ + 0x4620fef7, + 0xff76f60f, + 0xf8534b04, + 0x46203025, + 0x135ef893, + 0xfc68f5fa, + 0xbd702000, + 0xc0005de4,/*6a4c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch9 = +{ + 9, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch9_ibrt_ins_data_t3), + 0x0002347c, + 0xbad6f1e3, + 0xc0006a2c, + (uint8_t *)bes2300p_patch9_ibrt_ins_data_t3 +}; + +const uint32_t bes2300p_patch10_ibrt_ins_data_t3[] = +{ + 0x0818f104, + 0xbb9ff634, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch10 = +{ + 10, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch10_ibrt_ins_data_t3), + 0x0003b184, + 0xbc66f1cb, + 0xc0006a54, + (uint8_t *)bes2300p_patch10_ibrt_ins_data_t3 +};//set afh + +const uint32_t bes2300p_patch11_ibrt_ins_data_t3[] = +{ + 0xf8934b09,/*6a68*/ + 0xf0133084, + 0xd0050f06, + 0xf6374620, + 0x4601f805, + 0xe0052400, + 0xf8934b03, + 0xbf003084, + 0xb941f636, + 0xb987f636, + 0xc0006568,/*6a90*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch11 = +{ + 11, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch11_ibrt_ins_data_t3), + 0x0003cd08, + 0xbeaef1c9, + 0xc0006a68, + (uint8_t *)bes2300p_patch11_ibrt_ins_data_t3 +};// set ble adv data + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch12 = +{ + 12, + BTDRV_PATCH_ACT, + 0, + 0x0003cbf0, + 0xbf00e004, + 0, + NULL +};// set ble scan response data + +const uint32_t bes2300p_patch13_ibrt_ins_data_t3[] = +{ + /*6a98*/ 0x99049803, + /*6a9c*/ 0x4b12b470, + /*6aa0*/ 0x010e5c5a, + /*6aa4*/ 0x19734d11, + /*6aa8*/ 0x78244c11, + /*6aac*/ 0xd20342a2, + /*6ab0*/ 0x32015498, + /*6ab4*/ 0xe001b2d2, + /*6ab8*/ 0x22015570, + /*6abc*/ 0x5442480a, + /*6ac0*/ 0x461ab14c, + /*6ac4*/ 0x23001919, + /*6ac8*/ 0x0b01f912, + /*6acc*/ 0xbf004403, + /*6ad0*/ 0xd1f9428a, + /*6ad4*/ 0x2300e000, + /*6ad8*/ 0xf0f4fb93, + /*6adc*/ 0xbc70b240, + /*6ae0*/ 0x22019904, + /*6ae4*/ 0xba00f626, //jump a0206ae4 -> a002cee8 + /*6ae8*/ 0xc0006af8, //addr of rssi_idx_for_agc + /*6aec*/ 0xc0006afc, //addr of rssi_set_for_agc + /*6af0*/ 0xc0006af4, //addr of N + /*6af4*/ 0x00000005, //N : 1 ~ 16 + /*6af8*/ 0x00000000, //rssi_idx_for_agc[3] + /*6afc*/ 0xbabababa, //rssi_set_for_agc[3*16] + /*6b00*/ 0xbabababa, + /*6b04*/ 0xbabababa, + /*6b08*/ 0xbabababa, + /*6b0c*/ 0xbabababa, + /*6b10*/ 0xbabababa, + /*6b14*/ 0xbabababa, + /*6b18*/ 0xbabababa, + /*6b1c*/ 0xbabababa, + /*6b20*/ 0xbabababa, + /*6b24*/ 0xbabababa, + /*6b28*/ 0xbabababa, + /*6b2c*/ 0xbabababa, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch13 = +{ + 13, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch13_ibrt_ins_data_t3), + 0x0002cee4, + 0xbdd8f1d9, //jump a002cee4 -> a0206a98 + 0xc0006a98, + (uint8_t *)bes2300p_patch13_ibrt_ins_data_t3 +};//ld_acl_rx() average rssi + +const uint32_t bes2300p_patch14_ibrt_ins_data_t3[] = +{ + 0x305af893, + 0xd1032b00, + 0x12f4f240, + 0xbf00e002, + 0x32b8f640, + 0xbe30f60d,/*6bdc*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch14 = +{ + 14, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch14_ibrt_ins_data_t3), + 0x0001483c, + 0xb9c4f1f2, + 0xc0006bc8, + (uint8_t *)bes2300p_patch14_ibrt_ins_data_t3 +};//lmp to 5s before connection cmp sent + +const uint32_t bes2300p_patch15_ibrt_ins_data_t3[] = +{ + 0x2028f843,/*6b3c*/ + 0xf8434b08, + 0x4b052028, + 0x4b0e701a, + 0x2201701a, + 0xf8434b08, + 0xbf002028, + 0xba32f624, + 0xc0006b60, + 0x00000000, + 0xc0006b68, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0006b78, + 0x00000001, + 0x00000001, + 0x00000001, + 0xc0006b88, + 0x00000000,/*6b88*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch15 = +{ + 15, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch15_ibrt_ins_data_t3), + 0x0002afbc, + 0xbdbef1db, + 0xc0006b3c, + (uint8_t *)bes2300p_patch15_ibrt_ins_data_t3 +};//sync clear count + +const uint32_t bes2300p_patch16_ibrt_ins_data_t3[] = +{ + 0x0046f894,/*6b90*/ + 0xfe94f625, + 0xd8012802, + 0xba3ef629, + 0xba57f629,/*6ba0*/ +}; +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch16 = +{ + 16, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch16_ibrt_ins_data_t3), + 0x00030014, + 0xbdbcf1d6, + 0xc0006b90, + (uint8_t *)bes2300p_patch16_ibrt_ins_data_t3 +};//ld_sco_evt_start_cbk + +const uint32_t bes2300p_patch17_ibrt_ins_data_t3[] = +{ + 0xf6062002,/*6ba4*/ + 0x2802f937, + 0xf898d108, + 0xf62500b2, + 0x2802fe85, + 0xbf00d802, + 0xbc93f629, + 0xbc98f629,/*6bc0*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch17 = +{ + 17, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch17_ibrt_ins_data_t3), + 0x000304d4, + 0xbb66f1d6, + 0xc0006ba4, + (uint8_t *)bes2300p_patch17_ibrt_ins_data_t3 +};//ld_calculate_event_timestamp + +#ifdef BT_CONTROLLER_DEBUG +const uint32_t bes2300p_patch18_ibrt_ins_data_t3[] = +{ + 0x68124a0e, + 0x2084f8c3, + 0x68124a0d, + 0x2088f8c3, + 0x68124a0c, + 0x208cf8c3, + 0x68124a0b, + 0x2090f8c3, + 0x68124a0a, + 0x2094f8c3, + 0x68124a09, + 0x2098f8c3, + 0x68124a08, + 0x209cf8c3, + 0xbf004770, + 0xe000ed04, + 0xe000ed0c, + 0xe000ed10, + 0xe000ed14, + 0xe000ed24, + 0xe000ed3c, + 0xe000ed34,/*6d10*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch18 = +{ + 18, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch18_ibrt_ins_data_t3), + 0x000077fc, + 0xba5ef1ff, + 0xc0006cbc, + (uint8_t *)bes2300p_patch18_ibrt_ins_data_t3 +};//correct crash dump +#else +const uint32_t bes2300p_patch18_ibrt_ins_data_t3[] = +{ + 0x2271f240,/*6cc0*/ + 0x4080f8b0,/*6cc4*/ + 0xb9f9f63f, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch18 = +{ + 18, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch18_ibrt_ins_data_t3), + 0x000460ac, + 0xbe08f1c0, + 0xc0006cc0, + (uint8_t *)bes2300p_patch18_ibrt_ins_data_t3 + +};//BT avoid ble +#endif + +const uint32_t bes2300p_patch19_ibrt_ins_data_t3[] = +{ + 0x4603b508, + 0x8210f3ef, + 0x0f01f012, + 0xb672d112, + 0xf5a34811, + 0x3b285343, + 0xfba14910, + 0xf3c32303, + 0xeb032387, + 0xeb000343, + 0x31940183, + 0xfdd0f5fc, + 0xbd08b662, + 0xf5a34808, + 0x3b285343, + 0xfba14907, + 0xf3c32303, + 0xeb032387, + 0xeb000343, + 0x31940183, + 0xfdbef5fc, + 0xbf00bd08, + 0xc0005b4c, + 0xff00ff01, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch19 = +{ + 19, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch19_ibrt_ins_data_t3), + 0x00008b24, + 0xb8f8f1fe, + 0xc0006d18, + (uint8_t *)bes2300p_patch19_ibrt_ins_data_t3 +};//add lock interrupt when free acl buf + +const uint32_t bes2300p_patch20_ibrt_ins_data_t3[] = +{ + 0x460cb510, + 0xfafaf5fa, + 0xd9042870, + 0x007ef1b4, + 0x2001bf18, + 0x2000bd10, + 0xbf00bd10, + 0xf7ff4621, + 0x2800ffef, + 0x4628d104, + 0xfae8f5fa, + 0xbd9af61c, + 0xb85ff61d,/*6df4*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch20 = +{ + 20, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch20_ibrt_ins_data_t3), + 0x00023924, + 0xba5cf1e3, + 0xc0006dc4, + (uint8_t *)bes2300p_patch20_ibrt_ins_data_t3 +};//protect ext3 lmp tx cfm + +const uint32_t bes2300p_patch21_ibrt_ins_data_t3[] = +{ + 0x2040f897,/*6e00*/ + 0xd1112a01, + 0x0109f106, + 0xf5fc4608, + 0x2813fd4b, + 0x221ed802, + 0xbc54f614, + 0x2a017a32, + 0xf614d801, + 0x221ebbf6, + 0xbc4cf614, + 0xbc47f614,/*6e2c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch21 = +{ + 21, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch21_ibrt_ins_data_t3), + 0x0001b604, + 0xbbfcf1eb, + 0xc0006e00, + (uint8_t *)bes2300p_patch21_ibrt_ins_data_t3 +};//reject set afh lmp when channel number less than 20 + +const uint32_t bes2300p_patch22_ibrt_ins_data_t3[] = +{ + 0x2202729a,/*6e34*/ + 0xbd38719a,/*6e38*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch22 = +{ + 22, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch22_ibrt_ins_data_t3), + 0x00011c90, + 0xb8d0f1f5, + 0xc0006e34, + (uint8_t *)bes2300p_patch22_ibrt_ins_data_t3 +};//update sco sync type + +const uint32_t bes2300p_patch2a_ibrt_ins_data_t3[] = +{ + /*6e5c*/ 0xb10b4b04, + /*6e60*/ 0xbb84f615, //jump a001c56c + /*6e64*/ 0x783b2300, + /*6e68*/ 0x0301f003, + /*6e6c*/ 0xbb5ef615, //jump a001c52c + /*6e70*/ 0x00000000, //reject sniff +};//LMP_MSG_HANDLER(sniff_req) LC_CONNECTED + +const uint32_t bes2300p_patch23_ibrt_ins_data_t3[] = +{ + 0xf9c6f632,/*7744*/ + 0x02194603, + 0x417ff401, + 0xbeeff632,/*7750*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch23 = +{ + 23, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch23_ibrt_ins_data_t3), + 0x0003a52c, + 0xb90af1cd, + 0xc0007744, + (uint8_t *)bes2300p_patch23_ibrt_ins_data_t3 +};//fix sco success index + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch24 = +{ + 24, + BTDRV_PATCH_ACT, + 0, + 0x00002490, + 0xbf00e012, + 0, + NULL, +};//stop ibrt directly + +const uint32_t bes2300p_patch25_ibrt_ins_data_t3[] = +{ + 0x2a020a02, + 0xbf00d804, + 0x427ff400, + 0xbf44f61c, + 0xb807f61d, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch25 = +{ + 25, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch25_ibrt_ins_data_t3), + 0x00023d28, + 0xb8b4f1e3, + 0xc0006e94, + (uint8_t *)bes2300p_patch25_ibrt_ins_data_t3 +};//enc update2 idx error + +#if 1 +const uint32_t bes2300p_patch26_ibrt_ins_data_t3[] = +{ + 0x68134a05, + 0x2380f043, + 0xf5a26013, + 0x68137206, + 0x0301f043, + 0xbd386013, + 0xd0220400, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch26 = +{ + 26, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch26_ibrt_ins_data_t3), + 0x00048200, + 0xba8ef1bf, + 0xc0007720, + (uint8_t *)bes2300p_patch26_ibrt_ins_data_t3 +};//enable hw spiin BLE lld_evt_rx_isr + +#elif 0 +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch26 = +{ + 26, + BTDRV_PATCH_ACT, + 0, + 0x00013f44, + 0xbf00bd38, + 0, + NULL +};//assert +#else +const uint32_t bes2300p_patch26_ibrt_ins_data_t3[] = +{ + 0xf6324607, + 0xb120fa87, + 0x63a6f640, + 0xf63e827b, + 0x4638bd94, + 0x2080f8d0, + 0xbd86f63e, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch26 = +{ + 26, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch26_ibrt_ins_data_t3), + 0x000461dc, + 0xba6cf1c1, + 0xc00076b8, + (uint8_t *)bes2300p_patch26_ibrt_ins_data_t3 +};//ble con slave duration in snoop mode +#endif + +#if defined(SYNC_BT_CTLR_PROFILE) +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch27 = +{ + 27, + BTDRV_PATCH_ACT, + 0, + 0x000187b8, + 0x4628b123, + 0, + NULL +};//send profile via ble +#else +const uint32_t bes2300p_patch27_ibrt_ins_data_t3[] = +{ + 0xfe88f632, + 0xffe8f7ff, + 0xb9a2f625,/*6c68*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch27 = +{ + 27, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch27_ibrt_ins_data_t3), + 0x0002bfac, + 0xbe58f1da, + 0xc0006c60, + (uint8_t *)bes2300p_patch27_ibrt_ins_data_t3 +};//disconnect update ke state +#endif + +#if 1 +// for ble master update con param with large winsize +const uint32_t bes2300p_patch28_ibrt_ins_data_t3[] = +{ + 0x4630bf00, + 0x109ef894, + 0xf958f63f, + 0x309cf894, + 0x2271f240, + 0x0003fb02, + 0xbcf1f63f, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch28 = +{ + 28, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch28_ibrt_ins_data_t3), + 0x000471e4, + 0xbb08f1c0, + 0xc00077f8, + (uint8_t *)bes2300p_patch28_ibrt_ins_data_t3 +}; +#else +// only for search UI +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch28 = +{ + 28, + BTDRV_PATCH_ACT, + 0, + 0x0000e47a, + 0xe0027b20, + 0, + NULL +};//lm_inq_res_ind_handler() rssi +#endif + +const uint32_t bes2300p_patch29_ibrt_ins_data_t3[] = +{ + 0xf8934b04, + 0x2b0231c2, + 0x230fbf0c, + 0x75ab2314, + 0xbac2f629, + 0xc0005ea8,/*6ec4*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch29 = +{ + 29, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch29_ibrt_ins_data_t3), + 0x00030444, + 0xbd34f1d6, + 0xc0006eb0, + (uint8_t *)bes2300p_patch29_ibrt_ins_data_t3 +};///fix acl interv priority + +const uint32_t bes2300p_patch30_ibrt_ins_data_t3[] = +{ + 0xd80a2802, + 0x4b05b508, + 0x3020f853, + 0xf893b123, + 0x220510c4, + 0xfe86f61d, + 0x4770bd08, + 0xc00009d4, + 0xffeef7ff, + 0xbda8f634,/*6ef0*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch30 = +{ + 30, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch30_ibrt_ins_data_t3), + 0x0003ba40, + 0xba54f1cb, + 0xc0006ecc, + (uint8_t *)bes2300p_patch30_ibrt_ins_data_t3 +};///send max slot req when start ibrt + +const uint32_t bes2300p_patch31_ibrt_ins_data_t3[] = +{ + 0xf632b920, + 0x2800fdc1, + 0xbf00d002, + 0xbb3af629, + 0xbba2f629,/*6f08*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch31 = +{ + 31, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch31_ibrt_ins_data_t3), + 0x00030578, + 0xbcbef1d6, + 0xc0006ef8, + (uint8_t *)bes2300p_patch31_ibrt_ins_data_t3 +};//modify start ibrt timing + +#if 0//def BT_CONTROLLER_DEBUG +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch32= +{ + 32, + BTDRV_PATCH_ACT, + 0, + 0x00000348, + 0xbf00e005, + 0, + NULL +};///lmp trace +#else + +const uint32_t bes2300p_patch32_ibrt_ins_data_t3[] = +{ + 0xfe4af5f9, + 0xbf002300, + 0x30c8f884, + 0xbaf8f624,/*6f18*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch32 = +{ + 32, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch32_ibrt_ins_data_t3), + 0x0002b508, + 0xbd00f1db, + 0xc0006f0c, + (uint8_t *)bes2300p_patch32_ibrt_ins_data_t3 +};///role switch fail +#endif + +const uint32_t bes2300p_patch33_ibrt_ins_data_t3[] = +{ + 0x2300b430, + 0x4d072103, + 0x4290b2da, + 0xf855d004, + 0x2c004023, + 0x4611bf18, + 0x2b033301, + 0x4608d1f4, + 0x4770bc30, + 0xc00009d4,/*6f50*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch33 = +{ + 33, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch33_ibrt_ins_data_t3), + 0x0002c8c0, + 0xbb2ef1da, + 0xc0006f20, + (uint8_t *)bes2300p_patch33_ibrt_ins_data_t3 +};//find_other_acl_link + +const uint32_t bes2300p_patch34_ibrt_ins_data_t3[] = +{ + 0xfe38f632, + 0xd0052800, + 0xbf002002, + 0xfcb0f61c, + 0xbb2ff634, + 0xbb25f634,/*6f6c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch34 = +{ + 34, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch34_ibrt_ins_data_t3), + 0x0003b5b4, + 0xbcd0f1cb, + 0xc0006f58, + (uint8_t *)bes2300p_patch34_ibrt_ins_data_t3 +};//do not trans afh after IBRT switch + +const uint32_t bes2300p_patch35_ibrt_ins_data_t3[] = +{ + 0xfd92f632,/*6f70*/ + 0xd1092801, + 0xfe28f632, + 0xd0052800, + 0xfd9cf632, + 0xd10142a0, + 0xbc77f611, + 0x68294620, + 0xbc70f611,/*6f90*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch35 = +{ + 35, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch35_ibrt_ins_data_t3), + 0x00018870, + 0xbb7ef1ee, + 0xc0006f70, + (uint8_t *)bes2300p_patch35_ibrt_ins_data_t3 +};//acl data tx cfm + +const uint32_t bes2300p_patch36_ibrt_ins_data_t3[] = +{ + 0x460db538, + 0x78034614, + 0x7842085b, + 0x2b7f78c1, + 0x2a01d10a, + 0x290dd11e, + 0xf632d11c, + 0x4601fd45, + 0xf6342000, + 0xe015ff1f, + 0xd1132b03, + 0xd1112a18, + 0xd80f2d02, + 0xf6104628, + 0xb158fcb3, + 0x3047f890, + 0xd1072b02, + 0xf62a4628, + 0x0228fc0b, + 0x0001f040, + 0xfc88f60f, + 0x000cf1a4, + 0xfdf8f5f9, + 0xbf00bd38, + 0xd1072800, + 0x4620bf00, + 0x46524639, + 0xffc8f7ff, + 0xbbd8f61a, + 0xbb62f61a,/*7034*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch36 = +{ + 36, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch36_ibrt_ins_data_t3), + 0x000216f8, + 0xbc92f1e5, + 0xc0006fc0, + (uint8_t *)bes2300p_patch36_ibrt_ins_data_t3 +};//lmp filter + +const uint32_t bes2300p_patch37_ibrt_ins_data_t3[] = +{ + 0x47f0e92d,/*7050*/ + 0x4b97b082, + 0x236e5c1e, + 0xf300fb03, + 0x5a9b4a95, + 0x4f00f413, + 0x8120f040, + 0x46044689, + 0x1800ea4f, + 0xeb084f91, + 0x4b910507, + 0xa020f853, + 0xf8524a90, + 0x33013020, + 0x3020f842, + 0xf860f635, + 0x42a04601, + 0x8088f040, + 0xf8534b8a, + 0x4b8a2024, + 0x429a681b, + 0xf8dad817, + 0xebc22084, + 0xf0230309, + 0xf1b34378, + 0xd9046f80, + 0x0302ebc9, + 0x4378f023, + 0x4a82425b, + 0x0024f852, + 0x68124a81, + 0xf200fb02, + 0xf2404293, + 0x4b7f80eb, + 0x3000f993, + 0x4b7eb9c3, + 0xc000f893, + 0x0f00f1bc, + 0x462ad00a, + 0x0e0ceb05, + 0xf9122300, + 0x44030b01, + 0xd1fa4572, + 0xe0014662, + 0x46132200, + 0xfcfcfb93, + 0xf8804872, + 0xe001c000, + 0x46132200, + 0xf890486f, + 0x4870e000, + 0x9000f890, + 0xf890486f, + 0xfa4fc000, + 0xebc9f08e, + 0xfa4f0000, + 0x4550fa8c, + 0xebc9dd05, + 0x48660e0e, + 0xe000f880, + 0x4864e002, + 0xc000f880, + 0x0e00f04f, + 0xf840485d, + 0xf8dfe024, + 0xf85ee178, + 0x30010024, + 0x0024f84e, + 0x7800485d, + 0xd2054286, + 0x783f4f5a, + 0x360155af, + 0xe004b2f6, + 0x78364e57, + 0x6007f808, + 0x4f4d2601, + 0x4282553e, + 0x442ada06, + 0xf9124405, + 0x44234b01, + 0xd1fa42aa, + 0xfb934a53, + 0x9200f0f0, + 0xb2406a14, + 0x23002201, + 0xe08147a0, + 0xf8534b46, + 0x4b4e2024, + 0x429a681b, + 0xf8dad816, + 0xebc22084, + 0xf0230309, + 0xf1b34378, + 0xd9046f80, + 0x0302ebc9, + 0x4378f023, + 0x4a3e425b, + 0x1024f852, + 0x68124a44, + 0xf201fb02, + 0xd9634293, + 0xf9934b42, + 0xb9c33000, + 0xf8934b3a, + 0xf1bee000, + 0xd00a0f00, + 0xeb05462a, + 0x2300000e, + 0x1b01f912, + 0x4282440b, + 0x4672d1fa, + 0x2200e001, + 0xfb934613, + 0x4936fefe, + 0xe000f881, + 0x2200e001, + 0x49334613, + 0x49337808, + 0xc000f891, + 0xf8914932, + 0xb241e000, + 0x0101ebcc, + 0xf98efa4f, + 0xdd044549, + 0x0000ebcc, + 0x7008492a, + 0x4929e002, + 0xe000f881, + 0x491c2000, + 0x0024f841, + 0xf850481c, + 0x31011024, + 0x1024f840, + 0x7808491c, + 0xd2054286, + 0x78094920, + 0x360155a9, + 0xe004b2f6, + 0x7809491d, + 0x1007f808, + 0x490c2601, + 0x4282550e, + 0x442ada06, + 0xf9124405, + 0x440b1b01, + 0xd1fa42aa, + 0xfb934a12, + 0x9200f0f0, + 0xb2406a15, + 0x22014621, + 0x47a82300, + 0xe8bdb002, + 0xbf0087f0, + 0xc0006af8,//rssi_idx_for_agc[link_id] shenxin + 0xd02111f8,//EM_BT_RD(EM_BT_RXBIT_ADDR + 0xc0006afc,//rssi_set_for_agc shenxin + 0xc00009d4,//ld_acl_env[link_id] + 0xc0006b68,//link_no_sync_count[link_id] + 0xc00072fc,//link_agc_thd_tws + 0xc0006b78,//link_no_sync_count_time[link_id] + 0xc0007300,//link_agc_thd_tws_time + 0xc0006b60,//rssi_store_tws + 0xc0006af4,//n shenxin + 0xc0007304,//rssi_tws_step + 0xc0007308,//rssi_min_value_tws + 0xc0004268,//rwip_rf.rxgain_cntl + 0xc000730c,//link_agc_thd_mobile + 0xc0007310,//link_agc_thd_mobile_time + 0xc0006b88,//rssi_store_mobile + 0xc0007314,//rssi_mobile_step + 0xc0007318,//rssi_min_value_mobile + 0xffffffff,//link_agc_thd_tws + 0x00000030,//link_agc_thd_tws_time + 0x00000014,//rssi_tws_step + 0x0000009c,//rssi_min_value_tws + 0xffffffff,//link_agc_thd_mobile + 0x00000030,//link_agc_thd_mobile_time + 0x00000014,//rssi_mobile_step + 0x000000a1,//rssi_min_value_mobile + 0x99029804, + 0xfe96f7ff, + 0xfc48f632, + 0xb898f626,/*7328*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch37 = +{ + 37, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch37_ibrt_ins_data_t3), + 0x0002d458, + 0xbf60f1d9, + 0xc0007050, + (uint8_t *)bes2300p_patch37_ibrt_ins_data_t3 +};//swagc no sync + +#if 0 +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch38 = +{ + 38, + BTDRV_PATCH_ACT, + 0, + 0x000340b0, + 0xbf00e003, + 0, + NULL, +};//ld_sco_stop +#elif 1 +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch38 = +{ + 38, + BTDRV_PATCH_ACT, + 0, + 0x00039ecc, + 0xbf00e001, + 0, + NULL, +};//remove lc_start_lmp_to +#else +const uint32_t bes2300p_patch38_ibrt_ins_data_t3[] = +{ + 0x30d8f8c4, + 0xfed6f61f, + 0xd2014283, + 0xbca7f62a, + 0xbcbaf62a,/*7048*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch38 = +{ + 38, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch38_ibrt_ins_data_t3), + 0x000319a4, + 0xbb48f1d5, + 0xc0007038, + (uint8_t *)bes2300p_patch38_ibrt_ins_data_t3 +};//ble first connection anchor +#endif + +const uint32_t bes2300p_patch39_ibrt_ins_data_t3[] = +{ + 0x681b4b05,/*732c*/ + 0xd1032b00, + 0x781a9b12, + 0xbeb8f60b, + 0xbec3f60b, + 0xbf00bf00, + + 0xc0007348,//sniffer_sco_auto_accept + 0x00000000,/*7348*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch39 = +{ + 39, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch39_ibrt_ins_data_t3), + 0x000130a8, + 0xb940f1f4, + 0xc000732c, + (uint8_t *)bes2300p_patch39_ibrt_ins_data_t3 +};//lm_get_sync_param_hl_rsp + +const uint32_t bes2300p_patch40_ibrt_ins_data_t3[] = +{ + 0xfba2f632, + 0xd11d2801, + 0xfc38f632, + 0x4b33b1d0, + 0x2b00681b, + 0xf632d013, + 0x4606fba9, + 0xd10e42b8, + 0xfb98f632, + 0xd15f2800, + 0xfb76f632, + 0x7a224605, + 0x42937a63, + 0x4620d103, + 0xf99af000,// + 0x2000b9d0, + 0xbdeff614, + 0xfb80f632, + 0xd10d2802, + 0xfc16f632, + 0x4b22b150, + 0x2b00681b, + 0x4620d006, + 0xf988f000,// + 0x4b1fb910, + 0x601a2201, + 0xf0037823, + 0xbf000301, + 0xbda9f614, + 0xf8852602, + 0x79a36054, + 0x3055f885, + 0xf844f5fc, + 0x7c4279e3, + 0xd802429a, + 0xf83ef5fc, + 0xf8857c43, + 0x79633056, + 0x3057f885, + 0xf3c37923, + 0xf8850340, + 0x7a233058, + 0x3059f885, + 0xf8a58963, + 0x7ba3305a, + 0x305cf885, + 0xf88578e3, + 0x78a3305d, + 0x305ff885, + 0xfb28f632, + 0x46384603, + 0xf1052110, + 0xf6340252, + 0x2000fc65, + 0xbda3f614, + 0xc0007348,//sniffer_sco_auto_accept + 0xc0007434,//sco_param_filter_status + 0x00000000, + 0xfc3cf634, + 0xb2c33801, + 0xd8022b02, + 0xf6342004, + 0x2000fc3b, + 0xbd91f614, + 0x3c260cff, + 0x5a3712ff, + 0xffffffff, + 0xffffffff, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch40 = +{ + 40, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch40_ibrt_ins_data_t3), + 0x0001bf10, + 0xba1ef1eb, + 0xc0007350, + (uint8_t *)bes2300p_patch40_ibrt_ins_data_t3 +};//LMP_MSG_HANDLER(esco_link_req) + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch41 = +{ + 41, + BTDRV_PATCH_ACT, + 0, + 0x0003b818, + 0xfb1be001, + 0, + NULL, +};//config fastack none mode + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch42 = +{ + 42, + BTDRV_PATCH_ACT, + 0, + 0x0002ceb4, + 0xe00b0f0f, + 0, + NULL +};//ld_acl_rx() average rssi + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch43 = +{ + 43, + BTDRV_PATCH_ACT, + 0, + 0x0002a51c, + 0x3300f443, + 0, + NULL, +};//bt_e_scoltcntl_retxnb_setf 2 + +const uint32_t bes2300p_patch44_ibrt_ins_data_t3[] = +{ + 0xbf00686b, + 0xd00f42b3, + 0x4a212100, + 0x6863e004, + 0x42b34629, + 0x4625d00a, + 0xd9264293, + 0xd8242e01, + 0x462c461e, + 0xe001460d, + 0x2500462c, + 0x8008f8d4, + 0xa00cf894, + 0x900df894, + 0x46384f16, + 0x46224629, + 0xfb12f5fc, + 0x0014f1a7, + 0xf5fc4621, + 0xf1b8fa1d, + 0xd0050f00, + 0x46514630, + 0x2300464a, + 0xe00847c0, + 0x21ff480d, + 0xfffaf5ff, + 0x682ce003, + 0xd1ce2c00, + 0xb924e000, + 0xf44f4808, + 0xf5ff7185, + 0xe8bdffef, + 0xbf0087f0, + 0xc0000954, + 0xd02200bc, + 0xa00508ec, + 0x07fffffc, + 0xc0000968, + 0xa00508b4, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch44 = +{ + 44, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch44_ibrt_ins_data_t3), + 0x0002706c, + 0xb9f8f1e0, + 0xc0007460, + (uint8_t *)bes2300p_patch44_ibrt_ins_data_t3 +}; + +const uint32_t bes2300p_patch45_ibrt_ins_data_t3[] = +{ + 0x4b05b508, + 0x2b01681b, + 0x2200d104, + 0x601a4b02, + 0xfe6cf633, + 0xbf00bd08, + 0xc00076a4, + 0x00000000, + 0xffeef7ff, + 0xd1012b04, + 0xbff0f5ff, + 0xbff5f5ff,/*76b4*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch45 = +{ + 45, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch45_ibrt_ins_data_t3), + 0x00007690, + 0xb80af200, + 0xc0007688, + (uint8_t *)bes2300p_patch45_ibrt_ins_data_t3 +};//dbg state + +const uint32_t bes2300p_patch46_ibrt_ins_data_t3[] = +{ + 0x4b06b508, + 0x02007a98, + 0x0001f040, + 0xfb70f5fa, + 0xbf183801, + 0x30fff04f, + 0xbf00bd08, + 0xc00064d0, + 0xffeef7ff, + 0x781bb918, + 0xf6342b02, + 0xbd08bc89, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch46 = +{ + 46, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch46_ibrt_ins_data_t3), + 0x0003b60c, + 0xbb70f1cb, + 0xc0006cd0, + (uint8_t *)bes2300p_patch46_ibrt_ins_data_t3 +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch47 = +{ + 47, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch2a_ibrt_ins_data_t3), + 0x0001c528, + 0xbc98f1ea, //a001c528 -> a0206e5c + 0xc0006e5c, + (uint8_t *)bes2300p_patch2a_ibrt_ins_data_t3 +};//LMP_MSG_HANDLER(sniff_req) LC_CONNECTED + +const uint32_t bes2300p_patch48_ibrt_ins_data_t3[] = +{ + 0x681b4b1d, + 0xd1352b00, + 0xb083b530, + 0x8310f3ef, + 0x0f01f013, + 0xb672d117, + 0x25004c18, + 0x95019500, + 0xf1044620, + 0x2208013c, + 0xf5fc2307, + 0x9500f9ed, + 0xf5049501, + 0xf5047080, + 0x2208718a, + 0xf5fc2307, + 0xb662f9e3, + 0x4c0de014, + 0x95002500, + 0x46209501, + 0x013cf104, + 0x23072208, + 0xf9d6f5fc, + 0x95019500, + 0x7080f504, + 0x718af504, + 0x23072208, + 0xf9ccf5fc, + 0xbd30b003, + 0xbf004770, + 0xc0005df0, + 0xc0005b24, + 0xffbef7ff, + 0xe8bdb004, + 0xbf0081f0,/*75a4*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch48 = +{ + 48, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch48_ibrt_ins_data_t3), + 0x000013b0, + 0xb8f2f206, + 0xc0007518, + (uint8_t *)bes2300p_patch48_ibrt_ins_data_t3 +}; +#if 1 +const uint32_t bes2300p_patch49_ibrt_ins_data_t3[] = +{ + 0x78004804, + 0xbf00b120, + 0xfd8cf632, + 0xba1af609, + 0xba1af609, + 0xc0006221, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch49 = +{ + 49, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch49_ibrt_ins_data_t3), + 0x000103d8, + 0xbddef1f6, + 0xc0006f98, + (uint8_t *)bes2300p_patch49_ibrt_ins_data_t3 +};//lc_sco_ind +#else +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch49 = +{ + 49, + BTDRV_PATCH_ACT, + 0, + 0x000103d8, + 0xbf00e002, + 0, + NULL, +};//lc_sco_ind +#endif + +const uint32_t bes2300p_patch50_ibrt_ins_data_t3[] = +{ + 0xf632d806, + 0x2801fb0b, + 0x0209d002, + 0xbbeef632, + 0xbf00bd08,/*75d0*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch50 = +{ + 50, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch50_ibrt_ins_data_t3), + 0x00039d98, + 0xbc0af1cd, + 0xc00075b0, + (uint8_t *)bes2300p_patch50_ibrt_ins_data_t3 +};//do not trans stop SCO + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch51 = +{ + 51, + BTDRV_PATCH_ACT, + 0, + 0x0002ea00, + 0x8ff8e8bd, + 0, + NULL, +};//remove lmp flush + +const uint32_t bes2300p_patch52_ibrt_ins_data_t3[] = +{ + 0x4605b5f8, + 0xf8544c19, + 0xf6327020, + 0x4606fb05, + 0x4020f854, + 0xfaecf632, + 0xf632b320, + 0x42a8fa61, + 0xf897d120, + 0x2b023047, + 0x2e02d11c, + 0xb1ccd81a, + 0x3047f894, + 0xd1152b02, + 0x3040f894, + 0x0234b973, + 0x0401f044, + 0x4620b2a4, + 0xfeccf5f9, + 0xd0052836, + 0x60a2f44f, + 0x46224621, + 0xfadaf5f9, + 0x4b042001, + 0xbdf86018, + 0x4b022000, + 0xbdf86018, + 0xc0005de4, + 0xc0007668, + 0x4638bf00, + 0xffc2f7ff, + 0x4628d104, + 0xfeb0f5f9, + 0xfc38f614, + 0xbc84f614, + 0x00000000,/*7668*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch52 = +{ + 52, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch52_ibrt_ins_data_t3), + 0x0001bed0, + 0xbbbef1eb, + 0xc00075dc, + (uint8_t *)bes2300p_patch52_ibrt_ins_data_t3 +};//delay mobile unsniff lmp + +const uint32_t bes2300p_patch53_ibrt_ins_data_t3[] = +{ + 0x681b4b03,/*76fc*/ + 0xd1012b01,/*7700*/ + 0xfb06f632,/*7704*/ + 0x81f0e8bd,/*7708*/ + 0xc0007434,/*770c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch53 = +{ + 53, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch53_ibrt_ins_data_t3), + 0x0003a088, + 0xbb38f1cd, + 0xc00076fc, + (uint8_t *)bes2300p_patch53_ibrt_ins_data_t3 +};//don not trans start ibrt sco + +const uint32_t bes2300p_patch54_ibrt_ins_data_t3[] = +{ + 0xbf000a28, + 0xffc6f626, + 0x0a210a28, + 0xb8a4f611,/*767c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch54 = +{ + 54, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch54_ibrt_ins_data_t3), + 0x000187c4, + 0xbf54f1ee, + 0xc0007670, + (uint8_t *)bes2300p_patch54_ibrt_ins_data_t3 +};//protect tws tx type + +#if 0 +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch55 = +{ + 55, + BTDRV_PATCH_ACT, + 0, + 0x00030758, + 0xbf00e03a, + 0, + NULL, +};//decrease the connection time of TWS link in SCO +#else +const uint32_t bes2300p_patch55_ibrt_ins_data_t3[] = +{ + 0x68134a06, + 0x2380f023, + 0xf5a26013, + 0x68137206, + 0x0301f023, + 0xbf006013, + 0xbdaff63e, + 0xd0220400,/*77dc*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ibrt_ins_patch55 = +{ + 55, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch55_ibrt_ins_data_t3), + 0x00046330, + 0xba46f1c1, + 0xc00077c0, + (uint8_t *)bes2300p_patch55_ibrt_ins_data_t3 +};//disable hw spi in BLE push +#endif + +/////2300p t3 ibrt patch (chip id =2) +static const uint32_t best2300p_t3_ibrt_ins_patch_config[] = +{ + 56, + (uint32_t)&bes2300p_t3_ibrt_ins_patch0, + (uint32_t)&bes2300p_t3_ibrt_ins_patch1, + (uint32_t)&bes2300p_t3_ibrt_ins_patch2, + (uint32_t)&bes2300p_t3_ibrt_ins_patch3, + (uint32_t)&bes2300p_t3_ibrt_ins_patch4, + (uint32_t)&bes2300p_t3_ibrt_ins_patch5, + (uint32_t)&bes2300p_t3_ibrt_ins_patch6, + (uint32_t)&bes2300p_t3_ibrt_ins_patch7, + (uint32_t)&bes2300p_t3_ibrt_ins_patch8, + (uint32_t)&bes2300p_t3_ibrt_ins_patch9, + (uint32_t)&bes2300p_t3_ibrt_ins_patch10, + (uint32_t)&bes2300p_t3_ibrt_ins_patch11, + (uint32_t)&bes2300p_t3_ibrt_ins_patch12, + (uint32_t)&bes2300p_t3_ibrt_ins_patch13, + (uint32_t)&bes2300p_t3_ibrt_ins_patch14, + (uint32_t)&bes2300p_t3_ibrt_ins_patch15, + (uint32_t)&bes2300p_t3_ibrt_ins_patch16, + (uint32_t)&bes2300p_t3_ibrt_ins_patch17, + (uint32_t)&bes2300p_t3_ibrt_ins_patch18, + (uint32_t)&bes2300p_t3_ibrt_ins_patch19, + (uint32_t)&bes2300p_t3_ibrt_ins_patch20, + (uint32_t)&bes2300p_t3_ibrt_ins_patch21, + (uint32_t)&bes2300p_t3_ibrt_ins_patch22, + (uint32_t)&bes2300p_t3_ibrt_ins_patch23, + (uint32_t)&bes2300p_t3_ibrt_ins_patch24, + (uint32_t)&bes2300p_t3_ibrt_ins_patch25, + (uint32_t)&bes2300p_t3_ibrt_ins_patch26, + (uint32_t)&bes2300p_t3_ibrt_ins_patch27, + (uint32_t)&bes2300p_t3_ibrt_ins_patch28, + (uint32_t)&bes2300p_t3_ibrt_ins_patch29, + (uint32_t)&bes2300p_t3_ibrt_ins_patch30, + (uint32_t)&bes2300p_t3_ibrt_ins_patch31, + (uint32_t)&bes2300p_t3_ibrt_ins_patch32, + (uint32_t)&bes2300p_t3_ibrt_ins_patch33, + (uint32_t)&bes2300p_t3_ibrt_ins_patch34, + (uint32_t)&bes2300p_t3_ibrt_ins_patch35, + (uint32_t)&bes2300p_t3_ibrt_ins_patch36, + (uint32_t)&bes2300p_t3_ibrt_ins_patch37, + (uint32_t)&bes2300p_t3_ibrt_ins_patch38, + (uint32_t)&bes2300p_t3_ibrt_ins_patch39, + (uint32_t)&bes2300p_t3_ibrt_ins_patch40, + (uint32_t)&bes2300p_t3_ibrt_ins_patch41, + (uint32_t)&bes2300p_t3_ibrt_ins_patch42, + (uint32_t)&bes2300p_t3_ibrt_ins_patch43, + (uint32_t)&bes2300p_t3_ibrt_ins_patch44, + (uint32_t)&bes2300p_t3_ibrt_ins_patch45, + (uint32_t)&bes2300p_t3_ibrt_ins_patch46, + (uint32_t)&bes2300p_t3_ibrt_ins_patch47, + (uint32_t)&bes2300p_t3_ibrt_ins_patch48, + (uint32_t)&bes2300p_t3_ibrt_ins_patch49, + (uint32_t)&bes2300p_t3_ibrt_ins_patch50, + (uint32_t)&bes2300p_t3_ibrt_ins_patch51, + (uint32_t)&bes2300p_t3_ibrt_ins_patch52, + (uint32_t)&bes2300p_t3_ibrt_ins_patch53, + (uint32_t)&bes2300p_t3_ibrt_ins_patch54, + (uint32_t)&bes2300p_t3_ibrt_ins_patch55, +}; +#else + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch0 = +{ + 0, + BTDRV_PATCH_ACT, + 0, + 0x000324d4, + 0xbf00bf00, + 0, + NULL +};// afh filter disable + +const uint32_t bes2300p_patch1_ins_data_t3[] = +{ + 0xf8934b09, + 0xf0133084, + 0xd0050f06, + 0xf6374620, + 0x4601f839, + 0xe0052400, + 0xf8934b03, + 0xbf003084, + 0xb975f636, + 0xb9bbf636, + 0xc0006568, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch1 = +{ + 1, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch1_ins_data_t3), + 0x0003cd08, + 0xbe7af1c9, + 0xc0006a00, + (uint8_t *)bes2300p_patch1_ins_data_t3 +};// set ble adv data + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch2 = +{ + 2, + BTDRV_PATCH_ACT, + 0, + 0x0003cbf0, + 0xbf00e004, + 0, + NULL +};// set ble scan response data + +const uint32_t bes2300p_patch3_ins_data_t3[] = +{ + /*6a98*/ 0x99049803, + /*6a9c*/ 0x4b12b470, + /*6aa0*/ 0x010e5c5a, + /*6aa4*/ 0x19734d11, + /*6aa8*/ 0x78244c11, + /*6aac*/ 0xd20342a2, + /*6ab0*/ 0x32015498, + /*6ab4*/ 0xe001b2d2, + /*6ab8*/ 0x22015570, + /*6abc*/ 0x5442480a, + /*6ac0*/ 0x461ab14c, + /*6ac4*/ 0x23001919, + /*6ac8*/ 0x0b01f912, + /*6acc*/ 0xbf004403, + /*6ad0*/ 0xd1f9428a, + /*6ad4*/ 0x2300e000, + /*6ad8*/ 0xf0f4fb93, + /*6adc*/ 0xbc70b240, + /*6ae0*/ 0x22019904, + /*6ae4*/ 0xba00f626, //jump a0206ae4 -> a002cee8 + /*6ae8*/ 0xc0006af8, //addr of rssi_idx_for_agc + /*6aec*/ 0xc0006afc, //addr of rssi_set_for_agc + /*6af0*/ 0xc0006af4, //addr of N + /*6af4*/ 0x00000005, //N : 1 ~ 16 + /*6af8*/ 0x00000000, //rssi_idx_for_agc[3] + /*6afc*/ 0xbabababa, //rssi_set_for_agc[3*16] + /*6b00*/ 0xbabababa, + /*6b04*/ 0xbabababa, + /*6b08*/ 0xbabababa, + /*6b0c*/ 0xbabababa, + /*6b10*/ 0xbabababa, + /*6b14*/ 0xbabababa, + /*6b18*/ 0xbabababa, + /*6b1c*/ 0xbabababa, + /*6b20*/ 0xbabababa, + /*6b24*/ 0xbabababa, + /*6b28*/ 0xbabababa, + /*6b2c*/ 0xbabababa, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch3 = +{ + 3, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch3_ins_data_t3), + 0x0002cee4, + 0xbdd8f1d9, //jump a002cee4 -> a0206a98 + 0xc0006a98, + (uint8_t *)bes2300p_patch3_ins_data_t3 +};//ld_acl_rx() average rssi + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch4 = +{ + 4, + BTDRV_PATCH_ACT, + 0, + 0x0002ceb4, + 0xe00b0f0f, + 0, + NULL +};//ld_acl_rx() average rssi + +const uint32_t bes2300p_patch5_ins_data_t3[] = +{ + 0x2028f843,/*6b3c*/ + 0xf8434b08, + 0x4b052028, + 0x4b0e701a, + 0x2201701a, + 0xf8434b08, + 0xbf002028, + 0xba32f624, + 0xc0006b60, + 0x00000000, + 0xc0006b68, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0006b78, + 0x00000001, + 0x00000001, + 0x00000001, + 0xc0006b88, + 0x00000000,/*6b88*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch5 = +{ + 5, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch5_ins_data_t3), + 0x0002afbc, + 0xbdbef1db, + 0xc0006b3c, + (uint8_t *)bes2300p_patch5_ins_data_t3 +};//sync clear count + +const uint32_t bes2300p_patch6_ins_data_t3[] = +{ + 0x47f0e92d,/*7050*/ + 0x4b97b082, + 0x236e5c1e, + 0xf300fb03, + 0x5a9b4a95, + 0x4f00f413, + 0x8120f040, + 0x46044689, + 0x1800ea4f, + 0xeb084f91, + 0x4b910507, + 0xa020f853, + 0xf8524a90, + 0x33013020, + 0x3020f842, + 0xf860f635, + 0x42a04601, + 0x8088f040, + 0xf8534b8a, + 0x4b8a2024, + 0x429a681b, + 0xf8dad817, + 0xebc22084, + 0xf0230309, + 0xf1b34378, + 0xd9046f80, + 0x0302ebc9, + 0x4378f023, + 0x4a82425b, + 0x0024f852, + 0x68124a81, + 0xf200fb02, + 0xf2404293, + 0x4b7f80eb, + 0x3000f993, + 0x4b7eb9c3, + 0xc000f893, + 0x0f00f1bc, + 0x462ad00a, + 0x0e0ceb05, + 0xf9122300, + 0x44030b01, + 0xd1fa4572, + 0xe0014662, + 0x46132200, + 0xfcfcfb93, + 0xf8804872, + 0xe001c000, + 0x46132200, + 0xf890486f, + 0x4870e000, + 0x9000f890, + 0xf890486f, + 0xfa4fc000, + 0xebc9f08e, + 0xfa4f0000, + 0x4550fa8c, + 0xebc9dd05, + 0x48660e0e, + 0xe000f880, + 0x4864e002, + 0xc000f880, + 0x0e00f04f, + 0xf840485d, + 0xf8dfe024, + 0xf85ee178, + 0x30010024, + 0x0024f84e, + 0x7800485d, + 0xd2054286, + 0x783f4f5a, + 0x360155af, + 0xe004b2f6, + 0x78364e57, + 0x6007f808, + 0x4f4d2601, + 0x4282553e, + 0x442ada06, + 0xf9124405, + 0x44234b01, + 0xd1fa42aa, + 0xfb934a53, + 0x9200f0f0, + 0xb2406a14, + 0x23002201, + 0xe08147a0, + 0xf8534b46, + 0x4b4e2024, + 0x429a681b, + 0xf8dad816, + 0xebc22084, + 0xf0230309, + 0xf1b34378, + 0xd9046f80, + 0x0302ebc9, + 0x4378f023, + 0x4a3e425b, + 0x1024f852, + 0x68124a44, + 0xf201fb02, + 0xd9634293, + 0xf9934b42, + 0xb9c33000, + 0xf8934b3a, + 0xf1bee000, + 0xd00a0f00, + 0xeb05462a, + 0x2300000e, + 0x1b01f912, + 0x4282440b, + 0x4672d1fa, + 0x2200e001, + 0xfb934613, + 0x4936fefe, + 0xe000f881, + 0x2200e001, + 0x49334613, + 0x49337808, + 0xc000f891, + 0xf8914932, + 0xb241e000, + 0x0101ebcc, + 0xf98efa4f, + 0xdd044549, + 0x0000ebcc, + 0x7008492a, + 0x4929e002, + 0xe000f881, + 0x491c2000, + 0x0024f841, + 0xf850481c, + 0x31011024, + 0x1024f840, + 0x7808491c, + 0xd2054286, + 0x78094920, + 0x360155a9, + 0xe004b2f6, + 0x7809491d, + 0x1007f808, + 0x490c2601, + 0x4282550e, + 0x442ada06, + 0xf9124405, + 0x440b1b01, + 0xd1fa42aa, + 0xfb934a12, + 0x9200f0f0, + 0xb2406a15, + 0x22014621, + 0x47a82300, + 0xe8bdb002, + 0xbf0087f0, + 0xc0006af8,//rssi_idx_for_agc[link_id] shenxin + 0xd02111f8,//EM_BT_RD(EM_BT_RXBIT_ADDR + 0xc0006afc,//rssi_set_for_agc shenxin + 0xc00009d4,//ld_acl_env[link_id] + 0xc0006b68,//link_no_sync_count[link_id] + 0xc00072fc,//link_agc_thd_tws + 0xc0006b78,//link_no_sync_count_time[link_id] + 0xc0007300,//link_agc_thd_tws_time + 0xc0006b60,//rssi_store_tws + 0xc0006af4,//n shenxin + 0xc0007304,//rssi_tws_step + 0xc0007308,//rssi_min_value_tws + 0xc0004268,//rwip_rf.rxgain_cntl + 0xc000730c,//link_agc_thd_mobile + 0xc0007310,//link_agc_thd_mobile_time + 0xc0006b88,//rssi_store_mobile + 0xc0007314,//rssi_mobile_step + 0xc0007318,//rssi_min_value_mobile + 0xffffffff,//link_agc_thd_tws + 0x00000030,//link_agc_thd_tws_time + 0x00000014,//rssi_tws_step + 0x0000009c,//rssi_min_value_tws + 0xffffffff,//link_agc_thd_mobile + 0x00000030,//link_agc_thd_mobile_time + 0x00000014,//rssi_mobile_step + 0x000000a1,//rssi_min_value_mobile + 0x99029804, + 0xfe96f7ff, + 0xfc48f632, + 0xb898f626,/*7328*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch6 = +{ + 6, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch6_ins_data_t3), + 0x0002d458, + 0xbf60f1d9, + 0xc0007050, + (uint8_t *)bes2300p_patch6_ins_data_t3 +};//swagc no sync + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch7 = +{ + 7, + BTDRV_PATCH_ACT, + 0, + 0x0000e47a, + 0xe0027b20, + 0, + NULL +};//lm_inq_res_ind_handler() rssi + +const uint32_t bes2300p_patch8_ins_data_t3[] = +{ + 0x2300b430, + 0x4d072103, + 0x4290b2da, + 0xf855d004, + 0x2c004023, + 0x4611bf18, + 0x2b033301, + 0x4608d1f4, + 0x4770bc30, + 0xc00009d4, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch8 = +{ + 8, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch8_ins_data_t3), + 0x0002c8c0, + 0xbb2ef1da, + 0xc0006f20, + (uint8_t *)bes2300p_patch8_ins_data_t3 +};//find_other_acl_link + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch9 = +{ + 9, + BTDRV_PATCH_ACT, + 0, + 0x000123e8, + 0xf7f1bf00, + 0, + NULL +};//ignore lm_get_nb_acl(MASTER_FLAG|SLAVE_FLAG) > 1 when cal wesco + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch10 = +{ + 10, + BTDRV_PATCH_ACT, + 0, + 0x0002ff48, + 0xd9590f05, + 0, + NULL, +};//ignore bld_sco_retransmit_dec function + +const uint32_t bes2300p_patch11_ins_data_t3[] = +{ + 0x304bf996, + 0x44233302, + 0xbbfcf629, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch11 = +{ + 11, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch11_ins_data_t3), + 0x00030748, + 0xbbfef1d6, + 0xc0006f48, + (uint8_t *)bes2300p_patch11_ins_data_t3 +};//ld_calculate_timestamp + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch12 = +{ + 12, + BTDRV_PATCH_ACT, + 0, + 0x0001bcf4, + 0xbf00e004, + 0, + NULL, +};//LMP_MSG_HANDLER(max_slot_req) + +const uint32_t bes2300p_patch13_ins_data_t3[] = +{ + 0x3040f894, + 0xd1032b00, + 0x222a210b, + 0xbe00f616, + 0xbd06f616 +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch13 = +{ + 13, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch13_ins_data_t3), + 0x0001d63c, + 0xb9f8f1e9, + 0xc0006a30, + (uint8_t *)bes2300p_patch13_ins_data_t3 +};//LMP_MSG_HANDLER(aurand) + +const uint32_t bes2300p_patch14_ins_data_t3[] = +{ + 0xf8534b04, + 0x46283026, + 0x135ef893, + 0xfc62f5fa, + 0xbd55f616, + 0xc0005de4 +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch14 = +{ + 14, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch14_ins_data_t3), + 0x0001d4f4, + 0xbaa6f1e9, + 0xc0006a44, + (uint8_t *)bes2300p_patch14_ins_data_t3 +};//LMP_MSG_HANDLER(aurand) + +const uint32_t bes2300p_patch15_ins_data_t3[] = +{ + 0x3040f897, + 0xd1032b00, + 0xbbacf617, + 0x21234620, + 0xf836f610, + 0xbc8bf617/*0xc0006a74*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch15 = +{ + 15, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch15_ins_data_t3), + 0x0001e1c0, + 0xbc4ef1e8, + 0xc0006a60, + (uint8_t *)bes2300p_patch15_ins_data_t3 +};//LMP_MSG_HANDLER(not_accepted) + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch16 = +{ + 16, + BTDRV_PATCH_ACT, + 0, + 0x0002ea00, + 0x8ff8e8bd, + 0, + NULL, +};//remove lmp flush + +const uint32_t bes2300p_patch17_ins_data_t3[] = +{ + 0xfe4af5f9, + 0xbf002300, + 0x30c8f884, + 0xbaf8f624,/*6f18*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch17 = +{ + 17, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch17_ins_data_t3), + 0x0002b508, + 0xbd00f1db, + 0xc0006f0c, + (uint8_t *)bes2300p_patch17_ins_data_t3 +};///role switch fail + +const uint32_t bes2300p_patch18_ins_data_t3[] = +{ + 0xbf004628, + 0xfdc4f60d, + 0x21144628, + 0xba4af60f,/*6c94*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch18 = +{ + 18, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch18_ins_data_t3), + 0x00016128, + 0xbdaef1f0, + 0xc0006c88, + (uint8_t *)bes2300p_patch18_ins_data_t3 +};//start lmp to before sending LMP_HostConnectionReq + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch19 = +{ + 19, + BTDRV_PATCH_ACT, + 0, + 0x00020640, + 0xe00dbf00, + 0, + NULL, +};//detach directly + +const uint32_t bes2300p_patch20_ins_data_t3[] = +{ + 0x305af893, + 0xd1032b00, + 0x12f4f240, + 0xbf00e002, + 0x32b8f640, + 0xbe30f60d,/*6bdc*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch20 = +{ + 20, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch20_ins_data_t3), + 0x0001483c, + 0xb9c4f1f2, + 0xc0006bc8, + (uint8_t *)bes2300p_patch20_ins_data_t3 +};//lmp to 5s before connection cmp sent + +const uint32_t bes2300p_patch21_ins_data_t3[] = +{ + 0x4603b508, + 0x8210f3ef, + 0x0f01f012, + 0xb672d112, + 0xf5a34811, + 0x3b285343, + 0xfba14910, + 0xf3c32303, + 0xeb032387, + 0xeb000343, + 0x31940183, + 0xfdd0f5fc, + 0xbd08b662, + 0xf5a34808, + 0x3b285343, + 0xfba14907, + 0xf3c32303, + 0xeb032387, + 0xeb000343, + 0x31940183, + 0xfdbef5fc, + 0xbf00bd08, + 0xc0005b4c, + 0xff00ff01, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch21 = +{ + 21, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch21_ins_data_t3), + 0x00008b24, + 0xb8f8f1fe, + 0xc0006d18, + (uint8_t *)bes2300p_patch21_ins_data_t3 +};//add lock interrupt when free acl buf + +const uint32_t bes2300p_patch22_ins_data_t3[] = +{ + 0x2040f897,/*6e00*/ + 0xd1112a01, + 0x0109f106, + 0xf5fc4608, + 0x2813fd4b, + 0x221ed802, + 0xbc54f614, + 0x2a017a32, + 0xf614d801, + 0x221ebbf6, + 0xbc4cf614, + 0xbc47f614,/*6e2c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch22 = +{ + 22, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch22_ins_data_t3), + 0x0001b604, + 0xbbfcf1eb, + 0xc0006e00, + (uint8_t *)bes2300p_patch22_ins_data_t3 +};//reject set afh lmp when channel number less than 20 + +/*patch 23,24 for HiSilicon,BCS4.2,ver0x608 and Broadcom,BCS4.2,ver0x6106 Enhanced Data Rate problem*/ +const uint32_t bes2300p_patch23_ins_data_t3[] = +{ + 0x0a00b538,/*c0006b90*/ + 0xf8534b08, + 0xb2c45020, + 0xf6274620, + 0x4620fdaf, + 0xf895210b, + 0xf61d2046, + 0x2201ff63, + 0x701a4b02, + 0xbf00bd38, + 0xc0005de4, + 0xc0006bc0, + 0x00000000 /*c0006bc0*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch23 = +{ + 23, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch23_ins_data_t3), + 0x000144fc, + 0xbb48f1f2, + 0xc0006b90, + (uint8_t *)bes2300p_patch23_ins_data_t3 +};//table request + +const uint32_t bes2300p_patch24_ins_data_t3[] = +{ + 0x0a00b538,/*c0006be0*/ + 0xf8534b0f, + 0xb2c45020, + 0x104df895, + 0x31004620, + 0x2101bf18, + 0xfab8f628, + 0x8d298ea8, + 0xf61d2201, + 0x4601f9f7, + 0xf6284620, + 0x2301fae5, + 0x3062f885, + 0xf6274620, + 0x2200fd7f, + 0x701a4b02, + 0xbf00bd38, + 0xc0005de4, + 0xc0006bc0, + 0x78244c04, + 0x4628b114, + 0xffd4f7ff, + 0xb00d2000, + 0x83f0e8bd, + 0xc0006bc0 /*c0006c40*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch24 = +{ + 24, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch24_ins_data_t3), + 0x00023eb8, + 0xbeb8f1e2, + 0xc0006be0, + (uint8_t *)bes2300p_patch24_ins_data_t3 +};//table request configure +/*end patch 23,24 for HiSilicon,BCS4.2,ver0x608 and Broadcom,BCS4.2,ver0x6106 Enhanced Data Rate problem*/ + +const uint32_t bes2300p_patch25_ins_data_t3[] = +{ + 0xfa80f5fc,/*c0006f58*/ + 0xb9737f43, + 0x2b01786b, + 0x2b03d01a, + 0x2b05d010, + 0xf896d00e, + 0x22203044, + 0x4620212e, + 0xfd90f61d, + 0xf896e010, + 0x212e2044, + 0xf61d4620, + 0xe009fd65, + 0xfd70f60c, + 0xd1ec2800, + 0x325ef896, + 0xd1e82b00, + 0xbeb0f614, + 0xbec1f614,/*c0006fa0*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch25 = +{ + 25, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch25_ins_data_t3), + 0x0001bcb8, + 0xb94ef1eb, + 0xc0006f58, + (uint8_t *)bes2300p_patch25_ins_data_t3 +};//LMP_MSG_HANDLER(max_slot_req) + +const uint32_t bes2300p_patch26_ins_data_t3[] = +{ + 0x681b4b16, + 0xd0222b00, + 0xf8b34b16, + 0xf01331c0, + 0xd1000f18, + 0x4b13e020, + 0x71c2f893, + 0xff12f61f, + 0xd0192f02, + 0xf8534b10, + 0x2b003027, + 0x6b5ad014, + 0xd9074282, + 0xf8931a10, + 0xeb033042, + 0x42980343, + 0x2200d80a, + 0x46204611, + 0xfa62f629, + 0x4620e004, + 0xbf002100, + 0xbe0cf629, + 0xbe0df629, + + 0xc0007008,//sco_start_delay_flag + 0x00000000, + 0xc0005ea8,//ld_env + 0xc00009e4,//ld_sco_env + +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch26 = +{ + 26, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch26_ins_data_t3), + 0x00030c14, + 0xb9c8f1d6, + 0xc0006fa8, + (uint8_t *)bes2300p_patch26_ins_data_t3 +};//ld_acl_sched + +const uint32_t bes2300p_patch27_ins_data_t3[] = +{ + 0xf0234413, + 0x63634378, + 0x68094904, + 0x4904b121, + 0xfb016809, + 0x63633300, + 0xba5af62c, + + 0xc0007008,//sco_start_delay_flag + 0xc000703c,//sco_anchor_start_add + 0x0000000a, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch27 = +{ + 27, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch27_ins_data_t3), + 0x000334e0, + 0xbd9af1d3, + 0xc0007018, + (uint8_t *)bes2300p_patch27_ins_data_t3 +};//ld_sco_start + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch28 = +{ + 28, + BTDRV_PATCH_ACT, + 0, + 0x00019f54, + 0xbf00e00b, + 0, + NULL, +};//lc_sync_ind +//send max_slot anyway + +const uint32_t bes2300p_patch29_ins_data_t3[] = +{ + 0xf8862001, + 0xf8860060, + 0xbf000061, + 0xbba3f611, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch29 = +{ + 29, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch29_ins_data_t3), + 0x00018f1c, + 0xbc62f1ee, + 0xc00077e4, + (uint8_t *)bes2300p_patch29_ins_data_t3 +};//ignore 0x5d sm + +// for ble master update con param with large winsize +const uint32_t bes2300p_patch30_ins_data_t3[] = +{ + 0x4630bf00, + 0x109ef894, + 0xf958f63f, + 0x309cf894, + 0x2271f240, + 0x0003fb02, + 0xbcf1f63f, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch30 = +{ + 30, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch30_ins_data_t3), + 0x000471e4, + 0xbb08f1c0, + 0xc00077f8, + (uint8_t *)bes2300p_patch30_ins_data_t3 +}; + +static const uint32_t best2300p_t3_ins_patch_config[] = +{ + 31, + (uint32_t)&bes2300p_t3_ins_patch0, + (uint32_t)&bes2300p_t3_ins_patch1, + (uint32_t)&bes2300p_t3_ins_patch2, + (uint32_t)&bes2300p_t3_ins_patch3, + (uint32_t)&bes2300p_t3_ins_patch4, + (uint32_t)&bes2300p_t3_ins_patch5, + (uint32_t)&bes2300p_t3_ins_patch6, + (uint32_t)&bes2300p_t3_ins_patch7, + (uint32_t)&bes2300p_t3_ins_patch8, + (uint32_t)&bes2300p_t3_ins_patch9, + (uint32_t)&bes2300p_t3_ins_patch10, + (uint32_t)&bes2300p_t3_ins_patch11, + (uint32_t)&bes2300p_t3_ins_patch12, + (uint32_t)&bes2300p_t3_ins_patch13, + (uint32_t)&bes2300p_t3_ins_patch14, + (uint32_t)&bes2300p_t3_ins_patch15, + (uint32_t)&bes2300p_t3_ins_patch16, + (uint32_t)&bes2300p_t3_ins_patch17, + (uint32_t)&bes2300p_t3_ins_patch18, + (uint32_t)&bes2300p_t3_ins_patch19, + (uint32_t)&bes2300p_t3_ins_patch20, + (uint32_t)&bes2300p_t3_ins_patch21, + (uint32_t)&bes2300p_t3_ins_patch22, + (uint32_t)&bes2300p_t3_ins_patch23, + (uint32_t)&bes2300p_t3_ins_patch24, + (uint32_t)&bes2300p_t3_ins_patch25, + (uint32_t)&bes2300p_t3_ins_patch26, + (uint32_t)&bes2300p_t3_ins_patch27, + (uint32_t)&bes2300p_t3_ins_patch28, + (uint32_t)&bes2300p_t3_ins_patch29, + (uint32_t)&bes2300p_t3_ins_patch30, +}; +#endif + +#ifndef IBRT + +/*************************************************************************** + * + * instruction patch Information + * + * BT ROM Chip Version:1302 T2(CHIP ID=1) + * + * __BT_ONE_BRING_TWO__ function + * + ****************************************************************************/ + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch0 = +{ + 0, + BTDRV_PATCH_ACT, + 0, + 0x00030d48, + 0xbf00bf00, + 0, + NULL +};// set lsto when there is no connect + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch1 = +{ + 1, + BTDRV_PATCH_ACT, + 0, + 0x00019acc, + 0xbf00e003, + 0, + NULL +};////iocap rsp + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch2 = +{ + 2, + BTDRV_PATCH_ACT, + 0, + 0x0001a7a4, + 0xbf00e003, + 0, + NULL +};//pwer rsp in wrong state + +const uint32_t bes2300p_patch3_ins_data_t2[] = +{ + 0xf5fa4620, /*6900*/ + 0x285dfd4b, + 0xf240d10e, + 0x46215005, + 0xf84cf5fa, /*6910*/ + 0xf8534b05, + 0x46203026, + 0x135ef893, + 0xfcd0f5fa, /*6920*/ + 0xb9f3f617, + 0xb9ebf617, + 0xc0005cd8, /*692c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch3 = +{ + 3, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch3_ins_data_t2), + 0x0001dcfc, + 0xbe00f1e8, + 0xc0006900, + (uint8_t *)bes2300p_patch3_ins_data_t2 +};//not accept + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch4 = +{ + 4, + BTDRV_PATCH_ACT, + 0, + 0x0002a4a4, + 0xbf8c7f80, + 0, + NULL +};//LD_ACL_STOP_NOTIF_BIT_OFF_THR + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch5 = +{ + 5, + BTDRV_PATCH_ACT, + 0, + 0x0002a7e4, + 0x7f80f5b3, + 0, + NULL +};//LD_ACL_STOP_NOTIF_BIT_OFF_THR + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch6 = +{ + 6, + BTDRV_PATCH_ACT, + 0, + 0x0002a69c, + 0xbf947f80, + 0, + NULL +};//LD_ACL_STOP_NOTIF_BIT_OFF_THR + +const uint32_t bes2300p_patch7_ins_data_t2[] = +{ + 0xd01e0fdb, /*6930*/ + 0x6307f44f, + 0xf304fb03, + 0x48168f6a, + 0x93011810, /*6940*/ + 0x49154418, + 0xfea0f644, + 0x58fb4b14, + 0x4301f3c3, /*6950*/ + 0xf1028f2a, + 0xf5024250, + 0xf2021205, + 0x8f6942fc, /*6960*/ + 0x0241eb02, + 0x440a9901, + 0x600a490d, + 0xf44fe010, /*6970*/ + 0xfb036307, + 0x9301f304, + 0x18184806, + 0x8f6a4906, /*6980*/ + 0xfe82f644, + 0x58fb4b05, + 0x4381f3c3, + 0xba27f62e, /*6990*/ + 0xba2df62e, + + 0xd02144fc, + 0xc000593c, + 0xd0220144, /*69a0*/ + 0xc000005c, /*69a4*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch7 = +{ + 7, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch7_ins_data_t2), + 0x00034d80, + 0xbdd6f1d1, + 0xc0006930, + (uint8_t *)bes2300p_patch7_ins_data_t2 +};//ld_sco_frm_isr + +const uint32_t bes2300p_patch8_ins_data_t2[] = +{ + 0xf6052002, /*69a8*/ + 0x2802ffbf, + 0xf898d110, /*69b0*/ + 0x230120b2, + 0x4a074093, + 0x21c0f8b2, + 0x0303ea22, /*69c0*/ + 0x0341f3c3, + 0xf8524a04, + 0xbf003023, + 0xbbecf625, /*69d0*/ + 0xbbeef625, + + 0xc0005d9c,//ld_env + 0xc0000998,//ld_acl_env /*69dc*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch8 = +{ + 8, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch8_ins_data_t2), + 0x0002c188, + 0xbc0ef1da, + 0xc00069a8, + (uint8_t *)bes2300p_patch8_ins_data_t2 +};//ld_event_timestamp_calculate + +const uint32_t bes2300p_patch9_ins_data_t2[] = +{ + 0xf8934b07, /*69e0*/ + 0xf0133084, + 0xd0070f06, + 0xf6364620, + 0x4601fa4b, /*69f0*/ + 0xbf002400, + 0xbbd2f635, + 0xbb91f635, + + 0xc0006460,//llm_le_env /*6a00*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch9 = +{ + 9, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch9_ins_data_t2), + 0x0003c11c, + 0xbc60f1ca, + 0xc00069e0, + (uint8_t *)bes2300p_patch9_ins_data_t2 +};//hci_le_set_adv_data_cmd_handler + +const uint32_t bes2300p_patch10_ins_data_t2[] = +{ + 0x123ff240, /*6a04*/ + 0xd006421a, + 0x2b007aab, + 0x2201d003, /*6a10*/ + 0x601a4b05, + 0x2201e002, + 0x601a4b03, + 0xf240892b, /*6a20*/ + 0xbf00123f, + 0xbc1af63e, + + 0xc0006a30,//le_wrong_packet + 0x00000000, /*6a30*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch10 = +{ + 10, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch10_ins_data_t2), + 0x0004525c, + 0xbbd2f1c1, + 0xc0006a04, + (uint8_t *)bes2300p_patch10_ins_data_t2 +};//lld_pdu_rx_handler + +const uint32_t bes2300p_patch11_ins_data_t2[] = +{ + 0xf894b952, /*6a34*/ + 0xf01330ae, + 0xd1050f09, + 0x209ff894, /*6a40*/ + 0x4a03b912, + 0xb10a6812, + 0xbc05f63f, + 0xbc09f63f, /*6a50*/ + + 0xc0006a30, /*6a54*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch11 = +{ + 11, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch11_ins_data_t2), + 0x00046248, + 0xbbf4f1c0, + 0xc0006a34, + (uint8_t *)bes2300p_patch11_ins_data_t2 +};//lld_evt_restart + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch12 = //from bes2300p_t2_ibrt_ins_patch2 +{ + 12, + BTDRV_PATCH_ACT, + 0, + 0x00007024, + 0xbf00e011, + 0, + NULL +};//dont call rwip_assert_err when assert error + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch13 = //from bes2300p_t2_ibrt_ins_patch4 +{ + 13, + BTDRV_PATCH_ACT, + 0, + 0x0002be90, + 0xbd702000, + 0, + NULL +}; //ld_check_if_need_protect_sniff retrun 0 + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch14 = //from bes2300p_t2_ibrt_ins_patch9 +{ + 14, + BTDRV_PATCH_ACT, + 0, + 0x0002d82c, + 0x2b006013, + 0, + NULL, +};//ld_acl_rsw_rx + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch15 = //from bes2300p_t2_ibrt_ins_patch10 +{ + 15, + BTDRV_PATCH_ACT, + 0, + 0x0002fe60, + 0xbf00e001, + 0, + NULL, +};//ld_acl_flow_on + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch16 = //from bes2300p_t2_ibrt_ins_patch12 +{ + 16, + BTDRV_PATCH_ACT, + 0, + 0x0002a41c, + 0xbf000f01, + 0, + NULL +};//mode == SYNC2_SCO_MODE + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch17 = //from bes2300p_t2_ibrt_ins_patch17 +{ + 17, + BTDRV_PATCH_ACT, + 0, + 0x00007010, //a0007010 + 0xb9bef000, //jump a0007390 + 0, + NULL, +};//DEF_IRQHandler + +const uint32_t bes2300p_patch18_ins_data_t2[] = +{ + 0x4681b083,/*6b30*/ + 0x4b022200, + 0x2020f843, + 0xbddcf623, + 0xc0006b44, + 0x00000000, + 0x00000000, + 0x00000000,/*6b4c*/ +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch18 = //from bes2300p_t2_ibrt_ins_patch22 +{ + 18, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch18_ins_data_t2), + 0x0002a6f4, + 0xba1cf1dc, + 0xc0006b30, + (uint8_t *)bes2300p_patch18_ins_data_t2 +};//sync clear count + +const uint32_t bes2300p_patch19_ins_data_t2[] = +{ + /*6ba0*/ 0xbf0080c6, + /*6ba4*/ 0x71022200, + /*6ba8*/ 0xbb2af619, //jump a0020200 +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch19 = //from bes2300p_t2_ibrt_ins_patch29 +{ + 19, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch19_ins_data_t2), + 0x000201f8, + 0xbcd2f1e6, //jump a00201f8 -> a0206ba0 + 0xc0006ba0, + (uint8_t *)bes2300p_patch19_ins_data_t2 +};//KE_MSG_HANDLER(lc_op_loc_sniff_req, void) + +const uint32_t bes2300p_patch20_ins_data_t2[] = +{ + /*6bac*/ 0x46286825, + /*6bb0*/ 0x303ef895, + /*6bb4*/ 0xd0012b02, + /*6bb8*/ 0xbda2f622, //jump a0029700 + /*6bbc*/ 0xbf002300, + /*6bc0*/ 0x303ef885, + /*6bc4*/ 0xfea6f622, //call a0029914 + /*6bc8*/ 0xbdc1f622, //jump a002974e +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch20 = //from bes2300p_t2_ibrt_ins_patch30 +{ + 20, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch20_ins_data_t2), + 0x000296fc, + 0xba56f1dd, //jump a00296fc -> a0206bac + 0xc0006bac, + (uint8_t *)bes2300p_patch20_ins_data_t2 +};//ld_pscan_frm_cbk + + +const uint32_t bes2300p_patch21_ins_data_t2[] = +{ + 0x4620461d, /*6d00*/ + 0x463a4629, + 0xf5f94633, + 0xbdf8fc2b, /*6d0c*/ +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch21 = //from bes2300p_t2_ibrt_ins_patch0 +{ + 21, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch21_ins_data_t2), + 0x000070ec, + 0xbe08f1ff, + 0xc0006d00, + (uint8_t *)bes2300p_patch21_ins_data_t2 +};//assert warn + +const uint32_t bes2300p_patch22_ins_data_t2[] = +{ + 0x4630461f, /*6d14*/ + 0x462a4639, + 0xf5f94623, + 0xbdf8fc21, /*6d20*/ +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch22 = //from bes2300p_t2_ibrt_ins_patch1 +{ + 22, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch22_ins_data_t2), + 0x00007070, + 0xbe50f1ff, + 0xc0006d14, + (uint8_t *)bes2300p_patch22_ins_data_t2 +};//assert param + +const uint32_t bes2300p_patch23_ins_data_t2[] = +{ + 0x2a140c92, /*6d30*/ + 0x2214bf28, + 0xbf004691, + 0xbc44f623, /*6d3c*/ +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch23 = //from bes2300p_t2_ibrt_ins_patch40 +{ + 23, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch23_ins_data_t2), + 0x0002a5c4, + 0xbbb4f1dc, + 0xc0006d30, + (uint8_t *)bes2300p_patch23_ins_data_t2 +};//max_drift limit + +const uint32_t bes2300p_patch24_ins_data_t2[] = +{ + /*6d9c*/ 0x4b179a0b, + /*6da0*/ 0xd023429a, + /*6da4*/ 0x20b5f894, + /*6da8*/ 0xb9fab2d2, + /*6dac*/ 0xf9b4b22e, + /*6db0*/ 0x1b9b3098, + /*6db4*/ 0xf9b24a0f, + /*6db8*/ 0x42932000, + /*6dbc*/ 0x4251da05, + /*6dc0*/ 0xdd02428b, + /*6dc4*/ 0x7088f8d4, + /*6dc8*/ 0x4293e00f, + /*6dcc*/ 0xf8d4dd05, + /*6dd0*/ 0x3f017088, + /*6dd4*/ 0x4778f027, + /*6dd8*/ 0x4252e007, + /*6ddc*/ 0xda044293, + /*6de0*/ 0x7088f8d4, + /*6de4*/ 0xf0273701, + /*6de8*/ 0xbf004778, + /*6dec*/ 0x708cf8c4, + /*6df0*/ 0xbce4f623, // jump a002a7bc + /*6df4*/ 0xc0006df8, + /*6df8*/ 0x00000032, // 50 + /*6dfc*/ 0xa003477b, // ld_acl_sniff_frm_isr lr +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch24 = //from bes2300p_t2_ibrt_ins_patch46 +{ + 24, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch24_ins_data_t2), + 0x0002a7b8, + 0xbaf0f1dc, // jump a002a7b8 -> a0206d9c + 0xc0006d9c, + (uint8_t *)bes2300p_patch24_ins_data_t2 +};//ld_acl_rx_sync clk_off cal active mode + + +const uint32_t bes2300p_patch25_ins_data_t2[] = +{ + /*6e10*/ 0xbf00669a, + /*6e14*/ 0x66da466a,//mov r2, sp; str r2, [r3, #108] + /*6e18*/ 0x8208f3ef,//mrs r2, MSP + /*6e1c*/ 0xbf00671a,//str r2, [r3, #112] + /*6e20*/ 0x8209f3ef,//mrs r2, PSP + /*6e24*/ 0xbf00675a,//str r2, [r3, #116] + /*6e28*/ 0xbf00bf00, + /*6e2c*/ 0xbf00bf00, + /*6e30*/ 0xbf00bf00, + /*6e34*/ 0xbf00bf00, + /*6e38*/ 0xbf00bf00, + /*6e3c*/ 0xbf00bf00, + /*6e40*/ 0xbf00bf00, + /*6e44*/ 0xbf00bf00, + /*6e48*/ 0xbf00bf00, + /*6e4c*/ 0xbf00bf00, + /*6e50*/ 0xba90f600,//jump a0206e50 -> a0007374 +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch25 = //from bes2300p_t2_ibrt_ins_patch15 +{ + 25, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch25_ins_data_t2), + 0x00007360, + 0xbd56f1ff, // jump a0007360 -> a0206e10 + 0xc0006e10, + (uint8_t *)bes2300p_patch25_ins_data_t2 +};//bt_assert_crash_dump + +#define PATCH_IN_EXTRA_SPACE 1 +#if PATCH_IN_EXTRA_SPACE +const uint32_t bes2300p_patch26_ins_data_t2[] = +{ + 0xd8092b01,/*70d0*/ + 0xfb03236e, + 0x4a04f308, + 0xf4135a9b, + 0xd1016f00,/*70e0*/ + 0xb919f629, + 0xb9aef629, + 0xd0211200,/*70ec*/ +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch26 = //from bes2300p_t2_ibrt_ins_patch44 +{ + 26, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch26_ins_data_t2), + 0x00030314, + 0xbedcf1d6, + 0xc00070d0, + (uint8_t *)bes2300p_patch26_ins_data_t2 +};//lmp tx for tx desc error + +const uint32_t bes2300p_patch27_ins_data_t2[] = +{ + 0xfeecf5f8, /*7300*/ + 0xbf00bf00, + 0x8310f3ef, + 0x0401f013, + 0xb672d108, /*7310*/ + 0xff22f5f8, + 0xbf30b110, + 0xd1ef2c00, + 0xe7edb662, /*7320*/ + 0xff1af5f8, + 0xd1f62800, + 0xbf00e7e8, /*732c*/ +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch27 = //from bes2300p_t2_ibrt_ins_patch13 +{ + 27, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch27_ins_data_t2), + 0x0000721c, + 0xb870f200, + 0xc0007300, + (uint8_t *)bes2300p_patch27_ins_data_t2 +}; + +const uint32_t bes2300p_patch28_ins_data_t2[] = +{ + 0xf885b2db, /*7338*/ + 0xf89530bd, + 0x2a0220b4, /*7340*/ + 0xb98bd114, + 0xf8534b0a, + 0xf6430024, + 0xf895fd15, /*7350*/ + 0x2b0430b5, + 0x4620d103, + 0xf6232116, + 0x4620fc61, /*7360*/ + 0xf6242116, + 0xbf00f961, + 0xbc6bf62d, + 0xbc53f62d, /*7370*/ + 0xc0000998, /*7374*/ +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch28 = //from bes2300p_t2_ibrt_ins_patch15 +{ + 28, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch28_ins_data_t2), + 0x00034c14, + 0xbb90f1d2, + 0xc0007338, + (uint8_t *)bes2300p_patch28_ins_data_t2 +};//no disconnect evt +#endif /* PATCH_IN_EXTRA_SPACE */ + + +/////2300p t2 patch +static const uint32_t best2300p_t2_ins_patch_config[] = +{ + 29, + (uint32_t)&bes2300p_t2_ins_patch0, + (uint32_t)&bes2300p_t2_ins_patch1, + (uint32_t)&bes2300p_t2_ins_patch2, + (uint32_t)&bes2300p_t2_ins_patch3, + (uint32_t)&bes2300p_t2_ins_patch4, + (uint32_t)&bes2300p_t2_ins_patch5, + (uint32_t)&bes2300p_t2_ins_patch6, + (uint32_t)&bes2300p_t2_ins_patch7, + (uint32_t)&bes2300p_t2_ins_patch8, + (uint32_t)&bes2300p_t2_ins_patch9, + (uint32_t)&bes2300p_t2_ins_patch10, + (uint32_t)&bes2300p_t2_ins_patch11, + (uint32_t)&bes2300p_t2_ins_patch12, + (uint32_t)&bes2300p_t2_ins_patch13, + (uint32_t)&bes2300p_t2_ins_patch14, + (uint32_t)&bes2300p_t2_ins_patch15, + (uint32_t)&bes2300p_t2_ins_patch16, + (uint32_t)&bes2300p_t2_ins_patch17, + (uint32_t)&bes2300p_t2_ins_patch18, + (uint32_t)&bes2300p_t2_ins_patch19, + (uint32_t)&bes2300p_t2_ins_patch20, + (uint32_t)&bes2300p_t2_ins_patch21, + (uint32_t)&bes2300p_t2_ins_patch22, + (uint32_t)&bes2300p_t2_ins_patch23, + (uint32_t)&bes2300p_t2_ins_patch24, + (uint32_t)&bes2300p_t2_ins_patch25, + (uint32_t)&bes2300p_t2_ins_patch26, + (uint32_t)&bes2300p_t2_ins_patch27, + (uint32_t)&bes2300p_t2_ins_patch28, +}; + +#else +/*************************************************************************** + * + * instruction patch Information + * + * BT ROM Chip Version:1302 T2 (CHIP ID=1) + * + * IBRT function + * + * patch 3: 0xC0006900--->0xC0006910 + * patch 45:0xC0006930--->0xC0006940 + * patch 5: 0xC000694c--->0xC0006980 + * patch 14: 0xC000698c--->0xC00069cc + * patch 16: 0xC0006a18--->0xC0006a28//REMOVE + * patch 19: 0xC0006a2c--->0xC0006a9c + * patch 20: 0xC0006aa4--->0xC0006ab0 + * patch 21: 0xC0006ab4--->0xC0006ad0 + * patch 2: 0xC0006ae8--->0xC0006b04 + * patch 22: 0xC0006b30--->0xC0006b4c + * patch 22: 0xC0006b54--->0xC0006b7c + * patch 29: 0xC0006ba0--->0xC0006ba8 + * patch 30: 0xC0006bac--->0xC0006bc8 + * patch 32: 0xC0006be8--->0xC0006c14 + * patch 33: 0xC0006c1c--->0xC0006c2c + * patch 34: 0xC0006c30--->0xC0006c44 + * patch 35: 0xC0006c48--->0xC0006c84 + * patch 36: 0xC0006c88--->0xC0006c98 + * patch 37: 0xC0006ca0--->0xC0006cb8 + * patch 38: 0xC0006cc0--->0xC0006cf8 + * patch 0: 0xC0006d00--->0xC0006d0c + * patch 1: 0xC0006d14--->0xC0006d20 + * patch 44: 0xC0006d24--->0xC0006d2c (via ble) + * patch 40: 0xC0006d30--->0xC0006d40 + * patch 45: 0xC0006d50--->0xC0006d90 + * patch 46: 0xC0006d9c--->0xC0006dfc + * patch 47: 0xC0006e00--->0xC0006e28 + * patch 48: 0xC0006e30--->0xC0006e98 + * patch 49: 0xC0006ec0--->0xC0006ed0 + * patch 50: 0xC0006ed8--->0xC0006f2c + * patch 51: 0xC0006f30--->0xC0006f5c + * patch 53: 0xC0006f74--->0xC0006f8c + * patch 25: 0xC0006f90--->0xc0007074 + * patch 55: 0xC00070a4--->0xC00070c4 + * patch 44: 0xC00070d0--->0xC00070ec + * sniffer_filter_tab: 0xC00070f4--->0xC0007130 + * patch 7: 0xC0007138--->0xC0007164 + * patch 23: 0xC0007180--->0xC000720c + * patch 17: 0xC00072b4--->0xC00072ec + * patch 13: 0xC0007300--->0xC0007330 + * patch 15: 0xC0007338--->0xC0007374 + * patch 31: 0xC000737c--->0xC0007a4 + * patch 54: 0xC00073cc--->0XC00074E4(new) + ****************************************************************************/ +//#define ECC_LL_MONITOR + +const uint32_t bes2300p_patch0_ibrt_ins_data_t2[] = +{ + /*6d00*/ 0x4673b408, + /*6d04*/ 0x0f20f013, + /*6d08*/ 0xbc08d002, + /*6d0c*/ 0xb9e5f600, //jump a00070da + /*6d10*/ 0xbf00bc08, + /*6d14*/ 0x4b014699, + /*6d18*/ 0xbaeaf600, //jump a00072f0 + /*6d1c*/ 0xc0000050, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch0 = +{ + 0, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch0_ibrt_ins_data_t2), + 0x000072ec, + 0xbd08f1ff, //jump a00072ec -> a0206d00 + 0xc0006d00, + (uint8_t *)bes2300p_patch0_ibrt_ins_data_t2 +};//assert warn, assert param + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch1 = +{ + 1, + BTDRV_PATCH_ACT, + 0, + 0x0001ff2c, + 0xb81af000, //jump a001ff2c -> a001ff64 + 0, + NULL +};//KE_MSG_HANDLER(lc_op_loc_unsniff_req) + + +#if 0 +const uint32_t bes2300p_patch2_ibrt_ins_data_t2[] = +{ + 0x460a4603,/*6ae8*/ + 0x46194802, + 0xfcb6f5fc, + 0xbf00bd38, + 0xc0006afc,/*6af8*/ + 0x73617243, + 0x73252c68, + 0x0064252c,/*6b04*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch2 = +{ + 2, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch2_ibrt_ins_data_t2), + 0x00007018, + 0xbd66f1ff, + 0xc0006ae8, + (uint8_t *)bes2300p_patch2_ibrt_ins_data_t2 +};//"Crash,%s,%d", file, line +#elif 1 +#if 0 +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch2 = +{ + 2, + BTDRV_PATCH_ACT, + 0, + 0x00007024, + 0xbf00e011, + 0, + NULL +};//dont call rwip_assert_err when assert error +#else +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch2 = +{ + 2, + BTDRV_PATCH_ACT, + 0, + 0x0002d8b0, //0xa002d8b0 + 0xbf00bf00, + 0, + NULL +};//ld_acl_rsw_frm_isr +#endif +#else +const uint32_t bes2300p_patch2_ibrt_ins_data_t2[] = +{ + 0xfc12f631,/*7780*/ + 0xb1337843, + 0x0518f100, + 0xf5fb4628, + 0x2813fed9, + 0xf605d804, + 0xbf00fba1, + 0xba24f60c, + 0xba23f60c /*77a0*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch2 = +{ + 2, + BTDRV_PATCH_INACT, + sizeof(bes2300p_patch2_ibrt_ins_data_t2), + 0x00013be4, + 0xbdccf1f3, + 0xc0007780, + (uint8_t *)bes2300p_patch2_ibrt_ins_data_t2 +};//lc_afh_set use mobile afh +#endif + +const uint32_t bes2300p_patch3_ibrt_ins_data_t2[] = +{ + 0xd1052800,/*6900*/ + 0x000cf1aa, + 0xf97af5fa, + 0xbc48f61a, + 0xbbd2f61a,/*6910*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch3 = +{ + 3, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch3_ibrt_ins_data_t2), + 0x000210b4, + 0xbc24f1e5, + 0xc0006900, + (uint8_t *)bes2300p_patch3_ibrt_ins_data_t2 +};//lmp filter free heap + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch4 = +{ + 4, + BTDRV_PATCH_ACT, + 0, + 0x0002be90, + 0xbd702000, + 0, + NULL +}; //ld_check_if_need_protect_sniff retrun 0 + +#if 0 +const uint32_t bes2300p_patch5_ibrt_ins_data_t2[] = +{ + /*6950*/ 0x0f01f013, + /*6954*/ 0x4b06d00a, + /*6958*/ 0x104ff893, + /*695c*/ 0xd8052902, + /*6960*/ 0x2a027a9a, + /*6964*/ 0xbf00d802, + /*6968*/ 0xbc73f632, + /*696c*/ 0xbf00bd08, + /*6970*/ 0xc00063c8, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch5 = +{ + 5, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch5_ibrt_ins_data_t2), + 0x0003924c, + 0xbb80f1cd, // jump a00384dc -> a0206950 + 0xc0006950, + (uint8_t *)bes2300p_patch5_ibrt_ins_data_t2 +}; //protect link id when send bitoffset + +const uint32_t bes2300p_patch6_ibrt_ins_data_t2[] = +{ + /*6978*/ 0x5023f852, + /*697c*/ 0xd0012d00, + /*6980*/ 0xbc04f611,// jump a0206980 -> a001818c + /*6984*/ 0xbd382000, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch6 = +{ + 6, + BTDRV_PATCH_INACT, + sizeof(bes2300p_patch6_ibrt_ins_data_t2), + 0x00018188, + 0xbbf6f1ee, // jump a0018188 -> a0206978 + 0xc0006978, + (uint8_t *)bes2300p_patch6_ibrt_ins_data_t2 +};//protect null ptr when send afh +#else +const uint32_t bes2300p_patch5_ibrt_ins_data_t2[] = +{ + /*694c*/ 0xf632b1c0, + /*6950*/ 0xb1a8fc1b, + /*6954*/ 0x70b2f898, + /*6958*/ 0xfc2af632, + /*695c*/ 0xd10d4287, + /*6960*/ 0xfbfaf634, + /*6964*/ 0xbf142804, + /*6968*/ 0x22012200, + /*696c*/ 0x46294640, + /*6970*/ 0xf6259b03, + /*6974*/ 0x2001fae5, + /*6978*/ 0xbecef625, + /*697c*/ 0xbc6cf625, + /*6980*/ 0xbcc9f625, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch5 = +{ + 5, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch5_ibrt_ins_data_t2), + 0x0002c230, + 0xbb8cf1da, // jump a002c230 -> a020694c + 0xc000694c, + (uint8_t *)bes2300p_patch5_ibrt_ins_data_t2 +};//ld_cal_timestamp + +#if 1 +const uint32_t bes2300p_patch6_ibrt_ins_data_t2[] = +{ + 0x79ab4688, + 0x6383ea6f, + 0x4578f023, + 0xf8d39b09, + 0x9906308c, + 0x402b440b, + 0xbf004641, + 0xbb87f62c, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch6 = +{ + 6, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch6_ibrt_ins_data_t2), + 0x000330f4, + 0xbc6ef1d3, // jump a00330f4 -> a02069d4 + 0xc00069d4, + (uint8_t *)bes2300p_patch6_ibrt_ins_data_t2 +};//sco param init +#else +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch6 = +{ + 6, + BTDRV_PATCH_ACT, + 0, + 0x00007010, //a0007010 + 0xb9bef000, //jump a0007390 + 0, + NULL, +};//DEF_IRQHandler +#endif + +#endif +const uint32_t bes2300p_patch7_ibrt_ins_data_t2[] = +{ + /*7138*/ 0x28024604, + /*713c*/ 0xf89ad812, + /*7140*/ 0x28020046, + /*7144*/ 0xf610d803, + /*7148*/ 0x2800fb1b, + /*714c*/ 0x2112d106, + /*7150*/ 0xf61b20ff, + /*7154*/ 0x2000fec9, + /*7158*/ 0xbb0af633, + /*715c*/ 0xbf004620, + /*7160*/ 0xba4ef633, + /*7164*/ 0xbad8f633, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch7 = +{ + 7, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch7_ibrt_ins_data_t2), + 0x0003a5f8, + 0xbd9ef1cc, // jump a003a5f8 -> a0207138 + 0xc0007138, + (uint8_t *)bes2300p_patch7_ibrt_ins_data_t2 +};//start simu link check linkid + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch8 = +{ + 8, + BTDRV_PATCH_ACT, + 0, + 0x0002e720, + 0xf8a62308, + 0, + NULL, +};//ld_acl_start t_poll + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch9 = +{ + 9, + BTDRV_PATCH_ACT, + 0, + 0x0002d82c, + 0x2b006013, + 0, + NULL, +};//ld_acl_rsw_rx + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch10 = +{ + 10, + BTDRV_PATCH_ACT, + 0, + 0x0002fe60, + 0xbf00e001, + 0, + NULL, +};//ld_acl_flow_on + +#ifdef ECC_LL_MONITOR +////patch 11 12 13 used for ecc count by set it to ll monitor parameter +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch11 = +{ + 11, + BTDRV_PATCH_ACT, + 0, + 0x0002dc94, + 0x7000f400, + 0, + NULL +};////wrong flag + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch12 = +{ + 12, + BTDRV_PATCH_ACT, + 0, + 0x0002dc98, + 0x2800bf00, + 0, + NULL +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch13 = +{ + 13, + BTDRV_PATCH_ACT, + 0, + 0x0002f78c, + 0x46288113, + 0, + NULL +}; +#else +const uint32_t bes2300p_patch11_ibrt_ins_data_t2[] = +{ + 0x0034f104, + 0x220a4649, + 0xfd86f644, + 0xf632b940, + 0x2801fa39, + 0xf632d104, + 0x2800fb0d, + 0xbf00d104, + 0x00c5f894, + 0xb97cf62b, + 0xb9eaf62b, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch11 = +{ + 11, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch11_ibrt_ins_data_t2), + 0x00031e70, + 0xbe70f1d4, + 0xc0006b54, + (uint8_t *)bes2300p_patch11_ibrt_ins_data_t2 +};//filter afh map + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch12 = +{ + 12, + BTDRV_PATCH_ACT, + 0, + 0x0002a41c, + 0xbf000f01, + 0, + NULL +};//mode == SYNC2_SCO_MODE + +const uint32_t bes2300p_patch13_ibrt_ins_data_t2[] = +{ + 0xfeecf5f8, + 0xbf00bf00, + 0x8310f3ef, + 0x0401f013, + 0xb672d108, + 0xff22f5f8, + 0xbf30b110, + 0xd1ef2c00, + 0xe7edb662, + 0xff1af5f8, + 0xd1f62800, + 0xbf00e7e8, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch13 = +{ + 13, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch13_ibrt_ins_data_t2), + 0x0000721c, + 0xb870f200, + 0xc0007300, + (uint8_t *)bes2300p_patch13_ibrt_ins_data_t2 +}; +#endif + +const uint32_t bes2300p_patch14_ibrt_ins_data_t2[] = +{ + /*698c*/ 0x4604b510, + /*6990*/ 0xfc0ef632, + /*6994*/ 0xd00542a0, + /*6998*/ 0x7a984b03, + /*699c*/ 0xbf181b00, + /*69a0*/ 0xbd102001, + /*69a4*/ 0xbd102000, + /*69a8*/ 0xc00063c8, + /*69ac*/ 0x461f7a9e, + /*69b0*/ 0x46104625, + /*69b4*/ 0xffeaf7ff, + /*69b8*/ 0xd1072800, + /*69bc*/ 0x46392004, + /*69c0*/ 0xfc74f634, + /*69c4*/ 0x462c2003, + /*69c8*/ 0xbd68f634, + /*69cc*/ 0xbf00bdf8, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch14 = +{ + 14, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch14_ibrt_ins_data_t2), + 0x0003b498, + 0xba88f1cb, // jump a003b498 -> a02069ac + 0xc000698c, + (uint8_t *)bes2300p_patch14_ibrt_ins_data_t2 +};//protect idx when snoop disconnect + +#if 0 +const uint32_t bes2300p_patch15_ibrt_ins_data_t2[] = +{ + /*69D0*/ 0xbf00669a, + /*69D4*/ 0x66da466a,//mov r2, sp; str r2, [r3, #108] + /*69D8*/ 0x8208f3ef,//mrs r2, MSP + /*69DC*/ 0xbf00671a,//str r2, [r3, #112] + /*69E0*/ 0x8209f3ef,//mrs r2, PSP + /*69E4*/ 0xbf00675a,//str r2, [r3, #116] + /*69E8*/ 0xbf00bf00, + /*69EC*/ 0xbf00bf00, + /*69F0*/ 0xbf00bf00, + /*69F4*/ 0xbf00bf00, + /*69F8*/ 0xbf00bf00, + /*69FC*/ 0xbf00bf00, + /*6A00*/ 0xbf00bf00, + /*6A04*/ 0xbf00bf00, + /*6A08*/ 0xbf00bf00, + /*6A0C*/ 0xbf00bf00, + /*6A10*/ 0xbcb0f600,//jump a0206a10 -> a0007374 +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch15 = +{ + 15, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch15_ibrt_ins_data_t2), + 0x00007360, + 0xbb36f1ff, // jump a0007360 -> a02069d0 + 0xc00069d0, + (uint8_t *)bes2300p_patch15_ibrt_ins_data_t2 +};//bt_assert_crash_dump +#else + +const uint32_t bes2300p_patch15_ibrt_ins_data_t2[] = +{ + 0xf885b2db,/*7338*/ + 0xf89530bd, + 0x2a0220b4, + 0xb98bd114, + 0xf8534b0a,/*7348*/ + 0xf6430024, + 0xf895fd15, + 0x2b0430b5, + 0x4620d103,/*7358*/ + 0xf6232116, + 0x4620fc61, + 0xf6242116, + 0xbf00f961,/*7368*/ + 0xbc6bf62d, + 0xbc53f62d, + 0xc0000998,/*7374*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch15 = +{ + 15, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch15_ibrt_ins_data_t2), + 0x00034c14, + 0xbb90f1d2, + 0xc0007338, + (uint8_t *)bes2300p_patch15_ibrt_ins_data_t2 +};//no disconnect evt +#endif + +const uint32_t bes2300p_patch16_ibrt_ins_data_t2[] = +{ + 0x71ab2300, + 0x0000f8d9, + 0x380cb110, + 0xf96cf5fa, + 0xbf002300, + 0xbce2f608, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch16 = +{ + 16, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch16_ibrt_ins_data_t2), + 0x0000f2f0, + 0xbb12f1f7, + 0xc0006918, + (uint8_t *)bes2300p_patch16_ibrt_ins_data_t2 +};//lm_page_scan_end_ind free msg + +#if 0 +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch17 = +{ + 17, + BTDRV_PATCH_ACT, + 0, + 0x00007010, //a0007010 + 0xb9bef000, //jump a0007390 + 0, + NULL, +};//DEF_IRQHandler +#elif 1 +const uint32_t bes2300p_patch17_ibrt_ins_data_t2[] = +{ + 0x4605b538,/*72b4*/ + 0xfe76f631, + 0x7a834604, + 0x2f15ebb3, + 0x7803d10a,/*72c4*/ + 0xd1072b02, + 0xff5cf631, + 0xf894b120, + 0x2101004f,/*72d4*/ + 0xfc78f61d, + 0xbf00bd38, + 0x3312f886, + 0xbf004620,/*72e4*/ + 0xffe4f7ff, + 0xbcfaf614, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch17 = +{ + 17, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch17_ibrt_ins_data_t2), + 0x0001bce0, + 0xbafef1eb, + 0xc00072b4, + (uint8_t *)bes2300p_patch17_ibrt_ins_data_t2 +};//send unsniff cmd + +#else +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch17 = +{ + 17, + BTDRV_PATCH_ACT, + 0, + 0x0002e674, + 0x53faf44f, + 0, + NULL, +};//lc start lsto 5s +#endif + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch18 = +{ + 18, + BTDRV_PATCH_ACT, + 0, + 0x0002f264, + 0xbf00e001, + 0, + NULL, +};//close tx seq force set after start IBRT + +const uint32_t bes2300p_patch19_ibrt_ins_data_t2[] = +{ + 0xd01e0fdb,/*6a2c*/ + 0x6307f44f, + 0xf304fb03, + 0x48168f6a, + 0x93011810, + 0x49154418, + 0xfe22f644, + 0x58fb4b14, + 0x4301f3c3, + 0xf1028f2a, + 0xf5024250, + 0xf2021205, + 0x8f6942fc, + 0x0241eb02, + 0x440a9901, + 0x600a490d, + 0xf44fe010, + 0xfb036307, + 0x9301f304, + 0x18184806, + 0x8f6a4906, + 0xfe04f644, + 0x58fb4b05, + 0x4381f3c3, + 0xb9a9f62e, + 0xb9aff62e, + 0xd02144fc, + 0xc000593c, + 0xd0220144, + 0xc000005c,/*6a9c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch19 = +{ + 19, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch19_ibrt_ins_data_t2), + 0x00034d80, + 0xbe54f1d1, + 0xc0006a2c, + (uint8_t *)bes2300p_patch19_ibrt_ins_data_t2 +};//ld_sco_frm_isr + +const uint32_t bes2300p_patch20_ibrt_ins_data_t2[] = +{ + 0xbf002004,/*6aa4*/ + 0xfb5cf634,/*6aa8*/ + 0xb8c4f618,/*6aac*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch20 = +{ + 20, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch20_ibrt_ins_data_t2), + 0x0001ec10, + 0xbf48f1e7, + 0xc0006aa4, + (uint8_t *)bes2300p_patch20_ibrt_ins_data_t2 +};//ibrt sco status update + +const uint32_t bes2300p_patch21_ibrt_ins_data_t2[] = +{ + 0xf6414631, + 0x4620fc1b, + 0xf6064631, + 0x4a03faaf, + 0xf4436813, + 0x60130380, + 0xbdddf633, + 0xd0220468, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch21 = +{ + 21, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch21_ibrt_ins_data_t2), + 0x0003a684, + 0xba16f1cc, // jump a003a684 -> a0206ab4 + 0xc0006ab4, + (uint8_t *)bes2300p_patch21_ibrt_ins_data_t2 +};//register address at LM layer and open fa en register + +#if 0 +const uint32_t bes2300p_patch22_ibrt_ins_data_t2[] = +{ + 0x4681b083,/*6b30*/ + 0x4b022200, + 0x2020f843, + 0xbddcf623, + 0xc0006b44, + 0x00000000, + 0x00000000, + 0x00000000,/*6b4c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch22 = +{ + 22, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch22_ibrt_ins_data_t2), + 0x0002a6f4, + 0xba1cf1dc, + 0xc0006b30, + (uint8_t *)bes2300p_patch22_ibrt_ins_data_t2 +};//sync clear count +#else +const uint32_t bes2300p_patch22_ibrt_ins_data_t2[] = +{ + 0x4681b083, + 0x4b042200, + 0x2020f843, + 0x601a4b0d, + 0x601a4b0d, + 0xb8b0f623, + 0xc000759c, + 0x00000000,//link_no_sync_count + 0x00000000, + 0x00000000, + 0x00000018,//link_agc_thd + 0x00000000, //rssi_store_tws + 0x00000006, //rssi_tws_step + 0x00000000, //rssi_store_mobile + 0x00000006, //rssi_mobile_step + 0x0000009c, //rssi_min_value_tws + 0x0000009c, //rssi_min_value_mobile + 0xc00075ac, //rssi_store_tws + 0xc00075b4, //rssi_store_mobile + +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch22 = +{ + 22, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch22_ibrt_ins_data_t2), + 0x0002a6f4, + 0xbf44f1dc, + 0xc0007580, + (uint8_t *)bes2300p_patch22_ibrt_ins_data_t2 +};//sync clear count +#endif + +#if 0 +const uint32_t bes2300p_patch23_ibrt_ins_data_t2[] = +{ + 0x6020f853,/*6b50*/ + 0xf8524a0d, + 0x33013020, + 0x3020f842, + 0x68124a0b, + 0xd90f4293, + 0x4a082300, + 0x3020f842, + 0xb082b402, + 0x92004a08, + 0xf06f6a14, + 0x46290059, + 0x47a02201, + 0xbc02b002, + 0xbce4f623, + 0xc0006b44, + 0xc0006b94, + 0x00000050, + 0xc00041b4,/*6b98*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch23 = +{ + 23, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch23_ibrt_ins_data_t2), + 0x0002a550, + 0xbafef1dc, + 0xc0006b50, + (uint8_t *)bes2300p_patch23_ibrt_ins_data_t2 +};////swagc no sync +#elif 0 + +const uint32_t bes2300p_patch23_ibrt_ins_data_t2[] = +{ + 0xf6324620, + 0xb480fce9, + 0xfb07276e, + 0x4a1ff704, + 0xf837bf00, + 0xf4133002, + 0xd12b4f00, + 0xf8524a17, + 0x33013024, + 0x3024f842, + 0x68124a15, + 0xd8124293, + 0x3084f8d5, + 0xf0221af2, + 0xf1b14178, + 0xd9066f80, + 0xf0231b9b, + 0x425b4378, + 0xdc042b64, + 0xf022e012, + 0x2a644278, + 0x2300dd0e, + 0xf8424a08, + 0xb0823024, + 0x92004a09, + 0xc020f8d2, +// 0x0036f06f, + 0x004cf06f, + 0x22014621, + 0xb00247e0, + 0xbf00bc80, + 0xbbeff62d, + 0xc0006b44, + 0xc0007204, + 0x0000003c, + 0xc00041b4, + 0xd02111f8,//720c +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch23 = +{ + 23, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch23_ibrt_ins_data_t2), + 0x000349d4, + 0xbbd4f1d2, + 0xc0007180, + (uint8_t *)bes2300p_patch23_ibrt_ins_data_t2 +};////swagc no sync +#else +const uint32_t bes2300p_patch23_ibrt_ins_data_t2[] = +{ + 0xfb03236e, + 0x4a3ef300, + 0xf4135a9b, + 0xd1764f00, + 0xb082b570, + 0xf8534b3b, + 0x4a3b4020, + 0x3020f852, + 0xf8423301, + 0x4a393020, + 0x42936812, + 0xf8d4d812, + 0x1aca3084, + 0x4578f022, + 0x6f80f1b5, + 0x1a5bd906, + 0x4378f023, + 0x2b64425b, + 0xe04ddc04, + 0x4278f022, + 0xdd492a64, + 0x681b4b2e, + 0xd11d4298, + 0xf9934b2d, + 0xb93b3000, + 0x30acf9b4, + 0x20aef894, + 0xf3f2fb93, + 0x70134a28, + 0x78134a27, + 0x78094927, + 0xb2db1a5b, + 0x4a267013, + 0xb25b7812, + 0x428bb251, + 0x4b21bfbc, + 0x4b20701a, + 0xe01c781e, + 0xf9934b21, + 0xb93b3000, + 0x30acf9b4, + 0x20aef894, + 0xf3f2fb93, + 0x70134a1c, + 0x78134a1b, + 0x7809491b, + 0xb2db1a5b, + 0x4a1a7013, + 0xb25b7812, + 0x428bb251, + 0x4b15bfbc, + 0x4b14701a, + 0x4601781e, + 0x4a0c2300, + 0x3020f842, + 0x92004a13, + 0xb2706a15, + 0x47a82201, + 0x30aef894, + 0xd9042b95, + 0xf8a42300, + 0xf88430ac, + 0xb00230ae, + 0x4770bd70, + 0xd02111f8, + 0xc0000998, + 0xc000759c, + 0xc00075a8, + 0xc0006e2c, + 0xc00075ac, + 0xc00075b0, + 0xc00075bc, + 0xc00075b4, + 0xc00075b8, + 0xc00075c0, + 0xc00041b4, + 0xf6324620, + 0x4620f9f7, + 0xf7ff4631, + 0xbf00ff61, + 0xb931f62d +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch23 = +{ + 23, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch23_ibrt_ins_data_t2), + 0x000349d4, + 0xbec6f1d2, + 0xc0007634, + (uint8_t *)bes2300p_patch23_ibrt_ins_data_t2 +};////swagc no sync + +#endif + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch24 = +{ + 24, + BTDRV_PATCH_ACT, + 0, + 0x0000fe0c, + 0xf029bf00, + 0, + NULL, +};//filter tws link lc_sco_ind ke message + +const uint32_t bes2300p_patch25_ibrt_ins_data_t2[] = +{ + /*6f90*/ 0xbf009904, + /*6f94*/ 0x4b12b470, + /*6f98*/ 0x010e5c5a, + /*6f9c*/ 0x19734d11, + /*6fa0*/ 0x78244c11, + /*6fa4*/ 0xd20342a2, + /*6fa8*/ 0x32015498, + /*6fac*/ 0xe001b2d2, + /*6fb0*/ 0x22015570, + /*6fb4*/ 0x5442480a, + /*6fb8*/ 0x461ab14c, + /*6fbc*/ 0x23001919, + /*6fc0*/ 0x0b01f912, + /*6fc4*/ 0xbf004403, + /*6fc8*/ 0xd1f9428a, + /*6fcc*/ 0x2300e000, + /*6fd0*/ 0xf0f4fb93, + /*6fd4*/ 0xbc70b240, + /*6fd8*/ 0x22019904, + /*6fdc*/ 0xbb8cf628, //jump a002f6f8 + /*6fe0*/ 0xc0006ff0, //addr of rssi_idx_for_agc + /*6fe4*/ 0xc0006ff4, //addr of rssi_set_for_agc + /*6fe8*/ 0xc0006fec, //addr of N + /*6fec*/ 0x00000005, //N : 1 ~ 16 + /*6ff0*/ 0x00000000, //rssi_idx_for_agc[3] + /*6ff4*/ 0xbabababa, //rssi_set_for_agc[3*16] + /*6ff8*/ 0xbabababa, + /*6ffc*/ 0xbabababa, + /*7000*/ 0xbabababa, + /*7004*/ 0xbabababa, + /*7008*/ 0xbabababa, + /*700c*/ 0xbabababa, + /*7010*/ 0xbabababa, + /*7014*/ 0xbabababa, + /*7018*/ 0xbabababa, + /*701c*/ 0xbabababa, + /*7020*/ 0xbabababa, + /*7024*/ 0xbabababa, + /*7028*/ 0xbabababa, + /*702c*/ 0xbabababa, +};//0xc0006f90--->0xc0007074 + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch25 = +{ + 25, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch25_ibrt_ins_data_t2), + 0x0002f6f4, + 0xbc4cf1d7, //jump a002f6f4 -> a0206f90 + 0xc0006f90, + (uint8_t *)bes2300p_patch25_ibrt_ins_data_t2 +}; //ld_acl_rx() average rssi + + +#if 0 +//ECC patch 1 +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch26 = +{ + 26, + BTDRV_PATCH_ACT, + 0, + 0x00034790, + 0xbf00bf00, + 0, + NULL, +};//ld_acl_sniff_frm_isr ld_get_rx_isr_counter ignore +#else +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch26 = +{ + 26, + BTDRV_PATCH_ACT, + 0, + 0x00029d50, + 0x3300f443, + 0, + NULL, +};//bt_e_scoltcntl_retxnb_setf +#endif + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch27 = +{ + 27, + BTDRV_PATCH_ACT, + 0, + 0x000236e0, + 0xf0172004, + 0, + NULL, +};//LC_WAIT_EXCHANGE_SCO_STATUS_CFM + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch28 = +{ + 28, + BTDRV_PATCH_ACT, + 0, + 0x00039144, + 0x47702001, + 0, + NULL +};//ld_get_sniffer_enter_sniff_flag() forece return 1 + +#if 0 +const uint32_t bes2300p_patch29_ibrt_ins_data_t2[] = +{ + /*6ba0*/ 0xbf0080c6, + /*6ba4*/ 0x71022200, + /*6ba8*/ 0xbb2af619, //jump a0020200 +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch29 = +{ + 29, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch29_ibrt_ins_data_t2), + 0x000201f8, + 0xbcd2f1e6, //jump a00201f8 -> a0206ba0 + 0xc0006ba0, + (uint8_t *)bes2300p_patch29_ibrt_ins_data_t2 +};//KE_MSG_HANDLER(lc_op_loc_sniff_req, void) +#else + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch29 = +{ + 29, + BTDRV_PATCH_ACT, + 0, + 0x00020024, + 0xe00dbf00, + 0, + NULL, +};//detach directly +#endif + +const uint32_t bes2300p_patch30_ibrt_ins_data_t2[] = +{ + /*6bac*/ 0x46286825, + /*6bb0*/ 0x303ef895, + /*6bb4*/ 0xd0012b02, + /*6bb8*/ 0xbda2f622, //jump a0029700 + /*6bbc*/ 0xbf002300, + /*6bc0*/ 0x303ef885, + /*6bc4*/ 0xfea6f622, //call a0029914 + /*6bc8*/ 0xbdc1f622, //jump a002974e +}; +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch30 = +{ + 30, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch30_ibrt_ins_data_t2), + 0x000296fc, + 0xba56f1dd, //jump a00296fc -> a0206bac + 0xc0006bac, + (uint8_t *)bes2300p_patch30_ibrt_ins_data_t2 +};//ld_pscan_frm_cbk + +const uint32_t bes2300p_patch31_ibrt_ins_data_t2[] = +{ + 0x7021f853, + 0xb12fb136, + 0x017ff000, + 0xf8534b06, + 0xb93b3021, + 0x210c20ff, + 0xfda8f61b, + 0xbf002004, + 0xbffcf62b, + 0xbf76f62b, + 0xc0005cd8, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch31 = +{ + 31, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch31_ibrt_ins_data_t2), + 0x0003328c, + 0xb876f1d4, // jump a003328c -> a020737c + 0xc000737c, + (uint8_t *)bes2300p_patch31_ibrt_ins_data_t2 +}; //protect null ptr when acl tws switch + +const uint32_t bes2300p_patch32_ibrt_ins_data_t2[] = +{ + /*6be8*/ 0x46514620, + /*6bec*/ 0x4b09464a, + /*6bf0*/ 0x3022f853, + /*6bf4*/ 0xd10b2901, + /*6bf8*/ 0x0184f103, + /*6bfc*/ 0xbf002206, + /*6c00*/ 0xfd34f644, + /*6c04*/ 0xbf00b920, + /*6c08*/ 0x0802f05f, + /*6c0c*/ 0xba4af641, //jump a00480a4 + /*6c10*/ 0xbaf6f641, //jump a0048200 + /*6c14*/ 0xc0005cd8, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch32 = +{ + 32, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch32_ibrt_ins_data_t2), + 0x00048008, + 0xbdeef1be, // jump a0048008 -> a0206be8 + 0xc0006be8, + (uint8_t *)bes2300p_patch32_ibrt_ins_data_t2 +};//hci_evt_filter_con_check + +const uint32_t bes2300p_patch33_ibrt_ins_data_t2[] = +{ + /*6c1c*/ 0x0024f855, + /*6c20*/ 0xbf003038, + /*6c24*/ 0xfd9ef643, + /*6c28*/ 0x0024f855, + /*6c2c*/ 0xbe9ef60c, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch33 = +{ + 33, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch33_ibrt_ins_data_t2), + 0x00013968, + 0xb958f1f3, // jump a0013968 -> a0206c1c + 0xc0006c1c, + (uint8_t *)bes2300p_patch33_ibrt_ins_data_t2 +};//ea_interval_remove + +const uint32_t bes2300p_patch34_ibrt_ins_data_t2[] = +{ + /*6c30*/ 0xf632d108, + /*6c34*/ 0x2100f9e3, + /*6c38*/ 0xf802f634, + /*6c3c*/ 0xfa8cf634, + /*6c40*/ 0xbb8bf5fb, + /*6c44*/ 0xbbc3f5fb, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch34 = +{ + 34, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch34_ibrt_ins_data_t2), + 0x00002354, + 0xbc6cf204, // jump a0002354 -> a0206c30 + 0xc0006c30, + (uint8_t *)bes2300p_patch34_ibrt_ins_data_t2 +};//close fastack when stop ibrt + +const uint32_t bes2300p_patch35_ibrt_ins_data_t2[] = +{ + /*6c48*/ 0x4b0a0a02, + /*6c4c*/ 0x3022f853, + /*6c50*/ 0xb500b173, + /*6c54*/ 0x4601b083, + /*6c58*/ 0xf88d230f, + /*6c5c*/ 0x23133004, + /*6c60*/ 0x3005f88d, + /*6c64*/ 0xf616a801, + /*6c68*/ 0xb003fbc1, + /*6c6c*/ 0xfb04f85d, + /*6c70*/ 0xbf004770, + /*6c74*/ 0xc0005cd8, + /*6c78*/ 0xbf000230, + /*6c7c*/ 0x0001f040, + /*6c80*/ 0xffe2f7ff, + /*6c84*/ 0xbc5df634 +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch35 = +{ + 35, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch35_ibrt_ins_data_t2), + 0x0003b538, + 0xbb9ef1cb, // jump a003b538 -> a0206c78 + 0xc0006c48, + (uint8_t *)bes2300p_patch35_ibrt_ins_data_t2 +};//snoop disconnect lc_release + +#if 0 +//ECC patch 2 +const uint32_t bes2300p_patch36_ibrt_ins_data_t2[] = +{ + /*6c88*/ 0x701c4b03, + /*6c8c*/ 0x78134a01, + /*6c90*/ 0xbcfcf62d, + /*6c94*/ 0xc0000971, + /*6c98*/ 0xc000032a, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch36 = +{ + 36, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch36_ibrt_ins_data_t2), + 0x00034688, + 0xbafef1d2, // jump a0034688 -> a0206c88 + 0xc0006c88, + (uint8_t *)bes2300p_patch36_ibrt_ins_data_t2 +};//ld_acl_rx_isr set_ecc_recheck_link_id +#else +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch36 = +{ + 36, + BTDRV_PATCH_ACT, + 0, + 0x0002ddc0, + 0x4a07bf00, + 0, + NULL, +};// 1st ibrt ok, ignore sniffer role +#endif + +const uint32_t bes2300p_patch37_ibrt_ins_data_t2[] = +{ + 0x4605b538,/*6ca0*/ + 0xf643460c, + 0x6a00fc79, + 0xd2034285, + 0x28061b40,/*6cb0*/ + 0x2402bf98, + 0xb9fdf627, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch37 = +{ + 37, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch37_ibrt_ins_data_t2), + 0x0002e0b0, + 0xbdf6f1d8, + 0xc0006ca0, + (uint8_t *)bes2300p_patch37_ibrt_ins_data_t2 +};//decrease retx + +#if 0 +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch38 = +{ + 38, + BTDRV_PATCH_ACT, + 0, + 0x00000878, + 0x2300bf00, + 0, + NULL +};//SLEEP EN +#else +const uint32_t bes2300p_patch38_ibrt_ins_data_t2[] = +{ + 0x4604b510,/*6cc0*/ + 0xf6104608, + 0x2c03fd25, + 0x2803d001, + 0x200cd104,/*6cd0*/ + 0xfa4ef61c, + 0xbd102001, + 0xbd102000, + 0xfd18f610,/*6ce0*/ + 0xf1044605, + 0x46280145, + 0xffe8f7ff, + 0xd1012800,/*6cf0*/ + 0xbeb7f633, + 0xbf19f633,/*6cf8*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch38 = +{ + 38, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch38_ibrt_ins_data_t2), + 0x0003aa60, + 0xb93ef1cc, // jump a003aa60 -> a0206cc0 + 0xc0006cc0, + (uint8_t *)bes2300p_patch38_ibrt_ins_data_t2 +};//set env +#endif + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch39 = +{ + 39, + BTDRV_PATCH_ACT, + 0, + 0x0003b450, + 0xbf00bd08, + 0, + NULL +};//do not send ld_sniffer_connect_sco_forward + +const uint32_t bes2300p_patch40_ibrt_ins_data_t2[] = +{ + 0x2a140c92, + 0x2214bf28, + 0xbf004691, + 0xbc44f623,/*6d40*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch40 = +{ + 40, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch40_ibrt_ins_data_t2), + 0x0002a5c4, + 0xbbb4f1dc, + 0xc0006d30, + (uint8_t *)bes2300p_patch40_ibrt_ins_data_t2 +};//max_drift limit + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch41 = +{ + 41, + BTDRV_PATCH_ACT, + 0, + 0x0003acd8, + 0xbf00e005, + 0, + NULL +};///acl tx silence + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch42 = +{ + 42, + BTDRV_PATCH_ACT, + 0, + 0x00033668, + 0xbf00e001, + 0, + NULL +};///do not clear acl env during sco stop + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch43 = +{ + 43, + BTDRV_PATCH_ACT, + 0, + 0x0002a62c, + 0xe001021a, + 0, + NULL +};//rx window adjust for start ibrt + +#if defined(SYNC_BT_CTLR_PROFILE) +const uint32_t bes2300p_patch44_ibrt_ins_data_t2[] = +{ + /*6d24*/ 0xbf004628, + /*6d28*/ 0xfff8f633, + /*6d2c*/ 0xb8f7f611, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch44 = +{ + 44, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch44_ibrt_ins_data_t2), + 0x00017f10, + 0xbf08f1ee, // jump a0017f10 -> a0206d24 + 0xc0006d24, + (uint8_t *)bes2300p_patch44_ibrt_ins_data_t2 +};//send profile via BLE +#else + +const uint32_t bes2300p_patch44_ibrt_ins_data_t2[] = +{ + 0xd8092b01,/*70d0*/ + 0xfb03236e, + 0x4a04f308, + 0xf4135a9b, + 0xd1016f00,/*70e0*/ + 0xb919f629, + 0xb9aef629, + 0xd0211200,/*70ec*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch44 = +{ + 44, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch44_ibrt_ins_data_t2), + 0x00030314, + 0xbedcf1d6, + 0xc00070d0, + (uint8_t *)bes2300p_patch44_ibrt_ins_data_t2 +};//lmp tx for tx desc error +#endif + +#if 0 +const uint32_t bes2300p_patch45_ibrt_ins_data_t2[] = +{ + 0x20aef89b,/*6d50*/ + 0xd1052aa0, + 0xf88b2200, + 0xf8ab20ae, + 0xe01320ac,/*6d60*/ + 0x68194b0b, + 0xf3f1fbb2, + 0x2313fb01, + 0x4b07b963,/*6d70*/ + 0x00acf9bb, + 0x6a1e9300, + 0xfb90bf00, + 0x9904f0f2,/*6d80*/ + 0x2201b240, + 0x47b02300, + 0xbcb6f628, + 0xc00041b4,/*6d90*/ + 0xc0006d98, + 0x0000000a, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch45 = +{ + 45, + BTDRV_PATCH_INACT, + sizeof(bes2300p_patch45_ibrt_ins_data_t2), + 0x0002f6ec, + 0xbb30f1d7, + 0xc0006d50, + (uint8_t *)bes2300p_patch45_ibrt_ins_data_t2 +};//RSSI AVERAGE 10 +#else +const uint32_t bes2300p_patch45_ibrt_ins_data_t2[] = +{ + 0x4a033304,/*6930*/ + 0xbf008153, + 0x12c4f640, + 0xb9bdf632, + 0xc00061b8,/*6940*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch45 = +{ + 45, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch45_ibrt_ins_data_t2), + 0x00038cb0, + 0xbe3ef1cd, + 0xc0006930, + (uint8_t *)bes2300p_patch45_ibrt_ins_data_t2 +};//pscan duration +#endif + +const uint32_t bes2300p_patch46_ibrt_ins_data_t2[] = +{ + /*6d9c*/ 0x4b179a0b, + /*6da0*/ 0xd023429a, + /*6da4*/ 0x20b5f894, + /*6da8*/ 0xb9fab2d2, + /*6dac*/ 0xf9b4b22e, + /*6db0*/ 0x1b9b3098, + /*6db4*/ 0xf9b24a0f, + /*6db8*/ 0x42932000, + /*6dbc*/ 0x4251da05, + /*6dc0*/ 0xdd02428b, + /*6dc4*/ 0x7088f8d4, + /*6dc8*/ 0x4293e00f, + /*6dcc*/ 0xf8d4dd05, + /*6dd0*/ 0x3f017088, + /*6dd4*/ 0x4778f027, + /*6dd8*/ 0x4252e007, + /*6ddc*/ 0xda044293, + /*6de0*/ 0x7088f8d4, + /*6de4*/ 0xf0273701, + /*6de8*/ 0xbf004778, + /*6dec*/ 0x708cf8c4, + /*6df0*/ 0xbce4f623, // jump a002a7bc + /*6df4*/ 0xc0006df8, + /*6df8*/ 0x00000032, // 50 + /*6dfc*/ 0xa003477b, // ld_acl_sniff_frm_isr lr +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch46 = +{ + 46, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch46_ibrt_ins_data_t2), + 0x0002a7b8, + 0xbaf0f1dc, // jump a002a7b8 -> a0206d9c + 0xc0006d9c, + (uint8_t *)bes2300p_patch46_ibrt_ins_data_t2 +};//ld_acl_rx_sync clk_off cal active mode + +const uint32_t bes2300p_patch47_ibrt_ins_data_t2[] = +{ + 0xd10b2800,/*6e00*/ + 0x0f00f1ba, + 0x4a07d10a, + 0x2aff7812, + 0x4615d006,/*6e10*/ + 0x30b2f894, + 0xd10342ab, + 0xb8aff625, + 0xb974f625,/*6e20*/ + 0xb952f625, + 0xc0006e2c, + 0x000000ff,/*6e28*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch47 = +{ + 47, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch47_ibrt_ins_data_t2), + 0x0002bf78, + 0xbf42f1da, + 0xc0006e00, + (uint8_t *)bes2300p_patch47_ibrt_ins_data_t2 +};///adjust slot share for tws without ibrt + +const uint32_t bes2300p_patch48_ibrt_ins_data_t2[] = +{ + 0x781b4b13, + 0xd0212bff, + 0x4604b510, + 0xf946f632, + 0x4b0fb1d8, + 0x4b0f781a, + 0x3022f853, + 0x0f28f113, + 0xf893d013, + 0xeb0330c1, + 0xb2db0342, + 0x0383eb03, + 0x4a09005b, + 0xf3c35a9b, + 0x2b5303c9, + 0x7ea2d905, + 0x441368e3, + 0x4378f023, + 0xbd1060e3, + 0xbf004770, + 0xc0006e2c, + 0xc0000998, + 0xd0211632, + 0x0028f104, + 0xffcef7ff, + 0x60a36b63, + 0xb9fcf627, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch48 = +{ + 48, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch48_ibrt_ins_data_t2), + 0x0002e290, + 0xbdfcf1d8, + 0xc0006e30, + (uint8_t *)bes2300p_patch48_ibrt_ins_data_t2 +};//big packet send in sco v1 + +const uint32_t bes2300p_patch49_ibrt_ins_data_t2[] = +{ + /*6ec0*/ 0xf6232100, + /*6ec4*/ 0xf643feaf, + /*6ec8*/ 0x2300fb69, + /*6ecc*/ 0xbf006243, + /*6ed0*/ 0xbcf4f626, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch49 = +{ + 49, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch49_ibrt_ins_data_t2), + 0x0002d88c, + 0xbb18f1d9, // jump a0018188 -> a0206978 + 0xc0006ec0, + (uint8_t *)bes2300p_patch49_ibrt_ins_data_t2 +};///role switch fail to disconnect + +#if 0 +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch50 = +{ + 50, + BTDRV_PATCH_INACT, + 0, + 0x0003ea94, + 0xbf00e04a, + 0, + NULL +};//ble channel map disable +#elif 0 +const uint32_t bes2300p_patch50_ibrt_ins_data_t2[] = +{ + 0xf8948263, + 0xbf0030b3, + 0xbf00bf00, + 0xbf00bf00, + 0xbf002304, + 0xb8b8f625, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch50 = +{ + 50, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch50_ibrt_ins_data_t2), + 0x0002c024, + 0xbf3cf1da, + 0xc0006ea0, + (uint8_t *)bes2300p_patch50_ibrt_ins_data_t2 +}; +#else +const uint32_t bes2300p_patch50_ibrt_ins_data_t2[] = +{ + 0x75a32312,/*6ed8*/ + 0x001bf898, + 0x1088f8d1, + 0x300cf8d8, + 0xf023440b,/*6ee8*/ + 0xea834378, + 0xf8986380, + 0x1a5b1019, + 0x101af898,/*6ef8*/ + 0xf3f1fbb3, + 0xfbb3b2db, + 0xfb02f1f2, + 0x1ad23311,/*6f08*/ + 0xf894b2d6, + 0xb91330b3, + 0xf8842301, + 0xf5fc30bb,/*6f18*/ + 0xf890fa05, + 0xf5c33025, + 0x3304631c, + 0x23048263,/*6f28*/ + 0xb87cf625,/*6f2c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch50 = +{ + 50, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch50_ibrt_ins_data_t2), + 0x0002bfc4, + 0xbf88f1da, + 0xc0006ed8, + (uint8_t *)bes2300p_patch50_ibrt_ins_data_t2 +};////ibrt connect slot adjust in sco +#endif + +const uint32_t bes2300p_patch51_ibrt_ins_data_t2[] = +{ + 0x490a60e3,/*6f30*/ + 0x428f6809, + 0x4620d10c, + 0x22002100, + 0xf914f625,/*6f40*/ + 0x429d68a3, + 0x60a5bf38, + 0x134cf640, + 0x3012f8a4,/*6f50*/ + 0xbf004620, + 0xbc20f624, + 0xc0006e2c,/*6f5c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch51 = +{ + 51, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch51_ibrt_ins_data_t2), + 0x0002b798, + 0xbbcaf1db, + 0xc0006f30, + (uint8_t *)bes2300p_patch51_ibrt_ins_data_t2 +};//sniff trans mode timing + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch52 = +{ + 52, + BTDRV_PATCH_ACT, + 0, + 0x0001bf54, + 0xbff2f7ff, //jump a001bf54 -> a001bf3c + 0, + NULL +};//LMP_MSG_HANDLER(switch_req) LC_CONNECTED + +const uint32_t bes2300p_patch53_ibrt_ins_data_t2[] = +{ + /*6f74*/ 0xf632b140, + /*6f78*/ 0x42b0f841, + /*6f7c*/ 0xf632d104, + /*6f80*/ 0x2801f82b, + /*6f84*/ 0xbf00d002, + /*6f88*/ 0xbea8f619, + /*6f8c*/ 0xbf08f619, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch53 = +{ + 53, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch53_ibrt_ins_data_t2), + 0x00020cd8, + 0xb94cf1e6, // jump a0020cd8 -> a0206f74 + 0xc0006f74, + (uint8_t *)bes2300p_patch53_ibrt_ins_data_t2 +};//disconnect cmp + +#if 0 +const uint32_t bes2300p_patch54_ibrt_ins_data_t2[] = +{ + 0xb3384606,/*6f90*/ + 0x0a0388a0, + 0xd1212b05, + 0xf1034b14, + 0xb2c10528,/*6fa0*/ + 0xe044f8df, + 0x428a781a, + 0x785ad114, + 0x0f01f012,/*6fb0*/ + 0x88e7d006, + 0x2f020a3f, + 0xf85ed814, + 0xb18f7027,/*6fc0*/ + 0x0f02f012, + 0x8922d006, + 0x2a020a12, + 0xf85ed80a,/*6fe0*/ + 0xb13a2022, + 0x42ab3302, + 0xbf00d1e4, + 0xb8e5f5fa,/*6ff0*/ + 0xb8dcf5fa, + 0xb8ecf5fa, + 0xc0005cd8, + 0xc0006ff4,/*7000*/ + 0x0327032a, + 0x010e0326, + 0x0000010f, + 0x00000000,/*7010*/ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000,/*7020*/ + 0x00000000, + 0x00000000,/*7024*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch54 = +{ + 54, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch54_ibrt_ins_data_t2), + 0x0000119c, + 0xbef8f205, + 0xc0006f90, + (uint8_t *)bes2300p_patch54_ibrt_ins_data_t2 +};//msg filter +#else +const uint32_t bes2300p_patch54_ibrt_ins_data_t2[] = +{ + 0x8885b5f8,//73cc + 0x2b050a2b, + 0x4b49d121, + 0x0428f103, + 0x4f48b2e9, + 0x428a781a, + 0x785ad116, + 0x0f01f012, + 0x88c6d007, + 0x2e020a36, + 0xf857d86b, + 0x2e006026, + 0xf012d069, + 0xd0070f02, + 0x0a128902, + 0xd8642a02, + 0x2022f857, + 0xd0622a00, + 0x42a33302, + 0xf240d1e2, + 0x429d5335, + 0x4605d15d, + 0x08637b44, + 0xd1142b04, + 0xf5f988c0, + 0x2832ffb5, + 0xf240d155, + 0x88e95006, + 0xfb2ef5f9, + 0x0a0288e8, + 0xf8534b2e, + 0xf8933022, + 0xf5f9135e, + 0x2401ff39, + 0x2b18e050, + 0x88c0d126, + 0xff9ef5f9, + 0xd1402836, + 0x02fef004, + 0x0a3688ee, + 0xf8534b24, + 0xf8844026, + 0xb2f62044, + 0x21184630, + 0xff1cf61c, + 0x4040f894, + 0xd1302c01, + 0xf6294630, + 0x88e8fa29, + 0xf800f60f, + 0x0a0288e8, + 0xf8534b19, + 0xf8933022, + 0xf5f9135e, + 0xe027ff0f, + 0xd1202b7e, + 0x3b097b83, + 0x2b01b2db, + 0xf631d81d, + 0x7a83fd77, + 0xd81a2b02, + 0xf8524a0f, + 0xfab44023, + 0x0964f484, + 0x2401e014, + 0x2401e012, + 0x2401e010, + 0x2401e00e, + 0x2400e00c, + 0x2400e00a, + 0x2400e008, + 0x2401e006, + 0x2400e004, + 0x2400e002, + 0x2401e000, + 0xbdf84620, + 0xa0207520, + 0xc0005cd8, + 0xb1484606, + 0xf7ff4620, + 0x2801ff5f, + 0xbf00d102, + 0xbe56f5f9, + 0xbe49f5f9, + 0xbe40f5f9, + 0x0327032a, + 0x010e0326, + 0x0000010f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch54 = +{ + 54, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch54_ibrt_ins_data_t2), + 0x0000119c, + 0xb9b2f206, + 0xc00073cc, + (uint8_t *)bes2300p_patch54_ibrt_ins_data_t2 +};//msg filter + +#endif + +const uint32_t bes2300p_patch55_ibrt_ins_data_t2[] = +{ + 0x49079804,/*70a4*/ + 0x42886809, + 0xf632d103, + 0x2800f86b, + 0x3301d004,/*70b4*/ + 0xf88bb2db, + 0xbf0030bb, + 0xbaf4f628, + 0xc0006e2c,/*70c4*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ibrt_ins_patch55 = +{ + 55, + BTDRV_PATCH_ACT, + sizeof(bes2300p_patch55_ibrt_ins_data_t2), + 0x0002f6a4, + 0xbcfef1d7, + 0xc00070a4, + (uint8_t *)bes2300p_patch55_ibrt_ins_data_t2 +};//tws link dont rx traffic++ + +/////2300p t2 ibrt patch (chip id =1) +static const uint32_t best2300p_t2_ibrt_ins_patch_config[] = +{ + 56, + (uint32_t)&bes2300p_t2_ibrt_ins_patch0, + (uint32_t)&bes2300p_t2_ibrt_ins_patch1, + (uint32_t)&bes2300p_t2_ibrt_ins_patch2, + (uint32_t)&bes2300p_t2_ibrt_ins_patch3, + (uint32_t)&bes2300p_t2_ibrt_ins_patch4, + (uint32_t)&bes2300p_t2_ibrt_ins_patch5, + (uint32_t)&bes2300p_t2_ibrt_ins_patch6, + (uint32_t)&bes2300p_t2_ibrt_ins_patch7, + (uint32_t)&bes2300p_t2_ibrt_ins_patch8, + (uint32_t)&bes2300p_t2_ibrt_ins_patch9, + (uint32_t)&bes2300p_t2_ibrt_ins_patch10, + (uint32_t)&bes2300p_t2_ibrt_ins_patch11, + (uint32_t)&bes2300p_t2_ibrt_ins_patch12, + (uint32_t)&bes2300p_t2_ibrt_ins_patch13, + (uint32_t)&bes2300p_t2_ibrt_ins_patch14, + (uint32_t)&bes2300p_t2_ibrt_ins_patch15, + (uint32_t)&bes2300p_t2_ibrt_ins_patch16, + (uint32_t)&bes2300p_t2_ibrt_ins_patch17, + (uint32_t)&bes2300p_t2_ibrt_ins_patch18, + (uint32_t)&bes2300p_t2_ibrt_ins_patch19, + (uint32_t)&bes2300p_t2_ibrt_ins_patch20, + (uint32_t)&bes2300p_t2_ibrt_ins_patch21, + (uint32_t)&bes2300p_t2_ibrt_ins_patch22, + (uint32_t)&bes2300p_t2_ibrt_ins_patch23, + (uint32_t)&bes2300p_t2_ibrt_ins_patch24, + (uint32_t)&bes2300p_t2_ibrt_ins_patch25, + (uint32_t)&bes2300p_t2_ibrt_ins_patch26, + (uint32_t)&bes2300p_t2_ibrt_ins_patch27, + (uint32_t)&bes2300p_t2_ibrt_ins_patch28, + (uint32_t)&bes2300p_t2_ibrt_ins_patch29, + (uint32_t)&bes2300p_t2_ibrt_ins_patch30, + (uint32_t)&bes2300p_t2_ibrt_ins_patch31, + (uint32_t)&bes2300p_t2_ibrt_ins_patch32, + (uint32_t)&bes2300p_t2_ibrt_ins_patch33, + (uint32_t)&bes2300p_t2_ibrt_ins_patch34, + (uint32_t)&bes2300p_t2_ibrt_ins_patch35, + (uint32_t)&bes2300p_t2_ibrt_ins_patch36, + (uint32_t)&bes2300p_t2_ibrt_ins_patch37, + (uint32_t)&bes2300p_t2_ibrt_ins_patch38, + (uint32_t)&bes2300p_t2_ibrt_ins_patch39, + (uint32_t)&bes2300p_t2_ibrt_ins_patch40, + (uint32_t)&bes2300p_t2_ibrt_ins_patch41, + (uint32_t)&bes2300p_t2_ibrt_ins_patch42, + (uint32_t)&bes2300p_t2_ibrt_ins_patch43, + (uint32_t)&bes2300p_t2_ibrt_ins_patch44, + (uint32_t)&bes2300p_t2_ibrt_ins_patch45, + (uint32_t)&bes2300p_t2_ibrt_ins_patch46, + (uint32_t)&bes2300p_t2_ibrt_ins_patch47, + (uint32_t)&bes2300p_t2_ibrt_ins_patch48, + (uint32_t)&bes2300p_t2_ibrt_ins_patch49, + (uint32_t)&bes2300p_t2_ibrt_ins_patch50, + (uint32_t)&bes2300p_t2_ibrt_ins_patch51, + (uint32_t)&bes2300p_t2_ibrt_ins_patch52, + (uint32_t)&bes2300p_t2_ibrt_ins_patch53, + (uint32_t)&bes2300p_t2_ibrt_ins_patch54, + (uint32_t)&bes2300p_t2_ibrt_ins_patch55, +}; +#endif +/*************************************************************************** + * + * instruction patch Information + * + * BT ROM Chip Version:1302 T1 + * + * [IBRT] + * patch 7: 0xC0006a50--->0xC0006a78 + * patch 8: 0xC0006a90--->0xC0006a9C + * patch 9: in used check ble conflict with acl + * patch 10: 0xC0006AA0--->0xC0006AC8 + * patch 11: 0xC0006AD0--->0xC0006AEC + * patch 12: 0xC0006AF0--->0xC0006B04 + * patch 13: 0xC0006B08--->0xC0006B18 + * patch 14: in use + * patch 15: 0xC0006B74--->0xC0006B80 + * patch 16: in used :check afh mismatch 1 + * patch 17: in used :check afh mismatch 2 + * patch 18: 0xC0006B88--->0xC006C14 fix acl interval in sco + * patch 19: in used + * patch 20: in used + * patch 21: 0xC0006C78--->0xC0006C88 + * patch 22: 0xC0006810--->0xC0006878 + * patch 23: 0xC0006880--->0xC0006890 + * patch 24: 0xC0006C90--->0xC000689C + * patch 25: in used:ld_acl_start t_poll + * patch 26: 0xC0006CA0--->0xC0006CC8: unused + * patch 27: in used: ld_sniffer_update_status: SNIFFER_EVT_SCO_CONNECTED + * patch 28: in used: 0xC0006CF8--->0xC0006D0C + * patch 29: in used: 0xC0006D14--->0xC0006D30 + ****************************************************************************/ + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch0 = +{ + 0, + BTDRV_PATCH_ACT, + 0, + 0x00025ef4, + 0xbf00bf00, + 0, + NULL +};///remove the memset of ldenv + +const uint32_t bes2300p_t1_patch_0a_ins_data[] = +{ + /*6810*/ 0x681b4b0e, + /*6814*/ 0x4b0eb1ab, + /*6818*/ 0x31cbf893, + /*681c*/ 0x4a0d011b, + /*6820*/ 0xf3c35a9b, + /*6824*/ 0x4a0c2340, + /*6828*/ 0x2a025c12, + /*682c*/ 0x4a0ad103, + /*6830*/ 0x20005413, + /*6834*/ 0x42934770, + /*6838*/ 0x4a07d005, + /*683c*/ 0x20005413, + /*6840*/ 0x20004770, + /*6844*/ 0x20014770, + /*6848*/ 0xbf004770, + /*684c*/ 0xc000685c, + /*6850*/ 0xc0005d34, + /*6854*/ 0xd02115f2, + /*6858*/ 0xc0006860, + /*685c*/ 0x00000001, // sw_seqn_filter_en + /*6860*/ 0x00020202, // link_id_seq + /*6864*/ 0x9805bf00, + /*6868*/ 0xffd2f7ff, // call a0206810 + /*686c*/ 0x2019b910, + /*6870*/ 0xbd62f628, // jump a002f338 + /*6874*/ 0x22802107, + /*6878*/ 0xbe22f628, // jump a002f4c0 +}; // ld_acl_rx ld_sw_seqn_filter + +const uint32_t bes2300p_t1_patch_0b_ins_data[] = +{ + /*6880*/ 0x328af885, + /*6884*/ 0x22024b02, + /*6888*/ 0xbf00559a, + /*688c*/ 0xbe90f614, // jump a001b5b0 + /*6890*/ 0xc0006860, // link_id_seq +}; // lc_rsw_end_ind link_id_seq[link_id]=2 + +const uint32_t bes2300p_t1_patch_1_ins_data[] = +{ + 0x2c021b64, + 0x2009d101, + 0x3402e002, + 0xbc4af63c, + 0xbca6f63c, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch1 = +{ + 1, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_1_ins_data), + 0x000431a0, + 0xbbaef1c3, + 0xc0006900, + (uint8_t *)bes2300p_t1_patch_1_ins_data +};//for ble and sco: OVERLAP_RESERVE2 in lld_check_conflict_with_ble + +const uint32_t bes2300p_t1_patch_2_ins_data[] = +{ + 0x781b4b05, + 0xd1032b09, + 0x4b032200, + 0x2704701a, + 0x60eb1be3, + 0xb8ecf627, + 0xc000693c,////prev_conflict_type_record + 0x00000000, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch2 = +{ + 2, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_2_ins_data), + 0x0002db0c, + 0xbf08f1d8, + 0xc0006920, + (uint8_t *)bes2300p_t1_patch_2_ins_data +};//for ble and sco: prev_conflict_type_record in ld_sco_avoid_ble_connect + +const uint32_t bes2300p_t1_patch_3_ins_data[] = +{ + 0xd1084298, + 0x3047f894, + 0x92004a0e, + 0x22024631, + 0xfd42f61f, + 0x4b0ce014, + 0xb143781b, + 0x3047f894, + 0x92004a08, + 0x22024631, + 0xfd36f61f, + 0xf894e008, + 0x4a043047, + 0x46319200, + 0xbf002204, + 0xfd2cf61f, + 0xbaa2f62b, + 0xa002fce5, + 0xc000699c,///ble_sco_need_move_flag + 0x00000000, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch3 = +{ + 3, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_3_ins_data), + 0x00031ec4, + 0xbd44f1d4, + 0xc0006950, + (uint8_t *)bes2300p_t1_patch_3_ins_data +};//for ble and sco: ld_fm_prog_push LD_FRAME_TYPE_ESCO when ble_sco_need_move_flag in ld_sco_evt_start_cbk + + +const uint32_t bes2300p_t1_patch_4_ins_data[] = +{ + 0x781b4b18, + 0x2200b113, + 0x701a4b16, + 0x781b4b18, + 0xd0232b00, + 0x4b162201, + 0xbf00701a, + 0xb1e84680, + 0x781b4b11, + 0xd1192b00, + 0x0304f1a8, + 0x2b01b2db, + 0xf1b8d903, + 0xd1130f09, + 0x2201e00c, + 0x701a4b09, + 0x0f09f1b8, + 0x2209d103, + 0x701a4b08, + 0x68eb2704, + 0xb8a6f627, + 0x4b032201, + 0xe7f4701a, + 0xb8c2f627, + 0xb8aff627, + 0xc000699c,///ble_sco_need_move_flag + 0xc000099f, + 0xc000693c,///prev_conflict_type_record + 0xc0006a18,///sco_find_sync_flag + 0x00000000, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch4 = +{ + 4, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_4_ins_data), + 0x0002db30, + 0xbf38f1d8, + 0xc00069a4, + (uint8_t *)bes2300p_t1_patch_4_ins_data +};//for ble and sco: ble_sco_need_move_flag = 1,need_move=4 in ld_sco_avoid_ble_connect + +const uint32_t bes2300p_t1_patch_5_ins_data[] = +{ + 0xfbb24a02, + 0xf5f9f3f3, + 0xbf00bec6, + 0x9af8da00, +}; + + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch5 = +{ + 5, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_5_ins_data), + 0x00000650, + 0xb936f206, + 0xc00068c0, + (uint8_t *)bes2300p_t1_patch_5_ins_data +};//lpclk + + +const uint32_t bes2300p_t1_patch_6_ins_data[] = +{ + 0xd00d2b00, + 0xf8384b07, + 0xf4133003, + 0xd0024f00, + 0x4b052201, + 0xf899701a, + 0x2b0130b3, + 0xba5af629, + 0xbaccf629, + 0xd02111f8, + 0xc0006a18,////sco_find_sync_flag +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch6 = +{ + 6, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_6_ins_data), + 0x0002feec, + 0xbd98f1d6, + 0xc0006a20, + (uint8_t *)bes2300p_t1_patch_6_ins_data +};///for ble and sco: sco_find_sync_flag = 1 in ld_sco_frm_isr + +const uint32_t bes2300p_t1_patch_7_ins_data[] = +{ + 0xd10f2f03, + 0xfd16f642, + 0x4008f8d8, + 0x46216940, + 0xf6242220, + 0xb128fff5, + 0x0320f104, + 0x4378f023, + 0x3008f8c8, + 0xbf002000, + 0xbc7df625, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch7 = +{ + 7, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_7_ins_data), + 0x0002c32c, + 0xbb90f1da, + 0xc0006A50, + (uint8_t *)bes2300p_t1_patch_7_ins_data +};//ble avoid role switch + +const uint32_t bes2300p_t1_patch_8_ins_data[] = +{ + 0xf855b2e6, + 0xb1091b04, + 0xbc71f610, + 0xbc78f610, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch8 = +{ + 8, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_8_ins_data), + 0x00017378, + 0xbb8af1ef, + 0xc0006A90, + (uint8_t *)bes2300p_t1_patch_8_ins_data +};//lc_check_bt_device_conected + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch9 = +{ + 9, + BTDRV_PATCH_ACT, + 0, + 0x00043238, + 0xbf342c09, + 0, + NULL +};//check conflict 8 slot 1 + +const uint32_t bes2300p_t1_patch_10_ins_data[] = +{ + 0xf8934b07, + 0x98053078, + 0xd1074298, + 0xd0052b03, + 0x681b4b04, + 0x2201b913, + 0x601a4b02, + 0xbc3ff628, + 0xc0006358, + 0xc0006AC8, + 0x00000000, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch10 = +{ + 10, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_10_ins_data), + 0x0002f338, + 0xbbb2f1d7, + 0xc0006AA0, + (uint8_t *)bes2300p_t1_patch_10_ins_data +};//ibrt snoop success + +const uint32_t bes2300p_t1_patch_11_ins_data[] = +{ + 0xb149d208, + 0x681b4b05, + 0x2200b133, + 0x601a4b03, + 0xbce4f632, + 0xbcf2f632, + 0xbcfff632, + 0xc0006AC8, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch11 = +{ + 11, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_11_ins_data), + 0x000394a8, + 0xbb12f1cd, + 0xc0006AD0, + (uint8_t *)bes2300p_t1_patch_11_ins_data +};//ibrt snoop success 2 + +const uint32_t bes2300p_t1_patch_12_ins_data[] = +{ + 0x46032102, + 0xf9b4f633, + 0xbf004618, + 0x22012105, + 0xfa28f61d, + 0xba4ff633, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch12 = +{ + 12, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_12_ins_data), + 0x00039fa0, + 0xbda6f1cc, + 0xc0006AF0, + (uint8_t *)bes2300p_t1_patch_12_ins_data +};// hack tws switch tx seqn error + +const uint32_t bes2300p_t1_patch_13_ins_data[] = +{ + 0xfc6ef631, + 0xfcbaf631, + 0xbf004620, + 0xfcc2f631, + 0xbfb2f62a, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch13 = +{ + 13, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_13_ins_data), + 0x00031a7c, + 0xb844f1d5, + 0xc0006B08, + (uint8_t *)bes2300p_t1_patch_13_ins_data +};// lmp filter enable + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch14 = +{ + 14, + BTDRV_PATCH_ACT, + 0, + 0x000388a8, + 0xbf00e001, + 0, + NULL +};//open afh update + +const uint32_t bes2300p_t1_patch_15_ins_data[] = +{ + 0xfbd0f631, + 0x20004601, + 0xfbb8f633, + 0xba9ef618, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch15 = +{ + 15, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_15_ins_data), + 0x0001f0bc, + 0xbd5af1e7, + 0xc0006B74, + (uint8_t *)bes2300p_t1_patch_15_ins_data +};//ibrt slave stop sco + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch16 = +{ + 16, +#if defined(IBRT) + BTDRV_PATCH_ACT, +#else + BTDRV_PATCH_INACT, +#endif + 0, + 0x00038a78, + 0x7a22d206, + 0, + NULL, +};//check afh mismatch 1 + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch17 = +{ + 17, +#if defined(IBRT) + BTDRV_PATCH_ACT, +#else + BTDRV_PATCH_INACT, +#endif + 0, + 0x00038a88, + 0xbf00e00e, + 0, + NULL, +};//check afh mismatch 2 + +const uint32_t bes2300p_t1_patch_18_ins_data[] = +{ + 0x4606b570, + 0x7e8d460c, + 0xf5f5fb92, + 0x2114b2e8, + 0x68e175b1, + 0xf023440b, + 0x7ee14378, + 0x6381ea83, + 0x1a5b7e61, + 0xfbb37ea1, + 0xb2dbf3f1, + 0xf1f0fbb3, + 0x3311fb00, + 0xb2c31ac0, + 0xd8042a3c, + 0x622ef640, + 0x22048272, + 0xf640e003, + 0x8272124c, + 0x7ea02206, + 0xfb0068e1, + 0x44101003, + 0x4078f020, + 0x210060b0, + 0xfab4f63c, + 0xd9072806, + 0xb2ed7ea3, + 0xfb0568b2, + 0xf0252503, + 0x60b54578, + 0xbf00bd70, + 0x46514620, + 0x2042f8b8, + 0x3088f8d3, + 0xffbaf7ff, + 0xbfcbf624, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch18 = +{ + 18, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_18_ins_data), + 0x0002bad8, + 0xb894f1db, //jump a002bad8 -> A0206C04 + 0xc0006B88, + (uint8_t *)bes2300p_t1_patch_18_ins_data +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch19 = +{ + 19, + BTDRV_PATCH_ACT, + 0, + 0x00039d78, + 0xd13b2902, + 0, + NULL +};//ibrt switch op + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch20 = +{ + 20, + BTDRV_PATCH_ACT, + 0, + 0x00030240, + 0xe0022000, + 0, + NULL +};//acl end assert + +const uint32_t bes2300p_t1_patch_21_ins_data[] = +{ + 0x781b4b03, + 0xd1012b01, + 0xbc5cf633, + 0xbc63f633, + 0xc0006358, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch21 = +{ + 21, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_21_ins_data), + 0x0003a528, + 0xbba6f1cc, + 0xc0006C78, + (uint8_t *)bes2300p_t1_patch_21_ins_data +};//snoop disconnect + +// __SW_SEQ_FILTER__ - add software seqn filter to protect recive identical repeating packages +#if defined(IBRT) +#define __SW_SEQ_FILTER__ +#endif +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch22 = +{ + 22, +#ifdef __SW_SEQ_FILTER__ + BTDRV_PATCH_INACT, +#else + BTDRV_PATCH_INACT, +#endif + sizeof(bes2300p_t1_patch_0a_ins_data), + 0x0002f334, + 0xba96f1d7, // jump a002f334 -> a0206864 + 0xc0006810, + (uint8_t *)bes2300p_t1_patch_0a_ins_data +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch23 = +{ + 23, +#ifdef __SW_SEQ_FILTER__ + BTDRV_PATCH_INACT, +#else + BTDRV_PATCH_INACT, +#endif + sizeof(bes2300p_t1_patch_0b_ins_data), + 0x0001b5ac, + 0xb968f1eb, // jump a001b5ac -> a0206880 + 0xc0006880, + (uint8_t *)bes2300p_t1_patch_0b_ins_data +}; // lc_rsw_end_ind link_id_seq[link_id]=2 + + +const uint32_t bes2300p_t1_patch_24_ins_data[] = +{ + 0x0f01f1b8, + 0x380ebf0c, + 0xb280301c, + 0xbb30f632, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch24 = +{ + 24, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_24_ins_data), + 0x000392d8, + 0xbcdaf1cd, + 0xc0006c90, + (uint8_t *)bes2300p_t1_patch_24_ins_data +};//start snoop using bitoff + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch25 = +{ + 25, +#if defined(IBRT) + BTDRV_PATCH_ACT, +#else + BTDRV_PATCH_INACT, +#endif + 0, + 0x0002e09c, + 0xf8a6230a, + 0, + NULL, +};//ld_acl_start t_poll + +const uint32_t bes2300p_t1_patch_26_ins_data[] = +{ + 0x5040f898, + 0xd80d2d14, + 0xfbecf642, + 0x690068a6, + 0xb2ea4631, + 0xfeccf624, + 0xf106b120, + 0xf0230364, + 0x60a34378, + 0xfbdef642, + 0xbfb2f624, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch26 = +{ + 26, + BTDRV_PATCH_INACT, + sizeof(bes2300p_t1_patch_26_ins_data), + 0x0002bc2c, + 0xb838f1db, + 0xc0006CA0, + (uint8_t *)bes2300p_t1_patch_26_ins_data +};//mobile link avoid tws link when send profile + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch27 = +{ + 27, + BTDRV_PATCH_ACT, + 0, + 0x0003890c, + 0xbf00e008, + 0, + NULL, +};// ld_sniffer_update_status: SNIFFER_EVT_SCO_CONNECTED + +const uint32_t bes2300p_t1_patch_28_ins_data[] = +{ + 0xfa58f63f, + 0x4b034a02, + 0xbf00601a, + 0xbb66f63f, + 0xffff0009, + 0xd03300f0, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch28 = +{ + 28, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_28_ins_data), + 0x000463d0, + 0xbc92f1c0, + 0xc0006CF8, + (uint8_t *)bes2300p_t1_patch_28_ins_data +};//lld_evt_end_isr:SYS 2M + +const uint32_t bes2300p_t1_patch_29_ins_data[] = +{ + 0x681b4b0a, + 0x0301f033, + 0xbf00d106, + 0x4b044a03, + 0x4a04601a, + 0x601a4b04, + 0xbc96f63d, + 0x04007107, + 0xD0220000, + 0xffff0008, + 0xd03300f0, + 0xd0220054, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch29 = +{ + 29, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_29_ins_data), + 0x00044658, + 0xbb5cf1c2, + 0xc0006d14, + (uint8_t *)bes2300p_t1_patch_29_ins_data +};//lld_evt_schedule:SYS 1M + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch30 = +{ + 30, + BTDRV_PATCH_ACT, + 0, + 0x00029e70, + 0xbf8c7fb9, + 0, + NULL, +};//ld_acl_rx_sync2 + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch31 = +{ + 31, + BTDRV_PATCH_ACT, + 0, + 0x0002a068, + 0xbf947fb9, + 0, + NULL, +};//ld_acl_rx_no_sync + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch32 = +{ + 32, + BTDRV_PATCH_ACT, + 0, + 0x0002a1b0, + 0x7fb9f5b3, + 0, + NULL, +};//ld_acl_rx_sync + +const uint32_t bes2300p_t1_patch_33_ins_data[] = +{ + 0xfdf6f624, + 0x4638b920, + 0xf63c2100, + 0xb108fa01, + 0xbf2bf628, + 0xbf3df628, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch33 = +{ + 33, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_patch_33_ins_data), + 0x0002fba8, + 0xb8ccf1d7, + 0xc0006d44, + (uint8_t *)bes2300p_t1_patch_33_ins_data +};//protect ble 8 slot + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch34 = +{ + 34, + BTDRV_PATCH_ACT, + 0, + 0x00043248, + 0xbf8c2c08, + 0, + NULL, +};//check conflict 8 slot 2 + +const uint32_t bes2300p_t1_patch_35_ins_data[] = +{ + /*6d54*/ 0xf8534b02, + /*6d58*/ 0xb11b3020, + /*6d5c*/ 0xbafdf610, + /*6d60*/ 0xc0005c70, + /*6d64*/ 0x47702000, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch35 = +{ + 35, + BTDRV_PATCH_INACT, + sizeof(bes2300p_t1_patch_35_ins_data), + 0x00017354, + 0xbcfef1ef, + 0xc0006d54, + (uint8_t *)bes2300p_t1_patch_35_ins_data +};//is_in_sniff_mode use NULL ptr + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch36 = +{ + 36, + BTDRV_PATCH_INACT, + 0, + 0x00039b58, + 0xf2002802, + 0, + NULL, +};//ld_sniffer_start_monitored_link(link_id >= MAX_NB_ACTIVE_ACL) + +/////2300p t1 patch +static const uint32_t best2300p_t1_ins_patch_config[] = +{ + 37, + (uint32_t)&bes2300p_t1_ins_patch0, + (uint32_t)&bes2300p_t1_ins_patch1, + (uint32_t)&bes2300p_t1_ins_patch2, + (uint32_t)&bes2300p_t1_ins_patch3, + (uint32_t)&bes2300p_t1_ins_patch4, + (uint32_t)&bes2300p_t1_ins_patch5, + (uint32_t)&bes2300p_t1_ins_patch6, + (uint32_t)&bes2300p_t1_ins_patch7, + (uint32_t)&bes2300p_t1_ins_patch8, + (uint32_t)&bes2300p_t1_ins_patch9, + (uint32_t)&bes2300p_t1_ins_patch10, + (uint32_t)&bes2300p_t1_ins_patch11, + (uint32_t)&bes2300p_t1_ins_patch12, + (uint32_t)&bes2300p_t1_ins_patch13, + (uint32_t)&bes2300p_t1_ins_patch14, + (uint32_t)&bes2300p_t1_ins_patch15, + (uint32_t)&bes2300p_t1_ins_patch16, + (uint32_t)&bes2300p_t1_ins_patch17, + (uint32_t)&bes2300p_t1_ins_patch18, + (uint32_t)&bes2300p_t1_ins_patch19, + (uint32_t)&bes2300p_t1_ins_patch20, + (uint32_t)&bes2300p_t1_ins_patch21, + (uint32_t)&bes2300p_t1_ins_patch22, + (uint32_t)&bes2300p_t1_ins_patch23, + (uint32_t)&bes2300p_t1_ins_patch24, + (uint32_t)&bes2300p_t1_ins_patch25, + (uint32_t)&bes2300p_t1_ins_patch26, + (uint32_t)&bes2300p_t1_ins_patch27, + (uint32_t)&bes2300p_t1_ins_patch28, + (uint32_t)&bes2300p_t1_ins_patch29, + (uint32_t)&bes2300p_t1_ins_patch30, + (uint32_t)&bes2300p_t1_ins_patch31, + (uint32_t)&bes2300p_t1_ins_patch32, + (uint32_t)&bes2300p_t1_ins_patch33, + (uint32_t)&bes2300p_t1_ins_patch34, + (uint32_t)&bes2300p_t1_ins_patch35, + (uint32_t)&bes2300p_t1_ins_patch36, +}; + +void btdrv_ins_patch_write(BTDRV_PATCH_STRUCT *ins_patch_p) +{ + uint32_t remap_addr; + /// uint8_t i=0; + remap_addr = ins_patch_p->patch_remap_address | 1; + btdrv_write_memory(_32_Bit,(BTDRV_PATCH_INS_REMAP_ADDR_START + ins_patch_p->patch_index*4), + (uint8_t *)&ins_patch_p->patch_remap_value,4); + if(ins_patch_p->patch_length != 0) //have ram patch data + { + btdrv_memory_copy((uint32_t *)ins_patch_p->patch_start_address,(uint32_t *)ins_patch_p->patch_data,ins_patch_p->patch_length); + } + + btdrv_write_memory(_32_Bit,(BTDRV_PATCH_INS_COMP_ADDR_START + ins_patch_p->patch_index*4), + (uint8_t *)&remap_addr,4); + +} + +void btdrv_ins_patch_init(void) +{ + const BTDRV_PATCH_STRUCT *ins_patch_p; + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0) + { + for(uint8_t i=0; ipatch_state ==BTDRV_PATCH_ACT) + btdrv_ins_patch_write((BTDRV_PATCH_STRUCT *)best2300p_t1_ins_patch_config[i+1]); + } + } + else if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) + { +#ifndef IBRT + for(uint8_t i=0; ipatch_state ==BTDRV_PATCH_ACT) + btdrv_ins_patch_write((BTDRV_PATCH_STRUCT *)best2300p_t2_ins_patch_config[i+1]); + } +#else + for(uint8_t i=0; ipatch_state ==BTDRV_PATCH_ACT) + btdrv_ins_patch_write((BTDRV_PATCH_STRUCT *)best2300p_t2_ibrt_ins_patch_config[i+1]); + } +#endif + } + else if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { +#ifdef IBRT + for(uint8_t i=0; ipatch_state ==BTDRV_PATCH_ACT) + btdrv_ins_patch_write((BTDRV_PATCH_STRUCT *)best2300p_t3_ibrt_ins_patch_config[i+1]); + } +#else + for(uint8_t i=0; ipatch_state ==BTDRV_PATCH_ACT) + btdrv_ins_patch_write((BTDRV_PATCH_STRUCT *)best2300p_t3_ins_patch_config[i+1]); + } +#endif + } + else + { + ASSERT(0, "%s:error chip id=%d", __func__, hal_get_chip_metal_id()); + } +} + +///////////////////data patch ..//////////////////////////////////// + +static const POSSIBLY_UNUSED uint32_t best2300p_t2_data_patch_config[] = +{ +}; + +void btdrv_data_patch_write(const BTDRV_PATCH_STRUCT *d_patch_p) +{ + + uint32_t remap_addr; + uint8_t i=0; + + remap_addr = d_patch_p->patch_remap_address |1; + btdrv_write_memory(_32_Bit,(BTDRV_PATCH_DATA_COMP_ADDR_START + d_patch_p->patch_index*4), + (uint8_t *)&remap_addr,4); + btdrv_write_memory(_32_Bit,(BTDRV_PATCH_DATA_REMAP_ADDR_START + d_patch_p->patch_index*4), + (uint8_t *)&d_patch_p->patch_remap_value,4); + + if(d_patch_p->patch_length != 0) //have ram patch data + { + for( ; i<(d_patch_p->patch_length-1)/128; i++) + { + btdrv_write_memory(_32_Bit,d_patch_p->patch_start_address+i*128, + (d_patch_p->patch_data+i*128),128); + + } + + btdrv_write_memory(_32_Bit,d_patch_p->patch_start_address+i*128,d_patch_p->patch_data+i*128, + d_patch_p->patch_length%128); + } + +} + + +void btdrv_ins_patch_disable(uint8_t index) +{ + uint32_t addr=0; + btdrv_write_memory(_32_Bit,(BTDRV_PATCH_INS_COMP_ADDR_START + index*4), + (uint8_t *)&addr,4); + +} + +void btdrv_data_patch_init(void) +{ +#if 0 + const BTDRV_PATCH_STRUCT *data_patch_p; + if(hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) + { + for(uint8_t i=0; ipatch_state == BTDRV_PATCH_ACT) + btdrv_data_patch_write((BTDRV_PATCH_STRUCT *)best2300p_t2_data_patch_config[i+1]); + } + } +#endif +} + + +//////////////////////////////patch enable//////////////////////// + +void btdrv_patch_en(uint8_t en) +{ + uint32_t value[2]; + + //set patch enable + value[0] = 0x2f02 | en; + //set patch remap address to 0xc0000100 + value[1] = 0x20000100; + btdrv_write_memory(_32_Bit,BTDRV_PATCH_EN_REG,(uint8_t *)&value,8); +} + +/////////////2300p t3 test mode patch/////////////////////// + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch_testmode_0 = +{ + 0, + BTDRV_PATCH_ACT, + 0, + 0x0002ceb4, + 0xe00b0f0f, + 0, + NULL +};//ld_acl_rx() average rssi + +const uint32_t bes2300p_t3_ins_patch_data_testmode_1[] = +{ + /*6a98*/ 0x99049803, + /*6a9c*/ 0x4b12b470, + /*6aa0*/ 0x010e5c5a, + /*6aa4*/ 0x19734d11, + /*6aa8*/ 0x78244c11, + /*6aac*/ 0xd20342a2, + /*6ab0*/ 0x32015498, + /*6ab4*/ 0xe001b2d2, + /*6ab8*/ 0x22015570, + /*6abc*/ 0x5442480a, + /*6ac0*/ 0x461ab14c, + /*6ac4*/ 0x23001919, + /*6ac8*/ 0x0b01f912, + /*6acc*/ 0xbf004403, + /*6ad0*/ 0xd1f9428a, + /*6ad4*/ 0x2300e000, + /*6ad8*/ 0xf0f4fb93, + /*6adc*/ 0xbc70b240, + /*6ae0*/ 0x22019904, + /*6ae4*/ 0xba00f626, //jump a0206ae4 -> a002cee8 + /*6ae8*/ 0xc0006af8, //addr of rssi_idx_for_agc + /*6aec*/ 0xc0006afc, //addr of rssi_set_for_agc + /*6af0*/ 0xc0006af4, //addr of N + /*6af4*/ 0x00000005, //N : 1 ~ 16 + /*6af8*/ 0x00000000, //rssi_idx_for_agc[3] + /*6afc*/ 0xbabababa, //rssi_set_for_agc[3*16] + /*6b00*/ 0xbabababa, + /*6b04*/ 0xbabababa, + /*6b08*/ 0xbabababa, + /*6b0c*/ 0xbabababa, + /*6b10*/ 0xbabababa, + /*6b14*/ 0xbabababa, + /*6b18*/ 0xbabababa, + /*6b1c*/ 0xbabababa, + /*6b20*/ 0xbabababa, + /*6b24*/ 0xbabababa, + /*6b28*/ 0xbabababa, + /*6b2c*/ 0xbabababa, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch_testmode_1 = +{ + 1, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t3_ins_patch_data_testmode_1), + 0x0002cee4, + 0xbdd8f1d9, //jump a002cee4 -> a0206a98 + 0xc0006a98, + (uint8_t *)bes2300p_t3_ins_patch_data_testmode_1 +};//ld_acl_rx() average rssi + +const uint32_t bes2300p_t3_ins_patch_data_testmode_2[] = +{ + 0x2028f843,/*6b3c*/ + 0xf8434b08, + 0x4b052028, + 0x4b0e701a, + 0x2201701a, + 0xf8434b08, + 0xbf002028, + 0xba32f624, + 0xc0006b60, + 0x00000000, + 0xc0006b68, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0006b78, + 0x00000001, + 0x00000001, + 0x00000001, + 0xc0006b88, + 0x00000000,/*6b88*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch_testmode_2 = +{ + 2, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t3_ins_patch_data_testmode_2), + 0x0002afbc, + 0xbdbef1db, + 0xc0006b3c, + (uint8_t *)bes2300p_t3_ins_patch_data_testmode_2 +};//sync clear count + +const uint32_t bes2300p_t3_ins_patch_data_testmode_3[] = +{ + 0x47f0e92d,/*7050*/ + 0x4b97b082, + 0x236e5c1e, + 0xf300fb03, + 0x5a9b4a95, + 0x4f00f413, + 0x8120f040, + 0x46044689, + 0x1800ea4f, + 0xeb084f91, + 0x4b910507, + 0xa020f853, + 0xf8524a90, + 0x33013020, + 0x3020f842, + 0xf860f635, + 0x42a04601, + 0x8088f040, + 0xf8534b8a, + 0x4b8a2024, + 0x429a681b, + 0xf8dad817, + 0xebc22084, + 0xf0230309, + 0xf1b34378, + 0xd9046f80, + 0x0302ebc9, + 0x4378f023, + 0x4a82425b, + 0x0024f852, + 0x68124a81, + 0xf200fb02, + 0xf2404293, + 0x4b7f80eb, + 0x3000f993, + 0x4b7eb9c3, + 0xc000f893, + 0x0f00f1bc, + 0x462ad00a, + 0x0e0ceb05, + 0xf9122300, + 0x44030b01, + 0xd1fa4572, + 0xe0014662, + 0x46132200, + 0xfcfcfb93, + 0xf8804872, + 0xe001c000, + 0x46132200, + 0xf890486f, + 0x4870e000, + 0x9000f890, + 0xf890486f, + 0xfa4fc000, + 0xebc9f08e, + 0xfa4f0000, + 0x4550fa8c, + 0xebc9dd05, + 0x48660e0e, + 0xe000f880, + 0x4864e002, + 0xc000f880, + 0x0e00f04f, + 0xf840485d, + 0xf8dfe024, + 0xf85ee178, + 0x30010024, + 0x0024f84e, + 0x7800485d, + 0xd2054286, + 0x783f4f5a, + 0x360155af, + 0xe004b2f6, + 0x78364e57, + 0x6007f808, + 0x4f4d2601, + 0x4282553e, + 0x442ada06, + 0xf9124405, + 0x44234b01, + 0xd1fa42aa, + 0xfb934a53, + 0x9200f0f0, + 0xb2406a14, + 0x23002201, + 0xe08147a0, + 0xf8534b46, + 0x4b4e2024, + 0x429a681b, + 0xf8dad816, + 0xebc22084, + 0xf0230309, + 0xf1b34378, + 0xd9046f80, + 0x0302ebc9, + 0x4378f023, + 0x4a3e425b, + 0x1024f852, + 0x68124a44, + 0xf201fb02, + 0xd9634293, + 0xf9934b42, + 0xb9c33000, + 0xf8934b3a, + 0xf1bee000, + 0xd00a0f00, + 0xeb05462a, + 0x2300000e, + 0x1b01f912, + 0x4282440b, + 0x4672d1fa, + 0x2200e001, + 0xfb934613, + 0x4936fefe, + 0xe000f881, + 0x2200e001, + 0x49334613, + 0x49337808, + 0xc000f891, + 0xf8914932, + 0xb241e000, + 0x0101ebcc, + 0xf98efa4f, + 0xdd044549, + 0x0000ebcc, + 0x7008492a, + 0x4929e002, + 0xe000f881, + 0x491c2000, + 0x0024f841, + 0xf850481c, + 0x31011024, + 0x1024f840, + 0x7808491c, + 0xd2054286, + 0x78094920, + 0x360155a9, + 0xe004b2f6, + 0x7809491d, + 0x1007f808, + 0x490c2601, + 0x4282550e, + 0x442ada06, + 0xf9124405, + 0x440b1b01, + 0xd1fa42aa, + 0xfb934a12, + 0x9200f0f0, + 0xb2406a15, + 0x22014621, + 0x47a82300, + 0xe8bdb002, + 0xbf0087f0, + 0xc0006af8,//rssi_idx_for_agc[link_id] shenxin + 0xd02111f8,//EM_BT_RD(EM_BT_RXBIT_ADDR + 0xc0006afc,//rssi_set_for_agc shenxin + 0xc00009d4,//ld_acl_env[link_id] + 0xc0006b68,//link_no_sync_count[link_id] + 0xc00072fc,//link_agc_thd_tws + 0xc0006b78,//link_no_sync_count_time[link_id] + 0xc0007300,//link_agc_thd_tws_time + 0xc0006b60,//rssi_store_tws + 0xc0006af4,//n shenxin + 0xc0007304,//rssi_tws_step + 0xc0007308,//rssi_min_value_tws + 0xc0004268,//rwip_rf.rxgain_cntl + 0xc000730c,//link_agc_thd_mobile + 0xc0007310,//link_agc_thd_mobile_time + 0xc0006b88,//rssi_store_mobile + 0xc0007314,//rssi_mobile_step + 0xc0007318,//rssi_min_value_mobile + 0xffffffff,//link_agc_thd_tws + 0x00000030,//link_agc_thd_tws_time + 0x00000014,//rssi_tws_step + 0x0000009c,//rssi_min_value_tws + 0xffffffff,//link_agc_thd_mobile + 0x00000030,//link_agc_thd_mobile_time + 0x00000014,//rssi_mobile_step + 0x000000a1,//rssi_min_value_mobile + 0x99029804, + 0xfe96f7ff, + 0xfc48f632, + 0xb898f626,/*7328*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch_testmode_3 = +{ + 3, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t3_ins_patch_data_testmode_3), + 0x0002d458, + 0xbf60f1d9, + 0xc0007050, + (uint8_t *)bes2300p_t3_ins_patch_data_testmode_3 +};//swagc no sync + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch_testmode_4 = +{ + 4, + BTDRV_PATCH_ACT, + 0, + 0x0000e47a, + 0xe0027b20, + 0, + NULL +};//lm_inq_res_ind_handler() rssi + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch_testmode_5 = +{ + 5, + BTDRV_PATCH_INACT, + 0, + 0x0002ad78, + 0xbf00e009, + 0, + NULL +};//ld_acl_rx_no_sync() rssi + +const uint32_t bes2300p_t3_ins_patch_data_testmode_6[] = +{ + 0xf8802300, + 0xf8803024, + 0xbf003025, + 0x30b3f894, + 0xbc18f62d, +};/* 6b90-6ba0 */ + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch_testmode_6 = +{ + 6, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t3_ins_patch_data_testmode_6), + 0x000343d0, + 0xbbdef1d2, + 0xc0006b90, + (uint8_t *)bes2300p_t3_ins_patch_data_testmode_6 +};//nosig test pattern problem + +const BTDRV_PATCH_STRUCT bes2300p_t3_ins_patch_testmode_7 = +{ + 7, + BTDRV_PATCH_ACT, + 0, + 0x00000880, + 0x26004c0e, + 0, + NULL, +};//rwip_env.sleep_enable=false after hci reset + +static const uint32_t ins_patch_2300p_t3_config_testmode[] = +{ + 8, + (uint32_t)&bes2300p_t3_ins_patch_testmode_0, + (uint32_t)&bes2300p_t3_ins_patch_testmode_1, + (uint32_t)&bes2300p_t3_ins_patch_testmode_2, + (uint32_t)&bes2300p_t3_ins_patch_testmode_3, + (uint32_t)&bes2300p_t3_ins_patch_testmode_4, + (uint32_t)&bes2300p_t3_ins_patch_testmode_5, + (uint32_t)&bes2300p_t3_ins_patch_testmode_6, + (uint32_t)&bes2300p_t3_ins_patch_testmode_7, +}; +/////////////2300p t2 test mode patch/////////////////////// + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch_testmode_0 = +{ + 0, + BTDRV_PATCH_ACT, + 0, + 0x00000874, + 0x26004c0e, + 0, + NULL, +};////rwip_env.sleep_enable=false after hci reset + +const uint32_t bes2300p_t2_ins_patch_data_testmode_1[] = +{ + 0x4681b083,/*6b30*/ + 0x4b022200, + 0x2020f843, + 0xbddcf623, + 0xc0006b44, + 0x00000000, + 0x00000000, + 0x00000000,/*6b4c*/ +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch_testmode_1 = +{ + 1, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t2_ins_patch_data_testmode_1), + 0x0002a6f4, + 0xba1cf1dc, + 0xc0006b30, + (uint8_t *)bes2300p_t2_ins_patch_data_testmode_1 +};//sync clear count + +const uint32_t bes2300p_t2_ins_patch_data_testmode_2[] = +{ + 0x6020f853, + 0xf8524a0d, + 0x33013020, + 0x3020f842, + 0x68124a0b, + 0xd90f4293, + 0x4a082300, + 0x3020f842, + 0xb082b402, + 0x92004a08, + 0xf06f6a14, + 0x46290059, + 0x47a02201, + 0xbc02b002, + 0xbce4f623, + 0xc0006b44, + 0xc0006b94, + 0x00000010, + 0xc00041b4, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch_testmode_2 = +{ + 2, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t2_ins_patch_data_testmode_2), + 0x0002a550, + 0xbafef1dc, + 0xc0006b50, + (uint8_t *)bes2300p_t2_ins_patch_data_testmode_2 +}; + +const uint32_t bes2300p_t2_ins_patch_data_testmode_3[] = +{ + /*6f90*/ 0xbf009904, + /*6f94*/ 0x4b12b470, + /*6f98*/ 0x010e5c5a, + /*6f9c*/ 0x19734d11, + /*6fa0*/ 0x78244c11, + /*6fa4*/ 0xd20342a2, + /*6fa8*/ 0x32015498, + /*6fac*/ 0xe001b2d2, + /*6fb0*/ 0x22015570, + /*6fb4*/ 0x5442480a, + /*6fb8*/ 0x461ab14c, + /*6fbc*/ 0x23001919, + /*6fc0*/ 0x0b01f912, + /*6fc4*/ 0xbf004403, + /*6fc8*/ 0xd1f9428a, + /*6fcc*/ 0x2300e000, + /*6fd0*/ 0xf0f4fb93, + /*6fd4*/ 0xbc70b240, + /*6fd8*/ 0x22019904, + /*6fdc*/ 0xbb8cf628, //jump a002f6f8 + /*6fe0*/ 0xc0006ff0, //addr of rssi_idx_for_agc + /*6fe4*/ 0xc0006ff4, //addr of rssi_set_for_agc + /*6fe8*/ 0xc0006fec, //addr of N + /*6fec*/ 0x00000005, //N : 1 ~ 16 + /*6ff0*/ 0x00000000, //rssi_idx_for_agc[3] + /*6ff4*/ 0xbabababa, //rssi_set_for_agc[3*16] + /*6ff8*/ 0xbabababa, + /*6ffc*/ 0xbabababa, + /*7000*/ 0xbabababa, + /*7004*/ 0xbabababa, + /*7008*/ 0xbabababa, + /*700c*/ 0xbabababa, + /*7010*/ 0xbabababa, + /*7014*/ 0xbabababa, + /*7018*/ 0xbabababa, + /*701c*/ 0xbabababa, + /*7020*/ 0xbabababa, + /*7024*/ 0xbabababa, + /*7028*/ 0xbabababa, + /*702c*/ 0xbabababa, +};//0xc0006f90--->0xc0007074 + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch_testmode_3 = +{ + 3, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t2_ins_patch_data_testmode_3), + 0x0002f6f4, + 0xbc4cf1d7, //jump a002f6f4 -> a0206f90 + 0xc0006f90, + (uint8_t *)bes2300p_t2_ins_patch_data_testmode_3 +}; //ld_acl_rx() average rssi + +const uint32_t bes2300p_t2_ins_patch_data_testmode_4[] = +{ + 0x4620461d, + 0x463a4629, + 0xf5f94633, + 0xbdf8fc2b, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch_testmode_4 = +{ + 4, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t2_ins_patch_data_testmode_4), + 0x000070ec, + 0xbe08f1ff, + 0xc0006d00, + (uint8_t *)bes2300p_t2_ins_patch_data_testmode_4 +};//assert warn + +const uint32_t bes2300p_t2_ins_patch_data_testmode_5[] = +{ + 0x4630461f, + 0x462a4639, + 0xf5f94623, + 0xbdf8fc21, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch_testmode_5 = +{ + 5, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t2_ins_patch_data_testmode_5), + 0x00007070, + 0xbe50f1ff, + 0xc0006d14, + (uint8_t *)bes2300p_t2_ins_patch_data_testmode_5 +};//assert param + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch_testmode_6 = +{ + 6, + BTDRV_PATCH_ACT, + 0, + 0x0003bbe0, + 0xf7c52100, + 0, + NULL, +};///ble tx test mode switch freq channel problem + +const uint32_t bes2300p_t2_ins_patch_data_testmode_7[] = +{ + 0xf8802300, + 0xf8803024, + 0xbf003025, + 0x30b3f894, + 0xbe0ef62c, +};/* 6d30-6d40 */ + +const BTDRV_PATCH_STRUCT bes2300p_t2_ins_patch_testmode_7 = +{ + 7, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t2_ins_patch_data_testmode_7), + 0x0003395c, + 0xb9e8f1d3, + 0xc0006d30, + (uint8_t *)bes2300p_t2_ins_patch_data_testmode_7 +};//nosig test pattern problem + +static const uint32_t ins_patch_2300p_t2_config_testmode[] = +{ + 8, + (uint32_t)&bes2300p_t2_ins_patch_testmode_0, + (uint32_t)&bes2300p_t2_ins_patch_testmode_1, + (uint32_t)&bes2300p_t2_ins_patch_testmode_2, + (uint32_t)&bes2300p_t2_ins_patch_testmode_3, + (uint32_t)&bes2300p_t2_ins_patch_testmode_4, + (uint32_t)&bes2300p_t2_ins_patch_testmode_5, + (uint32_t)&bes2300p_t2_ins_patch_testmode_6, + (uint32_t)&bes2300p_t2_ins_patch_testmode_7, +}; + +/////////////2300p t1 test mode patch/////////////////////// + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch_testmode_0 = +{ + 0, + BTDRV_PATCH_ACT, + 0, + 0x0002f440, + 0x789abf00, + 0, + NULL +};///test mode: remove rxllid's judging condition in ld_acl_rx + +const uint32_t bes2300p_t1_ins_patch_data_testmode_1[] = +{ + 0x20fcf8d5, + 0xf8928811, + 0xf0088007, + 0xb909080f, + 0x88194b11, + 0x0484eb04, + 0x3014f837, + 0xf423b29b, + 0x4a0f7300, + 0xea438812, + 0xb29b2342, + 0x3014f827, + 0x3014f837, + 0xf023b29b, + 0xea430378, + 0xf82708c8, + 0x4b068014, + 0xf043781b, + 0xea430304, + 0xb28b01c1, + 0x3014f82a, + 0xbe8ef627, + 0xc000099c,////loopback_length + 0xc000097d,////loopback_llid + 0xc0006964,////rxseq_flag + 0x00000000, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch_testmode_1 = +{ + 1, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_ins_patch_data_testmode_1), + 0x0002e60c, + 0xb978f1d8, + 0xc0006900, + (uint8_t*)bes2300p_t1_ins_patch_data_testmode_1 +};///test mode: ld_acl_tx_prog + + +const uint32_t bes2300p_t1_ins_patch_data_testmode_2[] = +{ + 0xfbdcf5fc, + 0x3060f890, + 0xd01f2b00, + 0x30fcf8db, + 0xd01b2b00, + 0x0f03f1b9, + 0xf1b9d018, + 0xd0150f08, + 0xf8934b0b, + 0x011b31cb, + 0x5a9b4a0a, + 0x7f80f413, + 0x4b09d10a, + 0x4b0a781a, + 0x4b08601a, + 0x4b09881a, + 0x2201601a, + 0x601a4b08, + 0xbc32f628, + 0xbc2ef628, + 0xc0005d34, + 0xd02115f2, + 0xc000097d,////loopback_llid + 0xc000099c,////loopback_length + 0xc0006a8c,////rxllid_flag + 0xc0006a90,////rxlength_flag + 0xc0006a94,////unack_seqerr_flag + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch_testmode_2 = +{ + 2, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_ins_patch_data_testmode_2), + 0x0002f2c8, + 0xbbaaf1d7, + 0xc0006a20, + (uint8_t*)bes2300p_t1_ins_patch_data_testmode_2 +};///test mode: skip rx seq err in ld_acl_rx + +#if 0 +const uint32_t bes2300p_t1_ins_patch_data_testmode_3[] = +{ + 0xf015d002, + 0xd0010f24, + 0xbc1af628, + 0xbcfcf628, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch_testmode_3 = +{ + 3, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_ins_patch_data_testmode_3), + 0x0002f2d4, + 0xbbe0f1d7, + 0xc0006a98, + (uint8_t*)bes2300p_t1_ins_patch_data_testmode_3 +};///test mode: skip crc err in ld_acl_rx +#else +const uint32_t bes2300p_t1_ins_patch_data_testmode_3[] = +{ + 0xf015d006, + 0xd0050f24, + 0x0f03f1b9, + 0xbf00d002, + 0xbc16f628, + 0xbcf8f628, +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch_testmode_3 = +{ + 3, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_ins_patch_data_testmode_3), + 0x0002f2d4, + 0xbbe0f1d7, + 0xc0006a98, + (uint8_t*)bes2300p_t1_ins_patch_data_testmode_3 +};///test mode: skip crc err in ld_acl_rx + +#endif + +const uint32_t bes2300p_t1_ins_patch_data_testmode_4[] = +{ + 0x700d4914, + 0xf891490c, + 0x010911cb, + 0x5a8a4a0b, + 0x2240f3c2, + 0x6002480a, + 0x6800480a, + 0x2100b150, + 0x60014808, + 0x68014808, + 0x80014808, + 0x68014808, + 0x70014808, + 0xbcbaf628, + 0xc0005d34, + 0xd02115f2, + 0xc0006964,////rxseq_flag + 0xc0006a94,////unack_seqerr_flag + 0xc0006a90,////rxlength_flag + 0xc000099c,////loopback_length + 0xc0006a8c,////rxllid_flag + 0xc000097d,////loopback_llid +}; + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch_testmode_4 = +{ + 4, + BTDRV_PATCH_ACT, + sizeof(bes2300p_t1_ins_patch_data_testmode_4), + 0x0002f464, + 0xbb2af1d7, + 0xc0006abc, + (uint8_t*)bes2300p_t1_ins_patch_data_testmode_4 +};///test mode: ld_acl_rx + +const BTDRV_PATCH_STRUCT bes2300p_t1_ins_patch_testmode_5 = +{ + 5, + BTDRV_PATCH_ACT, + 0, + 0x00000100, + 0x20004b15, + 0, + NULL, +};////rwip_env.sleep_enable=false after hci reset + +static const uint32_t ins_patch_2300p_t1_config_testmode[] = +{ + 6, + (uint32_t)&bes2300p_t1_ins_patch_testmode_0, + (uint32_t)&bes2300p_t1_ins_patch_testmode_1, + (uint32_t)&bes2300p_t1_ins_patch_testmode_2, + (uint32_t)&bes2300p_t1_ins_patch_testmode_3, + (uint32_t)&bes2300p_t1_ins_patch_testmode_4, + (uint32_t)&bes2300p_t1_ins_patch_testmode_5, +}; + +void btdrv_ins_patch_test_init(void) +{ + const BTDRV_PATCH_STRUCT *ins_patch_p; + + btdrv_patch_en(0); + + for(uint8_t i=0; i<56; i++) + { + btdrv_ins_patch_disable(i); + } + bt_drv_reg_op_for_test_mode_disable(); + + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0 ) + { + for(uint8_t i=0; ipatch_state ==BTDRV_PATCH_ACT) + btdrv_ins_patch_write((BTDRV_PATCH_STRUCT *)ins_patch_2300p_t1_config_testmode[i+1]); + } + } + else if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1 ) + { + for(uint8_t i=0; ipatch_state ==BTDRV_PATCH_ACT) + btdrv_ins_patch_write((BTDRV_PATCH_STRUCT *)ins_patch_2300p_t2_config_testmode[i+1]); + } + + } + else if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2 ) + { + for(uint8_t i=0; ipatch_state ==BTDRV_PATCH_ACT) + btdrv_ins_patch_write((BTDRV_PATCH_STRUCT *)ins_patch_2300p_t3_config_testmode[i+1]); + } + bt_drv_reg_op_disable_swagc_nosync_count(); + } + else + { + ASSERT(0, "%s:error chip id=%d", __func__, hal_get_chip_metal_id()); + } + + btdrv_patch_en(1); +} diff --git a/platform/drivers/bt/best2300p/bt_drv_reg_op.cpp b/platform/drivers/bt/best2300p/bt_drv_reg_op.cpp new file mode 100644 index 0000000..dfe84ad --- /dev/null +++ b/platform/drivers/bt/best2300p/bt_drv_reg_op.cpp @@ -0,0 +1,3278 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis.h" +#include "bt_drv_reg_op.h" +#include "bt_drv_internal.h" +#include "bt_drv_2300p_internal.h" +#include "bt_drv_interface.h" +#include "bt_drv.h" +#include "hal_sysfreq.h" +#include "hal_chipid.h" +#include "hal_trace.h" +#include "hal_iomux.h" +#include +#include "CrashCatcher.h" +#include "bt_drv_internal.h" + + +static uint32_t bt_ram_start_addr=0; +static uint32_t hci_fc_env_addr=0; +static uint32_t ld_acl_env_addr=0; +static uint32_t bt_util_buf_env_addr=0; +static uint32_t em_buf_env_addr=0; +static uint32_t sniffer_env_addr=0; +static uint32_t dbg_state_addr=0; +static uint32_t lc_state_addr=0; +static uint32_t task_message_buffer_addr=0; +static uint32_t lmp_message_buffer_addr=0; +static uint32_t ld_sco_env_addr=0; +static uint32_t rx_monitor_addr=0; +static uint32_t lc_env_addr=0; +static uint32_t dbg_bt_setting_addr=0; +static uint32_t lm_nb_sync_active_addr=0; +static uint32_t lm_env_addr=0; +static uint32_t pending_seq_error_link_addr=0; +static uint32_t hci_env_addr=0; +static uint32_t lc_sco_env_addr=0; +static uint32_t llm_le_env_addr=0; +static uint32_t ld_env_addr=0; +static uint32_t rwip_env_addr=0; +static uint32_t MIC_BUFF_addr=0; +static uint32_t g_mem_dump_ctrl_addr=0; +static uint32_t ble_rx_monitor_addr=0; +static uint32_t reconnecting_flag_addr=0; +static uint32_t link_connect_bak_addr=0; +static uint32_t tws_link_id_addr=0; +static uint32_t llc_env_addr=0; +static uint32_t dbg_bt_setting_ext1_addr=0; +static uint32_t rwip_rf_addr=0; +void bt_drv_reg_op_global_symbols_init(void) +{ + bt_ram_start_addr = 0xc0000000; + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0) + { + hci_fc_env_addr = 0xC00067c4; + ld_acl_env_addr = 0xc000098c; + bt_util_buf_env_addr = 0xc00059fc; + em_buf_env_addr = 0xc000656c; + sniffer_env_addr = 0xc0006358; + dbg_state_addr = 0xc00058c4; + lc_state_addr = 0xc0005c7c; + task_message_buffer_addr = 0xc00007cc; + lmp_message_buffer_addr = 0xc0000834; + ld_sco_env_addr = 0xc0000980; + rx_monitor_addr = 0xc00058fc; + lc_env_addr = 0xc0005c70; + dbg_bt_setting_addr = 0xc0005854; + lm_nb_sync_active_addr = 0xc00007c0; + lm_env_addr = 0xc0005afc; + hci_env_addr = 0xc0006764; + lc_sco_env_addr = 0xc00007a4; + llm_le_env_addr = 0xc00063f0; + ld_env_addr = 0xc0005d34; + rwip_env_addr = 0xc00003d4; + MIC_BUFF_addr = 0xc0005920; + ble_rx_monitor_addr = 0xc00058ec; + llc_env_addr = 0xc00064f8; + rwip_rf_addr = 0xc00041a0; + + } + else if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) + { + hci_fc_env_addr = 0xC0006838; + ld_acl_env_addr = 0xc0000998; + bt_util_buf_env_addr = 0xc0005a18; + em_buf_env_addr = 0xc00065e0; + sniffer_env_addr = 0xc00063c8; + dbg_state_addr = 0xc00058e0; + lc_state_addr = 0xc0005ce4; + task_message_buffer_addr = 0xc00007c4; + lmp_message_buffer_addr = 0xc000082c; + ld_sco_env_addr = 0xc000098c; + rx_monitor_addr = 0xc0005918; + lc_env_addr = 0xc0005cd8; + dbg_bt_setting_addr = 0xc0005868; + lm_nb_sync_active_addr = 0xc00007b8; + lm_env_addr = 0xc0005b64; + pending_seq_error_link_addr = 0xc0000335; + hci_env_addr = 0xc00067d8; + lc_sco_env_addr = 0xc000079c; + llm_le_env_addr = 0xc0006460; + ld_env_addr = 0xc0005d9c; + rwip_env_addr = 0xc00003c8; + MIC_BUFF_addr = 0xc000593c; + ble_rx_monitor_addr = 0xc0005908; + link_connect_bak_addr = 0xc00061c8; + llc_env_addr = 0xc0006568; + rwip_rf_addr = 0xc00041b4; + + } + else if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + hci_fc_env_addr = 0xC0006940; + ld_acl_env_addr = 0xc00009d4; + bt_util_buf_env_addr = 0xc0005b24; + em_buf_env_addr = 0xc00066e8; + sniffer_env_addr = 0xc00064d0; + dbg_state_addr = 0xc00059b0; + lc_state_addr = 0xc0005df0; + task_message_buffer_addr = 0xc0000820; + lmp_message_buffer_addr = 0xc0000888; + ld_sco_env_addr = 0xc00009e4; + rx_monitor_addr = 0xc0005a24; + lc_env_addr = 0xc0005de4; + dbg_bt_setting_addr = 0xc0005938; + lm_nb_sync_active_addr = 0xc0000814; + lm_env_addr = 0xc0005c70; + pending_seq_error_link_addr = 0xc000034f; + hci_env_addr = 0xc00068e0; + lc_sco_env_addr = 0xc00007f8; + llm_le_env_addr = 0xc0006568; + ld_env_addr = 0xc0005ea8; + rwip_env_addr = 0xc00003dc; + MIC_BUFF_addr = 0xc0005a48; + g_mem_dump_ctrl_addr = 0xc00059d4; + ble_rx_monitor_addr = 0xc0005a14; + reconnecting_flag_addr = 0xc0000a1c; + link_connect_bak_addr = 0xc00062d0; + tws_link_id_addr = 0xc000034e; + llc_env_addr = 0xc0006670; + dbg_bt_setting_ext1_addr = 0xc000591c; + rwip_rf_addr = 0xc0004268; + + } +} + + + +void bt_drv_reg_op_rssi_set(uint16_t rssi) +{ +} + +void bt_drv_reg_op_scan_intv_set(uint32_t scan_intv) +{ +} + +void bt_drv_reg_op_encryptchange_errcode_reset(uint16_t hci_handle) +{ + +} + +void bt_drv_reg_op_sco_sniffer_checker(void) +{ +} + +void bt_drv_reg_op_trigger_time_checker(void) +{ + BT_DRV_REG_OP_ENTER(); + BT_DRV_TRACE(1,"BT_REG_OP:0xd02201f0 = %x",*(volatile uint32_t *)0xd02201f0); + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_tws_output_power_fix_separate(uint16_t hci_handle, uint16_t pwr) +{ +} + +#define SNIFF_IN_SCO 2 +///BD Address structure +struct bd_addr +{ + ///6-byte array address value + uint8_t addr[6]; +}; +///device info structure +struct ld_device_info +{ + struct bd_addr bd_addr; + uint8_t link_id; + uint8_t state; +}; + +bool bt_drv_reg_op_ld_sniffer_env_monitored_dev_state_get(void) +{ + return false; +} + +void bt_drv_reg_op_ld_sniffer_env_monitored_dev_state_set(bool state) +{ +} + +void bt_drv_reg_op_ibrt_env_reset(void) +{ + struct ld_device_info * mobile_device_info; + BT_DRV_REG_OP_ENTER(); + bool status = false; + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0) + { + mobile_device_info = (struct ld_device_info *)(sniffer_env_addr+4); + status = true; + } + + if(status) + { + mobile_device_info->link_id = 3; + mobile_device_info->state = 0; + } + BT_DRV_REG_OP_EXIT(); +} + +int bt_drv_reg_op_currentfreeaclbuf_get(void) +{ + BT_DRV_REG_OP_ENTER(); + //ACL packert number of host set - ACL number of controller has been send to host + //hci_fc_env.host_set.acl_pkt_nb - hci_fc_env.cntr.acl_pkt_sent + if(hci_fc_env_addr != 0) + { + return (*(volatile uint16_t *)(hci_fc_env_addr+0x4) - *(volatile uint16_t *)(hci_fc_env_addr+0xc)); + } + else + { + return 0; + } + BT_DRV_REG_OP_EXIT(); +} + +static uint16_t mobile_sync_info; +void bt_drv_reg_op_save_mobile_airpath_info(uint16_t hciHandle) +{ + BT_DRV_REG_OP_ENTER(); + + uint8_t link_id = btdrv_conhdl_to_linkid(hciHandle); + + if (btdrv_is_link_index_valid(link_id)) + { + mobile_sync_info = BT_DRIVER_GET_U16_REG_VAL(EM_BT_BTADDR1_ADDR + BT_EM_SIZE*link_id); + BT_DRV_TRACE(1,"BT_REG_OP: save xfer mobile sync info 0x%x ", mobile_sync_info); + } + + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_block_xfer_with_mobile(uint16_t hciHandle) +{ + BT_DRV_REG_OP_ENTER(); + + uint8_t link_id = btdrv_conhdl_to_linkid(hciHandle); + + if (btdrv_is_link_index_valid(link_id)) + { + BT_DRIVER_PUT_U16_REG_VAL((EM_BT_BTADDR1_ADDR + BT_EM_SIZE*link_id), mobile_sync_info^0x8000); + BT_DRV_TRACE(2,"BT_REG_OP: block xfer with mobile, save hci handle 0x%x sync info as 0x%x", hciHandle, mobile_sync_info^0x8000); + } + + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_resume_xfer_with_mobile(uint16_t hciHandle) +{ + BT_DRV_REG_OP_ENTER(); + uint8_t link_id = btdrv_conhdl_to_linkid(hciHandle); + + if (btdrv_is_link_index_valid(link_id)) + { + BT_DRIVER_PUT_U16_REG_VAL((EM_BT_BTADDR1_ADDR + BT_EM_SIZE*link_id), mobile_sync_info); + BT_DRV_TRACE(2,"BT_REG_OP:resume xfer with mobile, hci handle 0x%x as 0x%x", hciHandle, mobile_sync_info); + } + + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_block_fast_ack_with_mobile(void) +{ + /* + * ibrt master set its fast ack sync bit wrong,let itself NACK mobile link always + */ + + BT_DRV_REG_OP_ENTER(); + + bt_drv_set_fa_invert_enable(BT_FA_INVERT_DISABLE); + + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_resume_fast_ack_with_mobile(void) +{ + + /* + * old master recovery its fast ack sync bit right + */ + + BT_DRV_REG_OP_ENTER(); + + bt_drv_set_fa_invert_enable(BT_FA_INVERT_EN); + + BT_DRV_REG_OP_EXIT(); +} + +int bt_drv_reg_op_packet_type_checker(uint16_t hciHandle) +{ + return 0; +} + +void bt_drv_reg_op_max_slot_setting_checker(uint16_t hciHandle) +{} + +void bt_drv_reg_op_force_task_dbg_idle(void) +{ +} + +void bt_drv_reg_op_afh_follow_mobile_mobileidx_set(uint16_t hciHandle) +{} + + +void bt_drv_reg_op_afh_follow_mobile_twsidx_set(uint16_t hciHandle) +{} + +void bt_drv_reg_op_afh_bak_reset(void) +{} + +void bt_drv_reg_op_afh_bak_save(uint8_t role, uint16_t mobileHciHandle) +{} + +void bt_drv_reg_op_connection_checker(void) +{} + +void bt_drv_reg_op_sco_status_store(void) +{} + +void bt_drv_reg_op_sco_status_restore(void) +{} + +void bt_drv_reg_op_afh_set_default(void) +{ +} + +void bt_drv_reg_op_ld_sniffer_master_addr_set(uint8_t * addr) +{ +} + +void bt_drv_reg_op_lsto_hack(uint16_t hciHandle, uint16_t lsto) +{ + uint32_t acl_par_ptr = 0; + //ld_acl_env + + if(ld_acl_env_addr) + { + acl_par_ptr = *(uint32_t *)(ld_acl_env_addr+(hciHandle-0x80)*4); + } + + if(acl_par_ptr) + { + BT_DRV_TRACE(3,"BT_REG_OP:Set the lsto for hciHandle=0x%x, from:0x%x to 0x%x", + hciHandle,*(uint16_t *)(acl_par_ptr+154),lsto); + + *(uint16_t *)(acl_par_ptr+154) = lsto; + } + else + { + BT_DRV_TRACE(0,"BT_REG_OP:ERROR,acl par address error"); + } +} + +uint16_t bt_drv_reg_op_get_lsto(uint16_t hciHandle) +{ + uint32_t acl_par_ptr = 0; + uint16_t lsto = 0; + //ld_acl_env + + if(ld_acl_env_addr) + { + acl_par_ptr = *(uint32_t *)(ld_acl_env_addr+(hciHandle-0x80)*4); + } + + + if(acl_par_ptr) + { + lsto = *(uint16_t *)(acl_par_ptr+154) ; + BT_DRV_TRACE(2,"BT_REG_OP:lsto=0x%x for hciHandle=0x%x",lsto,hciHandle); + } + else + { + lsto= 0xffff; + BT_DRV_TRACE(0,"BT_REG_OP:ERROR,acl par null ptr"); + } + + return lsto; +} + +uint8_t bt_drv_reg_opmsbc_find_tx_sync(uint8_t *buff) +{ + BT_DRV_REG_OP_ENTER(); + + uint8_t i; + for(i=0; i<60; i++) + { + if(buff[i]==0x1 && buff[(i+2)%60] == 0xad) + { + // BT_DRV_TRACE(1,"MSBC tx sync find =%d",i); + return i; + } + } + BT_DRV_TRACE(0,"BT_REG_OP:TX No pACKET"); + + BT_DRV_REG_OP_EXIT(); + return 0; +} + +bool bt_drv_reg_op_sco_tx_buf_restore(uint8_t *trigger_test) +{ + uint8_t offset; + bool nRet = false; + + BT_DRV_REG_OP_ENTER(); + + offset = bt_drv_reg_opmsbc_find_tx_sync((uint8_t *)EM_BT_AUDIOBUF_OFF); + if(offset !=0) + { +#ifndef APB_PCM + *trigger_test = (((BTDIGITAL_REG(0xd022045c) & 0x3f)) +(60-offset))%64; +#endif + BT_DRV_TRACE(2,"BT_REG_OP:TX BUF ERROR trigger_test=%p,offset=%x", trigger_test,offset); + DUMP8("%02x ",(uint8_t *)EM_BT_AUDIOBUF_OFF,10); +// BT_DRV_TRACE(2,"pcm reg=%x %x",*(uint32_t *)0xd0220468,*(uint32_t *)0x400000f0); + nRet = true; + } + + BT_DRV_REG_OP_EXIT(); + + return nRet; +} + +int bt_drv_reg_op_acl_chnmap(uint16_t hciHandle, uint8_t *chnmap, uint8_t chnmap_len) +{ + uint32_t acl_evt_ptr = 0; + uint8_t *chnmap_ptr = 0; + uint8_t link_id = btdrv_conhdl_to_linkid(hciHandle); + + if (!btdrv_is_link_index_valid(link_id)) + { + memset(chnmap, 0, chnmap_len); + return -1; + } + if (chnmap_len < 10) + { + memset(chnmap, 0, chnmap_len); + return -1; + } + + + if(ld_acl_env_addr) + { + acl_evt_ptr = *(volatile uint32_t *)(ld_acl_env_addr+link_id*4); + } + + + if(acl_evt_ptr != 0) + { + chnmap_ptr = (uint8_t *)(acl_evt_ptr+0x34); + } + + if (!chnmap_ptr) + { + memset(chnmap, 0, chnmap_len); + return -1; + } + else + { + memcpy(chnmap, chnmap_ptr, chnmap_len); + } + + return 0; +} + +extern "C" uint32_t hci_current_left_tx_packets_left(void); +extern "C" uint32_t hci_current_left_rx_packets_left(void); +extern "C" uint32_t hci_current_rx_packet_complete(void); +extern "C" uint8_t hci_current_rx_aclfreelist_cnt(void); +void bt_drv_reg_op_bt_info_checker(void) +{ +#ifdef __CLK_GATE_DISABLE__ + uint32_t *rx_buf_ptr=NULL; + uint32_t *tx_buf_ptr=NULL; + uint8_t rx_free_buf_count=0, i=0; + uint8_t tx_free_buf_count=0; + uint16_t em_buf ; + + BT_DRV_REG_OP_ENTER(); + + if(bt_util_buf_env_addr) + { + rx_buf_ptr = (uint32_t *)(bt_util_buf_env_addr+0x14); //bt_util_buf_env.acl_rx_free + tx_buf_ptr = (uint32_t *)(bt_util_buf_env_addr+0x28); //bt_util_buf_env.acl_tx_free + + } + + while(rx_buf_ptr && *rx_buf_ptr) + { + rx_free_buf_count++; + rx_buf_ptr = (uint32_t *)(*rx_buf_ptr); + } + + uint8_t em_buf_count = 0; + for(i=0; i<4; i++) + { + em_buf = BT_DRIVER_GET_U16_REG_VAL(EM_BT_RXACLBUFPTR_ADDR + i*REG_EM_BT_RXDESC_SIZE); + if(em_buf != 0) + em_buf_count++; + } + BT_DRV_TRACE(4,"BT_REG_OP: rxbuff = %x,embuff =%x , host rx buff in controller = %x,%x", \ + rx_free_buf_count, \ + em_buf_count, \ + hci_current_left_rx_packets_left(), \ + bt_drv_reg_op_currentfreeaclbuf_get()); + + //check tx buff + while(tx_buf_ptr && *tx_buf_ptr) + { + tx_free_buf_count++; + tx_buf_ptr = (uint32_t *)(*tx_buf_ptr); + } + + BT_DRV_TRACE(2,"BT_REG_OP:txbuff = %x,acl tx host in controller = %x ", \ + tx_free_buf_count, \ + hci_current_left_tx_packets_left()); + + bt_drv_reg_op_controller_state_checker(); + BT_DRV_REG_OP_EXIT(); +#endif +} + +#if 0 +uint32_t *rxbuff; +uint16_t *send_count; +uint16_t *free_count; +uint16_t *bt_send_count; +#endif +void bt_drv_reg_op_ble_buffer_cleanup(void) +{ +} + +struct ke_timer +{ + /// next ke timer + struct ke_timer *next; + /// message identifier + uint16_t id; + /// task identifier + uint16_t task; + /// time value + uint32_t time; +}; + +struct co_list_hdr +{ + /// Pointer to next co_list_hdr + struct co_list_hdr *next; +}; + +/// structure of a list +struct co_list_con +{ + /// pointer to first element of the list + struct co_list_hdr *first; + /// pointer to the last element + struct co_list_hdr *last; + + /// number of element in the list + uint32_t cnt; + /// max number of element in the list + uint32_t maxcnt; + /// min number of element in the list + uint32_t mincnt; +}; + +struct mblock_free +{ + /// Next free block pointer + struct mblock_free* next; + /// Previous free block pointer + struct mblock_free* previous; + /// Size of the current free block (including delimiter) + uint16_t free_size; + /// Used to check if memory block has been corrupted or not + uint16_t corrupt_check; +}; + +bool bt_drv_reg_op_get_dbg_state(void) +{ + //dbg_state + + if(dbg_state_addr) + { + return (*(uint8_t *)dbg_state_addr); + } + else + { + return false; + } +} + +uint8_t bt_drv_reg_op_get_controller_tx_free_buffer(void) +{ + uint32_t *tx_buf_ptr=NULL; + uint8_t tx_free_buf_count=0; + + if(bt_util_buf_env_addr) + { + tx_buf_ptr = (uint32_t *)(bt_util_buf_env_addr+0x28); //bt_util_buf_env.acl_tx_free + } + else + { + BT_DRV_TRACE(1, "REG_OP: please fix %s", __func__); + return 0; + } + + //check tx buff + while(tx_buf_ptr && *tx_buf_ptr) + { + tx_free_buf_count++; + tx_buf_ptr = (uint32_t *)(*tx_buf_ptr); + } + return tx_free_buf_count; +} + +uint8_t bt_drv_reg_op_get_controller_ble_tx_free_buffer(void) +{ + uint32_t *tx_buf_ptr=NULL; + uint8_t tx_free_buf_count=0; + + if(em_buf_env_addr) + { + tx_buf_ptr = (uint32_t *)(em_buf_env_addr+0x14); //em_buf_env.tx_buff_free + } + else + { + BT_DRV_TRACE(1, "REG_OP: please fix %s", __func__); + return 0; + } + + //check tx buff + while(tx_buf_ptr && *tx_buf_ptr) + { + tx_free_buf_count++; + tx_buf_ptr = (uint32_t *)(*tx_buf_ptr); + } + + return tx_free_buf_count; +} + +void bt_drv_reg_op_controller_state_checker(void) +{ + BT_DRV_REG_OP_ENTER(); + + if(lc_state_addr != 0) + { + BT_DRV_TRACE(1,"BT_REG_OP: LC_STATE=0x%x",*(uint32_t *)lc_state_addr); + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_tx_flow_checker(void) +{ + BT_DRV_REG_OP_ENTER(); + uint8_t link_id = 0; + uint32_t acl_par_ptr = 0; + for(link_id=0; link_id<3; link_id++) + { + if(ld_acl_env_addr) + { + acl_par_ptr = *(volatile uint32_t *)(ld_acl_env_addr+link_id*4); + } + + if (acl_par_ptr) + { + BT_DRV_TRACE(2,"linkid =%d, tx flow=%d",link_id, *(uint8_t *)(acl_par_ptr+0xc0)); + } + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_controller_ble_flow_checker(void) +{ + uint8_t link_id = 0; + uint32_t llc_env_tag_ptr = 0; + uint32_t ea_elt_tag_ptr = 0; + uint32_t *tx_acl_rdy_ptr = NULL; + uint32_t *tx_acl_tofree_ptr = NULL; + uint32_t tx_acl_rdy_count = 0; + uint32_t tx_acl_tofree_count = 0; + + if(!llc_env_addr) + { + BT_DRV_TRACE(1, "REG_OP: please fix %s", __func__); + return; + } + + for (link_id = 0; link_id < 3; link_id += 1) + { + llc_env_tag_ptr = *(volatile uint32_t *)(llc_env_addr + link_id * 4); + if (!llc_env_tag_ptr) + { + continue; + } + + ea_elt_tag_ptr = *(volatile uint32_t *)(((uint32_t)llc_env_tag_ptr) + 16); + if (!ea_elt_tag_ptr) + { + continue; + } + + tx_acl_rdy_ptr = (uint32_t *)(((uint32_t)ea_elt_tag_ptr) + 48); + tx_acl_rdy_count = 0; + while(tx_acl_rdy_ptr && *tx_acl_rdy_ptr) + { + tx_acl_rdy_count++; + tx_acl_rdy_ptr = (uint32_t *)(*tx_acl_rdy_ptr); + } + + tx_acl_tofree_ptr = (uint32_t *)(((uint32_t)ea_elt_tag_ptr) + 68); + tx_acl_tofree_count = 0; + while(tx_acl_tofree_ptr && *tx_acl_tofree_ptr) + { + tx_acl_tofree_count++; + tx_acl_tofree_ptr = (uint32_t *)(*tx_acl_tofree_ptr); + } + + BT_DRV_TRACE(3, "linkid =%d, ble tx alloc=%d tofree=%d", link_id, tx_acl_rdy_count, tx_acl_tofree_count); + } +} + +uint8_t bt_drv_reg_op_force_get_lc_state(uint16_t conhdl) +{ + if(lc_state_addr != 0) + { + //BT_DRV_TRACE(1,"BT_REG_OP: read LC_STATE=0x%x",*(uint32_t *)lc_state_addr); + uint8_t idx = btdrv_conhdl_to_linkid(conhdl); + + if (btdrv_is_link_index_valid(idx)) + { + uint8_t * lc_state = (uint8_t *)lc_state_addr; + return lc_state[idx]; + } + } + return 0; +} +void bt_drv_reg_op_force_set_lc_state(uint16_t conhdl, uint8_t state) +{ + //lc_state + + if(lc_state_addr != 0) + { + BT_DRV_TRACE(1,"BT_REG_OP: read LC_STATE=0x%x",*(uint32_t *)lc_state_addr); + uint8_t idx = btdrv_conhdl_to_linkid(conhdl); + + if (btdrv_is_link_index_valid(idx)) + { + uint8_t * lc_state = (uint8_t *)lc_state_addr; + lc_state[idx] = state; + } + } +} + +void bt_drv_reg_op_crash_dump(void) +{ + if(hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) + { + uint8_t *bt_dump_mem_start = (uint8_t*)bt_ram_start_addr; + uint32_t bt_dump_len_max = 0x8000; + + //uint8_t *mcu_dump_mem_start = (uint8_t*)0x20000000; + //uint32_t mcu_dump_len_max = RAM_SIZE; + + //uint8_t *em_dump_area_1_start = (uint8_t*)0xd0220000; + //uint32_t em_area_1_len_max = 0x04A8; + + uint8_t *em_dump_area_2_start = (uint8_t*)0xd0210000; + uint32_t em_area_2_len_max = 0x8000; + + BT_DRV_TRACE(1,"BT_REG_OP:BT 2300p: metal id=%d", hal_get_chip_metal_id()); + //first move R3 to R9, lost R9 + BT_DRV_TRACE(1,"BT controller BusFault_Handler:\nREG:[LR] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE)); + BT_DRV_TRACE(1,"REG:[R0] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +120)); + BT_DRV_TRACE(1,"REG:[R1] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +124)); + BT_DRV_TRACE(1,"REG:[R2] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +128)); + BT_DRV_TRACE(1,"REG:[R3] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +132)); + BT_DRV_TRACE(1,"REG:[R4] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +4)); + BT_DRV_TRACE(1,"REG:[R5] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +8)); + BT_DRV_TRACE(1,"REG:[R6] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +12)); + BT_DRV_TRACE(1,"REG:[R7] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +16)); + BT_DRV_TRACE(1,"REG:[R8] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +20)); + hal_sys_timer_delay(MS_TO_TICKS(100)); + + //BT_DRV_TRACE(1,"REG:[R9] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +24)); + BT_DRV_TRACE(1,"REG:[sl] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +28)); + BT_DRV_TRACE(1,"REG:[fp] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +32)); + BT_DRV_TRACE(1,"REG:[ip] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +36)); + BT_DRV_TRACE(1,"REG:[SP,#0] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +40)); + BT_DRV_TRACE(1,"REG:[SP,#4] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +44)); + BT_DRV_TRACE(1,"REG:[SP,#8] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +48)); + BT_DRV_TRACE(1,"REG:[SP,#12] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +52)); + BT_DRV_TRACE(1,"REG:[SP,#16] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +56)); + BT_DRV_TRACE(1,"REG:[SP,#20] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +60)); + BT_DRV_TRACE(1,"REG:[SP,#24] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +64)); + BT_DRV_TRACE(1,"REG:[SP,#28] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +68)); + hal_sys_timer_delay(MS_TO_TICKS(100)); + + BT_DRV_TRACE(1,"REG:[SP,#32] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +72)); + BT_DRV_TRACE(1,"REG:[SP,#36] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +76)); + BT_DRV_TRACE(1,"REG:[SP,#40] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +80)); + BT_DRV_TRACE(1,"REG:[SP,#44] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +84)); + BT_DRV_TRACE(1,"REG:[SP,#48] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +88)); + BT_DRV_TRACE(1,"REG:[SP,#52] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +92)); + BT_DRV_TRACE(1,"REG:[SP,#56] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +96)); + BT_DRV_TRACE(1,"REG:[SP,#60] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +100)); + BT_DRV_TRACE(1,"REG:[SP,#64] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +104)); + BT_DRV_TRACE(1,"REG:SP = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +108)); + BT_DRV_TRACE(1,"REG:MSP = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +112)); + BT_DRV_TRACE(1,"REG:PSP = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +116)); + BT_DRV_TRACE(1,"REG:CFSR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +120)); + BT_DRV_TRACE(1,"REG:BFAR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +124)); + BT_DRV_TRACE(1,"REG:HFSR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +128)); + BT_DRV_TRACE(1,"REG:ICSR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +132)); + BT_DRV_TRACE(1,"REG:AIRCR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +136)); + BT_DRV_TRACE(1,"REG:SCR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +140)); + BT_DRV_TRACE(1,"REG:CCR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +144)); + BT_DRV_TRACE(1,"REG:SHCSR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +148)); + BT_DRV_TRACE(1,"REG:AFSR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +152)); + BT_DRV_TRACE(1,"REG:MMFAR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +156)); + hal_sys_timer_delay(MS_TO_TICKS(100)); + //task_message_buffer + uint32_t buff_addr = 0; + + if(task_message_buffer_addr) + { + buff_addr = task_message_buffer_addr; + } + + BT_DRV_TRACE(2,"0xd0330050: 0x%x, 54:0x%x",*(uint32_t *)0xd0330050,*(uint32_t *)0xd0330054); + BT_DRV_TRACE(2,"0x400000a0: 0x%x, a4:0x%x",*(uint32_t *)0x400000a0,*(uint32_t *)0x400000a4); + + if(g_mem_dump_ctrl_addr) + { + BT_DRV_TRACE(1,"LMP addr=0x%x",*(uint32_t *)(g_mem_dump_ctrl_addr+4)); + BT_DRV_TRACE(1,"STA addr=0x%x",*(uint32_t *)(g_mem_dump_ctrl_addr+0x10)); + BT_DRV_TRACE(1,"MSG addr=0x%x",*(uint32_t *)(g_mem_dump_ctrl_addr+0x1c)); + BT_DRV_TRACE(1,"SCH addr=0x%x",*(uint32_t *)(g_mem_dump_ctrl_addr+0x28)); + BT_DRV_TRACE(1,"ISR addr=0x%x",*(uint32_t *)(g_mem_dump_ctrl_addr+0x34)); + } + + BT_DRV_TRACE(0,"task msg buff:"); + if(buff_addr != 0) + { + for(uint8_t j=0; j<5; j++) + { + DUMP8("%02x ", (uint8_t *)(buff_addr+j*20), 20); + } + } + hal_sys_timer_delay(MS_TO_TICKS(100)); + + BT_DRV_TRACE(0," "); + BT_DRV_TRACE(0,"lmp buff:"); + //lmp_message_buffer + + if(lmp_message_buffer_addr) + { + buff_addr = lmp_message_buffer_addr; + } + + if(buff_addr != 0) + { + for(uint8_t j=0; j<10; j++) + { + DUMP8("%02x ",(uint8_t *)(buff_addr+j*20), 20); + } + } + hal_sys_timer_delay(MS_TO_TICKS(100)); + + uint8_t link_id = 0; + uint32_t evt_ptr = 0; + uint32_t acl_par_ptr = 0; + for(link_id=0; link_id<3; link_id++) + { + BT_DRV_TRACE(1,"acl_par: link id %d",link_id); + + if(ld_acl_env_addr) + { + evt_ptr = *(uint32_t *)(ld_acl_env_addr+link_id*4); + } + + + if (evt_ptr) + { + acl_par_ptr = evt_ptr; + BT_DRV_TRACE(5,"acl_par: acl_par_ptr 0x%x, clk off 0x%x, bit off 0x%x, last sync clk off 0x%x, last sync bit off 0x%x", + acl_par_ptr, *(uint32_t *)(acl_par_ptr+140),*(uint16_t *)(acl_par_ptr+150), + *(uint32_t *)(acl_par_ptr+136),((*(uint32_t *)(acl_par_ptr+150))&0xFFFF0000)>>16); + } + } + hal_sys_timer_delay(MS_TO_TICKS(100)); + + //ld_sco_env + evt_ptr = 0; + + if(ld_sco_env_addr) + { + evt_ptr = *(uint32_t *)ld_sco_env_addr; + } + + if(evt_ptr != 0) + { + BT_DRV_TRACE(1,"esco linkid :%d",*(uint8_t *)(evt_ptr+70)); + for(link_id=0; link_id<3; link_id++) + { + BT_DRV_TRACE(2,"bt_linkcntl_linklbl 0x%x: link id %d",*(uint16_t *)(EM_BT_LINKCNTL_ADDR+link_id*BT_EM_SIZE),link_id); + BT_DRV_TRACE(1,"rxcount :%x",*(uint16_t *)(EM_BT_RXDESCCNT_ADDR+link_id*BT_EM_SIZE)); + } + } + btdrv_dump_mem(bt_dump_mem_start, bt_dump_len_max, BT_SUB_SYS_TYPE); + //btdrv_dump_mem(em_dump_area_1_start, em_area_1_len_max, BT_EM_AREA_1_TYPE); + btdrv_dump_mem(em_dump_area_2_start, em_area_2_len_max, BT_EM_AREA_2_TYPE); + //btdrv_dump_mem(mcu_dump_mem_start, mcu_dump_len_max, MCU_SYS_TYPE); + } +} + +uint8_t bt_drv_reg_op_get_tx_pwr(uint16_t connHandle) +{ + uint8_t idx; + uint16_t localVal; + uint8_t tx_pwr = 0; + + idx = btdrv_conhdl_to_linkid(connHandle); + + if (btdrv_is_link_index_valid(idx)) + { + localVal = BT_DRIVER_GET_U16_REG_VAL(EM_BT_PWRCNTL_ADDR + idx * BT_EM_SIZE); + tx_pwr = ((localVal & ((uint16_t)0x000000FF)) >> 0); + } + + return tx_pwr; +} + +void bt_drv_reg_op_set_tx_pwr(uint16_t connHandle, uint8_t txpwr) +{ + BT_DRV_REG_OP_ENTER(); + + uint8_t idx = btdrv_conhdl_to_linkid(connHandle); + + if (btdrv_is_link_index_valid(idx)) + { + BT_DRIVER_PUT_U16_REG_VAL(EM_BT_PWRCNTL_ADDR + idx * BT_EM_SIZE, + (BT_DRIVER_GET_U16_REG_VAL(EM_BT_PWRCNTL_ADDR + idx * BT_EM_SIZE) & ~((uint16_t)0x000000FF)) | ((uint16_t)txpwr << 0)); + } + + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_fix_tx_pwr(uint16_t connHandle) +{ + BT_DRV_REG_OP_ENTER(); + bt_drv_reg_op_set_tx_pwr(connHandle, LBRT_TX_PWR_FIX); + BT_DRV_REG_OP_EXIT(); +} + +//#define __ACCESS_MODE_ADJUST_GAIN__ +//#define __SWAGC_MODE_ADJUST_GAIN__ +#define __REBOOT_PAIRING_MODE_ADJUST_GAIN__ + +void bt_drv_reg_op_set_accessible_mode(uint8_t mode) +{ +} + +void bt_drv_reg_op_set_swagc_mode(uint8_t mode) +{ +} + +void bt_drv_reg_op_set_reboot_pairing_mode(uint8_t mode) +{ +} + +void bt_drv_reg_op_force_sco_retrans(bool enable) +{ +#ifdef __FORCE_SCO_MAX_RETX__ + BT_DRV_REG_OP_ENTER(); + if (enable) + { + BTDIGITAL_REG_SET_FIELD(0xd0220468,3,24,3); + } + else + { + BTDIGITAL_REG_SET_FIELD(0xd0220468,3,24,0); + } + BT_DRV_REG_OP_EXIT(); +#endif +} + +void bt_drv_reg_op_enable_pcm_tx_hw_cal(void) +{ + BT_DRV_REG_OP_ENTER(); + *(volatile uint32_t *)0xd0220468 |= 1<<22; + *(volatile uint32_t *)0x400000f0 |= 1; + BT_DRV_REG_OP_EXIT(); +} + + + +void bt_drv_reg_op_monitor_clk(void) +{ + BT_DRV_REG_OP_ENTER(); + uint32_t env0 =0; + uint32_t env1 =0; + uint32_t env2 =0; + + + if(ld_acl_env_addr) + { + env0 = *(uint32_t *)ld_acl_env_addr; + env1 = *(uint32_t *)(ld_acl_env_addr+4); + env1 = *(uint32_t *)(ld_acl_env_addr+8); + + } + + + if(env0 & bt_ram_start_addr) + { + env0 +=0x8c; + BT_DRV_TRACE(2,"BT_REG_OP:env0 clk off=%x %x",*(uint32_t *)env0,*(uint16_t *)EM_BT_CLKOFF0_ADDR | (*(uint16_t *)EM_BT_CLKOFF1_ADDR <<16)); + } + if(env1 & bt_ram_start_addr) + { + env1 +=0x8c; + BT_DRV_TRACE(2,"BT_REG_OP:env1 clk off=%x %x",*(uint32_t *)env1,*(uint16_t *)(EM_BT_CLKOFF0_ADDR+BT_EM_SIZE) | (*(uint16_t *)(EM_BT_CLKOFF1_ADDR+BT_EM_SIZE) <<16)); + } + if(env2 & bt_ram_start_addr) + { + env2 +=0x8c; + BT_DRV_TRACE(2,"BT_REG_OP:env2 clk off=%x %x",*(uint32_t *)env2,*(uint16_t *)(EM_BT_CLKOFF0_ADDR+BT_EM_SIZE*2)| (*(uint16_t *)(EM_BT_CLKOFF1_ADDR+BT_EM_SIZE*2) <<16)); + } + + BT_DRV_REG_OP_EXIT(); +} + +bool bt_drv_reg_op_read_rssi_in_dbm(uint16_t connHandle,rx_agc_t* rx_val) +{ +#ifdef BT_RSSI_MONITOR + BT_DRV_REG_OP_ENTER(); + + if (connHandle == 0xFFFF) + return false; + + if(hal_get_chip_metal_id()>=HAL_CHIP_METAL_ID_0) + { + uint8_t idx = btdrv_conhdl_to_linkid(connHandle); + /// Accumulated RSSI (to compute an average value) + int16_t rssi_acc = 0; + /// Counter of received packets used in RSSI average + uint8_t rssi_avg_cnt = 1; + rx_agc_t * rx_monitor_env = NULL; + + if (!btdrv_is_link_index_valid(idx)) + { + return false; + } + + //rx_monitor + if(rx_monitor_addr) + { + rx_monitor_env = (rx_agc_t*)rx_monitor_addr; + } + + if(rx_monitor_env != NULL) + { + for(int i=0; i< rssi_avg_cnt; i++) + { + rssi_acc += rx_monitor_env[idx].rssi; + } + rx_val->rssi = rssi_acc / rssi_avg_cnt; + rx_val->rxgain = rx_monitor_env[idx].rxgain; + } + } + + BT_DRV_REG_OP_EXIT(); + return true; +#else + return false; +#endif +} + +bool bt_drv_reg_op_read_ble_rssi_in_dbm(uint16_t connHandle,rx_agc_t* rx_val) +{ +#ifdef BT_RSSI_MONITOR + BT_DRV_REG_OP_ENTER(); + + if (connHandle == 0xFFFF) + return false; + + if(hal_get_chip_metal_id()>=HAL_CHIP_METAL_ID_0) + { + uint8_t idx = connHandle; + /// Accumulated RSSI (to compute an average value) + int16_t rssi_acc = 0; + /// Counter of received packets used in RSSI average + uint8_t rssi_avg_cnt = 1; + rx_agc_t * rx_monitor_env = NULL; + if(idx > 2) + return false;//invalid idx + + //rx_monitor + + if(ble_rx_monitor_addr) + { + rx_monitor_env = (rx_agc_t*)ble_rx_monitor_addr; + } + + if(rx_monitor_env != NULL) + { + for(int i=0; i< rssi_avg_cnt; i++) + { + rssi_acc += rx_monitor_env[idx].rssi; + } + rx_val->rssi = rssi_acc / rssi_avg_cnt; + rx_val->rxgain = rx_monitor_env[idx].rxgain; + } + } + + BT_DRV_REG_OP_EXIT(); + return true; +#else + return false; +#endif +} + +void bt_drv_reg_op_acl_silence(uint16_t connHandle, uint8_t silence) +{ + BT_DRV_REG_OP_ENTER(); + + uint8_t idx = btdrv_conhdl_to_linkid(connHandle); + + if (btdrv_is_link_index_valid(idx)) + { + BT_DRIVER_PUT_U16_REG_VAL(EM_BT_BT_EXT1_ADDR + idx * BT_EM_SIZE, + (BT_DRIVER_GET_U16_REG_VAL(EM_BT_BT_EXT1_ADDR + idx * BT_EM_SIZE) & ~((uint16_t)0x00008000)) | ((uint16_t)silence << 15)); + } + + BT_DRV_REG_OP_EXIT(); +} + +///sniffer connect information environment structure +struct ld_sniffer_connect_env +{ + /// + uint16_t bitoff; + /// + uint32_t clk_offset; + /// + uint8_t map[10]; + /// + uint32_t afh_instant; + /// + uint8_t afh_mode; + /// + uint8_t enc_mode; + /// + uint8_t ltk[16]; + /// + uint8_t role; +}; + +void bt_drv_reg_op_call_monitor(uint16_t connHandle, uint8_t tws_role) +{ +} + +void bt_drv_reg_op_lock_sniffer_sco_resync(void) +{ + +} + +void bt_drv_reg_op_unlock_sniffer_sco_resync(void) +{ + +} + +void bt_drv_reg_op_ibrt_retx_att_nb_set(uint8_t retx_nb) +{ + BT_DRV_REG_OP_ENTER(); + + int ret = -1; + uint32_t sco_evt_ptr = 0x0; + // TODO: [ld_sco_env address] based on CHIP id + + if(ld_sco_env_addr) + { + sco_evt_ptr = *(volatile uint32_t *)ld_sco_env_addr; + ret = 0; + } + + if(ret == 0) + { + uint32_t retx_ptr=0x0; + if(sco_evt_ptr !=0) + { + //offsetof(struct ea_elt_tag, env) + sizeof(struct ld_sco_evt_params) + retx_ptr =sco_evt_ptr+0x44; + } + else + { + BT_DRV_TRACE(0,"BT_REG_OP:Error, ld_sco_env[0].evt ==NULL"); + ret = -2; + } + + if(ret == 0) + { + *(volatile uint8_t *)retx_ptr = retx_nb; + } + } + + BT_DRV_TRACE(3,"BT_REG_OP:%s,ret=%d,retx nb=%d",__func__,ret,retx_nb); + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_acl_tx_type_set(uint16_t hciHandle, uint8_t slot_sel) +{ + uint32_t lc_ptr=0; + uint32_t acl_par_ptr = 0; + uint32_t packet_type_addr = 0; + //lc_env and ld_acl_env + + if(lc_env_addr) + { + lc_ptr = *(uint32_t *)(lc_env_addr+(hciHandle-0x80)*4); + } + + if(ld_acl_env_addr) + { + acl_par_ptr = *(uint32_t *)(ld_acl_env_addr+(hciHandle-0x80)*4); + } + + //sanity check + if(lc_ptr == 0) + { + return; + } + else + { + packet_type_addr = (uint32_t)(acl_par_ptr+176); + BT_DRV_TRACE(3,"BT_REG_OP:%s hdl=0x%x packet_types=0x%x",__func__,hciHandle, *(uint16_t *)(packet_type_addr)); + BT_DRV_TRACE(2,"BT_REG_OP:lc_ptr 0x%x, acl_par_ptr 0x%x",lc_ptr,acl_par_ptr); + uint16_t edr_type = 0; + if(slot_sel == USE_1_SLOT_PACKET) + { +#if defined(__3M_PACK__) + edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX) | (1 << DH1_3_IDX); +#else + edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX); +#endif + } + else if(slot_sel == USE_3_SLOT_PACKET) + { +#if defined(__3M_PACK__) + edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX) | (1 << DH1_3_IDX) | \ + (1 << DH3_2_IDX) |(1 << DH3_3_IDX); +#else + edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX) | (1 << DH3_2_IDX); +#endif + } + else if(slot_sel == USE_5_SLOT_PACKET) + { +#if defined(__3M_PACK__) + edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX) | (1 << DH1_3_IDX) | \ + (1 << DH3_2_IDX) |(1 << DH3_3_IDX) |(1 << DH5_2_IDX) | (1 << DH5_3_IDX); +#else + edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX) | (1 << DH3_2_IDX)|(1 << DH5_2_IDX); +#endif + } + *(uint16_t *)(packet_type_addr) = ((edr_type<<8)|(*(uint16_t *)(packet_type_addr)&0xff)); + + BT_DRV_TRACE(1,"BT_REG_OP:After op,packet_types 0x%x",*(uint16_t *)(packet_type_addr)); + } +} + +void bt_drv_reg_op_acl_tx_type_trace(uint16_t hciHandle) +{ + uint32_t acl_par_ptr = 0; + uint32_t packet_type_addr = 0; + //ld_acl_env + + if(ld_acl_env_addr) + { + acl_par_ptr = *(uint32_t *)(ld_acl_env_addr+(hciHandle-0x80)*4); + } + + //sanity check + if(acl_par_ptr == 0) + { + return; + } + else + { + packet_type_addr = (uint32_t)(acl_par_ptr+176); + BT_DRV_TRACE(1,"BT_REG_OP:tx packet_types=0x%x",*(uint16_t *)(packet_type_addr)); + } +} + +uint8_t bt_drv_reg_op_acl_tx_type_get(uint16_t hciHandle, uint8_t* br_type, uint8_t* edr_type) +{ + uint8_t status = 0xff; + uint32_t lc_ptr=0; + uint32_t acl_par_ptr = 0; + uint32_t packet_type_addr = 0; + + + if(lc_env_addr) + { + lc_ptr = *(uint32_t *)(lc_env_addr+(hciHandle-0x80)*4); + } + + if(ld_acl_env_addr) + { + acl_par_ptr = *(uint32_t *)(ld_acl_env_addr+(hciHandle-0x80)*4); + } + + + //sanity check + if(lc_ptr == 0) + { + BT_DRV_TRACE(2,"BT_REG_OP:%s hdl=0x%x,lc_env_ptr = NULL",__func__,hciHandle); + } + else + { + packet_type_addr = (uint32_t)(acl_par_ptr+176); + uint16_t packet_type = *(uint16_t *)(packet_type_addr); + if(br_type) + { + *br_type = packet_type&0xff; + } + if(edr_type) + { + *br_type = (packet_type>>8)&0xff; + } + status = 0; + BT_DRV_TRACE(3,"BT_REG_OP:%s hdl=0x%x packet_types=0x%x",__func__,hciHandle, packet_type); + } + + return status; +} + +uint16_t em_bt_bitoff_getf(int elt_idx) +{ + uint16_t localVal = BTDIGITAL_BT_EM(EM_BT_BITOFF_ADDR + elt_idx * BT_EM_SIZE); + ASSERT_ERR((localVal & ~((uint16_t)0x000003FF)) == 0); + return (localVal >> 0); +} + +void em_bt_bitoff_setf(int elt_idx, uint16_t bitoff) +{ + ASSERT_ERR((((uint16_t)bitoff << 0) & ~((uint16_t)0x000003FF)) == 0); + BTDIGITAL_EM_BT_WR(EM_BT_BITOFF_ADDR + elt_idx * BT_EM_SIZE, (uint16_t)bitoff << 0); +} + +void em_bt_clkoff0_setf(int elt_idx, uint16_t clkoff0) +{ + ASSERT_ERR((((uint16_t)clkoff0 << 0) & ~((uint16_t)0x0000FFFF)) == 0); + BTDIGITAL_EM_BT_WR(EM_BT_CLKOFF0_ADDR + elt_idx * BT_EM_SIZE, (uint16_t)clkoff0 << 0); +} + +uint16_t em_bt_clkoff0_getf(int elt_idx) +{ + uint16_t localVal = BTDIGITAL_BT_EM(EM_BT_CLKOFF0_ADDR + elt_idx * BT_EM_SIZE); + ASSERT_ERR((localVal & ~((uint16_t)0x0000FFFF)) == 0); + return (localVal >> 0); +} +void em_bt_clkoff1_setf(int elt_idx, uint16_t clkoff1) +{ + ASSERT_ERR((((uint16_t)clkoff1 << 0) & ~((uint16_t)0x000007FF)) == 0); + BTDIGITAL_EM_BT_WR(EM_BT_CLKOFF1_ADDR + elt_idx * BT_EM_SIZE, (uint16_t)clkoff1 << 0); +} + +uint16_t em_bt_clkoff1_getf(int elt_idx) +{ + uint16_t localVal = BTDIGITAL_BT_EM(EM_BT_CLKOFF1_ADDR + elt_idx * BT_EM_SIZE); + ASSERT_ERR((localVal & ~((uint16_t)0x000007FF)) == 0); + return (localVal >> 0); +} + +void em_bt_wincntl_pack(int elt_idx, uint8_t rxwide, uint16_t rxwinsz) +{ + ASSERT_ERR((((uint16_t)rxwide << 15) & ~((uint16_t)0x00008000)) == 0); + ASSERT_ERR((((uint16_t)rxwinsz << 0) & ~((uint16_t)0x00000FFF)) == 0); + BTDIGITAL_EM_BT_WR(EM_BT_WINCNTL_ADDR + elt_idx * BT_EM_SIZE, ((uint16_t)rxwide << 15) | ((uint16_t)rxwinsz << 0)); +} + +void bt_drv_reg_op_update_sniffer_bitoffset(uint16_t mobile_conhdl,uint16_t master_conhdl) +{ +} + +void bt_drv_reg_op_modify_bitoff_timer(uint16_t time_out) +{ +} + +void bt_drv_reg_op_cs_monitor(void) +{ + uint32_t addr; + addr = BT_EM_ADDR_BASE+0x1e; + BT_DRV_TRACE(0,"BT_REG_OP:AFH 0:"); + DUMP8("%02x ",(uint8_t *)addr,10); + addr = BT_EM_ADDR_BASE + 0x1e + 110; + BT_DRV_TRACE(0,"AFH 1:"); + DUMP8("%02x ",(uint8_t *)addr,10); + addr = BT_EM_ADDR_BASE + 0x1e + 220; + BT_DRV_TRACE(0,"AFH 2:"); + DUMP8("%02x ",(uint8_t *)addr,10); + uint32_t tmp1,tmp2,tmp3; + tmp1 = BT_EM_ADDR_BASE+0x8; + tmp2 = BT_EM_ADDR_BASE+0x8+110; + tmp3 = BT_EM_ADDR_BASE+0x8+220; + BT_DRV_TRACE(3,"AFH EN:%x %x %x ",*(uint16_t *)tmp1,*(uint16_t *)tmp2,*(uint16_t *)tmp3); + tmp1 = BT_EM_ADDR_BASE+0x28; + tmp2 = BT_EM_ADDR_BASE+0x28+110; + tmp3 = BT_EM_ADDR_BASE+0x28+220; + BT_DRV_TRACE(3,"AFH ch num:%x %x %x ",*(uint16_t *)tmp1,*(uint16_t *)tmp2,*(uint16_t *)tmp3); + + tmp1 = BT_EM_ADDR_BASE+0x4; + tmp2 = BT_EM_ADDR_BASE+0x4 + 110; + tmp3 = BT_EM_ADDR_BASE+0x4 + 220; + BT_DRV_TRACE(3,"clk off:%x %x %x ",*(uint32_t *)tmp1,*(uint32_t *)tmp2,*(uint32_t *)tmp3); + + tmp1 = BT_EM_ADDR_BASE+0x2; + tmp2 = BT_EM_ADDR_BASE+0x2+110; + tmp3 = BT_EM_ADDR_BASE+0x2+220; + BT_DRV_TRACE(3,"bitoff:%x %x %x ",*(uint16_t *)tmp1,*(uint16_t *)tmp2,*(uint16_t *)tmp3); + +} + +void bt_drv_reg_op_ble_llm_substate_hacker(void) +{ + +} + +bool bt_drv_reg_op_check_esco_acl_sniff_conflict(uint16_t hciHandle) +{ + return false; +} + +void bt_drv_reg_op_esco_acl_sniff_delay_cal(uint16_t hciHandle,bool enable) +{ +} + +uint8_t bt_drv_reg_op_get_role(uint8_t linkid) +{ + uint32_t lc_evt_ptr=0; + uint32_t role_ptr = 0; + + if(lc_env_addr) + { + lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr+linkid*4);//lc_env + } + + if(lc_evt_ptr !=0) + { + role_ptr = lc_evt_ptr+0x40; + } + else + { + BT_DRV_TRACE(1,"BT_REG_OP:ERROR LINKID =%x",linkid); + return 0xFF; + } + return *(uint8_t *)role_ptr; +} + +void bt_drv_reg_op_set_tpoll(uint8_t linkid,uint16_t poll_interval) +{ + uint32_t acl_evt_ptr = 0x0; + uint32_t poll_addr; + + + if(ld_acl_env_addr) + { + acl_evt_ptr = *(uint32_t *)(ld_acl_env_addr+linkid*4); + } + + + + if (acl_evt_ptr != 0) + { + poll_addr = acl_evt_ptr + 0xb8; + *(uint16_t *)poll_addr = poll_interval; + } + else + { + BT_DRV_TRACE(1,"BT_REG_OP:ERROR LINK ID FOR TPOLL %x", linkid); + } +} + +int8_t bt_drv_reg_op_rssi_correction(int8_t rssi) +{ +#ifdef __HW_AGC__ + if(hal_get_chip_metal_id()>=HAL_CHIP_METAL_ID_0) + { + //the rssi is already corrected + return rssi; + } +#endif + + return rssi; +} + +void bt_drv_reg_op_set_music_link(uint8_t link_id) +{ + //dbg_bt_setting.music_playing_link + if(dbg_bt_setting_addr) + { + *(uint8_t *)(dbg_bt_setting_addr+0x10) = link_id; + } + +} + +void bt_drv_reg_op_set_music_link_duration_extra(uint8_t slot) +{ + if(dbg_bt_setting_addr) + { + *(uint32_t *)(dbg_bt_setting_addr+0x14) = slot*625; + } +} + + +void bt_drv_reg_op_set_hwagc_read_en(uint8_t en) +{ + +} +uint32_t bt_drv_reg_op_get_reconnecting_flag() +{ + uint32_t ret = 0; + + if(reconnecting_flag_addr) + { + ret = *(uint32_t *)reconnecting_flag_addr; + } + return ret; +} + +void bt_drv_reg_op_set_reconnecting_flag() +{ + + if(reconnecting_flag_addr) + { + *(uint32_t *)reconnecting_flag_addr = 1; + } + +} + +void bt_drv_reg_op_clear_reconnecting_flag() +{ + + if(reconnecting_flag_addr) + { + *(uint32_t *)reconnecting_flag_addr = 0; + } +} + +void bt_drv_reg_op_music_link_config(uint16_t active_link,uint8_t active_role,uint16_t inactive_link,uint8_t inactive_role) +{ + BT_DRV_TRACE(4,"BT_REG_OP:bt_drv_reg_op_music_link_config %x %d %x %d",active_link,active_role,inactive_link,inactive_role); + if (active_role == 0) //MASTER + { + bt_drv_reg_op_set_tpoll(active_link-0x80, 0x10); + if (inactive_role == 0) + { + bt_drv_reg_op_set_tpoll(inactive_link-0x80, 0x40); + } + } + else + { + bt_drv_reg_op_set_music_link(active_link-0x80); + bt_drv_reg_op_set_music_link_duration_extra(11); + if (inactive_role == 0) + { + bt_drv_reg_op_set_tpoll(inactive_link-0x80, 0x40); + } + } +} + +bool bt_drv_reg_op_check_bt_controller_state(void) +{ + bool ret=true; + BT_DRV_REG_OP_ENTER(); + if(hal_sysfreq_get() <= HAL_CMU_FREQ_32K) + return ret; + + + if((BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +0)==0x00) + &&(BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +8)==MIC_BUFF_addr)) + ret = true; + else + ret = false; + + if (false == ret) + { + BT_DRV_TRACE(0,"controller dead!!!"); + btdrv_trigger_coredump(); + } + + BT_DRV_REG_OP_EXIT(); + return ret; +} + +void bt_drv_reg_op_piconet_clk_offset_get(uint16_t connHandle, int32_t *clock_offset, uint16_t *bit_offset) +{ + uint8_t index = 0; + uint32_t clock_offset_raw = 0; + + BT_DRV_REG_OP_ENTER(); + if(hal_get_chip_metal_id()>=HAL_CHIP_METAL_ID_0) + { + if (connHandle) + { + index = btdrv_conhdl_to_linkid(connHandle); + + if (btdrv_is_link_index_valid(index)) + { + *bit_offset = em_bt_bitoff_getf(index); + clock_offset_raw = (em_bt_clkoff1_getf(index) << 16) | em_bt_clkoff0_getf(index); + *clock_offset = clock_offset_raw; + *clock_offset = (*clock_offset << 5) >> 5; + } + else + { + *bit_offset = 0; + *clock_offset = 0; + } + } + else + { + *bit_offset = 0; + *clock_offset = 0; + } + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_afh_env_reset(void) +{ + BT_DRV_REG_OP_ENTER(); + int ret = -1; + uint32_t ld_afh_env_addr = 0x0; + + if(hal_get_chip_metal_id()==HAL_CHIP_METAL_ID_0) + { + ld_afh_env_addr = ld_env_addr+0x198; + ret = 0; + + if(ret == 0) + { + struct ld_afh_env* ld_afh_env = (struct ld_afh_env*)ld_afh_env_addr; + if(ld_afh_env) + { + BT_DRV_TRACE(0,"BT_REG_OP:reset ld_afh_env"); + ld_afh_env->rf_rssi_interf_thr = BT_AFH_RSSI_INTERF_THR; + ld_afh_env->afh_update_period = BT_AFH_UPDATE_PERIOD; + ld_afh_env->afh_access_valid_to = BT_AFH_ASSESS_VALID_TO; + ld_afh_env->afh_reaccess_to = BT_AFH_REASSESS_TO; + ld_afh_env->afh_access_count_max = BT_AFH_ASSESS_COUNT_MAX; + ld_afh_env->afh_access_count_thr_good = BT_AFH_ASSESS_COUNT_THR_GOOD; + ld_afh_env->afh_access_count_thr_bad = BT_AFH_ASSESS_COUNT_THR_BAD; + ld_afh_env->afh_access_count_min = BT_AFH_ASSESS_COUNT_MIN; + } + } + } + + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_dma_tc_clkcnt_get(uint32_t *btclk, uint16_t *btcnt) +{ + BT_DRV_REG_OP_ENTER(); + *btclk = *((volatile uint32_t*)0xd02201fc); + *btcnt = *((volatile uint32_t*)0xd02201f8); + BT_DRV_REG_OP_EXIT(); +} + +void em_bt_bt_ext1_tx_silence_setf(int elt_idx, uint8_t txsilence) +{ + ASSERT_ERR((((uint16_t)txsilence << 15) & ~((uint16_t)0x00008000)) == 0); + BTDIGITAL_EM_BT_WR(EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE, + (BTDIGITAL_BT_EM(EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE) & ~((uint16_t)0x00008000)) | ((uint16_t)txsilence << 15)); +} + +void em_bt_bt_ext1_bw_2m_setf(int elt_idx, uint8_t bw2m) +{ + ASSERT_ERR((((uint16_t)bw2m << 11) & ~((uint16_t)0x00000800)) == 0); + BTDIGITAL_EM_BT_WR(EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE, + (BTDIGITAL_BT_EM(EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE) & ~((uint16_t)0x00000800)) | ((uint16_t)bw2m << 11)); +} + +void em_bt_bt_ext1_sco_tx_silence_setf(int elt_idx, uint8_t scotxsilence) +{ + ASSERT_ERR((((uint16_t)scotxsilence << 13) & ~((uint16_t)0x00002000)) == 0); + BTDIGITAL_EM_BT_WR(EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE, + (BTDIGITAL_BT_EM(EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE) & ~((uint16_t)0x00002000)) | ((uint16_t)scotxsilence << 13)); +} + +void bt_drv_reg_op_acl_tx_silence(uint16_t connHandle, uint8_t on) +{ + return; + BT_DRV_REG_OP_ENTER(); + uint8_t idx = btdrv_conhdl_to_linkid(connHandle); + BT_DRV_TRACE(2,"BT_REG_OP:BT ACL tx silence idx=%d,on=%d\n",idx,on); + + if (btdrv_is_link_index_valid(idx)) + { + if(TX_SILENCE_ON == on) + { + //config ACL silence cs + em_bt_bt_ext1_tx_silence_setf(idx, TX_SILENCE_ON); + if(hal_get_chip_metal_id()>= HAL_CHIP_METAL_ID_1) + { + //config SCO silence cs + em_bt_bt_ext1_sco_tx_silence_setf(idx, TX_SILENCE_ON); + //select ACL silence + BTDIGITAL_REG_SET_FIELD(0xd02204a8,3,2,2); + } + } + else if(TX_SILENCE_OFF == on) + { + //config ACL silence cs + em_bt_bt_ext1_tx_silence_setf(idx, TX_SILENCE_OFF); + if(hal_get_chip_metal_id()>= HAL_CHIP_METAL_ID_1) + { + //config SCO silence cs + em_bt_bt_ext1_sco_tx_silence_setf(idx, TX_SILENCE_OFF); + //select ACL silence + BTDIGITAL_REG_SET_FIELD(0xd02204a8,3,2,3); + } + } + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_acl_tx_silence_clear(uint16_t connHandle) +{ + uint8_t idx = btdrv_conhdl_to_linkid(connHandle); + + BT_DRV_TRACE(1,"BT_REG_OP:ACL tx silence clear idx=%d\n",idx); + + if (btdrv_is_link_index_valid(idx)) + { + em_bt_bt_ext1_tx_silence_setf(idx, TX_SILENCE_OFF); + if(hal_get_chip_metal_id()>= HAL_CHIP_METAL_ID_1) + { + //config SCO silence cs + em_bt_bt_ext1_sco_tx_silence_setf(idx, TX_SILENCE_OFF); + //select ACL silence + BTDIGITAL_REG_SET_FIELD(0xd02204a8,3,2,3); + } + } + bt_drv_reg_op_resume_fast_ack_with_mobile(); +} + +void bt_drv_reg_op_sw_seq_filter(uint16_t connHandle) +{ +} + +void bt_drv_reg_op_pcm_set(uint8_t en) +{ + if(hal_get_chip_metal_id()>=HAL_CHIP_METAL_ID_1) + { + if(en) + *(volatile unsigned int *)(0xd02204a8) &= 0xffffffdf; + else + *(volatile unsigned int *)(0xd02204a8) |= 1<<5; + } +} +uint8_t bt_drv_reg_op_pcm_get() +{ + uint8_t ret = 1; + if(hal_get_chip_metal_id()>=HAL_CHIP_METAL_ID_1) + { + ret = (*(volatile unsigned int *)(0xd02204a8) &0x00000020)>>5; + } + return ~ret; +} +void bt_drv_reg_op_clear_skip_flag() +{ +} + +void bt_drv_reg_op_clean_flags_of_ble_and_sco(void) +{ + if(hal_get_chip_metal_id()==HAL_CHIP_METAL_ID_0) + { + //0xc0006a18,////sco_find_sync_flag + //0xc000699c,///ble_sco_need_move_flag + //0xc000693c,///prev_conflict_type_record + //0xc000099f,///anchor_resume_flag + ASSERT(*(uint32_t *)0xc0006a14 ==0xc0006a18,"ERROR 2300pt1 sco_find_sync_flag!"); + ASSERT(*(uint32_t *)0xc0006998 ==0xc000699c,"ERROR 2300pt1 ble_sco_need_move_flag!"); + ASSERT(*(uint32_t *)0xc0006938 ==0xc000693c,"ERROR 2300pt1 prev_conflict_type_record!"); + //BT_DRV_TRACE(4,"0xc0006a18=%x,0xc000699c=%x,0xc000693c=%x,0xc000099f=%x\n",*(volatile uint32_t *)0xc0006a18,*(volatile uint32_t *)0xc000699c,*(volatile uint32_t *)0xc000693c,*(volatile uint32_t *)0xc000099f); + *(volatile uint32_t *)0xc0006a18 = 0; + *(volatile uint32_t *)0xc0006a88 = 0; + *(volatile uint32_t *)0xc000693c = 0; + *(volatile uint32_t *)0xc000099f = 0; + } +} + +const uint8_t msbc_mute_patten[]= +{ + 0x01,0x38, + 0xad, 0x0, 0x0, 0xc5, 0x0, 0x0, 0x0, 0x0, + 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, + 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77, + 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, + 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77, 0x6d, + 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, + 0x6d, 0xdd, 0xb6, 0xdb, 0x77, 0x6d, 0xb6, + 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6c, + 0x00 +}; +#define SCO_TX_FIFO_BASE (0xd0210000) + +#if defined(CVSD_BYPASS) +#define SCO_TX_MUTE_PATTERN (0x5555) +#else +#define SCO_TX_MUTE_PATTERN (0x0000) +#endif + +void bt_drv_reg_op_sco_txfifo_reset(uint16_t codec_id) +{ + uint32_t reg_val = BTDIGITAL_REG(0xd0220148); + uint32_t reg_offset0, reg_offset1; + uint16_t *patten_p = (uint16_t *)msbc_mute_patten; + + reg_offset0 = (reg_val & 0xffff); + reg_offset1 = (reg_val >> 16) & 0xffff; + + if (codec_id == 2) + { + for (uint8_t i=0; i<60; i+=2) + { + BTDIGITAL_BT_EM(SCO_TX_FIFO_BASE+reg_offset0+i) = *patten_p; + BTDIGITAL_BT_EM(SCO_TX_FIFO_BASE+reg_offset1+i) = *patten_p; + patten_p++; + } + } + else + { + for (uint8_t i=0; i<120; i+=2) + { + BTDIGITAL_BT_EM(SCO_TX_FIFO_BASE+reg_offset0+i) = SCO_TX_MUTE_PATTERN; + BTDIGITAL_BT_EM(SCO_TX_FIFO_BASE+reg_offset1+i) = SCO_TX_MUTE_PATTERN; + } + } +} + +/***************************************************************************** + Prototype : btdrv_set_tws_acl_poll_interval + Description : in ibrt mode, set tws acl poll interval + Input : uint16_t poll_interval + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/19 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void btdrv_reg_op_set_private_tws_poll_interval(uint16_t poll_interval, uint16_t poll_interval_in_sco) +{ + BT_DRV_TRACE(2,"BT_REG_OP:Set private tws interval,acl interv=%d,acl interv insco =%d", \ + poll_interval,poll_interval_in_sco); + + if(dbg_bt_setting_addr) + { + *(volatile uint16_t *)(dbg_bt_setting_addr+0x40) = poll_interval; + *(volatile uint16_t *)(dbg_bt_setting_addr+0x42) = poll_interval_in_sco; + } + + +} + +void btdrv_reg_op_set_tws_link_duration(uint8_t slot_num) +{ + BT_DRV_REG_OP_ENTER(); + //dbg_setting address + uint32_t op_addr = 0; + + + if(dbg_bt_setting_addr) + { + op_addr = dbg_bt_setting_addr; + } + + + if(op_addr != 0) + { + //uint16_t acl_slot = dbg_setting->acl_slot_in_snoop_mode; + uint16_t val = *(volatile uint16_t *)(op_addr+0x44); + val&=0xff00; + val|= slot_num; + *(volatile uint16_t *)(op_addr+0x44) = val; + BT_DRV_TRACE(1,"BT_REG_OP:Set private tws link duration,val=%d",*((volatile uint16_t*)(op_addr+0x44))&0xff); + } + BT_DRV_REG_OP_EXIT(); +} + +void btdrv_reg_op_enable_private_tws_schedule(bool enable) +{ + BT_DRV_REG_OP_ENTER(); + //sniffer_env + uint32_t op_addr = 0; + + if(sniffer_env_addr) + { + op_addr = sniffer_env_addr; + } + + if(op_addr!=0) + { + //sniffer_env.acl_switch_flag.in_process + uint16_t val = *((volatile uint16_t*)(op_addr+0x7e)); + val&=0xff; + if(enable) + { + val|=1<<8; + } + *((volatile uint16_t*)(op_addr+0x7e)) = val; + BT_DRV_TRACE(1,"BT_REG_OP:Enable private tws function,flag=%d", (*((volatile uint16_t*)(op_addr+0x7e)))>>8); + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_decrease_tx_pwr_when_reconnect(bool enable) +{ + + if(enable) + { + BT_DRV_TRACE(0,"BT_REG_OP:Decrese tx pwr"); + //drease defualt TX pwr + BTDIGITAL_REG(0xd0350300) = 0x33; + } + else + { + BT_DRV_TRACE(0,"BT_REG_OP:Increase tx pwr"); + //resume defualt TX pwr + BTDIGITAL_REG(0xd0350300) = 0x11; + } +} +/* + rwip_heap_env + from addr=0xc00027b8 left_length=6K + rwip_heap_non_ret + from addr=0xc00052b8 left_length=1.5K +*/ +void bt_drv_reg_op_controller_mem_log_config(void) +{ + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + uint32_t each_log_length = 0x200;//512Byte + uint32_t lmp_mem_addr = 0xc00027b8+0x64;//lmp:each_log_length + uint32_t msg_mem_addr = lmp_mem_addr+each_log_length+0x64;//msg:each_log_length + uint32_t sta_mem_addr = msg_mem_addr+each_log_length+0x64;//sta:each_log_length + uint32_t sch_mem_addr = sta_mem_addr+each_log_length+0x64;//sch:each_log_length + uint32_t isr_mem_addr = sch_mem_addr+each_log_length+0x64;//isr:each_log_length + + //LMP_DUMP_TRACE + *(uint32_t *)g_mem_dump_ctrl_addr= each_log_length; //g_mem_dump_ctrl[0].len_max default:1024 + *(uint32_t *)(g_mem_dump_ctrl_addr+4) = lmp_mem_addr; //g_mem_dump_ctrl[0].start_addr + *(uint8_t *)(g_mem_dump_ctrl_addr+8) = 0x01; //g_mem_dump_ctrl[0].trace_enable + + //MSG_DUMP_TRACE + *(uint32_t *)(g_mem_dump_ctrl_addr+0xc) = each_log_length; //g_mem_dump_ctrl[1].len_max default:1024 + *(uint32_t *)(g_mem_dump_ctrl_addr+0x10) = msg_mem_addr; //g_mem_dump_ctrl[1].start_addr + *(uint8_t *)(g_mem_dump_ctrl_addr+0x14) = 0x01; //g_mem_dump_ctrl[1].trace_enable + + //STA_DUMP_TRACE + *(uint32_t *)(g_mem_dump_ctrl_addr+0x18) = each_log_length; //g_mem_dump_ctrl[2].len_max default:1024 + *(uint32_t *)(g_mem_dump_ctrl_addr+0x1c) = sta_mem_addr; //g_mem_dump_ctrl[2].start_addr + *(uint8_t *)(g_mem_dump_ctrl_addr+0x20) = 0x01; //g_mem_dump_ctrl[2].trace_enable + + //SCH_DUMP_TRACE + *(uint32_t *)(g_mem_dump_ctrl_addr+0x24) = each_log_length; //g_mem_dump_ctrl[3].len_max default:1024 + *(uint32_t *)(g_mem_dump_ctrl_addr+0x28) = sch_mem_addr; //g_mem_dump_ctrl[3].start_addr + *(uint8_t *)(g_mem_dump_ctrl_addr+0x2c) = 0x01; //g_mem_dump_ctrl[3].trace_enable + + //ISR_DUMP_TRACE + *(uint32_t *)(g_mem_dump_ctrl_addr+0x30) = each_log_length; //g_mem_dump_ctrl[4].len_max default:1024 + *(uint32_t *)(g_mem_dump_ctrl_addr+0x34) = isr_mem_addr; //g_mem_dump_ctrl[4].start_addr + *(uint8_t *)(g_mem_dump_ctrl_addr+0x38) = 0x01; //g_mem_dump_ctrl[4].trace_enable + } +} + +void bt_drv_reg_op_lm_nb_sync_hacker(uint8_t sco_status) +{ + BT_DRV_REG_OP_ENTER(); + //lm_nb_sync_active + uint32_t op_addr = 0; + + if(lm_nb_sync_active_addr) + { + op_addr = lm_nb_sync_active_addr; + } + + if(op_addr != 0) + { + uint8_t org_val = *(volatile uint8_t *)(op_addr); + //sanity check + if(org_val > 0xf0) + org_val = 0; + + if((sco_status == SNIFFER_SCO_STOP ||sco_status == SNIFFER_SCO_START|| + sco_status == SNIFFER_ACL_DISCONNECT_STOP_SCO) + && (org_val >= 0 && org_val <= 2 )) + { + if(sco_status == SNIFFER_SCO_STOP || + sco_status == SNIFFER_ACL_DISCONNECT_STOP_SCO) + { + if(org_val>0) + { + *(volatile uint8_t *)(op_addr) = org_val -1; + } + } + else if(sco_status == SNIFFER_SCO_START) + { + *(volatile uint8_t *)(op_addr) = org_val + 1; + } + BT_DRV_TRACE(3,"BT_REG_OP:modify lm_nb_sync org val=%d, modify val=%d, status=%d", + org_val,*(volatile uint8_t *)(op_addr), sco_status); + } + else + { + BT_DRV_TRACE(2,"BT_REG_OP:do not need modify lm_nb_sync val=%d, status=%d",org_val, sco_status); + } + } + BT_DRV_REG_OP_EXIT(); +} + +#define BT_FASTACK_ADDR 0xD0220468 +#define BT_SCO_TRIGGER_BYPASS_ADDR 0xD022046C +void bt_drv_reg_op_fastack_status_checker(uint16_t conhdl) +{ + BT_DRV_REG_OP_ENTER(); + + uint8_t elt_idx = btdrv_conhdl_to_linkid(conhdl); + + if (btdrv_is_link_index_valid(elt_idx)) + { + uint32_t fast_cs_addr = EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE; + + BT_DRV_TRACE(3,"BT_DRV_REG: fastack cs=0x%x,fast ack reg=0x%x,Seq filter by pass=0x%x", + *(volatile uint16_t *)(fast_cs_addr), //fa rx bit10,tx bit9 + *(volatile uint32_t *)(BT_FASTACK_ADDR),//fast ack reg bit22 + *(volatile uint32_t *)(BT_SCO_TRIGGER_BYPASS_ADDR));//seq bypass reg bit 18 + } + + bt_drv_reg_op_bt_info_checker(); + + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_clear_ibrt_snoop_status(void) +{ + BT_DRV_REG_OP_ENTER(); + + //sniffer_env.snoop_status + uint32_t op_addr = 0; + + if(sniffer_env_addr) + { + op_addr = sniffer_env_addr+0x84; + } + + if(op_addr!=0) + { + BT_DRV_TRACE(0,"BT_REG_OP:clear snoop_status"); + *(volatile uint8_t *)(op_addr) = 0; + } + //close fastack register + bt_drv_reg_op_fa_set(0); + //clear fastack cs + for(uint8_t idx=0; idx<3; idx++) + { + //fastack cs: rx bit10,tx bit9 + uint32_t fast_cs_addr = EM_BT_BT_EXT1_ADDR + idx * BT_EM_SIZE; + *(volatile uint16_t *)(fast_cs_addr)&=~0x600; + } + + BT_DRV_REG_OP_EXIT(); +} + +uint8_t bt_drv_reg_op_linkcntl_aclltaddr_getf(uint16_t conhdl) +{ + uint8_t elt_idx = btdrv_conhdl_to_linkid(conhdl); + + if (btdrv_is_link_index_valid(elt_idx)) + { + uint16_t localVal = BTDIGITAL_BT_EM(EM_BT_LINKCNTL_ADDR + elt_idx * BT_EM_SIZE); + return ((localVal & ((uint16_t)0x00000700)) >> 8); + } + else + { + return 0; + } +} + +uint8_t bt_drv_reg_op_sync_bt_param(uint8_t* param, uint16_t len) +{ + uint8_t status = 0xff; + BT_DRV_REG_OP_ENTER(); + //link_connect_bak + uint32_t op_addr = 0; + + + if(link_connect_bak_addr) + { + op_addr = link_connect_bak_addr; + } + + if(op_addr!=0) + { + BT_DRV_TRACE(1,"BT_REG_OP:sync bt param len=%d",len); + + memcpy((uint8_t *)(op_addr),param, len); + status = 0; + } + + BT_DRV_REG_OP_EXIT(); + return status; +} + +uint32_t bt_drv_reg_op_get_lc_env_ptr(uint16_t conhdl, uint8_t type) +{ + uint32_t lc_ptr = 0; + uint32_t op_ptr = 0; + BT_DRV_REG_OP_ENTER(); + + + + if(lc_env_addr) + { + lc_ptr = *(uint32_t *)(lc_env_addr+(conhdl-0x80)*4); + } + + BT_DRV_TRACE(3,"BT_REG_OP:lc_env_ptr =0x%x, conhdl=0x%x,type=%d",lc_ptr,conhdl,type); + + if(lc_ptr == 0) + return 0; + + switch(type) + { + case LC_LINK_TAG: + //link tag len=108 + op_ptr = lc_ptr; + break; + case LC_INFO_TAG: + op_ptr = lc_ptr +0x6c; + break; + case LC_ENC_TAG: + //enc tag len=166 + op_ptr = lc_ptr +0x196; + break; + case LC_AFH_TAG: + op_ptr = lc_ptr +0x26c; + break; + case LC_SP_TAG: + //link tag len=108 + op_ptr = lc_ptr +0x28c; + break; + case LC_EPR_TAG: + op_ptr = lc_ptr +0x2f8; + break; + case LC_EPC_TAG: + op_ptr = lc_ptr +0x2fc; + break; + default: + break; + } + + BT_DRV_REG_OP_EXIT(); + return op_ptr; +} + +#ifdef __BT_ONE_BRING_TWO__ +void bt_drv_reg_op_set_music_ongong_flag() +{ +} + +void bt_drv_reg_op_clear_music_ongong_flag() +{ +} +#endif +uint16_t bt_drv_reg_op_get_ble_conn_latency(uint16_t ble_conhdl) +{ + uint16_t curr_conn_latency = 0xffff; + return curr_conn_latency; +} +bool bt_drv_reg_op_set_ble_conn_latency(uint16_t ble_conhdl, uint16_t conn_latency) +{ + return false; +} + +void bt_drv_reg_op_write_private_public_key(uint8_t* private_key,uint8_t* public_key) +{ + uint8_t* lm_env_ptr = 0; + uint8_t* lm_private_key_ptr = 0; + uint8_t* lm_public_key_ptr = 0; + //lm_env + if(lm_env_addr) + { + lm_env_ptr = (uint8_t*)lm_env_addr; + } + else + { + return; + } + + lm_private_key_ptr = lm_env_ptr + 0x6c; + lm_public_key_ptr = lm_private_key_ptr + 0x18; + memcpy(lm_private_key_ptr,private_key,24); + memcpy(lm_public_key_ptr,public_key,48); + BT_DRV_TRACE(0,"private key"); + DUMP8("%02x",lm_private_key_ptr,24); + BT_DRV_TRACE(0,"public key"); + DUMP8("%02x",lm_public_key_ptr,48); + +} + +void bt_drv_reg_op_for_test_mode_disable(void) +{ + + if(dbg_bt_setting_addr) + { + *(volatile uint32_t *)(dbg_bt_setting_addr+0x64) &= ~(1<<8);////sw_seq_filter_en set 0 + *(volatile uint32_t *)(dbg_bt_setting_addr+0x64) &= ~(1<<0);////ecc_enable set 0 + *(volatile uint32_t *)(dbg_bt_setting_addr+0x1c) &= 0x00ffffff;////dbg_trace_level set 0 + } + + +} + +uint16_t bt_drv_reg_op_get_ibrt_sco_hdl(uint16_t acl_hdl) +{ + // FIXME + return acl_hdl|0x100; +} + +void bt_drv_reg_op_get_ibrt_address(uint8_t *addr) +{ + struct ld_device_info * mobile_device_info=0; + BT_DRV_REG_OP_ENTER(); + + if(sniffer_env_addr) + { + mobile_device_info = (struct ld_device_info *)(sniffer_env_addr+4); + } + + if(mobile_device_info) + { + if (addr != NULL) + { + memcpy(addr, (uint8_t *)mobile_device_info->bd_addr.addr, 6); + BT_DRV_TRACE(0,"BT_REG_OP:get mobile address"); + DUMP8("%02x ",addr,6); + } + } + + BT_DRV_REG_OP_EXIT(); +} + + +void bt_drv_reg_op_set_tws_link_id(uint8_t link_id) +{ + //ASSERT(); + BT_DRV_TRACE(1,"set tws link id =%x",link_id); + ASSERT(link_id <3 || link_id == 0xff,"error tws link id set"); + if(hal_get_chip_metal_id()==HAL_CHIP_METAL_ID_1) + { + ASSERT(*(uint32_t *)0xc0006e28 == 0xc0006e2c,"PATCH ERROR!!"); + *(uint32_t *)0xc0006e2c = link_id; + } + else if(tws_link_id_addr) + { + if(link_id == 0xff) + { + link_id = 3; + } + *(uint8_t *)tws_link_id_addr = link_id; + } +} + +void bt_drv_reg_op_hack_max_slot(uint8_t link_id,uint8_t slot) +{ + uint32_t acl_evt_ptr = 0x0; + uint32_t slot_addr; + uint32_t stop_lantency_addr=0; + BT_DRV_TRACE(2,"hack slot id=%d,slot=%d",link_id,slot); + if(link_id>=3) + return; + + + if(ld_acl_env_addr) + { + acl_evt_ptr = *(uint32_t *)(ld_acl_env_addr+link_id*4); + } + + + + if(acl_evt_ptr) + { + slot_addr = acl_evt_ptr+0xc4; + stop_lantency_addr = acl_evt_ptr+0x18; + *(uint8_t *)slot_addr = slot; + *(uint8_t *)stop_lantency_addr = slot+3+(*(uint16_t *)(acl_evt_ptr+150)>128?1:0); + } +} + +void bt_drv_reg_op_rx_slot_stop_lantency_checker(void) +{ + uint32_t acl_evt_ptr = 0x0; + uint32_t slot_addr; + uint32_t stop_addr; + + + for(uint8_t i=0; i<3; i++) + { + + + if(ld_acl_env_addr) + { + acl_evt_ptr = *(uint32_t *)(ld_acl_env_addr+i*4); + } + + if(acl_evt_ptr) + { + slot_addr = acl_evt_ptr+0xc4; + stop_addr = acl_evt_ptr+0x18; + BT_DRV_TRACE(5,"id=%d,rx slot=%d stop=%d,acl_par: clk off 0x%x, bit off 0x%x",i,*(uint8_t *)slot_addr, + *(uint8_t *)stop_addr,*(uint32_t *)(acl_evt_ptr+140),*(uint16_t *)(acl_evt_ptr+150)); + } + } +} + +void bt_drv_reg_op_fa_set(uint8_t en) +{ + if(hal_get_chip_metal_id()>=HAL_CHIP_METAL_ID_1) + { + if(en) + { + *(uint32_t *)0xd0220468 |=0x00400000; + BT_DRV_TRACE(1,"%s", __func__); + } + else + { + *(uint32_t *)0xd0220468 &= ~0x00400000; + } + } +} + +//////return true means controller had received a data packet +bool bt_drv_reg_op_check_seq_pending_status(void) +{ + + if(pending_seq_error_link_addr) + { + return (*(uint8_t *)pending_seq_error_link_addr == 3); + } + else + { + return TRUE; + } +} + +///if the flag is not clear when disconnect happened call this function +void bt_drv_reg_op_clear_seq_pending_status(void) +{ + if(pending_seq_error_link_addr) + { + *(uint8_t *)pending_seq_error_link_addr = 3; + } + +} + + +void bt_drv_reg_op_rssi_checker(void) +{ + // BT_DRV_TRACE(1,"rssi thd=%x",*(uint32_t *)0xc00041e4); + + uint32_t acl_evt_ptr = 0x0; + uint32_t rssi_acc_addr; + uint32_t rssi_count_addr; + + + for(uint8_t i=0; i<3; i++) + { + + if(ld_acl_env_addr) + { + acl_evt_ptr = *(uint32_t *)(ld_acl_env_addr+i*4); + } + + if(acl_evt_ptr) + { + rssi_acc_addr = acl_evt_ptr+0xac; + rssi_count_addr = acl_evt_ptr+0xae; + BT_DRV_TRACE(3,"id=%d,rssi acc=%d count=%d",i,*(int16_t *)rssi_acc_addr,*(uint8_t *)rssi_count_addr); + } + + } + uint32_t lc_evt_ptr = 0x0; + uint32_t recv_addr; + + for(uint8_t i=0; i<3; i++) + { + if(lc_env_addr) + { + lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr+i*4);//lc_env + } + if(lc_evt_ptr) + { + recv_addr = lc_evt_ptr+0x60; + BT_DRV_TRACE(2,"id=%d,recv=%x",i,*(uint32_t *)recv_addr); + } + } +} + +void bt_drv_reg_op_set_link_policy(uint8_t linkid, uint8_t policy) +{ + BT_DRV_REG_OP_ENTER(); + uint32_t lc_evt_ptr = 0x0; + uint32_t policy_addr; + if(linkid>=0x3) + return; + + BT_DRV_TRACE(2,"REG_OP: set link=%d, policy=%d",linkid,policy); + + + if(lc_env_addr) + { + lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr+linkid*4);//lc_env + } + + if(lc_evt_ptr) + { + policy_addr = lc_evt_ptr+0x2c; + *(uint8_t *)policy_addr = policy; + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_voice_settings_set(uint16_t voice_settings) +{ + uint32_t voice_settings_addr = 0; + + + if(hci_env_addr) + { + voice_settings_addr = hci_env_addr+90; + } + + if(voice_settings_addr != 0) + { + BT_DRV_TRACE(2,"Fast_bt_init1:%s %d",__func__,voice_settings); + *(uint16_t *)voice_settings_addr = voice_settings; + } +} + +uint8_t bt_drv_reg_op_lmp_sco_hdl_get(uint16_t sco_handle) +{ + if (sco_handle == 0xffff) + { + return 0; + } + + if(hal_get_chip_metal_id()==HAL_CHIP_METAL_ID_1) + { + // uint32_t lc_sco_env_addr = 0xc000079c; + uint16_t sco_link_id = ((sco_handle >> 8) - 1); + uint32_t link_params_addr = *((uint32_t *)(lc_sco_env_addr + sco_link_id * 8)); + uint8_t sync_hdl = 0; + + if (sco_link_id > 2 || link_params_addr == 0) + { + return 0; + } + + sync_hdl = *((uint8_t *)(link_params_addr + 4)); + + return sync_hdl; + } + else + { + BT_DRV_TRACE(0,"BT_DRV:no need to get sco hdl\n"); + } + + return 0; +} + +bool bt_drv_reg_op_lmp_sco_hdl_set(uint16_t sco_handle, uint8_t lmp_hdl) +{ + if (sco_handle == 0xffff || lmp_hdl == 0x00) + { + return false; + } + + if(hal_get_chip_metal_id()==HAL_CHIP_METAL_ID_1) + { + // uint32_t lc_sco_env_addr = 0xc000079c; + uint16_t sco_link_id = ((sco_handle >> 8) - 1); + uint32_t link_params_addr = *((uint32_t *)(lc_sco_env_addr + sco_link_id * 8)); + uint8_t *p_sync_hdl = 0; + + if (sco_link_id > 2 || link_params_addr == 0) + { + return false; + } + + p_sync_hdl = (uint8_t *)(link_params_addr + 4); + + *p_sync_hdl = lmp_hdl; + return true; + } + else + { + BT_DRV_TRACE(0,"BT_DRV:no need to set sco hdl\n"); + } + + return false; +} + +void bt_drv_reg_op_host_buff_and_flow_ctl_set +(uint16_t acl_pkt_len, uint16_t acl_pkt_num,uint16_t sync_pkt_len, uint16_t sync_pkt_num,bool flow_ctl_en) +{ + uint32_t acl_pkt_len_addr = 0; + uint32_t acl_pkt_num_addr = 0; + uint32_t sync_pkt_len_addr = 0; + uint32_t sync_pkt_num_addr = 0; + uint32_t flow_ctl_addr = 0; + + + if(hci_fc_env_addr) + { + flow_ctl_addr = hci_fc_env_addr; + } + + if(flow_ctl_addr != 0) + { + //hci_fc_env.host_set.acl_pkt_len + acl_pkt_len_addr = flow_ctl_addr+2; + //hci_fc_env.host_set.acl_pkt_num + acl_pkt_num_addr = flow_ctl_addr+4; + //hci_fc_env.host_set.sync_pkt_len; + sync_pkt_len_addr = flow_ctl_addr+9; + //hci_fc_env.host_set.sync_pkt_nb; + sync_pkt_num_addr = flow_ctl_addr+10; + + BT_DRV_TRACE(6,"Fast_bt_init2:%s,acl len=%x,acl num=%x,sync len=%x sync num=%x,fl_ctl=%d", + __func__,acl_pkt_len,acl_pkt_num,sync_pkt_len,sync_pkt_num,flow_ctl_en); + + *(uint8_t *)flow_ctl_addr = flow_ctl_en; + *(uint16_t *)acl_pkt_len_addr = acl_pkt_len; + *(uint16_t *)acl_pkt_num_addr = acl_pkt_num; + *(uint8_t *)sync_pkt_len_addr = sync_pkt_len; + *(uint16_t *)sync_pkt_num_addr = sync_pkt_num; + } +} + +void bt_drv_reg_op_page_to_set(uint16_t page_to) +{ + BT_DRV_REG_OP_ENTER(); + uint32_t page_to_addr = 0; + + + if(lm_env_addr) + { + page_to_addr = lm_env_addr + 20; + } + + if(page_to_addr != 0) + { + BT_DRV_TRACE(2,"Fast_bt_init3:%s,to=%x",__func__,page_to); + *(uint16_t *)page_to_addr = page_to; + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_btdm_address_set(uint8_t* bt_addr, uint8_t* ble_addr) +{ + BT_DRV_REG_OP_ENTER(); + uint32_t btaddr_addr = 0; + uint32_t bleaddr_addr = 0; + uint32_t bch_addr = 0; + + + if(llm_le_env_addr) + { + bleaddr_addr = llm_le_env_addr+0x8f; + } + + if(ld_env_addr) + { + btaddr_addr = ld_env_addr; + bch_addr = btaddr_addr+451; + + } + + if(bleaddr_addr != 0) + { + BT_DRV_TRACE(1,"Fast_bt_init4:%s",__func__); + DUMP8("%02x ",bt_addr,6); + DUMP8("%02x ",ble_addr,6); + + for(uint8_t i=0; i<6; i++) + { + *(uint8_t *)(bleaddr_addr+i) = ble_addr[i]; + } + + for(uint8_t i=0; i<6; i++) + { + *(uint8_t *)(btaddr_addr+i) = bt_addr[i]; + } + ld_util_bch_create(bt_addr,(uint8_t *)bch_addr); + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_evtmask_set(uint8_t ble_en) +{ + BT_DRV_REG_OP_ENTER(); + uint32_t bt_evtmsk_addr = 0; + uint32_t ble_evtmask_addr = 0; + + if(llm_le_env_addr) + { + ble_evtmask_addr = llm_le_env_addr+0x64; + } + + + if(hci_env_addr) + { + bt_evtmsk_addr = hci_env_addr; + } + + if(bt_evtmsk_addr != 0) + { + BT_DRV_TRACE(2,"Fast_bt_init5:%s,ble enable=%x",__func__,ble_en); + uint8_t bt_mask[8]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f}; + if(ble_en) + { + bt_mask[7] = 0x3f; + } + memcpy((uint8_t *)bt_evtmsk_addr,bt_mask,8); + + uint8_t ble_mask[8]= {0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + memcpy((uint8_t *)ble_evtmask_addr,ble_mask,8); + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_simplepair_mode_set(uint8_t en) +{ + BT_DRV_REG_OP_ENTER(); + + if(lm_env_addr) + { + *(uint8_t *)(lm_env_addr+44) = en; + } + + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_class_of_dev_set(uint8_t* class_of_dev,uint8_t len) +{ + BT_DRV_REG_OP_ENTER(); + uint32_t class_of_dev_addr = 0; + + + + if(ld_env_addr) + { + //ld_env.class_of_dev.A + class_of_dev_addr = ld_env_addr+6; + } + + if(class_of_dev_addr != 0) + { + BT_DRV_TRACE(1,"Fast_bt_init7:%s",__func__); + DUMP8("%02x ",class_of_dev,3); + memcpy((uint8_t *)class_of_dev_addr, class_of_dev, 3); + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_sleep_set(bool en) +{ + BT_DRV_REG_OP_ENTER(); + uint32_t sleep_addr = 0; + + if(rwip_env_addr) + { + sleep_addr = rwip_env_addr+12; + } + + if(sleep_addr != 0) + { + BT_DRV_TRACE(2,"Fast_bt_init:%s en=%d",__func__,en); + *(uint8_t *)(sleep_addr) = en; + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_sco_fifo_reset(void) +{ + uint16_t sco_ptr0 = 0, sco_ptr1 = 0; + uint8_t *em_area_base = (uint8_t*)0xd0210000; + + BT_DRV_REG_OP_ENTER(); + BTDIGITAL_REG_GET_FIELD(0xd02201cc, 0xffff, 0, sco_ptr0); + BTDIGITAL_REG_GET_FIELD(0xd02201cc, 0xffff, 16, sco_ptr1); + BT_DRV_TRACE(3,"bt_drv_reg_op_sco_fifo_reset %d/%d %08x",sco_ptr0, sco_ptr1, BTDIGITAL_REG(0xd02201cc)); + memset(em_area_base+sco_ptr0, 0x55, 60); + memset(em_area_base+sco_ptr1, 0x55, 60); + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_sco_fifo_dump(void) +{ + uint16_t sco_ptr0 = 0, sco_ptr1 = 0; + uint8_t *em_area_base = (uint8_t*)0xd0210000; + BT_DRV_REG_OP_ENTER(); + BTDIGITAL_REG_GET_FIELD(0xd02201cc, 0xffff, 0, sco_ptr0); + BTDIGITAL_REG_GET_FIELD(0xd02201cc, 0xffff, 16, sco_ptr1); + BT_DRV_TRACE(3,"bt_drv_reg_op_sco_fifo_reset %d/%d %08x",sco_ptr0, sco_ptr1, BTDIGITAL_REG(0xd02201cc)); + DUMP8("%02x ", em_area_base+sco_ptr0, 10); + DUMP8("%02x ", em_area_base+sco_ptr1, 10); + BT_DRV_REG_OP_EXIT(); +} + +uint8_t bt_drv_reg_op_get_sync_id_op(uint8_t op, uint8_t sync_id) +{ + uint8_t sync_link_id = 0xff; + BT_DRV_REG_OP_ENTER(); + + uint32_t sync_id_addr = 0; + //only 2300P chip id =1 need this hack + if(hal_get_chip_metal_id()==HAL_CHIP_METAL_ID_1) + { + sync_id_addr =(sniffer_env_addr+ 0x3c); + } + + if(sync_id_addr != 0) + { + if(READ_OP == op) + { + sync_link_id = *(uint8_t *)(sync_id_addr); + } + else if(WRITE_OP == op) + { + *(uint8_t *)(sync_id_addr) = sync_id; + } + } + BT_DRV_REG_OP_EXIT(); + + return sync_link_id; +} + +void bt_drv_reg_op_disable_reporting_en(uint16_t conhdl) +{ + BT_DRV_REG_OP_ENTER(); + uint32_t lc_evt_ptr = 0x0; + uint32_t report_en_addr; + uint8_t linkid = btdrv_conhdl_to_linkid(conhdl); + + if (btdrv_is_link_index_valid(linkid)) + { + if(lc_env_addr) + { + lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr+linkid*4);//lc_env + report_en_addr = lc_evt_ptr+0x28a; + *(uint8_t *)report_en_addr = 0; + BT_DRV_TRACE(0,"REG_OP:disable afh report"); + } + } + BT_DRV_REG_OP_EXIT(); +} + +uint8_t bt_drv_reg_opcheck_controller_ld_lc_layer_mismatch(void) +{ + uint8_t cnt = 0; + BT_DRV_REG_OP_ENTER(); + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) + { + for(uint8_t link_id=0; link_id<3; link_id++) + { + uint32_t ld_acl_evt_ptr = 0; + uint32_t lc_evt_ptr = 0; + ld_acl_evt_ptr= *(uint32_t *)(ld_acl_env_addr+link_id*4); + lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr+link_id*4); + if((ld_acl_evt_ptr && !lc_evt_ptr) || + (!ld_acl_evt_ptr && lc_evt_ptr) ) + { + cnt ++; + } + } + } + BT_DRV_REG_OP_EXIT(); + return cnt; +} +void bt_drv_reg_op_ble_sup_timeout_set(uint16_t ble_conhdl, uint16_t sup_to) +{ + uint32_t llc_env_ptr = 0; + + if(llc_env_addr) + { + uint32_t llc_env_address = llc_env_addr+ble_conhdl*4; + llc_env_ptr = *(volatile uint32_t *)llc_env_address; + } + + if(llc_env_ptr != 0) + { + uint32_t llc_env_sup_to_address = llc_env_ptr + 0x54; + *(volatile uint16_t *)llc_env_sup_to_address = sup_to; + BT_DRV_TRACE(1,"BT_DRV:set ble sup_timeout to %d",sup_to); + } +} + +void bt_drv_reg_op_disable_swagc_nosync_count(void) +{ + if(dbg_bt_setting_ext1_addr) + { + *(uint16_t *)(dbg_bt_setting_ext1_addr+0x14) = 0xa604; + } +} + +void bt_drv_reg_op_hw_sw_agc_select(uint8_t agc_mode) +{ + uint32_t hw_agc_select_addr = 0; + BT_DRV_REG_OP_ENTER(); + + + if(rwip_rf_addr) + { + hw_agc_select_addr = rwip_rf_addr+0x37; + } + if(hw_agc_select_addr != 0) + { + *(volatile uint8_t *)hw_agc_select_addr = agc_mode; + } + + BT_DRV_REG_OP_EXIT(); +} + +void ble_maxevtime_set(int elt_idx, uint16_t value) +{ + BTDIGITAL_EM_BT_WR(BLE_MAXEVTIME_ADDR + elt_idx * BLE_EM_CS_SIZE, value); +} + +uint16_t ble_maxevtime_get(int elt_idx) +{ + return BTDIGITAL_BT_EM(BLE_MAXEVTIME_ADDR + elt_idx * BLE_EM_CS_SIZE); +} + +void bt_drv_reg_op_afh_follow_en(bool enable, uint8_t be_followed_link_id, uint8_t follow_link_id) +{ +#if BT_AFH_FOLLOW + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + *(uint8_t *)(lm_env_addr+0x168) = be_followed_link_id;//be follow follow link id + *(uint8_t *)(lm_env_addr+0x169) = follow_link_id;//follow link id + *(uint8_t *)(lm_env_addr+0x167) = enable; //afh follow enable + } +#endif +} + +void bt_drv_reg_op_set_agc_thd(bool isMaster, bool isSco) +{ + BT_DRV_REG_OP_ENTER(); + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + ASSERT(*(uint32_t *)0xc00072ec ==0xc0007310,"patch ERROR 2300p t2 bt_drv_reg_op_set_agc_thd!"); + BT_DRV_TRACE(1,"isMaster: %d, isSco: %d ",isMaster,isSco); + if(isMaster) + { + if(isSco) + { + BTDIGITAL_REG(0xc0007310)=0x00000020;//link_agc_thd_mobile_time£¬ reg address£º0xc0007310 + BTDIGITAL_REG(0xc0007300)=0x00000020;//link_agc_thd_tws_time£¬ reg address£º0xc0007300 + } + else + { + BTDIGITAL_REG(0xc0007310)=0x00000038;//link_agc_thd_mobile_time£¬ reg address£º0xc0007310 + BTDIGITAL_REG(0xc0007300)=0x00000038;//link_agc_thd_tws_time£¬ reg address£º0xc0007300 + } + } + else + { + if(isSco) + { + BTDIGITAL_REG(0xc0007310)=0x00000020;//link_agc_thd_mobile_time£¬ reg address£º0xc0007310 + BTDIGITAL_REG(0xc0007300)=0x00000020;//link_agc_thd_tws_time£¬ reg address£º0xc0007300 + } + else + { + BTDIGITAL_REG(0xc0007310)=0x00000038;//link_agc_thd_mobile_time£¬ reg address£º0xc0007310 + BTDIGITAL_REG(0xc0007300)=0x00000038;//link_agc_thd_tws_time£¬ reg address£º0xc0007300 + } + } + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_force_set_sniff_att(uint16_t conhdle) +{ + BT_DRV_REG_OP_ENTER(); + uint8_t linkid = btdrv_conhdl_to_linkid(conhdle); + uint32_t acl_evt_ptr = 0x0; + + if (btdrv_is_link_index_valid(linkid)) + { + if(hal_get_chip_metal_id()==HAL_CHIP_METAL_ID_1) + { + acl_evt_ptr=*(volatile uint32_t *)(0xc0000998+linkid*4);//ld_acl_env + } + else if(hal_get_chip_metal_id()==HAL_CHIP_METAL_ID_2) + { + acl_evt_ptr=*(volatile uint32_t *)(0xc00009d4+linkid*4);//ld_acl_env + } + + if (acl_evt_ptr != 0) + { + uint32_t sniff_att_addr = acl_evt_ptr + 0xe2; + if(BT_DRIVER_GET_U16_REG_VAL(sniff_att_addr) <3) + { + BT_DRIVER_PUT_U16_REG_VAL(sniff_att_addr, 3); + } + //set sniff timeout to 0 + BT_DRIVER_PUT_U16_REG_VAL(sniff_att_addr+4, 0); + + BT_DRV_TRACE(0,"BT_REG_OP:force set sniff att"); + } + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_fa_gain_direct_set(uint8_t gain_idx) +{ + BTDIGITAL_REG(0xd0220484) = (BTDIGITAL_REG(0xd0220484)&(~0xffff))|0x9401|(gain_idx << 1); //lxd 20191105 fixed ecc receive gain +} + +uint8_t bt_drv_reg_op_fa_gain_direct_get(void) +{ + uint32_t raw_reg = BTDIGITAL_REG(0xd0220484); + return (raw_reg >> 1)&0x07; +} + +struct rx_gain_fixed_t +{ + uint8_t enable;//enable or disable + uint8_t bt_or_ble;//0:bt 1:ble + uint8_t cs_id;//link id + uint8_t gain_idx;//gain index +}; + +void bt_drv_reg_op_dgb_link_gain_ctrl_set(uint16_t connHandle, uint8_t bt_ble_mode, uint8_t gain_idx, uint8_t enable) +{ + if(hal_get_chip_metal_id() <= HAL_CHIP_METAL_ID_1) + { + TRACE(1,"%s to all link", __func__); + uint16_t raw_reg = *((volatile uint16_t*)0xc00041ec); + if (bt_ble_mode) + { + raw_reg = raw_reg & (~0xff<<8); + raw_reg = raw_reg | (gain_idx<<8); + } + else + { + raw_reg = raw_reg & ~0xff; + raw_reg = raw_reg | gain_idx; + } + *((volatile uint16_t*)0xc00041ec) = raw_reg; + } + + struct rx_gain_fixed_t *rx_gain_fixed_p = (struct rx_gain_fixed_t *)0xc00004dc; + uint8_t cs_id = btdrv_conhdl_to_linkid(connHandle); + + if (btdrv_is_link_index_valid(cs_id)) + { + for (uint8_t i=0; i<3; i++) + { + if ((rx_gain_fixed_p->cs_id == cs_id) && + (rx_gain_fixed_p->bt_or_ble == bt_ble_mode)) + { + rx_gain_fixed_p->enable = enable; + rx_gain_fixed_p->bt_or_ble = bt_ble_mode; + rx_gain_fixed_p->gain_idx = gain_idx; + BT_DRV_TRACE(5,"%s hdl:%x/%x mode:%d idx:%d", __func__, connHandle, cs_id, rx_gain_fixed_p->bt_or_ble, gain_idx); + } + rx_gain_fixed_p++; + } + } +} + +void bt_drv_reg_op_dgb_link_gain_ctrl_clear(uint16_t connHandle, uint8_t bt_ble_mode) +{ + if(hal_get_chip_metal_id() <= HAL_CHIP_METAL_ID_1) + { + BT_DRV_TRACE(1,"%s REG_OP: not support", __func__); + } + + struct rx_gain_fixed_t *rx_gain_fixed_p = (struct rx_gain_fixed_t *)0xc00004dc; + uint8_t cs_id = btdrv_conhdl_to_linkid(connHandle); + + if (btdrv_is_link_index_valid(cs_id)) + { + for (uint8_t i=0; i<3; i++) + { + if ((rx_gain_fixed_p->cs_id == cs_id) && + (rx_gain_fixed_p->bt_or_ble == bt_ble_mode)) + { + rx_gain_fixed_p->enable = 0; + rx_gain_fixed_p->bt_or_ble = bt_ble_mode; + rx_gain_fixed_p->gain_idx = 0; + } + rx_gain_fixed_p++; + } + } +} + +void bt_drv_reg_op_dgb_link_gain_ctrl_init(void) +{ + if(hal_get_chip_metal_id() <= HAL_CHIP_METAL_ID_1) + { + BT_DRV_TRACE(1,"%s REG_OP: not support", __func__); + } + + struct rx_gain_fixed_t *rx_gain_fixed_p = (struct rx_gain_fixed_t *)0xc00004dc; + + for (uint8_t i=0; i<3; i++) + { + rx_gain_fixed_p->cs_id = i; + rx_gain_fixed_p++; + } +} + +void bt_drv_reg_op_rx_gain_fix(uint16_t connHandle, uint8_t bt_ble_mode, uint8_t gain_idx, uint8_t enable, uint8_t table_idx) +{ + if(hal_get_chip_metal_id() <= HAL_CHIP_METAL_ID_1) + { + BT_DRV_TRACE(1,"%s REG_OP: not support", __func__); + } + + struct rx_gain_fixed_t *rx_gain_fixed_p = (struct rx_gain_fixed_t *)0xc00004dc; + uint8_t cs_id; + + if(bt_ble_mode == 0)//bt + { + cs_id = btdrv_conhdl_to_linkid(connHandle); + } + else if(bt_ble_mode == 1)//ble + { + cs_id = connHandle; + } + else + { + BT_DRV_TRACE(1,"%s:fix gain fail",__func__); + return; + } + + if(table_idx < 3) + { + rx_gain_fixed_p[table_idx].enable = enable; + rx_gain_fixed_p[table_idx].bt_or_ble = bt_ble_mode; + rx_gain_fixed_p[table_idx].cs_id = cs_id; + rx_gain_fixed_p[table_idx].gain_idx = gain_idx; + } +} + +void bt_drv_reg_op_set_ibrt_auto_accept_sco(bool en) +{ + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + ASSERT(*(uint32_t *)0xc0007344 == 0xc0007348,"ibrt_auto_accept_sco PATCH ERROR!!"); + if(en) + { + BTDIGITAL_REG(0xc0007348) = 1; + BT_DRV_TRACE(0,"BT_REG_OP:enable ibrt_auto_accept_sco"); + } + else + { + BTDIGITAL_REG(0xc0007348) = 0; + } + } +} + +void bt_drv_reg_op_update_dbg_state(void) +{ + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + ASSERT(*(uint32_t *)0xc00076a0 == 0xc00076a4,"update_dbg_state PATCH ERROR!!"); + BTDIGITAL_REG(0xc00076a4) = 1; + BT_DRV_TRACE(0,"BT_REG_OP:update_dbg_state"); + } +} + +void bt_drv_reg_op_set_ibrt_reject_sniff_req(bool en) +{ + if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + ASSERT(*(uint32_t *)0xc0006e6c == 0xbb5ef615, "ibrt_reject_sniff_req PATCH ERROR!!"); + BTDIGITAL_REG(0xc0006e70) = en ? 1 : 0; + //BT_DRV_TRACE(1,"BT_REG_OP:ibrt reject sniff %d", en); + } +} + +uint8_t bt_drv_reg_op_get_esco_nego_airmode(uint8_t sco_link_id) +{ + BT_DRV_REG_OP_ENTER(); + + if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + // uint32_t lc_sco_env_addr = 0xc000079c; + uint32_t p_nego_params_addr = *((uint32_t *)(lc_sco_env_addr + 4 + sco_link_id * 8)); + uint8_t airmode = 0; + + if (sco_link_id > 2 || p_nego_params_addr == 0) + { + return 0xff; + } + + airmode = *((uint8_t *)(p_nego_params_addr + 0x5e)); + + BT_DRV_TRACE(1,"BT_REG_OP:Get nego esco airmode=%d",airmode); + return airmode; + } + + BT_DRV_REG_OP_EXIT(); + + return 0; + +} + +void bt_drv_reg_op_set_max_pwr_rcv(uint16_t connHandle) +{ + BT_DRV_REG_OP_ENTER(); + uint32_t lc_evt_ptr = 0x0; + uint32_t max_power_rcv_addr; + uint8_t linkid = btdrv_conhdl_to_linkid(connHandle); + + if(lc_env_addr) + { + lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr+linkid*4);//lc_env + } + + if(lc_evt_ptr) + { + //lc_env_ptr->link.MaxPowerRcv + max_power_rcv_addr = lc_evt_ptr+0x61; + *(bool *)max_power_rcv_addr = true; + BT_DRV_TRACE(1,"BT_REG_OP:conhdl=%x, max pwr recieve",connHandle); + } + BT_DRV_REG_OP_EXIT(); +} + +void bt_drv_reg_op_set_rand_seed(uint32_t seed) +{ + if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) + { + *(volatile uint32_t*)(0xc0006890)=seed; + } + else if(hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) + { + *(volatile uint32_t*)(0xc0006998)=seed; + } +} + +uint32_t bt_drv_reg_op_get_host_ref_clk(void) +{ + return 0; +} + +void bt_drv_reg_op_hci_vender_ibrt_ll_monitor(uint8_t* ptr, uint16_t* p_sum_err,uint16_t* p_rx_total) +{ + const char *monitor_str[29] = + { + "TX DM1", + "TX DH1", + "TX DM3", + "TX DH3", + "TX DM5", + "TX DH5", + "TX 2DH1", + "TX 3DH1", + "TX 2DH3", + "TX 3DH3", + "TX 2DH5", + "TX 3DH5", + + "RX DM1", + "RX DH1", + "RX DM3", + "RX DH3", + "RX DM5", + "RX DH5", + "RX 2DH1", + "RX 3DH1", + "RX 2DH3", + "RX 3DH3", + "RX 2DH5", + "RX 3DH5", + "hec error", + "crc error", + "fec error", + "gard error", + "ecc count", + }; + + uint32_t *p = ( uint32_t * )ptr; + uint32_t sum_err = 0; + uint32_t rx_data_sum = 0; + uint32_t val; + + TRACE(0,"ibrt_ui_log:ll_monitor"); + for (uint8_t i = 0; i < 29; i++) + { + val = co_read32p(p); + if (val) + { + if(i>= 12 && i<=23){ + rx_data_sum += val; + } + if(i>23) + { + sum_err += val; + } + TRACE(2,"%s %d", monitor_str[i], val); + } + p+=4; + } + *p_sum_err = sum_err; + *p_rx_total = rx_data_sum; +} + +uint8_t bt_drv_reg_op_bt_sync_swagc_en_get(void) +{ + return 0; +} +void bt_drv_reg_op_ecc_softbit_process(uint16_t* p_conn_handle1, uint16_t* p_conn_handle2, uint16_t length, uint8_t *data) +{ +} + +#if defined(PCM_FAST_MODE) && defined(PCM_PRIVATE_DATA_FLAG) +void bt_drv_reg_op_set_pcm_flag() +{ +} +#endif +void bt_drv_reg_op_key_gen_after_reset(bool enable) +{ +} diff --git a/platform/drivers/bt/best2300p/bt_drv_rfconfig.c b/platform/drivers/bt/best2300p/bt_drv_rfconfig.c new file mode 100644 index 0000000..f79fc6b --- /dev/null +++ b/platform/drivers/bt/best2300p/bt_drv_rfconfig.c @@ -0,0 +1,796 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "hal_i2c.h" +#include "hal_uart.h" +#include "bt_drv.h" +#ifdef RTOS +#include "cmsis_os.h" +#endif +#include "cmsis.h" +#include "hal_cmu.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "tgt_hardware.h" +#include "bt_drv_internal.h" +#include "bt_drv_2300p_internal.h" +#include "hal_chipid.h" +#include "bt_drv_interface.h" +#include "bt_drv_reg_op.h" +#include "pmu.h" +#include "iqcorrect.h" +#include "hal_btdump.h" + +#define AUTO_CAL 0 + +#ifndef BT_RF_MAX_XTAL_TUNE_PPB +// Default 10 ppm/bit or 10000 ppb/bit +#define BT_RF_MAX_XTAL_TUNE_PPB 10000 +#endif + +#ifndef BT_RF_XTAL_TUNE_FACTOR +// Default 0.2 ppm/bit or 200 ppb/bit +#define BT_RF_XTAL_TUNE_FACTOR 200 +#endif + +#define DEFAULT_XTAL_FCAP 0x8080 + +#define XTAL_FCAP_NORMAL_SHIFT 0 +#define XTAL_FCAP_NORMAL_MASK (0xFF << XTAL_FCAP_NORMAL_SHIFT) +#define XTAL_FCAP_NORMAL(n) BITFIELD_VAL(XTAL_FCAP_NORMAL, n) + +#define BT_XTAL_CMOM_DR (1 << 13) + +#define RF_REG_XTAL_FCAP 0xE9 +#define RF_REG_XTAL_CMOM_DR 0xE8 + +/* ljh add for sync modify rf RF_REG_XTAL_FCAP value*/ +#define SPI_TRIG_RX_NEG_TIMEOUT MS_TO_TICKS(3) + +#define SPI_TRIG_NEG_TIMEOUT SPI_TRIG_RX_NEG_TIMEOUT + + +enum BIT_OFFSET_CMD_TYPE_T +{ + BIT_OFFSET_CMD_STOP = 0, + BIT_OFFSET_CMD_START, + BIT_OFFSET_CMD_ACK, +}; + +static uint16_t xtal_fcap = DEFAULT_XTAL_FCAP; +static uint16_t init_xtal_fcap = DEFAULT_XTAL_FCAP; + + +//rampup start 1--->2->3 rampup ok +//rampdown start 3-->2-->1-->0 rampdown ok + + +//3a06=3b3f +//for pa@1.8v +struct bt_drv_tx_table_t +{ + uint16_t tbl[16][3]; +}; + + +struct RF_SYS_INIT_ITEM +{ + uint16_t reg; + uint16_t set; + uint16_t mask; + uint16_t delay; +}; + +static const struct RF_SYS_INIT_ITEM rf_sys_init_tbl[] = +{ + {0xb5,0x8000,0x8000,0}, + {0xc2,0x7188,0x7fff,0}, +#ifdef LBRT + {0xc4,0x0043,0x0043,0},//enable lbrt adc clk[6] +#else + {0xc4,0x0003,0x0003,0}, +#endif +}; + + +//zhangzhd agc config use default 1216 +#define REG_EB_VAL 0x000c +#define REG_181_VAL (0x00bf) +#define REG_EC_VAL 0x000d +#define REG_182_VAL 0x00bf +#define REG_ED_VAL 0x000e +#define REG_183_VAL 0x00bf +#define REG_EE_VAL 0x000b +#define REG_184_VAL 0x00bf +#define REG_EF_VAL 0x0007 +#define REG_185_VAL 0x00bf +#define REG_F0_VAL 0x0007 +#define REG_186_VAL 0x00af +#define REG_F1_VAL 0x0007 +#define REG_187_VAL 0x009f +#define REG_F2_VAL 0x0007 +#define REG_188_VAL 0x008f + +//zhangzhd agc config end +const uint16_t rf_init_tbl_1[][3] = +{ + {0x88,0x8640,0}, + {0x8b,0x8a4a,0},//set rx flt cap,filter start up +#if defined(__FANG_HW_AGC_CFG_ADC__) + {0xd1,0x8401,0},//set ra adc gain -3db + {0x8e,0x0D28,0},//adc noise reduction +#else + {0xd1,0x8403,0},//set gain + {0x8e,0x0128,0},//adc noise reduction +#endif + {0x90,0x8e1f,0},//enlarge txflt BW + {0x91,0x05c0,0},//by walker 20180427 + {0x92,0x668e,0},//update by luobin 2019/3/22 + {0x97,0x2523,0},//update by luobin 2019.0523 + {0x98,0x1324,0},//update by walker 2019.01.14, modify for yield + {0x9a,0x4470,0},//div2 rc + {0x9b,0xfd52,0},//update by walker 2018.10.24 + {0x9c,0x180f,0},/////////luobin + {0xa3,0x0789,0}, + {0xb0,0x0000,0}, + {0xb1,0x0000,0}, + {0xb3,0x31f3,0},// + {0xb4,0x883c,0}, + {0xb6,0x3156,0}, + {0xb7,0x183f,0},//update by walker 2018.07.30 + {0xb9,0x8000,0},//cap3g6 off + {0xba,0x104e,0}, +#if defined(__FANG_LNA_CFG__) + {0xac,0x080e,0},//pre-charge set to 5us + {0x85,0x7f00,0},//NFMI RXADC LDO rise up + // {0xc3,0x0068,0},//add by xrz increase pll cal time 2018/10/20 + {0xc3,0x0044,0}, +#else + {0xc3,0x0050,0}, +#endif + {0xc5,0x4b50,0},//vco ictrl dr + {0xc9,0x3a08,0},//vco ictrl + {0xd3,0xc1c1,0}, + {0xd4,0x000f,0}, + {0xd5,0x4000,0}, + {0xd6,0x7980,0}, + {0xe8,0xe000,0}, + {0xf3,0x0c41,0},//by fang + {0x1a6,0x0600,0}, + {0x1ae,0x6a00,0},//fastlock en + {0x1d4,0x0000,0}, + {0x1d7,0xc4ff,0},//update by walker 2018.10.10 + {0x1de,0x2000,0}, + {0x1df,0x2087,0}, + {0x1f4,0x2241,0},//by walker 20180427 + {0x1fa,0x03df,0},//rst needed + {0x1fa,0x83df,0}, + {0xeb,REG_EB_VAL,0},//gain_idx:0 + {0x181,REG_181_VAL,0}, + {0xec,REG_EC_VAL,0},//gain_idx:1 + {0x182,REG_182_VAL,0}, + {0xed,REG_ED_VAL,0},//gain_idx:2 + {0x183,REG_183_VAL,0}, + {0xee,REG_EE_VAL,0},//gain_idx:3 + {0x184,REG_184_VAL,0}, + {0xef,REG_EF_VAL,0},//gain_idx:4 + {0x185,REG_185_VAL,0}, + {0xf0,REG_F0_VAL,0},//gain_idx:5 + {0x186,REG_186_VAL,0}, + {0xf1,REG_F1_VAL,0},//gain_idx:6 + {0x187,REG_187_VAL,0}, + {0xf2,REG_F2_VAL,0},//gain_idx:7 + {0x188,REG_188_VAL,0}, + {0x1d6,0x7e58,0},//set lbrt rxflt dccal_ready=1 + {0x1c8,0xdfc0,0},//en rfpll bias in lbrt mode + {0x1c9,0xa0cf,0},//en log bias + {0x82,0x0caa,0}, // select rfpll and cplx_dir=0 and en rxflt test + {0xf4,0x2181,0}, // set flt_cap to match flt_gain + {0x86,0xdc99,0},//set nfmi tmix + {0xdf,0x2006,0},//set nfmi tmix vcm +#ifdef __HW_AGC__ + {0x1c7,0x007d,0},//open lbrt adc and vcm bias current +#endif + {0x18c,0x0000,0},//max tx gain lbrt + //air @ LBRT 31.5m + {0x1d8,0x9162,0},//lbrt tx freqword + {0x1d9,0x9162,0},//lbrt tx freqword + {0x1da,0x9162,0},//lbrt tx freqword + {0x1db,0x9162,0},//lbrt tx freqword + {0x1dc,0x0000,0},//txlccap + {0x1dd,0x0000,0},//txlccap + {0x1ed,0x0000,0},//rxlccap + {0x1ee,0x0000,0},//rxlccap + {0x1e9,0x0a0a,0},//set rfpll divn in lbrt tx mode + {0x1ea,0x0a0a,0}, + {0x1eb,0x0a0a,0},//set rfpll divn in lbrt rx mode + {0x1ec,0x0a0a,0}, + {0x1ef,0x8a76,0},//lbrt rx freqword + {0x1f0,0x8a76,0},//lbrt rx freqword + {0x1f1,0x8a76,0},//lbrt rx freqword + {0x1f2,0x8a76,0},//lbrt rx freqword + {0x87,0x9f00,0},//{0x87,0x9f40,0} + {0x81,0x9207,0}, + {0xce,0xfc08,0}, + {0x8A,0x4EA4,0},// use rfpll for nfmi adclk + //[below for ibrt] + {0x8c,0x9100,0}, + {0xab,0x1c0c,0}, //2019.05.08 by luofei + {0xa5,0x0404,0}, //rfpll pu time + {0xa6,0x2D20,0}, //2019.05.23 by luobin + {0xa8,0x2D22,0}, //2019.05.23 by luobin + {0x1b7,0x2c00,0}, //2019.05.08 by luofei + {0x1ad,0x9000,0}, // 2M tx filter baseband + {0xdc,0x8820,0}, //fa pa pwrup time + {0x8f,0x71b8,0},//tx dac by luobin +}; + +#ifdef __HW_AGC__ +const uint16_t rf_init_tbl_1_hw_agc[][3] = //hw agc table +{ + {0xad,0xa04a,1},//hwagc en=1 + {0xCD,0x0040,0},//default 0x0000 + {0xcf,0x7f32,0},//lna gain dr=0 //default 0x0000 + {0xd0,0xe91f,0},//i2v flt gain dr=0 //default 0x0000 + + {0xeb,0x0007,0},//gain_idx:0 + {0xec,0x0007,0},//gain_idx:1 + {0xed,0x0007,0},//gain_idx:2 + {0xee,0x000d,0},//gain_idx:3 + {0xef,0x000d,0},//gain_idx:4 + {0xf0,0x000d,0},//gain_idx:5 + {0xf1,0x000d,0},//gain_idx:6 + {0xf2,0x000c,0},//gain_idx:7 +}; +#endif //__HW_AGC__ + +const uint16_t rf_init_tbl_1_sw_agc[][3] = //sw agc table +{ + {0xad,0xa00a,1},//hwagc en=0 + {0xCD,0x0000,0},//default 0x0000 + {0xcf,0x0000,0},//lna gain dr=0 //default 0x0000 + {0xd0,0x0000,0},//i2v flt gain dr=0 //default 0x0000 + {0xeb,REG_EB_VAL,0},//gain_idx:0 + {0xec,REG_EC_VAL,0},//gain_idx:1 + {0xed,REG_ED_VAL,0},//gain_idx:2 + {0xee,REG_EE_VAL,0},//gain_idx:3 + {0xef,REG_EF_VAL,0},//gain_idx:4 + {0xf0,REG_F0_VAL,0},//gain_idx:5 + {0xf1,REG_F1_VAL,0},//gain_idx:6 + {0xf2,REG_F2_VAL,0},//gain_idx:7 +}; + +uint32_t btdrv_rf_get_max_xtal_tune_ppb(void) +{ + return BT_RF_MAX_XTAL_TUNE_PPB; +} + +uint32_t btdrv_rf_get_xtal_tune_factor(void) +{ + return BT_RF_XTAL_TUNE_FACTOR; +} + +void btdrv_rf_init_xtal_fcap(uint32_t fcap) +{ + xtal_fcap = SET_BITFIELD(xtal_fcap, XTAL_FCAP_NORMAL, fcap); + btdrv_write_rf_reg(RF_REG_XTAL_FCAP, xtal_fcap); + init_xtal_fcap = xtal_fcap; +} + +uint32_t btdrv_rf_get_init_xtal_fcap(void) +{ + return GET_BITFIELD(init_xtal_fcap, XTAL_FCAP_NORMAL); +} + +uint32_t btdrv_rf_get_xtal_fcap(void) +{ + return GET_BITFIELD(xtal_fcap, XTAL_FCAP_NORMAL); +} + +void btdrv_rf_set_xtal_fcap(uint32_t fcap, uint8_t is_direct) +{ + xtal_fcap = SET_BITFIELD(xtal_fcap, XTAL_FCAP_NORMAL, fcap); + btdrv_write_rf_reg(RF_REG_XTAL_FCAP, xtal_fcap); +} + + +int btdrv_rf_xtal_fcap_busy(uint8_t is_direct) +{ + return 0; +} + +void btdrv_rf_bit_offset_track_enable(bool enable) +{ + return; +} + +uint32_t btdrv_rf_bit_offset_get(void) +{ + return 0; +} + +uint16_t btdrv_rf_bitoffset_get(uint8_t conidx) +{ + uint16_t bitoffset; + bitoffset = BTDIGITAL_REG(EM_BT_BITOFF_ADDR+conidx*BT_EM_SIZE) & 0x3ff; + return bitoffset; +} + +void btdrv_rf_log_delay_cal(void) +{ + unsigned short read_value; + unsigned short write_value; + BT_DRV_TRACE(0,"btdrv_rf_log_delay_cal\n"); + + btdrv_write_rf_reg(0xa7, 0x0028); + + btdrv_write_rf_reg(0xd4, 0x0000); + btdrv_write_rf_reg(0xd5, 0x4002); +// *(volatile uint32_t*)(0xd02201e4) = 0x000a00b0; + *(volatile uint32_t*)(0xd0340020) = 0x030e01c1; + BT_DRV_TRACE(1,"0xd0340020 =%x\n",*(volatile uint32_t*)(0xd0340020) ); + + btdrv_delay(1); + + btdrv_write_rf_reg(0xd2, 0x5003); + + btdrv_delay(1); + + btdrv_read_rf_reg(0x1e2, &read_value); + BT_DRV_TRACE(1,"0x1e2 read_value:%x\n",read_value); + if(read_value == 0xff80) + { + btdrv_write_rf_reg(0xd3, 0xffff); + } + else + { + write_value = ((read_value>>7)&0x0001) | ((read_value & 0x007f)<<1) | ((read_value&0x8000)>>7) | ((read_value&0x7f00)<<1); + BT_DRV_TRACE(1,"d3 write_value:%x\n",write_value); + btdrv_write_rf_reg(0xd3, write_value); + } + btdrv_delay(1); + +// *(volatile uint32_t*)(0xd02201e4) = 0x00000000; + *(volatile uint32_t*)(0xd0340020) = 0x010e01c0; + BT_DRV_TRACE(1,"0xd0340020 =%x\n",*(volatile uint32_t*)(0xd0340020) ); + + + btdrv_write_rf_reg(0xd4, 0x000f); + btdrv_write_rf_reg(0xd2, 0x1003); + btdrv_write_rf_reg(0xd5, 0x4000); + +} + +void btdrv_rf_rx_gain_adjust_req(uint32_t user, bool lowgain) +{ + return; +} + +//rf Image calib +void btdtv_rf_image_calib(void) +{ + + uint16_t read_val; + //read calibrated val from efuse 0x05 register + pmu_get_efuse(PMU_EFUSE_PAGE_SW_CFG, &read_val); + //check if bit 11 has been set + uint8_t calb_done_flag = ((read_val &0x800)>>11); + if(calb_done_flag) + { + BT_DRV_TRACE(1,"EFUSE REG[5]=%x",read_val); + } + else + { + BT_DRV_TRACE(0,"EFUSE REG[5] rf image has not been calibrated!"); + return; + } + //[bit 12] calib flag + uint8_t calib_val = ((read_val &0x1000)>>12); + btdrv_read_rf_reg(0x9b,&read_val); + read_val&=0xfcff; + + if(calib_val==0) + { + read_val|= 1<<8; + } + else if(calib_val== 1) + { + read_val|= 1<<9; + } + + BT_DRV_TRACE(1,"write rf image calib val=%x in REG[0x9b]", read_val); + btdrv_write_rf_reg(0x9b,read_val); +} + +#ifdef TX_IQ_CAL +const uint16_t tx_cal_rfreg_set[][3] = +{ + //iq cal path + {0x1c4,0xffcf,0}, + {0x1c5,0xf8ff,0}, + {0x1c6,0x007f,0}, + {0x1c7,0x03ff,0}, + {0x1d6,0x7a58,0}, + {0x1d7,0xc0f7,0}, + {0x1f4,0x2481,0}, + {0x94,0x11c3,0}, + {0x95,0xe5c0,0}, + {0xd1,0x846b,0}, + {0xae,0x0403,0}, + {0x86,0xccd9,0}, + {0xf3,0x0c75,0}, + {0xf4,0x0309,0}, + {0xcf,0x8090,0}, + {0x82,0x2cab,0}, + + //nfmi adc + {0xc4,0x00c3,0}, + {0xae,0x07ff,0}, + {0x85,0x470f,0}, + {0x82,0x4aab,0}, + {0x82,0xecab,0}, + {0x87,0xa211,0}, + {0x87,0xe211,0}, + {0x84,0xfff8,0}, +}; + +const uint16_t tx_cal_rfreg_store[][1] = +{ + {0x1c4}, + {0x1c5}, + {0x1c6}, + {0x1c7}, + {0x1d6}, + {0x1d7}, + {0x1f4}, + {0x94}, + {0x95}, + {0xd1}, + {0xae}, + {0x86}, + {0xf3}, + {0xf4}, + {0xcf}, + {0x82}, + {0xc4}, + {0x85}, + {0x87}, + {0x84}, +}; + +int bt_iqimb_ini (); +int bt_iqimb_test_ex (int mismatch_type); +void btdrv_tx_iq_cal(void) +{ + uint8_t i; + const uint16_t (*tx_cal_rfreg_set_p)[3]; + const uint16_t (*tx_cal_rfreg_store_p)[1]; + uint32_t reg_set_tbl_size; + uint32_t reg_store_tbl_size; + uint16_t value; + uint32_t tx_cal_digreg_store[5]; + + tx_cal_rfreg_store_p = &tx_cal_rfreg_store[0]; + reg_store_tbl_size = sizeof(tx_cal_rfreg_store)/sizeof(tx_cal_rfreg_store[0]); + uint16_t tx_cal_rfreg_store[reg_store_tbl_size]; + BT_DRV_TRACE(0,"reg_store:\n"); + for(i=0; i< reg_store_tbl_size; i++) + { + btdrv_read_rf_reg(tx_cal_rfreg_store_p[i][0],&value); + tx_cal_rfreg_store[i] = value; + BT_DRV_TRACE(2,"reg=%x,v=%x",tx_cal_rfreg_store_p[i][0],value); + } + tx_cal_digreg_store[0] = *(volatile uint32_t*)(0xd0330038); + tx_cal_digreg_store[1] = *(volatile uint32_t*)(0xd0350364); + tx_cal_digreg_store[2] = *(volatile uint32_t*)(0xd0350360); + tx_cal_digreg_store[3] = *(volatile uint32_t*)(0xd035037c); + tx_cal_digreg_store[4] = *(volatile uint32_t*)(0xd02201e4); + BT_DRV_TRACE(1,"0xd0330038:%x\n",tx_cal_digreg_store[0]); + BT_DRV_TRACE(1,"0xd0350364:%x\n",tx_cal_digreg_store[1]); + BT_DRV_TRACE(1,"0xd0350360:%x\n",tx_cal_digreg_store[2]); + BT_DRV_TRACE(1,"0xd035037c:%x\n",tx_cal_digreg_store[3]); + BT_DRV_TRACE(1,"0xd02201e4:%x\n",tx_cal_digreg_store[4]); + + + tx_cal_rfreg_set_p = &tx_cal_rfreg_set[0]; + reg_set_tbl_size = sizeof(tx_cal_rfreg_set)/sizeof(tx_cal_rfreg_set[0]); + BT_DRV_TRACE(0,"reg_set:\n"); + for(i=0; i< reg_set_tbl_size; i++) + { + btdrv_write_rf_reg(tx_cal_rfreg_set_p[i][0],tx_cal_rfreg_set_p[i][1]); + if(tx_cal_rfreg_set_p[i][2] !=0) + btdrv_delay(tx_cal_rfreg_set_p[i][2]);//delay + btdrv_read_rf_reg(tx_cal_rfreg_set_p[i][0],&value); + BT_DRV_TRACE(2,"reg=%x,v=%x",tx_cal_rfreg_set_p[i][0],value); + } + //iq cal cordic + *(volatile uint32_t*)(0xd0330038) = 0x0020010d; + btdrv_delay(1); + *(volatile uint32_t*)(0xd0350364) = 0x002eb948; + *(volatile uint32_t*)(0xd0350360) = 0x007fc240; + *(volatile uint32_t*)(0xd035037c) = 0x00020405; + *(volatile uint32_t*)(0xd02201e4) = 0x000a0000; + BT_DRV_TRACE(1,"0xd0330038:%x\n",*(volatile uint32_t*)(0xd0330038)); + BT_DRV_TRACE(1,"0xd0350364:%x\n",*(volatile uint32_t*)(0xd0350364)); + BT_DRV_TRACE(1,"0xd0350360:%x\n",*(volatile uint32_t*)(0xd0350360)); + BT_DRV_TRACE(1,"0xd035037c:%x\n",*(volatile uint32_t*)(0xd035037c)); + BT_DRV_TRACE(1,"0xd02201e4:%x\n",*(volatile uint32_t*)(0xd02201e4)); + + bt_iqimb_ini(); + bt_iqimb_test_ex(1); + + BT_DRV_TRACE(0,"reg_reset:\n"); + for(i=0; i< reg_store_tbl_size; i++) + { + btdrv_write_rf_reg(tx_cal_rfreg_store_p[i][0],tx_cal_rfreg_store[i]); + + btdrv_read_rf_reg(tx_cal_rfreg_store_p[i][0],&value); + BT_DRV_TRACE(2,"reg=%x,v=%x",tx_cal_rfreg_store_p[i][0],value); + } + *(volatile uint32_t*)(0xd0330038) = tx_cal_digreg_store[0]; + *(volatile uint32_t*)(0xd0350364) = tx_cal_digreg_store[1]; + *(volatile uint32_t*)(0xd0350360) = tx_cal_digreg_store[2]; + *(volatile uint32_t*)(0xd035037c) = tx_cal_digreg_store[3]; + *(volatile uint32_t*)(0xd02201e4) = tx_cal_digreg_store[4]; + BT_DRV_TRACE(1,"0xd0330038:%x\n",*(volatile uint32_t*)(0xd0330038)); + BT_DRV_TRACE(1,"0xd0350364:%x\n",*(volatile uint32_t*)(0xd0350364)); + BT_DRV_TRACE(1,"0xd0350360:%x\n",*(volatile uint32_t*)(0xd0350360)); + BT_DRV_TRACE(1,"0xd035037c:%x\n",*(volatile uint32_t*)(0xd035037c)); + BT_DRV_TRACE(1,"0xd02201e4:%x\n",*(volatile uint32_t*)(0xd02201e4)); + +} +#endif + +uint8_t btdrv_rf_init(void) +{ + uint16_t value; + const uint16_t (*rf_init_tbl_p)[3]; + uint32_t tbl_size; + //uint8_t ret; + uint8_t i; + + for (i = 0; i < ARRAY_SIZE(rf_sys_init_tbl); i++) + { + btdrv_read_rf_reg(rf_sys_init_tbl[i].reg, &value); + value = (value & ~rf_sys_init_tbl[i].mask) | (rf_sys_init_tbl[i].set & rf_sys_init_tbl[i].mask); + if (rf_sys_init_tbl[i].delay) + { + btdrv_delay(rf_sys_init_tbl[i].delay); + } + btdrv_write_rf_reg(rf_sys_init_tbl[i].reg, value); + } + + rf_init_tbl_p = &rf_init_tbl_1[0]; + tbl_size = sizeof(rf_init_tbl_1)/sizeof(rf_init_tbl_1[0]); + + for(i=0; i< tbl_size; i++) + { + btdrv_write_rf_reg(rf_init_tbl_p[i][0],rf_init_tbl_p[i][1]); + if(rf_init_tbl_p[i][2] !=0) + btdrv_delay(rf_init_tbl_p[i][2]);//delay + } + + bt_drv_tx_pwr_init(); + +#ifdef __HW_AGC__ + for(i=0; i< sizeof(rf_init_tbl_1_hw_agc)/sizeof(rf_init_tbl_1_hw_agc[0]); i++) + { + btdrv_write_rf_reg(rf_init_tbl_1_hw_agc[i][0],rf_init_tbl_1_hw_agc[i][1]); + if(rf_init_tbl_1_hw_agc[i][2] !=0) + btdrv_delay(rf_init_tbl_1_hw_agc[i][2]);//delay + } +#endif + + //need before rf log delay cal + btdtv_rf_image_calib(); + + btdrv_rf_log_delay_cal(); + + btdrv_spi_trig_init(); + +#ifdef TX_IQ_CAL + hal_btdump_clk_enable(); + bt_iq_calibration_setup(); + hal_btdump_clk_disable(); +#endif + + return 1; +} + +void bt_drv_rf_reset(void) +{ + btdrv_write_rf_reg(0x80,0xcafe); + btdrv_write_rf_reg(0x80,0x5fee); +} + +static void bt_drv_switch_hw_sw_agc(enum BT_AGC_MODE_T agc_mode) +{ + static enum BT_AGC_MODE_T agc_mode_bak = BT_AGC_MODE_NONE; + uint16_t i = 0; + + if(agc_mode_bak != agc_mode) + { + agc_mode_bak = agc_mode; + BT_DRV_TRACE(1,"BT_DRV:use AGC mode=%d[1:HW,0:SW]",agc_mode); + uint32_t lock = int_lock_global(); + if(agc_mode == BT_AGC_MODE_HW) + { +#ifdef __HW_AGC__ + bt_drv_reg_op_hw_sw_agc_select(BT_AGC_MODE_HW); + for(i=0; i< sizeof(rf_init_tbl_1_hw_agc)/sizeof(rf_init_tbl_1_hw_agc[0]); i++) + { + btdrv_write_rf_reg(rf_init_tbl_1_hw_agc[i][0],rf_init_tbl_1_hw_agc[i][1]); + if(rf_init_tbl_1_hw_agc[i][2] !=0) + btdrv_delay(rf_init_tbl_1_hw_agc[i][2]);//delay + } +#endif + } + else + { + bt_drv_reg_op_hw_sw_agc_select(BT_AGC_MODE_SW); + for(i=0; i< sizeof(rf_init_tbl_1_sw_agc)/sizeof(rf_init_tbl_1_sw_agc[0]); i++) + { + btdrv_write_rf_reg(rf_init_tbl_1_sw_agc[i][0],rf_init_tbl_1_sw_agc[i][1]); + if(rf_init_tbl_1_sw_agc[i][2] !=0) + btdrv_delay(rf_init_tbl_1_sw_agc[i][2]);//delay + } + } + int_unlock_global(lock); + } +} + +void bt_drv_select_agc_mode(enum BT_WORK_MODE_T mode) +{ +#ifdef __HYBIRD_AGC__ + enum BT_AGC_MODE_T agc_mode = BT_AGC_MODE_SW; + switch(mode) + { + case BT_IDLE_MODE: + agc_mode = BT_AGC_MODE_HW; + break; + case BT_A2DP_WORK_MODE: + case BT_HFP_WORK_MODE: + agc_mode = BT_AGC_MODE_SW; + break; + default: + BT_DRV_TRACE(1,"BT_DRV:set error mork mode=%d",mode); + break; + } + + bt_drv_switch_hw_sw_agc(agc_mode); +#endif +} + +static uint16_t efuse; +static int16_t rf18b_6_4, rf18b_10_8, rf18b_14_12; +#define TX_POWET_CALIB_FACTOR 0x2 + +static int check_btpower_efuse_invalid(void) +{ + pmu_get_efuse(PMU_EFUSE_PAGE_BT_POWER, &efuse); + BT_DRV_TRACE(1,"efuse_8=0x%x",efuse); + + rf18b_6_4 = (efuse & 0x70) >> 4; //address_8 [6:4] + rf18b_10_8 = (efuse & 0x700) >> 8; //address_8 [10:8] + rf18b_14_12 = (efuse & 0x7000) >> 12; //address_8 [14:12] + + if((0 == efuse) || + (rf18b_6_4 > 5) || + (rf18b_10_8 > 5) || + (rf18b_14_12 > 5)) + { + BT_DRV_TRACE(0,"invalid efuse value."); + return 0; + } + + return 1; +} + +void bt_drv_tx_pwr_init(void) +{ + //ble txpower need modify ble tx idx @ bt_drv_config.c + //modify bit4~7 to change ble tx gain + btdrv_write_rf_reg(0x189, 0x0071); // min tx gain 2019.02.26 + btdrv_write_rf_reg(0x18a, 0x0071); // mid tx gain 2019.02.26 + if (0 == check_btpower_efuse_invalid()) + btdrv_write_rf_reg(0x18b, 0x0071); // max tx gain 2019.02.26 +} + +void bt_drv_tx_pwr_init_for_testmode(void) +{ + //ble txpower need modify ble tx idx @ bt_drv_config.c + //modify bit4~7 to change ble tx gain + btdrv_write_rf_reg(0x189, 0x007a); // min tx gain 2019.02.26 + btdrv_write_rf_reg(0x18a, 0x0076); // mid tx gain 2019.02.26 + if (0 == check_btpower_efuse_invalid()) + btdrv_write_rf_reg(0x18b, 0x0071); // max tx gain 2019.02.26 +} + +void btdrv_txpower_calib(void) +{ + uint16_t rf92_11_8; + uint16_t tmp_val; + int16_t average_value; //may be negative, so use signed numbers + uint16_t read_value; + + uint16_t bit7_symbol, bit11_symbol, bit15_symbol; + + if(0 == check_btpower_efuse_invalid()) + return; + + bit7_symbol = (efuse & 0x80) >> 4; + bit11_symbol = (efuse & 0x800) >> 8; + bit15_symbol = (efuse & 0x8000) >> 12; + rf92_11_8 = efuse & 0xf; //address_8 [3:0] + + BT_DRV_TRACE(3, "bit7_symbol=%d, bit11_symbol=%d, bit15_symbol=%d", + bit7_symbol, + bit11_symbol, + bit15_symbol); + BT_DRV_TRACE(4, "rf92_11_8=%x, rf18b_6_4=%x, rf18b_10_8=%x, rf18b_14_12=%x", + rf92_11_8, + rf18b_6_4, + rf18b_10_8, + rf18b_14_12); + + rf18b_6_4 = (bit7_symbol == 0) ? rf18b_6_4 : -rf18b_6_4; + rf18b_10_8 = (bit11_symbol == 0) ? rf18b_10_8 : -rf18b_10_8; + rf18b_14_12 = (bit15_symbol == 0) ? rf18b_14_12 : -rf18b_14_12; + + //set 0x92[11:8] begin + btdrv_read_rf_reg(0x92,&tmp_val); + BT_DRV_TRACE(1,"read reg 0x92 val=%x",tmp_val); + tmp_val &= 0xf0ff; //clear [11:8] + tmp_val |= ((rf92_11_8 & 0xffff) << 8); //set efuse[3:0] to rf_92 [11:8] + BT_DRV_TRACE(2,"%d write reg 0x92 val=%x",__LINE__,tmp_val); + btdrv_write_rf_reg(0x92,tmp_val); + //set 0x92[11:8] end + + //set 0x18b[3:0] begin + btdrv_read_rf_reg(0x18b, &read_value); //0x18b + + average_value = (int16_t)(( (float)(rf18b_6_4 + rf18b_10_8 + rf18b_14_12) / 6.f) + 0.5f); + BT_DRV_TRACE(2,"calc average_value=0x%x, dec:%d",average_value, average_value); + + if(0 < average_value) + { + btdrv_read_rf_reg(0x92,&tmp_val); + tmp_val &= 0x0fff; //clear [15:12] + + if(1 == average_value) + { + tmp_val |= ((0x8 & 0xffff) << 12); + } + else //average_value [2,~] + { + tmp_val |= ((0xA & 0xffff) << 12); + } + BT_DRV_TRACE(2,"%d write reg 0x92 val=%x",__LINE__,tmp_val); + btdrv_write_rf_reg(0x92,tmp_val); + } + + tmp_val = TX_POWET_CALIB_FACTOR - average_value; + if(average_value > TX_POWET_CALIB_FACTOR) + tmp_val = 0; + + BT_DRV_TRACE(1,"finally tmp_val=%x",tmp_val); + + read_value &= 0xff00; //clear [3:0] & [7:4] + read_value |= (tmp_val | (0x7 << 4)); //get 0x18b [3:0] & [7:4] + btdrv_write_rf_reg(0x18b,read_value); + BT_DRV_TRACE(1,"write reg 0x18b val=0x%x",read_value); + //set 0x18b[3:0] end +} diff --git a/platform/drivers/bt/best2300p/bt_drv_uart_bridge_intsys.c b/platform/drivers/bt/best2300p/bt_drv_uart_bridge_intsys.c new file mode 100644 index 0000000..e90b18a --- /dev/null +++ b/platform/drivers/bt/best2300p/bt_drv_uart_bridge_intsys.c @@ -0,0 +1,220 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "stdbool.h" +#include "hal_intersys.h" +#include "hal_iomux.h" +#include "hal_uart.h" +#include "hal_trace.h" +#include "string.h" +#include "hal_chipid.h" +#include "heap_api.h" +#include "bt_drv.h" +#include "bt_drv_2300p_internal.h" +#include "bt_drv.h" +#include "bt_drv_interface.h" + +#define BT_UART_BRIDGE_BUF_LEN (1024) + +static const struct HAL_UART_CFG_T uart_cfg = { + .parity = HAL_UART_PARITY_NONE, + .stop = HAL_UART_STOP_BITS_1, + .data = HAL_UART_DATA_BITS_8, + .flow = HAL_UART_FLOW_CONTROL_NONE, + .tx_level = HAL_UART_FIFO_LEVEL_1_2, + .rx_level = HAL_UART_FIFO_LEVEL_1_4, + .baud = 115200, + .dma_rx = true, + .dma_tx = true, + .dma_rx_stop_on_err = false, +}; + +#if (DEBUG_PORT == 1) +enum HAL_UART_ID_T br_uart = HAL_UART_ID_0; +#else +enum HAL_UART_ID_T br_uart = HAL_UART_ID_1; +#endif +enum HAL_INTERSYS_ID_T br_intersys = HAL_INTERSYS_ID_0; + +static volatile bool uart_rx_done = false; +static volatile bool uart_tx_done = false; +static volatile bool bt_rx_done = false; +static volatile bool bt_tx_done = false; + +static unsigned char *uart_rx_data_p; +static volatile unsigned int uart_rx_len = 0; + +static unsigned char *bt_rx_data_p; +static volatile unsigned int bt_rx_len = 0; + +static void uart_rx(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status) +{ + if (dma_error) { + BT_DRV_TRACE(1,"uart_rx dma error: xfer_size=%d", xfer_size); + uart_rx_len = 0; + } else if (status.BE || status.FE || status.OE || status.PE) { + BT_DRV_TRACE(2,"uart_rx uart error: xfer_size=%d, status=0x%08x", xfer_size, status.reg); + uart_rx_len = 0; + } else { + uart_rx_len = xfer_size; + } + uart_rx_done = true; +} + +static void uart_tx(uint32_t xfer_size, int dma_error) +{ + if (dma_error) { + BT_DRV_TRACE(1,"uart_tx dma error: xfer_size=%d", xfer_size); + } + uart_tx_done = true; +} + +#ifdef VCO_TEST_TOOL +static unsigned int bt_rx(const unsigned char *data, unsigned int len); + +void vco_test_simu_bt_rx(void) +{ + const unsigned char hci_bt_vco_test_event[] = {0x04, 0x0e, 0x04, 0x05, 0xaa,0xfc,0x00}; + bt_rx(hci_bt_vco_test_event, sizeof(hci_bt_vco_test_event)); +} +#endif + +static unsigned int bt_rx(const unsigned char *data, unsigned int len) +{ + unsigned int processed = len; + + + hal_intersys_stop_recv(br_intersys); + if (bt_rx_len + processed > BT_UART_BRIDGE_BUF_LEN) { + BT_DRV_TRACE(3,"bt_rx data too long: bt_rx_len=%d, len=%d, limit=%d", bt_rx_len, processed, sizeof(bt_rx_data_p)); + processed = BT_UART_BRIDGE_BUF_LEN-bt_rx_len; + } + if (processed > 0) { + memcpy(bt_rx_data_p + bt_rx_len, data, processed); + if((data[0] == 0x4) && (data[2] == 0xc) && (data[4] == 0x1) && (data[5] == 0x10)) + { + *(uint8_t *)(bt_rx_data_p + bt_rx_len+7) = 0x09; + *(uint8_t *)(bt_rx_data_p + bt_rx_len+10) = 0x09; + } + if(data[0] == 0x4 && data[1] == 0xe && data[4] == 0x3 && data[5] == 0xc) + { + memset((uint32_t *)BT_EM_ADDR_BASE,0,BT_EM_SIZE/4); + *(uint32_t *)0xd02201e4 = 0; + } + BT_DRV_TRACE(0,"[TX]:"); + DUMP8("%02x ",bt_rx_data_p + bt_rx_len,processed); + bt_rx_len += processed; + bt_rx_done = true; + } + return len; +} + +static void bt_tx(const unsigned char *data, unsigned int len) +{ + bt_tx_done = true; +} + +void btdrv_uart_bridge_loop(void) +{ + int ret; + union HAL_UART_IRQ_T mask; + + syspool_init(); + + syspool_get_buff(&uart_rx_data_p, BT_UART_BRIDGE_BUF_LEN); + syspool_get_buff(&bt_rx_data_p, BT_UART_BRIDGE_BUF_LEN); + + if (br_uart == HAL_UART_ID_0) { + hal_iomux_set_uart0(); + hal_trace_switch(HAL_TRACE_TRANSPORT_UART1); + hal_iomux_set_uart1(); + } else { + hal_iomux_set_uart1(); + hal_trace_switch(HAL_TRACE_TRANSPORT_UART0); + //hal_iomux_set_uart0(); + } + + ret = hal_uart_open(br_uart, &uart_cfg); + if (ret) { + BT_DRV_TRACE(0,"Failed to open uart"); + return; + } + + hal_uart_irq_set_dma_handler(br_uart, uart_rx, uart_tx); + mask.reg = 0; + mask.BE = 1; + mask.FE = 1; + mask.OE = 1; + mask.PE = 1; + mask.RT = 1; + hal_uart_dma_recv_mask(br_uart, uart_rx_data_p, BT_UART_BRIDGE_BUF_LEN, NULL, NULL,&mask); + + ret = hal_intersys_open(br_intersys, HAL_INTERSYS_MSG_HCI, bt_rx, bt_tx, false); + if (ret) { + BT_DRV_TRACE(0,"Failed to open intersys"); + return; + } + hal_intersys_start_recv(br_intersys); + BT_DRV_TRACE(0,"Enter bridge mode"); + + while (1) { + if (uart_rx_done) { + uart_rx_done = false; + if (uart_rx_len > 0) { + BT_DRV_TRACE(0,"[RX]:"); + DUMP8("%02x ",uart_rx_data_p,uart_rx_len); +#ifdef LAURENT_ALGORITHM + btdrv_ble_test_bridge_intsys_callback(uart_rx_data_p); +#endif + +#ifdef VCO_TEST_TOOL + if(btdrv_vco_test_bridge_intsys_callback(uart_rx_data_p)) + { + uart_rx_len =0; + continue ; + } +#endif + hal_intersys_send(br_intersys, HAL_INTERSYS_MSG_HCI, uart_rx_data_p, uart_rx_len); + } else { + bt_tx_done = true; + } + } + if (uart_tx_done) { + uart_tx_done = false; + bt_rx_len = 0; + hal_intersys_start_recv(br_intersys); + } + if (bt_rx_done) { + bt_rx_done = false; + if (bt_rx_len > 0) { + hal_uart_dma_send(br_uart, bt_rx_data_p, bt_rx_len, NULL, NULL); + } else { + uart_tx_done = true; + } + } + if (bt_tx_done) { + bt_tx_done = false; + hal_uart_dma_recv_mask(br_uart, uart_rx_data_p, BT_UART_BRIDGE_BUF_LEN, NULL, NULL,&mask); + } +#ifdef VCO_TEST_TOOL + if(btdrv_get_vco_test_process_flag()) + { + btdrv_vco_test_process(btdrv_get_vco_test_process_flag()); + vco_test_simu_bt_rx(); + } +#endif + } +} + diff --git a/platform/drivers/bt/best2300p/iqcorrect.c b/platform/drivers/bt/best2300p/iqcorrect.c new file mode 100644 index 0000000..d243a2f --- /dev/null +++ b/platform/drivers/bt/best2300p/iqcorrect.c @@ -0,0 +1,985 @@ +#ifdef RTOS + +#include +#include + +#include "hal_dma.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "heap_api.h" + +#include "string.h" +#include "bt_drv.h" +#include "cmsis_os.h" +#include "hal_btdump.h" +#include "iqcorrect.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#ifdef TX_IQ_CAL +#define LOG_MODULE HAL_TRACE_MODULE_APP + +#define NTbl (1024) +#define fftSize 1024 + +#define bitshift 10 +#define pi (3.1415926535898) +#define min(a,b) (((a) < (b)) ? (a) : (b)) + +#define READ_REG(b,a) *(volatile uint32_t *)(b+a) +#define WRITE_REG(v,b,a) *(volatile uint32_t *)(b+a) = v + +#define BUF_SIZE (1024) + +#define MAX_COUNT 5 +volatile int iqimb_dma_status = 0; +//short M0data[BUF_SIZE]; +#define MED_MEM_POOL_SIZE (20*1024) +static uint8_t *g_medMemPool = NULL; + +extern void *rt_malloc(unsigned int size); +extern void rt_free(void *rmem); + +typedef struct ComplexInt_ +{ + int re; + int im; +} ComplexInt; +typedef struct Complexflt_ +{ + float re; + float im; +} ComplexFlt; +typedef struct ComplexShort_ +{ + short re; + short im; +} ComplexShort; + +#ifdef DCCalib +static void Tblgen(ComplexShort*w0, ComplexShort*w1, ComplexShort*w2,int len) +{ + for (int i=0; iM0data = (short*)med_calloc(fft_size, sizeof(short)); + st->Table0 = (ComplexShort*)med_calloc(fft_size, sizeof(ComplexShort)); + st->Table1 = (ComplexShort*)med_calloc(fft_size, sizeof(ComplexShort)); + st->Table2 = (ComplexShort*)med_calloc(fft_size, sizeof(ComplexShort)); + BT_DRV_TRACE(5,"st:%p, st->M0data:%p, st->Table0:%p, st->Table1:%p, st->Table2:%p", st, st->M0data, st->Table0, st->Table1, st->Table2); + BT_DRV_TRACE(0,"malloc ok"); + return st; +} + +int32_t IQMismatchPreprocessState_destroy(IQMismatchPreprocessState *st) +{ + BT_DRV_TRACE(5,"st:%p, st->M0data:%p, st->Table0:%p, st->Table1:%p, st->Table2:%p", st, st->M0data, st->Table0, st->Table1, st->Table2); + med_free(st->M0data); + med_free(st->Table0); + med_free(st->Table1); + med_free(st->Table2); + med_free(st); + return 0; +} + +int IQMismatchParameterCalc_ex(short *M0data, + short Cohcnt, ComplexShort *Table0, ComplexShort *Table1, ComplexShort *Table2,int fftsize) +{ + int i,j,k; + float M0 = 0; + //ComplexInt tmp0; + ComplexFlt tmp0; + ComplexFlt tmp1; + ComplexFlt tmp2; + for (j = 0; j < Cohcnt; j++) + { + tmp0.re = 0.0f; + tmp0.im = 0.0f; + tmp1.re = 0.0f; + tmp1.im = 0.0f; + tmp2.re = 0.0f; + tmp2.im = 0.0f; + k = 0; + for (i=0; i=fftsize) + k = 0; + tmp0.re = tmp0.re + (((int)M0data[i] *(int)Table0[k].re) >> 15) ; + tmp0.im = tmp0.im + (((int)M0data[i] * (int)Table0[k].im) >> 15) ; + tmp1.re = tmp1.re + (((int)M0data[i] *(int)Table1[k].re) >> 15) ; + tmp1.im = tmp1.im + (((int)M0data[i] * (int)Table1[k].im) >> 15) ; + tmp2.re = tmp2.re + (((int)M0data[i] *(int)Table2[k].re) >> 15) ; + tmp2.im = tmp2.im + (((int)M0data[i] * (int)Table2[k].im) >> 15) ; + k = k + 1; + } + tmp0.re = tmp0.re/ fftsize;// >> bitshift; + tmp0.im = tmp0.im/ fftsize;// >>bitshift; + tmp1.re = tmp1.re/ fftsize;// >> bitshift; + tmp1.im = tmp1.im/ fftsize;// >>bitshift; + tmp2.re = tmp2.re/ fftsize;// >> bitshift; + tmp2.im = tmp2.im/ fftsize;// >>bitshift; + M0 = M0 + tmp0.re*tmp0.re + tmp0.im*tmp0.im; + M0 = M0 + tmp1.re*tmp1.re + tmp1.im*tmp1.im; + M0 = M0 + tmp2.re*tmp2.re + tmp2.im*tmp2.im; + } + return (int)(M0/Cohcnt); +} + + +void caculate_energy_main_test(IQMismatchPreprocessState *st,int* Energy,int* Energy1,int fftsize) +{ + short Cohcnt = 1; + *Energy1 = IQMismatchParameterCalc_ex(st->M0data, Cohcnt, st->Table0, st->Table1, st->Table2,fftsize); +} + +static struct HAL_DMA_DESC_T iqimb_dma_desc[1]; + + +static void iqimb_dma_dout_handler(uint32_t remains, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + hal_audma_free_chan(0); + hal_btdump_disable(); + iqimb_dma_status = 0; + + return; +} + +int bt_iqimb_dma_enable ( short * dma_dst_data, uint16_t size) +{ + struct HAL_DMA_CH_CFG_T iqimb_dma_cfg; + // BT_DRV_TRACE(0,"bt_iqimb_dma_enable :"); + + iqimb_dma_status = 1; + + memset(&iqimb_dma_cfg, 0, sizeof(iqimb_dma_cfg)); + + //iqimb_dma_cfg.ch = hal_audma_get_chan(HAL_AUDMA_DSD_RX,HAL_DMA_HIGH_PRIO); + + iqimb_dma_cfg.ch = hal_audma_get_chan(HAL_AUDMA_BTDUMP,HAL_DMA_HIGH_PRIO); + iqimb_dma_cfg.dst_bsize = HAL_DMA_BSIZE_16; + iqimb_dma_cfg.dst_periph = 0; //useless + iqimb_dma_cfg.dst_width = HAL_DMA_WIDTH_WORD; + iqimb_dma_cfg.handler = (HAL_DMA_IRQ_HANDLER_T)iqimb_dma_dout_handler; + iqimb_dma_cfg.src = 0; // useless + iqimb_dma_cfg.src_bsize = HAL_DMA_BSIZE_4; + + //iqimb_dma_cfg.src_periph = HAL_AUDMA_DSD_RX; + iqimb_dma_cfg.src_periph = HAL_AUDMA_BTDUMP; + iqimb_dma_cfg.src_tsize = size;//1600; //1600*2/26=123us + iqimb_dma_cfg.src_width = HAL_DMA_WIDTH_WORD; + //iqimb_dma_cfg.src_width = HAL_DMA_WIDTH_HALFWORD; + iqimb_dma_cfg.try_burst = 1; + iqimb_dma_cfg.type = HAL_DMA_FLOW_P2M_DMA; + iqimb_dma_cfg.dst = (uint32_t)(dma_dst_data); + + hal_audma_init_desc(&iqimb_dma_desc[0], &iqimb_dma_cfg, 0, 1); + + hal_audma_sg_start(&iqimb_dma_desc[0], &iqimb_dma_cfg); + + //configed after mismatch parameter done, or apb clock muxed. + + //wait + for(volatile int i=0; i<5000; i++); + hal_btdump_enable(); + + return 1; + +} + +int bt_iqimb_ini () +{ + uint32_t val; + + BT_DRV_TRACE(0,"bt_iqimb_ini :"); + //config gpadc 26m + val = READ_REG(0xd0350208,0x0); + val &= 0xffefffff; //bit20 + val |= (1<<18); //reg_gclk_en(BTM_CLK_26RXNFMI) + val &= 0xffbfffff; //bit22 + val |= (1<<20); //reg_gclk_en(BTM_CLK_26RXDUMP) + val &= 0xfdffffff; //bit25 + val |= (1<<25); //reg_gclk_en(BTM_CLK_26RXADC) + WRITE_REG(val,0xd0350208,0x0); + BT_DRV_TRACE(1,"0xd0350208 : 0x%08x",val); + + val = READ_REG(0xd0350228,0x0); + val &= 0xffefffff; //bit20 + val |= (1<<18); //reg_gclk_mode(BTM_CLK_26RXNFMI) + val &= 0xffbfffff; //bit22 + val |= (1<<20); //reg_gclk_mode(BTM_CLK_26RXDUMP) + val &= 0xfdffffff; //bit25 + val |= (1<<25); //reg_gclk_mode(BTM_CLK_26RXADC) + WRITE_REG(val,0xd0350228,0x0); + BT_DRV_TRACE(1,"0xd0350228 : 0x%08x",val); + + //for rx mux to gpadc + val = READ_REG(0xd0350218,0x0); + val &= 0xfffffff0; //bit3:0 1110 reg_diagcntl(3 downto 0) + val |= (0xe<<0); + val &= 0xfffffbff; //bit10 1 reg_diagcntl(10) + val |= (0x1<<10); + WRITE_REG(val,0xd0350218,0x0); + + BT_DRV_TRACE(1,"0xd0350218 : 0x%08x",val); + + + val = READ_REG(0xd0330024,0x0); + val &= 0xfffffff7; //bit3:0 1110 reg_diagcntl(3 downto 0) + val |= (0x1<<15); + WRITE_REG(val,0xd0330024,0x0); + BT_DRV_TRACE(1,"0xd0330024 : 0x%08x",val); + + + val = READ_REG(0xd0330034,0x0); + val &= 0x03ffffff; //bit3:0 1110 reg_diagcntl(3 downto 0) + val |= (0x1b<<26); + WRITE_REG(val,0xd0330034,0x0); + + BT_DRV_TRACE(1,"0xd0330034 : 0x%08x",val); + + WRITE_REG(0x002eb948,0xd0350364,0x0); + + + val = READ_REG(0xd0330038,0x0); + + val |= (0x1<<24); + WRITE_REG(val,0xd0330038,0x0); + + + WRITE_REG(0,0xc000033c,0x0); + return 1; +} +void check_mem_data(void* data, int len) +{ + short* share_mem = (short*)data; + BT_DRV_TRACE(3,"check_mem_data :share_mem= %p, 0x%x, 0x%x",share_mem,share_mem[0],share_mem[1]); + + int16_t i =0; + int16_t m =0; + int16_t remain = len; + for(m=0; m<32; m++) + { + for(i=0; i<32; i++) + { + + if (remain >16) + { + DUMP16("%04x ",share_mem,16); + share_mem +=16; + remain -= 16; + } + else + { + DUMP16("%04x ",share_mem,remain); + + remain =0; + return; + } + + } + // BT_DRV_TRACE(0,"\n"); + //BT_DRV_TRACE(1,"addr :0x%08x\n",share_mem); + hal_sys_timer_delay(MS_TO_TICKS(200)); + } + + + +} + +int bt_Txdc_cal_set(int ch_num, int dc_add) +{ + uint32_t val; + uint32_t tmp = (uint32_t)dc_add; + //sel apb clock + val = READ_REG(0xd0350348,0x0); + if(ch_num==0) + { + val &= 0xfffffc00; //bit31 1 int_en_mismatch + val |= tmp & 0x3ff; + } + else + { + // BT_DRV_TRACE(1,"bt_Txdc_cal_set, dcadd : 0x%08x",tmp); + val &= 0xfc00ffff; //bit31 1 int_en_mismatch + val |= (tmp & 0x3ff) <<16; + } + WRITE_REG(val,0xd0350348,0x0); + + + // BT_DRV_TRACE(1,"bt_Txdc_cal_set, 0xd0350348 : 0x%08x",val); + + return 1; +} + +//g/p mismatch base addr 0xd0310000 +//dc_i: 0xd0350348 9:0 +//dc_q: 0xd0350348 25:16 +int bt_iqimb_add_mismatch(int ch_num, int gain_mis, int phase_mis, int dc_i, int dc_q, uint32_t addr) +{ + uint32_t val; + //sel apb clock + val = READ_REG(0xd0350348,0x0); + val &= 0x7fffffff; //bit31 1 int_en_mismatch + val |= (0x0<<31); + WRITE_REG(val,0xd0350348,0x0); + + val = (phase_mis << 16) | (gain_mis & 0x0000ffff); + WRITE_REG(val,addr,ch_num*4); + //tval = READ_REG(addr,0x0); + //BT_DRV_TRACE(1,"bt_iqimb_add_mismatch, iq : 0x%08x",tval); + + WRITE_REG(0x400000,0xd0350220,0); + WRITE_REG(0x400000,0xd0350224,0); + // bt_Txdc_cal_set(0,dc_i); + //bt_Txdc_cal_set(1,dc_q); + + /* + val = READ_REG(0xd0350348,0x0); + val &= 0xfffffc00; //bit9:0 + val |= dc_i; + val &= 0xfc00ffff; //bit25:16 + val |= (dc_q<<16); + WRITE_REG(val,0xd0350348,0x0); + */ + //sel 26m clock + val = READ_REG(0xd0350348,0x0); + val &= 0x7fffffff; //bit31 1 int_en_mismatch + val |= (0x1<<31); + WRITE_REG(val,0xd0350348,0x0); + + return 1; +} + +void DC_correction(IQMismatchPreprocessState *st,int *dc_i_r,int *dc_q_r,int fftsize) +{ + uint8_t k; + int Energy,Energy1,tmp; + int dc_iters = 2; + int dc_i; + int dc_q; + int dc_step = 4; + int dc_i_base; + int dc_q_base; + int P0,PIplus,PIneg,PQplus,PQneg,PIPQ; + int CI,CQ,tmp_D; + dc_i_base =0; + dc_q_base = 0; + for(k=0; kM0data,(BUF_SIZE/2)); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + P0 = Energy1; + dc_i = dc_i_base + dc_step; + dc_q = dc_q_base; + bt_Txdc_cal_set(0,dc_i); + bt_Txdc_cal_set(1,dc_q); + bt_iqimb_dma_enable(st->M0data,(BUF_SIZE/2)); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + PIplus = Energy1; + dc_i = dc_i_base - dc_step; + dc_q = dc_q_base; + bt_Txdc_cal_set(0,dc_i); + bt_Txdc_cal_set(1,dc_q); + bt_iqimb_dma_enable(st->M0data,(BUF_SIZE/2)); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + PIneg = Energy1; + dc_i = dc_i_base; + dc_q = dc_q_base + dc_step; + bt_Txdc_cal_set(0,dc_i); + bt_Txdc_cal_set(1,dc_q); + bt_iqimb_dma_enable(st->M0data,(BUF_SIZE/2)); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + PQplus = Energy1; + dc_i = dc_i_base; + dc_q = dc_q_base - dc_step; + bt_Txdc_cal_set(0,dc_i); + bt_Txdc_cal_set(1,dc_q); + bt_iqimb_dma_enable(st->M0data,(BUF_SIZE/2)); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + PQneg = Energy1; + dc_i = dc_i_base + dc_step; + dc_q = dc_q_base + dc_step; + bt_Txdc_cal_set(0,dc_i); + bt_Txdc_cal_set(1,dc_q); + bt_iqimb_dma_enable(st->M0data,(BUF_SIZE/2)); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + PIPQ = Energy1; + tmp = 2*PIplus*PIplus + 2*PQplus*PQplus + 2*PIPQ*PIPQ; + tmp = tmp - 6*P0*P0; + tmp = tmp + 4*P0*(PIneg+PQneg+PIPQ); + tmp = tmp + 2*(PIplus*(PQplus - PQneg)-PIneg*(PQplus+PQneg)); + tmp_D = tmp - 4*PIPQ*(PIplus+PQplus); + tmp = P0*(2*(PIplus - PIneg)+PQplus -PQneg); + tmp = tmp - PIPQ*(PQneg-PQplus)+PIneg*(PQplus+PQneg); + tmp = tmp + PQplus*(PQneg-PQplus-2*PIplus); + CI = -dc_step*tmp; + tmp = P0*(2*(PQplus - PQneg)+PIplus-PIneg); + tmp = tmp - PIPQ*(PIneg-PIplus)+PQneg*(PIplus+PIneg); + tmp = tmp + PIplus*(PIneg-PIplus-2*PQplus); + CQ = -dc_step*tmp; + dc_i_base = dc_i_base + CI/tmp_D; + dc_q_base = dc_q_base + CQ/tmp_D; + //dc_step = dc_step/2; + } + *dc_i_r = dc_i_base; + *dc_q_r = dc_q_base; +} +int IQ_GAIN_Mismatch_Correction(IQMismatchPreprocessState *st,int phase_mis_base,int fftsize,uint32_t addr) +{ + uint8_t k = 0; + int phase_mis_tmp =0; + int gain_mis_tmp =0; + int tmp = 0; + int energy_ret0_last = 1048576; + int energy_ret0 = 0; + int energy_ret1 = 0; + int energy_ret2 = 0; + int Energy,Energy1 ; + int iters = 4; + int gainstep =8; + int gain_mis_base = 0; + + phase_mis_tmp = phase_mis_base; + energy_ret0_last = 1048576; + for(k=0; kM0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + energy_ret0 = Energy1; + if(energy_ret0<50) + break; + if(k>0) + { + if(energy_ret0_last < energy_ret0) + { + gain_mis_base = gain_mis_base + tmp; + gain_mis_tmp = gain_mis_base; + bt_iqimb_add_mismatch(0,gain_mis_tmp,phase_mis_tmp,0,0,addr); + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + energy_ret0 = Energy1; + } + } + //BT_DRV_TRACE(1,"IQ gain correct energy_ret0 = %d",energy_ret0); + gainstep = 4;/////////////////// + gain_mis_tmp = gain_mis_base + gainstep; + bt_iqimb_add_mismatch(0,gain_mis_tmp,phase_mis_tmp,0,0,addr); + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + energy_ret2 = Energy1; + gain_mis_tmp = gain_mis_base - gainstep; + bt_iqimb_add_mismatch(0,gain_mis_tmp,phase_mis_tmp,0,0,addr); + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + energy_ret1 = Energy1; + tmp = energy_ret2 -2*energy_ret0 + energy_ret1; + //BT_DRV_TRACE(1,"IQ gain correct energy_ret2 -2*energy_ret0 + energy_ret1 = %d",tmp); + if(tmp>0) + { + tmp = (energy_ret2-energy_ret1)*gainstep/tmp/2; + tmp = min(tmp,4*gainstep); + gainstep = gainstep/2; + } + else + { + tmp = 0; + iters = iters+1; + } + if(iters>8) + break; + if((gain_mis_base - tmp>60)||(gain_mis_base - tmp<-60)) + tmp = 0; + //BT_DRV_TRACE(2,"IQ gain correct gain_mis = %d ,gain_adj = %d",gain_mis_base,tmp); + gain_mis_base = gain_mis_base - tmp; + energy_ret0_last = energy_ret0; + } + return gain_mis_base; +} +int IQ_Phase_Mismatch_Correction(IQMismatchPreprocessState *st,int gain_mis_base,int fftsize,uint32_t addr) +{ + uint8_t k = 0; + int phase_mis_tmp =0; + int gain_mis_tmp =0; + int tmp = 0; + int energy_ret0_last = 1048576; + int energy_ret0 = 0; + int energy_ret1 = 0; + int energy_ret2 = 0; + int Energy,Energy1 ; + int iters = 4; + int phasestep =4; + int phase_mis_base = 0; + tmp = 0; + energy_ret0_last = 1048576; + gain_mis_tmp = gain_mis_base; + for(k=0; kM0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + energy_ret0 = Energy1; + if(k>0) + { + if(energy_ret0_last < energy_ret0) + { + phase_mis_base = phase_mis_base + tmp; + phase_mis_tmp = phase_mis_base; + bt_iqimb_add_mismatch(0,gain_mis_tmp,phase_mis_tmp,0,0,addr); //no mismatch + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + energy_ret0 = Energy1; + } + } + if(energy_ret0<50) + break; + // BT_DRV_TRACE(1,"IQ phase correct energy_ret0 = %d",energy_ret0); + phasestep = 4;////////////////////////// + phase_mis_tmp = phase_mis_base + phasestep; + bt_iqimb_add_mismatch(0,gain_mis_tmp,phase_mis_tmp,0,0,addr); //no mismatch + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + energy_ret2 = Energy1; + // BT_DRV_TRACE(1,"IQ phase correct energy_ret2 = %d",energy_ret2); + phase_mis_tmp = phase_mis_base - phasestep; + bt_iqimb_add_mismatch(0,gain_mis_tmp,phase_mis_tmp,0,0,addr); //no mismatch + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + energy_ret1 = Energy1; + //BT_DRV_TRACE(1,"IQ phase correct energy_ret1 = %d",energy_ret1); + tmp = energy_ret2 -2*energy_ret0 + energy_ret1; + // BT_DRV_TRACE(1,"IQ phase correct energy_ret2 -2*energy_ret0 + energy_ret1 = %d",tmp); + if(tmp>0) + { + tmp = (energy_ret2-energy_ret1)*phasestep/tmp/2; + tmp = min(tmp,4*phasestep); + phasestep = phasestep/2; + } + else + { + tmp = 0; + iters = iters + 1; + } + if(iters>8) + break; + if((phase_mis_base - tmp>60)||(phase_mis_base - tmp<-60)) + tmp = 0; + // BT_DRV_TRACE(2,"IQ phase correct phase_mis = %d ,phase_adj = %d",phase_mis_base,tmp); + phase_mis_base = phase_mis_base - tmp; + energy_ret0_last = energy_ret0; + + } + return phase_mis_base; +} + +static BT_IQ_CALIBRATION_CONFIG_T config; + +static void bt_update_local_iq_calibration_val(uint32_t freq_range, uint16_t gain_cal_val, uint16_t phase_cal_val) +{ + config.validityMagicNum = BT_IQ_VALID_MAGIC_NUM; + config.gain_cal_val[freq_range] = gain_cal_val; + config.phase_cal_val[freq_range] = phase_cal_val; +} + +// do QA calibration and get the calibration value +static POSSIBLY_UNUSED void btIqCalibration(void) +{ + btdrv_tx_iq_cal(); + BT_DRV_TRACE(0,"Acquired calibration value:"); + for (uint32_t range = 0;range < BT_FREQENCY_RANGE_NUM;range++) + { + BT_DRV_TRACE(3,"%d: 0x%x - 0x%x", range, + config.gain_cal_val[range], + config.phase_cal_val[range]); + } +} + +// get IQ calibration from NV +static bool bt_get_iq_calibration_val_from_nv(BT_IQ_CALIBRATION_CONFIG_T* pConfig) +{ + if (nv_record_get_extension_entry_ptr() && + (BT_IQ_VALID_MAGIC_NUM == + nv_record_get_extension_entry_ptr()->btIqCalConfig.validityMagicNum)) + { + *pConfig = nv_record_get_extension_entry_ptr()->btIqCalConfig; + return true; + } + else + { + return false; + } +} + +void bt_iq_calibration_setup(void) +{ + if (bt_get_iq_calibration_val_from_nv(&config)) + { + BT_DRV_TRACE(0,"Calibration value in NV:"); + + for (uint32_t range = 0;range < BT_FREQENCY_RANGE_NUM;range++) + { + BT_DRV_TRACE(3,"%d: 0x%x - 0x%x", range, + config.gain_cal_val[range], + config.phase_cal_val[range]); + } + uint32_t addr = 0xd0310000; + int chs = 27; + + for (uint32_t range = 0;range < 3;range++) + { + if (0 == range) + { + addr = 0xd0310034; + chs= 27; + addr = addr-13*4; + } + + for (uint32_t ch=0;ch < chs;ch++) + { + bt_iqimb_add_mismatch(0, + config.gain_cal_val[range], + config.phase_cal_val[range], + 0,0,addr); + addr = addr +4; + } + } + } + else + { + btIqCalibration(); + uint32_t lock = nv_record_pre_write_operation(); + nv_record_get_extension_entry_ptr()->btIqCalConfig = config; + nv_record_post_write_operation(lock); + + nv_record_extension_update(); + } +} + +void bt_IQ_DC_Mismatch_Correction_Release() +{ + int phase_mis_base; + int gain_mis_base; + int Energy,Energy1; + uint32_t time_start = hal_sys_timer_get(); + int fftsize; + uint32_t addr = 0xd0310000; + int chs = 27; + IQMismatchPreprocessState *st; + syspool_init(); + syspool_get_buff(&g_medMemPool, MED_MEM_POOL_SIZE); + med_heap_init(&g_medMemPool[0], MED_MEM_POOL_SIZE); + //config gpadc 26m + READ_REG(0xd0310000,0x0); + #ifdef DCCalib + int dc_i_base,dc_q_base; + fftsize = 1024; + st = IQMismatchPreprocessState_init(fftsize); + Tblgen(st->Table0,st->Table1,st->Table2,fftsize); + DC_correction(st,&dc_i_base,&dc_q_base,fftsize); + bt_Txdc_cal_set(0,dc_i_base); //set cal DC I + bt_Txdc_cal_set(1,dc_q_base); + //val = READ_REG(0xd0350348,0x0); + //BT_DRV_TRACE(1,"0xd0350348 = 0x%08x",val); + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); +// BT_DRV_TRACE(3,"dc cal done!!! dc_i = %d ,dc_q = %d,Energy1 = %d",dc_i_base,dc_q_base,Energy1); + if(Energy1>200) + { + DC_correction(st,&dc_i_base,&dc_q_base,fftsize); + bt_Txdc_cal_set(0,dc_i_base); //set cal DC I + bt_Txdc_cal_set(1,dc_q_base); + //val = READ_REG(0xd0350348,0x0); + //BT_DRV_TRACE(1,"0xd0350348 = 0x%08x",val); + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + } + if(Energy1>200) + { + DC_correction(st,&dc_i_base,&dc_q_base,fftsize); + bt_Txdc_cal_set(0,dc_i_base); //set cal DC I + bt_Txdc_cal_set(1,dc_q_base); + //val = READ_REG(0xd0350348,0x0); + //BT_DRV_TRACE(1,"0xd0350348 = 0x%08x",val); + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + } + #endif +// BT_DRV_TRACE(1,"use time: %d ticks", (hal_sys_timer_get()-time_start)); +// BT_DRV_TRACE(3,"dc cal done!!! dc_i = %d ,dc_q = %d,Energy1 = %d",dc_i_base,dc_q_base,Energy1); + fftsize = 1024; + st = IQMismatchPreprocessState_init(fftsize); + Tblgen_iq(st->Table0,st->Table1,st->Table2,fftsize); + BT_DRV_TRACE(1,"use time: %d ms", __TICKS_TO_MS(hal_sys_timer_get()-time_start)); + for (int k = 0; k<3; k++) + { + if(k==0) + { + WRITE_REG(0x0,0xD02201E4,0x0); + WRITE_REG(0x000A000D,0xD02201E4,0x0); + //osDelay(1000); + addr = 0xd0310034; + } + else if(k==1) + { + WRITE_REG(0x0,0xD02201E4,0x0); + WRITE_REG(0x000A0027,0xD02201E4,0x0); + addr = 0xd031009c; + } + else + { + WRITE_REG(0x0,0xD02201E4,0x0); + WRITE_REG(0x000A0041,0xD02201E4,0x0); + addr = 0xd0310104; + } + gain_mis_base = IQ_GAIN_Mismatch_Correction(st,0,fftsize,addr); + phase_mis_base = IQ_Phase_Mismatch_Correction(st,gain_mis_base,fftsize,addr); + bt_iqimb_add_mismatch(0,gain_mis_base,phase_mis_base,0,0,addr); //no mismatch + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); +// BT_DRV_TRACE(4,"IQ phase correct addr = 0x%08x,phase_mis = %d ,gain_mis = %d,Energy = %d",addr,phase_mis_base,gain_mis_base,Energy1); + if(Energy1>500) + { + if(ABS(gain_mis_base)>ABS(phase_mis_base)) + { + gain_mis_base = IQ_GAIN_Mismatch_Correction(st,0,fftsize,addr); + phase_mis_base = IQ_Phase_Mismatch_Correction(st,gain_mis_base,fftsize,addr); + } + else + { + phase_mis_base = IQ_Phase_Mismatch_Correction(st,0,fftsize,addr); + gain_mis_base = IQ_GAIN_Mismatch_Correction(st,phase_mis_base,fftsize,addr); + } + + bt_iqimb_add_mismatch(0,gain_mis_base,phase_mis_base,0,0,addr); //no mismatch +// BT_DRV_TRACE(1,"use time: %d ticks", (hal_sys_timer_get()-time_start)); + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); +// BT_DRV_TRACE(4,"IQ phase correct addr = 0x%08x,phase_mis = %d ,gain_mis = %d,Energy = %d",addr,phase_mis_base,gain_mis_base,Energy1); + } + + if(Energy1>500) + { + if(ABS(gain_mis_base)>ABS(phase_mis_base)) + { + gain_mis_base = IQ_GAIN_Mismatch_Correction(st,0,fftsize,addr); + phase_mis_base = IQ_Phase_Mismatch_Correction(st,gain_mis_base,fftsize,addr); + } + else + { + phase_mis_base = IQ_Phase_Mismatch_Correction(st,0,fftsize,addr); + gain_mis_base = IQ_GAIN_Mismatch_Correction(st,phase_mis_base,fftsize,addr); + } + // BT_DRV_TRACE(1,"use time: %d ticks", (hal_sys_timer_get()-time_start)); + bt_iqimb_dma_enable(st->M0data,fftsize); + while(1) + { + if(iqimb_dma_status==0) + break; + } + caculate_energy_main_test(st,&Energy,&Energy1,fftsize); + // BT_DRV_TRACE(4,"IQ phase correct addr = 0x%08x,phase_mis = %d ,gain_mis = %d,Energy = %d",addr,phase_mis_base,gain_mis_base,Energy1); + } + if(k==0) + { + chs= 27; + addr = addr-13*4; + } + else if(k==1) + { + chs = 26; + addr = addr - 12*4; + } + else + { + chs = 26; + addr = addr -12*4; + } + + bt_update_local_iq_calibration_val(k, gain_mis_base, phase_mis_base); + + for (int ch=0; ch300)TRACE(2,"%s exit, %dus",__func__, spent_time);}while(0); + +#define SBC_PKT_TYPE_DM1 0x3 +#define SBC_PKT_TYPE_2EV3 0x6 +#define SBC_PKT_TYPE_2DH5 0xe + +#define BT_ACL_CONHDL_BIT (0x80) + +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST2001) +#define BTDRV_ISPI_RF_REG(reg) (((reg) & 0xFFF) | 0x2000) +#else +#define BTDRV_ISPI_RF_REG(reg) (reg) +#endif + +#define btdrv_read_rf_reg(reg,val) hal_analogif_reg_read(BTDRV_ISPI_RF_REG(reg),val) +#define btdrv_write_rf_reg(reg,val) hal_analogif_reg_write(BTDRV_ISPI_RF_REG(reg),val) + +#define btdrv_delay(ms) hal_sys_timer_delay(MS_TO_TICKS(ms)) + + +#define BTDIGITAL_REG(a) (*(volatile uint32_t *)(uintptr_t)(a)) +#define BTDIGITAL_REG_WR(addr, value) (*(volatile uint32_t *)(uintptr_t)(addr)) = (value) + +#define BTDIGITAL_BT_EM(a) (*(volatile uint16_t *)(uintptr_t)(a)) +/// Macro to write a BT control structure field (16-bit wide) +#define BTDIGITAL_EM_BT_WR(addr, value) (*(volatile uint16_t *)(uintptr_t)(addr)) = (value) + +#define BTDIGITAL_REG_SET_FIELD(reg, mask, shift, v)\ + do{ \ + volatile unsigned int tmp = *(volatile unsigned int *)(reg); \ + tmp &= ~(mask<>shift)&mask; \ + }while(0) + +#define BT_DRV_DEBUG 0 +#if BT_DRV_DEBUG +#define BT_DRV_TRACE(n, fmt, ...) TRACE(n, fmt, ##__VA_ARGS__) +#define BT_DRV_DUMP(s,buff,len) DUMP8(s,buff,len) +#else +#define BT_DRV_TRACE(n, fmt, ...) hal_trace_dummy(fmt, ##__VA_ARGS__) +#define BT_DRV_DUMP(s,buff,len) hal_dump_dummy(s, buff, len) +#endif + +#define HCI_HOST_NB_CMP_PKTS_CMD_OPCODE 0x0C35 +#define HCI_NB_CMP_PKTS_EVT_CODE 0x13 + +#if defined(CHIP_BEST2300) || defined(__FPGA_BT_2300__) +#define BT_EM_ADDR_BASE (0xD021114A) +#define BT_EM_SIZE (110) +#define BLE_EM_CS_SIZE (90) +#define EM_BT_PWRCNTL_ADDR (BT_EM_ADDR_BASE + 0x16) +#define EM_BT_BT_EXT1_ADDR (BT_EM_ADDR_BASE + 0x66) +#define EM_BT_BITOFF_ADDR (BT_EM_ADDR_BASE + 0x02) +#define EM_BT_CLKOFF0_ADDR (BT_EM_ADDR_BASE + 0x04) +#define EM_BT_CLKOFF1_ADDR (BT_EM_ADDR_BASE + 0x06) +#define EM_BT_WINCNTL_ADDR (BT_EM_ADDR_BASE + 0x1A) +#define EM_BT_RXBIT_ADDR (BT_EM_ADDR_BASE + 0x56) +#define EM_BT_BTADDR1_ADDR (BT_EM_ADDR_BASE + 0xC) +#define EM_BT_LINKCNTL_ADDR (BT_EM_ADDR_BASE + 0x8) +#define EM_BT_RXDESCCNT_ADDR (BT_EM_ADDR_BASE + 0x5A) + +#define EM_BT_AUDIOBUF_OFF 0xd021449c +#define EM_BT_RXACLBUFPTR_ADDR 0xd02115a0 +#define REG_EM_BT_RXDESC_SIZE 14 + +#define LBRT_TX_PWR_FIX (3) +#define BT_CONTROLLER_CRASH_DUMP_ADDR_BASE (0xc0000050) +#define DEFAULT_XTAL_FCAP 0x8080 + +#define BT_ERRORTYPESTAT_ADDR (0xd0220060) +#define MAX_NB_ACTIVE_ACL (3) + +#elif defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) || defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(__FPGA_BT_1400__) || defined(CHIP_BEST2001) +#define BT_EM_ADDR_BASE (0xD02111A2) +#define BT_EM_SIZE (110) +#define BLE_EM_CS_SIZE (90) +#define EM_BT_PWRCNTL_ADDR (BT_EM_ADDR_BASE + 0x16) +#define EM_BT_BT_EXT1_ADDR (BT_EM_ADDR_BASE + 0x66) +#define EM_BT_BT_EXT2_ADDR (BT_EM_ADDR_BASE + 0x68) +#define EM_BT_BITOFF_ADDR (BT_EM_ADDR_BASE + 0x02) +#define EM_BT_CLKOFF0_ADDR (BT_EM_ADDR_BASE + 0x04) +#define EM_BT_CLKOFF1_ADDR (BT_EM_ADDR_BASE + 0x06) +#define EM_BT_WINCNTL_ADDR (BT_EM_ADDR_BASE + 0x1A) +#define EM_BT_RXBIT_ADDR (BT_EM_ADDR_BASE + 0x56) +#define EM_BT_BTADDR1_ADDR (BT_EM_ADDR_BASE + 0xC) +#define EM_BT_LINKCNTL_ADDR (BT_EM_ADDR_BASE + 0x8) +#define BLE_CRCINIT1_ADDR (0xd02100c2) +#define EM_BT_RXDESCCNT_ADDR (BT_EM_ADDR_BASE + 0x5A) + +#define BLE_MAXEVTIME_ADDR (0xd02100d0) + +#define EM_BT_AUDIOBUF_OFF 0xd02144fc +#define EM_BT_RXACLBUFPTR_ADDR 0xd02115f8 +#define REG_EM_BT_RXDESC_SIZE 16 + +#define LBRT_TX_PWR_FIX (3) +#define BT_CONTROLLER_CRASH_DUMP_ADDR_BASE (0xc0000050) +#define BT_ERRORTYPESTAT_ADDR (0xd0220060) +#define MAX_NB_ACTIVE_ACL (3) + +#ifdef CHIP_BEST2300A +#define DEFAULT_XTAL_FCAP 0x80ad //8pf crstal No cap by luobin +#else +#define DEFAULT_XTAL_FCAP 0x8080 +#endif + +#elif defined(__FPGA_BT_1500__) +#define BT_EM_ADDR_BASE (0xD0215000) +#define BT_EM_SIZE (104) +#define BLE_EM_CS_SIZE (112) +#define EM_BT_PWRCNTL_ADDR (BT_EM_ADDR_BASE + 0x14) +#define EM_BT_BT_EXT1_ADDR (BT_EM_ADDR_BASE + 0x60) +#define EM_BT_BITOFF_ADDR //(BT_EM_ADDR_BASE + 0x02) +#define EM_BT_CLKOFF0_ADDR (BT_EM_ADDR_BASE + 0x02) +#define EM_BT_CLKOFF1_ADDR (BT_EM_ADDR_BASE + 0x04) +#define EM_BT_WINCNTL_ADDR (BT_EM_ADDR_BASE + 0x18) +#define EM_BT_RXCLKN0_ADDR (BT_EM_ADDR_BASE + 0x52) +#define EM_BT_RXCLKN1_ADDR (BT_EM_ADDR_BASE + 0x54) +#define EM_BT_RXBIT_ADDR (BT_EM_ADDR_BASE + 0x56) +#define EM_BT_BTADDR1_ADDR (BT_EM_ADDR_BASE + 0x8) +#define EM_BT_LINKCNTL_ADDR (BT_EM_ADDR_BASE + 0x6) +#define EM_BT_RXDESCCNT_ADDR (BT_EM_ADDR_BASE + 0x5A) + +#define EM_BT_AUDIOBUF_OFF 0xd02144fc +#define EM_BT_RXACLBUFPTR_ADDR 0xd02115f8 +#define REG_EM_BT_RXDESC_SIZE 16 + +#define LBRT_TX_PWR_FIX (3) +#define BT_CONTROLLER_CRASH_DUMP_ADDR_BASE (0xc0000050) +#define BT_ERRORTYPESTAT_ADDR (0xd0220460) +#define DEFAULT_XTAL_FCAP 0x8080 +#define MAX_NB_ACTIVE_ACL (4) +#else +#define BT_EM_ADDR_BASE (0xd0210190) +#define BT_EM_SIZE (96) +#define BT_CONTROLLER_CRASH_DUMP_ADDR_BASE (0xc00064cc) +#endif + +#ifndef __FPGA_BT_1500__ +//#define FPGA_1303 +#endif + +//bt max slot clock +#define MAX_SLOT_CLOCK ((1L<<27) - 1) + // A slot is 625 us +#define SLOT_SIZE 625 +#define XTAL_OFFSET 50 + + +//#define __PASS_CI_TEST_SETTING__ +#define BT_LOW_POWER_MODE 1 +#define BT_HIGH_PERFORMANCE_MODE 2 +//#define __ENABLE_LINK_POWER_CONTROL__ + +#define BT_RFMODE BT_LOW_POWER_MODE +//#define BT_RFMODE BT_HIGH_PERFORMANCE_MODE +//#define BT_50_FUNCTION + +#define BT_POWERON 1 +#define BT_POWEROFF 0 + +/// 8 bit access types +#define _8_Bit 8 +/// 16 bit access types +#define _16_Bit 16 +/// 32 bit access types +#define _32_Bit 32 + +#define BTDRV_PATCH_WRITING 0x0 +#define BTDRV_PATCH_DONE 0x1 + +#define BTDRV_CFG_WRITING 0x0 +#define BTDRV_CFG_DONE 0x1 + +#define HCI_DBG_RD_MEM_CMD_OPCODE 0xFC01 +#define HCI_DBG_WR_MEM_CMD_OPCODE 0xFC02 +#define HCI_DBG_DEL_PAR_CMD_OPCODE 0xFC03 +#define HCI_DBG_FLASH_ID_CMD_OPCODE 0xFC05 +#define HCI_DBG_FLASH_ER_CMD_OPCODE 0xFC06 +#define HCI_DBG_FLASH_WR_CMD_OPCODE 0xFC07 +#define HCI_DBG_FLASH_RD_CMD_OPCODE 0xFC08 +#define HCI_DBG_RD_PAR_CMD_OPCODE 0xFC09 +#define HCI_DBG_WR_PAR_CMD_OPCODE 0xFC0A +#define HCI_DBG_WLAN_COEX_CMD_OPCODE 0xFC0B +#define HCI_DBG_ENTER_TEST_MODE_CMD_OPCODE 0xFC0C +#define HCI_DBG_WLAN_COEXTST_SCEN_CMD_OPCODE 0xFC0D +#define HCI_DBG_SEND_LMP_CMD_OPCODE 0xFC0E +#define HCI_DBG_WR_SYNC_DATA_CFG_CMD_OPCODE 0xFC0F +#define HCI_DBG_RD_KE_STATS_CMD_OPCODE 0xFC10 +#define HCI_DBG_PLF_RESET_CMD_OPCODE 0xFC11 +#define HCI_DBG_RD_MEM_INFO_CMD_OPCODE 0xFC12 +#define HCI_DBG_EMUL_TESTER_CMD_OPCODE 0xFC2D +#define HCI_DBG_SCATT_IMPROV_CMD_OPCODE 0xFC2E +#define HCI_DBG_RF_REG_RD_CMD_OPCODE 0xFC39 +#define HCI_DBG_RF_REG_WR_CMD_OPCODE 0xFC3A +#define HCI_DBG_HW_REG_RD_CMD_OPCODE 0xFC30 +#define HCI_DBG_HW_REG_WR_CMD_OPCODE 0xFC31 +#define HCI_DBG_SET_BD_ADDR_CMD_OPCODE 0xFC32 +#define HCI_DBG_SET_TYPE_PUB_CMD_OPCODE 0xFC33 +#define HCI_DBG_SET_TYPE_RAND_CMD_OPCODE 0xFC34 +#define HCI_DBG_SET_CRC_CMD_OPCODE 0xFC35 +#define HCI_DBG_LLCP_DISCARD_CMD_OPCODE 0xFC36 +#define HCI_DBG_RESET_RX_CNT_CMD_OPCODE 0xFC37 +#define HCI_DBG_RESET_TX_CNT_CMD_OPCODE 0xFC38 +#define HCI_DBG_SET_TX_PW_CMD_OPCODE 0xFC3B +#define HCI_DBG_SET_SYNCWORD_CMD_OPCODE 0xFC3C + + +//encrytion min and max key size +#define HCI_DBG_SET_ENCRYPTION_KEY_SIZE_CMD_OPCODE 0xFC41 +//preferred key type default :combine key +#define HCI_DBG_SET_PREFERRED_KEY_TYPE_CMD_OPCODE 0xFC42 +//creat unit key +#define HCI_DBG_CREAT_UNIT_KEY_CMD_OPCODE 0xFC43 +//set clk drift and jitter +#define HCI_DBG_SET_LPCLK_DRIFT_JITTER_CMD_OPCODE 0xFC44 + +//change uart buadrate +#define HCI_DBG_CHANGE_UART_BAUDRATE_CMD_OPCODE 0xFC46 + +//set sleep enable and external wakeup enable +#define HCI_DBG_SET_SLEEP_EXWAKEUP_EN_CMD_OPCODE 0xFC47 + +//set private key +#define HCI_DBG_SET_SP_PRIVATE_KEY_CMD_OPCODE 0xFC48 + +//set public key +#define HCI_DBG_SET_SP_PUBLIC_KEY_CMD_OPCODE 0xFC49 + +//set errdata adopted +#define HCI_DBG_SET_ERRDATA_ADOPTED_CMD_OPCODE 0xFC4A + +//set basic threshold +#define HCI_DBG_SET_BASIC_THRESHOLD_CMD_OPCODE 0xFC4B + +//set edr threshold +#define HCI_DBG_SET_EDR_THRESHOLD_CMD_OPCODE 0xFC4C + +//set basic algorithm +#define HCI_DBG_SET_BASIC_ALGORITHM_CMD_OPCODE 0xFC4D + +//set edr alorithm +#define HCI_DBG_SET_EDR_ALGORITHM_CMD_OPCODE 0xFC4E + +//set basic packet lut +#define HCI_DBG_SET_BASIC_PKT_LUT_CMD_OPCODE 0xFC4F + +//set edr packet lut +#define HCI_DBG_SET_EDR_PKT_LUT_CMD_OPCODE 0xFC50 + +//set diag_bt_hw +#define HCI_DBG_SET_DIAG_BT_HW_CMD_OPCODE 0xFC54 +//set diag ble hw +#define HCI_DBG_SET_DIAG_BLE_HW_CMD_OPCODE 0xFC55 +//set diag sw +#define HCI_DBG_SET_DIAG_SW_CMD_OPCODE 0xFC56 + +//set ble channel assessment parameter +#define HCI_DBG_SET_BLE_CA_PARA_CMD_OPCODE 0xFC57 + +//set ble rf timing + +//set ble rf timig + +//set ble rl size +#define HCI_DBG_SET_RL_SIZE_CMD_OPCODE 0xFC5D + +///set hostwake +#define HCI_DBG_SET_HOSTWAKE_CMD_OPCODE 0xFC5E +//reserved for VCO test +#define HCI_DBG_BT_VCO_TEST_CMD_OPCODE 0xFCAA + +#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || \ + defined(CHIP_BEST2300A) || defined(CHIP_BEST2001) || \ + defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || \ + defined(__FPGA_BT_2300__) ||defined(__FPGA_BT_1400__) || \ + defined(__FPGA_BT_1500__) + +///set dle dft value +#define HCI_DBG_WR_DLE_DFT_VALUE_CMD_OPCODE 0xFC41 + +//set exernal wake up time oscillater wakeup time and radio wakeup time +#define HCI_DBG_SET_WAKEUP_TIME_CMD_OPCODE 0xFC71 + +#define HCI_DBG_SET_SLEEP_SETTING_CMD_OPCODE 0xFC77 + +//bt address not ble address +#define HCI_DBG_SET_BT_ADDR_CMD_OPCODE 0xFC72 +//set pcm setting +#define HCI_DBG_SET_PCM_SETTING_CMD_OPCODE 0xFC74 + +#define HCI_DBG_SET_RSSI_THRHLD_CMD_OPCODE 0xFC76 + + +//set sync buff size +#define HCI_DBG_SET_SYNC_BUF_SIZE_CMD_OPCODE 0xFC7F +//set afh algorithm +#define HCI_DBG_SET_AFH_ALGORITHM_CMD_OPCODE 0xFC80 +//set local feature +#define HCI_DBG_SET_LOCAL_FEATURE_CMD_OPCODE 0xFC81 + +#define HCI_DBG_SET_BT_RF_TIMING_CMD_OPCODE 0xFC83 + +//set local extend feature +#define HCI_DBG_SET_LOCAL_EX_FEATURE_CMD_OPCODE 0xFC82 + +#define HCI_DBG_SET_2300_BT_RF_TIMING_CMD_OPCODE 0xFC83 + + +#define HCI_DBG_SET_BLE_RF_TIMING_CMD_OPCODE 0xfc84 + +//bt setting interface +#define HCI_DBG_SET_BT_SETTING_CMD_OPCODE 0xFC86 +// xiao add for nonsignaling test mode +#define HCI_DBG_NONSIG_TESTER_SETUP_CMD_OPCODE 0xFC87 +/* xiao add for custom set param*/ +#define HCI_DBG_SET_CUSTOM_PARAM_CMD_OPCODE 0xFC88 + +#define HCI_DBG_SET_SCO_SWITCH_CMD_OPCODE 0xFC89 + +#define HCI_DBG_SET_SNIFFER_ENV_CMD_OPCODE 0xFC8E +//set sco path +#define HCI_DBG_SET_SYNC_CONFIG_CMD_OPCODE 0xFC8F + +#define HCI_DBG_START_TWS_EXCHANGE_CMD_OPCODE 0xFC91 + +#define HCI_DBG_BTADDR_EXCHANGE_CMD_OPCODE 0xFC92 + +#define HCI_DBG_SEND_DATA_TO_PEER_DEV_CMD_OPCODE 0xFC93 + +#define HCI_DBG_SCO_TX_SILENCE_CMD_OPCODE 0xFC94 + +#define HCI_DBG_SNIFFER_CMD_OPCODE 0xFC95 + +#define HCI_DBG_CSB_UPDATE_LINK_PARAM_CMD_OPCODE 0xFC96 + +#define HCI_DBG_SET_LINK_LBRT_CMD_OPCODE 0xFC97 + +#define HCI_DBG_SET_CON_SLV_BCST_DATA_CMD_OPCODE 0xFC98 +#define HCI_DBG_SET_ROLE_SWITCH_INSTANT_CMD_OPCODE 0xFC99 +#define HCI_DBG_LOW_LAYER_METRICS_CMD_OPCODE 0xFC9B +#define HCI_DBG_LMP_MESSAGE_RECORD_CMD_OPCODE 0xFC9C + + +#define HCI_DBG_SET_LOCAL_FEATURE_50_CMD_OPCODE 0xFC72 +#define HCI_DBG_SET_SLEEP_SETTING_50_CMD_OPCODE 0xFC70 +#define HCI_DBG_SET_BT_SETTING_50_CMD_OPCODE 0xFC71 + +#define HCI_DBG_SET_CUSTOM_PARAM_50_CMD_OPCODE 0xFC73 +#define HCI_DBG_SET_BT_SETTING_EXT1_CMD_OPCODE 0xFCAE +#define HCI_DBG_SET_BT_TWS_LINK_CMD_OPCODE 0xFCAF +#define HCI_DBG_SET_AFH_FOLLOW_CMD_OPCODE 0xFCB0 +#define HCI_DBG_SET_RF_RX_GAIN_THS_TBL_CMD_OPCODE 0xFCB1 +#define HCI_DBG_SET_RF_RX_GAIN_FIXED_CMD_OPCODE 0xFCB2 + +#define HCI_DBG_SET_BT_SETTING_EXT2_CMD_OPCODE 0xFCB3 +#define HCI_DBG_SET_IBRT_TEST_MODE_CMD_OPCODE 0xFCB4 +#define HCI_DBG_SET_BT_LOCAL_CLK_CMD_OPCODE 0xFCB5 +#define HCI_DBG_SET_FUNC_PATCH_CMD_OPCODE 0xFCB8 +#define HCI_DBG_SET_TXPWR_MODE_CMD_OPCODE 0xFCB9 +#define HCI_DBG_SET_SW_RSSI_CMD_OPCODE 0xFCBA +#define HCI_DBG_SET_ECC_DATA_TEST_CMD_OPCODE 0xFCBB +#define HCI_DBG_SET_IBRT_DATA_TEST_CMD_OPCODE 0xFCBC +#define HCI_DBG_SET_NWINSZ_RXGRN_TO_CMD_OPCODE 0xFCBD +#define HCI_DBG_ENABLE_SOFTBIT_CMD_OPCODE 0xFCBE + +#else +//bt address not ble address +#define HCI_DBG_SET_BT_ADDR_CMD_OPCODE 0xFC40 +//set exernal wake up time oscillater wakeup time and radio wakeup time +#define HCI_DBG_SET_WAKEUP_TIME_CMD_OPCODE 0xFC45 +//set sco path +#define HCI_DBG_SET_SYNC_CONFIG_CMD_OPCODE 0xFC51 +//set pcm setting +#define HCI_DBG_SET_PCM_SETTING_CMD_OPCODE 0xFC52 +//set sync buff size +#define HCI_DBG_SET_SYNC_BUF_SIZE_CMD_OPCODE 0xFC53 +//set local feature +#define HCI_DBG_SET_LOCAL_FEATURE_CMD_OPCODE 0xFC59 +//bt setting interface +#define HCI_DBG_SET_BT_SETTING_CMD_OPCODE 0xFC5F +//set afh algorithm +#define HCI_DBG_SET_AFH_ALGORITHM_CMD_OPCODE 0xFC58 +//set local extend feature +#define HCI_DBG_SET_LOCAL_EX_FEATURE_CMD_OPCODE 0xFC5A + +#define HCI_DBG_SET_BT_RF_TIMING_CMD_OPCODE 0xFC5B + + +#define HCI_DBG_SET_BLE_RF_TIMING_CMD_OPCODE 0xFC5C + + +// xiao add for nonsignaling test mode +#define HCI_DBG_NONSIG_TESTER_SETUP_CMD_OPCODE 0xFC60 +/* xiao add for custom set param*/ +#define HCI_DBG_SET_CUSTOM_PARAM_CMD_OPCODE 0xFC61 + +#define HCI_DBG_SET_SCO_SWITCH_CMD_OPCODE 0xFC62 + +#define HCI_DBG_SET_SNIFFER_ENV_CMD_OPCODE 0xFC67 + +#define HCI_DBG_START_TWS_EXCHANGE_CMD_OPCODE 0xFC69 + +#define HCI_DBG_BTADDR_EXCHANGE_CMD_OPCODE 0xFC6A + +#define HCI_DBG_SEND_DATA_TO_PEER_DEV_CMD_OPCODE 0xFC6B + +#define HCI_DBG_SCO_TX_SILENCE_CMD_OPCODE 0xFC6C + +#define HCI_DBG_SNIFFER_CMD_OPCODE 0xFC6D + +#define HCI_DBG_BT_VCO_TEST_CMD_OPCODE 0xFCAA + +// Only new controller IP has this funciton,it is a error opcode +#define HCI_DBG_SET_ROLE_SWITCH_INSTANT_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_LINK_LBRT_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_BT_SETTING_EXT1_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_BT_TWS_LINK_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_AFH_FOLLOW_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_RF_RX_GAIN_THS_TBL_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_RF_RX_GAIN_FIXED_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_BT_SETTING_EXT2_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_IBRT_TEST_MODE_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_BT_LOCAL_CLK_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_FUNC_PATCH_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_TXPWR_MODE_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_SW_RSSI_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_ECC_DATA_TEST_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_IBRT_DATA_TEST_CMD_OPCODE 0xFCFF +#define HCI_DBG_SET_NWINSZ_RXGRN_TO_CMD_OPCODE 0xFCFF +#define HCI_DBG_ENABLE_SOFTBIT_CMD_OPCODE 0xFCFF + +#endif // 2300, 2300p, 1400,1402,1501 + +extern void btdrv_poweron(uint8_t en); +extern void btdrv_hciopen(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/bt/bt_drv_common.c b/platform/drivers/bt/bt_drv_common.c new file mode 100644 index 0000000..bdfeb43 --- /dev/null +++ b/platform/drivers/bt/bt_drv_common.c @@ -0,0 +1,633 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "hal_i2c.h" +#include "hal_uart.h" +#include "hal_chipid.h" +#include "bt_drv.h" +#include "bt_drv_internal.h" +#include "bt_drv_interface.h" +#include "bt_drv_reg_op.h" +#include "app_utils.h" +#include "string.h" +#include "besbt_string.h" + +#define BT_DUMP_LEN_LINE 100 +#define SLOT_SIZE 625 +#define MAX_SLOT_CLOCK ((1L<<27) - 1) +#define CLK_SUB(clock_a, clock_b) ((uint32_t)(((clock_a) - (clock_b)) & MAX_SLOT_CLOCK)) +#define CLK_ADD_2(clock_a, clock_b) ((uint32_t)(((clock_a) + (clock_b)) & MAX_SLOT_CLOCK)) + +struct bt_cb_tag bt_drv_func_cb = {NULL}; +struct bt_cb_tag* bt_drv_get_func_cb_ptr(void) +{ + return &bt_drv_func_cb; +} + +///only used for bt chip write patch data for speed up +void btdrv_memory_copy(uint32_t *dest,const uint32_t *src,uint16_t length) +{ + // memcpy(dest,src,length); + uint16_t i; + for(i=0; i SLOT_SIZE) + { + new_cnt -= SLOT_SIZE; + new_clk = CLK_SUB(new_clk, 1); + } + + *master_clk = new_clk; + *master_cnt = new_cnt; + return 0; +} + +void bt_drv_set_fa_invert_enable(uint8_t en) +{ + BTDIGITAL_REG_SET_FIELD(0xd0220468, 1, 17, en); + BT_DRV_TRACE(1,"BT_DRV:set fa invert en=%d", en); +} + +void btdrv_trigger_coredump(void) +{ + uint8_t *null_pointer = 0; + *null_pointer = 0;//MPU trigger coredump +} + +int btdrv_clkcnt_diff(int32_t clk1, int16_t cnt1, + int32_t clk2, int16_t cnt2, + int32_t *diff_clk, uint16_t *diff_bit) +{ + int32_t new_clk; + int16_t new_cnt; + int diff_us; + + new_clk = (int32_t)clk1 - (int32_t)clk2; + new_cnt = cnt1 - cnt2; + if (new_cnt < 0) + { + new_cnt += SLOT_SIZE; + }else{ + new_clk -= 1; + } + + *diff_clk = new_clk; + *diff_bit = new_cnt; + + diff_us = new_clk * SLOT_SIZE + (SLOT_SIZE - new_cnt); + + return diff_us; +} + +void WEAK btdrv_set_controller_trace_enable(uint8_t trace_level) +{ +} + +void WEAK btdrv_set_lmp_trace_enable(void) +{ +} +static bool g_controller_trace_dump_enable = false; +bool btdrv_get_controller_trace_dump_enable(void) +{ + return g_controller_trace_dump_enable; +} +void btdrv_set_controller_trace_dump_enable(void) +{ + g_controller_trace_dump_enable = true; +} + +void btdrv_btc_fault_dump(void) +{ + app_wdt_close(); + bt_drv_reg_op_crash_dump(); +} + +void btdrv_dump_mem(uint8_t *dump_mem_start, uint32_t dump_length, uint8_t dump_type) +{ +#if CONTROLLER_DUMP_ENABLE + uint32_t dump_counter=0; + uint32_t dump_line=0; + + hal_sys_timer_delay(MS_TO_TICKS(100)); + switch (dump_type) + { + case BT_SUB_SYS_TYPE: + BT_DRV_TRACE(1,"controller dump start, dump len=0x%x",dump_length); + break; + + case MCU_SYS_TYPE: + BT_DRV_TRACE(1,"mcu dump start, dump len=0x%x",dump_length); + break; + + case BT_EM_AREA_1_TYPE: + BT_DRV_TRACE(1,"em_area1 dump start, dump len=0x%x",dump_length); + break; + + case BT_EM_AREA_2_TYPE: + BT_DRV_TRACE(1,"em_area2 dump start, dump len=0x%x",dump_length); + break; + } + while (dump_counter < dump_length) + { + uint32_t data_left = dump_length - dump_counter; + dump_line += 1; + if (data_left >= BT_DUMP_LEN_LINE) + { + BT_DRV_TRACE(1,"dump_line=%d", dump_line); + DUMP8("%02x", dump_mem_start, BT_DUMP_LEN_LINE); + hal_trace_flush_buffer(); + dump_mem_start += BT_DUMP_LEN_LINE; + dump_counter += BT_DUMP_LEN_LINE; + hal_sys_timer_delay(MS_TO_TICKS(50)); + } + else + { + BT_DRV_TRACE(1,"dump_line=%d", dump_line); + DUMP8("%02x", dump_mem_start, data_left); + hal_trace_flush_buffer(); + hal_sys_timer_delay(MS_TO_TICKS(50)); + break; + } + } + switch (dump_type) + { + case BT_SUB_SYS_TYPE: + BT_DRV_TRACE(0,"controller dump end"); + break; + + case MCU_SYS_TYPE: + BT_DRV_TRACE(0,"mcu dump end"); + break; + + case BT_EM_AREA_1_TYPE: + BT_DRV_TRACE(0,"em_area1 dump end"); + break; + + case BT_EM_AREA_2_TYPE: + BT_DRV_TRACE(0,"em_area2 dump end"); + break; + } +#endif +} +void btdrv_trace_config(BT_CONTROLER_TRACE_TYPE trace_config) +{ + if (trace_config & BT_CONTROLER_TRACE_TYPE_INTERSYS) + { + btdrv_set_intersys_trace_enable(); + } + + if (trace_config & BT_CONTROLER_TRACE_TYPE_CONTROLLER) + { + btdrv_set_controller_trace_enable(0x00); + } + + if (trace_config & BT_CONTROLER_TRACE_TYPE_LMP_TRACE) + { + btdrv_set_lmp_trace_enable(); + } + + if (trace_config & BT_CONTROLER_TRACE_TYPE_SPUV_HCI_BUFF) + { + btdrv_set_spuv_hci_buff_trace_enable(); + } + + if (trace_config & BT_CONTROLER_FILTER_TRACE_TYPE_A2DP_STREAM) + { + btdrv_set_a2dp_stream_trace_disable(); + } + +#if CONTROLLER_MEM_LOG_ENABLE + btdrv_set_controller_trace_dump_enable(); +#endif +} + +bool bt_drv_is_enhanced_ibrt_rom(void) +{ + bool ret = false; + +#ifdef CHIP_BEST2300P + if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) + ret = true; +#elif CHIP_BEST1400 + if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2) + ret = true; +#elif CHIP_BEST1402 + ret = true; +#elif CHIP_BEST2300A + ret = true; +#elif FPGA + ret = true; +#elif CHIP_BEST2300 + ret = true; +#endif + + return ret; +} + +bool bt_drv_is_esco_auto_accept_support(void) +{ + bool ret = false; + +#ifdef CHIP_BEST2300P + if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2) + ret = true; +#elif CHIP_BEST1400 + if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_4) + ret = true; +#elif CHIP_BEST1402 + if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) + ret = true; +#elif CHIP_BEST2300A + ret = true; +#endif + + return ret; +} + +bool btdrv_is_acl_ecc_softbit_support(void) +{ + bool ret = false; +#ifdef CHIP_BEST2300A + ret = true; +#endif + + return ret; +} + + +void btdrv_softbit_enable(uint16_t connhdl, uint8_t type1,uint8_t type2,uint8_t type3, uint8_t num) +{ + if(btdrv_is_acl_ecc_softbit_support()) + { +#if (defined(SOFTBIT_EN)) + btdrv_softbit_config(connhdl, type1, type2, type3, num); +#endif + } +} + +void bt_drv_bt_tport_type_config(void) +{ + uint32_t tport_type = 0xb1b1; +#ifdef __BT_DEBUG_TPORTS__ + tport_type = TPORT_TYPE; +#endif + BTDIGITAL_REG(0xd0220050) = tport_type; + BTDIGITAL_REG(0xd0340000) = 0x23620200; + + BT_DRV_TRACE(1,"BT_DRV: tport type=0x%x",tport_type); +} + +bool bt_drv_is_bes_fa_mode_en(void) +{ + bool ret = false; +#ifdef __BES_FA_MODE__ + ret = true; +#endif + return ret; +} + +bool bt_drv_is_support_multipoint_ibrt(void) +{ + bool ret = false; +#ifdef __FPGA_BT_1500__ + ret = true; +#endif + return ret; +} + +void bt_drv_enable_hw_spi(uint8_t elt_idx, bool hwspien) +{ +#ifdef CHIP_BEST2300A + bt_drv_reg_op_hw_spi_en_setf(elt_idx, hwspien); +#endif +} + +struct btstack_chip_config_t +{ + uint16_t hci_dbg_set_sync_config_cmd_opcode; + uint16_t hci_dbg_set_sco_switch_cmd_opcode; +} g_bt_drv_btstack_chip_config = { + HCI_DBG_SET_SYNC_CONFIG_CMD_OPCODE, + HCI_DBG_SET_SCO_SWITCH_CMD_OPCODE, +}; + +void* bt_drv_get_btstack_chip_config(void) +{ + return &g_bt_drv_btstack_chip_config; +} + +void bt_drv_hwspi_select(uint8_t link_id, uint8_t spi_idx) +{ +#ifdef __FA_RX_GAIN_CTRL__ + btdrv_spi_trig_select(link_id, spi_idx); +#endif +} + +/// BCH size +#define LD_BCH_SIZE 8 + +static const uint8_t ld_util_bch_ppolynom[LD_BCH_SIZE] = +{ + 0x83, 0x84, 0x8D, 0x96, 0xBB, 0xCC, 0x54, 0xFC +}; + +static const uint8_t ld_util_bch_gpolynom[LD_BCH_SIZE] = +{ + 0x00, 0x00, 0x00, 0x05, 0x85, 0x71, 0x3D, 0xA9 +}; + +static void ld_util_bch_modulo(uint8_t *dividend, const uint8_t *divisor, uint8_t *rest) +{ + uint8_t clock; + uint8_t carry; + uint8_t index; + uint8_t dividend_tmp[LD_BCH_SIZE]; + + // Copy dividend vector in a temporary vector + // And reset rest vector + for (index = 0 ; index < LD_BCH_SIZE ; index++) + { + dividend_tmp[index] = dividend[index]; + rest[index] = 0; + } + + // Execute 64 times the LFSR process + for (clock = 0 ; clock < 64 ; clock++) + { + // Store bit Rest(degree-1) in carry (assume degree of G is 32) + carry = rest[3] & 0x02; + + // the rest is shifted of 1 bit Left + // The MSB of rest if lost and the MSB of dividend is shifted in LSB + rest[0] = (rest[0] << 1) | ((rest[1] & 0x80) >> 7); + rest[1] = (rest[1] << 1) | ((rest[2] & 0x80) >> 7); + rest[2] = (rest[2] << 1) | ((rest[3] & 0x80) >> 7); + rest[3] = (rest[3] << 1) | ((rest[4] & 0x80) >> 7); + rest[4] = (rest[4] << 1) | ((rest[5] & 0x80) >> 7); + rest[5] = (rest[5] << 1) | ((rest[6] & 0x80) >> 7); + rest[6] = (rest[6] << 1) | ((rest[7] & 0x80) >> 7); + rest[7] = (rest[7] << 1) | ((dividend_tmp[0] & 0x80) >> 7); + + // the dividend_tmp is shifted of 1 bit Left (a 0 is shifted in LSB) + dividend_tmp[0] = (dividend_tmp[0] << 1) | ((dividend_tmp[1] & 0x80) >> 7); + dividend_tmp[1] = (dividend_tmp[1] << 1) | ((dividend_tmp[2] & 0x80) >> 7); + dividend_tmp[2] = (dividend_tmp[2] << 1) | ((dividend_tmp[3] & 0x80) >> 7); + dividend_tmp[3] = (dividend_tmp[3] << 1) | ((dividend_tmp[4] & 0x80) >> 7); + dividend_tmp[4] = (dividend_tmp[4] << 1) | ((dividend_tmp[5] & 0x80) >> 7); + dividend_tmp[5] = (dividend_tmp[5] << 1) | ((dividend_tmp[6] & 0x80) >> 7); + dividend_tmp[6] = (dividend_tmp[6] << 1) | ((dividend_tmp[7] & 0x80) >> 7); + dividend_tmp[7] = (dividend_tmp[7] << 1); + + // If bit carry value was 1 + if (carry != 0) + { + // rest = rest XOR Divisor + for (index = 0 ; index < LD_BCH_SIZE ; index++) + { + rest[index] ^= divisor[index]; + } + } + } +} + +void ld_util_bch_create(uint8_t *lap, uint8_t *bch) +{ + uint8_t vector[LD_BCH_SIZE]; + uint8_t vector2[LD_BCH_SIZE]; + uint8_t index; + + // Copy lap and Appended in bch + if (lap[2] & 0x80) + { + vector[0] = 0x4C; // If a23 = 1 + } + else + { + vector[0] = 0xB0; // If a23 = 0 + } + + vector[0] |= lap[2] >> 6; + vector[1] = lap[2] << 2 | lap[1] >> 6; + vector[2] = lap[1] << 2 | lap[0] >> 6; + vector[3] = lap[0] << 2; + + // Xor Vector and PN (Vector contains only 30 significant bits) + for (index = 0 ; index < 4; index++) + { + vector[index] ^= ld_util_bch_ppolynom[index]; + } + + // Reset 34 last bits + vector[3] &= 0xFC; + vector[4] = 0; + vector[5] = 0; + vector[6] = 0; + vector[7] = 0; + + // Generate Parity bits Vector Modulo G + ld_util_bch_modulo(vector, ld_util_bch_gpolynom, vector2); + + // Create CodeWord (concatenate Modulo result and Xored Vector) + vector[3] |= vector2[3]; + vector[4] = vector2[4]; + vector[5] = vector2[5]; + vector[6] = vector2[6]; + vector[7] = vector2[7]; + + // Xor codeWord and PN + for (index = 0 ; index < 8; index++) + { + bch[7-index] = vector[index] ^ ld_util_bch_ppolynom[index]; + } +} + +void bt_drv_rssi_dump_handler(void) +{ + rx_agc_t bt_agc = {0,0xf}; + for(int i = 0; i +#include "stdint.h" +#include "stdbool.h" +#include "plat_types.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + int8_t rssi; + uint8_t rxgain; +} rx_agc_t; + +typedef struct +{ + uint8_t agc_idx0; + int8_t rssi0; + int8_t rssi0_max; + int8_t rssi0_min; + uint8_t agc_idx1; + int8_t rssi1; + int8_t rssi1_max; + int8_t rssi1_min; + uint8_t agc_idx2; + int8_t rssi2; + int8_t rssi2_max; + int8_t rssi2_min; + uint16_t ser; + uint16_t rx_data_sum; +} __attribute__((packed)) rssi_t; + +struct ld_afh_env +{ +/// RSSI threshold for interference detection (in dBm) + int8_t rf_rssi_interf_thr; +/// AFH update period (in sec) + uint8_t afh_update_period; +/// Maximum duration without receiving a packet before considering a channel quality unknown (in slots) (2 secs) + uint16_t afh_access_valid_to; +/// Maximum duration without receiving a packet before reintroducing a channel to the map (in slots) (20 secs) + uint16_t afh_reaccess_to; +/// Maximum counter value for channel assessment + int8_t afh_access_count_max; +/// Counter threshold to consider a channel good + int8_t afh_access_count_thr_good; +/// Counter threshold to consider a channel bad + int8_t afh_access_count_thr_bad; +/// Minimum counter value for channel assessment + int8_t afh_access_count_min; +}; + +/// RSSI threshold for interference detection (in dBm) +#define BT_AFH_RSSI_INTERF_THR (-70) + +/// AFH update period (in sec) +#define BT_AFH_UPDATE_PERIOD 4 + +/// Maximum duration without receiving a packet before considering a channel quality unknown (in slots) (2 secs) +#define BT_AFH_ASSESS_VALID_TO 0x1900 + +/// Maximum duration without receiving a packet before reintroducing a channel to the map (in slots) (20 secs) +#define BT_AFH_REASSESS_TO 0x7D00 + +/// Maximum counter value for channel assessment +#define BT_AFH_ASSESS_COUNT_MAX 4 +/// Counter threshold to consider a channel good +#define BT_AFH_ASSESS_COUNT_THR_GOOD 2 +/// Counter threshold to consider a channel bad +#define BT_AFH_ASSESS_COUNT_THR_BAD -2 +/// Minimum counter value for channel assessment +#define BT_AFH_ASSESS_COUNT_MIN -4 + +#define RETX_NB_0 0 +#define RETX_NB_1 1 +#define RETX_NB_2 2 +#define RETX_NEGO 3 +#ifdef CHIP_BEST2000 +#define MIC_BUFF_ADRR_REG (0xc0000040) +#define RX_BUFF_ADRR (0xc0000044) +#elif defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST2300P) +#define MIC_BUFF_ADRR_REG (0xc0000058) +#define RX_BUFF_ADRR (0xc000005c) +#elif defined(CHIP_BEST2300A) +#define MIC_BUFF_ADRR_REG (0xc0000058) +#define RX_BUFF_INFO_ADRR (0xc000005c) +#define RX_BUFF_ADRR (*(volatile uint32_t *)(RX_BUFF_INFO_ADRR)) +#endif + +//BT acl tx silence +#define TX_SILENCE_ON 1 +#define TX_SILENCE_OFF 0 + +struct dbg_set_ebq_test +{ + uint8_t ebq_testmode; + uint8_t ble_set_privacy_mode; + uint8_t ll_con_ini_bv2324; + uint8_t ll_con_ini_bv2021; + uint8_t ll_ddi_scn_bv26; + uint8_t ll_sec_adv_bv05; + uint8_t ll_sync_win_default; + uint8_t auth_end_notify_host_lk; + uint8_t ll_sec_adv_bv09; + uint8_t ll_sec_adv_bv17; + uint8_t ll_sec_adv_bv1819; + uint8_t LocEncKeyRefresh; + uint8_t publickey_check; + uint8_t Qos; + uint8_t hv1; + uint8_t ssr; + uint8_t aes_ccm_daycounter; + uint8_t bb_prot_flh_bv01; + uint8_t bb_prot_arq_bv43; + uint8_t pause_aes_generate_rand; +}; + + +void bt_drv_reg_op_rssi_set(uint16_t rssi); +void bt_drv_reg_op_scan_intv_set(uint32_t scan_intv); +void bt_drv_reg_op_encryptchange_errcode_reset(uint16_t hci_handle); +void bt_drv_reg_op_sco_sniffer_checker(void); +void bt_drv_reg_op_trigger_time_checker(void); +void bt_drv_reg_op_tws_output_power_fix_separate(uint16_t hci_handle, uint16_t pwr); +bool bt_drv_reg_op_ld_sniffer_env_monitored_dev_state_get(void); +void bt_drv_reg_op_ld_sniffer_env_monitored_dev_state_set(bool state); +void bt_drv_reg_op_ld_sniffer_master_addr_set(uint8_t * addr); +int bt_drv_reg_op_currentfreeaclbuf_get(void); +void bt_drv_reg_op_save_mobile_airpath_info(uint16_t hciHandle); +void bt_drv_reg_op_block_xfer_with_mobile(uint16_t hciHandle); +void bt_drv_reg_op_resume_xfer_with_mobile(uint16_t hciHandle); +void bt_drv_reg_op_block_fast_ack_with_mobile(void); +void bt_drv_reg_op_resume_fast_ack_with_mobile(void); +int bt_drv_reg_op_packet_type_checker(uint16_t hciHandle); +void bt_drv_reg_op_max_slot_setting_checker(uint16_t hciHandle); +void bt_drv_reg_op_force_task_dbg_idle(void); +void bt_drv_reg_op_afh_follow_mobile_mobileidx_set(uint16_t hciHandle); +void bt_drv_reg_op_afh_follow_mobile_twsidx_set(uint16_t hciHandle); +void bt_drv_reg_op_sco_status_store(void); +void bt_drv_reg_op_sco_status_restore(void); +bool bt_drv_reg_op_sco_tx_buf_restore(uint8_t *trigger_test); +void bt_drv_reg_op_afh_bak_reset(void); +void bt_drv_reg_op_afh_bak_save(uint8_t role, uint16_t mobileHciHandle); +void bt_drv_reg_op_connection_checker(void); +void bt_drv_reg_op_bt_info_checker(void); +uint8_t bt_drv_reg_op_get_controller_tx_free_buffer(void); +uint8_t bt_drv_reg_op_get_controller_ble_tx_free_buffer(void); +void bt_drv_reg_op_ble_buffer_cleanup(void); +bool bt_drv_reg_op_get_dbg_state(void); +void bt_drv_reg_op_crash_dump(void); +void bt_drv_reg_op_set_tx_pwr(uint16_t connHandle, uint8_t txpwr); +uint8_t bt_drv_reg_op_get_tx_pwr(uint16_t connHandle); +void bt_drv_reg_op_fix_tx_pwr(uint16_t connHandle); +void bt_drv_reg_op_lsto_hack(uint16_t hciHandle, uint16_t lsto); +uint16_t bt_drv_reg_op_get_lsto(uint16_t hciHandle); +void bt_drv_reg_op_enable_emsack_mode(uint16_t connHandle, uint8_t master, uint8_t enable); +void bt_drv_reg_op_set_accessible_mode(uint8_t mode); +void bt_drv_reg_op_force_sco_retrans(bool enable); +void bt_drv_reg_op_enable_pcm_tx_hw_cal(void); +void bt_drv_reg_op_monitor_clk(void); +bool bt_drv_reg_op_read_rssi_in_dbm(uint16_t connHandle,rx_agc_t* rx_val); +bool bt_drv_reg_op_read_ble_rssi_in_dbm(uint16_t connHandle,rx_agc_t* rx_val); +void bt_drv_reg_op_set_swagc_mode(uint8_t mode); +void bt_drv_reg_op_set_reboot_pairing_mode(uint8_t mode); + +void bt_drv_reg_op_acl_silence(uint16_t connHandle, uint8_t silence); +void bt_drv_reg_op_call_monitor(uint16_t connHandle, uint8_t tws_role); +void bt_drv_reg_op_lock_sniffer_sco_resync(void); +void bt_drv_reg_op_unlock_sniffer_sco_resync(void); +void bt_drv_reg_op_afh_set_default(void); +void bt_drv_reg_op_update_sniffer_bitoffset(uint16_t mobile_conhdl,uint16_t master_conhdl); +void bt_drv_reg_op_modify_bitoff_timer(uint16_t time_out); +uint16_t em_bt_bitoff_getf(int elt_idx); +void bt_drv_reg_op_ble_llm_substate_hacker(void); +void bt_drv_reg_op_esco_acl_sniff_delay_cal(uint16_t hciHandle,bool enable); +bool bt_drv_reg_op_check_esco_acl_sniff_conflict(uint16_t hciHandle); +void bt_drv_reg_op_set_tpoll(uint8_t linkid,uint16_t poll_interval); +uint8_t bt_drv_reg_op_get_role(uint8_t linkid); +int8_t bt_drv_reg_op_rssi_correction(int8_t rssi); +void bt_drv_reg_set_rssi_seed(uint32_t seed); +void bt_drv_reg_op_piconet_clk_offset_get(uint16_t connHandle, int32_t *clock_offset, uint16_t *bit_offset); +void bt_drv_reg_op_sw_seq_filter(uint16_t connHandle); +bool bt_drv_reg_op_check_bt_controller_state(void); +void bt_drv_reg_op_dma_tc_clkcnt_get(uint32_t *btclk, uint16_t *btcnt); + +void bt_drv_reg_op_clean_flags_of_ble_and_sco(void); +void bt_drv_reg_op_sco_txfifo_reset(uint16_t codec_id); +void bt_drv_reg_op_ibrt_retx_att_nb_set(uint8_t retx_nb); +void bt_drv_reg_op_acl_tx_type_set(uint16_t hciHandle, uint8_t slot_sel); +void bt_drv_reg_op_acl_tx_type_trace(uint16_t hciHandle); +uint8_t bt_drv_reg_op_acl_tx_type_get(uint16_t hciHandle, uint8_t* br_type, uint8_t* edr_type); +void bt_drv_reg_op_lm_nb_sync_hacker(uint8_t sco_status); + +void bt_drv_reg_op_afh_env_reset(void); +void bt_drv_reg_op_acl_tx_silence(uint16_t connHandle, uint8_t on); +void bt_drv_reg_op_acl_tx_silence_clear(uint16_t connHandle); + +void bt_drv_reg_op_ibrt_env_reset(void); +void btdrv_reg_op_set_private_tws_poll_interval(uint16_t poll_interval, uint16_t poll_interval_in_sco); +void btdrv_reg_op_enable_private_tws_schedule(bool enable); +void btdrv_reg_op_set_tws_link_duration(uint8_t slot_num); +void bt_drv_reg_op_decrease_tx_pwr_when_reconnect(bool enable); +void bt_drv_reg_op_controller_mem_log_config(void); +void bt_drv_reg_op_clear_ibrt_snoop_status(void); +uint8_t bt_drv_reg_op_linkcntl_aclltaddr_getf(uint16_t conhdl); +uint8_t bt_drv_reg_op_sync_bt_param(uint8_t* param, uint16_t len); +uint32_t bt_drv_reg_op_get_lc_env_ptr(uint16_t conhdl, uint8_t type); +void bt_drv_reg_op_set_tws_link_id(uint8_t link_id); +void bt_drv_reg_op_rx_slot_stop_lantency_checker(void); +void bt_drv_reg_op_hack_max_slot(uint8_t link_id,uint8_t slot); +void bt_drv_reg_op_fa_set(uint8_t en); +bool bt_drv_reg_op_check_seq_pending_status(void); +void bt_drv_reg_op_clear_seq_pending_status(void); +void bt_dev_clear_verison_receive_flag(uint8_t linkid); +void bt_drv_reg_op_fastack_status_checker(uint16_t conhdl); +void bt_drv_reg_op_set_link_policy(uint8_t linkid, uint8_t policy); +uint8_t bt_drv_reg_op_lmp_sco_hdl_get(uint16_t sco_handle); +bool bt_drv_reg_op_lmp_sco_hdl_set(uint16_t sco_handle, uint8_t lmp_hdl); +void bt_drv_reg_op_controller_state_checker(void); +void bt_drv_reg_op_controller_ble_flow_checker(void); +void bt_drv_reg_op_force_set_lc_state(uint16_t conhdl, uint8_t state); +uint8_t bt_drv_reg_op_force_get_lc_state(uint16_t conhdl); +void bt_drv_digital_config_for_ble_adv(bool en); +void bt_drv_reg_op_fa_gain_direct_set(uint8_t gain_idx); +uint8_t bt_drv_reg_op_fa_gain_direct_get(void); +void bt_drv_reg_op_dgb_link_gain_ctrl_set(uint16_t connHandle, uint8_t bt_ble_mode, uint8_t gain_idx, uint8_t enable); +void bt_drv_reg_op_dgb_link_gain_ctrl_clear(uint16_t connHandle, uint8_t bt_ble_mode); +void bt_drv_reg_op_dgb_link_gain_ctrl_init(void); +void bt_drv_reg_op_rx_gain_fix(uint16_t connHandle, uint8_t bt_ble_mode, uint8_t gain_idx, uint8_t enable, uint8_t table_idx); +void bt_drv_reg_op_afh_follow_en(bool enable, uint8_t be_followed_link_id, uint8_t follow_link_id); +/// Index for DM1 packet type (used in both BR and EDR) +#define DM1_IDX 0 +/// Enhanced Data Rate packet types indexes (classified by packet size) +#define DH1_2_IDX 1 +#define DH1_3_IDX 2 +#define DH3_2_IDX 3 +#define DH3_3_IDX 4 +#define DH5_2_IDX 5 +#define DH5_3_IDX 6 + +#define USE_1_SLOT_PACKET 0x02 +#define USE_3_SLOT_PACKET 0x04 +#define USE_5_SLOT_PACKET 0x06 + +///Sniffer sco status +#define SNIFFER_SCO_STOP 0 +#define SNIFFER_SCO_START 1 +#define SNIFFER_SCO_RESTART 2 +#define SNIFFER_SCO_RESUME_AFTER_TO 3 +#define SNIFFER_ACL_DISCONNECT_STOP_SCO 4 +#define SNIFFER_IBRT_START 5 +#define SNIFFER_IBRT_STOP 6 +#define IDEL_CHECK 0xff + +enum REG_OP +{ + READ_OP, + WRITE_OP, +}; + +enum LC_ENV_TAG +{ + LC_LINK_TAG, + LC_INFO_TAG, + LC_ENC_TAG, + LC_AFH_TAG, + LC_SP_TAG, + LC_EPR_TAG, + LC_EPC_TAG, +}; + +void bt_drv_reg_op_hw_sw_agc_select(uint8_t agc_mode); +void bt_drv_reg_op_force_set_sniff_att(uint16_t conhdle); +void bt_drv_reg_op_voice_settings_set(uint16_t voice_settings); +void bt_drv_reg_op_host_buff_and_flow_ctl_set +(uint16_t acl_pkt_len, uint16_t acl_pkt_num,uint16_t sync_pkt_len, uint16_t sync_pkt_num,bool flow_ctl_en); + +void bt_drv_reg_op_page_to_set(uint16_t page_to); +void bt_drv_reg_op_btdm_address_set(uint8_t* bt_addr, uint8_t* ble_addr); +void bt_drv_reg_op_evtmask_set(uint8_t ble_en); +void bt_drv_reg_op_simplepair_mode_set(uint8_t en); +void bt_drv_reg_op_class_of_dev_set(uint8_t* class_of_dev, uint8_t len); +void bt_drv_reg_op_sleep_set(bool en); +void bt_drv_reg_op_sco_fifo_reset(void); +void bt_drv_reg_sco_fifo_dump(void); +uint8_t bt_drv_reg_op_get_sync_id_op(uint8_t op, uint8_t sync_id); +void bt_drv_reg_op_set_agc_thd(bool isMaster, bool isSco); +void bt_drv_reg_op_global_symbols_init(void); +void bt_drv_tx_pwr_init(void); +void bt_drv_tx_pwr_init_for_testmode(void); +void bt_drv_reg_op_set_ibrt_auto_accept_sco(bool en); +void bt_drv_reg_op_update_dbg_state(void); +void bt_drv_reg_op_set_ibrt_reject_sniff_req(bool en); +uint8_t bt_drv_reg_op_get_esco_nego_airmode(uint8_t sco_link_id); +void bt_drv_reg_op_hci_vender_ibrt_ll_monitor(uint8_t* ptr, uint16_t* p_sum_err,uint16_t* p_rx_total); +uint32_t bt_drv_reg_op_get_host_ref_clk(void); +void bt_drv_reg_op_set_accept_new_mobile_enable(void); +void bt_drv_reg_op_clear_accept_new_mobile_enable(void); +void bt_drv_reg_op_ecc_softbit_process(uint16_t* p_conn_handle1,uint16_t* p_conn_handle2, uint16_t length, uint8_t *data); +void bt_drv_reg_op_ebq_test_setting(void); +void bt_drv_reg_op_hw_spi_en_setf(int elt_idx, uint8_t hwspien); +void bt_drv_enhance_fa_mode(bool enable); +void bt_drv_reg_op_set_rand_seed(uint32_t seed); +void bt_drv_reg_op_swagc_mode_set(uint8_t mode); +void bt_drv_reg_op_set_max_pwr_rcv(uint16_t connHandle); +void bt_drv_reg_op_key_gen_after_reset(bool enable); +uint8_t bt_drv_reg_op_bt_sync_swagc_en_get(void); +void bt_drv_reg_op_ble_sup_timeout_set(uint16_t ble_conhdl, uint16_t sup_to); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/btpcm/Makefile b/platform/drivers/btpcm/Makefile new file mode 100644 index 0000000..ad29ced --- /dev/null +++ b/platform/drivers/btpcm/Makefile @@ -0,0 +1,5 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) diff --git a/platform/drivers/btpcm/btpcm.c b/platform/drivers/btpcm/btpcm.c new file mode 100644 index 0000000..6192d94 --- /dev/null +++ b/platform/drivers/btpcm/btpcm.c @@ -0,0 +1,119 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "hal_trace.h" +//#include "hwtest.h" +//#include "hal_intersys.h" +//#include "hal_spi.h" +//#include "hal_cmu.h" +//#include "hal_sleep.h" +#include "hal_dma.h" +#include "stdbool.h" +#include "string.h" +#include "hal_btpcm.h" + +#if 0 +#define AUDIO_BUFFER_SIZE 2048 + +struct HAL_BTPCM_CONFIG_T btpcm_cfg; +struct HAL_DMA_CH_CFG_T dma_cfg; +struct HAL_DMA_DESC_T play_desc; +struct HAL_DMA_DESC_T record_desc; +uint32_t play_buffer[AUDIO_BUFFER_SIZE / 4]; +uint32_t record_buffer[AUDIO_BUFFER_SIZE / 4]; + +//pcm:rx-->codec:spk +static void btpcm2codec(void) +{ + memset(&dma_cfg, 0, sizeof(dma_cfg)); + dma_cfg.ch = hal_audma_get_chan(HAL_DMA_HIGH_PRIO); + dma_cfg.src_periph = (enum HAL_DMA_PERIPH_T)0; + dma_cfg.handler = NULL; + dma_cfg.dst_periph = HAL_AUDMA_BTPCM_TX; + dma_cfg.type = HAL_DMA_FLOW_M2P_DMA; + + dma_cfg.dst_bsize = HAL_DMA_BSIZE_4; + dma_cfg.src_bsize = HAL_DMA_BSIZE_4; + dma_cfg.dst_width = HAL_DMA_WIDTH_HALFWORD; + dma_cfg.src_width = HAL_DMA_WIDTH_HALFWORD; + dma_cfg.src_tsize = AUDIO_BUFFER_SIZE/2; /* cause of half word width */ + dma_cfg.try_burst = 1; + + dma_cfg.src = (uint32_t)play_buffer; + hal_audma_init_desc(&play_desc, &dma_cfg, &play_desc, 0); + hal_audma_sg_start(&play_desc, &dma_cfg); + + dma_cfg.ch = hal_audma_get_chan(HAL_DMA_HIGH_PRIO); + dma_cfg.dst_periph = (enum HAL_DMA_PERIPH_T)0; + dma_cfg.handler = NULL; + dma_cfg.src_periph = HAL_AUDMA_BTPCM_RX; + dma_cfg.type = HAL_DMA_FLOW_P2M_DMA; + + dma_cfg.dst = (uint32_t)record_buffer; + hal_audma_init_desc(&record_desc, &dma_cfg, &record_desc, 0); + hal_audma_sg_start(&record_desc, &dma_cfg); + + hal_btpcm_open(HAL_BTPCM_ID_0, AUD_STREAM_PLAYBACK); + hal_btpcm_open(HAL_BTPCM_ID_0, AUD_STREAM_CAPTURE); + memset(&btpcm_cfg, 0, sizeof(btpcm_cfg)); + btpcm_cfg.use_dma = 1; + hal_btpcm_setup_stream(HAL_BTPCM_ID_0, AUD_STREAM_PLAYBACK, &btpcm_cfg); + hal_btpcm_setup_stream(HAL_BTPCM_ID_0, AUD_STREAM_CAPTURE, &btpcm_cfg); + hal_btpcm_start_stream(HAL_BTPCM_ID_0, AUD_STREAM_PLAYBACK); + hal_btpcm_start_stream(HAL_BTPCM_ID_0, AUD_STREAM_CAPTURE); +} + +//codec:mic-->pcm:tx +static void codec2btpcm(void) +{ + memset(&dma_cfg, 0, sizeof(dma_cfg)); + dma_cfg.ch = hal_audma_get_chan(HAL_DMA_HIGH_PRIO); + dma_cfg.src_periph = (enum HAL_DMA_PERIPH_T)0; + dma_cfg.handler = NULL; + dma_cfg.dst_periph = HAL_AUDMA_BTPCM_TX; + dma_cfg.type = HAL_DMA_FLOW_M2P_DMA; + + dma_cfg.dst_bsize = HAL_DMA_BSIZE_4; + dma_cfg.src_bsize = HAL_DMA_BSIZE_4; + dma_cfg.dst_width = HAL_DMA_WIDTH_HALFWORD; + dma_cfg.src_width = HAL_DMA_WIDTH_HALFWORD; + dma_cfg.src_tsize = AUDIO_BUFFER_SIZE/2; /* cause of half word width */ + dma_cfg.try_burst = 1; + + dma_cfg.src = (uint32_t)play_buffer; + hal_audma_init_desc(&play_desc, &dma_cfg, &play_desc, 0); + hal_audma_sg_start(&play_desc, &dma_cfg); + + dma_cfg.ch = hal_audma_get_chan(HAL_DMA_HIGH_PRIO); + dma_cfg.dst_periph = (enum HAL_DMA_PERIPH_T)0; + dma_cfg.handler = NULL; + dma_cfg.src_periph = HAL_AUDMA_BTPCM_RX; + dma_cfg.type = HAL_DMA_FLOW_P2M_DMA; + + dma_cfg.dst = (uint32_t)record_buffer; + hal_audma_init_desc(&record_desc, &dma_cfg, &record_desc, 0); + hal_audma_sg_start(&record_desc, &dma_cfg); + + hal_btpcm_open(HAL_BTPCM_ID_0, AUD_STREAM_PLAYBACK); + hal_btpcm_open(HAL_BTPCM_ID_0, AUD_STREAM_CAPTURE); + memset(&btpcm_cfg, 0, sizeof(btpcm_cfg)); + btpcm_cfg.use_dma = 1; + hal_btpcm_setup_stream(HAL_BTPCM_ID_0, AUD_STREAM_PLAYBACK, &btpcm_cfg); + hal_btpcm_setup_stream(HAL_BTPCM_ID_0, AUD_STREAM_CAPTURE, &btpcm_cfg); + hal_btpcm_start_stream(HAL_BTPCM_ID_0, AUD_STREAM_PLAYBACK); + hal_btpcm_start_stream(HAL_BTPCM_ID_0, AUD_STREAM_CAPTURE); +} +#endif diff --git a/platform/drivers/btpcm/btpcm.h b/platform/drivers/btpcm/btpcm.h new file mode 100644 index 0000000..47f05be --- /dev/null +++ b/platform/drivers/btpcm/btpcm.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BTPCM_H__ +#define __BTPCM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif//__FMDEC_H__ diff --git a/platform/drivers/codec/Makefile b/platform/drivers/codec/Makefile new file mode 100644 index 0000000..67d0371 --- /dev/null +++ b/platform/drivers/codec/Makefile @@ -0,0 +1,34 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) + +obj-y += $(CHIP)/ + +subdir-ccflags-y += -Iplatform/drivers/codec + +export CODEC_INT_CFG_FLAGS := + +CODEC_INT_CFG_FLAGS += -Iplatform/drivers/ana + +ifeq ($(AUDIO_CODEC_ASYNC_CLOSE),1) +CODEC_INT_CFG_FLAGS += -D__CODEC_ASYNC_CLOSE__ +endif + +ifeq ($(AUDIO_RESAMPLE),1) +CODEC_INT_CFG_FLAGS += -D__AUDIO_RESAMPLE__ +endif + +ifeq ($(ANC_L_R_MISALIGN_WORKAROUND),1) +CODEC_INT_CFG_FLAGS += -DANC_L_R_MISALIGN_WORKAROUND +endif + +ifeq ($(AUDIO_OUTPUT_DC_CALIB),1) +CODEC_INT_CFG_FLAGS += -DAUDIO_OUTPUT_DC_CALIB +endif + +ifeq ($(CODEC_ANC_BOOST),1) +CODEC_INT_CFG_FLAGS += -DCODEC_ANC_BOOST +endif + diff --git a/platform/drivers/codec/best2300p/Makefile b/platform/drivers/codec/best2300p/Makefile new file mode 100644 index 0000000..b81e5cd --- /dev/null +++ b/platform/drivers/codec/best2300p/Makefile @@ -0,0 +1,8 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) + +CFLAGS_codec_$(CHIP).o += $(CODEC_INT_CFG_FLAGS) + diff --git a/platform/drivers/codec/best2300p/codec_best2300p.c b/platform/drivers/codec/best2300p/codec_best2300p.c new file mode 100644 index 0000000..269d89f --- /dev/null +++ b/platform/drivers/codec/best2300p/codec_best2300p.c @@ -0,0 +1,688 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "codec_int.h" +#include "hal_codec.h" +#include "hal_trace.h" +#include "hal_sleep.h" +#include "stdbool.h" +#include "analog.h" +#include "tgt_hardware.h" + +#define CODEC_TRACE(n, s, ...) TRACE(n, s, ##__VA_ARGS__) + +#define CODEC_INT_INST HAL_CODEC_ID_0 + +#ifndef CODEC_OUTPUT_DEV +#define CODEC_OUTPUT_DEV CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV +#endif + +#ifdef __CODEC_ASYNC_CLOSE__ +#include "cmsis_os.h" + +#define CODEC_ASYNC_CLOSE_DELAY (5000) + +static void codec_timehandler(void const *param); + +osTimerDef (CODEC_TIMER, codec_timehandler); +static osTimerId codec_timer; +static CODEC_CLOSE_HANDLER close_hdlr; + +enum CODEC_HW_STATE_T { + CODEC_HW_STATE_CLOSED, + CODEC_HW_STATE_CLOSE_PENDING, + CODEC_HW_STATE_OPENED, +}; + +enum CODEC_HW_STATE_T codec_hw_state = CODEC_HW_STATE_CLOSED; +#endif + +enum CODEC_USER_T { + CODEC_USER_STREAM = (1 << 0), + CODEC_USER_ANC = (1 << 1), + CODEC_USER_VAD = (1 << 2), +}; + +struct CODEC_CONFIG_T { + enum CODEC_USER_T user_map; + bool resample_en; + bool mute_state[AUD_STREAM_NUM]; + bool chan_vol_set[AUD_STREAM_NUM]; + struct STREAM_CONFIG_T { + bool opened; + bool started; + struct HAL_CODEC_CONFIG_T codec_cfg; + } stream_cfg[AUD_STREAM_NUM]; +}; + +static struct CODEC_CONFIG_T codec_int_cfg = { + .user_map = 0, + .resample_en = false, + .mute_state = { false, false, }, + .chan_vol_set = { false, false, }, + //playback + .stream_cfg[AUD_STREAM_PLAYBACK] = { + .opened = false, + .started = false, + .codec_cfg = { + .sample_rate = AUD_SAMPRATE_NULL, + } + }, + //capture + .stream_cfg[AUD_STREAM_CAPTURE] = { + .opened = false, + .started = false, + .codec_cfg = { + .sample_rate = AUD_SAMPRATE_NULL, + } + } +}; + +static bool anc_ff_enabled; +static bool anc_fb_enabled; +static enum AUD_SAMPRATE_T codec_anc_samp_rate; +static CODEC_ANC_HANDLER codec_anc_handler; + +#ifdef VOICE_DETECTOR_EN +static enum AUD_VAD_TYPE_T vad_type; +#endif + +#ifdef CODEC_ANC_BOOST +static CODEC_ANC_BOOST_DELAY_FUNC boost_delay; + +void codec_set_anc_boost_delay_func(CODEC_ANC_BOOST_DELAY_FUNC delay_func) +{ + boost_delay = delay_func; +} +#endif + +uint32_t codec_int_stream_open(enum AUD_STREAM_T stream) +{ + CODEC_TRACE(2,"%s: stream=%d", __func__, stream); + codec_int_cfg.stream_cfg[stream].opened = true; + return 0; +} + +uint32_t codec_int_stream_setup(enum AUD_STREAM_T stream, struct HAL_CODEC_CONFIG_T *cfg) +{ + enum AUD_CHANNEL_MAP_T ch_map; + + CODEC_TRACE(2,"%s: stream=%d", __func__, stream); + + if (codec_int_cfg.stream_cfg[stream].codec_cfg.sample_rate == AUD_SAMPRATE_NULL) { + // Codec uninitialized -- all config items should be set + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag = HAL_CODEC_CONFIG_ALL; + } else { + // Codec initialized before -- only different config items need to be set + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag = HAL_CODEC_CONFIG_NULL; + } + + // Always config sample rate, for the pll setting might have been changed by the other stream + CODEC_TRACE(2,"[sample_rate]old=%d new=%d", codec_int_cfg.stream_cfg[stream].codec_cfg.sample_rate, cfg->sample_rate); + if (codec_int_cfg.user_map & CODEC_USER_ANC) { + // Check ANC sample rate + if (codec_anc_handler) { + enum AUD_SAMPRATE_T cfg_rate; + enum AUD_SAMPRATE_T old_rate; + + cfg_rate = hal_codec_anc_convert_rate(cfg->sample_rate); + if (cfg_rate != codec_anc_samp_rate) { + old_rate = codec_anc_samp_rate; + + codec_anc_handler(stream, cfg_rate, NULL, NULL); + + codec_anc_samp_rate = cfg_rate; + TRACE(5,"%s: ANC sample rate changes from %u to %u due to stream=%d samp_rate=%u", + __func__, old_rate, codec_anc_samp_rate, stream, cfg->sample_rate); + } + } + } + codec_int_cfg.stream_cfg[stream].codec_cfg.sample_rate = cfg->sample_rate; + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag |= HAL_CODEC_CONFIG_SAMPLE_RATE; + + if(codec_int_cfg.stream_cfg[stream].codec_cfg.bits != cfg->bits) + { + CODEC_TRACE(2,"[bits]old=%d new=%d", codec_int_cfg.stream_cfg[stream].codec_cfg.bits, cfg->bits); + codec_int_cfg.stream_cfg[stream].codec_cfg.bits = cfg->bits; + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag |= HAL_CODEC_CONFIG_BITS; + } + + if(codec_int_cfg.stream_cfg[stream].codec_cfg.channel_num != cfg->channel_num) + { + CODEC_TRACE(2,"[channel_num]old=%d new=%d", codec_int_cfg.stream_cfg[stream].codec_cfg.channel_num, cfg->channel_num); + codec_int_cfg.stream_cfg[stream].codec_cfg.channel_num = cfg->channel_num; + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag |= HAL_CODEC_CONFIG_CHANNEL_NUM; + } + + ch_map = cfg->channel_map; + if (ch_map == 0) { + if (stream == AUD_STREAM_PLAYBACK) { + ch_map = (enum AUD_CHANNEL_MAP_T)CODEC_OUTPUT_DEV; + } else { + ch_map = (enum AUD_CHANNEL_MAP_T)hal_codec_get_input_path_cfg(cfg->io_path); + } + ch_map &= AUD_CHANNEL_MAP_ALL; + } + + if(codec_int_cfg.stream_cfg[stream].codec_cfg.channel_map != ch_map) + { + CODEC_TRACE(2,"[channel_map]old=0x%x new=0x%x", codec_int_cfg.stream_cfg[stream].codec_cfg.channel_map, ch_map); + codec_int_cfg.stream_cfg[stream].codec_cfg.channel_map = ch_map; + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag |= HAL_CODEC_CONFIG_CHANNEL_MAP | HAL_CODEC_CONFIG_VOL | HAL_CODEC_CONFIG_BITS; + } + + if(codec_int_cfg.stream_cfg[stream].codec_cfg.use_dma != cfg->use_dma) + { + CODEC_TRACE(2,"[use_dma]old=%d new=%d", codec_int_cfg.stream_cfg[stream].codec_cfg.use_dma, cfg->use_dma); + codec_int_cfg.stream_cfg[stream].codec_cfg.use_dma = cfg->use_dma; + } + + if(codec_int_cfg.stream_cfg[stream].codec_cfg.vol != cfg->vol) + { + CODEC_TRACE(3,"[vol]old=%d new=%d chan_vol_set=%d", codec_int_cfg.stream_cfg[stream].codec_cfg.vol, cfg->vol, codec_int_cfg.chan_vol_set[stream]); + codec_int_cfg.stream_cfg[stream].codec_cfg.vol = cfg->vol; + if (!codec_int_cfg.chan_vol_set[stream]) { + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag |= HAL_CODEC_CONFIG_VOL; + } + } + + if(codec_int_cfg.stream_cfg[stream].codec_cfg.io_path != cfg->io_path) + { + CODEC_TRACE(2,"[io_path]old=%d new=%d", codec_int_cfg.stream_cfg[stream].codec_cfg.io_path, cfg->io_path); + codec_int_cfg.stream_cfg[stream].codec_cfg.io_path = cfg->io_path; + } + + CODEC_TRACE(3,"[%s]stream=%d set_flag=0x%x",__func__,stream,codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag); + hal_codec_setup_stream(CODEC_INT_INST, stream, &(codec_int_cfg.stream_cfg[stream].codec_cfg)); + + return 0; +} + +void codec_int_stream_mute(enum AUD_STREAM_T stream, bool mute) +{ + bool anc_on; + + CODEC_TRACE(3,"%s: stream=%d mute=%d", __func__, stream, mute); + + if (mute == codec_int_cfg.mute_state[stream]) { + CODEC_TRACE(2,"[%s] Codec already in mute status: %d", __func__, mute); + return; + } + + anc_on = !!(codec_int_cfg.user_map & CODEC_USER_ANC); + + if (stream == AUD_STREAM_PLAYBACK) { + if (mute) { + if (!anc_on) { + analog_aud_codec_mute(); + } + hal_codec_dac_mute(true); + } else { + hal_codec_dac_mute(false); + if (!anc_on) { + analog_aud_codec_nomute(); + } + } + } else { + hal_codec_adc_mute(mute); + } + + codec_int_cfg.mute_state[stream] = mute; +} + +void codec_int_stream_set_chan_vol(enum AUD_STREAM_T stream, enum AUD_CHANNEL_MAP_T ch_map, uint8_t vol) +{ + CODEC_TRACE(4,"%s: stream=%d ch_map=0x%X vol=%u", __func__, stream, ch_map, vol); + + codec_int_cfg.chan_vol_set[stream] = true; + hal_codec_set_chan_vol(stream, ch_map, vol); +} + +void codec_int_stream_restore_chan_vol(enum AUD_STREAM_T stream) +{ + CODEC_TRACE(2,"%s: stream=%d", __func__, stream); + + if (codec_int_cfg.chan_vol_set[stream]) { + codec_int_cfg.chan_vol_set[stream] = false; + // Restore normal volume + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag = HAL_CODEC_CONFIG_VOL; + hal_codec_setup_stream(CODEC_INT_INST, stream, &(codec_int_cfg.stream_cfg[stream].codec_cfg)); + } +} + +static void codec_hw_start(enum AUD_STREAM_T stream) +{ + CODEC_TRACE(2,"%s: stream=%d", __func__, stream); + + if (stream == AUD_STREAM_PLAYBACK) { + // Enable DAC before starting stream (specifically before enabling PA) + analog_aud_codec_dac_enable(true); + } + + hal_codec_start_stream(CODEC_INT_INST, stream); +} + +static void codec_hw_stop(enum AUD_STREAM_T stream) +{ + CODEC_TRACE(2,"%s: stream=%d", __func__, stream); + + hal_codec_stop_stream(CODEC_INT_INST, stream); + + if (stream == AUD_STREAM_PLAYBACK) { + // Disable DAC after stopping stream (specifically after disabling PA) + analog_aud_codec_dac_enable(false); + } +} + +uint32_t codec_int_stream_start(enum AUD_STREAM_T stream) +{ + CODEC_TRACE(2,"%s: stream=%d", __func__, stream); + + codec_int_cfg.stream_cfg[stream].started = true; + + if (stream == AUD_STREAM_CAPTURE) { + analog_aud_codec_adc_enable(codec_int_cfg.stream_cfg[stream].codec_cfg.io_path, + codec_int_cfg.stream_cfg[stream].codec_cfg.channel_map, true); + } + + hal_codec_start_interface(CODEC_INT_INST, stream, + codec_int_cfg.stream_cfg[stream].codec_cfg.use_dma); + + if ((codec_int_cfg.user_map & CODEC_USER_ANC) == 0) { + codec_hw_start(stream); + } + + return 0; +} + +uint32_t codec_int_stream_stop(enum AUD_STREAM_T stream) +{ + CODEC_TRACE(2,"%s: stream=%d", __func__, stream); + + hal_codec_stop_interface(CODEC_INT_INST, stream); + + if ((codec_int_cfg.user_map & CODEC_USER_ANC) == 0) { + codec_hw_stop(stream); + } + + if (stream == AUD_STREAM_CAPTURE) { + analog_aud_codec_adc_enable(codec_int_cfg.stream_cfg[stream].codec_cfg.io_path, + codec_int_cfg.stream_cfg[stream].codec_cfg.channel_map, false); + } + + codec_int_cfg.stream_cfg[stream].started = false; + + return 0; +} + +uint32_t codec_int_stream_close(enum AUD_STREAM_T stream) +{ + //close all stream + CODEC_TRACE(2,"%s: stream=%d", __func__, stream); + if (codec_int_cfg.stream_cfg[stream].started) { + codec_int_stream_stop(stream); + } + codec_int_stream_restore_chan_vol(stream); + codec_int_cfg.stream_cfg[stream].opened = false; + return 0; +} + +static void codec_hw_open(enum CODEC_USER_T user) +{ + enum CODEC_USER_T old_map; +#ifdef __AUDIO_RESAMPLE__ + bool resample_en = !!hal_cmu_get_audio_resample_status(); +#endif + + old_map = codec_int_cfg.user_map; + codec_int_cfg.user_map |= user; + + if (old_map) { +#ifdef __AUDIO_RESAMPLE__ + ASSERT(codec_int_cfg.resample_en == resample_en, + "%s: Bad resamp status %d for user 0x%X (old_map=0x%X)", __func__, resample_en, user, old_map); +#endif + return; + } + +#ifdef __AUDIO_RESAMPLE__ + codec_int_cfg.resample_en = resample_en; +#endif + + CODEC_TRACE(1,"%s", __func__); + +#ifdef __CODEC_ASYNC_CLOSE__ + if (codec_timer == NULL) { + codec_timer = osTimerCreate (osTimer(CODEC_TIMER), osTimerOnce, NULL); + } + osTimerStop(codec_timer); +#endif + + // Audio resample: Might have different clock source, so must be reconfigured here + hal_codec_open(CODEC_INT_INST); + +#ifdef __CODEC_ASYNC_CLOSE__ + CODEC_TRACE(2,"%s: codec_hw_state=%d", __func__, codec_hw_state); + + if (codec_hw_state == CODEC_HW_STATE_CLOSED) { + codec_hw_state = CODEC_HW_STATE_OPENED; + // Continue to open the codec hardware + } else if (codec_hw_state == CODEC_HW_STATE_CLOSE_PENDING) { + // Still opened + codec_hw_state = CODEC_HW_STATE_OPENED; + return; + } else { + // Already opened + return; + } +#endif + + analog_aud_codec_open(); +} + +static void codec_hw_close(enum CODEC_CLOSE_TYPE_T type, enum CODEC_USER_T user) +{ + codec_int_cfg.user_map &= ~user; + + if (type == CODEC_CLOSE_NORMAL) { + if (codec_int_cfg.user_map) { + return; + } + } + +#ifdef __CODEC_ASYNC_CLOSE__ + CODEC_TRACE(3,"%s: type=%d codec_hw_state=%d", __func__, type, codec_hw_state); +#else + CODEC_TRACE(2,"%s: type=%d", __func__, type); +#endif + + if (type == CODEC_CLOSE_NORMAL) { + // Audio resample: Might have different clock source, so close now and reconfigure when open + hal_codec_close(CODEC_INT_INST); +#ifdef CODEC_POWER_DOWN + memset(&codec_int_cfg, 0, sizeof(codec_int_cfg)); +#endif +#ifdef __CODEC_ASYNC_CLOSE__ + ASSERT(codec_hw_state == CODEC_HW_STATE_OPENED, "%s: (type=%d) Bad codec_hw_state=%d", __func__, type, codec_hw_state); + // Start a timer to close the codec hardware + codec_hw_state = CODEC_HW_STATE_CLOSE_PENDING; + osTimerStop(codec_timer); + osTimerStart(codec_timer, CODEC_ASYNC_CLOSE_DELAY); + return; + } else if (type == CODEC_CLOSE_ASYNC_REAL) { + if (codec_hw_state != CODEC_HW_STATE_CLOSE_PENDING) { + // Already closed or reopened + return; + } + codec_hw_state = CODEC_HW_STATE_CLOSED; +#endif + } else if (type == CODEC_CLOSE_FORCED) { + hal_codec_crash_mute(); + } + + analog_aud_codec_close(); +} + +uint32_t codec_int_open(void) +{ + CODEC_TRACE(2,"%s: user_map=0x%X", __func__, codec_int_cfg.user_map); + + codec_hw_open(CODEC_USER_STREAM); + + return 0; +} + +uint32_t codec_int_close(enum CODEC_CLOSE_TYPE_T type) +{ + CODEC_TRACE(3,"%s: type=%d user_map=0x%X", __func__, type, codec_int_cfg.user_map); + + if (type == CODEC_CLOSE_NORMAL) { + if (codec_int_cfg.stream_cfg[AUD_STREAM_PLAYBACK].opened == false && + codec_int_cfg.stream_cfg[AUD_STREAM_CAPTURE].opened == false){ + codec_hw_close(type, CODEC_USER_STREAM); + } + } else { + codec_hw_close(type, CODEC_USER_STREAM); + } + + return 0; +} + +#ifdef __CODEC_ASYNC_CLOSE__ +void codec_int_set_close_handler(CODEC_CLOSE_HANDLER hdlr) +{ + close_hdlr = hdlr; +} + +static void codec_timehandler(void const *param) +{ + if (close_hdlr) { + close_hdlr(); + } +} +#endif + +int codec_anc_open(enum ANC_TYPE_T type, enum AUD_SAMPRATE_T dac_rate, enum AUD_SAMPRATE_T adc_rate, CODEC_ANC_HANDLER hdlr) +{ + bool anc_running = false; + + CODEC_TRACE(4,"%s: type=%d dac_rate=%d adc_rate=%d", __func__, type, dac_rate, adc_rate); + + dac_rate = hal_codec_anc_convert_rate(dac_rate); + adc_rate = hal_codec_anc_convert_rate(adc_rate); + ASSERT(dac_rate == adc_rate, "%s: Unmatched rates: dac_rate=%u adc_rate=%u", __func__, dac_rate, adc_rate); + + if (hdlr && (codec_int_cfg.user_map & CODEC_USER_STREAM)) { + enum AUD_SAMPRATE_T cfg_dac_rate, cfg_adc_rate; + + if (codec_int_cfg.stream_cfg[AUD_STREAM_PLAYBACK].opened) { + cfg_dac_rate = hal_codec_anc_convert_rate(codec_int_cfg.stream_cfg[AUD_STREAM_PLAYBACK].codec_cfg.sample_rate); + } else { + cfg_dac_rate = dac_rate; + } + if (codec_int_cfg.stream_cfg[AUD_STREAM_CAPTURE].opened) { + cfg_adc_rate = hal_codec_anc_convert_rate(codec_int_cfg.stream_cfg[AUD_STREAM_CAPTURE].codec_cfg.sample_rate); + } else { + cfg_adc_rate = adc_rate; + } + if (codec_int_cfg.stream_cfg[AUD_STREAM_PLAYBACK].opened && codec_int_cfg.stream_cfg[AUD_STREAM_CAPTURE].opened) { + ASSERT(cfg_dac_rate == cfg_adc_rate, "%s: Unmatched cfg rates: dac_rate=%u adc_rate=%u", __func__, cfg_dac_rate, cfg_adc_rate); + } else if (codec_int_cfg.stream_cfg[AUD_STREAM_CAPTURE].opened) { + cfg_dac_rate = cfg_adc_rate; + } + if (dac_rate != cfg_dac_rate) { + hdlr(AUD_STREAM_PLAYBACK, cfg_dac_rate, NULL, NULL); + TRACE(3,"%s: ANC sample rate changes from %u to %u", __func__, dac_rate, cfg_dac_rate); + dac_rate = cfg_dac_rate; + } + } + + codec_anc_samp_rate = dac_rate; + codec_anc_handler = hdlr; + + if (anc_ff_enabled || anc_fb_enabled) { + anc_running = true; + } + + if (type == ANC_FEEDFORWARD) { + anc_ff_enabled = true; + } else if (type == ANC_FEEDBACK) { + anc_fb_enabled = true; + } + + if (!anc_running) { + hal_chip_wake_lock(HAL_CHIP_WAKE_LOCK_USER_ANC); + + hal_cmu_anc_enable(HAL_CMU_ANC_CLK_USER_ANC); + + enum AUD_STREAM_T stream; + enum AUD_CHANNEL_NUM_T play_chan_num; + + codec_hw_open(CODEC_USER_ANC); + + if (CODEC_OUTPUT_DEV == (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1)) { + play_chan_num = AUD_CHANNEL_NUM_2; + } else { + play_chan_num = AUD_CHANNEL_NUM_1; + } + + for (stream = AUD_STREAM_PLAYBACK; stream <= AUD_STREAM_CAPTURE; stream++) { + if (codec_int_cfg.stream_cfg[stream].opened) { + if (stream == AUD_STREAM_PLAYBACK) { + /* ASSERT(codec_int_cfg.stream_cfg[stream].codec_cfg.channel_num == play_chan_num, + "Invalid existing ANC channel num %d != %d for stream %d", + codec_int_cfg.stream_cfg[stream].codec_cfg.channel_num, + play_chan_num, + stream);*/ + } + } else { + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag = 0; + codec_int_cfg.stream_cfg[stream].codec_cfg.sample_rate = codec_anc_samp_rate; + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag |= HAL_CODEC_CONFIG_SAMPLE_RATE; + if (stream == AUD_STREAM_PLAYBACK) { + codec_int_cfg.stream_cfg[stream].codec_cfg.vol = TGT_VOLUME_LEVEL_10; + } else { + codec_int_cfg.stream_cfg[stream].codec_cfg.vol = CODEC_SADC_VOL; + } + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag |= HAL_CODEC_CONFIG_VOL; + if (stream == AUD_STREAM_PLAYBACK) { + codec_int_cfg.stream_cfg[stream].codec_cfg.channel_num = play_chan_num; + codec_int_cfg.stream_cfg[stream].codec_cfg.channel_map = CODEC_OUTPUT_DEV; + } else { + codec_int_cfg.stream_cfg[stream].codec_cfg.channel_num = 0; + codec_int_cfg.stream_cfg[stream].codec_cfg.channel_map = 0; + } + codec_int_cfg.stream_cfg[stream].codec_cfg.set_flag |= HAL_CODEC_CONFIG_CHANNEL_NUM; + + hal_codec_setup_stream(CODEC_INT_INST, stream, &(codec_int_cfg.stream_cfg[stream].codec_cfg)); + } + } + + // Start play first, then start capture last + for (stream = AUD_STREAM_PLAYBACK; stream <= AUD_STREAM_CAPTURE; stream++) { + if (!codec_int_cfg.stream_cfg[stream].started) { + codec_hw_start(stream); + } + } + } + + hal_codec_anc_adc_enable(type); + + analog_aud_codec_anc_enable(type, true); + + if (!anc_running) { + // Enable pa if dac muted before + if (codec_int_cfg.mute_state[AUD_STREAM_PLAYBACK]) { + analog_aud_codec_nomute(); + } + +#ifdef CODEC_ANC_BOOST + analog_aud_codec_anc_boost(true, (ANALOG_ANC_BOOST_DELAY_FUNC)boost_delay); +#endif + } + + return 0; +} + +int codec_anc_close(enum ANC_TYPE_T type) +{ + CODEC_TRACE(2,"%s: type=%d", __func__, type); + + if (type == ANC_FEEDFORWARD) { + anc_ff_enabled = false; + } else if (type == ANC_FEEDBACK) { + anc_fb_enabled = false; + } + + hal_codec_anc_adc_disable(type); + + analog_aud_codec_anc_enable(type, false); + + if (anc_ff_enabled || anc_fb_enabled) { + return 0; + } + +#ifdef CODEC_ANC_BOOST + analog_aud_codec_anc_boost(false, (ANALOG_ANC_BOOST_DELAY_FUNC)boost_delay); +#endif + + enum AUD_STREAM_T stream; + + // Stop capture first, then stop play last + for (stream = AUD_STREAM_CAPTURE; stream >= AUD_STREAM_PLAYBACK && stream <= AUD_STREAM_CAPTURE; stream--) { + if (!codec_int_cfg.stream_cfg[stream].started) { + codec_hw_stop(stream); + } + } + + codec_hw_close(CODEC_CLOSE_NORMAL, CODEC_USER_ANC); + + hal_cmu_anc_disable(HAL_CMU_ANC_CLK_USER_ANC); + + hal_chip_wake_unlock(HAL_CHIP_WAKE_LOCK_USER_ANC); + + // Disable pa if dac muted before + if (codec_int_cfg.mute_state[AUD_STREAM_PLAYBACK]) { + analog_aud_codec_mute(); + } + + codec_anc_handler = NULL; + + return 0; +} + +#ifdef VOICE_DETECTOR_EN +int codec_vad_open(const struct AUD_VAD_CONFIG_T *cfg) +{ + if (cfg->type == AUD_VAD_TYPE_NONE) { + return codec_vad_close(); + } + + if (vad_type == cfg->type) { + return 0; + } + + vad_type = cfg->type; + + if (codec_int_cfg.user_map == 0) { + codec_hw_open(CODEC_USER_VAD); + } + + hal_codec_vad_open(cfg); + + codec_int_cfg.user_map |= (1 << CODEC_USER_VAD); + + return 0; +} + +int codec_vad_close(void) +{ + if (vad_type == AUD_VAD_TYPE_NONE) { + return 0; + } + + vad_type = AUD_VAD_TYPE_NONE; + + codec_int_cfg.user_map &= ~(1 << CODEC_USER_VAD); + + if (codec_int_cfg.user_map == 0) { + codec_hw_close(CODEC_CLOSE_NORMAL, CODEC_USER_VAD); + } + + return 0; +} +#endif + diff --git a/platform/drivers/codec/best2300p/codec_best2300p.h b/platform/drivers/codec/best2300p/codec_best2300p.h new file mode 100644 index 0000000..fee03cb --- /dev/null +++ b/platform/drivers/codec/best2300p/codec_best2300p.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __CODEC_BEST2300P_H__ +#define __CODEC_BEST2300P_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*CODEC_ANC_BOOST_DELAY_FUNC)(uint32_t ms); + +void codec_set_anc_boost_delay_func(CODEC_ANC_BOOST_DELAY_FUNC delay_func); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/drivers/codec/codec_int.h b/platform/drivers/codec/codec_int.h new file mode 100644 index 0000000..74e8ccc --- /dev/null +++ b/platform/drivers/codec/codec_int.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __CODEC_INT_H__ +#define __CODEC_INT_H__ + +#include "plat_addr_map.h" +#include "plat_types.h" +#include "hal_codec.h" +#include "hal_aud.h" +#include CHIP_SPECIFIC_HDR(codec) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*CODEC_CLOSE_HANDLER)(void); + +enum CODEC_CLOSE_TYPE_T { + CODEC_CLOSE_NORMAL, + CODEC_CLOSE_ASYNC_REAL, + CODEC_CLOSE_FORCED, +}; + +uint32_t codec_int_open(void); +uint32_t codec_int_stream_open(enum AUD_STREAM_T stream); +uint32_t codec_int_stream_setup(enum AUD_STREAM_T stream, struct HAL_CODEC_CONFIG_T *cfg); +void codec_int_stream_mute(enum AUD_STREAM_T stream, bool mute); +void codec_int_stream_set_chan_vol(enum AUD_STREAM_T stream, enum AUD_CHANNEL_MAP_T ch_map, uint8_t vol); +void codec_int_stream_restore_chan_vol(enum AUD_STREAM_T stream); +uint32_t codec_int_stream_start(enum AUD_STREAM_T stream); +uint32_t codec_int_stream_stop(enum AUD_STREAM_T stream); +uint32_t codec_int_stream_close(enum AUD_STREAM_T stream); +uint32_t codec_int_close(enum CODEC_CLOSE_TYPE_T type); +void codec_int_set_close_handler(CODEC_CLOSE_HANDLER hdlr); + +typedef void (*CODEC_ANC_HANDLER)(enum AUD_STREAM_T stream, enum AUD_SAMPRATE_T rate, enum AUD_SAMPRATE_T *new_play, enum AUD_SAMPRATE_T *new_cap); + +int codec_anc_open(enum ANC_TYPE_T type, enum AUD_SAMPRATE_T dac_rate, enum AUD_SAMPRATE_T adc_rate, CODEC_ANC_HANDLER hdlr); +int codec_anc_close(enum ANC_TYPE_T type); + +int codec_vad_open(const struct AUD_VAD_CONFIG_T *cfg); +int codec_vad_close(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/drivers/codec/codec_tlv32aic32.c b/platform/drivers/codec/codec_tlv32aic32.c new file mode 100644 index 0000000..44e5969 --- /dev/null +++ b/platform/drivers/codec/codec_tlv32aic32.c @@ -0,0 +1,239 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "codec_tlv32aic32.h" +#include "hal_i2c.h" +#include "hal_i2s.h" +#include "hal_uart.h" +#include "hal_trace.h" +#include "string.h" + +#define TLV32AIC32_INST HAL_I2S_ID_0 + +static struct HAL_I2C_CONFIG_T _codec_i2c_cfg; + +static uint8_t sample_rate_div[] = { + 10, /* index is 0 */ + 15, + 20, + 25, + 30, + 35, + 40, + 45, + 50, + 55, + 60, +}; + +/* i2c write */ +static int codec_write(uint8_t reg_addr, uint8_t value) +{ + uint8_t buf[2]; + buf[0] = reg_addr; + buf[1] = value; + + return hal_i2c_task_send(HAL_I2C_ID_0, TLV32AIC32_I2C_ADDRESS, buf, 1 + 1, 0, 0); +} + +/* i2c read */ +#if 0 +static uint8_t codec_read(uint8_t reg_addr) +{ + uint8_t buf[2]; + + buf[0] = reg_addr; + buf[1] = 0; + + hal_i2c_task_recv(HAL_I2C_ID_0, TLV32AIC32_I2C_ADDRESS, &buf[0], 1, &buf[1], 1, 0, 0); + + return buf[1]; +} +#endif + +uint32_t tlv32aic32_open(void) +{ + _codec_i2c_cfg.mode = HAL_I2C_API_MODE_TASK; + _codec_i2c_cfg.use_dma = 0; + _codec_i2c_cfg.use_sync = 1; + _codec_i2c_cfg.speed = 20000; + _codec_i2c_cfg.as_master = 1; + hal_i2c_open(HAL_I2C_ID_0, &_codec_i2c_cfg); + + return 0; +} +uint32_t tlv32aic32_stream_open(enum AUD_STREAM_T stream) +{ + hal_i2s_open(TLV32AIC32_INST, stream, HAL_I2S_MODE_MASTER); + + return 0; +} + +uint32_t tlv32aic32_stream_setup(enum AUD_STREAM_T stream, struct tlv32aic32_config_t *cfg) +{ + uint32_t param = 0, i = 0; + + /* select page : 0*/ + codec_write(AIC3X_PAGE_SELECT, PAGE0_SELECT); + + /* soft reset : 1 */ + codec_write(AIC3X_RESET, SOFT_RESET); + + /* CLKDIV_IN uses mCLK : 102 , PLLDIV_IN use mCLK */ + codec_write(AIC3X_CLKGEN_CTRL_REG, 0x02); + + /* CODEC_CLK_IN uses CLKDIV : 101, CODEC_CLK_IN use CLKDIV_IN */ + codec_write(101, 0x00); + + /* PLL R value : 11, R is 1 */ + codec_write(AIC3X_OVRF_STATUS_AND_PLLR_REG, 0x1); + + /* PLL J value : 4, J is 8 */ + codec_write(AIC3X_PLL_PROGB_REG, 0x8); + + /* PLL D value : 5,6, D is 1920 */ + codec_write(AIC3X_PLL_PROGC_REG, 0x780>>6); + + codec_write(AIC3X_PLL_PROGD_REG, (0x780&0x3f)<<2); + + /* PLL disable and select Q value : 3, enable pll, Q is 2 */ + codec_write(AIC3X_PLL_PROGA_REG, 0x81); + + /* left and right DAC open : 7, open codec dac path and fref */ + if ((cfg->sample_rate%8000) == 0) { + /* 48000 */ + codec_write(AIC3X_CODEC_DATAPATH_REG, 0x0a); + param = 480000/cfg->sample_rate; + } + else { + /* 44100 */ + codec_write(AIC3X_CODEC_DATAPATH_REG, 0x8a); + param = 441000/cfg->sample_rate; + } + + for (i = 0; i < sizeof(sample_rate_div); ++i) { + if (param == sample_rate_div[i]) + break; + } + + if (i == sizeof(sample_rate_div)) { + i = 0; + } + + /* sample_rate divider : 2, default is /1 */ + codec_write(AIC3X_SAMPLE_RATE_SEL_REG, i<<4|i<<4); + + /* ctrl mode : 8, bitclock input, word clock input */ + codec_write(AIC3X_ASD_INTF_CTRLA, 0x20); + + /* Audio Serial Data Interface Control : 9, 16bit i2s mode */ + if (cfg->bits == AUD_BITS_16) + param = 0; + else if (cfg->bits == AUD_BITS_20) + param = 1; + else if (cfg->bits == AUD_BITS_24) + param = 2; + else if (cfg->bits == AUD_BITS_32) + param = 3; + else + param = 0; + + + codec_write(AIC3X_ASD_INTF_CTRLB, 0x00 | param<<4); + + /* out ac-coupled : 14, headset control */ + codec_write(AIC3X_HEADSET_DETECT_CTRL_B, 0x08); + + /* left and right DAC power on : 37 */ + //codec_write(DAC_PWR, 0xC0); + codec_write(DAC_PWR, 0xD0); + + /* out common-mode voltage : 40 */ + codec_write(HPOUT_SC, 0x00); + + /* out path select : 41 */ + codec_write(DAC_LINE_MUX, 0xA1); + + /* left DAC not muted : 43 */ + codec_write(LDAC_VOL, 0x0f); + + /* right DAC not muted : 44 */ + codec_write(RDAC_VOL, 0x0f); + + /* HPLOUT is not muted : 51 */ + codec_write(HPLOUT_CTRL, 0x9F); + + /* HPROUT is not muted : 65 */ + codec_write(HPROUT_CTRL, 0x9F); + + /* out short circuit protection : 38 */ + //codec_write(HPRCOM_CFG, 0x3A); + codec_write(HPRCOM_CFG, 0x22); + + /* input */ + /* mic bias : 25 */ + codec_write(MICBIAS_CTRL, 0x40); + /* left adc power : 19 */ + codec_write(LINE1L_2_LADC_CTRL, 0x04); + /* right adc power : 22 */ + codec_write(LINE1R_2_RADC_CTRL, 0x04); + /* left adc pga mute : 15 */ + codec_write(LADC_VOL, 0x0); + /* right adc pga mute : 16 */ + codec_write(RADC_VOL, 0x0); + /* adc flag : 36 */ + //TRACE(1,"tlv adc flag 0x%x", codec_read(ADC_FLAG)); + /* left adc pga mute : 15 */ + //TRACE(1,"tlv left adc pga 0x%x", codec_read(LADC_VOL)); + /* right adc pga mute : 16 */ + //TRACE(1,"tlv right adc pga 0x%x", codec_read(RADC_VOL)); + /* input end */ + + struct HAL_I2S_CONFIG_T i2s_cfg; + + memset(&i2s_cfg, 0, sizeof(i2s_cfg)); + i2s_cfg.use_dma = cfg->use_dma; + i2s_cfg.chan_sep_buf = cfg->chan_sep_buf; + i2s_cfg.sync_start = cfg->sync_start; + i2s_cfg.cycles = cfg->slot_cycles; + i2s_cfg.bits = cfg->bits; + i2s_cfg.channel_num = cfg->channel_num; + i2s_cfg.channel_map = cfg->channel_map; + i2s_cfg.sample_rate = cfg->sample_rate; + hal_i2s_setup_stream(TLV32AIC32_INST, stream, &i2s_cfg); + + return 0; +} + +uint32_t tlv32aic32_stream_start(enum AUD_STREAM_T stream) +{ + hal_i2s_start_stream(TLV32AIC32_INST, stream); + return 0; +} +uint32_t tlv32aic32_stream_stop(enum AUD_STREAM_T stream) +{ + hal_i2s_stop_stream(TLV32AIC32_INST, stream); + return 0; +} +uint32_t tlv32aic32_stream_close(enum AUD_STREAM_T stream) +{ + hal_i2s_close(TLV32AIC32_INST, stream); + return 0; +} +uint32_t tlv32aic32_close(void) +{ + return 0; +} diff --git a/platform/drivers/codec/codec_tlv32aic32.h b/platform/drivers/codec/codec_tlv32aic32.h new file mode 100644 index 0000000..33ffd02 --- /dev/null +++ b/platform/drivers/codec/codec_tlv32aic32.h @@ -0,0 +1,287 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef CODEC_TLV32AIC32_H +#define CODEC_TLV32AIC32_H + +#include "plat_types.h" +#include "hal_aud.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TLV32AIC32_I2C_ADDRESS 0x18 + +/* AIC3X register space */ +#define AIC3X_CACHEREGNUM 110 + +/* Page select register */ +#define AIC3X_PAGE_SELECT 0 +/* Software reset register */ +#define AIC3X_RESET 1 +/* Codec Sample rate select register */ +#define AIC3X_SAMPLE_RATE_SEL_REG 2 +/* PLL progrramming register A */ +#define AIC3X_PLL_PROGA_REG 3 +/* PLL progrramming register B */ +#define AIC3X_PLL_PROGB_REG 4 +/* PLL progrramming register C */ +#define AIC3X_PLL_PROGC_REG 5 +/* PLL progrramming register D */ +#define AIC3X_PLL_PROGD_REG 6 +/* Codec datapath setup register */ +#define AIC3X_CODEC_DATAPATH_REG 7 +/* Audio serial data interface control register A */ +#define AIC3X_ASD_INTF_CTRLA 8 +/* Audio serial data interface control register B */ +#define AIC3X_ASD_INTF_CTRLB 9 +/* Audio serial data interface control register C */ +#define AIC3X_ASD_INTF_CTRLC 10 +/* Audio overflow status and PLL R value programming register */ +#define AIC3X_OVRF_STATUS_AND_PLLR_REG 11 +/* Audio codec digital filter control register */ +#define AIC3X_CODEC_DFILT_CTRL 12 +/* Headset/button press detection register */ +#define AIC3X_HEADSET_DETECT_CTRL_A 13 +#define AIC3X_HEADSET_DETECT_CTRL_B 14 +/* ADC PGA Gain control registers */ +#define LADC_VOL 15 +#define RADC_VOL 16 +/* MIC3 control registers */ +#define MIC3LR_2_LADC_CTRL 17 +#define MIC3LR_2_RADC_CTRL 18 +/* Line1 Input control registers */ +#define LINE1L_2_LADC_CTRL 19 +#define LINE1R_2_LADC_CTRL 21 +#define LINE1R_2_RADC_CTRL 22 +#define LINE1L_2_RADC_CTRL 24 +/* Line2 Input control registers */ +#define LINE2L_2_LADC_CTRL 20 +#define LINE2R_2_RADC_CTRL 23 +/* MICBIAS Control Register */ +#define MICBIAS_CTRL 25 + +/* AGC Control Registers A, B, C */ +#define LAGC_CTRL_A 26 +#define LAGC_CTRL_B 27 +#define LAGC_CTRL_C 28 +#define RAGC_CTRL_A 29 +#define RAGC_CTRL_B 30 +#define RAGC_CTRL_C 31 + +/* ADC flag registers */ +#define ADC_FLAG 36 + +/* DAC Power and Left High Power Output control registers */ +#define DAC_PWR 37 +#define HPLCOM_CFG 37 +/* Right High Power Output control registers */ +#define HPRCOM_CFG 38 +/* High Power Output Stage Control Register */ +#define HPOUT_SC 40 +/* DAC Output Switching control registers */ +#define DAC_LINE_MUX 41 +/* High Power Output Driver Pop Reduction registers */ +#define HPOUT_POP_REDUCTION 42 +/* DAC Digital control registers */ +#define LDAC_VOL 43 +#define RDAC_VOL 44 +/* Left High Power Output control registers */ +#define LINE2L_2_HPLOUT_VOL 45 +#define PGAL_2_HPLOUT_VOL 46 +#define DACL1_2_HPLOUT_VOL 47 +#define LINE2R_2_HPLOUT_VOL 48 +#define PGAR_2_HPLOUT_VOL 49 +#define DACR1_2_HPLOUT_VOL 50 +#define HPLOUT_CTRL 51 +/* Left High Power COM control registers */ +#define LINE2L_2_HPLCOM_VOL 52 +#define PGAL_2_HPLCOM_VOL 53 +#define DACL1_2_HPLCOM_VOL 54 +#define LINE2R_2_HPLCOM_VOL 55 +#define PGAR_2_HPLCOM_VOL 56 +#define DACR1_2_HPLCOM_VOL 57 +#define HPLCOM_CTRL 58 +/* Right High Power Output control registers */ +#define LINE2L_2_HPROUT_VOL 59 +#define PGAL_2_HPROUT_VOL 60 +#define DACL1_2_HPROUT_VOL 61 +#define LINE2R_2_HPROUT_VOL 62 +#define PGAR_2_HPROUT_VOL 63 +#define DACR1_2_HPROUT_VOL 64 +#define HPROUT_CTRL 65 +/* Right High Power COM control registers */ +#define LINE2L_2_HPRCOM_VOL 66 +#define PGAL_2_HPRCOM_VOL 67 +#define DACL1_2_HPRCOM_VOL 68 +#define LINE2R_2_HPRCOM_VOL 69 +#define PGAR_2_HPRCOM_VOL 70 +#define DACR1_2_HPRCOM_VOL 71 +#define HPRCOM_CTRL 72 +/* Mono Line Output Plus/Minus control registers */ +#define LINE2L_2_MONOLOPM_VOL 73 +#define PGAL_2_MONOLOPM_VOL 74 +#define DACL1_2_MONOLOPM_VOL 75 +#define LINE2R_2_MONOLOPM_VOL 76 +#define PGAR_2_MONOLOPM_VOL 77 +#define DACR1_2_MONOLOPM_VOL 78 +#define MONOLOPM_CTRL 79 +/* Class-D speaker driver on tlv320aic3007 */ +#define CLASSD_CTRL 73 +/* Left Line Output Plus/Minus control registers */ +#define LINE2L_2_LLOPM_VOL 80 +#define PGAL_2_LLOPM_VOL 81 +#define DACL1_2_LLOPM_VOL 82 +#define LINE2R_2_LLOPM_VOL 83 +#define PGAR_2_LLOPM_VOL 84 +#define DACR1_2_LLOPM_VOL 85 +#define LLOPM_CTRL 86 +/* Right Line Output Plus/Minus control registers */ +#define LINE2L_2_RLOPM_VOL 87 +#define PGAL_2_RLOPM_VOL 88 +#define DACL1_2_RLOPM_VOL 89 +#define LINE2R_2_RLOPM_VOL 90 +#define PGAR_2_RLOPM_VOL 91 +#define DACR1_2_RLOPM_VOL 92 +#define RLOPM_CTRL 93 +/* GPIO/IRQ registers */ +#define AIC3X_STICKY_IRQ_FLAGS_REG 96 +#define AIC3X_RT_IRQ_FLAGS_REG 97 +#define AIC3X_GPIO1_REG 98 +#define AIC3X_GPIO2_REG 99 +#define AIC3X_GPIOA_REG 100 +#define AIC3X_GPIOB_REG 101 +/* Clock generation control register */ +#define AIC3X_CLKGEN_CTRL_REG 102 +/* New AGC registers */ +#define LAGCN_ATTACK 103 +#define LAGCN_DECAY 104 +#define RAGCN_ATTACK 105 +#define RAGCN_DECAY 106 +/* New Programmable ADC Digital Path and I2C Bus Condition Register */ +#define NEW_ADC_DIGITALPATH 107 +/* Passive Analog Signal Bypass Selection During Powerdown Register */ +#define PASSIVE_BYPASS 108 +/* DAC Quiescent Current Adjustment Register */ +#define DAC_ICC_ADJ 109 + +/* Page select register bits */ +#define PAGE0_SELECT 0 +#define PAGE1_SELECT 1 + +/* Audio serial data interface control register A bits */ +#define BIT_CLK_MASTER 0x80 +#define WORD_CLK_MASTER 0x40 +#define DOUT_TRISTATE 0x20 + +/* Codec Datapath setup register 7 */ +#define FSREF_44100 (1 << 7) +#define FSREF_48000 (0 << 7) +#define DUAL_RATE_MODE ((1 << 5) | (1 << 6)) +#define LDAC2LCH (0x1 << 3) +#define RDAC2RCH (0x1 << 1) +#define LDAC2RCH (0x2 << 3) +#define RDAC2LCH (0x2 << 1) +#define LDAC2MONOMIX (0x3 << 3) +#define RDAC2MONOMIX (0x3 << 1) + +/* PLL registers bitfields */ +#define PLLP_SHIFT 0 +#define PLLP_MASK 7 +#define PLLQ_SHIFT 3 +#define PLLR_SHIFT 0 +#define PLLJ_SHIFT 2 +#define PLLD_MSB_SHIFT 0 +#define PLLD_LSB_SHIFT 2 + +/* Clock generation register bits */ +#define CODEC_CLKIN_PLLDIV 0 +#define CODEC_CLKIN_CLKDIV 1 +#define PLL_CLKIN_SHIFT 4 +#define MCLK_SOURCE 0x0 +#define PLL_CLKDIV_SHIFT 0 +#define PLLCLK_IN_MASK 0x30 +#define PLLCLK_IN_SHIFT 4 +#define CLKDIV_IN_MASK 0xc0 +#define CLKDIV_IN_SHIFT 6 +/* clock in source */ +#define CLKIN_MCLK 0 +#define CLKIN_GPIO2 1 +#define CLKIN_BCLK 2 + +/* Software reset register bits */ +#define SOFT_RESET 0x80 + +/* PLL progrramming register A bits */ +#define PLL_ENABLE 0x80 + +/* Route bits */ +#define ROUTE_ON 0x80 + +/* Mute bits */ +#define UNMUTE 0x08 +#define MUTE_ON 0x80 + +/* Power bits */ +#define LADC_PWR_ON 0x04 +#define RADC_PWR_ON 0x04 +#define LDAC_PWR_ON 0x80 +#define RDAC_PWR_ON 0x40 +#define HPLOUT_PWR_ON 0x01 +#define HPROUT_PWR_ON 0x01 +#define HPLCOM_PWR_ON 0x01 +#define HPRCOM_PWR_ON 0x01 +#define MONOLOPM_PWR_ON 0x01 +#define LLOPM_PWR_ON 0x01 +#define RLOPM_PWR_ON 0x01 + +#define INVERT_VOL(val) (0x7f - val) + +/* Default output volume (inverted) */ +#define DEFAULT_VOL INVERT_VOL(0x50) +/* Default input volume */ +#define DEFAULT_GAIN 0x20 + +/* MICBIAS Control Register */ +#define MICBIAS_LEVEL_SHIFT (6) +#define MICBIAS_LEVEL_MASK (3 << 6) + +struct tlv32aic32_config_t +{ + enum AUD_BITS_T bits; + enum AUD_SAMPRATE_T sample_rate; + enum AUD_CHANNEL_NUM_T channel_num; + enum AUD_CHANNEL_MAP_T channel_map; + + bool use_dma; + bool chan_sep_buf; + bool sync_start; + uint8_t slot_cycles; +}; + +uint32_t tlv32aic32_open(void); +uint32_t tlv32aic32_stream_open(enum AUD_STREAM_T stream); +uint32_t tlv32aic32_stream_setup(enum AUD_STREAM_T stream, struct tlv32aic32_config_t *cfg); +uint32_t tlv32aic32_stream_start(enum AUD_STREAM_T stream); +uint32_t tlv32aic32_stream_stop(enum AUD_STREAM_T stream); +uint32_t tlv32aic32_stream_close(enum AUD_STREAM_T stream); +uint32_t tlv32aic32_close(void); + +#ifdef __cplusplus +} +#endif + +#endif /* CODEC_TLV32AIC32_H */ diff --git a/platform/drivers/norflash/Makefile b/platform/drivers/norflash/Makefile new file mode 100644 index 0000000..8184737 --- /dev/null +++ b/platform/drivers/norflash/Makefile @@ -0,0 +1,44 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y := -I$(obj)/inc -Itests/programmer/inc -Iutils/boot_struct + +CFLAGS_norflash_drv.o += -DCHIP_FLASH_CTRL_VER=$(CHIP_FLASH_CTRL_VER) + +ifeq ($(FLASH_HPM),1) +ccflags-y += -DFLASH_HPM +endif + +ifeq ($(FLASH_CALIB_DEBUG),1) +CFLAGS_norflash_drv.o += -DFLASH_CALIB_DEBUG +endif +ifeq ($(FLASH_SUSPEND),1) +CFLAGS_norflash_drv.o += -DFLASH_SUSPEND +endif +ifeq ($(FLASH_SECURITY_REGISTER),1) +CFLAGS_norflash_drv.o += -DFLASH_SECURITY_REGISTER +endif + +ifeq ($(PSRAM_ENABLE),1) +CFLAGS_norflash_drv.o += -DPSRAM_ENABLE +endif +ifeq ($(PSRAMUHS_ENABLE),1) +CFLAGS_norflash_drv.o += -DPSRAMUHS_ENABLE +endif + +ifeq ($(FLASH_CHIP),) +ifeq ($(PROGRAMMER),1) +FLASH_CHIP := ALL +else +FLASH_CHIP := GD25Q32C +endif +endif +ifeq ($(FLASH_CHIP),) +$(error *** Error: FLASH_CHIP is NOT defined!) +endif + +CFLAGS_norflash_drv.o += $(foreach flash,$(FLASH_CHIP),-D__NORFLASH_$(flash)__) + diff --git a/platform/drivers/norflash/norflash_drv.c b/platform/drivers/norflash/norflash_drv.c new file mode 100644 index 0000000..de30d0e --- /dev/null +++ b/platform/drivers/norflash/norflash_drv.c @@ -0,0 +1,1620 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "cmsis.h" +#include "norflash_drv.h" +#include "cmsis.h" +#include "hal_cache.h" +#include "hal_norflaship.h" +#include "hal_norflash.h" +#include "hal_sleep.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "norflash_gd25q32c.h" +#include "plat_addr_map.h" +#include "tool_msg.h" + +#ifdef PROGRAMMER +#include "task_schedule.h" +#else +#define TASK_SCHEDULE true +#endif + +#if (CHIP_FLASH_CTRL_VER >= 2) && !defined(ROM_BUILD) && !defined(PROGRAMMER) && !(defined(CHIP_BEST2001) && (defined(PSRAMUHS_ENABLE) || defined(PSRAM_ENABLE))) +#define FLASH_BURST_WRAP +#endif + +#define SAMP_DELAY_PRIO_FALLING_EDGE + +#define NORFLASH_UNIQUE_ID_LEN 18 + +#define NORFLASH_MAX_DIV 0xFF + +#define NORFLASH_DEFAULT_MAX_SPEED (104 * 1000 * 1000) + +#define NORFLASH_DIV1_MAX_SPEED (99 * 1000 * 1000) + +#define NORFLASH_SPEED_RATIO_DENOMINATOR 8 + +#define NORFLASH_PUYA_ID_PREFIX 0x85 + +#define NORFLASH_XTS_ID_PREFIX 0x0B + +#define XTS_UNIQUE_ID_LEN 16 +#define XTS_UNIQUE_ID_CMD 0x5A +#define XTS_UNIQUE_ID_PARAM 0x00019400 + +// GigaDevice +extern const struct NORFLASH_CFG_T gd25lq64c_cfg; +extern const struct NORFLASH_CFG_T gd25lq32c_cfg; +extern const struct NORFLASH_CFG_T gd25lq16c_cfg; +extern const struct NORFLASH_CFG_T gd25lq80c_cfg; +extern const struct NORFLASH_CFG_T gd25q32c_cfg; +extern const struct NORFLASH_CFG_T gd25q80c_cfg; +extern const struct NORFLASH_CFG_T gd25d40c_cfg; +extern const struct NORFLASH_CFG_T gd25d20c_cfg; + +// Puya +extern const struct NORFLASH_CFG_T p25q128l_cfg; +extern const struct NORFLASH_CFG_T p25q64l_cfg; +extern const struct NORFLASH_CFG_T p25q32l_cfg; +extern const struct NORFLASH_CFG_T p25q16l_cfg; +extern const struct NORFLASH_CFG_T p25q80h_cfg; +extern const struct NORFLASH_CFG_T p25q21h_cfg; +extern const struct NORFLASH_CFG_T p25q40h_cfg; + +// XTS +extern const struct NORFLASH_CFG_T xt25q08b_cfg; + +// EON +extern const struct NORFLASH_CFG_T en25s80b_cfg; + +// XMC +extern const struct NORFLASH_CFG_T xm25qh16c_cfg; +extern const struct NORFLASH_CFG_T xm25qh80b_cfg; + +static const struct NORFLASH_CFG_T * const flash_list[] = { + // ---------------------- + // GigaDevice + // ---------------------- +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_GD25LQ64C__) + &gd25lq64c_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_GD25LQ32C__) + &gd25lq32c_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_GD25LQ6C__) + &gd25lq16c_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_GD25LQ80C__) + &gd25lq80c_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_GD25Q32C__) + &gd25q32c_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_GD25Q80C__) + &gd25q80c_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_GD25D40C__) + &gd25d40c_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_GD25D20C__) + &gd25d20c_cfg, +#endif + + // ---------------------- + // Puya + // ---------------------- +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_P25Q128L__) + &p25q128l_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_P25Q64L__) + &p25q64l_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_P25Q32L__) + &p25q32l_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_P25Q16L__) + &p25q16l_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_P25Q80H__) + &p25q80h_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_P25Q21H__) + &p25q21h_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_P25Q40H__) + &p25q40h_cfg, +#endif + + // ---------------------- + // Xinxin + // ---------------------- +#if defined(__NORFLASH_XM25QH16C__) + &xm25qh16c_cfg, +#endif +#if defined(__NORFLASH_ALL__) || defined(__NORFLASH_XM25QH80B__) + &xm25qh80b_cfg, +#endif + + // ---------------------- + // XTS + // ---------------------- +#if defined(__NORFLASH_XT25Q08B__) + &xt25q08b_cfg, +#endif + + // ---------------------- + // EON + // ---------------------- +#if defined(__NORFLASH_EN25S80B__) + &en25s80b_cfg, +#endif + +}; + +// Sample delay will be larger if: +// 1) flash speed is higher (major impact) +// 2) vcore voltage is lower (secondary major impact) +// 3) flash voltage is lower (minor impact) + +// Sample delay unit: +// V1: 1/2 source_clk cycle when <= 2, 1 source_clk cycle when >= 2 +// V2: 1/2 source_clk cycle when <= 4, 1 source_clk cycle when >= 4 + +// Flash clock low to output valid delay: +// T_clqv: 7 ns + +// Flash IO latency: +// BEST1000/3001/1400: 4 ns +// BEST2000: 5 ns +// BEST2300: 2 ns + +// Flash output time: T_clqv + T_io_latency +// Falling edge sample time: one spi_clk cycle (should > flash output time) + +#ifdef CHIP_BEST2300 +#define FALLING_EDGE_SAMPLE_ADJ_FREQ (110 * 1000 * 1000) // about 9 ns +#else +#define FALLING_EDGE_SAMPLE_ADJ_FREQ (77 * 1000 * 1000) // about 13 ns +#endif + +#if (CHIP_FLASH_CTRL_VER <= 1) +#define SAM_EDGE_FALLING (1 << 4) +#define SAM_NEG_PHASE (1 << 5) +#define SAMDLY_MASK (0xF << 0) + +#ifdef SAMP_DELAY_PRIO_FALLING_EDGE +#define DIV2_SAMP_DELAY_FALLING_EDGE_IDX 1 +#define DIVN_SAMP_DELAY_FALLING_EDGE_IDX 2 +// Sample delays: 1, 1.5, 2, 3 +static const uint8_t samdly_list_divn[] = { 1, SAM_NEG_PHASE | SAM_EDGE_FALLING | 2, 2, 3, }; +#else +// Sample delays: 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 7 +static const uint8_t samdly_list_divn[] = { /*0,*/ SAM_EDGE_FALLING | 1, 1, SAM_NEG_PHASE | SAM_EDGE_FALLING | 2, 2, 3, 4, /*5, 6, 7,*/ }; +#endif +#else +#ifdef SAMP_DELAY_PRIO_FALLING_EDGE +#ifdef CHIP_BEST1402 +#define DIV1_SAMP_DELAY_FALLING_EDGE_IDX 2 +#else +#define DIV1_SAMP_DELAY_FALLING_EDGE_IDX 1 +#endif +static const uint8_t samdly_list_div1[] = { 0, 1, 2, 3, }; +#define DIV2_SAMP_DELAY_FALLING_EDGE_IDX 1 +#define DIVN_SAMP_DELAY_FALLING_EDGE_IDX 3 +static const uint8_t samdly_list_divn[] = { 2, 3, 4, 5, 6, 7, 8, 9, }; +#else +static const uint8_t samdly_list_divn[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, }; +#endif +#endif + +static uint8_t flash_idx; +static uint8_t div_read; +static uint8_t div_std_read; +static uint8_t div_others; +static uint32_t norflash_op_mode = 0; +static bool falling_edge_adj; +static uint8_t sample_delay_index; + +#ifdef FLASH_SUSPEND +static uint32_t check_irq[(USER_IRQn_QTY + 31) / 32]; +static bool specific_irq_check; +#endif + +#ifdef FLASH_CALIB_DEBUG +static uint32_t norflash_source_clk; +static uint32_t norflash_speed; +static uint8_t calib_matched_idx[DRV_NORFLASH_CALIB_QTY]; +static uint8_t calib_matched_cnt[DRV_NORFLASH_CALIB_QTY]; +static uint8_t calib_final_idx[DRV_NORFLASH_CALIB_QTY]; +#endif + +static void norflash_delay(uint32_t us) +{ +#ifdef CHIP_BEST1000 + hal_sys_timer_delay(US_TO_TICKS(us)); +#else + hal_sys_timer_delay_us(us); +#endif +} + +#ifdef FLASH_HPM +static int norflash_set_hpm(uint8_t on) +{ + if (on) { + norflaship_cmd_addr(GD25Q32C_CMD_HIGH_PERFORMANCE, 0); + } else { + norflaship_cmd_addr(GD25Q32C_CMD_RELEASE_FROM_DP, 0); + } + norflaship_busy_wait(); + + return 0; +} +#endif + +#ifdef FLASH_SUSPEND +static int norflash_suspend(void) +{ + norflaship_clear_fifos(); + norflaship_ext_tx_cmd(GD25Q32C_CMD_PROGRAM_ERASE_SUSPEND, 0); + // Suspend time: 20~30 us + norflash_delay(40); + return 0; +} + +static int norflash_resume(void) +{ + norflaship_clear_fifos(); + norflaship_ext_tx_cmd(GD25Q32C_CMD_PROGRAM_ERASE_RESUME, 0); + if (flash_list[flash_idx]->id[0] == NORFLASH_PUYA_ID_PREFIX) { + // PUYA flash requires the mean interval of resume to suspend >= 250us + norflash_delay(250); + } else { + // At least resume the work for 100 us to avoid always staying in suspended state + norflash_delay(100); + } + return 0; +} +#endif + +uint8_t norflash_read_status_s0_s7(void) +{ + uint8_t val; + norflash_read_reg(GD25Q32C_CMD_READ_STATUS_S0_S7, &val, 1); + return val; +} + +uint8_t norflash_read_status_s8_s15(void) +{ + uint8_t val; + norflash_read_reg(GD25Q32C_CMD_READ_STATUS_S8_S15, &val, 1); + return val; +} + +static int norflash_status_WEL(void) +{ + uint32_t status; + status = norflash_read_status_s0_s7(); + return !!(status & GD25Q32C_WEL_BIT_MASK); +} + +static int norflash_status_WIP(void) +{ + uint32_t status; + status = norflash_read_status_s0_s7(); + return !!(status & GD25Q32C_WIP_BIT_MASK); +} + +void norflash_status_WEL_0_wait(void) +{ + while (norflash_status_WEL() == 0 && TASK_SCHEDULE); +} + +#ifdef FLASH_SUSPEND +int norflash_suspend_check_irq(uint32_t irq_num) +{ + uint32_t idx; + uint32_t offset; + + idx = irq_num / 32; + offset = irq_num % 32; + + if (idx >= ARRAY_SIZE(check_irq)) { + return 1; + } + + check_irq[idx] |= (1 << offset); + specific_irq_check = true; + + return 0; +} + +static int norflash_system_active(void) +{ + if (specific_irq_check) { + return hal_sleep_specific_irq_pending(check_irq, ARRAY_SIZE(check_irq)); + } else { + return hal_sleep_irq_pending(); + } +} +#endif + +enum HAL_NORFLASH_RET_T norflash_status_WIP_1_wait(int suspend) +{ + while (norflash_status_WIP() && TASK_SCHEDULE) { +#ifdef FLASH_SUSPEND + if (suspend && norflash_system_active()) { + norflash_suspend(); + return HAL_NORFLASH_SUSPENDED; + } +#endif + } + + return HAL_NORFLASH_OK; +} + +#ifdef FLASH_BURST_WRAP +static int norflash_set_burst_wrap(uint32_t len) +{ + uint8_t val; + + if (len == 64) { + val = (1 << 6) | (1 << 5); + } else if (len == 32) { + val = (1 << 6); + } else if (len == 16) { + val = (1 << 5); + } else if (len == 8) { + val = 0; + } else if (len == 0) { + // Disable wrap around + val = (1 << 4); + } else { + return 1; + } + + norflaship_clear_txfifo(); + norflaship_write_txfifo(&val, 1); + norflaship_cmd_addr(GD25Q32C_CMD_SET_BURST_WRAP, 0); + norflash_status_WIP_1_wait(0); + + return 0; +} +#endif + +static int norflash_set_continuous_read(uint8_t on) +{ + uint8_t cmd; + + if (on) { + norflaship_continuous_read_on(); + + norflaship_continuous_read_mode_bit(flash_list[flash_idx]->crm_en_bits); + + // Continuous Read Mode takes effect after the first read + } else { + norflaship_continuous_read_off(); + + norflaship_continuous_read_mode_bit(flash_list[flash_idx]->crm_dis_bits); + + if (norflash_op_mode & HAL_NORFLASH_OP_MODE_QUAD_IO) { + cmd = GD25Q32C_CMD_FAST_QUAD_IO_READ; + } else { + norflaship_quad_mode(0); + + if (norflash_op_mode & HAL_NORFLASH_OP_MODE_DUAL_IO) { + cmd = GD25Q32C_CMD_FAST_DUAL_IO_READ; + } else { + norflaship_dual_mode(0); + + // Command 0x03 and address 0xFFFFFE will make M4=1 (mode bit 4) + // at both qual and dual continuous read modes, which will disable it. + cmd = GD25Q32C_CMD_STANDARD_READ; + } + } + + norflaship_clear_rxfifo(); + norflaship_busy_wait(); + norflaship_blksize(2); + if (cmd == GD25Q32C_CMD_STANDARD_READ) { + if (div_std_read) { + norflaship_div(div_std_read); + } + } + norflaship_cmd_addr(cmd, 0xFFFFFE); + // Now Continuous Read Mode has been disabled + if (cmd == GD25Q32C_CMD_STANDARD_READ) { + if (div_others) { + norflaship_div(div_others); + } + } + norflaship_clear_rxfifo(); + } + + norflaship_busy_wait(); + + return 0; +} + +static int norflash_set_quad(uint8_t on) +{ + if (flash_list[flash_idx]->write_status == NULL) { + return -1; + } + + if (on) { + flash_list[flash_idx]->write_status(DRV_NORFLASH_W_STATUS_QE, 1); + } else { + flash_list[flash_idx]->write_status(DRV_NORFLASH_W_STATUS_QE, 0); + } + return 0; +} + +static int norflash_set_quad_io_mode(uint8_t on) +{ + norflash_set_quad(on); + if (on) { + norflaship_quad_mode(1); + } else { + norflaship_quad_mode(0); + } + norflaship_busy_wait(); + return 0; +} + +static int norflash_set_quad_output_mode(uint8_t on) +{ + norflash_set_quad(on); + if (on) { + norflaship_rdcmd(GD25Q32C_CMD_FAST_QUAD_OUTPUT_READ); + } else { + norflaship_rdcmd(GD25Q32C_CMD_STANDARD_READ); + } + norflaship_busy_wait(); + return 0; +} + +static uint8_t norflash_set_dual_io_mode(uint8_t on) +{ + if (on) { + norflaship_dual_mode(1); + } else { + norflaship_dual_mode(0); + } + norflaship_busy_wait(); + + return 0; +} + +static uint8_t norflash_set_dual_output_mode(uint8_t on) +{ + if (on) { + norflaship_rdcmd(GD25Q32C_CMD_FAST_DUAL_OUTPUT_READ); + } else { + norflaship_rdcmd(GD25Q32C_CMD_STANDARD_READ); + } + norflaship_busy_wait(); + return 0; +} + +static uint8_t norflash_set_fast_mode(uint8_t on) +{ + if (on) { + norflaship_rdcmd(GD25Q32C_CMD_STANDARD_FAST_READ); + } else { + norflaship_rdcmd(GD25Q32C_CMD_STANDARD_READ); + } + norflaship_busy_wait(); + return 0; +} + +static uint8_t norflash_set_stand_mode(void) +{ + norflaship_rdcmd(GD25Q32C_CMD_STANDARD_READ); + norflaship_busy_wait(); + return 0; +} + +uint32_t norflash_get_supported_mode(void) +{ + return flash_list[flash_idx]->mode; +} + +uint32_t norflash_get_current_mode(void) +{ + return norflash_op_mode; +} + +union DRV_NORFLASH_SEC_REG_CFG_T norflash_get_security_register_config(void) +{ + return flash_list[flash_idx]->sec_reg_cfg; +} + +uint32_t norflash_get_block_protect_mask(void) +{ + return flash_list[flash_idx]->block_protect_mask; +} + +void norflash_reset(void) +{ + norflaship_clear_fifos(); + + // Disable continuous read mode + norflaship_continuous_read_off(); + norflaship_busy_wait(); + norflaship_blksize(2); + // Command 0x03 and address 0xFFFFFE will make M4=1 (mode bit 4) + // at both qual and dual continuous read modes, which will disable it. + norflaship_cmd_addr(GD25Q32C_CMD_STANDARD_READ, 0xFFFFFE); + + // Release from deep power-down + norflaship_cmd_addr(GD25Q32C_CMD_RELEASE_FROM_DP, 0); + // Wait 20us for flash to finish + norflash_delay(40); + + // Software reset + norflaship_ext_tx_cmd(GD25Q32C_CMD_ENABLE_RESET, 0); + norflaship_ext_tx_cmd(GD25Q32C_CMD_RESET, 0); + // Reset recovery time: 20~30 us + norflash_delay(50); + + norflaship_cmd_done(); + + // Reset cfg + flash_idx = 0; + div_read = 0; + div_std_read = 0; + div_others = 0; + norflash_op_mode = 0; + falling_edge_adj = false; +} + +int norflash_get_size(uint32_t *total_size, uint32_t *block_size, uint32_t *sector_size, uint32_t *page_size) +{ + if (total_size) { + *total_size = flash_list[flash_idx]->total_size; + } + if (block_size) { + *block_size = flash_list[flash_idx]->block_size; + } + if (sector_size) { + *sector_size = flash_list[flash_idx]->sector_size; + } + if (page_size) { + *page_size = flash_list[flash_idx]->page_size; + } + + return 0; +} + +static void norflash_set_cfg_div(void) +{ + if (div_others) { + norflaship_div(div_others); + } +} + +static void norflash_set_read_div(void) +{ + if (norflash_op_mode & HAL_NORFLASH_OP_MODE_STAND_SPI) { + if (div_std_read) { + norflaship_div(div_std_read); + } + } else { + if (div_read) { + norflaship_div(div_read); + } + } +} + +int norflash_set_mode(uint32_t op) +{ + uint32_t read_mode = 0; + uint32_t ext_mode = 0; + uint32_t program_mode = 0; + uint32_t self_mode; + uint32_t mode; + + self_mode = norflash_get_supported_mode(); + mode = (self_mode & op); + + if (mode & HAL_NORFLASH_OP_MODE_QUAD_IO) { + read_mode = HAL_NORFLASH_OP_MODE_QUAD_IO; + } else if (mode & HAL_NORFLASH_OP_MODE_QUAD_OUTPUT) { + read_mode = HAL_NORFLASH_OP_MODE_QUAD_OUTPUT; + } else if (mode & HAL_NORFLASH_OP_MODE_DUAL_IO) { + read_mode = HAL_NORFLASH_OP_MODE_DUAL_IO; + } else if (mode & HAL_NORFLASH_OP_MODE_DUAL_OUTPUT) { + read_mode = HAL_NORFLASH_OP_MODE_DUAL_OUTPUT; + } else if (mode & HAL_NORFLASH_OP_MODE_FAST_SPI) { + read_mode = HAL_NORFLASH_OP_MODE_FAST_SPI; + } else if(mode & HAL_NORFLASH_OP_MODE_STAND_SPI) { + read_mode = HAL_NORFLASH_OP_MODE_STAND_SPI; + } else { + // Op error + return 1; + } + + if (mode & HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM) { + program_mode = HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM; + } else if (mode & HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM) { + program_mode = HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM; + } else if (mode & HAL_NORFLASH_OP_MODE_PAGE_PROGRAM) { + program_mode = HAL_NORFLASH_OP_MODE_PAGE_PROGRAM; + } else { + // Op error + return 1; + } + +#ifdef FLASH_BURST_WRAP + if (mode & HAL_NORFLASH_OP_MODE_READ_WRAP) { + ext_mode |= HAL_NORFLASH_OP_MODE_READ_WRAP; + } +#endif + +#ifdef FLASH_HPM + if (mode & HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE) { + ext_mode |= HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE; + } +#endif + + if (mode & (HAL_NORFLASH_OP_MODE_QUAD_IO | HAL_NORFLASH_OP_MODE_DUAL_IO)) { + if (mode & HAL_NORFLASH_OP_MODE_CONTINUOUS_READ) { + ext_mode |= HAL_NORFLASH_OP_MODE_CONTINUOUS_READ; + } + } + + mode = (read_mode | ext_mode | program_mode); + + if (norflash_op_mode != mode) { + norflash_op_mode = mode; + + // Continuous read off if flash supported + if ((self_mode & (HAL_NORFLASH_OP_MODE_QUAD_IO | HAL_NORFLASH_OP_MODE_DUAL_IO)) && + (self_mode & HAL_NORFLASH_OP_MODE_CONTINUOUS_READ)) { + norflash_set_continuous_read(0); + } + + norflaship_quad_mode(0); + + norflaship_dual_mode(0); + +#ifdef FLASH_HPM + if (mode & HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE) { + // High performance mode on + norflash_set_hpm(1); + } +#endif + + if (mode & HAL_NORFLASH_OP_MODE_QUAD_IO) { + // Quad io mode + norflash_set_quad_io_mode(1); + } else if (mode & HAL_NORFLASH_OP_MODE_QUAD_OUTPUT) { + // Quad output mode + norflash_set_quad_output_mode(1); + } else if (mode & HAL_NORFLASH_OP_MODE_DUAL_IO) { + // Dual io mode + norflash_set_dual_io_mode(1); + } else if (mode & HAL_NORFLASH_OP_MODE_DUAL_OUTPUT) { + // Dual output mode + norflash_set_dual_output_mode(1); + } else if (mode & HAL_NORFLASH_OP_MODE_FAST_SPI) { + // Fast mode + norflash_set_fast_mode(1); + } else if (mode & HAL_NORFLASH_OP_MODE_STAND_SPI) { + // Standard spi mode + norflash_set_stand_mode(); + } + +#ifdef FLASH_BURST_WRAP + if (mode & HAL_NORFLASH_OP_MODE_READ_WRAP) { + norflash_set_burst_wrap(32); + hal_cache_wrap_enable(HAL_CACHE_ID_I_CACHE); + hal_cache_wrap_enable(HAL_CACHE_ID_D_CACHE); + } +#endif + +#ifdef FLASH_HPM + if ((self_mode & HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE) && + (mode & HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE) == 0) { + // High performance mode off + norflash_set_hpm(0); + } +#endif + + if (mode & HAL_NORFLASH_OP_MODE_CONTINUOUS_READ) { + // Continuous read on + norflash_set_continuous_read(1); + } + + norflaship_cmd_done(); + } + + norflash_set_read_div(); + + return 0; +} + +int norflash_pre_operation(void) +{ + norflash_set_cfg_div(); + + if (norflash_op_mode & HAL_NORFLASH_OP_MODE_CONTINUOUS_READ) { + norflash_set_continuous_read(0); + } + + return 0; +} + +int norflash_post_operation(void) +{ + if (norflash_op_mode & HAL_NORFLASH_OP_MODE_CONTINUOUS_READ) { + norflash_set_continuous_read(1); + } + + norflaship_cmd_done(); + + norflash_set_read_div(); + + return 0; +} + +int norflash_read_reg(uint8_t cmd, uint8_t *val, uint32_t len) +{ + int i; + + norflaship_clear_fifos(); +#ifdef TRY_EMBEDDED_CMD + if ((cmd == GD25Q32C_CMD_READ_STATUS_S0_S7 || cmd == GD25Q32C_CMD_READ_STATUS_S8_S15) && len == 1) { + norflaship_cmd_addr(cmd, 0); + } else { + if (cmd == GD25Q32C_CMD_ID) { + norflaship_blksize(len); + norflaship_cmd_addr(cmd, 0); + } else { + norflaship_ext_rx_cmd(cmd, 0, len); + } + } +#else + norflaship_ext_rx_cmd(cmd, 0, len); +#endif + norflaship_rxfifo_count_wait(len); + for (i = 0; i < len; i++) { + val[i] = norflaship_read_rxfifo(); + } + + return 0; +} + +int norflash_read_reg_ex(uint8_t cmd, uint8_t *param, uint32_t param_len, uint8_t *val, uint32_t len) +{ + int i; + + norflaship_clear_fifos(); + if (param && param_len > 0) { + norflaship_write_txfifo(param, param_len); + } else { + param_len = 0; + } + norflaship_ext_rx_cmd(cmd, param_len, len); + for (i = 0; i < len; i++) { + norflaship_rxfifo_empty_wait(); + val[i] = norflaship_read_rxfifo(); + } + + return 0; +} + +int norflash_write_reg(uint8_t cmd, const uint8_t *val, uint32_t len) +{ + norflaship_cmd_addr(GD25Q32C_CMD_WRITE_ENABLE, 0); + norflash_status_WIP_1_wait(0); + norflash_status_WEL_0_wait(); + + norflaship_clear_txfifo(); + norflaship_write_txfifo(val, len); + +#ifdef TRY_EMBEDDED_CMD + if (cmd == GD25Q32C_CMD_WRITE_STATUS_S0_S7) { + norflaship_cmd_addr(GD25Q32C_CMD_WRITE_STATUS_S0_S7, 0); + } else { + norflaship_ext_tx_cmd(cmd, len); + } +#else + norflaship_ext_tx_cmd(cmd, len); +#endif + + norflash_status_WIP_1_wait(0); + + return 0; +} + +int norflash_get_id(uint8_t *value, uint32_t len) +{ + norflash_pre_operation(); + + if (len > NORFLASH_ID_LEN) { + len = NORFLASH_ID_LEN; + } + norflash_read_reg(GD25Q32C_CMD_ID, value, len); + + norflash_post_operation(); + + return 0; +} + +int norflash_get_unique_id(uint8_t *value, uint32_t len) +{ + uint32_t param; + uint8_t cmd; + + norflash_pre_operation(); + + if (flash_list[flash_idx]->id[0] == NORFLASH_XTS_ID_PREFIX) { + if (len > XTS_UNIQUE_ID_LEN) { + len = XTS_UNIQUE_ID_LEN; + } + param = XTS_UNIQUE_ID_PARAM; + cmd = XTS_UNIQUE_ID_CMD; + } else { + if (len > NORFLASH_UNIQUE_ID_LEN) { + len = NORFLASH_UNIQUE_ID_LEN; + } + param = 0; + cmd = GD25Q32C_CMD_UNIQUE_ID; + } + norflash_read_reg_ex(cmd, (uint8_t *)¶m, sizeof(param), value, len); + + norflash_post_operation(); + + return 0; +} + +static void norflash_get_samdly_list(uint32_t div, const uint8_t **samdly_list_p, uint32_t *size_p) +{ + const uint8_t *samdly_list = NULL; + uint32_t size = 0; + +#if (CHIP_FLASH_CTRL_VER <= 1) + if (div >= 2) { + samdly_list = samdly_list_divn; + size = ARRAY_SIZE(samdly_list_divn); + } +#else + if (div >= 1) { + if (div == 1) { + samdly_list = samdly_list_div1; + size = ARRAY_SIZE(samdly_list_div1); + } else { + samdly_list = samdly_list_divn; + size = ARRAY_SIZE(samdly_list_divn); + } + } +#endif + + if (samdly_list_p) { + *samdly_list_p = samdly_list; + } + if (size_p) { + *size_p = size; + } +} + +void norflash_set_sample_delay_index(uint32_t index) +{ + const uint8_t *samdly_list; + uint32_t size; + uint32_t div; + + sample_delay_index = index; + + div = norflaship_get_div(); + + norflash_get_samdly_list(div, &samdly_list, &size); + + if (index < size) { +#if (CHIP_FLASH_CTRL_VER <= 1) + norflaship_pos_neg(samdly_list[index] & SAM_EDGE_FALLING); + norflaship_neg_phase(samdly_list[index] & SAM_NEG_PHASE); + norflaship_samdly(samdly_list[index] & SAMDLY_MASK); +#else + norflaship_samdly(samdly_list[index]); +#endif + } +} + +uint32_t norflash_get_sample_delay_index(void) +{ + return sample_delay_index; +} + +static bool norflash_calib_flash_id_valid(void) +{ + uint8_t id[HAL_NORFLASH_DEVICE_ID_LEN]; + const uint8_t *cmp_id; + + norflash_get_id(id, sizeof(id)); + cmp_id = flash_list[flash_idx]->id; + + if (id[0] == cmp_id[0] && id[1] == cmp_id[1] && id[2] == cmp_id[2]) { + return true; + } + return false; +} + +static bool norflash_calib_magic_word_valid(void) +{ + uint32_t magic; + +#if (CHIP_FLASH_CTRL_VER <= 1) + norflash_read(FLASH_NC_BASE, NULL, 1); +#endif + norflaship_clear_rxfifo(); +#if (FLASH_NC_BASE == FLASH_BASE) + hal_cache_invalidate(HAL_CACHE_ID_D_CACHE, FLASH_BASE, sizeof(magic)); + magic = *(volatile uint32_t *)FLASH_BASE; +#else + magic = *(volatile uint32_t *)FLASH_NC_BASE; +#endif + + if (magic == BOOT_MAGIC_NUMBER) { + return true; + } + return false; +} + +int norflash_sample_delay_calib(enum DRV_NORFLASH_CALIB_T type) +{ + int i; + uint32_t matched_cnt = 0; + uint32_t matched_idx = 0; + uint32_t div; + uint32_t size; + bool valid; + + if (type >= DRV_NORFLASH_CALIB_QTY) { + return 1; + } +#if defined(ROM_BUILD) || defined(PROGRAMMER) + if (type != DRV_NORFLASH_CALIB_FLASH_ID) { + return 0; + } +#endif + + div = norflaship_get_div(); + + if (div == 0) { + return -1; +#if (CHIP_FLASH_CTRL_VER <= 1) + } else if (div == 1) { + return -2; +#endif + } + + norflash_get_samdly_list(div, NULL, &size); + + for (i = 0; i < size; i++) { + norflaship_busy_wait(); + + norflash_set_sample_delay_index(i); + + if (type == DRV_NORFLASH_CALIB_FLASH_ID) { + valid = norflash_calib_flash_id_valid(); + } else { + valid = norflash_calib_magic_word_valid(); + } + + if (valid) { + if (matched_cnt == 0) { + matched_idx = i; + } + matched_cnt++; + } else if (matched_cnt) { + break; + } + } + +#ifdef FLASH_CALIB_DEBUG + calib_matched_idx[type] = matched_idx; + calib_matched_cnt[type] = matched_cnt; +#endif + + if (matched_cnt) { +#ifdef SAMP_DELAY_PRIO_FALLING_EDGE + if (matched_cnt == 2) { + uint32_t falling_edge_idx; + + if (0) { +#if (CHIP_FLASH_CTRL_VER >= 2) + } else if (div == 1) { + falling_edge_idx = DIV1_SAMP_DELAY_FALLING_EDGE_IDX; +#endif + } else if (div == 2) { + falling_edge_idx = DIV2_SAMP_DELAY_FALLING_EDGE_IDX; + if (falling_edge_adj) { + falling_edge_idx++; + } + } else { + falling_edge_idx = DIVN_SAMP_DELAY_FALLING_EDGE_IDX; + } + if (matched_idx <= falling_edge_idx && + falling_edge_idx < matched_idx + matched_cnt) { + matched_idx = falling_edge_idx; + matched_cnt = 1; + } + } +#endif + matched_idx += matched_cnt / 2; + norflash_set_sample_delay_index(matched_idx); + +#ifdef FLASH_CALIB_DEBUG + calib_final_idx[type] = matched_idx; +#endif + + return 0; + } + +#ifdef FLASH_CALIB_DEBUG + calib_final_idx[type] = -1; +#endif + + return 1; +} + +void norflash_show_calib_result(void) +{ +#ifdef FLASH_CALIB_DEBUG + union DRV_NORFLASH_SPEED_RATIO_T ratio; + uint32_t div; + uint32_t size; + const uint8_t *list; + int i; + + TRACE(0, "FLASH_CALIB_RESULT:"); + TRACE(0, "\nsource_clk=%u speed=%u flash_max=%u", norflash_source_clk, norflash_speed, flash_list[flash_idx]->max_speed); + ratio = flash_list[flash_idx]->speed_ratio; + TRACE(0, "\nstd_read=%u/8 others=%u/8", (ratio.s.std_read + 1), (ratio.s.others + 1)); + + div = norflaship_get_div(); + TRACE(0, "
\ndiv=%u", div); + norflash_get_samdly_list(div, &list, &size); + TRACE(0, ""); + if (list == NULL || size == 0) { + TRACE(0, "NONE"); + } else { + DUMP8("%02X ", list, size); + } + TRACE(0, ""); + for (i = 0; i < DRV_NORFLASH_CALIB_QTY; i++) { + TRACE(0, "type=%d idx=%02u cnt=%02u final=%02u", + i, calib_matched_idx[i], calib_matched_cnt[i], calib_final_idx[i]); + } + TRACE(0, "\t"); +#endif +} + +int norflash_init_sample_delay_by_div(uint32_t div) +{ + if (div == 0) { + return -1; + } if (div == 1) { +#if (CHIP_FLASH_CTRL_VER <= 1) + return -2; +#else + norflaship_samdly(1); +#endif + } else if (div == 2 && !falling_edge_adj) { + // Set sample delay to clock falling edge +#if (CHIP_FLASH_CTRL_VER <= 1) + norflaship_pos_neg(1); + norflaship_neg_phase(1); + norflaship_samdly(2); +#else + norflaship_samdly(3); +#endif + } else { + // Set sample delay to nearest to but not later than clock falling edge +#if (CHIP_FLASH_CTRL_VER <= 1) + norflaship_pos_neg(0); + norflaship_neg_phase(0); + norflaship_samdly(2); +#else + norflaship_samdly(4); +#endif + } + + return 0; +} + +int norflash_init_div(const struct HAL_NORFLASH_CONFIG_T *cfg) +{ + uint32_t max_speed; + uint32_t std_read_speed; + uint32_t others_speed; + union DRV_NORFLASH_SPEED_RATIO_T ratio; + uint32_t div; + +#ifdef FLASH_CALIB_DEBUG + norflash_source_clk = cfg->source_clk; + norflash_speed = cfg->speed; +#endif + + max_speed = flash_list[flash_idx]->max_speed; + ratio = flash_list[flash_idx]->speed_ratio; + + if (max_speed == 0) { + max_speed = NORFLASH_DEFAULT_MAX_SPEED; + } + if (max_speed > cfg->speed) { + max_speed = cfg->speed; + } + if (max_speed > cfg->source_clk) { + max_speed = cfg->source_clk; + } + std_read_speed = max_speed * (1 + ratio.s.std_read) / NORFLASH_SPEED_RATIO_DENOMINATOR; + others_speed = max_speed * (1 + ratio.s.others) / NORFLASH_SPEED_RATIO_DENOMINATOR; + + div = (cfg->source_clk + max_speed - 1) / max_speed; + div_read = (div < NORFLASH_MAX_DIV) ? div : NORFLASH_MAX_DIV; + div = (cfg->source_clk + std_read_speed - 1) / std_read_speed; + div_std_read = (div < NORFLASH_MAX_DIV) ? div : NORFLASH_MAX_DIV; + div = (cfg->source_clk + others_speed - 1) / others_speed; + div_others = (div < NORFLASH_MAX_DIV) ? div : NORFLASH_MAX_DIV; + + if (div_read == 2 && max_speed >= FALLING_EDGE_SAMPLE_ADJ_FREQ) { + falling_edge_adj = true; + } else { + falling_edge_adj = false; + } + + if (div_read && div_std_read && div_others) { +#if (CHIP_FLASH_CTRL_VER <= 1) + if (div_read == 1) { + return -1; + } +#else + if (div_read == 1 && max_speed > NORFLASH_DIV1_MAX_SPEED) { + return -1; + } +#endif + // Init sample delay according to div_read + norflash_init_sample_delay_by_div(div_read); + // Still in command mode + norflaship_div(div_others); + return 0; + } + + return 1; +} + +int norflash_match_chip(const uint8_t *id, uint32_t len) +{ + const uint8_t *cmp_id; + + if (len == NORFLASH_ID_LEN) { + for (flash_idx = 0; flash_idx < ARRAY_SIZE(flash_list); flash_idx++) { + cmp_id = flash_list[flash_idx]->id; + if (id[0] == cmp_id[0] && id[1] == cmp_id[1] && id[2] == cmp_id[2]) { + return true; + } + } + } + + return false; +} + +#ifdef PUYA_FLASH_ERASE_PAGE_ENABLE +static void norflaship_ext_cmd_addr(uint8_t cmd, uint32_t addr) +{ + uint8_t buff[3]; + + buff[2] = (uint8_t)(addr & 0xff); + buff[1] = (uint8_t)((addr >> 8) & 0xff); + buff[0] = (uint8_t)((addr >> 16) & 0xff); + + norflaship_clear_txfifo(); + norflaship_write_txfifo(buff, 3); + norflaship_ext_tx_cmd(cmd, 3); +} +#endif + +enum HAL_NORFLASH_RET_T norflash_erase(uint32_t start_address, enum DRV_NORFLASH_ERASE_T type, int suspend) +{ + enum HAL_NORFLASH_RET_T ret; + + if (flash_list[flash_idx]->mode & HAL_NORFLASH_OP_MODE_ERASE_IN_STD) { + if(norflash_op_mode & HAL_NORFLASH_OP_MODE_QUAD_IO) { + norflash_set_quad_io_mode(0); + } else if(norflash_op_mode & HAL_NORFLASH_OP_MODE_QUAD_OUTPUT) { + norflash_set_quad_output_mode(0); + } + } + + norflaship_cmd_addr(GD25Q32C_CMD_WRITE_ENABLE, start_address); + // Need 1us. Or norflash_status_WEL_0_wait(), which needs 6us. + switch(type) { +#ifdef PUYA_FLASH_ERASE_PAGE_ENABLE + case DRV_NORFLASH_ERASE_PAGE: + norflaship_ext_cmd_addr(PUYA_FLASH_CMD_PAGE_ERASE, start_address); + break; +#endif + case DRV_NORFLASH_ERASE_SECTOR: + norflaship_cmd_addr(GD25Q32C_CMD_SECTOR_ERASE, start_address); + break; + case DRV_NORFLASH_ERASE_BLOCK: + norflaship_cmd_addr(GD25Q32C_CMD_BLOCK_ERASE, start_address); + break; + case DRV_NORFLASH_ERASE_CHIP: + norflaship_cmd_addr(GD25Q32C_CMD_CHIP_ERASE, start_address); + break; + } + + norflaship_busy_wait(); + +#ifdef FLASH_SUSPEND + // PUYA flash requires the first delay of erase >= 400us + if (flash_list[flash_idx]->id[0] == NORFLASH_PUYA_ID_PREFIX) { + norflash_delay(400); + } +#endif + + ret = norflash_status_WIP_1_wait(suspend); + + if (flash_list[flash_idx]->mode & HAL_NORFLASH_OP_MODE_ERASE_IN_STD) { + if(norflash_op_mode & HAL_NORFLASH_OP_MODE_QUAD_IO) { + norflash_set_quad_io_mode(1); + } else if(norflash_op_mode & HAL_NORFLASH_OP_MODE_QUAD_OUTPUT) { + norflash_set_quad_output_mode(1); + } + } + + norflaship_cmd_done(); + + return ret; +} + +enum HAL_NORFLASH_RET_T norflash_write(uint32_t start_address, const uint8_t *buffer, uint32_t len, int suspend) +{ + enum HAL_NORFLASH_RET_T ret; + uint32_t POSSIBLY_UNUSED remains; + + if (len > GD25Q32C_PAGE_SIZE) { + return HAL_NORFLASH_ERR; + } + + norflaship_clear_txfifo(); + +#if (CHIP_FLASH_CTRL_VER >= 2) + norflaship_blksize(len); +#endif + + remains = norflaship_write_txfifo(buffer, len); + + norflaship_cmd_addr(GD25Q32C_CMD_WRITE_ENABLE, start_address); + if (norflash_op_mode & HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM) { + norflaship_cmd_addr(GD25Q32C_CMD_QUAD_PAGE_PROGRAM, start_address); + } else if (norflash_op_mode & HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM) { + norflaship_cmd_addr(GD25Q32C_CMD_DUAL_PAGE_PROGRAM, start_address); + } else { + norflaship_cmd_addr(GD25Q32C_CMD_PAGE_PROGRAM, start_address); + } + +#if (CHIP_FLASH_CTRL_VER >= 2) + while (remains > 0) { + buffer += len - remains; + len = remains; + remains = norflaship_write_txfifo(buffer, len); + } +#endif + + norflaship_busy_wait(); + +#ifdef FLASH_SUSPEND + // PUYA flash requires the first delay of byte program >= 450us + if (flash_list[flash_idx]->id[0] == NORFLASH_PUYA_ID_PREFIX && len < GD25Q32C_PAGE_SIZE) { + norflash_delay(450); + } +#endif + + ret = norflash_status_WIP_1_wait(suspend); + + norflaship_cmd_done(); + + return ret; +} + +#ifdef FLASH_SUSPEND +enum HAL_NORFLASH_RET_T norflash_erase_resume(int suspend) +{ + // TODO: Need to check SUS1 bit in status reg? + + enum HAL_NORFLASH_RET_T ret; + + norflash_pre_operation(); + + norflash_resume(); + + ret = norflash_status_WIP_1_wait(suspend); + + norflash_post_operation(); + + return ret; +} + +enum HAL_NORFLASH_RET_T norflash_write_resume(int suspend) +{ + // TODO: Need to check SUS2 bit in status reg? + + return norflash_erase_resume(suspend); +} +#endif + +int norflash_read(uint32_t start_address, uint8_t *buffer, uint32_t len) +{ + uint32_t index = 0; + uint8_t val; + + if (len > NORFLASHIP_RXFIFO_SIZE) { + return 1; + } + + norflaship_clear_rxfifo(); + + norflaship_busy_wait(); + + norflaship_blksize(len); + + if (norflash_op_mode & HAL_NORFLASH_OP_MODE_QUAD_IO) { + /* Quad , only fast */ + norflaship_cmd_addr(GD25Q32C_CMD_FAST_QUAD_IO_READ, start_address); + } else if (norflash_op_mode & HAL_NORFLASH_OP_MODE_QUAD_OUTPUT) { + /* Dual, only fast */ + norflaship_cmd_addr(GD25Q32C_CMD_FAST_QUAD_OUTPUT_READ, start_address); + } else if (norflash_op_mode & HAL_NORFLASH_OP_MODE_DUAL_IO) { + /* Dual, only fast */ + norflaship_cmd_addr(GD25Q32C_CMD_FAST_DUAL_IO_READ, start_address); + } else if (norflash_op_mode & HAL_NORFLASH_OP_MODE_DUAL_OUTPUT) { + /* Dual, only fast */ + norflaship_cmd_addr(GD25Q32C_CMD_FAST_DUAL_OUTPUT_READ, start_address); + } else if (norflash_op_mode & HAL_NORFLASH_OP_MODE_FAST_SPI){ + /* fast */ + norflaship_cmd_addr(GD25Q32C_CMD_STANDARD_FAST_READ, start_address); + } else { + /* normal */ + norflaship_cmd_addr(GD25Q32C_CMD_STANDARD_READ, start_address); + } + + while (1) { + norflaship_rxfifo_empty_wait(); + + val = norflaship_read_rxfifo(); + if (buffer) { + buffer[index] = val; + } + + ++index; + if (index >= len) { + break; + } + } + + norflaship_cmd_done(); + + return 0; +} + +void norflash_sleep(void) +{ + norflash_pre_operation(); +#ifdef FLASH_HPM + if (norflash_op_mode & HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE) { + norflash_set_hpm(0); + } +#endif + norflaship_cmd_addr(GD25Q32C_CMD_DEEP_POWER_DOWN, 0); +} + +void norflash_wakeup(void) +{ + norflaship_cmd_addr(GD25Q32C_CMD_RELEASE_FROM_DP, 0); + // Wait 20us for flash to finish + norflash_delay(40); +#ifdef FLASH_HPM + if (norflash_op_mode & HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE) { + norflash_set_hpm(1); + } +#endif + norflash_post_operation(); +} + +int norflash_init_status(uint32_t status) +{ + if (flash_list[flash_idx]->write_status == NULL) { + return -1; + } + + flash_list[flash_idx]->write_status(DRV_NORFLASH_W_STATUS_INIT, status); + + return 0; +} + +int norflash_set_block_protection(uint32_t bp) +{ + if (flash_list[flash_idx]->write_status == NULL) { + return -1; + } + + flash_list[flash_idx]->write_status(DRV_NORFLASH_W_STATUS_BP, bp); + + return 0; +} + +#ifdef FLASH_SECURITY_REGISTER +int norflash_security_register_lock(uint32_t id) +{ + if (flash_list[flash_idx]->write_status == NULL) { + return -1; + } + + flash_list[flash_idx]->write_status(DRV_NORFLASH_W_STATUS_LB, id); + + return 0; +} + +enum HAL_NORFLASH_RET_T norflash_security_register_erase(uint32_t start_address) +{ + enum HAL_NORFLASH_RET_T ret; + + norflaship_cmd_addr(GD25Q32C_CMD_WRITE_ENABLE, start_address); + // Need 1us. Or norflash_status_WEL_0_wait(), which needs 6us. + + norflaship_cmd_addr(GD25Q32C_CMD_SECURITY_REGISTER_ERASE, start_address); + + ret = norflash_status_WIP_1_wait(0); + + norflaship_cmd_done(); + + return ret; +} + +enum HAL_NORFLASH_RET_T norflash_security_register_write(uint32_t start_address, const uint8_t *buffer, uint32_t len) +{ + enum HAL_NORFLASH_RET_T ret; + uint32_t remains; + + // Security register page size might be larger than normal page size + // E.g., the size of P25Q32L and P25Q64L is 1024 + + norflaship_clear_txfifo(); + +#if (CHIP_FLASH_CTRL_VER <= 1) + uint32_t div = 0; + + if (len > NORFLASHIP_TXFIFO_SIZE) { + div = norflaship_get_div(); + + // Slow down to avoid tx fifo underflow (it takes about 10 cpu cycles to fill one byte) + norflaship_div(16); + } + + remains = norflaship_v1_write_txfifo_safe(buffer, len); +#else + norflaship_blksize(len); + + remains = norflaship_write_txfifo(buffer, len); +#endif + + norflaship_cmd_addr(GD25Q32C_CMD_WRITE_ENABLE, start_address); + + norflaship_cmd_addr(GD25Q32C_CMD_SECURITY_REGISTER_PROGRAM, start_address); + +#if (CHIP_FLASH_CTRL_VER <= 1) + if (remains) { + norflaship_v1_write_txfifo_all(buffer, len); + } +#else + while (remains > 0) { + buffer += len - remains; + len = remains; + remains = norflaship_write_txfifo(buffer, len); + } +#endif + + norflaship_busy_wait(); + + ret = norflash_status_WIP_1_wait(0); + +#if (CHIP_FLASH_CTRL_VER <= 1) + if (div) { + // Restore the old div + norflaship_div(div); + } +#endif + + norflaship_cmd_done(); + + return ret; +} + +int norflash_security_register_read(uint32_t start_address, uint8_t *buffer, uint32_t len) +{ + uint32_t index = 0; + + if (len > NORFLASHIP_RXFIFO_SIZE) { + return 1; + } + + norflaship_clear_rxfifo(); + + norflaship_busy_wait(); + + norflaship_blksize(len); + + norflaship_cmd_addr(GD25Q32C_CMD_SECURITY_REGISTER_READ, start_address); + + while (1) { + norflaship_rxfifo_empty_wait(); + + buffer[index] = norflaship_read_rxfifo(); + + ++index; + if (index >= len) { + break; + } + } + + norflaship_cmd_done(); + + return 0; +} + +uint32_t norflash_security_register_enable_read(void) +{ + uint32_t mode; + + mode = norflash_op_mode; + + norflash_set_mode(0); + + norflaship_busy_wait(); +#if (CHIP_FLASH_CTRL_VER <= 1) + norflash_read(FLASH_NC_BASE, NULL, 1); +#endif + norflaship_clear_rxfifo(); + norflaship_busy_wait(); + norflaship_rdcmd(GD25Q32C_CMD_SECURITY_REGISTER_READ); + norflaship_busy_wait(); + + return mode; +} + +void norflash_security_register_disable_read(uint32_t mode) +{ + norflaship_busy_wait(); +#if (CHIP_FLASH_CTRL_VER <= 1) + norflash_read(FLASH_NC_BASE, NULL, 1); +#endif + norflaship_clear_rxfifo(); + norflaship_busy_wait(); + norflaship_rdcmd(GD25Q32C_CMD_STANDARD_READ); + norflaship_busy_wait(); + + norflash_set_mode(mode); +} + +#endif + diff --git a/platform/drivers/norflash/norflash_drv.h b/platform/drivers/norflash/norflash_drv.h new file mode 100644 index 0000000..be9d56d --- /dev/null +++ b/platform/drivers/norflash/norflash_drv.h @@ -0,0 +1,189 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef DRV_NORFLASH_H +#define DRV_NORFLASH_H + +#include "plat_types.h" +#include "hal_norflash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NORFLASH_ID_LEN 3 + +enum DRV_NORFLASH_ERASE_T { +#ifdef PUYA_FLASH_ERASE_PAGE_ENABLE + DRV_NORFLASH_ERASE_PAGE, +#endif + DRV_NORFLASH_ERASE_SECTOR, + DRV_NORFLASH_ERASE_BLOCK, + DRV_NORFLASH_ERASE_CHIP, +}; + +enum DRV_NORFLASH_W_STATUS_T { + DRV_NORFLASH_W_STATUS_INIT, + DRV_NORFLASH_W_STATUS_QE, + DRV_NORFLASH_W_STATUS_LB, + DRV_NORFLASH_W_STATUS_BP, +}; + +enum SPEED_RATIO_T { + SPEED_RATIO_1_EIGHTH, + SPEED_RATIO_2_EIGHTH, + SPEED_RATIO_3_EIGHTH, + SPEED_RATIO_4_EIGHTH, + SPEED_RATIO_5_EIGHTH, + SPEED_RATIO_6_EIGHTH, + SPEED_RATIO_7_EIGHTH, + SPEED_RATIO_8_EIGHTH, +}; + +enum DRV_NORFLASH_CALIB_T { + DRV_NORFLASH_CALIB_FLASH_ID, + DRV_NORFLASH_CALIB_MAGIC_WORD, + + DRV_NORFLASH_CALIB_QTY, +}; + +union DRV_NORFLASH_SPEED_RATIO_T { + struct { + uint8_t std_read :3; + uint8_t others :3; + uint8_t reserved :2; + } s; + uint8_t v; +}; + +union DRV_NORFLASH_SEC_REG_CFG_T { + struct { + uint16_t enabled :1; + uint16_t base :2; + uint16_t size :2; + uint16_t offset :2; + uint16_t cnt :2; + uint16_t pp :2; + uint16_t lb :2; + uint16_t reserved :3; + } s; + uint16_t v; +}; + +typedef int (*NORFLASH_WRITE_STATUS_CB)(enum DRV_NORFLASH_W_STATUS_T type, uint32_t param); + +struct NORFLASH_CFG_T { + const uint8_t id[NORFLASH_ID_LEN]; + const union DRV_NORFLASH_SPEED_RATIO_T speed_ratio; + const uint8_t crm_en_bits; + const uint8_t crm_dis_bits; + const uint16_t block_protect_mask; + const union DRV_NORFLASH_SEC_REG_CFG_T sec_reg_cfg; + const uint16_t page_size; + const uint16_t sector_size; + const uint32_t block_size; + const uint32_t total_size; + const uint32_t max_speed; + const uint32_t mode; + const NORFLASH_WRITE_STATUS_CB write_status; +}; + +uint8_t norflash_read_status_s0_s7(void); + +uint8_t norflash_read_status_s8_s15(void); + +void norflash_status_WEL_0_wait(void); + +enum HAL_NORFLASH_RET_T norflash_status_WIP_1_wait(int suspend); + +uint32_t norflash_get_supported_mode(void); + +uint32_t norflash_get_current_mode(void); + +union DRV_NORFLASH_SEC_REG_CFG_T norflash_get_security_register_config(void); + +uint32_t norflash_get_block_protect_mask(void); + +void norflash_reset(void); + +int norflash_get_size(uint32_t *total_size, uint32_t *block_size, uint32_t *sector_size, uint32_t *page_size); + +int norflash_set_mode(uint32_t op); + +int norflash_pre_operation(void); + +int norflash_post_operation(void); + +int norflash_read_reg(uint8_t cmd, uint8_t *val, uint32_t len); + +int norflash_read_reg_ex(uint8_t cmd, uint8_t *param, uint32_t param_len, uint8_t *val, uint32_t len); + +int norflash_write_reg(uint8_t cmd, const uint8_t *val, uint32_t len); + +int norflash_init_sample_delay_by_div(uint32_t div); + +void norflash_set_sample_delay_index(uint32_t index); + +uint32_t norflash_get_sample_delay_index(void); + +int norflash_sample_delay_calib(enum DRV_NORFLASH_CALIB_T type); + +void norflash_show_calib_result(void); + +int norflash_init_div(const struct HAL_NORFLASH_CONFIG_T *cfg); + +int norflash_match_chip(const uint8_t *id, uint32_t len); + +int norflash_get_id(uint8_t *value, uint32_t len); + +int norflash_get_unique_id(uint8_t *value, uint32_t len); + +enum HAL_NORFLASH_RET_T norflash_erase(uint32_t start_address, enum DRV_NORFLASH_ERASE_T type, int suspend); + +enum HAL_NORFLASH_RET_T norflash_erase_resume(int suspend); + +enum HAL_NORFLASH_RET_T norflash_write(uint32_t start_address, const uint8_t *buffer, uint32_t len, int suspend); + +enum HAL_NORFLASH_RET_T norflash_write_resume(int suspend); + +int norflash_suspend_check_irq(uint32_t irq_num); + +int norflash_read(uint32_t start_address, uint8_t *buffer, uint32_t len); + +void norflash_sleep(void); + +void norflash_wakeup(void); + +int norflash_init_status(uint32_t status); + +int norflash_set_block_protection(uint32_t bp); + +int norflash_security_register_lock(uint32_t id); + +enum HAL_NORFLASH_RET_T norflash_security_register_erase(uint32_t start_address); + +enum HAL_NORFLASH_RET_T norflash_security_register_write(uint32_t start_address, const uint8_t *buffer, uint32_t len); + +int norflash_security_register_read(uint32_t start_address, uint8_t *buffer, uint32_t len); + +uint32_t norflash_security_register_enable_read(void); + +void norflash_security_register_disable_read(uint32_t mode); + +#ifdef __cplusplus +} +#endif + +#endif /* DRV_NORFLASH_H */ diff --git a/platform/drivers/norflash/norflash_en25s80b.c b/platform/drivers/norflash/norflash_en25s80b.c new file mode 100644 index 0000000..38453cf --- /dev/null +++ b/platform/drivers/norflash/norflash_en25s80b.c @@ -0,0 +1,143 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "norflash_drv.h" +#include "hal_norflaship.h" +#include "norflash_en25s80b.h" +#include "hal_trace.h" +#include "hal_timer.h" + +static void POSSIBLY_UNUSED en25s80b_en25s80b_reset(void) +{ + // ip quad mode + norflaship_quad_mode(1); + norflaship_busy_wait(); + + hal_sys_timer_delay(20); + + // quad reset enable + norflaship_clear_txfifo(); + norflaship_cmd_addr(EN25S80B_CMD_QUAD_RESET_ENABLE, 0); + norflaship_busy_wait(); + + hal_sys_timer_delay(20); + + // quad reset + norflaship_clear_txfifo(); + norflaship_cmd_addr(EN25S80B_CMD_QUAD_RESET, 0); + norflaship_busy_wait(); + + hal_sys_timer_delay(20); + + // ip spi mode + norflaship_quad_mode(0); + norflaship_hold_pin(0); + norflaship_wpr_pin(0); + norflaship_busy_wait(); + + hal_sys_timer_delay(20); + + // reset enable + norflaship_clear_txfifo(); + norflaship_cmd_addr(EN25S80B_CMD_SPI_RESET_ENABLE, 0); + norflaship_busy_wait(); + + hal_sys_timer_delay(20); + + // reset + norflaship_clear_txfifo(); + norflaship_cmd_addr(EN25S80B_CMD_SPI_RESET, 0); + norflaship_busy_wait(); + + hal_sys_timer_delay(20); +} + +static void en25s80b_enter_OTP(void) +{ + norflaship_clear_txfifo(); + norflaship_cmd_addr(EN25S80B_CMD_ENTER_OTP, 0); + norflash_status_WIP_1_wait(0); +} + +static void en25s80b_exit_OTP(void) +{ + norflaship_clear_txfifo(); + norflaship_cmd_addr(EN25S80B_CMD_EXIT_OTP, 0); + norflash_status_WIP_1_wait(0); +} + +static void en25s80b_write_status_s0_s7(uint8_t status) +{ + norflash_write_reg(EN25S80B_CMD_WRITE_STATUS, &status, 1); +} + +static int en25s80b_write_status(enum DRV_NORFLASH_W_STATUS_T type, uint32_t param) +{ + uint8_t status; + + if (type == DRV_NORFLASH_W_STATUS_QE) { + en25s80b_enter_OTP(); + + status = norflash_read_status_s0_s7(); + + if (param) { + status |= (EN25S80B_WHDIS_BIT_MASK); + } else { + status &= ~(EN25S80B_WHDIS_BIT_MASK); + } + + en25s80b_write_status_s0_s7(status); + + en25s80b_exit_OTP(); + + return 0; + } + + return 1; +} + +const struct NORFLASH_CFG_T en25s80b_cfg = { + .id = { 0x1C, 0x38, 0x14, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_6_EIGHTH, + .others = SPEED_RATIO_6_EIGHTH, + }, + }, + .crm_en_bits = 0xA5, + .crm_dis_bits = 0xAA, + .sec_reg_cfg = { + .s = { + .enabled = false, + }, + }, + .page_size = EN25S80B_PAGE_SIZE, + .sector_size = EN25S80B_SECTOR_SIZE, + .block_size = EN25S80B_BLOCK_SIZE, + .total_size = EN25S80B_TOTAL_SIZE, + .max_speed = 104 * 1000 * 1000, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_ERASE_IN_STD), + .write_status = en25s80b_write_status, +}; + diff --git a/platform/drivers/norflash/norflash_en25s80b.h b/platform/drivers/norflash/norflash_en25s80b.h new file mode 100644 index 0000000..54c9465 --- /dev/null +++ b/platform/drivers/norflash/norflash_en25s80b.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef NORFLASH_EN25S80B_H +#define NORFLASH_EN25S80B_H + +#include "plat_types.h" + +/* bytes */ +#define EN25S80B_PAGE_SIZE (256) +#define EN25S80B_SECTOR_SIZE (4096) +#define EN25S80B_BLOCK_SIZE (32*1024) +#define EN25S80B_TOTAL_SIZE (1*1024*1024) + +/* device cmd : FIXME fixed for EN25S80B */ +#define EN25S80B_CMD_ID 0x9F +#define EN25S80B_CMD_WRITE_ENABLE 0x06 +#define EN25S80B_CMD_PAGE_PROGRAM 0x02 +#define EN25S80B_CMD_QUAD_PAGE_PROGRAM 0x32 +#define EN25S80B_CMD_BLOCK_ERASE_32K 0x52 +#define EN25S80B_CMD_BLOCK_ERASE_64K 0xD8 +#define EN25S80B_CMD_BLOCK_ERASE EN25S80B_CMD_BLOCK_ERASE_32K +#define EN25S80B_CMD_SECTOR_ERASE 0x20 +#define EN25S80B_CMD_CHIP_ERASE 0x60 +#define EN25S80B_CMD_READ_STATUS_S0_S7 0x05 +#define EN25S80B_CMD_READ_STATUS_S8_S15 0x35 +#define EN25S80B_CMD_WRITE_STATUS 0x01 +#define EN25S80B_CMD_WRITE_STATUS3 0xC0 +#define EN25S80B_CMD_READ_STATUS3 0x95 +#define EN25S80B_CMD_WRITE_STATUS_S0_S7 0x01 +#define EN25S80B_CMD_WRITE_STATUS_S8_S15 0x31 +#define EN25S80B_CMD_FAST_QUAD_READ 0xEB +#define EN25S80B_CMD_FAST_DUAL_READ 0xBB +#define EN25S80B_CMD_STANDARD_READ 0x03 +#define EN25S80B_CMD_STANDARD_FAST_READ 0x0B +#define EN25S80B_CMD_DEEP_POWER_DOWN 0xB9 +#define EN25S80B_CMD_RELEASE_FROM_DP 0xAB +#define EN25S80B_CMD_HIGH_PERFORMANCE 0xA3 + +#define EN25S80B_CMD_QUAD_RESET_ENABLE 0x66 +#define EN25S80B_CMD_QUAD_RESET 0x99 +#define EN25S80B_CMD_SPI_RESET_ENABLE 0x66 +#define EN25S80B_CMD_SPI_RESET 0x99 + +#define EN25S80B_CMD_EQPI_SET 0x38 +#define EN25S80B_CMD_EQPI_RELEASE 0xff + +#define EN25S80B_CMD_ENTER_OTP 0x3A +#define EN25S80B_CMD_EXIT_OTP 0x04 + +/* device register */ +/* status register */ +#define EN25S80B_WIP_BIT_SHIFT 0 +#define EN25S80B_WIP_BIT_MASK ((0x1)<>= 8; + bp_mask >>= 8; + status_s8_s15 = (status_s8_s15 & ~bp_mask) | (param & bp_mask); + } else if (type == DRV_NORFLASH_W_STATUS_LB) { + cfg = norflash_get_security_register_config(); + if (!cfg.s.enabled) { + return 2; + } + if (cfg.s.lb == SEC_REG_LB_S11_S13) { + if (param >= 3) { + return 3; + } + status_s8_s15 |= (STATUS_S11_LB1_BIT_MASK << param); + } else if (cfg.s.lb == SEC_REG_LB_S10) { + status_s8_s15 |= STATUS_S10_LB_BIT_MASK; + } else { + return 4; + } + } + + gd25lq32c_write_status_s0_s15(status_s0_s7 | (status_s8_s15 << 8), 2); + } else { + gd25lq32c_write_status_s0_s15(status_s0_s7, 1); + } + + return 0; +} + +// ---------------------- +// GigaDevice +// ---------------------- + +const struct NORFLASH_CFG_T gd25lq64c_cfg = { + .id = { 0xC8, 0x60, 0x17, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_6_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_1024, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = GD25LQ64C_TOTAL_SIZE, + .max_speed = 104 * 1000 * 1000, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25lq32c_write_status, +}; + +const struct NORFLASH_CFG_T gd25lq32c_cfg = { + .id = { 0xC8, 0x60, 0x16, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_5_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_1024, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = GD25LQ32C_TOTAL_SIZE, + .max_speed = 120 * 1000 * 1000, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25lq32c_write_status, +}; + +const struct NORFLASH_CFG_T gd25lq16c_cfg = { + .id = { 0xC8, 0x60, 0x15, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_6_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_512, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = GD25LQ16C_TOTAL_SIZE, + .max_speed = 104 * 1000 * 1000, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25lq32c_write_status, +}; + +const struct NORFLASH_CFG_T gd25lq80c_cfg = { + .id = { 0xC8, 0x60, 0x14, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_6_EIGHTH, + .others = SPEED_RATIO_6_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_512, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = GD25LQ80C_TOTAL_SIZE, + .max_speed = 104 * 1000 * 1000, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25lq32c_write_status, +}; + +const struct NORFLASH_CFG_T gd25q80c_cfg = { + .id = { 0xC8, 0x40, 0x14, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_5_EIGHTH, + .others = SPEED_RATIO_5_EIGHTH, + }, + }, + .crm_en_bits = 0xA0, + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X0000, + .size = SEC_REG_SIZE_256, + .offset = SEC_REG_OFFSET_0X0100, + .cnt = SEC_REG_CNT_4, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S10, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = GD25Q80C_TOTAL_SIZE, +#ifdef FLASH_HPM + .max_speed = 120 * 1000 * 1000, +#else + .max_speed = 104 * 1000 * 1000, +#endif + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | +#ifdef FLASH_HPM + HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE | +#endif + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25lq32c_write_status, +}; + +const struct NORFLASH_CFG_T gd25d40c_cfg = { + .id = { 0xC8, 0x40, 0x13, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_6_EIGHTH, + .others = SPEED_RATIO_6_EIGHTH, + }, + }, + .crm_en_bits = 0, + .crm_dis_bits = 0, + .block_protect_mask = 0x1C, + .sec_reg_cfg = { + .s = { + .enabled = false, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = GD25D40C_TOTAL_SIZE, + .max_speed = 80 * 1000 * 1000, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM), + .write_status = gd25lq32c_write_status, +}; + +const struct NORFLASH_CFG_T gd25d20c_cfg = { + .id = { 0xC8, 0x40, 0x12, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_6_EIGHTH, + .others = SPEED_RATIO_6_EIGHTH, + }, + }, + .crm_en_bits = 0, + .crm_dis_bits = 0, + .block_protect_mask = 0x1C, + .sec_reg_cfg = { + .s = { + .enabled = false, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = GD25D20C_TOTAL_SIZE, + .max_speed = 80 * 1000 * 1000, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM), + .write_status = gd25lq32c_write_status, +}; + +// ---------------------- +// Puya +// ---------------------- + +const struct NORFLASH_CFG_T p25q16l_cfg = { + .id = { 0x85, 0x60, 0x15, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_3_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_512, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = P25Q16L_TOTAL_SIZE, + .max_speed = 70 * 1000 * 1000, // P25Q80L=70M, P25Q80H=104M, P25Q80U=70M/104M + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25lq32c_write_status, +}; + +const struct NORFLASH_CFG_T p25q80h_cfg = { + .id = { 0x85, 0x60, 0x14, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_3_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_512, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = P25Q80H_TOTAL_SIZE, + .max_speed = 70 * 1000 * 1000, // P25Q80L=70M, P25Q80H=104M, P25Q80U=70M/104M + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25lq32c_write_status, +}; + +const struct NORFLASH_CFG_T p25q40h_cfg = { + .id = { 0x85, 0x60, 0x13, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_3_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_512, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = P25Q40H_TOTAL_SIZE, + .max_speed = 70 * 1000 * 1000, // P25Q21L=70M, P25Q21H=104M, P25Q21U=70M/104M + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25lq32c_write_status, +}; + + +const struct NORFLASH_CFG_T p25q21h_cfg = { + .id = { 0x85, 0x40, 0x12, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_3_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_512, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = P25Q21H_TOTAL_SIZE, + .max_speed = 70 * 1000 * 1000, // P25Q21L=70M, P25Q21H=104M, P25Q21U=70M/104M + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25lq32c_write_status, +}; + +// ---------------------- +// XTS +// ---------------------- + +const struct NORFLASH_CFG_T xt25q08b_cfg = { + .id = { 0x0B, 0x60, 0x14, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_7_EIGHTH, + .others = SPEED_RATIO_7_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x403C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X0000, + .size = SEC_REG_SIZE_256, + .offset = SEC_REG_OFFSET_0X0100, + .cnt = SEC_REG_CNT_4, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S10, + }, + }, + .page_size = GD25LQ32C_PAGE_SIZE, + .sector_size = GD25LQ32C_SECTOR_SIZE, + .block_size = GD25LQ32C_BLOCK_SIZE, + .total_size = XT25Q08B_TOTAL_SIZE, + .max_speed = 96 * 1000 * 1000, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25lq32c_write_status, +}; + diff --git a/platform/drivers/norflash/norflash_gd25lq32c.h b/platform/drivers/norflash/norflash_gd25lq32c.h new file mode 100644 index 0000000..3b8fe44 --- /dev/null +++ b/platform/drivers/norflash/norflash_gd25lq32c.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef NORFLASH_GD25LQ32C_H +#define NORFLASH_GD25LQ32C_H + +#include "plat_types.h" + +/* bytes */ +#define GD25LQ32C_PAGE_SIZE (256) +#define GD25LQ32C_SECTOR_SIZE (4096) +#define GD25LQ32C_BLOCK_SIZE (32*1024) +#define GD25LQ32C_TOTAL_SIZE (4*1024*1024) + +#define GD25LQ64C_TOTAL_SIZE (8*1024*1024) + +#define GD25LQ16C_TOTAL_SIZE (2*1024*1024) + +#define GD25LQ80C_TOTAL_SIZE (1*1024*1024) + +#define GD25Q80C_TOTAL_SIZE (1*1024*1024) + +#define GD25D40C_TOTAL_SIZE (512*1024) + +#define GD25D20C_TOTAL_SIZE (256*1024) + +#define P25Q16L_TOTAL_SIZE (2*1024*1024) + +#define P25Q80H_TOTAL_SIZE (1*1024*1024) + +#define P25Q21H_TOTAL_SIZE (256*1024) + +#define P25Q40H_TOTAL_SIZE (512*1024) + +#define XT25Q08B_TOTAL_SIZE (1*1024*1024) + +/* device cmd */ +#define GD25LQ32C_CMD_ID 0x9F +#define GD25LQ32C_CMD_WRITE_ENABLE 0x06 +#define GD25LQ32C_CMD_PAGE_PROGRAM 0x02 +#define GD25LQ32C_CMD_QUAD_PAGE_PROGRAM 0x32 +#define GD25LQ32C_CMD_BLOCK_ERASE_32K 0x52 +#define GD25LQ32C_CMD_BLOCK_ERASE_64K 0xD8 +#define GD25LQ32C_CMD_BLOCK_ERASE GD25LQ32C_CMD_BLOCK_ERASE_32K +#define GD25LQ32C_CMD_SECTOR_ERASE 0x20 +#define GD25LQ32C_CMD_CHIP_ERASE 0x60 +#define GD25LQ32C_CMD_READ_STATUS_S0_S7 0x05 +#define GD25LQ32C_CMD_READ_STATUS_S8_S15 0x35 +#define GD25LQ32C_CMD_WRITE_STATUS 0x01 + +#define GD25LQ32C_CMD_FAST_QUAD_READ 0xEB +#define GD25LQ32C_CMD_FAST_DUAL_READ 0xBB +#define GD25LQ32C_CMD_STANDARD_READ 0x03 +#define GD25LQ32C_CMD_STANDARD_FAST_READ 0x0B +#define GD25LQ32C_CMD_DEEP_POWER_DOWN 0xB9 +#define GD25LQ32C_CMD_RELEASE_FROM_DP 0xAB + +/* device register */ +/* status register _S0_S7*/ +#define GD25LQ32C_WIP_BIT_SHIFT 0 +#define GD25LQ32C_WIP_BIT_MASK ((0x1)<> 8) & 0xFF); + return 0; + } + + if (type == DRV_NORFLASH_W_STATUS_BP) { + bp_mask = norflash_get_block_protect_mask(); + status_s0_s7 = norflash_read_status_s0_s7(); + status_s0_s7 = (status_s0_s7 & ~bp_mask) | (param & bp_mask); + gd25q32c_write_status_s0_s7(status_s0_s7); + if ((bp_mask & ~0xFF) == 0) { + return 0; + } + } + + status_s8_s15 = norflash_read_status_s8_s15(); + + if (type == DRV_NORFLASH_W_STATUS_QE) { + if (param) { + status_s8_s15 |= GD25Q32C_QE_BIT_MASK; + } else { + status_s8_s15 &= ~(GD25Q32C_QE_BIT_MASK); + } + } else if (type == DRV_NORFLASH_W_STATUS_BP) { + param >>= 8; + bp_mask >>= 8; + status_s8_s15 = (status_s8_s15 & ~bp_mask) | (param & bp_mask); + } else if (type == DRV_NORFLASH_W_STATUS_LB) { + cfg = norflash_get_security_register_config(); + if (!cfg.s.enabled) { + return 2; + } + if (cfg.s.lb == SEC_REG_LB_S11_S13) { + if (param >= 3) { + return 3; + } + status_s8_s15 |= (STATUS_S11_LB1_BIT_MASK << param); + } else if (cfg.s.lb == SEC_REG_LB_S10) { + status_s8_s15 |= STATUS_S10_LB_BIT_MASK; + } else { + return 4; + } + } + + gd25q32c_write_status_s8_s15(status_s8_s15); + + return 0; +} + +// ---------------------- +// GigaDevice +// ---------------------- + +const struct NORFLASH_CFG_T gd25q32c_cfg = { + .id = { 0xC8, 0x40, 0x16, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_5_EIGHTH, + .others = SPEED_RATIO_5_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_1024, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25Q32C_PAGE_SIZE, + .sector_size = GD25Q32C_SECTOR_SIZE, + .block_size = GD25Q32C_BLOCK_SIZE, + .total_size = GD25Q32C_TOTAL_SIZE, +#ifdef FLASH_HPM + .max_speed = 120 * 1000 * 1000, +#else + // No high performance mode for gd25q32e + .max_speed = 104 * 1000 * 1000, +#endif + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | +#ifdef FLASH_HPM + HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE | +#endif + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25q32c_write_status, +}; + +// ---------------------- +// Puya +// ---------------------- + +const struct NORFLASH_CFG_T p25q128l_cfg = { + .id = { 0x85, 0x60, 0x18, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_3_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_1024, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_1024, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25Q32C_PAGE_SIZE, + .sector_size = GD25Q32C_SECTOR_SIZE, + .block_size = GD25Q32C_BLOCK_SIZE, + .total_size = P25Q128L_TOTAL_SIZE, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .max_speed = 85 * 1000 * 1000, + .write_status = gd25q32c_write_status, +}; + +const struct NORFLASH_CFG_T p25q64l_cfg = { + .id = { 0x85, 0x60, 0x17, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_3_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_1024, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_1024, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25Q32C_PAGE_SIZE, + .sector_size = GD25Q32C_SECTOR_SIZE, + .block_size = GD25Q32C_BLOCK_SIZE, + .total_size = P25Q64L_TOTAL_SIZE, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .max_speed = 70 * 1000 * 1000, // P25Q64L=70M, P25Q64H=120M, P25Q64U=70M/120M + .write_status = gd25q32c_write_status, +}; + +const struct NORFLASH_CFG_T p25q32l_cfg = { + .id = { 0x85, 0x60, 0x16, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_4_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_1024, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_1024, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25Q32C_PAGE_SIZE, + .sector_size = GD25Q32C_SECTOR_SIZE, + .block_size = GD25Q32C_BLOCK_SIZE, + .total_size = P25Q32L_TOTAL_SIZE, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .max_speed = 62 * 1000 * 1000, // P25Q32L=62.5M, P25Q32H=104M, P25Q32U=62.5M/104M + .write_status = gd25q32c_write_status, +}; + +// ---------------------- +// Xinxin +// ---------------------- + +// Additionally, the device supports JEDEC standard manufacturer and device ID and SFDP Register, +// a 64-bit Unique Serial Number and three 256-bytes Security Registers. +const struct NORFLASH_CFG_T xm25qh16c_cfg = { + .id = { 0x20, 0x40, 0x15, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_3_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_256, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25Q32C_PAGE_SIZE, + .sector_size = GD25Q32C_SECTOR_SIZE, + .block_size = GD25Q32C_BLOCK_SIZE, + .total_size = XM25QH16C_TOTAL_SIZE, + .max_speed = 108 * 1000 * 1000, + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25q32c_write_status, +}; + +const struct NORFLASH_CFG_T xm25qh80b_cfg = { + .id = { 0x20, 0x40, 0x14, }, + .speed_ratio = { + .s = { + .std_read = SPEED_RATIO_7_EIGHTH, + .others = SPEED_RATIO_8_EIGHTH, + }, + }, + .crm_en_bits = (1 << 5) | (0 << 4), + .crm_dis_bits = 0, + .block_protect_mask = 0x407C, + .sec_reg_cfg = { + .s = { + .enabled = true, + .base = SEC_REG_BASE_0X1000, + .size = SEC_REG_SIZE_256, + .offset = SEC_REG_OFFSET_0X1000, + .cnt = SEC_REG_CNT_3, + .pp = SEC_REG_PP_256, + .lb = SEC_REG_LB_S11_S13, + }, + }, + .page_size = GD25Q32C_PAGE_SIZE, + .sector_size = GD25Q32C_SECTOR_SIZE, + .block_size = GD25Q32C_BLOCK_SIZE, + .total_size = XM25QH80B_TOTAL_SIZE, + .max_speed = 60 * 1000 * 1000, // 104M (std_read=50M or 3/8) when HFM=1 (S20 or SR3-bit4) + .mode = (HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_SUSPEND), + .write_status = gd25q32c_write_status, +}; + diff --git a/platform/drivers/norflash/norflash_gd25q32c.h b/platform/drivers/norflash/norflash_gd25q32c.h new file mode 100644 index 0000000..323f967 --- /dev/null +++ b/platform/drivers/norflash/norflash_gd25q32c.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef NORFLASH_GD25Q32C_H +#define NORFLASH_GD25Q32C_H + +#include "plat_types.h" + +/* bytes */ +#define GD25Q32C_PAGE_SIZE (256) +#define GD25Q32C_SECTOR_SIZE (4096) +#define GD25Q32C_BLOCK_SIZE (32*1024) +#define GD25Q32C_TOTAL_SIZE (4*1024*1024) + +#define P25Q32L_TOTAL_SIZE (4*1024*1024) + +#define P25Q64L_TOTAL_SIZE (8*1024*1024) + +#define P25Q128L_TOTAL_SIZE (16*1024*1024) + +#define XM25QH16C_TOTAL_SIZE (2*1024*1024) + +#define XM25QH80B_TOTAL_SIZE (1*1024*1024) + +/* device cmd */ +#define GD25Q32C_CMD_ID 0x9F +#define GD25Q32C_CMD_WRITE_ENABLE 0x06 +#define GD25Q32C_CMD_PAGE_PROGRAM 0x02 +#define GD25Q32C_CMD_DUAL_PAGE_PROGRAM 0xA2 +#define GD25Q32C_CMD_QUAD_PAGE_PROGRAM 0x32 +#define GD25Q32C_CMD_BLOCK_ERASE_32K 0x52 +#define GD25Q32C_CMD_BLOCK_ERASE_64K 0xD8 +#define GD25Q32C_CMD_BLOCK_ERASE GD25Q32C_CMD_BLOCK_ERASE_32K +#define GD25Q32C_CMD_SECTOR_ERASE 0x20 +#define GD25Q32C_CMD_CHIP_ERASE 0x60 +#define GD25Q32C_CMD_READ_STATUS_S0_S7 0x05 +#define GD25Q32C_CMD_READ_STATUS_S8_S15 0x35 +#define GD25Q32C_CMD_WRITE_STATUS_S0_S7 0x01 +#define GD25Q32C_CMD_WRITE_STATUS_S8_S15 0x31 + +#define GD25Q32C_CMD_FAST_QUAD_IO_READ 0xEB +#define GD25Q32C_CMD_FAST_QUAD_OUTPUT_READ 0x6B +#define GD25Q32C_CMD_FAST_DUAL_IO_READ 0xBB +#define GD25Q32C_CMD_FAST_DUAL_OUTPUT_READ 0x3B +#define GD25Q32C_CMD_STANDARD_READ 0x03 +#define GD25Q32C_CMD_STANDARD_FAST_READ 0x0B +#define GD25Q32C_CMD_DEEP_POWER_DOWN 0xB9 +#define GD25Q32C_CMD_RELEASE_FROM_DP 0xAB +#define GD25Q32C_CMD_HIGH_PERFORMANCE 0xA3 +#define GD25Q32C_CMD_SET_BURST_WRAP 0x77 +#define GD25Q32C_CMD_UNIQUE_ID 0x4B +#define GD25Q32C_CMD_ENABLE_RESET 0x66 +#define GD25Q32C_CMD_RESET 0x99 +#define GD25Q32C_CMD_PROGRAM_ERASE_SUSPEND 0x75 +#define GD25Q32C_CMD_PROGRAM_ERASE_RESUME 0x7A +#define GD25Q32C_CMD_SECURITY_REGISTER_ERASE 0x44 +#define GD25Q32C_CMD_SECURITY_REGISTER_PROGRAM 0x42 +#define GD25Q32C_CMD_SECURITY_REGISTER_READ 0x48 + +#define PUYA_FLASH_CMD_PAGE_ERASE 0x81 + +/* status register _S0_S7*/ +#define GD25Q32C_WIP_BIT_SHIFT 0 +#define GD25Q32C_WIP_BIT_MASK ((0x1)<> 8) +#define DESCRIPTOR_INDEX(wValue) (wValue & 0xff) + +/* Device status */ +#define DEVICE_STATUS_SELF_POWERED (1U<<0) +#define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1) + +/* Endpoint status */ +#define ENDPOINT_STATUS_HALT (1U<<0) + +/* Standard feature selectors */ +#define DEVICE_REMOTE_WAKEUP (1) +#define ENDPOINT_HALT (0) +#define TEST_MODE (2) + +/* Test mode selectors */ +#define TEST_MODE_TEST_J (1) +#define TEST_MODE_TEST_K (2) +#define TEST_MODE_TEST_SE0_NAK (3) +#define TEST_MODE_TEST_PACKET (4) +#define TEST_MODE_FORCE_ENABLE (5) + +/* Standard descriptor types */ +#define DEVICE_DESCRIPTOR (1) +#define CONFIGURATION_DESCRIPTOR (2) +#define STRING_DESCRIPTOR (3) +#define INTERFACE_DESCRIPTOR (4) +#define ENDPOINT_DESCRIPTOR (5) +#define QUALIFIER_DESCRIPTOR (6) +#define BOS_DESCRIPTOR (0xF) + +/* Standard descriptor lengths */ +#define DEVICE_DESCRIPTOR_LENGTH (0x12) +#define CONFIGURATION_DESCRIPTOR_LENGTH (0x09) +#define INTERFACE_DESCRIPTOR_LENGTH (0x09) +#define ENDPOINT_DESCRIPTOR_LENGTH (0x07) +#define QUALIFIER_DESCRIPTOR_LENGTH (0x0A) +#define BOS_DESCRIPTOR_LENGTH (0x05) + +/*string offset*/ +#define STRING_OFFSET_LANGID (0) +#define STRING_OFFSET_IMANUFACTURER (1) +#define STRING_OFFSET_IPRODUCT (2) +#define STRING_OFFSET_ISERIAL (3) +#define STRING_OFFSET_ICONFIGURATION (4) +#define STRING_OFFSET_IINTERFACE (5) + +/* USB Specification Release Number */ +#define USB_VERSION_2_0 (0x0200) +#define USB_VERSION_1_1 (0x0101) + +/* Least/Most significant byte of short integer */ +#define LSB(n) ((n)&0xff) +#define MSB(n) (((n)&0xff00)>>8) + +#define LSB0(n) ((n) & 0xFF) +#define LSB1(n) (((n) >> 8) & 0xFF) +#define LSB2(n) (((n) >> 16) & 0xFF) +#define LSB3(n) (((n) >> 24) & 0xFF) + +/* Convert physical endpoint number to descriptor endpoint number */ +#define PHY_TO_DESC(endpoint, dir) (((endpoint) & 0xF) | ((dir == EP_OUT) ? 0 : 0x80)) + +/* bmAttributes in configuration descriptor */ +/* C_RESERVED must always be set */ +#define C_RESERVED (1U<<7) +#define C_SELF_POWERED (1U<<6) +#define C_REMOTE_WAKEUP (1U<<5) + +/* bMaxPower in configuration descriptor */ +#define C_POWER(mA) ((mA)/2) + +/* bmAttributes in endpoint descriptor */ +#define E_CONTROL (0x00) +#define E_ISOCHRONOUS (0x01) +#define E_BULK (0x02) +#define E_INTERRUPT (0x03) + +/* For isochronous endpoints only: */ +#define E_NO_SYNCHRONIZATION (0x00) +#define E_ASYNCHRONOUS (0x04) +#define E_ADAPTIVE (0x08) +#define E_SYNCHRONOUS (0x0C) +#define E_DATA (0x00) +#define E_FEEDBACK (0x10) +#define E_IMPLICIT_FEEDBACK (0x20) + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/usb/usb_dev/inc/usb_dev_desc.h b/platform/drivers/usb/usb_dev/inc/usb_dev_desc.h new file mode 100644 index 0000000..7cfd428 --- /dev/null +++ b/platform/drivers/usb/usb_dev/inc/usb_dev_desc.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __USB_DEV_DESC_H__ +#define __USB_DEV_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +#ifdef USB_AUDIO_32BIT +#if defined(USB_AUDIO_192K) && !defined(USB_HIGH_SPEED) +#error "192K 32BIT stream can run on USB_HIGH_SPEED only" +#endif +#if defined(USB_AUDIO_176_4K) && !defined(USB_HIGH_SPEED) +#error "176.4K 32BIT stream can run on USB_HIGH_SPEED only" +#endif +#elif defined(USB_AUDIO_24BIT) +#if defined(USB_AUDIO_192K) && !defined(USB_HIGH_SPEED) +#error "192K 24BIT stream can run on USB_HIGH_SPEED only" +#endif +#if defined(USB_AUDIO_176_4K) && !defined(USB_HIGH_SPEED) +#error "176.4K 24BIT stream can run on USB_HIGH_SPEED only" +#endif +#endif + +#if defined(USB_AUDIO_384K) && !(defined(USB_HIGH_SPEED) && defined(USB_AUDIO_UAC2)) +#error "384K stream can run on USB_HIGH_SPEED and USB_AUDIO_UAC2 only" +#endif +#if defined(USB_AUDIO_352_8K) && !(defined(USB_HIGH_SPEED) && defined(USB_AUDIO_UAC2)) +#error "352.8K stream can run on USB_HIGH_SPEED and USB_AUDIO_UAC2 only" +#endif + +#if defined(USB_AUDIO_UAC2) && !defined(USB_HIGH_SPEED) +#error "USB_AUDIO_UAC2 should run on USB_HIGH_SPEED" +#endif + +const uint8_t *cdc_dev_desc(uint8_t type); + +const uint8_t *cdc_string_desc(uint8_t index); + +const uint8_t *uaud_dev_desc(uint8_t type); + +const uint8_t *uaud_string_desc(uint8_t index); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/drivers/usb/usb_dev/uaud_cfg_flags.mk b/platform/drivers/usb/usb_dev/uaud_cfg_flags.mk new file mode 100644 index 0000000..bb7d926 --- /dev/null +++ b/platform/drivers/usb/usb_dev/uaud_cfg_flags.mk @@ -0,0 +1,110 @@ + +UAUD_CFG_FLAGS := + +ifeq ($(USB_AUDIO_DYN_CFG),1) + +UAUD_CFG_FLAGS += -DUSB_AUDIO_DYN_CFG + +USB_AUDIO_32BIT ?= 1 +USB_AUDIO_24BIT ?= 1 +USB_AUDIO_16BIT ?= 1 + +USB_AUDIO_16K ?= 1 +USB_AUDIO_44_1K ?= 1 +USB_AUDIO_48K ?= 1 +USB_AUDIO_96K ?= 1 +ifeq ($(USB_HIGH_SPEED),1) +USB_AUDIO_176_4K ?= 1 +USB_AUDIO_192K ?= 1 +ifeq ($(USB_AUDIO_UAC2),1) +USB_AUDIO_352_8K ?= 1 +USB_AUDIO_384K ?= 1 +endif +endif + +else # USB_AUDIO_DYN_CFG != 1 + +ifeq ($(filter 1,$(USB_AUDIO_384K) $(USB_AUDIO_352_8K) $(USB_AUDIO_192K) $(USB_AUDIO_176_4K) \ + $(USB_AUDIO_96K) $(USB_AUDIO_44_1K) $(USB_AUDIO_16K)),) +USB_AUDIO_48K := 1 +endif + +ifeq ($(filter 1,$(USB_AUDIO_32BIT) $(USB_AUDIO_24BIT)),) +USB_AUDIO_16BIT := 1 +endif + +endif # USB_AUDIO_DYN_CFG != 1 + +ifeq ($(filter 1,$(USB_AUDIO_384K) $(USB_AUDIO_352_8K) $(USB_AUDIO_192K) $(USB_AUDIO_176_4K) \ + $(USB_AUDIO_96K) $(USB_AUDIO_48K) $(USB_AUDIO_44_1K) $(USB_AUDIO_16K)),) +$(error None of usb audio sample rates is enabled) +endif + +ifeq ($(USB_AUDIO_384K),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_384K +endif +ifeq ($(USB_AUDIO_352_8K),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_352_8K +endif +ifeq ($(USB_AUDIO_192K),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_192K +endif +ifeq ($(USB_AUDIO_176_4K),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_176_4K +endif +ifeq ($(USB_AUDIO_96K),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_96K +endif +ifeq ($(USB_AUDIO_48K),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_48K +endif +ifeq ($(USB_AUDIO_44_1K),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_44_1K +endif +ifeq ($(USB_AUDIO_16K),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_16K +endif + +ifeq ($(filter 1,$(USB_AUDIO_32BIT) $(USB_AUDIO_24BIT) $(USB_AUDIO_16BIT)),) +$(error None of USB_AUDIO_32BIT/USB_AUDIO_24BIT/USB_AUDIO_16BIT is enabled) +endif + +ifeq ($(USB_AUDIO_32BIT),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_32BIT +endif +ifeq ($(USB_AUDIO_24BIT),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_24BIT +endif +ifeq ($(USB_AUDIO_16BIT),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_16BIT +endif + +ifeq ($(filter 1,$(USB_AUDIO_SEND_32BIT) $(USB_AUDIO_SEND_24BIT)),) +USB_AUDIO_SEND_16BIT := 1 +ifneq ($(USB_AUDIO_SEND_16BIT),1) +$(error None of USB_AUDIO_SEND_32BIT/USB_AUDIO_SEND_24BIT/USB_AUDIO_SEND_16BIT is enabled) +endif +endif + +ifeq ($(USB_AUDIO_SEND_32BIT),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_SEND_32BIT +endif +ifeq ($(USB_AUDIO_SEND_24BIT),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_SEND_24BIT +endif +ifeq ($(USB_AUDIO_SEND_16BIT),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_SEND_16BIT +endif + +ifneq ($(USB_AUDIO_SEND_CHAN),) +UAUD_CFG_FLAGS += -DUSB_AUDIO_SEND_CHAN=$(USB_AUDIO_SEND_CHAN) +endif + +ifeq ($(USB_AUDIO_UAC2),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_UAC2 +endif + +ifeq ($(USB_AUDIO_MULTIFUNC),1) +UAUD_CFG_FLAGS += -DUSB_AUDIO_MULTIFUNC +endif + diff --git a/platform/drivers/usb/usb_host/Makefile b/platform/drivers/usb/usb_host/Makefile new file mode 100644 index 0000000..d361ecd --- /dev/null +++ b/platform/drivers/usb/usb_host/Makefile @@ -0,0 +1,20 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +src_obj := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +src_obj := $(src_obj:.c=.o) +src_obj := $(src_obj:.cpp=.o) +src_obj := $(src_obj:.S=.o) + +libusbhost-y := $(src_obj) + +obj-y := libusbhost.a + +ccflags-y := -Iplatform-Iplatform/drivers/usb/usb_host/inc -Iplatform/drivers/ana + +ifeq ($(USB_WAKEUP_OPEN),1) +CFLAGS_USBHost.o += -DUSB_WAKEUP_OPEN +endif + +ifeq ($(USB_WAKEUP_RESET),1) +CFLAGS_USBHost.o += -DUSB_WAKEUP_RESET +endif diff --git a/platform/drivers/usb/usb_host/inc/USBHost.h b/platform/drivers/usb/usb_host/inc/USBHost.h new file mode 100644 index 0000000..36b9f24 --- /dev/null +++ b/platform/drivers/usb/usb_host/inc/USBHost.h @@ -0,0 +1,193 @@ + +/* +Copyright (c) 2010 Peter Barrett + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef USBHOST_H +#define USBHOST_H + +#include "plat_types.h" + +#define ENDPOINT_CONTROL 0 +#define ENDPOINT_ISOCRONOUS 1 +#define ENDPOINT_BULK 2 +#define ENDPOINT_INTERRUPT 3 + +#define DESCRIPTOR_TYPE_DEVICE 1 +#define DESCRIPTOR_TYPE_CONFIGURATION 2 +#define DESCRIPTOR_TYPE_STRING 3 +#define DESCRIPTOR_TYPE_INTERFACE 4 +#define DESCRIPTOR_TYPE_ENDPOINT 5 + +#define DESCRIPTOR_TYPE_HID 0x21 +#define DESCRIPTOR_TYPE_REPORT 0x22 +#define DESCRIPTOR_TYPE_PHYSICAL 0x23 +#define DESCRIPTOR_TYPE_HUB 0x29 + +enum USB_CLASS_CODE +{ + CLASS_DEVICE, + CLASS_AUDIO, + CLASS_COMM_AND_CDC_CONTROL, + CLASS_HID, + CLASS_PHYSICAL = 0x05, + CLASS_STILL_IMAGING, + CLASS_PRINTER, + CLASS_MASS_STORAGE, + CLASS_HUB, + CLASS_CDC_DATA, + CLASS_SMART_CARD, + CLASS_CONTENT_SECURITY = 0x0D, + CLASS_VIDEO = 0x0E, + CLASS_DIAGNOSTIC_DEVICE = 0xDC, + CLASS_WIRELESS_CONTROLLER = 0xE0, + CLASS_MISCELLANEOUS = 0xEF, + CLASS_APP_SPECIFIC = 0xFE, + CLASS_VENDOR_SPECIFIC = 0xFF +}; + +#define DEVICE_TO_HOST 0x80 +#define HOST_TO_DEVICE 0x00 +#define REQUEST_TYPE_CLASS 0x20 +#define RECIPIENT_DEVICE 0x00 +#define RECIPIENT_INTERFACE 0x01 +#define RECIPIENT_ENDPOINT 0x02 +#define RECIPIENT_OTHER 0x03 + +#define GET_STATUS 0 +#define CLEAR_FEATURE 1 +#define SET_FEATURE 3 +#define SET_ADDRESS 5 +#define GET_DESCRIPTOR 6 +#define SET_DESCRIPTOR 7 +#define GET_CONFIGURATION 8 +#define SET_CONFIGURATION 9 +#define GET_INTERFACE 10 +#define SET_INTERFACE 11 +#define SYNCH_FRAME 11 + +// -5 is nak +/* +0010 ACK Handshake +1010 NAK Handshake +1110 STALL Handshake +0110 NYET (No Response Yet) +*/ + +#define IO_PENDING -100 +#define ERR_ENDPOINT_NONE_LEFT -101 +#define ERR_ENDPOINT_NOT_FOUND -102 +#define ERR_DEVICE_NOT_FOUND -103 +#define ERR_DEVICE_NONE_LEFT -104 +#define ERR_HUB_INIT_FAILED -105 +#define ERR_INTERFACE_NOT_FOUND -106 + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u16 bcdUSB; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize; + u16 idVendor; + u16 idProduct; + u16 bcdDevice; // version + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; +} DeviceDescriptor; // 16 bytes + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u16 wTotalLength; + u8 bNumInterfaces; + u8 bConfigurationValue; // Value to use as an argument to select this configuration + u8 iConfiguration; // Index of String Descriptor describing this configuration + u8 bmAttributes; // Bitmap D7 Reserved, set to 1. (USB 1.0 Bus Powered),D6 Self Powered,D5 Remote Wakeup,D4..0 = 0 + u8 bMaxPower; // Maximum Power Consumption in 2mA units +} ConfigurationDescriptor; + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 bInterfaceNumber; + u8 bAlternateSetting; + u8 bNumEndpoints; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + u8 iInterface; // Index of String Descriptor Describing this interface +} InterfaceDescriptor; + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 bEndpointAddress; // Bits 0:3 endpoint, Bits 7 Direction 0 = Out, 1 = In (Ignored for Control Endpoints) + u8 bmAttributes; // Bits 0:1 00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt + u16 wMaxPacketSize; + u8 bInterval; // Interval for polling endpoint data transfers. +} EndpointDescriptor; + +typedef struct { + u8 bLength; + u8 bDescriptorType; + u16 bcdHID; + u8 bCountryCode; + u8 bNumDescriptors; + u8 bDescriptorType2; + u16 wDescriptorLength; +} HIDDescriptor; + +//============================================================================ +//============================================================================ + + +void USBInit(); +void USBLoop(); +u8* USBGetBuffer(u32* len); + +// Optional callback for transfers, called at interrupt time +typedef void (*USBCallback)(int device, int endpoint, int status, u8* data, int len, void* userData); + +// Transfers +int USBControlTransfer(int device, int request_type, int request, int value, int index, u8* data, int length, USBCallback callback = 0, void* userData = 0); +int USBInterruptTransfer(int device, int ep, u8* data, int length, USBCallback callback = 0, void* userData = 0); +int USBBulkTransfer(int device, int ep, u8* data, int length, USBCallback callback = 0, void* userData = 0); + +// Standard Device methods +int GetDescriptor(int device, int descType, int descIndex, u8* data, int length); +int GetString(int device, int index, char* dst, int length); +int SetAddress(int device, int new_addr); +int SetConfiguration(int device, int configNum); +int SetInterface(int device, int ifNum, int altNum); + +// Implemented to notify app of the arrival of a device +void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc, u8 *itfDescEnd); +void OnUnloadDevice(int device); + +#endif diff --git a/platform/drivers/usb/usb_host/inc/usb_tester.h b/platform/drivers/usb/usb_host/inc/usb_tester.h new file mode 100644 index 0000000..f89d50c --- /dev/null +++ b/platform/drivers/usb/usb_host/inc/usb_tester.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef USB_TESTER_H +#define USB_TESTER_H + +#include "FATFileSystem.h" +#include + + +class USBFileSystem : public FATFileSystem +{ + +public: + USBFileSystem(); + + void SetDevice(int device); + + int GetDevice(void); + + virtual int disk_initialize(); + + virtual int disk_write(const uint8_t * buffer, uint64_t sector, uint8_t count); + + virtual int disk_read(uint8_t * buffer, uint64_t sector, uint8_t count); + + virtual uint64_t disk_sectors(); + +protected: + int _device; + u32 _blockSize; + u32 _blockCount; + +}; + + +#endif diff --git a/platform/hal/Makefile b/platform/hal/Makefile new file mode 100644 index 0000000..2f69682 --- /dev/null +++ b/platform/hal/Makefile @@ -0,0 +1,685 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(filter-out hal_mcu2cp.c, $(obj-y)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) + +obj-y += $(CHIP)/ + +subdir-ccflags-y += -Iplatform/drivers/ana + +ifneq ($(PERIPH_PLL_FREQ),) +ccflags-y += -DPERIPH_PLL_FREQ=$(PERIPH_PLL_FREQ) +endif + +ifeq ($(CHIP_CACHE_VER),) +CFLAGS_hal_cache.o += -DCHIP_CACHE_VER=1 +else +CFLAGS_hal_cache.o += -DCHIP_CACHE_VER=$(CHIP_CACHE_VER) +endif + +ifeq ($(USB_EQ_TUNING), 1) +CFLAGS_hal_cmd.o += -DUSB_EQ_TUNING +endif + +ifeq ($(PC_CMD_UART), 1) +CFLAGS_hal_cmd.o += -D__PC_CMD_UART__ +endif + +ifeq ($(USB_AUDIO_APP), 1) +CFLAGS_hal_cmd.o += -DUSB_AUDIO_APP +endif + +ifeq ($(JTAG_ENABLE),1) +CFLAGS_hal_cmu_common.o += -DJTAG_ENABLE +endif +ifeq ($(NO_LPU_26M),1) +CFLAGS_hal_cmu_common.o += -DNO_LPU_26M +endif +ifeq ($(MCU_HIGH_PERFORMANCE_MODE),1) +CFLAGS_hal_cmu_common.o += -DMCU_HIGH_PERFORMANCE_MODE +endif +ifeq ($(ULTRA_LOW_POWER),1) +CFLAGS_hal_cmu_common.o += -DULTRA_LOW_POWER +CFLAGS_hal_sysfreq.o += -DULTRA_LOW_POWER +endif + +CFLAGS_hal_dma.o += -DCHIP_HAS_DMA=$(CHIP_HAS_DMA) + +ifeq ($(CODEC_DSD),1) +CFLAGS_hal_dma.o += -DCODEC_DSD +endif +ifeq ($(BTDUMP_ENABLE),1) +CFLAGS_hal_dma.o += -DBTDUMP_ENABLE +endif + +ifeq ($(PMU_IRQ_UNIFIED),1) +CFLAGS_hal_gpadc.o += -DPMU_IRQ_UNIFIED +endif + +I2C_TASK_MODE ?= 1 +I2C_SIMPLE_MODE ?= 1 +ifeq ($(I2C_TASK_MODE),1) +CFLAGS_hal_i2c.o += -DI2C_TASK_MODE +endif +ifeq ($(I2C_SIMPLE_MODE),1) +CFLAGS_hal_i2c.o += -DI2C_SIMPLE_MODE +endif +ifeq ($(I2C_USE_DMA),1) +CFLAGS_hal_i2c.o += -DI2C_USE_DMA +endif +ifeq ($(I2C_SENSOR_ENGINE),1) +CFLAGS_hal_i2c.o += -DI2C_SENSOR_ENGINE +endif +ifneq ($(I2C_SM_TASK_NUM),) +CFLAGS_hal_i2c.o += -DI2C_SM_TASK_NUM=$(I2C_SM_TASK_NUM) +endif +ifneq ($(I2C_SM_DMA_BUF_SIZE),) +CFLAGS_hal_i2c.o += -DI2C_SM_DMA_BUF_SIZE=$(I2C_SM_DMA_BUF_SIZE) +endif +ifeq ($(I2C_VAD),1) +CFLAGS_hal_i2c.o += -DI2C_VAD +endif +ifeq ($(I2C_DEBUG),1) +CFLAGS_hal_i2c.o += -DI2C_DEBUG +endif +ifeq ($(I2S_FSP_MODE),1) +CFLAGS_hal_i2c.o += -DI2S_FSP_MODE +endif + +ifeq ($(I2S_MCLK_FROM_SPDIF),1) +CFLAGS_hal_i2s.o += -DI2S_MCLK_FROM_SPDIF +ifeq ($(I2S_MCLK_PIN),1) +CFLAGS_hal_i2s.o += -DI2S_MCLK_PIN +endif +ifneq ($(I2S_MCLK_DIV),) +CFLAGS_hal_i2s.o += -DI2S_MCLK_DIV=$(I2S_MCLK_DIV) +endif +endif + +ifeq ($(BONE_SENSOR_TDM),1) +CFLAGS_hal_i2s.o += -DI2S_MCLK_PIN +endif + +ifeq ($(CHIP_HAS_SPDIF),1) +CFLAGS_hal_i2s.o += -DCHIP_HAS_SPDIF +CFLAGS_hal_spdif.o += -DCHIP_HAS_SPDIF +endif + +ifneq ($(CHIP_HAS_I2S),) +CFLAGS_hal_i2s.o += -DCHIP_HAS_I2S=$(CHIP_HAS_I2S) +CFLAGS_hal_tdm.o += -DCHIP_HAS_I2S=$(CHIP_HAS_I2S) +endif + +ifneq ($(CHIP_HAS_TDM),) +CFLAGS_hal_tdm.o += -DCHIP_HAS_TDM=$(CHIP_HAS_TDM) +endif + +CFLAGS_hal_key.o += -Iutils/hwtimer_list + +ifeq ($(NO_PWRKEY),1) +CFLAGS_hal_key.o += -DNO_PWRKEY +endif +ifeq ($(NO_GPIOKEY),1) +CFLAGS_hal_key.o += -DNO_GPIOKEY +endif +ifeq ($(NO_ADCKEY),1) +CFLAGS_hal_key.o += -DNO_ADCKEY +endif +ifeq ($(NO_GROUPKEY),1) +CFLAGS_hal_key.o += -DNO_GROUPKEY +endif +ifeq ($(KEY_DEBUG),1) +CFLAGS_hal_key.o += -DKEY_DEBUG +endif + +ifeq ($(CHIP_HAS_EXT_PMU),1) +CFLAGS_hal_key.o += -DCHIP_HAS_EXT_PMU +endif + +ifeq ($(CHIP_HAS_CP),1) +obj-y += hal_mcu2cp_mcu.o hal_mcu2cp_cp.o + +$(obj)/hal_mcu2cp_mcu.o $(obj)/hal_mcu2cp_cp.o: $(src)/hal_mcu2cp.c FORCE + $(call if_changed_rule,cc_o_c) + +CFLAGS_hal_mcu2cp_mcu.o += -DMCU_API +CFLAGS_hal_mcu2cp_cp.o += -DCP_API +endif + +CFLAGS_hal_norflash.o += -Iplatform/drivers/norflash -Iutils/boot_struct + +CFLAGS_hal_spi_norflash.o += -Iplatform/drivers/spi_norflash -Iutils/boot_struct + +ifeq ($(FLASH_LOW_SPEED),1) +CFLAGS_hal_cmu_common.o += -DFLASH_LOW_SPEED +CFLAGS_hal_norflash.o += -DFLASH_LOW_SPEED +endif +ifeq ($(SIMU_FAST_FLASH),1) +CFLAGS_hal_norflash.o += -DSIMU_FAST_FLASH +endif +ifeq ($(FLASH_DEEP_SLEEP),1) +CFLAGS_hal_norflash.o += -DFLASH_DEEP_SLEEP +endif +ifeq ($(FLASH_UNIQUE_ID),1) +CFLAGS_hal_norflash.o += -DFLASH_UNIQUE_ID +endif +ifeq ($(FLASH_SUSPEND),1) +CFLAGS_hal_norflash.o += -DFLASH_SUSPEND +endif +ifeq ($(FLASH_SECURITY_REGISTER),1) +CFLAGS_hal_norflash.o += -DFLASH_SECURITY_REGISTER +endif +ifeq ($(FLASH_SEC_REG_FIFO_READ),1) +CFLAGS_hal_norflash.o += -DFLASH_SEC_REG_FIFO_READ +endif +ifeq ($(FLASH_SEC_REG_PP_1024),1) +CFLAGS_hal_norflash.o += -DFLASH_SEC_REG_PP_1024 +endif +ifeq ($(OSC_26M_X4_AUD2BB),1) +CFLAGS_hal_cmu_common.o += -DOSC_26M_X4_AUD2BB +CFLAGS_hal_norflash.o += -DOSC_26M_X4_AUD2BB +endif +ifneq ($(FLASH_SIZE),) +CFLAGS_hal_norflash.o += -DFLASH_SIZE=$(FLASH_SIZE) +endif +ifeq ($(OTA_BARE_BOOT),1) +CFLAGS_hal_norflash.o += -DOTA_BARE_BOOT +endif +ifeq ($(OTA_PROGRAMMER),1) +CFLAGS_hal_norflash.o += -DOTA_PROGRAMMER +endif +ifeq ($(FLASH_PROTECTION),1) +CFLAGS_hal_norflash.o += -DFLASH_PROTECTION +endif + +CFLAGS_hal_norflash.o += -DCHIP_FLASH_CTRL_VER=$(CHIP_FLASH_CTRL_VER) +CFLAGS_hal_norflaship_v1.o += -Itests/programmer/inc -DCHIP_FLASH_CTRL_VER=$(CHIP_FLASH_CTRL_VER) +CFLAGS_hal_norflaship_v2.o += -Itests/programmer/inc -DCHIP_FLASH_CTRL_VER=$(CHIP_FLASH_CTRL_VER) + +ifeq ($(PWM_TRY_SLOW_CLOCK),1) +CFLAGS_hal_pwm.o += -DPWM_TRY_SLOW_CLOCK +endif + +PSRAM_CFG_FLAGS := +ifeq ($(CHIP_HAS_PSRAM),1) +PSRAM_CFG_FLAGS += -DCHIP_HAS_PSRAM +PSRAM_CFG_FLAGS += -DPSRAM_SPEED=$(PSRAM_SPEED) +ifeq ($(PSRAM_ENABLE),1) +PSRAM_CFG_FLAGS += -DPSRAM_ENABLE +CFLAGS_hal_norflash.o += -DPSRAM_ENABLE +endif +ifeq ($(PSRAM_LOW_SPEED),1) +PSRAM_CFG_FLAGS += -DPSRAM_LOW_SPEED +endif +ifeq ($(PSRAM_DUAL_8BIT),1) +CFLAGS_hal_psram_v2.o += -DPSRAM_DUAL_8BIT +endif + +PSRAM_CFG_FLAGS += -DCHIP_PSRAM_CTRL_VER=$(CHIP_PSRAM_CTRL_VER) +CFLAGS_hal_cache.o += $(PSRAM_CFG_FLAGS) +CFLAGS_hal_cmu_common.o += $(PSRAM_CFG_FLAGS) +CFLAGS_hal_overlay.o += $(PSRAM_CFG_FLAGS) +CFLAGS_hal_psram_v1.o += $(PSRAM_CFG_FLAGS) +CFLAGS_hal_psram_v2.o += $(PSRAM_CFG_FLAGS) +endif + +PSRAMUHS_CFG_FLAGS := +ifeq ($(CHIP_HAS_PSRAMUHS),1) +PSRAMUHS_CFG_FLAGS += -DCHIP_HAS_PSRAMUHS +ifeq ($(PSRAMUHS_ENABLE),1) +PSRAMUHS_CFG_FLAGS += -DPSRAMUHS_ENABLE +CFLAGS_hal_norflash.o += -DPSRAMUHS_ENABLE +endif +ifeq ($(PSRAMUHS_DUAL_8BIT),1) +PSRAMUHS_CFG_FLAGS += -DPSRAMUHS_DUAL_8BIT +endif +ifeq ($(PSRAMUHS_DUAL_SWITCH),1) +PSRAMUHS_CFG_FLAGS += -DPSRAMUHS_DUAL_SWITCH +endif +ifeq ($(DSP_ENABLE),1) +PSRAMUHS_CFG_FLAGS += -DDSP_ENABLE +endif +ifneq ($(PSRAMUHS_SIZE),) +PSRAMUHS_CFG_FLAGS +=-DPSRAMUHS_SIZE=$(PSRAMUHS_SIZE) +CFLAGS_hal_trace.o += -DPSRAMUHS_SIZE=$(PSRAMUHS_SIZE) +endif +PSRAMUHS_CFG_FLAGS +=-DPSRAMUHS_SPEED=$(PSRAMUHS_SPEED) +CFLAGS_hal_psramuhs.o += $(PSRAMUHS_CFG_FLAGS) +CFLAGS_hal_cache.o += $(PSRAMUHS_CFG_FLAGS) +CFLAGS_hal_cmu_common.o += $(PSRAMUHS_CFG_FLAGS) +endif + +ifeq ($(CHIP_HAS_SDMMC),1) +CFLAGS_hal_sdmmc.o += -DCHIP_HAS_SDMMC +endif +ifeq ($(CHIP_HAS_SDIO),1) +CFLAGS_hal_sdio.o += -DCHIP_HAS_SDIO +endif + +SLEEP_STATS_TRACE ?= 1 +ifeq ($(SLEEP_STATS_TRACE),1) +CFLAGS_hal_sleep.o += -DSLEEP_STATS_TRACE +endif + +ifeq ($(NO_SLEEP),1) +CFLAGS_hal_sleep.o += -DNO_SLEEP +endif +ifeq ($(NO_LIGHT_SLEEP),1) +CFLAGS_hal_sleep.o += -DNO_LIGHT_SLEEP +endif +ifeq ($(DEBUG_SLEEP_USER),1) +CFLAGS_hal_sleep.o += -DDEBUG_SLEEP_USER +endif + +CFLAGS_hal_spi.o += -DCHIP_SPI_VER=$(CHIP_SPI_VER) + +ifeq ($(SPI_ROM_ONLY),1) +CFLAGS_hal_spi.o += -DSPI_ROM_ONLY +endif +ifeq ($(CHIP_HAS_SPI),1) +CFLAGS_hal_spi.o += -DCHIP_HAS_SPI +endif +ifeq ($(CHIP_HAS_SPILCD),1) +CFLAGS_hal_spi.o += -DCHIP_HAS_SPILCD +endif +ifeq ($(CHIP_HAS_SPIPHY),1) +CFLAGS_hal_phyif.o += -DCHIP_HAS_SPIPHY +CFLAGS_hal_spi.o += -DCHIP_HAS_SPIPHY +endif +ifeq ($(CHIP_HAS_SPIDPD),1) +CFLAGS_hal_spi.o += -DCHIP_HAS_SPIDPD +endif + +ifeq ($(LOW_SYS_FREQ),1) +CFLAGS_hal_timer.o += -DLOW_SYS_FREQ +endif + +ifneq ($(TRACE_BAUD_RATE),) +CFLAGS_hal_trace.o += -DTRACE_BAUD_RATE=$(TRACE_BAUD_RATE) +CFLAGS_hal_uart.o += -DTRACE_BAUD_RATE=$(TRACE_BAUD_RATE) +endif +ifneq ($(TRACE_BUF_SIZE),) +CFLAGS_hal_trace.o += -DTRACE_BUF_SIZE=$(TRACE_BUF_SIZE) +endif +ifneq ($(TRACE_STACK_DUMP_PREV_WORD),) +CFLAGS_hal_trace.o += -DTRACE_STACK_DUMP_PREV_WORD=$(TRACE_STACK_DUMP_PREV_WORD) +endif +ifneq ($(TRACE_STACK_DUMP_WORD),) +CFLAGS_hal_trace.o += -DTRACE_STACK_DUMP_WORD=$(TRACE_STACK_DUMP_WORD) +endif +ifneq ($(TRACE_BACKTRACE_NUM),) +CFLAGS_hal_trace.o += -DTRACE_BACKTRACE_NUM=$(TRACE_BACKTRACE_NUM) +endif +ifneq ($(TRACE_BACKTRACE_SEARCH_WORD),) +CFLAGS_hal_trace.o += -DTRACE_BACKTRACE_SEARCH_WORD=$(TRACE_BACKTRACE_SEARCH_WORD) +endif +ifneq ($(FLASH_SIZE),) +CFLAGS_hal_trace.o += -DFLASH_SIZE=$(FLASH_SIZE) +endif +ifneq ($(PSRAM_SIZE),) +CFLAGS_hal_trace.o += -DPSRAM_SIZE=$(PSRAM_SIZE) +CFLAGS_hal_overlay.o += -DPSRAM_SIZE=$(PSRAM_SIZE) +endif +ifeq ($(USE_TRACE_ID),1) +CFLAGS_hal_trace.o += -DUSE_TRACE_ID +endif +ifeq ($(DUMP_NORMAL_LOG),1) +CFLAGS_hal_trace.o += -DDUMP_NORMAL_LOG +endif +ifeq ($(FAULT_DUMP),1) +CFLAGS_hal_trace.o += -DFAULT_DUMP +endif +ifeq ($(CRASH_REBOOT),1) +CFLAGS_hal_trace.o += -DCRASH_REBOOT +endif +ifeq ($(FORCE_TRACE_UART1),1) +CFLAGS_hal_trace.o += -DFORCE_TRACE_UART1 +endif +ifeq ($(NO_TRACE_TIME_STAMP),1) +CFLAGS_hal_trace.o += -DNO_TRACE_TIME_STAMP +endif + +ifeq ($(TRACE_CRLF),1) +CFLAGS_hal_trace.o += -DTRACE_CRLF +CFLAGS_hal_uart.o += -DTRACE_CRLF +endif + +ifeq ($(CORE_DUMP),1) +CFLAGS_hal_trace.o += -Iutils/crash_catcher/include -DCORE_DUMP +endif + +ifneq ($(UART_FREQ),) +CFLAGS_hal_uart.o += -DUART_FREQ=$(UART_FREQ) +endif +ifneq ($(DEBUG_PORT),) +CFLAGS_hal_uart.o += -DDEBUG_PORT=$(DEBUG_PORT) +endif + +CFLAGS_hal_usb.o += -Iplatform/drivers/usb/usb_dev/inc -Iutils/hwtimer_list + +ifeq ($(USB_ISO),1) +CFLAGS_hal_usb.o += -DUSB_ISO +endif + +ifneq ($(ROM_BUILD),1) +ifneq ($(PROGRAMMER),1) +USB_SUSPEND ?= 1 +PMU_USB_PIN_CHECK ?= 1 +endif +endif +ifeq ($(USB_SUSPEND),1) +CFLAGS_hal_usb.o += -DUSB_SUSPEND +endif +ifeq ($(PMU_USB_PIN_CHECK),1) +CFLAGS_hal_usb.o += -DPMU_USB_PIN_CHECK +CFLAGS_hal_usbhost.o += -DPMU_USB_PIN_CHECK +endif + +ifeq ($(USB_HIGH_SPEED),1) +CFLAGS_hal_usb.o += -DUSB_HIGH_SPEED +CFLAGS_hal_usbhost.o += -DUSB_HIGH_SPEED +endif + +ifeq ($(USB_LPM),1) +CFLAGS_hal_usb.o += -DUSB_LPM +endif + +ifeq ($(CHIP_HAS_USBPHY),1) +CFLAGS_hal_usb.o += -DCHIP_HAS_USBPHY +endif + +ifeq ($(SIMU_UAUD_MAX_PKT),1) +CFLAGS_hal_usb.o += -DSIMU_UAUD_MAX_PKT +endif + +CFLAGS_hal_usbhost.o += -Iutils/hwtimer_list + +# CMU settings +export CMU_CFG_FLAGS := + +CMU_CFG_FLAGS += $(PSRAM_CFG_FLAGS) $(PSRAMUHS_CFG_FLAGS) + +ifeq ($(AUDIO_RESAMPLE),1) +CMU_CFG_FLAGS += -D__AUDIO_RESAMPLE__ +endif + +ifeq ($(FLASH_LOW_SPEED),1) +CMU_CFG_FLAGS += -DFLASH_LOW_SPEED +endif + +ifeq ($(USB_HIGH_SPEED),1) +CMU_CFG_FLAGS += -DUSB_HIGH_SPEED +endif + +ifeq ($(ANA_26M_X4_ENABLE),1) +CMU_CFG_FLAGS += -DANA_26M_X4_ENABLE +endif + +ifeq ($(OSC_26M_X4_AUD2BB),1) +CMU_CFG_FLAGS += -DOSC_26M_X4_AUD2BB +endif + +ifeq ($(DIG_OSC_X2_ENABLE),1) +CMU_CFG_FLAGS += -DDIG_OSC_X2_ENABLE +endif + +ifeq ($(DIG_OSC_X4_ENABLE),1) +CMU_CFG_FLAGS += -DDIG_OSC_X4_ENABLE +endif + +ifeq ($(MCU_HIGH_PERFORMANCE_MODE),1) +CMU_CFG_FLAGS += -DMCU_HIGH_PERFORMANCE_MODE +endif + +ifeq ($(LOW_SYS_FREQ),1) +CMU_CFG_FLAGS += -DLOW_SYS_FREQ +endif + +ifeq ($(BTDUMP_ENABLE),1) +CMU_CFG_FLAGS += -DBTDUMP_ENABLE +endif + +ifeq ($(CODEC_DSD),1) +CMU_CFG_FLAGS += -DCODEC_DSD +endif + +ifeq ($(CHIP_HAS_DCO),1) +CMU_CFG_FLAGS += -DCHIP_HAS_DCO +endif + +# ANAIF settings +export ANAIF_CFG_FLAGS := + +ISPI_ARBITRATOR_ENABLE ?= 1 +ifeq ($(ISPI_ARBITRATOR_ENABLE),1) +ANAIF_CFG_FLAGS += -DISPI_ARBITRATOR_ENABLE +endif + +# PSC settings +export PSC_CFG_FLAGS := + +# CODEC settings +export CODEC_CFG_FLAGS := + +CODEC_CFG_FLAGS += $(MAX_DAC_OUTPUT_FLAGS) + +ifeq ($(AUDIO_RESAMPLE),1) +CODEC_CFG_FLAGS += -D__AUDIO_RESAMPLE__ +endif + +ifeq ($(SINGLE_CODEC_DAC_VOL),1) +CODEC_CFG_FLAGS += -DSINGLE_CODEC_DAC_VOL +endif + +ifeq ($(SINGLE_CODEC_ADC_VOL),1) +CODEC_CFG_FLAGS += -DSINGLE_CODEC_ADC_VOL +endif + +FIXED_CODEC_ADC_VOL ?= 1 +ifeq ($(FIXED_CODEC_ADC_VOL),1) +CODEC_CFG_FLAGS += -DFIXED_CODEC_ADC_VOL +endif + +ifeq ($(ANC_APP),1) +CODEC_CFG_FLAGS += -DANC_APP +endif + +ifeq ($(AUDIO_OUTPUT_SW_GAIN),1) +CODEC_CFG_FLAGS += -DAUDIO_OUTPUT_SW_GAIN +endif + +ifeq ($(AUDIO_OUTPUT_DC_CALIB),1) +CODEC_CFG_FLAGS += -DAUDIO_OUTPUT_DC_CALIB +endif +ifeq ($(AUDIO_OUTPUT_DC_CALIB_ANA),1) +CODEC_CFG_FLAGS += -DAUDIO_OUTPUT_DC_CALIB_ANA +endif + +ifeq ($(AUDIO_OUTPUT_SWAP),1) +CODEC_CFG_FLAGS += -DAUDIO_OUTPUT_SWAP +endif + +ifeq ($(NOISE_GATING),1) +CODEC_CFG_FLAGS += -DNOISE_GATING +endif + +ifeq ($(NOISE_REDUCTION),1) +CODEC_CFG_FLAGS += -DNOISE_REDUCTION +endif + +ifeq ($(ADC_DC_FILTER),1) +CODEC_CFG_FLAGS += -DADC_DC_FILTER +endif + +ifeq ($(CODEC_DSD),1) +CODEC_CFG_FLAGS += -DCODEC_DSD +endif + +ifeq ($(I2C_VAD),1) +CODEC_CFG_FLAGS += -DI2C_VAD +endif + +# IOMUX settings +export IOMUX_CFG_FLAGS := + +ifeq ($(IOMUX_DEFAULT_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DIOMUX_DEFAULT_VOLTAGE_VMEM +endif + +ifneq ($(I2S_MCLK_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DI2S_MCLK_IOMUX_INDEX=$(I2S_MCLK_IOMUX_INDEX) +endif + +ifeq ($(I2S0_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DI2S0_VOLTAGE_VMEM +endif + +ifneq ($(I2S0_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DI2S0_IOMUX_INDEX=$(I2S0_IOMUX_INDEX) +endif + +ifeq ($(I2S1_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DI2S1_VOLTAGE_VMEM +endif + +ifneq ($(I2S1_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DI2S1_IOMUX_INDEX=$(I2S1_IOMUX_INDEX) +endif + +ifeq ($(SPDIF0_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DSPDIF0_VOLTAGE_VMEM +endif + +ifneq ($(SPDIF0_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DSPDIF0_IOMUX_INDEX=$(SPDIF0_IOMUX_INDEX) +endif + +ifeq ($(SPDIF1_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DSPDIF1_VOLTAGE_VMEM +endif + +ifneq ($(SPDIF1_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DSPDIF1_IOMUX_INDEX=$(SPDIF1_IOMUX_INDEX) +endif + +ifeq ($(DIGMIC_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DDIGMIC_VOLTAGE_VMEM +endif + +ifeq ($(SPI_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DSPI_VOLTAGE_VMEM +endif + +ifeq ($(SPI_IOMUX_4WIRE),1) +IOMUX_CFG_FLAGS += -DSPI_IOMUX_4WIRE + +ifneq ($(SPI_IOMUX_DI1_INDEX),) +IOMUX_CFG_FLAGS += -DSPI_IOMUX_DI1_INDEX=$(SPI_IOMUX_DI1_INDEX) +endif + +ifneq ($(SPI_IOMUX_DI2_INDEX),) +IOMUX_CFG_FLAGS += -DSPI_IOMUX_DI2_INDEX=$(SPI_IOMUX_DI2_INDEX) +endif + +ifneq ($(SPI_IOMUX_DI3_INDEX),) +IOMUX_CFG_FLAGS += -DSPI_IOMUX_DI3_INDEX=$(SPI_IOMUX_DI3_INDEX) +endif +endif + +ifneq ($(SPI_IOMUX_CS1_INDEX),) +IOMUX_CFG_FLAGS += -DSPI_IOMUX_CS1_INDEX=$(SPI_IOMUX_CS1_INDEX) +endif + +ifneq ($(SPI_IOMUX_CS2_INDEX),) +IOMUX_CFG_FLAGS += -DSPI_IOMUX_CS2_INDEX=$(SPI_IOMUX_CS2_INDEX) +endif + +ifneq ($(SPI_IOMUX_CS3_INDEX),) +IOMUX_CFG_FLAGS += -DSPI_IOMUX_CS3_INDEX=$(SPI_IOMUX_CS3_INDEX) +endif + +ifneq ($(SPI_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DSPI_IOMUX_INDEX=$(SPI_IOMUX_INDEX) +endif + +ifeq ($(SPILCD_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DSPILCD_VOLTAGE_VMEM +endif + +ifeq ($(SPILCD_IOMUX_4WIRE),1) +IOMUX_CFG_FLAGS += -DSPILCD_IOMUX_4WIRE + +ifneq ($(SPILCD_IOMUX_DI1_INDEX),) +IOMUX_CFG_FLAGS += -DSPILCD_IOMUX_DI1_INDEX=$(SPILCD_IOMUX_DI1_INDEX) +endif + +ifneq ($(SPILCD_IOMUX_DI2_INDEX),) +IOMUX_CFG_FLAGS += -DSPILCD_IOMUX_DI2_INDEX=$(SPILCD_IOMUX_DI2_INDEX) +endif + +ifneq ($(SPILCD_IOMUX_DI3_INDEX),) +IOMUX_CFG_FLAGS += -DSPILCD_IOMUX_DI3_INDEX=$(SPILCD_IOMUX_DI3_INDEX) +endif +endif + +ifneq ($(SPILCD_IOMUX_CS1_INDEX),) +IOMUX_CFG_FLAGS += -DSPILCD_IOMUX_CS1_INDEX=$(SPILCD_IOMUX_CS1_INDEX) +endif + +ifneq ($(SPILCD_IOMUX_CS2_INDEX),) +IOMUX_CFG_FLAGS += -DSPILCD_IOMUX_CS2_INDEX=$(SPILCD_IOMUX_CS2_INDEX) +endif + +ifneq ($(SPILCD_IOMUX_CS3_INDEX),) +IOMUX_CFG_FLAGS += -DSPILCD_IOMUX_CS3_INDEX=$(SPILCD_IOMUX_CS3_INDEX) +endif + +ifneq ($(SPILCD_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DSPILCD_IOMUX_INDEX=$(SPILCD_IOMUX_INDEX) +endif + +ifeq ($(I2C0_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DI2C0_VOLTAGE_VMEM +endif + +ifneq ($(I2C0_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DI2C0_IOMUX_INDEX=$(I2C0_IOMUX_INDEX) +endif + +ifeq ($(I2C1_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DI2C1_VOLTAGE_VMEM +endif + +ifneq ($(I2C1_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DI2C1_IOMUX_INDEX=$(I2C1_IOMUX_INDEX) +endif + +ifeq ($(CLKOUT_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DCLKOUT_VOLTAGE_VMEM +endif + +ifneq ($(CLKOUT_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DCLKOUT_IOMUX_INDEX=$(CLKOUT_IOMUX_INDEX) +endif + +ifeq ($(CLK12M_VOLTAGE_VMEM),1) +IOMUX_CFG_FLAGS += -DCLK12M_VOLTAGE_VMEM +endif + +ifneq ($(CLK12M_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DCLK12M_IOMUX_INDEX=$(CLK12M_IOMUX_INDEX) +endif + +ifneq ($(MCU_CLKOUT_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DMCU_CLKOUT_IOMUX_INDEX=$(MCU_CLKOUT_IOMUX_INDEX) +endif + +ifneq ($(BT_CLKOUT_IOMUX_INDEX),) +IOMUX_CFG_FLAGS += -DBT_CLKOUT_IOMUX_INDEX=$(BT_CLKOUT_IOMUX_INDEX) +endif + +ifeq ($(BONE_SENSOR_TDM),1) +IOMUX_CFG_FLAGS += -DI2S_MCLK_IOMUX_INDEX=13 +endif diff --git a/platform/hal/best2300p/Makefile b/platform/hal/best2300p/Makefile new file mode 100644 index 0000000..3be2b79 --- /dev/null +++ b/platform/hal/best2300p/Makefile @@ -0,0 +1,78 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj-y := $(obj-y:.c=.o) + +ifeq ($(MCU_HIGH_PERFORMANCE_MODE),1) +ifneq ($(FLASH_LOW_SPEED),1) +ifneq ($(OSC_26M_X4_AUD2BB),1) +$(error FLASH_LOW_SPEED should be used with MCU_HIGH_PERFORMANCE_MODE when OSC_26M_X4_AUD2BB is NOT enabled on $(CHIP)) +endif +endif +endif + +ifeq ($(USB_USE_USBPLL),1) +CMU_CFG_FLAGS += -DUSB_USE_USBPLL +endif + +ifeq ($(USB_CLK_SRC_24M_X2),1) +CMU_CFG_FLAGS += -DUSB_CLK_SRC_24M_X2 +else +ifeq ($(USB_CLK_SRC_48M),1) +CMU_CFG_FLAGS += -DUSB_CLK_SRC_48M +else +ifeq ($(USB_CLK_SRC_26M_X4),1) +CMU_CFG_FLAGS += -DUSB_CLK_SRC_26M_X4 +else +ifeq ($(USB_CLK_SRC_26M_X2),1) +CMU_CFG_FLAGS += -DUSB_CLK_SRC_26M_X2 +endif +endif +endif +endif + +ifeq ($(RESAMPLE_CODEC_CLK_ANA),1) +CMU_CFG_FLAGS += -DRESAMPLE_CODEC_CLK_ANA +endif + +ifeq ($(LOW_SYS_FREQ),1) +ifneq ($(FLASH_LOW_SPEED),1) +$(error FLASH_LOW_SPEED should be enabled along with LOW_SYS_FREQ) +endif +endif + +ifeq ($(DAC_CLASSG_ENABLE),1) +CODEC_CFG_FLAGS += -DDAC_CLASSG_ENABLE +endif + +ifeq ($(DAC_DRE_ENABLE),1) +CODEC_CFG_FLAGS += -DDAC_DRE_ENABLE +endif + +ifeq ($(JTAG_BT),1) +PSC_CFG_FLAGS += -DJTAG_BT +JTAG_TDI_TDO_PIN ?= 1 +endif + +ifeq ($(JTAG_TDI_TDO_PIN),1) +IOMUX_CFG_FLAGS += -DJTAG_TDI_TDO_PIN +endif + +ifeq ($(JTAG_RESET_PIN),1) +IOMUX_CFG_FLAGS += -DJTAG_RESET_PIN +endif + +ifeq ($(USE_CYBERON),1) +ANAIF_CFG_FLAGS += -DUSE_CYBERON +endif + +CFLAGS_hal_analogif_$(CHIP).o += $(ANAIF_CFG_FLAGS) + +CFLAGS_hal_cmu_$(CHIP).o += $(CMU_CFG_FLAGS) + +CFLAGS_hal_psc_$(CHIP).o += $(PSC_CFG_FLAGS) + +CFLAGS_hal_codec_$(CHIP).o += $(CODEC_CFG_FLAGS) + +CFLAGS_hal_iomux_$(CHIP).o += $(IOMUX_CFG_FLAGS) + diff --git a/platform/hal/best2300p/hal_analogif_best2300p.c b/platform/hal/best2300p/hal_analogif_best2300p.c new file mode 100644 index 0000000..1cf487e --- /dev/null +++ b/platform/hal/best2300p/hal_analogif_best2300p.c @@ -0,0 +1,211 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "cmsis.h" +#include "hal_analogif.h" +#include "hal_location.h" +#include "hal_spi.h" + +#define ANA_REG_CHIP_ID 0x00 + +#define ANA_CHIP_ID_SHIFT (4) +#define ANA_CHIP_ID_MASK (0xFFF << ANA_CHIP_ID_SHIFT) +#define ANA_CHIP_ID(n) BITFIELD_VAL(ANA_CHIP_ID, n) +#define ANA_VAL_CHIP_ID 0x18E + +// ISPI_ARBITRATOR_ENABLE should be defined when: +// 1) BT and MCU will access RF register at the same time; or +// 2) BT can access PMU/ANA, and BT will access RF register at the same time +// when MCU is accessing PMU/ANA register + +#ifdef ISPI_ARBITRATOR_ENABLE +// Min padding OSC cycles needed: BT=0 MCU=6 +// When OSC=26M and SPI=6.5M, min padding SPI cycles is BT=0 MCU=2 +#define PADDING_CYCLES 2 +#else +#define PADDING_CYCLES 0 +#endif + +#define ANA_READ_CMD(r) (((1 << 24) | (((r) & 0xFF) << 16)) << PADDING_CYCLES) +#define ANA_WRITE_CMD(r, v) (((((r) & 0xFF) << 16) | ((v) & 0xFFFF)) << PADDING_CYCLES) +#define ANA_READ_VAL(v) (((v) >> PADDING_CYCLES) & 0xFFFF) + +#define ANA_PAGE_1 0xA010 +#define ANA_PAGE_0 0xA000 + +static const BOOT_RODATA_SRAM_LOC uint8_t page_reg[3] = { + 0x00, 0x60, 0x80, +}; + +static const BOOT_RODATA_FLASH_LOC struct HAL_SPI_CFG_T spi_cfg = { + .clk_delay_half = false, + .clk_polarity = false, + .slave = false, + .dma_rx = false, + .dma_tx = false, + .rx_sep_line = false, + .cs = 0, + .rate = 6500000, + .tx_bits = 25 + PADDING_CYCLES, + .rx_bits = 25 + PADDING_CYCLES, + .rx_frame_bits = 0, +}; + +static bool BOOT_BSS_LOC analogif_inited = false; + +static int BOOT_TEXT_SRAM_LOC hal_analogif_rawread(unsigned short reg, unsigned short *val) +{ + int ret; + unsigned int data; + unsigned int cmd; + + data = 0; + cmd = ANA_READ_CMD(reg); + ret = hal_ispi_recv(&cmd, &data, 4); + if (ret) { + return ret; + } + *val = ANA_READ_VAL(data); + return 0; +} + +static int BOOT_TEXT_SRAM_LOC hal_analogif_rawwrite(unsigned short reg, unsigned short val) +{ + int ret; + unsigned int cmd; + + cmd = ANA_WRITE_CMD(reg, val); + ret = hal_ispi_send(&cmd, 4); + if (ret) { + return ret; + } + return 0; +} + +int BOOT_TEXT_SRAM_LOC hal_analogif_reg_read(unsigned short reg, unsigned short *val) +{ + uint32_t lock; + uint32_t idx; + int ret; + +#if defined(USE_CYBERON) +extern int cyb_efuse_check_status(void); + + if (cyb_efuse_check_status()) { + if (reg == 0x5e) { + *val = 49185; + return 0; + } + if (reg == 0x00) { + *val = 0x20e0; + return 0; + } + } +#endif + + if (reg < 0x100) { + lock = int_lock(); + ret = hal_analogif_rawread(reg, val); + int_unlock(lock); + return ret; + } else if (reg >= 0x100 && reg <= 0x15F) { + idx = 0; + } else if (reg >= 0x160 && reg <= 0x17F) { + idx = 1; + } else if (reg >= 0x180 && reg <= 0x1FF) { + idx = 2; + } else { + return -1; + } + + reg &= 0xFF; + + lock = int_lock(); + hal_analogif_rawwrite(page_reg[idx], ANA_PAGE_1); + ret = hal_analogif_rawread(reg, val); + hal_analogif_rawwrite(page_reg[idx], ANA_PAGE_0); + int_unlock(lock); + + return ret; +} + +int BOOT_TEXT_SRAM_LOC hal_analogif_reg_write(unsigned short reg, unsigned short val) +{ + uint32_t lock; + uint32_t idx; + int ret; + + if (reg < 0x100) { + lock = int_lock(); + ret = hal_analogif_rawwrite(reg, val); + int_unlock(lock); + return ret; + } else if (reg >= 0x100 && reg <= 0x15F) { + idx = 0; + } else if (reg >= 0x160 && reg <= 0x17F) { + idx = 1; + } else if (reg >= 0x180 && reg <= 0x1FF) { + idx = 2; + } else { + return -1; + } + + reg &= 0xFF; + + lock = int_lock(); + hal_analogif_rawwrite(page_reg[idx], ANA_PAGE_1); + ret = hal_analogif_rawwrite(reg, val); + hal_analogif_rawwrite(page_reg[idx], ANA_PAGE_0); + int_unlock(lock); + + return ret; +} + +int BOOT_TEXT_FLASH_LOC hal_analogif_open(void) +{ + int ret; + unsigned short chip_id; + const struct HAL_SPI_CFG_T *cfg_ptr; + struct HAL_SPI_CFG_T cfg; + + if (analogif_inited) { + // Restore the nominal rate + cfg_ptr = &spi_cfg; + } else { + analogif_inited = true; + // Crystal freq is unknown yet. Let SPI run on half of the nominal rate + cfg = spi_cfg; + cfg.rate /= 2; + cfg_ptr = &cfg; + } + + ret = hal_ispi_open(cfg_ptr); + if (ret) { + return ret; + } + + ret = hal_analogif_rawread(ANA_REG_CHIP_ID, &chip_id); + if (ret) { + return ret; + } + + if (GET_BITFIELD(chip_id, ANA_CHIP_ID) != ANA_VAL_CHIP_ID) { + return -1; + } + + return 0; +} + diff --git a/platform/hal/best2300p/hal_cmu_best2300p.c b/platform/hal/best2300p/hal_cmu_best2300p.c new file mode 100644 index 0000000..e66451c --- /dev/null +++ b/platform/hal/best2300p/hal_cmu_best2300p.c @@ -0,0 +1,2784 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include CHIP_SPECIFIC_HDR(reg_cmu) +#include CHIP_SPECIFIC_HDR(reg_aoncmu) +#include CHIP_SPECIFIC_HDR(reg_btcmu) +#include "hal_cmu.h" +#include "hal_aud.h" +#include "hal_bootmode.h" +#include "hal_chipid.h" +#include "hal_codec.h" +#include "hal_location.h" +#include "hal_psc.h" +#include "hal_sleep_core_pd.h" +#include "hal_sysfreq.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "cmsis_nvic.h" +#include "pmu.h" +#include "system_cp.h" + +#ifdef USB_HIGH_SPEED +#ifndef USB_USE_USBPLL +#define USB_USE_USBPLL +#endif +#endif + +#define CODEC_CLK_FROM_ANA + +#define HAL_CMU_USB_PLL_CLOCK (192 * 1000 * 1000) +#define HAL_CMU_AUD_PLL_CLOCK (CODEC_FREQ_48K_SERIES * CODEC_CMU_DIV) + +#define HAL_CMU_USB_CLOCK_60M (60 * 1000 * 1000) +#define HAL_CMU_USB_CLOCK_48M (48 * 1000 * 1000) + +#define HAL_CMU_PLL_LOCKED_TIMEOUT US_TO_TICKS(200) +#define HAL_CMU_26M_READY_TIMEOUT MS_TO_TICKS(4) +#define HAL_CMU_LPU_EXTRA_TIMEOUT MS_TO_TICKS(1) + +#ifdef CORE_SLEEP_POWER_DOWN +#define TIMER1_SEL_LOC BOOT_TEXT_SRAM_LOC +#else +#define TIMER1_SEL_LOC BOOT_TEXT_FLASH_LOC +#endif + +enum CMU_USB_CLK_SRC_T { + CMU_USB_CLK_SRC_PLL_60M = 0, + CMU_USB_CLK_SRC_PLL_60M_ALT = 1, + CMU_USB_CLK_SRC_PLL_48M = 2, + CMU_USB_CLK_SRC_TS = 3, + CMU_USB_CLK_SRC_OSC_48M = 4, + CMU_USB_CLK_SRC_OSC_24M_X2 = 5, + CMU_USB_CLK_SRC_OSC_26M_X4 = 6, + CMU_USB_CLK_SRC_OSC_26M_X2 = 7, +}; + +enum CMU_AUD_26M_X4_USER_T { + CMU_AUD_26M_X4_USER_IIR, + CMU_AUD_26M_X4_USER_RS, + + CMU_AUD_26M_X4_USER_QTY, +}; + +enum CMU_DEBUG_REG_SEL_T { + CMU_DEBUG_REG_SEL_MCU_PC = 0, + CMU_DEBUG_REG_SEL_MCU_LR = 1, + CMU_DEBUG_REG_SEL_MCU_SP = 2, + CMU_DEBUG_REG_SEL_CP_PC = 3, + CMU_DEBUG_REG_SEL_CP_LR = 4, + CMU_DEBUG_REG_SEL_CP_SP = 5, + CMU_DEBUG_REG_SEL_DEBUG = 7, +}; + +struct CP_STARTUP_CFG_T { + __IO uint32_t stack; + __IO uint32_t reset_hdlr; + __IO uint32_t entry; +}; + +static struct CMU_T * const cmu = (struct CMU_T *)CMU_BASE; + +static struct AONCMU_T * const aoncmu = (struct AONCMU_T *)AON_CMU_BASE; + +static struct BTCMU_T * const POSSIBLY_UNUSED btcmu = (struct BTCMU_T *)BT_CMU_BASE; + +static struct CP_STARTUP_CFG_T * const cp_cfg = (struct CP_STARTUP_CFG_T *)0x200F7FE0; + +#define HAL_CMU_PLL_USB_HS HAL_CMU_PLL_QTY +#ifdef USB_USE_USBPLL +#define PLL_USER_MAP_NUM (HAL_CMU_PLL_QTY + 1) +#else +#define PLL_USER_MAP_NUM HAL_CMU_PLL_QTY +#endif +static uint8_t BOOT_BSS_LOC pll_user_map[PLL_USER_MAP_NUM]; +STATIC_ASSERT(HAL_CMU_PLL_USER_QTY <= sizeof(pll_user_map[0]) * 8, "Too many PLL users"); + +#ifdef ROM_BUILD +static enum HAL_CMU_USB_CLOCK_SEL_T usb_clk_sel; +#endif + +static bool anc_enabled; + +#ifdef __AUDIO_RESAMPLE__ +static bool aud_resample_en = true; +#ifdef ANA_26M_X4_ENABLE +static uint8_t aud_26m_x4_map; +STATIC_ASSERT(CMU_AUD_26M_X4_USER_QTY <= sizeof(aud_26m_x4_map) * 8, "Too many aud_26m_x4 users"); +#endif +#endif + +#ifdef LOW_SYS_FREQ +static enum HAL_CMU_LOW_SYS_FREQ_T BOOT_BSS_LOC low_sys_freq; +static bool BOOT_BSS_LOC low_sys_freq_en; +#endif + +void hal_cmu_audio_resample_enable(void) +{ +#ifdef __AUDIO_RESAMPLE__ + aud_resample_en = true; +#endif +} + +void hal_cmu_audio_resample_disable(void) +{ +#ifdef __AUDIO_RESAMPLE__ + aud_resample_en = false; +#endif +} + +int hal_cmu_get_audio_resample_status(void) +{ +#ifdef __AUDIO_RESAMPLE__ + return aud_resample_en; +#else + return false; +#endif +} + +static inline void aocmu_reg_update_wait(void) +{ + // Make sure AOCMU (26M clock domain) write opertions finish before return + aoncmu->CHIP_ID; +} + +int hal_cmu_clock_enable(enum HAL_CMU_MOD_ID_T id) +{ + if (id >= HAL_CMU_AON_MCU) { + return 1; + } + + if (id < HAL_CMU_MOD_P_CMU) { + cmu->HCLK_ENABLE = (1 << id); + } else if (id < HAL_CMU_MOD_O_SLEEP) { + cmu->PCLK_ENABLE = (1 << (id - HAL_CMU_MOD_P_CMU)); + } else if (id < HAL_CMU_AON_A_CMU) { + cmu->OCLK_ENABLE = (1 << (id - HAL_CMU_MOD_O_SLEEP)); + } else { + aoncmu->MOD_CLK_ENABLE = (1 << (id - HAL_CMU_AON_A_CMU)); + aocmu_reg_update_wait(); + } + + return 0; +} + +int hal_cmu_clock_disable(enum HAL_CMU_MOD_ID_T id) +{ + if (id >= HAL_CMU_AON_MCU) { + return 1; + } + + if (id < HAL_CMU_MOD_P_CMU) { + cmu->HCLK_DISABLE = (1 << id); + } else if (id < HAL_CMU_MOD_O_SLEEP) { + cmu->PCLK_DISABLE = (1 << (id - HAL_CMU_MOD_P_CMU)); + } else if (id < HAL_CMU_AON_A_CMU) { + cmu->OCLK_DISABLE = (1 << (id - HAL_CMU_MOD_O_SLEEP)); + } else { + aoncmu->MOD_CLK_DISABLE = (1 << (id - HAL_CMU_AON_A_CMU)); + } + + return 0; +} + +enum HAL_CMU_CLK_STATUS_T hal_cmu_clock_get_status(enum HAL_CMU_MOD_ID_T id) +{ + uint32_t status; + + if (id >= HAL_CMU_AON_MCU) { + return HAL_CMU_CLK_DISABLED; + } + + if (id < HAL_CMU_MOD_P_CMU) { + status = cmu->HCLK_ENABLE & (1 << id); + } else if (id < HAL_CMU_MOD_O_SLEEP) { + status = cmu->PCLK_ENABLE & (1 << (id - HAL_CMU_MOD_P_CMU)); + } else if (id < HAL_CMU_AON_A_CMU) { + status = cmu->OCLK_ENABLE & (1 << (id - HAL_CMU_MOD_O_SLEEP)); + } else { + status = aoncmu->MOD_CLK_ENABLE & (1 << (id - HAL_CMU_AON_A_CMU)); + } + + return status ? HAL_CMU_CLK_ENABLED : HAL_CMU_CLK_DISABLED; +} + +int hal_cmu_clock_set_mode(enum HAL_CMU_MOD_ID_T id, enum HAL_CMU_CLK_MODE_T mode) +{ + __IO uint32_t *reg; + uint32_t val; + uint32_t lock; + + if (id >= HAL_CMU_AON_MCU) { + return 1; + } + + if (id < HAL_CMU_MOD_P_CMU) { + reg = &cmu->HCLK_MODE; + val = (1 << id); + } else if (id < HAL_CMU_MOD_O_SLEEP) { + reg = &cmu->PCLK_MODE; + val = (1 << (id - HAL_CMU_MOD_P_CMU)); + } else if (id < HAL_CMU_AON_A_CMU) { + reg = &cmu->OCLK_MODE; + val = (1 << (id - HAL_CMU_MOD_O_SLEEP)); + } else { + reg = &aoncmu->MOD_CLK_MODE; + val = (1 << (id - HAL_CMU_AON_A_CMU)); + } + + lock = int_lock(); + if (mode == HAL_CMU_CLK_MANUAL) { + *reg |= val; + } else { + *reg &= ~val; + } + int_unlock(lock); + + return 0; +} + +enum HAL_CMU_CLK_MODE_T hal_cmu_clock_get_mode(enum HAL_CMU_MOD_ID_T id) +{ + uint32_t mode; + + if (id >= HAL_CMU_AON_MCU) { + return HAL_CMU_CLK_AUTO; + } + + if (id < HAL_CMU_MOD_P_CMU) { + mode = cmu->HCLK_MODE & (1 << id); + } else if (id < HAL_CMU_MOD_O_SLEEP) { + mode = cmu->PCLK_MODE & (1 << (id - HAL_CMU_MOD_P_CMU)); + } else if (id < HAL_CMU_AON_A_CMU) { + mode = cmu->OCLK_MODE & (1 << (id - HAL_CMU_MOD_O_SLEEP)); + } else { + mode = aoncmu->MOD_CLK_MODE & (1 << (id - HAL_CMU_AON_A_CMU)); + } + + return mode ? HAL_CMU_CLK_MANUAL : HAL_CMU_CLK_AUTO; +} + +int hal_cmu_reset_set(enum HAL_CMU_MOD_ID_T id) +{ + if (id >= HAL_CMU_MOD_QTY) { + return 1; + } + + if (id < HAL_CMU_MOD_P_CMU) { + cmu->HRESET_SET = (1 << id); + } else if (id < HAL_CMU_MOD_O_SLEEP) { + cmu->PRESET_SET = (1 << (id - HAL_CMU_MOD_P_CMU)); + } else if (id < HAL_CMU_AON_A_CMU) { + cmu->ORESET_SET = (1 << (id - HAL_CMU_MOD_O_SLEEP)); + } else { + aoncmu->RESET_SET = (1 << (id - HAL_CMU_AON_A_CMU)); + } + + return 0; +} + +int hal_cmu_reset_clear(enum HAL_CMU_MOD_ID_T id) +{ + if (id >= HAL_CMU_MOD_QTY) { + return 1; + } + + if (id < HAL_CMU_MOD_P_CMU) { + cmu->HRESET_CLR = (1 << id); + asm volatile("nop; nop;"); + } else if (id < HAL_CMU_MOD_O_SLEEP) { + cmu->PRESET_CLR = (1 << (id - HAL_CMU_MOD_P_CMU)); + asm volatile("nop; nop; nop; nop;"); + } else if (id < HAL_CMU_AON_A_CMU) { + cmu->ORESET_CLR = (1 << (id - HAL_CMU_MOD_O_SLEEP)); + } else { + aoncmu->RESET_CLR = (1 << (id - HAL_CMU_AON_A_CMU)); + aocmu_reg_update_wait(); + } + + return 0; +} + +enum HAL_CMU_RST_STATUS_T hal_cmu_reset_get_status(enum HAL_CMU_MOD_ID_T id) +{ + uint32_t status; + + if (id >= HAL_CMU_MOD_QTY) { + return HAL_CMU_RST_SET; + } + + if (id < HAL_CMU_MOD_P_CMU) { + status = cmu->HRESET_SET & (1 << id); + } else if (id < HAL_CMU_MOD_O_SLEEP) { + status = cmu->PRESET_SET & (1 << (id - HAL_CMU_MOD_P_CMU)); + } else if (id < HAL_CMU_AON_A_CMU) { + status = cmu->ORESET_SET & (1 << (id - HAL_CMU_MOD_O_SLEEP)); + } else { + status = aoncmu->RESET_SET & (1 << (id - HAL_CMU_AON_A_CMU)); + } + + return status ? HAL_CMU_RST_CLR : HAL_CMU_RST_SET; +} + +int hal_cmu_reset_pulse(enum HAL_CMU_MOD_ID_T id) +{ + volatile int i; + + if (id >= HAL_CMU_MOD_QTY) { + return 1; + } + + if (hal_cmu_reset_get_status(id) == HAL_CMU_RST_SET) { + return hal_cmu_reset_clear(id); + } + + if (id < HAL_CMU_MOD_P_CMU) { + cmu->HRESET_PULSE = (1 << id); + } else if (id < HAL_CMU_MOD_O_SLEEP) { + cmu->PRESET_PULSE = (1 << (id - HAL_CMU_MOD_P_CMU)); + } else if (id < HAL_CMU_AON_A_CMU) { + cmu->ORESET_PULSE = (1 << (id - HAL_CMU_MOD_O_SLEEP)); + } else { + aoncmu->RESET_PULSE = (1 << (id - HAL_CMU_AON_A_CMU)); + // Total 3 CLK-26M cycles needed + // AOCMU runs in 26M clock domain and its read operations consume at least 1 26M-clock cycle. + // (Whereas its write operations will finish at 1 HCLK cycle -- finish once in async bridge fifo) + aoncmu->CHIP_ID; + aoncmu->CHIP_ID; + aoncmu->CHIP_ID; + } + // Delay 5+ PCLK cycles (10+ HCLK cycles) + for (i = 0; i < 3; i++); + + return 0; +} + +int hal_cmu_timer_set_div(enum HAL_CMU_TIMER_ID_T id, uint32_t div) +{ + uint32_t lock; + + if (div < 1) { + return 1; + } + + div -= 1; + if ((div & (CMU_CFG_DIV_TIMER00_MASK >> CMU_CFG_DIV_TIMER00_SHIFT)) != div) { + return 1; + } + + lock = int_lock(); + if (id == HAL_CMU_TIMER_ID_00) { + cmu->TIMER0_CLK = SET_BITFIELD(cmu->TIMER0_CLK, CMU_CFG_DIV_TIMER00, div); + } else if (id == HAL_CMU_TIMER_ID_01) { + cmu->TIMER0_CLK = SET_BITFIELD(cmu->TIMER0_CLK, CMU_CFG_DIV_TIMER01, div); + } else if (id == HAL_CMU_TIMER_ID_10) { + cmu->TIMER1_CLK = SET_BITFIELD(cmu->TIMER1_CLK, CMU_CFG_DIV_TIMER10, div); + } else if (id == HAL_CMU_TIMER_ID_11) { + cmu->TIMER1_CLK = SET_BITFIELD(cmu->TIMER1_CLK, CMU_CFG_DIV_TIMER11, div); + } else if (id == HAL_CMU_TIMER_ID_20) { + cmu->TIMER2_CLK = SET_BITFIELD(cmu->TIMER2_CLK, CMU_CFG_DIV_TIMER20, div); + } else if (id == HAL_CMU_TIMER_ID_21) { + cmu->TIMER2_CLK = SET_BITFIELD(cmu->TIMER2_CLK, CMU_CFG_DIV_TIMER21, div); + } + int_unlock(lock); + + return 0; +} + +void BOOT_TEXT_FLASH_LOC hal_cmu_timer0_select_fast(void) +{ + uint32_t lock; + + lock = int_lock(); + // 6.5M + cmu->PERIPH_CLK |= (1 << CMU_SEL_TIMER_FAST_SHIFT); + // AON Timer + aoncmu->CLK_SELECT |= AON_CMU_SEL_TIMER_FAST; + int_unlock(lock); +} + +void BOOT_TEXT_FLASH_LOC hal_cmu_timer0_select_slow(void) +{ + uint32_t lock; + + lock = int_lock(); + // 16K + cmu->PERIPH_CLK &= ~(1 << CMU_SEL_TIMER_FAST_SHIFT); + // AON Timer + aoncmu->CLK_SELECT &= ~AON_CMU_SEL_TIMER_FAST; + int_unlock(lock); +} + +void TIMER1_SEL_LOC hal_cmu_timer1_select_fast(void) +{ + uint32_t lock; + + lock = int_lock(); + // 6.5M + cmu->PERIPH_CLK |= (1 << (CMU_SEL_TIMER_FAST_SHIFT + 1)); + int_unlock(lock); +} + +void TIMER1_SEL_LOC hal_cmu_timer1_select_slow(void) +{ + uint32_t lock; + + lock = int_lock(); + // 16K + cmu->PERIPH_CLK &= ~(1 << (CMU_SEL_TIMER_FAST_SHIFT + 1)); + int_unlock(lock); +} + +void hal_cmu_timer2_select_fast(void) +{ + uint32_t lock; + + lock = int_lock(); + // 6.5M + cmu->PERIPH_CLK |= (1 << (CMU_SEL_TIMER_FAST_SHIFT + 2)); + int_unlock(lock); +} + +void hal_cmu_timer2_select_slow(void) +{ + uint32_t lock; + + lock = int_lock(); + // 16K + cmu->PERIPH_CLK &= ~(1 << (CMU_SEL_TIMER_FAST_SHIFT + 2)); + int_unlock(lock); +} + +int hal_cmu_sdmmc_set_pll_div(uint32_t div) +{ + uint32_t lock; + if (div < 2) { + return 1; + } + div -= 2; + if ((div & (CMU_CFG_DIV_SDMMC_MASK >> CMU_CFG_DIV_SDMMC_SHIFT)) != div) { + return 1; + } + lock = int_lock(); + cmu->PERIPH_CLK = SET_BITFIELD(cmu->PERIPH_CLK, CMU_CFG_DIV_SDMMC, div) | + CMU_SEL_OSCX2_SDMMC | CMU_SEL_PLL_SDMMC | CMU_EN_PLL_SDMMC; + int_unlock(lock); + return 0; +} + +#ifdef OSC_26M_X4_AUD2BB + +// Any of 78M/104M/208M is changed to 26M x4 (104M) + +#define SYS_SET_FREQ_FUNC(f, F, CLK_OV) \ +int hal_cmu_ ##f## _set_freq(enum HAL_CMU_FREQ_T freq) \ +{ \ + uint32_t enable; \ + uint32_t disable; \ + if (freq >= HAL_CMU_FREQ_QTY) { \ + return 1; \ + } \ + if (freq == HAL_CMU_FREQ_32K) { \ + enable = 0; \ + disable = CMU_SEL_OSC_ ##F## _DISABLE | CMU_SEL_OSCX2_ ##F## _DISABLE | \ + CMU_SEL_PLL_ ##F## _DISABLE | CMU_RSTN_DIV_ ##F## _DISABLE | CMU_BYPASS_DIV_ ##F## _DISABLE; \ + } else if (freq == HAL_CMU_FREQ_26M) { \ + enable = CMU_SEL_OSC_ ##F## _ENABLE; \ + disable = CMU_SEL_OSCX2_ ##F## _DISABLE | \ + CMU_SEL_PLL_ ##F## _DISABLE | CMU_RSTN_DIV_ ##F## _DISABLE | CMU_BYPASS_DIV_ ##F## _DISABLE; \ + } else if (freq == HAL_CMU_FREQ_52M) { \ + enable = CMU_SEL_OSCX2_ ##F## _ENABLE; \ + disable = CMU_SEL_PLL_ ##F## _DISABLE | CMU_RSTN_DIV_ ##F## _DISABLE | CMU_BYPASS_DIV_ ##F## _DISABLE; \ + } else { \ + enable = CMU_SEL_PLL_ ##F## _ENABLE | CMU_BYPASS_DIV_ ##F## _ENABLE; \ + disable = CMU_RSTN_DIV_ ##F## _DISABLE; \ + } \ + if (enable & CMU_SEL_PLL_ ##F## _ENABLE) { \ + CLK_OV; \ + cmu->SYS_CLK_ENABLE = CMU_RSTN_DIV_ ##F## _ENABLE; \ + if (enable & CMU_BYPASS_DIV_ ##F## _ENABLE) { \ + cmu->SYS_CLK_ENABLE = CMU_BYPASS_DIV_ ##F## _ENABLE; \ + } else { \ + cmu->SYS_CLK_DISABLE = CMU_BYPASS_DIV_ ##F## _DISABLE; \ + } \ + } \ + cmu->SYS_CLK_ENABLE = enable; \ + if (enable & CMU_SEL_PLL_ ##F## _ENABLE) { \ + cmu->SYS_CLK_DISABLE = disable; \ + } else { \ + cmu->SYS_CLK_DISABLE = disable & ~(CMU_RSTN_DIV_ ##F## _DISABLE | CMU_BYPASS_DIV_ ##F## _DISABLE); \ + cmu->SYS_CLK_DISABLE = CMU_BYPASS_DIV_ ##F## _DISABLE; \ + cmu->SYS_CLK_DISABLE = CMU_RSTN_DIV_ ##F## _DISABLE; \ + } \ + return 0; \ +} + +#else // !OSC_26M_X4_AUD2BB + +#define SYS_SET_FREQ_FUNC(f, F, CLK_OV) \ +int hal_cmu_ ##f## _set_freq(enum HAL_CMU_FREQ_T freq) \ +{ \ + uint32_t lock; \ + uint32_t enable; \ + uint32_t disable; \ + int div = -1; \ + if (freq >= HAL_CMU_FREQ_QTY) { \ + return 1; \ + } \ + if (freq == HAL_CMU_FREQ_32K) { \ + enable = 0; \ + disable = CMU_SEL_OSC_ ##F## _DISABLE | CMU_SEL_OSCX2_ ##F## _DISABLE | \ + CMU_SEL_PLL_ ##F## _DISABLE | CMU_RSTN_DIV_ ##F## _DISABLE | CMU_BYPASS_DIV_ ##F## _DISABLE; \ + } else if (freq == HAL_CMU_FREQ_26M) { \ + enable = CMU_SEL_OSC_ ##F## _ENABLE; \ + disable = CMU_SEL_OSCX2_ ##F## _DISABLE | \ + CMU_SEL_PLL_ ##F## _DISABLE | CMU_RSTN_DIV_ ##F## _DISABLE | CMU_BYPASS_DIV_ ##F## _DISABLE; \ + } else if (freq == HAL_CMU_FREQ_52M) { \ + enable = CMU_SEL_OSCX2_ ##F## _ENABLE; \ + disable = CMU_SEL_PLL_ ##F## _DISABLE | CMU_RSTN_DIV_ ##F## _DISABLE | CMU_BYPASS_DIV_ ##F## _DISABLE; \ + } else if (freq == HAL_CMU_FREQ_78M) { \ + enable = CMU_SEL_PLL_ ##F## _ENABLE | CMU_RSTN_DIV_ ##F## _ENABLE; \ + disable = CMU_BYPASS_DIV_ ##F## _DISABLE; \ + div = 1; \ + } else if (freq == HAL_CMU_FREQ_104M) { \ + enable = CMU_SEL_PLL_ ##F## _ENABLE | CMU_RSTN_DIV_ ##F## _ENABLE; \ + disable = CMU_BYPASS_DIV_ ##F## _DISABLE; \ + div = 0; \ + } else { \ + enable = CMU_SEL_PLL_ ##F## _ENABLE | CMU_BYPASS_DIV_ ##F## _ENABLE; \ + disable = CMU_RSTN_DIV_ ##F## _DISABLE; \ + } \ + if (div >= 0) { \ + CLK_OV; \ + lock = int_lock(); \ + cmu->SYS_DIV = SET_BITFIELD(cmu->SYS_DIV, CMU_CFG_DIV_ ##F, div); \ + int_unlock(lock); \ + } \ + if (enable & CMU_SEL_PLL_ ##F## _ENABLE) { \ + cmu->SYS_CLK_ENABLE = CMU_RSTN_DIV_ ##F## _ENABLE; \ + if (enable & CMU_BYPASS_DIV_ ##F## _ENABLE) { \ + cmu->SYS_CLK_ENABLE = CMU_BYPASS_DIV_ ##F## _ENABLE; \ + } else { \ + cmu->SYS_CLK_DISABLE = CMU_BYPASS_DIV_ ##F## _DISABLE; \ + } \ + } \ + cmu->SYS_CLK_ENABLE = enable; \ + if (enable & CMU_SEL_PLL_ ##F## _ENABLE) { \ + cmu->SYS_CLK_DISABLE = disable; \ + } else { \ + cmu->SYS_CLK_DISABLE = disable & ~(CMU_RSTN_DIV_ ##F## _DISABLE | CMU_BYPASS_DIV_ ##F## _DISABLE); \ + cmu->SYS_CLK_DISABLE = CMU_BYPASS_DIV_ ##F## _DISABLE; \ + cmu->SYS_CLK_DISABLE = CMU_RSTN_DIV_ ##F## _DISABLE; \ + } \ + return 0; \ +} + +#endif // !OSC_26M_X4_AUD2BB + +#ifdef MCU_SYS_CLOCK_400M +#define FLASH_DIV_OFFSET 2 +#elif defined(MCU_SYS_CLOCK_300M) +#define FLASH_DIV_OFFSET 1 +#else +#define FLASH_DIV_OFFSET 0 +#endif + +#ifdef OSC_26M_X4_AUD2BB +#define FLASH_FREQ_OV { aoncmu->CLK_OUT |= AON_CMU_SEL_X4_FLS; } +#else +#define FLASH_FREQ_OV { div += FLASH_DIV_OFFSET; } +#endif + +BOOT_TEXT_SRAM_LOC SYS_SET_FREQ_FUNC(flash, FLS, FLASH_FREQ_OV); + +#ifdef LOW_SYS_FREQ +void hal_cmu_low_sys_clock_set(enum HAL_CMU_LOW_SYS_FREQ_T freq) +{ + uint32_t lock; + + if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0) { + return; + } + + lock = int_lock(); + low_sys_freq = freq; + hal_cmu_sys_set_freq(hal_sysfreq_get_hw_freq()); + int_unlock(lock); +} + +int hal_cmu_fast_timer_offline(void) +{ + return low_sys_freq_en && low_sys_freq != HAL_CMU_LOW_SYS_FREQ_13M; +} + +static void hal_cmu_osc_to_dig_x4_enable(void) +{ + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_X4_ANA_ENABLE; + aoncmu->CLK_SELECT |= AON_CMU_SEL_X4_SYS; + aoncmu->CLK_SELECT |= AON_CMU_SEL_X4_DIG; + aoncmu->RESERVED_03C |= AON_CMU_OSC_TO_DIG_X4; +} + +static void hal_cmu_osc_to_dig_x4_disable(void) +{ + aoncmu->CLK_SELECT &= ~AON_CMU_SEL_X4_DIG; + aoncmu->RESERVED_03C &= ~AON_CMU_OSC_TO_DIG_X4; +#ifndef OSC_26M_X4_AUD2BB + aoncmu->CLK_SELECT &= ~AON_CMU_SEL_X4_SYS; +#endif +#ifndef ANA_26M_X4_ENABLE + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_X4_ANA_DISABLE; +#endif +} + +int hal_cmu_sys_set_freq(enum HAL_CMU_FREQ_T freq) +{ + uint32_t lock; + uint32_t enable; + uint32_t disable; + int div = -1; + bool low_sys_set, low_sys_clr; + + if (freq >= HAL_CMU_FREQ_QTY) { + return 1; + } + + low_sys_set = false; + low_sys_clr = false; + + lock = int_lock(); + + if (low_sys_freq == HAL_CMU_LOW_SYS_FREQ_NONE) { + if (aoncmu->RESERVED_03C & AON_CMU_OSC_TO_DIG_X4) { + low_sys_clr = true; + } + } else { + if (freq == HAL_CMU_FREQ_26M) { + low_sys_set = true; + } else if (freq > HAL_CMU_FREQ_26M) { + if (aoncmu->RESERVED_03C & AON_CMU_OSC_TO_DIG_X4) { + low_sys_clr = true; + } + } + } + + if (low_sys_clr) { + low_sys_freq_en = false; + cmu->SYS_CLK_ENABLE = CMU_SEL_OSC_SYS_ENABLE; + cmu->SYS_CLK_DISABLE = CMU_SEL_OSCX2_SYS_DISABLE | CMU_SEL_PLL_SYS_DISABLE; + hal_cmu_osc_to_dig_x4_disable(); + } + if (low_sys_set) { + low_sys_freq_en = true; + cmu->SYS_CLK_ENABLE = CMU_SEL_OSC_SYS_ENABLE; + cmu->SYS_CLK_DISABLE = CMU_SEL_OSCX2_SYS_DISABLE | CMU_SEL_PLL_SYS_DISABLE; + hal_cmu_osc_to_dig_x4_enable(); + freq = HAL_CMU_FREQ_208M; + } + + if (freq == HAL_CMU_FREQ_32K) { + enable = 0; + disable = CMU_SEL_OSC_SYS_DISABLE | CMU_SEL_OSCX2_SYS_DISABLE | + CMU_SEL_PLL_SYS_DISABLE | CMU_RSTN_DIV_SYS_DISABLE | CMU_BYPASS_DIV_SYS_DISABLE; + } else if (freq == HAL_CMU_FREQ_26M) { + enable = CMU_SEL_OSC_SYS_ENABLE; + disable = CMU_SEL_OSCX2_SYS_DISABLE | + CMU_SEL_PLL_SYS_DISABLE | CMU_RSTN_DIV_SYS_DISABLE | CMU_BYPASS_DIV_SYS_DISABLE; + } else if (freq == HAL_CMU_FREQ_52M) { + enable = CMU_SEL_OSCX2_SYS_ENABLE; + disable = CMU_SEL_PLL_SYS_DISABLE | CMU_RSTN_DIV_SYS_DISABLE | CMU_BYPASS_DIV_SYS_DISABLE; +#ifndef OSC_26M_X4_AUD2BB + } else if (freq == HAL_CMU_FREQ_78M) { + enable = CMU_SEL_PLL_SYS_ENABLE | CMU_RSTN_DIV_SYS_ENABLE; + disable = CMU_BYPASS_DIV_SYS_DISABLE; + div = 1; + } else if (freq == HAL_CMU_FREQ_104M) { + enable = CMU_SEL_PLL_SYS_ENABLE | CMU_RSTN_DIV_SYS_ENABLE; + disable = CMU_BYPASS_DIV_SYS_DISABLE; + div = 0; +#endif + } else { + if (low_sys_set) { + if (low_sys_freq == HAL_CMU_LOW_SYS_FREQ_13M) { + enable = CMU_SEL_PLL_SYS_ENABLE | CMU_BYPASS_DIV_SYS_ENABLE; + disable = CMU_RSTN_DIV_SYS_DISABLE; + } else { + enable = CMU_SEL_PLL_SYS_ENABLE | CMU_RSTN_DIV_SYS_ENABLE; + disable = CMU_BYPASS_DIV_SYS_DISABLE; + if (low_sys_freq == HAL_CMU_LOW_SYS_FREQ_6P5M) { + div = 0; + } else if (low_sys_freq == HAL_CMU_LOW_SYS_FREQ_4P33M) { + div = 1; + } else { + div = 2; + } + } + } else { + enable = CMU_SEL_PLL_SYS_ENABLE | CMU_BYPASS_DIV_SYS_ENABLE; + disable = CMU_RSTN_DIV_SYS_DISABLE; + } + } + if (div >= 0) { + cmu->SYS_DIV = SET_BITFIELD(cmu->SYS_DIV, CMU_CFG_DIV_SYS, div); + } + if (enable & CMU_SEL_PLL_SYS_ENABLE) { + cmu->SYS_CLK_ENABLE = CMU_RSTN_DIV_SYS_ENABLE; + if (enable & CMU_BYPASS_DIV_SYS_ENABLE) { + cmu->SYS_CLK_ENABLE = CMU_BYPASS_DIV_SYS_ENABLE; + } else { + cmu->SYS_CLK_DISABLE = CMU_BYPASS_DIV_SYS_DISABLE; + } + } + cmu->SYS_CLK_ENABLE = enable; + if (enable & CMU_SEL_PLL_SYS_ENABLE) { + cmu->SYS_CLK_DISABLE = disable; + } else { + cmu->SYS_CLK_DISABLE = disable & ~(CMU_RSTN_DIV_SYS_DISABLE | CMU_BYPASS_DIV_SYS_DISABLE); + cmu->SYS_CLK_DISABLE = CMU_BYPASS_DIV_SYS_DISABLE; + cmu->SYS_CLK_DISABLE = CMU_RSTN_DIV_SYS_DISABLE; + } + + int_unlock(lock); + + return 0; +} +#else +SYS_SET_FREQ_FUNC(sys, SYS, {}); +#endif + +int hal_cmu_mem_set_freq(enum HAL_CMU_FREQ_T freq) +{ + return 0; +} + +enum HAL_CMU_FREQ_T BOOT_TEXT_SRAM_LOC hal_cmu_sys_get_freq(void) +{ + uint32_t sys_clk; + uint32_t div; + + sys_clk = cmu->SYS_CLK_ENABLE; + + if (sys_clk & CMU_SEL_PLL_SYS_ENABLE) { + if (sys_clk & CMU_BYPASS_DIV_SYS_ENABLE) { + return HAL_CMU_FREQ_208M; + } else { + div = GET_BITFIELD(cmu->SYS_DIV, CMU_CFG_DIV_SYS); + if (div == 0) { + return HAL_CMU_FREQ_104M; + } else if (div == 1) { + // (div == 1): 69M + return HAL_CMU_FREQ_78M; + } else { + // (div == 2): 52M + // (div == 3): 42M + return HAL_CMU_FREQ_52M; + } + } + } else if (sys_clk & CMU_SEL_OSCX2_SYS_ENABLE) { + return HAL_CMU_FREQ_52M; + } else if (sys_clk & CMU_SEL_OSC_SYS_ENABLE) { + return HAL_CMU_FREQ_26M; + } else { + return HAL_CMU_FREQ_32K; + } +} + +int BOOT_TEXT_SRAM_LOC hal_cmu_flash_select_pll(enum HAL_CMU_PLL_T pll) +{ + return hal_cmu_sys_select_pll(pll); +} + +int hal_cmu_mem_select_pll(enum HAL_CMU_PLL_T pll) +{ + return hal_cmu_sys_select_pll(pll); +} + +// hal_cmu_flash_select_pll() requires in BOOT_TEXT_SRAM_LOC +int BOOT_TEXT_SRAM_LOC hal_cmu_sys_select_pll(enum HAL_CMU_PLL_T pll) +{ + uint32_t lock; + uint32_t sel; + + if (pll >= HAL_CMU_PLL_QTY) { + return 1; + } + + lock = int_lock(); + // 0/1:bbpll, 2:audpll, 3:usbpll + sel = (pll == HAL_CMU_PLL_AUD) ? 2 : 0; + aoncmu->CLK_SELECT = SET_BITFIELD(aoncmu->CLK_SELECT, AON_CMU_SEL_PLL_SYS, sel); + int_unlock(lock); + + return 0; +} + +int hal_cmu_get_pll_status(enum HAL_CMU_PLL_T pll) +{ + return !!(aoncmu->TOP_CLK_ENABLE & ((pll == HAL_CMU_PLL_AUD) ? AON_CMU_EN_CLK_TOP_PLLAUD_ENABLE : AON_CMU_EN_CLK_TOP_PLLUSB_ENABLE)); +} + +int hal_cmu_pll_enable(enum HAL_CMU_PLL_T pll, enum HAL_CMU_PLL_USER_T user) +{ + uint32_t pu_val; + uint32_t en_val; + uint32_t check; + uint32_t lock; + uint32_t sel; + uint32_t start; + uint32_t timeout; + + if (pll >= HAL_CMU_PLL_QTY) { + return 1; + } + if (user >= HAL_CMU_PLL_USER_QTY && user != HAL_CMU_PLL_USER_ALL) { + return 2; + } + +#ifdef USB_USE_USBPLL + if (pll == HAL_CMU_PLL_USB && user == HAL_CMU_PLL_USER_USB) { + pll = HAL_CMU_PLL_USB_HS; + } +#endif + + if (pll == HAL_CMU_PLL_AUD) { + pu_val = AON_CMU_PU_PLLAUD_ENABLE; + en_val = AON_CMU_EN_CLK_TOP_PLLAUD_ENABLE; + check = AON_CMU_LOCK_PLLAUD; +#ifdef USB_USE_USBPLL + } else if (pll == HAL_CMU_PLL_USB_HS) { + pu_val = AON_CMU_PU_PLLUSB_ENABLE; + en_val = AON_CMU_EN_CLK_TOP_PLLUSB_ENABLE; + check = AON_CMU_LOCK_PLLUSB; +#endif + } else { + pu_val = AON_CMU_PU_PLLBB_ENABLE; + en_val = AON_CMU_EN_CLK_TOP_PLLBB_ENABLE; + check = AON_CMU_LOCK_PLLBB; + } + + lock = int_lock(); + if (pll_user_map[pll] == 0 || user == HAL_CMU_PLL_USER_ALL) { +#ifndef ROM_BUILD + pmu_pll_div_reset_set(pll); +#endif + aoncmu->TOP_CLK_ENABLE = pu_val; +#ifndef ROM_BUILD + hal_sys_timer_delay_us(20); + pmu_pll_div_reset_clear(pll); + // Wait at least 10us for clock ready +#endif + } else { + check = 0; + } + if (user < HAL_CMU_PLL_USER_QTY) { + pll_user_map[pll] |= (1 << user); + } + if (user == HAL_CMU_PLL_USER_AUD) { + // 0/1:audpll, 2:bbpll, 3:usbpll + sel = (pll == HAL_CMU_PLL_AUD) ? 0 : 2; + aoncmu->CLK_SELECT = SET_BITFIELD(aoncmu->CLK_SELECT, AON_CMU_SEL_PLL_AUD, sel); + } + // HAL_CMU_PLL_USER_SYS selects PLL in hal_cmu_sys_select_pll() + int_unlock(lock); + + start = hal_sys_timer_get(); + timeout = HAL_CMU_PLL_LOCKED_TIMEOUT; + do { + if (check) { + if (aoncmu->CODEC_DIV & check) { + //break; + } + } else { + if (aoncmu->TOP_CLK_ENABLE & en_val) { + break; + } + } + } while ((hal_sys_timer_get() - start) < timeout); + + aoncmu->TOP_CLK_ENABLE = en_val; + +#ifndef USB_USE_USBPLL + if (pll == HAL_CMU_PLL_USB && user == HAL_CMU_PLL_USER_USB) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_TOP_PLLBB2_ENABLE; + } +#endif + + return (aoncmu->CODEC_DIV & check) ? 0 : 2; +} + +int hal_cmu_pll_disable(enum HAL_CMU_PLL_T pll, enum HAL_CMU_PLL_USER_T user) +{ + uint32_t lock; + + if (pll >= HAL_CMU_PLL_QTY) { + return 1; + } + if (user >= HAL_CMU_PLL_USER_QTY && user != HAL_CMU_PLL_USER_ALL) { + return 2; + } + + if (pll == HAL_CMU_PLL_USB && user == HAL_CMU_PLL_USER_USB) { +#ifdef USB_USE_USBPLL + pll = HAL_CMU_PLL_USB_HS; +#else + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_PLLBB2_DISABLE; +#endif + } + + lock = int_lock(); + if (user < HAL_CMU_PLL_USER_ALL) { + pll_user_map[pll] &= ~(1 << user); + } + if (pll_user_map[pll] == 0 || user == HAL_CMU_PLL_USER_ALL) { + if (pll == HAL_CMU_PLL_AUD) { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_PLLAUD_DISABLE; + aoncmu->TOP_CLK_DISABLE = AON_CMU_PU_PLLAUD_DISABLE; +#ifdef USB_USE_USBPLL + } else if (pll == HAL_CMU_PLL_USB_HS) { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_PLLUSB_DISABLE; + aoncmu->TOP_CLK_DISABLE = AON_CMU_PU_PLLUSB_DISABLE; +#endif + } else { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_PLLBB_DISABLE; + aoncmu->TOP_CLK_DISABLE = AON_CMU_PU_PLLBB_DISABLE; + } + } + int_unlock(lock); + + return 0; +} + +void BOOT_TEXT_FLASH_LOC hal_cmu_low_freq_mode_init(void) +{ +#if defined(MCU_HIGH_PERFORMANCE_MODE) + hal_cmu_sys_select_pll(HAL_CMU_PLL_USB); +#else + // No need to switch to USB PLL, for there is a clock gate and a clock mux + // in front of the AUD/USB switch + hal_cmu_sys_select_pll(HAL_CMU_PLL_AUD); +#endif + +//#ifdef FLASH_LOW_SPEED +#ifdef OSC_26M_X4_AUD2BB + aoncmu->CLK_SELECT &= ~AON_CMU_SEL_X4_SYS; +#endif +//#endif +} + +void hal_cmu_low_freq_mode_enable(enum HAL_CMU_FREQ_T old_freq, enum HAL_CMU_FREQ_T new_freq) +{ + // TODO: Need to lock irq? + enum HAL_CMU_PLL_T POSSIBLY_UNUSED pll; + +#if defined(MCU_HIGH_PERFORMANCE_MODE) + pll = HAL_CMU_PLL_USB; +#else + pll = HAL_CMU_PLL_AUD; +#endif + +#ifdef OSC_26M_X4_AUD2BB + if (new_freq <= HAL_CMU_FREQ_52M) { + aoncmu->CLK_SELECT &= ~AON_CMU_SEL_X4_SYS; + } + if (new_freq <= HAL_CMU_FREQ_104M && old_freq > HAL_CMU_FREQ_104M) { + if (new_freq > HAL_CMU_FREQ_52M) { + // PLL is in use now. Switch to X2 first. + hal_cmu_sys_set_freq(HAL_CMU_FREQ_52M); + aoncmu->CLK_SELECT |= AON_CMU_SEL_X4_SYS; + // X4 is in use now + hal_cmu_sys_set_freq(new_freq); + } + hal_cmu_pll_disable(pll, HAL_CMU_PLL_USER_SYS); + } +#else +#ifdef FLASH_LOW_SPEED + if (old_freq > HAL_CMU_FREQ_52M && new_freq <= HAL_CMU_FREQ_52M) { + hal_cmu_pll_disable(pll, HAL_CMU_PLL_USER_SYS); + } +#endif +#endif +} + +void hal_cmu_low_freq_mode_disable(enum HAL_CMU_FREQ_T old_freq, enum HAL_CMU_FREQ_T new_freq) +{ + // TODO: Need to lock irq? + enum HAL_CMU_PLL_T POSSIBLY_UNUSED pll; + +#if defined(MCU_HIGH_PERFORMANCE_MODE) + pll = HAL_CMU_PLL_USB; +#else + pll = HAL_CMU_PLL_AUD; +#endif + +#ifdef OSC_26M_X4_AUD2BB + if (new_freq <= HAL_CMU_FREQ_52M) { + aoncmu->CLK_SELECT &= ~AON_CMU_SEL_X4_SYS; + } else if (new_freq <= HAL_CMU_FREQ_104M) { + aoncmu->CLK_SELECT |= AON_CMU_SEL_X4_SYS; + } else { + if (old_freq <= HAL_CMU_FREQ_104M) { + hal_cmu_pll_enable(pll, HAL_CMU_PLL_USER_SYS); + if (old_freq > HAL_CMU_FREQ_52M) { + // X4 is in use now. Switch to X2 before stopping X4 + hal_cmu_sys_set_freq(HAL_CMU_FREQ_52M); + } + aoncmu->CLK_SELECT &= ~AON_CMU_SEL_X4_SYS; + } + } +#else +#ifdef FLASH_LOW_SPEED + if (old_freq <= HAL_CMU_FREQ_52M && new_freq > HAL_CMU_FREQ_52M) { + hal_cmu_pll_enable(pll, HAL_CMU_PLL_USER_SYS); + } +#endif +#endif +} + +int hal_cmu_codec_adc_set_div(uint32_t div) +{ + uint32_t lock; + + if (div < 2) { + return 1; + } + + div -= 2; + lock = int_lock(); + aoncmu->CODEC_DIV = SET_BITFIELD(aoncmu->CODEC_DIV, AON_CMU_CFG_DIV_CODEC, div); + int_unlock(lock); + + return 0; +} + +uint32_t hal_cmu_codec_adc_get_div(void) +{ + return GET_BITFIELD(aoncmu->CODEC_DIV, AON_CMU_CFG_DIV_CODEC) + 2; +} + +int hal_cmu_codec_dac_set_div(uint32_t div) +{ + return hal_cmu_codec_adc_set_div(div); +} + +uint32_t hal_cmu_codec_dac_get_div(void) +{ + return hal_cmu_codec_adc_get_div();; +} + +#if defined(__AUDIO_RESAMPLE__) && defined(ANA_26M_X4_ENABLE) +void hal_cmu_audio_26m_x4_enable(enum CMU_AUD_26M_X4_USER_T user) +{ + uint32_t lock; + + if (user >= CMU_AUD_26M_X4_USER_QTY) { + return; + } + + lock = int_lock(); + + if (aud_26m_x4_map == 0) { + aoncmu->CLK_SELECT |= AON_CMU_SEL_X4_AUD; + } + aud_26m_x4_map |= (1 << user); + + int_unlock(lock); +} + +void hal_cmu_audio_26m_x4_disable(enum CMU_AUD_26M_X4_USER_T user) +{ + uint32_t lock; + + if (user >= CMU_AUD_26M_X4_USER_QTY) { + return; + } + + lock = int_lock(); + + if (aud_26m_x4_map & (1 << user)) { + aud_26m_x4_map &= ~(1 << user); + if (aud_26m_x4_map == 0) { + aoncmu->CLK_SELECT &= ~AON_CMU_SEL_X4_AUD; + } + } + + int_unlock(lock); +} +#endif + +void hal_cmu_codec_iir_enable(uint32_t speed) +{ + uint32_t lock; + uint32_t mask; + uint32_t val; + uint32_t div; + uint32_t cfg_speed = 0; + + mask = AON_CMU_SEL_OSC_CODECIIR | AON_CMU_SEL_OSCX2_CODECIIR | AON_CMU_BYPASS_DIV_CODECIIR; + val = 0; + + if (speed <= 26000000) { + val |= AON_CMU_SEL_OSC_CODECIIR | AON_CMU_SEL_OSCX2_CODECIIR; + cfg_speed = 26000000; + } else if (speed <= 52000000) { + val |= AON_CMU_SEL_OSCX2_CODECIIR; + cfg_speed = 52000000; + } else { +#if defined(__AUDIO_RESAMPLE__) && defined(ANA_26M_X4_ENABLE) + if (hal_cmu_get_audio_resample_status()) { + hal_cmu_audio_26m_x4_enable(CMU_AUD_26M_X4_USER_IIR); + val |= AON_CMU_BYPASS_DIV_CODECIIR; + cfg_speed = 104000000; + } + else +#endif + { + // Assume audio stream is one of 48K series + div = HAL_CMU_AUD_PLL_CLOCK / speed; + if (div >= 2) { + hal_cmu_codec_iir_set_div(div); + cfg_speed = HAL_CMU_AUD_PLL_CLOCK / div; + } else { + val |= AON_CMU_BYPASS_DIV_CODECIIR; + cfg_speed = HAL_CMU_AUD_PLL_CLOCK; + } + } + } + + ASSERT(speed <= cfg_speed, "%s: speed %u should <= cfg_speed %u", __func__, speed, cfg_speed); + + lock = int_lock(); + aoncmu->CODEC_IIR = (aoncmu->CODEC_IIR & ~mask) | val; + int_unlock(lock); + + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_CODEC_IIR_ENABLE; + + aocmu_reg_update_wait(); +} + +void hal_cmu_codec_iir_disable(void) +{ + uint32_t lock; + uint32_t val; + + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_CODEC_IIR_DISABLE; + +#if defined(__AUDIO_RESAMPLE__) && defined(ANA_26M_X4_ENABLE) + hal_cmu_audio_26m_x4_disable(CMU_AUD_26M_X4_USER_IIR); +#endif + + val = AON_CMU_SEL_OSC_CODECIIR | AON_CMU_SEL_OSCX2_CODECIIR; + + lock = int_lock(); + aoncmu->CODEC_IIR |= val; + int_unlock(lock); +} + +int hal_cmu_codec_iir_set_div(uint32_t div) +{ + uint32_t lock; + + if (div < 2) { + return 1; + } + + div -= 2; + lock = int_lock(); + aoncmu->CODEC_IIR = SET_BITFIELD(aoncmu->CODEC_IIR, AON_CMU_CFG_DIV_CODECIIR, div); + int_unlock(lock); + + return 0; +} + +void hal_cmu_codec_rs_enable(uint32_t speed) +{ + uint32_t lock; + uint32_t mask; + uint32_t val; + uint32_t div; + uint32_t cfg_speed = 0; + + mask = AON_CMU_SEL_OSC_CODECRS | AON_CMU_SEL_OSCX2_CODECRS | AON_CMU_BYPASS_DIV_CODECRS; + val = 0; + + if (speed <= 26000000) { + val |= AON_CMU_SEL_OSC_CODECRS | AON_CMU_SEL_OSCX2_CODECRS; + cfg_speed = 26000000; + } else if (speed <= 52000000) { + val |= AON_CMU_SEL_OSCX2_CODECRS; + cfg_speed = 52000000; + } else { +#if defined(__AUDIO_RESAMPLE__) && defined(ANA_26M_X4_ENABLE) + if (hal_cmu_get_audio_resample_status()) { + hal_cmu_audio_26m_x4_enable(CMU_AUD_26M_X4_USER_RS); + val |= AON_CMU_BYPASS_DIV_CODECRS; + cfg_speed = 104000000; + } + else +#endif + { + // Assume audio stream is one of 48K series + div = HAL_CMU_AUD_PLL_CLOCK / speed; + if (div >= 2) { + hal_cmu_codec_rs_set_div(div); + cfg_speed = HAL_CMU_AUD_PLL_CLOCK / div; + } else { + val |= AON_CMU_BYPASS_DIV_CODECRS; + cfg_speed = HAL_CMU_AUD_PLL_CLOCK; + } + } + + pmu_rs_freq_config(cfg_speed); + } + + ASSERT(speed <= cfg_speed, "%s: speed %u should <= cfg_speed %u", __func__, speed, cfg_speed); + + lock = int_lock(); + aoncmu->CODEC_IIR = (aoncmu->CODEC_IIR & ~mask) | val; + int_unlock(lock); + + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_CODEC_RS_ENABLE; + + aocmu_reg_update_wait(); +} + +void hal_cmu_codec_rs_disable(void) +{ + uint32_t lock; + bool high_speed; + + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_CODEC_RS_DISABLE; + +#if defined(__AUDIO_RESAMPLE__) && defined(ANA_26M_X4_ENABLE) + hal_cmu_audio_26m_x4_disable(CMU_AUD_26M_X4_USER_RS); +#endif + + high_speed = !(aoncmu->CODEC_IIR & AON_CMU_SEL_OSC_CODECRS); + + lock = int_lock(); + aoncmu->CODEC_IIR |= AON_CMU_SEL_OSC_CODECRS | AON_CMU_SEL_OSCX2_CODECRS; + int_unlock(lock); + + if (high_speed) { + pmu_rs_freq_config(0); + } +} + +int hal_cmu_codec_rs_set_div(uint32_t div) +{ + uint32_t lock; + + if (div < 2) { + return 1; + } + + div -= 2; + lock = int_lock(); + aoncmu->CODEC_IIR = SET_BITFIELD(aoncmu->CODEC_IIR, AON_CMU_CFG_DIV_CODECRS, div); + int_unlock(lock); + + return 0; +} + +void hal_cmu_anc_enable(enum HAL_CMU_ANC_CLK_USER_T user) +{ + anc_enabled = true; +} + +void hal_cmu_anc_disable(enum HAL_CMU_ANC_CLK_USER_T user) +{ + anc_enabled = false; +} + +int hal_cmu_anc_get_status(enum HAL_CMU_ANC_CLK_USER_T user) +{ + return anc_enabled; +} + +void hal_cmu_codec_clock_enable(void) +{ + uint32_t clk; + +#ifdef CODEC_CLK_FROM_ANA + // Always use ANA clock + clk = AON_CMU_EN_CLK_CODEC_HCLK_ENABLE | AON_CMU_EN_CLK_CODEC_ENABLE; +#else +#ifdef __AUDIO_RESAMPLE__ + if (hal_cmu_get_audio_resample_status()) { + uint32_t lock; + lock = int_lock(); + aoncmu->CODEC_DIV |= AON_CMU_SEL_OSC_CODEC; + int_unlock(lock); + +#ifdef RESAMPLE_CODEC_CLK_ANA + clk = AON_CMU_EN_CLK_CODEC_HCLK_ENABLE | AON_CMU_EN_CLK_CODEC_ENABLE; +#else + clk = AON_CMU_EN_CLK_PLL_CODEC_ENABLE | AON_CMU_EN_CLK_CODEC_HCLK_ENABLE | AON_CMU_EN_CLK_CODEC_ENABLE; + if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0) { + // Force codec to use analog clock + clk &= ~AON_CMU_EN_CLK_PLL_CODEC_ENABLE; + } +#endif + } + else +#endif + { + clk = AON_CMU_EN_CLK_PLL_CODEC_ENABLE | AON_CMU_EN_CLK_CODEC_HCLK_ENABLE | AON_CMU_EN_CLK_CODEC_ENABLE; + } +#endif + aoncmu->TOP_CLK_ENABLE = clk; + hal_cmu_clock_enable(HAL_CMU_MOD_H_CODEC); +} + +void hal_cmu_codec_clock_disable(void) +{ + uint32_t clk; + + hal_cmu_clock_disable(HAL_CMU_MOD_H_CODEC); + +#ifdef CODEC_CLK_FROM_ANA + clk = AON_CMU_EN_CLK_CODEC_HCLK_DISABLE | AON_CMU_EN_CLK_CODEC_DISABLE; +#else +#ifdef __AUDIO_RESAMPLE__ + if (hal_cmu_get_audio_resample_status()) { + uint32_t lock; + lock = int_lock(); + aoncmu->CODEC_DIV &= ~AON_CMU_SEL_OSC_CODEC; + int_unlock(lock); + + clk = AON_CMU_EN_CLK_CODEC_HCLK_DISABLE | AON_CMU_EN_CLK_CODEC_DISABLE; + } + else +#endif + { + clk = AON_CMU_EN_CLK_PLL_CODEC_DISABLE | AON_CMU_EN_CLK_CODEC_HCLK_DISABLE | AON_CMU_EN_CLK_CODEC_DISABLE; + } +#endif + aoncmu->TOP_CLK_DISABLE = clk; +} + +void hal_cmu_codec_vad_clock_enable(uint32_t enabled) +{ + if (enabled) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_TOP_OSC_ENABLE | AON_CMU_EN_CLK_32K_CODEC_ENABLE; + } else { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_OSC_DISABLE | AON_CMU_EN_CLK_32K_CODEC_DISABLE; + } +} + +void hal_cmu_codec_reset_set(void) +{ + aoncmu->RESET_SET = AON_CMU_SOFT_RSTN_CODEC_SET; +} + +void hal_cmu_codec_reset_clear(void) +{ + aoncmu->RESET_CLR = AON_CMU_SOFT_RSTN_CODEC_CLR; + aocmu_reg_update_wait(); +} + +void hal_cmu_codec_set_fault_mask(uint32_t msk) +{ + uint32_t lock; + + lock = int_lock(); + // If bit set 1, DAC will be muted when some faults occur + cmu->PERIPH_CLK = SET_BITFIELD(cmu->PERIPH_CLK, CMU_MASK_OBS, msk); + int_unlock(lock); +} + +void hal_cmu_i2s_clock_out_enable(enum HAL_I2S_ID_T id) +{ + uint32_t lock; + uint32_t val; + + if (id == HAL_I2S_ID_0) { + val = CMU_EN_CLK_I2S0_OUT; + } else { + val = CMU_EN_CLK_I2S1_OUT; + } + + lock = int_lock(); + cmu->I2C_CLK |= val; + int_unlock(lock); +} + +void hal_cmu_i2s_clock_out_disable(enum HAL_I2S_ID_T id) +{ + uint32_t lock; + uint32_t val; + + if (id == HAL_I2S_ID_0) { + val = CMU_EN_CLK_I2S0_OUT; + } else { + val = CMU_EN_CLK_I2S1_OUT; + } + + lock = int_lock(); + cmu->I2C_CLK &= ~val; + int_unlock(lock); +} + +void hal_cmu_i2s_set_slave_mode(enum HAL_I2S_ID_T id) +{ + uint32_t lock; + uint32_t val; + + if (id == HAL_I2S_ID_0) { + val = CMU_SEL_I2S0_CLKIN; + } else { + val = CMU_SEL_I2S1_CLKIN; + } + + lock = int_lock(); + cmu->I2C_CLK |= val; + int_unlock(lock); +} + +void hal_cmu_i2s_set_master_mode(enum HAL_I2S_ID_T id) +{ + uint32_t lock; + uint32_t val; + + if (id == HAL_I2S_ID_0) { + val = CMU_SEL_I2S0_CLKIN; + } else { + val = CMU_SEL_I2S1_CLKIN; + } + + lock = int_lock(); + cmu->I2C_CLK &= ~val; + int_unlock(lock); +} + +void hal_cmu_i2s_clock_enable(enum HAL_I2S_ID_T id) +{ + uint32_t lock; + uint32_t val; + volatile uint32_t *reg; + + if (id == HAL_I2S_ID_0) { + val = AON_CMU_EN_CLK_PLL_I2S0; + reg = &aoncmu->PCM_I2S_CLK; + } else { + val = AON_CMU_EN_CLK_PLL_I2S1; + reg = &aoncmu->SPDIF_CLK; + } + + lock = int_lock(); + *reg |= val; + int_unlock(lock); +} + +void hal_cmu_i2s_clock_disable(enum HAL_I2S_ID_T id) +{ + uint32_t lock; + uint32_t val; + volatile uint32_t *reg; + + if (id == HAL_I2S_ID_0) { + val = AON_CMU_EN_CLK_PLL_I2S0; + reg = &aoncmu->PCM_I2S_CLK; + } else { + val = AON_CMU_EN_CLK_PLL_I2S1; + reg = &aoncmu->SPDIF_CLK; + } + + lock = int_lock(); + *reg &= ~val; + int_unlock(lock); +} + +int hal_cmu_i2s_set_div(enum HAL_I2S_ID_T id, uint32_t div) +{ + uint32_t lock; + + if (div < 2) { + return 1; + } + + div -= 2; + if ((div & (AON_CMU_CFG_DIV_I2S0_MASK >> AON_CMU_CFG_DIV_I2S0_SHIFT)) != div) { + return 1; + } + + lock = int_lock(); + if (id == HAL_I2S_ID_0) { + aoncmu->PCM_I2S_CLK = SET_BITFIELD(aoncmu->PCM_I2S_CLK, AON_CMU_CFG_DIV_I2S0, div); + } else { + aoncmu->SPDIF_CLK = SET_BITFIELD(aoncmu->SPDIF_CLK, AON_CMU_CFG_DIV_I2S1, div); + } + int_unlock(lock); + + return 0; +} + +void hal_cmu_pcm_clock_out_enable(void) +{ + uint32_t lock; + + lock = int_lock(); + cmu->I2C_CLK |= CMU_EN_CLK_PCM_OUT; + int_unlock(lock); +} + +void hal_cmu_pcm_clock_out_disable(void) +{ + uint32_t lock; + + lock = int_lock(); + cmu->I2C_CLK &= ~CMU_EN_CLK_PCM_OUT; + int_unlock(lock); +} + +void hal_cmu_pcm_set_slave_mode(int clk_pol) +{ + uint32_t lock; + uint32_t mask; + uint32_t cfg; + + mask = CMU_SEL_PCM_CLKIN | CMU_POL_CLK_PCM_IN; + + if (clk_pol) { + cfg = CMU_SEL_PCM_CLKIN | CMU_POL_CLK_PCM_IN; + } else { + cfg = CMU_SEL_PCM_CLKIN; + } + + lock = int_lock(); + cmu->I2C_CLK = (cmu->I2C_CLK & ~mask) | cfg; + int_unlock(lock); +} + +void hal_cmu_pcm_set_master_mode(void) +{ + uint32_t lock; + + lock = int_lock(); + cmu->I2C_CLK &= ~CMU_SEL_PCM_CLKIN; + int_unlock(lock); +} + +void hal_cmu_pcm_clock_enable(void) +{ + uint32_t lock; + + lock = int_lock(); + aoncmu->PCM_I2S_CLK |= AON_CMU_EN_CLK_PLL_PCM; + int_unlock(lock); +} + +void hal_cmu_pcm_clock_disable(void) +{ + uint32_t lock; + + lock = int_lock(); + aoncmu->PCM_I2S_CLK &= ~AON_CMU_EN_CLK_PLL_PCM; + int_unlock(lock); +} + +int hal_cmu_pcm_set_div(uint32_t div) +{ + uint32_t lock; + + if (div < 2) { + return 1; + } + + div -= 2; + if ((div & (AON_CMU_CFG_DIV_PCM_MASK >> AON_CMU_CFG_DIV_PCM_SHIFT)) != div) { + return 1; + } + + lock = int_lock(); + aoncmu->PCM_I2S_CLK = SET_BITFIELD(aoncmu->PCM_I2S_CLK, AON_CMU_CFG_DIV_PCM, div); + int_unlock(lock); + return 0; +} + +int hal_cmu_spdif_clock_enable(enum HAL_SPDIF_ID_T id) +{ + uint32_t lock; + uint32_t mask; + + if (id >= HAL_SPDIF_ID_QTY) { + return 1; + } + + mask = AON_CMU_EN_CLK_PLL_SPDIF0; + + lock = int_lock(); + aoncmu->SPDIF_CLK |= mask; + int_unlock(lock); + return 0; +} + +int hal_cmu_spdif_clock_disable(enum HAL_SPDIF_ID_T id) +{ + uint32_t lock; + uint32_t mask; + + if (id >= HAL_SPDIF_ID_QTY) { + return 1; + } + + mask = AON_CMU_EN_CLK_PLL_SPDIF0; + + lock = int_lock(); + aoncmu->SPDIF_CLK &= ~mask; + int_unlock(lock); + + return 0; +} + +int hal_cmu_spdif_set_div(enum HAL_SPDIF_ID_T id, uint32_t div) +{ + uint32_t lock; + + if (id >= HAL_SPDIF_ID_QTY) { + return 1; + } + + if (div < 2) { + return 2; + } + + div -= 2; + if ((div & (AON_CMU_CFG_DIV_SPDIF0_MASK >> AON_CMU_CFG_DIV_SPDIF0_SHIFT)) != div) { + return 2; + } + + lock = int_lock(); + aoncmu->SPDIF_CLK = SET_BITFIELD(aoncmu->SPDIF_CLK, AON_CMU_CFG_DIV_SPDIF0, div); + int_unlock(lock); + return 0; +} + +#ifdef CHIP_HAS_USB +void hal_cmu_usb_set_device_mode(void) +{ + uint32_t lock; + + lock = int_lock(); + cmu->SYS_DIV |= CMU_USB_ID; + int_unlock(lock); +} + +void hal_cmu_usb_set_host_mode(void) +{ + uint32_t lock; + + lock = int_lock(); + cmu->SYS_DIV &= ~CMU_USB_ID; + int_unlock(lock); +} + +#ifdef ROM_BUILD +void hal_cmu_usb_rom_set_clock_source(enum HAL_CMU_USB_CLOCK_SEL_T sel) +{ + usb_clk_sel = sel; +} +#endif + +static uint32_t hal_cmu_usb_get_clock_source(void) +{ + uint32_t src; + +#if defined(USB_CLK_SRC_26M_X4) || defined(USB_CLK_SRC_26M_X2) || defined(USB_CLK_SRC_24M_X2) || defined(USB_CLK_SRC_48M) +#ifdef USB_HIGH_SPEED +#error "USB HIGH-SPEED must use PLL" +#endif +#if defined(USB_CLK_SRC_26M_X4) && !defined(ANA_26M_X4_ENABLE) +#error "USB_CLK_SRC_26M_X4 must use ANA_26M_X4_ENABLE" +#endif +#endif + +#ifdef ROM_BUILD + +#ifdef USB_USE_USBPLL + src = CMU_USB_CLK_SRC_PLL_60M; +#else + if (usb_clk_sel == HAL_CMU_USB_CLOCK_SEL_24M_X2) { + src = CMU_USB_CLK_SRC_OSC_24M_X2; + } else if (usb_clk_sel == HAL_CMU_USB_CLOCK_SEL_48M) { + src = CMU_USB_CLK_SRC_OSC_48M; + } else if (usb_clk_sel == HAL_CMU_USB_CLOCK_SEL_26M_X2) { + src = CMU_USB_CLK_SRC_OSC_26M_X2; + } else if (usb_clk_sel == HAL_CMU_USB_CLOCK_SEL_26M_X4) { + src = CMU_USB_CLK_SRC_OSC_26M_X4; + } else { + src = CMU_USB_CLK_SRC_PLL_48M; + } +#endif + +#else // !ROM_BUILD + +#ifdef USB_USE_USBPLL + src = CMU_USB_CLK_SRC_PLL_60M; +#else +#ifdef USB_CLK_SRC_24M_X2 + src = CMU_USB_CLK_SRC_OSC_24M_X2; +#elif defined(USB_CLK_SRC_48M) + src = CMU_USB_CLK_SRC_OSC_48M; +#elif defined(USB_CLK_SRC_26M_X4) + src = CMU_USB_CLK_SRC_OSC_26M_X4; +#elif defined(USB_CLK_SRC_26M_X2) + src = CMU_USB_CLK_SRC_OSC_26M_X2; +#else + src = CMU_USB_CLK_SRC_PLL_48M; +#endif +#endif + +#endif // !ROM_BUILD + + return src; +} + +void hal_cmu_usb_clock_enable(void) +{ + enum HAL_CMU_PLL_T pll; + uint32_t lock; + uint32_t src; + + pll = HAL_CMU_PLL_USB; + src = hal_cmu_usb_get_clock_source(); + + if (src == CMU_USB_CLK_SRC_PLL_60M || src == CMU_USB_CLK_SRC_PLL_60M_ALT || + src == CMU_USB_CLK_SRC_PLL_48M) { + hal_cmu_pll_enable(pll, HAL_CMU_PLL_USER_USB); + } + + lock = int_lock(); +#ifdef USB_CLK_SRC_26M_X4 + aoncmu->CLK_SELECT |= AON_CMU_SEL_X4_USB; +#endif + cmu->SYS_DIV = SET_BITFIELD(cmu->SYS_DIV, CMU_SEL_USB_SRC, src); + int_unlock(lock); + hal_cmu_clock_enable(HAL_CMU_MOD_H_USBC); +#ifdef USB_HIGH_SPEED + hal_cmu_clock_enable(HAL_CMU_MOD_H_USBH); +#endif + hal_cmu_clock_enable(HAL_CMU_MOD_O_USB32K); + hal_cmu_clock_enable(HAL_CMU_MOD_O_USB); + hal_cmu_reset_set(HAL_CMU_MOD_O_USB); + hal_cmu_reset_set(HAL_CMU_MOD_O_USB32K); +#ifdef USB_HIGH_SPEED + hal_cmu_reset_set(HAL_CMU_MOD_H_USBH); +#endif + hal_cmu_reset_set(HAL_CMU_MOD_H_USBC); + hal_sys_timer_delay(US_TO_TICKS(60)); + hal_cmu_reset_clear(HAL_CMU_MOD_H_USBC); +#ifdef USB_HIGH_SPEED + hal_cmu_reset_clear(HAL_CMU_MOD_H_USBH); +#endif + hal_cmu_reset_clear(HAL_CMU_MOD_O_USB32K); + hal_cmu_reset_clear(HAL_CMU_MOD_O_USB); +} + +void hal_cmu_usb_clock_disable(void) +{ + enum HAL_CMU_PLL_T pll; + uint32_t src; + + pll = HAL_CMU_PLL_USB; + src = hal_cmu_usb_get_clock_source(); + + hal_cmu_reset_set(HAL_CMU_MOD_O_USB); + hal_cmu_reset_set(HAL_CMU_MOD_O_USB32K); +#ifdef USB_HIGH_SPEED + hal_cmu_reset_set(HAL_CMU_MOD_H_USBH); +#endif + hal_cmu_reset_set(HAL_CMU_MOD_H_USBC); + hal_cmu_clock_disable(HAL_CMU_MOD_O_USB); + hal_cmu_clock_disable(HAL_CMU_MOD_O_USB32K); +#ifdef USB_HIGH_SPEED + hal_cmu_clock_disable(HAL_CMU_MOD_H_USBH); +#endif + hal_cmu_clock_disable(HAL_CMU_MOD_H_USBC); + + if (src == CMU_USB_CLK_SRC_PLL_60M || src == CMU_USB_CLK_SRC_PLL_60M_ALT || + src == CMU_USB_CLK_SRC_PLL_48M) { + hal_cmu_pll_disable(pll, HAL_CMU_PLL_USER_USB); + } +} +#endif + +void BOOT_TEXT_FLASH_LOC hal_cmu_apb_init_div(void) +{ + // Divider defaults to 2 (reg_val = div - 2) + //cmu->SYS_DIV = SET_BITFIELD(cmu->SYS_DIV, CMU_CFG_DIV_PCLK, 0); +} + +int hal_cmu_periph_set_div(uint32_t div) +{ + uint32_t lock; + int ret = 0; + + if (div == 0 || div > ((AON_CMU_CFG_DIV_PER_MASK >> AON_CMU_CFG_DIV_PER_SHIFT) + 2)) { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_PLL_PER_DISABLE; + if (div > ((AON_CMU_CFG_DIV_PER_MASK >> AON_CMU_CFG_DIV_PER_SHIFT) + 2)) { + ret = 1; + } + } else { + lock = int_lock(); + if (div == 1) { + aoncmu->CLK_SELECT |= AON_CMU_BYPASS_DIV_PER; + } else { + div -= 2; + aoncmu->CLK_SELECT = (aoncmu->CLK_SELECT & ~(AON_CMU_CFG_DIV_PER_MASK | AON_CMU_BYPASS_DIV_PER)) | + AON_CMU_CFG_DIV_PER(div); + } + int_unlock(lock); + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_PLL_PER_ENABLE; + } + + return ret; +} + +#define PERPH_SET_DIV_FUNC(f, F, r) \ +int hal_cmu_ ##f## _set_div(uint32_t div) \ +{ \ + uint32_t lock; \ + int ret = 0; \ + lock = int_lock(); \ + if (div < 2 || div > ((CMU_CFG_DIV_ ##F## _MASK >> CMU_CFG_DIV_ ##F## _SHIFT) + 2)) { \ + cmu->r &= ~(CMU_SEL_OSCX2_ ##F | CMU_SEL_PLL_ ##F | CMU_EN_PLL_ ##F); \ + ret = 1; \ + } else { \ + div -= 2; \ + cmu->r = (cmu->r & ~(CMU_CFG_DIV_ ##F## _MASK)) | CMU_SEL_OSCX2_ ##F | CMU_SEL_PLL_ ##F | \ + CMU_CFG_DIV_ ##F(div); \ + cmu->r |= CMU_EN_PLL_ ##F; \ + } \ + int_unlock(lock); \ + return ret; \ +} + +PERPH_SET_DIV_FUNC(uart0, UART0, UART_CLK); +PERPH_SET_DIV_FUNC(uart1, UART1, UART_CLK); +PERPH_SET_DIV_FUNC(uart2, UART2, UART_CLK); +PERPH_SET_DIV_FUNC(spi, SPI1, SYS_DIV); +PERPH_SET_DIV_FUNC(slcd, SPI0, SYS_DIV); +PERPH_SET_DIV_FUNC(sdmmc, SDMMC, PERIPH_CLK); +PERPH_SET_DIV_FUNC(i2c, I2C, I2C_CLK); + +#define PERPH_SET_FREQ_FUNC(f, F, r) \ +int hal_cmu_ ##f## _set_freq(enum HAL_CMU_PERIPH_FREQ_T freq) \ +{ \ + uint32_t lock; \ + int ret = 0; \ + lock = int_lock(); \ + if (freq == HAL_CMU_PERIPH_FREQ_26M) { \ + cmu->r &= ~(CMU_SEL_OSCX2_ ##F | CMU_SEL_PLL_ ##F | CMU_EN_PLL_ ##F); \ + } else if (freq == HAL_CMU_PERIPH_FREQ_52M) { \ + cmu->r = (cmu->r & ~(CMU_SEL_PLL_ ##F | CMU_EN_PLL_ ##F)) | CMU_SEL_OSCX2_ ##F; \ + } else { \ + ret = 1; \ + } \ + int_unlock(lock); \ + return ret; \ +} + +PERPH_SET_FREQ_FUNC(uart0, UART0, UART_CLK); +PERPH_SET_FREQ_FUNC(uart1, UART1, UART_CLK); +PERPH_SET_FREQ_FUNC(uart2, UART2, UART_CLK); +PERPH_SET_FREQ_FUNC(spi, SPI1, SYS_DIV); +PERPH_SET_FREQ_FUNC(slcd, SPI0, SYS_DIV); +PERPH_SET_FREQ_FUNC(sdmmc, SDMMC, PERIPH_CLK); +PERPH_SET_FREQ_FUNC(i2c, I2C, I2C_CLK); + +int hal_cmu_ispi_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq) +{ + uint32_t lock; + int ret = 0; + + lock = int_lock(); + if (freq == HAL_CMU_PERIPH_FREQ_26M) { + cmu->SYS_DIV &= ~CMU_SEL_OSCX2_SPI2; + } else if (freq == HAL_CMU_PERIPH_FREQ_52M) { + cmu->SYS_DIV |= CMU_SEL_OSCX2_SPI2; + } else { + ret = 1; + } + int_unlock(lock); + + return ret; +} + +int hal_cmu_clock_out_enable(enum HAL_CMU_CLOCK_OUT_ID_T id) +{ + uint32_t lock; + uint32_t sel; + uint32_t cfg; + + enum CMU_CLK_OUT_SEL_T { + CMU_CLK_OUT_SEL_AON = 0, + CMU_CLK_OUT_SEL_CODEC = 1, + CMU_CLK_OUT_SEL_BT = 2, + CMU_CLK_OUT_SEL_MCU = 3, + + CMU_CLK_OUT_SEL_QTY + }; + + sel = CMU_CLK_OUT_SEL_QTY; + cfg = 0; + + if (id <= HAL_CMU_CLOCK_OUT_AON_SYS) { + sel = CMU_CLK_OUT_SEL_AON; + cfg = id - HAL_CMU_CLOCK_OUT_AON_32K; + } else if (HAL_CMU_CLOCK_OUT_MCU_32K <= id && id <= HAL_CMU_CLOCK_OUT_MCU_SPI1) { + sel = CMU_CLK_OUT_SEL_MCU; + lock = int_lock(); + cmu->PERIPH_CLK = SET_BITFIELD(cmu->PERIPH_CLK, CMU_CFG_CLK_OUT, id - HAL_CMU_CLOCK_OUT_MCU_32K); + int_unlock(lock); + } else if (HAL_CMU_CLOCK_OUT_CODEC_ADC_ANA <= id && id <= HAL_CMU_CLOCK_OUT_CODEC_HCLK) { + sel = CMU_CLK_OUT_SEL_CODEC; + hal_codec_select_clock_out(id - HAL_CMU_CLOCK_OUT_CODEC_ADC_ANA); + } else if (HAL_CMU_CLOCK_OUT_BT_32K <= id && id <= HAL_CMU_CLOCK_OUT_BT_26M) { + sel = CMU_CLK_OUT_SEL_BT; + btcmu->CLK_OUT = SET_BITFIELD(btcmu->CLK_OUT, BT_CMU_CFG_CLK_OUT, id - HAL_CMU_CLOCK_OUT_BT_32K); + } + + if (sel < CMU_CLK_OUT_SEL_QTY) { + lock = int_lock(); + aoncmu->CLK_OUT = (aoncmu->CLK_OUT & ~(AON_CMU_SEL_CLK_OUT_MASK | AON_CMU_CFG_CLK_OUT_MASK)) | + AON_CMU_SEL_CLK_OUT(sel) | AON_CMU_CFG_CLK_OUT(cfg) | AON_CMU_EN_CLK_OUT; + int_unlock(lock); + + return 0; + } + + return 1; +} + +void hal_cmu_clock_out_disable(void) +{ + uint32_t lock; + + lock = int_lock(); + aoncmu->CLK_OUT &= ~AON_CMU_EN_CLK_OUT; + int_unlock(lock); +} + +int hal_cmu_i2s_mclk_enable(enum HAL_CMU_I2S_MCLK_ID_T id) +{ + uint32_t lock; + + lock = int_lock(); + aoncmu->PCM_I2S_CLK = SET_BITFIELD(aoncmu->PCM_I2S_CLK, AON_CMU_SEL_I2S_MCLK, id) | AON_CMU_EN_I2S_MCLK; + int_unlock(lock); + + return 0; +} + +void hal_cmu_i2s_mclk_disable(void) +{ + uint32_t lock; + + lock = int_lock(); + aoncmu->PCM_I2S_CLK &= ~AON_CMU_EN_I2S_MCLK; + int_unlock(lock); +} + +int hal_cmu_pwm_set_freq(enum HAL_PWM_ID_T id, uint32_t freq) +{ + uint32_t lock; + int clk_32k; + uint32_t div; + + if (id >= HAL_PWM_ID_QTY) { + return 1; + } + + if (freq == 0) { + clk_32k = 1; + div = 0; + } else { + clk_32k = 0; + div = hal_cmu_get_crystal_freq() / freq; + if (div < 2) { + return 1; + } + + div -= 2; + if ((div & (AON_CMU_CFG_DIV_PWM0_MASK >> AON_CMU_CFG_DIV_PWM0_SHIFT)) != div) { + return 1; + } + } + + lock = int_lock(); + if (id == HAL_PWM_ID_0) { + aoncmu->PWM01_CLK = (aoncmu->PWM01_CLK & ~(AON_CMU_CFG_DIV_PWM0_MASK | AON_CMU_SEL_OSC_PWM0 | AON_CMU_EN_OSC_PWM0)) | + AON_CMU_CFG_DIV_PWM0(div) | (clk_32k ? 0 : (AON_CMU_SEL_OSC_PWM0 | AON_CMU_EN_OSC_PWM0)); + } else if (id == HAL_PWM_ID_1) { + aoncmu->PWM01_CLK = (aoncmu->PWM01_CLK & ~(AON_CMU_CFG_DIV_PWM1_MASK | AON_CMU_SEL_OSC_PWM1 | AON_CMU_EN_OSC_PWM1)) | + AON_CMU_CFG_DIV_PWM1(div) | (clk_32k ? 0 : (AON_CMU_SEL_OSC_PWM1 | AON_CMU_EN_OSC_PWM1)); + } else if (id == HAL_PWM_ID_2) { + aoncmu->PWM23_CLK = (aoncmu->PWM23_CLK & ~(AON_CMU_CFG_DIV_PWM2_MASK | AON_CMU_SEL_OSC_PWM2 | AON_CMU_EN_OSC_PWM2)) | + AON_CMU_CFG_DIV_PWM2(div) | (clk_32k ? 0 : (AON_CMU_SEL_OSC_PWM2 | AON_CMU_EN_OSC_PWM2)); + } else { + aoncmu->PWM23_CLK = (aoncmu->PWM23_CLK & ~(AON_CMU_CFG_DIV_PWM3_MASK | AON_CMU_SEL_OSC_PWM3 | AON_CMU_EN_OSC_PWM3)) | + AON_CMU_CFG_DIV_PWM3(div) | (clk_32k ? 0 : (AON_CMU_SEL_OSC_PWM3 | AON_CMU_EN_OSC_PWM3)); + } + int_unlock(lock); + return 0; +} + +void hal_cmu_jtag_enable(void) +{ + uint32_t lock; + + lock = int_lock(); + cmu->MCU_TIMER &= ~(CMU_SECURE_BOOT_JTAG | CMU_SECURE_BOOT_I2C); + int_unlock(lock); +} + +void hal_cmu_jtag_disable(void) +{ + uint32_t lock; + + lock = int_lock(); + cmu->MCU_TIMER |= (CMU_SECURE_BOOT_JTAG | CMU_SECURE_BOOT_I2C); + int_unlock(lock); +} + +void hal_cmu_jtag_clock_enable(void) +{ + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_TOP_JTAG_ENABLE; +} + +void hal_cmu_jtag_clock_disable(void) +{ + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_JTAG_DISABLE; +} + +void hal_cmu_rom_clock_init(void) +{ + aoncmu->CODEC_DIV = (aoncmu->CODEC_DIV & ~AON_CMU_SEL_CLK_OSCX2) | + AON_CMU_BYPASS_LOCK_PLLBB | AON_CMU_BYPASS_LOCK_PLLAUD | AON_CMU_SEL_CLK_OSC; + // Enable PMU fast clock + aoncmu->CLK_OUT &= ~(AON_CMU_SEL_DCDC_PLL | AON_CMU_SEL_DCDC_OSCX2); + aoncmu->CLK_OUT |= AON_CMU_BYPASS_DIV_DCDC; + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_DCDC0_ENABLE; +} + +void hal_cmu_init_chip_feature(uint16_t feature) +{ + aoncmu->CHIP_FEATURE = feature | AON_CMU_EFUSE_LOCK; +} + +void BOOT_TEXT_FLASH_LOC hal_cmu_osc_x2_enable(void) +{ + // Debug Select CMU REG F4 + cmu->MCU_TIMER = SET_BITFIELD(cmu->MCU_TIMER, CMU_DEBUG_REG_SEL, CMU_DEBUG_REG_SEL_DEBUG); + // Enable OSCX2 for MCU peripheral + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_OSCX2_MCU_ENABLE; +} + +void BOOT_TEXT_FLASH_LOC hal_cmu_osc_x4_enable(void) +{ +#ifdef ANA_26M_X4_ENABLE + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_X4_ANA_ENABLE; +#endif +#ifdef OSC_26M_X4_AUD2BB + aoncmu->CLK_SELECT |= AON_CMU_SEL_X4_SYS; + aoncmu->CLK_SELECT &= ~AON_CMU_SEL_X4_DIG; +#endif +} + +void BOOT_TEXT_FLASH_LOC hal_cmu_module_init_state(void) +{ + aoncmu->CODEC_DIV = (aoncmu->CODEC_DIV & ~AON_CMU_SEL_CLK_OSCX2) | + AON_CMU_BYPASS_LOCK_PLLBB | AON_CMU_BYPASS_LOCK_PLLAUD | AON_CMU_SEL_CLK_OSC; + // Slow down PMU fast clock + aoncmu->CLK_OUT = (aoncmu->CLK_OUT & ~(AON_CMU_BYPASS_DIV_DCDC | AON_CMU_CFG_DIV_DCDC_MASK)) | AON_CMU_CFG_DIV_DCDC(2); + + // DMA channel config + cmu->ADMA_CH0_4_REQ = + // codec + CMU_ADMA_CH0_REQ_IDX(0) | CMU_ADMA_CH1_REQ_IDX(1) | +#ifdef CODEC_DSD + // codec_dsd + CMU_ADMA_CH2_REQ_IDX(16) | CMU_ADMA_CH3_REQ_IDX(17) | +#else + // btpcm + CMU_ADMA_CH2_REQ_IDX(2) | CMU_ADMA_CH3_REQ_IDX(3) | +#endif + // i2s0 + CMU_ADMA_CH4_REQ_IDX(4); + cmu->ADMA_CH5_9_REQ = + // i2s0 + CMU_ADMA_CH5_REQ_IDX(5) | + // fir + CMU_ADMA_CH6_REQ_IDX(6) | CMU_ADMA_CH7_REQ_IDX(7) | + // spdif + CMU_ADMA_CH8_REQ_IDX(8) | CMU_ADMA_CH9_REQ_IDX(9); + cmu->ADMA_CH10_14_REQ = + // iir + CMU_ADMA_CH10_REQ_IDX(10) | CMU_ADMA_CH11_REQ_IDX(11) | + // btdump + CMU_ADMA_CH12_REQ_IDX(12) | + // mc + CMU_ADMA_CH13_REQ_IDX(13) | + // i2s1 + CMU_ADMA_CH14_REQ_IDX(18); + cmu->ADMA_CH15_REQ = + // i2s1 + CMU_ADMA_CH15_REQ_IDX(19); + cmu->GDMA_CH0_4_REQ = + // flash + CMU_GDMA_CH0_REQ_IDX(20) | + // sdmmc + CMU_GDMA_CH1_REQ_IDX(21) | + // i2c0 + CMU_GDMA_CH2_REQ_IDX(22) | CMU_GDMA_CH3_REQ_IDX(23) | + // spi + CMU_GDMA_CH4_REQ_IDX(24); + cmu->GDMA_CH5_9_REQ = + // spi + CMU_GDMA_CH5_REQ_IDX(25) | + // spilcd + CMU_GDMA_CH6_REQ_IDX(26) | CMU_GDMA_CH7_REQ_IDX(27) | + // uart0 + CMU_GDMA_CH8_REQ_IDX(28) | CMU_GDMA_CH9_REQ_IDX(29); + cmu->GDMA_CH10_14_REQ = + // uart1 + CMU_GDMA_CH10_REQ_IDX(30) | CMU_GDMA_CH11_REQ_IDX(31) | + // i2c1 + CMU_GDMA_CH12_REQ_IDX(32) | CMU_GDMA_CH13_REQ_IDX(33) | + // uart2 + CMU_GDMA_CH14_REQ_IDX(34); + cmu->GDMA_CH15_REQ = + // uart2 + CMU_GDMA_CH15_REQ_IDX(35); + +#ifndef SIMU + cmu->ORESET_SET = SYS_ORST_USB | SYS_ORST_SDMMC | SYS_ORST_WDT | SYS_ORST_TIMER2 | + SYS_ORST_I2C0 | SYS_ORST_I2C1 | SYS_ORST_SPI | SYS_ORST_SLCD | SYS_ORST_SPI_PHY | + SYS_ORST_UART0 | SYS_ORST_UART1 | SYS_ORST_UART2 | SYS_ORST_I2S0 | SYS_ORST_SPDIF0 | SYS_ORST_PCM | + SYS_ORST_USB32K | SYS_ORST_I2S1; + cmu->PRESET_SET = SYS_PRST_WDT | SYS_PRST_TIMER2 | SYS_PRST_I2C0 | SYS_PRST_I2C1 | + SYS_PRST_SPI | SYS_PRST_SLCD | SYS_PRST_SPI_PHY | + SYS_PRST_UART0 | SYS_PRST_UART1 | SYS_PRST_UART2 | + SYS_PRST_PCM | SYS_PRST_I2S0 | SYS_PRST_SPDIF0 | SYS_PRST_I2S1 | SYS_PRST_BCM; + cmu->HRESET_SET = SYS_HRST_SDMMC | SYS_HRST_USBC | SYS_HRST_CODEC | SYS_HRST_FFT | + SYS_HRST_USBH | SYS_HRST_SENSOR_HUB | SYS_HRST_BT_DUMP | SYS_HRST_CP | SYS_HRST_BCM | SYS_HRST_ICACHE0; + + cmu->OCLK_DISABLE = SYS_OCLK_USB | SYS_OCLK_SDMMC | SYS_OCLK_WDT | SYS_OCLK_TIMER2 | + SYS_OCLK_I2C0 | SYS_OCLK_I2C1 | SYS_OCLK_SPI | SYS_OCLK_SLCD | SYS_OCLK_SPI_PHY | + SYS_OCLK_UART0 | SYS_OCLK_UART1 | SYS_OCLK_UART2 | SYS_OCLK_I2S0 | SYS_OCLK_SPDIF0 | SYS_OCLK_PCM | + SYS_OCLK_USB32K | SYS_OCLK_I2S1; + cmu->PCLK_DISABLE = SYS_PCLK_WDT | SYS_PCLK_TIMER2 | SYS_PCLK_I2C0 | SYS_PCLK_I2C1 | + SYS_PCLK_SPI | SYS_PCLK_SLCD | SYS_PCLK_SPI_PHY | + SYS_PCLK_UART0 | SYS_PCLK_UART1 | SYS_PCLK_UART2 | + SYS_PCLK_PCM | SYS_PCLK_I2S0 | SYS_PCLK_SPDIF0 | SYS_PCLK_I2S1 | SYS_PCLK_BCM; + cmu->HCLK_DISABLE = SYS_HCLK_SDMMC | SYS_HCLK_USBC | SYS_HCLK_CODEC | SYS_HCLK_FFT | + SYS_HCLK_USBH | SYS_HCLK_SENSOR_HUB | SYS_HCLK_BT_DUMP | SYS_HCLK_CP | SYS_HCLK_BCM | SYS_HCLK_ICACHE0; + + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_PLL_CODEC_DISABLE | AON_CMU_EN_CLK_CODEC_HCLK_DISABLE | AON_CMU_EN_CLK_CODEC_DISABLE | + AON_CMU_EN_CLK_CODEC_IIR_DISABLE | AON_CMU_EN_CLK_PLL_BT_DISABLE | + AON_CMU_EN_CLK_60M_BT_DISABLE | AON_CMU_EN_CLK_OSCX2_BT_DISABLE | AON_CMU_EN_CLK_OSC_BT_DISABLE | + AON_CMU_EN_CLK_32K_BT_DISABLE | AON_CMU_EN_CLK_PLL_PER_DISABLE; + + aoncmu->RESET_SET = AON_CMU_ARESETN_SET(AON_ARST_PWM) | + AON_CMU_ORESETN_SET(AON_ORST_PWM0 | AON_ORST_PWM1 | AON_ORST_PWM2 | AON_ORST_PWM3) | + AON_CMU_SOFT_RSTN_CODEC_SET | AON_CMU_SOFT_RSTN_BT_SET | AON_CMU_SOFT_RSTN_BTCPU_SET; + + aoncmu->MOD_CLK_DISABLE = AON_CMU_MANUAL_ACLK_DISABLE(AON_ACLK_PWM) | + AON_CMU_MANUAL_OCLK_DISABLE(AON_OCLK_PWM0 | AON_OCLK_PWM1 | AON_OCLK_PWM2 | AON_OCLK_PWM3); + + aoncmu->MOD_CLK_MODE &= ~AON_CMU_MODE_ACLK(AON_ACLK_CMU | AON_ACLK_GPIO_INT | AON_ACLK_WDT | AON_ACLK_PWM | + AON_ACLK_TIMER | AON_ACLK_PSC | AON_ACLK_IOMUX); + cmu->PCLK_MODE &= ~(SYS_PCLK_CMU | SYS_PCLK_WDT | SYS_PCLK_TIMER0 | SYS_PCLK_TIMER1 | SYS_PCLK_TIMER2); + + //cmu->HCLK_MODE = 0; + //cmu->PCLK_MODE = SYS_PCLK_UART0 | SYS_PCLK_UART1 | SYS_PCLK_UART2; + //cmu->OCLK_MODE = 0; +#endif + +#ifdef CORE_SLEEP_POWER_DOWN + hal_cmu_set_wakeup_pc((uint32_t)hal_sleep_core_power_up); +#endif + hal_psc_init(); +} + +void BOOT_TEXT_FLASH_LOC hal_cmu_ema_init(void) +{ + // Never change EMA in best2300 +} + +void hal_cmu_lpu_wait_26m_ready(void) +{ + while ((cmu->WAKEUP_CLK_CFG & CMU_LPU_STATUS_26M) == 0); +} + +int hal_cmu_lpu_busy(void) +{ + if ((cmu->WAKEUP_CLK_CFG & CMU_LPU_AUTO_SWITCH26) && + (cmu->WAKEUP_CLK_CFG & CMU_LPU_STATUS_26M) == 0) { + return 1; + } + if ((cmu->WAKEUP_CLK_CFG & CMU_LPU_AUTO_SWITCHPLL) && + (cmu->WAKEUP_CLK_CFG & CMU_LPU_STATUS_PLL) == 0) { + return 1; + } + return 0; +} + +int BOOT_TEXT_FLASH_LOC hal_cmu_lpu_init(enum HAL_CMU_LPU_CLK_CFG_T cfg) +{ + uint32_t lpu_clk; + uint32_t timer_26m; + uint32_t timer_pll; + + timer_26m = LPU_TIMER_US(TICKS_TO_US(HAL_CMU_26M_READY_TIMEOUT)); + timer_pll = LPU_TIMER_US(TICKS_TO_US(HAL_CMU_PLL_LOCKED_TIMEOUT)); + + if (cfg >= HAL_CMU_LPU_CLK_QTY) { + return 1; + } + if ((timer_26m & (CMU_TIMER_WT26_MASK >> CMU_TIMER_WT26_SHIFT)) != timer_26m) { + return 2; + } + if ((timer_pll & (CMU_TIMER_WTPLL_MASK >> CMU_TIMER_WTPLL_SHIFT)) != timer_pll) { + return 3; + } + if (hal_cmu_lpu_busy()) { + return -1; + } + + if (cfg == HAL_CMU_LPU_CLK_26M) { + lpu_clk = CMU_LPU_AUTO_SWITCH26; + } else if (cfg == HAL_CMU_LPU_CLK_PLL) { + lpu_clk = CMU_LPU_AUTO_SWITCHPLL | CMU_LPU_AUTO_SWITCH26; + } else { + lpu_clk = 0; + } + + if (lpu_clk & CMU_LPU_AUTO_SWITCH26) { + // Disable RAM wakeup early + cmu->MCU_TIMER &= ~CMU_RAM_RETN_UP_EARLY; + // MCU/ROM/RAM auto clock gating (which depends on RAM gating signal) + cmu->HCLK_MODE &= ~(SYS_HCLK_MCU | SYS_HCLK_ROM0 | SYS_HCLK_ROM1 | SYS_HCLK_ROM2 | + SYS_HCLK_RAM0 | SYS_HCLK_RAM1 | SYS_HCLK_RAM2 | SYS_HCLK_RAMRET | SYS_HCLK_RAM3 | + SYS_HCLK_RAM4 | SYS_HCLK_RAM5 | SYS_HCLK_RAM6); + // AON_CMU enable auto switch 26M (AON_CMU must have selected 26M and disabled 52M/32K already) + aoncmu->CLK_SELECT |= AON_CMU_LPU_AUTO_SWITCH26; + } else { + // AON_CMU disable auto switch 26M + aoncmu->CLK_SELECT &= ~AON_CMU_LPU_AUTO_SWITCH26; + } + + cmu->WAKEUP_CLK_CFG = CMU_TIMER_WT26(timer_26m) | CMU_TIMER_WTPLL(0) | lpu_clk; + if (timer_pll) { + hal_sys_timer_delay(US_TO_TICKS(60)); + cmu->WAKEUP_CLK_CFG = CMU_TIMER_WT26(timer_26m) | CMU_TIMER_WTPLL(timer_pll) | lpu_clk; + } + return 0; +} + +#ifdef CORE_SLEEP_POWER_DOWN + +static int SRAM_TEXT_LOC hal_cmu_lpu_sleep_pd(void) +{ + uint32_t start; + uint32_t timeout; + uint32_t saved_hclk; + uint32_t saved_oclk; + uint32_t saved_top_clk; + uint32_t saved_clk_cfg; + uint32_t saved_periph_clk; + uint32_t saved_sys_div; + uint32_t saved_uart_clk; + uint32_t saved_codec_div; + uint32_t pll_locked; + uint32_t saved_cpu_regs[50]; + register uint32_t sp asm("sp"); + uint32_t stack_limit; + +#ifdef ROM_BUILD + extern uint32_t __rom_StackLimit[]; + stack_limit = (uint32_t)__rom_StackLimit; +#else + extern uint32_t __StackLimit[]; + stack_limit = (uint32_t)__StackLimit; +#endif + if (sp < stack_limit + 20 * 4) { + do { + asm volatile("nop; nop; nop; nop"); + } while (1); + } + + NVIC_PowerDownSleep(saved_cpu_regs, ARRAY_SIZE(saved_cpu_regs)); + + saved_hclk = cmu->HCLK_ENABLE; + saved_oclk = cmu->OCLK_ENABLE; + saved_periph_clk = cmu->PERIPH_CLK; + saved_sys_div = cmu->SYS_DIV; + saved_uart_clk = cmu->UART_CLK; + saved_codec_div = aoncmu->CODEC_DIV; + + saved_top_clk = aoncmu->TOP_CLK_ENABLE; + saved_clk_cfg = cmu->SYS_CLK_ENABLE; + + // Switch VAD clock to AON and disable codec HCLK + aoncmu->CODEC_DIV |= AON_CMU_SEL_CODEC_HCLK_AON; + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_CODEC_HCLK_DISABLE; + + // Disable memory/flash clock + cmu->OCLK_DISABLE = SYS_OCLK_FLASH; + cmu->HCLK_DISABLE = SYS_HCLK_FLASH; + +#ifndef ROM_BUILD + // Reset pll div if pll is enabled + if (saved_top_clk & AON_CMU_PU_PLLAUD_ENABLE) { + pmu_pll_div_reset_set(HAL_CMU_PLL_AUD); + } + if (saved_top_clk & AON_CMU_PU_PLLBB_ENABLE) { + pmu_pll_div_reset_set(HAL_CMU_PLL_USB); + } +#endif + + // Switch system freq to 26M + cmu->SYS_CLK_ENABLE = CMU_SEL_OSC_SYS_ENABLE; + cmu->SYS_CLK_DISABLE = CMU_SEL_OSCX2_SYS_DISABLE | CMU_SEL_PLL_SYS_DISABLE; + cmu->SYS_CLK_DISABLE = CMU_RSTN_DIV_SYS_DISABLE; + + // Shutdown PLLs + if (saved_top_clk & AON_CMU_PU_PLLAUD_ENABLE) { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_PLLAUD_DISABLE; + aoncmu->TOP_CLK_DISABLE = AON_CMU_PU_PLLAUD_DISABLE; + } + if (saved_top_clk & AON_CMU_PU_PLLBB_ENABLE) { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_PLLBB_DISABLE; + aoncmu->TOP_CLK_DISABLE = AON_CMU_PU_PLLBB_DISABLE; + } + if (saved_top_clk & AON_CMU_PU_PLLUSB_ENABLE) { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_PLLUSB_DISABLE; + aoncmu->TOP_CLK_DISABLE = AON_CMU_PU_PLLUSB_DISABLE; + } + + // Set power down wakeup bootmode + aoncmu->BOOTMODE = (aoncmu->BOOTMODE | HAL_SW_BOOTMODE_POWER_DOWN_WAKEUP) & HAL_SW_BOOTMODE_MASK; + // Set AON_CMU clock to 32K + aoncmu->CODEC_DIV &= ~(AON_CMU_SEL_CLK_OSC | AON_CMU_SEL_CLK_OSCX2); + + hal_sleep_core_power_down(); + + while ((cmu->WAKEUP_CLK_CFG & CMU_LPU_STATUS_26M) == 0); + + // Restore AON_CMU clock + aoncmu->CODEC_DIV = saved_codec_div; + // Clear power down wakeup bootmode + aoncmu->BOOTMODE = (aoncmu->BOOTMODE & ~HAL_SW_BOOTMODE_POWER_DOWN_WAKEUP) & HAL_SW_BOOTMODE_MASK; + + // Disable memory/flash clock + cmu->OCLK_DISABLE = SYS_OCLK_FLASH; + cmu->HCLK_DISABLE = SYS_HCLK_FLASH; + + // Restore PLLs + if (saved_top_clk & (AON_CMU_PU_PLLAUD_ENABLE | AON_CMU_PU_PLLUSB_ENABLE | AON_CMU_PU_PLLBB_ENABLE)) { + pll_locked = 0; + if (saved_top_clk & AON_CMU_PU_PLLAUD_ENABLE) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_PU_PLLAUD_ENABLE; + pll_locked |= AON_CMU_LOCK_PLLAUD; + } + if (saved_top_clk & AON_CMU_PU_PLLBB_ENABLE) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_PU_PLLBB_ENABLE; + pll_locked |= AON_CMU_LOCK_PLLBB; + } + if (saved_top_clk & AON_CMU_PU_PLLUSB_ENABLE) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_PU_PLLUSB_ENABLE; + pll_locked |= AON_CMU_LOCK_PLLUSB; + } +#ifndef ROM_BUILD + hal_sys_timer_delay_us(10); + // Clear pll div reset if pll is enabled + if (saved_top_clk & AON_CMU_PU_PLLAUD_ENABLE) { + pmu_pll_div_reset_clear(HAL_CMU_PLL_AUD); + } + if (saved_top_clk & AON_CMU_PU_PLLBB_ENABLE) { + pmu_pll_div_reset_clear(HAL_CMU_PLL_USB); + } +#endif + start = hal_sys_timer_get(); + timeout = HAL_CMU_PLL_LOCKED_TIMEOUT; + while (//(aoncmu->CODEC_DIV & pll_locked) != pll_locked && + (hal_sys_timer_get() - start) < timeout); + if (saved_top_clk & AON_CMU_EN_CLK_TOP_PLLAUD_ENABLE) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_TOP_PLLAUD_ENABLE; + } + if (saved_top_clk & AON_CMU_EN_CLK_TOP_PLLBB_ENABLE) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_TOP_PLLBB_ENABLE; + } + if (saved_top_clk & AON_CMU_EN_CLK_TOP_PLLUSB_ENABLE) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_TOP_PLLUSB_ENABLE; + } + } + + // Restore system freq + cmu->SYS_CLK_ENABLE = saved_clk_cfg & + (CMU_RSTN_DIV_FLS_ENABLE | CMU_RSTN_DIV_SYS_ENABLE); + cmu->SYS_CLK_ENABLE = saved_clk_cfg; + // The original system freq are at least 26M + //cmu->SYS_CLK_DISABLE = ~saved_clk_cfg; + + cmu->PERIPH_CLK = saved_periph_clk; + cmu->SYS_DIV = saved_sys_div; + cmu->UART_CLK = saved_uart_clk; + + // Switch VAD clock to MCU and enable codec HCLK if it is on before entering sleep + //aoncmu->CODEC_DIV &= ~AON_CMU_SEL_CODEC_HCLK_AON; + aoncmu->TOP_CLK_ENABLE = saved_top_clk & AON_CMU_EN_CLK_CODEC_HCLK_ENABLE; + + int_lock(); + + NVIC_PowerDownWakeup(saved_cpu_regs, ARRAY_SIZE(saved_cpu_regs)); + + // TODO: + // 1) Restore hardware modules, e.g., timer, cache, flash, psram, dma, usb, uart, spi, i2c, sdmmc, codec + // 2) Recover system timer in rt_suspend() and rt_resume() + // 3) Dynamically select 32K sleep or power down sleep + + if (saved_oclk & SYS_OCLK_FLASH) { + // Enable memory/flash clock + cmu->HCLK_ENABLE = saved_hclk; + cmu->OCLK_ENABLE = saved_oclk; + // Wait until memory/flash clock ready + hal_sys_timer_delay_us(2); + } + + return 0; +} + +#endif + +__STATIC_FORCEINLINE void cpu_sleep(uint32_t wakeup_cfg) +{ + __DSB(); + + if (wakeup_cfg & (CMU_LPU_AUTO_SWITCHPLL | CMU_LPU_AUTO_SWITCH26)) { + // 1) Avoid race condition between LPU state machine entry and IRQ wakeup: + // wait 4 (at least 2) cycles of 32K clock, or 3248 cycles of 26M clock + // 2) Avoid race condition between CPU clock gating and RAM access when waiting: + // No consecutive RAM access is allowed (all instructions must be 16-bit and must have no data access) + asm volatile ( + "wfi;" + "movs.n r0, #0x3;" + "lsls r0, #8;" + "adds.n r0, #0x2c;" + "1:;" + "nop;" + "nop;" + "subs r0, 1;" + "bne.n 1b;" + : + : + : "r0", "cc" ); + } else { + __WFI(); + } +} + +static int SRAM_TEXT_LOC hal_cmu_lpu_sleep_normal(enum HAL_CMU_LPU_SLEEP_MODE_T mode) +{ + uint32_t start; + uint32_t timeout; + uint32_t saved_hclk; + uint32_t saved_oclk; + uint32_t saved_top_clk; + uint32_t saved_clk_cfg; + uint32_t saved_codec_div; + uint32_t wakeup_cfg; + bool pd_aud_pll; + bool pd_bb_pll; + bool wait_pll_locked; + + pd_aud_pll = true; + pd_bb_pll = true; + + saved_hclk = cmu->HCLK_ENABLE; + saved_oclk = cmu->OCLK_ENABLE; + saved_codec_div = aoncmu->CODEC_DIV; + saved_top_clk = aoncmu->TOP_CLK_ENABLE; + saved_clk_cfg = cmu->SYS_CLK_ENABLE; + + if (mode == HAL_CMU_LPU_SLEEP_MODE_CHIP) { + wakeup_cfg = cmu->WAKEUP_CLK_CFG; + } else { + wakeup_cfg = 0; + if (pll_user_map[HAL_CMU_PLL_AUD] & (1 << HAL_CMU_PLL_USER_AUD)) { + pd_aud_pll = false; + } + if (pll_user_map[HAL_CMU_PLL_USB] & (1 << HAL_CMU_PLL_USER_AUD)) { + pd_bb_pll = false; + } + } + + // Switch VAD clock to AON and disable codec HCLK + aoncmu->CODEC_DIV |= AON_CMU_SEL_CODEC_HCLK_AON; + if (mode == HAL_CMU_LPU_SLEEP_MODE_CHIP) { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_CODEC_HCLK_DISABLE; + } + + // Disable memory/flash clock + cmu->OCLK_DISABLE = SYS_OCLK_FLASH; + cmu->HCLK_DISABLE = SYS_HCLK_FLASH; + +#ifndef ROM_BUILD + // Reset pll div if pll is enabled + if (pd_aud_pll && (saved_top_clk & AON_CMU_PU_PLLAUD_ENABLE)) { + pmu_pll_div_reset_set(HAL_CMU_PLL_AUD); + } + if (pd_bb_pll && (saved_top_clk & AON_CMU_PU_PLLBB_ENABLE)) { + pmu_pll_div_reset_set(HAL_CMU_PLL_USB); + } +#endif + + // Setup wakeup mask + cmu->WAKEUP_MASK0 = NVIC->ISER[0]; + cmu->WAKEUP_MASK1 = NVIC->ISER[1]; + + if (wakeup_cfg & CMU_LPU_AUTO_SWITCHPLL) { + // Do nothing + // Hardware will switch system freq to 32K and shutdown PLLs automatically + } else { + // Switch system freq to 26M + cmu->SYS_CLK_ENABLE = CMU_SEL_OSC_SYS_ENABLE; + cmu->SYS_CLK_DISABLE = CMU_SEL_OSCX2_SYS_DISABLE | CMU_SEL_PLL_SYS_DISABLE; + cmu->SYS_CLK_DISABLE = CMU_RSTN_DIV_SYS_DISABLE; + // Shutdown PLLs + if (pd_aud_pll && (saved_top_clk & AON_CMU_PU_PLLAUD_ENABLE)) { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_PLLAUD_DISABLE; + aoncmu->TOP_CLK_DISABLE = AON_CMU_PU_PLLAUD_DISABLE; + } + if (pd_bb_pll && (saved_top_clk & AON_CMU_PU_PLLBB_ENABLE)) { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_PLLBB_DISABLE; + aoncmu->TOP_CLK_DISABLE = AON_CMU_PU_PLLBB_DISABLE; + } + if (saved_top_clk & AON_CMU_PU_PLLUSB_ENABLE) { + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_TOP_PLLUSB_DISABLE; + aoncmu->TOP_CLK_DISABLE = AON_CMU_PU_PLLUSB_DISABLE; + } + if (wakeup_cfg & CMU_LPU_AUTO_SWITCH26) { + // Do nothing + // Hardware will switch system freq to 32K automatically + } else { + // Manually switch AON_CMU clock to 32K + aoncmu->CODEC_DIV &= ~(AON_CMU_SEL_CLK_OSC | AON_CMU_SEL_CLK_OSCX2); + // Switch system freq to 32K + cmu->SYS_CLK_DISABLE = CMU_SEL_OSC_SYS_DISABLE; + } + } + + if (wakeup_cfg & CMU_LPU_AUTO_SWITCH26) { + // Enable auto memory retention + cmu->SLEEP = (cmu->SLEEP & ~CMU_MANUAL_RAM_RETN) | + CMU_DEEPSLEEP_EN | CMU_DEEPSLEEP_ROMRAM_EN | CMU_DEEPSLEEP_START; + } else { + // Disable auto memory retention + cmu->SLEEP = (cmu->SLEEP & ~CMU_DEEPSLEEP_ROMRAM_EN) | + CMU_DEEPSLEEP_EN | CMU_MANUAL_RAM_RETN | CMU_DEEPSLEEP_START; + } + + if (mode == HAL_CMU_LPU_SLEEP_MODE_CHIP) { + SCB->SCR = SCB_SCR_SLEEPDEEP_Msk; + } else { + SCB->SCR = 0; + } + + cpu_sleep(wakeup_cfg); + + if (wakeup_cfg & CMU_LPU_AUTO_SWITCHPLL) { + start = hal_sys_timer_get(); + timeout = HAL_CMU_26M_READY_TIMEOUT + HAL_CMU_PLL_LOCKED_TIMEOUT + HAL_CMU_LPU_EXTRA_TIMEOUT; + while ((cmu->WAKEUP_CLK_CFG & CMU_LPU_STATUS_PLL) == 0 && + (hal_sys_timer_get() - start) < timeout); + // !!! CAUTION !!! + // Hardware will switch system freq to PLL divider and enable PLLs automatically +#ifndef ROM_BUILD + hal_sys_timer_delay_us(10); + // Clear pll div reset if pll is enabled + if (saved_top_clk & AON_CMU_PU_PLLAUD_ENABLE) { + pmu_pll_div_reset_clear(HAL_CMU_PLL_AUD); + } + if (saved_top_clk & AON_CMU_PU_PLLBB_ENABLE) { + pmu_pll_div_reset_clear(HAL_CMU_PLL_USB); + } +#endif + } else { + // Wait for 26M ready + if (wakeup_cfg & CMU_LPU_AUTO_SWITCH26) { + start = hal_sys_timer_get(); + timeout = HAL_CMU_26M_READY_TIMEOUT + HAL_CMU_LPU_EXTRA_TIMEOUT; + while ((cmu->WAKEUP_CLK_CFG & CMU_LPU_STATUS_26M) == 0 && + (hal_sys_timer_get() - start) < timeout); + // Hardware will switch system freq to 26M automatically + } else { + if (mode == HAL_CMU_LPU_SLEEP_MODE_CHIP) { + timeout = HAL_CMU_26M_READY_TIMEOUT; + hal_sys_timer_delay(timeout); + } + // Switch system freq to 26M + cmu->SYS_CLK_ENABLE = CMU_SEL_OSC_SYS_ENABLE; + // Restore AON_CMU clock + aoncmu->CODEC_DIV = saved_codec_div; + } + // System freq is 26M now and will be restored later + // Restore PLLs + if (saved_top_clk & (AON_CMU_PU_PLLAUD_ENABLE | AON_CMU_PU_PLLUSB_ENABLE | AON_CMU_PU_PLLBB_ENABLE)) { + wait_pll_locked = false; + if (pd_aud_pll && (saved_top_clk & AON_CMU_PU_PLLAUD_ENABLE)) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_PU_PLLAUD_ENABLE; + wait_pll_locked = true; + } + if (pd_bb_pll && (saved_top_clk & AON_CMU_PU_PLLBB_ENABLE)) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_PU_PLLBB_ENABLE; + wait_pll_locked = true; + } + if (saved_top_clk & AON_CMU_PU_PLLUSB_ENABLE) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_PU_PLLUSB_ENABLE; + wait_pll_locked = true; + } + if (wait_pll_locked) { +#ifndef ROM_BUILD + hal_sys_timer_delay_us(10); + // Clear pll div reset if pll is enabled + if (pd_aud_pll && (saved_top_clk & AON_CMU_PU_PLLAUD_ENABLE)) { + pmu_pll_div_reset_clear(HAL_CMU_PLL_AUD); + } + if (pd_bb_pll && (saved_top_clk & AON_CMU_PU_PLLBB_ENABLE)) { + pmu_pll_div_reset_clear(HAL_CMU_PLL_USB); + } +#endif + start = hal_sys_timer_get(); + timeout = HAL_CMU_PLL_LOCKED_TIMEOUT; + while ((hal_sys_timer_get() - start) < timeout); + } + if (pd_aud_pll && (saved_top_clk & AON_CMU_EN_CLK_TOP_PLLAUD_ENABLE)) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_TOP_PLLAUD_ENABLE; + } + if (pd_bb_pll && (saved_top_clk & AON_CMU_EN_CLK_TOP_PLLBB_ENABLE)) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_TOP_PLLBB_ENABLE; + } + if (saved_top_clk & AON_CMU_EN_CLK_TOP_PLLUSB_ENABLE) { + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_TOP_PLLUSB_ENABLE; + } + } + } + + // Restore system freq + cmu->SYS_CLK_ENABLE = saved_clk_cfg & + (CMU_RSTN_DIV_FLS_ENABLE | CMU_RSTN_DIV_SYS_ENABLE); + cmu->SYS_CLK_ENABLE = saved_clk_cfg; + // The original system freq are at least 26M + //cmu->SYS_CLK_DISABLE = ~saved_clk_cfg; + + // Switch VAD clock to MCU and enable codec HCLK if it is on before entering sleep + aoncmu->CODEC_DIV &= ~AON_CMU_SEL_CODEC_HCLK_AON; + if (mode == HAL_CMU_LPU_SLEEP_MODE_CHIP) { + aoncmu->TOP_CLK_ENABLE = saved_top_clk & AON_CMU_EN_CLK_CODEC_HCLK_ENABLE; + } + + if (saved_oclk & SYS_OCLK_FLASH) { + // Enable memory/flash clock + cmu->HCLK_ENABLE = saved_hclk; + cmu->OCLK_ENABLE = saved_oclk; + // Wait until memory/flash clock ready + hal_sys_timer_delay_us(2); + } + + return 0; +} + +int SRAM_TEXT_LOC hal_cmu_lpu_sleep(enum HAL_CMU_LPU_SLEEP_MODE_T mode) +{ +#ifdef CORE_SLEEP_POWER_DOWN + if (mode == HAL_CMU_LPU_SLEEP_MODE_POWER_DOWN) { + return hal_cmu_lpu_sleep_pd(); + } +#endif + return hal_cmu_lpu_sleep_normal(mode); +} + +volatile uint32_t *hal_cmu_get_bootmode_addr(void) +{ + return &aoncmu->BOOTMODE; +} + +SRAM_TEXT_LOC +volatile uint32_t *hal_cmu_get_memsc_addr(void) +{ + return &aoncmu->MEMSC[0]; +} + +void hal_cmu_bt_clock_enable(void) +{ + aoncmu->TOP_CLK_ENABLE = AON_CMU_EN_CLK_OSCX2_BT_ENABLE | AON_CMU_EN_CLK_OSC_BT_ENABLE | AON_CMU_EN_CLK_32K_BT_ENABLE; + aocmu_reg_update_wait(); +} + +void hal_cmu_bt_clock_disable(void) +{ + aoncmu->TOP_CLK_DISABLE = AON_CMU_EN_CLK_OSCX2_BT_DISABLE | AON_CMU_EN_CLK_OSC_BT_DISABLE | AON_CMU_EN_CLK_32K_BT_DISABLE; +} + +void hal_cmu_bt_reset_set(void) +{ + aoncmu->RESET_SET = AON_CMU_SOFT_RSTN_BT_SET | AON_CMU_SOFT_RSTN_BTCPU_SET; +} + +void hal_cmu_bt_reset_clear(void) +{ + aoncmu->RESET_CLR = AON_CMU_SOFT_RSTN_BT_CLR | AON_CMU_SOFT_RSTN_BTCPU_CLR; + aocmu_reg_update_wait(); +} + +void hal_cmu_bt_module_init(void) +{ + //btcmu->CLK_MODE = 0; +} + +uint32_t hal_cmu_get_aon_chip_id(void) +{ + return aoncmu->CHIP_ID; +} + +uint32_t hal_cmu_get_aon_revision_id(void) +{ + return GET_BITFIELD(aoncmu->CHIP_ID, AON_CMU_REVISION_ID); +} + +void hal_cmu_cp_enable(uint32_t sp, uint32_t entry) +{ + cp_cfg->stack = sp; + cp_cfg->reset_hdlr = (uint32_t)system_cp_reset_handler; + cp_cfg->entry = entry; + + hal_cmu_clock_enable(HAL_CMU_MOD_H_CP); + hal_cmu_reset_clear(HAL_CMU_MOD_H_CP); +} + +void hal_cmu_cp_disable(void) +{ + hal_cmu_reset_set(HAL_CMU_MOD_H_CP); + hal_cmu_clock_disable(HAL_CMU_MOD_H_CP); +} + +uint32_t hal_cmu_cp_get_entry_addr(void) +{ + return cp_cfg->entry; +} + diff --git a/platform/hal/best2300p/hal_cmu_best2300p.h b/platform/hal/best2300p/hal_cmu_best2300p.h new file mode 100644 index 0000000..864364e --- /dev/null +++ b/platform/hal/best2300p/hal_cmu_best2300p.h @@ -0,0 +1,265 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_CMU_BEST2300P_H__ +#define __HAL_CMU_BEST2300P_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define HAL_CMU_VALID_CRYSTAL_FREQ { 26000000, 24000000, 40000000, 48000000, } + +enum HAL_CMU_MOD_ID_T { + // HCLK/HRST + HAL_CMU_MOD_H_MCU, // 0 + HAL_CMU_MOD_H_ROM0, // 1 + HAL_CMU_MOD_H_ROM1, // 2 + HAL_CMU_MOD_H_ROM2, // 3 + HAL_CMU_MOD_H_RAM0, // 4 + HAL_CMU_MOD_H_RAM1, // 5 + HAL_CMU_MOD_H_RAM2, // 6 + HAL_CMU_MOD_H_RAMRET, // 7 + HAL_CMU_MOD_H_AHB0, // 8 + HAL_CMU_MOD_H_AHB1, // 9 + HAL_CMU_MOD_H_AH2H_BT, // 10 + HAL_CMU_MOD_H_ADMA, // 11 + HAL_CMU_MOD_H_GDMA, // 12 + HAL_CMU_MOD_H_CACHE, // 13 + HAL_CMU_MOD_H_FLASH, // 14 + HAL_CMU_MOD_H_SDMMC, // 15 + HAL_CMU_MOD_H_USBC, // 16 + HAL_CMU_MOD_H_CODEC, // 17 + HAL_CMU_MOD_H_FFT, // 18 + HAL_CMU_MOD_H_I2C_SLAVE, // 19 + HAL_CMU_MOD_H_USBH, // 20 + HAL_CMU_MOD_H_SENSOR_ENG, // 21 + HAL_CMU_MOD_H_BT_DUMP, // 22 + HAL_CMU_MOD_H_CP, // 23 + HAL_CMU_MOD_H_RAM3, // 24 + HAL_CMU_MOD_H_RAM4, // 25 + HAL_CMU_MOD_H_RAM5, // 26 + HAL_CMU_MOD_H_RAM6, // 27 + HAL_CMU_MOD_H_SEC_ENG, // 28 + HAL_CMU_MOD_H_ICACHE0, // 29 + HAL_CMU_MOD_H_ICACHE1, // 30 + // PCLK/PRST + HAL_CMU_MOD_P_CMU, // 31 + HAL_CMU_MOD_P_WDT, // 32 + HAL_CMU_MOD_P_TIMER0, // 33 + HAL_CMU_MOD_P_TIMER1, // 34 + HAL_CMU_MOD_P_TIMER2, // 35 + HAL_CMU_MOD_P_I2C0, // 36 + HAL_CMU_MOD_P_I2C1, // 37 + HAL_CMU_MOD_P_SPI, // 38 + HAL_CMU_MOD_P_SLCD, // 39 + HAL_CMU_MOD_P_SPI_ITN, // 40 + HAL_CMU_MOD_P_SPI_PHY, // 41 + HAL_CMU_MOD_P_UART0, // 42 + HAL_CMU_MOD_P_UART1, // 43 + HAL_CMU_MOD_P_UART2, // 44 + HAL_CMU_MOD_P_PCM, // 45 + HAL_CMU_MOD_P_I2S0, // 46 + HAL_CMU_MOD_P_SPDIF0, // 47 + HAL_CMU_MOD_P_I2S1, // 48 + HAL_CMU_MOD_P_SEC_ENG, // 49 + // OCLK/ORST + HAL_CMU_MOD_O_SLEEP, // 50 + HAL_CMU_MOD_O_FLASH, // 51 + HAL_CMU_MOD_O_USB, // 52 + HAL_CMU_MOD_O_SDMMC, // 53 + HAL_CMU_MOD_O_WDT, // 54 + HAL_CMU_MOD_O_TIMER0, // 55 + HAL_CMU_MOD_O_TIMER1, // 56 + HAL_CMU_MOD_O_TIMER2, // 57 + HAL_CMU_MOD_O_I2C0, // 58 + HAL_CMU_MOD_O_I2C1, // 59 + HAL_CMU_MOD_O_SPI, // 60 + HAL_CMU_MOD_O_SLCD, // 61 + HAL_CMU_MOD_O_SPI_ITN, // 62 + HAL_CMU_MOD_O_SPI_PHY, // 63 + HAL_CMU_MOD_O_UART0, // 64 + HAL_CMU_MOD_O_UART1, // 65 + HAL_CMU_MOD_O_UART2, // 66 + HAL_CMU_MOD_O_I2S0, // 67 + HAL_CMU_MOD_O_SPDIF0, // 68 + HAL_CMU_MOD_O_PCM, // 69 + HAL_CMU_MOD_O_USB32K, // 70 + HAL_CMU_MOD_O_I2S1, // 71 + + // AON ACLK/ARST + HAL_CMU_AON_A_CMU, // 72 + HAL_CMU_AON_A_GPIO, // 73 + HAL_CMU_AON_A_GPIO_INT, // 74 + HAL_CMU_AON_A_WDT, // 75 + HAL_CMU_AON_A_PWM, // 76 + HAL_CMU_AON_A_TIMER, // 77 + HAL_CMU_AON_A_PSC, // 78 + HAL_CMU_AON_A_IOMUX, // 79 + HAL_CMU_AON_A_APBC, // 80 + HAL_CMU_AON_A_H2H_MCU, // 81 + // AON OCLK/ORST + HAL_CMU_AON_O_WDT, // 82 + HAL_CMU_AON_O_TIMER, // 83 + HAL_CMU_AON_O_GPIO, // 84 + HAL_CMU_AON_O_PWM0, // 85 + HAL_CMU_AON_O_PWM1, // 86 + HAL_CMU_AON_O_PWM2, // 87 + HAL_CMU_AON_O_PWM3, // 88 + HAL_CMU_AON_O_IOMUX, // 89 + HAL_CMU_AON_O_SLP32K, // 90 + HAL_CMU_AON_O_SLP26M, // 91 + HAL_CMU_AON_RESERVED0, // 92 + HAL_CMU_AON_RESERVED1, // 93 + HAL_CMU_AON_RESERVED2, // 94 + HAL_CMU_AON_RESERVED3, // 95 + // AON SUBSYS + HAL_CMU_AON_MCU, // 96 + HAL_CMU_AON_CODEC, // 97 + HAL_CMU_AON_RESERVED4, // 98 + HAL_CMU_AON_BT, // 99 + HAL_CMU_AON_MCUCPU, // 100 + HAL_CMU_AON_RESERVED5, // 101 + HAL_CMU_AON_BTCPU, // 102 + HAL_CMU_AON_GLOBAL, // 103 + + HAL_CMU_MOD_QTY, + + HAL_CMU_MOD_GLOBAL = HAL_CMU_AON_GLOBAL, + HAL_CMU_MOD_BT = HAL_CMU_AON_BT, + HAL_CMU_MOD_BTCPU = HAL_CMU_AON_BTCPU, + + HAL_CMU_MOD_P_PWM = HAL_CMU_AON_A_PWM, + HAL_CMU_MOD_O_PWM0 = HAL_CMU_AON_O_PWM0, + HAL_CMU_MOD_O_PWM1 = HAL_CMU_AON_O_PWM1, + HAL_CMU_MOD_O_PWM2 = HAL_CMU_AON_O_PWM2, + HAL_CMU_MOD_O_PWM3 = HAL_CMU_AON_O_PWM3, + + HAL_CMU_H_ICACHECP = HAL_CMU_MOD_H_ICACHE0, + HAL_CMU_H_DCACHECP = HAL_CMU_MOD_QTY, + + // TO BE REMOVED + HAL_CMU_MOD_P_CODEC = HAL_CMU_MOD_QTY, + HAL_CMU_MOD_O_CODEC_DA = HAL_CMU_MOD_QTY, + HAL_CMU_MOD_O_CODEC_AD = HAL_CMU_MOD_QTY, +}; + +enum HAL_CMU_CLOCK_OUT_ID_T { + HAL_CMU_CLOCK_OUT_AON_32K = 0x00, + HAL_CMU_CLOCK_OUT_AON_26M = 0x01, + HAL_CMU_CLOCK_OUT_AON_52M = 0x02, + HAL_CMU_CLOCK_OUT_AON_DIG_52M = 0x03, + HAL_CMU_CLOCK_OUT_AON_DIG_104M = 0x04, + HAL_CMU_CLOCK_OUT_AON_PER = 0x05, + HAL_CMU_CLOCK_OUT_AON_USB = 0x06, + HAL_CMU_CLOCK_OUT_AON_DCDC = 0x07, + HAL_CMU_CLOCK_OUT_AON_CHCLK = 0x08, + HAL_CMU_CLOCK_OUT_AON_SPDIF0 = 0x09, + HAL_CMU_CLOCK_OUT_AON_MCU = 0x0A, + HAL_CMU_CLOCK_OUT_AON_FLASH = 0x0B, + HAL_CMU_CLOCK_OUT_AON_SYS = 0x0C, + + HAL_CMU_CLOCK_OUT_BT_32K = 0x40, + HAL_CMU_CLOCK_OUT_BT_SYS = 0x41, + HAL_CMU_CLOCK_OUT_BT_52M = 0x42, + HAL_CMU_CLOCK_OUT_BT_26MI = 0x43, + HAL_CMU_CLOCK_OUT_BT_13M = 0x44, + HAL_CMU_CLOCK_OUT_BT_12M = 0x45, + HAL_CMU_CLOCK_OUT_BT_ADC = 0x46, + HAL_CMU_CLOCK_OUT_BT_ADC2 = 0x47, + HAL_CMU_CLOCK_OUT_BT_24M = 0x48, + HAL_CMU_CLOCK_OUT_BT_26M = 0x49, + + HAL_CMU_CLOCK_OUT_MCU_32K = 0x60, + HAL_CMU_CLOCK_OUT_MCU_SYS = 0x61, + HAL_CMU_CLOCK_OUT_MCU_FLASH = 0x62, + HAL_CMU_CLOCK_OUT_MCU_USB = 0x63, + HAL_CMU_CLOCK_OUT_MCU_PCLK = 0x64, + HAL_CMU_CLOCK_OUT_MCU_I2S = 0x65, + HAL_CMU_CLOCK_OUT_MCU_PCM = 0x66, + HAL_CMU_CLOCK_OUT_MCU_SPDIF0 = 0x67, + HAL_CMU_CLOCK_OUT_MCU_SDMMC = 0x68, + HAL_CMU_CLOCK_OUT_MCU_SPI2 = 0x69, + HAL_CMU_CLOCK_OUT_MCU_SPI0 = 0x6A, + HAL_CMU_CLOCK_OUT_MCU_SPI1 = 0x6B, + + HAL_CMU_CLOCK_OUT_CODEC_ADC_ANA = 0x80, + HAL_CMU_CLOCK_OUT_CODEC_CODEC = 0x81, + HAL_CMU_CLOCK_OUT_CODEC_IIR = 0x82, + HAL_CMU_CLOCK_OUT_CODEC_RS = 0x83, + HAL_CMU_CLOCK_OUT_CODEC_HCLK = 0x84, +}; + +enum HAL_CMU_I2S_MCLK_ID_T { + HAL_CMU_I2S_MCLK_PLLCODEC = 0x00, + HAL_CMU_I2S_MCLK_CODEC = 0x01, + HAL_CMU_I2S_MCLK_PLLIIR = 0x02, + HAL_CMU_I2S_MCLK_PLLRS = 0x03, + HAL_CMU_I2S_MCLK_PLLSPDIF0 = 0x04, + HAL_CMU_I2S_MCLK_PLLPCM = 0x05, + HAL_CMU_I2S_MCLK_PER = 0x06, + HAL_CMU_I2S_MCLK_CLK_OUT = 0x07, +}; + +enum HAL_I2S_ID_T { + HAL_I2S_ID_0 = 0, + HAL_I2S_ID_1, + + HAL_I2S_ID_QTY, +}; +#define HAL_I2S_ID_T HAL_I2S_ID_T + +enum HAL_CMU_ANC_CLK_USER_T { + HAL_CMU_ANC_CLK_USER_ANC, + + HAL_CMU_ANC_CLK_USER_QTY +}; + +enum HAL_CMU_LOW_SYS_FREQ_T { + HAL_CMU_LOW_SYS_FREQ_NONE, + HAL_CMU_LOW_SYS_FREQ_13M, + HAL_CMU_LOW_SYS_FREQ_6P5M, + HAL_CMU_LOW_SYS_FREQ_4P33M, + HAL_CMU_LOW_SYS_FREQ_3P25M, +}; + +void hal_cmu_low_sys_clock_set(enum HAL_CMU_LOW_SYS_FREQ_T freq); + +int hal_cmu_fast_timer_offline(void); + +void hal_cmu_anc_enable(enum HAL_CMU_ANC_CLK_USER_T user); + +void hal_cmu_anc_disable(enum HAL_CMU_ANC_CLK_USER_T user); + +int hal_cmu_anc_get_status(enum HAL_CMU_ANC_CLK_USER_T user); + +void hal_cmu_codec_vad_clock_enable(uint32_t enabled); + +uint32_t hal_cmu_get_aon_chip_id(void); + +uint32_t hal_cmu_get_aon_revision_id(void); + +void hal_cmu_cp_enable(uint32_t sp, uint32_t entry); + +void hal_cmu_cp_disable(void); + +uint32_t hal_cmu_cp_get_entry_addr(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/best2300p/hal_codec_best2300p.c b/platform/hal/best2300p/hal_codec_best2300p.c new file mode 100644 index 0000000..ecb006d --- /dev/null +++ b/platform/hal/best2300p/hal_codec_best2300p.c @@ -0,0 +1,4197 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include CHIP_SPECIFIC_HDR(reg_codec) +#include "hal_codec.h" +#include "hal_cmu.h" +#include "hal_psc.h" +#include "hal_aud.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "analog.h" +#include "cmsis.h" +#include "string.h" +#include "tgt_hardware.h" +#ifdef RTOS +#include "cmsis_os.h" +#endif +#include "hal_chipid.h" + +#define NO_DAC_RESET + +#define SDM_MUTE_NOISE_SUPPRESSION + +#ifndef CODEC_OUTPUT_DEV +#define CODEC_OUTPUT_DEV CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV +#endif +#if ((CODEC_OUTPUT_DEV & CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV) == 0) +#ifndef AUDIO_OUTPUT_SWAP +#define AUDIO_OUTPUT_SWAP +#endif +#endif + +#if (defined(__TWS__) || defined(IBRT)) && defined(ANC_APP) +//#define CODEC_TIMER +#endif + +#ifdef CODEC_DSD +#ifdef ANC_APP +#error "ANC_APP conflicts with CODEC_DSD" +#endif +#ifdef AUDIO_ANC_FB_MC +#error "AUDIO_ANC_FB_MC conflicts with CODEC_DSD" +#endif +#ifdef __AUDIO_RESAMPLE__ +#error "__AUDIO_RESAMPLE__ conflicts with CODEC_DSD" +#endif +#endif + +#define RS_CLOCK_FACTOR 200 + +// Trigger DMA request when TX-FIFO *empty* count > threshold +#define HAL_CODEC_TX_FIFO_TRIGGER_LEVEL (3) +// Trigger DMA request when RX-FIFO count >= threshold +#define HAL_CODEC_RX_FIFO_TRIGGER_LEVEL (4) + +#define MAX_DIG_DBVAL (50) +#define ZERODB_DIG_DBVAL (0) +#define MIN_DIG_DBVAL (-99) + +#define MAX_SIDETONE_DBVAL (30) +#define MIN_SIDETONE_DBVAL (-30) +#define SIDETONE_DBVAL_STEP (-2) + +#define MAX_SIDETONE_REGVAL (0) +#define MIN_SIDETONE_REGVAL (30) +#define MUTE_SIDETONE_REGVAL (31) + +#ifndef MC_DELAY_COMMON +#define MC_DELAY_COMMON 28 +#endif + +#ifndef CODEC_DIGMIC_PHASE +#define CODEC_DIGMIC_PHASE 7 +#endif + +#define ADC_IIR_CH_NUM 2 + +#define MAX_DIG_MIC_CH_NUM 5 + +#define NORMAL_ADC_CH_NUM 5 +// Echo cancel ADC channel number +#define EC_ADC_CH_NUM 2 +#define MAX_ADC_CH_NUM (NORMAL_ADC_CH_NUM + EC_ADC_CH_NUM) + +#define MAX_DAC_CH_NUM 2 + +#ifdef CODEC_DSD +#define NORMAL_MIC_MAP (AUD_CHANNEL_MAP_NORMAL_ALL & ~(AUD_CHANNEL_MAP_CH5 | AUD_CHANNEL_MAP_CH6 | AUD_CHANNEL_MAP_CH7 | \ + AUD_CHANNEL_MAP_DIGMIC_CH5 | AUD_CHANNEL_MAP_DIGMIC_CH6 | AUD_CHANNEL_MAP_DIGMIC_CH7 | \ + AUD_CHANNEL_MAP_DIGMIC_CH2 | AUD_CHANNEL_MAP_DIGMIC_CH3)) +#else +#define NORMAL_MIC_MAP (AUD_CHANNEL_MAP_NORMAL_ALL & ~(AUD_CHANNEL_MAP_CH5 | AUD_CHANNEL_MAP_CH6 | AUD_CHANNEL_MAP_CH7 | \ + AUD_CHANNEL_MAP_DIGMIC_CH5 | AUD_CHANNEL_MAP_DIGMIC_CH6 | AUD_CHANNEL_MAP_DIGMIC_CH7)) +#endif +#define NORMAL_ADC_MAP (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1 | AUD_CHANNEL_MAP_CH2 | AUD_CHANNEL_MAP_CH3 | AUD_CHANNEL_MAP_CH4) + +#define EC_MIC_MAP (AUD_CHANNEL_MAP_ECMIC_CH0 | AUD_CHANNEL_MAP_ECMIC_CH1) +#define EC_ADC_MAP (AUD_CHANNEL_MAP_CH5 | AUD_CHANNEL_MAP_CH6) + +#define VALID_MIC_MAP (NORMAL_MIC_MAP | EC_MIC_MAP) +#define VALID_ADC_MAP (NORMAL_ADC_MAP | EC_ADC_MAP) + +#define VALID_SPK_MAP (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1) +#define VALID_DAC_MAP VALID_SPK_MAP + +#if (CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV & ~VALID_SPK_MAP) +#error "Invalid CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV" +#endif +#if (CODEC_OUTPUT_DEV & ~VALID_SPK_MAP) +#error "Invalid CODEC_OUTPUT_DEV" +#endif + +#define RSTN_ADC_FREE_RUNNING_CLK CODEC_SOFT_RSTN_ADC(1 << NORMAL_ADC_CH_NUM) + +#if defined(SPEECH_SIDETONE) && \ + (defined(CFG_HW_AUD_SIDETONE_MIC_DEV) && (CFG_HW_AUD_SIDETONE_MIC_DEV)) && \ + defined(CFG_HW_AUD_SIDETONE_GAIN_DBVAL) +#define SIDETONE_ENABLE +#if (CFG_HW_AUD_SIDETONE_GAIN_DBVAL > MAX_SIDETONE_DBVAL) || \ + (CFG_HW_AUD_SIDETONE_GAIN_DBVAL < MIN_SIDETONE_DBVAL) || \ + defined(CFG_HW_AUD_SIDETONE_IIR_INDEX) || \ + defined(CFG_HW_AUD_SIDETONE_GAIN_RAMP) +#define SIDETONE_DEDICATED_ADC_CHAN +#define SIDETONE_RESERVED_ADC_CHAN +#endif +#endif + +enum CODEC_ADC_EN_REQ_T { + CODEC_ADC_EN_REQ_STREAM, + CODEC_ADC_EN_REQ_MC, + CODEC_ADC_EN_REQ_DSD, + + CODEC_ADC_EN_REQ_QTY, +}; + +enum CODEC_IRQ_TYPE_T { + CODEC_IRQ_TYPE_BT_TRIGGER, + CODEC_IRQ_TYPE_VAD, + CODEC_IRQ_TYPE_ANC_FB_CHECK, + + CODEC_IRQ_TYPE_QTY, +}; + +struct CODEC_DAC_DRE_CFG_T { + uint8_t dre_delay; + uint8_t thd_db_offset; + uint8_t step_mode; + uint32_t dre_win; + uint16_t amp_high; +}; + +struct CODEC_DAC_SAMPLE_RATE_T { + enum AUD_SAMPRATE_T sample_rate; + uint32_t codec_freq; + uint8_t codec_div; + uint8_t cmu_div; + uint8_t dac_up; + uint8_t bypass_cnt; + uint8_t mc_delay; +}; + +static const struct CODEC_DAC_SAMPLE_RATE_T codec_dac_sample_rate[] = { +#ifdef __AUDIO_RESAMPLE__ + {AUD_SAMPRATE_8463, CODEC_FREQ_CRYSTAL, 1, 1, 6, 0, MC_DELAY_COMMON + 160}, + {AUD_SAMPRATE_16927, CODEC_FREQ_CRYSTAL, 1, 1, 3, 0, MC_DELAY_COMMON + 85}, + {AUD_SAMPRATE_50781, CODEC_FREQ_CRYSTAL, 1, 1, 1, 0, MC_DELAY_COMMON + 29}, +#endif + {AUD_SAMPRATE_7350, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 6, 0, MC_DELAY_COMMON + 174}, + {AUD_SAMPRATE_8000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 6, 0, MC_DELAY_COMMON + 168}, // T + {AUD_SAMPRATE_14700, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 3, 0, MC_DELAY_COMMON + 71}, + {AUD_SAMPRATE_16000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 3, 0, MC_DELAY_COMMON + 88}, // T + {AUD_SAMPRATE_22050, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 2, 0, MC_DELAY_COMMON + 60}, + {AUD_SAMPRATE_24000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 2, 0, MC_DELAY_COMMON + 58}, + {AUD_SAMPRATE_44100, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 0, MC_DELAY_COMMON + 31}, // T + {AUD_SAMPRATE_48000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 0, MC_DELAY_COMMON + 30}, // T + {AUD_SAMPRATE_88200, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 1, MC_DELAY_COMMON + 12}, + {AUD_SAMPRATE_96000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 1, MC_DELAY_COMMON + 12}, // T + {AUD_SAMPRATE_176400, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 2, MC_DELAY_COMMON + 5}, + {AUD_SAMPRATE_192000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 2, MC_DELAY_COMMON + 5}, + {AUD_SAMPRATE_352800, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 3, MC_DELAY_COMMON + 2}, + {AUD_SAMPRATE_384000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 3, MC_DELAY_COMMON + 2}, +}; + +struct CODEC_ADC_SAMPLE_RATE_T { + enum AUD_SAMPRATE_T sample_rate; + uint32_t codec_freq; + uint8_t codec_div; + uint8_t cmu_div; + uint8_t adc_down; + uint8_t bypass_cnt; +}; + +static const struct CODEC_ADC_SAMPLE_RATE_T codec_adc_sample_rate[] = { +#ifdef __AUDIO_RESAMPLE__ + {AUD_SAMPRATE_8463, CODEC_FREQ_CRYSTAL, 1, 1, 6, 0}, + {AUD_SAMPRATE_16927, CODEC_FREQ_CRYSTAL, 1, 1, 3, 0}, + {AUD_SAMPRATE_50781, CODEC_FREQ_CRYSTAL, 1, 1, 1, 0}, +#endif + {AUD_SAMPRATE_7350, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 6, 0}, + {AUD_SAMPRATE_8000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 6, 0}, + {AUD_SAMPRATE_14700, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 3, 0}, + {AUD_SAMPRATE_16000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 3, 0}, + {AUD_SAMPRATE_44100, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 0}, + {AUD_SAMPRATE_48000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 0}, + {AUD_SAMPRATE_88200, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 1}, + {AUD_SAMPRATE_96000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 1}, + {AUD_SAMPRATE_176400, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 2}, + {AUD_SAMPRATE_192000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 2}, + {AUD_SAMPRATE_352800, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 3}, + {AUD_SAMPRATE_384000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, CODEC_CMU_DIV, 1, 3}, +}; + +const CODEC_ADC_VOL_T WEAK codec_adc_vol[TGT_ADC_VOL_LEVEL_QTY] = { + -99, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, +}; + +static struct CODEC_T * const codec = (struct CODEC_T *)CODEC_BASE; + +#define CODEC_FIR_CH0_BASE (CODEC_BASE + 0x9000) +#define CODEC_FIR_CH1_BASE (CODEC_BASE + 0xB000) +#define CODEC_FIR_CH2_BASE (CODEC_BASE + 0xD000) +#define CODEC_FIR_CH3_BASE (CODEC_BASE + 0xF000) + +#define CODEC_FIR_HISTORY_CH0_BASE (CODEC_FIR_CH0_BASE - 0x1000) +#define CODEC_FIR_HISTORY_CH1_BASE (CODEC_FIR_CH1_BASE - 0x1000) +#define CODEC_FIR_HISTORY_CH2_BASE (CODEC_FIR_CH2_BASE - 0x1000) +#define CODEC_FIR_HISTORY_CH3_BASE (CODEC_FIR_CH3_BASE - 0x1000) + +#ifdef CODEC_MIN_PHASE +static volatile int32_t * const codec_fir_ch0 = (int32_t *)CODEC_FIR_CH0_BASE; +static volatile int32_t * const codec_fir_ch1 = (int32_t *)CODEC_FIR_CH1_BASE; +static volatile int32_t * const codec_fir_ch2 = (int32_t *)CODEC_FIR_CH2_BASE; +static volatile int32_t * const codec_fir_ch3 = (int32_t *)CODEC_FIR_CH3_BASE; +static volatile int32_t * const codec_fir_history0 = (int32_t *)CODEC_FIR_HISTORY_CH0_BASE; +static volatile int32_t * const codec_fir_history1 = (int32_t *)CODEC_FIR_HISTORY_CH1_BASE; +static volatile int32_t * const codec_fir_history2 = (int32_t *)CODEC_FIR_HISTORY_CH2_BASE; +static volatile int32_t * const codec_fir_history3 = (int32_t *)CODEC_FIR_HISTORY_CH3_BASE; + +#define MAX_FIR_ORDERS (512) + +#define FIR_LOW_FREQ + +#ifdef FIR_LOW_FREQ +#define FIR_DAC_ORDERS (220) +#define FIR_ADC_ORDERS (220) +#else +#define FIR_DAC_ORDERS (512) +#define FIR_ADC_ORDERS (512) +#endif + +STATIC_ASSERT(FIR_DAC_ORDERS <= MAX_FIR_ORDERS, "FIR_DAC_ORDERS too large"); +STATIC_ASSERT(FIR_ADC_ORDERS <= MAX_FIR_ORDERS, "FIR_ADC_ORDERS too large"); + +const static int32_t POSSIBLY_UNUSED fir_coef_linear[FIR_DAC_ORDERS] = { + 524287, +}; + +const static int32_t POSSIBLY_UNUSED fir_coef_minimun[FIR_DAC_ORDERS] = { +#ifdef FIR_LOW_FREQ + 171,1077,4203,12582,31473,68652,133899,237244,385800,579602,807418,1044189,1251727,1383990,1396843,1260694,972640,563948, + 99101,-335381,-650923,-780973,-701927,-443652,-84578,268808,512951,579186,455906,192655,-116310,-364122,-468309,-399443, + -190845,74646,296174,392908,334154,149860,-82526,-269615,-339392,-269328,-94001,110604,259377,293401,203556,32780,-143605, + -250723,-245944,-136029,27365,171442,234497,192404,67901,-80955,-187545,-206431,-132784,-3152,122291,187500,165597,69954, + -53253,-147114,-170196,-114838,-9444,95806,152719,137136,59154,-42785,-120684,-139533,-93024,-5397,80987,126029,110487, + 44131,-39952,-101741,-113290,-71331,2185,71419,104055,86354,28846,-39643,-86369,-90279,-51459,9830,63615,84824,64943,15296, + -39213,-72539,-69912,-34308,15781,55890,67480,46479,4496,-37461,-59466,-52097,-20389,19303,47689,51882,31200,-3160,-34103, + -47104,-36994,-9893,20334,39133,38235,19235,-7752,-29414,-35781,-24769,-2693,19264,30682,26817,10499,-9713,-23968,-25906, + -15440,1619,16733,22882,17788,4668,-9693,-18412,-17788,-8810,3652,13454,16181,11101,1226,-8416,-13305,-11533,-4481,4101, + 10062,10834,6508,-446,-6545,-9016,-7036,-1934,3627,7021,6880,3613,-961,-4595,-5701,-4025,-619,2769,4591,4179,1965,-839, + -2887,-3327,-2140,-46,1903,2850,2488,1144,-458,-1565,-1740,-1020,170,1245,1754,1547,815,-53,-656,-761,-376,288,927,1290, + 1257,878,307,-256,-663,-840,-809,-642,-427,-237,-103,-33, +#else + 358,2134,7870,22383,53324,110934,206479,349044,541000,773159,1021370,1246556,1399740,1432299,1309745,1025462,609633,129002, + -324731,-656532,-794417,-712592,-443054,-70120,292346,535048,587990,443750,160328,-158614,-400055,-481834,-382027, + -146176,130807,341515,407598,309695,93804,-148511,-318068,-348626,-233320,-26063,182493,304084,290262,152119,-45991, + -215703,-283797,-223953,-67174,113414,236243,248077,147280,-16729,-167204,-235765,-193530,-63427,91650,198950,209932, + 122330,-19887,-148250,-202614,-159367,-41765,92191,178176,176391,90055,-37106,-142792,-176569,-123965,-12686,101744, + 163572,143971,54527,-59287,-141093,-151499,-87091,18628,112527,148481,110037,17958,-80830,-137074,-123736,-49016,48438, + 119432,129027,73750,-17278,-97589,-127045,-91900,-11220,73360,119064,103602,36056,-48313,-106407,-109292,-56617,23738, + 90354,109596,72600,-665,-72105,-105274,-83967,-20135,52732,97141,90877,38119,-33174,-86035,-93649,-52950,14213,72765, + 92702,64465,3511,-58099,-88538,-72655,-19509,42731,81690,77624,33421,-27283,-72714,-79582,-45018,12285,62151,78801,54174, + 1818,-50528,-75615,-60867,-14676,38325,70381,65146,26015,-25988,-63481,-67140,-35653,13901,55293,67020,43473,-2402,-46194, + -65008,-49433,-8237,36534,61346,53542,17793,-26648,-56304,-55870,-26107,16829,50150,56518,33065,-7346,-43163,-55631,-38609, + -1582,35606,53375,42719,9762,-27735,-49938,-45423,-17053,19783,45514,46773,23343,-11967,-40312,-46863,-28563,4471,34530,45798, + 32673,2539,-28370,-43713,-35673,-8936,22017,40746,37582,14610,-15648,-37053,-38453,-19489,9418,32783,38351,23519,-3470,-28096, + -37370,-26681,-2079,23137,35604,28971,7128,-18054,-33170,-30413,-11603,12974,30179,31045,15443,-8023,-26756,-30924,-18617,3302, + 23015,30118,21105,1094,-19077,-28707,-22913,-5093,15046,26776,24054,8635,-11031,-24419,-24565,-11680,7118,21726,24486,14198,-3394, + -18792,-23876,-16181,-76,15704,22793,17629,3230,-12551,-21309,-18559,-6028,9408,19490,18994,8433,-6352,-17414,-18974,-10431,3440, + 15149,18537,12008,-731,-12769,-17737,-13172,-1735,10336,16622,13932,3920,-7916,-15252,-14311,-5805,5559,13680,14335,7371,-3319,-11967, + -14040,-8615,1232,10161,13463,9538,664,-8320,-12648,-10154,-2348,6485,11634,10474,3797,-4703,-10470,-10527,-5006,3007,9196,10334,5966, + -1433,-7856,-9930,-6686,1,6486,9343,7168,1266,-5126,-8610,-7432,-2359,3803,7762,7491,3267,-2551,-6835,-7369,-3991,1387,5858,7087,4531, + -335,-4863,-6673,-4898,-597,3875,6149,5100,1395,-2920,-5545,-5154,-2058,2015,4882,5073,2582,-1181,-4187,-4878,-2974,427,3479,4586,3237, + 234,-2781,-4219,-3383,-799,2107,3793,3420,1262,-1476,-3331,-3363,-1628,894,2845,3224,1895,-375,-2357,-3021,-2074,-79,1875,2764,2167,459, + -1416,-2470,-2186,-771,987,2151,2139,1009,-599,-1823,-2040,-1182,254,1492,1894,1290,40,-1172,-1717,-1342,-286,869,1516,1343,480,-592,-1303, + -1303,-626,342,1084,1226,725,-127,-870,-1124,-784,-55,664,1001,803,200,-475,-869,-794,-313,303,729,756,392,-154,-592,-701,-443,28,458,630,468,74, + -337,-553,-473,-155,226,471,462,215,-130,-394,-443,-263,45,319,420,302,31,-253,-404,-349,-115,181,394,418,237,-74,-375,-536,-472,-196,214,626,935, + 1062,1013,824,581,341,166,55, +#endif +}; + +static uint8_t min_phase_cfg; +#endif + +static bool codec_init = false; +static bool codec_opened = false; + +static int8_t digdac_gain[MAX_DAC_CH_NUM]; +static int8_t digadc_gain[NORMAL_ADC_CH_NUM]; + +static bool codec_mute[AUD_STREAM_NUM]; + +#ifdef AUDIO_OUTPUT_SWAP +static bool output_swap = true; +#endif + +#ifdef ANC_APP +static float anc_boost_gain_attn; +static int8_t anc_adc_gain_offset[NORMAL_ADC_CH_NUM]; +static enum AUD_CHANNEL_MAP_T anc_adc_gain_offset_map; +#endif +#if defined(NOISE_GATING) && defined(NOISE_REDUCTION) +static bool codec_nr_enabled; +static int8_t digdac_gain_offset_nr; +#endif +#ifdef AUDIO_OUTPUT_DC_CALIB +static int32_t dac_dc_l; +static int32_t dac_dc_r; +static float dac_dc_gain_attn; +#endif +#ifdef __AUDIO_RESAMPLE__ +static uint8_t rs_clk_map; +STATIC_ASSERT(sizeof(rs_clk_map) * 8 >= AUD_STREAM_NUM, "rs_clk_map size too small"); + +static uint32_t resample_clk_freq; +static uint8_t resample_rate_idx[AUD_STREAM_NUM]; +#endif +#ifdef CODEC_TIMER +static uint32_t cur_codec_freq; +#endif +// EC +static uint8_t codec_rate_idx[AUD_STREAM_NUM]; + +//static HAL_CODEC_DAC_RESET_CALLBACK dac_reset_callback; + +static uint8_t codec_irq_map; +STATIC_ASSERT(sizeof(codec_irq_map) * 8 >= CODEC_IRQ_TYPE_QTY, "codec_irq_map size too small"); +static HAL_CODEC_IRQ_CALLBACK codec_irq_callback[CODEC_IRQ_TYPE_QTY]; + +static enum AUD_CHANNEL_MAP_T codec_dac_ch_map; +static enum AUD_CHANNEL_MAP_T codec_adc_ch_map; +static enum AUD_CHANNEL_MAP_T anc_adc_ch_map; +static enum AUD_CHANNEL_MAP_T codec_mic_ch_map; +static enum AUD_CHANNEL_MAP_T anc_mic_ch_map; +#ifdef SIDETONE_DEDICATED_ADC_CHAN +static enum AUD_CHANNEL_MAP_T sidetone_adc_ch_map; +static int8_t sidetone_adc_gain; +static int8_t sidetone_gain_offset; +#ifdef CFG_HW_AUD_SIDETONE_GAIN_RAMP +static float sidetone_ded_chan_coef; +#endif +#endif + +static uint8_t dac_delay_ms; + +#ifdef ANC_PROD_TEST +#define OPT_TYPE +#else +#define OPT_TYPE const +#endif + +static OPT_TYPE uint8_t codec_digmic_phase = CODEC_DIGMIC_PHASE; + +#if defined(AUDIO_ANC_FB_MC) && defined(__AUDIO_RESAMPLE__) +#error "Music cancel cannot work with audio resample" +#endif +#ifdef AUDIO_ANC_FB_MC +static bool mc_enabled; +static bool mc_dual_chan; +static bool mc_16bit; +#endif + +#ifdef CODEC_DSD +static bool dsd_enabled; +static uint8_t dsd_rate_idx; +#endif + +#if defined(AUDIO_ANC_FB_MC) || defined(CODEC_DSD) +static uint8_t adc_en_map; +STATIC_ASSERT(sizeof(adc_en_map) * 8 >= CODEC_ADC_EN_REQ_QTY, "adc_en_map size too small"); +#endif + +#ifdef PERF_TEST_POWER_KEY +static enum HAL_CODEC_PERF_TEST_POWER_T cur_perft_power; +#endif + +#ifdef AUDIO_OUTPUT_SW_GAIN +static int8_t swdac_gain; +static HAL_CODEC_SW_OUTPUT_COEF_CALLBACK sw_output_coef_callback; +#endif + +static HAL_CODEC_BT_TRIGGER_CALLBACK bt_trigger_callback = NULL; + +#ifdef VOICE_DETECTOR_EN +#define CODEC_VAD_BUF_ADDR 0x40304000 +#define CODEC_VAD_BUF_SIZE 0x4000 +static enum AUD_VAD_TYPE_T vad_type; +static AUD_VAD_CALLBACK vad_handler; +static bool vad_enabled; +static uint32_t vad_data_cnt; +static uint32_t vad_addr_cnt; +#endif + +#if defined(DAC_CLASSG_ENABLE) +static struct dac_classg_cfg _dac_classg_cfg = { + .thd2 = 0xC0, + .thd1 = 0x10, + .thd0 = 0x10, + .lr = 1, + .step_4_3n = 0, + .quick_down = 1, + .wind_width = 0x400, +}; +#endif + +#ifdef DAC_DRE_ENABLE +static const struct CODEC_DAC_DRE_CFG_T dac_dre_cfg = { + .dre_delay = 8, + .thd_db_offset = 0xF, //5, + .step_mode = 0, + .dre_win = 0x6000, + .amp_high = 2, //0x10, +}; +#endif + +static void hal_codec_set_dig_adc_gain(enum AUD_CHANNEL_MAP_T map, int32_t gain); +static void hal_codec_set_dig_dac_gain(enum AUD_CHANNEL_MAP_T map, int32_t gain); +static void hal_codec_restore_dig_dac_gain(void); +static void hal_codec_set_dac_gain_value(enum AUD_CHANNEL_MAP_T map, uint32_t val); +static int hal_codec_set_adc_down(enum AUD_CHANNEL_MAP_T map, uint32_t val); +static int hal_codec_set_adc_hbf_bypass_cnt(enum AUD_CHANNEL_MAP_T map, uint32_t cnt); +static uint32_t hal_codec_get_adc_chan(enum AUD_CHANNEL_MAP_T mic_map); +#ifdef AUDIO_OUTPUT_SW_GAIN +static void hal_codec_set_sw_gain(int32_t gain); +#endif +#ifdef __AUDIO_RESAMPLE__ +static float get_playback_resample_phase(void); +static float get_capture_resample_phase(void); +static uint32_t resample_phase_float_to_value(float phase); +static float resample_phase_value_to_float(uint32_t value); +#endif + +static void hal_codec_reg_update_delay(void) +{ + hal_sys_timer_delay_us(2); +} + +#if defined(DAC_CLASSG_ENABLE) +void hal_codec_classg_config(const struct dac_classg_cfg *cfg) +{ + _dac_classg_cfg = *cfg; +} + +static void hal_codec_classg_enable(bool en) +{ + struct dac_classg_cfg *config; + + if (en) { + config = &_dac_classg_cfg; + + codec->REG_0B4 = SET_BITFIELD(codec->REG_0B4, CODEC_CODEC_CLASSG_THD2, config->thd2); + codec->REG_0B4 = SET_BITFIELD(codec->REG_0B4, CODEC_CODEC_CLASSG_THD1, config->thd1); + codec->REG_0B4 = SET_BITFIELD(codec->REG_0B4, CODEC_CODEC_CLASSG_THD0, config->thd0); + + // Make class-g set the lowest gain after several samples. + // Class-g gain will have impact on dc. + codec->REG_0B0 = SET_BITFIELD(codec->REG_0B0, CODEC_CODEC_CLASSG_WINDOW, 6); + + if (config->lr) + codec->REG_0B0 |= CODEC_CODEC_CLASSG_LR; + else + codec->REG_0B0 &= ~CODEC_CODEC_CLASSG_LR; + + if (config->step_4_3n) + codec->REG_0B0 |= CODEC_CODEC_CLASSG_STEP_3_4N; + else + codec->REG_0B0 &= ~CODEC_CODEC_CLASSG_STEP_3_4N; + + if (config->quick_down) + codec->REG_0B0 |= CODEC_CODEC_CLASSG_QUICK_DOWN; + else + codec->REG_0B0 &= ~CODEC_CODEC_CLASSG_QUICK_DOWN; + + codec->REG_0B0 |= CODEC_CODEC_CLASSG_EN; + + // Restore class-g window after the gain has been updated + hal_codec_reg_update_delay(); + codec->REG_0B0 = SET_BITFIELD(codec->REG_0B0, CODEC_CODEC_CLASSG_WINDOW, config->wind_width); + } else { + codec->REG_0B0 &= ~CODEC_CODEC_CLASSG_QUICK_DOWN; + } +} +#endif + +#if defined(AUDIO_OUTPUT_DC_CALIB) || defined(SDM_MUTE_NOISE_SUPPRESSION) +static void hal_codec_dac_dc_offset_enable(int32_t dc_l, int32_t dc_r) +{ + codec->REG_0E0 &= CODEC_CODEC_DAC_DC_UPDATE_CH0; + hal_codec_reg_update_delay(); + codec->REG_0E8 = SET_BITFIELD(codec->REG_0E8, CODEC_CODEC_DAC_DC_CH1, dc_r); + codec->REG_0E0 = SET_BITFIELD(codec->REG_0E0, CODEC_CODEC_DAC_DC_CH0, dc_l) | CODEC_CODEC_DAC_DC_UPDATE_CH0; +} +#endif + +#ifdef CODEC_MIN_PHASE +static void hal_codec_min_phase_init(void) +{ + int i; + + // SYS clock should be 52M or above + + // DAC + codec->REG_108 &= ~(CODEC_STREAM0_FIR1_CH0); + codec->REG_108 = SET_BITFIELD(codec->REG_108,CODEC_FIR_MODE_CH0,0); + codec->REG_108 = SET_BITFIELD(codec->REG_108,CODEC_FIR_ORDER_CH0,FIR_DAC_ORDERS); + + codec->REG_10C = SET_BITFIELD(codec->REG_10C,CODEC_FIR_BURST_LENGTH_CH0,4); + codec->REG_10C = SET_BITFIELD(codec->REG_10C,CODEC_FIR_GAIN_SEL_CH0,4); + + codec->REG_110 &= ~(CODEC_STREAM0_FIR1_CH1); + codec->REG_110 = SET_BITFIELD(codec->REG_110,CODEC_FIR_MODE_CH1,0); + codec->REG_110 = SET_BITFIELD(codec->REG_110,CODEC_FIR_ORDER_CH1,FIR_DAC_ORDERS); + + codec->REG_114 = SET_BITFIELD(codec->REG_114,CODEC_FIR_BURST_LENGTH_CH1,4); + codec->REG_114 = SET_BITFIELD(codec->REG_114,CODEC_FIR_GAIN_SEL_CH1,4); + + // ADC + codec->REG_118 &= ~(CODEC_STREAM0_FIR1_CH2); + codec->REG_118 = SET_BITFIELD(codec->REG_118,CODEC_FIR_MODE_CH2,0); + codec->REG_118 = SET_BITFIELD(codec->REG_118,CODEC_FIR_ORDER_CH2,FIR_ADC_ORDERS); + + //codec->REG_11C = SET_BITFIELD(codec->REG_11C,CODEC_FIR_BURST_LENGTH_CH2,4); + codec->REG_11C = SET_BITFIELD(codec->REG_11C,CODEC_FIR_GAIN_SEL_CH2,6); + + codec->REG_120 &= ~(CODEC_STREAM0_FIR1_CH3); + codec->REG_120 = SET_BITFIELD(codec->REG_120,CODEC_FIR_MODE_CH3,0); + codec->REG_120 = SET_BITFIELD(codec->REG_120,CODEC_FIR_ORDER_CH3,FIR_ADC_ORDERS); + + //codec->REG_124 = SET_BITFIELD(codec->REG_124,CODEC_FIR_BURST_LENGTH_CH3,4); + codec->REG_124 = SET_BITFIELD(codec->REG_124,CODEC_FIR_GAIN_SEL_CH3,6); + + // DAC + codec->REG_100 |= (CODEC_FIR_UPSAMPLE_CH0 | CODEC_FIR_UPSAMPLE_CH1); + + for (i = 0; i < FIR_DAC_ORDERS; i++) { + codec_fir_ch0[i] = fir_coef_minimun[i]; + codec_fir_ch1[i] = fir_coef_minimun[i]; + } + + // ADC + codec->REG_100 &= ~(CODEC_FIR_UPSAMPLE_CH2 | CODEC_FIR_UPSAMPLE_CH3); + + for (i = 0; i < FIR_DAC_ORDERS; i++) { + codec_fir_ch2[i] = fir_coef_minimun[i]; + codec_fir_ch3[i] = fir_coef_minimun[i]; + } + + // Init history buffer + for (i=0; i < MAX_FIR_ORDERS; i++) { + codec_fir_history0[i] = 0; + codec_fir_history1[i] = 0; + codec_fir_history2[i] = 0; + codec_fir_history3[i] = 0; + } +} + +static void hal_codec_min_phase_term(void) +{ + // Release SYS clock request +} +#endif + +int hal_codec_open(enum HAL_CODEC_ID_T id) +{ + int i; + bool first_open; + +#ifdef CODEC_POWER_DOWN + first_open = true; +#else + first_open = !codec_init; +#endif + + analog_aud_pll_open(ANA_AUD_PLL_USER_CODEC); + + if (!codec_init) { + for (i = 0; i < CFG_HW_AUD_INPUT_PATH_NUM; i++) { + if (cfg_audio_input_path_cfg[i].cfg & AUD_CHANNEL_MAP_ALL & ~VALID_MIC_MAP) { + ASSERT(false, "Invalid input path cfg: i=%d io_path=%d cfg=0x%X", + i, cfg_audio_input_path_cfg[i].io_path, cfg_audio_input_path_cfg[i].cfg); + } + } +#ifdef ANC_APP + anc_boost_gain_attn = 1.0f; +#endif + codec_init = true; + } + if (first_open) { + // Codec will be powered down first + hal_psc_codec_enable(); + } + hal_cmu_codec_clock_enable(); + hal_cmu_codec_reset_clear(); + + codec_opened = true; + + codec->REG_060 |= CODEC_EN_CLK_ADC_MASK | CODEC_EN_CLK_ADC_ANA_MASK | CODEC_POL_ADC_ANA_MASK | CODEC_POL_DAC_OUT; + codec->REG_064 |= CODEC_SOFT_RSTN_32K | CODEC_SOFT_RSTN_IIR | CODEC_SOFT_RSTN_RS | + CODEC_SOFT_RSTN_DAC | CODEC_SOFT_RSTN_ADC_MASK | CODEC_SOFT_RSTN_ADC_ANA_MASK; + codec->REG_000 = 0; + codec->REG_04C &= ~CODEC_MC_ENABLE; + codec->REG_004 = ~0UL; + hal_codec_reg_update_delay(); + codec->REG_004 = 0; + codec->REG_000 |= CODEC_CODEC_IF_EN; + + codec->REG_054 |= CODEC_FAULT_MUTE_DAC_ENABLE; + +#ifdef AUDIO_OUTPUT_SWAP + if (output_swap) { + codec->REG_0A0 |= CODEC_CODEC_DAC_OUT_SWAP; + } else { + codec->REG_0A0 &= ~CODEC_CODEC_DAC_OUT_SWAP; + } +#endif + + if (first_open) { +#ifdef AUDIO_ANC_FB_MC + codec->REG_04C = CODEC_DMA_CTRL_MC; + codec->REG_230 |= CODEC_MC_EN_SEL|CODEC_MC_RATE_SRC_SEL; +#endif + + // ANC zero-crossing + codec->REG_0D4 |= CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FF_CH0 | CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FF_CH1; + codec->REG_0D8 |= CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FB_CH0 | CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FB_CH1; + + // Enable ADC zero-crossing gain adjustment + for (i = 0; i < NORMAL_ADC_CH_NUM; i++) { + *(&codec->REG_084 + i) |= CODEC_CODEC_ADC_GAIN_SEL_CH0; + } + + // DRE ini gain and offset + uint8_t max_gain, ini_gain, dre_offset; + max_gain = analog_aud_get_max_dre_gain(); + if (max_gain < 0xF) { + ini_gain = 0xF - max_gain; + } else { + ini_gain = 0; + } + if (max_gain > 0xF) { + dre_offset = max_gain - 0xF; + } else { + dre_offset = 0; + } + codec->REG_0C0 = CODEC_CODEC_DRE_INI_ANA_GAIN_CH0(ini_gain) | CODEC_CODEC_DRE_GAIN_OFFSET_CH0(dre_offset); + codec->REG_0C8 = CODEC_CODEC_DRE_INI_ANA_GAIN_CH1(ini_gain) | CODEC_CODEC_DRE_GAIN_OFFSET_CH1(dre_offset); + codec->REG_0E0 = CODEC_CODEC_DAC_ANA_GAIN_UPDATE_DELAY_CH0(0); + codec->REG_0E8 = CODEC_CODEC_DAC_ANA_GAIN_UPDATE_DELAY_CH1(0); + +#ifdef ANC_PROD_TEST +#ifdef AUDIO_ANC_FB_MC + // Enable ADC + music cancel. + codec->REG_130 |= CODEC_CODEC_FB_CHECK_KEEP_CH0; + codec->REG_134 |= CODEC_CODEC_FB_CHECK_KEEP_CH1; +#elif defined(AUDIO_ANC_FB_MC_HW) + // Enable ADC + music cancel. + codec->REG_130 |= CODEC_CODEC_FB_CHECK_KEEP_CH0; +#endif +#endif + +#if defined(FIXED_CODEC_ADC_VOL) && defined(SINGLE_CODEC_ADC_VOL) + const CODEC_ADC_VOL_T *adc_gain_db; + + adc_gain_db = hal_codec_get_adc_volume(CODEC_SADC_VOL); + if (adc_gain_db) { + hal_codec_set_dig_adc_gain(NORMAL_ADC_MAP, *adc_gain_db); +#ifdef SIDETONE_DEDICATED_ADC_CHAN + sidetone_adc_gain = *adc_gain_db; +#endif + } +#endif + +#ifdef AUDIO_OUTPUT_DC_CALIB + hal_codec_dac_dc_offset_enable(dac_dc_l, dac_dc_r); +#elif defined(SDM_MUTE_NOISE_SUPPRESSION) + hal_codec_dac_dc_offset_enable(1, 1); +#endif + +#ifdef AUDIO_OUTPUT_SW_GAIN + const struct CODEC_DAC_VOL_T *vol_tab_ptr; + + // Init gain settings + vol_tab_ptr = hal_codec_get_dac_volume(0); + if (vol_tab_ptr) { + analog_aud_set_dac_gain(vol_tab_ptr->tx_pa_gain); + hal_codec_set_dig_dac_gain(VALID_DAC_MAP, ZERODB_DIG_DBVAL); + } +#else + // Enable DAC zero-crossing gain adjustment + codec->REG_09C |= CODEC_CODEC_DAC_GAIN_SEL_CH0; + codec->REG_0A0 |= CODEC_CODEC_DAC_GAIN_SEL_CH1; +#endif + +#ifdef AUDIO_OUTPUT_DC_CALIB_ANA + // Reset SDM + hal_codec_set_dac_gain_value(VALID_DAC_MAP, 0); + codec->REG_098 |= CODEC_CODEC_DAC_SDM_CLOSE; +#endif + +#ifdef SDM_MUTE_NOISE_SUPPRESSION + codec->REG_098 = SET_BITFIELD(codec->REG_098, CODEC_CODEC_DAC_DITHER_GAIN, 0x10); +#endif + +#ifdef __AUDIO_RESAMPLE__ + codec->REG_0E4 &= ~(CODEC_CODEC_RESAMPLE_DAC_ENABLE | CODEC_CODEC_RESAMPLE_ADC_ENABLE | + CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE | CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE); +#endif + +#ifdef CODEC_DSD + for(i = 0; i < ARRAY_SIZE(codec_adc_sample_rate); i++) { + if(codec_adc_sample_rate[i].sample_rate == AUD_SAMPRATE_44100) { + break; + } + } + hal_codec_set_adc_down((AUD_CHANNEL_MAP_CH2 | AUD_CHANNEL_MAP_CH3), codec_adc_sample_rate[i].adc_down); + hal_codec_set_adc_hbf_bypass_cnt((AUD_CHANNEL_MAP_CH2 | AUD_CHANNEL_MAP_CH3), codec_adc_sample_rate[i].bypass_cnt); +#endif + + // Mute DAC when cpu fault occurs + hal_cmu_codec_set_fault_mask(0x3F); + +#ifdef CODEC_TIMER + // Disable sync stamp auto clear to avoid impacting codec timer capture + codec->REG_054 &= ~CODEC_STAMP_CLR_USED; +#else + // Enable sync stamp auto clear + codec->REG_054 |= CODEC_STAMP_CLR_USED; +#endif + } + +#ifdef CODEC_MIN_PHASE + if (min_phase_cfg) { + hal_codec_min_phase_init(); + } +#endif + + return 0; +} + +int hal_codec_close(enum HAL_CODEC_ID_T id) +{ +#ifdef CODEC_MIN_PHASE + if (min_phase_cfg) { + hal_codec_min_phase_term(); + } +#endif + + codec->REG_054 &= ~CODEC_FAULT_MUTE_DAC_ENABLE; + + codec->REG_000 &= ~CODEC_CODEC_IF_EN; + codec->REG_064 &= ~(CODEC_SOFT_RSTN_32K | CODEC_SOFT_RSTN_IIR | CODEC_SOFT_RSTN_RS | + CODEC_SOFT_RSTN_DAC | CODEC_SOFT_RSTN_ADC_MASK | CODEC_SOFT_RSTN_ADC_ANA_MASK); + codec->REG_060 &= ~(CODEC_EN_CLK_ADC_MASK | CODEC_EN_CLK_ADC_ANA_MASK); + + codec_opened = false; + +#ifdef CODEC_POWER_DOWN + hal_cmu_codec_reset_set(); + hal_cmu_codec_clock_disable(); + hal_psc_codec_disable(); +#else + // NEVER reset or power down CODEC registers, for the CODEC driver expects that last configurations + // still exist in the next stream setup + hal_cmu_codec_clock_disable(); +#endif + + analog_aud_pll_close(ANA_AUD_PLL_USER_CODEC); + + return 0; +} + +void hal_codec_crash_mute(void) +{ + if (codec_opened) { + codec->REG_000 &= ~CODEC_CODEC_IF_EN; + } +} + +#ifdef DAC_DRE_ENABLE +static void hal_codec_dac_dre_enable(void) +{ + codec->REG_0C0 = (codec->REG_0C0 & ~(CODEC_CODEC_DRE_THD_DB_OFFSET_SIGN_CH0 | CODEC_CODEC_DRE_DELAY_CH0_MASK | + CODEC_CODEC_DRE_INI_ANA_GAIN_CH0_MASK | CODEC_CODEC_DRE_THD_DB_OFFSET_CH0_MASK | CODEC_CODEC_DRE_STEP_MODE_CH0_MASK)) | + CODEC_CODEC_DRE_DELAY_CH0(dac_dre_cfg.dre_delay) | + CODEC_CODEC_DRE_INI_ANA_GAIN_CH0(0xF) | CODEC_CODEC_DRE_THD_DB_OFFSET_CH0(dac_dre_cfg.thd_db_offset) | + CODEC_CODEC_DRE_THD_DB_OFFSET_CH0(dac_dre_cfg.step_mode) | CODEC_CODEC_DRE_ENABLE_CH0; + codec->REG_0C4 = (codec->REG_0C4 & ~(CODEC_CODEC_DRE_WINDOW_CH0_MASK | CODEC_CODEC_DRE_AMP_HIGH_CH0_MASK)) | + CODEC_CODEC_DRE_WINDOW_CH0(dac_dre_cfg.dre_win) | CODEC_CODEC_DRE_AMP_HIGH_CH0(dac_dre_cfg.amp_high); + + codec->REG_0C8 = (codec->REG_0C8 & ~(CODEC_CODEC_DRE_THD_DB_OFFSET_SIGN_CH1 | CODEC_CODEC_DRE_DELAY_CH1_MASK | + CODEC_CODEC_DRE_INI_ANA_GAIN_CH1_MASK | CODEC_CODEC_DRE_THD_DB_OFFSET_CH1_MASK | CODEC_CODEC_DRE_STEP_MODE_CH1_MASK)) | + CODEC_CODEC_DRE_DELAY_CH1(dac_dre_cfg.dre_delay) | + CODEC_CODEC_DRE_INI_ANA_GAIN_CH1(0xF) | CODEC_CODEC_DRE_THD_DB_OFFSET_CH1(dac_dre_cfg.thd_db_offset) | + CODEC_CODEC_DRE_THD_DB_OFFSET_CH1(dac_dre_cfg.step_mode) | CODEC_CODEC_DRE_ENABLE_CH1; + codec->REG_0CC = (codec->REG_0CC & ~(CODEC_CODEC_DRE_WINDOW_CH1_MASK | CODEC_CODEC_DRE_AMP_HIGH_CH1_MASK)) | + CODEC_CODEC_DRE_WINDOW_CH1(dac_dre_cfg.dre_win) | CODEC_CODEC_DRE_AMP_HIGH_CH1(dac_dre_cfg.amp_high); +} + +static void hal_codec_dac_dre_disable(void) +{ + codec->REG_0C0 &= ~CODEC_CODEC_DRE_ENABLE_CH0; + codec->REG_0C8 &= ~CODEC_CODEC_DRE_ENABLE_CH1; +} +#endif + +#ifdef PERF_TEST_POWER_KEY +static void hal_codec_update_perf_test_power(void) +{ + int32_t nominal_vol; + uint32_t ini_ana_gain; + int32_t dac_vol; + + if (!codec_opened) { + return; + } + + dac_vol = 0; + if (cur_perft_power == HAL_CODEC_PERF_TEST_30MW) { + nominal_vol = 0; + ini_ana_gain = 0; + } else if (cur_perft_power == HAL_CODEC_PERF_TEST_10MW) { + nominal_vol = -5; + ini_ana_gain = 6; + } else if (cur_perft_power == HAL_CODEC_PERF_TEST_5MW) { + nominal_vol = -8; + ini_ana_gain = 0xA; + } else if (cur_perft_power == HAL_CODEC_PERF_TEST_M60DB) { + nominal_vol = -60; + ini_ana_gain = 0xF; // about -11 dB + dac_vol = -49; + } else { + return; + } + + if (codec->REG_0C0 & CODEC_CODEC_DRE_ENABLE_CH0) { + dac_vol = nominal_vol; + } else { + codec->REG_0C0 = SET_BITFIELD(codec->REG_0C0, CODEC_CODEC_DRE_INI_ANA_GAIN_CH0, ini_ana_gain); + codec->REG_0C8 = SET_BITFIELD(codec->REG_0C8, CODEC_CODEC_DRE_INI_ANA_GAIN_CH1, ini_ana_gain); + } + +#ifdef AUDIO_OUTPUT_SW_GAIN + hal_codec_set_sw_gain(dac_vol); +#else + hal_codec_set_dig_dac_gain(VALID_DAC_MAP, dac_vol); +#endif + +#if defined(NOISE_GATING) && defined(NOISE_REDUCTION) + if (codec_nr_enabled) { + codec_nr_enabled = false; + hal_codec_set_noise_reduction(true); + } +#endif +} + +void hal_codec_dac_gain_m60db_check(enum HAL_CODEC_PERF_TEST_POWER_T type) +{ + cur_perft_power = type; + + if (!codec_opened || (codec->REG_098 & CODEC_CODEC_DAC_EN) == 0) { + return; + } + + hal_codec_update_perf_test_power(); +} +#endif + +#if defined(NOISE_GATING) && defined(NOISE_REDUCTION) +void hal_codec_set_noise_reduction(bool enable) +{ + uint32_t ini_ana_gain; + + if (codec_nr_enabled == enable) { + // Avoid corrupting digdac_gain_offset_nr or using an invalid one + return; + } + + codec_nr_enabled = enable; + + if (!codec_opened) { + return; + } + + // ini_ana_gain=0 --> 0dB + // ini_ana_gain=0xF --> -11dB + if (enable) { + ini_ana_gain = GET_BITFIELD(codec->REG_0C0, CODEC_CODEC_DRE_INI_ANA_GAIN_CH0); + digdac_gain_offset_nr = ((0xF - ini_ana_gain) * 11 + 0xF / 2) / 0xF; + ini_ana_gain = 0xF; + } else { + ini_ana_gain = 0xF - (digdac_gain_offset_nr * 0xF + 11 / 2) / 11; + digdac_gain_offset_nr = 0; + } + + codec->REG_0C0 = SET_BITFIELD(codec->REG_0C0, CODEC_CODEC_DRE_INI_ANA_GAIN_CH0, ini_ana_gain); + codec->REG_0C8 = SET_BITFIELD(codec->REG_0C8, CODEC_CODEC_DRE_INI_ANA_GAIN_CH1, ini_ana_gain); + +#ifdef AUDIO_OUTPUT_SW_GAIN + hal_codec_set_sw_gain(swdac_gain); +#else + hal_codec_restore_dig_dac_gain(); +#endif +} +#endif + +void hal_codec_stop_playback_stream(enum HAL_CODEC_ID_T id) +{ +#if (defined(AUDIO_OUTPUT_DC_CALIB_ANA) || defined(AUDIO_OUTPUT_DC_CALIB)) && (!(defined(__TWS__) || defined(IBRT)) || defined(ANC_APP)) + // Disable PA + analog_aud_codec_speaker_enable(false); +#endif + + codec->REG_098 &= ~(CODEC_CODEC_DAC_EN | CODEC_CODEC_DAC_EN_CH0 | CODEC_CODEC_DAC_EN_CH1); + +#ifdef CODEC_TIMER + // Reset codec timer + codec->REG_054 &= ~CODEC_EVENT_FOR_CAPTURE; +#endif + +#ifdef DAC_DRE_ENABLE + hal_codec_dac_dre_disable(); +#endif + +#if defined(DAC_CLASSG_ENABLE) + hal_codec_classg_enable(false); +#endif + +#ifndef NO_DAC_RESET + // Reset DAC + // Avoid DAC outputing noise after it is disabled + codec->REG_064 &= ~CODEC_SOFT_RSTN_DAC; + codec->REG_064 |= CODEC_SOFT_RSTN_DAC; +#endif + codec->REG_060 &= ~CODEC_EN_CLK_DAC; +} + +void hal_codec_start_playback_stream(enum HAL_CODEC_ID_T id) +{ + codec->REG_060 |= CODEC_EN_CLK_DAC; +#ifndef NO_DAC_RESET + // Reset DAC + codec->REG_064 &= ~CODEC_SOFT_RSTN_DAC; + codec->REG_064 |= CODEC_SOFT_RSTN_DAC; +#endif + +#ifdef DAC_DRE_ENABLE + if ( + //(codec->REG_044 & CODEC_MODE_16BIT_DAC) == 0 && +#ifdef ANC_APP + anc_adc_ch_map == 0 && +#endif + 1 + ) + { + hal_codec_dac_dre_enable(); + } +#endif + +#ifdef PERF_TEST_POWER_KEY + hal_codec_update_perf_test_power(); +#endif + +#if defined(DAC_CLASSG_ENABLE) + hal_codec_classg_enable(true); +#endif + +#ifdef CODEC_TIMER + // Enable codec timer and record time by bt event instead of gpio event + codec->REG_054 = (codec->REG_054 & ~CODEC_EVENT_SEL) | CODEC_EVENT_FOR_CAPTURE; +#endif + + if (codec_dac_ch_map & AUD_CHANNEL_MAP_CH0) { + codec->REG_098 |= CODEC_CODEC_DAC_EN_CH0; + } else { + codec->REG_098 &= ~CODEC_CODEC_DAC_EN_CH0; + } + if (codec_dac_ch_map & AUD_CHANNEL_MAP_CH1) { + codec->REG_098 |= CODEC_CODEC_DAC_EN_CH1; + } else { + codec->REG_098 &= ~CODEC_CODEC_DAC_EN_CH1; + } + +#if (defined(AUDIO_OUTPUT_DC_CALIB_ANA) || defined(AUDIO_OUTPUT_DC_CALIB)) && (!(defined(__TWS__) || defined(IBRT)) || defined(ANC_APP)) +#if 0 + uint32_t cfg_en; + uint32_t anc_ff_gain, anc_fb_gain; + + cfg_en = codec->REG_000 & CODEC_DAC_ENABLE; + anc_ff_gain = codec->REG_0D4; + anc_fb_gain = codec->REG_0D8; + + if (cfg_en) { + codec->REG_000 &= ~cfg_en; + } + if (anc_ff_gain) { + codec->REG_0D4 = CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FF_CH0 | CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FF_CH1; + anc_ff_gain |= CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FF_CH0 | CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FF_CH1; + } + if (anc_fb_gain) { + codec->REG_0D8 = CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FB_CH0 | CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FB_CH1; + anc_fb_gain = CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FB_CH0 | CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FB_CH1; + } + osDelay(1); +#endif +#endif + + codec->REG_098 |= CODEC_CODEC_DAC_EN; + +#if (defined(AUDIO_OUTPUT_DC_CALIB_ANA) || defined(AUDIO_OUTPUT_DC_CALIB)) && (!(defined(__TWS__) || defined(IBRT)) || defined(ANC_APP)) +#ifdef AUDIO_OUTPUT_DC_CALIB + // At least delay 4ms for 8K-sample-rate mute data to arrive at DAC PA + osDelay(5); +#endif + +#if 0 + if (cfg_en) { + codec->REG_000 |= cfg_en; + } + if (anc_ff_gain) { + codec->REG_0D4 = anc_ff_gain; + } + if (anc_fb_gain) { + codec->REG_0D8 = anc_fb_gain; + } +#endif + + // Enable PA + analog_aud_codec_speaker_enable(true); + +#ifdef AUDIO_ANC_FB_MC + if (mc_enabled) { + uint32_t lock; + lock = int_lock(); + // MC FIFO and DAC FIFO must be started at the same time + codec->REG_04C |= CODEC_MC_ENABLE; + codec->REG_000 |= CODEC_DAC_ENABLE; + int_unlock(lock); + } +#endif +#endif +} + +#ifdef AF_ADC_I2S_SYNC +static bool _hal_codec_capture_enable_delay = false; + +void hal_codec_capture_enable_delay(void) +{ + _hal_codec_capture_enable_delay = true; +} + +void hal_codec_capture_enable(void) +{ + codec->REG_080 |= CODEC_CODEC_ADC_EN; +} +#endif + +int hal_codec_start_stream(enum HAL_CODEC_ID_T id, enum AUD_STREAM_T stream) +{ + if (stream == AUD_STREAM_PLAYBACK) { + // Reset and start DAC + hal_codec_start_playback_stream(id); + } else { +#if defined(AUDIO_ANC_FB_MC) || defined(CODEC_DSD) + adc_en_map |= (1 << CODEC_ADC_EN_REQ_STREAM); + if (adc_en_map == (1 << CODEC_ADC_EN_REQ_STREAM)) +#endif + { + // Reset ADC ANA + codec->REG_064 &= ~CODEC_SOFT_RSTN_ADC_ANA_MASK; + codec->REG_064 |= CODEC_SOFT_RSTN_ADC_ANA_MASK; + +#ifdef AF_ADC_I2S_SYNC + if (_hal_codec_capture_enable_delay) + { + _hal_codec_capture_enable_delay = false; + } + else + { + hal_codec_capture_enable(); + } +#else + codec->REG_080 |= CODEC_CODEC_ADC_EN; +#endif + } + } + + return 0; +} + +int hal_codec_stop_stream(enum HAL_CODEC_ID_T id, enum AUD_STREAM_T stream) +{ + if (stream == AUD_STREAM_PLAYBACK) { + // Stop and reset DAC + hal_codec_stop_playback_stream(id); + } else { +#if defined(AUDIO_ANC_FB_MC) || defined(CODEC_DSD) + adc_en_map &= ~(1 << CODEC_ADC_EN_REQ_STREAM); + if (adc_en_map == 0) +#endif + { + codec->REG_080 &= ~CODEC_CODEC_ADC_EN; +#ifdef AF_ADC_I2S_SYNC + _hal_codec_capture_enable_delay = false; +#endif + } + } + + return 0; +} + +#ifdef CODEC_DSD +void hal_codec_dsd_enable(void) +{ + dsd_enabled = true; +} + +void hal_codec_dsd_disable(void) +{ + dsd_enabled = false; +} + +static void hal_codec_dsd_cfg_start(void) +{ +#if !(defined(FIXED_CODEC_ADC_VOL) && defined(SINGLE_CODEC_ADC_VOL)) + uint32_t vol; + const CODEC_ADC_VOL_T *adc_gain_db; + + vol = hal_codec_get_mic_chan_volume_level(AUD_CHANNEL_MAP_DIGMIC_CH2); + adc_gain_db = hal_codec_get_adc_volume(vol); + if (adc_gain_db) { + hal_codec_set_dig_adc_gain((AUD_CHANNEL_MAP_CH2 | AUD_CHANNEL_MAP_CH3), *adc_gain_db); + } +#endif + + codec->REG_004 |= CODEC_DSD_RX_FIFO_FLUSH | CODEC_DSD_TX_FIFO_FLUSH; + hal_codec_reg_update_delay(); + codec->REG_004 &= ~(CODEC_DSD_RX_FIFO_FLUSH | CODEC_DSD_TX_FIFO_FLUSH); + + codec->REG_0B8 = CODEC_CODEC_DSD_ENABLE_L | CODEC_CODEC_DSD_ENABLE_R | CODEC_CODEC_DSD_SAMPLE_RATE(dsd_rate_idx); + codec->REG_048 = CODEC_DSD_IF_EN | CODEC_DSD_ENABLE | CODEC_DSD_DUAL_CHANNEL | CODEC_MODE_24BIT_DSD | + /* CODEC_DMA_CTRL_RX_DSD | */ CODEC_DMA_CTRL_TX_DSD | CODEC_DSD_IN_16BIT; + + codec->REG_080 = (codec->REG_080 & ~(CODEC_CODEC_LOOP_SEL_L_MASK | CODEC_CODEC_LOOP_SEL_R_MASK)) | + CODEC_CODEC_ADC_LOOP | CODEC_CODEC_LOOP_SEL_L(2) | CODEC_CODEC_LOOP_SEL_R(3); + + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH2, 2); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH2; + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH3, 3); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH3; + + codec->REG_064 &= ~(CODEC_SOFT_RSTN_ADC(1 << 2) | CODEC_SOFT_RSTN_ADC(1 << 3)); + codec->REG_064 |= CODEC_SOFT_RSTN_ADC(1 << 2) | CODEC_SOFT_RSTN_ADC(1 << 3); + codec->REG_080 |= CODEC_CODEC_ADC_EN_CH2 | CODEC_CODEC_ADC_EN_CH3; + + if (adc_en_map == 0) { + // Reset ADC free running clock and ADC ANA + codec->REG_064 &= ~(RSTN_ADC_FREE_RUNNING_CLK | CODEC_SOFT_RSTN_ADC_ANA_MASK); + codec->REG_064 |= (RSTN_ADC_FREE_RUNNING_CLK | CODEC_SOFT_RSTN_ADC_ANA_MASK); + codec->REG_080 |= CODEC_CODEC_ADC_EN; + } + adc_en_map |= (1 << CODEC_ADC_EN_REQ_DSD); +} + +static void hal_codec_dsd_cfg_stop(void) +{ + adc_en_map &= ~(1 << CODEC_ADC_EN_REQ_DSD); + if (adc_en_map == 0) { + codec->REG_080 &= ~CODEC_CODEC_ADC_EN; + } + + codec->REG_080 &= ~(CODEC_CODEC_ADC_EN_CH2 | CODEC_CODEC_ADC_EN_CH3); + codec->REG_0A4 &= ~(CODEC_CODEC_PDM_ADC_SEL_CH2 | CODEC_CODEC_PDM_ADC_SEL_CH3); + codec->REG_048 = 0; + codec->REG_0B8 = 0; + + codec->REG_080 &= ~CODEC_CODEC_ADC_LOOP; +} +#endif + +#ifdef __AUDIO_RESAMPLE__ +void hal_codec_resample_clock_enable(enum AUD_STREAM_T stream) +{ + uint32_t clk; + bool set = false; + + // 192K-24BIT requires 52M clock, and 384K-24BIT requires 104M clock + if (stream == AUD_STREAM_PLAYBACK) { + clk = codec_dac_sample_rate[resample_rate_idx[AUD_STREAM_PLAYBACK]].sample_rate * RS_CLOCK_FACTOR; + } else { + clk = codec_adc_sample_rate[resample_rate_idx[AUD_STREAM_CAPTURE]].sample_rate * RS_CLOCK_FACTOR; + } + + if (rs_clk_map == 0) { + set = true; + } else { + if (resample_clk_freq < clk) { + set = true; + } + } + + if (set) { + resample_clk_freq = clk; + hal_cmu_codec_rs_enable(clk); + } + + rs_clk_map |= (1 << stream); +} + +void hal_codec_resample_clock_disable(enum AUD_STREAM_T stream) +{ + if (rs_clk_map == 0) { + return; + } + rs_clk_map &= ~(1 << stream); + if (rs_clk_map == 0) { + hal_cmu_codec_rs_disable(); + } +} +#endif + +static void hal_codec_enable_dig_mic(enum AUD_CHANNEL_MAP_T mic_map) +{ + uint32_t phase = 0; + uint32_t line_map = 0; + + phase = codec->REG_0A8; + for (int i = 0; i < MAX_DIG_MIC_CH_NUM; i++) { + if (mic_map & (AUD_CHANNEL_MAP_DIGMIC_CH0 << i)) { + line_map |= (1 << (i / 2)); + } + phase = (phase & ~(CODEC_CODEC_PDM_CAP_PHASE_CH0_MASK << (i * 2))) | + (CODEC_CODEC_PDM_CAP_PHASE_CH0(codec_digmic_phase) << (i * 2)); + } + codec->REG_0A8 = phase; + codec->REG_0A4 |= CODEC_CODEC_PDM_ENABLE; + hal_iomux_set_dig_mic(line_map); +} + +static void hal_codec_disable_dig_mic(void) +{ + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ENABLE; +} + +static void hal_codec_set_ec_down_sel(bool dac_rate_valid) +{ + uint8_t dac_factor; + uint8_t adc_factor; + uint8_t d, a; + uint8_t val; + uint8_t sel = 0; + bool err = false; + + if (dac_rate_valid) { + d = codec_rate_idx[AUD_STREAM_PLAYBACK]; + if (codec_dac_sample_rate[d].sample_rate < AUD_SAMPRATE_44100) { + dac_factor = (6 / codec_dac_sample_rate[d].dac_up) * (codec_dac_sample_rate[d].bypass_cnt + 1); + } else { + // SINC to 48K/44.1K + dac_factor = (6 / 1) * (0 + 1); + } + a = codec_rate_idx[AUD_STREAM_CAPTURE]; + adc_factor = (6 / codec_adc_sample_rate[a].adc_down) * (codec_adc_sample_rate[a].bypass_cnt + 1); + + val = dac_factor / adc_factor; + if (val * adc_factor == dac_factor) { + if (val == 3) { + sel = 0; + } else if (val == 6) { + sel = 1; + } else if (val == 1) { + sel = 2; + } else if (val == 2) { + sel = 3; + } else { + err = true; + } + } else { + err = true; + } + + ASSERT(!err, "%s: Invalid EC sample rate: play=%u cap=%u", __FUNCTION__, + codec_dac_sample_rate[d].sample_rate, codec_adc_sample_rate[a].sample_rate); + } else { + sel = 0; + } + + uint32_t ec_mask, ec_val; + + ec_mask = 0; + ec_val = 0; + if (codec_adc_ch_map & AUD_CHANNEL_MAP_CH5) { + ec_mask |= CODEC_CODEC_DOWN_SEL_MC_CH0_MASK; + ec_val |= CODEC_CODEC_DOWN_SEL_MC_CH0(sel); + } + if (codec_adc_ch_map & AUD_CHANNEL_MAP_CH6) { + ec_mask |= CODEC_CODEC_DOWN_SEL_MC_CH1_MASK; + ec_val |= CODEC_CODEC_DOWN_SEL_MC_CH1(sel); + } + codec->REG_228 = (codec->REG_228 & ~ec_mask) | ec_val; +} + +static void hal_codec_ec_enable(void) +{ + uint32_t ec_val; + bool dac_rate_valid; + uint8_t a; + + dac_rate_valid = !!(codec->REG_000 & CODEC_DAC_ENABLE); + + hal_codec_set_ec_down_sel(dac_rate_valid); + + // If no normal ADC chan, ADC0 must be enabled + if ((codec_adc_ch_map & ~EC_ADC_MAP) == 0) { + a = codec_rate_idx[AUD_STREAM_CAPTURE]; + hal_codec_set_adc_down(AUD_CHANNEL_MAP_CH0, codec_adc_sample_rate[a].adc_down); + hal_codec_set_adc_hbf_bypass_cnt(AUD_CHANNEL_MAP_CH0, codec_adc_sample_rate[a].bypass_cnt); + codec->REG_080 |= CODEC_CODEC_ADC_EN_CH0; + } + + ec_val = 0; + if (codec_adc_ch_map & AUD_CHANNEL_MAP_CH5) { + ec_val |= CODEC_CODEC_MC_ENABLE_CH0; + } + if (codec_adc_ch_map & AUD_CHANNEL_MAP_CH6) { + ec_val |= CODEC_CODEC_MC_ENABLE_CH1; + } + if (codec->REG_0E4 & CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE) { + ec_val |= CODEC_CODEC_RESAMPLE_MC_ENABLE; + if ((codec_adc_ch_map & EC_ADC_MAP) == EC_ADC_MAP) { + ec_val |= CODEC_CODEC_RESAMPLE_MC_DUAL_CH; + } + } + codec->REG_228 |= ec_val; +} + +static void hal_codec_ec_disable(void) +{ + codec->REG_228 &= ~(CODEC_CODEC_MC_ENABLE_CH0 | CODEC_CODEC_MC_ENABLE_CH1 | + CODEC_CODEC_RESAMPLE_MC_ENABLE | CODEC_CODEC_RESAMPLE_MC_DUAL_CH); + if ((codec_adc_ch_map & ~EC_ADC_MAP) == 0 && (anc_adc_ch_map & AUD_CHANNEL_MAP_CH0) == 0) { + codec->REG_080 &= ~CODEC_CODEC_ADC_EN_CH0; + } +} + +int hal_codec_start_interface(enum HAL_CODEC_ID_T id, enum AUD_STREAM_T stream, int dma) +{ + uint32_t fifo_flush = 0; + + if (stream == AUD_STREAM_PLAYBACK) { +#ifdef CODEC_DSD + if (dsd_enabled) { + hal_codec_dsd_cfg_start(); + } +#endif +#ifdef CODEC_MIN_PHASE + if (min_phase_cfg & (1 << AUD_STREAM_PLAYBACK)) { + if (codec_dac_ch_map & AUD_CHANNEL_MAP_CH0) { + codec->REG_100 |= CODEC_FIR_STREAM_ENABLE_CH0; + codec->REG_098 |= CODEC_CODEC_DAC_L_FIR_UPSAMPLE; + } + if (codec_dac_ch_map & AUD_CHANNEL_MAP_CH1) { + codec->REG_100 |= CODEC_FIR_STREAM_ENABLE_CH1; + codec->REG_098 |= CODEC_CODEC_DAC_R_FIR_UPSAMPLE; + } + } +#endif +#ifdef __AUDIO_RESAMPLE__ + if (codec->REG_0E4 & CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE) { + hal_codec_resample_clock_enable(stream); +#if (defined(__TWS__) || defined(IBRT)) && defined(ANC_APP) + enum HAL_CODEC_SYNC_TYPE_T sync_type; + + sync_type = GET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_DAC_TRIGGER_SEL); + if (sync_type != HAL_CODEC_SYNC_TYPE_NONE) { + codec->REG_0E4 = SET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_DAC_TRIGGER_SEL, HAL_CODEC_SYNC_TYPE_NONE); + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + hal_codec_reg_update_delay(); + codec->REG_0F4 = resample_phase_float_to_value(1.0f); + hal_codec_reg_update_delay(); + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + hal_codec_reg_update_delay(); + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + codec->REG_0E4 = SET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_DAC_TRIGGER_SEL, sync_type); + hal_codec_reg_update_delay(); + codec->REG_0F4 = resample_phase_float_to_value(get_playback_resample_phase()); + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + } +#endif + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_DAC_ENABLE; + } +#endif + if ((codec->REG_000 & CODEC_ADC_ENABLE) && (codec_adc_ch_map & EC_ADC_MAP)) { + hal_codec_set_ec_down_sel(true); + } +#ifdef AUDIO_ANC_FB_MC + fifo_flush |= CODEC_MC_FIFO_FLUSH; +#endif + fifo_flush |= CODEC_TX_FIFO_FLUSH; + codec->REG_004 |= fifo_flush; + hal_codec_reg_update_delay(); + codec->REG_004 &= ~fifo_flush; + if (dma) { + codec->REG_008 = SET_BITFIELD(codec->REG_008, CODEC_CODEC_TX_THRESHOLD, HAL_CODEC_TX_FIFO_TRIGGER_LEVEL); + codec->REG_000 |= CODEC_DMACTRL_TX; + // Delay a little time for DMA to fill the TX FIFO before sending + for (volatile int i = 0; i < 50; i++); + } +#ifdef AUDIO_ANC_FB_MC + if (mc_dual_chan) { + codec->REG_04C |= CODEC_DUAL_CHANNEL_MC; + } else { + codec->REG_04C &= ~CODEC_DUAL_CHANNEL_MC; + } + if (mc_16bit) { + codec->REG_04C |= CODEC_MODE_16BIT_MC; + } else { + codec->REG_04C &= ~CODEC_MODE_16BIT_MC; + } + if (adc_en_map == 0) { + // Reset ADC free running clock and ADC ANA + codec->REG_064 &= ~(RSTN_ADC_FREE_RUNNING_CLK | CODEC_SOFT_RSTN_ADC_ANA_MASK); + codec->REG_064 |= (RSTN_ADC_FREE_RUNNING_CLK | CODEC_SOFT_RSTN_ADC_ANA_MASK); + codec->REG_080 |= CODEC_CODEC_ADC_EN; + } + adc_en_map |= (1 << CODEC_ADC_EN_REQ_MC); + // If codec function has been enabled, start FIFOs directly; + // otherwise, start FIFOs after PA is enabled + if (codec->REG_098 & CODEC_CODEC_DAC_EN) { + uint32_t lock; + lock = int_lock(); + // MC FIFO and DAC FIFO must be started at the same time + codec->REG_04C |= CODEC_MC_ENABLE; + codec->REG_000 |= CODEC_DAC_ENABLE; + int_unlock(lock); + } + mc_enabled = true; +#else + codec->REG_000 |= CODEC_DAC_ENABLE; +#endif + } else { +#ifdef VOICE_DETECTOR_EN + if ((codec_adc_ch_map & AUD_CHANNEL_MAP_CH4) && + (vad_type == AUD_VAD_TYPE_MIX || vad_type == AUD_VAD_TYPE_DIG)) { + // Stop vad buffering + hal_codec_vad_stop(); + } +#endif +#ifdef CODEC_MIN_PHASE + if (min_phase_cfg & (1 << AUD_STREAM_CAPTURE)) { + if (codec_adc_ch_map & AUD_CHANNEL_MAP_CH2) { + codec->REG_100 |= CODEC_FIR_STREAM_ENABLE_CH2; + codec->REG_0D0 |= CODEC_CODEC_ADC_FIR_DS_EN_CH2; + } + if (codec_adc_ch_map & AUD_CHANNEL_MAP_CH3) { + codec->REG_100 |= CODEC_FIR_STREAM_ENABLE_CH3; + codec->REG_0D0 |= CODEC_CODEC_ADC_FIR_DS_EN_CH3; + } + } +#endif +#ifdef __AUDIO_RESAMPLE__ + if (codec->REG_0E4 & CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE) { + hal_codec_resample_clock_enable(stream); +#if (defined(__TWS__) || defined(IBRT)) && defined(ANC_APP) + enum HAL_CODEC_SYNC_TYPE_T sync_type; + + sync_type = GET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_ADC_TRIGGER_SEL); + if (sync_type != HAL_CODEC_SYNC_TYPE_NONE) { + codec->REG_0E4 = SET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_ADC_TRIGGER_SEL, HAL_CODEC_SYNC_TYPE_NONE); + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + hal_codec_reg_update_delay(); + codec->REG_0F8 = resample_phase_float_to_value(1.0f); + hal_codec_reg_update_delay(); + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + hal_codec_reg_update_delay(); + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + codec->REG_0E4 = SET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_ADC_TRIGGER_SEL, sync_type); + hal_codec_reg_update_delay(); + codec->REG_0F8 = resample_phase_float_to_value(get_capture_resample_phase()); + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + } +#endif + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_ADC_ENABLE; + } +#endif + if (codec_mic_ch_map & AUD_CHANNEL_MAP_DIGMIC_ALL) { + hal_codec_enable_dig_mic(codec_mic_ch_map); + } + if (codec_adc_ch_map & EC_ADC_MAP) { + hal_codec_ec_enable(); + } + for (int i = 0; i < MAX_ADC_CH_NUM; i++) { + if (codec_adc_ch_map & (AUD_CHANNEL_MAP_CH0 << i)) { + if (i < NORMAL_ADC_CH_NUM && + (codec->REG_080 & (CODEC_CODEC_ADC_EN_CH0 << i)) == 0) { + // Reset ADC channel + codec->REG_064 &= ~CODEC_SOFT_RSTN_ADC(1 << i); + codec->REG_064 |= CODEC_SOFT_RSTN_ADC(1 << i); + codec->REG_080 |= (CODEC_CODEC_ADC_EN_CH0 << i); + } + codec->REG_000 |= (CODEC_ADC_ENABLE_CH0 << i); + } + } + fifo_flush = CODEC_RX_FIFO_FLUSH_CH0 | CODEC_RX_FIFO_FLUSH_CH1 | CODEC_RX_FIFO_FLUSH_CH2 | + CODEC_RX_FIFO_FLUSH_CH3 | CODEC_RX_FIFO_FLUSH_CH4 | CODEC_RX_FIFO_FLUSH_CH5 | CODEC_RX_FIFO_FLUSH_CH6; + codec->REG_004 |= fifo_flush; + hal_codec_reg_update_delay(); + codec->REG_004 &= ~fifo_flush; + if (dma) { + codec->REG_008 = SET_BITFIELD(codec->REG_008, CODEC_CODEC_RX_THRESHOLD, HAL_CODEC_RX_FIFO_TRIGGER_LEVEL); + codec->REG_000 |= CODEC_DMACTRL_RX; + } + codec->REG_000 |= CODEC_ADC_ENABLE; + } + + return 0; +} + +int hal_codec_stop_interface(enum HAL_CODEC_ID_T id, enum AUD_STREAM_T stream) +{ + uint32_t fifo_flush = 0; + + if (stream == AUD_STREAM_PLAYBACK) { + codec->REG_000 &= ~CODEC_DAC_ENABLE; + codec->REG_000 &= ~CODEC_DMACTRL_TX; +#ifdef __AUDIO_RESAMPLE__ + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_DAC_ENABLE; + hal_codec_resample_clock_disable(stream); +#endif +#ifdef CODEC_MIN_PHASE + if (min_phase_cfg & (1 << AUD_STREAM_PLAYBACK)) { + if (codec_dac_ch_map & AUD_CHANNEL_MAP_CH0) { + codec->REG_100 &= ~CODEC_FIR_STREAM_ENABLE_CH0; + codec->REG_098 &= ~CODEC_CODEC_DAC_L_FIR_UPSAMPLE; + } + if (codec_dac_ch_map & AUD_CHANNEL_MAP_CH1) { + codec->REG_100 &= ~CODEC_FIR_STREAM_ENABLE_CH1; + codec->REG_098 &= ~CODEC_CODEC_DAC_R_FIR_UPSAMPLE; + } + } +#endif +#ifdef CODEC_DSD + hal_codec_dsd_cfg_stop(); + dsd_enabled = false; +#endif +#ifdef AUDIO_ANC_FB_MC + mc_enabled = false; + codec->REG_04C &= ~CODEC_MC_ENABLE; + adc_en_map &= ~(1 << CODEC_ADC_EN_REQ_MC); + if (adc_en_map == 0) { + codec->REG_080 &= ~CODEC_CODEC_ADC_EN; + } + fifo_flush |= CODEC_MC_FIFO_FLUSH; +#endif + fifo_flush |= CODEC_TX_FIFO_FLUSH; + codec->REG_004 |= fifo_flush; + hal_codec_reg_update_delay(); + codec->REG_004 &= ~fifo_flush; + // Cancel dac sync request + hal_codec_sync_dac_disable(); + hal_codec_sync_dac_resample_rate_disable(); + hal_codec_sync_dac_gain_disable(); +#ifdef NO_DAC_RESET + // Clean up DAC intermediate states + osDelay(dac_delay_ms); +#endif + } else { + codec->REG_000 &= ~(CODEC_ADC_ENABLE | CODEC_ADC_ENABLE_CH0 | CODEC_ADC_ENABLE_CH1 | CODEC_ADC_ENABLE_CH2 | + CODEC_ADC_ENABLE_CH3 | CODEC_ADC_ENABLE_CH4 | CODEC_ADC_ENABLE_CH5 | CODEC_ADC_ENABLE_CH6); + codec->REG_000 &= ~CODEC_DMACTRL_RX; + for (int i = 0; i < MAX_ADC_CH_NUM; i++) { + if (i < NORMAL_ADC_CH_NUM && + (codec_adc_ch_map & (AUD_CHANNEL_MAP_CH0 << i)) && + (anc_adc_ch_map & (AUD_CHANNEL_MAP_CH0 << i)) == 0) { + codec->REG_080 &= ~(CODEC_CODEC_ADC_EN_CH0 << i); + } + } + if (codec_adc_ch_map & EC_ADC_MAP) { + hal_codec_ec_disable(); + } + if ((codec_mic_ch_map & AUD_CHANNEL_MAP_DIGMIC_ALL) && + (anc_mic_ch_map & AUD_CHANNEL_MAP_DIGMIC_ALL) == 0) { + hal_codec_disable_dig_mic(); + } +#ifdef __AUDIO_RESAMPLE__ + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_ADC_ENABLE; + hal_codec_resample_clock_disable(stream); +#endif +#ifdef CODEC_MIN_PHASE + if (min_phase_cfg & (1 << AUD_STREAM_CAPTURE)) { + if (codec_adc_ch_map & AUD_CHANNEL_MAP_CH2) { + codec->REG_100 &= ~CODEC_FIR_STREAM_ENABLE_CH2; + codec->REG_0D0 &= ~CODEC_CODEC_ADC_FIR_DS_EN_CH2; + } + if (codec_adc_ch_map & AUD_CHANNEL_MAP_CH3) { + codec->REG_100 &= ~CODEC_FIR_STREAM_ENABLE_CH3; + codec->REG_0D0 &= ~CODEC_CODEC_ADC_FIR_DS_EN_CH3; + } + } +#endif + fifo_flush = CODEC_RX_FIFO_FLUSH_CH0 | CODEC_RX_FIFO_FLUSH_CH1 | CODEC_RX_FIFO_FLUSH_CH2 | + CODEC_RX_FIFO_FLUSH_CH3 | CODEC_RX_FIFO_FLUSH_CH4 | CODEC_RX_FIFO_FLUSH_CH5 | CODEC_RX_FIFO_FLUSH_CH6; + codec->REG_004 |= fifo_flush; + hal_codec_reg_update_delay(); + codec->REG_004 &= ~fifo_flush; + // Cancel adc sync request + hal_codec_sync_adc_disable(); + hal_codec_sync_adc_resample_rate_disable(); + hal_codec_sync_adc_gain_disable(); + } + + return 0; +} + +static void hal_codec_set_dac_gain_value(enum AUD_CHANNEL_MAP_T map, uint32_t val) +{ + codec->REG_09C &= ~CODEC_CODEC_DAC_GAIN_UPDATE; + hal_codec_reg_update_delay(); + if (map & AUD_CHANNEL_MAP_CH0) { + codec->REG_09C = SET_BITFIELD(codec->REG_09C, CODEC_CODEC_DAC_GAIN_CH0, val); + } + if (map & AUD_CHANNEL_MAP_CH1) { + codec->REG_0A0 = SET_BITFIELD(codec->REG_0A0, CODEC_CODEC_DAC_GAIN_CH1, val); + } + codec->REG_09C |= CODEC_CODEC_DAC_GAIN_UPDATE; +} + +void hal_codec_get_dac_gain(float *left_gain, float *right_gain) +{ + struct DAC_GAIN_T { + int32_t v : 20; + }; + + struct DAC_GAIN_T left; + struct DAC_GAIN_T right; + + left.v = GET_BITFIELD(codec->REG_09C, CODEC_CODEC_DAC_GAIN_CH0); + right.v = GET_BITFIELD(codec->REG_0A0, CODEC_CODEC_DAC_GAIN_CH1); + + *left_gain = left.v; + *right_gain = right.v; + + // Gain format: 6.14 + *left_gain /= (1 << 14); + *right_gain /= (1 << 14); +} + +void hal_codec_dac_mute(bool mute) +{ + codec_mute[AUD_STREAM_PLAYBACK] = mute; + +#ifdef AUDIO_OUTPUT_SW_GAIN + hal_codec_set_sw_gain(swdac_gain); +#else + if (mute) { + hal_codec_set_dac_gain_value(VALID_DAC_MAP, 0); + } else { + hal_codec_restore_dig_dac_gain(); + } +#endif +} + +static float db_to_amplitude_ratio(int32_t db) +{ + float coef; + + if (db == ZERODB_DIG_DBVAL) { + coef = 1; + } else if (db <= MIN_DIG_DBVAL) { + coef = 0; + } else { + if (db > MAX_DIG_DBVAL) { + db = MAX_DIG_DBVAL; + } + coef = db_to_float(db); + } + + return coef; +} + +static float digdac_gain_to_float(int32_t gain) +{ + float coef; + +#if defined(NOISE_GATING) && defined(NOISE_REDUCTION) + gain += digdac_gain_offset_nr; +#endif + + coef = db_to_amplitude_ratio(gain); + +#ifdef AUDIO_OUTPUT_DC_CALIB + coef *= dac_dc_gain_attn; +#endif + +#ifdef ANC_APP + coef *= anc_boost_gain_attn; +#endif + +#if 0 + static const float thd_attn = 0.982878873; // -0.15dB + + // Ensure that THD is good at max gain + if (coef > thd_attn) { + coef = thd_attn; + } +#endif + + return coef; +} + +static void hal_codec_set_dig_dac_gain(enum AUD_CHANNEL_MAP_T map, int32_t gain) +{ + uint32_t val; + float coef; + bool mute; + + if (map & AUD_CHANNEL_MAP_CH0) { + digdac_gain[0] = gain; + } + if (map & AUD_CHANNEL_MAP_CH1) { + digdac_gain[1] = gain; + } + +#ifdef AUDIO_OUTPUT_SW_GAIN + mute = false; +#else + mute = codec_mute[AUD_STREAM_PLAYBACK]; +#endif + +#ifdef AUDIO_OUTPUT_DC_CALIB_ANA + if (codec->REG_098 & CODEC_CODEC_DAC_SDM_CLOSE) { + mute = true; + } +#endif + + if (mute) { + val = 0; + } else { + coef = digdac_gain_to_float(gain); + + // Gain format: 6.14 + int32_t s_val = (int32_t)(coef * (1 << 14)); + val = __SSAT(s_val, 20); + } + + hal_codec_set_dac_gain_value(map, val); +} + +static void hal_codec_restore_dig_dac_gain(void) +{ + if (digdac_gain[0] == digdac_gain[1]) { + hal_codec_set_dig_dac_gain(VALID_DAC_MAP, digdac_gain[0]); + } else { + hal_codec_set_dig_dac_gain(AUD_CHANNEL_MAP_CH0, digdac_gain[0]); + hal_codec_set_dig_dac_gain(AUD_CHANNEL_MAP_CH1, digdac_gain[1]); + } +} + +#ifdef AUDIO_OUTPUT_SW_GAIN +static void hal_codec_set_sw_gain(int32_t gain) +{ + float coef; + bool mute; + + swdac_gain = gain; + + mute = codec_mute[AUD_STREAM_PLAYBACK]; + + if (mute) { + coef = 0; + } else { + coef = digdac_gain_to_float(gain); + } + + if (sw_output_coef_callback) { + sw_output_coef_callback(coef); + } +} + +void hal_codec_set_sw_output_coef_callback(HAL_CODEC_SW_OUTPUT_COEF_CALLBACK callback) +{ + sw_output_coef_callback = callback; +} +#endif + +static void hal_codec_set_adc_gain_value(enum AUD_CHANNEL_MAP_T map, uint32_t val) +{ + uint32_t gain_update = 0; + + for (int i = 0; i < NORMAL_ADC_CH_NUM; i++) { + if (map & (AUD_CHANNEL_MAP_CH0 << i)) { + *(&codec->REG_084 + i) = SET_BITFIELD(*(&codec->REG_084 + i), CODEC_CODEC_ADC_GAIN_CH0, val); + gain_update |= (CODEC_CODEC_ADC_GAIN_UPDATE_CH0 << i); + } + } + codec->REG_09C &= ~gain_update; + hal_codec_reg_update_delay(); + codec->REG_09C |= gain_update; +} + +static void hal_codec_set_dig_adc_gain(enum AUD_CHANNEL_MAP_T map, int32_t gain) +{ + uint32_t val; + float coef; + bool mute; + int i; + int32_t s_val; + + for (i = 0; i < NORMAL_ADC_CH_NUM; i++) { + if (map & (1 << i)) { + digadc_gain[i] = gain; + } + } + + mute = codec_mute[AUD_STREAM_CAPTURE]; + + if (mute) { + val = 0; + } else { +#ifdef ANC_APP + enum AUD_CHANNEL_MAP_T adj_map; + int32_t anc_gain; + + adj_map = map & anc_adc_gain_offset_map; + while (adj_map) { + i = get_msb_pos(adj_map); + adj_map &= ~(1 << i); + anc_gain = gain + anc_adc_gain_offset[i]; + coef = db_to_amplitude_ratio(anc_gain); + coef /= anc_boost_gain_attn; + // Gain format: 8.12 + s_val = (int32_t)(coef * (1 << 12)); + val = __SSAT(s_val, 20); + hal_codec_set_adc_gain_value((1 << i), val); + } + + map &= ~anc_adc_gain_offset_map; +#endif + + if (map) { + coef = db_to_amplitude_ratio(gain); +#ifdef ANC_APP + coef /= anc_boost_gain_attn; +#endif + // Gain format: 8.12 + s_val = (int32_t)(coef * (1 << 12)); + val = __SSAT(s_val, 20); + } else { + val = 0; + } + } + + hal_codec_set_adc_gain_value(map, val); +} + +static void hal_codec_restore_dig_adc_gain(void) +{ + int i; + + for (i = 0; i < NORMAL_ADC_CH_NUM; i++) { + hal_codec_set_dig_adc_gain((1 << i), digadc_gain[i]); + } +} + +static void POSSIBLY_UNUSED hal_codec_get_adc_gain(enum AUD_CHANNEL_MAP_T map, float *gain) +{ + struct ADC_GAIN_T { + int32_t v : 20; + }; + + struct ADC_GAIN_T adc_val; + + for (int i = 0; i < NORMAL_ADC_CH_NUM; i++) { + if (map & (AUD_CHANNEL_MAP_CH0 << i)) { + adc_val.v = GET_BITFIELD(*(&codec->REG_084 + i), CODEC_CODEC_ADC_GAIN_CH0); + + *gain = adc_val.v; + // Gain format: 8.12 + *gain /= (1 << 12); + return; + } + } + + *gain = 0; +} + +void hal_codec_adc_mute(bool mute) +{ + codec_mute[AUD_STREAM_CAPTURE] = mute; + + if (mute) { + hal_codec_set_adc_gain_value(NORMAL_ADC_MAP, 0); + } else { + hal_codec_restore_dig_adc_gain(); + } +} + +int hal_codec_set_chan_vol(enum AUD_STREAM_T stream, enum AUD_CHANNEL_MAP_T ch_map, uint8_t vol) +{ + if (stream == AUD_STREAM_PLAYBACK) { +#ifdef AUDIO_OUTPUT_SW_GAIN + ASSERT(false, "%s: Cannot set play chan vol with AUDIO_OUTPUT_SW_GAIN", __func__); +#else +#ifdef SINGLE_CODEC_DAC_VOL + ASSERT(false, "%s: Cannot set play chan vol with SINGLE_CODEC_DAC_VOL", __func__); +#else + const struct CODEC_DAC_VOL_T *vol_tab_ptr; + + vol_tab_ptr = hal_codec_get_dac_volume(vol); + if (vol_tab_ptr) { + if (ch_map & AUD_CHANNEL_MAP_CH0) { + hal_codec_set_dig_dac_gain(AUD_CHANNEL_MAP_CH0, vol_tab_ptr->sdac_volume); + } + if (ch_map & AUD_CHANNEL_MAP_CH1) { + hal_codec_set_dig_dac_gain(AUD_CHANNEL_MAP_CH1, vol_tab_ptr->sdac_volume); + } + } +#endif +#endif + } else { +#ifdef SINGLE_CODEC_ADC_VOL + ASSERT(false, "%s: Cannot set cap chan vol with SINGLE_CODEC_ADC_VOL", __func__); +#else + uint8_t mic_ch, adc_ch; + enum AUD_CHANNEL_MAP_T map; + const CODEC_ADC_VOL_T *adc_gain_db; + + adc_gain_db = hal_codec_get_adc_volume(vol); + if (adc_gain_db) { + map = ch_map & ~EC_MIC_MAP; + while (map) { + mic_ch = get_lsb_pos(map); + map &= ~(1 << mic_ch); + adc_ch = hal_codec_get_adc_chan(1 << mic_ch); + ASSERT(adc_ch < NORMAL_ADC_CH_NUM, "%s: Bad cap ch_map=0x%X (ch=%u)", __func__, ch_map, mic_ch); + hal_codec_set_dig_adc_gain((1 << adc_ch), *adc_gain_db); + } + } +#endif + } + + return 0; +} + +static int hal_codec_set_dac_hbf_bypass_cnt(uint32_t cnt) +{ + uint32_t bypass = 0; + uint32_t bypass_mask = CODEC_CODEC_DAC_HBF1_BYPASS | CODEC_CODEC_DAC_HBF2_BYPASS | CODEC_CODEC_DAC_HBF3_BYPASS; + + if (cnt == 0) { + } else if (cnt == 1) { + bypass = CODEC_CODEC_DAC_HBF3_BYPASS; + } else if (cnt == 2) { + bypass = CODEC_CODEC_DAC_HBF2_BYPASS | CODEC_CODEC_DAC_HBF3_BYPASS; + } else if (cnt == 3) { + bypass = CODEC_CODEC_DAC_HBF1_BYPASS | CODEC_CODEC_DAC_HBF2_BYPASS | CODEC_CODEC_DAC_HBF3_BYPASS; + } else { + ASSERT(false, "%s: Invalid dac bypass cnt: %u", __FUNCTION__, cnt); + } + + // OSR is fixed to 512 + //codec->REG_098 = SET_BITFIELD(codec->REG_098, CODEC_CODEC_DAC_OSR_SEL, 2); + + codec->REG_098 = (codec->REG_098 & ~bypass_mask) | bypass; + return 0; +} + +static int hal_codec_set_dac_up(uint32_t val) +{ + uint32_t sel = 0; + + if (val == 2) { + sel = 0; + } else if (val == 3) { + sel = 1; + } else if (val == 4) { + sel = 2; + } else if (val == 6) { + sel = 3; + } else if (val == 1) { + sel = 4; + } else { + ASSERT(false, "%s: Invalid dac up: %u", __FUNCTION__, val); + } + codec->REG_098 = SET_BITFIELD(codec->REG_098, CODEC_CODEC_DAC_UP_SEL, sel); + return 0; +} + +static uint32_t POSSIBLY_UNUSED hal_codec_get_dac_up(void) +{ + uint32_t sel; + + sel = GET_BITFIELD(codec->REG_098, CODEC_CODEC_DAC_UP_SEL); + if (sel == 0) { + return 2; + } else if (sel == 1) { + return 3; + } else if (sel == 2) { + return 4; + } else if (sel == 3) { + return 6; + } else { + return 1; + } +} + +static int hal_codec_set_adc_down(enum AUD_CHANNEL_MAP_T map, uint32_t val) +{ + uint32_t sel = 0; + + if (val == 3) { + sel = 0; + } else if (val == 6) { + sel = 1; + } else if (val == 1) { + sel = 2; + } else { + ASSERT(false, "%s: Invalid adc down: %u", __FUNCTION__, val); + } + for (int i = 0; i < NORMAL_ADC_CH_NUM; i++) { + if (map & (AUD_CHANNEL_MAP_CH0 << i)) { + *(&codec->REG_084 + i) = SET_BITFIELD(*(&codec->REG_084 + i), CODEC_CODEC_ADC_DOWN_SEL_CH0, sel); + } + } + return 0; +} + +static int hal_codec_set_adc_hbf_bypass_cnt(enum AUD_CHANNEL_MAP_T map, uint32_t cnt) +{ + uint32_t bypass = 0; + uint32_t bypass_mask = CODEC_CODEC_ADC_HBF1_BYPASS_CH0 | CODEC_CODEC_ADC_HBF2_BYPASS_CH0 | CODEC_CODEC_ADC_HBF3_BYPASS_CH0; + + if (cnt == 0) { + } else if (cnt == 1) { + bypass = CODEC_CODEC_ADC_HBF3_BYPASS_CH0; + } else if (cnt == 2) { + bypass = CODEC_CODEC_ADC_HBF2_BYPASS_CH0 | CODEC_CODEC_ADC_HBF3_BYPASS_CH0; + } else if (cnt == 3) { + bypass = CODEC_CODEC_ADC_HBF1_BYPASS_CH0 | CODEC_CODEC_ADC_HBF2_BYPASS_CH0 | CODEC_CODEC_ADC_HBF3_BYPASS_CH0; + } else { + ASSERT(false, "%s: Invalid bypass cnt: %u", __FUNCTION__, cnt); + } + for (int i = 0; i < NORMAL_ADC_CH_NUM; i++) { + if (map & (AUD_CHANNEL_MAP_CH0 << i)) { + *(&codec->REG_084 + i) = (*(&codec->REG_084 + i) & ~bypass_mask) | bypass; + } + } + return 0; +} + +#ifdef __AUDIO_RESAMPLE__ +static float get_playback_resample_phase(void) +{ + return (float)codec_dac_sample_rate[resample_rate_idx[AUD_STREAM_PLAYBACK]].codec_freq / hal_cmu_get_crystal_freq(); +} + +static float get_capture_resample_phase(void) +{ + return (float)hal_cmu_get_crystal_freq() / codec_adc_sample_rate[resample_rate_idx[AUD_STREAM_CAPTURE]].codec_freq; +} + +static uint32_t resample_phase_float_to_value(float phase) +{ + if (phase >= 4.0) { + return (uint32_t)-1; + } else { + // Phase format: 2.30 + return (uint32_t)(phase * (1 << 30)); + } +} + +static float POSSIBLY_UNUSED resample_phase_value_to_float(uint32_t value) +{ + // Phase format: 2.30 + return (float)value / (1 << 30); +} +#endif + +#ifdef SIDETONE_ENABLE +static void hal_codec_set_sidetone_adc_chan(enum AUD_CHANNEL_MAP_T chan_map) +{ + if (chan_map == AUD_CHANNEL_MAP_CH0) { + codec->REG_080 &= ~CODEC_CODEC_SIDE_TONE_MIC_SEL; + codec->REG_078 &= ~CODEC_CODEC_SIDE_TONE_CH_SEL; + } else if (chan_map == AUD_CHANNEL_MAP_CH2) { + codec->REG_080 &= ~CODEC_CODEC_SIDE_TONE_MIC_SEL; + codec->REG_078 |= CODEC_CODEC_SIDE_TONE_CH_SEL; + } else if (chan_map == AUD_CHANNEL_MAP_CH4) { + codec->REG_080 |= CODEC_CODEC_SIDE_TONE_MIC_SEL; + } +} +#endif + +int hal_codec_setup_stream(enum HAL_CODEC_ID_T id, enum AUD_STREAM_T stream, const struct HAL_CODEC_CONFIG_T *cfg) +{ + int i; + int rate_idx; + uint32_t ana_dig_div; + enum AUD_SAMPRATE_T sample_rate; + + if (stream == AUD_STREAM_PLAYBACK) { + if ((HAL_CODEC_CONFIG_CHANNEL_MAP | HAL_CODEC_CONFIG_CHANNEL_NUM) & cfg->set_flag) { + if (cfg->channel_num == AUD_CHANNEL_NUM_2) { + if (cfg->channel_map != (AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1)) { + TRACE(2,"\n!!! WARNING:%s: Bad play stereo ch map: 0x%X\n", __func__, cfg->channel_map); + } + codec->REG_044 |= CODEC_DUAL_CHANNEL_DAC; + } else { + ASSERT(cfg->channel_num == AUD_CHANNEL_NUM_1, "%s: Bad play ch num: %u", __func__, cfg->channel_num); + // Allow to DMA one channel but output 2 channels + ASSERT((cfg->channel_map & ~(AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1)) == 0, + "%s: Bad play mono ch map: 0x%X", __func__, cfg->channel_map); + codec->REG_044 &= ~CODEC_DUAL_CHANNEL_DAC; + } + codec_dac_ch_map = AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1; + } + + if (HAL_CODEC_CONFIG_BITS & cfg->set_flag) { + if (cfg->bits == AUD_BITS_16) { + codec->REG_044 = (codec->REG_044 & ~CODEC_MODE_32BIT_DAC) | CODEC_MODE_16BIT_DAC; + codec->REG_04C = (codec->REG_04C & ~CODEC_MODE_32BIT_MC) | CODEC_MODE_16BIT_MC; + } else if (cfg->bits == AUD_BITS_24) { + codec->REG_044 &= ~(CODEC_MODE_16BIT_DAC | CODEC_MODE_32BIT_DAC); + codec->REG_04C &= ~(CODEC_MODE_16BIT_MC | CODEC_MODE_32BIT_MC); + } else if (cfg->bits == AUD_BITS_32) { + codec->REG_044 = (codec->REG_044 & ~CODEC_MODE_16BIT_DAC) | CODEC_MODE_32BIT_DAC; + codec->REG_04C = (codec->REG_04C & ~CODEC_MODE_16BIT_MC) | CODEC_MODE_32BIT_MC; + } else { + ASSERT(false, "%s: Bad play bits: %u", __func__, cfg->bits); + } + } + + if (HAL_CODEC_CONFIG_SAMPLE_RATE & cfg->set_flag) { + sample_rate = cfg->sample_rate; +#ifdef CODEC_DSD + if (dsd_enabled) { + if (sample_rate == AUD_SAMPRATE_176400) { + dsd_rate_idx = 0; + } else if (sample_rate == AUD_SAMPRATE_352800) { + dsd_rate_idx = 1; + } else if (sample_rate == AUD_SAMPRATE_705600) { + dsd_rate_idx = 2; + } else { + ASSERT(false, "%s: Bad DSD sample rate: %u", __func__, sample_rate); + } + sample_rate = AUD_SAMPRATE_44100; + } +#endif + + for (i = 0; i < ARRAY_SIZE(codec_dac_sample_rate); i++) { + if (codec_dac_sample_rate[i].sample_rate == sample_rate) { + break; + } + } + ASSERT(i < ARRAY_SIZE(codec_dac_sample_rate), "%s: Invalid playback sample rate: %u", __func__, sample_rate); + rate_idx = i; + ana_dig_div = codec_dac_sample_rate[rate_idx].codec_div / codec_dac_sample_rate[rate_idx].cmu_div; + ASSERT(ana_dig_div * codec_dac_sample_rate[rate_idx].cmu_div == codec_dac_sample_rate[rate_idx].codec_div, + "%s: Invalid playback div for rate %u: codec_div=%u cmu_div=%u", __func__, sample_rate, + codec_dac_sample_rate[rate_idx].codec_div, codec_dac_sample_rate[rate_idx].cmu_div); + + TRACE(2,"[%s] playback sample_rate=%d", __func__, sample_rate); + +#ifdef CODEC_TIMER + cur_codec_freq = codec_dac_sample_rate[rate_idx].codec_freq; +#endif + + codec_rate_idx[AUD_STREAM_PLAYBACK] = rate_idx; + +#ifdef __AUDIO_RESAMPLE__ + uint32_t mask, val; + + if (hal_cmu_get_audio_resample_status() && codec_dac_sample_rate[rate_idx].codec_freq != CODEC_FREQ_CRYSTAL) { +#ifdef CODEC_TIMER + cur_codec_freq = CODEC_FREQ_CRYSTAL; +#endif + if ((codec->REG_0E4 & CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE) == 0 || + resample_rate_idx[AUD_STREAM_PLAYBACK] != rate_idx) { + resample_rate_idx[AUD_STREAM_PLAYBACK] = rate_idx; + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + hal_codec_reg_update_delay(); + codec->REG_0F4 = resample_phase_float_to_value(get_playback_resample_phase()); + hal_codec_reg_update_delay(); + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + } + + mask = CODEC_CODEC_RESAMPLE_DAC_L_ENABLE | CODEC_CODEC_RESAMPLE_DAC_R_ENABLE; + val = 0; + if (codec_dac_ch_map & AUD_CHANNEL_MAP_CH0) { + val |= CODEC_CODEC_RESAMPLE_DAC_L_ENABLE; + } + if (codec_dac_ch_map & AUD_CHANNEL_MAP_CH1) { + val |= CODEC_CODEC_RESAMPLE_DAC_R_ENABLE; + } + } else { + mask = CODEC_CODEC_RESAMPLE_DAC_L_ENABLE | CODEC_CODEC_RESAMPLE_DAC_R_ENABLE | + CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + val = 0; + } + codec->REG_0E4 = (codec->REG_0E4 & ~mask) | val; +#endif + + // 8K -> 4ms, 16K -> 2ms, ... + dac_delay_ms = 4 / ((sample_rate + AUD_SAMPRATE_8000 / 2) / AUD_SAMPRATE_8000); + if (dac_delay_ms < 2) { + dac_delay_ms = 2; + } + +#ifdef __AUDIO_RESAMPLE__ + if (!hal_cmu_get_audio_resample_status()) +#endif + { +#ifdef __AUDIO_RESAMPLE__ + ASSERT(codec_dac_sample_rate[rate_idx].codec_freq != CODEC_FREQ_CRYSTAL, + "%s: playback sample rate %u is for resample only", __func__, sample_rate); +#endif + analog_aud_freq_pll_config(codec_dac_sample_rate[rate_idx].codec_freq, codec_dac_sample_rate[rate_idx].codec_div); + hal_cmu_codec_dac_set_div(codec_dac_sample_rate[rate_idx].cmu_div * CODEC_FREQ_EXTRA_DIV); + } + hal_codec_set_dac_up(codec_dac_sample_rate[rate_idx].dac_up); + hal_codec_set_dac_hbf_bypass_cnt(codec_dac_sample_rate[rate_idx].bypass_cnt); +#ifdef AUDIO_ANC_FB_MC + codec->REG_04C = SET_BITFIELD(codec->REG_04C, CODEC_MC_DELAY, codec_dac_sample_rate[rate_idx].mc_delay); +#endif + } + + if (HAL_CODEC_CONFIG_VOL & cfg->set_flag) { + const struct CODEC_DAC_VOL_T *vol_tab_ptr; + + vol_tab_ptr = hal_codec_get_dac_volume(cfg->vol); + if (vol_tab_ptr) { +#ifdef AUDIO_OUTPUT_SW_GAIN + hal_codec_set_sw_gain(vol_tab_ptr->sdac_volume); +#else + analog_aud_set_dac_gain(vol_tab_ptr->tx_pa_gain); + hal_codec_set_dig_dac_gain(VALID_DAC_MAP, vol_tab_ptr->sdac_volume); +#endif +#ifdef PERF_TEST_POWER_KEY + // Update performance test power after applying new dac volume + hal_codec_update_perf_test_power(); +#endif + } + } + } else { + enum AUD_CHANNEL_MAP_T mic_map; + enum AUD_CHANNEL_MAP_T reserv_map; + uint8_t cnt; + uint8_t ch_idx; + uint32_t cfg_set_mask; + uint32_t cfg_clr_mask; +#ifdef VOICE_DETECTOR_EN + uint32_t adc_channel_en = 0; +#endif + + mic_map = 0; + if ((HAL_CODEC_CONFIG_CHANNEL_MAP | HAL_CODEC_CONFIG_CHANNEL_NUM) & cfg->set_flag) { + codec_adc_ch_map = 0; + codec_mic_ch_map = 0; + mic_map = cfg->channel_map; + } + + if (mic_map) { + codec_mic_ch_map = mic_map; + reserv_map = 0; + +#ifdef ANC_APP +#if defined(ANC_FF_MIC_CH_L) || defined(ANC_FF_MIC_CH_R) +#ifdef ANC_PROD_TEST + if ((ANC_FF_MIC_CH_L & ~NORMAL_MIC_MAP) || (ANC_FF_MIC_CH_L & (ANC_FF_MIC_CH_L - 1))) { + ASSERT(false, "Invalid ANC_FF_MIC_CH_L: 0x%04X", ANC_FF_MIC_CH_L); + } + if ((ANC_FF_MIC_CH_R & ~NORMAL_MIC_MAP) || (ANC_FF_MIC_CH_R & (ANC_FF_MIC_CH_R - 1))) { + ASSERT(false, "Invalid ANC_FF_MIC_CH_R: 0x%04X", ANC_FF_MIC_CH_R); + } + if (ANC_FF_MIC_CH_L & ANC_FF_MIC_CH_R) { + ASSERT(false, "Conflicted ANC_FF_MIC_CH_L (0x%04X) and ANC_FF_MIC_CH_R (0x%04X)", ANC_FF_MIC_CH_L, ANC_FF_MIC_CH_R); + } +#if defined(ANC_FB_MIC_CH_L) || defined(ANC_FB_MIC_CH_R) + if ((ANC_FF_MIC_CH_L & ANC_FB_MIC_CH_L) || (ANC_FF_MIC_CH_L & ANC_FB_MIC_CH_R) || + (ANC_FF_MIC_CH_R & ANC_FB_MIC_CH_L) || (ANC_FF_MIC_CH_R & ANC_FB_MIC_CH_R)) { + ASSERT(false, "Conflicted FF MIC (0x%04X/0x%04X) and FB MIC (0x%04X/0x%04X)", + ANC_FF_MIC_CH_L, ANC_FF_MIC_CH_R, ANC_FB_MIC_CH_L, ANC_FB_MIC_CH_R); + } +#endif +#ifdef VOICE_DETECTOR_EN + if (ANC_FF_MIC_CH_L & AUD_CHANNEL_MAP_CH4) { + ASSERT(false, "Conflicted ANC_FF_MIC_CH_L and VAD MIC"); + } + if (ANC_FF_MIC_CH_R & AUD_CHANNEL_MAP_CH4) { + ASSERT(false, "Conflicted ANC_FF_MIC_CH_R and VAD MIC"); + } +#endif +#else // !ANC_PROD_TEST +#if (ANC_FF_MIC_CH_L & ~NORMAL_MIC_MAP) || (ANC_FF_MIC_CH_L & (ANC_FF_MIC_CH_L - 1)) +#error "Invalid ANC_FF_MIC_CH_L" +#endif +#if (ANC_FF_MIC_CH_R & ~NORMAL_MIC_MAP) || (ANC_FF_MIC_CH_R & (ANC_FF_MIC_CH_R - 1)) +#error "Invalid ANC_FF_MIC_CH_R" +#endif +#if (ANC_FF_MIC_CH_L & ANC_FF_MIC_CH_R) +#error "Conflicted ANC_FF_MIC_CH_L and ANC_FF_MIC_CH_R" +#endif +#if defined(ANC_FB_MIC_CH_L) || defined(ANC_FB_MIC_CH_R) +#if (ANC_FF_MIC_CH_L & ANC_FB_MIC_CH_L) || (ANC_FF_MIC_CH_L & ANC_FB_MIC_CH_R) || \ + (ANC_FF_MIC_CH_R & ANC_FB_MIC_CH_L) || (ANC_FF_MIC_CH_R & ANC_FB_MIC_CH_R) +#error "Conflicted ANC_FF_MIC_CH_L and ANC_FF_MIC_CH_R, ANC_FB_MIC_CH_L, ANC_FB_MIC_CH_R" +#endif +#endif +#ifdef VOICE_DETECTOR_EN +#if (ANC_FF_MIC_CH_L & AUD_CHANNEL_MAP_CH4) +#error "Conflicted ANC_FF_MIC_CH_L and VAD MIC" +#endif +#if (ANC_FF_MIC_CH_R & AUD_CHANNEL_MAP_CH4) +#error "Conflicted ANC_FF_MIC_CH_R and VAD MIC" +#endif +#endif +#endif // !ANC_PROD_TEST + if (mic_map & ANC_FF_MIC_CH_L) { + codec_adc_ch_map |= AUD_CHANNEL_MAP_CH0; + mic_map &= ~ANC_FF_MIC_CH_L; + ch_idx = get_msb_pos(ANC_FF_MIC_CH_L); + if (ANC_FF_MIC_CH_L & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH0, ch_idx); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH0; + } else { + codec->REG_084 = SET_BITFIELD(codec->REG_084, CODEC_CODEC_ADC_IN_SEL_CH0, ch_idx); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH0; + } + } else if (ANC_FF_MIC_CH_L & AUD_CHANNEL_MAP_ALL) { + reserv_map |= AUD_CHANNEL_MAP_CH0; + } + if (mic_map & ANC_FF_MIC_CH_R) { + codec_adc_ch_map |= AUD_CHANNEL_MAP_CH1; + mic_map &= ~ANC_FF_MIC_CH_R; + ch_idx = get_msb_pos(ANC_FF_MIC_CH_R); + if (ANC_FF_MIC_CH_R & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH1, ch_idx); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH1; + } else { + codec->REG_088 = SET_BITFIELD(codec->REG_088, CODEC_CODEC_ADC_IN_SEL_CH1, ch_idx); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH1; + } + } else if (ANC_FF_MIC_CH_R & AUD_CHANNEL_MAP_ALL) { + reserv_map |= AUD_CHANNEL_MAP_CH1; + } +#if defined(SIDETONE_ENABLE) && !defined(SIDETONE_DEDICATED_ADC_CHAN) + if (CFG_HW_AUD_SIDETONE_MIC_DEV == ANC_FF_MIC_CH_L) { + hal_codec_set_sidetone_adc_chan(AUD_CHANNEL_MAP_CH0); + } +#ifdef ANC_PROD_TEST + if (CFG_HW_AUD_SIDETONE_MIC_DEV == ANC_FF_MIC_CH_R) { + ASSERT(false, "SIDETONE MIC cannot be ANC_FF_MIC_CH_R: 0x%X", ANC_FF_MIC_CH_R); + } +#elif (CFG_HW_AUD_SIDETONE_MIC_DEV == ANC_FF_MIC_CH_R) +#error "SIDETONE MIC cannot be ANC_FF_MIC_CH_R" +#endif +#endif +#endif + +#if defined(ANC_FB_MIC_CH_L) || defined(ANC_FB_MIC_CH_R) +#ifdef ANC_PROD_TEST + if ((ANC_FB_MIC_CH_L & ~NORMAL_MIC_MAP) || (ANC_FB_MIC_CH_L & (ANC_FB_MIC_CH_L - 1))) { + ASSERT(false, "Invalid ANC_FB_MIC_CH_L: 0x%04X", ANC_FB_MIC_CH_L); + } + if ((ANC_FB_MIC_CH_R & ~NORMAL_MIC_MAP) || (ANC_FB_MIC_CH_R & (ANC_FB_MIC_CH_R - 1))) { + ASSERT(false, "Invalid ANC_FB_MIC_CH_R: 0x%04X", ANC_FB_MIC_CH_R); + } + if (ANC_FB_MIC_CH_L & ANC_FB_MIC_CH_R) { + ASSERT(false, "Conflicted ANC_FB_MIC_CH_L (0x%04X) and ANC_FB_MIC_CH_R (0x%04X)", ANC_FB_MIC_CH_L, ANC_FB_MIC_CH_R); + } +#ifdef VOICE_DETECTOR_EN + if (ANC_FB_MIC_CH_L & AUD_CHANNEL_MAP_CH4) { + ASSERT(false, "Conflicted ANC_FB_MIC_CH_L and VAD MIC"); + } + if (ANC_FB_MIC_CH_R & AUD_CHANNEL_MAP_CH4) { + ASSERT(false, "Conflicted ANC_FB_MIC_CH_R and VAD MIC"); + } +#endif +#else // !ANC_PROD_TEST +#if (ANC_FB_MIC_CH_L & ~NORMAL_MIC_MAP) || (ANC_FB_MIC_CH_L & (ANC_FB_MIC_CH_L - 1)) +#error "Invalid ANC_FB_MIC_CH_L" +#endif +#if (ANC_FB_MIC_CH_R & ~NORMAL_MIC_MAP) || (ANC_FB_MIC_CH_R & (ANC_FB_MIC_CH_R - 1)) +#error "Invalid ANC_FB_MIC_CH_R" +#endif +#if (ANC_FB_MIC_CH_L & ANC_FB_MIC_CH_R) +#error "Conflicted ANC_FB_MIC_CH_L and ANC_FB_MIC_CH_R" +#endif +#ifdef VOICE_DETECTOR_EN +#if (ANC_FB_MIC_CH_L & AUD_CHANNEL_MAP_CH4) +#error "Conflicted ANC_FB_MIC_CH_L and VAD MIC" +#endif +#if (ANC_FB_MIC_CH_R & AUD_CHANNEL_MAP_CH4) +#error "Conflicted ANC_FB_MIC_CH_R and VAD MIC" +#endif +#endif +#endif // !ANC_PROD_TEST + if (mic_map & ANC_FB_MIC_CH_L) { + codec_adc_ch_map |= AUD_CHANNEL_MAP_CH2; + mic_map &= ~ANC_FB_MIC_CH_L; + ch_idx = get_msb_pos(ANC_FB_MIC_CH_L); + if (ANC_FB_MIC_CH_L & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH2, ch_idx); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH2; + } else { + codec->REG_08C = SET_BITFIELD(codec->REG_08C, CODEC_CODEC_ADC_IN_SEL_CH2, ch_idx); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH2; + } + } else if (ANC_FB_MIC_CH_L & AUD_CHANNEL_MAP_ALL) { + reserv_map |= AUD_CHANNEL_MAP_CH2; + } + if (mic_map & ANC_FB_MIC_CH_R) { + codec_adc_ch_map |= AUD_CHANNEL_MAP_CH3; + mic_map &= ~ANC_FB_MIC_CH_R; + ch_idx = get_msb_pos(ANC_FB_MIC_CH_R); + if (ANC_FB_MIC_CH_R & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH3, ch_idx); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH3; + } else { + codec->REG_090 = SET_BITFIELD(codec->REG_090, CODEC_CODEC_ADC_IN_SEL_CH3, ch_idx); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH3; + } + } else if (ANC_FB_MIC_CH_R & AUD_CHANNEL_MAP_ALL) { + reserv_map |= AUD_CHANNEL_MAP_CH3; + } +#if defined(SIDETONE_ENABLE) && !defined(SIDETONE_DEDICATED_ADC_CHAN) + if (CFG_HW_AUD_SIDETONE_MIC_DEV == ANC_FB_MIC_CH_L) { + hal_codec_set_sidetone_adc_chan(AUD_CHANNEL_MAP_CH2); + } +#ifdef ANC_PROD_TEST + if (CFG_HW_AUD_SIDETONE_MIC_DEV == ANC_FB_MIC_CH_R) { + ASSERT(false, "SIDETONE MIC cannot be ANC_FB_MIC_CH_R: 0x%X", ANC_FB_MIC_CH_R); + } +#elif (CFG_HW_AUD_SIDETONE_MIC_DEV == ANC_FB_MIC_CH_R) +#error "SIDETONE MIC cannot be ANC_FB_MIC_CH_R" +#endif +#endif +#endif +#endif // ANC_APP + +#ifdef CODEC_DSD + reserv_map |= AUD_CHANNEL_MAP_CH2 | AUD_CHANNEL_MAP_CH3; +#endif + + if (mic_map & AUD_CHANNEL_MAP_CH4) { + codec_adc_ch_map |= AUD_CHANNEL_MAP_CH4; + mic_map &= ~AUD_CHANNEL_MAP_CH4; + codec->REG_094 = SET_BITFIELD(codec->REG_094, CODEC_CODEC_ADC_IN_SEL_CH4, 4); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH4; +#if defined(SIDETONE_ENABLE) && !defined(SIDETONE_DEDICATED_ADC_CHAN) + if (CFG_HW_AUD_SIDETONE_MIC_DEV == AUD_CHANNEL_MAP_CH4) { + hal_codec_set_sidetone_adc_chan(AUD_CHANNEL_MAP_CH4); + } +#endif + } + if (mic_map & AUD_CHANNEL_MAP_ECMIC_CH0) { + codec_adc_ch_map |= AUD_CHANNEL_MAP_CH5; + mic_map &= ~AUD_CHANNEL_MAP_ECMIC_CH0; + codec->REG_228 &= ~CODEC_CODEC_MC_SEL_CH0; + } + if (mic_map & AUD_CHANNEL_MAP_ECMIC_CH1) { + codec_adc_ch_map |= AUD_CHANNEL_MAP_CH6; + mic_map &= ~AUD_CHANNEL_MAP_ECMIC_CH1; + codec->REG_228 |= CODEC_CODEC_MC_SEL_CH1; + } + + reserv_map |= codec_adc_ch_map; + +#ifdef CODEC_MIN_PHASE + if (min_phase_cfg & (1 << AUD_STREAM_CAPTURE)) { + if (mic_map && (reserv_map & AUD_CHANNEL_MAP_CH2) == 0) { + codec_adc_ch_map |= AUD_CHANNEL_MAP_CH2; + reserv_map |= codec_adc_ch_map; + ch_idx = get_lsb_pos(mic_map); + mic_map &= ~(1 << ch_idx); + if ((1 << ch_idx) & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH2, ch_idx); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH2; + } else { + codec->REG_08C = SET_BITFIELD(codec->REG_08C, CODEC_CODEC_ADC_IN_SEL_CH2, ch_idx); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH2; + } + } + if (mic_map && (reserv_map & AUD_CHANNEL_MAP_CH3) == 0) { + codec_adc_ch_map |= AUD_CHANNEL_MAP_CH3; + reserv_map |= codec_adc_ch_map; + ch_idx = get_lsb_pos(mic_map); + mic_map &= ~(1 << ch_idx); + if ((1 << ch_idx) & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH3, ch_idx); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH3; + } else { + codec->REG_090 = SET_BITFIELD(codec->REG_090, CODEC_CODEC_ADC_IN_SEL_CH3, ch_idx); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH3; + } + } + } +#endif + +#ifdef SIDETONE_ENABLE +#if defined(SIDETONE_DEDICATED_ADC_CHAN) || defined(SIDETONE_RESERVED_ADC_CHAN) + if (mic_map & CFG_HW_AUD_SIDETONE_MIC_DEV) { + enum AUD_CHANNEL_MAP_T st_map = 0; + + // Alloc sidetone adc chan + if ((reserv_map & AUD_CHANNEL_MAP_CH0) == 0) { + st_map = AUD_CHANNEL_MAP_CH0; + } else if ((reserv_map & AUD_CHANNEL_MAP_CH2) == 0) { + st_map = AUD_CHANNEL_MAP_CH2; + } else if ((reserv_map & AUD_CHANNEL_MAP_CH4) == 0) { + st_map = AUD_CHANNEL_MAP_CH4; + } else { + ASSERT(false, "%s: Cannot alloc dedicated sidetone adc: reserv_map=0x%X", __func__, reserv_map); + } + // Associate mic and sidetone adc + hal_codec_set_sidetone_adc_chan(st_map); + ch_idx = get_lsb_pos(CFG_HW_AUD_SIDETONE_MIC_DEV); + i = get_lsb_pos(st_map); + if ((1 << ch_idx) & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = (codec->REG_0A8 & ~(CODEC_CODEC_PDM_MUX_CH0_MASK << (3 * i))) | + (CODEC_CODEC_PDM_MUX_CH0(ch_idx) << (3 * i)); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH0 << i; + } else { + *(&codec->REG_084 + i) = SET_BITFIELD(*(&codec->REG_084 + i), CODEC_CODEC_ADC_IN_SEL_CH0, ch_idx); + codec->REG_0A4 &= ~(CODEC_CODEC_PDM_ADC_SEL_CH0 << i); + } +#ifdef SIDETONE_DEDICATED_ADC_CHAN + sidetone_adc_ch_map = st_map; +#else + mic_map &= ~(1 << ch_idx); + codec_adc_ch_map |= st_map; +#endif + // Mark sidetone adc as used + reserv_map |= st_map; + } +#endif +#endif + + i = 0; + while (mic_map && i < NORMAL_ADC_CH_NUM) { + ASSERT(i < MAX_ANA_MIC_CH_NUM || (mic_map & AUD_CHANNEL_MAP_DIGMIC_ALL), + "%s: Not enough ana cap chan: mic_map=0x%X adc_map=0x%X reserv_map=0x%X", + __func__, mic_map, codec_adc_ch_map, reserv_map); + ch_idx = get_lsb_pos(mic_map); + mic_map &= ~(1 << ch_idx); + while ((reserv_map & (AUD_CHANNEL_MAP_CH0 << i)) && i < NORMAL_ADC_CH_NUM) { + i++; + } +#if defined(SIDETONE_ENABLE) && !(defined(SIDETONE_DEDICATED_ADC_CHAN) || defined(SIDETONE_RESERVED_ADC_CHAN)) + if (CFG_HW_AUD_SIDETONE_MIC_DEV == (1 << ch_idx)) { + if ((reserv_map & AUD_CHANNEL_MAP_CH0) == 0) { + i = 0; + } else if ((reserv_map & AUD_CHANNEL_MAP_CH2) == 0) { + i = 2; + } else if ((reserv_map & AUD_CHANNEL_MAP_CH4) == 0) { + i = 4; + } else { + ASSERT(false, "%s: No sidetone adc: reserv_map=0x%X. Try SIDETONE_RESERVED_ADC_CHAN", __func__, reserv_map); + } + hal_codec_set_sidetone_adc_chan((1 << i)); + } +#endif + if (i < NORMAL_ADC_CH_NUM) { + codec_adc_ch_map |= (AUD_CHANNEL_MAP_CH0 << i); + reserv_map |= codec_adc_ch_map; + if ((1 << ch_idx) & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = (codec->REG_0A8 & ~(CODEC_CODEC_PDM_MUX_CH0_MASK << (3 * i))) | + (CODEC_CODEC_PDM_MUX_CH0(ch_idx) << (3 * i)); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH0 << i; + } else { + *(&codec->REG_084 + i) = SET_BITFIELD(*(&codec->REG_084 + i), CODEC_CODEC_ADC_IN_SEL_CH0, ch_idx); + codec->REG_0A4 &= ~(CODEC_CODEC_PDM_ADC_SEL_CH0 << i); + } + i++; + } + } + +#if defined(SIDETONE_ENABLE) && !(defined(SIDETONE_DEDICATED_ADC_CHAN) || defined(SIDETONE_RESERVED_ADC_CHAN)) + if (mic_map) { + if (reserv_map + 1 < (1 << NORMAL_ADC_CH_NUM)) { + ASSERT(false, "%s: No adc due to sidetone mic_map=0x%X reserv_map=0x%X. Try SIDETONE_RESERVED_ADC_CHAN", + __func__, mic_map, reserv_map); + } + } +#endif + ASSERT(mic_map == 0, "%s: Bad cap chan map: 0x%X reserv_map=0x%X", __func__, mic_map, reserv_map); + } + + if (HAL_CODEC_CONFIG_BITS & cfg->set_flag) { + cfg_set_mask = 0; + cfg_clr_mask = CODEC_MODE_16BIT_ADC_CH0 | CODEC_MODE_16BIT_ADC_CH1 | CODEC_MODE_16BIT_ADC_CH2 | + CODEC_MODE_16BIT_ADC_CH3 | CODEC_MODE_16BIT_ADC_CH4 | CODEC_MODE_16BIT_ADC_CH5 | CODEC_MODE_16BIT_ADC_CH6 | + CODEC_MODE_24BIT_ADC | CODEC_MODE_32BIT_ADC; + if (cfg->bits == AUD_BITS_16) { + cfg_set_mask |= CODEC_MODE_16BIT_ADC_CH0 | CODEC_MODE_16BIT_ADC_CH1 | CODEC_MODE_16BIT_ADC_CH2 | + CODEC_MODE_16BIT_ADC_CH3 | CODEC_MODE_16BIT_ADC_CH4 | CODEC_MODE_16BIT_ADC_CH5 | CODEC_MODE_16BIT_ADC_CH6; + } else if (cfg->bits == AUD_BITS_24) { + cfg_set_mask |= CODEC_MODE_24BIT_ADC; + } else if (cfg->bits == AUD_BITS_32) { + cfg_set_mask |= CODEC_MODE_32BIT_ADC; + } else { + ASSERT(false, "%s: Bad cap bits: %d", __func__, cfg->bits); + } +#ifdef VOICE_DETECTOR_EN + for (int i = 0; i < MAX_ADC_CH_NUM; i++){ + adc_channel_en |= (CODEC_ADC_ENABLE_CH0 << i); + } + + if(((codec->REG_000 & adc_channel_en) != 0) && ((codec->REG_040 & cfg_set_mask) == 0)){ + ASSERT(false, "%s: Cap bits conflict: %d", __func__, cfg->bits); + }else +#endif + codec->REG_040 = (codec->REG_040 & ~cfg_clr_mask) | cfg_set_mask; + } + + cnt = 0; + for (i = 0; i < MAX_ADC_CH_NUM; i++) { + if (codec_adc_ch_map & (AUD_CHANNEL_MAP_CH0 << i)) { + cnt++; + } + } + ASSERT(cnt == cfg->channel_num, "%s: Invalid capture stream chan cfg: map=0x%X num=%u", + __func__, codec_adc_ch_map, cfg->channel_num); + + if (HAL_CODEC_CONFIG_SAMPLE_RATE & cfg->set_flag) { + sample_rate = cfg->sample_rate; + + for(i = 0; i < ARRAY_SIZE(codec_adc_sample_rate); i++) { + if(codec_adc_sample_rate[i].sample_rate == sample_rate) { + break; + } + } + ASSERT(i < ARRAY_SIZE(codec_adc_sample_rate), "%s: Invalid capture sample rate: %d", __func__, sample_rate); + rate_idx = i; + ana_dig_div = codec_adc_sample_rate[rate_idx].codec_div / codec_adc_sample_rate[rate_idx].cmu_div; + ASSERT(ana_dig_div * codec_adc_sample_rate[rate_idx].cmu_div == codec_adc_sample_rate[rate_idx].codec_div, + "%s: Invalid catpure div for rate %u: codec_div=%u cmu_div=%u", __func__, sample_rate, + codec_adc_sample_rate[rate_idx].codec_div, codec_adc_sample_rate[rate_idx].cmu_div); + + TRACE(2,"[%s] capture sample_rate=%d", __func__, sample_rate); + +#ifdef CODEC_TIMER + cur_codec_freq = codec_adc_sample_rate[rate_idx].codec_freq; +#endif + + codec_rate_idx[AUD_STREAM_CAPTURE] = rate_idx; + + if (codec_adc_ch_map & EC_ADC_MAP) { + // If EC enabled, init resample-adc-ch0 to adc0 + codec->REG_0E4 = SET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_ADC_CH0_SEL, 0); + } + + uint32_t normal_chan_num; + + normal_chan_num = cfg->channel_num; + if (codec_adc_ch_map & AUD_CHANNEL_MAP_CH5) { + normal_chan_num--; + } + if (codec_adc_ch_map & AUD_CHANNEL_MAP_CH6) { + normal_chan_num--; + } + +#ifdef __AUDIO_RESAMPLE__ + uint32_t mask, val; + + if (hal_cmu_get_audio_resample_status() && codec_adc_sample_rate[rate_idx].codec_freq != CODEC_FREQ_CRYSTAL) { + ASSERT(normal_chan_num <= AUD_CHANNEL_NUM_2, + "%s: Invalid capture resample chan num: %d/%d map=0x%X", __func__, normal_chan_num, cfg->channel_num, cfg->channel_map); +#ifdef CODEC_TIMER + cur_codec_freq = CODEC_FREQ_CRYSTAL; +#endif + if ((codec->REG_0E4 & CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE) == 0 || + resample_rate_idx[AUD_STREAM_CAPTURE] != rate_idx) { + resample_rate_idx[AUD_STREAM_CAPTURE] = rate_idx; + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + hal_codec_reg_update_delay(); + codec->REG_0F8 = resample_phase_float_to_value(get_capture_resample_phase()); + hal_codec_reg_update_delay(); + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + } + + mask = CODEC_CODEC_RESAMPLE_ADC_DUAL_CH | + CODEC_CODEC_RESAMPLE_ADC_CH0_SEL_MASK | CODEC_CODEC_RESAMPLE_ADC_CH1_SEL_MASK; + val = 0; + cnt = 0; + for (i = 0; i < NORMAL_ADC_CH_NUM; i++) { + if (codec_adc_ch_map & (AUD_CHANNEL_MAP_CH0 << i)) { + if (cnt == 0) { + val |= CODEC_CODEC_RESAMPLE_ADC_CH0_SEL(i); + } else { + val |= CODEC_CODEC_RESAMPLE_ADC_CH1_SEL(i); + } + cnt++; + } + } + if (normal_chan_num == AUD_CHANNEL_NUM_2) { + val |= CODEC_CODEC_RESAMPLE_ADC_DUAL_CH; + } + } else { + mask = CODEC_CODEC_RESAMPLE_ADC_DUAL_CH | + CODEC_CODEC_RESAMPLE_ADC_CH0_SEL_MASK | CODEC_CODEC_RESAMPLE_ADC_CH1_SEL_MASK | + CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + val = 0; + } + codec->REG_0E4 = (codec->REG_0E4 & ~mask) | val; +#endif + + // Echo cancel channels will check the enable signal of resample ADC CH0, even when resample is disabled + if (codec_adc_ch_map & EC_ADC_MAP) { + if (normal_chan_num && (codec->REG_0E4 & CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE) == 0) { + for (i = 0; i < NORMAL_ADC_CH_NUM; i++) { + if (codec_adc_ch_map & (AUD_CHANNEL_MAP_CH0 << i)) { + codec->REG_0E4 = SET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_ADC_CH0_SEL, i); + break; + } + } + } + } + +#ifdef __AUDIO_RESAMPLE__ + if (!hal_cmu_get_audio_resample_status()) +#endif + { +#ifdef __AUDIO_RESAMPLE__ + ASSERT(codec_adc_sample_rate[rate_idx].codec_freq != CODEC_FREQ_CRYSTAL, + "%s: capture sample rate %u is for resample only", __func__, sample_rate); +#endif + analog_aud_freq_pll_config(codec_adc_sample_rate[rate_idx].codec_freq, codec_adc_sample_rate[rate_idx].codec_div); + hal_cmu_codec_adc_set_div(codec_adc_sample_rate[rate_idx].cmu_div * CODEC_FREQ_EXTRA_DIV); + } + hal_codec_set_adc_down(codec_adc_ch_map, codec_adc_sample_rate[rate_idx].adc_down); + hal_codec_set_adc_hbf_bypass_cnt(codec_adc_ch_map, codec_adc_sample_rate[rate_idx].bypass_cnt); + } + +#if !(defined(FIXED_CODEC_ADC_VOL) && defined(SINGLE_CODEC_ADC_VOL)) + if (HAL_CODEC_CONFIG_VOL & cfg->set_flag) { +#ifdef SINGLE_CODEC_ADC_VOL + const CODEC_ADC_VOL_T *adc_gain_db; + adc_gain_db = hal_codec_get_adc_volume(cfg->vol); + if (adc_gain_db) { + hal_codec_set_dig_adc_gain(NORMAL_ADC_MAP, *adc_gain_db); +#ifdef SIDETONE_DEDICATED_ADC_CHAN + sidetone_adc_gain = *adc_gain_db; + hal_codec_set_dig_adc_gain(sidetone_adc_ch_map, sidetone_adc_gain + sidetone_gain_offset); +#endif + } +#else // !SINGLE_CODEC_ADC_VOL + uint32_t vol; + + mic_map = codec_mic_ch_map; + while (mic_map) { + ch_idx = get_lsb_pos(mic_map); + mic_map &= ~(1 << ch_idx); + vol = hal_codec_get_mic_chan_volume_level(1 << ch_idx); + hal_codec_set_chan_vol(AUD_STREAM_CAPTURE, (1 << ch_idx), vol); + } +#ifdef SIDETONE_DEDICATED_ADC_CHAN + if (codec_mic_ch_map & CFG_HW_AUD_SIDETONE_MIC_DEV) { + const CODEC_ADC_VOL_T *adc_gain_db; + + vol = hal_codec_get_mic_chan_volume_level(CFG_HW_AUD_SIDETONE_MIC_DEV); + adc_gain_db = hal_codec_get_adc_volume(vol); + if (adc_gain_db) { + sidetone_adc_gain = *adc_gain_db; + hal_codec_set_dig_adc_gain(sidetone_adc_ch_map, sidetone_adc_gain + sidetone_gain_offset); + } + } +#endif +#endif // !SINGLE_CODEC_ADC_VOL + } +#endif + } + + return 0; +} + +int hal_codec_anc_adc_enable(enum ANC_TYPE_T type) +{ +#ifdef ANC_APP + enum AUD_CHANNEL_MAP_T map; + enum AUD_CHANNEL_MAP_T mic_map; + uint8_t ch_idx; + + map = 0; + mic_map = 0; + if (type == ANC_FEEDFORWARD) { +#if defined(ANC_FF_MIC_CH_L) || defined(ANC_FF_MIC_CH_R) + if (ANC_FF_MIC_CH_L) { + ch_idx = get_msb_pos(ANC_FF_MIC_CH_L); + if (ANC_FF_MIC_CH_L & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH0, ch_idx); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH0; + } else { + codec->REG_084 = SET_BITFIELD(codec->REG_084, CODEC_CODEC_ADC_IN_SEL_CH0, ch_idx); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH0; + } + map |= AUD_CHANNEL_MAP_CH0; + mic_map |= ANC_FF_MIC_CH_L; + } + if (ANC_FF_MIC_CH_R) { + ch_idx = get_msb_pos(ANC_FF_MIC_CH_R); + if (ANC_FF_MIC_CH_R & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH1, ch_idx); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH1; + } else { + codec->REG_088 = SET_BITFIELD(codec->REG_088, CODEC_CODEC_ADC_IN_SEL_CH1, ch_idx); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH1; + } + map |= AUD_CHANNEL_MAP_CH1; + mic_map |= ANC_FF_MIC_CH_R; + } +#else + ASSERT(false, "No ana adc ff ch defined"); +#endif + } else if (type == ANC_FEEDBACK) { +#if defined(ANC_FB_MIC_CH_L) || defined(ANC_FB_MIC_CH_R) + if (ANC_FB_MIC_CH_L) { + ch_idx = get_msb_pos(ANC_FB_MIC_CH_L); + if (ANC_FB_MIC_CH_L & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH2, ch_idx); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH2; + } else { + codec->REG_08C = SET_BITFIELD(codec->REG_08C, CODEC_CODEC_ADC_IN_SEL_CH2, ch_idx); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH2; + } + map |= AUD_CHANNEL_MAP_CH2; + mic_map |= ANC_FB_MIC_CH_L; + } + if (ANC_FB_MIC_CH_R) { + ch_idx = get_msb_pos(ANC_FB_MIC_CH_R); + if (ANC_FB_MIC_CH_R & AUD_CHANNEL_MAP_DIGMIC_ALL) { + ch_idx = hal_codec_get_digmic_hw_index(ch_idx); + codec->REG_0A8 = SET_BITFIELD(codec->REG_0A8, CODEC_CODEC_PDM_MUX_CH3, ch_idx); + codec->REG_0A4 |= CODEC_CODEC_PDM_ADC_SEL_CH3; + } else { + codec->REG_090 = SET_BITFIELD(codec->REG_090, CODEC_CODEC_ADC_IN_SEL_CH3, ch_idx); + codec->REG_0A4 &= ~CODEC_CODEC_PDM_ADC_SEL_CH3; + } + map |= AUD_CHANNEL_MAP_CH3; + mic_map |= ANC_FB_MIC_CH_R; + } +#else + ASSERT(false, "No ana adc fb ch defined"); +#endif + } + anc_adc_ch_map |= map; + anc_mic_ch_map |= mic_map; + + if (anc_mic_ch_map & AUD_CHANNEL_MAP_DIGMIC_ALL) { + hal_codec_enable_dig_mic(anc_mic_ch_map); + } + + for (int i = 0; i < NORMAL_ADC_CH_NUM; i++) { + if (map & (AUD_CHANNEL_MAP_CH0 << i)) { + if ((codec->REG_080 & (CODEC_CODEC_ADC_EN_CH0 << i)) == 0) { + // Reset ADC channel + codec->REG_064 &= ~CODEC_SOFT_RSTN_ADC(1 << i); + codec->REG_064 |= CODEC_SOFT_RSTN_ADC(1 << i); + codec->REG_080 |= (CODEC_CODEC_ADC_EN_CH0 << i); + } + } + } + +#ifdef DAC_DRE_ENABLE + if (anc_adc_ch_map && (codec->REG_098 & CODEC_CODEC_DAC_EN)) { + hal_codec_dac_dre_disable(); + } +#endif +#endif + + return 0; +} + +int hal_codec_anc_adc_disable(enum ANC_TYPE_T type) +{ +#ifdef ANC_APP + enum AUD_CHANNEL_MAP_T map; + enum AUD_CHANNEL_MAP_T mic_map; + + map = 0; + mic_map = 0; + if (type == ANC_FEEDFORWARD) { +#if defined(ANC_FF_MIC_CH_L) || defined(ANC_FF_MIC_CH_R) + if (ANC_FF_MIC_CH_L) { + map |= AUD_CHANNEL_MAP_CH0; + mic_map |= ANC_FF_MIC_CH_L; + } + if (ANC_FF_MIC_CH_R) { + map |= AUD_CHANNEL_MAP_CH1; + mic_map |= ANC_FF_MIC_CH_R; + } +#endif + } else if (type == ANC_FEEDBACK) { +#if defined(ANC_FB_MIC_CH_L) || defined(ANC_FB_MIC_CH_R) + if (ANC_FB_MIC_CH_L) { + map |= AUD_CHANNEL_MAP_CH2; + mic_map |= ANC_FB_MIC_CH_L; + } + if (ANC_FB_MIC_CH_R) { + map |= AUD_CHANNEL_MAP_CH3; + mic_map |= ANC_FB_MIC_CH_R; + } +#endif + } + anc_adc_ch_map &= ~map; + anc_mic_ch_map &= ~mic_map; + + if ((anc_mic_ch_map & AUD_CHANNEL_MAP_DIGMIC_ALL) == 0 && + ((codec_mic_ch_map & AUD_CHANNEL_MAP_DIGMIC_ALL) == 0 || (codec->REG_000 & CODEC_ADC_ENABLE) == 0)) { + hal_codec_disable_dig_mic(); + } + + for (int i = 0; i < NORMAL_ADC_CH_NUM; i++) { + if ((map & (AUD_CHANNEL_MAP_CH0 << i)) == 0) { + continue; + } + if (codec->REG_000 & CODEC_ADC_ENABLE) { + if (codec_adc_ch_map & (AUD_CHANNEL_MAP_CH0 << i)) { + continue; + } + if (i == 0 && + (codec->REG_228 & (CODEC_CODEC_MC_ENABLE_CH0 | CODEC_CODEC_MC_ENABLE_CH1)) && + (codec_adc_ch_map & ~EC_ADC_MAP) == 0) { + continue; + } + } + codec->REG_080 &= ~(CODEC_CODEC_ADC_EN_CH0 << i); + } + +#ifdef DAC_DRE_ENABLE + if (anc_adc_ch_map == 0 && (codec->REG_098 & CODEC_CODEC_DAC_EN) && + //(codec->REG_044 & CODEC_MODE_16BIT_DAC) == 0 && + 1) { + hal_codec_dac_dre_enable(); + } +#endif +#endif + + return 0; +} + +enum AUD_SAMPRATE_T hal_codec_anc_convert_rate(enum AUD_SAMPRATE_T rate) +{ + if (hal_cmu_get_audio_resample_status()) { + return AUD_SAMPRATE_50781; + } else if (CODEC_FREQ_48K_SERIES / rate * rate == CODEC_FREQ_48K_SERIES) { + return AUD_SAMPRATE_48000; + } else /* if (CODEC_FREQ_44_1K_SERIES / rate * rate == CODEC_FREQ_44_1K_SERIES) */ { + return AUD_SAMPRATE_44100; + } +} + +int hal_codec_anc_dma_enable(enum HAL_CODEC_ID_T id) +{ + return 0; +} + +int hal_codec_anc_dma_disable(enum HAL_CODEC_ID_T id) +{ + return 0; +} + +int hal_codec_aux_mic_dma_enable(enum HAL_CODEC_ID_T id) +{ + return 0; +} + +int hal_codec_aux_mic_dma_disable(enum HAL_CODEC_ID_T id) +{ + return 0; +} + +uint32_t hal_codec_get_alg_dac_shift(void) +{ + return 0; +} + +#ifdef ANC_APP +void hal_codec_set_anc_boost_gain_attn(float attn) +{ + anc_boost_gain_attn = attn; + +#ifdef AUDIO_OUTPUT_SW_GAIN + hal_codec_set_sw_gain(swdac_gain); +#else + hal_codec_restore_dig_dac_gain(); +#endif + hal_codec_restore_dig_adc_gain(); +} + +void hal_codec_apply_anc_adc_gain_offset(enum ANC_TYPE_T type, int8_t offset_l, int8_t offset_r) +{ + enum AUD_CHANNEL_MAP_T map_l, map_r; + enum AUD_CHANNEL_MAP_T ch_map; + uint8_t ch_idx; + + if (analog_debug_get_anc_calib_mode()) { + return; + } + + map_l = 0; + map_r = 0; + +#if defined(ANC_FF_MIC_CH_L) || defined(ANC_FF_MIC_CH_R) + if (type & ANC_FEEDFORWARD) { + if (ANC_FF_MIC_CH_L) { + map_l |= AUD_CHANNEL_MAP_CH0; + } + if (ANC_FF_MIC_CH_R) { + map_r |= AUD_CHANNEL_MAP_CH1; + } + } +#endif +#if defined(ANC_FB_MIC_CH_L) || defined(ANC_FB_MIC_CH_R) + if (type & ANC_FEEDBACK) { + if (ANC_FB_MIC_CH_L) { + map_l |= AUD_CHANNEL_MAP_CH2; + } + if (ANC_FB_MIC_CH_R) { + map_r |= AUD_CHANNEL_MAP_CH3; + } + } +#endif + + if (map_l) { + ch_map = map_l; + while (ch_map) { + ch_idx = get_msb_pos(ch_map); + ch_map &= ~(1 << ch_idx); + anc_adc_gain_offset[ch_idx] = offset_l; + } + if (offset_l) { + anc_adc_gain_offset_map |= map_l; + } else { + anc_adc_gain_offset_map &= ~map_l; + } + } + if (map_r) { + ch_map = map_r; + while (ch_map) { + ch_idx = get_msb_pos(ch_map); + ch_map &= ~(1 << ch_idx); + anc_adc_gain_offset[ch_idx] = offset_r; + } + if (offset_r) { + anc_adc_gain_offset_map |= map_r; + } else { + anc_adc_gain_offset_map &= ~map_r; + } + } + if (map_l || map_r) { + hal_codec_restore_dig_adc_gain(); + } +} +#endif + +#ifdef AUDIO_OUTPUT_DC_CALIB +void hal_codec_set_dac_dc_gain_attn(float attn) +{ + dac_dc_gain_attn = attn; +} + +void hal_codec_set_dac_dc_offset(int16_t dc_l, int16_t dc_r) +{ + // DC calib values are based on 16-bit, but hardware compensation is based on 24-bit + dac_dc_l = dc_l << 8; + dac_dc_r = dc_r << 8; +#ifdef SDM_MUTE_NOISE_SUPPRESSION + if (dac_dc_l == 0) { + dac_dc_l = 1; + } + if (dac_dc_r == 0) { + dac_dc_r = 1; + } +#endif +} +#endif + +void hal_codec_set_dac_reset_callback(HAL_CODEC_DAC_RESET_CALLBACK callback) +{ + //dac_reset_callback = callback; +} + +static uint32_t POSSIBLY_UNUSED hal_codec_get_adc_chan(enum AUD_CHANNEL_MAP_T mic_map) +{ + uint8_t adc_ch; + uint8_t mic_ch; + uint8_t digmic_ch0; + uint8_t en_ch; + bool digmic; + int i; + + adc_ch = MAX_ADC_CH_NUM; + + mic_ch = get_lsb_pos(mic_map); + + if (((1 << mic_ch) & codec_mic_ch_map) == 0) { + return adc_ch; + } + + digmic_ch0 = get_lsb_pos(AUD_CHANNEL_MAP_DIGMIC_CH0); + + if (mic_ch >= digmic_ch0) { + mic_ch -= digmic_ch0; + digmic = true; + } else { + digmic = false; + } + + for (i = 0; i < NORMAL_ADC_CH_NUM; i++) { + if (codec_adc_ch_map & (1 << i)) { + if (digmic ^ !!(codec->REG_0A4 & (CODEC_CODEC_PDM_ADC_SEL_CH0 << i))) { + continue; + } + if (digmic) { + en_ch = (codec->REG_0A8 & (CODEC_CODEC_PDM_MUX_CH0_MASK << (3 * i))) >> (CODEC_CODEC_PDM_MUX_CH0_SHIFT + 3 * i); + } else { + en_ch = GET_BITFIELD(*(&codec->REG_084 + i), CODEC_CODEC_ADC_IN_SEL_CH0); + } + if (mic_ch == en_ch) { + adc_ch = i; + break; + } + } + } + + return adc_ch; +} + +void hal_codec_sidetone_enable(void) +{ +#ifdef SIDETONE_ENABLE +#if (CFG_HW_AUD_SIDETONE_MIC_DEV & (CFG_HW_AUD_SIDETONE_MIC_DEV - 1)) +#error "Invalid CFG_HW_AUD_SIDETONE_MIC_DEV: only 1 mic can be defined" +#endif +#if (CFG_HW_AUD_SIDETONE_MIC_DEV == 0) || (CFG_HW_AUD_SIDETONE_MIC_DEV & ~NORMAL_MIC_MAP) +#error "Invalid CFG_HW_AUD_SIDETONE_MIC_DEV: bad mic channel" +#endif + int gain = CFG_HW_AUD_SIDETONE_GAIN_DBVAL; + uint32_t val; + +#ifdef SIDETONE_DEDICATED_ADC_CHAN + sidetone_gain_offset = 0; + if (gain > MAX_SIDETONE_DBVAL) { + sidetone_gain_offset = gain - MAX_SIDETONE_DBVAL; + } else if (gain < MIN_SIDETONE_DBVAL) { + sidetone_gain_offset = gain - MIN_SIDETONE_DBVAL; + } +#endif + + if (gain > MAX_SIDETONE_DBVAL) { + gain = MAX_SIDETONE_DBVAL; + } else if (gain < MIN_SIDETONE_DBVAL) { + gain = MIN_SIDETONE_DBVAL; + } + + val = MIN_SIDETONE_REGVAL + (gain - MIN_SIDETONE_DBVAL) / SIDETONE_DBVAL_STEP; + + codec->REG_080 = SET_BITFIELD(codec->REG_080, CODEC_CODEC_SIDE_TONE_GAIN, val); + +#ifdef SIDETONE_DEDICATED_ADC_CHAN + uint8_t adc_ch; + + adc_ch = get_lsb_pos(sidetone_adc_ch_map); + if (adc_ch >= NORMAL_ADC_CH_NUM) { + return; + } + + hal_codec_set_dig_adc_gain(sidetone_adc_ch_map, sidetone_adc_gain + sidetone_gain_offset); +#ifdef CFG_HW_AUD_SIDETONE_GAIN_RAMP + hal_codec_get_adc_gain(sidetone_adc_ch_map, &sidetone_ded_chan_coef); + hal_codec_set_dig_adc_gain(sidetone_adc_ch_map, MIN_DIG_DBVAL); +#endif + codec->REG_080 |= (CODEC_CODEC_ADC_EN_CH0 << adc_ch); + +#ifdef CFG_HW_AUD_SIDETONE_IIR_INDEX +#if (CFG_HW_AUD_SIDETONE_IIR_INDEX >= ADC_IIR_CH_NUM + 0UL) +#error "Invalid CFG_HW_AUD_SIDETONE_IIR_INDEX" +#endif + uint32_t mask; + + if (CFG_HW_AUD_SIDETONE_IIR_INDEX == 0) { + mask = CODEC_CODEC_ADC_IIR_CH0_SEL_MASK; + val = CODEC_CODEC_ADC_IIR_CH0_SEL(adc_ch); + } else { + mask = CODEC_CODEC_ADC_IIR_CH1_SEL_MASK; + val = CODEC_CODEC_ADC_IIR_CH1_SEL(adc_ch); + } + codec->REG_078 = (codec->REG_078 & ~mask) | val; +#endif +#endif +#endif +} + +void hal_codec_sidetone_disable(void) +{ +#ifdef SIDETONE_ENABLE + codec->REG_080 = SET_BITFIELD(codec->REG_080, CODEC_CODEC_SIDE_TONE_GAIN, MUTE_SIDETONE_REGVAL); +#ifdef SIDETONE_DEDICATED_ADC_CHAN + if (sidetone_adc_ch_map) { + uint8_t adc_ch; + + adc_ch = get_lsb_pos(sidetone_adc_ch_map); + codec->REG_080 &= ~(CODEC_CODEC_ADC_EN_CH0 << adc_ch); + } +#endif +#endif +} + +int hal_codec_sidetone_gain_ramp_up(float step) +{ + int ret = 0; +#ifdef CFG_HW_AUD_SIDETONE_GAIN_RAMP + float coef; + uint32_t val; + + hal_codec_get_adc_gain(sidetone_adc_ch_map, &coef); + coef += step; + if (coef >= sidetone_ded_chan_coef) { + coef = sidetone_ded_chan_coef; + ret = 1; + } + // Gain format: 8.12 + int32_t s_val = (int32_t)(coef * (1 << 12)); + val = __SSAT(s_val, 20); + hal_codec_set_adc_gain_value(sidetone_adc_ch_map, val); + +#endif + return ret; +} + +int hal_codec_sidetone_gain_ramp_down(float step) +{ + int ret = 0; +#ifdef CFG_HW_AUD_SIDETONE_GAIN_RAMP + float coef; + uint32_t val; + + hal_codec_get_adc_gain(sidetone_adc_ch_map, &coef); + coef -= step; + if (coef <= 0) { + coef = 0; + ret = 1; + } + + // Gain format: 8.12 + int32_t s_val = (int32_t)(coef * (1 << 12)); + val = __SSAT(s_val, 20); + hal_codec_set_adc_gain_value(sidetone_adc_ch_map, val); +#endif + return ret; +} + +void hal_codec_select_adc_iir_mic(uint32_t index, enum AUD_CHANNEL_MAP_T mic_map) +{ + uint32_t mask, val; + uint8_t adc_ch; + + ASSERT(index < ADC_IIR_CH_NUM, "%s: Bad index=%u", __func__, index); + ASSERT(mic_map && (mic_map & (mic_map - 1)) == 0, "%s: Bad mic_map=0x%X", __func__, mic_map); +#ifdef CFG_HW_AUD_SIDETONE_IIR_INDEX + ASSERT(index != CFG_HW_AUD_SIDETONE_IIR_INDEX, "%s: Adc iir index conflicts with sidetone", __func__); +#endif + + adc_ch = hal_codec_get_adc_chan(mic_map); + if (index == 0) { + mask = CODEC_CODEC_ADC_IIR_CH0_SEL_MASK; + val = CODEC_CODEC_ADC_IIR_CH0_SEL(adc_ch); + } else { + mask = CODEC_CODEC_ADC_IIR_CH1_SEL_MASK; + val = CODEC_CODEC_ADC_IIR_CH1_SEL(adc_ch); + } + codec->REG_078 = (codec->REG_078 & ~mask) | val; +} + +void hal_codec_min_phase_mode_enable(enum AUD_STREAM_T stream) +{ +#ifdef CODEC_MIN_PHASE + if (min_phase_cfg == 0 && codec_opened) { + hal_codec_min_phase_init(); + } + + min_phase_cfg |= (1 << stream); +#endif +} + +void hal_codec_min_phase_mode_disable(enum AUD_STREAM_T stream) +{ +#ifdef CODEC_MIN_PHASE + min_phase_cfg &= ~(1 << stream); + + if (min_phase_cfg == 0 && codec_opened) { + hal_codec_min_phase_term(); + } +#endif +} + +void hal_codec_sync_dac_enable(enum HAL_CODEC_SYNC_TYPE_T type) +{ +#if defined(ANC_APP) + //hal_codec_sync_dac_resample_rate_enable(type); + codec->REG_054 = SET_BITFIELD(codec->REG_054, CODEC_DAC_ENABLE_SEL, type); +#else + codec->REG_054 = SET_BITFIELD(codec->REG_054, CODEC_CODEC_DAC_ENABLE_SEL, type); +#endif +} + +void hal_codec_sync_dac_disable(void) +{ +#if defined(ANC_APP) + //hal_codec_sync_dac_resample_rate_disable(); + codec->REG_054 = SET_BITFIELD(codec->REG_054, CODEC_DAC_ENABLE_SEL, HAL_CODEC_SYNC_TYPE_NONE); +#else + codec->REG_054 = SET_BITFIELD(codec->REG_054, CODEC_CODEC_DAC_ENABLE_SEL, HAL_CODEC_SYNC_TYPE_NONE); +#endif +} + +void hal_codec_sync_adc_enable(enum HAL_CODEC_SYNC_TYPE_T type) +{ +#if defined(ANC_APP) + //hal_codec_sync_adc_resample_rate_enable(type); + codec->REG_054 = SET_BITFIELD(codec->REG_054, CODEC_ADC_ENABLE_SEL, type); +#else + codec->REG_054 = SET_BITFIELD(codec->REG_054, CODEC_CODEC_ADC_ENABLE_SEL, type); +#endif +} + +void hal_codec_sync_adc_disable(void) +{ +#if defined(ANC_APP) + //hal_codec_sync_adc_resample_rate_disable(); + codec->REG_054 = SET_BITFIELD(codec->REG_054, CODEC_ADC_ENABLE_SEL, HAL_CODEC_SYNC_TYPE_NONE); +#else + codec->REG_054 = SET_BITFIELD(codec->REG_054, CODEC_CODEC_ADC_ENABLE_SEL, HAL_CODEC_SYNC_TYPE_NONE); +#endif +} + +void hal_codec_sync_dac_resample_rate_enable(enum HAL_CODEC_SYNC_TYPE_T type) +{ + codec->REG_0E4 = SET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_DAC_TRIGGER_SEL, type); +} + +void hal_codec_sync_dac_resample_rate_disable(void) +{ + codec->REG_0E4 = SET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_DAC_TRIGGER_SEL, HAL_CODEC_SYNC_TYPE_NONE); +} + +void hal_codec_sync_adc_resample_rate_enable(enum HAL_CODEC_SYNC_TYPE_T type) +{ + codec->REG_0E4 = SET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_ADC_TRIGGER_SEL, type); +} + +void hal_codec_sync_adc_resample_rate_disable(void) +{ + codec->REG_0E4 = SET_BITFIELD(codec->REG_0E4, CODEC_CODEC_RESAMPLE_ADC_TRIGGER_SEL, HAL_CODEC_SYNC_TYPE_NONE); +} + +void hal_codec_sync_dac_gain_enable(enum HAL_CODEC_SYNC_TYPE_T type) +{ + codec->REG_09C = SET_BITFIELD(codec->REG_09C, CODEC_CODEC_DAC_GAIN_TRIGGER_SEL, type); +} + +void hal_codec_sync_dac_gain_disable(void) +{ + codec->REG_09C = SET_BITFIELD(codec->REG_09C, CODEC_CODEC_DAC_GAIN_TRIGGER_SEL, HAL_CODEC_SYNC_TYPE_NONE); +} + +void hal_codec_sync_adc_gain_enable(enum HAL_CODEC_SYNC_TYPE_T type) +{ +} + +void hal_codec_sync_adc_gain_disable(void) +{ +} + +void hal_codec_gpio_trigger_debounce_enable(void) +{ + if (codec_opened) { + codec->REG_054 |= CODEC_GPIO_TRIGGER_DB_ENABLE; + } +} + +void hal_codec_gpio_trigger_debounce_disable(void) +{ + if (codec_opened) { + codec->REG_054 &= ~CODEC_GPIO_TRIGGER_DB_ENABLE; + } +} + +#ifdef CODEC_TIMER +uint32_t hal_codec_timer_get(void) +{ + if (codec_opened) { + return codec->REG_050; + } + + return 0; +} + +uint32_t hal_codec_timer_ticks_to_us(uint32_t ticks) +{ + uint32_t timer_freq; + + timer_freq = cur_codec_freq / 4 / CODEC_FREQ_EXTRA_DIV; + + return (uint32_t)((float)ticks * 1000000 / timer_freq); +} + +void hal_codec_timer_trigger_read(void) +{ + if (codec_opened) { + codec->REG_078 ^= CODEC_GET_CNT_TRIG; + hal_codec_reg_update_delay(); + } +} +#endif + +#ifdef AUDIO_OUTPUT_DC_CALIB_ANA +int hal_codec_dac_sdm_reset_set(void) +{ + if (codec_opened) { + hal_codec_set_dac_gain_value(VALID_DAC_MAP, 0); + if (codec->REG_098 & CODEC_CODEC_DAC_EN) { + osDelay(dac_delay_ms); + } + for (int i = 0x200; i >= 0; i -= 0x100) { + hal_codec_dac_dc_offset_enable(i, i); + osDelay(1); + } + codec->REG_098 |= CODEC_CODEC_DAC_SDM_CLOSE; + osDelay(1); + } + + return 0; +} + +int hal_codec_dac_sdm_reset_clear(void) +{ + if (codec_opened) { + osDelay(1); + codec->REG_098 &= ~CODEC_CODEC_DAC_SDM_CLOSE; + for (int i = 0x100; i <= 0x300; i += 0x100) { + hal_codec_dac_dc_offset_enable(i, i); + osDelay(1); + } + hal_codec_restore_dig_dac_gain(); + } + + return 0; +} +#endif + +void hal_codec_tune_resample_rate(enum AUD_STREAM_T stream, float ratio) +{ +#ifdef __AUDIO_RESAMPLE__ + uint32_t val; + + if (!codec_opened) { + return; + } + + if (stream == AUD_STREAM_PLAYBACK) { + if (codec->REG_0E4 & CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE) { + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + hal_codec_reg_update_delay(); + val = resample_phase_float_to_value(get_playback_resample_phase()); + val += (int)(val * ratio); + codec->REG_0F4 = val; + hal_codec_reg_update_delay(); + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + } + } else { + if (codec->REG_0E4 & CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE) { + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + hal_codec_reg_update_delay(); + val = resample_phase_float_to_value(get_capture_resample_phase()); + val -= (int)(val * ratio); + codec->REG_0F8 = val; + hal_codec_reg_update_delay(); + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + } + } +#endif +} + +void hal_codec_tune_both_resample_rate(float ratio) +{ +#ifdef __AUDIO_RESAMPLE__ + bool update[2]; + uint32_t val[2]; + uint32_t lock; + + if (!codec_opened) { + return; + } + + update[0] = !!(codec->REG_0E4 & CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE); + update[1] = !!(codec->REG_0E4 & CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE); + + val[0] = val[1] = 0; + + if (update[0]) { + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + val[0] = resample_phase_float_to_value(get_playback_resample_phase()); + val[0] += (int)(val[0] * ratio); + } + if (update[1]) { + codec->REG_0E4 &= ~CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + val[1] = resample_phase_float_to_value(get_capture_resample_phase()); + val[1] -= (int)(val[1] * ratio); + } + + hal_codec_reg_update_delay(); + + if (update[0]) { + codec->REG_0F4 = val[0]; + } + if (update[1]) { + codec->REG_0F8 = val[1]; + } + + hal_codec_reg_update_delay(); + + lock = int_lock(); + if (update[0]) { + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE; + } + if (update[1]) { + codec->REG_0E4 |= CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE; + } + int_unlock(lock); +#endif +} + +int hal_codec_select_clock_out(uint32_t cfg) +{ + uint32_t lock; + int ret = 1; + + lock = int_lock(); + + if (codec_opened) { + codec->REG_060 = SET_BITFIELD(codec->REG_060, CODEC_CFG_CLK_OUT, cfg); + ret = 0; + } + + int_unlock(lock); + + return ret; +} + +#ifdef AUDIO_ANC_FB_MC +void hal_codec_setup_mc(enum AUD_CHANNEL_NUM_T channel_num, enum AUD_BITS_T bits) +{ + if (channel_num == AUD_CHANNEL_NUM_2) { + mc_dual_chan = true; + } else { + mc_dual_chan = false; + } + + if (bits <= AUD_BITS_16) { + mc_16bit = true; + } else { + mc_16bit = false; + } +} +#endif + +void hal_codec_swap_output(bool swap) +{ +#ifdef AUDIO_OUTPUT_SWAP + output_swap = swap; + + if (codec_opened) { + if (output_swap) { + codec->REG_0A0 |= CODEC_CODEC_DAC_OUT_SWAP; + } else { + codec->REG_0A0 &= ~CODEC_CODEC_DAC_OUT_SWAP; + } + } +#endif +} + +int hal_codec_config_digmic_phase(uint8_t phase) +{ +#ifdef ANC_PROD_TEST + codec_digmic_phase = phase; +#endif + return 0; +} + +static void hal_codec_general_irq_handler(void) +{ + uint32_t status; + + status = codec->REG_00C; + codec->REG_00C = status; + + status &= codec->REG_010; + + for (int i = 0; i < CODEC_IRQ_TYPE_QTY; i++) { + if (codec_irq_callback[i]) { + codec_irq_callback[i](status); + } + } +} + +static void hal_codec_set_irq_handler(enum CODEC_IRQ_TYPE_T type, HAL_CODEC_IRQ_CALLBACK cb) +{ + uint32_t lock; + + ASSERT(type < CODEC_IRQ_TYPE_QTY, "%s: Bad type=%d", __func__, type); + + lock = int_lock(); + + codec_irq_callback[type] = cb; + + if (cb) { + if (codec_irq_map == 0) { + NVIC_SetVector(CODEC_IRQn, (uint32_t)hal_codec_general_irq_handler); + NVIC_SetPriority(CODEC_IRQn, IRQ_PRIORITY_HIGHPLUSPLUS); + NVIC_ClearPendingIRQ(CODEC_IRQn); + NVIC_EnableIRQ(CODEC_IRQn); + } + codec_irq_map |= (1 << type); + } else { + codec_irq_map &= ~(1 << type); + if (codec_irq_map == 0) { + NVIC_DisableIRQ(CODEC_IRQn); + NVIC_ClearPendingIRQ(CODEC_IRQn); + } + } + + int_unlock(lock); +} + +void hal_codec_anc_fb_check_set_irq_handler(HAL_CODEC_IRQ_CALLBACK cb) +{ + hal_codec_set_irq_handler(CODEC_IRQ_TYPE_ANC_FB_CHECK, cb); +} + +/* AUDIO CODEC VOICE ACTIVE DETECTION DRIVER */ +#ifdef VOICE_DETECTOR_EN + +//#define CODEC_VAD_DEBUG + +static inline void hal_codec_vad_set_udc(int v) +{ + codec->REG_14C &= ~CODEC_VAD_U_DC(0xf); + codec->REG_14C |= CODEC_VAD_U_DC(v); +} + +static inline void hal_codec_vad_set_upre(int v) +{ + codec->REG_14C &= ~CODEC_VAD_U_PRE(0x7); + codec->REG_14C |= CODEC_VAD_U_PRE(v); +} + +static inline void hal_codec_vad_set_frame_len(int v) +{ + codec->REG_14C &= ~CODEC_VAD_FRAME_LEN(0xff); + codec->REG_14C |= CODEC_VAD_FRAME_LEN(v); +} + +static inline void hal_codec_vad_set_mvad(int v) +{ + codec->REG_14C &= ~CODEC_VAD_MVAD(0xf); + codec->REG_14C |= CODEC_VAD_MVAD(v); +} + +static inline void hal_codec_vad_set_pre_gain(int v) +{ + codec->REG_14C &= ~CODEC_VAD_PRE_GAIN(0x3f); + codec->REG_14C |= CODEC_VAD_PRE_GAIN(v); +} + +static inline void hal_codec_vad_set_sth(int v) +{ + codec->REG_14C &= ~CODEC_VAD_STH(0x3f); + codec->REG_14C |= CODEC_VAD_STH(v); +} + +static inline void hal_codec_vad_set_frame_th1(int v) +{ + codec->REG_150 &= ~CODEC_VAD_FRAME_TH1(0xff); + codec->REG_150 |= CODEC_VAD_FRAME_TH1(v); +} + +static inline void hal_codec_vad_set_frame_th2(int v) +{ + codec->REG_150 &= ~CODEC_VAD_FRAME_TH2(0x3ff); + codec->REG_150 |= CODEC_VAD_FRAME_TH2(v); +} + +static inline void hal_codec_vad_set_frame_th3(int v) +{ + codec->REG_150 &= ~CODEC_VAD_FRAME_TH3(0x3fff); + codec->REG_150 |= CODEC_VAD_FRAME_TH3(v); +} + +static inline void hal_codec_vad_set_range1(int v) +{ + codec->REG_154 &= ~CODEC_VAD_RANGE1(0x1f); + codec->REG_154 |= CODEC_VAD_RANGE1(v); +} + +static inline void hal_codec_vad_set_range2(int v) +{ + codec->REG_154 &= ~CODEC_VAD_RANGE2(0x7f); + codec->REG_154 |= CODEC_VAD_RANGE2(v); +} + +static inline void hal_codec_vad_set_range3(int v) +{ + codec->REG_154 &= ~CODEC_VAD_RANGE3(0x1ff); + codec->REG_154 |= CODEC_VAD_RANGE3(v); +} + +static inline void hal_codec_vad_set_range4(int v) +{ + codec->REG_154 &= ~CODEC_VAD_RANGE4(0x3ff); + codec->REG_154 |= CODEC_VAD_RANGE4(v); +} + +static inline void hal_codec_vad_set_psd_th1(int v) +{ + codec->REG_158 &= ~CODEC_VAD_PSD_TH1(0x7ffffff); + codec->REG_158 |= CODEC_VAD_PSD_TH1(v); +} + +static inline void hal_codec_vad_set_psd_th2(int v) +{ + codec->REG_15C &= ~CODEC_VAD_PSD_TH2(0x7ffffff); + codec->REG_15C |= CODEC_VAD_PSD_TH2(v); +} + +static inline void hal_codec_vad_en(int enable) +{ + if (enable) { + codec->REG_148 |= CODEC_VAD_EN; //enable vad + } else { + codec->REG_148 &= ~CODEC_VAD_EN; //disable vad + codec->REG_148 |= CODEC_VAD_FINISH; + } +} + +static inline void hal_codec_vad_bypass_ds(int bypass) +{ + if (bypass) + codec->REG_148 |= CODEC_VAD_DS_BYPASS; //bypass ds + else + codec->REG_148 &= ~CODEC_VAD_DS_BYPASS; //not bypass ds +} + +static inline void hal_codec_vad_bypass_dc(int bypass) +{ + if (bypass) + codec->REG_148 |= CODEC_VAD_DC_CANCEL_BYPASS; // bypass dc + else + codec->REG_148 &= ~CODEC_VAD_DC_CANCEL_BYPASS; //not bypass dc +} + +static inline void hal_codec_vad_bypass_pre(int bypass) +{ + if (bypass) + codec->REG_148 |= CODEC_VAD_PRE_BYPASS; //bypass pre + else + codec->REG_148 &= ~CODEC_VAD_PRE_BYPASS; //not bypass pre +} + +static inline void hal_codec_vad_dig_mode(int enable) +{ + if (enable) + codec->REG_148 |= CODEC_VAD_DIG_MODE; //digital mode + else + codec->REG_148 &= ~CODEC_VAD_DIG_MODE; //not digital mode +} + +static inline void hal_codec_vad_adc_en(int enable) +{ + if (enable) { + codec->REG_080 |= (CODEC_CODEC_ADC_EN | CODEC_CODEC_ADC_EN_CH4); + } else { + uint32_t val; + + val = codec->REG_080; + val &= ~CODEC_CODEC_ADC_EN_CH4; + if ((val & (CODEC_CODEC_ADC_EN_CH0 | CODEC_CODEC_ADC_EN_CH1 | + CODEC_CODEC_ADC_EN_CH2 | CODEC_CODEC_ADC_EN_CH3)) == 0) { + val &= ~CODEC_CODEC_ADC_EN; + } + codec->REG_080 = val; + } +} + +static inline void hal_codec_vad_irq_en(int enable) +{ + if (enable){ + codec->REG_010 |= (CODEC_VAD_FIND_MSK | CODEC_VAD_NOT_FIND_MSK); + } + else{ + codec->REG_010 &= ~(CODEC_VAD_FIND_MSK | CODEC_VAD_NOT_FIND_MSK); + } + + codec->REG_00C = CODEC_VAD_FIND | CODEC_VAD_NOT_FIND; +} + +static inline void hal_codec_vad_adc_if_en(int enable) +{ + if (enable) { + codec->REG_000 |= (CODEC_DMACTRL_RX | CODEC_ADC_ENABLE_CH4 | CODEC_ADC_ENABLE); + } else { + codec->REG_000 &= ~(CODEC_DMACTRL_RX | CODEC_ADC_ENABLE_CH4 | CODEC_ADC_ENABLE); + } +} + +static inline void hal_codec_vad_adc_down(int v) +{ + unsigned int regval = codec->REG_094; + + regval &= ~CODEC_CODEC_ADC_DOWN_SEL_CH4(0x3); + regval |= CODEC_CODEC_ADC_DOWN_SEL_CH4(v); + codec->REG_094 = regval; +} + +#ifdef CODEC_VAD_DEBUG +void hal_codec_vad_reg_dump(void) +{ + TRACE(1,"codec base = %8x\n", (int)&(codec->REG_000)); + TRACE(1,"codec->REG_000 = %x\n", codec->REG_000); + TRACE(1,"codec->REG_00C = %x\n", codec->REG_00C); + TRACE(1,"codec->REG_010 = %x\n", codec->REG_010); + TRACE(1,"codec->REG_060 = %x\n", codec->REG_060); + TRACE(1,"codec->REG_064 = %x\n", codec->REG_064); + TRACE(1,"codec->REG_080 = %x\n", codec->REG_080); + TRACE(1,"codec->REG_094 = %x\n", codec->REG_094); + TRACE(1,"codec->REG_148 = %x\n", codec->REG_148); + TRACE(1,"codec->REG_14C = %x\n", codec->REG_14C); + TRACE(1,"codec->REG_150 = %x\n", codec->REG_150); + TRACE(1,"codec->REG_154 = %x\n", codec->REG_154); + TRACE(1,"codec->REG_158 = %x\n", codec->REG_158); + TRACE(1,"codec->REG_15C = %x\n", codec->REG_15C); +} +#endif + +static inline void hal_codec_vad_data_info(uint32_t *data_cnt, uint32_t *addr_cnt) +{ + uint32_t regval = codec->REG_160; + + *data_cnt = GET_BITFIELD(regval, CODEC_VAD_MEM_DATA_CNT) * 2; + if (*data_cnt >= ((CODEC_VAD_MEM_DATA_CNT_MASK >> CODEC_VAD_MEM_DATA_CNT_SHIFT) - 1) * 2) { + *data_cnt = ((CODEC_VAD_MEM_DATA_CNT_MASK >> CODEC_VAD_MEM_DATA_CNT_SHIFT) + 1) * 2; + } + *addr_cnt = GET_BITFIELD(regval, CODEC_VAD_MEM_ADDR_CNT) * 2; +} + +uint32_t hal_codec_vad_recv_data(uint8_t *dst, uint32_t dst_size) +{ + uint8_t *src = (uint8_t *)CODEC_VAD_BUF_ADDR; + const uint32_t src_size = CODEC_VAD_BUF_SIZE; + uint32_t len; + uint32_t start_pos; + + TRACE(5,"%s, dst=%x, dst_size=%d, vad_data_cnt=%d, vad_addr_cnt=%d", + __func__, (uint32_t)dst, dst_size, vad_data_cnt, vad_addr_cnt); + + if (vad_data_cnt > src_size || vad_addr_cnt >= src_size) { + return 0; + } + + if (dst == NULL) { + return vad_data_cnt; + } + + if (vad_addr_cnt >= vad_data_cnt) { + start_pos = vad_addr_cnt - vad_data_cnt; + } else { + // In this case (src_size == vad_data_cnt) + start_pos = vad_addr_cnt + src_size - vad_data_cnt; + } + + len = MIN(dst_size, vad_data_cnt); + + if (start_pos + len <= src_size) { + memcpy(dst, src + start_pos, len); + } else { + uint32_t len1, len2; + len1 = src_size - start_pos; + len2 = len - len1; + memcpy(dst, src + start_pos, len1); + memcpy(dst + len1, src, len2); + } + + TRACE(2,"%s, len=%d", __func__, len); + return len; +} + +void hal_codec_get_vad_data_info(struct CODEC_VAD_BUF_INFO_T* vad_buf_info) +{ + vad_buf_info->base_addr = CODEC_VAD_BUF_ADDR; + vad_buf_info->buf_size = CODEC_VAD_BUF_SIZE; + vad_buf_info->data_count = vad_data_cnt; + vad_buf_info->addr_count = vad_addr_cnt; +} + +static void hal_codec_vad_isr(uint32_t irq_status) +{ + if ((irq_status & (CODEC_VAD_FIND | CODEC_VAD_NOT_FIND)) == 0) { + return; + } + + TRACE(2,"%s VAD_FIND=%d", __func__, !!(irq_status & CODEC_VAD_FIND)); + + if (vad_handler) { + vad_handler(!!(irq_status & CODEC_VAD_FIND)); + } +} + +int hal_codec_vad_config(const struct AUD_VAD_CONFIG_T *conf) +{ + unsigned int adc_channel_en = 0; + unsigned int cfg_set_mask = 0; + unsigned int cfg_clr_mask = 0; + + if (!conf) + return -1; + + vad_handler = conf->handler; + + hal_codec_vad_en(0); + hal_codec_vad_irq_en(0); + + hal_codec_vad_set_udc(conf->udc); + hal_codec_vad_set_upre(conf->upre); + hal_codec_vad_set_frame_len(conf->frame_len); + hal_codec_vad_set_mvad(conf->mvad); + hal_codec_vad_set_pre_gain(conf->pre_gain); + hal_codec_vad_set_sth(conf->sth); + hal_codec_vad_set_frame_th1(conf->frame_th[0]); + hal_codec_vad_set_frame_th2(conf->frame_th[1]); + hal_codec_vad_set_frame_th3(conf->frame_th[2]); + hal_codec_vad_set_range1(conf->range[0]); + hal_codec_vad_set_range2(conf->range[1]); + hal_codec_vad_set_range3(conf->range[2]); + hal_codec_vad_set_range4(conf->range[3]); + hal_codec_vad_set_psd_th1(conf->psd_th[0]); + hal_codec_vad_set_psd_th2(conf->psd_th[1]); + hal_codec_vad_dig_mode(0); + hal_codec_vad_bypass_dc(0); + hal_codec_vad_bypass_pre(0); + + if (conf->sample_rate == AUD_SAMPRATE_8000) { + // select adc down 8KHz + hal_codec_vad_adc_down(1); + hal_codec_vad_bypass_ds(1); + } else if (conf->sample_rate == AUD_SAMPRATE_16000) { + // select adc down 16KHz + hal_codec_vad_adc_down(0); + hal_codec_vad_bypass_ds(0); + } else { + ASSERT(false, "%s: Bad sample rate: %u", __func__, conf->sample_rate); + } + + cfg_clr_mask = CODEC_MODE_16BIT_ADC_CH0 | CODEC_MODE_16BIT_ADC_CH1 | CODEC_MODE_16BIT_ADC_CH2 | + CODEC_MODE_16BIT_ADC_CH3 | CODEC_MODE_16BIT_ADC_CH4 | CODEC_MODE_16BIT_ADC_CH5 | CODEC_MODE_16BIT_ADC_CH6 | + CODEC_MODE_24BIT_ADC | CODEC_MODE_32BIT_ADC; + + if (conf->bits == AUD_BITS_16) { + cfg_set_mask |= CODEC_MODE_16BIT_ADC_CH0 | CODEC_MODE_16BIT_ADC_CH1 | CODEC_MODE_16BIT_ADC_CH2 | + CODEC_MODE_16BIT_ADC_CH3 | CODEC_MODE_16BIT_ADC_CH4 | CODEC_MODE_16BIT_ADC_CH5 | CODEC_MODE_16BIT_ADC_CH6; + } else if (conf->bits == AUD_BITS_24) { + cfg_set_mask |= CODEC_MODE_24BIT_ADC; + } else if (conf->bits == AUD_BITS_32) { + cfg_set_mask |= CODEC_MODE_32BIT_ADC; + } else { + ASSERT(false, "%s: Bad cap bits: %d", __func__, conf->bits); + } + + for (int i = 0; i < MAX_ADC_CH_NUM; i++){ + adc_channel_en |= (CODEC_ADC_ENABLE_CH0 << i); + } + + if(((codec->REG_000 & adc_channel_en) != 0) && ((codec->REG_040 & cfg_set_mask) == 0)){ + ASSERT(false, "%s: Cap bits conflict: %d", __func__, conf->bits); + }else{ + codec->REG_040 = (codec->REG_040 & ~cfg_clr_mask) | cfg_set_mask; + } + + codec->REG_220 = 320; + codec->REG_224 = 32000*3;//vad timeout value +#ifdef I2C_VAD + codec->REG_230 |= CODEC_VAD_EXT_EN | CODEC_VAD_SRC_SEL; +#endif + +#if !(defined(FIXED_CODEC_ADC_VOL) && defined(SINGLE_CODEC_ADC_VOL)) + const CODEC_ADC_VOL_T *adc_gain_db; + +#ifdef SINGLE_CODEC_ADC_VOL + adc_gain_db = hal_codec_get_adc_volume(CODEC_SADC_VOL); +#else + adc_gain_db = hal_codec_get_adc_volume(hal_codec_get_mic_chan_volume_level(AUD_CHANNEL_MAP_CH4)); +#endif + if (adc_gain_db) { + hal_codec_set_dig_adc_gain(AUD_CHANNEL_MAP_CH4, *adc_gain_db); + } +#endif + + return 0; +} + +int hal_codec_vad_open(const struct AUD_VAD_CONFIG_T *conf) +{ + vad_type = conf->type; + + // open analog vad + analog_aud_vad_adc_enable(true); + + // enable vad clock + hal_cmu_codec_vad_clock_enable(1); + + hal_codec_vad_config(conf); + + return 0; +} + +int hal_codec_vad_close(void) +{ +#ifdef I2C_VAD + codec->REG_230 &= ~(CODEC_VAD_EXT_EN | CODEC_VAD_SRC_SEL); +#endif + + // disable vad clock + hal_cmu_codec_vad_clock_enable(0); + + // close analog vad + analog_aud_vad_adc_enable(false); + + vad_type = AUD_VAD_TYPE_NONE; + + return 0; +} + +int hal_codec_vad_start(void) +{ + if (vad_enabled) { + return 0; + } + vad_enabled = true; + vad_data_cnt = 0; + vad_addr_cnt = 0; + + hal_codec_vad_irq_en(1); + hal_codec_set_irq_handler(CODEC_IRQ_TYPE_VAD, hal_codec_vad_isr); + + if (vad_type == AUD_VAD_TYPE_MIX || vad_type == AUD_VAD_TYPE_DIG) { + // digital vad + hal_codec_vad_en(1); + // enable adc if + hal_codec_vad_adc_if_en(1); + // enable adc + hal_codec_vad_adc_en(1); + } + + analog_aud_vad_enable(vad_type, true); + + return 0; +} + +int hal_codec_vad_stop(void) +{ + if (!vad_enabled) { + return 0; + } + vad_enabled = false; + hal_codec_vad_data_info(&vad_data_cnt, &vad_addr_cnt); + + analog_aud_vad_enable(vad_type, false); + + hal_codec_vad_irq_en(0); + hal_codec_set_irq_handler(CODEC_IRQ_TYPE_VAD, NULL); + + if (vad_type == AUD_VAD_TYPE_MIX || vad_type == AUD_VAD_TYPE_DIG) { + hal_codec_vad_en(0); + hal_codec_vad_adc_if_en(0); + hal_codec_vad_adc_en(0); + } + + return 0; +} + +#endif + +//********************BT trigger functions: START******************** +static void hal_codec_bt_trigger_isr(uint32_t irq_status) +{ + if ((irq_status & CODEC_BT_TRIGGER) == 0) { + return; + } + + if (bt_trigger_callback) { + TRACE(1,"[%s] bt_trigger_callback Start...", __func__); + bt_trigger_callback(); + } else { + TRACE(1,"[%s] bt_trigger_callback = NULL", __func__); + } +} + +static inline void hal_codec_bt_trigger_irq_en(int enable) +{ + if (enable) + codec->REG_010 |= CODEC_BT_TRIGGER_MSK; + else + codec->REG_010 &= ~CODEC_BT_TRIGGER_MSK; + + codec->REG_00C = CODEC_BT_TRIGGER; +} + +void hal_codec_set_bt_trigger_callback(HAL_CODEC_BT_TRIGGER_CALLBACK callback) +{ + bt_trigger_callback = callback; +} + +int hal_codec_bt_trigger_start(void) +{ + uint32_t lock; + + TRACE(1,"[%s] Start", __func__); + + lock = int_lock(); + + hal_codec_set_irq_handler(CODEC_IRQ_TYPE_BT_TRIGGER, hal_codec_bt_trigger_isr); + hal_codec_bt_trigger_irq_en(1); + + int_unlock(lock); + + return 0; +} + +int hal_codec_bt_trigger_stop(void) +{ + uint32_t lock; + + TRACE(1,"[%s] Stop", __func__); + + lock = int_lock(); + + hal_codec_bt_trigger_irq_en(0); + hal_codec_set_irq_handler(CODEC_IRQ_TYPE_BT_TRIGGER, NULL); + + int_unlock(lock); + + return 0; +} +//********************BT trigger functions: END******************** + diff --git a/platform/hal/best2300p/hal_dmacfg_best2300p.h b/platform/hal/best2300p/hal_dmacfg_best2300p.h new file mode 100644 index 0000000..9a9b7ac --- /dev/null +++ b/platform/hal/best2300p/hal_dmacfg_best2300p.h @@ -0,0 +1,115 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_DMACFG_BEST2300P_H__ +#define __HAL_DMACFG_BEST2300P_H__ + +#define AUDMA_PERIPH_NUM 16 +#define GPDMA_PERIPH_NUM 16 + +#define AUDMA_CHAN_NUM 8 +#define GPDMA_CHAN_NUM 8 + +#define AUDMA_CHAN_START (0) +#define GPDMA_CHAN_START (0) + +static const uint32_t audma_fifo_addr[AUDMA_PERIPH_NUM] = { + CODEC_BASE + 0x01C, // CODEC RX + CODEC_BASE + 0x01C, // CODEC TX +#ifdef CODEC_DSD + CODEC_BASE + 0x034, // DSD RX + CODEC_BASE + 0x034, // DSD TX +#else + BTPCM_BASE + 0x1C0, // BTPCM RX + BTPCM_BASE + 0x1C8, // BTPCM TX +#endif + I2S0_BASE + 0x200, // I2S0 RX + I2S0_BASE + 0x240, // I2S0 TX + 0, // FIR RX + 0, // FIR TX + SPDIF0_BASE + 0x1C0, // SPDIF0 RX + SPDIF0_BASE + 0x1C8, // SPDIF0 TX + CODEC_BASE + 0x03C, // IIR RX + CODEC_BASE + 0x03C, // IIR TX + BTDUMP_BASE + 0x34, // BTDUMP + CODEC_BASE + 0x038, // MC RX + I2S1_BASE + 0x200, // I2S1 RX + I2S1_BASE + 0x240, // I2S1 TX +}; + +static const enum HAL_DMA_PERIPH_T audma_fifo_periph[AUDMA_PERIPH_NUM] = { + HAL_AUDMA_CODEC_RX, + HAL_AUDMA_CODEC_TX, +#ifdef CODEC_DSD + HAL_AUDMA_DSD_RX, + HAL_AUDMA_DSD_TX, +#else + HAL_AUDMA_BTPCM_RX, + HAL_AUDMA_BTPCM_TX, +#endif + HAL_AUDMA_I2S0_RX, + HAL_AUDMA_I2S0_TX, + HAL_AUDMA_FIR_RX, + HAL_AUDMA_FIR_TX, + HAL_AUDMA_SPDIF0_RX, + HAL_AUDMA_SPDIF0_TX, + HAL_AUDMA_IIR_RX, + HAL_AUDMA_IIR_TX, + HAL_AUDMA_BTDUMP, + HAL_AUDMA_MC_RX, + HAL_AUDMA_I2S1_RX, + HAL_AUDMA_I2S1_TX, +}; + +static const uint32_t gpdma_fifo_addr[GPDMA_PERIPH_NUM] = { + FLASH_CTRL_BASE + 0x008, // FLASH CTRL + SDMMC_BASE + 0x200, // SDMMC + I2C0_BASE + 0x010, // I2C0 RX + I2C0_BASE + 0x010, // I2C0 TX + SPI_BASE + 0x008, // SPI RX + SPI_BASE + 0x008, // SPI TX + SPILCD_BASE + 0x008, // SPILCD RX + SPILCD_BASE + 0x008, // SPILCD TX + UART0_BASE + 0x000, // UART0 RX + UART0_BASE + 0x000, // UART0 TX + UART1_BASE + 0x000, // UART1 RX + UART1_BASE + 0x000, // UART1 TX + I2C1_BASE + 0x010, // I2C1 RX + I2C1_BASE + 0x010, // I2C1 TX + UART2_BASE + 0x000, // UART2 RX + UART2_BASE + 0x000, // UART2 TX +}; + +static const enum HAL_DMA_PERIPH_T gpdma_fifo_periph[GPDMA_PERIPH_NUM] = { + HAL_GPDMA_FLASH_TX, + HAL_GPDMA_SDMMC, + HAL_GPDMA_I2C0_RX, + HAL_GPDMA_I2C0_TX, + HAL_GPDMA_SPI_RX, + HAL_GPDMA_SPI_TX, + HAL_GPDMA_SPILCD_RX, + HAL_GPDMA_SPILCD_TX, + HAL_GPDMA_UART0_RX, + HAL_GPDMA_UART0_TX, + HAL_GPDMA_UART1_RX, + HAL_GPDMA_UART1_TX, + HAL_GPDMA_I2C1_RX, + HAL_GPDMA_I2C1_TX, + HAL_GPDMA_UART2_RX, + HAL_GPDMA_UART2_TX, +}; + +#endif + diff --git a/platform/hal/best2300p/hal_iomux_best2300p.c b/platform/hal/best2300p/hal_iomux_best2300p.c new file mode 100644 index 0000000..594d44c --- /dev/null +++ b/platform/hal/best2300p/hal_iomux_best2300p.c @@ -0,0 +1,1104 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include CHIP_SPECIFIC_HDR(reg_iomux) +#include "hal_iomux.h" +#include "hal_chipid.h" +#include "hal_gpio.h" +#include "hal_location.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "pmu.h" + +#ifdef I2S0_VOLTAGE_VMEM +#define I2S0_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_MEM +#else +#define I2S0_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_VIO +#endif + +#ifdef I2S1_VOLTAGE_VMEM +#define I2S1_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_MEM +#else +#define I2S1_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_VIO +#endif + +#ifdef SPDIF0_VOLTAGE_VMEM +#define SPDIF0_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_MEM +#else +#define SPDIF0_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_VIO +#endif + +#ifdef DIGMIC_VOLTAGE_VMEM +#define DIGMIC_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_MEM +#else +#define DIGMIC_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_VIO +#endif + +#ifdef SPI_VOLTAGE_VMEM +#define SPI_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_MEM +#else +#define SPI_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_VIO +#endif + +#ifdef SPILCD_VOLTAGE_VMEM +#define SPILCD_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_MEM +#else +#define SPILCD_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_VIO +#endif + +#ifdef I2C0_VOLTAGE_VMEM +#define I2C0_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_MEM +#else +#define I2C0_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_VIO +#endif + +#ifdef I2C1_VOLTAGE_VMEM +#define I2C1_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_MEM +#else +#define I2C1_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_VIO +#endif + +#ifdef CLKOUT_VOLTAGE_VMEM +#define CLKOUT_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_MEM +#else +#define CLKOUT_VOLTAGE_SEL HAL_IOMUX_PIN_VOLTAGE_VIO +#endif + +#ifndef I2S0_IOMUX_INDEX +#define I2S0_IOMUX_INDEX 0 +#endif + +#ifndef I2S1_IOMUX_INDEX +#define I2S1_IOMUX_INDEX 0 +#endif + +#ifndef I2S_MCLK_IOMUX_INDEX +#define I2S_MCLK_IOMUX_INDEX 0 +#endif + +#ifndef SPDIF0_IOMUX_INDEX +#define SPDIF0_IOMUX_INDEX 0 +#endif + +#ifndef DIG_MIC2_CK_IOMUX_INDEX +#define DIG_MIC2_CK_IOMUX_INDEX 0 +#endif + +#ifndef DIG_MIC3_CK_IOMUX_INDEX +#define DIG_MIC3_CK_IOMUX_INDEX 0 +#endif + +#ifndef DIG_MIC_CK_IOMUX_PIN +#define DIG_MIC_CK_IOMUX_PIN 0 +#endif + +#ifndef DIG_MIC_D0_IOMUX_PIN +#define DIG_MIC_D0_IOMUX_PIN 1 +#endif + +#ifndef DIG_MIC_D1_IOMUX_PIN +#define DIG_MIC_D1_IOMUX_PIN 2 +#endif + +#ifndef DIG_MIC_D2_IOMUX_PIN +#define DIG_MIC_D2_IOMUX_PIN 3 +#endif + +#ifndef SPI_IOMUX_INDEX +#define SPI_IOMUX_INDEX 0 +#endif + +#ifndef SPILCD_IOMUX_INDEX +#define SPILCD_IOMUX_INDEX 0 +#endif + +#ifndef I2C0_IOMUX_INDEX +#define I2C0_IOMUX_INDEX 0 +#endif + +#ifndef I2C1_IOMUX_INDEX +#define I2C1_IOMUX_INDEX 0 +#endif + +#ifndef CLKOUT_IOMUX_INDEX +#define CLKOUT_IOMUX_INDEX 0 +#endif + +#define IOMUX_FUNC_VAL_GPIO 0 + +#define IOMUX_ALT_FUNC_NUM 6 + +// Other func values: 0 -> gpio, 6 -> rf_ana, 7 -> jtag/btdm, 9 -> clk_req, 10 -> ana_test +static const uint8_t index_to_func_val[IOMUX_ALT_FUNC_NUM] = { 1, 2, 3, 4, 5, 8, }; + +static const enum HAL_IOMUX_FUNCTION_T pin_func_map[HAL_IOMUX_PIN_NUM][IOMUX_ALT_FUNC_NUM] = { + // P0_0 + { HAL_IOMUX_FUNC_I2S0_SDI0, HAL_IOMUX_FUNC_UART2_RX, HAL_IOMUX_FUNC_PCM_DI, HAL_IOMUX_FUNC_SPILCD_DI0, + HAL_IOMUX_FUNC_PDM0_CK, HAL_IOMUX_FUNC_SPILCD_DCN, }, + // P0_1 + { HAL_IOMUX_FUNC_I2S0_SDO, HAL_IOMUX_FUNC_UART2_TX, HAL_IOMUX_FUNC_PCM_DO, HAL_IOMUX_FUNC_SPILCD_DIO, + HAL_IOMUX_FUNC_PDM0_D, HAL_IOMUX_FUNC_NONE, }, + // P0_2 + { HAL_IOMUX_FUNC_I2S0_WS, HAL_IOMUX_FUNC_I2C_M1_SCL, HAL_IOMUX_FUNC_PCM_FSYNC, HAL_IOMUX_FUNC_SPILCD_CS0, + HAL_IOMUX_FUNC_PDM1_D, HAL_IOMUX_FUNC_NONE, }, + // P0_3 + { HAL_IOMUX_FUNC_I2S0_SCK, HAL_IOMUX_FUNC_I2C_M1_SDA, HAL_IOMUX_FUNC_PCM_CLK, HAL_IOMUX_FUNC_SPILCD_CLK, + HAL_IOMUX_FUNC_PDM2_D, HAL_IOMUX_FUNC_NONE, }, + // P0_4 + { HAL_IOMUX_FUNC_SDMMC_DATA7, HAL_IOMUX_FUNC_SPI_DI0, HAL_IOMUX_FUNC_I2S0_MCLK, HAL_IOMUX_FUNC_CLK_OUT, + HAL_IOMUX_FUNC_PDM1_CK, HAL_IOMUX_FUNC_SPI_DCN, }, + // P0_5 + { HAL_IOMUX_FUNC_SDMMC_DATA6, HAL_IOMUX_FUNC_SPI_CLK, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPILCD_CS1, + HAL_IOMUX_FUNC_PDM1_D, HAL_IOMUX_FUNC_NONE, }, + // P0_6 + { HAL_IOMUX_FUNC_SDMMC_DATA5, HAL_IOMUX_FUNC_SPI_CS0, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPILCD_CS2, + HAL_IOMUX_FUNC_PDM0_D, HAL_IOMUX_FUNC_NONE, }, + // P0_7 + { HAL_IOMUX_FUNC_SDMMC_DATA4, HAL_IOMUX_FUNC_SPI_DIO, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPILCD_CS3, + HAL_IOMUX_FUNC_PDM2_D, HAL_IOMUX_FUNC_NONE, }, + // P1_0 + { HAL_IOMUX_FUNC_SDMMC_DATA2, HAL_IOMUX_FUNC_I2S1_SCK, HAL_IOMUX_FUNC_SPILCD_CLK, HAL_IOMUX_FUNC_SPI_CS1, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P1_1 + { HAL_IOMUX_FUNC_SDMMC_DATA3, HAL_IOMUX_FUNC_I2S1_WS, HAL_IOMUX_FUNC_SPILCD_CS0, HAL_IOMUX_FUNC_SPI_CS2, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P1_2 + { HAL_IOMUX_FUNC_SDMMC_CMD, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPILCD_CS1, HAL_IOMUX_FUNC_SPI_CS3, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P1_3 + { HAL_IOMUX_FUNC_SDMMC_CLK, HAL_IOMUX_FUNC_I2S0_MCLK, HAL_IOMUX_FUNC_SPILCD_DCN, HAL_IOMUX_FUNC_CLK_OUT, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P1_4 + { HAL_IOMUX_FUNC_SDMMC_DATA0, HAL_IOMUX_FUNC_I2S1_SDI0, HAL_IOMUX_FUNC_SPILCD_DI0, HAL_IOMUX_FUNC_NONE, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P1_5 + { HAL_IOMUX_FUNC_SDMMC_DATA1, HAL_IOMUX_FUNC_I2S1_SDO, HAL_IOMUX_FUNC_SPILCD_DIO, HAL_IOMUX_FUNC_I2S0_MCLK, + HAL_IOMUX_FUNC_CLK_OUT, HAL_IOMUX_FUNC_NONE, }, + // P1_6 + { HAL_IOMUX_FUNC_UART0_RX, HAL_IOMUX_FUNC_I2C_M0_SCL, HAL_IOMUX_FUNC_BT_UART_RX, HAL_IOMUX_FUNC_NONE, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P1_7 + { HAL_IOMUX_FUNC_UART0_TX, HAL_IOMUX_FUNC_I2C_M0_SDA, HAL_IOMUX_FUNC_BT_UART_TX, HAL_IOMUX_FUNC_NONE, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P2_0 + { HAL_IOMUX_FUNC_UART1_RX, HAL_IOMUX_FUNC_I2C_M0_SCL, HAL_IOMUX_FUNC_BT_UART_RX, HAL_IOMUX_FUNC_SPDIF0_DI, + HAL_IOMUX_FUNC_PWM0, HAL_IOMUX_FUNC_I2S0_MCLK, }, + // P2_1 + { HAL_IOMUX_FUNC_UART1_TX, HAL_IOMUX_FUNC_I2C_M0_SDA, HAL_IOMUX_FUNC_BT_UART_TX, HAL_IOMUX_FUNC_SPDIF0_DO, + HAL_IOMUX_FUNC_PWM1, HAL_IOMUX_FUNC_CLK_OUT, }, + // P2_2 + { HAL_IOMUX_FUNC_I2C_M1_SCL, HAL_IOMUX_FUNC_UART2_RX, HAL_IOMUX_FUNC_UART1_CTS, HAL_IOMUX_FUNC_BT_UART_CTS, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_I2S0_MCLK, }, + // P2_3 + { HAL_IOMUX_FUNC_I2C_M1_SDA, HAL_IOMUX_FUNC_UART2_TX, HAL_IOMUX_FUNC_UART1_RTS, HAL_IOMUX_FUNC_BT_UART_RTS, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_CLK_OUT, }, + // P2_4 + { HAL_IOMUX_FUNC_PWM0, HAL_IOMUX_FUNC_CLK_REQ_OUT, HAL_IOMUX_FUNC_SPI_DI3, HAL_IOMUX_FUNC_NONE, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P2_5 + { HAL_IOMUX_FUNC_PWM1, HAL_IOMUX_FUNC_CLK_REQ_IN, HAL_IOMUX_FUNC_SPI_CS3, HAL_IOMUX_FUNC_NONE, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P2_6 + { HAL_IOMUX_FUNC_PWM2, HAL_IOMUX_FUNC_SPILCD_DI1, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPDIF0_DI, + HAL_IOMUX_FUNC_CLK_32K_IN, HAL_IOMUX_FUNC_NONE, }, + // P2_7 + { HAL_IOMUX_FUNC_PWM3, HAL_IOMUX_FUNC_SPILCD_CS1, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPDIF0_DO, + HAL_IOMUX_FUNC_CLK_OUT, HAL_IOMUX_FUNC_NONE, }, + // P3_0 + { HAL_IOMUX_FUNC_SPILCD_DI2, HAL_IOMUX_FUNC_I2S1_SCK, HAL_IOMUX_FUNC_SPILCD_CS1, HAL_IOMUX_FUNC_NONE, + HAL_IOMUX_FUNC_PDM0_D, HAL_IOMUX_FUNC_NONE, }, + // P3_1 + { HAL_IOMUX_FUNC_SPILCD_CS2, HAL_IOMUX_FUNC_I2S1_WS, HAL_IOMUX_FUNC_SPILCD_CS3, HAL_IOMUX_FUNC_NONE, + HAL_IOMUX_FUNC_PDM1_D, HAL_IOMUX_FUNC_NONE, }, + // P3_2 + { HAL_IOMUX_FUNC_SPILCD_CS3, HAL_IOMUX_FUNC_I2S1_SDI0, HAL_IOMUX_FUNC_SPILCD_CS3, HAL_IOMUX_FUNC_NONE, + HAL_IOMUX_FUNC_PDM2_D, HAL_IOMUX_FUNC_NONE, }, + // P3_3 + { HAL_IOMUX_FUNC_SPILCD_DI3, HAL_IOMUX_FUNC_I2S1_SDO, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, + HAL_IOMUX_FUNC_PDM2_CK, HAL_IOMUX_FUNC_NONE, }, + // P3_4 + { HAL_IOMUX_FUNC_PWM0, HAL_IOMUX_FUNC_SPI_DI1, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPILCD_DI0, + HAL_IOMUX_FUNC_CLK_OUT, HAL_IOMUX_FUNC_SPILCD_DCN, }, + // P3_5 + { HAL_IOMUX_FUNC_PWM1, HAL_IOMUX_FUNC_SPI_CS1, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPILCD_DIO, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P3_6 + { HAL_IOMUX_FUNC_PWM2, HAL_IOMUX_FUNC_SPI_DI2, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPILCD_CS0, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, + // P3_7 + { HAL_IOMUX_FUNC_PWM3, HAL_IOMUX_FUNC_SPI_CS2, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPILCD_CLK, + HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, }, +}; + +static struct IOMUX_T * const iomux = (struct IOMUX_T *)IOMUX_BASE; + +#ifdef ANC_PROD_TEST +#define OPT_TYPE +#else +#define OPT_TYPE const +#endif + +static OPT_TYPE enum HAL_IOMUX_PIN_T digmic_ck_pin = DIG_MIC_CK_IOMUX_PIN; + +static OPT_TYPE enum HAL_IOMUX_PIN_T digmic_d0_pin = DIG_MIC_D0_IOMUX_PIN; +static OPT_TYPE enum HAL_IOMUX_PIN_T digmic_d1_pin = DIG_MIC_D1_IOMUX_PIN; +static OPT_TYPE enum HAL_IOMUX_PIN_T digmic_d2_pin = DIG_MIC_D2_IOMUX_PIN; + +static enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T BOOT_DATA_LOC uart0_volt = HAL_IOMUX_PIN_VOLTAGE_VIO; +// UART1 is tied to vmem domain + +void hal_iomux_set_default_config(void) +{ + uint32_t i; + // Set all unused GPIOs to pull-down by default + for (i = 0; i < 8; i++) { + if (((iomux->REG_004 & (0xF << (i * 4))) >> (i * 4)) == 0xF) { + iomux->REG_030 |= (1 << i); + } + } + for (i = 0; i < 6; i++) { + if (((iomux->REG_008 & (0xF << (i * 4))) >> (i * 4)) == 0xF) { + iomux->REG_030 |= (1 << (i + 8)); + } + } + for (i = 0; i < 8; i++) { + if (((iomux->REG_00C & (0xF << (i * 4))) >> (i * 4)) == 0xF) { + iomux->REG_030 |= (1 << (i + 16)); + } + } + for (i = 0; i < 8; i++) { + if (((iomux->REG_010 & (0xF << (i * 4))) >> (i * 4)) == 0xF) { + iomux->REG_030 |= (1 << (i + 24)); + } + } +} + +uint32_t hal_iomux_check(const struct HAL_IOMUX_PIN_FUNCTION_MAP *map, uint32_t count) +{ + uint32_t i; + for (i = 0; i < count; ++i) { + } + return 0; +} + +uint32_t hal_iomux_init(const struct HAL_IOMUX_PIN_FUNCTION_MAP *map, uint32_t count) +{ + uint32_t i; + uint32_t ret; + + for (i = 0; i < count; ++i) { + ret = hal_iomux_set_function(map[i].pin, map[i].function, HAL_IOMUX_OP_CLEAN_OTHER_FUNC_BIT); + if (ret) { + return (i << 8) + 1; + } + ret = hal_iomux_set_io_voltage_domains(map[i].pin, map[i].volt); + if (ret) { + return (i << 8) + 2; + } + ret = hal_iomux_set_io_pull_select(map[i].pin, map[i].pull_sel); + if (ret) { + return (i << 8) + 3; + } + } + + return 0; +} + +#ifdef ANC_PROD_TEST +void hal_iomux_set_dig_mic_clock_pin(enum HAL_IOMUX_PIN_T pin) +{ + digmic_ck_pin = pin; +} +void hal_iomux_set_dig_mic_data0_pin(enum HAL_IOMUX_PIN_T pin) +{ + digmic_d0_pin = pin; +} + +void hal_iomux_set_dig_mic_data1_pin(enum HAL_IOMUX_PIN_T pin) +{ + digmic_d1_pin = pin; +} + +void hal_iomux_set_dig_mic_data2_pin(enum HAL_IOMUX_PIN_T pin) +{ + digmic_d2_pin = pin; +} +#endif + + +uint32_t hal_iomux_set_function(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_FUNCTION_T func, enum HAL_IOMUX_OP_TYPE_T type) +{ + int i; + uint8_t val; + __IO uint32_t *reg; + uint32_t shift; + + if (pin >= HAL_IOMUX_PIN_LED_NUM) { + return 1; + } + if (func >= HAL_IOMUX_FUNC_END) { + return 2; + } + + if (pin == HAL_IOMUX_PIN_P1_6 || pin == HAL_IOMUX_PIN_P1_7) { + if (func == HAL_IOMUX_FUNC_I2C_SCL || func == HAL_IOMUX_FUNC_I2C_SDA) { + // Enable analog I2C slave + iomux->REG_050 &= ~IOMUX_GPIO_I2C_MODE; + // Set mcu GPIO func + iomux->REG_008 = (iomux->REG_008 & ~(IOMUX_GPIO_P16_SEL_MASK | IOMUX_GPIO_P17_SEL_MASK)) | + IOMUX_GPIO_P16_SEL(IOMUX_FUNC_VAL_GPIO) | IOMUX_GPIO_P17_SEL(IOMUX_FUNC_VAL_GPIO); + return 0; + } else { + iomux->REG_050 |= IOMUX_GPIO_I2C_MODE; + // Continue to set the alt func + } + } else if (pin == HAL_IOMUX_PIN_P0_2) { + if (func == HAL_IOMUX_FUNC_SPDIF0_DI) { + iomux->REG_004 = SET_BITFIELD(iomux->REG_004, IOMUX_GPIO_P02_SEL, 6); + return 0; + } + } else if (pin == HAL_IOMUX_PIN_P0_3) { + if (func == HAL_IOMUX_FUNC_SPDIF0_DO) { + iomux->REG_004 = SET_BITFIELD(iomux->REG_004, IOMUX_GPIO_P03_SEL, 6); + return 0; + } + } else if (pin == HAL_IOMUX_PIN_P2_0) { + if (func == HAL_IOMUX_FUNC_CLK_REQ_OUT) { + iomux->REG_00C = SET_BITFIELD(iomux->REG_00C, IOMUX_GPIO_P20_SEL, 9); + return 0; + } + } else if (pin == HAL_IOMUX_PIN_P2_1) { + if (func == HAL_IOMUX_FUNC_CLK_REQ_IN) { + iomux->REG_00C = SET_BITFIELD(iomux->REG_00C, IOMUX_GPIO_P21_SEL, 9); + return 0; + } + } else if (pin == HAL_IOMUX_PIN_LED1 || pin == HAL_IOMUX_PIN_LED2) { + ASSERT(func == HAL_IOMUX_FUNC_GPIO, "Bad func=%d for IOMUX pin=%d", func, pin); + return 0; + } + + if (func == HAL_IOMUX_FUNC_GPIO) { + val = IOMUX_FUNC_VAL_GPIO; + } else { + for (i = 0; i < IOMUX_ALT_FUNC_NUM; i++) { + if (pin_func_map[pin][i] == func) { + break; + } + } + + if (i == IOMUX_ALT_FUNC_NUM) { + return 3; + } + val = index_to_func_val[i]; + } + + reg = &iomux->REG_004 + pin / 8; + shift = (pin % 8) * 4; + + *reg = (*reg & ~(0xF << shift)) | (val << shift); + + return 0; +} + +enum HAL_IOMUX_FUNCTION_T hal_iomux_get_function(enum HAL_IOMUX_PIN_T pin) +{ + return HAL_IOMUX_FUNC_NONE; +} + +uint32_t hal_iomux_set_io_voltage_domains(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt) +{ + if (pin >= HAL_IOMUX_PIN_LED_NUM) { + return 1; + } + + if (pin == HAL_IOMUX_PIN_LED1 || pin == HAL_IOMUX_PIN_LED2) { + pmu_led_set_voltage_domains(pin, volt); + } + + return 0; +} + +uint32_t hal_iomux_set_io_pull_select(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_PIN_PULL_SELECT_T pull_sel) +{ + if (pin >= HAL_IOMUX_PIN_LED_NUM) { + return 1; + } + + if (pin < HAL_IOMUX_PIN_LED1) { + iomux->REG_02C &= ~(1 << pin); + iomux->REG_030 &= ~(1 << pin); + if (pull_sel == HAL_IOMUX_PIN_PULLUP_ENABLE) { + iomux->REG_02C |= (1 << pin); + } else if (pull_sel == HAL_IOMUX_PIN_PULLDOWN_ENABLE) { + iomux->REG_030 |= (1 << pin); + } + } else if (pin == HAL_IOMUX_PIN_LED1 || pin == HAL_IOMUX_PIN_LED2) { + pmu_led_set_pull_select(pin, pull_sel); + } + + return 0; +} + +void hal_iomux_set_sdmmc_dt_n_out_group(int enable) +{ +} + +void hal_iomux_set_uart0_voltage(enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt) +{ + uart0_volt = volt; +} + +void hal_iomux_set_uart1_voltage(enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt) +{ +} + +bool hal_iomux_uart0_connected(void) +{ + uint32_t reg_050, reg_008, reg_02c, reg_030; + uint32_t mask; + int val; + + // Save current iomux settings + reg_050 = iomux->REG_050; + reg_008 = iomux->REG_008; + reg_02c = iomux->REG_02C; + reg_030 = iomux->REG_030; + + // Disable analog I2C slave & master + iomux->REG_050 |= IOMUX_GPIO_I2C_MODE | IOMUX_I2C0_M_SEL_GPIO; + // Set uart0-rx as gpio + iomux->REG_008 = SET_BITFIELD(iomux->REG_008, IOMUX_GPIO_P16_SEL, IOMUX_FUNC_VAL_GPIO); + + mask = (1 << HAL_IOMUX_PIN_P1_6); + // Set voltage domain + if (uart0_volt == HAL_IOMUX_PIN_VOLTAGE_VIO) { + iomux->REG_070 |= (1 << (IOMUX_GPIO_P1_PWS_SHIFT + 1)); + } else { + iomux->REG_070 &= ~(1 << (IOMUX_GPIO_P1_PWS_SHIFT + 1)); + } + // Clear pullup + iomux->REG_02C &= ~mask; + // Setup pulldown + iomux->REG_030 |= mask; + + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)HAL_IOMUX_PIN_P1_6, HAL_GPIO_DIR_IN, 0); + + hal_sys_timer_delay(MS_TO_TICKS(2)); + + val = hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)HAL_IOMUX_PIN_P1_6); + + // Restore iomux settings + iomux->REG_030 = reg_030; + iomux->REG_02C = reg_02c; + iomux->REG_008 = reg_008; + iomux->REG_050 = reg_050; + + hal_sys_timer_delay(MS_TO_TICKS(2)); + + return !!val; +} + +bool hal_iomux_uart1_connected(void) +{ + uint32_t reg_00c, reg_02c, reg_030; + uint32_t mask; + int val; + + // Save current iomux settings + reg_00c = iomux->REG_00C; + reg_02c = iomux->REG_02C; + reg_030 = iomux->REG_030; + + // Set uart1-rx as gpio + iomux->REG_00C = SET_BITFIELD(iomux->REG_00C, IOMUX_GPIO_P20_SEL, IOMUX_FUNC_VAL_GPIO); + + mask = (1 << HAL_IOMUX_PIN_P2_0); + // Clear pullup + iomux->REG_02C &= ~mask; + // Setup pulldown + iomux->REG_030 |= mask; + + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)HAL_IOMUX_PIN_P2_0, HAL_GPIO_DIR_IN, 0); + + hal_sys_timer_delay(MS_TO_TICKS(2)); + + val = hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)HAL_IOMUX_PIN_P2_0); + + // Restore iomux settings + iomux->REG_030 = reg_030; + iomux->REG_02C = reg_02c; + iomux->REG_00C = reg_00c; + + hal_sys_timer_delay(MS_TO_TICKS(2)); + + return !!val; +} + +void hal_iomux_set_uart0(void) +{ + uint32_t mask; + + // Disable analog I2C slave & master + iomux->REG_050 |= IOMUX_GPIO_I2C_MODE | IOMUX_I2C0_M_SEL_GPIO; + // Set uart0 func + iomux->REG_008 = (iomux->REG_008 & ~(IOMUX_GPIO_P16_SEL_MASK | IOMUX_GPIO_P17_SEL_MASK)) | + IOMUX_GPIO_P16_SEL(1) | IOMUX_GPIO_P17_SEL(1); + + mask = (1 << HAL_IOMUX_PIN_P1_6) | (1 << HAL_IOMUX_PIN_P1_7); + // Set voltage domain + if (uart0_volt == HAL_IOMUX_PIN_VOLTAGE_VIO) { + iomux->REG_070 |= (1 << (IOMUX_GPIO_P1_PWS_SHIFT + 1)); + } else { + iomux->REG_070 &= ~(1 << (IOMUX_GPIO_P1_PWS_SHIFT + 1)); + } + // Setup pullup + iomux->REG_02C |= (1 << HAL_IOMUX_PIN_P1_6); + iomux->REG_02C &= ~(1 << HAL_IOMUX_PIN_P1_7); + // Clear pulldown + iomux->REG_030 &= ~mask; +} + +void hal_iomux_set_uart1(void) +{ + uint32_t mask; + + // Set uart1 func + iomux->REG_00C = (iomux->REG_00C & ~(IOMUX_GPIO_P20_SEL_MASK | IOMUX_GPIO_P21_SEL_MASK)) | + IOMUX_GPIO_P20_SEL(1) | IOMUX_GPIO_P21_SEL(1); + + mask = (1 << HAL_IOMUX_PIN_P2_0) | (1 << HAL_IOMUX_PIN_P2_1); + // Setup pullup + iomux->REG_02C |= (1 << HAL_IOMUX_PIN_P2_0); + iomux->REG_02C &= ~(1 << HAL_IOMUX_PIN_P2_1); + // Clear pulldown + iomux->REG_030 &= ~mask; +} + +void hal_iomux_set_uart2(void) +{ +} + +void hal_iomux_set_analog_i2c(void) +{ + uint32_t mask; + + // Disable analog I2C master + iomux->REG_050 |= IOMUX_I2C0_M_SEL_GPIO; + // Set mcu GPIO func + iomux->REG_008 = (iomux->REG_008 & ~(IOMUX_GPIO_P16_SEL_MASK | IOMUX_GPIO_P17_SEL_MASK)) | + IOMUX_GPIO_P16_SEL(0) | IOMUX_GPIO_P17_SEL(0); + // Enable analog I2C slave + iomux->REG_050 &= ~IOMUX_GPIO_I2C_MODE; + + mask = (1 << HAL_IOMUX_PIN_P1_6) | (1 << HAL_IOMUX_PIN_P1_7); + // Set voltage domain + if (uart0_volt == HAL_IOMUX_PIN_VOLTAGE_VIO) { + iomux->REG_070 |= (1 << (IOMUX_GPIO_P1_PWS_SHIFT + 1)); + } else { + iomux->REG_070 &= ~(1 << (IOMUX_GPIO_P1_PWS_SHIFT + 1)); + } + // Setup pullup + iomux->REG_02C |= mask; + // Clear pulldown + iomux->REG_030 &= ~mask; +} + +void hal_iomux_set_jtag(void) +{ + uint32_t mask; + uint32_t val; + + // SWCLK/TCK, SWDIO/TMS + mask = IOMUX_GPIO_P01_SEL_MASK | IOMUX_GPIO_P02_SEL_MASK; + val = IOMUX_GPIO_P01_SEL(7) | IOMUX_GPIO_P02_SEL(7); + + // TDI, TDO +#ifdef JTAG_TDI_TDO_PIN + mask |= IOMUX_GPIO_P00_SEL_MASK | IOMUX_GPIO_P03_SEL_MASK; + val |= IOMUX_GPIO_P00_SEL(7) | IOMUX_GPIO_P03_SEL(7); +#endif + iomux->REG_004 = (iomux->REG_004 & ~mask) | val; + + // RESET +#if defined(JTAG_RESET_PIN) || defined(JTAG_TDI_TDO_PIN) + iomux->REG_00C = (iomux->REG_00C & ~(IOMUX_GPIO_P20_SEL_MASK)) | IOMUX_GPIO_P20_SEL(7); +#endif + + mask = (1 << HAL_IOMUX_PIN_P0_1) | (1 << HAL_IOMUX_PIN_P0_2); +#ifdef JTAG_TDI_TDO_PIN + mask |= (1 << HAL_IOMUX_PIN_P0_0) | (1 << HAL_IOMUX_PIN_P0_3); +#endif +#if defined(JTAG_RESET_PIN) || defined(JTAG_TDI_TDO_PIN) + mask |= (1 << HAL_IOMUX_PIN_P2_0); +#endif + // Clear pullup + iomux->REG_02C &= ~mask; + // Clear pulldown + iomux->REG_030 &= ~mask; +} + +enum HAL_IOMUX_ISPI_ACCESS_T hal_iomux_ispi_access_enable(enum HAL_IOMUX_ISPI_ACCESS_T access) +{ + uint32_t v; + + v = iomux->REG_044; + iomux->REG_044 |= access; + + return v; +} + +enum HAL_IOMUX_ISPI_ACCESS_T hal_iomux_ispi_access_disable(enum HAL_IOMUX_ISPI_ACCESS_T access) +{ + uint32_t v; + + v = iomux->REG_044; + iomux->REG_044 &= ~access; + + return v; +} + +void hal_iomux_ispi_access_init(void) +{ + // Disable bt spi access ana/pmu interface + hal_iomux_ispi_access_disable(HAL_IOMUX_ISPI_BT_ANA | HAL_IOMUX_ISPI_BT_PMU); +} + +void hal_iomux_set_i2s0(void) +{ + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_i2s[] = { + {HAL_IOMUX_PIN_P0_0, HAL_IOMUX_FUNC_I2S0_SDI0, I2S0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P0_1, HAL_IOMUX_FUNC_I2S0_SDO, I2S0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P0_2, HAL_IOMUX_FUNC_I2S0_WS, I2S0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P0_3, HAL_IOMUX_FUNC_I2S0_SCK, I2S0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + }; + + hal_iomux_init(pinmux_i2s, ARRAY_SIZE(pinmux_i2s)); +} + +void hal_iomux_set_i2s1(void) +{ + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_i2s[] = { +#if (I2S1_IOMUX_INDEX == 30) + {HAL_IOMUX_PIN_P3_2, HAL_IOMUX_FUNC_I2S1_SDI0, I2S1_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P3_3, HAL_IOMUX_FUNC_I2S1_SDO, I2S1_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P3_1, HAL_IOMUX_FUNC_I2S1_WS, I2S1_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P3_0, HAL_IOMUX_FUNC_I2S1_SCK, I2S1_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P1_4, HAL_IOMUX_FUNC_I2S1_SDI0, I2S1_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P1_5, HAL_IOMUX_FUNC_I2S1_SDO, I2S1_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P1_1, HAL_IOMUX_FUNC_I2S1_WS, I2S1_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P1_0, HAL_IOMUX_FUNC_I2S1_SCK, I2S1_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + }; +#endif + hal_iomux_init(pinmux_i2s, ARRAY_SIZE(pinmux_i2s)); +} + +void hal_iomux_set_i2s_mclk(void) +{ + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux[] = { +#if (I2S_MCLK_IOMUX_INDEX == 13) + {HAL_IOMUX_PIN_P1_3, HAL_IOMUX_FUNC_I2S0_MCLK, I2S0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (I2S_MCLK_IOMUX_INDEX == 15) + {HAL_IOMUX_PIN_P1_5, HAL_IOMUX_FUNC_I2S0_MCLK, I2S0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (I2S_MCLK_IOMUX_INDEX == 20) + {HAL_IOMUX_PIN_P2_0, HAL_IOMUX_FUNC_I2S0_MCLK, I2S0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (I2S_MCLK_IOMUX_INDEX == 22) + {HAL_IOMUX_PIN_P2_2, HAL_IOMUX_FUNC_I2S0_MCLK, I2S0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P0_4, HAL_IOMUX_FUNC_I2S0_MCLK, I2S0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif + }; + + hal_iomux_init(pinmux, ARRAY_SIZE(pinmux)); +} + +void hal_iomux_set_spdif0(void) +{ + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_spdif[] = { +#if (SPDIF0_IOMUX_INDEX == 20) + {HAL_IOMUX_PIN_P2_0, HAL_IOMUX_FUNC_SPDIF0_DI, SPDIF0_VOLTAGE_SEL, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_P2_1, HAL_IOMUX_FUNC_SPDIF0_DO, SPDIF0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (SPDIF0_IOMUX_INDEX == 26) + {HAL_IOMUX_PIN_P2_6, HAL_IOMUX_FUNC_SPDIF0_DI, SPDIF0_VOLTAGE_SEL, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_P2_7, HAL_IOMUX_FUNC_SPDIF0_DO, SPDIF0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P0_2, HAL_IOMUX_FUNC_SPDIF0_DI, SPDIF0_VOLTAGE_SEL, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_P0_3, HAL_IOMUX_FUNC_SPDIF0_DO, SPDIF0_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif + }; + + hal_iomux_init(pinmux_spdif, ARRAY_SIZE(pinmux_spdif)); +} + +void hal_iomux_set_spdif1(void) +{ +} + +void hal_iomux_set_dig_mic(uint32_t map) +{ + struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_digitalmic_clk[] = { + {HAL_IOMUX_PIN_P0_0, HAL_IOMUX_FUNC_PDM0_CK, DIGMIC_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + }; + struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_digitalmic0[] = { + {HAL_IOMUX_PIN_P0_1, HAL_IOMUX_FUNC_PDM0_D, DIGMIC_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + }; + struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_digitalmic1[] = { + {HAL_IOMUX_PIN_P0_2, HAL_IOMUX_FUNC_PDM1_D, DIGMIC_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + }; + struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_digitalmic2[] = { + {HAL_IOMUX_PIN_P0_3, HAL_IOMUX_FUNC_PDM2_D, DIGMIC_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + }; + + if (digmic_ck_pin == HAL_IOMUX_PIN_P0_0) { + pinmux_digitalmic_clk[0].pin = HAL_IOMUX_PIN_P0_0; + pinmux_digitalmic_clk[0].function = HAL_IOMUX_FUNC_PDM0_CK; + } else if (digmic_ck_pin == HAL_IOMUX_PIN_P0_4) { + pinmux_digitalmic_clk[0].pin = HAL_IOMUX_PIN_P0_4; + pinmux_digitalmic_clk[0].function = HAL_IOMUX_FUNC_PDM1_CK; + } else if (digmic_ck_pin == HAL_IOMUX_PIN_P3_3) { + pinmux_digitalmic_clk[0].pin = HAL_IOMUX_PIN_P3_3; + pinmux_digitalmic_clk[0].function = HAL_IOMUX_FUNC_PDM2_CK; + } + + if (digmic_d0_pin == HAL_IOMUX_PIN_P0_1) { + pinmux_digitalmic0[0].pin = HAL_IOMUX_PIN_P0_1; + } else if (digmic_d0_pin == HAL_IOMUX_PIN_P0_6) { + pinmux_digitalmic0[0].pin = HAL_IOMUX_PIN_P0_6; + } else if (digmic_d0_pin == HAL_IOMUX_PIN_P3_0) { + pinmux_digitalmic0[0].pin = HAL_IOMUX_PIN_P3_0; + } + + if (digmic_d1_pin == HAL_IOMUX_PIN_P0_2) { + pinmux_digitalmic1[0].pin = HAL_IOMUX_PIN_P0_2; + } else if (digmic_d1_pin == HAL_IOMUX_PIN_P0_5) { + pinmux_digitalmic1[0].pin = HAL_IOMUX_PIN_P0_5; + } else if (digmic_d1_pin == HAL_IOMUX_PIN_P3_1) { + pinmux_digitalmic1[0].pin = HAL_IOMUX_PIN_P3_1; + } + + if (digmic_d2_pin == HAL_IOMUX_PIN_P0_3) { + pinmux_digitalmic2[0].pin = HAL_IOMUX_PIN_P0_3; + } else if (digmic_d2_pin == HAL_IOMUX_PIN_P0_7) { + pinmux_digitalmic2[0].pin = HAL_IOMUX_PIN_P0_7; + } else if (digmic_d2_pin == HAL_IOMUX_PIN_P3_2) { + pinmux_digitalmic2[0].pin = HAL_IOMUX_PIN_P3_2; + } + + if ((map & 0xF) == 0) { + pinmux_digitalmic_clk[0].function = HAL_IOMUX_FUNC_GPIO; + } + hal_iomux_init(pinmux_digitalmic_clk, ARRAY_SIZE(pinmux_digitalmic_clk)); + if (map & (1 << 0)) { + hal_iomux_init(pinmux_digitalmic0, ARRAY_SIZE(pinmux_digitalmic0)); + } + if (map & (1 << 1)) { + hal_iomux_init(pinmux_digitalmic1, ARRAY_SIZE(pinmux_digitalmic1)); + } + if (map & (1 << 2)) { + hal_iomux_init(pinmux_digitalmic2, ARRAY_SIZE(pinmux_digitalmic2)); + } +} + +void hal_iomux_set_spi(void) +{ + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_spi_3wire[3] = { + {HAL_IOMUX_PIN_P0_5, HAL_IOMUX_FUNC_SPI_CLK, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P0_6, HAL_IOMUX_FUNC_SPI_CS0, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P0_7, HAL_IOMUX_FUNC_SPI_DIO, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#ifdef SPI_IOMUX_CS1_INDEX +#if (SPI_IOMUX_CS1_INDEX == 35) + {HAL_IOMUX_PIN_P3_5, HAL_IOMUX_FUNC_SPI_CS1, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P1_0, HAL_IOMUX_FUNC_SPI_CS1, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#endif +#ifdef SPI_IOMUX_CS2_INDEX +#if (SPI_IOMUX_CS2_INDEX == 37) + {HAL_IOMUX_PIN_P3_7, HAL_IOMUX_FUNC_SPI_CS2, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P1_1, HAL_IOMUX_FUNC_SPI_CS2, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#endif +#ifdef SPI_IOMUX_CS3_INDEX +#if (SPI_IOMUX_CS3_INDEX == 25) + {HAL_IOMUX_PIN_P2_5, HAL_IOMUX_FUNC_SPI_CS3, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P1_2, HAL_IOMUX_FUNC_SPI_CS3, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#endif + }; +#ifdef SPI_IOMUX_4WIRE + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_spi_4wire[1] = { + {HAL_IOMUX_PIN_P0_4, HAL_IOMUX_FUNC_SPI_DI0, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#ifdef SPI_IOMUX_DI1_INDEX + {HAL_IOMUX_PIN_P3_4, HAL_IOMUX_FUNC_SPI_DI1, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#ifdef SPI_IOMUX_DI2_INDEX + {HAL_IOMUX_PIN_P3_6, HAL_IOMUX_FUNC_SPI_DI2, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#ifdef SPI_IOMUX_DI3_INDEX + {HAL_IOMUX_PIN_P2_4, HAL_IOMUX_FUNC_SPI_DI3, SPI_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif + }; +#endif + + hal_iomux_init(pinmux_spi_3wire, ARRAY_SIZE(pinmux_spi_3wire)); +#ifdef SPI_IOMUX_4WIRE + hal_iomux_init(pinmux_spi_4wire, ARRAY_SIZE(pinmux_spi_4wire)); +#endif +} + +void hal_iomux_set_spilcd(void) +{ + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_spilcd_3wire[] = { +#if (SPILCD_IOMUX_INDEX == 10) + {HAL_IOMUX_PIN_P1_0, HAL_IOMUX_FUNC_SPILCD_CLK, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P1_1, HAL_IOMUX_FUNC_SPILCD_CS0, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P1_5, HAL_IOMUX_FUNC_SPILCD_DIO, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (SPILCD_IOMUX_INDEX == 35) + {HAL_IOMUX_PIN_P3_7, HAL_IOMUX_FUNC_SPILCD_CLK, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P3_6, HAL_IOMUX_FUNC_SPILCD_CS0, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P3_5, HAL_IOMUX_FUNC_SPILCD_DIO, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P0_3, HAL_IOMUX_FUNC_SPILCD_CLK, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P0_2, HAL_IOMUX_FUNC_SPILCD_CS0, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, + {HAL_IOMUX_PIN_P0_1, HAL_IOMUX_FUNC_SPILCD_DIO, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#ifdef SPILCD_IOMUX_CS1_INDEX +#if (SPILCD_IOMUX_CS1_INDEX == 12) + {HAL_IOMUX_PIN_P1_2, HAL_IOMUX_FUNC_SPILCD_CS1, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (SPILCD_IOMUX_CS1_INDEX == 27) + {HAL_IOMUX_PIN_P2_7, HAL_IOMUX_FUNC_SPILCD_CS1, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (SPILCD_IOMUX_CS1_INDEX == 30) + {HAL_IOMUX_PIN_P3_0, HAL_IOMUX_FUNC_SPILCD_CS1, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P0_5, HAL_IOMUX_FUNC_SPILCD_CS1, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#endif +#ifdef SPILCD_IOMUX_CS2_INDEX +#if (SPILCD_IOMUX_CS2_INDEX == 31) + {HAL_IOMUX_PIN_P3_1, HAL_IOMUX_FUNC_SPILCD_CS2, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P0_6, HAL_IOMUX_FUNC_SPILCD_CS2, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#endif +#ifdef SPILCD_IOMUX_CS3_INDEX +#if (SPILCD_IOMUX_CS3_INDEX == 31) + {HAL_IOMUX_PIN_P3_1, HAL_IOMUX_FUNC_SPILCD_CS3, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (SPILCD_IOMUX_CS3_INDEX == 32) + {HAL_IOMUX_PIN_P3_2, HAL_IOMUX_FUNC_SPILCD_CS3, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P0_7, HAL_IOMUX_FUNC_SPILCD_CS3, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#endif + }; +#ifdef SPILCD_IOMUX_4WIRE + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_spilcd_4wire[] = { +#ifdef SPILCD_IOMUX_DI0_INDEX +#if (SPILCD_IOMUX_DI0_INDEX == 14) + {HAL_IOMUX_PIN_P1_4, HAL_IOMUX_FUNC_SPILCD_DI0, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (SPILCD_IOMUX_DI0_INDEX == 34) + {HAL_IOMUX_PIN_P3_4, HAL_IOMUX_FUNC_SPILCD_DI0, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P0_0, HAL_IOMUX_FUNC_SPILCD_DI0, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#endif +#ifdef SPILCD_IOMUX_DI1_INDEX + {HAL_IOMUX_PIN_P2_6, HAL_IOMUX_FUNC_SPILCD_DI1, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#ifdef SPILCD_IOMUX_DI2_INDEX + {HAL_IOMUX_PIN_P3_0, HAL_IOMUX_FUNC_SPILCD_DI2, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif +#ifdef SPILCD_IOMUX_DI3_INDEX + {HAL_IOMUX_PIN_P3_3, HAL_IOMUX_FUNC_SPILCD_DI3, SPILCD_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif + }; +#endif + + hal_iomux_init(pinmux_spilcd_3wire, ARRAY_SIZE(pinmux_spilcd_3wire)); +#ifdef SPILCD_IOMUX_4WIRE + hal_iomux_init(pinmux_spilcd_4wire, ARRAY_SIZE(pinmux_spilcd_4wire)); +#endif +} + +void hal_iomux_set_i2c0(void) +{ +#if (I2C0_IOMUX_INDEX == 16) + hal_iomux_set_analog_i2c(); + // IOMUX_GPIO_I2C_MODE should be kept in disabled state + iomux->REG_050 &= ~IOMUX_I2C0_M_SEL_GPIO; +#else + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_i2c[] = { + {HAL_IOMUX_PIN_P2_0, HAL_IOMUX_FUNC_I2C_M0_SCL, I2C0_VOLTAGE_SEL, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_P2_1, HAL_IOMUX_FUNC_I2C_M0_SDA, I2C0_VOLTAGE_SEL, HAL_IOMUX_PIN_PULLUP_ENABLE}, + }; + + hal_iomux_init(pinmux_i2c, ARRAY_SIZE(pinmux_i2c)); +#endif +} + +void hal_iomux_set_i2c1(void) +{ + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_i2c[] = { +#if (I2C1_IOMUX_INDEX == 22) + {HAL_IOMUX_PIN_P2_2, HAL_IOMUX_FUNC_I2C_M1_SCL, I2C1_VOLTAGE_SEL, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_P2_3, HAL_IOMUX_FUNC_I2C_M1_SDA, I2C1_VOLTAGE_SEL, HAL_IOMUX_PIN_PULLUP_ENABLE}, +#else + {HAL_IOMUX_PIN_P0_2, HAL_IOMUX_FUNC_I2C_M1_SCL, I2C1_VOLTAGE_SEL, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_P0_3, HAL_IOMUX_FUNC_I2C_M1_SDA, I2C1_VOLTAGE_SEL, HAL_IOMUX_PIN_PULLUP_ENABLE}, +#endif + }; + + hal_iomux_init(pinmux_i2c, ARRAY_SIZE(pinmux_i2c)); + iomux->REG_050 |= IOMUX_I2C1_M_SEL_GPIO; +} + +void hal_iomux_set_clock_out(void) +{ + static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_clkout[] = { +#if (CLKOUT_IOMUX_INDEX == 13) + {HAL_IOMUX_PIN_P1_3, HAL_IOMUX_FUNC_CLK_OUT, CLKOUT_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (CLKOUT_IOMUX_INDEX == 15) + {HAL_IOMUX_PIN_P1_5, HAL_IOMUX_FUNC_CLK_OUT, CLKOUT_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (CLKOUT_IOMUX_INDEX == 21) + {HAL_IOMUX_PIN_P2_1, HAL_IOMUX_FUNC_CLK_OUT, CLKOUT_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (CLKOUT_IOMUX_INDEX == 23) + {HAL_IOMUX_PIN_P2_3, HAL_IOMUX_FUNC_CLK_OUT, CLKOUT_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (CLKOUT_IOMUX_INDEX == 27) + {HAL_IOMUX_PIN_P2_7, HAL_IOMUX_FUNC_CLK_OUT, CLKOUT_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#elif (CLKOUT_IOMUX_INDEX == 34) + {HAL_IOMUX_PIN_P3_4, HAL_IOMUX_FUNC_CLK_OUT, CLKOUT_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#else + {HAL_IOMUX_PIN_P0_4, HAL_IOMUX_FUNC_CLK_OUT, CLKOUT_VOLTAGE_SEL, HAL_IOMUX_PIN_NOPULL}, +#endif + }; + + hal_iomux_init(pinmux_clkout, ARRAY_SIZE(pinmux_clkout)); +} + +void hal_iomux_set_mcu_clock_out(void) +{ +} + +void hal_iomux_set_bt_clock_out(void) +{ +} + +void hal_iomux_set_bt_tport(void) +{ + // P0_0 ~ P0_3, + iomux->REG_004 = (iomux->REG_004 & ~(IOMUX_GPIO_P00_SEL_MASK | IOMUX_GPIO_P01_SEL_MASK | IOMUX_GPIO_P02_SEL_MASK | IOMUX_GPIO_P03_SEL_MASK)) | + IOMUX_GPIO_P00_SEL(0xA) | IOMUX_GPIO_P01_SEL(0xA) | IOMUX_GPIO_P02_SEL(0xA) |IOMUX_GPIO_P03_SEL(0xA); +#ifdef TPORTS_KEY_COEXIST + //P1_1 ~ P1_2, + iomux->REG_008 = (iomux->REG_008 & ~(IOMUX_GPIO_P11_SEL_MASK | IOMUX_GPIO_P12_SEL_MASK)) | + IOMUX_GPIO_P11_SEL(0xA) | IOMUX_GPIO_P12_SEL(0xA); +#else + //P1_0 ~ P1_3, + iomux->REG_008 = (iomux->REG_008 & ~(IOMUX_GPIO_P10_SEL_MASK | IOMUX_GPIO_P11_SEL_MASK | IOMUX_GPIO_P12_SEL_MASK | IOMUX_GPIO_P13_SEL_MASK )) | + IOMUX_GPIO_P10_SEL(0xA) | IOMUX_GPIO_P11_SEL(0xA) | IOMUX_GPIO_P12_SEL(0xA) | IOMUX_GPIO_P13_SEL(0xA); +#endif + // ANA TEST DIR + iomux->REG_014 = 0x0f0f; + // ANA TEST SEL + iomux->REG_018 = IOMUX_ANA_TEST_SEL(5); +} + +void hal_iomux_set_bt_rf_sw(int rx_on, int tx_on) +{ + uint32_t val; + uint32_t dir; + + //iomux->REG_004 = (iomux->REG_004 & ~(IOMUX_GPIO_P00_SEL_MASK | IOMUX_GPIO_P01_SEL_MASK)) | + // IOMUX_GPIO_P00_SEL(6) | IOMUX_GPIO_P01_SEL(6); + + val = iomux->REG_004; + dir = 0; + if (rx_on) { + val = SET_BITFIELD(val, IOMUX_GPIO_P00_SEL, 0xA); + dir = (1 << HAL_IOMUX_PIN_P0_0); + } + if (tx_on) { + val = SET_BITFIELD(val, IOMUX_GPIO_P01_SEL, 0xA); + dir = (1 << HAL_IOMUX_PIN_P0_1); + } + iomux->REG_004 = val; + // ANA TEST DIR + iomux->REG_014 |= dir; + // ANA TEST SEL + iomux->REG_018 = IOMUX_ANA_TEST_SEL(5); +} + +int WEAK hal_pwrkey_set_irq(enum HAL_PWRKEY_IRQ_T type) +{ + return 0; +} + +bool WEAK hal_pwrkey_pressed(void) +{ + return 0; +} + +bool hal_pwrkey_startup_pressed(void) +{ + return hal_pwrkey_pressed(); +} + +enum HAL_PWRKEY_IRQ_T WEAK hal_pwrkey_get_irq_state(void) +{ + enum HAL_PWRKEY_IRQ_T state = HAL_PWRKEY_IRQ_NONE; + + return state; +} + +const struct HAL_IOMUX_PIN_FUNCTION_MAP iomux_tport[] = { +/* {HAL_IOMUX_PIN_P1_1, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE},*/ + {HAL_IOMUX_PIN_P1_5, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}, +}; + +int hal_iomux_tportopen(void) +{ + int i; + + for (i=0;iREG_064 = SET_BITFIELD(iomux->REG_064, IOMUX_CFG_CODEC_TRIG_SEL, pin); + if (polarity) { + iomux->REG_064 &= ~IOMUX_CFG_CODEC_TRIG_POL; + } else { + iomux->REG_064 |= IOMUX_CFG_CODEC_TRIG_POL; + } +} + diff --git a/platform/hal/best2300p/hal_iomux_best2300p.h b/platform/hal/best2300p/hal_iomux_best2300p.h new file mode 100644 index 0000000..03383eb --- /dev/null +++ b/platform/hal/best2300p/hal_iomux_best2300p.h @@ -0,0 +1,234 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_IOMUX_BEST2300P_H__ +#define __HAL_IOMUX_BEST2300P_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +#ifndef ROM_BUILD +#define PMU_HAS_LED_PIN +#endif + +enum HAL_IOMUX_PIN_T { + HAL_IOMUX_PIN_P0_0 = 0, + HAL_IOMUX_PIN_P0_1, + HAL_IOMUX_PIN_P0_2, + HAL_IOMUX_PIN_P0_3, + HAL_IOMUX_PIN_P0_4, + HAL_IOMUX_PIN_P0_5, + HAL_IOMUX_PIN_P0_6, + HAL_IOMUX_PIN_P0_7, + + HAL_IOMUX_PIN_P1_0, + HAL_IOMUX_PIN_P1_1, + HAL_IOMUX_PIN_P1_2, + HAL_IOMUX_PIN_P1_3, + HAL_IOMUX_PIN_P1_4, + HAL_IOMUX_PIN_P1_5, + HAL_IOMUX_PIN_P1_6, + HAL_IOMUX_PIN_P1_7, + + HAL_IOMUX_PIN_P2_0, + HAL_IOMUX_PIN_P2_1, + HAL_IOMUX_PIN_P2_2, + HAL_IOMUX_PIN_P2_3, + HAL_IOMUX_PIN_P2_4, + HAL_IOMUX_PIN_P2_5, + HAL_IOMUX_PIN_P2_6, + HAL_IOMUX_PIN_P2_7, + + HAL_IOMUX_PIN_P3_0, + HAL_IOMUX_PIN_P3_1, + HAL_IOMUX_PIN_P3_2, + HAL_IOMUX_PIN_P3_3, + HAL_IOMUX_PIN_P3_4, + HAL_IOMUX_PIN_P3_5, + HAL_IOMUX_PIN_P3_6, + HAL_IOMUX_PIN_P3_7, + + HAL_IOMUX_PIN_NUM, + + HAL_IOMUX_PIN_LED1 = HAL_IOMUX_PIN_NUM, + HAL_IOMUX_PIN_LED2, + + HAL_IOMUX_PIN_LED_NUM, +}; + +enum HAL_GPIO_PIN_T { + HAL_GPIO_PIN_P0_0 = HAL_IOMUX_PIN_P0_0, + HAL_GPIO_PIN_P0_1 = HAL_IOMUX_PIN_P0_1, + HAL_GPIO_PIN_P0_2 = HAL_IOMUX_PIN_P0_2, + HAL_GPIO_PIN_P0_3 = HAL_IOMUX_PIN_P0_3, + HAL_GPIO_PIN_P0_4 = HAL_IOMUX_PIN_P0_4, + HAL_GPIO_PIN_P0_5 = HAL_IOMUX_PIN_P0_5, + HAL_GPIO_PIN_P0_6 = HAL_IOMUX_PIN_P0_6, + HAL_GPIO_PIN_P0_7 = HAL_IOMUX_PIN_P0_7, + + HAL_GPIO_PIN_P1_0 = HAL_IOMUX_PIN_P1_0, + HAL_GPIO_PIN_P1_1 = HAL_IOMUX_PIN_P1_1, + HAL_GPIO_PIN_P1_2 = HAL_IOMUX_PIN_P1_2, + HAL_GPIO_PIN_P1_3 = HAL_IOMUX_PIN_P1_3, + HAL_GPIO_PIN_P1_4 = HAL_IOMUX_PIN_P1_4, + HAL_GPIO_PIN_P1_5 = HAL_IOMUX_PIN_P1_5, + HAL_GPIO_PIN_P1_6 = HAL_IOMUX_PIN_P1_6, + HAL_GPIO_PIN_P1_7 = HAL_IOMUX_PIN_P1_7, + + HAL_GPIO_PIN_P2_0 = HAL_IOMUX_PIN_P2_0, + HAL_GPIO_PIN_P2_1 = HAL_IOMUX_PIN_P2_1, + HAL_GPIO_PIN_P2_2 = HAL_IOMUX_PIN_P2_2, + HAL_GPIO_PIN_P2_3 = HAL_IOMUX_PIN_P2_3, + HAL_GPIO_PIN_P2_4 = HAL_IOMUX_PIN_P2_4, + HAL_GPIO_PIN_P2_5 = HAL_IOMUX_PIN_P2_5, + HAL_GPIO_PIN_P2_6 = HAL_IOMUX_PIN_P2_6, + HAL_GPIO_PIN_P2_7 = HAL_IOMUX_PIN_P2_7, + + HAL_GPIO_PIN_P3_0 = HAL_IOMUX_PIN_P3_0, + HAL_GPIO_PIN_P3_1 = HAL_IOMUX_PIN_P3_1, + HAL_GPIO_PIN_P3_2 = HAL_IOMUX_PIN_P3_2, + HAL_GPIO_PIN_P3_3 = HAL_IOMUX_PIN_P3_3, + HAL_GPIO_PIN_P3_4 = HAL_IOMUX_PIN_P3_4, + HAL_GPIO_PIN_P3_5 = HAL_IOMUX_PIN_P3_5, + HAL_GPIO_PIN_P3_6 = HAL_IOMUX_PIN_P3_6, + HAL_GPIO_PIN_P3_7 = HAL_IOMUX_PIN_P3_7, + + HAL_GPIO_PIN_NUM = HAL_IOMUX_PIN_NUM, + + HAL_GPIO_PIN_LED1 = HAL_IOMUX_PIN_LED1, + HAL_GPIO_PIN_LED2 = HAL_IOMUX_PIN_LED2, + + HAL_GPIO_PIN_LED_NUM = HAL_IOMUX_PIN_LED_NUM, +}; + +enum HAL_IOMUX_FUNCTION_T { + HAL_IOMUX_FUNC_NONE = 0, + HAL_IOMUX_FUNC_GPIO, + HAL_IOMUX_FUNC_AS_GPIO = HAL_IOMUX_FUNC_GPIO, + HAL_IOMUX_FUNC_BT_UART_CTS, + HAL_IOMUX_FUNC_BT_UART_RTS, + HAL_IOMUX_FUNC_BT_UART_RX, + HAL_IOMUX_FUNC_BT_UART_TX, + HAL_IOMUX_FUNC_CLK_32K_IN, + HAL_IOMUX_FUNC_CLK_REQ_IN, + HAL_IOMUX_FUNC_CLK_REQ_OUT, + HAL_IOMUX_FUNC_CLK_OUT, + HAL_IOMUX_FUNC_I2C_M0_SCL, + HAL_IOMUX_FUNC_I2C_M0_SDA, + HAL_IOMUX_FUNC_I2C_M1_SCL, + HAL_IOMUX_FUNC_I2C_M1_SDA, + HAL_IOMUX_FUNC_I2C_SCL, + HAL_IOMUX_FUNC_I2C_SDA, + HAL_IOMUX_FUNC_I2S0_MCLK, + HAL_IOMUX_FUNC_I2S0_SCK, + HAL_IOMUX_FUNC_I2S0_SDI0, + HAL_IOMUX_FUNC_I2S0_SDO, + HAL_IOMUX_FUNC_I2S0_WS, + HAL_IOMUX_FUNC_I2S1_MCLK, + HAL_IOMUX_FUNC_I2S1_SCK, + HAL_IOMUX_FUNC_I2S1_SDI0, + HAL_IOMUX_FUNC_I2S1_SDO, + HAL_IOMUX_FUNC_I2S1_WS, + HAL_IOMUX_FUNC_PCM_CLK, + HAL_IOMUX_FUNC_PCM_DI, + HAL_IOMUX_FUNC_PCM_DO, + HAL_IOMUX_FUNC_PCM_FSYNC, + HAL_IOMUX_FUNC_PDM0_CK, + HAL_IOMUX_FUNC_PDM0_D, + HAL_IOMUX_FUNC_PDM1_CK, + HAL_IOMUX_FUNC_PDM1_D, + HAL_IOMUX_FUNC_PDM2_CK, + HAL_IOMUX_FUNC_PDM2_D, + HAL_IOMUX_FUNC_PWM0, + HAL_IOMUX_FUNC_PWM1, + HAL_IOMUX_FUNC_PWM2, + HAL_IOMUX_FUNC_PWM3, + HAL_IOMUX_FUNC_SDMMC_CLK, + HAL_IOMUX_FUNC_SDMMC_CMD, + HAL_IOMUX_FUNC_SDMMC_DATA0, + HAL_IOMUX_FUNC_SDMMC_DATA1, + HAL_IOMUX_FUNC_SDMMC_DATA2, + HAL_IOMUX_FUNC_SDMMC_DATA3, + HAL_IOMUX_FUNC_SDMMC_DATA4, + HAL_IOMUX_FUNC_SDMMC_DATA5, + HAL_IOMUX_FUNC_SDMMC_DATA6, + HAL_IOMUX_FUNC_SDMMC_DATA7, + HAL_IOMUX_FUNC_SPDIF0_DI, + HAL_IOMUX_FUNC_SPDIF0_DO, + HAL_IOMUX_FUNC_SPI_CLK, + HAL_IOMUX_FUNC_SPI_CS0, + HAL_IOMUX_FUNC_SPI_CS1, + HAL_IOMUX_FUNC_SPI_CS2, + HAL_IOMUX_FUNC_SPI_CS3, + HAL_IOMUX_FUNC_SPI_DCN, + HAL_IOMUX_FUNC_SPI_DI0, + HAL_IOMUX_FUNC_SPI_DI1, + HAL_IOMUX_FUNC_SPI_DI2, + HAL_IOMUX_FUNC_SPI_DI3, + HAL_IOMUX_FUNC_SPI_DIO, + HAL_IOMUX_FUNC_SPILCD_CLK, + HAL_IOMUX_FUNC_SPILCD_CS0, + HAL_IOMUX_FUNC_SPILCD_CS1, + HAL_IOMUX_FUNC_SPILCD_CS2, + HAL_IOMUX_FUNC_SPILCD_CS3, + HAL_IOMUX_FUNC_SPILCD_DCN, + HAL_IOMUX_FUNC_SPILCD_DI0, + HAL_IOMUX_FUNC_SPILCD_DI1, + HAL_IOMUX_FUNC_SPILCD_DI2, + HAL_IOMUX_FUNC_SPILCD_DI3, + HAL_IOMUX_FUNC_SPILCD_DIO, + HAL_IOMUX_FUNC_UART0_RX, + HAL_IOMUX_FUNC_UART0_TX, + HAL_IOMUX_FUNC_UART1_CTS, + HAL_IOMUX_FUNC_UART1_RTS, + HAL_IOMUX_FUNC_UART1_RX, + HAL_IOMUX_FUNC_UART1_TX, + HAL_IOMUX_FUNC_UART2_RX, + HAL_IOMUX_FUNC_UART2_TX, + + HAL_IOMUX_FUNC_END +}; + +enum HAL_IOMUX_ISPI_ACCESS_T { + HAL_IOMUX_ISPI_BT_RF = (1 << 0), + HAL_IOMUX_ISPI_BT_PMU = (1 << 1), + HAL_IOMUX_ISPI_BT_ANA = (1 << 2), + HAL_IOMUX_ISPI_MCU_RF = (1 << 3), + HAL_IOMUX_ISPI_MCU_PMU = (1 << 4), + HAL_IOMUX_ISPI_MCU_ANA = (1 << 5), +}; + +void hal_iomux_set_i2s_mclk(void); + +void hal_iomux_set_i2s1(void); + +void hal_iomux_set_mcu_clock_out(void); + +void hal_iomux_set_bt_clock_out(void); + +int hal_iomux_tportopen(void); + +int hal_iomux_tportclr(int port); + +int hal_iomux_tportset(int port); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/best2300p/hal_psc_best2300p.c b/platform/hal/best2300p/hal_psc_best2300p.c new file mode 100644 index 0000000..1a2d424 --- /dev/null +++ b/platform/hal/best2300p/hal_psc_best2300p.c @@ -0,0 +1,123 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include "cmsis.h" +#include "hal_timer.h" +#include "hal_location.h" +#include "hal_psc.h" +#include CHIP_SPECIFIC_HDR(reg_psc) + +#define PSC_WRITE_ENABLE 0xCAFE0000 + +static struct AONPSC_T * const psc = (struct AONPSC_T *)AON_PSC_BASE; + +void BOOT_TEXT_FLASH_LOC hal_psc_init(void) +{ + // Setup wakeup mask + psc->REG_080 = 0xFFFFFFFF; + psc->REG_084 = 0xFFFFFFFF; +} + +void SRAM_TEXT_LOC hal_psc_core_auto_power_down(void) +{ + psc->REG_018 = PSC_WRITE_ENABLE | 0; + psc->REG_000 = PSC_WRITE_ENABLE | PSC_AON_MCU_PG_AUTO_EN; + psc->REG_010 = PSC_WRITE_ENABLE | PSC_AON_MCU_POWERDN_START; +} + +void SRAM_TEXT_LOC hal_psc_mcu_auto_power_up(void) +{ + psc->REG_014 = PSC_WRITE_ENABLE | PSC_AON_MCU_POWERUP_START; +} + +void BOOT_TEXT_FLASH_LOC hal_psc_codec_enable(void) +{ + psc->REG_078 = PSC_WRITE_ENABLE | + PSC_AON_CODEC_PSW_EN_DR | + PSC_AON_CODEC_RESETN_ASSERT_DR | PSC_AON_CODEC_RESETN_ASSERT_REG | + PSC_AON_CODEC_ISO_EN_DR | PSC_AON_CODEC_ISO_EN_REG | + PSC_AON_CODEC_CLK_STOP_DR | PSC_AON_CODEC_CLK_STOP_REG; + hal_sys_timer_delay(MS_TO_TICKS(1)); + psc->REG_078 = PSC_WRITE_ENABLE | + PSC_AON_CODEC_PSW_EN_DR | + PSC_AON_CODEC_RESETN_ASSERT_DR | + PSC_AON_CODEC_ISO_EN_DR | PSC_AON_CODEC_ISO_EN_REG | + PSC_AON_CODEC_CLK_STOP_DR | PSC_AON_CODEC_CLK_STOP_REG; + psc->REG_078 = PSC_WRITE_ENABLE | + PSC_AON_CODEC_PSW_EN_DR | + PSC_AON_CODEC_RESETN_ASSERT_DR | + PSC_AON_CODEC_ISO_EN_DR | + PSC_AON_CODEC_CLK_STOP_DR | PSC_AON_CODEC_CLK_STOP_REG; + psc->REG_078 = PSC_WRITE_ENABLE | + PSC_AON_CODEC_PSW_EN_DR | + PSC_AON_CODEC_RESETN_ASSERT_DR | + PSC_AON_CODEC_ISO_EN_DR | + PSC_AON_CODEC_CLK_STOP_DR; +} + +void BOOT_TEXT_FLASH_LOC hal_psc_codec_disable(void) +{ + psc->REG_078 = PSC_WRITE_ENABLE | + PSC_AON_CODEC_PSW_EN_DR | PSC_AON_CODEC_PSW_EN_REG | + PSC_AON_CODEC_RESETN_ASSERT_DR | PSC_AON_CODEC_RESETN_ASSERT_REG | + PSC_AON_CODEC_ISO_EN_DR | PSC_AON_CODEC_ISO_EN_REG | + PSC_AON_CODEC_CLK_STOP_DR | PSC_AON_CODEC_CLK_STOP_REG; +} + +void BOOT_TEXT_FLASH_LOC hal_psc_bt_enable(void) +{ + psc->REG_038 = PSC_WRITE_ENABLE | + PSC_AON_BT_PSW_EN_DR | + PSC_AON_BT_RESETN_ASSERT_DR | PSC_AON_BT_RESETN_ASSERT_REG | + PSC_AON_BT_ISO_EN_DR | PSC_AON_BT_ISO_EN_REG | + PSC_AON_BT_CLK_STOP_DR | PSC_AON_BT_CLK_STOP_REG; + hal_sys_timer_delay(MS_TO_TICKS(1)); + psc->REG_038 = PSC_WRITE_ENABLE | + PSC_AON_BT_PSW_EN_DR | + PSC_AON_BT_RESETN_ASSERT_DR | + PSC_AON_BT_ISO_EN_DR | PSC_AON_BT_ISO_EN_REG | + PSC_AON_BT_CLK_STOP_DR | PSC_AON_BT_CLK_STOP_REG; + psc->REG_038 = PSC_WRITE_ENABLE | + PSC_AON_BT_PSW_EN_DR | + PSC_AON_BT_RESETN_ASSERT_DR | + PSC_AON_BT_ISO_EN_DR | + PSC_AON_BT_CLK_STOP_DR | PSC_AON_BT_CLK_STOP_REG; + psc->REG_038 = PSC_WRITE_ENABLE | + PSC_AON_BT_PSW_EN_DR | + PSC_AON_BT_RESETN_ASSERT_DR | + PSC_AON_BT_ISO_EN_DR | + PSC_AON_BT_CLK_STOP_DR; + +#ifdef JTAG_BT + psc->REG_064 |= PSC_AON_CODEC_RESERVED(1 << 3); + psc->REG_064 &= ~PSC_AON_CODEC_RESERVED(1 << 2); +#endif +} + +void BOOT_TEXT_FLASH_LOC hal_psc_bt_disable(void) +{ +#ifdef JTAG_BT + psc->REG_064 &= ~PSC_AON_CODEC_RESERVED(1 << 3); + psc->REG_064 |= PSC_AON_CODEC_RESERVED(1 << 2); +#endif + + psc->REG_038 = PSC_WRITE_ENABLE | + PSC_AON_BT_PSW_EN_DR | PSC_AON_BT_PSW_EN_REG | + PSC_AON_BT_RESETN_ASSERT_DR | PSC_AON_BT_RESETN_ASSERT_REG | + PSC_AON_BT_ISO_EN_DR | PSC_AON_BT_ISO_EN_REG | + PSC_AON_BT_CLK_STOP_DR | PSC_AON_BT_CLK_STOP_REG; +} + diff --git a/platform/hal/best2300p/hal_sensor_eng_best2300p.c b/platform/hal/best2300p/hal_sensor_eng_best2300p.c new file mode 100644 index 0000000..6972742 --- /dev/null +++ b/platform/hal/best2300p/hal_sensor_eng_best2300p.c @@ -0,0 +1,345 @@ +#include "plat_addr_map.h" +#include "cmsis_nvic.h" +#include "hal_dma.h" +#include "hal_sensor_eng.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include CHIP_SPECIFIC_HDR(reg_sensor_eng) +#include "reg_timer.h" +#include "string.h" +#ifdef RTOS +#include "cmsis_os.h" +#endif + +#define MAX_RX_FRAME_NUM (5) + +static struct SENSOR_ENG_T * const sensor_eng[] = { + (struct SENSOR_ENG_T *)SENSOR_ENG_BASE, +}; + +static struct DUAL_TIMER_T * const sensor_eng_timer = (struct DUAL_TIMER_T *)MCU_TIMER2_BASE; + +static struct HAL_DMA_DESC_T tx_dma_desc[1]; +static struct HAL_DMA_DESC_T rx_dma_desc[MAX_RX_FRAME_NUM]; + +static HAL_SENSOR_ENG_HANDLER_T sensor_eng_handler; + +static uint8_t dma_rx_chan; + +static uint8_t *dma_rx_buf; +static uint32_t dma_rx_len; +static uint32_t prev_rx_pos; + +void hal_sensor_process_rx_buffer(void) +{ + if (dma_rx_len == 0) { + return; + } + + uint8_t *dma_buf_active = (uint8_t *)hal_dma_get_cur_dst_addr(dma_rx_chan); + uint32_t result_len = 0; + uint8_t *curr_pos; + + curr_pos = dma_rx_buf + prev_rx_pos; + + //TRACE(2,"dma_buf_active:%08x curr_pos:%08x", dma_buf_active, curr_pos); + + if (dma_buf_active < curr_pos) { + result_len = dma_rx_buf + dma_rx_len - curr_pos; + //TRACE(2,"1:result_len:%08x, curr_pos:%08x", result_len, curr_pos); + //DUMP8("%02x ", curr_pos, result_len); + if (sensor_eng_handler){ + sensor_eng_handler(HAL_SENSOR_ENGINE_ID_0, HAL_SENSOR_ENGINE_DEVICE_I2C0, curr_pos, result_len); + } + curr_pos = dma_rx_buf; + } + + if (curr_pos < dma_buf_active) { + result_len = dma_buf_active - curr_pos; + //TRACE(2,"2:result_len:%08x, curr_pos:%08x", result_len, curr_pos); + //DUMP8("%02x ", curr_pos, result_len); + if (sensor_eng_handler){ + sensor_eng_handler(HAL_SENSOR_ENGINE_ID_0, HAL_SENSOR_ENGINE_DEVICE_I2C0, curr_pos, result_len); + } + curr_pos = dma_buf_active; + } + + prev_rx_pos = curr_pos - dma_rx_buf; +} + +static void hal_sensor_eng_irq_handler(void) +{ + //TRACE(2,"%s: irq=0x%08x", __func__, sensor_eng[0]->SENSOR_INTR_STS); + + sensor_eng[0]->SENSOR_INTR_CLR = SENSOR_INTR_CLEAR; + + hal_sensor_process_rx_buffer(); +} + +static void hal_sensor_eng_irq_enable(void) +{ + NVIC_SetVector(SENSOR_WKUP_IRQn, (uint32_t)hal_sensor_eng_irq_handler); + NVIC_SetPriority(SENSOR_WKUP_IRQn, IRQ_PRIORITY_HIGH); + NVIC_ClearPendingIRQ(SENSOR_WKUP_IRQn); + NVIC_EnableIRQ(SENSOR_WKUP_IRQn); +} + +static void hal_sensor_eng_irq_disable(void) +{ + NVIC_DisableIRQ(SENSOR_WKUP_IRQn); +} + +static void hal_sensor_eng_timer_stop(void) +{ + sensor_eng_timer->timer[0].Control = 0; + sensor_eng_timer->timer[0].IntClr = 1; +} + +static void hal_sensor_eng_timer_open(uint32_t ticks) +{ + if (ticks > 1) { + ticks -= 1; + } else { + ticks = 1; + } + sensor_eng_timer->timer[0].Load = ticks; + sensor_eng_timer->timer[0].Control = TIMER_CTRL_MODE_PERIODIC | TIMER_CTRL_INTEN | TIMER_CTRL_PRESCALE_DIV_1 | TIMER_CTRL_SIZE_32_BIT; +} + +static void hal_sensor_eng_timer_start(void) +{ + sensor_eng_timer->timer[0].Control |= TIMER_CTRL_EN; +} + +int hal_sensor_engine_open(const struct HAL_SENSOR_ENGINE_CFG_T *cfg) +{ + struct HAL_DMA_CH_CFG_T rx_dma_cfg; + enum HAL_DMA_RET_T dret; + uint32_t i; + uint32_t sx_sel; + + ASSERT(cfg->id == HAL_SENSOR_ENGINE_ID_0, "Bad sensor engine id: %d", cfg->id); + ASSERT(cfg->device == HAL_SENSOR_ENGINE_DEVICE_I2C0, "Bad sensor engine device: %d", cfg->device); + ASSERT(cfg->rx_burst_cnt <= MAX_RX_FRAME_NUM, "Bad rx_burst_cnt: %d", cfg->rx_burst_cnt); + ASSERT(cfg->tx_dma_cfg, "Bad tx_dma_cfg"); + + sensor_eng_handler = cfg->handler; + dma_rx_chan = cfg->rx_dma_cfg->ch; + dma_rx_buf = (uint8_t *)cfg->rx_dma_cfg->dst; + dma_rx_len = cfg->rx_burst_len * cfg->rx_burst_cnt; + prev_rx_pos = 0; + + dret = hal_dma_init_desc(&tx_dma_desc[0], cfg->tx_dma_cfg, &tx_dma_desc[0], 0); + ASSERT(dret == HAL_DMA_OK, "SensorEng: Failed to init tx desc 0"); + + dret = hal_gpdma_sg_start(&tx_dma_desc[0], cfg->tx_dma_cfg); + ASSERT(dret == HAL_DMA_OK, "SensorEng: Failed to start tx dma"); + + if (dma_rx_len) { + ASSERT(cfg->rx_dma_cfg, "Bad rx_dma_cfg"); + + rx_dma_cfg = *cfg->rx_dma_cfg; + for (i = 0; i < cfg->rx_burst_cnt; i++) { + rx_dma_cfg.dst = (uint32_t)(dma_rx_buf + cfg->rx_burst_len * i); + if (i + 1 == cfg->rx_burst_cnt) { + dret = hal_dma_init_desc(&rx_dma_desc[i], &rx_dma_cfg, &rx_dma_desc[0], 0); + } else { + dret = hal_dma_init_desc(&rx_dma_desc[i], &rx_dma_cfg, &rx_dma_desc[i + 1], 0); + } + ASSERT(dret == HAL_DMA_OK, "SensorEng: Failed to init rx desc %d", i); + } + hal_gpdma_sg_start(&rx_dma_desc[0], cfg->rx_dma_cfg); + ASSERT(dret == HAL_DMA_OK, "SensorEng: Failed to start rx dma"); + } + + hal_cmu_clock_enable(HAL_CMU_MOD_H_SENSOR_ENG); + hal_cmu_reset_clear(HAL_CMU_MOD_H_SENSOR_ENG); + hal_cmu_clock_enable(HAL_CMU_MOD_O_TIMER2); + hal_cmu_clock_enable(HAL_CMU_MOD_P_TIMER2); + hal_cmu_reset_clear(HAL_CMU_MOD_O_TIMER2); + hal_cmu_reset_clear(HAL_CMU_MOD_P_TIMER2); + + sensor_eng[0]->SLV0_CONFIG_REG = SLV_I2C_SPI_SEL(cfg->device) | SLV_SLV_DEV_ID(cfg->device_address) | SLV_ENABLE; + if (dma_rx_len) { + //RX LLI = 1 + sensor_eng[0]->GLOBAL_CFG1_REG = SET_BITFIELD(sensor_eng[0]->GLOBAL_CFG1_REG, NUM_OF_RX_LLI0, 1); + } + //TX LLI = 1 + sensor_eng[0]->GLOBAL_CFG3_REG = SET_BITFIELD(sensor_eng[0]->GLOBAL_CFG3_REG, NUM_OF_TX_LLI0, 1); + if (cfg->trigger_type == HAL_SENSOR_ENGINE_TRIGGER_GPIO) { + sensor_eng[0]->SLV0_INTR_MASK = ~(1 << cfg->trigger_gpio); + } + + if (cfg->data_to_vad) { + sx_sel = cfg->id; + } else { + sx_sel = GET_BITFIELD(sensor_eng[0]->GLOBAL_CFG0_REG, GBL_CODEC_SX_SEL); + } + sensor_eng[0]->GLOBAL_CFG0_REG = GBL_CODEC_SX_SEL(sx_sel) | GBL_SENSORHUB_EN | + (cfg->trigger_type == HAL_SENSOR_ENGINE_TRIGGER_GPIO ? GBL_TRIGGER_TYPE : 0); + + if (cfg->trigger_type == HAL_SENSOR_ENGINE_TRIGGER_TIMER) { + hal_sensor_eng_timer_open(US_TO_TICKS(cfg->period_us)); + hal_sensor_eng_timer_start(); + } + + hal_sensor_eng_irq_enable(); + + return 0; +} + +int hal_sensor_engine_close(enum HAL_SENSOR_ENGINE_ID_T id) +{ + uint32_t cnt; + + hal_sensor_eng_irq_disable(); + + hal_sensor_eng_timer_stop(); + + sensor_eng[0]->GLOBAL_CFG0_REG &= ~GBL_SENSORHUB_EN; + + // Wait until sensor engine becomes idle + cnt = 0; + while ((sensor_eng[0]->SENSOR_STATUS & SENSOR_ENG_FSM_MASK) && cnt < 10) { + osDelay(1); + cnt++; + } + if (sensor_eng[0]->SENSOR_STATUS & SENSOR_ENG_FSM_MASK) { + ASSERT(false, "%s: Sensor engine cannot become idle: 0x%08X", __func__, sensor_eng[0]->SENSOR_STATUS); + } + + sensor_eng[0]->SLV0_INTR_MASK = ~0UL; + + dma_rx_len = 0; + + hal_cmu_reset_set(HAL_CMU_MOD_P_TIMER2); + hal_cmu_reset_set(HAL_CMU_MOD_O_TIMER2); + hal_cmu_clock_disable(HAL_CMU_MOD_P_TIMER2); + hal_cmu_clock_disable(HAL_CMU_MOD_O_TIMER2); + hal_cmu_reset_set(HAL_CMU_MOD_H_SENSOR_ENG); + hal_cmu_clock_disable(HAL_CMU_MOD_H_SENSOR_ENG); + + return 0; +} + +#if 0 +#include "hal_i2c.h" + +#define READ_BUF_BURST_CNT 5 +#define TRIGGER_TIMER_US 500000 +#define LOCK_INTR_CNT 3 +#define TRIGGER_GPIO_PIN HAL_GPIO_PIN_P0_0 + +static void hal_sensor_eng_external_input_pin_irqhandler(enum HAL_GPIO_PIN_T pin) +{ + bool gpio_lvl = 0; + gpio_lvl = hal_gpio_pin_get_val(pin); + TRACE(2,"hal_sensor_eng_external_irqhandler io=%d val=%d", pin, gpio_lvl); +} + +static void sensor_timer_test_handler(enum HAL_I2C_ID_T id, const uint8_t *buf, uint32_t len) +{ + TRACE(7,"%s: id=%d len=%u %02X-%02X-%02X-%02x", __FUNCTION__, id, len, buf[0], buf[1], buf[2], buf[3]); +} + +static void sensor_gpio_test_handler(enum HAL_I2C_ID_T id, const uint8_t *buf, uint32_t len) +{ + TRACE(7,"%s: id=%d len=%u %02X-%02X-%02X-%02x", __FUNCTION__, id, len, buf[0], buf[1], buf[2], buf[3]); +} + +static int sensor_eng_test(enum HAL_SENSOR_ENGINE_TRIGGER_T trigger_type) +{ + static uint8_t write_buf[3]; + static uint8_t read_buf[READ_BUF_BURST_CNT][sizeof(write_buf) * 2]; + + int ret; + struct HAL_I2C_CONFIG_T cfg; + struct HAL_I2C_SENSOR_ENGINE_CONFIG_T se_cfg; + enum HAL_I2C_ID_T id; + uint32_t i; + + id = HAL_I2C_ID_0; + + for (i = 0; i < sizeof(write_buf); i++) { + write_buf[i] = i; + } + + memset(&cfg, 0, sizeof(cfg)); + cfg.mode = HAL_I2C_API_MODE_SENSOR_ENGINE; + cfg.as_master = 1; + cfg.use_dma = 1; + cfg.use_sync = 1; + cfg.speed = 100000; + ret = hal_i2c_open(id, &cfg); + if (ret) { + TRACE(2,"%s: i2c open failed %d", __func__, ret); + return ret; + } + + memset(&se_cfg, 0, sizeof(se_cfg)); + se_cfg.id = HAL_SENSOR_ENGINE_ID_0; + se_cfg.trigger_type = trigger_type; + if (trigger_type == HAL_SENSOR_ENGINE_TRIGGER_TIMER) { + se_cfg.period_us = TRIGGER_TIMER_US; + se_cfg.handler = sensor_timer_test_handler; + } else { + se_cfg.trigger_gpio = TRIGGER_GPIO_PIN; + se_cfg.handler = sensor_gpio_test_handler; + } + se_cfg.target_addr = 0x17; + se_cfg.write_buf = &write_buf[0]; + se_cfg.write_txn_len = 1; + se_cfg.read_buf = &read_buf[0][0]; + se_cfg.read_txn_len = 2; + se_cfg.txn_cnt = sizeof(write_buf); + se_cfg.read_burst_cnt = READ_BUF_BURST_CNT; + + hal_i2c_sensor_engine_start(id, &se_cfg); + + uint32_t lock = int_lock(); + while (1) { + hal_sys_timer_delay(US_TO_TICKS(TRIGGER_TIMER_US) * LOCK_INTR_CNT); + TRACE_IMM(2,"%s: delay %u ms", __func__, (TRIGGER_TIMER_US / 1000 * LOCK_INTR_CNT)); + hal_sensor_process_rx_buffer(); + } + int_unlock(lock); + + return 0; +} + +int hal_sensor_eng_periodic_timer_test(void) +{ + sensor_eng_test(HAL_SENSOR_ENGINE_TRIGGER_TIMER); + return 0; +} + +int hal_sensor_eng_external_input_test(void) +{ + static const struct HAL_IOMUX_PIN_FUNCTION_MAP ext_pin[] = { + {TRIGGER_GPIO_PIN, HAL_IOMUX_FUNC_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}, + }; + struct HAL_GPIO_IRQ_CFG_T gpiocfg; + + sensor_eng_test(HAL_SENSOR_ENGINE_TRIGGER_GPIO); + + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)ext_pin, sizeof(ext_pin)/sizeof(struct HAL_IOMUX_PIN_FUNCTION_MAP)); + hal_gpio_pin_set_dir(TRIGGER_GPIO_PIN, HAL_GPIO_DIR_IN, 1); + + gpiocfg.irq_enable = true; + gpiocfg.irq_debounce = false; + gpiocfg.irq_polarity = HAL_GPIO_IRQ_POLARITY_HIGH_RISING; + gpiocfg.irq_handler = hal_sensor_eng_external_input_pin_irqhandler; + gpiocfg.irq_type = HAL_GPIO_IRQ_TYPE_EDGE_SENSITIVE; + + hal_gpio_setup_irq(TRIGGER_GPIO_PIN, &gpiocfg); + + TRACE(5,"SLV0:%08x CFG1:0x%08x CFG3:0x%08x CFG0:0x%08x INTR_MASK:0x%08x", + sensor_eng[0]->SLV0_CONFIG_REG, + sensor_eng[0]->GLOBAL_CFG1_REG, + sensor_eng[0]->GLOBAL_CFG3_REG, + sensor_eng[0]->GLOBAL_CFG0_REG, + sensor_eng[0]->SLV0_INTR_MASK); + return 0; +} +#endif + diff --git a/platform/hal/best2300p/plat_addr_map_best2300p.h b/platform/hal/best2300p/plat_addr_map_best2300p.h new file mode 100644 index 0000000..ad22421 --- /dev/null +++ b/platform/hal/best2300p/plat_addr_map_best2300p.h @@ -0,0 +1,175 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __PLAT_ADDR_MAP_BEST2300P_H__ +#define __PLAT_ADDR_MAP_BEST2300P_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ROM_BASE 0x00000000 + +#ifndef ROM_SIZE +#define ROM_SIZE 0x0000C000 +#endif + +#define RAMRET_BASE 0x200D8000 +#define RAMXRET_BASE 0x002D8000 + +#ifndef RAMRET_SIZE +#define RAMRET_SIZE 0x00020000 +#endif + +#define RAM0_BASE 0x20000000 +#define RAMX0_BASE 0x00200000 +#define RAM1_BASE 0x20020000 +#define RAMX1_BASE 0x00220000 +#define RAM2_BASE 0x20040000 +#define RAMX2_BASE 0x00240000 +#define RAM3_BASE 0x20060000 +#define RAMX3_BASE 0x00260000 +#define RAM4_BASE 0x20080000 +#define RAMX4_BASE 0x00280000 +#define RAM5_BASE 0x200A0000 +#define RAMX5_BASE 0x002A0000 +#define RAM6_BASE 0x200C0000 +#define RAMX6_BASE 0x002C0000 +#define RAM_BASE RAM0_BASE +#define RAMX_BASE RAMX0_BASE + +#ifdef CHIP_HAS_CP +#define RAMCP_TOP (RAMRET_BASE + RAMRET_SIZE - 0x20) + +#ifndef RAMCP_SIZE +#define RAMCP_SIZE (RAMRET_SIZE - 0x20) +#endif +#define RAMCP_BASE (RAMCP_TOP - RAMCP_SIZE) + +#ifndef RAMCPX_SIZE +#define RAMCPX_SIZE (RAMXRET_BASE - RAMX6_BASE) +#endif +#ifndef RAMCPX_BASE +#define RAMCPX_BASE (RAM_TO_RAMX(RAMCP_BASE) - RAMCPX_SIZE) +#endif +#endif + +#ifndef RAM_SIZE +#ifdef CHIP_HAS_CP +#define RAM_SIZE (RAMCPX_BASE - RAMX_BASE) // 0X000C0000 +#else +#ifdef LARGE_RAM +#define RAM_SIZE (RAMRET_BASE + RAMRET_SIZE - RAM_BASE) // 0x000F8000 +#else +#define RAM_SIZE (RAMRET_BASE - RAM_BASE) // 0x000D8000 +#endif +#endif /* !CHIP_HAS_CP */ +#endif /* !RAM_SIZE */ + +#if defined(ROM_BUILD) && defined(CORE_SLEEP_POWER_DOWN) +#undef RAM_BASE +#undef RAMX_BASE +#undef RAM_SIZE +#define RAM_BASE RAMRET_BASE +#define RAMX_BASE RAMXRET_BASE +#define RAM_SIZE RAMRET_SIZE +#endif + +#define FLASH_BASE 0x3C000000 +#define FLASH_NC_BASE 0x38000000 +#define FLASHX_BASE 0x0C000000 +#define FLASHX_NC_BASE 0x08000000 + +#define ICACHE_CTRL_BASE 0x07FFE000 +#define ICACHECP_CTRL_BASE 0x07FFA000 +/* No data cache */ + +#define CMU_BASE 0x40000000 +#define MCU_WDT_BASE 0x40001000 +#define MCU_TIMER0_BASE 0x40002000 +#define MCU_TIMER1_BASE 0x40003000 +#define MCU_TIMER2_BASE 0x40004000 +#define I2C0_BASE 0x40005000 +#define I2C1_BASE 0x40006000 +#define SPI_BASE 0x40007000 +#define SPILCD_BASE 0x40008000 +#define ISPI_BASE 0x40009000 +#define SPIPHY_BASE 0x4000A000 +#define UART0_BASE 0x4000B000 +#define UART1_BASE 0x4000C000 +#define UART2_BASE 0x4000D000 +#define BTPCM_BASE 0x4000E000 +#define I2S0_BASE 0x4000F000 +#define SPDIF0_BASE 0x40010000 +#define I2S1_BASE 0x40011000 +#define SEC_ENG_BASE 0x40020000 + +#define AON_CMU_BASE 0x40080000 +#define AON_GPIO_BASE 0x40081000 +#define AON_WDT_BASE 0x40082000 +#define AON_PWM_BASE 0x40083000 +#define AON_TIMER_BASE 0x40084000 +#define AON_PSC_BASE 0x40085000 +#define AON_IOMUX_BASE 0x40086000 + +#define SDMMC_BASE 0x40110000 +#define AUDMA_BASE 0x40120000 +#define GPDMA_BASE 0x40130000 +#define FLASH_CTRL_BASE 0x40140000 +#define BTDUMP_BASE 0x40150000 +#define I2C_SLAVE_BASE 0x40160000 +#define SENSOR_ENG_BASE 0x40170000 +#define USB_BASE 0x40180000 +#define SEDMA_BASE 0x401D0000 + +#define CODEC_BASE 0x40300000 + +#define BT_SUBSYS_BASE 0xA0000000 +#define BT_RAM_BASE 0xC0000000 +#define BT_RAM_SIZE 0x00008000 +#define BT_EXCH_MEM_BASE 0xD0210000 +#define BT_EXCH_MEM_SIZE 0x00008000 +#define BT_UART_BASE 0xD0300000 +#define BT_CMU_BASE 0xD0330000 + +#define IOMUX_BASE AON_IOMUX_BASE +#define GPIO_BASE AON_GPIO_BASE +#define PWM_BASE AON_PWM_BASE +#ifdef CORE_SLEEP_POWER_DOWN +#define TIMER0_BASE AON_TIMER_BASE +#else +#define TIMER0_BASE MCU_TIMER0_BASE +#endif +#define TIMER1_BASE MCU_TIMER1_BASE +#define WDT_BASE AON_WDT_BASE + +/* For linker scripts */ + +#define VECTOR_SECTION_SIZE 320 +#define REBOOT_PARAM_SECTION_SIZE 64 +#define ROM_BUILD_INFO_SECTION_SIZE 40 +#define ROM_EXPORT_FN_SECTION_SIZE 128 +#define BT_INTESYS_MEM_OFFSET 0x00000000 + +/* For boot struct version */ +#ifndef SECURE_BOOT_VER +#define SECURE_BOOT_VER 2 +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/best2300p/reg_aoncmu_best2300p.h b/platform/hal/best2300p/reg_aoncmu_best2300p.h new file mode 100644 index 0000000..5d45f38 --- /dev/null +++ b/platform/hal/best2300p/reg_aoncmu_best2300p.h @@ -0,0 +1,532 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_AONCMU_BEST2300P_H__ +#define __REG_AONCMU_BEST2300P_H__ + +#include "plat_types.h" + +struct AONCMU_T { + __I uint32_t CHIP_ID; // 0x00 + __IO uint32_t TOP_CLK_ENABLE; // 0x04 + __IO uint32_t TOP_CLK_DISABLE; // 0x08 + __IO uint32_t RESET_PULSE; // 0x0C + __IO uint32_t RESET_SET; // 0x10 + __IO uint32_t RESET_CLR; // 0x14 + __IO uint32_t CLK_SELECT; // 0x18 + __IO uint32_t CLK_OUT; // 0x1C + __IO uint32_t WRITE_UNLOCK; // 0x20 + __IO uint32_t MEMSC[4]; // 0x24 + __I uint32_t MEMSC_STATUS; // 0x34 + __IO uint32_t BOOTMODE; // 0x38 + __IO uint32_t RESERVED_03C; // 0x3C + __IO uint32_t MOD_CLK_ENABLE; // 0x40 + __IO uint32_t MOD_CLK_DISABLE; // 0x44 + __IO uint32_t MOD_CLK_MODE; // 0x48 + __IO uint32_t CODEC_DIV; // 0x4C + __IO uint32_t TIMER_CLK; // 0x50 + __IO uint32_t PWM01_CLK; // 0x54 + __IO uint32_t PWM23_CLK; // 0x58 + __IO uint32_t RAM_CFG; // 0x5C + __IO uint32_t RESERVED_060; // 0x60 + __IO uint32_t PCM_I2S_CLK; // 0x64 + __IO uint32_t SPDIF_CLK; // 0x68 + __IO uint32_t SLEEP_TIMER_OSC; // 0x6C + __IO uint32_t SLEEP_TIMER_32K; // 0x70 + __IO uint32_t STORE_GPIO_MASK; // 0x74 + __IO uint32_t CODEC_IIR; // 0x78 + __IO uint32_t SE_WLOCK; // 0x7C + __IO uint32_t SE_RLOCK; // 0x80 + __IO uint32_t PD_STAB_TIMER; // 0x84 + uint32_t RESERVED_088[0x1A]; // 0x88 + __IO uint32_t WAKEUP_PC; // 0xF0 + __IO uint32_t DEBUG_RES[2]; // 0xF4 + __IO uint32_t CHIP_FEATURE; // 0xFC +}; + +// reg_00 +#define AON_CMU_CHIP_ID(n) (((n) & 0xFFFF) << 0) +#define AON_CMU_CHIP_ID_MASK (0xFFFF << 0) +#define AON_CMU_CHIP_ID_SHIFT (0) +#define AON_CMU_REVISION_ID(n) (((n) & 0xFFFF) << 16) +#define AON_CMU_REVISION_ID_MASK (0xFFFF << 16) +#define AON_CMU_REVISION_ID_SHIFT (16) + +// reg_04 +#define AON_CMU_EN_CLK_TOP_PLLBB_ENABLE (1 << 0) +#define AON_CMU_EN_CLK_TOP_PLLAUD_ENABLE (1 << 1) +#define AON_CMU_EN_CLK_TOP_OSCX2_ENABLE (1 << 2) +#define AON_CMU_EN_CLK_TOP_OSC_ENABLE (1 << 3) +#define AON_CMU_EN_CLK_TOP_JTAG_ENABLE (1 << 4) +#define AON_CMU_EN_CLK_TOP_PLLBB2_ENABLE (1 << 5) +#define AON_CMU_EN_CLK_TOP_PLLUSB_ENABLE (1 << 6) +#define AON_CMU_EN_CLK_PLL_CODEC_ENABLE (1 << 7) +#define AON_CMU_EN_CLK_CODEC_HCLK_ENABLE (1 << 8) +#define AON_CMU_EN_CLK_CODEC_RS_ENABLE (1 << 9) +#define AON_CMU_EN_CLK_CODEC_ENABLE (1 << 10) +#define AON_CMU_EN_CLK_CODEC_IIR_ENABLE (1 << 11) +#define AON_CMU_EN_CLK_OSCX2_MCU_ENABLE (1 << 12) +#define AON_CMU_EN_CLK_OSC_MCU_ENABLE (1 << 13) +#define AON_CMU_EN_CLK_32K_MCU_ENABLE (1 << 14) +#define AON_CMU_EN_CLK_PLL_BT_ENABLE (1 << 15) +#define AON_CMU_EN_CLK_60M_BT_ENABLE (1 << 16) +#define AON_CMU_EN_CLK_OSCX2_BT_ENABLE (1 << 17) +#define AON_CMU_EN_CLK_OSC_BT_ENABLE (1 << 18) +#define AON_CMU_EN_CLK_32K_BT_ENABLE (1 << 19) +#define AON_CMU_EN_CLK_PLL_PER_ENABLE (1 << 20) +#define AON_CMU_EN_CLK_DCDC0_ENABLE (1 << 21) +#define AON_CMU_EN_CLK_DCDC1_ENABLE (1 << 22) +#define AON_CMU_EN_CLK_DCDC2_ENABLE (1 << 23) +#define AON_CMU_EN_X2_DIG_ENABLE (1 << 24) +#define AON_CMU_EN_X4_DIG_ENABLE (1 << 25) +#define AON_CMU_PU_PLLBB_ENABLE (1 << 26) +#define AON_CMU_PU_PLLUSB_ENABLE (1 << 27) +#define AON_CMU_PU_PLLAUD_ENABLE (1 << 28) +#define AON_CMU_PU_OSC_ENABLE (1 << 29) +#define AON_CMU_EN_X4_ANA_ENABLE (1 << 30) +#define AON_CMU_EN_CLK_32K_CODEC_ENABLE (1 << 31) + +// reg_08 +#define AON_CMU_EN_CLK_TOP_PLLBB_DISABLE (1 << 0) +#define AON_CMU_EN_CLK_TOP_PLLAUD_DISABLE (1 << 1) +#define AON_CMU_EN_CLK_TOP_OSCX2_DISABLE (1 << 2) +#define AON_CMU_EN_CLK_TOP_OSC_DISABLE (1 << 3) +#define AON_CMU_EN_CLK_TOP_JTAG_DISABLE (1 << 4) +#define AON_CMU_EN_CLK_TOP_PLLBB2_DISABLE (1 << 5) +#define AON_CMU_EN_CLK_TOP_PLLUSB_DISABLE (1 << 6) +#define AON_CMU_EN_CLK_PLL_CODEC_DISABLE (1 << 7) +#define AON_CMU_EN_CLK_CODEC_HCLK_DISABLE (1 << 8) +#define AON_CMU_EN_CLK_CODEC_RS_DISABLE (1 << 9) +#define AON_CMU_EN_CLK_CODEC_DISABLE (1 << 10) +#define AON_CMU_EN_CLK_CODEC_IIR_DISABLE (1 << 11) +#define AON_CMU_EN_CLK_OSCX2_MCU_DISABLE (1 << 12) +#define AON_CMU_EN_CLK_OSC_MCU_DISABLE (1 << 13) +#define AON_CMU_EN_CLK_32K_MCU_DISABLE (1 << 14) +#define AON_CMU_EN_CLK_PLL_BT_DISABLE (1 << 15) +#define AON_CMU_EN_CLK_60M_BT_DISABLE (1 << 16) +#define AON_CMU_EN_CLK_OSCX2_BT_DISABLE (1 << 17) +#define AON_CMU_EN_CLK_OSC_BT_DISABLE (1 << 18) +#define AON_CMU_EN_CLK_32K_BT_DISABLE (1 << 19) +#define AON_CMU_EN_CLK_PLL_PER_DISABLE (1 << 20) +#define AON_CMU_EN_CLK_DCDC0_DISABLE (1 << 21) +#define AON_CMU_EN_CLK_DCDC1_DISABLE (1 << 22) +#define AON_CMU_EN_CLK_DCDC2_DISABLE (1 << 23) +#define AON_CMU_EN_X2_DIG_DISABLE (1 << 24) +#define AON_CMU_EN_X4_DIG_DISABLE (1 << 25) +#define AON_CMU_PU_PLLBB_DISABLE (1 << 26) +#define AON_CMU_PU_PLLUSB_DISABLE (1 << 27) +#define AON_CMU_PU_PLLAUD_DISABLE (1 << 28) +#define AON_CMU_PU_OSC_DISABLE (1 << 29) +#define AON_CMU_EN_X4_ANA_DISABLE (1 << 30) +#define AON_CMU_EN_CLK_32K_CODEC_DISABLE (1 << 31) + +#define AON_ARST_NUM 10 +#define AON_ORST_NUM 10 +#define AON_ACLK_NUM AON_ARST_NUM +#define AON_OCLK_NUM AON_ORST_NUM + +// reg_0c +#define AON_CMU_ARESETN_PULSE(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_ARESETN_PULSE_MASK (0xFFFFFFFF << 0) +#define AON_CMU_ARESETN_PULSE_SHIFT (0) +#define AON_CMU_ORESETN_PULSE(n) (((n) & 0xFFFFFFFF) << AON_ARST_NUM) +#define AON_CMU_ORESETN_PULSE_MASK (0xFFFFFFFF << AON_ARST_NUM) +#define AON_CMU_ORESETN_PULSE_SHIFT (AON_ARST_NUM) +#define AON_CMU_SOFT_RSTN_MCU_PULSE (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1-1)) +#define AON_CMU_SOFT_RSTN_CODEC_PULSE (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1-1)) +#define AON_CMU_SOFT_RSTN_WF_PULSE (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_BT_PULSE (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_MCUCPU_PULSE (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_WFCPU_PULSE (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_BTCPU_PULSE (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1+1+1-1)) +#define AON_CMU_GLOBAL_RESETN_PULSE (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1+1+1+1-1)) + +// reg_10 +#define AON_CMU_ARESETN_SET(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_ARESETN_SET_MASK (0xFFFFFFFF << 0) +#define AON_CMU_ARESETN_SET_SHIFT (0) +#define AON_CMU_ORESETN_SET(n) (((n) & 0xFFFFFFFF) << AON_ARST_NUM) +#define AON_CMU_ORESETN_SET_MASK (0xFFFFFFFF << AON_ARST_NUM) +#define AON_CMU_ORESETN_SET_SHIFT (AON_ARST_NUM) +#define AON_CMU_SOFT_RSTN_MCU_SET (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1-1)) +#define AON_CMU_SOFT_RSTN_CODEC_SET (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1-1)) +#define AON_CMU_SOFT_RSTN_WF_SET (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_BT_SET (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_MCUCPU_SET (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_WFCPU_SET (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_BTCPU_SET (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1+1+1-1)) +#define AON_CMU_GLOBAL_RESETN_SET (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1+1+1+1-1)) + +// reg_14 +#define AON_CMU_ARESETN_CLR(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_ARESETN_CLR_MASK (0xFFFFFFFF << 0) +#define AON_CMU_ARESETN_CLR_SHIFT (0) +#define AON_CMU_ORESETN_CLR(n) (((n) & 0xFFFFFFFF) << AON_ARST_NUM) +#define AON_CMU_ORESETN_CLR_MASK (0xFFFFFFFF << AON_ARST_NUM) +#define AON_CMU_ORESETN_CLR_SHIFT (AON_ARST_NUM) +#define AON_CMU_SOFT_RSTN_MCU_CLR (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1-1)) +#define AON_CMU_SOFT_RSTN_CODEC_CLR (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1-1)) +#define AON_CMU_SOFT_RSTN_WF_CLR (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_BT_CLR (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_MCUCPU_CLR (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_WFCPU_CLR (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1+1-1)) +#define AON_CMU_SOFT_RSTN_BTCPU_CLR (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1+1+1-1)) +#define AON_CMU_GLOBAL_RESETN_CLR (1 << (AON_ARST_NUM+AON_ORST_NUM+32-8-AON_ARST_NUM-AON_ORST_NUM+1+1+1+1+1+1+1+1-1)) + +// reg_18 +#define AON_CMU_BYPASS_DIV_BTSYS (1 << 0) +#define AON_CMU_CFG_DIV_BTSYS(n) (((n) & 0x3) << 1) +#define AON_CMU_CFG_DIV_BTSYS_MASK (0x3 << 1) +#define AON_CMU_CFG_DIV_BTSYS_SHIFT (1) +#define AON_CMU_CFG_DIV_BT60M(n) (((n) & 0x3) << 3) +#define AON_CMU_CFG_DIV_BT60M_MASK (0x3 << 3) +#define AON_CMU_CFG_DIV_BT60M_SHIFT (3) +#define AON_CMU_SEL_PLL_SYS(n) (((n) & 0x3) << 5) +#define AON_CMU_SEL_PLL_SYS_MASK (0x3 << 5) +#define AON_CMU_SEL_PLL_SYS_SHIFT (5) +#define AON_CMU_SEL_PLL_AUD(n) (((n) & 0x3) << 7) +#define AON_CMU_SEL_PLL_AUD_MASK (0x3 << 7) +#define AON_CMU_SEL_PLL_AUD_SHIFT (7) +#define AON_CMU_SEL_OSCX2_DIG (1 << 9) +#define AON_CMU_SEL_X2_PHASE(n) (((n) & 0x1F) << 10) +#define AON_CMU_SEL_X2_PHASE_MASK (0x1F << 10) +#define AON_CMU_SEL_X2_PHASE_SHIFT (10) +#define AON_CMU_SEL_X4_SYS (1 << 15) +#define AON_CMU_SEL_X4_AUD (1 << 16) +#define AON_CMU_SEL_X4_USB (1 << 17) +#define AON_CMU_SEL_X4_PHASE(n) (((n) & 0x1F) << 18) +#define AON_CMU_SEL_X4_PHASE_MASK (0x1F << 18) +#define AON_CMU_SEL_X4_PHASE_SHIFT (18) +#define AON_CMU_SEL_X4_DIG (1 << 23) +#define AON_CMU_CFG_DIV_PER(n) (((n) & 0x3) << 24) +#define AON_CMU_CFG_DIV_PER_MASK (0x3 << 24) +#define AON_CMU_CFG_DIV_PER_SHIFT (24) +#define AON_CMU_BYPASS_DIV_PER (1 << 26) +#define AON_CMU_SEL_32K_TIMER (1 << 27) +#define AON_CMU_SEL_32K_WDT (1 << 28) +#define AON_CMU_SEL_TIMER_FAST (1 << 29) +#define AON_CMU_LPU_AUTO_SWITCH26 (1 << 30) +#define AON_CMU_EN_MCU_WDG_RESET (1 << 31) + +// reg_1c +#define AON_CMU_EN_CLK_OUT (1 << 0) +#define AON_CMU_SEL_CLK_OUT(n) (((n) & 0x3) << 1) +#define AON_CMU_SEL_CLK_OUT_MASK (0x3 << 1) +#define AON_CMU_SEL_CLK_OUT_SHIFT (1) +#define AON_CMU_CFG_CLK_OUT(n) (((n) & 0xF) << 3) +#define AON_CMU_CFG_CLK_OUT_MASK (0xF << 3) +#define AON_CMU_CFG_CLK_OUT_SHIFT (3) +#define AON_CMU_CFG_DIV_DCDC(n) (((n) & 0xF) << 7) +#define AON_CMU_CFG_DIV_DCDC_MASK (0xF << 7) +#define AON_CMU_CFG_DIV_DCDC_SHIFT (7) +#define AON_CMU_BYPASS_DIV_DCDC (1 << 11) +#define AON_CMU_SEL_DCDC_PLL (1 << 12) +#define AON_CMU_SEL_DCDC_OSCX2 (1 << 13) +#define AON_CMU_CLK_DCDC_DRV(n) (((n) & 0x3) << 14) +#define AON_CMU_CLK_DCDC_DRV_MASK (0x3 << 14) +#define AON_CMU_CLK_DCDC_DRV_SHIFT (14) +#define AON_CMU_EN_VOD_IIR (1 << 16) +#define AON_CMU_EN_VOD_RS (1 << 17) +#define AON_CMU_SEL_X4_FLS (1 << 18) + +// reg_20 +#define AON_CMU_WRITE_UNLOCK_H (1 << 0) +#define AON_CMU_WRITE_UNLOCK_STATUS (1 << 1) + +// reg_24 +#define AON_CMU_MEMSC0 (1 << 0) + +// reg_28 +#define AON_CMU_MEMSC1 (1 << 0) + +// reg_2c +#define AON_CMU_MEMSC2 (1 << 0) + +// reg_30 +#define AON_CMU_MEMSC3 (1 << 0) + +// reg_34 +#define AON_CMU_MEMSC_STATUS0 (1 << 0) +#define AON_CMU_MEMSC_STATUS1 (1 << 1) +#define AON_CMU_MEMSC_STATUS2 (1 << 2) +#define AON_CMU_MEMSC_STATUS3 (1 << 3) + +// reg_38 +#define AON_CMU_WATCHDOG_RESET (1 << 0) +#define AON_CMU_SOFT_GLOBLE_RESET (1 << 1) +#define AON_CMU_RTC_INTR_H (1 << 2) +#define AON_CMU_CHG_INTR_H (1 << 3) +#define AON_CMU_SOFT_BOOT_MODE(n) (((n) & 0xFFFFFFF) << 4) +#define AON_CMU_SOFT_BOOT_MODE_MASK (0xFFFFFFF << 4) +#define AON_CMU_SOFT_BOOT_MODE_SHIFT (4) + +// reg_3c +#define AON_CMU_RESERVED(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_RESERVED_MASK (0xFFFFFFFF << 0) +#define AON_CMU_RESERVED_SHIFT (0) +#define AON_CMU_OSC_TO_DIG_X4 (1 << 1) + +// reg_40 +#define AON_CMU_MANUAL_ACLK_ENABLE(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_MANUAL_ACLK_ENABLE_MASK (0xFFFFFFFF << 0) +#define AON_CMU_MANUAL_ACLK_ENABLE_SHIFT (0) +#define AON_CMU_MANUAL_OCLK_ENABLE(n) (((n) & 0xFFFFFFFF) << AON_ACLK_NUM) +#define AON_CMU_MANUAL_OCLK_ENABLE_MASK (0xFFFFFFFF << AON_ACLK_NUM) +#define AON_CMU_MANUAL_OCLK_ENABLE_SHIFT (AON_ACLK_NUM) + +// reg_44 +#define AON_CMU_MANUAL_ACLK_DISABLE(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_MANUAL_ACLK_DISABLE_MASK (0xFFFFFFFF << 0) +#define AON_CMU_MANUAL_ACLK_DISABLE_SHIFT (0) +#define AON_CMU_MANUAL_OCLK_DISABLE(n) (((n) & 0xFFFFFFFF) << AON_ACLK_NUM) +#define AON_CMU_MANUAL_OCLK_DISABLE_MASK (0xFFFFFFFF << AON_ACLK_NUM) +#define AON_CMU_MANUAL_OCLK_DISABLE_SHIFT (AON_ACLK_NUM) + +// reg_48 +#define AON_CMU_MODE_ACLK(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_MODE_ACLK_MASK (0xFFFFFFFF << 0) +#define AON_CMU_MODE_ACLK_SHIFT (0) +#define AON_CMU_MODE_OCLK(n) (((n) & 0xFFFFFFFF) << AON_ACLK_NUM) +#define AON_CMU_MODE_OCLK_MASK (0xFFFFFFFF << AON_ACLK_NUM) +#define AON_CMU_MODE_OCLK_SHIFT (AON_ACLK_NUM) + +// reg_4c +#define AON_CMU_SEL_CLK_OSC (1 << 0) +#define AON_CMU_SEL_CLK_OSCX2 (1 << 1) +#define AON_CMU_CFG_DIV_CODEC(n) (((n) & 0x1F) << 2) +#define AON_CMU_CFG_DIV_CODEC_MASK (0x1F << 2) +#define AON_CMU_CFG_DIV_CODEC_SHIFT (2) +#define AON_CMU_SEL_OSC_CODEC (1 << 7) +#define AON_CMU_SEL_OSCX2_CODECHCLK (1 << 8) +#define AON_CMU_SEL_PLL_CODECHCLK (1 << 9) +#define AON_CMU_SEL_CODEC_HCLK_AON (1 << 10) +#define AON_CMU_BYPASS_LOCK_PLLUSB (1 << 11) +#define AON_CMU_BYPASS_LOCK_PLLBB (1 << 12) +#define AON_CMU_BYPASS_LOCK_PLLAUD (1 << 13) +#define AON_CMU_POL_SPI_CS(n) (((n) & 0x7) << 14) +#define AON_CMU_POL_SPI_CS_MASK (0x7 << 14) +#define AON_CMU_POL_SPI_CS_SHIFT (14) +#define AON_CMU_CFG_SPI_ARB(n) (((n) & 0x7) << 17) +#define AON_CMU_CFG_SPI_ARB_MASK (0x7 << 17) +#define AON_CMU_CFG_SPI_ARB_SHIFT (17) +#define AON_CMU_PU_FLASH_IO (1 << 20) +#define AON_CMU_POR_SLEEP_MODE (1 << 21) +#define AON_CMU_LOCK_PLLBB (1 << 22) +#define AON_CMU_LOCK_PLLUSB (1 << 23) +#define AON_CMU_LOCK_PLLAUD (1 << 24) + +// reg_50 +#define AON_CMU_CFG_DIV_TIMER0(n) (((n) & 0xFFFF) << 0) +#define AON_CMU_CFG_DIV_TIMER0_MASK (0xFFFF << 0) +#define AON_CMU_CFG_DIV_TIMER0_SHIFT (0) +#define AON_CMU_CFG_DIV_TIMER1(n) (((n) & 0xFFFF) << 16) +#define AON_CMU_CFG_DIV_TIMER1_MASK (0xFFFF << 16) +#define AON_CMU_CFG_DIV_TIMER1_SHIFT (16) + +// reg_54 +#define AON_CMU_CFG_DIV_PWM0(n) (((n) & 0xFFF) << 0) +#define AON_CMU_CFG_DIV_PWM0_MASK (0xFFF << 0) +#define AON_CMU_CFG_DIV_PWM0_SHIFT (0) +#define AON_CMU_SEL_OSC_PWM0 (1 << 12) +#define AON_CMU_EN_OSC_PWM0 (1 << 13) +#define AON_CMU_CFG_DIV_PWM1(n) (((n) & 0xFFF) << 16) +#define AON_CMU_CFG_DIV_PWM1_MASK (0xFFF << 16) +#define AON_CMU_CFG_DIV_PWM1_SHIFT (16) +#define AON_CMU_SEL_OSC_PWM1 (1 << 28) +#define AON_CMU_EN_OSC_PWM1 (1 << 29) + +// reg_58 +#define AON_CMU_CFG_DIV_PWM2(n) (((n) & 0xFFF) << 0) +#define AON_CMU_CFG_DIV_PWM2_MASK (0xFFF << 0) +#define AON_CMU_CFG_DIV_PWM2_SHIFT (0) +#define AON_CMU_SEL_OSC_PWM2 (1 << 12) +#define AON_CMU_EN_OSC_PWM2 (1 << 13) +#define AON_CMU_CFG_DIV_PWM3(n) (((n) & 0xFFF) << 16) +#define AON_CMU_CFG_DIV_PWM3_MASK (0xFFF << 16) +#define AON_CMU_CFG_DIV_PWM3_SHIFT (16) +#define AON_CMU_SEL_OSC_PWM3 (1 << 28) +#define AON_CMU_EN_OSC_PWM3 (1 << 29) + +// reg_5c +#define AON_CMU_RAM_EMA(n) (((n) & 0x7) << 0) +#define AON_CMU_RAM_EMA_MASK (0x7 << 0) +#define AON_CMU_RAM_EMA_SHIFT (0) +#define AON_CMU_RAM_EMAW(n) (((n) & 0x3) << 3) +#define AON_CMU_RAM_EMAW_MASK (0x3 << 3) +#define AON_CMU_RAM_EMAW_SHIFT (3) +#define AON_CMU_RAM_WABL (1 << 5) +#define AON_CMU_RAM_WABLM(n) (((n) & 0x3) << 6) +#define AON_CMU_RAM_WABLM_MASK (0x3 << 6) +#define AON_CMU_RAM_WABLM_SHIFT (6) +#define AON_CMU_RAM_RET1N0(n) (((n) & 0x7) << 8) +#define AON_CMU_RAM_RET1N0_MASK (0x7 << 8) +#define AON_CMU_RAM_RET1N0_SHIFT (8) +#define AON_CMU_RAM_RET2N0(n) (((n) & 0x7) << 11) +#define AON_CMU_RAM_RET2N0_MASK (0x7 << 11) +#define AON_CMU_RAM_RET2N0_SHIFT (11) +#define AON_CMU_RAM_PGEN0(n) (((n) & 0x7) << 14) +#define AON_CMU_RAM_PGEN0_MASK (0x7 << 14) +#define AON_CMU_RAM_PGEN0_SHIFT (14) +#define AON_CMU_RAM_RET1N1(n) (((n) & 0x7) << 17) +#define AON_CMU_RAM_RET1N1_MASK (0x7 << 17) +#define AON_CMU_RAM_RET1N1_SHIFT (17) +#define AON_CMU_RAM_RET2N1(n) (((n) & 0x7) << 20) +#define AON_CMU_RAM_RET2N1_MASK (0x7 << 20) +#define AON_CMU_RAM_RET2N1_SHIFT (20) +#define AON_CMU_RAM_PGEN1(n) (((n) & 0x7) << 23) +#define AON_CMU_RAM_PGEN1_MASK (0x7 << 23) +#define AON_CMU_RAM_PGEN1_SHIFT (23) +#define AON_CMU_RAM_EMAS (1 << 26) + +// reg_64 +#define AON_CMU_CFG_DIV_PCM(n) (((n) & 0x1FFF) << 0) +#define AON_CMU_CFG_DIV_PCM_MASK (0x1FFF << 0) +#define AON_CMU_CFG_DIV_PCM_SHIFT (0) +#define AON_CMU_SEL_I2S_MCLK(n) (((n) & 0x7) << 13) +#define AON_CMU_SEL_I2S_MCLK_MASK (0x7 << 13) +#define AON_CMU_SEL_I2S_MCLK_SHIFT (13) +#define AON_CMU_CFG_DIV_I2S0(n) (((n) & 0x1FFF) << 16) +#define AON_CMU_CFG_DIV_I2S0_MASK (0x1FFF << 16) +#define AON_CMU_CFG_DIV_I2S0_SHIFT (16) +#define AON_CMU_EN_CLK_PLL_I2S0 (1 << 29) +#define AON_CMU_EN_CLK_PLL_PCM (1 << 30) +#define AON_CMU_EN_I2S_MCLK (1 << 31) + +// reg_68 +#define AON_CMU_CFG_DIV_SPDIF0(n) (((n) & 0x1FFF) << 0) +#define AON_CMU_CFG_DIV_SPDIF0_MASK (0x1FFF << 0) +#define AON_CMU_CFG_DIV_SPDIF0_SHIFT (0) +#define AON_CMU_EN_CLK_PLL_SPDIF0 (1 << 13) +#define AON_CMU_CFG_DIV_I2S1(n) (((n) & 0x1FFF) << 16) +#define AON_CMU_CFG_DIV_I2S1_MASK (0x1FFF << 16) +#define AON_CMU_CFG_DIV_I2S1_SHIFT (16) +#define AON_CMU_EN_CLK_PLL_I2S1 (1 << 29) + +// reg_6c +#define AON_CMU_SLEEP_TIMER_OSC(n) (((n) & 0x7FF) << 0) +#define AON_CMU_SLEEP_TIMER_OSC_MASK (0x7FF << 0) +#define AON_CMU_SLEEP_TIMER_OSC_SHIFT (0) +#define AON_CMU_STORE_GPIO_EN (1 << 30) +#define AON_CMU_STORE_TIMER (1 << 31) + +// reg_70 +#define AON_CMU_SLEEP_TIMER_32K(n) (((n) & 0xFFFFFF) << 0) +#define AON_CMU_SLEEP_TIMER_32K_MASK (0xFFFFFF << 0) +#define AON_CMU_SLEEP_TIMER_32K_SHIFT (0) + +// reg_74 +#define AON_CMU_STORE_GPIO_MASK(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_STORE_GPIO_MASK_MASK (0xFFFFFFFF << 0) +#define AON_CMU_STORE_GPIO_MASK_SHIFT (0) + +// reg_78 +#define AON_CMU_CFG_DIV_CODECIIR(n) (((n) & 0xF) << 0) +#define AON_CMU_CFG_DIV_CODECIIR_MASK (0xF << 0) +#define AON_CMU_CFG_DIV_CODECIIR_SHIFT (0) +#define AON_CMU_SEL_OSC_CODECIIR (1 << 4) +#define AON_CMU_SEL_OSCX2_CODECIIR (1 << 5) +#define AON_CMU_BYPASS_DIV_CODECIIR (1 << 6) +#define AON_CMU_CFG_DIV_CODECRS(n) (((n) & 0xF) << 8) +#define AON_CMU_CFG_DIV_CODECRS_MASK (0xF << 8) +#define AON_CMU_CFG_DIV_CODECRS_SHIFT (8) +#define AON_CMU_SEL_OSC_CODECRS (1 << 12) +#define AON_CMU_SEL_OSCX2_CODECRS (1 << 13) +#define AON_CMU_BYPASS_DIV_CODECRS (1 << 14) + +// reg_7c +#define AON_CMU_OTP_WR_LOCK(n) (((n) & 0xFFFF) << 0) +#define AON_CMU_OTP_WR_LOCK_MASK (0xFFFF << 0) +#define AON_CMU_OTP_WR_LOCK_SHIFT (0) +#define AON_CMU_OTP_WR_UNLOCK (1 << 31) + +// reg_80 +#define AON_CMU_OTP_RD_LOCK(n) (((n) & 0xFFFF) << 0) +#define AON_CMU_OTP_RD_LOCK_MASK (0xFFFF << 0) +#define AON_CMU_OTP_RD_LOCK_SHIFT (0) +#define AON_CMU_OTP_RD_UNLOCK (1 << 31) + +// reg_84 +#define AON_CMU_CFG_PD_STAB_TIMER(n) (((n) & 0xF) << 0) +#define AON_CMU_CFG_PD_STAB_TIMER_MASK (0xF << 0) +#define AON_CMU_CFG_PD_STAB_TIMER_SHIFT (0) + +// reg_f0 +#define AON_CMU_DEBUG0(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_DEBUG0_MASK (0xFFFFFFFF << 0) +#define AON_CMU_DEBUG0_SHIFT (0) + +// reg_f4 +#define AON_CMU_DEBUG1(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_DEBUG1_MASK (0xFFFFFFFF << 0) +#define AON_CMU_DEBUG1_SHIFT (0) + +// reg_f8 +#define AON_CMU_DEBUG2(n) (((n) & 0xFFFFFFFF) << 0) +#define AON_CMU_DEBUG2_MASK (0xFFFFFFFF << 0) +#define AON_CMU_DEBUG2_SHIFT (0) + +// reg_fc +#define AON_CMU_EFUSE(n) (((n) & 0xFFFF) << 0) +#define AON_CMU_EFUSE_MASK (0xFFFF << 0) +#define AON_CMU_EFUSE_SHIFT (0) +#define AON_CMU_EFUSE_LOCK (1 << 31) + + +// APB and AHB Clocks: +#define AON_ACLK_CMU (1 << 0) +#define AON_ARST_CMU (1 << 0) +#define AON_ACLK_GPIO (1 << 1) +#define AON_ARST_GPIO (1 << 1) +#define AON_ACLK_GPIO_INT (1 << 2) +#define AON_ARST_GPIO_INT (1 << 2) +#define AON_ACLK_WDT (1 << 3) +#define AON_ARST_WDT (1 << 3) +#define AON_ACLK_PWM (1 << 4) +#define AON_ARST_PWM (1 << 4) +#define AON_ACLK_TIMER (1 << 5) +#define AON_ARST_TIMER (1 << 5) +#define AON_ACLK_PSC (1 << 6) +#define AON_ARST_PSC (1 << 6) +#define AON_ACLK_IOMUX (1 << 7) +#define AON_ARST_IOMUX (1 << 7) +#define AON_ACLK_APBC (1 << 8) +#define AON_ARST_APBC (1 << 8) +#define AON_ACLK_H2H_MCU (1 << 9) +#define AON_ARST_H2H_MCU (1 << 9) + +// AON other Clocks: +#define AON_OCLK_WDT (1 << 0) +#define AON_ORST_WDT (1 << 0) +#define AON_OCLK_TIMER (1 << 1) +#define AON_ORST_TIMER (1 << 1) +#define AON_OCLK_GPIO (1 << 2) +#define AON_ORST_GPIO (1 << 2) +#define AON_OCLK_PWM0 (1 << 3) +#define AON_ORST_PWM0 (1 << 3) +#define AON_OCLK_PWM1 (1 << 4) +#define AON_ORST_PWM1 (1 << 4) +#define AON_OCLK_PWM2 (1 << 5) +#define AON_ORST_PWM2 (1 << 5) +#define AON_OCLK_PWM3 (1 << 6) +#define AON_ORST_PWM3 (1 << 6) +#define AON_OCLK_IOMUX (1 << 7) +#define AON_ORST_IOMUX (1 << 7) +#define AON_OCLK_SLP32K (1 << 8) +#define AON_ORST_SLP32K (1 << 8) +#define AON_OCLK_SLP26M (1 << 9) +#define AON_ORST_SLP26M (1 << 9) + +#endif + diff --git a/platform/hal/best2300p/reg_btcmu_best2300p.h b/platform/hal/best2300p/reg_btcmu_best2300p.h new file mode 100644 index 0000000..75b5214 --- /dev/null +++ b/platform/hal/best2300p/reg_btcmu_best2300p.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_BTCMU_BEST2300P_H__ +#define __REG_BTCMU_BEST2300P_H__ + +#include "plat_types.h" + +struct BTCMU_T { + __IO uint32_t CLK_ENABLE; // 0x00 + __IO uint32_t CLK_DISABLE; // 0x04 + __IO uint32_t CLK_MODE; // 0x08 + __IO uint32_t DIV_TIMER; // 0x0C + __IO uint32_t RESET_SET; // 0x10 + __IO uint32_t RESET_CLR; // 0x14 + __IO uint32_t DIV_WDT; // 0x18 + __IO uint32_t RESET_PULSE; // 0x1C + uint32_t RESERVED_020[0x24 / 4]; // 0x20 + __IO uint32_t CLK_OUT; // 0x44 + uint32_t RESERVED_048[2]; // 0x48 + __IO uint32_t ISIRQ_SET; // 0x50 + __IO uint32_t ISIRQ_CLR; // 0x54 +}; + +// reg_44 +#define BT_CMU_CAL_TIME(n) (((n) & 0xFF) << 0) +#define BT_CMU_CAL_TIME_MASK (0xFF << 0) +#define BT_CMU_CAL_TIME_SHIFT (0) +#define BT_CMU_SMP_CMU_SEL(n) (((n) & 0xF) << 8) +#define BT_CMU_SMP_CMU_SEL_MASK (0xF << 8) +#define BT_CMU_SMP_CMU_SEL_SHIFT (8) +#define BT_CMU_CFG_CLK_OUT(n) (((n) & 0xF) << 12) +#define BT_CMU_CFG_CLK_OUT_MASK (0xF << 12) +#define BT_CMU_CFG_CLK_OUT_SHIFT (12) +#define BT_CMU_PWR_DELAY(n) (((n) & 0x7F) << 16) +#define BT_CMU_PWR_DELAY_MASK (0x7F << 16) +#define BT_CMU_PWR_DELAY_SHIFT (16) +#define BT_CMU_ROM_PGEN(n) (((n) & 0xF) << 23) +#define BT_CMU_ROM_PGEN_MASK (0xF << 23) +#define BT_CMU_ROM_PGEN_SHIFT (23) +#define BT_CMU_RAM_EMAS (1 << 27) +#define BT_CMU_RF_EMAS (1 << 28) + +#endif + diff --git a/platform/hal/best2300p/reg_cmu_best2300p.h b/platform/hal/best2300p/reg_cmu_best2300p.h new file mode 100644 index 0000000..bbedfa7 --- /dev/null +++ b/platform/hal/best2300p/reg_cmu_best2300p.h @@ -0,0 +1,852 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_CMU_BEST2300P_H__ +#define __REG_CMU_BEST2300P_H__ + +#include "plat_types.h" + +struct CMU_T { + __IO uint32_t HCLK_ENABLE; // 0x00 + __IO uint32_t HCLK_DISABLE; // 0x04 + __IO uint32_t PCLK_ENABLE; // 0x08 + __IO uint32_t PCLK_DISABLE; // 0x0C + __IO uint32_t OCLK_ENABLE; // 0x10 + __IO uint32_t OCLK_DISABLE; // 0x14 + __IO uint32_t HCLK_MODE; // 0x18 + __IO uint32_t PCLK_MODE; // 0x1C + __IO uint32_t OCLK_MODE; // 0x20 + __IO uint32_t RAM_CFG3; // 0x24 + __IO uint32_t HRESET_PULSE; // 0x28 + __IO uint32_t PRESET_PULSE; // 0x2C + __IO uint32_t ORESET_PULSE; // 0x30 + __IO uint32_t HRESET_SET; // 0x34 + __IO uint32_t HRESET_CLR; // 0x38 + __IO uint32_t PRESET_SET; // 0x3C + __IO uint32_t PRESET_CLR; // 0x40 + __IO uint32_t ORESET_SET; // 0x44 + __IO uint32_t ORESET_CLR; // 0x48 + __IO uint32_t TIMER0_CLK; // 0x4C + __IO uint32_t BOOTMODE; // 0x50 + __IO uint32_t MCU_TIMER; // 0x54 + __IO uint32_t SLEEP; // 0x58 + __IO uint32_t PERIPH_CLK; // 0x5C + __IO uint32_t SYS_CLK_ENABLE; // 0x60 + __IO uint32_t SYS_CLK_DISABLE; // 0x64 + __IO uint32_t ADMA_CH15_REQ; // 0x68 + __IO uint32_t BOOT_DVS; // 0x6C + __IO uint32_t UART_CLK; // 0x70 + __IO uint32_t I2C_CLK; // 0x74 + __IO uint32_t RAM_CFG0; // 0x78 + __IO uint32_t RAM_CFG1; // 0x7C + __IO uint32_t WRITE_UNLOCK; // 0x80 + __IO uint32_t WAKEUP_MASK0; // 0x84 + __IO uint32_t WAKEUP_MASK1; // 0x88 + __IO uint32_t WAKEUP_CLK_CFG; // 0x8C + __IO uint32_t TIMER1_CLK; // 0x90 + __IO uint32_t TIMER2_CLK; // 0x94 + __IO uint32_t CP2MCU_IRQ_SET; // 0x98 + __IO uint32_t CP2MCU_IRQ_CLR; // 0x9C + __IO uint32_t ISIRQ_SET; // 0xA0 + __IO uint32_t ISIRQ_CLR; // 0xA4 + __IO uint32_t SYS_DIV; // 0xA8 + __IO uint32_t RESERVED_0AC; // 0xAC + __IO uint32_t MCU2BT_INTMASK0; // 0xB0 + __IO uint32_t MCU2BT_INTMASK1; // 0xB4 + __IO uint32_t MCU2CP_IRQ_SET; // 0xB8 + __IO uint32_t MCU2CP_IRQ_CLR; // 0xBC + __IO uint32_t MEMSC[4]; // 0xC0 + __I uint32_t MEMSC_STATUS; // 0xD0 + __IO uint32_t ADMA_CH0_4_REQ; // 0xD4 + __IO uint32_t ADMA_CH5_9_REQ; // 0xD8 + __IO uint32_t ADMA_CH10_14_REQ; // 0xDC + __IO uint32_t GDMA_CH0_4_REQ; // 0xE0 + __IO uint32_t GDMA_CH5_9_REQ; // 0xE4 + __IO uint32_t GDMA_CH10_14_REQ; // 0xE8 + __IO uint32_t GDMA_CH15_REQ; // 0xEC + __IO uint32_t MISC; // 0xF0 + __IO uint32_t SIMU_RES; // 0xF4 + __IO uint32_t SEC_ROM_CFG; // 0xF8 + __IO uint32_t ACC_CTRL; // 0xFC +}; + +// reg_00 +#define CMU_MANUAL_HCLK_ENABLE(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_MANUAL_HCLK_ENABLE_MASK (0xFFFFFFFF << 0) +#define CMU_MANUAL_HCLK_ENABLE_SHIFT (0) + +// reg_04 +#define CMU_MANUAL_HCLK_DISABLE(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_MANUAL_HCLK_DISABLE_MASK (0xFFFFFFFF << 0) +#define CMU_MANUAL_HCLK_DISABLE_SHIFT (0) + +// reg_08 +#define CMU_MANUAL_PCLK_ENABLE(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_MANUAL_PCLK_ENABLE_MASK (0xFFFFFFFF << 0) +#define CMU_MANUAL_PCLK_ENABLE_SHIFT (0) + +// reg_0c +#define CMU_MANUAL_PCLK_DISABLE(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_MANUAL_PCLK_DISABLE_MASK (0xFFFFFFFF << 0) +#define CMU_MANUAL_PCLK_DISABLE_SHIFT (0) + +// reg_10 +#define CMU_MANUAL_OCLK_ENABLE(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_MANUAL_OCLK_ENABLE_MASK (0xFFFFFFFF << 0) +#define CMU_MANUAL_OCLK_ENABLE_SHIFT (0) + +// reg_14 +#define CMU_MANUAL_OCLK_DISABLE(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_MANUAL_OCLK_DISABLE_MASK (0xFFFFFFFF << 0) +#define CMU_MANUAL_OCLK_DISABLE_SHIFT (0) + +// reg_18 +#define CMU_MODE_HCLK(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_MODE_HCLK_MASK (0xFFFFFFFF << 0) +#define CMU_MODE_HCLK_SHIFT (0) + +// reg_1c +#define CMU_MODE_PCLK(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_MODE_PCLK_MASK (0xFFFFFFFF << 0) +#define CMU_MODE_PCLK_SHIFT (0) + +// reg_20 +#define CMU_MODE_OCLK(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_MODE_OCLK_MASK (0xFFFFFFFF << 0) +#define CMU_MODE_OCLK_SHIFT (0) + +// reg_24 +#define CMU_RAM3_RET1N0(n) (((n) & 0x1F) << 0) +#define CMU_RAM3_RET1N0_MASK (0x1F << 0) +#define CMU_RAM3_RET1N0_SHIFT (0) +#define CMU_RAM3_RET2N0(n) (((n) & 0x1F) << 5) +#define CMU_RAM3_RET2N0_MASK (0x1F << 5) +#define CMU_RAM3_RET2N0_SHIFT (5) +#define CMU_RAM3_PGEN0(n) (((n) & 0x1F) << 10) +#define CMU_RAM3_PGEN0_MASK (0x1F << 10) +#define CMU_RAM3_PGEN0_SHIFT (10) +#define CMU_RAM3_RET1N1(n) (((n) & 0x1F) << 15) +#define CMU_RAM3_RET1N1_MASK (0x1F << 15) +#define CMU_RAM3_RET1N1_SHIFT (15) +#define CMU_RAM3_RET2N1(n) (((n) & 0x1F) << 20) +#define CMU_RAM3_RET2N1_MASK (0x1F << 20) +#define CMU_RAM3_RET2N1_SHIFT (20) +#define CMU_RAM3_PGEN1(n) (((n) & 0x1F) << 25) +#define CMU_RAM3_PGEN1_MASK (0x1F << 25) +#define CMU_RAM3_PGEN1_SHIFT (25) + +// reg_28 +#define CMU_HRESETN_PULSE(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_HRESETN_PULSE_MASK (0xFFFFFFFF << 0) +#define CMU_HRESETN_PULSE_SHIFT (0) + +#define SYS_PRST_NUM 19 + +// reg_2c +#define CMU_PRESETN_PULSE(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_PRESETN_PULSE_MASK (0xFFFFFFFF << 0) +#define CMU_PRESETN_PULSE_SHIFT (0) +#define CMU_GLOBAL_RESETN_PULSE (1 << (SYS_PRST_NUM+1-1)) + +// reg_30 +#define CMU_ORESETN_PULSE(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_ORESETN_PULSE_MASK (0xFFFFFFFF << 0) +#define CMU_ORESETN_PULSE_SHIFT (0) + +// reg_34 +#define CMU_HRESETN_SET(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_HRESETN_SET_MASK (0xFFFFFFFF << 0) +#define CMU_HRESETN_SET_SHIFT (0) + +// reg_38 +#define CMU_HRESETN_CLR(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_HRESETN_CLR_MASK (0xFFFFFFFF << 0) +#define CMU_HRESETN_CLR_SHIFT (0) + +// reg_3c +#define CMU_PRESETN_SET(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_PRESETN_SET_MASK (0xFFFFFFFF << 0) +#define CMU_PRESETN_SET_SHIFT (0) +#define CMU_GLOBAL_RESETN_SET (1 << (SYS_PRST_NUM+1-1)) + +// reg_40 +#define CMU_PRESETN_CLR(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_PRESETN_CLR_MASK (0xFFFFFFFF << 0) +#define CMU_PRESETN_CLR_SHIFT (0) +#define CMU_GLOBAL_RESETN_CLR (1 << (SYS_PRST_NUM+1-1)) + +// reg_44 +#define CMU_ORESETN_SET(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_ORESETN_SET_MASK (0xFFFFFFFF << 0) +#define CMU_ORESETN_SET_SHIFT (0) + +// reg_48 +#define CMU_ORESETN_CLR(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_ORESETN_CLR_MASK (0xFFFFFFFF << 0) +#define CMU_ORESETN_CLR_SHIFT (0) + +// reg_4c +#define CMU_CFG_DIV_TIMER00(n) (((n) & 0xFFFF) << 0) +#define CMU_CFG_DIV_TIMER00_MASK (0xFFFF << 0) +#define CMU_CFG_DIV_TIMER00_SHIFT (0) +#define CMU_CFG_DIV_TIMER01(n) (((n) & 0xFFFF) << 16) +#define CMU_CFG_DIV_TIMER01_MASK (0xFFFF << 16) +#define CMU_CFG_DIV_TIMER01_SHIFT (16) + +// reg_50 +#define CMU_WATCHDOG_RESET (1 << 0) +#define CMU_SOFT_GLOBLE_RESET (1 << 1) +#define CMU_RTC_INTR_H (1 << 2) +#define CMU_CHG_INTR_H (1 << 3) +#define CMU_SOFT_BOOT_MODE(n) (((n) & 0xFFFFFFF) << 4) +#define CMU_SOFT_BOOT_MODE_MASK (0xFFFFFFF << 4) +#define CMU_SOFT_BOOT_MODE_SHIFT (4) + +// reg_54 +#define CMU_CFG_HCLK_MCU_OFF_TIMER(n) (((n) & 0xFF) << 0) +#define CMU_CFG_HCLK_MCU_OFF_TIMER_MASK (0xFF << 0) +#define CMU_CFG_HCLK_MCU_OFF_TIMER_SHIFT (0) +#define CMU_HCLK_MCU_ENABLE (1 << 8) +#define CMU_SECURE_BOOT_JTAG (1 << 9) +#define CMU_RAM_RETN_UP_EARLY (1 << 10) +#define CMU_FLS_SEC_MSK_EN (1 << 11) +#define CMU_SECURE_BOOT_I2C (1 << 12) +#define CMU_DEBUG_REG_SEL(n) (((n) & 0x7) << 13) +#define CMU_DEBUG_REG_SEL_MASK (0x7 << 13) +#define CMU_DEBUG_REG_SEL_SHIFT (13) + +// reg_58 +#define CMU_SLEEP_TIMER(n) (((n) & 0xFFFFFF) << 0) +#define CMU_SLEEP_TIMER_MASK (0xFFFFFF << 0) +#define CMU_SLEEP_TIMER_SHIFT (0) +#define CMU_SLEEP_TIMER_EN (1 << 24) +#define CMU_DEEPSLEEP_EN (1 << 25) +#define CMU_DEEPSLEEP_ROMRAM_EN (1 << 26) +#define CMU_MANUAL_RAM_RETN (1 << 27) +#define CMU_DEEPSLEEP_START (1 << 28) +#define CMU_DEEPSLEEP_MODE (1 << 29) +#define CMU_PU_OSC (1 << 30) +#define CMU_WAKEUP_DEEPSLEEP_L (1 << 31) + +// reg_5c +#define CMU_CFG_DIV_SDMMC(n) (((n) & 0xF) << 0) +#define CMU_CFG_DIV_SDMMC_MASK (0xF << 0) +#define CMU_CFG_DIV_SDMMC_SHIFT (0) +#define CMU_SEL_OSCX2_SDMMC (1 << 4) +#define CMU_SEL_PLL_SDMMC (1 << 5) +#define CMU_EN_PLL_SDMMC (1 << 6) +#define CMU_SEL_32K_TIMER(n) (((n) & 0x7) << 7) +#define CMU_SEL_32K_TIMER_MASK (0x7 << 7) +#define CMU_SEL_32K_TIMER_SHIFT (7) +#define CMU_SEL_32K_WDT (1 << 10) +#define CMU_SEL_TIMER_FAST(n) (((n) & 0x7) << 11) +#define CMU_SEL_TIMER_FAST_MASK (0x7 << 11) +#define CMU_SEL_TIMER_FAST_SHIFT (11) +#define CMU_CFG_CLK_OUT(n) (((n) & 0xF) << 14) +#define CMU_CFG_CLK_OUT_MASK (0xF << 14) +#define CMU_CFG_CLK_OUT_SHIFT (14) +#define CMU_SPI_I2C_DMAREQ_SEL (1 << 18) +#define CMU_MASK_OBS(n) (((n) & 0x3F) << 19) +#define CMU_MASK_OBS_MASK (0x3F << 19) +#define CMU_MASK_OBS_SHIFT (19) +#define CMU_JTAG_SEL_CP (1 << 25) + +// reg_60 +#define CMU_RSTN_DIV_FLS_ENABLE (1 << 0) +#define CMU_SEL_OSC_FLS_ENABLE (1 << 1) +#define CMU_SEL_OSCX2_FLS_ENABLE (1 << 2) +#define CMU_SEL_PLL_FLS_ENABLE (1 << 3) +#define CMU_BYPASS_DIV_FLS_ENABLE (1 << 4) +#define CMU_RSTN_DIV_SYS_ENABLE (1 << 5) +#define CMU_SEL_OSC_SYS_ENABLE (1 << 6) +#define CMU_SEL_OSCX2_SYS_ENABLE (1 << 7) +#define CMU_SEL_PLL_SYS_ENABLE (1 << 8) +#define CMU_BYPASS_DIV_SYS_ENABLE (1 << 9) +#define CMU_EN_PLL_ENABLE (1 << 10) +#define CMU_PU_PLL_ENABLE (1 << 11) + +// reg_64 +#define CMU_RSTN_DIV_FLS_DISABLE (1 << 0) +#define CMU_SEL_OSC_FLS_DISABLE (1 << 1) +#define CMU_SEL_OSCX2_FLS_DISABLE (1 << 2) +#define CMU_SEL_PLL_FLS_DISABLE (1 << 3) +#define CMU_BYPASS_DIV_FLS_DISABLE (1 << 4) +#define CMU_RSTN_DIV_SYS_DISABLE (1 << 5) +#define CMU_SEL_OSC_SYS_DISABLE (1 << 6) +#define CMU_SEL_OSCX2_SYS_DISABLE (1 << 7) +#define CMU_SEL_PLL_SYS_DISABLE (1 << 8) +#define CMU_BYPASS_DIV_SYS_DISABLE (1 << 9) +#define CMU_EN_PLL_DISABLE (1 << 10) +#define CMU_PU_PLL_DISABLE (1 << 11) + +// reg_68 +#define CMU_ADMA_CH15_REQ_IDX(n) (((n) & 0x3F) << 0) +#define CMU_ADMA_CH15_REQ_IDX_MASK (0x3F << 0) +#define CMU_ADMA_CH15_REQ_IDX_SHIFT (0) + +// reg_6c +#define CMU_ROM_EMA(n) (((n) & 0x7) << 0) +#define CMU_ROM_EMA_MASK (0x7 << 0) +#define CMU_ROM_EMA_SHIFT (0) +#define CMU_ROM_KEN (1 << 3) +#define CMU_ROM_PGEN(n) (((n) & 0x7) << 4) +#define CMU_ROM_PGEN_MASK (0x7 << 4) +#define CMU_ROM_PGEN_SHIFT (4) +#define CMU_RAM_EMA(n) (((n) & 0x7) << 7) +#define CMU_RAM_EMA_MASK (0x7 << 7) +#define CMU_RAM_EMA_SHIFT (7) +#define CMU_RAM_EMAW(n) (((n) & 0x3) << 10) +#define CMU_RAM_EMAW_MASK (0x3 << 10) +#define CMU_RAM_EMAW_SHIFT (10) +#define CMU_RAM_WABL (1 << 12) +#define CMU_RAM_WABLM(n) (((n) & 0x3) << 13) +#define CMU_RAM_WABLM_MASK (0x3 << 13) +#define CMU_RAM_WABLM_SHIFT (13) +#define CMU_RAM_EMAS (1 << 15) +#define CMU_RF_EMA(n) (((n) & 0x7) << 16) +#define CMU_RF_EMA_MASK (0x7 << 16) +#define CMU_RF_EMA_SHIFT (16) +#define CMU_RF_EMAW(n) (((n) & 0x3) << 19) +#define CMU_RF_EMAW_MASK (0x3 << 19) +#define CMU_RF_EMAW_SHIFT (19) +#define CMU_RF_WABL (1 << 21) +#define CMU_RF_WABLM(n) (((n) & 0x3) << 22) +#define CMU_RF_WABLM_MASK (0x3 << 22) +#define CMU_RF_WABLM_SHIFT (22) +#define CMU_RF_EMAS (1 << 24) +#define CMU_RF_RET1N0 (1 << 25) +#define CMU_RF_RET2N0 (1 << 26) +#define CMU_RF_PGEN0 (1 << 27) +#define CMU_RF_RET1N1 (1 << 28) +#define CMU_RF_RET2N1 (1 << 29) +#define CMU_RF_PGEN1 (1 << 30) + +// reg_70 +#define CMU_CFG_DIV_UART0(n) (((n) & 0x1F) << 0) +#define CMU_CFG_DIV_UART0_MASK (0x1F << 0) +#define CMU_CFG_DIV_UART0_SHIFT (0) +#define CMU_SEL_OSCX2_UART0 (1 << 5) +#define CMU_SEL_PLL_UART0 (1 << 6) +#define CMU_EN_PLL_UART0 (1 << 7) +#define CMU_CFG_DIV_UART1(n) (((n) & 0x1F) << 8) +#define CMU_CFG_DIV_UART1_MASK (0x1F << 8) +#define CMU_CFG_DIV_UART1_SHIFT (8) +#define CMU_SEL_OSCX2_UART1 (1 << 13) +#define CMU_SEL_PLL_UART1 (1 << 14) +#define CMU_EN_PLL_UART1 (1 << 15) +#define CMU_CFG_DIV_UART2(n) (((n) & 0x1F) << 16) +#define CMU_CFG_DIV_UART2_MASK (0x1F << 16) +#define CMU_CFG_DIV_UART2_SHIFT (16) +#define CMU_SEL_OSCX2_UART2 (1 << 21) +#define CMU_SEL_PLL_UART2 (1 << 22) +#define CMU_EN_PLL_UART2 (1 << 23) + +// reg_74 +#define CMU_CFG_DIV_I2C(n) (((n) & 0xFF) << 0) +#define CMU_CFG_DIV_I2C_MASK (0xFF << 0) +#define CMU_CFG_DIV_I2C_SHIFT (0) +#define CMU_SEL_OSC_I2C (1 << 8) +#define CMU_SEL_OSCX2_I2C (1 << 9) +#define CMU_SEL_PLL_I2C (1 << 10) +#define CMU_EN_PLL_I2C (1 << 11) +#define CMU_POL_CLK_PCM_IN (1 << 12) +#define CMU_SEL_PCM_CLKIN (1 << 13) +#define CMU_EN_CLK_PCM_OUT (1 << 14) +#define CMU_POL_CLK_PCM_OUT (1 << 15) +#define CMU_POL_CLK_I2S0_IN (1 << 16) +#define CMU_SEL_I2S0_CLKIN (1 << 17) +#define CMU_EN_CLK_I2S0_OUT (1 << 18) +#define CMU_POL_CLK_I2S0_OUT (1 << 19) +#define CMU_FORCE_PU_OFF (1 << 20) +#define CMU_LOCK_CPU_EN (1 << 21) +#define CMU_SEL_ROM_FAST (1 << 22) +#define CMU_POL_CLK_I2S1_IN (1 << 23) +#define CMU_SEL_I2S1_CLKIN (1 << 24) +#define CMU_EN_CLK_I2S1_OUT (1 << 25) +#define CMU_POL_CLK_I2S1_OUT (1 << 26) + +// reg_78 +#define CMU_RAM_RET1N0(n) (((n) & 0x3FF) << 0) +#define CMU_RAM_RET1N0_MASK (0x3FF << 0) +#define CMU_RAM_RET1N0_SHIFT (0) +#define CMU_RAM_RET2N0(n) (((n) & 0x3FF) << 10) +#define CMU_RAM_RET2N0_MASK (0x3FF << 10) +#define CMU_RAM_RET2N0_SHIFT (10) +#define CMU_RAM_PGEN0(n) (((n) & 0x3FF) << 20) +#define CMU_RAM_PGEN0_MASK (0x3FF << 20) +#define CMU_RAM_PGEN0_SHIFT (20) + +// reg_7c +#define CMU_RAM_RET1N1(n) (((n) & 0x3FF) << 0) +#define CMU_RAM_RET1N1_MASK (0x3FF << 0) +#define CMU_RAM_RET1N1_SHIFT (0) +#define CMU_RAM_RET2N1(n) (((n) & 0x3FF) << 10) +#define CMU_RAM_RET2N1_MASK (0x3FF << 10) +#define CMU_RAM_RET2N1_SHIFT (10) +#define CMU_RAM_PGEN1(n) (((n) & 0x3FF) << 20) +#define CMU_RAM_PGEN1_MASK (0x3FF << 20) +#define CMU_RAM_PGEN1_SHIFT (20) + +// reg_80 +#define CMU_WRITE_UNLOCK_H (1 << 0) +#define CMU_WRITE_UNLOCK_STATUS (1 << 1) + +// reg_84 +#define CMU_WAKEUP_IRQ_MASK0(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_WAKEUP_IRQ_MASK0_MASK (0xFFFFFFFF << 0) +#define CMU_WAKEUP_IRQ_MASK0_SHIFT (0) + +// reg_88 +#define CMU_WAKEUP_IRQ_MASK1(n) (((n) & 0xFFFFF) << 0) +#define CMU_WAKEUP_IRQ_MASK1_MASK (0xFFFFF << 0) +#define CMU_WAKEUP_IRQ_MASK1_SHIFT (0) + +// reg_8c +#define CMU_TIMER_WT26(n) (((n) & 0xFF) << 0) +#define CMU_TIMER_WT26_MASK (0xFF << 0) +#define CMU_TIMER_WT26_SHIFT (0) +#define CMU_TIMER_WTPLL(n) (((n) & 0xF) << 8) +#define CMU_TIMER_WTPLL_MASK (0xF << 8) +#define CMU_TIMER_WTPLL_SHIFT (8) +#define CMU_LPU_AUTO_SWITCH26 (1 << 12) +#define CMU_LPU_AUTO_SWITCHPLL (1 << 13) +#define CMU_LPU_STATUS_26M (1 << 14) +#define CMU_LPU_STATUS_PLL (1 << 15) + +// reg_90 +#define CMU_CFG_DIV_TIMER10(n) (((n) & 0xFFFF) << 0) +#define CMU_CFG_DIV_TIMER10_MASK (0xFFFF << 0) +#define CMU_CFG_DIV_TIMER10_SHIFT (0) +#define CMU_CFG_DIV_TIMER11(n) (((n) & 0xFFFF) << 16) +#define CMU_CFG_DIV_TIMER11_MASK (0xFFFF << 16) +#define CMU_CFG_DIV_TIMER11_SHIFT (16) + +// reg_94 +#define CMU_CFG_DIV_TIMER20(n) (((n) & 0xFFFF) << 0) +#define CMU_CFG_DIV_TIMER20_MASK (0xFFFF << 0) +#define CMU_CFG_DIV_TIMER20_SHIFT (0) +#define CMU_CFG_DIV_TIMER21(n) (((n) & 0xFFFF) << 16) +#define CMU_CFG_DIV_TIMER21_MASK (0xFFFF << 16) +#define CMU_CFG_DIV_TIMER21_SHIFT (16) + +// reg_98 +#define CMU_MCU2CP_DATA_DONE_SET (1 << 0) +#define CMU_MCU2CP_DATA1_DONE_SET (1 << 1) +#define CMU_MCU2CP_DATA2_DONE_SET (1 << 2) +#define CMU_MCU2CP_DATA3_DONE_SET (1 << 3) +#define CMU_CP2MCU_DATA_IND_SET (1 << 4) +#define CMU_CP2MCU_DATA1_IND_SET (1 << 5) +#define CMU_CP2MCU_DATA2_IND_SET (1 << 6) +#define CMU_CP2MCU_DATA3_IND_SET (1 << 7) + +// reg_9c +#define CMU_MCU2CP_DATA_DONE_CLR (1 << 0) +#define CMU_MCU2CP_DATA1_DONE_CLR (1 << 1) +#define CMU_MCU2CP_DATA2_DONE_CLR (1 << 2) +#define CMU_MCU2CP_DATA3_DONE_CLR (1 << 3) +#define CMU_CP2MCU_DATA_IND_CLR (1 << 4) +#define CMU_CP2MCU_DATA1_IND_CLR (1 << 5) +#define CMU_CP2MCU_DATA2_IND_CLR (1 << 6) +#define CMU_CP2MCU_DATA3_IND_CLR (1 << 7) + +// reg_a0 +#define CMU_BT2MCU_DATA_DONE_SET (1 << 0) +#define CMU_BT2MCU_DATA1_DONE_SET (1 << 1) +#define CMU_MCU2BT_DATA_IND_SET (1 << 2) +#define CMU_MCU2BT_DATA1_IND_SET (1 << 3) +#define CMU_BT_ALLIRQ_MASK_SET (1 << 4) + +// reg_a4 +#define CMU_BT2MCU_DATA_DONE_CLR (1 << 0) +#define CMU_BT2MCU_DATA1_DONE_CLR (1 << 1) +#define CMU_MCU2BT_DATA_IND_CLR (1 << 2) +#define CMU_MCU2BT_DATA1_IND_CLR (1 << 3) +#define CMU_BT_ALLIRQ_MASK_CLR (1 << 4) + +// reg_a8 +#define CMU_CFG_DIV_SYS(n) (((n) & 0x3) << 0) +#define CMU_CFG_DIV_SYS_MASK (0x3 << 0) +#define CMU_CFG_DIV_SYS_SHIFT (0) +#define CMU_SEL_SMP_MCU(n) (((n) & 0x3) << 2) +#define CMU_SEL_SMP_MCU_MASK (0x3 << 2) +#define CMU_SEL_SMP_MCU_SHIFT (2) +#define CMU_CFG_DIV_FLS(n) (((n) & 0x3) << 4) +#define CMU_CFG_DIV_FLS_MASK (0x3 << 4) +#define CMU_CFG_DIV_FLS_SHIFT (4) +#define CMU_SEL_USB_6M (1 << 6) +#define CMU_SEL_USB_SRC(n) (((n) & 0x7) << 7) +#define CMU_SEL_USB_SRC_MASK (0x7 << 7) +#define CMU_SEL_USB_SRC_SHIFT (7) +#define CMU_POL_CLK_USB (1 << 10) +#define CMU_USB_ID (1 << 11) +#define CMU_CFG_DIV_PCLK(n) (((n) & 0x3) << 12) +#define CMU_CFG_DIV_PCLK_MASK (0x3 << 12) +#define CMU_CFG_DIV_PCLK_SHIFT (12) +#define CMU_CFG_DIV_SPI0(n) (((n) & 0xF) << 14) +#define CMU_CFG_DIV_SPI0_MASK (0xF << 14) +#define CMU_CFG_DIV_SPI0_SHIFT (14) +#define CMU_SEL_OSCX2_SPI0 (1 << 18) +#define CMU_SEL_PLL_SPI0 (1 << 19) +#define CMU_EN_PLL_SPI0 (1 << 20) +#define CMU_CFG_DIV_SPI1(n) (((n) & 0xF) << 21) +#define CMU_CFG_DIV_SPI1_MASK (0xF << 21) +#define CMU_CFG_DIV_SPI1_SHIFT (21) +#define CMU_SEL_OSCX2_SPI1 (1 << 25) +#define CMU_SEL_PLL_SPI1 (1 << 26) +#define CMU_EN_PLL_SPI1 (1 << 27) +#define CMU_SEL_OSCX2_SPI2 (1 << 28) +#define CMU_DSD_PCM_DMAREQ_SEL (1 << 29) + +// reg_ac +#define CMU_DMA_HANDSHAKE_SWAP(n) (((n) & 0xFFFF) << 0) +#define CMU_DMA_HANDSHAKE_SWAP_MASK (0xFFFF << 0) +#define CMU_DMA_HANDSHAKE_SWAP_SHIFT (0) +#define CMU_RESERVED_2(n) (((n) & 0xFFFF) << 16) +#define CMU_RESERVED_2_MASK (0xFFFF << 16) +#define CMU_RESERVED_2_SHIFT (16) + +// reg_b0 +#define CMU_MCU2BT_INTISR_MASK0(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_MCU2BT_INTISR_MASK0_MASK (0xFFFFFFFF << 0) +#define CMU_MCU2BT_INTISR_MASK0_SHIFT (0) + +// reg_b4 +#define CMU_MCU2BT_INTISR_MASK1(n) (((n) & 0xFFFFF) << 0) +#define CMU_MCU2BT_INTISR_MASK1_MASK (0xFFFFF << 0) +#define CMU_MCU2BT_INTISR_MASK1_SHIFT (0) + +// reg_b8 +#define CMU_CP2MCU_DATA_DONE_SET (1 << 0) +#define CMU_CP2MCU_DATA1_DONE_SET (1 << 1) +#define CMU_CP2MCU_DATA2_DONE_SET (1 << 2) +#define CMU_CP2MCU_DATA3_DONE_SET (1 << 3) +#define CMU_MCU2CP_DATA_IND_SET (1 << 4) +#define CMU_MCU2CP_DATA1_IND_SET (1 << 5) +#define CMU_MCU2CP_DATA2_IND_SET (1 << 6) +#define CMU_MCU2CP_DATA3_IND_SET (1 << 7) + +// reg_bc +#define CMU_CP2MCU_DATA_DONE_CLR (1 << 0) +#define CMU_CP2MCU_DATA1_DONE_CLR (1 << 1) +#define CMU_CP2MCU_DATA2_DONE_CLR (1 << 2) +#define CMU_CP2MCU_DATA3_DONE_CLR (1 << 3) +#define CMU_MCU2CP_DATA_IND_CLR (1 << 4) +#define CMU_MCU2CP_DATA1_IND_CLR (1 << 5) +#define CMU_MCU2CP_DATA2_IND_CLR (1 << 6) +#define CMU_MCU2CP_DATA3_IND_CLR (1 << 7) + +// reg_c0 +#define CMU_MEMSC0 (1 << 0) + +// reg_c4 +#define CMU_MEMSC1 (1 << 0) + +// reg_c8 +#define CMU_MEMSC2 (1 << 0) + +// reg_cc +#define CMU_MEMSC3 (1 << 0) + +// reg_d0 +#define CMU_MEMSC_STATUS0 (1 << 0) +#define CMU_MEMSC_STATUS1 (1 << 1) +#define CMU_MEMSC_STATUS2 (1 << 2) +#define CMU_MEMSC_STATUS3 (1 << 3) + +// reg_d4 +#define CMU_ADMA_CH0_REQ_IDX(n) (((n) & 0x3F) << 0) +#define CMU_ADMA_CH0_REQ_IDX_MASK (0x3F << 0) +#define CMU_ADMA_CH0_REQ_IDX_SHIFT (0) +#define CMU_ADMA_CH1_REQ_IDX(n) (((n) & 0x3F) << 6) +#define CMU_ADMA_CH1_REQ_IDX_MASK (0x3F << 6) +#define CMU_ADMA_CH1_REQ_IDX_SHIFT (6) +#define CMU_ADMA_CH2_REQ_IDX(n) (((n) & 0x3F) << 12) +#define CMU_ADMA_CH2_REQ_IDX_MASK (0x3F << 12) +#define CMU_ADMA_CH2_REQ_IDX_SHIFT (12) +#define CMU_ADMA_CH3_REQ_IDX(n) (((n) & 0x3F) << 18) +#define CMU_ADMA_CH3_REQ_IDX_MASK (0x3F << 18) +#define CMU_ADMA_CH3_REQ_IDX_SHIFT (18) +#define CMU_ADMA_CH4_REQ_IDX(n) (((n) & 0x3F) << 24) +#define CMU_ADMA_CH4_REQ_IDX_MASK (0x3F << 24) +#define CMU_ADMA_CH4_REQ_IDX_SHIFT (24) + +// reg_d8 +#define CMU_ADMA_CH5_REQ_IDX(n) (((n) & 0x3F) << 0) +#define CMU_ADMA_CH5_REQ_IDX_MASK (0x3F << 0) +#define CMU_ADMA_CH5_REQ_IDX_SHIFT (0) +#define CMU_ADMA_CH6_REQ_IDX(n) (((n) & 0x3F) << 6) +#define CMU_ADMA_CH6_REQ_IDX_MASK (0x3F << 6) +#define CMU_ADMA_CH6_REQ_IDX_SHIFT (6) +#define CMU_ADMA_CH7_REQ_IDX(n) (((n) & 0x3F) << 12) +#define CMU_ADMA_CH7_REQ_IDX_MASK (0x3F << 12) +#define CMU_ADMA_CH7_REQ_IDX_SHIFT (12) +#define CMU_ADMA_CH8_REQ_IDX(n) (((n) & 0x3F) << 18) +#define CMU_ADMA_CH8_REQ_IDX_MASK (0x3F << 18) +#define CMU_ADMA_CH8_REQ_IDX_SHIFT (18) +#define CMU_ADMA_CH9_REQ_IDX(n) (((n) & 0x3F) << 24) +#define CMU_ADMA_CH9_REQ_IDX_MASK (0x3F << 24) +#define CMU_ADMA_CH9_REQ_IDX_SHIFT (24) + +// reg_dc +#define CMU_ADMA_CH10_REQ_IDX(n) (((n) & 0x3F) << 0) +#define CMU_ADMA_CH10_REQ_IDX_MASK (0x3F << 0) +#define CMU_ADMA_CH10_REQ_IDX_SHIFT (0) +#define CMU_ADMA_CH11_REQ_IDX(n) (((n) & 0x3F) << 6) +#define CMU_ADMA_CH11_REQ_IDX_MASK (0x3F << 6) +#define CMU_ADMA_CH11_REQ_IDX_SHIFT (6) +#define CMU_ADMA_CH12_REQ_IDX(n) (((n) & 0x3F) << 12) +#define CMU_ADMA_CH12_REQ_IDX_MASK (0x3F << 12) +#define CMU_ADMA_CH12_REQ_IDX_SHIFT (12) +#define CMU_ADMA_CH13_REQ_IDX(n) (((n) & 0x3F) << 18) +#define CMU_ADMA_CH13_REQ_IDX_MASK (0x3F << 18) +#define CMU_ADMA_CH13_REQ_IDX_SHIFT (18) +#define CMU_ADMA_CH14_REQ_IDX(n) (((n) & 0x3F) << 24) +#define CMU_ADMA_CH14_REQ_IDX_MASK (0x3F << 24) +#define CMU_ADMA_CH14_REQ_IDX_SHIFT (24) + +// reg_e0 +#define CMU_GDMA_CH0_REQ_IDX(n) (((n) & 0x3F) << 0) +#define CMU_GDMA_CH0_REQ_IDX_MASK (0x3F << 0) +#define CMU_GDMA_CH0_REQ_IDX_SHIFT (0) +#define CMU_GDMA_CH1_REQ_IDX(n) (((n) & 0x3F) << 6) +#define CMU_GDMA_CH1_REQ_IDX_MASK (0x3F << 6) +#define CMU_GDMA_CH1_REQ_IDX_SHIFT (6) +#define CMU_GDMA_CH2_REQ_IDX(n) (((n) & 0x3F) << 12) +#define CMU_GDMA_CH2_REQ_IDX_MASK (0x3F << 12) +#define CMU_GDMA_CH2_REQ_IDX_SHIFT (12) +#define CMU_GDMA_CH3_REQ_IDX(n) (((n) & 0x3F) << 18) +#define CMU_GDMA_CH3_REQ_IDX_MASK (0x3F << 18) +#define CMU_GDMA_CH3_REQ_IDX_SHIFT (18) +#define CMU_GDMA_CH4_REQ_IDX(n) (((n) & 0x3F) << 24) +#define CMU_GDMA_CH4_REQ_IDX_MASK (0x3F << 24) +#define CMU_GDMA_CH4_REQ_IDX_SHIFT (24) + +// reg_e4 +#define CMU_GDMA_CH5_REQ_IDX(n) (((n) & 0x3F) << 0) +#define CMU_GDMA_CH5_REQ_IDX_MASK (0x3F << 0) +#define CMU_GDMA_CH5_REQ_IDX_SHIFT (0) +#define CMU_GDMA_CH6_REQ_IDX(n) (((n) & 0x3F) << 6) +#define CMU_GDMA_CH6_REQ_IDX_MASK (0x3F << 6) +#define CMU_GDMA_CH6_REQ_IDX_SHIFT (6) +#define CMU_GDMA_CH7_REQ_IDX(n) (((n) & 0x3F) << 12) +#define CMU_GDMA_CH7_REQ_IDX_MASK (0x3F << 12) +#define CMU_GDMA_CH7_REQ_IDX_SHIFT (12) +#define CMU_GDMA_CH8_REQ_IDX(n) (((n) & 0x3F) << 18) +#define CMU_GDMA_CH8_REQ_IDX_MASK (0x3F << 18) +#define CMU_GDMA_CH8_REQ_IDX_SHIFT (18) +#define CMU_GDMA_CH9_REQ_IDX(n) (((n) & 0x3F) << 24) +#define CMU_GDMA_CH9_REQ_IDX_MASK (0x3F << 24) +#define CMU_GDMA_CH9_REQ_IDX_SHIFT (24) + +// reg_e8 +#define CMU_GDMA_CH10_REQ_IDX(n) (((n) & 0x3F) << 0) +#define CMU_GDMA_CH10_REQ_IDX_MASK (0x3F << 0) +#define CMU_GDMA_CH10_REQ_IDX_SHIFT (0) +#define CMU_GDMA_CH11_REQ_IDX(n) (((n) & 0x3F) << 6) +#define CMU_GDMA_CH11_REQ_IDX_MASK (0x3F << 6) +#define CMU_GDMA_CH11_REQ_IDX_SHIFT (6) +#define CMU_GDMA_CH12_REQ_IDX(n) (((n) & 0x3F) << 12) +#define CMU_GDMA_CH12_REQ_IDX_MASK (0x3F << 12) +#define CMU_GDMA_CH12_REQ_IDX_SHIFT (12) +#define CMU_GDMA_CH13_REQ_IDX(n) (((n) & 0x3F) << 18) +#define CMU_GDMA_CH13_REQ_IDX_MASK (0x3F << 18) +#define CMU_GDMA_CH13_REQ_IDX_SHIFT (18) +#define CMU_GDMA_CH14_REQ_IDX(n) (((n) & 0x3F) << 24) +#define CMU_GDMA_CH14_REQ_IDX_MASK (0x3F << 24) +#define CMU_GDMA_CH14_REQ_IDX_SHIFT (24) + +// reg_ec +#define CMU_GDMA_CH15_REQ_IDX(n) (((n) & 0x3F) << 0) +#define CMU_GDMA_CH15_REQ_IDX_MASK (0x3F << 0) +#define CMU_GDMA_CH15_REQ_IDX_SHIFT (0) + +// reg_f0 +#define CMU_RESERVED(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_RESERVED_MASK (0xFFFFFFFF << 0) +#define CMU_RESERVED_SHIFT (0) + +// reg_f4 +#define CMU_DEBUG(n) (((n) & 0xFFFFFFFF) << 0) +#define CMU_DEBUG_MASK (0xFFFFFFFF << 0) +#define CMU_DEBUG_SHIFT (0) + +// reg_f8 +#define CMU_SEC_ROM_STR_ADDR(n) (((n) & 0xFFFF) << 0) +#define CMU_SEC_ROM_STR_ADDR_MASK (0xFFFF << 0) +#define CMU_SEC_ROM_STR_ADDR_SHIFT (0) +#define CMU_SEC_ROM_END_ADDR(n) (((n) & 0xFFFF) << 16) +#define CMU_SEC_ROM_END_ADDR_MASK (0xFFFF << 16) +#define CMU_SEC_ROM_END_ADDR_SHIFT (16) + +// reg_fc +#define CMU_CPU_ACC_RAM_EN (1 << 0) +#define CMU_BCM_ACC_RAM_EN (1 << 1) +#define CMU_NONSEC_ACC_RAM_EN (1 << 2) +#define CMU_JTAG_ACC_RAM_EN (1 << 3) +#define CMU_JTAG_ACC_SECROM_EN (1 << 4) +#define CMU_DCODE_ACC_SECROM_EN (1 << 5) + +// MCU System AHB Clocks: +#define SYS_HCLK_MCU (1 << 0) +#define SYS_HRST_MCU (1 << 0) +#define SYS_HCLK_ROM0 (1 << 1) +#define SYS_HRST_ROM0 (1 << 1) +#define SYS_HCLK_ROM1 (1 << 2) +#define SYS_HRST_ROM1 (1 << 2) +#define SYS_HCLK_ROM2 (1 << 3) +#define SYS_HRST_ROM2 (1 << 3) +#define SYS_HCLK_RAM0 (1 << 4) +#define SYS_HRST_RAM0 (1 << 4) +#define SYS_HCLK_RAM1 (1 << 5) +#define SYS_HRST_RAM1 (1 << 5) +#define SYS_HCLK_RAM2 (1 << 6) +#define SYS_HRST_RAM2 (1 << 6) +#define SYS_HCLK_RAMRET (1 << 7) +#define SYS_HRST_RAMRET (1 << 7) +#define SYS_HCLK_AHB0 (1 << 8) +#define SYS_HRST_AHB0 (1 << 8) +#define SYS_HCLK_AHB1 (1 << 9) +#define SYS_HRST_AHB1 (1 << 9) +#define SYS_HCLK_AH2H_BT (1 << 10) +#define SYS_HRST_AH2H_BT (1 << 10) +#define SYS_HCLK_ADMA (1 << 11) +#define SYS_HRST_ADMA (1 << 11) +#define SYS_HCLK_GDMA (1 << 12) +#define SYS_HRST_GDMA (1 << 12) +#define SYS_HCLK_EXTMEM (1 << 13) +#define SYS_HRST_EXTMEM (1 << 13) +#define SYS_HCLK_FLASH (1 << 14) +#define SYS_HRST_FLASH (1 << 14) +#define SYS_HCLK_SDMMC (1 << 15) +#define SYS_HRST_SDMMC (1 << 15) +#define SYS_HCLK_USBC (1 << 16) +#define SYS_HRST_USBC (1 << 16) +#define SYS_HCLK_CODEC (1 << 17) +#define SYS_HRST_CODEC (1 << 17) +#define SYS_HCLK_FFT (1 << 18) +#define SYS_HRST_FFT (1 << 18) +#define SYS_HCLK_I2C_SLAVE (1 << 19) +#define SYS_HRST_I2C_SLAVE (1 << 19) +#define SYS_HCLK_USBH (1 << 20) +#define SYS_HRST_USBH (1 << 20) +#define SYS_HCLK_SENSOR_HUB (1 << 21) +#define SYS_HRST_SENSOR_HUB (1 << 21) +#define SYS_HCLK_BT_DUMP (1 << 22) +#define SYS_HRST_BT_DUMP (1 << 22) +#define SYS_HCLK_CP (1 << 23) +#define SYS_HRST_CP (1 << 23) +#define SYS_HCLK_RAM3 (1 << 24) +#define SYS_HRST_RAM3 (1 << 24) +#define SYS_HCLK_RAM4 (1 << 25) +#define SYS_HRST_RAM4 (1 << 25) +#define SYS_HCLK_RAM5 (1 << 26) +#define SYS_HRST_RAM5 (1 << 26) +#define SYS_HCLK_RAM6 (1 << 27) +#define SYS_HRST_RAM6 (1 << 27) +#define SYS_HCLK_BCM (1 << 28) +#define SYS_HRST_BCM (1 << 28) +#define SYS_HCLK_ICACHE0 (1 << 29) +#define SYS_HRST_ICACHE0 (1 << 29) +#define SYS_HCLK_ICACHE1 (1 << 30) +#define SYS_HRST_ICACHE1 (1 << 30) + +// MCU System APB Clocks: +#define SYS_PCLK_CMU (1 << 0) +#define SYS_PRST_CMU (1 << 0) +#define SYS_PCLK_WDT (1 << 1) +#define SYS_PRST_WDT (1 << 1) +#define SYS_PCLK_TIMER0 (1 << 2) +#define SYS_PRST_TIMER0 (1 << 2) +#define SYS_PCLK_TIMER1 (1 << 3) +#define SYS_PRST_TIMER1 (1 << 3) +#define SYS_PCLK_TIMER2 (1 << 4) +#define SYS_PRST_TIMER2 (1 << 4) +#define SYS_PCLK_I2C0 (1 << 5) +#define SYS_PRST_I2C0 (1 << 5) +#define SYS_PCLK_I2C1 (1 << 6) +#define SYS_PRST_I2C1 (1 << 6) +#define SYS_PCLK_SPI (1 << 7) +#define SYS_PRST_SPI (1 << 7) +#define SYS_PCLK_SLCD (1 << 8) +#define SYS_PRST_SLCD (1 << 8) +#define SYS_PCLK_SPI_ITN (1 << 9) +#define SYS_PRST_SPI_ITN (1 << 9) +#define SYS_PCLK_SPI_PHY (1 << 10) +#define SYS_PRST_SPI_PHY (1 << 10) +#define SYS_PCLK_UART0 (1 << 11) +#define SYS_PRST_UART0 (1 << 11) +#define SYS_PCLK_UART1 (1 << 12) +#define SYS_PRST_UART1 (1 << 12) +#define SYS_PCLK_UART2 (1 << 13) +#define SYS_PRST_UART2 (1 << 13) +#define SYS_PCLK_PCM (1 << 14) +#define SYS_PRST_PCM (1 << 14) +#define SYS_PCLK_I2S0 (1 << 15) +#define SYS_PRST_I2S0 (1 << 15) +#define SYS_PCLK_SPDIF0 (1 << 16) +#define SYS_PRST_SPDIF0 (1 << 16) +#define SYS_PCLK_I2S1 (1 << 17) +#define SYS_PRST_I2S1 (1 << 17) +#define SYS_PCLK_BCM (1 << 18) +#define SYS_PRST_BCM (1 << 18) + +// MCU System Other Clocks: +#define SYS_OCLK_SLEEP (1 << 0) +#define SYS_ORST_SLEEP (1 << 0) +#define SYS_OCLK_FLASH (1 << 1) +#define SYS_ORST_FLASH (1 << 1) +#define SYS_OCLK_USB (1 << 2) +#define SYS_ORST_USB (1 << 2) +#define SYS_OCLK_SDMMC (1 << 3) +#define SYS_ORST_SDMMC (1 << 3) +#define SYS_OCLK_WDT (1 << 4) +#define SYS_ORST_WDT (1 << 4) +#define SYS_OCLK_TIMER0 (1 << 5) +#define SYS_ORST_TIMER0 (1 << 5) +#define SYS_OCLK_TIMER1 (1 << 6) +#define SYS_ORST_TIMER1 (1 << 6) +#define SYS_OCLK_TIMER2 (1 << 7) +#define SYS_ORST_TIMER2 (1 << 7) +#define SYS_OCLK_I2C0 (1 << 8) +#define SYS_ORST_I2C0 (1 << 8) +#define SYS_OCLK_I2C1 (1 << 9) +#define SYS_ORST_I2C1 (1 << 9) +#define SYS_OCLK_SPI (1 << 10) +#define SYS_ORST_SPI (1 << 10) +#define SYS_OCLK_SLCD (1 << 11) +#define SYS_ORST_SLCD (1 << 11) +#define SYS_OCLK_SPI_ITN (1 << 12) +#define SYS_ORST_SPI_ITN (1 << 12) +#define SYS_OCLK_SPI_PHY (1 << 13) +#define SYS_ORST_SPI_PHY (1 << 13) +#define SYS_OCLK_UART0 (1 << 14) +#define SYS_ORST_UART0 (1 << 14) +#define SYS_OCLK_UART1 (1 << 15) +#define SYS_ORST_UART1 (1 << 15) +#define SYS_OCLK_UART2 (1 << 16) +#define SYS_ORST_UART2 (1 << 16) +#define SYS_OCLK_I2S0 (1 << 17) +#define SYS_ORST_I2S0 (1 << 17) +#define SYS_OCLK_SPDIF0 (1 << 18) +#define SYS_ORST_SPDIF0 (1 << 18) +#define SYS_OCLK_PCM (1 << 19) +#define SYS_ORST_PCM (1 << 19) +#define SYS_OCLK_USB32K (1 << 20) +#define SYS_ORST_USB32K (1 << 20) +#define SYS_OCLK_I2S1 (1 << 21) +#define SYS_ORST_I2S1 (1 << 21) + +#endif + diff --git a/platform/hal/best2300p/reg_codec_best2300p.h b/platform/hal/best2300p/reg_codec_best2300p.h new file mode 100644 index 0000000..6efc4c9 --- /dev/null +++ b/platform/hal/best2300p/reg_codec_best2300p.h @@ -0,0 +1,1785 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_CODEC_H__ +#define __REG_CODEC_H__ + +#include "plat_types.h" + +struct CODEC_T { + __IO uint32_t REG_000; + __IO uint32_t REG_004; + __IO uint32_t REG_008; + __IO uint32_t REG_00C; + __IO uint32_t REG_010; + __IO uint32_t REG_014; + __IO uint32_t REG_018; + __IO uint32_t REG_01C; + __IO uint32_t REG_020; + __IO uint32_t REG_024; + __IO uint32_t REG_028; + __IO uint32_t REG_02C; + __IO uint32_t REG_030; + __IO uint32_t REG_034; + __IO uint32_t REG_038; + __IO uint32_t REG_03C; + __IO uint32_t REG_040; + __IO uint32_t REG_044; + __IO uint32_t REG_048; + __IO uint32_t REG_04C; + __IO uint32_t REG_050; + __IO uint32_t REG_054; + __IO uint32_t REG_058; + __IO uint32_t REG_05C; + __IO uint32_t REG_060; + __IO uint32_t REG_064; + __IO uint32_t REG_068; + __IO uint32_t REG_06C; + __IO uint32_t REG_070; + __IO uint32_t REG_074; + __IO uint32_t REG_078; + __IO uint32_t REG_07C; + __IO uint32_t REG_080; + __IO uint32_t REG_084; + __IO uint32_t REG_088; + __IO uint32_t REG_08C; + __IO uint32_t REG_090; + __IO uint32_t REG_094; + __IO uint32_t REG_098; + __IO uint32_t REG_09C; + __IO uint32_t REG_0A0; + __IO uint32_t REG_0A4; + __IO uint32_t REG_0A8; + __IO uint32_t REG_0AC; + __IO uint32_t REG_0B0; + __IO uint32_t REG_0B4; + __IO uint32_t REG_0B8; + __IO uint32_t REG_0BC; + __IO uint32_t REG_0C0; + __IO uint32_t REG_0C4; + __IO uint32_t REG_0C8; + __IO uint32_t REG_0CC; + __IO uint32_t REG_0D0; + __IO uint32_t REG_0D4; + __IO uint32_t REG_0D8; + __IO uint32_t REG_0DC; + __IO uint32_t REG_0E0; + __IO uint32_t REG_0E4; + __IO uint32_t REG_0E8; + __IO uint32_t REG_0EC; + __IO uint32_t REG_0F0; + __IO uint32_t REG_0F4; + __IO uint32_t REG_0F8; + __IO uint32_t REG_0FC; + __IO uint32_t REG_100; + __IO uint32_t REG_104; + __IO uint32_t REG_108; + __IO uint32_t REG_10C; + __IO uint32_t REG_110; + __IO uint32_t REG_114; + __IO uint32_t REG_118; + __IO uint32_t REG_11C; + __IO uint32_t REG_120; + __IO uint32_t REG_124; + __IO uint32_t REG_128; + __IO uint32_t REG_12C; + __IO uint32_t REG_130; + __IO uint32_t REG_134; + __IO uint32_t REG_138; + __IO uint32_t REG_13C; + __IO uint32_t REG_140; + __IO uint32_t REG_144; + __IO uint32_t REG_148; + __IO uint32_t REG_14C; + __IO uint32_t REG_150; + __IO uint32_t REG_154; + __IO uint32_t REG_158; + __IO uint32_t REG_15C; + __IO uint32_t REG_160; + __IO uint32_t REG_164; + __IO uint32_t REG_168; + __IO uint32_t REG_16C; + __IO uint32_t REG_170; + __IO uint32_t REG_174; + __IO uint32_t REG_178; + __IO uint32_t REG_17C; + __IO uint32_t REG_180; + __IO uint32_t REG_184; + __IO uint32_t REG_188; + __IO uint32_t REG_18C; + __IO uint32_t REG_190; + __IO uint32_t REG_194; + __IO uint32_t REG_198; + __IO uint32_t REG_19C; + __IO uint32_t REG_1A0; + __IO uint32_t REG_1A4; + __IO uint32_t REG_1A8; + __IO uint32_t REG_1AC; + __IO uint32_t REG_1B0; + __IO uint32_t REG_1B4; + __IO uint32_t REG_1B8; + __IO uint32_t REG_1BC; + __IO uint32_t REG_1C0; + __IO uint32_t REG_1C4; + __IO uint32_t REG_1C8; + __IO uint32_t REG_1CC; + __IO uint32_t REG_1D0; + __IO uint32_t REG_1D4; + __IO uint32_t REG_1D8; + __IO uint32_t REG_1DC; + __IO uint32_t REG_1E0; + __IO uint32_t REG_1E4; + __IO uint32_t REG_1E8; + __IO uint32_t REG_1EC; + __IO uint32_t REG_1F0; + __IO uint32_t REG_1F4; + __IO uint32_t REG_1F8; + __IO uint32_t REG_1FC; + __IO uint32_t REG_200; + __IO uint32_t REG_204; + __IO uint32_t REG_208; + __IO uint32_t REG_20C; + __IO uint32_t REG_210; + __IO uint32_t REG_214; + __IO uint32_t REG_218; + __IO uint32_t REG_21C; + __IO uint32_t REG_220; + __IO uint32_t REG_224; + __IO uint32_t REG_228; + __IO uint32_t REG_22C; + __IO uint32_t REG_230; +}; + +// reg_00 +#define CODEC_CODEC_IF_EN (1 << 0) +#define CODEC_ADC_ENABLE (1 << 1) +#define CODEC_ADC_ENABLE_CH0 (1 << 2) +#define CODEC_ADC_ENABLE_CH1 (1 << 3) +#define CODEC_ADC_ENABLE_CH2 (1 << 4) +#define CODEC_ADC_ENABLE_CH3 (1 << 5) +#define CODEC_ADC_ENABLE_CH4 (1 << 6) +#define CODEC_ADC_ENABLE_CH5 (1 << 7) +#define CODEC_ADC_ENABLE_CH6 (1 << 8) +#define CODEC_DAC_ENABLE (1 << 9) +#define CODEC_DMACTRL_RX (1 << 10) +#define CODEC_DMACTRL_TX (1 << 11) + +// reg_04 +#define CODEC_RX_FIFO_FLUSH_CH0 (1 << 0) +#define CODEC_RX_FIFO_FLUSH_CH1 (1 << 1) +#define CODEC_RX_FIFO_FLUSH_CH2 (1 << 2) +#define CODEC_RX_FIFO_FLUSH_CH3 (1 << 3) +#define CODEC_RX_FIFO_FLUSH_CH4 (1 << 4) +#define CODEC_RX_FIFO_FLUSH_CH5 (1 << 5) +#define CODEC_RX_FIFO_FLUSH_CH6 (1 << 6) +#define CODEC_TX_FIFO_FLUSH (1 << 7) +#define CODEC_DSD_RX_FIFO_FLUSH (1 << 8) +#define CODEC_DSD_TX_FIFO_FLUSH (1 << 9) +#define CODEC_MC_FIFO_FLUSH (1 << 10) +#define CODEC_IIR_RX_FIFO_FLUSH (1 << 11) +#define CODEC_IIR_TX_FIFO_FLUSH (1 << 12) + +// reg_08 +#define CODEC_CODEC_RX_THRESHOLD(n) (((n) & 0xF) << 0) +#define CODEC_CODEC_RX_THRESHOLD_MASK (0xF << 0) +#define CODEC_CODEC_RX_THRESHOLD_SHIFT (0) +#define CODEC_CODEC_TX_THRESHOLD(n) (((n) & 0xF) << 4) +#define CODEC_CODEC_TX_THRESHOLD_MASK (0xF << 4) +#define CODEC_CODEC_TX_THRESHOLD_SHIFT (4) +#define CODEC_DSD_RX_THRESHOLD(n) (((n) & 0xF) << 8) +#define CODEC_DSD_RX_THRESHOLD_MASK (0xF << 8) +#define CODEC_DSD_RX_THRESHOLD_SHIFT (8) +#define CODEC_DSD_TX_THRESHOLD(n) (((n) & 0x7) << 12) +#define CODEC_DSD_TX_THRESHOLD_MASK (0x7 << 12) +#define CODEC_DSD_TX_THRESHOLD_SHIFT (12) +#define CODEC_MC_THRESHOLD(n) (((n) & 0xF) << 15) +#define CODEC_MC_THRESHOLD_MASK (0xF << 15) +#define CODEC_MC_THRESHOLD_SHIFT (15) +#define CODEC_IIR_RX_THRESHOLD(n) (((n) & 0x3F) << 19) +#define CODEC_IIR_RX_THRESHOLD_MASK (0x3F << 19) +#define CODEC_IIR_RX_THRESHOLD_SHIFT (19) +#define CODEC_IIR_TX_THRESHOLD(n) (((n) & 0x3F) << 25) +#define CODEC_IIR_TX_THRESHOLD_MASK (0x3F << 25) +#define CODEC_IIR_TX_THRESHOLD_SHIFT (25) + +// reg_0c +#define CODEC_CODEC_RX_OVERFLOW(n) (((n) & 0x1F) << 0) +#define CODEC_CODEC_RX_OVERFLOW_MASK (0x1F << 0) +#define CODEC_CODEC_RX_OVERFLOW_SHIFT (0) +#define CODEC_CODEC_RX_UNDERFLOW(n) (((n) & 0x1F) << 5) +#define CODEC_CODEC_RX_UNDERFLOW_MASK (0x1F << 5) +#define CODEC_CODEC_RX_UNDERFLOW_SHIFT (5) +#define CODEC_CODEC_TX_OVERFLOW (1 << 10) +#define CODEC_CODEC_TX_UNDERFLOW (1 << 11) +#define CODEC_DSD_RX_OVERFLOW (1 << 12) +#define CODEC_DSD_RX_UNDERFLOW (1 << 13) +#define CODEC_DSD_TX_OVERFLOW (1 << 14) +#define CODEC_DSD_TX_UNDERFLOW (1 << 15) +#define CODEC_MC_OVERFLOW (1 << 16) +#define CODEC_MC_UNDERFLOW (1 << 17) +#define CODEC_IIR_RX_OVERFLOW (1 << 18) +#define CODEC_IIR_RX_UNDERFLOW (1 << 19) +#define CODEC_IIR_TX_OVERFLOW (1 << 20) +#define CODEC_IIR_TX_UNDERFLOW (1 << 21) +#define CODEC_EVENT_TRIGGER (1 << 22) +#define CODEC_FB_CHECK_ERROR_TRIG_CH0 (1 << 23) +#define CODEC_FB_CHECK_ERROR_TRIG_CH1 (1 << 24) +#define CODEC_VAD_FIND (1 << 25) +#define CODEC_VAD_NOT_FIND (1 << 26) +#define CODEC_BT_TRIGGER (1 << 27) +#define CODEC_ADC_MAX_OVERFLOW (1 << 28) +#define CODEC_TIME_TRIGGER_STATUS (1 << 29) + +// reg_10 +#define CODEC_CODEC_RX_OVERFLOW_MSK(n) (((n) & 0x1F) << 0) +#define CODEC_CODEC_RX_OVERFLOW_MSK_MASK (0x1F << 0) +#define CODEC_CODEC_RX_OVERFLOW_MSK_SHIFT (0) +#define CODEC_CODEC_RX_UNDERFLOW_MSK(n) (((n) & 0x1F) << 5) +#define CODEC_CODEC_RX_UNDERFLOW_MSK_MASK (0x1F << 5) +#define CODEC_CODEC_RX_UNDERFLOW_MSK_SHIFT (5) +#define CODEC_CODEC_TX_OVERFLOW_MSK (1 << 10) +#define CODEC_CODEC_TX_UNDERFLOW_MSK (1 << 11) +#define CODEC_DSD_RX_OVERFLOW_MSK (1 << 12) +#define CODEC_DSD_RX_UNDERFLOW_MSK (1 << 13) +#define CODEC_DSD_TX_OVERFLOW_MSK (1 << 14) +#define CODEC_DSD_TX_UNDERFLOW_MSK (1 << 15) +#define CODEC_MC_OVERFLOW_MSK (1 << 16) +#define CODEC_MC_UNDERFLOW_MSK (1 << 17) +#define CODEC_IIR_RX_OVERFLOW_MSK (1 << 18) +#define CODEC_IIR_RX_UNDERFLOW_MSK (1 << 19) +#define CODEC_IIR_TX_OVERFLOW_MSK (1 << 20) +#define CODEC_IIR_TX_UNDERFLOW_MSK (1 << 21) +#define CODEC_EVENT_TRIGGER_MSK (1 << 22) +#define CODEC_FB_CHECK_ERROR_TRIG_CH0_MSK (1 << 23) +#define CODEC_FB_CHECK_ERROR_TRIG_CH1_MSK (1 << 24) +#define CODEC_VAD_FIND_MSK (1 << 25) +#define CODEC_VAD_NOT_FIND_MSK (1 << 26) +#define CODEC_BT_TRIGGER_MSK (1 << 27) +#define CODEC_ADC_MAX_OVERFLOW_MSK (1 << 28) +#define CODEC_TIME_TRIGGER_MSK (1 << 29) + +// reg_14 +#define CODEC_FIFO_COUNT_CH0(n) (((n) & 0xF) << 0) +#define CODEC_FIFO_COUNT_CH0_MASK (0xF << 0) +#define CODEC_FIFO_COUNT_CH0_SHIFT (0) +#define CODEC_FIFO_COUNT_CH1(n) (((n) & 0xF) << 4) +#define CODEC_FIFO_COUNT_CH1_MASK (0xF << 4) +#define CODEC_FIFO_COUNT_CH1_SHIFT (4) +#define CODEC_FIFO_COUNT_CH2(n) (((n) & 0xF) << 8) +#define CODEC_FIFO_COUNT_CH2_MASK (0xF << 8) +#define CODEC_FIFO_COUNT_CH2_SHIFT (8) +#define CODEC_FIFO_COUNT_CH3(n) (((n) & 0xF) << 12) +#define CODEC_FIFO_COUNT_CH3_MASK (0xF << 12) +#define CODEC_FIFO_COUNT_CH3_SHIFT (12) +#define CODEC_FIFO_COUNT_CH4(n) (((n) & 0xF) << 16) +#define CODEC_FIFO_COUNT_CH4_MASK (0xF << 16) +#define CODEC_FIFO_COUNT_CH4_SHIFT (16) +#define CODEC_FIFO_COUNT_RX_DSD(n) (((n) & 0xF) << 20) +#define CODEC_FIFO_COUNT_RX_DSD_MASK (0xF << 20) +#define CODEC_FIFO_COUNT_RX_DSD_SHIFT (20) +#define CODEC_FIFO_COUNT_RX_IIR(n) (((n) & 0x3F) << 24) +#define CODEC_FIFO_COUNT_RX_IIR_MASK (0x3F << 24) +#define CODEC_FIFO_COUNT_RX_IIR_SHIFT (24) + +// reg_18 +#define CODEC_FIFO_COUNT_TX(n) (((n) & 0xF) << 0) +#define CODEC_FIFO_COUNT_TX_MASK (0xF << 0) +#define CODEC_FIFO_COUNT_TX_SHIFT (0) +#define CODEC_STATE_RX_CH(n) (((n) & 0x3F) << 4) +#define CODEC_STATE_RX_CH_MASK (0x3F << 4) +#define CODEC_STATE_RX_CH_SHIFT (4) +#define CODEC_FIFO_COUNT_TX_DSD(n) (((n) & 0x7) << 10) +#define CODEC_FIFO_COUNT_TX_DSD_MASK (0x7 << 10) +#define CODEC_FIFO_COUNT_TX_DSD_SHIFT (10) +#define CODEC_MC_FIFO_COUNT(n) (((n) & 0xF) << 13) +#define CODEC_MC_FIFO_COUNT_MASK (0xF << 13) +#define CODEC_MC_FIFO_COUNT_SHIFT (13) +#define CODEC_FIFO_COUNT_TX_IIR(n) (((n) & 0x3F) << 17) +#define CODEC_FIFO_COUNT_TX_IIR_MASK (0x3F << 17) +#define CODEC_FIFO_COUNT_TX_IIR_SHIFT (17) +#define CODEC_FIFO_COUNT_CH5(n) (((n) & 0xF) << 23) +#define CODEC_FIFO_COUNT_CH5_MASK (0xF << 23) +#define CODEC_FIFO_COUNT_CH5_SHIFT (23) +#define CODEC_FIFO_COUNT_CH6(n) (((n) & 0xF) << 27) +#define CODEC_FIFO_COUNT_CH6_MASK (0xF << 27) +#define CODEC_FIFO_COUNT_CH6_SHIFT (27) + +// reg_1c +#define CODEC_RX_FIFO_DATA(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RX_FIFO_DATA_MASK (0xFFFFFFFF << 0) +#define CODEC_RX_FIFO_DATA_SHIFT (0) + +// reg_20 +#define CODEC_RX_FIFO_DATA(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RX_FIFO_DATA_MASK (0xFFFFFFFF << 0) +#define CODEC_RX_FIFO_DATA_SHIFT (0) + +// reg_24 +#define CODEC_RX_FIFO_DATA(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RX_FIFO_DATA_MASK (0xFFFFFFFF << 0) +#define CODEC_RX_FIFO_DATA_SHIFT (0) + +// reg_28 +#define CODEC_RX_FIFO_DATA(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RX_FIFO_DATA_MASK (0xFFFFFFFF << 0) +#define CODEC_RX_FIFO_DATA_SHIFT (0) + +// reg_2c +#define CODEC_RX_FIFO_DATA(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RX_FIFO_DATA_MASK (0xFFFFFFFF << 0) +#define CODEC_RX_FIFO_DATA_SHIFT (0) + +// reg_30 +#define CODEC_RX_FIFO_DATA(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RX_FIFO_DATA_MASK (0xFFFFFFFF << 0) +#define CODEC_RX_FIFO_DATA_SHIFT (0) + +// reg_34 +#define CODEC_RX_FIFO_DATA_DSD(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RX_FIFO_DATA_DSD_MASK (0xFFFFFFFF << 0) +#define CODEC_RX_FIFO_DATA_DSD_SHIFT (0) + +// reg_38 +#define CODEC_MC_FIFO_DATA(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_MC_FIFO_DATA_MASK (0xFFFFFFFF << 0) +#define CODEC_MC_FIFO_DATA_SHIFT (0) + +// reg_3c +#define CODEC_RX_FIFO_DATA_IIR(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RX_FIFO_DATA_IIR_MASK (0xFFFFFFFF << 0) +#define CODEC_RX_FIFO_DATA_IIR_SHIFT (0) + +// reg_40 +#define CODEC_MODE_16BIT_ADC_CH0 (1 << 0) +#define CODEC_MODE_16BIT_ADC_CH1 (1 << 1) +#define CODEC_MODE_16BIT_ADC_CH2 (1 << 2) +#define CODEC_MODE_16BIT_ADC_CH3 (1 << 3) +#define CODEC_MODE_16BIT_ADC_CH4 (1 << 4) +#define CODEC_MODE_16BIT_ADC_CH5 (1 << 5) +#define CODEC_MODE_16BIT_ADC_CH6 (1 << 6) +#define CODEC_MODE_24BIT_ADC (1 << 7) +#define CODEC_MODE_32BIT_ADC (1 << 8) + +// reg_44 +#define CODEC_DUAL_CHANNEL_DAC (1 << 0) +#define CODEC_DAC_EXCHANGE_L_R (1 << 1) +#define CODEC_MODE_16BIT_DAC (1 << 2) +#define CODEC_MODE_32BIT_DAC (1 << 3) + +// reg_48 +#define CODEC_DSD_IF_EN (1 << 0) +#define CODEC_DSD_ENABLE (1 << 1) +#define CODEC_DSD_DUAL_CHANNEL (1 << 2) +#define CODEC_DSD_MSB_FIRST (1 << 3) +#define CODEC_MODE_24BIT_DSD (1 << 4) +#define CODEC_MODE_32BIT_DSD (1 << 5) +#define CODEC_DMA_CTRL_RX_DSD (1 << 6) +#define CODEC_DMA_CTRL_TX_DSD (1 << 7) +#define CODEC_MODE_16BIT_DSD (1 << 8) +#define CODEC_DSD_IN_16BIT (1 << 9) + +// reg_4c +#define CODEC_MC_ENABLE (1 << 0) +#define CODEC_DUAL_CHANNEL_MC (1 << 1) +#define CODEC_MODE_16BIT_MC (1 << 2) +#define CODEC_DMA_CTRL_MC (1 << 3) +#define CODEC_MC_DELAY(n) (((n) & 0xFF) << 4) +#define CODEC_MC_DELAY_MASK (0xFF << 4) +#define CODEC_MC_DELAY_SHIFT (4) +#define CODEC_MC_RATE_SEL (1 << 12) +#define CODEC_MODE_32BIT_MC (1 << 13) + +// reg_50 +#define CODEC_CODEC_COUNT_KEEP(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_CODEC_COUNT_KEEP_MASK (0xFFFFFFFF << 0) +#define CODEC_CODEC_COUNT_KEEP_SHIFT (0) + +// reg_54 +#define CODEC_DAC_ENABLE_SEL(n) (((n) & 0x3) << 0) +#define CODEC_DAC_ENABLE_SEL_MASK (0x3 << 0) +#define CODEC_DAC_ENABLE_SEL_SHIFT (0) +#define CODEC_ADC_ENABLE_SEL(n) (((n) & 0x3) << 2) +#define CODEC_ADC_ENABLE_SEL_MASK (0x3 << 2) +#define CODEC_ADC_ENABLE_SEL_SHIFT (2) +#define CODEC_CODEC_DAC_ENABLE_SEL(n) (((n) & 0x3) << 4) +#define CODEC_CODEC_DAC_ENABLE_SEL_MASK (0x3 << 4) +#define CODEC_CODEC_DAC_ENABLE_SEL_SHIFT (4) +#define CODEC_CODEC_ADC_ENABLE_SEL(n) (((n) & 0x3) << 6) +#define CODEC_CODEC_ADC_ENABLE_SEL_MASK (0x3 << 6) +#define CODEC_CODEC_ADC_ENABLE_SEL_SHIFT (6) +#define CODEC_GPIO_TRIGGER_DB_ENABLE (1 << 8) +#define CODEC_STAMP_CLR_USED (1 << 9) +#define CODEC_EVENT_SEL (1 << 10) +#define CODEC_EVENT_FOR_CAPTURE (1 << 11) +#define CODEC_TEST_PORT_SEL(n) (((n) & 0x7) << 12) +#define CODEC_TEST_PORT_SEL_MASK (0x7 << 12) +#define CODEC_TEST_PORT_SEL_SHIFT (12) +#define CODEC_PLL_OSC_TRIGGER_SEL(n) (((n) & 0x3) << 15) +#define CODEC_PLL_OSC_TRIGGER_SEL_MASK (0x3 << 15) +#define CODEC_PLL_OSC_TRIGGER_SEL_SHIFT (15) +#define CODEC_FAULT_MUTE_DAC_ENABLE (1 << 17) + +// reg_58 +#define CODEC_RX_FIFO_DATA(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RX_FIFO_DATA_MASK (0xFFFFFFFF << 0) +#define CODEC_RX_FIFO_DATA_SHIFT (0) + +// reg_5c +#define CODEC_RX_FIFO_DATA(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RX_FIFO_DATA_MASK (0xFFFFFFFF << 0) +#define CODEC_RX_FIFO_DATA_SHIFT (0) + +// reg_60 +#define CODEC_EN_CLK_ADC_ANA(n) (((n) & 0x1F) << 0) +#define CODEC_EN_CLK_ADC_ANA_MASK (0x1F << 0) +#define CODEC_EN_CLK_ADC_ANA_SHIFT (0) +#define CODEC_EN_CLK_ADC(n) (((n) & 0x3F) << 5) +#define CODEC_EN_CLK_ADC_MASK (0x3F << 5) +#define CODEC_EN_CLK_ADC_SHIFT (5) +#define CODEC_EN_CLK_DAC (1 << 11) +#define CODEC_POL_ADC_ANA(n) (((n) & 0x1F) << 12) +#define CODEC_POL_ADC_ANA_MASK (0x1F << 12) +#define CODEC_POL_ADC_ANA_SHIFT (12) +#define CODEC_POL_DAC_OUT (1 << 17) +#define CODEC_CFG_CLK_OUT(n) (((n) & 0x7) << 18) +#define CODEC_CFG_CLK_OUT_MASK (0x7 << 18) +#define CODEC_CFG_CLK_OUT_SHIFT (18) + +// reg_64 +#define CODEC_SOFT_RSTN_ADC_ANA(n) (((n) & 0x1F) << 0) +#define CODEC_SOFT_RSTN_ADC_ANA_MASK (0x1F << 0) +#define CODEC_SOFT_RSTN_ADC_ANA_SHIFT (0) +#define CODEC_SOFT_RSTN_ADC(n) (((n) & 0x3F) << 5) +#define CODEC_SOFT_RSTN_ADC_MASK (0x3F << 5) +#define CODEC_SOFT_RSTN_ADC_SHIFT (5) +#define CODEC_SOFT_RSTN_DAC (1 << 11) +#define CODEC_SOFT_RSTN_RS (1 << 12) +#define CODEC_SOFT_RSTN_IIR (1 << 13) +#define CODEC_SOFT_RSTN_32K (1 << 14) + +// reg_68 +#define CODEC_RET1N_RF (1 << 0) +#define CODEC_RET2N_RF (1 << 1) +#define CODEC_PGEN_RF (1 << 2) +#define CODEC_EMA_RF(n) (((n) & 0x7) << 3) +#define CODEC_EMA_RF_MASK (0x7 << 3) +#define CODEC_EMA_RF_SHIFT (3) +#define CODEC_EMAW_RF(n) (((n) & 0x3) << 6) +#define CODEC_EMAW_RF_MASK (0x3 << 6) +#define CODEC_EMAW_RF_SHIFT (6) +#define CODEC_EMAS_RF (1 << 8) +#define CODEC_WABL_RF (1 << 9) +#define CODEC_WABLM_RF(n) (((n) & 0x3) << 10) +#define CODEC_WABLM_RF_MASK (0x3 << 10) +#define CODEC_WABLM_RF_SHIFT (10) +#define CODEC_RET1N_SRAM (1 << 12) +#define CODEC_RET2N_SRAM (1 << 13) +#define CODEC_PGEN_SRAM (1 << 14) +#define CODEC_EMA_SRAM(n) (((n) & 0x7) << 15) +#define CODEC_EMA_SRAM_MASK (0x7 << 15) +#define CODEC_EMA_SRAM_SHIFT (15) +#define CODEC_EMAW_SRAM(n) (((n) & 0x3) << 18) +#define CODEC_EMAW_SRAM_MASK (0x3 << 18) +#define CODEC_EMAW_SRAM_SHIFT (18) +#define CODEC_EMAS_SRAM (1 << 20) +#define CODEC_WABL_SRAM (1 << 21) +#define CODEC_WABLM_SRAM(n) (((n) & 0x3) << 22) +#define CODEC_WABLM_SRAM_MASK (0x3 << 22) +#define CODEC_WABLM_SRAM_SHIFT (22) +#define CODEC_EMA_ROM(n) (((n) & 0x7) << 24) +#define CODEC_EMA_ROM_MASK (0x7 << 24) +#define CODEC_EMA_ROM_SHIFT (24) +#define CODEC_KEN_ROM (1 << 27) +#define CODEC_PGEN_ROM_0 (1 << 28) +#define CODEC_PGEN_ROM_1 (1 << 29) + +// reg_6c +#define CODEC_CODEC_RX5_6_OVERFLOW(n) (((n) & 0x3) << 0) +#define CODEC_CODEC_RX5_6_OVERFLOW_MASK (0x3 << 0) +#define CODEC_CODEC_RX5_6_OVERFLOW_SHIFT (0) +#define CODEC_CODEC_RX5_6_UNDERFLOW(n) (((n) & 0x3) << 2) +#define CODEC_CODEC_RX5_6_UNDERFLOW_MASK (0x3 << 2) +#define CODEC_CODEC_RX5_6_UNDERFLOW_SHIFT (2) + +// reg_70 +#define CODEC_CODEC_RX5_6_OVERFLOW_MSK(n) (((n) & 0x3) << 0) +#define CODEC_CODEC_RX5_6_OVERFLOW_MSK_MASK (0x3 << 0) +#define CODEC_CODEC_RX5_6_OVERFLOW_MSK_SHIFT (0) +#define CODEC_CODEC_RX5_6_UNDERFLOW_MSK(n) (((n) & 0x3) << 2) +#define CODEC_CODEC_RX5_6_UNDERFLOW_MSK_MASK (0x3 << 2) +#define CODEC_CODEC_RX5_6_UNDERFLOW_MSK_SHIFT (2) + +// reg_78 +#define CODEC_CODEC_SIDE_TONE_CH_SEL (1 << 0) +#define CODEC_CODEC_ADC_IIR_CH0_SEL(n) (((n) & 0x7) << 1) +#define CODEC_CODEC_ADC_IIR_CH0_SEL_MASK (0x7 << 1) +#define CODEC_CODEC_ADC_IIR_CH0_SEL_SHIFT (1) +#define CODEC_CODEC_ADC_IIR_CH1_SEL(n) (((n) & 0x7) << 4) +#define CODEC_CODEC_ADC_IIR_CH1_SEL_MASK (0x7 << 4) +#define CODEC_CODEC_ADC_IIR_CH1_SEL_SHIFT (4) +#define CODEC_CODEC_DAC_HBF4_DELAY_SEL (1 << 7) +#define CODEC_TRIG_TIME(n) (((n) & 0x3FFFFF) << 8) +#define CODEC_TRIG_TIME_MASK (0x3FFFFF << 8) +#define CODEC_TRIG_TIME_SHIFT (8) +#define CODEC_TRIG_TIME_ENABLE (1 << 30) +#define CODEC_GET_CNT_TRIG (1 << 31) + +// reg_7c +#define CODEC_RESERVED_REG1(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_RESERVED_REG1_MASK (0xFFFFFFFF << 0) +#define CODEC_RESERVED_REG1_SHIFT (0) + +// reg_80 +#define CODEC_CODEC_ADC_EN (1 << 0) +#define CODEC_CODEC_ADC_EN_CH0 (1 << 1) +#define CODEC_CODEC_ADC_EN_CH1 (1 << 2) +#define CODEC_CODEC_ADC_EN_CH2 (1 << 3) +#define CODEC_CODEC_ADC_EN_CH3 (1 << 4) +#define CODEC_CODEC_ADC_EN_CH4 (1 << 5) +#define CODEC_CODEC_SIDE_TONE_GAIN(n) (((n) & 0x1F) << 6) +#define CODEC_CODEC_SIDE_TONE_GAIN_MASK (0x1F << 6) +#define CODEC_CODEC_SIDE_TONE_GAIN_SHIFT (6) +#define CODEC_CODEC_SIDE_TONE_MIC_SEL (1 << 11) +#define CODEC_CODEC_ADC_LOOP (1 << 12) +#define CODEC_CODEC_LOOP_SEL_L(n) (((n) & 0x7) << 13) +#define CODEC_CODEC_LOOP_SEL_L_MASK (0x7 << 13) +#define CODEC_CODEC_LOOP_SEL_L_SHIFT (13) +#define CODEC_CODEC_LOOP_SEL_R(n) (((n) & 0x7) << 16) +#define CODEC_CODEC_LOOP_SEL_R_MASK (0x7 << 16) +#define CODEC_CODEC_LOOP_SEL_R_SHIFT (16) +#define CODEC_CODEC_TEST_PORT_SEL(n) (((n) & 0x1F) << 19) +#define CODEC_CODEC_TEST_PORT_SEL_MASK (0x1F << 19) +#define CODEC_CODEC_TEST_PORT_SEL_SHIFT (19) + +// reg_84 +#define CODEC_CODEC_ADC_SIGNED_CH0 (1 << 0) +#define CODEC_CODEC_ADC_IN_SEL_CH0(n) (((n) & 0x7) << 1) +#define CODEC_CODEC_ADC_IN_SEL_CH0_MASK (0x7 << 1) +#define CODEC_CODEC_ADC_IN_SEL_CH0_SHIFT (1) +#define CODEC_CODEC_ADC_DOWN_SEL_CH0(n) (((n) & 0x3) << 4) +#define CODEC_CODEC_ADC_DOWN_SEL_CH0_MASK (0x3 << 4) +#define CODEC_CODEC_ADC_DOWN_SEL_CH0_SHIFT (4) +#define CODEC_CODEC_ADC_HBF3_BYPASS_CH0 (1 << 6) +#define CODEC_CODEC_ADC_HBF2_BYPASS_CH0 (1 << 7) +#define CODEC_CODEC_ADC_HBF1_BYPASS_CH0 (1 << 8) +#define CODEC_CODEC_ADC_GAIN_SEL_CH0 (1 << 9) +#define CODEC_CODEC_ADC_GAIN_CH0(n) (((n) & 0xFFFFF) << 10) +#define CODEC_CODEC_ADC_GAIN_CH0_MASK (0xFFFFF << 10) +#define CODEC_CODEC_ADC_GAIN_CH0_SHIFT (10) +#define CODEC_CODEC_ADC_HBF3_SEL_CH0(n) (((n) & 0x3) << 30) +#define CODEC_CODEC_ADC_HBF3_SEL_CH0_MASK (0x3 << 30) +#define CODEC_CODEC_ADC_HBF3_SEL_CH0_SHIFT (30) + +// reg_88 +#define CODEC_CODEC_ADC_SIGNED_CH1 (1 << 0) +#define CODEC_CODEC_ADC_IN_SEL_CH1(n) (((n) & 0x7) << 1) +#define CODEC_CODEC_ADC_IN_SEL_CH1_MASK (0x7 << 1) +#define CODEC_CODEC_ADC_IN_SEL_CH1_SHIFT (1) +#define CODEC_CODEC_ADC_DOWN_SEL_CH1(n) (((n) & 0x3) << 4) +#define CODEC_CODEC_ADC_DOWN_SEL_CH1_MASK (0x3 << 4) +#define CODEC_CODEC_ADC_DOWN_SEL_CH1_SHIFT (4) +#define CODEC_CODEC_ADC_HBF3_BYPASS_CH1 (1 << 6) +#define CODEC_CODEC_ADC_HBF2_BYPASS_CH1 (1 << 7) +#define CODEC_CODEC_ADC_HBF1_BYPASS_CH1 (1 << 8) +#define CODEC_CODEC_ADC_GAIN_SEL_CH1 (1 << 9) +#define CODEC_CODEC_ADC_GAIN_CH1(n) (((n) & 0xFFFFF) << 10) +#define CODEC_CODEC_ADC_GAIN_CH1_MASK (0xFFFFF << 10) +#define CODEC_CODEC_ADC_GAIN_CH1_SHIFT (10) +#define CODEC_CODEC_ADC_HBF3_SEL_CH1(n) (((n) & 0x3) << 30) +#define CODEC_CODEC_ADC_HBF3_SEL_CH1_MASK (0x3 << 30) +#define CODEC_CODEC_ADC_HBF3_SEL_CH1_SHIFT (30) + +// reg_8c +#define CODEC_CODEC_ADC_SIGNED_CH2 (1 << 0) +#define CODEC_CODEC_ADC_IN_SEL_CH2(n) (((n) & 0x7) << 1) +#define CODEC_CODEC_ADC_IN_SEL_CH2_MASK (0x7 << 1) +#define CODEC_CODEC_ADC_IN_SEL_CH2_SHIFT (1) +#define CODEC_CODEC_ADC_DOWN_SEL_CH2(n) (((n) & 0x3) << 4) +#define CODEC_CODEC_ADC_DOWN_SEL_CH2_MASK (0x3 << 4) +#define CODEC_CODEC_ADC_DOWN_SEL_CH2_SHIFT (4) +#define CODEC_CODEC_ADC_HBF3_BYPASS_CH2 (1 << 6) +#define CODEC_CODEC_ADC_HBF2_BYPASS_CH2 (1 << 7) +#define CODEC_CODEC_ADC_HBF1_BYPASS_CH2 (1 << 8) +#define CODEC_CODEC_ADC_GAIN_SEL_CH2 (1 << 9) +#define CODEC_CODEC_ADC_GAIN_CH2(n) (((n) & 0xFFFFF) << 10) +#define CODEC_CODEC_ADC_GAIN_CH2_MASK (0xFFFFF << 10) +#define CODEC_CODEC_ADC_GAIN_CH2_SHIFT (10) +#define CODEC_CODEC_ADC_HBF3_SEL_CH2(n) (((n) & 0x3) << 30) +#define CODEC_CODEC_ADC_HBF3_SEL_CH2_MASK (0x3 << 30) +#define CODEC_CODEC_ADC_HBF3_SEL_CH2_SHIFT (30) + +// reg_90 +#define CODEC_CODEC_ADC_SIGNED_CH3 (1 << 0) +#define CODEC_CODEC_ADC_IN_SEL_CH3(n) (((n) & 0x7) << 1) +#define CODEC_CODEC_ADC_IN_SEL_CH3_MASK (0x7 << 1) +#define CODEC_CODEC_ADC_IN_SEL_CH3_SHIFT (1) +#define CODEC_CODEC_ADC_DOWN_SEL_CH3(n) (((n) & 0x3) << 4) +#define CODEC_CODEC_ADC_DOWN_SEL_CH3_MASK (0x3 << 4) +#define CODEC_CODEC_ADC_DOWN_SEL_CH3_SHIFT (4) +#define CODEC_CODEC_ADC_HBF3_BYPASS_CH3 (1 << 6) +#define CODEC_CODEC_ADC_HBF2_BYPASS_CH3 (1 << 7) +#define CODEC_CODEC_ADC_HBF1_BYPASS_CH3 (1 << 8) +#define CODEC_CODEC_ADC_GAIN_SEL_CH3 (1 << 9) +#define CODEC_CODEC_ADC_GAIN_CH3(n) (((n) & 0xFFFFF) << 10) +#define CODEC_CODEC_ADC_GAIN_CH3_MASK (0xFFFFF << 10) +#define CODEC_CODEC_ADC_GAIN_CH3_SHIFT (10) +#define CODEC_CODEC_ADC_HBF3_SEL_CH3(n) (((n) & 0x3) << 30) +#define CODEC_CODEC_ADC_HBF3_SEL_CH3_MASK (0x3 << 30) +#define CODEC_CODEC_ADC_HBF3_SEL_CH3_SHIFT (30) + +// reg_94 +#define CODEC_CODEC_ADC_SIGNED_CH4 (1 << 0) +#define CODEC_CODEC_ADC_IN_SEL_CH4(n) (((n) & 0x7) << 1) +#define CODEC_CODEC_ADC_IN_SEL_CH4_MASK (0x7 << 1) +#define CODEC_CODEC_ADC_IN_SEL_CH4_SHIFT (1) +#define CODEC_CODEC_ADC_DOWN_SEL_CH4(n) (((n) & 0x3) << 4) +#define CODEC_CODEC_ADC_DOWN_SEL_CH4_MASK (0x3 << 4) +#define CODEC_CODEC_ADC_DOWN_SEL_CH4_SHIFT (4) +#define CODEC_CODEC_ADC_HBF3_BYPASS_CH4 (1 << 6) +#define CODEC_CODEC_ADC_HBF2_BYPASS_CH4 (1 << 7) +#define CODEC_CODEC_ADC_HBF1_BYPASS_CH4 (1 << 8) +#define CODEC_CODEC_ADC_GAIN_SEL_CH4 (1 << 9) +#define CODEC_CODEC_ADC_GAIN_CH4(n) (((n) & 0xFFFFF) << 10) +#define CODEC_CODEC_ADC_GAIN_CH4_MASK (0xFFFFF << 10) +#define CODEC_CODEC_ADC_GAIN_CH4_SHIFT (10) +#define CODEC_CODEC_ADC_HBF3_SEL_CH4(n) (((n) & 0x3) << 30) +#define CODEC_CODEC_ADC_HBF3_SEL_CH4_MASK (0x3 << 30) +#define CODEC_CODEC_ADC_HBF3_SEL_CH4_SHIFT (30) + +// reg_98 +#define CODEC_CODEC_DAC_EN (1 << 0) +#define CODEC_CODEC_DAC_EN_CH0 (1 << 1) +#define CODEC_CODEC_DAC_EN_CH1 (1 << 2) +#define CODEC_CODEC_DAC_DITHER_GAIN(n) (((n) & 0x1F) << 3) +#define CODEC_CODEC_DAC_DITHER_GAIN_MASK (0x1F << 3) +#define CODEC_CODEC_DAC_DITHER_GAIN_SHIFT (3) +#define CODEC_CODEC_DAC_SDM_GAIN(n) (((n) & 0x3) << 8) +#define CODEC_CODEC_DAC_SDM_GAIN_MASK (0x3 << 8) +#define CODEC_CODEC_DAC_SDM_GAIN_SHIFT (8) +#define CODEC_CODEC_DITHER_BYPASS (1 << 10) +#define CODEC_CODEC_DAC_HBF3_BYPASS (1 << 11) +#define CODEC_CODEC_DAC_HBF2_BYPASS (1 << 12) +#define CODEC_CODEC_DAC_HBF1_BYPASS (1 << 13) +#define CODEC_CODEC_DAC_UP_SEL(n) (((n) & 0x7) << 14) +#define CODEC_CODEC_DAC_UP_SEL_MASK (0x7 << 14) +#define CODEC_CODEC_DAC_UP_SEL_SHIFT (14) +#define CODEC_CODEC_DAC_TONE_TEST (1 << 17) +#define CODEC_CODEC_DAC_SIN1K_STEP(n) (((n) & 0xF) << 18) +#define CODEC_CODEC_DAC_SIN1K_STEP_MASK (0xF << 18) +#define CODEC_CODEC_DAC_SIN1K_STEP_SHIFT (18) +#define CODEC_CODEC_DAC_OSR_SEL(n) (((n) & 0x3) << 22) +#define CODEC_CODEC_DAC_OSR_SEL_MASK (0x3 << 22) +#define CODEC_CODEC_DAC_OSR_SEL_SHIFT (22) +#define CODEC_CODEC_DAC_LR_SWAP (1 << 24) +#define CODEC_CODEC_DAC_SDM_H4_6M_CH0 (1 << 25) +#define CODEC_CODEC_DAC_SDM_H4_6M_CH1 (1 << 26) +#define CODEC_CODEC_DAC_L_FIR_UPSAMPLE (1 << 27) +#define CODEC_CODEC_DAC_R_FIR_UPSAMPLE (1 << 28) +#define CODEC_CODEC_DAC_SDM_CLOSE (1 << 29) +#define CODEC_CODEC_DAC_USE_HBF4 (1 << 30) +#define CODEC_CODEC_DAC_USE_HBF5 (1 << 31) + +// reg_9c +#define CODEC_CODEC_DAC_GAIN_CH0(n) (((n) & 0xFFFFF) << 0) +#define CODEC_CODEC_DAC_GAIN_CH0_MASK (0xFFFFF << 0) +#define CODEC_CODEC_DAC_GAIN_CH0_SHIFT (0) +#define CODEC_CODEC_DAC_GAIN_SEL_CH0 (1 << 20) +#define CODEC_CODEC_DAC_GAIN_UPDATE (1 << 21) +#define CODEC_CODEC_ADC_GAIN_UPDATE_CH0 (1 << 22) +#define CODEC_CODEC_ADC_GAIN_UPDATE_CH1 (1 << 23) +#define CODEC_CODEC_ADC_GAIN_UPDATE_CH2 (1 << 24) +#define CODEC_CODEC_ADC_GAIN_UPDATE_CH3 (1 << 25) +#define CODEC_CODEC_ADC_GAIN_UPDATE_CH4 (1 << 26) +#define CODEC_CODEC_DAC_GAIN_TRIGGER_SEL(n) (((n) & 0x3) << 27) +#define CODEC_CODEC_DAC_GAIN_TRIGGER_SEL_MASK (0x3 << 27) +#define CODEC_CODEC_DAC_GAIN_TRIGGER_SEL_SHIFT (27) + +// reg_a0 +#define CODEC_CODEC_DAC_GAIN_CH1(n) (((n) & 0xFFFFF) << 0) +#define CODEC_CODEC_DAC_GAIN_CH1_MASK (0xFFFFF << 0) +#define CODEC_CODEC_DAC_GAIN_CH1_SHIFT (0) +#define CODEC_CODEC_DAC_GAIN_SEL_CH1 (1 << 20) +#define CODEC_CODEC_DAC_OUT_SWAP (1 << 21) +#define CODEC_CODEC_DAC_H4_DELAY_CH0(n) (((n) & 0x3) << 22) +#define CODEC_CODEC_DAC_H4_DELAY_CH0_MASK (0x3 << 22) +#define CODEC_CODEC_DAC_H4_DELAY_CH0_SHIFT (22) +#define CODEC_CODEC_DAC_L4_DELAY_CH0(n) (((n) & 0x3) << 24) +#define CODEC_CODEC_DAC_L4_DELAY_CH0_MASK (0x3 << 24) +#define CODEC_CODEC_DAC_L4_DELAY_CH0_SHIFT (24) +#define CODEC_CODEC_DAC_H4_DELAY_CH1(n) (((n) & 0x3) << 26) +#define CODEC_CODEC_DAC_H4_DELAY_CH1_MASK (0x3 << 26) +#define CODEC_CODEC_DAC_H4_DELAY_CH1_SHIFT (26) +#define CODEC_CODEC_DAC_L4_DELAY_CH1(n) (((n) & 0x3) << 28) +#define CODEC_CODEC_DAC_L4_DELAY_CH1_MASK (0x3 << 28) +#define CODEC_CODEC_DAC_L4_DELAY_CH1_SHIFT (28) + +// reg_a4 +#define CODEC_CODEC_PDM_ENABLE (1 << 0) +#define CODEC_CODEC_PDM_DATA_INV (1 << 1) +#define CODEC_CODEC_PDM_ADC_SEL_CH0 (1 << 2) +#define CODEC_CODEC_PDM_ADC_SEL_CH1 (1 << 3) +#define CODEC_CODEC_PDM_ADC_SEL_CH2 (1 << 4) +#define CODEC_CODEC_PDM_ADC_SEL_CH3 (1 << 5) +#define CODEC_CODEC_PDM_ADC_SEL_CH4 (1 << 6) + +// reg_a8 +#define CODEC_CODEC_PDM_MUX_CH0(n) (((n) & 0x7) << 0) +#define CODEC_CODEC_PDM_MUX_CH0_MASK (0x7 << 0) +#define CODEC_CODEC_PDM_MUX_CH0_SHIFT (0) +#define CODEC_CODEC_PDM_MUX_CH1(n) (((n) & 0x7) << 3) +#define CODEC_CODEC_PDM_MUX_CH1_MASK (0x7 << 3) +#define CODEC_CODEC_PDM_MUX_CH1_SHIFT (3) +#define CODEC_CODEC_PDM_MUX_CH2(n) (((n) & 0x7) << 6) +#define CODEC_CODEC_PDM_MUX_CH2_MASK (0x7 << 6) +#define CODEC_CODEC_PDM_MUX_CH2_SHIFT (6) +#define CODEC_CODEC_PDM_MUX_CH3(n) (((n) & 0x7) << 9) +#define CODEC_CODEC_PDM_MUX_CH3_MASK (0x7 << 9) +#define CODEC_CODEC_PDM_MUX_CH3_SHIFT (9) +#define CODEC_CODEC_PDM_MUX_CH4(n) (((n) & 0x7) << 12) +#define CODEC_CODEC_PDM_MUX_CH4_MASK (0x7 << 12) +#define CODEC_CODEC_PDM_MUX_CH4_SHIFT (12) +#define CODEC_CODEC_PDM_CAP_PHASE_CH0(n) (((n) & 0x3) << 15) +#define CODEC_CODEC_PDM_CAP_PHASE_CH0_MASK (0x3 << 15) +#define CODEC_CODEC_PDM_CAP_PHASE_CH0_SHIFT (15) +#define CODEC_CODEC_PDM_CAP_PHASE_CH1(n) (((n) & 0x3) << 17) +#define CODEC_CODEC_PDM_CAP_PHASE_CH1_MASK (0x3 << 17) +#define CODEC_CODEC_PDM_CAP_PHASE_CH1_SHIFT (17) +#define CODEC_CODEC_PDM_CAP_PHASE_CH2(n) (((n) & 0x3) << 19) +#define CODEC_CODEC_PDM_CAP_PHASE_CH2_MASK (0x3 << 19) +#define CODEC_CODEC_PDM_CAP_PHASE_CH2_SHIFT (19) +#define CODEC_CODEC_PDM_CAP_PHASE_CH3(n) (((n) & 0x3) << 21) +#define CODEC_CODEC_PDM_CAP_PHASE_CH3_MASK (0x3 << 21) +#define CODEC_CODEC_PDM_CAP_PHASE_CH3_SHIFT (21) +#define CODEC_CODEC_PDM_CAP_PHASE_CH4(n) (((n) & 0x3) << 23) +#define CODEC_CODEC_PDM_CAP_PHASE_CH4_MASK (0x3 << 23) +#define CODEC_CODEC_PDM_CAP_PHASE_CH4_SHIFT (23) + +// reg_b0 +#define CODEC_CODEC_CLASSG_EN (1 << 0) +#define CODEC_CODEC_CLASSG_QUICK_DOWN (1 << 1) +#define CODEC_CODEC_CLASSG_STEP_3_4N (1 << 2) +#define CODEC_CODEC_CLASSG_LR (1 << 3) +#define CODEC_CODEC_CLASSG_WINDOW(n) (((n) & 0xFFF) << 4) +#define CODEC_CODEC_CLASSG_WINDOW_MASK (0xFFF << 4) +#define CODEC_CODEC_CLASSG_WINDOW_SHIFT (4) + +// reg_b4 +#define CODEC_CODEC_CLASSG_THD0(n) (((n) & 0xFF) << 0) +#define CODEC_CODEC_CLASSG_THD0_MASK (0xFF << 0) +#define CODEC_CODEC_CLASSG_THD0_SHIFT (0) +#define CODEC_CODEC_CLASSG_THD1(n) (((n) & 0xFF) << 8) +#define CODEC_CODEC_CLASSG_THD1_MASK (0xFF << 8) +#define CODEC_CODEC_CLASSG_THD1_SHIFT (8) +#define CODEC_CODEC_CLASSG_THD2(n) (((n) & 0xFF) << 16) +#define CODEC_CODEC_CLASSG_THD2_MASK (0xFF << 16) +#define CODEC_CODEC_CLASSG_THD2_SHIFT (16) + +// reg_b8 +#define CODEC_CODEC_DSD_ENABLE_L (1 << 0) +#define CODEC_CODEC_DSD_ENABLE_R (1 << 1) +#define CODEC_CODEC_DSD_DATA_INV (1 << 2) +#define CODEC_CODEC_DSD_SAMPLE_RATE(n) (((n) & 0x3) << 3) +#define CODEC_CODEC_DSD_SAMPLE_RATE_MASK (0x3 << 3) +#define CODEC_CODEC_DSD_SAMPLE_RATE_SHIFT (3) + +// reg_bc +#define CODEC_CODEC_ADC_MC_EN_CH0 (1 << 0) +#define CODEC_CODEC_ADC_MC_EN_CH1 (1 << 1) +#define CODEC_CODEC_FEEDBACK_MC_EN_CH0 (1 << 2) +#define CODEC_CODEC_FEEDBACK_MC_EN_CH1 (1 << 3) + +// reg_c0 +#define CODEC_CODEC_DRE_ENABLE_CH0 (1 << 0) +#define CODEC_CODEC_DRE_STEP_MODE_CH0(n) (((n) & 0x3) << 1) +#define CODEC_CODEC_DRE_STEP_MODE_CH0_MASK (0x3 << 1) +#define CODEC_CODEC_DRE_STEP_MODE_CH0_SHIFT (1) +#define CODEC_CODEC_DRE_THD_DB_OFFSET_CH0(n) (((n) & 0xF) << 3) +#define CODEC_CODEC_DRE_THD_DB_OFFSET_CH0_MASK (0xF << 3) +#define CODEC_CODEC_DRE_THD_DB_OFFSET_CH0_SHIFT (3) +#define CODEC_CODEC_DRE_INI_ANA_GAIN_CH0(n) (((n) & 0xF) << 7) +#define CODEC_CODEC_DRE_INI_ANA_GAIN_CH0_MASK (0xF << 7) +#define CODEC_CODEC_DRE_INI_ANA_GAIN_CH0_SHIFT (7) +#define CODEC_CODEC_DRE_DELAY_CH0(n) (((n) & 0x3F) << 11) +#define CODEC_CODEC_DRE_DELAY_CH0_MASK (0x3F << 11) +#define CODEC_CODEC_DRE_DELAY_CH0_SHIFT (11) +#define CODEC_CODEC_DRE_THD_DB_OFFSET_SIGN_CH0 (1 << 17) +#define CODEC_CODEC_DRE_GAIN_OFFSET_CH0(n) (((n) & 0x7) << 18) +#define CODEC_CODEC_DRE_GAIN_OFFSET_CH0_MASK (0x7 << 18) +#define CODEC_CODEC_DRE_GAIN_OFFSET_CH0_SHIFT (18) + +// reg_c4 +#define CODEC_CODEC_DRE_AMP_HIGH_CH0(n) (((n) & 0x7FF) << 0) +#define CODEC_CODEC_DRE_AMP_HIGH_CH0_MASK (0x7FF << 0) +#define CODEC_CODEC_DRE_AMP_HIGH_CH0_SHIFT (0) +#define CODEC_CODEC_DRE_WINDOW_CH0(n) (((n) & 0x1FFFFF) << 11) +#define CODEC_CODEC_DRE_WINDOW_CH0_MASK (0x1FFFFF << 11) +#define CODEC_CODEC_DRE_WINDOW_CH0_SHIFT (11) + +// reg_c8 +#define CODEC_CODEC_DRE_ENABLE_CH1 (1 << 0) +#define CODEC_CODEC_DRE_STEP_MODE_CH1(n) (((n) & 0x3) << 1) +#define CODEC_CODEC_DRE_STEP_MODE_CH1_MASK (0x3 << 1) +#define CODEC_CODEC_DRE_STEP_MODE_CH1_SHIFT (1) +#define CODEC_CODEC_DRE_THD_DB_OFFSET_CH1(n) (((n) & 0xF) << 3) +#define CODEC_CODEC_DRE_THD_DB_OFFSET_CH1_MASK (0xF << 3) +#define CODEC_CODEC_DRE_THD_DB_OFFSET_CH1_SHIFT (3) +#define CODEC_CODEC_DRE_INI_ANA_GAIN_CH1(n) (((n) & 0xF) << 7) +#define CODEC_CODEC_DRE_INI_ANA_GAIN_CH1_MASK (0xF << 7) +#define CODEC_CODEC_DRE_INI_ANA_GAIN_CH1_SHIFT (7) +#define CODEC_CODEC_DRE_DELAY_CH1(n) (((n) & 0x3F) << 11) +#define CODEC_CODEC_DRE_DELAY_CH1_MASK (0x3F << 11) +#define CODEC_CODEC_DRE_DELAY_CH1_SHIFT (11) +#define CODEC_CODEC_DRE_THD_DB_OFFSET_SIGN_CH1 (1 << 17) +#define CODEC_CODEC_DRE_GAIN_OFFSET_CH1(n) (((n) & 0x7) << 18) +#define CODEC_CODEC_DRE_GAIN_OFFSET_CH1_MASK (0x7 << 18) +#define CODEC_CODEC_DRE_GAIN_OFFSET_CH1_SHIFT (18) + +// reg_cc +#define CODEC_CODEC_DRE_AMP_HIGH_CH1(n) (((n) & 0x7FF) << 0) +#define CODEC_CODEC_DRE_AMP_HIGH_CH1_MASK (0x7FF << 0) +#define CODEC_CODEC_DRE_AMP_HIGH_CH1_SHIFT (0) +#define CODEC_CODEC_DRE_WINDOW_CH1(n) (((n) & 0x1FFFFF) << 11) +#define CODEC_CODEC_DRE_WINDOW_CH1_MASK (0x1FFFFF << 11) +#define CODEC_CODEC_DRE_WINDOW_CH1_SHIFT (11) + +// reg_d0 +#define CODEC_CODEC_ANC_ENABLE_CH0 (1 << 0) +#define CODEC_CODEC_ANC_ENABLE_CH1 (1 << 1) +#define CODEC_CODEC_DUAL_ANC_CH0 (1 << 2) +#define CODEC_CODEC_DUAL_ANC_CH1 (1 << 3) +#define CODEC_CODEC_ANC_MUTE_CH0 (1 << 4) +#define CODEC_CODEC_ANC_MUTE_CH1 (1 << 5) +#define CODEC_CODEC_FF_CH0_FIR_EN (1 << 6) +#define CODEC_CODEC_FF_CH1_FIR_EN (1 << 7) +#define CODEC_CODEC_FB_CH0_FIR_EN (1 << 8) +#define CODEC_CODEC_FB_CH1_FIR_EN (1 << 9) +#define CODEC_CODEC_ANC_RATE_SEL (1 << 10) +#define CODEC_CODEC_ANC_FF_SR_SEL(n) (((n) & 0x3) << 11) +#define CODEC_CODEC_ANC_FF_SR_SEL_MASK (0x3 << 11) +#define CODEC_CODEC_ANC_FF_SR_SEL_SHIFT (11) +#define CODEC_CODEC_ANC_FF_IN_PHASE_SEL(n) (((n) & 0x7) << 13) +#define CODEC_CODEC_ANC_FF_IN_PHASE_SEL_MASK (0x7 << 13) +#define CODEC_CODEC_ANC_FF_IN_PHASE_SEL_SHIFT (13) +#define CODEC_CODEC_ANC_FB_SR_SEL(n) (((n) & 0x3) << 16) +#define CODEC_CODEC_ANC_FB_SR_SEL_MASK (0x3 << 16) +#define CODEC_CODEC_ANC_FB_SR_SEL_SHIFT (16) +#define CODEC_CODEC_ANC_FB_IN_PHASE_SEL(n) (((n) & 0x7) << 18) +#define CODEC_CODEC_ANC_FB_IN_PHASE_SEL_MASK (0x7 << 18) +#define CODEC_CODEC_ANC_FB_IN_PHASE_SEL_SHIFT (18) +#define CODEC_CODEC_FEEDBACK_CH0 (1 << 21) +#define CODEC_CODEC_FEEDBACK_CH1 (1 << 22) +#define CODEC_CODEC_ADC_FIR_DS_EN_CH2 (1 << 23) +#define CODEC_CODEC_ADC_FIR_DS_SEL_CH2 (1 << 24) +#define CODEC_CODEC_ADC_FIR_DS_EN_CH3 (1 << 25) +#define CODEC_CODEC_ADC_FIR_DS_SEL_CH3 (1 << 26) + +// reg_d4 +#define CODEC_CODEC_ANC_MUTE_GAIN_FF_CH0(n) (((n) & 0xFFF) << 0) +#define CODEC_CODEC_ANC_MUTE_GAIN_FF_CH0_MASK (0xFFF << 0) +#define CODEC_CODEC_ANC_MUTE_GAIN_FF_CH0_SHIFT (0) +#define CODEC_CODEC_ANC_MUTE_GAIN_FF_CH1(n) (((n) & 0xFFF) << 12) +#define CODEC_CODEC_ANC_MUTE_GAIN_FF_CH1_MASK (0xFFF << 12) +#define CODEC_CODEC_ANC_MUTE_GAIN_FF_CH1_SHIFT (12) +#define CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FF_CH0 (1 << 24) +#define CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FF_CH1 (1 << 25) + +// reg_d8 +#define CODEC_CODEC_ANC_MUTE_GAIN_FB_CH0(n) (((n) & 0xFFF) << 0) +#define CODEC_CODEC_ANC_MUTE_GAIN_FB_CH0_MASK (0xFFF << 0) +#define CODEC_CODEC_ANC_MUTE_GAIN_FB_CH0_SHIFT (0) +#define CODEC_CODEC_ANC_MUTE_GAIN_FB_CH1(n) (((n) & 0xFFF) << 12) +#define CODEC_CODEC_ANC_MUTE_GAIN_FB_CH1_MASK (0xFFF << 12) +#define CODEC_CODEC_ANC_MUTE_GAIN_FB_CH1_SHIFT (12) +#define CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FB_CH0 (1 << 24) +#define CODEC_CODEC_ANC_MUTE_GAIN_PASS0_FB_CH1 (1 << 25) + +// reg_dc +#define CODEC_CODEC_IIR_ENABLE (1 << 0) +#define CODEC_CODEC_IIR_CH0_BYPASS (1 << 1) +#define CODEC_CODEC_IIR_CH1_BYPASS (1 << 2) +#define CODEC_CODEC_IIR_CH2_BYPASS (1 << 3) +#define CODEC_CODEC_IIR_CH3_BYPASS (1 << 4) +#define CODEC_CODEC_IIR_COUNT_CH0(n) (((n) & 0xF) << 5) +#define CODEC_CODEC_IIR_COUNT_CH0_MASK (0xF << 5) +#define CODEC_CODEC_IIR_COUNT_CH0_SHIFT (5) +#define CODEC_CODEC_IIR_COUNT_CH1(n) (((n) & 0xF) << 9) +#define CODEC_CODEC_IIR_COUNT_CH1_MASK (0xF << 9) +#define CODEC_CODEC_IIR_COUNT_CH1_SHIFT (9) +#define CODEC_CODEC_IIR_COUNT_CH2(n) (((n) & 0xF) << 13) +#define CODEC_CODEC_IIR_COUNT_CH2_MASK (0xF << 13) +#define CODEC_CODEC_IIR_COUNT_CH2_SHIFT (13) +#define CODEC_CODEC_IIR_COUNT_CH3(n) (((n) & 0xF) << 17) +#define CODEC_CODEC_IIR_COUNT_CH3_MASK (0xF << 17) +#define CODEC_CODEC_IIR_COUNT_CH3_SHIFT (17) +#define CODEC_CODEC_DAC_L_IIR_ENABLE (1 << 21) +#define CODEC_CODEC_DAC_R_IIR_ENABLE (1 << 22) +#define CODEC_CODEC_ADC_CH0_IIR_ENABLE (1 << 23) +#define CODEC_CODEC_ADC_CH1_IIR_ENABLE (1 << 24) +#define CODEC_CODEC_IIR_COEF_SWAP (1 << 25) +#define CODEC_CODEC_IIR_COEF_SWAP_STATUS (1 << 26) + +// reg_e0 +#define CODEC_CODEC_DAC_DC_CH0(n) (((n) & 0x7FFFF) << 0) +#define CODEC_CODEC_DAC_DC_CH0_MASK (0x7FFFF << 0) +#define CODEC_CODEC_DAC_DC_CH0_SHIFT (0) +#define CODEC_CODEC_DAC_DC_UPDATE_CH0 (1 << 19) +#define CODEC_CODEC_DAC_ANA_GAIN_UPDATE_DELAY_CH0(n) (((n) & 0xFF) << 20) +#define CODEC_CODEC_DAC_ANA_GAIN_UPDATE_DELAY_CH0_MASK (0xFF << 20) +#define CODEC_CODEC_DAC_ANA_GAIN_UPDATE_DELAY_CH0_SHIFT (20) +#define CODEC_CODEC_DAC_DC_UPDATE_PASS0_CH0 (1 << 28) +#define CODEC_CODEC_DAC_DC_UPDATE_STATUS_CH0 (1 << 29) + +// reg_e4 +#define CODEC_CODEC_RESAMPLE_DAC_ENABLE (1 << 0) +#define CODEC_CODEC_RESAMPLE_DAC_L_ENABLE (1 << 1) +#define CODEC_CODEC_RESAMPLE_DAC_R_ENABLE (1 << 2) +#define CODEC_CODEC_RESAMPLE_ADC_ENABLE (1 << 3) +#define CODEC_CODEC_RESAMPLE_ADC_DUAL_CH (1 << 4) +#define CODEC_CODEC_RESAMPLE_ADC_CH0_SEL(n) (((n) & 0x7) << 5) +#define CODEC_CODEC_RESAMPLE_ADC_CH0_SEL_MASK (0x7 << 5) +#define CODEC_CODEC_RESAMPLE_ADC_CH0_SEL_SHIFT (5) +#define CODEC_CODEC_RESAMPLE_ADC_CH1_SEL(n) (((n) & 0x7) << 8) +#define CODEC_CODEC_RESAMPLE_ADC_CH1_SEL_MASK (0x7 << 8) +#define CODEC_CODEC_RESAMPLE_ADC_CH1_SEL_SHIFT (8) +#define CODEC_CODEC_RESAMPLE_DAC_PHASE_UPDATE (1 << 11) +#define CODEC_CODEC_RESAMPLE_DAC_TRIGGER_SEL(n) (((n) & 0x3) << 12) +#define CODEC_CODEC_RESAMPLE_DAC_TRIGGER_SEL_MASK (0x3 << 12) +#define CODEC_CODEC_RESAMPLE_DAC_TRIGGER_SEL_SHIFT (12) +#define CODEC_CODEC_RESAMPLE_ADC_PHASE_UPDATE (1 << 14) +#define CODEC_CODEC_RESAMPLE_ADC_TRIGGER_SEL(n) (((n) & 0x3) << 15) +#define CODEC_CODEC_RESAMPLE_ADC_TRIGGER_SEL_MASK (0x3 << 15) +#define CODEC_CODEC_RESAMPLE_ADC_TRIGGER_SEL_SHIFT (15) + +// reg_e8 +#define CODEC_CODEC_DAC_DC_CH1(n) (((n) & 0x7FFFF) << 0) +#define CODEC_CODEC_DAC_DC_CH1_MASK (0x7FFFF << 0) +#define CODEC_CODEC_DAC_DC_CH1_SHIFT (0) +#define CODEC_CODEC_DAC_DC_UPDATE_CH1 (1 << 19) +#define CODEC_CODEC_DAC_ANA_GAIN_UPDATE_DELAY_CH1(n) (((n) & 0xFF) << 20) +#define CODEC_CODEC_DAC_ANA_GAIN_UPDATE_DELAY_CH1_MASK (0xFF << 20) +#define CODEC_CODEC_DAC_ANA_GAIN_UPDATE_DELAY_CH1_SHIFT (20) +#define CODEC_CODEC_DAC_DC_UPDATE_PASS0_CH1 (1 << 28) +#define CODEC_CODEC_DAC_DC_UPDATE_STATUS_CH1 (1 << 29) + +// reg_ec +#define CODEC_CODEC_RAMP_STEP_CH0(n) (((n) & 0xFFF) << 0) +#define CODEC_CODEC_RAMP_STEP_CH0_MASK (0xFFF << 0) +#define CODEC_CODEC_RAMP_STEP_CH0_SHIFT (0) +#define CODEC_CODEC_RAMP_DIRECT_CH0 (1 << 12) +#define CODEC_CODEC_RAMP_EN_CH0 (1 << 13) +#define CODEC_CODEC_RAMP_INTERVAL_CH0(n) (((n) & 0x7) << 14) +#define CODEC_CODEC_RAMP_INTERVAL_CH0_MASK (0x7 << 14) +#define CODEC_CODEC_RAMP_INTERVAL_CH0_SHIFT (14) + +// reg_f0 +#define CODEC_CODEC_RAMP_STEP_CH1(n) (((n) & 0xFFF) << 0) +#define CODEC_CODEC_RAMP_STEP_CH1_MASK (0xFFF << 0) +#define CODEC_CODEC_RAMP_STEP_CH1_SHIFT (0) +#define CODEC_CODEC_RAMP_DIRECT_CH1 (1 << 12) +#define CODEC_CODEC_RAMP_EN_CH1 (1 << 13) +#define CODEC_CODEC_RAMP_INTERVAL_CH1(n) (((n) & 0x7) << 14) +#define CODEC_CODEC_RAMP_INTERVAL_CH1_MASK (0x7 << 14) +#define CODEC_CODEC_RAMP_INTERVAL_CH1_SHIFT (14) + +// reg_f4 +#define CODEC_CODEC_RESAMPLE_DAC_PHASE_INC(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_CODEC_RESAMPLE_DAC_PHASE_INC_MASK (0xFFFFFFFF << 0) +#define CODEC_CODEC_RESAMPLE_DAC_PHASE_INC_SHIFT (0) + +// reg_f8 +#define CODEC_CODEC_RESAMPLE_ADC_PHASE_INC(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_CODEC_RESAMPLE_ADC_PHASE_INC_MASK (0xFFFFFFFF << 0) +#define CODEC_CODEC_RESAMPLE_ADC_PHASE_INC_SHIFT (0) + +// reg_100 +#define CODEC_FIR_STREAM_ENABLE_CH0 (1 << 0) +#define CODEC_FIR_STREAM_ENABLE_CH1 (1 << 1) +#define CODEC_FIR_STREAM_ENABLE_CH2 (1 << 2) +#define CODEC_FIR_STREAM_ENABLE_CH3 (1 << 3) +#define CODEC_FIR_ENABLE_CH0 (1 << 4) +#define CODEC_FIR_ENABLE_CH1 (1 << 5) +#define CODEC_FIR_ENABLE_CH2 (1 << 6) +#define CODEC_FIR_ENABLE_CH3 (1 << 7) +#define CODEC_DMA_CTRL_RX_FIR (1 << 8) +#define CODEC_DMA_CTRL_TX_FIR (1 << 9) +#define CODEC_FIR_UPSAMPLE_CH0 (1 << 10) +#define CODEC_FIR_UPSAMPLE_CH1 (1 << 11) +#define CODEC_FIR_UPSAMPLE_CH2 (1 << 12) +#define CODEC_FIR_UPSAMPLE_CH3 (1 << 13) +#define CODEC_MODE_32BIT_FIR (1 << 14) +#define CODEC_FIR_RESERVED_REG0 (1 << 15) +#define CODEC_MODE_16BIT_FIR_TX_CH0 (1 << 16) +#define CODEC_MODE_16BIT_FIR_RX_CH0 (1 << 17) +#define CODEC_MODE_16BIT_FIR_TX_CH1 (1 << 18) +#define CODEC_MODE_16BIT_FIR_RX_CH1 (1 << 19) +#define CODEC_MODE_16BIT_FIR_TX_CH2 (1 << 20) +#define CODEC_MODE_16BIT_FIR_RX_CH2 (1 << 21) +#define CODEC_MODE_16BIT_FIR_TX_CH3 (1 << 22) +#define CODEC_MODE_16BIT_FIR_RX_CH3 (1 << 23) + +// reg_104 +#define CODEC_FIR_ACCESS_OFFSET_CH0(n) (((n) & 0x7) << 0) +#define CODEC_FIR_ACCESS_OFFSET_CH0_MASK (0x7 << 0) +#define CODEC_FIR_ACCESS_OFFSET_CH0_SHIFT (0) +#define CODEC_FIR_ACCESS_OFFSET_CH1(n) (((n) & 0x7) << 3) +#define CODEC_FIR_ACCESS_OFFSET_CH1_MASK (0x7 << 3) +#define CODEC_FIR_ACCESS_OFFSET_CH1_SHIFT (3) +#define CODEC_FIR_ACCESS_OFFSET_CH2(n) (((n) & 0x7) << 6) +#define CODEC_FIR_ACCESS_OFFSET_CH2_MASK (0x7 << 6) +#define CODEC_FIR_ACCESS_OFFSET_CH2_SHIFT (6) +#define CODEC_FIR_ACCESS_OFFSET_CH3(n) (((n) & 0x7) << 9) +#define CODEC_FIR_ACCESS_OFFSET_CH3_MASK (0x7 << 9) +#define CODEC_FIR_ACCESS_OFFSET_CH3_SHIFT (9) + +// reg_108 +#define CODEC_STREAM0_FIR1_CH0 (1 << 0) +#define CODEC_FIR_MODE_CH0(n) (((n) & 0x3) << 1) +#define CODEC_FIR_MODE_CH0_MASK (0x3 << 1) +#define CODEC_FIR_MODE_CH0_SHIFT (1) +#define CODEC_FIR_ORDER_CH0(n) (((n) & 0x3FF) << 3) +#define CODEC_FIR_ORDER_CH0_MASK (0x3FF << 3) +#define CODEC_FIR_ORDER_CH0_SHIFT (3) +#define CODEC_FIR_SAMPLE_START_CH0(n) (((n) & 0x1FF) << 13) +#define CODEC_FIR_SAMPLE_START_CH0_MASK (0x1FF << 13) +#define CODEC_FIR_SAMPLE_START_CH0_SHIFT (13) +#define CODEC_FIR_SAMPLE_NUM_CH0(n) (((n) & 0x1FF) << 22) +#define CODEC_FIR_SAMPLE_NUM_CH0_MASK (0x1FF << 22) +#define CODEC_FIR_SAMPLE_NUM_CH0_SHIFT (22) +#define CODEC_FIR_DO_REMAP_CH0 (1 << 31) + +// reg_10c +#define CODEC_FIR_RESULT_BASE_ADDR_CH0(n) (((n) & 0x1FF) << 0) +#define CODEC_FIR_RESULT_BASE_ADDR_CH0_MASK (0x1FF << 0) +#define CODEC_FIR_RESULT_BASE_ADDR_CH0_SHIFT (0) +#define CODEC_FIR_SLIDE_OFFSET_CH0(n) (((n) & 0x3F) << 9) +#define CODEC_FIR_SLIDE_OFFSET_CH0_MASK (0x3F << 9) +#define CODEC_FIR_SLIDE_OFFSET_CH0_SHIFT (9) +#define CODEC_FIR_BURST_LENGTH_CH0(n) (((n) & 0x3F) << 15) +#define CODEC_FIR_BURST_LENGTH_CH0_MASK (0x3F << 15) +#define CODEC_FIR_BURST_LENGTH_CH0_SHIFT (15) +#define CODEC_FIR_GAIN_SEL_CH0(n) (((n) & 0xF) << 21) +#define CODEC_FIR_GAIN_SEL_CH0_MASK (0xF << 21) +#define CODEC_FIR_GAIN_SEL_CH0_SHIFT (21) +#define CODEC_FIR_LOOP_NUM_CH0(n) (((n) & 0x7F) << 25) +#define CODEC_FIR_LOOP_NUM_CH0_MASK (0x7F << 25) +#define CODEC_FIR_LOOP_NUM_CH0_SHIFT (25) + +// reg_110 +#define CODEC_STREAM0_FIR1_CH1 (1 << 0) +#define CODEC_FIR_MODE_CH1(n) (((n) & 0x3) << 1) +#define CODEC_FIR_MODE_CH1_MASK (0x3 << 1) +#define CODEC_FIR_MODE_CH1_SHIFT (1) +#define CODEC_FIR_ORDER_CH1(n) (((n) & 0x3FF) << 3) +#define CODEC_FIR_ORDER_CH1_MASK (0x3FF << 3) +#define CODEC_FIR_ORDER_CH1_SHIFT (3) +#define CODEC_FIR_SAMPLE_START_CH1(n) (((n) & 0x1FF) << 13) +#define CODEC_FIR_SAMPLE_START_CH1_MASK (0x1FF << 13) +#define CODEC_FIR_SAMPLE_START_CH1_SHIFT (13) +#define CODEC_FIR_SAMPLE_NUM_CH1(n) (((n) & 0x1FF) << 22) +#define CODEC_FIR_SAMPLE_NUM_CH1_MASK (0x1FF << 22) +#define CODEC_FIR_SAMPLE_NUM_CH1_SHIFT (22) +#define CODEC_FIR_DO_REMAP_CH1 (1 << 31) + +// reg_114 +#define CODEC_FIR_RESULT_BASE_ADDR_CH1(n) (((n) & 0x1FF) << 0) +#define CODEC_FIR_RESULT_BASE_ADDR_CH1_MASK (0x1FF << 0) +#define CODEC_FIR_RESULT_BASE_ADDR_CH1_SHIFT (0) +#define CODEC_FIR_SLIDE_OFFSET_CH1(n) (((n) & 0x3F) << 9) +#define CODEC_FIR_SLIDE_OFFSET_CH1_MASK (0x3F << 9) +#define CODEC_FIR_SLIDE_OFFSET_CH1_SHIFT (9) +#define CODEC_FIR_BURST_LENGTH_CH1(n) (((n) & 0x3F) << 15) +#define CODEC_FIR_BURST_LENGTH_CH1_MASK (0x3F << 15) +#define CODEC_FIR_BURST_LENGTH_CH1_SHIFT (15) +#define CODEC_FIR_GAIN_SEL_CH1(n) (((n) & 0xF) << 21) +#define CODEC_FIR_GAIN_SEL_CH1_MASK (0xF << 21) +#define CODEC_FIR_GAIN_SEL_CH1_SHIFT (21) +#define CODEC_FIR_LOOP_NUM_CH1(n) (((n) & 0x7F) << 25) +#define CODEC_FIR_LOOP_NUM_CH1_MASK (0x7F << 25) +#define CODEC_FIR_LOOP_NUM_CH1_SHIFT (25) + +// reg_118 +#define CODEC_STREAM0_FIR1_CH2 (1 << 0) +#define CODEC_FIR_MODE_CH2(n) (((n) & 0x3) << 1) +#define CODEC_FIR_MODE_CH2_MASK (0x3 << 1) +#define CODEC_FIR_MODE_CH2_SHIFT (1) +#define CODEC_FIR_ORDER_CH2(n) (((n) & 0x3FF) << 3) +#define CODEC_FIR_ORDER_CH2_MASK (0x3FF << 3) +#define CODEC_FIR_ORDER_CH2_SHIFT (3) +#define CODEC_FIR_SAMPLE_START_CH2(n) (((n) & 0x1FF) << 13) +#define CODEC_FIR_SAMPLE_START_CH2_MASK (0x1FF << 13) +#define CODEC_FIR_SAMPLE_START_CH2_SHIFT (13) +#define CODEC_FIR_SAMPLE_NUM_CH2(n) (((n) & 0x1FF) << 22) +#define CODEC_FIR_SAMPLE_NUM_CH2_MASK (0x1FF << 22) +#define CODEC_FIR_SAMPLE_NUM_CH2_SHIFT (22) +#define CODEC_FIR_DO_REMAP_CH2 (1 << 31) + +// reg_11c +#define CODEC_FIR_RESULT_BASE_ADDR_CH2(n) (((n) & 0x1FF) << 0) +#define CODEC_FIR_RESULT_BASE_ADDR_CH2_MASK (0x1FF << 0) +#define CODEC_FIR_RESULT_BASE_ADDR_CH2_SHIFT (0) +#define CODEC_FIR_SLIDE_OFFSET_CH2(n) (((n) & 0x3F) << 9) +#define CODEC_FIR_SLIDE_OFFSET_CH2_MASK (0x3F << 9) +#define CODEC_FIR_SLIDE_OFFSET_CH2_SHIFT (9) +#define CODEC_FIR_BURST_LENGTH_CH2(n) (((n) & 0x3F) << 15) +#define CODEC_FIR_BURST_LENGTH_CH2_MASK (0x3F << 15) +#define CODEC_FIR_BURST_LENGTH_CH2_SHIFT (15) +#define CODEC_FIR_GAIN_SEL_CH2(n) (((n) & 0xF) << 21) +#define CODEC_FIR_GAIN_SEL_CH2_MASK (0xF << 21) +#define CODEC_FIR_GAIN_SEL_CH2_SHIFT (21) +#define CODEC_FIR_LOOP_NUM_CH2(n) (((n) & 0x7F) << 25) +#define CODEC_FIR_LOOP_NUM_CH2_MASK (0x7F << 25) +#define CODEC_FIR_LOOP_NUM_CH2_SHIFT (25) + +// reg_120 +#define CODEC_STREAM0_FIR1_CH3 (1 << 0) +#define CODEC_FIR_MODE_CH3(n) (((n) & 0x3) << 1) +#define CODEC_FIR_MODE_CH3_MASK (0x3 << 1) +#define CODEC_FIR_MODE_CH3_SHIFT (1) +#define CODEC_FIR_ORDER_CH3(n) (((n) & 0x3FF) << 3) +#define CODEC_FIR_ORDER_CH3_MASK (0x3FF << 3) +#define CODEC_FIR_ORDER_CH3_SHIFT (3) +#define CODEC_FIR_SAMPLE_START_CH3(n) (((n) & 0x1FF) << 13) +#define CODEC_FIR_SAMPLE_START_CH3_MASK (0x1FF << 13) +#define CODEC_FIR_SAMPLE_START_CH3_SHIFT (13) +#define CODEC_FIR_SAMPLE_NUM_CH3(n) (((n) & 0x1FF) << 22) +#define CODEC_FIR_SAMPLE_NUM_CH3_MASK (0x1FF << 22) +#define CODEC_FIR_SAMPLE_NUM_CH3_SHIFT (22) +#define CODEC_FIR_DO_REMAP_CH3 (1 << 31) + +// reg_124 +#define CODEC_FIR_RESULT_BASE_ADDR_CH3(n) (((n) & 0x1FF) << 0) +#define CODEC_FIR_RESULT_BASE_ADDR_CH3_MASK (0x1FF << 0) +#define CODEC_FIR_RESULT_BASE_ADDR_CH3_SHIFT (0) +#define CODEC_FIR_SLIDE_OFFSET_CH3(n) (((n) & 0x3F) << 9) +#define CODEC_FIR_SLIDE_OFFSET_CH3_MASK (0x3F << 9) +#define CODEC_FIR_SLIDE_OFFSET_CH3_SHIFT (9) +#define CODEC_FIR_BURST_LENGTH_CH3(n) (((n) & 0x3F) << 15) +#define CODEC_FIR_BURST_LENGTH_CH3_MASK (0x3F << 15) +#define CODEC_FIR_BURST_LENGTH_CH3_SHIFT (15) +#define CODEC_FIR_GAIN_SEL_CH3(n) (((n) & 0xF) << 21) +#define CODEC_FIR_GAIN_SEL_CH3_MASK (0xF << 21) +#define CODEC_FIR_GAIN_SEL_CH3_SHIFT (21) +#define CODEC_FIR_LOOP_NUM_CH3(n) (((n) & 0x7F) << 25) +#define CODEC_FIR_LOOP_NUM_CH3_MASK (0x7F << 25) +#define CODEC_FIR_LOOP_NUM_CH3_SHIFT (25) + +// reg_128 +#define CODEC_AHB_IIR_ENABLE (1 << 0) +#define CODEC_DO_SAMPLE_INI (1 << 1) +#define CODEC_USE_SAMPLE_HIGH_HALF (1 << 2) +#define CODEC_AHB_IIR_IF_EN (1 << 3) +#define CODEC_DMA_CTRL_RX_IIR (1 << 4) +#define CODEC_DMA_CTRL_TX_IIR (1 << 5) +#define CODEC_MODE_32BIT_IIR (1 << 6) +#define CODEC_MODE_16BIT_IIR (1 << 7) +#define CODEC_AHB_IIR_MAX_CNT(n) (((n) & 0xF) << 8) +#define CODEC_AHB_IIR_MAX_CNT_MASK (0xF << 8) +#define CODEC_AHB_IIR_MAX_CNT_SHIFT (8) +#define CODEC_IIR_MULTI_CYCLE_MODE(n) (((n) & 0x3) << 12) +#define CODEC_IIR_MULTI_CYCLE_MODE_MASK (0x3 << 12) +#define CODEC_IIR_MULTI_CYCLE_MODE_SHIFT (12) + +// reg_130 +#define CODEC_CODEC_FB_CHECK_ENABLE_CH0 (1 << 0) +#define CODEC_CODEC_FB_CHECK_ACC_SAMPLE_RATE_CH0(n) (((n) & 0x3) << 1) +#define CODEC_CODEC_FB_CHECK_ACC_SAMPLE_RATE_CH0_MASK (0x3 << 1) +#define CODEC_CODEC_FB_CHECK_ACC_SAMPLE_RATE_CH0_SHIFT (1) +#define CODEC_CODEC_FB_CHECK_SRC_SEL_CH0(n) (((n) & 0x3) << 3) +#define CODEC_CODEC_FB_CHECK_SRC_SEL_CH0_MASK (0x3 << 3) +#define CODEC_CODEC_FB_CHECK_SRC_SEL_CH0_SHIFT (3) +#define CODEC_CODEC_FB_CHECK_KEEP_SEL_CH0 (1 << 5) +#define CODEC_CODEC_FB_CHECK_ACC_WINDOW_CH0(n) (((n) & 0xFFF) << 6) +#define CODEC_CODEC_FB_CHECK_ACC_WINDOW_CH0_MASK (0xFFF << 6) +#define CODEC_CODEC_FB_CHECK_ACC_WINDOW_CH0_SHIFT (6) +#define CODEC_CODEC_FB_CHECK_TRIG_WINDOW_CH0(n) (((n) & 0x3FF) << 18) +#define CODEC_CODEC_FB_CHECK_TRIG_WINDOW_CH0_MASK (0x3FF << 18) +#define CODEC_CODEC_FB_CHECK_TRIG_WINDOW_CH0_SHIFT (18) +#define CODEC_CODEC_FB_CHECK_KEEP_CH0 (1 << 28) + +// reg_134 +#define CODEC_CODEC_FB_CHECK_ENABLE_CH1 (1 << 0) +#define CODEC_CODEC_FB_CHECK_ACC_SAMPLE_RATE_CH1(n) (((n) & 0x3) << 1) +#define CODEC_CODEC_FB_CHECK_ACC_SAMPLE_RATE_CH1_MASK (0x3 << 1) +#define CODEC_CODEC_FB_CHECK_ACC_SAMPLE_RATE_CH1_SHIFT (1) +#define CODEC_CODEC_FB_CHECK_SRC_SEL_CH1(n) (((n) & 0x3) << 3) +#define CODEC_CODEC_FB_CHECK_SRC_SEL_CH1_MASK (0x3 << 3) +#define CODEC_CODEC_FB_CHECK_SRC_SEL_CH1_SHIFT (3) +#define CODEC_CODEC_FB_CHECK_KEEP_SEL_CH1 (1 << 5) +#define CODEC_CODEC_FB_CHECK_ACC_WINDOW_CH1(n) (((n) & 0xFFF) << 6) +#define CODEC_CODEC_FB_CHECK_ACC_WINDOW_CH1_MASK (0xFFF << 6) +#define CODEC_CODEC_FB_CHECK_ACC_WINDOW_CH1_SHIFT (6) +#define CODEC_CODEC_FB_CHECK_TRIG_WINDOW_CH1(n) (((n) & 0x3FF) << 18) +#define CODEC_CODEC_FB_CHECK_TRIG_WINDOW_CH1_MASK (0x3FF << 18) +#define CODEC_CODEC_FB_CHECK_TRIG_WINDOW_CH1_SHIFT (18) +#define CODEC_CODEC_FB_CHECK_KEEP_CH1 (1 << 28) + +// reg_138 +#define CODEC_CODEC_FB_CHECK_THRESHOLD_CH0(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_CODEC_FB_CHECK_THRESHOLD_CH0_MASK (0xFFFFFFFF << 0) +#define CODEC_CODEC_FB_CHECK_THRESHOLD_CH0_SHIFT (0) + +// reg_13c +#define CODEC_CODEC_FB_CHECK_THRESHOLD_CH1(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_CODEC_FB_CHECK_THRESHOLD_CH1_MASK (0xFFFFFFFF << 0) +#define CODEC_CODEC_FB_CHECK_THRESHOLD_CH1_SHIFT (0) + +// reg_140 +#define CODEC_CODEC_FB_CHECK_DATA_AVG_KEEP_CH0(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_CODEC_FB_CHECK_DATA_AVG_KEEP_CH0_MASK (0xFFFFFFFF << 0) +#define CODEC_CODEC_FB_CHECK_DATA_AVG_KEEP_CH0_SHIFT (0) + +// reg_144 +#define CODEC_CODEC_FB_CHECK_DATA_AVG_KEEP_CH1(n) (((n) & 0xFFFFFFFF) << 0) +#define CODEC_CODEC_FB_CHECK_DATA_AVG_KEEP_CH1_MASK (0xFFFFFFFF << 0) +#define CODEC_CODEC_FB_CHECK_DATA_AVG_KEEP_CH1_SHIFT (0) + +// reg_148 +#define CODEC_VAD_EN (1 << 0) +#define CODEC_VAD_DS_BYPASS (1 << 1) +#define CODEC_VAD_DC_CANCEL_BYPASS (1 << 2) +#define CODEC_VAD_PRE_BYPASS (1 << 3) +#define CODEC_VAD_DIG_MODE (1 << 4) +#define CODEC_VAD_FINISH (1 << 5) + +// reg_14c +#define CODEC_VAD_U_DC(n) (((n) & 0xF) << 0) +#define CODEC_VAD_U_DC_MASK (0xF << 0) +#define CODEC_VAD_U_DC_SHIFT (0) +#define CODEC_VAD_U_PRE(n) (((n) & 0x7) << 4) +#define CODEC_VAD_U_PRE_MASK (0x7 << 4) +#define CODEC_VAD_U_PRE_SHIFT (4) +#define CODEC_VAD_FRAME_LEN(n) (((n) & 0xFF) << 7) +#define CODEC_VAD_FRAME_LEN_MASK (0xFF << 7) +#define CODEC_VAD_FRAME_LEN_SHIFT (7) +#define CODEC_VAD_MVAD(n) (((n) & 0xF) << 15) +#define CODEC_VAD_MVAD_MASK (0xF << 15) +#define CODEC_VAD_MVAD_SHIFT (15) +#define CODEC_VAD_PRE_GAIN(n) (((n) & 0x3F) << 19) +#define CODEC_VAD_PRE_GAIN_MASK (0x3F << 19) +#define CODEC_VAD_PRE_GAIN_SHIFT (19) +#define CODEC_VAD_STH(n) (((n) & 0x3F) << 25) +#define CODEC_VAD_STH_MASK (0x3F << 25) +#define CODEC_VAD_STH_SHIFT (25) + +// reg_150 +#define CODEC_VAD_FRAME_TH1(n) (((n) & 0xFF) << 0) +#define CODEC_VAD_FRAME_TH1_MASK (0xFF << 0) +#define CODEC_VAD_FRAME_TH1_SHIFT (0) +#define CODEC_VAD_FRAME_TH2(n) (((n) & 0x3FF) << 8) +#define CODEC_VAD_FRAME_TH2_MASK (0x3FF << 8) +#define CODEC_VAD_FRAME_TH2_SHIFT (8) +#define CODEC_VAD_FRAME_TH3(n) (((n) & 0x3FFF) << 18) +#define CODEC_VAD_FRAME_TH3_MASK (0x3FFF << 18) +#define CODEC_VAD_FRAME_TH3_SHIFT (18) + +// reg_154 +#define CODEC_VAD_RANGE1(n) (((n) & 0x1F) << 0) +#define CODEC_VAD_RANGE1_MASK (0x1F << 0) +#define CODEC_VAD_RANGE1_SHIFT (0) +#define CODEC_VAD_RANGE2(n) (((n) & 0x7F) << 5) +#define CODEC_VAD_RANGE2_MASK (0x7F << 5) +#define CODEC_VAD_RANGE2_SHIFT (5) +#define CODEC_VAD_RANGE3(n) (((n) & 0x1FF) << 12) +#define CODEC_VAD_RANGE3_MASK (0x1FF << 12) +#define CODEC_VAD_RANGE3_SHIFT (12) +#define CODEC_VAD_RANGE4(n) (((n) & 0x3FF) << 21) +#define CODEC_VAD_RANGE4_MASK (0x3FF << 21) +#define CODEC_VAD_RANGE4_SHIFT (21) + +// reg_158 +#define CODEC_VAD_PSD_TH1(n) (((n) & 0x7FFFFFF) << 0) +#define CODEC_VAD_PSD_TH1_MASK (0x7FFFFFF << 0) +#define CODEC_VAD_PSD_TH1_SHIFT (0) + +// reg_15c +#define CODEC_VAD_PSD_TH2(n) (((n) & 0x7FFFFFF) << 0) +#define CODEC_VAD_PSD_TH2_MASK (0x7FFFFFF << 0) +#define CODEC_VAD_PSD_TH2_SHIFT (0) + +// reg_160 +#define CODEC_VAD_MEM_ADDR_CNT(n) (((n) & 0x1FFF) << 1) +#define CODEC_VAD_MEM_ADDR_CNT_MASK (0x1FFF << 1) +#define CODEC_VAD_MEM_ADDR_CNT_SHIFT (1) +#define CODEC_VAD_MEM_DATA_CNT(n) (((n) & 0x1FFF) << 15) +#define CODEC_VAD_MEM_DATA_CNT_MASK (0x1FFF << 15) +#define CODEC_VAD_MEM_DATA_CNT_SHIFT (15) + +// reg_164 +#define CODEC_SMIN_SYC(n) (((n) & 0x7FFFFFF) << 0) +#define CODEC_SMIN_SYC_MASK (0x7FFFFFF << 0) +#define CODEC_SMIN_SYC_SHIFT (0) + +// reg_168 +#define CODEC_PSD_SYC(n) (((n) & 0x7FFFFFF) << 0) +#define CODEC_PSD_SYC_MASK (0x7FFFFFF << 0) +#define CODEC_PSD_SYC_SHIFT (0) + +// reg_170 +#define CODEC_FIR_CH0_STATE(n) (((n) & 0xFF) << 0) +#define CODEC_FIR_CH0_STATE_MASK (0xFF << 0) +#define CODEC_FIR_CH0_STATE_SHIFT (0) +#define CODEC_FIR_CH1_STATE(n) (((n) & 0xFF) << 8) +#define CODEC_FIR_CH1_STATE_MASK (0xFF << 8) +#define CODEC_FIR_CH1_STATE_SHIFT (8) +#define CODEC_FIR_CH2_STATE(n) (((n) & 0xFF) << 16) +#define CODEC_FIR_CH2_STATE_MASK (0xFF << 16) +#define CODEC_FIR_CH2_STATE_SHIFT (16) +#define CODEC_FIR_CH3_STATE(n) (((n) & 0xFF) << 24) +#define CODEC_FIR_CH3_STATE_MASK (0xFF << 24) +#define CODEC_FIR_CH3_STATE_SHIFT (24) + +// reg_174 +#define CODEC_CODEC_ADC_DC_DOUT_CH0_SYNC(n) (((n) & 0x1FFFFF) << 0) +#define CODEC_CODEC_ADC_DC_DOUT_CH0_SYNC_MASK (0x1FFFFF << 0) +#define CODEC_CODEC_ADC_DC_DOUT_CH0_SYNC_SHIFT (0) + +// reg_178 +#define CODEC_CODEC_ADC_DC_DOUT_CH1_SYNC(n) (((n) & 0x1FFFFF) << 0) +#define CODEC_CODEC_ADC_DC_DOUT_CH1_SYNC_MASK (0x1FFFFF << 0) +#define CODEC_CODEC_ADC_DC_DOUT_CH1_SYNC_SHIFT (0) + +// reg_17c +#define CODEC_CODEC_ADC_DC_DOUT_CH2_SYNC(n) (((n) & 0x1FFFFF) << 0) +#define CODEC_CODEC_ADC_DC_DOUT_CH2_SYNC_MASK (0x1FFFFF << 0) +#define CODEC_CODEC_ADC_DC_DOUT_CH2_SYNC_SHIFT (0) + +// reg_180 +#define CODEC_CODEC_ADC_DC_DOUT_CH3_SYNC(n) (((n) & 0x1FFFFF) << 0) +#define CODEC_CODEC_ADC_DC_DOUT_CH3_SYNC_MASK (0x1FFFFF << 0) +#define CODEC_CODEC_ADC_DC_DOUT_CH3_SYNC_SHIFT (0) + +// reg_184 +#define CODEC_CODEC_ADC_DC_DOUT_CH4_SYNC(n) (((n) & 0x1FFFFF) << 0) +#define CODEC_CODEC_ADC_DC_DOUT_CH4_SYNC_MASK (0x1FFFFF << 0) +#define CODEC_CODEC_ADC_DC_DOUT_CH4_SYNC_SHIFT (0) + +// reg_188 +#define CODEC_CODEC_ADC_DC_DIN_CH0(n) (((n) & 0x7FFF) << 0) +#define CODEC_CODEC_ADC_DC_DIN_CH0_MASK (0x7FFF << 0) +#define CODEC_CODEC_ADC_DC_DIN_CH0_SHIFT (0) +#define CODEC_CODEC_ADC_DC_UPDATE_CH0 (1 << 15) + +// reg_18c +#define CODEC_CODEC_ADC_DC_DIN_CH1(n) (((n) & 0x7FFF) << 0) +#define CODEC_CODEC_ADC_DC_DIN_CH1_MASK (0x7FFF << 0) +#define CODEC_CODEC_ADC_DC_DIN_CH1_SHIFT (0) +#define CODEC_CODEC_ADC_DC_UPDATE_CH1 (1 << 15) + +// reg_190 +#define CODEC_CODEC_ADC_DC_DIN_CH2(n) (((n) & 0x7FFF) << 0) +#define CODEC_CODEC_ADC_DC_DIN_CH2_MASK (0x7FFF << 0) +#define CODEC_CODEC_ADC_DC_DIN_CH2_SHIFT (0) +#define CODEC_CODEC_ADC_DC_UPDATE_CH2 (1 << 15) + +// reg_194 +#define CODEC_CODEC_ADC_DC_DIN_CH3(n) (((n) & 0x7FFF) << 0) +#define CODEC_CODEC_ADC_DC_DIN_CH3_MASK (0x7FFF << 0) +#define CODEC_CODEC_ADC_DC_DIN_CH3_SHIFT (0) +#define CODEC_CODEC_ADC_DC_UPDATE_CH3 (1 << 15) + +// reg_198 +#define CODEC_CODEC_ADC_DC_DIN_CH4(n) (((n) & 0x7FFF) << 0) +#define CODEC_CODEC_ADC_DC_DIN_CH4_MASK (0x7FFF << 0) +#define CODEC_CODEC_ADC_DC_DIN_CH4_SHIFT (0) +#define CODEC_CODEC_ADC_DC_UPDATE_CH4 (1 << 15) + +// reg_1a0 +#define CODEC_CODEC_DAC_DRE_GAIN_STEP0(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP0_MASK (0x3FFF << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP0_SHIFT (0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP1(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP1_MASK (0x3FFF << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP1_SHIFT (14) + +// reg_1a4 +#define CODEC_CODEC_DAC_DRE_GAIN_STEP2(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP2_MASK (0x3FFF << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP2_SHIFT (0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP3(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP3_MASK (0x3FFF << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP3_SHIFT (14) + +// reg_1a8 +#define CODEC_CODEC_DAC_DRE_GAIN_STEP4(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP4_MASK (0x3FFF << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP4_SHIFT (0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP5(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP5_MASK (0x3FFF << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP5_SHIFT (14) + +// reg_1ac +#define CODEC_CODEC_DAC_DRE_GAIN_STEP6(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP6_MASK (0x3FFF << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP6_SHIFT (0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP7(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP7_MASK (0x3FFF << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP7_SHIFT (14) + +// reg_1b0 +#define CODEC_CODEC_DAC_DRE_GAIN_STEP8(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP8_MASK (0x3FFF << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP8_SHIFT (0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP9(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP9_MASK (0x3FFF << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP9_SHIFT (14) + +// reg_1b4 +#define CODEC_CODEC_DAC_DRE_GAIN_STEP10(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP10_MASK (0x3FFF << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP10_SHIFT (0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP11(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP11_MASK (0x3FFF << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP11_SHIFT (14) + +// reg_1b8 +#define CODEC_CODEC_DAC_DRE_GAIN_STEP12(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP12_MASK (0x3FFF << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP12_SHIFT (0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP13(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP13_MASK (0x3FFF << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP13_SHIFT (14) + +// reg_1bc +#define CODEC_CODEC_DAC_DRE_GAIN_STEP14(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP14_MASK (0x3FFF << 0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP14_SHIFT (0) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP15(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP15_MASK (0x3FFF << 14) +#define CODEC_CODEC_DAC_DRE_GAIN_STEP15_SHIFT (14) + +// reg_1c0 +#define CODEC_CODEC_ADC_DRE_ENABLE_CH0 (1 << 0) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH0(n) (((n) & 0x3) << 1) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH0_MASK (0x3 << 1) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH0_SHIFT (1) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH0(n) (((n) & 0xF) << 3) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH0_MASK (0xF << 3) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH0_SHIFT (3) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH0(n) (((n) & 0xF) << 7) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH0_MASK (0xF << 7) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH0_SHIFT (7) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH0(n) (((n) & 0x7) << 11) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH0_MASK (0x7 << 11) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH0_SHIFT (11) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH0(n) (((n) & 0x1F) << 14) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH0_MASK (0x1F << 14) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH0_SHIFT (14) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_SIGN_CH0 (1 << 19) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH0(n) (((n) & 0x3) << 20) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH0_MASK (0x3 << 20) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH0_SHIFT (20) +#define CODEC_CODEC_ADC_DRE_OVERFLOW_MUTE_EN_CH0 (1 << 22) +#define CODEC_CODEC_ADC_DRE_MUTE_MODE_CH0 (1 << 23) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH0(n) (((n) & 0x3) << 24) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH0_MASK (0x3 << 24) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH0_SHIFT (24) +#define CODEC_CODEC_ADC_DRE_MUTE_STATUS_CH0 (1 << 26) + +// reg_1c4 +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH0(n) (((n) & 0x7FF) << 0) +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH0_MASK (0x7FF << 0) +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH0_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH0(n) (((n) & 0xFFFFF) << 11) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH0_MASK (0xFFFFF << 11) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH0_SHIFT (11) + +// reg_1c8 +#define CODEC_CODEC_ADC_DRE_ENABLE_CH1 (1 << 0) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH1(n) (((n) & 0x3) << 1) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH1_MASK (0x3 << 1) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH1_SHIFT (1) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH1(n) (((n) & 0xF) << 3) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH1_MASK (0xF << 3) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH1_SHIFT (3) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH1(n) (((n) & 0xF) << 7) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH1_MASK (0xF << 7) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH1_SHIFT (7) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH1(n) (((n) & 0x7) << 11) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH1_MASK (0x7 << 11) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH1_SHIFT (11) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH1(n) (((n) & 0x1F) << 14) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH1_MASK (0x1F << 14) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH1_SHIFT (14) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_SIGN_CH1 (1 << 19) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH1(n) (((n) & 0x3) << 20) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH1_MASK (0x3 << 20) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH1_SHIFT (20) +#define CODEC_CODEC_ADC_DRE_OVERFLOW_MUTE_EN_CH1 (1 << 22) +#define CODEC_CODEC_ADC_DRE_MUTE_MODE_CH1 (1 << 23) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH1(n) (((n) & 0x3) << 24) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH1_MASK (0x3 << 24) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH1_SHIFT (24) +#define CODEC_CODEC_ADC_DRE_MUTE_STATUS_CH1 (1 << 26) + +// reg_1cc +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH1(n) (((n) & 0x7FF) << 0) +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH1_MASK (0x7FF << 0) +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH1_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH1(n) (((n) & 0xFFFFF) << 11) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH1_MASK (0xFFFFF << 11) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH1_SHIFT (11) + +// reg_1d0 +#define CODEC_CODEC_ADC_DRE_ENABLE_CH2 (1 << 0) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH2(n) (((n) & 0x3) << 1) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH2_MASK (0x3 << 1) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH2_SHIFT (1) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH2(n) (((n) & 0xF) << 3) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH2_MASK (0xF << 3) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH2_SHIFT (3) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH2(n) (((n) & 0xF) << 7) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH2_MASK (0xF << 7) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH2_SHIFT (7) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH2(n) (((n) & 0x7) << 11) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH2_MASK (0x7 << 11) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH2_SHIFT (11) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH2(n) (((n) & 0x1F) << 14) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH2_MASK (0x1F << 14) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH2_SHIFT (14) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_SIGN_CH2 (1 << 19) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH2(n) (((n) & 0x3) << 20) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH2_MASK (0x3 << 20) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH2_SHIFT (20) +#define CODEC_CODEC_ADC_DRE_OVERFLOW_MUTE_EN_CH2 (1 << 22) +#define CODEC_CODEC_ADC_DRE_MUTE_MODE_CH2 (1 << 23) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH2(n) (((n) & 0x3) << 24) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH2_MASK (0x3 << 24) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH2_SHIFT (24) +#define CODEC_CODEC_ADC_DRE_MUTE_STATUS_CH2 (1 << 26) + +// reg_1d4 +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH2(n) (((n) & 0x7FF) << 0) +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH2_MASK (0x7FF << 0) +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH2_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH2(n) (((n) & 0xFFFFF) << 11) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH2_MASK (0xFFFFF << 11) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH2_SHIFT (11) + +// reg_1d8 +#define CODEC_CODEC_ADC_DRE_ENABLE_CH3 (1 << 0) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH3(n) (((n) & 0x3) << 1) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH3_MASK (0x3 << 1) +#define CODEC_CODEC_ADC_DRE_STEP_MODE_CH3_SHIFT (1) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH3(n) (((n) & 0xF) << 3) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH3_MASK (0xF << 3) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_CH3_SHIFT (3) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH3(n) (((n) & 0xF) << 7) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH3_MASK (0xF << 7) +#define CODEC_CODEC_ADC_DRE_INI_ANA_GAIN_CH3_SHIFT (7) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH3(n) (((n) & 0x7) << 11) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH3_MASK (0x7 << 11) +#define CODEC_CODEC_ADC_DRE_DELAY_DIG_CH3_SHIFT (11) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH3(n) (((n) & 0x1F) << 14) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH3_MASK (0x1F << 14) +#define CODEC_CODEC_ADC_DRE_DELAY_ANA_CH3_SHIFT (14) +#define CODEC_CODEC_ADC_DRE_THD_DB_OFFSET_SIGN_CH3 (1 << 19) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH3(n) (((n) & 0x3) << 20) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH3_MASK (0x3 << 20) +#define CODEC_CODEC_ADC_DRE_BIT_SEL_CH3_SHIFT (20) +#define CODEC_CODEC_ADC_DRE_OVERFLOW_MUTE_EN_CH3 (1 << 22) +#define CODEC_CODEC_ADC_DRE_MUTE_MODE_CH3 (1 << 23) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH3(n) (((n) & 0x3) << 24) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH3_MASK (0x3 << 24) +#define CODEC_CODEC_ADC_DRE_MUTE_RANGE_SEL_CH3_SHIFT (24) +#define CODEC_CODEC_ADC_DRE_MUTE_STATUS_CH3 (1 << 26) + +// reg_1dc +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH3(n) (((n) & 0x7FF) << 0) +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH3_MASK (0x7FF << 0) +#define CODEC_CODEC_ADC_DRE_AMP_HIGH_CH3_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH3(n) (((n) & 0xFFFFF) << 11) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH3_MASK (0xFFFFF << 11) +#define CODEC_CODEC_ADC_DRE_WINDOW_CH3_SHIFT (11) + +// reg_1e0 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP0_CH0(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP0_CH0_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP0_CH0_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP1_CH0(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP1_CH0_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP1_CH0_SHIFT (14) + +// reg_1e4 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP2_CH0(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP2_CH0_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP2_CH0_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP3_CH0(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP3_CH0_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP3_CH0_SHIFT (14) + +// reg_1e8 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP4_CH0(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP4_CH0_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP4_CH0_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP5_CH0(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP5_CH0_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP5_CH0_SHIFT (14) + +// reg_1ec +#define CODEC_CODEC_ADC_DRE_GAIN_STEP6_CH0(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP6_CH0_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP6_CH0_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP7_CH0(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP7_CH0_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP7_CH0_SHIFT (14) + +// reg_1f0 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP8_CH0(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP8_CH0_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP8_CH0_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP9_CH0(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP9_CH0_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP9_CH0_SHIFT (14) + +// reg_1f4 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP10_CH0(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP10_CH0_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP10_CH0_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP11_CH0(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP11_CH0_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP11_CH0_SHIFT (14) + +// reg_1f8 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP12_CH0(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP12_CH0_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP12_CH0_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP13_CH0(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP13_CH0_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP13_CH0_SHIFT (14) + +// reg_1fc +#define CODEC_CODEC_ADC_DRE_GAIN_STEP14_CH0(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP14_CH0_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP14_CH0_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP15_CH0(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP15_CH0_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP15_CH0_SHIFT (14) + +// reg_200 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP0_CH1(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP0_CH1_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP0_CH1_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP1_CH1(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP1_CH1_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP1_CH1_SHIFT (14) + +// reg_204 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP2_CH1(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP2_CH1_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP2_CH1_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP3_CH1(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP3_CH1_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP3_CH1_SHIFT (14) + +// reg_208 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP4_CH1(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP4_CH1_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP4_CH1_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP5_CH1(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP5_CH1_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP5_CH1_SHIFT (14) + +// reg_20c +#define CODEC_CODEC_ADC_DRE_GAIN_STEP6_CH1(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP6_CH1_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP6_CH1_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP7_CH1(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP7_CH1_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP7_CH1_SHIFT (14) + +// reg_210 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP8_CH1(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP8_CH1_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP8_CH1_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP9_CH1(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP9_CH1_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP9_CH1_SHIFT (14) + +// reg_214 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP10_CH1(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP10_CH1_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP10_CH1_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP11_CH1(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP11_CH1_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP11_CH1_SHIFT (14) + +// reg_218 +#define CODEC_CODEC_ADC_DRE_GAIN_STEP12_CH1(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP12_CH1_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP12_CH1_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP13_CH1(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP13_CH1_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP13_CH1_SHIFT (14) + +// reg_21c +#define CODEC_CODEC_ADC_DRE_GAIN_STEP14_CH1(n) (((n) & 0x3FFF) << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP14_CH1_MASK (0x3FFF << 0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP14_CH1_SHIFT (0) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP15_CH1(n) (((n) & 0x3FFF) << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP15_CH1_MASK (0x3FFF << 14) +#define CODEC_CODEC_ADC_DRE_GAIN_STEP15_CH1_SHIFT (14) + +// reg_220 +#define CODEC_VAD_DELAY1(n) (((n) & 0x3FF) << 0) +#define CODEC_VAD_DELAY1_MASK (0x3FF << 0) +#define CODEC_VAD_DELAY1_SHIFT (0) + +// reg_224 +#define CODEC_VAD_DELAY2(n) (((n) & 0xFFFFFF) << 0) +#define CODEC_VAD_DELAY2_MASK (0xFFFFFF << 0) +#define CODEC_VAD_DELAY2_SHIFT (0) + +// reg_228 +#define CODEC_CODEC_MC_ENABLE_CH0 (1 << 0) +#define CODEC_CODEC_MC_SEL_CH0 (1 << 1) +#define CODEC_CODEC_DOWN_SEL_MC_CH0(n) (((n) & 0x3) << 2) +#define CODEC_CODEC_DOWN_SEL_MC_CH0_MASK (0x3 << 2) +#define CODEC_CODEC_DOWN_SEL_MC_CH0_SHIFT (2) +#define CODEC_CODEC_MC_SINC_BYPASS_CH0 (1 << 4) +#define CODEC_CODEC_MC_ENABLE_CH1 (1 << 5) +#define CODEC_CODEC_MC_SEL_CH1 (1 << 6) +#define CODEC_CODEC_DOWN_SEL_MC_CH1(n) (((n) & 0x3) << 7) +#define CODEC_CODEC_DOWN_SEL_MC_CH1_MASK (0x3 << 7) +#define CODEC_CODEC_DOWN_SEL_MC_CH1_SHIFT (7) +#define CODEC_CODEC_MC_SINC_BYPASS_CH1 (1 << 9) +#define CODEC_CODEC_RESAMPLE_MC_ENABLE (1 << 10) +#define CODEC_CODEC_RESAMPLE_MC_DUAL_CH (1 << 11) + +// reg_22c +#define CODEC_CODEC_TT_ENABLE (1 << 0) +#define CODEC_CODEC_MUTE_GAIN_COEF_TT(n) (((n) & 0xFFF) << 1) +#define CODEC_CODEC_MUTE_GAIN_COEF_TT_MASK (0xFFF << 1) +#define CODEC_CODEC_MUTE_GAIN_COEF_TT_SHIFT (1) +#define CODEC_CODEC_MUTE_GAIN_PASS0_TT (1 << 13) +#define CODEC_CODEC_MM_ENABLE (1 << 14) +#define CODEC_CODEC_MUTE_GAIN_COEF_MM(n) (((n) & 0xFFF) << 15) +#define CODEC_CODEC_MUTE_GAIN_COEF_MM_MASK (0xFFF << 15) +#define CODEC_CODEC_MUTE_GAIN_COEF_MM_SHIFT (15) +#define CODEC_CODEC_MUTE_GAIN_PASS0_MM (1 << 27) + +// reg_230 +#define CODEC_CODEC_MM_FIFO_EN (1 << 0) +#define CODEC_CODEC_MM_FIFO_BYPASS (1 << 1) +#define CODEC_CODEC_MM_DELAY_UPDATE (1 << 2) +#define CODEC_CODEC_MM_DELAY(n) (((n) & 0x1F) << 3) +#define CODEC_CODEC_MM_DELAY_MASK (0x1F << 3) +#define CODEC_CODEC_MM_DELAY_SHIFT (3) +#define CODEC_VAD_EXT_EN (1 << 8) +#define CODEC_VAD_SRC_SEL (1 << 9) +#define CODEC_VAD_DATA_EXT_SWAP (1 << 10) +#define CODEC_MC_EN_SEL (1 << 11) +#define CODEC_MC_RATE_SRC_SEL (1 << 12) + +#endif diff --git a/platform/hal/best2300p/reg_iomux_best2300p.h b/platform/hal/best2300p/reg_iomux_best2300p.h new file mode 100644 index 0000000..c82b451 --- /dev/null +++ b/platform/hal/best2300p/reg_iomux_best2300p.h @@ -0,0 +1,406 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_IOMUX_BEST2300P_H_ +#define __REG_IOMUX_BEST2300P_H_ + +#include "plat_types.h" + +struct IOMUX_T { + __IO uint32_t REG_000; + __IO uint32_t REG_004; + __IO uint32_t REG_008; + __IO uint32_t REG_00C; + __IO uint32_t REG_010; + __IO uint32_t REG_014; + __IO uint32_t REG_018; + __IO uint32_t REG_01C; + __IO uint32_t REG_020; + __IO uint32_t REG_024; + __IO uint32_t REG_028; + __IO uint32_t REG_02C; + __IO uint32_t REG_030; + __IO uint32_t REG_034; + __IO uint32_t REG_038; + __IO uint32_t REG_03C; + __IO uint32_t REG_040; + __IO uint32_t REG_044; + __IO uint32_t REG_048; + __IO uint32_t REG_04C; + __IO uint32_t REG_050; + __IO uint32_t REG_054; + __IO uint32_t REG_058; + __IO uint32_t REG_05C; + __IO uint32_t REG_060; + __IO uint32_t REG_064; + __IO uint32_t REG_068; + __IO uint32_t REG_06C; + __IO uint32_t REG_070; + __IO uint32_t REG_074; + __IO uint32_t REG_078; +}; + +// reg_00 +#define IOMUX_32_H00001300(n) (((n) & 0xFFFFFFFF) << 0) +#define IOMUX_32_H00001300_MASK (0xFFFFFFFF << 0) +#define IOMUX_32_H00001300_SHIFT (0) + +// reg_04 +#define IOMUX_GPIO_P00_SEL(n) (((n) & 0xF) << 0) +#define IOMUX_GPIO_P00_SEL_MASK (0xF << 0) +#define IOMUX_GPIO_P00_SEL_SHIFT (0) +#define IOMUX_GPIO_P01_SEL(n) (((n) & 0xF) << 4) +#define IOMUX_GPIO_P01_SEL_MASK (0xF << 4) +#define IOMUX_GPIO_P01_SEL_SHIFT (4) +#define IOMUX_GPIO_P02_SEL(n) (((n) & 0xF) << 8) +#define IOMUX_GPIO_P02_SEL_MASK (0xF << 8) +#define IOMUX_GPIO_P02_SEL_SHIFT (8) +#define IOMUX_GPIO_P03_SEL(n) (((n) & 0xF) << 12) +#define IOMUX_GPIO_P03_SEL_MASK (0xF << 12) +#define IOMUX_GPIO_P03_SEL_SHIFT (12) +#define IOMUX_GPIO_P04_SEL(n) (((n) & 0xF) << 16) +#define IOMUX_GPIO_P04_SEL_MASK (0xF << 16) +#define IOMUX_GPIO_P04_SEL_SHIFT (16) +#define IOMUX_GPIO_P05_SEL(n) (((n) & 0xF) << 20) +#define IOMUX_GPIO_P05_SEL_MASK (0xF << 20) +#define IOMUX_GPIO_P05_SEL_SHIFT (20) +#define IOMUX_GPIO_P06_SEL(n) (((n) & 0xF) << 24) +#define IOMUX_GPIO_P06_SEL_MASK (0xF << 24) +#define IOMUX_GPIO_P06_SEL_SHIFT (24) +#define IOMUX_GPIO_P07_SEL(n) (((n) & 0xF) << 28) +#define IOMUX_GPIO_P07_SEL_MASK (0xF << 28) +#define IOMUX_GPIO_P07_SEL_SHIFT (28) + +// reg_08 +#define IOMUX_GPIO_P10_SEL(n) (((n) & 0xF) << 0) +#define IOMUX_GPIO_P10_SEL_MASK (0xF << 0) +#define IOMUX_GPIO_P10_SEL_SHIFT (0) +#define IOMUX_GPIO_P11_SEL(n) (((n) & 0xF) << 4) +#define IOMUX_GPIO_P11_SEL_MASK (0xF << 4) +#define IOMUX_GPIO_P11_SEL_SHIFT (4) +#define IOMUX_GPIO_P12_SEL(n) (((n) & 0xF) << 8) +#define IOMUX_GPIO_P12_SEL_MASK (0xF << 8) +#define IOMUX_GPIO_P12_SEL_SHIFT (8) +#define IOMUX_GPIO_P13_SEL(n) (((n) & 0xF) << 12) +#define IOMUX_GPIO_P13_SEL_MASK (0xF << 12) +#define IOMUX_GPIO_P13_SEL_SHIFT (12) +#define IOMUX_GPIO_P14_SEL(n) (((n) & 0xF) << 16) +#define IOMUX_GPIO_P14_SEL_MASK (0xF << 16) +#define IOMUX_GPIO_P14_SEL_SHIFT (16) +#define IOMUX_GPIO_P15_SEL(n) (((n) & 0xF) << 20) +#define IOMUX_GPIO_P15_SEL_MASK (0xF << 20) +#define IOMUX_GPIO_P15_SEL_SHIFT (20) +#define IOMUX_GPIO_P16_SEL(n) (((n) & 0xF) << 24) +#define IOMUX_GPIO_P16_SEL_MASK (0xF << 24) +#define IOMUX_GPIO_P16_SEL_SHIFT (24) +#define IOMUX_GPIO_P17_SEL(n) (((n) & 0xF) << 28) +#define IOMUX_GPIO_P17_SEL_MASK (0xF << 28) +#define IOMUX_GPIO_P17_SEL_SHIFT (28) + +// reg_0c +#define IOMUX_GPIO_P20_SEL(n) (((n) & 0xF) << 0) +#define IOMUX_GPIO_P20_SEL_MASK (0xF << 0) +#define IOMUX_GPIO_P20_SEL_SHIFT (0) +#define IOMUX_GPIO_P21_SEL(n) (((n) & 0xF) << 4) +#define IOMUX_GPIO_P21_SEL_MASK (0xF << 4) +#define IOMUX_GPIO_P21_SEL_SHIFT (4) +#define IOMUX_GPIO_P22_SEL(n) (((n) & 0xF) << 8) +#define IOMUX_GPIO_P22_SEL_MASK (0xF << 8) +#define IOMUX_GPIO_P22_SEL_SHIFT (8) +#define IOMUX_GPIO_P23_SEL(n) (((n) & 0xF) << 12) +#define IOMUX_GPIO_P23_SEL_MASK (0xF << 12) +#define IOMUX_GPIO_P23_SEL_SHIFT (12) +#define IOMUX_GPIO_P24_SEL(n) (((n) & 0xF) << 16) +#define IOMUX_GPIO_P24_SEL_MASK (0xF << 16) +#define IOMUX_GPIO_P24_SEL_SHIFT (16) +#define IOMUX_GPIO_P25_SEL(n) (((n) & 0xF) << 20) +#define IOMUX_GPIO_P25_SEL_MASK (0xF << 20) +#define IOMUX_GPIO_P25_SEL_SHIFT (20) +#define IOMUX_GPIO_P26_SEL(n) (((n) & 0xF) << 24) +#define IOMUX_GPIO_P26_SEL_MASK (0xF << 24) +#define IOMUX_GPIO_P26_SEL_SHIFT (24) +#define IOMUX_GPIO_P27_SEL(n) (((n) & 0xF) << 28) +#define IOMUX_GPIO_P27_SEL_MASK (0xF << 28) +#define IOMUX_GPIO_P27_SEL_SHIFT (28) + +// reg_10 +#define IOMUX_GPIO_P30_SEL(n) (((n) & 0xF) << 0) +#define IOMUX_GPIO_P30_SEL_MASK (0xF << 0) +#define IOMUX_GPIO_P30_SEL_SHIFT (0) +#define IOMUX_GPIO_P31_SEL(n) (((n) & 0xF) << 4) +#define IOMUX_GPIO_P31_SEL_MASK (0xF << 4) +#define IOMUX_GPIO_P31_SEL_SHIFT (4) +#define IOMUX_GPIO_P32_SEL(n) (((n) & 0xF) << 8) +#define IOMUX_GPIO_P32_SEL_MASK (0xF << 8) +#define IOMUX_GPIO_P32_SEL_SHIFT (8) +#define IOMUX_GPIO_P33_SEL(n) (((n) & 0xF) << 12) +#define IOMUX_GPIO_P33_SEL_MASK (0xF << 12) +#define IOMUX_GPIO_P33_SEL_SHIFT (12) +#define IOMUX_GPIO_P34_SEL(n) (((n) & 0xF) << 16) +#define IOMUX_GPIO_P34_SEL_MASK (0xF << 16) +#define IOMUX_GPIO_P34_SEL_SHIFT (16) +#define IOMUX_GPIO_P35_SEL(n) (((n) & 0xF) << 20) +#define IOMUX_GPIO_P35_SEL_MASK (0xF << 20) +#define IOMUX_GPIO_P35_SEL_SHIFT (20) +#define IOMUX_GPIO_P36_SEL(n) (((n) & 0xF) << 24) +#define IOMUX_GPIO_P36_SEL_MASK (0xF << 24) +#define IOMUX_GPIO_P36_SEL_SHIFT (24) +#define IOMUX_GPIO_P37_SEL(n) (((n) & 0xF) << 28) +#define IOMUX_GPIO_P37_SEL_MASK (0xF << 28) +#define IOMUX_GPIO_P37_SEL_SHIFT (28) + +// reg_14 +#define IOMUX_ANA_TEST_DIR(n) (((n) & 0xFFFFFFFF) << 0) +#define IOMUX_ANA_TEST_DIR_MASK (0xFFFFFFFF << 0) +#define IOMUX_ANA_TEST_DIR_SHIFT (0) + +// reg_18 +#define IOMUX_ANA_TEST_SEL(n) (((n) & 0xF) << 0) +#define IOMUX_ANA_TEST_SEL_MASK (0xF << 0) +#define IOMUX_ANA_TEST_SEL_SHIFT (0) + +// reg_1c +#define IOMUX_RESERVED(n) (((n) & 0xFFFFFFFF) << 0) +#define IOMUX_RESERVED_MASK (0xFFFFFFFF << 0) +#define IOMUX_RESERVED_SHIFT (0) + +// reg_20 +#define IOMUX_RESERVED2(n) (((n) & 0xFFFFFFFF) << 0) +#define IOMUX_RESERVED2_MASK (0xFFFFFFFF << 0) +#define IOMUX_RESERVED2_SHIFT (0) + +// reg_24 +#define IOMUX_RESERVED3(n) (((n) & 0xFFFFFFFF) << 0) +#define IOMUX_RESERVED3_MASK (0xFFFFFFFF << 0) +#define IOMUX_RESERVED3_SHIFT (0) + +// reg_28 +#define IOMUX_RESERVED4(n) (((n) & 0xFFFFFFFF) << 0) +#define IOMUX_RESERVED4_MASK (0xFFFFFFFF << 0) +#define IOMUX_RESERVED4_SHIFT (0) + +// reg_2c +#define IOMUX_R_GPIO_P0_PU(n) (((n) & 0xFF) << 0) +#define IOMUX_R_GPIO_P0_PU_MASK (0xFF << 0) +#define IOMUX_R_GPIO_P0_PU_SHIFT (0) +#define IOMUX_R_GPIO_P1_PU(n) (((n) & 0xFF) << 8) +#define IOMUX_R_GPIO_P1_PU_MASK (0xFF << 8) +#define IOMUX_R_GPIO_P1_PU_SHIFT (8) +#define IOMUX_R_GPIO_P2_PU(n) (((n) & 0xFF) << 16) +#define IOMUX_R_GPIO_P2_PU_MASK (0xFF << 16) +#define IOMUX_R_GPIO_P2_PU_SHIFT (16) +#define IOMUX_R_GPIO_P3_PU(n) (((n) & 0xFF) << 24) +#define IOMUX_R_GPIO_P3_PU_MASK (0xFF << 24) +#define IOMUX_R_GPIO_P3_PU_SHIFT (24) + +// reg_30 +#define IOMUX_R_GPIO_P0_PD(n) (((n) & 0xFF) << 0) +#define IOMUX_R_GPIO_P0_PD_MASK (0xFF << 0) +#define IOMUX_R_GPIO_P0_PD_SHIFT (0) +#define IOMUX_R_GPIO_P1_PD(n) (((n) & 0xFF) << 8) +#define IOMUX_R_GPIO_P1_PD_MASK (0xFF << 8) +#define IOMUX_R_GPIO_P1_PD_SHIFT (8) +#define IOMUX_R_GPIO_P2_PD(n) (((n) & 0xFF) << 16) +#define IOMUX_R_GPIO_P2_PD_MASK (0xFF << 16) +#define IOMUX_R_GPIO_P2_PD_SHIFT (16) +#define IOMUX_R_GPIO_P3_PD(n) (((n) & 0xFF) << 24) +#define IOMUX_R_GPIO_P3_PD_MASK (0xFF << 24) +#define IOMUX_R_GPIO_P3_PD_SHIFT (24) + +// reg_34 +#define IOMUX_AGPIO_EN(n) (((n) & 0xFFFFFFFF) << 0) +#define IOMUX_AGPIO_EN_MASK (0xFFFFFFFF << 0) +#define IOMUX_AGPIO_EN_SHIFT (0) + +// reg_38 +#define IOMUX_MCUIO_DB_ACTIVE(n) (((n) & 0xFFFFFFFF) << 0) +#define IOMUX_MCUIO_DB_ACTIVE_MASK (0xFFFFFFFF << 0) +#define IOMUX_MCUIO_DB_ACTIVE_SHIFT (0) + +// reg_3c +#define IOMUX_MCUIO_DB_VALUE(n) (((n) & 0xFF) << 0) +#define IOMUX_MCUIO_DB_VALUE_MASK (0xFF << 0) +#define IOMUX_MCUIO_DB_VALUE_SHIFT (0) +#define IOMUX_PWK_DB_VALUE(n) (((n) & 0xFF) << 8) +#define IOMUX_PWK_DB_VALUE_MASK (0xFF << 8) +#define IOMUX_PWK_DB_VALUE_SHIFT (8) +#define IOMUX_PWK_DB_ACTIVE (1 << 16) + +// reg_40 +#define IOMUX_POWER_KEY_ON_INT_STATUS (1 << 0) +#define IOMUX_POWER_KEY_OFF_INT_STATUS (1 << 1) +#define IOMUX_R_POWER_KEY_INTR_U (1 << 2) +#define IOMUX_R_POWER_KEY_INTR_D (1 << 3) +#define IOMUX_POWER_KEY_ON_INT_EN (1 << 4) +#define IOMUX_POWER_KEY_OFF_INT_EN (1 << 5) +#define IOMUX_POWER_KEY_ON_INT_MSK (1 << 6) +#define IOMUX_POWER_KEY_OFF_INT_MSK (1 << 7) +#define IOMUX_POWER_KEY_DB (1 << 30) +#define IOMUX_POWER_ON_FEEDOUT (1 << 31) + +// reg_44 +#define IOMUX_BT_SPI_RF_ENABLE (1 << 0) +#define IOMUX_BT_SPI_PMU_ENABLE (1 << 1) +#define IOMUX_BT_SPI_ANA_ENABLE (1 << 2) +#define IOMUX_MCU_APB_SPI_RF_ENABLE (1 << 3) +#define IOMUX_MCU_APB_SPI_PMU_ENABLE (1 << 4) +#define IOMUX_MCU_APB_SPI_ANA_ENABLE (1 << 5) + +// reg_50 +#define IOMUX_GPIO_I2C_MODE (1 << 0) +#define IOMUX_I2C0_M_SEL_GPIO (1 << 1) +#define IOMUX_GPIO_PCM_MODE (1 << 2) +#define IOMUX_BT_RXTX_SW_EN (1 << 3) +#define IOMUX_I2C1_M_SEL_GPIO (1 << 4) +#define IOMUX_SPILCD0_WM3 (1 << 5) +#define IOMUX_SPILCD1_WM3 (1 << 6) +#define IOMUX_CFG_EN_CLK_REQIN (1 << 7) +#define IOMUX_CFG_POL_CLK_REQIN (1 << 8) +#define IOMUX_CFG_EN_CLK_REQOUT (1 << 9) +#define IOMUX_CFG_POL_CLK_REQOUT (1 << 10) +#define IOMUX_BT_UART_HALFN (1 << 11) +#define IOMUX_UART0_HALFN (1 << 12) +#define IOMUX_UART1_HALFN (1 << 13) +#define IOMUX_UART2_HALFN (1 << 14) + +// reg_54 +#define IOMUX_CFG_GPIO_OENB_P0_POL(n) (((n) & 0xFF) << 0) +#define IOMUX_CFG_GPIO_OENB_P0_POL_MASK (0xFF << 0) +#define IOMUX_CFG_GPIO_OENB_P0_POL_SHIFT (0) +#define IOMUX_CFG_GPIO_OENB_P1_POL(n) (((n) & 0xFF) << 8) +#define IOMUX_CFG_GPIO_OENB_P1_POL_MASK (0xFF << 8) +#define IOMUX_CFG_GPIO_OENB_P1_POL_SHIFT (8) +#define IOMUX_CFG_GPIO_OENB_P2_POL(n) (((n) & 0xFF) << 16) +#define IOMUX_CFG_GPIO_OENB_P2_POL_MASK (0xFF << 16) +#define IOMUX_CFG_GPIO_OENB_P2_POL_SHIFT (16) +#define IOMUX_CFG_GPIO_OENB_P3_POL(n) (((n) & 0xFF) << 24) +#define IOMUX_CFG_GPIO_OENB_P3_POL_MASK (0xFF << 24) +#define IOMUX_CFG_GPIO_OENB_P3_POL_SHIFT (24) + +// reg_64 +#define IOMUX_CFG_CODEC_TRIG_SEL(n) (((n) & 0x3F) << 0) +#define IOMUX_CFG_CODEC_TRIG_SEL_MASK (0x3F << 0) +#define IOMUX_CFG_CODEC_TRIG_SEL_SHIFT (0) +#define IOMUX_CFG_CODEC_TRIG_POL (1 << 6) + +// reg_70 +#define IOMUX_GPIO_P1_RXHZ_EN(n) (((n) & 0xFF) << 0) +#define IOMUX_GPIO_P1_RXHZ_EN_MASK (0xFF << 0) +#define IOMUX_GPIO_P1_RXHZ_EN_SHIFT (0) +#define IOMUX_GPIO_P1_PWS(n) (((n) & 0x3) << 8) +#define IOMUX_GPIO_P1_PWS_MASK (0x3 << 8) +#define IOMUX_GPIO_P1_PWS_SHIFT (8) + +// reg_74 +#define IOMUX_GPIO_P0_DRV0_SEL(n) (((n) & 0x3) << 0) +#define IOMUX_GPIO_P0_DRV0_SEL_MASK (0x3 << 0) +#define IOMUX_GPIO_P0_DRV0_SEL_SHIFT (0) +#define IOMUX_GPIO_P0_DRV1_SEL(n) (((n) & 0x3) << 2) +#define IOMUX_GPIO_P0_DRV1_SEL_MASK (0x3 << 2) +#define IOMUX_GPIO_P0_DRV1_SEL_SHIFT (2) +#define IOMUX_GPIO_P0_DRV2_SEL(n) (((n) & 0x3) << 4) +#define IOMUX_GPIO_P0_DRV2_SEL_MASK (0x3 << 4) +#define IOMUX_GPIO_P0_DRV2_SEL_SHIFT (4) +#define IOMUX_GPIO_P0_DRV3_SEL(n) (((n) & 0x3) << 6) +#define IOMUX_GPIO_P0_DRV3_SEL_MASK (0x3 << 6) +#define IOMUX_GPIO_P0_DRV3_SEL_SHIFT (6) +#define IOMUX_GPIO_P0_DRV4_SEL(n) (((n) & 0x3) << 8) +#define IOMUX_GPIO_P0_DRV4_SEL_MASK (0x3 << 8) +#define IOMUX_GPIO_P0_DRV4_SEL_SHIFT (8) +#define IOMUX_GPIO_P0_DRV5_SEL(n) (((n) & 0x3) << 10) +#define IOMUX_GPIO_P0_DRV5_SEL_MASK (0x3 << 10) +#define IOMUX_GPIO_P0_DRV5_SEL_SHIFT (10) +#define IOMUX_GPIO_P0_DRV6_SEL(n) (((n) & 0x3) << 12) +#define IOMUX_GPIO_P0_DRV6_SEL_MASK (0x3 << 12) +#define IOMUX_GPIO_P0_DRV6_SEL_SHIFT (12) +#define IOMUX_GPIO_P0_DRV7_SEL(n) (((n) & 0x3) << 14) +#define IOMUX_GPIO_P0_DRV7_SEL_MASK (0x3 << 14) +#define IOMUX_GPIO_P0_DRV7_SEL_SHIFT (14) +#define IOMUX_GPIO_P1_DRV0_SEL(n) (((n) & 0x3) << 16) +#define IOMUX_GPIO_P1_DRV0_SEL_MASK (0x3 << 16) +#define IOMUX_GPIO_P1_DRV0_SEL_SHIFT (16) +#define IOMUX_GPIO_P1_DRV1_SEL(n) (((n) & 0x3) << 18) +#define IOMUX_GPIO_P1_DRV1_SEL_MASK (0x3 << 18) +#define IOMUX_GPIO_P1_DRV1_SEL_SHIFT (18) +#define IOMUX_GPIO_P1_DRV2_SEL(n) (((n) & 0x3) << 20) +#define IOMUX_GPIO_P1_DRV2_SEL_MASK (0x3 << 20) +#define IOMUX_GPIO_P1_DRV2_SEL_SHIFT (20) +#define IOMUX_GPIO_P1_DRV3_SEL(n) (((n) & 0x3) << 22) +#define IOMUX_GPIO_P1_DRV3_SEL_MASK (0x3 << 22) +#define IOMUX_GPIO_P1_DRV3_SEL_SHIFT (22) +#define IOMUX_GPIO_P1_DRV4_SEL(n) (((n) & 0x3) << 24) +#define IOMUX_GPIO_P1_DRV4_SEL_MASK (0x3 << 24) +#define IOMUX_GPIO_P1_DRV4_SEL_SHIFT (24) +#define IOMUX_GPIO_P1_DRV5_SEL(n) (((n) & 0x3) << 26) +#define IOMUX_GPIO_P1_DRV5_SEL_MASK (0x3 << 26) +#define IOMUX_GPIO_P1_DRV5_SEL_SHIFT (26) +#define IOMUX_GPIO_P1_DRV6_SEL(n) (((n) & 0x3) << 28) +#define IOMUX_GPIO_P1_DRV6_SEL_MASK (0x3 << 28) +#define IOMUX_GPIO_P1_DRV6_SEL_SHIFT (28) +#define IOMUX_GPIO_P1_DRV7_SEL(n) (((n) & 0x3) << 30) +#define IOMUX_GPIO_P1_DRV7_SEL_MASK (0x3 << 30) +#define IOMUX_GPIO_P1_DRV7_SEL_SHIFT (30) + +// reg_78 +#define IOMUX_GPIO_P2_DRV0_SEL(n) (((n) & 0x3) << 0) +#define IOMUX_GPIO_P2_DRV0_SEL_MASK (0x3 << 0) +#define IOMUX_GPIO_P2_DRV0_SEL_SHIFT (0) +#define IOMUX_GPIO_P2_DRV1_SEL(n) (((n) & 0x3) << 2) +#define IOMUX_GPIO_P2_DRV1_SEL_MASK (0x3 << 2) +#define IOMUX_GPIO_P2_DRV1_SEL_SHIFT (2) +#define IOMUX_GPIO_P2_DRV2_SEL(n) (((n) & 0x3) << 4) +#define IOMUX_GPIO_P2_DRV2_SEL_MASK (0x3 << 4) +#define IOMUX_GPIO_P2_DRV2_SEL_SHIFT (4) +#define IOMUX_GPIO_P2_DRV3_SEL(n) (((n) & 0x3) << 6) +#define IOMUX_GPIO_P2_DRV3_SEL_MASK (0x3 << 6) +#define IOMUX_GPIO_P2_DRV3_SEL_SHIFT (6) +#define IOMUX_GPIO_P2_DRV4_SEL(n) (((n) & 0x3) << 8) +#define IOMUX_GPIO_P2_DRV4_SEL_MASK (0x3 << 8) +#define IOMUX_GPIO_P2_DRV4_SEL_SHIFT (8) +#define IOMUX_GPIO_P2_DRV5_SEL(n) (((n) & 0x3) << 10) +#define IOMUX_GPIO_P2_DRV5_SEL_MASK (0x3 << 10) +#define IOMUX_GPIO_P2_DRV5_SEL_SHIFT (10) +#define IOMUX_GPIO_P2_DRV6_SEL(n) (((n) & 0x3) << 12) +#define IOMUX_GPIO_P2_DRV6_SEL_MASK (0x3 << 12) +#define IOMUX_GPIO_P2_DRV6_SEL_SHIFT (12) +#define IOMUX_GPIO_P2_DRV7_SEL(n) (((n) & 0x3) << 14) +#define IOMUX_GPIO_P2_DRV7_SEL_MASK (0x3 << 14) +#define IOMUX_GPIO_P2_DRV7_SEL_SHIFT (14) +#define IOMUX_GPIO_P3_DRV0_SEL(n) (((n) & 0x3) << 16) +#define IOMUX_GPIO_P3_DRV0_SEL_MASK (0x3 << 16) +#define IOMUX_GPIO_P3_DRV0_SEL_SHIFT (16) +#define IOMUX_GPIO_P3_DRV1_SEL(n) (((n) & 0x3) << 18) +#define IOMUX_GPIO_P3_DRV1_SEL_MASK (0x3 << 18) +#define IOMUX_GPIO_P3_DRV1_SEL_SHIFT (18) +#define IOMUX_GPIO_P3_DRV2_SEL(n) (((n) & 0x3) << 20) +#define IOMUX_GPIO_P3_DRV2_SEL_MASK (0x3 << 20) +#define IOMUX_GPIO_P3_DRV2_SEL_SHIFT (20) +#define IOMUX_GPIO_P3_DRV3_SEL(n) (((n) & 0x3) << 22) +#define IOMUX_GPIO_P3_DRV3_SEL_MASK (0x3 << 22) +#define IOMUX_GPIO_P3_DRV3_SEL_SHIFT (22) +#define IOMUX_GPIO_P3_DRV4_SEL(n) (((n) & 0x3) << 24) +#define IOMUX_GPIO_P3_DRV4_SEL_MASK (0x3 << 24) +#define IOMUX_GPIO_P3_DRV4_SEL_SHIFT (24) +#define IOMUX_GPIO_P3_DRV5_SEL(n) (((n) & 0x3) << 26) +#define IOMUX_GPIO_P3_DRV5_SEL_MASK (0x3 << 26) +#define IOMUX_GPIO_P3_DRV5_SEL_SHIFT (26) +#define IOMUX_GPIO_P3_DRV6_SEL(n) (((n) & 0x3) << 28) +#define IOMUX_GPIO_P3_DRV6_SEL_MASK (0x3 << 28) +#define IOMUX_GPIO_P3_DRV6_SEL_SHIFT (28) +#define IOMUX_GPIO_P3_DRV7_SEL(n) (((n) & 0x3) << 30) +#define IOMUX_GPIO_P3_DRV7_SEL_MASK (0x3 << 30) +#define IOMUX_GPIO_P3_DRV7_SEL_SHIFT (30) + +#endif /* __REG_IOMUXIP_H_ */ diff --git a/platform/hal/best2300p/reg_psc_best2300p.h b/platform/hal/best2300p/reg_psc_best2300p.h new file mode 100644 index 0000000..a02772e --- /dev/null +++ b/platform/hal/best2300p/reg_psc_best2300p.h @@ -0,0 +1,450 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_PSC_BEST2300P_H__ +#define __REG_PSC_BEST2300P_H__ + +#include "plat_types.h" + +struct AONPSC_T { + __IO uint32_t REG_000; + __IO uint32_t REG_004; + __IO uint32_t REG_008; + __IO uint32_t REG_00C; + __IO uint32_t REG_010; + __IO uint32_t REG_014; + __IO uint32_t REG_018; + __IO uint32_t REG_01C; + __IO uint32_t REG_020; + __IO uint32_t REG_024; + __IO uint32_t REG_028; + __IO uint32_t REG_02C; + __IO uint32_t REG_030; + __IO uint32_t REG_034; + __IO uint32_t REG_038; + __IO uint32_t REG_03C; + __IO uint32_t REG_040; + __IO uint32_t REG_044; + __IO uint32_t REG_048; + __IO uint32_t REG_04C; + __IO uint32_t REG_050; + __IO uint32_t REG_054; + __IO uint32_t REG_058; + __IO uint32_t REG_05C; + __IO uint32_t REG_060; + __IO uint32_t REG_064; + __IO uint32_t REG_068; + __IO uint32_t REG_06C; + __IO uint32_t REG_070; + __IO uint32_t REG_074; + __IO uint32_t REG_078; + __IO uint32_t REG_07C; + __IO uint32_t REG_080; + __IO uint32_t REG_084; + __IO uint32_t REG_088; + __IO uint32_t REG_08C; + __IO uint32_t REG_090; + __IO uint32_t REG_094; + __IO uint32_t REG_098; + __IO uint32_t REG_09C; + __IO uint32_t REG_0A0; + __IO uint32_t REG_0A4; + __IO uint32_t REG_0A8; + __IO uint32_t REG_0AC; + __IO uint32_t REG_0B0; + __IO uint32_t REG_0B4; +}; + +// reg_00 +#define PSC_AON_MCU_PG_AUTO_EN (1 << 0) + +// reg_04 +#define PSC_AON_MCU_PSW_ACK_VALID (1 << 0) +#define PSC_AON_MCU_RESERVED(n) (((n) & 0x7F) << 1) +#define PSC_AON_MCU_RESERVED_MASK (0x7F << 1) +#define PSC_AON_MCU_RESERVED_SHIFT (1) +#define PSC_AON_MCU_MAIN_STATE(n) (((n) & 0x3) << 8) +#define PSC_AON_MCU_MAIN_STATE_MASK (0x3 << 8) +#define PSC_AON_MCU_MAIN_STATE_SHIFT (8) +#define PSC_AON_MCU_POWERDN_STATE(n) (((n) & 0x7) << 10) +#define PSC_AON_MCU_POWERDN_STATE_MASK (0x7 << 10) +#define PSC_AON_MCU_POWERDN_STATE_SHIFT (10) +#define PSC_AON_MCU_POWERUP_STATE(n) (((n) & 0x7) << 13) +#define PSC_AON_MCU_POWERUP_STATE_MASK (0x7 << 13) +#define PSC_AON_MCU_POWERUP_STATE_SHIFT (13) + +// reg_08 +#define PSC_AON_MCU_POWERDN_TIMER1(n) (((n) & 0x3F) << 0) +#define PSC_AON_MCU_POWERDN_TIMER1_MASK (0x3F << 0) +#define PSC_AON_MCU_POWERDN_TIMER1_SHIFT (0) +#define PSC_AON_MCU_POWERDN_TIMER2(n) (((n) & 0x3F) << 6) +#define PSC_AON_MCU_POWERDN_TIMER2_MASK (0x3F << 6) +#define PSC_AON_MCU_POWERDN_TIMER2_SHIFT (6) +#define PSC_AON_MCU_POWERDN_TIMER3(n) (((n) & 0x3F) << 12) +#define PSC_AON_MCU_POWERDN_TIMER3_MASK (0x3F << 12) +#define PSC_AON_MCU_POWERDN_TIMER3_SHIFT (12) +#define PSC_AON_MCU_POWERDN_TIMER4(n) (((n) & 0x3F) << 18) +#define PSC_AON_MCU_POWERDN_TIMER4_MASK (0x3F << 18) +#define PSC_AON_MCU_POWERDN_TIMER4_SHIFT (18) +#define PSC_AON_MCU_POWERDN_TIMER5(n) (((n) & 0xFF) << 24) +#define PSC_AON_MCU_POWERDN_TIMER5_MASK (0xFF << 24) +#define PSC_AON_MCU_POWERDN_TIMER5_SHIFT (24) + +// reg_0c +#define PSC_AON_MCU_POWERUP_TIMER1(n) (((n) & 0x3F) << 0) +#define PSC_AON_MCU_POWERUP_TIMER1_MASK (0x3F << 0) +#define PSC_AON_MCU_POWERUP_TIMER1_SHIFT (0) +#define PSC_AON_MCU_POWERUP_TIMER2(n) (((n) & 0xFF) << 6) +#define PSC_AON_MCU_POWERUP_TIMER2_MASK (0xFF << 6) +#define PSC_AON_MCU_POWERUP_TIMER2_SHIFT (6) +#define PSC_AON_MCU_POWERUP_TIMER3(n) (((n) & 0x3F) << 14) +#define PSC_AON_MCU_POWERUP_TIMER3_MASK (0x3F << 14) +#define PSC_AON_MCU_POWERUP_TIMER3_SHIFT (14) +#define PSC_AON_MCU_POWERUP_TIMER4(n) (((n) & 0x3F) << 20) +#define PSC_AON_MCU_POWERUP_TIMER4_MASK (0x3F << 20) +#define PSC_AON_MCU_POWERUP_TIMER4_SHIFT (20) +#define PSC_AON_MCU_POWERUP_TIMER5(n) (((n) & 0x3F) << 26) +#define PSC_AON_MCU_POWERUP_TIMER5_MASK (0x3F << 26) +#define PSC_AON_MCU_POWERUP_TIMER5_SHIFT (26) + +// reg_10 +#define PSC_AON_MCU_POWERDN_START (1 << 0) + +// reg_14 +#define PSC_AON_MCU_POWERUP_START (1 << 0) + +// reg_18 +#define PSC_AON_MCU_CLK_STOP_REG (1 << 0) +#define PSC_AON_MCU_ISO_EN_REG (1 << 1) +#define PSC_AON_MCU_RESETN_ASSERT_REG (1 << 2) +#define PSC_AON_MCU_PSW_EN_REG (1 << 3) +#define PSC_AON_MCU_CLK_STOP_DR (1 << 4) +#define PSC_AON_MCU_ISO_EN_DR (1 << 5) +#define PSC_AON_MCU_RESETN_ASSERT_DR (1 << 6) +#define PSC_AON_MCU_PSW_EN_DR (1 << 7) + +// reg_1c +#define PSC_AON_MCU_MAIN_STATE_R(n) (((n) & 0x3) << 0) +#define PSC_AON_MCU_MAIN_STATE_R_MASK (0x3 << 0) +#define PSC_AON_MCU_MAIN_STATE_R_SHIFT (0) +#define PSC_AON_MCU_POWERDN_STATE_R(n) (((n) & 0x7) << 2) +#define PSC_AON_MCU_POWERDN_STATE_R_MASK (0x7 << 2) +#define PSC_AON_MCU_POWERDN_STATE_R_SHIFT (2) +#define PSC_AON_MCU_POWERUP_STATE_R(n) (((n) & 0x7) << 5) +#define PSC_AON_MCU_POWERUP_STATE_R_MASK (0x7 << 5) +#define PSC_AON_MCU_POWERUP_STATE_R_SHIFT (5) +#define PSC_AON_BT_MAIN_STATE_R(n) (((n) & 0x3) << 8) +#define PSC_AON_BT_MAIN_STATE_R_MASK (0x3 << 8) +#define PSC_AON_BT_MAIN_STATE_R_SHIFT (8) +#define PSC_AON_BT_POWERDN_STATE_R(n) (((n) & 0x7) << 10) +#define PSC_AON_BT_POWERDN_STATE_R_MASK (0x7 << 10) +#define PSC_AON_BT_POWERDN_STATE_R_SHIFT (10) +#define PSC_AON_BT_POWERUP_STATE_R(n) (((n) & 0x7) << 13) +#define PSC_AON_BT_POWERUP_STATE_R_MASK (0x7 << 13) +#define PSC_AON_BT_POWERUP_STATE_R_SHIFT (13) +#define PSC_AON_WLAN_MAIN_STATE_R(n) (((n) & 0x3) << 16) +#define PSC_AON_WLAN_MAIN_STATE_R_MASK (0x3 << 16) +#define PSC_AON_WLAN_MAIN_STATE_R_SHIFT (16) +#define PSC_AON_WLAN_POWERDN_STATE_R(n) (((n) & 0x7) << 18) +#define PSC_AON_WLAN_POWERDN_STATE_R_MASK (0x7 << 18) +#define PSC_AON_WLAN_POWERDN_STATE_R_SHIFT (18) +#define PSC_AON_WLAN_POWERUP_STATE_R(n) (((n) & 0x7) << 21) +#define PSC_AON_WLAN_POWERUP_STATE_R_MASK (0x7 << 21) +#define PSC_AON_WLAN_POWERUP_STATE_R_SHIFT (21) +#define PSC_AON_CODEC_MAIN_STATE_R(n) (((n) & 0x3) << 24) +#define PSC_AON_CODEC_MAIN_STATE_R_MASK (0x3 << 24) +#define PSC_AON_CODEC_MAIN_STATE_R_SHIFT (24) +#define PSC_AON_CODEC_POWERDN_STATE_R(n) (((n) & 0x7) << 26) +#define PSC_AON_CODEC_POWERDN_STATE_R_MASK (0x7 << 26) +#define PSC_AON_CODEC_POWERDN_STATE_R_SHIFT (26) +#define PSC_AON_CODEC_POWERUP_STATE_R(n) (((n) & 0x7) << 29) +#define PSC_AON_CODEC_POWERUP_STATE_R_MASK (0x7 << 29) +#define PSC_AON_CODEC_POWERUP_STATE_R_SHIFT (29) + +// reg_20 +#define PSC_AON_BT_PG_AUTO_EN (1 << 0) + +// reg_24 +#define PSC_AON_BT_PSW_ACK_VALID (1 << 0) +#define PSC_AON_BT_RESERVED(n) (((n) & 0x7F) << 1) +#define PSC_AON_BT_RESERVED_MASK (0x7F << 1) +#define PSC_AON_BT_RESERVED_SHIFT (1) +#define PSC_AON_BT_MAIN_STATE(n) (((n) & 0x3) << 8) +#define PSC_AON_BT_MAIN_STATE_MASK (0x3 << 8) +#define PSC_AON_BT_MAIN_STATE_SHIFT (8) +#define PSC_AON_BT_POWERDN_STATE(n) (((n) & 0x7) << 10) +#define PSC_AON_BT_POWERDN_STATE_MASK (0x7 << 10) +#define PSC_AON_BT_POWERDN_STATE_SHIFT (10) +#define PSC_AON_BT_POWERUP_STATE(n) (((n) & 0x7) << 13) +#define PSC_AON_BT_POWERUP_STATE_MASK (0x7 << 13) +#define PSC_AON_BT_POWERUP_STATE_SHIFT (13) + +// reg_28 +#define PSC_AON_BT_POWERDN_TIMER1(n) (((n) & 0x3F) << 0) +#define PSC_AON_BT_POWERDN_TIMER1_MASK (0x3F << 0) +#define PSC_AON_BT_POWERDN_TIMER1_SHIFT (0) +#define PSC_AON_BT_POWERDN_TIMER2(n) (((n) & 0x3F) << 6) +#define PSC_AON_BT_POWERDN_TIMER2_MASK (0x3F << 6) +#define PSC_AON_BT_POWERDN_TIMER2_SHIFT (6) +#define PSC_AON_BT_POWERDN_TIMER3(n) (((n) & 0x3F) << 12) +#define PSC_AON_BT_POWERDN_TIMER3_MASK (0x3F << 12) +#define PSC_AON_BT_POWERDN_TIMER3_SHIFT (12) +#define PSC_AON_BT_POWERDN_TIMER4(n) (((n) & 0x3F) << 18) +#define PSC_AON_BT_POWERDN_TIMER4_MASK (0x3F << 18) +#define PSC_AON_BT_POWERDN_TIMER4_SHIFT (18) +#define PSC_AON_BT_POWERDN_TIMER5(n) (((n) & 0xFF) << 24) +#define PSC_AON_BT_POWERDN_TIMER5_MASK (0xFF << 24) +#define PSC_AON_BT_POWERDN_TIMER5_SHIFT (24) + +// reg_2c +#define PSC_AON_BT_POWERUP_TIMER1(n) (((n) & 0x3F) << 0) +#define PSC_AON_BT_POWERUP_TIMER1_MASK (0x3F << 0) +#define PSC_AON_BT_POWERUP_TIMER1_SHIFT (0) +#define PSC_AON_BT_POWERUP_TIMER2(n) (((n) & 0xFF) << 6) +#define PSC_AON_BT_POWERUP_TIMER2_MASK (0xFF << 6) +#define PSC_AON_BT_POWERUP_TIMER2_SHIFT (6) +#define PSC_AON_BT_POWERUP_TIMER3(n) (((n) & 0x3F) << 14) +#define PSC_AON_BT_POWERUP_TIMER3_MASK (0x3F << 14) +#define PSC_AON_BT_POWERUP_TIMER3_SHIFT (14) +#define PSC_AON_BT_POWERUP_TIMER4(n) (((n) & 0x3F) << 20) +#define PSC_AON_BT_POWERUP_TIMER4_MASK (0x3F << 20) +#define PSC_AON_BT_POWERUP_TIMER4_SHIFT (20) +#define PSC_AON_BT_POWERUP_TIMER5(n) (((n) & 0x3F) << 26) +#define PSC_AON_BT_POWERUP_TIMER5_MASK (0x3F << 26) +#define PSC_AON_BT_POWERUP_TIMER5_SHIFT (26) + +// reg_30 +#define PSC_AON_BT_POWERDN_START (1 << 0) + +// reg_34 +#define PSC_AON_BT_POWERUP_START (1 << 0) + +// reg_38 +#define PSC_AON_BT_CLK_STOP_REG (1 << 0) +#define PSC_AON_BT_ISO_EN_REG (1 << 1) +#define PSC_AON_BT_RESETN_ASSERT_REG (1 << 2) +#define PSC_AON_BT_PSW_EN_REG (1 << 3) +#define PSC_AON_BT_CLK_STOP_DR (1 << 4) +#define PSC_AON_BT_ISO_EN_DR (1 << 5) +#define PSC_AON_BT_RESETN_ASSERT_DR (1 << 6) +#define PSC_AON_BT_PSW_EN_DR (1 << 7) + +// reg_40 +#define PSC_AON_WLAN_PG_AUTO_EN (1 << 0) + +// reg_44 +#define PSC_AON_WLAN_PSW_ACK_VALID (1 << 0) +#define PSC_AON_WLAN_RESERVED(n) (((n) & 0x7F) << 1) +#define PSC_AON_WLAN_RESERVED_MASK (0x7F << 1) +#define PSC_AON_WLAN_RESERVED_SHIFT (1) +#define PSC_AON_WLAN_MAIN_STATE(n) (((n) & 0x3) << 8) +#define PSC_AON_WLAN_MAIN_STATE_MASK (0x3 << 8) +#define PSC_AON_WLAN_MAIN_STATE_SHIFT (8) +#define PSC_AON_WLAN_POWERDN_STATE(n) (((n) & 0x7) << 10) +#define PSC_AON_WLAN_POWERDN_STATE_MASK (0x7 << 10) +#define PSC_AON_WLAN_POWERDN_STATE_SHIFT (10) +#define PSC_AON_WLAN_POWERUP_STATE(n) (((n) & 0x7) << 13) +#define PSC_AON_WLAN_POWERUP_STATE_MASK (0x7 << 13) +#define PSC_AON_WLAN_POWERUP_STATE_SHIFT (13) + +// reg_48 +#define PSC_AON_WLAN_POWERDN_TIMER1(n) (((n) & 0x3F) << 0) +#define PSC_AON_WLAN_POWERDN_TIMER1_MASK (0x3F << 0) +#define PSC_AON_WLAN_POWERDN_TIMER1_SHIFT (0) +#define PSC_AON_WLAN_POWERDN_TIMER2(n) (((n) & 0x3F) << 6) +#define PSC_AON_WLAN_POWERDN_TIMER2_MASK (0x3F << 6) +#define PSC_AON_WLAN_POWERDN_TIMER2_SHIFT (6) +#define PSC_AON_WLAN_POWERDN_TIMER3(n) (((n) & 0x3F) << 12) +#define PSC_AON_WLAN_POWERDN_TIMER3_MASK (0x3F << 12) +#define PSC_AON_WLAN_POWERDN_TIMER3_SHIFT (12) +#define PSC_AON_WLAN_POWERDN_TIMER4(n) (((n) & 0x3F) << 18) +#define PSC_AON_WLAN_POWERDN_TIMER4_MASK (0x3F << 18) +#define PSC_AON_WLAN_POWERDN_TIMER4_SHIFT (18) +#define PSC_AON_WLAN_POWERDN_TIMER5(n) (((n) & 0xFF) << 24) +#define PSC_AON_WLAN_POWERDN_TIMER5_MASK (0xFF << 24) +#define PSC_AON_WLAN_POWERDN_TIMER5_SHIFT (24) + +// reg_4c +#define PSC_AON_WLAN_POWERUP_TIMER1(n) (((n) & 0x3F) << 0) +#define PSC_AON_WLAN_POWERUP_TIMER1_MASK (0x3F << 0) +#define PSC_AON_WLAN_POWERUP_TIMER1_SHIFT (0) +#define PSC_AON_WLAN_POWERUP_TIMER2(n) (((n) & 0xFF) << 6) +#define PSC_AON_WLAN_POWERUP_TIMER2_MASK (0xFF << 6) +#define PSC_AON_WLAN_POWERUP_TIMER2_SHIFT (6) +#define PSC_AON_WLAN_POWERUP_TIMER3(n) (((n) & 0x3F) << 14) +#define PSC_AON_WLAN_POWERUP_TIMER3_MASK (0x3F << 14) +#define PSC_AON_WLAN_POWERUP_TIMER3_SHIFT (14) +#define PSC_AON_WLAN_POWERUP_TIMER4(n) (((n) & 0x3F) << 20) +#define PSC_AON_WLAN_POWERUP_TIMER4_MASK (0x3F << 20) +#define PSC_AON_WLAN_POWERUP_TIMER4_SHIFT (20) +#define PSC_AON_WLAN_POWERUP_TIMER5(n) (((n) & 0x3F) << 26) +#define PSC_AON_WLAN_POWERUP_TIMER5_MASK (0x3F << 26) +#define PSC_AON_WLAN_POWERUP_TIMER5_SHIFT (26) + +// reg_50 +#define PSC_AON_WLAN_POWERDN_START (1 << 0) + +// reg_54 +#define PSC_AON_WLAN_POWERUP_START (1 << 0) + +// reg_58 +#define PSC_AON_WLAN_CLK_STOP_REG (1 << 0) +#define PSC_AON_WLAN_ISO_EN_REG (1 << 1) +#define PSC_AON_WLAN_RESETN_ASSERT_REG (1 << 2) +#define PSC_AON_WLAN_PSW_EN_REG (1 << 3) +#define PSC_AON_WLAN_CLK_STOP_DR (1 << 4) +#define PSC_AON_WLAN_ISO_EN_DR (1 << 5) +#define PSC_AON_WLAN_RESETN_ASSERT_DR (1 << 6) +#define PSC_AON_WLAN_PSW_EN_DR (1 << 7) + +// reg_60 +#define PSC_AON_CODEC_PG_AUTO_EN (1 << 0) + +// reg_64 +#define PSC_AON_CODEC_PSW_ACK_VALID (1 << 0) +#define PSC_AON_CODEC_RESERVED(n) (((n) & 0x7F) << 1) +#define PSC_AON_CODEC_RESERVED_MASK (0x7F << 1) +#define PSC_AON_CODEC_RESERVED_SHIFT (1) +#define PSC_AON_CODEC_MAIN_STATE(n) (((n) & 0x3) << 8) +#define PSC_AON_CODEC_MAIN_STATE_MASK (0x3 << 8) +#define PSC_AON_CODEC_MAIN_STATE_SHIFT (8) +#define PSC_AON_CODEC_POWERDN_STATE(n) (((n) & 0x7) << 10) +#define PSC_AON_CODEC_POWERDN_STATE_MASK (0x7 << 10) +#define PSC_AON_CODEC_POWERDN_STATE_SHIFT (10) +#define PSC_AON_CODEC_POWERUP_STATE(n) (((n) & 0x7) << 13) +#define PSC_AON_CODEC_POWERUP_STATE_MASK (0x7 << 13) +#define PSC_AON_CODEC_POWERUP_STATE_SHIFT (13) + +// reg_68 +#define PSC_AON_CODEC_POWERDN_TIMER1(n) (((n) & 0x3F) << 0) +#define PSC_AON_CODEC_POWERDN_TIMER1_MASK (0x3F << 0) +#define PSC_AON_CODEC_POWERDN_TIMER1_SHIFT (0) +#define PSC_AON_CODEC_POWERDN_TIMER2(n) (((n) & 0x3F) << 6) +#define PSC_AON_CODEC_POWERDN_TIMER2_MASK (0x3F << 6) +#define PSC_AON_CODEC_POWERDN_TIMER2_SHIFT (6) +#define PSC_AON_CODEC_POWERDN_TIMER3(n) (((n) & 0x3F) << 12) +#define PSC_AON_CODEC_POWERDN_TIMER3_MASK (0x3F << 12) +#define PSC_AON_CODEC_POWERDN_TIMER3_SHIFT (12) +#define PSC_AON_CODEC_POWERDN_TIMER4(n) (((n) & 0x3F) << 18) +#define PSC_AON_CODEC_POWERDN_TIMER4_MASK (0x3F << 18) +#define PSC_AON_CODEC_POWERDN_TIMER4_SHIFT (18) +#define PSC_AON_CODEC_POWERDN_TIMER5(n) (((n) & 0xFF) << 24) +#define PSC_AON_CODEC_POWERDN_TIMER5_MASK (0xFF << 24) +#define PSC_AON_CODEC_POWERDN_TIMER5_SHIFT (24) + +// reg_6c +#define PSC_AON_CODEC_POWERUP_TIMER1(n) (((n) & 0x3F) << 0) +#define PSC_AON_CODEC_POWERUP_TIMER1_MASK (0x3F << 0) +#define PSC_AON_CODEC_POWERUP_TIMER1_SHIFT (0) +#define PSC_AON_CODEC_POWERUP_TIMER2(n) (((n) & 0xFF) << 6) +#define PSC_AON_CODEC_POWERUP_TIMER2_MASK (0xFF << 6) +#define PSC_AON_CODEC_POWERUP_TIMER2_SHIFT (6) +#define PSC_AON_CODEC_POWERUP_TIMER3(n) (((n) & 0x3F) << 14) +#define PSC_AON_CODEC_POWERUP_TIMER3_MASK (0x3F << 14) +#define PSC_AON_CODEC_POWERUP_TIMER3_SHIFT (14) +#define PSC_AON_CODEC_POWERUP_TIMER4(n) (((n) & 0x3F) << 20) +#define PSC_AON_CODEC_POWERUP_TIMER4_MASK (0x3F << 20) +#define PSC_AON_CODEC_POWERUP_TIMER4_SHIFT (20) +#define PSC_AON_CODEC_POWERUP_TIMER5(n) (((n) & 0x3F) << 26) +#define PSC_AON_CODEC_POWERUP_TIMER5_MASK (0x3F << 26) +#define PSC_AON_CODEC_POWERUP_TIMER5_SHIFT (26) + +// reg_70 +#define PSC_AON_CODEC_POWERDN_START (1 << 0) + +// reg_74 +#define PSC_AON_CODEC_POWERUP_START (1 << 0) + +// reg_78 +#define PSC_AON_CODEC_CLK_STOP_REG (1 << 0) +#define PSC_AON_CODEC_ISO_EN_REG (1 << 1) +#define PSC_AON_CODEC_RESETN_ASSERT_REG (1 << 2) +#define PSC_AON_CODEC_PSW_EN_REG (1 << 3) +#define PSC_AON_CODEC_CLK_STOP_DR (1 << 4) +#define PSC_AON_CODEC_ISO_EN_DR (1 << 5) +#define PSC_AON_CODEC_RESETN_ASSERT_DR (1 << 6) +#define PSC_AON_CODEC_PSW_EN_DR (1 << 7) + +// reg_80 +#define PSC_AON_MCU_INTR_MASK(n) (((n) & 0xFFFFFFFF) << 0) +#define PSC_AON_MCU_INTR_MASK_MASK (0xFFFFFFFF << 0) +#define PSC_AON_MCU_INTR_MASK_SHIFT (0) + +// reg_84 +#define PSC_AON_MCU_INTR_MASK2(n) (((n) & 0xFFFF) << 0) +#define PSC_AON_MCU_INTR_MASK2_MASK (0xFFFF << 0) +#define PSC_AON_MCU_INTR_MASK2_SHIFT (0) + +// reg_88 +#define PSC_AON_MCU_INTR_MASK_STATUS(n) (((n) & 0xFFFFFFFF) << 0) +#define PSC_AON_MCU_INTR_MASK_STATUS_MASK (0xFFFFFFFF << 0) +#define PSC_AON_MCU_INTR_MASK_STATUS_SHIFT (0) + +// reg_8c +#define PSC_AON_MCU_INTR_MASK_STATUS2(n) (((n) & 0xFFFF) << 0) +#define PSC_AON_MCU_INTR_MASK_STATUS2_MASK (0xFFFF << 0) +#define PSC_AON_MCU_INTR_MASK_STATUS2_SHIFT (0) + +// reg_90 +#define PSC_AON_BT_INTR_MASK(n) (((n) & 0xFFFFFFFF) << 0) +#define PSC_AON_BT_INTR_MASK_MASK (0xFFFFFFFF << 0) +#define PSC_AON_BT_INTR_MASK_SHIFT (0) + +// reg_94 +#define PSC_AON_BT_INTR_MASK2(n) (((n) & 0xFFFF) << 0) +#define PSC_AON_BT_INTR_MASK2_MASK (0xFFFF << 0) +#define PSC_AON_BT_INTR_MASK2_SHIFT (0) + +// reg_98 +#define PSC_AON_BT_INTR_MASK_STATUS(n) (((n) & 0xFFFFFFFF) << 0) +#define PSC_AON_BT_INTR_MASK_STATUS_MASK (0xFFFFFFFF << 0) +#define PSC_AON_BT_INTR_MASK_STATUS_SHIFT (0) + +// reg_9c +#define PSC_AON_BT_INTR_MASK_STATUS2(n) (((n) & 0xFFFF) << 0) +#define PSC_AON_BT_INTR_MASK_STATUS2_MASK (0xFFFF << 0) +#define PSC_AON_BT_INTR_MASK_STATUS2_SHIFT (0) + +// reg_a0 +#define PSC_AON_WLAN_INTR_MASK(n) (((n) & 0xFFFFFFFF) << 0) +#define PSC_AON_WLAN_INTR_MASK_MASK (0xFFFFFFFF << 0) +#define PSC_AON_WLAN_INTR_MASK_SHIFT (0) + +// reg_a4 +#define PSC_AON_WLAN_INTR_MASK2(n) (((n) & 0xFFFF) << 0) +#define PSC_AON_WLAN_INTR_MASK2_MASK (0xFFFF << 0) +#define PSC_AON_WLAN_INTR_MASK2_SHIFT (0) + +// reg_a8 +#define PSC_AON_WLAN_INTR_MASK_STATUS(n) (((n) & 0xFFFFFFFF) << 0) +#define PSC_AON_WLAN_INTR_MASK_STATUS_MASK (0xFFFFFFFF << 0) +#define PSC_AON_WLAN_INTR_MASK_STATUS_SHIFT (0) + +// reg_ac +#define PSC_AON_WLAN_INTR_MASK_STATUS2(n) (((n) & 0xFFFF) << 0) +#define PSC_AON_WLAN_INTR_MASK_STATUS2_MASK (0xFFFF << 0) +#define PSC_AON_WLAN_INTR_MASK_STATUS2_SHIFT (0) + +// reg_b0 +#define PSC_AON_INTR_RAW_STATUS(n) (((n) & 0xFFFFFFFF) << 0) +#define PSC_AON_INTR_RAW_STATUS_MASK (0xFFFFFFFF << 0) +#define PSC_AON_INTR_RAW_STATUS_SHIFT (0) + +// reg_b4 +#define PSC_AON_INTR_RAW_STATUS2(n) (((n) & 0xFFFF) << 0) +#define PSC_AON_INTR_RAW_STATUS2_MASK (0xFFFF << 0) +#define PSC_AON_INTR_RAW_STATUS2_SHIFT (0) + +#endif diff --git a/platform/hal/best2300p/reg_sensor_eng_best2300p.h b/platform/hal/best2300p/reg_sensor_eng_best2300p.h new file mode 100644 index 0000000..bf5faf7 --- /dev/null +++ b/platform/hal/best2300p/reg_sensor_eng_best2300p.h @@ -0,0 +1,119 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_SENSOR_ENG_BEST2300P_H__ +#define __REG_SENSOR_ENG_BEST2300P_H__ + +#include "plat_types.h" + +struct SENSOR_ENG_T { + __IO uint32_t SLV0_CONFIG_REG; // 0000 + __IO uint32_t SLV1_CONFIG_REG; // 0004 + __IO uint32_t SLV2_CONFIG_REG; // 0008 + __IO uint32_t SLV3_CONFIG_REG; // 000C + __IO uint32_t GLOBAL_CFG0_REG; // 0010 + __IO uint32_t GLOBAL_CFG1_REG; // 0014 + __IO uint32_t GLOBAL_CFG2_REG; // 0018 + __IO uint32_t GLOBAL_CFG3_REG; // 001C + __IO uint32_t SLV0_INTR_MASK; // 0020 + __IO uint32_t SLV1_INTR_MASK; // 0024 + __IO uint32_t SLV2_INTR_MASK; // 0028 + __IO uint32_t SLV3_INTR_MASK; // 002C + __IO uint32_t SENSOR_INTR_CLR; // 0030 + __I uint32_t SENSOR_INTR_STS; // 0034 + __IO uint32_t TIMER_INTVL_NUM; // 0038 + __IO uint32_t SENSOR_STATUS; // 003C + __IO uint32_t I2C0_BASE_ADDR; // 0040 + __IO uint32_t I2C1_BASE_ADDR; // 0044 + __IO uint32_t SPI0_BASE_ADDR; // 0048 + __IO uint32_t SPI1_BASE_ADDR; // 004C + __IO uint32_t SPI2_BASE_ADDR; // 0050 +}; + +// 0000 - 000C +#define SLV_SPI_RXDS (1 << 15) +#define SLV_RDN_WR (1 << 14) +#define SLV_I2C_SPI_SEL_SHIFT 11 +#define SLV_I2C_SPI_SEL_MASK (0x7 << SLV_I2C_SPI_SEL_SHIFT) +#define SLV_I2C_SPI_SEL(n) BITFIELD_VAL(SLV_I2C_SPI_SEL, n) +#define SLV_SLV_DEV_ID_SHIFT 1 +#define SLV_SLV_DEV_ID_MASK (0x3FF << SLV_SLV_DEV_ID_SHIFT) +#define SLV_SLV_DEV_ID(n) BITFIELD_VAL(SLV_SLV_DEV_ID, n) +#define SLV_ENABLE (1 << 0) + +// 0010 +#define GBL_CODEC_SX_SEL_SHIFT 5 +#define GBL_CODEC_SX_SEL_MASK (0x3 << GBL_CODEC_SX_SEL_SHIFT) +#define GBL_CODEC_SX_SEL(n) BITFIELD_VAL(GBL_CODEC_SX_SEL, n) +#define GBL_TRI_INORDER (1 << 4) +#define GBL_SENSORHUB_EN (1 << 3) +#define GBL_RESERVED (1 << 2) +#define GBL_TIMER_SEL (1 << 1) +#define GBL_TRIGGER_TYPE (1 << 0) + +// 0014 +#define NUM_OF_RX_LLI3_SHIFT 24 +#define NUM_OF_RX_LLI3_MASK (0xFF << NUM_OF_RX_LLI3_SHIFT) +#define NUM_OF_RX_LLI3(n) BITFIELD_VAL(NUM_OF_RX_LLI3, n) +#define NUM_OF_RX_LLI2_SHIFT 16 +#define NUM_OF_RX_LLI2_MASK (0xFF << NUM_OF_RX_LLI2_SHIFT) +#define NUM_OF_RX_LLI2(n) BITFIELD_VAL(NUM_OF_RX_LLI2, n) +#define NUM_OF_RX_LLI1_SHIFT 8 +#define NUM_OF_RX_LLI1_MASK (0xFF << NUM_OF_RX_LLI1_SHIFT) +#define NUM_OF_RX_LLI1(n) BITFIELD_VAL(NUM_OF_RX_LLI1, n) +#define NUM_OF_RX_LLI0_SHIFT 0 +#define NUM_OF_RX_LLI0_MASK (0xFF << NUM_OF_RX_LLI0_SHIFT) +#define NUM_OF_RX_LLI0(n) BITFIELD_VAL(NUM_OF_RX_LLI0, n) + +// 001C +#define NUM_OF_TX_LLI3_SHIFT 24 +#define NUM_OF_TX_LLI3_MASK (0xFF << NUM_OF_TX_LLI3_SHIFT) +#define NUM_OF_TX_LLI3(n) BITFIELD_VAL(NUM_OF_TX_LLI3, n) +#define NUM_OF_TX_LLI2_SHIFT 16 +#define NUM_OF_TX_LLI2_MASK (0xFF << NUM_OF_TX_LLI2_SHIFT) +#define NUM_OF_TX_LLI2(n) BITFIELD_VAL(NUM_OF_TX_LLI2, n) +#define NUM_OF_TX_LLI1_SHIFT 8 +#define NUM_OF_TX_LLI1_MASK (0xFF << NUM_OF_TX_LLI1_SHIFT) +#define NUM_OF_TX_LLI1(n) BITFIELD_VAL(NUM_OF_TX_LLI1, n) +#define NUM_OF_TX_LLI0_SHIFT 0 +#define NUM_OF_TX_LLI0_MASK (0xFF << NUM_OF_TX_LLI0_SHIFT) +#define NUM_OF_TX_LLI0(n) BITFIELD_VAL(NUM_OF_TX_LLI0, n) + +// 0030 +#define SENSOR_INTR_CLEAR (1 << 0) + +// 0034 +#define EXT_SENSOR3_INTR (1 << 4) +#define EXT_SENSOR2_INTR (1 << 3) +#define EXT_SENSOR1_INTR (1 << 2) +#define EXT_SENSOR0_INTR (1 << 1) +#define SENSOR_WKUP_INTR (1 << 0) + +// 0038 +#define TIMER_INTERVAL_NUM_SHIFT 0 +#define TIMER_INTERVAL_NUM_MASK (0xFF << TIMER_INTERVAL_NUM_SHIFT) +#define TIMER_INTERVAL_NUM(n) BITFIELD_VAL(TIMER_INTERVAL_NUM, n) + +// 003C +#define SENSOR_ENG_FSM_SHIFT 8 +#define SENSOR_ENG_FSM_MASK (0xF << SENSOR_ENG_FSM_SHIFT) +#define SENSOR_ENG_FSM(n) BITFIELD_VAL(SENSOR_ENG_FSM, n) +#define SENSOR3_BUSY (1 << 7) +#define SENSOR2_BUSY (1 << 6) +#define SENSOR1_BUSY (1 << 5) +#define SENSOR0_BUSY (1 << 4) + +#endif + diff --git a/platform/hal/hal_analogif.h b/platform/hal/hal_analogif.h new file mode 100644 index 0000000..cb369fd --- /dev/null +++ b/platform/hal/hal_analogif.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_ANALOGIF_H__ +#define __HAL_ANALOGIF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int hal_analogif_open(void); + +int hal_analogif_reg_write(unsigned short reg, unsigned short val); + +int hal_analogif_reg_read(unsigned short reg, unsigned short *val); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_aud.h b/platform/hal/hal_aud.h new file mode 100644 index 0000000..64d2889 --- /dev/null +++ b/platform/hal/hal_aud.h @@ -0,0 +1,354 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef AUDIO_DEF_H +#define AUDIO_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define CODEC_FREQ_24M 24000000 +#define CODEC_FREQ_26M 26000000 +#define CODEC_FREQ_24P576M 24576000 +#define CODEC_FREQ_22P5792M 22579200 + +#define CODEC_FREQ_48K_SERIES CODEC_FREQ_24P576M +#define CODEC_FREQ_44_1K_SERIES CODEC_FREQ_22P5792M + +#if 0 +#elif defined(CHIP_BEST3001) || defined(CHIP_BEST3003) || defined(CHIP_BEST3005) + +#define CODEC_FREQ_CRYSTAL CODEC_FREQ_24M + +#define CODEC_PLL_DIV 36 +#define CODEC_CMU_DIV 9 +#ifdef CHIP_BEST3001 +#define CODEC_PLAYBACK_BIT_DEPTH 20 +#else +#define CODEC_PLAYBACK_BIT_DEPTH 24 +#endif + +#elif defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || \ + defined(CHIP_BEST2300) || defined(CHIP_BEST2300A) || \ + defined(CHIP_BEST2300P) + +#define CODEC_FREQ_EXTRA_DIV 2 + +#define CODEC_PLL_DIV 16 +#define CODEC_CMU_DIV 8 +#define CODEC_PLAYBACK_BIT_DEPTH 24 + +#elif defined(CHIP_BEST1000) + +#if defined(__AUDIO_DIV_10___) +#define CODEC_PLL_DIV 10 +#elif defined(__AUDIO_DIV_9___) +#define CODEC_PLL_DIV 9 +#else +#define CODEC_PLL_DIV 8 +#endif +#define CODEC_CMU_DIV CODEC_PLL_DIV +#define CODEC_PLAYBACK_BIT_DEPTH 18 + +#elif defined(CHIP_BEST2000) + +#define CODEC_PLL_DIV 32 +#define CODEC_CMU_DIV 8 +#define CODEC_PLAYBACK_BIT_DEPTH 20 + +#elif defined(CHIP_BEST2001) + +#define CODEC_PLL_DIV 38 +#define CODEC_CMU_DIV 8 +#define CODEC_PLAYBACK_BIT_DEPTH 20 + +#else + +#error "Please update audio definitions" + +#endif + +#ifndef CODEC_FREQ_CRYSTAL +#define CODEC_FREQ_CRYSTAL CODEC_FREQ_26M +#endif +#ifndef CODEC_FREQ_EXTRA_DIV +#define CODEC_FREQ_EXTRA_DIV 1 +#endif + +#define CODEC_TX_PA_GAIN_DEFAULT -1 + +enum AUD_STREAM_USE_DEVICE_T{ + AUD_STREAM_USE_DEVICE_NULL = 0, + AUD_STREAM_USE_EXT_CODEC, + AUD_STREAM_USE_I2S0_MASTER, + AUD_STREAM_USE_I2S0_SLAVE, + AUD_STREAM_USE_I2S1_MASTER, + AUD_STREAM_USE_I2S1_SLAVE, + AUD_STREAM_USE_TDM0_MASTER, + AUD_STREAM_USE_TDM0_SLAVE, + AUD_STREAM_USE_TDM1_MASTER, + AUD_STREAM_USE_TDM1_SLAVE, + AUD_STREAM_USE_INT_CODEC, + AUD_STREAM_USE_INT_SPDIF, + AUD_STREAM_USE_BT_PCM, + AUD_STREAM_USE_DPD_RX, + AUD_STREAM_USE_MC, +}; + +enum AUD_SAMPRATE_T { + AUD_SAMPRATE_NULL = 0, + AUD_SAMPRATE_7350 = 7350, + AUD_SAMPRATE_8000 = 8000, + AUD_SAMPRATE_8463 = 8463, // 26M / 512 / 6 + AUD_SAMPRATE_14700 = 14700, + AUD_SAMPRATE_16000 = 16000, + AUD_SAMPRATE_16927 = 16927, // 26M / 512 / 3 + AUD_SAMPRATE_22050 = 22050, + AUD_SAMPRATE_24000 = 24000, + AUD_SAMPRATE_32000 = 32000, + AUD_SAMPRATE_44100 = 44100, + AUD_SAMPRATE_48000 = 48000, + AUD_SAMPRATE_50781 = 50781, // 26M / 512 + AUD_SAMPRATE_64000 = 64000, + AUD_SAMPRATE_88200 = 88200, + AUD_SAMPRATE_96000 = 96000, + AUD_SAMPRATE_101562 = 101562, // 26M / 256 + AUD_SAMPRATE_128000 = 128000, + AUD_SAMPRATE_176400 = 176400, + AUD_SAMPRATE_192000 = 192000, + AUD_SAMPRATE_203125 = 203125, // 26M / 128 + AUD_SAMPRATE_256000 = 256000, + AUD_SAMPRATE_352800 = 352800, + AUD_SAMPRATE_384000 = 384000, + AUD_SAMPRATE_406250 = 406250, // 26M / 64 + AUD_SAMPRATE_512000 = 512000, + AUD_SAMPRATE_705600 = 705600, + AUD_SAMPRATE_768000 = 768000, + AUD_SAMPRATE_1024000 = 1024000, +}; + +enum AUD_CHANNEL_NUM_T { + AUD_CHANNEL_NUM_NULL = 0, + AUD_CHANNEL_NUM_1 = 1, + AUD_CHANNEL_NUM_2 = 2, + AUD_CHANNEL_NUM_3 = 3, + AUD_CHANNEL_NUM_4 = 4, + AUD_CHANNEL_NUM_5 = 5, + AUD_CHANNEL_NUM_6 = 6, + AUD_CHANNEL_NUM_7 = 7, + AUD_CHANNEL_NUM_8 = 8, +}; + +// For preprocess check +#define AUD_CHANNEL_MAP_CH0 (1 << 0) +#define AUD_CHANNEL_MAP_CH1 (1 << 1) +#define AUD_CHANNEL_MAP_CH2 (1 << 2) +#define AUD_CHANNEL_MAP_CH3 (1 << 3) +#define AUD_CHANNEL_MAP_CH4 (1 << 4) +#define AUD_CHANNEL_MAP_CH5 (1 << 5) +#define AUD_CHANNEL_MAP_CH6 (1 << 6) +#define AUD_CHANNEL_MAP_CH7 (1 << 7) +#define AUD_CHANNEL_MAP_DIGMIC_CH0 (1 << 8) +#define AUD_CHANNEL_MAP_DIGMIC_CH1 (1 << 9) +#define AUD_CHANNEL_MAP_DIGMIC_CH2 (1 << 10) +#define AUD_CHANNEL_MAP_DIGMIC_CH3 (1 << 11) +#define AUD_CHANNEL_MAP_DIGMIC_CH4 (1 << 12) +#define AUD_CHANNEL_MAP_DIGMIC_CH5 (1 << 13) +#define AUD_CHANNEL_MAP_DIGMIC_CH6 (1 << 14) +#define AUD_CHANNEL_MAP_DIGMIC_CH7 (1 << 15) +#define AUD_CHANNEL_MAP_ECMIC_CH0 (1 << 16) +#define AUD_CHANNEL_MAP_ECMIC_CH1 (1 << 17) + +#define AUD_CHANNEL_MAP_ANA_ALL (0x000000FF) +#define AUD_CHANNEL_MAP_DIGMIC_ALL (0x0000FF00) +#define AUD_CHANNEL_MAP_NORMAL_ALL (0x0000FFFF) +#define AUD_CHANNEL_MAP_ALL (0x0003FFFF) + +enum AUD_CHANNEL_MAP_T { + AUD_CHANNEL_MAP_END = AUD_CHANNEL_MAP_ECMIC_CH1, +}; + +enum AUD_VMIC_MAP_T { + AUD_VMIC_MAP_VMIC1 = (AUD_CHANNEL_MAP_END << 1), + AUD_VMIC_MAP_VMIC2 = (AUD_CHANNEL_MAP_END << 2), + AUD_VMIC_MAP_VMIC3 = (AUD_CHANNEL_MAP_END << 3), + AUD_VMIC_MAP_VMIC4 = (AUD_CHANNEL_MAP_END << 4), + AUD_VMIC_MAP_VMIC5 = (AUD_CHANNEL_MAP_END << 5), +}; + +enum AUD_BITS_T { + AUD_BITS_NULL = 0, + AUD_BITS_8 = 8, + AUD_BITS_12 = 12, + AUD_BITS_16 = 16, + AUD_BITS_20 = 20, + AUD_BITS_24 = 24, + AUD_BITS_32 = 32, +}; + +enum AUD_STREAM_ID_T { + AUD_STREAM_ID_0 = 0, + AUD_STREAM_ID_1, + AUD_STREAM_ID_2, +#ifdef __ANC_ASSIST__ + AUD_STREAM_ID_3, +#endif + AUD_STREAM_ID_NUM, +}; + +enum AUD_STREAM_T { + AUD_STREAM_PLAYBACK = 0, + AUD_STREAM_CAPTURE, + + AUD_STREAM_NUM, +}; + +// TODO: Need rename +enum AUD_IO_PATH_T { + AUD_IO_PATH_NULL = 0, + + // Input path + AUD_INPUT_PATH_MAINMIC, + AUD_INPUT_PATH_VADMIC, + AUD_INPUT_PATH_ASRMIC, + AUD_INPUT_PATH_LINEIN, + AUD_INPUT_PATH_NTMIC, + AUD_INPUT_PATH_ANC_WNR, + AUD_INPUT_PATH_USBAUDIO, +#ifdef __ANC_ASSIST__ + AUD_INPUT_PATH_AF_ANC, +#endif + // Output path + AUD_OUTPUT_PATH_SPEAKER, +}; + +struct AUD_IO_PATH_CFG_T { + enum AUD_IO_PATH_T io_path; + unsigned int cfg; +}; + +enum ANC_TYPE_T { + ANC_NOTYPE = (1 << 0), + ANC_FEEDFORWARD=(1 << 1), + ANC_FEEDBACK=(1 << 2), + ANC_TALKTHRU=(1 << 3), + ANC_MUSICCANCLE=(1 << 4), +}; + +struct CODEC_DAC_VOL_T { + signed char tx_pa_gain :6; + unsigned char sdm_gain :2; + signed char sdac_volume; +}; + +typedef signed char CODEC_ADC_VOL_T; + +enum TGT_VOLUME_LEVEL_T { + TGT_VOLUME_LEVEL_WARNINGTONE = 0, + + TGT_VOLUME_LEVEL_MUTE, + TGT_VOLUME_LEVEL_0, + TGT_VOLUME_LEVEL_1, + TGT_VOLUME_LEVEL_2, + TGT_VOLUME_LEVEL_3, + TGT_VOLUME_LEVEL_4, + TGT_VOLUME_LEVEL_5, + TGT_VOLUME_LEVEL_6, + TGT_VOLUME_LEVEL_7, + TGT_VOLUME_LEVEL_8, + TGT_VOLUME_LEVEL_9, + TGT_VOLUME_LEVEL_10, + TGT_VOLUME_LEVEL_11, + TGT_VOLUME_LEVEL_12, + TGT_VOLUME_LEVEL_13, + TGT_VOLUME_LEVEL_14, + TGT_VOLUME_LEVEL_15, + + TGT_VOLUME_LEVEL_QTY +}; + +enum TGT_ADC_VOL_LEVEL_T { + TGT_ADC_VOL_LEVEL_0, + TGT_ADC_VOL_LEVEL_1, + TGT_ADC_VOL_LEVEL_2, + TGT_ADC_VOL_LEVEL_3, + TGT_ADC_VOL_LEVEL_4, + TGT_ADC_VOL_LEVEL_5, + TGT_ADC_VOL_LEVEL_6, + TGT_ADC_VOL_LEVEL_7, + TGT_ADC_VOL_LEVEL_8, + TGT_ADC_VOL_LEVEL_9, + TGT_ADC_VOL_LEVEL_10, + TGT_ADC_VOL_LEVEL_11, + TGT_ADC_VOL_LEVEL_12, + TGT_ADC_VOL_LEVEL_13, + TGT_ADC_VOL_LEVEL_14, + TGT_ADC_VOL_LEVEL_15, + + TGT_ADC_VOL_LEVEL_QTY +}; + +typedef void (*AUD_VAD_CALLBACK)(int found); + +enum AUD_VAD_TYPE_T { + AUD_VAD_TYPE_NONE = 0, + AUD_VAD_TYPE_MIX, + AUD_VAD_TYPE_DIG, + AUD_VAD_TYPE_ANA, + + AUD_VAD_TYPE_NUM, +}; + +struct AUD_VAD_CONFIG_T { + enum AUD_VAD_TYPE_T type; + enum AUD_SAMPRATE_T sample_rate; + enum AUD_BITS_T bits; + AUD_VAD_CALLBACK handler; + + uint8_t udc; + uint8_t upre; + uint8_t frame_len; + uint8_t mvad; + + uint8_t dig_mode; + uint8_t pre_gain; + uint8_t sth; + uint8_t dc_bypass; + + uint8_t ds_bypass; + uint8_t pre_bypass; + uint8_t adc_gain; + + uint16_t range[4]; + + uint32_t frame_th[3]; + uint32_t psd_th[2]; +}; + +struct CODEC_VAD_BUF_INFO_T { + uint32_t base_addr; + uint32_t buf_size; + uint32_t data_count; + uint32_t addr_count; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* AUDIO_DEF_H */ diff --git a/platform/hal/hal_bootmode.c b/platform/hal/hal_bootmode.c new file mode 100644 index 0000000..24524de --- /dev/null +++ b/platform/hal/hal_bootmode.c @@ -0,0 +1,99 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_cmu.h" +#include "hal_bootmode.h" +#include "hal_location.h" +#include "cmsis.h" + +// BOOTMODE +#define CMU_BOOTMODE_WATCHDOG (1 << 0) +#define CMU_BOOTMODE_GLOBAL (1 << 1) +#define CMU_BOOTMODE_RTC (1 << 2) +#define CMU_BOOTMODE_CHARGER (1 << 3) + +static union HAL_HW_BOOTMODE_T BOOT_BSS_LOC hw_bm; + +union HAL_HW_BOOTMODE_T hal_hw_bootmode_get(void) +{ + return hw_bm; +} + +union HAL_HW_BOOTMODE_T hal_rom_hw_bootmode_get(void) +{ + union HAL_HW_BOOTMODE_T bm; + volatile uint32_t *addr; + + addr = hal_cmu_get_bootmode_addr(); + + bm.reg = *addr & HAL_HW_BOOTMODE_MASK; + return bm; +} + +void BOOT_TEXT_FLASH_LOC hal_hw_bootmode_init(void) +{ + volatile uint32_t *addr; + + addr = hal_cmu_get_bootmode_addr(); + + hw_bm.reg = *addr & HAL_HW_BOOTMODE_MASK; +#if defined(CHIP_BEST3001) || defined(CHIP_BEST3005) + *addr = (*addr | HAL_HW_BOOTMODE_MASK) >> 2; +#else + *addr = *addr | HAL_HW_BOOTMODE_MASK; +#endif +} + +uint32_t hal_sw_bootmode_get(void) +{ + volatile uint32_t *addr; + + addr = hal_cmu_get_bootmode_addr(); + + return *addr & HAL_SW_BOOTMODE_MASK; +} + +void hal_sw_bootmode_set(uint32_t bm) +{ + uint32_t lock; + volatile uint32_t *addr; + + addr = hal_cmu_get_bootmode_addr(); + + lock = int_lock(); +#if defined(CHIP_BEST3001) || defined(CHIP_BEST3005) + *addr = ((*addr | bm) & HAL_SW_BOOTMODE_MASK) >> 2; +#else + *addr = (*addr | bm) & HAL_SW_BOOTMODE_MASK; +#endif + int_unlock(lock); +} + +void hal_sw_bootmode_clear(uint32_t bm) +{ + uint32_t lock; + volatile uint32_t *addr; + + addr = hal_cmu_get_bootmode_addr(); + + lock = int_lock(); +#if defined(CHIP_BEST3001) || defined(CHIP_BEST3005) + *addr = ((*addr & ~bm) & HAL_SW_BOOTMODE_MASK) >> 2; +#else + *addr = (*addr & ~bm) & HAL_SW_BOOTMODE_MASK; +#endif + int_unlock(lock); +} + diff --git a/platform/hal/hal_bootmode.h b/platform/hal/hal_bootmode.h new file mode 100644 index 0000000..a3fa501 --- /dev/null +++ b/platform/hal/hal_bootmode.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_BOOTMODE_H__ +#define __HAL_BOOTMODE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" + +#define HAL_HW_BOOTMODE_MASK (0xF << 0) +#define HAL_SW_BOOTMODE_MASK (0x0FFFFFFF << 4) + +// SW_BOOTMODE_START (1 << 4) +#define HAL_SW_BOOTMODE_READ_ENABLED (1 << 4) +#define HAL_SW_BOOTMODE_WRITE_ENABLED (1 << 5) +#define HAL_SW_BOOTMODE_JTAG_ENABLED (1 << 6) +#define HAL_SW_BOOTMODE_FORCE_USB_DLD (1 << 7) +#define HAL_SW_BOOTMODE_FORCE_UART_DLD (1 << 8) +#define HAL_SW_BOOTMODE_DLD_TRANS_UART (1 << 9) +#define HAL_SW_BOOTMODE_SKIP_FLASH_BOOT (1 << 10) +#define HAL_SW_BOOTMODE_CHIP_TEST (1 << 11) +#define HAL_SW_BOOTMODE_FACTORY (1 << 12) +#define HAL_SW_BOOTMODE_CALIB (1 << 13) +#define HAL_SW_BOOTMODE_ROM_RESERVED_14 (1 << 14) +#define HAL_SW_BOOTMODE_FLASH_BOOT (1 << 15) +#define HAL_SW_BOOTMODE_REBOOT (1 << 16) +#define HAL_SW_BOOTMODE_ROM_RESERVED_17 (1 << 17) +#define HAL_SW_BOOTMODE_FORCE_USB_PLUG_IN (1 << 18) +#define HAL_SW_BOOTMODE_POWER_DOWN_WAKEUP (1 << 19) + +// APP_BOOTMODE_START (1 << 20) +// Add new application bootmodes here (from highest bit to lowest bit) + +#define HAL_SW_BOOTMODE_TEST_MASK (7 << 20) +#define HAL_SW_BOOTMODE_TEST_MODE (1 << 20) +#define HAL_SW_BOOTMODE_TEST_SIGNALINGMODE (1 << 21) +#define HAL_SW_BOOTMODE_TEST_NOSIGNALINGMODE (1 << 22) + +#define HAL_SW_BOOTMODE_ENTER_HIDE_BOOT (1 << 23) + +#define HAL_SW_BOOTMODE_RESERVED_BIT24 (1 << 24) +#define HAL_SW_BOOTMODE_REBOOT_FROM_CRASH (1 << 25) +#define HAL_SW_BOOTMODE_SINGLE_LINE_DOWNLOAD (1 << 26) + +#ifdef __USB_COMM__ +#define HAL_SW_BOOTMODE_CDC_COMM (1 << 28) +#endif +#ifdef ANC_APP +#define HAL_SW_BOOTMODE_REBOOT_BT_ON (1 << 29) +#define HAL_SW_BOOTMODE_REBOOT_ANC_ON (1 << 30) +#endif + +#ifdef USER_REBOOT_PLAY_MUSIC_AUTO +#define HAL_SW_BOOTMODE_LOCAL_PLAYER (1 << 31) +#endif + +// APP_BOOTMODE_END (1 << 31) +// SW_BOOTMODE_END (1 << 31) + +union HAL_HW_BOOTMODE_T { + struct { + uint8_t watchdog : 1; + uint8_t global : 1; + uint8_t rtc : 1; + uint8_t charger : 1; + }; + uint8_t reg; +}; + +union HAL_HW_BOOTMODE_T hal_rom_hw_bootmode_get(void); + +union HAL_HW_BOOTMODE_T hal_hw_bootmode_get(void); + +void hal_hw_bootmode_init(void); + +uint32_t hal_sw_bootmode_get(void); + +void hal_sw_bootmode_set(uint32_t bm); + +void hal_sw_bootmode_clear(uint32_t bm); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_btdump.c b/platform/hal/hal_btdump.c new file mode 100644 index 0000000..6d869d8 --- /dev/null +++ b/platform/hal/hal_btdump.c @@ -0,0 +1,83 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" + +#ifdef BTDUMP_BASE + +#include "hal_cmu.h" +#include "hal_btdump.h" + +#define BTDUMP_DMA_CTL_REG_OFFSET 0x30 +#define BTDUMP_DMA_CTL_MASK 0xFFFFFFFE +#define BTDUMP_DEVICE_EN_MASK 0xFFFFFFFE +#define BTDUMP_FM_PSD_MASK 0xFFFFFFDF +#define BTDUMP_DEVICE_EN (1 << 0) +#define BTDUMP_DMA_CTL_EN (1 << 0) +#define BTDUMP_FM_PSD_EN (1 << 5) +#define BTDUMP_DMA_CTL_DISABLE (0 << 0) +#define BTDUMP_DEVICE_DISABLE (0 << 0) + +#define btdump_read32(b,a) \ + (*(volatile uint32_t *)(b+a)) + +#define btdump_write32(v,b,a) \ + ((*(volatile uint32_t *)(b+a)) = v) + +void hal_btdump_clk_enable(void) +{ + hal_cmu_clock_enable(HAL_CMU_MOD_H_BT_DUMP); + hal_cmu_reset_clear(HAL_CMU_MOD_H_BT_DUMP); +} + +void hal_btdump_clk_disable(void) +{ + hal_cmu_reset_set(HAL_CMU_MOD_H_BT_DUMP); + hal_cmu_clock_disable(HAL_CMU_MOD_H_BT_DUMP); +} + +void hal_btdump_enable(void) +{ + uint32_t val; + + val = btdump_read32(BTDUMP_BASE,BTDUMP_DMA_CTL_REG_OFFSET); + val &= BTDUMP_DMA_CTL_MASK; + val |= BTDUMP_DMA_CTL_EN; + btdump_write32(val,BTDUMP_BASE,BTDUMP_DMA_CTL_REG_OFFSET); + + val = btdump_read32(BTDUMP_BASE,0); + val &= BTDUMP_DEVICE_EN_MASK; + val |= BTDUMP_DEVICE_EN; + val &= BTDUMP_FM_PSD_MASK; + val |= BTDUMP_FM_PSD_EN; + btdump_write32(val,BTDUMP_BASE,0); +} + +void hal_btdump_disable(void) +{ + uint32_t val; + + val = btdump_read32(BTDUMP_BASE,BTDUMP_DMA_CTL_REG_OFFSET); + val &= BTDUMP_DMA_CTL_MASK; + val |= BTDUMP_DMA_CTL_DISABLE; + btdump_write32(val,BTDUMP_BASE,BTDUMP_DMA_CTL_REG_OFFSET); + + val = btdump_read32(BTDUMP_BASE,0); + val &= BTDUMP_DEVICE_EN_MASK; + val |= BTDUMP_DEVICE_DISABLE; + btdump_write32(val,BTDUMP_BASE,0); +} + +#endif \ No newline at end of file diff --git a/platform/hal/hal_btdump.h b/platform/hal/hal_btdump.h new file mode 100644 index 0000000..cadb82b --- /dev/null +++ b/platform/hal/hal_btdump.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_BTDUMP_H__ +#define __HAL_BTDUMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void hal_btdump_clk_enable(void); +void hal_btdump_clk_disable(void); + +void hal_btdump_enable(void); +void hal_btdump_disable(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/platform/hal/hal_btpcm.c b/platform/hal/hal_btpcm.c new file mode 100644 index 0000000..cdc606e --- /dev/null +++ b/platform/hal/hal_btpcm.c @@ -0,0 +1,211 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" + +#ifdef BTPCM_BASE + +#include "plat_types.h" +#include "reg_btpcmip.h" +#include "hal_btpcmip.h" +#include "hal_btpcm.h" +#include "hal_uart.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "hal_cmu.h" + +//#define BTPCM_CLOCK_SOURCE 240000000 +#define BTPCM_CLOCK_SOURCE 22579200 +//#define BTPCM_CLOCK_SOURCE 48000000 +//#define BTPCM_CLOCK_SOURCE 3072000 + +//#define BTPCM_CLOCK_SOURCE 76800000 +//#define BTPCM_CLOCK_SOURCE 84672000 + +//#define HAL_BTPCM_TX_FIFO_TRIGGER_LEVEL (BTPCMIP_FIFO_DEPTH/2) +//#define HAL_BTPCM_RX_FIFO_TRIGGER_LEVEL (BTPCMIP_FIFO_DEPTH/2) + +#define HAL_BTPCM_TX_FIFO_TRIGGER_LEVEL (1) +#define HAL_BTPCM_RX_FIFO_TRIGGER_LEVEL (0) + +#define HAL_BTPCM_YES 1 +#define HAL_BTPCM_NO 0 + +static const char * const invalid_id = "Invalid BTPCM ID: %d\n"; +//static const char * const invalid_ch = "Invalid BTPCM CH: %d\n"; + +static bool btpcm_opened[HAL_BTPCM_ID_NUM][AUD_STREAM_NUM]; + +static inline POSSIBLY_UNUSED unsigned char reverse(unsigned char in) +{ + uint8_t out = 0; + uint32_t i = 0; + for (i = 0; i < 8; ++i) { + if((1<= 2)) || (defined(CHIP_HAS_PSRAMUHS) && defined(PSRAMUHS_ENABLE)) + uint32_t val; + + val = cacheip_read32(reg_base, WRITEBUFFER_ENABLE_REG_OFFSET); + if (v) { + val |= WRITE_BACK_EN; + } else { + val &= ~WRITE_BACK_EN; + } + cacheip_write32(val, reg_base, WRITEBUFFER_ENABLE_REG_OFFSET); +#endif +#endif +} +__STATIC_FORCEINLINE void cacheip_flush_writebuffer(uint32_t reg_base) +{ + cacheip_write32(1, reg_base, WRITEBUFFER_FLUSH_REG_OFFSET); +} +__STATIC_FORCEINLINE void cacheip_set_invalidate_address(uint32_t reg_base, uint32_t v) +{ + cacheip_write32(v, reg_base, INVALIDATE_ADDRESS_REG_OFFSET); +} +__STATIC_FORCEINLINE void cacheip_trigger_invalidate(uint32_t reg_base) +{ + cacheip_write32(1, reg_base, INVALIDATE_SET_CMD_REG_OFFSET); +} +__STATIC_FORCEINLINE void cacheip_trigger_sync(uint32_t reg_base) +{ + cacheip_write32(1, reg_base, SYNC_CMD_REG_OFFSET); +} +/* cache controller end */ + +/* hal api */ +__STATIC_FORCEINLINE uint32_t _cache_get_reg_base(enum HAL_CACHE_ID_T id) +{ + uint32_t base; + + if (id == HAL_CACHE_ID_I_CACHE) { + base = ICACHE_CTRL_BASE; + } else if (id == HAL_CACHE_ID_D_CACHE) { +#ifdef DCACHE_CTRL_BASE + base = DCACHE_CTRL_BASE; +#else + base = 0; +#endif + } else { + base = 0; + } + + return base; +} +uint8_t BOOT_TEXT_FLASH_LOC hal_cache_enable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_init_cache(reg_base); + cacheip_enable_cache(reg_base, HAL_CACHE_YES); + + return 0; +} +uint8_t SRAM_TEXT_LOC hal_cache_disable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + +#if !(defined(ROM_BUILD) || defined(PROGRAMMER)) +#if (CHIP_CACHE_VER >= 2) + uint32_t val; + + do { + val = cacheip_read32(reg_base, STATUS_REG_OFFSET); + } while (val & STATUS_FETCHING); +#else + uint32_t time; + + time = hal_sys_timer_get(); + while (hal_norflash_busy() && (hal_sys_timer_get() - time) < MS_TO_TICKS(2)); + // Delay for at least 8 cycles till the cache becomes idle + for (int delay = 0; delay < 8; delay++) { + asm volatile("nop"); + } +#endif +#endif + + cacheip_enable_cache(reg_base, HAL_CACHE_NO); + + return 0; +} +uint8_t BOOT_TEXT_FLASH_LOC hal_cache_writebuffer_enable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_enable_writebuffer(reg_base, HAL_CACHE_YES); + + return 0; +} +uint8_t hal_cache_writebuffer_disable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_enable_writebuffer(reg_base, HAL_CACHE_NO); + + return 0; +} +uint8_t hal_cache_writebuffer_flush(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_flush_writebuffer(reg_base); + + return 0; +} +uint8_t BOOT_TEXT_FLASH_LOC hal_cache_writeback_enable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_enable_writeback(reg_base, HAL_CACHE_YES); + + return 0; +} +uint8_t hal_cache_writeback_disable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_enable_writeback(reg_base, HAL_CACHE_NO); + + return 0; +} +// Wrap is enabled during flash init +uint8_t BOOT_TEXT_SRAM_LOC hal_cache_wrap_enable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_enable_wrap(reg_base, HAL_CACHE_YES); + + return 0; +} +uint8_t hal_cache_wrap_disable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_enable_wrap(reg_base, HAL_CACHE_NO); + + return 0; +} +// Flash timing calibration might need to invalidate cache +uint8_t BOOT_TEXT_SRAM_LOC hal_cache_invalidate(enum HAL_CACHE_ID_T id, uint32_t start_address, uint32_t len) +{ + uint32_t reg_base; + uint32_t end_address; + uint32_t lock; + +#ifndef DCACHE_CTRL_BASE + if (id == HAL_CACHE_ID_D_CACHE) { + id = HAL_CACHE_ID_I_CACHE; + } +#endif + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + lock = int_lock_global(); + +#if defined(CHIP_BEST2300) || defined(CHIP_BEST1400) + uint32_t time; + + time = hal_sys_timer_get(); + while (hal_norflash_busy() && (hal_sys_timer_get() - time) < MS_TO_TICKS(2)); + // Delay for at least 8 cycles till the cache becomes idle + for (int delay = 0; delay < 8; delay++) { + asm volatile("nop"); + } +#endif + + if (len >= CACHE_SIZE / 2) { + cacheip_init_cache(reg_base); + cacheip_init_cache(reg_base); + } else { + end_address = start_address + len; + start_address &= (~(CACHE_LINE_SIZE-1)); + while (start_address < end_address) { + cacheip_set_invalidate_address(reg_base, start_address); + cacheip_trigger_invalidate(reg_base); + cacheip_trigger_invalidate(reg_base); + start_address += CACHE_LINE_SIZE; + } + } + + int_unlock_global(lock); + + return 0; +} +uint8_t hal_cache_invalidate_all(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + //warning BEST1501 may change this reg offset to 0x38 + cacheip_write32(1, reg_base, CACHE_INI_CMD_REG_OFFSET); + cacheip_write32(1, reg_base, CACHE_INI_CMD_REG_OFFSET); + return 0; +} +uint8_t hal_cache_sync(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cache_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_trigger_sync(reg_base); + + return 0; +} + +#ifdef CHIP_HAS_CP +__STATIC_FORCEINLINE uint32_t _cachecp_get_reg_base(enum HAL_CACHE_ID_T id) +{ + uint32_t base; + + if (id == HAL_CACHE_ID_I_CACHE) { + base = ICACHECP_CTRL_BASE; + } else if (id == HAL_CACHE_ID_D_CACHE) { +#ifdef DCACHECP_CTRL_BASE + base = DCACHECP_CTRL_BASE; +#else + base = 0; +#endif + } else { + base = 0; + } + + return base; +} +uint8_t hal_cachecp_enable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + uint32_t main_cache_reg_base; + enum HAL_CMU_MOD_ID_T mod; + + reg_base = _cachecp_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + if (id == HAL_CACHE_ID_D_CACHE) { + mod = HAL_CMU_H_DCACHECP; + } else { + mod = HAL_CMU_H_ICACHECP; + } + hal_cmu_clock_enable(mod); + hal_cmu_reset_clear(mod); + + cacheip_init_cache(reg_base); + cacheip_enable_cache(reg_base, HAL_CACHE_YES); + // Init wrap option + main_cache_reg_base = _cache_get_reg_base(id); + if (main_cache_reg_base == 0) { + return 0; + } + cacheip_enable_wrap(reg_base, cacheip_wrap_enabled(main_cache_reg_base)); + + return 0; +} +uint8_t CP_TEXT_SRAM_LOC hal_cachecp_disable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + enum HAL_CMU_MOD_ID_T mod; + + reg_base = _cachecp_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + +#if !(defined(ROM_BUILD) || defined(PROGRAMMER)) + uint32_t val; + + do { + val = cacheip_read32(reg_base, STATUS_REG_OFFSET); + } while (val & STATUS_FETCHING); +#endif + + cacheip_enable_cache(reg_base, HAL_CACHE_NO); + + if (id == HAL_CACHE_ID_D_CACHE) { + mod = HAL_CMU_H_DCACHECP; + } else { + mod = HAL_CMU_H_ICACHECP; + } + hal_cmu_reset_set(mod); + hal_cmu_clock_disable(mod); + + return 0; +} +uint8_t hal_cachecp_writebuffer_enable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cachecp_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_enable_writebuffer(reg_base, HAL_CACHE_YES); + + return 0; +} +uint8_t hal_cachecp_writebuffer_disable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cachecp_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_enable_writebuffer(reg_base, HAL_CACHE_NO); + + return 0; +} +uint8_t hal_cachecp_writebuffer_flush(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cachecp_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_flush_writebuffer(reg_base); + + return 0; +} +uint8_t hal_cachecp_writeback_enable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cachecp_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_enable_writeback(reg_base, HAL_CACHE_YES); + + return 0; +} +uint8_t hal_cachecp_writeback_disable(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cachecp_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_enable_writeback(reg_base, HAL_CACHE_NO); + + return 0; +} +uint8_t CP_TEXT_SRAM_LOC hal_cachecp_invalidate(enum HAL_CACHE_ID_T id, uint32_t start_address, uint32_t len) +{ + uint32_t reg_base; + uint32_t end_address; + +#ifndef DCACHECP_CTRL_BASE + if (id == HAL_CACHE_ID_D_CACHE) { + id = HAL_CACHE_ID_I_CACHE; + } +#endif + + reg_base = _cachecp_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + if (len >= CACHE_SIZE / 2) { + cacheip_init_cache(reg_base); + cacheip_init_cache(reg_base); + } else { + end_address = start_address + len; + start_address &= (~(CACHE_LINE_SIZE-1)); + while (start_address < end_address) { + cacheip_set_invalidate_address(reg_base, start_address); + cacheip_trigger_invalidate(reg_base); + cacheip_trigger_invalidate(reg_base); + start_address += CACHE_LINE_SIZE; + } + } + + return 0; +} +uint8_t hal_cachecp_sync(enum HAL_CACHE_ID_T id) +{ + uint32_t reg_base = 0; + + reg_base = _cachecp_get_reg_base(id); + if (reg_base == 0) { + return 0; + } + + cacheip_trigger_sync(reg_base); + + return 0; +} +#endif + diff --git a/platform/hal/hal_cache.h b/platform/hal/hal_cache.h new file mode 100644 index 0000000..0a3f4cb --- /dev/null +++ b/platform/hal/hal_cache.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef CACHE_HAL_H +#define CACHE_HAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +enum HAL_CACHE_ID_T { + HAL_CACHE_ID_I_CACHE = 0, + HAL_CACHE_ID_D_CACHE, + HAL_CACHE_ID_NUM, +}; + +uint8_t hal_cache_enable(enum HAL_CACHE_ID_T id); +uint8_t hal_cache_disable(enum HAL_CACHE_ID_T id); +uint8_t hal_cache_writebuffer_enable(enum HAL_CACHE_ID_T id); +uint8_t hal_cache_writebuffer_disable(enum HAL_CACHE_ID_T id); +uint8_t hal_cache_writebuffer_flush(enum HAL_CACHE_ID_T id); +uint8_t hal_cache_writeback_enable(enum HAL_CACHE_ID_T id); +uint8_t hal_cache_writeback_disable(enum HAL_CACHE_ID_T id); +uint8_t hal_cache_wrap_enable(enum HAL_CACHE_ID_T id); +uint8_t hal_cache_wrap_disable(enum HAL_CACHE_ID_T id); +uint8_t hal_cache_invalidate(enum HAL_CACHE_ID_T id, uint32_t start_address, uint32_t len); +uint8_t hal_cache_sync(enum HAL_CACHE_ID_T id); + +uint8_t hal_cachecp_enable(enum HAL_CACHE_ID_T id); +uint8_t hal_cachecp_disable(enum HAL_CACHE_ID_T id); +uint8_t hal_cachecp_writebuffer_enable(enum HAL_CACHE_ID_T id); +uint8_t hal_cachecp_writebuffer_disable(enum HAL_CACHE_ID_T id); +uint8_t hal_cachecp_writebuffer_flush(enum HAL_CACHE_ID_T id); +uint8_t hal_cachecp_writeback_enable(enum HAL_CACHE_ID_T id); +uint8_t hal_cachecp_writeback_disable(enum HAL_CACHE_ID_T id); +uint8_t hal_cachecp_invalidate(enum HAL_CACHE_ID_T id, uint32_t start_address, uint32_t len); +uint8_t hal_cachecp_sync(enum HAL_CACHE_ID_T id); + +#ifdef __cplusplus +} +#endif + +#endif /* CACHE_HAL_H */ diff --git a/platform/hal/hal_chipid.c b/platform/hal/hal_chipid.c new file mode 100644 index 0000000..b0bc820 --- /dev/null +++ b/platform/hal/hal_chipid.c @@ -0,0 +1,50 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_chipid.h" +#include "hal_location.h" + +enum HAL_CHIP_METAL_ID_T BOOT_BSS_LOC metal_id; + +uint32_t WEAK BOOT_TEXT_FLASH_LOC read_hw_metal_id(void) +{ + return HAL_CHIP_METAL_ID_0; +} + +void BOOT_TEXT_FLASH_LOC hal_chipid_init(void) +{ + metal_id = read_hw_metal_id(); +} + +enum HAL_CHIP_METAL_ID_T BOOT_TEXT_SRAM_LOC hal_get_chip_metal_id(void) +{ +#ifdef FPGA + return HAL_CHIP_METAL_ID_15; +#else + return metal_id; +#endif +} + +enum HAL_BT_CHIP_SERIES_T hal_get_bt_chip_series(void) +{ +#if (defined(CHIP_BEST1000)) || defined(CHIP_BEST2000) + return HAL_BT_CHIP_SERIES_2000; +#elif defined(CHIP_BEST2500) + return HAL_BT_CHIP_SERIES_2500; +#else// (defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST1400) || defined(CHIP_BEST1402)) + return HAL_BT_CHIP_SERIES_2300; +#endif +} + diff --git a/platform/hal/hal_chipid.h b/platform/hal/hal_chipid.h new file mode 100644 index 0000000..ef9e632 --- /dev/null +++ b/platform/hal/hal_chipid.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_CHIPID_H__ +#define __HAL_CHIPID_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +// BEST1000: A=0 C=1 D=2 F=3 G=4 I=5 +// BEST1400: A=0 B=1 C=2(cmuRev=2&diffRom) D=3 E=4(cmuRev=3&diffRom) F=5(cmuRev=4) +// BEST1402: A=0 B=1 +// BEST2000: A=0 C=1 D=2 E=3(rev=2&aonRev=4) F=4 G=5 +// BEST2300: A=0 B=1(rfRev=15) C=3 D=4 E=5(rfRev=4&diffRom) + +enum HAL_CHIP_METAL_ID_T { + HAL_CHIP_METAL_ID_0, + HAL_CHIP_METAL_ID_1, + HAL_CHIP_METAL_ID_2, + HAL_CHIP_METAL_ID_3, + HAL_CHIP_METAL_ID_4, + HAL_CHIP_METAL_ID_5, + HAL_CHIP_METAL_ID_6, + HAL_CHIP_METAL_ID_7, + HAL_CHIP_METAL_ID_8, + HAL_CHIP_METAL_ID_9, + HAL_CHIP_METAL_ID_10, + HAL_CHIP_METAL_ID_11, + HAL_CHIP_METAL_ID_12, + HAL_CHIP_METAL_ID_13, + HAL_CHIP_METAL_ID_14, + HAL_CHIP_METAL_ID_15, +}; + +enum HAL_BT_CHIP_SERIES_T { + HAL_BT_CHIP_SERIES_2000, + HAL_BT_CHIP_SERIES_2300, + HAL_BT_CHIP_SERIES_2500, +}; + +// Invoked by hal_chipid_init() only +uint32_t read_hw_metal_id(void); + +void hal_chipid_init(void); + +enum HAL_CHIP_METAL_ID_T hal_get_chip_metal_id(void); +enum HAL_BT_CHIP_SERIES_T hal_get_bt_chip_series(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_cmd.c b/platform/hal/hal_cmd.c new file mode 100644 index 0000000..95c543e --- /dev/null +++ b/platform/hal/hal_cmd.c @@ -0,0 +1,545 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_iomux.h" +#include "hal_cmd.h" +#include "hal_uart.h" +#include "hal_trace.h" +#include "string.h" +#include "hal_timer.h" + +/* +|-----|-------|----------------------------------| +| | crc | Discription | +| | ----- | -------------------------------- | +| | -3 | Can not find head name | +| | ----- | -------------------------------- | +| | -2 | Can not find callback function | +| | ----- | -------------------------------- | +| res | -1 | Unknown issue | +| | ----- | -------------------------------- | +| | 0 | OK | +| | ----- | -------------------------------- | +| | 1 | Data length is mismatching | +| | ----- | -------------------------------- | +| | >1 | Issue from application | +|-----|-------|----------------------------------| + */ + +#define HAL_CMD_PREFIX_SIZE 4 +#define HAL_CMD_CRC_SIZE 4 +#define HAL_CMD_NAME_SIZE 12 +#define HAL_CMD_LEN_SIZE 4 +#define HAL_CMD_DATA_MAX_SIZE 1024 * 3 + +// #define HAL_CMD_PREFIX_OFFSET 0 +// #define HAL_CMD_TYPE_OFFSET 1 +// #define HAL_CMD_SEQ_OFFSET 2 +// #define HAL_CMD_LEN_OFFSET 3 +// #define HAL_CMD_CMD_OFFSET 4 +// #define HAL_CMD_DATA_OFFSET 5 + +// #define HAL_CMD_PREFIX 0xFE +// #define HAL_CMD_TYPE 0xA0 + +#define HAL_CMD_RX_BUF_SIZE (HAL_CMD_PREFIX_SIZE + HAL_CMD_NAME_SIZE + HAL_CMD_CRC_SIZE + HAL_CMD_LEN_SIZE + HAL_CMD_DATA_MAX_SIZE) +#define HAL_CMD_TX_BUF_SIZE (100) + +#define HAL_CMD_LIST_NUM 10 + +#ifdef USB_EQ_TUNING +#define STATIC +#else +#define STATIC static +#endif + +#ifdef USB_EQ_TUNING +#ifdef __PC_CMD_UART__ +#error "USB_EQ_TUNING can not be defined together with PC_CMD_UART" +#endif +#endif + +typedef struct { + uint32_t len; + uint8_t data[HAL_CMD_TX_BUF_SIZE - 13]; +}hal_cmd_res_payload_t; + +typedef struct{ + int prefix; + int crc; + char name[HAL_CMD_NAME_SIZE]; +}hal_cmd_res_t; + +typedef struct{ + int prefix; + int crc; + char *name; + uint32_t len; + uint8_t *data; +}hal_cmd_cfg_t; + +typedef struct{ + char name[HAL_CMD_NAME_SIZE]; + hal_cmd_callback_t callback; +}hal_cmd_list_t; + +typedef struct { + uint8_t uart_work; + hal_cmd_rx_status_t rx_status; + uint8_t cur_seq; + +#ifdef __PC_CMD_UART__ + uint8_t rx_len; +#endif + uint8_t tx_len; +#ifdef __PC_CMD_UART__ + uint8_t rx_buf[HAL_CMD_RX_BUF_SIZE]; +#endif + uint8_t tx_buf[HAL_CMD_TX_BUF_SIZE]; + + hal_cmd_res_t res; + hal_cmd_res_payload_t res_payload; + + uint32_t list_num; + hal_cmd_list_t list[HAL_CMD_LIST_NUM]; +} hal_cmd_t; + +hal_cmd_t hal_cmd; +CMD_CALLBACK_HANDLER_T hal_cmd_callback = NULL; + +#ifdef __PC_CMD_UART__ + +#define HAL_CMD_ID HAL_UART_ID_0 + +static const struct HAL_UART_CFG_T hal_cmd_cfg = { + .parity = HAL_UART_PARITY_NONE, + .stop = HAL_UART_STOP_BITS_1, + .data = HAL_UART_DATA_BITS_8, + .flow = HAL_UART_FLOW_CONTROL_NONE,//HAL_UART_FLOW_CONTROL_RTSCTS, + .tx_level = HAL_UART_FIFO_LEVEL_1_2, + .rx_level = HAL_UART_FIFO_LEVEL_1_2, + .baud = 115200, + .dma_rx = true, + .dma_tx = true, + .dma_rx_stop_on_err = false, +}; +#endif + +#define HAL_CMD_TRACE TRACE + +#ifdef __PC_CMD_UART__ +STATIC int hal_cmd_list_process(uint8_t *buf); +#endif +static int hal_cmd_list_register(char *name, hal_cmd_callback_t callback); + +#ifdef __PC_CMD_UART__ +void hal_cmd_break_irq_handler (void) +{ + HAL_CMD_TRACE(1,"%s", __func__); + + // gElCtx.sync_step = EL_SYNC_ERROR; + +} + +void hal_cmd_dma_rx_irq_handler (uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status) +{ + // uint8_t prefix = gpElUartCtx->rx_buf[EL_PREFIX_OFFSET]; + // uint8_t type = gpElUartCtx->rx_buf[EL_TYPE_OFFSET]; + // uint8_t len = gpElUartCtx->rx_buf[EL_LEN_OFFSET]; + // uint8_t cmd = gpElUartCtx->rx_buf[EL_CMD_OFFSET]; + HAL_CMD_TRACE(5,"%s: xfer_size[%d], dma_error[%x], status[%x], rx_status[%d]", + __func__, xfer_size, dma_error, status.reg, hal_cmd.rx_status); + + if (status.BE) { + hal_cmd_break_irq_handler(); + return; + } + + if (hal_cmd.rx_status != HAL_CMD_RX_START) + { + return; + } + + if (dma_error || status.FE || status.OE || status.PE || status.BE) + { + // TODO: + ; + } + else + { + // mask.RT = 1 + hal_cmd.rx_len = xfer_size; + hal_cmd.rx_status = HAL_CMD_RX_DONE; + hal_cmd_callback(hal_cmd.rx_status); + } +} +#endif + +int hal_cmd_init (void) +{ +#ifdef __PC_CMD_UART__ + HAL_CMD_TRACE(1,"[%s]", __func__); + if(HAL_CMD_ID == HAL_UART_ID_0) + { + hal_iomux_set_uart0(); + } + else if(HAL_CMD_ID == HAL_UART_ID_1) + { + hal_iomux_set_uart1(); + } + +#endif + +#ifdef USB_AUDIO_APP + hal_cmd_set_callback(hal_cmd_run); +#endif + + return 0; +} + +void hal_cmd_set_callback(CMD_CALLBACK_HANDLER_T handler) +{ + hal_cmd_callback = handler; +} + +#ifdef __PC_CMD_UART__ +static union HAL_UART_IRQ_T mask; +#endif + +int hal_cmd_open (void) +{ +#ifdef __PC_CMD_UART__ + int ret = -1; + + ret = hal_uart_open(HAL_CMD_ID, &hal_cmd_cfg); + ASSERT(!ret, "!!%s: UART open failed (%d)!!", __func__, ret); + + hal_uart_irq_set_dma_handler(HAL_CMD_ID, hal_cmd_dma_rx_irq_handler, NULL); + + // Do not enable tx and rx interrupt, use dma + mask.reg = 0; + mask.BE = 1; + mask.FE = 1; + mask.OE = 1; + mask.PE = 1; + mask.RT = 1; + hal_uart_irq_set_mask(HAL_CMD_ID, mask); + + hal_cmd.uart_work = 1; + hal_cmd.rx_status = HAL_CMD_RX_STOP; + hal_cmd_callback(hal_cmd.rx_status); +#endif + + return 0; +} + +int hal_cmd_close (void) +{ +#ifdef __PC_CMD_UART__ + mask.reg = 0; + hal_uart_irq_set_mask(HAL_CMD_ID, mask); + hal_uart_irq_set_dma_handler(HAL_CMD_ID, NULL, NULL); + hal_uart_close(HAL_CMD_ID); + + hal_cmd.uart_work = 0; +#endif + + return 0; +} + +int hal_cmd_register(char *name, hal_cmd_callback_t callback) +{ + int ret = -1; + + ASSERT(strlen(name) < HAL_CMD_NAME_SIZE, "[%s] strlen(%s) = %d >= HAL_CMD_NAME_SIZE", __func__, + name, + strlen(name)); + + ret = hal_cmd_list_register(name, callback); + + return ret; +} + +#ifdef __PC_CMD_UART__ +static int hal_cmd_send (void) +{ + int ret = -1; + + if (!hal_cmd.uart_work) + { + hal_cmd_open(); + } + + ret = hal_uart_dma_send(HAL_CMD_ID, hal_cmd.tx_buf, hal_cmd.tx_len, NULL, NULL); + + HAL_CMD_TRACE(4,"%s: %d - %d - %d", __func__, hal_cmd.tx_len, hal_cmd.uart_work, ret); + + return ret; +} + +static int hal_cmd_rx_start (void) +{ + int ret = -1; + + if (!hal_cmd.uart_work) + { + hal_cmd_open(); + } + + ret = hal_uart_dma_recv_mask(HAL_CMD_ID, hal_cmd.rx_buf, HAL_CMD_RX_BUF_SIZE, NULL, NULL, &mask); //HAL_CMD_RX_BUF_SIZE + + ASSERT(!ret, "!!%s: UART recv failed (%d)!!", __func__, ret); + + hal_cmd.rx_status = HAL_CMD_RX_START; + hal_cmd_callback(hal_cmd.rx_status); + return ret; +} + +static int hal_cmd_rx_process (void) +{ + int ret = -1; + + HAL_CMD_TRACE(1,"[%s] start...", __func__); + + ret = hal_cmd_list_process(hal_cmd.rx_buf); + + hal_cmd.rx_status = HAL_CMD_RX_STOP; + hal_cmd_callback(hal_cmd.rx_status); + return ret; +} +#endif + +void hal_cmd_set_res_playload(uint8_t* data, int len) +{ + hal_cmd.res_payload.len = len; + memcpy(hal_cmd.res_payload.data, data, len); +} + +#ifdef __PC_CMD_UART__ +static int hal_cmd_tx_process (void) +{ + int ret = -1; + + HAL_CMD_TRACE(1,"[%s] start...", __func__); + +#if 0 + // Test loop + hal_cmd.tx_len = hal_cmd.rx_len; + memcpy(hal_cmd.tx_buf, hal_cmd.rx_buf, hal_cmd.rx_len); +#endif + +#if 1 + hal_cmd.tx_len = sizeof(hal_cmd.res); + TRACE(5,"[%s] len : %d, %c, %d, %s", __func__, hal_cmd.tx_len, hal_cmd.res.prefix, hal_cmd.res.crc, hal_cmd.res.name); + memcpy(hal_cmd.tx_buf, &hal_cmd.res, hal_cmd.tx_len); + + if (hal_cmd.res_payload.len) { + memcpy(hal_cmd.tx_buf + hal_cmd.tx_len, &hal_cmd.res_payload.len, sizeof(hal_cmd.res_payload.len)); + hal_cmd.tx_len += sizeof(hal_cmd.res_payload.len); + + memcpy(hal_cmd.tx_buf + hal_cmd.tx_len, hal_cmd.res_payload.data, hal_cmd.res_payload.len); + hal_cmd.tx_len += hal_cmd.res_payload.len; + + memset(&hal_cmd.res_payload, 0, sizeof(hal_cmd.res_payload)); + } +#else + char send_string[] = "791,"; + hal_cmd.tx_len = sizeof(send_string); + memcpy(hal_cmd.tx_buf, send_string, hal_cmd.tx_len); +#endif + + hal_cmd_send(); + + return ret; +} +#endif + +#ifdef USB_EQ_TUNING + +void hal_cmd_tx_process (uint8_t** ppbuf, uint16_t* plen) +{ + hal_cmd.tx_len = sizeof(hal_cmd.res); + + memcpy(hal_cmd.tx_buf, &hal_cmd.res, hal_cmd.tx_len); + + if (hal_cmd.res_payload.len) { + memcpy(hal_cmd.tx_buf + hal_cmd.tx_len, &hal_cmd.res_payload.len, sizeof(hal_cmd.res_payload.len)); + hal_cmd.tx_len += sizeof(hal_cmd.res_payload.len); + + memcpy(hal_cmd.tx_buf + hal_cmd.tx_len, hal_cmd.res_payload.data, hal_cmd.res_payload.len); + hal_cmd.tx_len += hal_cmd.res_payload.len; + + memset(&hal_cmd.res_payload, 0, sizeof(hal_cmd.res_payload)); + } + + *ppbuf = hal_cmd.tx_buf; + *plen = hal_cmd.tx_len; +} + +#endif + +#ifdef __PC_CMD_UART__ + +#ifdef USB_AUDIO_APP +void hal_cmd_run (hal_cmd_rx_status_t status) +#else +int hal_cmd_run (hal_cmd_rx_status_t status) +#endif +{ + int ret = -1; + + // static uint32_t pre_time_ms = 0, curr_ticks = 0, curr_time_ms = 0; + + // curr_ticks = hal_sys_timer_get(); + // curr_time_ms = TICKS_TO_MS(curr_ticks); + + + // if(curr_time_ms - pre_time_ms > 1000) + // { + // HAL_CMD_TRACE(1,"[%s] start...", __func__); + // pre_time_ms = curr_time_ms; + // } + + if(status == HAL_CMD_RX_DONE) + { + ret = hal_cmd_rx_process(); + + if (ret) + { + hal_cmd.res.crc = ret; + } + + ret = hal_cmd_tx_process(); + } + + if(status == HAL_CMD_RX_STOP) + { + ret = hal_cmd_rx_start(); + } + +#ifndef USB_AUDIO_APP + return ret; +#endif +} +#endif + +// List process +static int hal_cmd_list_get_id(char *name) +{ + for(int i=0;iprefix = *((uint32_t *)buf); + HAL_CMD_TRACE(2,"[%s] PREFIX = %c", __func__, cfg->prefix); + buf += HAL_CMD_PREFIX_SIZE; + hal_cmd.res.prefix = cfg->prefix; + + cfg->crc = *((uint32_t *)buf); + HAL_CMD_TRACE(2,"[%s] crc = %d", __func__, cfg->crc); + buf += HAL_CMD_CRC_SIZE; + hal_cmd.res.crc = cfg->crc; + + cfg->name = (char *)buf; + HAL_CMD_TRACE(2,"[%s] NAME = %s", __func__, cfg->name); + buf += HAL_CMD_NAME_SIZE; + memcpy(hal_cmd.res.name, cfg->name, HAL_CMD_NAME_SIZE); + + cfg->len = *((uint32_t *)buf); + HAL_CMD_TRACE(2,"[%s] LEN = %d", __func__, cfg->len); + buf += HAL_CMD_LEN_SIZE; + + cfg->data = buf; + + return 0; +} + +STATIC int hal_cmd_list_process(uint8_t *buf) +{ + int ret = -1; + int id = 0; + hal_cmd_cfg_t cfg; + + hal_cmd_list_parse(buf, &cfg); + + id = hal_cmd_list_get_id(cfg.name); + + if(id == -1) + { + TRACE(2,"[%s] %s is invalid", __func__, cfg.name); + return -2; + } + + if(hal_cmd.list[id].callback) + { + ret = hal_cmd.list[id].callback(cfg.data, cfg.len); + } + else + { + TRACE(2,"[%s] %s has not callback", __func__, hal_cmd.list[id].name); + ret = -3; + } + + return ret; +} +#endif diff --git a/platform/hal/hal_cmd.h b/platform/hal/hal_cmd.h new file mode 100644 index 0000000..3c79c0a --- /dev/null +++ b/platform/hal/hal_cmd.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_CMD_H__ +#define __HAL_CMD_H__ + +#include "stdint.h" + +// typedef enum { +// HAL_CMD_ERR_NONE = 0x00, +// HAL_CMD_ERR_LEN = 0x01, +// HAL_CMD_ERR_CHECKSUM = 0x02, +// HAL_CMD_ERR_NOT_SYNC = 0x03, + +// HAL_CMD_ERR_CMD = 0x06, + +// HAL_CMD_ERR_BURN_OK = 0x60, +// HAL_CMD_ERR_SECTOR_SIZE = 0x61, + +// HAL_CMD_ERR_BURN_INFO_MISSING = 0x63, +// HAL_CMD_ERR_SECTOR_DATA_LEN = 0x64, +// HAL_CMD_ERR_SECTOR_DATA_CRC = 0x65, +// HAL_CMD_ERR_SECTOR_SEQ = 0x66, +// HAL_CMD_ERR_ERASE_FLSH = 0x67, +// HAL_CMD_ERR_BURN_FLSH = 0x68, +// } HAL_CMD_ERR_T; + +// typedef enum { +// HAL_CMD_GET_PARA = 0x00, +// HAL_CMD_SET_PARA, +// HAL_CMD_SAVE_PARA, +// HAL_CMD_PUSH_PARA, + +// HAL_CMD_PLAYBACK_SWITCH = 0x08, +// HAL_CMD_CAPTURE_SWITCH, + +// HAL_CMD_BURN_HANDSHAKE = 0x10, +// HAL_CMD_BURN_START, +// HAL_CMD_BURN_DATA, + +// HAL_CMD_HANDSHAKE = 0x18, +// HAL_CMD_SHUTDOWN, +// HAL_CMD_REBOOT, +// HAL_CMD_NOTIFICATION, + +// HAL_CMD_INVALID = 0xff +// } EL_CMD_E; + +// typedef enum { +// HAL_CMD_PARA_SOUND_VOLUME, +// HAL_CMD_PARA_LC_SWITCH, +// HAL_CMD_PARA_EQ_GAIN, +// HAL_CMD_PARA_ANC_SWITCH, +// HAL_CMD_PARA_ANC_GAIN, + +// HAL_CMD_PARA_INVALID +// } EL_PARA_E; + +typedef enum { + HAL_CMD_RX_START, + HAL_CMD_RX_STOP, + HAL_CMD_RX_DONE +} hal_cmd_rx_status_t; + +typedef int (*hal_cmd_callback_t)(uint8_t *buf, uint32_t len); +typedef void (*CMD_CALLBACK_HANDLER_T)(hal_cmd_rx_status_t status); + +#ifdef __cplusplus +extern "C" { +#endif +int hal_cmd_init (void); +int hal_cmd_open (void); +int hal_cmd_close (void); + +#ifdef USB_AUDIO_APP +void hal_cmd_run (hal_cmd_rx_status_t status); +#else +int hal_cmd_run (hal_cmd_rx_status_t status); +#endif +void hal_cmd_set_callback(CMD_CALLBACK_HANDLER_T handler); +int hal_cmd_register(char *name, hal_cmd_callback_t callback); + +#ifdef USB_EQ_TUNING +int hal_cmd_list_process(uint8_t *buf); +void hal_cmd_tx_process (uint8_t** ppbuf, uint16_t* plen); +#endif + +#ifdef __cplusplus +} +#endif +// hal_cmd_t *hal_cmd_get_ptr(void); + +#endif \ No newline at end of file diff --git a/platform/hal/hal_cmu.h b/platform/hal/hal_cmu.h new file mode 100644 index 0000000..3b033f3 --- /dev/null +++ b/platform/hal/hal_cmu.h @@ -0,0 +1,462 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_CMU_H__ +#define __HAL_CMU_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "plat_addr_map.h" +#include CHIP_SPECIFIC_HDR(hal_cmu) + +#ifndef HAL_CMU_DEFAULT_CRYSTAL_FREQ +#define HAL_CMU_DEFAULT_CRYSTAL_FREQ 26000000 +#endif + +#define LPU_TIMER_US(us) (((us) * 32 + 1000 - 1) / 1000) + +enum HAL_CMU_CLK_STATUS_T { + HAL_CMU_CLK_DISABLED, + HAL_CMU_CLK_ENABLED, +}; + +enum HAL_CMU_CLK_MODE_T { + HAL_CMU_CLK_AUTO, + HAL_CMU_CLK_MANUAL, +}; + +enum HAL_CMU_RST_STATUS_T { + HAL_CMU_RST_SET, + HAL_CMU_RST_CLR, +}; + +enum HAL_CMU_TIMER_ID_T { + HAL_CMU_TIMER_ID_00, + HAL_CMU_TIMER_ID_01, + HAL_CMU_TIMER_ID_10, + HAL_CMU_TIMER_ID_11, + HAL_CMU_TIMER_ID_20, + HAL_CMU_TIMER_ID_21, +}; + +#ifndef HAL_CMU_FREQ_T +enum HAL_CMU_FREQ_T { + HAL_CMU_FREQ_32K, + HAL_CMU_FREQ_26M, + HAL_CMU_FREQ_52M, + HAL_CMU_FREQ_78M, + HAL_CMU_FREQ_104M, + HAL_CMU_FREQ_208M, + + HAL_CMU_FREQ_QTY +}; +#endif + +#ifndef HAL_CMU_PLL_T +enum HAL_CMU_PLL_T { + HAL_CMU_PLL_AUD, + HAL_CMU_PLL_USB, + + HAL_CMU_PLL_QTY +}; +#endif + +#ifndef HAL_CMU_PLL_USER_T +enum HAL_CMU_PLL_USER_T { + HAL_CMU_PLL_USER_SYS, + HAL_CMU_PLL_USER_AUD, + HAL_CMU_PLL_USER_USB, + + HAL_CMU_PLL_USER_QTY, + HAL_CMU_PLL_USER_ALL = HAL_CMU_PLL_USER_QTY, +}; +#endif + +enum HAL_CMU_PERIPH_FREQ_T { + HAL_CMU_PERIPH_FREQ_26M, + HAL_CMU_PERIPH_FREQ_52M, + + HAL_CMU_PERIPH_FREQ_QTY +}; + +enum HAL_CMU_LPU_CLK_CFG_T { + HAL_CMU_LPU_CLK_NONE, + HAL_CMU_LPU_CLK_26M, + HAL_CMU_LPU_CLK_PLL, + + HAL_CMU_LPU_CLK_QTY +}; + +enum HAL_CMU_LPU_SLEEP_MODE_T { + HAL_CMU_LPU_SLEEP_MODE_SYS, + HAL_CMU_LPU_SLEEP_MODE_CHIP, + + HAL_CMU_LPU_SLEEP_MODE_QTY +}; + +#ifndef HAL_PWM_ID_T +enum HAL_PWM_ID_T { + HAL_PWM_ID_0, + HAL_PWM_ID_1, + HAL_PWM_ID_2, + HAL_PWM_ID_3, + + HAL_PWM_ID_QTY +}; +#endif + +#ifndef HAL_I2S_ID_T +enum HAL_I2S_ID_T { + HAL_I2S_ID_0 = 0, + + HAL_I2S_ID_QTY, +}; +#endif + +#ifndef HAL_SPDIF_ID_T +enum HAL_SPDIF_ID_T { + HAL_SPDIF_ID_0 = 0, + + HAL_SPDIF_ID_QTY, +}; +#endif + +enum HAL_CMU_USB_CLOCK_SEL_T { + HAL_CMU_USB_CLOCK_SEL_PLL, + HAL_CMU_USB_CLOCK_SEL_24M_X2, + HAL_CMU_USB_CLOCK_SEL_48M, + HAL_CMU_USB_CLOCK_SEL_26M_X2, + HAL_CMU_USB_CLOCK_SEL_26M_X4, +}; + +void hal_cmu_set_crystal_freq_index(uint32_t index); + +uint32_t hal_cmu_get_crystal_freq(void); + +uint32_t hal_cmu_get_default_crystal_freq(void); + +int hal_cmu_clock_enable(enum HAL_CMU_MOD_ID_T id); + +int hal_cmu_clock_disable(enum HAL_CMU_MOD_ID_T id); + +enum HAL_CMU_CLK_STATUS_T hal_cmu_clock_get_status(enum HAL_CMU_MOD_ID_T id); + +int hal_cmu_clock_set_mode(enum HAL_CMU_MOD_ID_T id, enum HAL_CMU_CLK_MODE_T mode); + +enum HAL_CMU_CLK_MODE_T hal_cmu_clock_get_mode(enum HAL_CMU_MOD_ID_T id); + +int hal_cmu_reset_set(enum HAL_CMU_MOD_ID_T id); + +int hal_cmu_reset_clear(enum HAL_CMU_MOD_ID_T id); + +enum HAL_CMU_RST_STATUS_T hal_cmu_reset_get_status(enum HAL_CMU_MOD_ID_T id); + +int hal_cmu_reset_pulse(enum HAL_CMU_MOD_ID_T id); + +int hal_cmu_timer_set_div(enum HAL_CMU_TIMER_ID_T id, uint32_t div); + +void hal_cmu_timer0_select_fast(void); + +void hal_cmu_timer0_select_slow(void); + +void hal_cmu_timer1_select_fast(void); + +void hal_cmu_timer1_select_slow(void); + +void hal_cmu_timer2_select_fast(void); + +void hal_cmu_timer2_select_slow(void); + +void hal_cmu_dsp_timer0_select_fast(void); + +void hal_cmu_dsp_timer0_select_slow(void); + +void hal_cmu_dsp_timer1_select_fast(void); + +void hal_cmu_dsp_timer1_select_slow(void); + +int hal_cmu_periph_set_div(uint32_t div); + +int hal_cmu_uart0_set_div(uint32_t div); + +int hal_cmu_uart1_set_div(uint32_t div); + +int hal_cmu_uart2_set_div(uint32_t div); + +int hal_cmu_spi_set_div(uint32_t div); + +int hal_cmu_slcd_set_div(uint32_t div); + +int hal_cmu_sdio_set_div(uint32_t div); + +int hal_cmu_sdmmc_set_div(uint32_t div); + +int hal_cmu_i2c_set_div(uint32_t div); + +int hal_cmu_uart0_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq); + +int hal_cmu_uart1_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq); + +int hal_cmu_uart2_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq); + +int hal_cmu_spi_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq); + +int hal_cmu_slcd_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq); + +int hal_cmu_sdio_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq); + +int hal_cmu_sdmmc_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq); + +int hal_cmu_i2c_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq); + +int hal_cmu_ispi_set_freq(enum HAL_CMU_PERIPH_FREQ_T freq); + +int hal_cmu_pwm_set_freq(enum HAL_PWM_ID_T id, uint32_t freq); + +int hal_cmu_flash_set_freq(enum HAL_CMU_FREQ_T freq); + +int hal_cmu_mem_set_freq(enum HAL_CMU_FREQ_T freq); + +int hal_cmu_sys_set_freq(enum HAL_CMU_FREQ_T freq); + +enum HAL_CMU_FREQ_T hal_cmu_sys_get_freq(void); + +enum HAL_CMU_FREQ_T hal_cmu_flash_get_freq(void); + +int hal_cmu_flash_select_pll(enum HAL_CMU_PLL_T pll); + +int hal_cmu_mem_select_pll(enum HAL_CMU_PLL_T pll); + +int hal_cmu_sys_select_pll(enum HAL_CMU_PLL_T pll); + +int hal_cmu_get_pll_status(enum HAL_CMU_PLL_T pll); + +int hal_cmu_pll_enable(enum HAL_CMU_PLL_T pll, enum HAL_CMU_PLL_USER_T user); + +int hal_cmu_pll_disable(enum HAL_CMU_PLL_T pll, enum HAL_CMU_PLL_USER_T user); + +void hal_cmu_audio_resample_enable(void); + +void hal_cmu_audio_resample_disable(void); + +int hal_cmu_get_audio_resample_status(void); + +int hal_cmu_codec_adc_set_div(uint32_t div); + +uint32_t hal_cmu_codec_adc_get_div(void); + +int hal_cmu_codec_dac_set_div(uint32_t div); + +uint32_t hal_cmu_codec_dac_get_div(void); + +void hal_cmu_codec_clock_enable(void); + +void hal_cmu_codec_clock_disable(void); + +void hal_cmu_codec_reset_set(void); + +void hal_cmu_codec_reset_clear(void); + +void hal_cmu_codec_iir_enable(uint32_t speed); + +void hal_cmu_codec_iir_disable(void); + +int hal_cmu_codec_iir_set_div(uint32_t div); + +void hal_cmu_codec_iir_eq_enable(uint32_t speed); + +void hal_cmu_codec_iir_eq_disable(void); + +void hal_cmu_codec_psap_enable(uint32_t speed); + +void hal_cmu_codec_psap_disable(void); + +void hal_cmu_codec_fir_enable(uint32_t speed); + +void hal_cmu_codec_fir_disable(void); + +int hal_cmu_codec_fir_set_div(uint32_t div); + +void hal_cmu_codec_fir_select_sys_clock(void); + +void hal_cmu_codec_fir_select_own_clock(void); + +void hal_cmu_codec_rs_enable(uint32_t speed); + +void hal_cmu_codec_rs_disable(void); + +int hal_cmu_codec_rs_set_div(uint32_t div); + +void hal_cmu_codec_rs_adc_enable(uint32_t speed); + +void hal_cmu_codec_rs_adc_disable(void); + +int hal_cmu_codec_rs_adc_set_div(uint32_t div); + +void hal_cmu_codec_set_fault_mask(uint32_t msk); + +void hal_cmu_i2s_clock_out_enable(enum HAL_I2S_ID_T id); + +void hal_cmu_i2s_clock_out_disable(enum HAL_I2S_ID_T id); + +void hal_cmu_i2s_set_slave_mode(enum HAL_I2S_ID_T id); + +void hal_cmu_i2s_set_master_mode(enum HAL_I2S_ID_T id); + +void hal_cmu_i2s_clock_enable(enum HAL_I2S_ID_T id); + +void hal_cmu_i2s_clock_disable(enum HAL_I2S_ID_T id); + +int hal_cmu_i2s_set_div(enum HAL_I2S_ID_T id, uint32_t div); + +int hal_cmu_i2s_mclk_enable(enum HAL_CMU_I2S_MCLK_ID_T id); + +void hal_cmu_i2s_mclk_disable(void); + +void hal_cmu_pcm_clock_out_enable(void); + +void hal_cmu_pcm_clock_out_disable(void); + +void hal_cmu_pcm_set_slave_mode(int clk_pol); + +void hal_cmu_pcm_set_master_mode(void); + +void hal_cmu_pcm_clock_enable(void); + +void hal_cmu_pcm_clock_disable(void); + +int hal_cmu_pcm_set_div(uint32_t div); + +int hal_cmu_spdif_clock_enable(enum HAL_SPDIF_ID_T id); + +int hal_cmu_spdif_clock_disable(enum HAL_SPDIF_ID_T id); + +int hal_cmu_spdif_set_div(enum HAL_SPDIF_ID_T id, uint32_t div); + +void hal_cmu_usb_set_device_mode(void); + +void hal_cmu_usb_set_host_mode(void); + +void hal_cmu_rom_select_usb_clock(enum HAL_CMU_USB_CLOCK_SEL_T sel); + +void hal_cmu_usb_clock_enable(void); + +void hal_cmu_usb_clock_disable(void); + +void hal_cmu_bt_clock_enable(void); + +void hal_cmu_bt_clock_disable(void); + +void hal_cmu_bt_reset_set(void); + +void hal_cmu_bt_reset_clear(void); + +void hal_cmu_bt_module_init(void); + +void hal_cmu_bt_sys_clock_force_on(void); + +void hal_cmu_bt_sys_clock_auto(void); + +void hal_cmu_bt_sys_set_freq(enum HAL_CMU_FREQ_T freq); + +int hal_cmu_clock_out_enable(enum HAL_CMU_CLOCK_OUT_ID_T id); + +void hal_cmu_clock_out_disable(void); + +void hal_cmu_write_lock(void); + +void hal_cmu_write_unlock(void); + +void hal_cmu_sys_reboot(void); + +void hal_cmu_jtag_enable(void); + +void hal_cmu_jtag_disable(void); + +void hal_cmu_jtag_clock_enable(void); + +void hal_cmu_jtag_clock_disable(void); + +void hal_cmu_simu_init(void); + +void hal_cmu_simu_pass(void); + +void hal_cmu_simu_fail(void); + +void hal_cmu_simu_tag(uint8_t shift); + +void hal_cmu_simu_set_val(uint32_t val); + +uint32_t hal_cmu_simu_get_val(void); + +void hal_cmu_low_freq_mode_init(void); + +void hal_cmu_low_freq_mode_enable(enum HAL_CMU_FREQ_T old_freq, enum HAL_CMU_FREQ_T new_freq); + +void hal_cmu_low_freq_mode_disable(enum HAL_CMU_FREQ_T old_freq, enum HAL_CMU_FREQ_T new_freq); + +void hal_cmu_rom_enable_pll(void); + +void hal_cmu_programmer_enable_pll(void); + +void hal_cmu_init_pll_selection(void); + +void hal_cmu_rom_setup(void); + +void hal_cmu_programmer_setup(void); + +void hal_cmu_fpga_setup(void); + +void hal_cmu_setup(void); + +// Some internal functions + +void hal_cmu_apb_init_div(void); + +void hal_cmu_rom_clock_init(void); + +void hal_cmu_init_chip_feature(uint16_t feature); + +void hal_cmu_osc_x2_enable(void); + +void hal_cmu_osc_x4_enable(void); + +void hal_cmu_module_init_state(void); + +void hal_cmu_ema_init(void); + +void hal_cmu_lpu_wait_26m_ready(void); + +int hal_cmu_lpu_busy(void); + +int hal_cmu_lpu_init(enum HAL_CMU_LPU_CLK_CFG_T cfg); + +int hal_cmu_lpu_sleep(enum HAL_CMU_LPU_SLEEP_MODE_T mode); + +void hal_cmu_set_wakeup_pc(uint32_t pc); + +volatile uint32_t *hal_cmu_get_bootmode_addr(void); + +volatile uint32_t *hal_cmu_get_memsc_addr(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_cmu_common.c b/platform/hal/hal_cmu_common.c new file mode 100644 index 0000000..147ac9f --- /dev/null +++ b/platform/hal/hal_cmu_common.c @@ -0,0 +1,447 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include "hal_cmu.h" +#include CHIP_SPECIFIC_HDR(reg_cmu) +#ifdef AON_CMU_BASE +#include CHIP_SPECIFIC_HDR(reg_aoncmu) +#endif +#include "cmsis.h" +#include "hal_analogif.h" +#include "hal_bootmode.h" +#include "hal_cache.h" +#include "hal_chipid.h" +#include "hal_iomux.h" +#include "hal_location.h" +#include "hal_norflash.h" +#include "hal_sleep.h" +#include "hal_sysfreq.h" +#include "hal_timer.h" +#include "hal_trace.h" + +#if defined(CHIP_HAS_USB) && (defined(MCU_HIGH_PERFORMANCE_MODE) && !(defined(ULTRA_LOW_POWER) || defined(OSC_26M_X4_AUD2BB))) +#define USB_PLL_INIT_ON +#endif +#if (!defined(ULTRA_LOW_POWER) && !defined(OSC_26M_X4_AUD2BB)) || \ + (!defined(FLASH_LOW_SPEED) && !defined(OSC_26M_X4_AUD2BB)) || \ + (defined(PSRAM_ENABLE) && !defined(PSRAM_LOW_SPEED)) +#define AUD_PLL_INIT_ON +#endif + +// SIMU_RES +#define CMU_SIMU_RES_PASSED (0x9A55) +#define CMU_SIMU_RES_FAILED (0xFA11) + +typedef void (*HAL_POWER_DOWN_WAKEUP_HANDLER)(void); + +static struct CMU_T * const cmu = (struct CMU_T *)CMU_BASE; +#ifdef AON_CMU_BASE +static struct AONCMU_T * const POSSIBLY_UNUSED aoncmu = (struct AONCMU_T *)AON_CMU_BASE; +#endif + +#ifdef HAL_CMU_VALID_CRYSTAL_FREQ +static const uint32_t valid_crystal_freq_list[] = HAL_CMU_VALID_CRYSTAL_FREQ; +#define CRYSTAL_FREQ_ATTR BOOT_DATA_LOC +#else +#define CRYSTAL_FREQ_ATTR const +#endif + +static uint32_t CRYSTAL_FREQ_ATTR crystal_freq = HAL_CMU_DEFAULT_CRYSTAL_FREQ; + +void BOOT_TEXT_FLASH_LOC hal_cmu_set_crystal_freq_index(uint32_t index) +{ +#ifdef HAL_CMU_VALID_CRYSTAL_FREQ + if (index >= ARRAY_SIZE(valid_crystal_freq_list)) { + index %= ARRAY_SIZE(valid_crystal_freq_list); + } + crystal_freq = valid_crystal_freq_list[index]; +#endif +} + +uint32_t BOOT_TEXT_SRAM_LOC hal_cmu_get_crystal_freq(void) +{ + return crystal_freq; +} + +uint32_t BOOT_TEXT_FLASH_LOC hal_cmu_get_default_crystal_freq(void) +{ + return HAL_CMU_DEFAULT_CRYSTAL_FREQ; +} + +void hal_cmu_write_lock(void) +{ + cmu->WRITE_UNLOCK = 0xCAFE0000; +} + +void hal_cmu_write_unlock(void) +{ + cmu->WRITE_UNLOCK = 0xCAFE0001; +} + +void hal_cmu_sys_reboot(void) +{ + hal_cmu_reset_set(HAL_CMU_MOD_GLOBAL); +} + +void hal_cmu_simu_init(void) +{ + cmu->SIMU_RES = 0; +} + +void hal_cmu_simu_pass(void) +{ + cmu->SIMU_RES = CMU_SIMU_RES_PASSED; +} + +void hal_cmu_simu_fail(void) +{ + cmu->SIMU_RES = CMU_SIMU_RES_FAILED; +} + +void hal_cmu_simu_tag(uint8_t shift) +{ + cmu->SIMU_RES |= (1 << shift); +} + +void hal_cmu_simu_set_val(uint32_t val) +{ + cmu->SIMU_RES = val; +} + +uint32_t hal_cmu_simu_get_val(void) +{ + return cmu->SIMU_RES; +} + +void hal_cmu_set_wakeup_pc(uint32_t pc) +{ +#ifdef RAMRET_BASE + uint32_t *wake_pc = +#ifdef CHIP_BEST2000 + (uint32_t *)RAMRET_BASE; +#else + (uint32_t *)&aoncmu->WAKEUP_PC; + + STATIC_ASSERT(sizeof(HAL_POWER_DOWN_WAKEUP_HANDLER) <= sizeof(uint32_t), "Invalid func ptr size"); +#endif + + *wake_pc = pc; +#endif +} + +void hal_cmu_rom_wakeup_check(void) +{ +#ifdef RAMRET_BASE + union HAL_HW_BOOTMODE_T hw; + uint32_t sw; + HAL_POWER_DOWN_WAKEUP_HANDLER *wake_fn = +#ifdef CHIP_BEST2000 + (HAL_POWER_DOWN_WAKEUP_HANDLER *)RAMRET_BASE; +#else + (HAL_POWER_DOWN_WAKEUP_HANDLER *)&aoncmu->WAKEUP_PC; +#endif + + hw = hal_rom_hw_bootmode_get(); + if (hw.watchdog == 0 && hw.global == 0) { + sw = hal_sw_bootmode_get(); + if ((sw & HAL_SW_BOOTMODE_POWER_DOWN_WAKEUP) && *wake_fn) { + (*wake_fn)(); + } + } + + *wake_fn = NULL; +#endif +} + +#ifndef HAL_CMU_PLL_T +void hal_cmu_rom_enable_pll(void) +{ +#ifdef CHIP_HAS_USB + hal_cmu_pll_enable(HAL_CMU_PLL_USB, HAL_CMU_PLL_USER_SYS); + hal_cmu_sys_select_pll(HAL_CMU_PLL_USB); + hal_cmu_flash_select_pll(HAL_CMU_PLL_USB); +#else + hal_cmu_pll_enable(HAL_CMU_PLL_AUD, HAL_CMU_PLL_USER_SYS); + hal_cmu_sys_select_pll(HAL_CMU_PLL_AUD); + hal_cmu_flash_select_pll(HAL_CMU_PLL_AUD); +#endif +} + +void hal_cmu_programmer_enable_pll(void) +{ + hal_cmu_pll_enable(HAL_CMU_PLL_AUD, HAL_CMU_PLL_USER_SYS); + hal_cmu_flash_select_pll(HAL_CMU_PLL_AUD); + hal_cmu_sys_select_pll(HAL_CMU_PLL_AUD); +} + +void BOOT_TEXT_FLASH_LOC hal_cmu_init_pll_selection(void) +{ + // !!!!!! + // CAUTION: + // hal_cmu_pll_enable()/hal_cmu_pll_disable() must be called after hal_chipid_init(), + // for the init div values are extracted in hal_chipid_init(). + // !!!!!! + +#if defined(CHIP_BEST1000) || defined(CHIP_BEST2000) +#ifdef CHIP_HAS_USB + // Enable USB PLL before switching (clock mux requirement) + // -- USB PLL might not be started in ROM + hal_cmu_pll_enable(HAL_CMU_PLL_USB, HAL_CMU_PLL_USER_SYS); +#endif + hal_cmu_pll_enable(HAL_CMU_PLL_AUD, HAL_CMU_PLL_USER_SYS); +#else // !(best1000 || best2000) + // Disable the PLL which might be enabled in ROM +#ifdef CHIP_HAS_USB + hal_cmu_pll_disable(HAL_CMU_PLL_USB, HAL_CMU_PLL_USER_ALL); +#else + hal_cmu_pll_disable(HAL_CMU_PLL_AUD, HAL_CMU_PLL_USER_ALL); +#endif +#endif // !(best1000 || best2000) + +#ifdef FLASH_LOW_SPEED +#ifdef CHIP_HAS_USB + // Switch flash clock to USB PLL, and then shutdown USB PLL, + // to save power consumed in clock divider + hal_cmu_flash_select_pll(HAL_CMU_PLL_USB); +#endif +#else + // Switch flash clock to audio PLL + hal_cmu_flash_select_pll(HAL_CMU_PLL_AUD); +#endif + +#ifdef CHIP_HAS_PSRAM +#ifdef PSRAM_LOW_SPEED +#ifdef CHIP_HAS_USB + // Switch psram clock to USB PLL, and then shutdown USB PLL, + // to save power consumed in clock divider + hal_cmu_mem_select_pll(HAL_CMU_PLL_USB); +#endif +#else + // Switch psram clock to audio PLL + hal_cmu_mem_select_pll(HAL_CMU_PLL_AUD); +#endif +#endif + + // Select system PLL after selecting flash/psram PLLs +#ifdef ULTRA_LOW_POWER + hal_cmu_low_freq_mode_init(); +#else +#if defined(MCU_HIGH_PERFORMANCE_MODE) && defined(CHIP_HAS_USB) + // Switch system clocks to USB PLL + hal_cmu_sys_select_pll(HAL_CMU_PLL_USB); +#else + // Switch system clocks to audio PLL + hal_cmu_sys_select_pll(HAL_CMU_PLL_AUD); +#endif +#endif + +#if defined(CHIP_BEST1000) || defined(CHIP_BEST2000) +#ifndef USB_PLL_INIT_ON + // Disable USB PLL after switching (clock mux requirement) + hal_cmu_pll_disable(HAL_CMU_PLL_USB, HAL_CMU_PLL_USER_SYS); +#endif +#ifndef AUD_PLL_INIT_ON + hal_cmu_pll_disable(HAL_CMU_PLL_AUD, HAL_CMU_PLL_USER_SYS); +#endif +#else // !(best1000 || best2000) +#ifdef USB_PLL_INIT_ON + hal_cmu_pll_enable(HAL_CMU_PLL_USB, HAL_CMU_PLL_USER_SYS); +#endif +#ifdef AUD_PLL_INIT_ON + hal_cmu_pll_enable(HAL_CMU_PLL_AUD, HAL_CMU_PLL_USER_SYS); +#endif +#endif // !(best1000 || best2000) + +#if defined(MCU_HIGH_PERFORMANCE_MODE) && !defined(ULTRA_LOW_POWER) && defined(OSC_26M_X4_AUD2BB) +#error "Error configuration: MCU_HIGH_PERFORMANCE_MODE has no effect" +#endif +} +#endif // !HAL_CMU_PLL_T + +static void BOOT_TEXT_FLASH_LOC hal_cmu_init_periph_clock(void) +{ +#ifdef PERIPH_PLL_FREQ + hal_cmu_periph_set_div(1); +#endif + + // TODO: Move the following SDIO freq setting to hal_sdio.c +#ifdef CHIP_HAS_SDIO + hal_cmu_sdio_set_freq(HAL_CMU_PERIPH_FREQ_26M); +#endif +} + +void hal_cmu_rom_setup(void) +{ + hal_cmu_lpu_wait_26m_ready(); + hal_cmu_simu_init(); + hal_cmu_rom_clock_init(); + hal_cmu_timer0_select_slow(); +#ifdef TIMER1_BASE + hal_cmu_timer1_select_fast(); +#endif + hal_sys_timer_open(); + + // Init sys clock + hal_cmu_sys_set_freq(HAL_CMU_FREQ_26M); + + // Init flash clock (this should be done before load_boot_settings, for security register read) + hal_cmu_flash_set_freq(HAL_CMU_FREQ_26M); + // Reset flash controller (for JTAG reset and run) + // Enable flash controller (flash controller is reset by default since BEST1400) + hal_cmu_reset_set(HAL_CMU_MOD_O_FLASH); + hal_cmu_reset_set(HAL_CMU_MOD_H_FLASH); + hal_cmu_reset_clear(HAL_CMU_MOD_H_FLASH); + hal_cmu_reset_clear(HAL_CMU_MOD_O_FLASH); + + // Disable cache (for JTAG reset and run) + hal_cache_disable(HAL_CACHE_ID_I_CACHE); + hal_cache_disable(HAL_CACHE_ID_D_CACHE); + + // Init APB clock + hal_cmu_apb_init_div(); +} + +void hal_cmu_programmer_setup(void) +{ + hal_cmu_ema_init(); + hal_sys_timer_open(); + +#ifdef JTAG_ENABLE + hal_iomux_set_jtag(); + hal_cmu_jtag_clock_enable(); +#endif + +#ifndef FPGA + int ret; + // Open analogif (ISPI) + ret = hal_analogif_open(); + if (ret) { + hal_cmu_simu_tag(31); + do { volatile int i = 0; i++; } while (1); + } + // Init chip id + // 1) Read id from ana/rf/pmu + // 2) Init clock settings in ana/rf/pmu if the default h/w register values are bad + hal_chipid_init(); + + // Enable OSC X2/X4 in cmu after enabling their source in hal_chipid_init() + hal_cmu_osc_x2_enable(); + hal_cmu_osc_x4_enable(); +#endif +} + +#ifdef FPGA + +void BOOT_TEXT_FLASH_LOC hal_cmu_fpga_setup(void) +{ + hal_cmu_timer0_select_slow(); + hal_sys_timer_open(); + + hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_52M); + + hal_cmu_apb_init_div(); + hal_cmu_ispi_set_freq(HAL_CMU_PERIPH_FREQ_26M); + + // Init peripheral clocks + hal_cmu_init_periph_clock(); + + hal_norflash_init(); +#if defined(CHIP_HAS_PSRAM) && defined(PSRAM_ENABLE) + hal_psram_init(); +#endif +} + +#else // !FPGA + +void BOOT_TEXT_FLASH_LOC hal_cmu_setup(void) +{ + int ret; + enum HAL_CMU_FREQ_T freq; + + hal_iomux_set_default_config(); +#ifdef JTAG_ENABLE + hal_iomux_set_jtag(); + hal_cmu_jtag_clock_enable(); +#endif + hal_cmu_module_init_state(); + hal_cmu_ema_init(); + hal_cmu_timer0_select_slow(); +#ifdef TIMER1_BASE + hal_cmu_timer1_select_fast(); +#endif + hal_sys_timer_open(); + hal_hw_bootmode_init(); + + // Init system/flash/memory clocks before initializing clock setting + // and before switching PLL + hal_norflash_set_freq(HAL_CMU_FREQ_26M); + hal_cmu_mem_set_freq(HAL_CMU_FREQ_26M); + hal_cmu_sys_set_freq(HAL_CMU_FREQ_26M); + + // Set ISPI module freq + hal_cmu_ispi_set_freq(HAL_CMU_PERIPH_FREQ_26M); + // Open analogif (ISPI) + ret = hal_analogif_open(); + if (ret) { + hal_cmu_simu_tag(31); + do { volatile int i = 0; i++; } while (1); + } + // Init chip id + // 1) Read id from ana/rf/pmu + // 2) Init clock settings in ana/rf/pmu if the default h/w register values are bad + hal_chipid_init(); + +#ifdef CALIB_SLOW_TIMER + // Calib slow timer after determining the crystal freq + hal_sys_timer_calib(); +#endif + + // Enable OSC X2/X4 in cmu after enabling their source in hal_chipid_init() + hal_cmu_osc_x2_enable(); + hal_cmu_osc_x4_enable(); + + // Init PLL selection + hal_cmu_init_pll_selection(); + + // Init peripheral clocks + hal_cmu_init_periph_clock(); + + // Sleep setting +#ifdef NO_LPU_26M + while (hal_cmu_lpu_init(HAL_CMU_LPU_CLK_NONE) == -1); +#else + while (hal_cmu_lpu_init(HAL_CMU_LPU_CLK_26M) == -1); +#endif + // Init sys freq after applying the sleep setting (which might change sys freq) +#ifdef NO_LPU_26M + hal_sys_timer_delay(MS_TO_TICKS(20)); +#endif + + // Init system clock +#ifdef ULTRA_LOW_POWER + freq = HAL_CMU_FREQ_52M; +#else + freq = HAL_CMU_FREQ_104M; +#endif + hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, freq); + + // Init flash + hal_norflash_init(); + +} + +#endif // !FPGA + diff --git a/platform/hal/hal_codec.h b/platform/hal/hal_codec.h new file mode 100644 index 0000000..a853f83 --- /dev/null +++ b/platform/hal/hal_codec.h @@ -0,0 +1,213 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_CODEC_H__ +#define __HAL_CODEC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_aud.h" + +#define DB_TO_QDB(n) ((n) * 4) +#define QDB_TO_DB(n) ((n) / 4) + +enum HAL_CODEC_ID_T { + HAL_CODEC_ID_0 = 0, + HAL_CODEC_ID_NUM, +}; + +struct HAL_CODEC_CONFIG_T { + enum AUD_BITS_T bits; + enum AUD_SAMPRATE_T sample_rate; + enum AUD_CHANNEL_NUM_T channel_num; + enum AUD_CHANNEL_MAP_T channel_map; + + uint32_t use_dma:1; + uint32_t vol:5; + + enum AUD_IO_PATH_T io_path; + + uint32_t set_flag; +}; + +struct dac_classg_cfg { + uint8_t thd2; + uint8_t thd1; + uint8_t thd0; + uint8_t lr; + uint8_t step_4_3n; + uint8_t quick_down; + uint16_t wind_width; +}; + +enum HAL_CODEC_CONFIG_FLAG_T{ + HAL_CODEC_CONFIG_NULL = 0x00, + + HAL_CODEC_CONFIG_BITS = 0x01, + HAL_CODEC_CONFIG_SAMPLE_RATE = 0x02, + HAL_CODEC_CONFIG_CHANNEL_NUM = 0x04, + HAL_CODEC_CONFIG_CHANNEL_MAP = 0x08, + HAL_CODEC_CONFIG_VOL = 0x10, + + HAL_CODEC_CONFIG_ALL = 0xff, +}; + +enum HAL_CODEC_DAC_RESET_STAGE_T { + HAL_CODEC_DAC_PRE_RESET, + HAL_CODEC_DAC_POST_RESET, +}; + +enum HAL_CODEC_SYNC_TYPE_T { + HAL_CODEC_SYNC_TYPE_NONE, + HAL_CODEC_SYNC_TYPE_GPIO, + HAL_CODEC_SYNC_TYPE_BT, + HAL_CODEC_SYNC_TYPE_WIFI, +}; + +enum HAL_CODEC_PERF_TEST_POWER_T { + HAL_CODEC_PERF_TEST_30MW, + HAL_CODEC_PERF_TEST_10MW, + HAL_CODEC_PERF_TEST_5MW, + HAL_CODEC_PERF_TEST_M60DB, + + HAL_CODEC_PERF_TEST_QTY +}; + +enum HAL_CODEC_IIR_USER_T { + HAL_CODEC_IIR_USER_ANC, + HAL_CODEC_IIR_USER_EQ, + + HAL_CODEC_IIR_USER_QTY, +}; + +enum HAL_CODEC_TIMER_TRIG_MODE_T { + HAL_CODEC_TIMER_TRIG_MODE_DAC, + HAL_CODEC_TIMER_TRIG_MODE_ADC, + HAL_CODEC_TIMER_TRIG_MODE_ANY, + + HAL_CODEC_TIMER_TRIG_MODE_QTY, +}; + +typedef void (*HAL_CODEC_DAC_RESET_CALLBACK)(enum HAL_CODEC_DAC_RESET_STAGE_T stage); +typedef void (*HAL_CODEC_SW_OUTPUT_COEF_CALLBACK)(float coef); +typedef void (*HAL_CODEC_BT_TRIGGER_CALLBACK)(void); +typedef void (*HAL_CODEC_EVENT_TRIGGER_CALLBACK)(void); +typedef void (*HAL_CODEC_TIMER_TRIGGER_CALLBACK)(void); +typedef void (*HAL_CODEC_IRQ_CALLBACK)(uint32_t status); + +uint32_t hal_codec_get_input_path_cfg(enum AUD_IO_PATH_T io_path); +const struct CODEC_DAC_VOL_T *hal_codec_get_dac_volume(uint32_t index); +const CODEC_ADC_VOL_T *hal_codec_get_adc_volume(uint32_t index); +uint32_t hal_codec_get_mic_chan_volume_level(uint32_t map); +uint8_t hal_codec_get_digmic_hw_index(uint8_t chan); + +int hal_codec_open(enum HAL_CODEC_ID_T id); +int hal_codec_close(enum HAL_CODEC_ID_T id); +void hal_codec_crash_mute(void); +void hal_codec_stop_playback_stream(enum HAL_CODEC_ID_T id); +void hal_codec_start_playback_stream(enum HAL_CODEC_ID_T id); +int hal_codec_start_stream(enum HAL_CODEC_ID_T id, enum AUD_STREAM_T stream); +int hal_codec_stop_stream(enum HAL_CODEC_ID_T id, enum AUD_STREAM_T stream); +int hal_codec_start_interface(enum HAL_CODEC_ID_T id, enum AUD_STREAM_T stream, int dma); +int hal_codec_stop_interface(enum HAL_CODEC_ID_T id, enum AUD_STREAM_T stream); +int hal_codec_setup_stream(enum HAL_CODEC_ID_T id, enum AUD_STREAM_T stream, const struct HAL_CODEC_CONFIG_T *cfg); +int hal_codec_anc_adc_enable(enum ANC_TYPE_T type); +int hal_codec_anc_adc_disable(enum ANC_TYPE_T type); +enum AUD_SAMPRATE_T hal_codec_anc_convert_rate(enum AUD_SAMPRATE_T rate); +int hal_codec_anc_dma_enable(enum HAL_CODEC_ID_T id); +int hal_codec_anc_dma_disable(enum HAL_CODEC_ID_T id); +void hal_codec_set_anc_boost_gain_attn(float attn); +void hal_codec_apply_anc_adc_gain_offset(enum ANC_TYPE_T type, int8_t offset_l, int8_t offset_r); +int hal_codec_aux_mic_dma_enable(enum HAL_CODEC_ID_T id); +int hal_codec_aux_mic_dma_disable(enum HAL_CODEC_ID_T id); +uint32_t hal_codec_get_alg_dac_shift(void); +void hal_codec_set_dac_reset_callback(HAL_CODEC_DAC_RESET_CALLBACK callback); +void hal_codec_set_sw_output_coef_callback(HAL_CODEC_SW_OUTPUT_COEF_CALLBACK callback); +void hal_codec_dac_gain_m60db_check(enum HAL_CODEC_PERF_TEST_POWER_T type); +void hal_codec_set_noise_reduction(bool enable); +void hal_codec_classg_config(const struct dac_classg_cfg *cfg); +void hal_codec_set_dac_dc_gain_attn(float attn); +void hal_codec_set_dac_dc_offset(int16_t dc_l, int16_t dc_r); +void hal_codec_sidetone_enable(void); +void hal_codec_sidetone_disable(void); +int hal_codec_sidetone_gain_ramp_up(float step); +int hal_codec_sidetone_gain_ramp_down(float step); +void hal_codec_select_adc_iir_mic(uint32_t index, enum AUD_CHANNEL_MAP_T mic_map); +void hal_codec_dac_mute(bool mute); +void hal_codec_adc_mute(bool mute); +int hal_codec_set_chan_vol(enum AUD_STREAM_T stream, enum AUD_CHANNEL_MAP_T ch_map, uint8_t vol); +void hal_codec_sync_dac_enable(enum HAL_CODEC_SYNC_TYPE_T type); +void hal_codec_sync_dac_disable(void); +void hal_codec_sync_adc_enable(enum HAL_CODEC_SYNC_TYPE_T type); +void hal_codec_sync_adc_disable(void); +void hal_codec_sync_dac_resample_rate_enable(enum HAL_CODEC_SYNC_TYPE_T type); +void hal_codec_sync_dac_resample_rate_disable(void); +void hal_codec_sync_adc_resample_rate_enable(enum HAL_CODEC_SYNC_TYPE_T type); +void hal_codec_sync_adc_resample_rate_disable(void); +void hal_codec_sync_dac_gain_enable(enum HAL_CODEC_SYNC_TYPE_T type); +void hal_codec_sync_dac_gain_disable(void); +void hal_codec_sync_adc_gain_enable(enum HAL_CODEC_SYNC_TYPE_T type); +void hal_codec_sync_adc_gain_disable(void); +int hal_codec_dac_reset_set(void); +int hal_codec_dac_reset_clear(void); +int hal_codec_dac_sdm_reset_set(void); +int hal_codec_dac_sdm_reset_clear(void); +void hal_codec_tune_resample_rate(enum AUD_STREAM_T stream, float ratio); +void hal_codec_tune_both_resample_rate(float ratio); +void hal_codec_get_dac_gain(float *left_gain,float *right_gain); +int hal_codec_select_clock_out(uint32_t cfg); +int hal_codec_config_digmic_phase(uint8_t phase); +void hal_codec_setup_mc(enum AUD_CHANNEL_NUM_T channel_num, enum AUD_BITS_T bits); +void hal_codec_dsd_enable(void); +void hal_codec_dsd_disable(void); +void hal_codec_swap_output(bool swap); + +void hal_codec_gpio_trigger_debounce_enable(void); +void hal_codec_gpio_trigger_debounce_disable(void); + +uint32_t hal_codec_timer_get(void); +uint32_t hal_codec_timer_ticks_to_us(uint32_t ticks); +void hal_codec_timer_trigger_read(void); + +void hal_codec_anc_fb_check_set_irq_handler(HAL_CODEC_IRQ_CALLBACK cb); + +int hal_codec_vad_open(const struct AUD_VAD_CONFIG_T *cfg); +int hal_codec_vad_close(void); +int hal_codec_vad_start(void); +int hal_codec_vad_stop(void); +uint32_t hal_codec_vad_recv_data(uint8_t *dst, uint32_t dst_size); +void hal_codec_get_vad_data_info(struct CODEC_VAD_BUF_INFO_T* vad_buf_info); + +void hal_codec_set_bt_trigger_callback(HAL_CODEC_BT_TRIGGER_CALLBACK callback); +int hal_codec_bt_trigger_start(void); +int hal_codec_bt_trigger_stop(void); + +int hal_codec_iir_enable(enum HAL_CODEC_IIR_USER_T user, uint32_t speed); +int hal_codec_iir_disable(enum HAL_CODEC_IIR_USER_T user); + +void hal_codec_min_phase_mode_enable(enum AUD_STREAM_T stream); +void hal_codec_min_phase_mode_disable(enum AUD_STREAM_T stream); + +int hal_codec_timer_trig_i2s_enable(enum HAL_CODEC_TIMER_TRIG_MODE_T mode, uint32_t ticks, bool periodic); +int hal_codec_timer_trig_i2s_disable(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_codec_common.c b/platform/hal/hal_codec_common.c new file mode 100644 index 0000000..53fd8e4 --- /dev/null +++ b/platform/hal/hal_codec_common.c @@ -0,0 +1,129 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis.h" +#include "hal_codec.h" +#include "hal_trace.h" +#include "tgt_hardware.h" + +extern const CODEC_ADC_VOL_T codec_adc_vol[TGT_ADC_VOL_LEVEL_QTY]; + +#ifndef CODEC_MIC_CH0_SADC_VOL +#define CODEC_MIC_CH0_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_MIC_CH1_SADC_VOL +#define CODEC_MIC_CH1_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_MIC_CH2_SADC_VOL +#define CODEC_MIC_CH2_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_MIC_CH3_SADC_VOL +#define CODEC_MIC_CH3_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_MIC_CH4_SADC_VOL +#define CODEC_MIC_CH4_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_MIC_CH5_SADC_VOL +#define CODEC_MIC_CH5_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_MIC_CH6_SADC_VOL +#define CODEC_MIC_CH6_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_MIC_CH7_SADC_VOL +#define CODEC_MIC_CH7_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_DIGMIC_CH0_SADC_VOL +#define CODEC_DIGMIC_CH0_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_DIGMIC_CH1_SADC_VOL +#define CODEC_DIGMIC_CH1_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_DIGMIC_CH2_SADC_VOL +#define CODEC_DIGMIC_CH2_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_DIGMIC_CH3_SADC_VOL +#define CODEC_DIGMIC_CH3_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_DIGMIC_CH4_SADC_VOL +#define CODEC_DIGMIC_CH4_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_DIGMIC_CH5_SADC_VOL +#define CODEC_DIGMIC_CH5_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_DIGMIC_CH6_SADC_VOL +#define CODEC_DIGMIC_CH6_SADC_VOL CODEC_SADC_VOL +#endif +#ifndef CODEC_DIGMIC_CH7_SADC_VOL +#define CODEC_DIGMIC_CH7_SADC_VOL CODEC_SADC_VOL +#endif + +static const uint8_t codec_mic_chan_vol[] = { + CODEC_MIC_CH0_SADC_VOL, CODEC_MIC_CH1_SADC_VOL, CODEC_MIC_CH2_SADC_VOL, CODEC_MIC_CH3_SADC_VOL, + CODEC_MIC_CH4_SADC_VOL, CODEC_MIC_CH5_SADC_VOL, CODEC_MIC_CH6_SADC_VOL, CODEC_MIC_CH7_SADC_VOL, + CODEC_DIGMIC_CH0_SADC_VOL, CODEC_DIGMIC_CH1_SADC_VOL, CODEC_DIGMIC_CH2_SADC_VOL, CODEC_DIGMIC_CH3_SADC_VOL, + CODEC_DIGMIC_CH4_SADC_VOL, CODEC_DIGMIC_CH5_SADC_VOL, CODEC_DIGMIC_CH6_SADC_VOL, CODEC_DIGMIC_CH7_SADC_VOL, +}; + +uint32_t hal_codec_get_input_path_cfg(enum AUD_IO_PATH_T io_path) +{ + int i; + + for (i = 0; i < CFG_HW_AUD_INPUT_PATH_NUM; i++) { + if (io_path == cfg_audio_input_path_cfg[i].io_path) { + return cfg_audio_input_path_cfg[i].cfg; + } + } + ASSERT(false, "%s: Bad input path: %d", __func__, io_path); + return 0; +} + +const struct CODEC_DAC_VOL_T *hal_codec_get_dac_volume(uint32_t index) +{ + uint32_t _array_sizeof_vol = ARRAY_SIZE(codec_dac_vol); + if (index < _array_sizeof_vol) { + return &codec_dac_vol[index]; + } else { + return &codec_dac_vol[_array_sizeof_vol-1]; + } +} + +const CODEC_ADC_VOL_T *hal_codec_get_adc_volume(uint32_t index) +{ + uint32_t _array_sizeof_vol = ARRAY_SIZE(codec_adc_vol); + if (index < _array_sizeof_vol) { + return &codec_adc_vol[index]; + } else { + return &codec_adc_vol[_array_sizeof_vol-1]; + } +} + +uint32_t hal_codec_get_mic_chan_volume_level(uint32_t map) +{ + uint32_t mic_ch; + + mic_ch = get_lsb_pos(map); + + if (mic_ch < ARRAY_SIZE(codec_mic_chan_vol)) { + return codec_mic_chan_vol[mic_ch]; + } else { + return ARRAY_SIZE(codec_adc_vol); + } +} + +uint8_t hal_codec_get_digmic_hw_index(uint8_t chan) +{ + return chan - get_msb_pos(AUD_CHANNEL_MAP_DIGMIC_CH0); +} + diff --git a/platform/hal/hal_dma.c b/platform/hal/hal_dma.c new file mode 100644 index 0000000..87d3ccd --- /dev/null +++ b/platform/hal/hal_dma.c @@ -0,0 +1,1057 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include "cmsis_nvic.h" +#include "hal_chipid.h" +#include "hal_cmu.h" +#include "hal_dma.h" +#include "hal_location.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "reg_dma.h" + +#if (defined(CHIP_BEST1000) || defined(CHIP_BEST2000) || defined(CHIP_BEST2300)) && !(defined(ROM_BUILD) || defined(PROGRAMMER)) +#define DMA_REMAP +#endif + +enum HAL_DMA_INST_T { + HAL_DMA_INST_AUDMA = 0, +#if (CHIP_HAS_DMA == 1) + HAL_DMA_INST_GPDMA = HAL_DMA_INST_AUDMA, +#else + HAL_DMA_INST_GPDMA, +#endif + + HAL_DMA_INST_QTY +}; + +struct HAL_DMA_FIFO_ADDR_T { + uint32_t count; + const uint32_t *addr; +}; + +struct HAL_DMA_FIFO_PERIPH_T { + uint32_t count; + const enum HAL_DMA_PERIPH_T *periph; +#ifdef DMA_REMAP + const enum HAL_DMA_PERIPH_T *periph_remap; +#endif +}; + +/***************************************************************************** + * Private types/enumerations/variables + ****************************************************************************/ + +#include CHIP_SPECIFIC_HDR(hal_dmacfg) + +static struct DMA_T * const dma[HAL_DMA_INST_QTY] = { + (struct DMA_T *)AUDMA_BASE, +#if (CHIP_HAS_DMA > 1) + (struct DMA_T *)GPDMA_BASE, +#endif +}; + +static const IRQn_Type irq_type[HAL_DMA_INST_QTY] = { + AUDMA_IRQn, +#if (CHIP_HAS_DMA > 1) + GPDMA_IRQn, +#endif +}; + +static void hal_audma_irq_handler(void); +#if (CHIP_HAS_DMA > 1) +static void hal_gpdma_irq_handler(void); +#endif + +static const uint32_t irq_entry[HAL_DMA_INST_QTY] = { + (uint32_t)hal_audma_irq_handler, +#if (CHIP_HAS_DMA > 1) + (uint32_t)hal_gpdma_irq_handler, +#endif +}; + +static const struct HAL_DMA_FIFO_ADDR_T fifo_addr[HAL_DMA_INST_QTY] = { + { + .count = ARRAY_SIZE(audma_fifo_addr), + .addr = audma_fifo_addr, + }, +#if (CHIP_HAS_DMA > 1) + { + .count = ARRAY_SIZE(gpdma_fifo_addr), + .addr = gpdma_fifo_addr, + }, +#endif +}; + +static const struct HAL_DMA_FIFO_PERIPH_T fifo_periph[HAL_DMA_INST_QTY] = { + { + .count = ARRAY_SIZE(audma_fifo_periph), + .periph = audma_fifo_periph, +#ifdef DMA_REMAP + .periph_remap = audma_fifo_periph_remap, +#endif + }, +#if (CHIP_HAS_DMA > 1) + { + .count = ARRAY_SIZE(gpdma_fifo_periph), + .periph = gpdma_fifo_periph, +#ifdef DMA_REMAP + .periph_remap = gpdma_fifo_periph_remap, +#endif + }, +#endif +}; + +static const uint8_t chan_start[HAL_DMA_INST_QTY] = { + AUDMA_CHAN_START, +#if (CHIP_HAS_DMA > 1) + GPDMA_CHAN_START, +#endif +}; + +static const uint8_t chan_num[HAL_DMA_INST_QTY] = { + AUDMA_CHAN_NUM, +#if (CHIP_HAS_DMA > 1) + GPDMA_CHAN_NUM, +#endif +}; + +/* Channel array to monitor free channel */ +static bool chan_enabled[HAL_DMA_INST_QTY][DMA_NUMBER_CHANNELS]; + +static HAL_DMA_IRQ_HANDLER_T handler[HAL_DMA_INST_QTY][DMA_NUMBER_CHANNELS]; + +#ifdef DMA_REMAP +static uint32_t periph_remap_bitmap[HAL_DMA_INST_QTY]; +#endif + +#ifdef CORE_SLEEP_POWER_DOWN +static uint32_t saved_dma_regs[HAL_DMA_INST_QTY]; +#endif + +static const char * const err_invalid_inst = "Invalid DMA inst: %u"; + +static const char * const err_invalid_chan[HAL_DMA_INST_QTY] = { + "Invalid AUDMA chan: %u", +#if (CHIP_HAS_DMA > 1) + "Invalid GPDMA chan: %u", +#endif +}; + +static bool dma_opened = false; + +static HAL_DMA_DELAY_FUNC dma_delay = NULL; + + +/***************************************************************************** + * Public types/enumerations/variables + ****************************************************************************/ + +/***************************************************************************** + * Private functions + ****************************************************************************/ +static void hal_dma_delay(uint32_t ms) +{ + if (dma_delay && !in_isr()) { + dma_delay(ms); + } else { + hal_sys_timer_delay(MS_TO_TICKS(ms)); + } +} + +static inline uint8_t generate_chan(enum HAL_DMA_INST_T inst, uint8_t hwch) +{ + return ((inst << 4) | (hwch & 0xF)); +} + +static inline enum HAL_DMA_INST_T get_inst_from_chan(uint8_t ch) +{ + return (enum HAL_DMA_INST_T)(ch >> 4); +} + +static inline uint8_t get_hwch_from_chan(uint8_t ch) +{ + return (ch & 0xF); +} + +static inline int get_index_from_periph(enum HAL_DMA_PERIPH_T periph, enum HAL_DMA_INST_T *pinst, uint8_t *pidx) +{ + enum HAL_DMA_INST_T inst; + int i; + + for (inst = 0; inst < HAL_DMA_INST_QTY; inst++) { + for (i = 0; i < fifo_periph[inst].count; i++) { + if (fifo_periph[inst].periph[i] == periph) { + *pinst = inst; + *pidx = i; + return 0; + } + } + } + + return 1; +} + +#ifdef DMA_REMAP +static inline int get_remap_index_from_periph(enum HAL_DMA_INST_T inst, enum HAL_DMA_PERIPH_T periph, uint8_t *pidx) +{ + int i; + + if (fifo_periph[inst].periph_remap == NULL) { + return 1; + } + + for (i = 0; i < fifo_periph[inst].count; i++) { + if (fifo_periph[inst].periph_remap[i] == periph) { + *pidx = i; + return 0; + } + } + + return 2; +} +#endif + +static inline uint32_t hal_dma_get_periph_addr(enum HAL_DMA_PERIPH_T periph) +{ + int ret; + enum HAL_DMA_INST_T inst; + uint8_t index; + + ret = get_index_from_periph(periph, &inst, &index); + if (ret) { + return 0; + } + + return fifo_addr[inst].addr[index]; +} + +/* Initialize the DMA */ +static void hal_dma_open_inst(enum HAL_DMA_INST_T inst) +{ + uint8_t i; + + /* Reset all channel configuration register */ + for (i = 0; i < DMA_NUMBER_CHANNELS; i++) { + dma[inst]->CH[i].CONFIG = 0; + } + + /* Clear all DMA interrupt and error flag */ + dma[inst]->INTTCCLR = ~0UL; + dma[inst]->INTERRCLR = ~0UL; + + dma[inst]->DMACONFIG = (dma[inst]->DMACONFIG & ~(DMA_DMACONFIG_AHB1_BIGENDIAN | + DMA_DMACONFIG_AHB2_BIGENDIAN | DMA_DMACONFIG_CLK_EN_MASK)) | + DMA_DMACONFIG_EN | +#ifdef CHIP_BEST3001 + DMA_DMACONFIG_TC_IRQ_EN_MASK | +#endif + 0; + +#ifdef CHIP_BEST1400 + dma[inst]->DMACONFIG &= ~DMA_DMACONFIG_TC_IRQ_EN_MASK; +#endif + + /* Reset all channels are free */ + for (i = 0; i < DMA_NUMBER_CHANNELS; i++) { + chan_enabled[inst][i] = false; + } + + NVIC_SetVector(irq_type[inst], irq_entry[inst]); + if (inst == HAL_DMA_INST_AUDMA) { + NVIC_SetPriority(irq_type[inst], IRQ_PRIORITY_ABOVENORMAL); + } else { + NVIC_SetPriority(irq_type[inst], IRQ_PRIORITY_NORMAL); + } + NVIC_ClearPendingIRQ(irq_type[inst]); + NVIC_EnableIRQ(irq_type[inst]); +} + +/* Shutdown the DMA */ +static void hal_dma_close_inst(enum HAL_DMA_INST_T inst) +{ + NVIC_DisableIRQ(irq_type[inst]); + dma[inst]->DMACONFIG = 0; +} + +static bool hal_dma_chan_busy_inst(enum HAL_DMA_INST_T inst, uint8_t hwch) +{ + return !!(dma[inst]->ENBLDCHNS & DMA_STAT_CHAN(hwch)); +} + +static void hal_dma_handle_chan_irq(enum HAL_DMA_INST_T inst, uint8_t hwch) +{ + uint32_t remains; + struct HAL_DMA_DESC_T *lli; + bool tcint, errint; + + /* Check counter terminal status */ + tcint = !!(dma[inst]->INTTCSTAT & DMA_STAT_CHAN(hwch)); + /* Check error terminal status */ + errint = !!(dma[inst]->INTERRSTAT & DMA_STAT_CHAN(hwch)); + + if (tcint || errint) { + if (tcint) { + /* Clear terminate counter Interrupt pending */ + dma[inst]->INTTCCLR = DMA_STAT_CHAN(hwch); + } + if (errint) { + /* Clear error counter Interrupt pending */ + dma[inst]->INTERRCLR = DMA_STAT_CHAN(hwch); + } + + if (handler[inst][hwch]) { + remains = GET_BITFIELD(dma[inst]->CH[hwch].CONTROL, DMA_CONTROL_TRANSFERSIZE); + lli = (struct HAL_DMA_DESC_T *)dma[inst]->CH[hwch].LLI; + handler[inst][hwch](generate_chan(inst, hwch), remains, errint, lli); + } + } +} + +static void hal_dma_irq_handler(enum HAL_DMA_INST_T inst) +{ + uint8_t hwch; + + for (hwch = 0; hwch < DMA_NUMBER_CHANNELS; hwch++) { + if ((dma[inst]->INTSTAT & DMA_STAT_CHAN(hwch)) == 0) { + continue; + } + hal_dma_handle_chan_irq(inst, hwch); + } +} + +static void hal_audma_irq_handler(void) +{ + hal_dma_irq_handler(HAL_DMA_INST_AUDMA); +} + +#if (CHIP_HAS_DMA > 1) +static void hal_gpdma_irq_handler(void) +{ + hal_dma_irq_handler(HAL_DMA_INST_GPDMA); +} +#endif + +static enum HAL_DMA_RET_T hal_dma_init_control(uint32_t *ctrl, + const struct HAL_DMA_CH_CFG_T *cfg, + int tc_irq) +{ + uint32_t addr_inc; + enum HAL_DMA_FLOW_CONTROL_T type; + + if (cfg->src_tsize > HAL_DMA_MAX_DESC_XFER_SIZE) { + return HAL_DMA_ERR; + } + +#ifdef CHIP_BEST1000 + type = cfg->type; +#else + type = cfg->type & ~HAL_DMA_FLOW_FLAG_MASK; +#endif + + switch (type) { + case HAL_DMA_FLOW_M2M_DMA: + addr_inc = DMA_CONTROL_SI | DMA_CONTROL_DI; + break; + case HAL_DMA_FLOW_M2P_DMA: + case HAL_DMA_FLOW_M2P_PERIPH: + addr_inc = DMA_CONTROL_SI; + break; + case HAL_DMA_FLOW_P2M_DMA: + case HAL_DMA_FLOW_P2M_PERIPH: + addr_inc = DMA_CONTROL_DI; + break; + case HAL_DMA_FLOW_P2P_DMA: + case HAL_DMA_FLOW_P2P_DSTPERIPH: + case HAL_DMA_FLOW_P2P_SRCPERIPH: + addr_inc = 0; + break; + default: + return HAL_DMA_ERR; + } + +#ifndef CHIP_BEST1000 + if (cfg->type & HAL_DMA_FLOW_FLAG_SI) { + addr_inc |= DMA_CONTROL_SI; + } + if (cfg->type & HAL_DMA_FLOW_FLAG_DI) { + addr_inc |= DMA_CONTROL_DI; + } +#endif + + *ctrl = DMA_CONTROL_TRANSFERSIZE(cfg->src_tsize) | + DMA_CONTROL_SBSIZE(cfg->src_bsize) | + DMA_CONTROL_DBSIZE(cfg->dst_bsize) | + DMA_CONTROL_SWIDTH(cfg->src_width) | + DMA_CONTROL_DWIDTH(cfg->dst_width) | + (tc_irq ? DMA_CONTROL_TC_IRQ : 0) | + addr_inc; + + return HAL_DMA_OK; +} + +/***************************************************************************** + * Generic Public functions + ****************************************************************************/ + +enum HAL_DMA_RET_T hal_dma_init_desc(struct HAL_DMA_DESC_T *desc, + const struct HAL_DMA_CH_CFG_T *cfg, + const struct HAL_DMA_DESC_T *next, + int tc_irq) +{ + uint32_t ctrl; + enum HAL_DMA_RET_T ret; + enum HAL_DMA_FLOW_CONTROL_T type; + + ret = hal_dma_init_control(&ctrl, cfg, tc_irq); + if (ret != HAL_DMA_OK) { + return ret; + } + +#ifdef CHIP_BEST1000 + type = cfg->type; +#else + type = cfg->type & ~HAL_DMA_FLOW_FLAG_MASK; +#endif + + if (type == HAL_DMA_FLOW_M2M_DMA || type == HAL_DMA_FLOW_M2P_DMA || + type == HAL_DMA_FLOW_M2P_PERIPH) { + desc->src = cfg->src; + } else { + desc->src = hal_dma_get_periph_addr(cfg->src_periph); + } + if (type == HAL_DMA_FLOW_M2M_DMA || type == HAL_DMA_FLOW_P2M_DMA || + type == HAL_DMA_FLOW_P2M_PERIPH) { + desc->dst = cfg->dst; + } else { + desc->dst = hal_dma_get_periph_addr(cfg->dst_periph); + } + desc->lli = (uint32_t)next; + desc->ctrl = ctrl; + + return HAL_DMA_OK; +} + +enum HAL_DMA_RET_T hal_dma_sg_2d_start(const struct HAL_DMA_DESC_T *desc, + const struct HAL_DMA_CH_CFG_T *cfg, + const struct HAL_DMA_2D_CFG_T *src_2d, + const struct HAL_DMA_2D_CFG_T *dst_2d) +{ + enum HAL_DMA_INST_T inst; + uint8_t hwch; + enum HAL_DMA_FLOW_CONTROL_T type; + uint8_t src_periph, dst_periph; + enum HAL_DMA_INST_T periph_inst; + int ret; + uint32_t irq_mask, try_burst; + uint32_t lock; + + inst = get_inst_from_chan(cfg->ch); + hwch = get_hwch_from_chan(cfg->ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + +#ifdef CHIP_BEST1000 + type = cfg->type; +#else + type = cfg->type & ~HAL_DMA_FLOW_FLAG_MASK; +#endif + + if (type == HAL_DMA_FLOW_M2M_DMA || type == HAL_DMA_FLOW_M2P_DMA || + type == HAL_DMA_FLOW_M2P_PERIPH) { + src_periph = 0; + } else { + ret = get_index_from_periph(cfg->src_periph, &periph_inst, &src_periph); + ASSERT(ret == 0, "Failed to get src periph: %d", cfg->src_periph); +#ifdef DMA_REMAP + if (periph_remap_bitmap[periph_inst] & (1 << src_periph)) { + periph_inst ^= 1; + ret = get_remap_index_from_periph(periph_inst, cfg->src_periph, &src_periph); + ASSERT(ret == 0, "Failed to get remap src periph: %d", cfg->src_periph); + } +#endif + ASSERT(inst == periph_inst, "Mismatch inst in chan=0x%02x and src periph %d", cfg->ch, cfg->src_periph); + } + if (type == HAL_DMA_FLOW_M2M_DMA || type == HAL_DMA_FLOW_P2M_DMA || + type == HAL_DMA_FLOW_P2M_PERIPH) { + dst_periph = 0; + } else { + ret = get_index_from_periph(cfg->dst_periph, &periph_inst, &dst_periph); + ASSERT(ret == 0, "Failed to get dst periph: %d", cfg->dst_periph); +#ifdef DMA_REMAP + if (periph_remap_bitmap[periph_inst] & (1 << dst_periph)) { + periph_inst ^= 1; + ret = get_remap_index_from_periph(periph_inst, cfg->dst_periph, &dst_periph); + ASSERT(ret == 0, "Failed to get remap dst periph: %d", cfg->dst_periph); + } +#endif + ASSERT(inst == periph_inst, "Mismatch inst in chan=0x%02x and dst periph %d", cfg->ch, cfg->dst_periph); + } + + if (!chan_enabled[inst][hwch]) { + // Not acquired + return HAL_DMA_ERR; + } + if (hal_dma_chan_busy_inst(inst, hwch)) { + // Busy + return HAL_DMA_ERR; + } + + if (cfg->handler == NULL) { + irq_mask = 0; + } else { + irq_mask = DMA_CONFIG_ERR_IRQMASK | DMA_CONFIG_TC_IRQMASK; + handler[inst][hwch] = cfg->handler; + } + + try_burst = cfg->try_burst ? DMA_CONFIG_TRY_BURST : 0; + + /* Reset the Interrupt status */ + dma[inst]->INTTCCLR = DMA_STAT_CHAN(hwch); + dma[inst]->INTERRCLR = DMA_STAT_CHAN(hwch); + + dma[inst]->CH[hwch].SRCADDR = desc->src; + dma[inst]->CH[hwch].DSTADDR = desc->dst; + dma[inst]->CH[hwch].LLI = desc->lli; + dma[inst]->CH[hwch].CONTROL = desc->ctrl; + dma[inst]->CH[hwch].CONFIG = DMA_CONFIG_SRCPERIPH(src_periph) | + DMA_CONFIG_DSTPERIPH(dst_periph) | + DMA_CONFIG_TRANSFERTYPE(type) | + irq_mask | + try_burst; + +#ifndef CHIP_BEST1000 + if (src_2d) { + dma[inst]->_2D[hwch].SRCX = DMA_2D_MODIFY(src_2d->xmodify) | DMA_2D_COUNT(src_2d->xcount); + dma[inst]->_2D[hwch].SRCY = DMA_2D_MODIFY(src_2d->ymodify) | DMA_2D_COUNT(src_2d->ycount); + dma[inst]->_2D[hwch].CTRL |= DMA_2D_CTRL_SRC_EN; + } else { + dma[inst]->_2D[hwch].CTRL &= ~DMA_2D_CTRL_SRC_EN; + } + if (dst_2d) { + dma[inst]->_2D[hwch].DSTX = DMA_2D_MODIFY(dst_2d->xmodify) | DMA_2D_COUNT(dst_2d->xcount); + dma[inst]->_2D[hwch].DSTY = DMA_2D_MODIFY(dst_2d->ymodify) | DMA_2D_COUNT(dst_2d->ycount); + dma[inst]->_2D[hwch].CTRL |= DMA_2D_CTRL_DST_EN; + } else { + dma[inst]->_2D[hwch].CTRL &= ~DMA_2D_CTRL_DST_EN; + } +#endif + + lock = int_lock(); + if (cfg->start_cb) { + cfg->start_cb(cfg->ch); + } + dma[inst]->CH[hwch].CONFIG |= DMA_CONFIG_EN; + int_unlock(lock); + + return HAL_DMA_OK; +} + +enum HAL_DMA_RET_T hal_dma_sg_start(const struct HAL_DMA_DESC_T *desc, + const struct HAL_DMA_CH_CFG_T *cfg) +{ + return hal_dma_sg_2d_start(desc, cfg, NULL, NULL); +} + +enum HAL_DMA_RET_T hal_dma_start(const struct HAL_DMA_CH_CFG_T *cfg) +{ + struct HAL_DMA_DESC_T desc; + enum HAL_DMA_RET_T ret; + + ret = hal_dma_init_desc(&desc, cfg, NULL, 1); + if (ret != HAL_DMA_OK) { + return ret; + } + + ret = hal_dma_sg_start(&desc, cfg); + if (ret != HAL_DMA_OK) { + return ret; + } + + return HAL_DMA_OK; +} + +uint32_t hal_dma_cancel(uint8_t ch) +{ + enum HAL_DMA_INST_T inst; + uint8_t hwch; + uint32_t remains; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + dma[inst]->CH[hwch].CONFIG &= ~DMA_CONFIG_EN; + dma[inst]->INTTCCLR = DMA_STAT_CHAN(hwch); + dma[inst]->INTERRCLR = DMA_STAT_CHAN(hwch); + + remains = GET_BITFIELD(dma[inst]->CH[hwch].CONTROL, DMA_CONTROL_TRANSFERSIZE); + + return remains; +} + +uint32_t hal_dma_stop(uint8_t ch) +{ + enum HAL_DMA_INST_T inst; + uint8_t hwch; + uint8_t retry = 0; + const uint8_t max_retry = 10; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + dma[inst]->CH[hwch].CONFIG |= DMA_CONFIG_HALT; +#if 1 + while ((dma[inst]->CH[hwch].CONFIG & DMA_CONFIG_ACTIVE) && (++retry < max_retry)) { + if (retry <= 3) { + hal_sys_timer_delay_us(10); + } else { + hal_dma_delay(1); + } + } +#else + while (dma[inst]->CH[hwch].CONFIG & DMA_CONFIG_ACTIVE); +#endif + return hal_dma_cancel(ch); +} + +uint8_t hal_dma_get_chan(enum HAL_DMA_PERIPH_T periph, enum HAL_DMA_GET_CHAN_T policy) +{ + enum HAL_DMA_INST_T inst; + int ret; + uint8_t i, hwch; + uint8_t got = HAL_DMA_CHAN_NONE; + uint32_t lock; + + ASSERT(policy == HAL_DMA_HIGH_PRIO || policy == HAL_DMA_LOW_PRIO || policy == HAL_DMA_LOW_PRIO_ONLY, + "Invalid DMA policy: %d", policy); + + if (periph == HAL_GPDMA_MEM) { + inst = HAL_DMA_INST_GPDMA; + } else if (periph == HAL_AUDMA_MEM) { + inst = HAL_DMA_INST_AUDMA; + } else { + ret = get_index_from_periph(periph, &inst, &i); + ASSERT(ret == 0, "Invalid DMA periph: %d", periph); +#ifdef DMA_REMAP + if (periph_remap_bitmap[inst] & (1 << i)) { + inst ^= 1; + } +#endif + } + + lock = int_lock(); + for (i = 0; i < DMA_NUMBER_CHANNELS; i++) { + if (policy == HAL_DMA_HIGH_PRIO) { + hwch = i; + } else if (policy == HAL_DMA_LOW_PRIO) { + hwch = DMA_NUMBER_CHANNELS - 1 - i; + } else { + hwch = DMA_NUMBER_CHANNELS - 1 - i; + if (hwch < 6) { + break; + } + } + + if (!chan_enabled[inst][hwch] && !hal_dma_chan_busy_inst(inst, hwch)) { + chan_enabled[inst][hwch] = true; + got = generate_chan(inst, hwch); + dma[inst]->DMACONFIG |= DMA_DMACONFIG_CLK_EN(1 << hwch); + break; + } + } + int_unlock(lock); + + return got; +} + +void hal_dma_free_chan(uint8_t ch) +{ + enum HAL_DMA_INST_T inst; + uint8_t hwch; + uint32_t lock; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + ASSERT(chan_enabled[inst][hwch], "DMA chan not enabled: inst=%u hwch=%u", inst, hwch); + + hal_dma_cancel(ch); + + lock = int_lock(); + chan_enabled[inst][hwch] = false; + dma[inst]->DMACONFIG &= ~DMA_DMACONFIG_CLK_EN(1 << hwch); + int_unlock(lock); +} + +uint32_t hal_dma_get_cur_src_addr(uint8_t ch) +{ + enum HAL_DMA_INST_T inst; + uint8_t hwch; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + return dma[inst]->CH[hwch].SRCADDR; +} + +uint32_t hal_dma_get_cur_dst_addr(uint8_t ch) +{ + enum HAL_DMA_INST_T inst; + uint8_t hwch; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + return dma[inst]->CH[hwch].DSTADDR; +} + +void SRAM_TEXT_LOC hal_dma_get_cur_src_remain_and_addr(uint8_t ch, uint32_t *remain, uint32_t *src) +{ + enum HAL_DMA_INST_T inst; + uint8_t hwch; + uint32_t lock; + uint32_t size[2]; + uint32_t srcaddr[2]; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + lock = int_lock(); + size[0] = dma[inst]->CH[hwch].CONTROL; + srcaddr[0] = dma[inst]->CH[hwch].SRCADDR; + size[1] = dma[inst]->CH[hwch].CONTROL; + srcaddr[1] = dma[inst]->CH[hwch].SRCADDR; + int_unlock(lock); + + size[0] = GET_BITFIELD(size[0], DMA_CONTROL_TRANSFERSIZE); + size[1] = GET_BITFIELD(size[1], DMA_CONTROL_TRANSFERSIZE); + + if (size[0] == size[1]) { + *remain = size[0]; + *src = srcaddr[0]; + } else { + *remain = size[1]; + *src = srcaddr[1]; + } + + return; +} + +enum HAL_DMA_RET_T hal_dma_irq_run_chan(uint8_t ch) +{ + enum HAL_DMA_INST_T inst; + uint8_t hwch; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + if ((dma[inst]->INTSTAT & DMA_STAT_CHAN(hwch)) == 0) { + return HAL_DMA_ERR; + } + + hal_dma_handle_chan_irq(inst, hwch); + + return HAL_DMA_OK; +} + +bool hal_dma_chan_busy(uint8_t ch) +{ + enum HAL_DMA_INST_T inst; + uint8_t hwch; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + return hal_dma_chan_busy_inst(inst, hwch); +} + +bool hal_dma_busy(void) +{ + enum HAL_DMA_INST_T inst; + int hwch; + + for (inst = HAL_DMA_INST_AUDMA; inst < HAL_DMA_INST_QTY; inst++) { + for (hwch = chan_start[inst]; hwch < chan_num[inst]; hwch++) { + if (hal_dma_chan_busy_inst(inst, hwch)) { + return true; + } + } + } + + return false; +} + +uint32_t hal_dma_get_sg_remain_size(uint8_t ch) +{ + enum HAL_DMA_INST_T inst; + uint8_t hwch; + uint32_t remains; + const struct HAL_DMA_DESC_T *desc, *first; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + remains = GET_BITFIELD(dma[inst]->CH[hwch].CONTROL, DMA_CONTROL_TRANSFERSIZE); + first = (const struct HAL_DMA_DESC_T *)dma[inst]->CH[hwch].LLI; + desc = first; + while (desc) { + remains += GET_BITFIELD(desc->ctrl, DMA_CONTROL_TRANSFERSIZE); + desc = (const struct HAL_DMA_DESC_T *)desc->lli; + if (desc == first) { + break; + } + } + + return remains; +} + +void hal_dma_tc_irq_enable(uint8_t ch) +{ +#if !(defined(CHIP_BEST1000) || defined(CHIP_BEST2000) || defined(CHIP_BEST3001) || defined(CHIP_BEST3005)) + enum HAL_DMA_INST_T inst; + uint8_t hwch; + uint32_t lock; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + lock = int_lock(); +#ifdef CHIP_BEST2300 + if (inst == HAL_DMA_INST_AUDMA) { + hal_cmu_dma_tc_irq_set_chan(hwch); + } +#else + dma[inst]->DMACONFIG |= DMA_DMACONFIG_TC_IRQ_EN(1 << hwch); +#endif + int_unlock(lock); +#endif +} + +void hal_dma_tc_irq_disable(uint8_t ch) +{ +#if !(defined(CHIP_BEST1000) || defined(CHIP_BEST2000) || defined(CHIP_BEST3001) || defined(CHIP_BEST3005)) + enum HAL_DMA_INST_T inst; + uint8_t hwch; + uint32_t lock; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + lock = int_lock(); +#ifdef CHIP_BEST2300 + if (inst == HAL_DMA_INST_AUDMA) { + hal_cmu_dma_tc_irq_clear_chan(hwch); + } +#else + dma[inst]->DMACONFIG &= ~DMA_DMACONFIG_TC_IRQ_EN(1 << hwch); +#endif + int_unlock(lock); +#endif +} + +void hal_dma_set_burst_addr_inc(uint8_t ch, const struct HAL_DMA_BURST_ADDR_INC_T *inc) +{ +#if !(defined(CHIP_BEST1000) || defined(CHIP_BEST2000) || defined(CHIP_BEST3001) || defined(CHIP_BEST3005)) + enum HAL_DMA_INST_T inst; + uint8_t hwch; + uint32_t lock; + + inst = get_inst_from_chan(ch); + hwch = get_hwch_from_chan(ch); + + ASSERT(inst < HAL_DMA_INST_QTY, err_invalid_inst, inst); + ASSERT(hwch < DMA_NUMBER_CHANNELS, err_invalid_chan[inst], hwch); + + lock = int_lock(); + if (inc && inc->src_inc_en) { + dma[inst]->CH[hwch].CONTROL |= DMA_CONTROL_BURST_SI; + dma[inst]->_2D[hwch].SRC_INC = SET_BITFIELD(dma[inst]->_2D[hwch].SRC_INC, DMA_BURST_SRC_INC_VAL, inc->src_inc_val); + } else { + dma[inst]->CH[hwch].CONTROL &= ~DMA_CONTROL_BURST_SI; + } + if (inc && inc->dst_inc_en) { + dma[inst]->CH[hwch].CONTROL |= DMA_CONTROL_BURST_DI; + dma[inst]->_2D[hwch].DST_INC = SET_BITFIELD(dma[inst]->_2D[hwch].DST_INC, DMA_BURST_DST_INC_VAL, inc->dst_inc_val); + } else { + dma[inst]->CH[hwch].CONTROL &= ~DMA_CONTROL_BURST_DI; + } + int_unlock(lock); +#endif +} + +void hal_dma_clear_burst_addr_inc(uint8_t ch) +{ + hal_dma_set_burst_addr_inc(ch, NULL); +} + +void hal_dma_set_desc_burst_addr_inc(struct HAL_DMA_DESC_T *desc, const struct HAL_DMA_BURST_ADDR_INC_T *inc) +{ +#if !(defined(CHIP_BEST1000) || defined(CHIP_BEST2000) || defined(CHIP_BEST3001) || defined(CHIP_BEST3005)) + if (inc && inc->src_inc_en) { + desc->ctrl |= DMA_CONTROL_BURST_SI; + } else { + desc->ctrl &= ~DMA_CONTROL_BURST_SI; + } + if (inc && inc->dst_inc_en) { + desc->ctrl |= DMA_CONTROL_BURST_DI; + } else { + desc->ctrl &= ~DMA_CONTROL_BURST_DI; + } +#endif +} + +void hal_dma_clear_desc_burst_addr_inc(struct HAL_DMA_DESC_T *desc) +{ + hal_dma_set_desc_burst_addr_inc(desc, NULL); +} + +#ifdef DMA_REMAP +void hal_dma_remap_periph(enum HAL_DMA_PERIPH_T periph, int enable) +{ + enum HAL_DMA_INST_T inst1, inst2; + uint8_t index1, index2; + int ret; + uint32_t lock; + + // Tag the periph + ret = get_index_from_periph(periph, &inst1, &index1); + ASSERT(ret == 0, "Invalid DMA periph for remap1: %d", periph); + + // Tag the peer periph + inst2 = inst1 ^ 1; + ret = get_remap_index_from_periph(inst2, periph, &index2); + ASSERT(ret == 0, "Invalid DMA periph for remap2: %d", periph); + + lock = int_lock(); + if (enable) { + periph_remap_bitmap[inst1] |= (1 << index1); + periph_remap_bitmap[inst2] |= (1 << index2); +#ifndef CHIP_BEST1000 + // For best2000, index1 == index2 + hal_cmu_dma_swap_enable(index1); +#endif + } else { + periph_remap_bitmap[inst1] &= ~(1 << index1); + periph_remap_bitmap[inst2] &= ~(1 << index2); +#ifndef CHIP_BEST1000 + hal_cmu_dma_swap_disable(index1); +#endif + } + int_unlock(lock); +} +#endif + +void hal_dma_open(void) +{ + enum HAL_DMA_INST_T inst; + + if (dma_opened) { + return; + } + + for (inst = 0; inst < HAL_DMA_INST_QTY; inst++) { + hal_dma_open_inst(inst); + } + +#ifdef DMA_REMAP +#ifdef CHIP_BEST1000 + if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_4) { + hal_dma_remap_periph(HAL_AUDMA_I2S0_RX, 1); + hal_dma_remap_periph(HAL_AUDMA_I2S0_TX, 1); + hal_dma_remap_periph(HAL_AUDMA_SPDIF0_RX, 1); + hal_dma_remap_periph(HAL_AUDMA_SPDIF0_TX, 1); + } +#endif +#endif + + dma_opened = true; +} + +void hal_dma_close(void) +{ + enum HAL_DMA_INST_T inst; + + if (!dma_opened) { + return; + } + + for (inst = 0; inst < HAL_DMA_INST_QTY; inst++) { + hal_dma_close_inst(inst); + } + + dma_opened = false; +} + +#ifdef CORE_SLEEP_POWER_DOWN +void hal_dma_sleep(void) +{ + enum HAL_DMA_INST_T inst; + + for (inst = 0; inst < HAL_DMA_INST_QTY; inst++) { + saved_dma_regs[inst] = dma[inst]->DMACONFIG; + } +} + +void hal_dma_wakeup(void) +{ + enum HAL_DMA_INST_T inst; + + for (inst = 0; inst < HAL_DMA_INST_QTY; inst++) { + dma[inst]->DMACONFIG = saved_dma_regs[inst]; + } +} +#endif + +HAL_DMA_DELAY_FUNC hal_dma_set_delay_func(HAL_DMA_DELAY_FUNC new_func) +{ + HAL_DMA_DELAY_FUNC old_func = dma_delay; + dma_delay = new_func; + return old_func; +} + diff --git a/platform/hal/hal_dma.h b/platform/hal/hal_dma.h new file mode 100644 index 0000000..e513e8c --- /dev/null +++ b/platform/hal/hal_dma.h @@ -0,0 +1,293 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_DMA_H__ +#define __HAL_DMA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "stdbool.h" + +#define HAL_DMA_CHAN_NONE 0xFF + +#define HAL_DMA_MAX_DESC_XFER_SIZE 0xFFF + +enum HAL_DMA_RET_T { + HAL_DMA_OK, + HAL_DMA_ERR, +}; + +enum HAL_DMA_GET_CHAN_T { + HAL_DMA_HIGH_PRIO, + HAL_DMA_LOW_PRIO, + HAL_DMA_LOW_PRIO_ONLY +}; + +// DMA Type of DMA controller +enum HAL_DMA_FLOW_CONTROL_T { + HAL_DMA_FLOW_M2M_DMA = 0, /* Memory to memory - DMA control */ + HAL_DMA_FLOW_M2P_DMA = 1, /* Memory to peripheral - DMA control */ + HAL_DMA_FLOW_P2M_DMA = 2, /* Peripheral to memory - DMA control */ + HAL_DMA_FLOW_P2P_DMA = 3, /* Source peripheral to destination peripheral - DMA control */ + HAL_DMA_FLOW_P2P_DSTPERIPH = 4, /* Source peripheral to destination peripheral - destination peripheral control */ + HAL_DMA_FLOW_M2P_PERIPH = 5, /* Memory to peripheral - peripheral control */ + HAL_DMA_FLOW_P2M_PERIPH = 6, /* Peripheral to memory - peripheral control */ + HAL_DMA_FLOW_P2P_SRCPERIPH = 7, /* Source peripheral to destination peripheral - source peripheral control */ + + HAL_DMA_FLOW_FLAG_SI = 0x40, + HAL_DMA_FLOW_FLAG_DI = 0x80, + HAL_DMA_FLOW_FLAG_MASK = (HAL_DMA_FLOW_FLAG_SI | HAL_DMA_FLOW_FLAG_DI), + + HAL_DMA_FLOW_M2P_DI_DMA = HAL_DMA_FLOW_M2P_DMA | HAL_DMA_FLOW_FLAG_DI, + HAL_DMA_FLOW_P2M_SI_DMA = HAL_DMA_FLOW_P2M_DMA | HAL_DMA_FLOW_FLAG_SI, + HAL_DMA_FLOW_P2P_DI_DMA = HAL_DMA_FLOW_P2P_DMA | HAL_DMA_FLOW_FLAG_DI, + HAL_DMA_FLOW_P2P_SI_DMA = HAL_DMA_FLOW_P2P_DMA | HAL_DMA_FLOW_FLAG_SI, +}; + +// DMA Burst size in Source and Destination definitions +enum HAL_DMA_BSIZE_T { + HAL_DMA_BSIZE_1 = 0, /* Burst size = 1 */ + HAL_DMA_BSIZE_4 = 1, /* Burst size = 4 */ + HAL_DMA_BSIZE_8 = 2, /* Burst size = 8 */ + HAL_DMA_BSIZE_16 = 3, /* Burst size = 16 */ + HAL_DMA_BSIZE_32 = 4, /* Burst size = 32 */ + HAL_DMA_BSIZE_64 = 5, /* Burst size = 64 */ + HAL_DMA_BSIZE_128 = 6, /* Burst size = 128 */ + HAL_DMA_BSIZE_256 = 7, /* Burst size = 256 */ +}; + +// Width in Source transfer width and Destination transfer width definitions +enum HAL_DMA_WDITH_T { + HAL_DMA_WIDTH_BYTE = 0, /* Width = 1 byte */ + HAL_DMA_WIDTH_HALFWORD = 1, /* Width = 2 bytes */ + HAL_DMA_WIDTH_WORD = 2, /* Width = 4 bytes */ +}; + +enum HAL_DMA_PERIPH_T { + HAL_DMA_PERIPH_NULL = 0, + HAL_GPDMA_MEM = 1, + HAL_AUDMA_MEM = 2, + + HAL_GPDMA_SDIO = 10, + HAL_GPDMA_SDMMC = 11, + HAL_GPDMA_I2C0_RX = 12, + HAL_GPDMA_I2C0_TX = 13, + HAL_GPDMA_SPI_RX = 14, + HAL_GPDMA_SPI_TX = 15, + HAL_GPDMA_SPILCD_RX = 16, + HAL_GPDMA_SPILCD_TX = 17, + HAL_GPDMA_UART0_RX = 18, + HAL_GPDMA_UART0_TX = 19, + HAL_GPDMA_UART1_RX = 20, + HAL_GPDMA_UART1_TX = 21, + HAL_GPDMA_ISPI_RX = 22, + HAL_GPDMA_ISPI_TX = 23, + HAL_GPDMA_UART2_RX = 24, + HAL_GPDMA_UART2_TX = 25, + HAL_GPDMA_FLASH_RX = 26, + HAL_GPDMA_FLASH_TX = 27, + HAL_GPDMA_I2C1_RX = 28, + HAL_GPDMA_I2C1_TX = 29, + HAL_GPDMA_I2C2_RX = 30, + HAL_GPDMA_I2C2_TX = 31, + HAL_GPDMA_I2C3_RX = 32, + HAL_GPDMA_I2C3_TX = 33, + + HAL_AUDMA_CODEC_RX = 50, + HAL_AUDMA_CODEC_TX = 51, + HAL_AUDMA_BTPCM_RX = 52, + HAL_AUDMA_BTPCM_TX = 53, + HAL_AUDMA_I2S0_RX = 54, + HAL_AUDMA_I2S0_TX = 55, + HAL_AUDMA_DPD_RX = 56, + HAL_AUDMA_DPD_TX = 57, + HAL_AUDMA_SPDIF0_RX = 58, + HAL_AUDMA_SPDIF0_TX = 59, + HAL_AUDMA_SPDIF1_RX = 60, + HAL_AUDMA_SPDIF1_TX = 61, + HAL_AUDMA_DSD_RX = 62, + HAL_AUDMA_DSD_TX = 63, + HAL_AUDMA_MC_RX = 64, + HAL_AUDMA_FFT_RX = 65, + HAL_AUDMA_FFT_TX = 66, + HAL_AUDMA_FIR_RX = 67, + HAL_AUDMA_FIR_TX = 68, + HAL_AUDMA_IIR_RX = 69, + HAL_AUDMA_IIR_TX = 70, + HAL_AUDMA_BTDUMP = 71, + HAL_AUDMA_I2S1_RX = 72, + HAL_AUDMA_I2S1_TX = 73, + HAL_AUDMA_FM_RX = 74, + HAL_AUDMA_FMDUMP0 = 75, + HAL_AUDMA_FMDUMP1 = 76, + HAL_AUDMA_CODEC_TX2 = 77, + + HAL_DMA_PERIPH_QTY, +}; + +struct HAL_DMA_DESC_T; + +typedef void (*HAL_DMA_IRQ_HANDLER_T)(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli); + +typedef void (*HAL_DMA_START_CALLBACK_T)(uint8_t chan); + +typedef void (*HAL_DMA_DELAY_FUNC)(uint32_t ms); + +// DMA structure using for DMA configuration +struct HAL_DMA_CH_CFG_T { + uint8_t ch; /* DMA channel number */ + uint8_t try_burst; + uint16_t src_tsize; /* Length/Size of transfer */ + enum HAL_DMA_WDITH_T src_width; + enum HAL_DMA_WDITH_T dst_width; + enum HAL_DMA_BSIZE_T src_bsize; + enum HAL_DMA_BSIZE_T dst_bsize; + enum HAL_DMA_FLOW_CONTROL_T type; /* Transfer Type */ + enum HAL_DMA_PERIPH_T src_periph; + enum HAL_DMA_PERIPH_T dst_periph; + uint32_t src; /* Physical Source Address */ + uint32_t dst; /* Physical Destination Address */ + HAL_DMA_IRQ_HANDLER_T handler; + HAL_DMA_START_CALLBACK_T start_cb; +}; + +// Transfer Descriptor structure typedef +struct HAL_DMA_DESC_T { + uint32_t src; /* Source address */ + uint32_t dst; /* Destination address */ + uint32_t lli; /* Pointer to next descriptor structure */ + uint32_t ctrl; /* Control word that has transfer size, type etc. */ +}; + +// DMA 2D configuration structure +struct HAL_DMA_2D_CFG_T { + int16_t xmodify; + uint16_t xcount; + int16_t ymodify; + uint16_t ycount; +}; + +struct HAL_DMA_BURST_ADDR_INC_T { + bool src_inc_en; + bool dst_inc_en; + int16_t src_inc_val; + int16_t dst_inc_val; +}; + +//============================================================= + +void hal_dma_open(void); + +void hal_dma_close(void); + +void hal_dma_sleep(void); + +void hal_dma_wakeup(void); + +bool hal_dma_chan_busy(uint8_t ch); + +uint8_t hal_dma_get_chan(enum HAL_DMA_PERIPH_T periph, enum HAL_DMA_GET_CHAN_T policy); + +void hal_dma_free_chan(uint8_t ch); + +uint32_t hal_dma_cancel(uint8_t ch); + +uint32_t hal_dma_stop(uint8_t ch); + +enum HAL_DMA_RET_T hal_dma_init_desc(struct HAL_DMA_DESC_T *desc, + const struct HAL_DMA_CH_CFG_T *cfg, + const struct HAL_DMA_DESC_T *next, + int tc_irq); + +enum HAL_DMA_RET_T hal_dma_sg_start(const struct HAL_DMA_DESC_T *desc, + const struct HAL_DMA_CH_CFG_T *cfg); + +enum HAL_DMA_RET_T hal_dma_sg_2d_start(const struct HAL_DMA_DESC_T *desc, + const struct HAL_DMA_CH_CFG_T *cfg, + const struct HAL_DMA_2D_CFG_T *src_2d, + const struct HAL_DMA_2D_CFG_T *dst_2d); + +enum HAL_DMA_RET_T hal_dma_start(const struct HAL_DMA_CH_CFG_T *cfg); + +uint32_t hal_dma_get_cur_src_addr(uint8_t ch); + +uint32_t hal_dma_get_cur_dst_addr(uint8_t ch); + +void hal_dma_get_cur_src_remain_and_addr(uint8_t ch, uint32_t *remain, uint32_t *src); + +uint32_t hal_dma_get_sg_remain_size(uint8_t ch); + +enum HAL_DMA_RET_T hal_dma_irq_run_chan(uint8_t ch); + +bool hal_dma_busy(void); + +HAL_DMA_DELAY_FUNC hal_dma_set_delay_func(HAL_DMA_DELAY_FUNC new_func); + +void hal_dma_remap_periph(enum HAL_DMA_PERIPH_T periph, int enable); + +void hal_dma_tc_irq_enable(uint8_t ch); + +void hal_dma_tc_irq_disable(uint8_t ch); + +void hal_dma_set_burst_addr_inc(uint8_t ch, const struct HAL_DMA_BURST_ADDR_INC_T *inc); + +void hal_dma_clear_burst_addr_inc(uint8_t ch); + +void hal_dma_set_desc_burst_addr_inc(struct HAL_DMA_DESC_T *desc, const struct HAL_DMA_BURST_ADDR_INC_T *inc); + +void hal_dma_clear_desc_burst_addr_inc(struct HAL_DMA_DESC_T *desc); + +//============================================================= + +#define hal_audma_open hal_dma_open +#define hal_audma_close hal_dma_close +#define hal_audma_chan_busy hal_dma_chan_busy +#define hal_audma_get_chan hal_dma_get_chan +#define hal_audma_free_chan hal_dma_free_chan +#define hal_audma_cancel hal_dma_cancel +#define hal_audma_stop hal_dma_stop +#define hal_audma_init_desc hal_dma_init_desc +#define hal_audma_sg_start hal_dma_sg_start +#define hal_audma_start hal_dma_start +#define hal_audma_get_cur_src_addr hal_dma_get_cur_src_addr +#define hal_audma_get_cur_dst_addr hal_dma_get_cur_dst_addr +#define hal_audma_get_sg_remain_size hal_dma_get_sg_remain_size +#define hal_audma_irq_run_chan hal_dma_irq_run_chan + +#define hal_gpdma_open hal_dma_open +#define hal_gpdma_close hal_dma_close +#define hal_gpdma_chan_busy hal_dma_chan_busy +#define hal_gpdma_get_chan hal_dma_get_chan +#define hal_gpdma_free_chan hal_dma_free_chan +#define hal_gpdma_cancel hal_dma_cancel +#define hal_gpdma_stop hal_dma_stop +#define hal_gpdma_init_desc hal_dma_init_desc +#define hal_gpdma_sg_start hal_dma_sg_start +#define hal_gpdma_start hal_dma_start +#define hal_gpdma_get_cur_src_addr hal_dma_get_cur_src_addr +#define hal_gpdma_get_cur_dst_addr hal_dma_get_cur_dst_addr +#define hal_gpdma_get_sg_remain_size hal_dma_get_sg_remain_size +#define hal_gpdma_irq_run_chan hal_dma_irq_run_chan + +//============================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_gpadc.c b/platform/hal/hal_gpadc.c new file mode 100644 index 0000000..7149498 --- /dev/null +++ b/platform/hal/hal_gpadc.c @@ -0,0 +1,791 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" + +#ifndef GPADC_CHIP_SPECIFIC + +#include "stddef.h" +#include "cmsis_nvic.h" +#include "hal_gpadc.h" +#include "hal_trace.h" +#include "hal_analogif.h" +#include "pmu.h" + +#define HAL_GPADC_TRACE(n, s, ...) //TRACE(n, s, ##__VA_ARGS__) + +#define VBAT_DIV_ALWAYS_ON + +#define gpadc_reg_read(reg,val) pmu_read(reg,val) +#define gpadc_reg_write(reg,val) pmu_write(reg,val) + +// Battery voltage = gpadc voltage * 4 +// adc rate 0~2v(10bit) +// Battery_voltage:Adc_rate = 4:1 +#define HAL_GPADC_MVOLT_A 800 +#define HAL_GPADC_MVOLT_B 1050 +#define HAL_GPADC_CALIB_DEFAULT_A 428 +#define HAL_GPADC_CALIB_DEFAULT_B 565 + +#if 0 +#elif defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || \ + defined(CHIP_BEST2000) || defined(CHIP_BEST2001) || \ + defined(CHIP_BEST2300) || defined(CHIP_BEST2300A) || defined(CHIP_BEST2300P) || \ + defined(CHIP_BEST3001) || defined(CHIP_BEST3005) + +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST2001) + +enum GPADC_REG_T { + GPADC_REG_VBAT_EN = 0x02, + GPADC_REG_INTVL_EN = 0x18, + GPADC_REG_INTVL_VAL = 0x1C, + GPADC_REG_START = 0x4F, + GPADC_REG_CH_EN = 0x1D, + GPADC_REG_INT_MASK = 0x1F, + GPADC_REG_INT_EN = 0x20, + GPADC_REG_INT_RAW_STS = 0x50, + GPADC_REG_INT_MSKED_STS = 0x51, + GPADC_REG_INT_CLR = 0x51, + GPADC_REG_CH0_DATA = 0x56, +}; + +#else + +enum GPADC_REG_T { + GPADC_REG_VBAT_EN = 0x02, + GPADC_REG_INTVL_EN = 0x1F, + GPADC_REG_INTVL_VAL = 0x23, + GPADC_REG_START = 0x4F, + GPADC_REG_CH_EN = 0x24, + GPADC_REG_INT_MASK = 0x26, + GPADC_REG_INT_EN = 0x27, +#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) + GPADC_REG_INT_RAW_STS = 0x52, + GPADC_REG_INT_MSKED_STS = 0x53, + GPADC_REG_INT_CLR = 0x51, +#else + GPADC_REG_INT_RAW_STS = 0x50, + GPADC_REG_INT_MSKED_STS = 0x51, + GPADC_REG_INT_CLR = 0x51, +#endif + GPADC_REG_CH0_DATA = 0x56, +}; + +#endif + +// GPADC_REG_VBAT_EN +#define REG_PU_VBAT_DIV (1 << 15) + +// GPADC_REG_INTVL_EN +#define GPADC_INTERVAL_MODE (1 << 12) + +// GPADC_REG_START +#define GPADC_START (1 << 5) +#define KEY_START (1 << 4) + +// GPADC_REG_CH_EN +#define CHAN_EN_REG_SHIFT 0 +#define CHAN_EN_REG_MASK (0xFF << CHAN_EN_REG_SHIFT) +#define CHAN_EN_REG(n) BITFIELD_VAL(CHAN_EN_REG, n) + +// GPADC_REG_INT_MASK +#define KEY_ERR1_INTR_MSK (1 << 12) +#define KEY_ERR0_INTR_MSK (1 << 11) +#define KEY_PRESS_INTR_MSK (1 << 10) +#define KEY_RELEASE_INTR_MSK (1 << 9) +#define SAMPLE_DONE_INTR_MSK (1 << 8) +#define CHAN_DATA_INTR_MSK_SHIFT 0 +#define CHAN_DATA_INTR_MSK_MASK (0xFF << CHAN_DATA_INTR_MSK_SHIFT) +#define CHAN_DATA_INTR_MSK(n) BITFIELD_VAL(CHAN_DATA_INTR_MSK, n) + +// GPADC_REG_INT_EN +#define KEY_ERR1_INTR_EN (1 << 12) +#define KEY_ERR0_INTR_EN (1 << 11) +#define KEY_PRESS_INTR_EN (1 << 10) +#define KEY_RELEASE_INTR_EN (1 << 9) +#define SAMPLE_DONE_INTR_EN (1 << 8) +#define CHAN_DATA_INTR_EN_SHIFT 0 +#define CHAN_DATA_INTR_EN_MASK (0xFF << CHAN_DATA_INTR_EN_SHIFT) +#define CHAN_DATA_INTR_EN(n) BITFIELD_VAL(CHAN_DATA_INTR_EN, n) + +// GPADC_REG_INT_RAW_STS +#define KEY_ERR1_INTR (1 << 12) +#define KEY_ERR0_INTR (1 << 11) +#define KEY_PRESS_INTR (1 << 10) +#define KEY_RELEASE_INTR (1 << 9) +#define SAMPLE_PERIOD_DONE_INTR (1 << 8) +#define CHAN_DATA_VALID_INTR_SHIFT 0 +#define CHAN_DATA_VALID_INTR_MASK (0xFF << CHAN_DATA_VALID_INTR_SHIFT) +#define CHAN_DATA_VALID_INTR(n) BITFIELD_VAL(CHAN_DATA_VALID_INTR, n) + +// GPADC_REG_INT_MSKED_STS +#define KEY_ERR1_INTR_MSKED (1 << 12) +#define KEY_ERR0_INTR_MSKED (1 << 11) +#define KEY_PRESS_INTR_MSKED (1 << 10) +#define KEY_RELEASE_INTR_MSKED (1 << 9) +#define SAMPLE_DONE_INTR_MSKED (1 << 8) +#define CHAN_DATA_INTR_MSKED_SHIFT 0 +#define CHAN_DATA_INTR_MSKED_MASK (0xFF << CHAN_DATA_INTR_MSKED_SHIFT) +#define CHAN_DATA_INTR_MSKED(n) BITFIELD_VAL(CHAN_DATA_INTR_MSKED, n) + +// GPADC_REG_INT_CLR +#define KEY_ERR1_INTR_CLR (1 << 12) +#define KEY_ERR0_INTR_CLR (1 << 11) +#define KEY_PRESS_INTR_CLR (1 << 10) +#define KEY_RELEASE_INTR_CLR (1 << 9) +#define SAMPLE_DONE_INTR_CLR (1 << 8) +#define CHAN_DATA_INTR_CLR_SHIFT 0 +#define CHAN_DATA_INTR_CLR_MASK (0xFF << CHAN_DATA_INTR_CLR_SHIFT) +#define CHAN_DATA_INTR_CLR(n) BITFIELD_VAL(CHAN_DATA_INTR_CLR, n) + +// GPADC_REG_CH0_DATA +#define DATA_CHAN0_SHIFT 0 +#define DATA_CHAN0_MASK (0x3FF << DATA_CHAN0_SHIFT) +#define DATA_CHAN0(n) BITFIELD_VAL(DATA_CHAN0, n) + +#elif defined(CHIP_BEST1000) + +enum GPADC_REG_T { + GPADC_REG_VBAT_EN = 0x45, + GPADC_REG_INTVL_EN = 0x60, + GPADC_REG_INTVL_VAL = 0x64, + GPADC_REG_START = 0x65, + GPADC_REG_CH_EN = 0x65, + GPADC_REG_INT_MASK = 0x67, + GPADC_REG_INT_EN = 0x68, + GPADC_REG_INT_RAW_STS = 0x69, + GPADC_REG_INT_MSKED_STS = 0x6A, + GPADC_REG_INT_CLR = 0x6A, + GPADC_REG_CH0_DATA = 0x78, +}; + +// GPADC_REG_VBAT_EN +#define REG_PU_VBAT_DIV (1 << 0) + +// GPADC_REG_INTVL_EN +#define GPADC_INTERVAL_MODE (1 << 12) + +// GPADC_REG_START +#define KEY_START (1 << 9) +#define GPADC_START (1 << 8) + +// GPADC_REG_CH_EN +#define CHAN_EN_REG_SHIFT 0 +#define CHAN_EN_REG_MASK (0xFF << CHAN_EN_REG_SHIFT) +#define CHAN_EN_REG(n) BITFIELD_VAL(CHAN_EN_REG, n) + +// GPADC_REG_INT_MASK +#define KEY_ERR1_INTR_MSK (1 << 12) +#define KEY_ERR0_INTR_MSK (1 << 11) +#define KEY_PRESS_INTR_MSK (1 << 10) +#define KEY_RELEASE_INTR_MSK (1 << 9) +#define SAMPLE_DONE_INTR_MSK (1 << 8) +#define CHAN_DATA_INTR_MSK_SHIFT 0 +#define CHAN_DATA_INTR_MSK_MASK (0xFF << CHAN_DATA_INTR_MSK_SHIFT) +#define CHAN_DATA_INTR_MSK(n) BITFIELD_VAL(CHAN_DATA_INTR_MSK, n) + +// GPADC_REG_INT_EN +#define KEY_ERR1_INTR_EN (1 << 12) +#define KEY_ERR0_INTR_EN (1 << 11) +#define KEY_PRESS_INTR_EN (1 << 10) +#define KEY_RELEASE_INTR_EN (1 << 9) +#define SAMPLE_DONE_INTR_EN (1 << 8) +#define CHAN_DATA_INTR_EN_SHIFT 0 +#define CHAN_DATA_INTR_EN_MASK (0xFF << CHAN_DATA_INTR_EN_SHIFT) +#define CHAN_DATA_INTR_EN(n) BITFIELD_VAL(CHAN_DATA_INTR_EN, n) + +// GPADC_REG_INT_RAW_STS +#define KEY_ERR1_INTR (1 << 12) +#define KEY_ERR0_INTR (1 << 11) +#define KEY_PRESS_INTR (1 << 10) +#define KEY_RELEASE_INTR (1 << 9) +#define SAMPLE_PERIOD_DONE_INTR (1 << 8) +#define CHAN_DATA_VALID_INTR_SHIFT 0 +#define CHAN_DATA_VALID_INTR_MASK (0xFF << CHAN_DATA_VALID_INTR_SHIFT) +#define CHAN_DATA_VALID_INTR(n) BITFIELD_VAL(CHAN_DATA_VALID_INTR, n) + +// GPADC_REG_INT_MSKED_STS +#define KEY_ERR1_INTR_MSKED (1 << 12) +#define KEY_ERR0_INTR_MSKED (1 << 11) +#define KEY_PRESS_INTR_MSKED (1 << 10) +#define KEY_RELEASE_INTR_MSKED (1 << 9) +#define SAMPLE_DONE_INTR_MSKED (1 << 8) +#define CHAN_DATA_INTR_MSKED_SHIFT 0 +#define CHAN_DATA_INTR_MSKED_MASK (0xFF << CHAN_DATA_INTR_MSKED_SHIFT) +#define CHAN_DATA_INTR_MSKED(n) BITFIELD_VAL(CHAN_DATA_INTR_MSKED, n) + +// GPADC_REG_INT_CLR +#define KEY_ERR1_INTR_CLR (1 << 12) +#define KEY_ERR0_INTR_CLR (1 << 11) +#define KEY_PRESS_INTR_CLR (1 << 10) +#define KEY_RELEASE_INTR_CLR (1 << 9) +#define SAMPLE_DONE_INTR_CLR (1 << 8) +#define CHAN_DATA_INTR_CLR_SHIFT 0 +#define CHAN_DATA_INTR_CLR_MASK (0xFF << CHAN_DATA_INTR_CLR_SHIFT) +#define CHAN_DATA_INTR_CLR(n) BITFIELD_VAL(CHAN_DATA_INTR_CLR, n) + +// GPADC_REG_CH0_DATA +#define DATA_CHAN0_SHIFT 0 +#define DATA_CHAN0_MASK (0x3FF << DATA_CHAN0_SHIFT) +#define DATA_CHAN0(n) BITFIELD_VAL(DATA_CHAN0, n) + +#else +#error "Please update GPADC register definitions" +#endif + +static int32_t g_adcSlope = 0; +static int32_t g_adcIntcpt = 0; +static bool gpadc_enabled = false; +static bool adckey_enabled = false; +static bool irq_enabled = false; +static bool g_adcCalibrated = false; +static HAL_GPADC_EVENT_CB_T gpadc_event_cb[HAL_GPADC_CHAN_QTY]; +static enum HAL_GPADC_ATP_T gpadc_atp[HAL_GPADC_CHAN_QTY]; + +static enum HAL_GPADC_ATP_T hal_gpadc_get_min_atp(void) +{ + enum HAL_GPADC_CHAN_T ch; + enum HAL_GPADC_ATP_T atp = HAL_GPADC_ATP_NULL; + + for (ch = HAL_GPADC_CHAN_0; ch < HAL_GPADC_CHAN_QTY; ch++) { + if (gpadc_atp[ch] != HAL_GPADC_ATP_NULL) { + if (atp == HAL_GPADC_ATP_NULL || + (uint32_t)gpadc_atp[ch] < (uint32_t)atp) { + atp = gpadc_atp[ch]; + } + } + } + + return atp; +} + +static void hal_gpadc_update_atp(void) +{ + enum HAL_GPADC_ATP_T atp; + uint16_t val; + + atp = hal_gpadc_get_min_atp(); + + if (atp == HAL_GPADC_ATP_NULL || atp == HAL_GPADC_ATP_ONESHOT) { + gpadc_reg_read(GPADC_REG_INTVL_EN, &val); + val &= ~GPADC_INTERVAL_MODE; + gpadc_reg_write(GPADC_REG_INTVL_EN, val); + } else { + gpadc_reg_read(GPADC_REG_INTVL_EN, &val); + val |= GPADC_INTERVAL_MODE; + gpadc_reg_write(GPADC_REG_INTVL_EN, val); + val = atp * 1000 / 1024; + gpadc_reg_write(GPADC_REG_INTVL_VAL, val); + } +} + +static int hal_gpadc_adc2volt_calib(void) +{ + int32_t y1, y2, x1, x2; + unsigned short efuse_a = 0; + unsigned short efuse_b = 0; + + if (!g_adcCalibrated) + { + y1 = HAL_GPADC_MVOLT_A*1000; + y2 = HAL_GPADC_MVOLT_B*1000; + + pmu_get_efuse(PMU_EFUSE_PAGE_BATTER_LV, &efuse_a); + + x1 = efuse_a > 0 ? efuse_a : HAL_GPADC_CALIB_DEFAULT_A; + + pmu_get_efuse(PMU_EFUSE_PAGE_BATTER_HV, &efuse_b); + x2 = efuse_b > 0 ? efuse_b : HAL_GPADC_CALIB_DEFAULT_B; + + g_adcSlope = (y2-y1)/(x2-x1); + g_adcIntcpt = ((y1*x2)-(x1*y2))/((x2-x1)*1000); + g_adcCalibrated = true; + + TRACE(7,"%s efuse:%d/%d LV=%d, HV=%d, Slope:%d Intcpt:%d",__func__, efuse_a, efuse_b, x1, x2, g_adcSlope, g_adcIntcpt); + } + + return 0; +} + +static HAL_GPADC_MV_T hal_gpadc_adc2volt(uint16_t gpadcVal) +{ + int32_t voltage; + + hal_gpadc_adc2volt_calib(); + if (gpadcVal == HAL_GPADC_BAD_VALUE) + { + // Bad values from the GPADC are still Bad Values + // for the voltage-speaking user. + return HAL_GPADC_BAD_VALUE; + } + else + { + voltage = (((g_adcSlope*gpadcVal)/1000) + (g_adcIntcpt)); + + return (voltage < 0) ? 0 : voltage; + } +} + +#ifdef PMU_IRQ_UNIFIED +#define GPADC_IRQ_HDLR_PARAM uint16_t irq_status +#else +#define GPADC_IRQ_HDLR_PARAM void +#endif +static void hal_gpadc_irq_handler(GPADC_IRQ_HDLR_PARAM) +{ + uint32_t lock; + enum HAL_GPADC_CHAN_T ch; + unsigned short read_val; + uint16_t adc_val; + HAL_GPADC_MV_T volt; + +#ifndef PMU_IRQ_UNIFIED + unsigned short irq_status; + + gpadc_reg_read(GPADC_REG_INT_MSKED_STS, &irq_status); + irq_status &= (CHAN_DATA_INTR_MSKED_MASK|SAMPLE_DONE_INTR_MSKED| + KEY_RELEASE_INTR_MSKED|KEY_PRESS_INTR_MSKED| + KEY_ERR0_INTR_MSKED|KEY_ERR1_INTR_MSKED); + gpadc_reg_write(GPADC_REG_INT_CLR, irq_status); +#endif + + if (irq_status & CHAN_DATA_INTR_MSKED((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6))) { + for (ch = HAL_GPADC_CHAN_0; ch < HAL_GPADC_CHAN_QTY; ch++) { + if (irq_status & CHAN_DATA_INTR_MSKED(1<= HAL_GPADC_CHAN_QTY) { + return res; + } + + gpadc_reg_read(GPADC_REG_INT_RAW_STS, &read_val); + + if (read_val & CHAN_DATA_VALID_INTR(1<= HAL_GPADC_CHAN_QTY) { + return -1; + } + + // NOTE: ADCKEY callback is not set here, but in hal_adckey_set_irq_handler() + if (channel != HAL_GPADC_CHAN_ADCKEY) { + gpadc_event_cb[channel] = cb; + gpadc_atp[channel] = atp; + } + + switch (channel) { + case HAL_GPADC_CHAN_BATTERY: + // Enable vbat measurement clock + // vbat div enable + lock = int_lock(); + gpadc_reg_read(GPADC_REG_VBAT_EN, &val); + val |= REG_PU_VBAT_DIV; + gpadc_reg_write(GPADC_REG_VBAT_EN, val); + int_unlock(lock); +#ifndef VBAT_DIV_ALWAYS_ON + // GPADC VBAT needs 10us to be stable and consumes 13mA current + hal_sys_timer_delay_us(20); +#endif + case HAL_GPADC_CHAN_0: + case HAL_GPADC_CHAN_2: + case HAL_GPADC_CHAN_3: + case HAL_GPADC_CHAN_4: + case HAL_GPADC_CHAN_5: + case HAL_GPADC_CHAN_6: + case HAL_GPADC_CHAN_ADCKEY: + lock = int_lock(); + +#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) + if (channel == HAL_GPADC_CHAN_3){ + pmu_led_set_hiz(HAL_GPIO_PIN_LED2); + } +#endif + + // Int mask + if (channel == HAL_GPADC_CHAN_ADCKEY || gpadc_event_cb[channel]) { + // 1) Always enable ADCKEY mask + // 2) Enable mask if handler is not null + gpadc_reg_read(GPADC_REG_INT_MASK, &val); + val |= CHAN_DATA_INTR_MSK(1<= HAL_GPADC_CHAN_QTY) { + return -1; + } + + if (channel != HAL_GPADC_CHAN_ADCKEY) { + gpadc_atp[channel] = HAL_GPADC_ATP_NULL; + } + + switch (channel) { + case HAL_GPADC_CHAN_BATTERY: +#ifndef VBAT_DIV_ALWAYS_ON + // disable vbat measurement clock + // vbat div disable + lock = int_lock(); + gpadc_reg_read(GPADC_REG_VBAT_EN, &val); + val &= ~REG_PU_VBAT_DIV; + gpadc_reg_write(GPADC_REG_VBAT_EN, val); + int_unlock(lock); +#endif + case HAL_GPADC_CHAN_0: + case HAL_GPADC_CHAN_2: + case HAL_GPADC_CHAN_3: + case HAL_GPADC_CHAN_4: + case HAL_GPADC_CHAN_5: + case HAL_GPADC_CHAN_6: + case HAL_GPADC_CHAN_ADCKEY: + lock = int_lock(); + + // Int mask + gpadc_reg_read(GPADC_REG_INT_MASK, &val); + val &= ~CHAN_DATA_INTR_MSK(1<= HAL_GPIO_PIN_P4_0) + { + bank = HAL_GPIO_AUX_PIN_TO_BANK(pin); + port = HAL_GPIO_AUX_PIN_TO_PORT(pin); + pin_offset = pin%HAL_GPIO_AUX_PIN_NUM_EACH_PORT; + + if (gpio_aux_bank[bank]->port[port].GPIO_DDR & (0x1<port[port].GPIO_DDR & (0x1<= HAL_GPIO_PIN_P4_0) + { + bank = HAL_GPIO_AUX_PIN_TO_BANK(pin); + port = HAL_GPIO_AUX_PIN_TO_PORT(pin); + pin_offset = pin%HAL_GPIO_AUX_PIN_NUM_EACH_PORT; + + if(dir == HAL_GPIO_DIR_OUT) + gpio_aux_bank[bank]->port[port].GPIO_DDR |= 0x1<port[port].GPIO_DDR &= ~(0x1<port[port].GPIO_DDR |= 0x1<port[port].GPIO_DDR &= ~(0x1<port[0].GPIO_DR |= 0x1<= HAL_GPIO_PIN_P4_0) + { + bank = HAL_GPIO_AUX_PIN_TO_BANK(pin); + port = HAL_GPIO_AUX_PIN_TO_PORT(pin); + pin_offset = pin%HAL_GPIO_AUX_PIN_NUM_EACH_PORT; + + gpio_aux_bank[bank]->port[port].GPIO_DR |= 0x1<port[port].GPIO_DR |= 0x1<port[0].GPIO_DR &= ~(0x1<= HAL_GPIO_PIN_P4_0) + { + bank = HAL_GPIO_AUX_PIN_TO_BANK(pin); + port = HAL_GPIO_AUX_PIN_TO_PORT(pin); + pin_offset = pin%HAL_GPIO_AUX_PIN_NUM_EACH_PORT; + + gpio_aux_bank[bank]->port[port].GPIO_DR &= ~(0x1<port[port].GPIO_DR &= ~(0x1<GPIO_EXT_PORT[0]) & (0x1<> pin_offset); +#else + return pmu_led_get_value(pin); +#endif + } +#endif +#ifdef GPIOAUX_BASE + else if (pin >= HAL_GPIO_PIN_P4_0) + { + bank = HAL_GPIO_AUX_PIN_TO_BANK(pin); + port = HAL_GPIO_AUX_PIN_TO_PORT(pin); + pin_offset = pin%HAL_GPIO_AUX_PIN_NUM_EACH_PORT; + + /* when as input : read back outside signal value */ + /* when as output: read back DR register value ,same as read back DR register */ + + return (((gpio_aux_bank[bank]->GPIO_EXT_PORT[port]) & (0x1<> pin_offset); + } +#endif + else + { + bank = HAL_GPIO_PIN_TO_BANK(pin); + port = HAL_GPIO_PIN_TO_PORT(pin); + pin_offset = pin%HAL_GPIO_PIN_NUM_EACH_PORT; + + /* when as input : read back outside signal value */ + /* when as output: read back DR register value ,same as read back DR register */ + + return (((gpio_bank[bank]->GPIO_EXT_PORT[port]) & (0x1<> pin_offset); + } +} + +void _hal_gpio_bank0_irq_handler(void) +{ + uint32_t raw_status = 0, bank = 0, pin_offset = 0; + + raw_status = gpio_bank[bank]->GPIO_RAW_INTSTATUS; + + if (raw_status == 0) + { + return; + } + + /* clear irq */ + gpio_bank[bank]->GPIO_PORTA_EOI = raw_status; + + while (raw_status) { + if (raw_status & 0x1) { + if (gpio_irq_handler[pin_offset]) { + gpio_irq_handler[pin_offset](pin_offset + bank*HAL_GPIO_PIN_NUM_EACH_BANK); + } + } + raw_status >>= 1; + ++pin_offset; + } +} + +#ifdef GPIOAUX_BASE +void _hal_gpio_aux_bank0_irq_handler(void) +{ + uint32_t raw_status = 0, bank = 0, pin_offset = 0; + + raw_status = 0; + bank = 0; + pin_offset = 0; + + raw_status = gpio_aux_bank[bank]->GPIO_RAW_INTSTATUS; + + if (raw_status == 0) + return; + + /* clear irq */ + gpio_aux_bank[bank]->GPIO_PORTA_EOI = raw_status; + + while (raw_status) { + if (raw_status & 0x1) { + if (gpio_irq_handler[pin_offset + HAL_GPIO_PIN_P4_0]) { + gpio_irq_handler[pin_offset + HAL_GPIO_PIN_P4_0](pin_offset + HAL_GPIO_PIN_P4_0 + bank*HAL_GPIO_PIN_NUM_EACH_BANK); + } + } + raw_status >>= 1; + ++pin_offset; + } +} +#endif + +uint8_t hal_gpio_setup_irq(enum HAL_GPIO_PIN_T pin, const struct HAL_GPIO_IRQ_CFG_T *cfg) +{ + int pin_offset = 0; + int bank = 0, port = 0; + + enum HAL_GPIO_PIN_T max_pin = HAL_GPIO_PIN_NUM; +#if defined(PMU_HAS_LED_PIN) && defined(PMU_HAS_LED_IRQ) + max_pin = HAL_GPIO_PIN_LED_NUM; +#endif + ASSERT(pin < max_pin, err_bad_pin, pin, max_pin); + + if (0) + { + } +#if defined(PMU_HAS_LED_PIN) && defined(PMU_HAS_LED_IRQ) + else if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) + { + return pmu_gpio_setup_irq(pin, cfg); + } +#endif +#ifdef GPIOAUX_BASE + else if (pin >= HAL_GPIO_PIN_P4_0) + { + bank = HAL_GPIO_AUX_PIN_TO_BANK(pin); + port = HAL_GPIO_AUX_PIN_TO_PORT(pin); + pin_offset = pin%HAL_GPIO_AUX_PIN_NUM_EACH_PORT; + + /* only port A support irq */ + if (port != 0) + return 0; + + if (cfg->irq_enable) { + gpio_aux_bank[bank]->GPIO_INTMASK |= (0x1<irq_debounce) + gpio_aux_bank[bank]->GPIO_DEBOUNCE |= 0x1<GPIO_DEBOUNCE &= ~(0x1<irq_type == HAL_GPIO_IRQ_TYPE_EDGE_SENSITIVE) + gpio_aux_bank[bank]->GPIO_INTTYPE_LEVEL |= 0x1<GPIO_INTTYPE_LEVEL &= ~(0x1<irq_polarity == HAL_GPIO_IRQ_POLARITY_HIGH_RISING) + gpio_aux_bank[bank]->GPIO_INT_POLARITY |= 0x1<GPIO_INT_POLARITY &= ~(0x1<irq_handler; + + NVIC_SetVector(GPIOAUX_IRQn, (uint32_t)_gpio_aux_irq_handler[bank]); + NVIC_SetPriority(GPIOAUX_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_EnableIRQ(GPIOAUX_IRQn); + + gpio_aux_bank[bank]->GPIO_INTMASK &= ~(0x1<GPIO_INTEN |= 0x1<GPIO_INTMASK |= (0x1<GPIO_INTEN &= ~(0x1<irq_enable) { + gpio_bank[bank]->GPIO_INTMASK |= (0x1<irq_debounce) + gpio_bank[bank]->GPIO_DEBOUNCE |= 0x1<GPIO_DEBOUNCE &= ~(0x1<irq_type == HAL_GPIO_IRQ_TYPE_EDGE_SENSITIVE) + gpio_bank[bank]->GPIO_INTTYPE_LEVEL |= 0x1<GPIO_INTTYPE_LEVEL &= ~(0x1<irq_polarity == HAL_GPIO_IRQ_POLARITY_HIGH_RISING) + gpio_bank[bank]->GPIO_INT_POLARITY |= 0x1<GPIO_INT_POLARITY &= ~(0x1<irq_handler; + + NVIC_SetVector(GPIO_IRQn, (uint32_t)_gpio_irq_handler[bank]); + NVIC_SetPriority(GPIO_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_EnableIRQ(GPIO_IRQn); + + gpio_bank[bank]->GPIO_INTMASK &= ~(0x1<GPIO_INTEN |= 0x1<GPIO_INTMASK |= (0x1<GPIO_INTEN &= ~(0x1< 1) + { + .base = I2C1_BASE, + .mod = HAL_CMU_MOD_O_I2C1, + .apb = HAL_CMU_MOD_P_I2C1, + .irq = I2C1_IRQn, +#ifdef I2C_USE_DMA + .rx_periph = HAL_GPDMA_I2C1_RX, + .tx_periph = HAL_GPDMA_I2C1_TX, +#endif + }, +#endif +}; + +static const char * const invalid_id = "Invalid I2C ID: %d"; + +static struct HAL_I2C_SM_T hal_i2c_sm[HAL_I2C_ID_NUM]; + +/* simple mode */ +#ifdef I2C_SIMPLE_MODE +static void hal_i2c_simple_proc(enum HAL_I2C_ID_T id); + +static HAL_I2C_INT_HANDLER_T hal_i2c_int_handlers[HAL_I2C_ID_NUM] = {NULL}; +#endif +/* simple mode end */ + +#ifdef I2C_SENSOR_ENGINE +static enum HAL_SENSOR_ENGINE_ID_T i2c_sensor_id[HAL_I2C_ID_NUM]; +static HAL_I2C_SENSOR_ENG_HANDLER_T i2c_sensor_handler[HAL_I2C_ID_NUM]; + +#ifdef I2C_SENSOR_ENGINE +static void hal_i2c_sensor_eng_proc(enum HAL_I2C_ID_T id); +#endif +#endif + +static uint32_t _i2c_get_base(enum HAL_I2C_ID_T id) +{ + return i2c_desc[id].base; +} + +static void POSSIBLY_UNUSED hal_i2c_delay_ms(int ms) +{ + osDelay(ms); +} + +static uint32_t _i2c_adjust_period_cnt(uint32_t period_cnt, uint16_t trising_ns, uint16_t tfalling_ns, uint16_t pclk_mhz) +{ + uint32_t old_period_cnt; + uint16_t rising_falling_cycle; + + old_period_cnt = period_cnt; + + // Round down the rising and falling cycle, so that the period count is rounded up, + // and the SCL freq is always <= the requested freq. + rising_falling_cycle = ((trising_ns + tfalling_ns) * pclk_mhz) / 1000; + + if (period_cnt > rising_falling_cycle) { + period_cnt -= rising_falling_cycle; + } else { + period_cnt = 0; + } + + HAL_I2C_TRACE(5,"%s: period_cnt=%u->%u trising_ns=%u tfalling_ns=%u", + __FUNCTION__, old_period_cnt, period_cnt, trising_ns, tfalling_ns); + + return period_cnt; +} + +static void _i2c_get_clk_cnt(uint32_t period_cnt, uint16_t tlow_ns, uint16_t thigh_ns, uint16_t spklen, + uint16_t pclk_mhz, uint16_t *plcnt, uint16_t *phcnt) +{ +#define IC_SCL_LOW_CYCLE_ADD (1) +// NOTE: H/w spec says that (6 + spklen) cycles is added for SCL high interval, but tests show that 1 more cycle is needed +#define IC_SCL_HIGH_CYCLE_ADD (6 + spklen + 1) + +#define MIN_IC_SCL_LCNT (7 + spklen + IC_SCL_LOW_CYCLE_ADD) +#define MIN_IC_SCL_HCNT (5 + spklen + IC_SCL_HIGH_CYCLE_ADD) + + uint32_t lcnt, hcnt; + uint16_t min_lcnt, min_hcnt; + + HAL_I2C_TRACE(6,"%s: period_cnt=%u tlow_ns=%u thigh_ns=%u spklen=%u pclk_mhz=%u", + __FUNCTION__, period_cnt, tlow_ns, thigh_ns, spklen, pclk_mhz); + + min_lcnt = (tlow_ns * pclk_mhz + 1000 - 1) / 1000; + if (min_lcnt < MIN_IC_SCL_LCNT) { + min_lcnt = MIN_IC_SCL_LCNT; + } + min_hcnt = (thigh_ns * pclk_mhz + 1000 - 1) / 1000; + if (min_hcnt < MIN_IC_SCL_HCNT) { + min_hcnt = MIN_IC_SCL_HCNT; + } + + if (min_lcnt + min_hcnt > period_cnt) { + HAL_I2C_ERROR(5,"%s:WARNING: period_cnt=%u too small: min_lcnt=%u min_hcnt=%u pclk_mhz=%u", + __FUNCTION__, period_cnt, min_lcnt, min_hcnt, pclk_mhz); + + lcnt = min_lcnt; + hcnt = min_hcnt; + } else { + lcnt = (period_cnt + 1) / 2; + if (min_lcnt >= min_hcnt) { + if (lcnt < min_lcnt) { + lcnt = min_lcnt; + } + hcnt = period_cnt - lcnt; + if (hcnt < min_hcnt) { + hcnt = min_hcnt; + } + } else { + hcnt = lcnt; + if (hcnt < min_hcnt) { + hcnt = min_hcnt; + } + lcnt = period_cnt - hcnt; + if (lcnt < min_lcnt) { + lcnt = min_lcnt; + } + } + } + + lcnt -= IC_SCL_LOW_CYCLE_ADD; + hcnt -= IC_SCL_HIGH_CYCLE_ADD; + + ASSERT(lcnt <= UINT16_MAX && hcnt <= UINT16_MAX, "%s: lcnt=%u or hcnt=%u overflow", __FUNCTION__, lcnt, hcnt); + + *plcnt = lcnt; + *phcnt = hcnt; +} + +static void _i2c_set_speed(enum HAL_I2C_ID_T id, int speed_mode, int speed) +{ +#define MAX_HS_SPK_NS 10 +#define MAX_FSP_SPK_NS 50 +#define MAX_FS_SPK_NS 50 + +#define SS_THOLD_NS 1800 // [300, 3450] +#define FS_THOLD_NS 600 // [300, 900] +#define FSP_THOLD_NS 300 // [ 0, -] +#define HS_100PF_THOLD_NS 30 // [ 0, 70] +#define HS_400PF_THOLD_NS 70 // [ 0, 150] + +#define SS_TRISING_NS 300 // [ 0, 1000] +#define FS_TRISING_NS 50 // [ 20, 300] +#define FSP_TRISING_NS 30 // [ 0, 120] +#define HS_100PF_TRISING_NS 30 // [ 10, 40] for SCL, [ 20, 80] for SDA +#define HS_400PF_TRISING_NS 30 // [ 10, 80] for SCL, [ 20, 160] for SDA + +#define SS_TFALLING_NS 30 // [ 0, 300] +#define FS_TFALLING_NS 30 // [ 20, 300] +#define FSP_TFALLING_NS 30 // [ 20, 120] +#define HS_100PF_TFALLING_NS 30 // [ 10, 40] for SCL, [ 20, 80] for SDA +#define HS_400PF_TFALLING_NS 30 // [ 10, 80] for SCL, [ 20, 160] for SDA + +#define MIN_SS_TLOW_NS 4700 +#define MIN_SS_THIGH_NS 4000 +#define MIN_FS_TLOW_NS 1300 +#define MIN_FS_THIGH_NS 600 +#define MIN_FSP_TLOW_NS 500 +#define MIN_FSP_THIGH_NS 260 +#define MIN_HS_100PF_TLOW_NS 160 +#define MIN_HS_100PF_THIGH_NS 60 +#define MIN_HS_400PF_TLOW_NS 320 +#define MIN_HS_400PF_THIGH_NS 120 + +// Round down the spike suppression limit value +#define GET_SPKLEN_VAL(s) ((s) * pclk_mhz / 1000) + + uint32_t reg_base = _i2c_get_base(id); + uint32_t min_mclk, pclk, period_cnt; + uint16_t lcnt, hcnt, hold_cycle, spklen; + uint16_t tlow_ns, thigh_ns, thold_ns, trising_ns, tfalling_ns; + uint8_t spk_ns; + uint16_t pclk_mhz; + + if (speed_mode == IC_SPEED_MODE_MAX) { + min_mclk = speed * 50; + } else { + min_mclk = speed * 40; + } + pclk = 0; +#ifdef PERIPH_PLL_FREQ + if (PERIPH_PLL_FREQ / 2 > 2 * hal_cmu_get_crystal_freq()) { + // Init to OSC_X2 + pclk = 2 * hal_cmu_get_crystal_freq(); + if (min_mclk > pclk) { + pclk = PERIPH_PLL_FREQ / 2; + hal_cmu_i2c_set_div(2); + } else { + pclk = 0; + } + } +#endif + if (pclk == 0) { + enum HAL_CMU_PERIPH_FREQ_T periph_freq; + + // Init to OSC + pclk = hal_cmu_get_crystal_freq(); + if (min_mclk > pclk) { + pclk *= 2; + periph_freq = HAL_CMU_PERIPH_FREQ_52M; + } else { + periph_freq = HAL_CMU_PERIPH_FREQ_26M; + } + + // NOTE: All I2C controllers share the same module clock configuration + hal_cmu_i2c_set_freq(periph_freq); + } + + pclk_mhz = pclk / 1000000; + period_cnt = (pclk + speed - 1) / speed; + + switch (speed_mode) { + case IC_SPEED_MODE_MAX: + + spk_ns = MAX_HS_SPK_NS; + tlow_ns = MIN_HS_100PF_TLOW_NS; + thigh_ns = MIN_HS_100PF_THIGH_NS; + thold_ns = HS_100PF_THOLD_NS; + trising_ns = HS_100PF_TRISING_NS; + tfalling_ns = HS_100PF_TFALLING_NS; + + spklen = GET_SPKLEN_VAL(spk_ns); + if (spklen == 0) { + spklen = 1; + } + i2cip_w_hs_spklen(reg_base, spklen); + + period_cnt = _i2c_adjust_period_cnt(period_cnt, trising_ns, tfalling_ns, pclk_mhz); + _i2c_get_clk_cnt(period_cnt, tlow_ns, thigh_ns, spklen, pclk_mhz, &lcnt, &hcnt); + + i2cip_w_high_speed_hcnt(reg_base, hcnt); + i2cip_w_high_speed_lcnt(reg_base, lcnt); + + i2cip_w_speed(reg_base, I2CIP_HIGH_SPEED_MASK); + + // Continue to config fast mode +#ifdef I2S_FSP_MODE + period_cnt = (pclk + I2C_FSP_SPEED - 1) / I2C_FSP_SPEED; +#else + period_cnt = (pclk + I2C_FAST_SPEED - 1) / I2C_FAST_SPEED; +#endif + + case IC_SPEED_MODE_FAST: + +#ifdef I2S_FSP_MODE + if (speed > I2C_FAST_SPEED) { + spk_ns = MAX_FSP_SPK_NS; + tlow_ns = MIN_FSP_TLOW_NS; + thigh_ns = MIN_FSP_THIGH_NS; + thold_ns = FSP_THOLD_NS; + trising_ns = FSP_TRISING_NS; + tfalling_ns = FSP_TFALLING_NS; + } else +#endif + { + spk_ns = MAX_FS_SPK_NS; + tlow_ns = MIN_FS_TLOW_NS; + thigh_ns = MIN_FS_THIGH_NS; + trising_ns = FS_TRISING_NS; + tfalling_ns = FS_TFALLING_NS; + } + + spklen = GET_SPKLEN_VAL(spk_ns); + if (spklen == 0) { + spklen = 1; + } + i2cip_w_fs_spklen(reg_base, spklen); + + period_cnt = _i2c_adjust_period_cnt(period_cnt, trising_ns, tfalling_ns, pclk_mhz); + _i2c_get_clk_cnt(period_cnt, tlow_ns, thigh_ns, spklen, pclk_mhz, &lcnt, &hcnt); + + i2cip_w_fast_speed_hcnt(reg_base, hcnt); + i2cip_w_fast_speed_lcnt(reg_base, lcnt); + + // Update sda hold time and speed mode if in fast mode + // Skip if in high speed mode + if (speed_mode == IC_SPEED_MODE_FAST) { + thold_ns = FS_THOLD_NS; + i2cip_w_speed(reg_base, I2CIP_FAST_SPEED_MASK); + } + + break; + + case IC_SPEED_MODE_STANDARD: + default: + + spk_ns = MAX_FS_SPK_NS; + tlow_ns = MIN_SS_TLOW_NS; + thigh_ns = MIN_SS_THIGH_NS; + thold_ns = SS_THOLD_NS; + trising_ns = SS_TRISING_NS; + tfalling_ns = SS_TFALLING_NS; + + spklen = GET_SPKLEN_VAL(spk_ns); + if (spklen == 0) { + spklen = 1; + } + i2cip_w_fs_spklen(reg_base, spklen); + + period_cnt = _i2c_adjust_period_cnt(period_cnt, trising_ns, tfalling_ns, pclk_mhz); + _i2c_get_clk_cnt(period_cnt, tlow_ns, thigh_ns, spklen, pclk_mhz, &lcnt, &hcnt); + + i2cip_w_standard_speed_hcnt(reg_base, hcnt); + i2cip_w_standard_speed_lcnt(reg_base, lcnt); + i2cip_w_speed(reg_base, I2CIP_STANDARD_SPEED_MASK); + break; + } + + // Master mode: min = 1; slave mode: min = (spklen + 7) + hold_cycle = (thold_ns * pclk_mhz + 1000 - 1) / 1000; + i2cip_w_sda_hold_time(reg_base, hold_cycle); + + HAL_I2C_TRACE(1,"crystal freq=%d", pclk); + HAL_I2C_TRACE(5,"i2c-%d mode=%d lcnt=%d hcnt=%d hold=%d", + id, speed_mode, lcnt, hcnt, hold_cycle); +} + +static uint8_t _i2c_set_bus_speed(enum HAL_I2C_ID_T id, + unsigned int speed) +{ + uint32_t speed_mode; + + if (speed > I2C_FSP_SPEED) + speed_mode = IC_SPEED_MODE_MAX; + else if (speed > I2C_FAST_SPEED) +#ifdef I2S_FSP_MODE + speed_mode = IC_SPEED_MODE_FAST; +#else + speed_mode = IC_SPEED_MODE_MAX; +#endif + else if (speed > I2C_STANDARD_SPEED) + speed_mode = IC_SPEED_MODE_FAST; + else + speed_mode = IC_SPEED_MODE_STANDARD; + + _i2c_set_speed(id, speed_mode, speed); + + return 0; +} + +/* state machine related */ +static void hal_i2c_sm_init(enum HAL_I2C_ID_T id, const struct HAL_I2C_CONFIG_T *cfg) +{ + memcpy(&hal_i2c_sm[id].cfg, cfg, sizeof(*cfg)); + hal_i2c_sm[id].state = HAL_I2C_SM_IDLE; +#if defined(I2C_TASK_MODE) || defined(I2C_SENSOR_ENGINE) + hal_i2c_sm[id].in_task = 0; + hal_i2c_sm[id].out_task = 0; + hal_i2c_sm[id].task_count = 0; + +#ifdef I2C_USE_DMA + hal_i2c_sm[id].tx_dma_cfg.ch = HAL_DMA_CHAN_NONE; + hal_i2c_sm[id].rx_dma_cfg.ch = HAL_DMA_CHAN_NONE; +#else + hal_i2c_sm[id].cfg.use_dma = 0; +#endif +#endif +} + +#if defined(I2C_TASK_MODE) || defined(I2C_SENSOR_ENGINE) +static uint32_t hal_i2c_sm_commit(enum HAL_I2C_ID_T id, const uint8_t *tx_buf, uint16_t tx_txn_len, + uint8_t *rx_buf, uint16_t rx_txn_len, uint16_t txn_cnt, + uint16_t target_addr, uint32_t action, + uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler) +{ + uint32_t cur = hal_i2c_sm[id].in_task; + + hal_i2c_sm[id].task[cur].tx_buf = tx_buf; + hal_i2c_sm[id].task[cur].rx_buf = rx_buf; + hal_i2c_sm[id].task[cur].stop = 1; + hal_i2c_sm[id].task[cur].lock = 1; + hal_i2c_sm[id].task[cur].state = 0; + hal_i2c_sm[id].task[cur].rx_txn_len = rx_txn_len; + hal_i2c_sm[id].task[cur].tx_txn_len = tx_txn_len; + hal_i2c_sm[id].task[cur].txn_cnt = txn_cnt; + hal_i2c_sm[id].task[cur].tx_pos = 0; + hal_i2c_sm[id].task[cur].rx_pos = 0; + hal_i2c_sm[id].task[cur].rx_cmd_sent = 0; + hal_i2c_sm[id].task[cur].errcode = 0; + hal_i2c_sm[id].task[cur].action = action; + hal_i2c_sm[id].task[cur].handler = handler; + hal_i2c_sm[id].task[cur].restart_after_write = 1; + hal_i2c_sm[id].task[cur].target_addr = target_addr; + hal_i2c_sm[id].task[cur].transfer_id = transfer_id; + + hal_i2c_sm[id].in_task = (cur + 1) % HAL_I2C_SM_TASK_NUM_MAX; + hal_i2c_sm[id].task_count++; + return cur; +} + +static void hal_i2c_sm_done(enum HAL_I2C_ID_T id) +{ + hal_i2c_sm[id].in_task = 0; + hal_i2c_sm[id].out_task = 0; + hal_i2c_sm[id].task_count = 0; + hal_i2c_sm[id].state = HAL_I2C_SM_IDLE; + + HAL_I2C_TRACE(1,"%s", __func__); +} + +static enum HAL_I2C_SM_TASK_STATE_T _i2c_chk_clr_task_error(uint32_t reg_base, uint32_t ip_int_status, uint32_t tx_abrt_source) +{ + enum HAL_I2C_SM_TASK_STATE_T state = 0; + uint32_t tmp1; + + /* tx abort interrupt */ + if (ip_int_status & I2CIP_INT_STATUS_TX_ABRT_MASK) { + state |= HAL_I2C_SM_TASK_STATE_TX_ABRT; + + /* sbyte_norstrt is special to clear : restart disable but user want to send a restart */ + /* to fix this bit : enable restart , clear speical , clear gc_or_start bit temporary */ + tmp1 = i2cip_r_target_address_reg(reg_base); + if (tx_abrt_source & I2CIP_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT_MASK) { + i2cip_w_restart(reg_base, HAL_I2C_YES); + i2cip_w_special_bit(reg_base, HAL_I2C_NO); + i2cip_w_gc_or_start_bit(reg_base, HAL_I2C_NO); + } + i2cip_r_clr_tx_abrt(reg_base); + /* restore register after clear */ + if (tx_abrt_source & I2CIP_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT_MASK) { + i2cip_w_target_address_reg(reg_base, tmp1); + } + } + /* tx overflow interrupt */ + if (ip_int_status & I2CIP_INT_MASK_TX_OVER_MASK) { + state |= HAL_I2C_SM_TASK_STATE_FIFO_ERR; + i2cip_r_clr_tx_over(reg_base); + } + /* rx overflow interrupt */ + if (ip_int_status & I2CIP_INT_MASK_RX_OVER_MASK) { + state |= HAL_I2C_SM_TASK_STATE_FIFO_ERR; + i2cip_r_clr_rx_over(reg_base); + } + /* rx underflow interrupt */ + if (ip_int_status & I2CIP_INT_MASK_RX_UNDER_MASK) { + state |= HAL_I2C_SM_TASK_STATE_FIFO_ERR; + i2cip_r_clr_rx_under(reg_base); + } + + return state; +} + +static void _i2c_show_error_code(uint32_t errcode) +{ +#ifdef DEBUG + if (errcode & HAL_I2C_ERRCODE_SLVRD_INTX) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_SLVRD_INTX"); + if (errcode & HAL_I2C_ERRCODE_SLV_ARBLOST) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_SLV_ARBLOST"); + if (errcode & HAL_I2C_ERRCODE_SLVFLUSH_TXFIFO) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_SLVFLUSH_TXFIFO"); + if (errcode & HAL_I2C_ERRCODE_MASTER_DIS) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_MASTER_DIS"); + if (errcode & HAL_I2C_ERRCODE_10B_RD_NORSTRT) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_10B_RD_NORSTRT"); + if (errcode & HAL_I2C_ERRCODE_SBYTE_NORSTRT) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_SBYTE_NORSTRT"); + if (errcode & HAL_I2C_ERRCODE_HS_NORSTRT) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_HS_NORSTRT"); + if (errcode & HAL_I2C_ERRCODE_SBYTE_ACKDET) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_SBYTE_ACKDET"); + if (errcode & HAL_I2C_ERRCODE_HS_ACKDET) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_HS_ACKDET"); + if (errcode & HAL_I2C_ERRCODE_GCALL_READ) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_GCALL_READ"); + if (errcode & HAL_I2C_ERRCODE_GCALL_NOACK) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_GCALL_NOACK"); + if (errcode & HAL_I2C_ERRCODE_TXDATA_NOACK) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_TXDATA_NOACK"); + if (errcode & HAL_I2C_ERRCODE_10ADDR2_NOACK) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_10ADDR2_NOACK"); + if (errcode & HAL_I2C_ERRCODE_10ADDR1_NOACK) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_10ADDR1_NOACK"); + if (errcode & HAL_I2C_ERRCODE_7B_ADDR_NOACK) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_7B_ADDR_NOACK"); + + if (errcode & HAL_I2C_ERRCODE_INV_PARAM) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_INV_PARAM"); + if (errcode & HAL_I2C_ERRCODE_IN_USE) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_IN_USE"); + if (errcode & HAL_I2C_ERRCODE_FIFO_ERR) + HAL_I2C_ERROR(0,"i2c err : HAL_I2C_ERRCODE_FIFO_ERR"); +#endif +} + +#ifdef I2C_USE_DMA +static void hal_i2c_tx_dma_handler(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + enum HAL_I2C_ID_T id; + + for (id = HAL_I2C_ID_0; id < HAL_I2C_ID_NUM; id++) { + if (hal_i2c_sm[id].tx_dma_cfg.ch == chan) { + } + } +} + +static void hal_i2c_rx_dma_handler(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + enum HAL_I2C_ID_T id; + + for (id = HAL_I2C_ID_0; id < HAL_I2C_ID_NUM; id++) { + if (hal_i2c_sm[id].rx_dma_cfg.ch == chan) { + } + } +} + +static void hal_i2c_dma_release(enum HAL_I2C_ID_T id) +{ + uint32_t reg_base; + struct HAL_DMA_CH_CFG_T *tx_dma_cfg = NULL, *rx_dma_cfg = NULL; + + if (hal_i2c_sm[id].cfg.use_dma == 0) { + return; + } + + reg_base = _i2c_get_base(id); + + i2cip_w_tx_dma_enable(reg_base, HAL_I2C_NO); + i2cip_w_rx_dma_enable(reg_base, HAL_I2C_NO); + + tx_dma_cfg = &hal_i2c_sm[id].tx_dma_cfg; + rx_dma_cfg = &hal_i2c_sm[id].rx_dma_cfg; + + HAL_I2C_TRACE(1,"i2c tx free dma ch %d", tx_dma_cfg->ch); + if (tx_dma_cfg->ch != HAL_DMA_CHAN_NONE) { + hal_gpdma_cancel(tx_dma_cfg->ch); + hal_gpdma_free_chan(tx_dma_cfg->ch); + tx_dma_cfg->ch = HAL_DMA_CHAN_NONE; + } + + HAL_I2C_TRACE(1,"i2c rx free dma ch %d", rx_dma_cfg->ch); + if (rx_dma_cfg->ch != HAL_DMA_CHAN_NONE) { + hal_gpdma_cancel(rx_dma_cfg->ch); + hal_gpdma_free_chan(rx_dma_cfg->ch); + rx_dma_cfg->ch = HAL_DMA_CHAN_NONE; + } +} + +static void hal_i2c_dma_config(enum HAL_I2C_ID_T id, const struct HAL_I2C_SM_TASK_T *out_task) +{ + uint32_t reg_base; + uint32_t i, txn; + uint32_t txn_start, org_start; + struct HAL_DMA_CH_CFG_T *tx_dma_cfg = NULL, *rx_dma_cfg = NULL; + enum HAL_I2C_SM_TASK_ACTION_T action; + uint32_t total_tx_len; + + if (hal_i2c_sm[id].cfg.use_dma == 0) { + return; + } + + reg_base = _i2c_get_base(id); + action = out_task->action; + + total_tx_len = out_task->tx_txn_len * out_task->txn_cnt; + if (action == HAL_I2C_SM_TASK_ACTION_M_RECV) { + total_tx_len += out_task->rx_txn_len * out_task->txn_cnt; + } + ASSERT(total_tx_len < ARRAY_SIZE(hal_i2c_sm[id].dma_tx_buf), + "%s: xfer size too large: action=%d total_tx_len=%u (should <= %u)", + __FUNCTION__, action, total_tx_len, ARRAY_SIZE(hal_i2c_sm[id].dma_tx_buf)); + + i2cip_w_tx_dma_enable(reg_base, HAL_I2C_YES); + i2cip_w_tx_dma_tl(reg_base, HAL_I2C_DMA_TX_TL); + + tx_dma_cfg = &hal_i2c_sm[id].tx_dma_cfg; + memset(tx_dma_cfg, 0, sizeof(*tx_dma_cfg)); + tx_dma_cfg->dst = 0; // useless + tx_dma_cfg->dst_bsize = HAL_DMA_BSIZE_1; + tx_dma_cfg->dst_periph = i2c_desc[id].tx_periph; + tx_dma_cfg->dst_width = HAL_DMA_WIDTH_HALFWORD; + tx_dma_cfg->handler = hal_i2c_tx_dma_handler; + tx_dma_cfg->src_bsize = HAL_DMA_BSIZE_1; + tx_dma_cfg->src_periph = 0; // useless + tx_dma_cfg->src_tsize = total_tx_len; + tx_dma_cfg->src_width = HAL_DMA_WIDTH_HALFWORD; + tx_dma_cfg->try_burst = 1; + tx_dma_cfg->type = HAL_DMA_FLOW_M2P_DMA; + tx_dma_cfg->src = (uint32_t)hal_i2c_sm[id].dma_tx_buf; + tx_dma_cfg->ch = hal_gpdma_get_chan(tx_dma_cfg->dst_periph, HAL_DMA_HIGH_PRIO); + HAL_I2C_TRACE(1,"i2c tx get dma ch %d", tx_dma_cfg->ch); + ASSERT(tx_dma_cfg->ch != HAL_DMA_CHAN_NONE, "I2C: Failed to get tx dma chan"); + + HAL_I2C_TRACE(3,"tx size %d cnt %d total tx size %d", out_task->tx_txn_len, out_task->txn_cnt, total_tx_len); + + memset(&hal_i2c_sm[id].dma_tx_buf[0], 0, sizeof(hal_i2c_sm[id].dma_tx_buf)); + + for (txn = 0; txn < out_task->txn_cnt; txn++) { + org_start = out_task->tx_txn_len * txn; + txn_start = (out_task->tx_txn_len + out_task->rx_txn_len) * txn; + for (i = 0; i < out_task->tx_txn_len; i++) { + // lo byte of short : for data + // hi byte of short : for cmd/stop/restart + hal_i2c_sm[id].dma_tx_buf[txn_start + i] = out_task->tx_buf[org_start + i]; + } + if (txn && out_task->restart_after_write) { + hal_i2c_sm[id].dma_tx_buf[txn_start] |= I2CIP_CMD_DATA_RESTART_MASK; + } + } + + if (action == HAL_I2C_SM_TASK_ACTION_M_RECV) { + i2cip_w_rx_dma_enable(reg_base, HAL_I2C_YES); + i2cip_w_rx_dma_tl(reg_base, HAL_I2C_DMA_RX_TL); + + for (txn = 0; txn < out_task->txn_cnt; txn++) { + txn_start = (out_task->tx_txn_len + out_task->rx_txn_len) * txn + out_task->tx_txn_len; + for (i = 0; i < out_task->rx_txn_len; i++) { + // lo byte of short : for data + // hi byte of short : for cmd/stop/restart + hal_i2c_sm[id].dma_tx_buf[txn_start + i] = I2CIP_CMD_DATA_CMD_READ_MASK; + } + if (out_task->restart_after_write) { + hal_i2c_sm[id].dma_tx_buf[txn_start] |= I2CIP_CMD_DATA_RESTART_MASK; + } + } + + HAL_I2C_TRACE(2,"rx size %d cnt %d", out_task->rx_txn_len, out_task->txn_cnt); + + rx_dma_cfg = &hal_i2c_sm[id].rx_dma_cfg; + memset(rx_dma_cfg, 0, sizeof(*rx_dma_cfg)); + rx_dma_cfg->dst = (uint32_t)(out_task->rx_buf); + rx_dma_cfg->dst_bsize = HAL_DMA_BSIZE_1; + rx_dma_cfg->dst_periph = 0; // useless + rx_dma_cfg->dst_width = HAL_DMA_WIDTH_BYTE; + rx_dma_cfg->handler = hal_i2c_rx_dma_handler; + rx_dma_cfg->src_bsize = HAL_DMA_BSIZE_1; + rx_dma_cfg->src_periph = i2c_desc[id].rx_periph; + rx_dma_cfg->src_tsize = out_task->rx_txn_len * out_task->txn_cnt; + rx_dma_cfg->src_width = HAL_DMA_WIDTH_BYTE; + rx_dma_cfg->try_burst = 0; + rx_dma_cfg->src = 0; // useless + rx_dma_cfg->type = HAL_DMA_FLOW_P2M_DMA; + rx_dma_cfg->ch = hal_gpdma_get_chan(rx_dma_cfg->src_periph, HAL_DMA_HIGH_PRIO); + HAL_I2C_TRACE(1,"i2c rx get dma ch %d", rx_dma_cfg->ch); + ASSERT(tx_dma_cfg->ch != HAL_DMA_CHAN_NONE, "I2C: Failed to get rx dma chan"); + } + + if (out_task->stop) { + hal_i2c_sm[id].dma_tx_buf[total_tx_len - 1] |= I2CIP_CMD_DATA_STOP_MASK; + } +} +#endif +#endif + +#ifdef I2C_TASK_MODE +static void hal_i2c_sm_done_task(enum HAL_I2C_ID_T id) +{ + struct HAL_I2C_SM_TASK_T *task; + uint32_t reg_base = _i2c_get_base(id); + + task = &(hal_i2c_sm[id].task[hal_i2c_sm[id].out_task]); + + if (task->errcode) { + HAL_I2C_ERROR(1,"i2c err : 0x%X", task->errcode); + _i2c_show_error_code(task->errcode); + } + + if (task->stop || task->errcode) { + HAL_I2C_TRACE(0,"disable i2c"); + i2cip_w_enable(reg_base, HAL_I2C_NO); + } + +#ifdef I2C_USE_DMA + if (hal_i2c_sm[id].cfg.use_dma) { + hal_i2c_dma_release(id); + } +#endif + + if (hal_i2c_sm[id].cfg.use_sync) { + /* FIXME : os and non-os - different proc */ + task->lock = 0; + } else { + if (task->handler) { + task->handler(id, task->transfer_id, task->tx_buf, task->tx_txn_len * task->txn_cnt, + task->rx_buf, task->rx_txn_len * task->txn_cnt, task->errcode); + } + } + + hal_i2c_sm[id].out_task = (hal_i2c_sm[id].out_task+1)%HAL_I2C_SM_TASK_NUM_MAX; + --hal_i2c_sm[id].task_count; +} + +static void hal_i2c_sm_next_task(enum HAL_I2C_ID_T id) +{ + uint32_t out_task_index; + uint32_t reg_base, reinit; + enum HAL_I2C_SM_TASK_ACTION_T action; + struct HAL_I2C_SM_TASK_T *out_task = 0; + + reg_base = _i2c_get_base(id); + + if (hal_i2c_sm[id].task_count <= 0) { + HAL_I2C_TRACE(0,"no task"); + hal_i2c_sm_done(id); + return; + } + + out_task_index = hal_i2c_sm[id].out_task; + out_task = &(hal_i2c_sm[id].task[out_task_index]); + action = out_task->action; + + /* tx : quarter trigger TX EMPTY INT */ + i2cip_w_tx_threshold(reg_base, HAL_I2C_TX_TL); + if (action == HAL_I2C_SM_TASK_ACTION_M_RECV) { + /* rx : three quarter trigger RX FULL INT */ + i2cip_w_rx_threshold(reg_base, HAL_I2C_RX_TL); + } + +#ifdef I2C_USE_DMA + if (hal_i2c_sm[id].cfg.use_dma) { + i2cip_init_int_mask(reg_base, I2CIP_INT_MASK_STOP_DET_MASK|I2CIP_INT_MASK_ERROR_MASK); + + /* prepare for dma operation */ + hal_i2c_dma_config(id, out_task); + } else +#endif + { + /* open all interrupt */ + i2cip_init_int_mask(reg_base, (I2CIP_INT_MASK_ALL & ~(I2CIP_INT_MASK_START_DET_MASK | I2CIP_INT_MASK_ACTIVITY_MASK))); + } + + reinit = i2cip_r_enable_status(reg_base); + /* not enable : reconfig i2cip with new-task params */ + /* enable : same operation with pre task */ + if (!(reinit & I2CIP_ENABLE_STATUS_ENABLE_MASK)) { + HAL_I2C_TRACE(0,"enable i2c"); + i2cip_w_restart(reg_base, HAL_I2C_YES); + i2cip_w_target_address(reg_base, out_task->target_addr); + i2cip_w_enable(reg_base, HAL_I2C_YES); + } + +#ifdef I2C_USE_DMA + if (hal_i2c_sm[id].cfg.use_dma) { + if (action == HAL_I2C_SM_TASK_ACTION_M_RECV) { + HAL_I2C_TRACE(0,"enable rx dma"); + hal_gpdma_start(&hal_i2c_sm[id].rx_dma_cfg); + } + HAL_I2C_TRACE(0,"enable tx dma"); + hal_gpdma_start(&hal_i2c_sm[id].tx_dma_cfg); + } +#endif +} + +static uint32_t hal_i2c_sm_wait_task_if_need(enum HAL_I2C_ID_T id, uint32_t task_idx, uint32_t tm_ms) +{ + int tmcnt; + struct HAL_I2C_SM_TASK_T *task = 0; + + /* FIXME : task_id maybe invalid cause so-fast device operation */ + task = &(hal_i2c_sm[id].task[task_idx]); + + if (!(hal_i2c_sm[id].cfg.use_sync)) + return 0; + + /* FIXME : os and non-os - different proc */ + tmcnt = tm_ms / HAL_I2C_DLY_MS; + while(1) { + uint32_t lock = task->lock; + + if (!lock) + break; + + if (!tmcnt) { + HAL_I2C_TRACE(1,"wait lock timeout %d ms", tm_ms); + task->errcode = HAL_I2C_ERRCODE_SYNC_TIMEOUT; + hal_i2c_sm_done_task(id); + hal_i2c_sm_next_task(id); + break; + } + hal_i2c_delay_ms(HAL_I2C_DLY_MS); + tmcnt--; + } + return task->errcode; +} + +static void hal_i2c_sm_kickoff(enum HAL_I2C_ID_T id) +{ + if (hal_i2c_sm[id].state == HAL_I2C_SM_IDLE) { + hal_i2c_sm[id].state = HAL_I2C_SM_RUNNING; + hal_i2c_sm_next_task(id); + } +} + +static void hal_i2c_sm_proc(enum HAL_I2C_ID_T id) +{ + uint32_t reg_base = 0; + enum HAL_I2C_SM_STATE_T state; + enum HAL_I2C_SM_TASK_STATE_T task_state; + struct HAL_I2C_SM_TASK_T *task; + uint32_t i = 0, restart = 0, stop = 0, data = 0; + uint32_t ip_int_status = 0, tx_abrt_source = 0; + uint8_t rx_limit, tx_limit, rx_cnt, tx_cnt; + uint32_t total_tx_len, total_rx_len; + uint32_t txn_idx, txn_pos; + + reg_base = _i2c_get_base(id); + state = hal_i2c_sm[id].state; + task = &(hal_i2c_sm[id].task[hal_i2c_sm[id].out_task]); + + ip_int_status = i2cip_r_int_status(reg_base); + tx_abrt_source = i2cip_r_tx_abrt_source(reg_base); + + HAL_I2C_TRACE(4,"id:%d, ip_int_status=0x%X tx_abrt_source=0x%X state=%d", + id, ip_int_status, tx_abrt_source, state); + + task_state = _i2c_chk_clr_task_error(reg_base, ip_int_status, tx_abrt_source); + + if (state != HAL_I2C_SM_RUNNING) { + HAL_I2C_ERROR(3,"*** WARNING: No i2c task running: id=%d ip_int_status=0x%X tx_abrt_source=0x%X", id, ip_int_status, tx_abrt_source); + i2cip_r_clr_all_intr(reg_base); + return; + } + + HAL_I2C_TRACE(1,"RUNNING action=%d", task->action); + + task->state |= task_state; + + if (task->state & (HAL_I2C_SM_TASK_STATE_TX_ABRT | HAL_I2C_SM_TASK_STATE_FIFO_ERR)) { + HAL_I2C_ERROR(5,"*** ERROR:%s: id=%d task_state=0x%X ip_int_status=0x%X tx_abrt_source=0x%X", __func__, id, task->state, ip_int_status, tx_abrt_source); + task->errcode = tx_abrt_source; + if (task->state & HAL_I2C_SM_TASK_STATE_FIFO_ERR) { + task->errcode |= HAL_I2C_ERRCODE_FIFO_ERR; + } + /* done task on any error */ + hal_i2c_sm_done_task(id); + hal_i2c_sm_next_task(id); + return; + } + + /* stop det interrupt */ + if (ip_int_status & I2CIP_INT_STATUS_STOP_DET_MASK) { + task->state |= HAL_I2C_SM_TASK_STATE_STOP; + i2cip_r_clr_stop_det(reg_base); + } + + /* start det interrupt */ + if (ip_int_status & I2CIP_INT_STATUS_START_DET_MASK) { + task->state |= HAL_I2C_SM_TASK_STATE_START; + i2cip_r_clr_start_det(reg_base); + } + + /* activeity det interrupt */ + if (ip_int_status & I2CIP_INT_STATUS_ACTIVITY_MASK) { + task->state |= HAL_I2C_SM_TASK_STATE_ACT; + i2cip_r_clr_activity(reg_base); + } + + switch (task->action) { + case HAL_I2C_SM_TASK_ACTION_M_SEND: + { + if (hal_i2c_sm[id].cfg.use_dma == 0) { + /* tx empty : means tx fifo is at or below IC_TX_TL : + need to write more data : we can NOT clear this bit, cleared by hw */ + if (ip_int_status & I2CIP_INT_STATUS_TX_EMPTY_MASK) { + total_tx_len = task->tx_txn_len * task->txn_cnt; + tx_limit = i2cip_r_tx_fifo_level(reg_base); + if (tx_limit < I2CIP_TX_FIFO_DEPTH) { + tx_limit = I2CIP_TX_FIFO_DEPTH - tx_limit; + } else { + tx_limit = 0; + } + HAL_I2C_TRACE(4,"m_send: tx_pos=%d tx_txn_len=%d cnt=%d tx_limit=%d", + task->tx_pos, task->tx_txn_len, task->txn_cnt, tx_limit); + for (i = task->tx_pos, tx_cnt = 0; + ((i < total_tx_len) && (tx_cnt < tx_limit)); + ++i, ++tx_cnt) { + /* last byte : we need to decide stop */ + if (i == total_tx_len - 1) { + stop = task->stop ? I2CIP_CMD_DATA_STOP_MASK : 0; + } else { + stop = 0; + } + if (task->txn_cnt == 1) { + txn_pos = i; + } else { + txn_pos = i % task->tx_txn_len; + } + /* first byte : need to decide restart */ + if (i && task->restart_after_write && txn_pos == 0) { + restart = I2CIP_CMD_DATA_RESTART_MASK; + } else { + restart = 0; + } + /* write data to FIFO */ + i2cip_w_cmd_data(reg_base, + task->tx_buf[i] | I2CIP_CMD_DATA_CMD_WRITE_MASK | restart | stop); + + HAL_I2C_TRACE(3,"m_send: data=0x%02X restart=0x%X stop=0x%X", + task->tx_buf[i], restart, stop); + } + + task->tx_pos = i; + + /* all write action done : do NOT need tx empty int */ + if (task->tx_pos == total_tx_len) { + i2cip_clear_int_mask(reg_base, I2CIP_INT_MASK_TX_EMPTY_MASK); + } + HAL_I2C_TRACE(1,"m_send: i2c status=0x%X", i2cip_r_status(reg_base)); + } + } + + /* stop condition : done task */ + if (task->state & HAL_I2C_SM_TASK_STATE_STOP) { + HAL_I2C_TRACE(1,"m_send: task->state:0x%X", task->state); + hal_i2c_sm_done_task(id); + hal_i2c_sm_next_task(id); + } + break; + } + case HAL_I2C_SM_TASK_ACTION_M_RECV: + { + if (hal_i2c_sm[id].cfg.use_dma == 0) { + /* rx full : need to read */ + if (ip_int_status & I2CIP_INT_STATUS_RX_FULL_MASK) { + total_rx_len = task->rx_txn_len * task->txn_cnt; + rx_limit = i2cip_r_rx_fifo_level(reg_base); + HAL_I2C_TRACE(4,"m_recv:full: rx_pos=%d rx_txn_len=%d cnt=%d rx_limit=%d", + task->rx_pos, task->rx_txn_len, task->txn_cnt, rx_limit); + for (i = task->rx_pos, rx_cnt = 0; + ((i < total_rx_len) && (rx_cnt < rx_limit)); + ++i, ++rx_cnt) { + task->rx_buf[i] = i2cip_r_cmd_data(reg_base); + HAL_I2C_TRACE(2,"m_recv:full: rx_buf[%d] 0x%X", i, task->rx_buf[i]); + } + task->rx_pos = i; + } + + /* tx empty : means tx fifo is at or below IC_TX_TL : + need to write more data : we can NOT clear this bit, cleared by hw */ + if (ip_int_status & I2CIP_INT_STATUS_TX_EMPTY_MASK) { + total_tx_len = (task->tx_txn_len + task->rx_txn_len) * task->txn_cnt; + tx_limit = i2cip_r_tx_fifo_level(reg_base); + if (tx_limit < I2CIP_TX_FIFO_DEPTH) { + tx_limit = I2CIP_TX_FIFO_DEPTH - tx_limit; + } else { + tx_limit = 0; + } + rx_limit = task->rx_cmd_sent - task->rx_pos + 1; + if (rx_limit < I2CIP_RX_FIFO_DEPTH) { + rx_limit = I2CIP_RX_FIFO_DEPTH - rx_limit; + } else { + rx_limit = 0; + } + HAL_I2C_TRACE(6,"m_recv:txEmpty: tx_pos=%d tx_txn_len=%d rx_txn_len=%d cnt=%d tx_limit=%d rx_limit=%d", + task->tx_pos, task->tx_txn_len, task->rx_txn_len, task->txn_cnt, tx_limit, rx_limit); + if (tx_limit > rx_limit) { + tx_limit = rx_limit; + } + for (i = task->tx_pos, tx_cnt = 0; + ((i < total_tx_len) && (tx_cnt < tx_limit)); + ++i, ++tx_cnt) { + /* last byte : we need to decide stop */ + if (i == (total_tx_len - 1)) { + stop = task->stop ? I2CIP_CMD_DATA_STOP_MASK : 0; + } else { + stop = 0; + } + if (task->txn_cnt == 1) { + txn_idx = 0; + txn_pos = i; + } else { + txn_idx = i / (task->tx_txn_len + task->rx_txn_len); + txn_pos = i % (task->tx_txn_len + task->rx_txn_len); + } + /* first byte : need to decide restart */ + if (i && task->restart_after_write && (txn_pos == 0 || txn_pos == task->tx_txn_len)) { + restart = I2CIP_CMD_DATA_RESTART_MASK; + } else { + restart = 0; + } + /* real write data */ + if (txn_pos < task->tx_txn_len) { + if (task->txn_cnt == 1) { + data = task->tx_buf[txn_pos]; + } else { + data = task->tx_buf[txn_idx * task->tx_txn_len + txn_pos]; + } + } else { + data = I2CIP_CMD_DATA_CMD_READ_MASK; + task->rx_cmd_sent++; + } + + i2cip_w_cmd_data(reg_base, data | restart | stop); + HAL_I2C_TRACE(4,"m_recv:tx: data[%u]=0x%02X restart=0x%X stop=0x%X", + i, data, restart, stop); + } + + task->tx_pos = i; + + /* all write action done */ + if (task->tx_pos == total_tx_len) { + i2cip_clear_int_mask(reg_base, I2CIP_INT_MASK_TX_EMPTY_MASK); + } + } + } + + /* stop condition : need to read out all rx fifo */ + if (task->state & HAL_I2C_SM_TASK_STATE_STOP) { + if (hal_i2c_sm[id].cfg.use_dma) { +#ifdef I2C_USE_DMA + if (hal_i2c_sm[id].rx_dma_cfg.ch == HAL_DMA_CHAN_NONE) { + HAL_I2C_TRACE(0,"m_recv:stop:WARNING: bad rx dma chan!"); + } else { + if (hal_dma_chan_busy(hal_i2c_sm[id].rx_dma_cfg.ch)) { + HAL_I2C_TRACE(0,"m_recv:stop:WARNING: rx dma not finished yet!"); + } + } +#endif + } else { + rx_limit = i2cip_r_rx_fifo_level(reg_base); + HAL_I2C_TRACE(1,"m_recv:stop: rx_limit=%d", rx_limit); + for (i = task->rx_pos, rx_cnt = 0; + ((rx_cnt < rx_limit) && (i < task->rx_txn_len)); + ++i, ++rx_cnt) { + task->rx_buf[i] = i2cip_r_cmd_data(reg_base); + HAL_I2C_TRACE(2,"m_recv:stop: rx_buf[%d] 0x%X", i, task->rx_buf[i]); + } + task->rx_pos = i; + if (task->rx_pos != task->rx_txn_len * task->txn_cnt) { + HAL_I2C_TRACE(3,"m_recv:stop:WARNING: rx_pos(%u) != rx_txn_len(%u) * txn_cnt(%u)", task->rx_pos, task->rx_txn_len, task->txn_cnt); + } + } + hal_i2c_sm_done_task(id); + hal_i2c_sm_next_task(id); + } + break; + } + default: + break; + } +} + +void hal_i2c_irq_handler(void) +{ + enum HAL_I2C_ID_T id; + + for (id = HAL_I2C_ID_0; id < HAL_I2C_ID_NUM; id++) { + if (NVIC_GetActive(i2c_desc[id].irq)) { + hal_i2c_sm_proc(id); + } + } +} +#endif + +#ifdef I2C_SIMPLE_MODE +void hal_i2c_irq_handler_s(void) +{ + enum HAL_I2C_ID_T id; + + for (id = HAL_I2C_ID_0; id < HAL_I2C_ID_NUM; id++) { + if (NVIC_GetActive(i2c_desc[id].irq)) { + hal_i2c_simple_proc(id); + } + } +} +#endif + +#ifdef I2C_SENSOR_ENGINE +void hal_i2c_irq_handler_sensor_eng(void) +{ + enum HAL_I2C_ID_T id; + + for (id = HAL_I2C_ID_0; id < HAL_I2C_ID_NUM; id++) { + if (NVIC_GetActive(i2c_desc[id].irq)) { + hal_i2c_sensor_eng_proc(id); + } + } +} +#endif + +static int POSSIBLY_UNUSED hal_i2c_nvic_setup_irq(enum HAL_I2C_ID_T id, uint32_t handler) +{ + IRQn_Type irqt = i2c_desc[id].irq; + + NVIC_SetVector(irqt, handler); + NVIC_SetPriority(irqt, IRQ_PRIORITY_NORMAL); + return 0; +} + +static int hal_i2c_nvic_enable_irq(enum HAL_I2C_ID_T id, int enabled) +{ + IRQn_Type irqt = i2c_desc[id].irq; + + if (enabled) { + NVIC_ClearPendingIRQ(irqt); + NVIC_EnableIRQ(irqt); + } else { + NVIC_DisableIRQ(irqt); + NVIC_ClearPendingIRQ(irqt); + } + return 0; +} + +uint32_t hal_i2c_open(enum HAL_I2C_ID_T id, const struct HAL_I2C_CONFIG_T *cfg) +{ + uint32_t reg_base; + + ASSERT(id < HAL_I2C_ID_NUM, invalid_id, id); + + if (hal_i2c_sm[id].state != HAL_I2C_SM_CLOSED) { + return HAL_I2C_ERRCODE_IN_USE; + } + + hal_i2c_sm_init(id, cfg); + + hal_cmu_clock_enable(i2c_desc[id].mod); + hal_cmu_clock_enable(i2c_desc[id].apb); + hal_cmu_reset_clear(i2c_desc[id].mod); + hal_cmu_reset_clear(i2c_desc[id].apb); + + reg_base = _i2c_get_base(id); + HAL_I2C_TRACE(2,"i2c id=%d reg_base=0x%X", id, reg_base); + + i2cip_w_enable(reg_base, HAL_I2C_NO); + + i2cip_w_target_address(reg_base, 0x18); + + /* clear */ + i2cip_w_clear_ctrl(reg_base); + + /* as master */ + if (cfg->as_master) { + i2cip_w_disable_slave(reg_base, HAL_I2C_YES); + i2cip_w_master_mode(reg_base, HAL_I2C_YES); + } else { + i2cip_w_disable_slave(reg_base, HAL_I2C_NO); + i2cip_w_master_mode(reg_base, HAL_I2C_NO); + + /* address as slave */ + i2cip_w_address_as_slave(reg_base, cfg->addr_as_slave); + } + + /* speed */ + _i2c_set_bus_speed(id, cfg->speed); + if (0) { +#ifdef I2C_SIMPLE_MODE + } else if (cfg->mode == HAL_I2C_API_MODE_SIMPLE) { + HAL_I2C_TRACE(0,"simple mode"); + hal_i2c_nvic_setup_irq(id, (uint32_t)hal_i2c_irq_handler_s); + + /* only open slave related int, polling in master */ + /* read req (master read us), rx full (master write us) */ + if (cfg->as_master) { + i2cip_init_int_mask(reg_base, I2CIP_INT_UNMASK_ALL); + } else { + i2cip_init_int_mask(reg_base, I2CIP_INT_MASK_RD_REQ_MASK|I2CIP_INT_MASK_RX_FULL_MASK); + } + + /* rx threshold, 1 byte trigger RX_FULL */ + i2cip_w_rx_threshold(reg_base, I2CIP_RX_TL_1_BYTE); + + /* tx threshold, 1 byte trigger TX_EMPTY */ + i2cip_w_tx_threshold(reg_base, I2CIP_TX_TL_1_BYTE); + + /* enable restart */ + i2cip_w_restart(reg_base, HAL_I2C_YES); + + /* enable i2c */ + i2cip_w_enable(reg_base, HAL_I2C_YES); +#endif +#ifdef I2C_TASK_MODE + } else if (cfg->mode == HAL_I2C_API_MODE_TASK) { + /* only use task irq handler when master mode */ + HAL_I2C_TRACE(0,"task mode"); + if (!cfg->as_master) { + HAL_I2C_TRACE(0,"not as master"); + return HAL_I2C_ERRCODE_INV_PARAM; + } +#ifndef I2C_USE_DMA + if (cfg->use_dma) { + HAL_I2C_TRACE(0,"using DMA when I2C_USE_DMA is NOT enabled"); + return HAL_I2C_ERRCODE_INV_PARAM; + } +#endif + + hal_i2c_nvic_setup_irq(id, (uint32_t)hal_i2c_irq_handler); +#endif +#ifdef I2C_SENSOR_ENGINE + } else if (cfg->mode == HAL_I2C_API_MODE_SENSOR_ENGINE) { + HAL_I2C_TRACE(0,"sensor engine mode"); + ASSERT(cfg->as_master, "%s: i2c master should be used with sensor engine", __FUNCTION__); + ASSERT(cfg->use_dma, "%s: i2c dma should be used with sensor engine", __FUNCTION__); + + hal_i2c_nvic_setup_irq(id, (uint32_t)hal_i2c_irq_handler_sensor_eng); +#endif + } else { + ASSERT(false, "%s: Bad i2c api mode: %u", __FUNCTION__, cfg->mode); + } + + hal_i2c_nvic_enable_irq(id, HAL_I2C_YES); + + return 0; +} + +uint32_t hal_i2c_close(enum HAL_I2C_ID_T id) +{ + uint32_t reg_base; + ASSERT(id < HAL_I2C_ID_NUM, invalid_id, id); + + if (hal_i2c_sm[id].state == HAL_I2C_SM_CLOSED) { + return 0; + } + + reg_base = _i2c_get_base(id); + + hal_i2c_nvic_enable_irq(id, HAL_I2C_NO); + i2cip_w_enable(reg_base, HAL_I2C_NO); + +#if defined(I2C_TASK_MODE) || defined(I2C_SENSOR_ENGINE) +#ifdef I2C_USE_DMA + hal_i2c_dma_release(id); +#endif +#endif + + hal_cmu_reset_set(i2c_desc[id].apb); + hal_cmu_reset_set(i2c_desc[id].mod); + hal_cmu_clock_disable(i2c_desc[id].apb); + hal_cmu_clock_disable(i2c_desc[id].mod); + + hal_i2c_sm[id].state = HAL_I2C_SM_CLOSED; + + return 0; +} + +/* task mode */ +#ifdef I2C_TASK_MODE +uint32_t hal_i2c_task_msend(enum HAL_I2C_ID_T id, uint16_t device_addr, + const uint8_t *tx_buf, uint16_t tx_item_len, + uint16_t item_cnt, uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler) +{ + uint32_t task_idx; + ASSERT(id < HAL_I2C_ID_NUM, invalid_id, id); + + if (hal_i2c_sm[id].cfg.mode != HAL_I2C_API_MODE_TASK) { + HAL_I2C_TRACE(0,"send: not task mode"); + return HAL_I2C_ERRCODE_INV_PARAM; + } + + task_idx = hal_i2c_sm_commit(id, tx_buf, tx_item_len, NULL, 0, item_cnt, + device_addr, HAL_I2C_SM_TASK_ACTION_M_SEND, + transfer_id, handler); + + hal_i2c_sm_kickoff(id); + return hal_i2c_sm_wait_task_if_need(id, task_idx, HAL_I2C_SYNC_TM_MS); +} + +uint32_t hal_i2c_task_send(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_len, + uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler) +{ + return hal_i2c_task_msend(id, device_addr, tx_buf, tx_len, 1, transfer_id, handler); +} + +uint32_t hal_i2c_task_mrecv(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_item_len, + uint8_t *rx_buf, uint16_t rx_item_len, uint16_t item_cnt, + uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler) +{ + uint32_t task_idx; + ASSERT(id < HAL_I2C_ID_NUM, invalid_id, id); + + if (hal_i2c_sm[id].cfg.mode != HAL_I2C_API_MODE_TASK) { + HAL_I2C_TRACE(0,"recv: not task mode"); + return HAL_I2C_ERRCODE_INV_PARAM; + } + + task_idx = hal_i2c_sm_commit(id, tx_buf, tx_item_len, rx_buf, rx_item_len, item_cnt, + device_addr, HAL_I2C_SM_TASK_ACTION_M_RECV, + transfer_id, handler); + + hal_i2c_sm_kickoff(id); + return hal_i2c_sm_wait_task_if_need(id, task_idx, HAL_I2C_SYNC_TM_MS); +} + +uint32_t hal_i2c_task_recv(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_len, + uint8_t *rx_buf, uint16_t rx_len, + uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler) +{ + return hal_i2c_task_mrecv(id, device_addr, tx_buf, tx_len, rx_buf, rx_len, 1, transfer_id, handler); +} + +uint32_t hal_i2c_send(enum HAL_I2C_ID_T id, uint32_t device_addr, uint8_t *buf, uint32_t reg_len, uint32_t value_len, + uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler) +{ + return hal_i2c_task_send(id, device_addr, buf, reg_len + value_len, transfer_id, handler); +} + +uint32_t hal_i2c_recv(enum HAL_I2C_ID_T id, uint32_t device_addr, uint8_t *buf, uint32_t reg_len, uint32_t value_len, + uint8_t restart_after_write, uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler) +{ + return hal_i2c_task_recv(id, device_addr, buf, reg_len, buf + reg_len, value_len, transfer_id, handler); +} +#endif +/* task mode end */ + +/* simple mode */ +#ifdef I2C_SIMPLE_MODE +static void hal_i2c_simple_proc(enum HAL_I2C_ID_T id) +{ + uint32_t reg_base = _i2c_get_base(id); + uint32_t irq_status = i2cip_r_raw_int_status(reg_base); + uint32_t abt_source = i2cip_r_tx_abrt_source(reg_base); + HAL_I2C_INT_HANDLER_T h = hal_i2c_int_handlers[id]; + + i2cip_r_clr_all_intr(reg_base); + + if (h) { + HAL_I2C_TRACE(3,"%s:irq=0x%X abt=0x%X", __func__, irq_status, abt_source); + h(id, irq_status, abt_source); + } + + // TODO: clean irq after callback done ? + i2cip_r_clr_all_intr(reg_base); + + HAL_I2C_TRACE(3,"%s:0x%X 0x%X", __func__, + i2cip_r_status(reg_base), i2cip_r_raw_int_status(reg_base)); +} + +static uint32_t _i2c_check_tx_abrt_error(enum HAL_I2C_ID_T id) +{ + uint32_t reg_base = _i2c_get_base(id); + + if (i2cip_r_raw_int_status(reg_base) & I2CIP_RAW_INT_STATUS_TX_ABRT_MASK) + return i2cip_r_tx_abrt_source(reg_base); + + return 0; +} + +uint32_t hal_i2c_slv_write(enum HAL_I2C_ID_T id, uint8_t *buf, uint32_t len, uint32_t *act_write) +{ + uint32_t reg_base = 0, i = 0, ret = 0; + + reg_base = _i2c_get_base(id); + + *act_write = 0; + + for (i = 0; i < len;) { + /* Tx Fifo Not Full */ + if (i2cip_r_status(reg_base) & I2CIP_STATUS_TFNF_MASK) { + i2cip_w_cmd_data(reg_base, buf[i]); + ++(*act_write); + ++i; + } + else { + /* wait for TFNF & not rx done & no error */ + while(!(i2cip_r_status(reg_base) & I2CIP_STATUS_TFNF_MASK) + && !(i2cip_r_raw_int_status(reg_base) & I2CIP_RAW_INT_STATUS_RX_DONE_MASK) + && !(ret = _i2c_check_tx_abrt_error(reg_base))); + + if (ret || (i2cip_r_raw_int_status(reg_base) & I2CIP_RAW_INT_STATUS_RX_DONE_MASK)) + break; + } + } + + /* FIXME : tx empty is not end of transmit, i2cip may transmit the last byte */ + while(!(i2cip_r_status(reg_base) & I2CIP_STATUS_TFE_SHIFT) + && !(ret = _i2c_check_tx_abrt_error(reg_base))); + + /* wait to idle */ + /* FIXME : time out */ + while(i2cip_r_status(reg_base) & I2CIP_STATUS_ACT_MASK); + + return ret; +} + +uint32_t hal_i2c_slv_read(enum HAL_I2C_ID_T id, uint8_t *buf, uint32_t len, uint32_t *act_read) +{ + uint32_t reg_base = 0, i = 0, ret = 0, depth = 0; + + reg_base = _i2c_get_base(id); + + *act_read = 0; + /* slave mode : just read */ + for (i = 0; i < len;) { + /* Rx Fifo Not Empty */ + if (i2cip_r_status(reg_base) & I2CIP_STATUS_RFNE_MASK) { + buf[i] = i2cip_r_cmd_data(reg_base); + ++(*act_read); + ++i; + } + else { + /* wait for RFNE & no stop & no error */ + while(!(i2cip_r_status(reg_base) & I2CIP_STATUS_RFNE_MASK) + && !(i2cip_r_raw_int_status(reg_base) & I2CIP_RAW_INT_STATUS_STOP_DET_MASK) + && !(ret = _i2c_check_tx_abrt_error(reg_base))) { + } + + if (ret || (i2cip_r_raw_int_status(reg_base) & I2CIP_RAW_INT_STATUS_STOP_DET_MASK)) { + HAL_I2C_TRACE(2,"drv:i2c slave read ret 0x%X, raw status 0x%X", ret, i2cip_r_raw_int_status(reg_base)); + break; + } + } + } + + /* may left some bytes in rx fifo */ + depth = i2cip_r_rx_fifo_level(reg_base); + HAL_I2C_TRACE(1,"drv:i2c slave read depth %d", depth); + while (depth > 0 && i < len) { + buf[i] = i2cip_r_cmd_data(reg_base); + ++(*act_read); + ++i; + --depth; + } + + /* wait to idle */ + while(i2cip_r_status(reg_base) & I2CIP_STATUS_ACT_MASK); + + return 0; +} + +static void i2c_clear_special_tx_abrt(uint32_t reg_base) +{ + uint32_t abrt = i2cip_r_tx_abrt_source(reg_base); + + i2cip_r_clr_tx_abrt(reg_base); + + if (abrt & I2CIP_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT_MASK) { + i2cip_w_restart(reg_base, HAL_I2C_YES); + i2cip_w_special_bit(reg_base, HAL_I2C_NO); + i2cip_w_gc_or_start_bit(reg_base, HAL_I2C_NO); + i2cip_r_clr_tx_abrt(reg_base); + } +} + +static uint32_t _i2c_check_raw_int_status(uint32_t reg_base, uint32_t mask) +{ + uint32_t regval = i2cip_r_raw_int_status(reg_base); + + HAL_I2C_TRACE(3,"%s: raw status=0x%X mask=0x%X", __func__, regval, mask); + return regval & mask; +} + +uint32_t hal_i2c_mst_write(enum HAL_I2C_ID_T id, uint32_t dev_addr, + const uint8_t *buf, uint32_t len, uint32_t *act_write, + uint32_t restart, uint32_t stop, uint32_t yield) +{ + uint32_t i, tar, wrcnt, ret = 0; + uint32_t reg_base; + uint32_t start_time, timeout; + uint32_t res, sto; + + ASSERT(id < HAL_I2C_ID_NUM, invalid_id, id); + + if (hal_i2c_sm[id].cfg.mode != HAL_I2C_API_MODE_SIMPLE) { + HAL_I2C_TRACE(0,"mst_write: not simple mode"); + return HAL_I2C_ERRCODE_INV_PARAM; + } + + HAL_I2C_TRACE(7,"%s:id=%d addr=0x%02X buf=0x%X len=%d res=%d sto=%d", + __func__, id, dev_addr, (int)buf, len, restart, stop); + + reg_base = _i2c_get_base(id); + + //update TAR + tar = i2cip_r_target_address_reg(reg_base); + if (tar != dev_addr) { + timeout = MS_TO_TICKS(HAL_I2C_WAIT_ACT_MS); + start_time = hal_sys_timer_get(); + while((i2cip_r_status(reg_base) & I2CIP_STATUS_ACT_MASK)) { + if (hal_sys_timer_get() - start_time >= timeout) { + HAL_I2C_TRACE(1,"%s:wait bus idle timeout", __func__); + ret = HAL_I2C_ERRCODE_ACT_TIMEOUT; + goto exit; + } + if (yield) { + hal_i2c_delay_ms(HAL_I2C_DLY_MS); + } + } + + i2cip_w_enable(reg_base, HAL_I2C_NO); + i2cip_w_target_address(reg_base, dev_addr); + i2cip_w_enable(reg_base, HAL_I2C_YES); + HAL_I2C_TRACE(3,"%s:update tar to 0x%02X from 0x%02X", __func__, dev_addr, tar); + } + + // check error + if (_i2c_check_raw_int_status(reg_base, I2CIP_RAW_INT_STATUS_TX_ABRT_MASK + | I2CIP_RAW_INT_STATUS_TX_OVER_MASK + | I2CIP_RAW_INT_STATUS_RX_OVER_MASK + | I2CIP_RAW_INT_STATUS_RX_UNDER_MASK)) { + i2cip_r_clr_all_intr(reg_base); + i2c_clear_special_tx_abrt(reg_base); + HAL_I2C_TRACE(1,"clear error status done before xfer: status=0x%X", + i2cip_r_raw_int_status(reg_base)); + } + + // start to transmit + wrcnt = 0; + for (i = 0; i < len; i++) { + if (i == 0) { + res = restart ? I2CIP_CMD_DATA_RESTART_MASK : 0; + } else { + res = 0; + } + if (i == (len - 1)) { + sto = stop ? I2CIP_CMD_DATA_STOP_MASK : 0; + } else { + sto = 0; + } + + timeout = MS_TO_TICKS(HAL_I2C_WAIT_TFNF_MS); + start_time = hal_sys_timer_get(); + while (!(i2cip_r_status(reg_base) & I2CIP_STATUS_TFNF_MASK)) { + ret = _i2c_check_raw_int_status(reg_base, I2CIP_RAW_INT_STATUS_TX_ABRT_MASK); + if (ret) { + i2c_clear_special_tx_abrt(reg_base); + HAL_I2C_TRACE(2,"%s:error 0x%X", __func__, ret); + goto exit; + } + if (hal_sys_timer_get() - start_time >= timeout) { + HAL_I2C_TRACE(1,"%s:wait tfnf timeout", __func__); + ret = HAL_I2C_ERRCODE_TFNF_TIMEOUT; + goto exit; + } + if (yield) { + hal_i2c_delay_ms(HAL_I2C_DLY_MS); + } + } + i2cip_w_cmd_data(reg_base, buf[i] | res | sto + | I2CIP_CMD_DATA_CMD_WRITE_MASK); + + HAL_I2C_TRACE(4,"send write cmd: data[%d]=0x%02X res=0x%X sto=0x%X", i, buf[i], res, sto); + wrcnt++; + } + + if (act_write) + *act_write = wrcnt; + + if (stop) { + // wait bus idle + timeout = MS_TO_TICKS(HAL_I2C_WAIT_ACT_MS); + start_time = hal_sys_timer_get(); + while (i2cip_r_status(reg_base) & I2CIP_STATUS_ACT_MASK) { + if (hal_sys_timer_get() - start_time >= timeout) { + if (_i2c_check_raw_int_status(reg_base, I2CIP_RAW_INT_STATUS_TX_ABRT_MASK)) { + i2cip_r_clr_all_intr(reg_base); + i2c_clear_special_tx_abrt(reg_base); + HAL_I2C_TRACE(0,"clear error status done after xfer"); + } + HAL_I2C_TRACE(1,"%s:wait act timeout", __func__); + ret = HAL_I2C_ERRCODE_ACT_TIMEOUT; + goto exit; + } + if (yield) { + hal_i2c_delay_ms(HAL_I2C_DLY_MS); + } + } + } else { + // wait until txfifo empty + timeout = MS_TO_TICKS(HAL_I2C_WAIT_TFE_MS); + start_time = hal_sys_timer_get(); + while(!(i2cip_r_status(reg_base) & I2CIP_STATUS_TFE_MASK)) { + if (hal_sys_timer_get() - start_time >= timeout) { + HAL_I2C_TRACE(1,"%s:wait tfe timeout", __func__); + ret = HAL_I2C_ERRCODE_TFE_TIMEOUT; + goto exit; + } + if (yield) { + hal_i2c_delay_ms(HAL_I2C_DLY_MS); + } + } + } + + HAL_I2C_TRACE(1,"%s:done", __func__); + return 0; +exit: + HAL_I2C_TRACE(3,"%s:error=0x%X, status=0x%X", __func__, ret, + i2cip_r_raw_int_status(reg_base)); + return ret; +} + +uint32_t hal_i2c_mst_read(enum HAL_I2C_ID_T id, uint32_t dev_addr, + uint8_t *buf, uint32_t len, uint32_t *act_read, + uint32_t restart, uint32_t stop, uint32_t yield) +{ + uint32_t i, j, tar, rdcnt, wrcnt, ret = 0; + uint32_t reg_base; + uint32_t start_time, timeout; + uint32_t res, sto; + uint8_t tmp; + uint8_t rx_ongoing, tx_limit; + + ASSERT(id < HAL_I2C_ID_NUM, invalid_id, id); + + if (hal_i2c_sm[id].cfg.mode != HAL_I2C_API_MODE_SIMPLE) { + HAL_I2C_TRACE(0,"mst_read: not simple mode"); + return HAL_I2C_ERRCODE_INV_PARAM; + } + + HAL_I2C_TRACE(7,"%s:id=%d addr=0x%02X buf=0x%X len=%d res=%d sto=%d", + __func__, id, dev_addr, (int)buf, len, restart, stop); + + reg_base = _i2c_get_base(id); + + // update TAR + tar = i2cip_r_target_address_reg(reg_base); + if (tar != dev_addr) { + timeout = MS_TO_TICKS(HAL_I2C_WAIT_ACT_MS); + start_time = hal_sys_timer_get(); + while((i2cip_r_status(reg_base) & I2CIP_STATUS_ACT_MASK)) { + if (hal_sys_timer_get() - start_time >= timeout) { + HAL_I2C_TRACE(1,"%s:wait bus idle timeout", __func__); + ret = HAL_I2C_ERRCODE_ACT_TIMEOUT; + goto exit; + } + if (yield) { + hal_i2c_delay_ms(HAL_I2C_DLY_MS); + } + } + + i2cip_w_enable(reg_base, HAL_I2C_NO); + i2cip_w_target_address(reg_base, dev_addr); + i2cip_w_enable(reg_base, HAL_I2C_YES); + HAL_I2C_TRACE(3,"%s:update tar to 0x%02X from 0x%02X", __func__, dev_addr, tar); + } + + // clear fifo by reading + j = i2cip_r_rx_fifo_level(reg_base); + if (j) { + for (i = 0;i < j; i++) { + tmp = i2cip_r_cmd_data(reg_base); + HAL_I2C_TRACE(2,"%s:discard data 0x%02X", __func__, tmp); + } + } + + // check error + if (_i2c_check_raw_int_status(reg_base, I2CIP_RAW_INT_STATUS_TX_ABRT_MASK + | I2CIP_RAW_INT_STATUS_TX_OVER_MASK + | I2CIP_RAW_INT_STATUS_RX_OVER_MASK + | I2CIP_RAW_INT_STATUS_RX_UNDER_MASK)) { + i2cip_r_clr_all_intr(reg_base); + i2c_clear_special_tx_abrt(reg_base); + HAL_I2C_TRACE(1,"clear error status done before xfer, status=0x%X", + i2cip_r_raw_int_status(reg_base)); + } + + // read data + timeout = MS_TO_TICKS(HAL_I2C_WAIT_RFNE_MS); + start_time = hal_sys_timer_get(); + wrcnt = 0; + rdcnt = 0; + while(rdcnt < len) { + // send reading cmd + rx_ongoing = i2cip_r_tx_fifo_level(reg_base) + i2cip_r_rx_fifo_level(reg_base) + 1; + if (rx_ongoing < I2CIP_RX_FIFO_DEPTH) { + tx_limit = I2CIP_RX_FIFO_DEPTH - rx_ongoing; + } else { + tx_limit = 0; + } + + for(i = 0; i < tx_limit && wrcnt < len; i++, wrcnt++) { + if (!(i2cip_r_status(reg_base) & I2CIP_STATUS_TFNF_MASK)) { + break; + } + if (wrcnt == 0) { + res = restart ? I2CIP_CMD_DATA_RESTART_MASK : 0; + } else { + res = 0; + } + if (wrcnt == len - 1) { + sto = stop ? I2CIP_CMD_DATA_STOP_MASK : 0; + } else { + sto = 0; + } + + i2cip_w_cmd_data(reg_base, I2CIP_CMD_DATA_CMD_READ_MASK | res | sto); + HAL_I2C_TRACE(3,"send read cmd: [%u] res=0x%X, sto=0x%X", wrcnt, res, sto); + } + + if (i2cip_r_status(reg_base) & I2CIP_STATUS_RFNE_MASK) { + tmp = i2cip_r_cmd_data(reg_base); + HAL_I2C_TRACE(2,"i2c recv [%u] 0x%02X", rdcnt, tmp); + if (buf) { + buf[rdcnt++] = tmp; + } + start_time = hal_sys_timer_get(); + } else { + if (hal_sys_timer_get() - start_time >= timeout) { + HAL_I2C_TRACE(1,"%s:wait rfne timeout", __func__); + ret = HAL_I2C_ERRCODE_RFNE_TIMEOUT; + goto exit; + } + if (yield) { + hal_i2c_delay_ms(HAL_I2C_DLY_MS); + } + } + } + + if (act_read) *act_read = rdcnt; + + if (stop) { + timeout = MS_TO_TICKS(HAL_I2C_WAIT_ACT_MS); + start_time = hal_sys_timer_get(); + while (i2cip_r_status(reg_base) & I2CIP_STATUS_ACT_MASK){ + if (hal_sys_timer_get() - start_time >= timeout) { + HAL_I2C_TRACE(1,"%s:wait act timeout", __func__); + ret = HAL_I2C_ERRCODE_ACT_TIMEOUT; + goto exit; + } + if (yield) { + hal_i2c_delay_ms(HAL_I2C_DLY_MS); + } + } + } + + HAL_I2C_TRACE(1,"%s:done", __func__); + return 0; +exit: + HAL_I2C_TRACE(3,"%s:error=0x%X, status=0x%X", __func__, ret, + i2cip_r_raw_int_status(reg_base)); + return ret; +} + +uint32_t hal_i2c_simple_send(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_len) +{ + return hal_i2c_mst_write(id, device_addr, tx_buf, tx_len, NULL, true, true, false); +} + +uint32_t hal_i2c_simple_recv(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_len, uint8_t *rx_buf, uint16_t rx_len) +{ + int ret; + + ret = hal_i2c_mst_write(id, device_addr, tx_buf, tx_len, NULL, true, false, false); + if (ret) { + HAL_I2C_TRACE(2,"%s: mst_write failed: ret=%d", __func__, ret); + return ret; + } + + return hal_i2c_mst_read(id, device_addr, rx_buf, rx_len, NULL, true, true, false); +} + +uint32_t hal_i2c_set_interrupt_handler(enum HAL_I2C_ID_T id, HAL_I2C_INT_HANDLER_T handler) +{ + hal_i2c_int_handlers[id] = handler; + return 0; +} +#endif +/* simple mode end */ + +/* sensor engine mode */ +#ifdef I2C_SENSOR_ENGINE +static void hal_i2c_sensor_eng_proc(enum HAL_I2C_ID_T id) +{ + HAL_I2C_TRACE(2,"%s: id=%d", __func__, id); + + uint32_t reg_base = _i2c_get_base(id); + uint32_t irq_status = i2cip_r_int_status(reg_base); + uint32_t POSSIBLY_UNUSED irq_raw_status = i2cip_r_raw_int_status(reg_base); + uint32_t abt_source = i2cip_r_tx_abrt_source(reg_base); + enum HAL_I2C_SM_TASK_STATE_T task_state; + + task_state = _i2c_chk_clr_task_error(reg_base, irq_status, abt_source); + + HAL_I2C_TRACE(5,"%s: id=%d irq=0x%X/0x%X abt=0x%X", __func__, id, irq_status, irq_raw_status, abt_source); + _i2c_show_error_code(abt_source); + + if (task_state & (HAL_I2C_SM_TASK_STATE_TX_ABRT | HAL_I2C_SM_TASK_STATE_FIFO_ERR)) { + HAL_I2C_ERROR(6,"*** Error:%s: id=%d task_state=0x%X irq=0x%X/0x%X abt=0x%X", __func__, id, task_state, irq_status, irq_raw_status, abt_source); + hal_i2c_sensor_engine_stop(i2c_sensor_id[id]); + } +} + +static void _sensor_irq_handler(enum HAL_SENSOR_ENGINE_ID_T id, enum HAL_SENSOR_ENGINE_DEVICE_T device, const uint8_t *buf, uint32_t len) +{ + enum HAL_I2C_ID_T i2c_id; + + i2c_id = HAL_I2C_ID_0 + (device - HAL_SENSOR_ENGINE_DEVICE_I2C0); + ASSERT(i2c_id < HAL_I2C_ID_NUM, invalid_id, i2c_id); + + if (i2c_sensor_handler[i2c_id]) { + i2c_sensor_handler[i2c_id](i2c_id, buf, len); + } +} + +uint32_t hal_i2c_sensor_engine_start(enum HAL_I2C_ID_T id, const struct HAL_I2C_SENSOR_ENGINE_CONFIG_T *cfg) +{ + enum HAL_I2C_SM_TASK_ACTION_T action; + const struct HAL_I2C_SM_TASK_T *out_task; + struct HAL_SENSOR_ENGINE_CFG_T sensor_cfg; + uint32_t reg_base; + + HAL_I2C_ERROR(2,"%s: id=%d", __func__, id); + ASSERT(id < HAL_I2C_ID_NUM, invalid_id, id); + + if (hal_i2c_sm[id].cfg.mode != HAL_I2C_API_MODE_SENSOR_ENGINE) { + HAL_I2C_TRACE(1,"i2c-se start: not sensor engine mode: %d", hal_i2c_sm[id].cfg.mode); + return HAL_I2C_ERRCODE_INV_PARAM; + } + if (hal_i2c_sm[id].state != HAL_I2C_SM_IDLE) { + HAL_I2C_TRACE(1,"i2c-se start: not idle: %d", hal_i2c_sm[id].state); + return HAL_I2C_ERRCODE_INV_PARAM; + } + + reg_base = _i2c_get_base(id); + action = HAL_I2C_SM_TASK_ACTION_M_RECV; + + hal_i2c_sm[id].state = HAL_I2C_SM_RUNNING; + + hal_i2c_sm_commit(id, cfg->write_buf, cfg->write_txn_len, + cfg->read_buf, cfg->read_txn_len, cfg->txn_cnt, + cfg->target_addr, action, 0, NULL); + + out_task = &(hal_i2c_sm[id].task[hal_i2c_sm[id].out_task]); + hal_i2c_dma_config(id, out_task); + + i2c_sensor_id[id] = cfg->id; + i2c_sensor_handler[id] = cfg->handler; + + memset(&sensor_cfg, 0, sizeof(sensor_cfg)); + sensor_cfg.id = cfg->id; + sensor_cfg.device = (id == HAL_I2C_ID_0) ? HAL_SENSOR_ENGINE_DEVICE_I2C0 : HAL_SENSOR_ENGINE_DEVICE_I2C1; + sensor_cfg.trigger_type = cfg->trigger_type; + sensor_cfg.trigger_gpio = cfg->trigger_gpio; + sensor_cfg.period_us = cfg->period_us; + sensor_cfg.device_address = cfg->target_addr; + sensor_cfg.tx_dma_cfg = &hal_i2c_sm[id].tx_dma_cfg; + sensor_cfg.rx_dma_cfg = &hal_i2c_sm[id].rx_dma_cfg; + sensor_cfg.rx_burst_len = cfg->read_txn_len * cfg->txn_cnt; + sensor_cfg.rx_burst_cnt = cfg->read_burst_cnt; + sensor_cfg.handler = _sensor_irq_handler;; +#ifdef I2C_VAD + sensor_cfg.data_to_vad = 1; + i2cip_w_data_to_vad(reg_base, HAL_I2C_YES); +#endif + + hal_sensor_engine_open(&sensor_cfg); + + /* tx : quarter trigger TX EMPTY INT */ + i2cip_w_tx_threshold(reg_base, HAL_I2C_TX_TL); + if (action == HAL_I2C_SM_TASK_ACTION_M_RECV) { + /* rx : three quarter trigger RX FULL INT */ + i2cip_w_rx_threshold(reg_base, HAL_I2C_RX_TL); + } + + i2cip_init_int_mask(reg_base, I2CIP_INT_MASK_ERROR_MASK); + + i2cip_w_restart(reg_base, HAL_I2C_YES); + i2cip_w_target_address(reg_base, out_task->target_addr); + + return 0; +} + +uint32_t hal_i2c_sensor_engine_stop(enum HAL_I2C_ID_T id) +{ + uint32_t reg_base; + uint32_t irq_status; + uint32_t abt_source; + + HAL_I2C_ERROR(2,"%s: id=%d", __func__, id); + ASSERT(id < HAL_I2C_ID_NUM, invalid_id, id); + + if (hal_i2c_sm[id].cfg.mode != HAL_I2C_API_MODE_SENSOR_ENGINE) { + HAL_I2C_TRACE(1,"i2c-se stop: not sensor engine mode: %d", hal_i2c_sm[id].cfg.mode); + return HAL_I2C_ERRCODE_INV_PARAM; + } + if (hal_i2c_sm[id].state != HAL_I2C_SM_RUNNING) { + HAL_I2C_TRACE(1,"i2c-se stop: not running: %d", hal_i2c_sm[id].state); + return HAL_I2C_ERRCODE_INV_PARAM; + } + + hal_sensor_engine_close(i2c_sensor_id[id]); + + hal_i2c_dma_release(id); + + reg_base = _i2c_get_base(id); + + HAL_I2C_TRACE(0,"disable i2c"); + i2cip_w_enable(reg_base, HAL_I2C_NO); + + irq_status = i2cip_r_int_status(reg_base); + abt_source = i2cip_r_tx_abrt_source(reg_base); + _i2c_chk_clr_task_error(reg_base, irq_status, abt_source); + +#ifdef I2C_VAD + i2cip_w_data_to_vad(reg_base, HAL_I2C_NO); +#endif + + hal_i2c_sm_done(id); + + return 0; +} +#endif +/* sensor engine mode end */ + +/* gpio iic mode */ +#include "hal_gpio.h" + +static uint8_t g_i2c_open = false; + +#define DURATION_INIT_1 600 +#define DURATION_INIT_2 600 +#define DURATION_INIT_3 600 + +#define DURATION_START_1 600 +#define DURATION_START_2 600 +#define DURATION_START_3 600 + +#define DURATION_STOP_1 800 +#define DURATION_STOP_2 600 +#define DURATION_STOP_3 1300 + +#define DURATION_HIGH 900 +#define DURATION_LOW 600 + +#define HAL_GPIO_I2C_DELAY(duration) hal_sys_timer_delay_ns(duration); + +struct HAL_GPIO_I2C_CONFIG_T hal_gpio_i2c_cfg; + +inline void GPIO_InitIO(uint8_t port, uint8_t direction, uint8_t val_for_out) +{ + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)port, (enum HAL_GPIO_DIR_T)direction, val_for_out); +} + +inline void GPIO_WriteIO(uint8_t port, uint8_t data) +{ + if(data){ + hal_gpio_pin_set((enum HAL_GPIO_PIN_T)port); + }else{ + hal_gpio_pin_clr((enum HAL_GPIO_PIN_T)port); + } +} +inline uint8_t GPIO_ReadIO(uint8_t port) +{ + uint8_t level = 0; + level = hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)port); + return level; +} + + +// +//------------------------------------------------------------------- +// Function: gpio_i2c_init +// Purpose: This function is used to init I2C port of the device +// In: +// Return: bool +//------------------------------------------------------------------- + + +static int hal_gpio_i2c_initialize(const struct HAL_GPIO_I2C_CONFIG_T *cfg) +{ + struct HAL_IOMUX_PIN_FUNCTION_MAP hal_gpio_i2c_iomux_cfg[] = { + {HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}, + {HAL_IOMUX_PIN_NUM, HAL_IOMUX_FUNC_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}, + }; + + hal_gpio_i2c_cfg.scl = cfg->scl; + hal_gpio_i2c_cfg.sda = cfg->sda; + hal_gpio_i2c_iomux_cfg[0].pin = (enum HAL_IOMUX_PIN_T)hal_gpio_i2c_cfg.scl; + hal_gpio_i2c_iomux_cfg[1].pin = (enum HAL_IOMUX_PIN_T)hal_gpio_i2c_cfg.sda; + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)hal_gpio_i2c_iomux_cfg, sizeof(hal_gpio_i2c_iomux_cfg)/sizeof(struct HAL_IOMUX_PIN_FUNCTION_MAP)); + + HAL_I2C_TRACE(2,"hal_gpio_i2c_initialize scl=%d sda=%d", hal_gpio_i2c_cfg.scl , hal_gpio_i2c_cfg.sda); + //iTemp = hal_gpio_i2c_cfg.scl | hal_gpio_i2c_cfg.sda ; + // Set the GPIO pin to output status + GPIO_InitIO(hal_gpio_i2c_cfg.scl, 1, 1); + GPIO_InitIO(hal_gpio_i2c_cfg.sda, 1, 1); + HAL_GPIO_I2C_DELAY(DURATION_INIT_1); + + // Make the I2C bus in idle status + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,1); + HAL_GPIO_I2C_DELAY(DURATION_INIT_1); + GPIO_WriteIO(hal_gpio_i2c_cfg.sda ,1); + HAL_GPIO_I2C_DELAY(DURATION_INIT_1); + + for(byte i=0;i<30;i++) + { + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,0); /* low */ + HAL_GPIO_I2C_DELAY(DURATION_LOW); + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,1); + HAL_GPIO_I2C_DELAY(DURATION_HIGH); + } + + return 0; +} + +static void hal_gpio_i2c_start(void) /* start or re-start */ +{ + GPIO_InitIO(hal_gpio_i2c_cfg.sda, 1, 1); + GPIO_WriteIO(hal_gpio_i2c_cfg.sda ,1); + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,1); + + HAL_GPIO_I2C_DELAY(DURATION_START_1); + GPIO_WriteIO(hal_gpio_i2c_cfg.sda ,0); + HAL_GPIO_I2C_DELAY(DURATION_START_2); + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,0); + HAL_GPIO_I2C_DELAY(DURATION_START_3);/* start condition */ +} + +static void hal_gpio_i2c_stop(void) +{ + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,0); + HAL_GPIO_I2C_DELAY(DURATION_LOW); + GPIO_InitIO(hal_gpio_i2c_cfg.sda, 1, 0); + GPIO_WriteIO(hal_gpio_i2c_cfg.sda ,0); + HAL_GPIO_I2C_DELAY(DURATION_STOP_1); + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,1); + HAL_GPIO_I2C_DELAY(DURATION_STOP_2); + GPIO_WriteIO(hal_gpio_i2c_cfg.sda ,1); /* stop condition */ + HAL_GPIO_I2C_DELAY(DURATION_STOP_3); +} + +static uint8_t hal_gpio_i2c_txbyte(uint8_t data) /* return 0 --> ack */ +{ + int i; + uint8_t temp_value = 0; + for(i=7; (i>=0)&&(i<=7); i--) + { + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,0); /* low */ + HAL_GPIO_I2C_DELAY(DURATION_LOW); + if(i==7)GPIO_InitIO(hal_gpio_i2c_cfg.sda, 1, 0); + HAL_GPIO_I2C_DELAY(DURATION_LOW); + + GPIO_WriteIO(hal_gpio_i2c_cfg.sda ,((data>>i)&0x01)); + HAL_GPIO_I2C_DELAY(DURATION_LOW/2); + GPIO_WriteIO(hal_gpio_i2c_cfg.scl, 1); /* high */ + HAL_GPIO_I2C_DELAY(DURATION_HIGH); + } + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,0); /* low */ + HAL_GPIO_I2C_DELAY(DURATION_LOW); + GPIO_InitIO(hal_gpio_i2c_cfg.sda, 0, 1);/* input */ + HAL_GPIO_I2C_DELAY(DURATION_LOW/2); + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,1); /* high */ + HAL_GPIO_I2C_DELAY(DURATION_HIGH); + temp_value = GPIO_ReadIO(hal_gpio_i2c_cfg.sda ); + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,0); /* low */ + HAL_GPIO_I2C_DELAY(DURATION_LOW); + return temp_value; +} + +static void hal_gpio_i2c_rxbyte(uint8_t *data, uint8_t ack) +{ + int i; + uint32_t dataCache; + + dataCache = 0; + for(i=7; (i>=0)&&(i<=7); i--) + { + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,0); + HAL_GPIO_I2C_DELAY(DURATION_LOW); + if(i==7)GPIO_InitIO(hal_gpio_i2c_cfg.sda, 0, 1); + HAL_GPIO_I2C_DELAY(DURATION_LOW); + GPIO_WriteIO(hal_gpio_i2c_cfg.scl,1); + HAL_GPIO_I2C_DELAY(DURATION_HIGH); + dataCache |= (GPIO_ReadIO(hal_gpio_i2c_cfg.sda )<> 7)); + hal_gpio_i2c_txbyte(device_addr & 0xFF); + } else { + hal_gpio_i2c_txbyte((device_addr & 0x7F) << 1); + } + for (i = 0; i < tx_len; i++, tx_buf++) { + hal_gpio_i2c_txbyte(*tx_buf); + } + hal_gpio_i2c_stop(); + + return 0; +} + +uint32_t hal_gpio_i2c_simple_recv(uint32_t device_addr, const uint8_t *tx_buf, uint16_t tx_len, uint8_t *rx_buf, uint16_t rx_len) +{ + uint8_t tempdata; + uint32_t i; + + if (tx_len) { + hal_gpio_i2c_start(); + if (device_addr & HAL_I2C_10BITADDR_MASK) { + hal_gpio_i2c_txbyte(((device_addr & 0x200) >> 7) | 0xF0); + hal_gpio_i2c_txbyte(device_addr & 0xFF); + } else { + hal_gpio_i2c_txbyte((device_addr & 0x7F) << 1); + } + for (i = 0; i < tx_len; i++, tx_buf++) { + hal_gpio_i2c_txbyte(*tx_buf); + } + } + + hal_gpio_i2c_start(); + if (device_addr & HAL_I2C_10BITADDR_MASK) { + hal_gpio_i2c_txbyte(((device_addr & 0x200) >> 7) | 0xF1); + } else { + hal_gpio_i2c_txbyte(((device_addr & 0x7F) << 1) | 1); + } + for (i = 0; i < rx_len; i++, rx_buf++) { + hal_gpio_i2c_rxbyte(&tempdata, (i == rx_len - 1)); + *rx_buf = tempdata; + } + hal_gpio_i2c_stop(); + + return 0; +} + +#define touch_ic_device_addr 0x60 +unsigned char I2C_WriteByte(unsigned char reg, unsigned char data) +{ + unsigned char result; + unsigned char buff[2]; + + buff[0] = reg; + buff[1] = data; + + result = hal_gpio_i2c_simple_send((unsigned char)touch_ic_device_addr,buff,2); + return result; +} + +unsigned char I2C_ReadByte(unsigned char reg, unsigned char* data) +{ + unsigned char result; + + result = hal_gpio_i2c_simple_recv((unsigned char)touch_ic_device_addr,®,1,data,1); + + return result; +} + + + +int hal_gpio_i2c_open(const struct HAL_GPIO_I2C_CONFIG_T *cfg) +{ + static bool i2cInitDone = false; + int lock; + + if (g_i2c_open == true) + { + return -1; + } + lock = int_lock(); + g_i2c_open = 0; + int_unlock(lock); + + if (!i2cInitDone) + { + hal_gpio_i2c_initialize(cfg); + i2cInitDone = 0; + } + + return 0; +} + +int hal_gpio_i2c_close(void) +{ + int lock; + + if (g_i2c_open == false) + { + return false; + } + + lock = int_lock(); + g_i2c_open = false; + int_unlock(lock); + + return 0; +} + +uint32_t hal_gpio_i2c_send(uint32_t device_addr, const uint8_t *buf, uint32_t reg_len, uint32_t value_len) +{ + return hal_gpio_i2c_simple_send(device_addr, buf, reg_len + value_len); +} + +uint32_t hal_gpio_i2c_recv(uint32_t device_addr, uint8_t *buf, uint32_t reg_len, uint32_t value_len, uint8_t restart_after_write) +{ + return hal_gpio_i2c_simple_recv(device_addr, buf, reg_len, buf+reg_len, value_len); +} +/* gpio iic end */ + +int app_i2c_demo_init(void) +{ + static struct HAL_GPIO_I2C_CONFIG_T i2c_cfg={ + HAL_GPIO_PIN_P2_0, + HAL_GPIO_PIN_P2_1, + 0, + }; + hal_gpio_i2c_open(&i2c_cfg); + + return 0; +} + diff --git a/platform/hal/hal_i2c.h b/platform/hal/hal_i2c.h new file mode 100644 index 0000000..7dc4583 --- /dev/null +++ b/platform/hal/hal_i2c.h @@ -0,0 +1,221 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_I2C_H__ +#define __HAL_I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_gpio.h" +#include "hal_sensor_eng.h" + +// For 10-bit address devices: OR the following mask with the real address +#define HAL_I2C_10BITADDR_MASK (1 << 15) + +enum HAL_I2C_ACTION_AFTER_WRITE_T { + HAL_I2C_STOP_AFTER_WRITE = 0, + HAL_I2C_RESTART_AFTER_WRITE, +}; + +enum HAL_I2C_ID_T { + HAL_I2C_ID_0 = 0, +#if (CHIP_HAS_I2C > 1) + HAL_I2C_ID_1, +#endif + + HAL_I2C_ID_NUM, +}; + +enum HAL_I2C_API_MODE_T { + HAL_I2C_API_MODE_TASK = 0, + HAL_I2C_API_MODE_SIMPLE, + HAL_I2C_API_MODE_SENSOR_ENGINE, +}; + +enum HAL_I2C_INT_STATUS_T { + HAL_I2C_INT_STATUS_GEN_CALL_MASK = 0x1<<11, + HAL_I2C_INT_STATUS_START_DET_MASK = 0x1<<10, + HAL_I2C_INT_STATUS_STOP_DET_MASK = 0x1<<9, + HAL_I2C_INT_STATUS_ACTIVITY_MASK = 0x1<<8, + HAL_I2C_INT_STATUS_RX_DONE_MASK = 0x1<<7, + HAL_I2C_INT_STATUS_TX_ABRT_MASK = 0x1<<6, + HAL_I2C_INT_STATUS_RD_REQ_MASK = 0x1<<5, + HAL_I2C_INT_STATUS_TX_EMPTY_MASK = 0x1<<4, + HAL_I2C_INT_STATUS_TX_OVER_MASK = 0x1<<3, + HAL_I2C_INT_STATUS_RX_FULL_MASK = 0x1<<2, + HAL_I2C_INT_STATUS_RX_OVER_MASK = 0x1<<1, + HAL_I2C_INT_STATUS_RX_UNDER_MASK = 0x1<<0, + /* FIXME : same as i2cip definitions + #define I2CIP_INT_STATUS_GEN_CALL_SHIFT (11) + #define I2CIP_INT_STATUS_START_DET_SHIFT (10) + #define I2CIP_INT_STATUS_STOP_DET_SHIFT (9) + #define I2CIP_INT_STATUS_ACTIVITY_SHIFT (8) + #define I2CIP_INT_STATUS_RX_DONE_SHIFT (7) + #define I2CIP_INT_STATUS_TX_ABRT_SHIFT (6) + #define I2CIP_INT_STATUS_RD_REQ_SHIFT (5) + #define I2CIP_INT_STATUS_TX_EMPTY_SHIFT (4) + #define I2CIP_INT_STATUS_TX_OVER_SHIFT (3) + #define I2CIP_INT_STATUS_RX_FULL_SHIFT (2) + #define I2CIP_INT_STATUS_RX_OVER_SHIFT (1) + #define I2CIP_INT_STATUS_RX_UNDER_SHIFT (0) + */ +}; + +enum HAL_I2C_ERRCODE_T { + HAL_I2C_ERRCODE_SLVRD_INTX = 1<<15, + HAL_I2C_ERRCODE_SLV_ARBLOST = 1<<14, + HAL_I2C_ERRCODE_SLVFLUSH_TXFIFO = 1<<13, + HAL_I2C_ERRCODE_ARB_LOST = 1<<12, + HAL_I2C_ERRCODE_MASTER_DIS = 1<<11, + HAL_I2C_ERRCODE_10B_RD_NORSTRT = 1<<10, + HAL_I2C_ERRCODE_SBYTE_NORSTRT = 1<<9, + HAL_I2C_ERRCODE_HS_NORSTRT = 1<<8, + HAL_I2C_ERRCODE_SBYTE_ACKDET = 1<<7, + HAL_I2C_ERRCODE_HS_ACKDET = 1<<6, + HAL_I2C_ERRCODE_GCALL_READ = 1<<5, + HAL_I2C_ERRCODE_GCALL_NOACK = 1<<4, + HAL_I2C_ERRCODE_TXDATA_NOACK = 1<<3, + HAL_I2C_ERRCODE_10ADDR2_NOACK = 1<<2, + HAL_I2C_ERRCODE_10ADDR1_NOACK = 1<<1, + HAL_I2C_ERRCODE_7B_ADDR_NOACK = 1<<0, + + HAL_I2C_ERRCODE_INV_PARAM = 1<<31, + HAL_I2C_ERRCODE_IN_USE = 1<<30, + HAL_I2C_ERRCODE_FIFO_ERR = 1<<29, + HAL_I2C_ERRCODE_SYNC_TIMEOUT = 1<<28, + HAL_I2C_ERRCODE_ACT_TIMEOUT = 1<<27, + HAL_I2C_ERRCODE_TFNF_TIMEOUT = 1<<26, + HAL_I2C_ERRCODE_TFE_TIMEOUT = 1<<25, + HAL_I2C_ERRCODE_RFNE_TIMEOUT = 1<<24, + + /* FIXME : same as i2cip definitions + #define I2CIP_TX_ABRT_SOURCE_ABRT_SLVRD_INTX_SHIFT (15) + #define I2CIP_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST_SHIFT (14) + #define I2CIP_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO_SHIFT (13) + #define I2CIP_TX_ABRT_SOURCE_ARB_LOST_SHIFT (12) + #define I2CIP_TX_ABRT_SOURCE_ABRT_MASTER_DIS_SHIFT (11) + #define I2CIP_TX_ABRT_SOURCE_ABRT_10B_RD_NORSTRT_SHIFT (10) + #define I2CIP_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT_SHIFT (9) + #define I2CIP_TX_ABRT_SOURCE_ABRT_HS_NORSTRT_SHIFT (8) + #define I2CIP_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET_SHIFT (7) + #define I2CIP_TX_ABRT_SOURCE_ABRT_HS_ACKDET_SHIFT (6) + #define I2CIP_TX_ABRT_SOURCE_ABRT_GCALL_READ_SHIFT (5) + #define I2CIP_TX_ABRT_SOURCE_ABRT_GCALL_NOACK_SHIFT (4) + #define I2CIP_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_SHIFT (3) + #define I2CIP_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_SHIFT (2) + #define I2CIP_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK_SHIFT (1) + #define I2CIP_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_SHIFT (0) + */ +}; + +struct HAL_I2C_CONFIG_T { + /* mode + SIMPLE_MODE : pulling when reading or writing (always sync), or use dma external;master or slave;only enable slave related irq; + TASK_MODE : task to driven reading or writing (sync or async, dma or non-dma);only master + */ + enum HAL_I2C_API_MODE_T mode; + + uint8_t use_sync; + uint8_t use_dma; + uint8_t as_master; + uint32_t speed; + uint32_t addr_as_slave; +}; + +typedef void (*HAL_I2C_SENSOR_ENG_HANDLER_T)(enum HAL_I2C_ID_T id, const uint8_t *buf, uint32_t len); + +struct HAL_I2C_SENSOR_ENGINE_CONFIG_T { + enum HAL_SENSOR_ENGINE_ID_T id; + enum HAL_SENSOR_ENGINE_TRIGGER_T trigger_type; + enum HAL_GPIO_PIN_T trigger_gpio; + uint32_t period_us; + uint16_t target_addr; + uint8_t *write_buf; + uint16_t write_txn_len; + uint8_t *read_buf; + uint16_t read_txn_len; + uint16_t txn_cnt; + uint8_t read_burst_cnt; + HAL_I2C_SENSOR_ENG_HANDLER_T handler; +}; + +struct HAL_GPIO_I2C_CONFIG_T { + enum HAL_GPIO_PIN_T scl; + enum HAL_GPIO_PIN_T sda; + uint32_t speed; +}; + +uint32_t hal_i2c_open(enum HAL_I2C_ID_T id, const struct HAL_I2C_CONFIG_T *cfg); +uint32_t hal_i2c_close(enum HAL_I2C_ID_T id); + +/* for master task mode */ +typedef void (*HAL_I2C_TRANSFER_HANDLER_T)(enum HAL_I2C_ID_T id, uint32_t transfer_id, + const uint8_t *tx_buf, uint32_t tx_len, + const uint8_t *rx_buf, uint32_t rx_len, + enum HAL_I2C_ERRCODE_T errcode); +uint32_t hal_i2c_send(enum HAL_I2C_ID_T id, uint32_t device_addr, uint8_t *buf, uint32_t reg_len, uint32_t value_len, + uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler); +uint32_t hal_i2c_recv(enum HAL_I2C_ID_T id, uint32_t device_addr, uint8_t *buf, uint32_t reg_len, uint32_t value_len, + uint8_t restart_after_write, uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler); +// New I2C task mode APIs +uint32_t hal_i2c_task_send(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_len, + uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler); +uint32_t hal_i2c_task_recv(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_len, + uint8_t *rx_buf, uint16_t rx_len, + uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler); +uint32_t hal_i2c_task_msend(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_item_len, + uint16_t item_cnt, uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler); +uint32_t hal_i2c_task_mrecv(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_item_len, + uint8_t *rx_buf, uint16_t rx_item_len, uint16_t item_cnt, + uint32_t transfer_id, HAL_I2C_TRANSFER_HANDLER_T handler); +/* for master task mode end */ + +/* for slave and simple master mode */ +typedef void (*HAL_I2C_INT_HANDLER_T)(enum HAL_I2C_ID_T id, enum HAL_I2C_INT_STATUS_T status, uint32_t errocode); +uint32_t hal_i2c_slv_write(enum HAL_I2C_ID_T id, uint8_t *buf, uint32_t buf_len, uint32_t *act_len); +uint32_t hal_i2c_slv_read(enum HAL_I2C_ID_T id, uint8_t *buf, uint32_t buf_len, uint32_t *act_len); +uint32_t hal_i2c_set_interrupt_handler(enum HAL_I2C_ID_T id, HAL_I2C_INT_HANDLER_T handler); +uint32_t hal_i2c_mst_write(enum HAL_I2C_ID_T id, uint32_t device_addr, const uint8_t *buf, uint32_t buf_len, uint32_t *act_len, uint32_t restart, uint32_t stop, uint32_t yield); +uint32_t hal_i2c_mst_read(enum HAL_I2C_ID_T id, uint32_t device_addr, uint8_t *buf, uint32_t buf_len, uint32_t *act_len, uint32_t restart, uint32_t stop, uint32_t yield); +// New I2C simple mode APIs +uint32_t hal_i2c_simple_send(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_len); +uint32_t hal_i2c_simple_recv(enum HAL_I2C_ID_T id, uint16_t device_addr, const uint8_t *tx_buf, uint16_t tx_len, uint8_t *rx_buf, uint16_t rx_len); +/* for slave and simple master mode end */ + +/* sensor engine mode */ +uint32_t hal_i2c_sensor_engine_start(enum HAL_I2C_ID_T id, const struct HAL_I2C_SENSOR_ENGINE_CONFIG_T *cfg); +uint32_t hal_i2c_sensor_engine_stop(enum HAL_I2C_ID_T id); +/* sensor engine end */ + +int hal_gpio_i2c_open(const struct HAL_GPIO_I2C_CONFIG_T *cfg); +int hal_gpio_i2c_close(void); +uint32_t hal_gpio_i2c_send(uint32_t device_addr, const uint8_t *buf, uint32_t reg_len, uint32_t value_len); +uint32_t hal_gpio_i2c_recv(uint32_t device_addr, uint8_t *buf, uint32_t reg_len, uint32_t value_len, uint8_t restart_after_write); +// New GPIO I2C APIs +uint32_t hal_gpio_i2c_simple_send(uint32_t device_addr, const uint8_t *tx_buf, uint16_t tx_len); +uint32_t hal_gpio_i2c_simple_recv(uint32_t device_addr, const uint8_t *tx_buf, uint16_t tx_len, uint8_t *rx_buf, uint16_t rx_len); + + +int app_i2c_demo_init(void); +unsigned char I2C_WriteByte(unsigned char reg, unsigned char data); +unsigned char I2C_ReadByte(unsigned char reg, unsigned char* data); +#ifdef __cplusplus +} +#endif + +#endif /* __HAL_I2C_H__ */ diff --git a/platform/hal/hal_i2cip.h b/platform/hal/hal_i2cip.h new file mode 100644 index 0000000..82de247 --- /dev/null +++ b/platform/hal/hal_i2cip.h @@ -0,0 +1,374 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_I2CIP_H__ +#define __HAL_I2CIP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "reg_i2cip.h" + +#define i2cip_read32(b,a) \ + (*(volatile uint32_t *)(b+a)) + +#define i2cip_write32(v,b,a) \ + ((*(volatile uint32_t *)(b+a)) = v) + +static inline uint8_t i2cip_w_enable(uint32_t reg_base, uint8_t enable) +{ + uint32_t val = 0; + val = i2cip_read32(reg_base, I2CIP_ENABLE_REG_OFFSET); + if (enable) + val |= I2CIP_ENABLE_MASK; + else + val &= ~I2CIP_ENABLE_MASK; + i2cip_write32(val, reg_base, I2CIP_ENABLE_REG_OFFSET); + return 0; +} +static inline uint8_t i2cip_w_clear_ctrl(uint32_t reg_base) +{ + i2cip_write32(0, reg_base, I2CIP_CTRL_REG_OFFSET); + return 0; +} +static inline uint8_t i2cip_w_10bit_master(uint32_t reg_base, uint8_t enable) +{ + uint32_t val = 0; + val = i2cip_read32(reg_base, I2CIP_CTRL_REG_OFFSET); + if (enable) + val |= I2CIP_10BITADDR_MASTER_MASK; + else + val &= ~I2CIP_10BITADDR_MASTER_MASK; + i2cip_write32(val, reg_base, I2CIP_CTRL_REG_OFFSET); + return 0; +} +static inline uint8_t i2cip_r_ctrl_reg(uint32_t reg_base) +{ + return i2cip_read32(reg_base, I2CIP_CTRL_REG_OFFSET); +} +static inline uint8_t i2cip_w_10bit_slave(uint32_t reg_base, uint8_t enable) +{ + uint32_t val = 0; + val = i2cip_read32(reg_base, I2CIP_CTRL_REG_OFFSET); + if (enable) + val |= I2CIP_10BITADDR_SLAVE_MASK; + else + val &= ~I2CIP_10BITADDR_SLAVE_MASK; + i2cip_write32(val, reg_base, I2CIP_CTRL_REG_OFFSET); + return 0; +} +static inline uint8_t i2cip_w_restart(uint32_t reg_base, uint8_t restart) +{ + uint32_t val = 0; + val = i2cip_read32(reg_base, I2CIP_CTRL_REG_OFFSET); + if (restart) + val |= I2CIP_RESTART_ENABLE_MASK; + else + val &= ~I2CIP_RESTART_ENABLE_MASK; + i2cip_write32(val, reg_base, I2CIP_CTRL_REG_OFFSET); + return 0; +} +static inline uint8_t i2cip_w_speed(uint32_t reg_base, uint32_t speed) +{ + uint32_t val = 0; + val = i2cip_read32(reg_base, I2CIP_CTRL_REG_OFFSET); + val &= ~I2CIP_SPEED_MASK; + val |= speed; + i2cip_write32(val, reg_base, I2CIP_CTRL_REG_OFFSET); + return 0; +} +static inline uint8_t i2cip_w_standard_speed_hcnt(uint32_t reg_base, uint32_t hcnt) +{ + uint32_t val = 0; + val |= hcnt<= threshold +#define HAL_I2S_RX_FIFO_TRIGGER_LEVEL (I2SIP_FIFO_DEPTH/2) + +#define HAL_I2S_YES 1 +#define HAL_I2S_NO 0 + +#ifdef CHIP_BEST1000 +#define I2S_CMU_DIV CODEC_PLL_DIV +#define I2S_CHAN_NUM 1 +#else +#define I2S_CMU_DIV CODEC_CMU_DIV +#define I2S_CHAN_NUM 4 +#endif + +#ifndef I2S_MCLK_DIV +#define I2S_MCLK_DIV 2 +#endif + +enum HAL_I2S_STATUS_T { + HAL_I2S_STATUS_NULL, + HAL_I2S_STATUS_OPENED, + HAL_I2S_STATUS_STARTED, +}; + +struct I2S_SAMPLE_RATE_T{ + enum AUD_SAMPRATE_T sample_rate; + uint32_t codec_freq; + uint8_t codec_div; + uint8_t cmu_div; +}; + +struct HAL_I2S_MOD_NAME_T { + enum HAL_CMU_MOD_ID_T mod; + enum HAL_CMU_MOD_ID_T apb; +}; + +#ifndef FPGA +static const struct I2S_SAMPLE_RATE_T i2s_sample_rate[]={ + {AUD_SAMPRATE_8000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_16000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_32000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_44100, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_48000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_64000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_96000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_128000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_256000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_176400, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_192000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_352800, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_384000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_512000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_705600, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_768000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, + {AUD_SAMPRATE_1024000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, I2S_CMU_DIV}, +}; +#endif + +static const char * const invalid_id = "Invalid I2S ID: %d\n"; +//static const char * const invalid_ch = "Invalid I2S CH: %d\n"; + +static enum HAL_I2S_STATUS_T i2s_status[HAL_I2S_ID_QTY][AUD_STREAM_NUM]; +static enum HAL_I2S_MODE_T i2s_mode[HAL_I2S_ID_QTY]; +static bool i2s_dma[HAL_I2S_ID_QTY][AUD_STREAM_NUM]; +static bool sync_start[HAL_I2S_ID_QTY][AUD_STREAM_NUM]; +#ifdef CHIP_BEST2000 +static uint8_t i2s_rx_line_map[HAL_I2S_ID_QTY]; +STATIC_ASSERT(sizeof(i2s_rx_line_map) * 8 >= I2S_CHAN_NUM, "i2s_rx_line_map size too small"); +#endif + +static const struct HAL_I2S_MOD_NAME_T i2s_mod[HAL_I2S_ID_QTY] = { + { + .mod = HAL_CMU_MOD_O_I2S0, + .apb = HAL_CMU_MOD_P_I2S0, + }, +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + { + .mod = HAL_CMU_MOD_O_I2S1, + .apb = HAL_CMU_MOD_P_I2S1, + }, +#endif +}; + +static inline uint32_t _i2s_get_reg_base(enum HAL_I2S_ID_T id) +{ + ASSERT(id < HAL_I2S_ID_QTY, invalid_id, id); + switch(id) { + case HAL_I2S_ID_0: + return I2S0_BASE; + break; +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + case HAL_I2S_ID_1: + return I2S1_BASE; + break; +#endif + default: + break; + } + return 0; +} + +static int hal_i2s_master_stream_closed(void) +{ + enum HAL_I2S_ID_T id; + + for (id = HAL_I2S_ID_0; id < HAL_I2S_ID_QTY; id++) { + if (i2s_status[id][AUD_STREAM_PLAYBACK] != HAL_I2S_STATUS_NULL || + i2s_status[id][AUD_STREAM_CAPTURE] != HAL_I2S_STATUS_NULL) { + if (i2s_mode[id] == HAL_I2S_MODE_MASTER) { + return false; + } + } + } + + return true; +} + +int hal_i2s_open(enum HAL_I2S_ID_T id, enum AUD_STREAM_T stream, enum HAL_I2S_MODE_T mode) +{ + uint32_t reg_base; + + reg_base = _i2s_get_reg_base(id); + + ASSERT(mode == HAL_I2S_MODE_MASTER || mode == HAL_I2S_MODE_SLAVE, + "Invalid I2S mode for stream %d: %d", stream, mode); + ASSERT(i2s_mode[id] == HAL_I2S_MODE_NULL || i2s_mode[id] == mode, + "Incompatible I2S mode for stream %d: prev=%d cur=%d", stream, i2s_mode[id], mode); + + if (i2s_status[id][stream] != HAL_I2S_STATUS_NULL) { + TRACE(2,"Invalid I2S opening status for stream %d: %d", stream, i2s_status[id][stream]); + return 1; + } + + if (i2s_status[id][AUD_STREAM_PLAYBACK] == HAL_I2S_STATUS_NULL && + i2s_status[id][AUD_STREAM_CAPTURE] == HAL_I2S_STATUS_NULL) { + if (mode == HAL_I2S_MODE_MASTER) { +#ifndef SIMU + if (hal_i2s_master_stream_closed()) { + analog_aud_pll_open(ANA_AUD_PLL_USER_I2S); + } +#endif + hal_cmu_i2s_clock_enable(id); + } + + if (id == HAL_I2S_ID_0) { + hal_iomux_set_i2s0(); +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + } else { + hal_iomux_set_i2s1(); +#endif + } + + hal_cmu_clock_enable(i2s_mod[id].mod); + hal_cmu_clock_enable(i2s_mod[id].apb); + hal_cmu_reset_clear(i2s_mod[id].mod); + hal_cmu_reset_clear(i2s_mod[id].apb); + i2sip_w_enable_i2sip(reg_base, HAL_I2S_YES); + + for (int i = 0; i < I2S_CHAN_NUM; i++) { + i2sip_w_enable_rx_channel(reg_base, i, HAL_I2S_NO); + i2sip_w_enable_tx_channel(reg_base, i, HAL_I2S_NO); + i2sip_w_rx_fifo_reset(reg_base, i); + i2sip_w_tx_fifo_reset(reg_base, i); + } + +#ifndef CHIP_BEST1000 + if (mode == HAL_I2S_MODE_MASTER) { + i2sip_w_enable_slave_mode(reg_base, HAL_I2S_NO); + } else { + i2sip_w_enable_slave_mode(reg_base, HAL_I2S_YES); + } +#endif + + if (mode == HAL_I2S_MODE_MASTER) { + hal_cmu_i2s_set_master_mode(id); + } else { + hal_cmu_i2s_set_slave_mode(id); + } + + i2s_mode[id] = mode; + } + + i2s_dma[id][stream] = false; + i2s_status[id][stream] = HAL_I2S_STATUS_OPENED; + + return 0; +} + +int hal_i2s_close(enum HAL_I2S_ID_T id, enum AUD_STREAM_T stream) +{ + uint32_t reg_base; + + reg_base = _i2s_get_reg_base(id); + + if (i2s_status[id][stream] != HAL_I2S_STATUS_OPENED) { + TRACE(2,"Invalid I2S closing status for stream %d: %d", stream, i2s_status[id][stream]); + return 1; + } + + i2s_status[id][stream] = HAL_I2S_STATUS_NULL; + + if (i2s_status[id][AUD_STREAM_PLAYBACK] == HAL_I2S_STATUS_NULL && + i2s_status[id][AUD_STREAM_CAPTURE] == HAL_I2S_STATUS_NULL) { + i2sip_w_enable_i2sip(reg_base, HAL_I2S_NO); + hal_cmu_reset_set(i2s_mod[id].apb); + hal_cmu_reset_set(i2s_mod[id].mod); + hal_cmu_clock_disable(i2s_mod[id].apb); + hal_cmu_clock_disable(i2s_mod[id].mod); + + if (i2s_mode[id] == HAL_I2S_MODE_MASTER) { + hal_cmu_i2s_clock_disable(id); + if (hal_i2s_master_stream_closed()) { +#if !defined(CHIP_BEST1000) && defined(I2S_MCLK_FROM_SPDIF) + hal_cmu_clock_out_disable(); + hal_spdif_clock_out_disable(HAL_SPDIF_ID_0); +#endif +#ifndef SIMU + analog_aud_pll_close(ANA_AUD_PLL_USER_I2S); +#endif + } + } + + i2s_mode[id] = HAL_I2S_MODE_NULL; + } + + return 0; +} + +#ifdef AF_ADC_I2S_SYNC +static bool _hal_i2s_enable_delay[HAL_I2S_ID_QTY]; + +void hal_i2s_enable_delay(enum HAL_I2S_ID_T id) +{ + _hal_i2s_enable_delay[id] = true; +} + +void hal_i2s_disable_delay(enum HAL_I2S_ID_T id) +{ + _hal_i2s_enable_delay[id] = false; +} + +void hal_i2s_enable(enum HAL_I2S_ID_T id) +{ + i2sip_w_enable_clk_gen(_i2s_get_reg_base(id), HAL_I2S_YES); +} +#endif + +int hal_i2s_start_stream(enum HAL_I2S_ID_T id, enum AUD_STREAM_T stream) +{ + uint32_t reg_base; + uint32_t lock; + bool xfer_en[AUD_STREAM_NUM]; + + reg_base = _i2s_get_reg_base(id); + + if (i2s_status[id][stream] != HAL_I2S_STATUS_OPENED) { + TRACE(2,"Invalid I2S starting status for stream %d: %d", stream, i2s_status[id][stream]); + return 1; + } + + if (i2s_mode[id] == HAL_I2S_MODE_SLAVE && sync_start[id][stream]) { + xfer_en[stream] = false; + xfer_en[!stream] = false; + } else { + xfer_en[stream] = true; + if (i2s_mode[id] == HAL_I2S_MODE_SLAVE && + i2s_status[id][!stream] == HAL_I2S_STATUS_STARTED && + sync_start[id][!stream]) { + xfer_en[!stream] = true; + } else { + xfer_en[!stream] = false; + } + } + + if (stream == AUD_STREAM_PLAYBACK) { + lock = int_lock(); + i2sip_w_enable_tx_channel(reg_base, 0, HAL_I2S_YES); + if (xfer_en[stream]) { + i2sip_w_enable_tx_block(reg_base, HAL_I2S_YES); + if (i2s_dma[id][stream]) { + i2sip_w_enable_tx_dma(reg_base, HAL_I2S_YES); + } + } + if (xfer_en[!stream]) { + i2sip_w_enable_rx_block(reg_base, HAL_I2S_YES); + } + int_unlock(lock); + if (i2s_dma[id][stream] && i2s_mode[id] == HAL_I2S_MODE_MASTER) { + // Delay a little time for DMA to fill the TX FIFO before sending (enabling clk gen) + for (volatile int i = 0; i < 50; i++); + } + } else { + if (i2s_dma[id][stream]) { + i2sip_w_enable_rx_dma(reg_base, HAL_I2S_YES); + } +#ifdef CHIP_BEST2000 + int i; + for (i = 0; i < I2S_CHAN_NUM; i++) { + if (i2s_rx_line_map[id] & (1 << i)) { + i2sip_w_enable_rx_channel(reg_base, i, HAL_I2S_YES); + } + } +#else + i2sip_w_enable_rx_channel(reg_base, 0, HAL_I2S_YES); +#endif + lock = int_lock(); + if (xfer_en[stream]) { + i2sip_w_enable_rx_block(reg_base, HAL_I2S_YES); + } + if (xfer_en[!stream]) { + i2sip_w_enable_tx_block(reg_base, HAL_I2S_YES); + if (i2s_dma[id][!stream]) { + i2sip_w_enable_tx_dma(reg_base, HAL_I2S_YES); + } + } + int_unlock(lock); + } + + if (i2s_mode[id] == HAL_I2S_MODE_MASTER && !sync_start[id][stream]) { + if (i2sip_r_clk_gen_enabled(reg_base) == 0) { + hal_cmu_i2s_clock_out_enable(id); +#ifdef AF_ADC_I2S_SYNC + if (_hal_i2s_enable_delay[id]) { + _hal_i2s_enable_delay[id] = false; + } else { + hal_i2s_enable(id); + } +#else + i2sip_w_enable_clk_gen(reg_base, HAL_I2S_YES); +#endif + } + } + + i2s_status[id][stream] = HAL_I2S_STATUS_STARTED; + + return 0; +} + +int hal_i2s_stop_stream(enum HAL_I2S_ID_T id, enum AUD_STREAM_T stream) +{ + uint32_t reg_base; + + reg_base = _i2s_get_reg_base(id); + + if (i2s_status[id][stream] != HAL_I2S_STATUS_STARTED) { + TRACE(2,"Invalid I2S stopping status for stream %d: %d", stream, i2s_status[id][stream]); + return 1; + } + + i2s_status[id][stream] = HAL_I2S_STATUS_OPENED; + + if (i2s_status[id][AUD_STREAM_PLAYBACK] != HAL_I2S_STATUS_STARTED && + i2s_status[id][AUD_STREAM_CAPTURE] != HAL_I2S_STATUS_STARTED) { + if (i2s_mode[id] == HAL_I2S_MODE_MASTER) { + hal_cmu_i2s_clock_out_disable(id); + i2sip_w_enable_clk_gen(reg_base, HAL_I2S_NO); +#ifdef AF_ADC_I2S_SYNC + _hal_i2s_enable_delay[id] = false; +#endif + } + } + + if (stream == AUD_STREAM_PLAYBACK) { + i2sip_w_enable_tx_block(reg_base, HAL_I2S_NO); + i2sip_w_enable_tx_channel(reg_base, 0, HAL_I2S_NO); + i2sip_w_enable_tx_dma(reg_base, HAL_I2S_NO); + i2sip_w_tx_fifo_reset(reg_base, 0); + } else { + i2sip_w_enable_rx_block(reg_base, HAL_I2S_NO); + i2sip_w_enable_rx_dma(reg_base, HAL_I2S_NO); +#ifdef CHIP_BEST1000 + i2sip_w_enable_rx_channel(reg_base, 0, HAL_I2S_NO); + i2sip_w_rx_fifo_reset(reg_base, 0); +#else + int i; + for (i = 0; i < I2S_CHAN_NUM; i++) { + i2sip_w_enable_rx_channel(reg_base, i, HAL_I2S_NO); + i2sip_w_rx_fifo_reset(reg_base, i); + } +#endif + } + + return 0; +} + +int hal_i2s_setup_stream(enum HAL_I2S_ID_T id, enum AUD_STREAM_T stream, const struct HAL_I2S_CONFIG_T *cfg) +{ + uint32_t reg_base; + uint32_t div = 0; + uint8_t cycles; + uint8_t resolution = 0, word_sclk = 0; + bool valid; + int POSSIBLY_UNUSED i; + + reg_base = _i2s_get_reg_base(id); + + if (i2s_status[id][stream] != HAL_I2S_STATUS_OPENED) { + TRACE(2,"Invalid I2S setup status for stream %d: %d", stream, i2s_status[id][stream]); + return 1; + } + + cycles = cfg->cycles; + if (cycles == 0) { + if (cfg->bits <= AUD_BITS_16) { + cycles = 16; + } else { + cycles = 32; + } + } + ASSERT(cycles >= cfg->bits, "I2S cycles (%u) should >= bits (%u)", cycles, cfg->bits); + + switch (cycles) + { + case 16: + word_sclk = I2SIP_CLK_CFG_WSS_VAL_16CYCLE; + break; + case 24: + word_sclk = I2SIP_CLK_CFG_WSS_VAL_24CYCLE; + break; + case 32: + word_sclk = I2SIP_CLK_CFG_WSS_VAL_32CYCLE; + break; + default: + ASSERT(false, "Bad I2S cycles (%u)", cycles); + return 1; + } + + switch (cfg->bits) + { + case AUD_BITS_8: + resolution = I2SIP_CFG_WLEN_VAL_IGNORE; + break; + case AUD_BITS_12: + resolution = I2SIP_CFG_WLEN_VAL_12BIT; + break; + case AUD_BITS_16: + resolution = I2SIP_CFG_WLEN_VAL_16BIT; + break; + case AUD_BITS_20: + resolution = I2SIP_CFG_WLEN_VAL_20BIT; + break; + case AUD_BITS_24: + resolution = I2SIP_CFG_WLEN_VAL_24BIT; + break; + case AUD_BITS_32: + resolution = I2SIP_CFG_WLEN_VAL_32BIT; + break; + default: + ASSERT(false, "Bad I2S bits (%u)", cfg->bits); + return 1; + } + + /* word clock width : how many sclk work sclk count*/ + /* sclk gate in word clock : how many sclk gate : fixed no gate */ + i2sip_w_clk_cfg_reg(reg_base, (word_sclk<channel_num == AUD_CHANNEL_NUM_2); + } else { + valid = (cfg->channel_num == AUD_CHANNEL_NUM_2 || cfg->channel_num == AUD_CHANNEL_NUM_4 || + cfg->channel_num == AUD_CHANNEL_NUM_6 || cfg->channel_num == AUD_CHANNEL_NUM_8); + } +#else + valid = (cfg->channel_num == AUD_CHANNEL_NUM_2); +#endif + ASSERT(valid, "[%s] Stream %d Channel number(%d) error", __func__, stream, cfg->channel_num); + + if (i2s_mode[id] == HAL_I2S_MODE_MASTER) { +#ifdef FPGA + uint32_t sclk; + + sclk = cfg->sample_rate * cycles * AUD_CHANNEL_NUM_2; + +#define I2S_CLOCK_SOURCE 22579200 //44100*512 + div = I2S_CLOCK_SOURCE/sclk - 1; +#undef I2S_CLOCK_SOURCE + + TRACE(1,"div = %x",div); +#else + uint32_t i2s_clock; + uint32_t bit_rate; + + for (i = 0; i < ARRAY_SIZE(i2s_sample_rate); i++) + { + if (i2s_sample_rate[i].sample_rate == cfg->sample_rate) + { + break; + } + } + ASSERT(i < ARRAY_SIZE(i2s_sample_rate), "%s: Invalid i2s sample rate: %d", __func__, cfg->sample_rate); + + TRACE(3,"[%s] stream=%d sample_rate=%d", __func__, stream, cfg->sample_rate); + + ASSERT(i2s_sample_rate[i].codec_div / i2s_sample_rate[i].cmu_div * i2s_sample_rate[i].cmu_div == i2s_sample_rate[i].codec_div, + "%s: Invalid codec div for rate %u: codec_div=%u cmu_div=%u", __func__, cfg->sample_rate, + i2s_sample_rate[i].codec_div, i2s_sample_rate[i].cmu_div); + +#ifndef SIMU + analog_aud_freq_pll_config(i2s_sample_rate[i].codec_freq, i2s_sample_rate[i].codec_div); +#ifdef CHIP_BEST2000 + analog_aud_pll_set_dig_div(i2s_sample_rate[i].codec_div / i2s_sample_rate[i].cmu_div); +#endif +#endif + + i2s_clock = i2s_sample_rate[i].codec_freq * i2s_sample_rate[i].cmu_div; + bit_rate = i2s_sample_rate[i].sample_rate * AUD_CHANNEL_NUM_2 * cycles; + div = i2s_clock / bit_rate; + + ASSERT(i2s_clock == bit_rate * div, "%s: Bad stream cfg (bad cycles?): i2s_clock=%u bit_rate=%u cycles=%u", + __func__, i2s_clock, bit_rate, cycles); + +#if !defined(CHIP_BEST1000) && defined(I2S_MCLK_FROM_SPDIF) +#ifdef I2S_MCLK_PIN + hal_iomux_set_i2s_mclk(); + hal_cmu_i2s_mclk_enable(HAL_CMU_I2S_MCLK_PLLSPDIF0); +#else + hal_iomux_set_clock_out(); + hal_cmu_clock_out_enable(HAL_CMU_CLOCK_OUT_MCU_SPDIF0); +#endif + // By default MCLK is half of (CODEC_FREQ_24P576M or CODEC_FREQ_22P5792M) + hal_spdif_clock_out_enable(HAL_SPDIF_ID_0, i2s_sample_rate[i].cmu_div * I2S_MCLK_DIV); +#endif +#endif + + hal_cmu_i2s_set_div(id, div); + } + + if ((stream == AUD_STREAM_PLAYBACK && i2s_status[id][AUD_STREAM_CAPTURE] == HAL_I2S_STATUS_NULL) || + (stream == AUD_STREAM_CAPTURE && i2s_status[id][AUD_STREAM_PLAYBACK] == HAL_I2S_STATUS_NULL)) { + hal_cmu_reset_pulse(i2s_mod[id].mod); + } + + i2s_dma[id][stream] = cfg->use_dma; + sync_start[id][stream] = cfg->sync_start; + + if (stream == AUD_STREAM_PLAYBACK) + { + /* resolution : valid bit width */ + i2sip_w_tx_resolution(reg_base, 0, resolution); + + /* fifo level to trigger empty interrupt or dma req */ + i2sip_w_tx_fifo_threshold(reg_base, 0, HAL_I2S_TX_FIFO_TRIGGER_LEVEL); + } + else + { +#ifdef CHIP_BEST2000 + uint32_t ch; + uint32_t cnt = 0; + + i2s_rx_line_map[id] = 0; + + for (i = 0; i < I2S_CHAN_NUM; i++) { + ch = (cfg->channel_map >> (i * 2)) & 3; + ASSERT(ch == 0 || ch == 3, "[%s] Stream %d Bad Chan Map 0x%04X", __func__, stream, cfg->channel_map); + if (ch == 3) { + i2s_rx_line_map[id] |= (1 << i); + cnt += 2; + } + } + ASSERT(cnt == cfg->channel_num, "[%s] Stream %d Unmatched Chan Num (%u) and Map (0x%04X)", + __func__, stream, cfg->channel_num, cfg->channel_map); + + if (cfg->chan_sep_buf) { + i2sip_w_rx_dma_blk_size(reg_base, HAL_I2S_RX_FIFO_TRIGGER_LEVEL); + i2sp_w_enable_rx_dma_block(reg_base, HAL_I2S_YES); + } else { + i2sp_w_enable_rx_dma_block(reg_base, HAL_I2S_NO); + } + + for (i = 0; i < I2S_CHAN_NUM; i++) { + if (i2s_rx_line_map[id] & (1 << i)) { + i2sip_w_rx_resolution(reg_base, i, resolution); + i2sip_w_rx_fifo_threshold(reg_base, i, HAL_I2S_RX_FIFO_TRIGGER_LEVEL); + } + } +#else + /* resolution : valid bit width */ + i2sip_w_rx_resolution(reg_base, 0, resolution); + + /* fifo level to trigger empty interrupt or dma req */ + i2sip_w_rx_fifo_threshold(reg_base, 0, HAL_I2S_RX_FIFO_TRIGGER_LEVEL); +#endif + } + + return 0; +} + +int hal_i2s_send(enum HAL_I2S_ID_T id, const uint8_t *value, uint32_t value_len) +{ + uint32_t i = 0; + uint32_t reg_base; + + reg_base = _i2s_get_reg_base(id); + + for (i = 0; i < value_len; i += 4) { + while (!(i2sip_r_int_status(reg_base, 0) & I2SIP_INT_STATUS_TX_FIFO_EMPTY_MASK)); + + i2sip_w_tx_left_fifo(reg_base, 0, value[i+1]<<8 | value[i]); + i2sip_w_tx_right_fifo(reg_base, 0, value[i+3]<<8 | value[i+2]); + } + + return 0; +} +uint8_t hal_i2s_recv(enum HAL_I2S_ID_T id, uint8_t *value, uint32_t value_len) +{ + //uint32_t reg_base; + + //reg_base = _i2s_get_reg_base(id); + + return 0; +} + +//================================================================================ +// I2S Packet Mode +//================================================================================ + +static bool i2s_pkt_opened = false; + +int hal_i2s_packet_open(void) +{ + uint32_t reg_base; + uint8_t resolution = 0, word_sclk = 0; + + if (i2s_pkt_opened) { + return 1; + } + + word_sclk = I2SIP_CLK_CFG_WSS_VAL_32CYCLE; + resolution = I2SIP_CFG_WLEN_VAL_32BIT; + + reg_base = _i2s_get_reg_base(HAL_I2S_ID_0); + + hal_iomux_set_i2s0(); + hal_cmu_i2s_clock_enable(HAL_I2S_ID_0); + hal_cmu_clock_enable(i2s_mod[HAL_I2S_ID_0].mod); + hal_cmu_clock_enable(i2s_mod[HAL_I2S_ID_0].apb); + hal_cmu_reset_clear(i2s_mod[HAL_I2S_ID_0].mod); + hal_cmu_reset_clear(i2s_mod[HAL_I2S_ID_0].apb); + i2sip_w_enable_i2sip(reg_base, HAL_I2S_YES); + + for (int i = 0; i < I2S_CHAN_NUM; i++) { + i2sip_w_enable_rx_channel(reg_base, i, HAL_I2S_NO); + i2sip_w_enable_tx_channel(reg_base, i, HAL_I2S_NO); + } + + hal_cmu_i2s_set_slave_mode(HAL_I2S_ID_0); +#ifndef CHIP_BEST1000 + i2sip_w_enable_slave_mode(reg_base, HAL_I2S_YES); +#endif + + /* word clock width : how many sclk work sclk count*/ + /* sclk gate in word clock : how many sclk gate : fixed no gate */ + i2sip_w_clk_cfg_reg(reg_base, (word_sclk< +#include +#include +#include "hal_i2s.h" +#include "hal_trace.h" +#include "hal_dma.h" +#include "hal_i2s_tdm.h" + +#if 0 +#define I2S_TDM_TRACE TRACE +#define I2S_TDM_DUMP8 DUMP8 +#else +#define I2S_TDM_TRACE(n, str, ...) +#define I2S_TDM_DUMP8(str, ...) +#endif + +#define I2S_TDM_FRAME_SIZE_MAX 512 +#define I2S_TDM_TX_FRAME_NUM 2 +#define I2S_TDM_TX_FRAME_SIZE I2S_TDM_FRAME_SIZE_MAX/16 + +static struct HAL_DMA_DESC_T i2s_tdm_tx_dma_desc[HAL_I2S_ID_QTY][I2S_TDM_TX_FRAME_NUM]; +static uint16_t I2S_TDM_BUF_ALIGN i2s_tdm_tx_buf[HAL_I2S_ID_QTY][I2S_TDM_TX_FRAME_NUM][I2S_TDM_TX_FRAME_SIZE]; +static struct HAL_DMA_CH_CFG_T tx_dma_cfg[HAL_I2S_ID_QTY]; +static struct HAL_I2S_TDM_CONFIG_T i2s_tdm_cfg[HAL_I2S_ID_QTY]; + +static inline bool i2s_tdm_cycles_in_arrays(uint16_t cycles) +{ + if(cycles == (uint16_t)HAL_I2S_TDM_CYCLES_16 + || cycles == (uint16_t)HAL_I2S_TDM_CYCLES_32 + || cycles == (uint16_t)HAL_I2S_TDM_CYCLES_64 + || cycles == (uint16_t)HAL_I2S_TDM_CYCLES_128 + || cycles == (uint16_t)HAL_I2S_TDM_CYCLES_256 + || cycles == (uint16_t)HAL_I2S_TDM_CYCLES_512 + ) + return true; + else + return false; +} + +static inline bool i2s_tdm_fs_cycles_in_arrays(uint16_t fs_cycles) +{ + if(fs_cycles == (uint16_t)HAL_I2S_TDM_FS_CYCLES_1 + || fs_cycles == (uint16_t)HAL_TDM_FS_CYCLES_8 + || fs_cycles == (uint16_t)HAL_I2S_TDM_FS_CYCLES_16 + || fs_cycles == (uint16_t)HAL_I2S_TDM_FS_CYCLES_32 + || fs_cycles == (uint16_t)HAL_I2S_TDM_FS_CYCLES_64 + || fs_cycles == (uint16_t)HAL_I2S_TDM_FS_CYCLES_128 + || fs_cycles == (uint16_t)HAL_I2S_TDM_FS_CYCLES_256 + || fs_cycles == (uint16_t)HAL_I2S_TDM_FS_CYCLES_ONE_LESS) + return true; + else + return false; +} + +static inline bool i2s_tdm_slot_cycles_in_arrays(uint8_t slot_cycles) +{ + if(slot_cycles == (uint8_t)HAL_I2S_TDM_SLOT_CYCLES_16 + || slot_cycles == (uint8_t)HAL_I2S_TDM_SLOT_CYCLES_32) + return true; + else + return false; +} + +static void i2s_tdm0_tx_handler(uint8_t chan, uint32_t remains, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ +#if 0 + static int cnt = 0; + + cnt++; + if (cnt % 600 == 0) + { + I2S_TDM_TRACE(4,"I2S_TDM0-TX: remains=%ld, error=%ld, cnt=%d,tx_buff_len = %d.", remains, error, cnt,sizeof(i2s_tdm_tx_buf[HAL_I2S_ID_0])); + I2S_TDM_DUMP8("0x%x,",i2s_tdm_tx_buf[HAL_I2S_ID_0],sizeof(i2s_tdm_tx_buf[HAL_I2S_ID_0]) <= 32 ? sizeof(i2s_tdm_tx_buf[HAL_I2S_ID_0]) : 32 ); + } +#endif +} + +static void i2s_tdm1_tx_handler(uint8_t chan, uint32_t remains, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ +#if 0 + static int cnt = 0; + + cnt++; + if (cnt % 600 == 0) { + I2S_TDM_TRACE(4,"I2S_TDM1-TX: remains=%ld, error=%ld, cnt=%d,tx_buff_len = %d.", remains, error, cnt,sizeof(i2s_tdm_tx_buf[HAL_I2S_ID_1])); + I2S_TDM_DUMP8("0x%x,",i2s_tdm_tx_buf[HAL_I2S_ID_1],sizeof(i2s_tdm_tx_buf[HAL_I2S_ID_1]) <= 32 ? sizeof(i2s_tdm_tx_buf[HAL_I2S_ID_1]) : 32 ); + } +#endif +} + +int32_t hal_i2s_tdm_open(enum HAL_I2S_ID_T i2s_id,enum HAL_I2S_MODE_T mode) +{ + int ret; + + I2S_TDM_TRACE(3,"%s: i2s_id = %d,mode = %d.", __func__, i2s_id, mode); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + // i2s open playback and capture. + ret = hal_i2s_open(i2s_id, AUD_STREAM_PLAYBACK, mode); + if(ret) + { + I2S_TDM_TRACE(2,"%s: hal_i2s_open playback failed.ret = %d.", __func__, ret); + goto __func_fail; + } + ret = hal_i2s_open(i2s_id, AUD_STREAM_CAPTURE, mode); + if(ret) + { + I2S_TDM_TRACE(2,"%s: hal_i2s_open capture failed.ret = %d.", __func__, ret); + goto __func_fail; + } + + I2S_TDM_TRACE(1,"%s done.", __func__); + return 0; + +__func_fail: + I2S_TDM_TRACE(2,"%s failed. ret = %d.", __func__, ret); + return ret; +} + +int32_t hal_i2s_tdm_setup(enum HAL_I2S_ID_T i2s_id, + uint32_t sample_rate, + struct HAL_I2S_TDM_CONFIG_T *i2s_tdm_cfg) +{ + int i,j,m,n; + int ret; + struct HAL_I2S_CONFIG_T i2s_cfg; + uint16_t *buf; + uint32_t cycles; + uint32_t fs_cycles; + uint32_t slot_cycles; + uint32_t fs_remain; + + I2S_TDM_TRACE(3,"%s: i2s_id = %d,sample_rate = %d.", __func__, i2s_id, sample_rate); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + ASSERT(i2s_tdm_cycles_in_arrays(i2s_tdm_cfg->cycles), + "%s: cycles(%d) error!", __func__, i2s_tdm_cfg->cycles); + ASSERT(i2s_tdm_fs_cycles_in_arrays(i2s_tdm_cfg->fs_cycles), + "%s: fs_cycles(%d) error!", __func__, i2s_tdm_cfg->fs_cycles); + ASSERT(i2s_tdm_slot_cycles_in_arrays(i2s_tdm_cfg->slot_cycles), + "%s: slot_cycles(%d) error!", __func__, i2s_tdm_cfg->slot_cycles); + + i2s_tdm_cfg[i2s_id] = *i2s_tdm_cfg; + cycles = i2s_tdm_cfg->cycles; + fs_cycles = i2s_tdm_cfg->fs_cycles == HAL_I2S_TDM_FS_CYCLES_ONE_LESS ?\ + cycles - 1: i2s_tdm_cfg->fs_cycles; + slot_cycles = i2s_tdm_cfg->slot_cycles; + + memset(&i2s_cfg, 0, sizeof(i2s_cfg)); + i2s_cfg.use_dma = true; + i2s_cfg.sync_start = true; + i2s_cfg.chan_sep_buf = false; + i2s_cfg.bits = slot_cycles; + i2s_cfg.channel_num = 2; + i2s_cfg.channel_map = AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1; + i2s_cfg.sample_rate = (sample_rate*(cycles/i2s_cfg.bits))/2; + ret = hal_i2s_setup_stream(i2s_id, AUD_STREAM_PLAYBACK, &i2s_cfg); + if(ret) + { + I2S_TDM_TRACE(2,"%s: playback failed.ret = %d.", __func__, ret); + goto __func_fail; + } + i2s_cfg.sync_start = false; + ret = hal_i2s_setup_stream(i2s_id, AUD_STREAM_CAPTURE, &i2s_cfg); + if(ret) + { + I2S_TDM_TRACE(1,"hal_i2s_setup_stream capture failed.ret = %d.", ret); + goto __func_fail; + } + + // Set tx buffer, output signal as slave device ws. + I2S_TDM_TRACE(3,"%s: cycles = %d, fs_cycles = %d", __func__, cycles, fs_cycles); + for (i = 0; i < I2S_TDM_TX_FRAME_NUM ; i++) { + buf = (uint16_t*)(&i2s_tdm_tx_buf[i2s_id][i][0]); + for(j = 0; j < I2S_TDM_TX_FRAME_SIZE/(cycles/16); j ++){ + fs_remain = fs_cycles; + for(m = 0; m < (cycles/16); m++) { + buf[j*(cycles/16) + m] = 0; + for(n = 0; n < 16; n++) { + if (fs_remain > 0) { + buf[j*(cycles/16) + m] |= (1<< n); + fs_remain --; + } else { + break; + } + } + } + } + } + + I2S_TDM_TRACE(1,"%s done.", __func__); + return 0; + +__func_fail: + I2S_TDM_TRACE(2,"%s failed. ret = %d.", __func__, ret); + return ret; +} + +int32_t hal_i2s_tdm_start_stream(enum HAL_I2S_ID_T i2s_id) +{ + uint32_t i; + int ret; + + I2S_TDM_TRACE(2,"%s: i2s_id = %d.", __func__, i2s_id); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + + memset(&tx_dma_cfg[i2s_id], 0, sizeof(tx_dma_cfg[i2s_id])); + tx_dma_cfg[i2s_id].dst = 0; //useless + tx_dma_cfg[i2s_id].dst_bsize = HAL_DMA_BSIZE_4; + tx_dma_cfg[i2s_id].dst_periph = i2s_id == HAL_I2S_ID_0 ? HAL_AUDMA_I2S0_TX : HAL_AUDMA_I2S1_TX; + tx_dma_cfg[i2s_id].dst_width = HAL_DMA_WIDTH_HALFWORD; + tx_dma_cfg[i2s_id].handler = i2s_id == HAL_I2S_ID_0 ? i2s_tdm0_tx_handler : i2s_tdm1_tx_handler; + tx_dma_cfg[i2s_id].src_bsize = HAL_DMA_BSIZE_4; + tx_dma_cfg[i2s_id].src_tsize = (sizeof(i2s_tdm_tx_buf[i2s_id][0])/2); + tx_dma_cfg[i2s_id].src_width = HAL_DMA_WIDTH_HALFWORD; + tx_dma_cfg[i2s_id].try_burst = 1; + tx_dma_cfg[i2s_id].type = HAL_DMA_FLOW_M2P_DMA; + tx_dma_cfg[i2s_id].ch = hal_audma_get_chan(tx_dma_cfg[i2s_id].dst_periph, HAL_DMA_HIGH_PRIO); + + for (i = 0; i < I2S_TDM_TX_FRAME_NUM; i++) { + tx_dma_cfg[i2s_id].src = (uint32_t)&i2s_tdm_tx_buf[i2s_id][i][0]; + ret = hal_audma_init_desc(&i2s_tdm_tx_dma_desc[i2s_id][i], + &tx_dma_cfg[i2s_id], + &i2s_tdm_tx_dma_desc[i2s_id][(i + 1) % I2S_TDM_TX_FRAME_NUM], + 1); + if(ret) + { + I2S_TDM_TRACE(2,"%s: hal_audma_init_desc tx failed.ret = %d.", __func__, ret); + goto __func_fail; + } + } + + ret = hal_audma_sg_start(&i2s_tdm_tx_dma_desc[i2s_id][0], &tx_dma_cfg[i2s_id]); + if(ret) + { + I2S_TDM_TRACE(2,"%s: hal_audma_sg_start tx failed.ret = %d.", __func__, ret); + goto __func_fail; + } + + // i2s start stream playback and capture. + ret = hal_i2s_start_stream(i2s_id, AUD_STREAM_PLAYBACK); + if(ret) + { + I2S_TDM_TRACE(2,"%s: hal_i2s_start_stream failed.ret = %d.", __func__, ret); + } + + ret = hal_i2s_start_stream(i2s_id, AUD_STREAM_CAPTURE); + if(ret) + { + I2S_TDM_TRACE(1,"hal_i2s_start_stream tx failed.ret = %d.", ret); + goto __func_fail; + } + + I2S_TDM_TRACE(1,"%s done.", __func__); + return ret; + +__func_fail: + I2S_TDM_TRACE(2,"%s failed.ret = %d.", __func__, ret); + return ret; +} + +int32_t hal_i2s_tdm_stop_stream(enum HAL_I2S_ID_T i2s_id) +{ + I2S_TDM_TRACE(2,"%s: i2s_id = %d.", __func__, i2s_id); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + + hal_dma_stop(tx_dma_cfg[i2s_id].ch); + hal_i2s_stop_stream(i2s_id,AUD_STREAM_PLAYBACK); + hal_i2s_stop_stream(i2s_id,AUD_STREAM_CAPTURE); + + I2S_TDM_TRACE(1,"%s done.", __func__); + return 0; +} + +int32_t hal_i2s_tdm_close(enum HAL_I2S_ID_T i2s_id) +{ + I2S_TDM_TRACE(2,"%s: i2s_id = %d.", __func__, i2s_id); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + + hal_i2s_close(i2s_id,AUD_STREAM_PLAYBACK); + hal_i2s_close(i2s_id,AUD_STREAM_CAPTURE); + + I2S_TDM_TRACE(1,"%s done.", __func__); + return 0; +} + +void hal_i2s_tdm_get_config(enum HAL_I2S_ID_T i2s_id,struct HAL_I2S_TDM_CONFIG_T *tdm_cfg) +{ + I2S_TDM_TRACE(2,"%s: i2s_id = %d.", __func__, i2s_id); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + + *tdm_cfg = i2s_tdm_cfg[i2s_id]; +} + +void hal_i2s_tdm_set_config(enum HAL_I2S_ID_T i2s_id,struct HAL_I2S_TDM_CONFIG_T *tdm_cfg) +{ + I2S_TDM_TRACE(2,"%s: i2s_id = %d.", __func__, i2s_id); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + + i2s_tdm_cfg[i2s_id] = *tdm_cfg; +} + diff --git a/platform/hal/hal_i2s_tdm.h b/platform/hal/hal_i2s_tdm.h new file mode 100644 index 0000000..ae21211 --- /dev/null +++ b/platform/hal/hal_i2s_tdm.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_I2S_TDM_H__ +#define __HAL_I2S_TDM_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "hal_i2s.h" +#include "hal_tdm.h" + +#define I2S_TDM_BUF_ALIGN __attribute__((aligned(0x100))) + +enum HAL_I2S_TDM_CYCLES_T { + HAL_I2S_TDM_CYCLES_16 = HAL_TDM_CYCLES_16, + HAL_I2S_TDM_CYCLES_32 = HAL_TDM_CYCLES_32, + HAL_I2S_TDM_CYCLES_64 = HAL_TDM_CYCLES_64, + HAL_I2S_TDM_CYCLES_128 = HAL_TDM_CYCLES_128, + HAL_I2S_TDM_CYCLES_256 = HAL_TDM_CYCLES_256, + HAL_I2S_TDM_CYCLES_512 = HAL_TDM_CYCLES_512, + HAL_I2S_TDM_CYCLES_NUM, +}; + +enum HAL_I2S_TDM_FS_CYCLES_T { + HAL_I2S_TDM_FS_CYCLES_ONE_LESS = HAL_TDM_FS_CYCLES_ONE_LESS, + HAL_I2S_TDM_FS_CYCLES_1 = HAL_TDM_FS_CYCLES_1, + HAL_I2S_TDM_FS_CYCLES_8 = HAL_TDM_FS_CYCLES_8, + HAL_I2S_TDM_FS_CYCLES_16 = HAL_TDM_FS_CYCLES_16, + HAL_I2S_TDM_FS_CYCLES_32 = HAL_TDM_FS_CYCLES_32, + HAL_I2S_TDM_FS_CYCLES_64 = HAL_TDM_FS_CYCLES_64, + HAL_I2S_TDM_FS_CYCLES_128 = HAL_TDM_FS_CYCLES_128, + HAL_I2S_TDM_FS_CYCLES_256 = HAL_TDM_FS_CYCLES_256, +}; + +enum HAL_I2S_TDM_SLOT_CYCLES_T { + HAL_I2S_TDM_SLOT_CYCLES_32 = HAL_TDM_SLOT_CYCLES_32, + HAL_I2S_TDM_SLOT_CYCLES_16 = HAL_TDM_SLOT_CYCLES_16, +}; + +struct HAL_I2S_TDM_CONFIG_T { + enum HAL_I2S_TDM_CYCLES_T cycles; + enum HAL_I2S_TDM_FS_CYCLES_T fs_cycles; + enum HAL_I2S_TDM_SLOT_CYCLES_T slot_cycles; + uint32_t data_offset; +}; + +int32_t hal_i2s_tdm_open(enum HAL_I2S_ID_T i2s_id,enum HAL_I2S_MODE_T mode); +int32_t hal_i2s_tdm_setup(enum HAL_I2S_ID_T i2s_id, + uint32_t sample_rate, + struct HAL_I2S_TDM_CONFIG_T *i2s_tdm_cfg); +int32_t hal_i2s_tdm_start_stream(enum HAL_I2S_ID_T i2s_id); +int32_t hal_i2s_tdm_stop_stream(enum HAL_I2S_ID_T i2s_id); +int32_t hal_i2s_tdm_close(enum HAL_I2S_ID_T i2s_id); +void hal_i2s_tdm_set_config(enum HAL_I2S_ID_T i2s_id,struct HAL_I2S_TDM_CONFIG_T *tdm_cfg); +void hal_i2s_tdm_get_config(enum HAL_I2S_ID_T i2s_id,struct HAL_I2S_TDM_CONFIG_T *tdm_cfg); + +#ifdef __cplusplus +} +#endif + +#endif // __HAL_I2S_TDM_H__ diff --git a/platform/hal/hal_i2sip.h b/platform/hal/hal_i2sip.h new file mode 100644 index 0000000..c2657c4 --- /dev/null +++ b/platform/hal/hal_i2sip.h @@ -0,0 +1,236 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_I2SIP_H__ +#define __HAL_I2SIP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "reg_i2sip.h" +#include "hal_i2s.h" + +#define i2sip_read32(b,a) \ + (*(volatile uint32_t *)(b+a)) + +#define i2sip_write32(v,b,a) \ + ((*(volatile uint32_t *)(b+a)) = v) + +static inline void i2sip_w_enable_i2sip(uint32_t reg_base, uint32_t v) +{ + uint32_t val = 0; + + val = i2sip_read32(reg_base, I2SIP_ENABLE_REG_REG_OFFSET); + if (v) + val |= I2SIP_ENABLE_REG_I2S_ENABLE_MASK; + else + val &= ~I2SIP_ENABLE_REG_I2S_ENABLE_MASK; + + i2sip_write32(val, reg_base, I2SIP_ENABLE_REG_REG_OFFSET); +} +#ifndef CHIP_BEST1000 +static inline void i2sip_w_enable_slave_mode(uint32_t reg_base, uint32_t v) +{ + uint32_t val = 0; + + val = i2sip_read32(reg_base, I2SIP_ENABLE_REG_REG_OFFSET); + if (v) + val |= I2SIP_ENABLE_REG_SLAVE_MODE_MASK; + else + val &= ~I2SIP_ENABLE_REG_SLAVE_MODE_MASK; + + i2sip_write32(val, reg_base, I2SIP_ENABLE_REG_REG_OFFSET); +} +#endif +static inline void i2sip_w_enable_clk_gen(uint32_t reg_base, uint32_t v) +{ + if (v) + i2sip_write32(1, reg_base, I2SIP_CLK_GEN_ENABLE_REG_REG_OFFSET); + else + i2sip_write32(0, reg_base, I2SIP_CLK_GEN_ENABLE_REG_REG_OFFSET); +} +static inline uint32_t i2sip_r_clk_gen_enabled(uint32_t reg_base) +{ + uint32_t v; + + v = i2sip_read32(reg_base, I2SIP_CLK_GEN_ENABLE_REG_REG_OFFSET); + return !!(v & I2SIP_CLK_GEN_ENABLE_REG_ENABLE_MASK); +} +static inline void i2sip_w_enable_rx_block(uint32_t reg_base, uint32_t v) +{ + if (v) + i2sip_write32(1, reg_base, I2SIP_RX_BLOCK_ENABLE_REG_REG_OFFSET); + else + i2sip_write32(0, reg_base, I2SIP_RX_BLOCK_ENABLE_REG_REG_OFFSET); +} +static inline void i2sip_w_enable_rx_channel(uint32_t reg_base, uint32_t chan, uint32_t v) +{ + if (v) + i2sip_write32(1, reg_base, I2SIP_RX_ENABLE_REG_OFFSET(chan)); + else + i2sip_write32(0, reg_base, I2SIP_RX_ENABLE_REG_OFFSET(chan)); +} +static inline void i2sip_w_enable_tx_block(uint32_t reg_base, uint32_t v) +{ + if (v) + i2sip_write32(1, reg_base, I2SIP_TX_BLOCK_ENABLE_REG_REG_OFFSET); + else + i2sip_write32(0, reg_base, I2SIP_TX_BLOCK_ENABLE_REG_REG_OFFSET); +} +static inline void i2sip_w_enable_tx_channel(uint32_t reg_base, uint32_t chan, uint32_t v) +{ + if (v) + i2sip_write32(1, reg_base, I2SIP_TX_ENABLE_REG_OFFSET(chan)); + else + i2sip_write32(0, reg_base, I2SIP_TX_ENABLE_REG_OFFSET(chan)); +} +static inline void i2sip_w_tx_resolution(uint32_t reg_base, uint32_t chan, uint32_t v) +{ + i2sip_write32(v<= HAL_INTERSYS_MSG_TYPE_QTY, "chan_opened size too small"); + +static bool need_flow_ctrl[HAL_INTERSYS_ID_QTY] = { false, false, }; + +static bool chan_busy[HAL_INTERSYS_ID_QTY] = { false, false, }; + +static bool busy_now = false; + +#ifdef PEER_IRQ_AUTO_CLEAR +static bool peer_irq_auto_clear; +#endif + +static struct CMU_T * const cmu = (struct CMU_T *)CMU_BASE; + +static struct BTCMU_T * const btcmu = (struct BTCMU_T *)BT_CMU_BASE; + +static void hal_intersys_busy(enum HAL_INTERSYS_ID_T id, bool busy) +{ + int i; + bool new_state; + + if (chan_busy[id] == busy) { + return; + } + + chan_busy[id] = busy; + + if (busy_now == busy) { + return; + } + + if (busy) { + hal_sys_wake_lock(HAL_SYS_WAKE_LOCK_USER_INTERSYS); + busy_now = true; + } else { + new_state = false; + for (i = 0; i < HAL_INTERSYS_ID_QTY; i++) { + if (chan_busy[i]) { + new_state = true; + break; + } + } + if (!new_state) { + hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_INTERSYS); + busy_now = false; + } + } +} + +#ifdef PEER_IRQ_AUTO_CLEAR +void hal_intersys_peer_irq_auto_clear(bool enable) +{ + peer_irq_auto_clear = enable; +} +#endif + +static int hal_intersys_peer_irq_set(enum HAL_INTERSYS_ID_T id, enum HAL_INTERSYS_IRQ_TYPE_T type) +{ + uint32_t value; + + if (id == HAL_INTERSYS_ID_0) { + if (type == HAL_INTERSYS_IRQ_SEND_IND) { + value = CMU_MCU2BT_DATA_IND_SET; + } else { + value = CMU_BT2MCU_DATA_DONE_SET; + } + } else { + if (type == HAL_INTERSYS_IRQ_SEND_IND) { + value = CMU_MCU2BT_DATA1_IND_SET; + } else { + value = CMU_BT2MCU_DATA1_DONE_SET; + } + } + +#ifdef PEER_IRQ_AUTO_CLEAR + uint32_t ret; + + ret = int_lock(); + cmu->ISIRQ_SET = value; + if (peer_irq_auto_clear) { + if (CMU_MCU2BT_DATA_IND_SET == value) { + cmu->ISIRQ_CLR |= CMU_MCU2BT_DATA_IND_CLR; + } else { + cmu->ISIRQ_CLR |= CMU_BT2MCU_DATA_DONE_CLR; + } + hal_sys_timer_delay(MS_TO_TICKS(2)); + } + int_unlock(ret); +#else + cmu->ISIRQ_SET = value; +#endif + return 0; +} + +static inline void btcmu_reg_update_wait(void) +{ + // Make sure BTCMU (26M clock domain) write opertions finish before return + btcmu->ISIRQ_CLR; +} + +static int hal_intersys_local_irq_clear(enum HAL_INTERSYS_ID_T id, enum HAL_INTERSYS_IRQ_TYPE_T type) +{ + uint32_t value; + + if (id == HAL_INTERSYS_ID_0) { + if (type == HAL_INTERSYS_IRQ_SEND_IND) { + value = BTCMU_BT2MCU_DATA_IND_CLR; + } else { + value = BTCMU_MCU2BT_DATA_DONE_CLR; + } + } else { + if (type == HAL_INTERSYS_IRQ_SEND_IND) { + value = BTCMU_BT2MCU_DATA1_IND_CLR; + } else { + value = BTCMU_MCU2BT_DATA1_DONE_CLR; + } + } + + btcmu->ISIRQ_CLR = value; + btcmu_reg_update_wait(); + return 0; +} + +static int hal_intersys_local_irq_set(enum HAL_INTERSYS_ID_T id, enum HAL_INTERSYS_IRQ_TYPE_T type) +{ + uint32_t value; + + if (id == HAL_INTERSYS_ID_0) { + if (type == HAL_INTERSYS_IRQ_SEND_IND) { + value = BTCMU_BT2MCU_DATA_IND_SET; + } else { + value = BTCMU_MCU2BT_DATA_DONE_SET; + } + } else { + if (type == HAL_INTERSYS_IRQ_SEND_IND) { + value = BTCMU_BT2MCU_DATA1_IND_SET; + } else { + value = BTCMU_MCU2BT_DATA1_DONE_SET; + } + } + + btcmu->ISIRQ_SET = value; + btcmu_reg_update_wait(); + return 0; +} + + +//static void hal_intersys_wait_done_idle(void) +//{ +// while(hal_cmu_get_address()->ISIRQ_SET & (CMU_BT2MCU_DATA_DONE_SET |CMU_BT2MCU_DATA1_DONE_SET)); +//} + + +//static void hal_intersys_wait_data_idle(void) +//{ +// while(hal_cmu_get_address()->ISIRQ_SET & (CMU_MCU2BT_DATA_IND_SET |CMU_MCU2BT_DATA1_IND_SET)); +//} +debug_intersys_type g_debug_intersys; +static void hal_intersys_rx_irq(void) +{ + int id; + struct HAL_INTERSYS_MSG_T *msg_ptr; + enum HAL_INTERSYS_MSG_TYPE_T type; + unsigned int processed; + + if (g_debug_intersys.cmd_opcode != 0xFFFF){ + g_debug_intersys.irq_happen += 1; + } + + for (id = HAL_INTERSYS_ID_0; id < HAL_INTERSYS_ID_QTY; id++) { + if (NVIC_GetActive(rx_irq_id[id])) { + hal_intersys_local_irq_clear(id, HAL_INTERSYS_IRQ_SEND_IND); + + if (recv_pending_head[id].data) { + // Previous unprocessed message + msg_ptr = &recv_pending_head[id]; + } else { + // New message + msg_ptr = *recv_msg_list_p[id]; + } + while (msg_ptr) { + type = msg_ptr->type; + if (type >= HAL_INTERSYS_MSG_TYPE_QTY) { + // Error + ASSERT(false, "INTERSYS-RX: Invalid msg type: %d", type); + break; + } + if (rx_irq_handler[id][type]) { + processed = rx_irq_handler[id][type](msg_ptr->data, msg_ptr->len); + // Check if flow control needed + if (processed < msg_ptr->len) { + recv_pending_head[id].next = msg_ptr->next; + recv_pending_head[id].type = msg_ptr->type; + recv_pending_head[id].len = msg_ptr->len - processed; + recv_pending_head[id].data = msg_ptr->data + processed; + break; + } + } else { + // Error + ASSERT(false, "INTERSYS-RX: Handler missing"); + break; + } + msg_ptr = msg_ptr->next; + } + + if (msg_ptr == NULL) { + if (!need_flow_ctrl[id]){ + hal_intersys_peer_irq_set(id, HAL_INTERSYS_IRQ_RECV_DONE); + } + recv_pending_head[id].data = NULL; + } + } + } +} + +static void hal_intersys_tx_irq(void) +{ + int id; + struct HAL_INTERSYS_MSG_T *msg_ptr; + enum HAL_INTERSYS_MSG_TYPE_T type; + + for (id = HAL_INTERSYS_ID_0; id < HAL_INTERSYS_ID_QTY; id++) { + if (NVIC_GetActive(tx_irq_id[id])) { + hal_intersys_local_irq_clear(id, HAL_INTERSYS_IRQ_RECV_DONE); + + msg_ptr = send_msg_list_p[id]; + while (msg_ptr) { + type = msg_ptr->type; + if (type >= HAL_INTERSYS_MSG_TYPE_QTY) { + // Error + ASSERT(false, "INTERSYS-TX: Invalid msg type: %d", type); + break; + } + if (tx_irq_handler[id][type]) { + tx_irq_handler[id][type](msg_ptr->data, msg_ptr->len); + }; + CONTAINER_OF(msg_ptr, struct HAL_INTERSYS_SEND_RECORD_T, msg)->in_use = false; + msg_ptr = msg_ptr->next; + } + + if (send_pending_list_p[id]) { + send_msg_list_p[id] = send_pending_list_p[id]; + send_pending_list_p[id] = NULL; + hal_intersys_peer_irq_set(id, HAL_INTERSYS_IRQ_SEND_IND); + } else { + send_msg_list_p[id] = NULL; + // Allow sleep + hal_intersys_busy(id, false); + } + } + } +} + +int hal_intersys_open(enum HAL_INTERSYS_ID_T id, enum HAL_INTERSYS_MSG_TYPE_T type, + HAL_INTERSYS_RX_IRQ_HANDLER rxhandler, HAL_INTERSYS_TX_IRQ_HANDLER txhandler, bool rx_flowctrl) +{ + int i; + + if (id >= HAL_INTERSYS_ID_QTY) { + return 1; + } + if (type >= HAL_INTERSYS_MSG_TYPE_QTY) { + return 2; + } + + if (chan_opened[id] == 0) { + if (id == HAL_INTERSYS_ID_0) { + cmu->ISIRQ_CLR = CMU_BT2MCU_DATA_DONE_CLR | CMU_MCU2BT_DATA_IND_CLR; + } else { + cmu->ISIRQ_CLR = CMU_BT2MCU_DATA1_DONE_CLR | CMU_MCU2BT_DATA1_IND_CLR; + } + *bt_recv_msg_list_ppp[id] = &send_msg_list_p[id]; + + NVIC_SetVector(rx_irq_id[id], (uint32_t)hal_intersys_rx_irq); + NVIC_SetPriority(rx_irq_id[id], IRQ_PRIORITY_NORMAL); + + NVIC_SetVector(tx_irq_id[id], (uint32_t)hal_intersys_tx_irq); + NVIC_SetPriority(tx_irq_id[id], IRQ_PRIORITY_NORMAL); + + // Stop IRQs by default + NVIC_DisableIRQ(rx_irq_id[id]); + NVIC_DisableIRQ(tx_irq_id[id]); + + send_msg_list_p[id] = NULL; + send_pending_list_p[id] = NULL; + recv_pending_head[id].data = NULL; + for (i = 0; i < MAX_SEND_RECORD_COUNT; i++) { + send_msgs[id][i].in_use = false; + } + need_flow_ctrl[id] = rx_flowctrl; + } else { + ASSERT(need_flow_ctrl[id] == rx_flowctrl, "INTERSYS-OPEN: rx_flowctrl=%d (should be %d)", rx_flowctrl, need_flow_ctrl[id]); + return 3; + } + chan_opened[id] |= (1 << type); + + rx_irq_handler[id][type] = rxhandler; + tx_irq_handler[id][type] = txhandler; + + return 0; +} + +int hal_intersys_close(enum HAL_INTERSYS_ID_T id,enum HAL_INTERSYS_MSG_TYPE_T type) +{ + if (id >= HAL_INTERSYS_ID_QTY) { + return 1; + } + + chan_opened[id] &= ~(1 << type); + rx_irq_handler[id][type] = NULL; + tx_irq_handler[id][type] = NULL; + + if (chan_opened[id] == 0) { + // Stop IRQs by default + NVIC_DisableIRQ(rx_irq_id[id]); + NVIC_DisableIRQ(tx_irq_id[id]); + + send_msg_list_p[id] = NULL; + send_pending_list_p[id] = NULL; + recv_pending_head[id].data = NULL; + need_flow_ctrl[id] = false; + } + + return 0; +} + +int hal_intersys_start_recv(enum HAL_INTERSYS_ID_T id) +{ + if (id >= HAL_INTERSYS_ID_QTY) { + return 1; + } + + NVIC_EnableIRQ(rx_irq_id[id]); + // Check if there is any previous unprocessed message + if (recv_pending_head[id].data) { + hal_intersys_local_irq_set(id, HAL_INTERSYS_IRQ_SEND_IND); + } + return 0; +} + +int hal_intersys_stop_recv(enum HAL_INTERSYS_ID_T id) +{ + if (id >= HAL_INTERSYS_ID_QTY) { + return 1; + } + + NVIC_DisableIRQ(rx_irq_id[id]); + return 0; +} + +int hal_intersys_send(enum HAL_INTERSYS_ID_T id, enum HAL_INTERSYS_MSG_TYPE_T type, + const unsigned char *data, unsigned int len) +{ + uint32_t lock; + int ret; + struct HAL_INTERSYS_SEND_RECORD_T *record; + struct HAL_INTERSYS_MSG_T *next; + int i; + + if (id >= HAL_INTERSYS_ID_QTY) { + return 1; + } + if (type >= HAL_INTERSYS_MSG_TYPE_QTY) { + return 2; + } + if ((chan_opened[id] & (1 << type)) == 0) { + return 3; + } + + NVIC_EnableIRQ(tx_irq_id[id]); + + ret = -1; + record = &send_msgs[id][0]; + + lock = int_lock(); + for (i = 0; i < MAX_SEND_RECORD_COUNT; i++) { + if (record->in_use) { + record++; + continue; + } + record->in_use = true; + record->msg.next = NULL; + record->msg.type = type; + record->msg.len = len; + record->msg.data = data; + if (send_msg_list_p[id] == NULL) { + send_msg_list_p[id] = &record->msg; + hal_intersys_peer_irq_set(id, HAL_INTERSYS_IRQ_SEND_IND); + } else if (send_pending_list_p[id] == NULL) { + send_pending_list_p[id] = &record->msg; + } else { + next = send_pending_list_p[id]; + while (next->next) { + next = next->next; + } + next->next = &record->msg; + } + ret = 0; + // Prohibit sleep here + hal_intersys_busy(id, true); + break; + } + int_unlock(lock); + + return ret; +} + +void hal_intersys_rx_done(enum HAL_INTERSYS_ID_T id) +{ + hal_intersys_peer_irq_set(id, HAL_INTERSYS_IRQ_RECV_DONE); +} + +#endif + +#ifdef TX_RX_PCM_MASK +static FRAME2BUFF_HANDLER DecQ; + +void hal_intersys_mic_rx_irq() +{ + int id; + id = HAL_INTERSYS_ID_1; + if(NVIC_GetActive(rx_irq_id[id])) + { + hal_intersys_local_irq_clear(id, HAL_INTERSYS_IRQ_SEND_IND); + //TRACE(0,"HAL_INTERSYS_ID_1 CLEAR"); + //output data to buff + DecQ(); + } +} + +int hal_intersys_mic_open(enum HAL_INTERSYS_ID_T id, FRAME2BUFF_HANDLER dch) +{ + // if(btdrv_is_pcm_mask_enable()==1) + { + DecQ= dch; + NVIC_EnableIRQ(rx_irq_id[id]); + if(id == HAL_INTERSYS_ID_1) + { + cmu->ISIRQ_CLR = CMU_BT2MCU_DATA1_DONE_CLR | CMU_MCU2BT_DATA1_IND_CLR; + NVIC_SetVector(rx_irq_id[id], (uint32_t)hal_intersys_mic_rx_irq); + NVIC_SetPriority(rx_irq_id[id], IRQ_PRIORITY_NORMAL); + } + } + return 0; +} +#endif diff --git a/platform/hal/hal_intersys.h b/platform/hal/hal_intersys.h new file mode 100644 index 0000000..a73219d --- /dev/null +++ b/platform/hal/hal_intersys.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_INTERSYS_H__ +#define __HAL_INTERSYS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdbool.h" + +enum HAL_INTERSYS_ID_T { + HAL_INTERSYS_ID_0, + HAL_INTERSYS_ID_1, + + HAL_INTERSYS_ID_QTY +}; + +enum HAL_INTERSYS_MSG_TYPE_T { + HAL_INTERSYS_MSG_HCI, + HAL_INTERSYS_MSG_SYS, + + HAL_INTERSYS_MSG_TYPE_QTY +}; + +typedef struct debug_intersys +{ + unsigned short irq_happen; + unsigned short cmd_opcode; +}debug_intersys_type; + +typedef unsigned int (*HAL_INTERSYS_RX_IRQ_HANDLER)(const unsigned char *data, unsigned int len); +typedef void (*HAL_INTERSYS_TX_IRQ_HANDLER)(const unsigned char *data, unsigned int len); + +int hal_intersys_open(enum HAL_INTERSYS_ID_T id, enum HAL_INTERSYS_MSG_TYPE_T type, + HAL_INTERSYS_RX_IRQ_HANDLER rxhandler, HAL_INTERSYS_TX_IRQ_HANDLER txhandler, bool rx_flowctrl); + +int hal_intersys_close(enum HAL_INTERSYS_ID_T id,enum HAL_INTERSYS_MSG_TYPE_T type); + +int hal_intersys_start_recv(enum HAL_INTERSYS_ID_T id); + +int hal_intersys_stop_recv(enum HAL_INTERSYS_ID_T id); + +int hal_intersys_send(enum HAL_INTERSYS_ID_T id, enum HAL_INTERSYS_MSG_TYPE_T type, + const unsigned char *data, unsigned int len); + +void hal_intersys_rx_done(enum HAL_INTERSYS_ID_T id); + +void hal_intersys_peer_irq_auto_clear(bool enable); + +#ifdef TX_RX_PCM_MASK +typedef void (*FRAME2BUFF_HANDLER)(); + +int hal_intersys_mic_open(enum HAL_INTERSYS_ID_T id, FRAME2BUFF_HANDLER dch); + +void hal_intersys_mic_rx_irq(); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_iomux.h b/platform/hal/hal_iomux.h new file mode 100644 index 0000000..072feda --- /dev/null +++ b/platform/hal/hal_iomux.h @@ -0,0 +1,113 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_IOMUX_H__ +#define __HAL_IOMUX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "plat_addr_map.h" +#include CHIP_SPECIFIC_HDR(hal_iomux) + +enum HAL_IOMUX_OP_TYPE_T { + HAL_IOMUX_OP_KEEP_OTHER_FUNC_BIT = 0, + HAL_IOMUX_OP_CLEAN_OTHER_FUNC_BIT, +}; + +enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T { + HAL_IOMUX_PIN_VOLTAGE_VIO = 0, + HAL_IOMUX_PIN_VOLTAGE_MEM, + // For PMU LED pins only + HAL_IOMUX_PIN_VOLTAGE_VBAT, +}; + +enum HAL_IOMUX_PIN_PULL_SELECT_T { + HAL_IOMUX_PIN_NOPULL = 0, + HAL_IOMUX_PIN_PULLUP_ENABLE, + HAL_IOMUX_PIN_PULLDOWN_ENABLE, +}; + +enum HAL_PWRKEY_IRQ_T { + HAL_PWRKEY_IRQ_NONE = 0, + HAL_PWRKEY_IRQ_FALLING_EDGE = (1 << 0), + HAL_PWRKEY_IRQ_RISING_EDGE = (1 << 1), + HAL_PWRKEY_IRQ_BOTH_EDGE = (HAL_PWRKEY_IRQ_FALLING_EDGE | HAL_PWRKEY_IRQ_RISING_EDGE), +}; + +struct HAL_IOMUX_PIN_FUNCTION_MAP { + enum HAL_IOMUX_PIN_T pin; + enum HAL_IOMUX_FUNCTION_T function; + enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt; + enum HAL_IOMUX_PIN_PULL_SELECT_T pull_sel; +}; + +uint32_t hal_iomux_check(const struct HAL_IOMUX_PIN_FUNCTION_MAP *map, uint32_t count); +uint32_t hal_iomux_init(const struct HAL_IOMUX_PIN_FUNCTION_MAP *map, uint32_t count); +uint32_t hal_iomux_set_function(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_FUNCTION_T func, enum HAL_IOMUX_OP_TYPE_T type); +enum HAL_IOMUX_FUNCTION_T hal_iomux_get_function(enum HAL_IOMUX_PIN_T pin); +uint32_t hal_iomux_set_io_voltage_domains(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt); +uint32_t hal_iomux_set_io_pull_select(enum HAL_IOMUX_PIN_T pin, enum HAL_IOMUX_PIN_PULL_SELECT_T pull_sel); + +void hal_iomux_set_default_config(void); +void hal_iomux_set_uart0_voltage(enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt); +void hal_iomux_set_uart1_voltage(enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt); +void hal_iomux_set_uart2_voltage(enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt); +bool hal_iomux_uart0_connected(void); +bool hal_iomux_uart1_connected(void); +void hal_iomux_set_uart0(void); +void hal_iomux_set_uart1(void); +void hal_iomux_set_uart2(void); +void hal_iomux_set_analog_i2c(void); +void hal_iomux_set_analog_i2c_master_slave(void); +void hal_iomux_set_jtag(void); +void hal_iomux_set_sdmmc_dt_n_out_group(int enable); +void hal_iomux_set_i2s0(void); +void hal_iomux_set_i2s1(void); +void hal_iomux_set_spdif0(void); +void hal_iomux_set_spdif1(void); +void hal_iomux_set_dig_mic_clock_pin(enum HAL_IOMUX_PIN_T pin); +void hal_iomux_set_dig_mic_data0_pin(enum HAL_IOMUX_PIN_T pin); +void hal_iomux_set_dig_mic_data1_pin(enum HAL_IOMUX_PIN_T pin); +void hal_iomux_set_dig_mic_data2_pin(enum HAL_IOMUX_PIN_T pin); +void hal_iomux_set_dig_mic(uint32_t map); +void hal_iomux_set_spi(void); +void hal_iomux_set_spilcd(void); +void hal_iomux_set_i2c0(void); +void hal_iomux_set_i2c1(void); +void hal_iomux_set_clock_out(void); +void hal_iomux_set_clock_12m(void); +void hal_iomux_clear_clock_12m(void); +void hal_iomux_set_bt_tport(void); +void hal_iomux_set_bt_rf_sw(int rx_on, int tx_on); + +void hal_iomux_ispi_access_init(void); +enum HAL_IOMUX_ISPI_ACCESS_T hal_iomux_ispi_access_enable(enum HAL_IOMUX_ISPI_ACCESS_T access); +enum HAL_IOMUX_ISPI_ACCESS_T hal_iomux_ispi_access_disable(enum HAL_IOMUX_ISPI_ACCESS_T access); + +int hal_pwrkey_set_irq(enum HAL_PWRKEY_IRQ_T type); +bool hal_pwrkey_pressed(void); +bool hal_pwrkey_startup_pressed(void); +enum HAL_PWRKEY_IRQ_T hal_pwrkey_get_irq_state(void); + +void hal_iomux_set_codec_gpio_trigger(enum HAL_IOMUX_PIN_T pin, bool polarity); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_key.c b/platform/hal/hal_key.c new file mode 100644 index 0000000..5c6f53f --- /dev/null +++ b/platform/hal/hal_key.c @@ -0,0 +1,1183 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include "plat_types.h" +#include "string.h" +#include "hal_iomux.h" +#include "hal_timer.h" +#include "hwtimer_list.h" +#include "hal_sleep.h" +#include "hal_trace.h" +#include "hal_chipid.h" +#include "hal_key.h" +#include "cmsis_nvic.h" +#include "pmu.h" +#include "tgt_hardware.h" + +#ifdef KEY_DEBUG +#define HAL_KEY_TRACE(n, s, ...) TRACE(n, "[%u]" s, TICKS_TO_MS(hal_sys_timer_get()), ##__VA_ARGS__) +#else +#define HAL_KEY_TRACE(n, s, ...) TRACE_DUMMY(n, s, ##__VA_ARGS__) +#endif + +#ifdef CHIP_BEST2000 +#define GPIO_MAP_64BIT +#endif + +#ifdef GPIO_MAP_64BIT +typedef uint64_t GPIO_MAP_T; +#else +typedef uint32_t GPIO_MAP_T; +#endif + +#ifndef APP_TEST_MODE +#define CHECK_PWRKEY_AT_BOOT +#endif +#ifdef NO_PWRKEY +#undef CHECK_PWRKEY_AT_BOOT +#endif +#ifdef NO_GPIOKEY +#undef CFG_HW_GPIOKEY_NUM +#define CFG_HW_GPIOKEY_NUM 0 +#endif +#ifdef NO_ADCKEY +#undef CFG_HW_ADCKEY_NUMBER +#define CFG_HW_ADCKEY_NUMBER 0 +#endif + +#ifndef CFG_SW_KEY_LLPRESS_THRESH_MS +#define CFG_SW_KEY_LLPRESS_THRESH_MS 5000 +#endif +#ifndef CFG_SW_KEY_LPRESS_THRESH_MS +#define CFG_SW_KEY_LPRESS_THRESH_MS 1500 +#endif +#ifndef CFG_SW_KEY_REPEAT_THRESH_MS +#define CFG_SW_KEY_REPEAT_THRESH_MS 500 +#endif +#ifndef CFG_SW_KEY_DBLCLICK_THRESH_MS +#define CFG_SW_KEY_DBLCLICK_THRESH_MS 400 +#endif +#ifndef CFG_SW_KEY_INIT_DOWN_THRESH_MS +#define CFG_SW_KEY_INIT_DOWN_THRESH_MS 200 +#endif +#ifndef CFG_SW_KEY_INIT_LPRESS_THRESH_MS +#define CFG_SW_KEY_INIT_LPRESS_THRESH_MS 3000 +#endif +#ifndef CFG_SW_KEY_INIT_LLPRESS_THRESH_MS +#define CFG_SW_KEY_INIT_LLPRESS_THRESH_MS 10000 +#endif +#ifndef CFG_SW_KEY_CHECK_INTERVAL_MS +#define CFG_SW_KEY_CHECK_INTERVAL_MS 40 +#endif + +//common key define +#define KEY_LONGLONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_LLPRESS_THRESH_MS) +#define KEY_LONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_LPRESS_THRESH_MS) +#define KEY_DOUBLECLICK_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_DBLCLICK_THRESH_MS) +#define KEY_LONGPRESS_REPEAT_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_REPEAT_THRESH_MS) + +#define KEY_INIT_DOWN_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_INIT_DOWN_THRESH_MS) +#define KEY_INIT_LONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_INIT_LPRESS_THRESH_MS) +#define KEY_INIT_LONGLONGPRESS_THRESHOLD MS_TO_TICKS(CFG_SW_KEY_INIT_LLPRESS_THRESH_MS) + +#define KEY_CHECKER_INTERVAL MS_TO_TICKS(CFG_SW_KEY_CHECK_INTERVAL_MS) + +#define KEY_DEBOUNCE_INTERVAL (KEY_CHECKER_INTERVAL * 2) +#define KEY_DITHER_INTERVAL (KEY_CHECKER_INTERVAL * 1) + +#define MAX_KEY_CLICK_COUNT (HAL_KEY_EVENT_RAMPAGECLICK - HAL_KEY_EVENT_CLICK) + +struct HAL_KEY_ADCKEY_T { + bool debounce; + bool dither; + enum HAL_KEY_CODE_T code_debounce; + enum HAL_KEY_CODE_T code_down; + uint32_t time; +}; + +struct HAL_KEY_GPIOKEY_T { + GPIO_MAP_T pin_debounce; + GPIO_MAP_T pin_dither; + GPIO_MAP_T pin_down; + uint32_t time_debounce; + uint32_t time_dither; +}; + +struct HAL_KEY_PWRKEY_T { + bool debounce; + bool dither; + bool pressed; + uint32_t time; +}; + +struct HAL_KEY_STATUS_T { + enum HAL_KEY_CODE_T code_down; + enum HAL_KEY_CODE_T code_ready; + enum HAL_KEY_CODE_T code_click; + enum HAL_KEY_EVENT_T event; + uint32_t time_updown; + uint32_t time_click; + uint8_t cnt_repeat; + uint8_t cnt_click; +}; + +static int (*key_detected_callback)(uint32_t, uint8_t) = NULL; +static HWTIMER_ID debounce_timer = NULL; +static bool timer_active = false; +static struct HAL_KEY_STATUS_T key_status; + +static void hal_key_disable_allint(void); +static void hal_key_enable_allint(void); + +static int send_key_event(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event) +{ + if (key_detected_callback) { + return key_detected_callback(code, event); + } + return 0; +} + +static void hal_key_debounce_timer_restart(void) +{ + uint32_t lock; + bool set = false; + + lock = int_lock(); + if (!timer_active) { + timer_active = true; + set = true; + } + int_unlock(lock); + + if (set) { + hwtimer_stop(debounce_timer); + hwtimer_start(debounce_timer, KEY_CHECKER_INTERVAL); + //hal_sys_wake_lock(HAL_SYS_WAKE_LOCK_USER_KEY); + } +} + +#if (CFG_HW_ADCKEY_NUMBER > 0) +static uint16_t adckey_volt_table[CFG_HW_ADCKEY_NUMBER]; +struct HAL_KEY_ADCKEY_T adc_key; + +static inline POSSIBLY_UNUSED void hal_adckey_enable_press_int(void) +{ + hal_adckey_set_irq(HAL_ADCKEY_IRQ_PRESSED); +} + +static inline POSSIBLY_UNUSED void hal_adckey_enable_release_int(void) +{ + hal_adckey_set_irq(HAL_ADCKEY_IRQ_RELEASED); +} + +static inline POSSIBLY_UNUSED void hal_adckey_enable_adc_int(void) +{ + hal_gpadc_open(HAL_GPADC_CHAN_ADCKEY, HAL_GPADC_ATP_NULL, NULL); +} + +static inline POSSIBLY_UNUSED void hal_adckey_disable_adc_int(void) +{ + hal_gpadc_close(HAL_GPADC_CHAN_ADCKEY); +} + +static inline POSSIBLY_UNUSED void hal_adckey_disable_allint(void) +{ + hal_gpadc_close(HAL_GPADC_CHAN_ADCKEY); + hal_adckey_set_irq(HAL_ADCKEY_IRQ_NONE); +} + +static inline POSSIBLY_UNUSED void hal_adckey_reset(void) +{ + memset(&adc_key, 0, sizeof(adc_key)); +} + +static enum HAL_KEY_CODE_T hal_adckey_findkey(uint16_t volt) +{ + int index = 0; + +#if 0 + if (volt == HAL_GPADC_BAD_VALUE) { + return HAL_KEY_CODE_NONE; + } +#endif + + if (CFG_HW_ADCKEY_ADC_KEYVOLT_BASE < volt && volt < CFG_HW_ADCKEY_ADC_MAXVOLT) { + for (index = 0; index < CFG_HW_ADCKEY_NUMBER; index++) { + if (volt <= adckey_volt_table[index]) { + return CFG_HW_ADCKEY_MAP_TABLE[index]; + } + } + } + + return HAL_KEY_CODE_NONE; +} + +static void hal_adckey_irqhandler(enum HAL_ADCKEY_IRQ_STATUS_T irq_status, HAL_GPADC_MV_T val) +{ + enum HAL_KEY_CODE_T code; + +#ifdef NO_GROUPKEY + hal_key_disable_allint(); +#else + hal_adckey_disable_allint(); +#endif + + if (irq_status & (HAL_ADCKEY_ERR0 | HAL_ADCKEY_ERR1)) { + HAL_KEY_TRACE(1,"irq,adckey err 0x%04X", irq_status); + adc_key.debounce = true; + adc_key.code_debounce = HAL_KEY_CODE_NONE; + goto _debounce; + } + if (irq_status & HAL_ADCKEY_PRESSED) { + HAL_KEY_TRACE(0,"irq,adckey press"); + adc_key.debounce = true; + adc_key.code_debounce = HAL_KEY_CODE_NONE; + adc_key.time = hal_sys_timer_get(); + hal_adckey_enable_adc_int(); + goto _exit; + } + if (irq_status & HAL_ADCKEY_RELEASED) { + HAL_KEY_TRACE(0,"irq,adckey release"); + adc_key.code_debounce = HAL_KEY_CODE_NONE; + goto _debounce; + } + if(irq_status & HAL_ADCKEY_ADC_VALID) { + code = hal_adckey_findkey(val); + HAL_KEY_TRACE(3,"irq,adckey cur:0x%X pre:0x%X volt:%d", code, adc_key.code_debounce, val); + + if (adc_key.code_debounce == HAL_KEY_CODE_NONE) { + adc_key.code_debounce = code; + } else if (adc_key.code_debounce != code) { + adc_key.code_debounce = HAL_KEY_CODE_NONE; + } + } + +_debounce: + hal_key_debounce_timer_restart(); +_exit: + return; +} + +static void hal_adckey_open(void) +{ + uint16_t i; + uint32_t basevolt; + + HAL_KEY_TRACE(1,"%s\n", __func__); + + hal_adckey_reset(); + + basevolt = (CFG_HW_ADCKEY_ADC_MAXVOLT - CFG_HW_ADCKEY_ADC_MINVOLT) / (CFG_HW_ADCKEY_NUMBER + 2); + + adckey_volt_table[0] = CFG_HW_ADCKEY_ADC_KEYVOLT_BASE + basevolt; + + for(i = 1; i < CFG_HW_ADCKEY_NUMBER-1; i++) { + adckey_volt_table[i] = adckey_volt_table[i - 1] + basevolt; + } + adckey_volt_table[CFG_HW_ADCKEY_NUMBER - 1] = CFG_HW_ADCKEY_ADC_MAXVOLT; + + hal_adckey_set_irq_handler(hal_adckey_irqhandler); +} + +static void hal_adckey_close(void) +{ + HAL_KEY_TRACE(1,"%s\n", __func__); + + hal_adckey_reset(); + + hal_adckey_disable_allint(); +} +#endif // (CFG_HW_ADCKEY_NUMBER > 0) + +#ifndef NO_PWRKEY +struct HAL_KEY_PWRKEY_T pwr_key; + +static inline POSSIBLY_UNUSED void hal_pwrkey_enable_riseedge_int(void) +{ + hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_RISING_EDGE); +} + +static inline POSSIBLY_UNUSED void hal_pwrkey_enable_falledge_int(void) +{ + hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_FALLING_EDGE); +} + +static inline POSSIBLY_UNUSED void hal_pwrkey_enable_bothedge_int(void) +{ + hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_BOTH_EDGE); +} + +static inline void hal_pwrkey_enable_int(void) +{ +#ifdef __POWERKEY_CTRL_ONOFF_ONLY__ + hal_pwrkey_enable_riseedge_int(); +#else + hal_pwrkey_enable_falledge_int(); +#endif +} + +static inline void hal_pwrkey_disable_int(void) +{ + hal_pwrkey_set_irq(HAL_PWRKEY_IRQ_NONE); +} + +static inline void hal_pwrkey_reset(void) +{ + memset(&pwr_key, 0, sizeof(pwr_key)); +} + +static inline bool hal_pwrkey_get_status(void) +{ +#ifdef CHIP_BEST1000 + if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_2) { + return pwr_key.pressed; + } else +#endif + { + return hal_pwrkey_pressed(); + } +} + +static void hal_pwrkey_handle_irq_state(enum HAL_PWRKEY_IRQ_T state) +{ +// uint32_t time = hal_sys_timer_get(); + +#ifdef NO_GROUPKEY + hal_key_disable_allint(); +#else + hal_pwrkey_disable_int(); +#endif + +#ifdef __POWERKEY_CTRL_ONOFF_ONLY__ + + if (state & HAL_PWRKEY_IRQ_RISING_EDGE) { + HAL_KEY_TRACE(0,"pwr_key irq up"); + pwr_key.debounce = true; + } + +#else // !__POWERKEY_CTRL_ONOFF_ONLY__ + + if (state & HAL_PWRKEY_IRQ_FALLING_EDGE) { + HAL_KEY_TRACE(0,"pwr_key irq down"); +#ifdef CHIP_BEST1000 + if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_2) { + pwr_key.debounce = true; + pwr_key.pressed = true; + hal_pwrkey_enable_riseedge_int(); + } else +#endif + { + pwr_key.pressed = hal_pwrkey_pressed(); + if (pwr_key.pressed) { + pwr_key.debounce = true; + } else { + pwr_key.dither = true; + } + } + // pwr_key.time = time; + } + +#ifdef CHIP_BEST1000 + if (state & HAL_PWRKEY_IRQ_RISING_EDGE) { + if (hal_get_chip_metal_id() < HAL_CHIP_METAL_ID_2) { + HAL_KEY_TRACE(0,"pwr_key irq up"); + pwr_key.pressed = false; + hal_pwrkey_enable_falledge_int(); + } + } +#endif + +#endif // !__POWERKEY_CTRL_ONOFF_ONLY__ + + hal_key_debounce_timer_restart(); +} + +#ifdef CHIP_HAS_EXT_PMU +#define PWRKEY_IRQ_HDLR_PARAM uint16_t irq_status +#else +#define PWRKEY_IRQ_HDLR_PARAM void +#endif +static void hal_pwrkey_irqhandler(PWRKEY_IRQ_HDLR_PARAM) +{ + enum HAL_PWRKEY_IRQ_T state; + +#ifdef CHIP_HAS_EXT_PMU + state = pmu_pwrkey_irq_value_to_state(irq_status); +#else + state = hal_pwrkey_get_irq_state(); +#endif + + HAL_KEY_TRACE(2,"%s: %08x", __func__, state); + + hal_pwrkey_handle_irq_state(state); +} + +static void hal_pwrkey_open(void) +{ + hal_pwrkey_reset(); + +#ifdef CHIP_HAS_EXT_PMU + pmu_set_irq_unified_handler(PMU_IRQ_TYPE_PWRKEY, hal_pwrkey_irqhandler); +#else + NVIC_SetVector(PWRKEY_IRQn, (uint32_t)hal_pwrkey_irqhandler); + NVIC_SetPriority(PWRKEY_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(PWRKEY_IRQn); + NVIC_EnableIRQ(PWRKEY_IRQn); +#endif +} + +static void hal_pwrkey_close(void) +{ + hal_pwrkey_reset(); + + hal_pwrkey_disable_int(); + +#ifdef CHIP_HAS_EXT_PMU + pmu_set_irq_unified_handler(PMU_IRQ_TYPE_PWRKEY, NULL); +#else + NVIC_SetVector(PWRKEY_IRQn, (uint32_t)NULL); + NVIC_DisableIRQ(PWRKEY_IRQn); +#endif +} +#endif // !NO_PWRKEY + +#if (CFG_HW_GPIOKEY_NUM > 0) +struct HAL_KEY_GPIOKEY_T gpio_key; + +static void hal_gpiokey_disable_irq(enum HAL_GPIO_PIN_T pin); + +static inline void hal_gpiokey_reset(void) +{ + memset(&gpio_key, 0, sizeof(gpio_key)); +} + +static int hal_gpiokey_find_index(enum HAL_GPIO_PIN_T pin) +{ + int i; + + for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++) { + if (cfg_hw_gpio_key_cfg[i].key_config.pin == (enum HAL_IOMUX_PIN_T)pin) { + return i; + } + } + + ASSERT(i < CFG_HW_GPIOKEY_NUM, "GPIOKEY IRQ: Invalid pin=%d", pin); + return i; +} + +static bool hal_gpiokey_pressed(enum HAL_GPIO_PIN_T pin) +{ + int i = hal_gpiokey_find_index(pin); + return (hal_gpio_pin_get_val(pin) == cfg_hw_gpio_key_cfg[i].key_down); +} + +static void hal_gpiokey_irqhandler(enum HAL_GPIO_PIN_T pin) +{ + bool pressed; + uint32_t lock; + uint32_t time; + +#ifdef NO_GROUPKEY + hal_key_disable_allint(); +#else + hal_gpiokey_disable_irq(pin); +#endif + + pressed = hal_gpiokey_pressed(pin); + HAL_KEY_TRACE(2,"gpio_key trig=%d pressed=%d", pin, pressed); + + time = hal_sys_timer_get(); + + lock = int_lock(); + if (pressed) { + gpio_key.pin_debounce |= ((GPIO_MAP_T)1 << pin); + gpio_key.time_debounce = time; + } else { + gpio_key.pin_dither |= ((GPIO_MAP_T)1 << pin); + gpio_key.time_dither = time; + } + int_unlock(lock); + + hal_key_debounce_timer_restart(); +} + +static void hal_gpiokey_enable_irq(enum HAL_GPIO_PIN_T pin, enum HAL_GPIO_IRQ_POLARITY_T polarity) +{ + struct HAL_GPIO_IRQ_CFG_T gpiocfg; + + hal_gpio_pin_set_dir(pin, HAL_GPIO_DIR_IN, 0); + + gpiocfg.irq_enable = true; + gpiocfg.irq_debounce = true; + gpiocfg.irq_polarity = polarity; + gpiocfg.irq_handler = hal_gpiokey_irqhandler; + gpiocfg.irq_type = HAL_GPIO_IRQ_TYPE_LEVEL_SENSITIVE; + + hal_gpio_setup_irq(pin, &gpiocfg); +} + +static void hal_gpiokey_disable_irq(enum HAL_GPIO_PIN_T pin) +{ + static const struct HAL_GPIO_IRQ_CFG_T gpiocfg = { + .irq_enable = false, + .irq_debounce = false, + .irq_polarity = HAL_GPIO_IRQ_POLARITY_LOW_FALLING, + .irq_handler = NULL, + .irq_type = HAL_GPIO_IRQ_TYPE_LEVEL_SENSITIVE, + }; + + hal_gpio_setup_irq(pin, &gpiocfg); +} + +static inline void hal_gpiokey_enable_allint(void) +{ + uint8_t i; + enum HAL_GPIO_IRQ_POLARITY_T polarity; + + for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++){ + if (cfg_hw_gpio_key_cfg[i].key_code == HAL_KEY_CODE_NONE) { + continue; + } + + if (cfg_hw_gpio_key_cfg[i].key_down == HAL_KEY_GPIOKEY_VAL_LOW) { + polarity = HAL_GPIO_IRQ_POLARITY_LOW_FALLING; + } else { + polarity = HAL_GPIO_IRQ_POLARITY_HIGH_RISING; + } + hal_gpiokey_enable_irq((enum HAL_GPIO_PIN_T)cfg_hw_gpio_key_cfg[i].key_config.pin, polarity); + } +} + +static inline void hal_gpiokey_disable_allint(void) +{ + uint8_t i; + + for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++) { + if (cfg_hw_gpio_key_cfg[i].key_code == HAL_KEY_CODE_NONE) { + continue; + } + + hal_gpiokey_disable_irq((enum HAL_GPIO_PIN_T)cfg_hw_gpio_key_cfg[i].key_config.pin); + } +} + +static void hal_gpiokey_open(void) +{ + uint8_t i; + HAL_KEY_TRACE(1,"%s\n", __func__); + + hal_gpiokey_reset(); + + for (i = 0; i < CFG_HW_GPIOKEY_NUM; i++) { + if (cfg_hw_gpio_key_cfg[i].key_code == HAL_KEY_CODE_NONE) { + continue; + } + + hal_iomux_init(&cfg_hw_gpio_key_cfg[i].key_config, 1); + } +} + +static void hal_gpiokey_close(void) +{ + HAL_KEY_TRACE(1,"%s\n", __func__); + + hal_gpiokey_reset(); + + hal_gpiokey_disable_allint(); +} +#endif // (CFG_HW_GPIOKEY_NUM > 0) + +enum HAL_KEY_EVENT_T hal_key_read_status(enum HAL_KEY_CODE_T code) +{ + uint8_t gpio_val; + int i; + + if (code == HAL_KEY_CODE_PWR){ + if (hal_pwrkey_pressed()) + return HAL_KEY_EVENT_DOWN; + else + return HAL_KEY_EVENT_UP; + }else{ + for(i = 0; i < CFG_HW_GPIOKEY_NUM; i++) { + if(cfg_hw_gpio_key_cfg[i].key_code == code) { + gpio_val = hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)cfg_hw_gpio_key_cfg[i].key_config.pin); + if (gpio_val == cfg_hw_gpio_key_cfg[i].key_down) { + return HAL_KEY_EVENT_DOWN; + } else { + return HAL_KEY_EVENT_UP; + } + } + } + } + return HAL_KEY_EVENT_NONE; +} + +static void hal_key_disable_allint(void) +{ +#ifndef NO_PWRKEY + hal_pwrkey_disable_int(); +#endif + +#if (CFG_HW_ADCKEY_NUMBER > 0) + hal_adckey_disable_allint(); +#endif + +#if (CFG_HW_GPIOKEY_NUM > 0) + hal_gpiokey_disable_allint(); +#endif +} + +static void hal_key_enable_allint(void) +{ +#ifndef NO_PWRKEY + hal_pwrkey_enable_int(); +#endif + +#if (CFG_HW_ADCKEY_NUMBER > 0) + hal_adckey_enable_press_int(); +#endif + +#if (CFG_HW_GPIOKEY_NUM > 0) + hal_gpiokey_enable_allint(); +#endif +} + +static void hal_key_debounce_handler(void *param) +{ + uint32_t time; + enum HAL_KEY_CODE_T code_down = HAL_KEY_CODE_NONE; + int index; + bool need_timer = false; + + timer_active = false; + + time = hal_sys_timer_get(); + +#ifndef NO_PWRKEY +#ifdef __POWERKEY_CTRL_ONOFF_ONLY__ + if (pwr_key.debounce) { + pwr_key.debounce = false; + code_down |= HAL_KEY_CODE_PWR; +#ifdef NO_GROUPKEY + hal_key_enable_allint(); +#else + hal_pwrkey_enable_int(); +#endif + } +#else + if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) { + bool pressed = hal_pwrkey_get_status(); + + //HAL_KEY_TRACE(4,"keyDbnPwr: dbn=%d dither=%d pressed=%d/%d", pwr_key.debounce, pwr_key.dither, pwr_key.pressed, pressed); + + if (pwr_key.debounce) { + pwr_key.pressed = pressed; + if (pressed) { + pwr_key.dither = false; + if (time - pwr_key.time >= KEY_DEBOUNCE_INTERVAL) { + pwr_key.debounce = false; + pwr_key.dither = false; + code_down |= HAL_KEY_CODE_PWR; + } + } else { + pwr_key.debounce = false; + pwr_key.dither = true; + pwr_key.time = time; + } + } else if (pwr_key.dither) { + if (time - pwr_key.time >= KEY_DITHER_INTERVAL) { + pwr_key.dither = false; + pwr_key.pressed = false; +#ifdef NO_GROUPKEY + hal_key_enable_allint(); +#else + hal_pwrkey_enable_int(); +#endif + } + } else if (pwr_key.pressed) { + if (pressed) { + code_down |= HAL_KEY_CODE_PWR; + } else { + pwr_key.pressed = false; +#ifdef NO_GROUPKEY + hal_key_enable_allint(); +#else + hal_pwrkey_enable_int(); +#endif + } + } + } + if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) { + need_timer = true; + } +#endif +#endif + +#if (CFG_HW_ADCKEY_NUMBER > 0) + if (adc_key.debounce || adc_key.dither || adc_key.code_down != HAL_KEY_CODE_NONE) { + bool skip_check = false; + + //HAL_KEY_TRACE(4,"keyDbnAdc: dbn=%d dither=%d code_dbn=0x%X code_down=0x%X", adc_key.debounce, adc_key.dither, adc_key.code_debounce, adc_key.code_down); + + if (adc_key.debounce) { + if (adc_key.code_debounce == HAL_KEY_CODE_NONE) { + adc_key.debounce = false; + adc_key.dither = true; + adc_key.time = time; + } else { + if (time - adc_key.time >= KEY_DEBOUNCE_INTERVAL) { + adc_key.debounce = false; + adc_key.dither = false; + adc_key.code_down = adc_key.code_debounce; + adc_key.code_debounce = HAL_KEY_CODE_NONE; + code_down |= adc_key.code_down; + } + } + } else if (adc_key.dither) { + if (time - adc_key.time >= KEY_DITHER_INTERVAL) { + adc_key.dither = false; + adc_key.code_debounce = HAL_KEY_CODE_NONE; + adc_key.code_down = HAL_KEY_CODE_NONE; +#ifdef NO_GROUPKEY + hal_key_enable_allint(); +#else + hal_adckey_enable_press_int(); +#endif + } + skip_check = true; + } else if (adc_key.code_down != HAL_KEY_CODE_NONE) { + if (adc_key.code_debounce == adc_key.code_down) { + code_down |= adc_key.code_down; + } else { + adc_key.code_down = HAL_KEY_CODE_NONE; +#ifdef NO_GROUPKEY + hal_key_enable_allint(); +#else + hal_adckey_enable_press_int(); +#endif + skip_check = true; + } + } + + if (!skip_check) { + hal_adckey_enable_adc_int(); + } + } + if (adc_key.debounce || adc_key.dither || adc_key.code_down != HAL_KEY_CODE_NONE) { + need_timer = true; + } +#endif + +#if (CFG_HW_GPIOKEY_NUM > 0) + enum HAL_GPIO_PIN_T gpio; + GPIO_MAP_T pin; + uint32_t lock; + +#ifdef GPIO_MAP_64BIT + ASSERT((gpio_key.pin_debounce & gpio_key.pin_dither) == 0 && + (gpio_key.pin_debounce & gpio_key.pin_dither) == 0 && + (gpio_key.pin_debounce & gpio_key.pin_dither) == 0, + "Bad gpio_key pin map: dbn=0x%X-%X dither=0x%X-%X down=0x%X-%X", + (uint32_t)(gpio_key.pin_debounce >> 32), (uint32_t)(gpio_key.pin_debounce), + (uint32_t)(gpio_key.pin_dither >> 32), (uint32_t)(gpio_key.pin_dither), + (uint32_t)(gpio_key.pin_down >> 32), (uint32_t)(gpio_key.pin_down)); +#if 0 + HAL_KEY_TRACE(6,"keyDbnGpio: pin_dbn=0x%X-%X pin_dither=0x%X-%X pin_down=0x%X-%X", + (uint32_t)(gpio_key.pin_debounce >> 32), (uint32_t)(gpio_key.pin_debounce), + (uint32_t)(gpio_key.pin_dither >> 32), (uint32_t)(gpio_key.pin_dither), + (uint32_t)(gpio_key.pin_down >> 32), (uint32_t)(gpio_key.pin_down)); +#endif +#else // !GPIO_MAP_64BIT + ASSERT((gpio_key.pin_debounce & gpio_key.pin_dither) == 0 && + (gpio_key.pin_debounce & gpio_key.pin_dither) == 0 && + (gpio_key.pin_debounce & gpio_key.pin_dither) == 0, + "Bad gpio_key pin map: dbn=0x%X dither=0x%X down=0x%X", + (uint32_t)gpio_key.pin_debounce, (uint32_t)gpio_key.pin_dither, (uint32_t)gpio_key.pin_down); +#if 0 + HAL_KEY_TRACE(3,"keyDbnGpio: pin_dbn=0x%X pin_dither=0x%X pin_down=0x%X", + (uint32_t)gpio_key.pin_debounce, (uint32_t)gpio_key.pin_dither, (uint32_t)gpio_key.pin_down); +#endif +#endif // !GPIO_MAP_64BIT + + if (gpio_key.pin_dither) { + if (time - gpio_key.time_dither >= KEY_DITHER_INTERVAL) { + pin = gpio_key.pin_dither; + + lock = int_lock(); + gpio_key.pin_dither &= ~pin; + int_unlock(lock); + +#ifdef NO_GROUPKEY + hal_key_enable_allint(); +#else + gpio = HAL_GPIO_PIN_P0_0; + while (pin) { + if (pin & ((GPIO_MAP_T)1 << gpio)) { + pin &= ~((GPIO_MAP_T)1 << gpio); + index = hal_gpiokey_find_index(gpio); + hal_gpiokey_enable_irq(gpio, (cfg_hw_gpio_key_cfg[index].key_down == HAL_KEY_GPIOKEY_VAL_LOW) ? + HAL_GPIO_IRQ_POLARITY_LOW_FALLING : HAL_GPIO_IRQ_POLARITY_HIGH_RISING); + } + gpio++; + } +#endif + } + } + if (gpio_key.pin_down) { + pin = gpio_key.pin_down; + + gpio = HAL_GPIO_PIN_P0_0; + while (pin) { + if (pin & ((GPIO_MAP_T)1 << gpio)) { + pin &= ~((GPIO_MAP_T)1 << gpio); + index = hal_gpiokey_find_index(gpio); + if (hal_gpio_pin_get_val(gpio) == cfg_hw_gpio_key_cfg[index].key_down) { + code_down |= cfg_hw_gpio_key_cfg[index].key_code; + } else { + gpio_key.pin_down &= ~((GPIO_MAP_T)1 << gpio); +#ifdef NO_GROUPKEY + hal_key_enable_allint(); +#else + hal_gpiokey_enable_irq(gpio, (cfg_hw_gpio_key_cfg[index].key_down == HAL_KEY_GPIOKEY_VAL_LOW) ? + HAL_GPIO_IRQ_POLARITY_LOW_FALLING : HAL_GPIO_IRQ_POLARITY_HIGH_RISING); +#endif + } + } + gpio++; + } + } + if (gpio_key.pin_debounce) { + GPIO_MAP_T down_added = 0; + GPIO_MAP_T dither_added = 0; + + pin = gpio_key.pin_debounce; + + gpio = HAL_GPIO_PIN_P0_0; + while (pin) { + if (pin & ((GPIO_MAP_T)1 << gpio)) { + pin &= ~((GPIO_MAP_T)1 << gpio); + index = hal_gpiokey_find_index(gpio); + if (hal_gpio_pin_get_val(gpio) == cfg_hw_gpio_key_cfg[index].key_down) { + if (time - gpio_key.time_debounce >= KEY_DEBOUNCE_INTERVAL) { + down_added |= ((GPIO_MAP_T)1 << gpio); + code_down |= cfg_hw_gpio_key_cfg[index].key_code; + gpio_key.pin_down |= ((GPIO_MAP_T)1 << gpio); + } + } else { + dither_added |= ((GPIO_MAP_T)1 << gpio); + } + } + gpio++; + } + + lock = int_lock(); + gpio_key.pin_debounce &= ~(down_added | dither_added); + gpio_key.pin_dither |= dither_added; + int_unlock(lock); + } + if (gpio_key.pin_dither || gpio_key.pin_down || gpio_key.pin_debounce) { + need_timer = true; + } +#endif + + enum HAL_KEY_CODE_T down_new; + enum HAL_KEY_CODE_T up_new; + enum HAL_KEY_CODE_T map; + + down_new = code_down & ~key_status.code_down; + up_new = ~code_down & key_status.code_down; + + //HAL_KEY_TRACE(5,"keyDbn: code_down=0x%X/0x%X down_new=0x%X up_new=0x%X event=%d", key_status.code_down, code_down, down_new, up_new, key_status.event); + + // Check newly up keys + map = up_new; + index = 0; + while (map) { + if (map & (1 << index)) { + map &= ~(1 << index); + send_key_event((1 << index), HAL_KEY_EVENT_UP); + if (key_status.event == HAL_KEY_EVENT_LONGPRESS || key_status.event == HAL_KEY_EVENT_LONGLONGPRESS) { + send_key_event((1 << index), HAL_KEY_EVENT_UP_AFTER_LONGPRESS); + } + key_status.time_updown = time; + } + index++; + } + + if (up_new) { + if (key_status.event == HAL_KEY_EVENT_LONGPRESS || key_status.event == HAL_KEY_EVENT_LONGLONGPRESS) { + // LongPress is finished when all of the LongPress keys are released + if ((code_down & key_status.code_ready) == 0) { + key_status.event = HAL_KEY_EVENT_NONE; + } + } else if (key_status.event == HAL_KEY_EVENT_DOWN) { + // Enter click handling if not in LongPress + key_status.event = HAL_KEY_EVENT_UP; + } + } + + if (key_status.event == HAL_KEY_EVENT_UP) { + //ASSERT(key_status.code_ready != HAL_KEY_CODE_NONE, "Bad code_ready"); + + if (key_status.code_click == HAL_KEY_CODE_NONE || key_status.code_click != key_status.code_ready) { + if (key_status.code_click != HAL_KEY_CODE_NONE) { + send_key_event(key_status.code_click, HAL_KEY_EVENT_CLICK + key_status.cnt_click); + } + key_status.code_click = key_status.code_ready; + key_status.cnt_click = 0; + key_status.time_click = time; + } else if (up_new && (up_new | key_status.code_down) == key_status.code_click) { + key_status.cnt_click++; + key_status.time_click = time; + } + if (time - key_status.time_click >= KEY_DOUBLECLICK_THRESHOLD || key_status.cnt_click >= MAX_KEY_CLICK_COUNT) { + send_key_event(key_status.code_click, HAL_KEY_EVENT_CLICK + key_status.cnt_click); + key_status.code_click = HAL_KEY_CODE_NONE; + key_status.cnt_click = 0; + key_status.event = HAL_KEY_EVENT_NONE; + } + } + + // Update key_status.code_down + key_status.code_down = code_down; + + // Check newly down keys and update key_status.code_ready + map = down_new; + index = 0; + while (map) { + if (map & (1 << index)) { + map &= ~(1 << index); + send_key_event((1 << index), HAL_KEY_EVENT_DOWN); + if (key_status.event == HAL_KEY_EVENT_NONE) { + send_key_event((1 << index), HAL_KEY_EVENT_FIRST_DOWN); + } else { + send_key_event((1 << index), HAL_KEY_EVENT_CONTINUED_DOWN); + } + if (key_status.event == HAL_KEY_EVENT_NONE || + key_status.event == HAL_KEY_EVENT_DOWN || + key_status.event == HAL_KEY_EVENT_UP) { + key_status.code_ready = code_down; + } + key_status.time_updown = time; + } + index++; + } + + if (down_new) { + if (key_status.event == HAL_KEY_EVENT_NONE || key_status.event == HAL_KEY_EVENT_UP) { + key_status.event = HAL_KEY_EVENT_DOWN; + } + } + + // LongPress should be stopped if any key is released + if ((code_down & key_status.code_ready) == key_status.code_ready) { + if (key_status.event == HAL_KEY_EVENT_DOWN) { + if (time - key_status.time_updown >= KEY_LONGPRESS_THRESHOLD) { + key_status.cnt_repeat = 0; + key_status.event = HAL_KEY_EVENT_LONGPRESS; + send_key_event(key_status.code_ready, key_status.event); + } + } else if (key_status.event == HAL_KEY_EVENT_LONGPRESS || key_status.event == HAL_KEY_EVENT_LONGLONGPRESS) { + key_status.cnt_repeat++; + if (key_status.cnt_repeat == KEY_LONGPRESS_REPEAT_THRESHOLD / KEY_CHECKER_INTERVAL) { + key_status.cnt_repeat = 0; + send_key_event(key_status.code_ready, HAL_KEY_EVENT_REPEAT); + } + if (key_status.event == HAL_KEY_EVENT_LONGPRESS) { + if (time - key_status.time_updown >= KEY_LONGLONGPRESS_THRESHOLD) { + key_status.event = HAL_KEY_EVENT_LONGLONGPRESS; + send_key_event(key_status.code_ready, key_status.event); + } + } + } + } + + if (key_status.event != HAL_KEY_EVENT_NONE) { + need_timer = true; + } + + if (need_timer) { + hal_key_debounce_timer_restart(); + } else { + //hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_KEY); + } +} + +#if 0//def CHECK_PWRKEY_AT_BOOT +static void hal_key_boot_handler(void *param) +{ +#ifndef NO_PWRKEY + uint32_t time; + + timer_active = false; + + time = hal_sys_timer_get(); + + if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) { + bool pressed = hal_pwrkey_get_status(); + + //HAL_KEY_TRACE(5,"keyBoot: dbn=%d dither=%d pressed=%d/%d event=%d", pwr_key.debounce, pwr_key.dither, pwr_key.pressed, pressed, key_status.event); + + if (pwr_key.debounce) { + pwr_key.pressed = pressed; + if (pressed) { + pwr_key.dither = false; + if (time - pwr_key.time >= KEY_DEBOUNCE_INTERVAL) { + pwr_key.debounce = false; + key_status.time_updown = time; + } + } else { + pwr_key.debounce = false; + pwr_key.dither = true; + pwr_key.time = time; + } + } else if (pwr_key.dither) { + if (time - pwr_key.time >= KEY_DITHER_INTERVAL) { + pwr_key.dither = false; + pwr_key.pressed = false; + } + } else if (pwr_key.pressed) { + if (!pressed) { + pwr_key.pressed = false; + } + } + } + if (pwr_key.debounce || pwr_key.dither || pwr_key.pressed) { + if (pwr_key.pressed) { + if (key_status.event == HAL_KEY_EVENT_NONE) { + if (time - key_status.time_updown >= KEY_INIT_DOWN_THRESHOLD) { + key_status.event = HAL_KEY_EVENT_INITDOWN; + send_key_event(HAL_KEY_CODE_PWR, key_status.event); + } + } else if (key_status.event == HAL_KEY_EVENT_INITDOWN) { + if (time - key_status.time_updown >= KEY_INIT_LONGPRESS_THRESHOLD) { + key_status.cnt_repeat = 0; + key_status.event = HAL_KEY_EVENT_INITLONGPRESS; + send_key_event(HAL_KEY_CODE_PWR, key_status.event); + } + } else if (key_status.event == HAL_KEY_EVENT_INITLONGPRESS) { + if (time - key_status.time_updown >= KEY_INIT_LONGLONGPRESS_THRESHOLD) { + key_status.event = HAL_KEY_EVENT_INITLONGLONGPRESS; + send_key_event(HAL_KEY_CODE_PWR, key_status.event); + } + } + } + hal_key_debounce_timer_restart(); + } else { + if (key_status.event == HAL_KEY_EVENT_NONE || key_status.event == HAL_KEY_EVENT_INITDOWN) { + send_key_event(HAL_KEY_CODE_PWR, HAL_KEY_EVENT_INITUP); + } + send_key_event(HAL_KEY_CODE_PWR, HAL_KEY_EVENT_INITFINISHED); + + hwtimer_update(debounce_timer, hal_key_debounce_handler, NULL); + //hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_KEY); + + memset(&key_status, 0, sizeof(key_status)); + hal_pwrkey_reset(); + hal_key_enable_allint(); + } +#endif +} +#endif //CHECK_PWRKEY_AT_BOOT + +int hal_key_open(int checkPwrKey, int (* cb)(uint32_t, uint8_t)) +{ + int nRet = 0; + uint32_t lock; + + key_detected_callback = cb; + + memset(&key_status, 0, sizeof(key_status)); + + lock = int_lock(); + +#ifdef CHECK_PWRKEY_AT_BOOT + if (checkPwrKey) { + int cnt; + int i = 0; + + cnt = 10; + do { + hal_sys_timer_delay(MS_TO_TICKS(150)); + if (!hal_pwrkey_startup_pressed()) { + HAL_KEY_TRACE(0,"pwr_key init DITHERING"); + nRet = -1; + goto _exit; + } + } while (++i < cnt); + } +#endif + +#ifndef NO_PWRKEY + hal_pwrkey_open(); +#endif +#if (CFG_HW_ADCKEY_NUMBER > 0) + hal_adckey_open(); +#endif +#if (CFG_HW_GPIOKEY_NUM > 0) + hal_gpiokey_open(); +#endif + +#ifdef CHECK_PWRKEY_AT_BOOT +#ifndef __POWERKEY_CTRL_ONOFF_ONLY__ + if (checkPwrKey) { + debounce_timer = hwtimer_alloc(hal_key_boot_handler, NULL); + hal_pwrkey_handle_irq_state(HAL_PWRKEY_IRQ_FALLING_EDGE); + } else +#endif +#endif + { + debounce_timer = hwtimer_alloc(hal_key_debounce_handler, NULL); + hal_key_enable_allint(); + } + + ASSERT(debounce_timer, "Failed to alloc key debounce timer"); + + goto _exit; // Avoid compiler warnings + +_exit: + int_unlock(lock); + + return nRet; +} + +int hal_key_close(void) +{ + hal_key_disable_allint(); + +#ifndef NO_PWRKEY + hal_pwrkey_close(); +#endif +#if (CFG_HW_ADCKEY_NUMBER > 0) + hal_adckey_close(); +#endif +#if (CFG_HW_GPIOKEY_NUM > 0) + hal_gpiokey_close(); +#endif + + if (debounce_timer) { + hwtimer_stop(debounce_timer); + hwtimer_free(debounce_timer); + debounce_timer = NULL; + } + timer_active = false; + key_detected_callback = NULL; + + //hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_KEY); + + return 0; +} + diff --git a/platform/hal/hal_key.h b/platform/hal/hal_key.h new file mode 100644 index 0000000..76ad248 --- /dev/null +++ b/platform/hal/hal_key.h @@ -0,0 +1,103 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_KEY_H__ +#define __HAL_KEY_H__ + +#include "hal_gpio.h" +#include "hal_gpadc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum HAL_KEY_CODE_T { + HAL_KEY_CODE_NONE = 0, + HAL_KEY_CODE_PWR = (1 << 0), + HAL_KEY_CODE_FN1 = (1 << 1), + HAL_KEY_CODE_FN2 = (1 << 2), + HAL_KEY_CODE_FN3 = (1 << 3), + HAL_KEY_CODE_FN4 = (1 << 4), + HAL_KEY_CODE_FN5 = (1 << 5), + HAL_KEY_CODE_FN6 = (1 << 6), + HAL_KEY_CODE_FN7 = (1 << 7), + HAL_KEY_CODE_FN8 = (1 << 8), + HAL_KEY_CODE_FN9 = (1 << 9), + HAL_KEY_CODE_FN10 = (1 << 10), + HAL_KEY_CODE_FN11 = (1 << 11), + HAL_KEY_CODE_FN12 = (1 << 12), + HAL_KEY_CODE_FN13 = (1 << 13), + HAL_KEY_CODE_FN14 = (1 << 14), + HAL_KEY_CODE_FN15 = (1 << 15), +}; + +enum HAL_KEY_EVENT_T { + HAL_KEY_EVENT_NONE = 0, + HAL_KEY_EVENT_DOWN, + HAL_KEY_EVENT_FIRST_DOWN, + HAL_KEY_EVENT_CONTINUED_DOWN, + HAL_KEY_EVENT_UP, + HAL_KEY_EVENT_UP_AFTER_LONGPRESS, + HAL_KEY_EVENT_LONGPRESS, + HAL_KEY_EVENT_LONGLONGPRESS, + HAL_KEY_EVENT_CLICK, + HAL_KEY_EVENT_DOUBLECLICK, + HAL_KEY_EVENT_TRIPLECLICK, + HAL_KEY_EVENT_ULTRACLICK, + HAL_KEY_EVENT_RAMPAGECLICK, + HAL_KEY_EVENT_SIXTHCLICK, + HAL_KEY_EVENT_SEVENTHCLICK, + HAL_KEY_EVENT_EIGHTHCLICK, + HAL_KEY_EVENT_NINETHCLICK, + HAL_KEY_EVENT_TENTHCLICK, + HAL_KEY_EVENT_REPEAT, + HAL_KEY_EVENT_GROUPKEY_DOWN, + HAL_KEY_EVENT_GROUPKEY_REPEAT, + HAL_KEY_EVENT_INITDOWN, + HAL_KEY_EVENT_INITUP, + HAL_KEY_EVENT_INITLONGPRESS, + HAL_KEY_EVENT_INITLONGLONGPRESS, + HAL_KEY_EVENT_INITFINISHED, + + HAL_KEY_EVENT_NUM, +}; + +#define KEY_EVENT_SET(a) (1 << HAL_KEY_EVENT_ ## a) +#define KEY_EVENT_SET2(a, b) (KEY_EVENT_SET(a) | KEY_EVENT_SET(b)) +#define KEY_EVENT_SET3(a, b, c) (KEY_EVENT_SET2(a, b) | KEY_EVENT_SET(c)) +#define KEY_EVENT_SET4(a, b, c, d) (KEY_EVENT_SET3(a, b, c) | KEY_EVENT_SET(d)) + +enum HAL_KEY_GPIOKEY_VAL_T { + HAL_KEY_GPIOKEY_VAL_LOW = 0, + HAL_KEY_GPIOKEY_VAL_HIGH, +}; + +struct HAL_KEY_GPIOKEY_CFG_T { + enum HAL_KEY_CODE_T key_code; + struct HAL_IOMUX_PIN_FUNCTION_MAP key_config; + enum HAL_KEY_GPIOKEY_VAL_T key_down; +}; + +int hal_key_open(int checkPwrKey, int (* cb)(uint32_t, uint8_t)); + +enum HAL_KEY_EVENT_T hal_key_read_status(enum HAL_KEY_CODE_T code); + +int hal_key_close(void); + +#ifdef __cplusplus + } +#endif + +#endif//__FMDEC_H__ diff --git a/platform/hal/hal_location.h b/platform/hal/hal_location.h new file mode 100644 index 0000000..8d1cdac --- /dev/null +++ b/platform/hal/hal_location.h @@ -0,0 +1,164 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_LOCATION_H__ +#define __HAL_LOCATION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define HAL_SEC_CONCAT_2(a, b) a.b +#define HAL_SEC_CONCAT_3(a, b, c) a.b.c + +#define HAL_SEC_TO_STR_A(s) #s +#define HAL_SEC_TO_STR(s) HAL_SEC_TO_STR_A(s) + +#define HAL_SEC_NAME_ATTR(s) __attribute__((section(s))) + +#define HAL_SEC_DEF(section, name) HAL_SEC_NAME_ATTR(HAL_SEC_TO_STR(HAL_SEC_CONCAT_2(section, name))) name +#ifdef __COUNTER__ +#define HAL_SEC_LOC(section) HAL_SEC_NAME_ATTR(HAL_SEC_TO_STR(HAL_SEC_CONCAT_3(section, __LINE__, __COUNTER__))) +#else +#define HAL_SEC_LOC(section) HAL_SEC_NAME_ATTR(HAL_SEC_TO_STR(HAL_SEC_CONCAT_2(section, __LINE__))) +#endif + +#if defined(__GNUC__) && !((defined(ROM_BUILD) && !defined(ROM_IN_FLASH)) || defined(PROGRAMMER)) + +#define BOOT_TEXT_SRAM_LOC HAL_SEC_LOC(.boot_text_sram) +#define BOOT_TEXT_SRAM_DEF(n) HAL_SEC_DEF(.boot_text_sram, n) +#define BOOT_TEXT_FLASH_LOC HAL_SEC_LOC(.boot_text_flash) +#define BOOT_TEXT_FLASH_DEF(n) HAL_SEC_DEF(.boot_text_flash, n) +#define BOOT_RODATA_SRAM_LOC HAL_SEC_LOC(.boot_rodata_sram) +#define BOOT_RODATA_SRAM_DEF(n) HAL_SEC_DEF(.boot_rodata_sram, n) +#define BOOT_RODATA_FLASH_LOC HAL_SEC_LOC(.boot_rodata_flash) +#define BOOT_RODATA_FLASH_DEF(n) HAL_SEC_DEF(.boot_rodata_flash, n) +#define BOOT_DATA_LOC HAL_SEC_LOC(.boot_data) +#define BOOT_DATA_DEF(n) HAL_SEC_DEF(.boot_data, n) +#ifdef __ARMCC_VERSION +#define BOOT_BSS_LOC HAL_SEC_LOC(.bss.boot_bss) +#define BOOT_BSS_DEF(n) HAL_SEC_DEF(.bss.boot_bss, n) +#else +#define BOOT_BSS_LOC HAL_SEC_LOC(.boot_bss) +#define BOOT_BSS_DEF(n) HAL_SEC_DEF(.boot_bss, n) +#endif + +#define SRAM_TEXT_LOC HAL_SEC_LOC(.sram_text) +#define SRAM_TEXT_DEF(n) HAL_SEC_DEF(.sram_text, n) +#define SRAM_DATA_LOC HAL_SEC_LOC(.sram_data) +#define SRAM_DATA_DEF(n) HAL_SEC_DEF(.sram_data, n) +#define SRAM_STACK_LOC ALIGNED(8) HAL_SEC_LOC(.sram_data) +#define SRAM_STACK_DEF(n) ALIGNED(8) HAL_SEC_LOC(.sram_data, n) +#ifdef __ARMCC_VERSION +#define SRAM_BSS_LOC HAL_SEC_LOC(.bss.sram_bss) +#define SRAM_BSS_DEF(n) HAL_SEC_DEF(.bss.sram_bss, n) +#else +#define SRAM_BSS_LOC HAL_SEC_LOC(.sram_bss) +#define SRAM_BSS_DEF(n) HAL_SEC_DEF(.sram_bss, n) +#endif + +#define FRAM_TEXT_LOC HAL_SEC_LOC(.fast_text_sram) +#define FRAM_TEXT_DEF(n) HAL_SEC_DEF(.fast_text_sram, n) + +#define CP_TEXT_SRAM_LOC HAL_SEC_LOC(.cp_text_sram) +#define CP_TEXT_SRAM_DEF(n) HAL_SEC_DEF(.cp_text_sram, n) +#define CP_DATA_LOC HAL_SEC_LOC(.cp_data) +#define CP_DATA_DEF(n) HAL_SEC_DEF(.cp_data, n) +#ifdef __ARMCC_VERSION +#define CP_BSS_LOC HAL_SEC_LOC(.bss.cp_bss) +#define CP_BSS_DEF(n) HAL_SEC_DEF(.bss.cp_bss, n) +#else +#define CP_BSS_LOC HAL_SEC_LOC(.cp_bss) +#define CP_BSS_DEF(n) HAL_SEC_DEF(.cp_bss, n) +#endif + +#define FLASH_TEXT_LOC HAL_SEC_LOC(.flash_text) +#define FLASH_TEXT_DEF(n) HAL_SEC_DEF(.flash_text, n) +#define FLASH_RODATA_LOC HAL_SEC_LOC(.flash_rodata) +#define FLASH_RODATA_DEF(n) HAL_SEC_DEF(.flash_rodata, n) + +#define REBOOT_CUSTOM_PARAM_LOC HAL_SEC_LOC(.reboot_custom_param) +#define REBOOT_CUSTOM_PARAM_DEF HAL_SEC_DEF(.reboot_custom_param) + +#else + +#define BOOT_TEXT_SRAM_LOC +#define BOOT_TEXT_SRAM_DEF(n) n +#if defined(__GNUC__) && defined(PROGRAMMER_INFLASH) +#define BOOT_TEXT_FLASH_LOC HAL_SEC_LOC(.boot_text_flash) +#define BOOT_TEXT_FLASH_DEF(n) HAL_SEC_DEF(.boot_text_flash, n) +#else +#define BOOT_TEXT_FLASH_LOC +#define BOOT_TEXT_FLASH_DEF(n) n +#endif +#define BOOT_RODATA_SRAM_LOC +#define BOOT_RODATA_SRAM_DEF(n) n +#define BOOT_RODATA_FLASH_LOC +#define BOOT_RODATA_FLASH_DEF(n) n +#define BOOT_DATA_LOC +#define BOOT_DATA_DEF(n) n +#define BOOT_BSS_LOC +#define BOOT_BSS_DEF(n) n + +#define SRAM_TEXT_LOC +#define SRAM_TEXT_DEF(n) n +#define SRAM_DATA_LOC +#define SRAM_DATA_DEF(n) n +#define SRAM_STACK_LOC +#define SRAM_STACK_DEF(n) n +#define SRAM_BSS_LOC +#define SRAM_BSS_DEF(n) n + +#define FRAM_TEXT_LOC +#define FRAM_TEXT_DEF(n) n + +#define CP_TEXT_SRAM_LOC +#define CP_TEXT_SRAM_DEF(n) n +#define CP_DATA_LOC +#define CP_DATA_DEF(n) n +#define CP_BSS_LOC +#define CP_BSS_DEF(n) n + +#define FLASH_TEXT_LOC +#define FLASH_TEXT_DEF(n) n +#define FLASH_RODATA_LOC +#define FLASH_RODATA_DEF(n) n + +#define REBOOT_CUSTOM_PARAM_LOC +#define REBOOT_CUSTOM_PARAM_DEF(n) n + +#endif // !__GNUC__ || ROM_BUILD || PROGRAMMER + +#if defined(__GNUC__) && defined(__ARM_ARCH_ISA_ARM) +#define SYNC_FLAGS_LOC HAL_SEC_LOC(.sync_flags) +#define SYNC_FLAGS_DEF(n) HAL_SEC_DEF(.sync_flags, n) +#else +#define SYNC_FLAGS_LOC +#define SYNC_FLAGS_DEF(n) n +#endif + +#if defined(__ARM_ARCH_ISA_ARM) +#define PSRAMUHS_TEXT_LOC HAL_SEC_LOC(.psramuhs_text) +#define PSRAMUHS_TEXT_DEF(n) HAL_SEC_DEF(.psramuhs_text, n) +#else +#define PSRAMUHS_TEXT_LOC +#define PSRAMUHS_TEXT_DEF(n) n +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_mcu2cp.c b/platform/hal/hal_mcu2cp.c new file mode 100644 index 0000000..e1ef87f --- /dev/null +++ b/platform/hal/hal_mcu2cp.c @@ -0,0 +1,554 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_HAS_CP + +#include "plat_addr_map.h" +#include "cmsis_nvic.h" +#include "hal_location.h" +#include "hal_mcu2cp.h" +#include "hal_sleep.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include CHIP_SPECIFIC_HDR(reg_cmu) + +#define MAX_SEND_RECORD_COUNT 3 + +#define HAL_SYS_WAKE_LOCK_USER_MCU2CP HAL_SYS_WAKE_LOCK_USER_4 + +#ifdef CP_API +#define API_POSTFIX _cp +#define MCU2CP_TEXT_LOC CP_TEXT_SRAM_LOC +#define MCU2CP_RODATA_LOC CP_DATA_LOC +#define MCU2CP_BSS_LOC CP_BSS_LOC +#define MCU2CP_BSS_DEF CP_BSS_DEF +#else +#define API_POSTFIX _mcu +#define MCU2CP_TEXT_LOC +#define MCU2CP_RODATA_LOC +#define MCU2CP_BSS_LOC +#define MCU2CP_BSS_DEF CP_BSS_DEF +#endif + +#define MCU2CP_API_A(n, p) MCU2CP_TEXT_LOC n ## p +#define MCU2CP_API_B(n, p) MCU2CP_API_A(n, p) +#define MCU2CP_API(n) MCU2CP_API_B(n, API_POSTFIX) + +enum HAL_MCU2CP_IRQ_TYPE_T { + HAL_MCU2CP_IRQ_SEND_IND, + HAL_MCU2CP_IRQ_RECV_DONE, + + HAL_MCU2CP_IRQ_TYPE_QTY +}; + +struct HAL_MCU2CP_MSG_T { + struct HAL_MCU2CP_MSG_T *next; // pointer to next element in the list + enum HAL_MCU2CP_MSG_TYPE_T type; // message type + unsigned int len; // message data length in bytes + const unsigned char *data; // pointer to the message data +}; + +struct HAL_MCU2CP_SEND_RECORD_T { + struct HAL_MCU2CP_MSG_T msg; + bool in_use; +}; + +static const IRQn_Type MCU2CP_RODATA_LOC rx_irq_id[HAL_MCU2CP_ID_QTY] = { + CP2MCU_DATA_IRQn, + CP2MCU_DATA1_IRQn, +}; + +static const IRQn_Type MCU2CP_RODATA_LOC tx_irq_id[HAL_MCU2CP_ID_QTY] = { + MCU2CP_DONE_IRQn, + MCU2CP_DONE1_IRQn, +}; + +static const struct HAL_MCU2CP_MSG_T ** MCU2CP_BSS_LOC recv_msg_list_p; + +static struct HAL_MCU2CP_MSG_T * MCU2CP_BSS_LOC send_msg_list_p[HAL_MCU2CP_ID_QTY]; +static struct HAL_MCU2CP_MSG_T * MCU2CP_BSS_LOC send_pending_list_p[HAL_MCU2CP_ID_QTY]; + +static struct HAL_MCU2CP_MSG_T MCU2CP_BSS_LOC recv_pending_head[HAL_MCU2CP_ID_QTY]; + +static struct HAL_MCU2CP_SEND_RECORD_T MCU2CP_BSS_LOC send_msgs[HAL_MCU2CP_ID_QTY][MAX_SEND_RECORD_COUNT]; + +static HAL_MCU2CP_RX_IRQ_HANDLER MCU2CP_BSS_LOC rx_irq_handler[HAL_MCU2CP_ID_QTY][HAL_MCU2CP_MSG_TYPE_QTY]; +static HAL_MCU2CP_TX_IRQ_HANDLER MCU2CP_BSS_LOC tx_irq_handler[HAL_MCU2CP_ID_QTY][HAL_MCU2CP_MSG_TYPE_QTY]; + +static uint8_t MCU2CP_BSS_LOC chan_opened[HAL_MCU2CP_ID_QTY] = { 0, 0, }; +STATIC_ASSERT(sizeof(chan_opened[0]) * 8 >= HAL_MCU2CP_MSG_TYPE_QTY, "chan_opened size too small"); + +static bool MCU2CP_BSS_LOC need_flow_ctrl[HAL_MCU2CP_ID_QTY] = { false, false, }; + +#ifndef CP_API +static bool MCU2CP_BSS_LOC chan_busy[HAL_MCU2CP_ID_QTY] = { false, false, }; + +static bool MCU2CP_BSS_LOC busy_now = false; +#endif + +static struct CMU_T * const MCU2CP_RODATA_LOC cmu = (struct CMU_T *)CMU_BASE; + +static void MCU2CP_TEXT_LOC hal_mcu2cp_busy(enum HAL_MCU2CP_ID_T id, bool busy) +{ +#ifndef CP_API + int i; + bool new_state; + + if (chan_busy[id] == busy) { + return; + } + + chan_busy[id] = busy; + + if (busy_now == busy) { + return; + } + + if (busy) { + hal_sys_wake_lock(HAL_SYS_WAKE_LOCK_USER_MCU2CP); + busy_now = true; + } else { + new_state = false; + for (i = 0; i < HAL_MCU2CP_ID_QTY; i++) { + if (chan_busy[i]) { + new_state = true; + break; + } + } + if (!new_state) { + hal_sys_wake_unlock(HAL_SYS_WAKE_LOCK_USER_MCU2CP); + busy_now = false; + } + } +#endif +} + +static int MCU2CP_TEXT_LOC hal_mcu2cp_peer_irq_set(enum HAL_MCU2CP_ID_T id, enum HAL_MCU2CP_IRQ_TYPE_T type) +{ + uint32_t value; + +#ifdef CP_API + if (id == HAL_MCU2CP_ID_0) { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_CP2MCU_DATA_IND_SET; + } else { + value = CMU_MCU2CP_DATA_DONE_SET; + } + } else { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_CP2MCU_DATA1_IND_SET; + } else { + value = CMU_MCU2CP_DATA1_DONE_SET; + } + } + + cmu->CP2MCU_IRQ_SET = value; +#else + if (id == HAL_MCU2CP_ID_0) { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_MCU2CP_DATA_IND_SET; + } else { + value = CMU_CP2MCU_DATA_DONE_SET; + } + } else { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_MCU2CP_DATA1_IND_SET; + } else { + value = CMU_CP2MCU_DATA1_DONE_SET; + } + } + + cmu->MCU2CP_IRQ_SET = value; +#endif + + return 0; +} + +static int MCU2CP_TEXT_LOC hal_mcu2cp_local_irq_clear(enum HAL_MCU2CP_ID_T id, enum HAL_MCU2CP_IRQ_TYPE_T type) +{ + uint32_t value; + +#ifdef CP_API + if (id == HAL_MCU2CP_ID_0) { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_MCU2CP_DATA_IND_CLR; + } else { + value = CMU_CP2MCU_DATA_DONE_CLR; + } + } else { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_MCU2CP_DATA1_IND_CLR; + } else { + value = CMU_CP2MCU_DATA1_DONE_CLR; + } + } + + cmu->MCU2CP_IRQ_CLR = value; +#else + if (id == HAL_MCU2CP_ID_0) { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_CP2MCU_DATA_IND_CLR; + } else { + value = CMU_MCU2CP_DATA_DONE_CLR; + } + } else { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_CP2MCU_DATA1_IND_CLR; + } else { + value = CMU_MCU2CP_DATA1_DONE_CLR; + } + } + + cmu->CP2MCU_IRQ_CLR = value; +#endif + + return 0; +} + +static int MCU2CP_TEXT_LOC hal_mcu2cp_local_irq_set(enum HAL_MCU2CP_ID_T id, enum HAL_MCU2CP_IRQ_TYPE_T type) +{ + uint32_t value; + +#ifdef CP_API + if (id == HAL_MCU2CP_ID_0) { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_MCU2CP_DATA_IND_SET; + } else { + value = CMU_CP2MCU_DATA_DONE_SET; + } + } else { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_MCU2CP_DATA1_IND_SET; + } else { + value = CMU_CP2MCU_DATA1_DONE_SET; + } + } + + cmu->MCU2CP_IRQ_SET = value; +#else + if (id == HAL_MCU2CP_ID_0) { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_CP2MCU_DATA_IND_SET; + } else { + value = CMU_MCU2CP_DATA_DONE_SET; + } + } else { + if (type == HAL_MCU2CP_IRQ_SEND_IND) { + value = CMU_CP2MCU_DATA1_IND_SET; + } else { + value = CMU_MCU2CP_DATA1_DONE_SET; + } + } + + cmu->CP2MCU_IRQ_SET = value; +#endif + + return 0; +} + +static void MCU2CP_TEXT_LOC hal_mcu2cp_rx_irq(void) +{ + int id; + const struct HAL_MCU2CP_MSG_T *msg_ptr; + enum HAL_MCU2CP_MSG_TYPE_T type; + unsigned int processed; + + for (id = HAL_MCU2CP_ID_0; id < HAL_MCU2CP_ID_QTY; id++) { + if (NVIC_GetActive(rx_irq_id[id])) { + hal_mcu2cp_local_irq_clear(id, HAL_MCU2CP_IRQ_SEND_IND); + + if (recv_pending_head[id].data) { + // Previous unprocessed message + msg_ptr = &recv_pending_head[id]; + } else { + // New message + msg_ptr = recv_msg_list_p[id]; + } + while (msg_ptr) { + type = msg_ptr->type; + if (type >= HAL_MCU2CP_MSG_TYPE_QTY) { + // Error + ASSERT(false, "MCU2CP-RX: Invalid msg type: %d", type); + break; + } + if (rx_irq_handler[id][type]) { + processed = rx_irq_handler[id][type](msg_ptr->data, msg_ptr->len); + // Check if flow control needed + if (processed < msg_ptr->len) { + recv_pending_head[id].next = msg_ptr->next; + recv_pending_head[id].type = msg_ptr->type; + recv_pending_head[id].len = msg_ptr->len - processed; + recv_pending_head[id].data = msg_ptr->data + processed; + break; + } + } else { + // Error + ASSERT(false, "MCU2CP-RX: Handler missing"); + break; + } + msg_ptr = msg_ptr->next; + } + + if (msg_ptr == NULL) { + if (!need_flow_ctrl[id]){ + hal_mcu2cp_peer_irq_set(id, HAL_MCU2CP_IRQ_RECV_DONE); + } + recv_pending_head[id].data = NULL; + } + } + } +} + +static void MCU2CP_TEXT_LOC hal_mcu2cp_tx_irq(void) +{ + int id; + struct HAL_MCU2CP_MSG_T *msg_ptr; + enum HAL_MCU2CP_MSG_TYPE_T type; + + for (id = HAL_MCU2CP_ID_0; id < HAL_MCU2CP_ID_QTY; id++) { + if (NVIC_GetActive(tx_irq_id[id])) { + hal_mcu2cp_local_irq_clear(id, HAL_MCU2CP_IRQ_RECV_DONE); + + msg_ptr = send_msg_list_p[id]; + while (msg_ptr) { + type = msg_ptr->type; + if (type >= HAL_MCU2CP_MSG_TYPE_QTY) { + // Error + ASSERT(false, "MCU2CP-TX: Invalid msg type: %d", type); + break; + } + if (tx_irq_handler[id][type]) { + tx_irq_handler[id][type](msg_ptr->data, msg_ptr->len); + }; + CONTAINER_OF(msg_ptr, struct HAL_MCU2CP_SEND_RECORD_T, msg)->in_use = false; + msg_ptr = msg_ptr->next; + } + + if (send_pending_list_p[id]) { + send_msg_list_p[id] = send_pending_list_p[id]; + send_pending_list_p[id] = NULL; + hal_mcu2cp_peer_irq_set(id, HAL_MCU2CP_IRQ_SEND_IND); + } else { + send_msg_list_p[id] = NULL; + // Allow sleep + hal_mcu2cp_busy(id, false); + } + } + } +} + +const struct HAL_MCU2CP_MSG_T ** hal_mcu2cp_get_send_msg_list_mcu(void); +const struct HAL_MCU2CP_MSG_T ** hal_mcu2cp_get_send_msg_list_cp (void); + +#ifdef CP_API +// This is initialization code and should NOT be in CP text location +const struct HAL_MCU2CP_MSG_T ** hal_mcu2cp_get_send_msg_list_cp(void) +#else +const struct HAL_MCU2CP_MSG_T ** hal_mcu2cp_get_send_msg_list_mcu(void) +#endif +{ + return (const struct HAL_MCU2CP_MSG_T **)&send_msg_list_p[0]; +} + +int MCU2CP_API(hal_mcu2cp_open)(enum HAL_MCU2CP_ID_T id, enum HAL_MCU2CP_MSG_TYPE_T type, + HAL_MCU2CP_RX_IRQ_HANDLER rxhandler, HAL_MCU2CP_TX_IRQ_HANDLER txhandler, bool rx_flowctrl) +{ + int i; + + if (id >= HAL_MCU2CP_ID_QTY) { + return 1; + } + if (type >= HAL_MCU2CP_MSG_TYPE_QTY) { + return 2; + } + + if (chan_opened[id] == 0) { + hal_mcu2cp_local_irq_clear(id, HAL_MCU2CP_IRQ_SEND_IND); + hal_mcu2cp_local_irq_clear(id, HAL_MCU2CP_IRQ_RECV_DONE); +#ifdef CP_API + recv_msg_list_p = hal_mcu2cp_get_send_msg_list_mcu(); +#else + recv_msg_list_p = hal_mcu2cp_get_send_msg_list_cp(); +#endif + + NVIC_SetVector(rx_irq_id[id], (uint32_t)hal_mcu2cp_rx_irq); + NVIC_SetPriority(rx_irq_id[id], IRQ_PRIORITY_NORMAL); + + NVIC_SetVector(tx_irq_id[id], (uint32_t)hal_mcu2cp_tx_irq); + NVIC_SetPriority(tx_irq_id[id], IRQ_PRIORITY_NORMAL); + + // Stop IRQs by default + NVIC_DisableIRQ(rx_irq_id[id]); + NVIC_DisableIRQ(tx_irq_id[id]); + + send_msg_list_p[id] = NULL; + send_pending_list_p[id] = NULL; + recv_pending_head[id].data = NULL; + for (i = 0; i < MAX_SEND_RECORD_COUNT; i++) { + send_msgs[id][i].in_use = false; + } + need_flow_ctrl[id] = rx_flowctrl; + } else { + ASSERT(need_flow_ctrl[id] == rx_flowctrl, "MCU2CP-OPEN: rx_flowctrl=%d (should be %d)", rx_flowctrl, need_flow_ctrl[id]); + return 3; + } + chan_opened[id] |= (1 << type); + + rx_irq_handler[id][type] = rxhandler; + tx_irq_handler[id][type] = txhandler; + + return 0; +} + +int MCU2CP_API(hal_mcu2cp_close)(enum HAL_MCU2CP_ID_T id,enum HAL_MCU2CP_MSG_TYPE_T type) +{ + if (id >= HAL_MCU2CP_ID_QTY) { + return 1; + } + + chan_opened[id] &= ~(1 << type); + rx_irq_handler[id][type] = NULL; + tx_irq_handler[id][type] = NULL; + + if (chan_opened[id] == 0) { + // Stop IRQs by default + NVIC_DisableIRQ(rx_irq_id[id]); + NVIC_DisableIRQ(tx_irq_id[id]); + + send_msg_list_p[id] = NULL; + send_pending_list_p[id] = NULL; + recv_pending_head[id].data = NULL; + need_flow_ctrl[id] = false; + } + + return 0; +} + +int MCU2CP_API(hal_mcu2cp_start_recv)(enum HAL_MCU2CP_ID_T id) +{ + if (id >= HAL_MCU2CP_ID_QTY) { + return 1; + } + + NVIC_EnableIRQ(rx_irq_id[id]); + // Check if there is any previous unprocessed message + if (recv_pending_head[id].data) { + hal_mcu2cp_local_irq_set(id, HAL_MCU2CP_IRQ_SEND_IND); + } + return 0; +} + +int MCU2CP_API(hal_mcu2cp_stop_recv)(enum HAL_MCU2CP_ID_T id) +{ + if (id >= HAL_MCU2CP_ID_QTY) { + return 1; + } + + NVIC_DisableIRQ(rx_irq_id[id]); + return 0; +} + +int MCU2CP_API(hal_mcu2cp_send)(enum HAL_MCU2CP_ID_T id, enum HAL_MCU2CP_MSG_TYPE_T type, + const unsigned char *data, unsigned int len) +{ + uint32_t lock; + int ret; + struct HAL_MCU2CP_SEND_RECORD_T *record; + struct HAL_MCU2CP_MSG_T *next; + int i; + + if (id >= HAL_MCU2CP_ID_QTY) { + return 1; + } + if (type >= HAL_MCU2CP_MSG_TYPE_QTY) { + return 2; + } + if ((chan_opened[id] & (1 << type)) == 0) { + return 3; + } + + NVIC_EnableIRQ(tx_irq_id[id]); + + ret = -1; + record = &send_msgs[id][0]; + + lock = int_lock(); + for (i = 0; i < MAX_SEND_RECORD_COUNT; i++) { + if (record->in_use) { + record++; + continue; + } + record->in_use = true; + record->msg.next = NULL; + record->msg.type = type; + record->msg.len = len; + record->msg.data = data; + if (send_msg_list_p[id] == NULL) { + send_msg_list_p[id] = &record->msg; + hal_mcu2cp_peer_irq_set(id, HAL_MCU2CP_IRQ_SEND_IND); + } else if (send_pending_list_p[id] == NULL) { + send_pending_list_p[id] = &record->msg; + } else { + next = send_pending_list_p[id]; + while (next->next) { + next = next->next; + } + next->next = &record->msg; + } + ret = 0; + // Prohibit sleep here + hal_mcu2cp_busy(id, true); + break; + } + int_unlock(lock); + + return ret; +} + +void MCU2CP_API(hal_mcu2cp_rx_done)(enum HAL_MCU2CP_ID_T id) +{ + hal_mcu2cp_peer_irq_set(id, HAL_MCU2CP_IRQ_RECV_DONE); +} + +int MCU2CP_API(hal_mcu2cp_opened)(enum HAL_MCU2CP_ID_T id) +{ + return !!chan_opened[id]; +} + +int MCU2CP_API(hal_mcu2cp_local_irq_pending)(enum HAL_MCU2CP_ID_T id) +{ + uint32_t value; + +#ifdef CP_API + if (id == HAL_MCU2CP_ID_0) { + value = CMU_MCU2CP_DATA_IND_SET | CMU_CP2MCU_DATA_DONE_SET; + } else { + value = CMU_MCU2CP_DATA1_IND_SET | CMU_CP2MCU_DATA1_DONE_SET; + } + + return !!(cmu->MCU2CP_IRQ_SET & value); +#else + if (id == HAL_MCU2CP_ID_0) { + value = CMU_CP2MCU_DATA_IND_SET | CMU_MCU2CP_DATA_DONE_SET; + } else { + value = CMU_CP2MCU_DATA1_IND_SET | CMU_MCU2CP_DATA1_DONE_SET; + } + + return !!(cmu->CP2MCU_IRQ_SET & value); +#endif +} + +#endif + diff --git a/platform/hal/hal_mcu2cp.h b/platform/hal/hal_mcu2cp.h new file mode 100644 index 0000000..123794a --- /dev/null +++ b/platform/hal/hal_mcu2cp.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_MCU2CP_H__ +#define __HAL_MCU2CP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdbool.h" + +enum HAL_MCU2CP_ID_T { + HAL_MCU2CP_ID_0, + HAL_MCU2CP_ID_1, + + HAL_MCU2CP_ID_QTY +}; + +enum HAL_MCU2CP_MSG_TYPE_T { + HAL_MCU2CP_MSG_TYPE_0, + HAL_MCU2CP_MSG_TYPE_1, + + HAL_MCU2CP_MSG_TYPE_QTY +}; + +typedef unsigned int (*HAL_MCU2CP_RX_IRQ_HANDLER)(const unsigned char *data, unsigned int len); +typedef void (*HAL_MCU2CP_TX_IRQ_HANDLER)(const unsigned char *data, unsigned int len); + +int hal_mcu2cp_open_mcu(enum HAL_MCU2CP_ID_T id, enum HAL_MCU2CP_MSG_TYPE_T type, + HAL_MCU2CP_RX_IRQ_HANDLER rxhandler, HAL_MCU2CP_TX_IRQ_HANDLER txhandler, bool rx_flowctrl); +int hal_mcu2cp_open_cp (enum HAL_MCU2CP_ID_T id, enum HAL_MCU2CP_MSG_TYPE_T type, + HAL_MCU2CP_RX_IRQ_HANDLER rxhandler, HAL_MCU2CP_TX_IRQ_HANDLER txhandler, bool rx_flowctrl); + +int hal_mcu2cp_close_mcu(enum HAL_MCU2CP_ID_T id,enum HAL_MCU2CP_MSG_TYPE_T type); +int hal_mcu2cp_close_cp (enum HAL_MCU2CP_ID_T id,enum HAL_MCU2CP_MSG_TYPE_T type); + +int hal_mcu2cp_start_recv_mcu(enum HAL_MCU2CP_ID_T id); +int hal_mcu2cp_start_recv_cp (enum HAL_MCU2CP_ID_T id); + +int hal_mcu2cp_stop_recv_mcu(enum HAL_MCU2CP_ID_T id); +int hal_mcu2cp_stop_recv_cp (enum HAL_MCU2CP_ID_T id); + +int hal_mcu2cp_send_mcu(enum HAL_MCU2CP_ID_T id, enum HAL_MCU2CP_MSG_TYPE_T type, + const unsigned char *data, unsigned int len); +int hal_mcu2cp_send_cp (enum HAL_MCU2CP_ID_T id, enum HAL_MCU2CP_MSG_TYPE_T type, + const unsigned char *data, unsigned int len); + +void hal_mcu2cp_rx_done_mcu(enum HAL_MCU2CP_ID_T id); +void hal_mcu2cp_rx_done_cp (enum HAL_MCU2CP_ID_T id); + +int hal_mcu2cp_opened_mcu(enum HAL_MCU2CP_ID_T id); +int hal_mcu2cp_opened_cp(enum HAL_MCU2CP_ID_T id); + +int hal_mcu2cp_local_irq_pending_mcu(enum HAL_MCU2CP_ID_T id); +int hal_mcu2cp_local_irq_pending_cp(enum HAL_MCU2CP_ID_T id); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_memsc.c b/platform/hal/hal_memsc.c new file mode 100644 index 0000000..5a7d6dc --- /dev/null +++ b/platform/hal/hal_memsc.c @@ -0,0 +1,46 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include "hal_memsc.h" +#include "hal_cmu.h" + +int hal_memsc_lock(enum HAL_MEMSC_ID_T id) +{ + if (id >= HAL_MEMSC_ID_QTY) { + return 0; + } + + return (hal_cmu_get_memsc_addr())[id]; +} + +void hal_memsc_unlock(enum HAL_MEMSC_ID_T id) +{ + if (id >= HAL_MEMSC_ID_QTY) { + return; + } + + (hal_cmu_get_memsc_addr())[id] = 1; +} + +bool hal_memsc_avail(enum HAL_MEMSC_ID_T id) +{ + if (id >= HAL_MEMSC_ID_QTY) { + return false; + } + + return !!((hal_cmu_get_memsc_addr())[4] & (1 << id)); +} + diff --git a/platform/hal/hal_memsc.h b/platform/hal/hal_memsc.h new file mode 100644 index 0000000..bf4c66a --- /dev/null +++ b/platform/hal/hal_memsc.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_MEMSC_H__ +#define __HAL_MEMSC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "stdbool.h" + +enum HAL_MEMSC_ID_T { + HAL_MEMSC_ID_0, + HAL_MEMSC_ID_1, + HAL_MEMSC_ID_2, + HAL_MEMSC_ID_3, + + HAL_MEMSC_ID_QTY +}; + +int hal_memsc_lock(enum HAL_MEMSC_ID_T id); + +void hal_memsc_unlock(enum HAL_MEMSC_ID_T id); + +bool hal_memsc_avail(enum HAL_MEMSC_ID_T id); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_norflash.c b/platform/hal/hal_norflash.c new file mode 100644 index 0000000..ddfa14d --- /dev/null +++ b/platform/hal/hal_norflash.c @@ -0,0 +1,1609 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "plat_addr_map.h" +#include "cmsis.h" +#include "hal_norflaship.h" +#include "hal_norflash.h" +#include "hal_bootmode.h" +#include "hal_cmu.h" +#include "hal_sysfreq.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "norflash_cfg.h" +#include "norflash_drv.h" +#include "pmu.h" +#include "string.h" + +/* Demo: + * + * uint8_t data[1024]; + * hal_norflash_open(HAL_NORFLASH_ID_0, HAL_NORFLASH_SPEED_26M, 0); + * \/\/ hal_norflash_open(HAL_NORFLASH_ID_0, HAL_NORFLASH_SPEED_13M, HAL_NORFLASH_OP_MODE_QUAD); + * \/\/ hal_norflash_open(HAL_NORFLASH_ID_0, HAL_NORFLASH_SPEED_13M, HAL_NORFLASH_OP_MODE_QUAD|HAL_NORFLASH_OP_MODE_CONTINUOUS_READ); + * hal_norflash_erase(HAL_I2C_ID_0, 0, 4096); + * memset(data, 0xcc, 1024); + * hal_norflash_write(HAL_I2C_ID_0, 0, data, 1024); + * for (i = 0; i < 10; ++i) { + * TRACE(2,"[0x%x] - 0x%x\n", 0x08000000 + i, *((volatile uint8_t *)(0x08000000 + i))); + * } +*/ + +#define HAL_NORFLASH_CP_ID_LEN 2 + +#define HAL_NORFLASH_YES 1 +#define HAL_NORFLASH_NO 0 + +// 64M Bytes +#define HAL_NORFLASH_ADDR_MASK 0x03FFFFFF + +// Protect lower 1/2 by default +#ifndef FLASH_BLOCK_PROTECTION_64M_BIT +#define FLASH_BLOCK_PROTECTION_64M_BIT 0x0034 +#endif +#ifndef FLASH_BLOCK_PROTECTION_32M_BIT +#define FLASH_BLOCK_PROTECTION_32M_BIT 0x0038 +#endif +#ifndef FLASH_BLOCK_PROTECTION_16M_BIT +#define FLASH_BLOCK_PROTECTION_16M_BIT 0x0034 +#endif +#ifndef FLASH_BLOCK_PROTECTION_8M_BIT +#define FLASH_BLOCK_PROTECTION_8M_BIT 0x0030 +#endif + +struct HAL_Norflash_Context { + bool opened; + uint8_t device_id[HAL_NORFLASH_DEVICE_ID_LEN]; +#ifdef FLASH_UNIQUE_ID + uint8_t unique_id[HAL_NORFLASH_UNIQUE_ID_LEN + HAL_NORFLASH_CP_ID_LEN]; +#endif + uint32_t total_size; + uint32_t block_size; + uint32_t sector_size; + uint32_t page_size; + enum HAL_NORFLASH_RET_T open_state; +}; + +static struct HAL_Norflash_Context norflash_ctx[HAL_NORFLASH_ID_NUM]; + +static const char * const err_not_opened = "norflash not opened"; + +static const struct HAL_NORFLASH_CONFIG_T norflash_cfg = { +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) + .source_clk = HAL_NORFLASH_SPEED_52M, + .speed = HAL_NORFLASH_SPEED_52M, +#else +#ifdef FPGA + .source_clk = HAL_NORFLASH_SPEED_13M * 2, + .speed = HAL_NORFLASH_SPEED_13M, +#elif defined(FLASH_LOW_SPEED) + .source_clk = HAL_NORFLASH_SPEED_26M * 2, + .speed = HAL_NORFLASH_SPEED_26M, +#elif defined(OSC_26M_X4_AUD2BB) + .source_clk = HAL_NORFLASH_SPEED_52M * 2, + .speed = HAL_NORFLASH_SPEED_52M, +#else + .source_clk = HAL_NORFLASH_SPEED_104M * 2, + .speed = HAL_NORFLASH_SPEED_104M, +#endif +#endif + .mode = HAL_NORFLASH_OP_MODE_STAND_SPI | + HAL_NORFLASH_OP_MODE_FAST_SPI | + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT | + HAL_NORFLASH_OP_MODE_DUAL_IO | + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT | + HAL_NORFLASH_OP_MODE_QUAD_IO | + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ | + HAL_NORFLASH_OP_MODE_READ_WRAP | + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM | + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM, + .override_config = 0, +}; + +#ifdef FLASH_FREQ_DYNAMIC_ADJUST +struct HAL_NORFLASH_FREQ_DYNAMIC_ADJUST_CONFIG_T{ + uint32_t source_clk; + uint8_t timing_index; +}; +static struct HAL_NORFLASH_FREQ_DYNAMIC_ADJUST_CONFIG_T norflash_freq_dynamic_adjust_cfg[2]; +#endif + +#ifdef FLASH_SUSPEND +enum SUSPEND_STATE_T { + SUSPEND_STATE_NONE, + SUSPEND_STATE_ERASE, + SUSPEND_STATE_PROGRAM, +}; + +static enum SUSPEND_STATE_T suspend_state; +static uint32_t op_next_addr; +static const uint8_t *op_next_buf; +static uint32_t op_remain_len; +#endif + +#ifdef FLASH_SECURITY_REGISTER +static uint32_t sec_reg_base; +static uint16_t sec_reg_size; +static uint16_t sec_reg_offset; +static uint16_t sec_reg_total_size; +static uint16_t sec_reg_pp_size; +static bool sec_reg_enabled; +#endif + +enum HAL_CMU_FREQ_T hal_norflash_clk_to_cmu_freq(uint32_t clk) +{ + enum HAL_CMU_FREQ_T freq; + + if (clk >= HAL_NORFLASH_SPEED_208M) { + freq = HAL_CMU_FREQ_208M; + } else if (clk >= HAL_NORFLASH_SPEED_104M) { + freq = HAL_CMU_FREQ_104M; + } else if (clk >= HAL_NORFLASH_SPEED_78M) { + freq = HAL_CMU_FREQ_78M; + } else if (clk >= HAL_NORFLASH_SPEED_52M) { + freq = HAL_CMU_FREQ_52M; + } else { + freq = HAL_CMU_FREQ_26M; + } + +#if defined(CHIP_BEST1000) && defined(AUD_PLL_DOUBLE) + if (freq == HAL_CMU_FREQ_208M) { + freq = HAL_CMU_FREQ_104M; + } +#endif +#ifdef SIMU +#ifdef SIMU_FAST_FLASH +#define MAX_SIMU_FLASH_FREQ HAL_CMU_FREQ_104M +#else +#define MAX_SIMU_FLASH_FREQ HAL_CMU_FREQ_52M +#endif + if (freq > MAX_SIMU_FLASH_FREQ) { + freq = MAX_SIMU_FLASH_FREQ; + } +#endif + + return freq; +} + +enum HAL_NORFLASH_RET_T hal_norflash_get_size(enum HAL_NORFLASH_ID_T id, uint32_t *total_size, + uint32_t *block_size, uint32_t *sector_size, + uint32_t *page_size) +{ + ASSERT(norflash_ctx[id].opened, err_not_opened); + + if (total_size) { + *total_size = norflash_ctx[id].total_size; + } + if (block_size) { + *block_size = norflash_ctx[id].block_size; + } + if (sector_size) { + *sector_size = norflash_ctx[id].sector_size; + } + if (page_size) { + *page_size = norflash_ctx[id].page_size; + } + return HAL_NORFLASH_OK; +} + +enum HAL_NORFLASH_RET_T hal_norflash_get_boundary(enum HAL_NORFLASH_ID_T id, uint32_t address, + uint32_t *block_boundary, uint32_t *sector_boundary) +{ + ASSERT(norflash_ctx[id].opened, err_not_opened); + + static const uint32_t flash_base[] = { FLASH_BASE, FLASHX_BASE, FLASH_NC_BASE, FLASHX_NC_BASE, }; + int i; + + for (i = 0; i < ARRAY_SIZE(flash_base); i++) { + if (flash_base[i] <= address && address < flash_base[i] + norflash_ctx[id].total_size) { + address -= flash_base[i]; + if (block_boundary) + *block_boundary = flash_base[i] + (address/norflash_ctx[id].block_size)*norflash_ctx[id].block_size; + if (sector_boundary) + *sector_boundary = flash_base[i] + (address/norflash_ctx[id].sector_size)*norflash_ctx[id].sector_size; + break; + } + } + + if (i == ARRAY_SIZE(flash_base)) { + return HAL_NORFLASH_BAD_ADDR; + } + + return HAL_NORFLASH_OK; +} + +enum HAL_NORFLASH_RET_T hal_norflash_get_id(enum HAL_NORFLASH_ID_T id, uint8_t *value, uint32_t len) +{ + len = MIN(len, sizeof(norflash_ctx[id].device_id)); + + memcpy(value, norflash_ctx[id].device_id, len); + + return HAL_NORFLASH_OK; +} + +#ifdef FLASH_UNIQUE_ID +enum HAL_NORFLASH_RET_T hal_norflash_get_unique_id(enum HAL_NORFLASH_ID_T id, uint8_t *value, uint32_t len) +{ + ASSERT(norflash_ctx[id].opened, err_not_opened); + + len = MIN(len, sizeof(norflash_ctx[id].unique_id)); + + memcpy(value, norflash_ctx[id].unique_id, len); + + return HAL_NORFLASH_OK; +} +#endif + +#ifdef FLASH_PROTECTION +static uint32_t hal_norflash_get_bp_cfg(enum HAL_NORFLASH_ID_T id) +{ + uint32_t val = 0; + + // Set BP and CMP bits + // E.g., for 32M bit flash, BP=0b00010 CMP=1 can protect 0x000000 - 0x3DFFFF + + if (FLASH_SIZE != hal_norflash_get_flash_total_size(id)) { + return val; + } + + if (norflash_ctx[id].device_id[0] != 0xC8 && // GigaDevice + norflash_ctx[id].device_id[0] != 0x85 && // Puya + norflash_ctx[id].device_id[0] != 0x20 // Xinxin + ) { + return val; + } + + if (FLASH_SIZE == 0x800000) { + val = FLASH_BLOCK_PROTECTION_64M_BIT; + } else if (FLASH_SIZE == 0x400000) { + val = FLASH_BLOCK_PROTECTION_32M_BIT; + } else if (FLASH_SIZE == 0x200000) { + val = FLASH_BLOCK_PROTECTION_16M_BIT; + } else if (FLASH_SIZE == 0x100000) { + val = FLASH_BLOCK_PROTECTION_8M_BIT; + } else { + // CAUTION: + // Different configuration for GD and Puya + } + + return val; +} +#endif + +enum HAL_NORFLASH_RET_T hal_norflash_enable_protection(enum HAL_NORFLASH_ID_T id) +{ + int ret = 0; + +#ifdef FLASH_PROTECTION + uint32_t lock; + + if (!norflash_ctx[id].opened) { + return HAL_NORFLASH_NOT_OPENED; + } + + lock = int_lock_global(); + + norflash_pre_operation(); + + ret = norflash_set_block_protection(hal_norflash_get_bp_cfg(id)); + + norflash_post_operation(); + + int_unlock_global(lock); +#endif + + return ret ? HAL_NORFLASH_BAD_OP : HAL_NORFLASH_OK; +} + +enum HAL_NORFLASH_RET_T hal_norflash_disable_protection(enum HAL_NORFLASH_ID_T id) +{ + int ret = 0; + +#ifdef FLASH_PROTECTION + uint32_t lock; + + if (!norflash_ctx[id].opened) { + return HAL_NORFLASH_NOT_OPENED; + } + + lock = int_lock_global(); + + norflash_pre_operation(); + + ret = norflash_set_block_protection(0); + + norflash_post_operation(); + + int_unlock_global(lock); +#endif + + return ret ? HAL_NORFLASH_BAD_OP : HAL_NORFLASH_OK; +} + +#ifdef FLASH_SECURITY_REGISTER +enum HAL_NORFLASH_RET_T hal_norflash_security_register_lock(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint32_t len) +{ + uint32_t remain_len; + int ret = 0; + uint32_t reg_base; + uint32_t reg_pos; + uint32_t pos; + uint32_t lock_size; + uint32_t reg_id; + + ASSERT(norflash_ctx[id].opened, err_not_opened); + + if (!sec_reg_enabled) { + return HAL_NORFLASH_BAD_OP; + } + // Check address and length + if (sec_reg_total_size <= start_address) { + return HAL_NORFLASH_BAD_ADDR; + } + remain_len = sec_reg_total_size - start_address; + if (len > remain_len) { + return HAL_NORFLASH_BAD_LEN; + } + // Align to register boundary + remain_len = start_address & (sec_reg_size - 1); + if (remain_len) { + start_address -= remain_len; + len += remain_len; + } + remain_len = len & (sec_reg_size - 1); + if (remain_len) { + len += sec_reg_size - remain_len; + } + + pos = start_address; + remain_len = len; + + reg_base = sec_reg_base; + reg_pos = 0; + reg_id = 0; + + norflash_pre_operation(); + + while (remain_len > 0 && ret == 0) { + if (reg_pos <= pos && pos < reg_pos + sec_reg_size) { + // lock a register + lock_size = sec_reg_size - (pos - reg_pos); + ret = norflash_security_register_lock(reg_id); + if (remain_len > lock_size) { + remain_len -= lock_size; + } else { + remain_len = 0; + } + pos += lock_size; + } + reg_pos += sec_reg_size; + reg_base += sec_reg_offset; + reg_id++; + } + + norflash_post_operation(); + + return ret; +} + +enum HAL_NORFLASH_RET_T hal_norflash_security_register_erase(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint32_t len) +{ + uint32_t remain_len; + enum HAL_NORFLASH_RET_T ret = HAL_NORFLASH_OK; + uint32_t reg_base; + uint32_t reg_pos; + uint32_t pos; + uint32_t erase_size; + + ASSERT(norflash_ctx[id].opened, err_not_opened); + + if (!sec_reg_enabled) { + return HAL_NORFLASH_BAD_OP; + } + // Check address and length + if (sec_reg_total_size <= start_address) { + return HAL_NORFLASH_BAD_ADDR; + } + remain_len = sec_reg_total_size - start_address; + if (len > remain_len) { + return HAL_NORFLASH_BAD_LEN; + } + // Align to register boundary + remain_len = start_address & (sec_reg_size - 1); + if (remain_len) { + start_address -= remain_len; + len += remain_len; + } + remain_len = len & (sec_reg_size - 1); + if (remain_len) { + len += sec_reg_size - remain_len; + } + + pos = start_address; + remain_len = len; + + reg_base = sec_reg_base; + reg_pos = 0; + + norflash_pre_operation(); + + while (remain_len > 0 && ret == HAL_NORFLASH_OK) { + if (reg_pos <= pos && pos < reg_pos + sec_reg_size) { + // erase a register + erase_size = sec_reg_size - (pos - reg_pos); + ret = norflash_security_register_erase(reg_base + (pos - reg_pos)); + if (remain_len > erase_size) { + remain_len -= erase_size; + } else { + remain_len = 0; + } + pos += erase_size; + } + reg_pos += sec_reg_size; + reg_base += sec_reg_offset; + } + + norflash_post_operation(); + + return ret; +} + +enum HAL_NORFLASH_RET_T hal_norflash_security_register_write(enum HAL_NORFLASH_ID_T id, uint32_t start_address, const uint8_t *buffer, uint32_t len) +{ + const uint8_t *current_buffer; + uint32_t remain_len; + enum HAL_NORFLASH_RET_T ret = HAL_NORFLASH_OK; + uint32_t reg_base; + uint32_t reg_pos; + uint32_t pos; + uint32_t write_size; + uint32_t each_write; + uint32_t pp_remain; + + ASSERT(norflash_ctx[id].opened, err_not_opened); + + if (!sec_reg_enabled) { + return HAL_NORFLASH_BAD_OP; + } + // Check address and length + if (sec_reg_total_size <= start_address) { + return HAL_NORFLASH_BAD_ADDR; + } + remain_len = sec_reg_total_size - start_address; + if (len > remain_len) { + return HAL_NORFLASH_BAD_LEN; + } + + pos = start_address; + current_buffer = buffer; + remain_len = len; + + reg_base = sec_reg_base; + reg_pos = 0; + + norflash_pre_operation(); + + while (remain_len > 0 && ret == HAL_NORFLASH_OK) { + if (reg_pos <= pos && pos < reg_pos + sec_reg_size) { + // write a register + if (pos + remain_len <= reg_pos + sec_reg_size) { + write_size = remain_len; + } else { + write_size = sec_reg_size - (pos - reg_pos); + } + remain_len -= write_size; + while (write_size > 0 && ret == HAL_NORFLASH_OK) { + if (write_size > sec_reg_pp_size) { + each_write = sec_reg_pp_size; + } else { + each_write = write_size; + } + // Align to security register program page size + pp_remain = sec_reg_pp_size - ((pos - reg_pos) & (sec_reg_pp_size - 1)); + if (each_write > pp_remain) { + each_write = pp_remain; + } + ret = norflash_security_register_write(reg_base + (pos - reg_pos), current_buffer, each_write); + write_size -= each_write; + pos += each_write; + current_buffer += each_write; + } + } + reg_pos += sec_reg_size; + reg_base += sec_reg_offset; + } + + norflash_post_operation(); + + return ret; +} + +enum HAL_NORFLASH_RET_T hal_norflash_security_register_read(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint8_t *buffer, uint32_t len) +{ + uint8_t *current_buffer; + uint32_t remain_len, read_size; + int ret = 0; + uint32_t reg_base; + uint32_t reg_pos; + uint32_t pos; +#ifdef FLASH_SEC_REG_FIFO_READ + uint32_t each_read; +#endif + + ASSERT(norflash_ctx[id].opened, err_not_opened); + + if (!sec_reg_enabled) { + return HAL_NORFLASH_BAD_OP; + } + // Check address and length + if (sec_reg_total_size <= start_address) { + return HAL_NORFLASH_BAD_ADDR; + } + remain_len = sec_reg_total_size - start_address; + if (len > remain_len) { + return HAL_NORFLASH_BAD_LEN; + } + + pos = start_address; + current_buffer = buffer; + remain_len = len; + + reg_base = sec_reg_base; + reg_pos = 0; + + norflash_pre_operation(); + +#ifndef FLASH_SEC_REG_FIFO_READ + uint32_t mode = norflash_security_register_enable_read(); +#endif + + while (remain_len > 0 && ret == 0) { + if (reg_pos <= pos && pos < reg_pos + sec_reg_size) { + // read a register + if (pos + remain_len <= reg_pos + sec_reg_size) { + read_size = remain_len; + } else { + read_size = sec_reg_size - (pos - reg_pos); + } + remain_len -= read_size; +#ifdef FLASH_SEC_REG_FIFO_READ + while (read_size > 0 && ret == 0) { + if (read_size > NORFLASHIP_RXFIFO_SIZE) { + each_read = NORFLASHIP_RXFIFO_SIZE; + } else { + each_read = read_size; + } + ret = norflash_security_register_read(reg_base + (pos - reg_pos), current_buffer, each_read); + read_size -= each_read; + pos += each_read; + current_buffer += each_read; + } +#else + memcpy(current_buffer, (void *)(reg_base + (pos - reg_pos)), read_size); + pos += read_size; + current_buffer += read_size; +#endif + } + reg_pos += sec_reg_size; + reg_base += sec_reg_offset; + } + +#ifndef FLASH_SEC_REG_FIFO_READ + norflash_security_register_disable_read(mode); +#endif + + norflash_post_operation(); + + return (ret ? HAL_NORFLASH_ERR : HAL_NORFLASH_OK); +} + +static enum HAL_NORFLASH_RET_T hal_norflash_parse_security_register_config(void) +{ + union DRV_NORFLASH_SEC_REG_CFG_T cfg; + uint32_t reg_cnt; + + cfg = norflash_get_security_register_config(); + + if (!cfg.s.enabled) { + return HAL_NORFLASH_BAD_OP; + } + + if (cfg.s.base == SEC_REG_BASE_0X1000) { + sec_reg_base = 0x1000; + } else if (cfg.s.base == SEC_REG_BASE_0X0000) { + sec_reg_base = 0; + } else { + return HAL_NORFLASH_BAD_CFG; + } + sec_reg_base += FLASH_NC_BASE; + + if (cfg.s.size == SEC_REG_SIZE_1024) { + sec_reg_size = 1024; + } else if (cfg.s.size == SEC_REG_SIZE_512) { + sec_reg_size = 512; + } else if (cfg.s.size == SEC_REG_SIZE_256) { + sec_reg_size = 256; + } else { + return HAL_NORFLASH_BAD_CFG; + } + + if (cfg.s.offset == SEC_REG_OFFSET_0X1000) { + sec_reg_offset = 0x1000; + } else if (cfg.s.offset == SEC_REG_OFFSET_0X0100) { + sec_reg_offset = 0x0100; + } else { + return HAL_NORFLASH_BAD_CFG; + } + + if (sec_reg_size > sec_reg_offset) { + return HAL_NORFLASH_BAD_CFG; + } + + if (cfg.s.cnt == SEC_REG_CNT_3) { + reg_cnt = 3; + } else if (cfg.s.cnt == SEC_REG_CNT_4) { + reg_cnt = 4; + } else { + return HAL_NORFLASH_BAD_CFG; + } + + if (cfg.s.pp == SEC_REG_PP_256) { + sec_reg_pp_size = 256; + } else if (cfg.s.pp == SEC_REG_PP_1024) { + sec_reg_pp_size = 1024; + } else { + return HAL_NORFLASH_BAD_CFG; + } +#if (CHIP_FLASH_CTRL_VER <= 1) +#ifdef FLASH_SEC_REG_PP_1024 + // To write more than 256 bytes on flash controller V1, SPI rate must be lowered to avoid tx FIFO underflow. + // Otherwise, the data must be split into pieces with size no more than 256 bytes. +#else + sec_reg_pp_size = 256; +#endif +#endif + + sec_reg_total_size = sec_reg_size * reg_cnt; + + return HAL_NORFLASH_OK; +} +#endif + +static void hal_norflash_reset_timing(void) +{ + const uint32_t default_div = 8; + + // Restore default divider + norflaship_div(default_div); + norflash_init_sample_delay_by_div(default_div); +} + +static enum HAL_NORFLASH_RET_T _norflash_open(enum HAL_NORFLASH_ID_T id, const struct HAL_NORFLASH_CONFIG_T *cfg, + bool reopen, bool calib, uint32_t timing_idx) +{ + struct HAL_NORFLASH_CONFIG_T norcfg; + enum HAL_CMU_FREQ_T source_freq; + int result; + uint32_t op; + int found; + + if (reopen) { + ASSERT(norflash_ctx[id].opened, err_not_opened); + } + + // Place the config into ram + if (cfg == NULL) { + return HAL_NORFLASH_CFG_NULL; + } + memcpy(&norcfg, cfg, sizeof(norcfg)); + + norflaship_busy_wait(); + + // Reset states + norflash_ctx[id].opened = false; + norflash_ctx[id].open_state = HAL_NORFLASH_NOT_OPENED; +#ifdef FLASH_SUSPEND + suspend_state = SUSPEND_STATE_NONE; +#endif +#ifdef FLASH_SECURITY_REGISTER + sec_reg_enabled = false; +#endif + + if (!reopen) { +#if (CHIP_FLASH_CTRL_VER >= 2) + // Set the direction of 4 IO pins to output when in idle + norflaship_set_idle_io_dir(0); +#endif +#if (CHIP_FLASH_CTRL_VER >= 3) + // Set the dummy cycles for security register read command + norflaship_dummy_others(8); +#endif + + // Reset norflash source clock + hal_cmu_flash_set_freq(HAL_CMU_FREQ_26M); + + // Reset controller timing + hal_norflash_reset_timing(); + + // Reset norflash in slow clock configuration + norflash_reset(); + + // Get device ID + norflash_get_id(norflash_ctx[id].device_id, sizeof(norflash_ctx[id].device_id)); + + // For each driver in array, match chip and select drv_ops + found = norflash_match_chip(norflash_ctx[id].device_id, sizeof(norflash_ctx[id].device_id)); + if (!found) { + result = HAL_NORFLASH_BAD_ID; + goto _exit; + } + +#ifdef FLASH_UNIQUE_ID + // 1) Flash controller V1: + // Use slow clock to avoid rx fifo overflow + // 2) Flash controller V2/3/4/5: + // Use slow clock to avoid stopping SPI clock + // (One bit might be read as a fixed 1 at the SPI clock stopping edge in some timing combinations) + // 3) Flash controller V6 or later: + // Can use fast clock + norflash_get_unique_id(norflash_ctx[id].unique_id, sizeof(norflash_ctx[id].unique_id)); +#endif + } + + // Set norflash source clock + source_freq = hal_norflash_clk_to_cmu_freq(norcfg.source_clk); + hal_cmu_flash_set_freq(source_freq); + + /* over write config */ + if (norcfg.override_config) { + /* div */ + norflaship_div(norcfg.div); + /* cmd quad */ + norflaship_cmdquad(norcfg.cmdquad?HAL_NORFLASH_YES:HAL_NORFLASH_NO); + /* sample delay */ + norflaship_samdly(norcfg.samdly); +#if 0 + /* dummy clc */ + norflaship_dummyclc(norcfg.dummyclc); + + /* dummy clc en */ + norflaship_dummyclcen(norcfg.dummyclcen); + + /* 4 byte address */ + norflaship_addrbyte4(norcfg.byte4byteaddr); +#endif + /* ru en */ + norflaship_ruen(norcfg.spiruen); + /* rd en */ + norflaship_rden(norcfg.spirden); + /* rd cmd */ + norflaship_rdcmd(norcfg.rdcmd); + /* frd cmd */ + norflaship_frdcmd(norcfg.frdcmd); + /* qrd cmd */ + norflaship_qrdcmd(norcfg.qrdcmd); + } else { + // Init divider + result = norflash_init_div(&norcfg); + if (result != 0) { + result = HAL_NORFLASH_BAD_DIV; + goto _exit; + } + + if (!reopen || calib) { + if (reopen) { + norflash_pre_operation(); + } + // Calib with the new divider + result = norflash_sample_delay_calib(DRV_NORFLASH_CALIB_FLASH_ID); + if (result != 0) { + result = HAL_NORFLASH_BAD_CALIB_ID; + goto _exit; + } + if (reopen) { + norflash_post_operation(); + } + } else { + norflash_set_sample_delay_index(timing_idx); + } + } + + if (!reopen) { + norflash_get_size(&norflash_ctx[id].total_size, &norflash_ctx[id].block_size, + &norflash_ctx[id].sector_size, &norflash_ctx[id].page_size); + +#ifdef FLASH_SECURITY_REGISTER + result = hal_norflash_parse_security_register_config(); + if (result == HAL_NORFLASH_OK) { + sec_reg_enabled = true; + } else if (result != HAL_NORFLASH_BAD_OP) { + goto _exit; + } +#endif + +#if (CHIP_FLASH_CTRL_VER <= 1) && !defined(FLASH_LOW_SPEED) && !defined(OSC_26M_X4_AUD2BB) + // 1) Flash controller V2 or later + // No requirement on system_freq + // 2) Flash controller V1 + // Requirement on system_freq when running in quad mode (4-line mode): + // Byte Access: flash_line_speed < 2 * system_freq + // Halfword Access: flash_line_speed < 4 * system_freq + // Word Access: flash_line_speed < 8 * system_freq + // The maximum flash_line_speed is 120M in spec, and PLL_FREQ / 2 in our system. + // Normally it is 24.576M * 8 / 2 ~= 100M. + // So the safe system_freq should be larger than 50M/25M/12.5M for byte/halfword/word access. + // Cached access to flash is always safe, because it is always word-aligned (system_freq is never below 26M). + // However, uncached access (e.g., access to audio/user/factory data sections) is under risk. + hal_sysfreq_set_min_freq(HAL_CMU_FREQ_52M); +#endif + +#if defined(PROGRAMMER) || defined(OTA_PROGRAMMER) + norflash_init_status(0); +#elif defined(FLASH_PROTECTION) + norflash_set_block_protection(hal_norflash_get_bp_cfg(id)); +#endif + } + + op = norcfg.mode; + if (norcfg.speed >= HAL_NORFLASH_SPEED_104M) { + op |= HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE; + } + + // Divider will be set to normal read mode + result = norflash_set_mode(op); + if (result != 0) { + result = HAL_NORFLASH_BAD_OP; + goto _exit; + } + + // ----------------------------- + // From now on, norflash_pre_operation() must be called before + // sending any command to flash + // ----------------------------- + + if (!reopen) { +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) + if (norcfg.dec_enable && (norcfg.dec_size > 0)) { + norflaship_dec_saddr(norcfg.dec_addr); + norflaship_dec_eaddr(norcfg.dec_addr + norcfg.dec_size); + norflaship_dec_index(norcfg.dec_idx); + norflaship_dec_enable(); + } else { + norflaship_dec_disable(); + } +#endif + +#if defined(CHIP_BEST2001) && (defined(PSRAMUHS_ENABLE) || defined(PSRAM_ENABLE)) + norflaship_fetch_disable(); +#endif + } + + if (!norcfg.override_config && (!reopen || calib)) { + result = norflash_sample_delay_calib(DRV_NORFLASH_CALIB_MAGIC_WORD); + if (result != 0) { + result = HAL_NORFLASH_BAD_CALIB_MAGIC; + goto _exit; + } + } + + norflash_ctx[id].opened = true; + + result = HAL_NORFLASH_OK; + +_exit: + if (result != HAL_NORFLASH_OK) { + hal_cmu_flash_set_freq(HAL_CMU_FREQ_26M); + hal_norflash_reset_timing(); + // Flash might be accessed again + } + + norflash_ctx[id].open_state = result; + + return result; +} + +enum HAL_NORFLASH_RET_T hal_norflash_open(enum HAL_NORFLASH_ID_T id, const struct HAL_NORFLASH_CONFIG_T *cfg) +{ + return _norflash_open(id, cfg, false, true, 0); +} + +enum HAL_NORFLASH_RET_T hal_norflash_reopen(enum HAL_NORFLASH_ID_T id, const struct HAL_NORFLASH_CONFIG_T *cfg) +{ + return _norflash_open(id, cfg, true, true, 0); +} + +enum HAL_NORFLASH_RET_T hal_norflash_apply_config(enum HAL_NORFLASH_ID_T id, const struct HAL_NORFLASH_CONFIG_T *cfg, uint32_t timing_idx) +{ + return _norflash_open(id, cfg, true, false, timing_idx); +} + +uint32_t hal_norflash_get_timing_index(enum HAL_NORFLASH_ID_T id) +{ + ASSERT(norflash_ctx[id].opened, err_not_opened); + return norflash_get_sample_delay_index(); +} + +void hal_norflash_show_calib_result(void) +{ + norflash_show_calib_result(); +} + +enum HAL_NORFLASH_RET_T hal_norflash_erase_chip(enum HAL_NORFLASH_ID_T id) +{ + uint32_t total_size = 0; + + ASSERT(norflash_ctx[id].opened, err_not_opened); + + total_size = norflash_ctx[id].total_size; + + return hal_norflash_erase(id, 0, total_size); +} + +static enum HAL_NORFLASH_RET_T hal_norflash_erase_int(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint32_t len, int suspend) +{ + uint32_t remain_len, current_address, total_size, block_size, sector_size; + enum HAL_NORFLASH_RET_T ret = HAL_NORFLASH_OK; + total_size = norflash_ctx[id].total_size; + block_size = norflash_ctx[id].block_size; + sector_size = norflash_ctx[id].sector_size; + + // Check address and length + if (total_size <= (start_address & HAL_NORFLASH_ADDR_MASK)) { + return HAL_NORFLASH_BAD_ADDR; + } + remain_len = total_size - (start_address & HAL_NORFLASH_ADDR_MASK); + if (len > remain_len) { + return HAL_NORFLASH_BAD_LEN; + } + +#ifdef PUYA_FLASH_ERASE_PAGE_ENABLE + // Align to page boundary + uint32_t page_size; + + page_size = norflash_ctx[id].page_size; + remain_len = start_address & (page_size - 1); + if (remain_len) { + start_address -= remain_len; + len += remain_len; + } + remain_len = len & (page_size - 1); + if (remain_len) { + len += page_size - remain_len; + } +#else + // Align to sector boundary + remain_len = start_address & (sector_size - 1); + if (remain_len) { + start_address -= remain_len; + len += remain_len; + } + remain_len = len & (sector_size - 1); + if (remain_len) { + len += sector_size - remain_len; + } +#endif + current_address = start_address; + remain_len = len; + + norflash_pre_operation(); + + if ((current_address & HAL_NORFLASH_ADDR_MASK) == 0 && remain_len >= total_size) { + // erase whole chip + ret = norflash_erase(current_address, DRV_NORFLASH_ERASE_CHIP, suspend); + } else { + while (remain_len > 0 && ret == HAL_NORFLASH_OK) { + if (remain_len >= block_size && ((current_address & (block_size - 1)) == 0)) { + // if large enough to erase a block and current_address is block boundary - erase a block + ret = norflash_erase(current_address, DRV_NORFLASH_ERASE_BLOCK, suspend); + remain_len -= block_size; + current_address += block_size; + } else { +#ifdef PUYA_FLASH_ERASE_PAGE_ENABLE + if (remain_len >= sector_size && ((current_address & (sector_size - 1)) == 0)) { + // if large enough to erase a sector and current_address is sector boundary - erase a sector + ret = norflash_erase(current_address, DRV_NORFLASH_ERASE_SECTOR, suspend); + remain_len -= sector_size; + current_address += sector_size; + } else { + // erase a page + ret = norflash_erase(current_address, DRV_NORFLASH_ERASE_PAGE, suspend); + if (remain_len > page_size) { + remain_len -= page_size; + } else { + remain_len = 0; + } + current_address += page_size; + } +#else + // erase a sector + ret = norflash_erase(current_address, DRV_NORFLASH_ERASE_SECTOR, suspend); + if (remain_len > sector_size) { + remain_len -= sector_size; + } else { + remain_len = 0; + } + current_address += sector_size; +#endif + } + } + } + + norflash_post_operation(); + +#ifdef FLASH_SUSPEND + if (ret == HAL_NORFLASH_SUSPENDED) { + suspend_state = SUSPEND_STATE_ERASE; + op_next_addr = current_address; + op_remain_len = remain_len; + } else { + suspend_state = SUSPEND_STATE_NONE; + } +#endif + + return ret; +} + +enum HAL_NORFLASH_RET_T hal_norflash_erase_suspend(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint32_t len, int suspend) +{ + ASSERT(norflash_ctx[id].opened, err_not_opened); + +#ifdef FLASH_SUSPEND + if (suspend_state != SUSPEND_STATE_NONE) { + return HAL_NORFLASH_BAD_OP; + } + if ((norflash_get_supported_mode() & HAL_NORFLASH_OP_MODE_SUSPEND) == 0) { + suspend = 0; + } +#endif + + return hal_norflash_erase_int(id, start_address, len, suspend); +} + +enum HAL_NORFLASH_RET_T hal_norflash_erase(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint32_t len) +{ + return hal_norflash_erase_suspend(id, start_address, len, 0); +} + +enum HAL_NORFLASH_RET_T hal_norflash_erase_resume(enum HAL_NORFLASH_ID_T id, int suspend) +{ +#ifdef FLASH_SUSPEND + enum HAL_NORFLASH_RET_T ret; + + ASSERT(norflash_ctx[id].opened, err_not_opened); + + if (suspend_state != SUSPEND_STATE_ERASE) { + return HAL_NORFLASH_BAD_OP; + } + if ((norflash_get_supported_mode() & HAL_NORFLASH_OP_MODE_SUSPEND) == 0) { + return HAL_NORFLASH_BAD_OP; + } + + ret = norflash_erase_resume(suspend); + if (ret == HAL_NORFLASH_SUSPENDED) { + return ret; + } + + return hal_norflash_erase_int(id, op_next_addr, op_remain_len, suspend); +#else + return HAL_NORFLASH_OK; +#endif +} + +static enum HAL_NORFLASH_RET_T hal_norflash_write_int(enum HAL_NORFLASH_ID_T id, uint32_t start_address, const uint8_t *buffer, uint32_t len, int suspend) +{ + const uint8_t *current_buffer; + uint32_t remain_len, current_address, total_size, page_size, write_size; + uint32_t pp_remain; + enum HAL_NORFLASH_RET_T ret = HAL_NORFLASH_OK; + + total_size = norflash_ctx[id].total_size; + page_size = norflash_ctx[id].page_size; + + // Check address and length + if (total_size <= (start_address & HAL_NORFLASH_ADDR_MASK)) { + return HAL_NORFLASH_BAD_ADDR; + } + remain_len = total_size - (start_address & HAL_NORFLASH_ADDR_MASK); + if (len > remain_len) { + return HAL_NORFLASH_BAD_LEN; + } + + current_address = start_address; + current_buffer = buffer; + remain_len = len; + + norflash_pre_operation(); + + while (remain_len > 0 && ret == HAL_NORFLASH_OK) { + if (remain_len > page_size) { + write_size = page_size; + } else { + write_size = remain_len; + } + // Align to program page + pp_remain = page_size - (current_address & (page_size - 1)); + if (write_size > pp_remain) { + write_size = pp_remain; + } + + ret = norflash_write(current_address, current_buffer, write_size, suspend); + + current_address += write_size; + current_buffer += write_size; + remain_len -= write_size; + } + + norflash_post_operation(); + +#ifdef FLASH_SUSPEND + if (ret == HAL_NORFLASH_SUSPENDED) { + suspend_state = SUSPEND_STATE_PROGRAM; + op_next_addr = current_address; + op_next_buf = current_buffer; + op_remain_len = remain_len; + } else { + suspend_state = SUSPEND_STATE_NONE; + } +#endif + + return ret; +} + +enum HAL_NORFLASH_RET_T hal_norflash_write_suspend(enum HAL_NORFLASH_ID_T id, uint32_t start_address, const uint8_t *buffer, uint32_t len, int suspend) +{ + ASSERT(norflash_ctx[id].opened, err_not_opened); + +#ifdef FLASH_SUSPEND + if (suspend_state != SUSPEND_STATE_NONE) { + return HAL_NORFLASH_BAD_OP; + } + if ((norflash_get_supported_mode() & HAL_NORFLASH_OP_MODE_SUSPEND) == 0) { + suspend = 0; + } +#endif + + return hal_norflash_write_int(id, start_address, buffer, len, suspend); +} + +enum HAL_NORFLASH_RET_T hal_norflash_write(enum HAL_NORFLASH_ID_T id, uint32_t start_address, const uint8_t *buffer, uint32_t len) +{ + return hal_norflash_write_suspend(id, start_address, buffer, len, 0); +} + +enum HAL_NORFLASH_RET_T hal_norflash_write_resume(enum HAL_NORFLASH_ID_T id, int suspend) +{ +#ifdef FLASH_SUSPEND + enum HAL_NORFLASH_RET_T ret; + + ASSERT(norflash_ctx[id].opened, err_not_opened); + + if (suspend_state != SUSPEND_STATE_PROGRAM) { + return HAL_NORFLASH_BAD_OP; + } + if ((norflash_get_supported_mode() & HAL_NORFLASH_OP_MODE_SUSPEND) == 0) { + return HAL_NORFLASH_BAD_OP; + } + + ret = norflash_write_resume(suspend); + if (ret == HAL_NORFLASH_SUSPENDED) { + return ret; + } + + return hal_norflash_write_int(id, op_next_addr, op_next_buf, op_remain_len, suspend); +#else + return HAL_NORFLASH_OK; +#endif +} + +enum HAL_NORFLASH_RET_T hal_norflash_suspend_check_irq(enum HAL_NORFLASH_ID_T id, uint32_t irq_num) +{ +#ifdef FLASH_SUSPEND + int ret; + + ret = norflash_suspend_check_irq(irq_num); + if (ret) { + return HAL_NORFLASH_ERR; + } +#endif + + return HAL_NORFLASH_OK; +} + +enum HAL_NORFLASH_RET_T hal_norflash_read(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint8_t *buffer, uint32_t len) +{ + uint8_t *current_buffer; + uint32_t remain_len, current_address, total_size, read_size; + + ASSERT(norflash_ctx[id].opened, err_not_opened); + + total_size = norflash_ctx[id].total_size; + + // Check address and length + if (total_size <= (start_address & HAL_NORFLASH_ADDR_MASK)) { + return HAL_NORFLASH_BAD_ADDR; + } + remain_len = total_size - (start_address & HAL_NORFLASH_ADDR_MASK); + if (len > remain_len) { + return HAL_NORFLASH_BAD_LEN; + } + + read_size = NORFLASHIP_RXFIFO_SIZE; + remain_len = len; + current_address = start_address; + current_buffer = buffer; + + norflash_pre_operation(); + + while (remain_len > 0) { + read_size = (remain_len > NORFLASHIP_RXFIFO_SIZE) ? NORFLASHIP_RXFIFO_SIZE : remain_len; + norflash_read(current_address, current_buffer, read_size); + + current_address += read_size; + current_buffer += read_size; + remain_len -= read_size; + } + + norflash_post_operation(); + + return HAL_NORFLASH_OK; +} + +enum HAL_NORFLASH_RET_T hal_norflash_close(enum HAL_NORFLASH_ID_T id) +{ + return HAL_NORFLASH_OK; +} + +void hal_norflash_sleep(enum HAL_NORFLASH_ID_T id) +{ + if (!norflash_ctx[id].opened) { + return; + } + +#ifdef FLASH_DEEP_SLEEP + norflash_sleep(); +#else + norflash_pre_operation(); +#endif + + norflaship_busy_wait(); + norflaship_sleep(); +} + +void hal_norflash_wakeup(enum HAL_NORFLASH_ID_T id) +{ + if (!norflash_ctx[id].opened) { + return; + } + + norflaship_wakeup(); + +#ifdef FLASH_DEEP_SLEEP + norflash_wakeup(); +#else + norflash_post_operation(); +#endif + +#if 0 + // Flush prefetch buffer + *(volatile uint32_t *)FLASH_NC_BASE; + *(volatile uint32_t *)(FLASH_NC_BASE + 0x1000); +#else + norflaship_clear_rxfifo(); + norflaship_busy_wait(); +#endif +} + +int hal_norflash_busy(void) +{ + return norflaship_is_busy(); +} + +static void hal_norflash_prefetch_idle(void) +{ + hal_sys_timer_delay(4); + if (norflaship_is_busy()) { + hal_sys_timer_delay(4); + } +} + +#ifdef FLASH_FREQ_DYNAMIC_ADJUST +int hal_norflash_freq_dynamic_adjust_save_config(struct HAL_NORFLASH_FREQ_DYNAMIC_ADJUST_CONFIG_T *adjust_cfg) +{ + int ret = -1; + + for (uint8_t i = 0; i= 2) + // Set the direction of 4 IO pins to output when in idle + norflaship_set_idle_io_dir(0); +#endif +#if (CHIP_FLASH_CTRL_VER >= 3) + // Set the dummy cycles for security register read command + norflaship_dummy_others(8); +#endif + + // Reset norflash source clock + hal_cmu_flash_set_freq(HAL_CMU_FREQ_26M); + + // Reset controller timing + hal_norflash_reset_timing(); + + // Reset norflash in slow clock configuration + norflash_reset(); + + norflash_ctx[HAL_NORFLASH_ID_0].opened = false; + + return HAL_NORFLASH_OK; +} + +uint32_t hal_norflash_get_flash_total_size(enum HAL_NORFLASH_ID_T id) +{ + return norflash_ctx[id].total_size; +} + +int hal_norflash_opened(enum HAL_NORFLASH_ID_T id) +{ + return norflash_ctx[id].opened; +} + +enum HAL_NORFLASH_RET_T hal_norflash_get_open_state(enum HAL_NORFLASH_ID_T id) +{ + return norflash_ctx[id].open_state; +} + +enum HAL_NORFLASH_RET_T hal_norflash_enable_remap(enum HAL_NORFLASH_ID_T id, uint32_t addr, uint32_t len, uint32_t offset) +{ +#if (CHIP_FLASH_CTRL_VER >= 2) + uint32_t flash_size; + uint32_t remap_from; + int ret; + + STATIC_ASSERT((FLASH_BASE & HAL_NORFLASH_ADDR_MASK) == 0, "Bad FLASH_BASE"); + STATIC_ASSERT((FLASH_SIZE & (FLASH_SIZE - 1)) == 0, "Bad FLASH_SIZE"); + +#ifdef OTA_BARE_BOOT + flash_size = FLASH_SIZE; +#else + if (!norflash_ctx[id].opened) { + return HAL_NORFLASH_NOT_OPENED; + } + + flash_size = norflash_ctx[id].total_size; +#ifndef PROGRAMMER + if (flash_size > FLASH_SIZE) { + flash_size = FLASH_SIZE; + } +#endif +#endif + + remap_from = addr & HAL_NORFLASH_ADDR_MASK; + +#ifdef CHIP_BEST2300P + uint32_t remap_to, remap_len, remap_end, region_len; + uint8_t remap_id; + uint8_t msb_pos; + + if (offset & (offset - 1)) { + return HAL_NORFLASH_BAD_ADDR; + } + if (offset > flash_size / 2) { + return HAL_NORFLASH_BAD_ADDR; + } + flash_size = offset * 2; + + if (remap_from < flash_size / (1 << (NORFLASHIP_REMAP_NUM + 1))) { + return HAL_NORFLASH_BAD_ADDR; + } + if (remap_from % (flash_size / (1 << (NORFLASHIP_REMAP_NUM + 1)))) { + return HAL_NORFLASH_BAD_ADDR; + } + + if (remap_from + len > flash_size / 2) { + return HAL_NORFLASH_BAD_LEN; + } + + norflaship_busy_wait(); + + remap_id = 0; + remap_end = flash_size / 2; + remap_len = remap_end - remap_from; + while (remap_len && remap_id < NORFLASHIP_REMAP_NUM) { + msb_pos = 31 - __CLZ(remap_len); + region_len = 1 << msb_pos; + remap_from = remap_end - region_len; + remap_to = flash_size - remap_end; // OR: (flash_size / 2 + (flash_size / 2 - remap_end)) + ret = norflaship_config_remap_section(remap_id, remap_from, region_len, remap_to); + if (ret) { + return HAL_NORFLASH_BAD_OP; + } + remap_len -= region_len; + remap_end -= region_len; + remap_id++; + } + + if (remap_len) { + return HAL_NORFLASH_BAD_LEN; + } +#else + // Align len to sector size + len = (len + (REMAP_SECTOR_SIZE - 1)) & ~(REMAP_SECTOR_SIZE - 1); + if (len > offset) { + return HAL_NORFLASH_BAD_LEN; + } + if (remap_from + len > offset) { + return HAL_NORFLASH_BAD_LEN; + } + if (remap_from + len + offset > flash_size) { + return HAL_NORFLASH_BAD_ADDR; + } + + norflaship_busy_wait(); + + ret = norflaship_config_remap_section(0, remap_from, len, remap_from + offset); + if (ret) { + return HAL_NORFLASH_BAD_OP; + } +#endif + + hal_norflash_re_enable_remap(id); + + return HAL_NORFLASH_OK; +#else + return HAL_NORFLASH_ERR; +#endif +} + +enum HAL_NORFLASH_RET_T hal_norflash_disable_remap(enum HAL_NORFLASH_ID_T id) +{ +#if (CHIP_FLASH_CTRL_VER >= 2) + norflaship_busy_wait(); + + norflaship_disable_remap(); + + norflaship_busy_wait(); + norflaship_clear_fifos(); + + return HAL_NORFLASH_OK; +#else + return HAL_NORFLASH_ERR; +#endif +} + +enum HAL_NORFLASH_RET_T hal_norflash_re_enable_remap(enum HAL_NORFLASH_ID_T id) +{ +#if (CHIP_FLASH_CTRL_VER >= 2) + norflaship_busy_wait(); + + norflaship_enable_remap(); + + norflaship_busy_wait(); + norflaship_clear_fifos(); + + return HAL_NORFLASH_OK; +#else + return HAL_NORFLASH_ERR; +#endif +} + +int hal_norflash_get_remap_status(enum HAL_NORFLASH_ID_T id) +{ +#if (CHIP_FLASH_CTRL_VER >= 2) + return norflaship_get_remap_status(); +#else + return HAL_NORFLASH_ERR; +#endif +} + diff --git a/platform/hal/hal_norflash.h b/platform/hal/hal_norflash.h new file mode 100644 index 0000000..41ce65e --- /dev/null +++ b/platform/hal/hal_norflash.h @@ -0,0 +1,185 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef NORFLASH_HAL_H +#define NORFLASH_HAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_cmu.h" + +#define HAL_NORFLASH_DEVICE_ID_LEN 3 + +#define HAL_NORFLASH_UNIQUE_ID_LEN 16 + +enum HAL_NORFLASH_ID_T { + HAL_NORFLASH_ID_0 = 0, + HAL_NORFLASH_ID_NUM, +}; + +enum HAL_NORFLASH_RET_T { + HAL_NORFLASH_OK, + HAL_NORFLASH_SUSPENDED, + HAL_NORFLASH_ERR, + HAL_NORFLASH_BAD_ID, + HAL_NORFLASH_BAD_DIV, + HAL_NORFLASH_BAD_CALIB_ID, + HAL_NORFLASH_BAD_CFG, + HAL_NORFLASH_BAD_OP, + HAL_NORFLASH_BAD_CALIB_MAGIC, + HAL_NORFLASH_BAD_ADDR, + HAL_NORFLASH_BAD_LEN, + HAL_NORFLASH_NOT_OPENED, + HAL_NORFLASH_CFG_NULL, +}; + +enum HAL_NORFLASH_SPEED { + HAL_NORFLASH_SPEED_13M = 13000000, + HAL_NORFLASH_SPEED_26M = 26000000, + HAL_NORFLASH_SPEED_52M = 52000000, + HAL_NORFLASH_SPEED_78M = 78000000, + HAL_NORFLASH_SPEED_104M = 104000000, + HAL_NORFLASH_SPEED_130M = 130000000, + HAL_NORFLASH_SPEED_156M = 156000000, + HAL_NORFLASH_SPEED_182M = 182000000, + HAL_NORFLASH_SPEED_208M = 208000000, + HAL_NORFLASH_SPEED_234M = 234000000, +}; + +enum HAL_NORFLASH_OP_MODE { + // Different groups can be used together, different flash-device may support different option(s) + + // (1) basic read mode + /* standard spi mode */ + HAL_NORFLASH_OP_MODE_STAND_SPI = 0x1, + /* fast spi mode*/ + HAL_NORFLASH_OP_MODE_FAST_SPI = 0x2, + /* dual mode */ + HAL_NORFLASH_OP_MODE_DUAL_OUTPUT = 0x4, + /* dual mode */ + HAL_NORFLASH_OP_MODE_DUAL_IO = 0x8, + /* quad mode */ + HAL_NORFLASH_OP_MODE_QUAD_OUTPUT = 0x10, + /* quad mode */ + HAL_NORFLASH_OP_MODE_QUAD_IO = 0x20, + + // (2) extend read mode + // read accelerate (no cmd bettween read operation) : + // may need Dual or Quad Mode + HAL_NORFLASH_OP_MODE_CONTINUOUS_READ = 0x40, + // read high performance mode + HAL_NORFLASH_OP_MODE_HIGH_PERFORMANCE = 0x80, + // read wrap mode + HAL_NORFLASH_OP_MODE_READ_WRAP = 0x100, + + // (3) program mode. + // page program mode + HAL_NORFLASH_OP_MODE_PAGE_PROGRAM = 0x200, + // dual program mode + HAL_NORFLASH_OP_MODE_DUAL_PAGE_PROGRAM = 0x400, + // quad program mode + HAL_NORFLASH_OP_MODE_QUAD_PAGE_PROGRAM = 0x800, + + // (4) advanced features + // suspend and resume + HAL_NORFLASH_OP_MODE_SUSPEND = 0x1000, + // erase in standard spi mode + HAL_NORFLASH_OP_MODE_ERASE_IN_STD = 0x2000, + + HAL_NORFLASH_OP_MODE_RESERVED = 0xFFFFFFFF, +}; + +struct HAL_NORFLASH_CONFIG_T { + uint32_t source_clk; + uint32_t speed; + enum HAL_NORFLASH_OP_MODE mode; + + /* internal use : can be config if need to (useful for rom) */ + uint8_t override_config:1; + uint8_t neg_phase:1; + uint8_t pos_neg:1; + uint8_t cmdquad:1; + uint8_t samdly:3; + uint8_t div; /* least 2 */ + uint8_t dualmode:1; + uint8_t holdpin:1; + uint8_t wprpin:1; + uint8_t quadmode:1; + + uint8_t spiruen:3; + uint8_t spirden:3; + + uint8_t dualiocmd; + uint8_t rdcmd; + uint8_t frdcmd; + uint8_t qrdcmd; /* quad io cmd */ +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) + uint8_t dec_enable; /* 1: enable decoder, 0: disable decoder */ + uint8_t dec_idx; /* decoder key index ,from 0 to 3 */ + uint32_t dec_addr; /* start address where to decode */ + uint32_t dec_size; /* bytes number will be decoded */ +#endif +}; + +/* hal api */ +void hal_norflash_set_freq(enum HAL_CMU_FREQ_T freq); +const struct HAL_NORFLASH_CONFIG_T *hal_norflash_get_init_config(void); +enum HAL_NORFLASH_RET_T hal_norflash_init(void); +enum HAL_NORFLASH_RET_T hal_norflash_deinit(void); +enum HAL_NORFLASH_RET_T hal_norflash_open(enum HAL_NORFLASH_ID_T id, const struct HAL_NORFLASH_CONFIG_T *cfg); +enum HAL_NORFLASH_RET_T hal_norflash_reopen(enum HAL_NORFLASH_ID_T id, const struct HAL_NORFLASH_CONFIG_T *cfg); +enum HAL_NORFLASH_RET_T hal_norflash_apply_config(enum HAL_NORFLASH_ID_T id, const struct HAL_NORFLASH_CONFIG_T *cfg, uint32_t timing_idx); +uint32_t hal_norflash_get_timing_index(enum HAL_NORFLASH_ID_T id); +void hal_norflash_show_calib_result(void); +enum HAL_CMU_FREQ_T hal_norflash_clk_to_cmu_freq(uint32_t clk); +enum HAL_NORFLASH_RET_T hal_norflash_get_size(enum HAL_NORFLASH_ID_T id, uint32_t *total_size, uint32_t *block_size, uint32_t *sector_size, uint32_t *page_size); +enum HAL_NORFLASH_RET_T hal_norflash_get_boundary(enum HAL_NORFLASH_ID_T id, uint32_t address, uint32_t* block_boundary, uint32_t* sector_boundary); +enum HAL_NORFLASH_RET_T hal_norflash_get_id(enum HAL_NORFLASH_ID_T id, uint8_t *value, uint32_t len); +enum HAL_NORFLASH_RET_T hal_norflash_get_unique_id(enum HAL_NORFLASH_ID_T id, uint8_t *value, uint32_t len); +enum HAL_NORFLASH_RET_T hal_norflash_enable_protection(enum HAL_NORFLASH_ID_T id); +enum HAL_NORFLASH_RET_T hal_norflash_disable_protection(enum HAL_NORFLASH_ID_T id); +enum HAL_NORFLASH_RET_T hal_norflash_erase_chip(enum HAL_NORFLASH_ID_T id); +enum HAL_NORFLASH_RET_T hal_norflash_erase_suspend(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint32_t len, int suspend); +enum HAL_NORFLASH_RET_T hal_norflash_erase(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint32_t len); +enum HAL_NORFLASH_RET_T hal_norflash_erase_resume(enum HAL_NORFLASH_ID_T id, int suspend); +enum HAL_NORFLASH_RET_T hal_norflash_write_suspend(enum HAL_NORFLASH_ID_T id, uint32_t start_address, const uint8_t *buffer, uint32_t len, int suspend); +enum HAL_NORFLASH_RET_T hal_norflash_write(enum HAL_NORFLASH_ID_T id, uint32_t start_address, const uint8_t *buffer, uint32_t len); +enum HAL_NORFLASH_RET_T hal_norflash_write_resume(enum HAL_NORFLASH_ID_T id, int suspend); +enum HAL_NORFLASH_RET_T hal_norflash_suspend_check_irq(enum HAL_NORFLASH_ID_T id, uint32_t irq_num); +enum HAL_NORFLASH_RET_T hal_norflash_read(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint8_t *buffer, uint32_t len); +enum HAL_NORFLASH_RET_T hal_norflash_close(enum HAL_NORFLASH_ID_T id); +void hal_norflash_sleep(enum HAL_NORFLASH_ID_T id); +void hal_norflash_wakeup(enum HAL_NORFLASH_ID_T id); +int hal_norflash_busy(void); +uint32_t hal_norflash_get_flash_total_size(enum HAL_NORFLASH_ID_T id); +int hal_norflash_opened(enum HAL_NORFLASH_ID_T id); +enum HAL_NORFLASH_RET_T hal_norflash_get_open_state(enum HAL_NORFLASH_ID_T id); +enum HAL_NORFLASH_RET_T hal_norflash_security_register_lock(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint32_t len); +enum HAL_NORFLASH_RET_T hal_norflash_security_register_erase(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint32_t len); +enum HAL_NORFLASH_RET_T hal_norflash_security_register_write(enum HAL_NORFLASH_ID_T id, uint32_t start_address, const uint8_t *buffer, uint32_t len); +enum HAL_NORFLASH_RET_T hal_norflash_security_register_read(enum HAL_NORFLASH_ID_T id, uint32_t start_address, uint8_t *buffer, uint32_t len); +enum HAL_NORFLASH_RET_T hal_norflash_enable_remap(enum HAL_NORFLASH_ID_T id, uint32_t addr, uint32_t len, uint32_t offset); +enum HAL_NORFLASH_RET_T hal_norflash_disable_remap(enum HAL_NORFLASH_ID_T id); +enum HAL_NORFLASH_RET_T hal_norflash_re_enable_remap(enum HAL_NORFLASH_ID_T id); +int hal_norflash_get_remap_status(enum HAL_NORFLASH_ID_T id); + +#ifdef __cplusplus +} +#endif + +#endif /* NORFLASH_HAL_H */ diff --git a/platform/hal/hal_norflaship.h b/platform/hal/hal_norflaship.h new file mode 100644 index 0000000..afc9b31 --- /dev/null +++ b/platform/hal/hal_norflaship.h @@ -0,0 +1,179 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_NORFLASHIP_H__ +#define __HAL_NORFLASHIP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +#if (CHIP_FLASH_CTRL_VER <= 1) +#define NORFLASHIP_RXFIFO_SIZE 8 +#define NORFLASHIP_TXFIFO_SIZE 256 +#else +#define NORFLASHIP_RXFIFO_SIZE 8 +#define NORFLASHIP_TXFIFO_SIZE 16 + +#if !defined(CHIP_BEST2300) +#define NORFLASHIP_HAS_SECURITY +#endif + +#if (defined(CHIP_BEST2300) || defined(CHIP_BEST1400)) +#define NORFLASHIP_REMAP_NUM 0 +#else +#define NORFLASHIP_HAS_IDLE_IO_CTRL +#define NORFLASHIP_HAS_REMAP +#define NORFLASHIP_REMAP_NUM 4 +#endif +#endif + +#define REMAP_SECTOR_SIZE 0x1000 + +uint8_t norflaship_continuous_read_mode_bit(uint8_t mode_bit); + +uint8_t norflaship_continuous_read_off(void); + +uint8_t norflaship_continuous_read_on(void); + +uint32_t norflaship_write_txfifo(const uint8_t *val, uint32_t len); + +#if (CHIP_FLASH_CTRL_VER <= 1) +uint32_t norflaship_v1_write_txfifo_safe(const uint8_t *val, uint32_t len); + +uint32_t norflaship_v1_write_txfifo_all(const uint8_t *val, uint32_t len); +#endif + +uint8_t norflaship_read_rxfifo_count(void); + +uint8_t norflaship_read_rxfifo(void); + +void norflaship_blksize(uint32_t blksize); + +void norflaship_cmd_addr(uint8_t cmd, uint32_t address); + +void norflaship_ext_tx_cmd(uint8_t cmd, uint32_t tx_len); + +void norflaship_ext_rx_cmd(uint8_t cmd, uint32_t tx_len, uint32_t rx_len); + +void norflaship_cmd_done(void); + +void norflaship_rxfifo_count_wait(uint8_t cnt); + +void norflaship_rxfifo_empty_wait(void); + +void norflaship_busy_wait(void); + +int norflaship_is_busy(void); + +void norflaship_clear_fifos(void); + +void norflaship_clear_rxfifo(void); + +void norflaship_clear_txfifo(void); + +void norflaship_div(uint32_t div); + +uint32_t norflaship_get_div(void); + +void norflaship_cmdquad(uint32_t v); + +uint32_t norflaship_get_pos_neg(void); + +void norflaship_pos_neg(uint32_t v); + +uint32_t norflaship_get_neg_phase(void); + +void norflaship_neg_phase(uint32_t v); + +uint32_t norflaship_get_samdly(void); + +void norflaship_samdly(uint32_t v); + +void norflaship_dual_mode(uint32_t v); + +void norflaship_hold_pin(uint32_t v); + +void norflaship_wpr_pin(uint32_t v); + +void norflaship_quad_mode(uint32_t v); + +void norflaship_dummyclc(uint32_t v); + +void norflaship_dummyclcen(uint32_t v); + +void norflaship_addrbyte4(uint32_t v); + +void norflaship_ruen(uint32_t v); + +void norflaship_rden(uint32_t v); + +void norflaship_dualiocmd(uint32_t v); + +void norflaship_rdcmd(uint32_t v); + +void norflaship_frdcmd(uint32_t v); + +void norflaship_qrdcmd(uint32_t v); + +uint32_t norflaship_get_rdcmd(void); + +void norflaship_set_idle_io_dir(uint32_t v); + +void norflaship_sleep(void); + +void norflaship_wakeup(void); + +void norflaship_dec_index(uint32_t idx); + +void norflaship_dec_saddr(uint32_t addr); + +void norflaship_dec_eaddr(uint32_t addr); + +void norflaship_dec_enable(void); + +void norflaship_dec_disable(void); + +void norflaship_man_wrap_width(uint32_t width); + +void norflaship_man_wrap_enable(void); + +void norflaship_man_wrap_disable(void); + +void norflaship_auto_wrap_cmd(uint32_t cmd); + +void norflaship_man_mode_enable(void); + +void norflaship_man_mode_disable(void); + +int norflaship_config_remap_section(uint32_t id, uint32_t addr, uint32_t len, uint32_t new_addr); + +void norflaship_enable_remap(void); + +void norflaship_disable_remap(void); + +int norflaship_get_remap_status(void); + +void norflaship_dummy_others(uint32_t v); + +void norflaship_fetch_disable(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_norflaship_v1.c b/platform/hal/hal_norflaship_v1.c new file mode 100644 index 0000000..d88054c --- /dev/null +++ b/platform/hal/hal_norflaship_v1.c @@ -0,0 +1,431 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if (CHIP_FLASH_CTRL_VER <= 1) + +#include "plat_types.h" +#include "plat_addr_map.h" +#include "reg_norflaship_v1.h" +#include "hal_norflaship.h" +#ifdef PROGRAMMER +#include "task_schedule.h" +#else +#define TASK_SCHEDULE true +#endif + +//==================================================================================== +// Flash IP Operations +//==================================================================================== + +/* + Supported Command List (Based on GD25Q32C): + + parameter NOP = 8'h00 ; + parameter WRR = 8'h01 ; + parameter PP = 8'h02 ; + parameter READ = 8'h03 ; + parameter WRDI = 8'h04 ; + parameter RDSR = 8'h05 ; + parameter WREN = 8'h06 ; + parameter FAST_READ = 8'h0B ; + parameter P4E = 8'h20 ; + parameter SE2 = 8'h20 ; + parameter CLSR = 8'h30 ; + parameter QPP = 8'h32 ; + parameter RCR = 8'h35 ; + parameter DOR = 8'h3B ; + parameter P8E = 8'h40 ; + parameter OTPP = 8'h42 ; + parameter PSR = 8'h42 ; + parameter ESR = 8'h44 ; + parameter RSR = 8'h48 ; + parameter OTPR = 8'h4B ; + parameter BE32 = 8'h52 ; + parameter CE = 8'h60 ; + parameter QOR = 8'h6B ; + parameter PES = 8'h75 ; + parameter PER = 8'h7A ; + parameter READ_ID = 8'h90 ; + parameter RDID = 8'h9F ; + parameter HPM = 8'hA3 ; + parameter RES = 8'hAB ; + parameter DP = 8'hB9 ; + parameter DIOR = 8'hBB ; + parameter BE = 8'hC7 ; + parameter BE64 = 8'hD8 ; + parameter SE = 8'hD8 ; + parameter QIOWR = 8'hE7 ; + parameter QIOR = 8'hEB ; + parameter CRR = 8'hFF ; +*/ + +/* register memory address */ +#define NORFLASHIP_BASEADDR FLASH_CTRL_BASE + +#define norflaship_readb(a) \ + (*(volatile unsigned char*)(NORFLASHIP_BASEADDR+a)) + +#define norflaship_read32(a) \ + (*(volatile unsigned int *)(NORFLASHIP_BASEADDR+a)) + +#define norflaship_write32(v,a) \ + ((*(volatile unsigned int *)(NORFLASHIP_BASEADDR+a)) = v) + +/* ip ops */ +uint8_t norflaship_continuous_read_mode_bit(uint8_t mode_bit) +{ + uint32_t val = 0; + norflaship_busy_wait(); + val = norflaship_read32(TX_CONFIG2_BASE); + val &= ~(TX_MODBIT_MASK); + val |= (mode_bit< 0) { + st = norflaship_read32(INT_STATUS_BASE); + if (st & TXFIFOFULL_MASK) { + continue; + } + norflaship_write32(*val, TXDATA_BASE); + val++; + len--; + } + return 0; +} +uint8_t norflaship_read_rxfifo_count(void) +{ + uint32_t val = 0; + val = norflaship_readb(INT_STATUS_BASE); + return ((val&RXFIFOCOUNT_MASK)>>RXFIFOCOUNT_SHIFT); +} +uint8_t norflaship_read_rxfifo(void) +{ + uint32_t val = 0; + val = norflaship_readb(RXDATA_BASE); + return val&0xff; +} +void norflaship_blksize(uint32_t blksize) +{ + uint32_t val = 0; + val = norflaship_read32(TX_CONFIG2_BASE); + val = ((~(TX_BLKSIZE_MASK))&val) | (blksize<>RXFIFOCOUNT_SHIFT) < cnt) && TASK_SCHEDULE); +} +void norflaship_rxfifo_empty_wait(void) +{ + uint32_t st = 0; + do { + st = norflaship_read32(INT_STATUS_BASE); + } while ((st&RXFIFOEMPTY_MASK) && TASK_SCHEDULE); +} +void norflaship_busy_wait(void) +{ + uint32_t st = 0; + do { + st = norflaship_read32(INT_STATUS_BASE); + } while ((st&BUSY_MASK) && TASK_SCHEDULE); +} +int norflaship_is_busy(void) +{ + uint32_t st = 0; + st = norflaship_read32(INT_STATUS_BASE); + return !!(st&BUSY_MASK); +} +void norflaship_clear_fifos(void) +{ + norflaship_busy_wait(); + norflaship_write32(RXFIFOCLR_MASK|TXFIFOCLR_MASK, FIFO_CONFIG_BASE); + norflaship_busy_wait(); +} +void norflaship_clear_rxfifo(void) +{ + norflaship_busy_wait(); + norflaship_write32(RXFIFOCLR_MASK, FIFO_CONFIG_BASE); + norflaship_busy_wait(); +} +void norflaship_clear_txfifo(void) +{ + norflaship_busy_wait(); + norflaship_write32(TXFIFOCLR_MASK, FIFO_CONFIG_BASE); + norflaship_busy_wait(); +} +void norflaship_div(uint32_t div) +{ + uint32_t val = 0; + norflaship_busy_wait(); + val = norflaship_read32(MODE1_CONFIG_BASE); + val = (~(CLKDIV_MASK) & val) | (div<> CLKDIV_SHIFT; +} +void norflaship_cmdquad(uint32_t v) +{ + uint32_t val = 0; + norflaship_busy_wait(); + val = norflaship_read32(MODE1_CONFIG_BASE); + if (v) + val |= CMDQUAD_MASK; + else + val &= ~CMDQUAD_MASK; + norflaship_write32(val, MODE1_CONFIG_BASE); +} +uint32_t norflaship_get_pos_neg(void) +{ + uint32_t val = 0; + val = norflaship_read32(MODE1_CONFIG_BASE); + return !!(val & POS_NEG_MASK); +} +void norflaship_pos_neg(uint32_t v) +{ + uint32_t val = 0; + norflaship_busy_wait(); + val = norflaship_read32(MODE1_CONFIG_BASE); + if (v) + val |= POS_NEG_MASK; + else + val &= ~POS_NEG_MASK; + norflaship_write32(val, MODE1_CONFIG_BASE); +} +uint32_t norflaship_get_neg_phase(void) +{ + uint32_t val = 0; + val = norflaship_read32(MODE1_CONFIG_BASE); + return !!(val & NEG_PHASE_MASK); +} +void norflaship_neg_phase(uint32_t v) +{ + uint32_t val = 0; + norflaship_busy_wait(); + val = norflaship_read32(MODE1_CONFIG_BASE); + if (v) + val |= NEG_PHASE_MASK; + else + val &= ~NEG_PHASE_MASK; + norflaship_write32(val, MODE1_CONFIG_BASE); +} +uint32_t norflaship_get_samdly(void) +{ + uint32_t val = 0; + val = norflaship_read32(MODE1_CONFIG_BASE); + return (val & SAMDLY_MASK) >> SAMDLY_SHIFT; +} +void norflaship_samdly(uint32_t v) +{ + uint32_t val = 0; + norflaship_busy_wait(); + val = norflaship_read32(MODE1_CONFIG_BASE); + val = (~(SAMDLY_MASK) & val) | (v<> RDCMD_SHIFT); +} +void norflaship_sleep(void) +{ +} +void norflaship_wakeup(void) +{ +} + +#endif diff --git a/platform/hal/hal_norflaship_v2.c b/platform/hal/hal_norflaship_v2.c new file mode 100644 index 0000000..9b5e2c8 --- /dev/null +++ b/platform/hal/hal_norflaship_v2.c @@ -0,0 +1,563 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if (CHIP_FLASH_CTRL_VER >= 2) + +#include "plat_types.h" +#include "plat_addr_map.h" +#include "cmsis.h" +#include "reg_norflaship_v2.h" +#include "hal_norflaship.h" +#ifdef PROGRAMMER +#include "task_schedule.h" +#else +#define TASK_SCHEDULE true +#endif + +//==================================================================================== +// Flash IP Operations +//==================================================================================== + +/* + Supported Command List (Based on GD25Q32C): + + parameter WRSR1 = 8'h01 ; + parameter PP = 8'h02 ; + parameter READ = 8'h03 ; + parameter WRDI = 8'h04 ; + parameter RDSR1 = 8'h05 ; + parameter WREN = 8'h06 ; + parameter FREAD = 8'h0B ; + parameter WRSR3 = 8'h11 ; + parameter RDSR3 = 8'h15 ; + parameter SE = 8'h20 ; + parameter WRSR2 = 8'h31 ; + parameter QPP = 8'h32 ; + parameter RDSR2 = 8'h35 ; + parameter DOR = 8'h3B ; + parameter PSR = 8'h42 ; + parameter ESR = 8'h44 ; + parameter RSR = 8'h48 ; + parameter WEVSR = 8'h50 ; + parameter BE32 = 8'h52 ; + parameter RSFDP = 8'h5A ; + parameter CE = 8'h60 ; + parameter RSTE = 8'h66 ; + parameter QOR = 8'h6B ; + parameter PES = 8'h75 ; + parameter SBW = 8'h77 ; + parameter PER = 8'h7A ; + parameter REMS = 8'h90 ; + parameter DREAD_ID = 8'h92 ; + parameter QREAD_ID = 8'h94 ; + parameter RST = 8'h99 ; + parameter RDID = 8'h9F ; + parameter HPM = 8'hA3 ; + parameter RDI = 8'hAB ; + parameter DP = 8'hB9 ; + parameter DIOR = 8'hBB ; + parameter BE64 = 8'hD8 ; + parameter QIOWR = 8'hE7 ; + parameter QIOR = 8'hEB ; + parameter FPP = 8'hF2 ; +*/ + +static struct NORFLASH_CTRL_T * const norflash = (struct NORFLASH_CTRL_T *)FLASH_CTRL_BASE; + +#if 0 +static const uint8_t line_mode[8] = { + NEW_CMD_LINE_1X, NEW_CMD_LINE_1X, NEW_CMD_LINE_2X, NEW_CMD_LINE_1X, + NEW_CMD_LINE_4X, NEW_CMD_LINE_1X, NEW_CMD_LINE_1X, NEW_CMD_LINE_1X, +}; +#endif + +uint8_t norflaship_continuous_read_mode_bit(uint8_t mode_bit) +{ + norflaship_busy_wait(); + norflash->REG_004 = SET_BITFIELD(norflash->REG_004, REG_004_MODEBIT, mode_bit); + return 0; +} +uint8_t norflaship_continuous_read_off(void) +{ + norflaship_busy_wait(); + norflash->REG_004 &= ~REG_004_CONTINUOUS_MODE; + return 0; +} +uint8_t norflaship_continuous_read_on(void) +{ + norflaship_busy_wait(); + norflash->REG_004 |= REG_004_CONTINUOUS_MODE; + return 0; +} +uint8_t norflaship_read_txfifo_empty_count(void) +{ + return GET_BITFIELD(norflash->REG_00C, REG_00C_TXFIFO_EMPCNT); +} +uint32_t norflaship_write_txfifo(const uint8_t *val, uint32_t len) +{ + uint32_t avail = norflaship_read_txfifo_empty_count(); + while (len > 0 && avail > 0) { +#if 0 + if (len >= 4 && ((uint32_t)val & 3) == 0) { + norflash->REG_008.TXWORD = *(uint32_t *)val; + val += 4; + len -= 4; + } else if (len >= 2 && ((uint32_t)val & 1) == 0) { + norflash->REG_008.TXHALFWORD = *(uint16_t *)val; + val += 2; + len -= 2; + } else +#endif + { + norflash->REG_008.TXBYTE = *(uint8_t *)val; + val += 1; + len -= 1; + } + avail -= 1; + } + return len; +} +uint8_t norflaship_read_rxfifo_count(void) +{ + return GET_BITFIELD(norflash->REG_00C, REG_00C_RXFIFO_COUNT); +} +uint8_t norflaship_read_rxfifo(void) +{ + return norflash->REG_010; +} +void norflaship_blksize(uint32_t blksize) +{ + norflash->REG_004 = SET_BITFIELD(norflash->REG_004, REG_004_BLOCK_SIZE, blksize); +} +void norflaship_cmd_addr(uint8_t cmd, uint32_t address) +{ + norflaship_busy_wait(); + norflash->REG_004 &= ~REG_004_NEW_CMD_EN; + norflash->REG_000 = REG_000_CMD(cmd) | REG_000_ADDR(address); +} +void norflaship_ext_tx_cmd(uint8_t cmd, uint32_t tx_len) +{ + norflaship_busy_wait(); + norflash->REG_004 = SET_BITFIELD(norflash->REG_004, REG_004_BLOCK_SIZE, tx_len) | REG_004_NEW_CMD_EN; + norflash->REG_000 = REG_000_CMD(cmd); +} +void norflaship_ext_rx_cmd(uint8_t cmd, uint32_t tx_len, uint32_t rx_len) +{ + norflaship_busy_wait(); + norflash->REG_004 = SET_BITFIELD(norflash->REG_004, REG_004_BLOCK_SIZE, tx_len) | REG_004_NEW_CMD_EN; + norflash->REG_000 = REG_000_CMD(cmd) | REG_000_NEW_CMD_RX_EN | REG_000_NEW_CMD_RX_LEN(rx_len); +} +void norflaship_cmd_done(void) +{ + norflaship_busy_wait(); + norflash->REG_004 &= ~REG_004_NEW_CMD_EN; +} +void norflaship_rxfifo_count_wait(uint8_t cnt) +{ + while ((norflaship_read_rxfifo_count() < cnt) && TASK_SCHEDULE); +} +void norflaship_rxfifo_empty_wait(void) +{ + while ((norflash->REG_00C & REG_00C_RXFIFO_EMPTY) && TASK_SCHEDULE); +} +int norflaship_txfifo_is_full(void) +{ + return !!(norflash->REG_00C & REG_00C_TXFIFO_FULL); +} +void norflaship_busy_wait(void) +{ + while ((norflash->REG_00C & REG_00C_BUSY) && TASK_SCHEDULE); +} +int norflaship_is_busy(void) +{ + return !!(norflash->REG_00C & REG_00C_BUSY); +} +void norflaship_clear_fifos(void) +{ + norflaship_busy_wait(); + norflash->REG_018 = REG_018_TXFIFOCLR | REG_018_RXFIFOCLR; + norflaship_busy_wait(); +} +void norflaship_clear_rxfifo(void) +{ + norflaship_busy_wait(); + norflash->REG_018 = REG_018_RXFIFOCLR; + norflaship_busy_wait(); +} +void norflaship_clear_txfifo(void) +{ + norflaship_busy_wait(); + norflash->REG_018 = REG_018_TXFIFOCLR; + norflaship_busy_wait(); +} +void norflaship_div(uint32_t div) +{ + norflaship_busy_wait(); +#ifdef CHIP_BEST2300P + norflash->REG_014 = SET_BITFIELD(norflash->REG_014, REG_014_CLKDIV, div) | EXTRA_TCHSH_EN_O; +#else + norflash->REG_014 = SET_BITFIELD(norflash->REG_014, REG_014_CLKDIV, div); +#endif +} +uint32_t norflaship_get_div(void) +{ + return GET_BITFIELD(norflash->REG_014, REG_014_CLKDIV); +} +void norflaship_cmdquad(uint32_t v) +{ + norflaship_busy_wait(); +#ifdef CHIP_BEST2300P + if (v) { + norflash->REG_014 |= REG_014_CMDQUAD | EXTRA_TCHSH_EN_O; + } else { + norflash->REG_014 = (norflash->REG_014 & ~REG_014_CMDQUAD) | EXTRA_TCHSH_EN_O; + } +#else + if (v) { + norflash->REG_014 |= REG_014_CMDQUAD; + } else { + norflash->REG_014 &= ~REG_014_CMDQUAD; + } +#endif +} +uint32_t norflaship_get_samdly(void) +{ + return GET_BITFIELD(norflash->REG_014, REG_014_SAMPLESEL); +} +void norflaship_samdly(uint32_t v) +{ + norflaship_busy_wait(); +#ifdef CHIP_BEST2300P + norflash->REG_014 = SET_BITFIELD(norflash->REG_014, REG_014_SAMPLESEL, v) | EXTRA_TCHSH_EN_O; +#else + norflash->REG_014 = SET_BITFIELD(norflash->REG_014, REG_014_SAMPLESEL, v); +#endif +} +void norflaship_dual_mode(uint32_t v) +{ + norflaship_busy_wait(); +#ifdef CHIP_BEST2300P + if (v) { + norflash->REG_014 |= REG_014_RAM_DUALMODE | EXTRA_TCHSH_EN_O; + } else { + norflash->REG_014 = (norflash->REG_014 & ~REG_014_RAM_DUALMODE) | EXTRA_TCHSH_EN_O; + } +#else + if (v) { + norflash->REG_014 |= REG_014_RAM_DUALMODE; + } else { + norflash->REG_014 &= ~REG_014_RAM_DUALMODE; + } +#endif +} +void norflaship_hold_pin(uint32_t v) +{ +#ifdef CHIP_BEST2300P + if (v) { + norflash->REG_014 |= REG_014_HOLDPIN | EXTRA_TCHSH_EN_O; + } else { + norflash->REG_014 = (norflash->REG_014 & ~REG_014_HOLDPIN) | EXTRA_TCHSH_EN_O; + } +#else + if (v) { + norflash->REG_014 |= REG_014_HOLDPIN; + } else { + norflash->REG_014 &= ~REG_014_HOLDPIN; + } +#endif +} +void norflaship_wpr_pin(uint32_t v) +{ +#ifdef CHIP_BEST2300P + if (v) { + norflash->REG_014 |= REG_014_WPROPIN | EXTRA_TCHSH_EN_O; + } else { + norflash->REG_014 = (norflash->REG_014 & ~REG_014_WPROPIN) | EXTRA_TCHSH_EN_O; + } +#else + if (v) { + norflash->REG_014 |= REG_014_WPROPIN; + } else { + norflash->REG_014 &= ~REG_014_WPROPIN; + } +#endif +} +void norflaship_quad_mode(uint32_t v) +{ + norflaship_busy_wait(); +#ifdef CHIP_BEST2300P + if (v) { + norflash->REG_014 |= REG_014_RAM_QUADMODE | EXTRA_TCHSH_EN_O; + } else { + norflash->REG_014 = (norflash->REG_014 & ~REG_014_RAM_QUADMODE) | EXTRA_TCHSH_EN_O; + } +#else + if (v) { + norflash->REG_014 |= REG_014_RAM_QUADMODE; + } else { + norflash->REG_014 &= ~REG_014_RAM_QUADMODE; + } +#endif +} +void norflaship_addrbyte4(uint32_t v) +{ +#ifdef CHIP_BEST2300P + if (v) { + norflash->REG_014 |= REG_014_FOUR_BYTE_ADDR_EN | EXTRA_TCHSH_EN_O; + } else { + norflash->REG_014 = (norflash->REG_014 & ~REG_014_FOUR_BYTE_ADDR_EN) | EXTRA_TCHSH_EN_O; + } +#else + if (v) { + norflash->REG_014 |= REG_014_FOUR_BYTE_ADDR_EN; + } else { + norflash->REG_014 &= ~REG_014_FOUR_BYTE_ADDR_EN; + } +#endif +} +void norflaship_ruen(uint32_t v) +{ + norflash->REG_034 = SET_BITFIELD(norflash->REG_034, REG_034_SPI_RUEN, v); +} +void norflaship_rden(uint32_t v) +{ + norflash->REG_034 = SET_BITFIELD(norflash->REG_034, REG_034_SPI_RDEN, v); +} +void norflaship_dualiocmd(uint32_t v) +{ + norflash->REG_020 = SET_BITFIELD(norflash->REG_020, REG_020_DUALCMD, v); +} +void norflaship_rdcmd(uint32_t v) +{ + norflash->REG_020 = SET_BITFIELD(norflash->REG_020, REG_020_READCMD, v); +} +void norflaship_frdcmd(uint32_t v) +{ + norflash->REG_020 = SET_BITFIELD(norflash->REG_020, REG_020_FREADCMD, v); +} +void norflaship_qrdcmd(uint32_t v) +{ + norflash->REG_020 = SET_BITFIELD(norflash->REG_020, REG_020_QUADCMD, v); +} +uint32_t norflaship_get_rdcmd(void) +{ + return GET_BITFIELD(norflash->REG_020, REG_020_READCMD); +} +void norflaship_set_idle_io_dir(uint32_t v) +{ +#ifdef NORFLASHIP_HAS_IDLE_IO_CTRL + norflash->REG_034 = SET_BITFIELD(norflash->REG_034, REG_034_SPI_IOEN, v); +#endif +} +void norflaship_sleep(void) +{ +#ifndef NORFLASHIP_HAS_IDLE_IO_CTRL + norflash->REG_034 |= REG_034_SPI_IORES(1 << 2); +#endif +} +void norflaship_wakeup(void) +{ +#ifndef NORFLASHIP_HAS_IDLE_IO_CTRL + norflash->REG_034 &= ~REG_034_SPI_IORES(1 << 2); +#endif +} + +void norflaship_dec_index(uint32_t idx) +{ +#ifdef NORFLASHIP_HAS_SECURITY + norflash->REG_058 = SET_BITFIELD(norflash->REG_058, REG_058_IDX, idx); +#endif +} + +void norflaship_dec_saddr(uint32_t addr) +{ +#ifdef NORFLASHIP_HAS_SECURITY + norflash->REG_060 = ((addr & 0x000000ff) << 24) + |((addr & 0x0000ff00) << 8) + |((addr & 0x00ff0000) >> 8) + |((addr & 0xff000000) >> 24); +#endif +} + +void norflaship_dec_eaddr(uint32_t addr) +{ +#ifdef NORFLASHIP_HAS_SECURITY + norflash->REG_064 = ((addr & 0x000000ff) << 24) + |((addr & 0x0000ff00) << 8) + |((addr & 0x00ff0000) >> 8) + |((addr & 0xff000000) >> 24); +#endif +} + +void norflaship_dec_enable(void) +{ +#ifdef NORFLASHIP_HAS_SECURITY + norflash->REG_06C |= REG_06C_DEC_ENABLE; +#endif +} + +void norflaship_dec_disable(void) +{ +#ifdef NORFLASHIP_HAS_SECURITY + norflash->REG_06C &= ~REG_06C_DEC_ENABLE; +#endif +} + +void norflaship_man_wrap_width(uint32_t width) +{ +#ifdef NORFLASHIP_HAS_SECURITY + int bits = 0; + + if (width == 8) + bits = 0; + else if (width == 16) + bits = 1; + else if (width == 32) + bits = 2; + else if (width == 64) + bits = 3; + else + bits = 1; + norflash->REG_038 = SET_BITFIELD(norflash->REG_038, REG_038_MAN_WRAP_BITS, bits); +#endif +} + +void norflaship_man_wrap_enable(void) +{ +#ifdef NORFLASHIP_HAS_SECURITY + norflash->REG_038 |= REG_038_MAN_WRAP_ENABLE; +#endif +} + +void norflaship_man_wrap_disable(void) +{ +#ifdef NORFLASHIP_HAS_SECURITY + norflash->REG_038 &= ~REG_038_MAN_WRAP_ENABLE; +#endif +} + +void norflaship_auto_wrap_cmd(uint32_t cmd) +{ +#ifdef NORFLASHIP_HAS_SECURITY + norflash->REG_038 = SET_BITFIELD(norflash->REG_038, REG_038_AUTO_WRAP_CMD, cmd); +#endif +} + +void norflaship_man_mode_enable(void) +{ +#ifdef NORFLASHIP_HAS_SECURITY + norflash->REG_038 |= REG_038_WRAP_MODE_SEL; +#endif +} + +void norflaship_man_mode_disable(void) +{ +#ifdef NORFLASHIP_HAS_SECURITY + norflash->REG_038 &= ~REG_038_WRAP_MODE_SEL; +#endif +} + +int norflaship_config_remap_section(uint32_t id, uint32_t addr, uint32_t len, uint32_t new_addr) +{ +#ifdef NORFLASHIP_HAS_REMAP + __IO uint32_t *start, *end, *to; + + if (id >= 4) { + return 1; + } + if (len == 0) { + norflash->REG_0B0 &= ~(REG_0B0_ADDR0_REMAP_EN << id); + return 0; + } + if (addr & (REMAP_SECTOR_SIZE - 1)) { + return 2; + } + if (new_addr & (REMAP_SECTOR_SIZE - 1)) { + return 3; + } + if (len < REMAP_SECTOR_SIZE) { + return 4; + } + +#ifdef CHIP_BEST2300P + if (len & (len - 1)) { + return 5; + } + + uint32_t len_idx; + + len_idx = __CLZ(__RBIT(len)) - 9; + + norflash->REG_0A0 = (norflash->REG_0A0 & ~(REG_0A0_LEN_WIDTH0_MASK << (id * REG_0A0_LEN_WIDTH1_SHIFT))) | + (REG_0A0_LEN_WIDTH0(len_idx) << (id * REG_0A0_LEN_WIDTH1_SHIFT)); +#else + if (len & (REMAP_SECTOR_SIZE - 1)) { + return 5; + } +#endif + + start = &norflash->REG_070 + id; + end = &norflash->REG_080 + id; + to = &norflash->REG_090 + id; + + *start = addr; + *end = addr + len - 1; + *to = new_addr; + + norflash->REG_0B0 |= (REG_0B0_ADDR0_REMAP_EN << id); + + return 0; +#else + return -1; +#endif +} + +void norflaship_enable_remap(void) +{ +#ifdef NORFLASHIP_HAS_REMAP + norflash->REG_0B0 |= REG_0B0_GLB_REMAP_EN; +#endif +} + +void norflaship_disable_remap(void) +{ +#ifdef NORFLASHIP_HAS_REMAP + norflash->REG_0B0 &= ~REG_0B0_GLB_REMAP_EN; +#endif +} + +int norflaship_get_remap_status(void) +{ +#ifdef NORFLASHIP_HAS_REMAP + return (norflash->REG_0B0 & REG_0B0_GLB_REMAP_EN) ? true : false; +#else + return false; +#endif +} + +#if (CHIP_FLASH_CTRL_VER >= 3) +void norflaship_dummy_others(uint32_t v) +{ + norflash->REG_150 = REG_150_DUMMY_OTHERS(v); +} +#endif + +void norflaship_fetch_disable() +{ + norflash->REG_02C &= ~REG_02C_FETCH_EN; +} + +#endif + diff --git a/platform/hal/hal_overlay.c b/platform/hal/hal_overlay.c new file mode 100644 index 0000000..1d741f0 --- /dev/null +++ b/platform/hal/hal_overlay.c @@ -0,0 +1,359 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "hal_overlay.h" +#include "hal_sysfreq.h" +#include "hal_cache.h" +#include "hal_trace.h" +#include "cmsis.h" +#ifdef __ARMCC_VERSION +#include "link_sym_armclang.h" +#endif + +extern uint32_t __overlay_text_start__[]; +extern uint32_t __overlay_text_exec_start__[]; +extern uint32_t __load_start_overlay_text0[]; +extern uint32_t __load_stop_overlay_text0[]; +extern uint32_t __load_start_overlay_text1[]; +extern uint32_t __load_stop_overlay_text1[]; +extern uint32_t __load_start_overlay_text2[]; +extern uint32_t __load_stop_overlay_text2[]; +extern uint32_t __load_start_overlay_text3[]; +extern uint32_t __load_stop_overlay_text3[]; +extern uint32_t __load_start_overlay_text4[]; +extern uint32_t __load_stop_overlay_text4[]; +extern uint32_t __load_start_overlay_text5[]; +extern uint32_t __load_stop_overlay_text5[]; +extern uint32_t __load_start_overlay_text6[]; +extern uint32_t __load_stop_overlay_text6[]; +extern uint32_t __load_start_overlay_text7[]; +extern uint32_t __load_stop_overlay_text7[]; +extern uint32_t __overlay_text_exec_end__[]; + +extern uint32_t __overlay_data_start__[]; +extern uint32_t __load_start_overlay_data0[]; +extern uint32_t __load_stop_overlay_data0[]; +extern uint32_t __load_start_overlay_data1[]; +extern uint32_t __load_stop_overlay_data1[]; +extern uint32_t __load_start_overlay_data2[]; +extern uint32_t __load_stop_overlay_data2[]; +extern uint32_t __load_start_overlay_data3[]; +extern uint32_t __load_stop_overlay_data3[]; +extern uint32_t __load_start_overlay_data4[]; +extern uint32_t __load_stop_overlay_data4[]; +extern uint32_t __load_start_overlay_data5[]; +extern uint32_t __load_stop_overlay_data5[]; +extern uint32_t __load_start_overlay_data6[]; +extern uint32_t __load_stop_overlay_data6[]; +extern uint32_t __load_start_overlay_data7[]; +extern uint32_t __load_stop_overlay_data7[]; + +#ifndef NO_OVERLAY + +#define OVERLAY_IS_FREE 0 +#define OVERLAY_IS_USED 1 + +#define CHECK_OVERLAY_ID(id) \ + do {\ + if ((id < 0) || (id >= HAL_OVERLAY_ID_QTY)) { \ + ASSERT(0, "overlay id error %d", id); \ + } \ + } while (0) + + +static bool segment_state[HAL_OVERLAY_ID_QTY]; + +static enum HAL_OVERLAY_ID_T cur_overlay_id = HAL_OVERLAY_ID_QTY; + +static uint32_t * const text_load_start[HAL_OVERLAY_ID_QTY] = { + __load_start_overlay_text0, + __load_start_overlay_text1, + __load_start_overlay_text2, + __load_start_overlay_text3, + __load_start_overlay_text4, + __load_start_overlay_text5, + __load_start_overlay_text6, + __load_start_overlay_text7, +}; + +static uint32_t * const text_load_stop[HAL_OVERLAY_ID_QTY] = { + __load_stop_overlay_text0, + __load_stop_overlay_text1, + __load_stop_overlay_text2, + __load_stop_overlay_text3, + __load_stop_overlay_text4, + __load_stop_overlay_text5, + __load_stop_overlay_text6, + __load_stop_overlay_text7, +}; + +static uint32_t * const data_load_start[HAL_OVERLAY_ID_QTY] = { + __load_start_overlay_data0, + __load_start_overlay_data1, + __load_start_overlay_data2, + __load_start_overlay_data3, + __load_start_overlay_data4, + __load_start_overlay_data5, + __load_start_overlay_data6, + __load_start_overlay_data7, +}; + +static uint32_t * const data_load_stop[HAL_OVERLAY_ID_QTY] = { + __load_stop_overlay_data0, + __load_stop_overlay_data1, + __load_stop_overlay_data2, + __load_stop_overlay_data3, + __load_stop_overlay_data4, + __load_stop_overlay_data5, + __load_stop_overlay_data6, + __load_stop_overlay_data7, +}; + + +/*must called by lock get */ +static void invalid_overlay_cache(enum HAL_OVERLAY_ID_T id) +{ + // TODO: PSRAM is large enough and no need to overlay + return; + +#if defined(CHIP_HAS_PSRAM) && defined(PSRAM_ENABLE) + if (((uint32_t)__overlay_text_exec_start__ >= PSRAM_BASE && + (uint32_t)__overlay_text_exec_start__ < PSRAM_BASE + PSRAM_SIZE) || + ((uint32_t)__overlay_text_exec_start__ >= PSRAMX_BASE && + (uint32_t)__overlay_text_exec_start__ < PSRAMX_BASE + PSRAM_SIZE)) { + hal_cache_invalidate(HAL_CACHE_ID_I_CACHE, + (uint32_t)__overlay_text_exec_start__, + (uint32_t)text_load_stop[id] - (uint32_t)text_load_start[id]); + } + + if (((uint32_t)__overlay_data_start__ >= PSRAM_BASE && + (uint32_t)__overlay_data_start__ < PSRAM_BASE + PSRAM_SIZE) || + ((uint32_t)__overlay_data_start__ >= PSRAMX_BASE && + (uint32_t)__overlay_data_start__ < PSRAMX_BASE + PSRAM_SIZE)) { + hal_cache_invalidate(HAL_CACHE_ID_D_CACHE, + (uint32_t)__overlay_data_start__, + (uint32_t)data_load_stop[id] - (uint32_t)data_load_start[id]); + } +#endif +} + +enum HAL_OVERLAY_RET_T hal_overlay_load(enum HAL_OVERLAY_ID_T id) +{ + enum HAL_OVERLAY_RET_T ret; + + CHECK_OVERLAY_ID(id); + ret = HAL_OVERLAY_RET_OK; + + uint32_t lock; + uint32_t *dst, *src; + + if (hal_overlay_is_used()) { + ASSERT(0, "overlay %d is in use", id); + return HAL_OVERLAY_RET_IN_USE; + } + + hal_sysfreq_req(HAL_SYSFREQ_USER_OVERLAY, HAL_CMU_FREQ_52M); + lock = int_lock(); + + if (cur_overlay_id == HAL_OVERLAY_ID_QTY) { + cur_overlay_id = HAL_OVERLAY_ID_IN_CFG; + } else if (cur_overlay_id == HAL_OVERLAY_ID_IN_CFG) { + ret = HAL_OVERLAY_RET_IN_CFG; + } else { + ret = HAL_OVERLAY_RET_IN_USE; + } + + if (ret != HAL_OVERLAY_RET_OK) { + goto _exit; + } + + hal_overlay_acquire(id); + + for (dst = __overlay_text_start__, src = text_load_start[id]; + src < text_load_stop[id]; + dst++, src++) { + *dst = *src; + } + + for (dst = __overlay_data_start__, src = data_load_start[id]; + src < data_load_stop[id]; + dst++, src++) { + *dst = *src; + } + + cur_overlay_id = id; + segment_state[id] = OVERLAY_IS_USED; + +_exit: + int_unlock(lock); + hal_sysfreq_req(HAL_SYSFREQ_USER_OVERLAY, HAL_CMU_FREQ_32K); + + return ret; +} + +enum HAL_OVERLAY_RET_T hal_overlay_unload(enum HAL_OVERLAY_ID_T id) +{ + enum HAL_OVERLAY_RET_T ret; + + CHECK_OVERLAY_ID(id); + ret = HAL_OVERLAY_RET_OK; + + uint32_t lock; + + lock = int_lock(); + if (cur_overlay_id == id) { + cur_overlay_id = HAL_OVERLAY_ID_QTY; + } else if (cur_overlay_id == HAL_OVERLAY_ID_IN_CFG) { + ret = HAL_OVERLAY_RET_IN_CFG; + } else { + ret = HAL_OVERLAY_RET_IN_USE; + } + hal_overlay_release(id); + int_unlock(lock); + + return ret; +} + +/* + * get the overlay's text start address + */ +uint32_t hal_overlay_get_text_address(void) +{ + return (uint32_t)__overlay_text_start__; +} + +/* + * get the whole size of the overlay text + */ +uint32_t hal_overlay_get_text_all_size(void) +{ + uint32_t text_start, text_end; + + text_start = (uint32_t)__overlay_text_exec_start__; + text_end = (uint32_t)__overlay_text_exec_end__; + return text_end - text_start; +} + +/* + * get the segment size of one overlay text + */ +uint32_t hal_overlay_get_text_size(enum HAL_OVERLAY_ID_T id) +{ + CHECK_OVERLAY_ID(id); + + return (uint32_t)text_load_stop[id] - (uint32_t)text_load_start[id]; +} + +/* + ____________ overlay's text end + | | + | | + | free | + | | + |__________|free_addr ______________________segment text end + | | | | + | | | | + | | | | + | | | | + | | | | + |__________| text's start_addr |__________|segment text start_addr + * + */ + +/* + * Use the free space of one segement, this function + * return the free address of space + */ +uint32_t hal_overlay_get_text_free_addr(enum HAL_OVERLAY_ID_T id) +{ + uint32_t segment_text_sz; + uint32_t start_addr; + uint32_t free_addr; + + CHECK_OVERLAY_ID(id); + segment_text_sz = hal_overlay_get_text_size(id); + start_addr = hal_overlay_get_text_address(); + free_addr = start_addr + segment_text_sz; + + if (free_addr & 0x3 ) { + ASSERT(0, "free addr %p is not aligned to 4", (void *)free_addr); + } + return free_addr; +} + +/* + * get the free size for one overlay text + */ +uint32_t hal_overlay_get_text_free_size(enum HAL_OVERLAY_ID_T id) +{ + uint32_t all_text_sz; + uint32_t segment_text_sz; + + CHECK_OVERLAY_ID(id); + all_text_sz = hal_overlay_get_text_all_size(); + segment_text_sz = hal_overlay_get_text_size(id); + + return all_text_sz - segment_text_sz; +} + +/* + * acquire one overlay segment + */ +void hal_overlay_acquire(enum HAL_OVERLAY_ID_T id) +{ + uint32_t lock; + + CHECK_OVERLAY_ID(id); + segment_state[id] = OVERLAY_IS_USED; + + lock = int_lock(); + invalid_overlay_cache(id); + int_unlock(lock); + return; +} + +/* + * release one overlay segment + */ +void hal_overlay_release(enum HAL_OVERLAY_ID_T id) +{ + CHECK_OVERLAY_ID(id); + segment_state[id] = OVERLAY_IS_FREE; + return; +} + +/* + * check if any overlay segment is used + */ +bool hal_overlay_is_used(void) +{ + int i; + uint32_t lock; + + lock = int_lock(); + for (i = 0; i < HAL_OVERLAY_ID_QTY; i++) { + // if any segment is in use, the overlay is used; + if (segment_state[i] == OVERLAY_IS_USED ) { + int_unlock(lock); + return true; + } + } + int_unlock(lock); + return false; +} + +#endif + diff --git a/platform/hal/hal_overlay.h b/platform/hal/hal_overlay.h new file mode 100644 index 0000000..2ad555b --- /dev/null +++ b/platform/hal/hal_overlay.h @@ -0,0 +1,148 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_OVERLAY_H__ +#define __HAL_OVERLAY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define HAL_OVERLAY_TEXT0_LOC __attribute__((section(".overlay_text0"))) +#define HAL_OVERLAY_TEXT1_LOC __attribute__((section(".overlay_text1"))) +#define HAL_OVERLAY_TEXT2_LOC __attribute__((section(".overlay_text2"))) +#define HAL_OVERLAY_TEXT3_LOC __attribute__((section(".overlay_text3"))) +#define HAL_OVERLAY_TEXT4_LOC __attribute__((section(".overlay_text4"))) +#define HAL_OVERLAY_TEXT5_LOC __attribute__((section(".overlay_text5"))) +#define HAL_OVERLAY_TEXT6_LOC __attribute__((section(".overlay_text6"))) +#define HAL_OVERLAY_TEXT7_LOC __attribute__((section(".overlay_text7"))) + +#define HAL_OVERLAY_RODATA0_LOC __attribute__((section(".overlay_rodata0"))) +#define HAL_OVERLAY_RODATA1_LOC __attribute__((section(".overlay_rodata1"))) +#define HAL_OVERLAY_RODATA2_LOC __attribute__((section(".overlay_rodata2"))) +#define HAL_OVERLAY_RODATA3_LOC __attribute__((section(".overlay_rodata3"))) +#define HAL_OVERLAY_RODATA4_LOC __attribute__((section(".overlay_rodata4"))) +#define HAL_OVERLAY_RODATA5_LOC __attribute__((section(".overlay_rodata5"))) +#define HAL_OVERLAY_RODATA6_LOC __attribute__((section(".overlay_rodata6"))) +#define HAL_OVERLAY_RODATA7_LOC __attribute__((section(".overlay_rodata7"))) + +#define HAL_OVERLAY_DATA0_LOC __attribute__((section(".overlay_data0"))) +#define HAL_OVERLAY_DATA1_LOC __attribute__((section(".overlay_data1"))) +#define HAL_OVERLAY_DATA2_LOC __attribute__((section(".overlay_data2"))) +#define HAL_OVERLAY_DATA3_LOC __attribute__((section(".overlay_data3"))) +#define HAL_OVERLAY_DATA4_LOC __attribute__((section(".overlay_data4"))) +#define HAL_OVERLAY_DATA5_LOC __attribute__((section(".overlay_data5"))) +#define HAL_OVERLAY_DATA6_LOC __attribute__((section(".overlay_data6"))) +#define HAL_OVERLAY_DATA7_LOC __attribute__((section(".overlay_data7"))) + +#define INVALID_OVERLAY_ADDR 0xffffffff +enum HAL_OVERLAY_ID_T { + HAL_OVERLAY_ID_0, + HAL_OVERLAY_ID_1, + HAL_OVERLAY_ID_2, + HAL_OVERLAY_ID_3, + HAL_OVERLAY_ID_4, + HAL_OVERLAY_ID_5, + HAL_OVERLAY_ID_6, + HAL_OVERLAY_ID_7, + + HAL_OVERLAY_ID_QTY, + HAL_OVERLAY_ID_IN_CFG, +}; + +enum HAL_OVERLAY_RET_T { + HAL_OVERLAY_RET_OK, + HAL_OVERLAY_RET_BAD_ID, + HAL_OVERLAY_RET_IN_CFG, + HAL_OVERLAY_RET_IN_USE, +}; + +#ifndef NO_OVERLAY +enum HAL_OVERLAY_RET_T hal_overlay_load(enum HAL_OVERLAY_ID_T id); + +enum HAL_OVERLAY_RET_T hal_overlay_unload(enum HAL_OVERLAY_ID_T id); + +/* + * get the overlay's text start address + */ +uint32_t hal_overlay_get_text_address(void); + +/* + * get the whole size of the overlay text + */ +uint32_t hal_overlay_get_text_all_size(void); +/* + * get the segment size of one overlay text + */ +uint32_t hal_overlay_get_text_size(enum HAL_OVERLAY_ID_T id); +/* + * Use the free space of one segement, this function + * return the free address of space + */ +uint32_t hal_overlay_get_text_free_addr(enum HAL_OVERLAY_ID_T id); +/* + * get the free size for one overlay text + */ +uint32_t hal_overlay_get_text_free_size(enum HAL_OVERLAY_ID_T id); +/* + * acquire one overlay segment + */ +void hal_overlay_acquire(enum HAL_OVERLAY_ID_T id); +/* + * release one overlay segment + */ +void hal_overlay_release(enum HAL_OVERLAY_ID_T id); +/* + * check if any overlay segment is used + */ +bool hal_overlay_is_used(void); + +#else + +static inline enum HAL_OVERLAY_RET_T hal_overlay_load(enum HAL_OVERLAY_ID_T id) +{ return HAL_OVERLAY_RET_OK; } + +static inline enum HAL_OVERLAY_RET_T hal_overlay_unload(enum HAL_OVERLAY_ID_T id) +{ return HAL_OVERLAY_RET_OK; } + +static inline uint32_t hal_overlay_get_text_address(void) +{ return INVALID_OVERLAY_ADDR;} + +static inline uint32_t hal_overlay_get_text_all_size(void) +{ return 0;} + +static inline uint32_t hal_overlay_get_text_size(enum HAL_OVERLAY_ID_T id) +{ return 0;} + +static inline uint32_t hal_overlay_get_text_free_addr(enum HAL_OVERLAY_ID_T id) +{ return INVALID_OVERLAY_ADDR;} + +static inline uint32_t hal_overlay_get_text_free_size(enum HAL_OVERLAY_ID_T id) +{ return 0;} + +static inline void hal_overlay_acquire(enum HAL_OVERLAY_ID_T id) { return;} + +static inline void hal_overlay_release(enum HAL_OVERLAY_ID_T id) { return;} + +static inline bool hal_overlay_is_used(void) { return false;} + +#endif /*NO_OVERLAY*/ + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_OVERLAY_H__*/ + diff --git a/platform/hal/hal_phyif.c b/platform/hal/hal_phyif.c new file mode 100644 index 0000000..08d05bd --- /dev/null +++ b/platform/hal/hal_phyif.c @@ -0,0 +1,159 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_HAS_SPIPHY + +#include "plat_types.h" +#include "cmsis.h" +#include "hal_phyif.h" +#include "hal_spi.h" +#include "hal_location.h" + +#define PHY_READ_CMD(r) ((1 << 24) | (((r) & 0xFF) << 16)) +#define PHY_WRITE_CMD(r, v) ((((r) & 0xFF) << 16) | ((v) & 0xFFFF)) +#define PHY_READ_VAL(v) ((v) & 0xFFFF) + +#define SPIPHY_REG_CS(r) ((r) >> 12) +#define SPIPHY_REG_PAGE(r) (((r) >> 8) & 0xF) +#define SPIPHY_REG_OFFSET(r) ((r) & 0xFF) + +static const struct HAL_SPI_CFG_T spi_cfg = { + .clk_delay_half = false, + .clk_polarity = false, + .slave = false, + .dma_rx = false, + .dma_tx = false, + .rx_sep_line = true, + .cs = 0, + .rate = 6500000, + .tx_bits = 25, + .rx_bits = 25, + .rx_frame_bits = 0, +}; + +static uint8_t BOOT_BSS_LOC phyif_open_map; + +static uint8_t BOOT_BSS_LOC phy_cs; + +static int hal_phyif_rawread(unsigned short reg, unsigned short *val) +{ + int ret; + unsigned int data; + unsigned int cmd; + + data = 0; + cmd = PHY_READ_CMD(reg); + ret = hal_spiphy_recv(&cmd, &data, 4); + if (ret) { + return ret; + } + *val = PHY_READ_VAL(data); + return 0; +} + +static int hal_phyif_rawwrite(unsigned short reg, unsigned short val) +{ + int ret; + unsigned int cmd; + + cmd = PHY_WRITE_CMD(reg, val); + ret = hal_spiphy_send(&cmd, 4); + if (ret) { + return ret; + } + return 0; +} + +int hal_phyif_reg_read(unsigned short reg, unsigned short *val) +{ + uint32_t lock; + int ret; + uint8_t cs; + //uint8_t page; + + cs = SPIPHY_REG_CS(reg); + //page = SPIPHY_REG_PAGE(reg); + reg = SPIPHY_REG_OFFSET(reg); + + lock = int_lock(); + if (cs != phy_cs) { + hal_spiphy_activate_cs(cs); + phy_cs = cs; + } + ret = hal_phyif_rawread(reg, val); + int_unlock(lock); + + return ret; +} + +int hal_phyif_reg_write(unsigned short reg, unsigned short val) +{ + uint32_t lock; + int ret; + uint8_t cs; + //uint8_t page; + + cs = SPIPHY_REG_CS(reg); + //page = SPIPHY_REG_PAGE(reg); + reg = SPIPHY_REG_OFFSET(reg); + + lock = int_lock(); + if (cs != phy_cs) { + hal_spiphy_activate_cs(cs); + phy_cs = cs; + } + ret = hal_phyif_rawwrite(reg, val); + int_unlock(lock); + + return ret; +} + +int hal_phyif_open(uint32_t cs) +{ + int ret; + uint32_t lock; + + ret = 0; + + lock = int_lock(); + if (phyif_open_map == 0) { + ret = hal_spiphy_open(&spi_cfg); + } + if (ret == 0) { + phyif_open_map |= (1 << cs); + } + int_unlock(lock); + + return ret; +} + +int hal_phyif_close(uint32_t cs) +{ + int ret; + uint32_t lock; + + ret = 0; + + lock = int_lock(); + phyif_open_map &= ~(1 << cs); + if (phyif_open_map == 0) { + ret = hal_spiphy_close(spi_cfg.cs); + } + int_unlock(lock); + + return ret; +} + +#endif diff --git a/platform/hal/hal_phyif.h b/platform/hal/hal_phyif.h new file mode 100644 index 0000000..58a9140 --- /dev/null +++ b/platform/hal/hal_phyif.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_PHYIF_H__ +#define __HAL_PHYIF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +int hal_phyif_open(uint32_t cs); + +int hal_phyif_close(uint32_t cs); + +int hal_phyif_reg_write(unsigned short reg, unsigned short val); + +int hal_phyif_reg_read(unsigned short reg, unsigned short *val); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_psc.h b/platform/hal/hal_psc.h new file mode 100644 index 0000000..7475cec --- /dev/null +++ b/platform/hal/hal_psc.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_PSC_H__ +#define __HAL_PSC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" + +void hal_psc_init(void); + +void hal_psc_mcu_auto_power_down(void); + +void hal_psc_mcu_auto_power_up(void); + +void hal_psc_codec_enable(void); + +void hal_psc_codec_disable(void); + +void hal_psc_bt_enable(void); + +void hal_psc_bt_disable(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_psram.h b/platform/hal/hal_psram.h new file mode 100644 index 0000000..799222d --- /dev/null +++ b/platform/hal/hal_psram.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_PSRAM_H__ +#define __HAL_PSRAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +enum HAL_PSRAM_ID_T { + HAL_PSRAM_ID_0 = 0, + HAL_PSRAM_ID_NUM, +}; + +void hal_psram_sleep(void); +void hal_psram_wakeup(void); +void hal_psram_init(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_psram_v1.c b/platform/hal/hal_psram_v1.c new file mode 100644 index 0000000..92263f3 --- /dev/null +++ b/platform/hal/hal_psram_v1.c @@ -0,0 +1,533 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(CHIP_HAS_PSRAM) && (CHIP_PSRAM_CTRL_VER == 1) + +#include "plat_types.h" +#include "plat_addr_map.h" +#include "hal_cmu.h" +#include "hal_location.h" +#include "hal_psram.h" +#include "hal_psramip_v1.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_uart.h" +#include "pmu.h" +#define PSRAM_CALIB 0 + +#define HAL_PSRAM_YES 1 +#define HAL_PSRAM_NO 0 + +#define HAL_PSRAM_CMD_REG_READ 0x40 +#define HAL_PSRAM_CMD_REG_WRITE 0xc0 +#define HAL_PSRAM_CMD_RAM_READ 0x00 +#define HAL_PSRAM_CMD_RAM_WRITE 0x80 + +enum HAL_PSRAM_SPEED { + HAL_PSRAM_SPEED_13M = 13000000, + HAL_PSRAM_SPEED_26M = 26000000, + HAL_PSRAM_SPEED_50M = 50000000, + HAL_PSRAM_SPEED_52M = 52000000, + HAL_PSRAM_SPEED_78M = 78000000, + HAL_PSRAM_SPEED_104M = 104000000, + HAL_PSRAM_SPEED_130M = 130000000, + HAL_PSRAM_SPEED_156M = 156000000, + HAL_PSRAM_SPEED_182M = 182000000, + HAL_PSRAM_SPEED_208M = 208000000, + HAL_PSRAM_SPEED_234M = 234000000, +}; + +struct HAL_PSRAM_CONFIG_T { + uint32_t source_clk; + uint32_t speed; + uint32_t dqs_rd_sel; + uint32_t dqs_wr_sel; + + /* internal use : can be config if need to (useful for rom) */ + uint8_t override_config:1; + uint8_t div; +}; + +#define PSRAM_DEVICE_ID_LEN_MAX 8 +struct HAL_Psram_Context { + uint8_t device_id[PSRAM_DEVICE_ID_LEN_MAX]; + uint32_t total_size; + uint32_t read_size; + uint32_t write_size; +}; + +/* hal api */ +#if 0 +uint8_t hal_psram_open(enum HAL_PSRAM_ID_T id, struct HAL_PSRAM_CONFIG_T *cfg); +uint8_t hal_psram_close(enum HAL_PSRAM_ID_T id); +void hal_psram_reg_dump(enum HAL_PSRAM_ID_T id); +#endif +void hal_psram_suspend(enum HAL_PSRAM_ID_T id); +void hal_psram_resume(enum HAL_PSRAM_ID_T id); +void hal_psram_wakeup_init(void); + +struct HAL_Psram_Context psram_ctx[HAL_PSRAM_ID_NUM]; + +//static const char * const invalid_drv = "psram drv invalid"; + +#define DIGITAL_REG(a) *(volatile uint32_t *)(a) + +FLASH_TEXT_LOC static uint32_t _psram_get_reg_base(enum HAL_PSRAM_ID_T id) +{ + switch(id) { + case HAL_PSRAM_ID_0: + default: + return PSRAM_CTRL_BASE; + break; + } +} + +FLASH_TEXT_LOC static void _psram_exitsleep_onprocess_wait(enum HAL_PSRAM_ID_T id) +{ + uint32_t reg_base = 0; + reg_base = _psram_get_reg_base(id); + while (psramip_r_exit_sleep_onprocess(reg_base)); + + while (!psramip_r_sleep_wakeup_state(reg_base)); +} +FLASH_TEXT_LOC static void _psram_busy_wait(enum HAL_PSRAM_ID_T id) +{ + uint32_t reg_base = 0; + reg_base = _psram_get_reg_base(id); + while (psramip_r_busy(reg_base)); +} +#if 0 +static void _psram_div(enum HAL_PSRAM_ID_T id) +{ + /* TODO */ +} +/* hal api */ +uint8_t hal_psram_open(enum HAL_PSRAM_ID_T id, struct HAL_PSRAM_CONFIG_T *cfg) +{ + uint32_t div = 0, reg_base = 0; + //uint32_t psram_id = 0; + reg_base = _psram_get_reg_base(id); + + /* over write config */ + if (cfg->override_config) { + /* div */ + _psram_div(cfg->div); + } + else { + div = cfg->source_clk/cfg->speed; + _psram_div(div); + } + + /* 0. dqs config */ + psramip_w_dqs_rd_sel(reg_base, cfg->dqs_rd_sel); + psramip_w_dqs_wr_sel(reg_base, cfg->dqs_wr_sel); + + /* 1. high speed mode */ + if (cfg->speed >= HAL_PSRAM_SPEED_50M) + psramip_w_high_speed_enable(reg_base, HAL_PSRAM_YES); + else + psramip_w_high_speed_enable(reg_base, HAL_PSRAM_NO); + + _psram_busy_wait(id); + + /* 2. wait calib done or FIXME timeout */ + psramip_w_enable_and_trigger_calib(reg_base); + while (!psramip_r_calibst(reg_base)); + + psramip_w_wrap_mode_enable(reg_base, HAL_PSRAM_YES); + //psramip_w_wrap_mode_enable(reg_base, HAL_PSRAM_NO); + + //psramip_w_32bytewrap_mode(reg_base); + psramip_w_1kwrap_mode(reg_base); +#if 0 + /* psram device register read 1 or 2 or 3 */ + psramip_w_acc_size(reg_base, 1); + psramip_w_cmd_addr(reg_base, HAL_PSRAM_CMD_REG_READ, 2); + _psram_busy_wait(id); + psram_id = psramip_r_rx_fifo(reg_base); + + uart_printf("psram id 0x%x\n", psram_id); +#endif + + return 0; +} +uint8_t hal_psram_close(enum HAL_PSRAM_ID_T id) +{ + return 0; +} +void hal_psram_reg_dump(enum HAL_PSRAM_ID_T id) +{ + uint32_t reg_base = 0; + uint32_t psram_id = 0; + reg_base = _psram_get_reg_base(id); + + /* psram device register read 1 or 2 or 3 */ + psramip_w_acc_size(reg_base, 1); + psramip_w_cmd_addr(reg_base, HAL_PSRAM_CMD_REG_READ, 2); + _psram_busy_wait(id); + psram_id = psramip_r_rx_fifo(reg_base); + + uart_printf("psram id 0x%x\n", psram_id); +} + +#endif + +FLASH_TEXT_LOC uint8_t hal_psramip_read_reg(uint8_t reg) +{ + uint32_t mr; + psramip_clear_fifo(_psram_get_reg_base(HAL_PSRAM_ID_0)); + psramip_w_cmd_addr(0x40150000, HAL_PSRAM_CMD_REG_READ, (uint32_t)reg); + while((psramip_r_status(0x40150000)& PSRAM_STAT_BUSY)); + + mr = psramip_r_rx_fifo(0x40150000); + return mr&0xff; +} + +FLASH_TEXT_LOC void hal_psramip_write_reg(uint8_t reg, uint8_t val) +{ + enum HAL_PSRAM_ID_T id = HAL_PSRAM_ID_0; + psramip_clear_fifo(_psram_get_reg_base(HAL_PSRAM_ID_0)); + psramip_w_tx_fifo(0x40150000, (uint32_t)val); + psramip_w_cmd_addr(0x40150000, HAL_PSRAM_CMD_REG_WRITE, (uint32_t)reg); + _psram_busy_wait(id); +} + +FLASH_TEXT_LOC void hal_psram_suspend(enum HAL_PSRAM_ID_T id) +{ + uint32_t reg_base = 0; + reg_base = _psram_get_reg_base(id); + + psramip_w_acc_size(reg_base, 1); + hal_psramip_write_reg(0x6, 0xf0); +} + +FLASH_TEXT_LOC void hal_psram_resume(enum HAL_PSRAM_ID_T id) +{ + uint32_t reg_base = 0; + reg_base = _psram_get_reg_base(id); + + psramip_w_exit_sleep(reg_base); + + _psram_exitsleep_onprocess_wait(id); +} +//uint32_t test_ctrl =0; + +#ifdef CHIP_BEST2000 +void pmu_open_bbpll_for_psram(); +/*psram 120M use bbpll(div 4), 160M use bbpll(dir4), 100M use audio pll*/ +FLASH_TEXT_LOC void hal_psram_init(void) +{ +#ifndef PSRAM_LOW_SPEED + uint8_t mr = 0; +// enum HAL_PSRAM_ID_T id = HAL_PSRAM_ID_0; +#if defined(PSRAM_120M) || defined(PSRAM_160M) + pmu_open_bbpll_for_psram(); + hal_cmu_mem_set_freq(HAL_CMU_FREQ_208M); +#else /*PSRAM_160M*/ +#ifdef MCU_ULTRAHIGH_PERFORMANCE_MODE + hal_cmu_mem_set_freq(HAL_CMU_FREQ_104M);//104*2 +#else + hal_cmu_mem_set_freq(HAL_CMU_FREQ_208M); +#endif +#endif /*PSRAM_160M*/ + pmu_psram_freq_config(HAL_PSRAM_SPEED_208M); +#else + hal_cmu_mem_set_freq(HAL_CMU_FREQ_26M); + pmu_psram_freq_config(HAL_PSRAM_SPEED_26M); +#endif + + hal_cmu_clock_enable(HAL_CMU_MOD_O_PSRAM); + hal_cmu_clock_enable(HAL_CMU_MOD_H_PSRAM); + hal_cmu_reset_clear(HAL_CMU_MOD_O_PSRAM); + hal_cmu_reset_clear(HAL_CMU_MOD_H_PSRAM); + DIGITAL_REG(0x4008004c) |= 0x1<<21; + #if 0 //for debug + DIGITAL_REG(0x40150020) = 0x01; + DIGITAL_REG(0x400000ac) &= ~(0xc0000); + + DIGITAL_REG(0x400000ac) |= (0x80000); + + DIGITAL_REG(0x40087008) = 0xFFFFFFAF; + DIGITAL_REG(0x4008701c) = 0x2; +#endif + +#ifndef PSRAM_LOW_SPEED + DIGITAL_REG(0x40150040) = 0x44712133; + + DIGITAL_REG(0x40150044) = 0x200040b1; + DIGITAL_REG(0x40150044) |= (1<<1)|(1<<30); + + while (((DIGITAL_REG(0x40150044)) & (0x1<<30))); + //hal_sys_timer_delay(MS_TO_TICKS(10)); + DIGITAL_REG(0x40150044) &= ~(1<<0); + + while (!((DIGITAL_REG(0x40150044)) & (0x1<<0))); + //hal_sys_timer_delay(MS_TO_TICKS(10)); + + DIGITAL_REG(0x40000090) = 0x0001ffff; + while (!((DIGITAL_REG(0x40000090)) & (0x1<<20))); + //hal_sys_timer_delay(MS_TO_TICKS(10)); + + //lp delay + // DIGITAL_REG(0x4015001C)=0xffffffff;//c + DIGITAL_REG(0x4015001C)=((4*200)<<0)| + ((70*200)<<16)| + ((70*200/1000)<<10);// 208MHZ: tHS 10us, tXHS 100us, tXPHS 100ns + //ramp=1k select low speed + DIGITAL_REG(0x4015002C)=0x0000000d;//c + //tx/rx Phase + // #error "6666666666666666" + //DIGITAL_REG(0x40150024)= 0x55000713;//0x55000373;//223 + //DIGITAL_REG(0x40150024)= 0x55000373;//0x55000373;//223 + #if PSRAM_CALIB + + DIGITAL_REG(0x40150024)= 0x55000373;//0x55000373;//223 + #else +#if defined(PSRAM_200M) + DIGITAL_REG(0x40150024)= 0x55000653;//0x55000373;//223 +#elif defined(PSRAM_160M) + DIGITAL_REG(0x40150024)= 0x55000463;//;//0x55000373;//223 +#elif defined(PSRAM_120M) + DIGITAL_REG(0x40150024)= 0x55000113;//0x55000373;//223 +#else /*100M*/ + DIGITAL_REG(0x40150024)= 0x55000113;//0x55000373;//223 +#endif + #endif + while (!((DIGITAL_REG(0x40150024)) & (0x1<<3))); +#if 1 + //reset psram chip + psramip_write32(0xff, 0x40150000, 0x00); + while((psramip_r_status(0x40150000)& PSRAM_STAT_BUSY)); + //clear fifo + psramip_write32(0x03, 0x40150000, 0x18); + + while((psramip_r_status(0x40150000)& PSRAM_STAT_BUSY)); + hal_sys_timer_delay(US_TO_TICKS(10)); + // test_ctrl = 1; + // while (test_ctrl ==1); + + mr = hal_psramip_read_reg(0x0); + mr &= ~(0x3 << 6); // MR[7:6] must set 0 + mr &= ~(0x1 << 5); //MR0[5] = 0, latency type 0->variable + mr &= ~(0x7 << 2); + mr |= (0x6 << 2); //MR0[4:2] = '110 Latency =6 for 200M (variable latency) + mr &= ~(0x3 << 0); + mr |= (0x1 << 0); //driver strength '01 -> half + hal_psramip_write_reg(0x0, mr); + mr = hal_psramip_read_reg(0x0); + //TRACE(2,"PSRAM MODE REG 0 = 0x%x, status = 0x%x", mr, psramip_r_status(0x40150000)); + + mr = hal_psramip_read_reg(0x4); + mr &= ~(0x01 << 7); + mr |= (0x01 << 7); // MR[7] '1 -> write latency 1 for clk > 166MHz + //hal_psramip_write_reg(0x4, mr); + mr = hal_psramip_read_reg(0x4); + //TRACE(2,"PSRAM MODE REG 4 = 0x%x, status = 0x%x", mr, psramip_r_status(0x40150000)); + +#endif + hal_sys_timer_delay(US_TO_TICKS(10)); +#else /*PSRAM_LOW_SPEED*/ + // open psram phy power + DIGITAL_REG(0x4008004c) |= (1 << 21); + //init psram + //lp delay + DIGITAL_REG(0x4015001C)=0x3fff3cff;//c + //ramp=1k select low speed + DIGITAL_REG(0x4015002C)=0x0000000c; + //tx/rx Phase + DIGITAL_REG(0x40150024)=0x55000223; +#endif /*PSRAM_LOW_SPEED*/ + + psramip_w_acc_size(_psram_get_reg_base(HAL_PSRAM_ID_0), 1); +#ifdef PSRAM_200M + hal_cmu_mem_set_freq(HAL_CMU_FREQ_208M); +#endif +} +FLASH_TEXT_LOC void hal_psram_wakeup_init(void) +{ +#ifndef PSRAM_LOW_SPEED + DIGITAL_REG(0x40150040) = 0x44712133; + + DIGITAL_REG(0x40150044) = 0x200040b1; + DIGITAL_REG(0x40150044) |= (1<<1)|(1<<30); + + //TRACE(1,"0x40150044 = 0x%x \n",DIGITAL_REG(0x40150044)); + while (((DIGITAL_REG(0x40150044)) & (0x1<<30))); + //hal_sys_timer_delay(MS_TO_TICKS(10)); + DIGITAL_REG(0x40150044) &= ~(1<<0); + + //TRACE(1,"0x40150044 = 0x%x \n", DIGITAL_REG(0x40150044)); + while (!((DIGITAL_REG(0x40150044)) & (0x1<<0))); + //hal_sys_timer_delay(MS_TO_TICKS(10)); + + DIGITAL_REG(0x40000090) = 0x0001ffff; + //TRACE(1,"0x40000090 = 0x%x \n", DIGITAL_REG(0x40000090)); + while (!((DIGITAL_REG(0x40000090)) & (0x1<<20))); + //hal_sys_timer_delay(MS_TO_TICKS(10)); +#endif + + hal_psram_resume(HAL_PSRAM_ID_0); +} + +FLASH_TEXT_LOC void hal_psram_sleep(void) +{ +#ifndef PSRAM_LOW_SPEED + hal_psram_suspend(HAL_PSRAM_ID_0); + /* dll power off */ + DIGITAL_REG(0x40150044) &= ~(1 << 1); + /* phy power off */ + /* DIGITAL_REG(0x4008004c) &= ~(1 << 21) */ +#endif +} + +#else + +FLASH_TEXT_LOC void hal_psram_init(void) +{ +#ifndef PSRAM_LOW_SPEED + unsigned int mr = 0; + enum HAL_PSRAM_ID_T id = HAL_PSRAM_ID_0; +#endif + hal_cmu_mem_set_freq(HAL_CMU_FREQ_208M); + + hal_cmu_clock_enable(HAL_CMU_MOD_O_PSRAM); + hal_cmu_clock_enable(HAL_CMU_MOD_H_PSRAM); + hal_cmu_reset_clear(HAL_CMU_MOD_O_PSRAM); + hal_cmu_reset_clear(HAL_CMU_MOD_H_PSRAM); + + +#ifndef PSRAM_LOW_SPEED + DIGITAL_REG(0x4001f038) = 0x77783533; + + DIGITAL_REG(0x4001f03c) = 0x3ffffff4; + DIGITAL_REG(0x4001f03c) |= (1<<1)|(1<<30); + while (((DIGITAL_REG(0x4001f03c)) & (0x1<<30))); + hal_sys_timer_delay(MS_TO_TICKS(10)); + DIGITAL_REG(0x4001f03c) &= ~(1<<0); + while (!((DIGITAL_REG(0x4001f03c)) & (0x1<<0))); + hal_sys_timer_delay(MS_TO_TICKS(10)); + + DIGITAL_REG(0x40000090) = 0x0001ffff; + while (!((DIGITAL_REG(0x40000090)) & (0x1<<20))); + hal_sys_timer_delay(MS_TO_TICKS(10)); + + //lp delay + DIGITAL_REG(0x4015001C)=0xffffffff;//c + //ramp=1k select low speed + DIGITAL_REG(0x4015002C)=0x0000000d;//c + //tx/rx Phase + DIGITAL_REG(0x40150024)=0x55000563;//223 + while (!((DIGITAL_REG(0x40150024)) & (0x1<<3))); +#if 1 + //reset psram chip + psramip_write32(0xff, 0x40150000, 0x00); + while((psramip_r_status(0x40150000)& PSRAM_STAT_BUSY)); + //clear fifo + psramip_write32(0x03, 0x40150000, 0x18); + while((psramip_r_status(0x40150000)& PSRAM_STAT_BUSY)); + hal_sys_timer_delay(MS_TO_TICKS(10)); + + //read MR0 + psramip_w_cmd_addr(0x40150000, HAL_PSRAM_CMD_REG_READ, 0); + while((psramip_r_status(0x40150000)& PSRAM_STAT_BUSY)); + //need read twice + mr = psramip_r_rx_fifo(0x40150000); + mr = psramip_r_rx_fifo(0x40150000); + // hal_uart_printf("count=0x%x mr0 = 0x%x \n", psramip_r_status(0x40150000), mr); + + mr &= 0xff; + mr &= ~(0x03 << 6); // MR[7:6] must set 0 + // driver strength 00:1/16 01:1/2 10:1/4 11:1/8 MR0[1:0] + mr &= ~0x03; + mr |= 0x01; + //for >> 200M MR0[4:2] + mr &= ~(0x07 << 2); + mr |= (0x06 << 2); + psramip_w_tx_fifo(0x40150000, mr); + psramip_w_cmd_addr(0x40150000, HAL_PSRAM_CMD_REG_WRITE, 0); + _psram_busy_wait(id); + + //read MR0 again + psramip_w_cmd_addr(0x40150000, HAL_PSRAM_CMD_REG_READ, 0); + while((psramip_r_status(0x40150000)& PSRAM_STAT_BUSY)); + mr = psramip_r_rx_fifo(0x40150000); + mr = psramip_r_rx_fifo(0x40150000); + // hal_uart_printf("count=0x%x mr0 = 0x%x \n", psramip_r_status(0x40150000), mr); + //read MR4 + psramip_w_cmd_addr(0x40150000, HAL_PSRAM_CMD_REG_READ, 4); + _psram_busy_wait(id); + mr = psramip_r_rx_fifo(0x40150000); + mr = psramip_r_rx_fifo(0x40150000); + // hal_uart_printf("mr4 = 0x%x\n", mr); + + _psram_busy_wait(id); +#endif + hal_sys_timer_delay(MS_TO_TICKS(10)); +#else + // open psram phy power + DIGITAL_REG(0x4001f02c) |= (1 << 16); + //init psram + //lp delay + DIGITAL_REG(0x4015001C)=0x3fff3cff;//c + //ramp=1k select low speed + DIGITAL_REG(0x4015002C)=0x0000000c; + //tx/rx Phase + DIGITAL_REG(0x40150024)=0x55000223; +#endif +} + +FLASH_TEXT_LOC void hal_psram_wakeup_init(void) +{ +#ifndef PSRAM_LOW_SPEED + // dll + DIGITAL_REG(0x4001f038) = 0x77783533; + + DIGITAL_REG(0x4001f03c) = 0x3ffffff4; + DIGITAL_REG(0x4001f03c) |= (1<<1)|(1<<30); + while (((DIGITAL_REG(0x4001f03c)) & (0x1<<30))); + hal_sys_timer_delay(MS_TO_TICKS(10)); + DIGITAL_REG(0x4001f03c) &= ~(1<<0); + while (!((DIGITAL_REG(0x4001f03c)) & (0x1<<0))); + hal_sys_timer_delay(MS_TO_TICKS(10)); + + DIGITAL_REG(0x40000090) = 0x0001ffff; + while (!((DIGITAL_REG(0x40000090)) & (0x1<<20))); + hal_sys_timer_delay(MS_TO_TICKS(10)); +#endif + + hal_psram_resume(HAL_PSRAM_ID_0); +} + +FLASH_TEXT_LOC void hal_psram_sleep(void) +{ +#ifndef PSRAM_LOW_SPEED + hal_psram_suspend(HAL_PSRAM_ID_0); + /* dll power off */ + DIGITAL_REG(0x4001f03c) &= ~(1 << 1); + /* phy power off */ + /* DIGITAL_REG(0x4001f02c) &= ~(1 << 16) */ +#endif +} + +#endif + +FLASH_TEXT_LOC void hal_psram_wakeup(void) +{ +#ifndef PSRAM_LOW_SPEED + hal_psram_wakeup_init(); +#endif +} + +#endif diff --git a/platform/hal/hal_psram_v2.c b/platform/hal/hal_psram_v2.c new file mode 100644 index 0000000..76a39ba --- /dev/null +++ b/platform/hal/hal_psram_v2.c @@ -0,0 +1,815 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(CHIP_HAS_PSRAM) && (CHIP_PSRAM_CTRL_VER >= 2) + +#include "plat_types.h" +#include "plat_addr_map.h" +#include "hal_location.h" +#include "hal_psram.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_cache.h" +#include "pmu.h" +#include "reg_psram_mc_v2.h" +#include "reg_psram_phy_v2.h" +#include "string.h" + +#define PSRAM_RESET +//#define PSRAM_DUAL_8BIT +//#define PSRAM_WRAP_ENABLE + +//#define PSRAM_DEBUG +#ifdef PSRAM_DEBUG +#define PSRAM_TRACE TRACE_IMM +#else +#define PSRAM_TRACE(...) +#endif + +#ifdef PSRAM_DEBUG +#define PSRAM_TRACENOCRLF_NOTS REL_TRACE_NOCRLF_NOTS +#else +#define PSRAM_TRACENOCRLF_NOTS(...) +#endif + +#define TX_FIFO_DEPTH 8 +#define RX_FIFO_DEPTH 8 + +// MR0 +#define MR0_DRIVE_STR_SHIFT 0 +#define MR0_DRIVE_STR_MASK (0x3 << MR0_DRIVE_STR_SHIFT) +#define MR0_DRIVE_STR(n) BITFIELD_VAL(MR0_DRIVE_STR, n) +#define MR0_READ_LATENCY_SHIFT 2 +#define MR0_READ_LATENCY_MASK (0x7 << MR0_READ_LATENCY_SHIFT) +#define MR0_READ_LATENCY(n) BITFIELD_VAL(MR0_READ_LATENCY, n) +#define MR0_LT (1 << 5) +#define MR0_FIXED_00_SHIFT 6 +#define MR0_FIXED_00_MASK (0x3 << MR0_FIXED_00_SHIFT) +#define MR0_FIXED_00(n) BITFIELD_VAL(MR0_FIXED_00, n) + +// MR1 +#define MR1_VENDOR_ID_SHIFT 0 +#define MR1_VENDOR_ID_MASK (0x1F << MR1_VENDOR_ID_SHIFT) +#define MR1_VENDOR_ID(n) BITFIELD_VAL(MR1_VENDOR_ID, n) +#define MR1_DENSITY_SHIFT 5 +#define MR1_DENSITY_MASK (0x3 << MR1_DENSITY_SHIFT) +#define MR1_DENSITY(n) BITFIELD_VAL(MR1_DENSITY, n) +#define MR1_ULP (1 << 7) + +// MR2 +#define MR2_VENDOR_ID_SHIFT 0 +#define MR2_VENDOR_ID_MASK (0x7 << MR2_VENDOR_ID_SHIFT) +#define MR2_VENDOR_ID(n) BITFIELD_VAL(MR2_VENDOR_ID, n) +#define MR2_DEV_ID_SHIFT 3 +#define MR2_DEV_ID_MASK (0x3 << MR2_DEV_ID_SHIFT) +#define MR2_DEV_ID(n) BITFIELD_VAL(MR2_DEV_ID, n) +#define MR2_RSVD (1 << 5) +#define MR2_FIXED_1 (1 << 6) +#define MR2_GB (1 << 7) + +// MR4 +#define MR4_PASR_SHIFT 0 +#define MR4_PASR_MASK (0x7 << MR4_PASR_SHIFT) +#define MR4_PASR(n) BITFIELD_VAL(MR4_PASR, n) +#define MR4_RF (1 << 3) +#define MR4_FIXED_0 (1 << 4) +#define MR4_WRITE_LATENCY_SHIFT 5 +#define MR4_WRITE_LATENCY_MASK (0x7 << MR4_WRITE_LATENCY_SHIFT) +#define MR4_WRITE_LATENCY(n) BITFIELD_VAL(MR4_WRITE_LATENCY, n) + +// MR6 +#define MR6_RSVD_SHIFT 0 +#define MR6_RSVD_MASK (0xF << MR6_RSVD_SHIFT) +#define MR6_RSVD(n) BITFIELD_VAL(MR6_RSVD, n) +#define MR6_HALF_SLEEP_SHIFT 4 +#define MR6_HALF_SLEEP_MASK (0xF << MR6_HALF_SLEEP_SHIFT) +#define MR6_HALF_SLEEP(n) BITFIELD_VAL(MR6_HALF_SLEEP, n) + +// MR8 +#define MR8_BL_SHIFT 0 +#define MR8_BL_MASK (0x3 << MR8_BL_SHIFT) +#define MR8_BL(n) BITFIELD_VAL(MR8_BL, n) +#define MR8_BT (1 << 2) +#define MR8_FIXED_0 (1 << 3) +#define MR8_RSVD_SHIFT 4 +#define MR8_RSVD_MASK (0x7 << MR8_RSVD_SHIFT) +#define MR8_RSVD(n) BITFIELD_VAL(MR8_RSVD, n) +#define MR8_FIXED_00 (1 << 7) + +enum PSRAM_CMD_T { + PSRAM_CMD_SYNC_READ = 0x00, + PSRAM_CMD_SYNC_WRITE = 0x80, + PSRAM_CMD_4BYTE_READ = 0x3F, + PSRAM_CMD_4BYTE_WRITE = 0xBF, + PSRAM_CMD_REG_READ = 0x40, + PSRAM_CMD_REG_WRITE = 0xC0, + PSRAM_CMD_GLOBAL_RESET = 0xFF, +}; + +enum CP_FSM_STATE_T { + CP_FSM_STATE_SELF_REFRESH = 1, + CP_FSM_STATE_PD = 2, + CP_FSM_STATE_READY = 4, +}; + +enum MEMIF_CMD_T { + MEMIF_NO_CMD = 0x00, + MEMIF_WRITE = 0x01, + MEMIF_READ = 0x02, + MEMIF_MRS = 0x05, + MEMIF_MRR = 0x06, + MEMIF_REF = 0x08, + MEMIF_SREF = 0x09, + MEMIF_PD = 0x10, + MEMIF_NOP = 0x20, + MEMIF_RST = 0xFF, + MEMIF_ZQCL = 0x85, + MEMIF_ZQCS = 0x45, + MEMIF_ZQCRST = 0x25, + MEMIF_START_CLOCK = 0x40, + MEMIF_STOP_CLOCK = 0x80, + MEMIF_NEW_CMD = 0x7F, +}; + +static struct PSRAM_MC_T * const psram_mc = (struct PSRAM_MC_T *)PSRAM_CTRL_BASE; +static struct PSRAM_PHY_T * const psram_phy = (struct PSRAM_PHY_T *)(PSRAM_CTRL_BASE + 0x8000); + +static const uint32_t psram_cfg_clk = 48*1000*1000; + +#if (PSRAM_SPEED != 0) +static const uint32_t psram_run_clk = PSRAM_SPEED*1000*1000; +#else +#error "invalid PSRAMUHS_SPEED" +#endif + +static void psram_chip_timing_config(uint32_t clk, bool psram_first); + +int hal_psramip_mc_busy(void) +{ + return !!(psram_mc->REG_404 & PSRAM_ULP_MC_BUSY); +} + +static int hal_psramip_wb_busy(void) +{ + return !!(psram_mc->REG_404 & PSRAM_ULP_MC_WB_FILL_LEVEL_MASK); +} + +int hal_psramip_mc_in_sleep(void) +{ + return GET_BITFIELD(psram_mc->REG_404, PSRAM_ULP_MC_CP_FSM_STATE) == CP_FSM_STATE_PD; +} + +int hal_psramip_rx_fifo_empty(void) +{ + return !!(psram_mc->REG_404 & PSRAM_ULP_MC_MGR_RXFIFO_R_EMPTY); +} + +int hal_psramip_tx_fifo_full(void) +{ + return !!(psram_mc->REG_404 & PSRAM_ULP_MC_MGR_TXFIFO_W_FULL); +} + +uint32_t hal_psramip_get_rx_fifo_len(void) +{ + return GET_BITFIELD(psram_mc->REG_404, PSRAM_ULP_MC_MGR_RXFIFO_FULL_CNT); +} + +uint32_t hal_psramip_get_tx_fifo_free_len(void) +{ + return GET_BITFIELD(psram_mc->REG_404, PSRAM_ULP_MC_MGR_TXFIFO_EMPTY_CNT); +} + +void hal_psramip_mc_busy_wait(void) +{ + while (hal_psramip_mc_busy()); +} + +void hal_psramip_wb_busy_wait(void) +{ + while (hal_psramip_wb_busy()); +} + +void hal_psramip_flush_tx_fifo(void) +{ + hal_psramip_mc_busy_wait(); + psram_mc->REG_01C = PSRAM_ULP_MC_MGR_TX_FIFO_CLR; + hal_psramip_mc_busy_wait(); +} + +void hal_psramip_flush_rx_fifo(void) +{ + hal_psramip_mc_busy_wait(); + psram_mc->REG_01C = PSRAM_ULP_MC_MGR_RX_FIFO_CLR; + hal_psramip_mc_busy_wait(); +} + +void hal_psramip_flush_all_fifo(void) +{ + hal_psramip_mc_busy_wait(); + psram_mc->REG_01C = PSRAM_ULP_MC_MGR_TX_FIFO_CLR | PSRAM_ULP_MC_MGR_RX_FIFO_CLR; + hal_psramip_mc_busy_wait(); +} + +void hal_psramip_xfer_addr_len(uint32_t addr, uint32_t len) +{ + psram_mc->REG_008 = addr; + psram_mc->REG_00C = len; +} + +void hal_psramip_write_fifo(uint32_t *data, uint32_t len) +{ + for (int i = 0; i < len; i++) { + psram_mc->REG_014 = *data++; + } +} + +void hal_psramip_read_fifo(uint32_t *data, uint32_t len) +{ + for (int i = 0; i < len; i++) { + *data++ = psram_mc->REG_018; + } +} + +void hal_psramip_set_reg_data_mask(void) +{ +#ifdef PSRAM_DUAL_8BIT + psram_mc->REG_010 = 0xFC; +#else + psram_mc->REG_010 = 0xFE; +#endif +} + +void hal_psramip_set_mem_data_mask(void) +{ + psram_mc->REG_010 = 0; +} + +void hal_psramip_set_cmd(enum MEMIF_CMD_T cmd) +{ + psram_mc->REG_004 = cmd; +} + +POSSIBLY_UNUSED void psram_read_reg(uint32_t reg, uint32_t *val) +{ + hal_psramip_flush_all_fifo(); + hal_psramip_xfer_addr_len(reg, 1); + hal_psramip_set_cmd(MEMIF_MRR); + while (hal_psramip_rx_fifo_empty()); + hal_psramip_read_fifo(val, 1); +} + +static void psram_send_cmd_reg(enum MEMIF_CMD_T cmd, uint32_t reg, uint32_t val) +{ +#ifdef PSRAM_DUAL_8BIT + val &= 0xFF; + val |= (val << 8); +#endif + hal_psramip_flush_all_fifo(); + //hal_psramip_set_reg_data_mask(); + hal_psramip_write_fifo(&val, 1); + hal_psramip_xfer_addr_len(reg, 1); + hal_psramip_set_cmd(cmd); + while (hal_psramip_get_tx_fifo_free_len() != TX_FIFO_DEPTH); + hal_psramip_mc_busy_wait(); + //hal_psramip_set_mem_data_mask(); +} + +static void psram_write_reg(uint32_t reg, uint32_t val) +{ + psram_send_cmd_reg(MEMIF_MRS, reg, val); +} + +static void psram_single_cmd(enum MEMIF_CMD_T cmd) +{ + hal_psramip_flush_all_fifo(); + hal_psramip_set_cmd(cmd); + hal_psramip_mc_busy_wait(); +} + +static POSSIBLY_UNUSED void psram_reset(void) +{ + psram_single_cmd(MEMIF_RST); +} + +static void psram_set_timing(uint32_t clk) +{ + uint32_t reg; + uint32_t val; + +#if PSRAMSIZE == 0x800000 + reg = 8; +#ifdef PSRAM_WRAP_ENABLE + // Wrap 32 + val = MR8_BL(1); +#else + // Wrap 1k + val = MR8_BL(0x3); +#endif + psram_write_reg(reg, val); +#endif + reg = 0; + if (clk <= 66000000) { + val = 2; + } else if (clk <= 109000000) { + val = 3; + } else if (clk <= 133000000) { + val = 4; + } else if (clk <= 166000000) { + val = 5; + } else { + val = 6; + } + // Latency type: Variable + val = MR0_DRIVE_STR(3) | MR0_READ_LATENCY(val); + psram_write_reg(reg, val); + + reg = 4; + if (clk <= 166000000) { + val = 0; + } else { + val = 4; + } + //Fast Refresh, + val = MR4_PASR(0) | MR4_WRITE_LATENCY(val); + psram_write_reg(reg, val); +} + +static void hal_psram_phy_dll_config(uint32_t clk) +{ + uint32_t phy_clk; + uint32_t range; + uint32_t val; + + val = psram_phy->REG_050; + val &= ~PSRAM_ULP_PHY_REG_DLL_RESETB | PSRAM_ULP_PHY_REG_DLL_CK_RDY; + psram_phy->REG_050 = val; + phy_clk = clk; + if (phy_clk <= 100000000 / 2) { + range = 3; + } else if (phy_clk <= 150000000 / 2) { + range = 2; + } else if (phy_clk <= 300000000 / 2) { + range = 1; + } else { + range = 0; + } + val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_DLL_RANGE, range); + psram_phy->REG_050 = val; + val |= PSRAM_ULP_PHY_REG_DLL_RESETB | PSRAM_ULP_PHY_REG_DLL_CK_RDY; + psram_phy->REG_050 = val; +} + +static void hal_psram_phy_init(uint32_t clk) +{ + uint32_t val; + val = psram_phy->REG_048; + val |= PSRAM_ULP_PHY_REG_LDO_PU | PSRAM_ULP_PHY_REG_LDO_PRECHARGE; + psram_phy->REG_048 = val; + hal_sys_timer_delay_us(10); + + val &= ~PSRAM_ULP_PHY_REG_LDO_PRECHARGE; + val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_IEN1, 0xc); + val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_IEN2, 0x5); + val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_LDO_VTUNE, 0x0); + psram_phy->REG_048 = val; + + val = psram_phy->REG_04C; + val |= PSRAM_ULP_PHY_REG_PSRAM_PU; + val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_PSRAM_SWRC, 0x3); + val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_PSRAM_TXDRV, 0x3); + psram_phy->REG_04C = val; + + val = psram_phy->REG_050; + val |= PSRAM_ULP_PHY_REG_DLL_PU; + //val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_DLL_SWRC, 0x3); + psram_phy->REG_050 = val; + hal_sys_timer_delay_us(2); + + val |= PSRAM_ULP_PHY_REG_DLL_RESETB; + psram_phy->REG_050 = val; + hal_sys_timer_delay_us(20); + + hal_psram_phy_dll_config(clk); +} + +static void hal_psram_mc_set_timing(uint32_t clk) +{ + uint32_t val; + + if (clk <= 166000000) { + val = PSRAM_ULP_MC_WRITE_LATENCY(0); + } else { + val = PSRAM_ULP_MC_WRITE_LATENCY(2); + } + psram_mc->REG_028 = val; +#if (CHIP_PSRAM_CTRL_VER == 2) + if (clk <= 66000000) { + val = PSRAM_ULP_MC_READ_LATENCY(2); + } else if (clk <= 109000000) { + val = PSRAM_ULP_MC_READ_LATENCY(3); + } else if (clk <= 133000000) { + val = PSRAM_ULP_MC_READ_LATENCY(4); + } else if (clk <= 166000000) { + val = PSRAM_ULP_MC_READ_LATENCY(5); + } else { + val = PSRAM_ULP_MC_READ_LATENCY(6); + } + psram_mc->REG_02C = val; +#else + // Min latency: 2 cycles + psram_mc->REG_02C = PSRAM_ULP_MC_READ_LATENCY(2); +#endif + // tRC >= 55 ns + val = (clk / 1000000 * 55 + (1000 - 1)) / 1000; + psram_mc->REG_050 = PSRAM_ULP_MC_T_RC(val); + val = 2; + psram_mc->REG_058 = PSRAM_ULP_MC_T_CPHR(val); + psram_mc->REG_068 = PSRAM_ULP_MC_T_MRR(val); + val = 6; + psram_mc->REG_060 = PSRAM_ULP_MC_T_CPHW(val); +#ifdef CHIP_BEST2001 + val += 1; +#endif + psram_mc->REG_06C = PSRAM_ULP_MC_T_MRS(val); + // tCEM <= 2.5 us + val = clk / 1000000 * 25 / 10; + psram_mc->REG_070 = PSRAM_ULP_MC_T_CEM(val); + // tRST >= 2 us + val = clk / 1000000 * 2 + 1; + psram_mc->REG_074 = PSRAM_ULP_MC_T_RST(val); + // tHS >= 4 us + val = clk / 1000000 * 4 + 1; + psram_mc->REG_080 = PSRAM_ULP_MC_T_HS(val); + // tXPHS in [60 ns, 4 us] + val = (clk / 1000000 * 60 + (1000 - 1)) / 1000; + psram_mc->REG_084 = PSRAM_ULP_MC_T_XPHS(val); + // tXHS >= 70 us + val = clk / 1000000 * 70 + 1; + psram_mc->REG_088 = PSRAM_ULP_MC_T_XHS(val); + psram_mc->REG_09C = PSRAM_ULP_MC_WR_DMY_CYC(1); + // NOP dummy cycles, same as tXPHS in [60 ns, 4 us] + val = (clk / 1000000 * 60 + (1000 - 1)) / 1000; + psram_mc->REG_0A0 = PSRAM_ULP_MC_STOP_CLK_IN_NOP | PSRAM_ULP_MC_NOP_DMY_CYC(val); + psram_mc->REG_0A4 = PSRAM_ULP_MC_QUEUE_IDLE_CYCLE(5000); +} + +static void hal_psram_init_calib(void) +{ + uint32_t delay; + + while ((psram_phy->REG_058 & PSRAM_ULP_PHY_DLL_LOCK) == 0); + + delay = GET_BITFIELD(psram_phy->REG_058, PSRAM_ULP_PHY_DLL_DLY_IN); + //ASSERT(delay < (PSRAM_ULP_PHY_DLL_DLY_IN_MASK >> PSRAM_ULP_PHY_DLL_DLY_IN_SHIFT), + // "%s: Bad DLL_DLY_IN=0x%X reg=0x%08X", __func__, delay, psram_phy->REG_058); + + delay /= 2; + psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(delay) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(delay) | + PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(delay) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(delay); +} + +static void hal_psram_mc_init(uint32_t clk) +{ +#ifdef PSRAM_DUAL_8BIT + psram_mc->REG_000 = PSRAM_ULP_MC_CHIP_BIT; +#else + psram_mc->REG_000 = 0; +#endif + psram_mc->REG_020 = 0; + psram_mc->REG_024 = +#ifndef CHIP_BEST2001 + PSRAM_ULP_MC_ENTRY_SLEEP_IDLE | +#endif + PSRAM_ULP_MC_AUTOWAKEUP_EN | + PSRAM_ULP_MC_PD_MR(6) | PSRAM_ULP_MC_PD_CMD(0xF0); +#ifdef PSRAM_WRAP_ENABLE + // Burst len: 32 bytes, page: 1K + psram_mc->REG_034 = PSRAM_ULP_MC_BURST_LENGTH(1) | PSRAM_ULP_MC_PAGE_BOUNDARY(0); +#else + // 8MB psram + // Burst len: 1K, page: 1K + psram_mc->REG_034 = PSRAM_ULP_MC_BURST_LENGTH(4) | PSRAM_ULP_MC_PAGE_BOUNDARY(0); +#endif + // AHB bus width: 32 bits + psram_mc->REG_038 = 0; + // Write buffer level with high priority: 0~7 + psram_mc->REG_03C = PSRAM_ULP_MC_HIGH_PRI_LEVEL(4); +#ifdef PSRAM_WRAP_ENABLE + psram_mc->REG_040 = PSRAM_ULP_MC_CP_WRAP_EN; +#else + psram_mc->REG_040 = PSRAM_ULP_MC_WRAP_CRT_RET_EN; +#endif + psram_mc->REG_044 = 0; + psram_mc->REG_048 = 0; + + hal_psramip_set_reg_data_mask(); + + hal_psram_mc_set_timing(clk); + + psram_mc->REG_400 = PSRAM_ULP_MC_INIT_COMPLETE; + + hal_psram_init_calib(); +} + +void hal_psram_sleep(void) +{ + hal_psramip_mc_busy_wait(); + if (!hal_psramip_mc_in_sleep()) { +#ifndef CHIP_BEST2001 + psram_mc->REG_024 &= ~PSRAM_ULP_MC_ENTRY_SLEEP_IDLE; +#endif + hal_psramip_mc_busy_wait(); + hal_psramip_set_cmd(MEMIF_PD); + hal_psramip_mc_busy_wait(); + } +} + +void hal_psram_wakeup(void) +{ + hal_psramip_mc_busy_wait(); +#ifndef CHIP_BEST2001 + psram_mc->REG_024 |= PSRAM_ULP_MC_ENTRY_SLEEP_IDLE; +#endif +} + +static void psram_chip_timing_config(uint32_t clk, bool update_psram_first) +{ + enum HAL_CMU_FREQ_T freq; + + if (clk <= 52000000) { + freq = HAL_CMU_FREQ_104M; + } else if (clk <= 104000000) { + freq = HAL_CMU_FREQ_208M; + } else { +#ifdef HAL_CMU_FREQ_T + freq = HAL_CMU_FREQ_390M; +#else + freq = HAL_CMU_FREQ_208M; +#endif + } + + if (update_psram_first) { + psram_set_timing(clk); + } + + hal_cmu_mem_set_freq(freq); + hal_sys_timer_delay_us(3); + hal_psram_phy_dll_config(clk); + hal_psram_init_calib(); + hal_psram_mc_set_timing(clk); + if (!update_psram_first) { + psram_set_timing(clk); + } +} + +static bool psramphy_check_write_valid() +{ + int i; + volatile uint32_t *psram_base = (volatile uint32_t *)PSRAM_NC_BASE; + for (i=0; i<0x8; ++i) { + *(psram_base+i) = 0xffffffff; + } + for (i=0; i<0x8; ++i) { + *(psram_base+i) = ((i << 0) | (i << 8) | (i << 16) | (i << 24)); + } + hal_psramip_wb_busy_wait(); + hal_psramip_mc_busy_wait(); + for (i=0; i<0x8; ++i) { + uint32_t check_val = *(psram_base+i); + if (check_val != ((i << 0) | (i << 8) | (i << 16) | (i << 24))) { + //PSRAM_TRACE(2,"write fail, %p = 0x%x", (uint32_t)(psram_base+i), check_val); + return false; + } + } + return true; +} + +static void hal_psram_calib_range(uint32_t range) +{ + uint32_t val; + uint32_t delay; + uint8_t tx_dqs, rx_dqs; + uint8_t inc_delay, volume; + uint8_t cali_valid[0x20][0x20]; + uint8_t cali_value[0x20][0x20]; + + ASSERT(range <= (PSRAM_ULP_PHY_DLL_DLY_IN_MASK >> PSRAM_ULP_PHY_DLL_DLY_IN_SHIFT), "ERROR, bad ana phy range:%d", range); + + val = psram_phy->REG_050; + val &= ~(PSRAM_ULP_PHY_REG_DLL_RESETB | PSRAM_ULP_PHY_REG_DLL_CK_RDY); + psram_phy->REG_050 = val; + val = SET_BITFIELD(val, PSRAM_ULP_PHY_REG_DLL_RANGE, range); + psram_phy->REG_050 = val; + val |= (PSRAM_ULP_PHY_REG_DLL_RESETB | PSRAM_ULP_PHY_REG_DLL_CK_RDY); + psram_phy->REG_050 = val; + + hal_sys_timer_delay_us(100); + while ((psram_phy->REG_058 & PSRAM_ULP_PHY_DLL_LOCK) == 0); + + val = psram_phy->REG_058; + if ((val & PSRAM_ULP_PHY_DLL_ALL_ONE)) { + PSRAM_TRACE(2,"%s: all one, increase range=%d", __func__, range+1); + return hal_psram_calib_range(range+1); + } + + delay = GET_BITFIELD(val, PSRAM_ULP_PHY_DLL_DLY_IN); + PSRAM_TRACE(4,"%s, range:%d, T/4 = 0x%x(psram_phy->REG_058:0x%x)", __func__, range, delay/2, val); + if (delay > (PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_MASK>>PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_SHIFT) && range<3) { + PSRAM_TRACE("%s: bad delay (T/2 > 0x1f). increase range=%d", __func__, range+1); + return hal_psram_calib_range(range+1); + } + + inc_delay = delay/8; + if (inc_delay == 0) + inc_delay = 1; + + //volume = (PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_MASK>>PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_SHIFT) / inc_delay; + volume = MIN(delay, (PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_MASK>>PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_SHIFT)) / inc_delay; + + PSRAM_TRACE(2,"volume:%d, inc_delay:%d", volume, inc_delay); + + uint8_t all_valid = 1; + + memset(cali_valid, 0, sizeof(cali_valid)); + for (tx_dqs=0; tx_dqs<=volume; tx_dqs++) { + for (rx_dqs=0; rx_dqs<=volume; rx_dqs++) { + psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(delay/2) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(delay/2) | + PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(tx_dqs*inc_delay) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(rx_dqs*inc_delay); + cali_valid[tx_dqs][rx_dqs] = psramphy_check_write_valid(); + if (cali_valid[tx_dqs][rx_dqs] == 0) + all_valid = 0; + } + } + + if (all_valid && range < (PSRAM_ULP_PHY_DLL_DLY_IN_MASK >> PSRAM_ULP_PHY_DLL_DLY_IN_SHIFT)) { + PSRAM_TRACE(2,"%s: all valid increase range=%d", __func__, range+1); + //return hal_psram_calib_range(range+1); + } + + memset(cali_value, 0, sizeof(cali_value)); + PSRAM_TRACENOCRLF_NOTS("\r\n\r\n ---------------------------------------------------------------------- \r\n"); + PSRAM_TRACENOCRLF_NOTS(" rx_dqs"); + for (tx_dqs=0; tx_dqs<=volume; tx_dqs++) { + PSRAM_TRACENOCRLF_NOTS(" %2d ", tx_dqs*inc_delay); + } + PSRAM_TRACENOCRLF_NOTS("\r\n"); + for (tx_dqs=0; tx_dqs<=volume; tx_dqs++) { + PSRAM_TRACENOCRLF_NOTS("tx_dqs:%2d ", tx_dqs*inc_delay); + for (rx_dqs=0; rx_dqs<=volume; rx_dqs++) { + PSRAM_TRACENOCRLF_NOTS(" %d ", cali_valid[tx_dqs][rx_dqs]); + if (cali_valid[tx_dqs][rx_dqs]) { + uint8_t len_from_zero; + int8_t p; + p = tx_dqs; + while (p>=0) { + if (cali_valid[p][rx_dqs] == 0) + break; + p--; + } + len_from_zero = tx_dqs - p; + cali_value[tx_dqs][rx_dqs] = len_from_zero; + + p = tx_dqs; + while (p<=volume) { + if (cali_valid[p][rx_dqs] == 0) + break; + p++; + } + len_from_zero = p - tx_dqs; + cali_value[tx_dqs][rx_dqs] = MIN(cali_value[tx_dqs][rx_dqs], len_from_zero); + + p = rx_dqs; + while (p>=0) { + if (cali_valid[tx_dqs][p] == 0) + break; + p--; + } + len_from_zero = rx_dqs - p; + cali_value[tx_dqs][rx_dqs] = MIN(cali_value[tx_dqs][rx_dqs], len_from_zero); + + p = rx_dqs; + while (p<=volume) { + if (cali_valid[tx_dqs][p] == 0) + break; + p++; + } + len_from_zero = p - rx_dqs; + cali_value[tx_dqs][rx_dqs] = MIN(cali_value[tx_dqs][rx_dqs], len_from_zero); + } + } + PSRAM_TRACENOCRLF_NOTS("\r\n"); + } + PSRAM_TRACENOCRLF_NOTS(" -------------------------------------------------------------------------- \r\n"); + +#if 0 + PSRAM_TRACENOCRLF_NOTS("\r\n\r\n ---------------------------------------------------------------------- \r\n"); + PSRAM_TRACENOCRLF_NOTS(" rx_dqs"); + for (tx_dqs=0; tx_dqs<=volume; tx_dqs++) { + PSRAM_TRACENOCRLF_NOTS(" %2d ", tx_dqs*inc_delay); + } + PSRAM_TRACENOCRLF_NOTS("\r\n"); + for (tx_dqs=0; tx_dqs<=volume; tx_dqs++) { + PSRAM_TRACENOCRLF_NOTS("tx_dqs:%2d ", tx_dqs*inc_delay); + for (rx_dqs=0; rx_dqs<=volume; rx_dqs++) { + PSRAM_TRACENOCRLF_NOTS(" %d ", cali_value[tx_dqs][rx_dqs]); + } + PSRAM_TRACENOCRLF_NOTS("\r\n"); + } + PSRAM_TRACENOCRLF_NOTS(" -------------------------------------------------------------------------- \r\n"); +#endif + + uint32_t position = 0; + uint8_t max_value = 0; + for (tx_dqs=0; tx_dqs<=volume; tx_dqs++) { + for (rx_dqs=0; rx_dqs<=volume; rx_dqs++) { + if (cali_value[tx_dqs][rx_dqs] > max_value) { + max_value = cali_value[tx_dqs][rx_dqs]; + position = tx_dqs*(volume+1) + rx_dqs; + } + } + } + PSRAM_TRACENOCRLF_NOTS("position:%d\r\n", position); + tx_dqs = position/(volume+1)*inc_delay; + rx_dqs = (position%(volume+1))*inc_delay; + PSRAM_TRACENOCRLF_NOTS("most optimal position. tx_dqs:%d, rx_dqs:%d\r\n", tx_dqs, rx_dqs); + + psram_phy->REG_054 = PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(delay/2) | PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(delay/2) | + PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(tx_dqs) | PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(rx_dqs); + +} +static void hal_psram_calib(uint32_t clk) +{ + uint32_t phy_clk; + uint32_t range; + PSRAM_TRACE("%s, speed:%d", __func__, clk); + phy_clk = clk; + if (phy_clk <= 100000000 / 2) { + range = 3; + } else if (phy_clk <= 150000000 / 2) { + range = 2; + } else if (phy_clk <= 300000000 / 2) { + range = 1; + } else { + range = 0; + } + hal_psram_calib_range(range); +} +void hal_psram_snoop_enable() +{ + psram_mc->REG_044 &= ~PSRAM_ULP_MC_SNP_DISABLE; +} +void hal_psram_snoop_disable() +{ + psram_mc->REG_044 |= PSRAM_ULP_MC_SNP_DISABLE; +} + +void hal_psram_init(void) +{ + hal_cache_wrap_enable(HAL_CACHE_ID_I_CACHE); + hal_cache_wrap_enable(HAL_CACHE_ID_D_CACHE); + + hal_cmu_mem_set_freq(HAL_CMU_FREQ_104M); + hal_cmu_clock_enable(HAL_CMU_MOD_O_PSRAM); + hal_cmu_clock_enable(HAL_CMU_MOD_H_PSRAM); + hal_cmu_reset_clear(HAL_CMU_MOD_O_PSRAM); + hal_cmu_reset_clear(HAL_CMU_MOD_H_PSRAM); + + hal_psram_phy_init(psram_cfg_clk); + hal_sys_timer_delay_us(30); + hal_psram_mc_init(psram_cfg_clk); + +#ifdef PSRAM_RESET + psram_reset(); + psram_chip_timing_config(psram_run_clk, true); +#else + uint32_t reg; + uint32_t val; + + reg = 4; + psram_read_reg(reg, &val); + if (val & MR4_WL) { + psram_chip_timing_config(psram_run_clk, false); + } else { + psram_chip_timing_config(psram_run_clk, true); + } +#endif + + hal_psram_snoop_disable(); + hal_psram_calib(psram_run_clk); + hal_psram_snoop_enable(); +} + +#endif + diff --git a/platform/hal/hal_psramip_v1.h b/platform/hal/hal_psramip_v1.h new file mode 100644 index 0000000..5c7bff0 --- /dev/null +++ b/platform/hal/hal_psramip_v1.h @@ -0,0 +1,217 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_PSRAMIP_V1_H__ +#define __HAL_PSRAMIP_V1_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "reg_psramip_v1.h" + +#define PSRIP_KEY (0x55000000) + +#define psramip_read8(reg_base,a) \ + (*(volatile unsigned char*)((reg_base)+(a))) + +#define psramip_read32(reg_base,a) \ + (*(volatile unsigned int *)((reg_base)+(a))) + +#define psramip_write32(v,reg_base,a) \ + ((*(volatile unsigned int *)((reg_base)+(a))) = v) + + +#define PSRAM_STAT_BUSY (0x01) +#define PSRAM_STAT_TXFIFO_EMPTY (0x02) +#define PSRAM_STAT_TXFIFO_FULL (0x04) +#define PSRAM_STAT_RXFIFO_EMPTY (0x08) +#define PSRAM_STAT_RXFIFO_COUNT (0x1f << 4) + +/* ip ops */ +#if 1 +inline static void psramip_w_cmd_addr(uint32_t reg_base, uint32_t cmd, uint32_t addr) +{ + psramip_write32(cmd<REG_404 & PSRAM_UHS_MC_BUSY); +} + +static int hal_psramuhsip_wb_busy(void) +{ + return !!(psramuhs_mc->REG_404 & PSRAM_UHS_MC_WB_FILL_LEVEL_MASK); +} + +int hal_psramuhsip_mc_in_sleep(void) +{ + return GET_BITFIELD(psramuhs_mc->REG_404, PSRAM_UHS_MC_CP_FSM_STATE) == CP_FSM_STATE_PD; +} + +int hal_psramuhsip_rx_fifo_empty(void) +{ + return !!(psramuhs_mc->REG_404 & PSRAM_UHS_MC_MGR_RXFIFO_R_EMPTY); +} + +int hal_psramuhsip_tx_fifo_full(void) +{ + return !!(psramuhs_mc->REG_404 & PSRAM_UHS_MC_MGR_TXFIFO_W_FULL); +} + +uint32_t hal_psramuhsip_get_rx_fifo_len(void) +{ + return GET_BITFIELD(psramuhs_mc->REG_404, PSRAM_UHS_MC_MGR_RXFIFO_FULL_CNT); +} + +uint32_t hal_psramuhsip_get_tx_fifo_free_len(void) +{ + return GET_BITFIELD(psramuhs_mc->REG_404, PSRAM_UHS_MC_MGR_TXFIFO_EMPTY_CNT); +} + +void hal_psramuhsip_mc_busy_wait(void) +{ + while (hal_psramuhsip_mc_busy()); +} + +void hal_psramuhsip_wb_busy_wait(void) +{ + while (hal_psramuhsip_wb_busy()); +} + +void hal_psramuhsip_flush_tx_fifo(void) +{ + hal_psramuhsip_mc_busy_wait(); + psramuhs_mc->REG_01C = PSRAM_UHS_MC_MGR_TX_FIFO_CLR; + hal_psramuhsip_mc_busy_wait(); +} + +void hal_psramuhsip_flush_rx_fifo(void) +{ + hal_psramuhsip_mc_busy_wait(); + psramuhs_mc->REG_01C = PSRAM_UHS_MC_MGR_RX_FIFO_CLR; + hal_psramuhsip_mc_busy_wait(); +} + +void hal_psramuhsip_flush_all_fifo(void) +{ + hal_psramuhsip_mc_busy_wait(); + psramuhs_mc->REG_01C = PSRAM_UHS_MC_MGR_TX_FIFO_CLR | PSRAM_UHS_MC_MGR_RX_FIFO_CLR; + hal_psramuhsip_mc_busy_wait(); +} + +void hal_psramuhsip_xfer_addr_len(uint32_t addr, uint32_t len) +{ + psramuhs_mc->REG_008 = addr; + psramuhs_mc->REG_00C = len; +} + +void hal_psramuhsip_write_fifo(uint32_t *data, uint32_t len) +{ + for (int i = 0; i < len; i++) { + psramuhs_mc->REG_014 = *data++; + } +} + +void hal_psramuhsip_read_fifo(uint32_t *data, uint32_t len) +{ + for (int i = 0; i < len; i++) { + *data++ = psramuhs_mc->REG_018; + } +} + +void hal_psramuhsip_set_reg_data_mask(void) +{ +#ifdef PSRAMUHS_DUAL_8BIT + psramuhs_mc->REG_010 = 0xFFFC; +#else + psramuhs_mc->REG_010 = 0xFFFE; +#endif +} + +void hal_psramuhsip_set_mem_data_mask(void) +{ + psramuhs_mc->REG_010 = 0; +} + +void hal_psramuhsip_set_reg_fifo_width(void) +{ + psramuhs_mc->REG_0B0 = 0; +} + +void hal_psramuhsip_set_mem_fifo_width(void) +{ + // 128 bits if PSRAMUHS_DUAL_8BIT; 64 bits otherwise + psramuhs_mc->REG_0B0 = PSRAM_UHS_MC_MGR_FIFO_TEST_EN; +} + +void hal_psramuhsip_set_cmd(enum MEMIF_CMD_T cmd) +{ + psramuhs_mc->REG_004 = cmd; +} + +POSSIBLY_UNUSED void psramuhs_read_reg(uint32_t reg, uint32_t *val) +{ + hal_psramuhsip_flush_all_fifo(); + hal_psramuhsip_xfer_addr_len(reg, 1); + hal_psramuhsip_set_cmd(MEMIF_MRR); + while (hal_psramuhsip_rx_fifo_empty()); + hal_psramuhsip_read_fifo(val, 1); +} + +static void psramuhs_send_cmd_reg(enum MEMIF_CMD_T cmd, uint32_t reg, uint32_t val) +{ +#if !defined(PSRAMUHS_DIG_LOOPBACK) && !defined(PSRAMUHS_ANA_LOOPBACK) +#ifdef PSRAMUHS_DUAL_8BIT + val &= 0xFF; + val |= (val << 8); +#endif + hal_psramuhsip_flush_all_fifo(); + //hal_psramuhsip_set_reg_fifo_width(); + //hal_psramuhsip_set_reg_data_mask(); + hal_psramuhsip_write_fifo(&val, 1); + hal_psramuhsip_xfer_addr_len(reg, 1); + hal_psramuhsip_set_cmd(cmd); + while (hal_psramuhsip_get_tx_fifo_free_len() != TX_FIFO_DEPTH); + hal_psramuhsip_mc_busy_wait(); + //hal_psramuhsip_set_mem_fifo_width(); + //hal_psramuhsip_set_mem_data_mask(); +#endif +} + +static void psramuhs_write_reg(uint32_t reg, uint32_t val) +{ + psramuhs_send_cmd_reg(MEMIF_MRS, reg, val); +} + +static void psramuhs_single_cmd(enum MEMIF_CMD_T cmd) +{ +#if !defined(PSRAMUHS_DIG_LOOPBACK) && !defined(PSRAMUHS_ANA_LOOPBACK) + hal_psramuhsip_flush_all_fifo(); + hal_psramuhsip_set_cmd(cmd); + hal_psramuhsip_mc_busy_wait(); +#endif +} + +static POSSIBLY_UNUSED void psramuhs_start_clock(void) +{ + psramuhs_single_cmd(MEMIF_START_CLOCK); +} + +static POSSIBLY_UNUSED void psramuhs_stop_clock(void) +{ + psramuhs_single_cmd(MEMIF_STOP_CLOCK); +} + +static POSSIBLY_UNUSED void psramuhs_reset(void) +{ + psramuhs_single_cmd(MEMIF_RST); +} + +static POSSIBLY_UNUSED void psramuhs_zq_calib_reset(void) +{ + psramuhs_send_cmd_reg(MEMIF_ZQCRST, 7, 0); +} + +static POSSIBLY_UNUSED void psramuhs_zq_calib(void) +{ + psramuhs_send_cmd_reg(MEMIF_ZQCL, 5, 0); +} + +static void psramuhs_set_timing(uint32_t clk) +{ + uint32_t reg; + uint32_t val; + uint32_t burst_len; + + reg = 0; + if (clk <= 200000000) { + val = 7; + } else if (clk <= 333000000) { + val = 6; + } else if (clk <= 400000000) { + val = 5; + } else if (clk <= 533000000) { + val = 4; + } else if (clk <= 667000000) { + val = 0; + } else if (clk <= 800000000) { + val = 1; + } else if (clk <= 933000000) { + val = 2; + } else { + val = 3; + } + // Latency, drive + val = (val << 0) | (2 << 3); +#if 0 + //refresh disable + val |= (1 << 7); +#endif + psramuhs_write_reg(reg, val); + + reg = 2; +#if defined(__ARM_ARCH_ISA_ARM) || defined(DSP_ENABLE) +#ifdef PSRAMUHS_DUAL_8BIT + burst_len = 0x1;//32B +#else + burst_len = 0x2;//64B +#endif +#else +#ifdef PSRAMUHS_DUAL_8BIT + burst_len = 0x0;//16B +#else + burst_len = 0x1;//32B +#endif +#endif +#ifdef PSRAMUHS_PRA_ENABLE + // Burst len, pra enable + val = (burst_len << 0) | (1 << 4); +#else + // Burst len, auto-precharge +#ifdef PSRAMUHS_AUTO_PRECHARGE + val = (burst_len << 0) | (1 << 3); +#else + val = (burst_len << 0); +#endif +#endif + //wrap enable +#ifdef PSRAMUHS_WRAP_ENABLE + val |= (1 << 2); +#endif + psramuhs_write_reg(reg, val); + + reg = 6; + // Vref trim + val = (8 << 0); + psramuhs_write_reg(reg, val); + hal_sys_timer_delay_us(5); + + psramuhs_zq_calib_reset(); + psramuhs_zq_calib(); +} + +void hal_psramuhs_sleep(void) +{ +} + +void hal_psramuhs_wakeup(void) +{ +} + +static void hal_psramuhs_mc_set_timing(uint32_t clk) +{ + uint32_t val1, val2; + uint32_t val; + + if (clk <= 200000000) { + val1 = 9; + val2 = 5; + } else if (clk <= 333000000) { + val1 = 13; + val2 = 5; + } else if (clk <= 400000000) { + val1 = 16; + val2 = 6; + } else if (clk <= 533000000) { + val1 = 20; + val2 = 10; + } else if (clk <= 667000000) { + val1 = 24; + val2 = 12; + } else if (clk <= 800000000) { + val1 = 29; + val2 = 14; + } else if (clk <= 933000000) { + val1 = 33; + val2 = 16; + } else { + val1 = 37; + val2 = 18; + } + if (clk >= 466000000) + val2--; + + psramuhs_mc->REG_028 = PSRAM_UHS_MC_WRITE_LATENCY(val2); + psramuhs_mc->REG_02C = PSRAM_UHS_MC_READ_LATENCY(val1); + + // tCEM_MAX <= 7.8 us when MRW2[5]==1 && MRR4[2]==0, or <= 3.9 us when MRW2[5]==0 || MRR4[2]==1 + val = (clk / 1000000) * 30 / 10 - 1; + psramuhs_mc->REG_04C = PSRAM_UHS_MC_T_REFI(val) | PSRAM_UHS_MC_NUM_OF_BURST_RFS(0x1000); + +#ifdef FPGA + clk = 800*1000*1000; +#endif + // tRC >= 60 ns + val = ((clk / 1000000) * 60 + (1000 - 1)) / 1000; + psramuhs_mc->REG_050 = PSRAM_UHS_MC_T_RC(val); + // tRFC >= 60 ns + val = ((clk / 1000000) * 60 + (1000 - 1)) / 1000; + psramuhs_mc->REG_054 = PSRAM_UHS_MC_T_RFC(val); +#ifdef PSRAMUHS_AUTO_PRECHARGE + + // tCPHR >= 5 ns (auto precharge) +#if PSRAMUHS_SPEED >= 900 + val = ((clk / 1000000) * 5 + (1000 - 1)) / 1000; +#else /*PSRAMUHS_SPEED == 1000*/ + val = 20; +#endif /*PSRAMUHS_SPEED == 1000*/ + psramuhs_mc->REG_05C = PSRAM_UHS_MC_T_CPHR_AP(val); + + // tCPHW >= 30 ns (auto precharge) +#if PSRAMUHS_SPEED >= 900 + val = ((clk / 1000000) * 30 + (1000 - 1)) / 1000; +#else /*PSRAMUHS_SPEED == 1000*/ + val = 100; +#endif /*PSRAMUHS_SPEED == 1000*/ + psramuhs_mc->REG_064 = PSRAM_UHS_MC_T_CPHW_AP(val); + +#else /*PSRAMUHS_AUTO_PRECHARGE*/ + + // tCPHR >= 20 ns (no auto precharge) +#if PSRAMUHS_SPEED >= 900 + val = ((clk / 1000000) * 20 + (1000 - 1)) / 1000; +#else /*PSRAMUHS_SPEED == 1000*/ + val = 20; +#endif /*PSRAMUHS_SPEED == 1000*/ + psramuhs_mc->REG_058 = PSRAM_UHS_MC_T_CPHR(val); + + // tCPHW >= 30 ns (no auto precharge) +#if PSRAMUHS_SPEED >= 900 + val = ((clk / 1000000) * 30 + (1000 - 1)) / 1000; +#else /*PSRAMUHS_SPEED == 1000*/ + val = 100; +#endif /*PSRAMUHS_SPEED == 1000*/ + psramuhs_mc->REG_060 = PSRAM_UHS_MC_T_CPHW(val); + +#endif /*PSRAMUHS_AUTO_PRECHARGE*/ + // tMRR >= 20ns + val = 20;//((clk / 1000000) * 20 + (1000 - 1)) / 1000; + psramuhs_mc->REG_068 = PSRAM_UHS_MC_T_MRR(val); + // tMRW >= 100 ns + val = ((clk / 1000000) * 100 + (1000 - 1)) / 1000; + psramuhs_mc->REG_06C = PSRAM_UHS_MC_T_MRS(val); + // tCEM >= 4 cycles + psramuhs_mc->REG_070 = PSRAM_UHS_MC_T_CEM(4); + // tRST >= 10 us + val = (clk / 1000000) * 10; + psramuhs_mc->REG_074 = PSRAM_UHS_MC_T_RST(val); + // tSRF >= 100 ns + val = ((clk / 1000000) + (10 - 1)) / 10; + psramuhs_mc->REG_078 = PSRAM_UHS_MC_T_SRF(val); + // tSRF >= 70 ns + val = ((clk / 1000000) * 70 + (1000 - 1)) / 1000; + psramuhs_mc->REG_07C = PSRAM_UHS_MC_T_XSR(val); + // tHS >= 150 us + val = (clk / 1000000) * 150; + psramuhs_mc->REG_080 = PSRAM_UHS_MC_T_HS(val); + // tXPHS >= 100 ns + val = ((clk / 1000000) + (10 - 1)) / 10; + psramuhs_mc->REG_084 = PSRAM_UHS_MC_T_XPHS(val); + // tXHS >= 150 us + val = (clk / 1000000) * 150; + psramuhs_mc->REG_088 = PSRAM_UHS_MC_T_XHS(val); + // tZQCAL >= 1 us + val = (clk / 1000000) * 1; + psramuhs_mc->REG_08C = PSRAM_UHS_MC_T_ZQCAL(val); + // tZQCRST >= 1 us + val = (clk / 1000000) * 1; + psramuhs_mc->REG_090 = PSRAM_UHS_MC_T_ZQCRST(val); + // NOP dummy cycles, same as tXPHS >= 100 ns + val = ((clk / 1000000) + (10 - 1)) / 10; + psramuhs_mc->REG_0A0 = PSRAM_UHS_MC_STOP_CLK_IN_NOP | PSRAM_UHS_MC_NOP_DMY_CYC(val); + psramuhs_mc->REG_0A4 = PSRAM_UHS_MC_QUEUE_IDLE_CYCLE(50000); + // tDQSCK in [2 ns, 6.5 ns], expanded time >= tDQSCK_MAX + val = ((clk / 1000000) * 65/10 + (1000 - 1)) / 1000; + psramuhs_mc->REG_0A8 = PSRAM_UHS_MC_T_EXPANDRD(val); +} + +static void hal_psramuhs_mc_init(uint32_t clk) +{ + uint32_t val; + uint32_t burst_len; + uint32_t boundary; + + val = PSRAM_UHS_MC_CHIP_TYPE; +#ifdef PSRAMUHS_DUAL_8BIT + val |= PSRAM_UHS_MC_CHIP_BIT; +#endif +#ifdef PSRAMUHS_DUAL_SWITCH + val |= PSRAM_UHS_MC_CHIP_SWITCH; +#endif +#ifdef PSRAMUHS_16BIT + val |= PSRAM_UHS_MC_CHIP_IO_X16 | PSRAM_UHS_MC_CHIP_CA_PATTERN(2); +#else + val |= PSRAM_UHS_MC_CHIP_CA_PATTERN(1); +#endif +#if (PSRAMUHS_SIZE == 0x800000) + val |= PSRAM_UHS_MC_CHIP_MEM_SIZE(1); +#elif (PSRAMUHS_SIZE == 0x1000000) + val |= PSRAM_UHS_MC_CHIP_MEM_SIZE(2); +#elif (PSRAMUHS_SIZE == 0x2000000) + val |= PSRAM_UHS_MC_CHIP_MEM_SIZE(3); +#else + ASSERT(false, "Bad PSRAMUHS_SIZE=0x%08X", PSRAMUHS_SIZE); +#endif + psramuhs_mc->REG_000 = val; + psramuhs_mc->REG_024 = PSRAM_UHS_MC_STOP_CLK_IDLE | PSRAM_UHS_MC_AUTOWAKEUP_EN; + // Burst length: 1=32 bytes (Cortex-M) or 2=64 bytes (Cortex-A), Page boundary: 2K bytes +#ifdef PSRAMUHS_WRAP_ENABLE +#if defined(__ARM_ARCH_ISA_ARM) || defined(DSP_ENABLE) + burst_len = 0x2;//64B +#else + burst_len = 0x1;//32B +#endif +#else +#ifdef PSRAMUHS_DUAL_8BIT + burst_len = 0x6;// 0:16B 5;2KB 6:4KB +#else + burst_len = 0x5;// 0:16B 5;2KB 6:4KB +#endif +#endif +#ifdef PSRAMUHS_DUAL_8BIT + boundary = 2; +#else + boundary = 1; +#endif + psramuhs_mc->REG_034 = PSRAM_UHS_MC_BURST_LENGTH(burst_len) | PSRAM_UHS_MC_PAGE_BOUNDARY(boundary); + + // AXI bus width: 128 bits + psramuhs_mc->REG_038 = PSRAM_UHS_MC_BUS_WIDTH; + // Write buffer level with high priority: 0~15 + psramuhs_mc->REG_03C = PSRAM_UHS_MC_HIGH_PRI_LEVEL(8); +#ifdef PSRAMUHS_PRA_ENABLE + psramuhs_mc->REG_040 = PSRAM_UHS_MC_PRA_ENABLE | PSRAM_UHS_MC_PRA_MAX_CNT(32); +#else +#ifdef PSRAMUHS_AUTO_PRECHARGE + psramuhs_mc->REG_040 = PSRAM_UHS_MC_AUTO_PRECHARGE | PSRAM_UHS_MC_PRA_MAX_CNT(32); +#else + psramuhs_mc->REG_040 = PSRAM_UHS_MC_PRA_MAX_CNT(32); +#endif +#endif +#ifdef PSRAMUHS_WRAP_ENABLE + psramuhs_mc->REG_040 |= PSRAM_UHS_MC_CP_WRAP_EN; +#endif + psramuhs_mc->REG_048 = PSRAM_UHS_MC_FRE_RATIO(2); +#ifdef PSRAMUHS_DUMMY_CYCLE + psramuhs_mc->REG_840 |= PSRAM_UHS_MC_PHY_DUMMY_CYC_EN; +#endif +#if defined(CHIP_BEST2001) + psramuhs_mc->REG_840 |= PSRAM_UHS_MC_PHY_IDLE_PAD_EN; +#endif + psramuhs_mc->REG_844 = PSRAM_UHS_MC_T_WPST(2); + + hal_psramuhsip_set_reg_fifo_width(); + hal_psramuhsip_set_reg_data_mask(); + + hal_psramuhs_mc_set_timing(clk); + + psramuhs_mc->REG_400 = PSRAM_UHS_MC_INIT_COMPLETE; + +#ifdef PSRAMUHS_DIG_LOOPBACK + psramuhs_mc->REG_840 |= PSRAM_UHS_MC_PHY_LOOPBACK_EN; + psramuhs_mc->REG_044 |= PSRAM_UHS_MC_SNP_DISABLE; +#endif +#ifdef PSRAMUHS_ANA_LOOPBACK + psramuhs_mc->REG_044 |= PSRAM_UHS_MC_SNP_DISABLE; + psramuhs_mc->REG_0B0 |= PSRAM_UHS_MC_MGR_FIFO_TEST_EN; + psramuhs_mc->REG_840 |= PSRAM_UHS_MC_ANA_LOOPBACK_EN; +#endif + +#ifndef FPGA +#if !defined(PSRAMUHS_DIG_LOOPBACK) && !defined(PSRAMUHS_ANA_LOOPBACK) + psramuhsphy_init_calib(); +#endif +#endif + +} + +void hal_psramuhs_mc_entry_auto_lp() +{ + psramuhs_mc->REG_024 |= PSRAM_UHS_MC_ENTRY_SLEEP_IDLE | PSRAM_UHS_MC_ENTRY_SELF_REFRESH_IDLE; +} + +void hal_psramuhs_snoop_enable() +{ + psramuhs_mc->REG_044 &= ~PSRAM_UHS_MC_SNP_DISABLE; +} +void hal_psramuhs_snoop_disable() +{ + psramuhs_mc->REG_044 |= PSRAM_UHS_MC_SNP_DISABLE; +} +void hal_psramuhs_refresh_enable() +{ +#ifdef PSRAMUHS_BURST_REFRESH + psramuhs_mc->REG_020 = PSRAM_UHS_MC_REFRESH_MODE | PSRAM_UHS_MC_BURST_REFRESH_EN; +#else + psramuhs_mc->REG_020 = PSRAM_UHS_MC_REFRESH_MODE; +#endif +} +void hal_psramuhs_init(void) +{ +#if PSRAMUHS_ENABLE +#error "must set MPU befor 2001 eco" +#endif + + hal_cache_wrap_enable(HAL_CACHE_ID_I_CACHE); + hal_cache_wrap_enable(HAL_CACHE_ID_D_CACHE); + + hal_cmu_ddr_clock_enable(); + hal_cmu_clock_enable(HAL_CMU_MOD_O_PSRAMUHS); + hal_cmu_clock_enable(HAL_CMU_MOD_H_PSRAMUHS); + hal_cmu_reset_clear(HAL_CMU_MOD_O_PSRAMUHS); + hal_cmu_reset_clear(HAL_CMU_MOD_H_PSRAMUHS); + +#ifndef FPGA + psramuhsphy_open(psramuhs_run_clk); +#endif + hal_psramuhs_mc_init(psramuhs_run_clk); + psramuhs_start_clock(); + hal_sys_timer_delay_us(3); + psramuhs_reset(); + psramuhs_stop_clock(); + psramuhs_set_timing(psramuhs_run_clk); + hal_psramuhs_refresh_enable(); +#ifndef FPGA +#if !defined(PSRAMUHS_DIG_LOOPBACK) && !defined(PSRAMUHS_ANA_LOOPBACK) + hal_psramuhs_snoop_disable(); + psramuhsphy_calib(psramuhs_run_clk); + hal_psramuhs_snoop_enable(); +#endif +#endif + //hal_psramuhs_mc_entry_auto_lp(); +} + +#endif + diff --git a/platform/hal/hal_psramuhs.h b/platform/hal/hal_psramuhs.h new file mode 100644 index 0000000..05528dd --- /dev/null +++ b/platform/hal/hal_psramuhs.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_PSRAMUHS_H__ +#define __HAL_PSRAMUHS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +void hal_psramuhs_sleep(void); +void hal_psramuhs_wakeup(void); +void hal_psramuhs_init(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_pwm.c b/platform/hal/hal_pwm.c new file mode 100644 index 0000000..c02c713 --- /dev/null +++ b/platform/hal/hal_pwm.c @@ -0,0 +1,203 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include "hal_pwm.h" +#include "reg_pwm.h" +#include "cmsis.h" +#include "hal_cmu.h" +#include "hal_timer.h" +#include "hal_trace.h" + +#define PWM_SLOW_CLOCK (CONFIG_SYSTICK_HZ) +#define PWM_FAST_CLOCK (hal_cmu_get_crystal_freq() / 2) +#define PWM_MAX_VALUE 0xFFFF + +// Max allowed PWM freqency error in percentage +#define PWM_MAX_FREQ_ERR_PCT 5 + +static struct PWM_T * const pwm[] = { + (struct PWM_T *)PWM_BASE, +#ifdef CHIP_BEST2000 + (struct PWM_T *)AON_PWM_BASE, +#endif +}; + +static const enum HAL_CMU_MOD_ID_T pwm_o_mod[] = { + HAL_CMU_MOD_O_PWM0, +#ifdef CHIP_BEST2000 + HAL_CMU_AON_O_PWM0, +#endif +}; + +static const enum HAL_CMU_MOD_ID_T pwm_p_mod[] = { + HAL_CMU_MOD_P_PWM, +#ifdef CHIP_BEST2000 + HAL_CMU_AON_A_PWM, +#endif +}; + +int hal_pwm_enable(enum HAL_PWM_ID_T id, const struct HAL_PWM_CFG_T *cfg) +{ + uint32_t mod_freq; + uint32_t load; + uint32_t toggle; + uint32_t lock; + uint8_t ratio; + uint8_t index; + uint8_t offset; + + if (id >= HAL_PWM_ID_QTY) { + return 1; + } + if (cfg->ratio > 100) { + return 2; + } + + if (cfg->inv && (cfg->ratio == 0 || cfg->ratio == 100)) { + ratio = 100 - cfg->ratio; + } else { + ratio = cfg->ratio; + } + +#ifdef PWM_TRY_SLOW_CLOCK + mod_freq = PWM_SLOW_CLOCK; +#else + if (cfg->sleep_on) { + mod_freq = PWM_SLOW_CLOCK; + } else { + mod_freq = PWM_FAST_CLOCK; + } +#endif + + if (ratio == 100) { + load = PWM_MAX_VALUE; + toggle = PWM_MAX_VALUE; + } else if (ratio == 0) { + load = 0; + toggle = 0; + } else { + load = mod_freq / cfg->freq; + toggle = load * ratio / 100; + if (toggle == 0) { + toggle = 1; + } +#ifdef PWM_TRY_SLOW_CLOCK + // Check PWM frequency error in percentage + if (!cfg->sleep_on && ABS((int)(toggle * 100 - load * ratio)) > load * PWM_MAX_FREQ_ERR_PCT) { + mod_freq = PWM_FAST_CLOCK; + load = mod_freq / cfg->freq; + toggle = load * ratio / 100; + } +#endif + load = PWM_MAX_VALUE + 1 - load; + toggle = PWM_MAX_VALUE - toggle; + } + +#ifdef CHIP_BEST2000 + if (id < HAL_PWM2_ID_0) { + index = 0; + offset = id - HAL_PWM_ID_0; + } else { + index = 1; + offset = id - HAL_PWM2_ID_0; + } +#else + index = 0; + offset = id - HAL_PWM_ID_0; +#endif + + if (hal_cmu_reset_get_status(pwm_o_mod[index] + offset) == HAL_CMU_RST_SET) { + hal_cmu_clock_enable(pwm_o_mod[index] + offset); + hal_cmu_clock_enable(pwm_p_mod[index]); + hal_cmu_reset_clear(pwm_o_mod[index] + offset); + hal_cmu_reset_clear(pwm_p_mod[index]); + } else { + pwm[index]->EN &= ~(1 << offset); + } + + if (ratio == 0) { + // Output 0 when disabled + return 0; + } + + hal_cmu_pwm_set_freq(id, mod_freq); + + lock = int_lock(); + + if (offset == 0) { + pwm[index]->LOAD01 = SET_BITFIELD(pwm[index]->LOAD01, PWM_LOAD01_0, load); + pwm[index]->TOGGLE01 = SET_BITFIELD(pwm[index]->TOGGLE01, PWM_TOGGLE01_0, toggle); + } else if (offset == 1) { + pwm[index]->LOAD01 = SET_BITFIELD(pwm[index]->LOAD01, PWM_LOAD01_1, load); + pwm[index]->TOGGLE01 = SET_BITFIELD(pwm[index]->TOGGLE01, PWM_TOGGLE01_1, toggle); + } else if (offset == 2) { + pwm[index]->LOAD23 = SET_BITFIELD(pwm[index]->LOAD23, PWM_LOAD23_2, load); + pwm[index]->TOGGLE23 = SET_BITFIELD(pwm[index]->TOGGLE23, PWM_TOGGLE23_2, toggle); + } else { + pwm[index]->LOAD23 = SET_BITFIELD(pwm[index]->LOAD23, PWM_LOAD23_3, load); + pwm[index]->TOGGLE23 = SET_BITFIELD(pwm[index]->TOGGLE23, PWM_TOGGLE23_3, toggle); + } + + if (cfg->inv) { + pwm[index]->INV |= (1 << offset); + } else { + pwm[index]->INV &= ~(1 << offset); + } + + pwm[index]->EN |= (1 << offset); + + int_unlock(lock); + + return 0; +} + +int hal_pwm_disable(enum HAL_PWM_ID_T id) +{ + uint8_t index; + uint8_t offset; + + if (id >= HAL_PWM_ID_QTY) { + return 1; + } + +#ifdef CHIP_BEST2000 + if (id < HAL_PWM2_ID_0) { + index = 0; + offset = id - HAL_PWM_ID_0; + } else { + index = 1; + offset = id - HAL_PWM2_ID_0; + } +#else + index = 0; + offset = id - HAL_PWM_ID_0; +#endif + + if (hal_cmu_reset_get_status(pwm_o_mod[index] + offset) == HAL_CMU_RST_SET) { + return 0; + } + + pwm[index]->EN &= ~(1 << offset); + hal_cmu_reset_set(pwm_o_mod[index] + offset); + hal_cmu_clock_disable(pwm_o_mod[index] + offset); + if (pwm[index]->EN == 0) { + hal_cmu_reset_set(pwm_p_mod[index]); + hal_cmu_clock_disable(pwm_p_mod[index]); + } + + return 0; +} + diff --git a/platform/hal/hal_pwm.h b/platform/hal/hal_pwm.h new file mode 100644 index 0000000..2abaad1 --- /dev/null +++ b/platform/hal/hal_pwm.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_PWM_H__ +#define __HAL_PWM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "stdbool.h" +#include "hal_cmu.h" + +struct HAL_PWM_CFG_T { + uint32_t freq; + uint8_t ratio; + bool inv; + bool sleep_on; +}; + +int hal_pwm_enable(enum HAL_PWM_ID_T id, const struct HAL_PWM_CFG_T *cfg); + +int hal_pwm_disable(enum HAL_PWM_ID_T id); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_rtc.c b/platform/hal/hal_rtc.c new file mode 100644 index 0000000..1851b0f --- /dev/null +++ b/platform/hal/hal_rtc.c @@ -0,0 +1,246 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_HAS_DIG_RTC + +#include "plat_addr_map.h" +#include "hal_rtc.h" +#include "reg_rtc.h" + +static HAL_RTC_IRQ_HANDLER_T irq_handler = NULL; + +static struct RTC_T * const rtc = (struct RTC_T *)RTC_BASE; + +static const unsigned char rtc_days_in_month[] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +static const unsigned short rtc_ydays[2][13] = { + /* Normal years */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; + +#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) + +static inline int is_leap_year(unsigned int year) +{ + return (!(year % 4) && (year % 100)) || !(year % 400); +} + +/* + * The number of days in the month. + */ +int rtc_month_days(unsigned int month, unsigned int year) +{ + return rtc_days_in_month[month] + (is_leap_year(year) && month == 1); +} + +/* + * The number of days since January 1. (0 to 365) + */ +int rtc_year_days(unsigned int day, unsigned int month, unsigned int year) +{ + return rtc_ydays[is_leap_year(year)][month] + day-1; +} + +/* + * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. + */ +void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) +{ + unsigned int month, year; + int days; + + days = time / 86400; + time -= (unsigned int) days * 86400; + + /* day of the week, 1970-01-01 was a Thursday */ + //tm->tm_wday = (days + 4) % 7; + + year = 1970 + days / 365; + days -= (year - 1970) * 365 + + LEAPS_THRU_END_OF(year - 1) + - LEAPS_THRU_END_OF(1970 - 1); + if (days < 0) { + year -= 1; + days += 365 + is_leap_year(year); + } + tm->tm_year = year - 1900; + //tm->tm_yday = days + 1; + + for (month = 0; month < 11; month++) { + int newdays; + + newdays = days - rtc_month_days(month, year); + if (newdays < 0) + break; + days = newdays; + } + tm->tm_mon = month; + tm->tm_mday = days + 1; + + tm->tm_hour = time / 3600; + time -= tm->tm_hour * 3600; + tm->tm_min = time / 60; + tm->tm_sec = time - tm->tm_min * 60; +} + +/* + * Does the rtc_time represent a valid date/time? + */ +int rtc_valid_tm(struct rtc_time *tm) +{ + if (tm->tm_year < 70 + || ((unsigned)tm->tm_mon) >= 12 + || tm->tm_mday < 1 + || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900) + || ((unsigned)tm->tm_hour) >= 24 + || ((unsigned)tm->tm_min) >= 60 + || ((unsigned)tm->tm_sec) >= 60) + return -1; + + return 0; +} + +/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. + * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 + * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. + * + * [For the Julian calendar (which was used in Russia before 1917, + * Britain & colonies before 1752, anywhere else before 1582, + * and is still in use by some communities) leave out the + * -year/100+year/400 terms, and add 10.] + * + * This algorithm was first published by Gauss (I think). + * + * WARNING: this function will overflow on 2106-02-07 06:28:16 on + * machines where long is 32-bit! (However, as time_t is signed, we + * will already get problems at other places on 2038-01-19 03:14:08) + */ +unsigned long +mktime(const unsigned int year0, const unsigned int mon0, + const unsigned int day, const unsigned int hour, + const unsigned int min, const unsigned int sec) +{ + unsigned int mon = mon0, year = year0; + + /* 1..12 -> 11,12,1..10 */ + if (0 >= (int) (mon -= 2)) { + mon += 12; /* Puts Feb last since it has leap day */ + year -= 1; + } + + return ((((unsigned long) + (year/4 - year/100 + year/400 + 367*mon/12 + day) + + year*365 - 719499 + )*24 + hour /* now have hours */ + )*60 + min /* now have minutes */ + )*60 + sec; /* finally seconds */ +} + +/* + * Convert Gregorian date to seconds since 01-01-1970 00:00:00. + */ +int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) +{ + *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + return 0; +} + +int hal_rtc_get(struct rtc_time *time) +{ + unsigned long value; + + if ((rtc->RTCCR & RTC_CR_EN) == 0) { + return 1; + } + + value = rtc->RTCDR; + rtc_tm_to_time(time, &value); + return 0; +} + +int hal_rtc_set(struct rtc_time *time) +{ + unsigned long value; + + if (rtc_valid_tm(time) != 0) { + return 1; + } + + if ((rtc->RTCCR & RTC_CR_EN) == 0) { + rtc->RTCCR = RTC_CR_EN; + } + + rtc_tm_to_time(time, &value); + rtc->RTCLR = value; + return 0; +} + +int hal_rtc_set_alarm(struct rtc_time *time) +{ + unsigned long value; + + if (rtc_valid_tm(time) != 0) { + return 1; + } + + if ((rtc->RTCCR & RTC_CR_EN) == 0) { + return 1; + } + + rtc_tm_to_time(time, &value); + rtc->RTCMR = value; + rtc->RTCICR = RTC_BIT_AI; + rtc->RTCIMSC = RTC_BIT_AI; + return 0; +} + +int hal_rtc_clear_alarm(void) +{ + rtc->RTCIMSC = 0; + rtc->RTCICR = RTC_BIT_AI; + return 0; +} + +HAL_RTC_IRQ_HANDLER_T hal_rtc_set_irq_handler(HAL_RTC_IRQ_HANDLER_T handler) +{ + HAL_RTC_IRQ_HANDLER_T old_handler; + + old_handler = irq_handler; + irq_handler = handler; + return old_handler; +} + +void RTC_IRQHandler(void) +{ + uint32_t value; + struct rtc_time time; + + if ((rtc->RTCMIS & RTC_BIT_AI) != 0) { + rtc->RTCICR = RTC_BIT_AI; + + if (irq_handler != NULL) { + value = rtc->RTCDR; + rtc_time_to_tm(value, &time); + irq_handler(&time); + } + } +} + +#endif // CHIP_HAS_DIG_RTC diff --git a/platform/hal/hal_rtc.h b/platform/hal/hal_rtc.h new file mode 100644 index 0000000..fc5f62e --- /dev/null +++ b/platform/hal/hal_rtc.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_RTC_H__ +#define __HAL_RTC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +struct rtc_time { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; +}; + +typedef void (*HAL_RTC_IRQ_HANDLER_T)(struct rtc_time *time); + +int hal_rtc_get(struct rtc_time *time); + +int hal_rtc_set(struct rtc_time *time); + +int hal_rtc_set_alarm(struct rtc_time *time); + +int hal_rtc_clear_alarm(void); + +HAL_RTC_IRQ_HANDLER_T hal_rtc_set_irq_handler(HAL_RTC_IRQ_HANDLER_T handler); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_sdmmc.c b/platform/hal/hal_sdmmc.c new file mode 100644 index 0000000..7d87402 --- /dev/null +++ b/platform/hal/hal_sdmmc.c @@ -0,0 +1,2827 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_HAS_SDMMC + +#include "errno.h" +#include "stdarg.h" +#include "stdio.h" +#include "string.h" +#include "plat_addr_map.h" +#include "reg_sdmmcip.h" +#include "hal_sdmmc.h" +#include "cmsis_nvic.h" +#include "hal_uart.h" +#include "hal_trace.h" +#include "hal_dma.h" +#include "hal_timer.h" +#include "hal_cmu.h" + +#ifndef ETIMEDOUT +#define ETIMEDOUT 110 /* Connection timed out */ +#endif + +#define HAL_SDMMC_USE_DMA 1 +//#define __BUS_WIDTH_SUPPORT_4BIT__ 1 + +#define HAL_SDMMC_TRACE(...) +//#define HAL_SDMMC_TRACE TRACE +#define HAL_SDMMC_ASSERT(...) +//#define HAL_SDMMC_ASSERT ASSERT + +#define _SDMMC_CLOCK 52000000 + +#define _SDMMC_DMA_MINALIGN 32 + +#define _sdmmc_be32_to_cpu(x) \ + ((uint32_t)( \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) + +#define _SDMMC_DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#define _SDMMC_ROUND(a,b) (((a) + (b) - 1) & ~((b) - 1)) + +#define _SDMMC_PAD_COUNT(s, pad) (((s) - 1) / (pad) + 1) +#define _SDMMC_PAD_SIZE(s, pad) (_SDMMC_PAD_COUNT(s, pad) * pad) +#define _SDMMC_ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad) \ + char __##name[_SDMMC_ROUND(_SDMMC_PAD_SIZE((size) * sizeof(type), pad), align) + (align - 1)]; \ + type *name = (type *) ALIGN((uint32_t)__##name, align) + +#define _SDMMC_ALLOC_ALIGN_BUFFER(type, name, size, align) \ + _SDMMC_ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1) +#define _SDMMC_ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad) \ + _SDMMC_ALLOC_ALIGN_BUFFER_PAD(type, name, size, _SDMMC_DMA_MINALIGN, pad) +#define _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \ + _SDMMC_ALLOC_ALIGN_BUFFER(type, name, size, _SDMMC_DMA_MINALIGN) + +typedef struct block_dev_desc { + int if_type; /* type of the interface */ + int dev; /* device number */ + unsigned char part_type; /* partition type */ + unsigned char target; /* target SCSI ID */ + unsigned char lun; /* target LUN */ + unsigned char type; /* device type */ + unsigned char removable; /* removable device */ +#ifdef CONFIG_LBA48 + unsigned char lba48; /* device can use 48bit addr (ATA/ATAPI v7) */ +#endif + uint32_t lba; /* number of blocks */ + unsigned long blksz; /* block size */ + int log2blksz; /* for convenience: log2(blksz) */ + char vendor [40+1]; /* IDE model, SCSI Vendor */ + char product[20+1]; /* IDE Serial no, SCSI product */ + char revision[8+1]; /* firmware revision */ + void *priv; /* driver private struct pointer */ +} block_dev_desc_t; + +/* SD/MMC version bits; 8 flags, 8 major, 8 minor, 8 change */ +#define SD_VERSION_SD (1U << 31) +#define MMC_VERSION_MMC (1U << 30) + +#define MAKE_SDMMC_VERSION(a, b, c) \ + ((((uint32_t)(a)) << 16) | ((uint32_t)(b) << 8) | (uint32_t)(c)) +#define MAKE_SD_VERSION(a, b, c) \ + (SD_VERSION_SD | MAKE_SDMMC_VERSION(a, b, c)) +#define MAKE_MMC_VERSION(a, b, c) \ + (MMC_VERSION_MMC | MAKE_SDMMC_VERSION(a, b, c)) + +#define EXTRACT_SDMMC_MAJOR_VERSION(x) \ + (((uint32_t)(x) >> 16) & 0xff) +#define EXTRACT_SDMMC_MINOR_VERSION(x) \ + (((uint32_t)(x) >> 8) & 0xff) +#define EXTRACT_SDMMC_CHANGE_VERSION(x) \ + ((uint32_t)(x) & 0xff) + +#define SD_VERSION_3 MAKE_SD_VERSION(3, 0, 0) +#define SD_VERSION_2 MAKE_SD_VERSION(2, 0, 0) +#define SD_VERSION_1_0 MAKE_SD_VERSION(1, 0, 0) +#define SD_VERSION_1_10 MAKE_SD_VERSION(1, 10, 0) + +#define MMC_VERSION_UNKNOWN MAKE_MMC_VERSION(0, 0, 0) +#define MMC_VERSION_1_2 MAKE_MMC_VERSION(1, 2, 0) +#define MMC_VERSION_1_4 MAKE_MMC_VERSION(1, 4, 0) +#define MMC_VERSION_2_2 MAKE_MMC_VERSION(2, 2, 0) +#define MMC_VERSION_3 MAKE_MMC_VERSION(3, 0, 0) +#define MMC_VERSION_4 MAKE_MMC_VERSION(4, 0, 0) +#define MMC_VERSION_4_1 MAKE_MMC_VERSION(4, 1, 0) +#define MMC_VERSION_4_2 MAKE_MMC_VERSION(4, 2, 0) +#define MMC_VERSION_4_3 MAKE_MMC_VERSION(4, 3, 0) +#define MMC_VERSION_4_41 MAKE_MMC_VERSION(4, 4, 1) +#define MMC_VERSION_4_5 MAKE_MMC_VERSION(4, 5, 0) +#define MMC_VERSION_5_0 MAKE_MMC_VERSION(5, 0, 0) + +#define MMC_MODE_HS (1 << 0) +#define MMC_MODE_HS_52MHz (1 << 1) +#define MMC_MODE_4BIT (1 << 2) +#define MMC_MODE_8BIT (1 << 3) +#define MMC_MODE_SPI (1 << 4) +#define MMC_MODE_DDR_52MHz (1 << 5) + +#define SD_DATA_4BIT 0x00040000 + +#define IS_SD(x) ((x)->version & SD_VERSION_SD) +#define IS_MMC(x) ((x)->version & MMC_VERSION_MMC) + +#define MMC_DATA_READ 1 +#define MMC_DATA_WRITE 2 + +#define NO_CARD_ERR -16 /* No SD/MMC card inserted */ +#define UNUSABLE_ERR -17 /* Unusable Card */ +#define COMM_ERR -18 /* Communications Error */ +#define TIMEOUT -19 +#define SWITCH_ERR -20 /* Card reports failure to switch mode */ + +#define MMC_CMD_GO_IDLE_STATE 0 +#define MMC_CMD_SEND_OP_COND 1 +#define MMC_CMD_ALL_SEND_CID 2 +#define MMC_CMD_SET_RELATIVE_ADDR 3 +#define MMC_CMD_SET_DSR 4 +#define MMC_CMD_SWITCH 6 +#define MMC_CMD_SELECT_CARD 7 +#define MMC_CMD_SEND_EXT_CSD 8 +#define MMC_CMD_SEND_CSD 9 +#define MMC_CMD_SEND_CID 10 +#define MMC_CMD_STOP_TRANSMISSION 12 +#define MMC_CMD_SEND_STATUS 13 +#define MMC_CMD_SET_BLOCKLEN 16 +#define MMC_CMD_READ_SINGLE_BLOCK 17 +#define MMC_CMD_READ_MULTIPLE_BLOCK 18 +#define MMC_CMD_SET_BLOCK_COUNT 23 +#define MMC_CMD_WRITE_SINGLE_BLOCK 24 +#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25 +#define MMC_CMD_ERASE_GROUP_START 35 +#define MMC_CMD_ERASE_GROUP_END 36 +#define MMC_CMD_ERASE 38 +#define MMC_CMD_APP_CMD 55 +#define MMC_CMD_SPI_READ_OCR 58 +#define MMC_CMD_SPI_CRC_ON_OFF 59 +#define MMC_CMD_RES_MAN 62 + +#define MMC_CMD62_ARG1 0xefac62ec +#define MMC_CMD62_ARG2 0xcbaea7 + + +#define SD_CMD_SEND_RELATIVE_ADDR 3 +#define SD_CMD_SWITCH_FUNC 6 +#define SD_CMD_SEND_IF_COND 8 +#define SD_CMD_SWITCH_UHS18V 11 + +#define SD_CMD_APP_SET_BUS_WIDTH 6 +#define SD_CMD_ERASE_WR_BLK_START 32 +#define SD_CMD_ERASE_WR_BLK_END 33 +#define SD_CMD_APP_SEND_OP_COND 41 +#define SD_CMD_APP_SEND_SCR 51 + +/* SCR definitions in different words */ +#define SD_HIGHSPEED_BUSY 0x00020000 +#define SD_HIGHSPEED_SUPPORTED 0x00020000 + +#define OCR_BUSY 0x80000000 +#define OCR_HCS 0x40000000 +#define OCR_VOLTAGE_MASK 0x007FFF80 +#define OCR_ACCESS_MODE 0x60000000 + +#define SECURE_ERASE 0x80000000 + +#define MMC_STATUS_MASK (~0x0206BF7F) +#define MMC_STATUS_SWITCH_ERROR (1 << 7) +#define MMC_STATUS_RDY_FOR_DATA (1 << 8) +#define MMC_STATUS_CURR_STATE (0xf << 9) +#define MMC_STATUS_ERROR (1 << 19) + +#define MMC_STATE_PRG (7 << 9) + +#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ +#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ +#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ +#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ +#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */ +#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */ +#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */ +#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */ +#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */ +#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */ +#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */ +#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */ +#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */ +#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */ +#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ +#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ +#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ + +#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ +#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits in EXT_CSD byte + addressed by index which are + 1 in value field */ +#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits in EXT_CSD byte + addressed by index, which are + 1 in value field */ +#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target byte to value */ + +#define SD_SWITCH_CHECK 0 +#define SD_SWITCH_SWITCH 1 + +/* + * EXT_CSD fields + */ +#define EXT_CSD_ENH_START_ADDR 136 /* R/W */ +#define EXT_CSD_ENH_SIZE_MULT 140 /* R/W */ +#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ +#define EXT_CSD_PARTITION_SETTING 155 /* R/W */ +#define EXT_CSD_PARTITIONS_ATTRIBUTE 156 /* R/W */ +#define EXT_CSD_MAX_ENH_SIZE_MULT 157 /* R */ +#define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */ +#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ +#define EXT_CSD_WR_REL_PARAM 166 /* R */ +#define EXT_CSD_WR_REL_SET 167 /* R/W */ +#define EXT_CSD_RPMB_MULT 168 /* RO */ +#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ +#define EXT_CSD_BOOT_BUS_WIDTH 177 +#define EXT_CSD_PART_CONF 179 /* R/W */ +#define EXT_CSD_BUS_WIDTH 183 /* R/W */ +#define EXT_CSD_HS_TIMING 185 /* R/W */ +#define EXT_CSD_REV 192 /* RO */ +#define EXT_CSD_CARD_TYPE 196 /* RO */ +#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ +#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ +#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ +#define EXT_CSD_BOOT_MULT 226 /* RO */ + +/* + * EXT_CSD field definitions + */ + +#define EXT_CSD_CMD_SET_NORMAL (1 << 0) +#define EXT_CSD_CMD_SET_SECURE (1 << 1) +#define EXT_CSD_CMD_SET_CPSECURE (1 << 2) + +#define EXT_CSD_CARD_TYPE_26 (1 << 0) /* Card can run at 26MHz */ +#define EXT_CSD_CARD_TYPE_52 (1 << 1) /* Card can run at 52MHz */ +#define EXT_CSD_CARD_TYPE_DDR_1_8V (1 << 2) +#define EXT_CSD_CARD_TYPE_DDR_1_2V (1 << 3) +#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \ + | EXT_CSD_CARD_TYPE_DDR_1_2V) + +#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ +#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ +#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ +#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */ +#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */ + +#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) +#define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) +#define EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0) +#define EXT_CSD_PARTITION_ACCESS_DISABLE (0 << 0) + +#define EXT_CSD_BOOT_ACK(x) (x << 6) +#define EXT_CSD_BOOT_PART_NUM(x) (x << 3) +#define EXT_CSD_PARTITION_ACCESS(x) (x << 0) + +#define EXT_CSD_BOOT_BUS_WIDTH_MODE(x) (x << 3) +#define EXT_CSD_BOOT_BUS_WIDTH_RESET(x) (x << 2) +#define EXT_CSD_BOOT_BUS_WIDTH_WIDTH(x) (x) + +#define EXT_CSD_PARTITION_SETTING_COMPLETED (1 << 0) + +#define EXT_CSD_ENH_USR (1 << 0) /* user data area is enhanced */ +#define EXT_CSD_ENH_GP(x) (1 << ((x)+1)) /* GP part (x+1) is enhanced */ + +#define EXT_CSD_HS_CTRL_REL (1 << 0) /* host controlled WR_REL_SET */ + +#define EXT_CSD_WR_DATA_REL_USR (1 << 0) /* user data area WR_REL */ +#define EXT_CSD_WR_DATA_REL_GP(x) (1 << ((x)+1)) /* GP part (x+1) WR_REL */ + +#define R1_ILLEGAL_COMMAND (1 << 22) +#define R1_APP_CMD (1 << 5) + +#define MMC_RSP_PRESENT (1 << 0) +#define MMC_RSP_136 (1 << 1) /* 136 bit response */ +#define MMC_RSP_CRC (1 << 2) /* expect valid crc */ +#define MMC_RSP_BUSY (1 << 3) /* card may send busy */ +#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */ + +#define MMC_RSP_NONE (0) +#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) +#define MMC_RSP_R1b (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE| \ + MMC_RSP_BUSY) +#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) +#define MMC_RSP_R3 (MMC_RSP_PRESENT) +#define MMC_RSP_R4 (MMC_RSP_PRESENT) +#define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) +#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) +#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) + +#define MMCPART_NOAVAILABLE (0xff) +#define PART_ACCESS_MASK (0x7) +#define PART_SUPPORT (0x1) +#define ENHNCD_SUPPORT (0x2) +#define PART_ENH_ATTRIB (0x1f) + +/* Maximum block size for MMC */ +#define MMC_MAX_BLOCK_LEN 512 + +/* The number of MMC physical partitions. These consist of: + * boot partitions (2), general purpose partitions (4) in MMC v4.4. + */ +#define MMC_NUM_BOOT_PARTITION 2 +#define MMC_PART_RPMB 3 /* RPMB partition number */ + +struct mmc_cid { + unsigned long psn; + unsigned short oid; + uint8_t mid; + uint8_t prv; + uint8_t mdt; + char pnm[7]; +}; + +struct mmc_cmd { + u16 cmdidx; + uint32_t resp_type; + uint32_t cmdarg; + uint32_t response[4]; +}; + +struct mmc_data { + union { + char *dest; + const char *src; /* src buffers don't get written to */ + }; + uint32_t flags; + uint32_t blocks; + uint32_t blocksize; +}; + +/* forward decl. */ +struct mmc; + +struct mmc_ops { + int (*send_cmd)(struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data); + void (*set_ios)(struct mmc *mmc); + int (*init)(struct mmc *mmc); + int (*getcd)(struct mmc *mmc); + int (*getwp)(struct mmc *mmc); +}; + +struct mmc_config { + const struct mmc_ops *ops; + uint32_t host_caps; + uint32_t voltages; + uint32_t f_min; + uint32_t f_max; + uint32_t b_max; + uint8_t part_type; +}; + +/* TODO struct mmc should be in mmc_private but it's hard to fix right now */ +struct mmc { + const struct mmc_config *cfg; /* provided configuration */ + uint32_t version; + void *priv; + uint32_t has_init; + int high_capacity; + uint32_t bus_width; + uint32_t clock; + uint32_t card_caps; + uint32_t ocr; + uint32_t dsr; + uint32_t dsr_imp; + uint32_t scr[2]; + uint32_t csd[4]; + uint32_t cid[4]; + u16 rca; + u8 part_support; + u8 part_attr; + u8 wr_rel_set; + char part_config; + char part_num; + uint32_t tran_speed; + uint32_t read_bl_len; + uint32_t write_bl_len; + uint32_t erase_grp_size; /* in 512-byte sectors */ + uint32_t hc_wp_grp_size; /* in 512-byte sectors */ + uint64_t capacity; + uint64_t capacity_user; + uint64_t capacity_boot; + uint64_t capacity_rpmb; + uint64_t capacity_gp[4]; + uint64_t enh_user_start; + uint64_t enh_user_size; + block_dev_desc_t block_dev; + char op_cond_pending; /* 1 if we are waiting on an op_cond command */ + char init_in_progress; /* 1 if we have done mmc_start_init() */ + char preinit; /* start init as early as possible */ + int ddr_mode; +}; + +struct mmc_hwpart_conf { + struct { + uint32_t enh_start; /* in 512-byte sectors */ + uint32_t enh_size; /* in 512-byte sectors, if 0 no enh area */ + unsigned wr_rel_change : 1; + unsigned wr_rel_set : 1; + } user; + struct { + uint32_t size; /* in 512-byte sectors */ + unsigned enhanced : 1; + unsigned wr_rel_change : 1; + unsigned wr_rel_set : 1; + } gp_part[4]; +}; + +enum mmc_hwpart_conf_mode { + MMC_HWPART_CONF_CHECK, + MMC_HWPART_CONF_SET, + MMC_HWPART_CONF_COMPLETE, +}; + +struct sdmmcip_host { + void *ioaddr; + unsigned int quirks; + unsigned int caps; + unsigned int version; + unsigned int clock; + unsigned int bus_hz; + unsigned int div; + int dev_index; + int dev_id; + int buswidth; + uint32_t fifoth_val; + bool detect_enb; + struct mmc *mmc; + void *priv; + + void (*clksel)(struct sdmmcip_host *host); + void (*board_init)(struct sdmmcip_host *host); + unsigned int (*get_mmc_clk)(struct sdmmcip_host *host); + + struct mmc_config cfg; + +#ifdef HAL_SDMMC_USE_DMA + /* TODO : os and non-os condition */ + uint8_t dma_ch; + volatile uint32_t sdmmc_dma_lock; + HAL_DMA_IRQ_HANDLER_T tx_dma_handler; + HAL_DMA_IRQ_HANDLER_T rx_dma_handler; +#endif +}; + +struct sdmmcip_idmac { + uint32_t flags; + uint32_t cnt; + uint32_t addr; + uint32_t next_addr; +}; + +static void hal_sdmmc_delay(uint32_t ms); + +static HAL_SDMMC_DELAY_FUNC sdmmc_delay = NULL; + +static inline void sdmmcip_writel(struct sdmmcip_host *host, int reg, uint32_t val) +{ + *((volatile uint32_t *)(host->ioaddr + reg)) = val; +} + +static inline uint32_t sdmmcip_readl(struct sdmmcip_host *host, int reg) +{ + return *((volatile uint32_t *)(host->ioaddr + reg)); +} + +#ifdef CONFIG_MMC_SPI +#define sdmmc_host_is_spi(mmc) ((mmc)->cfg->host_caps & MMC_MODE_SPI) +#else +#define sdmmc_host_is_spi(mmc) 0 +#endif + +#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT +#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535 +#endif + +static void (*sdmmc_detected_callback)(uint8_t) = NULL; +static uint32_t sdmmc_ip_base[HAL_SDMMC_ID_NUM] = {SDMMC_BASE, }; +static struct sdmmcip_host sdmmc_host[HAL_SDMMC_ID_NUM]; +static struct mmc sdmmc_devices[HAL_SDMMC_ID_NUM]; +//static const char * const invalid_id = "Invalid SDMMC ID: %d\n"; + +#ifdef HAL_SDMMC_USE_DMA +static void sdmmcip0_ext_dma_tx_handler(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli); +static void sdmmcip0_ext_dma_rx_handler(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli); +static HAL_DMA_IRQ_HANDLER_T sdmmcip_ext_dma_irq_handlers[HAL_SDMMC_ID_NUM*2] = { + sdmmcip0_ext_dma_tx_handler, sdmmcip0_ext_dma_rx_handler, +}; +#endif + +uint32_t _sdmmc_div64_32(uint64_t *n, uint32_t base) +{ + uint64_t rem = *n; + uint64_t b = base; + uint64_t res, d = 1; + uint32_t high = rem >> 32; + + /* Reduce the thing a bit first */ + res = 0; + if (high >= base) { + high /= base; + res = (uint64_t) high << 32; + rem -= (uint64_t) (high*base) << 32; + } + + while ((int64_t)b > 0 && b < rem) { + b = b+b; + d = d+d; + } + + do { + if (rem >= b) { + rem -= b; + res += d; + } + b >>= 1; + d >>= 1; + } while (d); + + *n = res; + return rem; +} + + +/* The unnecessary pointer compare is there + * * to check for type safety (n must be 64bit) + * */ +# define _sdmmc_do_div(n,base) ({ \ + uint32_t __base = (base); \ + uint32_t __rem; \ + (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ + if (((n) >> 32) == 0) { \ + __rem = (uint32_t)(n) % __base; \ + (n) = (uint32_t)(n) / __base; \ + } else \ + __rem = _sdmmc_div64_32(&(n), __base); \ + __rem; \ + }) + +/* Wrapper for _sdmmc_do_div(). Doesn't modify dividend and returns + * * the result, not reminder. + * */ +static inline uint64_t _sdmmc_lldiv(uint64_t dividend, uint32_t divisor) +{ + uint64_t __res = dividend; + _sdmmc_do_div(__res, divisor); + return(__res); +} + + +static void mmc_udelay(int cnt) +{ + volatile uint32_t i = 0, c = 0; + for(i = 0; i < cnt; ++i) { + c++; + __asm("nop"); + } +} + + +static int sdmmcip_wait_reset(struct sdmmcip_host *host, uint32_t value) +{ + uint32_t ctrl; + unsigned long timeout = 1000; + + sdmmcip_writel(host, SDMMCIP_REG_CTRL, value); + + while (timeout--) { + ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); + if (!(ctrl & SDMMCIP_REG_RESET_ALL)) + return 1; + } + return 0; +} + +#ifdef HAL_SDMMC_USE_DMA +static void sdmmcip0_ext_dma_tx_handler(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + uint32_t ip_raw_int_status = 0; + struct sdmmcip_host *host = &sdmmc_host[HAL_SDMMC_ID_0]; + HAL_SDMMC_TRACE(2,"%s:%d\n", __func__, __LINE__); + ip_raw_int_status = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); + HAL_SDMMC_TRACE(3,"%s:%d, tx ip_raw_int_status 0x%x\n", __func__, __LINE__, ip_raw_int_status); + if (ip_raw_int_status & (SDMMCIP_REG_DATA_ERR|SDMMCIP_REG_DATA_TOUT)) { + HAL_SDMMC_TRACE(3,"%s:%d, sdmmcip0 tx dma error 0x%x\n", __func__, __LINE__, ip_raw_int_status); + } + + /* TODO : os and non-os condition */ + host->sdmmc_dma_lock = 0; +} + +static void sdmmcip0_ext_dma_rx_handler(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + uint32_t ip_raw_int_status = 0; + struct sdmmcip_host *host = &sdmmc_host[HAL_SDMMC_ID_0]; + HAL_SDMMC_TRACE(2,"%s:%d\n", __func__, __LINE__); + ip_raw_int_status = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); + HAL_SDMMC_TRACE(3,"%s:%d, ip_raw_int_status 0x%x\n", __func__, __LINE__, ip_raw_int_status); + if (ip_raw_int_status & (SDMMCIP_REG_DATA_ERR|SDMMCIP_REG_DATA_TOUT)) { + HAL_SDMMC_TRACE(3,"%s:%d, sdmmcip0 rx dma error 0x%x\n", __func__, __LINE__, ip_raw_int_status); + } + + /* TODO : os and non-os condition */ + host->sdmmc_dma_lock = 0; +} +#endif + +static void sdmmcip_prepare_data(struct sdmmcip_host *host, + struct mmc_data *data, + struct sdmmcip_idmac *cur_idmac, + void *bounce_buffer) +{ +#ifdef HAL_SDMMC_USE_DMA + uint32_t ctrl = 0; + struct HAL_DMA_CH_CFG_T dma_cfg; +#endif + sdmmcip_writel(host, SDMMCIP_REG_BLKSIZ, data->blocksize); + sdmmcip_writel(host, SDMMCIP_REG_BYTCNT, data->blocksize * data->blocks); + + + /* use dma */ +#ifdef HAL_SDMMC_USE_DMA + + HAL_SDMMC_TRACE(0,"sdmmc use dma\n"); + /* enable sdmmcip e-dma */ + ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); + ctrl |= (SDMMCIP_REG_DMA_EN); + sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); + + host->sdmmc_dma_lock = 1; + + memset(&dma_cfg, 0, sizeof(dma_cfg)); + if (data->flags & MMC_DATA_READ) { + HAL_SDMMC_TRACE(0,"sdmmc use dma read\n"); + dma_cfg.dst = (uint32_t)data->dest; + //HAL_SDMMC_TRACE(2,"sddma :len %d, buf 0x%x\n", data->blocksize*data->blocks, dma_cfg.dst); + if ((dma_cfg.dst % 4) != 0) { + dma_cfg.dst_width = HAL_DMA_WIDTH_BYTE; + } + else { + dma_cfg.dst_width = HAL_DMA_WIDTH_WORD; + } + dma_cfg.dst_bsize = HAL_DMA_BSIZE_1; + dma_cfg.dst_periph = 0; // useless + //dma_cfg.dst_width = HAL_DMA_WIDTH_WORD; + dma_cfg.handler = host->rx_dma_handler; + dma_cfg.src_bsize = HAL_DMA_BSIZE_1; + dma_cfg.src_periph = HAL_GPDMA_SDMMC; + dma_cfg.src_tsize = data->blocks*data->blocksize/4; + HAL_SDMMC_TRACE(1,"sdmmc use dma tsize %d\n", dma_cfg.src_tsize); + dma_cfg.src_width = HAL_DMA_WIDTH_WORD; + dma_cfg.try_burst = 1; + dma_cfg.type = HAL_DMA_FLOW_P2M_DMA; + dma_cfg.src = (uint32_t)0; // useless + dma_cfg.ch = hal_gpdma_get_chan(dma_cfg.src_periph, HAL_DMA_HIGH_PRIO); + HAL_SDMMC_TRACE(1,"sdmmc use dma get ch %d\n", dma_cfg.ch); + } + else { + HAL_SDMMC_TRACE(0,"sdmmc use dma write\n"); + dma_cfg.dst = 0; // useless + dma_cfg.dst_bsize = HAL_DMA_BSIZE_1; + dma_cfg.dst_periph = HAL_GPDMA_SDMMC; + dma_cfg.dst_width = HAL_DMA_WIDTH_WORD; + dma_cfg.handler = host->tx_dma_handler; + dma_cfg.src_bsize = HAL_DMA_BSIZE_1; + dma_cfg.src_periph = 0; // useless + //dma_cfg.src_tsize = data->blocks*data->blocksize/4; + HAL_SDMMC_TRACE(1,"sdmmc use dma tsize %d\n", dma_cfg.src_tsize); + //dma_cfg.src_width = HAL_DMA_WIDTH_WORD; + dma_cfg.try_burst = 1; + dma_cfg.type = HAL_DMA_FLOW_M2P_DMA; + dma_cfg.src = (uint32_t)data->src; + //uart_printf("sddma :len %d, buf 0x%x\n", data->blocksize*data->blocks, dma_cfg.src); + if ((dma_cfg.src % 4) != 0) { + dma_cfg.src_width = HAL_DMA_WIDTH_BYTE; + dma_cfg.src_tsize = data->blocks*data->blocksize; + } + else { + dma_cfg.src_width = HAL_DMA_WIDTH_WORD; + dma_cfg.src_tsize = data->blocks*data->blocksize/4; + } + dma_cfg.ch = hal_gpdma_get_chan(dma_cfg.dst_periph, HAL_DMA_HIGH_PRIO); + HAL_SDMMC_TRACE(1,"sdmmc use dma get ch %d\n", dma_cfg.ch); + + //uart_printf("%s:%d src 0x%x\n", __func__, __LINE__, dma_cfg.src); + } + + host->dma_ch = dma_cfg.ch; + + hal_gpdma_start(&dma_cfg); +#endif +} + +static int sdmmcip_set_transfer_mode(struct sdmmcip_host *host, + struct mmc_data *data) +{ + unsigned long mode; + + mode = SDMMCIP_REG_CMD_DATA_EXP; + if (data->flags & MMC_DATA_WRITE) + mode |= SDMMCIP_REG_CMD_RW; + + return mode; +} + +static int sdmmcip_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + int ret = 0; + int flags = 0, i; + uint32_t retry = 1000000; + uint32_t mask, ctrl; + int busy_tmo = MS_TO_TICKS(1000), busy_t = 0; +#ifndef HAL_SDMMC_USE_DMA + uint32_t status = 0, fifo_data = 0; +#endif + struct sdmmcip_host *host = mmc->priv; + + busy_t = hal_sys_timer_get(); + + while ((sdmmcip_readl(host, SDMMCIP_REG_STATUS) & SDMMCIP_REG_BUSY) && hal_sys_timer_get()<(busy_t+busy_tmo)) { + HAL_SDMMC_TRACE(0,"[sdmmc]busy\n"); + } + + sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_CD); + + if (data) { + sdmmcip_prepare_data(host, data, 0, 0); + } + + sdmmcip_writel(host, SDMMCIP_REG_CMDARG, cmd->cmdarg); + + if (data) + flags = sdmmcip_set_transfer_mode(host, data); + + if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY)) + return -1; + + if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) + flags |= SDMMCIP_REG_CMD_ABORT_STOP; + else + flags |= SDMMCIP_REG_CMD_PRV_DAT_WAIT; + + if (cmd->resp_type & MMC_RSP_PRESENT) { + flags |= SDMMCIP_REG_CMD_RESP_EXP; + if (cmd->resp_type & MMC_RSP_136) + flags |= SDMMCIP_REG_CMD_RESP_LENGTH; + } + + if (cmd->resp_type & MMC_RSP_CRC) + flags |= SDMMCIP_REG_CMD_CHECK_CRC; + + flags |= (cmd->cmdidx | SDMMCIP_REG_CMD_START | SDMMCIP_REG_CMD_USE_HOLD_REG); + + sdmmcip_writel(host, SDMMCIP_REG_CMD, flags); + + for (i = 0; i < retry; i++) { + mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); + if (mask & SDMMCIP_REG_INTMSK_CDONE) { + if (!data) + sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_CDONE); + break; + } + } + + if (i == retry) { + HAL_SDMMC_TRACE(1,"%s: Timeout.\n", __func__); + return TIMEOUT; + } + + if (mask & SDMMCIP_REG_INTMSK_RTO) { + /* + * Timeout here is not necessarily fatal. (e)MMC cards + * will splat here when they receive CMD55 as they do + * not support this command and that is exactly the way + * to tell them apart from SD cards. Thus, this output + * below shall be TRACE(). eMMC cards also do not favor + * CMD8, please keep that in mind. + */ + HAL_SDMMC_TRACE(1,"%s: Response Timeout.\n", __func__); + return TIMEOUT; + } else if (mask & SDMMCIP_REG_INTMSK_RE) { + HAL_SDMMC_TRACE(1,"%s: Response Error.\n", __func__); + return -1; + } + + + if (cmd->resp_type & MMC_RSP_PRESENT) { + if (cmd->resp_type & MMC_RSP_136) { + cmd->response[0] = sdmmcip_readl(host, SDMMCIP_REG_RESP3); + cmd->response[1] = sdmmcip_readl(host, SDMMCIP_REG_RESP2); + cmd->response[2] = sdmmcip_readl(host, SDMMCIP_REG_RESP1); + cmd->response[3] = sdmmcip_readl(host, SDMMCIP_REG_RESP0); + } else { + cmd->response[0] = sdmmcip_readl(host, SDMMCIP_REG_RESP0); + } + } + +#ifndef HAL_SDMMC_USE_DMA + if (data) { + i = 0; + while(1) { + mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); + if (mask & (SDMMCIP_REG_DATA_ERR | SDMMCIP_REG_DATA_TOUT)) { + HAL_SDMMC_TRACE(1,"%s: READ DATA ERROR!\n", __func__); + ret = -1; + goto out; + } + status = sdmmcip_readl(host, SDMMCIP_REG_STATUS); + if (data->flags == MMC_DATA_READ) { + if (status & SDMMCIP_REG_FIFO_COUNT_MASK) { + fifo_data = sdmmcip_readl(host, SDMMCIP_REG_FIFO_OFFSET); + //HAL_SDMMC_TRACE(3,"%s: count %d, read -> 0x%x\n", __func__, i, fifo_data); + /* FIXME: now we just deal with 32bit width fifo one time */ + if (i < data->blocks*data->blocksize) { + memcpy(data->dest + i, &fifo_data, sizeof(fifo_data)); + i += sizeof(fifo_data); + } + else { + HAL_SDMMC_TRACE(1,"%s: fifo data too much\n", __func__); + ret = -1; + goto out; + } + } + /* nothing to read from fifo and DTO is set */ + else if(mask & SDMMCIP_REG_INTMSK_DTO) { + if(i != data->blocks*data->blocksize) { + HAL_SDMMC_TRACE(3,"%s: need to read %d, actually read %d\n", __func__, data->blocks*data->blocksize, i); + } + ret = 0; + goto out; + } + } + else { + /* nothing to write to fifo and DTO is set */ + if(mask & SDMMCIP_REG_INTMSK_DTO) { + /* check if number is right */ + if(i != data->blocks*data->blocksize) { + HAL_SDMMC_TRACE(3,"%s: need to write %d, actually written %d\n", __func__, data->blocks*data->blocksize, i); + } + ret = 0; + goto out; + } + else if (!(status & SDMMCIP_REG_FIFO_COUNT_MASK)) { + /* FIXME: now we just deal with 32bit width fifo one time */ + if(i < data->blocks*data->blocksize) { + memcpy(&fifo_data, data->src + i, sizeof(fifo_data)); + //HAL_SDMMC_TRACE(4,"%s: fifo %d, count %d, write -> 0x%x\n", __func__, ((status & SDMMCIP_REG_FIFO_COUNT_MASK)>>SDMMCIP_REG_FIFO_COUNT_SHIFT), i, fifo_data); + i += sizeof(fifo_data); + sdmmcip_writel(host, SDMMCIP_REG_FIFO_OFFSET, fifo_data); + } + else { + HAL_SDMMC_TRACE(1,"%s: no data to write to fifo, do nothing\n", __func__); + } + } + } + } + } +#endif + +#ifdef HAL_SDMMC_USE_DMA + while (host->sdmmc_dma_lock); + ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); + ctrl |= SDMMCIP_REG_CTRL_DMA_RESET; + sdmmcip_wait_reset(host, ctrl); + if (data) { + hal_gpdma_free_chan(host->dma_ch); +#if 0 + if (data->flags & MMC_DATA_READ) { + for (int ccc = 0; ccc < 400; ++ccc) { + HAL_SDMMC_TRACE(2,"%d-0x%x ", ccc, data->dest[ccc]); + } + HAL_SDMMC_TRACE(0,"\n"); + } +#endif + } +#endif + +#ifndef HAL_SDMMC_USE_DMA +out: +#endif + + mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); + sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, mask&(~SDMMCIP_REG_INTMSK_CD)); + + ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); + ctrl &= ~(SDMMCIP_REG_DMA_EN); + sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); + + mmc_udelay(100); + + return ret; +} + +static int sdmmcip_setup_bus(struct sdmmcip_host *host, uint32_t freq) +{ + uint32_t div, status; + int timeout = 10000; + unsigned long sclk; + + if ((freq == host->clock) || (freq == 0)) + return 0; + /* + * If host->get_mmc_clk isn't defined, + * then assume that host->bus_hz is source clock value. + * host->bus_hz should be set by user. + */ + if (host->get_mmc_clk) + sclk = host->get_mmc_clk(host); + else if (host->bus_hz) + sclk = host->bus_hz; + else { + HAL_SDMMC_TRACE(1,"%s: Didn't get source clock value.\n", __func__); + return -EINVAL; + } + + if (sclk == freq) + div = 0; /* bypass mode */ + else + div = _SDMMC_DIV_ROUND_UP(sclk, 2 * freq); + + HAL_SDMMC_TRACE(4,"%s : freq %d, sclk %ld, div %d\n", __func__, freq, sclk, div); + + sdmmcip_writel(host, SDMMCIP_REG_CLKENA, 0); + //sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0); + //sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x03000000); + //sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x11000000); + + sdmmcip_writel(host, SDMMCIP_REG_CLKDIV, div); + sdmmcip_writel(host, SDMMCIP_REG_CMD, SDMMCIP_REG_CMD_PRV_DAT_WAIT | + SDMMCIP_REG_CMD_UPD_CLK | SDMMCIP_REG_CMD_START); + + do { + status = sdmmcip_readl(host, SDMMCIP_REG_CMD); + if (timeout-- < 0) { + HAL_SDMMC_TRACE(1,"%s: Timeout!\n", __func__); + return -ETIMEDOUT; + } + } while (status & SDMMCIP_REG_CMD_START); + + sdmmcip_writel(host, SDMMCIP_REG_CLKENA, SDMMCIP_REG_CLKEN_ENABLE | + SDMMCIP_REG_CLKEN_LOW_PWR); + //sdmmcip_writel(host, SDMMCIP_REG_CLKENA, SDMMCIP_REG_CLKEN_ENABLE); + + sdmmcip_writel(host, SDMMCIP_REG_CMD, SDMMCIP_REG_CMD_PRV_DAT_WAIT | + SDMMCIP_REG_CMD_UPD_CLK | SDMMCIP_REG_CMD_START); + + timeout = 10000; + do { + status = sdmmcip_readl(host, SDMMCIP_REG_CMD); + if (timeout-- < 0) { + HAL_SDMMC_TRACE(1,"%s: Timeout!\n", __func__); + return -ETIMEDOUT; + } + } while (status & SDMMCIP_REG_CMD_START); + + host->clock = freq; + + return 0; +} + +static void sdmmcip_set_ios(struct mmc *mmc) +{ + struct sdmmcip_host *host = (struct sdmmcip_host *)mmc->priv; + uint32_t ctype, regs; + + HAL_SDMMC_TRACE(2,"Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock); + + sdmmcip_setup_bus(host, mmc->clock); + + switch (mmc->bus_width) { + case 8: + ctype = SDMMCIP_REG_CTYPE_8BIT; + break; + case 4: + ctype = SDMMCIP_REG_CTYPE_4BIT; + break; + default: + ctype = SDMMCIP_REG_CTYPE_1BIT; + break; + } + + sdmmcip_writel(host, SDMMCIP_REG_CTYPE, ctype); + + regs = sdmmcip_readl(host, SDMMCIP_REG_UHS_REG); + if (mmc->ddr_mode) + regs |= SDMMCIP_REG_DDR_MODE; + else + regs &= ~SDMMCIP_REG_DDR_MODE; + + sdmmcip_writel(host, SDMMCIP_REG_UHS_REG, regs); + + if (host->clksel) + host->clksel(host); +} + +static int sdmmcip_init(struct mmc *mmc) +{ + struct sdmmcip_host *host = mmc->priv; + + if (host->board_init) + host->board_init(host); + + HAL_SDMMC_TRACE(2,"host->ioaddr %x, SDMMCIP_REG_PWREN %x\n", host->ioaddr, SDMMCIP_REG_PWREN); + sdmmcip_writel(host, SDMMCIP_REG_PWREN, 1); + + if (!sdmmcip_wait_reset(host, SDMMCIP_REG_RESET_ALL)) { + HAL_SDMMC_TRACE(2,"%s[%d] Fail-reset!!\n", __func__, __LINE__); + return -1; + } + + /* Enumerate at 400KHz */ + sdmmcip_setup_bus(host, mmc->cfg->f_min); + + if (host->detect_enb){ + sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_ALL&(~SDMMCIP_REG_INTMSK_CD)); + sdmmcip_writel(host, SDMMCIP_REG_INTMASK, SDMMCIP_REG_INTMSK_CD); + sdmmcip_writel(host, SDMMCIP_REG_CTRL, SDMMCIP_REG_INT_EN); + }else{ + sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_ALL); + sdmmcip_writel(host, SDMMCIP_REG_INTMASK, ~SDMMCIP_REG_INTMSK_ALL); + } + + sdmmcip_writel(host, SDMMCIP_REG_TMOUT, 0xFFFFFFFF); + + sdmmcip_writel(host, SDMMCIP_REG_IDINTEN, 0); + sdmmcip_writel(host, SDMMCIP_REG_BMOD, 1); + + sdmmcip_writel(host, SDMMCIP_REG_FIFOTH, host->fifoth_val); + + sdmmcip_writel(host, SDMMCIP_REG_CLKENA, 0); + //sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0); + //sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x03000000); + //sdmmcip_writel(host, SDMMCIP_REG_CLKSRC, 0x11000000); + + sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 0); + mmc_udelay(1000); + sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 1); + mmc_udelay(1000); + mmc_udelay(1000); + sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 0); + //sdmmcip_writel(host, SDMMCIP_REG_RESET_CARD, 1); + + return 0; +} + +static const struct mmc_ops sdmmcip_ops = { + .send_cmd = sdmmcip_send_cmd, + .set_ios = sdmmcip_set_ios, + .init = sdmmcip_init, +}; + +int board_mmc_getcd(struct mmc *mmc) +{ + return -1; +} + +int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) +{ + int ret; + + int i; + uint8_t *ptr; + + HAL_SDMMC_TRACE(1,"CMD_SEND:%d\n", cmd->cmdidx); + HAL_SDMMC_TRACE(1,"\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg); + ret = mmc->cfg->ops->send_cmd(mmc, cmd, data); + HAL_SDMMC_TRACE(0,"send cmd end..."); + switch (cmd->resp_type) { + case MMC_RSP_NONE: + HAL_SDMMC_TRACE(0,"\t\tMMC_RSP_NONE\n"); + break; + case MMC_RSP_R1: + HAL_SDMMC_TRACE(1,"\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n", + cmd->response[0]); + break; + case MMC_RSP_R1b: + HAL_SDMMC_TRACE(1,"\t\tMMC_RSP_R1b\t\t 0x%08X \n", + cmd->response[0]); + break; + case MMC_RSP_R2: + HAL_SDMMC_TRACE(1,"\t\tMMC_RSP_R2\t\t 0x%08X \n", + cmd->response[0]); + HAL_SDMMC_TRACE(1,"\t\t \t\t 0x%08X \n", + cmd->response[1]); + HAL_SDMMC_TRACE(1,"\t\t \t\t 0x%08X \n", + cmd->response[2]); + HAL_SDMMC_TRACE(1,"\t\t \t\t 0x%08X \n", + cmd->response[3]); + HAL_SDMMC_TRACE(0,"\n"); + HAL_SDMMC_TRACE(0,"\t\t\t\t\tDUMPING DATA\n"); + for (i = 0; i < 4; i++) { + int j; + HAL_SDMMC_TRACE(1,"\t\t\t\t\t%03d - ", i*4); + ptr = (uint8_t *)&cmd->response[i]; + ptr += 3; + for (j = 0; j < 4; j++) + HAL_SDMMC_TRACE(1,"%02X ", *ptr--); + HAL_SDMMC_TRACE(0,"\n"); + } + break; + case MMC_RSP_R3: + HAL_SDMMC_TRACE(1,"\t\tMMC_RSP_R3,4\t\t 0x%08X \n", + cmd->response[0]); + break; + default: + HAL_SDMMC_TRACE(0,"\t\tERROR MMC rsp not supported\n"); + break; + } + return ret; +} + +int mmc_send_status(struct mmc *mmc, int timeout) +{ + struct mmc_cmd cmd; + int err, retries = 5; + int POSSIBLY_UNUSED status; + + cmd.cmdidx = MMC_CMD_SEND_STATUS; + cmd.resp_type = MMC_RSP_R1; + if (!sdmmc_host_is_spi(mmc)) + cmd.cmdarg = mmc->rca << 16; + + while (1) { + err = mmc_send_cmd(mmc, &cmd, NULL); + if (!err) { + if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) && + (cmd.response[0] & MMC_STATUS_CURR_STATE) != + MMC_STATE_PRG) + break; + else if (cmd.response[0] & MMC_STATUS_MASK) { + return COMM_ERR; + } + } else if (--retries < 0) + return err; + + if (timeout-- <= 0) + break; + + mmc_udelay(1000); + } + + status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9; + HAL_SDMMC_TRACE(1,"CURR STATE:%d\n", status); + if (timeout <= 0) { + return TIMEOUT; + } + if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR) + return SWITCH_ERR; + + return 0; +} + +int mmc_set_blocklen(struct mmc *mmc, int len) +{ + struct mmc_cmd cmd; + + if (mmc->ddr_mode) + return 0; + + cmd.cmdidx = MMC_CMD_SET_BLOCKLEN; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = len; + + return mmc_send_cmd(mmc, &cmd, NULL); +} + +struct mmc *find_mmc_device(int dev_num) +{ + return &sdmmc_devices[dev_num]; +} + +static int mmc_read_blocks(struct mmc *mmc, void *dst, uint32_t start, + uint32_t blkcnt) +{ + struct mmc_cmd cmd; + struct mmc_data data; + + if (blkcnt > 1) + cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; + else + cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK; + + if (mmc->high_capacity) + cmd.cmdarg = start; + else + cmd.cmdarg = start * mmc->read_bl_len; + + cmd.resp_type = MMC_RSP_R1; + + data.dest = dst; + data.blocks = blkcnt; + data.blocksize = mmc->read_bl_len; + data.flags = MMC_DATA_READ; + + if (mmc_send_cmd(mmc, &cmd, &data)) + return 0; + + if (blkcnt > 1) { + cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; + cmd.cmdarg = 0; + cmd.resp_type = MMC_RSP_R1b; + if (mmc_send_cmd(mmc, &cmd, NULL)) { + return 0; + } + } + + return blkcnt; +} + +static unsigned long mmc_bread(int dev_num, uint32_t start, uint32_t blkcnt, void *dst) +{ + uint32_t cur, blocks_todo = blkcnt; + + if (blkcnt == 0) + return 0; + + struct mmc *mmc = find_mmc_device(dev_num); + if (!mmc) + return 0; + + if ((start + blkcnt) > mmc->block_dev.lba) { + return 0; + } + + if (mmc_set_blocklen(mmc, mmc->read_bl_len)) + return 0; + + do { + cur = (blocks_todo > mmc->cfg->b_max) ? + mmc->cfg->b_max : blocks_todo; + if(mmc_read_blocks(mmc, dst, start, cur) != cur) + return 0; + blocks_todo -= cur; + start += cur; + dst += cur * mmc->read_bl_len; + } while (blocks_todo > 0); + + return blkcnt; +} + +static unsigned long mmc_erase_t(struct mmc *mmc, unsigned long start, uint32_t blkcnt) +{ + struct mmc_cmd cmd; + unsigned long end; + int err, start_cmd, end_cmd; + + if (mmc->high_capacity) { + end = start + blkcnt - 1; + } else { + end = (start + blkcnt - 1) * mmc->write_bl_len; + start *= mmc->write_bl_len; + } + + if (IS_SD(mmc)) { + start_cmd = SD_CMD_ERASE_WR_BLK_START; + end_cmd = SD_CMD_ERASE_WR_BLK_END; + } else { + start_cmd = MMC_CMD_ERASE_GROUP_START; + end_cmd = MMC_CMD_ERASE_GROUP_END; + } + + cmd.cmdidx = start_cmd; + cmd.cmdarg = start; + cmd.resp_type = MMC_RSP_R1; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + goto err_out; + + cmd.cmdidx = end_cmd; + cmd.cmdarg = end; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + goto err_out; + + cmd.cmdidx = MMC_CMD_ERASE; + cmd.cmdarg = SECURE_ERASE; + cmd.resp_type = MMC_RSP_R1b; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + goto err_out; + + return 0; + +err_out: + //puts("mmc erase failed\n"); + return err; +} + +unsigned long mmc_berase(int dev_num, uint32_t start, uint32_t blkcnt) +{ + int err = 0; + struct mmc *mmc = find_mmc_device(dev_num); + uint32_t blk = 0, blk_r = 0; + int timeout = 1000; + + if (!mmc) + return -1; + + if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size)) + //printf("\n\nCaution! Your devices Erase group is 0x%x\n" + // "The erase range would be change to " + // "0x" LBAF "~0x" LBAF "\n\n", + // mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1), + // ((start + blkcnt + mmc->erase_grp_size) + // & ~(mmc->erase_grp_size - 1)) - 1); + + while (blk < blkcnt) { + blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? + mmc->erase_grp_size : (blkcnt - blk); + err = mmc_erase_t(mmc, start + blk, blk_r); + if (err) + break; + + blk += blk_r; + + /* Waiting for the ready status */ + if (mmc_send_status(mmc, timeout)) + return 0; + } + + return blk; +} + +static unsigned long mmc_write_blocks(struct mmc *mmc, uint32_t start, + uint32_t blkcnt, const void *src) +{ + struct mmc_cmd cmd; + struct mmc_data data; + int timeout = 1000; + + if ((start + blkcnt) > mmc->block_dev.lba) { + return 0; + } + + if (blkcnt == 0) + return 0; + else if (blkcnt == 1) + cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK; + else + cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; + + if (mmc->high_capacity) + cmd.cmdarg = start; + else + cmd.cmdarg = start * mmc->write_bl_len; + + cmd.resp_type = MMC_RSP_R1; + + data.src = src; + data.blocks = blkcnt; + data.blocksize = mmc->write_bl_len; + data.flags = MMC_DATA_WRITE; + + if (mmc_send_cmd(mmc, &cmd, &data)) { + HAL_SDMMC_TRACE(0,"mmc write failed\n"); + return 0; + } + + /* SPI multiblock writes terminate using a special + * token, not a STOP_TRANSMISSION request. + */ + if (!sdmmc_host_is_spi(mmc) && blkcnt > 1) { + cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; + cmd.cmdarg = 0; + cmd.resp_type = MMC_RSP_R1b; + if (mmc_send_cmd(mmc, &cmd, NULL)) { + HAL_SDMMC_TRACE(0,"mmc fail to send stop cmd\n"); + return 0; + } + } + + /* Waiting for the ready status */ + if (mmc_send_status(mmc, timeout)) + return 0; + + return blkcnt; +} + +unsigned long mmc_bwrite(int dev_num, uint32_t start, uint32_t blkcnt, const void *src) +{ + uint32_t cur, blocks_todo = blkcnt; + + struct mmc *mmc = find_mmc_device(dev_num); + if (!mmc) + return 0; + + if (mmc_set_blocklen(mmc, mmc->write_bl_len)) + return 0; + + do { + cur = (blocks_todo > mmc->cfg->b_max) ? + mmc->cfg->b_max : blocks_todo; + if (mmc_write_blocks(mmc, start, cur, src) != cur) + return 0; + blocks_todo -= cur; + start += cur; + src += cur * mmc->write_bl_len; + } while (blocks_todo > 0); + + return blkcnt; +} + +static int mmc_go_idle(struct mmc *mmc) +{ + struct mmc_cmd cmd; + int err; + + mmc_udelay(1000); + + cmd.cmdidx = MMC_CMD_GO_IDLE_STATE; + cmd.cmdarg = 0; + cmd.resp_type = MMC_RSP_NONE; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + + mmc_udelay(2000); + + return 0; +} + +static int sd_send_op_cond(struct mmc *mmc) +{ + int timeout = 1000; + int err; + struct mmc_cmd cmd; + + while (1) { + cmd.cmdidx = MMC_CMD_APP_CMD; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + + cmd.cmdidx = SD_CMD_APP_SEND_OP_COND; + cmd.resp_type = MMC_RSP_R3; + + /* + * Most cards do not answer if some reserved bits + * in the ocr are set. However, Some controller + * can set bit 7 (reserved for low voltages), but + * how to manage low voltages SD card is not yet + * specified. + */ + cmd.cmdarg = sdmmc_host_is_spi(mmc) ? 0 : + (mmc->cfg->voltages & 0xff8000); + + if (mmc->version == SD_VERSION_2) + cmd.cmdarg |= OCR_HCS; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + + if (cmd.response[0] & OCR_BUSY) + break; + + if (timeout-- <= 0) + return UNUSABLE_ERR; + + mmc_udelay(1000); + } + + if (mmc->version != SD_VERSION_2) + mmc->version = SD_VERSION_1_0; + + if (sdmmc_host_is_spi(mmc)) { /* read OCR for spi */ + cmd.cmdidx = MMC_CMD_SPI_READ_OCR; + cmd.resp_type = MMC_RSP_R3; + cmd.cmdarg = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + } + + mmc->ocr = cmd.response[0]; + + mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); + mmc->rca = 0; + + return 0; +} + +static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg) +{ + struct mmc_cmd cmd; + int err; + + cmd.cmdidx = MMC_CMD_SEND_OP_COND; + cmd.resp_type = MMC_RSP_R3; + cmd.cmdarg = 0; + if (use_arg && !sdmmc_host_is_spi(mmc)) + cmd.cmdarg = OCR_HCS | + (mmc->cfg->voltages & + (mmc->ocr & OCR_VOLTAGE_MASK)) | + (mmc->ocr & OCR_ACCESS_MODE); + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + mmc->ocr = cmd.response[0]; + return 0; +} + +static int mmc_send_op_cond(struct mmc *mmc) +{ + int err, i; + + /* Some cards seem to need this */ + // mmc_go_idle(mmc); + + /* Asking to the card its capabilities */ + for (i = 0; i < 2; i++) { + err = mmc_send_op_cond_iter(mmc, i != 0); + if (err) + return err; + + /* exit if not busy (flag seems to be inverted) */ + if (mmc->ocr & OCR_BUSY) + break; + } + mmc->op_cond_pending = 1; + return 0; +} + +static int mmc_complete_op_cond(struct mmc *mmc) +{ + struct mmc_cmd cmd; + int err; + + mmc->op_cond_pending = 0; + if (!(mmc->ocr & OCR_BUSY)) { + while (1) { + err = mmc_send_op_cond_iter(mmc, 1); + if (err) + return err; + if (mmc->ocr & OCR_BUSY) + break; + mmc_udelay(100); + } + } + + if (sdmmc_host_is_spi(mmc)) { /* read OCR for spi */ + cmd.cmdidx = MMC_CMD_SPI_READ_OCR; + cmd.resp_type = MMC_RSP_R3; + cmd.cmdarg = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + + mmc->ocr = cmd.response[0]; + } + + mmc->version = MMC_VERSION_UNKNOWN; + + mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); + mmc->rca = 1; + + return 0; +} + + +static int mmc_send_ext_csd(struct mmc *mmc, uint8_t *ext_csd) +{ + struct mmc_cmd cmd; + struct mmc_data data; + int err; + + /* Get the Card Status Register */ + cmd.cmdidx = MMC_CMD_SEND_EXT_CSD; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = 0; + + data.dest = (char *)ext_csd; + data.blocks = 1; + data.blocksize = MMC_MAX_BLOCK_LEN; + data.flags = MMC_DATA_READ; + + HAL_SDMMC_TRACE(1,"[%s] start...", __func__); + err = mmc_send_cmd(mmc, &cmd, &data); + HAL_SDMMC_TRACE(2,"[%s] err = %d", __func__, err); + + return err; +} + + +static int mmc_switch(struct mmc *mmc, uint8_t set, uint8_t index, uint8_t value) +{ + struct mmc_cmd cmd; + int timeout = 1000; + int ret; + + cmd.cmdidx = MMC_CMD_SWITCH; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (index << 16) | + (value << 8); + + ret = mmc_send_cmd(mmc, &cmd, NULL); + + /* Waiting for the ready status */ + if (!ret) + ret = mmc_send_status(mmc, timeout); + + return ret; + +} + +static int mmc_change_freq(struct mmc *mmc) +{ + _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint8_t, ext_csd, MMC_MAX_BLOCK_LEN); + char cardtype; + int err; + + mmc->card_caps = 0; + + if (sdmmc_host_is_spi(mmc)) + return 0; + + /* Only version 4 supports high-speed */ + if (mmc->version < MMC_VERSION_4) + return 0; + + mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT; + + err = mmc_send_ext_csd(mmc, ext_csd); + + if (err) + return err; + + cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf; + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); + + if (err) + return err == SWITCH_ERR ? 0 : err; + + /* Now check to see that it worked */ + err = mmc_send_ext_csd(mmc, ext_csd); + + if (err) + return err; + + /* No high-speed support */ + if (!ext_csd[EXT_CSD_HS_TIMING]) + return 0; + + /* High Speed is set, there are two types: 52MHz and 26MHz */ + if (cardtype & EXT_CSD_CARD_TYPE_52) { + if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V) + mmc->card_caps |= MMC_MODE_DDR_52MHz; + mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; + } else { + mmc->card_caps |= MMC_MODE_HS; + } + + return 0; +} + +static int mmc_set_capacity(struct mmc *mmc, int part_num) +{ + switch (part_num) { + case 0: + mmc->capacity = mmc->capacity_user; + break; + case 1: + case 2: + mmc->capacity = mmc->capacity_boot; + break; + case 3: + mmc->capacity = mmc->capacity_rpmb; + break; + case 4: + case 5: + case 6: + case 7: + mmc->capacity = mmc->capacity_gp[part_num - 4]; + break; + default: + return -1; + } + + mmc->block_dev.lba = _sdmmc_lldiv(mmc->capacity, mmc->read_bl_len); + + return 0; +} + +int mmc_getcd(struct mmc *mmc) +{ + int cd; + + cd = board_mmc_getcd(mmc); + + if (cd < 0) { + if (mmc->cfg->ops->getcd) + cd = mmc->cfg->ops->getcd(mmc); + else + cd = 1; + } + + return cd; +} + +static int sd_switch(struct mmc *mmc, int mode, int group, uint8_t value, uint8_t *resp) +{ + struct mmc_cmd cmd; + struct mmc_data data; + + /* Switch the frequency */ + cmd.cmdidx = SD_CMD_SWITCH_FUNC; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = (mode << 31) | 0xffffff; + cmd.cmdarg &= ~(0xf << (group * 4)); + cmd.cmdarg |= value << (group * 4); + + data.dest = (char *)resp; + data.blocksize = 64; + data.blocks = 1; + data.flags = MMC_DATA_READ; + + hal_sdmmc_delay(1); + + return mmc_send_cmd(mmc, &cmd, &data); +} + + +static int sd_change_freq(struct mmc *mmc) +{ + int err; + struct mmc_cmd cmd; + _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint32_t, scr, 2); + _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint32_t, switch_status, 16); + struct mmc_data data; + int timeout; + + mmc->card_caps = 0; + + if (sdmmc_host_is_spi(mmc)) + return 0; + + /* Read the SCR to find out if this card supports higher speeds */ + cmd.cmdidx = MMC_CMD_APP_CMD; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = mmc->rca << 16; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + + cmd.cmdidx = SD_CMD_APP_SEND_SCR; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = 0; + + timeout = 3; + +retry_scr: + data.dest = (char *)scr; + data.blocksize = 8; + data.blocks = 1; + data.flags = MMC_DATA_READ; + + err = mmc_send_cmd(mmc, &cmd, &data); + + if (err) { + if (timeout--) + goto retry_scr; + + return err; + } + + mmc->scr[0] = _sdmmc_be32_to_cpu(scr[0]); + mmc->scr[1] = _sdmmc_be32_to_cpu(scr[1]); + + switch ((mmc->scr[0] >> 24) & 0xf) { + case 0: + mmc->version = SD_VERSION_1_0; + break; + case 1: + mmc->version = SD_VERSION_1_10; + break; + case 2: + mmc->version = SD_VERSION_2; + if ((mmc->scr[0] >> 15) & 0x1) + mmc->version = SD_VERSION_3; + break; + default: + mmc->version = SD_VERSION_1_0; + break; + } + + if (mmc->scr[0] & SD_DATA_4BIT) + mmc->card_caps |= MMC_MODE_4BIT; + + /* Version 1.0 doesn't support switching */ + if (mmc->version == SD_VERSION_1_0) + return 0; + + timeout = 4; + while (timeout--) { + err = sd_switch(mmc, SD_SWITCH_CHECK, 0, 1, + (uint8_t *)switch_status); + + if (err) + return err; + + /* The high-speed function is busy. Try again */ + if (!(_sdmmc_be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY)) + break; + } + + /* If high-speed isn't supported, we return */ + if (!(_sdmmc_be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)) + return 0; + + /* + * If the host doesn't support SD_HIGHSPEED, do not switch card to + * HIGHSPEED mode even if the card support SD_HIGHSPPED. + * This can avoid furthur problem when the card runs in different + * mode between the host. + */ + if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) && + (mmc->cfg->host_caps & MMC_MODE_HS))) + return 0; + + err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (uint8_t *)switch_status); + + if (err) + return err; + + if ((_sdmmc_be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000) + mmc->card_caps |= MMC_MODE_HS; + + return 0; +} + +/* frequency bases */ +/* divided by 10 to be nice to platforms without floating point */ +static const int fbase[] = { + 10000, + 100000, + 1000000, + 10000000, +}; + +/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice + * to platforms without floating point. + */ +static const int multipliers[] = { + 0, /* reserved */ + 10, + 12, + 13, + 15, + 20, + 25, + 30, + 35, + 40, + 45, + 50, + 55, + 60, + 70, + 80, +}; + +static void mmc_set_ios(struct mmc *mmc) +{ + if (mmc->cfg->ops->set_ios) + mmc->cfg->ops->set_ios(mmc); +} + +void mmc_set_clock(struct mmc *mmc, uint32_t clock) +{ + if (clock > mmc->cfg->f_max) + clock = mmc->cfg->f_max; + + if (clock < mmc->cfg->f_min) + clock = mmc->cfg->f_min; + + mmc->clock = clock; + + mmc_set_ios(mmc); +} + +static void mmc_set_bus_width(struct mmc *mmc, uint32_t width) +{ + mmc->bus_width = width; + + mmc_set_ios(mmc); +} + +static int mmc_startup(struct mmc *mmc) +{ + int err, i; + uint32_t mult, freq; + uint32_t cmult, csize, capacity; + struct mmc_cmd cmd; + _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint8_t, ext_csd, MMC_MAX_BLOCK_LEN); + _SDMMC_ALLOC_CACHE_ALIGN_BUFFER(uint8_t, test_csd, MMC_MAX_BLOCK_LEN); + int timeout = 1000; + bool has_parts = false; + bool part_completed; + +#ifdef CONFIG_MMC_SPI_CRC_ON + if (sdmmc_host_is_spi(mmc)) { /* enable CRC check for spi */ + cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = 1; + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + } +#endif + + /* Put the Card in Identify Mode */ + cmd.cmdidx = sdmmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID : + MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */ + cmd.resp_type = MMC_RSP_R2; + cmd.cmdarg = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + + memcpy(mmc->cid, cmd.response, 16); + + /* + * For MMC cards, set the Relative Address. + * For SD cards, get the Relatvie Address. + * This also puts the cards into Standby State + */ + if (!sdmmc_host_is_spi(mmc)) { /* cmd not supported in spi */ + cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR; + cmd.cmdarg = mmc->rca << 16; + cmd.resp_type = MMC_RSP_R6; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + + if (IS_SD(mmc)) + mmc->rca = (cmd.response[0] >> 16) & 0xffff; + } + + /* Get the Card-Specific Data */ + cmd.cmdidx = MMC_CMD_SEND_CSD; + cmd.resp_type = MMC_RSP_R2; + cmd.cmdarg = mmc->rca << 16; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + /* Waiting for the ready status */ + mmc_send_status(mmc, timeout); + + if (err) + return err; + + mmc->csd[0] = cmd.response[0]; + mmc->csd[1] = cmd.response[1]; + mmc->csd[2] = cmd.response[2]; + mmc->csd[3] = cmd.response[3]; + + if (mmc->version == MMC_VERSION_UNKNOWN) { + int version = (cmd.response[0] >> 26) & 0xf; + + switch (version) { + case 0: + mmc->version = MMC_VERSION_1_2; + break; + case 1: + mmc->version = MMC_VERSION_1_4; + break; + case 2: + mmc->version = MMC_VERSION_2_2; + break; + case 3: + mmc->version = MMC_VERSION_3; + break; + case 4: + mmc->version = MMC_VERSION_4; + break; + default: + mmc->version = MMC_VERSION_1_2; + break; + } + } + + /* divide frequency by 10, since the mults are 10x bigger */ + freq = fbase[(cmd.response[0] & 0x7)]; + mult = multipliers[((cmd.response[0] >> 3) & 0xf)]; + + mmc->tran_speed = freq * mult; + + mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1); + mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf); + + if (IS_SD(mmc)) + mmc->write_bl_len = mmc->read_bl_len; + else + mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf); + + if (mmc->high_capacity) { + csize = (mmc->csd[1] & 0x3f) << 16 + | (mmc->csd[2] & 0xffff0000) >> 16; + cmult = 8; + } else { + csize = (mmc->csd[1] & 0x3ff) << 2 + | (mmc->csd[2] & 0xc0000000) >> 30; + cmult = (mmc->csd[2] & 0x00038000) >> 15; + } + + mmc->capacity_user = (csize + 1) << (cmult + 2); + mmc->capacity_user *= mmc->read_bl_len; + mmc->capacity_boot = 0; + mmc->capacity_rpmb = 0; + for (i = 0; i < 4; i++) + mmc->capacity_gp[i] = 0; + + if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN) + mmc->read_bl_len = MMC_MAX_BLOCK_LEN; + + if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN) + mmc->write_bl_len = MMC_MAX_BLOCK_LEN; + + if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) { + cmd.cmdidx = MMC_CMD_SET_DSR; + cmd.cmdarg = (mmc->dsr & 0xffff) << 16; + cmd.resp_type = MMC_RSP_NONE; + if (mmc_send_cmd(mmc, &cmd, NULL)) { + HAL_SDMMC_TRACE(0,"MMC: SET_DSR failed\n"); + } + } + + /* Select the card, and put it into Transfer Mode */ + if (!sdmmc_host_is_spi(mmc)) { /* cmd not supported in spi */ + cmd.cmdidx = MMC_CMD_SELECT_CARD; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = mmc->rca << 16; + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + } + + /* + * For SD, its erase group is always one sector + */ + mmc->erase_grp_size = 1; + mmc->part_config = MMCPART_NOAVAILABLE; + if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) { + /* check ext_csd version and capacity */ + err = mmc_send_ext_csd(mmc, ext_csd); + if (err) + return err; + if (ext_csd[EXT_CSD_REV] >= 2) { + /* + * According to the JEDEC Standard, the value of + * ext_csd's capacity is valid if the value is more + * than 2GB + */ + capacity = ext_csd[EXT_CSD_SEC_CNT] << 0 + | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 + | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 + | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; + capacity *= MMC_MAX_BLOCK_LEN; + if ((capacity >> 20) > 2 * 1024) + mmc->capacity_user = capacity; + } + + switch (ext_csd[EXT_CSD_REV]) { + case 1: + mmc->version = MMC_VERSION_4_1; + break; + case 2: + mmc->version = MMC_VERSION_4_2; + break; + case 3: + mmc->version = MMC_VERSION_4_3; + break; + case 5: + mmc->version = MMC_VERSION_4_41; + break; + case 6: + mmc->version = MMC_VERSION_4_5; + break; + case 7: + mmc->version = MMC_VERSION_5_0; + break; + } + + /* The partition data may be non-zero but it is only + * effective if PARTITION_SETTING_COMPLETED is set in + * EXT_CSD, so ignore any data if this bit is not set, + * except for enabling the high-capacity group size + * definition (see below). */ + part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] & + EXT_CSD_PARTITION_SETTING_COMPLETED); + + /* store the partition info of emmc */ + mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT]; + if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) || + ext_csd[EXT_CSD_BOOT_MULT]) + mmc->part_config = ext_csd[EXT_CSD_PART_CONF]; + if (part_completed && + (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT)) + mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE]; + + mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17; + + mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17; + + for (i = 0; i < 4; i++) { + int idx = EXT_CSD_GP_SIZE_MULT + i * 3; + uint32_t mult = (ext_csd[idx + 2] << 16) + + (ext_csd[idx + 1] << 8) + ext_csd[idx]; + if (mult) + has_parts = true; + if (!part_completed) + continue; + mmc->capacity_gp[i] = mult; + mmc->capacity_gp[i] *= + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + mmc->capacity_gp[i] <<= 19; + } + + if (part_completed) { + mmc->enh_user_size = + (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) + + (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) + + ext_csd[EXT_CSD_ENH_SIZE_MULT]; + mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + mmc->enh_user_size <<= 19; + mmc->enh_user_start = + (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) + + (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) + + (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) + + ext_csd[EXT_CSD_ENH_START_ADDR]; + if (mmc->high_capacity) + mmc->enh_user_start <<= 9; + } + + /* + * Host needs to enable ERASE_GRP_DEF bit if device is + * partitioned. This bit will be lost every time after a reset + * or power off. This will affect erase size. + */ + if (part_completed) + has_parts = true; + if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) && + (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) + has_parts = true; + if (has_parts) { + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_ERASE_GROUP_DEF, 1); + + if (err) + return err; + else + ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1; + } + + if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) { + /* Read out group size from ext_csd */ + mmc->erase_grp_size = + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024; + /* + * if high capacity and partition setting completed + * SEC_COUNT is valid even if it is smaller than 2 GiB + * JEDEC Standard JESD84-B45, 6.2.4 + */ + if (mmc->high_capacity && part_completed) { + capacity = (ext_csd[EXT_CSD_SEC_CNT]) | + (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) | + (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) | + (ext_csd[EXT_CSD_SEC_CNT + 3] << 24); + capacity *= MMC_MAX_BLOCK_LEN; + mmc->capacity_user = capacity; + } + } else { + /* Calculate the group size from the csd value. */ + int erase_gsz, erase_gmul; + erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10; + erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5; + mmc->erase_grp_size = (erase_gsz + 1) + * (erase_gmul + 1); + } + + mmc->hc_wp_grp_size = 1024 + * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] + * ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + + mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET]; + } + + err = mmc_set_capacity(mmc, mmc->part_num); + if (err) + return err; + + if (IS_SD(mmc)) + err = sd_change_freq(mmc); + else + err = mmc_change_freq(mmc); + + if (err) + return err; + + /* Restrict card's capabilities by what the host can do */ + mmc->card_caps &= mmc->cfg->host_caps; + + if (IS_SD(mmc)) { +#ifdef __BUS_WIDTH_SUPPORT_4BIT__ + if (mmc->card_caps & MMC_MODE_4BIT) { + cmd.cmdidx = MMC_CMD_APP_CMD; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = mmc->rca << 16; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = 2; + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + mmc_set_bus_width(mmc, 4); + } +#endif + if (mmc->card_caps & MMC_MODE_HS) + mmc->tran_speed = 50000000; + else + mmc->tran_speed = 25000000; + } else if (mmc->version >= MMC_VERSION_4) { + /* Only version 4 of MMC supports wider bus widths */ + int idx; + + /* An array of possible bus widths in order of preference */ + static unsigned ext_csd_bits[] = { + EXT_CSD_DDR_BUS_WIDTH_8, + EXT_CSD_DDR_BUS_WIDTH_4, + EXT_CSD_BUS_WIDTH_8, + EXT_CSD_BUS_WIDTH_4, + EXT_CSD_BUS_WIDTH_1, + }; + + /* An array to map CSD bus widths to host cap bits */ + static unsigned ext_to_hostcaps[] = { + [EXT_CSD_DDR_BUS_WIDTH_4] = + MMC_MODE_DDR_52MHz | MMC_MODE_4BIT, + [EXT_CSD_DDR_BUS_WIDTH_8] = + MMC_MODE_DDR_52MHz | MMC_MODE_8BIT, + [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT, + [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT, + }; + + /* An array to map chosen bus width to an integer */ + static unsigned widths[] = { + 8, 4, 8, 4, 1, + }; + + for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) { + unsigned int extw = ext_csd_bits[idx]; + unsigned int caps = ext_to_hostcaps[extw]; + + /* + * If the bus width is still not changed, + * don't try to set the default again. + * Otherwise, recover from switch attempts + * by switching to 1-bit bus width. + */ + if (extw == EXT_CSD_BUS_WIDTH_1 && + mmc->bus_width == 1) { + err = 0; + break; + } + + /* + * Check to make sure the card and controller support + * these capabilities + */ + if ((mmc->card_caps & caps) != caps) + continue; + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BUS_WIDTH, extw); + + if (err) + continue; + + mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0; + mmc_set_bus_width(mmc, widths[idx]); + + err = mmc_send_ext_csd(mmc, test_csd); + + if (err) + continue; + + /* Only compare read only fields */ + if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] + == test_csd[EXT_CSD_PARTITIONING_SUPPORT] && + ext_csd[EXT_CSD_HC_WP_GRP_SIZE] + == test_csd[EXT_CSD_HC_WP_GRP_SIZE] && + ext_csd[EXT_CSD_REV] + == test_csd[EXT_CSD_REV] && + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] + == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] && + memcmp(&ext_csd[EXT_CSD_SEC_CNT], + &test_csd[EXT_CSD_SEC_CNT], 4) == 0) + break; + else + err = SWITCH_ERR; + } + + if (err) + return err; + + if (mmc->card_caps & MMC_MODE_HS) { + if (mmc->card_caps & MMC_MODE_HS_52MHz) + mmc->tran_speed = 52000000; + else + mmc->tran_speed = 26000000; + } + } + + mmc_set_clock(mmc, mmc->tran_speed); + + /* Fix the block length for DDR mode */ + if (mmc->ddr_mode) { + mmc->read_bl_len = MMC_MAX_BLOCK_LEN; + mmc->write_bl_len = MMC_MAX_BLOCK_LEN; + } + + /* fill in device description */ + mmc->block_dev.lun = 0; + mmc->block_dev.type = 0; + mmc->block_dev.blksz = mmc->read_bl_len; + //mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz); + mmc->block_dev.lba = _sdmmc_lldiv(mmc->capacity, mmc->read_bl_len); +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) + sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x", + (unsigned)(mmc->cid[0] >> 24), (unsigned)(mmc->cid[2] & 0xffff), + (unsigned)((mmc->cid[3] >> 16) & 0xffff)); + sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", (char)mmc->cid[0], + (char)(mmc->cid[1] >> 24), (char)(mmc->cid[1] >> 16), + (char)(mmc->cid[1] >> 8), (char)mmc->cid[1], + (char)(mmc->cid[2] >> 24)); + sprintf(mmc->block_dev.revision, "%d.%d", (unsigned)((mmc->cid[2] >> 20) & 0xf), + (unsigned)((mmc->cid[2] >> 16) & 0xf)); +#else + mmc->block_dev.vendor[0] = 0; + mmc->block_dev.product[0] = 0; + mmc->block_dev.revision[0] = 0; +#endif + + HAL_SDMMC_TRACE(1,"%s done\n", __func__); + return 0; +} + +static int mmc_send_if_cond(struct mmc *mmc) +{ + struct mmc_cmd cmd; + int err; + + cmd.cmdidx = SD_CMD_SEND_IF_COND; + /* We set the bit if the host supports voltages between 2.7 and 3.6 V */ + cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa; + cmd.resp_type = MMC_RSP_R7; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + + if ((cmd.response[0] & 0xff) != 0xaa) + return UNUSABLE_ERR; + else + mmc->version = SD_VERSION_2; + + return 0; +} + +struct mmc *mmc_create(int id, const struct mmc_config *cfg, void *priv) +{ + struct mmc *mmc; + + /* quick validation */ + if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL || + cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0) + return NULL; + + mmc = &sdmmc_devices[id]; + if (mmc == NULL) + return NULL; + + mmc->cfg = cfg; + mmc->priv = priv; + + /* the following chunk was mmc_register() */ + + /* Setup dsr related values */ + mmc->dsr_imp = 0; + mmc->dsr = 0xffffffff; + /* Setup the universal parts of the block interface just once */ + mmc->block_dev.removable = 1; + /* setup initial part type */ + mmc->block_dev.part_type = mmc->cfg->part_type; + + return mmc; +} + +int mmc_start_init(struct mmc *mmc) +{ + int err; + + /* we pretend there's no card when init is NULL */ + if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) { + mmc->has_init = 0; + HAL_SDMMC_TRACE(1,"%s : no card present\n", __func__); + return NO_CARD_ERR; + } + + if (mmc->has_init) + return 0; + + /* made sure it's not NULL earlier */ + err = mmc->cfg->ops->init(mmc); + HAL_SDMMC_TRACE(1,"%s : init done\n", __func__); + + if (err) + return err; + + mmc->ddr_mode = 0; + mmc_set_bus_width(mmc, 1); + mmc_set_clock(mmc, 1); + + /* Reset the Card */ + err = mmc_go_idle(mmc); + HAL_SDMMC_TRACE(1,"%s : idle done\n", __func__); + + if (err) + return err; + + /* The internal partition reset to user partition(0) at every CMD0*/ + mmc->part_num = 0; + + /* Test for SD version 2 */ + err = mmc_send_if_cond(mmc); + + /* Now try to get the SD card's operating condition */ + err = sd_send_op_cond(mmc); + + /* If the command timed out, we check for an MMC card */ + if (err == TIMEOUT) { + err = mmc_send_op_cond(mmc); + + if (err) { +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) + HAL_SDMMC_TRACE(1,"%s : Card did not respond to voltage select!\n", __func__); +#endif + return UNUSABLE_ERR; + } + } + + if (!err) + mmc->init_in_progress = 1; + + HAL_SDMMC_TRACE(1,"%s : done\n", __func__); + return err; +} + +static int mmc_complete_init(struct mmc *mmc) +{ + int err = 0; + + mmc->init_in_progress = 0; + if (mmc->op_cond_pending) + err = mmc_complete_op_cond(mmc); + + if (!err) + err = mmc_startup(mmc); + if (err) + mmc->has_init = 0; + else + mmc->has_init = 1; + return err; +} + +void hal_sdmmc_irq_handler(void) +{ + uint32_t cdetect,mask; + struct sdmmcip_host *host = &sdmmc_host[HAL_SDMMC_ID_0]; + mask = sdmmcip_readl(host, SDMMCIP_REG_RINTSTS); + + if (mask & SDMMCIP_REG_INTMSK_CD){ + sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, SDMMCIP_REG_INTMSK_CD); + cdetect = sdmmcip_readl(host, SDMMCIP_REG_CDETECT); + HAL_SDMMC_TRACE(3,"%s cdetect:%d mask:%x\n", __func__, cdetect, mask); + if (sdmmc_detected_callback) + sdmmc_detected_callback(cdetect&0x01 ? 0 : 1); + } +} + +int hal_sdmmc_enable_detecter(enum HAL_SDMMC_ID_T id,void (* cb)(uint8_t)) +{ + uint32_t ctrl; + struct sdmmcip_host *host = NULL; + HAL_SDMMC_TRACE(1,"%s\n", __func__); + + sdmmc_detected_callback = cb; + + host = &sdmmc_host[id]; + host->ioaddr = (void *)sdmmc_ip_base[id]; + + if (!sdmmcip_wait_reset(host, SDMMCIP_REG_RESET_ALL)) { + HAL_SDMMC_TRACE(2,"%s[%d] Fail-reset!!\n", __func__, __LINE__); + return -1; + } + + host->detect_enb = true; + + sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, 0xFFFFFFFF); + sdmmcip_writel(host, SDMMCIP_REG_INTMASK, SDMMCIP_REG_INTMSK_CD); + + ctrl = SDMMCIP_REG_INT_EN; + sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); + + NVIC_SetVector(SDMMC_IRQn, (uint32_t)hal_sdmmc_irq_handler); + NVIC_SetPriority(SDMMC_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(SDMMC_IRQn); + NVIC_EnableIRQ(SDMMC_IRQn); + return 0; +} + +void hal_sdmmc_disable_detecter(enum HAL_SDMMC_ID_T id) +{ + uint32_t ctrl = 0; + struct sdmmcip_host *host = NULL; + host = &sdmmc_host[id]; + + NVIC_DisableIRQ(SDMMC_IRQn); + NVIC_SetVector(SDMMC_IRQn, (uint32_t)NULL); + + sdmmcip_writel(host, SDMMCIP_REG_RINTSTS, 0xFFFFFFFF); + sdmmcip_writel(host, SDMMCIP_REG_INTMASK, ~SDMMCIP_REG_INTMSK_ALL); + + ctrl = sdmmcip_readl(host, SDMMCIP_REG_CTRL); + ctrl |= (SDMMCIP_REG_DMA_EN); + sdmmcip_writel(host, SDMMCIP_REG_CTRL, ctrl); + + host->detect_enb = false; + sdmmc_detected_callback = NULL; +} + +int mmc_init(struct mmc *mmc) +{ + int err = 0; + if (mmc->has_init) + return 0; + + if (!mmc->init_in_progress) + err = mmc_start_init(mmc); + + if (!err) + err = mmc_complete_init(mmc); + + return err; +} + +/* hal api */ +static void hal_sdmmc_delay(uint32_t ms) +{ + if (sdmmc_delay) { + sdmmc_delay(ms); + } else { + hal_sys_timer_delay(MS_TO_TICKS(ms)); + } +} + +HAL_SDMMC_DELAY_FUNC hal_sdmmc_set_delay_func(HAL_SDMMC_DELAY_FUNC new_func) +{ + HAL_SDMMC_DELAY_FUNC old_func = sdmmc_delay; + sdmmc_delay = new_func; + return old_func; +} + +int32_t hal_sdmmc_open(enum HAL_SDMMC_ID_T id) +{ + int32_t ret = 0; + struct sdmmcip_host *host = NULL; + HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); + +#ifdef FPGA + hal_cmu_sdmmc_set_freq(HAL_CMU_PERIPH_FREQ_26M); +#else + hal_cmu_sdmmc_set_freq(HAL_CMU_PERIPH_FREQ_52M); +#endif + + hal_cmu_clock_enable(HAL_CMU_MOD_O_SDMMC); + hal_cmu_clock_enable(HAL_CMU_MOD_H_SDMMC); + hal_cmu_reset_clear(HAL_CMU_MOD_O_SDMMC); + hal_cmu_reset_clear(HAL_CMU_MOD_H_SDMMC); + +#ifdef FPGA +#ifdef CHIP_BEST1000 + /* iomux */ + *((volatile uint32_t *)0x4001f004) |= 0x1<<16; + *((volatile uint32_t *)0x4001f004) |= 0x1<<17; +#endif +#endif + + host = &sdmmc_host[id]; + + host->ioaddr = (void *)sdmmc_ip_base[id]; + //host->buswidth = 4; + host->buswidth = 1; + host->clksel = 0; + host->bus_hz = _SDMMC_CLOCK; + host->dev_index = id; + /* fifo threshold : MSIZE 0 - 1 transter, rx water mark 0 - greater than 0 word triiger dma-req, + * tx water mark 1 - less than or equal 1 word triiger dma-req */ + host->fifoth_val = MSIZE(0) | RX_WMARK(0) | TX_WMARK(1); + + host->cfg.ops = &sdmmcip_ops; + host->cfg.f_min = 400000; + //host->cfg.f_min = 1000000; + //host->cfg.f_min = 25000000; + //host->cfg.f_min = 52000000; + //host->cfg.f_max = 1000000; + host->cfg.f_max = 26000000; + //host->cfg.f_max = 52000000; + host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; + host->cfg.host_caps = 0; + +#ifdef HAL_SDMMC_USE_DMA + host->tx_dma_handler = sdmmcip_ext_dma_irq_handlers[id*2]; + host->rx_dma_handler = sdmmcip_ext_dma_irq_handlers[id*2+1]; +#endif + + if (host->buswidth == 8) { + host->cfg.host_caps |= MMC_MODE_8BIT; + host->cfg.host_caps &= ~MMC_MODE_4BIT; + } else if (host->buswidth == 4) { + host->cfg.host_caps |= MMC_MODE_4BIT; + host->cfg.host_caps &= ~MMC_MODE_8BIT; + } + else { + //host->cfg.host_caps &= ~MMC_MODE_4BIT; + host->cfg.host_caps |= MMC_MODE_4BIT; + host->cfg.host_caps &= ~MMC_MODE_8BIT; + } + + host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz; + + host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + + host->mmc = mmc_create(host->dev_index, &host->cfg, host); + + ret = mmc_init(host->mmc); + + hal_sdmmc_dump(HAL_SDMMC_ID_0); + + return ret; +} +uint32_t hal_sdmmc_read_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, uint32_t block_count, uint8_t* dest) +{ + HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); + + return mmc_bread(id, start_block, block_count, dest); +} + +uint32_t hal_sdmmc_write_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, uint32_t block_count, uint8_t* src) +{ + HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); + + return mmc_bwrite(id, start_block, block_count, src); +} + +void hal_sdmmc_close(enum HAL_SDMMC_ID_T id) +{ + struct sdmmcip_host *host = NULL; + + HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); + + HAL_SDMMC_TRACE(1,"%s\n", __func__); + + host = &sdmmc_host[id]; + while(host->mmc->init_in_progress) + hal_sdmmc_delay(1); + + host->mmc->has_init = 0; + + hal_cmu_reset_set(HAL_CMU_MOD_H_SDMMC); + hal_cmu_reset_set(HAL_CMU_MOD_O_SDMMC); + hal_cmu_clock_disable(HAL_CMU_MOD_H_SDMMC); + hal_cmu_clock_disable(HAL_CMU_MOD_O_SDMMC); +} + +void hal_sdmmc_dump(enum HAL_SDMMC_ID_T id) +{ + struct mmc *mmc = NULL; + struct sdmmcip_host *host = NULL; + HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); + + host = &sdmmc_host[id]; + mmc = host->mmc; + + HAL_SDMMC_TRACE(0,"-----------hal_sdmmc_dump-------------\n"); + HAL_SDMMC_TRACE(1," [sdmmc id] : %d\n", id); + HAL_SDMMC_TRACE(1," [io register address] : 0x%x\n", sdmmc_ip_base[id]); + HAL_SDMMC_TRACE(1," [ddr mode] : %d\n", mmc->ddr_mode); + switch(mmc->version) + { + case SD_VERSION_1_0: HAL_SDMMC_TRACE(0," [version] : SD_VERSION_1_0\n"); break; + case SD_VERSION_1_10: HAL_SDMMC_TRACE(0," [version] : SD_VERSION_1_10\n"); break; + case SD_VERSION_2: HAL_SDMMC_TRACE(0," [version] : SD_VERSION_2\n"); break; + case SD_VERSION_3: HAL_SDMMC_TRACE(0," [version] : SD_VERSION_3\n"); break; + case MMC_VERSION_5_0: HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_5_0\n"); break; + case MMC_VERSION_4_5: HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_4_5\n"); break; + case MMC_VERSION_4_41:HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_4_41\n");break; + case MMC_VERSION_4_3: HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_4_3\n"); break; + case MMC_VERSION_4_2: HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_4_2\n"); break; + case MMC_VERSION_4_1: HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_4_1\n"); break; + case MMC_VERSION_4: HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_4\n"); break; + case MMC_VERSION_3: HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_3\n"); break; + case MMC_VERSION_2_2: HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_2_2\n"); break; + case MMC_VERSION_1_4: HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_1_4\n"); break; + case MMC_VERSION_1_2: HAL_SDMMC_TRACE(0," [version] : MMC_VERSION_1_2\n"); break; + default: HAL_SDMMC_TRACE(0," [version] : unkown version\n"); break; + } + HAL_SDMMC_TRACE(1," [is SD card] : 0x%x\n", IS_SD(mmc)); + HAL_SDMMC_TRACE(1," [high_capacity] : 0x%x\n", mmc->high_capacity); + HAL_SDMMC_TRACE(1," [bus_width] : 0x%x\n", mmc->bus_width); + HAL_SDMMC_TRACE(1," [clock] : %d\n", mmc->clock); + HAL_SDMMC_TRACE(1," [card_caps] : 0x%x\n", mmc->card_caps); + HAL_SDMMC_TRACE(1," [ocr] : 0x%x\n", mmc->ocr); + HAL_SDMMC_TRACE(1," [dsr] : 0x%x\n", mmc->dsr); + HAL_SDMMC_TRACE(1," [capacity_user/1024] : %d(K)\n", (uint32_t)(mmc->capacity_user/1024)); + HAL_SDMMC_TRACE(1," [capacity_user/1024/1024] : %d(M)\n", (uint32_t)(mmc->capacity_user/1024/1024)); + HAL_SDMMC_TRACE(1," [capacity_user/1024/1024/1024] : %d(G)\n", (uint32_t)(mmc->capacity_user/1024/1024/1024)); + HAL_SDMMC_TRACE(1," [read_bl_len] : %d\n", mmc->read_bl_len); + HAL_SDMMC_TRACE(1," [write_bl_len] : %d\n", mmc->write_bl_len); + HAL_SDMMC_TRACE(0,"--------------------------------------\n"); +} +void hal_sdmmc_info(enum HAL_SDMMC_ID_T id, uint32_t *sector_count, uint32_t *sector_size) +{ + struct mmc *mmc = NULL; + struct sdmmcip_host *host = NULL; + HAL_SDMMC_ASSERT(id < HAL_SDMMC_ID_NUM, invalid_id, id); + + host = &sdmmc_host[id]; + mmc = host->mmc; + + if (sector_size) { + *sector_size = mmc->read_bl_len; + HAL_SDMMC_TRACE(1,"[sdmmc] sector_size %d\n", *sector_size); + } + if (sector_count) { + if (mmc->read_bl_len != 0) + *sector_count = mmc->capacity_user/mmc->read_bl_len; + else + *sector_count = 0; + HAL_SDMMC_TRACE(1,"[sdmmc] sector_count %d\n", *sector_count); + } +} + +#endif // CHIP_HAS_SDMMC diff --git a/platform/hal/hal_sdmmc.h b/platform/hal/hal_sdmmc.h new file mode 100644 index 0000000..5c64fb4 --- /dev/null +++ b/platform/hal/hal_sdmmc.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _HAL_SDMMC_H_ +#define _HAL_SDMMC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +enum HAL_SDMMC_ID_T { + HAL_SDMMC_ID_0 = 0, + HAL_SDMMC_ID_NUM, +}; + +typedef void (*HAL_SDMMC_DELAY_FUNC)(uint32_t ms); + +/* hal api */ +HAL_SDMMC_DELAY_FUNC hal_sdmmc_set_delay_func(HAL_SDMMC_DELAY_FUNC new_func); +int32_t hal_sdmmc_open(enum HAL_SDMMC_ID_T id); +void hal_sdmmc_info(enum HAL_SDMMC_ID_T id, uint32_t *sector_count, uint32_t *sector_size); +uint32_t hal_sdmmc_read_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, uint32_t block_count, uint8_t* dest); +uint32_t hal_sdmmc_write_blocks(enum HAL_SDMMC_ID_T id, uint32_t start_block, uint32_t block_count, uint8_t* src); +void hal_sdmmc_close(enum HAL_SDMMC_ID_T id); +void hal_sdmmc_dump(enum HAL_SDMMC_ID_T id); +int hal_sdmmc_enable_detecter(enum HAL_SDMMC_ID_T id,void (* cb)(uint8_t)); + +#ifdef __cplusplus +} +#endif + +#endif /* _HAL_SDMMC_H_ */ diff --git a/platform/hal/hal_sec_eng.c b/platform/hal/hal_sec_eng.c new file mode 100644 index 0000000..33c2156 --- /dev/null +++ b/platform/hal/hal_sec_eng.c @@ -0,0 +1,1037 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" + +#ifdef SEC_ENG_BASE + +#include "hal_sec_eng.h" +#include "reg_sec_eng.h" +#include "reg_dma.h" +#include "cmsis_nvic.h" +#include "hal_cmu.h" +#include "hal_dma.h" +#include "hal_timer.h" +#include "hal_trace.h" + +#define SE_DMA_CHAN_NUM 2 +#define SE_DMA_DESC_NUM 4 + +#define SE_DMA_MAX_DESC_XFER_SIZE (HAL_DMA_MAX_DESC_XFER_SIZE & ~(4 - 1)) + +#define SE_DMA_RX_CHAN 0 +#define SE_DMA_TX_CHAN 1 + +// Trigger DMA request when RX-FIFO count >= threshold +#define SE_DMA_RX_FIFO_TRIG_LEVEL 8 +// Trigger DMA request when TX-FIFO count <= threshold +#define SE_DMA_TX_FIFO_TRIG_LEVEL 8 + +enum SE_ACC_CLK_T { + SE_ACC_CLK_DMA = (1 << 1), + SE_ACC_CLK_ACC_BUS = (1 << 2), + SE_ACC_CLK_CRYPT = (1 << 3), + SE_ACC_CLK_ECP = (1 << 4), + SE_ACC_CLK_HASH = (1 << 5), + SE_ACC_CLK_SCRATCH = (1 << 6), + SE_ACC_CLK_ZMODP = (1 << 7), + SE_ACC_CLK_MCT = (1 << 8), + SE_ACC_CLK_OTP = (1 << 9), + SE_ACC_CLK_EBG = (1 << 10), +}; + +enum SE_ACC_RST_T { + SE_ACC_RST_DMA = (1 << 1), + SE_ACC_RST_ACC_BUS = (1 << 2), + SE_ACC_RST_CRYPT = (1 << 3), + SE_ACC_RST_ECP = (1 << 4), + SE_ACC_RST_HASH = (1 << 5), + SE_ACC_RST_SCRATCH = (1 << 6), + SE_ACC_RST_ZMODP = (1 << 7), + SE_ACC_RST_MCT = (1 << 8), + SE_ACC_RST_OTP = (1 << 9), + SE_ACC_RST_EBG = (1 << 10), +}; + +enum SE_ACC_INT_T { + SE_ACC_INT_AES = (1 << 1), + SE_ACC_INT_DES = (1 << 2), + SE_ACC_INT_RC4 = (1 << 3), + SE_ACC_INT_OTP = (1 << 4), + SE_ACC_INT_ECP = (1 << 6), + SE_ACC_INT_MCT = (1 << 7), + SE_ACC_INT_HASH = (1 << 8), + SE_ACC_INT_ZMODP = (1 << 9), + SE_ACC_INT_SCRATCH = (1 << 10), +}; + +enum SE_DMA_PERIPH_T { + SE_DMA_PERIPH_TX = 0, + SE_DMA_PERIPH_RX, + + SE_DMA_PERIPH_QTY, +}; + +enum SE_CRYPT_TYPE_T { + SE_CRYPT_NONE = 0, + SE_CRYPT_AES, + SE_CRYPT_DES, + SE_CRYPT_RC4, + + SE_CRYPT_QTY, +}; + +enum SE_AES_KEY_LEN_T { + SE_AES_KEY_128 = 0, + SE_AES_KEY_192, + SE_AES_KEY_256, + + SE_AES_KEY_LEN_QTY, +}; + +enum SE_HASH_OP_T { + SE_HASH_OP_INIT = 1, + SE_HASH_OP_UPDATE, + SE_HASH_OP_FINAL, +}; + +static struct DMA_T * const se_dma = (struct DMA_T *)SEDMA_BASE; + +static struct SE_ADEC_T * const se_adec = (struct SE_ADEC_T *)SE_ADEC_BASE; +static struct SE_ACB_T * const se_acb = (struct SE_ACB_T *)SE_ACB_BASE; +static struct SE_DMACFG_T * const se_dmacfg = (struct SE_DMACFG_T *)SE_DMACFG_BASE; +static struct SE_CRYPT_T * const se_crypt = (struct SE_CRYPT_T *)SE_CRYPT_BASE; +POSSIBLY_UNUSED static struct SE_HASH_T * const se_hash = (struct SE_HASH_T *)SE_HASH_BASE; +POSSIBLY_UNUSED static struct SE_OTP_T * const se_otp = (struct SE_OTP_T *)SE_OTP_BASE; + +static bool se_enabled; + +static HAL_SC_DONE_HANDLER_T se_done_hdlr; + +static uint32_t in_addr; +static uint32_t total_in_len; +static uint32_t cur_in_len; + +static uint32_t out_addr; +static uint32_t total_out_len; +static uint32_t cur_out_len; + +static struct HAL_DMA_DESC_T dma_desc[SE_DMA_CHAN_NUM][SE_DMA_DESC_NUM]; + +static uint32_t se_dma_init_rx_desc(uint32_t out, uint32_t out_len, uint32_t src, uint32_t ctrl); +static uint32_t se_dma_init_tx_desc(uint32_t in, uint32_t in_len, uint32_t dst, uint32_t ctrl); +#ifdef SEC_ENG_HAS_HASH +static uint32_t se_hash_get_digest_len(void); +static void read_mreg(const volatile uint32_t *reg, void *mem, uint32_t len); +#endif + +static void sec_eng_irq_handler(void) +{ + enum HAL_SE_DONE_ERR_T err; + uint32_t all_int; + uint32_t aes_int = 0; + uint32_t hash_int = 0; + + all_int = se_adec->ADEC_INT; + + if (all_int & SE_ACC_INT_AES) { + aes_int = se_crypt->AES_INTRPT; + + // Clear IRQs + se_crypt->AES_INTRPT = aes_int; + se_adec->ADEC_INT = SE_ACC_INT_AES; + + if (aes_int & (AES_INTRPT_ERROR1 | AES_INTRPT_ERROR2)) { + if (se_done_hdlr) { + if ((aes_int & (AES_INTRPT_ERROR1 | AES_INTRPT_ERROR2)) == (AES_INTRPT_ERROR1 | AES_INTRPT_ERROR2)) { + err = HAL_SE_DONE_ERR_ENG_ERR1_ERR2; + } else if (aes_int & AES_INTRPT_ERROR1) { + err = HAL_SE_DONE_ERR_ENG_ERR1; + } else { + err = HAL_SE_DONE_ERR_ENG_ERR2; + } + se_done_hdlr((void *)out_addr, 0, err); + } + } + } + +#ifdef SEC_ENG_HAS_HASH + if (all_int & SE_ACC_INT_HASH) { + hash_int = se_hash->HASH_STATUS; + + // Clear IRQs + se_hash->HASH_STATUS = hash_int; + se_adec->ADEC_INT = SE_ACC_INT_HASH; + + if (hash_int & HASH_STATUS_HASH_DONE) { + if (se_done_hdlr) { + enum HAL_SE_RET_T ret; + uint32_t digest[16]; + uint32_t len; + + ret = hal_se_hash_get_digest(&digest[0], sizeof(digest), &len); + if (ret == HAL_SE_OK) { + se_done_hdlr(&digest[0], len, HAL_SE_DONE_OK); + } else { + se_done_hdlr(NULL, 0, HAL_SE_DONE_OK); + } + } + } + } +#endif + + LOG_INFO(0, "%s: all_int=0x%08X aes_int=0x%08X hash_int=%d", __func__, all_int, aes_int, hash_int); +} + +static void sedma_irq_handler(void) +{ + uint8_t hwch; + uint32_t remains; + uint32_t len; + uint32_t ctrl; + bool tcint, errint; + + for (hwch = 0; hwch < SE_DMA_CHAN_NUM; hwch++) { + if ((se_dma->INTSTAT & DMA_STAT_CHAN(hwch)) == 0) { + continue; + } + + /* Check counter terminal status */ + tcint = !!(se_dma->INTTCSTAT & DMA_STAT_CHAN(hwch)); + /* Check error terminal status */ + errint = !!(se_dma->INTERRSTAT & DMA_STAT_CHAN(hwch)); + + if (tcint || errint) { + if (tcint) { + /* Clear terminate counter Interrupt pending */ + se_dma->INTTCCLR = DMA_STAT_CHAN(hwch); + } + if (errint) { + /* Clear error counter Interrupt pending */ + se_dma->INTERRCLR = DMA_STAT_CHAN(hwch); + } + + remains = GET_BITFIELD(se_dma->CH[hwch].CONTROL, DMA_CONTROL_TRANSFERSIZE); + if (errint) { + se_dma->CH[hwch].CONFIG &= ~DMA_CONFIG_EN; + if (se_done_hdlr) { + se_done_hdlr((uint8_t *)out_addr, 0, + (hwch == SE_DMA_RX_CHAN) ? HAL_SE_DONE_ERR_DMA_OUT : HAL_SE_DONE_ERR_DMA_IN); + } + } else { + if (hwch == SE_DMA_RX_CHAN) { + if (cur_out_len < total_out_len) { + len = total_out_len - cur_out_len; + ctrl = se_dma->CH[hwch].CONTROL & ~DMA_CONTROL_TC_IRQ; + cur_out_len += se_dma_init_rx_desc(out_addr + cur_out_len, len, se_dma->CH[hwch].SRCADDR, ctrl); + se_dma->CH[SE_DMA_RX_CHAN].CONFIG |= DMA_CONFIG_EN; + } else { + if (se_done_hdlr) { + if (remains) { + se_done_hdlr((void *)out_addr, cur_out_len - remains, HAL_SE_DONE_ERR_DMA_IN_REMAIN); + } else { + se_done_hdlr((void *)out_addr, cur_out_len, HAL_SE_DONE_OK); + } + } + } + } else { + if (cur_in_len < total_in_len) { + len = total_in_len - cur_in_len; + ctrl = se_dma->CH[hwch].CONTROL & ~DMA_CONTROL_TC_IRQ; + cur_in_len += se_dma_init_tx_desc(in_addr + cur_in_len, len, se_dma->CH[hwch].DSTADDR, ctrl); + se_dma->CH[SE_DMA_TX_CHAN].CONFIG |= DMA_CONFIG_EN; + } else { + if (remains) { + if (se_done_hdlr) { + se_done_hdlr((void *)out_addr, 0, HAL_SE_DONE_ERR_DMA_IN_REMAIN); + } + } + } + } + } + LOG_INFO(0, "%s: ch=%d tcint=%d errint=%d remains=%u", __func__, hwch, tcint, errint, remains); + } + } +} + +static void se_dma_open(void) +{ + uint8_t i; + + se_adec->ADEC_CTRL |= ADEC_CTRL_CLK_EN_15_0(SE_ACC_CLK_DMA) | ADEC_CTRL_RST_15_0(SE_ACC_RST_DMA); + se_adec->ADEC_CTRL &= ~ADEC_CTRL_RST_15_0(SE_ACC_RST_DMA); + se_adec->ADEC_INT_MSK = ~0UL; + + se_dmacfg->DMA_CTRL = DMA_CTRL_RX_DMA_EN | DMA_CTRL_TX_DMA_EN; + se_dmacfg->DMA_RDL = SE_DMA_RX_FIFO_TRIG_LEVEL; + se_dmacfg->DMA_TDL = SE_DMA_TX_FIFO_TRIG_LEVEL; + + /* Reset all channel configuration register */ + for (i = 0; i < SE_DMA_CHAN_NUM; i++) { + se_dma->CH[i].CONFIG = 0; + } + + /* Clear all DMA interrupt and error flag */ + se_dma->INTTCCLR = ~0UL; + se_dma->INTERRCLR = ~0UL; + + se_dma->DMACONFIG = (se_dma->DMACONFIG & ~(DMA_DMACONFIG_AHB1_BIGENDIAN | + DMA_DMACONFIG_AHB2_BIGENDIAN)) | DMA_DMACONFIG_EN; + + NVIC_SetVector(SEDMA_IRQn, (uint32_t)sedma_irq_handler); + NVIC_SetPriority(SEDMA_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(SEDMA_IRQn); + NVIC_EnableIRQ(SEDMA_IRQn); +} + +static void se_dma_cancel_rx(void) +{ + se_dma->CH[SE_DMA_RX_CHAN].CONFIG &= ~DMA_CONFIG_EN; +} + +static void se_dma_cancel_tx(void) +{ + se_dma->CH[SE_DMA_TX_CHAN].CONFIG &= ~DMA_CONFIG_EN; +} + +static void se_dma_close(void) +{ + NVIC_DisableIRQ(SEDMA_IRQn); + se_dma_cancel_rx(); + se_dma_cancel_tx(); + se_dma->DMACONFIG = 0; +} + +static uint32_t se_dma_init_rx_desc(uint32_t out, uint32_t out_len, uint32_t src, uint32_t ctrl) +{ + uint32_t len; + uint32_t cfg_len; + uint32_t desc_idx; + uint32_t i; + + len = out_len; + if (len > SE_DMA_MAX_DESC_XFER_SIZE * 4) { + len = SE_DMA_MAX_DESC_XFER_SIZE * 4; + } + len &= ~(4 - 1); + ctrl = SET_BITFIELD(ctrl, DMA_CONTROL_TRANSFERSIZE, len / 4); + if (len >= out_len) { + // Always enable IRQ at the end of each xfer + ctrl |= DMA_CONTROL_TC_IRQ; + } + se_dma->CH[SE_DMA_RX_CHAN].CONTROL = ctrl; + se_dma->CH[SE_DMA_RX_CHAN].SRCADDR = src; + se_dma->CH[SE_DMA_RX_CHAN].DSTADDR = out; + + if (len >= out_len) { + se_dma->CH[SE_DMA_RX_CHAN].LLI = 0; + return len; + } + + cfg_len = len; + desc_idx = 0; + while (desc_idx < SE_DMA_DESC_NUM && cfg_len < out_len) { + len = out_len - cfg_len; + if (len > SE_DMA_MAX_DESC_XFER_SIZE * 4) { + len = SE_DMA_MAX_DESC_XFER_SIZE * 4; + } + len &= ~(4 - 1); + ctrl = SET_BITFIELD(ctrl, DMA_CONTROL_TRANSFERSIZE, len / 4); + dma_desc[SE_DMA_RX_CHAN][desc_idx].ctrl = ctrl; + dma_desc[SE_DMA_RX_CHAN][desc_idx].src = src; + dma_desc[SE_DMA_RX_CHAN][desc_idx].dst = out + cfg_len; + cfg_len += len; + desc_idx++; + } + + // Always enable IRQ at the end of each xfer + dma_desc[SE_DMA_RX_CHAN][desc_idx - 1].ctrl |= DMA_CONTROL_TC_IRQ; + + for (i = 0; i + 1 < desc_idx; i++) { + dma_desc[SE_DMA_RX_CHAN][i].lli = (uint32_t)&dma_desc[SE_DMA_RX_CHAN][i + 1]; + } + dma_desc[SE_DMA_RX_CHAN][desc_idx - 1].lli = 0; + + se_dma->CH[SE_DMA_RX_CHAN].LLI = (uint32_t)&dma_desc[SE_DMA_RX_CHAN][0]; + + return cfg_len; +} + +static void se_dma_enable_rx(void *out, uint32_t out_len) +{ + uint32_t ctrl; + + ASSERT((out_len & (4 - 1)) == 0, "%s: out_len must align to 4 bytes: %u", __func__, out_len); + + out_addr = (uint32_t)out; + total_out_len = out_len; + + /* Reset the Interrupt status */ + se_dma->INTTCCLR = DMA_STAT_CHAN(SE_DMA_RX_CHAN); + se_dma->INTERRCLR = DMA_STAT_CHAN(SE_DMA_RX_CHAN); + + ctrl = DMA_CONTROL_SBSIZE(HAL_DMA_BSIZE_8) | + DMA_CONTROL_DBSIZE(HAL_DMA_BSIZE_16) | + DMA_CONTROL_SWIDTH(HAL_DMA_WIDTH_WORD) | + DMA_CONTROL_DWIDTH(HAL_DMA_WIDTH_BYTE) | + DMA_CONTROL_DI; + + cur_out_len = se_dma_init_rx_desc((uint32_t)out, out_len, (uint32_t)&se_dmacfg->DMA_RXFIFO, ctrl); + + se_dma->CH[SE_DMA_RX_CHAN].CONFIG = DMA_CONFIG_SRCPERIPH(SE_DMA_PERIPH_RX) | + DMA_CONFIG_TRANSFERTYPE(HAL_DMA_FLOW_P2M_DMA) | + DMA_CONFIG_ERR_IRQMASK | DMA_CONFIG_TC_IRQMASK; + se_dma->CH[SE_DMA_RX_CHAN].CONFIG |= DMA_CONFIG_EN; +} + +static uint32_t se_dma_init_tx_desc(uint32_t in, uint32_t in_len, uint32_t dst, uint32_t ctrl) +{ + uint32_t len; + uint32_t cfg_len; + uint32_t desc_idx; + uint32_t i; + + len = in_len; + if (len > SE_DMA_MAX_DESC_XFER_SIZE) { + len = SE_DMA_MAX_DESC_XFER_SIZE; + } + ctrl = SET_BITFIELD(ctrl, DMA_CONTROL_TRANSFERSIZE, len); + se_dma->CH[SE_DMA_TX_CHAN].CONTROL = ctrl; + se_dma->CH[SE_DMA_TX_CHAN].SRCADDR = in; + se_dma->CH[SE_DMA_TX_CHAN].DSTADDR = dst; + + if (len >= in_len) { + se_dma->CH[SE_DMA_TX_CHAN].LLI = 0; + return len; + } + + cfg_len = len; + desc_idx = 0; + while (desc_idx < SE_DMA_DESC_NUM && cfg_len < in_len) { + len = in_len - cfg_len; + if (len > SE_DMA_MAX_DESC_XFER_SIZE) { + len = SE_DMA_MAX_DESC_XFER_SIZE; + } + ctrl = SET_BITFIELD(ctrl, DMA_CONTROL_TRANSFERSIZE, len); + dma_desc[SE_DMA_TX_CHAN][desc_idx].ctrl = ctrl; + dma_desc[SE_DMA_TX_CHAN][desc_idx].src = in + cfg_len; + dma_desc[SE_DMA_TX_CHAN][desc_idx].dst = dst; + cfg_len += len; + desc_idx++; + } + + if (cfg_len < in_len) { + // Enable IRQ at the end of xfer + dma_desc[SE_DMA_TX_CHAN][desc_idx - 1].ctrl |= DMA_CONTROL_TC_IRQ; + } + + for (i = 0; i + 1 < desc_idx; i++) { + dma_desc[SE_DMA_TX_CHAN][i].lli = (uint32_t)&dma_desc[SE_DMA_TX_CHAN][i + 1]; + } + dma_desc[SE_DMA_TX_CHAN][desc_idx - 1].lli = 0; + + se_dma->CH[SE_DMA_TX_CHAN].LLI = (uint32_t)&dma_desc[SE_DMA_TX_CHAN][0]; + + return cfg_len; +} + +static void se_dma_enable_tx(const void *in, uint32_t in_len) +{ + uint32_t ctrl; + + if (in_len & (4 - 1)) { + in_len = (in_len + (4 - 1)) & ~(4 - 1); + } + + in_addr = (uint32_t)in; + total_in_len = in_len; + + /* Reset the Interrupt status */ + se_dma->INTTCCLR = DMA_STAT_CHAN(SE_DMA_TX_CHAN); + se_dma->INTERRCLR = DMA_STAT_CHAN(SE_DMA_TX_CHAN); + + ctrl = DMA_CONTROL_SBSIZE(HAL_DMA_BSIZE_16) | + DMA_CONTROL_DBSIZE(HAL_DMA_BSIZE_8) | + DMA_CONTROL_SWIDTH(HAL_DMA_WIDTH_BYTE) | + DMA_CONTROL_DWIDTH(HAL_DMA_WIDTH_WORD) | + DMA_CONTROL_SI; + + cur_in_len = se_dma_init_tx_desc((uint32_t)in, in_len, (uint32_t)&se_dmacfg->DMA_TXFIFO, ctrl); + + se_dma->CH[SE_DMA_TX_CHAN].CONFIG = DMA_CONFIG_DSTPERIPH(SE_DMA_PERIPH_TX) | + DMA_CONFIG_TRANSFERTYPE(HAL_DMA_FLOW_M2P_DMA) | + DMA_CONFIG_ERR_IRQMASK | DMA_CONFIG_TC_IRQMASK; + se_dma->CH[SE_DMA_TX_CHAN].CONFIG |= DMA_CONFIG_EN; +} + +enum HAL_SE_RET_T hal_se_open(void) +{ + if (se_enabled) { + return HAL_SE_ALREADY_OPENED; + } + + se_enabled = true; + + hal_cmu_clock_enable(HAL_CMU_MOD_H_SEC_ENG); + hal_cmu_clock_enable(HAL_CMU_MOD_P_SEC_ENG); + hal_cmu_reset_clear(HAL_CMU_MOD_H_SEC_ENG); + hal_cmu_reset_clear(HAL_CMU_MOD_P_SEC_ENG); + + se_dma_open(); + + NVIC_SetVector(SEC_ENG_IRQn, (uint32_t)sec_eng_irq_handler); + NVIC_SetPriority(SEC_ENG_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(SEC_ENG_IRQn); + NVIC_EnableIRQ(SEC_ENG_IRQn); + + return HAL_SE_OK; +} + +enum HAL_SE_RET_T hal_se_close(void) +{ + if (!se_enabled) { + return HAL_SE_NOT_OPENED; + } + + NVIC_DisableIRQ(SEC_ENG_IRQn); + + se_dma_close(); + + se_adec->ADEC_INT_MSK = ~0UL; + se_adec->ADEC_CTRL = ~0UL; + se_adec->ADEC_CTRL2 = ~0UL; + se_adec->ADEC_CTRL = 0x0000FFFF; + se_adec->ADEC_CTRL2 = 0x0000FFFF; + + hal_cmu_reset_set(HAL_CMU_MOD_H_SEC_ENG); + hal_cmu_reset_set(HAL_CMU_MOD_P_SEC_ENG); + hal_cmu_clock_disable(HAL_CMU_MOD_H_SEC_ENG); + hal_cmu_clock_disable(HAL_CMU_MOD_P_SEC_ENG); + + se_enabled = false; + + return HAL_SE_OK; +} + +static void write_mreg(volatile uint32_t *reg, const void *mem, uint32_t len) +{ + const uint32_t *p32 = (const uint32_t *)mem; + uint32_t i; + bool aligned_state; + + aligned_state = config_unaligned_access(true); + + i = 0; + while (i < len) { + *reg++ = *p32++; + i += 4; + } + + config_unaligned_access(aligned_state); +} + +POSSIBLY_UNUSED static void read_mreg(const volatile uint32_t *reg, void *mem, uint32_t len) +{ + uint32_t *p32 = (uint32_t *)mem; + uint32_t i; + bool aligned_state; + + aligned_state = config_unaligned_access(true); + + i = 0; + while (i < len) { + *p32++ = *reg++; + i += 4; + } + + config_unaligned_access(aligned_state); +} + +enum HAL_SE_RET_T se_aes_crypt(const struct HAL_SE_AES_CFG_T *cfg, bool decrypt) +{ + enum SE_AES_KEY_LEN_T key_len_t; + uint8_t modular; + + if (!se_enabled) { + return HAL_SE_NOT_OPENED; + } + + if (cfg == NULL) { + return HAL_SE_CFG_NULL; + } + if (cfg->in == NULL) { + return HAL_SE_INPUT_NULL; + } + if (cfg->out == NULL) { + return HAL_SE_OUTPUT_NULL; + } + if (cfg->key == NULL) { + return HAL_SE_KEY_NULL; + } + if (cfg->mode >= HAL_SE_AES_MODE_QTY) { + return HAL_SE_BAD_AES_MODE; + } + if (cfg->mode != HAL_SE_AES_ECB && cfg->iv == NULL) { + return HAL_SE_IV_NULL; + } + if (cfg->in_len < 16) { + return HAL_SE_BAD_INPUT_LEN; + } + if (cfg->mode == HAL_SE_AES_ECB) { + if (cfg->in_len & (16 - 1)) { + return HAL_SE_BAD_INPUT_LEN; + } + } else { + // TODO: Support padding or CBC CTS mode? + if (cfg->in_len & (16 - 1)) { + return HAL_SE_BAD_INPUT_LEN; + } + } + if (cfg->mode == HAL_SE_AES_KEY_WRAP) { + if (cfg->in_len & (8 - 1)) { + return HAL_SE_BAD_INPUT_LEN; + } + if (decrypt) { + if (cfg->out_len + 8 != cfg->in_len) { + return HAL_SE_BAD_OUTPUT_LEN; + } + } else { + if (cfg->out_len != cfg->in_len + 8) { + return HAL_SE_BAD_OUTPUT_LEN; + } + } + } else { + // If padding enabled, + // 1) ENC: cfg->out_len == ((cfg->in_len + 16) & ~(16 - 1)) + // 2) DEC: cfg->out_len == cfg->in_len + if (cfg->out_len != cfg->in_len) { + return HAL_SE_BAD_OUTPUT_LEN; + } + } + modular = 0; + if (cfg->mode == HAL_SE_AES_CTR) { + if (cfg->ctr_modular > 128) { + return HAL_SE_BAD_AES_MODULAR; + } else if (cfg->ctr_modular < 128) { + modular = cfg->ctr_modular; + } + } + + if (cfg->key_len == 16) { + key_len_t = SE_AES_KEY_128; + } else if (cfg->key_len == 24) { + key_len_t = SE_AES_KEY_192; + } else if (cfg->key_len == 32) { + key_len_t = SE_AES_KEY_256; + } else { + return HAL_SE_BAD_KEY_LEN; + } + + if (se_crypt->AES_STATUS & AES_STATUS_BUSY) { + return HAL_SE_ENG_BUSY; + } + if (se_dma->ENBLDCHNS & (DMA_STAT_CHAN(SE_DMA_RX_CHAN) | DMA_STAT_CHAN(SE_DMA_TX_CHAN))) { + return HAL_SE_DMA_BUSY; + } + + se_done_hdlr = cfg->done_hdlr; + + se_adec->ADEC_CTRL |= ADEC_CTRL_CLK_EN_15_0(SE_ACC_CLK_CRYPT) | ADEC_CTRL_RST_15_0(SE_ACC_RST_CRYPT); + se_adec->ADEC_CTRL &= ~ADEC_CTRL_RST_15_0(SE_ACC_RST_CRYPT); + se_adec->ADEC_INT = SE_ACC_INT_AES; + se_adec->ADEC_INT_MSK &= ~SE_ACC_INT_AES; + + se_dmacfg->DMA_FIFOCLR = DMA_FIFOCLR_RXFIFO_CLR | DMA_FIFOCLR_TXFIFO_CLR; + + se_acb->ACB_CTRL &= ~(ACB_CTRL_WR_CB_CTRL | ACB_CTRL_RD_CB_CTRL); + + se_crypt->ENGINE_SELECT = ENGINE_SELECT_SELECT(SE_CRYPT_AES); + // TODO: Set cts_mode, rkey + se_crypt->AES_CFG = AES_CFG_MODULAR(modular) | AES_CFG_MODE(cfg->mode) | + AES_CFG_KEYLEN(key_len_t) | (decrypt ? AES_CFG_DECRYPT : 0); + se_crypt->AES_INTRPT = ~0UL; + se_crypt->AES_INTRPT_SRC_EN = AES_INTRPT_SRC_EN_ERROR1 | AES_INTRPT_SRC_EN_ERROR2; + //se_crypt->AES_INTRPT_SRC_EN |= AES_INTRPT_SRC_EN_DONE; + // TODO: Set outputblock, resume + se_crypt->AES_CTRL |= AES_CTRL_RESET; + se_crypt->AES_CTRL &= ~AES_CTRL_RESET; + + write_mreg(&se_crypt->KEY1[0], cfg->key, cfg->key_len); + if (cfg->mode != HAL_SE_AES_ECB) { + write_mreg(&se_crypt->IV[0], cfg->iv, 16); + if (cfg->mode == HAL_SE_AES_XTS) { + write_mreg(&se_crypt->KEY2[0], cfg->key2, cfg->key_len); + } + } + + se_dma_enable_tx(cfg->in, cfg->in_len); + se_dma_enable_rx(cfg->out, cfg->out_len); + + se_crypt->AES_STREAM_SIZE = cfg->in_len; + se_crypt->AES_CMD = AES_CMD_START; + + return HAL_SE_OK; +} + +enum HAL_SE_RET_T hal_se_aes_encrypt(const struct HAL_SE_AES_CFG_T *cfg) +{ + return se_aes_crypt(cfg, false); +} + +enum HAL_SE_RET_T hal_se_aes_decrypt(const struct HAL_SE_AES_CFG_T *cfg) +{ + return se_aes_crypt(cfg, true); +} + +int hal_se_aes_busy(void) +{ + if (se_enabled) { + if (se_crypt->AES_STATUS & AES_STATUS_BUSY) { + return true; + } + if (se_dma->ENBLDCHNS & DMA_STAT_CHAN(SE_DMA_RX_CHAN)) { + return true; + } + } + return false; +} + +enum HAL_SE_RET_T hal_se_aes_reset(void) +{ + uint32_t lock; + + if (!se_enabled) { + return HAL_SE_NOT_OPENED; + } + + lock = int_lock(); + se_dma_cancel_rx(); + se_dma_cancel_tx(); + /* Clear all DMA interrupt and error flag */ + se_dma->INTTCCLR = ~0UL; + se_dma->INTERRCLR = ~0UL; + + se_adec->ADEC_CTRL |= ADEC_CTRL_CLK_EN_15_0(SE_ACC_CLK_CRYPT) | ADEC_CTRL_RST_15_0(SE_ACC_RST_CRYPT); + se_crypt->AES_INTRPT = ~0UL; + se_adec->ADEC_INT = SE_ACC_INT_AES; + int_unlock(lock); + + return HAL_SE_OK; +} + +#ifdef SEC_ENG_HAS_HASH +enum HAL_SE_RET_T se_hash_init(enum HAL_SE_HASH_MODE_T mode, const void *key, uint32_t key_len) +{ + uint32_t val; + bool hmac; + + if (!se_enabled) { + return HAL_SE_NOT_OPENED; + } + + if (mode >= HAL_SE_HASH_QTY) { + return HAL_SE_BAD_MODE; + } + + hmac = (key_len > 0); + if (hmac) { + if (key == NULL) { + return HAL_SE_KEY_NULL; + } + if (mode == HAL_SE_HASH_SHA384 || mode == HAL_SE_HASH_SHA512) { + if (key_len > 128) { + return HAL_SE_BAD_KEY_LEN; + } + } else { + if (key_len > 64) { + return HAL_SE_BAD_KEY_LEN; + } + } + } + + if (se_hash->HASH_STATUS & HASH_STATUS_HASH_BUSY) { + return HAL_SE_ENG_BUSY; + } + if (se_dma->ENBLDCHNS & DMA_STAT_CHAN(SE_DMA_TX_CHAN)) { + return HAL_SE_DMA_BUSY; + } + + se_adec->ADEC_CTRL |= ADEC_CTRL_CLK_EN_15_0(SE_ACC_CLK_HASH) | ADEC_CTRL_RST_15_0(SE_ACC_RST_HASH); + se_adec->ADEC_CTRL &= ~ADEC_CTRL_RST_15_0(SE_ACC_RST_HASH); + se_adec->ADEC_INT = SE_ACC_INT_HASH; + se_adec->ADEC_INT_MSK |= SE_ACC_INT_HASH; + + se_dmacfg->DMA_FIFOCLR = DMA_FIFOCLR_TXFIFO_CLR; + + se_acb->ACB_CTRL |= ACB_CTRL_RD_CB_CTRL; + + se_hash->HASH_CFG = HASH_CFG_ALG_SELECT(mode); + val = se_hash->HASH_CTRL; + //val |= HASH_CTRL_RESET; + se_hash->HASH_CTRL = val; + val &= ~(HASH_CTRL_RESET | HASH_CTRL_HW_PADDING); + se_hash->HASH_CTRL = val; + val = SET_BITFIELD(val, HASH_CTRL_HASH_OP_MODE, SE_HASH_OP_INIT); + se_hash->HASH_CTRL = val; + if (hmac) { + se_hash->HASH_CFG |= HASH_CFG_HASH_MODE; + write_mreg(&se_hash->HMAC_KEY[0], key, key_len); + se_hash->HMAC_KEY_LEN = key_len; + } + se_hash->HASH_CMD = HASH_CMD_START; + + // HASH: 500ns; HMAC: 3000ns + while ((se_hash->HASH_STATUS & HASH_STATUS_HASH_DONE) == 0); + + return HAL_SE_OK; +} + +enum HAL_SE_RET_T hal_se_hash_init(enum HAL_SE_HASH_MODE_T mode) +{ + return se_hash_init(mode, NULL, 0); +} + +enum HAL_SE_RET_T se_hash_start(const struct HAL_SE_HASH_CFG_T *cfg, enum SE_HASH_OP_T op, uint64_t total_in_len) +{ + enum SE_HASH_OP_T prev_op; + uint32_t val; + + if (!se_enabled) { + return HAL_SE_NOT_OPENED; + } + + if (cfg == NULL) { + return HAL_SE_CFG_NULL; + } + if (op == SE_HASH_OP_FINAL) { + if (cfg->in == NULL && cfg->in_len) { + return HAL_SE_INPUT_NULL; + } + } else { + if (cfg->in == NULL) { + return HAL_SE_INPUT_NULL; + } + if (cfg->in_len == 0) { + return HAL_SE_BAD_INPUT_LEN; + } + if (cfg->in_len & (64 - 1)) { + return HAL_SE_BAD_INPUT_LEN; + } + } + + prev_op = GET_BITFIELD(se_hash->HASH_CTRL, HASH_CTRL_HASH_OP_MODE); + if (prev_op != SE_HASH_OP_INIT && prev_op != SE_HASH_OP_UPDATE) { + return HAL_SE_BAD_OP; + } + if (se_hash->HASH_STATUS & HASH_STATUS_HASH_BUSY) { + return HAL_SE_ENG_BUSY; + } + if (se_dma->ENBLDCHNS & DMA_STAT_CHAN(SE_DMA_TX_CHAN)) { + return HAL_SE_DMA_BUSY; + } + + se_done_hdlr = cfg->done_hdlr; + + se_hash->HASH_STATUS = ~0UL; + se_adec->ADEC_INT = SE_ACC_INT_HASH; + se_adec->ADEC_INT_MSK &= ~SE_ACC_INT_HASH; + + se_dmacfg->DMA_FIFOCLR = DMA_FIFOCLR_TXFIFO_CLR; + + if (cfg->in_len) { + se_dma_enable_tx(cfg->in, cfg->in_len); + } + + val = se_hash->HASH_CTRL; + val = SET_BITFIELD(val, HASH_CTRL_HASH_OP_MODE, op); + if (op == SE_HASH_OP_UPDATE) { + val &= ~HASH_CTRL_HW_PADDING; + } else { + val |= HASH_CTRL_HW_PADDING; + } + se_hash->HASH_CTRL = val; + if (op == SE_HASH_OP_FINAL) { + se_hash->HASH_MSG_SIZE_L = (uint32_t)total_in_len; + se_hash->HASH_MSG_SIZE_H = (uint32_t)(total_in_len >> 32); + } + se_hash->HASH_SEG_SIZE = cfg->in_len; + se_hash->HASH_CMD = HASH_CMD_START; + + return HAL_SE_OK; +} + +enum HAL_SE_RET_T hal_se_hash_update(const struct HAL_SE_HASH_CFG_T *cfg) +{ + return se_hash_start(cfg, SE_HASH_OP_UPDATE, 0); +} + +enum HAL_SE_RET_T hal_se_hash_final(const struct HAL_SE_HASH_CFG_T *cfg, uint64_t total_in_len) +{ + return se_hash_start(cfg, SE_HASH_OP_FINAL, total_in_len); +} + +enum HAL_SE_RET_T hal_se_hash(enum HAL_SE_HASH_MODE_T mode, const struct HAL_SE_HASH_CFG_T *cfg) +{ + enum HAL_SE_RET_T ret; + + ret = hal_se_hash_init(mode); + if (ret != HAL_SE_OK) { + return ret; + } + ret = hal_se_hash_final(cfg, cfg->in_len); + return ret; +} + +static uint32_t se_hash_get_digest_len(void) +{ + enum HAL_SE_HASH_MODE_T mode; + uint32_t max_len; + + mode = GET_BITFIELD(se_hash->HASH_CFG, HASH_CFG_ALG_SELECT); + if (mode == HAL_SE_HASH_MD5) { + max_len = 16; + } else if (mode == HAL_SE_HASH_SHA1) { + max_len = 20; + } else if (mode == HAL_SE_HASH_SHA224) { + max_len = 28; + } else if (mode == HAL_SE_HASH_SHA256) { + max_len = 32; + } else if (mode == HAL_SE_HASH_SHA384) { + max_len = 48; + } else { + max_len = 64; + } + + return max_len; +} + +enum HAL_SE_RET_T hal_se_hash_get_digest(void *out, uint32_t out_len, uint32_t *real_len) +{ + enum SE_HASH_OP_T prev_op; + uint32_t max_len; + int i; + + if (!se_enabled) { + return HAL_SE_NOT_OPENED; + } + + if (out == NULL) { + return HAL_SE_OUTPUT_NULL; + } + if (out_len & (4 - 1)) { + return HAL_SE_BAD_OUTPUT_LEN; + } + + prev_op = GET_BITFIELD(se_hash->HASH_CTRL, HASH_CTRL_HASH_OP_MODE); + if (prev_op != SE_HASH_OP_FINAL) { + return HAL_SE_BAD_OP; + } + if (se_hash->HASH_STATUS & HASH_STATUS_HASH_BUSY) { + return HAL_SE_ENG_BUSY; + } + if (se_dma->ENBLDCHNS & DMA_STAT_CHAN(SE_DMA_TX_CHAN)) { + return HAL_SE_DMA_BUSY; + } + + max_len = se_hash_get_digest_len(); + if (out_len > max_len) { + out_len = max_len; + } + if (real_len) { + *real_len = out_len; + } + if (out_len > 32) { + for (i = 0; i < out_len / 8; i++) { + read_mreg(&se_hash->HASH_CTX_H[i], out, 4); + read_mreg(&se_hash->HASH_CTX[i], out + 4, 4); + out += 8; + } + } else { + read_mreg(&se_hash->HASH_CTX[0], out, out_len); + } + + return HAL_SE_OK; +} + +int hal_se_hash_busy(void) +{ + if (se_enabled) { + if (se_hash->HASH_STATUS & HASH_STATUS_HASH_BUSY) { + return true; + } + if (se_dma->ENBLDCHNS & DMA_STAT_CHAN(SE_DMA_TX_CHAN)) { + return true; + } + } + return false; +} + +enum HAL_SE_RET_T hal_se_hash_reset(void) +{ + uint32_t lock; + + if (!se_enabled) { + return HAL_SE_NOT_OPENED; + } + + lock = int_lock(); + se_dma_cancel_tx(); + /* Clear all DMA interrupt and error flag */ + se_dma->INTTCCLR = ~0UL; + se_dma->INTERRCLR = ~0UL; + + se_adec->ADEC_CTRL |= ADEC_CTRL_CLK_EN_15_0(SE_ACC_CLK_HASH) | ADEC_CTRL_RST_15_0(SE_ACC_RST_HASH); + se_hash->HASH_STATUS = ~0UL; + se_adec->ADEC_INT = SE_ACC_INT_HASH; + int_unlock(lock); + + return HAL_SE_OK; +} + +enum HAL_SE_RET_T hal_se_hmac_init(enum HAL_SE_HASH_MODE_T mode, const void *key, uint32_t key_len) +{ + if (key_len == 0) { + return HAL_SE_BAD_KEY_LEN; + } + + return se_hash_init(mode, key, key_len); +} + +enum HAL_SE_RET_T hal_se_hmac_update(const struct HAL_SE_HASH_CFG_T *cfg) __attribute__((alias("hal_se_hash_update"))); + +enum HAL_SE_RET_T hal_se_hmac_final(const struct HAL_SE_HASH_CFG_T *cfg, uint64_t total_in_len) __attribute__((alias("hal_se_hash_final"))); + +enum HAL_SE_RET_T hal_se_hmac(enum HAL_SE_HASH_MODE_T mode, const void *key, uint32_t key_len, const struct HAL_SE_HASH_CFG_T *cfg) +{ + enum HAL_SE_RET_T ret; + + ret = hal_se_hmac_init(mode, key, key_len); + if (ret != HAL_SE_OK) { + return ret; + } + ret = hal_se_hmac_final(cfg, cfg->in_len); + return ret; +} + +enum HAL_SE_RET_T hal_se_hmac_get_digest(void *out, uint32_t out_len, uint32_t *real_len) __attribute__((alias("hal_se_hash_get_digest"))); + +int hal_se_hmac_busy(void) __attribute__((alias("hal_se_hash_busy"))); + +enum HAL_SE_RET_T hal_se_hmac_reset(void) __attribute__((alias("hal_se_hash_reset"))); + +#endif + +#endif + diff --git a/platform/hal/hal_sec_eng.h b/platform/hal/hal_sec_eng.h new file mode 100644 index 0000000..a97d19a --- /dev/null +++ b/platform/hal/hal_sec_eng.h @@ -0,0 +1,149 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_SEC_ENG_H__ +#define __HAL_SEC_ENG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "stdbool.h" +#include "stdint.h" +#include "hal_dma.h" + +enum HAL_SE_RET_T { + HAL_SE_OK, + HAL_SE_ERR, + HAL_SE_ALREADY_OPENED, + HAL_SE_NOT_OPENED, + HAL_SE_ENG_BUSY, + HAL_SE_DMA_BUSY, + HAL_SE_CFG_NULL, + HAL_SE_INPUT_NULL, + HAL_SE_OUTPUT_NULL, + HAL_SE_KEY_NULL, + HAL_SE_IV_NULL, + HAL_SE_KEY2_NULL, + HAL_SE_BAD_INPUT_LEN, + HAL_SE_BAD_OUTPUT_LEN, + HAL_SE_BAD_KEY_LEN, + HAL_SE_BAD_AES_MODE, + HAL_SE_BAD_AES_MODULAR, + HAL_SE_BAD_MODE, + HAL_SE_BAD_OP, +}; + +enum HAL_SE_AES_MODE_T { + HAL_SE_AES_ECB = 0, + HAL_SE_AES_CBC = 1, + HAL_SE_AES_CTR = 2, + HAL_SE_AES_XTS = 3, + HAL_SE_AES_KEY_WRAP = 4, + + HAL_SE_AES_MODE_QTY, +}; + +enum HAL_SE_DONE_ERR_T { + HAL_SE_DONE_OK = 0, + HAL_SE_DONE_ERR_DMA_IN, + HAL_SE_DONE_ERR_DMA_OUT, + HAL_SE_DONE_ERR_DMA_IN_REMAIN, + HAL_SE_DONE_ERR_DMA_OUT_REMAIN, + HAL_SE_DONE_ERR_ENG_ERR1, + HAL_SE_DONE_ERR_ENG_ERR2, + HAL_SE_DONE_ERR_ENG_ERR1_ERR2, +}; + +enum HAL_SE_HASH_MODE_T { + HAL_SE_HASH_SHA1 = 0, + HAL_SE_HASH_SHA256, + HAL_SE_HASH_SHA224, + HAL_SE_HASH_MD5, + HAL_SE_HASH_SHA512, + HAL_SE_HASH_SHA384, + + HAL_SE_HASH_QTY, +}; + +typedef void (*HAL_SC_DONE_HANDLER_T)(void *buf, uint32_t len, enum HAL_SE_DONE_ERR_T err); + +struct HAL_SE_AES_CFG_T { + enum HAL_SE_AES_MODE_T mode; + const void *key; + uint16_t key_len; + uint8_t ctr_modular; + const void *key2; + const void *iv; + const void *in; + uint32_t in_len; + void *out; + uint32_t out_len; + HAL_SC_DONE_HANDLER_T done_hdlr; +}; + +struct HAL_SE_HASH_CFG_T { + const void *in; + uint32_t in_len; + HAL_SC_DONE_HANDLER_T done_hdlr; +}; + +enum HAL_SE_RET_T hal_se_open(void); + +enum HAL_SE_RET_T hal_se_close(void); + +enum HAL_SE_RET_T hal_se_aes_encrypt(const struct HAL_SE_AES_CFG_T *cfg); + +enum HAL_SE_RET_T hal_se_aes_decrypt(const struct HAL_SE_AES_CFG_T *cfg); + +int hal_se_aes_busy(void); + +enum HAL_SE_RET_T hal_se_aes_reset(void); + +enum HAL_SE_RET_T hal_se_hash_init(enum HAL_SE_HASH_MODE_T mode); + +enum HAL_SE_RET_T hal_se_hash_update(const struct HAL_SE_HASH_CFG_T *cfg); + +enum HAL_SE_RET_T hal_se_hash_final(const struct HAL_SE_HASH_CFG_T *cfg, uint64_t total_in_len); + +enum HAL_SE_RET_T hal_se_hash(enum HAL_SE_HASH_MODE_T mode, const struct HAL_SE_HASH_CFG_T *cfg); + +enum HAL_SE_RET_T hal_se_hash_get_digest(void *out, uint32_t out_len, uint32_t *real_len); + +int hal_se_hash_busy(void); + +enum HAL_SE_RET_T hal_se_hash_reset(void); + +enum HAL_SE_RET_T hal_se_hmac_init(enum HAL_SE_HASH_MODE_T mode, const void *key, uint32_t key_len); + +enum HAL_SE_RET_T hal_se_hmac_update(const struct HAL_SE_HASH_CFG_T *cfg); + +enum HAL_SE_RET_T hal_se_hmac_final(const struct HAL_SE_HASH_CFG_T *cfg, uint64_t total_in_len); + +enum HAL_SE_RET_T hal_se_hmac(enum HAL_SE_HASH_MODE_T mode, const void *key, uint32_t key_len, const struct HAL_SE_HASH_CFG_T *cfg); + +enum HAL_SE_RET_T hal_se_hmac_get_digest(void *out, uint32_t out_len, uint32_t *real_len); + +int hal_se_hmac_busy(void); + +enum HAL_SE_RET_T hal_se_hmac_reset(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_sensor_eng.h b/platform/hal/hal_sensor_eng.h new file mode 100644 index 0000000..82ab18e --- /dev/null +++ b/platform/hal/hal_sensor_eng.h @@ -0,0 +1,63 @@ +#ifndef __HAL_SENSOR_HUB_H__ +#define __HAL_SENSOR_HUB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_dma.h" +#include "hal_gpio.h" + +enum HAL_SENSOR_ENGINE_ID_T { + HAL_SENSOR_ENGINE_ID_0 = 0, + HAL_SENSOR_ENGINE_ID_1, + HAL_SENSOR_ENGINE_ID_2, + HAL_SENSOR_ENGINE_ID_3, + + HAL_SENSOR_ENGINE_ID_QTY, +}; + +enum HAL_SENSOR_ENGINE_TRIGGER_T { + HAL_SENSOR_ENGINE_TRIGGER_TIMER = 0, + HAL_SENSOR_ENGINE_TRIGGER_GPIO, + + HAL_SENSOR_ENGINE_TRIGGER_QTY, +}; + +enum HAL_SENSOR_ENGINE_DEVICE_T { + HAL_SENSOR_ENGINE_DEVICE_I2C0 = 0, + HAL_SENSOR_ENGINE_DEVICE_I2C1, + HAL_SENSOR_ENGINE_DEVICE_SPI0 = 4, + HAL_SENSOR_ENGINE_DEVICE_SPI1, + HAL_SENSOR_ENGINE_DEVICE_SPI2, +}; + +typedef void (*HAL_SENSOR_ENG_HANDLER_T)(enum HAL_SENSOR_ENGINE_ID_T id, enum HAL_SENSOR_ENGINE_DEVICE_T device, const uint8_t *buf, uint32_t len); + +struct HAL_SENSOR_ENGINE_CFG_T { + enum HAL_SENSOR_ENGINE_ID_T id; + enum HAL_SENSOR_ENGINE_DEVICE_T device; + enum HAL_SENSOR_ENGINE_TRIGGER_T trigger_type; + enum HAL_GPIO_PIN_T trigger_gpio; + uint32_t period_us; + struct HAL_DMA_CH_CFG_T *tx_dma_cfg; + struct HAL_DMA_CH_CFG_T *rx_dma_cfg; + uint16_t device_address; + uint16_t rx_burst_len; + uint8_t rx_burst_cnt; + uint8_t data_to_vad; + HAL_SENSOR_ENG_HANDLER_T handler; +}; + +int hal_sensor_engine_open(const struct HAL_SENSOR_ENGINE_CFG_T *cfg); +int hal_sensor_engine_close(enum HAL_SENSOR_ENGINE_ID_T id); + +void hal_sensor_process_rx_buffer(void); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/platform/hal/hal_slave_i2c.c b/platform/hal/hal_slave_i2c.c new file mode 100644 index 0000000..64ae1a7 --- /dev/null +++ b/platform/hal/hal_slave_i2c.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" + +#ifdef I2C_SLAVE_BASE + +#include "hal_slave_i2c.h" +#include "reg_slave_i2c.h" + +static struct SLAVE_I2C_T * const slave_i2c = (struct SLAVE_I2C_T *)I2C_SLAVE_BASE; + +void hal_slave_i2c_enable(void) +{ + slave_i2c->EN |= I2C_EN; +} + +void hal_slave_i2c_disable(void) +{ + slave_i2c->EN &= ~I2C_EN; +} + +uint32_t hal_slave_i2c_get_filter_len(void) +{ + return GET_BITFIELD(slave_i2c->EN, R_FILTERLEN); +} + +int hal_slave_i2c_set_filter_len(uint32_t len) +{ + if (len > (W_FILTERLEN_MASK >> W_FILTERLEN_SHIFT)) { + return 1; + } + slave_i2c->EN = SET_BITFIELD(slave_i2c->EN, W_FILTERLEN, len); + return 0; +} + +uint32_t hal_slave_i2c_get_dev_id(void) +{ + return GET_BITFIELD(slave_i2c->ID, DEV_ID); +} + +int hal_slave_i2c_set_dev_id(uint32_t dev_id) +{ + if (dev_id > 0x7F) { + return 1; + } + slave_i2c->ID = SET_BITFIELD(slave_i2c->ID, DEV_ID, dev_id); + return 0; +} + +void hal_slave_i2c_bypass_timeout(void) +{ + slave_i2c->TBP |= TIMEOUT_BYPASS; +} + +void hal_slave_i2c_restore_timeout(void) +{ + slave_i2c->TBP &= ~TIMEOUT_BYPASS; +} + +#endif diff --git a/platform/hal/hal_slave_i2c.h b/platform/hal/hal_slave_i2c.h new file mode 100644 index 0000000..806d076 --- /dev/null +++ b/platform/hal/hal_slave_i2c.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_SLAVE_I2C_H__ +#define __HAL_SLAVE_I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +void hal_slave_i2c_enable(void); + +void hal_slave_i2c_disable(void); + +uint32_t hal_slave_i2c_get_filter_len(void); + +int hal_slave_i2c_set_filter_len(uint32_t len); + +uint32_t hal_slave_i2c_get_dev_id(void); + +int hal_slave_i2c_set_dev_id(uint32_t dev_id); + +void hal_slave_i2c_bypass_timeout(void); + +void hal_slave_i2c_restore_timeout(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_sleep.c b/platform/hal/hal_sleep.c new file mode 100644 index 0000000..335b31b --- /dev/null +++ b/platform/hal/hal_sleep.c @@ -0,0 +1,587 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_sleep.h" +#include "hal_cmu.h" +#include "hal_location.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "hal_sysfreq.h" +#include "hal_dma.h" +#include "hal_norflash.h" +#include "hal_gpadc.h" +#include "analog.h" +#include "pmu.h" +#include "cmsis.h" + +//static uint8_t SRAM_STACK_LOC sleep_stack[128]; + +static HAL_SLEEP_HOOK_HANDLER sleep_hook_handler[HAL_SLEEP_HOOK_USER_QTY]; +static HAL_DEEP_SLEEP_HOOK_HANDLER deep_sleep_hook_handler[HAL_DEEP_SLEEP_HOOK_USER_QTY]; + +static uint32_t cpu_wake_lock_map; +static uint32_t sys_wake_lock_map; +static uint32_t chip_wake_lock_map; + +#ifdef SLEEP_STATS_TRACE +static uint32_t stats_trace_interval; +static uint32_t stats_trace_time; +#endif +static uint32_t stats_interval; +static uint32_t stats_start_time; +static uint32_t light_sleep_time; +static uint32_t sys_deep_sleep_time; +static uint32_t chip_deep_sleep_time; +static bool stats_started; +static bool stats_valid; +static uint8_t light_sleep_ratio; +static uint8_t sys_deep_sleep_ratio; +static uint8_t chip_deep_sleep_ratio; + +void hal_sleep_start_stats(uint32_t stats_interval_ms, uint32_t trace_interval_ms) +{ + uint32_t lock; + + lock = int_lock(); + if (stats_interval_ms) { + stats_interval = MS_TO_TICKS(stats_interval_ms); + stats_start_time = hal_sys_timer_get(); + light_sleep_time = 0; + sys_deep_sleep_time = 0; + chip_deep_sleep_time = 0; + stats_valid = false; + stats_started = true; + } else { + stats_started = false; + } + int_unlock(lock); + +#ifdef SLEEP_STATS_TRACE + if (stats_interval_ms && trace_interval_ms) { + stats_trace_interval = MS_TO_TICKS(trace_interval_ms); + } else { + stats_trace_interval = 0; + } +#endif +} + +int hal_sleep_get_stats(struct CPU_USAGE_T *usage) +{ + int ret; + uint32_t lock; + + lock = int_lock(); + if (stats_valid) { + usage->light_sleep = light_sleep_ratio; + usage->sys_deep_sleep = sys_deep_sleep_ratio; + usage->chip_deep_sleep = chip_deep_sleep_ratio; + usage->busy = 100 - (light_sleep_ratio + sys_deep_sleep_ratio + chip_deep_sleep_ratio); + ret = 0; + } else { + ret = 1; + } + int_unlock(lock); + + return ret; +} + +static int hal_sleep_cpu_busy(void) +{ + if (cpu_wake_lock_map || hal_cmu_lpu_busy()) { + return 1; + } else { + return 0; + } +} + +static int hal_sleep_sys_busy(void) +{ + if (sys_wake_lock_map || hal_sysfreq_busy() || hal_dma_busy()) { + return 1; + } else { + return 0; + } +} + +int hal_sleep_set_sleep_hook(enum HAL_SLEEP_HOOK_USER_T user, HAL_SLEEP_HOOK_HANDLER handler) +{ + if (user >= ARRAY_SIZE(sleep_hook_handler)) { + return 1; + } + sleep_hook_handler[user] = handler; + return 0; +} + +static int SRAM_TEXT_LOC hal_sleep_exec_sleep_hook(void) +{ + int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(sleep_hook_handler); i++) { + if (sleep_hook_handler[i]) { + ret = sleep_hook_handler[i](); + if (ret) { + return ret; + } + } + } + + return 0; +} + +int hal_sleep_set_deep_sleep_hook(enum HAL_DEEP_SLEEP_HOOK_USER_T user, HAL_DEEP_SLEEP_HOOK_HANDLER handler) +{ + if (user >= ARRAY_SIZE(deep_sleep_hook_handler)) { + return 1; + } + deep_sleep_hook_handler[user] = handler; + return 0; +} + +static int SRAM_TEXT_LOC hal_sleep_exec_deep_sleep_hook(void) +{ + int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(deep_sleep_hook_handler); i++) { + if (deep_sleep_hook_handler[i]) { + ret = deep_sleep_hook_handler[i](); + if (ret) { + return ret; + } + } + } + + return 0; +} + +int SRAM_TEXT_LOC hal_sleep_irq_pending(void) +{ +#if defined(__GIC_PRESENT) && (__GIC_PRESENT) + int i; + + for (i = 0; i < (USER_IRQn_QTY + 31) / 32; i++) { + if (GICDistributor->ICPENDR[i] & GICDistributor->ISENABLER[i]) { + return 1; + } + } +#else +#if 0 + int i; + + for (i = 0; i < (USER_IRQn_QTY + 31) / 32; i++) { + if (NVIC->ICPR[i] & NVIC->ISER[i]) { + return 1; + } + } +#else + // If there is any pending and enabled exception (including sysTick) + if (SCB->ICSR & SCB_ICSR_VECTPENDING_Msk) { + return 1; + } +#endif +#endif + + return 0; +} + +int SRAM_TEXT_LOC hal_sleep_specific_irq_pending(const uint32_t *irq, uint32_t cnt) +{ + int i; + uint32_t check_cnt; + + check_cnt = (USER_IRQn_QTY + 31) / 32; + if (check_cnt > cnt) { + check_cnt = cnt; + } + +#if defined(__GIC_PRESENT) && (__GIC_PRESENT) + for (i = 0; i < check_cnt; i++) { + if (GICDistributor->ICPENDR[i] & GICDistributor->ISENABLER[i] & irq[i]) { + return 1; + } + } +#else + for (i = 0; i < check_cnt; i++) { + if (NVIC->ICPR[i] & NVIC->ISER[i] & irq[i]) { + return 1; + } + } +#endif + + return 0; +} + +void WEAK bt_drv_sleep(void) +{ +} + +void WEAK bt_drv_wakeup(void) +{ +} + +static enum HAL_SLEEP_STATUS_T SRAM_TEXT_LOC hal_sleep_lowpower_mode(void) +{ + enum HAL_SLEEP_STATUS_T ret; + enum HAL_CMU_LPU_SLEEP_MODE_T mode; + uint32_t time = 0; + + ret = HAL_SLEEP_STATUS_LIGHT; + + // Deep sleep hook + if (hal_sleep_exec_deep_sleep_hook() || hal_trace_busy()) { + return ret; + } + + if (stats_started) { + time = hal_sys_timer_get(); + } + + // Modules (except for psram and flash) sleep + hal_gpadc_sleep(); + if (chip_wake_lock_map == 0) { + analog_sleep(); + pmu_sleep(); + } + bt_drv_sleep(); + + // End of sleep + + //psram_sleep(); + hal_norflash_sleep(HAL_NORFLASH_ID_0); + + // Now neither psram nor flash are usable + + if (!hal_sleep_irq_pending()) { + if (chip_wake_lock_map) { + mode = HAL_CMU_LPU_SLEEP_MODE_SYS; + } else { + mode = HAL_CMU_LPU_SLEEP_MODE_CHIP; + } + hal_cmu_lpu_sleep(mode); + ret = HAL_SLEEP_STATUS_DEEP; + } + + hal_norflash_wakeup(HAL_NORFLASH_ID_0); + //psram_wakeup(); + + // Now both psram and flash are usable + + if (chip_wake_lock_map == 0) { + pmu_wakeup(); + analog_wakeup(); + } + bt_drv_wakeup(); + + hal_gpadc_wakeup(); + // Modules (except for psram and flash) wakeup + + // End of wakeup + + if (stats_started) { + time = hal_sys_timer_get() - time; + if (chip_wake_lock_map) { + sys_deep_sleep_time += time; + } else { + chip_deep_sleep_time += time; + } + } + + return ret; +} + +// GCC has trouble in detecting static function usage in embedded ASM statements. +// The following function might be optimized away if there is no explicted call in C codes. +// Specifying "used" (or "noclone") attribute on the function can avoid the mistaken optimization. +static enum HAL_SLEEP_STATUS_T SRAM_TEXT_LOC NOINLINE USED hal_sleep_proc(int light_sleep) +{ + enum HAL_SLEEP_STATUS_T ret; + uint32_t time = 0; + uint32_t interval; + + ret = HAL_SLEEP_STATUS_LIGHT; + + // Check the sleep conditions in interrupt-locked context + if (hal_sleep_cpu_busy()) { + // Cannot sleep + } else { + // Sleep hook + if (hal_sleep_exec_sleep_hook()) { + goto _exit_sleep; + } + + if (hal_sleep_sys_busy()) { + // Light sleep + + if (stats_started) { + time = hal_sys_timer_get(); + } + +#ifdef NO_LIGHT_SLEEP + // WFI during USB ISO transfer might generate very weak (0.1 mV) 1K tone interference ??? + while (!hal_sleep_irq_pending()); +#else +#ifndef __ARM_ARCH_ISA_ARM + SCB->SCR = 0; +#endif + __DSB(); + __WFI(); +#endif + + if (stats_started) { + light_sleep_time += hal_sys_timer_get() - time; + } +#ifdef DEBUG + } else if (hal_trace_busy()) { + // Light sleep with trace busy only + + if (stats_started) { + time = hal_sys_timer_get(); + } + + // No irq will be generated when trace becomes idle, so the trace status should + // be kept polling actively instead of entering WFI + while (!hal_sleep_irq_pending() && hal_trace_busy()); + + if (stats_started) { + light_sleep_time += hal_sys_timer_get() - time; + } + + if (!hal_sleep_irq_pending()) { + goto _deep_sleep; + } +#endif + } else { + // Deep sleep + +_deep_sleep: POSSIBLY_UNUSED; + + if (light_sleep) { + ret = HAL_SLEEP_STATUS_DEEP; + } else { + ret = hal_sleep_lowpower_mode(); + } + } + } + +_exit_sleep: + if (stats_started) { + time = hal_sys_timer_get(); + interval = time - stats_start_time; + if (interval >= stats_interval) { + if (light_sleep_time > UINT32_MAX / 100) { + light_sleep_ratio = (uint64_t)light_sleep_time * 100 / interval; + } else { + light_sleep_ratio = light_sleep_time * 100 / interval; + } + if (sys_deep_sleep_time > UINT32_MAX / 100) { + sys_deep_sleep_ratio = (uint64_t)sys_deep_sleep_time * 100 / interval; + } else { + sys_deep_sleep_ratio = sys_deep_sleep_time * 100 / interval; + } + if (chip_deep_sleep_time > UINT32_MAX / 100) { + chip_deep_sleep_ratio = (uint64_t)chip_deep_sleep_time * 100 / interval; + } else { + chip_deep_sleep_ratio = chip_deep_sleep_time * 100 / interval; + } + stats_valid = true; + light_sleep_time = 0; + sys_deep_sleep_time = 0; + chip_deep_sleep_time = 0; + stats_start_time = time; + } +#ifdef SLEEP_STATS_TRACE + if (stats_valid && stats_trace_interval) { + uint32_t time = hal_sys_timer_get(); + if (time - stats_trace_time >= stats_trace_interval) { + TRACE(4,"CPU USAGE: busy=%d light=%d sys_deep=%d chip_deep=%d", + 100 - (light_sleep_ratio + sys_deep_sleep_ratio + chip_deep_sleep_ratio), + light_sleep_ratio, sys_deep_sleep_ratio, chip_deep_sleep_ratio); + stats_trace_time = time; +#ifdef DEBUG_SLEEP_USER + TRACE(4,"SLEEP_USER: cpulock=0x%X syslock=0x%X irq=0x%08X_%08X", + cpu_wake_lock_map, sys_wake_lock_map, (NVIC->ICPR[1] & NVIC->ISER[1]), (NVIC->ICPR[0] & NVIC->ISER[0])); + hal_sysfreq_print(); +#endif + } + } +#endif + } + + return ret; +} + +#ifndef __ARM_ARCH_ISA_ARM +static enum HAL_SLEEP_STATUS_T SRAM_TEXT_LOC NOINLINE USED NAKED hal_sleep_deep_sleep_wrapper(void) +{ + asm volatile( + "push {r4, lr} \n" + // Switch current stack pointer to MSP + "mrs r4, control \n" + "bic r4, #2 \n" + "msr control, r4 \n" + "isb \n" + "movs r0, #0 \n" + "bl hal_sleep_proc \n" + // Switch current stack pointer back to PSP + "orr r4, #2 \n" + "msr control, r4 \n" + "isb \n" + "pop {r4, pc} \n" + ); + +#ifndef __ARMCC_VERSION + return HAL_SLEEP_STATUS_LIGHT; +#endif +} +#endif + +enum HAL_SLEEP_STATUS_T SRAM_TEXT_LOC hal_sleep_enter_sleep(void) +{ + enum HAL_SLEEP_STATUS_T ret; + uint32_t lock; + + ret = HAL_SLEEP_STATUS_LIGHT; + +#ifdef NO_SLEEP + return ret; +#endif + + lock = int_lock_global(); + +#ifndef __ARM_ARCH_ISA_ARM + if (__get_CONTROL() & 0x02) { + ret = hal_sleep_deep_sleep_wrapper(); + } else +#endif + { + ret = hal_sleep_proc(false); + } + + int_unlock_global(lock); + + return ret; +} + +enum HAL_SLEEP_STATUS_T SRAM_TEXT_LOC hal_sleep_light_sleep(void) +{ + enum HAL_SLEEP_STATUS_T ret; + uint32_t lock; + + ret = HAL_SLEEP_STATUS_LIGHT; + +#ifdef NO_SLEEP + return ret; +#endif + + lock = int_lock_global(); + + ret = hal_sleep_proc(true); + + int_unlock_global(lock); + + return ret; +} + +int hal_cpu_wake_lock(enum HAL_CPU_WAKE_LOCK_USER_T user) +{ + uint32_t lock; + + if (user >= HAL_CPU_WAKE_LOCK_USER_QTY) { + return 1; + } + + lock = int_lock(); + cpu_wake_lock_map |= (1 << user); + int_unlock(lock); + + return 0; +} + +int hal_cpu_wake_unlock(enum HAL_CPU_WAKE_LOCK_USER_T user) +{ + uint32_t lock; + + if (user >= HAL_CPU_WAKE_LOCK_USER_QTY) { + return 1; + } + + lock = int_lock(); + cpu_wake_lock_map &= ~(1 << user); + int_unlock(lock); + + return 0; +} + +int hal_sys_wake_lock(enum HAL_SYS_WAKE_LOCK_USER_T user) +{ + uint32_t lock; + + if (user >= HAL_SYS_WAKE_LOCK_USER_QTY) { + return 1; + } + + lock = int_lock(); + sys_wake_lock_map |= (1 << user); + int_unlock(lock); + + return 0; +} + +int hal_sys_wake_unlock(enum HAL_SYS_WAKE_LOCK_USER_T user) +{ + uint32_t lock; + + if (user >= HAL_SYS_WAKE_LOCK_USER_QTY) { + return 1; + } + + lock = int_lock(); + sys_wake_lock_map &= ~(1 << user); + int_unlock(lock); + + return 0; +} + +int hal_chip_wake_lock(enum HAL_CHIP_WAKE_LOCK_USER_T user) +{ + uint32_t lock; + + if (user >= HAL_CHIP_WAKE_LOCK_USER_QTY) { + return 1; + } + + lock = int_lock(); + chip_wake_lock_map |= (1 << user); + int_unlock(lock); + + return 0; +} + +int hal_chip_wake_unlock(enum HAL_CHIP_WAKE_LOCK_USER_T user) +{ + uint32_t lock; + + if (user >= HAL_CHIP_WAKE_LOCK_USER_QTY) { + return 1; + } + + lock = int_lock(); + chip_wake_lock_map &= ~(1 << user); + int_unlock(lock); + + return 0; +} + diff --git a/platform/hal/hal_sleep.h b/platform/hal/hal_sleep.h new file mode 100644 index 0000000..b81f544 --- /dev/null +++ b/platform/hal/hal_sleep.h @@ -0,0 +1,201 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_SLEEP_H__ +#define __HAL_SLEEP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +enum HAL_CPU_WAKE_LOCK_USER_T { + HAL_CPU_WAKE_LOCK_USER_RTOS, + HAL_CPU_WAKE_LOCK_USER_EXTERNAL, + HAL_CPU_WAKE_LOCK_USER_AUDIOFLINGER, + HAL_CPU_WAKE_LOCK_USER_3, + HAL_CPU_WAKE_LOCK_USER_4, + HAL_CPU_WAKE_LOCK_USER_5, + HAL_CPU_WAKE_LOCK_USER_6, + HAL_CPU_WAKE_LOCK_USER_7, + HAL_CPU_WAKE_LOCK_USER_8, + HAL_CPU_WAKE_LOCK_USER_9, + HAL_CPU_WAKE_LOCK_USER_10, + HAL_CPU_WAKE_LOCK_USER_11, + HAL_CPU_WAKE_LOCK_USER_12, + HAL_CPU_WAKE_LOCK_USER_13, + HAL_CPU_WAKE_LOCK_USER_14, + HAL_CPU_WAKE_LOCK_USER_15, + HAL_CPU_WAKE_LOCK_USER_16, + HAL_CPU_WAKE_LOCK_USER_17, + HAL_CPU_WAKE_LOCK_USER_18, + HAL_CPU_WAKE_LOCK_USER_19, + HAL_CPU_WAKE_LOCK_USER_20, + HAL_CPU_WAKE_LOCK_USER_21, + HAL_CPU_WAKE_LOCK_USER_22, + HAL_CPU_WAKE_LOCK_USER_23, + HAL_CPU_WAKE_LOCK_USER_24, + HAL_CPU_WAKE_LOCK_USER_25, + HAL_CPU_WAKE_LOCK_USER_26, + HAL_CPU_WAKE_LOCK_USER_27, + HAL_CPU_WAKE_LOCK_USER_28, + HAL_CPU_WAKE_LOCK_USER_29, + HAL_CPU_WAKE_LOCK_USER_30, + HAL_CPU_WAKE_LOCK_USER_31, + + HAL_CPU_WAKE_LOCK_USER_QTY +}; + +enum HAL_SYS_WAKE_LOCK_USER_T { + HAL_SYS_WAKE_LOCK_USER_INTERSYS, + HAL_SYS_WAKE_LOCK_USER_INTERSYS_HCI, + HAL_SYS_WAKE_LOCK_USER_2, + HAL_SYS_WAKE_LOCK_USER_3, + HAL_SYS_WAKE_LOCK_USER_4, + HAL_SYS_WAKE_LOCK_USER_5, + HAL_SYS_WAKE_LOCK_USER_6, + HAL_SYS_WAKE_LOCK_USER_7, + HAL_SYS_WAKE_LOCK_USER_8, + HAL_SYS_WAKE_LOCK_USER_9, + HAL_SYS_WAKE_LOCK_USER_10, + HAL_SYS_WAKE_LOCK_USER_11, + HAL_SYS_WAKE_LOCK_USER_12, + HAL_SYS_WAKE_LOCK_USER_13, + HAL_SYS_WAKE_LOCK_USER_14, + HAL_SYS_WAKE_LOCK_USER_15, + HAL_SYS_WAKE_LOCK_USER_16, + HAL_SYS_WAKE_LOCK_USER_17, + HAL_SYS_WAKE_LOCK_USER_18, + HAL_SYS_WAKE_LOCK_USER_19, + HAL_SYS_WAKE_LOCK_USER_20, + HAL_SYS_WAKE_LOCK_USER_21, + HAL_SYS_WAKE_LOCK_USER_22, + HAL_SYS_WAKE_LOCK_USER_23, + HAL_SYS_WAKE_LOCK_USER_24, + HAL_SYS_WAKE_LOCK_USER_25, + HAL_SYS_WAKE_LOCK_USER_26, + HAL_SYS_WAKE_LOCK_USER_27, + HAL_SYS_WAKE_LOCK_USER_28, + HAL_SYS_WAKE_LOCK_USER_29, + HAL_SYS_WAKE_LOCK_USER_30, + HAL_SYS_WAKE_LOCK_USER_31, + + HAL_SYS_WAKE_LOCK_USER_QTY +}; + +enum HAL_CHIP_WAKE_LOCK_USER_T { + HAL_CHIP_WAKE_LOCK_USER_ANC, + HAL_CHIP_WAKE_LOCK_USER_1, + HAL_CHIP_WAKE_LOCK_USER_2, + HAL_CHIP_WAKE_LOCK_USER_3, + HAL_CHIP_WAKE_LOCK_USER_4, + HAL_CHIP_WAKE_LOCK_USER_5, + HAL_CHIP_WAKE_LOCK_USER_6, + HAL_CHIP_WAKE_LOCK_USER_7, + HAL_CHIP_WAKE_LOCK_USER_8, + HAL_CHIP_WAKE_LOCK_USER_9, + HAL_CHIP_WAKE_LOCK_USER_10, + HAL_CHIP_WAKE_LOCK_USER_11, + HAL_CHIP_WAKE_LOCK_USER_12, + HAL_CHIP_WAKE_LOCK_USER_13, + HAL_CHIP_WAKE_LOCK_USER_14, + HAL_CHIP_WAKE_LOCK_USER_15, + HAL_CHIP_WAKE_LOCK_USER_16, + HAL_CHIP_WAKE_LOCK_USER_17, + HAL_CHIP_WAKE_LOCK_USER_18, + HAL_CHIP_WAKE_LOCK_USER_19, + HAL_CHIP_WAKE_LOCK_USER_20, + HAL_CHIP_WAKE_LOCK_USER_21, + HAL_CHIP_WAKE_LOCK_USER_22, + HAL_CHIP_WAKE_LOCK_USER_23, + HAL_CHIP_WAKE_LOCK_USER_24, + HAL_CHIP_WAKE_LOCK_USER_25, + HAL_CHIP_WAKE_LOCK_USER_26, + HAL_CHIP_WAKE_LOCK_USER_27, + HAL_CHIP_WAKE_LOCK_USER_28, + HAL_CHIP_WAKE_LOCK_USER_29, + HAL_CHIP_WAKE_LOCK_USER_30, + HAL_CHIP_WAKE_LOCK_USER_31, + + HAL_CHIP_WAKE_LOCK_USER_QTY +}; + +enum HAL_SLEEP_HOOK_USER_T { + HAL_SLEEP_HOOK_USER_NVRECORD = 0, + HAL_SLEEP_HOOK_USER_OTA, + HAL_SLEEP_HOOK_NORFLASH_API, + HAL_SLEEP_HOOK_DUMP_LOG, + HAL_SLEEP_HOOK_USER_QTY +}; + +enum HAL_DEEP_SLEEP_HOOK_USER_T { + HAL_DEEP_SLEEP_HOOK_USER_WDT = 0, + HAL_DEEP_SLEEP_HOOK_USER_NVRECORD, + HAL_DEEP_SLEEP_HOOK_USER_OTA, + HAL_DEEP_SLEEP_HOOK_NORFLASH_API, + HAL_DEEP_SLEEP_HOOK_DUMP_LOG, + HAL_DEEP_SLEEP_HOOK_USER_QTY +}; + +enum HAL_SLEEP_STATUS_T { + HAL_SLEEP_STATUS_DEEP, + HAL_SLEEP_STATUS_LIGHT, +}; + +struct CPU_USAGE_T { + uint8_t busy; + uint8_t light_sleep; + uint8_t sys_deep_sleep; + uint8_t chip_deep_sleep; +}; + +typedef int (*HAL_SLEEP_HOOK_HANDLER)(void); +typedef int (*HAL_DEEP_SLEEP_HOOK_HANDLER)(void); + +int hal_sleep_irq_pending(void); + +int hal_sleep_specific_irq_pending(const uint32_t *irq, uint32_t cnt); + +enum HAL_SLEEP_STATUS_T hal_sleep_enter_sleep(void); + +enum HAL_SLEEP_STATUS_T hal_sleep_light_sleep(void); + +int hal_sleep_set_sleep_hook(enum HAL_SLEEP_HOOK_USER_T user, HAL_SLEEP_HOOK_HANDLER handler); + +int hal_sleep_set_deep_sleep_hook(enum HAL_DEEP_SLEEP_HOOK_USER_T user, HAL_DEEP_SLEEP_HOOK_HANDLER handler); + +int hal_cpu_wake_lock(enum HAL_CPU_WAKE_LOCK_USER_T user); + +int hal_cpu_wake_unlock(enum HAL_CPU_WAKE_LOCK_USER_T user); + +int hal_sys_wake_lock(enum HAL_SYS_WAKE_LOCK_USER_T user); + +int hal_sys_wake_unlock(enum HAL_SYS_WAKE_LOCK_USER_T user); + +int hal_chip_wake_lock(enum HAL_CHIP_WAKE_LOCK_USER_T user); + +int hal_chip_wake_unlock(enum HAL_CHIP_WAKE_LOCK_USER_T user); + +void hal_sleep_start_stats(uint32_t stats_interval_ms, uint32_t trace_interval_ms); + +int hal_sleep_get_stats(struct CPU_USAGE_T *usage); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_sleep_core_pd.S b/platform/hal/hal_sleep_core_pd.S new file mode 100644 index 0000000..3afe297 --- /dev/null +++ b/platform/hal/hal_sleep_core_pd.S @@ -0,0 +1,100 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +/* +========================================================================= + Core Sleep Power Down and Wakeup Power Up Helper Functions +========================================================================= +*/ + + #include "cmsis.h" + + .syntax unified + +#ifdef CORE_SLEEP_POWER_DOWN + +#ifdef ROM_BUILD + .section .bss.core_sleep_stack +#else + .section .sram_bss.core_sleep_stack +#endif + .align 2 +core_sleep_stack: + .space 4 + +#ifdef ROM_BUILD + .section .text.hal_sleep_core_power_down, "ax", %progbits +#else + .section .sram_text.hal_sleep_core_power_down, "ax", %progbits +#endif + .thumb + .thumb_func + .align 2 + .globl hal_sleep_core_power_down + .type hal_sleep_core_power_down, %function +hal_sleep_core_power_down: + + ldr r3, =core_sleep_stack + push {r4-r12,lr} +#ifdef __ARM_ARCH_8M_MAIN__ + mrs r0, msplim + push {r0,r1} +#endif +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + ldr r1, =0xE000EF34 + ldr r0, [r1] /* Load FPCCR */ + bic r0, #1 /* Clear LSPACT (Lazy state) */ + str r0, [r1] /* Store FPCCR */ +#endif + /* TODO: Save FPU registers? */ + str sp, [r3] + bl hal_psc_core_auto_power_down +.pd_loop: + b .pd_loop + + .pool + .size hal_sleep_core_power_down, . - hal_sleep_core_power_down + + +#ifdef ROM_BUILD + .section .text.hal_sleep_core_power_up, "ax", %progbits +#else + .section .sram_text.hal_sleep_core_power_up, "ax", %progbits +#endif + .thumb + .thumb_func + .align 2 + .globl hal_sleep_core_power_up + .type hal_sleep_core_power_up, %function +hal_sleep_core_power_up: + + ldr r3, =core_sleep_stack + ldr sp, [r3] + isb + /* TODO: Restore FPU registers? */ +#ifdef __ARM_ARCH_8M_MAIN__ + pop {r0,r1} + msr msplim, r0 +#endif + pop {r4-r12,lr} + bx lr + + .pool + .size hal_sleep_core_power_up, . - hal_sleep_core_power_up + +#endif + + .end diff --git a/platform/hal/hal_sleep_core_pd.h b/platform/hal/hal_sleep_core_pd.h new file mode 100644 index 0000000..c882e58 --- /dev/null +++ b/platform/hal/hal_sleep_core_pd.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_SLEEP_MCU_PD_H__ +#define __HAL_SLEEP_MCU_PD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +void hal_sleep_core_power_down(void); + +void hal_sleep_core_power_up(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_sleep_mcu_pd.S b/platform/hal/hal_sleep_mcu_pd.S new file mode 100644 index 0000000..ec05cb5 --- /dev/null +++ b/platform/hal/hal_sleep_mcu_pd.S @@ -0,0 +1,84 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +/* +========================================================================= + MCU Sleep Power Down and Wakeup Power Up Helper Functions +========================================================================= +*/ + + .syntax unified + +#ifdef MCU_SLEEP_POWER_DOWN + +#ifdef ROM_BUILD + .section .bss.mcu_sleep_stack +#else + .section .sram_bss.mcu_sleep_stack +#endif + .align 2 +mcu_sleep_stack: + .space 4 + +#ifdef ROM_BUILD + .section .text.hal_sleep_mcu_power_down, "ax", %progbits +#else + .section .sram_text.hal_sleep_mcu_power_down, "ax", %progbits +#endif + .thumb + .thumb_func + .align 2 + .globl hal_sleep_mcu_power_down + .type hal_sleep_mcu_power_down, %function +hal_sleep_mcu_power_down: + + ldr r3, =mcu_sleep_stack + push {r4-r12,lr} + /* TODO: Save FPU registers? */ + str sp, [r3] + bl hal_psc_mcu_auto_power_down +.pd_loop: + b .pd_loop + + .pool + .size hal_sleep_mcu_power_down, . - hal_sleep_mcu_power_down + + +#ifdef ROM_BUILD + .section .text.hal_sleep_mcu_power_up, "ax", %progbits +#else + .section .sram_text.hal_sleep_mcu_power_up, "ax", %progbits +#endif + .thumb + .thumb_func + .align 2 + .globl hal_sleep_mcu_power_up + .type hal_sleep_mcu_power_up, %function +hal_sleep_mcu_power_up: + + ldr r3, =mcu_sleep_stack + ldr sp, [r3] + isb + /* TODO: Restore FPU registers? */ + pop {r4-r12,lr} + bx lr + + .pool + .size hal_sleep_mcu_power_up, . - hal_sleep_mcu_power_up + +#endif + + .end diff --git a/platform/hal/hal_sleep_mcu_pd.h b/platform/hal/hal_sleep_mcu_pd.h new file mode 100644 index 0000000..f08ed81 --- /dev/null +++ b/platform/hal/hal_sleep_mcu_pd.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_SLEEP_MCU_PD_H__ +#define __HAL_SLEEP_MCU_PD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +void hal_sleep_mcu_power_down(void); + +void hal_sleep_mcu_power_up(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_spdif.c b/platform/hal/hal_spdif.c new file mode 100644 index 0000000..8f4ea6b --- /dev/null +++ b/platform/hal/hal_spdif.c @@ -0,0 +1,412 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_HAS_SPDIF + +#include "plat_types.h" +#include "plat_addr_map.h" +#include "reg_spdifip.h" +#include "hal_spdifip.h" +#include "hal_spdif.h" +#include "hal_iomux.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "analog.h" +#include "cmsis.h" + +//#define SPDIF_CLOCK_SOURCE 240000000 +//#define SPDIF_CLOCK_SOURCE 22579200 +//#define SPDIF_CLOCK_SOURCE 48000000 +#define SPDIF_CLOCK_SOURCE 3072000 + +//#define SPDIF_CLOCK_SOURCE 76800000 +//#define SPDIF_CLOCK_SOURCE 84672000 + +// Trigger DMA request when TX-FIFO count <= threshold +#define HAL_SPDIF_TX_FIFO_TRIGGER_LEVEL (SPDIFIP_FIFO_DEPTH/2) +// Trigger DMA request when RX-FIFO count >= threshold +#define HAL_SPDIF_RX_FIFO_TRIGGER_LEVEL (SPDIFIP_FIFO_DEPTH/2) + +#define HAL_SPDIF_YES 1 +#define HAL_SPDIF_NO 0 + +#ifdef CHIP_BEST2000 +#define SPDIF_CMU_DIV CODEC_CMU_DIV +#else +#define SPDIF_CMU_DIV CODEC_PLL_DIV +#endif + +enum HAL_SPDIF_STATUS_T { + HAL_SPDIF_STATUS_NULL, + HAL_SPDIF_STATUS_OPENED, + HAL_SPDIF_STATUS_STARTED, +}; + +struct HAL_SPDIF_MOD_NAME_T { + enum HAL_CMU_MOD_ID_T mod; + enum HAL_CMU_MOD_ID_T apb; +}; + +struct HAL_SPDIF_MOD_NAME_T spdif_mod[HAL_SPDIF_ID_QTY] = { + { + .mod = HAL_CMU_MOD_O_SPDIF0, + .apb = HAL_CMU_MOD_P_SPDIF0, + }, +#if (CHIP_HAS_SPDIF > 1) + { + .mod = HAL_CMU_MOD_O_SPDIF1, + .apb = HAL_CMU_MOD_P_SPDIF1, + }, +#endif +}; + +static const char * const invalid_id = "Invalid SPDIF ID: %d\n"; +//static const char * const invalid_ch = "Invalid SPDIF CH: %d\n"; + +struct SPDIF_SAMPLE_RATE_T { + enum AUD_SAMPRATE_T sample_rate; + uint32_t codec_freq; + uint8_t codec_div; + uint8_t pcm_div; + uint8_t tx_ratio; +}; + +// SAMPLE_RATE * 128 = PLL_nominal / PCM_DIV / TX_RATIO +static const struct SPDIF_SAMPLE_RATE_T spdif_sample_rate[]={ +#if defined(CHIP_BEST1000) && defined(AUD_PLL_DOUBLE) + {AUD_SAMPRATE_96000, CODEC_FREQ_48K_SERIES*2, CODEC_PLL_DIV, SPDIF_CMU_DIV, 4}, + {AUD_SAMPRATE_192000, CODEC_FREQ_48K_SERIES*2, CODEC_PLL_DIV, SPDIF_CMU_DIV, 2}, + {AUD_SAMPRATE_384000, CODEC_FREQ_48K_SERIES*2, CODEC_PLL_DIV, SPDIF_CMU_DIV, 1}, +#else + {AUD_SAMPRATE_8000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, SPDIF_CMU_DIV, 24}, + {AUD_SAMPRATE_16000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, SPDIF_CMU_DIV, 12}, + {AUD_SAMPRATE_22050, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, SPDIF_CMU_DIV, 8}, + {AUD_SAMPRATE_24000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, SPDIF_CMU_DIV, 8}, + {AUD_SAMPRATE_44100, CODEC_FREQ_44_1K_SERIES, CODEC_PLL_DIV, SPDIF_CMU_DIV, 4}, + {AUD_SAMPRATE_48000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, SPDIF_CMU_DIV, 4}, + {AUD_SAMPRATE_96000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, SPDIF_CMU_DIV, 2}, + {AUD_SAMPRATE_192000, CODEC_FREQ_48K_SERIES, CODEC_PLL_DIV, SPDIF_CMU_DIV, 1}, +#endif +}; + +#if (CHIP_HAS_SPDIF > 1) +static uint8_t spdif_map; +STATIC_ASSERT(HAL_SPDIF_ID_QTY <= sizeof(spdif_map) * 8, "Too many SPDIF IDs"); +#endif + +static enum HAL_SPDIF_STATUS_T spdif_status[HAL_SPDIF_ID_QTY][AUD_STREAM_NUM]; +static bool spdif_dma[HAL_SPDIF_ID_QTY][AUD_STREAM_NUM]; + +static inline uint32_t _spdif_get_reg_base(enum HAL_SPDIF_ID_T id) +{ + ASSERT(id < HAL_SPDIF_ID_QTY, invalid_id, id); + + switch(id) { + case HAL_SPDIF_ID_0: + default: + return SPDIF0_BASE; + break; +#if (CHIP_HAS_SPDIF > 1) + case HAL_SPDIF_ID_1: + return SPDIF1_BASE; + break; +#endif + } + return 0; +} + +int hal_spdif_open(enum HAL_SPDIF_ID_T id, enum AUD_STREAM_T stream) +{ + uint32_t reg_base; + + reg_base = _spdif_get_reg_base(id); + + if (spdif_status[id][stream] != HAL_SPDIF_STATUS_NULL) { + TRACE(2,"Invalid SPDIF opening status for stream %d: %d", stream, spdif_status[id][stream]); + return 1; + } + + if (spdif_status[id][AUD_STREAM_PLAYBACK] == HAL_SPDIF_STATUS_NULL && + spdif_status[id][AUD_STREAM_CAPTURE] == HAL_SPDIF_STATUS_NULL) { +#ifndef SIMU + bool cfg_pll = true; + int i; + + for (i = HAL_SPDIF_ID_0; i < HAL_SPDIF_ID_QTY; i++) { + if (spdif_status[i][AUD_STREAM_PLAYBACK] != HAL_SPDIF_STATUS_NULL || + spdif_status[i][AUD_STREAM_CAPTURE] != HAL_SPDIF_STATUS_NULL) { + cfg_pll = false; + break; + } + } + if (cfg_pll) { + analog_aud_pll_open(ANA_AUD_PLL_USER_SPDIF); + } +#endif + +#if (CHIP_HAS_SPDIF > 1) + if (id == HAL_SPDIF_ID_1) { + hal_iomux_set_spdif1(); + } else +#endif + { + hal_iomux_set_spdif0(); + } + hal_cmu_spdif_clock_enable(id); + hal_cmu_clock_enable(spdif_mod[id].mod); + hal_cmu_clock_enable(spdif_mod[id].apb); + hal_cmu_reset_clear(spdif_mod[id].mod); + hal_cmu_reset_clear(spdif_mod[id].apb); + + spdifip_w_enable_spdifip(reg_base, HAL_SPDIF_YES); + } + + spdif_dma[id][stream] = false; + spdif_status[id][stream] = HAL_SPDIF_STATUS_OPENED; + + return 0; +} + +int hal_spdif_close(enum HAL_SPDIF_ID_T id, enum AUD_STREAM_T stream) +{ + uint32_t reg_base; + + if (id >= HAL_SPDIF_ID_QTY) { + return 1; + } + + if (spdif_status[id][stream] != HAL_SPDIF_STATUS_OPENED) { + TRACE(2,"Invalid SPDIF closing status for stream %d: %d", stream, spdif_status[id][stream]); + return 1; + } + + spdif_status[id][stream] = HAL_SPDIF_STATUS_NULL; + + if (spdif_status[id][AUD_STREAM_PLAYBACK] == HAL_SPDIF_STATUS_NULL && + spdif_status[id][AUD_STREAM_CAPTURE] == HAL_SPDIF_STATUS_NULL) { + reg_base = _spdif_get_reg_base(id); + + spdifip_w_enable_spdifip(reg_base, HAL_SPDIF_NO); + + hal_cmu_spdif_set_div(id, 0x1FFF + 2); + hal_cmu_reset_set(spdif_mod[id].apb); + hal_cmu_reset_set(spdif_mod[id].mod); + hal_cmu_clock_disable(spdif_mod[id].apb); + hal_cmu_clock_disable(spdif_mod[id].mod); + hal_cmu_spdif_clock_disable(id); + +#ifndef SIMU + bool cfg_pll = true; + int i; + + for (i = HAL_SPDIF_ID_0; i < HAL_SPDIF_ID_QTY; i++) { + if (spdif_status[i][AUD_STREAM_PLAYBACK] != HAL_SPDIF_STATUS_NULL || + spdif_status[i][AUD_STREAM_CAPTURE] != HAL_SPDIF_STATUS_NULL) { + cfg_pll = false; + break; + } + } + if (cfg_pll) { + analog_aud_pll_close(ANA_AUD_PLL_USER_SPDIF); + } +#endif + } + + return 0; +} + +int hal_spdif_start_stream(enum HAL_SPDIF_ID_T id, enum AUD_STREAM_T stream) +{ + uint32_t reg_base; + uint32_t lock; + + reg_base = _spdif_get_reg_base(id); + + if (spdif_status[id][stream] != HAL_SPDIF_STATUS_OPENED) { + TRACE(2,"Invalid SPDIF starting status for stream %d: %d", stream, spdif_status[id][stream]); + return 1; + } + + if (stream == AUD_STREAM_PLAYBACK) { + lock = int_lock(); + spdifip_w_enable_tx_channel0(reg_base, HAL_SPDIF_YES); + spdifip_w_enable_tx(reg_base, HAL_SPDIF_YES); + spdifip_w_tx_valid(reg_base, HAL_SPDIF_YES); + if (spdif_dma[id][stream]) { + spdifip_w_enable_tx_dma(reg_base, HAL_SPDIF_YES); + } + int_unlock(lock); + } else { + if (spdif_dma[id][stream]) { + spdifip_w_enable_rx_dma(reg_base, HAL_SPDIF_YES); + } + spdifip_w_enable_rx_channel0(reg_base, HAL_SPDIF_YES); + spdifip_w_enable_rx(reg_base, HAL_SPDIF_YES); + spdifip_w_sample_en(reg_base, HAL_SPDIF_YES); + } + + spdif_status[id][stream] = HAL_SPDIF_STATUS_STARTED; + + return 0; +} + +int hal_spdif_stop_stream(enum HAL_SPDIF_ID_T id, enum AUD_STREAM_T stream) +{ + uint32_t reg_base; + + reg_base = _spdif_get_reg_base(id); + + if (spdif_status[id][stream] != HAL_SPDIF_STATUS_STARTED) { + TRACE(2,"Invalid SPDIF stopping status for stream %d: %d", stream, spdif_status[id][stream]); + return 1; + } + + spdif_status[id][stream] = HAL_SPDIF_STATUS_OPENED; + + if (stream == AUD_STREAM_PLAYBACK) { + spdifip_w_enable_tx(reg_base, HAL_SPDIF_NO); + spdifip_w_enable_tx_channel0(reg_base, HAL_SPDIF_NO); + spdifip_w_enable_tx_dma(reg_base, HAL_SPDIF_NO); + spdifip_w_tx_fifo_reset(reg_base); + } else { + spdifip_w_enable_rx(reg_base, HAL_SPDIF_NO); + spdifip_w_enable_rx_channel0(reg_base, HAL_SPDIF_NO); + spdifip_w_enable_rx_dma(reg_base, HAL_SPDIF_NO); + spdifip_w_rx_fifo_reset(reg_base); + } + + return 0; +} + +int hal_spdif_setup_stream(enum HAL_SPDIF_ID_T id, enum AUD_STREAM_T stream, struct HAL_SPDIF_CONFIG_T *cfg) +{ + uint8_t i; + uint32_t reg_base; + uint8_t fmt; + + reg_base = _spdif_get_reg_base(id); + + if (spdif_status[id][stream] != HAL_SPDIF_STATUS_OPENED) { + TRACE(2,"Invalid SPDIF setup status for stream %d: %d", stream, spdif_status[id][stream]); + return 1; + } + + for (i = 0; i < ARRAY_SIZE(spdif_sample_rate); i++) + { + if (spdif_sample_rate[i].sample_rate == cfg->sample_rate) + { + break; + } + } + ASSERT(i < ARRAY_SIZE(spdif_sample_rate), "%s: Invalid spdif sample rate: %d", __func__, cfg->sample_rate); + + TRACE(3,"[%s] stream=%d sample_rate=%d", __func__, stream, cfg->sample_rate); + +#ifdef FPGA + hal_cmu_spdif_set_div(id, 2); +#else +#ifndef SIMU + analog_aud_freq_pll_config(spdif_sample_rate[i].codec_freq, spdif_sample_rate[i].codec_div); +#ifdef CHIP_BEST2000 + analog_aud_pll_set_dig_div(spdif_sample_rate[i].codec_div / spdif_sample_rate[i].pcm_div); +#endif +#endif + // SPDIF module is working on 24.576M or 22.5792M + hal_cmu_spdif_set_div(id, spdif_sample_rate[i].pcm_div); +#endif + + if ((stream == AUD_STREAM_PLAYBACK && spdif_status[id][AUD_STREAM_CAPTURE] == HAL_SPDIF_STATUS_NULL) || + (stream == AUD_STREAM_CAPTURE && spdif_status[id][AUD_STREAM_PLAYBACK] == HAL_SPDIF_STATUS_NULL)) { + hal_cmu_reset_pulse(spdif_mod[id].mod); + } + + spdif_dma[id][stream] = cfg->use_dma; + + fmt = 0; + switch (cfg->bits) { + case AUD_BITS_16: + fmt = 0; + break; + // here, 32-bit is treated as 24-bit + case AUD_BITS_32: + case AUD_BITS_24: + fmt = 8; + break; + default: + ASSERT(0, "%s: invalid bits[%d]", __func__, cfg->bits); + } + + if (stream == AUD_STREAM_PLAYBACK) { + spdifip_w_tx_ratio(reg_base, spdif_sample_rate[i].tx_ratio - 1); + spdifip_w_tx_format_cfg_reg(reg_base, fmt); + spdifip_w_tx_fifo_threshold(reg_base, HAL_SPDIF_TX_FIFO_TRIGGER_LEVEL); + } else { + spdifip_w_rx_format_cfg_reg(reg_base, fmt); + spdifip_w_rx_fifo_threshold(reg_base, HAL_SPDIF_RX_FIFO_TRIGGER_LEVEL); + } + + return 0; +} + +int hal_spdif_send(enum HAL_SPDIF_ID_T id, uint8_t *value, uint32_t value_len) +{ + uint32_t i = 0; + uint32_t reg_base; + + reg_base = _spdif_get_reg_base(id); + + for (i = 0; i < value_len; i += 4) { + while (!(spdifip_r_int_status(reg_base) & SPDIFIP_INT_STATUS_TX_FIFO_EMPTY_MASK)); + + spdifip_w_tx_left_fifo(reg_base, value[i+1]<<8 | value[i]); + spdifip_w_tx_right_fifo(reg_base, value[i+3]<<8 | value[i+2]); + } + + return 0; +} + +uint8_t hal_spdif_recv(enum HAL_SPDIF_ID_T id, uint8_t *value, uint32_t value_len) +{ + //uint32_t reg_base; + + //reg_base = _spdif_get_reg_base(id); + return 0; +} + +int hal_spdif_clock_out_enable(enum HAL_SPDIF_ID_T id, uint32_t div) +{ + if (id >= HAL_SPDIF_ID_QTY) { + return 1; + } + + hal_cmu_spdif_clock_enable(id); + hal_cmu_spdif_set_div(id, div); + + return 0; +} + +int hal_spdif_clock_out_disable(enum HAL_SPDIF_ID_T id) +{ + if (id >= HAL_SPDIF_ID_QTY) { + return 1; + } + + hal_cmu_spdif_set_div(id, 0x1FFF + 2); + hal_cmu_spdif_clock_disable(id); + + return 0; +} + +#endif diff --git a/platform/hal/hal_spdif.h b/platform/hal/hal_spdif.h new file mode 100644 index 0000000..92c0389 --- /dev/null +++ b/platform/hal/hal_spdif.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_SPDIF_H__ +#define __HAL_SPDIF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CHIP_HAS_SPDIF + +#include "plat_types.h" +#include "hal_cmu.h" +#include "hal_aud.h" + +struct HAL_SPDIF_CONFIG_T { + uint32_t bits; + uint32_t channel_num; + uint32_t sample_rate; + + uint32_t use_dma; +}; + +int hal_spdif_open(enum HAL_SPDIF_ID_T id, enum AUD_STREAM_T stream); +int hal_spdif_close(enum HAL_SPDIF_ID_T id, enum AUD_STREAM_T stream); +int hal_spdif_start_stream(enum HAL_SPDIF_ID_T id, enum AUD_STREAM_T stream); +int hal_spdif_stop_stream(enum HAL_SPDIF_ID_T id, enum AUD_STREAM_T stream); +int hal_spdif_setup_stream(enum HAL_SPDIF_ID_T id, enum AUD_STREAM_T stream, struct HAL_SPDIF_CONFIG_T *cfg); +int hal_spdif_send(enum HAL_SPDIF_ID_T id, uint8_t *value, uint32_t value_len); +uint8_t hal_spdif_recv(enum HAL_SPDIF_ID_T id, uint8_t *value, uint32_t value_len); + +int hal_spdif_clock_out_enable(enum HAL_SPDIF_ID_T id, uint32_t div); +int hal_spdif_clock_out_disable(enum HAL_SPDIF_ID_T id); + +#endif // CHIP_HAS_SPDIF + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_spdifip.h b/platform/hal/hal_spdifip.h new file mode 100644 index 0000000..ae185e9 --- /dev/null +++ b/platform/hal/hal_spdifip.h @@ -0,0 +1,261 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_SPDIFIP_H__ +#define __HAL_SPDIFIP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "reg_spdifip.h" + +#define spdifip_read32(b,a) \ + (*(volatile uint32_t *)(b+a)) + +#define spdifip_write32(v,b,a) \ + ((*(volatile uint32_t *)(b+a)) = v) + +static inline void spdifip_w_enable_spdifip(uint32_t reg_base, uint32_t v) +{ + uint32_t val = 0; + + val = spdifip_read32(reg_base, SPDIFIP_ENABLE_REG_REG_OFFSET); + if (v) + val |= SPDIFIP_ENABLE_REG_SPDIF_ENABLE_MASK; + else + val &= ~SPDIFIP_ENABLE_REG_SPDIF_ENABLE_MASK; + + spdifip_write32(val, reg_base, SPDIFIP_ENABLE_REG_REG_OFFSET); +} +#if 0 +static inline void spdifip_w_enable_clk_gen(uint32_t reg_base, uint32_t v) +{ + if (v) + spdifip_write32(1, reg_base, SPDIFIP_CLK_GEN_ENABLE_REG_REG_OFFSET); + else + spdifip_write32(0, reg_base, SPDIFIP_CLK_GEN_ENABLE_REG_REG_OFFSET); +} +#endif +#if 0 +static inline void spdifip_w_enable_rx_block(uint32_t reg_base, uint32_t v) +{ + if (v) + spdifip_write32(1, reg_base, SPDIFIP_RX_BLOCK_ENABLE_REG_REG_OFFSET); + else + spdifip_write32(0, reg_base, SPDIFIP_RX_BLOCK_ENABLE_REG_REG_OFFSET); +} +#endif +static inline void spdifip_w_sample_en(uint32_t reg_base, uint32_t v) +{ + uint32_t val = 0; + val = spdifip_read32(reg_base, SPDIFIP_RX_CFG_REG_OFFSET); + + if (v) + val |= SPDIFIP_RX_CFG_SAMPLEEN_MASK; + else + val &= ~SPDIFIP_RX_CFG_SAMPLEEN_MASK; + + spdifip_write32(val, reg_base, SPDIFIP_RX_CFG_REG_OFFSET); +} +static inline void spdifip_w_enable_rx(uint32_t reg_base, uint32_t v) +{ + uint32_t val = 0; + val = spdifip_read32(reg_base, SPDIFIP_RX_CFG_REG_OFFSET); + + if (v) + val |= SPDIFIP_RX_CFG_RXEN_MASK; + else + val &= ~SPDIFIP_RX_CFG_RXEN_MASK; + + spdifip_write32(val, reg_base, SPDIFIP_RX_CFG_REG_OFFSET); +} +static inline void spdifip_w_rx_format_cfg_reg(uint32_t reg_base, uint32_t v) +{ + uint32_t val = 0; + + val = spdifip_read32(reg_base, SPDIFIP_RX_CFG_REG_OFFSET); + val &= ~SPDIFIP_RX_CFG_FORMAT_MASK; + val |= v<= 2) + HAL_SPI_CS_1, + HAL_SPI_CS_2, +#if (CHIP_SPI_VER >= 3) + HAL_SPI_CS_3, +#if (CHIP_SPI_VER >= 4) + //HAL_SPI_CS_4, +#endif +#endif +#endif + + HAL_SPI_CS_QTY +}; + +enum HAL_SPI_XFER_TYPE_T { + HAL_SPI_XFER_TYPE_SEND, + HAL_SPI_XFER_TYPE_RECV, + + HAL_SPI_XFER_TYPE_QTY +}; + +struct HAL_SPI_MOD_NAME_T { + enum HAL_CMU_MOD_ID_T mod; + enum HAL_CMU_MOD_ID_T apb; +}; + +static struct SPI_T * const spi[HAL_SPI_ID_QTY] = { + (struct SPI_T *)ISPI_BASE, +#ifdef CHIP_HAS_SPI + (struct SPI_T *)SPI_BASE, +#endif +#ifdef CHIP_HAS_SPILCD + (struct SPI_T *)SPILCD_BASE, +#endif +#ifdef CHIP_HAS_SPIPHY + (struct SPI_T *)SPIPHY_BASE, +#endif +#ifdef CHIP_HAS_SPIDPD + (struct SPI_T *)SPIDPD_BASE, +#endif +}; + +static const struct HAL_SPI_MOD_NAME_T spi_mod[HAL_SPI_ID_QTY] = { + { + .mod = HAL_CMU_MOD_O_SPI_ITN, + .apb = HAL_CMU_MOD_P_SPI_ITN, + }, +#ifdef CHIP_HAS_SPI + { + .mod = HAL_CMU_MOD_O_SPI, + .apb = HAL_CMU_MOD_P_SPI, + }, +#endif +#ifdef CHIP_HAS_SPILCD + { + .mod = HAL_CMU_MOD_O_SLCD, + .apb = HAL_CMU_MOD_P_SLCD, + }, +#endif +#ifdef CHIP_HAS_SPIPHY + { + .mod = HAL_CMU_MOD_O_SPI_PHY, + .apb = HAL_CMU_MOD_P_SPI_PHY, + }, +#endif +#ifdef CHIP_HAS_SPIDPD + { + .mod = HAL_CMU_MOD_O_SPI_DPD, + .apb = HAL_CMU_MOD_P_SPI_DPD, + }, +#endif +}; + +#ifndef SPI_ROM_ONLY +#ifdef CHIP_HAS_SPI +static struct HAL_SPI_CTRL_T spi0_ctrl[HAL_SPI_CS_QTY]; +#if (CHIP_SPI_VER >= 2) +static enum HAL_SPI_CS_T spi0_cs = HAL_SPI_CS_0; +#else +static const enum HAL_SPI_CS_T spi0_cs = HAL_SPI_CS_0; +#endif +#endif +#ifdef CHIP_HAS_SPILCD +static struct HAL_SPI_CTRL_T spilcd_ctrl[HAL_SPI_CS_QTY]; +#if (CHIP_SPI_VER >= 2) +static enum HAL_SPI_CS_T spilcd_cs = HAL_SPI_CS_0; +#else +static const enum HAL_SPI_CS_T spilcd_cs = HAL_SPI_CS_0; +#endif +#endif +#ifdef CHIP_HAS_SPIDPD +static struct HAL_SPI_CTRL_T spidpd_ctrl; +#endif + +static uint8_t BOOT_BSS_LOC spi_cs_map[HAL_SPI_ID_QTY]; +STATIC_ASSERT(sizeof(spi_cs_map[0]) * 8 >= HAL_SPI_CS_QTY, "spi_cs_map size too small"); + +static bool BOOT_BSS_LOC in_use[HAL_SPI_ID_QTY] = { false, }; + +static HAL_SPI_DMA_HANDLER_T BOOT_BSS_LOC spi_txdma_handler[HAL_SPI_ID_QTY]; +static HAL_SPI_DMA_HANDLER_T BOOT_BSS_LOC spi_rxdma_handler[HAL_SPI_ID_QTY]; +static uint8_t BOOT_BSS_LOC spi_txdma_chan[HAL_SPI_ID_QTY]; +static uint8_t BOOT_BSS_LOC spi_rxdma_chan[HAL_SPI_ID_QTY]; + +static enum HAL_SPI_MOD_CLK_SEL_T clk_sel[HAL_SPI_ID_QTY]; + +static bool BOOT_BSS_LOC spi_init_done = false; + +static int hal_spi_activate_cs_id(enum HAL_SPI_ID_T id, uint32_t cs); +#endif + +//static const char *invalid_id = "Invalid SPI ID: %d"; + +static inline uint8_t get_frame_bytes(enum HAL_SPI_ID_T id) +{ + uint8_t bits, cnt; + + bits = GET_BITFIELD(spi[id]->SSPCR0, SPI_SSPCR0_DSS) + 1; + if (bits <= 8) { + cnt = 1; + } else if (bits <= 16) { + cnt = 2; + } else { + cnt = 4; + } + + return cnt; +} + +static inline void copy_frame_from_bytes(uint32_t *val, const uint8_t *data, uint8_t cnt) +{ +#ifdef UNALIGNED_ACCESS + if (cnt == 1) { + *val = *(const uint8_t *)data; + } else if (cnt == 2) { + *val = *(const uint16_t *)data; + } else { + *val = *(const uint32_t *)data; + } +#else + if (cnt == 1) { + *val = data[0]; + } else if (cnt == 2) { + *val = data[0] | (data[1] << 8); + } else { + *val = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + } +#endif +} + +static inline void copy_bytes_from_frame(uint8_t *data, uint32_t val, uint8_t cnt) +{ +#ifdef UNALIGNED_ACCESS + if (cnt == 1) { + *(uint8_t *)data = (uint8_t)val; + } else if (cnt == 2) { + *(uint16_t *)data = (uint16_t)val; + } else { + *(uint32_t *)data = (uint32_t)val; + } +#else + data[0] = (uint8_t)val; + if (cnt == 1) { + return; + } else if (cnt == 2) { + data[1] = (uint8_t)(val >> 8); + } else { + data[1] = (uint8_t)(val >> 8); + data[2] = (uint8_t)(val >> 16); + data[3] = (uint8_t)(val >> 24); + } +#endif +} + +int hal_spi_init_ctrl(const struct HAL_SPI_CFG_T *cfg, struct HAL_SPI_CTRL_T *ctrl) +{ + uint32_t div; + uint16_t cpsdvsr, scr; + uint32_t mod_clk; + +#ifdef SPI_ROM_ONLY + // Assume default crystal -- Never access global versatile data to ensure reentrance + mod_clk = HAL_CMU_DEFAULT_CRYSTAL_FREQ; +#else // !SPI_ROM_ONLY + mod_clk = 0; +#ifdef PERIPH_PLL_FREQ + if (PERIPH_PLL_FREQ / 2 > 2 * hal_cmu_get_crystal_freq()) { + // Init to OSC_X2 + mod_clk = 2 * hal_cmu_get_crystal_freq(); + if (cfg->rate * 2 > mod_clk) { + mod_clk = PERIPH_PLL_FREQ / 2; + ctrl->clk_sel = HAL_SPI_MOD_CLK_SEL_PLL; + } else { + mod_clk = 0; + } + } +#endif + if (mod_clk == 0) { + // Init to OSC + mod_clk = hal_cmu_get_crystal_freq(); + if (cfg->rate * 2 > mod_clk) { + mod_clk *= 2; + ctrl->clk_sel = HAL_SPI_MOD_CLK_SEL_OSC_X2; + } else { + ctrl->clk_sel = HAL_SPI_MOD_CLK_SEL_OSC; + } + } +#endif // !SPI_ROM_ONLY + + SPI_ASSERT(cfg->rate <= mod_clk / (MIN_CPSDVSR * (1 + MIN_SCR)), "SPI rate too large: %u", cfg->rate); + SPI_ASSERT(cfg->rate >= mod_clk / (MAX_CPSDVSR * (1 + MAX_SCR)), "SPI rate too small: %u", cfg->rate); + SPI_ASSERT(cfg->tx_bits <= MAX_DATA_BITS && cfg->tx_bits >= MIN_DATA_BITS, "Invalid SPI TX bits: %d", cfg->tx_bits); + SPI_ASSERT(cfg->rx_bits <= MAX_DATA_BITS && cfg->rx_bits >= MIN_DATA_BITS, "Invalid SPI RX bits: %d", cfg->rx_bits); + SPI_ASSERT(cfg->rx_frame_bits <= MAX_DATA_BITS && (cfg->rx_frame_bits == 0 || cfg->rx_frame_bits > cfg->rx_bits), + "Invalid SPI RX FRAME bits: %d", cfg->rx_frame_bits); + SPI_ASSERT(cfg->cs < HAL_SPI_CS_QTY, "SPI cs bad: %d", cfg->cs); + + div = (mod_clk + cfg->rate - 1) / cfg->rate; + cpsdvsr = (div + MAX_SCR) / (MAX_SCR + 1); + if (cpsdvsr < 2) { + cpsdvsr = 2; + } else { + if (cpsdvsr & 0x1) { + cpsdvsr += 1; + } + if (cpsdvsr > MAX_CPSDVSR) { + cpsdvsr = MAX_CPSDVSR; + } + } + scr = (div + cpsdvsr - 1) / cpsdvsr; + if (scr > 0) { + scr -= 1; + } + if (scr > MAX_SCR) { + scr = MAX_SCR; + } + + ctrl->sspcr0_tx = SPI_SSPCR0_SCR(scr) | + (cfg->clk_delay_half ? SPI_SSPCR0_SPH : 0) | + (cfg->clk_polarity ? SPI_SSPCR0_SPO : 0) | + SPI_SSPCR0_FRF(0) | // Only support Motorola SPI frame format + SPI_SSPCR0_DSS(cfg->tx_bits - 1); + ctrl->sspcr1 = (cfg->rx_sep_line ? SPI_RX_SEL_EN : 0) | + SPI_SLAVE_ID(cfg->cs) | + SPI_SSPCR1_SOD | + (cfg->slave ? SPI_SSPCR1_MS : 0) | + SPI_SSPCR1_SSE; + ctrl->sspcpsr = SPI_SSPCPSR_CPSDVSR(cpsdvsr); + ctrl->sspdmacr = (cfg->dma_tx ? SPI_SSPDMACR_TXDMAE : 0) | + (cfg->dma_rx ? SPI_SSPDMACR_RXDMAE : 0); + ctrl->ssprxcr_tx = 0; + if (cfg->rx_frame_bits > 0) { + ctrl->sspcr0_rx = SET_BITFIELD(ctrl->sspcr0_tx, SPI_SSPCR0_DSS, cfg->rx_frame_bits - 1); + ctrl->ssprxcr_rx = SPI_SSPRXCR_EN | SPI_SSPRXCR_OEN_POLARITY | SPI_SSPRXCR_RXBITS(cfg->rx_bits - 1); + } else { + ctrl->sspcr0_rx = SET_BITFIELD(ctrl->sspcr0_tx, SPI_SSPCR0_DSS, cfg->rx_bits - 1); + ctrl->ssprxcr_rx = 0; + } + + return 0; +} + +static void NOINLINE POSSIBLY_UNUSED hal_spi_set_xfer_type_id(enum HAL_SPI_ID_T id, const struct HAL_SPI_CTRL_T *ctrl, enum HAL_SPI_XFER_TYPE_T type) +{ + uint32_t sspcr0; + uint32_t ssprxcr; + + if (type == HAL_SPI_XFER_TYPE_SEND) { + sspcr0 = ctrl->sspcr0_tx; + ssprxcr = ctrl->ssprxcr_tx; + } else { + sspcr0 = ctrl->sspcr0_rx; + ssprxcr = ctrl->ssprxcr_rx; + } + + spi[id]->SSPCR0 = sspcr0; + spi[id]->SSPRXCR = ssprxcr; +} + +static void NOINLINE hal_spi_enable_id(enum HAL_SPI_ID_T id, const struct HAL_SPI_CTRL_T *ctrl, enum HAL_SPI_XFER_TYPE_T type) +{ + hal_spi_set_xfer_type_id(id, ctrl, type); + + spi[id]->SSPCR1 = ctrl->sspcr1; + spi[id]->SSPCPSR = ctrl->sspcpsr; + spi[id]->SSPDMACR = ctrl->sspdmacr; + +#ifdef SPI_ROM_ONLY + if (id == HAL_SPI_ID_INTERNAL) { + hal_cmu_ispi_set_freq(HAL_CMU_PERIPH_FREQ_26M); +#ifdef CHIP_HAS_SPI + } else if (id == HAL_SPI_ID_0) { + hal_cmu_spi_set_freq(HAL_CMU_PERIPH_FREQ_26M); +#endif +#ifdef CHIP_HAS_SPILCD + } else if (id == HAL_SPI_ID_SLCD) { + hal_cmu_slcd_set_freq(HAL_CMU_PERIPH_FREQ_26M); +#endif + } +#else // !SPI_ROM_ONLY + if (clk_sel[id] != ctrl->clk_sel) { + clk_sel[id] = ctrl->clk_sel; + if (ctrl->clk_sel == HAL_SPI_MOD_CLK_SEL_PLL) { +#ifdef PERIPH_PLL_FREQ + if (0) { +#ifdef CHIP_HAS_SPI + } else if (id == HAL_SPI_ID_0) { + hal_cmu_spi_set_div(2); +#endif +#ifdef CHIP_HAS_SPILCD + } else if (id == HAL_SPI_ID_SLCD) { + hal_cmu_slcd_set_div(2); +#endif + } + // ISPI cannot use PLL clock +#endif + } else { + enum HAL_CMU_PERIPH_FREQ_T periph_freq; + + if (ctrl->clk_sel == HAL_SPI_MOD_CLK_SEL_OSC_X2) { + periph_freq = HAL_CMU_PERIPH_FREQ_52M; + } else { + periph_freq = HAL_CMU_PERIPH_FREQ_26M; + } + + if (id == HAL_SPI_ID_INTERNAL) { + hal_cmu_ispi_set_freq(periph_freq); +#ifdef CHIP_HAS_SPI + } else if (id == HAL_SPI_ID_0) { + hal_cmu_spi_set_freq(periph_freq); +#endif +#ifdef CHIP_HAS_SPILCD + } else if (id == HAL_SPI_ID_SLCD) { + hal_cmu_slcd_set_freq(periph_freq); +#endif + } + } + } +#endif // !SPI_ROM_ONLY +} + +static void hal_spi_disable_id(enum HAL_SPI_ID_T id) +{ + spi[id]->SSPCR1 &= ~SPI_SSPCR1_SSE; +} + +static void POSSIBLY_UNUSED hal_spi_get_ctrl_id(enum HAL_SPI_ID_T id, struct HAL_SPI_CTRL_T *ctrl) +{ + ctrl->sspcr0_tx = spi[id]->SSPCR0; + ctrl->sspcr1 = spi[id]->SSPCR1; + ctrl->sspcpsr = spi[id]->SSPCPSR; + ctrl->sspdmacr = spi[id]->SSPDMACR; + ctrl->ssprxcr_tx = spi[id]->SSPRXCR; +} + +static int NOINLINE hal_spi_open_id(enum HAL_SPI_ID_T id, const struct HAL_SPI_CFG_T *cfg, struct HAL_SPI_CTRL_T *ctrl) +{ + int ret; + struct HAL_SPI_CTRL_T ctrl_regs; + bool cfg_clk = true; + + //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id); + + if (ctrl == NULL) { + ctrl = &ctrl_regs; + } + + ret = hal_spi_init_ctrl(cfg, ctrl); + if (ret) { + return ret; + } + +#ifndef SPI_ROM_ONLY + if (!spi_init_done) { + spi_init_done = true; + for (int i = HAL_SPI_ID_INTERNAL; i < HAL_SPI_ID_QTY; i++) { + spi_txdma_chan[i] = HAL_DMA_CHAN_NONE; + spi_rxdma_chan[i] = HAL_DMA_CHAN_NONE; + } + } + + if (spi_cs_map[id]) { + cfg_clk = false; + } + spi_cs_map[id] |= (1 << cfg->cs); +#endif + + if (cfg_clk) { + hal_cmu_clock_enable(spi_mod[id].mod); + hal_cmu_clock_enable(spi_mod[id].apb); + hal_cmu_reset_clear(spi_mod[id].mod); + hal_cmu_reset_clear(spi_mod[id].apb); + } + + hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND); + + return 0; +} + +static int POSSIBLY_UNUSED hal_spi_close_id(enum HAL_SPI_ID_T id, uint32_t cs) +{ + int ret = 0; + bool cfg_clk = true; + +#ifndef SPI_ROM_ONLY + if (spi_cs_map[id] & (1 << cs)) { + spi_cs_map[id] &= ~(1 << cs); +#if (CHIP_SPI_VER >= 2) + if (spi_cs_map[id]) { + cfg_clk = false; + } +#endif + } else { + ret = 1; + cfg_clk = false; + } +#endif + + if (cfg_clk) { + hal_spi_disable_id(id); + + hal_cmu_reset_set(spi_mod[id].apb); + hal_cmu_reset_set(spi_mod[id].mod); + hal_cmu_clock_disable(spi_mod[id].apb); + hal_cmu_clock_disable(spi_mod[id].mod); + } + + return ret; +} + +static void POSSIBLY_UNUSED hal_spi_set_cs_id(enum HAL_SPI_ID_T id, uint32_t cs) +{ + spi[id]->SSPCR1 = SET_BITFIELD(spi[id]->SSPCR1, SPI_SLAVE_ID, cs); +} + +static bool hal_spi_busy_id(enum HAL_SPI_ID_T id) +{ + return ((spi[id]->SSPCR1 & SPI_SSPCR1_SSE) && (spi[id]->SSPSR & SPI_SSPSR_BSY)); +} + +static void hal_spi_enable_slave_output_id(enum HAL_SPI_ID_T id) +{ + if (spi[id]->SSPCR1 & SPI_SSPCR1_MS) { + spi[id]->SSPCR1 &= ~SPI_SSPCR1_SOD; + } +} + +static void hal_spi_disable_slave_output_id(enum HAL_SPI_ID_T id) +{ + if (spi[id]->SSPCR1 & SPI_SSPCR1_MS) { + spi[id]->SSPCR1 |= SPI_SSPCR1_SOD; + } +} + +static int hal_spi_send_id(enum HAL_SPI_ID_T id, const void *data, uint32_t len) +{ + uint8_t cnt; + uint32_t sent, value; + int ret; + + //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id); + SPI_ASSERT((spi[id]->SSPDMACR & SPI_SSPDMACR_TXDMAE) == 0, "TX-DMA configured on SPI %d", id); + + cnt = get_frame_bytes(id); + + if (len == 0 || (len & (cnt - 1)) != 0) { + return -1; + } + + sent = 0; + + hal_spi_enable_slave_output_id(id); + + while (sent < len) { + if ((spi[id]->SSPCR1 & SPI_SSPCR1_SSE) == 0) { + break; + } + if (spi[id]->SSPSR & SPI_SSPSR_TNF) { + value = 0; + copy_frame_from_bytes(&value, (uint8_t *)data + sent, cnt); + spi[id]->SSPDR = value; + sent += cnt; + } + } + + if (sent >= len) { + ret = 0; + } else { + ret = 1; + } + + while (hal_spi_busy_id(id)); + hal_spi_disable_slave_output_id(id); + + return ret; +} + +static int hal_spi_recv_id(enum HAL_SPI_ID_T id, const void *cmd, void *data, uint32_t len) +{ + uint8_t cnt; + uint32_t sent, recv, value; + int ret; + + //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id); + SPI_ASSERT((spi[id]->SSPDMACR & (SPI_SSPDMACR_TXDMAE | SPI_SSPDMACR_RXDMAE)) == 0, "RX/TX-DMA configured on SPI %d", id); + + cnt = get_frame_bytes(id); + + if (len == 0 || (len & (cnt - 1)) != 0) { + return -1; + } + + // Rx transaction should start from idle state + if (spi[id]->SSPSR & SPI_SSPSR_BSY) { + return -11; + } + + sent = 0; + recv = 0; + + // Flush the RX FIFO by reset or CPU read + while (spi[id]->SSPSR & SPI_SSPSR_RNE) { + spi[id]->SSPDR; + } + spi[id]->SSPICR = ~0UL; + + hal_spi_enable_slave_output_id(id); + + while (recv < len || sent < len) { + if ((spi[id]->SSPCR1 & SPI_SSPCR1_SSE) == 0) { + break; + } + if (sent < len && (spi[id]->SSPSR & SPI_SSPSR_TNF)) { + value = 0; + copy_frame_from_bytes(&value, (uint8_t *)cmd + sent, cnt); + spi[id]->SSPDR = value; + sent += cnt; + } + if (recv < len && (spi[id]->SSPSR & SPI_SSPSR_RNE)) { + value = spi[id]->SSPDR; + copy_bytes_from_frame((uint8_t *)data + recv, value, cnt); + recv += cnt; + } + } + + if (recv >= len && sent >= len) { + ret = 0; + } else { + ret = 1; + } + + while (hal_spi_busy_id(id)); + hal_spi_disable_slave_output_id(id); + + return ret; +} + +#ifdef SPI_ROM_ONLY + +//------------------------------------------------------------ +// ISPI ROM functions +//------------------------------------------------------------ + +int hal_ispi_rom_open(const struct HAL_SPI_CFG_T *cfg) +{ + SPI_ASSERT(cfg->tx_bits == cfg->rx_bits && cfg->rx_frame_bits == 0, "ISPI_ROM: Bad bits cfg"); + + return hal_spi_open_id(HAL_SPI_ID_INTERNAL, cfg, NULL); +} + +void hal_ispi_rom_activate_cs(uint32_t cs) +{ + SPI_ASSERT(cs < HAL_SPI_CS_QTY, "ISPI_ROM: SPI cs bad: %d", cs); + + hal_spi_set_cs_id(HAL_SPI_ID_INTERNAL, cs); +} + +int hal_ispi_rom_busy(void) +{ + return hal_spi_busy_id(HAL_SPI_ID_INTERNAL); +} + +int hal_ispi_rom_send(const void *data, uint32_t len) +{ + int ret; + + ret = hal_spi_send_id(HAL_SPI_ID_INTERNAL, data, len); + + return ret; +} + +int hal_ispi_rom_recv(const void *cmd, void *data, uint32_t len) +{ + int ret; + + ret = hal_spi_recv_id(HAL_SPI_ID_INTERNAL, cmd, data, len); + + return ret; +} + +#ifdef CHIP_HAS_SPIPHY +//------------------------------------------------------------ +// SPI PHY ROM functions +//------------------------------------------------------------ + +int hal_spiphy_rom_open(const struct HAL_SPI_CFG_T *cfg) +{ + SPI_ASSERT(cfg->tx_bits == cfg->rx_bits && cfg->rx_frame_bits == 0, "SPIPHY_ROM: Bad bits cfg"); + + return hal_spi_open_id(HAL_SPI_ID_PHY, cfg, NULL); +} + +int hal_spiphy_rom_busy(void) +{ + return hal_spi_busy_id(HAL_SPI_ID_PHY); +} + +int hal_spiphy_rom_send(const void *data, uint32_t len) +{ + int ret; + + ret = hal_spi_send_id(HAL_SPI_ID_PHY, data, len); + + return ret; +} + +int hal_spiphy_rom_recv(const void *cmd, void *data, uint32_t len) +{ + int ret; + + ret = hal_spi_recv_id(HAL_SPI_ID_PHY, cmd, data, len); + + return ret; +} +#endif + +#else // !SPI_ROM_ONLY + +static int hal_spi_activate_cs_id(enum HAL_SPI_ID_T id, uint32_t cs) +{ + struct HAL_SPI_CTRL_T *ctrl = NULL; + + SPI_ASSERT(cs < HAL_SPI_CS_QTY, "SPI cs bad: %d", cs); + SPI_ASSERT(spi_cs_map[id] & (1 << cs), "SPI cs not opened: %d", cs); + +#if (CHIP_SPI_VER >= 2) + if (0) { +#ifdef CHIP_HAS_SPI + } else if (id == HAL_SPI_ID_0) { + spi0_cs = cs; +#endif +#ifdef CHIP_HAS_SPILCD + } else if (id == HAL_SPI_ID_SLCD) { + spilcd_cs = cs; +#endif + } +#endif + + if (0) { +#ifdef CHIP_HAS_SPI + } else if (id == HAL_SPI_ID_0) { + ctrl = &spi0_ctrl[spi0_cs]; +#endif +#ifdef CHIP_HAS_SPILCD + } else if (id == HAL_SPI_ID_SLCD) { + ctrl = &spilcd_ctrl[spilcd_cs]; +#endif + } + if (ctrl) { + hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND); + } + + return 0; +} + +static int POSSIBLY_UNUSED hal_spi_enable_and_send_id(enum HAL_SPI_ID_T id, const struct HAL_SPI_CTRL_T *ctrl, const void *data, uint32_t len) +{ + int ret; + struct HAL_SPI_CTRL_T saved; + + //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id); + + if (set_bool_flag(&in_use[id])) { + return -31; + } + + hal_spi_get_ctrl_id(id, &saved); + hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND); + ret = hal_spi_send_id(id, data, len); + hal_spi_enable_id(id, &saved, HAL_SPI_XFER_TYPE_SEND); + + clear_bool_flag(&in_use[id]); + + return ret; +} + +static int POSSIBLY_UNUSED hal_spi_enable_and_recv_id(enum HAL_SPI_ID_T id, const struct HAL_SPI_CTRL_T *ctrl, const void *cmd, void *data, uint32_t len) +{ + int ret; + struct HAL_SPI_CTRL_T saved; + + if (set_bool_flag(&in_use[id])) { + return -31; + } + + hal_spi_get_ctrl_id(id, &saved); + hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_RECV); + ret = hal_spi_recv_id(id, cmd, data, len); + hal_spi_enable_id(id, &saved, HAL_SPI_XFER_TYPE_SEND); + + clear_bool_flag(&in_use[id]); + + return ret; +} + +static void hal_spi_txdma_handler(uint8_t chan, uint32_t remains, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + enum HAL_SPI_ID_T id; + uint32_t lock; + + lock = int_lock(); + for (id = HAL_SPI_ID_INTERNAL; id < HAL_SPI_ID_QTY; id++) { + if (spi_txdma_chan[id] == chan) { + spi_txdma_chan[id] = HAL_DMA_CHAN_NONE; + break; + } + } + int_unlock(lock); + + if (id >= HAL_SPI_ID_QTY) { + return; + } + + hal_gpdma_free_chan(chan); + + clear_bool_flag(&in_use[id]); + + if (spi_txdma_handler[id]) { + spi_txdma_handler[id](error); + } +} + +static int hal_spi_dma_send_id(enum HAL_SPI_ID_T id, const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler) +{ + uint8_t cnt; + enum HAL_DMA_RET_T ret; + struct HAL_DMA_CH_CFG_T dma_cfg; + enum HAL_DMA_WDITH_T dma_width; + uint32_t lock; + enum HAL_DMA_PERIPH_T dst_periph; + + //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id); + SPI_ASSERT((spi[id]->SSPDMACR & SPI_SSPDMACR_TXDMAE), "TX-DMA not configured on SPI %d", id); + + spi_txdma_handler[id] = handler; + + cnt = get_frame_bytes(id); + + if ((len & (cnt - 1)) != 0) { + return -1; + } + if (((uint32_t)data & (cnt - 1)) != 0) { + return -2; + } + + // Tx transaction should start from idle state for SPI mode 1 and 3 (SPH=1) + if ((spi[id]->SSPCR0 & SPI_SSPCR0_SPH) && (spi[id]->SSPSR & SPI_SSPSR_BSY)) { + return -11; + } + + if (id == HAL_SPI_ID_INTERNAL) { + dst_periph = HAL_GPDMA_ISPI_TX; +#ifdef CHIP_HAS_SPI + } else if (id == HAL_SPI_ID_0) { + dst_periph = HAL_GPDMA_SPI_TX; +#endif +#ifdef CHIP_HAS_SPILCD + } else if (id == HAL_SPI_ID_SLCD) { + dst_periph = HAL_GPDMA_SPILCD_TX; +#endif + } else { + return -12; + } + + lock = int_lock(); + if (spi_txdma_chan[id] != HAL_DMA_CHAN_NONE) { + int_unlock(lock); + return -3; + } + spi_txdma_chan[id] = hal_gpdma_get_chan(dst_periph, HAL_DMA_HIGH_PRIO); + if (spi_txdma_chan[id] == HAL_DMA_CHAN_NONE) { + int_unlock(lock); + return -4; + } + int_unlock(lock); + + if (cnt == 1) { + dma_width = HAL_DMA_WIDTH_BYTE; + } else if (cnt == 2) { + dma_width = HAL_DMA_WIDTH_HALFWORD; + } else { + dma_width = HAL_DMA_WIDTH_WORD; + } + + memset(&dma_cfg, 0, sizeof(dma_cfg)); + dma_cfg.ch = spi_txdma_chan[id]; + dma_cfg.dst = 0; // useless + dma_cfg.dst_bsize = HAL_DMA_BSIZE_4; + dma_cfg.dst_periph = dst_periph; + dma_cfg.dst_width = dma_width; + dma_cfg.handler = handler ? hal_spi_txdma_handler : NULL; + dma_cfg.src = (uint32_t)data; + dma_cfg.src_bsize = HAL_DMA_BSIZE_16; + //dma_cfg.src_periph = HAL_GPDMA_PERIPH_QTY; // useless + dma_cfg.src_tsize = len / cnt; + dma_cfg.src_width = dma_width; + dma_cfg.try_burst = 0; + dma_cfg.type = HAL_DMA_FLOW_M2P_DMA; + + hal_spi_enable_slave_output_id(id); + + ret = hal_gpdma_start(&dma_cfg); + if (ret != HAL_DMA_OK) { + hal_spi_disable_slave_output_id(id); + return -5; + } + + if (handler == NULL) { + while ((spi[id]->SSPCR1 & SPI_SSPCR1_SSE) && hal_gpdma_chan_busy(spi_txdma_chan[id])); + hal_gpdma_free_chan(spi_txdma_chan[id]); + spi_txdma_chan[id] = HAL_DMA_CHAN_NONE; + while (hal_spi_busy_id(id)); + hal_spi_disable_slave_output_id(id); + } + + return 0; +} + +void hal_spi_stop_dma_send_id(enum HAL_SPI_ID_T id) +{ + uint32_t lock; + uint8_t tx_chan; + + lock = int_lock(); + tx_chan = spi_txdma_chan[id]; + spi_txdma_chan[id] = HAL_DMA_CHAN_NONE; + int_unlock(lock); + + if (tx_chan != HAL_DMA_CHAN_NONE) { + hal_gpdma_cancel(tx_chan); + hal_gpdma_free_chan(tx_chan); + } + + clear_bool_flag(&in_use[id]); +} + +static void hal_spi_rxdma_handler(uint8_t chan, uint32_t remains, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + enum HAL_SPI_ID_T id; + uint32_t lock; + uint8_t tx_chan = HAL_DMA_CHAN_NONE; + struct HAL_SPI_CTRL_T *ctrl = NULL; + + lock = int_lock(); + for (id = HAL_SPI_ID_INTERNAL; id < HAL_SPI_ID_QTY; id++) { + if (spi_rxdma_chan[id] == chan) { + tx_chan = spi_txdma_chan[id]; + spi_rxdma_chan[id] = HAL_DMA_CHAN_NONE; + spi_txdma_chan[id] = HAL_DMA_CHAN_NONE; + break; + } + } + int_unlock(lock); + + if (id >= HAL_SPI_ID_QTY) { + return; + } + + hal_gpdma_free_chan(chan); + hal_gpdma_cancel(tx_chan); + hal_gpdma_free_chan(tx_chan); + + if (0) { +#ifdef CHIP_HAS_SPI + } else if (id == HAL_SPI_ID_0) { + ctrl = &spi0_ctrl[spi0_cs]; +#endif +#ifdef CHIP_HAS_SPILCD + } else if (id == HAL_SPI_ID_SLCD) { + ctrl = &spilcd_ctrl[spilcd_cs]; +#endif + } + if (ctrl) { + hal_spi_set_xfer_type_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND); + } + clear_bool_flag(&in_use[id]); + + if (spi_rxdma_handler[id]) { + spi_rxdma_handler[id](error); + } +} + +static int hal_spi_dma_recv_id(enum HAL_SPI_ID_T id, const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler) +{ + uint8_t cnt; + enum HAL_DMA_RET_T ret; + struct HAL_DMA_CH_CFG_T dma_cfg; + enum HAL_DMA_WDITH_T dma_width; + uint32_t lock; + int result; + enum HAL_DMA_PERIPH_T dst_periph, src_periph; + struct HAL_SPI_CTRL_T *ctrl = NULL; + + //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id); + SPI_ASSERT((spi[id]->SSPDMACR & (SPI_SSPDMACR_TXDMAE | SPI_SSPDMACR_RXDMAE)) == + (SPI_SSPDMACR_TXDMAE | SPI_SSPDMACR_RXDMAE), "RX/TX-DMA not configured on SPI %d", id); + + spi_rxdma_handler[id] = handler; + + result = 0; + + cnt = get_frame_bytes(id); + + if ((len & (cnt - 1)) != 0) { + return -1; + } + if (((uint32_t)data & (cnt - 1)) != 0) { + return -2; + } + + // Rx transaction should start from idle state + if (spi[id]->SSPSR & SPI_SSPSR_BSY) { + return -11; + } + + if (id == HAL_SPI_ID_INTERNAL) { + src_periph = HAL_GPDMA_ISPI_RX; + dst_periph = HAL_GPDMA_ISPI_TX; +#ifdef CHIP_HAS_SPI + } else if (id == HAL_SPI_ID_0) { + src_periph = HAL_GPDMA_SPI_RX; + dst_periph = HAL_GPDMA_SPI_TX; +#endif +#ifdef CHIP_HAS_SPILCD + } else if (id == HAL_SPI_ID_SLCD) { + src_periph = HAL_GPDMA_SPILCD_RX; + dst_periph = HAL_GPDMA_SPILCD_TX; +#endif + } else { + return -12; + } + + lock = int_lock(); + if (spi_txdma_chan[id] != HAL_DMA_CHAN_NONE || spi_rxdma_chan[id] != HAL_DMA_CHAN_NONE) { + int_unlock(lock); + return -3; + } + spi_txdma_chan[id] = hal_gpdma_get_chan(dst_periph, HAL_DMA_HIGH_PRIO); + if (spi_txdma_chan[id] == HAL_DMA_CHAN_NONE) { + int_unlock(lock); + return -4; + } + spi_rxdma_chan[id] = hal_gpdma_get_chan(src_periph, HAL_DMA_HIGH_PRIO); + if (spi_rxdma_chan[id] == HAL_DMA_CHAN_NONE) { + hal_gpdma_free_chan(spi_txdma_chan[id]); + spi_txdma_chan[id] = HAL_DMA_CHAN_NONE; + int_unlock(lock); + return -5; + } + int_unlock(lock); + + if (cnt == 1) { + dma_width = HAL_DMA_WIDTH_BYTE; + } else if (cnt == 2) { + dma_width = HAL_DMA_WIDTH_HALFWORD; + } else { + dma_width = HAL_DMA_WIDTH_WORD; + } + + memset(&dma_cfg, 0, sizeof(dma_cfg)); + dma_cfg.ch = spi_rxdma_chan[id]; + dma_cfg.dst = (uint32_t)data; + dma_cfg.dst_bsize = HAL_DMA_BSIZE_16; + //dma_cfg.dst_periph = HAL_GPDMA_PERIPH_QTY; // useless + dma_cfg.dst_width = dma_width; + dma_cfg.handler = handler ? hal_spi_rxdma_handler : NULL; + dma_cfg.src = 0; // useless + dma_cfg.src_periph = src_periph; + dma_cfg.src_bsize = HAL_DMA_BSIZE_4; + dma_cfg.src_tsize = len / cnt; + dma_cfg.src_width = dma_width; + dma_cfg.try_burst = 0; + dma_cfg.type = HAL_DMA_FLOW_P2M_DMA; + + // Flush the RX FIFO by reset or DMA read (CPU read is forbidden when DMA is enabled) + if (spi[id]->SSPSR & SPI_SSPSR_RNE) { + // Reset SPI MODULE might cause the increment of the FIFO pointer + hal_cmu_reset_pulse(spi_mod[id].mod); + // Reset SPI APB will reset the FIFO pointer + hal_cmu_reset_pulse(spi_mod[id].apb); + if (0) { +#ifdef CHIP_HAS_SPI + } else if (id == HAL_SPI_ID_0) { + ctrl = &spi0_ctrl[spi0_cs]; +#endif +#ifdef CHIP_HAS_SPILCD + } else if (id == HAL_SPI_ID_SLCD) { + ctrl = &spilcd_ctrl[spilcd_cs]; +#endif + } + if (ctrl) { + // hal_spi_set_xfer_type_id() is not enough, for all the registers have been reset by APB reset + hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_RECV); + } + } + spi[id]->SSPICR = ~0UL; + + ret = hal_gpdma_start(&dma_cfg); + if (ret != HAL_DMA_OK) { + result = -8; + goto _exit; + } + + dma_cfg.ch = spi_txdma_chan[id]; + dma_cfg.dst = 0; // useless + dma_cfg.dst_bsize = HAL_DMA_BSIZE_4; + dma_cfg.dst_periph = dst_periph; + dma_cfg.dst_width = dma_width; + dma_cfg.handler = NULL; + dma_cfg.src = (uint32_t)cmd; + dma_cfg.src_bsize = HAL_DMA_BSIZE_16; + //dma_cfg.src_periph = HAL_GPDMA_PERIPH_QTY; // useless + dma_cfg.src_tsize = len / cnt; + dma_cfg.src_width = dma_width; + dma_cfg.try_burst = 0; + dma_cfg.type = HAL_DMA_FLOW_M2P_DMA; + + hal_spi_enable_slave_output_id(id); + + ret = hal_gpdma_start(&dma_cfg); + if (ret != HAL_DMA_OK) { + result = -9; + goto _exit; + } + + if (handler == NULL) { + while ((spi[id]->SSPCR1 & SPI_SSPCR1_SSE) && hal_gpdma_chan_busy(spi_rxdma_chan[id])); + } + +_exit: + if (result || handler == NULL) { + hal_gpdma_cancel(spi_txdma_chan[id]); + hal_gpdma_free_chan(spi_txdma_chan[id]); + spi_txdma_chan[id] = HAL_DMA_CHAN_NONE; + + while (hal_spi_busy_id(id)); + hal_spi_disable_slave_output_id(id); + + hal_gpdma_cancel(spi_rxdma_chan[id]); + hal_gpdma_free_chan(spi_rxdma_chan[id]); + spi_rxdma_chan[id] = HAL_DMA_CHAN_NONE; + + if (ctrl) { + hal_spi_set_xfer_type_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND); + } + } + + return 0; +} + +void hal_spi_stop_dma_recv_id(enum HAL_SPI_ID_T id) +{ + uint32_t lock; + uint8_t rx_chan, tx_chan; + struct HAL_SPI_CTRL_T *ctrl = NULL; + + lock = int_lock(); + rx_chan = spi_rxdma_chan[id]; + spi_rxdma_chan[id] = HAL_DMA_CHAN_NONE; + tx_chan = spi_txdma_chan[id]; + spi_txdma_chan[id] = HAL_DMA_CHAN_NONE; + int_unlock(lock); + + if (rx_chan == HAL_DMA_CHAN_NONE && tx_chan == HAL_DMA_CHAN_NONE) { + return; + } + + if (rx_chan != HAL_DMA_CHAN_NONE) { + hal_gpdma_cancel(rx_chan); + hal_gpdma_free_chan(rx_chan); + } + if (tx_chan != HAL_DMA_CHAN_NONE) { + hal_gpdma_cancel(tx_chan); + hal_gpdma_free_chan(tx_chan); + } + + if (0) { +#ifdef CHIP_HAS_SPI + } else if (id == HAL_SPI_ID_0) { + ctrl = &spi0_ctrl[spi0_cs]; +#endif +#ifdef CHIP_HAS_SPILCD + } else if (id == HAL_SPI_ID_SLCD) { + ctrl = &spilcd_ctrl[spilcd_cs]; +#endif + } + if (ctrl) { + hal_spi_set_xfer_type_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND); + } + clear_bool_flag(&in_use[id]); +} + +//------------------------------------------------------------ +// ISPI functions +//------------------------------------------------------------ + +int hal_ispi_open(const struct HAL_SPI_CFG_T *cfg) +{ + SPI_ASSERT(cfg->tx_bits == cfg->rx_bits && cfg->rx_frame_bits == 0, "ISPI: Bad bits cfg"); + + return hal_spi_open_id(HAL_SPI_ID_INTERNAL, cfg, NULL); +} + +int hal_ispi_close(uint32_t cs) +{ + return hal_spi_close_id(HAL_SPI_ID_INTERNAL, cs); +} + +void hal_ispi_activate_cs(uint32_t cs) +{ + SPI_ASSERT(cs < HAL_SPI_CS_QTY, "ISPI: SPI cs bad: %d", cs); + + hal_spi_set_cs_id(HAL_SPI_ID_INTERNAL, cs); +} + +int hal_ispi_busy(void) +{ + return hal_spi_busy_id(HAL_SPI_ID_INTERNAL); +} + +int hal_ispi_send(const void *data, uint32_t len) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_INTERNAL])) { + return -31; + } + + ret = hal_spi_send_id(HAL_SPI_ID_INTERNAL, data, len); + + clear_bool_flag(&in_use[HAL_SPI_ID_INTERNAL]); + + return ret; +} + +int hal_ispi_recv(const void *cmd, void *data, uint32_t len) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_INTERNAL])) { + return -31; + } + + ret = hal_spi_recv_id(HAL_SPI_ID_INTERNAL, cmd, data, len); + + clear_bool_flag(&in_use[HAL_SPI_ID_INTERNAL]); + + return ret; +} + +int hal_ispi_dma_send(const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_INTERNAL])) { + return -31; + } + + ret = hal_spi_dma_send_id(HAL_SPI_ID_INTERNAL, data, len, handler); + + if (ret || handler == NULL) { + clear_bool_flag(&in_use[HAL_SPI_ID_INTERNAL]); + } + + return ret; +} + +int hal_ispi_dma_recv(const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_INTERNAL])) { + return -31; + } + + ret = hal_spi_dma_recv_id(HAL_SPI_ID_INTERNAL, cmd, data, len, handler); + + if (ret || handler == NULL) { + clear_bool_flag(&in_use[HAL_SPI_ID_INTERNAL]); + } + + return ret; +} + +void hal_ispi_stop_dma_send(void) +{ + hal_spi_stop_dma_send_id(HAL_SPI_ID_INTERNAL); +} + +void hal_ispi_stop_dma_recv(void) +{ + hal_spi_stop_dma_recv_id(HAL_SPI_ID_INTERNAL); +} + +#ifdef CHIP_HAS_SPI +//------------------------------------------------------------ +// SPI peripheral functions +//------------------------------------------------------------ + +int hal_spi_open(const struct HAL_SPI_CFG_T *cfg) +{ + int ret; + uint32_t lock; + + if (cfg->cs >= HAL_SPI_CS_QTY) { + return -1; + } + + lock = int_lock(); + + ret = hal_spi_open_id(HAL_SPI_ID_0, cfg, &spi0_ctrl[cfg->cs]); + +#if (CHIP_SPI_VER >= 2) + if (ret == 0) { + spi0_cs = cfg->cs; + } +#endif + + int_unlock(lock); + + return ret; +} + +int hal_spi_close(uint32_t cs) +{ + int ret; + uint32_t lock; + + lock = int_lock(); + + ret = hal_spi_close_id(HAL_SPI_ID_0, cs); + +#if (CHIP_SPI_VER >= 2) + if (ret == 0 && spi0_cs == cs) { + uint32_t lowest_cs; + + lowest_cs = __CLZ(__RBIT(spi_cs_map[HAL_SPI_ID_0])); + if (lowest_cs < HAL_SPI_CS_QTY) { + hal_spi_activate_cs_id(HAL_SPI_ID_0, lowest_cs); + } else { + lowest_cs = HAL_SPI_CS_0; + } + spi0_cs = lowest_cs; + } +#endif + + int_unlock(lock); + + return ret; +} + +int hal_spi_activate_cs(uint32_t cs) +{ + return hal_spi_activate_cs_id(HAL_SPI_ID_0, cs); +} + +int hal_spi_busy(void) +{ + return hal_spi_busy_id(HAL_SPI_ID_0); +} + +int hal_spi_send(const void *data, uint32_t len) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_0])) { + return -31; + } + + ret = hal_spi_send_id(HAL_SPI_ID_0, data, len); + + clear_bool_flag(&in_use[HAL_SPI_ID_0]); + + return ret; +} + +int hal_spi_recv(const void *cmd, void *data, uint32_t len) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_0])) { + return -31; + } + + hal_spi_set_xfer_type_id(HAL_SPI_ID_0, &spi0_ctrl[spi0_cs], HAL_SPI_XFER_TYPE_RECV); + ret = hal_spi_recv_id(HAL_SPI_ID_0, cmd, data, len); + hal_spi_set_xfer_type_id(HAL_SPI_ID_0, &spi0_ctrl[spi0_cs], HAL_SPI_XFER_TYPE_SEND); + + clear_bool_flag(&in_use[HAL_SPI_ID_0]); + + return ret; +} + +int hal_spi_dma_send(const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_0])) { + return -31; + } + + ret = hal_spi_dma_send_id(HAL_SPI_ID_0, data, len, handler); + + if (ret || handler == NULL) { + clear_bool_flag(&in_use[HAL_SPI_ID_0]); + } + + return ret; +} + +int hal_spi_dma_recv(const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_0])) { + return -31; + } + + hal_spi_set_xfer_type_id(HAL_SPI_ID_0, &spi0_ctrl[spi0_cs], HAL_SPI_XFER_TYPE_RECV); + + ret = hal_spi_dma_recv_id(HAL_SPI_ID_0, cmd, data, len, handler); + + if (ret || handler == NULL) { + hal_spi_set_xfer_type_id(HAL_SPI_ID_0, &spi0_ctrl[spi0_cs], HAL_SPI_XFER_TYPE_SEND); + + clear_bool_flag(&in_use[HAL_SPI_ID_0]); + } + + return ret; +} + +void hal_spi_stop_dma_send(void) +{ + hal_spi_stop_dma_send_id(HAL_SPI_ID_0); +} + +void hal_spi_stop_dma_recv(void) +{ + hal_spi_stop_dma_recv_id(HAL_SPI_ID_0); +} + +int hal_spi_enable_and_send(const struct HAL_SPI_CTRL_T *ctrl, const void *data, uint32_t len) +{ + return hal_spi_enable_and_send_id(HAL_SPI_ID_0, ctrl, data, len); +} + +int hal_spi_enable_and_recv(const struct HAL_SPI_CTRL_T *ctrl, const void *cmd, void *data, uint32_t len) +{ + return hal_spi_enable_and_recv_id(HAL_SPI_ID_0, ctrl, cmd, data, len); +} +#endif // CHIP_HAS_SPI + +#ifdef CHIP_HAS_SPILCD +//------------------------------------------------------------ +// SPI LCD functions +//------------------------------------------------------------ + +int hal_spilcd_open(const struct HAL_SPI_CFG_T *cfg) +{ + int ret; + uint32_t lock; + + if (cfg->cs >= HAL_SPI_CS_QTY) { + return -1; + } + + lock = int_lock(); + + ret = hal_spi_open_id(HAL_SPI_ID_SLCD, cfg, &spilcd_ctrl[cfg->cs]); + +#if (CHIP_SPI_VER >= 2) + if (ret == 0) { + spilcd_cs = cfg->cs; + } +#endif + + int_unlock(lock); + + return ret; +} + +int hal_spilcd_close(uint32_t cs) +{ + int ret; + uint32_t lock; + + lock = int_lock(); + + ret = hal_spi_close_id(HAL_SPI_ID_SLCD, cs); + +#if (CHIP_SPI_VER >= 2) + if (ret == 0 && spilcd_cs == cs) { + uint32_t lowest_cs; + + lowest_cs = __CLZ(__RBIT(spi_cs_map[HAL_SPI_ID_SLCD])); + if (lowest_cs < HAL_SPI_CS_QTY) { + hal_spi_activate_cs_id(HAL_SPI_ID_SLCD, lowest_cs); + } else { + lowest_cs = HAL_SPI_CS_0; + } + spilcd_cs = lowest_cs; + } +#endif + + int_unlock(lock); + + return ret; +} + +int hal_spilcd_activate_cs(uint32_t cs) +{ + return hal_spi_activate_cs_id(HAL_SPI_ID_SLCD, cs); +} + +int hal_spilcd_busy(void) +{ + return hal_spi_busy_id(HAL_SPI_ID_SLCD); +} + +int hal_spilcd_send(const void *data, uint32_t len) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) { + return -31; + } + + ret = hal_spi_send_id(HAL_SPI_ID_SLCD, data, len); + + clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]); + + return ret; +} + +int hal_spilcd_recv(const void *cmd, void *data, uint32_t len) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) { + return -31; + } + + hal_spi_set_xfer_type_id(HAL_SPI_ID_SLCD, &spilcd_ctrl[spilcd_cs], HAL_SPI_XFER_TYPE_RECV); + ret = hal_spi_recv_id(HAL_SPI_ID_SLCD, cmd, data, len); + hal_spi_set_xfer_type_id(HAL_SPI_ID_SLCD, &spilcd_ctrl[spilcd_cs], HAL_SPI_XFER_TYPE_SEND); + + clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]); + + return ret; +} + +int hal_spilcd_dma_send(const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) { + return -31; + } + + ret = hal_spi_dma_send_id(HAL_SPI_ID_SLCD, data, len, handler); + + if (ret || handler == NULL) { + clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]); + } + + return ret; +} + +int hal_spilcd_dma_recv(const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) { + return -31; + } + + hal_spi_set_xfer_type_id(HAL_SPI_ID_SLCD, &spilcd_ctrl[spilcd_cs], HAL_SPI_XFER_TYPE_RECV); + + ret = hal_spi_dma_recv_id(HAL_SPI_ID_SLCD, cmd, data, len, handler); + + if (ret || handler == NULL) { + hal_spi_set_xfer_type_id(HAL_SPI_ID_SLCD, &spilcd_ctrl[spilcd_cs], HAL_SPI_XFER_TYPE_SEND); + + clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]); + } + + return ret; +} + +void hal_spilcd_stop_dma_send(void) +{ + hal_spi_stop_dma_send_id(HAL_SPI_ID_SLCD); +} + +void hal_spilcd_stop_dma_recv(void) +{ + hal_spi_stop_dma_recv_id(HAL_SPI_ID_SLCD); +} + +int hal_spilcd_set_data_mode(void) +{ + if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) { + return -31; + } + + spi[HAL_SPI_ID_SLCD]->SSPCR1 |= SPI_LCD_DC_DATA; + + clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]); + return 0; +} + +int hal_spilcd_set_cmd_mode(void) +{ + if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) { + return -31; + } + + spi[HAL_SPI_ID_SLCD]->SSPCR1 &= ~SPI_LCD_DC_DATA; + + clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]); + return 0; +} + +int hal_spilcd_enable_and_send(const struct HAL_SPI_CTRL_T *ctrl, const void *data, uint32_t len) +{ + return hal_spi_enable_and_send_id(HAL_SPI_ID_SLCD, ctrl, data, len); +} + +int hal_spilcd_enable_and_recv(const struct HAL_SPI_CTRL_T *ctrl, const void *cmd, void *data, uint32_t len) +{ + return hal_spi_enable_and_recv_id(HAL_SPI_ID_SLCD, ctrl, cmd, data, len); +} +#endif // CHIP_HAS_SPILCD + +#ifdef CHIP_HAS_SPIPHY +//------------------------------------------------------------ +// SPI PHY functions +//------------------------------------------------------------ + +int hal_spiphy_open(const struct HAL_SPI_CFG_T *cfg) +{ + SPI_ASSERT(cfg->tx_bits == cfg->rx_bits && cfg->rx_frame_bits == 0, "SPIPHY: Bad bits cfg"); + + return hal_spi_open_id(HAL_SPI_ID_PHY, cfg, NULL); +} + +int hal_spiphy_close(uint32_t cs) +{ + return hal_spi_close_id(HAL_SPI_ID_PHY, cs); +} + +void hal_spiphy_activate_cs(uint32_t cs) +{ + SPI_ASSERT(cs < HAL_SPI_CS_QTY, "SPIPHY: SPI cs bad: %d", cs); + + hal_spi_set_cs_id(HAL_SPI_ID_PHY, cs); +} + +int hal_spiphy_busy(void) +{ + return hal_spi_busy_id(HAL_SPI_ID_PHY); +} + +int hal_spiphy_send(const void *data, uint32_t len) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_PHY])) { + return -31; + } + + ret = hal_spi_send_id(HAL_SPI_ID_PHY, data, len); + + clear_bool_flag(&in_use[HAL_SPI_ID_PHY]); + + return ret; +} + +int hal_spiphy_recv(const void *cmd, void *data, uint32_t len) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_PHY])) { + return -31; + } + + ret = hal_spi_recv_id(HAL_SPI_ID_PHY, cmd, data, len); + + clear_bool_flag(&in_use[HAL_SPI_ID_PHY]); + + return ret; +} +#endif // CHIP_HAS_SPIPHY + +#ifdef CHIP_HAS_SPIDPD +//------------------------------------------------------------ +// SPI DPD functions +//------------------------------------------------------------ + +int hal_spidpd_open(const struct HAL_SPI_CFG_T *cfg) +{ + SPI_ASSERT(cfg->rx_frame_bits == 0, "SPIDPD: Bad bits cfg"); + + return hal_spi_open_id(HAL_SPI_ID_DPD, cfg, &spidpd_ctrl); +} + +int hal_spidpd_close(uint32_t cs) +{ + return hal_spi_close_id(HAL_SPI_ID_DPD, cs); +} + +void hal_spidpd_activate_cs(uint32_t cs) +{ + SPI_ASSERT(cs < HAL_SPI_CS_QTY, "SPIDPD: SPI cs bad: %d", cs); + + hal_spi_set_cs_id(HAL_SPI_ID_DPD, cs); +} + +int hal_spidpd_busy(void) +{ + return hal_spi_busy_id(HAL_SPI_ID_DPD); +} + +int hal_spidpd_send(const void *data, uint32_t len) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_DPD])) { + return -31; + } + + ret = hal_spi_send_id(HAL_SPI_ID_DPD, data, len); + + clear_bool_flag(&in_use[HAL_SPI_ID_DPD]); + + return ret; +} + +int hal_spidpd_recv(const void *cmd, void *data, uint32_t len) +{ + int ret; + + if (set_bool_flag(&in_use[HAL_SPI_ID_DPD])) { + return -31; + } + + hal_spi_set_xfer_type_id(HAL_SPI_ID_DPD, &spidpd_ctrl, HAL_SPI_XFER_TYPE_RECV); + ret = hal_spi_recv_id(HAL_SPI_ID_DPD, cmd, data, len); + hal_spi_set_xfer_type_id(HAL_SPI_ID_DPD, &spidpd_ctrl, HAL_SPI_XFER_TYPE_SEND); + + clear_bool_flag(&in_use[HAL_SPI_ID_DPD]); + + return ret; +} +#endif // CHIP_HAS_SPIDPD + +#endif // !SPI_ROM_ONLY + diff --git a/platform/hal/hal_spi.h b/platform/hal/hal_spi.h new file mode 100644 index 0000000..bc161ff --- /dev/null +++ b/platform/hal/hal_spi.h @@ -0,0 +1,209 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_SPI_H__ +#define __HAL_SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "stdbool.h" + +enum HAL_SPI_MOD_CLK_SEL_T { + HAL_SPI_MOD_CLK_SEL_NONE, + HAL_SPI_MOD_CLK_SEL_OSC, + HAL_SPI_MOD_CLK_SEL_OSC_X2, + HAL_SPI_MOD_CLK_SEL_PLL, +}; + +struct HAL_SPI_CTRL_T { + uint32_t sspcr0_tx; + uint32_t sspcr0_rx; + uint16_t sspcr1; + uint16_t sspcpsr; + uint16_t sspdmacr; + uint16_t ssprxcr_tx; + uint16_t ssprxcr_rx; + enum HAL_SPI_MOD_CLK_SEL_T clk_sel; +}; + +struct HAL_SPI_CFG_T { + uint32_t rate; + bool clk_delay_half :1; + bool clk_polarity :1; + bool slave :1; + bool dma_rx :1; + bool dma_tx :1; + bool rx_sep_line :1; + uint8_t cs; + uint8_t tx_bits; + uint8_t rx_bits; + uint8_t rx_frame_bits; +}; + +typedef void (*HAL_SPI_DMA_HANDLER_T)(int error); + +//------------------------------------------------------------ +// SPI common functions +//------------------------------------------------------------ + +int hal_spi_init_ctrl(const struct HAL_SPI_CFG_T *cfg, struct HAL_SPI_CTRL_T *ctrl); + +//------------------------------------------------------------ +// SPI ROM functions +//------------------------------------------------------------ + +int hal_ispi_rom_open(const struct HAL_SPI_CFG_T *cfg); + +void hal_ispi_rom_activate_cs(uint32_t cs); + +int hal_ispi_rom_busy(void); + +int hal_ispi_rom_send(const void *data, uint32_t len); + +int hal_ispi_rom_recv(const void *cmd, void *data, uint32_t len); + +int hal_spiphy_rom_open(const struct HAL_SPI_CFG_T *cfg); + +void hal_spiphy_rom_close(void); + +int hal_spiphy_rom_busy(void); + +int hal_spiphy_rom_send(const void *data, uint32_t len); + +int hal_spiphy_rom_recv(const void *cmd, void *data, uint32_t len); + +//------------------------------------------------------------ +// ISPI functions +//------------------------------------------------------------ + +int hal_ispi_open(const struct HAL_SPI_CFG_T *cfg); + +int hal_ispi_close(uint32_t cs); + +void hal_ispi_activate_cs(uint32_t cs); + +int hal_ispi_busy(void); + +int hal_ispi_send(const void *data, uint32_t len); + +int hal_ispi_recv(const void *cmd, void *data, uint32_t len); + +int hal_ispi_dma_send(const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler); + +int hal_ispi_dma_recv(const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler); + +void hal_ispi_stop_dma_send(void); + +void hal_ispi_stop_dma_recv(void); + +//------------------------------------------------------------ +// SPI peripheral functions +//------------------------------------------------------------ + +int hal_spi_open(const struct HAL_SPI_CFG_T *cfg); + +int hal_spi_close(uint32_t cs); + +int hal_spi_activate_cs(uint32_t cs); + +int hal_spi_busy(void); + +int hal_spi_send(const void *data, uint32_t len); + +int hal_spi_recv(const void *cmd, void *data, uint32_t len); + +int hal_spi_dma_send(const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler); + +int hal_spi_dma_recv(const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler); + +void hal_spi_stop_dma_send(void); + +void hal_spi_stop_dma_recv(void); + +int hal_spi_enable_and_send(const struct HAL_SPI_CTRL_T *ctrl, const void *data, uint32_t len); + +int hal_spi_enable_and_recv(const struct HAL_SPI_CTRL_T *ctrl, const void *cmd, void *data, uint32_t len); + +//------------------------------------------------------------ +// SPI LCD functions +//------------------------------------------------------------ + +int hal_spilcd_open(const struct HAL_SPI_CFG_T *cfg); + +int hal_spilcd_close(uint32_t cs); + +int hal_spilcd_activate_cs(uint32_t cs); + +int hal_spilcd_busy(void); + +int hal_spilcd_send(const void *data, uint32_t len); + +int hal_spilcd_recv(const void *cmd, void *data, uint32_t len); + +int hal_spilcd_dma_send(const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler); + +int hal_spilcd_dma_recv(const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler); + +void hal_spilcd_stop_dma_send(void); + +void hal_spilcd_stop_dma_recv(void); + +int hal_spilcd_set_data_mode(void); + +int hal_spilcd_set_cmd_mode(void); + +int hal_spilcd_enable_and_send(const struct HAL_SPI_CTRL_T *ctrl, const void *data, uint32_t len); + +int hal_spilcd_enable_and_recv(const struct HAL_SPI_CTRL_T *ctrl, const void *cmd, void *data, uint32_t len); + +//------------------------------------------------------------ +// SPI PHY functions +//------------------------------------------------------------ + +int hal_spiphy_open(const struct HAL_SPI_CFG_T *cfg); + +int hal_spiphy_close(uint32_t cs); + +void hal_spiphy_activate_cs(uint32_t cs); + +int hal_spiphy_busy(void); + +int hal_spiphy_send(const void *data, uint32_t len); + +int hal_spiphy_recv(const void *cmd, void *data, uint32_t len); + +//------------------------------------------------------------ +// SPI DPD functions +//------------------------------------------------------------ + +int hal_spidpd_open(const struct HAL_SPI_CFG_T *cfg); + +int hal_spidpd_close(uint32_t cs); + +int hal_spidpd_busy(void); + +int hal_spidpd_send(const void *data, uint32_t len); + +int hal_spidpd_recv(const void *cmd, void *data, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_sysfreq.c b/platform/hal/hal_sysfreq.c new file mode 100644 index 0000000..8b2e332 --- /dev/null +++ b/platform/hal/hal_sysfreq.c @@ -0,0 +1,160 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "hal_sysfreq.h" +#include "hal_location.h" +#include "hal_trace.h" +#include "cmsis.h" +#ifndef ROM_BUILD +#include "pmu.h" +#endif + +static uint32_t BOOT_BSS_LOC sysfreq_bundle[(HAL_SYSFREQ_USER_QTY + 3) / 4]; + +static uint8_t * const sysfreq_per_user = (uint8_t *)&sysfreq_bundle[0]; + +static enum HAL_SYSFREQ_USER_T BOOT_DATA_LOC top_user = HAL_SYSFREQ_USER_QTY; + +static enum HAL_CMU_FREQ_T BOOT_DATA_LOC min_sysfreq = HAL_CMU_FREQ_26M; + +static enum HAL_CMU_FREQ_T hal_sysfreq_revise_freq(enum HAL_CMU_FREQ_T freq) +{ + return freq > min_sysfreq ? freq : min_sysfreq; +} + +void hal_sysfreq_set_min_freq(enum HAL_CMU_FREQ_T freq) +{ + uint32_t lock; + + lock = int_lock(); + + if (min_sysfreq < freq) { + min_sysfreq = freq; + if (min_sysfreq > hal_sysfreq_get()) { + hal_cmu_sys_set_freq(min_sysfreq); + } + } + + int_unlock(lock); +} + +int hal_sysfreq_req(enum HAL_SYSFREQ_USER_T user, enum HAL_CMU_FREQ_T freq) +{ + uint32_t lock; + enum HAL_CMU_FREQ_T cur_sys_freq; + int i; + + if (user >= HAL_SYSFREQ_USER_QTY) { + return 1; + } + if (freq >= HAL_CMU_FREQ_QTY) { + return 2; + } + + lock = int_lock(); + + cur_sys_freq = hal_sysfreq_get(); + + sysfreq_per_user[user] = freq; + + if (freq == cur_sys_freq) { + top_user = user; + } else if (freq > cur_sys_freq) { + top_user = user; + freq = hal_sysfreq_revise_freq(freq); +#ifndef ROM_BUILD + pmu_sys_freq_config(freq); +#ifdef ULTRA_LOW_POWER + // Enable PLL if required + hal_cmu_low_freq_mode_disable(hal_sysfreq_revise_freq(cur_sys_freq), freq); +#endif +#endif + hal_cmu_sys_set_freq(freq); + } else /* if (freq < cur_sys_freq) */ { + if (top_user == user || top_user == HAL_SYSFREQ_USER_QTY) { + if (top_user == user) { + freq = sysfreq_per_user[0]; + user = 0; + for (i = 1; i < HAL_SYSFREQ_USER_QTY; i++) { + if (freq < sysfreq_per_user[i]) { + freq = sysfreq_per_user[i]; + user = i; + } + } + } + top_user = user; + if (freq != cur_sys_freq) { + freq = hal_sysfreq_revise_freq(freq); + hal_cmu_sys_set_freq(freq); +#ifndef ROM_BUILD +#ifdef ULTRA_LOW_POWER + // Disable PLL if capable + hal_cmu_low_freq_mode_enable(hal_sysfreq_revise_freq(cur_sys_freq), freq); +#endif + pmu_sys_freq_config(freq); +#endif + } + } + } + + int_unlock(lock); + + return 0; +} + +enum HAL_CMU_FREQ_T hal_sysfreq_get(void) +{ + if (top_user < HAL_SYSFREQ_USER_QTY) { + return sysfreq_per_user[top_user]; + } else { + return hal_cmu_sys_get_freq(); + } +} + +enum HAL_CMU_FREQ_T hal_sysfreq_get_hw_freq(void) +{ + if (top_user < HAL_SYSFREQ_USER_QTY) { + return hal_sysfreq_revise_freq(sysfreq_per_user[top_user]); + } else { + return hal_cmu_sys_get_freq(); + } +} + +int hal_sysfreq_busy(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(sysfreq_bundle); i++) { + if (sysfreq_bundle[i] != 0) { + return 1; + } + } + + return 0; +} + +void hal_sysfreq_print(void) +{ + int i; + + for (i = 0; i < HAL_SYSFREQ_USER_QTY; i++) { + if (sysfreq_per_user[i] != 0) { + TRACE(2,"*** SYSFREQ user=%d freq=%d", i, sysfreq_per_user[i]); + } + } + TRACE(1,"*** SYSFREQ top_user=%d", top_user); +} + diff --git a/platform/hal/hal_sysfreq.h b/platform/hal/hal_sysfreq.h new file mode 100644 index 0000000..1f3808e --- /dev/null +++ b/platform/hal/hal_sysfreq.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_SYSFREQ_H__ +#define __HAL_SYSFREQ_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_cmu.h" + +enum HAL_SYSFREQ_USER_T { + HAL_SYSFREQ_USER_INIT, + HAL_SYSFREQ_USER_OVERLAY, + HAL_SYSFREQ_USER_USB, + HAL_SYSFREQ_USER_BT, + HAL_SYSFREQ_USER_ANC, + + HAL_SYSFREQ_USER_APP_0, + HAL_SYSFREQ_USER_APP_1, + HAL_SYSFREQ_USER_APP_2, + HAL_SYSFREQ_USER_APP_3, + HAL_SYSFREQ_USER_APP_4, + HAL_SYSFREQ_USER_APP_5, + HAL_SYSFREQ_USER_APP_6, + HAL_SYSFREQ_USER_APP_7, + HAL_SYSFREQ_USER_APP_8, + HAL_SYSFREQ_USER_APP_9, + HAL_SYSFREQ_USER_APP_10, + HAL_SYSFREQ_USER_APP_11, + HAL_SYSFREQ_USER_APP_12, + HAL_SYSFREQ_USER_APP_13, + HAL_SYSFREQ_USER_APP_14, + HAL_SYSFREQ_USER_APP_15, + + HAL_SYSFREQ_USER_QTY +}; + +void hal_sysfreq_set_min_freq(enum HAL_CMU_FREQ_T freq); + +int hal_sysfreq_req(enum HAL_SYSFREQ_USER_T user, enum HAL_CMU_FREQ_T freq); + +enum HAL_CMU_FREQ_T hal_sysfreq_get(void); + +enum HAL_CMU_FREQ_T hal_sysfreq_get_hw_freq(void); + +int hal_sysfreq_busy(void); + +void hal_sysfreq_print(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_tdm.c b/platform/hal/hal_tdm.c new file mode 100644 index 0000000..af6632a --- /dev/null +++ b/platform/hal/hal_tdm.c @@ -0,0 +1,589 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include +#include +#include "hal_i2s.h" +#include "hal_trace.h" +#include "hal_dma.h" +#include "hal_tdm.h" +#ifndef CHIP_HAS_TDM +#include "hal_i2s_tdm.h" +#endif + +#if 0 +#define TDM_TRACE TRACE +#define TDM_DUMP8 DUMP8 +#else +#define TDM_TRACE(n, str, ...) +#define TDM_DUMP8(str, ...) +#endif + +#ifdef CHIP_HAS_TDM + +static const char * const invalid_id = "Invalid I2S ID: %d\n"; +static inline uint32_t _tdm_get_reg_base(enum HAL_I2S_ID_T id) +{ + ASSERT(id < HAL_I2S_ID_QTY, invalid_id, id); + switch(id) { + case HAL_I2S_ID_0: + return (I2S0_BASE | I2SIP_TDM_CTRL_REG_OFFSET); + break; +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + case HAL_I2S_ID_1: + return (I2S1_BASE | I2SIP_TDM_CTRL_REG_OFFSET); + break; +#endif + default: + break; + } + return 0; +} + +static inline bool tdm_slot_cycles_in_arrays(uint8_t slot_cycles) +{ + if(slot_cycles == (uint8_t)HAL_TDM_SLOT_CYCLES_16 + || slot_cycles == (uint8_t)HAL_TDM_SLOT_CYCLES_32) + return true; + else + return false; +} + +static inline bool tdm_cycles_in_arrays(uint16_t cycles) +{ + if(cycles == (uint16_t)HAL_TDM_CYCLES_16 + || cycles == (uint16_t)HAL_TDM_CYCLES_32 + || cycles == (uint16_t)HAL_TDM_CYCLES_64 + || cycles == (uint16_t)HAL_TDM_CYCLES_128 + || cycles == (uint16_t)HAL_TDM_CYCLES_256) + return true; + else + return false; +} + +static inline bool tdm_fs_cycles_in_arrays(uint16_t fs_cycles) +{ + if(fs_cycles == (uint16_t)HAL_TDM_FS_CYCLES_1 + || fs_cycles == (uint16_t)HAL_TDM_FS_CYCLES_8 + || fs_cycles == (uint16_t)HAL_TDM_FS_CYCLES_16 + || fs_cycles == (uint16_t)HAL_TDM_FS_CYCLES_32 + || fs_cycles == (uint16_t)HAL_TDM_FS_CYCLES_64 + || fs_cycles == (uint16_t)HAL_TDM_FS_CYCLES_128 + || fs_cycles == (uint16_t)HAL_TDM_FS_CYCLES_ONE_LESS) + return true; + else + return false; +} +static void tdm_get_config(enum HAL_I2S_ID_T i2s_id,struct HAL_TDM_CONFIG_T *tdm_config) +{ + volatile uint32_t *base_addr; + uint32_t val; + + base_addr = (uint32_t*)_tdm_get_reg_base(i2s_id); + val = *base_addr; + + if((val & (TDM_MODE_FS_ASSERTED_AT_LAST << TDM_MODE_FS_ASSERTED_SHIFT)) == (TDM_MODE_FS_ASSERTED_AT_LAST << TDM_MODE_FS_ASSERTED_SHIFT)) + { + tdm_config->mode = HAL_TDM_MODE_FS_ASSERTED_AT_LAST; + } + else + { + tdm_config->mode = HAL_TDM_MODE_FS_ASSERTED_AT_FIRST; + } + + if((val & (TDM_FS_EDGE_NEGEDGE << TDM_FS_EDGE_SHIFT)) == (TDM_FS_EDGE_NEGEDGE << TDM_FS_EDGE_SHIFT)) + { + tdm_config->edge = HAL_TDM_FS_EDGE_NEGEDGE; + } + else + { + tdm_config->edge = HAL_TDM_FS_EDGE_POSEDGE; + } + + if((val & (TDM_FRAME_WIDTH_16_CYCLES << TDM_FRAME_WIDTH_SHIFT)) == (TDM_FRAME_WIDTH_16_CYCLES << TDM_FRAME_WIDTH_SHIFT)) + { + tdm_config->cycles = HAL_TDM_CYCLES_16; + } + else if((val & (TDM_FRAME_WIDTH_32_CYCLES << TDM_FRAME_WIDTH_SHIFT)) == (TDM_FRAME_WIDTH_32_CYCLES << TDM_FRAME_WIDTH_SHIFT)) + { + tdm_config->cycles = HAL_TDM_CYCLES_32; + } + else if((val & (TDM_FRAME_WIDTH_64_CYCLES << TDM_FRAME_WIDTH_SHIFT)) == (TDM_FRAME_WIDTH_64_CYCLES << TDM_FRAME_WIDTH_SHIFT)) + { + tdm_config->cycles = HAL_TDM_CYCLES_64; + } + else if((val & (TDM_FRAME_WIDTH_128_CYCLES << TDM_FRAME_WIDTH_SHIFT)) == (TDM_FRAME_WIDTH_128_CYCLES << TDM_FRAME_WIDTH_SHIFT)) + { + tdm_config->cycles = HAL_TDM_CYCLES_128; + } + else if((val & (TDM_FRAME_WIDTH_256_CYCLES << TDM_FRAME_WIDTH_SHIFT)) == (TDM_FRAME_WIDTH_256_CYCLES << TDM_FRAME_WIDTH_SHIFT)) + { + tdm_config->cycles = HAL_TDM_CYCLES_256; + } + else + { + tdm_config->cycles = HAL_TDM_CYCLES_256; + } + + if((val & (TDM_FS_WIDTH_8_CYCLES << TDM_FS_WIDTH_SHIFT)) == (TDM_FS_WIDTH_8_CYCLES << TDM_FS_WIDTH_SHIFT)) + { + tdm_config->fs_cycles = HAL_TDM_FS_CYCLES_8; + } + else if((val & (TDM_FS_WIDTH_16_CYCLES << TDM_FS_WIDTH_SHIFT)) == (TDM_FS_WIDTH_16_CYCLES << TDM_FS_WIDTH_SHIFT)) + { + tdm_config->fs_cycles = HAL_TDM_FS_CYCLES_16; + } + else if((val & (TDM_FS_WIDTH_32_CYCLES << TDM_FS_WIDTH_SHIFT)) == (TDM_FS_WIDTH_32_CYCLES << TDM_FS_WIDTH_SHIFT)) + { + tdm_config->fs_cycles = HAL_TDM_FS_CYCLES_32; + } + else if((val & (TDM_FS_WIDTH_64_CYCLES << TDM_FS_WIDTH_SHIFT)) == (TDM_FS_WIDTH_64_CYCLES << TDM_FS_WIDTH_SHIFT)) + { + tdm_config->fs_cycles = HAL_TDM_FS_CYCLES_64; + } + else if((val & (TDM_FS_WIDTH_128_CYCLES << TDM_FS_WIDTH_SHIFT)) == (TDM_FS_WIDTH_128_CYCLES << TDM_FS_WIDTH_SHIFT)) + { + tdm_config->fs_cycles = HAL_TDM_FS_CYCLES_128; + } + else if((val & (TDM_FS_WIDTH_1_CYCLE << TDM_FS_WIDTH_SHIFT)) == (TDM_FS_WIDTH_1_CYCLE << TDM_FS_WIDTH_SHIFT)) + { + tdm_config->fs_cycles = HAL_TDM_FS_CYCLES_ONE_LESS; + } + else + { + tdm_config->fs_cycles = HAL_TDM_FS_CYCLES_ONE_LESS; + } + + if((val & (TDM_SLOT_WIDTH_16_BIT << TDM_SLOT_WIDTH_SHIFT)) == (TDM_SLOT_WIDTH_16_BIT << TDM_SLOT_WIDTH_SHIFT)) + { + tdm_config->slot_cycles = HAL_TDM_SLOT_CYCLES_16; + } + else + { + tdm_config->slot_cycles = HAL_TDM_SLOT_CYCLES_32; + } + + tdm_config->data_offset = ((val >> TDM_DATA_OFFSET_SHIT) & 0x7); +} + +static void tdm_set_config(enum HAL_I2S_ID_T i2s_id,struct HAL_TDM_CONFIG_T *tdm_config) +{ + volatile uint32_t *base_addr; + uint32_t val = 0; + + base_addr = (uint32_t*)_tdm_get_reg_base(i2s_id); + ASSERT(tdm_config->mode < HAL_TDM_MODE_NUM, + "%s: mode = %d error!",__func__, tdm_config->mode); + ASSERT(tdm_config->edge < HAL_TDM_FS_EDGE_NUM, + "%s: edge = %d error!",__func__, tdm_config->edge); + ASSERT(tdm_cycles_in_arrays((uint16_t)tdm_config->cycles), + "%s: cycles = %d error!",__func__, tdm_config->cycles); + ASSERT(tdm_fs_cycles_in_arrays((uint16_t)tdm_config->fs_cycles), + "%s: fs_cycles = %d cycles = %d error!",__func__, tdm_config->fs_cycles, tdm_config->cycles); + ASSERT(tdm_slot_cycles_in_arrays((uint8_t)tdm_config->slot_cycles), + "%s: slot_cycles = %d error!",__func__, tdm_config->slot_cycles); + + if(tdm_config->mode == HAL_TDM_MODE_FS_ASSERTED_AT_LAST) { + val |= (TDM_MODE_FS_ASSERTED_AT_LAST << TDM_MODE_FS_ASSERTED_SHIFT); + } + + if(tdm_config->edge == HAL_TDM_FS_EDGE_NEGEDGE) { + val |= (TDM_FS_EDGE_NEGEDGE << TDM_FS_EDGE_SHIFT); + } + + if(tdm_config->cycles == HAL_TDM_CYCLES_16) { + val |= (TDM_FRAME_WIDTH_16_CYCLES << TDM_FRAME_WIDTH_SHIFT); + } + else if(tdm_config->cycles == HAL_TDM_CYCLES_32) { + val |= (TDM_FRAME_WIDTH_32_CYCLES << TDM_FRAME_WIDTH_SHIFT); + } + else if(tdm_config->cycles == HAL_TDM_CYCLES_64) { + val |= (TDM_FRAME_WIDTH_64_CYCLES << TDM_FRAME_WIDTH_SHIFT); + } + else if(tdm_config->cycles == HAL_TDM_CYCLES_128) { + val |= (TDM_FRAME_WIDTH_128_CYCLES << TDM_FRAME_WIDTH_SHIFT); + } + else { + val |= (TDM_FRAME_WIDTH_256_CYCLES << TDM_FRAME_WIDTH_SHIFT); + } + + if(tdm_config->fs_cycles == HAL_TDM_FS_CYCLES_8) { + val |= (TDM_FS_WIDTH_8_CYCLES << TDM_FS_WIDTH_SHIFT); + } + else if(tdm_config->fs_cycles == HAL_TDM_FS_CYCLES_16) + { + val |= (TDM_FS_WIDTH_16_CYCLES << TDM_FS_WIDTH_SHIFT); + } + else if(tdm_config->fs_cycles == HAL_TDM_FS_CYCLES_32) + { + val |= (TDM_FS_WIDTH_32_CYCLES << TDM_FS_WIDTH_SHIFT); + } + else if(tdm_config->fs_cycles == HAL_TDM_FS_CYCLES_64) + { + val |= (TDM_FS_WIDTH_64_CYCLES << TDM_FS_WIDTH_SHIFT); + } + else if(tdm_config->fs_cycles == HAL_TDM_FS_CYCLES_128) + { + val |= (TDM_FS_WIDTH_128_CYCLES << TDM_FS_WIDTH_SHIFT); + } + else + { + val |= (TDM_FS_WIDTH_FRAME_LENGTH_1_CYCLES << TDM_FS_WIDTH_SHIFT); + } + + if(tdm_config->slot_cycles == HAL_TDM_SLOT_CYCLES_16) + { + val |= (TDM_SLOT_WIDTH_16_BIT << TDM_SLOT_WIDTH_SHIFT); + } + + if(tdm_config->data_offset >= TDM_DATA_OFFSET_MIN + && tdm_config->data_offset <= TDM_DATA_OFFSET_MAX) + { + val |= (tdm_config->data_offset << TDM_DATA_OFFSET_SHIT); + } + + *base_addr = val; +} + +static void tdm_get_default_config(struct HAL_TDM_CONFIG_T *tdm_config) +{ + tdm_config->mode = HAL_TDM_MODE_FS_ASSERTED_AT_FIRST; + tdm_config->edge = HAL_TDM_FS_EDGE_POSEDGE; + tdm_config->cycles = HAL_TDM_CYCLES_32; + tdm_config->fs_cycles = HAL_TDM_FS_CYCLES_1; + tdm_config->slot_cycles = HAL_TDM_SLOT_CYCLES_32; + tdm_config->data_offset = 0; +} + +static void tdm_get_i2s_config(struct HAL_TDM_CONFIG_T *tdm_config) +{ + tdm_config->mode = HAL_TDM_MODE_FS_ASSERTED_AT_LAST; + tdm_config->edge = HAL_TDM_FS_EDGE_NEGEDGE; + tdm_config->cycles = HAL_TDM_CYCLES_32; + tdm_config->fs_cycles = HAL_TDM_FS_CYCLES_16; + tdm_config->slot_cycles = HAL_TDM_SLOT_CYCLES_16; + tdm_config->data_offset = 0; +} + +static void tdm_enable(enum HAL_I2S_ID_T i2s_id,bool enable) +{ + volatile uint32_t *base_addr; + uint32_t val = 0; + + base_addr = (uint32_t*)_tdm_get_reg_base(i2s_id); + val = *base_addr; + + if(enable) + { + val |= (TDM_ENABLE << TDM_ENABLE_SHIFT); + } + else + { + val &= ~(TDM_ENABLE << TDM_ENABLE_SHIFT); + } + *base_addr = val; +} + +static int32_t tdm_open(enum HAL_I2S_ID_T i2s_id,enum AUD_STREAM_T stream,enum HAL_I2S_MODE_T mode) +{ + int ret; + struct HAL_TDM_CONFIG_T tdm_config; + + TDM_TRACE(4,"%s: i2s_id = %d, stream = %d, mode = %d.", __func__, i2s_id, stream, mode); + ret = hal_i2s_open(i2s_id, stream, mode); + if(ret) + { + TDM_TRACE(2,"%s: hal_i2s_open failed.ret = %d.", __func__, ret); + } + tdm_enable(i2s_id,false); + tdm_get_default_config(&tdm_config); + tdm_set_config(i2s_id, &tdm_config); + TDM_TRACE(1,"%s: done.",__func__); + return ret; +} + +static int32_t tdm_setup_stream(enum HAL_I2S_ID_T i2s_id, + enum AUD_STREAM_T stream, + uint32_t sample_rate, + struct HAL_TDM_CONFIG_T *tdm_cfg) +{ + struct HAL_I2S_CONFIG_T i2s_cfg; + uint32_t cycles; + const uint8_t bits = 16; + int ret; + + TDM_TRACE(4,"%s: i2s_id = %d, stream = %d, sample_rate = %d", + __func__, i2s_id, stream, sample_rate); + TDM_TRACE(5,"%s: tdm_cfg: mode = %d,edge = %d,cycles = %d,fs_cycles = %d," + "slot_cycles= %d, offs = %d.", + __func__, tdm_cfg->mode, tdm_cfg->edge, tdm_cfg->cycles, + tdm_cfg->fs_cycles,tdm_cfg->slot_cycles,tdm_cfg->data_offset); + cycles = tdm_cfg->cycles; + ASSERT(tdm_cycles_in_arrays(cycles), + "%s: cycles = %d error!",__func__, tdm_cfg->cycles); + memset(&i2s_cfg, 0, sizeof(i2s_cfg)); + i2s_cfg.use_dma = true; + i2s_cfg.sync_start = tdm_cfg->sync_start; + i2s_cfg.chan_sep_buf = false; + i2s_cfg.bits = bits; + i2s_cfg.channel_num = 2; + i2s_cfg.channel_map = AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1; + i2s_cfg.sample_rate = sample_rate*(cycles/bits)/2; + ret = hal_i2s_setup_stream(i2s_id, stream, &i2s_cfg); + if(ret) + { + TDM_TRACE(2,"%s: playback failed.ret = %d.", __func__, ret); + } + else + { + tdm_enable(i2s_id,false); + tdm_set_config(i2s_id,tdm_cfg); + } + + TDM_TRACE(1,"%s done.", __func__); + return ret; +} + +int32_t tdm_as_i2s_setup_stream(enum HAL_I2S_ID_T i2s_id, + enum AUD_STREAM_T stream, + uint32_t sample_rate) +{ + struct HAL_I2S_CONFIG_T i2s_cfg; + struct HAL_TDM_CONFIG_T tdm_cfg; + int ret; + + TDM_TRACE(4,"%s: i2s_id = %d, stream = %d, sample_rate = 0x%x.", + __func__, i2s_id, stream, sample_rate); + memset(&i2s_cfg, 0, sizeof(i2s_cfg)); + i2s_cfg.use_dma = true; + i2s_cfg.sync_start = stream == AUD_STREAM_PLAYBACK ? true : false; + i2s_cfg.chan_sep_buf = false; + i2s_cfg.bits = 16; + i2s_cfg.channel_num = 2; + i2s_cfg.channel_map = AUD_CHANNEL_MAP_CH0 | AUD_CHANNEL_MAP_CH1; + i2s_cfg.sample_rate = sample_rate; + ret = hal_i2s_setup_stream(i2s_id, stream, &i2s_cfg); + if(ret) + { + TDM_TRACE(2,"%s: playback failed.ret = %d.", __func__, ret); + } + else + { + tdm_enable(i2s_id,false); + tdm_get_i2s_config(&tdm_cfg); + tdm_set_config(i2s_id,&tdm_cfg); + } + + TDM_TRACE(1,"%s: done.", __func__); + return ret; +} + +static int32_t tdm_start_stream(enum HAL_I2S_ID_T i2s_id, enum AUD_STREAM_T stream) +{ + int ret; + + TDM_TRACE(3,"%s: i2s_id = %d, stream = %d.", __func__, i2s_id, stream); + tdm_enable(i2s_id,true); + ret = hal_i2s_start_stream(i2s_id, stream); + + TDM_TRACE(2,"%s done. ret = %d.", __func__, ret); + return ret; +} + +static int32_t tdm_stop_stream(enum HAL_I2S_ID_T i2s_id, enum AUD_STREAM_T stream) +{ + int ret; + + TDM_TRACE(3,"%s: i2s_id = %d, stream = %d.", __func__, i2s_id, stream); + tdm_enable(i2s_id,false); + + ret = hal_i2s_stop_stream(i2s_id,stream); + + TDM_TRACE(2,"%s done. ret = %d.", __func__, ret); + return ret; +} + +static int32_t tdm_close(enum HAL_I2S_ID_T i2s_id, enum AUD_STREAM_T stream) +{ + int ret; + + TDM_TRACE(3,"%s: i2s_id = %d, stream = %d.", __func__, i2s_id, stream); + tdm_enable(i2s_id,false); + + ret = hal_i2s_close(i2s_id,stream); + + TDM_TRACE(2,"%s done. ret = %d.", __func__, ret); + return ret; +} +#endif // CHIP_HAS_TDM + +int32_t hal_tdm_open(enum HAL_I2S_ID_T i2s_id,enum AUD_STREAM_T stream,enum HAL_I2S_MODE_T mode) +{ + int ret; + + TDM_TRACE(3,"hal_tdm_open:i2s_id = %d, stream = %d, mode = %d.", + i2s_id, stream, mode); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + + #ifdef CHIP_HAS_TDM + ret = tdm_open(i2s_id, stream, mode); + #else + ASSERT(stream == AUD_STREAM_CAPTURE, "stream = AUD_STREAM_PLAYBACK!"); + ret = hal_i2s_tdm_open(i2s_id, mode); + #endif + + TDM_TRACE(2,"%s done. ret = %d.", __func__, ret); + return ret; +} + +int32_t hal_tdm_setup_stream(enum HAL_I2S_ID_T i2s_id, + enum AUD_STREAM_T stream, + uint32_t sample_rate, + struct HAL_TDM_CONFIG_T *tdm_cfg) +{ + int ret; + + TDM_TRACE(4,"%s:i2s_id = %d, stream = %d, sample_rate = %d.", + __func__, i2s_id, stream, sample_rate); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + TDM_TRACE(4,"%s: cycles = %d, fs_cycles = %d,slot_cycles = %d.", + __func__, + tdm_cfg->cycles, + tdm_cfg->fs_cycles, + tdm_cfg->slot_cycles); + +#ifdef CHIP_HAS_TDM + ret = tdm_setup_stream(i2s_id, stream, sample_rate,tdm_cfg); +#else + struct HAL_I2S_TDM_CONFIG_T i2s_tdm_cfg; + + i2s_tdm_cfg.cycles = (enum HAL_I2S_TDM_CYCLES_T)tdm_cfg->cycles; + i2s_tdm_cfg.fs_cycles = (enum HAL_I2S_TDM_FS_CYCLES_T)tdm_cfg->fs_cycles; + i2s_tdm_cfg.slot_cycles = (enum HAL_I2S_TDM_SLOT_CYCLES_T)tdm_cfg->slot_cycles; + i2s_tdm_cfg.data_offset = tdm_cfg->data_offset; + ret = hal_i2s_tdm_setup(i2s_id, sample_rate, &i2s_tdm_cfg); +#endif + + TDM_TRACE(2,"%s done. ret = %d.", __func__, ret); + return ret; +} + +int32_t hal_tdm_as_i2s_setup_stream(enum HAL_I2S_ID_T i2s_id, + enum AUD_STREAM_T stream, + uint32_t sample_rate) +{ + int ret; + + TDM_TRACE(4,"%s: i2s_id = %d, stream = %d, sample_rate = %d.", + __func__, i2s_id, stream, sample_rate); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + + // i2s setup stream playback and capture. +#ifdef CHIP_HAS_TDM + ret = tdm_as_i2s_setup_stream(i2s_id, stream, sample_rate); +#else + struct HAL_I2S_TDM_CONFIG_T i2s_tdm_cfg={ + HAL_I2S_TDM_CYCLES_32, + HAL_I2S_TDM_FS_CYCLES_16, + HAL_I2S_TDM_SLOT_CYCLES_16,}; + ret = hal_i2s_tdm_setup(i2s_id, sample_rate, &i2s_tdm_cfg); +#endif + + TDM_TRACE(2,"%s done. ret = %d.", __func__, ret); + return ret; +} + +int32_t hal_tdm_start_stream(enum HAL_I2S_ID_T i2s_id, enum AUD_STREAM_T stream) +{ + int ret; + + TDM_TRACE(3,"%s: i2s_id = %d stream = %d.", + __func__, i2s_id, stream); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); + +#ifdef CHIP_HAS_TDM + ret = tdm_start_stream(i2s_id, stream); +#else + ret = hal_i2s_tdm_start_stream(i2s_id); +#endif + TDM_TRACE(2,"%s done. ret = %d.", __func__, ret); + return ret; +} + +int32_t hal_tdm_stop_stream(enum HAL_I2S_ID_T i2s_id, enum AUD_STREAM_T stream) +{ + int32_t ret; + + TDM_TRACE(3,"%s: i2s_id = %d stream = %d.", + __func__, i2s_id, stream); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); +#ifdef CHIP_HAS_TDM + ret = tdm_stop_stream(i2s_id, stream); +#else + ret = hal_i2s_tdm_stop_stream(i2s_id); +#endif + TDM_TRACE(2,"%s done. ret = %d.", __func__, ret); + return ret; +} + +int32_t hal_tdm_close(enum HAL_I2S_ID_T i2s_id, enum AUD_STREAM_T stream) +{ + int32_t ret; + + TDM_TRACE(3,"%s: i2s_id = %d stream = %d.", + __func__, i2s_id, stream); + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); +#ifdef CHIP_HAS_TDM + ret = tdm_close(i2s_id, stream); +#else + ret = hal_i2s_tdm_close(i2s_id); +#endif + TDM_TRACE(2,"%s done. ret = %d.", __func__, ret); + return ret; +} + +void hal_tdm_get_config(enum HAL_I2S_ID_T i2s_id,struct HAL_TDM_CONFIG_T *tdm_cfg) +{ + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); +#ifdef CHIP_HAS_TDM + tdm_get_config(i2s_id,tdm_cfg); +#else + struct HAL_I2S_TDM_CONFIG_T i2s_tdm_cfg; + hal_i2s_tdm_get_config(i2s_id, &i2s_tdm_cfg); + tdm_cfg->mode = HAL_TDM_MODE_FS_ASSERTED_AT_FIRST; + tdm_cfg->edge = HAL_TDM_FS_EDGE_POSEDGE; + tdm_cfg->cycles = (enum HAL_TDM_CYCLES_T)i2s_tdm_cfg.cycles; + tdm_cfg->fs_cycles = (enum HAL_TDM_FS_CYCLES)i2s_tdm_cfg.fs_cycles; + tdm_cfg->slot_cycles = (enum HAL_TDM_SLOT_CYCLES_T)i2s_tdm_cfg.slot_cycles; + tdm_cfg->data_offset = i2s_tdm_cfg.data_offset; +#endif +} + +void hal_tdm_set_config(enum HAL_I2S_ID_T i2s_id,struct HAL_TDM_CONFIG_T *tdm_cfg) +{ + ASSERT(i2s_id < HAL_I2S_ID_QTY,"%s: i2s_id = %d!", __func__, i2s_id); +#ifdef CHIP_HAS_TDM + tdm_set_config(i2s_id,tdm_cfg); +#else + struct HAL_I2S_TDM_CONFIG_T i2s_tdm_cfg; + i2s_tdm_cfg.cycles = HAL_I2S_TDM_CYCLES_32; + i2s_tdm_cfg.fs_cycles = HAL_I2S_TDM_FS_CYCLES_16; + i2s_tdm_cfg.slot_cycles = HAL_I2S_TDM_SLOT_CYCLES_16; + i2s_tdm_cfg.data_offset = 0; + hal_i2s_tdm_set_config(i2s_id, &i2s_tdm_cfg); +#endif +} + diff --git a/platform/hal/hal_tdm.h b/platform/hal/hal_tdm.h new file mode 100644 index 0000000..4ad0265 --- /dev/null +++ b/platform/hal/hal_tdm.h @@ -0,0 +1,98 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_TDM_H__ +#define __HAL_TDM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "reg_tdm.h" +#include "hal_i2s.h" + +#define TDM_BUF_ALIGN __attribute__((aligned(0x100))) + +enum HAL_TDM_ENABLE_T { + HAL_TDM_DISABLE, + HAL_TDM_ENABLE, + HAL_TDM_ENABLE_NUM, +}; + +enum HAL_TDM_MODE_T { + HAL_TDM_MODE_FS_ASSERTED_AT_FIRST, + HAL_TDM_MODE_FS_ASSERTED_AT_LAST, + HAL_TDM_MODE_NUM, +}; + +enum HAL_TDM_FS_EDGE_T { + HAL_TDM_FS_EDGE_POSEDGE, + HAL_TDM_FS_EDGE_NEGEDGE, + HAL_TDM_FS_EDGE_NUM, +}; + +enum HAL_TDM_CYCLES_T { + HAL_TDM_CYCLES_16 = 16, + HAL_TDM_CYCLES_32 = 32, + HAL_TDM_CYCLES_64 = 64, + HAL_TDM_CYCLES_128 = 128, + HAL_TDM_CYCLES_256 = 256, + HAL_TDM_CYCLES_512 = 512, +}; + +enum HAL_TDM_FS_CYCLES { + HAL_TDM_FS_CYCLES_ONE_LESS = 0, + HAL_TDM_FS_CYCLES_1 = 1, + HAL_TDM_FS_CYCLES_8 = 8, + HAL_TDM_FS_CYCLES_16 = 16, + HAL_TDM_FS_CYCLES_32 = 32, + HAL_TDM_FS_CYCLES_64 = 64, + HAL_TDM_FS_CYCLES_128 = 128, + HAL_TDM_FS_CYCLES_256 = 256, +}; + +enum HAL_TDM_SLOT_CYCLES_T { + HAL_TDM_SLOT_CYCLES_32 = 32, + HAL_TDM_SLOT_CYCLES_16 = 16, +}; + +struct HAL_TDM_CONFIG_T { + enum HAL_TDM_MODE_T mode; + enum HAL_TDM_FS_EDGE_T edge; + enum HAL_TDM_CYCLES_T cycles; + enum HAL_TDM_FS_CYCLES fs_cycles; + enum HAL_TDM_SLOT_CYCLES_T slot_cycles; + uint32_t data_offset; + bool sync_start; +}; + +int32_t hal_tdm_open(enum HAL_I2S_ID_T i2s_id,enum AUD_STREAM_T stream,enum HAL_I2S_MODE_T mode); +int32_t hal_tdm_setup_stream(enum HAL_I2S_ID_T i2s_id, + enum AUD_STREAM_T stream, + uint32_t sample_rate, + struct HAL_TDM_CONFIG_T *tdm_cfg); +int32_t hal_tdm_as_i2s_setup_stream(enum HAL_I2S_ID_T i2s_id, + enum AUD_STREAM_T stream, + uint32_t sample_rate); +int32_t hal_tdm_start_stream(enum HAL_I2S_ID_T i2s_id, enum AUD_STREAM_T stream); +int32_t hal_tdm_stop_stream(enum HAL_I2S_ID_T i2s_id, enum AUD_STREAM_T stream); +int32_t hal_tdm_close(enum HAL_I2S_ID_T i2s_id, enum AUD_STREAM_T stream); +void hal_tdm_get_config(enum HAL_I2S_ID_T i2s_id,struct HAL_TDM_CONFIG_T *tdm_cfg); +void hal_tdm_set_config(enum HAL_I2S_ID_T i2s_id,struct HAL_TDM_CONFIG_T *tdm_cfg); +#ifdef __cplusplus +} +#endif + +#endif // __HAL_TDM_H__ \ No newline at end of file diff --git a/platform/hal/hal_timer.c b/platform/hal/hal_timer.c new file mode 100644 index 0000000..440ed99 --- /dev/null +++ b/platform/hal/hal_timer.c @@ -0,0 +1,684 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include "hal_timer.h" +#define IGNORE_HAL_TIMER_RAW_API_CHECK +#include "hal_timer_raw.h" +#include "reg_timer.h" +#include "hal_location.h" +#include "hal_cmu.h" +#include "cmsis_nvic.h" + +//#define ELAPSED_TIMER_ENABLED + +#if defined(CHIP_BEST3001) || defined(CHIP_BEST3003) || defined(CHIP_BEST3005) || defined(CHIP_BEST1400) || defined(CHIP_BEST1402) +#define CLOCK_SYNC_WORKAROUND +#endif + +#ifdef LOW_SYS_FREQ +#if defined(CHIP_BEST1305) || defined(CHIP_BEST1501) || \ + defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) +#define FAST_TIMER_WORKAROUND +#endif +#endif + +#if defined(__FPU_USED) && (__FPU_USED == 1) +//#define TIMER_USE_FPU +#endif + +#define SLOW_TIMER_VAL_DELTA 1 +#define SLOW_TIMER_VAL_DELTA_SLEEP 10 +#define FAST_TIMER_VAL_DELTA 20 + +#ifdef CALIB_SLOW_TIMER +#define MAX_CALIB_SYSTICK_HZ (CONFIG_SYSTICK_HZ_NOMINAL * 2) + +#define MIN_CALIB_TICKS (10 * (CONFIG_SYSTICK_HZ_NOMINAL / 1000)) + +#define MAX_CALIB_TICKS (30 * CONFIG_SYSTICK_HZ_NOMINAL) + +static uint32_t BOOT_DATA_LOC sys_tick_hz = CONFIG_SYSTICK_HZ_NOMINAL; +static uint32_t BOOT_BSS_LOC slow_val; +static uint32_t BOOT_BSS_LOC fast_val; +#endif + +static struct DUAL_TIMER_T * const BOOT_RODATA_SRAM_LOC dual_timer0 = (struct DUAL_TIMER_T *)TIMER0_BASE; +#ifdef TIMER1_BASE +static struct DUAL_TIMER_T * const BOOT_RODATA_SRAM_LOC dual_timer1 = (struct DUAL_TIMER_T *)TIMER1_BASE; +#endif + +static HAL_TIMER_IRQ_HANDLER_T irq_handler = NULL; + +//static uint32_t load_value = 0; +static uint32_t start_time; + +static void POSSIBLY_UNUSED hal_timer00_irq_handler(void); +static void hal_timer01_irq_handler(void); + +__STATIC_FORCEINLINE uint32_t get_timer_value(struct TIMER_T *timer, uint32_t delta) +{ +#ifdef CLOCK_SYNC_WORKAROUND + uint32_t lock; + uint32_t v1, v2; + + lock = int_lock(); + do { + v1 = timer->Value; + v2 = timer->Value; + } while ((v1 < v2) || (v1 > v2 + delta)); + int_unlock(lock); + + return v2; +#else + return timer->Value; +#endif +} + +__STATIC_FORCEINLINE void clear_timer_irq(struct TIMER_T *timer) +{ +#ifdef CLOCK_SYNC_WORKAROUND + do { + timer->IntClr = 1; + } while (timer->RIS & TIMER_RIS_RIS); +#else + timer->IntClr = 1; +#endif +} + +__STATIC_FORCEINLINE void set_timer_load(struct TIMER_T *timer, uint32_t load, uint32_t delta) +{ +#ifdef CLOCK_SYNC_WORKAROUND + uint32_t lock; + uint32_t val; + + lock = int_lock(); + do { + timer->Load = load; + val = timer->Value; + } while ((load < val) || (load > val + delta)); + int_unlock(lock); +#else + timer->Load = load; +#endif +} + +__STATIC_FORCEINLINE void fast_timer_open(void) +{ +#ifdef TIMER1_BASE + hal_cmu_timer1_select_fast(); + dual_timer1->timer[0].Control = TIMER_CTRL_EN | TIMER_CTRL_PRESCALE_DIV_1 | TIMER_CTRL_SIZE_32_BIT; +#endif +} + +void BOOT_TEXT_FLASH_LOC hal_sys_timer_open(void) +{ + hal_cmu_timer0_select_slow(); + dual_timer0->timer[0].Control = TIMER_CTRL_EN | TIMER_CTRL_PRESCALE_DIV_1 | TIMER_CTRL_SIZE_32_BIT; + fast_timer_open();; +} + +#ifdef CORE_SLEEP_POWER_DOWN +void SRAM_TEXT_LOC hal_sys_timer_wakeup(void) +{ + fast_timer_open();; +} +#endif + +uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_get(void) +{ + return -get_timer_value(&dual_timer0->timer[0], SLOW_TIMER_VAL_DELTA); +} + +#ifdef CLOCK_SYNC_WORKAROUND +uint32_t SRAM_TEXT_LOC hal_sys_timer_get_in_sleep(void) +{ + return -get_timer_value(&dual_timer0->timer[0], SLOW_TIMER_VAL_DELTA_SLEEP); +} +#else +uint32_t hal_sys_timer_get_in_sleep(void) __attribute__((alias("hal_sys_timer_get"))); +#endif + +uint32_t BOOT_TEXT_FLASH_LOC flash_hal_sys_timer_get(void) +{ + return -get_timer_value(&dual_timer0->timer[0], SLOW_TIMER_VAL_DELTA); +} + +uint32_t BOOT_TEXT_SRAM_LOC hal_sys_ms_get(void) +{ + return GET_CURRENT_MS(); +} + +uint32_t BOOT_TEXT_SRAM_LOC hal_fast_sys_timer_get(void) +{ +#ifdef TIMER1_BASE +#ifdef FAST_TIMER_WORKAROUND + if (hal_cmu_fast_timer_offline()) { +#ifdef TIMER_USE_FPU + return (uint32_t)(hal_sys_timer_get() * ((float)CONFIG_FAST_SYSTICK_HZ / CONFIG_SYSTICK_HZ)); +#else + return (uint32_t)(hal_sys_timer_get() * (uint64_t)CONFIG_FAST_SYSTICK_HZ / CONFIG_SYSTICK_HZ); +#endif + } +#endif // FAST_TIMER_WORKAROUND + return -get_timer_value(&dual_timer1->timer[0], FAST_TIMER_VAL_DELTA); +#else + return 0; +#endif +} + +uint32_t hal_sys_timer_get_max(void) +{ + return 0xFFFFFFFF; +} + +void BOOT_TEXT_SRAM_LOC hal_sys_timer_delay(uint32_t ticks) +{ + uint32_t start = hal_sys_timer_get(); + + while (hal_sys_timer_get() - start < ticks); +} + +#ifdef CLOCK_SYNC_WORKAROUND +void SRAM_TEXT_LOC hal_sys_timer_delay_in_sleep(uint32_t ticks) +{ + uint32_t start = hal_sys_timer_get_in_sleep(); + + while (hal_sys_timer_get_in_sleep() - start < ticks); +} +#else +void hal_sys_timer_delay_in_sleep(uint32_t ticks) __attribute__((alias("hal_sys_timer_delay"))); +#endif + +void BOOT_TEXT_FLASH_LOC flash_hal_sys_timer_delay(uint32_t ticks) +{ + uint32_t start = flash_hal_sys_timer_get(); + + while (flash_hal_sys_timer_get() - start < ticks); +} + +void BOOT_TEXT_SRAM_LOC hal_sys_timer_delay_us(uint32_t us) +{ +#ifdef TIMER1_BASE +#ifdef FAST_TIMER_WORKAROUND + if (hal_cmu_fast_timer_offline()) { + uint32_t start = hal_sys_timer_get(); + uint32_t ticks = US_TO_TICKS(us); + + while (hal_sys_timer_get() - start < ticks); + } +#endif // FAST_TIMER_WORKAROUND + + uint32_t start = hal_fast_sys_timer_get(); + uint32_t ticks = US_TO_FAST_TICKS(us); + + while (hal_fast_sys_timer_get() - start < ticks); +#else + enum HAL_CMU_FREQ_T freq = hal_cmu_sys_get_freq(); + uint32_t loop; + uint32_t i; + + // Assuming: + // 1) system clock uses audio PLL + // 2) audio PLL is configured as 48K series, 196.608M + // 3) crystal is 26M + + if (freq == HAL_CMU_FREQ_208M) { + loop = 197; + } else if (freq == HAL_CMU_FREQ_104M) { + loop = 197 / 2; + } else if (freq == HAL_CMU_FREQ_78M) { + loop = 197 / 3; + } else if (freq == HAL_CMU_FREQ_52M) { + loop = 52; + } else { + loop = 26; + } + + loop = loop * us / 5; + for (i = 0; i < loop; i++) { + asm volatile("nop"); + } +#endif +} + +void SRAM_TEXT_LOC hal_sys_timer_delay_ns(uint32_t ns) +{ +#ifdef TIMER1_BASE +#ifdef FAST_TIMER_WORKAROUND + if (hal_cmu_fast_timer_offline()) { + uint32_t start = hal_sys_timer_get(); + uint32_t ticks = US_TO_TICKS((ns + (1000 - 1)) / 1000); + + while (hal_sys_timer_get() - start < ticks); + } +#endif // FAST_TIMER_WORKAROUND + + uint32_t start = hal_fast_sys_timer_get(); + uint32_t ticks = NS_TO_FAST_TICKS(ns); + + while (hal_fast_sys_timer_get() - start < ticks); +#else + enum HAL_CMU_FREQ_T freq = hal_cmu_sys_get_freq(); + uint32_t loop; + uint32_t i; + + // Assuming: + // 1) system clock uses audio PLL + // 2) audio PLL is configured as 48K series, 196.608M + // 3) crystal is 26M + + if (freq == HAL_CMU_FREQ_208M) { + loop = 197; + } else if (freq == HAL_CMU_FREQ_104M) { + loop = 197 / 2; + } else if (freq == HAL_CMU_FREQ_78M) { + loop = 197 / 3; + } else if (freq == HAL_CMU_FREQ_52M) { + loop = 52; + } else { + loop = 26; + } + + loop = loop * ns / 5000; + for (i = 0; i < loop; i++) { + asm volatile("nop"); + } +#endif +} + +static uint32_t NOINLINE SRAM_TEXT_DEF(measure_cpu_freq_interval)(uint32_t cnt) +{ + uint32_t start; + struct DUAL_TIMER_T *t; + uint32_t delta; + +#ifdef TIMER1_BASE + t = dual_timer1; + delta = FAST_TIMER_VAL_DELTA; +#ifdef FAST_TIMER_WORKAROUND + if (hal_cmu_fast_timer_offline()) { + t = dual_timer0; + delta = SLOW_TIMER_VAL_DELTA; + } +#endif // FAST_TIMER_WORKAROUND +#else + t = dual_timer0; + delta = SLOW_TIMER_VAL_DELTA; +#endif + + start = get_timer_value(&t->timer[0], delta); + + asm volatile( + "_loop:;" +#ifdef __ARM_ARCH_ISA_ARM + "nop;" + "nop;" +#endif + "subs %0, #1;" + "cmp %0, #0;" + "bne _loop;" + : : "r"(cnt)); + + return start - get_timer_value(&t->timer[0], delta); +} + +uint32_t hal_sys_timer_calc_cpu_freq(uint32_t interval_ms, int high_res) +{ + uint32_t ref_freq; + uint32_t cnt; + uint32_t one_sec; + uint32_t lock; + uint32_t run_interval; + uint32_t base_interval; + uint32_t freq; + + // Default measurement interval + if (interval_ms == 0) { +#ifdef TIMER1_BASE + interval_ms = 10; +#else + interval_ms = 100; +#endif + } + + ref_freq = hal_cmu_get_crystal_freq(); + // CPU loop cycle count + cnt = ref_freq / 4 * interval_ms / 1000; + + // Timer ticks per second +#ifdef TIMER1_BASE + one_sec = CONFIG_FAST_SYSTICK_HZ; +#ifdef FAST_TIMER_WORKAROUND + if (hal_cmu_fast_timer_offline()) { + one_sec = CONFIG_SYSTICK_HZ; + } +#endif // FAST_TIMER_WORKAROUND +#else + if (high_res) { + one_sec = CONFIG_FAST_SYSTICK_HZ; + } else { + one_sec = CONFIG_SYSTICK_HZ; + } +#endif + // Timer ticks per measurement interval + base_interval = one_sec * interval_ms / 1000; + + lock = int_lock(); + +#ifndef TIMER1_BASE + if (high_res) { + hal_cmu_timer0_select_fast(); + } +#endif + + run_interval = measure_cpu_freq_interval(cnt); + +#ifndef TIMER1_BASE + if (high_res) { + hal_cmu_timer0_select_slow(); + } +#endif + + int_unlock(lock); + +#ifdef TIMER_USE_FPU + freq = (uint32_t)((float)ref_freq / run_interval * base_interval); +#else + freq = (uint32_t)((uint64_t)ref_freq * base_interval / run_interval); +#endif + + if (high_res == 0) { + freq = (freq + 500000) / 1000000 * 1000000; + } + + return freq; +} + +#ifdef CALIB_SLOW_TIMER +void hal_sys_timer_calib_start(void) +{ + uint32_t lock; + uint32_t slow; + uint32_t fast; + + lock = int_lock(); + slow = hal_sys_timer_get(); + while (hal_sys_timer_get() == slow); + fast = hal_fast_sys_timer_get(); + int_unlock(lock); + + slow_val = slow + 1; + fast_val = fast; +} + +int hal_sys_timer_calib_end(void) +{ + uint32_t lock; + uint32_t slow; + uint32_t fast; + uint32_t slow_diff; + + lock = int_lock(); + slow = hal_sys_timer_get(); + while (hal_sys_timer_get() == slow); + fast = hal_fast_sys_timer_get(); + int_unlock(lock); + + slow += 1; + slow_diff = slow - slow_val; + + // Avoid computation error + if (slow_diff < MIN_CALIB_TICKS) { + return 1; + } + // Avoid fast tick overflow + if (slow_diff > MAX_CALIB_TICKS) { + return 2; + } + +#ifdef TIMER_USE_FPU + sys_tick_hz = (uint32_t)((float)CONFIG_FAST_SYSTICK_HZ / (fast - fast_val) * slow_diff); +#else + uint64_t mul; + + mul = (uint64_t)CONFIG_FAST_SYSTICK_HZ * slow_diff; + if ((mul >> 32) == 0) { + sys_tick_hz = (uint32_t)mul / (fast - fast_val); + } else { + sys_tick_hz = mul / (fast - fast_val); + } +#endif + + if (sys_tick_hz > MAX_CALIB_SYSTICK_HZ) { + sys_tick_hz = MAX_CALIB_SYSTICK_HZ; + } + + return 0; +} + +void hal_sys_timer_calib(void) +{ + hal_sys_timer_calib_start(); + hal_sys_timer_delay(MIN_CALIB_TICKS); + hal_sys_timer_calib_end(); +} + +uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_systick_hz(void) +{ + return sys_tick_hz; +} + +uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_ms_to_ticks(uint32_t ms) +{ + if (ms <= (~0UL / MAX_CALIB_SYSTICK_HZ)) { + return (ms * sys_tick_hz / 1000); + } else { +#ifdef TIMER_USE_FPU + return (uint32_t)((float)ms / 1000 * sys_tick_hz); +#else + return ((uint64_t)ms * sys_tick_hz / 1000); +#endif + } +} + +uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_us_to_ticks(uint32_t us) +{ + if (us <= (~0UL / MAX_CALIB_SYSTICK_HZ)) { + return ((us * sys_tick_hz / 1000 + 1000 - 1) / 1000 + 1); + } else { +#ifdef TIMER_USE_FPU + return (uint32_t)((float)us / (1000 * 1000) * sys_tick_hz + 1 + 1); +#else + return (((uint64_t)us * sys_tick_hz / 1000 + 1000 - 1) / 1000 + 1); +#endif + } +} + +uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_ticks_to_ms(uint32_t tick) +{ + if (tick <= (~0UL / 1000)) { + return tick * 1000 / CONFIG_SYSTICK_HZ; + } else { +#ifdef TIMER_USE_FPU + return (uint32_t)((float)tick / CONFIG_SYSTICK_HZ * 1000); +#else + return (uint64_t)tick * 1000 / CONFIG_SYSTICK_HZ; +#endif + } +} + +uint32_t BOOT_TEXT_SRAM_LOC hal_sys_timer_ticks_to_us(uint32_t tick) +{ + if (tick <= (~0UL / (1000 * 1000))) { + return tick * (1000 * 1000) / CONFIG_SYSTICK_HZ; + } else { +#ifdef TIMER_USE_FPU + return (uint32_t)((float)tick / CONFIG_SYSTICK_HZ * (1000 * 1000)); +#else + return (uint64_t)tick * (1000 * 1000) / CONFIG_SYSTICK_HZ; +#endif + } +} +#endif + +#ifndef RTOS +int osDelay(uint32_t ms) +{ + hal_sys_timer_delay(MS_TO_TICKS(ms)); + return 0; +} +#endif + +static void hal_timer00_irq_handler(void) +{ + clear_timer_irq(&dual_timer0->timer[0]); + dual_timer0->timer[0].Control &= ~TIMER_CTRL_INTEN; +} + +void hal_timer_setup(enum HAL_TIMER_TYPE_T type, HAL_TIMER_IRQ_HANDLER_T handler) +{ + uint32_t mode; + + if (type == HAL_TIMER_TYPE_ONESHOT) { + mode = TIMER_CTRL_ONESHOT; + } else if (type == HAL_TIMER_TYPE_PERIODIC) { + mode = TIMER_CTRL_MODE_PERIODIC; + } else { + mode = 0; + } + + irq_handler = handler; + + clear_timer_irq(&dual_timer0->timer[1]); +#ifdef ELAPSED_TIMER_ENABLED + dual_timer0->elapsed_timer[1].ElapsedCtrl = TIMER_ELAPSED_CTRL_CLR; +#endif + + if (handler) { + NVIC_SetVector(TIMER01_IRQn, (uint32_t)hal_timer01_irq_handler); + NVIC_SetPriority(TIMER01_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(TIMER01_IRQn); + NVIC_EnableIRQ(TIMER01_IRQn); + } + + dual_timer0->timer[1].Control = mode | + (handler ? TIMER_CTRL_INTEN : 0) | + TIMER_CTRL_PRESCALE_DIV_1 | + TIMER_CTRL_SIZE_32_BIT; +} + +void hal_timer_start(uint32_t load) +{ + start_time = hal_sys_timer_get(); + hal_timer_reload(load); + hal_timer_continue(); +} + +void hal_timer_stop(void) +{ + dual_timer0->timer[1].Control &= ~TIMER_CTRL_EN; +#ifdef ELAPSED_TIMER_ENABLED + dual_timer0->elapsed_timer[1].ElapsedCtrl = TIMER_ELAPSED_CTRL_CLR; +#endif + clear_timer_irq(&dual_timer0->timer[1]); + NVIC_ClearPendingIRQ(TIMER01_IRQn); +} + +void hal_timer_continue(void) +{ +#ifdef ELAPSED_TIMER_ENABLED + dual_timer0->elapsed_timer[1].ElapsedCtrl = TIMER_ELAPSED_CTRL_EN | TIMER_ELAPSED_CTRL_CLR; +#endif + dual_timer0->timer[1].Control |= TIMER_CTRL_EN; +} + +int hal_timer_is_enabled(void) +{ + return !!(dual_timer0->timer[1].Control & TIMER_CTRL_EN); +} + +void hal_timer_reload(uint32_t load) +{ + if (load > HAL_TIMER_LOAD_DELTA) { + //load_value = load; + load -= HAL_TIMER_LOAD_DELTA; + } else { + //load_value = HAL_TIMER_LOAD_DELTA + 1; + load = 1; + } + set_timer_load(&dual_timer0->timer[1], load, SLOW_TIMER_VAL_DELTA); +} + +uint32_t hal_timer_get(void) +{ + return get_timer_value(&dual_timer0->timer[1], SLOW_TIMER_VAL_DELTA); +} + +int hal_timer_irq_active(void) +{ + return NVIC_GetActive(TIMER01_IRQn); +} + +int hal_timer_irq_pending(void) +{ + // Or NVIC_GetPendingIRQ(TIMER2_IRQn) ? + return (dual_timer0->timer[1].MIS & TIMER_MIS_MIS); +} + +uint32_t hal_timer_get_overrun_time(void) +{ +#ifdef ELAPSED_TIMER_ENABLED + uint32_t extra; + + if (dual_timer0->elapsed_timer[1].ElapsedCtrl & TIMER_ELAPSED_CTRL_EN) { + extra = dual_timer0->elapsed_timer[1].ElapsedVal; + } else { + extra = 0; + } + + return extra; +#else + return 0; +#endif +} + +uint32_t hal_timer_get_elapsed_time(void) +{ + //return load_value + hal_timer_get_overrun_time(); + return hal_sys_timer_get() - start_time; +} + +static void hal_timer01_irq_handler(void) +{ + uint32_t elapsed; + + clear_timer_irq(&dual_timer0->timer[1]); + if (irq_handler) { + elapsed = hal_timer_get_elapsed_time(); + irq_handler(elapsed); + } else { + dual_timer0->timer[1].Control &= ~TIMER_CTRL_INTEN; + } +} + +uint32_t hal_timer_get_passed_ticks(uint32_t curr_ticks, uint32_t prev_ticks) +{ + if(curr_ticks < prev_ticks) + return ((0xffffffff - prev_ticks + 1) + curr_ticks); + else + return (curr_ticks - prev_ticks); +} + diff --git a/platform/hal/hal_timer.h b/platform/hal/hal_timer.h new file mode 100644 index 0000000..8f038cc --- /dev/null +++ b/platform/hal/hal_timer.h @@ -0,0 +1,166 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_TIMER_H__ +#define __HAL_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_cmu.h" + +//============================================================================= +// Slow Timer (Default Timer) + +#ifdef FPGA +#define CONFIG_SYSTICK_HZ_NOMINAL (32000) +#else +#define CONFIG_SYSTICK_HZ_NOMINAL (16000) +#endif + +//#if (CONFIG_SYSTICK_HZ_NOMINAL % 1000) +//#error "Bad CONFIG_SYSTICK_HZ_NOMINAL configuration" +//#endif + +#ifdef CALIB_SLOW_TIMER + +#define CONFIG_SYSTICK_HZ hal_sys_timer_systick_hz() + +#define __MS_TO_TICKS(ms) hal_sys_timer_ms_to_ticks(ms) + +#define __US_TO_TICKS(us) hal_sys_timer_us_to_ticks(us) + +#define __TICKS_TO_MS(tick) hal_sys_timer_ticks_to_ms(tick) + +#define __TICKS_TO_US(tick) hal_sys_timer_ticks_to_us(tick) + +#else + +#define CONFIG_SYSTICK_HZ CONFIG_SYSTICK_HZ_NOMINAL + +#define __MS_TO_TICKS(ms) ((ms) * ((uint32_t)CONFIG_SYSTICK_HZ / 1000)) + +#define __US_TO_TICKS(us) (((us) * ((uint32_t)CONFIG_SYSTICK_HZ / 1000) + 1000 - 1) / 1000 + 1) + +#define __TICKS_TO_MS(tick) ((tick) / ((uint32_t)CONFIG_SYSTICK_HZ / 1000)) + +#define __TICKS_TO_US(tick) ((tick) * 1000 / ((uint32_t)CONFIG_SYSTICK_HZ / 1000)) + +#endif + +/* + * + * This is very confused with the common sense, because + * MS_TO_TICKS is always refer to ms converted to os ticks + * but here it is converted to a hardware timer's tick + * which ticks is 16K one second; + * + * The same is as US_TO_TICKS, TICKS_TO_MS series; + * They are reserved for historic reason; + * + * Note, don't use these macros, use MS_TO_HWTICKS/US_TO_HWTICKS/HWTICKS_TO_MS + * alternately + */ +#define MS_TO_TICKS(ms) __MS_TO_TICKS(ms) + +#define US_TO_TICKS(us) __US_TO_TICKS(us) + +#define TICKS_TO_MS(tick) __TICKS_TO_MS(tick) + +#define TICKS_TO_US(tick) __TICKS_TO_US(tick) + +#define MS_TO_HWTICKS(ms) __MS_TO_TICKS(ms) + +#define US_TO_HWTICKS(us) __US_TO_TICKS(us) + +#define HWTICKS_TO_MS(tick) __TICKS_TO_MS(tick) + +#define HWTICKS_TO_US(tick) __TICKS_TO_US(tick) + +#define GET_CURRENT_TICKS() hal_sys_timer_get() + +#define GET_CURRENT_MS() TICKS_TO_MS(GET_CURRENT_TICKS()) + +void hal_sys_timer_open(void); + +uint32_t hal_sys_timer_get(void); + +uint32_t hal_sys_timer_get_in_sleep(void); + +uint32_t hal_sys_timer_get_max(void); + +void hal_sys_timer_delay(uint32_t ticks); + +void hal_sys_timer_delay_in_sleep(uint32_t ticks); + +void hal_sys_timer_delay_us(uint32_t us); + +void hal_sys_timer_delay_ns(uint32_t ns); + +uint32_t hal_sys_timer_calc_cpu_freq(uint32_t interval_ms, int high_res); + +uint32_t flash_hal_sys_timer_get(void); + +void flash_hal_sys_timer_delay(uint32_t ticks); + +void hal_sys_timer_calib_start(void); + +int hal_sys_timer_calib_end(void); + +void hal_sys_timer_calib(void); + +uint32_t hal_sys_timer_systick_hz(void); + +uint32_t hal_sys_timer_ms_to_ticks(uint32_t ms); + +uint32_t hal_sys_timer_us_to_ticks(uint32_t us); + +uint32_t hal_sys_timer_ticks_to_ms(uint32_t tick); + +uint32_t hal_sys_timer_ticks_to_us(uint32_t tick); + +uint32_t hal_timer_get_passed_ticks(uint32_t curr_ticks, uint32_t prev_ticks); + +//============================================================================= +// Fast Timer + +#define CONFIG_FAST_SYSTICK_HZ (hal_cmu_get_crystal_freq() / 4) + +#define MS_TO_FAST_TICKS(ms) ((uint32_t)(ms) * (CONFIG_FAST_SYSTICK_HZ / 1000)) + +#define US_TO_FAST_TICKS(us) ((uint32_t)(us) * (CONFIG_FAST_SYSTICK_HZ / 1000 / 100) / 10) + +#define NS_TO_FAST_TICKS(ns) ((uint32_t)(ns) * (CONFIG_FAST_SYSTICK_HZ / 1000 / 100) / 10 / 1000) + +#define FAST_TICKS_TO_MS(tick) ((uint32_t)(tick) / (CONFIG_FAST_SYSTICK_HZ / 1000)) + +#define FAST_TICKS_TO_US(tick) ((uint32_t)(tick) * 10 / (CONFIG_FAST_SYSTICK_HZ / 1000 / 100)) + +#define FAST_TICKS_TO_NS(tick) ((uint32_t)(tick) * 10 * 1000 / (CONFIG_FAST_SYSTICK_HZ / 1000 / 100)) + +uint32_t hal_fast_sys_timer_get(void); + +#ifndef RTOS +int osDelay(uint32_t ms); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_timer_raw.h b/platform/hal/hal_timer_raw.h new file mode 100644 index 0000000..57f29ac --- /dev/null +++ b/platform/hal/hal_timer_raw.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_TIMER_RAW_H__ +#define __HAL_TIMER_RAW_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef IGNORE_HAL_TIMER_RAW_API_CHECK +#if !(defined(ROM_BUILD) || defined(SIMU)) +#error "Raw timer API can only be used in rom or simulation environment!" +#endif +#endif + +#include "hal_timer.h" + +#define HAL_TIMER_LOAD_DELTA 1 + +enum HAL_TIMER_TYPE_T { + HAL_TIMER_TYPE_FREERUNNING = 0, + HAL_TIMER_TYPE_ONESHOT, + HAL_TIMER_TYPE_PERIODIC, + HAL_TIMER_TYPE_QTY +}; + +typedef void (*HAL_TIMER_IRQ_HANDLER_T)(uint32_t elapsed); + +void hal_timer_setup(enum HAL_TIMER_TYPE_T type, HAL_TIMER_IRQ_HANDLER_T handler); + +void hal_timer_start(uint32_t load); + +void hal_timer_stop(void); + +void hal_timer_continue(void); + +int hal_timer_is_enabled(void); + +void hal_timer_reload(uint32_t load); + +uint32_t hal_timer_get(void); + +uint32_t hal_timer_get_overrun_time(void); + +int hal_timer_irq_active(void); + +int hal_timer_irq_pending(void); + +uint32_t hal_timer_get_elapsed_time(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_trace.c b/platform/hal/hal_trace.c new file mode 100644 index 0000000..bbcbe90 --- /dev/null +++ b/platform/hal/hal_trace.c @@ -0,0 +1,2801 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if !(defined(DEBUG) || defined(REL_TRACE_ENABLE)) +// Implement a local copy of dummy trace functions for library linking (which might be built with DEBUG enabled) +#define TRACE_FUNC_SPEC +#endif +#include "hal_trace.h" +#include "cmsis_nvic.h" +#ifdef RTOS +#include "cmsis_os.h" +#endif +#include "hal_cmu.h" +#include "hal_chipid.h" +#include "hal_codec.h" +#include "hal_dma.h" +#include "hal_iomux.h" +#include "hal_location.h" +#include "hal_memsc.h" +#include "hal_sysfreq.h" +#include "hal_timer.h" +#include "hal_uart.h" +#include "stdarg.h" +#include "stdio.h" +#include "string.h" +#include "hal_bootmode.h" + +#ifdef CORE_DUMP +#include "CrashCatcherApi.h" +#endif + +extern const char sys_build_info[]; +extern void nv_record_flash_flush(void); + +#ifdef FAULT_DUMP +void hal_trace_fault_dump(const uint32_t *regs, const uint32_t *extra, uint32_t extra_len); +#ifndef __ARM_ARCH_ISA_ARM +static void hal_trace_fault_handler(void); +#endif +#endif + +#if !(defined(ROM_BUILD) || defined(PROGRAMMER)) +#define ASSERT_MUTE_CODEC +#define CRASH_DUMP_ENABLE +#if !(defined(NO_TRACE_TIME_STAMP) || defined(AUDIO_DEBUG_V0_1_0)) +#define TRACE_TIME_STAMP +#endif +#if (defined(DUMP_LOG_ENABLE) || defined(DUMP_CRASH_ENABLE)) +#define TRACE_TO_APP +#endif +#ifdef CHIP_HAS_CP +#define CP_TRACE_ENABLE +#endif +#endif + +#define TRACE_IDLE_OUTPUT 0 + +#ifndef TRACE_BAUD_RATE +#define TRACE_BAUD_RATE (921600) +#endif + +#ifndef TRACE_BUF_SIZE +#ifdef AUDIO_DEBUG +#define TRACE_BUF_SIZE (6 * 1024) +#else +#define TRACE_BUF_SIZE (4 * 1024) +#endif +#endif + +#define CRASH_BUF_SIZE 100 +#define CRASH_BUF_ATTR ALIGNED(4) USED + +#ifndef TRACE_STACK_DUMP_PREV_WORD +#define TRACE_STACK_DUMP_PREV_WORD 16 +#endif +#ifndef TRACE_STACK_DUMP_WORD +#define TRACE_STACK_DUMP_WORD 32 +#endif +#ifndef TRACE_BACKTRACE_NUM +#define TRACE_BACKTRACE_NUM 20 +#endif +#ifndef TRACE_BACKTRACE_SEARCH_WORD +#define TRACE_BACKTRACE_SEARCH_WORD 1024 +#endif + +#define STACK_DUMP_CNT_PER_LEN 4 +#define STACK_DUMP_CNT_PREV ((TRACE_STACK_DUMP_PREV_WORD + STACK_DUMP_CNT_PER_LEN - 1) / STACK_DUMP_CNT_PER_LEN * STACK_DUMP_CNT_PER_LEN) +#define STACK_DUMP_CNT ((TRACE_STACK_DUMP_WORD + STACK_DUMP_CNT_PER_LEN - 1) / STACK_DUMP_CNT_PER_LEN * STACK_DUMP_CNT_PER_LEN) + +#define TRACE_FLUSH_TIMEOUT MS_TO_TICKS(2000) + +#define TRACE_NEAR_FULL_THRESH 200 + +#ifdef TRACE_CRLF +#define NEW_LINE_STR "\r\n" +#else +#define NEW_LINE_STR "\n" +#endif + +#define HAL_TRACE_ASSERT_ID 0xBE57AAAA +#define HAL_TRACE_EXCEPTION_ID 0xBE57EEEE + +#define HAL_MEMSC_ID_TRACE HAL_MEMSC_ID_0 + +#define TRACE_BUF_LOC SYNC_FLAGS_LOC + +struct ASSERT_INFO_T { + uint32_t ID; + uint32_t CPU_ID; + const char *FILE; + const char *FUNC; + uint32_t LINE; + const char *FMT; + uint32_t R[15]; +#ifndef __ARM_ARCH_ISA_ARM + uint32_t MSP; + uint32_t PSP; + uint32_t CONTROL; +#ifdef __ARM_ARCH_8M_MAIN__ + uint32_t MSPLIM; + uint32_t PSPLIM; +#endif +#endif +}; + +struct EXCEPTION_INFO_T { + uint32_t ID; + uint32_t CPU_ID; + const uint32_t *REGS; +#ifdef __ARM_ARCH_ISA_ARM + const uint32_t *extra; + uint32_t extra_len; +#else + uint32_t MSP; + uint32_t PSP; + uint8_t PRIMASK; + uint8_t FAULTMASK; + uint8_t BASEPRI; + uint8_t CONTROL; + uint32_t ICSR; + uint32_t AIRCR; + uint32_t SCR; + uint32_t CCR; + uint32_t SHCSR; + uint32_t CFSR; + uint32_t HFSR; + uint32_t AFSR; + uint32_t MMFAR; + uint32_t BFAR; +#ifdef __ARM_ARCH_8M_MAIN__ + uint32_t MSPLIM; + uint32_t PSPLIM; +#endif +#endif +}; + +static CRASH_BUF_ATTR char crash_buf[CRASH_BUF_SIZE]; + +STATIC_ASSERT(sizeof(crash_buf) >= sizeof(((struct ASSERT_INFO_T *)0)->R), "crash_buf too small to hold assert registers"); + +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) + +struct HAL_TRACE_BUF_T { + unsigned char buf[TRACE_BUF_SIZE]; + unsigned short wptr; + unsigned short rptr; +#if (TRACE_IDLE_OUTPUT == 0) + unsigned short sends[2]; +#endif + unsigned short discards; + bool sending; + bool in_trace; + bool wrapped; +}; + +STATIC_ASSERT(TRACE_BUF_SIZE < (1 << (8 * sizeof(((struct HAL_TRACE_BUF_T *)0)->wptr))), "TRACE_BUF_SIZE is too large to fit in wptr/rptr variable"); + +static const struct HAL_UART_CFG_T uart_cfg = { + .parity = HAL_UART_PARITY_NONE, + .stop = HAL_UART_STOP_BITS_1, + .data = HAL_UART_DATA_BITS_8, + .flow = HAL_UART_FLOW_CONTROL_NONE,//HAL_UART_FLOW_CONTROL_RTSCTS, + .tx_level = HAL_UART_FIFO_LEVEL_1_2, + .rx_level = HAL_UART_FIFO_LEVEL_1_2, + .baud = TRACE_BAUD_RATE, +#ifdef HAL_TRACE_RX_ENABLE + .dma_rx = true, +#else + .dma_rx = false, +#endif +#if (TRACE_IDLE_OUTPUT == 0) + .dma_tx = true, +#else + .dma_tx = false, +#endif + .dma_rx_stop_on_err = false, +}; + +#if (TRACE_IDLE_OUTPUT == 0) +static const enum HAL_DMA_PERIPH_T uart_periph[] = { + HAL_GPDMA_UART0_TX, +#if (CHIP_HAS_UART > 1) + HAL_GPDMA_UART1_TX, +#endif +#if (CHIP_HAS_UART > 2) + HAL_GPDMA_UART2_TX, +#endif +}; + +static const struct HAL_UART_CFG_T uart_rx_enable_cfg = { + .parity = HAL_UART_PARITY_NONE, + .stop = HAL_UART_STOP_BITS_1, + .data = HAL_UART_DATA_BITS_8, + .flow = HAL_UART_FLOW_CONTROL_NONE,//HAL_UART_FLOW_CONTROL_RTSCTS, + .tx_level = HAL_UART_FIFO_LEVEL_1_2, + .rx_level = HAL_UART_FIFO_LEVEL_1_2, + .baud = TRACE_BAUD_RATE, + .dma_rx = true, + +#if (TRACE_IDLE_OUTPUT == 0) + .dma_tx = true, +#else + .dma_tx = false, +#endif + .dma_rx_stop_on_err = false, +}; + +static struct HAL_DMA_CH_CFG_T dma_cfg; +TRACE_BUF_LOC static struct HAL_DMA_DESC_T dma_desc[2]; +#endif + +static enum HAL_TRACE_TRANSPORT_T trace_transport = HAL_TRACE_TRANSPORT_QTY; +static enum HAL_UART_ID_T trace_uart; + +TRACE_BUF_LOC +static struct HAL_TRACE_BUF_T trace; + +POSSIBLY_UNUSED +static const char newline[] = NEW_LINE_STR; + +static const char discards_prefix[] = NEW_LINE_STR "LOST "; +static const uint32_t max_discards = 99999; +// 5 digits + "\r\n" = 7 chars +static char discards_buf[sizeof(discards_prefix) - 1 + 7]; +static const unsigned char discards_digit_start = sizeof(discards_prefix) - 1; + +static bool crash_dump_onprocess = false; + +#ifdef CRASH_DUMP_ENABLE +static HAL_TRACE_CRASH_DUMP_CB_T crash_dump_cb_list[HAL_TRACE_CRASH_DUMP_MODULE_END]; +static bool crash_handling; +#ifdef TRACE_TO_APP +static HAL_TRACE_APP_NOTIFY_T app_notify_cb = NULL; +static HAL_TRACE_APP_OUTPUT_T app_output_cb = NULL; +static HAL_TRACE_APP_OUTPUT_T app_crash_custom_cb = NULL; +static bool app_output_enabled = +#if defined(DUMP_LOG_ENABLE) + true; +#else + false; +#endif +#endif // TRACE_TO_APP +#endif // CRASH_DUMP_ENABLE +#ifdef CP_TRACE_ENABLE +static HAL_TRACE_APP_NOTIFY_T cp_notify_cb = NULL; +static HAL_TRACE_BUF_CTRL_T cp_buffer_cb = NULL; +#endif + +#ifdef AUDIO_DEBUG_V0_1_0 +static const char trace_head_buf[] = "[trace]"; +#endif + +static enum LOG_LEVEL_T trace_max_level; +static uint32_t trace_mod_map[(LOG_MODULE_QTY + 31) / 32]; + +static bool hal_trace_is_uart_transport(enum HAL_TRACE_TRANSPORT_T transport) +{ + if (transport == HAL_TRACE_TRANSPORT_UART0 +#if (CHIP_HAS_UART > 1) + || transport == HAL_TRACE_TRANSPORT_UART1 +#endif +#if (CHIP_HAS_UART > 2) + || transport == HAL_TRACE_TRANSPORT_UART2 +#endif + ) { + return true; + } + return false; +} + +#if (TRACE_IDLE_OUTPUT == 0) + +static void hal_trace_uart_send(void) +{ + uint32_t wptr, rptr; + uint32_t sends[2]; + uint32_t lock; + + lock = int_lock(); + + wptr = trace.wptr; + rptr = trace.rptr; + + // There is a race condition if we do not check s/w flag, but only check the h/w status. + // [e.g., hal_gpdma_chan_busy(dma_cfg.ch)] + // When the DMA is done, but DMA IRQ handler is still pending due to interrupt lock + // or higher priority IRQ, it will have a chance to send the same content twice. + if (!trace.sending && wptr != rptr) { + trace.sending = true; + + sends[1] = 0; + if (wptr > rptr) { + sends[0] = wptr - rptr; + } else { + sends[0] = TRACE_BUF_SIZE - rptr; + if (sends[0] <= HAL_DMA_MAX_DESC_XFER_SIZE) { + sends[1] = wptr; + } + } + if (sends[0] > HAL_DMA_MAX_DESC_XFER_SIZE) { + sends[1] = sends[0] - HAL_DMA_MAX_DESC_XFER_SIZE; + sends[0] = HAL_DMA_MAX_DESC_XFER_SIZE; + } + if (sends[1] > HAL_DMA_MAX_DESC_XFER_SIZE) { + sends[1] = HAL_DMA_MAX_DESC_XFER_SIZE; + } + + dma_cfg.src = (uint32_t)&trace.buf[rptr]; + if (sends[1] == 0) { + dma_cfg.src_tsize = sends[0]; + hal_gpdma_init_desc(&dma_desc[0], &dma_cfg, NULL, 1); + } else { + dma_cfg.src_tsize = sends[0]; + hal_gpdma_init_desc(&dma_desc[0], &dma_cfg, &dma_desc[1], 0); + + if (rptr + sends[0] < TRACE_BUF_SIZE) { + dma_cfg.src = (uint32_t)&trace.buf[rptr + sends[0]]; + } else { + dma_cfg.src = (uint32_t)&trace.buf[0]; + } + dma_cfg.src_tsize = sends[1]; + hal_gpdma_init_desc(&dma_desc[1], &dma_cfg, NULL, 1); + } + trace.sends[0] = sends[0]; + trace.sends[1] = sends[1]; + + hal_gpdma_sg_start(&dma_desc[0], &dma_cfg); + } + + int_unlock(lock); +} + +static void hal_trace_uart_xfer_done(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + uint32_t sends[2]; + uint32_t lock; + + lock = int_lock(); + + sends[0] = trace.sends[0]; + sends[1] = trace.sends[1]; + + if (error) { + if (lli || sends[1] == 0) { + if (sends[0] > remain_tsize) { + sends[0] -= remain_tsize; + } else { + sends[0] = 0; + } + sends[1] = 0; + } else { + if (sends[1] > remain_tsize) { + sends[1] -= remain_tsize; + } else { + sends[1] = 0; + } + } + } + + trace.rptr += sends[0] + sends[1]; + if (trace.rptr >= TRACE_BUF_SIZE) { + trace.rptr -= TRACE_BUF_SIZE; + } + trace.sends[0] = 0; + trace.sends[1] = 0; + trace.sending = false; + + hal_trace_uart_send(); + + int_unlock(lock); +} + +static void hal_trace_send(void) +{ +#ifdef CP_TRACE_ENABLE + if (get_cpu_id()) { + return; + } +#endif + + if (hal_trace_is_uart_transport(trace_transport)) { + hal_trace_uart_send(); + } +} + +#else // TRACE_IDLE_OUTPUT + +static void hal_trace_uart_idle_send(void) +{ + int i; + uint32_t lock; + unsigned short wptr, rptr; + + lock = int_lock(); + wptr = trace.wptr; + rptr = trace.rptr; + int_unlock(lock); + + if (wptr == rptr) { + return; + } + + if (wptr < rptr) { + for (i = rptr; i < TRACE_BUF_SIZE; i++) { + hal_uart_blocked_putc(trace_uart, trace.buf[i]); + } + rptr = 0; + } + + for (i = rptr; i < wptr; i++) { + hal_uart_blocked_putc(trace_uart, trace.buf[i]); + } + + trace.rptr = wptr; + if (trace.rptr >= TRACE_BUF_SIZE) { + trace.rptr -= TRACE_BUF_SIZE; + } +} + +void hal_trace_idle_send(void) +{ + if (hal_trace_is_uart_transport(trace_transport)) { + hal_trace_uart_idle_send(); + } +} + +#endif // TRACE_IDLE_OUTPUT + +int hal_trace_open(enum HAL_TRACE_TRANSPORT_T transport) +{ + int ret; + + crash_dump_onprocess = false; + +#if (CHIP_HAS_UART > 1) +#ifdef FORCE_TRACE_UART1 + transport = HAL_TRACE_TRANSPORT_UART1; +#endif +#endif + +#if (CHIP_HAS_UART > 2) +#ifdef FORCE_TRACE_UART2 + transport = HAL_TRACE_TRANSPORT_UART2; +#endif +#endif + + if (transport >= HAL_TRACE_TRANSPORT_QTY) { + return 1; + } +#ifdef CHIP_HAS_USB + if (transport == HAL_TRACE_TRANSPORT_USB) { + return 1; + } +#endif + + if (trace_transport != HAL_TRACE_TRANSPORT_QTY) { + return hal_trace_switch(transport); + } + + trace_max_level = LOG_LEVEL_INFO; + for (int i = 0; i < ARRAY_SIZE(trace_mod_map); i++) { + trace_mod_map[i] = ~0; + } + + memcpy(discards_buf, discards_prefix, discards_digit_start); + + trace.wptr = 0; + trace.rptr = 0; + trace.discards = 0; + trace.sending = false; + trace.in_trace = false; + trace.wrapped = false; + + if (hal_trace_is_uart_transport(transport)) { + trace_uart = HAL_UART_ID_0 + (transport - HAL_TRACE_TRANSPORT_UART0); + ret = hal_uart_open(trace_uart, &uart_cfg); + if (ret) { + return ret; + } + +#if (TRACE_IDLE_OUTPUT == 0) + trace.sends[0] = 0; + trace.sends[1] = 0; + + memset(&dma_cfg, 0, sizeof(dma_cfg)); + dma_cfg.dst = 0; // useless + dma_cfg.dst_bsize = HAL_DMA_BSIZE_8; + dma_cfg.dst_periph = uart_periph[trace_uart - HAL_UART_ID_0]; + dma_cfg.dst_width = HAL_DMA_WIDTH_BYTE; + dma_cfg.handler = hal_trace_uart_xfer_done; + dma_cfg.src_bsize = HAL_DMA_BSIZE_32; + dma_cfg.src_periph = 0; // useless + dma_cfg.src_width = HAL_DMA_WIDTH_BYTE; + dma_cfg.type = HAL_DMA_FLOW_M2P_DMA; + dma_cfg.try_burst = 0; + dma_cfg.ch = hal_gpdma_get_chan(dma_cfg.dst_periph, HAL_DMA_HIGH_PRIO); + + ASSERT(dma_cfg.ch != HAL_DMA_CHAN_NONE, "Failed to get DMA channel"); +#endif + } + +#ifdef FAULT_DUMP +#ifdef __ARM_ARCH_ISA_ARM + GIC_SetFaultDumpHandler(hal_trace_fault_dump); +#else + NVIC_SetDefaultFaultHandler(hal_trace_fault_handler); +#endif +#endif + + trace_transport = transport; + +#ifdef HAL_TRACE_RX_ENABLE + hal_trace_rx_open(); +#endif + + // Show build info + static const char dbl_new_line[] = NEW_LINE_STR NEW_LINE_STR; + hal_trace_output((unsigned char *)dbl_new_line, sizeof(dbl_new_line)); + hal_trace_output((unsigned char *)sys_build_info, strlen(sys_build_info)+1); + + char buf[50]; + int len; + len = snprintf(buf, sizeof(buf), + NEW_LINE_STR NEW_LINE_STR "------" NEW_LINE_STR "METAL_ID: %d" NEW_LINE_STR "------" NEW_LINE_STR NEW_LINE_STR, + hal_get_chip_metal_id()); + hal_trace_output((unsigned char *)buf, len+1); + + return 0; +} + +int hal_trace_switch(enum HAL_TRACE_TRANSPORT_T transport) +{ + uint32_t POSSIBLY_UNUSED lock; + int ret; + +#if (CHIP_HAS_UART > 1) +#ifdef FORCE_TRACE_UART1 + transport = HAL_TRACE_TRANSPORT_UART1; +#endif +#endif + +#if (CHIP_HAS_UART > 2) +#ifdef FORCE_TRACE_UART2 + transport = HAL_TRACE_TRANSPORT_UART2; +#endif +#endif + +#ifdef CHIP_HAS_USB + if (transport == HAL_TRACE_TRANSPORT_USB) { + return 1; + } +#endif + if (transport >= HAL_TRACE_TRANSPORT_QTY) { + return 1; + } + if (trace_transport >= HAL_TRACE_TRANSPORT_QTY) { + return 1; + } + if (trace_transport == transport) { + return 0; + } + + ret = 0; + +#if (CHIP_HAS_UART > 1) + + lock = int_lock(); + + if (hal_trace_is_uart_transport(trace_transport)) { +#if (TRACE_IDLE_OUTPUT == 0) + if (dma_cfg.ch != HAL_DMA_CHAN_NONE) { + hal_gpdma_cancel(dma_cfg.ch); + } +#endif + hal_uart_close(trace_uart); + } + + if (hal_trace_is_uart_transport(transport)) { + trace_uart = HAL_UART_ID_0 + (transport - HAL_TRACE_TRANSPORT_UART0); +#if (TRACE_IDLE_OUTPUT == 0) + dma_cfg.dst_periph = uart_periph[trace_uart - HAL_UART_ID_0]; + trace.sends[0] = 0; + trace.sends[1] = 0; +#endif + ret = hal_uart_open(trace_uart, &uart_cfg); + if (ret) { +#if (TRACE_IDLE_OUTPUT == 0) + hal_gpdma_free_chan(dma_cfg.ch); + dma_cfg.ch = HAL_DMA_CHAN_NONE; +#endif + trace_transport = HAL_TRACE_TRANSPORT_QTY; + goto _exit; + } + } + + trace.sending = false; + + trace_transport = transport; + +_exit: + int_unlock(lock); + +#endif // CHIP_HAS_UART > 1 + + return ret; +} + +int hal_trace_close(void) +{ + if (trace_transport >= HAL_TRACE_TRANSPORT_QTY) { + goto _exit; + } +#ifdef CHIP_HAS_USB + if (trace_transport == HAL_TRACE_TRANSPORT_USB) { + goto _exit; + } +#endif + + if (hal_trace_is_uart_transport(trace_transport)) { +#if (TRACE_IDLE_OUTPUT == 0) + if (dma_cfg.ch != HAL_DMA_CHAN_NONE) { + hal_gpdma_cancel(dma_cfg.ch); + hal_gpdma_free_chan(dma_cfg.ch); + dma_cfg.ch = HAL_DMA_CHAN_NONE; + } +#endif + hal_uart_close(trace_uart); + } + +_exit: + trace_transport = HAL_TRACE_TRANSPORT_QTY; + + return 0; +} + +int hal_trace_enable_log_module(enum LOG_MODULE_T module) +{ + if (module >= LOG_MODULE_QTY) { + return 1; + } + + trace_mod_map[module >> 5] |= (1 << (module & 0x1F)); + return 0; +} + +int hal_trace_disable_log_module(enum LOG_MODULE_T module) +{ + if (module >= LOG_MODULE_QTY) { + return 1; + } + + trace_mod_map[module >> 5] &= ~(1 << (module & 0x1F)); + return 0; +} + +int hal_trace_set_log_module(const uint32_t *map, uint32_t word_cnt) +{ + if (map == NULL || word_cnt == 0) { + return 1; + } + + if (word_cnt > ARRAY_SIZE(trace_mod_map)) { + word_cnt = ARRAY_SIZE(trace_mod_map); + } + for (int i = 0; i < word_cnt; i++) { + trace_mod_map[i] = map[i]; + } + return 0; +} + +int hal_trace_set_log_level(enum LOG_LEVEL_T level) +{ + if (level >= LOG_LEVEL_QTY) { + return 1; + } + + trace_max_level = level; + return 0; +} + +void hal_trace_get_history_buffer(const unsigned char **buf1, unsigned int *len1, const unsigned char **buf2, unsigned int *len2) +{ + uint32_t lock; + uint8_t *b1, *b2; + uint32_t l1, l2; + + b1 = b2 = NULL; + l1 = l2 = 0; + + lock = int_lock(); + + if (TRACE_BUF_SIZE > trace.wptr) { + if (trace.wrapped) { + b1 = &trace.buf[trace.wptr]; + l1 = TRACE_BUF_SIZE - trace.wptr; + b2 = &trace.buf[0]; + l2 = trace.wptr; + } else { + b1 = &trace.buf[0]; + l1 = trace.wptr; + b2 = NULL; + l2 = 0; + } + } + + int_unlock(lock); + + if (buf1) { + *buf1 = b1; + } + if (len1) { + *len1 = l1; + } + if (buf2) { + *buf2 = b2; + } + if (len2) { + *len2 = l2; + } +} + +static void hal_trace_print_discards(uint32_t discards) +{ + static const uint8_t base = 10; + char digit[5], *d, *out; + uint16_t len; + uint16_t size; + + if (discards > max_discards) { + discards = max_discards; + } + + d = &digit[0]; + do { + *d++ = (discards % base) + '0'; + } while (discards /= base); + + out = &discards_buf[discards_digit_start]; + do { + *out++ = *--d; + } while (d > &digit[0]); +#ifdef TRACE_CRLF + *out++ = '\r'; +#endif + *out++ = '\n'; + len = out - &discards_buf[0]; + + size = TRACE_BUF_SIZE - trace.wptr; + if (size >= len) { + size = len; + } + memcpy(&trace.buf[trace.wptr], &discards_buf[0], size); + if (size < len) { + memcpy(&trace.buf[0], &discards_buf[size], len - size); + } + trace.wptr += len; + if (trace.wptr >= TRACE_BUF_SIZE) { + trace.wptr -= TRACE_BUF_SIZE; + } +} + +#ifdef AUDIO_DEBUG_V0_1_0 +static void hal_trace_print_head(void) +{ + uint16_t len; + uint16_t size; + + len = sizeof(trace_head_buf) - 1; + + size = TRACE_BUF_SIZE - trace.wptr; + if (size >= len) { + size = len; + } + memcpy(&trace.buf[trace.wptr], &trace_head_buf[0], size); + if (size < len) { + memcpy(&trace.buf[0], &trace_head_buf[size], len - size); + } + trace.wptr += len; + if (trace.wptr >= TRACE_BUF_SIZE) { + trace.wptr -= TRACE_BUF_SIZE; + } +} +#endif + +int hal_trace_output(const unsigned char *buf, unsigned int buf_len) +{ + int ret; + uint32_t lock; + uint32_t avail; + uint32_t out_len; + uint16_t size; + + ret = 0; + + lock = int_lock(); +#ifdef CP_TRACE_ENABLE + while (hal_memsc_lock(HAL_MEMSC_ID_TRACE) == 0); +#endif + + // Avoid troubles when NMI occurs during trace + if (!trace.in_trace) { + trace.in_trace = true; + + if (trace.wptr >= trace.rptr) { + avail = TRACE_BUF_SIZE - (trace.wptr - trace.rptr) - 1; + } else { + avail = (trace.rptr - trace.wptr) - 1; + } + + out_len = buf_len; +#ifdef AUDIO_DEBUG_V0_1_0 + out_len += sizeof(trace_head_buf) - 1; +#endif + if (trace.discards) { + out_len += sizeof(discards_buf); + } + + if (avail < out_len) { + ret = 1; + if (trace.discards < (1 << (sizeof(trace.discards) * 8)) - 1) { + trace.discards++; + } +#ifdef CP_TRACE_ENABLE +#if (TRACE_IDLE_OUTPUT == 0) + hal_trace_send(); +#endif +#endif + } else { +#ifdef AUDIO_DEBUG_V0_1_0 + hal_trace_print_head(); +#endif + + if (trace.discards) { + hal_trace_print_discards(trace.discards); + trace.discards = 0; + } + + size = TRACE_BUF_SIZE - trace.wptr; + if (size >= buf_len) { + size = buf_len; + } + memcpy(&trace.buf[trace.wptr], &buf[0], size); + if (size < buf_len) { + memcpy(&trace.buf[0], &buf[size], buf_len - size); + } + trace.wptr += buf_len; + if (trace.wptr >= TRACE_BUF_SIZE) { + trace.wptr -= TRACE_BUF_SIZE; + trace.wrapped = true; + } +#if (TRACE_IDLE_OUTPUT == 0) + hal_trace_send(); +#endif + } + +#ifdef CP_TRACE_ENABLE + if (get_cpu_id()) { + if (cp_buffer_cb) { + if (avail < out_len) { + cp_buffer_cb(HAL_TRACE_BUF_STATE_FULL); + } else if (avail - out_len < TRACE_NEAR_FULL_THRESH) { + cp_buffer_cb(HAL_TRACE_BUF_STATE_NEAR_FULL); + } + } + } +#endif + + trace.in_trace = false; + +#ifdef CRASH_DUMP_ENABLE +#ifdef TRACE_TO_APP + if (app_output_cb && app_output_enabled) { + bool saved_output_state; + + saved_output_state = app_output_enabled; + app_output_enabled = false; + + app_output_cb(buf, buf_len); + + app_output_enabled = saved_output_state; + } +#endif +#endif + } + +#ifdef CP_TRACE_ENABLE + hal_memsc_unlock(HAL_MEMSC_ID_TRACE); +#endif + int_unlock(lock); + + return ret ? 0 : buf_len; +} +#ifdef USE_TRACE_ID +//define USE_CRC_CHECK +//#define LITE_VERSION + +typedef struct { + uint32_t crc:6; + uint32_t count:4; + uint32_t tskid:5; + uint32_t addr:17; //127 KB trace space support +}trace_info_t; + +typedef struct { + uint32_t crc:8; + uint32_t timestamp:24; // 4 hours support +}trace_head_t; + +typedef struct { +#ifndef LITE_VERSION + trace_head_t trace_head; +#endif + trace_info_t trace_info; +}__attribute__((packed)) LOG_DATA_T; + +extern const char *unkonw_str; + +extern uint32_t __trc_str_start__[]; +extern uint32_t __trc_str_end__[]; +uint8_t crc8(uint8_t *data, uint32_t length) +{ + uint8_t i; + uint8_t crc = 0; // Initial value + while(length--) + { + crc ^= *data++; // crc ^= *data; data++; + for ( i = 0; i < 8; i++ ) + { + if ( crc & 0x80 ) + crc = (crc << 1) ^ 0x07; + else + crc <<= 1; + } + } + return crc; +} + +uint8_t crc6(uint8_t *data, uint32_t length) +{ + uint8_t i; + uint8_t crc = 0; // Initial value + while(length--) + { + crc ^= *data++; // crc ^= *data; data++; + for (i = 0; i < 8; ++i) + { + if (crc & 1) + crc = (crc >> 1) ^ 0x30;// 0x30 = (reverse 0x03)>>(8-6) + else + crc = (crc >> 1); + } + } + return crc; +} + + +static int hal_trace_format_id(uint32_t attr, char *buf, uint32_t size, const char *fmt, va_list ap) +{ + uint8_t num; + unsigned int value[10]; + LOG_DATA_T trace; + + if (size < sizeof(trace) + sizeof(value)) { + return -1; + } + + num = GET_BITFIELD(attr, LOG_ATTR_ARG_NUM); + if (num > 10) { + num = 10; + } + for (int i = 0; i < num; i++) { + value[i] = va_arg(ap, unsigned long); + } + + //memset(buf, 0, size); + + trace.trace_info.count = num; + trace.trace_info.addr = (uint32_t)fmt-(uint32_t)0xFFFC0000;//(uint32_t)fmt-(uint32_t)__trc_str_start__; + trace.trace_info.tskid = osGetThreadIntId(); + trace.trace_info.crc = 0x2A; +#ifndef LITE_VERSION + trace.trace_head.timestamp = TICKS_TO_MS(hal_sys_timer_get()); +#ifdef USE_CRC_CHECK + trace.trace_head.crc = crc8(((uint8_t *)&trace)+1,7); +#else + trace.trace_head.crc = 0xBE; +#endif +#else + trace.trace_info.crc = crc6(((uint8_t *)&trace)+1,3); +#endif + memcpy(buf, &trace, sizeof(trace)); + if (num != 0) { + memcpy(buf + sizeof(trace), value, 4*num); + } + + return sizeof(trace) + 4*num; +} +#endif + +static int hal_trace_print_time(enum LOG_LEVEL_T level, enum LOG_MODULE_T module, char *buf, unsigned int size) +{ +#ifdef TRACE_TIME_STAMP + static const char level_ch[] = { 'C', 'E', 'W', 'N', 'I', 'D', 'V', '-', }; + char ctx[10]; + int len; + int i; + const char *mod_name; + +#ifdef CRASH_DUMP_ENABLE + if (crash_handling) { + return 0; + } +#endif + + if (0) { +#ifdef CP_TRACE_ENABLE + } else if (get_cpu_id()) { + ctx[0] = ' '; + ctx[1] = 'C'; + ctx[2] = 'P'; + ctx[3] = '\0'; +#endif + } else if (in_isr()) { + len = snprintf(ctx, sizeof(ctx), "%2d", (int8_t)NVIC_GetCurrentActiveIRQ()); + if (len + 1 < ARRAY_SIZE(ctx)) { + ctx[len] = 'E'; + ctx[len + 1] = '\0'; + } else { + ctx[ARRAY_SIZE(ctx) - 2] = '.'; + ctx[ARRAY_SIZE(ctx) - 1] = '\0'; + } + } else { +#ifdef RTOS +#ifdef KERNEL_RTX5 + /* const char *thread_name = osGetThreadName(); */ + /* snprintf(ctx, sizeof(ctx), "%.9s", thread_name ? (char *)thread_name : "NULL"); */ + ctx[0] = ' '; + ctx[1] = ' '; + ctx[2] = 't'; + ctx[3] = '\0'; +#else + snprintf(ctx, sizeof(ctx), "%3d", osGetThreadIntId()); +#endif +#else + ctx[0] = ' '; + ctx[1] = ' '; + ctx[2] = '0'; + ctx[3] = '\0'; +#endif + } + ctx[ARRAY_SIZE(ctx) - 1] = '\0'; + len = 0; + len += snprintf(&buf[len], size - len, "%9u/", (unsigned)TICKS_TO_MS(hal_sys_timer_get())); + if (size > len + 2) { + buf[len++] = level_ch[level]; + buf[len++] = '/'; + } + if (size > len + 7) { + mod_name = hal_trace_get_log_module_desc(module); + for (i = 0; i < 6; i++) { + if (mod_name[i] == '\0') { + break; + } + buf[len++] = mod_name[i]; + } + for (; i < 6; i++) { + buf[len++] = ' '; + } + buf[len++] = '/'; + } + len += snprintf(&buf[len], size - len, "%s | ", ctx); + return len; +#else // !TRACE_TIME_STAMP + return 0; +#endif // !TRACE_TIME_STAMP +} + +static inline int hal_trace_format_va(uint32_t attr, char *buf, unsigned int size, const char *fmt, va_list ap) +{ + int len; + + len = vsnprintf(&buf[0], size, fmt, ap); + if ((attr & LOG_ATTR_NO_LF) == 0) { +#ifdef TRACE_CRLF + if (len + 2 < size) { + buf[len++] = '\r'; + } +#endif + if (len + 1 < size) { + buf[len++] = '\n'; + } + } + //if (len < size) buf[len] = 0; + + return len; +} + +static int hal_trace_printf_internal(uint32_t attr, const char *fmt, va_list ap) +{ +#ifdef USE_TRACE_ID + char buf[60]; +#else + char buf[120]; +#endif + int len = 0; + enum LOG_LEVEL_T level; + enum LOG_MODULE_T module; + + level = GET_BITFIELD(attr, LOG_ATTR_LEVEL); + module = GET_BITFIELD(attr, LOG_ATTR_MOD); + +#ifdef CRASH_DUMP_ENABLE + if (!crash_handling) +#endif + { + if (level > trace_max_level) { + return 0; + } + if (level > LOG_LEVEL_CRITICAL && (trace_mod_map[module >> 5] & (1 << (module & 0x1F))) == 0) { + return 0; + } + } + +#ifdef USE_TRACE_ID + if ((attr & LOG_ATTR_NO_ID) || (len = hal_trace_format_id(attr, buf, sizeof(buf), fmt, ap)) < 0) +#endif + { + len = 0; + if ((attr & LOG_ATTR_NO_TS) == 0) { + len += hal_trace_print_time(level, module, &buf[len], sizeof(buf) - len); + } + len += hal_trace_format_va(attr, &buf[len], sizeof(buf) - len, fmt, ap); + } + + return hal_trace_output((unsigned char *)buf, len); +} + +int hal_trace_printf(uint32_t attr, const char *fmt, ...) +{ + int ret; + va_list ap; + + if (attr & LOG_ATTR_IMM) { + hal_trace_flush_buffer(); + } + + va_start(ap, fmt); + ret = hal_trace_printf_internal(attr, fmt, ap); + va_end(ap); + + if (attr & LOG_ATTR_IMM) { + hal_trace_flush_buffer(); + } + + return ret; +} + +int hal_trace_dump(const char *fmt, unsigned int size, unsigned int count, const void *buffer) +{ + char buf[255]={0}; + int len=0, n=0, i=0; + + switch( size ) + { + case sizeof(uint32_t): + while(i 0) { + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + hal_trace_output((unsigned char *)crash_buf, len); + } + len = snprintf(&crash_buf[0], sizeof(crash_buf), NEW_LINE_STR "### ASSERT @ 0x%08X ###" NEW_LINE_STR, (unsigned)info.R[14]); + hal_trace_output((unsigned char *)crash_buf, len); + +#if defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FILE) || defined(ASSERT_SHOW_FUNC) + const char separate_line[] = "----------------------------------------" NEW_LINE_STR; +#ifdef ASSERT_SHOW_FILE + const char *file = scope; +#elif defined(ASSERT_SHOW_FUNC) + const char *func = scope; +#endif + +#if defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FILE) + hal_trace_output((const unsigned char *)desc_file, sizeof(desc_file)); + hal_trace_output((const unsigned char *)file, strlen(file)+1); + hal_trace_output((const unsigned char *)newline, sizeof(newline)); +#endif + +#if defined(ASSERT_SHOW_FILE_FUNC) || defined(ASSERT_SHOW_FUNC) + hal_trace_output((const unsigned char *)desc_func, sizeof(desc_func)); + hal_trace_output((const unsigned char *)func, strlen(func)+!); + hal_trace_output((const unsigned char *)newline, sizeof(newline)); +#endif + + hal_trace_output((const unsigned char *)desc_line, sizeof(desc_func)); + len = snprintf(crash_buf, sizeof(crash_buf), "%u", line); + hal_trace_output((const unsigned char *)crash_buf, len); + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + + hal_trace_output((unsigned char *)separate_line, sizeof(separate_line)); + + hal_trace_flush_buffer(); +#endif + + va_start(ap, fmt); + len = hal_trace_format_va(0, crash_buf, sizeof(crash_buf), fmt, ap); + va_end(ap); + + hal_trace_output((unsigned char *)crash_buf, len); + + hal_trace_flush_buffer(); + + hal_trace_print_common_registers(info.R); + hal_trace_print_special_stack_registers(); + + hal_trace_print_stack(info.R[13]); + + hal_trace_print_backtrace(info.R[13], TRACE_BACKTRACE_SEARCH_WORD, TRACE_BACKTRACE_NUM); + + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + + hal_trace_flush_buffer(); + +#ifdef CRASH_DUMP_ENABLE + if (full_dump) { + hal_trace_crash_dump_callback(); + hal_trace_flush_buffer(); + hal_sys_timer_delay(MS_TO_TICKS(5)); + +#ifdef CORE_DUMP + AssertCatcher_Entry(); + hal_sys_timer_delay(MS_TO_TICKS(5)); +#endif + +#ifdef TRACE_TO_APP + if (app_notify_cb) { + app_notify_cb(HAL_TRACE_STATE_CRASH_END); + } +#endif + } + +#ifdef CP_TRACE_ENABLE + if (get_cpu_id()) { + if (cp_notify_cb) { + cp_notify_cb(HAL_TRACE_STATE_CRASH_END); + } + SAFE_PROGRAM_STOP(); + } +#endif +#endif // CRASH_DUMP_ENABLE + +#endif // DEBUG || REL_TRACE_ENABLE + + hal_trace_crash_end(); +} + +void NORETURN NAKED hal_trace_assert_dump(ASSERT_DUMP_ARGS) +{ + asm volatile ( + "subs sp, sp, #4*" TO_STRING(STACK_DUMP_CNT_PREV) ";" + ".cfi_def_cfa_offset 4*" TO_STRING(STACK_DUMP_CNT_PREV) ";" + "push {r0, r1};" + "ldr r0, =crash_buf;" + "ldr r1, [sp];" + "str r1, [r0], 4;" + "ldr r1, [sp, 4];" + "str r1, [r0], 4;" + "stmia r0!, {r2-r12};" + "add r1, sp, #4*(2+" TO_STRING(STACK_DUMP_CNT_PREV) ");" + "str r1, [r0], 4;" + "str lr, [r0], 4;" + "pop {r0, r1};" + "b.w hal_trace_assert_dump_internal;" + ); +} + +#ifdef FAULT_DUMP +static void hal_trace_fill_exception_info(struct EXCEPTION_INFO_T *info, const uint32_t *regs, const uint32_t *extra, uint32_t extra_len) +{ + info->ID = HAL_TRACE_EXCEPTION_ID; + info->CPU_ID = get_cpu_id_tag(); + info->REGS = regs; +#ifdef __ARM_ARCH_ISA_ARM + info->extra = extra; + info->extra_len = extra_len; +#else + info->MSP = __get_MSP(); + info->PSP = __get_PSP(); + info->PRIMASK = regs[17]; + info->FAULTMASK = __get_FAULTMASK(); + info->BASEPRI = __get_BASEPRI(); + info->CONTROL = __get_CONTROL(); + info->ICSR = SCB->ICSR; + info->AIRCR = SCB->AIRCR; + info->SCR = SCB->SCR; + info->CCR = SCB->CCR; + info->SHCSR = SCB->SHCSR; + info->CFSR = SCB->CFSR; + info->HFSR = SCB->HFSR; + info->AFSR = SCB->AFSR; + info->MMFAR = SCB->MMFAR; + info->BFAR = SCB->BFAR; +#ifdef __ARM_ARCH_8M_MAIN__ + info->MSPLIM = __get_MSPLIM(); + info->PSPLIM = __get_PSPLIM(); +#endif +#endif +} + +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) +#ifdef __ARM_ARCH_ISA_ARM +static void hal_trace_print_fault_info_ca(const struct EXCEPTION_INFO_T *info) +{ + const struct FAULT_REGS_T *fregs; + const uint32_t *extra; + //uint32_t extra_len; + enum EXCEPTION_ID_T id; + int len; + uint32_t val; + const char *desc; + + fregs = (const struct FAULT_REGS_T*)info->REGS; + extra = info->extra; + //extra_len = info->extra_len; + + id = (enum EXCEPTION_ID_T)extra[0]; + + len = snprintf(crash_buf, sizeof(crash_buf), "PC =%08X", (unsigned)fregs->r[15]); + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", ExceptionNumber=%d" NEW_LINE_STR, id); + hal_trace_output((unsigned char *)crash_buf, len); + + hal_trace_print_common_registers(fregs->r); + + len = snprintf(crash_buf, sizeof(crash_buf), "SPSR=%08X", (unsigned)fregs->spsr); + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", APSR=%c%c%c%c%c", + (fregs->spsr & (1 << 31)) ? 'N' : 'n', + (fregs->spsr & (1 << 30)) ? 'Z' : 'z', + (fregs->spsr & (1 << 29)) ? 'C' : 'c', + (fregs->spsr & (1 << 28)) ? 'V' : 'v', + (fregs->spsr & (1 << 27)) ? 'Q' : 'q' + ); + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", XC=%c%c%c%c%c", + (fregs->spsr & (1 << 9)) ? 'E' : 'e', + (fregs->spsr & (1 << 8)) ? 'A' : 'a', + (fregs->spsr & (1 << 7)) ? 'I' : 'i', + (fregs->spsr & (1 << 6)) ? 'F' : 'f', + (fregs->spsr & (1 << 5)) ? 'T' : 't' + ); + val = fregs->spsr & 0x1F; + if (val == 0x10) { + desc = "USR"; + } else if (val == 0x11) { + desc = "FIQ"; + } else if (val == 0x12) { + desc = "IRQ"; + } else if (val == 0x13) { + desc = "SVC"; + } else if (val == 0x16) { + desc = "MON"; + } else if (val == 0x17) { + desc = "ABT"; + } else if (val == 0x1A) { + desc = "HYP"; + } else if (val == 0x1B) { + desc = "UND"; + } else if (val == 0x1F) { + desc = "SYS"; + } else { + desc = "UNKNOWN"; + } + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", MODE=%02X (%s)", (unsigned)val, desc); + hal_trace_output((unsigned char *)crash_buf, len); + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + + hal_trace_flush_buffer(); + + if (id == EXCEPTION_UNDEF) { + } else if (id == EXCEPTION_SVC) { + } else if (id == EXCEPTION_PABT) { + } else if (id == EXCEPTION_DABT) { + } else { + } +} +#else +static void hal_trace_print_fault_info_cm(const struct EXCEPTION_INFO_T *info) +{ + const uint32_t *regs; + int len; + uint32_t val; + uint32_t primask; + + regs = info->REGS; + primask = regs[17]; + + len = snprintf(crash_buf, sizeof(crash_buf), "PC =%08X", (unsigned)regs[15]); + val = __get_IPSR(); + if (val == 0) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", ThreadMode" NEW_LINE_STR); + } else { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", ExceptionNumber=%d" NEW_LINE_STR, (int)val - 16); + } + hal_trace_output((unsigned char *)crash_buf, len); + + hal_trace_print_common_registers(regs); + hal_trace_print_special_stack_registers(); + + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + + len = snprintf(crash_buf, sizeof(crash_buf), "PRIMASK=%02X, FAULTMASK=%02X, BASEPRI=%02X, CONTROL=%02X" NEW_LINE_STR, + (unsigned)primask, (unsigned)__get_FAULTMASK(), (unsigned)__get_BASEPRI(), (unsigned)__get_CONTROL()); + hal_trace_output((unsigned char *)crash_buf, len); + len = snprintf(crash_buf, sizeof(crash_buf), "XPSR=%08X", (unsigned)regs[16]); + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", APSR=%c%c%c%c%c", + (regs[16] & (1 << 31)) ? 'N' : 'n', + (regs[16] & (1 << 30)) ? 'Z' : 'z', + (regs[16] & (1 << 29)) ? 'C' : 'c', + (regs[16] & (1 << 28)) ? 'V' : 'v', + (regs[16] & (1 << 27)) ? 'Q' : 'q' + ); + val = regs[16] & 0xFF; + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, ", EPSR=%08X, IPSR=%02X", (unsigned)(regs[16] & 0x0700FC00), (unsigned)val); + if (val == 0) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (NoException)"); + } + hal_trace_output((unsigned char *)crash_buf, len); + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + + hal_trace_flush_buffer(); + + len = snprintf(crash_buf, sizeof(crash_buf), "ICSR =%08X, AIRCR=%08X, SCR =%08X, CCR =%08X" NEW_LINE_STR, + (unsigned)info->ICSR, (unsigned)info->AIRCR, (unsigned)info->SCR, (unsigned)info->CCR); + hal_trace_output((unsigned char *)crash_buf, len); + + len = snprintf(crash_buf, sizeof(crash_buf), "SHCSR=%08X, CFSR =%08X, HFSR =%08X, AFSR =%08X" NEW_LINE_STR, + (unsigned)info->SHCSR, (unsigned)info->CFSR, (unsigned)info->HFSR, (unsigned)info->AFSR); + hal_trace_output((unsigned char *)crash_buf, len); + + len = snprintf(crash_buf, sizeof(crash_buf), "MMFAR=%08X, BFAR =%08X" NEW_LINE_STR, (unsigned)info->MMFAR, (unsigned)info->BFAR); + hal_trace_output((unsigned char *)crash_buf, len); + + if (info->HFSR & (1 << 30)) { + len = snprintf(crash_buf, sizeof(crash_buf), "(Escalation HardFault)" NEW_LINE_STR); + hal_trace_output((unsigned char *)crash_buf, len); + } + + len = snprintf(crash_buf, sizeof(crash_buf), "FaultInfo :"); + if ((info->SHCSR & 0x3F) == 0) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (None)"); + } else { + if (info->SHCSR & (1 << 0)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault)"); + } + if (info->SHCSR & (1 << 1)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault)"); + } +#ifdef __ARM_ARCH_8M_MAIN__ + if (info->SHCSR & (1 << 2)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (HardFault)"); + } +#endif + if (info->SHCSR & (1 << 3)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (UsageFault)"); + } +#ifdef __ARM_ARCH_8M_MAIN__ + if (info->SHCSR & (1 << 4)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (SecureFault)"); + } + if (info->SHCSR & (1 << 5)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (NMI)"); + } +#endif + } + hal_trace_output((unsigned char *)crash_buf, len); + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + + len = snprintf(crash_buf, sizeof(crash_buf), "FaultCause:"); + if (info->CFSR == 0) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (None)"); + } else { + if (info->CFSR & (1 << 0)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Instruction access violation)"); + } + if (info->CFSR & (1 << 1)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Data access violation)"); + } + if (info->CFSR & (1 << 3)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault on unstacking for a return from exception)"); + } + if (info->CFSR & (1 << 4)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault on stacking for exception entry)"); + } + if (info->CFSR & (1 << 5)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MemFault during floating-point lazy state preservation)"); + } + if (info->CFSR & (1 << 7)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (MMFAR valid)"); + } + if (len) { + hal_trace_output((unsigned char *)crash_buf, len); + hal_trace_flush_buffer(); + len = 0; + } + if (info->CFSR & (1 << 8)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Instruction bus error)"); + } + if (info->CFSR & (1 << 9)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Precise data bus error)"); + } +#ifndef __ARM_ARCH_8M_MAIN__ + if (info->CFSR & (1 << 10)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Imprecise data bus error)"); + } +#endif + if (info->CFSR & (1 << 11)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault on unstacking for a return from exception)"); + } + if (info->CFSR & (1 << 12)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault on stacking for exception entry)"); + } + if (info->CFSR & (1 << 13)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BusFault during floating-point lazy state preservation)"); + } + if (info->CFSR & (1 << 15)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (BFAR valid)"); + } + if (len) { + hal_trace_output((unsigned char *)crash_buf, len); + hal_trace_flush_buffer(); + len = 0; + } + if (info->CFSR & (1 << 16)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Undefined instruction UsageFault)"); + } + if (info->CFSR & (1 << 17)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid state UsageFault)"); + } + if (info->CFSR & (1 << 18)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Invalid PC load by EXC_RETURN UsageFault)"); + } + if (info->CFSR & (1 << 19)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (No coprocessor UsageFault)"); + } +#ifdef __ARM_ARCH_8M_MAIN__ + if (info->CFSR & (1 << 20)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Stack overflow UsageFault)"); + } +#endif + if (info->CFSR & (1 << 24)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Unaligned access UsageFault)"); + } + if (info->CFSR & (1 << 25)) { + len += snprintf(&crash_buf[len], sizeof(crash_buf) - len, " (Divide by zero UsageFault)"); + } + } + hal_trace_output((unsigned char *)crash_buf, len); + hal_trace_output((const unsigned char *)newline, sizeof(newline)); +} +#endif + +static void hal_trace_print_fault_info(const struct EXCEPTION_INFO_T *info) +{ +#ifdef __ARM_ARCH_ISA_ARM + hal_trace_print_fault_info_ca(info); +#else + hal_trace_print_fault_info_cm(info); +#endif +} +#endif // DEBUG || REL_TRACE_ENABLE + +void hal_trace_fault_dump(const uint32_t *regs, const uint32_t *extra, uint32_t extra_len) +{ + struct EXCEPTION_INFO_T info; + + int_lock_global(); + + hal_trace_fill_exception_info(&info, regs, extra, extra_len); + + *(volatile uint32_t *)RAM_BASE = (uint32_t)&info; + +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) + + static const char title[] = NEW_LINE_STR "### EXCEPTION ###" NEW_LINE_STR; + int len; + +#ifdef CRASH_DUMP_ENABLE + bool full_dump = true; + +#ifdef CP_TRACE_ENABLE + if (get_cpu_id()) { + full_dump = false; + if (cp_notify_cb) { + cp_notify_cb(HAL_TRACE_STATE_CRASH_FAULT_START); + } + } +#endif + + if (full_dump) { +#ifdef TRACE_TO_APP + if (app_notify_cb) { + app_notify_cb(HAL_TRACE_STATE_CRASH_FAULT_START); + } + if (app_crash_custom_cb == NULL) { + app_output_enabled = true; + } +#endif + + crash_dump_onprocess = true; + for (uint8_t i = 0; i < 10; i++) { + REL_TRACE_IMM(0," "); + REL_TRACE_IMM(0," " NEW_LINE_STR); + hal_sys_timer_delay(MS_TO_TICKS(50)); + } + } +#endif + + hal_trace_flush_buffer(); + + hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_52M); + + len = hal_trace_print_time(LOG_LEVEL_CRITICAL, LOG_MODULE_NONE, &crash_buf[0], sizeof(crash_buf)); + if (len > 0) { + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + hal_trace_output((unsigned char *)crash_buf, len); + } + hal_trace_output((unsigned char *)title, sizeof(title)); + + hal_trace_print_fault_info(&info); + + hal_trace_flush_buffer(); + + hal_trace_print_stack(regs[13]); + + hal_trace_print_backtrace(regs[13], TRACE_BACKTRACE_SEARCH_WORD, TRACE_BACKTRACE_NUM); + + hal_trace_output((const unsigned char *)newline, sizeof(newline)); + + hal_trace_flush_buffer(); + +#ifdef CRASH_DUMP_ENABLE + if (full_dump) { + hal_trace_crash_dump_callback(); + hal_trace_flush_buffer(); + +#ifndef __ARM_ARCH_ISA_ARM +#ifdef TRACE_TO_APP + // Crash-Dump "Lite-Version" + if (app_crash_custom_cb) { + app_crash_custom_cb((unsigned char *)regs, + CRASH_DUMP_REGISTERS_NUM_BYTES); + stack = (uint32_t *)(__get_MSP() & ~3); + app_crash_custom_cb((unsigned char *)stack, + ((CRASH_DUMP_STACK_NUM_BYTES)/2)); + stack = (uint32_t *)(__get_PSP() & ~3); + app_crash_custom_cb((unsigned char *)stack, + ((CRASH_DUMP_STACK_NUM_BYTES)/2)); + } +#endif + +#ifdef CORE_DUMP + { + static CrashCatcherExceptionRegisters eregs; + + eregs.msp = info.MSP; + eregs.psp = info.PSP; + eregs.exceptionPSR = regs[16] & 0x0700FE00; + eregs.r4 = regs[4]; + eregs.r5 = regs[5]; + eregs.r6 = regs[6]; + eregs.r7 = regs[7]; + eregs.r8 = regs[8]; + eregs.r9 = regs[9]; + eregs.r10 = regs[10]; + eregs.r11 = regs[11]; + eregs.exceptionLR = regs[14]; + CrashCatcher_Entry( &eregs); + } +#endif +#endif // !__ARM_ARCH_ISA_ARM + +#ifdef TRACE_TO_APP + if (app_notify_cb) { + app_notify_cb(HAL_TRACE_STATE_CRASH_END); + } +#endif + } + +#ifdef CP_TRACE_ENABLE + if (get_cpu_id()) { + if (cp_notify_cb) { + cp_notify_cb(HAL_TRACE_STATE_CRASH_END); + } + SAFE_PROGRAM_STOP(); + } +#endif +#endif // CRASH_DUMP_ENABLE + +#endif // DEBUG || REL_TRACE_ENABLE + + hal_trace_crash_end(); +} + +#ifndef __ARM_ARCH_ISA_ARM +static void NAKED hal_trace_fault_handler(void) +{ + // TODO: Save FP registers (and check lazy Floating-point context preservation) + asm volatile ( + // Check EXC_RETURN.SPSEL (bit[2]) + "tst lr, #0x04;" + "ite eq;" + // Using MSP + "mrseq r3, msp;" + // Using PSP + "mrsne r3, psp;" + // Check EXC_RETURN.FType (bit[4]) + "tst lr, #0x10;" + "ite eq;" + // FPU context saved + "moveq r1, #1;" + // No FPU context + "movne r1, #0;" +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + "mov, r0, #0;" + // -- Check EXC_RETURN.S (bit[6]) + "tst lr, #0x40;" + "beq _done_sec_cntx;" + // -- Check EXC_RETURN.ES (bit[0]) + "tst lr, #0x01;" + "bne _done_sec_cntx;" + // -- Check EXC_RETURN.DCRS (bit[5]) + "tst lr, #0x20;" + "bne _done_sec_cntx;" + "mov, r0, #1;" + "push {r4-r11};" + "add r3, #2*4;" + "ldm r3!, {r4-r11};" + "_done_sec_cntx:;" + "push {r0};" +#endif + // Make room for r0-r15,psr,primask + "sub sp, #18*4;" + ".cfi_def_cfa_offset 18*4;" + // Save r4-r11 + "add r0, sp, #4*4;" + "stm r0, {r4-r11};" + ".cfi_offset r4, -14*4;" + ".cfi_offset r5, -13*4;" + ".cfi_offset r6, -12*4;" + ".cfi_offset r7, -11*4;" + ".cfi_offset r8, -10*4;" + ".cfi_offset r9, -9*4;" + ".cfi_offset r10, -8*4;" + ".cfi_offset r11, -7*4;" + // Save r0-r3 + "ldm r3, {r4-r7};" + "stm sp, {r4-r7};" + ".cfi_offset r0, -18*4;" + ".cfi_offset r1, -17*4;" + ".cfi_offset r2, -16*4;" + ".cfi_offset r3, -15*4;" + // Save r12 + "ldr r0, [r3, #4*4];" + "str r0, [sp, #12*4];" + ".cfi_offset r12, -6*4;" + // Save sp + "teq r1, 0;" + "itt eq;" + "addeq r0, r3, #8*4;" + "beq _done_stack_frame;" + "add r0, r3, #(8+18)*4;" +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + // -- Check EXC_RETURN.S (bit[6]) + "tst lr, #0x40;" + "beq _done_stack_frame;" + // -- Check FPCCR_S.TS (bit[26]) + "ldr r4, =0xE000EF34;" + "ldr r4, [r4];" + "tst r4, #(1 << 26);" + "it ne;" + "addne r3, #16*4;" +#endif + "_done_stack_frame:;" + // -- Check RETPSR.SPREALIGN (bit[9]) + "ldr r4, [r3, #7*4];" + "tst r4, #(1 << 9);" + "it ne;" + "addne r0, #4;" + "str r0, [sp, #13*4];" + // Save lr + "ldr r0, [r3, #5*4];" + "str r0, [sp, #14*4];" + // Save pc + "ldr r0, [r3, #6*4];" + "str r0, [sp, #15*4];" + // Save PSR + "ldr r0, [r3, #7*4];" + "str r0, [sp, #16*4];" + // Save primask + "mrs r0, primask;" + "str r0, [sp, #17*4];" + // Save current exception lr + "mov r4, lr;" + ".cfi_register lr, r4;" + // Invoke the fault handler + "mov r0, sp;" + "ldr r2, =hal_trace_fault_dump;" + "blx r2;" + // Restore current exception lr + "mov lr, r4;" + // Restore r4-r7 + "add r0, sp, #4*4;" + "ldm r0, {r4-r7};" + "mov r0, r3;" + // Restore sp + "add sp, #18*4;" +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + "pop {r0};" + "cmp r0, #1;" + "it eq;" + "popeq {r4-r11};" +#endif + "bx lr;" + "" + ); +} +#endif +#endif + +#define HAL_TRACE_RX_HEAD_SIZE 4 +#define HAL_TRACE_RX_NAME_SIZE 20 +#define HAL_TRACE_RX_BUF_SIZE 1024 +#define HAL_TRACE_RX_ROLE_NUM 6 + +#define HAL_TRACE_RX_HEAD '[' +#define HAL_TRACE_RX_END ']' +#define HAL_TRACE_RX_SEPARATOR ',' + +//static struct HAL_DMA_CH_CFG_T dma_cfg_rx; +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) +static struct HAL_DMA_DESC_T dma_desc_rx; +#endif + +typedef struct{ + char *name; + uint32_t len; + uint8_t *buf; +}HAL_TRACE_RX_CFG_T; + +typedef struct{ + char name[HAL_TRACE_RX_NAME_SIZE]; + HAL_TRACE_RX_CALLBACK_T callback; +}HAL_TRACE_RX_LIST_T; + +typedef struct{ + uint32_t list_num; + HAL_TRACE_RX_LIST_T list[HAL_TRACE_RX_ROLE_NUM]; + + uint32_t rx_enable; + uint32_t pos; + uint8_t buf[HAL_TRACE_RX_BUF_SIZE]; +}HAL_TRACE_RX_T; + +#if defined(_AUTO_TEST_) +extern int auto_test_prase(uint8_t *cmd); +#endif + +HAL_TRACE_RX_T hal_trace_rx; + +int hal_trace_rx_dump_list(void) +{ + for(int i=0;iname = (char *)(buf+pos); + for(; posname); + // TRACE(1,"%d", strlen(cfg->name)); + + if(pos == HAL_TRACE_RX_NAME_SIZE) + { + return 1; + } + + pos++; + + len = 0; + cfg->buf = (uint8_t*)(buf+pos); + for(; poslen = len; + if(pos == HAL_TRACE_RX_BUF_SIZE) + { + return 2; + } + + return 0; +} + +#if defined(IBRT) +void app_ibrt_peripheral_automate_test(const char* ibrt_cmd, uint32_t cmd_len); +void app_ibrt_peripheral_perform_test(const char* ibrt_cmd); +#endif + +int hal_trace_rx_process(uint8_t *buf, uint32_t len) +{ + HAL_TRACE_RX_CFG_T cfg; + int id = 0; + int res = 0; + +#if defined(IBRT) + if(buf && strlen((char*)buf) >= 10 &&((strncmp((char*)buf, "auto_test:", 10) == 0)||(strncmp((char*)buf, "ibrt_test:", 10) == 0))) + { +#ifdef BES_AUTOMATE_TEST + app_ibrt_peripheral_automate_test((char*)(buf + 10), len - 10); +#else + app_ibrt_peripheral_perform_test((char*)(buf + 10)); +#endif + return 0; + } +#endif + + res = hal_trace_rx_parse((int8_t*)buf, &cfg); + + if(res) + { + TRACE(1,"ERROR: hal_trace_rx_parse %d", res); + return 1; + } + else + { + // TRACE(1,"%s rx OK", cfg.name); + } + + id = hal_trace_rx_is_in_list(cfg.name); + + if(id == -1) + { + TRACE(1,"%s is invalid", cfg.name); + return -1; + } + + if(hal_trace_rx.list[id].callback) + { + hal_trace_rx.list[id].callback(cfg.buf, cfg.len); + } + else + { + TRACE(1,"%s has not callback", hal_trace_rx.list[id].name); + } + + return 0; +} +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) +void hal_trace_rx_start(void) +{ + uint32_t desc_cnt = 1; + union HAL_UART_IRQ_T mask; + + mask.reg = 0; + mask.BE = 0; + mask.FE = 0; + mask.OE = 0; + mask.PE = 0; + mask.RT = 1; + + hal_uart_dma_recv_mask(trace_uart, hal_trace_rx.buf, HAL_TRACE_RX_BUF_SIZE, &dma_desc_rx, &desc_cnt, &mask); +} + +void hal_trace_rx_irq_handler(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status) +{ + int res; + // TRACE(4,"[%s] %d, %d, %d", __func__, xfer_size, dma_error, status); + + if (xfer_size) + { + hal_trace_rx.buf[xfer_size] = 0; + #if defined(_AUTO_TEST_) + res = auto_test_prase(hal_trace_rx.buf); + if(res) + { + TRACE(2,"%s:auto_test_prase prase data error, err_code = %d", __func__, res); + } + #else + //TRACE(2,"[%s] RX = %s", __func__, hal_trace_rx.buf); + res = hal_trace_rx_process(hal_trace_rx.buf, xfer_size); + if(res) + { + TRACE(2,"%s:hal_trace_rx_process prase data error, err_code = %d",__func__, res); + } + #endif + hal_trace_rx_reset(); + hal_trace_rx_start(); + } +} + +uint32_t app_test_callback(unsigned char *buf, uint32_t len) +{ + TRACE(2,"[%s] len = %d", __func__, len); + + // Process string + int num_int = 0; + int num_float = 0.0; + TRACE(2,"[%s] %s", __func__, buf); + hal_trace_rx_parser((char*)buf, "%d,%d", &num_int, &num_float); + + TRACE(3,"[%s] %d:%d", __func__, num_int, num_float); + + return 0; +} + +int hal_trace_rx_open() +{ + hal_uart_irq_set_dma_handler(trace_uart, hal_trace_rx_irq_handler, NULL); + hal_trace_rx_start(); + + hal_trace_rx_register("test", (HAL_TRACE_RX_CALLBACK_T)app_test_callback); + + return 0; +} + +int hal_trace_rx_reopen() +{ + hal_uart_reopen(trace_uart, &uart_rx_enable_cfg); + hal_trace_rx_open(); + + return 0; +} +#endif diff --git a/platform/hal/hal_trace.h b/platform/hal/hal_trace.h new file mode 100644 index 0000000..0236961 --- /dev/null +++ b/platform/hal/hal_trace.h @@ -0,0 +1,406 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_TRACE_H__ +#define __HAL_TRACE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_trace_mod.h" + +#if 0 +#define AUDIO_DEBUG +#define AUDIO_DEBUG_V0_1_0 +#define INTERSYS_RAW_DATA_ONLY +#ifdef AUDIO_DEBUG +#undef TRACE_BAUD_RATE +#define TRACE_BAUD_RATE 2000000 +#endif +#endif + +#if (defined(AUDIO_DEBUG) && !defined(AUDIO_DEBUG_V0_1_0)) +#define NO_REL_TRACE +#endif +#if (defined(AUDIO_DEBUG) && !defined(AUDIO_DEBUG_V0_1_0)) || \ + defined(INTERSYS_RAW_DATA_ONLY) +#define NO_TRACE +#endif + +#if defined(__BT_DEBUG_TPORTS__) || defined(AUDIO_DEBUG_V0_1_0) +#ifndef TPORTS_KEY_COEXIST +#ifndef HAL_TRACE_RX_ENABLE +#define HAL_TRACE_RX_ENABLE +#endif +#ifndef CRASH_REBOOT +#define CRASH_REBOOT +#endif +#endif +#endif + +/* + * Total number of core registers stored + */ +#define CRASH_DUMP_REGISTERS_NUM 17 +#define CRASH_DUMP_REGISTERS_NUM_BYTES ((CRASH_DUMP_REGISTERS_NUM)*4) + +/* + * Number bytes to store from stack + * - this is total, not per PSP/MSP + */ +#define CRASH_DUMP_STACK_NUM_BYTES 384 + +// Log Attributes +#define LOG_ATTR_ARG_NUM_SHIFT 0 +#define LOG_ATTR_ARG_NUM_MASK (0xF << LOG_ATTR_ARG_NUM_SHIFT) +#define LOG_ATTR_ARG_NUM(n) BITFIELD_VAL(LOG_ATTR_ARG_NUM, n) +#define LOG_ATTR_LEVEL_SHIFT 4 +#define LOG_ATTR_LEVEL_MASK (0x7 << LOG_ATTR_LEVEL_SHIFT) +#define LOG_ATTR_LEVEL(n) BITFIELD_VAL(LOG_ATTR_LEVEL, n) +#define LOG_ATTR_MOD_SHIFT 7 +#define LOG_ATTR_MOD_MASK (0x7F << LOG_ATTR_MOD_SHIFT) +#define LOG_ATTR_MOD(n) BITFIELD_VAL(LOG_ATTR_MOD, n) +#define LOG_ATTR_IMM (1 << 14) +#define LOG_ATTR_NO_LF (1 << 15) +#define LOG_ATTR_NO_TS (1 << 16) +#define LOG_ATTR_NO_ID (1 << 17) + +// Count variadic argument number +#define _VAR_ARG_12(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, ...) a12 +#define COUNT_ARG_NUM(...) _VAR_ARG_12(unused, ##__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) + +#if defined(TRACE_STR_SECTION) && !(defined(ROM_BUILD) || defined(PROGRAMMER) || defined(FPGA)) +#define CONCAT_(x,y) x##y +#define CONCATS(x,y) CONCAT_(x,y) +#define __trcname CONCATS(__trc, __LINE__) +#define TRC_STR_LOC __attribute__((section(TO_STRING(CONCATS(.trc_str,__LINE__))))) +#define TRC_STR(s) (({ static const char TRC_STR_LOC __trcname[] = (s); __trcname; })) +#else +#define TRC_STR_LOC +#define TRC_STR(s) (s) +#endif + +#define LOG_DUMMY(attr, str, ...) hal_trace_dummy(str, ##__VA_ARGS__) + +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && !defined(NO_REL_TRACE) +#define REL_LOG(attr, str, ...) hal_trace_printf(((attr) & ~LOG_ATTR_ARG_NUM_MASK) | \ + LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), \ + TRC_STR(str), ##__VA_ARGS__) +#define REL_LOG_RAW_OUTPUT(str, len) hal_trace_output(str, len) +#define REL_LOG_FLUSH() hal_trace_flush_buffer() +#define REL_DUMP8(str, buf, cnt) hal_trace_dump(str, sizeof(uint8_t), cnt, buf) +#define REL_DUMP16(str, buf, cnt) hal_trace_dump(str, sizeof(uint16_t), cnt, buf) +#define REL_DUMP32(str, buf, cnt) hal_trace_dump(str, sizeof(uint32_t), cnt, buf) +#else +#define REL_LOG(attr, str, ...) hal_trace_dummy(str, ##__VA_ARGS__) +#define REL_LOG_RAW_OUTPUT(str, len) hal_trace_dummy((const char *)str, len) +#define REL_LOG_FLUSH() hal_trace_dummy(NULL) +#define REL_DUMP8(str, buf, cnt) hal_dump_dummy(str, buf, cnt) +#define REL_DUMP16(str, buf, cnt) hal_dump_dummy(str, buf, cnt) +#define REL_DUMP32(str, buf, cnt) hal_dump_dummy(str, buf, cnt) +#endif + +#if (!defined(DEBUG) && defined(REL_TRACE_ENABLE)) && !defined(NO_TRACE) +// To avoid warnings on unused variables +#define NORM_LOG(num,str, ...) hal_trace_dummy(str, ##__VA_ARGS__) +#define NORM_LOG_RAW_OUTPUT(str, len) hal_trace_dummy((const char *)str, len) +#define NORM_LOG_FLUSH() hal_trace_dummy(NULL) +#define DUMP8(str, buf, cnt) hal_dump_dummy(str, buf, cnt) +#define DUMP16(str, buf, cnt) hal_dump_dummy(str, buf, cnt) +#define DUMP32(str, buf, cnt) hal_dump_dummy(str, buf, cnt) +#else +#define NORM_LOG REL_LOG +#define NORM_LOG_RAW_OUTPUT REL_LOG_RAW_OUTPUT +#define NORM_LOG_FLUSH REL_TRACE_FLUSH +#define DUMP8 REL_DUMP8 +#define DUMP16 REL_DUMP16 +#define DUMP32 REL_DUMP32 +#endif + +#define RLOG_CRITICAL(attr, str, ...) REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_CRITICAL), \ + str, ##__VA_ARGS__) +#define RLOG_ERROR(attr, str, ...) REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_ERROR), \ + str, ##__VA_ARGS__) +#define RLOG_WARN(attr, str, ...) REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_WARN), \ + str, ##__VA_ARGS__) +#define RLOG_NOTIF(attr, str, ...) REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_NOTIF), \ + str, ##__VA_ARGS__) +#define RLOG_INFO(attr, str, ...) REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_INFO), \ + str, ##__VA_ARGS__) +#define RLOG_DEBUG(attr, str, ...) REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_DEBUG), \ + str, ##__VA_ARGS__) +#define RLOG_VERBOSE(attr, str, ...) REL_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_VERBOSE), \ + str, ##__VA_ARGS__) + +#define LOG_CRITICAL(attr, str, ...) NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_CRITICAL), \ + str, ##__VA_ARGS__) +#define LOG_ERROR(attr, str, ...) NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_ERROR), \ + str, ##__VA_ARGS__) +#define LOG_WARN(attr, str, ...) NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_WARN), \ + str, ##__VA_ARGS__) +#define LOG_NOTIF(attr, str, ...) NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_NOTIF), \ + str, ##__VA_ARGS__) +#define LOG_INFO(attr, str, ...) NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_INFO), \ + str, ##__VA_ARGS__) +#define LOG_DEBUG(attr, str, ...) NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_DEBUG), \ + str, ##__VA_ARGS__) +#define LOG_VERBOSE(attr, str, ...) NORM_LOG(((attr) & ~LOG_ATTR_LEVEL_MASK) | LOG_ATTR_LEVEL(LOG_LEVEL_VERBOSE), \ + str, ##__VA_ARGS__) + +#define REL_TRACE(attr, str, ...) RLOG_NOTIF(attr, str, ##__VA_ARGS__) +#define REL_TRACE_IMM(attr, str, ...) RLOG_NOTIF((attr) | LOG_ATTR_IMM, str, ##__VA_ARGS__) +#define REL_TRACE_NOCRLF(attr, str, ...) RLOG_NOTIF((attr) | LOG_ATTR_NO_LF, str, ##__VA_ARGS__) +#define REL_TRACE_NOTS(attr, str, ...) RLOG_NOTIF((attr) | LOG_ATTR_NO_TS, str, ##__VA_ARGS__) +#define REL_TRACE_IMM_NOTS(attr, str, ...) RLOG_NOTIF((attr) | LOG_ATTR_IMM | LOG_ATTR_NO_TS, str, ##__VA_ARGS__) +#define REL_TRACE_NOCRLF_NOTS(attr, str, ...) RLOG_NOTIF((attr) | LOG_ATTR_NO_LF | LOG_ATTR_NO_TS, str, ##__VA_ARGS__) +#define REL_FUNC_ENTRY_TRACE() RLOG_NOTIF(1, "%s", __FUNCTION__) +#define REL_TRACE_OUTPUT(str, len) REL_LOG_RAW_OUTPUT(str, len) +#define REL_TRACE_FLUSH() REL_LOG_FLUSH() + +#define TRACE(attr, str, ...) LOG_INFO(attr, str, ##__VA_ARGS__) +#define TRACE_IMM(attr, str, ...) LOG_INFO((attr) | LOG_ATTR_IMM, str, ##__VA_ARGS__) +#define TRACE_NOCRLF(attr, str, ...) LOG_INFO((attr) | LOG_ATTR_NO_LF, str, ##__VA_ARGS__) +#define FUNC_ENTRY_TRACE() LOG_INFO(1, "%s", __FUNCTION__) +#define TRACE_OUTPUT(str, len) NORM_LOG_RAW_OUTPUT(str, len) +#define TRACE_FLUSH() NORM_LOG_FLUSH() +#ifdef BES_AUTOMATE_TEST +#define AUTO_TEST_TRACE(attr, str, ...) LOG_INFO(attr, "_AT_"str, ##__VA_ARGS__) +#else +#define AUTO_TEST_TRACE(attr, str, ...) LOG_INFO(attr, str, ##__VA_ARGS__) +#endif + +#define TRACE_DUMMY(attr, str, ...) LOG_DUMMY(attr, str, ##__VA_ARGS__) + +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FILE_FUNC) +#define ASSERT(cond, str, ...) { if (!(cond)) { hal_trace_assert_dump(__FILE__, __FUNCTION__, __LINE__, str, ##__VA_ARGS__); } } +#define ASSERT_DUMP_ARGS const char *file, const char *func, unsigned int line, const char *fmt, ... +#define ASSERT_FMT_ARG_IDX 4 +#elif (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FILE) +#define ASSERT(cond, str, ...) { if (!(cond)) { hal_trace_assert_dump(__FILE__, __LINE__, str, ##__VA_ARGS__); } } +#define ASSERT_DUMP_ARGS const char *file, const char *func, unsigned int line, const char *fmt, ... +#define ASSERT_FMT_ARG_IDX 4 +#elif (defined(DEBUG) || defined(REL_TRACE_ENABLE)) && defined(ASSERT_SHOW_FUNC) +#define ASSERT(cond, str, ...) { if (!(cond)) { hal_trace_assert_dump(__FUNCTION__, __LINE__, str, ##__VA_ARGS__); } } +#define ASSERT_DUMP_ARGS const char *scope, unsigned int line, const char *fmt, ... +#define ASSERT_FMT_ARG_IDX 3 +#elif (defined(DEBUG) || defined(REL_TRACE_ENABLE)) +#define ASSERT(cond, str, ...) { if (!(cond)) { hal_trace_assert_dump(str, ##__VA_ARGS__); } } +#define ASSERT_DUMP_ARGS const char *fmt, ... +#define ASSERT_FMT_ARG_IDX 1 +#else +#define ASSERT(cond, str, ...) { if (!(cond)) { hal_trace_dummy(str, ##__VA_ARGS__); hal_trace_assert_dump(NULL); } } +#define ASSERT_DUMP_ARGS const char *fmt +#define ASSERT_FMT_ARG_IDX 0 +#endif + +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) +#define TRACE_FUNC_DECLARE(d, r) d +#else +#ifndef TRACE_FUNC_SPEC +#define TRACE_FUNC_SPEC static inline +#endif +#define TRACE_FUNC_DECLARE(d, r) TRACE_FUNC_SPEC d { r; } +#endif + +#if defined(__GNUC__) && !defined(NO_CHK_TRC_FMT) +#define TRC_FMT_CHK(sidx, vaidx) __attribute__((format(printf, (sidx), (vaidx)))) +#else +#define TRC_FMT_CHK(sidx, vaidx) +#endif + +#define ASSERT_NODUMP(cond) { if (!(cond)) { SAFE_PROGRAM_STOP(); } } + +#ifdef CHIP_BEST1000 +// Avoid CPU instruction fetch blocking the system bus on BEST1000 +#define SAFE_PROGRAM_STOP() do { asm volatile("nop; nop; nop; nop"); } while (1) +#else +#define SAFE_PROGRAM_STOP() do { } while (1) +#endif + +enum HAL_TRACE_TRANSPORT_T { +#ifdef CHIP_HAS_USB + HAL_TRACE_TRANSPORT_USB, +#endif + HAL_TRACE_TRANSPORT_UART0, +#if (CHIP_HAS_UART > 1) + HAL_TRACE_TRANSPORT_UART1, +#endif +#if (CHIP_HAS_UART > 2) + HAL_TRACE_TRANSPORT_UART2, +#endif + + HAL_TRACE_TRANSPORT_QTY +}; + +enum HAL_TRACE_STATE_T { + HAL_TRACE_STATE_CRASH_ASSERT_START, + HAL_TRACE_STATE_CRASH_FAULT_START, + HAL_TRACE_STATE_CRASH_END, +}; + +enum HAL_TRACE_BUF_STATE_T { + HAL_TRACE_BUF_STATE_FLUSH, + HAL_TRACE_BUF_STATE_NEAR_FULL, + HAL_TRACE_BUF_STATE_FULL, +}; + +enum HAL_TRACE_CRASH_DUMP_MODULE_T { + HAL_TRACE_CRASH_DUMP_MODULE_SYS = 0, + HAL_TRACE_CRASH_DUMP_MODULE_ID1 = 1, + HAL_TRACE_CRASH_DUMP_MODULE_ID2 = 2, + HAL_TRACE_CRASH_DUMP_MODULE_ID3 = 3, + HAL_TRACE_CRASH_DUMP_MODULE_BT = 4, + HAL_TRACE_CRASH_DUMP_MODULE_END = 5, +}; + +enum LOG_LEVEL_T { + LOG_LEVEL_CRITICAL = 0, + LOG_LEVEL_ERROR = 1, + LOG_LEVEL_WARN = 2, + LOG_LEVEL_NOTIF = 3, + LOG_LEVEL_INFO = 4, + LOG_LEVEL_DEBUG = 5, + LOG_LEVEL_VERBOSE = 6, + + LOG_LEVEL_QTY, +}; + +typedef void (*HAL_TRACE_CRASH_DUMP_CB_T)(void); + +typedef void (*HAL_TRACE_APP_NOTIFY_T)(enum HAL_TRACE_STATE_T state); + +typedef void (*HAL_TRACE_APP_OUTPUT_T)(const unsigned char *buf, unsigned int buf_len); + +typedef void (*HAL_TRACE_BUF_CTRL_T)(enum HAL_TRACE_BUF_STATE_T buf_ctrl); + +int hal_trace_open(enum HAL_TRACE_TRANSPORT_T transport); + +int hal_trace_open_cp(void); + +TRACE_FUNC_DECLARE(int hal_trace_switch(enum HAL_TRACE_TRANSPORT_T transport), return 0); + +TRACE_FUNC_DECLARE(int hal_trace_close(void), return 0); + +TRACE_FUNC_DECLARE(int hal_trace_enable_log_module(enum LOG_MODULE_T module), return 0); + +TRACE_FUNC_DECLARE(int hal_trace_disable_log_module(enum LOG_MODULE_T module), return 0); + +TRACE_FUNC_DECLARE(int hal_trace_set_log_module(const uint32_t *map, uint32_t word_cnt), return 0); + +TRACE_FUNC_DECLARE(int hal_trace_set_log_level(enum LOG_LEVEL_T level), return 0); + +TRACE_FUNC_DECLARE(void hal_trace_get_history_buffer(const unsigned char **buf1, unsigned int *len1, \ + const unsigned char **buf2, unsigned int *len2), \ + { if (buf1) { *buf1 = NULL; } if (len1) { *len1 = 0; } if (buf2) { *buf2 = NULL; } if (len2) { *len2 = 0; } }); + +TRACE_FUNC_DECLARE(int hal_trace_output(const unsigned char *buf, unsigned int buf_len), return 0); + +TRC_FMT_CHK(2, 3) +TRACE_FUNC_DECLARE(int hal_trace_printf(uint32_t attr, const char *fmt, ...), return 0); + +TRACE_FUNC_DECLARE(int hal_trace_dump(const char *fmt, unsigned int size, unsigned int count, const void *buffer), return 0); + +TRACE_FUNC_DECLARE(int hal_trace_busy(void), return 0); + +TRACE_FUNC_DECLARE(int hal_trace_pause(void), return 0); + +TRACE_FUNC_DECLARE(int hal_trace_continue(void), return 0); + +TRACE_FUNC_DECLARE(int hal_trace_flush_buffer(void), return 0); + +TRACE_FUNC_DECLARE(void hal_trace_idle_send(void), return); + +TRACE_FUNC_DECLARE(int hal_trace_crash_dump_register(enum HAL_TRACE_CRASH_DUMP_MODULE_T module, HAL_TRACE_CRASH_DUMP_CB_T cb), return 0); + +TRACE_FUNC_DECLARE(void hal_trace_app_register(HAL_TRACE_APP_NOTIFY_T notify_cb, HAL_TRACE_APP_OUTPUT_T output_cb), return); + +TRACE_FUNC_DECLARE(void hal_trace_app_custom_register(HAL_TRACE_APP_NOTIFY_T notify_cb, HAL_TRACE_APP_OUTPUT_T output_cb, HAL_TRACE_APP_OUTPUT_T crash_custom_cb), return); + +TRACE_FUNC_DECLARE(void hal_trace_cp_register(HAL_TRACE_APP_NOTIFY_T notify_cb, HAL_TRACE_BUF_CTRL_T buf_cb), return); + +TRACE_FUNC_DECLARE(void hal_trace_print_backtrace(uint32_t addr, uint32_t search_cnt, uint32_t print_cnt), return); + +TRACE_FUNC_DECLARE(bool hal_trace_crash_dump_onprocess(void), return false); + +TRACE_FUNC_DECLARE(uint32_t hal_trace_get_baudrate(void), return 0); + +TRC_FMT_CHK(1, 2) +static inline void hal_trace_dummy(const char *fmt, ...) { } + +static inline void hal_dump_dummy(const char *fmt, ...) { } + +#if (ASSERT_FMT_ARG_IDX > 0) +TRC_FMT_CHK(ASSERT_FMT_ARG_IDX, ASSERT_FMT_ARG_IDX + 1) +#endif +void NORETURN hal_trace_assert_dump(ASSERT_DUMP_ARGS); + +int hal_trace_address_writable(uint32_t addr); + +int hal_trace_address_executable(uint32_t addr); + +int hal_trace_address_readable(uint32_t addr); + + +//============================================================================== +// AUDIO_DEBUG +//============================================================================== + +#ifdef AUDIO_DEBUG +#define AUDIO_DEBUG_TRACE(str, ...) hal_trace_printf(str, ##__VA_ARGS__) +#define AUDIO_DEBUG_DUMP(buf, cnt) hal_trace_output(buf, cnt) +#endif + + +//============================================================================== +// INTERSYS_RAW_DATA_ONLY +//============================================================================== + +#ifdef INTERSYS_RAW_DATA_ONLY +#define TRACE_RAW(str, ...) hal_trace_printf(str, ##__VA_ARGS__) +#define DUMP8_RAW(str, buf, cnt) hal_trace_dump(str, sizeof(uint8_t), cnt, buf) +#endif + + +//============================================================================== +// TRACE RX +//============================================================================== + +#if defined(_AUTO_TEST_) +#ifndef HAL_TRACE_RX_ENABLE +#define HAL_TRACE_RX_ENABLE +#endif +extern int auto_test_send(char *resp); +#define AUTO_TEST_SEND(str) auto_test_send((char*)str) +#endif + +#include "stdio.h" + +#define hal_trace_rx_parser(buf, str, ...) sscanf(buf, str, ##__VA_ARGS__) + +typedef unsigned int (*HAL_TRACE_RX_CALLBACK_T)(unsigned char *buf, unsigned int len); + +int hal_trace_rx_register(const char *name, HAL_TRACE_RX_CALLBACK_T callback); +int hal_trace_rx_deregister(const char *name); +int hal_trace_rx_reopen(); +int hal_trace_rx_open(); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_trace_mod.c b/platform/hal/hal_trace_mod.c new file mode 100644 index 0000000..28426f9 --- /dev/null +++ b/platform/hal/hal_trace_mod.c @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_trace_mod.h" +#include "plat_types.h" + +#undef _LOG_MODULE_DEF_A +#define _LOG_MODULE_DEF_A(p, m) # m + +static const char * mod_desc[] = { + _LOG_MODULE_LIST +}; + +const char *hal_trace_get_log_module_desc(enum LOG_MODULE_T module) +{ + if (module < ARRAY_SIZE(mod_desc)) { + return mod_desc[module]; + } + return NULL; +} diff --git a/platform/hal/hal_trace_mod.h b/platform/hal/hal_trace_mod.h new file mode 100644 index 0000000..6960c51 --- /dev/null +++ b/platform/hal/hal_trace_mod.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_TRACE_MOD_H__ +#define __HAL_TRACE_MOD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LOG_MOD(m) LOG_ATTR_MOD(LOG_MODULE_ ## m) + +#define _LOG_MODULE_DEF_A(p, m) p ## m +#define _LOG_MODULE_DEF(m) _LOG_MODULE_DEF_A(LOG_MODULE_, m) + +#define _LOG_MODULE_LIST \ + _LOG_MODULE_DEF(NONE), \ + _LOG_MODULE_DEF(HAL), \ + _LOG_MODULE_DEF(DRVANA), \ + _LOG_MODULE_DEF(DRVCODEC), \ + _LOG_MODULE_DEF(DRVBT), \ + _LOG_MODULE_DEF(DRVFLS), \ + _LOG_MODULE_DEF(DRVSEC), \ + _LOG_MODULE_DEF(DRVUSB), \ + _LOG_MODULE_DEF(AUDFLG), \ + _LOG_MODULE_DEF(MAIN), \ + _LOG_MODULE_DEF(RT_OS), \ + _LOG_MODULE_DEF(BTPRF), \ + _LOG_MODULE_DEF(BLEPRF), \ + _LOG_MODULE_DEF(BTAPP), \ + _LOG_MODULE_DEF(BLEAPP), \ + _LOG_MODULE_DEF(TWSAPP), \ + _LOG_MODULE_DEF(IBRTAPP), \ + _LOG_MODULE_DEF(APPMAIN), \ + _LOG_MODULE_DEF(APPTHREAD), \ + _LOG_MODULE_DEF(PLAYER), \ + _LOG_MODULE_DEF(TEST), \ + _LOG_MODULE_DEF(AUD), \ + _LOG_MODULE_DEF(OTA), \ + _LOG_MODULE_DEF(NV_SEC), \ + _LOG_MODULE_DEF(AI_GVA), \ + _LOG_MODULE_DEF(AI_AMA), \ + _LOG_MODULE_DEF(AI_GMA), \ + + +enum LOG_MODULE_T { + _LOG_MODULE_LIST + + // Should <= 128 + LOG_MODULE_QTY, +}; + +const char *hal_trace_get_log_module_desc(enum LOG_MODULE_T module); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_transq.c b/platform/hal/hal_transq.c new file mode 100644 index 0000000..2849378 --- /dev/null +++ b/platform/hal/hal_transq.c @@ -0,0 +1,618 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_HAS_TRANSQ + +#include "plat_addr_map.h" +#include "reg_transq.h" +#include "hal_transq.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "stdbool.h" +#include "cmsis_nvic.h" + +// BITMAP: +// [High Priority Slots] ...... [Normal Priority Slots] +// 31 30 29 28 27 26 25 ...... 10 9 8 7 6 5 4 3 2 1 0 + +static struct TRANSQ_T * const transq[HAL_TRANSQ_ID_QTY] = { + (struct TRANSQ_T *)TRANSQ0_BASE, +#if (CHIP_HAS_TRANSQ > 1) + (struct TRANSQ_T *)TRANSQ1_BASE, +#endif +}; + +static struct TRANSQ_T * const peer_transq[HAL_TRANSQ_ID_QTY] = { + (struct TRANSQ_T *)TRANSQ0_PEER_BASE, +#if (CHIP_HAS_TRANSQ > 1) + (struct TRANSQ_T *)TRANSQ1_PEER_BASE, +#endif +}; + +static const IRQn_Type remote_irq_num[HAL_TRANSQ_ID_QTY] = { + TRANSQ0_RMT_IRQn, +#if (CHIP_HAS_TRANSQ > 1) + TRANSQ1_RMT_IRQn, +#endif +}; + +static const IRQn_Type local_irq_num[HAL_TRANSQ_ID_QTY] = { + TRANSQ0_LCL_IRQn, +#if (CHIP_HAS_TRANSQ > 1) + TRANSQ1_LCL_IRQn, +#endif +}; + +static struct HAL_TRANSQ_CFG_T transq_cfg[HAL_TRANSQ_ID_QTY]; + +static uint8_t next_tx_slot[HAL_TRANSQ_ID_QTY][HAL_TRANSQ_PRI_QTY]; + +static uint8_t active_tx_slot[HAL_TRANSQ_ID_QTY][HAL_TRANSQ_PRI_QTY]; + +static bool tx_slot_full[HAL_TRANSQ_ID_QTY][HAL_TRANSQ_PRI_QTY]; + +static uint8_t next_rx_slot[HAL_TRANSQ_ID_QTY][HAL_TRANSQ_PRI_QTY]; + +static uint32_t rx_irq_mask[HAL_TRANSQ_ID_QTY][HAL_TRANSQ_PRI_QTY]; + +static uint32_t construct_mask(uint32_t lsb, uint32_t width) +{ + int i; + uint32_t result; + + if (lsb >= 32 || width == 0) { + return 0; + } + + result = 0; + for (i = lsb; i < lsb + width; i++) { + result |= (1 << i); + } + + return result; +} + +static uint32_t get_next_rx_slot(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, uint32_t slot) +{ + slot++; + if (pri == HAL_TRANSQ_PRI_HIGH) { + if (slot >= TRANSQ_SLOT_NUM) { + slot = TRANSQ_SLOT_NUM - transq_cfg[id].slot.rx_num[pri]; + } + } else { + if (slot >= transq_cfg[id].slot.rx_num[pri]) { + slot = 0; + } + } + + return slot; +} + +static uint32_t get_next_tx_slot(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, uint32_t slot) +{ + slot++; + if (pri == HAL_TRANSQ_PRI_HIGH) { + if (slot >= TRANSQ_SLOT_NUM) { + slot = TRANSQ_SLOT_NUM - transq_cfg[id].slot.tx_num[pri]; + } + } else { + if (slot >= transq_cfg[id].slot.tx_num[pri]) { + slot = 0; + } + } + + return slot; +} + +static void hal_transq_remote_irq_handler(void) +{ + enum HAL_TRANSQ_ID_T id; + enum HAL_TRANSQ_PRI_T pri; + uint32_t status; + uint32_t slot; + +#if (CHIP_HAS_TRANSQ > 1) + IRQn_Type irq = NVIC_GetCurrentActiveIRQ(); + + for (id = HAL_TRANSQ_ID_0; id < HAL_TRANSQ_ID_QTY; id++) { + if (irq == remote_irq_num[id]) { + break; + } + } + if (id >= HAL_TRANSQ_ID_QTY) { + return; + } +#else + id = HAL_TRANSQ_ID_0; +#endif + + while ((status = peer_transq[id]->RMT_MIS) != 0) { + slot = next_rx_slot[id][HAL_TRANSQ_PRI_HIGH]; + if (slot < TRANSQ_SLOT_NUM && (status & (1 << slot))) { + pri = HAL_TRANSQ_PRI_HIGH; + } else { + pri = HAL_TRANSQ_PRI_NORMAL; + slot = next_rx_slot[id][HAL_TRANSQ_PRI_NORMAL]; + + ASSERT(slot < TRANSQ_SLOT_NUM && (status & (1 << slot)), + "TRANSQ-%d: Rx IRQ when no slot or out of order: status=0x%08x next=%d pri_next=%d", + id, status, next_rx_slot[id][HAL_TRANSQ_PRI_NORMAL], next_rx_slot[id][HAL_TRANSQ_PRI_HIGH]); + } + + // Mask IRQ from corresponding slots + peer_transq[id]->RMT_INTMASK &= ~rx_irq_mask[id][pri]; + + if (transq_cfg[id].rx_handler) { + transq_cfg[id].rx_handler(pri); + } + } +} + +static int hal_transq_active_tx_valid(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri) +{ + return (active_tx_slot[id][pri] >= TRANSQ_SLOT_NUM || + active_tx_slot[id][pri] != next_tx_slot[id][pri] || + tx_slot_full[id][pri]); +} + +static void hal_transq_local_irq_handler(void) +{ + enum HAL_TRANSQ_ID_T id; + enum HAL_TRANSQ_PRI_T pri; + uint32_t status; + uint32_t slot, next_slot; + uint32_t lock; + +#if (CHIP_HAS_TRANSQ > 1) + IRQn_Type irq = NVIC_GetCurrentActiveIRQ(); + + for (id = HAL_TRANSQ_ID_0; id < HAL_TRANSQ_ID_QTY; id++) { + if (irq == local_irq_num[id]) { + break; + } + } + if (id >= HAL_TRANSQ_ID_QTY) { + return; + } +#else + id = HAL_TRANSQ_ID_0; +#endif + + while ((status = transq[id]->LERR_MIS) != 0) { + transq[id]->LERR_ISC.LERR_INTCLR = status; + ASSERT(false, "TRANSQ-%d: Tx on active slot: 0x%08x", id, status); + } + + while ((status = transq[id]->LDONE_MIS) != 0) { + if (transq_cfg[id].tx_handler) { + lock = int_lock(); + + ASSERT(hal_transq_active_tx_valid(id, HAL_TRANSQ_PRI_HIGH), "TRANSQ-%d: Corrupted pri active tx: active=%d next=%d full=%d", + id, active_tx_slot[id][HAL_TRANSQ_PRI_HIGH], next_tx_slot[id][HAL_TRANSQ_PRI_HIGH], tx_slot_full[id][HAL_TRANSQ_PRI_HIGH]); + ASSERT(hal_transq_active_tx_valid(id, HAL_TRANSQ_PRI_NORMAL), "TRANSQ-%d: Corrupted active tx: active=%d next=%d full=%d", + id, active_tx_slot[id][HAL_TRANSQ_PRI_NORMAL], next_tx_slot[id][HAL_TRANSQ_PRI_NORMAL], tx_slot_full[id][HAL_TRANSQ_PRI_NORMAL]); + + slot = active_tx_slot[id][HAL_TRANSQ_PRI_HIGH]; + if (slot < TRANSQ_SLOT_NUM && (status & (1 << slot))) { + pri = HAL_TRANSQ_PRI_HIGH; + } else { + pri = HAL_TRANSQ_PRI_NORMAL; + slot = active_tx_slot[id][HAL_TRANSQ_PRI_NORMAL]; + + ASSERT(slot < TRANSQ_SLOT_NUM && (status & (1 << slot)), + "TRANSQ-%d: Tx done IRQ when slot empty or out of order: status=0x%08x next=%d pri_next=%d", + id, status, active_tx_slot[id][HAL_TRANSQ_PRI_NORMAL], active_tx_slot[id][HAL_TRANSQ_PRI_HIGH]); + } + + // Clear the interrupt + transq[id]->LDONE_ISC.LDONE_INTCLR = (1 << slot); + + next_slot = get_next_tx_slot(id, pri, slot); + + if (!tx_slot_full[id][pri] && next_slot == next_tx_slot[id][pri]) { + // No tx in progress + active_tx_slot[id][pri] = TRANSQ_SLOT_NUM; + } else { + tx_slot_full[id][pri] = false; + if (transq_cfg[id].slot.tx_num[pri] == 1) { + // No tx in progress + active_tx_slot[id][pri] = TRANSQ_SLOT_NUM; + } else { + // Some tx in progress + active_tx_slot[id][pri] = next_slot; + } + } + + int_unlock(lock); + + transq_cfg[id].tx_handler(pri, + (const uint8_t *)transq[id]->WSLOT[slot].ADDR, + transq[id]->WSLOT[slot].LEN); + } else { + transq[id]->LDONE_INTMASK = 0; + } + } +} + +enum HAL_TRANSQ_RET_T hal_transq_get_rx_status(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, bool *ready) +{ + uint32_t lock; + uint32_t slot; + + if (id >= HAL_TRANSQ_ID_QTY) { + return HAL_TRANSQ_RET_BAD_ID; + } + if (pri >= HAL_TRANSQ_PRI_QTY) { + return HAL_TRANSQ_RET_BAD_PRI; + } + if (transq_cfg[id].slot.rx_num[pri] == 0) { + return HAL_TRANSQ_RET_BAD_RX_NUM; + } + if (transq_cfg[id].rx_handler) { + // Rx will be processed by IRQ handler + return HAL_TRANSQ_RET_BAD_MODE; + } + + lock = int_lock(); + + slot = next_rx_slot[id][pri]; + + if (slot < TRANSQ_SLOT_NUM && peer_transq[id]->RMT_ISC.RMT_RIS & (1 << slot)) { + *ready = true; + } else { + *ready = false; + } + + int_unlock(lock); + + return HAL_TRANSQ_RET_OK; +} + +enum HAL_TRANSQ_RET_T hal_transq_get_tx_status(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, bool *done) +{ + uint32_t lock; + uint32_t slot, next_slot; + + if (id >= HAL_TRANSQ_ID_QTY) { + return HAL_TRANSQ_RET_BAD_ID; + } + if (pri >= HAL_TRANSQ_PRI_QTY) { + return HAL_TRANSQ_RET_BAD_PRI; + } + if (transq_cfg[id].slot.tx_num[pri] == 0) { + return HAL_TRANSQ_RET_BAD_TX_NUM; + } + if (transq_cfg[id].tx_handler) { + // Tx done will be processed by IRQ handler + return HAL_TRANSQ_RET_BAD_MODE; + } + + lock = int_lock(); + + slot = active_tx_slot[id][pri]; + + ASSERT(hal_transq_active_tx_valid(id, pri), "TRANSQ-%d: Corrupted active tx: pri=%d active=%d next=%d full=%d", + id, pri, active_tx_slot[id][pri], next_tx_slot[id][pri], tx_slot_full[id][pri]); + + if (transq[id]->LDONE_ISC.LDONE_RIS & (1 << slot)) { + *done = true; + + // Clear the interrupt + transq[id]->LDONE_ISC.LDONE_INTCLR = (1 << slot); + + next_slot = get_next_tx_slot(id, pri, slot); + + if (!tx_slot_full[id][pri] && next_slot == next_tx_slot[id][pri]) { + // No tx in progress + active_tx_slot[id][pri] = TRANSQ_SLOT_NUM; + } else { + tx_slot_full[id][pri] = false; + if (transq_cfg[id].slot.tx_num[pri] == 1) { + // No tx in progress + active_tx_slot[id][pri] = TRANSQ_SLOT_NUM; + } else { + // Some tx in progress + active_tx_slot[id][pri] = next_slot; + } + } + } else { + *done = false; + } + + int_unlock(lock); + + return HAL_TRANSQ_RET_OK; +} + +enum HAL_TRANSQ_RET_T hal_transq_rx_first(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, const uint8_t **data, uint32_t *len) +{ + enum HAL_TRANSQ_RET_T ret; + uint32_t slot; + //uint32_t lock; + + if (id >= HAL_TRANSQ_ID_QTY) { + return HAL_TRANSQ_RET_BAD_ID; + } + if (pri >= HAL_TRANSQ_PRI_QTY) { + return HAL_TRANSQ_RET_BAD_PRI; + } + if (transq_cfg[id].slot.rx_num[pri] == 0) { + return HAL_TRANSQ_RET_BAD_RX_NUM; + } + + //lock = int_lock(); + + slot = next_rx_slot[id][pri]; + + if (slot < TRANSQ_SLOT_NUM && peer_transq[id]->RMT_ISC.RMT_RIS & (1 << slot)) { + // Msg available + ret = HAL_TRANSQ_RET_OK; + + if (data) { + *data = (const uint8_t *)peer_transq[id]->RSLOT[slot].ADDR; + } + if (len) { + *len = peer_transq[id]->RSLOT[slot].LEN; + } + } else { + // No msg. Re-enable IRQ + ret = HAL_TRANSQ_RET_RX_EMPTY; + + if (data) { + *data = NULL; + } + if (len) { + *len = 0; + } + peer_transq[id]->RMT_INTMASK |= rx_irq_mask[id][pri]; + } + + //int_unlock(lock); + + return ret; +} + +enum HAL_TRANSQ_RET_T hal_transq_rx_next(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, const uint8_t **data, uint32_t *len) +{ + enum HAL_TRANSQ_RET_T ret; + uint32_t slot; + //uint32_t lock; + + if (id >= HAL_TRANSQ_ID_QTY) { + return HAL_TRANSQ_RET_BAD_ID; + } + if (pri >= HAL_TRANSQ_PRI_QTY) { + return HAL_TRANSQ_RET_BAD_PRI; + } + if (transq_cfg[id].slot.rx_num[pri] == 0) { + return HAL_TRANSQ_RET_BAD_RX_NUM; + } + + ret = HAL_TRANSQ_RET_OK; + + //lock = int_lock(); + + slot = next_rx_slot[id][pri]; + + if (slot < TRANSQ_SLOT_NUM && peer_transq[id]->RMT_ISC.RMT_RIS & (1 << slot)) { + // Clear cur IRQ + peer_transq[id]->RMT_ISC.RMT_INTCLR = (1 << slot); + + // Update next_rx_slot + slot = get_next_rx_slot(id, pri, slot); + next_rx_slot[id][pri] = slot; + + if (slot < TRANSQ_SLOT_NUM && peer_transq[id]->RMT_ISC.RMT_RIS & (1 << slot)) { + // Next msg available + if (data) { + *data = (const uint8_t *)peer_transq[id]->RSLOT[slot].ADDR; + } + if (len) { + *len = peer_transq[id]->RSLOT[slot].LEN; + } + } else { + // No msg + ret = HAL_TRANSQ_RET_RX_EMPTY; + } + } else { + // No msg + ret = HAL_TRANSQ_RET_RX_EMPTY; + } + + if (ret == HAL_TRANSQ_RET_RX_EMPTY) { + if (data) { + *data = NULL; + } + if (len) { + *len = 0; + } + // Re-enable IRQ + peer_transq[id]->RMT_INTMASK |= rx_irq_mask[id][pri]; + } + + //int_unlock(lock); + + return ret; +} + +enum HAL_TRANSQ_RET_T hal_transq_tx(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, const uint8_t *data, uint32_t len) +{ + enum HAL_TRANSQ_RET_T ret; + uint32_t lock; + uint32_t slot; + + if (id >= HAL_TRANSQ_ID_QTY) { + return HAL_TRANSQ_RET_BAD_ID; + } + if (pri >= HAL_TRANSQ_PRI_QTY) { + return HAL_TRANSQ_RET_BAD_PRI; + } + if (transq_cfg[id].slot.tx_num[pri] == 0) { + return HAL_TRANSQ_RET_BAD_TX_NUM; + } + + lock = int_lock(); + + if (tx_slot_full[id][pri]) { + ret = HAL_TRANSQ_RET_TX_FULL; + } else { + ret = HAL_TRANSQ_RET_OK; + + slot = next_tx_slot[id][pri]; + + transq[id]->WSLOT[slot].ADDR = (uint32_t)data; + transq[id]->WSLOT[slot].LEN = len; + transq[id]->RMT_INTSET = (1 << slot); + + // Update active_tx_slot if this is the only tx in progress + if (active_tx_slot[id][pri] >= TRANSQ_SLOT_NUM) { + active_tx_slot[id][pri] = slot; + } + + // Update next_tx_slot + next_tx_slot[id][pri] = get_next_tx_slot(id, pri, slot); + + if (next_tx_slot[id][pri] == active_tx_slot[id][pri]) { + tx_slot_full[id][pri] = true; + } + } + + int_unlock(lock); + + return ret; +} + +enum HAL_TRANSQ_RET_T hal_transq_update_num(enum HAL_TRANSQ_ID_T id, const struct HAL_TRANSQ_SLOT_NUM_T *slot) +{ + uint32_t tx_mask; + + if (id >= HAL_TRANSQ_ID_QTY) { + return HAL_TRANSQ_RET_BAD_ID; + } + if (slot == NULL) { + return HAL_TRANSQ_RET_BAD_SLOT; + } + if (slot->tx_num[HAL_TRANSQ_PRI_NORMAL] + slot->tx_num[HAL_TRANSQ_PRI_HIGH] > TRANSQ_SLOT_NUM) { + return HAL_TRANSQ_RET_BAD_TX_NUM; + } + if (slot->rx_num[HAL_TRANSQ_PRI_NORMAL] + slot->rx_num[HAL_TRANSQ_PRI_HIGH] > TRANSQ_SLOT_NUM) { + return HAL_TRANSQ_RET_BAD_RX_NUM; + } + + transq_cfg[id].slot = *slot; + + rx_irq_mask[id][HAL_TRANSQ_PRI_NORMAL] = construct_mask(0, slot->rx_num[HAL_TRANSQ_PRI_NORMAL]); + rx_irq_mask[id][HAL_TRANSQ_PRI_HIGH] = construct_mask( + TRANSQ_SLOT_NUM - slot->rx_num[HAL_TRANSQ_PRI_HIGH], + slot->rx_num[HAL_TRANSQ_PRI_HIGH]); + + tx_mask = construct_mask(0, slot->tx_num[HAL_TRANSQ_PRI_NORMAL]) | + construct_mask(TRANSQ_SLOT_NUM - slot->tx_num[HAL_TRANSQ_PRI_HIGH], slot->tx_num[HAL_TRANSQ_PRI_HIGH]); + + transq[id]->RMT_INTMASK = tx_mask; + transq[id]->LERR_INTMASK = tx_mask; + if (transq_cfg[id].tx_handler) { + transq[id]->LDONE_INTMASK = tx_mask; + } else { + transq[id]->LDONE_INTMASK = 0; + } + + return HAL_TRANSQ_RET_OK; +} + +enum HAL_TRANSQ_RET_T hal_transq_open(enum HAL_TRANSQ_ID_T id, const struct HAL_TRANSQ_CFG_T *cfg) +{ + const struct HAL_TRANSQ_SLOT_NUM_T *slot; + uint32_t ctrl; + enum HAL_TRANSQ_RET_T ret; + + if (id >= HAL_TRANSQ_ID_QTY) { + return HAL_TRANSQ_RET_BAD_ID; + } + if (cfg == NULL) { + return HAL_TRANSQ_RET_BAD_CFG; + } + +#ifdef CHIP_BEST2000 + hal_cmu_clock_enable(HAL_CMU_MOD_P_TRANSQ_WF); + hal_cmu_reset_clear(HAL_CMU_MOD_P_TRANSQ_WF); +#elif defined(CHIP_BEST2001) && !defined(CHIP_BEST2001_DSP) + //2001 dsp has enable transq clk at hal_cmu_dsp_clock_enable() + hal_cmu_clock_enable(HAL_CMU_MOD_P_TQWF); + hal_cmu_reset_clear(HAL_CMU_MOD_P_TQWF); + hal_cmu_clock_enable(HAL_CMU_MOD_P_TQA7); + hal_cmu_reset_clear(HAL_CMU_MOD_P_TQA7); +#endif + + transq_cfg[id] = *cfg; + + slot = &cfg->slot; + + ret = hal_transq_update_num(id, slot); + if (ret) { + return ret; + } + + next_tx_slot[id][HAL_TRANSQ_PRI_NORMAL] = slot->tx_num[HAL_TRANSQ_PRI_NORMAL] ? 0 : TRANSQ_SLOT_NUM; + active_tx_slot[id][HAL_TRANSQ_PRI_NORMAL] = TRANSQ_SLOT_NUM; + tx_slot_full[id][HAL_TRANSQ_PRI_NORMAL] = false; + next_rx_slot[id][HAL_TRANSQ_PRI_NORMAL] = slot->rx_num[HAL_TRANSQ_PRI_NORMAL] ? 0 : TRANSQ_SLOT_NUM; + + next_tx_slot[id][HAL_TRANSQ_PRI_HIGH] = slot->tx_num[HAL_TRANSQ_PRI_HIGH] ? + (TRANSQ_SLOT_NUM - slot->tx_num[HAL_TRANSQ_PRI_HIGH]) : TRANSQ_SLOT_NUM; + active_tx_slot[id][HAL_TRANSQ_PRI_HIGH] = TRANSQ_SLOT_NUM; + tx_slot_full[id][HAL_TRANSQ_PRI_HIGH] = false; + next_rx_slot[id][HAL_TRANSQ_PRI_HIGH] = slot->rx_num[HAL_TRANSQ_PRI_HIGH] ? + (TRANSQ_SLOT_NUM - slot->rx_num[HAL_TRANSQ_PRI_HIGH]) : TRANSQ_SLOT_NUM; + + transq[id]->LDONE_ISC.LDONE_INTCLR = ~0UL; + transq[id]->LERR_ISC.LERR_INTCLR = ~0UL; + transq[id]->RMT_ISC.RMT_INTCLR = ~0UL; + + ctrl = CTRL_REMOTE_IRQ_EN | CTRL_LOCAL_ERR_IRQ_EN; + if (cfg->tx_handler) { + ctrl |= CTRL_LOCAL_DONE_IRQ_EN; + } + transq[id]->CTRL = ctrl; + + if (cfg->rx_handler) { + NVIC_SetVector(remote_irq_num[id], (uint32_t)hal_transq_remote_irq_handler); + NVIC_SetPriority(remote_irq_num[id], IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(remote_irq_num[id]); + NVIC_EnableIRQ(remote_irq_num[id]); + } + + NVIC_SetVector(local_irq_num[id], (uint32_t)hal_transq_local_irq_handler); + NVIC_SetPriority(local_irq_num[id], IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(local_irq_num[id]); + NVIC_EnableIRQ(local_irq_num[id]); + + return HAL_TRANSQ_RET_OK; +} + +enum HAL_TRANSQ_RET_T hal_transq_close(enum HAL_TRANSQ_ID_T id) +{ + if (id >= HAL_TRANSQ_ID_QTY) { + return HAL_TRANSQ_RET_BAD_ID; + } + + transq[id]->CTRL = 0; + NVIC_DisableIRQ(remote_irq_num[id]); + NVIC_DisableIRQ(local_irq_num[id]); + + return HAL_TRANSQ_RET_OK; +} + +#endif // CHIP_HAS_TRANSQ diff --git a/platform/hal/hal_transq.h b/platform/hal/hal_transq.h new file mode 100644 index 0000000..6d1bdc5 --- /dev/null +++ b/platform/hal/hal_transq.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_TRANSQ_H__ +#define __HAL_TRANSQ_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CHIP_HAS_TRANSQ + +#include "plat_types.h" + +enum HAL_TRANSQ_ID_T { + HAL_TRANSQ_ID_0 = 0, +#if (CHIP_HAS_TRANSQ > 1) + HAL_TRANSQ_ID_1, +#endif + + HAL_TRANSQ_ID_QTY +}; + +enum HAL_TRANSQ_PRI_T { + HAL_TRANSQ_PRI_NORMAL = 0, + HAL_TRANSQ_PRI_HIGH, + + HAL_TRANSQ_PRI_QTY +}; + +enum HAL_TRANSQ_RET_T { + HAL_TRANSQ_RET_OK = 0, + HAL_TRANSQ_RET_BAD_ID, + HAL_TRANSQ_RET_BAD_PRI, + HAL_TRANSQ_RET_BAD_CFG, + HAL_TRANSQ_RET_BAD_SLOT, + HAL_TRANSQ_RET_BAD_TX_NUM, + HAL_TRANSQ_RET_BAD_RX_NUM, + HAL_TRANSQ_RET_BAD_MODE, + HAL_TRANSQ_RET_RX_EMPTY, + HAL_TRANSQ_RET_TX_FULL, +}; + +typedef void (*HAL_TRANSQ_RX_IRQ_HANDLER)(enum HAL_TRANSQ_PRI_T pri); +typedef void (*HAL_TRANSQ_TX_IRQ_HANDLER)(enum HAL_TRANSQ_PRI_T pri, const uint8_t *data, uint32_t len); + +struct HAL_TRANSQ_SLOT_NUM_T { + uint8_t tx_num[HAL_TRANSQ_PRI_QTY]; + uint8_t rx_num[HAL_TRANSQ_PRI_QTY]; +}; + +struct HAL_TRANSQ_CFG_T { + struct HAL_TRANSQ_SLOT_NUM_T slot; + HAL_TRANSQ_RX_IRQ_HANDLER rx_handler; + HAL_TRANSQ_TX_IRQ_HANDLER tx_handler; +}; + +enum HAL_TRANSQ_RET_T hal_transq_get_rx_status(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, bool *ready); + +enum HAL_TRANSQ_RET_T hal_transq_get_tx_status(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, bool *done); + +enum HAL_TRANSQ_RET_T hal_transq_rx_first(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, const uint8_t **data, uint32_t *len); + +enum HAL_TRANSQ_RET_T hal_transq_rx_next(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, const uint8_t **data, uint32_t *len); + +enum HAL_TRANSQ_RET_T hal_transq_tx(enum HAL_TRANSQ_ID_T id, enum HAL_TRANSQ_PRI_T pri, const uint8_t *data, uint32_t len); + +enum HAL_TRANSQ_RET_T hal_transq_update_num(enum HAL_TRANSQ_ID_T id, const struct HAL_TRANSQ_SLOT_NUM_T *slot); + +enum HAL_TRANSQ_RET_T hal_transq_open(enum HAL_TRANSQ_ID_T id, const struct HAL_TRANSQ_CFG_T *cfg); + +enum HAL_TRANSQ_RET_T hal_transq_close(enum HAL_TRANSQ_ID_T id); + +#endif // CHIP_HAS_TRANSQ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/hal_uart.c b/platform/hal/hal_uart.c new file mode 100644 index 0000000..1898ca4 --- /dev/null +++ b/platform/hal/hal_uart.c @@ -0,0 +1,1355 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_HAS_UART + +#include "plat_addr_map.h" +#include "hal_uart.h" +#include "reg_uart.h" +#include "cmsis_nvic.h" +#include "hal_bootmode.h" +#include "hal_cmu.h" +#include "hal_dma.h" +#include "hal_iomux.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "string.h" + +#define UART_FLUSH_DELAY_DEFAULT 2 + +enum UART_RX_DMA_MODE_T { + UART_RX_DMA_MODE_NORMAL, + UART_RX_DMA_MODE_PINGPANG, + UART_RX_DMA_MODE_STREAM, + UART_RX_DMA_MODE_BUF_LIST, +}; + +struct HAL_UART_HW_DESC_T { + struct UART_T *base; + IRQn_Type irq; + enum HAL_CMU_MOD_ID_T mod; + enum HAL_CMU_MOD_ID_T apb; + enum HAL_DMA_PERIPH_T rx_periph; + enum HAL_DMA_PERIPH_T tx_periph; +}; + +static const struct HAL_UART_HW_DESC_T uart[HAL_UART_ID_QTY] = { + { + .base = (struct UART_T *)UART0_BASE, + .irq = UART0_IRQn, + .mod = HAL_CMU_MOD_O_UART0, + .apb = HAL_CMU_MOD_P_UART0, + .rx_periph = HAL_GPDMA_UART0_RX, + .tx_periph = HAL_GPDMA_UART0_TX, + }, +#if (CHIP_HAS_UART > 1) + { + .base = (struct UART_T *)UART1_BASE, + .irq = UART1_IRQn, + .mod = HAL_CMU_MOD_O_UART1, + .apb = HAL_CMU_MOD_P_UART1, + .rx_periph = HAL_GPDMA_UART1_RX, + .tx_periph = HAL_GPDMA_UART1_TX, + }, +#endif +#if (CHIP_HAS_UART > 2) + { + .base = (struct UART_T *)UART2_BASE, + .irq = UART2_IRQn, + .mod = HAL_CMU_MOD_O_UART2, + .apb = HAL_CMU_MOD_P_UART2, + .rx_periph = HAL_GPDMA_UART2_RX, + .tx_periph = HAL_GPDMA_UART2_TX, + }, +#endif +#ifdef BT_UART + { + .base = (struct UART_T *)BT_UART_BASE, + .irq = INVALID_IRQn, + .mod = HAL_CMU_MOD_QTY, + .apb = HAL_CMU_MOD_QTY, + .rx_periph = HAL_DMA_PERIPH_NULL, + .tx_periph = HAL_DMA_PERIPH_NULL, + }, +#endif +}; + +static bool init_done = false; + +static HAL_UART_IRQ_HANDLER_T irq_handler[HAL_UART_ID_QTY] = { NULL }; + +static HAL_UART_IRQ_RXDMA_HANDLER_T rxdma_handler[HAL_UART_ID_QTY] = { NULL }; +static HAL_UART_IRQ_TXDMA_HANDLER_T txdma_handler[HAL_UART_ID_QTY] = { NULL }; + +static uint8_t recv_dma_chan[HAL_UART_ID_QTY]; +static uint8_t send_dma_chan[HAL_UART_ID_QTY]; + +static uint32_t recv_dma_size[HAL_UART_ID_QTY]; +static uint32_t send_dma_size[HAL_UART_ID_QTY]; + +static union HAL_UART_IRQ_T recv_mask[HAL_UART_ID_QTY]; + +static enum UART_RX_DMA_MODE_T recv_dma_mode[HAL_UART_ID_QTY]; + +static const char * const err_invalid_id = "Invalid UART ID: %d"; +static const char * const err_recv_dma_api = "%s: Set RT irq in hal_uart_dma_recv_mask... to avoid data lost"; + +static const struct HAL_UART_CFG_T default_cfg = { + .parity = HAL_UART_PARITY_NONE, + .stop = HAL_UART_STOP_BITS_1, + .data = HAL_UART_DATA_BITS_8, + .flow = HAL_UART_FLOW_CONTROL_RTSCTS, + .tx_level = HAL_UART_FIFO_LEVEL_1_2, + .rx_level = HAL_UART_FIFO_LEVEL_1_4, + .baud = 921600, + .dma_rx = false, + .dma_tx = false, + .dma_rx_stop_on_err = false, +}; + +static void hal_uart_irq_handler(void); + +static void set_baud_rate(enum HAL_UART_ID_T id, uint32_t rate) +{ + uint32_t mod_clk; + uint32_t ibrd, fbrd; + uint32_t div; + + mod_clk = 0; +#ifdef PERIPH_PLL_FREQ + if (PERIPH_PLL_FREQ / 2 > 2 * hal_cmu_get_crystal_freq()) { + // Init to OSC_X2 + mod_clk = 2 * hal_cmu_get_crystal_freq() / 16; + if (cfg->baud > mod_clk) { + mod_clk = PERIPH_PLL_FREQ / 2 / 16; + + if (id == HAL_UART_ID_0) { + hal_cmu_uart0_set_div(2); +#if (CHIP_HAS_UART > 1) + } else if (id == HAL_UART_ID_1) { + hal_cmu_uart1_set_div(2); +#endif +#if (CHIP_HAS_UART > 2) + } else if (id == HAL_UART_ID_2) { + hal_cmu_uart2_set_div(2); +#endif + } + } else { + mod_clk = 0; + } + } +#endif + if (mod_clk == 0) { + enum HAL_CMU_PERIPH_FREQ_T periph_freq; + + // Init to OSC + mod_clk = hal_cmu_get_crystal_freq() / 16; + if (rate > mod_clk) { + mod_clk *= 2; + periph_freq = HAL_CMU_PERIPH_FREQ_52M; + } else { + periph_freq = HAL_CMU_PERIPH_FREQ_26M; + } + + if (id == HAL_UART_ID_0) { + hal_cmu_uart0_set_freq(periph_freq); +#if (CHIP_HAS_UART > 1) + } else if (id == HAL_UART_ID_1) { + hal_cmu_uart1_set_freq(periph_freq); +#endif +#if (CHIP_HAS_UART > 2) + } else if (id == HAL_UART_ID_2) { + hal_cmu_uart2_set_freq(periph_freq); +#endif + } + } + + div = (mod_clk * 64 + rate / 2) / rate; + ibrd = div / 64; + fbrd = div % 64; + if (ibrd == 0 || ibrd >= 65535) { + ASSERT(false, "Invalid baud param: %d", rate); + } + + uart[id].base->UARTIBRD = ibrd; + uart[id].base->UARTFBRD = fbrd; + + return; +} + +int hal_uart_open(enum HAL_UART_ID_T id, const struct HAL_UART_CFG_T *cfg) +{ + uint32_t cr, lcr, dmacr; + int i; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + + if (!init_done) { + init_done = true; + for (i = HAL_UART_ID_0; i < HAL_UART_ID_QTY; i++) { + recv_dma_chan[i] = HAL_DMA_CHAN_NONE; + send_dma_chan[i] = HAL_DMA_CHAN_NONE; + } + } + + if (hal_uart_opened(id)) { + hal_uart_close(id); + } + + if (cfg == NULL) { + cfg = &default_cfg; + } + + hal_cmu_clock_enable(uart[id].mod); + hal_cmu_clock_enable(uart[id].apb); + hal_cmu_reset_clear(uart[id].mod); + hal_cmu_reset_clear(uart[id].apb); + + cr = lcr = 0; + + switch (cfg->parity) { + case HAL_UART_PARITY_NONE: + break; + case HAL_UART_PARITY_ODD: + lcr |= UARTLCR_H_PEN; + break; + case HAL_UART_PARITY_EVEN: + lcr |= UARTLCR_H_PEN + | UARTLCR_H_EPS; + break; + case HAL_UART_PARITY_FORCE1: + lcr |= UARTLCR_H_PEN + | UARTLCR_H_SPS; + break; + case HAL_UART_PARITY_FORCE0: + lcr |= UARTLCR_H_PEN + | UARTLCR_H_EPS + | UARTLCR_H_SPS; + break; + default: + ASSERT(false, "Invalid parity param: %d", cfg->parity); + break; + } + + if (cfg->stop == HAL_UART_STOP_BITS_2) { + lcr |= UARTLCR_H_STP2; + } else if (cfg->stop != HAL_UART_STOP_BITS_1) { + ASSERT(false, "Invalid stop bits param: %d", cfg->stop); + } + + switch (cfg->data) { + case HAL_UART_DATA_BITS_5: + lcr |= UARTLCR_H_WLEN_5; + break; + case HAL_UART_DATA_BITS_6: + lcr |= UARTLCR_H_WLEN_6; + break; + case HAL_UART_DATA_BITS_7: + lcr |= UARTLCR_H_WLEN_7; + break; + case HAL_UART_DATA_BITS_8: + lcr |= UARTLCR_H_WLEN_8; + break; + default: + ASSERT(false, "Invalid data bits param: %d", cfg->data); + break; + } + + switch (cfg->flow) { + case HAL_UART_FLOW_CONTROL_NONE: + break; + case HAL_UART_FLOW_CONTROL_RTS: + cr |= UARTCR_RTSEN; + break; + case HAL_UART_FLOW_CONTROL_CTS: + cr |= UARTCR_CTSEN; + break; + case HAL_UART_FLOW_CONTROL_RTSCTS: + cr |= UARTCR_RTSEN + | UARTCR_CTSEN; + break; + default: + ASSERT(false, "Invalid flow control param: %d", cfg->flow); + break; + } + + lcr |= UARTLCR_H_FEN | UARTLCR_H_DMA_RT_CNT(9); + cr |= UARTCR_UARTEN | UARTCR_TXE | UARTCR_RXE; + + dmacr = 0; + if (cfg->dma_rx) { + dmacr |= UARTDMACR_RXDMAE; + } + if (cfg->dma_tx) { + dmacr |= UARTDMACR_TXDMAE; + } + if (cfg->dma_rx_stop_on_err) { + dmacr |= UARTDMACR_DMAONERR; + } + + // Disable UART + uart[id].base->UARTCR &= ~UARTCR_UARTEN; + // Empty FIFO + uart[id].base->UARTLCR_H &= ~UARTLCR_H_FEN; + // Wait until UART becomes idle + while (((uart[id].base->UARTFR) & UARTFR_BUSY) != 0); + // Clear previous errors + uart[id].base->UARTECR = 1; + // Clear previous IRQs + uart[id].base->UARTIMSC = 0; + uart[id].base->UARTICR = ~0UL; + // Configure UART + set_baud_rate(id, cfg->baud); + uart[id].base->UARTLCR_H = lcr; + uart[id].base->UARTDMACR = dmacr; + uart[id].base->UARTIFLS = UARTIFLS_TXFIFO_LEVEL(cfg->tx_level) | + UARTIFLS_RXFIFO_LEVEL(cfg->rx_level); + uart[id].base->UARTCR = cr; + + if (uart[id].irq != INVALID_IRQn) { + NVIC_SetVector(uart[id].irq, (uint32_t)hal_uart_irq_handler); + // The priority should be the same as DMA's + NVIC_SetPriority(uart[id].irq, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(uart[id].irq); + NVIC_EnableIRQ(uart[id].irq); + } + + return 0; +} + +int hal_uart_reopen(enum HAL_UART_ID_T id, const struct HAL_UART_CFG_T *cfg) +{ + uint32_t cr, dmacr; + int i; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + + if (!init_done) { + init_done = true; + for (i = HAL_UART_ID_0; i < HAL_UART_ID_QTY; i++) { + recv_dma_chan[i] = HAL_DMA_CHAN_NONE; + send_dma_chan[i] = HAL_DMA_CHAN_NONE; + } + } + + cr = 0; + switch (cfg->flow) { + case HAL_UART_FLOW_CONTROL_NONE: + break; + case HAL_UART_FLOW_CONTROL_RTS: + cr |= UARTCR_RTSEN; + break; + case HAL_UART_FLOW_CONTROL_CTS: + cr |= UARTCR_CTSEN; + break; + case HAL_UART_FLOW_CONTROL_RTSCTS: + cr |= UARTCR_RTSEN + | UARTCR_CTSEN; + break; + default: + ASSERT(false, "Invalid flow control param: %d", cfg->flow); + break; + } + + dmacr = 0; + if (cfg->dma_rx) { + dmacr |= UARTDMACR_RXDMAE; + } + if (cfg->dma_tx) { + dmacr |= UARTDMACR_TXDMAE; + } + if (cfg->dma_rx_stop_on_err) { + dmacr |= UARTDMACR_DMAONERR; + } + + // Configure UART + uart[id].base->UARTDMACR = dmacr; + uart[id].base->UARTCR = (uart[id].base->UARTCR & ~(UARTCR_RTSEN | UARTCR_CTSEN)) | cr; + + if (uart[id].irq != INVALID_IRQn) { + NVIC_SetVector(uart[id].irq, (uint32_t)hal_uart_irq_handler); + // The priority should be the same as DMA's + NVIC_SetPriority(uart[id].irq, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(uart[id].irq); + NVIC_EnableIRQ(uart[id].irq); + } + + return 0; +} + +int hal_uart_close(enum HAL_UART_ID_T id) +{ + uint32_t lock; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + + if (uart[id].irq != INVALID_IRQn) { + NVIC_DisableIRQ(uart[id].irq); + } + + lock = int_lock(); + if (recv_dma_chan[id] != HAL_DMA_CHAN_NONE) { + hal_gpdma_cancel(recv_dma_chan[id]); + hal_gpdma_free_chan(recv_dma_chan[id]); + recv_dma_chan[id] = HAL_DMA_CHAN_NONE; + } + if (send_dma_chan[id] != HAL_DMA_CHAN_NONE) { + hal_gpdma_cancel(send_dma_chan[id]); + hal_gpdma_free_chan(send_dma_chan[id]); + send_dma_chan[id] = HAL_DMA_CHAN_NONE; + } + int_unlock(lock); + + // Disable UART + uart[id].base->UARTCR &= ~UARTCR_UARTEN; + // Empty FIFO + uart[id].base->UARTLCR_H &= ~UARTLCR_H_FEN; + + hal_cmu_reset_set(uart[id].apb); + hal_cmu_reset_set(uart[id].mod); + hal_cmu_clock_disable(uart[id].apb); + hal_cmu_clock_disable(uart[id].mod); + + return 0; +} + +int hal_uart_opened(enum HAL_UART_ID_T id) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + if (uart[id].apb < HAL_CMU_MOD_QTY && + hal_cmu_clock_get_status(uart[id].apb) != HAL_CMU_CLK_ENABLED) { + return 0; + } + if (uart[id].base->UARTCR & UARTCR_UARTEN) { + return 1; + } + return 0; +} + +int hal_uart_change_baud_rate(enum HAL_UART_ID_T id, uint32_t rate) +{ + union HAL_UART_FLAG_T flag; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + + if (!hal_uart_opened(id)) { + return 1; + } + + flag.reg = uart[id].base->UARTFR; + if (flag.BUSY) { + return 2; + } + + uart[id].base->UARTCR &= ~UARTCR_UARTEN; + + set_baud_rate(id, rate); + + uart[id].base->UARTLCR_H = uart[id].base->UARTLCR_H; + uart[id].base->UARTCR |= UARTCR_UARTEN; + + return 0; +} + +int hal_uart_pause(enum HAL_UART_ID_T id) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + if (hal_uart_opened(id)) { + uart[id].base->UARTCR &= ~(UARTCR_TXE | UARTCR_RXE); + return 0; + } + return 1; +} + +int hal_uart_continue(enum HAL_UART_ID_T id) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + if (hal_uart_opened(id)) { + uart[id].base->UARTCR |= (UARTCR_TXE | UARTCR_RXE); + return 0; + } + return 1; +} + +int hal_uart_readable(enum HAL_UART_ID_T id) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + return (uart[id].base->UARTFR & UARTFR_RXFE) == 0; +} + +int hal_uart_writable(enum HAL_UART_ID_T id) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + return (uart[id].base->UARTFR & UARTFR_TXFF) == 0; +} + +uint8_t hal_uart_getc(enum HAL_UART_ID_T id) +{ + uint32_t c; + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + ASSERT((uart[id].base->UARTDMACR & UARTDMACR_RXDMAE) == 0, "RX-DMA configured on UART %d", id); + c = uart[id].base->UARTDR; + return (c & 0xFF); +} + +int hal_uart_putc(enum HAL_UART_ID_T id, uint8_t c) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + ASSERT((uart[id].base->UARTDMACR & UARTDMACR_TXDMAE) == 0, "TX-DMA configured on UART %d", id); + uart[id].base->UARTDR = c; + return 0; +} + +uint8_t hal_uart_blocked_getc(enum HAL_UART_ID_T id) +{ + while (hal_uart_readable(id) == 0); + return hal_uart_getc(id); +} + +int hal_uart_blocked_putc(enum HAL_UART_ID_T id, uint8_t c) +{ + while (hal_uart_writable(id) == 0); + return hal_uart_putc(id, c); +} + +union HAL_UART_FLAG_T hal_uart_get_flag(enum HAL_UART_ID_T id) +{ + union HAL_UART_FLAG_T flag; + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + flag.reg = uart[id].base->UARTFR; + return flag; +} + +union HAL_UART_STATUS_T hal_uart_get_status(enum HAL_UART_ID_T id) +{ + union HAL_UART_STATUS_T status; + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + status.reg = uart[id].base->UARTRSR; + return status; +} + +void hal_uart_clear_status(enum HAL_UART_ID_T id) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + uart[id].base->UARTECR = 0; +} + +void hal_uart_break_set(enum HAL_UART_ID_T id) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + uart[id].base->UARTLCR_H |= UARTLCR_H_BRK; +} + +void hal_uart_break_clear(enum HAL_UART_ID_T id) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + uart[id].base->UARTLCR_H &= ~UARTLCR_H_BRK; +} + +void hal_uart_flush(enum HAL_UART_ID_T id, uint32_t ticks) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + + if (!hal_uart_opened(id)) { + return; + } + if ((uart[id].base->UARTLCR_H & UARTLCR_H_FEN) == 0) { + return; + } + + // Disable the UART + uart[id].base->UARTCR &= ~UARTCR_UARTEN; + // Wait for the end of transmission or reception of the current character + hal_sys_timer_delay((ticks > 0) ? ticks : UART_FLUSH_DELAY_DEFAULT); + + // Flush FIFO + uart[id].base->UARTLCR_H &= ~UARTLCR_H_FEN; + uart[id].base->UARTLCR_H |= UARTLCR_H_FEN; + + // Enable the UART + uart[id].base->UARTCR |= UARTCR_UARTEN; +} + +union HAL_UART_IRQ_T hal_uart_get_raw_irq(enum HAL_UART_ID_T id) +{ + union HAL_UART_IRQ_T irq; + + irq.reg = uart[id].base->UARTRIS; + + return irq; +} + +void hal_uart_clear_irq(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T irq) +{ + uart[id].base->UARTICR = irq.reg; +} + +union HAL_UART_IRQ_T hal_uart_irq_get_mask(enum HAL_UART_ID_T id) +{ + union HAL_UART_IRQ_T mask; + + mask.reg = uart[id].base->UARTIMSC; + + return mask; +} + +union HAL_UART_IRQ_T hal_uart_irq_set_mask(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T mask) +{ + union HAL_UART_IRQ_T old_mask; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + if (mask.RT) { + ASSERT(recv_dma_chan[id] == HAL_DMA_CHAN_NONE, err_recv_dma_api, __FUNCTION__); + } + old_mask.reg = uart[id].base->UARTIMSC; + uart[id].base->UARTIMSC = mask.reg; + + return old_mask; +} + +HAL_UART_IRQ_HANDLER_T hal_uart_irq_set_handler(enum HAL_UART_ID_T id, HAL_UART_IRQ_HANDLER_T handler) +{ + HAL_UART_IRQ_HANDLER_T old_handler; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + old_handler = irq_handler[id]; + irq_handler[id] = handler; + + return old_handler; +} + +static void dma_mode_uart_irq_handler(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T status) +{ + uint32_t xfer = 0; + uint32_t lock; + + if (status.RT || status.FE || status.OE || status.PE || status.BE) { + if (recv_dma_mode[id] == UART_RX_DMA_MODE_NORMAL) { + // Restore the traditional RT behaviour + lock = int_lock(); + uart[id].base->UARTLCR_H &= ~UARTLCR_H_DMA_RT_EN; + int_unlock(lock); + } + + if (rxdma_handler[id]) { + if (recv_dma_chan[id] != HAL_DMA_CHAN_NONE) { + if (recv_dma_mode[id] == UART_RX_DMA_MODE_NORMAL) { + xfer = hal_uart_stop_dma_recv(id); + if (recv_dma_size[id] > xfer) { + xfer = recv_dma_size[id] - xfer; + } else { + xfer = 0; + } + } + } + rxdma_handler[id](xfer, 0, status); + } + } +} + +void hal_uart_irq_set_dma_handler(enum HAL_UART_ID_T id, HAL_UART_IRQ_RXDMA_HANDLER_T rxdma, HAL_UART_IRQ_TXDMA_HANDLER_T txdma) +{ + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + rxdma_handler[id] = rxdma; + txdma_handler[id] = txdma; + irq_handler[id] = dma_mode_uart_irq_handler; +} + +static void recv_dma_irq_handler(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + enum HAL_UART_ID_T id; + uint32_t xfer; + uint32_t lock; + union HAL_UART_IRQ_T status; + + lock = int_lock(); + for (id = HAL_UART_ID_0; id < HAL_UART_ID_QTY; id++) { + if (recv_dma_chan[id] == chan) { + if (recv_dma_mode[id] == UART_RX_DMA_MODE_NORMAL) { + recv_dma_chan[id] = HAL_DMA_CHAN_NONE; + } + break; + } + } + int_unlock(lock); + + if (id == HAL_UART_ID_QTY) { + return; + } + + if (recv_dma_mode[id] == UART_RX_DMA_MODE_NORMAL) { + // Get remain xfer size + xfer = hal_gpdma_get_sg_remain_size(chan); + + hal_gpdma_free_chan(chan); + } else { + xfer = 0; + status.reg = 0; + } + + if (rxdma_handler[id]) { + if (recv_dma_mode[id] == UART_RX_DMA_MODE_NORMAL) { + // Already get xfer size + if (recv_dma_size[id] > xfer) { + xfer = recv_dma_size[id] - xfer; + } else { + xfer = 0; + } + } else if (recv_dma_mode[id] == UART_RX_DMA_MODE_PINGPANG) { + xfer = recv_dma_size[id] / 2; + } + rxdma_handler[id](xfer, error, status); + } +} + +static void recv_dma_start_callback(uint8_t chan) +{ + enum HAL_UART_ID_T id; + + for (id = HAL_UART_ID_0; id < HAL_UART_ID_QTY; id++) { + if (recv_dma_chan[id] == chan) { + break; + } + } + + if (id == HAL_UART_ID_QTY) { + return; + } + + uart[id].base->UARTIMSC = recv_mask[id].reg; +} + +static int fill_buf_list_dma_desc(struct HAL_DMA_DESC_T *desc, uint32_t cnt, struct HAL_DMA_CH_CFG_T *cfg, + const struct HAL_UART_BUF_T *ubuf, uint32_t ucnt, uint32_t step) +{ + enum HAL_DMA_RET_T ret; + struct HAL_DMA_DESC_T *last_desc; + int tc_irq; + int i; + int u; + uint32_t remain; + uint32_t dlen; + + last_desc = NULL; + + u = 0; + remain = ubuf[0].len; + + for (i = 0, u = 0; i < cnt - 1; i++) { + if (ubuf[u].loop_hdr && last_desc == NULL) { + last_desc = &desc[i]; + } + if (remain <= step) { + dlen = remain; + tc_irq = ubuf[u].irq; + } else { + dlen = step; + tc_irq = 0; + } + cfg->src_tsize = dlen; + ret = hal_gpdma_init_desc(&desc[i], cfg, &desc[i + 1], tc_irq); + if (ret != HAL_DMA_OK) { + return 1; + } + remain -= dlen; + if (remain) { + cfg->dst += dlen; + } else { + u++; + if (u >= ucnt) { + return 2; + } + cfg->dst = (uint32_t)ubuf[u].buf; + remain = ubuf[u].len; + } + } + + cfg->src_tsize = remain; + ret = hal_gpdma_init_desc(&desc[i], cfg, last_desc, ubuf[u].irq); + if (ret != HAL_DMA_OK) { + return 1; + } + + return 0; +} + +static int fill_dma_desc(struct HAL_DMA_DESC_T *desc, uint32_t cnt, struct HAL_DMA_CH_CFG_T *cfg, + uint32_t len, enum UART_RX_DMA_MODE_T mode, uint32_t step) +{ + enum HAL_DMA_RET_T ret; + struct HAL_DMA_DESC_T *last_desc; + int tc_irq; + int i; + + for (i = 0; i < cnt - 1; i++) { + cfg->src_tsize = step; + tc_irq = 0; + if (mode == UART_RX_DMA_MODE_PINGPANG) { + tc_irq = (i == cnt / 2 - 1) ? 1 : 0; + } else if (mode == UART_RX_DMA_MODE_STREAM) { + tc_irq = 1; + } + ret = hal_gpdma_init_desc(&desc[i], cfg, &desc[i + 1], tc_irq); + if (ret != HAL_DMA_OK) { + return 1; + } + cfg->dst += step; + } + + cfg->src_tsize = len - (step * i); + last_desc = NULL; + if (mode == UART_RX_DMA_MODE_PINGPANG || mode == UART_RX_DMA_MODE_STREAM) { + last_desc = &desc[0]; + } + ret = hal_gpdma_init_desc(&desc[i], cfg, last_desc, 1); + if (ret != HAL_DMA_OK) { + return 1; + } + + return 0; +} + +static int start_recv_dma_with_mask(enum HAL_UART_ID_T id, const struct HAL_UART_BUF_T *ubuf, uint32_t ucnt, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, + const union HAL_UART_IRQ_T *mask, + enum UART_RX_DMA_MODE_T mode, uint32_t step) +{ + uint8_t *buf; + uint32_t len; + struct HAL_DMA_CH_CFG_T dma_cfg; + enum HAL_DMA_RET_T ret; + uint32_t lock; + uint32_t cnt; + uint32_t i; + enum HAL_DMA_PERIPH_T periph; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + ASSERT(uart[id].irq != INVALID_IRQn, "DMA not supported on UART %d", id); + ASSERT((uart[id].base->UARTDMACR & UARTDMACR_RXDMAE), "DMA not configured on UART %d", id); + + if (ucnt == 0) { + return -21; + } + if (step > HAL_UART_DMA_TRANSFER_STEP || step == 0) { + return -22; + } + + buf = ubuf[0].buf; + len = ubuf[0].len; + + if (buf == NULL) { + return -23; + } + if (len == 0) { + return -24; + } + + if (0) { + } else if (mode == UART_RX_DMA_MODE_NORMAL) { + cnt = (len + step - 1) / step; + } else if (mode == UART_RX_DMA_MODE_PINGPANG) { + cnt = ((len / 2 + step - 1) / step) * 2; + step = len / cnt; + if (len % cnt != 0) { + return -11; + } + if (step == 0) { + return -12; + } + } else if (mode == UART_RX_DMA_MODE_STREAM) { + cnt = (len + step - 1) / step; + if (cnt == 1) { + // cnt should >= 2 + cnt++; + } + step = (len + cnt - 1) / cnt; + if (step == 0) { + return -13; + } + } else if (mode == UART_RX_DMA_MODE_BUF_LIST) { + cnt = 0; + for (i = 0; i < ucnt; i++) { + if (ubuf->buf == NULL) { + return -14; + } + if (ubuf->len == 0) { + return -15; + } + cnt += (ubuf->len + step - 1) / step; + } + } else { + return -10; + } + + // Return the required DMA descriptor count + if (desc == NULL && desc_cnt) { + *desc_cnt = (cnt == 1) ? 0 : cnt; + return 0; + } + + if (cnt > 1) { + if (desc == NULL || desc_cnt == NULL) { + return -1; + } + if (*desc_cnt < cnt) { + return -2; + } + } + if (desc_cnt) { + *desc_cnt = (cnt == 1) ? 0 : cnt; + } + + periph = uart[id].rx_periph; + + lock = int_lock(); + if (recv_dma_chan[id] != HAL_DMA_CHAN_NONE) { + int_unlock(lock); + return 1; + } + recv_dma_chan[id] = hal_gpdma_get_chan(periph, HAL_DMA_HIGH_PRIO); + if (recv_dma_chan[id] == HAL_DMA_CHAN_NONE) { + int_unlock(lock); + return 2; + } + int_unlock(lock); + + recv_dma_mode[id] = mode; + recv_dma_size[id] = len; + + memset(&dma_cfg, 0, sizeof(dma_cfg)); + dma_cfg.ch = recv_dma_chan[id]; + dma_cfg.dst = (uint32_t)buf; + dma_cfg.dst_bsize = HAL_DMA_BSIZE_32; + dma_cfg.dst_periph = 0; // useless + dma_cfg.dst_width = HAL_DMA_WIDTH_BYTE; + dma_cfg.handler = recv_dma_irq_handler; + dma_cfg.src = 0; // useless + dma_cfg.src_bsize = HAL_DMA_BSIZE_8; + dma_cfg.src_periph = periph; + dma_cfg.src_tsize = len; + dma_cfg.src_width = HAL_DMA_WIDTH_BYTE; + dma_cfg.type = HAL_DMA_FLOW_P2M_DMA; + dma_cfg.try_burst = 0; + + if (mask) { + recv_mask[id] = *mask; + dma_cfg.start_cb = recv_dma_start_callback; + } else { + union HAL_UART_IRQ_T irq_mask; + + irq_mask.reg = uart[id].base->UARTIMSC; + ASSERT(irq_mask.RT == 0, err_recv_dma_api, __FUNCTION__); + } + + // Activate DMA RT behaviour + lock = int_lock(); + uart[id].base->UARTLCR_H |= UARTLCR_H_DMA_RT_EN; + int_unlock(lock); + + if (cnt == 1) { + ret = hal_gpdma_start(&dma_cfg); + } else { + if (mode == UART_RX_DMA_MODE_BUF_LIST) { + ret = fill_buf_list_dma_desc(desc, cnt, &dma_cfg, ubuf, ucnt, step); + } else { + ret = fill_dma_desc(desc, cnt, &dma_cfg, len, mode, step); + } + if (ret) { + goto _err_exit; + } + ret = hal_gpdma_sg_start(desc, &dma_cfg); + } + + if (ret != HAL_DMA_OK) { +_err_exit: + // Restore the traditional RT behaviour + lock = int_lock(); + uart[id].base->UARTLCR_H &= ~UARTLCR_H_DMA_RT_EN; + int_unlock(lock); + hal_gpdma_free_chan(recv_dma_chan[id]); + recv_dma_chan[id] = HAL_DMA_CHAN_NONE; + return 3; + } + + return 0; +} + +// Safe API to trigger receive timeout IRQ and DMA IRQ +int hal_uart_dma_recv_mask(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, + const union HAL_UART_IRQ_T *mask) +{ + struct HAL_UART_BUF_T uart_buf; + + uart_buf.buf = buf; + uart_buf.len = len; + uart_buf.irq = false; + uart_buf.loop_hdr = false; + return start_recv_dma_with_mask(id, &uart_buf, 1, desc, desc_cnt, mask, UART_RX_DMA_MODE_NORMAL, HAL_UART_DMA_TRANSFER_STEP); +} + +// Safe API to trigger receive timeout IRQ and DMA IRQ +int hal_uart_dma_recv_mask_pingpang(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, + const union HAL_UART_IRQ_T *mask, uint32_t step) +{ + struct HAL_UART_BUF_T uart_buf; + + uart_buf.buf = buf; + uart_buf.len = len; + uart_buf.irq = false; + uart_buf.loop_hdr = false; + return start_recv_dma_with_mask(id, &uart_buf, 1, desc, desc_cnt, mask, UART_RX_DMA_MODE_PINGPANG, step); +} + +// Safe API to trigger receive timeout IRQ and DMA IRQ +int hal_uart_dma_recv_mask_stream(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, + const union HAL_UART_IRQ_T *mask, uint32_t step) +{ + struct HAL_UART_BUF_T uart_buf; + + uart_buf.buf = buf; + uart_buf.len = len; + uart_buf.irq = false; + uart_buf.loop_hdr = false; + return start_recv_dma_with_mask(id, &uart_buf, 1, desc, desc_cnt, mask, UART_RX_DMA_MODE_STREAM, step); +} + +// Safe API to trigger receive timeout IRQ and DMA IRQ +int hal_uart_dma_recv_mask_buf_list(enum HAL_UART_ID_T id, const struct HAL_UART_BUF_T *ubuf, uint32_t ucnt, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, const union HAL_UART_IRQ_T *mask) +{ + return start_recv_dma_with_mask(id, ubuf, ucnt, desc, desc_cnt, mask, UART_RX_DMA_MODE_BUF_LIST, HAL_UART_DMA_TRANSFER_STEP); +} + +int hal_uart_dma_recv(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt) +{ + struct HAL_UART_BUF_T uart_buf; + + uart_buf.buf = buf; + uart_buf.len = len; + uart_buf.irq = false; + uart_buf.loop_hdr = false; + return start_recv_dma_with_mask(id, &uart_buf, 1, desc, desc_cnt, NULL, UART_RX_DMA_MODE_NORMAL, HAL_UART_DMA_TRANSFER_STEP); +} + +int hal_uart_dma_recv_pingpang(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt) +{ + struct HAL_UART_BUF_T uart_buf; + + uart_buf.buf = buf; + uart_buf.len = len; + uart_buf.irq = false; + uart_buf.loop_hdr = false; + return start_recv_dma_with_mask(id, &uart_buf, 1, desc, desc_cnt, NULL, UART_RX_DMA_MODE_PINGPANG, HAL_UART_DMA_TRANSFER_STEP_PINGPANG); +} + +uint32_t hal_uart_get_dma_recv_addr(enum HAL_UART_ID_T id) +{ + uint32_t lock; + uint32_t addr; + int i; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + + addr = 0; + + lock = int_lock(); + if (recv_dma_chan[id] != HAL_DMA_CHAN_NONE) { + for (i = 0; i < 2; i++) { + addr = hal_dma_get_cur_dst_addr(recv_dma_chan[id]); + if (addr) { + break; + } + } + } + int_unlock(lock); + + return addr; +} + +uint32_t hal_uart_stop_dma_recv(enum HAL_UART_ID_T id) +{ + uint32_t remains; + uint32_t lock; + uint8_t chan; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + + lock = int_lock(); + chan = recv_dma_chan[id]; + recv_dma_chan[id] = HAL_DMA_CHAN_NONE; + // Restore the traditional RT behaviour + uart[id].base->UARTLCR_H &= ~UARTLCR_H_DMA_RT_EN; + int_unlock(lock); + + if (chan == HAL_DMA_CHAN_NONE) { + return 0; + } + + // Save the data in DMA FIFO + hal_gpdma_stop(chan); + remains = hal_gpdma_get_sg_remain_size(chan); + hal_gpdma_free_chan(chan); + + return remains; +} + +static void send_dma_irq_handler(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + enum HAL_UART_ID_T id; + uint32_t xfer; + uint32_t lock; + + lock = int_lock(); + for (id = HAL_UART_ID_0; id < HAL_UART_ID_QTY; id++) { + if (send_dma_chan[id] == chan) { + send_dma_chan[id] = HAL_DMA_CHAN_NONE; + break; + } + } + int_unlock(lock); + + if (id == HAL_UART_ID_QTY) { + return; + } + + // Get remain xfer size + xfer = hal_gpdma_get_sg_remain_size(chan); + + hal_gpdma_free_chan(chan); + + if (txdma_handler[id]) { + // Get already xfer size + if (send_dma_size[id] > xfer) { + xfer = send_dma_size[id] - xfer; + } else { + xfer = 0; + } + txdma_handler[id](xfer, error); + } +} + +int hal_uart_dma_send(enum HAL_UART_ID_T id, const uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt) +{ + struct HAL_DMA_CH_CFG_T dma_cfg; + enum HAL_DMA_RET_T ret; + uint32_t lock; + uint32_t cnt; + uint32_t i; + enum HAL_DMA_PERIPH_T periph; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + ASSERT(uart[id].irq != INVALID_IRQn, "DMA not supported on UART %d", id); + ASSERT((uart[id].base->UARTDMACR & UARTDMACR_TXDMAE), "DMA not configured on UART %d", id); + + cnt = (len + HAL_UART_DMA_TRANSFER_STEP - 1) / HAL_UART_DMA_TRANSFER_STEP; + + // Return the required DMA descriptor count + if (desc == NULL && desc_cnt) { + *desc_cnt = (cnt == 1) ? 0 : cnt; + return 0; + } + + if (cnt == 0) { + return 0; + } + if (cnt > 1) { + if (desc == NULL || desc_cnt == NULL) { + return -1; + } + if (*desc_cnt < cnt) { + return -2; + } + } + if (desc_cnt) { + *desc_cnt = (cnt == 1) ? 0 : cnt; + } + + periph = uart[id].tx_periph; + + lock = int_lock(); + if (send_dma_chan[id] != HAL_DMA_CHAN_NONE) { + int_unlock(lock); + return 1; + } + send_dma_chan[id] = hal_gpdma_get_chan(periph, HAL_DMA_HIGH_PRIO); + if (send_dma_chan[id] == HAL_DMA_CHAN_NONE) { + int_unlock(lock); + return 2; + } + int_unlock(lock); + + send_dma_size[id] = len; + + memset(&dma_cfg, 0, sizeof(dma_cfg)); + dma_cfg.ch = send_dma_chan[id]; + dma_cfg.dst = 0; // useless + dma_cfg.dst_bsize = HAL_DMA_BSIZE_8; + dma_cfg.dst_periph = periph; + dma_cfg.dst_width = HAL_DMA_WIDTH_BYTE; + dma_cfg.handler = send_dma_irq_handler; + dma_cfg.src = (uint32_t)buf; + dma_cfg.src_bsize = HAL_DMA_BSIZE_32; + dma_cfg.src_periph = 0; // useless + dma_cfg.src_tsize = len; + dma_cfg.src_width = HAL_DMA_WIDTH_BYTE; + dma_cfg.type = HAL_DMA_FLOW_M2P_DMA; + dma_cfg.try_burst = 0; + + if (cnt == 1) { + ret = hal_gpdma_start(&dma_cfg); + } else { + for (i = 0; i < cnt - 1; i++) { + dma_cfg.src_tsize = HAL_UART_DMA_TRANSFER_STEP; + ret = hal_gpdma_init_desc(&desc[i], &dma_cfg, &desc[i + 1], 0); + if (ret != HAL_DMA_OK) { + goto _err_exit; + } + dma_cfg.src += HAL_UART_DMA_TRANSFER_STEP; + } + dma_cfg.src_tsize = len - (HAL_UART_DMA_TRANSFER_STEP * i); + ret = hal_gpdma_init_desc(&desc[i], &dma_cfg, NULL, 1); + if (ret != HAL_DMA_OK) { + goto _err_exit; + } + ret = hal_gpdma_sg_start(desc, &dma_cfg); + } + + if (ret != HAL_DMA_OK) { +_err_exit: + hal_gpdma_free_chan(send_dma_chan[id]); + send_dma_chan[id] = HAL_DMA_CHAN_NONE; + return 3; + } + + return 0; +} + +uint32_t hal_uart_stop_dma_send(enum HAL_UART_ID_T id) +{ + uint32_t remains; + uint32_t lock; + uint8_t chan; + + ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id); + + lock = int_lock(); + chan = send_dma_chan[id]; + send_dma_chan[id] = HAL_DMA_CHAN_NONE; + int_unlock(lock); + + if (chan == HAL_DMA_CHAN_NONE) { + return 0; + } + + // Not to keep the data in DMA FIFO + hal_gpdma_cancel(chan); + remains = hal_gpdma_get_sg_remain_size(chan); + hal_gpdma_free_chan(chan); + + return remains; +} + +static void hal_uart_irq_handler(void) +{ + enum HAL_UART_ID_T id; + union HAL_UART_IRQ_T state; + + for (id = HAL_UART_ID_0; id < HAL_UART_ID_QTY; id++) { + state.reg = uart[id].base->UARTMIS; + + if (state.reg) { + uart[id].base->UARTICR = state.reg; + + if (irq_handler[id] != NULL) { + irq_handler[id](id, state); + } + } + } +} + +// ======================================================================== +// Test function + +#include "stdarg.h" +#include "stdio.h" + +#if !defined(DEBUG_PORT) || (DEBUG_PORT == 1) +#define UART_PRINTF_ID HAL_UART_ID_0 +#else +#define UART_PRINTF_ID HAL_UART_ID_1 +#endif + +#ifndef TRACE_BAUD_RATE +#define TRACE_BAUD_RATE (921600) +#endif + +int hal_uart_printf_init(void) +{ + static const struct HAL_UART_CFG_T uart_cfg = { + .parity = HAL_UART_PARITY_NONE, + .stop = HAL_UART_STOP_BITS_1, + .data = HAL_UART_DATA_BITS_8, + .flow = HAL_UART_FLOW_CONTROL_NONE,//HAL_UART_FLOW_CONTROL_RTSCTS, + .tx_level = HAL_UART_FIFO_LEVEL_1_2, + .rx_level = HAL_UART_FIFO_LEVEL_1_4, + .baud = TRACE_BAUD_RATE, + .dma_rx = false, + .dma_tx = false, + .dma_rx_stop_on_err = false, + }; + + if (UART_PRINTF_ID == HAL_UART_ID_0) { + hal_iomux_set_uart0(); + } else { + hal_iomux_set_uart1(); + } + + return hal_uart_open(UART_PRINTF_ID, &uart_cfg); +} + +void hal_uart_printf(const char *fmt, ...) +{ + char buf[200]; + int ret; + int i; + va_list ap; + + va_start(ap, fmt); + ret = vsnprintf(buf, sizeof(buf), fmt, ap); +#ifdef TRACE_CRLF + if (ret + 2 < sizeof(buf)) { + buf[ret++] = '\r'; + } +#endif + if (ret + 1 < sizeof(buf)) { + buf[ret++] = '\n'; + } + //buf[ret] = 0; + va_end(ap); + + if (ret > 0) { + for (i = 0; i < ret; i++) { + hal_uart_blocked_putc(UART_PRINTF_ID, buf[i]); + } + } +} + +#endif // CHIP_HAS_UART diff --git a/platform/hal/hal_uart.h b/platform/hal/hal_uart.h new file mode 100644 index 0000000..0375f8e --- /dev/null +++ b/platform/hal/hal_uart.h @@ -0,0 +1,253 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_UART_H__ +#define __HAL_UART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CHIP_HAS_UART + +#include "plat_types.h" +#include "stdbool.h" +#include "stdint.h" +#include "hal_dma.h" + +//#define BT_UART + +#define HAL_UART_DMA_TRANSFER_STEP 0xFFF +#ifdef __KNOWLES +#define HAL_UART_DMA_TRANSFER_STEP_PINGPANG 640 +#else +#define HAL_UART_DMA_TRANSFER_STEP_PINGPANG 4 +#endif + +enum HAL_UART_ID_T { + HAL_UART_ID_0 = 0, +#if (CHIP_HAS_UART > 1) + HAL_UART_ID_1, +#endif +#if (CHIP_HAS_UART > 2) + HAL_UART_ID_2, +#endif +#ifdef BT_UART + HAL_UART_ID_BT, +#endif + + HAL_UART_ID_QTY +}; + +enum HAL_UART_PARITY_T { + HAL_UART_PARITY_NONE, + HAL_UART_PARITY_ODD, + HAL_UART_PARITY_EVEN, + HAL_UART_PARITY_FORCE1, + HAL_UART_PARITY_FORCE0, +}; + +enum HAL_UART_STOP_BITS_T { + HAL_UART_STOP_BITS_1, + HAL_UART_STOP_BITS_2, +}; + +enum HAL_UART_DATA_BITS_T { + HAL_UART_DATA_BITS_5, + HAL_UART_DATA_BITS_6, + HAL_UART_DATA_BITS_7, + HAL_UART_DATA_BITS_8, +}; + +enum HAL_UART_FLOW_CONTROL_T { + HAL_UART_FLOW_CONTROL_NONE, + HAL_UART_FLOW_CONTROL_RTS, + HAL_UART_FLOW_CONTROL_CTS, + HAL_UART_FLOW_CONTROL_RTSCTS, +}; + +enum HAL_UART_FIFO_LEVEL_T { + HAL_UART_FIFO_LEVEL_1_8, + HAL_UART_FIFO_LEVEL_1_4, + HAL_UART_FIFO_LEVEL_1_2, + HAL_UART_FIFO_LEVEL_3_4, + HAL_UART_FIFO_LEVEL_7_8, +}; + +struct HAL_UART_CFG_T { + enum HAL_UART_PARITY_T parity; + enum HAL_UART_STOP_BITS_T stop; + enum HAL_UART_DATA_BITS_T data; + enum HAL_UART_FLOW_CONTROL_T flow; + enum HAL_UART_FIFO_LEVEL_T rx_level; + enum HAL_UART_FIFO_LEVEL_T tx_level; + uint32_t baud; + bool dma_rx : 1; + bool dma_tx : 1; + bool dma_rx_stop_on_err : 1; +}; + +struct HAL_UART_BUF_T { + uint8_t *buf; + uint32_t len; + bool irq; + bool loop_hdr; +}; + +union HAL_UART_STATUS_T { + struct { + uint32_t FE :1; // frame error + uint32_t PE :1; // parity error + uint32_t BE :1; // break error + uint32_t OE :1; // overrun error + }; + uint32_t reg; +}; + +union HAL_UART_FLAG_T { + struct { + uint32_t CTS :1; + uint32_t DSR :1; + uint32_t DCD :1; + uint32_t BUSY :1; + uint32_t RXFE :1; // rx fifo empty + uint32_t TXFF :1; // tx fifo full + uint32_t RXFF :1; // rx fifo full + uint32_t TXFE :1; // tx fifo empty + uint32_t RI :1; // ring indicator + }; + uint32_t reg; +}; + +union HAL_UART_IRQ_T { + struct { + uint32_t RIM :1; // ri + uint32_t CTSM :1; // cts + uint32_t DCDM :1; // dcd + uint32_t DSRM :1; // dsr + uint32_t RX :1; // rx + uint32_t TX :1; // tx + uint32_t RT :1; // receive timeout + uint32_t FE :1; // framing error + uint32_t PE :1; // parity error + uint32_t BE :1; // break error + uint32_t OE :1; // overrun + }; + uint32_t reg; +}; + +typedef void (*HAL_UART_IRQ_HANDLER_T)(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T status); + +typedef void (*HAL_UART_IRQ_RXDMA_HANDLER_T)(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status); + +typedef void (*HAL_UART_IRQ_TXDMA_HANDLER_T)(uint32_t xfer_size, int dma_error); + +int hal_uart_open(enum HAL_UART_ID_T id, const struct HAL_UART_CFG_T *cfg); + +int hal_uart_reopen(enum HAL_UART_ID_T id, const struct HAL_UART_CFG_T *cfg); + +int hal_uart_close(enum HAL_UART_ID_T id); + +int hal_uart_opened(enum HAL_UART_ID_T id); + +int hal_uart_change_baud_rate(enum HAL_UART_ID_T id, uint32_t rate); + +int hal_uart_pause(enum HAL_UART_ID_T id); + +int hal_uart_continue(enum HAL_UART_ID_T id); + +int hal_uart_readable(enum HAL_UART_ID_T id); + +int hal_uart_writable(enum HAL_UART_ID_T id); + +uint8_t hal_uart_getc(enum HAL_UART_ID_T id); + +int hal_uart_putc(enum HAL_UART_ID_T id, uint8_t c); + +uint8_t hal_uart_blocked_getc(enum HAL_UART_ID_T id); + +int hal_uart_blocked_putc(enum HAL_UART_ID_T id, uint8_t c); + +union HAL_UART_FLAG_T hal_uart_get_flag(enum HAL_UART_ID_T id); + +union HAL_UART_STATUS_T hal_uart_get_status(enum HAL_UART_ID_T id); + +void hal_uart_clear_status(enum HAL_UART_ID_T id); + +void hal_uart_break_set(enum HAL_UART_ID_T id); + +void hal_uart_break_clear(enum HAL_UART_ID_T id); + +void hal_uart_flush(enum HAL_UART_ID_T id, uint32_t ticks); + +union HAL_UART_IRQ_T hal_uart_get_raw_irq(enum HAL_UART_ID_T id); + +void hal_uart_clear_irq(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T irq); + +union HAL_UART_IRQ_T hal_uart_irq_get_mask(enum HAL_UART_ID_T id); + +union HAL_UART_IRQ_T hal_uart_irq_set_mask(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T mask); + +HAL_UART_IRQ_HANDLER_T hal_uart_irq_set_handler(enum HAL_UART_ID_T id, HAL_UART_IRQ_HANDLER_T handler); + +void hal_uart_irq_set_dma_handler(enum HAL_UART_ID_T id, HAL_UART_IRQ_RXDMA_HANDLER_T rxdma, HAL_UART_IRQ_TXDMA_HANDLER_T txdma); + +int hal_uart_dma_recv(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt); + +int hal_uart_dma_recv_pingpang(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt); + + +int hal_uart_dma_recv_mask(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, + const union HAL_UART_IRQ_T *mask); + +int hal_uart_dma_recv_mask_pingpang(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, + const union HAL_UART_IRQ_T *mask, uint32_t step); + +int hal_uart_dma_recv_mask_stream(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, + const union HAL_UART_IRQ_T *mask, uint32_t step); + +int hal_uart_dma_recv_mask_buf_list(enum HAL_UART_ID_T id, const struct HAL_UART_BUF_T *ubuf, uint32_t ucnt, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, const union HAL_UART_IRQ_T *mask); + +uint32_t hal_uart_get_dma_recv_addr(enum HAL_UART_ID_T id); + +uint32_t hal_uart_stop_dma_recv(enum HAL_UART_ID_T id); + +int hal_uart_dma_send(enum HAL_UART_ID_T id, const uint8_t *buf, uint32_t len, + struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt); + +uint32_t hal_uart_stop_dma_send(enum HAL_UART_ID_T id); + + +// ======================================================================== +// Test function + +int hal_uart_printf_init(void); + +void hal_uart_printf(const char *fmt, ...); + +#endif // CHIP_HAS_UART + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_usb.c b/platform/hal/hal_usb.c new file mode 100644 index 0000000..7796075 --- /dev/null +++ b/platform/hal/hal_usb.c @@ -0,0 +1,2735 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_HAS_USB + +#include "plat_addr_map.h" +#include "reg_usb.h" +#include "hal_usb.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_timer.h" +#include "hal_sysfreq.h" +#include "hal_chipid.h" +#include "usb_descriptor.h" +#include "string.h" +#include "cmsis_nvic.h" +#include "hwtimer_list.h" +#include "pmu.h" +#ifdef CHIP_HAS_USBPHY +#include "usbphy.h" +#endif + +// TODO List: +// 1) Thread-safe issue (race condition) + +// Hardware configuration: +// GHWCFG1 = 0x00000000 +// GHWCFG2 = 0x228a5512 +// GHWCFG3 = 0x03f404e8 +// GHWCFG4 = 0x16108020 + +#define USB_TRACE(n, mask, str, ...) { if (usb_trmask & (1 << mask)) { TRACE(n, str, ##__VA_ARGS__); } } +#define USB_FUNC_ENTRY_TRACE(mask) { if (usb_trmask & (1 << mask)) { FUNC_ENTRY_TRACE(); } } + +#ifndef CHIP_BEST1000 +#define CHIP_HAS_USBIF +#endif + +#ifdef USB_HIGH_SPEED +#ifndef USB_ISO_INTERVAL +#define USB_ISO_INTERVAL 8 // ANY value larger than 1 +#endif +#if (USB_ISO_INTERVAL <= 1) +#error "Invalid USB_ISO_INTERVAL" +#endif +#else +#undef USB_ISO_INTERVAL +#define USB_ISO_INTERVAL 1 +#endif + +#ifdef SIMU_UAUD_MAX_PKT +// SEND/RECV with mps = USB_MAX_PACKET_SIZE_ISO +#define USB_FIFO_MPS_ISO_RECV USB_FIFO_MPS_ISO_SEND +#else +#ifdef USB_HIGH_SPEED +// 384K sample rate, 32 bits, 2 channels = 3072 bytes/ms +#define USB_FIFO_MPS_ISO_RECV 1200 +#else +// 192K sample rate, 16 bits, 2 channels = 768 bytes/ms +#define USB_FIFO_MPS_ISO_RECV USB_FIFO_MPS_ISO_SEND +#endif +#endif + +#define PIN_CHECK_ENABLE_INTERVAL MS_TO_TICKS(1) +#define PIN_CHECK_WAIT_RESUME_INTERVAL MS_TO_TICKS(30) +#define LPM_CHECK_INTERVAL MS_TO_TICKS(100) //(US_TO_TICKS(8 + 50) + 2) + +#define USB_SYS_FREQ HAL_CMU_FREQ_52M + +enum DEVICE_STATE { + ATTACHED, + POWERED, + DEFAULT, + ADDRESS, + CONFIGURED, +}; + +struct EPN_OUT_TRANSFER { + uint8_t *data; + uint32_t length; + bool enabled; +}; + +struct EPN_IN_TRANSFER { + const uint8_t *data; + uint32_t length; + uint16_t pkt_cnt; + bool zero_len_pkt; + bool enabled; +}; + +enum DATA_PID_T { + DATA_PID_DATA0 = 0, + DATA_PID_DATA1 = 2, + DATA_PID_DATA2 = 1, + DATA_PID_MDATA = 3, +}; + +enum USB_SLEEP_T { + USB_SLEEP_NONE, + USB_SLEEP_SUSPEND, + USB_SLEEP_L1, +}; + +static const uint32_t usb_trmask = (1 << 0); //(1 << 2) | (1 << 6) | (1 << 8); + +static struct USBC_T * const usbc = (struct USBC_T *)USB_BASE; +#ifdef CHIP_HAS_USBIF +static struct USBIF_T * const usbif = (struct USBIF_T *)(USB_BASE + 0x00040000); +#endif + +static uint16_t fifo_addr; + +static uint32_t ep0_out_buffer[USB_MAX_PACKET_SIZE_CTRL / 4]; +static uint32_t ep0_in_buffer[USB_MAX_PACKET_SIZE_CTRL / 4]; + +static struct EPN_OUT_TRANSFER epn_out_transfer[EPNUM - 1]; +static struct EPN_IN_TRANSFER epn_in_transfer[EPNUM - 1]; +#ifdef USB_HIGH_SPEED +static uint8_t epn_in_mc[EPNUM - 1]; +#endif + +static struct EP0_TRANSFER ep0_transfer; + +static struct HAL_USB_CALLBACKS callbacks; + +static volatile enum DEVICE_STATE device_state = ATTACHED; +static uint8_t device_cfg = 0; +static uint8_t currentAlternate; +static uint16_t currentInterface; + +static enum USB_SLEEP_T device_sleep_status; +static uint8_t device_pwr_wkup_status; +static uint8_t device_test_mode; + +#if defined(USB_SUSPEND) && (defined(PMU_USB_PIN_CHECK) || defined(USB_LPM)) +#ifdef USB_LPM +static bool lpm_entry; +#endif +static bool usbdev_timer_active; +static HWTIMER_ID usbdev_timer; + +static void hal_usb_stop_usbdev_timer(void); +#endif + +static void hal_usb_irq_handler(void); + +static void hal_usb_init_ep0_transfer(void) +{ + ep0_transfer.stage = NONE_STAGE; + ep0_transfer.data = NULL; + ep0_transfer.length = 0; + ep0_transfer.trx_len = 0; +} + +static void hal_usb_init_epn_transfer(void) +{ + memset(&epn_out_transfer[0], 0, sizeof(epn_out_transfer)); + memset(&epn_in_transfer[0], 0, sizeof(epn_in_transfer)); +} + +static void get_setup_packet(uint8_t *data, struct SETUP_PACKET *packet) +{ + packet->bmRequestType.direction = (data[0] & 0x80) >> 7; + packet->bmRequestType.type = (data[0] & 0x60) >> 5; + packet->bmRequestType.recipient = data[0] & 0x1f; + packet->bRequest = data[1]; + packet->wValue = (data[2] | data[3] << 8); + packet->wIndex = (data[4] | data[5] << 8); + packet->wLength = (data[6] | data[7] << 8); +} + +static void reset_epn_out_transfer(uint8_t ep) +{ + bool enabled; + + enabled = epn_out_transfer[ep - 1].enabled; + + // Clear epn_out_transfer[] before invoking the callback, + // so that ep can be restarted in the callback + memset(&epn_out_transfer[ep - 1], 0, sizeof(epn_out_transfer[0])); + + if (enabled && callbacks.epn_recv_compl[ep - 1]) { + callbacks.epn_recv_compl[ep - 1](NULL, 0, XFER_COMPL_ERROR); + } +} + +static void reset_epn_in_transfer(uint8_t ep) +{ + bool enabled; + + enabled = epn_in_transfer[ep - 1].enabled; + + // Clear epn_in_transfer[] before invoking the callback, + // so that ep can be restarted in the callback + memset(&epn_in_transfer[ep - 1], 0, sizeof(epn_in_transfer[0])); + + if (enabled && callbacks.epn_send_compl[ep - 1]) { + callbacks.epn_send_compl[ep - 1](NULL, 0, XFER_COMPL_ERROR); + } +} + +static uint32_t get_ep_type(enum EP_DIR dir, uint8_t ep) +{ + uint32_t type; + + if (ep == 0) { + return E_CONTROL; + } + + if (dir == EP_OUT) { + type = GET_BITFIELD(usbc->DOEPnCONFIG[ep - 1].DOEPCTL, USBC_EPTYPE); + } else { + type = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPTYPE); + } + + return type; +} + +static void _set_global_out_nak(void) +{ + uint32_t start; + uint32_t sts; + uint32_t ep; + + usbc->DCTL |= USBC_SGOUTNAK; + + start = hal_sys_timer_get(); + while (((usbc->GINTSTS & USBC_GOUTNAKEFF) == 0) && + (hal_sys_timer_get() - start < MS_TO_TICKS(5))) { + if (hal_sys_timer_get() - start >= US_TO_TICKS(60)) { + if ((usbc->GRSTCTL & USBC_DMAREQ) == 0) { + break; + } + } + } + + if (usbc->GINTSTS & USBC_GOUTNAKEFF) { + return; + } + + start = hal_sys_timer_get(); + while ((usbc->GINTSTS & USBC_RXFLVL) && + (hal_sys_timer_get() - start < MS_TO_TICKS(5))) { + sts = usbc->GRXSTSP; + + ep = GET_BITFIELD(sts, USBC_EPNUM); + ASSERT(ep == 0, "Global OUT NAK: Only ep0 packets can be dropped: ep=%u sts=0x%08X", ep, sts); + + // NOTE: + // Global OUT NAK pattern cannot be read out from GRXSTSP -- consumed by controller automatically when poping? + + hal_sys_timer_delay(US_TO_TICKS(60)); + if (usbc->GINTSTS & USBC_GOUTNAKEFF) { + return; + } + } + + ASSERT((usbc->GINTSTS & USBC_GOUTNAKEFF), "Global OUT NAK: Failed to recover"); +} + +static void _disable_out_ep(uint8_t ep, uint32_t set, uint32_t clr) +{ + volatile uint32_t *ctrl; + volatile uint32_t *intr; + uint32_t doepctl; + + if (ep >= EPNUM) { + return; + } + + if (ep == 0) { + ctrl = &usbc->DOEPCTL0; + intr = &usbc->DOEPINT0; + } else { + ctrl = &usbc->DOEPnCONFIG[ep - 1].DOEPCTL; + intr = &usbc->DOEPnCONFIG[ep - 1].DOEPINT; + } + + doepctl = *ctrl; + + if ((doepctl & (USBC_EPENA | USBC_USBACTEP)) == 0) { + goto _exit; + } + if ((doepctl & (USBC_EPENA | USBC_NAKSTS)) == USBC_NAKSTS && set == USBC_SNAK && clr == 0) { + goto _exit; + } + + _set_global_out_nak(); + + *ctrl |= USBC_SNAK | USBC_USBACTEP | set; + + if (clr) { + *ctrl &= ~clr; + } + + // EP0 out cannot be disabled, but stalled + if (ep != 0) { + if (doepctl & USBC_EPENA) { + *intr = USBC_EPDISBLD; + *ctrl |= USBC_EPDIS; + while ((*intr & USBC_EPDISBLD) == 0); + } + + if ((doepctl & USBC_USBACTEP) == 0) { + *ctrl &= ~USBC_USBACTEP; + } + } + + usbc->DCTL |= USBC_CGOUTNAK; + +_exit: + if (ep > 0) { + reset_epn_out_transfer(ep); + } +} + +static void _disable_in_ep(uint8_t ep, uint32_t set, uint32_t clr) +{ + volatile uint32_t *ctrl; + volatile uint32_t *intr; + uint32_t diepctl; + + if (ep >= EPNUM) { + return; + } + + if (ep == 0) { + ctrl = &usbc->DIEPCTL0; + intr = &usbc->DIEPINT0; + } else { + ctrl = &usbc->DIEPnCONFIG[ep - 1].DIEPCTL; + intr = &usbc->DIEPnCONFIG[ep - 1].DIEPINT; + } + + diepctl = *ctrl; + + if ((diepctl & (USBC_EPENA | USBC_USBACTEP)) == 0) { + goto _exit; + } + if ((diepctl & (USBC_EPENA | USBC_NAKSTS)) == USBC_NAKSTS && set == USBC_SNAK && clr == 0) { + goto _exit; + } + + *intr = USBC_INEPNAKEFF; + *ctrl |= USBC_SNAK | USBC_USBACTEP | set; + if ((diepctl & USBC_EPENA) && (diepctl & USBC_NAKSTS) == 0) { + while ((*intr & USBC_INEPNAKEFF) == 0); + *intr = USBC_INEPNAKEFF; + } + + if (clr) { + *ctrl &= ~clr; + } + + if (diepctl & USBC_EPENA) { + *intr = USBC_EPDISBLD; + *ctrl |= USBC_EPDIS; + while ((*intr & USBC_EPDISBLD) == 0); + } + + usbc->GRSTCTL = USBC_TXFNUM(ep) | USBC_TXFFLSH; + while ((usbc->GRSTCTL & USBC_TXFFLSH) != 0); + + if ((diepctl & USBC_USBACTEP) == 0) { + *ctrl &= ~USBC_USBACTEP; + } + +_exit: + if (ep > 0) { + reset_epn_in_transfer(ep); + } +} + +void hal_usb_disable_ep(enum EP_DIR dir, uint8_t ep) +{ + USB_TRACE(3,14, "%s: %d ep%d", __FUNCTION__, dir, ep); + + if (dir == EP_OUT) { + _disable_out_ep(ep, USBC_SNAK, 0); + } else { + _disable_in_ep(ep, USBC_SNAK, 0); + } +} + +void hal_usb_stall_ep(enum EP_DIR dir, uint8_t ep) +{ + uint32_t set; + uint32_t clr; + + USB_TRACE(3,13, "%s: %d ep%d", __FUNCTION__, dir, ep); + + set = USBC_STALL; + clr = 0; + + if (dir == EP_OUT) { + _disable_out_ep(ep, set, clr); + } else { + _disable_in_ep(ep, set, clr); + } +} + +void hal_usb_unstall_ep(enum EP_DIR dir, uint8_t ep) +{ + uint32_t set; + uint32_t clr; + uint8_t type; + + USB_TRACE(3,12, "%s: %d ep%d", __FUNCTION__, dir, ep); + + set = USBC_SNAK; + clr = USBC_STALL; + + type = get_ep_type(dir, ep); + if (type == E_INTERRUPT || type == E_BULK) { + set |= USBC_SETD0PID; + } + + if (hal_usb_get_ep_stall_state(dir, ep) == 0) { + // Ep not in stall state + if (ep != 0 && (type == E_INTERRUPT || type == E_BULK)) { + if (dir == EP_OUT) { + usbc->DOEPnCONFIG[ep - 1].DOEPCTL |= USBC_SETD0PID; + } else { + usbc->DIEPnCONFIG[ep - 1].DIEPCTL |= USBC_SETD0PID; + } + } + return; + } + + if (dir == EP_OUT) { + _disable_out_ep(ep, set, clr); + } else { + _disable_in_ep(ep, set, clr); + } +} + +int hal_usb_get_ep_stall_state(enum EP_DIR dir, uint8_t ep) +{ + volatile uint32_t *ctrl; + + if (ep >= EPNUM) { + return 0; + } + + // Select ctl register + if(ep == 0) { + if (dir == EP_IN) { + ctrl = &usbc->DIEPCTL0; + } else { + ctrl = &usbc->DOEPCTL0; + } + } else { + if (dir == EP_IN) { + ctrl = &usbc->DIEPnCONFIG[ep - 1].DIEPCTL; + } else { + ctrl = &usbc->DOEPnCONFIG[ep - 1].DOEPCTL; + } + } + + return ((*ctrl & USBC_STALL) != 0); +} + +void hal_usb_stop_ep(enum EP_DIR dir, uint8_t ep) +{ + USB_TRACE(3,11, "%s: %d ep%d", __FUNCTION__, dir, ep); + + hal_usb_disable_ep(dir, ep); +} + +static void hal_usb_stop_all_out_eps(void) +{ + int i; + volatile uint32_t *ctrl; + volatile uint32_t *intr; + uint32_t doepctl; + + USB_FUNC_ENTRY_TRACE(11); + + // Enable global out nak + _set_global_out_nak(); + + for (i = 0; i < EPNUM; i++) { + if (i == 0) { + ctrl = &usbc->DOEPCTL0; + intr = &usbc->DOEPINT0; + } else { + ctrl = &usbc->DOEPnCONFIG[i - 1].DOEPCTL; + intr = &usbc->DOEPnCONFIG[i - 1].DOEPINT; + } + + doepctl = *ctrl; + + // BUS RESET will clear USBC_USBACTEP but keep USBC_EPENA in ep ctrl + if (doepctl & (USBC_EPENA | USBC_USBACTEP)) { + *ctrl |= USBC_SNAK | USBC_USBACTEP; + // EP0 out cannot be disabled, but stalled + if (i != 0) { + if (doepctl & USBC_EPENA) { + *intr = USBC_EPDISBLD; + *ctrl |= USBC_EPDIS; + while ((*intr & USBC_EPDISBLD) == 0); + } + if ((doepctl & USBC_USBACTEP) == 0) { + *ctrl &= ~USBC_USBACTEP; + } + } + } + } + + // Disable global out nak + usbc->DCTL |= USBC_CGOUTNAK; +} + +static void hal_usb_stop_all_in_eps(void) +{ + int i; + volatile uint32_t *ctrl; + volatile uint32_t *intr; + uint32_t diepctl; + + USB_FUNC_ENTRY_TRACE(11); + + usbc->DCTL |= USBC_SGNPINNAK; + while ((usbc->GINTSTS & USBC_GINNAKEFF) == 0); + + for (i = 0; i < EPNUM; i++) { + if (i == 0) { + ctrl = &usbc->DIEPCTL0; + intr = &usbc->DIEPINT0; + } else { + ctrl = &usbc->DIEPnCONFIG[i - 1].DIEPCTL; + intr = &usbc->DIEPnCONFIG[i - 1].DIEPINT; + } + + diepctl = *ctrl; + + // BUS RESET will clear USBC_USBACTEP but keep USBC_EPENA in ep ctrl + if (diepctl & (USBC_EPENA | USBC_USBACTEP)) { + *intr = USBC_INEPNAKEFF; + *ctrl |= USBC_SNAK | USBC_USBACTEP; + if ((diepctl & USBC_EPENA) && (diepctl & USBC_NAKSTS) == 0) { + while ((*intr & USBC_INEPNAKEFF) == 0); + *intr = USBC_INEPNAKEFF; + } + if (diepctl & USBC_EPENA) { + *intr = USBC_EPDISBLD; + *ctrl |= USBC_EPDIS; + while ((*intr & USBC_EPDISBLD) == 0); + } + if ((diepctl & USBC_USBACTEP) == 0) { + *ctrl &= ~USBC_USBACTEP; + } + } + } + + // Flush Tx Fifo + usbc->GRSTCTL = USBC_TXFNUM(0x10) | USBC_TXFFLSH | USBC_RXFFLSH; + while ((usbc->GRSTCTL & (USBC_TXFFLSH | USBC_RXFFLSH)) != 0); + + usbc->DCTL |= USBC_CGNPINNAK; +} + +static void hal_usb_flush_tx_fifo(uint8_t ep) +{ + usbc->DCTL |= USBC_SGNPINNAK; + while ((usbc->GINTSTS & USBC_GINNAKEFF) == 0); + + while ((usbc->GRSTCTL & USBC_AHBIDLE) == 0); + + //while ((usbc->GRSTCTL & USBC_TXFFLSH) != 0); + + usbc->GRSTCTL = USBC_TXFNUM(ep) | USBC_TXFFLSH; + while ((usbc->GRSTCTL & USBC_TXFFLSH) != 0); + + usbc->DCTL |= USBC_CGNPINNAK; +} + +static void hal_usb_flush_all_tx_fifos(void) +{ + hal_usb_flush_tx_fifo(0x10); +} + +static void POSSIBLY_UNUSED hal_usb_flush_rx_fifo(void) +{ + _set_global_out_nak(); + + usbc->GRSTCTL |= USBC_RXFFLSH; + while ((usbc->GRSTCTL & USBC_RXFFLSH) != 0); + + usbc->DCTL |= USBC_CGOUTNAK; +} + +static void hal_usb_alloc_ep0_fifo(void) +{ + uint32_t ram_size; + uint32_t ram_avail; + + if ((usbc->GHWCFG2 & USBC_DYNFIFOSIZING) == 0) { + return; + } + + // All endpoints have been stopped in hal_usb_irq_reset() + + // Configure FIFOs + + // RX FIFO Calculation + // ------------------- + // SETUP Packets : 4 * n + 6 + // Global OUT NAK : 1 + // DATA Packets + Status Info : (MPS / 4 + 1) * m + // OutEp XFER COMPL : 1 * outEpNum + // OutEp Disable : 1 * outEpNum + +#ifdef USB_ISO +#define RXFIFOSIZE ((4 * CTRL_EPNUM + 6) + 1 + (2 * (USB_FIFO_MPS_ISO_RECV / 4 + 1)) + (EPNUM * 2)) +#else +#define RXFIFOSIZE ((4 * CTRL_EPNUM + 6) + 1 + (2 * (USB_MAX_PACKET_SIZE_BULK / 4 + 1)) + (EPNUM * 2)) +#endif +#define EP0_TXFIFOSIZE (2 * (USB_MAX_PACKET_SIZE_CTRL + 3) / 4) + +#if (RXFIFOSIZE + EP0_TXFIFOSIZE > SPFIFORAM_SIZE) +#error "Invalid FIFO size configuration" +#endif + + ram_size = GET_BITFIELD(usbc->GDFIFOCFG, USBC_GDFIFOCFG); + ram_avail = GET_BITFIELD(usbc->GDFIFOCFG, USBC_EPINFOBASEADDR); + + ASSERT(SPFIFORAM_SIZE == ram_size, "Bad dfifo size: %u (should be %u)", ram_size, SPFIFORAM_SIZE); + ASSERT(RXFIFOSIZE + EP0_TXFIFOSIZE <= ram_avail, "Bad dfifo size cfg: rx=%u ep0=%u avail=%u", RXFIFOSIZE, EP0_TXFIFOSIZE, ram_avail); + + // Rx Fifo Size (and init fifo_addr) + usbc->GRXFSIZ = USBC_RXFDEP(RXFIFOSIZE); + fifo_addr = RXFIFOSIZE; + + // EP0 / Non-periodic Tx Fifo Size + usbc->GNPTXFSIZ = USBC_NPTXFSTADDR(fifo_addr) | USBC_NPTXFDEPS(EP0_TXFIFOSIZE); + fifo_addr += EP0_TXFIFOSIZE; + + // Flush Tx FIFOs + hal_usb_flush_all_tx_fifos(); +} + +static void hal_usb_alloc_epn_fifo(uint8_t ep, uint16_t mps) +{ + uint16_t size; + uint32_t ram_avail; + + if (ep == 0 || ep >= EPNUM) { + return; + } + + size = (mps + 3) / 4 * 2; + + ram_avail = GET_BITFIELD(usbc->GDFIFOCFG, USBC_EPINFOBASEADDR); + + ASSERT(fifo_addr + size <= ram_avail, + "Fifo overflow: fifo_addr=%u, size=%u, avail=%u", + fifo_addr, size, ram_avail); + + usbc->DTXFSIZE[ep - 1].DIEPTXFn = USBC_INEPNTXFSTADDR(fifo_addr) | USBC_INEPNTXFDEP(size); + fifo_addr += size; +} + +static void hal_usb_soft_reset(void) +{ + usbc->GRSTCTL |= USBC_CSFTRST; + while ((usbc->GRSTCTL & USBC_CSFTRST) != 0); + while ((usbc->GRSTCTL & USBC_AHBIDLE) == 0); +} + +static void hal_usb_init_phy(void) +{ +#ifdef USB_HIGH_SPEED + usbc->GUSBCFG |= USBC_FORCEDEVMODE | USBC_ULPIAUTORES | USBC_ULPIFSLS | USBC_ULPI_UTMI_SEL; + usbc->GUSBCFG &= ~(USBC_FSINTF | USBC_PHYIF | USBC_PHYSEL | USBC_USBTRDTIM_MASK); +#else + usbc->GUSBCFG |= USBC_FORCEDEVMODE | USBC_ULPIAUTORES | USBC_ULPIFSLS | + USBC_PHYSEL | USBC_ULPI_UTMI_SEL; + usbc->GUSBCFG &= ~(USBC_FSINTF | USBC_PHYIF | USBC_USBTRDTIM_MASK); +#endif + // USB turnaround time = 4 * AHB Clock + 1 PHY Clock, in terms of PHY clocks. + // If AHB Clock >= PHY Clock, time can be set to 5. + // If AHB Clock * 2 == PHY Clock, time should be set to 9. + usbc->GUSBCFG |= USBC_USBTRDTIM(5); +} + +static void hal_usb_device_init(void) +{ + int i; + uint8_t speed; + +#ifdef CHIP_HAS_USBPHY + usbphy_open(); +#endif + +#ifdef USB_HIGH_SPEED +#ifdef CHIP_HAS_USBIF + usbif->USBIF_00 &= ~(USBIF_00_CFG_DR_SUSPEND | USBIF_00_CFG_REG_SUSPEND); + usbif->USBIF_08 &= ~USBIF_08_CFG_SEL48M; +#endif + speed = 0; +#else +#ifdef CHIP_HAS_USBIF + usbif->USBIF_00 |= USBIF_00_CFG_DR_SUSPEND | USBIF_00_CFG_REG_SUSPEND; + usbif->USBIF_08 |= USBIF_08_CFG_SEL48M; +#endif + speed = 3; +#endif + +#ifdef CHIP_BEST2000 + if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { + // dr_suspend and reg_suspend are inverted since metal 1 + usbif->USBIF_00 ^= USBIF_00_CFG_DR_SUSPEND | USBIF_00_CFG_REG_SUSPEND; + } +#endif + +#ifdef USB_HIGH_SPEED + // Wait until usbphy clock is ready + hal_sys_timer_delay(US_TO_TICKS(60)); +#endif + + hal_usb_soft_reset(); + hal_usb_init_phy(); + // Reset after selecting PHY + hal_usb_soft_reset(); + // Some core cfg (except for PHY selection) will also be reset during soft reset + hal_usb_init_phy(); + + usbc->DCFG &= ~(USBC_DEVSPD_MASK | USBC_PERFRINT_MASK); + usbc->DCFG |= USBC_DEVSPD(speed) | USBC_NZSTSOUTHSHK | USBC_PERFRINT(0); + + // Clear previous interrupts + usbc->GINTMSK = 0; + usbc->GINTSTS = ~0UL; + usbc->DAINTMSK = 0; + usbc->DOEPMSK = 0; + usbc->DIEPMSK = 0; + for (i = 0; i < EPNUM; ++i) { + if (i == 0) { + usbc->DOEPINT0 = ~0UL; + usbc->DIEPINT0 = ~0UL; + } else { + usbc->DOEPnCONFIG[i - 1].DOEPINT = ~0UL; + usbc->DIEPnCONFIG[i - 1].DIEPINT = ~0UL; + } + } + usbc->GINTMSK = USBC_USBRST | USBC_ENUMDONE | USBC_ERLYSUSP | USBC_USBSUSP; + + usbc->DCTL &= ~USBC_SFTDISCON; +#if (USB_ISO_INTERVAL > 1) + // Not to check frame number and ignore ISO incomplete interrupts + usbc->DCTL |= USBC_IGNRFRMNUM; +#endif + + // Enable DMA mode + // Burst size 16 words + usbc->GAHBCFG = USBC_DMAEN | USBC_HBSTLEN(7); + usbc->GAHBCFG |= USBC_GLBLINTRMSK; +} + +static void hal_usb_soft_disconnect(void) +{ + // Disable global interrupt + usbc->GAHBCFG &= ~USBC_GLBLINTRMSK; + // Soft disconnection + usbc->DCTL |= USBC_SFTDISCON; + + hal_usb_device_init(); +} + +static void enable_usb_irq(void) +{ + NVIC_SetVector(USB_IRQn, (uint32_t)hal_usb_irq_handler); +#ifdef USB_ISO + NVIC_SetPriority(USB_IRQn, IRQ_PRIORITY_HIGH); +#else + NVIC_SetPriority(USB_IRQn, IRQ_PRIORITY_NORMAL); +#endif + NVIC_ClearPendingIRQ(USB_IRQn); + NVIC_EnableIRQ(USB_IRQn); +} + +int hal_usb_open(const struct HAL_USB_CALLBACKS *c, enum HAL_USB_API_MODE m) +{ + if (c == NULL) { + return 1; + } + if (c->device_desc == NULL || + c->cfg_desc == NULL || + c->string_desc == NULL || + c->setcfg == NULL) { + return 2; + } + + if (device_state != ATTACHED) { + return 3; + } + device_state = POWERED; + device_sleep_status = USB_SLEEP_NONE; + + hal_sysfreq_req(HAL_SYSFREQ_USER_USB, USB_SYS_FREQ); + +#if defined(USB_SUSPEND) && (defined(PMU_USB_PIN_CHECK) || defined(USB_LPM)) + if (usbdev_timer == NULL) { + usbdev_timer = hwtimer_alloc(NULL, NULL); + ASSERT(usbdev_timer, "Failed to alloc usbdev_timer"); + } +#endif + + hal_cmu_usb_set_device_mode(); + hal_cmu_usb_clock_enable(); + + memcpy(&callbacks, c, sizeof(callbacks)); + + if (usbc->GAHBCFG & USBC_GLBLINTRMSK) { + hal_usb_soft_disconnect(); + } else { + hal_usb_device_init(); + } + + enable_usb_irq(); + + if (m == HAL_USB_API_BLOCKING) { + while (device_state != CONFIGURED); + } + + return 0; +} + +int hal_usb_reopen(const struct HAL_USB_CALLBACKS *c, uint8_t dcfg, uint8_t alt, uint16_t itf) +{ + if (c == NULL) { + return 1; + } + if (c->device_desc == NULL || + c->cfg_desc == NULL || + c->string_desc == NULL || + c->setcfg == NULL) { + return 2; + } + + hal_sysfreq_req(HAL_SYSFREQ_USER_USB, USB_SYS_FREQ); + + memcpy(&callbacks, c, sizeof(callbacks)); + + device_state = CONFIGURED; + device_cfg = dcfg; + currentAlternate = alt; + currentInterface = itf; + + enable_usb_irq(); + + return 0; +} + +void hal_usb_close(void) +{ +#ifdef USB_SUSPEND +#if defined(PMU_USB_PIN_CHECK) || defined(USB_LPM) + // Stop pin check timer + hal_usb_stop_usbdev_timer(); +#ifdef PMU_USB_PIN_CHECK + // Disabe PMU pin status check + pmu_usb_disable_pin_status_check(); +#endif +#endif +#endif + + NVIC_DisableIRQ(USB_IRQn); + + device_state = ATTACHED; + + // Disable global interrupt + usbc->GAHBCFG &= ~USBC_GLBLINTRMSK; + // Soft disconnection + usbc->DCTL |= USBC_SFTDISCON; + // Soft reset + usbc->GRSTCTL |= USBC_CSFTRST; + usbc->DCTL |= USBC_SFTDISCON; + usbc->GRSTCTL |= USBC_CSFTRST; + //while ((usbc->GRSTCTL & USBC_CSFTRST) != 0); + //while ((usbc->GRSTCTL & USBC_AHBIDLE) == 0); + +#ifdef CHIP_HAS_USBPHY + usbphy_close(); +#endif + + hal_cmu_usb_clock_disable(); + + memset(&callbacks, 0, sizeof(callbacks)); + + hal_sysfreq_req(HAL_SYSFREQ_USER_USB, HAL_CMU_FREQ_32K); +} + +void hal_usb_detect_disconn(void) +{ + // NOTE: + // PHY detects the disconnection event by DP/DN voltage level change. + // But DP/DN voltages are provided by vusb ldo inside chip, which has nothing + // to do with VBUS. That is why USB controller cannot generate the disconnection + // interrupt. + // Meanwhile VBUS detection or charger detection can help to generate USB + // disconnection event via this function. + + USB_FUNC_ENTRY_TRACE(26); + + if (device_state != ATTACHED && callbacks.state_change) { + callbacks.state_change(HAL_USB_EVENT_DISCONNECT, 0); + } +} + +int hal_usb_configured(void) +{ + return (device_state == CONFIGURED); +} + +int hal_usb_suspended(void) +{ + return (device_sleep_status == USB_SLEEP_SUSPEND); +} + +uint32_t hal_usb_get_soffn(void) +{ + return GET_BITFIELD(usbc->DSTS, USBC_SOFFN); +} + +#ifdef USB_HIGH_SPEED +uint32_t hal_usb_calc_hshb_ep_mps(uint32_t pkt_size) +{ + // For high speed, high bandwidth endpoints + if (pkt_size <= USB_MAX_PACKET_SIZE_ISO) { + return pkt_size; + } else if (pkt_size > USB_MAX_PACKET_SIZE_ISO && pkt_size <= USB_MAX_PACKET_SIZE_ISO * 2) { + return ALIGN(pkt_size / 2, 4); + } else { + // if (pkt_size > USB_MAX_PACKET_SIZE_ISO * 2 && pkt_size <= USB_MAX_PACKET_SIZE_ISO * 3) + return ALIGN(pkt_size / 3, 4); + } +} +#endif + +int hal_usb_activate_epn(enum EP_DIR dir, uint8_t ep, uint8_t type, uint16_t mps) +{ + uint32_t fifo_mps; + + USB_TRACE(3,10, "%s: %d ep%d", __FUNCTION__, dir, ep); + + if (ep == 0 || ep >= EPNUM) { + return 1; + } + + if (dir == EP_OUT) { + // Stop ep out + if (usbc->DOEPnCONFIG[ep - 1].DOEPCTL & (USBC_EPENA | USBC_USBACTEP)) { + hal_usb_stop_ep(dir, ep); + } + // Config ep out + usbc->DOEPnCONFIG[ep - 1].DOEPCTL = + USBC_EPN_MPS(mps) | USBC_EPTYPE(type) | + USBC_USBACTEP | USBC_SNAK | USBC_SETD0PID; + // Unstall ep out + usbc->DOEPnCONFIG[ep - 1].DOEPCTL &= ~USBC_STALL; + // Unmask ep out interrupt + usbc->DAINTMSK |= USBC_OUTEPMSK(1 << ep); + } else { + fifo_mps = mps; +#ifdef USB_HIGH_SPEED + if (type == E_ISOCHRONOUS || type == E_INTERRUPT) { + if (mps > USB_FIFO_MPS_ISO_SEND) { + fifo_mps = USB_FIFO_MPS_ISO_SEND; + } + epn_in_mc[ep - 1] = 1; + } +#endif + // Stop ep in + if (usbc->DIEPnCONFIG[ep - 1].DIEPCTL & (USBC_EPENA | USBC_USBACTEP)) { + hal_usb_stop_ep(dir, ep); + } + // Config ep in + usbc->DIEPnCONFIG[ep - 1].DIEPCTL = + USBC_EPN_MPS(mps) | USBC_EPTYPE(type) | + USBC_USBACTEP | USBC_EPTXFNUM(ep) | USBC_SNAK | USBC_SETD0PID; + // Allocate tx fifo + hal_usb_alloc_epn_fifo(ep, fifo_mps); + // Unstall ep in + usbc->DIEPnCONFIG[ep - 1].DIEPCTL &= ~USBC_STALL; + // Unmask ep in interrupt + usbc->DAINTMSK |= USBC_INEPMSK(1 << ep); + } + + return 0; +} + +int hal_usb_deactivate_epn(enum EP_DIR dir, uint8_t ep) +{ + USB_TRACE(3,9, "%s: %d ep%d", __FUNCTION__, dir, ep); + + if (ep == 0 || ep >= EPNUM) { + return 1; + } + + hal_usb_stop_ep(dir, ep); + + if (dir == EP_OUT) { + usbc->DOEPnCONFIG[ep - 1].DOEPCTL &= ~USBC_USBACTEP; + // Mask ep out interrupt + usbc->DAINTMSK &= ~ USBC_OUTEPMSK(1 << ep); + } else { + usbc->DIEPnCONFIG[ep - 1].DIEPCTL &= ~USBC_USBACTEP; + // Mask ep in interrupt + usbc->DAINTMSK &= ~ USBC_INEPMSK(1 << ep); + } + + return 0; +} + +// NOTE: Not support send epn mps change, which will involve tx fifo reallocation +int hal_usb_update_recv_epn_mps(uint8_t ep, uint16_t mps) +{ + uint8_t type; + + USB_TRACE(3,9, "%s: ep%d mps=%u", __FUNCTION__, ep, mps); + + if (ep == 0 || ep >= EPNUM) { + return 1; + } + + if ((usbc->DOEPnCONFIG[ep - 1].DOEPCTL & USBC_USBACTEP) == 0) { + return 2; + } + + hal_usb_stop_ep(EP_OUT, ep); + + usbc->DOEPnCONFIG[ep - 1].DOEPCTL &= ~USBC_USBACTEP; + // Mask ep out interrupt + usbc->DAINTMSK &= ~ USBC_OUTEPMSK(1 << ep); + // Config ep out + type = GET_BITFIELD(usbc->DOEPnCONFIG[ep - 1].DOEPCTL, USBC_EPTYPE); + usbc->DOEPnCONFIG[ep - 1].DOEPCTL = + USBC_EPN_MPS(mps) | USBC_EPTYPE(type) | + USBC_USBACTEP | USBC_SNAK | USBC_SETD0PID; + // Unmask ep out interrupt + usbc->DAINTMSK |= USBC_OUTEPMSK(1 << ep); + + return 0; +} + +int hal_usb_update_send_epn_mc(uint8_t ep, uint8_t mc) +{ +#ifdef USB_HIGH_SPEED + uint8_t type; + + USB_TRACE(3,9, "%s: ep%d mc=%u", __FUNCTION__, ep, mc); + + if (ep == 0 || ep >= EPNUM) { + return 1; + } + + if (mc < 1 || mc > 3) { + return 3; + } + + if ((usbc->DIEPnCONFIG[ep - 1].DIEPCTL & USBC_USBACTEP) == 0) { + return 2; + } + + type = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPTYPE); + if (type == E_INTERRUPT || type == E_ISOCHRONOUS) { + epn_in_mc[ep - 1] = mc; + return 0; + } +#endif + + return 4; +} + +static void hal_usb_recv_ep0(void) +{ + USB_FUNC_ENTRY_TRACE(8); + + // Enable EP0 to receive a new setup packet + usbc->DOEPTSIZ0 = USBC_SUPCNT(3) | USBC_OEPXFERSIZE0(USB_MAX_PACKET_SIZE_CTRL) | USBC_OEPPKTCNT0; + usbc->DOEPDMA0 = (uint32_t)ep0_out_buffer; + usbc->DOEPINT0 = usbc->DOEPINT0; + usbc->DOEPCTL0 |= USBC_CNAK | USBC_EPENA; +} + +static void hal_usb_send_ep0(const uint8_t *data, uint16_t size) +{ + USB_TRACE(2,8, "%s: %d", __FUNCTION__, size); + ASSERT(size <= USB_MAX_PACKET_SIZE_CTRL, "Invalid ep0 send size: %d", size); + + if (data && size) { + memcpy(ep0_in_buffer, data, size); + } + + // Enable EP0 to send one packet + usbc->DIEPTSIZ0 = USBC_IEPXFERSIZE0(size) | USBC_IEPPKTCNT0(1); + usbc->DIEPDMA0 = (uint32_t)ep0_in_buffer; + usbc->DIEPINT0 = usbc->DIEPINT0; + usbc->DIEPCTL0 |= USBC_CNAK | USBC_EPENA; +} + +int hal_usb_recv_epn(uint8_t ep, uint8_t *buffer, uint32_t size) +{ + uint16_t mps; + uint32_t pkt; + uint32_t xfer; + uint32_t fn = 0; +#ifdef USB_ISO + bool isoEp; + uint32_t lock; +#endif + + USB_TRACE(3,7, "%s: ep%d %d", __FUNCTION__, ep, size); + + if (device_state != CONFIGURED) { + return 1; + } + if (ep == 0 || ep > EPNUM) { + return 2; + } + if (((uint32_t)buffer & 0x3) != 0) { + return 3; + } + if (epn_out_transfer[ep - 1].data != NULL) { + return 4; + } + if ((usbc->DOEPnCONFIG[ep - 1].DOEPCTL & USBC_USBACTEP) == 0) { + return 5; + } + mps = GET_BITFIELD(usbc->DOEPnCONFIG[ep - 1].DOEPCTL, USBC_EPN_MPS); + mps = ALIGN(mps, 4); + if (size < mps) { + return 6; + } + + if (size > EPN_MAX_XFERSIZE) { + return 7; + } + pkt = size / mps; + if (pkt > EPN_MAX_PKTCNT) { + return 8; + } + xfer = pkt * mps; + if (size != xfer) { + return 9; + } + + usbc->DOEPnCONFIG[ep - 1].DOEPTSIZ = USBC_OEPXFERSIZE(xfer) | USBC_OEPPKTCNT(pkt); + usbc->DOEPnCONFIG[ep - 1].DOEPDMA = (uint32_t)buffer; + usbc->DOEPnCONFIG[ep - 1].DOEPINT = usbc->DOEPnCONFIG[ep - 1].DOEPINT; + + epn_out_transfer[ep - 1].data = buffer; + epn_out_transfer[ep - 1].length = xfer; + epn_out_transfer[ep - 1].enabled = true; + +#ifdef USB_ISO + if (GET_BITFIELD(usbc->DOEPnCONFIG[ep - 1].DOEPCTL, USBC_EPTYPE) == E_ISOCHRONOUS) { + isoEp = true; + } else { + isoEp = false; + } + if (isoEp) { + // Set the frame number in time + lock = int_lock(); + // Get next frame number + if (GET_BITFIELD(usbc->DSTS, USBC_SOFFN) & 0x1) { + fn = USBC_SETD0PID; + } else { + fn = USBC_SETD1PID; + } + } +#endif + + usbc->DOEPnCONFIG[ep - 1].DOEPCTL |= USBC_EPENA | USBC_CNAK | fn; + +#ifdef USB_ISO + if (isoEp) { + int_unlock(lock); + } +#endif + + return 0; +} + +int hal_usb_send_epn(uint8_t ep, const uint8_t *buffer, uint32_t size, enum ZLP_STATE zlp) +{ + uint16_t mps; + uint8_t type; + uint32_t pkt; + uint32_t fn = 0; +#ifdef USB_ISO + bool isoEp; + uint32_t lock; +#endif + + USB_TRACE(3,6, "%s: ep%d %d", __FUNCTION__, ep, size); + + if (device_state != CONFIGURED) { + return 1; + } + if (ep == 0 || ep > EPNUM) { + return 2; + } + if (((uint32_t)buffer & 0x3) != 0) { + return 3; + } + if (epn_in_transfer[ep - 1].data != NULL) { + return 4; + } + if ((usbc->DIEPnCONFIG[ep - 1].DIEPCTL & USBC_USBACTEP) == 0) { + return 5; + } + if (size > EPN_MAX_XFERSIZE) { + return 7; + } + mps = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPN_MPS); + if (size <= mps) { + // Also taking care of 0 size packet + pkt = 1; + } else { + // If mps is not aligned in 4 bytes, application should add padding at the end of each packet to + // make sure a new packet always starts at 4-byte boundary + pkt = (size + mps - 1) / mps; + if (pkt > EPN_MAX_PKTCNT) { + return 8; + } + } + + type = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPTYPE); + if (type == E_INTERRUPT || type == E_ISOCHRONOUS) { +#ifdef USB_HIGH_SPEED + if (pkt != epn_in_mc[ep - 1] && (pkt % epn_in_mc[ep - 1])) { + // MC is the pkt cnt must be sent in every (micro)frame. + // The total pkt cnt should be integral multiple of MC value. + return 9; + } +#endif + // Never send a zero length packet at the end of transfer + epn_in_transfer[ep - 1].zero_len_pkt = false; + usbc->DIEPnCONFIG[ep - 1].DIEPTSIZ = USBC_IEPXFERSIZE(size) | USBC_IEPPKTCNT(pkt) | +#ifdef USB_HIGH_SPEED + USBC_MC(epn_in_mc[ep - 1]); +#else + USBC_MC(1); +#endif + } else { + // Check if a zero length packet is needed at the end of transfer + if (zlp == ZLP_AUTO) { + epn_in_transfer[ep - 1].zero_len_pkt = ((size % mps) == 0); + } else { + epn_in_transfer[ep - 1].zero_len_pkt = false; + } + usbc->DIEPnCONFIG[ep - 1].DIEPTSIZ = USBC_IEPXFERSIZE(size) | USBC_IEPPKTCNT(pkt); + } + usbc->DIEPnCONFIG[ep - 1].DIEPDMA = (uint32_t)buffer; + usbc->DIEPnCONFIG[ep - 1].DIEPINT = usbc->DIEPnCONFIG[ep - 1].DIEPINT; + + epn_in_transfer[ep - 1].data = buffer; + epn_in_transfer[ep - 1].length = size; + epn_in_transfer[ep - 1].pkt_cnt = pkt; + epn_in_transfer[ep - 1].enabled = true; + +#ifdef USB_ISO + if (GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPTYPE) == E_ISOCHRONOUS) { + isoEp = true; + } else { + isoEp = false; + } + if (isoEp) { + // Set the frame number in time + lock = int_lock(); + // Get next frame number + if (GET_BITFIELD(usbc->DSTS, USBC_SOFFN) & 0x1) { + fn = USBC_SETD0PID; + } else { + fn = USBC_SETD1PID; + } + } +#endif + + usbc->DIEPnCONFIG[ep - 1].DIEPCTL |= USBC_EPENA | USBC_CNAK | fn; + +#ifdef USB_ISO + if (isoEp) { + int_unlock(lock); + } +#endif + + return 0; +} + +static void hal_usb_recv_epn_complete(uint8_t ep, uint32_t statusEp) +{ + uint8_t *data; + uint32_t size; + uint32_t doeptsiz; + enum XFER_COMPL_STATE state = XFER_COMPL_SUCCESS; + + USB_TRACE(3,5, "%s: ep%d 0x%08x", __FUNCTION__, ep, statusEp); + + if (!epn_out_transfer[ep - 1].enabled) { + return; + } + + doeptsiz = usbc->DOEPnCONFIG[ep - 1].DOEPTSIZ; + + data = epn_out_transfer[ep - 1].data; + size = GET_BITFIELD(doeptsiz, USBC_OEPXFERSIZE); + ASSERT(size <= epn_out_transfer[ep - 1].length, + "Invalid xfer size: size=%d, len=%d", size, epn_out_transfer[ep - 1].length); + size = epn_out_transfer[ep - 1].length - size; + +#ifdef USB_ISO + uint32_t doepctl = usbc->DOEPnCONFIG[ep - 1].DOEPCTL; + + if (GET_BITFIELD(doepctl, USBC_EPTYPE) == E_ISOCHRONOUS) { +#if (USB_ISO_INTERVAL == 1) +#if 1 + if (GET_BITFIELD(doeptsiz, USBC_OEPPKTCNT) != 0) { + state = XFER_COMPL_ERROR; + } +#else + uint32_t rxdpid = GET_BITFIELD(doeptsiz, USBC_RXDPID); + uint32_t pkt = epn_out_transfer[ep - 1].length / GET_BITFIELD(doepctl, USBC_EPN_MPS) + - GET_BITFIELD(doeptsiz, USBC_OEPPKTCNT); + if ((rxdpid == DATA_PID_DATA0 && pkt != 1) || + (rxdpid == DATA_PID_DATA1 && pkt != 2) || + (rxdpid == DATA_PID_DATA2 && pkt != 3)) { + state = XFER_COMPL_ERROR; + } +#endif +#else // USB_ISO_INTERVAL != 1 + if (statusEp & USBC_PKTDRPSTS) { + state = XFER_COMPL_ERROR; + } +#endif // USB_ISO_INTERVAL != 1 + } +#endif // USB_ISO + + // Clear epn_out_transfer[] before invoking the callback, + // so that ep can be restarted in the callback + memset(&epn_out_transfer[ep - 1], 0, sizeof(epn_out_transfer[0])); + + if (callbacks.epn_recv_compl[ep - 1]) { + callbacks.epn_recv_compl[ep - 1](data, size, state); + } +} + +static void hal_usb_send_epn_complete(uint8_t ep, uint32_t statusEp) +{ + const uint8_t *data; + uint32_t size; + uint16_t pkt, mps; + uint8_t type; + uint32_t mc; + enum XFER_COMPL_STATE state = XFER_COMPL_SUCCESS; + + USB_TRACE(3,4, "%s: ep%d 0x%08x", __FUNCTION__, ep, statusEp); + + if (!epn_in_transfer[ep - 1].enabled) { + return; + } + + if ((statusEp & USBC_XFERCOMPLMSK) == 0) { + state = XFER_COMPL_ERROR; + } + + pkt = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPTSIZ, USBC_IEPPKTCNT); + if (pkt != 0) { + state = XFER_COMPL_ERROR; + mps = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPN_MPS); + ASSERT(pkt <= epn_in_transfer[ep - 1].pkt_cnt, "Invalid pkt cnt: pkt=%d, pkt_cnt=%d", + pkt, epn_in_transfer[ep - 1].pkt_cnt); + size = (epn_in_transfer[ep - 1].pkt_cnt - pkt) * mps; + } else { + size = epn_in_transfer[ep - 1].length; + } + + if (state == XFER_COMPL_SUCCESS && epn_in_transfer[ep - 1].zero_len_pkt) { + epn_in_transfer[ep - 1].zero_len_pkt = false; + // Send the last zero length packet, except for isochronous/interrupt endpoints + type = GET_BITFIELD(usbc->DIEPnCONFIG[ep - 1].DIEPCTL, USBC_EPTYPE); + if (type == E_INTERRUPT || type == E_ISOCHRONOUS) { +#ifdef USB_HIGH_SPEED + mc = USBC_MC(epn_in_mc[ep - 1]); +#else + mc = USBC_MC(1); +#endif + } else { + mc = 0; + } + usbc->DIEPnCONFIG[ep - 1].DIEPTSIZ = USBC_IEPXFERSIZE(0) | USBC_IEPPKTCNT(1) | mc; + usbc->DIEPnCONFIG[ep - 1].DIEPCTL |= USBC_EPENA | USBC_CNAK; + } else { + data = epn_in_transfer[ep - 1].data; + + // Clear epn_in_transfer[] before invoking the callback, + // so that ep can be restarted in the callback + memset(&epn_in_transfer[ep - 1], 0, sizeof(epn_in_transfer[0])); + + if (state != XFER_COMPL_SUCCESS) { + // The callback will not be invoked when stopping ep, + // for epn_in_transfer[] has been cleared + hal_usb_stop_ep(EP_IN, ep); + } + + if (callbacks.epn_send_compl[ep - 1]) { + callbacks.epn_send_compl[ep - 1](data, size, state); + } + } + +} + +static bool requestSetAddress(void) +{ + USB_FUNC_ENTRY_TRACE(25); + + /* Set the device address */ + usbc->DCFG = SET_BITFIELD(usbc->DCFG, USBC_DEVADDR, ep0_transfer.setup_pkt.wValue); + ep0_transfer.stage = STATUS_IN_STAGE; + + if (ep0_transfer.setup_pkt.wValue == 0) + { + device_state = DEFAULT; + } + else + { + device_state = ADDRESS; + } + + return true; +} + +static bool requestSetConfiguration(void) +{ + USB_FUNC_ENTRY_TRACE(24); + + device_cfg = ep0_transfer.setup_pkt.wValue; + /* Set the device configuration */ + if (device_cfg == 0) + { + /* Not configured */ + device_state = ADDRESS; + } + else + { + if (callbacks.setcfg && callbacks.setcfg(device_cfg)) + { + /* Valid configuration */ + device_state = CONFIGURED; + ep0_transfer.stage = STATUS_IN_STAGE; + } + else + { + return false; + } + } + + return true; +} + +static bool requestGetConfiguration(void) +{ + USB_FUNC_ENTRY_TRACE(23); + + /* Send the device configuration */ + ep0_transfer.data = &device_cfg; + ep0_transfer.length = sizeof(device_cfg); + ep0_transfer.stage = DATA_IN_STAGE; + return true; +} + +static bool requestGetInterface(void) +{ + USB_FUNC_ENTRY_TRACE(22); + + /* Return the selected alternate setting for an interface */ + if (device_state != CONFIGURED) + { + return false; + } + + /* Send the alternate setting */ + ep0_transfer.setup_pkt.wIndex = currentInterface; + ep0_transfer.data = ¤tAlternate; + ep0_transfer.length = sizeof(currentAlternate); + ep0_transfer.stage = DATA_IN_STAGE; + return true; +} + +static bool requestSetInterface(void) +{ + bool success = false; + + USB_FUNC_ENTRY_TRACE(21); + + if(callbacks.setitf && callbacks.setitf(ep0_transfer.setup_pkt.wIndex, ep0_transfer.setup_pkt.wValue)) + { + success = true; + currentInterface = ep0_transfer.setup_pkt.wIndex; + currentAlternate = ep0_transfer.setup_pkt.wValue; + ep0_transfer.stage = STATUS_IN_STAGE; + } + return success; +} + +static bool requestSetFeature(void) +{ + bool success = false; + + USB_FUNC_ENTRY_TRACE(20); + + if (device_state != CONFIGURED) + { + /* Endpoint or interface must be zero */ + if (ep0_transfer.setup_pkt.wIndex != 0) + { + return false; + } + } + + switch (ep0_transfer.setup_pkt.bmRequestType.recipient) + { + case DEVICE_RECIPIENT: + if (ep0_transfer.setup_pkt.wValue == TEST_MODE) { + // TODO: Check test mode + device_test_mode = (ep0_transfer.setup_pkt.wIndex >> 8); + success = true; + } +#ifdef USB_SUSPEND + else if (ep0_transfer.setup_pkt.wValue == DEVICE_REMOTE_WAKEUP) { + if (callbacks.set_remote_wakeup) { + callbacks.set_remote_wakeup(1); + device_pwr_wkup_status |= DEVICE_STATUS_REMOTE_WAKEUP; + success = true; + } + } +#endif + break; + case ENDPOINT_RECIPIENT: + if (ep0_transfer.setup_pkt.wValue == ENDPOINT_HALT) + { + // TODO: Check endpoint number + hal_usb_stall_ep((ep0_transfer.setup_pkt.wIndex & 0x80) ? EP_IN : EP_OUT, + ep0_transfer.setup_pkt.wIndex & 0xF); + if (callbacks.state_change) { + callbacks.state_change(HAL_USB_EVENT_STALL, ep0_transfer.setup_pkt.wIndex & 0xFF); + } + success = true; + } + break; + default: + break; + } + + ep0_transfer.stage = STATUS_IN_STAGE; + + return success; +} + +static bool requestClearFeature(void) +{ + bool success = false; + + USB_FUNC_ENTRY_TRACE(19); + + if (device_state != CONFIGURED) + { + /* Endpoint or interface must be zero */ + if (ep0_transfer.setup_pkt.wIndex != 0) + { + return false; + } + } + + switch (ep0_transfer.setup_pkt.bmRequestType.recipient) + { + case DEVICE_RECIPIENT: +#ifdef USB_SUSPEND + if (ep0_transfer.setup_pkt.wValue == DEVICE_REMOTE_WAKEUP) { + if (callbacks.set_remote_wakeup) { + callbacks.set_remote_wakeup(0); + device_pwr_wkup_status &= ~DEVICE_STATUS_REMOTE_WAKEUP; + success = true; + } + } +#endif + break; + case ENDPOINT_RECIPIENT: + /* TODO: We should check that the endpoint number is valid */ + if (ep0_transfer.setup_pkt.wValue == ENDPOINT_HALT) + { + hal_usb_unstall_ep((ep0_transfer.setup_pkt.wIndex & 0x80) ? EP_IN : EP_OUT, + ep0_transfer.setup_pkt.wIndex & 0xF); + if (callbacks.state_change) { + callbacks.state_change(HAL_USB_EVENT_UNSTALL, ep0_transfer.setup_pkt.wIndex & 0xFF); + } + success = true; + } + break; + default: + break; + } + + ep0_transfer.stage = STATUS_IN_STAGE; + + return success; +} + +static bool requestGetStatus(void) +{ + static uint16_t status; + bool success = false; + + USB_FUNC_ENTRY_TRACE(18); + + if (device_state != CONFIGURED) + { + /* Endpoint or interface must be zero */ + if (ep0_transfer.setup_pkt.wIndex != 0) + { + return false; + } + } + + switch (ep0_transfer.setup_pkt.bmRequestType.recipient) + { + case DEVICE_RECIPIENT: + status = device_pwr_wkup_status; + success = true; + break; + case INTERFACE_RECIPIENT: + status = 0; + success = true; + break; + case ENDPOINT_RECIPIENT: + /* TODO: We should check that the endpoint number is valid */ + if (hal_usb_get_ep_stall_state((ep0_transfer.setup_pkt.wIndex & 0x80) ? EP_IN : EP_OUT, + ep0_transfer.setup_pkt.wIndex & 0xF)) + { + status = ENDPOINT_STATUS_HALT; + } + else + { + status = 0; + } + success = true; + break; + default: + break; + } + + if (success) + { + /* Send the status */ + ep0_transfer.data = (uint8_t *)&status; /* Assumes little endian */ + ep0_transfer.length = sizeof(status); + ep0_transfer.stage = DATA_IN_STAGE; + } + + return success; +} + +static bool requestGetDescriptor(void) +{ + bool success = false; + uint8_t type; + uint8_t index; + uint8_t *desc; + + type = DESCRIPTOR_TYPE(ep0_transfer.setup_pkt.wValue); + index = DESCRIPTOR_INDEX(ep0_transfer.setup_pkt.wValue); + + USB_TRACE(3,3, "%s: %d %d", __FUNCTION__, type, index); + + switch (type) + { + case DEVICE_DESCRIPTOR: + desc = (uint8_t *)callbacks.device_desc(type); + if (desc != NULL) + { + if ((desc[0] == DEVICE_DESCRIPTOR_LENGTH) \ + && (desc[1] == DEVICE_DESCRIPTOR)) + { + ep0_transfer.length = desc[0]; + ep0_transfer.data = desc; + success = true; + } + } + break; + case CONFIGURATION_DESCRIPTOR: + desc = (uint8_t *)callbacks.cfg_desc(index); + if (desc != NULL) + { + if ((desc[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \ + && (desc[1] == CONFIGURATION_DESCRIPTOR)) + { + /* Get wTotalLength */ + ep0_transfer.length = desc[2] | (desc[3] << 8); + ep0_transfer.data = desc; + // Get self-powered status + if ((desc[7] >> 6) & 0x01) { + device_pwr_wkup_status |= DEVICE_STATUS_SELF_POWERED; + } else { + device_pwr_wkup_status &= ~DEVICE_STATUS_SELF_POWERED; + } + success = true; + } + } + break; + case STRING_DESCRIPTOR: + ep0_transfer.data = (uint8_t *)callbacks.string_desc(index); + if (ep0_transfer.data) { + ep0_transfer.length = ep0_transfer.data[0]; + success = true; + } + break; + case INTERFACE_DESCRIPTOR: + case ENDPOINT_DESCRIPTOR: + /* TODO: Support is optional, not implemented here */ + break; + case QUALIFIER_DESCRIPTOR: +#ifdef USB_HIGH_SPEED + desc = (uint8_t *)callbacks.device_desc(type); + if (desc != NULL) + { + if (desc[0] == QUALIFIER_DESCRIPTOR_LENGTH && desc[1] == type) + { + ep0_transfer.length = desc[0]; + ep0_transfer.data = desc; + success = true; + } + } +#endif + break; + case BOS_DESCRIPTOR: +#ifdef USB_HIGH_SPEED + desc = (uint8_t *)callbacks.device_desc(type); + if (desc != NULL) + { + if (desc[0] == BOS_DESCRIPTOR_LENGTH && desc[1] == type) + { + // Total length + ep0_transfer.length = desc[2]; + ep0_transfer.data = desc; + success = true; + } + } +#endif + break; + default: + // Might be a class or vendor specific descriptor, which + // should be handled in setuprecv callback + USB_TRACE(1,0, "*** Error: Unknown desc type: %d", type); + break; + } + + if (success) { + ep0_transfer.stage = DATA_IN_STAGE; + } + + return success; +} + +static void hal_usb_reset_all_transfers(void) +{ + int ep; + + USB_FUNC_ENTRY_TRACE(31); + + for (ep = 1; ep < EPNUM; ep++) { + reset_epn_out_transfer(ep); + reset_epn_in_transfer(ep); + } +} + +static bool hal_usb_handle_setup(void) +{ + bool success = false; + enum DEVICE_STATE old_state; + + USB_FUNC_ENTRY_TRACE(17); + + old_state = device_state; + + /* Process standard requests */ + if (ep0_transfer.setup_pkt.bmRequestType.type == STANDARD_TYPE) + { + switch (ep0_transfer.setup_pkt.bRequest) + { + case GET_STATUS: + success = requestGetStatus(); + break; + case CLEAR_FEATURE: + success = requestClearFeature(); + break; + case SET_FEATURE: + success = requestSetFeature(); + break; + case SET_ADDRESS: + success = requestSetAddress(); + break; + case GET_DESCRIPTOR: + success = requestGetDescriptor(); + break; + case SET_DESCRIPTOR: + /* TODO: Support is optional, not implemented here */ + success = false; + break; + case GET_CONFIGURATION: + success = requestGetConfiguration(); + break; + case SET_CONFIGURATION: + success = requestSetConfiguration(); + break; + case GET_INTERFACE: + success = requestGetInterface(); + break; + case SET_INTERFACE: + success = requestSetInterface(); + break; + default: + break; + } + } + + if (old_state == CONFIGURED && device_state != CONFIGURED) { + hal_usb_reset_all_transfers(); + } + + return success; +} + +static int hal_usb_ep0_setup_stage(uint32_t statusEp) +{ + uint8_t *data; + uint8_t setup_cnt; + uint16_t pkt_len; + + // Skip the check on IN/OUT tokens + usbc->DOEPMSK &= ~USBC_OUTTKNEPDISMSK; + usbc->DIEPMSK &= ~USBC_INTKNTXFEMPMSK; + + if (statusEp & USBC_BACK2BACKSETUP) { + data = (uint8_t *)(usbc->DOEPDMA0 - 8); + } else { + setup_cnt = GET_BITFIELD(usbc->DOEPTSIZ0, USBC_SUPCNT); + if (setup_cnt >= 3) { + setup_cnt = 2; + } + data = (uint8_t *)((uint32_t)ep0_out_buffer + 8 * (2 - setup_cnt)); + } + // Init new transfer + hal_usb_init_ep0_transfer(); + ep0_transfer.stage = SETUP_STAGE; + get_setup_packet(data, &ep0_transfer.setup_pkt); + + USB_TRACE(5,2, "Got SETUP type=%d, req=0x%x, val=0x%x, idx=0x%x, len=%d", + ep0_transfer.setup_pkt.bmRequestType.type, + ep0_transfer.setup_pkt.bRequest, + ep0_transfer.setup_pkt.wValue, + ep0_transfer.setup_pkt.wIndex, + ep0_transfer.setup_pkt.wLength); + + if (ep0_transfer.setup_pkt.wLength == 0 && ep0_transfer.setup_pkt.bmRequestType.direction != EP_OUT) { + USB_TRACE(0,0, "*** Error: Ep0 dir should be out if wLength=0"); + return 1; + } + + if (callbacks.setuprecv == NULL || !callbacks.setuprecv(&ep0_transfer)) { + if (!hal_usb_handle_setup()) { + return 1; + } + } + +#if 0 + if (ep0_transfer.setup_pkt.wLength == 0) { + ep0_transfer.setup_pkt.bmRequestType.direction = EP_OUT; + } +#endif + + if (ep0_transfer.stage == DATA_OUT_STAGE) { + if (ep0_transfer.data == NULL) { + ep0_transfer.data = (uint8_t *)ep0_out_buffer; + } + } else if (ep0_transfer.stage == DATA_IN_STAGE) { + if (ep0_transfer.length > ep0_transfer.setup_pkt.wLength) { + ep0_transfer.length = ep0_transfer.setup_pkt.wLength; + } + pkt_len = ep0_transfer.length; + if (pkt_len > USB_MAX_PACKET_SIZE_CTRL) { + pkt_len = USB_MAX_PACKET_SIZE_CTRL; + } + hal_usb_send_ep0(ep0_transfer.data, pkt_len); + } else if(ep0_transfer.stage == STATUS_IN_STAGE) { + hal_usb_send_ep0(NULL, 0); + } else { + USB_TRACE(1,0, "*** Setup stage switches to invalid stage: %d", ep0_transfer.stage); + return 1; + } + + return 0; +} + +static int hal_usb_ep0_data_out_stage(void) +{ + uint16_t pkt_len; + uint16_t reg_size; + + reg_size = GET_BITFIELD(usbc->DOEPTSIZ0, USBC_OEPXFERSIZE0); + + ASSERT(reg_size <= USB_MAX_PACKET_SIZE_CTRL, "Invalid ep0 recv size"); + + pkt_len = MIN(USB_MAX_PACKET_SIZE_CTRL - reg_size, (uint16_t)(ep0_transfer.length - ep0_transfer.trx_len)); + + ASSERT(ep0_transfer.length >= ep0_transfer.trx_len + pkt_len, + "Invalid ep0 recv len: length=%u trx_len=%u pkt_len=%u", ep0_transfer.length, ep0_transfer.trx_len, pkt_len); + + memcpy(ep0_transfer.data + ep0_transfer.trx_len, ep0_out_buffer, pkt_len); + ep0_transfer.trx_len += pkt_len; + + // Always enable setup packet receiving + // CAUTION: Start ep0 recv before invoking datarecv callbacks to handle all kinds of endpoints. + // Some USBC events are triggered by patterns in receive FIFO, only when these + // patterns are popped by the core (DMA reading) or the application (usbc->GRXSTSP reading). + // E.g., Global OUT NAK (DCTL.SGOUTNak) triggers GINTSTS.GOUTNakEff, but the interrupt will + // never raise in data out stage without DMA or usbc->GRXSTSP reading. + hal_usb_recv_ep0(); + + pkt_len = ep0_transfer.length - ep0_transfer.trx_len; + if (pkt_len == 0) { + if (callbacks.datarecv == NULL || !callbacks.datarecv(&ep0_transfer)) { + //hal_usb_stall_ep(EP_OUT, 0); + //hal_usb_stall_ep(EP_IN, 0); + //return; + } + ep0_transfer.stage = STATUS_IN_STAGE; + // Check error on IN/OUT tokens + usbc->DOEPMSK |= USBC_OUTTKNEPDISMSK; + // Send status packet + hal_usb_send_ep0(NULL, 0); + } else { + // Receive next data packet + } + + return 0; +} + +static int hal_usb_ep0_data_in_stage(void) +{ + uint16_t pkt_len; + bool zero_len_pkt = false; + + ASSERT(GET_BITFIELD(usbc->DIEPTSIZ0, USBC_IEPPKTCNT0) == 0, "Invalid ep0 sent pkt cnt"); + ASSERT(ep0_transfer.length >= ep0_transfer.trx_len, "Invalid ep0 sent len 1: length=%u trx_len=%u", ep0_transfer.length, ep0_transfer.trx_len); + + pkt_len = ep0_transfer.length - ep0_transfer.trx_len; + if (pkt_len == 0) { + // The last zero length packet was sent successfully + ep0_transfer.stage = STATUS_OUT_STAGE; + // Receive status packet (receiving is always enabled) + } else { + // Update sent count + if (pkt_len == USB_MAX_PACKET_SIZE_CTRL) { + zero_len_pkt = true; + } else if (pkt_len > USB_MAX_PACKET_SIZE_CTRL) { + pkt_len = USB_MAX_PACKET_SIZE_CTRL; + } + ep0_transfer.trx_len += pkt_len; + + ASSERT(ep0_transfer.length >= ep0_transfer.trx_len, "Invalid ep0 sent len 2: length=%u trx_len=%u", ep0_transfer.length, ep0_transfer.trx_len); + + // Send next packet + pkt_len = ep0_transfer.length - ep0_transfer.trx_len; + if (pkt_len > USB_MAX_PACKET_SIZE_CTRL) { + pkt_len = USB_MAX_PACKET_SIZE_CTRL; + } + if (pkt_len == 0) { + if (zero_len_pkt) { + // Send the last zero length packet + hal_usb_send_ep0(NULL, 0); + } else { + ep0_transfer.stage = STATUS_OUT_STAGE; + // Check error on IN/OUT tokens + usbc->DIEPMSK |= USBC_INTKNTXFEMPMSK; + // Receive status packet (receiving is always enabled) + } + } else { + hal_usb_send_ep0(ep0_transfer.data + ep0_transfer.trx_len, pkt_len); + } + } + + return 0; +} + +static int hal_usb_ep0_status_stage(void) +{ + // Done with status packet + ep0_transfer.stage = NONE_STAGE; + // Skip the check on IN/OUT tokens + usbc->DOEPMSK &= ~USBC_OUTTKNEPDISMSK; + usbc->DIEPMSK &= ~USBC_INTKNTXFEMPMSK; + + return 0; +} + +static void hal_usb_ep0_test_mode_check(void) +{ + if (device_test_mode) { + usbc->DCTL = SET_BITFIELD(usbc->DCTL, USBC_TSTCTL, device_test_mode); + device_test_mode = 0; + } +} + +static void hal_usb_handle_ep0_packet(enum EP_DIR dir, uint32_t statusEp) +{ + int ret; + + USB_TRACE(3,16, "%s: dir=%d, statusEp=0x%08x", __FUNCTION__, dir, statusEp); + + if (dir == EP_OUT) { + if ((statusEp & (USBC_XFERCOMPL | USBC_STSPHSERCVD)) == (USBC_XFERCOMPL | USBC_STSPHSERCVD)) { + // From Linux driver + if (GET_BITFIELD(usbc->DOEPTSIZ0, USBC_OEPXFERSIZE0) == USB_MAX_PACKET_SIZE_CTRL && + (usbc->DOEPTSIZ0 & USBC_OEPPKTCNT0)) { + // Abnormal case + USB_TRACE(2,0, "*** EP0 OUT empty compl with stsphsercvd: stage=%d, size=0x%08x", + ep0_transfer.stage, usbc->DOEPTSIZ0); + // Always enable setup packet receiving + hal_usb_recv_ep0(); + return; + } + } + + if (statusEp & USBC_XFERCOMPL) { + // New packet received + if (statusEp & USBC_SETUP) { + // Clean previous transfer + if (ep0_transfer.stage != NONE_STAGE) { + USB_TRACE(1,0, "*** Setup stage breaks previous stage %d", ep0_transfer.stage); + hal_usb_stop_ep(EP_IN, 0); + } + // New setup packet + ep0_transfer.stage = SETUP_STAGE; + } else if (statusEp & USBC_STUPPKTRCVD) { + // Clean previous transfer + if (ep0_transfer.stage != NONE_STAGE) { + USB_TRACE(1,0, "*** Wait setup stage breaks previous stage %d", ep0_transfer.stage); + hal_usb_stop_ep(EP_IN, 0); + } + // New setup packet received, and wait for USBC h/w state machine finished + // CAUTION: Enabling data receipt before getting USBC_SETUP interrupt might cause + // race condition in h/w, which leads to missing USBC_XFERCOMPL interrupt + // after the data has been received and acked + ep0_transfer.stage = WAIT_SETUP_STAGE; + return; + } + } else { + // No packet received + if (statusEp & USBC_SETUP) { + if (ep0_transfer.stage == WAIT_SETUP_STAGE) { + // Previous packet is setup packet + ep0_transfer.stage = SETUP_STAGE; + } else { + USB_TRACE(1,0, "*** Setup interrupt occurs in stage %d", ep0_transfer.stage); + // The setup packet has been processed + return; + } + } + } + } + + if (ep0_transfer.stage == SETUP_STAGE) { + ASSERT(dir == EP_OUT, "Invalid dir for setup stage"); + + ret = hal_usb_ep0_setup_stage(statusEp); + if (ret) { + // Error + ep0_transfer.stage = NONE_STAGE; + hal_usb_stall_ep(EP_OUT, 0); + hal_usb_stall_ep(EP_IN, 0); + // H/w will unstall EP0 automatically when a setup token is received + //hal_usb_recv_ep0(); + } + // Always enable setup packet receiving + hal_usb_recv_ep0(); + + return; + } + + if (statusEp & USBC_XFERCOMPL) { + if (dir == EP_OUT) { + if (ep0_transfer.stage == DATA_OUT_STAGE) { + hal_usb_ep0_data_out_stage(); + } else if (ep0_transfer.stage == STATUS_OUT_STAGE) { + hal_usb_ep0_status_stage(); + // Always enable setup packet receiving + hal_usb_recv_ep0(); + } else { + // Abnormal case + USB_TRACE(2,0, "*** EP0 OUT compl in stage %d with size 0x%08x", ep0_transfer.stage, usbc->DOEPTSIZ0); + // Always enable setup packet receiving + hal_usb_recv_ep0(); + } + } else { + if (ep0_transfer.stage == DATA_IN_STAGE) { + hal_usb_ep0_data_in_stage(); + } else if (ep0_transfer.stage == STATUS_IN_STAGE) { + hal_usb_ep0_status_stage(); + hal_usb_ep0_test_mode_check(); + } else { + // Abnormal case + USB_TRACE(2,0, "*** EP0 IN compl in stage %d with size 0x%08x", ep0_transfer.stage, usbc->DIEPTSIZ0); + } + } + } +} + +static void hal_usb_irq_reset(void) +{ + USB_FUNC_ENTRY_TRACE(2); + + device_state = DEFAULT; + device_pwr_wkup_status = 0; + device_sleep_status = USB_SLEEP_NONE; + + usbc->PCGCCTL &= ~USBC_STOPPCLK; + usbc->DCTL &= ~USBC_RMTWKUPSIG; + + hal_usb_reset_all_transfers(); + hal_usb_stop_all_out_eps(); + hal_usb_stop_all_in_eps(); + + // Unmask ep0 interrupts + usbc->DAINTMSK = USBC_INEPMSK(1 << 0) | USBC_OUTEPMSK(1 << 0); + usbc->DOEPMSK = USBC_XFERCOMPLMSK | USBC_SETUPMSK; + usbc->DIEPMSK = USBC_XFERCOMPLMSK | USBC_TIMEOUTMSK; + usbc->GINTMSK |= USBC_OEPINT | USBC_IEPINT +#if defined(USB_ISO) && (USB_ISO_INTERVAL == 1) + | USBC_INCOMPISOOUT | USBC_INCOMPISOIN +#endif + ; +#ifdef USB_SUSPEND + usbc->GINTMSK &= ~USBC_WKUPINT; +#endif +#ifdef USB_LPM + usbc->GINTMSK |= USBC_LPM_INT; + usbc->PCGCCTL |= USBC_ENBL_L1GATING; + usbc->GLPMCFG = SET_BITFIELD(usbc->GLPMCFG, USBC_HIRD_THRES, USB_L1_LIGHT_SLEEP_BESL) | USBC_HIRD_THRES_BIT4 | + USBC_LPMCAP | USBC_APPL1RES | USBC_ENBESL; // | USBC_ENBLSLPM; +#ifdef CHIP_HAS_USBIF + usbif->USBIF_04 = SET_BITFIELD(usbif->USBIF_04, USBIF_04_CFG_SLEEP_THSD, USB_L1_LIGHT_SLEEP_BESL); +#endif +#endif + + // Config ep0 size + hal_usb_alloc_ep0_fifo(); + // Reset device address + usbc->DCFG &= ~USBC_DEVADDR_MASK; + + hal_usb_init_ep0_transfer(); + hal_usb_init_epn_transfer(); + + if (callbacks.state_change) { + callbacks.state_change(HAL_USB_EVENT_RESET, 0); + } +} + +static void hal_usb_irq_enum_done(void) +{ + uint8_t speed; + uint8_t mps = 0; + + USB_FUNC_ENTRY_TRACE(2); + + speed = GET_BITFIELD(usbc->DSTS, USBC_ENUMSPD); + if (speed == 0) { + // High speed -- ERROR! + mps = 0; // 64 bytes + } else if (speed == 1 || speed == 3) { + // Full speed + mps = 0; // 64 bytes + } else { + // Low speed -- ERROR! + mps = 3; // 8 bytes + } + // Only support 64-byte MPS ! + mps = 0; + // Config max packet size + usbc->DIEPCTL0 = USBC_EP0_MPS(mps) | USBC_USBACTEP | USBC_EPTXFNUM(0) | USBC_SNAK; + usbc->DOEPCTL0 = USBC_EP0_MPS(mps) | USBC_USBACTEP | USBC_SNAK; + + hal_usb_recv_ep0(); +} + +#if defined(USB_ISO) && (USB_ISO_INTERVAL == 1) +static void hal_usb_irq_incomp_iso_out(void) +{ + int i; + uint32_t ctrl; + uint32_t sof_fn; + uint32_t statusEp; + + sof_fn = GET_BITFIELD(usbc->DSTS, USBC_SOFFN); + + for (i = 0; i < EPNUM - 1; i++) { + ctrl = usbc->DOEPnCONFIG[i].DOEPCTL; + if ((ctrl & USBC_EPENA) && ((ctrl >> USBC_EPDPID_SHIFT) & 1) == (sof_fn & 1) && + GET_BITFIELD(ctrl, USBC_EPTYPE) == E_ISOCHRONOUS) { + statusEp = usbc->DOEPnCONFIG[i].DOEPINT; + hal_usb_disable_ep(EP_OUT, i + 1); + break; + } + } + + if (i < EPNUM - 1) { + USB_TRACE(4,17, "%s ep%d: INT=0x%08x, SOF=0x%04x", __FUNCTION__, i + 1, statusEp, sof_fn); + } else { + USB_TRACE(1,17, "%s: No valid ISO ep", __FUNCTION__); + } +} + +static void hal_usb_irq_incomp_iso_in(void) +{ + int i; + uint32_t ctrl; + uint32_t sof_fn; + uint32_t statusEp; + + sof_fn = GET_BITFIELD(usbc->DSTS, USBC_SOFFN); + + for (i = 0; i < EPNUM - 1; i++) { + ctrl = usbc->DIEPnCONFIG[i].DIEPCTL; + if ((ctrl & USBC_EPENA) && ((ctrl >> USBC_EPDPID_SHIFT) & 1) == (sof_fn & 1) && + GET_BITFIELD(ctrl, USBC_EPTYPE) == E_ISOCHRONOUS) { + statusEp = usbc->DIEPnCONFIG[i].DIEPINT; + hal_usb_disable_ep(EP_IN, i + 1); + break; + } + } + + if (i < EPNUM - 1) { + USB_TRACE(4,17, "%s ep%d: INT=0x%08x, SOF=0x%04x", __FUNCTION__, i + 1, statusEp, sof_fn); + } else { + USB_TRACE(1,17, "%s: No valid ISO ep", __FUNCTION__); + } +} +#endif + +#ifdef USB_SUSPEND +static void hal_usb_restore_clock(void) +{ + hal_sysfreq_req(HAL_SYSFREQ_USER_USB, USB_SYS_FREQ); + +#ifdef PMU_USB_PIN_CHECK +#ifdef CHIP_HAS_USBPHY + // Enable dig phy clock + usbphy_wakeup(); +#endif + + hal_cmu_clock_enable(HAL_CMU_MOD_H_USBC); + hal_cmu_clock_enable(HAL_CMU_MOD_O_USB); +#endif + + usbc->PCGCCTL &= ~USBC_STOPPCLK; + +#ifdef PMU_USB_PIN_CHECK + NVIC_ClearPendingIRQ(USB_IRQn); + NVIC_EnableIRQ(USB_IRQn); +#endif +} + +static void hal_usb_stop_clock(void) +{ +#ifdef PMU_USB_PIN_CHECK + // Disable USB IRQ to avoid errors when RESET/RESUME is detected before stopping USB clock + NVIC_DisableIRQ(USB_IRQn); +#endif + + usbc->PCGCCTL |= USBC_STOPPCLK; + +#ifdef PMU_USB_PIN_CHECK + hal_cmu_clock_disable(HAL_CMU_MOD_O_USB); + hal_cmu_clock_disable(HAL_CMU_MOD_H_USBC); + +#ifdef CHIP_HAS_USBPHY + // Disable dig phy clock + usbphy_sleep(); +#endif +#endif + + hal_sysfreq_req(HAL_SYSFREQ_USER_USB, HAL_CMU_FREQ_32K); +} + +#ifdef PMU_USB_PIN_CHECK +static void hal_usb_pin_status_resume(enum PMU_USB_PIN_CHK_STATUS_T status); + +static void hal_usb_pin_check_enable_check(void *param) +{ + pmu_usb_enable_pin_status_check(); +} + +static void hal_usb_pin_check_cancel_resume(void *param) +{ + USB_TRACE(3,18, "[%X] %s: DSTS=0x%08x", hal_sys_timer_get(), __FUNCTION__, usbc->DSTS); + + if (usbc->DSTS & USBC_SUSPSTS) { + hal_usb_stop_clock(); + pmu_usb_enable_pin_status_check(); + } +} + +static void hal_usb_pin_status_resume(enum PMU_USB_PIN_CHK_STATUS_T status) +{ + USB_TRACE(2,18, "%s: %d", __FUNCTION__, status); + + // Start timer to check resume status, so as to avoid fake pin resume signal + if (usbdev_timer_active) { + hwtimer_stop(usbdev_timer); + } + hwtimer_update_then_start(usbdev_timer, hal_usb_pin_check_cancel_resume, NULL, PIN_CHECK_WAIT_RESUME_INTERVAL); + usbdev_timer_active = 1; + + hal_usb_restore_clock(); +} +#endif + +#if defined(PMU_USB_PIN_CHECK) || defined(USB_LPM) +static void hal_usb_stop_usbdev_timer(void) +{ + if (usbdev_timer_active) { + hwtimer_stop(usbdev_timer); + usbdev_timer_active = 0; + } +} +#endif + +static void hal_usb_sleep(enum USB_SLEEP_T cause) +{ + USB_FUNC_ENTRY_TRACE(18); + + device_sleep_status = cause; + + if (callbacks.state_change) { + callbacks.state_change((cause == USB_SLEEP_SUSPEND) ? HAL_USB_EVENT_SUSPEND : HAL_USB_EVENT_L1_DEEP_SLEEP, 0); + } + + usbc->GINTMSK |= USBC_WKUPINT; +#ifdef USB_LPM + usbc->GINTMSK &= ~USBC_LPM_INT; +#endif + + hal_usb_stop_clock(); + +#ifdef PMU_USB_PIN_CHECK + pmu_usb_config_pin_status_check(PMU_USB_PIN_CHK_HOST_RESUME, hal_usb_pin_status_resume, false); + // Stat timer to check current pin status + if (usbdev_timer_active) { + hwtimer_stop(usbdev_timer); + } + hwtimer_update_then_start(usbdev_timer, hal_usb_pin_check_enable_check, NULL, PIN_CHECK_ENABLE_INTERVAL); + usbdev_timer_active = 1; +#endif +} + +static void hal_usb_wakeup(void) +{ + USB_FUNC_ENTRY_TRACE(18); + + device_sleep_status = USB_SLEEP_NONE; + +#ifndef PMU_USB_PIN_CHECK + hal_usb_restore_clock(); +#endif + + usbc->GINTMSK &= ~USBC_WKUPINT; +#ifdef USB_LPM + usbc->GINTMSK |= USBC_LPM_INT; +#endif + + if (callbacks.state_change) { + callbacks.state_change(HAL_USB_EVENT_RESUME, 0); + } +} + +static void hal_usb_send_resume_signal(int enable) +{ + if (enable) { +#ifdef PMU_USB_PIN_CHECK + // Stop pin check timer + hal_usb_stop_usbdev_timer(); + // Disabe PMU pin status check + pmu_usb_disable_pin_status_check(); +#endif + + // Restore USB clock and IRQ + hal_usb_restore_clock(); + + usbc->GINTMSK &= ~USBC_WKUPINT; + + usbc->DCTL |= USBC_RMTWKUPSIG; + } else { + usbc->DCTL &= ~USBC_RMTWKUPSIG; + } +} +#endif + +int hal_usb_remote_wakeup(int signal) +{ +#ifdef USB_SUSPEND + USB_TRACE(2,15, "%s: %d", __FUNCTION__, signal); + + if (signal) { + if (device_sleep_status != USB_SLEEP_SUSPEND) { + return 1; + } + if ((device_pwr_wkup_status & DEVICE_STATUS_REMOTE_WAKEUP) == 0) { + return 2; + } + + hal_usb_send_resume_signal(1); + } else { + hal_usb_send_resume_signal(0); + + // USBC will NOT generate resume IRQ in case of remote wakeup, so fake one here + hal_usb_wakeup(); + } +#endif + + return 0; +} + +void hal_usb_lpm_sleep_enable(void) +{ +#ifdef USB_LPM + if (usbc->GLPMCFG & USBC_ENBESL) { + //usbc->GLPMCFG &= ~USBC_RSTRSLPSTS; + } + usbc->GLPMCFG |= (USBC_APPL1RES | USBC_HIRD_THRES_BIT4); + + usbc->PCGCCTL |= USBC_ENBL_L1GATING; +#endif +} + +void hal_usb_lpm_sleep_disable(void) +{ +#ifdef USB_LPM + uint32_t cnt; + uint32_t lock; + uint32_t lpm; + bool POSSIBLY_UNUSED rmtWake = false; + + usbc->PCGCCTL &= ~USBC_ENBL_L1GATING; + + usbc->GLPMCFG &= ~(USBC_APPL1RES | USBC_HIRD_THRES_BIT4 | USBC_ENBLSLPM); + if (usbc->GLPMCFG & USBC_ENBESL) { + usbc->GLPMCFG |= USBC_RSTRSLPSTS; + } + + lpm_entry = false; + + // Resume if in L1 state + if (usbc->GLPMCFG & USBC_SLPSTS) { + cnt = 0; + while ((usbc->GLPMCFG & (USBC_BREMOTEWAKE | USBC_SLPSTS | USBC_L1RESUMEOK)) == + (USBC_BREMOTEWAKE | USBC_SLPSTS)) { + hal_sys_timer_delay(US_TO_TICKS(0)); + if (++cnt > 3) { + break; + } + } + + lock = int_lock(); + + lpm = usbc->GLPMCFG; + + if (lpm & USBC_SLPSTS) { + if ((lpm & (USBC_BREMOTEWAKE | USBC_L1RESUMEOK)) == (USBC_BREMOTEWAKE | USBC_L1RESUMEOK)) { + hal_usb_send_resume_signal(1); + rmtWake = true; +#if 0 + // Detect race condition between remote wake and L1 state change + if ((usbc->GLPMCFG & USBC_SLPSTS) == 0) { + usbc->DCTL &= ~USBC_RMTWKUPSIG; + } +#endif +#ifdef USB_SUSPEND + if (device_sleep_status == USB_SLEEP_L1) { + // USBC will NOT generate resume IRQ in case of remote wakeup, so fake one here + hal_usb_wakeup(); + } +#endif + } else if ((lpm & (USBC_BREMOTEWAKE | USBC_L1RESUMEOK)) == USBC_BREMOTEWAKE) { + TRACE(1,"\n*** ERROR: LPM Disable: Failed to wait L1 resume OK: 0x%08X\n", lpm); + } + } + + int_unlock(lock); + + if (rmtWake) { + USB_TRACE(1,0, "LPM RmtWake: 0x%08X", lpm); + } + } +#endif +} + +#ifdef USB_LPM +#ifdef USB_SUSPEND +static void hal_usb_lpm_check(void *param) +{ + uint32_t lpm; + uint32_t lock; + + // TODO: Disable USB irq only (might conflict with hal_usb_stop_clock) + lock = int_lock(); + + lpm = usbc->GLPMCFG; + + if (lpm_entry && GET_BITFIELD(lpm, USBC_HIRD) >= USB_L1_DEEP_SLEEP_BESL) { + if ((lpm & USBC_SLPSTS) && (lpm & (USBC_BREMOTEWAKE | USBC_L1RESUMEOK)) != USBC_BREMOTEWAKE) { + lpm_entry = false; + hal_usb_sleep(USB_SLEEP_L1); + } else { + hwtimer_update_then_start(usbdev_timer, hal_usb_lpm_check, NULL, LPM_CHECK_INTERVAL); + usbdev_timer_active = 1; + } + } + + int_unlock(lock); +} +#endif + +static void hal_usb_irq_lpm(void) +{ + static const uint32_t lpm_trace_interval = MS_TO_TICKS(2000); + static uint32_t last_lpm_irq_time; + static uint32_t cnt = 0; + uint32_t time; + uint32_t lpm; + + cnt++; + lpm = usbc->GLPMCFG; + +#ifdef USB_SUSPEND + if (GET_BITFIELD(lpm, USBC_HIRD) >= USB_L1_DEEP_SLEEP_BESL) { + // Stat timer to check L1 sleep state + if (usbdev_timer_active) { + hwtimer_stop(usbdev_timer); + } + hwtimer_update_then_start(usbdev_timer, hal_usb_lpm_check, NULL, LPM_CHECK_INTERVAL); + usbdev_timer_active = 1; + lpm_entry = true; + } +#endif + + time = hal_sys_timer_get(); + if (time - last_lpm_irq_time >= lpm_trace_interval || GET_BITFIELD(lpm, USBC_HIRD) >= USB_L1_DEEP_SLEEP_BESL) { + last_lpm_irq_time = time; + USB_TRACE(6,0, "LPM IRQ: 0x%08X rmtWake=%d hird=0x%x l1Res=%d slpSts=%d cnt=%u", + lpm, !!(lpm & USBC_BREMOTEWAKE), GET_BITFIELD(lpm, USBC_HIRD), + GET_BITFIELD(lpm, USBC_COREL1RES), !!(lpm & USBC_SLPSTS), cnt); + } +} +#endif + +static void hal_usb_irq_handler(void) +{ + uint32_t status, rawStatus; + uint32_t statusEp, rawStatusEp; + uint32_t data; + uint8_t i; + + // Store interrupt flag and reset it + rawStatus = usbc->GINTSTS; + usbc->GINTSTS = rawStatus; + + status = rawStatus & (usbc->GINTMSK & (USBC_USBRST | USBC_ENUMDONE +#if defined(USB_ISO) && (USB_ISO_INTERVAL == 1) + | USBC_INCOMPISOOUT | USBC_INCOMPISOIN +#endif + | USBC_IEPINT | USBC_OEPINT + | USBC_ERLYSUSP | USBC_USBSUSP | USBC_WKUPINT + | USBC_LPM_INT)); + + USB_TRACE(3,1, "%s: 0x%08x / 0x%08x", __FUNCTION__, status, rawStatus); + +#if defined(USB_SUSPEND) && (defined(PMU_USB_PIN_CHECK) || defined(USB_LPM)) + bool stop_timer = true; + +#ifdef USB_LPM + if (lpm_entry && status == USBC_ERLYSUSP && (usbc->DSTS & USBC_ERRTICERR) == 0) { + // LPM TL1TokenRetry (8 us) timer has expired. L1 state transition will be finished + // after TL1Residency (50 us) timer from now. + stop_timer = false; + } else { + lpm_entry = false; + } +#endif + + if (stop_timer) { + hal_usb_stop_usbdev_timer(); + } +#endif + + if (status & USBC_USBRST) { + // Usb reset + hal_usb_irq_reset(); + + // We got a reset, and reseted the soft state machine: Discard all other + // interrupt causes. + status &= USBC_ENUMDONE; + } + + if (status & USBC_ENUMDONE) { + // Enumeration done + hal_usb_irq_enum_done(); + } + +#if defined(USB_ISO) && (USB_ISO_INTERVAL == 1) + if (status & USBC_INCOMPISOOUT) { + // Incomplete ISO OUT + hal_usb_irq_incomp_iso_out(); + } + + if (status & USBC_INCOMPISOIN) { + // Incomplete ISO IN + hal_usb_irq_incomp_iso_in(); + } +#endif + + if (status & USBC_IEPINT) { + // Tx + data = usbc->DAINT & usbc->DAINTMSK; + for (i = 0; i < EPNUM; ++i) { + if (data & USBC_INEPMSK(1 << i)) { + if (i == 0) { + // EP0 + rawStatusEp = usbc->DIEPINT0; + usbc->DIEPINT0 = rawStatusEp; + statusEp = rawStatusEp & usbc->DIEPMSK; + + if ((statusEp & USBC_TIMEOUT) || (statusEp & USBC_INTKNTXFEMP)) { + usbc->DIEPMSK &= ~USBC_INTKNTXFEMPMSK; + hal_usb_stall_ep(EP_IN, i); + } else if (statusEp & USBC_XFERCOMPL) { + // Handle ep0 command + hal_usb_handle_ep0_packet(EP_IN, rawStatusEp); + } + } else { + rawStatusEp = usbc->DIEPnCONFIG[i - 1].DIEPINT; + usbc->DIEPnCONFIG[i - 1].DIEPINT = rawStatusEp; + statusEp = rawStatusEp & usbc->DIEPMSK; + + if ((statusEp & USBC_TIMEOUT) || (statusEp & USBC_XFERCOMPL)) { + hal_usb_send_epn_complete(i, rawStatusEp); + } + } + } + } + } + + if (status & USBC_OEPINT) { + // Rx + data = usbc->DAINT & usbc->DAINTMSK; + for (i = 0; i < EPNUM; ++i) { + if (data & USBC_OUTEPMSK(1 << i)) { + if (i == 0) { + rawStatusEp = usbc->DOEPINT0; + usbc->DOEPINT0 = rawStatusEp; + statusEp = rawStatusEp & usbc->DOEPMSK; + + if (statusEp & USBC_OUTTKNEPDIS) { + usbc->DOEPMSK &= ~USBC_OUTTKNEPDISMSK; + hal_usb_stall_ep(EP_OUT, i); + if (statusEp & USBC_XFERCOMPL) { + // Always enable setup packet receiving + hal_usb_recv_ep0(); + } + } else if (statusEp & (USBC_XFERCOMPL | USBC_SETUP)) { + // Handle ep0 command + hal_usb_handle_ep0_packet(EP_OUT, rawStatusEp); + } + } else { + rawStatusEp = usbc->DOEPnCONFIG[i - 1].DOEPINT; + usbc->DOEPnCONFIG[i - 1].DOEPINT = rawStatusEp; + statusEp = rawStatusEp & usbc->DOEPMSK; + + if (statusEp & USBC_XFERCOMPL) { + hal_usb_recv_epn_complete(i, rawStatusEp); + } + } + } + } + } + +#ifdef USB_SUSPEND + if (status & USBC_ERLYSUSP) { + if (usbc->DSTS & USBC_ERRTICERR) { + hal_usb_soft_disconnect(); + return; + } + } + + if (status & USBC_USBSUSP) { + hal_usb_sleep(USB_SLEEP_SUSPEND); + } + + if (status & USBC_WKUPINT) { + hal_usb_wakeup(); + } +#endif + +#ifdef USB_LPM + if (status & USBC_LPM_INT) { + hal_usb_irq_lpm(); + } +#endif +} + +#endif // CHIP_HAS_USB diff --git a/platform/hal/hal_usb.h b/platform/hal/hal_usb.h new file mode 100644 index 0000000..4533273 --- /dev/null +++ b/platform/hal/hal_usb.h @@ -0,0 +1,232 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_USB_H__ +#define __HAL_USB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "stdbool.h" + +#define USB_MAX_PACKET_SIZE_CTRL 64 +#ifdef USB_HIGH_SPEED +#define USB_MAX_PACKET_SIZE_BULK 512 +#define USB_MAX_PACKET_SIZE_INT 1024 +#define USB_MAX_PACKET_SIZE_ISO 1024 +#define USB_FIFO_MPS_ISO_SEND 800 +#else +#define USB_MAX_PACKET_SIZE_BULK 64 +#define USB_MAX_PACKET_SIZE_INT 64 +#define USB_MAX_PACKET_SIZE_ISO 1023 +#define USB_FIFO_MPS_ISO_SEND 768 +#endif + +// H/w register bit field width limitation +#define EPN_MAX_PKTCNT ((1 << 10) - 1) +#define EPN_MAX_XFERSIZE ((1 << 19) - 1) + +#define EPNUM 6 +#define CTRL_EPNUM 2 + +#define USB_L1_LIGHT_SLEEP_BESL USB_BESL_125US +#define USB_L1_DEEP_SLEEP_BESL USB_BESL_6000US + +enum HAL_USB_API_MODE { + HAL_USB_API_NONBLOCKING, + HAL_USB_API_BLOCKING, +}; + +enum EP_DIR { + EP_OUT, + EP_IN, +}; + +enum CTRL_STAGE { + NONE_STAGE, + WAIT_SETUP_STAGE, + SETUP_STAGE, + DATA_OUT_STAGE, + DATA_IN_STAGE, + STATUS_OUT_STAGE, + STATUS_IN_STAGE, +}; + +enum ZLP_STATE { + ZLP_AUTO, + ZLP_DISABLED, +}; + +enum XFER_COMPL_STATE { + XFER_COMPL_SUCCESS, + XFER_COMPL_ERROR, +}; + +enum HAL_USB_STATE_EVENT { + HAL_USB_EVENT_RESET, // RESET event should be processed as quickly as possible + HAL_USB_EVENT_DISCONNECT, + HAL_USB_EVENT_SUSPEND, + HAL_USB_EVENT_L1_DEEP_SLEEP, + HAL_USB_EVENT_RESUME, + HAL_USB_EVENT_STALL, + HAL_USB_EVENT_UNSTALL, + + HAL_USB_EVENT_QTY +}; + +enum USB_BESL_T { + USB_BESL_125US = 0, + USB_BESL_150US, + USB_BESL_200US, + USB_BESL_300US, + USB_BESL_400US, + USB_BESL_500US, + USB_BESL_1000US, + USB_BESL_2000US, + USB_BESL_3000US, + USB_BESL_4000US, + USB_BESL_5000US, + USB_BESL_6000US, + USB_BESL_7000US, + USB_BESL_8000US, + USB_BESL_9000US, + USB_BESL_10000US, +}; + +enum USB_BESL_HIRD_T { + USB_BESL_HIRD_75US, + USB_BESL_HIRD_100US, + USB_BESL_HIRD_150US, + USB_BESL_HIRD_250US, + USB_BESL_HIRD_350US, + USB_BESL_HIRD_450US, + USB_BESL_HIRD_950US, + USB_BESL_HIRD_1950US, + USB_BESL_HIRD_2950US, + USB_BESL_HIRD_3950US, + USB_BESL_HIRD_4950US, + USB_BESL_HIRD_5950US, + USB_BESL_HIRD_6950US, + USB_BESL_HIRD_7950US, + USB_BESL_HIRD_8950US, + USB_BESL_HIRD_9950US, +}; + +enum USB_HIRD_T { + USB_HIRD_50US, + USB_HIRD_125US, + USB_HIRD_200US, + USB_HIRD_275US, + USB_HIRD_350US, + USB_HIRD_425US, + USB_HIRD_500US, + USB_HIRD_575US, + USB_HIRD_650US, + USB_HIRD_725US, + USB_HIRD_800US, + USB_HIRD_875US, + USB_HIRD_950US, + USB_HIRD_1025US, + USB_HIRD_1100US, + USB_HIRD_1175US, +}; + +struct SETUP_PACKET { + struct { + uint8_t recipient : 5; + uint8_t type : 2; + uint8_t direction : 1; + } bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +}; + +struct EP0_TRANSFER { + enum CTRL_STAGE stage; + uint8_t *data; + uint16_t length; + uint16_t trx_len; + struct SETUP_PACKET setup_pkt; +}; + +typedef const uint8_t *(*HAL_USB_GET_DESCRIPTOR_CALLBACK)(uint8_t); +typedef bool (*HAL_USB_SETUPRECV_CALLBACK)(struct EP0_TRANSFER *); +typedef bool (*HAL_USB_DATARECV_CALLBACK)(struct EP0_TRANSFER *); +typedef bool (*HAL_USB_SETCFG_CALLBACK)(uint8_t); +typedef bool (*HAL_USB_SETITF_CALLBACK)(uint16_t, uint16_t); +typedef void (*HAL_USB_REMOTE_WAKEUP_CALLBACK)(int enable); +typedef void (*HAL_USB_STATE_CHANGE_CALLBACK)(enum HAL_USB_STATE_EVENT, uint32_t); +typedef bool (*HAL_USB_RECV_COMPL_CALLBACK)(const uint8_t *, uint32_t, enum XFER_COMPL_STATE); +typedef bool (*HAL_USB_SEND_COMPL_CALLBACK)(const uint8_t *, uint32_t, enum XFER_COMPL_STATE); + +struct HAL_USB_CALLBACKS { + HAL_USB_GET_DESCRIPTOR_CALLBACK device_desc; + HAL_USB_GET_DESCRIPTOR_CALLBACK cfg_desc; + HAL_USB_GET_DESCRIPTOR_CALLBACK string_desc; + + HAL_USB_SETUPRECV_CALLBACK setuprecv; + HAL_USB_DATARECV_CALLBACK datarecv; + HAL_USB_SETCFG_CALLBACK setcfg; + HAL_USB_SETITF_CALLBACK setitf; + HAL_USB_REMOTE_WAKEUP_CALLBACK set_remote_wakeup; + HAL_USB_STATE_CHANGE_CALLBACK state_change; + + HAL_USB_RECV_COMPL_CALLBACK epn_recv_compl[EPNUM - 1]; + HAL_USB_SEND_COMPL_CALLBACK epn_send_compl[EPNUM - 1]; +}; + +int hal_usb_open(const struct HAL_USB_CALLBACKS *c, enum HAL_USB_API_MODE m); +int hal_usb_reopen(const struct HAL_USB_CALLBACKS *c, uint8_t dcfg, uint8_t alt, uint16_t itf); +void hal_usb_close(void); + +int hal_usb_remote_wakeup(int signal); +void hal_usb_detect_disconn(void); + +void hal_usb_lpm_sleep_enable(void); +void hal_usb_lpm_sleep_disable(void); + +int hal_usb_configured(void); +int hal_usb_suspended(void); + +uint32_t hal_usb_calc_hshb_ep_mps(uint32_t pkt_size); + +int hal_usb_activate_epn(enum EP_DIR dir, uint8_t ep, uint8_t type, uint16_t mps); +int hal_usb_deactivate_epn(enum EP_DIR dir, uint8_t ep); +int hal_usb_update_recv_epn_mps(uint8_t ep, uint16_t mps); +int hal_usb_update_send_epn_mc(uint8_t ep, uint8_t mc); + +void hal_usb_disable_ep(enum EP_DIR dir, uint8_t ep); + +void hal_usb_stall_ep(enum EP_DIR dir, uint8_t ep); +void hal_usb_unstall_ep(enum EP_DIR dir, uint8_t ep); +int hal_usb_get_ep_stall_state(enum EP_DIR dir, uint8_t ep); + +void hal_usb_stop_ep(enum EP_DIR dir, uint8_t ep); + +int hal_usb_recv_epn(uint8_t ep, uint8_t *buffer, uint32_t size); +int hal_usb_send_epn(uint8_t ep, const uint8_t *buffer, uint32_t size, enum ZLP_STATE zlp); + +uint32_t hal_usb_get_soffn(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_usbhost.c b/platform/hal/hal_usbhost.c new file mode 100644 index 0000000..3ec3596 --- /dev/null +++ b/platform/hal/hal_usbhost.c @@ -0,0 +1,1079 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_HAS_USB + +#include "plat_addr_map.h" +#include "reg_usb.h" +#include "hal_usbhost.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_timer.h" +#include "hal_sysfreq.h" +#include "string.h" +#include "cmsis_nvic.h" +#include "hwtimer_list.h" +#include "pmu.h" + +#define MAX_CHAN_NUM 10 +#define MAX_EP_NUM 16 + +#define MAX_XFER_SIZE (USBC_HCTSIZN_XFERSIZE_MASK >> USBC_HCTSIZN_XFERSIZE_SHIFT) +#define MAX_XFER_PKT (USBC_HCTSIZN_PKTCNT_MASK >> USBC_HCTSIZN_PKTCNT_SHIFT) + +#define HAL_USBC_PHY_FREQ_MHZ 48 +#define HAL_USBC_PHY_FREQ_MHZ_HS 60 +#define HAL_USBC_HPRT_WC_MASK \ + (USBC_HPRT_PRTSUSP | USBC_HPRT_PRTOVRCURRCHNG | USBC_HPRT_PRTENCHNG | USBC_HPRT_PRTENA | USBC_HPRT_PRTCONNDET) + +#define HAL_USBHOST_TIMEOUT_TICKS MS_TO_TICKS(200) + +#define USBHOST_TRACE(n, mask, str, ...) { if (usbhost_trmask & (1 << mask)) { TRACE(n, str, ##__VA_ARGS__); } } +#define USBHOST_FUNC_ENTRY_TRACE(mask) { if (usbhost_trmask & (1 << mask)) { FUNC_ENTRY_TRACE(); } } + +enum HAL_USBHOST_CHAN_STATE_T { + HAL_USBHOST_CHAN_IDLE, + HAL_USBHOST_CHAN_ALLOC, + HAL_USBHOST_CHAN_INIT, + HAL_USBHOST_CHAN_XFER, + + HAL_USBHOST_CHAN_QTY +}; + +struct HAL_USBHOST_CHAN_DESC_T { + enum HAL_USBHOST_CHAN_STATE_T state; + uint32_t start_xfer_size; + uint16_t start_pkt_cnt; + uint8_t err_cnt; + struct HAL_USBHOST_CHAN_TYPE_T type; + struct HAL_USBHOST_XFER_T xfer; +}; + +static const uint32_t usbhost_trmask = (1 << 0); //~0UL; //(1 << 3) | (1 << 4); + +static struct USBC_T * const usbc = (struct USBC_T *)USB_BASE; + +static HAL_USBHOST_PORT_HANDLER port_handler; +static HAL_USBHOST_DELAY_FUNC delay_func; + +static struct HAL_USBHOST_CHAN_DESC_T chan_desc[MAX_CHAN_NUM]; + +static struct HAL_USBHOST_SETUP_XFER_T setup_xfer; + +static volatile bool in_setup = false; + +static bool usbhost_opened = false; + +static enum HAL_USBHOST_SETUP_STAGE_T cur_setup_stage; + +static HWTIMER_ID usbhost_timer[MAX_CHAN_NUM]; + +#ifdef PMU_USB_PIN_CHECK +static HAL_USBHOST_PLUG_HANDLER plug_handler; +#endif + +static uint32_t hal_usbhost_get_xfer_size(uint8_t chan, int complete); +static void hal_usbhost_irq_handler(void); +static void hal_usbhost_timeout(void *param); + +void hal_usbhost_halt_chan(uint8_t chan) +{ + uint32_t mask; + + USBHOST_TRACE(2,17, "%s: %d", __FUNCTION__, chan); + + if (chan >= MAX_CHAN_NUM) { + return; + } + + hwtimer_stop(usbhost_timer[chan]); + + mask = usbc->HCSR[chan].HCINTMSKn; + usbc->HCSR[chan].HCINTMSKn = 0; + if ((usbc->HCSR[chan].HCCHARn & USBC_HCCHARN_CHENA) == 0) { + goto _exit; + } + usbc->HCSR[chan].HCINTn = USBC_HCINTN_CHHLTD; + usbc->HCSR[chan].HCCHARn |= USBC_HCCHARN_CHENA | USBC_HCCHARN_CHDIS; + while ((usbc->HCSR[chan].HCINTn & USBC_HCINTN_CHHLTD) == 0); + +_exit: + usbc->HCSR[chan].HCINTn = ~0UL; + usbc->HCSR[chan].HCINTMSKn = mask; +} + +static void hal_usbhost_soft_reset(void) +{ + usbc->GRSTCTL |= USBC_CSFTRST; + while ((usbc->GRSTCTL & USBC_CSFTRST) != 0); + while ((usbc->GRSTCTL & USBC_AHBIDLE) == 0); +} + +static void hal_usbhost_init_phy(void) +{ + usbc->GUSBCFG |= USBC_FORCEHSTMODE | USBC_ULPIAUTORES | USBC_ULPIFSLS | + USBC_PHYSEL | USBC_ULPI_UTMI_SEL; + usbc->GUSBCFG &= ~(USBC_FSINTF | USBC_PHYIF | USBC_USBTRDTIM_MASK); + // USBC_USBTRDTIM(9) if AHB bus is 26M + usbc->GUSBCFG |= USBC_USBTRDTIM(5); +} + +int hal_usbhost_open(HAL_USBHOST_PORT_HANDLER port_cb, HAL_USBHOST_DELAY_FUNC delay_fn) +{ + int i; + + USBHOST_FUNC_ENTRY_TRACE(16); + + for (i = 0; i < MAX_CHAN_NUM; i++) { + chan_desc[i].state = HAL_USBHOST_CHAN_IDLE; + } + + hal_sysfreq_req(HAL_SYSFREQ_USER_USB, HAL_CMU_FREQ_52M); + + hal_cmu_usb_set_host_mode(); + hal_cmu_usb_clock_enable(); + + hal_usbhost_soft_reset(); + hal_usbhost_init_phy(); + // Reset after selecting PHY + hal_usbhost_soft_reset(); + // Some core cfg (except for PHY selection) will also be reset during soft reset + hal_usbhost_init_phy(); + +#ifdef USB_HIGH_SPEED + usbc->HCFG = USBC_HCFG_FSLSPCLKSEL(0); +#else + usbc->HCFG = USBC_HCFG_FSLSSUPP | USBC_HCFG_FSLSPCLKSEL(1); +#endif + + usbc->HPRT = USBC_HPRT_PRTPWR; + + // Clear previous interrupts + usbc->GINTMSK = 0; + usbc->GINTSTS = ~0UL; + usbc->HAINTMSK = 0; + for (i = 0; i < MAX_CHAN_NUM; i++) { + usbc->HCSR[i].HCINTMSKn = 0; + usbc->HCSR[i].HCINTn = ~0UL; + } + usbc->GINTMSK = USBC_PRTINT | USBC_HCHINT | USBC_DISCONNINT; + + // Enable DMA mode + // Burst size 16 words + usbc->GAHBCFG = USBC_DMAEN | USBC_HBSTLEN(7); + usbc->GAHBCFG |= USBC_GLBLINTRMSK; + + port_handler = port_cb; + delay_func = delay_fn; + + usbhost_opened = true; + + NVIC_SetVector(USB_IRQn, (uint32_t)hal_usbhost_irq_handler); + NVIC_SetPriority(USB_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(USB_IRQn); + NVIC_EnableIRQ(USB_IRQn); + + //usbc->TPORTDBG1 = 0x11; + + return 0; +} + +void hal_usbhost_close(void) +{ + uint8_t chan; + + USBHOST_FUNC_ENTRY_TRACE(15); + +#ifdef PMU_USB_PIN_CHECK + pmu_usb_disable_pin_status_check(); +#endif + + NVIC_DisableIRQ(USB_IRQn); + + usbhost_opened = false; + + hal_cmu_usb_clock_disable(); + + for (chan = 0; chan < MAX_CHAN_NUM; chan++) { + hal_usbhost_free_chan(chan); + } + + hal_sysfreq_req(HAL_SYSFREQ_USER_USB, HAL_CMU_FREQ_32K); +} + +static void hal_usbhost_delay(uint32_t ms) +{ + if (delay_func) { + delay_func(ms); + } else { + hal_sys_timer_delay(MS_TO_TICKS(ms)); + } +} + +void hal_usbhost_port_reset(uint32_t ms) +{ + int lock; + + USBHOST_TRACE(2,14, "%s: %d", __FUNCTION__, ms); + + lock = int_lock(); + usbc->HPRT = (usbc->HPRT & ~HAL_USBC_HPRT_WC_MASK) | USBC_HPRT_PRTRST; + int_unlock(lock); + + hal_usbhost_delay(ms); + + lock = int_lock(); + usbc->HPRT = (usbc->HPRT & ~HAL_USBC_HPRT_WC_MASK) & ~USBC_HPRT_PRTRST; + int_unlock(lock); +} + +static void hal_usbhost_port_suspend(void) +{ + int lock; + + USBHOST_FUNC_ENTRY_TRACE(22); + + lock = int_lock(); + usbc->HPRT = (usbc->HPRT & ~HAL_USBC_HPRT_WC_MASK) | USBC_HPRT_PRTSUSP; + int_unlock(lock); + + hal_usbhost_delay(3); +} + +static void hal_usbhost_port_resume(void) +{ + int lock; + + USBHOST_FUNC_ENTRY_TRACE(22); + + lock = int_lock(); + usbc->HPRT = (usbc->HPRT & ~HAL_USBC_HPRT_WC_MASK) | USBC_HPRT_PRTRES; + int_unlock(lock); + + hal_usbhost_delay(20); + + lock = int_lock(); + usbc->HPRT = (usbc->HPRT & ~HAL_USBC_HPRT_WC_MASK) & ~USBC_HPRT_PRTRES; + int_unlock(lock); +} + +int hal_usbhost_get_chan(uint8_t *chan) +{ + int i; + uint32_t lock; + + lock = int_lock(); + for (i = 0; i < MAX_CHAN_NUM; i++) { + if (chan_desc[i].state == HAL_USBHOST_CHAN_IDLE) { + chan_desc[i].state = HAL_USBHOST_CHAN_ALLOC; + break; + } + } + int_unlock(lock); + + USBHOST_TRACE(2,13, "%s: %d", __FUNCTION__, i); + + if (i == MAX_CHAN_NUM) { + return 1; + } + + *chan = i; + + ASSERT(usbhost_timer[i] == NULL, "%s: Prev hwtimer not released: 0x%08x", __FUNCTION__, (uint32_t)usbhost_timer[i]); + usbhost_timer[i] = hwtimer_alloc(hal_usbhost_timeout, (void *)(uint32_t)i); + if (usbhost_timer[i] == NULL) { + USBHOST_TRACE(2,0, "%s: WARNING: Failed to alloc hwtimer for chan=%d", __FUNCTION__, i); + // Continue even if usbhost_timer is null + } + + return 0; +} + +int hal_usbhost_free_chan(uint8_t chan) +{ + USBHOST_TRACE(2,12, "%s: %d", __FUNCTION__, chan); + + if (chan >= MAX_CHAN_NUM) { + return 1; + } + + hwtimer_stop(usbhost_timer[chan]); + hwtimer_free(usbhost_timer[chan]); + usbhost_timer[chan] = NULL; + + chan_desc[chan].state = HAL_USBHOST_CHAN_IDLE; + + return 0; +} + +int hal_usbhost_init_chan(uint8_t chan, const struct HAL_USBHOST_CHAN_TYPE_T *type) +{ + USBHOST_TRACE(7,11, "%s: chan=%d mps=%d ep=%d in=%d type=%d addr=%d", + __FUNCTION__, chan, type->mps, type->ep_num, type->ep_in, type->ep_type, type->dev_addr); + + if (chan >= MAX_CHAN_NUM) { + return 1; + } + if (chan_desc[chan].state != HAL_USBHOST_CHAN_ALLOC) { + return 2; + } + if (usbc->HCSR[chan].HCCHARn & USBC_HCCHARN_CHENA) { + return 3; + } + if ((type->dev_addr & (USBC_HCCHARN_DEVADDR_MASK >> USBC_HCCHARN_DEVADDR_SHIFT)) != type->dev_addr) { + return 4; + } + if (type->ep_num >= MAX_EP_NUM) { + return 5; + } + if (type->ep_type >= HAL_USBHOST_EP_QTY) { + return 6; + } + if ((type->mps & (USBC_HCCHARN_MPS_MASK >> USBC_HCCHARN_MPS_SHIFT)) != type->mps) { + return 7; + } + if (type->mps == 0) { + return 8; + } + + memcpy(&chan_desc[chan].type, type, sizeof(chan_desc[chan].type)); + chan_desc[chan].err_cnt = 0; + + usbc->HCSR[chan].HCINTMSKn = 0; + usbc->HCSR[chan].HCINTn = ~0UL; + + usbc->HCSR[chan].HCCHARn = USBC_HCCHARN_MPS(type->mps) | USBC_HCCHARN_EPNUM(type->ep_num) | + (type->ep_in ? USBC_HCCHARN_EPDIR : 0) | USBC_HCCHARN_EPTYPE(type->ep_type) | + USBC_HCCHARN_DEVADDR(type->dev_addr); + + usbc->HCSR[chan].HCINTMSKn = USBC_HCINTN_AHBERR | USBC_HCINTN_CHHLTD; + usbc->HAINTMSK |= (1 << chan); + usbc->GINTMSK |= USBC_HCHINT; + + chan_desc[chan].state = HAL_USBHOST_CHAN_INIT; + + return 0; +} + +int hal_usbhost_update_chan_dev_addr(uint8_t chan, uint8_t dev_addr) +{ + USBHOST_TRACE(3,10, "%s: chan=%d dev_addr=%d", __FUNCTION__, chan, dev_addr); + + if (chan >= MAX_CHAN_NUM) { + return 1; + } + if (chan_desc[chan].state != HAL_USBHOST_CHAN_INIT) { + return 2; + } + + chan_desc[chan].type.dev_addr = dev_addr; + + usbc->HCSR[chan].HCCHARn = SET_BITFIELD(usbc->HCSR[chan].HCCHARn, USBC_HCCHARN_DEVADDR, dev_addr); + + chan_desc[chan].state = HAL_USBHOST_CHAN_INIT; + + return 0; +} + +int hal_usbhost_update_chan_mps(uint8_t chan, uint16_t mps) +{ + USBHOST_TRACE(3,9, "%s: chan=%d mps=%d", __FUNCTION__, chan, mps); + + if (chan >= MAX_CHAN_NUM) { + return 1; + } + if (chan_desc[chan].state != HAL_USBHOST_CHAN_INIT) { + return 2; + } + + chan_desc[chan].type.mps = mps; + + usbc->HCSR[chan].HCCHARn = SET_BITFIELD(usbc->HCSR[chan].HCCHARn, USBC_HCCHARN_MPS, mps); + + chan_desc[chan].state = HAL_USBHOST_CHAN_INIT; + + return 0; +} + +int hal_usbhost_start_xfer(uint8_t chan, const struct HAL_USBHOST_XFER_T *xfer) +{ + uint32_t max_periodic_len; + uint32_t pkt_cnt; + uint32_t size; + enum HAL_USBHOST_PID_TYPE_T pid; + uint8_t multi_cnt; + + USBHOST_TRACE(5,7, "%s: chan=%d size=%u mc=%d pid=%d", + __FUNCTION__, chan, xfer->size, xfer->multi_cnt, xfer->pid); + + if (chan >= MAX_CHAN_NUM) { + return 1; + } + if (chan_desc[chan].state != HAL_USBHOST_CHAN_INIT) { + return 2; + } + if (usbc->HCSR[chan].HCCHARn & USBC_HCCHARN_CHENA) { + return 3; + } + if (((uint32_t)xfer->buf & 0x3) != 0) { + return 4; + } + if (chan_desc[chan].type.ep_type == HAL_USBHOST_EP_ISO || + chan_desc[chan].type.ep_type == HAL_USBHOST_EP_INT) { + max_periodic_len = xfer->multi_cnt * chan_desc[chan].type.mps; + if (max_periodic_len < xfer->size) { + return 5; + } + } else { + if (xfer->size > MAX_XFER_SIZE) { + return 6; + } + } + + pkt_cnt = (xfer->size + (chan_desc[chan].type.mps - 1)) / chan_desc[chan].type.mps; + if (pkt_cnt > MAX_XFER_PKT) { + return 7; + } + if (pkt_cnt == 0) { + pkt_cnt = 1; + } + + if (chan_desc[chan].type.ep_in) { + size = pkt_cnt * chan_desc[chan].type.mps; + } else { + size = xfer->size; + } + + chan_desc[chan].start_xfer_size = size; + chan_desc[chan].start_pkt_cnt = pkt_cnt; + memcpy(&chan_desc[chan].xfer, xfer, sizeof(chan_desc[chan].xfer)); + + pid = xfer->pid; + if (pid == HAL_USBHOST_PID_AUTO) { + pid = GET_BITFIELD(usbc->HCSR[chan].HCTSIZn, USBC_HCTSIZN_PID); + } + multi_cnt = xfer->multi_cnt; + + if (chan_desc[chan].type.ep_type == HAL_USBHOST_EP_ISO || + chan_desc[chan].type.ep_type == HAL_USBHOST_EP_INT) { + multi_cnt = pkt_cnt; + + if (chan_desc[chan].type.ep_type == HAL_USBHOST_EP_ISO) { + pid = HAL_USBHOST_PID_DATA0; // Full speed + } + + if (usbc->HFNUM & 0x1) { + usbc->HCSR[chan].HCCHARn &= ~USBC_HCCHARN_ODDFRM; + } else { + usbc->HCSR[chan].HCCHARn |= USBC_HCCHARN_ODDFRM; + } + } + + chan_desc[chan].state = HAL_USBHOST_CHAN_XFER; + + usbc->HCSR[chan].HCTSIZn = USBC_HCTSIZN_PID(pid) | USBC_HCTSIZN_PKTCNT(pkt_cnt) | USBC_HCTSIZN_XFERSIZE(size); + usbc->HCSR[chan].HCDMAn = (uint32_t)xfer->buf; + + usbc->HCSR[chan].HCINTn = ~0UL; + + usbc->HCSR[chan].HCCHARn = SET_BITFIELD(usbc->HCSR[chan].HCCHARn, USBC_HCCHARN_EC, multi_cnt); + usbc->HCSR[chan].HCCHARn &= ~USBC_HCCHARN_CHDIS; + usbc->HCSR[chan].HCCHARn |= USBC_HCCHARN_CHENA; + + if (xfer->handler) { + hwtimer_start(usbhost_timer[chan], HAL_USBHOST_TIMEOUT_TICKS); + } + + return 0; +} + +static void hal_usbhost_setup_xfer_handler(uint8_t chan, uint8_t *buf, uint32_t len, enum HAL_USBHOST_XFER_ERR_T error) +{ + int ret; + struct HAL_USBHOST_XFER_T xfer; + enum HAL_USBHOST_SETUP_STAGE_T handler_stage; + uint8_t handler_chan; + + ret = 1; + if (error != HAL_USBHOST_XFER_ERR_NONE) { + goto _exit; + } + + USBHOST_TRACE(5,6, "%s: chan=%d cur=%d next=%d error=%d", + __FUNCTION__, chan, cur_setup_stage, setup_xfer.next_stage, error); + + handler_stage = setup_xfer.next_stage; + handler_chan = HAL_USBHOST_CHAN_NONE; + + switch (handler_stage) { + case HAL_USBHOST_SETUP_DATA_IN: + case HAL_USBHOST_SETUP_DATA_OUT: + xfer.buf = setup_xfer.data_buf; + xfer.size = setup_xfer.setup_pkt.wLength; + xfer.pid = HAL_USBHOST_PID_DATA1; + xfer.multi_cnt = 0; + xfer.handler = hal_usbhost_setup_xfer_handler; + if (handler_stage == HAL_USBHOST_SETUP_DATA_IN) { + handler_chan = setup_xfer.chan_in; + setup_xfer.next_stage = HAL_USBHOST_SETUP_STATUS_OUT; + } else { + handler_chan = setup_xfer.chan_out; + setup_xfer.next_stage = HAL_USBHOST_SETUP_STATUS_IN; + } + ret = hal_usbhost_start_xfer(handler_chan, &xfer); + if (ret) { + goto _exit; + } + break; + case HAL_USBHOST_SETUP_STATUS_IN: + case HAL_USBHOST_SETUP_STATUS_OUT: + if (cur_setup_stage == HAL_USBHOST_SETUP_DATA_IN) { + if (setup_xfer.setup_pkt.wLength != len) { + USBHOST_TRACE(2,0, "Invalid setup data length: %d expect=%d", len, setup_xfer.setup_pkt.wLength); + // Update received len + setup_xfer.setup_pkt.wLength = len; + } + } + xfer.buf = NULL; + xfer.size = 0; + xfer.pid = HAL_USBHOST_PID_DATA1; + xfer.multi_cnt = 0; + xfer.handler = hal_usbhost_setup_xfer_handler; + if (handler_stage == HAL_USBHOST_SETUP_STATUS_IN) { + handler_chan = setup_xfer.chan_in; + } else { + handler_chan = setup_xfer.chan_out; + } + setup_xfer.next_stage = HAL_USBHOST_SETUP_DONE; + ret = hal_usbhost_start_xfer(handler_chan, &xfer); + if (ret) { + goto _exit; + } + break; + case HAL_USBHOST_SETUP_DONE: + ret = 0; + goto _exit; + break; + default: + ASSERT(false, "Invalid setup next stage %d for chan %d", setup_xfer.next_stage, chan); + ret = 1; + goto _exit; + } + + cur_setup_stage = handler_stage; + + return; + +_exit: + if (error != HAL_USBHOST_XFER_ERR_NONE) { + setup_xfer.next_stage = HAL_USBHOST_SETUP_ERROR; + } + + { + struct HAL_USBHOST_SETUP_XFER_T setup; + + memcpy(&setup, &setup_xfer, sizeof(setup)); + in_setup = false; + if (setup.handler) { + setup.handler(&setup, ret); + } + } + + return; +} + +int hal_usbhost_start_setup_xfer(const struct HAL_USBHOST_SETUP_XFER_T *setup, uint32_t *recv_len) +{ + int ret; + struct HAL_USBHOST_XFER_T xfer; + + USBHOST_TRACE(7,6, "%s: out=%d in=%d type=0x%02x req=0x%02x wlen=%d next_stage=%d", + __FUNCTION__, setup->chan_out, setup->chan_in, setup->setup_pkt.bmRequestType, + setup->setup_pkt.bRequest, setup->setup_pkt.wLength, setup->next_stage); + + if (setup->next_stage >= HAL_USBHOST_SETUP_STATUS_OUT) { + return -1; + } + + if (in_setup) { + return -2; + } + in_setup = true; + + memcpy(&setup_xfer, setup, sizeof(setup_xfer)); + cur_setup_stage = HAL_USBHOST_SETUP_STAGE_QTY; + + xfer.buf = (uint8_t *)&setup_xfer.setup_pkt; + xfer.size = sizeof(setup_xfer.setup_pkt); + xfer.pid = HAL_USBHOST_PID_SETUP; + xfer.multi_cnt = 0; + xfer.handler = hal_usbhost_setup_xfer_handler; + + ret = hal_usbhost_start_xfer(setup_xfer.chan_out, &xfer); + if (ret) { + in_setup = false; + return ret; + } + + if (setup->handler == NULL) { + while (in_setup); + if (setup_xfer.next_stage != HAL_USBHOST_SETUP_DONE) { + return -3; + } + if (recv_len) { + if (setup->next_stage == HAL_USBHOST_SETUP_DATA_IN) { + *recv_len = setup_xfer.setup_pkt.wLength; + } else { + *recv_len = 0; + } + } + } + + return 0; +} + +static void hal_usbhost_stop_all_chans(void) +{ + int i; + uint32_t xfer; + HAL_USBHOST_XFER_COMPL_HANDLER handler; + uint8_t *buf; + + usbc->HAINTMSK = 0; + + for (i = 0; i < MAX_CHAN_NUM; i++) { + hal_usbhost_halt_chan(i); + + if (chan_desc[i].state != HAL_USBHOST_CHAN_XFER) { + continue; + } + + if (chan_desc[i].xfer.handler) { + // TODO: Check whether HCTSIZn is reset after channel is halted + xfer = hal_usbhost_get_xfer_size(i, 0); + + // Reset the chan_desc to INIT state so that it can be reused in callback + handler = chan_desc[i].xfer.handler; + buf = chan_desc[i].xfer.buf; + chan_desc[i].state = HAL_USBHOST_CHAN_INIT; + + handler(i, buf, xfer, HAL_USBHOST_XFER_ERR_DISCONN); + } + } + + usbc->HAINT = ~0UL; +} + +static void hal_usbhost_disconn_handler(void) +{ + USBHOST_FUNC_ENTRY_TRACE(5); + + usbc->GINTMSK &= ~USBC_HCHINT; + + hal_usbhost_stop_all_chans(); + + if (port_handler) { + port_handler(HAL_USBHOST_PORT_DISCONN); + } +} + +static void hal_usbhost_alloc_fifo(void) +{ + // FIFO configuration should be started after port enabled, or 60 ms after soft reset + + hal_usbhost_stop_all_chans(); + + // RX FIFO Calculation + // ------------------- + // DATA Packets + Status Info : (MPS / 4 + 1) * m + // OutEp XFER COMPL : 1 * m + // NAK/NYET Handling : 1 * outEpNum + +#define RXFIFOSIZE (2 * (MAX_USBHOST_PACKET_SIZE / 4 + 1 + 1) + USBHOST_EPNUM) +#define TXFIFOSIZE (2 * (MAX_USBHOST_PACKET_SIZE / 4)) + + // Rx Fifo Size (and init fifo_addr) + usbc->GRXFSIZ = USBC_RXFDEP(RXFIFOSIZE); + + // EP0 / Non-periodic Tx Fifo Size + usbc->GNPTXFSIZ = USBC_NPTXFSTADDR(RXFIFOSIZE) | USBC_NPTXFDEPS(TXFIFOSIZE); + + // Flush all FIFOs + usbc->GRSTCTL = USBC_TXFNUM(0x10) | USBC_TXFFLSH | USBC_RXFFLSH; + while ((usbc->GRSTCTL & (USBC_TXFFLSH | USBC_RXFFLSH)) != 0); +} + +static void hal_usbhost_port_handler(void) +{ + uint32_t prt; + uint32_t speed; + enum HAL_USBHOST_PORT_EVENT_T event; + + prt = usbc->HPRT; + // USBC_HPRT_PRTENA also controls the port status + usbc->HPRT = prt & ~(USBC_HPRT_PRTENA | USBC_HPRT_PRTSUSP); + + USBHOST_TRACE(2,4, "%s: 0x%08x", __FUNCTION__, prt); + + if (prt & USBC_HPRT_PRTCONNDET) { + if (port_handler) { + port_handler(HAL_USBHOST_PORT_CONN); + } + } + + if (prt & USBC_HPRT_PRTENCHNG) { + if (prt & USBC_HPRT_PRTENA) { + speed = GET_BITFIELD(usbc->HPRT,USBC_HPRT_PRTSPD); + if (speed == 1 || +#ifdef USB_HIGH_SPEED + speed == 0 || +#endif + 0) { +#ifdef USB_HIGH_SPEED + if (speed == 0) { + // High speed + usbc->HFIR = SET_BITFIELD(usbc->HFIR, USBC_HFIR_FRINT, 125 * HAL_USBC_PHY_FREQ_MHZ_HS); + event = HAL_USBHOST_PORT_EN_HS; + } else +#else + { + // Full speed + usbc->HFIR = SET_BITFIELD(usbc->HFIR, USBC_HFIR_FRINT, 1000 * HAL_USBC_PHY_FREQ_MHZ); + event = HAL_USBHOST_PORT_EN_FS; + } +#endif + // Config FIFOs + hal_usbhost_alloc_fifo(); + // Notify upper layer + if (port_handler) { + port_handler(event); + } + } else { + // High (0) or low (2) speed not supported + if (port_handler) { + port_handler(HAL_USBHOST_PORT_EN_BAD); + } + } + } + } +} + +static void hal_usbhost_retry_chan(uint8_t chan, uint32_t size) +{ + uint32_t pkt_cnt; + + USBHOST_TRACE(3,20, "%s: chan=%d size=%u", __FUNCTION__, chan, size); + +#if 0 + if (chan_desc[chan].state != HAL_USBHOST_CHAN_XFER) { + return; + } +#endif + + hal_usbhost_halt_chan(chan); + + pkt_cnt = (size + chan_desc[chan].type.mps - 1) / chan_desc[chan].type.mps; + if (pkt_cnt == 0) { + pkt_cnt = 1; + } + + usbc->HCSR[chan].HCTSIZn = (usbc->HCSR[chan].HCTSIZn & ~(USBC_HCTSIZN_PKTCNT_MASK | USBC_HCTSIZN_XFERSIZE_MASK)) | + USBC_HCTSIZN_PKTCNT(pkt_cnt) | USBC_HCTSIZN_XFERSIZE(size); + usbc->HCSR[chan].HCDMAn = (uint32_t)chan_desc[chan].xfer.buf + (chan_desc[chan].start_xfer_size - size); + + usbc->HCSR[chan].HCINTn = ~0UL; + + //usbc->HCSR[chan].HCCHARn = SET_BITFIELD(usbc->HCSR[chan].HCCHARn, USBC_HCCHARN_EC, multi_cnt); + usbc->HCSR[chan].HCCHARn &= ~USBC_HCCHARN_CHDIS; + usbc->HCSR[chan].HCCHARn |= USBC_HCCHARN_CHENA; +} + +static uint32_t hal_usbhost_get_xfer_size(uint8_t chan, int complete) +{ + uint32_t xfer; + + if (complete) { + if (chan_desc[chan].type.ep_in) { + xfer = GET_BITFIELD(usbc->HCSR[chan].HCTSIZn, USBC_HCTSIZN_XFERSIZE); + if (chan_desc[chan].start_xfer_size > xfer) { + xfer = chan_desc[chan].start_xfer_size - xfer; + } else { + xfer = 0; + } + } else { + xfer = chan_desc[chan].start_xfer_size; + } + } else { + xfer = GET_BITFIELD(usbc->HCSR[chan].HCTSIZn, USBC_HCTSIZN_PKTCNT); + if (chan_desc[chan].start_pkt_cnt > xfer) { + xfer = (chan_desc[chan].start_pkt_cnt - xfer) * chan_desc[chan].type.mps; + } else { + xfer = 0; + } + } + + return xfer; +} + +static enum HAL_USBHOST_XFER_ERR_T hal_usbhost_get_xfer_error(uint32_t irq) +{ + if (irq & USBC_HCINTN_XFERCOMPL) return HAL_USBHOST_XFER_ERR_NONE; + if (irq & USBC_HCINTN_AHBERR) return HAL_USBHOST_XFER_ERR_AHB; + if (irq & USBC_HCINTN_STALL) return HAL_USBHOST_XFER_ERR_STALL; + if (irq & USBC_HCINTN_XACTERR) return HAL_USBHOST_XFER_ERR_TRANSACTION; + if (irq & USBC_HCINTN_BBLERR) return HAL_USBHOST_XFER_ERR_BABBLE; + if (irq & USBC_HCINTN_FRMOVRUN) return HAL_USBHOST_XFER_ERR_FRAME_OVERRUN; + if (irq & USBC_HCINTN_DATATGLERR) return HAL_USBHOST_XFER_ERR_DATA_TOGGLE; + + return HAL_USBHOST_XFER_ERR_QTY; +} + +static void hal_usbhost_chan_n_handler(uint8_t chan) +{ + uint32_t raw_irq; + uint32_t irq; + uint32_t xfer; + enum HAL_USBHOST_XFER_ERR_T error; + HAL_USBHOST_XFER_COMPL_HANDLER handler; + uint8_t *buf; + + USBHOST_TRACE(2,3, "%s: %d", __FUNCTION__, chan); + + if (chan_desc[chan].state != HAL_USBHOST_CHAN_XFER) { + return; + } + + raw_irq = usbc->HCSR[chan].HCINTn; + usbc->HCSR[chan].HCINTn = raw_irq; + irq = raw_irq & usbc->HCSR[chan].HCINTMSKn; + + xfer = hal_usbhost_get_xfer_size(chan, (raw_irq & USBC_HCINTN_XFERCOMPL)); + + USBHOST_TRACE(4,18, "%s: chan=%d HCINTn=0x%08x xfer=%u", __FUNCTION__, chan, raw_irq, xfer); + + error = HAL_USBHOST_XFER_ERR_QTY; + + if (chan_desc[chan].type.ep_type == HAL_USBHOST_EP_BULK || + chan_desc[chan].type.ep_type == HAL_USBHOST_EP_CTRL) { + if (chan_desc[chan].type.ep_in) { + if (raw_irq & USBC_HCINTN_CHHLTD) { + if (raw_irq & (USBC_HCINTN_XFERCOMPL | USBC_HCINTN_STALL | USBC_HCINTN_BBLERR)) { + chan_desc[chan].err_cnt = 0; + usbc->HCSR[chan].HCINTMSKn &= ~(USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_DATATGLERR); + error = hal_usbhost_get_xfer_error(raw_irq); + } else if (raw_irq & USBC_HCINTN_XACTERR) { + if (chan_desc[chan].err_cnt >= 2) { + error = HAL_USBHOST_XFER_ERR_TRANSACTION; + } else { + chan_desc[chan].err_cnt++; + usbc->HCSR[chan].HCINTMSKn |= USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_DATATGLERR; + hal_usbhost_retry_chan(chan, chan_desc[chan].start_xfer_size - xfer); + return; + } + } + } else if (raw_irq & (USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_DATATGLERR)) { + chan_desc[chan].err_cnt = 0; + usbc->HCSR[chan].HCINTMSKn &= ~(USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_DATATGLERR); + return; + } + } else { + if (raw_irq & USBC_HCINTN_CHHLTD) { + if (raw_irq & (USBC_HCINTN_XFERCOMPL | USBC_HCINTN_STALL)) { + chan_desc[chan].err_cnt = 0; + usbc->HCSR[chan].HCINTMSKn &= ~(USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_NYET); + error = hal_usbhost_get_xfer_error(raw_irq); + } else if (raw_irq & USBC_HCINTN_XACTERR) { + if (chan_desc[chan].err_cnt >= 2) { + usbc->HCSR[chan].HCINTMSKn &= ~(USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_NYET); + error = HAL_USBHOST_XFER_ERR_TRANSACTION; + } else { + chan_desc[chan].err_cnt++; + usbc->HCSR[chan].HCINTMSKn |= (USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_NYET); + hal_usbhost_retry_chan(chan, chan_desc[chan].start_xfer_size - xfer); + return; + } + } + } else if (raw_irq & (USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_NYET)) { + chan_desc[chan].err_cnt = 0; + usbc->HCSR[chan].HCINTMSKn &= ~(USBC_HCINTN_ACK | USBC_HCINTN_NAK | USBC_HCINTN_NYET); + return; + } + } + } + + if (error == HAL_USBHOST_XFER_ERR_QTY) { + error = hal_usbhost_get_xfer_error(raw_irq); + } + + if (error == HAL_USBHOST_XFER_ERR_QTY) { + // Unknown IRQ + usbc->HCSR[chan].HCINTMSKn &= ~irq; + USBHOST_TRACE(3,19, "%s: Got unknown IRQ chan=%d irq=0x%08x", __FUNCTION__, chan, irq); + } else { + // Stop xfer timer + hwtimer_stop(usbhost_timer[chan]); + + // Reset the chan_desc to INIT state so that it can be reused in callback + handler = chan_desc[chan].xfer.handler; + buf = chan_desc[chan].xfer.buf; + chan_desc[chan].state = HAL_USBHOST_CHAN_INIT; + + if (error != HAL_USBHOST_XFER_ERR_NONE) { + usbc->HAINTMSK &= ~(1 << chan); + if ((raw_irq & USBC_HCINTN_CHHLTD) == 0) { + hal_usbhost_halt_chan(chan); + } + } + if (handler) { + handler(chan, buf, xfer, error); + } + } +} + +static void hal_usbhost_chan_handler(void) +{ + uint8_t i; + + USBHOST_FUNC_ENTRY_TRACE(2); + + for (i = 0; i < MAX_CHAN_NUM; i++) { + if (usbc->HAINT & (1 << i)) { + hal_usbhost_chan_n_handler(i); + } + } +} + +static void hal_usbhost_irq_handler(void) +{ + uint32_t status; + + // Store interrupt flag and reset it + status = usbc->GINTSTS; + usbc->GINTSTS = status; + + status &= (usbc->GINTMSK & (USBC_PRTINT | USBC_HCHINT | USBC_DISCONNINT)); + + USBHOST_TRACE(2,1, "%s: 0x%08x", __FUNCTION__, status); + + if (status & USBC_DISCONNINT) { + hal_usbhost_disconn_handler(); + return; + } + if (status & USBC_PRTINT) { + hal_usbhost_port_handler(); + } + if (status & USBC_HCHINT) { + hal_usbhost_chan_handler(); + } +} + +static void hal_usbhost_timeout(void *param) +{ + uint8_t chan = (uint8_t)(uint32_t)param; + uint32_t xfer; + HAL_USBHOST_XFER_COMPL_HANDLER handler; + uint8_t *buf; + + USBHOST_TRACE(2,21, "%s: %d", __FUNCTION__, chan); + + if (chan_desc[chan].state != HAL_USBHOST_CHAN_XFER) { + return; + } + + hal_usbhost_halt_chan(chan); + + if (chan_desc[chan].xfer.handler) { + // TODO: Check whether HCTSIZn is reset after channel is halted + xfer = hal_usbhost_get_xfer_size(chan, 0); + + // Reset the chan_desc to INIT state so that it can be reused in callback + handler = chan_desc[chan].xfer.handler; + buf = chan_desc[chan].xfer.buf; + chan_desc[chan].state = HAL_USBHOST_CHAN_INIT; + + handler(chan, buf, xfer, HAL_USBHOST_XFER_ERR_TIMEOUT); + } +} + +#ifdef PMU_USB_PIN_CHECK +static void hal_usbhost_pin_status_change(enum PMU_USB_PIN_CHK_STATUS_T status) +{ + USBHOST_TRACE(2,24, "%s: %d", __FUNCTION__, status); + + if (plug_handler) { + if (status == PMU_USB_PIN_CHK_DEV_CONN) { + plug_handler(HAL_USBHOST_PLUG_IN); + } else if (status == PMU_USB_PIN_CHK_DEV_DISCONN) { + plug_handler(HAL_USBHOST_PLUG_OUT); + } + } +} +#endif + +void hal_usbhost_detect(enum HAL_USBHOST_PLUG_STATUS_T status, HAL_USBHOST_PLUG_HANDLER handler) +{ +#ifdef PMU_USB_PIN_CHECK + enum PMU_USB_PIN_CHK_STATUS_T pmu_status; + + USBHOST_FUNC_ENTRY_TRACE(23); + + if (status == HAL_USBHOST_PLUG_IN) { + pmu_status = PMU_USB_PIN_CHK_DEV_CONN; + } else if (status == HAL_USBHOST_PLUG_OUT) { + pmu_status = PMU_USB_PIN_CHK_DEV_DISCONN; + } else { + pmu_status = PMU_USB_PIN_CHK_NONE; + } + + plug_handler = handler; + if (handler && pmu_status != PMU_USB_PIN_CHK_NONE) { + pmu_usb_config_pin_status_check(pmu_status, hal_usbhost_pin_status_change, true); + } else { + pmu_usb_disable_pin_status_check(); + } +#else + ASSERT(false, "No aux usb pin status check support"); +#endif +} + +void hal_usbhost_sleep(void) +{ + USBHOST_FUNC_ENTRY_TRACE(22); + + if (usbhost_opened) { + hal_usbhost_port_suspend(); +#ifdef PMU_USB_PIN_CHECK + hal_cmu_clock_disable(HAL_CMU_MOD_H_USBC); + hal_cmu_clock_disable(HAL_CMU_MOD_O_USB); + pmu_usb_config_pin_status_check(PMU_USB_PIN_CHK_DEV_DISCONN, hal_usbhost_pin_status_change, true); +#endif + } +} + +void hal_usbhost_wakeup(void) +{ + USBHOST_FUNC_ENTRY_TRACE(22); + + if (usbhost_opened) { +#ifdef PMU_USB_PIN_CHECK + pmu_usb_disable_pin_status_check(); + hal_cmu_clock_enable(HAL_CMU_MOD_H_USBC); + hal_cmu_clock_enable(HAL_CMU_MOD_O_USB); +#endif + hal_usbhost_port_resume(); + } +} + +#endif // CHIP_HAS_USB diff --git a/platform/hal/hal_usbhost.h b/platform/hal/hal_usbhost.h new file mode 100644 index 0000000..bb348cf --- /dev/null +++ b/platform/hal/hal_usbhost.h @@ -0,0 +1,173 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HAL_USB_H__ +#define __HAL_USB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "stdbool.h" + +#ifdef USB_HIGH_SPEED +#define MAX_USBHOST_PACKET_SIZE 512 +#else +#define MAX_USBHOST_PACKET_SIZE 64 +#endif + +#define USBHOST_EPNUM 6 + +#define HAL_USBHOST_CHAN_NONE 0xFF + +enum HAL_USBHOST_EP_TYPE_T { + HAL_USBHOST_EP_CTRL, + HAL_USBHOST_EP_ISO, + HAL_USBHOST_EP_BULK, + HAL_USBHOST_EP_INT, + + HAL_USBHOST_EP_QTY +}; + +enum HAL_USBHOST_PID_TYPE_T { + HAL_USBHOST_PID_DATA0 = 0, + HAL_USBHOST_PID_DATA2 = 1, + HAL_USBHOST_PID_DATA1 = 2, + HAL_USBHOST_PID_MDATA = 3, + HAL_USBHOST_PID_SETUP = 3, + + HAL_USBHOST_PID_QTY, + HAL_USBHOST_PID_AUTO = 0xFF, +}; + +enum HAL_USBHOST_PORT_EVENT_T { + HAL_USBHOST_PORT_CONN, + HAL_USBHOST_PORT_EN_LS, + HAL_USBHOST_PORT_EN_FS, + HAL_USBHOST_PORT_EN_HS, + HAL_USBHOST_PORT_EN_BAD, + HAL_USBHOST_PORT_DISCONN, + + HAL_USBHOST_PORT_QTY +}; + +enum HAL_USBHOST_SETUP_STAGE_T { + HAL_USBHOST_SETUP_DATA_IN, + HAL_USBHOST_SETUP_DATA_OUT, + HAL_USBHOST_SETUP_STATUS_IN, + HAL_USBHOST_SETUP_STATUS_OUT, + HAL_USBHOST_SETUP_DONE, + HAL_USBHOST_SETUP_ERROR, + + HAL_USBHOST_SETUP_STAGE_QTY +}; + +enum HAL_USBHOST_XFER_ERR_T { + HAL_USBHOST_XFER_ERR_NONE, + HAL_USBHOST_XFER_ERR_AHB, + HAL_USBHOST_XFER_ERR_STALL, + HAL_USBHOST_XFER_ERR_TRANSACTION, + HAL_USBHOST_XFER_ERR_BABBLE, + HAL_USBHOST_XFER_ERR_FRAME_OVERRUN, + HAL_USBHOST_XFER_ERR_DATA_TOGGLE, + HAL_USBHOST_XFER_ERR_TIMEOUT, + HAL_USBHOST_XFER_ERR_DISCONN, + + HAL_USBHOST_XFER_ERR_QTY +}; + +struct HAL_USBHOST_SETUP_XFER_T; + +typedef void (*HAL_USBHOST_DELAY_FUNC)(uint32_t ms); +typedef void (*HAL_USBHOST_PORT_HANDLER)(enum HAL_USBHOST_PORT_EVENT_T evt); +typedef void (*HAL_USBHOST_XFER_COMPL_HANDLER)(uint8_t chan, uint8_t *buf, uint32_t len, enum HAL_USBHOST_XFER_ERR_T error); +typedef void (*HAL_USBHOST_SETUP_COMPL_HANDLER)(struct HAL_USBHOST_SETUP_XFER_T *setup, int error); + +enum HAL_USBHOST_PLUG_STATUS_T { + HAL_USBHOST_PLUG_UNKNOWN, + HAL_USBHOST_PLUG_IN, + HAL_USBHOST_PLUG_OUT, +}; + +typedef void (*HAL_USBHOST_PLUG_HANDLER)(enum HAL_USBHOST_PLUG_STATUS_T status); + +struct HAL_USBHOST_CHAN_TYPE_T { + uint16_t mps; + uint8_t ep_num; + uint8_t ep_in; + enum HAL_USBHOST_EP_TYPE_T ep_type; + uint8_t dev_addr; +}; + +struct HAL_USBHOST_XFER_T { + uint8_t *buf; + uint32_t size; + uint8_t multi_cnt; + enum HAL_USBHOST_PID_TYPE_T pid; + HAL_USBHOST_XFER_COMPL_HANDLER handler; +}; + +struct HAL_USBHOST_SETUP_PKT_T { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +}; + +struct HAL_USBHOST_SETUP_XFER_T { + struct HAL_USBHOST_SETUP_PKT_T setup_pkt; + enum HAL_USBHOST_SETUP_STAGE_T next_stage; + HAL_USBHOST_SETUP_COMPL_HANDLER handler; + uint8_t *data_buf; + uint8_t chan_out; + uint8_t chan_in; +}; + +int hal_usbhost_open(HAL_USBHOST_PORT_HANDLER port_cb, HAL_USBHOST_DELAY_FUNC delay_fn); + +void hal_usbhost_close(void); + +void hal_usbhost_halt_chan(uint8_t chan); + +void hal_usbhost_port_reset(uint32_t ms); + +int hal_usbhost_get_chan(uint8_t *chan); + +int hal_usbhost_free_chan(uint8_t chan); + +int hal_usbhost_init_chan(uint8_t chan, const struct HAL_USBHOST_CHAN_TYPE_T *type); + +int hal_usbhost_update_chan_dev_addr(uint8_t chan, uint8_t dev_addr); + +int hal_usbhost_update_chan_mps(uint8_t chan, uint16_t mps); + +int hal_usbhost_start_xfer(uint8_t chan, const struct HAL_USBHOST_XFER_T *xfer); + +int hal_usbhost_start_setup_xfer(const struct HAL_USBHOST_SETUP_XFER_T *setup, uint32_t *recv_len); + +void hal_usbhost_detect(enum HAL_USBHOST_PLUG_STATUS_T status, HAL_USBHOST_PLUG_HANDLER handler); + +void hal_usbhost_sleep(void); + +void hal_usbhost_wakeup(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/hal_wdt.c b/platform/hal/hal_wdt.c new file mode 100644 index 0000000..a740b9c --- /dev/null +++ b/platform/hal/hal_wdt.c @@ -0,0 +1,242 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "plat_addr_map.h" +#include "cmsis.h" +#include "cmsis_nvic.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_uart.h" +#include "hal_wdt.h" + +#if defined(CHIP_BEST3001) || defined(CHIP_BEST3003) || defined(CHIP_BEST3005) || defined(CHIP_BEST1400) || defined(CHIP_BEST1402) +#define CLOCK_SYNC_WORKAROUND +#endif + +#define SLOW_TIMER_VAL_DELTA 1 +#define FAST_TIMER_VAL_DELTA 20 + +/* wdt controller */ +/* reg address */ +/* default timeout in seconds */ +#define DEFAULT_TIMEOUT 60 + +#define WDT_RATE CONFIG_SYSTICK_HZ + +/* watchdog register offsets and masks */ +#define WDTLOAD_REG_OFFSET 0x000 +#define WDTLOAD_LOAD_MIN 0x00000001 +#define WDTLOAD_LOAD_MAX 0xFFFFFFFF + +#define WDTVALUE_REG_OFFSET 0x004 + +#define WDTCONTROL_REG_OFFSET 0x008 +#define WDTCONTROL_REG_INT_ENABLE (1 << 0) +#define WDTCONTROL_REG_RESET_ENABLE (1 << 1) + +#define WDTINTCLR_REG_OFFSET 0x00C + +#define WDTRIS_REG_OFFSET 0x010 +#define WDTRIS_REG_INT_MASK (1 << 0) + +#define WDTMIS_REG_OFFSET 0x014 +#define WDTMIS_REG_INT_MASK (1 << 0) + +#define WDTLOCK_REG_OFFSET 0xC00 +#define WDTLOCK_REG_UNLOCK 0x1ACCE551 +#define WDTLOCK_REG_LOCK 0x00000001 + +/* read write */ +#define wdtip_write32(v,b,a) \ + (*((volatile unsigned int *)(b+a)) = v) +#define wdtip_read32(b,a) \ + (*((volatile unsigned int *)(b+a))) + +#if 1 +typedef void (*HAL_WDT_IRQ_HANDLER)(void); + +struct HAL_WDT_CTX { + unsigned int load_val; +}; + +struct HAL_WDT_CTX hal_wdt_ctx[HAL_WDT_ID_NUM]; +static void _wdt1_irq_handler(void); +HAL_WDT_IRQ_HANDLER hal_wdt_irq_handler[HAL_WDT_ID_NUM] = +{ + _wdt1_irq_handler, +}; +HAL_WDT_IRQ_CALLBACK hal_wdt_irq_callback[HAL_WDT_ID_NUM]; + +static void _wdt1_irq_handler(void) +{ + if (hal_wdt_irq_callback[HAL_WDT_ID_0] != 0) { + hal_wdt_irq_callback[HAL_WDT_ID_0](HAL_WDT_ID_0, HAL_WDT_EVENT_FIRE); + } +} + +static unsigned int _wdt_get_base(enum HAL_WDT_ID_T id) +{ + switch(id) { + default: + case HAL_WDT_ID_0: + return WDT_BASE; + break; + } + + return 0; +} + +static void _wdt_load(enum HAL_WDT_ID_T id) +{ + unsigned int reg_base = 0; + struct HAL_WDT_CTX *wdt = &hal_wdt_ctx[id]; + uint32_t lock; + + reg_base = _wdt_get_base(id); + + lock = int_lock(); + + wdtip_write32(WDTLOCK_REG_UNLOCK, reg_base, WDTLOCK_REG_OFFSET); + +#ifdef CLOCK_SYNC_WORKAROUND + uint32_t val; + + do { + wdtip_write32(wdt->load_val, reg_base, WDTLOAD_REG_OFFSET); + val = wdtip_read32(reg_base, WDTVALUE_REG_OFFSET); + } while ((wdt->load_val < val) || (wdt->load_val > val + SLOW_TIMER_VAL_DELTA)); +#else + wdtip_write32(wdt->load_val, reg_base, WDTLOAD_REG_OFFSET); +#endif + + wdtip_write32(WDTLOCK_REG_LOCK, reg_base, WDTLOCK_REG_OFFSET); + + int_unlock(lock); + + /* Flush posted writes. */ + wdtip_read32(reg_base, WDTLOCK_REG_OFFSET); +} + +static void _wdt_config(enum HAL_WDT_ID_T id) +{ + unsigned int reg_base = 0; + uint32_t lock; + + reg_base = _wdt_get_base(id); + + lock = int_lock(); + wdtip_write32(WDTLOCK_REG_UNLOCK, reg_base, WDTLOCK_REG_OFFSET); + wdtip_write32(WDTRIS_REG_INT_MASK, reg_base, WDTINTCLR_REG_OFFSET); + wdtip_write32(WDTCONTROL_REG_INT_ENABLE | WDTCONTROL_REG_RESET_ENABLE, reg_base, WDTCONTROL_REG_OFFSET); + wdtip_write32(WDTLOCK_REG_LOCK, reg_base, WDTLOCK_REG_OFFSET); + int_unlock(lock); + + /* Flush posted writes. */ + wdtip_read32(reg_base, WDTLOCK_REG_OFFSET); +} + +static int wdt_start; + +/* mandatory operations */ +int hal_wdt_start(enum HAL_WDT_ID_T id) +{ + _wdt_load(id); + _wdt_config(id); + wdt_start = 1; + return 0; +} +int hal_wdt_stop(enum HAL_WDT_ID_T id) +{ + unsigned int reg_base = 0; + uint32_t lock; + + reg_base = _wdt_get_base(id); + + lock = int_lock(); + wdtip_write32(WDTLOCK_REG_UNLOCK, reg_base, WDTLOCK_REG_OFFSET); + wdtip_write32(0, reg_base, WDTCONTROL_REG_OFFSET); + wdtip_write32(WDTLOCK_REG_LOCK, reg_base, WDTLOCK_REG_OFFSET); + int_unlock(lock); + + /* Flush posted writes. */ + wdtip_read32(reg_base, WDTLOCK_REG_OFFSET); + + wdt_start = 0; + return 0; +} + +/* optional operations */ +int hal_wdt_ping(enum HAL_WDT_ID_T id) +{ + if (wdt_start) { + _wdt_load(id); + } + + return 0; +} +int hal_wdt_set_timeout(enum HAL_WDT_ID_T id, unsigned int timeout) +{ + uint64_t load; + struct HAL_WDT_CTX *wdt = &hal_wdt_ctx[id]; + + /* + * sp805 runs counter with given value twice, after the end of first + * counter it gives an interrupt and then starts counter again. If + * interrupt already occurred then it resets the system. This is why + * load is half of what should be required. + */ + load = WDT_RATE * timeout - 1; + + load = (load > WDTLOAD_LOAD_MAX) ? WDTLOAD_LOAD_MAX: load; + load = (load < WDTLOAD_LOAD_MIN) ? WDTLOAD_LOAD_MIN: load; + + wdt->load_val = load; + + return 0; +} +unsigned int hal_wdt_get_timeleft(enum HAL_WDT_ID_T id) +{ + uint64_t load; + unsigned int reg_base = 0; + struct HAL_WDT_CTX *wdt = &hal_wdt_ctx[id]; + + reg_base = _wdt_get_base(id); + + load = wdtip_read32(reg_base, WDTVALUE_REG_OFFSET); + + /*If the interrupt is inactive then time left is WDTValue + WDTLoad. */ + if (!(wdtip_read32(reg_base, WDTRIS_REG_OFFSET) & WDTRIS_REG_INT_MASK)) + load += wdt->load_val + 1; + + return load/WDT_RATE; +} + +void hal_wdt_set_irq_callback(enum HAL_WDT_ID_T id, HAL_WDT_IRQ_CALLBACK cb) +{ + switch(id) { + default: + case HAL_WDT_ID_0: + NVIC_SetVector(WDT_IRQn, (uint32_t)hal_wdt_irq_handler[id]); + NVIC_SetPriority(WDT_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(WDT_IRQn); + NVIC_EnableIRQ(WDT_IRQn); + break; + } + + hal_wdt_irq_callback[id] = cb; +} + +#endif diff --git a/platform/hal/hal_wdt.h b/platform/hal/hal_wdt.h new file mode 100644 index 0000000..c9ae55b --- /dev/null +++ b/platform/hal/hal_wdt.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef WDT_HAL_H +#define WDT_HAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +enum HAL_WDT_ID_T { + HAL_WDT_ID_0 = 0, + HAL_WDT_ID_NUM, +}; + +enum HAL_WDT_EVENT_T { + HAL_WDT_EVENT_FIRE = 0, +}; + +#define HAL_WDT_YES 1 +#define HAL_WDT_NO 0 + +typedef void (*HAL_WDT_IRQ_CALLBACK)(enum HAL_WDT_ID_T id, uint32_t status); +/* hal api */ +void hal_wdt_set_irq_callback(enum HAL_WDT_ID_T id, HAL_WDT_IRQ_CALLBACK handler); + +/* mandatory operations */ +int hal_wdt_start(enum HAL_WDT_ID_T id); +int hal_wdt_stop(enum HAL_WDT_ID_T id); + +/* optional operations */ +int hal_wdt_ping(enum HAL_WDT_ID_T id); +int hal_wdt_set_timeout(enum HAL_WDT_ID_T id, unsigned int); +unsigned int hal_wdt_get_timeleft(enum HAL_WDT_ID_T id); + +#ifdef __cplusplus +} +#endif + +#endif /* WDT_HAL_H */ diff --git a/platform/hal/plat_addr_map.h b/platform/hal/plat_addr_map.h new file mode 100644 index 0000000..3de7ed5 --- /dev/null +++ b/platform/hal/plat_addr_map.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __PLAT_ADDR_MAP_H__ +#define __PLAT_ADDR_MAP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#if 0 +#elif defined(CHIP_FPGA1000) +#define CHIP_ID_LITERAL fpga1000 +#elif defined(CHIP_BEST1000) +#define CHIP_ID_LITERAL best1000 +#elif defined(CHIP_BEST1400) || defined(CHIP_BEST1402) +#define CHIP_ID_LITERAL best1400 +#elif defined(CHIP_BEST2000) +#define CHIP_ID_LITERAL best2000 +#elif defined(CHIP_BEST2001) +#define CHIP_ID_LITERAL best2001 +#elif defined(CHIP_BEST2300) +#define CHIP_ID_LITERAL best2300 +#elif defined(CHIP_BEST2300A) +#define CHIP_ID_LITERAL best2300a +#elif defined(CHIP_BEST2300P) +#define CHIP_ID_LITERAL best2300p +#elif defined(CHIP_BEST3001) || defined(CHIP_BEST3005) +#define CHIP_ID_LITERAL best3001 +#elif defined(CHIP_BEST3003) +#define CHIP_ID_LITERAL best3003 +#else +#error "Unknown chip ID" +#endif + +#define _TO_STRING_A(s) # s +#define _TO_STRING(s) _TO_STRING_A(s) + +#define CONCAT_NAME_A(a, b) a ## b +#define CONCAT_NAME(a, b) CONCAT_NAME_A(a, b) +#define CONCAT_SUFFIX(a, b) a.b + +#define CONSTRUCT_HDR_NAME_A(d, n) d/n ## _ ## d +#define CONSTRUCT_HDR_NAME(d, n) CONSTRUCT_HDR_NAME_A(d, n) +#define CHIP_SPECIFIC_HDR(n) _TO_STRING(CONSTRUCT_HDR_NAME(CHIP_ID_LITERAL, n).h) + +#include CHIP_SPECIFIC_HDR(plat_addr_map) + +#define RAM_TO_RAMX(d) ((d) - RAM_BASE + RAMX_BASE) +#define RAMX_TO_RAM(d) ((d) - RAMX_BASE + RAM_BASE) + +#define FLASH_TO_FLASHX(d) ((d) - FLASH_BASE + FLASHX_BASE) +#define FLASHX_TO_FLASH(d) ((d) - FLASHX_BASE + FLASH_BASE) + +#define FLASH_C_TO_NC(d) ((d) - FLASH_BASE + FLASH_NC_BASE) +#define FLASH_NC_TO_C(d) ((d) - FLASH_NC_BASE + FLASH_BASE) + +#define PSRAM_TO_PSRAMX(d) ((d) - PSRAM_BASE + PSRAMX_BASE) +#define PSRAMX_TO_PSRAM(d) ((d) - PSRAMX_BASE + PSRAM_BASE) + +#define PSRAM_C_TO_NC(d) ((d) - PSRAM_BASE + PSRAM_NC_BASE) +#define PSRAM_NC_TO_C(d) ((d) - PSRAM_NC_BASE + PSRAM_BASE) + +#define BUILD_INFO_MAGIC 0xBE57341D + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/hal/plat_types.h b/platform/hal/plat_types.h new file mode 100644 index 0000000..9c93a91 --- /dev/null +++ b/platform/hal/plat_types.h @@ -0,0 +1,219 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __PLAT_TYPES_H__ +#define __PLAT_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stddef.h" +#include "stdint.h" +#include "stdbool.h" + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; +typedef unsigned long long u64; +typedef char s8; +typedef short s16; +typedef long s32; +typedef long long s64; + +typedef char ascii; +typedef unsigned char byte; /* unsigned 8-bit data */ +typedef unsigned short word; /* unsigned 16-bit data */ +typedef unsigned long dword; /* unsigned 32-bit data */ + + +/* 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. +*/ +#ifndef __I +#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 */ +#endif + + +#define BITFIELD_VAL(field, value) (((value) & (field ## _MASK >> field ## _SHIFT)) << field ## _SHIFT) +#define SET_BITFIELD(reg, field, value) (((reg) & ~field ## _MASK) | BITFIELD_VAL(field, value)) +#define GET_BITFIELD(reg, field) (((reg) & field ## _MASK) >> field ## _SHIFT) + + +/* Frequently used macros */ + +#ifndef ALIGN +#define ALIGN(val,exp) (((val) + ((exp)-1)) & ~((exp)-1)) +#endif + +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) +#define LAST_ELEMENT(x) (&x[ARRAY_SIZE(x)-1]) +#define BOUND(x, min, max) ( (x) < (min) ? (min) : ((x) > (max) ? (max):(x)) ) +#define ROUND_SIZEOF(t) ((sizeof(t)+sizeof(int)-1)&~(sizeof(int)-1)) + +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef ABS +#define ABS(x) ((x<0)?(-(x)):(x)) +#endif + +#define TO_STRING_A(s) # s +#define TO_STRING(s) TO_STRING_A(s) + +#ifdef __GNUC__ + +/* Remove const cast-away warnings from gcc -Wcast-qual */ +#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) + +/// From http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/ +/// Macro to use in a if statement to tell the compiler this branch +/// is likely taken, and optimize accordingly. +#define LIKELY(x) __builtin_expect(!!(x), 1) +/// Macro to use in a if statement to tell the compiler this branch +/// is unlikely take, and optimize accordingly. +#define UNLIKELY(x) __builtin_expect(!!(x), 0) + +/// For packing structure +#define PACKED __attribute__((packed)) + +/// To describe alignment +#define ALIGNED(a) __attribute__((aligned(a))) + +/// For possibly unused functions or variables (e.g., debugging stuff) +#define POSSIBLY_UNUSED __attribute__((unused)) + +/// For functions or variables must be emitted even if not referenced +#define USED __attribute__((used)) + +/// For inline functions +#define ALWAYS_INLINE __attribute__((always_inline)) + +// For functions never inlined +#define NOINLINE __attribute__((noinline)) + +// For functions not caring performance +#ifdef __ARMCC_VERSION +#define OPT_SIZE +#else +#define OPT_SIZE __attribute__((optimize("Os"))) +#endif + +// For functions not returning +#define NORETURN __attribute__((noreturn)) + +// For ASM functions in C +#ifdef __arm__ +#define NAKED __attribute__((naked)) +#else +#define NAKED __attribute__((error("Unsupport naked functions"))) +#endif + +// For weak symbols +#define WEAK __attribute__((weak)) + +// Structure offset +#ifndef OFFSETOF +#define OFFSETOF(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +/** + * CONTAINER_OF - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#ifndef CONTAINER_OF +#define CONTAINER_OF(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - OFFSETOF(type,member) );}) +#endif + +#else // Not GCC + +#define __UNCONST(a) +#define LIKELY(x) +#define UNLIKELY(x) +#define PACKED +#define ALIGNED(a) +#define POSSIBLY_UNUSED +#define USED +#define ALWAYS_INLINE +#define NOINLINE +#define OPT_SIZE +#define NORETURN +#define NAKED +#define WEAK +#define OFFSETOF(TYPE, MEMBER) + +#endif // Not GCC + +/// C preprocessor conditional check +/// -------------------------------- +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +#if defined(__GNUC__) && (GCC_VERSION >= 40600) && !defined(__cplusplus) + +// GCC 4.6 or later +#define STATIC_ASSERT(e, m) _Static_assert(e, m) + +#elif defined(__GNUC__) && (GCC_VERSION >= 40300) && defined(__cplusplus) && (__cplusplus >= 201103L) + +#define STATIC_ASSERT(e, m) static_assert(e, m) + +#else // No built-in static assert + +/// FROM: http://www.pixelbeat.org/programming/gcc/static_assert.html +#define ASSERT_CONCAT_(a, b) a##b +#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b) +/* These can't be used after statements in c89. */ +#ifdef __COUNTER__ +#define STATIC_ASSERT(e, m) \ + enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }; +#else +/* This can't be used twice on the same line so ensure if using in headers + * that the headers are not included twice (by wrapping in #ifndef...#endif) + * Note it doesn't cause an issue when used on same line of separate modules + * compiled with gcc -combine -fwhole-program. */ +#define STATIC_ASSERT(e, m) \ + enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }; +#endif + +#endif // No built-in static assert +/// -------------------------------- + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/platform/hal/reg_btpcmip.h b/platform/hal/reg_btpcmip.h new file mode 100644 index 0000000..976f573 --- /dev/null +++ b/platform/hal/reg_btpcmip.h @@ -0,0 +1,141 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_BTPCMIP_H_ +#define __REG_BTPCMIP_H_ + +#include "plat_types.h" + +#define BTPCMIP_FIFO_DEPTH 8 + +/* btpcmip register */ +/* enable register */ +#define BTPCMIP_ENABLE_REG_REG_OFFSET 0x0 +#define BTPCMIP_ENABLE_REG_BTPCM_ENABLE_SHIFT (0) +#define BTPCMIP_ENABLE_REG_BTPCM_ENABLE_MASK ((0x1)<= 3) + __IO uint32_t RESERVED_0B4[0x13]; + __IO uint32_t REG_100; + __IO uint32_t REG_104; + __IO uint32_t REG_108; + __IO uint32_t REG_10C; + __IO uint32_t REG_110; + __IO uint32_t REG_114; + __IO uint32_t REG_118; + __IO uint32_t REG_11C; + __IO uint32_t REG_120; + __IO uint32_t REG_124; + __IO uint32_t REG_128; + __IO uint32_t REG_12C; + __IO uint32_t REG_130; + __IO uint32_t REG_134; + __IO uint32_t REG_138; + __IO uint32_t REG_13C; + __IO uint32_t REG_140; + __IO uint32_t REG_144; + __IO uint32_t REG_148; + __IO uint32_t REG_14C; + __IO uint32_t REG_150; +#endif +#endif +#endif +}; + +// REG_000 +#define REG_000_ADDR_SHIFT 8 +#define REG_000_ADDR_MASK (0xFFFFFF << REG_000_ADDR_SHIFT) +#define REG_000_ADDR(n) BITFIELD_VAL(REG_000_ADDR, n) +#define REG_000_CMD_SHIFT 0 +#define REG_000_CMD_MASK (0xFF << REG_000_CMD_SHIFT) +#define REG_000_CMD(n) BITFIELD_VAL(REG_000_CMD, n) + +#define REG_000_NEW_CMD_RX_LEN_SHIFT 13 +#define REG_000_NEW_CMD_RX_LEN_MASK (0x3FFF << REG_000_NEW_CMD_RX_LEN_SHIFT) +#define REG_000_NEW_CMD_RX_LEN(n) BITFIELD_VAL(REG_000_NEW_CMD_RX_LEN, n) +#define REG_000_NEW_CMD_RX_LINE_SHIFT 11 +#define REG_000_NEW_CMD_RX_LINE_MASK (0x3 << REG_000_NEW_CMD_RX_LINE_SHIFT) +#define REG_000_NEW_CMD_RX_LINE(n) BITFIELD_VAL(REG_000_NEW_CMD_RX_LINE, n) +#define REG_000_NEW_CMD_TX_LINE_SHIFT 9 +#define REG_000_NEW_CMD_TX_LINE_MASK (0x3 << REG_000_NEW_CMD_TX_LINE_SHIFT) +#define REG_000_NEW_CMD_TX_LINE(n) BITFIELD_VAL(REG_000_NEW_CMD_TX_LINE, n) +#define REG_000_NEW_CMD_RX_EN (1 << 8) + +#define NEW_CMD_LINE_4X 2 +#define NEW_CMD_LINE_2X 1 +#define NEW_CMD_LINE_1X 0 + +// REG_004 +#define REG_004_RES26_SHIFT 26 +#define REG_004_RES26_MASK (0x3F << REG_004_RES26_SHIFT) +#define REG_004_RES26(n) BITFIELD_VAL(REG_004_RES26, n) +#define REG_004_CONTINUOUS_MODE (1 << 25) +#define REG_004_BLOCK_SIZE_SHIFT 12 +#define REG_004_BLOCK_SIZE_MASK (0x1FFF << REG_004_BLOCK_SIZE_SHIFT) +#define REG_004_BLOCK_SIZE(n) BITFIELD_VAL(REG_004_BLOCK_SIZE, n) +#define REG_004_MODEBIT_SHIFT 4 +#define REG_004_MODEBIT_MASK (0xFF << REG_004_MODEBIT_SHIFT) +#define REG_004_MODEBIT(n) BITFIELD_VAL(REG_004_MODEBIT, n) +#define REG_004_RES1_SHIFT 1 +#define REG_004_RES1_MASK (0x7 << REG_004_RES1_SHIFT) +#define REG_004_RES1(n) BITFIELD_VAL(REG_004_RES1, n) +#define REG_004_NEW_CMD_EN (1 << 0) + +// REG_008 +#define REG_008_TXDATA_SHIFT 0 +#define REG_008_TXDATA_MASK (0xFFFFFFFF << REG_008_TXDATA_SHIFT) +#define REG_008_TXDATA(n) BITFIELD_VAL(REG_008_TXDATA, n) + +// REG_00C +#define REG_00C_RES_SHIFT 13 +#define REG_00C_RES_MASK (0x7FFFF << REG_00C_RES_SHIFT) +#define REG_00C_RES(n) BITFIELD_VAL(REG_00C_RES, n) +#define REG_00C_TXFIFO_EMPCNT_SHIFT 8 +#define REG_00C_TXFIFO_EMPCNT_MASK (0x1F << REG_00C_TXFIFO_EMPCNT_SHIFT) +#define REG_00C_TXFIFO_EMPCNT(n) BITFIELD_VAL(REG_00C_TXFIFO_EMPCNT, n) +#define REG_00C_RXFIFO_COUNT_SHIFT 4 +#define REG_00C_RXFIFO_COUNT_MASK (0xF << REG_00C_RXFIFO_COUNT_SHIFT) +#define REG_00C_RXFIFO_COUNT(n) BITFIELD_VAL(REG_00C_RXFIFO_COUNT, n) +#define REG_00C_RXFIFO_EMPTY (1 << 3) +#define REG_00C_TXFIFO_FULL (1 << 2) +#define REG_00C_TXFIFO_EMPTY (1 << 1) +#define REG_00C_BUSY (1 << 0) + +// REG_010 +#define REG_010_RXDATA_SHIFT 0 +#define REG_010_RXDATA_MASK (0xFFFFFFFF << REG_010_RXDATA_SHIFT) +#define REG_010_RXDATA(n) BITFIELD_VAL(REG_010_RXDATA, n) + +// REG_014 +#define REG_014_RES29_SHIFT 29 +#define REG_014_RES29_MASK (0x7 << REG_014_RES29_SHIFT) +#define REG_014_RES29(n) BITFIELD_VAL(REG_014_RES29, n) +#define REG_014_EXTRA_SHSL_SHIFT 25 +#define REG_014_EXTRA_SHSL_MASK (0xF << REG_014_EXTRA_SHSL_SHIFT) +#define REG_014_EXTRA_SHSL(n) BITFIELD_VAL(REG_014_EXTRA_SHSL, n) +#define REG_014_EXTRA_SHSL_EN (1 << 24) +#define REG_014_CLKDIV_SHIFT 16 +#define REG_014_CLKDIV_MASK (0xFF << REG_014_CLKDIV_SHIFT) +#define REG_014_CLKDIV(n) BITFIELD_VAL(REG_014_CLKDIV, n) +#define REG_014_SAMPLESEL_SHIFT 12 +#define REG_014_SAMPLESEL_MASK (0xF << REG_014_SAMPLESEL_SHIFT) +#define REG_014_SAMPLESEL(n) BITFIELD_VAL(REG_014_SAMPLESEL, n) +// Since 2300p +#define EXTRA_TCHSH_O_SHIFT 8 +#define EXTRA_TCHSH_O_MASK (0xF << EXTRA_TCHSH_O_SHIFT) +#define EXTRA_TCHSH_O(n) BITFIELD_VAL(EXTRA_TCHSH_O, n) +#define EXTRA_TCHSH_EN_O (1 << 7) +// End of since 2300p +#define REG_014_CMDQUAD (1 << 6) +#define REG_014_RAM_DUALMODE (1 << 5) +#define REG_014_RAM_QUADMODE (1 << 4) +#define REG_014_FOUR_BYTE_ADDR_EN (1 << 3) +#define REG_014_RES2 (1 << 2) +#define REG_014_HOLDPIN (1 << 1) +#define REG_014_WPROPIN (1 << 0) + +// REG_018 +#define REG_018_RES_SHIFT 2 +#define REG_018_RES_MASK (0x3FFFFFFF << REG_018_RES_SHIFT) +#define REG_018_RES(n) BITFIELD_VAL(REG_018_RES, n) +#define REG_018_TXFIFOCLR (1 << 1) +#define REG_018_RXFIFOCLR (1 << 0) + +// REG_01C +#define REG_01C_RES18_SHIFT 18 +#define REG_01C_RES18_MASK (0x3FFF << REG_01C_RES18_SHIFT) +#define REG_01C_RES18(n) BITFIELD_VAL(REG_01C_RES18, n) +#define REG_01C_DMA_RX_SIZE_SHIFT 16 +#define REG_01C_DMA_RX_SIZE_MASK (0x3 << REG_01C_DMA_RX_SIZE_SHIFT) +#define REG_01C_DMA_RX_SIZE(n) BITFIELD_VAL(REG_01C_DMA_RX_SIZE, n) +#define REG_01C_TX_THRESHOLD_SHIFT 8 +#define REG_01C_TX_THRESHOLD_MASK (0x1F << REG_01C_TX_THRESHOLD_SHIFT) +#define REG_01C_TX_THRESHOLD(n) BITFIELD_VAL(REG_01C_TX_THRESHOLD, n) +#define REG_01C_RX_THRESHOLD_SHIFT 4 +#define REG_01C_RX_THRESHOLD_MASK (0xF << REG_01C_RX_THRESHOLD_SHIFT) +#define REG_01C_RX_THRESHOLD(n) BITFIELD_VAL(REG_01C_RX_THRESHOLD, n) +#define REG_01C_RES3 (1 << 3) +#define REG_01C_DMACTRL_RX_EN (1 << 2) +#define REG_01C_DMACTRL_TX_EN (1 << 1) +#define REG_01C_NAND_SEL (1 << 0) + +// REG_020 +#define REG_020_DUALCMD_SHIFT 24 +#define REG_020_DUALCMD_MASK (0xFF << REG_020_DUALCMD_SHIFT) +#define REG_020_DUALCMD(n) BITFIELD_VAL(REG_020_DUALCMD, n) +#define REG_020_READCMD_SHIFT 16 +#define REG_020_READCMD_MASK (0xFF << REG_020_READCMD_SHIFT) +#define REG_020_READCMD(n) BITFIELD_VAL(REG_020_READCMD, n) +#define REG_020_FREADCMD_SHIFT 8 +#define REG_020_FREADCMD_MASK (0xFF << REG_020_FREADCMD_SHIFT) +#define REG_020_FREADCMD(n) BITFIELD_VAL(REG_020_FREADCMD, n) +#define REG_020_QUADCMD_SHIFT 0 +#define REG_020_QUADCMD_MASK (0xFF << REG_020_QUADCMD_SHIFT) +#define REG_020_QUADCMD(n) BITFIELD_VAL(REG_020_QUADCMD, n) + +// REG_024 +#define REG_024_CMD_SEQ1_SHIFT 0 +#define REG_024_CMD_SEQ1_MASK (0xFFFFFFFF << REG_024_CMD_SEQ1_SHIFT) +#define REG_024_CMD_SEQ1(n) BITFIELD_VAL(REG_024_CMD_SEQ1, n) + +// REG_028 +#define REG_028_CMD_SEQ_EN (1 << 4) +#define REG_028_CMD_SEQ2_SHIFT 0 +#define REG_028_CMD_SEQ2_MASK (0xF << REG_028_CMD_SEQ2_SHIFT) +#define REG_028_CMD_SEQ2(n) BITFIELD_VAL(REG_028_CMD_SEQ2, n) + +// REG_02C +#define REG_02C_RES_SHIFT 1 +#define REG_02C_RES_MASK (0x7FFFFFFF << REG_02C_RES_SHIFT) +#define REG_02C_RES(n) BITFIELD_VAL(REG_02C_RES, n) +#define REG_02C_FETCH_EN (1 << 0) + +// REG_030 +#define REG_030_RES_SHIFT 2 +#define REG_030_RES_MASK (0x3FFFFFFF << REG_030_RES_SHIFT) +#define REG_030_RES(n) BITFIELD_VAL(REG_030_RES, n) +#define REG_030_ADDR_25_24_SHIFT 0 +#define REG_030_ADDR_25_24_MASK (0x3 << REG_030_ADDR_25_24_SHIFT) +#define REG_030_ADDR_25_24(n) BITFIELD_VAL(REG_030_ADDR_25_24, n) + +// REG_034 +#define REG_034_RES_SHIFT 22 +#define REG_034_RES_MASK (0x3FF << REG_034_RES_SHIFT) +#define REG_034_RES(n) BITFIELD_VAL(REG_034_RES, n) +#define REG_034_SPI_IOEN_SHIFT 18 +#define REG_034_SPI_IOEN_MASK (0xF << REG_034_SPI_IOEN_SHIFT) +#define REG_034_SPI_IOEN(n) BITFIELD_VAL(REG_034_SPI_IOEN, n) +#define REG_034_SPI_IODRV_SHIFT 16 +#define REG_034_SPI_IODRV_MASK (0x3 << REG_034_SPI_IODRV_SHIFT) +#define REG_034_SPI_IODRV(n) BITFIELD_VAL(REG_034_SPI_IODRV, n) +#define REG_034_SPI_IORES_SHIFT 8 +#define REG_034_SPI_IORES_MASK (0xFF << REG_034_SPI_IORES_SHIFT) +#define REG_034_SPI_IORES(n) BITFIELD_VAL(REG_034_SPI_IORES, n) +#define REG_034_SPI_RDEN_SHIFT 4 +#define REG_034_SPI_RDEN_MASK (0xF << REG_034_SPI_RDEN_SHIFT) +#define REG_034_SPI_RDEN(n) BITFIELD_VAL(REG_034_SPI_RDEN, n) +#define REG_034_SPI_RUEN_SHIFT 0 +#define REG_034_SPI_RUEN_MASK (0xF << REG_034_SPI_RUEN_SHIFT) +#define REG_034_SPI_RUEN(n) BITFIELD_VAL(REG_034_SPI_RUEN, n) + +// REG_038 +#define REG_038_MAN_WRAP_BITS_SHIFT 13 +#define REG_038_MAN_WRAP_BITS_MASK (0x3 << REG_038_MAN_WRAP_BITS_SHIFT) +#define REG_038_MAN_WRAP_BITS(n) BITFIELD_VAL(REG_038_MAN_WRAP_BITS, n) +#define REG_038_MAN_WRAP_ENABLE_SHIFT 12 +#define REG_038_MAN_WRAP_ENABLE_MASK (0x1 << REG_038_MAN_WRAP_ENABLE_SHIFT) +#define REG_038_MAN_WRAP_ENABLE (REG_038_MAN_WRAP_ENABLE_MASK) +#define REG_038_AUTO_WRAP_CMD_SHIFT 4 +#define REG_038_AUTO_WRAP_CMD_MASK (0xFF << REG_038_AUTO_WRAP_CMD_SHIFT) +#define REG_038_AUTO_WRAP_CMD(n) BITFIELD_VAL(REG_038_AUTO_WRAP_CMD, n) +#define REG_038_WRAP_MODE_SEL_SHIFT 0 +#define REG_038_WRAP_MODE_SEL_MASK (0x1 << REG_038_WRAP_MODE_SEL_SHIFT) +#define REG_038_WRAP_MODE_SEL (REG_038_WRAP_MODE_SEL_MASK) + +#if (CHIP_FLASH_CTRL_VER >= 3) +// REG_40 +#define REG_40_RES_31_6_SHIFT 6 +#define REG_40_RES_31_6_MASK (0x3FFFFFF << REG_40_RES_31_6_SHIFT) +#define REG_40_RES_31_6(n) BITFIELD_VAL(REG_40_RES_31_6, n) +#define REG_40_SPH (1 << 5) +#define REG_40_RES_4 (1 << 4) +#define REG_40_DQS_MODE (1 << 3) +#define REG_40_DTR_MODE (1 << 2) +#define REG_40_OPI_MODE (1 << 1) +#define REG_40_QPI_MODE (1 << 0) +#endif + +// REG_058 +#define REG_058_IDX_SHIFT 0 +#define REG_058_IDX_MASK (0x7 << REG_058_IDX_SHIFT) +#define REG_058_IDX(n) BITFIELD_VAL(REG_058_IDX, n) + +// REG_060 +#define REG_060_ADDR_BGN_SHIFT 0 +#define REG_060_ADDR_BGN_MASK (0xFFFFFFFF << REG_060_ADDR_BGN_SHIFT) +#define REG_060_ADDR_BGN(n) BITFIELD_VAL(REG_060_ADDR_BGN, n) + +// REG_064 +#define REG_064_ADDR_END_SHIFT 0 +#define REG_064_ADDR_END_MASK (0xFFFFFFFF << REG_064_ADDR_END_SHIFT) +#define REG_064_ADDR_END(n) BITFIELD_VAL(REG_064_ADDR_END, n) + +// REG_06C +#define REG_06C_DEC_ENABLE_SHIFT 0 +#define REG_06C_DEC_ENABLE_MASK (0x1 << REG_06C_DEC_ENABLE_SHIFT) +#define REG_06C_DEC_ENABLE (REG_06C_DEC_ENABLE_MASK) + +// REG_0A0 +#ifdef CHIP_BEST2300P +#define REG_0A0_LEN_WIDTH3_SHIFT 12 +#define REG_0A0_LEN_WIDTH3_MASK (0xF << REG_0A0_LEN_WIDTH3_SHIFT) +#define REG_0A0_LEN_WIDTH3(n) BITFIELD_VAL(REG_0A0_LEN_WIDTH3, n) +#define REG_0A0_LEN_WIDTH2_SHIFT 8 +#define REG_0A0_LEN_WIDTH2_MASK (0xF << REG_0A0_LEN_WIDTH2_SHIFT) +#define REG_0A0_LEN_WIDTH2(n) BITFIELD_VAL(REG_0A0_LEN_WIDTH2, n) +#define REG_0A0_LEN_WIDTH1_SHIFT 4 +#define REG_0A0_LEN_WIDTH1_MASK (0xF << REG_0A0_LEN_WIDTH1_SHIFT) +#define REG_0A0_LEN_WIDTH1(n) BITFIELD_VAL(REG_0A0_LEN_WIDTH1, n) +#define REG_0A0_LEN_WIDTH0_SHIFT 0 +#define REG_0A0_LEN_WIDTH0_MASK (0xF << REG_0A0_LEN_WIDTH0_SHIFT) +#define REG_0A0_LEN_WIDTH0(n) BITFIELD_VAL(REG_0A0_LEN_WIDTH0, n) +#endif + +// REG_0B0 +#define REG_0B0_ADDR3_REMAP_EN (1 << 4) +#define REG_0B0_ADDR2_REMAP_EN (1 << 3) +#define REG_0B0_ADDR1_REMAP_EN (1 << 2) +#define REG_0B0_ADDR0_REMAP_EN (1 << 1) +#define REG_0B0_GLB_REMAP_EN (1 << 0) +// End of since 2300p + +#if (CHIP_FLASH_CTRL_VER >= 3) +// REG_100 +#define REG_100_DUMMY_READ_SHIFT 0 +#define REG_100_DUMMY_READ_MASK (0x1F << REG_100_DUMMY_READ_SHIFT) +#define REG_100_DUMMY_READ(n) BITFIELD_VAL(REG_100_DUMMY_READ, n) + +// REG_104 +#define REG_104_DUMMY_DIOR_SHIFT 0 +#define REG_104_DUMMY_DIOR_MASK (0x1F << REG_104_DUMMY_DIOR_SHIFT) +#define REG_104_DUMMY_DIOR(n) BITFIELD_VAL(REG_104_DUMMY_DIOR, n) + +// REG_108 +#define REG_108_DUMMY_QIOR_SHIFT 0 +#define REG_108_DUMMY_QIOR_MASK (0x1F << REG_108_DUMMY_QIOR_SHIFT) +#define REG_108_DUMMY_QIOR(n) BITFIELD_VAL(REG_108_DUMMY_QIOR, n) + +// REG_10C +#define REG_10C_DUMMY_FREAD_SHIFT 0 +#define REG_10C_DUMMY_FREAD_MASK (0x1F << REG_10C_DUMMY_FREAD_SHIFT) +#define REG_10C_DUMMY_FREAD(n) BITFIELD_VAL(REG_10C_DUMMY_FREAD, n) + +// REG_110 +#define REG_110_DUMMY_DOR_SHIFT 0 +#define REG_110_DUMMY_DOR_MASK (0x1F << REG_110_DUMMY_DOR_SHIFT) +#define REG_110_DUMMY_DOR(n) BITFIELD_VAL(REG_110_DUMMY_DOR, n) + +// REG_114 +#define REG_114_DUMMY_QOR_SHIFT 0 +#define REG_114_DUMMY_QOR_MASK (0x1F << REG_114_DUMMY_QOR_SHIFT) +#define REG_114_DUMMY_QOR(n) BITFIELD_VAL(REG_114_DUMMY_QOR, n) + +// REG_118 +#define REG_118_DUMMY_QIOWR_SHIFT 0 +#define REG_118_DUMMY_QIOWR_MASK (0x1F << REG_118_DUMMY_QIOWR_SHIFT) +#define REG_118_DUMMY_QIOWR(n) BITFIELD_VAL(REG_118_DUMMY_QIOWR, n) + +// REG_11C +#define REG_11C_DUMMY_BRWR_SHIFT 0 +#define REG_11C_DUMMY_BRWR_MASK (0x1F << REG_11C_DUMMY_BRWR_SHIFT) +#define REG_11C_DUMMY_BRWR(n) BITFIELD_VAL(REG_11C_DUMMY_BRWR, n) + +// REG_120 +#define REG_120_DUMMY_BFRD_SHIFT 0 +#define REG_120_DUMMY_BFRD_MASK (0x1F << REG_120_DUMMY_BFRD_SHIFT) +#define REG_120_DUMMY_BFRD(n) BITFIELD_VAL(REG_120_DUMMY_BFRD, n) + +// REG_124 +#define REG_124_DUMMY_DTRFRD_SHIFT 0 +#define REG_124_DUMMY_DTRFRD_MASK (0x1F << REG_124_DUMMY_DTRFRD_SHIFT) +#define REG_124_DUMMY_DTRFRD(n) BITFIELD_VAL(REG_124_DUMMY_DTRFRD, n) + +// REG_128 +#define REG_128_DUMMY_DTR2RD_SHIFT 0 +#define REG_128_DUMMY_DTR2RD_MASK (0x1F << REG_128_DUMMY_DTR2RD_SHIFT) +#define REG_128_DUMMY_DTR2RD(n) BITFIELD_VAL(REG_128_DUMMY_DTR2RD, n) + +// REG_12C +#define REG_12C_DUMMY_DTR4RD_SHIFT 0 +#define REG_12C_DUMMY_DTR4RD_MASK (0x1F << REG_12C_DUMMY_DTR4RD_SHIFT) +#define REG_12C_DUMMY_DTR4RD(n) BITFIELD_VAL(REG_12C_DUMMY_DTR4RD, n) + +// REG_130 +#define REG_130_DUMMY_DTRRWR_SHIFT 0 +#define REG_130_DUMMY_DTRRWR_MASK (0x1F << REG_130_DUMMY_DTRRWR_SHIFT) +#define REG_130_DUMMY_DTRRWR(n) BITFIELD_VAL(REG_130_DUMMY_DTRRWR, n) + +// REG_134 +#define REG_134_DUMMY_OCTFRD_SHIFT 0 +#define REG_134_DUMMY_OCTFRD_MASK (0x1F << REG_134_DUMMY_OCTFRD_SHIFT) +#define REG_134_DUMMY_OCTFRD(n) BITFIELD_VAL(REG_134_DUMMY_OCTFRD, n) + +// REG_138 +#define REG_138_DUMMY_OCTIORD_SHIFT 0 +#define REG_138_DUMMY_OCTIORD_MASK (0x1F << REG_138_DUMMY_OCTIORD_SHIFT) +#define REG_138_DUMMY_OCTIORD(n) BITFIELD_VAL(REG_138_DUMMY_OCTIORD, n) + +// REG_13C +#define REG_13C_DUMMY_4BDTROCTRD_SHIFT 0 +#define REG_13C_DUMMY_4BDTROCTRD_MASK (0x1F << REG_13C_DUMMY_4BDTROCTRD_SHIFT) +#define REG_13C_DUMMY_4BDTROCTRD(n) BITFIELD_VAL(REG_13C_DUMMY_4BDTROCTRD, n) + +// REG_150 +#define REG_150_DUMMY_OTHERS_SHIFT 0 +#define REG_150_DUMMY_OTHERS_MASK (0x1F << REG_150_DUMMY_OTHERS_SHIFT) +#define REG_150_DUMMY_OTHERS(n) BITFIELD_VAL(REG_150_DUMMY_OTHERS, n) +#endif + +#endif + diff --git a/platform/hal/reg_psram_mc_v2.h b/platform/hal/reg_psram_mc_v2.h new file mode 100644 index 0000000..738ab1d --- /dev/null +++ b/platform/hal/reg_psram_mc_v2.h @@ -0,0 +1,604 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_PSRAM_MC_V2_H__ +#define __REG_PSRAM_MC_V2_H__ + +#include "plat_types.h" + +struct PSRAM_MC_T { + __IO uint32_t REG_000; + __IO uint32_t REG_004; + __IO uint32_t REG_008; + __IO uint32_t REG_00C; + __IO uint32_t REG_010; + __IO uint32_t REG_014; + __IO uint32_t REG_018; + __IO uint32_t REG_01C; + __IO uint32_t REG_020; + __IO uint32_t REG_024; + __IO uint32_t REG_028; + __IO uint32_t REG_02C; + __IO uint32_t REG_030; + __IO uint32_t REG_034; + __IO uint32_t REG_038; + __IO uint32_t REG_03C; + __IO uint32_t REG_040; + __IO uint32_t REG_044; + __IO uint32_t REG_048; + __IO uint32_t REG_04C; + __IO uint32_t REG_050; + __IO uint32_t REG_054; + __IO uint32_t REG_058; + __IO uint32_t REG_05C; + __IO uint32_t REG_060; + __IO uint32_t REG_064; + __IO uint32_t REG_068; + __IO uint32_t REG_06C; + __IO uint32_t REG_070; + __IO uint32_t REG_074; + __IO uint32_t REG_078; + __IO uint32_t REG_07C; + __IO uint32_t REG_080; + __IO uint32_t REG_084; + __IO uint32_t REG_088; + __IO uint32_t REG_08C; + __IO uint32_t REG_090; + __IO uint32_t REG_094; + __IO uint32_t REG_098; + __IO uint32_t REG_09C; + __IO uint32_t REG_0A0; + __IO uint32_t REG_0A4; + __IO uint32_t REG_0A8; + __IO uint32_t REG_0AC; + __IO uint32_t REG_0B0; + __IO uint32_t REG_0B4; + __IO uint32_t REG_0B8; + __IO uint32_t REG_0BC; + __IO uint32_t REG_RESERVED_0C0[0x20]; + __IO uint32_t REG_140; + __IO uint32_t REG_144; + __IO uint32_t REG_148; + __IO uint32_t REG_14C; + __IO uint32_t REG_150; + __IO uint32_t REG_154; + __IO uint32_t REG_158; + __IO uint32_t REG_15C; + __IO uint32_t REG_160; + __IO uint32_t REG_RESERVED_164[7]; + __IO uint32_t REG_180; + __IO uint32_t REG_184; + __IO uint32_t REG_188; + __IO uint32_t REG_18C; + __IO uint32_t REG_190; + __IO uint32_t REG_194; + __IO uint32_t REG_RESERVED_198[0x1A]; + __IO uint32_t REG_200; + __IO uint32_t REG_RESERVED_204[0x7F]; + __IO uint32_t REG_400; + __IO uint32_t REG_404; + __IO uint32_t REG_RESERVED_408[0xE]; + __IO uint32_t REG_440; + __IO uint32_t REG_444; + __IO uint32_t REG_448; + __IO uint32_t REG_44C; + __IO uint32_t REG_450; + __IO uint32_t REG_454; + __IO uint32_t REG_458; + __IO uint32_t REG_45C; + __IO uint32_t REG_460; + __IO uint32_t REG_464; + __IO uint32_t REG_468; + __IO uint32_t REG_46C; +}; + +// reg_00 +#define PSRAM_ULP_MC_CHIP_BIT (1 << 0) +#define PSRAM_ULP_MC_CHIP_TYPE (1 << 1) +#define PSRAM_ULP_MC_RES_3_2_REG00 (1 << 2) +#define PSRAM_ULP_MC_CHIP_CA_PATTERN(n) (((n) & 0x7) << 3) +#define PSRAM_ULP_MC_CHIP_CA_PATTERN_MASK (0x7 << 3) +#define PSRAM_ULP_MC_CHIP_CA_PATTERN_SHIFT (3) + +// reg_04 +#define PSRAM_ULP_MC_MGR_CMD(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_MGR_CMD_MASK (0xFF << 0) +#define PSRAM_ULP_MC_MGR_CMD_SHIFT (0) + +// reg_08 +#define PSRAM_ULP_MC_MGR_ADDR(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_MGR_ADDR_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_MGR_ADDR_SHIFT (0) + +// reg_0c +#define PSRAM_ULP_MC_MGR_LEN(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_MGR_LEN_MASK (0xFF << 0) +#define PSRAM_ULP_MC_MGR_LEN_SHIFT (0) + +// reg_10 +#define PSRAM_ULP_MC_MGR_WSTRB(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_MGR_WSTRB_MASK (0xFF << 0) +#define PSRAM_ULP_MC_MGR_WSTRB_SHIFT (0) + +// reg_14 +#define PSRAM_ULP_MC_MGR_TX_FIFO(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_MGR_TX_FIFO_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_MGR_TX_FIFO_SHIFT (0) + +// reg_18 +#define PSRAM_ULP_MC_MGR_RX_FIFO(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_MGR_RX_FIFO_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_MGR_RX_FIFO_SHIFT (0) + +// reg_1c +#define PSRAM_ULP_MC_MGR_TX_FIFO_CLR (1 << 0) +#define PSRAM_ULP_MC_MGR_RX_FIFO_CLR (1 << 1) + +// reg_20 +#define PSRAM_ULP_MC_REFRESH_MODE (1 << 0) +#define PSRAM_ULP_MC_BURST_REFRESH_EN (1 << 1) + +// reg_24 +#define PSRAM_ULP_MC_ENTRY_SLEEP_IDLE (1 << 0) +#define PSRAM_ULP_MC_ENTRY_SELF_REFRESH_IDLE (1 << 1) +#define PSRAM_ULP_MC_STOP_CLK_IDLE (1 << 2) +#define PSRAM_ULP_MC_AUTOWAKEUP_EN (1 << 3) +#define PSRAM_ULP_MC_RES_7_4_REG24(n) (((n) & 0xF) << 4) +#define PSRAM_ULP_MC_RES_7_4_REG24_MASK (0xF << 4) +#define PSRAM_ULP_MC_RES_7_4_REG24_SHIFT (4) +#define PSRAM_ULP_MC_PD_MR(n) (((n) & 0xFF) << 8) +#define PSRAM_ULP_MC_PD_MR_MASK (0xFF << 8) +#define PSRAM_ULP_MC_PD_MR_SHIFT (8) +#define PSRAM_ULP_MC_PD_CMD(n) (((n) & 0xFF) << 16) +#define PSRAM_ULP_MC_PD_CMD_MASK (0xFF << 16) +#define PSRAM_ULP_MC_PD_CMD_SHIFT (16) + +// reg_28 +#define PSRAM_ULP_MC_WRITE_LATENCY(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_WRITE_LATENCY_MASK (0xFF << 0) +#define PSRAM_ULP_MC_WRITE_LATENCY_SHIFT (0) + +// reg_2c +#define PSRAM_ULP_MC_READ_LATENCY(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_READ_LATENCY_MASK (0xFF << 0) +#define PSRAM_ULP_MC_READ_LATENCY_SHIFT (0) + +// reg_30 +#define PSRAM_ULP_MC_MEMORY_WIDTH(n) (((n) & 0x3) << 0) +#define PSRAM_ULP_MC_MEMORY_WIDTH_MASK (0x3 << 0) +#define PSRAM_ULP_MC_MEMORY_WIDTH_SHIFT (0) + +// reg_34 +#define PSRAM_ULP_MC_BURST_LENGTH(n) (((n) & 0x7) << 0) +#define PSRAM_ULP_MC_BURST_LENGTH_MASK (0x7 << 0) +#define PSRAM_ULP_MC_BURST_LENGTH_SHIFT (0) +#define PSRAM_ULP_MC_RES_3_3_REG34 (1 << 3) +#define PSRAM_ULP_MC_PAGE_BOUNDARY(n) (((n) & 0x3) << 4) +#define PSRAM_ULP_MC_PAGE_BOUNDARY_MASK (0x3 << 4) +#define PSRAM_ULP_MC_PAGE_BOUNDARY_SHIFT (4) + +// reg_38 +#define PSRAM_ULP_MC_BUS_WIDTH (1 << 0) + +// reg_3c +#define PSRAM_ULP_MC_HIGH_PRI_LEVEL(n) (((n) & 0x1F) << 0) +#define PSRAM_ULP_MC_HIGH_PRI_LEVEL_MASK (0x1F << 0) +#define PSRAM_ULP_MC_HIGH_PRI_LEVEL_SHIFT (0) + +// reg_40 +#define PSRAM_ULP_MC_CP_WRAP_EN (1 << 0) +#define PSRAM_ULP_MC_AUTO_PRECHARGE (1 << 1) +#define PSRAM_ULP_MC_WRAP_CRT_RET_EN (1 << 2) + +// reg_44 +#define PSRAM_ULP_MC_WB_DRAIN (1 << 0) +#define PSRAM_ULP_MC_WB_INVALID (1 << 1) +#define PSRAM_ULP_MC_RB_INVALID (1 << 2) +#define PSRAM_ULP_MC_SNP_DISABLE (1 << 3) +#define PSRAM_ULP_MC_BUFFERABLE_WB_EN (1 << 4) + +// reg_48 +#define PSRAM_ULP_MC_FRE_RATIO(n) (((n) & 0x3) << 0) +#define PSRAM_ULP_MC_FRE_RATIO_MASK (0x3 << 0) +#define PSRAM_ULP_MC_FRE_RATIO_SHIFT (0) + +// reg_4c +#define PSRAM_ULP_MC_T_REFI(n) (((n) & 0xFFFF) << 0) +#define PSRAM_ULP_MC_T_REFI_MASK (0xFFFF << 0) +#define PSRAM_ULP_MC_T_REFI_SHIFT (0) +#define PSRAM_ULP_MC_NUM_OF_BURST_RFS(n) (((n) & 0xFFFF) << 16) +#define PSRAM_ULP_MC_NUM_OF_BURST_RFS_MASK (0xFFFF << 16) +#define PSRAM_ULP_MC_NUM_OF_BURST_RFS_SHIFT (16) + +// reg_50 +#define PSRAM_ULP_MC_T_RC(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_T_RC_MASK (0xFF << 0) +#define PSRAM_ULP_MC_T_RC_SHIFT (0) + +// reg_54 +#define PSRAM_ULP_MC_T_RFC(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_T_RFC_MASK (0xFF << 0) +#define PSRAM_ULP_MC_T_RFC_SHIFT (0) + +// reg_58 +#define PSRAM_ULP_MC_T_CPHR(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_MC_T_CPHR_MASK (0x3F << 0) +#define PSRAM_ULP_MC_T_CPHR_SHIFT (0) + +// reg_5c +#define PSRAM_ULP_MC_T_CPHR_AP(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_MC_T_CPHR_AP_MASK (0x3F << 0) +#define PSRAM_ULP_MC_T_CPHR_AP_SHIFT (0) + +// reg_60 +#define PSRAM_ULP_MC_T_CPHW(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_MC_T_CPHW_MASK (0x3F << 0) +#define PSRAM_ULP_MC_T_CPHW_SHIFT (0) + +// reg_64 +#define PSRAM_ULP_MC_T_CPHW_AP(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_MC_T_CPHW_AP_MASK (0x3F << 0) +#define PSRAM_ULP_MC_T_CPHW_AP_SHIFT (0) + +// reg_68 +#define PSRAM_ULP_MC_T_MRR(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_MC_T_MRR_MASK (0x3F << 0) +#define PSRAM_ULP_MC_T_MRR_SHIFT (0) + +// reg_6c +#define PSRAM_ULP_MC_T_MRS(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_MC_T_MRS_MASK (0x3F << 0) +#define PSRAM_ULP_MC_T_MRS_SHIFT (0) + +// reg_70 +#define PSRAM_ULP_MC_T_CEM(n) (((n) & 0xFFFF) << 0) +#define PSRAM_ULP_MC_T_CEM_MASK (0xFFFF << 0) +#define PSRAM_ULP_MC_T_CEM_SHIFT (0) + +// reg_74 +#define PSRAM_ULP_MC_T_RST(n) (((n) & 0xFFFF) << 0) +#define PSRAM_ULP_MC_T_RST_MASK (0xFFFF << 0) +#define PSRAM_ULP_MC_T_RST_SHIFT (0) + +// reg_78 +#define PSRAM_ULP_MC_T_SRF(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_T_SRF_MASK (0xFF << 0) +#define PSRAM_ULP_MC_T_SRF_SHIFT (0) + +// reg_7c +#define PSRAM_ULP_MC_T_XSR(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_T_XSR_MASK (0xFF << 0) +#define PSRAM_ULP_MC_T_XSR_SHIFT (0) + +// reg_80 +#define PSRAM_ULP_MC_T_HS(n) (((n) & 0xFFFF) << 0) +#define PSRAM_ULP_MC_T_HS_MASK (0xFFFF << 0) +#define PSRAM_ULP_MC_T_HS_SHIFT (0) + +// reg_84 +#define PSRAM_ULP_MC_T_XPHS(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_T_XPHS_MASK (0xFF << 0) +#define PSRAM_ULP_MC_T_XPHS_SHIFT (0) + +// reg_88 +#define PSRAM_ULP_MC_T_XHS(n) (((n) & 0xFFFFF) << 0) +#define PSRAM_ULP_MC_T_XHS_MASK (0xFFFFF << 0) +#define PSRAM_ULP_MC_T_XHS_SHIFT (0) + +// reg_8c +#define PSRAM_ULP_MC_T_ZQCAL(n) (((n) & 0xFFFFF) << 0) +#define PSRAM_ULP_MC_T_ZQCAL_MASK (0xFFFFF << 0) +#define PSRAM_ULP_MC_T_ZQCAL_SHIFT (0) + +// reg_90 +#define PSRAM_ULP_MC_T_ZQCRST(n) (((n) & 0xFFFFF) << 0) +#define PSRAM_ULP_MC_T_ZQCRST_MASK (0xFFFFF << 0) +#define PSRAM_ULP_MC_T_ZQCRST_SHIFT (0) + +// reg_94 +#define PSRAM_ULP_MC_T_XCKD(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_MC_T_XCKD_MASK (0x3F << 0) +#define PSRAM_ULP_MC_T_XCKD_SHIFT (0) + +// reg_98 +#define PSRAM_ULP_MC_T_ECKD(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_MC_T_ECKD_MASK (0x3F << 0) +#define PSRAM_ULP_MC_T_ECKD_SHIFT (0) + +// reg_9c +#define PSRAM_ULP_MC_WR_DMY_CYC(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_WR_DMY_CYC_MASK (0xFF << 0) +#define PSRAM_ULP_MC_WR_DMY_CYC_SHIFT (0) + +// reg_a0 +#define PSRAM_ULP_MC_STOP_CLK_IN_NOP (1 << 0) +#define PSRAM_ULP_MC_NOP_DMY_CYC(n) (((n) & 0xFF) << 1) +#define PSRAM_ULP_MC_NOP_DMY_CYC_MASK (0xFF << 1) +#define PSRAM_ULP_MC_NOP_DMY_CYC_SHIFT (1) + +// reg_a4 +#define PSRAM_ULP_MC_QUEUE_IDLE_CYCLE(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_QUEUE_IDLE_CYCLE_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_QUEUE_IDLE_CYCLE_SHIFT (0) + +// reg_a8 +#define PSRAM_ULP_MC_T_EXPANDRD(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_MC_T_EXPANDRD_MASK (0x3F << 0) +#define PSRAM_ULP_MC_T_EXPANDRD_SHIFT (0) + +// reg_ac +#define PSRAM_ULP_MC_RX_SYNC_BYPASS (1 << 0) + +// reg_b4 +#define PSRAM_ULP_MC_T_ZQCAS(n) (((n) & 0xFFFFF) << 0) +#define PSRAM_ULP_MC_T_ZQCAS_MASK (0xFFFFF << 0) +#define PSRAM_ULP_MC_T_ZQCAS_SHIFT (0) + +// reg_b8 +#define PSRAM_ULP_MC_T_NEW_HOLD(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_T_NEW_HOLD_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_T_NEW_HOLD_SHIFT (0) + +// reg_bc +#define PSRAM_ULP_MC_NEW_CMD_OP(n) (((n) & 0x7) << 0) +#define PSRAM_ULP_MC_NEW_CMD_OP_MASK (0x7 << 0) +#define PSRAM_ULP_MC_NEW_CMD_OP_SHIFT (0) + +// reg_140 +#define PSRAM_ULP_MC_CMD_TABLE_ARRAY_RD(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_CMD_TABLE_ARRAY_RD_MASK (0xFF << 0) +#define PSRAM_ULP_MC_CMD_TABLE_ARRAY_RD_SHIFT (0) + +// reg_144 +#define PSRAM_ULP_MC_CMD_TABLE_ARRAY_WR(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_CMD_TABLE_ARRAY_WR_MASK (0xFF << 0) +#define PSRAM_ULP_MC_CMD_TABLE_ARRAY_WR_SHIFT (0) + +// reg_148 +#define PSRAM_ULP_MC_CMD_TABLE_REG_RD(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_CMD_TABLE_REG_RD_MASK (0xFF << 0) +#define PSRAM_ULP_MC_CMD_TABLE_REG_RD_SHIFT (0) + +// reg_14c +#define PSRAM_ULP_MC_CMD_TABLE_REG_WR(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_CMD_TABLE_REG_WR_MASK (0xFF << 0) +#define PSRAM_ULP_MC_CMD_TABLE_REG_WR_SHIFT (0) + +// reg_150 +#define PSRAM_ULP_MC_CMD_TABLE_AUTO_REFR(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_CMD_TABLE_AUTO_REFR_MASK (0xFF << 0) +#define PSRAM_ULP_MC_CMD_TABLE_AUTO_REFR_SHIFT (0) + +// reg_154 +#define PSRAM_ULP_MC_CMD_TABLE_SELF_REFR(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_CMD_TABLE_SELF_REFR_MASK (0xFF << 0) +#define PSRAM_ULP_MC_CMD_TABLE_SELF_REFR_SHIFT (0) + +// reg_158 +#define PSRAM_ULP_MC_CMD_TABLE_HSLP_ENTRY(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_CMD_TABLE_HSLP_ENTRY_MASK (0xFF << 0) +#define PSRAM_ULP_MC_CMD_TABLE_HSLP_ENTRY_SHIFT (0) + +// reg_15c +#define PSRAM_ULP_MC_CMD_TABLE_GLBRST(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_CMD_TABLE_GLBRST_MASK (0xFF << 0) +#define PSRAM_ULP_MC_CMD_TABLE_GLBRST_SHIFT (0) + +// reg_160 +#define PSRAM_ULP_MC_CMD_TABLE_NOP(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_CMD_TABLE_NOP_MASK (0xFF << 0) +#define PSRAM_ULP_MC_CMD_TABLE_NOP_SHIFT (0) + +// reg_180 +#define PSRAM_ULP_MC_CA_MAP_BIT0(n) (((n) & 0x1F) << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT0_MASK (0x1F << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT0_SHIFT (0) +#define PSRAM_ULP_MC_CA_MAP_BIT1(n) (((n) & 0x1F) << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT1_MASK (0x1F << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT1_SHIFT (5) +#define PSRAM_ULP_MC_CA_MAP_BIT2(n) (((n) & 0x1F) << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT2_MASK (0x1F << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT2_SHIFT (10) +#define PSRAM_ULP_MC_CA_MAP_BIT3(n) (((n) & 0x1F) << 15) +#define PSRAM_ULP_MC_CA_MAP_BIT3_MASK (0x1F << 15) +#define PSRAM_ULP_MC_CA_MAP_BIT3_SHIFT (15) +#define PSRAM_ULP_MC_CA_MAP_BIT4(n) (((n) & 0x1F) << 20) +#define PSRAM_ULP_MC_CA_MAP_BIT4_MASK (0x1F << 20) +#define PSRAM_ULP_MC_CA_MAP_BIT4_SHIFT (20) +#define PSRAM_ULP_MC_CA_MAP_BIT5(n) (((n) & 0x1F) << 25) +#define PSRAM_ULP_MC_CA_MAP_BIT5_MASK (0x1F << 25) +#define PSRAM_ULP_MC_CA_MAP_BIT5_SHIFT (25) + +// reg_184 +#define PSRAM_ULP_MC_CA_MAP_BIT6(n) (((n) & 0x1F) << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT6_MASK (0x1F << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT6_SHIFT (0) +#define PSRAM_ULP_MC_CA_MAP_BIT7(n) (((n) & 0x1F) << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT7_MASK (0x1F << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT7_SHIFT (5) +#define PSRAM_ULP_MC_CA_MAP_BIT8(n) (((n) & 0x1F) << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT8_MASK (0x1F << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT8_SHIFT (10) +#define PSRAM_ULP_MC_CA_MAP_BIT9(n) (((n) & 0x1F) << 15) +#define PSRAM_ULP_MC_CA_MAP_BIT9_MASK (0x1F << 15) +#define PSRAM_ULP_MC_CA_MAP_BIT9_SHIFT (15) +#define PSRAM_ULP_MC_CA_MAP_BIT10(n) (((n) & 0x1F) << 20) +#define PSRAM_ULP_MC_CA_MAP_BIT10_MASK (0x1F << 20) +#define PSRAM_ULP_MC_CA_MAP_BIT10_SHIFT (20) +#define PSRAM_ULP_MC_CA_MAP_BIT11(n) (((n) & 0x1F) << 25) +#define PSRAM_ULP_MC_CA_MAP_BIT11_MASK (0x1F << 25) +#define PSRAM_ULP_MC_CA_MAP_BIT11_SHIFT (25) + +// reg_188 +#define PSRAM_ULP_MC_CA_MAP_BIT12(n) (((n) & 0x1F) << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT12_MASK (0x1F << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT12_SHIFT (0) +#define PSRAM_ULP_MC_CA_MAP_BIT13(n) (((n) & 0x1F) << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT13_MASK (0x1F << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT13_SHIFT (5) +#define PSRAM_ULP_MC_CA_MAP_BIT14(n) (((n) & 0x1F) << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT14_MASK (0x1F << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT14_SHIFT (10) +#define PSRAM_ULP_MC_CA_MAP_BIT15(n) (((n) & 0x1F) << 15) +#define PSRAM_ULP_MC_CA_MAP_BIT15_MASK (0x1F << 15) +#define PSRAM_ULP_MC_CA_MAP_BIT15_SHIFT (15) +#define PSRAM_ULP_MC_CA_MAP_BIT16(n) (((n) & 0x1F) << 20) +#define PSRAM_ULP_MC_CA_MAP_BIT16_MASK (0x1F << 20) +#define PSRAM_ULP_MC_CA_MAP_BIT16_SHIFT (20) +#define PSRAM_ULP_MC_CA_MAP_BIT17(n) (((n) & 0x1F) << 25) +#define PSRAM_ULP_MC_CA_MAP_BIT17_MASK (0x1F << 25) +#define PSRAM_ULP_MC_CA_MAP_BIT17_SHIFT (25) + +// reg_18c +#define PSRAM_ULP_MC_CA_MAP_BIT18(n) (((n) & 0x1F) << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT18_MASK (0x1F << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT18_SHIFT (0) +#define PSRAM_ULP_MC_CA_MAP_BIT19(n) (((n) & 0x1F) << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT19_MASK (0x1F << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT19_SHIFT (5) +#define PSRAM_ULP_MC_CA_MAP_BIT20(n) (((n) & 0x1F) << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT20_MASK (0x1F << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT20_SHIFT (10) +#define PSRAM_ULP_MC_CA_MAP_BIT21(n) (((n) & 0x1F) << 15) +#define PSRAM_ULP_MC_CA_MAP_BIT21_MASK (0x1F << 15) +#define PSRAM_ULP_MC_CA_MAP_BIT21_SHIFT (15) +#define PSRAM_ULP_MC_CA_MAP_BIT22(n) (((n) & 0x1F) << 20) +#define PSRAM_ULP_MC_CA_MAP_BIT22_MASK (0x1F << 20) +#define PSRAM_ULP_MC_CA_MAP_BIT22_SHIFT (20) +#define PSRAM_ULP_MC_CA_MAP_BIT23(n) (((n) & 0x1F) << 25) +#define PSRAM_ULP_MC_CA_MAP_BIT23_MASK (0x1F << 25) +#define PSRAM_ULP_MC_CA_MAP_BIT23_SHIFT (25) + +// reg_190 +#define PSRAM_ULP_MC_CA_MAP_BIT24(n) (((n) & 0x1F) << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT24_MASK (0x1F << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT24_SHIFT (0) +#define PSRAM_ULP_MC_CA_MAP_BIT25(n) (((n) & 0x1F) << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT25_MASK (0x1F << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT25_SHIFT (5) +#define PSRAM_ULP_MC_CA_MAP_BIT26(n) (((n) & 0x1F) << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT26_MASK (0x1F << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT26_SHIFT (10) +#define PSRAM_ULP_MC_CA_MAP_BIT27(n) (((n) & 0x1F) << 15) +#define PSRAM_ULP_MC_CA_MAP_BIT27_MASK (0x1F << 15) +#define PSRAM_ULP_MC_CA_MAP_BIT27_SHIFT (15) +#define PSRAM_ULP_MC_CA_MAP_BIT28(n) (((n) & 0x1F) << 20) +#define PSRAM_ULP_MC_CA_MAP_BIT28_MASK (0x1F << 20) +#define PSRAM_ULP_MC_CA_MAP_BIT28_SHIFT (20) +#define PSRAM_ULP_MC_CA_MAP_BIT29(n) (((n) & 0x1F) << 25) +#define PSRAM_ULP_MC_CA_MAP_BIT29_MASK (0x1F << 25) +#define PSRAM_ULP_MC_CA_MAP_BIT29_SHIFT (25) + +// reg_194 +#define PSRAM_ULP_MC_CA_MAP_BIT30(n) (((n) & 0x1F) << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT30_MASK (0x1F << 0) +#define PSRAM_ULP_MC_CA_MAP_BIT30_SHIFT (0) +#define PSRAM_ULP_MC_CA_MAP_BIT31(n) (((n) & 0x1F) << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT31_MASK (0x1F << 5) +#define PSRAM_ULP_MC_CA_MAP_BIT31_SHIFT (5) +#define PSRAM_ULP_MC_CA_MAP_BIT32(n) (((n) & 0x1F) << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT32_MASK (0x1F << 10) +#define PSRAM_ULP_MC_CA_MAP_BIT32_SHIFT (10) + +// reg_190 + +// reg_200 +#define PSRAM_ULP_MC_RESERVED_0(n) (((n) & 0xFF) << 0) +#define PSRAM_ULP_MC_RESERVED_0_MASK (0xFF << 0) +#define PSRAM_ULP_MC_RESERVED_0_SHIFT (0) + +// reg_400 +#define PSRAM_ULP_MC_INIT_COMPLETE (1 << 0) + +// reg_404 +#define PSRAM_ULP_MC_BUSY (1 << 0) +#define PSRAM_ULP_MC_MGR_RXFIFO_R_EMPTY (1 << 1) +#define PSRAM_ULP_MC_MGR_RXFIFO_FULL_CNT(n) (((n) & 0xF) << 2) +#define PSRAM_ULP_MC_MGR_RXFIFO_FULL_CNT_MASK (0xF << 2) +#define PSRAM_ULP_MC_MGR_RXFIFO_FULL_CNT_SHIFT (2) +#define PSRAM_ULP_MC_MGR_TXFIFO_W_FULL (1 << 6) +#define PSRAM_ULP_MC_MGR_TXFIFO_EMPTY_CNT(n) (((n) & 0xF) << 7) +#define PSRAM_ULP_MC_MGR_TXFIFO_EMPTY_CNT_MASK (0xF << 7) +#define PSRAM_ULP_MC_MGR_TXFIFO_EMPTY_CNT_SHIFT (7) +#define PSRAM_ULP_MC_WB_FILL_LEVEL(n) (((n) & 0x1F) << 11) +#define PSRAM_ULP_MC_WB_FILL_LEVEL_MASK (0x1F << 11) +#define PSRAM_ULP_MC_WB_FILL_LEVEL_SHIFT (11) +#define PSRAM_ULP_MC_CP_FSM_STATE(n) (((n) & 0xF) << 16) +#define PSRAM_ULP_MC_CP_FSM_STATE_MASK (0xF << 16) +#define PSRAM_ULP_MC_CP_FSM_STATE_SHIFT (16) +#define PSRAM_ULP_MC_RD_FSM(n) (((n) & 0x3) << 20) +#define PSRAM_ULP_MC_RD_FSM_MASK (0x3 << 20) +#define PSRAM_ULP_MC_RD_FSM_SHIFT (20) + +// reg_440 +#define PSRAM_ULP_MC_PMU_MONITOR_START (1 << 0) +#define PSRAM_ULP_MC_PMU_MONITOR_END (1 << 1) + +// reg_444 +#define PSRAM_ULP_MC_PMU_TOL_MON_CLK_CYCLE0(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_PMU_TOL_MON_CLK_CYCLE0_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_PMU_TOL_MON_CLK_CYCLE0_SHIFT (0) + +// reg_448 +#define PSRAM_ULP_MC_PMU_TOL_MON_CLK_CYCLE1(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_PMU_TOL_MON_CLK_CYCLE1_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_PMU_TOL_MON_CLK_CYCLE1_SHIFT (0) + +// reg_44c +#define PSRAM_ULP_MC_PMU_TOL_WR_DATA_BYTES0(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_PMU_TOL_WR_DATA_BYTES0_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_PMU_TOL_WR_DATA_BYTES0_SHIFT (0) + +// reg_450 +#define PSRAM_ULP_MC_PMU_TOL_WR_DATA_BYTES1(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_PMU_TOL_WR_DATA_BYTES1_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_PMU_TOL_WR_DATA_BYTES1_SHIFT (0) + +// reg_454 +#define PSRAM_ULP_MC_PMU_TOL_RD_DATA_BYTES0(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_DATA_BYTES0_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_DATA_BYTES0_SHIFT (0) + +// reg_458 +#define PSRAM_ULP_MC_PMU_TOL_RD_DATA_BYTES1(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_DATA_BYTES1_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_DATA_BYTES1_SHIFT (0) + +// reg_45c +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_LATENCY0(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_LATENCY0_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_LATENCY0_SHIFT (0) + +// reg_460 +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_LATENCY1(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_LATENCY1_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_LATENCY1_SHIFT (0) + +// reg_464 +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_NUM0(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_NUM0_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_NUM0_SHIFT (0) + +// reg_468 +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_NUM1(n) (((n) & 0xFFFFFFFF) << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_NUM1_MASK (0xFFFFFFFF << 0) +#define PSRAM_ULP_MC_PMU_TOL_RD_ACC_NUM1_SHIFT (0) + +// reg_46c +#define PSRAM_ULP_MC_PMU_MAX_RD_ACC_LATENCY(n) (((n) & 0xFFFF) << 0) +#define PSRAM_ULP_MC_PMU_MAX_RD_ACC_LATENCY_MASK (0xFFFF << 0) +#define PSRAM_ULP_MC_PMU_MAX_RD_ACC_LATENCY_SHIFT (0) + +#endif diff --git a/platform/hal/reg_psram_phy_v2.h b/platform/hal/reg_psram_phy_v2.h new file mode 100644 index 0000000..c3e2914 --- /dev/null +++ b/platform/hal/reg_psram_phy_v2.h @@ -0,0 +1,153 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_PSRAM_PHY_V2_H__ +#define __REG_PSRAM_PHY_V2_H__ + +#include "plat_types.h" + +struct PSRAM_PHY_T { + __IO uint32_t REG_000; + __IO uint32_t REG_004; + __IO uint32_t REG_008; + __IO uint32_t REG_00C; + __IO uint32_t REG_010; + __IO uint32_t REG_014; + __IO uint32_t REG_018; + __IO uint32_t REG_01C; + __IO uint32_t REG_020; + __IO uint32_t REG_024; + __IO uint32_t REG_028; + __IO uint32_t REG_02C; + __IO uint32_t REG_030; + __IO uint32_t REG_034; + __IO uint32_t REG_038; + __IO uint32_t REG_03C; + __IO uint32_t REG_040; + __IO uint32_t REG_044; + __IO uint32_t REG_048; + __IO uint32_t REG_04C; + __IO uint32_t REG_050; + __IO uint32_t REG_054; + __IO uint32_t REG_058; + __IO uint32_t REG_05C; +}; + +// reg_00 +#define PSRAM_ULP_PHY_CHIP_TYPE (1 << 0) +#define PSRAM_ULP_PHY_CHIP_BIT (1 << 1) +#define PSRAM_ULP_PHY_MEMORY_WIDTH(n) (((n) & 0x3) << 2) +#define PSRAM_ULP_PHY_MEMORY_WIDTH_MASK (0x3 << 2) +#define PSRAM_ULP_PHY_MEMORY_WIDTH_SHIFT (2) +#define PSRAM_ULP_PHY_FRE_RATIO(n) (((n) & 0x3) << 4) +#define PSRAM_ULP_PHY_FRE_RATIO_MASK (0x3 << 4) +#define PSRAM_ULP_PHY_FRE_RATIO_SHIFT (4) + +// reg_04 +#define PSRAM_ULP_PHY_CTRL_DELAY(n) (((n) & 0x3) << 0) +#define PSRAM_ULP_PHY_CTRL_DELAY_MASK (0x3 << 0) +#define PSRAM_ULP_PHY_CTRL_DELAY_SHIFT (0) +#define PSRAM_ULP_PHY_RX_DLY_EN (1 << 2) +#define PSRAM_ULP_PHY_ALIGN_BYPASS (1 << 3) +#define PSRAM_ULP_PHY_PHY_LOOPBACK_EN (1 << 4) +#define PSRAM_ULP_PHY_PHY_DUMMY_CYC_EN (1 << 5) + +// reg_08 +#define PSRAM_ULP_PHY_T_WPST(n) (((n) & 0x7) << 0) +#define PSRAM_ULP_PHY_T_WPST_MASK (0x7 << 0) +#define PSRAM_ULP_PHY_T_WPST_SHIFT (0) + +// reg_0c +#define PSRAM_ULP_PHY_RESERVED(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_PHY_RESERVED_MASK (0x3F << 0) +#define PSRAM_ULP_PHY_RESERVED_SHIFT (0) + +// reg_00 + +// reg_10 +#define PSRAM_ULP_PHY_CMD_CONFLICT_CLR (1 << 0) + +// reg_40 +#define PSRAM_ULP_PHY_PHY_CFG_UPDATE (1 << 0) + +// reg_44 +#define PSRAM_ULP_PHY_CMD_CONFLICT_STS (1 << 0) +#define PSRAM_ULP_PHY_PHY_FSM_STATE(n) (((n) & 0xF) << 1) +#define PSRAM_ULP_PHY_PHY_FSM_STATE_MASK (0xF << 1) +#define PSRAM_ULP_PHY_PHY_FSM_STATE_SHIFT (1) + +// reg_48 +#define PSRAM_ULP_PHY_REG_LDO_PU (1 << 0) +#define PSRAM_ULP_PHY_REG_LDO_PRECHARGE (1 << 1) +#define PSRAM_ULP_PHY_REG_LDO_IEN1(n) (((n) & 0xF) << 2) +#define PSRAM_ULP_PHY_REG_LDO_IEN1_MASK (0xF << 2) +#define PSRAM_ULP_PHY_REG_LDO_IEN1_SHIFT (2) +#define PSRAM_ULP_PHY_REG_LDO_IEN2(n) (((n) & 0xF) << 6) +#define PSRAM_ULP_PHY_REG_LDO_IEN2_MASK (0xF << 6) +#define PSRAM_ULP_PHY_REG_LDO_IEN2_SHIFT (6) +#define PSRAM_ULP_PHY_REG_LDO_VTUNE(n) (((n) & 0x7) << 10) +#define PSRAM_ULP_PHY_REG_LDO_VTUNE_MASK (0x7 << 10) +#define PSRAM_ULP_PHY_REG_LDO_VTUNE_SHIFT (10) + +// reg_4c +#define PSRAM_ULP_PHY_REG_PSRAM_PU (1 << 0) +#define PSRAM_ULP_PHY_REG_PSRAM_SWRC(n) (((n) & 0x3) << 1) +#define PSRAM_ULP_PHY_REG_PSRAM_SWRC_MASK (0x3 << 1) +#define PSRAM_ULP_PHY_REG_PSRAM_SWRC_SHIFT (1) +#define PSRAM_ULP_PHY_REG_PSRAM_TXDRV(n) (((n) & 0x7) << 3) +#define PSRAM_ULP_PHY_REG_PSRAM_TXDRV_MASK (0x7 << 3) +#define PSRAM_ULP_PHY_REG_PSRAM_TXDRV_SHIFT (3) +#define PSRAM_ULP_PHY_REG_PSRAM_LOOPBACK_EN (1 << 6) + +// reg_50 +#define PSRAM_ULP_PHY_REG_DLL_PU (1 << 0) +#define PSRAM_ULP_PHY_REG_DLL_SWRC(n) (((n) & 0x3) << 1) +#define PSRAM_ULP_PHY_REG_DLL_SWRC_MASK (0x3 << 1) +#define PSRAM_ULP_PHY_REG_DLL_SWRC_SHIFT (1) +#define PSRAM_ULP_PHY_REG_DLL_RANGE(n) (((n) & 0x3) << 3) +#define PSRAM_ULP_PHY_REG_DLL_RANGE_MASK (0x3 << 3) +#define PSRAM_ULP_PHY_REG_DLL_RANGE_SHIFT (3) +#define PSRAM_ULP_PHY_REG_DLL_DLY_INI(n) (((n) & 0xFF) << 5) +#define PSRAM_ULP_PHY_REG_DLL_DLY_INI_MASK (0xFF << 5) +#define PSRAM_ULP_PHY_REG_DLL_DLY_INI_SHIFT (5) +#define PSRAM_ULP_PHY_REG_DLL(n) (((n) & 0xFF) << 13) +#define PSRAM_ULP_PHY_REG_DLL_MASK (0xFF << 13) +#define PSRAM_ULP_PHY_REG_DLL_SHIFT (13) +#define PSRAM_ULP_PHY_REG_DLL_RESETB (1 << 21) +#define PSRAM_ULP_PHY_REG_DLL_CK_RDY (1 << 22) + +// reg_54 +#define PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY(n) (((n) & 0x1F) << 0) +#define PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY_MASK (0x1F << 0) +#define PSRAM_ULP_PHY_REG_PSRAM_TX_CEB_DLY_SHIFT (0) +#define PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY(n) (((n) & 0x1F) << 5) +#define PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY_MASK (0x1F << 5) +#define PSRAM_ULP_PHY_REG_PSRAM_TX_CLK_DLY_SHIFT (5) +#define PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY(n) (((n) & 0x1F) << 10) +#define PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_MASK (0x1F << 10) +#define PSRAM_ULP_PHY_REG_PSRAM_TX_DQS_DLY_SHIFT (10) +#define PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY(n) (((n) & 0x1F) << 15) +#define PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY_MASK (0x1F << 15) +#define PSRAM_ULP_PHY_REG_PSRAM_RX_DQS_DLY_SHIFT (15) + +// reg_58 +#define PSRAM_ULP_PHY_DLL_DLY_IN(n) (((n) & 0x3F) << 0) +#define PSRAM_ULP_PHY_DLL_DLY_IN_MASK (0x3F << 0) +#define PSRAM_ULP_PHY_DLL_DLY_IN_SHIFT (0) +#define PSRAM_ULP_PHY_DLL_LOCK (1 << 6) +#define PSRAM_ULP_PHY_DLL_ALL_ZERO (1 << 7) +#define PSRAM_ULP_PHY_DLL_ALL_ONE (1 << 8) + +#endif diff --git a/platform/hal/reg_psramip_v1.h b/platform/hal/reg_psramip_v1.h new file mode 100644 index 0000000..882bb27 --- /dev/null +++ b/platform/hal/reg_psramip_v1.h @@ -0,0 +1,127 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef PSRAM_REG_H +#define PSRAM_REG_H + +#include "plat_types.h" + +/* ip register */ +/* 0x0 */ +#define PSRIP_CMD_ADDR_REG_OFFSET 0x0 +#define PSRIP_CMD_ADDR_ADDR_SHIFT (8) +#define PSRIP_CMD_ADDR_ADDR_MASK ((0xfffffff)<= 4) +#define SPI_RX_SEL_EN (1 << 11) +#define SPI_SLAVE_ID_SHIFT (7) +#define SPI_SLAVE_ID_MASK (0xF << SPI_SLAVE_ID_SHIFT) +#define SPI_SLAVE_ID(n) BITFIELD_VAL(SPI_SLAVE_ID, n) +#else +#define SPI_RX_SEL_EN (1 << 9) +#define SPI_SLAVE_ID_SHIFT (7) +#define SPI_SLAVE_ID_MASK (3 << SPI_SLAVE_ID_SHIFT) +#define SPI_SLAVE_ID(n) BITFIELD_VAL(SPI_SLAVE_ID, n) +#endif +#define SPI_LCD_DC_DATA (1 << 4) +#define SPI_SSPCR1_SOD (1 << 3) +#define SPI_SSPCR1_MS (1 << 2) +#define SPI_SSPCR1_SSE (1 << 1) +#define SPI_SSPCR1_LBM (1 << 0) + +#define SPI_SSPSR_BSY (1 << 4) +#define SPI_SSPSR_RFF (1 << 3) +#define SPI_SSPSR_RNE (1 << 2) +#define SPI_SSPSR_TNF (1 << 1) +#define SPI_SSPSR_TFE (1 << 0) + +#define MAX_CPSDVSR (0xFE) +#define MIN_CPSDVSR (2) + +#define SPI_SSPCPSR_CPSDVSR(n) (((n) & 0xFF) << 0) +#define SPI_SSPCPSR_CPSDVSR_MASK (0xFF << 0) +#define SPI_SSPCPSR_CPSDVSR_SHIFT (0) + +#define SPI_SSPIMSC_TXIM (1 << 3) +#define SPI_SSPIMSC_RXIM (1 << 2) +#define SPI_SSPIMSC_RTIM (1 << 1) +#define SPI_SSPIMSC_RORIM (1 << 0) + +#define SPI_SSPRIS_TXRIS (1 << 3) +#define SPI_SSPRIS_RXRIS (1 << 2) +#define SPI_SSPRIS_RTRIS (1 << 1) +#define SPI_SSPRIS_RORRIS (1 << 0) + +#define SPI_SSPMIS_TXMIS (1 << 3) +#define SPI_SSPMIS_RXMIS (1 << 2) +#define SPI_SSPMIS_RTMIS (1 << 1) +#define SPI_SSPMIS_RORMIS (1 << 0) + +#define SPI_SSPICR_RTIC (1 << 1) +#define SPI_SSPICR_RORIC (1 << 0) + +#define SPI_SSPDMACR_TXDMAE (1 << 1) +#define SPI_SSPDMACR_RXDMAE (1 << 0) + +#define SPI_SSPRXCR_EN (1 << 6) +#define SPI_SSPRXCR_OEN_POLARITY (1 << 5) +#define SPI_SSPRXCR_RXBITS(n) (((n) & 0x1F) << 0) +#define SPI_SSPRXCR_RXBITS_MASK (0x1F << 0) +#define SPI_SSPRXCR_RXBITS_SHIFT (0) + +#endif + diff --git a/platform/hal/reg_tdm.h b/platform/hal/reg_tdm.h new file mode 100644 index 0000000..d5c42cb --- /dev/null +++ b/platform/hal/reg_tdm.h @@ -0,0 +1,44 @@ +#ifndef _REG_TDM_H_ +#define _REG_TDM_H_ + +#include "plat_types.h" +#include "reg_i2sip.h" +// 0 enable offset +#define TDM_ENABLE_SHIFT 0x0 +#define TDM_ENABLE 0x1 +#define TDM_DISABLE 0x0 +// 1 FS_ASSERTED +#define TDM_MODE_FS_ASSERTED_SHIFT 0x1 +#define TDM_MODE_FS_ASSERTED_AT_FIRST 0x0 +#define TDM_MODE_FS_ASSERTED_AT_LAST 0x1 +// 2 FS_EDGE +#define TDM_FS_EDGE_SHIFT 0x2 +#define TDM_FS_EDGE_POSEDGE 0x0 +#define TDM_FS_EDGE_NEGEDGE 0x1 +// 3 FRAME_WIDTH +#define TDM_FRAME_WIDTH_SHIFT 0x3 +#define TDM_FRAME_WIDTH_16_CYCLES 0x1 +#define TDM_FRAME_WIDTH_32_CYCLES 0x2 +#define TDM_FRAME_WIDTH_64_CYCLES 0x3 +#define TDM_FRAME_WIDTH_128_CYCLES 0x4 +#define TDM_FRAME_WIDTH_256_CYCLES 0x5 +// 6 FRAME_WIDTH +#define TDM_FS_WIDTH_SHIFT 0x6 +#define TDM_FS_WIDTH_1_CYCLE 0x0 +#define TDM_FS_WIDTH_8_CYCLES 0x1 +#define TDM_FS_WIDTH_16_CYCLES 0x2 +#define TDM_FS_WIDTH_32_CYCLES 0x3 +#define TDM_FS_WIDTH_64_CYCLES 0x4 +#define TDM_FS_WIDTH_128_CYCLES 0x5 +#define TDM_FS_WIDTH_FRAME_LENGTH_1_CYCLES 0x7 +// 9 SLOT_WIDTH +#define TDM_SLOT_WIDTH_SHIFT 0x9 +#define TDM_SLOT_WIDTH_32_BIT 0x0 +#define TDM_SLOT_WIDTH_16_BIT 0x1 + +#define TDM_DATA_OFFSET_SHIT 0xa +#define TDM_DATA_OFFSET_MIN 0x0 +#define TDM_DATA_OFFSET_SIZE 0x0 +#define TDM_DATA_OFFSET_MAX 0x7 + +#endif diff --git a/platform/hal/reg_timer.h b/platform/hal/reg_timer.h new file mode 100644 index 0000000..d75af54 --- /dev/null +++ b/platform/hal/reg_timer.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_TIMER_H_ +#define __REG_TIMER_H_ + +#include "plat_types.h" + +/* ================================================================================ */ +/* ================ Timer (TIM) ================ */ +/* ================================================================================ */ +struct DUAL_TIMER_T { + struct TIMER_T { + __IO uint32_t Load; /* Offset: 0x000 (R/W) Timer X Load */ + __I uint32_t Value; /* Offset: 0x004 (R/ ) Timer X Counter Current Value */ + __IO uint32_t Control; /* Offset: 0x008 (R/W) Timer X Control */ + __O uint32_t IntClr; /* Offset: 0x00C ( /W) Timer X Interrupt Clear */ + __I uint32_t RIS; /* Offset: 0x010 (R/ ) Timer X Raw Interrupt Status */ + __I uint32_t MIS; /* Offset: 0x014 (R/ ) Timer X Masked Interrupt Status */ + __IO uint32_t BGLoad; /* Offset: 0x018 (R/W) Background Load Register */ + uint32_t RESERVED0[1]; + } timer[2]; + struct ELAPSED_TIMER_T { + __IO uint32_t ElapsedCtrl; + __I uint32_t ElapsedVal; + uint32_t RESERVED1[6]; + } elapsed_timer[2]; +}; + +#define TIMER_CTRL_EN (1 << 7) +#define TIMER_CTRL_MODE_PERIODIC (1 << 6) +#define TIMER_CTRL_INTEN (1 << 5) +#define TIMER_CTRL_PRESCALE_DIV_1 (0 << 2) +#define TIMER_CTRL_PRESCALE_DIV_16 (1 << 2) +#define TIMER_CTRL_PRESCALE_DIV_256 (2 << 2) +#define TIMER_CTRL_PRESCALE_MASK (3 << 2) +#define TIMER_CTRL_SIZE_32_BIT (1 << 1) +#define TIMER_CTRL_ONESHOT (1 << 0) + +#define TIMER_RIS_RIS (1 << 0) + +#define TIMER_MIS_MIS (1 << 0) + +#define TIMER_ELAPSED_CTRL_EN (1 << 0) +#define TIMER_ELAPSED_CTRL_CLR (1 << 1) + +#endif + diff --git a/platform/hal/reg_transq.h b/platform/hal/reg_transq.h new file mode 100644 index 0000000..8bd34ff --- /dev/null +++ b/platform/hal/reg_transq.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_TRANSQ_H__ +#define __REG_TRANSQ_H__ + +#include "plat_types.h" + +#define TRANSQ_SLOT_NUM 32 + +struct TRANSQ_T +{ + __IO uint32_t CTRL; // 0x000 + __IO uint32_t RMT_INTMASK; // 0x004 + __IO uint32_t RMT_INTSET; // 0x008 + __IO uint32_t LDONE_INTMASK; // 0x00C + union { + __I uint32_t LDONE_RIS; // 0x010 + __O uint32_t LDONE_INTCLR; // 0x010 + } LDONE_ISC; + __IO uint32_t LERR_INTMASK; // 0x014 + union { + __I uint32_t LERR_RIS; // 0x018 + __O uint32_t LERR_INTCLR; // 0x018 + } LERR_ISC; + __IO uint32_t RESERVED_01C; // 0x01C + __I uint32_t LDONE_MIS; // 0x020 + __I uint32_t LERR_MIS; // 0x024 + __IO uint32_t RESERVED_028[2]; // 0x028 + struct { + __IO uint32_t ADDR; // 0x030 + N * 8 + __IO uint32_t LEN; // 0x038 + N * 8 + } WSLOT[TRANSQ_SLOT_NUM]; + __IO uint32_t RESERVED_130[0x34]; // 0x130 + union { + __I uint32_t RMT_RIS; // 0x200 + __O uint32_t RMT_INTCLR; // 0x200 + } RMT_ISC; + __IO uint32_t RMT_MIS; // 0x204 + __IO uint32_t RESERVED_208[10]; // 0x208 + struct { + __I uint32_t ADDR; // 0x230 + N * 8 + __I uint32_t LEN; // 0x238 + N * 8 + } RSLOT[TRANSQ_SLOT_NUM]; +}; + +// CTRL +#define CTRL_REMOTE_IRQ_EN (1 << 0) +#define CTRL_LOCAL_DONE_IRQ_EN (1 << 1) +#define CTRL_LOCAL_ERR_IRQ_EN (1 << 2) + +#define TRANSQ_BIT(n) (1 << (n)) + +#endif diff --git a/platform/hal/reg_uart.h b/platform/hal/reg_uart.h new file mode 100644 index 0000000..c2d5f39 --- /dev/null +++ b/platform/hal/reg_uart.h @@ -0,0 +1,116 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REG_UART_H__ +#define __REG_UART_H__ + +#include "plat_types.h" + +// UART Registers +struct UART_T { + __IO uint32_t UARTDR; // 0x000 + union { + __I uint32_t UARTRSR; // 0x004 + __O uint32_t UARTECR; // 0x004 + }; + uint32_t RESERVED_008[4]; // 0x008 + __I uint32_t UARTFR; // 0x018 + uint32_t RESERVED_01C; // 0x01C + __IO uint32_t UARTILPR; // 0x020 + __IO uint32_t UARTIBRD; // 0x024 + __IO uint32_t UARTFBRD; // 0x028 + __IO uint32_t UARTLCR_H; // 0x02C + __IO uint32_t UARTCR; // 0x030 + __IO uint32_t UARTIFLS; // 0x034 + __IO uint32_t UARTIMSC; // 0x038 + __I uint32_t UARTRIS; // 0x03C + __I uint32_t UARTMIS; // 0x040 + __O uint32_t UARTICR; // 0x044 + __IO uint32_t UARTDMACR; // 0x048 + uint32_t RESERVED_04C[997]; // 0x04C + __I uint32_t UARTPID0; // 0xFE0 + __I uint32_t UARTPID1; // 0xFE4 + __I uint32_t UARTPID2; // 0xFE8 + __I uint32_t UARTPID3; // 0xFEC + __I uint32_t UARTPCID0; // 0xFF0 + __I uint32_t UARTPCID1; // 0xFF4 + __I uint32_t UARTPCID2; // 0xFF8 + __I uint32_t UARTPCID3; // 0xFFC +}; + +// Data status bits +#define UART_DATA_ERROR_MASK 0x0F00 + +// Status reg bits +#define UART_STATUS_ERROR_MASK 0x0F + +// Flag reg bits +#define UARTFR_RI (1 << 8) // Ring indicator +#define UARTFR_TXFE (1 << 7) // Transmit FIFO empty +#define UARTFR_RXFF (1 << 6) // Receive FIFO full +#define UARTFR_TXFF (1 << 5) // Transmit FIFO full +#define UARTFR_RXFE (1 << 4) // Receive FIFO empty +#define UARTFR_BUSY (1 << 3) // UART busy +#define UARTFR_DCD (1 << 2) // Data carrier detect +#define UARTFR_DSR (1 << 1) // Data set ready +#define UARTFR_CTS (1 << 0) // Clear to send + +// Flag reg bits - alternative names +#define UART_TX_EMPTY_FLAG_MASK UARTFR_TXFE +#define UART_RX_FULL_FLAG_MASK UARTFR_RXFF +#define UART_TX_FULL_FLAG_MASK UARTFR_TXFF +#define UART_RX_EMPTY_FLAG_MASK UARTFR_RXFE +#define UART_BUSY_FLAG_MASK UARTFR_BUSY + +// Control reg bits +#define UARTCR_CTSEN (1 << 15) // CTS hardware flow control enable +#define UARTCR_RTSEN (1 << 14) // RTS hardware flow control enable +#define UARTCR_RTS (1 << 11) // Request to send +#define UARTCR_DTR (1 << 10) // Data transmit ready. +#define UARTCR_RXE (1 << 9) // Receive enable +#define UARTCR_TXE (1 << 8) // Transmit enable +#define UARTCR_LBE (1 << 7) // Loopback enable +#define UARTCR_UARTEN (1 << 0) // UART Enable + +// Line Control Register Bits +#define UARTLCR_H_DMA_RT_EN (1 << 15) +#define UARTLCR_H_DMA_RT_CNT(n) (((n) & 0x7F) << 8) +#define UARTLCR_H_DMA_RT_CNT_MASK (0x7F << 8) +#define UARTLCR_H_DMA_RT_CNT_SHIFT (8) +#define UARTLCR_H_SPS (1 << 7) // Stick parity select +#define UARTLCR_H_WLEN_8 (3 << 5) +#define UARTLCR_H_WLEN_7 (2 << 5) +#define UARTLCR_H_WLEN_6 (1 << 5) +#define UARTLCR_H_WLEN_5 (0 << 5) +#define UARTLCR_H_FEN (1 << 4) // FIFOs Enable +#define UARTLCR_H_STP2 (1 << 3) // Two stop bits select +#define UARTLCR_H_EPS (1 << 2) // Even parity select +#define UARTLCR_H_PEN (1 << 1) // Parity Enable +#define UARTLCR_H_BRK (1 << 0) // Send break + +// UARTIFLS reg bits +#define UARTIFLS_TXFIFO_LEVEL(n) (((n) & 3) << 0) +#define UARTIFLS_TXFIFO_LEVEL_MASK (3 << 0) +#define UARTIFLS_TXFIFO_LEVEL_SHIFT (0) +#define UARTIFLS_RXFIFO_LEVEL(n) (((n) & 3) << 3) +#define UARTIFLS_RXFIFO_LEVEL_MASK (3 << 3) +#define UARTIFLS_RXFIFO_LEVEL_SHIFT (3) + +// DMACR reg bits +#define UARTDMACR_RXDMAE (1 << 0) +#define UARTDMACR_TXDMAE (1 << 1) +#define UARTDMACR_DMAONERR (1 << 2) + +#endif diff --git a/platform/hal/reg_usb.h b/platform/hal/reg_usb.h new file mode 100644 index 0000000..62416db --- /dev/null +++ b/platform/hal/reg_usb.h @@ -0,0 +1,1744 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _REG_USB_H_ +#define _REG_USB_H_ + +#include "stdint.h" +#include "plat_types.h" + +// ============================================================================= +// MACROS +// ============================================================================= +#define SPFIFORAM_SIZE (1024) + +// ============================================================================= +// TYPES +// ============================================================================= + +// ============================================================================ +// USBC_T +// ----------------------------------------------------------------------------- +/// +// ============================================================================= +struct USBC_T { + //common part + __IO uint32_t GOTGCTL; //0x00000000 + __IO uint32_t GOTGINT; //0x00000004 + __IO uint32_t GAHBCFG; //0x00000008 + __IO uint32_t GUSBCFG; //0x0000000C + __IO uint32_t GRSTCTL; //0x00000010 + __IO uint32_t GINTSTS; //0x00000014 + __IO uint32_t GINTMSK; //0x00000018 + __IO uint32_t GRXSTSR; //0x0000001C + __IO uint32_t GRXSTSP; //0x00000020 + __IO uint32_t GRXFSIZ; //0x00000024 + __IO uint32_t GNPTXFSIZ; //0x00000028 + __IO uint32_t GNPTXSTS; //0x0000002C + __IO uint32_t GI2CCTL; //0x00000030 + __IO uint32_t GPVNDCTL; //0x00000034 + __IO uint32_t GGPIO; //0x00000038 + __IO uint32_t GUID; //0x0000003C + __IO uint32_t GSNPSID; //0x00000040 + __IO uint32_t GHWCFG1; //0x00000044 + __IO uint32_t GHWCFG2; //0x00000048 + __IO uint32_t GHWCFG3; //0x0000004C + __IO uint32_t GHWCFG4; //0x00000050 + __IO uint32_t GLPMCFG; //0x00000054 + __IO uint32_t GPWRDN; //0x00000058 + __IO uint32_t GDFIFOCFG; //0x0000005C + __IO uint32_t GADPCTL; //0x00000060 + __IO uint32_t Reserved_00000054[0x27]; //0x00000064 + __IO uint32_t HPTXFSIZ; //0x00000100 + union + { + __IO uint32_t DPTXFSIZn; //0x00000104 - 13F + __IO uint32_t DIEPTXFn; //0x00000104 - 13F + } DTXFSIZE[15]; + __IO uint32_t Reserved_00000140[0xB0]; //0x00000140 - 3FF + //host part + __IO uint32_t HCFG; //0x00000400 + __IO uint32_t HFIR; //0x00000404 + __IO uint32_t HFNUM; //0x00000408 + __IO uint32_t Reserved_0000040C; //0x0000040C + __IO uint32_t HPTXSTS; //0x00000410 + __IO uint32_t HAINT; //0x00000414 + __IO uint32_t HAINTMSK; //0x00000418 + __IO uint32_t Reserved_0000041C[9]; //0x0000041C + __IO uint32_t HPRT; //0x00000440 + __IO uint32_t Reserved_00000444[0x2F]; //0x00000444 + struct + { + __IO uint32_t HCCHARn; //0x00000500+n*0x20 + __IO uint32_t HCSPLTn; //0x00000504+n*0x20 + __IO uint32_t HCINTn; //0x00000508+n*0x20 + __IO uint32_t HCINTMSKn; //0x0000050C+n*0x20 + __IO uint32_t HCTSIZn; //0x00000510+n*0x20 + __IO uint32_t HCDMAn; //0x00000514+n*0x20 + __IO uint32_t Reserved_00000518; //0x00000518+n*0x20 + __IO uint32_t HCDMABn; //0x0000051C+n*0x20 + } HCSR[16]; + __IO uint32_t Reserved_00000700[0x40]; //0x00000700 + //device part + __IO uint32_t DCFG; //0x00000800 + __IO uint32_t DCTL; //0x00000804 + __IO uint32_t DSTS; //0x00000808 + __IO uint32_t Reserved_0000080C; //0x0000080C + __IO uint32_t DIEPMSK; //0x00000810 + __IO uint32_t DOEPMSK; //0x00000814 + __IO uint32_t DAINT; //0x00000818 + __IO uint32_t DAINTMSK; //0x0000081C + __IO uint32_t DTKNQR1; //0x00000820 + __IO uint32_t DTKNQR2; //0x00000824 + __IO uint32_t DVBUSDIS; //0x00000828 + __IO uint32_t DVBUSPULSE; //0x0000082C + __IO uint32_t DTHRCTL; //0x00000830 + __IO uint32_t DIEPEMPMSK; //0x00000834 + __IO uint32_t Reserved_00000838[0x32]; //0x00000838 + __IO uint32_t DIEPCTL0; //0x00000900 + __IO uint32_t Reserved_00000904; //0x00000904 + __IO uint32_t DIEPINT0; //0x00000908 + __IO uint32_t Reserved_0000090C; //0x0000090C + __IO uint32_t DIEPTSIZ0; //0x00000910 + __IO uint32_t DIEPDMA0; //0x00000914 + __IO uint32_t DIEPFSTS0; //0x00000918 + __IO uint32_t DIEPDMAB0; //0x0000091C + struct + { + __IO uint32_t DIEPCTL; //0x00000920 + __IO uint32_t Reserved_00000924; //0x00000924 + __IO uint32_t DIEPINT; //0x00000928 + __IO uint32_t Reserved_0000092C; //0x0000092C + __IO uint32_t DIEPTSIZ; //0x00000930 + __IO uint32_t DIEPDMA; //0x00000934 + __IO uint32_t DIEPFSTS; //0x00000938 + __IO uint32_t DIEPDMAB; //0x0000093C + } DIEPnCONFIG[15]; + __IO uint32_t DOEPCTL0; //0x00000B00 + __IO uint32_t Reserved_00000B04; //0x00000B04 + __IO uint32_t DOEPINT0; //0x00000B08 + __IO uint32_t Reserved_00000B0C; //0x00000B0C + __IO uint32_t DOEPTSIZ0; //0x00000B10 + __IO uint32_t DOEPDMA0; //0x00000B14 + __IO uint32_t Reserved_00000B18; //0x00000B18 + __IO uint32_t DOEPDMAB0; //0x00000B1C + struct + { + __IO uint32_t DOEPCTL; //0x00000B20 + __IO uint32_t Reserved_00000B24; //0x00000B24 + __IO uint32_t DOEPINT; //0x00000B28 + __IO uint32_t Reserved_00000B2C; //0x00000B2C + __IO uint32_t DOEPTSIZ; //0x00000B30 + __IO uint32_t DOEPDMA; //0x00000B34 + __IO uint32_t Reserved_00000B38; //0x00000B38 + __IO uint32_t DOEPDMAB; //0x00000B3C + } DOEPnCONFIG[15]; + __IO uint32_t Reserved_00000D00[0x40]; //0x00000D00 + __IO uint32_t PCGCCTL; //0x00000E00 + __IO uint32_t Reserved_00000E04; //0x00000E04 + __IO uint32_t TPORTDBG0; //0x00000E08 + __IO uint32_t TPORTDBG1; //0x00000E0C + __IO uint32_t Reserved_00000E0C[0x7C]; //0x00000E10 + struct + { + __IO uint32_t TxRxData; //0x00001000 + __IO uint32_t Reserved_00001004[0x3FF]; //0x00001004 + } EPnFIFO[16]; + __IO uint32_t Reserved_00011000[0x3C00]; //0x00011000 + struct + { + __IO uint32_t RAMData; //0x00020000 + } SPFIFORAM[SPFIFORAM_SIZE]; +}; + +//GOTGCTL +#define USBC_SESREQSCS (1<<0) +#define USBC_SESREQSCS_MASK (1<<0) +#define USBC_SESREQSCS_SHIFT (0) +#define USBC_SESREQ (1<<1) +#define USBC_SESREQ_MASK (1<<1) +#define USBC_SESREQ_SHIFT (1) +#define USBC_HSTNEGSCS (1<<8) +#define USBC_HSTNEGSCS_MASK (1<<8) +#define USBC_HSTNEGSCS_SHIFT (8) +#define USBC_HNPREQ (1<<9) +#define USBC_HNPREQ_MASK (1<<9) +#define USBC_HNPREQ_SHIFT (9) +#define USBC_HSTSETHNPEN (1<<10) +#define USBC_HSTSETHNPEN_MASK (1<<10) +#define USBC_HSTSETHNPEN_SHIFT (10) +#define USBC_DEVHNPEN (1<<11) +#define USBC_DEVHNPEN_MASK (1<<11) +#define USBC_DEVHNPEN_SHIFT (11) +#define USBC_CONLDSTS (1<<16) +#define USBC_CONLDSTS_MASK (1<<16) +#define USBC_CONLDSTS_SHIFT (16) +#define USBC_DBNCTIME (1<<17) +#define USBC_DBNCTIME_MASK (1<<17) +#define USBC_DBNCTIME_SHIFT (17) +#define USBC_ASESVLD (1<<18) +#define USBC_ASESVLD_MASK (1<<18) +#define USBC_ASESVLD_SHIFT (18) +#define USBC_BSESVLD (1<<19) +#define USBC_BSESVLD_MASK (1<<19) +#define USBC_BSESVLD_SHIFT (19) + +//GOTGINT +#define USBC_SESENDDET (1<<2) +#define USBC_SESENDDET_MASK (1<<2) +#define USBC_SESENDDET_SHIFT (2) +#define USBC_SESREQSUCSTSCHNG (1<<8) +#define USBC_SESREQSUCSTSCHNG_MASK (1<<8) +#define USBC_SESREQSUCSTSCHNG_SHIFT (8) +#define USBC_HSTNEGSUCSTSCHNG (1<<9) +#define USBC_HSTNEGSUCSTSCHNG_MASK (1<<9) +#define USBC_HSTNEGSUCSTSCHNG_SHIFT (9) +#define USBC_HSTNEGDET (1<<17) +#define USBC_HSTNEGDET_MASK (1<<17) +#define USBC_HSTNEGDET_SHIFT (17) +#define USBC_ADEVTOUTCHG (1<<18) +#define USBC_ADEVTOUTCHG_MASK (1<<18) +#define USBC_ADEVTOUTCHG_SHIFT (18) +#define USBC_DBNCEDONE (1<<19) +#define USBC_DBNCEDONE_MASK (1<<19) +#define USBC_DBNCEDONE_SHIFT (19) + +//GAHBCFG +#define USBC_GLBLINTRMSK (1<<0) +#define USBC_GLBLINTRMSK_MASK (1<<0) +#define USBC_GLBLINTRMSK_SHIFT (0) +#define USBC_HBSTLEN(n) (((n)&15)<<1) +#define USBC_HBSTLEN_MASK (15<<1) +#define USBC_HBSTLEN_SHIFT (1) +#define USBC_DMAEN (1<<5) +#define USBC_DMAEN_MASK (1<<5) +#define USBC_DMAEN_SHIFT (5) +#define USBC_NPTXFEMPLVL (1<<7) +#define USBC_NPTXFEMPLVL_MASK (1<<7) +#define USBC_NPTXFEMPLVL_SHIFT (7) +#define USBC_PTXFEMPLVL (1<<8) +#define USBC_PTXFEMPLVL_MASK (1<<8) +#define USBC_PTXFEMPLVL_SHIFT (8) + +//GUSBCFG +#define USBC_TOUTCAL(n) (((n)&7)<<0) +#define USBC_TOUTCAL_MASK (7<<0) +#define USBC_TOUTCAL_SHIFT (0) +#define USBC_PHYIF (1<<3) +#define USBC_PHYIF_MASK (1<<3) +#define USBC_PHYIF_SHIFT (3) +#define USBC_ULPI_UTMI_SEL (1<<4) +#define USBC_ULPI_UTMI_SEL_MASK (1<<4) +#define USBC_ULPI_UTMI_SEL_SHIFT (4) +#define USBC_FSINTF (1<<5) +#define USBC_FSINTF_MASK (1<<5) +#define USBC_FSINTF_SHIFT (5) +#define USBC_PHYSEL (1<<6) +#define USBC_PHYSEL_MASK (1<<6) +#define USBC_PHYSEL_SHIFT (6) +#define USBC_DDRSEL (1<<7) +#define USBC_DDRSEL_MASK (1<<7) +#define USBC_DDRSEL_SHIFT (7) +#define USBC_SRPCAP (1<<8) +#define USBC_SRPCAP_MASK (1<<8) +#define USBC_SRPCAP_SHIFT (8) +#define USBC_HNPCAP (1<<9) +#define USBC_HNPCAP_MASK (1<<9) +#define USBC_HNPCAP_SHIFT (9) +#define USBC_USBTRDTIM(n) (((n)&15)<<10) +#define USBC_USBTRDTIM_MASK (15<<10) +#define USBC_USBTRDTIM_SHIFT (10) +#define USBC_PHYPWRCLKSEL (1<<15) +#define USBC_PHYPWRCLKSEL_MASK (1<<15) +#define USBC_PHYPWRCLKSEL_SHIFT (15) +#define USBC_OTGI2CSEL (1<<16) +#define USBC_OTGI2CSEL_MASK (1<<16) +#define USBC_OTGI2CSEL_SHIFT (16) +#define USBC_ULPIFSLS (1<<17) +#define USBC_ULPIFSLS_MASK (1<<17) +#define USBC_ULPIFSLS_SHIFT (17) +#define USBC_ULPIAUTORES (1<<18) +#define USBC_ULPIAUTORES_MASK (1<<18) +#define USBC_ULPIAUTORES_SHIFT (18) +#define USBC_ULPICLKSUSM (1<<19) +#define USBC_ULPICLKSUSM_MASK (1<<19) +#define USBC_ULPICLKSUSM_SHIFT (19) +#define USBC_ULPIEXTVBUSDRV (1<<20) +#define USBC_ULPIEXTVBUSDRV_MASK (1<<20) +#define USBC_ULPIEXTVBUSDRV_SHIFT (20) +#define USBC_ULPIEXTVBUSINDICATOR (1<<21) +#define USBC_ULPIEXTVBUSINDICATOR_MASK (1<<21) +#define USBC_ULPIEXTVBUSINDICATOR_SHIFT (21) +#define USBC_TERMSELDLPULSE (1<<22) +#define USBC_TERMSELDLPULSE_MASK (1<<22) +#define USBC_TERMSELDLPULSE_SHIFT (22) +#define USBC_FORCEHSTMODE (1<<29) +#define USBC_FORCEHSTMODE_MASK (1<<29) +#define USBC_FORCEHSTMODE_SHIFT (29) +#define USBC_FORCEDEVMODE (1<<30) +#define USBC_FORCEDEVMODE_MASK (1<<30) +#define USBC_FORCEDEVMODE_SHIFT (30) +#define USBC_CORRUPTTXPACKET (1<<31) +#define USBC_CORRUPTTXPACKET_MASK (1<<31) +#define USBC_CORRUPTTXPACKET_SHIFT (31) + +//GRSTCTL +#define USBC_CSFTRST (1<<0) +#define USBC_CSFTRST_MASK (1<<0) +#define USBC_CSFTRST_SHIFT (0) +#define USBC_FRMCNTRRST (1<<2) +#define USBC_FRMCNTRRST_MASK (1<<2) +#define USBC_FRMCNTRRST_SHIFT (2) +#define USBC_INTKNQFLSH (1<<3) +#define USBC_INTKNQFLSH_MASK (1<<3) +#define USBC_INTKNQFLSH_SHIFT (3) +#define USBC_RXFFLSH (1<<4) +#define USBC_RXFFLSH_MASK (1<<4) +#define USBC_RXFFLSH_SHIFT (4) +#define USBC_TXFFLSH (1<<5) +#define USBC_TXFFLSH_MASK (1<<5) +#define USBC_TXFFLSH_SHIFT (5) +#define USBC_TXFNUM(n) (((n)&31)<<6) +#define USBC_TXFNUM_MASK (31<<6) +#define USBC_TXFNUM_SHIFT (6) +#define USBC_DMAREQ (1<<30) +#define USBC_DMAREQ_MASK (1<<30) +#define USBC_DMAREQ_SHIFT (30) +#define USBC_AHBIDLE (1<<31) +#define USBC_AHBIDLE_MASK (1<<31) +#define USBC_AHBIDLE_SHIFT (31) + +//GINTSTS +#define USBC_CURMOD (1<<0) +#define USBC_CURMOD_MASK (1<<0) +#define USBC_CURMOD_SHIFT (0) +#define USBC_MODEMIS (1<<1) +#define USBC_MODEMIS_MASK (1<<1) +#define USBC_MODEMIS_SHIFT (1) +#define USBC_OTGINT (1<<2) +#define USBC_OTGINT_MASK (1<<2) +#define USBC_OTGINT_SHIFT (2) +#define USBC_SOF (1<<3) +#define USBC_SOF_MASK (1<<3) +#define USBC_SOF_SHIFT (3) +#define USBC_RXFLVL (1<<4) +#define USBC_RXFLVL_MASK (1<<4) +#define USBC_RXFLVL_SHIFT (4) +#define USBC_NPTXFEMP (1<<5) +#define USBC_NPTXFEMP_MASK (1<<5) +#define USBC_NPTXFEMP_SHIFT (5) +#define USBC_GINNAKEFF (1<<6) +#define USBC_GINNAKEFF_MASK (1<<6) +#define USBC_GINNAKEFF_SHIFT (6) +#define USBC_GOUTNAKEFF (1<<7) +#define USBC_GOUTNAKEFF_MASK (1<<7) +#define USBC_GOUTNAKEFF_SHIFT (7) +#define USBC_ULPICKINT (1<<8) +#define USBC_ULPICKINT_MASK (1<<8) +#define USBC_ULPICKINT_SHIFT (8) +#define USBC_I2CINT (1<<9) +#define USBC_I2CINT_MASK (1<<9) +#define USBC_I2CINT_SHIFT (9) +#define USBC_ERLYSUSP (1<<10) +#define USBC_ERLYSUSP_MASK (1<<10) +#define USBC_ERLYSUSP_SHIFT (10) +#define USBC_USBSUSP (1<<11) +#define USBC_USBSUSP_MASK (1<<11) +#define USBC_USBSUSP_SHIFT (11) +#define USBC_USBRST (1<<12) +#define USBC_USBRST_MASK (1<<12) +#define USBC_USBRST_SHIFT (12) +#define USBC_ENUMDONE (1<<13) +#define USBC_ENUMDONE_MASK (1<<13) +#define USBC_ENUMDONE_SHIFT (13) +#define USBC_ISOOUTDROP (1<<14) +#define USBC_ISOOUTDROP_MASK (1<<14) +#define USBC_ISOOUTDROP_SHIFT (14) +#define USBC_EOPF (1<<15) +#define USBC_EOPF_MASK (1<<15) +#define USBC_EOPF_SHIFT (15) +#define USBC_EPMIS (1<<17) +#define USBC_EPMIS_MASK (1<<17) +#define USBC_EPMIS_SHIFT (17) +#define USBC_IEPINT (1<<18) +#define USBC_IEPINT_MASK (1<<18) +#define USBC_IEPINT_SHIFT (18) +#define USBC_OEPINT (1<<19) +#define USBC_OEPINT_MASK (1<<19) +#define USBC_OEPINT_SHIFT (19) +#define USBC_INCOMPISOIN (1<<20) +#define USBC_INCOMPISOIN_MASK (1<<20) +#define USBC_INCOMPISOIN_SHIFT (20) +#define USBC_INCOMPISOOUT (1<<21) +#define USBC_INCOMPISOOUT_MASK (1<<21) +#define USBC_INCOMPISOOUT_SHIFT (21) +#define USBC_FETSUSP (1<<22) +#define USBC_FETSUSP_MASK (1<<22) +#define USBC_FETSUSP_SHIFT (22) +#define USBC_PRTINT (1<<24) +#define USBC_PRTINT_MASK (1<<24) +#define USBC_PRTINT_SHIFT (24) +#define USBC_HCHINT (1<<25) +#define USBC_HCHINT_MASK (1<<25) +#define USBC_HCHINT_SHIFT (25) +#define USBC_PTXFEMP (1<<26) +#define USBC_PTXFEMP_MASK (1<<26) +#define USBC_PTXFEMP_SHIFT (26) +#define USBC_LPM_INT (1<<27) +#define USBC_LPM_INT_MASK (1<<27) +#define USBC_LPM_INT_SHIFT (27) +#define USBC_CONLDSTSCHNG (1<<28) +#define USBC_CONLDSTSCHNG_MASK (1<<28) +#define USBC_CONLDSTSCHNG_SHIFT (28) +#define USBC_DISCONNINT (1<<29) +#define USBC_DISCONNINT_MASK (1<<29) +#define USBC_DISCONNINT_SHIFT (29) +#define USBC_SESSREQINT (1<<30) +#define USBC_SESSREQINT_MASK (1<<30) +#define USBC_SESSREQINT_SHIFT (30) +#define USBC_WKUPINT (1<<31) +#define USBC_WKUPINT_MASK (1<<31) +#define USBC_WKUPINT_SHIFT (31) + +//GINTMSK +//#define USBC_MODEMIS (1<<1) +//#define USBC_MODEMIS_MASK (1<<1) +//#define USBC_MODEMIS_SHIFT (1) +//#define USBC_OTGINT (1<<2) +//#define USBC_OTGINT_MASK (1<<2) +//#define USBC_OTGINT_SHIFT (2) +//#define USBC_SOF (1<<3) +//#define USBC_SOF_MASK (1<<3) +//#define USBC_SOF_SHIFT (3) +//#define USBC_RXFLVL (1<<4) +//#define USBC_RXFLVL_MASK (1<<4) +//#define USBC_RXFLVL_SHIFT (4) +//#define USBC_NPTXFEMP (1<<5) +//#define USBC_NPTXFEMP_MASK (1<<5) +//#define USBC_NPTXFEMP_SHIFT (5) +//#define USBC_GINNAKEFF (1<<6) +//#define USBC_GINNAKEFF_MASK (1<<6) +//#define USBC_GINNAKEFF_SHIFT (6) +//#define USBC_GOUTNAKEFF (1<<7) +//#define USBC_GOUTNAKEFF_MASK (1<<7) +//#define USBC_GOUTNAKEFF_SHIFT (7) +//#define USBC_ULPICKINT (1<<8) +//#define USBC_ULPICKINT_MASK (1<<8) +//#define USBC_ULPICKINT_SHIFT (8) +//#define USBC_I2CINT (1<<9) +//#define USBC_I2CINT_MASK (1<<9) +//#define USBC_I2CINT_SHIFT (9) +//#define USBC_ERLYSUSP (1<<10) +//#define USBC_ERLYSUSP_MASK (1<<10) +//#define USBC_ERLYSUSP_SHIFT (10) +//#define USBC_USBSUSP (1<<11) +//#define USBC_USBSUSP_MASK (1<<11) +//#define USBC_USBSUSP_SHIFT (11) +//#define USBC_USBRST (1<<12) +//#define USBC_USBRST_MASK (1<<12) +//#define USBC_USBRST_SHIFT (12) +//#define USBC_ENUMDONE (1<<13) +//#define USBC_ENUMDONE_MASK (1<<13) +//#define USBC_ENUMDONE_SHIFT (13) +//#define USBC_ISOOUTDROP (1<<14) +//#define USBC_ISOOUTDROP_MASK (1<<14) +//#define USBC_ISOOUTDROP_SHIFT (14) +//#define USBC_EOPF (1<<15) +//#define USBC_EOPF_MASK (1<<15) +//#define USBC_EOPF_SHIFT (15) +//#define USBC_EPMIS (1<<17) +//#define USBC_EPMIS_MASK (1<<17) +//#define USBC_EPMIS_SHIFT (17) +//#define USBC_IEPINT (1<<18) +//#define USBC_IEPINT_MASK (1<<18) +//#define USBC_IEPINT_SHIFT (18) +//#define USBC_OEPINT (1<<19) +//#define USBC_OEPINT_MASK (1<<19) +//#define USBC_OEPINT_SHIFT (19) +//#define USBC_INCOMPLSOIN (1<<20) +//#define USBC_INCOMPLSOIN_MASK (1<<20) +//#define USBC_INCOMPLSOIN_SHIFT (20) +//#define USBC_INCOMPIP (1<<21) +//#define USBC_INCOMPIP_MASK (1<<21) +//#define USBC_INCOMPIP_SHIFT (21) +//#define USBC_FETSUSP (1<<22) +//#define USBC_FETSUSP_MASK (1<<22) +//#define USBC_FETSUSP_SHIFT (22) +//#define USBC_PRTINT (1<<24) +//#define USBC_PRTINT_MASK (1<<24) +//#define USBC_PRTINT_SHIFT (24) +//#define USBC_HCHINT (1<<25) +//#define USBC_HCHINT_MASK (1<<25) +//#define USBC_HCHINT_SHIFT (25) +//#define USBC_PTXFEMP (1<<26) +//#define USBC_PTXFEMP_MASK (1<<26) +//#define USBC_PTXFEMP_SHIFT (26) +//#define USBC_CONLDSTSCHNG (1<<28) +//#define USBC_CONLDSTSCHNG_MASK (1<<28) +//#define USBC_CONLDSTSCHNG_SHIFT (28) +//#define USBC_DISCONNINT (1<<29) +//#define USBC_DISCONNINT_MASK (1<<29) +//#define USBC_DISCONNINT_SHIFT (29) +//#define USBC_SESSREQINT (1<<30) +//#define USBC_SESSREQINT_MASK (1<<30) +//#define USBC_SESSREQINT_SHIFT (30) +//#define USBC_WKUPINT (1<<31) +//#define USBC_WKUPINT_MASK (1<<31) +//#define USBC_WKUPINT_SHIFT (31) + +//GRXSTSR +#define USBC_EPNUM(n) (((n)&15)<<0) +#define USBC_EPNUM_MASK (15<<0) +#define USBC_EPNUM_SHIFT (0) +#define USBC_BCNT(n) (((n)&0x7FF)<<4) +#define USBC_BCNT_MASK (0x7FF<<4) +#define USBC_BCNT_SHIFT (4) +#define USBC_DPID(n) (((n)&3)<<15) +#define USBC_DPID_MASK (3<<15) +#define USBC_DPID_SHIFT (15) +#define USBC_PKTSTS(n) (((n)&15)<<17) +#define USBC_PKTSTS_MASK (15<<17) +#define USBC_PKTSTS_SHIFT (17) +#define USBC_FN(n) (((n)&15)<<21) +#define USBC_FN_MASK (15<<21) +#define USBC_FN_SHIFT (21) + +//GRXSTSP +//#define USBC_EPNUM(n) (((n)&15)<<0) +//#define USBC_EPNUM_MASK (15<<0) +//#define USBC_EPNUM_SHIFT (0) +//#define USBC_BCNT(n) (((n)&0x7FF)<<4) +//#define USBC_BCNT_MASK (0x7FF<<4) +//#define USBC_BCNT_SHIFT (4) +//#define USBC_DPID(n) (((n)&3)<<15) +//#define USBC_DPID_MASK (3<<15) +//#define USBC_DPID_SHIFT (15) +//#define USBC_PKTSTS(n) (((n)&15)<<17) +//#define USBC_PKTSTS_MASK (15<<17) +//#define USBC_PKTSTS_SHIFT (17) +//#define USBC_FN(n) (((n)&15)<<21) +//#define USBC_FN_MASK (15<<21) +//#define USBC_FN_SHIFT (21) + +//GRXFSIZ +#define USBC_RXFDEP(n) (((n)&0xFFFF)<<0) +#define USBC_RXFDEP_MASK (0xFFFF<<0) +#define USBC_RXFDEP_SHIFT (0) + +//GNPTXFSIZ +#define USBC_NPTXFSTADDR(n) (((n)&0xFFFF)<<0) +#define USBC_NPTXFSTADDR_MASK (0xFFFF<<0) +#define USBC_NPTXFSTADDR_SHIFT (0) +#define USBC_NPTXFDEPS(n) (((n)&0xFFFF)<<16) +#define USBC_NPTXFDEPS_MASK (0xFFFF<<16) +#define USBC_NPTXFDEPS_SHIFT (16) + +//GNPTXSTS +#define USBC_NPTXFSPCAVAIL(n) (((n)&0xFFFF)<<0) +#define USBC_NPTXFSPCAVAIL_MASK (0xFFFF<<0) +#define USBC_NPTXFSPCAVAIL_SHIFT (0) +#define USBC_NPTXQSPCAVAIL(n) (((n)&0xFF)<<16) +#define USBC_NPTXQSPCAVAIL_MASK (0xFF<<16) +#define USBC_NPTXQSPCAVAIL_SHIFT (16) +#define USBC_NPTXQTOP(n) (((n)&0x7F)<<24) +#define USBC_NPTXQTOP_MASK (0x7F<<24) +#define USBC_NPTXQTOP_SHIFT (24) + +//GPVNDCTL +#define USBC_GPVNDCTL_DISULPIDRVR (1<<31) +#define USBC_GPVNDCTL_DISULPIDRVR_MASK (1<<31) +#define USBC_GPVNDCTL_DISULPIDRVR_SHIFT (31) +#define USBC_GPVNDCTL_VSTSDONE (1<<27) +#define USBC_GPVNDCTL_VSTSDONE_MASK (1<<27) +#define USBC_GPVNDCTL_VSTSDONE_SHIFT (27) +#define USBC_GPVNDCTL_VSTSBSY (1<<26) +#define USBC_GPVNDCTL_VSTSBSY_MASK (1<<26) +#define USBC_GPVNDCTL_VSTSBSY_SHIFT (26) +#define USBC_GPVNDCTL_NEWREGREQ (1<<25) +#define USBC_GPVNDCTL_NEWREGREQ_MASK (1<<25) +#define USBC_GPVNDCTL_NEWREGREQ_SHIFT (25) +#define USBC_GPVNDCTL_REGWR (1<<22) +#define USBC_GPVNDCTL_REGWR_MASK (1<<22) +#define USBC_GPVNDCTL_REGWR_SHIFT (22) +#define USBC_GPVNDCTL_REGADDR(n) (((n)&0x3f)<<16) +#define USBC_GPVNDCTL_REGADDR_MASK (0x3f<<16) +#define USBC_GPVNDCTL_REGADDR_SHIFT (16) +#define USBC_GPVNDCTL_EXTREGADDR(n) (((n)&0xff)<<8) +#define USBC_GPVNDCTL_EXTREGADDR_MASK (0xff<<8) +#define USBC_GPVNDCTL_EXTREGADDR_SHIFT (8) +#define USBC_GPVNDCTL_REGDATA(n) (((n)&0xff)<<0) +#define USBC_GPVNDCTL_REGDATA_MASK (0xff<<0) +#define USBC_GPVNDCTL_REGDATA_SHIFT (0) + +//GUID +#define USBC_USERID(n) (((n)&0xFFFFFFFF)<<0) +#define USBC_USERID_MASK (0xFFFFFFFF<<0) +#define USBC_USERID_SHIFT (0) + +//GSNPSID +#define USBC_SYNOPSYSID(n) (((n)&0xFFFFFFFF)<<0) +#define USBC_SYNOPSYSID_MASK (0xFFFFFFFF<<0) +#define USBC_SYNOPSYSID_SHIFT (0) + +//GHWCFG1 +#define USBC_EPDIR(n) (((n)&0xFFFFFFFF)<<0) +#define USBC_EPDIR_MASK (0xFFFFFFFF<<0) +#define USBC_EPDIR_SHIFT (0) + +//GHWCFG2 +#define USBC_OTGMODE(n) (((n)&7)<<0) +#define USBC_OTGMODE_MASK (7<<0) +#define USBC_OTGMODE_SHIFT (0) +#define USBC_OTGARCH(n) (((n)&3)<<3) +#define USBC_OTGARCH_MASK (3<<3) +#define USBC_OTGARCH_SHIFT (3) +#define USBC_SINGPNT (1<<5) +#define USBC_SINGPNT_MASK (1<<5) +#define USBC_SINGPNT_SHIFT (5) +#define USBC_HSPHYTYPE(n) (((n)&3)<<6) +#define USBC_HSPHYTYPE_MASK (3<<6) +#define USBC_HSPHYTYPE_SHIFT (6) +#define USBC_FSPHYTYPE(n) (((n)&3)<<8) +#define USBC_FSPHYTYPE_MASK (3<<8) +#define USBC_FSPHYTYPE_SHIFT (8) +#define USBC_NUMDEVEPS(n) (((n)&15)<<10) +#define USBC_NUMDEVEPS_MASK (15<<10) +#define USBC_NUMDEVEPS_SHIFT (10) +#define USBC_NUMHSTCHNL(n) (((n)&15)<<14) +#define USBC_NUMHSTCHNL_MASK (15<<14) +#define USBC_NUMHSTCHNL_SHIFT (14) +#define USBC_PERIOSUPPORT (1<<18) +#define USBC_PERIOSUPPORT_MASK (1<<18) +#define USBC_PERIOSUPPORT_SHIFT (18) +#define USBC_DYNFIFOSIZING (1<<19) +#define USBC_DYNFIFOSIZING_MASK (1<<19) +#define USBC_DYNFIFOSIZING_SHIFT (19) +#define USBC_NPTXQDEPTH(n) (((n)&3)<<22) +#define USBC_NPTXQDEPTH_MASK (3<<22) +#define USBC_NPTXQDEPTH_SHIFT (22) +#define USBC_PTXQDEPTH(n) (((n)&3)<<24) +#define USBC_PTXQDEPTH_MASK (3<<24) +#define USBC_PTXQDEPTH_SHIFT (24) +#define USBC_TKNQDEPTH(n) (((n)&31)<<26) +#define USBC_TKNQDEPTH_MASK (31<<26) +#define USBC_TKNQDEPTH_SHIFT (26) + +//GHWCFG3 +#define USBC_XFERSIZEWIDTH(n) (((n)&15)<<0) +#define USBC_XFERSIZEWIDTH_MASK (15<<0) +#define USBC_XFERSIZEWIDTH_SHIFT (0) +#define USBC_PKTSIZEWIDTH(n) (((n)&7)<<4) +#define USBC_PKTSIZEWIDTH_MASK (7<<4) +#define USBC_PKTSIZEWIDTH_SHIFT (4) +#define USBC_OTGEN (1<<7) +#define USBC_OTGEN_MASK (1<<7) +#define USBC_OTGEN_SHIFT (7) +#define USBC_I2CINTSEL (1<<8) +#define USBC_I2CINTSEL_MASK (1<<8) +#define USBC_I2CINTSEL_SHIFT (8) +//#define USBC_VNDCTLSUPT (1<<9) +#define USBC_VNDCTLSUPT(n) (((n)&0x1)<<9) +#define USBC_VNDCTLSUPT_MASK (1<<9) +#define USBC_VNDCTLSUPT_SHIFT (9) +#define USBC_OPTFEATURE (1<<10) +#define USBC_OPTFEATURE_MASK (1<<10) +#define USBC_OPTFEATURE_SHIFT (10) +#define USBC_RSTTYPE (1<<11) +#define USBC_RSTTYPE_MASK (1<<11) +#define USBC_RSTTYPE_SHIFT (11) +#define USBC_DFIFODEPTH(n) (((n)&0xFFFF)<<16) +#define USBC_DFIFODEPTH_MASK (0xFFFF<<16) +#define USBC_DFIFODEPTH_SHIFT (16) + +//GHWCFG4 +#define USBC_NUMDEVPERIOEPS(n) (((n)&15)<<0) +#define USBC_NUMDEVPERIOEPS_MASK (15<<0) +#define USBC_NUMDEVPERIOEPS_SHIFT (0) +#define USBC_ENABLEPWROPT (1<<4) +#define USBC_ENABLEPWROPT_MASK (1<<4) +#define USBC_ENABLEPWROPT_SHIFT (4) +#define USBC_AHBFREQ (1<<5) +#define USBC_AHBFREQ_MASK (1<<5) +#define USBC_AHBFREQ_SHIFT (5) +#define USBC_PHYDATAWIDTH(n) (((n)&3)<<14) +#define USBC_PHYDATAWIDTH_MASK (3<<14) +#define USBC_PHYDATAWIDTH_SHIFT (14) +#define USBC_NUMCTLEPS(n) (((n)&15)<<16) +#define USBC_NUMCTLEPS_MASK (15<<16) +#define USBC_NUMCTLEPS_SHIFT (16) +#define USBC_IDDIGFLTR (1<<20) +#define USBC_IDDIGFLTR_MASK (1<<20) +#define USBC_IDDIGFLTR_SHIFT (20) +#define USBC_VBUSVALIDFLTR (1<<21) +#define USBC_VBUSVALIDFLTR_MASK (1<<21) +#define USBC_VBUSVALIDFLTR_SHIFT (21) +#define USBC_AVALIDFLTR (1<<22) +#define USBC_AVALIDFLTR_MASK (1<<22) +#define USBC_AVALIDFLTR_SHIFT (22) +#define USBC_BVALIDFLTR (1<<23) +#define USBC_BVALIDFLTR_MASK (1<<23) +#define USBC_BVALIDFLTR_SHIFT (23) +#define USBC_SESSENDFLTR (1<<24) +#define USBC_SESSENDFLTR_MASK (1<<24) +#define USBC_SESSENDFLTR_SHIFT (24) +#define USBC_DEFIFOMODE (1<<25) +#define USBC_DEFIFOMODE_MASK (1<<25) +#define USBC_DEFIFOMODE_SHIFT (25) +#define USBC_INEPS(n) (((n)&15)<<26) +#define USBC_INEPS_MASK (15<<26) +#define USBC_INEPS_SHIFT (26) + +//GLPMCFG +#define USBC_LPMCAP (1<<0) +#define USBC_LPMCAP_MASK (1<<0) +#define USBC_LPMCAP_SHIFT (0) +#define USBC_APPL1RES (1<<1) +#define USBC_APPL1RES_MASK (1<<1) +#define USBC_APPL1RES_SHIFT (1) +#define USBC_HIRD(n) (((n)&15)<<2) +#define USBC_HIRD_MASK (15<<2) +#define USBC_HIRD_SHIFT (2) +#define USBC_BREMOTEWAKE (1 << 6) +#define USBC_BREMOTEWAKE_MASK (1 << 6) +#define USBC_BREMOTEWAKE_SHIFT (6) +#define USBC_ENBLSLPM (1<<7) +#define USBC_ENBLSLPM_MASK (1<<7) +#define USBC_ENBLSLPM_SHIFT (7) +#define USBC_HIRD_THRES(n) (((n)&15)<<8) +#define USBC_HIRD_THRES_MASK (15<<8) +#define USBC_HIRD_THRES_SHIFT (8) +#define USBC_HIRD_THRES_BIT4 (1 << 12) +#define USBC_HIRD_THRES_BIT4_MASK (1 << 12) +#define USBC_HIRD_THRES_BIT4_SHIFT (12) +#define USBC_COREL1RES(n) (((n)&3)<<13) +#define USBC_COREL1RES_MASK (3<<13) +#define USBC_COREL1RES_SHIFT (13) +#define USBC_SLPSTS (1<<15) +#define USBC_SLPSTS_MASK (1<<15) +#define USBC_SLPSTS_SHIFT (15) +#define USBC_L1RESUMEOK (1<<16) +#define USBC_L1RESUMEOK_MASK (1<<16) +#define USBC_L1RESUMEOK_SHIFT (16) +#define USBC_ENBESL (1<<28) +#define USBC_ENBESL_MASK (1<<28) +#define USBC_ENBESL_SHIFT (28) +#define USBC_RSTRSLPSTS (1<<29) +#define USBC_RSTRSLPSTS_MASK (1<<29) +#define USBC_RSTRSLPSTS_SHIFT (29) + +//GDFIFOCFG +#define USBC_GDFIFOCFG_SHIFT 0 +#define USBC_GDFIFOCFG_MASK (0xFFFF << USBC_GDFIFOCFG_SHIFT) +#define USBC_GDFIFOCFG(n) BITFIELD_VAL(USBC_GDFIFOCFG, n) +#define USBC_EPINFOBASEADDR_SHIFT 16 +#define USBC_EPINFOBASEADDR_MASK (0xFFFF << USBC_EPINFOBASEADDR_SHIFT) +#define USBC_EPINFOBASEADDR(n) BITFIELD_VAL(USBC_EPINFOBASEADDR, n) + +//DPTXFSIZn +#define USBC_DPTXFSTADDR(n) (((n)&0xFFFF)<<0) +#define USBC_DPTXFSTADDR_MASK (0xFFFF<<0) +#define USBC_DPTXFSTADDR_SHIFT (0) +#define USBC_DPTXFSIZE(n) (((n)&0xFFFF)<<16) +#define USBC_DPTXFSIZE_MASK (0xFFFF<<16) +#define USBC_DPTXFSIZE_SHIFT (16) + +//DIEPTXFn +#define USBC_INEPNTXFSTADDR(n) (((n)&0xFFFF)<<0) +#define USBC_INEPNTXFSTADDR_MASK (0xFFFF<<0) +#define USBC_INEPNTXFSTADDR_SHIFT (0) +#define USBC_INEPNTXFDEP(n) (((n)&0xFFFF)<<16) +#define USBC_INEPNTXFDEP_MASK (0xFFFF<<16) +#define USBC_INEPNTXFDEP_SHIFT (16) + +//HPTXFSIZ +#define USBC_HPTXFSIZ_PTXFSTADDR(n) (((n)&0xFFFF)<<0) +#define USBC_HPTXFSIZ_PTXFSTADDR_MASK (0xFFFF<<0) +#define USBC_HPTXFSIZ_PTXFSTADDR_SHIFT (0) +#define USBC_HPTXFSIZ_PTXFSIZE(n) (((n)&0xFFFF)<<16) +#define USBC_HPTXFSIZ_PTXFSIZE_MASK (0xFFFF<<16) +#define USBC_HPTXFSIZ_PTXFSIZE_SHIFT (16) + +//HCFG +#define USBC_HCFG_MODECHTIMEN (1<<31) +#define USBC_HCFG_MODECHTIMEN_MASK (1<<31) +#define USBC_HCFG_MODECHTIMEN_SHIFT (31) +#define USBC_HCFG_PERSCHEDENA (1<<26) +#define USBC_HCFG_PERSCHEDENA_MASK (1<<26) +#define USBC_HCFG_PERSCHEDENA_SHIFT (26) +#define USBC_HCFG_FRLISTEN(n) (((n)&0x3)<<24) +#define USBC_HCFG_FRLISTEN_MASK (0x3<<24) +#define USBC_HCFG_FRLISTEN_SHIFT (24) +#define USBC_HCFG_DESCDMA (1<<23) +#define USBC_HCFG_DESCDMA_MASK (1<<23) +#define USBC_HCFG_DESCDMA_SHIFT (23) +#define USBC_HCFG_RESVALID(n) (((n)&0xff)<<8) +#define USBC_HCFG_RESVALID_MASK (0xff<<8) +#define USBC_HCFG_RESVALID_SHIFT (8) +#define USBC_HCFG_ENA32KHZS (1<<7) +#define USBC_HCFG_ENA32KHZS_MASK (1<<7) +#define USBC_HCFG_ENA32KHZS_SHIFT (7) +#define USBC_HCFG_FSLSSUPP (1<<2) +#define USBC_HCFG_FSLSSUPP_MASK (1<<2) +#define USBC_HCFG_FSLSSUPP_SHIFT (2) +#define USBC_HCFG_FSLSPCLKSEL(n) (((n)&0x3)<<0) +#define USBC_HCFG_FSLSPCLKSEL_MASK (0x3<<0) +#define USBC_HCFG_FSLSPCLKSEL_SHIFT (0) + +//HFIR +#define USBC_HFIR_HFIRRLDCTRL (1<<16) +#define USBC_HFIR_HFIRRLDCTRL_MASK (1<<16) +#define USBC_HFIR_HFIRRLDCTRL_SHIFT (16) +#define USBC_HFIR_FRINT(n) (((n)&0xffff)<<0) +#define USBC_HFIR_FRINT_MASK (0xffff<<0) +#define USBC_HFIR_FRINT_SHIFT (0) + +//HFNUM +#define USBC_HFNUM_FRREM(n) (((n)&0xffff)<<16) +#define USBC_HFNUM_FRREM_MASK (0xffff<<16) +#define USBC_HFNUM_FRREM_SHIFT (16) +#define USBC_HFNUM_FRNUM(n) (((n)&0xffff)<<0) +#define USBC_HFNUM_FRNUM_MASK (0xffff<<0) +#define USBC_HFNUM_FRNUM_SHIFT (0) + +//HPTXSTS +#define USBC_HPTXSTS_PTXQTOP(n) (((n)&0xff)<<24) +#define USBC_HPTXSTS_PTXQTOP_MASK (0xff<<24) +#define USBC_HPTXSTS_PTXQTOP_SHIFT (24) +#define USBC_HPTXSTS_PTXQSPCAVAIL(n) (((n)&0xff)<<16) +#define USBC_HPTXSTS_PTXQSPCAVAIL_MASK (0xff<<16) +#define USBC_HPTXSTS_PTXQSPCAVAIL_SHIFT (16) +#define USBC_HPTXSTS_PTXFSPCAVAIL(n) (((n)&0xffff)<<0) +#define USBC_HPTXSTS_PTXFSPCAVAIL_MASK (0xffff<<0) +#define USBC_HPTXSTS_PTXFSPCAVAIL_SHIFT (0) + +//HAINT +#define USBC_HAINT_HAINT(n) (((n)&0xffff)<<0) +#define USBC_HAINT_HAINT_MASK (0xffff<<0) +#define USBC_HAINT_HAINT_SHIFT (0) + +//HAINTMSK +#define USBC_HAINTMSK_HAINTMSK(n) (((n)&0xffff)<<0) +#define USBC_HAINTMSK_HAINTMSK_MASK (0xffff<<0) +#define USBC_HAINTMSK_HAINTMSK_SHIFT (0) + +//HPRT +#define USBC_HPRT_PRTSPD(n) (((n)&0x3)<<17) +#define USBC_HPRT_PRTSPD_MASK (0x3<<17) +#define USBC_HPRT_PRTSPD_SHIFT (17) +#define USBC_HPRT_PRTTSTCTL(n) (((n)&0xf)<<13) +#define USBC_HPRT_PRTTSTCTL_MASK (0xf<<13) +#define USBC_HPRT_PRTTSTCTL_SHIFT (13) +#define USBC_HPRT_PRTPWR (1<<12) +#define USBC_HPRT_PRTPWR_MASK (1<<12) +#define USBC_HPRT_PRTPWR_SHIFT (12) +#define USBC_HPRT_PRTLNSTS(n) (((n)&0x3)<<10) +#define USBC_HPRT_PRTLNSTS_MASK (0x3<<10) +#define USBC_HPRT_PRTLNSTS_SHIFT (10) +#define USBC_HPRT_PRTRST (1<<8) +#define USBC_HPRT_PRTRST_MASK (1<<8) +#define USBC_HPRT_PRTRST_SHIFT (8) +#define USBC_HPRT_PRTSUSP (1<<7) +#define USBC_HPRT_PRTSUSP_MASK (1<<7) +#define USBC_HPRT_PRTSUSP_SHIFT (7) +#define USBC_HPRT_PRTRES (1<<6) +#define USBC_HPRT_PRTRES_MASK (1<<6) +#define USBC_HPRT_PRTRES_SHIFT (6) +#define USBC_HPRT_PRTOVRCURRCHNG (1<<5) +#define USBC_HPRT_PRTOVRCURRCHNG_MASK (1<<5) +#define USBC_HPRT_PRTOVRCURRCHNG_SHIFT (5) +#define USBC_HPRT_PRTOVRCURRACT (1<<4) +#define USBC_HPRT_PRTOVRCURRACT_MASK (1<<4) +#define USBC_HPRT_PRTOVRCURRACT_SHIFT (4) +#define USBC_HPRT_PRTENCHNG (1<<3) +#define USBC_HPRT_PRTENCHNG_MASK (1<<3) +#define USBC_HPRT_PRTENCHNG_SHIFT (3) +#define USBC_HPRT_PRTENA (1<<2) +#define USBC_HPRT_PRTENA_MASK (1<<2) +#define USBC_HPRT_PRTENA_SHIFT (2) +#define USBC_HPRT_PRTCONNDET (1<<1) +#define USBC_HPRT_PRTCONNDET_MASK (1<<1) +#define USBC_HPRT_PRTCONNDET_SHIFT (1) +#define USBC_HPRT_PRTCONNSTS (1<<0) +#define USBC_HPRT_PRTCONNSTS_MASK (1<<0) +#define USBC_HPRT_PRTCONNSTS_SHIFT (0) + +//HCCHARN +#define USBC_HCCHARN_CHENA (1<<31) +#define USBC_HCCHARN_CHENA_MASK (1<<31) +#define USBC_HCCHARN_CHENA_SHIFT (31) +#define USBC_HCCHARN_CHDIS (1<<30) +#define USBC_HCCHARN_CHDIS_MASK (1<<30) +#define USBC_HCCHARN_CHDIS_SHIFT (30) +#define USBC_HCCHARN_ODDFRM (1<<29) +#define USBC_HCCHARN_ODDFRM_MASK (1<<29) +#define USBC_HCCHARN_ODDFRM_SHIFT (29) +#define USBC_HCCHARN_DEVADDR(n) (((n)&0x7f)<<22) +#define USBC_HCCHARN_DEVADDR_MASK (0x7f<<22) +#define USBC_HCCHARN_DEVADDR_SHIFT (22) +#define USBC_HCCHARN_EC(n) (((n)&0x3)<<20) +#define USBC_HCCHARN_EC_MASK (0x3<<20) +#define USBC_HCCHARN_EC_SHIFT (20) +#define USBC_HCCHARN_EPTYPE(n) (((n)&0x3)<<18) +#define USBC_HCCHARN_EPTYPE_MASK (0x3<<18) +#define USBC_HCCHARN_EPTYPE_SHIFT (18) +#define USBC_HCCHARN_LSPDDEV (1<<17) +#define USBC_HCCHARN_LSPDDEV_MASK (1<<17) +#define USBC_HCCHARN_LSPDDEV_SHIFT (17) +#define USBC_HCCHARN_EPDIR (1<<15) +#define USBC_HCCHARN_EPDIR_MASK (1<<15) +#define USBC_HCCHARN_EPDIR_SHIFT (15) +#define USBC_HCCHARN_EPNUM(n) (((n)&0xf)<<11) +#define USBC_HCCHARN_EPNUM_MASK (0xf<<11) +#define USBC_HCCHARN_EPNUM_SHIFT (11) +#define USBC_HCCHARN_MPS(n) (((n)&0x7ff)<<0) +#define USBC_HCCHARN_MPS_MASK (0x7ff<<0) +#define USBC_HCCHARN_MPS_SHIFT (0) + +//HCSPLTN +#define USBC_HCSPLTN_SPLTENA (1<<31) +#define USBC_HCSPLTN_SPLTENA_MASK (1<<31) +#define USBC_HCSPLTN_SPLTENA_SHIFT (31) +#define USBC_HCSPLTN_COMPSPLT (1<<16) +#define USBC_HCSPLTN_COMPSPLT_MASK (1<<16) +#define USBC_HCSPLTN_COMPSPLT_SHIFT (16) +#define USBC_HCSPLTN_EPDIR(n) (((n)&0x3)<<14) +#define USBC_HCSPLTN_EPDIR_MASK (0x3<<14) +#define USBC_HCSPLTN_EPDIR_SHIFT (14) +#define USBC_HCSPLTN_EPNUM(n) (((n)&0x7f)<<7) +#define USBC_HCSPLTN_EPNUM_MASK (0x7f<<7) +#define USBC_HCSPLTN_EPNUM_SHIFT (7) +#define USBC_HCSPLTN_MPS(n) (((n)&0x7f)<<0) +#define USBC_HCSPLTN_MPS_MASK (0x7f<<0) +#define USBC_HCSPLTN_MPS_SHIFT (0) + +//HCINTN +#define USBC_HCINTN_DESC_LST_ROLLINTR (1<<13) +#define USBC_HCINTN_DESC_LST_ROLLINTR_MASK (1<<13) +#define USBC_HCINTN_DESC_LST_ROLLINTR_SHIFT (13) +#define USBC_HCINTN_XCS_XACT_ERR (1<<12) +#define USBC_HCINTN_XCS_XACT_ERR_MASK (1<<12) +#define USBC_HCINTN_XCS_XACT_ERR_SHIFT (12) +#define USBC_HCINTN_BNAINTR (1<<11) +#define USBC_HCINTN_BNAINTR_MASK (1<<11) +#define USBC_HCINTN_BNAINTR_SHIFT (11) +#define USBC_HCINTN_DATATGLERR (1<<10) +#define USBC_HCINTN_DATATGLERR_MASK (1<<10) +#define USBC_HCINTN_DATATGLERR_SHIFT (10) +#define USBC_HCINTN_FRMOVRUN (1<<9) +#define USBC_HCINTN_FRMOVRUN_MASK (1<<9) +#define USBC_HCINTN_FRMOVRUN_SHIFT (9) +#define USBC_HCINTN_BBLERR (1<<8) +#define USBC_HCINTN_BBLERR_MASK (1<<8) +#define USBC_HCINTN_BBLERR_SHIFT (8) +#define USBC_HCINTN_XACTERR (1<<7) +#define USBC_HCINTN_XACTERR_MASK (1<<7) +#define USBC_HCINTN_XACTERR_SHIFT (7) +#define USBC_HCINTN_NYET (1<<6) +#define USBC_HCINTN_NYET_MASK (1<<6) +#define USBC_HCINTN_NYET_SHIFT (6) +#define USBC_HCINTN_ACK (1<<5) +#define USBC_HCINTN_ACK_MASK (1<<5) +#define USBC_HCINTN_ACK_SHIFT (5) +#define USBC_HCINTN_NAK (1<<4) +#define USBC_HCINTN_NAK_MASK (1<<4) +#define USBC_HCINTN_NAK_SHIFT (4) +#define USBC_HCINTN_STALL (1<<3) +#define USBC_HCINTN_STALL_MASK (1<<3) +#define USBC_HCINTN_STALL_SHIFT (3) +#define USBC_HCINTN_AHBERR (1<<2) +#define USBC_HCINTN_AHBERR_MASK (1<<2) +#define USBC_HCINTN_AHBERR_SHIFT (2) +#define USBC_HCINTN_CHHLTD (1<<1) +#define USBC_HCINTN_CHHLTD_MASK (1<<1) +#define USBC_HCINTN_CHHLTD_SHIFT (1) +#define USBC_HCINTN_XFERCOMPL (1<<0) +#define USBC_HCINTN_XFERCOMPL_MASK (1<<0) +#define USBC_HCINTN_XFERCOMPL_SHIFT (0) + +//HCINTMSKN +#define USBC_HCINTMSKN_DESC_LST_ROLLINTRMSK (1<<13) +#define USBC_HCINTMSKN_DESC_LST_ROLLINTRMSK_MASK (1<<13) +#define USBC_HCINTMSKN_DESC_LST_ROLLINTRMSK_SHIFT (13) +#define USBC_HCINTMSKN_BNAINTRMSK (1<<11) +#define USBC_HCINTMSKN_BNAINTRMSK_MASK (1<<11) +#define USBC_HCINTMSKN_BNAINTRMSK_SHIFT (11) +#define USBC_HCINTMSKN_DATATGLERRMSK (1<<10) +#define USBC_HCINTMSKN_DATATGLERRMSK_MASK (1<<10) +#define USBC_HCINTMSKN_DATATGLERRMSK_SHIFT (10) +#define USBC_HCINTMSKN_FRMOVRUNMSK (1<<9) +#define USBC_HCINTMSKN_FRMOVRUNMSK_MASK (1<<9) +#define USBC_HCINTMSKN_FRMOVRUNMSK_SHIFT (9) +#define USBC_HCINTMSKN_BBLERRMSK (1<<8) +#define USBC_HCINTMSKN_BBLERRMSK_MASK (1<<8) +#define USBC_HCINTMSKN_BBLERRMSK_SHIFT (8) +#define USBC_HCINTMSKN_XACTERRMSK (1<<7) +#define USBC_HCINTMSKN_XACTERRMSK_MASK (1<<7) +#define USBC_HCINTMSKN_XACTERRMSK_SHIFT (7) +#define USBC_HCINTMSKN_NYETMSK (1<<6) +#define USBC_HCINTMSKN_NYETMSK_MASK (1<<6) +#define USBC_HCINTMSKN_NYETMSK_SHIFT (6) +#define USBC_HCINTMSKN_ACKMSK (1<<5) +#define USBC_HCINTMSKN_ACKMSK_MASK (1<<5) +#define USBC_HCINTMSKN_ACKMSK_SHIFT (5) +#define USBC_HCINTMSKN_NAKMSK (1<<4) +#define USBC_HCINTMSKN_NAKMSK_MASK (1<<4) +#define USBC_HCINTMSKN_NAKMSK_SHIFT (4) +#define USBC_HCINTMSKN_STALLMSK (1<<3) +#define USBC_HCINTMSKN_STALLMSK_MASK (1<<3) +#define USBC_HCINTMSKN_STALLMSK_SHIFT (3) +#define USBC_HCINTMSKN_AHBERRMSK (1<<2) +#define USBC_HCINTMSKN_AHBERRMSK_MASK (1<<2) +#define USBC_HCINTMSKN_AHBERRMSK_SHIFT (2) +#define USBC_HCINTMSKN_CHHLTDMSK (1<<1) +#define USBC_HCINTMSKN_CHHLTDMSK_MASK (1<<1) +#define USBC_HCINTMSKN_CHHLTDMSK_SHIFT (1) +#define USBC_HCINTMSKN_XFERCOMPLMSK (1<<0) +#define USBC_HCINTMSKN_XFERCOMPLMSK_MASK (1<<0) +#define USBC_HCINTMSKN_XFERCOMPLMSK_SHIFT (0) + +//HCTSIZN +//SCATTER/GATHER DMA MODE +#define USBC_HCTSIZN_DOPNG (1<<31) +#define USBC_HCTSIZN_DOPNG_MASK (1<<31) +#define USBC_HCTSIZN_DOPNG_SHIFT (31) +#define USBC_HCTSIZN_PID(n) (((n)&0x3)<<29) +#define USBC_HCTSIZN_PID_MASK (0x3<<29) +#define USBC_HCTSIZN_PID_SHIFT (29) +#define USBC_HCTSIZN_NTD(n) (((n)&0xff)<<8) +#define USBC_HCTSIZN_NTD_MASK (0xff<<8) +#define USBC_HCTSIZN_NTD_SHIFT (8) +#define USBC_HCTSIZN_SCHED(n) (((n)&0xff)<<0) +#define USBC_HCTSIZN_SCHED_MASK (0xff<<0) +#define USBC_HCTSIZN_SCHED_SHIFT (0) + +//HCTSIZN +//NON-SCATTER/GATHER DMA MODE +#define USBC_HCTSIZN_DOPNG (1<<31) +#define USBC_HCTSIZN_DOPNG_MASK (1<<31) +#define USBC_HCTSIZN_DOPNG_SHIFT (31) +#define USBC_HCTSIZN_PID(n) (((n)&0x3)<<29) +#define USBC_HCTSIZN_PID_MASK (0x3<<29) +#define USBC_HCTSIZN_PID_SHIFT (29) +#define USBC_HCTSIZN_PKTCNT(n) (((n)&0x3ff)<<19) +#define USBC_HCTSIZN_PKTCNT_MASK (0x3ff<<19) +#define USBC_HCTSIZN_PKTCNT_SHIFT (19) +#define USBC_HCTSIZN_XFERSIZE(n) (((n)&0x7ffff)<<0) +#define USBC_HCTSIZN_XFERSIZE_MASK (0x7ffff<<0) +#define USBC_HCTSIZN_XFERSIZE_SHIFT (0) + +//HCDMAN +//BUFFER DMA MODE +#define USBC_HCDMAN_DMAADDR(n) (((n)&0xffffffff)<<0) +#define USBC_HCDMAN_DMAADDR_MASK (0xffffffff<<0) +#define USBC_HCDMAN_DMAADDR_SHIFT (0) + +//HCDMABN +#define USBC_HCDMABN_DMAADDR(n) (((n)&0xffffffff)<<0) +#define USBC_HCDMABN_DMAADDR_MASK (0xffffffff<<0) +#define USBC_HCDMABN_DMAADDR_SHIFT (0) + +//DCFG +#define USBC_DEVSPD(n) (((n)&3)<<0) +#define USBC_DEVSPD_MASK (3<<0) +#define USBC_DEVSPD_SHIFT (0) +#define USBC_NZSTSOUTHSHK (1<<2) +#define USBC_NZSTSOUTHSHK_MASK (1<<2) +#define USBC_NZSTSOUTHSHK_SHIFT (2) +#define USBC_DEVADDR(n) (((n)&0x7F)<<4) +#define USBC_DEVADDR_MASK (0x7F<<4) +#define USBC_DEVADDR_SHIFT (4) +#define USBC_PERFRINT(n) (((n)&3)<<11) +#define USBC_PERFRINT_MASK (3<<11) +#define USBC_PERFRINT_SHIFT (11) +#define USBC_EPMISCNT(n) (((n)&31)<<18) +#define USBC_EPMISCNT_MASK (31<<18) +#define USBC_EPMISCNT_SHIFT (18) + +//DCTL +#define USBC_RMTWKUPSIG (1<<0) +#define USBC_RMTWKUPSIG_MASK (1<<0) +#define USBC_RMTWKUPSIG_SHIFT (0) +#define USBC_SFTDISCON (1<<1) +#define USBC_SFTDISCON_MASK (1<<1) +#define USBC_SFTDISCON_SHIFT (1) +#define USBC_GNPINNAKSTS (1<<2) +#define USBC_GNPINNAKSTS_MASK (1<<2) +#define USBC_GNPINNAKSTS_SHIFT (2) +#define USBC_GOUTNAKSTS (1<<3) +#define USBC_GOUTNAKSTS_MASK (1<<3) +#define USBC_GOUTNAKSTS_SHIFT (3) +#define USBC_TSTCTL(n) (((n)&7)<<4) +#define USBC_TSTCTL_MASK (7<<4) +#define USBC_TSTCTL_SHIFT (4) +#define USBC_SGNPINNAK (1<<7) +#define USBC_SGNPINNAK_MASK (1<<7) +#define USBC_SGNPINNAK_SHIFT (7) +#define USBC_CGNPINNAK (1<<8) +#define USBC_CGNPINNAK_MASK (1<<8) +#define USBC_CGNPINNAK_SHIFT (8) +#define USBC_SGOUTNAK (1<<9) +#define USBC_SGOUTNAK_MASK (1<<9) +#define USBC_SGOUTNAK_SHIFT (9) +#define USBC_CGOUTNAK (1<<10) +#define USBC_CGOUTNAK_MASK (1<<10) +#define USBC_CGOUTNAK_SHIFT (10) +#define USBC_PWRONPRGDONE (1<<11) +#define USBC_PWRONPRGDONE_MASK (1<<11) +#define USBC_PWRONPRGDONE_SHIFT (11) +#define USBC_GMC(n) (((n)&3)<<12) +#define USBC_GMC_MASK (3<<12) +#define USBC_GMC_SHIFT (12) +#define USBC_IGNRFRMNUM (1<<15) +#define USBC_IGNRFRMNUM_MASK (1<<15) +#define USBC_IGNRFRMNUM_SHIFT (15) + +//DSTS +#define USBC_SUSPSTS (1<<0) +#define USBC_SUSPSTS_MASK (1<<0) +#define USBC_SUSPSTS_SHIFT (0) +#define USBC_ENUMSPD(n) (((n)&3)<<1) +#define USBC_ENUMSPD_MASK (3<<1) +#define USBC_ENUMSPD_SHIFT (1) +#define USBC_ERRTICERR (1<<3) +#define USBC_ERRTICERR_MASK (1<<3) +#define USBC_ERRTICERR_SHIFT (3) +#define USBC_SOFFN(n) (((n)&0x3FFF)<<8) +#define USBC_SOFFN_MASK (0x3FFF<<8) +#define USBC_SOFFN_SHIFT (8) + +//DIEPMSK +#define USBC_XFERCOMPLMSK (1<<0) +#define USBC_XFERCOMPLMSK_MASK (1<<0) +#define USBC_XFERCOMPLMSK_SHIFT (0) +#define USBC_EPDISBLDMSK (1<<1) +#define USBC_EPDISBLDMSK_MASK (1<<1) +#define USBC_EPDISBLDMSK_SHIFT (1) +#define USBC_AHBERRMSK (1<<2) +#define USBC_AHBERRMSK_MASK (1<<2) +#define USBC_AHBERRMSK_SHIFT (2) +#define USBC_TIMEOUTMSK (1<<3) +#define USBC_TIMEOUTMSK_MASK (1<<3) +#define USBC_TIMEOUTMSK_SHIFT (3) +#define USBC_INTKNTXFEMPMSK (1<<4) +#define USBC_INTKNTXFEMPMSK_MASK (1<<4) +#define USBC_INTKNTXFEMPMSK_SHIFT (4) +#define USBC_INTKNEPMISMSK (1<<5) +#define USBC_INTKNEPMISMSK_MASK (1<<5) +#define USBC_INTKNEPMISMSK_SHIFT (5) +#define USBC_INEPNAKEFFMSK (1<<6) +#define USBC_INEPNAKEFFMSK_MASK (1<<6) +#define USBC_INEPNAKEFFMSK_SHIFT (6) +#define USBC_TXFEMPMSK (1<<7) +#define USBC_TXFIFOUNDRNMSK (1<<8) +#define USBC_TXFIFOUNDRNMSK_MASK (1<<8) +#define USBC_TXFIFOUNDRNMSK_SHIFT (8) +#define USBC_BNAINTRMSK (1<<9) +#define USBC_PKTDRPSTSMSK (1<<11) +#define USBC_BBLEERRINTRPTMSK (1<<12) +#define USBC_NAKINTRPTMSK (1<<13) +#define USBC_NYETINTRPTMSK (1<<14) +#define USBC_STUPPKTRCVDMSK (1<<15) + +//DOEPMSK +//#define USBC_XFERCOMPLMSK (1<<0) +//#define USBC_XFERCOMPLMSK_MASK (1<<0) +//#define USBC_XFERCOMPLMSK_SHIFT (0) +//#define USBC_EPDISBLDMSK (1<<1) +//#define USBC_EPDISBLDMSK_MASK (1<<1) +//#define USBC_EPDISBLDMSK_SHIFT (1) +//#define USBC_AHBERRMSK (1<<2) +//#define USBC_AHBERRMSK_MASK (1<<2) +//#define USBC_AHBERRMSK_SHIFT (2) +#define USBC_SETUPMSK (1<<3) +#define USBC_SETUPMSK_MASK (1<<3) +#define USBC_SETUPMSK_SHIFT (3) +#define USBC_OUTTKNEPDISMSK (1<<4) +#define USBC_OUTTKNEPDISMSK_MASK (1<<4) +#define USBC_OUTTKNEPDISMSK_SHIFT (4) +#define USBC_BACK2BACKSETUPMSK (1<<6) +#define USBC_BACK2BACKSETUPMSK_MASK (1<<6) +#define USBC_BACK2BACKSETUPMSK_SHIFT (6) +#define USBC_OUTPKTERRMSK (1<<8) +#define USBC_OUTPKTERRMSK_MASK (1<<8) +#define USBC_OUTPKTERRMSK_SHIFT (8) +//#define USBC_BNAINTRMSK (1<<9) +//#define USBC_PKTDRPSTSMSK (1<<11) +//#define USBC_BBLEERRINTRPTMSK (1<<12) +//#define USBC_NAKINTRPTMSK (1<<13) +//#define USBC_NYETINTRPTMSK (1<<14) +//#define USBC_STUPPKTRCVDMSK (1<<15) + +//DAINT +#define USBC_INEPINT(n) (((n)&0xFFFF)<<0) +#define USBC_INEPINT_MASK (0xFFFF<<0) +#define USBC_INEPINT_SHIFT (0) +#define USBC_OUTEPINT(n) (((n)&0xFFFF)<<16) +#define USBC_OUTEPINT_MASK (0xFFFF<<16) +#define USBC_OUTEPINT_SHIFT (16) + +//DAINTMSK +#define USBC_INEPMSK(n) (((n)&0xFFFF)<<0) +#define USBC_INEPMSK_MASK (0xFFFF<<0) +#define USBC_INEPMSK_SHIFT (0) +#define USBC_OUTEPMSK(n) (((n)&0xFFFF)<<16) +#define USBC_OUTEPMSK_MASK (0xFFFF<<16) +#define USBC_OUTEPMSK_SHIFT (16) + +//DVBUSDIS +#define USBC_DVBUSDIS(n) (((n)&0xFFFF)<<0) +#define USBC_DVBUSDIS_MASK (0xFFFF<<0) +#define USBC_DVBUSDIS_SHIFT (0) + +//DVBUSPULSE +#define USBC_DVBUSPULSE(n) (((n)&0xFFF)<<0) +#define USBC_DVBUSPULSE_MASK (0xFFF<<0) +#define USBC_DVBUSPULSE_SHIFT (0) + +//DTHRCTL +#define USBC_NONISOTHREN (1<<0) +#define USBC_NONISOTHREN_MASK (1<<0) +#define USBC_NONISOTHREN_SHIFT (0) +#define USBC_ISOTHREN (1<<1) +#define USBC_ISOTHREN_MASK (1<<1) +#define USBC_ISOTHREN_SHIFT (1) +#define USBC_TXTHRLEN(n) (((n)&0x1FF)<<2) +#define USBC_TXTHRLEN_MASK (0x1FF<<2) +#define USBC_TXTHRLEN_SHIFT (2) +#define USBC_RXTHREN (1<<16) +#define USBC_RXTHREN_MASK (1<<16) +#define USBC_RXTHREN_SHIFT (16) +#define USBC_RXTHRLEN(n) (((n)&0x1FF)<<17) +#define USBC_RXTHRLEN_MASK (0x1FF<<17) +#define USBC_RXTHRLEN_SHIFT (17) +#define USBC_ARBPRKEN (1<<27) +#define USBC_ARBPRKEN_MASK (1<<27) +#define USBC_ARBPRKEN_SHIFT (27) + +//DIEPEMPMSK +#define USBC_INEPTXFEMPMSK(n) (((n)&0xFFFF)<<0) +#define USBC_INEPTXFEMPMSK_MASK (0xFFFF<<0) +#define USBC_INEPTXFEMPMSK_SHIFT (0) + +//DIEPCTL0 +#define USBC_EP0_MPS(n) (((n)&3)<<0) +#define USBC_EP0_MPS_MASK (3<<0) +#define USBC_EP0_MPS_SHIFT (0) +#define USBC_NEXTEP(n) (((n)&15)<<11) +#define USBC_NEXTEP_MASK (15<<11) +#define USBC_NEXTEP_SHIFT (11) +#define USBC_USBACTEP (1<<15) +#define USBC_USBACTEP_MASK (1<<15) +#define USBC_USBACTEP_SHIFT (15) +#define USBC_NAKSTS (1<<17) +#define USBC_NAKSTS_MASK (1<<17) +#define USBC_NAKSTS_SHIFT (17) +#define USBC_EPTYPE(n) (((n)&3)<<18) +#define USBC_EPTYPE_MASK (3<<18) +#define USBC_EPTYPE_SHIFT (18) +#define USBC_STALL (1<<21) +#define USBC_STALL_MASK (1<<21) +#define USBC_STALL_SHIFT (21) +#define USBC_EPTXFNUM(n) (((n)&15)<<22) +#define USBC_EPTXFNUM_MASK (15<<22) +#define USBC_EPTXFNUM_SHIFT (22) +#define USBC_CNAK (1<<26) +#define USBC_CNAK_MASK (1<<26) +#define USBC_CNAK_SHIFT (26) +#define USBC_SNAK (1<<27) +#define USBC_SNAK_MASK (1<<27) +#define USBC_SNAK_SHIFT (27) +#define USBC_EPDIS (1<<30) +#define USBC_EPDIS_MASK (1<<30) +#define USBC_EPDIS_SHIFT (30) +#define USBC_EPENA (1<<31) +#define USBC_EPENA_MASK (1<<31) +#define USBC_EPENA_SHIFT (31) + +//DIEPINT0 +#define USBC_XFERCOMPL (1<<0) +#define USBC_XFERCOMPL_MASK (1<<0) +#define USBC_XFERCOMPL_SHIFT (0) +#define USBC_EPDISBLD (1<<1) +#define USBC_EPDISBLD_MASK (1<<1) +#define USBC_EPDISBLD_SHIFT (1) +#define USBC_AHBERR (1<<2) +#define USBC_AHBERR_MASK (1<<2) +#define USBC_AHBERR_SHIFT (2) +#define USBC_TIMEOUT (1<<3) +#define USBC_TIMEOUT_MASK (1<<3) +#define USBC_TIMEOUT_SHIFT (3) +#define USBC_INTKNTXFEMP (1<<4) +#define USBC_INTKNTXFEMP_MASK (1<<4) +#define USBC_INTKNTXFEMP_SHIFT (4) +#define USBC_INTKNEPMIS (1<<5) +#define USBC_INTKNEPMIS_MASK (1<<5) +#define USBC_INTKNEPMIS_SHIFT (5) +#define USBC_INEPNAKEFF (1<<6) +#define USBC_INEPNAKEFF_MASK (1<<6) +#define USBC_INEPNAKEFF_SHIFT (6) +#define USBC_TXFEMP (1<<7) +#define USBC_TXFEMP_MASK (1<<7) +#define USBC_TXFEMP_SHIFT (7) +#define USBC_TXFIFOUNDRN (1<<8) +#define USBC_TXFIFOUNDRN_MASK (1<<8) +#define USBC_TXFIFOUNDRN_SHIFT (8) +#define USBC_BNAINTR (1<<9) +#define USBC_PKTDRPSTS (1<<11) +#define USBC_BBLEERRINTRPT (1<<12) +#define USBC_NAKINTRPT (1<<13) +#define USBC_NYETINTRPT (1<<14) +#define USBC_STUPPKTRCVD (1<<15) + +//DIEPTSIZ0 +#define USBC_IEPXFERSIZE0(n) (((n)&0x7F)<<0) +#define USBC_IEPXFERSIZE0_MASK (0x7F<<0) +#define USBC_IEPXFERSIZE0_SHIFT (0) +#define USBC_IEPPKTCNT0(n) (((n)&3)<<19) +#define USBC_IEPPKTCNT0_MASK (3<<19) +#define USBC_IEPPKTCNT0_SHIFT (19) + +//DIEPDMA0 +#define USBC_DMAADDR(n) (((n)&0xFFFFFFFF)<<0) +#define USBC_DMAADDR_MASK (0xFFFFFFFF<<0) +#define USBC_DMAADDR_SHIFT (0) + +//DIEPFSTS0 +#define USBC_INEPTXFSPCAVAIL(n) (((n)&0xFFFF)<<0) +#define USBC_INEPTXFSPCAVAIL_MASK (0xFFFF<<0) +#define USBC_INEPTXFSPCAVAIL_SHIFT (0) + +//DIEPCTL +#define USBC_EPN_MPS(n) (((n)&0x7FF)<<0) +#define USBC_EPN_MPS_MASK (0x7FF<<0) +#define USBC_EPN_MPS_SHIFT (0) +//#define USBC_NEXTEP(n) (((n)&15)<<11) +//#define USBC_NEXTEP_MASK (15<<11) +//#define USBC_NEXTEP_SHIFT (11) +//#define USBC_USBACTEP (1<<15) +//#define USBC_USBACTEP_MASK (1<<15) +//#define USBC_USBACTEP_SHIFT (15) +#define USBC_EPDPID (1<<16) +#define USBC_EPDPID_MASK (1<<16) +#define USBC_EPDPID_SHIFT (16) +//#define USBC_NAKSTS (1<<17) +//#define USBC_NAKSTS_MASK (1<<17) +//#define USBC_NAKSTS_SHIFT (17) +//#define USBC_EPTYPE(n) (((n)&3)<<18) +//#define USBC_EPTYPE_MASK (3<<18) +//#define USBC_EPTYPE_SHIFT (18) +#define USBC_SNP (1<<20) +#define USBC_SNP_MASK (1<<20) +#define USBC_SNP_SHIFT (20) +//#define USBC_STALL (1<<21) +//#define USBC_STALL_MASK (1<<21) +//#define USBC_STALL_SHIFT (21) +//#define USBC_EPTXFNUM(n) (((n)&15)<<22) +//#define USBC_EPTXFNUM_MASK (15<<22) +//#define USBC_EPTXFNUM_SHIFT (22) +//#define USBC_CNAK (1<<26) +//#define USBC_CNAK_MASK (1<<26) +//#define USBC_CNAK_SHIFT (26) +//#define USBC_SNAK (1<<27) +//#define USBC_SNAK_MASK (1<<27) +//#define USBC_SNAK_SHIFT (27) +#define USBC_SETD0PID (1<<28) +#define USBC_SETD0PID_MASK (1<<28) +#define USBC_SETD0PID_SHIFT (28) +#define USBC_SETD1PID (1<<29) +#define USBC_SETD1PID_MASK (1<<29) +#define USBC_SETD1PID_SHIFT (29) +//#define USBC_EPDIS (1<<30) +//#define USBC_EPDIS_MASK (1<<30) +//#define USBC_EPDIS_SHIFT (30) +//#define USBC_EPENA (1<<31) +//#define USBC_EPENA_MASK (1<<31) +//#define USBC_EPENA_SHIFT (31) + +//DIEPINT +//#define USBC_XFERCOMPL (1<<0) +//#define USBC_XFERCOMPL_MASK (1<<0) +//#define USBC_XFERCOMPL_SHIFT (0) +//#define USBC_EPDISBLD (1<<1) +//#define USBC_EPDISBLD_MASK (1<<1) +//#define USBC_EPDISBLD_SHIFT (1) +//#define USBC_AHBERR (1<<2) +//#define USBC_AHBERR_MASK (1<<2) +//#define USBC_AHBERR_SHIFT (2) +//#define USBC_TIMEOUT (1<<3) +//#define USBC_TIMEOUT_MASK (1<<3) +//#define USBC_TIMEOUT_SHIFT (3) +//#define USBC_INTKNTXFEMP (1<<4) +//#define USBC_INTKNTXFEMP_MASK (1<<4) +//#define USBC_INTKNTXFEMP_SHIFT (4) +//#define USBC_INTKNEPMIS (1<<5) +//#define USBC_INTKNEPMIS_MASK (1<<5) +//#define USBC_INTKNEPMIS_SHIFT (5) +//#define USBC_INEPNAKEFF (1<<6) +//#define USBC_INEPNAKEFF_MASK (1<<6) +//#define USBC_INEPNAKEFF_SHIFT (6) +//#define USBC_TXFEMP (1<<7) +//#define USBC_TXFEMP_MASK (1<<7) +//#define USBC_TXFEMP_SHIFT (7) +//#define USBC_TXFIFOUNDRN (1<<8) +//#define USBC_TXFIFOUNDRN_MASK (1<<8) +//#define USBC_TXFIFOUNDRN_SHIFT (8) + +//DIEPTSIZ +#define USBC_IEPXFERSIZE(n) (((n)&0x7FFFF)<<0) +#define USBC_IEPXFERSIZE_MASK (0x7FFFF<<0) +#define USBC_IEPXFERSIZE_SHIFT (0) +#define USBC_IEPPKTCNT(n) (((n)&0x3FF)<<19) +#define USBC_IEPPKTCNT_MASK (0x3FF<<19) +#define USBC_IEPPKTCNT_SHIFT (19) +#define USBC_MC(n) (((n)&3)<<29) +#define USBC_MC_MASK (3<<29) +#define USBC_MC_SHIFT (29) + +//DIEPDMA +//#define USBC_DMAADDR(n) (((n)&0xFFFFFFFF)<<0) +//#define USBC_DMAADDR_MASK (0xFFFFFFFF<<0) +//#define USBC_DMAADDR_SHIFT (0) + +//DIEPFSTS +//#define USBC_INEPTXFSPCAVAIL(n) (((n)&0xFFFF)<<0) +//#define USBC_INEPTXFSPCAVAIL_MASK (0xFFFF<<0) +//#define USBC_INEPTXFSPCAVAIL_SHIFT (0) + +//DOEPCTL0 +//#define USBC_EP0_MPS(n) (((n)&3)<<0) +//#define USBC_EP0_MPS_MASK (3<<0) +//#define USBC_EP0_MPS_SHIFT (0) +//#define USBC_USBACTEP (1<<15) +//#define USBC_USBACTEP_MASK (1<<15) +//#define USBC_USBACTEP_SHIFT (15) +//#define USBC_NAKSTS (1<<17) +//#define USBC_NAKSTS_MASK (1<<17) +//#define USBC_NAKSTS_SHIFT (17) +//#define USBC_EPTYPE(n) (((n)&3)<<18) +//#define USBC_EPTYPE_MASK (3<<18) +//#define USBC_EPTYPE_SHIFT (18) +//#define USBC_SNP (1<<20) +//#define USBC_SNP_MASK (1<<20) +//#define USBC_SNP_SHIFT (20) +//#define USBC_STALL (1<<21) +//#define USBC_STALL_MASK (1<<21) +//#define USBC_STALL_SHIFT (21) +//#define USBC_CNAK (1<<26) +//#define USBC_CNAK_MASK (1<<26) +//#define USBC_CNAK_SHIFT (26) +//#define USBC_SNAK (1<<27) +//#define USBC_SNAK_MASK (1<<27) +//#define USBC_SNAK_SHIFT (27) +//#define USBC_EPDIS (1<<30) +//#define USBC_EPDIS_MASK (1<<30) +//#define USBC_EPDIS_SHIFT (30) +//#define USBC_EPENA (1<<31) +//#define USBC_EPENA_MASK (1<<31) +//#define USBC_EPENA_SHIFT (31) + +//DOEPINT0 +//#define USBC_XFERCOMPL (1<<0) +//#define USBC_XFERCOMPL_MASK (1<<0) +//#define USBC_XFERCOMPL_SHIFT (0) +//#define USBC_EPDISBLD (1<<1) +//#define USBC_EPDISBLD_MASK (1<<1) +//#define USBC_EPDISBLD_SHIFT (1) +//#define USBC_AHBERR (1<<2) +//#define USBC_AHBERR_MASK (1<<2) +//#define USBC_AHBERR_SHIFT (2) +#define USBC_SETUP (1<<3) +#define USBC_SETUP_MASK (1<<3) +#define USBC_SETUP_SHIFT (3) +#define USBC_OUTTKNEPDIS (1<<4) +#define USBC_OUTTKNEPDIS_MASK (1<<4) +#define USBC_OUTTKNTPDIS_SHIFT (4) +#define USBC_STSPHSERCVD (1<<5) +#define USBC_STSPHSERCVD_MASK (1<<5) +#define USBC_STSPHSERCVD_SHIFT (5) +#define USBC_BACK2BACKSETUP (1<<6) +#define USBC_BACK2BACKSETUP_MASK (1<<6) +#define USBC_BACK2BACKSETUP_SHIFT (6) +//#define USBC_TXFEMP (1<<7) +//#define USBC_TXFEMP_MASK (1<<7) +//#define USBC_TXFEMP_SHIFT (7) +#define USBC_OUTPKTERR (1<<8) +#define USBC_OUTPKTERR_MASK (1<<8) +#define USBC_OUTPKTERR_SHIFT (8) +//#define USBC_BNAINTR (1<<9) +//#define USBC_PKTDRPSTS (1<<11) +//#define USBC_BBLEERRINTRPT (1<<12) +//#define USBC_NAKINTRPT (1<<13) +//#define USBC_NYETINTRPT (1<<14) +//#define USBC_STUPPKTRCVD (1<<15) + +//DOEPTSIZ0 +#define USBC_OEPXFERSIZE0(n) (((n)&0x7F)<<0) +#define USBC_OEPXFERSIZE0_MASK (0x7F<<0) +#define USBC_OEPXFERSIZE0_SHIFT (0) +#define USBC_OEPPKTCNT0 (1<<19) +#define USBC_OEPPKTCNT0_MASK (1<<19) +#define USBC_OEPPKTCNT0_SHIFT (19) +#define USBC_SUPCNT(n) (((n)&3)<<29) +#define USBC_SUPCNT_MASK (3<<29) +#define USBC_SUPCNT_SHIFT (29) + +//DOEPDMA0 +//#define USBC_DMAADDR(n) (((n)&0xFFFFFFFF)<<0) +//#define USBC_DMAADDR_MASK (0xFFFFFFFF<<0) +//#define USBC_DMAADDR_SHIFT (0) + +//DOEPCTL +//#define USBC_EPN_MPS(n) (((n)&0x7FF)<<0) +//#define USBC_EPN_MPS_MASK (0x7FF<<0) +//#define USBC_EPN_MPS_SHIFT (0) +//#define USBC_NEXTEP(n) (((n)&15)<<11) +//#define USBC_NEXTEP_MASK (15<<11) +//#define USBC_NEXTEP_SHIFT (11) +//#define USBC_USBACTEP (1<<15) +//#define USBC_USBACTEP_MASK (1<<15) +//#define USBC_USBACTEP_SHIFT (15) +//#define USBC_EPDPID (1<<16) +//#define USBC_EPDPID_MASK (1<<16) +//#define USBC_EPDPID_SHIFT (16) +//#define USBC_NAKSTS (1<<17) +//#define USBC_NAKSTS_MASK (1<<17) +//#define USBC_NAKSTS_SHIFT (17) +//#define USBC_EPTYPE(n) (((n)&3)<<18) +//#define USBC_EPTYPE_MASK (3<<18) +//#define USBC_EPTYPE_SHIFT (18) +//#define USBC_SNP (1<<20) +//#define USBC_SNP_MASK (1<<20) +//#define USBC_SNP_SHIFT (20) +//#define USBC_STALL (1<<21) +//#define USBC_STALL_MASK (1<<21) +//#define USBC_STALL_SHIFT (21) +//#define USBC_EPTXFNUM(n) (((n)&15)<<22) +//#define USBC_EPTXFNUM_MASK (15<<22) +//#define USBC_EPTXFNUM_SHIFT (22) +//#define USBC_CNAK (1<<26) +//#define USBC_CNAK_MASK (1<<26) +//#define USBC_CNAK_SHIFT (26) +//#define USBC_SNAK (1<<27) +//#define USBC_SNAK_MASK (1<<27) +//#define USBC_SNAK_SHIFT (27) +//#define USBC_SETD0PID (1<<28) +//#define USBC_SETD0PID_MASK (1<<28) +//#define USBC_SETD0PID_SHIFT (28) +//#define USBC_SETD1PID (1<<29) +//#define USBC_SETD1PID_MASK (1<<29) +//#define USBC_SETD1PID_SHIFT (29) +//#define USBC_EPDIS (1<<30) +//#define USBC_EPDIS_MASK (1<<30) +//#define USBC_EPDIS_SHIFT (30) +//#define USBC_EPENA (1<<31) +//#define USBC_EPENA_MASK (1<<31) +//#define USBC_EPENA_SHIFT (31) + +//DOEPINT +//#define USBC_XFERCOMPL (1<<0) +//#define USBC_XFERCOMPL_MASK (1<<0) +//#define USBC_XFERCOMPL_SHIFT (0) +//#define USBC_EPDISBLD (1<<1) +//#define USBC_EPDISBLD_MASK (1<<1) +//#define USBC_EPDISBLD_SHIFT (1) +//#define USBC_AHBERR (1<<2) +//#define USBC_AHBERR_MASK (1<<2) +//#define USBC_AHBERR_SHIFT (2) +//#define USBC_SETUP (1<<3) +//#define USBC_SETUP_MASK (1<<3) +//#define USBC_SETUP_SHIFT (3) +//#define USBC_OUTTKNEPDIS (1<<4) +//#define USBC_OUTTKNEPDIS_MASK (1<<4) +//#define USBC_OUTTKNTPDIS_SHIFT (4) +//#define USBC_STSPHSERCVD (1<<5) +//#define USBC_STSPHSERCVD_MASK (1<<5) +//#define USBC_STSPHSERCVD_SHIFT (5) +//#define USBC_BACK2BACKSETUP (1<<6) +//#define USBC_BACK2BACKSETUP_MASK (1<<6) +//#define USBC_BACK2BACKSETUP_SHIFT (6) +//#define USBC_TXFEMP (1<<7) +//#define USBC_TXFEMP_MASK (1<<7) +//#define USBC_TXFEMP_SHIFT (7) +//#define USBC_OUTPKTERR (1<<8) +//#define USBC_OUTPKTERR_MASK (1<<8) +//#define USBC_OUTPKTERR_SHIFT (8) +//#define USBC_BNAINTR (1<<9) +//#define USBC_PKTDRPSTS (1<<11) +//#define USBC_BBLEERRINTRPT (1<<12) +//#define USBC_NAKINTRPT (1<<13) +//#define USBC_NYETINTRPT (1<<14) +//#define USBC_STUPPKTRCVD (1<<15) + +//DOEPTSIZ +#define USBC_OEPXFERSIZE(n) (((n)&0x7FFFF)<<0) +#define USBC_OEPXFERSIZE_MASK (0x7FFFF<<0) +#define USBC_OEPXFERSIZE_SHIFT (0) +#define USBC_OEPPKTCNT(n) (((n)&0x3FF)<<19) +#define USBC_OEPPKTCNT_MASK (0x3FF<<19) +#define USBC_OEPPKTCNT_SHIFT (19) +//#define USBC_MC(n) (((n)&3)<<29) +//#define USBC_MC_MASK (3<<29) +//#define USBC_MC_SHIFT (29) +#define USBC_RXDPID(n) (((n)&3)<<29) +#define USBC_RXDPID_MASK (3<<29) +#define USBC_RXDPID_SHIFT (29) + +//DOEPDMA +//#define USBC_DMAADDR(n) (((n)&0xFFFFFFFF)<<0) +//#define USBC_DMAADDR_MASK (0xFFFFFFFF<<0) +//#define USBC_DMAADDR_SHIFT (0) + +//PCGCCTL +#define USBC_STOPPCLK (1<<0) +#define USBC_STOPPCLK_MASK (1<<0) +#define USBC_STOPPCLK_SHIFT (0) +#define USBC_GATEHCLK (1<<1) +#define USBC_GATEHCLK_MASK (1<<1) +#define USBC_GATEHCLK_SHIFT (1) +#define USBC_PWRCLMP (1<<2) +#define USBC_PWRCLMP_MASK (1<<2) +#define USBC_PWRCLMP_SHIFT (2) +#define USBC_RSTPDWNMODULE (1<<3) +#define USBC_RSTPDWNMODULE_MASK (1<<3) +#define USBC_RSTPDWNMODULE_SHIFT (3) +#define USBC_ENBL_L1GATING (1<<5) +#define USBC_ENBL_L1GATING_MASK (1<<5) +#define USBC_ENBL_L1GATING_SHIFT (5) +#define USBC_PHYSLEEP (1<<6) +#define USBC_PHYSLEEP_MASK (1<<6) +#define USBC_PHYSLEEP_SHIFT (6) +#define USBC_SUSPENDED (1<<7) +#define USBC_SUSPENDED_MASK (1<<7) +#define USBC_SUSPENDED_SHIFT (7) + +//TxRxData +#define USBC_TXDATA(n) (((n)&0xFFFFFFFF)<<0) +#define USBC_TXDATA_MASK (0xFFFFFFFF<<0) +#define USBC_TXDATA_SHIFT (0) +#define USBC_RXDATA(n) (((n)&0xFFFFFFFF)<<0) +#define USBC_RXDATA_MASK (0xFFFFFFFF<<0) +#define USBC_RXDATA_SHIFT (0) + +//RAMData +#define USBC_DATA(n) (((n)&0xFFFFFFFF)<<0) +#define USBC_DATA_MASK (0xFFFFFFFF<<0) +#define USBC_DATA_SHIFT (0) + + +// ============================================================================ +// USBIF_T +// ----------------------------------------------------------------------------- +/// +// ============================================================================= +struct USBIF_T { + __IO uint32_t USBIF_00; + __IO uint32_t USBIF_04; + __IO uint32_t USBIF_08; + __IO uint32_t USBIF_0C; + __IO uint32_t USBIF_10; + __IO uint32_t USBIF_14; + __IO uint32_t USBIF_18; + __IO uint32_t USBIF_1C; + __IO uint32_t USBIF_20; +}; + +// USBIF_00 +#define USBIF_00_CFG_TP_SEL_SHIFT 0 +#define USBIF_00_CFG_TP_SEL_MASK (0xFF << USBIF_00_CFG_TP_SEL_SHIFT) +#define USBIF_00_CFG_TP_SEL(n) BITFIELD_VAL(USBIF_00_CFG_TP_SEL, n) +#define USBIF_00_CFG_EXT_PHY (1 << 8) +#define USBIF_00_CFG_EXT_ADP (1 << 9) +#define USBIF_00_CFG_EXT_OTG (1 << 10) +#define USBIF_00_CFG_EXT_RID (1 << 11) +#define USBIF_00_CFG_DR_PLL (1 << 16) +#define USBIF_00_CFG_DR_SUSPEND (1 << 17) +#define USBIF_00_CFG_REG_PLL (1 << 24) +#define USBIF_00_CFG_REG_SUSPEND (1 << 25) + +// USBIF_04 +#define USBIF_04_CFG_MODE_PLLEN_SHIFT 4 +#define USBIF_04_CFG_MODE_PLLEN_MASK (0x3 << USBIF_04_CFG_MODE_PLLEN_SHIFT) +#define USBIF_04_CFG_MODE_PLLEN(n) BITFIELD_VAL(USBIF_04_CFG_MODE_PLLEN, n) +#define USBIF_04_CFG_SUSPEND_MODE_SHIFT 6 +#define USBIF_04_CFG_SUSPEND_MODE_MASK (0x3 << USBIF_04_CFG_SUSPEND_MODE_SHIFT) +#define USBIF_04_CFG_SUSPEND_MODE(n) BITFIELD_VAL(USBIF_04_CFG_SUSPEND_MODE, n) +#define USBIF_04_CFG_SLEEP_THSD_SHIFT 8 +#define USBIF_04_CFG_SLEEP_THSD_MASK (0xF << USBIF_04_CFG_SLEEP_THSD_SHIFT) +#define USBIF_04_CFG_SLEEP_THSD(n) BITFIELD_VAL(USBIF_04_CFG_SLEEP_THSD, n) + +// USBIF_08 +#define USBIF_08_CFG_EXTPHY_RXTIMING (1 << 0) +#define USBIF_08_CFG_EXTPHY_TXTIMING (1 << 1) +#define USBIF_08_CFG_PHY_TXTIMING (1 << 2) +#define USBIF_08_CFG_PHY_RXTIMING (1 << 3) +#define USBIF_08_CFG_PHY_RXLSTIMING (1 << 4) +#define USBIF_08_CFG_EN_HOSTDISC (1 << 5) +#define USBIF_08_CFG_MODE_FSRCV (1 << 6) +#define USBIF_08_CFG_PHY_TXOPMODE (1 << 7) +#define USBIF_08_CFG_PHY_TXXCVSEL (1 << 8) +#define USBIF_08_CFG_PHY_TXTERMSEL (1 << 9) +#define USBIF_08_CFG_SEL_HSIC (1 << 10) +#define USBIF_08_CFG_SEL48M (1 << 11) +#define USBIF_08_CFG_POL_SPI_CLK (1 << 12) +#define USBIF_08_CFG_MACPLL_RDY (1 << 13) +#define USBIF_08_CFG_PHY_HOST_MODE (1 << 14) +#define USBIF_08_CFG_SOFT_RESETN_PHY (1 << 15) + +// USBIF_0C +#define USBIF_0C_PLL_EN_MSK (1 << 0) +#define USBIF_0C_D1_DEV_HIRD_VALID_MSK (1 << 1) +#define USBIF_0C_SOF_TOGGLE_OUT_MSK (1 << 2) +#define USBIF_0C_SOF_SEND_MSK (1 << 3) +#define USBIF_0C_CHEP_LAST_TRANS_MSK (1 << 4) +#define USBIF_0C_ID_DIG_MSK (1 << 5) +#define USBIF_0C_ENABLE_ALL_MSK (1 << 6) + +// USBIF_10 +#define USBIF_10_PLL_EN_RIS (1 << 0) +#define USBIF_10_D1_DEV_HIRD_VALID_RIS (1 << 1) +#define USBIF_10_SOF_TOGGLE_OUT_RIS (1 << 2) +#define USBIF_10_SOF_SEND_RIS (1 << 3) +#define USBIF_10_CHEP_LAST_TRANS_RIS (1 << 4) +#define USBIF_10_ID_DIG_RIS (1 << 5) + +// USBIF_14 +#define USBIF_14_PLL_EN_MIS (1 << 0) +#define USBIF_14_D1_DEV_HIRD_VALID_MIS (1 << 1) +#define USBIF_14_SOF_TOGGLE_OUT_MIS (1 << 2) +#define USBIF_14_SOF_SEND_MIS (1 << 3) +#define USBIF_14_CHEP_LAST_TRANS_MIS (1 << 4) +#define USBIF_14_ID_DIG_MIS (1 << 5) + +// USBIF_18 +#define USBIF_18_LAST_DEV_HIRD_RCVD_SHIFT 0 +#define USBIF_18_LAST_DEV_HIRD_RCVD_MASK (0xF << USBIF_18_LAST_DEV_HIRD_RCVD_SHIFT) +#define USBIF_18_LAST_DEV_HIRD_RCVD(n) BITFIELD_VAL(USBIF_18_LAST_DEV_HIRD_RCVD, n) +#define USBIF_18_LAST_CHEP_NUMBER_SHIFT 4 +#define USBIF_18_LAST_CHEP_NUMBER_MASK (0xF << USBIF_18_LAST_CHEP_NUMBER_SHIFT) +#define USBIF_18_LAST_CHEP_NUMBER(n) BITFIELD_VAL(USBIF_18_LAST_CHEP_NUMBER, n) +#define USBIF_18_DEV_HIRD_RCVD_SHIFT 8 +#define USBIF_18_DEV_HIRD_RCVD_MASK (0xF << USBIF_18_DEV_HIRD_RCVD_SHIFT) +#define USBIF_18_DEV_HIRD_RCVD(n) BITFIELD_VAL(USBIF_18_DEV_HIRD_RCVD, n) +#define USBIF_18_CHEP_NUMBER_SHIFT 12 +#define USBIF_18_CHEP_NUMBER_MASK (0xF << USBIF_18_CHEP_NUMBER_SHIFT) +#define USBIF_18_CHEP_NUMBER(n) BITFIELD_VAL(USBIF_18_CHEP_NUMBER, n) +#define USBIF_18_CHEP_LAST_TRANS (1 << 16) +#define USBIF_18_SOF_SENT_RCVD_TGL (1 << 17) +#define USBIF_18_SOF_TOGGLE_OUT (1 << 18) +#define USBIF_18_DEV_HIRD_VLD_TGL (1 << 19) +#define USBIF_18_ID_DIG (1 << 20) + +#endif + diff --git a/platform/main/Makefile b/platform/main/Makefile new file mode 100644 index 0000000..6994838 --- /dev/null +++ b/platform/main/Makefile @@ -0,0 +1,252 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +#obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := + +ifeq ($(ROM_BUILD),1) +obj-y += ../../tests/rom/startup_ARMCM.S +else +obj-y += startup_main.S +endif + +ifeq ($(FACTORY_SUITE),1) +obj-y += ../../tests/factory_suite/ +else ifeq ($(RELIABILITY_TEST),1) +obj-y += ../../tests/reliability_test/ +else ifeq ($(NOSTD),1) +obj-y += nostd_main.c +else ifeq ($(NOAPP),1) +obj-y += noapp_main.cpp +else +obj-y += main.cpp +endif + +ifneq ($(filter 1,$(USB_SERIAL_TEST) $(USB_SERIAL_DIRECT_XFER_TEST) $(USB_AUDIO_TEST) $(I2C_TEST) \ + $(AF_TEST) $(VD_TEST) $(CP_TEST) $(TDM_TEST) $(SEC_ENG_TEST) $(A7_DSP_TEST) \ + $(TRANSQ_TEST) $(FLASH_TEST) $(PSRAM_TEST) $(PSRAMUHS_TEST)),) +ccflags-y += -Itests/hwtest -DHWTEST + +ifneq ($(filter 1,$(USB_SERIAL_TEST) $(USB_SERIAL_DIRECT_XFER_TEST) $(USB_AUDIO_TEST)),) +obj-y += ../../tests/hwtest/usb_dev_test.c +ifeq ($(USB_SERIAL_TEST),1) +ccflags-y += -DUSB_SERIAL_TEST +else ifeq ($(USB_SERIAL_DIRECT_XFER_TEST),1) +ccflags-y += -DUSB_SERIAL_DIRECT_XFER_TEST +else +ccflags-y += -DUSB_AUDIO_TEST +endif +endif + +ifneq ($(USB_SERIAL_DIRECT_XFER_SIZE),) +ccflags-y += -DUSB_SERIAL_DIRECT_XFER_SIZE=$(USB_SERIAL_DIRECT_XFER_SIZE) +endif + +ifeq ($(I2C_TEST),1) +obj-y += ../../tests/hwtest/i2c_test.c +ccflags-y += -DI2C_TEST + +ifeq ($(I2C_TEST_DMA_MODE),1) +CFLAGS_i2c_test.o += -DI2C_TEST_DMA_MODE +endif +ifeq ($(I2C_TEST_INT_MODE),1) +CFLAGS_i2c_test.o += -DI2C_TEST_INT_MODE +endif +ifneq ($(I2C_SPEED),) +CFLAGS_i2c_test.o += -DI2C_SPEED=$(I2C_SPEED) +endif +endif # I2C_TEST + +ifeq ($(AF_TEST),1) +obj-y += ../../services/audioflinger/ ../../tests/hwtest/af_test.c +ccflags-y += -Iservices/audioflinger -DAF_TEST + +ifeq ($(AF_INT_CODEC_TEST),1) +obj-y += ../../platform/drivers/codec/ +CFLAGS_af_test.o += -DAF_INT_CODEC_TEST +export AF_DEVICE_INT_CODEC ?= 1 +export AF_DEVICE_I2S ?= 0 +else +export AF_DEVICE_INT_CODEC ?= 0 +export AF_DEVICE_I2S ?= 1 +endif + +ifneq ($(CHAN_NUM_CAPTURE),) +CFLAGS_af_test.o += -DCHAN_NUM_CAPTURE=$(CHAN_NUM_CAPTURE) +endif +ifneq ($(CHAN_SEP_BUF_CAPTURE),) +CFLAGS_af_test.o += -DCHAN_SEP_BUF_CAPTURE=$(CHAN_SEP_BUF_CAPTURE) +endif +ifeq ($(FIXED_BUF_CAPTURE),1) +CFLAGS_af_test.o += -DFIXED_BUF_CAPTURE +endif +endif # AF_TEST + +ifeq ($(VD_TEST),1) +ifneq ($(VOICE_DETECTOR_EN),1) +$(error VOICE_DETECTOR_EN=1 missing when VD_TEST=1) +endif +obj-y += ../../apps/voice_detector/voice_detector.c \ + ../../apps/common/app_utils.c \ + ../../services/audioflinger/ \ + ../../services/audio_dump/ \ + ../../platform/drivers/codec/ +ccflags-y += -DVD_TEST \ + -Iapps/voice_detector \ + -Iapps/common \ + -Iservices/audio_dump/include \ + -Iservices/multimedia/speech/inc +subdir-ccflags-y += -Iservices/audioflinger +endif + +ifeq ($(CP_TEST),1) +obj-y += ../../tests/hwtest/cp_test.c +ccflags-y += -DCP_TEST +endif + +ifeq ($(TDM_TEST),1) +obj-y += ../../tests/hwtest/tdm_test.c +ccflags-y += -DTDM_TEST +ccflags-y += -DCHIP_HAS_I2S=$(CHIP_HAS_I2S) +ifneq ($(CHIP_HAS_TDM),) +ccflags-y += -DCHIP_HAS_TDM=$(CHIP_HAS_TDM) +endif +ifeq ($(LIS25_TEST), 1) +ccflags-y += -DLIS25_TEST +obj-y += ../../tests/codec_vad/lis25ba.c +ccflags-y += -Itests/codec_vad/ +endif + +ifeq ($(TDM_LOOPBACK_TEST), 1) +ccflags-y += -DTDM_LOOPBACK_TEST +endif + +ifeq ($(TDM_PLAYBACK_ONLY_TEST), 1) +ccflags-y += -DTDM_PLAYBACK_ONLY_TEST +endif + +endif #TDM_TEST + +ifeq ($(SEC_ENG_TEST),1) +obj-y += ../../tests/hwtest/sec_eng_test.c ../../utils/hexdump/ +ccflags-y += -DSEC_ENG_TEST -Iutils/hexdump +ifneq ($(filter 1,$(AES_LARGE_DATA) $(HASH_LARGE_DATA) $(HMAC_LARGE_DATA)),) +obj-y += ../../tests/hwtest/asm_test.S +asflags-y += -Itests/hwtest +ifeq ($(AES_LARGE_DATA),1) +asflags-y += -DAES_LARGE_DATA +ccflags-y += -DAES_LARGE_DATA +endif +ifeq ($(HASH_LARGE_DATA),1) +asflags-y += -DHASH_LARGE_DATA +ccflags-y += -DHASH_LARGE_DATA +endif +ifeq ($(HMAC_LARGE_DATA),1) +asflags-y += -DHMAC_LARGE_DATA +ccflags-y += -DHMAC_LARGE_DATA +endif +endif +endif + +$(call echo-help,INFO Please make sure DSP bin is up to date: out/$(DSP_BIN_NAME)/$(DSP_BIN_NAME).bin) +ifeq ($(A7_DSP_TEST),1) +obj-y += ../../tests/hwtest/a7_dsp_test.c +obj-y += ../../tests/hwtest/asm_test.S +ccflags-y += -DA7_DSP_TEST +AFLAGS_asm_test.o += -DA7_DSP_TEST -DDSP_BIN_NAME=$(DSP_BIN_NAME).bin -Iout/$(T) +DSP_BIN_NAME ?= hwtest_a7_dsp +$(obj)/../../tests/hwtest/asm_test.o : out/$(T)/$(DSP_BIN_NAME).bin +out/$(T)/$(DSP_BIN_NAME).bin : $(srctree)/out/$(DSP_BIN_NAME)/$(DSP_BIN_NAME).bin + $(call CMDCPFILE,$(srctree)/out/$(DSP_BIN_NAME)/$(DSP_BIN_NAME).bin,$(srctree)/$@) + $(call CMDCPFILE,$(srctree)/out/$(DSP_BIN_NAME)/$(DSP_BIN_NAME).elf,$(srctree)/$(@:.bin=.elf)) + $(call CMDCPFILE,$(srctree)/out/$(DSP_BIN_NAME)/$(DSP_BIN_NAME).map,$(srctree)/$(@:.bin=.map)) + $(call CMDCPFILE,$(srctree)/out/$(DSP_BIN_NAME)/$(DSP_BIN_NAME).lst,$(srctree)/$(@:.bin=.lst)) +$(srctree)/out/$(DSP_BIN_NAME)/$(DSP_BIN_NAME).bin : FORCE + $(call echo-help,) + $(call echo-help,INFO Please make sure DSP bin is up to date: out/$(DSP_BIN_NAME)/$(DSP_BIN_NAME).bin) +# We cannot build $(DSP_BIN_NAME) automatically here, because the env inherited by sub-make cannot be cleaned: +# E.g., KBUILD_SRC, TC, CHIP_HAS_CP, ... + $(call echo-help,) +endif #A7_DSP_TEST + +ifeq ($(TRANSQ_TEST),1) +obj-y += ../../tests/hwtest/transq_test.c +ccflags-y += -DTRANSQ_TEST +ifneq ($(RX_ROLE),) +CFLAGS_transq_test.o += -DRX_ROLE +endif +ifneq ($(TRANSQ_ID),) +CFLAGS_transq_test.o += -DTRANSQ_ID=$(TRANSQ_ID) +endif +endif #TRANSQ_TEST + +ifeq ($(PSRAM_TEST),1) +obj-y += ../../tests/hwtest/psram_test.c +ccflags-y += -DPSRAM_TEST -DCHIP_PSRAM_CTRL_VER=$(CHIP_PSRAM_CTRL_VER) +endif #PSRAM_TEST + +ifeq ($(PSRAMUHS_TEST),1) +obj-y += ../../tests/hwtest/psram_test.c +ccflags-y += -DPSRAMUHS_TEST +endif #PSRAMUHS_TEST + +endif # hwtest cases + + +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +obj-y += ../../utils/hwtimer_list/ + +ccflags-y += \ + -Iutils/hwtimer_list \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/security_engine \ + -Iplatform/drivers/usb/usb_dev/inc \ + -Iapps/main \ + -Iapps/factory \ + -Iutils/list \ + -Iapps/audioplayers \ + -Iservices/bt_app \ + -Iapps/common \ + -Iservices/norflash_api \ + -Iservices/nv_section/log_section + +ifneq ($(FLASH_FILL),) +ccflags-y += -DFLASH_FILL=$(FLASH_FILL) +endif + +ifneq ($(DEBUG_PORT),) +ccflags-y += -DDEBUG_PORT=$(DEBUG_PORT) +endif + +ifneq ($(FLASH_SIZE),) +ccflags-y += -DFLASH_SIZE=$(FLASH_SIZE) +endif + +ifeq ($(ROM_UTILS_ON),1) +ccflags-y += -DROM_UTILS_ON +endif + +ifeq ($(NO_PMU),1) +ccflags-y += -DNO_PMU +endif + +ifeq ($(NO_TIMER),1) +ccflags-y += -DNO_TIMER +endif + +ifeq ($(SLEEP_TEST),1) +ccflags-y += -DSLEEP_TEST +endif + +ifeq ($(RTOS),1) +ifeq ($(KERNEL),RTX) +ccflags-y += -Irtos/rtx/TARGET_CORTEX_M +endif +endif + +ifeq ($(DEBUG_MODE_USB_DOWNLOAD),1) +ccflags-y += -DDEBUG_MODE_USB_DOWNLOAD +endif + diff --git a/platform/main/main.cpp b/platform/main/main.cpp new file mode 100644 index 0000000..e2d3561 --- /dev/null +++ b/platform/main/main.cpp @@ -0,0 +1,414 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include "analog.h" +#include "apps.h" +#include "app_bt_stream.h" +#include "cmsis.h" +#include "hal_bootmode.h" +#include "hal_cmu.h" +#include "hal_dma.h" +#include "hal_gpio.h" +#include "hal_iomux.h" +#include "hal_location.h" +#include "hal_norflash.h" +#include "hal_sleep.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_wdt.h" +#include "hwtimer_list.h" +#include "mpu.h" +#include "norflash_api.h" +#include "pmu.h" +#include "stdlib.h" +#include "tgt_hardware.h" +#include "app_utils.h" + +#ifdef RTOS +#include "cmsis_os.h" +#include "app_factory.h" +#endif +#ifdef CORE_DUMP_TO_FLASH +#include "coredump_section.h" +#endif + +extern "C" void log_dump_init(void); +extern "C" void crash_dump_init(void); + +#ifdef FIRMWARE_REV +#define SYS_STORE_FW_VER(x) \ + if(fw_rev_##x) { \ + *fw_rev_##x = fw.softwareRevByte##x; \ + } + +typedef struct +{ + uint8_t softwareRevByte0; + uint8_t softwareRevByte1; + uint8_t softwareRevByte2; + uint8_t softwareRevByte3; +} FIRMWARE_REV_INFO_T; + +static FIRMWARE_REV_INFO_T fwRevInfoInFlash __attribute((section(".fw_rev"))) = {0, 0, 1, 0}; +FIRMWARE_REV_INFO_T fwRevInfoInRam; + +extern "C" void system_get_info(uint8_t *fw_rev_0, uint8_t *fw_rev_1, + uint8_t *fw_rev_2, uint8_t *fw_rev_3) +{ + FIRMWARE_REV_INFO_T fw = fwRevInfoInFlash; + + SYS_STORE_FW_VER(0); + SYS_STORE_FW_VER(1); + SYS_STORE_FW_VER(2); + SYS_STORE_FW_VER(3); +} +#endif + +#if defined(_AUTO_TEST_) +static uint8_t fwversion[4] = {0,0,1,0}; + +void system_get_fwversion(uint8_t *fw_rev_0, uint8_t *fw_rev_1, + uint8_t *fw_rev_2, uint8_t *fw_rev_3) +{ + *fw_rev_0 = fwversion[0]; + *fw_rev_1 = fwversion[1]; + *fw_rev_2 = fwversion[2]; + *fw_rev_3 = fwversion[3]; +} +#endif + + +#define system_shutdown_wdt_config(seconds) \ + do{ \ + hal_wdt_stop(HAL_WDT_ID_0); \ + hal_wdt_set_irq_callback(HAL_WDT_ID_0, NULL); \ + hal_wdt_set_timeout(HAL_WDT_ID_0, seconds); \ + hal_wdt_start(HAL_WDT_ID_0); \ + hal_sleep_set_deep_sleep_hook(HAL_DEEP_SLEEP_HOOK_USER_WDT, NULL); \ + }while(0) + +static osThreadId main_thread_tid = NULL; + +extern "C" int system_shutdown(void) +{ + TRACE(0,"system_shutdown!!"); + osThreadSetPriority(main_thread_tid, osPriorityRealtime); + osSignalSet(main_thread_tid, 0x4); + return 0; +} + +int system_reset(void) +{ + osThreadSetPriority(main_thread_tid, osPriorityRealtime); + osSignalSet(main_thread_tid, 0x8); + return 0; +} + +int signal_send_to_main_thread(uint32_t signals) +{ + osSignalSet(main_thread_tid, signals); + return 0; +} + +int tgt_hardware_setup(void) +{ +#ifdef __APP_USE_LED_INDICATE_IBRT_STATUS__ + for (uint8_t i=0;i<3;i++){ + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&cfg_ibrt_indication_pinmux_pwl[i], 1); + if(i==0) + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)cfg_ibrt_indication_pinmux_pwl[i].pin, HAL_GPIO_DIR_OUT, 0); + else + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)cfg_ibrt_indication_pinmux_pwl[i].pin, HAL_GPIO_DIR_OUT, 1); + } +#endif + + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)cfg_hw_pinmux_pwl, sizeof(cfg_hw_pinmux_pwl)/sizeof(struct HAL_IOMUX_PIN_FUNCTION_MAP)); + if (app_battery_ext_charger_indicator_cfg.pin != HAL_IOMUX_PIN_NUM){ + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&app_battery_ext_charger_indicator_cfg, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)app_battery_ext_charger_indicator_cfg.pin, HAL_GPIO_DIR_IN, 1); + } + return 0; +} + +#if defined(ROM_UTILS_ON) +void rom_utils_init(void); +#endif + +#ifdef FPGA +uint32_t a2dp_audio_more_data(uint8_t *buf, uint32_t len); +uint32_t a2dp_audio_init(void); +extern "C" void app_audio_manager_open(void); +extern "C" void app_bt_init(void); +extern "C" uint32_t hal_iomux_init(const struct HAL_IOMUX_PIN_FUNCTION_MAP *map, uint32_t count); +void app_overlay_open(void); + +extern "C" void BesbtInit(void); +extern "C" int app_os_init(void); +extern "C" uint32_t af_open(void); +extern "C" int list_init(void); +extern "C" void app_audio_open(void); + + +volatile uint32_t ddddd = 0; + +#if defined(AAC_TEST) +#include "app_overlay.h" +int decode_aac_frame_test(unsigned char *pcm_buffer, unsigned int pcm_len); +#define AAC_TEST_PCM_BUFF_LEN (4096) +unsigned char aac_test_pcm_buff[AAC_TEST_PCM_BUFF_LEN]; +#endif + +#endif + +#if defined(_AUTO_TEST_) +extern int32_t at_Init(void); +#endif + +#ifdef DEBUG_MODE_USB_DOWNLOAD +static void process_usb_download_mode(void) +{ + if (pmu_charger_get_status() == PMU_CHARGER_PLUGIN && hal_pwrkey_pressed()) { + hal_sw_bootmode_set(HAL_SW_BOOTMODE_FORCE_USB_DLD); + hal_cmu_sys_reboot(); + } +} +#endif +int main(void) +{ + uint8_t sys_case = 0; + int ret = 0; +#ifdef __WATCHER_DOG_RESET__ +#if !defined(BLE_ONLY_ENABLED) + app_wdt_open(15); +#else + app_wdt_open(30); +#endif +#endif + +#ifdef __FACTORY_MODE_SUPPORT__ + uint32_t bootmode = hal_sw_bootmode_get(); +#endif + +#ifdef DEBUG_MODE_USB_DOWNLOAD + process_usb_download_mode(); +#endif + + tgt_hardware_setup(); + +#if defined(ROM_UTILS_ON) + rom_utils_init(); +#endif + + main_thread_tid = osThreadGetId(); + + hwtimer_init(); + + hal_dma_set_delay_func((HAL_DMA_DELAY_FUNC)osDelay); + hal_audma_open(); + hal_gpdma_open(); + norflash_api_init(); +#if defined(DUMP_LOG_ENABLE) + log_dump_init(); +#endif +#if defined(DUMP_CRASH_ENABLE) + crash_dump_init(); +#endif +#ifdef CORE_DUMP_TO_FLASH + coredump_to_flash_init(); +#endif + +#ifdef DEBUG +#if (DEBUG_PORT == 1) + hal_iomux_set_uart0(); +#ifdef __FACTORY_MODE_SUPPORT__ + if (!(bootmode & HAL_SW_BOOTMODE_FACTORY)) +#endif + { + hal_trace_open(HAL_TRACE_TRANSPORT_UART0); + } +#endif + +#if (DEBUG_PORT == 2) +#ifdef __FACTORY_MODE_SUPPORT__ + if (!(bootmode & HAL_SW_BOOTMODE_FACTORY)) +#endif + { + hal_iomux_set_analog_i2c(); + } + hal_iomux_set_uart1(); + hal_trace_open(HAL_TRACE_TRANSPORT_UART1); +#endif + hal_sleep_start_stats(10000, 10000); + hal_trace_set_log_level(LOG_LEVEL_DEBUG); +#endif + + hal_iomux_ispi_access_init(); + +#ifndef FPGA + uint8_t flash_id[HAL_NORFLASH_DEVICE_ID_LEN]; + hal_norflash_get_id(HAL_NORFLASH_ID_0, flash_id, ARRAY_SIZE(flash_id)); + TRACE(3,"FLASH_ID: %02X-%02X-%02X", flash_id[0], flash_id[1], flash_id[2]); + ASSERT(hal_norflash_opened(HAL_NORFLASH_ID_0), "Failed to init flash: %d", hal_norflash_get_open_state(HAL_NORFLASH_ID_0)); + + // Software will load the factory data and user data from the bottom TWO sectors from the flash, + // the FLASH_SIZE defined is the common.mk must be equal or greater than the actual chip flash size, + // otherwise the ota will load the wrong information + uint32_t actualFlashSize = hal_norflash_get_flash_total_size(HAL_NORFLASH_ID_0); + if (FLASH_SIZE > actualFlashSize) + { + TRACE_IMM(0,"Wrong FLASH_SIZE defined in target.mk!"); + TRACE_IMM(2,"FLASH_SIZE is defined as 0x%x while the actual chip flash size is 0x%x!", FLASH_SIZE, actualFlashSize); + TRACE_IMM(1,"Please change the FLASH_SIZE in common.mk to 0x%x to enable the OTA feature.", actualFlashSize); + ASSERT(false, " "); + } +#endif + + pmu_open(); + + analog_open(); + + ret = mpu_open(); + if (ret == 0) { + mpu_setup(); + } + + srand(hal_sys_timer_get()); + +#if defined(_AUTO_TEST_) + at_Init(); +#endif + +#ifdef VOICE_DATAPATH + app_audio_buffer_check(); +#endif + +#ifdef FPGA + + TRACE(0,"\n[best of best of best...]\n"); + TRACE(1,"\n[ps: w4 0x%x,2]", &ddddd); + + ddddd = 1; + while (ddddd == 1); + TRACE(0,"bt start"); + + list_init(); + + app_os_init(); + app_bt_init(); + a2dp_audio_init(); + + af_open(); + app_audio_open(); + app_audio_manager_open(); + app_overlay_open(); + +#if defined(AAC_TEST) + app_overlay_select(APP_OVERLAY_A2DP_AAC); + decode_aac_frame_test(aac_test_pcm_buff, AAC_TEST_PCM_BUFF_LEN); +#endif + + SAFE_PROGRAM_STOP(); + +#else // !FPGA + +#ifdef __FACTORY_MODE_SUPPORT__ + if (bootmode & HAL_SW_BOOTMODE_FACTORY){ + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_FACTORY); + ret = app_factorymode_init(bootmode); + + }else if(bootmode & HAL_SW_BOOTMODE_CALIB){ + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_CALIB); + ret = app_factorymode_calib_only(); + } +#ifdef __USB_COMM__ + else if(bootmode & HAL_SW_BOOTMODE_CDC_COMM) + { + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_CDC_COMM); + ret = app_factorymode_cdc_comm(); + } +#endif + else +#endif + { +#ifdef FIRMWARE_REV + fwRevInfoInRam = fwRevInfoInFlash; + TRACE(4,"The Firmware rev is %d.%d.%d.%d", + fwRevInfoInRam.softwareRevByte0, + fwRevInfoInRam.softwareRevByte1, + fwRevInfoInRam.softwareRevByte2, + fwRevInfoInRam.softwareRevByte3); +#endif + ret = app_init(); + } + if (!ret){ +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("BT Init ok."); +#endif + while(1) + { + osEvent evt; +#ifndef __POWERKEY_CTRL_ONOFF_ONLY__ + osSignalClear (main_thread_tid, 0x0f); +#endif + //wait any signal + evt = osSignalWait(0x0, osWaitForever); + + //get role from signal value + if(evt.status == osEventSignal) + { + if(evt.value.signals & 0x04) + { + sys_case = 1; + break; + } + else if(evt.value.signals & 0x08) + { + sys_case = 2; + break; + } + }else{ + sys_case = 1; + break; + } + } + } +#ifdef __WATCHER_DOG_RESET__ + system_shutdown_wdt_config(10); +#endif + app_deinit(ret); + TRACE(1,"byebye~~~ %d\n", sys_case); + if ((sys_case == 1)||(sys_case == 0)){ + TRACE(0,"shutdown\n"); +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("System shutdown."); + osDelay(50); +#endif + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_REBOOT); + pmu_shutdown(); + }else if (sys_case == 2){ + TRACE(0,"reset\n"); +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("System reset."); + osDelay(50); +#endif + hal_cmu_sys_reboot(); + } + +#endif // !FPGA + + return 0; +} + diff --git a/platform/main/noapp_main.cpp b/platform/main/noapp_main.cpp new file mode 100644 index 0000000..205e950 --- /dev/null +++ b/platform/main/noapp_main.cpp @@ -0,0 +1,213 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_cmu.h" +#include "hal_timer.h" +#include "hal_dma.h" +#include "hal_trace.h" +#include "hal_iomux.h" +#include "hal_bootmode.h" +#include "hal_norflash.h" +#include "hal_sleep.h" +#include "hal_sysfreq.h" +#include "cmsis.h" +#include "hwtimer_list.h" +#include "main_entry.h" +#include "pmu.h" +#include "analog.h" + +#ifdef RTOS +#include "cmsis_os.h" +#ifdef KERNEL_RTX +#include "rt_Time.h" +#endif +#endif + +#ifdef HWTEST +#include "hwtest.h" +#ifdef VD_TEST +#include "voice_detector.h" +#endif +#endif + +#ifdef __cplusplus +#define EXTERN_C extern "C" +#else +#define EXTERN_C extern +#endif + +#define TIMER_IRQ_PERIOD_MS 2500 +#define DELAY_PERIOD_MS 4000 + +#ifndef FLASH_FILL +#define FLASH_FILL 1 +#endif + +#ifdef KERNEL_RTX +#define OS_TIME_STR "[%2u/%u]" +#define OS_CUR_TIME , SysTick->VAL, os_time +#else +#define OS_TIME_STR +#define OS_CUR_TIME +#endif + +#if defined(MS_TIME) +#define TIME_STR "[%u]" OS_TIME_STR +#define CUR_TIME TICKS_TO_MS(hal_sys_timer_get()) OS_CUR_TIME +#elif defined(RAW_TIME) +#define TIME_STR "[0x%X]" OS_TIME_STR +#define CUR_TIME hal_sys_timer_get() OS_CUR_TIME +#else +#define TIME_STR "[%u/0x%X]" OS_TIME_STR +#define CUR_TIME TICKS_TO_MS(hal_sys_timer_get()), hal_sys_timer_get() OS_CUR_TIME +#endif + +#ifndef NO_TIMER +static HWTIMER_ID hw_timer = NULL; + +static void timer_handler(void *param) +{ + TRACE(1,TIME_STR " Timer handler: %u", CUR_TIME, (uint32_t)param); + hwtimer_start(hw_timer, MS_TO_TICKS(TIMER_IRQ_PERIOD_MS)); + TRACE(1,TIME_STR " Start timer %u ms", CUR_TIME, TIMER_IRQ_PERIOD_MS); +} +#endif + +const static unsigned char bytes[FLASH_FILL] = { 0x1, }; + +// GDB can set a breakpoint on the main function only if it is +// declared as below, when linking with STD libraries. + +int MAIN_ENTRY(void) +{ + int POSSIBLY_UNUSED ret; + + hwtimer_init(); + hal_audma_open(); + hal_gpdma_open(); +#ifdef DEBUG +#if (DEBUG_PORT == 3) + hal_iomux_set_analog_i2c(); + hal_iomux_set_uart2(); + hal_trace_open(HAL_TRACE_TRANSPORT_UART2); +#elif (DEBUG_PORT == 2) + hal_iomux_set_analog_i2c(); + hal_iomux_set_uart1(); + hal_trace_open(HAL_TRACE_TRANSPORT_UART1); +#else + hal_iomux_set_uart0(); + hal_trace_open(HAL_TRACE_TRANSPORT_UART0); +#endif +#endif + +#if !defined(SIMU) && !defined(FPGA) + uint8_t flash_id[HAL_NORFLASH_DEVICE_ID_LEN]; + hal_norflash_get_id(HAL_NORFLASH_ID_0, flash_id, ARRAY_SIZE(flash_id)); + TRACE(3,"FLASH_ID: %02X-%02X-%02X", flash_id[0], flash_id[1], flash_id[2]); +#endif + + TRACE(1,TIME_STR " main started: filled@0x%08x", CUR_TIME, (uint32_t)bytes); + +#ifndef NO_PMU + ret = pmu_open(); + ASSERT(ret == 0, "Failed to open pmu"); +#endif + analog_open(); + + hal_cmu_simu_pass(); + +#ifdef SIMU + hal_sw_bootmode_set(HAL_SW_BOOTMODE_FLASH_BOOT); + hal_cmu_sys_reboot(); +#else +#ifdef SLEEP_TEST + hal_sleep_start_stats(10000, 10000); + hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_32K); +#else + hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_104M); +#endif + TRACE(1,"CPU freq: %u", hal_sys_timer_calc_cpu_freq(5, 0)); +#endif + +#ifdef HWTEST + +#ifdef USB_SERIAL_TEST + pmu_usb_config(PMU_USB_CONFIG_TYPE_DEVICE); + usb_serial_test(); +#endif +#ifdef USB_SERIAL_DIRECT_XFER_TEST + pmu_usb_config(PMU_USB_CONFIG_TYPE_DEVICE); + usb_serial_direct_xfer_test(); +#endif +#ifdef USB_AUDIO_TEST + pmu_usb_config(PMU_USB_CONFIG_TYPE_DEVICE); + usb_audio_test(); +#endif +#ifdef I2C_TEST + i2c_test(); +#endif +#ifdef AF_TEST + af_test(); +#endif +#ifdef VD_TEST + voice_detector_test(); +#endif +#ifdef CP_TEST + cp_test(); +#endif +#ifdef SEC_ENG_TEST + sec_eng_test(); +#endif +#ifdef TDM_TEST + tdm_test(); +#endif +#ifdef A7_DSP_TEST + a7_dsp_test(); +#endif +#ifdef TRANSQ_TEST + transq_test(); +#endif +#ifdef PSRAM_TEST + psram_test(); +#endif +#ifdef PSRAMUHS_TEST + psramuhs_test(); +#endif + + SAFE_PROGRAM_STOP(); + +#endif // HWTEST + +#ifdef NO_TIMER + TRACE(0,TIME_STR " Enter sleep ...", CUR_TIME); +#else + hw_timer = hwtimer_alloc(timer_handler, 0); + hwtimer_start(hw_timer, MS_TO_TICKS(TIMER_IRQ_PERIOD_MS)); + TRACE(1,TIME_STR " Start timer %u ms", CUR_TIME, TIMER_IRQ_PERIOD_MS); +#endif + + while (1) { +#if defined(SLEEP_TEST) && !defined(RTOS) + hal_sleep_enter_sleep(); +#else + osDelay(DELAY_PERIOD_MS); + TRACE(1,TIME_STR " Delay %u ms done", CUR_TIME, DELAY_PERIOD_MS); +#endif + } + + SAFE_PROGRAM_STOP(); + return 0; +} + diff --git a/platform/main/nostd_main.c b/platform/main/nostd_main.c new file mode 100644 index 0000000..5fa28fc --- /dev/null +++ b/platform/main/nostd_main.c @@ -0,0 +1,18 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "noapp_main.cpp" + diff --git a/platform/main/startup_main.S b/platform/main/startup_main.S new file mode 100644 index 0000000..3f3db38 --- /dev/null +++ b/platform/main/startup_main.S @@ -0,0 +1,196 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __ARM_ARCH_ISA_ARM + +#if defined(NOSTD) || defined(__ARMCC_VERSION) +#define __STARTUP_CLEAR_BSS +#endif + +#ifdef __ARMCC_VERSION +#include "link_sym_armclang.h" +#endif + + .syntax unified + + .section .boot_loader, "ax", %progbits + .thumb + .thumb_func + .align 2 + .globl Boot_Loader + .type Boot_Loader, %function +Boot_Loader: + +#ifdef __ARM_ARCH_8M_MAIN__ + ldr r0, =__StackLimit + msr msplim, r0 +#endif + +#if defined(CHIP_BEST2001) && defined(LARGE_RAM) + ldr r3, =0x4000008c + ldr r0, [r3] + bic.w r0, r0, #0x03f80000 + orr.w r0, r0, #0x00f80000 /*0x1f<<19*/ + str r0, [r3] +#endif + + ldr r3, =__StackTop + msr msp, r3 + + bl NVIC_InitVectors + +#ifndef __NO_BOOT_INIT + bl BootInit +#endif + +#ifdef USER_SECURE_BOOT + bl user_secure_boot_init +#endif + +/* Firstly it copies data from read only memory to RAM. There are two schemes + * to copy. One can copy more than one sections. Another can only copy + * one section. The former scheme needs more instructions and read-only + * data to implement than the latter. + * Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */ + +#ifdef __STARTUP_COPY_MULTIPLE +/* Multiple sections scheme. + * + * Between symbol address __copy_table_start__ and __copy_table_end__, + * there are array of triplets, each of which specify: + * offset 0: LMA of start of a section to copy from + * offset 4: VMA of start of a section to copy to + * offset 8: size of the section to copy. Must be multiply of 4 + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r4, =__copy_table_start__ + ldr r5, =__copy_table_end__ + +.L_loop0: + cmp r4, r5 + bge .L_loop0_done + ldr r1, [r4] + ldr r2, [r4, #4] + ldr r3, [r4, #8] + +.L_loop0_0: + subs r3, #4 + ittt ge + ldrge r0, [r1, r3] + strge r0, [r2, r3] + bge .L_loop0_0 + + adds r4, #12 + b .L_loop0 + +.L_loop0_done: +#else +/* Single section scheme. + * + * The ranges of copy from/to are specified by following symbols + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to + * __data_end__: VMA of end of the section to copy to + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + +.L_loop1: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .L_loop1 +#endif /*__STARTUP_COPY_MULTIPLE */ + +/* This part of work usually is done in C library startup code. Otherwise, + * define this macro to enable it in this startup. + * + * There are two schemes too. One can clear multiple BSS sections. Another + * can only clear one section. The former is more size expensive than the + * latter. + * + * Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former. + * Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later. + */ +#ifdef __STARTUP_CLEAR_BSS_MULTIPLE +/* Multiple sections scheme. + * + * Between symbol address __copy_table_start__ and __copy_table_end__, + * there are array of tuples specifying: + * offset 0: Start of a BSS section + * offset 4: Size of this BSS section. Must be multiply of 4 + */ + ldr r3, =__zero_table_start__ + ldr r4, =__zero_table_end__ + +.L_loop2: + cmp r3, r4 + bge .L_loop2_done + ldr r1, [r3] + ldr r2, [r3, #4] + movs r0, 0 + +.L_loop2_0: + subs r2, #4 + itt ge + strge r0, [r1, r2] + bge .L_loop2_0 + + adds r3, #8 + b .L_loop2 +.L_loop2_done: +#elif defined (__STARTUP_CLEAR_BSS) +/* Single BSS section scheme. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * Both addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 +.L_loop3: + cmp r1, r2 + itt lt + strlt r0, [r1], #4 + blt .L_loop3 +#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */ + +#ifndef __NO_SYSTEM_INIT + bl SystemInit +#endif + +#if defined(__ARMCC_VERSION) && !defined(NOSTD) + bl __rt_entry +#else + bl _start +#endif + + .pool + .size Boot_Loader, . - Boot_Loader + + .end + +#endif + diff --git a/rtos/Makefile b/rtos/Makefile new file mode 100644 index 0000000..2f9545f --- /dev/null +++ b/rtos/Makefile @@ -0,0 +1,16 @@ +ifeq ($(KERNEL),RTX) +rtos_lib-y := rtx/TARGET_CORTEX_M/ +else ifeq ($(KERNEL),RTX5) +rtos_lib-y := rtx5/ +else ifeq ($(KERNEL),FREERTOS) +rtos_lib-y := freertos/ +endif + +ifeq ($(MBED),1) +rtos_lib-y += rtos/ +endif + +obj-y := rtos_lib.o + +subdir-ccflags-y += -Iplatform/cmsis/inc -Iplatform/hal -Iutils/hwtimer_list + diff --git a/rtos/rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/HAL_CM0.S b/rtos/rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/HAL_CM0.S new file mode 100644 index 0000000..9acc600 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/HAL_CM0.S @@ -0,0 +1,329 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.S + * Purpose: Hardware Abstraction Layer for ARM7TDMI + * Rev.: V1.0 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + .file "HAL_CM0.S" + .syntax unified + + .equ TCB_TSTACK, 40 + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + .arm + + .section ".text" + .align 2 + +/*-------------------------- Save Context --------------------------------*/ +/* MUST be called the first */ +.macro SaveContext + + /* Push R0 as we are going to use the register. */ \ + STMDB SP!, {R0} + + /* Set R0 to SP(user) */ + STMDB SP,{SP}^ + NOP + SUB SP, SP, #4 + LDMIA SP!,{R0} + + /* Push the LR return address onto the user stack. */ + STMDB R0!, {LR} + + /* Now we have saved LR we can use it instead of R0. */ + MOV LR, R0 + + /* Pop R0 so we can save it onto the system mode stack. */ + LDMIA SP!, {R0} + + /* Push all the system mode registers onto the task stack. */ + STMDB LR,{R0-R12,LR}^ /* LR can not be changed because user's LR is used*/ + NOP /* pass 1 cycle before changing LR */ + SUB LR, LR, #14*4 /* change LR now -15 dwords (R0-R14)*/ + + /* Push the SPSR onto the task stack. */ + MRS R0, SPSR + STMDB LR!, {R0} + + /* Store the new top of stack for the task. */ + LDR R0,=os_tsk + LDR R0, [R0] /* R0 = (tcb) os_tsk.run */ + STR LR, [R0, TCB_TSTACK] /* tcb.tsk_stack = SP(user) */ +.endm + +/*-------------------------- Restore Context --------------------------------*/ + .type RestoreContext, %function + .global RestoreContext +RestoreContext: + .fnstart + .cantunwind + /* Set the LR to the task stack. */ + LDR R0,=os_tsk + LDR R1, [R0, 4] /* R1 = (tcb) os_tsk.new */ + STR R1, [R0] /* os_tsk.run = os_tsk_newk */ + LDR LR, [R1, TCB_TSTACK] /* LR = tcb.tsk_stack */ + + /* Get the SPSR from the stack. */ + LDMFD LR!, {R0} /* SPSR */ + MSR SPSR, R0 + + /* Restore all system mode registers for the task. */ + LDMFD LR, {R0-R12,LR}^ + NOP + + ADD LR, LR, 15*4 /* increase starck pointer */ + /* Set SP(user) to LR */ + STMDB SP!,{LR} + LDMIA SP,{SP}^ + NOP + ADD SP, SP, #4 + + /* Restore the return address. */ + LDR LR, [LR,#-4] /* last dword is task's PC register */ + + /* And return - correcting the offset in the LR to obtain the */ + /* correct address. */ + SUBS PC, LR, #4 + +/*-------------------------- End --------------------------------*/ + .fnend + .size RestoreContext, .-RestoreContext + + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +# void rt_set_PSP (U32 stack); + + .type rt_set_PSP, %function + .global rt_set_PSP +rt_set_PSP: + .fnstart + .cantunwind + + MOV SP,R0 + BX LR + + .fnend + .size rt_set_PSP, .-rt_set_PSP + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +# U32 rt_get_PSP (void); + + .type rt_get_PSP, %function + .global rt_get_PSP +rt_get_PSP: + .fnstart + .cantunwind + + MOV R0,SP + BX LR + + .fnend + .size rt_get_PSP, .-rt_get_PSP + + + +/*--------------------------- _alloc_box ------------------------------------*/ + +# void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .type _alloc_box, %function + .global _alloc_box +_alloc_box: + .fnstart + .cantunwind + + LDR R3,=rt_alloc_box + MOV R12, R3 + MRS R3, CPSR + AND R3, 0x1F + CMP R3, 0x12 /* IRQ mode*/ + BNE PrivilegedA + CMP R3, 0x1F /* System mode*/ + BNE PrivilegedA + SVC 0 + BX LR +PrivilegedA: + BX R12 + + .fnend + .size _alloc_box, .-_alloc_box + + +/*--------------------------- _free_box -------------------------------------*/ + +# int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .type _free_box, %function + .global _free_box +_free_box: + .fnstart + .cantunwind + + LDR R3,=rt_free_box + MOV R12, R3 + MRS R3, CPSR + AND R3, 0x1F + CMP R3, 0x12 /* IRQ mode*/ + BNE PrivilegedA + CMP R3, 0x1F /* System mode*/ + BNE PrivilegedA + SVC 0 + BX LR +PrivilegedF: + BX R12 + + .fnend + .size _free_box, .-_free_box + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +# void SVC_Handler (void); + + .type SVC_Handler, %function + .global SVC_Handler +SVC_Handler: + .fnstart + .cantunwind + /* Within an IRQ ISR the link register has an offset from the true return + address, but an SWI ISR does not. Add the offset manually so the same + ISR return code can be used in both cases. */ + + STMFD SP!, {R0,LR} /* Store registers. */ + ADD LR, LR, #4 /* Align LR with IRQ handler */ + SaveContext + MOV R11, LR /* Save Task Stack Pointer */ + LDMFD SP!, {R0,LR} /* Restore registers and return. */ + STMFD SP!, {R11} /* Save Task Stack Pointer */ + + LDR R5, [LR,#-4] /* Calculate address of SWI instruction and load it into r5. */ + BIC R5, R5,#0xff000000 /* Mask off top 8 bits of instruction to give SWI number. */ + + CMP R5, #0 + BNE SVC_User /* User SVC Number > 0 */ + MOV LR, PC /* set LR to return address */ + BX R12 /* Call SVC Function */ + + LDMFD SP!, {R11} /* Load Task Stack Pointer */ + STMIB R11!, {R0-R3} /* Store return values to Task stack */ + +SVC_Exit: + B RestoreContext /* return to the task */ + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + LDR R6,=SVC_Count + LDR R6,[R6] + CMP R5,R6 + LDMFDHI SP!, {R11} + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table - 4 + LSLS R5,R5,#2 + LDR R4,[R4,R5] /* Load SVC Function Address */ + /* R0-R3,R12 are unchanged */ + MOV LR, PC /* set LR to return address */ + BX R4 /* Call SVC Function */ + + LDMFD SP!, {R11} /* Load Task Stack Pointer */ + BEQ SVC_Exit /* no need in return values */ + + STMIB R11!, {R0-R3} /* Store return values to Task stack */ +SVC_Done: + B RestoreContext /* return to the task */ + + .fnend + .size SVC_Handler, .-SVC_Handler + + +/*-------------------------- IRQ_Handler ---------------------------------*/ + +# void IRQ_Handler (void); + + .type IRQ_Handler, %function + .global IRQ_Handler +IRQ_Handler: + .fnstart + .cantunwind + + SaveContext + + MOV R0, #0xFFFFFF00 + LDR R0, [R0] /* Load address of raised IRQ handler*/ + + MOV LR, PC + BX R0 + + MOV R0, #0xFFFFFF00 + STR R0, [R0] /* Clear interrupt */ + + B RestoreContext + + .fnend + .size IRQ_Handler, .-IRQ_Handler + +/*-------------------------- SysTick_Handler --------------------------------*/ + +# void SysTick_Handler (void); + + .type SysTick_Handler, %function + .global SysTick_Handler +SysTick_Handler: + .fnstart + .cantunwind + + PUSH {LR} + BL rt_systick + POP {LR} + BX LR /* return to IRQ handler */ + +/*-------------------------- End --------------------------------*/ + .fnend + .size SysTick_Handler, .-SysTick_Handler + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + +.end diff --git a/rtos/rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/SVC_Table.S b/rtos/rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/SVC_Table.S new file mode 100644 index 0000000..1942f4c --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/ARM7/TOOLCHAIN_GCC/SVC_Table.S @@ -0,0 +1,56 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + .file "SVC_Table.S" + + + .section ".svc_table" + + .global SVC_Table +SVC_Table: +/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ +# .long __SVC_1 /* user SVC function */ +SVC_End: + + .global SVC_Count +SVC_Count: + .long (SVC_End-SVC_Table)/4 + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_ARM7/HAL_CM.c b/rtos/rtx/TARGET_ARM7/HAL_CM.c new file mode 100644 index 0000000..071fd73 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/HAL_CM.c @@ -0,0 +1,161 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM.C + * Purpose: Hardware Abstraction Layer for ARM7TDMI + * Rev.: V1.0 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +#ifdef DBG_MSG +BIT dbg_msg; +#endif + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_init_stack ---------------------------------*/ + +void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { + /* Prepare TCB and saved context for a first time start of a task. */ + U32 *stk,i,size; + + /* Prepare a complete interrupt frame for first task start */ + size = p_TCB->priv_stack >> 2; + + /* Write to the top of stack. */ + stk = &p_TCB->stack[size]; + + /* Auto correct to 8-byte ARM stack alignment. */ + if ((U32)stk & 0x04) { + stk--; + } + + stk -= 16; + + /* Default xPSR and initial PC */ + stk[15] = (U32)task_body + 4; /* add 4 byte offset because SUB PC, LR - 4 */ + stk[0] = INITIAL_xPSR; + + /* Clear R0-R13/LR registers. */ + for (i = 1; i < 14; i++) { + stk[i] = 0; + } + + /* Assign a void pointer to R0. */ + stk[TCB_STACK_R0_OFFSET_DWORDS] = (U32)p_TCB->msg; + + /* Initial Task stack pointer. */ + p_TCB->tsk_stack = (U32)stk; + + /* Task entry point. */ + p_TCB->ptask = task_body; + + /* Set a magic word for checking of stack overflow. + For the main thread (ID: 0x01) the stack is in a memory area shared with the + heap, therefore the last word of the stack is a moving target. + We want to do stack/heap collision detection instead. + */ + if (p_TCB->task_id != 0x01) + p_TCB->stack[0] = MAGIC_WORD; +} + + +/*--------------------------- rt_ret_val ----------------------------------*/ + +static __inline U32 *rt_ret_regs (P_TCB p_TCB) { + /* Get pointer to task return value registers (R0..R3) in Stack */ + + /* Stack Frame: CPSR,R0-R13,PC */ + return (U32 *)(p_TCB->tsk_stack + TCB_STACK_R0_OFFSET_BYTES); +} + +void rt_ret_val (P_TCB p_TCB, U32 v0) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; +} + +void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; + ret[1] = v1; +} + + +/*--------------------------- dbg_init --------------------------------------*/ + +#ifdef DBG_MSG +void dbg_init (void) { + if ((DEMCR & DEMCR_TRCENA) && + (ITM_CONTROL & ITM_ITMENA) && + (ITM_ENABLE & (1UL << 31))) { + dbg_msg = __TRUE; + } +} +#endif + +/*--------------------------- dbg_task_notify -------------------------------*/ + +#ifdef DBG_MSG +void dbg_task_notify (P_TCB p_tcb, BOOL create) { + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U32 = (U32)p_tcb->ptask; + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U16 = (create << 8) | p_tcb->task_id; +} +#endif + +/*--------------------------- dbg_task_switch -------------------------------*/ + +#ifdef DBG_MSG +void dbg_task_switch (U32 task_id) { + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U8 = task_id; +} +#endif + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/RTX_CM_lib.h b/rtos/rtx/TARGET_ARM7/RTX_CM_lib.h new file mode 100644 index 0000000..bec021b --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/RTX_CM_lib.h @@ -0,0 +1,384 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_CM_LIB.H + * Purpose: RTX Kernel System Configuration + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "cmsis_os.h" + +#if defined (__CC_ARM) +#pragma O3 +#define __USED __attribute__((used)) +#elif defined (__GNUC__) +#pragma GCC optimize ("O3") +#define __USED __attribute__((used)) +#elif defined (__ICCARM__) +#define __USED __root +#endif + + +/*---------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3] +#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2] + +#define OS_TCB_SIZE 48 +#define OS_TMR_SIZE 8 + +#if defined (__CC_ARM) && !defined (__MICROLIB) + +typedef void *OS_ID; +typedef uint32_t OS_TID; +typedef uint32_t OS_MUT[3]; +typedef uint32_t OS_RESULT; + +#define runtask_id() rt_tsk_self() +#define mutex_init(m) rt_mut_init(m) +#define mutex_wait(m) os_mut_wait(m,0xFFFF) +#define mutex_rel(m) os_mut_release(m) + +extern OS_TID rt_tsk_self (void); +extern void rt_mut_init (OS_ID mutex); +extern OS_RESULT rt_mut_release (OS_ID mutex); +extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout); + +#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout) +#define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex) + +OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0); +OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0); + +#endif + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +#if (OS_TIMERS != 0) +#define OS_TASK_CNT (OS_TASKCNT + 1) +#else +#define OS_TASK_CNT OS_TASKCNT +#endif + +uint16_t const os_maxtaskrun = OS_TASK_CNT; +uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT; +uint32_t const os_trv = OS_TRV; +uint8_t const os_flags = OS_RUNPRIV; + +/* Export following defines to uVision debugger. */ +__USED uint32_t const os_clockrate = OS_TICK; +__USED uint32_t const os_timernum = 0; + +/* Stack for the os_idle_demon */ +unsigned int idle_task_stack[OS_IDLESTKSIZE]; +unsigned short const idle_task_stack_size = OS_IDLESTKSIZE; + +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +/* Fifo Queue buffer for ISR requests.*/ +uint32_t os_fifo[OS_FIFOSZ*2+1]; +uint8_t const os_fifo_size = OS_FIFOSZ; + +/* An array of Active task pointers. */ +void *os_active_TCB[OS_TASK_CNT]; + +/* User Timers Resources */ +#if (OS_TIMERS != 0) +extern void osTimerThread (void const *argument); +osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ); +osThreadId osThreadId_osTimerThread; +osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *); +osMessageQId osMessageQId_osTimerMessageQ; +#else +osThreadDef_t os_thread_def_osTimerThread = { NULL }; +osThreadId osThreadId_osTimerThread; +osMessageQDef(osTimerMessageQ, 0, void *); +osMessageQId osMessageQId_osTimerMessageQ; +#endif + + +/*---------------------------------------------------------------------------- + * RTX Optimizations (empty functions) + *---------------------------------------------------------------------------*/ + +#if OS_ROBIN == 0 + void rt_init_robin (void) {;} + void rt_chk_robin (void) {;} +#endif + +#if OS_STKCHECK == 0 + void rt_stk_check (void) {;} +#endif + + +/*---------------------------------------------------------------------------- + * Standard Library multithreading interface + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) && !defined (__MICROLIB) + static OS_MUT std_libmutex[OS_MUTEXCNT]; + static uint32_t nr_mutex; + + /*--------------------------- _mutex_initialize -----------------------------*/ + +int _mutex_initialize (OS_ID *mutex) { + /* Allocate and initialize a system mutex. */ + + if (nr_mutex >= OS_MUTEXCNT) { + /* If you are here, you need to increase the number OS_MUTEXCNT. */ + os_error_str("Not enough stdlib mutexes\n"); + } + *mutex = &std_libmutex[nr_mutex++]; + mutex_init (*mutex); + return (1); +} + + +/*--------------------------- _mutex_acquire --------------------------------*/ + +__attribute__((used)) void _mutex_acquire (OS_ID *mutex) { + /* Acquire a system mutex, lock stdlib resources. */ + if (runtask_id ()) { + /* RTX running, acquire a mutex. */ + mutex_wait (*mutex); + } +} + + +/*--------------------------- _mutex_release --------------------------------*/ + +__attribute__((used)) void _mutex_release (OS_ID *mutex) { + /* Release a system mutex, unlock stdlib resources. */ + if (runtask_id ()) { + /* RTX running, release a mutex. */ + mutex_rel (*mutex); + } +} + +#endif + + +/*---------------------------------------------------------------------------- + * RTX Startup + *---------------------------------------------------------------------------*/ + +/* Main Thread definition */ +extern int main (void); +osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 0, NULL}; + +// This define should be probably moved to the CMSIS layer + +#if defined(TARGET_LPC2460) +extern unsigned char __usr_stack_top__[]; +#define INITIAL_SP (__usr_stack_top__) + +#else +#error "no target defined" + +#endif + +#ifdef __CC_ARM +extern unsigned char Image$$RW_IRAM1$$ZI$$Limit[]; +#define HEAP_START (Image$$RW_IRAM1$$ZI$$Limit) +#elif defined(__GNUC__) +extern unsigned char __end__[]; +#define HEAP_START (__end__) +#elif defined(__ICCARM__) +#pragma section="HEAP" +#define HEAP_START (void *)__section_begin("HEAP") +#endif + +void set_main_stack(void) { + // That is the bottom of the main stack block: no collision detection + os_thread_def_main.stack_pointer = HEAP_START; + + // Leave OS_SCHEDULERSTKSIZE words for the scheduler and interrupts + os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)HEAP_START) - (OS_SCHEDULERSTKSIZE * 4); +} + +#if defined (__CC_ARM) +#ifdef __MICROLIB +void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); +void _main_init (void) { + osKernelInitialize(); + set_main_stack(); + osThreadCreate(&os_thread_def_main, NULL); + osKernelStart(); + for (;;); +} +#else + +/* The single memory model is checking for stack collision at run time, verifing + that the heap pointer is underneath the stack pointer. + + With the RTOS there is not only one stack above the heap, there are multiple + stacks and some of them are underneath the heap pointer. +*/ +#pragma import(__use_two_region_memory) + +__asm void __rt_entry (void) { + + IMPORT __user_setup_stackheap + IMPORT __rt_lib_init + IMPORT os_thread_def_main + IMPORT osKernelInitialize + IMPORT set_main_stack + IMPORT osKernelStart + IMPORT osThreadCreate + IMPORT exit + + BL __user_setup_stackheap + MOV R1,R2 + BL __rt_lib_init + BL osKernelInitialize + BL set_main_stack + LDR R0,=os_thread_def_main + MOVS R1,#0 + BL osThreadCreate + BL osKernelStart + BL exit + + ALIGN +} +#endif + +#elif defined (__GNUC__) + +#ifdef __CS3__ + +/* CS3 start_c routine. + * + * Copyright (c) 2006, 2007 CodeSourcery Inc + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include "cs3.h" + +extern void __libc_init_array (void); + +__attribute ((noreturn)) void __cs3_start_c (void){ + unsigned regions = __cs3_region_num; + const struct __cs3_region *rptr = __cs3_regions; + + /* Initialize memory */ + for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) { + long long *src = (long long *)rptr->init; + long long *dst = (long long *)rptr->data; + unsigned limit = rptr->init_size; + unsigned count; + + if (src != dst) + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = *src++; + else + dst = (long long *)((char *)dst + limit); + limit = rptr->zero_size; + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = 0; + } + + /* Run initializers. */ + __libc_init_array (); + + osKernelInitialize(); + set_main_stack(); + osThreadCreate(&os_thread_def_main, NULL); + osKernelStart(); + for (;;); +} + +#else + +__attribute__((naked)) void software_init_hook (void) { + __asm ( + ".syntax unified\n" + ".thumb\n" + "movs r0,#0\n" + "movs r1,#0\n" + "mov r8,r0\n" + "mov r9,r1\n" + "ldr r0,= __libc_fini_array\n" + "bl atexit\n" + "bl __libc_init_array\n" + "mov r0,r8\n" + "mov r1,r9\n" + "bl osKernelInitialize\n" + "bl set_main_stack\n" + "ldr r0,=os_thread_def_main\n" + "movs r1,#0\n" + "bl osThreadCreate\n" + "bl osKernelStart\n" + "bl exit\n" + ); +} + +#endif + +#elif defined (__ICCARM__) + +extern int __low_level_init(void); +extern void __iar_data_init3(void); +extern void exit(int arg); + +__noreturn __stackless void __cmain(void) { + int a; + + if (__low_level_init() != 0) { + __iar_data_init3(); + } + osKernelInitialize(); + set_main_stack(); + osThreadCreate(&os_thread_def_main, NULL); + a = osKernelStart(); + exit(a); +} + +#endif + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + + diff --git a/rtos/rtx/TARGET_ARM7/RTX_Conf.h b/rtos/rtx/TARGET_ARM7/RTX_Conf.h new file mode 100644 index 0000000..babf9c1 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/RTX_Conf.h @@ -0,0 +1,72 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_CONFIG.H + * Purpose: Exported functions of RTX_Config.c + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + +/* Error Codes */ +#define OS_ERR_STK_OVF 1 +#define OS_ERR_FIFO_OVF 2 +#define OS_ERR_MBX_OVF 3 + +/* Definitions */ +#define BOX_ALIGN_8 0x80000000 +#define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)*(cnt) + 3] +#define _declare_box8(pool,size,cnt) U64 pool[(((size)+7)/8)*(cnt) + 2] +#define _init_box8(pool,size,bsize) _init_box (pool,size,(bsize) | BOX_ALIGN_8) + +/* Variables */ +extern U32 idle_task_stack[]; +extern U32 os_fifo[]; +extern void *os_active_TCB[]; + +/* Constants */ +extern U16 const os_maxtaskrun; +extern U32 const os_trv; +extern U8 const os_flags; +extern U32 const os_rrobin; +extern U32 const os_clockrate; +extern U32 const os_timernum; +extern U16 const idle_task_stack_size; + +extern U8 const os_fifo_size; + +/* Functions */ +extern void os_idle_demon (void); +extern int os_tick_init (void); +extern void os_tick_irqack (void); +extern void os_tmr_call (U16 info); +extern void os_error (U32 err_code); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_ARM7/RTX_Conf_CM.c b/rtos/rtx/TARGET_ARM7/RTX_Conf_CM.c new file mode 100644 index 0000000..8293e3a --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/RTX_Conf_CM.c @@ -0,0 +1,246 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_Conf_CM.C + * Purpose: Configuration of CMSIS RTX Kernel for ARM7TDMI + * Rev.: V1.0 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "cmsis_os.h" + + +/*---------------------------------------------------------------------------- + * RTX User configuration part BEGIN + *---------------------------------------------------------------------------*/ + +//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- +// +// Thread Configuration +// ======================= +// +// Number of concurrent running threads <0-250> +// Defines max. number of threads that will run at the same time. +// counting "main", but not counting "osTimerThread" +// Default: 6 +#ifndef OS_TASKCNT +# if defined(TARGET_LPC2368) || defined(TARGET_LPC2460) +# define OS_TASKCNT 14 +# else +# error "no target defined" +# endif +#endif + +// Scheduler (+ interrupts) stack size [bytes] <64-4096:8><#/4> +#ifndef OS_SCHEDULERSTKSIZE +# if defined(TARGET_LPC2368) || defined(TARGET_LPC2460) +# define OS_SCHEDULERSTKSIZE (136*2) +# else +# error "no target defined" +# endif +#endif + +// Idle stack size [bytes] <64-4096:8><#/4> +// Defines default stack size for the Idle thread. +#ifndef OS_IDLESTKSIZE + #define OS_IDLESTKSIZE 136 +#endif + +// Timer Thread stack size [bytes] <64-4096:8><#/4> +// Defines stack size for Timer thread. +// Default: 200 +#ifndef OS_TIMERSTKSZ + #define OS_TIMERSTKSZ WORDS_STACK_SIZE +#endif + +// Check for stack overflow +// Includes the stack checking code for stack overflow. +// Note that additional code reduces the Kernel performance. +#ifndef OS_STKCHECK + #define OS_STKCHECK 1 +#endif + +// Processor mode for thread execution +// <0=> Unprivileged mode +// <1=> Privileged mode +// Default: Privileged mode +#ifndef OS_RUNPRIV + #define OS_RUNPRIV 1 +#endif + +// +// SysTick Timer Configuration +// ============================== +// +// Timer clock value [Hz] <1-1000000000> +// Defines the timer clock value. +// Default: 6000000 (6MHz) +#ifndef OS_CLOCK +# if defined(TARGET_LPC2368) +# define OS_CLOCK 96000000 + +# elif defined(TARGET_LPC2460) +# define OS_CLOCK 72000000 + +# else +# error "no target defined" +# endif +#endif + +// Timer tick value [us] <1-1000000> +// Defines the timer tick value. +// Default: 1000 (1ms) +#ifndef OS_TICK + #define OS_TICK 1000 +#endif + +// + +// System Configuration +// ======================= +// +// Round-Robin Thread switching +// =============================== +// +// Enables Round-Robin Thread switching. +#ifndef OS_ROBIN + #define OS_ROBIN 1 +#endif + +// Round-Robin Timeout [ticks] <1-1000> +// Defines how long a thread will execute before a thread switch. +// Default: 5 +#ifndef OS_ROBINTOUT + #define OS_ROBINTOUT 5 +#endif + +// + +// User Timers +// ============== +// Enables user Timers +#ifndef OS_TIMERS + #define OS_TIMERS 1 +#endif + +// Timer Thread Priority +// <1=> Low +// <2=> Below Normal +// <3=> Normal +// <4=> Above Normal +// <5=> High +// <6=> Realtime (highest) +// Defines priority for Timer Thread +// Default: High +#ifndef OS_TIMERPRIO + #define OS_TIMERPRIO 5 +#endif + +// Timer Callback Queue size <1-32> +// Number of concurrent active timer callback functions. +// Default: 4 +#ifndef OS_TIMERCBQSZ + #define OS_TIMERCBQS 4 +#endif + +// + +// ISR FIFO Queue size<4=> 4 entries <8=> 8 entries +// <12=> 12 entries <16=> 16 entries +// <24=> 24 entries <32=> 32 entries +// <48=> 48 entries <64=> 64 entries +// <96=> 96 entries +// ISR functions store requests to this buffer, +// when they are called from the interrupt handler. +// Default: 16 entries +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +// + +//------------- <<< end of configuration section >>> ----------------------- + +// Standard library system mutexes +// =============================== +// Define max. number system mutexes that are used to protect +// the arm standard runtime library. For microlib they are not used. +#ifndef OS_MUTEXCNT + #define OS_MUTEXCNT 12 +#endif + +/*---------------------------------------------------------------------------- + * RTX User configuration part END + *---------------------------------------------------------------------------*/ + +#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) + + +/*---------------------------------------------------------------------------- + * OS Idle daemon + *---------------------------------------------------------------------------*/ +void os_idle_demon (void) { + /* The idle demon is a system thread, running when no other thread is */ + /* ready to run. */ + + /* Sleep: ideally, we should put the chip to sleep. + Unfortunately, this usually requires disconnecting the interface chip (debugger). + This can be done, but it would break the local file system. + */ + for (;;) { + // sleep(); + } +} + +/*---------------------------------------------------------------------------- + * RTX Errors + *---------------------------------------------------------------------------*/ +extern void mbed_die(void); + +void os_error (uint32_t err_code) { + /* This function is called when a runtime error is detected. Parameter */ + /* 'err_code' holds the runtime error code (defined in RTX_Conf.h). */ + mbed_die(); +} + +void sysThreadError(osStatus status) { + if (status != osOK) { + mbed_die(); + } +} + +/*---------------------------------------------------------------------------- + * RTX Configuration Functions + *---------------------------------------------------------------------------*/ + +#include "RTX_CM_lib.h" + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/cmsis_os.h b/rtos/rtx/TARGET_ARM7/cmsis_os.h new file mode 100644 index 0000000..5c6dea8 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/cmsis_os.h @@ -0,0 +1,774 @@ +/* ---------------------------------------------------------------------- + * Copyright (C) 2015 ARM Limited. All rights reserved. + * + * $Date: 5. June 2012 + * $Revision: V1.01 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h RTX header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedef's + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * -------------------------------------------------------------------- */ + +/** +\page cmsis_os_h Header File Template: cmsis_os.h + +The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). +Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents +its implementation. + +The file cmsis_os.h contains: + - CMSIS-RTOS API function definitions + - struct definitions for parameters and return types + - status and priority values used by CMSIS-RTOS API functions + - macros for defining threads and other kernel objects + + +Name conventions and header file modifications + +All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. +Definitions that are prefixed \b os_ are not used in the application code but local to this header file. +All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. + +Definitions that are marked with CAN BE CHANGED can be adapted towards the needs of the actual CMSIS-RTOS implementation. +These definitions can be specific to the underlying RTOS kernel. + +Definitions that are marked with MUST REMAIN UNCHANGED cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer +compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. + + +Function calls from interrupt service routines + +The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): + - \ref osSignalSet + - \ref osSemaphoreRelease + - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree + - \ref osMessagePut, \ref osMessageGet + - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree + +Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called +from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. + +Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. +If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. + + +Define and reference object definitions + +With \#define osObjectsExternal objects are defined as external symbols. This allows to create a consistent header file +that is used throughout a project as shown below: + +Header File +\code +#include // CMSIS RTOS header file + +// Thread definition +extern void thread_sample (void const *argument); // function prototype +osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); + +// Pool definition +osPoolDef(MyPool, 10, long); +\endcode + + +This header file defines all objects when included in a C/C++ source file. When \#define osObjectsExternal is +present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be +used throughout the whole project. + +Example +\code +#include "osObjects.h" // Definition of the CMSIS-RTOS objects +\endcode + +\code +#define osObjectExternal // Objects will be defined as external symbols +#include "osObjects.h" // Reference to the CMSIS-RTOS objects +\endcode + +*/ + +#ifndef _CMSIS_OS_H +#define _CMSIS_OS_H + +/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x10001 ///< API version (main [31:16] .sub [15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_RTX ((4<<16)|61) ///< RTOS identification and version (main [31:16] .sub [15:0]) + +/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. +#define osKernelSystemId "RTX V4.61" ///< RTOS identification string + + +#define CMSIS_OS_RTX + +// The stack space occupied is mainly dependent on the underling C standard library +#if defined(__GNUC__) || defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__ICCARM__) +# define WORDS_STACK_SIZE 512 +#elif defined(TOOLCHAIN_ARM_MICRO) +# define WORDS_STACK_SIZE 128 +#endif + +#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4) + + +/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_Signals 16 ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 65535 ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available + +#if defined (__CC_ARM) +#define os_InRegs __value_in_regs // Compiler specific: force struct in registers +#elif defined (__ICCARM__) +#define os_InRegs __value_in_regs // Compiler specific: force struct in registers +#else +#define os_InRegs +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "os_tcb.h" + +// ==== Enumeration, structures, defines ==== + +/// Priority used for thread control. +/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. +typedef enum { + osPriorityIdle = -3, ///< priority: idle (lowest) + osPriorityLow = -2, ///< priority: low + osPriorityBelowNormal = -1, ///< priority: below normal + osPriorityNormal = 0, ///< priority: normal (default) + osPriorityAboveNormal = +1, ///< priority: above normal + osPriorityHigh = +2, ///< priority: high + osPriorityRealtime = +3, ///< priority: realtime (highest) + osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority +} osPriority; + +/// Timeout value. +/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value + +/// Status code values returned by CMSIS-RTOS functions. +/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osEventMessage = 0x10, ///< function completed; message event occurred. + osEventMail = 0x20, ///< function completed; mail event occurred. + osEventTimeout = 0x40, ///< function completed; timeout occurred. + osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< value of a parameter is out of range. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; + + +/// Timer type value for the timer definition. +/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. +typedef enum { + osTimerOnce = 0, ///< one-shot timer + osTimerPeriodic = 1 ///< repeating timer +} os_timer_type; + +/// Entry point of a thread. +/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. +typedef void (*os_ptimer) (void const *argument); + +// >>> the following data type definitions may shall adapted towards a specific RTOS + +/// Thread ID identifies the thread (pointer to a thread control block). +/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_cb *osThreadId; + +/// Timer ID identifies the timer (pointer to a timer control block). +/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_cb *osTimerId; + +/// Mutex ID identifies the mutex (pointer to a mutex control block). +/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_cb *osMutexId; + +/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). +/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_cb *osSemaphoreId; + +/// Pool ID identifies the memory pool (pointer to a memory pool control block). +/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_cb *osPoolId; + +/// Message ID identifies the message queue (pointer to a message queue control block). +/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_cb *osMessageQId; + +/// Mail ID identifies the mail queue (pointer to a mail queue control block). +/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_cb *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t stacksize; ///< stack size requirements in bytes + uint32_t *stack_pointer; ///< pointer to the stack memory block + struct OS_TCB tcb; +} osThreadDef_t; + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + void *timer; ///< pointer to internal data +} osTimerDef_t; + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_def { + void *mutex; ///< pointer to internal data +} osMutexDef_t; + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_def { + void *semaphore; ///< pointer to internal data +} osSemaphoreDef_t; + +/// Definition structure for memory block allocation. +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + void *pool; ///< memory array for messages +} osMessageQDef_t; + +/// Definition structure for mail queue. +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; + +/// Event structure contains detailed information about an event. +/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. +/// However the struct may be extended at the end. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Control Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. +osStatus osKernelInitialize (void); + +/// Start the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. +osStatus osKernelStart (void); + +/// Check if the RTOS kernel is already started. +/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. +/// \return 0 RTOS is not started, 1 RTOS is started. +int32_t osKernelRunning(void); + + +// ==== Thread Management ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, stacksz) \ +extern osThreadDef_t os_thread_def_##name +#else // define the object +#define osThreadDef(name, priority, stacksz) \ +uint32_t os_thread_def_stack_##name [stacksz / sizeof(uint32_t)]; \ +osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (stacksz), (os_thread_def_stack_##name)} +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. +osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. +osThreadId osThreadGetId (void); + +/// Terminate execution of a thread and remove it from Active Threads. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. +osStatus osThreadTerminate (osThreadId thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. +osStatus osThreadYield (void); + +/// Change priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); + +/// Get current priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the thread function. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. +osPriority osThreadGetPriority (osThreadId thread_id); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec time delay value +/// \return status code that indicates the execution status of the function. +osStatus osDelay (uint32_t millisec); + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern osTimerDef_t os_timer_def_##name +#else // define the object +#define osTimerDef(name, function) \ +uint32_t os_timer_cb_##name[5]; \ +osTimerDef_t os_timer_def_##name = \ +{ (function), (os_timer_cb_##name) } +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. +osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec time delay value of the timer. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); + +/// Stop the timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. +osStatus osTimerStop (osTimerId timer_id); + +/// Delete a timer that was created by \ref osTimerCreate. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. +osStatus osTimerDelete (osTimerId timer_id); + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Get Signal Flags status of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalGet shall be consistent in every CMSIS-RTOS. +int32_t osSignalGet (osThreadId thread_id); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event flag information or error code. +/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Mutex Management ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern osMutexDef_t os_mutex_def_##name +#else // define the object +#define osMutexDef(name) \ +uint32_t os_mutex_cb_##name[3]; \ +osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) } +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. +osMutexId osMutexCreate (osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. +osStatus osMutexRelease (osMutexId mutex_id); + +/// Delete a Mutex that was created by \ref osMutexCreate. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. +osStatus osMutexDelete (osMutexId mutex_id); + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ +uint32_t os_semaphore_cb_##name[2]; \ +osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) } +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object used for managing resources. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count number of available resources. +/// \return semaphore ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. +osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); + +/// Delete a Semaphore that was created by \ref osSemaphoreCreate. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern osPoolDef_t os_pool_def_##name +#else // define the object +#define osPoolDef(name, no, type) \ +uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \ +osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), (os_pool_m_##name) } +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a memory pool. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. +osPoolId osPoolCreate (osPoolDef_t *pool_def); + +/// Allocate a memory block from a memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a memory pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a specific memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block that is returned to the memory pool. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool Management available + + +// ==== Message Queue Management Functions ==== + +#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern osMessageQDef_t os_messageQ_def_##name +#else // define the object +#define osMessageQDef(name, queue_sz, type) \ +uint32_t os_messageQ_q_##name[4+(queue_sz)]; \ +osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), (os_messageQ_q_##name) } +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue. +/// \param[in] queue_def queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. +osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message or Wait for a Message from a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event information that includes status code. +/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +#endif // Message Queues available + + +// ==== Mail Queue Management Functions ==== + +#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue +/// \param queue_sz maximum number of messages in queue +/// \param type data type of a single message element +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern osMailQDef_t os_mailQ_def_##name +#else // define the object +#define osMailQDef(name, queue_sz, type) \ +uint32_t os_mailQ_q_##name[4+(queue_sz)]; \ +uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \ +void * os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \ +osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize mail queue. +/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. +osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block from a mail and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a mail to a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. +osStatus osMailPut (osMailQId queue_id, void *mail); + +/// Get a mail from a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queues available + + +#ifdef __cplusplus +} +#endif + +#endif // _CMSIS_OS_H diff --git a/rtos/rtx/TARGET_ARM7/os_tcb.h b/rtos/rtx/TARGET_ARM7/os_tcb.h new file mode 100644 index 0000000..fe66b9a --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/os_tcb.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef OS_TCB_H +#define OS_TCB_H + +/* Types */ +typedef char S8; +typedef unsigned char U8; +typedef short S16; +typedef unsigned short U16; +typedef int S32; +typedef unsigned int U32; +typedef long long S64; +typedef unsigned long long U64; +typedef unsigned char BIT; +typedef unsigned int BOOL; +typedef void (*FUNCP)(void); +#define TCB_STACK_LR_OFFSET_BYTES (14*4) // prelast DWORD +#define TCB_STACK_LR_OFFSET_DWORDS (14) // prelast DWORD +#define TCB_STACK_R0_OFFSET_BYTES (1*4) // second DWORD +#define TCB_STACK_R0_OFFSET_DWORDS (1) // second DWORD + +typedef struct OS_TCB { + /* General part: identical for all implementations. */ + U8 cb_type; /* Control Block Type */ + U8 state; /* Task state */ + U8 prio; /* Execution priority */ + U8 task_id; /* Task ID value for optimized TCB access */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ + U16 interval_time; /* Time interval for periodic waits */ + U16 events; /* Event flags */ + U16 waits; /* Wait flags */ + void **msg; /* Direct message passing when task waits */ + + /* Hardware dependant part: specific for CM processor */ + U8 stack_frame; /* Stack frame: 0=Basic, 1=Extended */ + U8 reserved1; + U16 reserved2; + U32 priv_stack; /* Private stack size in bytes */ + U32 tsk_stack; /* Current task Stack pointer (R13) */ + U32 *stack; /* Pointer to Task Stack memory block */ + + /* Library dependant part */ +#if defined (__CC_ARM) && !defined (__MICROLIB) + /* A memory space for arm standard library. */ + U32 std_libspace[96/4]; +#endif + + /* Task entry point used for uVision debugger */ + FUNCP ptask; /* Task entry address */ +} *P_TCB; + +#endif diff --git a/rtos/rtx/TARGET_ARM7/rt_CMSIS.c b/rtos/rtx/TARGET_ARM7/rt_CMSIS.c new file mode 100644 index 0000000..b2992c8 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_CMSIS.c @@ -0,0 +1,1853 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: rt_CMSIS.c + * Purpose: CMSIS RTOS API + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 __CMSIS_GENERIC + +#include "core_arm7.h" + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Time.h" +#include "rt_Mutex.h" +#include "rt_Semaphore.h" +#include "rt_Mailbox.h" +#include "rt_MemBox.h" +#include "rt_HAL_CM.h" + +#define os_thread_cb OS_TCB + +#include "cmsis_os.h" + +#if (osFeature_Signals != 16) +#error Invalid "osFeature_Signals" value! +#endif +#if (osFeature_Semaphore > 65535) +#error Invalid "osFeature_Semaphore" value! +#endif +#if (osFeature_Wait != 0) +#error osWait not supported! +#endif + + +// ==== Enumeration, structures, defines ==== + +// Service Calls defines + +#if defined (__CC_ARM) /* ARM Compiler */ + +#define __NO_RETURN __declspec(noreturn) + +#define osEvent_type osEvent +#define osEvent_ret_status ret +#define osEvent_ret_value ret +#define osEvent_ret_msg ret +#define osEvent_ret_mail ret + +#define osCallback_type osCallback +#define osCallback_ret ret + +#define SVC_0_1(f,t,...) \ +__svc_indirect(0) t _##f (t(*)()); \ + t f (void); \ +__attribute__((always_inline)) \ +static __inline t __##f (void) { \ + return _##f(f); \ +} + +#define SVC_1_1(f,t,t1,...) \ +__svc_indirect(0) t _##f (t(*)(t1),t1); \ + t f (t1 a1); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1) { \ + return _##f(f,a1); \ +} + +#define SVC_2_1(f,t,t1,t2,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \ + t f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2) { \ + return _##f(f,a1,a2); \ +} + +#define SVC_3_1(f,t,t1,t2,t3,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \ + t f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2, t3 a3) { \ + return _##f(f,a1,a2,a3); \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ + t f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + return _##f(f,a1,a2,a3,a4); \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#elif defined (__GNUC__) /* GNU Compiler */ + +#define __NO_RETURN __attribute__((noreturn)) + +typedef uint32_t __attribute__((vector_size(8))) ret64; +typedef uint32_t __attribute__((vector_size(16))) ret128; + +#define RET_pointer __r0 +#define RET_int32_t __r0 +#define RET_osStatus __r0 +#define RET_osPriority __r0 +#define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}} +#define RET_osCallback {(void *)__r0, (void *)__r1} + +#define osEvent_type ret128 +#define osEvent_ret_status (ret128){ret.status} +#define osEvent_ret_value (ret128){ret.status, ret.value.v} +#define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id} +#define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id} + +#define osCallback_type ret64 +#define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg} + +#define SVC_ArgN(n) \ + register int __r##n __asm("r"#n); + +#define SVC_ArgR(n,t,a) \ + register t __r##n __asm("r"#n) = a; + +#define SVC_Arg0() \ + SVC_ArgN(0) \ + SVC_ArgN(1) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg1(t1) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgN(1) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg2(t1,t2) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg3(t1,t2,t3) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgR(2,t3,a3) \ + SVC_ArgN(3) + +#define SVC_Arg4(t1,t2,t3,t4) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgR(2,t3,a3) \ + SVC_ArgR(3,t4,a4) + +#if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS) +#define SVC_Call(f) \ + __asm volatile \ + ( \ + "ldr r7,="#f"\n\t" \ + "mov r12,r7\n\t" \ + "svc 0" \ + : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ + : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ + : "r7", "r12", "lr", "cc" \ + ); +#else +#define SVC_Call(f) \ + __asm volatile \ + ( \ + "ldr r12,="#f"\n\t" \ + "svc 0" \ + : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ + : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ + : "r12", "lr", "cc" \ + ); +#endif + +#define SVC_0_1(f,t,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (void) { \ + SVC_Arg0(); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_1_1(f,t,t1,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1) { \ + SVC_Arg1(t1); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_2_1(f,t,t1,t2,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2) { \ + SVC_Arg2(t1,t2); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_3_1(f,t,t1,t2,t3,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Arg3(t1,t2,t3); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Arg4(t1,t2,t3,t4); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#define __NO_RETURN __noreturn + +#define osEvent_type osEvent +#define osEvent_ret_status ret +#define osEvent_ret_value ret +#define osEvent_ret_msg ret +#define osEvent_ret_mail ret + +#define osCallback_type osCallback +#define osCallback_ret ret + +#define RET_osEvent osEvent +#define RET_osCallback osCallback + +#define SVC_Setup(f) \ + __asm( \ + "mov r12,%0\n" \ + :: "r"(&f): "r12" \ + ); + + +#define SVC_0_1(f,t,...) \ +t f (void); \ +_Pragma("swi_number=0") __swi t _##f (void); \ +static inline t __##f (void) { \ + SVC_Setup(f); \ + return _##f(); \ +} + +#define SVC_1_1(f,t,t1,...) \ +t f (t1 a1); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + SVC_Setup(f); \ + return _##f(a1); \ +} + +#define SVC_2_1(f,t,t1,t2,...) \ +t f (t1 a1, t2 a2); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \ +static inline t __##f (t1 a1, t2 a2) { \ + SVC_Setup(f); \ + return _##f(a1,a2); \ +} + +#define SVC_3_1(f,t,t1,t2,t3,...) \ +t f (t1 a1, t2 a2, t3 a3); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \ +static inline t __##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Setup(f); \ + return _##f(a1,a2,a3); \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ +t f (t1 a1, t2 a2, t3 a3, t4 a4); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Setup(f); \ + return _##f(a1,a2,a3,a4); \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#endif + + +// Callback structure +typedef struct { + void *fp; // Function pointer + void *arg; // Function argument +} osCallback; + + +// OS Section definitions +#ifdef OS_SECTIONS_LINK_INFO +extern const uint32_t os_section_id$$Base; +extern const uint32_t os_section_id$$Limit; +#endif + +// OS Timers external resources +extern osThreadDef_t os_thread_def_osTimerThread; +extern osThreadId osThreadId_osTimerThread; +extern osMessageQDef_t os_messageQ_def_osTimerMessageQ; +extern osMessageQId osMessageQId_osTimerMessageQ; + + +// ==== Helper Functions ==== + +/// Convert timeout in millisec to system ticks +static uint32_t rt_ms2tick (uint32_t millisec) { + uint32_t tick; + + if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout + if (millisec > 4000000) return 0xFFFE; // Max ticks supported + + tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate; + if (tick > 0xFFFE) return 0xFFFE; + + return tick; +} + +/// Convert Thread ID to TCB pointer +static P_TCB rt_tid2ptcb (osThreadId thread_id) { + P_TCB ptcb; + + if (thread_id == NULL) return NULL; + + if ((uint32_t)thread_id & 3) return NULL; + +#ifdef OS_SECTIONS_LINK_INFO + if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { + if (thread_id < (osThreadId)os_section_id$$Base) return NULL; + if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL; + } +#endif + + ptcb = thread_id; + + if (ptcb->cb_type != TCB) return NULL; + + return ptcb; +} + +/// Convert ID pointer to Object pointer +static void *rt_id2obj (void *id) { + + if ((uint32_t)id & 3) return NULL; + +#ifdef OS_SECTIONS_LINK_INFO + if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { + if (id < (void *)os_section_id$$Base) return NULL; + if (id >= (void *)os_section_id$$Limit) return NULL; + } +#endif + + return id; +} + + +// ==== Kernel Control ==== + +uint8_t os_initialized; // Kernel Initialized flag +uint8_t os_running; // Kernel Running flag + +// Kernel Control Service Calls declarations +SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus) +SVC_0_1(svcKernelStart, osStatus, RET_osStatus) +SVC_0_1(svcKernelRunning, int32_t, RET_int32_t) + +extern void sysThreadError (osStatus status); +osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument); +osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); + +// Kernel Control Service Calls + +/// Initialize the RTOS Kernel for creating objects +osStatus svcKernelInitialize (void) { + if (os_initialized) return osOK; + + rt_sys_init(); // RTX System Initialization + os_tsk.run->prio = 255; // Highest priority + + sysThreadError(osOK); + + os_initialized = 1; + + return osOK; +} + +/// Start the RTOS Kernel +osStatus svcKernelStart (void) { + + if (os_running) return osOK; + + // Create OS Timers resources (Message Queue & Thread) + osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); + osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL); + + rt_tsk_prio(0, 0); // Lowest priority +// __set_SP(os_tsk.run->tsk_stack + 8*4); // New context + os_tsk.run = NULL; // Force context switch + + rt_sys_start(); + + os_running = 1; + + return osOK; +} + +/// Check if the RTOS kernel is already started +int32_t svcKernelRunning(void) { + return os_running; +} + +// Kernel Control Public API + +/// Initialize the RTOS Kernel for creating objects +osStatus osKernelInitialize (void) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + if (__get_CONTROL() == MODE_SUPERVISOR) { // Privileged mode + return svcKernelInitialize(); + } else { + return __svcKernelInitialize(); + } +} + +/// Start the RTOS Kernel +osStatus osKernelStart (void) { + + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + switch (__get_CONTROL()) { + case MODE_SUPERVISOR: // Privileged mode + break; + case MODE_USER: + case MODE_SYSTEM: // Unprivileged mode + return osErrorOS; + default: // Other invalid modes + return osErrorOS; + break; + } + return svcKernelStart(); +} + +/// Check if the RTOS kernel is already started +int32_t osKernelRunning(void) { + if ((__get_CONTROL() == MODE_IRQ) || (__get_CONTROL() == MODE_SUPERVISOR)) { + // in ISR or Privileged + return os_running; + } else { + return __svcKernelRunning(); + } +} + + +// ==== Thread Management ==== + +__NO_RETURN void osThreadExit (void); + +// Thread Service Calls declarations +SVC_2_1(svcThreadCreate, osThreadId, osThreadDef_t *, void *, RET_pointer) +SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) +SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) +SVC_0_1(svcThreadYield, osStatus, RET_osStatus) +SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) +SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) + +// Thread Service Calls +extern OS_TID rt_get_TID (void); +extern void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body); + +/// Create a thread and add it to Active Threads and set it to state READY +osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument) { + P_TCB ptcb; + + if ((thread_def == NULL) || + (thread_def->pthread == NULL) || + (thread_def->tpriority < osPriorityIdle) || + (thread_def->tpriority > osPriorityRealtime) || + (thread_def->stacksize == 0) || + (thread_def->stack_pointer == NULL) ) { + sysThreadError(osErrorParameter); + return NULL; + } + + U8 priority = thread_def->tpriority - osPriorityIdle + 1; + P_TCB task_context = &thread_def->tcb; + + /* Utilize the user provided stack. */ + task_context->stack = (U32*)thread_def->stack_pointer; + task_context->priv_stack = thread_def->stacksize; + /* Find a free entry in 'os_active_TCB' table. */ + OS_TID tsk = rt_get_TID (); + os_active_TCB[tsk-1] = task_context; + task_context->task_id = tsk; + /* Pass parameter 'argv' to 'rt_init_context' */ + task_context->msg = argument; + /* For 'size == 0' system allocates the user stack from the memory pool. */ + rt_init_context (task_context, priority, (FUNCP)thread_def->pthread); + + /* Dispatch this task to the scheduler for execution. */ + DBG_TASK_NOTIFY(task_context, __TRUE); + rt_dispatch (task_context); + + ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer + + *((uint32_t *)ptcb->tsk_stack + TCB_STACK_LR_OFFSET_DWORDS) = (uint32_t)osThreadExit; /* LR = osThreadExit */ + + return ptcb; +} + +/// Return the thread ID of the current running thread +osThreadId svcThreadGetId (void) { + OS_TID tsk; + + tsk = rt_tsk_self(); + if (tsk == 0) return NULL; + return (P_TCB)os_active_TCB[tsk - 1]; +} + +/// Terminate execution of a thread and remove it from ActiveThreads +osStatus svcThreadTerminate (osThreadId thread_id) { + OS_RESULT res; + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + res = rt_tsk_delete(ptcb->task_id); // Delete task + + if (res == OS_R_NOK) return osErrorResource; // Delete task failed + + return osOK; +} + +/// Pass control to next thread that is in state READY +osStatus svcThreadYield (void) { + rt_tsk_pass(); // Pass control to next task + return osOK; +} + +/// Change priority of an active thread +osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) { + OS_RESULT res; + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) { + return osErrorValue; + } + + res = rt_tsk_prio( // Change task priority + ptcb->task_id, // Task ID + priority - osPriorityIdle + 1 // New task priority + ); + + if (res == OS_R_NOK) return osErrorResource; // Change task priority failed + + return osOK; +} + +/// Get current priority of an active thread +osPriority svcThreadGetPriority (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osPriorityError; + + return (osPriority)(ptcb->prio - 1 + osPriorityIdle); +} + + +// Thread Public API + +/// Create a thread and add it to Active Threads and set it to state READY +osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument) { + if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR + if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) { + // Privileged and not running + return svcThreadCreate(thread_def, argument); + } else { + return __svcThreadCreate(thread_def, argument); + } +} + +/// Return the thread ID of the current running thread +osThreadId osThreadGetId (void) { + if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR + return __svcThreadGetId(); +} + +/// Terminate execution of a thread and remove it from ActiveThreads +osStatus osThreadTerminate (osThreadId thread_id) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcThreadTerminate(thread_id); +} + +/// Pass control to next thread that is in state READY +osStatus osThreadYield (void) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcThreadYield(); +} + +/// Change priority of an active thread +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcThreadSetPriority(thread_id, priority); +} + +/// Get current priority of an active thread +osPriority osThreadGetPriority (osThreadId thread_id) { + if (__get_CONTROL() == MODE_IRQ) return osPriorityError;// Not allowed in ISR + return __svcThreadGetPriority(thread_id); +} + +/// INTERNAL - Not Public +/// Auto Terminate Thread on exit (used implicitly when thread exists) +__NO_RETURN void osThreadExit (void) { + __svcThreadTerminate(__svcThreadGetId()); + for (;;); // Should never come here +} + + +// ==== Generic Wait Functions ==== + +// Generic Wait Service Calls declarations +SVC_1_1(svcDelay, osStatus, uint32_t, RET_osStatus) +#if osFeature_Wait != 0 +SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent) +#endif + +// Generic Wait Service Calls + +/// Wait for Timeout (Time Delay) +osStatus svcDelay (uint32_t millisec) { + if (millisec == 0) return osOK; + rt_dly_wait(rt_ms2tick(millisec)); + return osEventTimeout; +} + +/// Wait for Signal, Message, Mail, or Timeout +#if osFeature_Wait != 0 +os_InRegs osEvent_type svcWait (uint32_t millisec) { + osEvent ret; + + if (millisec == 0) { + ret.status = osOK; + return osEvent_ret_status; + } + + /* To Do: osEventSignal, osEventMessage, osEventMail */ + rt_dly_wait(rt_ms2tick(millisec)); + ret.status = osEventTimeout; + + return osEvent_ret_status; +} +#endif + + +// Generic Wait API + +/// Wait for Timeout (Time Delay) +osStatus osDelay (uint32_t millisec) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcDelay(millisec); +} + +/// Wait for Signal, Message, Mail, or Timeout +os_InRegs osEvent osWait (uint32_t millisec) { + osEvent ret; + +#if osFeature_Wait == 0 + ret.status = osErrorOS; + return ret; +#else + if (__get_CONTROL() == MODE_IRQ) { // Not allowed in ISR + ret.status = osErrorISR; + return ret; + } + return __svcWait(millisec); +#endif +} + + +// ==== Timer Management ==== + +// Timer definitions +#define osTimerInvalid 0 +#define osTimerStopped 1 +#define osTimerRunning 2 + +// Timer structures + +typedef struct os_timer_cb_ { // Timer Control Block + struct os_timer_cb_ *next; // Pointer to next active Timer + uint8_t state; // Timer State + uint8_t type; // Timer Type (Periodic/One-shot) + uint16_t reserved; // Reserved + uint16_t tcnt; // Timer Delay Count + uint16_t icnt; // Timer Initial Count + void *arg; // Timer Function Argument + osTimerDef_t *timer; // Pointer to Timer definition +} os_timer_cb; + +// Timer variables +os_timer_cb *os_timer_head; // Pointer to first active Timer + + +// Timer Helper Functions + +// Insert Timer into the list sorted by time +static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) { + os_timer_cb *p, *prev; + + prev = NULL; + p = os_timer_head; + while (p != NULL) { + if (tcnt < p->tcnt) break; + tcnt -= p->tcnt; + prev = p; + p = p->next; + } + pt->next = p; + pt->tcnt = (uint16_t)tcnt; + if (p != NULL) { + p->tcnt -= pt->tcnt; + } + if (prev != NULL) { + prev->next = pt; + } else { + os_timer_head = pt; + } +} + +// Remove Timer from the list +static int rt_timer_remove (os_timer_cb *pt) { + os_timer_cb *p, *prev; + + prev = NULL; + p = os_timer_head; + while (p != NULL) { + if (p == pt) break; + prev = p; + p = p->next; + } + if (p == NULL) return -1; + if (prev != NULL) { + prev->next = pt->next; + } else { + os_timer_head = pt->next; + } + if (pt->next != NULL) { + pt->next->tcnt += pt->tcnt; + } + + return 0; +} + + +// Timer Service Calls declarations +SVC_3_1(svcTimerCreate, osTimerId, osTimerDef_t *, os_timer_type, void *, RET_pointer) +SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus) +SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus) +SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus) +SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback) + +// Timer Management Service Calls + +/// Create timer +osTimerId svcTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) { + os_timer_cb *pt; + + if ((timer_def == NULL) || (timer_def->ptimer == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + pt = timer_def->timer; + if (pt == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if ((type != osTimerOnce) && (type != osTimerPeriodic)) { + sysThreadError(osErrorValue); + return NULL; + } + + if (osThreadId_osTimerThread == NULL) { + sysThreadError(osErrorResource); + return NULL; + } + + if (pt->state != osTimerInvalid){ + sysThreadError(osErrorResource); + return NULL; + } + + pt->state = osTimerStopped; + pt->type = (uint8_t)type; + pt->arg = argument; + pt->timer = timer_def; + + return (osTimerId)pt; +} + +/// Start or restart timer +osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) { + os_timer_cb *pt; + uint32_t tcnt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + tcnt = rt_ms2tick(millisec); + if (tcnt == 0) return osErrorValue; + + switch (pt->state) { + case osTimerRunning: + if (rt_timer_remove(pt) != 0) { + return osErrorResource; + } + break; + case osTimerStopped: + pt->state = osTimerRunning; + pt->icnt = (uint16_t)tcnt; + break; + default: + return osErrorResource; + } + + rt_timer_insert(pt, tcnt); + + return osOK; +} + +/// Stop timer +osStatus svcTimerStop (osTimerId timer_id) { + os_timer_cb *pt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + if (pt->state != osTimerRunning) return osErrorResource; + + pt->state = osTimerStopped; + + if (rt_timer_remove(pt) != 0) { + return osErrorResource; + } + + return osOK; +} + +/// Delete timer +osStatus svcTimerDelete (osTimerId timer_id) { + os_timer_cb *pt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + switch (pt->state) { + case osTimerRunning: + rt_timer_remove(pt); + break; + case osTimerStopped: + break; + default: + return osErrorResource; + } + + pt->state = osTimerInvalid; + + return osOK; +} + +/// Get timer callback parameters +os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) { + os_timer_cb *pt; + osCallback ret; + + pt = rt_id2obj(timer_id); + if (pt == NULL) { + ret.fp = NULL; + ret.arg = NULL; + return osCallback_ret; + } + + ret.fp = (void *)pt->timer->ptimer; + ret.arg = pt->arg; + + return osCallback_ret; +} + +static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Timer Tick (called each SysTick) +void sysTimerTick (void) { + os_timer_cb *pt, *p; + + p = os_timer_head; + if (p == NULL) return; + + p->tcnt--; + while ((p != NULL) && (p->tcnt == 0)) { + pt = p; + p = p->next; + os_timer_head = p; + isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0); + if (pt->type == osTimerPeriodic) { + rt_timer_insert(pt, pt->icnt); + } else { + pt->state = osTimerStopped; + } + } +} + + +// Timer Management Public API + +/// Create timer +osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) { + if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR + if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) { + // Privileged and not running + return svcTimerCreate(timer_def, type, argument); + } else { + return __svcTimerCreate(timer_def, type, argument); + } +} + +/// Start or restart timer +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcTimerStart(timer_id, millisec); +} + +/// Stop timer +osStatus osTimerStop (osTimerId timer_id) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcTimerStop(timer_id); +} + +/// Delete timer +osStatus osTimerDelete (osTimerId timer_id) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcTimerDelete(timer_id); +} + +/// INTERNAL - Not Public +/// Get timer callback parameters (used by OS Timer Thread) +os_InRegs osCallback osTimerCall (osTimerId timer_id) { + return __svcTimerCall(timer_id); +} + + +// Timer Thread +__NO_RETURN void osTimerThread (void const *argument) { + osCallback cb; + osEvent evt; + + for (;;) { + evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever); + if (evt.status == osEventMessage) { + cb = osTimerCall(evt.value.p); + if (cb.fp != NULL) { + (*(os_ptimer)cb.fp)(cb.arg); + } + } + } +} + + +// ==== Signal Management ==== + +// Signal Service Calls declarations +SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t) +SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t) +SVC_1_1(svcSignalGet, int32_t, osThreadId, RET_int32_t) +SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent) + +// Signal Service Calls + +/// Set the specified Signal Flags of an active thread +int32_t svcSignalSet (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + rt_evt_set(signals, ptcb->task_id); // Set event flags + + return sig; +} + +/// Clear the specified Signal Flags of an active thread +int32_t svcSignalClear (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + rt_evt_clr(signals, ptcb->task_id); // Clear event flags + + return sig; +} + +/// Get Signal Flags status of an active thread +int32_t svcSignalGet (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + return ptcb->events; // Return event flags +} + +/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread +os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) { + ret.status = osErrorValue; + return osEvent_ret_status; + } + + if (signals != 0) { // Wait for all specified signals + res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE); + } else { // Wait for any signal + res = rt_evt_wait(0xFFFF, rt_ms2tick(millisec), __FALSE); + } + + if (res == OS_R_EVT) { + ret.status = osEventSignal; + ret.value.signals = signals ? signals : os_tsk.run->waits; + } else { + ret.status = millisec ? osEventTimeout : osOK; + ret.value.signals = 0; + } + + return osEvent_ret_value; +} + + +// Signal ISR Calls + +/// Set the specified Signal Flags of an active thread +static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + isr_evt_set(signals, ptcb->task_id); // Set event flags + + return sig; +} + + +// Signal Public API + +/// Set the specified Signal Flags of an active thread +int32_t osSignalSet (osThreadId thread_id, int32_t signals) { + if (__get_CONTROL() == MODE_IRQ) { // in ISR + return isrSignalSet(thread_id, signals); + } else { // in Thread + return __svcSignalSet(thread_id, signals); + } +} + +/// Clear the specified Signal Flags of an active thread +int32_t osSignalClear (osThreadId thread_id, int32_t signals) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcSignalClear(thread_id, signals); +} + +/// Get Signal Flags status of an active thread +int32_t osSignalGet (osThreadId thread_id) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcSignalGet(thread_id); +} + +/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) { + osEvent ret; + + if (__get_CONTROL() == MODE_IRQ) { // Not allowed in ISR + ret.status = osErrorISR; + return ret; + } + return __svcSignalWait(signals, millisec); +} + + +// ==== Mutex Management ==== + +// Mutex Service Calls declarations +SVC_1_1(svcMutexCreate, osMutexId, osMutexDef_t *, RET_pointer) +SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus) +SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus) +SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus) + +// Mutex Service Calls + +/// Create and Initialize a Mutex object +osMutexId svcMutexCreate (osMutexDef_t *mutex_def) { + OS_ID mut; + + if (mutex_def == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + mut = mutex_def->mutex; + if (mut == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_MUCB)mut)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + rt_mut_init(mut); // Initialize Mutex + + return mut; +} + +/// Wait until a Mutex becomes available +osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) { + OS_ID mut; + OS_RESULT res; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex + + if (res == OS_R_TMO) { + return (millisec ? osErrorTimeoutResource : osErrorResource); + } + + return osOK; +} + +/// Release a Mutex that was obtained with osMutexWait +osStatus svcMutexRelease (osMutexId mutex_id) { + OS_ID mut; + OS_RESULT res; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + res = rt_mut_release(mut); // Release Mutex + + if (res == OS_R_NOK) return osErrorResource; // Thread not owner or Zero Counter + + return osOK; +} + +/// Delete a Mutex that was created by osMutexCreate +osStatus svcMutexDelete (osMutexId mutex_id) { + OS_ID mut; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + rt_mut_delete(mut); // Release Mutex + + return osOK; +} + + +// Mutex Public API + +/// Create and Initialize a Mutex object +osMutexId osMutexCreate (osMutexDef_t *mutex_def) { + if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR + if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) { + // Privileged and not running + return svcMutexCreate(mutex_def); + } else { + return __svcMutexCreate(mutex_def); + } +} + +/// Wait until a Mutex becomes available +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcMutexWait(mutex_id, millisec); +} + +/// Release a Mutex that was obtained with osMutexWait +osStatus osMutexRelease (osMutexId mutex_id) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcMutexRelease(mutex_id); +} + +/// Delete a Mutex that was created by osMutexCreate +osStatus osMutexDelete (osMutexId mutex_id) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcMutexDelete(mutex_id); +} + + +// ==== Semaphore Management ==== + +// Semaphore Service Calls declarations +SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer) +SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t) +SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus) +SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus) + +// Semaphore Service Calls + +/// Create and Initialize a Semaphore object +osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + OS_ID sem; + + if (semaphore_def == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + sem = semaphore_def->semaphore; + if (sem == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_SCB)sem)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (count > osFeature_Semaphore) { + sysThreadError(osErrorValue); + return NULL; + } + + rt_sem_init(sem, count); // Initialize Semaphore + + return sem; +} + +/// Wait until a Semaphore becomes available +int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + OS_ID sem; + OS_RESULT res; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return -1; + + if (((P_SCB)sem)->cb_type != SCB) return -1; + + res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore + + if (res == OS_R_TMO) return 0; // Timeout + + return (((P_SCB)sem)->tokens + 1); +} + +/// Release a Semaphore +osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + + rt_sem_send(sem); // Release Semaphore + + return osOK; +} + +/// Delete a Semaphore that was created by osSemaphoreCreate +osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + rt_sem_delete(sem); // Delete Semaphore + + return osOK; +} + + +// Semaphore ISR Calls + +/// Release a Semaphore +static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + + isr_sem_send(sem); // Release Semaphore + + return osOK; +} + + +// Semaphore Public API + +/// Create and Initialize a Semaphore object +osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count) { + if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR + if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) { + // Privileged and not running + return svcSemaphoreCreate(semaphore_def, count); + } else { + return __svcSemaphoreCreate(semaphore_def, count); + } +} + +/// Wait until a Semaphore becomes available +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + if (__get_CONTROL() == MODE_IRQ) return -1; // Not allowed in ISR + return __svcSemaphoreWait(semaphore_id, millisec); +} + +/// Release a Semaphore +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) { + if (__get_CONTROL() == MODE_IRQ) { // in ISR + return isrSemaphoreRelease(semaphore_id); + } else { // in Thread + return __svcSemaphoreRelease(semaphore_id); + } +} + +/// Delete a Semaphore that was created by osSemaphoreCreate +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) { + if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR + return __svcSemaphoreDelete(semaphore_id); +} + + +// ==== Memory Management Functions ==== + +// Memory Management Helper Functions + +// Clear Memory Box (Zero init) +static void rt_clr_box (void *box_mem, void *box) { + uint32_t *p, n; + + if (box) { + p = box; + for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) { + *p++ = 0; + } + } +} + +// Memory Management Service Calls declarations +SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer) +SVC_2_1(sysPoolAlloc, void *, osPoolId, uint32_t, RET_pointer) +SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus) + +// Memory Management Service & ISR Calls + +/// Create and Initialize memory pool +osPoolId svcPoolCreate (const osPoolDef_t *pool_def) { + uint32_t blk_sz; + + if ((pool_def == NULL) || + (pool_def->pool_sz == 0) || + (pool_def->item_sz == 0) || + (pool_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + blk_sz = (pool_def->item_sz + 3) & ~3; + + _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz); + + return pool_def->pool; +} + +/// Allocate a memory block from a memory pool +void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) { + void *ptr; + + if (pool_id == NULL) return NULL; + + ptr = rt_alloc_box(pool_id); + if (clr) { + rt_clr_box(pool_id, ptr); + } + + return ptr; +} + +/// Return an allocated memory block back to a specific memory pool +osStatus sysPoolFree (osPoolId pool_id, void *block) { + int32_t res; + + if (pool_id == NULL) return osErrorParameter; + + res = rt_free_box(pool_id, block); + if (res != 0) return osErrorValue; + + return osOK; +} + + +// Memory Management Public API + +/// Create and Initialize memory pool +osPoolId osPoolCreate (osPoolDef_t *pool_def) { + if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR + if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) { + // Privileged and not running + return svcPoolCreate(pool_def); + } else { + return __svcPoolCreate(pool_def); + } +} + +/// Allocate a memory block from a memory pool +void *osPoolAlloc (osPoolId pool_id) { + if ((__get_CONTROL() == MODE_IRQ) || (__get_CONTROL() == MODE_SUPERVISOR)) { // in ISR or Privileged + return sysPoolAlloc(pool_id, 0); + } else { // in Thread + return __sysPoolAlloc(pool_id, 0); + } +} + +/// Allocate a memory block from a memory pool and set memory block to zero +void *osPoolCAlloc (osPoolId pool_id) { + if ((__get_CONTROL() == MODE_IRQ) || (__get_CONTROL() == MODE_SUPERVISOR)) { // in ISR or Privileged + return sysPoolAlloc(pool_id, 1); + } else { // in Thread + return __sysPoolAlloc(pool_id, 1); + } +} + +/// Return an allocated memory block back to a specific memory pool +osStatus osPoolFree (osPoolId pool_id, void *block) { + if ((__get_CONTROL() == MODE_IRQ) || (__get_CONTROL() == MODE_SUPERVISOR)) { // in ISR or Privileged + return sysPoolFree(pool_id, block); + } else { // in Thread + return __sysPoolFree(pool_id, block); + } +} + + +// ==== Message Queue Management Functions ==== + +// Message Queue Management Service Calls declarations +SVC_2_1(svcMessageCreate, osMessageQId, osMessageQDef_t *, osThreadId, RET_pointer) +SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus) +SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent) + +// Message Queue Service Calls + +/// Create and Initialize Message Queue +osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) { + + if ((queue_def == NULL) || + (queue_def->queue_sz == 0) || + (queue_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_MCB)queue_def->pool)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4)); + + return queue_def->pool; +} + +/// Put a Message to a Queue +osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + OS_RESULT res; + + if (queue_id == NULL) return osErrorParameter; + + if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + + res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec)); + + if (res == OS_R_TMO) { + return (millisec ? osErrorTimeoutResource : osErrorResource); + } + + return osOK; +} + +/// Get a Message or Wait for a Message from a Queue +os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if (queue_id == NULL) { + ret.status = osErrorParameter; + return osEvent_ret_status; + } + + if (((P_MCB)queue_id)->cb_type != MCB) { + ret.status = osErrorParameter; + return osEvent_ret_status; + } + + res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec)); + + if (res == OS_R_TMO) { + ret.status = millisec ? osEventTimeout : osOK; + return osEvent_ret_value; + } + + ret.status = osEventMessage; + + return osEvent_ret_value; +} + + +// Message Queue ISR Calls + +/// Put a Message to a Queue +static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + + if ((queue_id == NULL) || (millisec != 0)) { + return osErrorParameter; + } + + if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + + if (rt_mbx_check(queue_id) == 0) { // Check if Queue is full + return osErrorResource; + } + + isr_mbx_send(queue_id, (void *)info); + + return osOK; +} + +/// Get a Message or Wait for a Message from a Queue +static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if ((queue_id == NULL) || (millisec != 0)) { + ret.status = osErrorParameter; + return ret; + } + + if (((P_MCB)queue_id)->cb_type != MCB) { + ret.status = osErrorParameter; + return ret; + } + + res = isr_mbx_receive(queue_id, &ret.value.p); + + if (res != OS_R_MBX) { + ret.status = osOK; + return ret; + } + + ret.status = osEventMessage; + + return ret; +} + + +// Message Queue Management Public API + +/// Create and Initialize Message Queue +osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) { + if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR + if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) { + // Privileged and not running + return svcMessageCreate(queue_def, thread_id); + } else { + return __svcMessageCreate(queue_def, thread_id); + } +} + +/// Put a Message to a Queue +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + if (__get_CONTROL() == MODE_IRQ) { // in ISR + return isrMessagePut(queue_id, info, millisec); + } else { // in Thread + return __svcMessagePut(queue_id, info, millisec); + } +} + +/// Get a Message or Wait for a Message from a Queue +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { + if (__get_CONTROL() == MODE_IRQ) { // in ISR + return isrMessageGet(queue_id, millisec); + } else { // in Thread + return __svcMessageGet(queue_id, millisec); + } +} + + +// ==== Mail Queue Management Functions ==== + +// Mail Queue Management Service Calls declarations +SVC_2_1(svcMailCreate, osMailQId, osMailQDef_t *, osThreadId, RET_pointer) +SVC_4_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, uint32_t, RET_pointer) +SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus) + +// Mail Queue Management Service & ISR Calls + +/// Create and Initialize mail queue +osMailQId svcMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) { + uint32_t blk_sz; + P_MCB pmcb; + void *pool; + + if ((queue_def == NULL) || + (queue_def->queue_sz == 0) || + (queue_def->item_sz == 0) || + (queue_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + pmcb = *(((void **)queue_def->pool) + 0); + pool = *(((void **)queue_def->pool) + 1); + + if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) { + sysThreadError(osErrorParameter); + return NULL; + } + + blk_sz = (queue_def->item_sz + 3) & ~3; + + _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz); + + rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4)); + + + return queue_def->pool; +} + +/// Allocate a memory block from a mail +void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) { + P_MCB pmcb; + void *pool; + void *mem; + + if (queue_id == NULL) return NULL; + + pmcb = *(((void **)queue_id) + 0); + pool = *(((void **)queue_id) + 1); + + if ((pool == NULL) || (pmcb == NULL)) return NULL; + + if (isr && (millisec != 0)) return NULL; + + mem = rt_alloc_box(pool); + if (clr) { + rt_clr_box(pool, mem); + } + + if ((mem == NULL) && (millisec != 0)) { + // Put Task to sleep when Memory not available + if (pmcb->p_lnk != NULL) { + rt_put_prio((P_XCB)pmcb, os_tsk.run); + } else { + pmcb->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)pmcb; + // Task is waiting to allocate a message + pmcb->state = 3; + } + rt_block(rt_ms2tick(millisec), WAIT_MBX); + } + + return mem; +} + +/// Free a memory block from a mail +osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) { + P_MCB pmcb; + P_TCB ptcb; + void *pool; + void *mem; + int32_t res; + + if (queue_id == NULL) return osErrorParameter; + + pmcb = *(((void **)queue_id) + 0); + pool = *(((void **)queue_id) + 1); + + if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter; + + res = rt_free_box(pool, mail); + + if (res != 0) return osErrorValue; + + if (pmcb->state == 3) { + // Task is waiting to allocate a message + if (isr) { + rt_psq_enq (pmcb, (U32)pool); + rt_psh_req (); + } else { + mem = rt_alloc_box(pool); + if (mem != NULL) { + ptcb = rt_get_first((P_XCB)pmcb); + if (pmcb->p_lnk == NULL) { + pmcb->state = 0; + } + rt_ret_val(ptcb, (U32)mem); + rt_rmv_dly(ptcb); + rt_dispatch(ptcb); + } + } + } + + return osOK; +} + + +// Mail Queue Management Public API + +/// Create and Initialize mail queue +osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) { + if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR + if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) { + // Privileged and not running + return svcMailCreate(queue_def, thread_id); + } else { + return __svcMailCreate(queue_def, thread_id); + } +} + +/// Allocate a memory block from a mail +void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { + if (__get_CONTROL() == MODE_IRQ) { // in ISR + return sysMailAlloc(queue_id, millisec, 1, 0); + } else { // in Thread + return __sysMailAlloc(queue_id, millisec, 0, 0); + } +} + +/// Allocate a memory block from a mail and set memory block to zero +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { + if (__get_CONTROL() == MODE_IRQ) { // in ISR + return sysMailAlloc(queue_id, millisec, 1, 1); + } else { // in Thread + return __sysMailAlloc(queue_id, millisec, 0, 1); + } +} + +/// Free a memory block from a mail +osStatus osMailFree (osMailQId queue_id, void *mail) { + if (__get_CONTROL() == MODE_IRQ) { // in ISR + return sysMailFree(queue_id, mail, 1); + } else { // in Thread + return __sysMailFree(queue_id, mail, 0); + } +} + +/// Put a mail to a queue +osStatus osMailPut (osMailQId queue_id, void *mail) { + if (queue_id == NULL) return osErrorParameter; + if (mail == NULL) return osErrorValue; + return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0); +} + +/// Get a mail from a queue +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { + osEvent ret; + + if (queue_id == NULL) { + ret.status = osErrorParameter; + return ret; + } + + ret = osMessageGet(*((void **)queue_id), millisec); + if (ret.status == osEventMessage) ret.status = osEventMail; + + return ret; +} diff --git a/rtos/rtx/TARGET_ARM7/rt_Event.c b/rtos/rtx/TARGET_ARM7/rt_Event.c new file mode 100644 index 0000000..871e4b0 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Event.c @@ -0,0 +1,190 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_EVENT.C + * Purpose: Implements waits and wake-ups for event flags + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_evt_wait -----------------------------------*/ + +OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) { + /* Wait for one or more event flags with optional time-out. */ + /* "wait_flags" identifies the flags to wait for. */ + /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */ + /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */ + /* to complete the wait. (OR-ing if set to 0). */ + U32 block_state; + + if (and_wait) { + /* Check for AND-connected events */ + if ((os_tsk.run->events & wait_flags) == wait_flags) { + os_tsk.run->events &= ~wait_flags; + return (OS_R_EVT); + } + block_state = WAIT_AND; + } + else { + /* Check for OR-connected events */ + if (os_tsk.run->events & wait_flags) { + os_tsk.run->waits = os_tsk.run->events & wait_flags; + os_tsk.run->events &= ~wait_flags; + return (OS_R_EVT); + } + block_state = WAIT_OR; + } + /* Task has to wait */ + os_tsk.run->waits = wait_flags; + rt_block (timeout, (U8)block_state); + return (OS_R_TMO); +} + + +/*--------------------------- rt_evt_set ------------------------------------*/ + +void rt_evt_set (U16 event_flags, OS_TID task_id) { + /* Set one or more event flags of a selectable task. */ + P_TCB p_tcb; + + p_tcb = os_active_TCB[task_id-1]; + if (p_tcb == NULL) { + return; + } + p_tcb->events |= event_flags; + event_flags = p_tcb->waits; + /* If the task is not waiting for an event, it should not be put */ + /* to ready state. */ + if (p_tcb->state == WAIT_AND) { + /* Check for AND-connected events */ + if ((p_tcb->events & event_flags) == event_flags) { + goto wkup; + } + } + if (p_tcb->state == WAIT_OR) { + /* Check for OR-connected events */ + if (p_tcb->events & event_flags) { + p_tcb->waits &= p_tcb->events; +wkup: p_tcb->events &= ~event_flags; + rt_rmv_dly (p_tcb); + p_tcb->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val2(p_tcb, 0x08/*osEventSignal*/, p_tcb->waits); +#else + rt_ret_val (p_tcb, OS_R_EVT); +#endif + rt_dispatch (p_tcb); + } + } +} + + +/*--------------------------- rt_evt_clr ------------------------------------*/ + +void rt_evt_clr (U16 clear_flags, OS_TID task_id) { + /* Clear one or more event flags (identified by "clear_flags") of a */ + /* selectable task (identified by "task"). */ + P_TCB task = os_active_TCB[task_id-1]; + + if (task == NULL) { + return; + } + task->events &= ~clear_flags; +} + + +/*--------------------------- isr_evt_set -----------------------------------*/ + +void isr_evt_set (U16 event_flags, OS_TID task_id) { + /* Same function as "os_evt_set", but to be called by ISRs. */ + P_TCB p_tcb = os_active_TCB[task_id-1]; + + if (p_tcb == NULL) { + return; + } + rt_psq_enq (p_tcb, event_flags); + rt_psh_req (); +} + + +/*--------------------------- rt_evt_get ------------------------------------*/ + +U16 rt_evt_get (void) { + /* Get events of a running task after waiting for OR connected events. */ + return (os_tsk.run->waits); +} + + +/*--------------------------- rt_evt_psh ------------------------------------*/ + +void rt_evt_psh (P_TCB p_CB, U16 set_flags) { + /* Check if task has to be waken up */ + U16 event_flags; + + p_CB->events |= set_flags; + event_flags = p_CB->waits; + if (p_CB->state == WAIT_AND) { + /* Check for AND-connected events */ + if ((p_CB->events & event_flags) == event_flags) { + goto rdy; + } + } + if (p_CB->state == WAIT_OR) { + /* Check for OR-connected events */ + if (p_CB->events & event_flags) { + p_CB->waits &= p_CB->events; +rdy: p_CB->events &= ~event_flags; + rt_rmv_dly (p_CB); + p_CB->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val2(p_CB, 0x08/*osEventSignal*/, p_CB->waits); +#else + rt_ret_val (p_CB, OS_R_EVT); +#endif + rt_put_prio (&os_rdy, p_CB); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_ARM7/rt_Event.h b/rtos/rtx/TARGET_ARM7/rt_Event.h new file mode 100644 index 0000000..9118c4f --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Event.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_EVENT.H + * Purpose: Implements waits and wake-ups for event flags + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait); +extern void rt_evt_set (U16 event_flags, OS_TID task_id); +extern void rt_evt_clr (U16 clear_flags, OS_TID task_id); +extern void isr_evt_set (U16 event_flags, OS_TID task_id); +extern U16 rt_evt_get (void); +extern void rt_evt_psh (P_TCB p_CB, U16 set_flags); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_HAL_CM.h b/rtos/rtx/TARGET_ARM7/rt_HAL_CM.h new file mode 100644 index 0000000..b6a1907 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_HAL_CM.h @@ -0,0 +1,216 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_HAL_CM.H + * Purpose: Hardware Abstraction Layer for Cortex-M definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "cmsis.h" +/* Definitions */ +#define INITIAL_xPSR 0x10000000 +#define DEMCR_TRCENA 0x01000000 +#define ITM_ITMENA 0x00000001 +#define MAGIC_WORD 0xE25A2EA5 + +#define SYS_TICK_IRQn TIMER0_IRQn + +extern void rt_set_PSP (U32 stack); +extern U32 rt_get_PSP (void); +extern void os_set_env (void); +extern void SysTick_Handler (void); +extern void *_alloc_box (void *box_mem); +extern int _free_box (void *box_mem, void *box); + +extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); +extern void rt_ret_val (P_TCB p_TCB, U32 v0); +extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); + +extern void dbg_init (void); +extern void dbg_task_notify (P_TCB p_tcb, BOOL create); +extern void dbg_task_switch (U32 task_id); + + +#if defined (__CC_ARM) /* ARM Compiler */ + +#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS) + #define __USE_EXCLUSIVE_ACCESS +#else + #undef __USE_EXCLUSIVE_ACCESS +#endif + +#elif defined (__GNUC__) /* GNU Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if defined (__CORTEX_M0) || defined (__CORTEX_M0PLUS) +#define __TARGET_ARCH_6S_M 1 +#else +#define __TARGET_ARCH_6S_M 0 +#endif + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline +#define __weak __attribute__((weak)) + + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if (__CORE__ == __ARM6M__) +#define __TARGET_ARCH_6S_M 1 +#else +#define __TARGET_ARCH_6S_M 0 +#endif + +#if defined __ARMVFP__ +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline + +#endif + + +/* NVIC registers */ + +#define OS_PEND_IRQ() NVIC_PendIRQ(SYS_TICK_IRQn) +#define OS_PENDING NVIC_PendingIRQ(SYS_TICK_IRQn) +#define OS_UNPEND(fl) NVIC_UnpendIRQ(SYS_TICK_IRQn) +#define OS_PEND(fl,p) NVIC_PendIRQ(SYS_TICK_IRQn) +#define OS_LOCK() NVIC_DisableIRQ(SYS_TICK_IRQn) +#define OS_UNLOCK() NVIC_EnableIRQ(SYS_TICK_IRQn) + +#define OS_X_PENDING NVIC_PendingIRQ(SYS_TICK_IRQn) +#define OS_X_UNPEND(fl) NVIC_UnpendIRQ(SYS_TICK_IRQn) +#define OS_X_PEND(fl,p) NVIC_PendIRQ(SYS_TICK_IRQn) + +#define OS_X_INIT(n) NVIC_EnableIRQ(n) +#define OS_X_LOCK(n) NVIC_DisableIRQ(n) +#define OS_X_UNLOCK(n) NVIC_EnableIRQ(n) + +/* Variables */ +extern BIT dbg_msg; + +/* Functions */ +#ifdef __USE_EXCLUSIVE_ACCESS + #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) + #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) +#else + #define rt_inc(p) __disable_irq();(*p)++;__enable_irq(); + #define rt_dec(p) __disable_irq();(*p)--;__enable_irq(); +#endif + +__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { + U32 cnt,c2; +#ifdef __USE_EXCLUSIVE_ACCESS + do { + if ((cnt = __ldrex(count)) == size) { + __clrex(); + return (cnt); } + } while (__strex(cnt+1, count)); + do { + c2 = (cnt = __ldrex(first)) + 1; + if (c2 == size) c2 = 0; + } while (__strex(c2, first)); +#else + __disable_irq(); + if ((cnt = *count) < size) { + *count = cnt+1; + c2 = (cnt = *first) + 1; + if (c2 == size) c2 = 0; + *first = c2; + } + __enable_irq (); +#endif + return (cnt); +} + +__inline static void rt_systick_init (void) { +#if SYS_TICK_IRQn == TIMER0_IRQn + #define SYS_TICK_TIMER LPC_TIM0 + LPC_SC->PCONP |= (1 << PCTIM0); + LPC_SC->PCLKSEL0 = (LPC_SC->PCLKSEL0 & (~(1<<3))) | (1<<2); //PCLK == CPUCLK +#elif SYS_TICK_IRQn == TIMER1_IRQn + #define SYS_TICK_TIMER LPC_TIM1 + LPC_SC->PCONP |= (1 << PCTIM1); + LPC_SC->PCLKSEL0 = (LPC_SC->PCLKSEL0 & (~(1<<5))) | (1<<4); //PCLK == CPUCLK +#elif SYS_TICK_IRQn == TIMER2_IRQn + #define SYS_TICK_TIMER LPC_TIM2 + LPC_SC->PCONP |= (1 << PCTIM2); + LPC_SC->PCLKSEL1 = (LPC_SC->PCLKSEL1 & (~(1<<13))) | (1<<12); //PCLK == CPUCLK +#else + #define SYS_TICK_TIMER LPC_TIM3 + LPC_SC->PCONP |= (1 << PCTIM3); + LPC_SC->PCLKSEL1 = (LPC_SC->PCLKSEL1 & (~(1<<15))) | (1<<14); //PCLK == CPUCLK +#endif + + // setup Timer to count forever + //interrupt_reg + SYS_TICK_TIMER->TCR = 2; // reset & disable timer 0 + SYS_TICK_TIMER->TC = os_trv; + SYS_TICK_TIMER->PR = 0; // set the prescale divider + //Reset of TC and Interrupt when MR3 MR2 matches TC + SYS_TICK_TIMER->MCR = (1 << 9) |(1 << 10); //TMCR_MR3_R_Msk | TMCR_MR3_I_Msk + SYS_TICK_TIMER->MR3 = os_trv; // match registers + SYS_TICK_TIMER->CCR = 0; // disable compare registers + SYS_TICK_TIMER->EMR = 0; // disable external match register + // initialize the interrupt vector + NVIC_SetVector(SYS_TICK_IRQn, (uint32_t)&SysTick_Handler); + SYS_TICK_TIMER->TCR = 1; // enable timer 0 +} + +__inline static void rt_svc_init (void) { +// TODO: add svcInit + +} + +#ifdef DBG_MSG +#define DBG_INIT() dbg_init() +#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new_tsk != os_tsk.run)) \ + dbg_task_switch(task_id) +#else +#define DBG_INIT() +#define DBG_TASK_NOTIFY(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_List.c b/rtos/rtx/TARGET_ARM7/rt_List.c new file mode 100644 index 0000000..06b5a89 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_List.c @@ -0,0 +1,320 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_LIST.C + * Purpose: Functions for the management of different lists + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Time.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* List head of chained ready tasks */ +struct OS_XCB os_rdy; +/* List head of chained delay tasks */ +struct OS_XCB os_dly; + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_put_prio -----------------------------------*/ + +void rt_put_prio (P_XCB p_CB, P_TCB p_task) { + /* Put task identified with "p_task" into list ordered by priority. */ + /* "p_CB" points to head of list; list has always an element at end with */ + /* a priority less than "p_task->prio". */ + P_TCB p_CB2; + U32 prio; + BOOL sem_mbx = __FALSE; + + if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + sem_mbx = __TRUE; + } + prio = p_task->prio; + p_CB2 = p_CB->p_lnk; + /* Search for an entry in the list */ + while (p_CB2 != NULL && prio <= p_CB2->prio) { + p_CB = (P_XCB)p_CB2; + p_CB2 = p_CB2->p_lnk; + } + /* Entry found, insert the task into the list */ + p_task->p_lnk = p_CB2; + p_CB->p_lnk = p_task; + if (sem_mbx) { + if (p_CB2 != NULL) { + p_CB2->p_rlnk = p_task; + } + p_task->p_rlnk = (P_TCB)p_CB; + } + else { + p_task->p_rlnk = NULL; + } +} + + +/*--------------------------- rt_get_first ----------------------------------*/ + +P_TCB rt_get_first (P_XCB p_CB) { + /* Get task at head of list: it is the task with highest priority. */ + /* "p_CB" points to head of list. */ + P_TCB p_first; + + p_first = p_CB->p_lnk; + p_CB->p_lnk = p_first->p_lnk; + if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + if (p_first->p_lnk != NULL) { + p_first->p_lnk->p_rlnk = (P_TCB)p_CB; + p_first->p_lnk = NULL; + } + p_first->p_rlnk = NULL; + } + else { + p_first->p_lnk = NULL; + } + return (p_first); +} + + +/*--------------------------- rt_put_rdy_first ------------------------------*/ + +void rt_put_rdy_first (P_TCB p_task) { + /* Put task identified with "p_task" at the head of the ready list. The */ + /* task must have at least a priority equal to highest priority in list. */ + p_task->p_lnk = os_rdy.p_lnk; + p_task->p_rlnk = NULL; + os_rdy.p_lnk = p_task; +} + + +/*--------------------------- rt_get_same_rdy_prio --------------------------*/ + +P_TCB rt_get_same_rdy_prio (void) { + /* Remove a task of same priority from ready list if any exists. Other- */ + /* wise return NULL. */ + P_TCB p_first; + + p_first = os_rdy.p_lnk; + if (p_first->prio == os_tsk.run->prio) { + os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; + return (p_first); + } + return (NULL); +} + + +/*--------------------------- rt_resort_prio --------------------------------*/ + +void rt_resort_prio (P_TCB p_task) { + /* Re-sort ordered lists after the priority of 'p_task' has changed. */ + P_TCB p_CB; + + if (p_task->p_rlnk == NULL) { + if (p_task->state == READY) { + /* Task is chained into READY list. */ + p_CB = (P_TCB)&os_rdy; + goto res; + } + } + else { + p_CB = p_task->p_rlnk; + while (p_CB->cb_type == TCB) { + /* Find a header of this task chain list. */ + p_CB = p_CB->p_rlnk; + } +res:rt_rmv_list (p_task); + rt_put_prio ((P_XCB)p_CB, p_task); + } +} + + +/*--------------------------- rt_put_dly ------------------------------------*/ + +void rt_put_dly (P_TCB p_task, U16 delay) { + /* Put a task identified with "p_task" into chained delay wait list using */ + /* a delay value of "delay". */ + P_TCB p; + U32 delta,idelay = delay; + + p = (P_TCB)&os_dly; + if (p->p_dlnk == NULL) { + /* Delay list empty */ + delta = 0; + goto last; + } + delta = os_dly.delta_time; + while (delta < idelay) { + if (p->p_dlnk == NULL) { + /* End of list found */ +last: p_task->p_dlnk = NULL; + p->p_dlnk = p_task; + p_task->p_blnk = p; + p->delta_time = (U16)(idelay - delta); + p_task->delta_time = 0; + return; + } + p = p->p_dlnk; + delta += p->delta_time; + } + /* Right place found */ + p_task->p_dlnk = p->p_dlnk; + p->p_dlnk = p_task; + p_task->p_blnk = p; + if (p_task->p_dlnk != NULL) { + p_task->p_dlnk->p_blnk = p_task; + } + p_task->delta_time = (U16)(delta - idelay); + p->delta_time -= p_task->delta_time; +} + + +/*--------------------------- rt_dec_dly ------------------------------------*/ + +void rt_dec_dly (void) { + /* Decrement delta time of list head: remove tasks having a value of zero.*/ + P_TCB p_rdy; + + if (os_dly.p_dlnk == NULL) { + return; + } + os_dly.delta_time--; + while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { + p_rdy = os_dly.p_dlnk; + if (p_rdy->p_rlnk != NULL) { + /* Task is really enqueued, remove task from semaphore/mailbox */ + /* timeout waiting list. */ + p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; + if (p_rdy->p_lnk != NULL) { + p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; + p_rdy->p_lnk = NULL; + } + p_rdy->p_rlnk = NULL; + } + rt_put_prio (&os_rdy, p_rdy); + os_dly.delta_time = p_rdy->delta_time; + if (p_rdy->state == WAIT_ITV) { + /* Calculate the next time for interval wait. */ + p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; + } + p_rdy->state = READY; + os_dly.p_dlnk = p_rdy->p_dlnk; + if (p_rdy->p_dlnk != NULL) { + p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; + p_rdy->p_dlnk = NULL; + } + p_rdy->p_blnk = NULL; + } +} + + +/*--------------------------- rt_rmv_list -----------------------------------*/ + +void rt_rmv_list (P_TCB p_task) { + /* Remove task identified with "p_task" from ready, semaphore or mailbox */ + /* waiting list if enqueued. */ + P_TCB p_b; + + if (p_task->p_rlnk != NULL) { + /* A task is enqueued in semaphore / mailbox waiting list. */ + p_task->p_rlnk->p_lnk = p_task->p_lnk; + if (p_task->p_lnk != NULL) { + p_task->p_lnk->p_rlnk = p_task->p_rlnk; + } + return; + } + + p_b = (P_TCB)&os_rdy; + while (p_b != NULL) { + /* Search the ready list for task "p_task" */ + if (p_b->p_lnk == p_task) { + p_b->p_lnk = p_task->p_lnk; + return; + } + p_b = p_b->p_lnk; + } +} + + +/*--------------------------- rt_rmv_dly ------------------------------------*/ + +void rt_rmv_dly (P_TCB p_task) { + /* Remove task identified with "p_task" from delay list if enqueued. */ + P_TCB p_b; + + p_b = p_task->p_blnk; + if (p_b != NULL) { + /* Task is really enqueued */ + p_b->p_dlnk = p_task->p_dlnk; + if (p_task->p_dlnk != NULL) { + /* 'p_task' is in the middle of list */ + p_b->delta_time += p_task->delta_time; + p_task->p_dlnk->p_blnk = p_b; + p_task->p_dlnk = NULL; + } + else { + /* 'p_task' is at the end of list */ + p_b->delta_time = 0; + } + p_task->p_blnk = NULL; + } +} + + +/*--------------------------- rt_psq_enq ------------------------------------*/ + +void rt_psq_enq (OS_ID entry, U32 arg) { + /* Insert post service request "entry" into ps-queue. */ + U32 idx; + + idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); + if (idx < os_psq->size) { + os_psq->q[idx].id = entry; + os_psq->q[idx].arg = arg; + } + else { + os_error (OS_ERR_FIFO_OVF); + } +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_List.h b/rtos/rtx/TARGET_ARM7/rt_List.h new file mode 100644 index 0000000..385123b --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_List.h @@ -0,0 +1,67 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_LIST.H + * Purpose: Functions for the management of different lists + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Definitions */ + +/* Values for 'cb_type' */ +#define TCB 0 +#define MCB 1 +#define SCB 2 +#define MUCB 3 +#define HCB 4 + +/* Variables */ +extern struct OS_XCB os_rdy; +extern struct OS_XCB os_dly; + +/* Functions */ +extern void rt_put_prio (P_XCB p_CB, P_TCB p_task); +extern P_TCB rt_get_first (P_XCB p_CB); +extern void rt_put_rdy_first (P_TCB p_task); +extern P_TCB rt_get_same_rdy_prio (void); +extern void rt_resort_prio (P_TCB p_task); +extern void rt_put_dly (P_TCB p_task, U16 delay); +extern void rt_dec_dly (void); +extern void rt_rmv_list (P_TCB p_task); +extern void rt_rmv_dly (P_TCB p_task); +extern void rt_psq_enq (OS_ID entry, U32 arg); + +/* This is a fast macro generating in-line code */ +#define rt_rdy_prio(void) (os_rdy.p_lnk->prio) + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_Mailbox.c b/rtos/rtx/TARGET_ARM7/rt_Mailbox.c new file mode 100644 index 0000000..b351bd1 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Mailbox.c @@ -0,0 +1,292 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MAILBOX.C + * Purpose: Implements waits and wake-ups for mailbox messages + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Mailbox.h" +#include "rt_MemBox.h" +#include "rt_Task.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_mbx_init -----------------------------------*/ + +void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { + /* Initialize a mailbox */ + P_MCB p_MCB = mailbox; + + p_MCB->cb_type = MCB; + p_MCB->state = 0; + p_MCB->isr_st = 0; + p_MCB->p_lnk = NULL; + p_MCB->first = 0; + p_MCB->last = 0; + p_MCB->count = 0; + p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) / + (U32)sizeof (void *); +} + + +/*--------------------------- rt_mbx_send -----------------------------------*/ + +OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { + /* Send message to a mailbox */ + P_MCB p_MCB = mailbox; + P_TCB p_TCB; + + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1)) { + /* A task is waiting for message */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); +#else + *p_TCB->msg = p_msg; + rt_ret_val (p_TCB, OS_R_MBX); +#endif + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + /* Store message in mailbox queue */ + if (p_MCB->count == p_MCB->size) { + /* No free message entry, wait for one. If message queue is full, */ + /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ + /* pointer can now be reused for send message waits task list. */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + /* Task is waiting to send a message */ + p_MCB->state = 2; + } + os_tsk.run->msg = p_msg; + rt_block (timeout, WAIT_MBX); + return (OS_R_TMO); + } + /* Yes, there is a free entry in a mailbox. */ + p_MCB->msg[p_MCB->first] = p_msg; + rt_inc (&p_MCB->count); + if (++p_MCB->first == p_MCB->size) { + p_MCB->first = 0; + } + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mbx_wait -----------------------------------*/ + +OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { + /* Receive a message; possibly wait for it */ + P_MCB p_MCB = mailbox; + P_TCB p_TCB; + + /* If a message is available in the fifo buffer */ + /* remove it from the fifo buffer and return. */ + if (p_MCB->count) { + *message = p_MCB->msg[p_MCB->last]; + if (++p_MCB->last == p_MCB->size) { + p_MCB->last = 0; + } + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2)) { + /* A task is waiting to send message */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_OK); +#endif + p_MCB->msg[p_MCB->first] = p_TCB->msg; + if (++p_MCB->first == p_MCB->size) { + p_MCB->first = 0; + } + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + rt_dec (&p_MCB->count); + } + return (OS_R_OK); + } + /* No message available: wait for one */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + /* Task is waiting to receive a message */ + p_MCB->state = 1; + } + rt_block(timeout, WAIT_MBX); +#ifndef __CMSIS_RTOS + os_tsk.run->msg = message; +#endif + return (OS_R_TMO); +} + + +/*--------------------------- rt_mbx_check ----------------------------------*/ + +OS_RESULT rt_mbx_check (OS_ID mailbox) { + /* Check for free space in a mailbox. Returns the number of messages */ + /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ + P_MCB p_MCB = mailbox; + + return (p_MCB->size - p_MCB->count); +} + + +/*--------------------------- isr_mbx_send ----------------------------------*/ + +void isr_mbx_send (OS_ID mailbox, void *p_msg) { + /* Same function as "os_mbx_send", but to be called by ISRs. */ + P_MCB p_MCB = mailbox; + + rt_psq_enq (p_MCB, (U32)p_msg); + rt_psh_req (); +} + + +/*--------------------------- isr_mbx_receive -------------------------------*/ + +OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { + /* Receive a message in the interrupt function. The interrupt function */ + /* should not wait for a message since this would block the rtx os. */ + P_MCB p_MCB = mailbox; + + if (p_MCB->count) { + /* A message is available in the fifo buffer. */ + *message = p_MCB->msg[p_MCB->last]; + if (p_MCB->state == 2) { + /* A task is locked waiting to send message */ + rt_psq_enq (p_MCB, 0); + rt_psh_req (); + } + rt_dec (&p_MCB->count); + if (++p_MCB->last == p_MCB->size) { + p_MCB->last = 0; + } + return (OS_R_MBX); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mbx_psh ------------------------------------*/ + +void rt_mbx_psh (P_MCB p_CB, void *p_msg) { + /* Store the message to the mailbox queue or pass it to task directly. */ + P_TCB p_TCB; + void *mem; + + if (p_CB->p_lnk != NULL) switch (p_CB->state) { +#ifdef __CMSIS_RTOS + case 3: + /* Task is waiting to allocate memory, remove it from the waiting list */ + mem = rt_alloc_box(p_msg); + if (mem == NULL) break; + p_TCB = rt_get_first ((P_XCB)p_CB); + rt_ret_val(p_TCB, (U32)mem); + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; +#endif + case 2: + /* Task is waiting to send a message, remove it from the waiting list */ + p_TCB = rt_get_first ((P_XCB)p_CB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_OK); +#endif + p_CB->msg[p_CB->first] = p_TCB->msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0; + } + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; + case 1: + /* Task is waiting for a message, pass the message to the task directly */ + p_TCB = rt_get_first ((P_XCB)p_CB); +#ifdef __CMSIS_RTOS + rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); +#else + *p_TCB->msg = p_msg; + rt_ret_val (p_TCB, OS_R_MBX); +#endif + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; + } else { + /* No task is waiting for a message, store it to the mailbox queue */ + if (p_CB->count < p_CB->size) { + p_CB->msg[p_CB->first] = p_msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0; + } + } + else { + os_error (OS_ERR_MBX_OVF); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_Mailbox.h b/rtos/rtx/TARGET_ARM7/rt_Mailbox.h new file mode 100644 index 0000000..4862f5e --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Mailbox.h @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MAILBOX.H + * Purpose: Implements waits and wake-ups for mailbox messages + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_mbx_init (OS_ID mailbox, U16 mbx_size); +extern OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout); +extern OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout); +extern OS_RESULT rt_mbx_check (OS_ID mailbox); +extern void isr_mbx_send (OS_ID mailbox, void *p_msg); +extern OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message); +extern void rt_mbx_psh (P_MCB p_CB, void *p_msg); + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_MemBox.c b/rtos/rtx/TARGET_ARM7/rt_MemBox.c new file mode 100644 index 0000000..9b5a00f --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_MemBox.c @@ -0,0 +1,166 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMBOX.C + * Purpose: Interface functions for fixed memory block management system + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_MemBox.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- _init_box -------------------------------------*/ + +int _init_box (void *box_mem, U32 box_size, U32 blk_size) { + /* Initialize memory block system, returns 0 if OK, 1 if fails. */ + void *end; + void *blk; + void *next; + U32 sizeof_bm; + + /* Create memory structure. */ + if (blk_size & BOX_ALIGN_8) { + /* Memory blocks 8-byte aligned. */ + blk_size = ((blk_size & ~BOX_ALIGN_8) + 7) & ~7; + sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7; + } + else { + /* Memory blocks 4-byte aligned. */ + blk_size = (blk_size + 3) & ~3; + sizeof_bm = sizeof (struct OS_BM); + } + if (blk_size == 0) { + return (1); + } + if ((blk_size + sizeof_bm) > box_size) { + return (1); + } + /* Create a Memory structure. */ + blk = ((U8 *) box_mem) + sizeof_bm; + ((P_BM) box_mem)->free = blk; + end = ((U8 *) box_mem) + box_size; + ((P_BM) box_mem)->end = end; + ((P_BM) box_mem)->blk_size = blk_size; + + /* Link all free blocks using offsets. */ + end = ((U8 *) end) - blk_size; + while (1) { + next = ((U8 *) blk) + blk_size; + if (next > end) break; + *((void **)blk) = next; + blk = next; + } + /* end marker */ + *((void **)blk) = 0; + return (0); +} + +/*--------------------------- rt_alloc_box ----------------------------------*/ + +void *rt_alloc_box (void *box_mem) { + /* Allocate a memory block and return start address. */ + void **free; +#ifndef __USE_EXCLUSIVE_ACCESS + int irq_dis; + + irq_dis = __disable_irq (); + free = ((P_BM) box_mem)->free; + if (free) { + ((P_BM) box_mem)->free = *free; + } + if (!irq_dis) __enable_irq (); +#else + do { + if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0) { + __clrex(); + break; + } + } while (__strex((U32)*free, &((P_BM) box_mem)->free)); +#endif + return (free); +} + + +/*--------------------------- _calloc_box -----------------------------------*/ + +void *_calloc_box (void *box_mem) { + /* Allocate a 0-initialized memory block and return start address. */ + void *free; + U32 *p; + U32 i; + + free = _alloc_box (box_mem); + if (free) { + p = free; + for (i = ((P_BM) box_mem)->blk_size; i; i -= 4) { + *p = 0; + p++; + } + } + return (free); +} + + +/*--------------------------- rt_free_box -----------------------------------*/ + +int rt_free_box (void *box_mem, void *box) { + /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */ +#ifndef __USE_EXCLUSIVE_ACCESS + int irq_dis; +#endif + + if (box < box_mem || box >= ((P_BM) box_mem)->end) { + return (1); + } + +#ifndef __USE_EXCLUSIVE_ACCESS + irq_dis = __disable_irq (); + *((void **)box) = ((P_BM) box_mem)->free; + ((P_BM) box_mem)->free = box; + if (!irq_dis) __enable_irq (); +#else + do { + *((void **)box) = (void *)__ldrex(&((P_BM) box_mem)->free); + } while (__strex ((U32)box, &((P_BM) box_mem)->free)); +#endif + return (0); +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_MemBox.h b/rtos/rtx/TARGET_ARM7/rt_MemBox.h new file mode 100644 index 0000000..d761c41 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_MemBox.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMBOX.H + * Purpose: Interface functions for fixed memory block management system + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +#define rt_init_box _init_box +#define rt_calloc_box _calloc_box +extern int _init_box (void *box_mem, U32 box_size, U32 blk_size); +extern void *rt_alloc_box (void *box_mem); +extern void * _calloc_box (void *box_mem); +extern int rt_free_box (void *box_mem, void *box); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_Mutex.c b/rtos/rtx/TARGET_ARM7/rt_Mutex.c new file mode 100644 index 0000000..87398ad --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Mutex.c @@ -0,0 +1,197 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MUTEX.C + * Purpose: Implements mutex synchronization objects + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Mutex.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_mut_init -----------------------------------*/ + +void rt_mut_init (OS_ID mutex) { + /* Initialize a mutex object */ + P_MUCB p_MCB = mutex; + + p_MCB->cb_type = MUCB; + p_MCB->prio = 0; + p_MCB->level = 0; + p_MCB->p_lnk = NULL; + p_MCB->owner = NULL; +} + + +/*--------------------------- rt_mut_delete ---------------------------------*/ + +#ifdef __CMSIS_RTOS +OS_RESULT rt_mut_delete (OS_ID mutex) { + /* Delete a mutex object */ + P_MUCB p_MCB = mutex; + P_TCB p_TCB; + + /* Restore owner task's priority. */ + if (p_MCB->level != 0) { + p_MCB->owner->prio = p_MCB->prio; + if (p_MCB->owner != os_tsk.run) { + rt_resort_prio (p_MCB->owner); + } + } + + while (p_MCB->p_lnk != NULL) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); + rt_ret_val(p_TCB, 0/*osOK*/); + rt_rmv_dly(p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + } + + if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + /* preempt running task */ + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + + p_MCB->cb_type = 0; + + return (OS_R_OK); +} +#endif + + +/*--------------------------- rt_mut_release --------------------------------*/ + +OS_RESULT rt_mut_release (OS_ID mutex) { + /* Release a mutex object */ + P_MUCB p_MCB = mutex; + P_TCB p_TCB; + + if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { + /* Unbalanced mutex release or task is not the owner */ + return (OS_R_NOK); + } + if (--p_MCB->level != 0) { + return (OS_R_OK); + } + /* Restore owner task's priority. */ + os_tsk.run->prio = p_MCB->prio; + if (p_MCB->p_lnk != NULL) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_MUT); +#endif + rt_rmv_dly (p_TCB); + /* A waiting task becomes the owner of this mutex. */ + p_MCB->level = 1; + p_MCB->owner = p_TCB; + p_MCB->prio = p_TCB->prio; + /* Priority inversion, check which task continues. */ + if (os_tsk.run->prio >= rt_rdy_prio()) { + rt_dispatch (p_TCB); + } + else { + /* Ready task has higher priority than running task. */ + rt_put_prio (&os_rdy, os_tsk.run); + rt_put_prio (&os_rdy, p_TCB); + os_tsk.run->state = READY; + p_TCB->state = READY; + rt_dispatch (NULL); + } + } + else { + /* Check if own priority raised by priority inversion. */ + if (rt_rdy_prio() > os_tsk.run->prio) { + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mut_wait -----------------------------------*/ + +OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { + /* Wait for a mutex, continue when mutex is free. */ + P_MUCB p_MCB = mutex; + + if (p_MCB->level == 0) { + p_MCB->owner = os_tsk.run; + p_MCB->prio = os_tsk.run->prio; + goto inc; + } + if (p_MCB->owner == os_tsk.run) { + /* OK, running task is the owner of this mutex. */ +inc:p_MCB->level++; + return (OS_R_OK); + } + /* Mutex owned by another task, wait until released. */ + if (timeout == 0) { + return (OS_R_TMO); + } + /* Raise the owner task priority if lower than current priority. */ + /* This priority inversion is called priority inheritance. */ + if (p_MCB->prio < os_tsk.run->prio) { + p_MCB->owner->prio = os_tsk.run->prio; + rt_resort_prio (p_MCB->owner); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + } + rt_block(timeout, WAIT_MUT); + return (OS_R_TMO); +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_Mutex.h b/rtos/rtx/TARGET_ARM7/rt_Mutex.h new file mode 100644 index 0000000..a2f8916 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Mutex.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MUTEX.H + * Purpose: Implements mutex synchronization objects + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_mut_init (OS_ID mutex); +extern OS_RESULT rt_mut_delete (OS_ID mutex); +extern OS_RESULT rt_mut_release (OS_ID mutex); +extern OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_Robin.c b/rtos/rtx/TARGET_ARM7/rt_Robin.c new file mode 100644 index 0000000..ed58ea0 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Robin.c @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_ROBIN.C + * Purpose: Round Robin Task switching + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Time.h" +#include "rt_Robin.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +struct OS_ROBIN os_robin; + + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +/*--------------------------- rt_init_robin ---------------------------------*/ + +__weak void rt_init_robin (void) { + /* Initialize Round Robin variables. */ + os_robin.task = NULL; + os_robin.tout = (U16)os_rrobin; +} + +/*--------------------------- rt_chk_robin ----------------------------------*/ + +__weak void rt_chk_robin (void) { + /* Check if Round Robin timeout expired and switch to the next ready task.*/ + P_TCB p_new; + + if (os_robin.task != os_rdy.p_lnk) { + /* New task was suspended, reset Round Robin timeout. */ + os_robin.task = os_rdy.p_lnk; + os_robin.time = (U16)os_time + os_robin.tout - 1; + } + if (os_robin.time == (U16)os_time) { + /* Round Robin timeout has expired, swap Robin tasks. */ + os_robin.task = NULL; + p_new = rt_get_first (&os_rdy); + rt_put_prio ((P_XCB)&os_rdy, p_new); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_Robin.h b/rtos/rtx/TARGET_ARM7/rt_Robin.h new file mode 100644 index 0000000..9eebaf0 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Robin.h @@ -0,0 +1,45 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_ROBIN.H + * Purpose: Round Robin Task switching definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern struct OS_ROBIN os_robin; + +/* Functions */ +extern void rt_init_robin (void); +extern void rt_chk_robin (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_Semaphore.c b/rtos/rtx/TARGET_ARM7/rt_Semaphore.c new file mode 100644 index 0000000..5bf6525 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Semaphore.c @@ -0,0 +1,183 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SEMAPHORE.C + * Purpose: Implements binary and counting semaphores + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Semaphore.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_sem_init -----------------------------------*/ + +void rt_sem_init (OS_ID semaphore, U16 token_count) { + /* Initialize a semaphore */ + P_SCB p_SCB = semaphore; + + p_SCB->cb_type = SCB; + p_SCB->p_lnk = NULL; + p_SCB->tokens = token_count; +} + + +/*--------------------------- rt_sem_delete ---------------------------------*/ + +#ifdef __CMSIS_RTOS +OS_RESULT rt_sem_delete (OS_ID semaphore) { + /* Delete semaphore */ + P_SCB p_SCB = semaphore; + P_TCB p_TCB; + + while (p_SCB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_SCB); + rt_ret_val(p_TCB, 0); + rt_rmv_dly(p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + } + + if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + /* preempt running task */ + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + + p_SCB->cb_type = 0; + + return (OS_R_OK); +} +#endif + + +/*--------------------------- rt_sem_send -----------------------------------*/ + +OS_RESULT rt_sem_send (OS_ID semaphore) { + /* Return a token to semaphore */ + P_SCB p_SCB = semaphore; + P_TCB p_TCB; + + if (p_SCB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_SCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 1); +#else + rt_ret_val(p_TCB, OS_R_SEM); +#endif + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + /* Store token. */ + p_SCB->tokens++; + } + return (OS_R_OK); +} + + +/*--------------------------- rt_sem_wait -----------------------------------*/ + +OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) { + /* Obtain a token; possibly wait for it */ + P_SCB p_SCB = semaphore; + + if (p_SCB->tokens) { + p_SCB->tokens--; + return (OS_R_OK); + } + /* No token available: wait for one */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_SCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_SCB, os_tsk.run); + } + else { + p_SCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_SCB; + } + rt_block(timeout, WAIT_SEM); + return (OS_R_TMO); +} + + +/*--------------------------- isr_sem_send ----------------------------------*/ + +void isr_sem_send (OS_ID semaphore) { + /* Same function as "os_sem"send", but to be called by ISRs */ + P_SCB p_SCB = semaphore; + + rt_psq_enq (p_SCB, 0); + rt_psh_req (); +} + + +/*--------------------------- rt_sem_psh ------------------------------------*/ + +void rt_sem_psh (P_SCB p_CB) { + /* Check if task has to be waken up */ + P_TCB p_TCB; + + if (p_CB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_CB); + rt_rmv_dly (p_TCB); + p_TCB->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 1); +#else + rt_ret_val(p_TCB, OS_R_SEM); +#endif + rt_put_prio (&os_rdy, p_TCB); + } + else { + /* Store token */ + p_CB->tokens++; + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_Semaphore.h b/rtos/rtx/TARGET_ARM7/rt_Semaphore.h new file mode 100644 index 0000000..ed553a7 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Semaphore.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SEMAPHORE.H + * Purpose: Implements binary and counting semaphores + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_sem_init (OS_ID semaphore, U16 token_count); +extern OS_RESULT rt_sem_delete(OS_ID semaphore); +extern OS_RESULT rt_sem_send (OS_ID semaphore); +extern OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout); +extern void isr_sem_send (OS_ID semaphore); +extern void rt_sem_psh (P_SCB p_CB); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_System.c b/rtos/rtx/TARGET_ARM7/rt_System.c new file mode 100644 index 0000000..2482701 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_System.c @@ -0,0 +1,293 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SYSTEM.C + * Purpose: System Task Manager + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_Task.h" +#include "rt_System.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Mailbox.h" +#include "rt_Semaphore.h" +#include "rt_Time.h" +#include "rt_Robin.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +int os_tick_irqn; + +/*---------------------------------------------------------------------------- + * Local Variables + *---------------------------------------------------------------------------*/ + +static volatile BIT os_lock; +static volatile BIT os_psh_flag; +static U8 pend_flags; + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) +__asm void $$RTX$$version (void) { + /* Export a version number symbol for a version control. */ + + EXPORT __RL_RTX_VER + +__RL_RTX_VER EQU 0x450 +} +#endif + + +/*--------------------------- rt_suspend ------------------------------------*/ +U32 rt_suspend (void) { + /* Suspend OS scheduler */ + U32 delta = 0xFFFF; + + rt_tsk_lock(); + + if (os_dly.p_dlnk) { + delta = os_dly.delta_time; + } +#ifndef __CMSIS_RTOS + if (os_tmr.next) { + if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; + } +#endif + + return (delta); +} + + +/*--------------------------- rt_resume -------------------------------------*/ +void rt_resume (U32 sleep_time) { + /* Resume OS scheduler after suspend */ + P_TCB next; + U32 delta; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + os_robin.task = NULL; + + /* Update delays. */ + if (os_dly.p_dlnk) { + delta = sleep_time; + if (delta >= os_dly.delta_time) { + delta -= os_dly.delta_time; + os_time += os_dly.delta_time; + os_dly.delta_time = 1; + while (os_dly.p_dlnk) { + rt_dec_dly(); + if (delta == 0) break; + delta--; + os_time++; + } + } else { + os_time += delta; + os_dly.delta_time -= delta; + } + } else { + os_time += sleep_time; + } + +#ifndef __CMSIS_RTOS + /* Check the user timers. */ + if (os_tmr.next) { + delta = sleep_time; + if (delta >= os_tmr.tcnt) { + delta -= os_tmr.tcnt; + os_tmr.tcnt = 1; + while (os_tmr.next) { + rt_tmr_tick(); + if (delta == 0) break; + delta--; + } + } else { + os_tmr.tcnt -= delta; + } + } +#endif + + /* Switch back to highest ready task */ + next = rt_get_first (&os_rdy); + rt_switch_req (next); + + rt_tsk_unlock(); +} + + +/*--------------------------- rt_tsk_lock -----------------------------------*/ + +void rt_tsk_lock (void) { + /* Prevent task switching by locking out scheduler */ + OS_X_LOCK(os_tick_irqn); + os_lock = __TRUE; + OS_X_UNPEND (&pend_flags); +} + + +/*--------------------------- rt_tsk_unlock ---------------------------------*/ + +void rt_tsk_unlock (void) { + /* Unlock scheduler and re-enable task switching */ + OS_X_UNLOCK(os_tick_irqn); + os_lock = __FALSE; + OS_X_PEND (pend_flags, os_psh_flag); + os_psh_flag = __FALSE; +} + + +/*--------------------------- rt_psh_req ------------------------------------*/ + +void rt_psh_req (void) { + /* Initiate a post service handling request if required. */ + if (os_lock == __FALSE) { + OS_PEND_IRQ (); + } + else { + os_psh_flag = __TRUE; + } +} + + +/*--------------------------- rt_pop_req ------------------------------------*/ + +void rt_pop_req (void) { + /* Process an ISR post service requests. */ + struct OS_XCB *p_CB; + P_TCB next; + U32 idx; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + idx = os_psq->last; + while (os_psq->count) { + p_CB = os_psq->q[idx].id; + if (p_CB->cb_type == TCB) { + /* Is of TCB type */ + rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg); + } + else if (p_CB->cb_type == MCB) { + /* Is of MCB type */ + rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg); + } + else { + /* Must be of SCB type */ + rt_sem_psh ((P_SCB)p_CB); + } + if (++idx == os_psq->size) idx = 0; + rt_dec (&os_psq->count); + } + os_psq->last = idx; + + next = rt_get_first (&os_rdy); + rt_switch_req (next); +} + + +/*--------------------------- os_tick_init ----------------------------------*/ + +__weak int os_tick_init (void) { + /* Initialize SysTick timer as system tick timer. */ + rt_systick_init (); + return (SYS_TICK_IRQn); /* Return IRQ number of SysTick timer */ +} + + +/*--------------------------- os_tick_irqack --------------------------------*/ + +__weak void os_tick_irqack (void) { + /* Acknowledge timer interrupt. */ +} + + +/*--------------------------- rt_systick ------------------------------------*/ + +extern void sysTimerTick(void); + +void rt_systick (void) { + if(NVIC_Pending(SYS_TICK_IRQn)){ + rt_pop_req(); + NVIC_UnpendIRQ(SYS_TICK_IRQn); + SYS_TICK_TIMER->IR = 0xF; // clear timer interrupt + return; + } + /* Check for system clock update, suspend running task. */ + P_TCB next; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + /* Check Round Robin timeout. */ + rt_chk_robin (); + + /* Update delays. */ + os_time++; + rt_dec_dly (); + + /* Check the user timers. */ +#ifdef __CMSIS_RTOS + sysTimerTick(); +#else + rt_tmr_tick (); +#endif + + /* Switch back to highest ready task */ + next = rt_get_first (&os_rdy); + rt_switch_req (next); + SYS_TICK_TIMER->IR = 0xF; // clear timer interrupt +} + +/*--------------------------- rt_stk_check ----------------------------------*/ +__weak void rt_stk_check (void) { + /* Check for stack overflow. */ + if (os_tsk.run->task_id == 0x01) { + // TODO: For the main thread the check should be done against the main heap pointer + } else { + if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || + (os_tsk.run->stack[0] != MAGIC_WORD)) { + os_error (OS_ERR_STK_OVF); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_System.h b/rtos/rtx/TARGET_ARM7/rt_System.h new file mode 100644 index 0000000..e73ef4d --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_System.h @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SYSTEM.H + * Purpose: System Task Manager definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Variables */ +#define os_psq ((P_PSQ)&os_fifo) +extern int os_tick_irqn; + +/* Functions */ +extern U32 rt_suspend (void); +extern void rt_resume (U32 sleep_time); +extern void rt_tsk_lock (void); +extern void rt_tsk_unlock (void); +extern void rt_psh_req (void); +extern void rt_pop_req (void); +extern void rt_systick (void); +extern void rt_stk_check (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_Task.c b/rtos/rtx/TARGET_ARM7/rt_Task.c new file mode 100644 index 0000000..d9e4d3f --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Task.c @@ -0,0 +1,341 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TASK.C + * Purpose: Task functions and system start up. + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_List.h" +#include "rt_MemBox.h" +#include "rt_Robin.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* Running and next task info. */ +struct OS_TSK os_tsk; + +/* Task Control Blocks of idle demon */ +struct OS_TCB os_idle_TCB; + + +/*---------------------------------------------------------------------------- + * Local Functions + *---------------------------------------------------------------------------*/ + +OS_TID rt_get_TID (void) { + U32 tid; + + for (tid = 1; tid <= os_maxtaskrun; tid++) { + if (os_active_TCB[tid-1] == NULL) { + return ((OS_TID)tid); + } + } + return (0); +} + +#if defined (__CC_ARM) && !defined (__MICROLIB) +/*--------------------------- __user_perthread_libspace ---------------------*/ +extern void *__libspace_start; + +void *__user_perthread_libspace (void) { + /* Provide a separate libspace for each task. */ + if (os_tsk.run == NULL) { + /* RTX not running yet. */ + return (&__libspace_start); + } + return (void *)(os_tsk.run->std_libspace); +} +#endif + +/*--------------------------- rt_init_context -------------------------------*/ + +void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) { + /* Initialize general part of the Task Control Block. */ + p_TCB->cb_type = TCB; + p_TCB->state = READY; + p_TCB->prio = priority; + p_TCB->p_lnk = NULL; + p_TCB->p_rlnk = NULL; + p_TCB->p_dlnk = NULL; + p_TCB->p_blnk = NULL; + p_TCB->delta_time = 0; + p_TCB->interval_time = 0; + p_TCB->events = 0; + p_TCB->waits = 0; + p_TCB->stack_frame = 0; + + rt_init_stack (p_TCB, task_body); +} + + +/*--------------------------- rt_switch_req ---------------------------------*/ + +void rt_switch_req (P_TCB p_new) { + /* Switch to next task (identified by "p_new"). */ + os_tsk.new_tsk = p_new; + p_new->state = RUNNING; + DBG_TASK_SWITCH(p_new->task_id); +} + + +/*--------------------------- rt_dispatch -----------------------------------*/ + +void rt_dispatch (P_TCB next_TCB) { + /* Dispatch next task if any identified or dispatch highest ready task */ + /* "next_TCB" identifies a task to run or has value NULL (=no next task) */ + if (next_TCB == NULL) { + /* Running task was blocked: continue with highest ready task */ + next_TCB = rt_get_first (&os_rdy); + rt_switch_req (next_TCB); + } + else { + /* Check which task continues */ + if (next_TCB->prio > os_tsk.run->prio) { + /* preempt running task */ + rt_put_rdy_first (os_tsk.run); + os_tsk.run->state = READY; + rt_switch_req (next_TCB); + } + else { + /* put next task into ready list, no task switch takes place */ + next_TCB->state = READY; + rt_put_prio (&os_rdy, next_TCB); + } + } +} + + +/*--------------------------- rt_block --------------------------------------*/ + +void rt_block (U16 timeout, U8 block_state) { + /* Block running task and choose next ready task. */ + /* "timeout" sets a time-out value or is 0xffff (=no time-out). */ + /* "block_state" defines the appropriate task state */ + P_TCB next_TCB; + + if (timeout) { + if (timeout < 0xffff) { + rt_put_dly (os_tsk.run, timeout); + } + os_tsk.run->state = block_state; + next_TCB = rt_get_first (&os_rdy); + rt_switch_req (next_TCB); + } +} + + +/*--------------------------- rt_tsk_pass -----------------------------------*/ + +void rt_tsk_pass (void) { + /* Allow tasks of same priority level to run cooperatively.*/ + P_TCB p_new; + + p_new = rt_get_same_rdy_prio(); + if (p_new != NULL) { + rt_put_prio ((P_XCB)&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_switch_req (p_new); + } +} + + +/*--------------------------- rt_tsk_self -----------------------------------*/ + +OS_TID rt_tsk_self (void) { + /* Return own task identifier value. */ + if (os_tsk.run == NULL) { + return (0); + } + return (os_tsk.run->task_id); +} + + +/*--------------------------- rt_tsk_prio -----------------------------------*/ + +OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) { + /* Change execution priority of a task to "new_prio". */ + P_TCB p_task; + + if (task_id == 0) { + /* Change execution priority of calling task. */ + os_tsk.run->prio = new_prio; +run:if (rt_rdy_prio() > new_prio) { + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + return (OS_R_OK); + } + + /* Find the task in the "os_active_TCB" array. */ + if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + /* Task with "task_id" not found or not started. */ + return (OS_R_NOK); + } + p_task = os_active_TCB[task_id-1]; + p_task->prio = new_prio; + if (p_task == os_tsk.run) { + goto run; + } + rt_resort_prio (p_task); + if (p_task->state == READY) { + /* Task enqueued in a ready list. */ + p_task = rt_get_first (&os_rdy); + rt_dispatch (p_task); + } + return (OS_R_OK); +} + +/*--------------------------- rt_tsk_delete ---------------------------------*/ + +OS_RESULT rt_tsk_delete (OS_TID task_id) { + /* Terminate the task identified with "task_id". */ + P_TCB task_context; + + if (task_id == 0 || task_id == os_tsk.run->task_id) { + /* Terminate itself. */ + os_tsk.run->state = INACTIVE; + os_tsk.run->tsk_stack = 0; + rt_stk_check (); + os_active_TCB[os_tsk.run->task_id-1] = NULL; + + os_tsk.run->stack = NULL; + DBG_TASK_NOTIFY(os_tsk.run, __FALSE); + os_tsk.run = NULL; + rt_dispatch (NULL); + /* The program should never come to this point. */ + } + else { + /* Find the task in the "os_active_TCB" array. */ + if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + /* Task with "task_id" not found or not started. */ + return (OS_R_NOK); + } + task_context = os_active_TCB[task_id-1]; + rt_rmv_list (task_context); + rt_rmv_dly (task_context); + os_active_TCB[task_id-1] = NULL; + + task_context->stack = NULL; + DBG_TASK_NOTIFY(task_context, __FALSE); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_sys_init -----------------------------------*/ + +#ifdef __CMSIS_RTOS +void rt_sys_init (void) { +#else +void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { +#endif + /* Initialize system and start up task declared with "first_task". */ + U32 i; + + DBG_INIT(); + + /* Initialize dynamic memory and task TCB pointers to NULL. */ + for (i = 0; i < os_maxtaskrun; i++) { + os_active_TCB[i] = NULL; + } + + /* Set up TCB of idle demon */ + os_idle_TCB.task_id = 255; + os_idle_TCB.priv_stack = idle_task_stack_size; + os_idle_TCB.stack = idle_task_stack; + rt_init_context (&os_idle_TCB, 0, os_idle_demon); + + /* Set up ready list: initially empty */ + os_rdy.cb_type = HCB; + os_rdy.p_lnk = NULL; + /* Set up delay list: initially empty */ + os_dly.cb_type = HCB; + os_dly.p_dlnk = NULL; + os_dly.p_blnk = NULL; + os_dly.delta_time = 0; + + /* Fix SP and systemvariables to assume idle task is running */ + /* Transform main program into idle task by assuming idle TCB */ +#ifndef __CMSIS_RTOS + rt_set_PSP (os_idle_TCB.tsk_stack); +#endif + os_tsk.run = &os_idle_TCB; + os_tsk.run->state = RUNNING; + + /* Initialize ps queue */ + os_psq->first = 0; + os_psq->last = 0; + os_psq->size = os_fifo_size; + + rt_init_robin (); + + /* Intitialize SVC and PendSV */ + rt_svc_init (); + +#ifndef __CMSIS_RTOS + /* Intitialize and start system clock timer */ + os_tick_irqn = os_tick_init (); + if (os_tick_irqn >= 0) { + OS_X_INIT(os_tick_irqn); + } + + /* Start up first user task before entering the endless loop */ + rt_tsk_create (first_task, prio_stksz, stk, NULL); +#endif +} + + +/*--------------------------- rt_sys_start ----------------------------------*/ + +#ifdef __CMSIS_RTOS +void rt_sys_start (void) { + /* Start system */ + + /* Intitialize and start system clock timer */ + os_tick_irqn = os_tick_init (); + if (os_tick_irqn >= 0) { + OS_X_INIT(os_tick_irqn); + } + extern void RestoreContext(); + RestoreContext(); // Start the first task +} +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_ARM7/rt_Task.h b/rtos/rtx/TARGET_ARM7/rt_Task.h new file mode 100644 index 0000000..0e70c78 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Task.h @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TASK.H + * Purpose: Task functions and system start up. + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Definitions */ +#define __CMSIS_RTOS 1 + +/* Values for 'state' */ +#define INACTIVE 0 +#define READY 1 +#define RUNNING 2 +#define WAIT_DLY 3 +#define WAIT_ITV 4 +#define WAIT_OR 5 +#define WAIT_AND 6 +#define WAIT_SEM 7 +#define WAIT_MBX 8 +#define WAIT_MUT 9 + +/* Return codes */ +#define OS_R_TMO 0x01 +#define OS_R_EVT 0x02 +#define OS_R_SEM 0x03 +#define OS_R_MBX 0x04 +#define OS_R_MUT 0x05 + +#define OS_R_OK 0x00 +#define OS_R_NOK 0xff + +/* Variables */ +extern struct OS_TSK os_tsk; +extern struct OS_TCB os_idle_TCB; + +/* Functions */ +extern void rt_switch_req (P_TCB p_new); +extern void rt_dispatch (P_TCB next_TCB); +extern void rt_block (U16 timeout, U8 block_state); +extern void rt_tsk_pass (void); +extern OS_TID rt_tsk_self (void); +extern OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio); +extern OS_RESULT rt_tsk_delete (OS_TID task_id); +extern void rt_sys_init (void); +extern void rt_sys_start (void); diff --git a/rtos/rtx/TARGET_ARM7/rt_Time.c b/rtos/rtx/TARGET_ARM7/rt_Time.c new file mode 100644 index 0000000..075f2e5 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Time.c @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIME.C + * Purpose: Delay and interval wait functions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_Task.h" +#include "rt_Time.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* Free running system tick counter */ +U32 os_time; + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_time_get -----------------------------------*/ + +U32 rt_time_get (void) { + /* Get system time tick */ + return (os_time); +} + + +/*--------------------------- rt_dly_wait -----------------------------------*/ + +void rt_dly_wait (U16 delay_time) { + /* Delay task by "delay_time" */ + rt_block (delay_time, WAIT_DLY); +} + + +/*--------------------------- rt_itv_set ------------------------------------*/ + +void rt_itv_set (U16 interval_time) { + /* Set interval length and define start of first interval */ + os_tsk.run->interval_time = interval_time; + os_tsk.run->delta_time = interval_time + (U16)os_time; +} + + +/*--------------------------- rt_itv_wait -----------------------------------*/ + +void rt_itv_wait (void) { + /* Wait for interval end and define start of next one */ + U16 delta; + + delta = os_tsk.run->delta_time - (U16)os_time; + os_tsk.run->delta_time += os_tsk.run->interval_time; + if ((delta & 0x8000) == 0) { + rt_block (delta, WAIT_ITV); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_Time.h b/rtos/rtx/TARGET_ARM7/rt_Time.h new file mode 100644 index 0000000..addac58 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_Time.h @@ -0,0 +1,47 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIME.H + * Purpose: Delay and interval wait functions definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern U32 os_time; + +/* Functions */ +extern U32 rt_time_get (void); +extern void rt_dly_wait (U16 delay_time); +extern void rt_itv_set (U16 interval_time); +extern void rt_itv_wait (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_ARM7/rt_TypeDef.h b/rtos/rtx/TARGET_ARM7/rt_TypeDef.h new file mode 100644 index 0000000..33ed708 --- /dev/null +++ b/rtos/rtx/TARGET_ARM7/rt_TypeDef.h @@ -0,0 +1,128 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TYPEDEF.H + * Purpose: Type Definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 RT_TYPE_DEF_H +#define RT_TYPE_DEF_H + +#include "os_tcb.h" + +typedef U32 OS_TID; +typedef void *OS_ID; +typedef U32 OS_RESULT; + +#define TCB_STACKF 32 /* 'stack_frame' offset */ +#define TCB_TSTACK 40 /* 'tsk_stack' offset */ + +typedef struct OS_PSFE { /* Post Service Fifo Entry */ + void *id; /* Object Identification */ + U32 arg; /* Object Argument */ +} *P_PSFE; + +typedef struct OS_PSQ { /* Post Service Queue */ + U8 first; /* FIFO Head Index */ + U8 last; /* FIFO Tail Index */ + U8 count; /* Number of stored items in FIFO */ + U8 size; /* FIFO Size */ + struct OS_PSFE q[1]; /* FIFO Content */ +} *P_PSQ; + +typedef struct OS_TSK { + P_TCB run; /* Current running task */ + P_TCB new_tsk; /* Scheduled task to run */ +} *P_TSK; + +typedef struct OS_ROBIN { /* Round Robin Control */ + P_TCB task; /* Round Robin task */ + U16 time; /* Round Robin switch time */ + U16 tout; /* Round Robin timeout */ +} *P_ROBIN; + +typedef struct OS_XCB { + U8 cb_type; /* Control Block Type */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ +} *P_XCB; + +typedef struct OS_MCB { + U8 cb_type; /* Control Block Type */ + U8 state; /* State flag variable */ + U8 isr_st; /* State flag variable for isr functions */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for message */ + U16 first; /* Index of the message list begin */ + U16 last; /* Index of the message list end */ + U16 count; /* Actual number of stored messages */ + U16 size; /* Maximum number of stored messages */ + void *msg[1]; /* FIFO for Message pointers 1st element */ +} *P_MCB; + +typedef struct OS_SCB { + U8 cb_type; /* Control Block Type */ + U8 mask; /* Semaphore token mask */ + U16 tokens; /* Semaphore tokens */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for tokens */ +} *P_SCB; + +typedef struct OS_MUCB { + U8 cb_type; /* Control Block Type */ + U8 prio; /* Owner task default priority */ + U16 level; /* Call nesting level */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for mutex */ + struct OS_TCB *owner; /* Mutex owner task */ +} *P_MUCB; + +typedef struct OS_XTMR { + struct OS_TMR *next; + U16 tcnt; +} *P_XTMR; + +typedef struct OS_TMR { + struct OS_TMR *next; /* Link pointer to Next timer */ + U16 tcnt; /* Timer delay count */ + U16 info; /* User defined call info */ +} *P_TMR; + +typedef struct OS_BM { + void *free; /* Pointer to first free memory block */ + void *end; /* Pointer to memory block end */ + U32 blk_size; /* Memory block size */ +} *P_BM; + +/* Definitions */ +#define __TRUE 1 +#define __FALSE 0 +#define NULL ((void *) 0) + +#endif diff --git a/rtos/rtx/TARGET_CORTEX_A/HAL_CA.c b/rtos/rtx/TARGET_CORTEX_A/HAL_CA.c new file mode 100644 index 0000000..295a64f --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/HAL_CA.c @@ -0,0 +1,126 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CA.C + * Purpose: Hardware Abstraction Layer for Cortex-A + * Rev.: + *---------------------------------------------------------------------------- + * + * Copyright (c) 2012 ARM Limited + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_HAL_CA.h" + +/*--------------------------- os_init_context -------------------------------*/ + +void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { + /* Prepare TCB and saved context for a first time start of a task. */ + U32 *stk,i,size; + + /* Prepare a complete interrupt frame for first task start */ + size = p_TCB->priv_stack >> 2; + if (size == 0) { + size = (U16)os_stackinfo >> 2; + } + /* Write to the top of stack. */ + stk = &p_TCB->stack[size]; + + /* Auto correct to 8-byte ARM stack alignment. */ + if ((U32)stk & 0x04) { + stk--; + } + + stk -= 16; + + /* Initial PC and default CPSR */ + stk[14] = (U32)task_body; + /* Task run mode is inherited from the startup file. */ + /* (non-privileged USER or privileged SYSTEM mode) */ + stk[15] = (os_flags & 1) ? INIT_CPSR_SYS : INIT_CPSR_USER; + /* Set T-bit if task function in Thumb mode. */ + if ((U32)task_body & 1) { + stk[15] |= CPSR_T_BIT; + } + /* Assign a void pointer to R0. */ + stk[8] = (U32)p_TCB->msg; + /* Clear R1-R12,LR registers. */ + for (i = 0; i < 8; i++) { + stk[i] = 0; + } + for (i = 9; i < 14; i++) { + stk[i] = 0; + } + + /* Initial Task stack pointer. */ + p_TCB->tsk_stack = (U32)stk; + + /* Task entry point. */ + p_TCB->ptask = task_body; + + /* Set a magic word for checking of stack overflow. */ + p_TCB->stack[0] = MAGIC_WORD; +} + + +/*--------------------------- rt_ret_val ----------------------------------*/ + +static __inline U32 *rt_ret_regs (P_TCB p_TCB) { + /* Get pointer to task return value registers (R0..R3) in Stack */ +#if (__TARGET_FPU_VFP) + if (p_TCB->stack_frame & 0x2) { + /* Extended Stack Frame: S0-31,FPSCR,Reserved,R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4 + 34*4); + } else { + /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4); + } +#else + /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4); +#endif +} + +void rt_ret_val (P_TCB p_TCB, U32 v0) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; +} + +void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; + ret[1] = v1; +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_A/RTX_CM_lib.h b/rtos/rtx/TARGET_CORTEX_A/RTX_CM_lib.h new file mode 100644 index 0000000..3d95aac --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/RTX_CM_lib.h @@ -0,0 +1,407 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_CM_LIB.H + * Purpose: RTX Kernel System Configuration + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) +#pragma O3 +#define __USED __attribute__((used)) +#elif defined (__GNUC__) +#pragma GCC optimize ("O3") +#define __USED __attribute__((used)) +#elif defined (__ICCARM__) +#define __USED __root +#endif + + +/*---------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3] +#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2] + +#define OS_TCB_SIZE 48 +#define OS_TMR_SIZE 8 + +#if defined (__CC_ARM) && !defined (__MICROLIB) + +typedef void *OS_ID; +typedef uint32_t OS_TID; +typedef uint32_t OS_MUT[3]; +typedef uint32_t OS_RESULT; + +#define runtask_id() rt_tsk_self() +#define mutex_init(m) rt_mut_init(m) +#define mutex_wait(m) os_mut_wait(m,0xFFFF) +#define mutex_rel(m) os_mut_release(m) + +extern OS_TID rt_tsk_self (void); +extern void rt_mut_init (OS_ID mutex); +extern OS_RESULT rt_mut_release (OS_ID mutex); +extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout); + +#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout) +#define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex) + +OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0); +OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0); + +#endif + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +#if (OS_TIMERS != 0) +#define OS_TASK_CNT (OS_TASKCNT + 1) +#ifndef __MBED_CMSIS_RTOS_CA9 +#define OS_PRIV_CNT (OS_PRIVCNT + 2) +#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ)) +#endif +#else +#define OS_TASK_CNT OS_TASKCNT +#ifndef __MBED_CMSIS_RTOS_CA9 +#define OS_PRIV_CNT (OS_PRIVCNT + 1) +#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE)) +#endif +#endif + +uint16_t const os_maxtaskrun = OS_TASK_CNT; +#ifdef __MBED_CMSIS_RTOS_CA9 +uint32_t const os_stackinfo = (OS_STKCHECK<<24)| (OS_IDLESTKSIZE*4); +#else +uint32_t const os_stackinfo = (OS_STKCHECK<<24)| (OS_PRIV_CNT<<16) | (OS_STKSIZE*4); +#endif +uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT; +uint32_t const os_trv = OS_TRV; +uint8_t const os_flags = OS_RUNPRIV; + +/* Export following defines to uVision debugger. */ +__USED uint32_t const os_clockrate = OS_TICK; +__USED uint32_t const os_timernum = 0; + +/* Memory pool for TCB allocation */ +_declare_box (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT); +uint16_t const mp_tcb_size = sizeof(mp_tcb); + +#ifdef __MBED_CMSIS_RTOS_CA9 +/* Memory pool for os_idle_demon stack allocation. */ +_declare_box8 (mp_stk, OS_IDLESTKSIZE*4, 1); +uint32_t const mp_stk_size = sizeof(mp_stk); +#else +/* Memory pool for System stack allocation (+os_idle_demon). */ +_declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1); +uint32_t const mp_stk_size = sizeof(mp_stk); + +/* Memory pool for user specified stack allocation (+main, +timer) */ +uint64_t os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)]; +uint32_t const os_stack_sz = sizeof(os_stack_mem); +#endif + +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +/* Fifo Queue buffer for ISR requests.*/ +uint32_t os_fifo[OS_FIFOSZ*2+1]; +uint8_t const os_fifo_size = OS_FIFOSZ; + +/* An array of Active task pointers. */ +void *os_active_TCB[OS_TASK_CNT]; + +/* User Timers Resources */ +#if (OS_TIMERS != 0) +extern void osTimerThread (void const *argument); +#ifdef __MBED_CMSIS_RTOS_CA9 +osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ); +#else +osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ); +#endif +osThreadId osThreadId_osTimerThread; +osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *); +osMessageQId osMessageQId_osTimerMessageQ; +#else +osThreadDef_t os_thread_def_osTimerThread = { NULL }; +osThreadId osThreadId_osTimerThread; +osMessageQDef(osTimerMessageQ, 0, void *); +osMessageQId osMessageQId_osTimerMessageQ; +#endif + +/* Legacy RTX User Timers not used */ +uint32_t os_tmr = 0; +uint32_t const *m_tmr = NULL; +uint16_t const mp_tmr_size = 0; + +#if defined (__CC_ARM) && !defined (__MICROLIB) + /* A memory space for arm standard library. */ + static uint32_t std_libspace[OS_TASK_CNT][96/4]; + static OS_MUT std_libmutex[OS_MUTEXCNT]; + static uint32_t nr_mutex; + extern void *__libspace_start; +#endif + + +/*---------------------------------------------------------------------------- + * RTX Optimizations (empty functions) + *---------------------------------------------------------------------------*/ + +#if OS_ROBIN == 0 + void rt_init_robin (void) {;} + void rt_chk_robin (void) {;} +#endif + +#if OS_STKCHECK == 0 + void rt_stk_check (void) {;} +#endif + + +/*---------------------------------------------------------------------------- + * Standard Library multithreading interface + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) && !defined (__MICROLIB) + +/*--------------------------- __user_perthread_libspace ---------------------*/ + +void *__user_perthread_libspace (void) { + /* Provide a separate libspace for each task. */ + uint32_t idx; + + idx = runtask_id (); + if (idx == 0) { + /* RTX not running yet. */ + return (&__libspace_start); + } + return ((void *)&std_libspace[idx-1]); +} + +/*--------------------------- _mutex_initialize -----------------------------*/ + +int _mutex_initialize (OS_ID *mutex) { + /* Allocate and initialize a system mutex. */ + + if (nr_mutex >= OS_MUTEXCNT) { + /* If you are here, you need to increase the number OS_MUTEXCNT. */ + for (;;); + } + *mutex = &std_libmutex[nr_mutex++]; + mutex_init (*mutex); + return (1); +} + + +/*--------------------------- _mutex_acquire --------------------------------*/ + +__attribute__((used)) void _mutex_acquire (OS_ID *mutex) { + /* Acquire a system mutex, lock stdlib resources. */ + if (runtask_id ()) { + /* RTX running, acquire a mutex. */ + mutex_wait (*mutex); + } +} + + +/*--------------------------- _mutex_release --------------------------------*/ + +__attribute__((used)) void _mutex_release (OS_ID *mutex) { + /* Release a system mutex, unlock stdlib resources. */ + if (runtask_id ()) { + /* RTX running, release a mutex. */ + mutex_rel (*mutex); + } +} + +#endif + + +/*---------------------------------------------------------------------------- + * RTX Startup + *---------------------------------------------------------------------------*/ + +/* Main Thread definition */ +extern int main (void); +#ifdef __MBED_CMSIS_RTOS_CA9 +uint32_t os_thread_def_stack_main [(4 * OS_MAINSTKSIZE) / sizeof(uint32_t)]; +osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE, os_thread_def_stack_main }; +#else +osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE }; +#endif + + +#if defined (__CC_ARM) + +#ifdef __MICROLIB +void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); +#if __TARGET_ARCH_ARM +#pragma push +#pragma arm +#endif +void _main_init (void) { + osKernelInitialize(); + osThreadCreate(&os_thread_def_main, NULL); + osKernelStart(); + for (;;); +} +#if __TARGET_ARCH_ARM +#pragma pop +#endif +#else +__asm void __rt_entry (void) { + + IMPORT __user_setup_stackheap + IMPORT __rt_lib_init + IMPORT os_thread_def_main + IMPORT osKernelInitialize + IMPORT osKernelStart + IMPORT osThreadCreate + IMPORT exit + + BL __user_setup_stackheap + MOV R1,R2 + BL __rt_lib_init + BL osKernelInitialize + LDR R0,=os_thread_def_main + MOVS R1,#0 + BL osThreadCreate + BL osKernelStart + BL exit + + ALIGN +} +#endif + +#elif defined (__GNUC__) + +#ifdef __CS3__ + +/* CS3 start_c routine. + * + * Copyright (c) 2006, 2007 CodeSourcery Inc + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include "cs3.h" + +extern void __libc_init_array (void); + +__attribute ((noreturn)) void __cs3_start_c (void){ + unsigned regions = __cs3_region_num; + const struct __cs3_region *rptr = __cs3_regions; + + /* Initialize memory */ + for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) { + long long *src = (long long *)rptr->init; + long long *dst = (long long *)rptr->data; + unsigned limit = rptr->init_size; + unsigned count; + + if (src != dst) + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = *src++; + else + dst = (long long *)((char *)dst + limit); + limit = rptr->zero_size; + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = 0; + } + + /* Run initializers. */ + __libc_init_array (); + + osKernelInitialize(); + osThreadCreate(&os_thread_def_main, NULL); + osKernelStart(); + for (;;); +} + +#else + +__attribute__((naked)) void software_init_hook (void) { + __asm ( + ".syntax unified\n" + ".arm\n" + "movs r0,#0\n" + "movs r1,#0\n" + "mov r4,r0\n" + "mov r5,r1\n" + "ldr r0,= __libc_fini_array\n" + "bl atexit\n" + "bl __libc_init_array\n" + "mov r0,r4\n" + "mov r1,r5\n" + "bl osKernelInitialize\n" + "ldr r0,=os_thread_def_main\n" + "movs r1,#0\n" + "bl osThreadCreate\n" + "bl osKernelStart\n" + "bl exit\n" + ); +} + +#endif + +#elif defined (__ICCARM__) + +extern int __low_level_init(void); +extern void __iar_data_init3(void); +extern void exit(int arg); + +__noreturn __stackless void __cmain(void) { + int a; + + if (__low_level_init() != 0) { + __iar_data_init3(); + } + osKernelInitialize(); + osThreadCreate(&os_thread_def_main, NULL); + a = osKernelStart(); + exit(a); +} + +#endif + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c b/rtos/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c new file mode 100644 index 0000000..78863e8 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/RTX_Conf_CA.c @@ -0,0 +1,329 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_Conf_CM.C + * Purpose: Configuration of CMSIS RTX Kernel + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "cmsis_os.h" + +/*---------------------------------------------------------------------------- + * RTX User configuration part BEGIN + *---------------------------------------------------------------------------*/ + +//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- +// +// Thread Configuration +// ======================= +// +// Number of concurrent running threads <0-250> +// Defines max. number of threads that will run at the same time. +// Default: 6 +#ifndef OS_TASKCNT + #define OS_TASKCNT 25 +#endif + +#ifdef __MBED_CMSIS_RTOS_CA9 +// Idle stack size [bytes] <64-4096:8><#/4> +// Defines default stack size for the Idle thread. +#ifndef OS_IDLESTKSIZE + #define OS_IDLESTKSIZE 128 +#endif +#else // __MBED_CMSIS_RTOS_CA9 +// Default Thread stack size [bytes] <64-4096:8><#/4> +// Defines default stack size for threads with osThreadDef stacksz = 0 +// Default: 200 +#ifndef OS_STKSIZE + #define OS_STKSIZE 200 +#endif +#endif // __MBED_CMSIS_RTOS_CA9 + +// Main Thread stack size [bytes] <64-4096:8><#/4> +// Defines stack size for main thread. +// Default: 200 +#ifndef OS_MAINSTKSIZE + #define OS_MAINSTKSIZE 2048 +#endif + +#ifndef __MBED_CMSIS_RTOS_CA9 +// Number of threads with user-provided stack size <0-250> +// Defines the number of threads with user-provided stack size. +// Default: 0 +#ifndef OS_PRIVCNT + #define OS_PRIVCNT 0 +#endif + +// Total stack size [bytes] for threads with user-provided stack size <0-4096:8><#/4> +// Defines the combined stack size for threads with user-provided stack size. +// Default: 0 +#ifndef OS_PRIVSTKSIZE + #define OS_PRIVSTKSIZE 0 +#endif +#endif // __MBED_CMSIS_RTOS_CA9 + +// Check for stack overflow +// Includes the stack checking code for stack overflow. +// Note that additional code reduces the Kernel performance. +#ifndef OS_STKCHECK + #define OS_STKCHECK 1 +#endif + +// Processor mode for thread execution +// <0=> Unprivileged mode +// <1=> Privileged mode +// Default: Privileged mode +#ifndef OS_RUNPRIV + #define OS_RUNPRIV 1 +#endif + +// + +// RTX Kernel Timer Tick Configuration +// ====================================== +// Use Cortex-M SysTick timer as RTX Kernel Timer +// Use the Cortex-M SysTick timer as a time-base for RTX. +#ifndef OS_SYSTICK + #define OS_SYSTICK 0 +#endif +// +// Timer clock value [Hz] <1-1000000000> +// Defines the timer clock value. +// Default: 12000000 (12MHz) +#ifndef OS_CLOCK +# if defined(TARGET_RZ_A1H) + #define OS_CLOCK 12000000 +# else +# error "no target defined" +# endif +#endif + +// Timer tick value [us] <1-1000000> +// Defines the timer tick value. +// Default: 1000 (1ms) +#ifndef OS_TICK + #define OS_TICK 1000 +#endif + +// + +// System Configuration +// ======================= +// +// Round-Robin Thread switching +// =============================== +// +// Enables Round-Robin Thread switching. +#ifndef OS_ROBIN + #define OS_ROBIN 1 +#endif + +// Round-Robin Timeout [ticks] <1-1000> +// Defines how long a thread will execute before a thread switch. +// Default: 5 +#ifndef OS_ROBINTOUT + #define OS_ROBINTOUT 5 +#endif + +// + +// User Timers +// ============== +// Enables user Timers +#ifndef OS_TIMERS + #define OS_TIMERS 1 +#endif + +// Timer Thread Priority +// <1=> Low +// <2=> Below Normal <3=> Normal <4=> Above Normal +// <5=> High +// <6=> Realtime (highest) +// Defines priority for Timer Thread +// Default: High +#ifndef OS_TIMERPRIO + #define OS_TIMERPRIO 5 +#endif + +// Timer Thread stack size [bytes] <64-4096:8><#/4> +// Defines stack size for Timer thread. +// Default: 200 +#ifndef OS_TIMERSTKSZ + #define OS_TIMERSTKSZ WORDS_STACK_SIZE +#endif + +// Timer Callback Queue size <1-32> +// Number of concurrent active timer callback functions. +// Default: 4 +#ifndef OS_TIMERCBQS + #define OS_TIMERCBQS 4 +#endif + +// + +// ISR FIFO Queue size<4=> 4 entries <8=> 8 entries +// <12=> 12 entries <16=> 16 entries +// <24=> 24 entries <32=> 32 entries +// <48=> 48 entries <64=> 64 entries +// <96=> 96 entries +// ISR functions store requests to this buffer, +// when they are called from the interrupt handler. +// Default: 16 entries +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +// + +//------------- <<< end of configuration section >>> ----------------------- + +// Standard library system mutexes +// =============================== +// Define max. number system mutexes that are used to protect +// the arm standard runtime library. For microlib they are not used. +#ifndef OS_MUTEXCNT + #define OS_MUTEXCNT 12 +#endif + +/*---------------------------------------------------------------------------- + * RTX User configuration part END + *---------------------------------------------------------------------------*/ + +#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) + + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +/*--------------------------- os_idle_demon ---------------------------------*/ + +void os_idle_demon (void) { + /* The idle demon is a system thread, running when no other thread is */ + /* ready to run. */ + + for (;;) { + /* HERE: include optional user code to be executed when no thread runs.*/ + } +} + +#if (OS_SYSTICK == 0) // Functions for alternative timer as RTX kernel timer + +/*--------------------------- os_tick_init ----------------------------------*/ +#ifdef TARGET_RZ_A1H +#define OSTM0 (0xFCFEC000uL) /* OSTM0 */ +#define OSTM1 (0xFCFEC400uL) /* OSTM1 */ +#define CPG (0xFCFE0410uL) /* CPG */ + +#define CPGSTBCR5 (*((volatile unsigned char*)(CPG + 0x00000018uL))) + +#define OSTM0CMP (*((volatile unsigned long*)(OSTM0 + 0x00000000uL))) +#define OSTM0CNT (*((volatile unsigned long*)(OSTM0 + 0x00000004uL))) +#define OSTM0TE (*((volatile unsigned char*)(OSTM0 + 0x00000010uL))) +#define OSTM0TS (*((volatile unsigned char*)(OSTM0 + 0x00000014uL))) +#define OSTM0TT (*((volatile unsigned char*)(OSTM0 + 0x00000018uL))) +#define OSTM0CTL (*((volatile unsigned char*)(OSTM0 + 0x00000020uL))) + +#define OSTM1CMP (*((volatile unsigned long*)(OSTM1 + 0x00000000uL))) +#define OSTM1CNT (*((volatile unsigned long*)(OSTM1 + 0x00000004uL))) +#define OSTM1TE (*((volatile unsigned char*)(OSTM1 + 0x00000010uL))) +#define OSTM1TS (*((volatile unsigned char*)(OSTM1 + 0x00000014uL))) +#define OSTM1TT (*((volatile unsigned char*)(OSTM1 + 0x00000018uL))) +#define OSTM1CTL (*((volatile unsigned char*)(OSTM1 + 0x00000020uL))) + +#define CPG_STBCR5_BIT_MSTP51 (0x02u) /* OSTM0 */ +#define CM1_RENESAS_RZ_A1_P0_CLK ( 32000000u) +#define CM0_RENESAS_RZ_A1_P0_CLK ( 33333333u) + +typedef enum +{ + IRQ_SGI0 = 0, + IRQ_OSTMI0TINT = 134 +} IRQn_Type; + +typedef void(*IRQHandler)(); + +extern void PendSV_Handler(uint32_t); +extern void OS_Tick_Handler(uint32_t); +extern uint32_t InterruptHandlerRegister (IRQn_Type irq, IRQHandler handler); +#endif + +// Initialize alternative hardware timer as RTX kernel timer +// Return: IRQ number of the alternative hardware timer +int os_tick_init (void) { +#ifdef TARGET_RZ_A1H + CPGSTBCR5 &= ~(CPG_STBCR5_BIT_MSTP51); /* enable OSTM0 clock */ + + OSTM0TT = 0x1; /* Stop the counter and clears the OSTM0TE bit. */ + OSTM0CTL = 0x1; /* Interval timer mode. Interrupt enabled */ + + OSTM0CMP = (uint32_t)(((double)CM0_RENESAS_RZ_A1_P0_CLK*(double)OS_TICK)/1E6); + + OSTM0TS = 0x1; /* Start the counter and sets the OSTM0TE bit. */ + + InterruptHandlerRegister(IRQ_SGI0 , (IRQHandler)PendSV_Handler); + InterruptHandlerRegister(IRQ_OSTMI0TINT, (IRQHandler)OS_Tick_Handler); + + + return IRQ_OSTMI0TINT; /* Return IRQ number of timer (0..239) */ + /* RTX will set and configure the interrupt */ +#endif +} + +/*--------------------------- os_tick_irqack --------------------------------*/ + +// Acknowledge alternative hardware timer interrupt +void os_tick_irqack (void) { + /* ... */ +} + +#endif // (OS_SYSTICK == 0) + +/*--------------------------- os_error --------------------------------------*/ +extern void mbed_die(void); + +void os_error (uint32_t err_code) { + /* This function is called when a runtime error is detected. Parameter */ + /* 'err_code' holds the runtime error code (defined in RTL.H). */ + mbed_die(); + + /* HERE: include optional code to be executed on runtime error. */ + for (;;); +} + + +/*---------------------------------------------------------------------------- + * RTX Configuration Functions + *---------------------------------------------------------------------------*/ + +#include "RTX_CM_lib.h" + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_A/RTX_Config.h b/rtos/rtx/TARGET_CORTEX_A/RTX_Config.h new file mode 100644 index 0000000..9b42ab4 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/RTX_Config.h @@ -0,0 +1,76 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_CONFIG.H + * Purpose: Exported functions of RTX_Config.c + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + +/* Error Codes */ +#define OS_ERR_STK_OVF 1 +#define OS_ERR_FIFO_OVF 2 +#define OS_ERR_MBX_OVF 3 + +/* Definitions */ +#define BOX_ALIGN_8 0x80000000 +#define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)*(cnt) + 3] +#define _declare_box8(pool,size,cnt) U64 pool[(((size)+7)/8)*(cnt) + 2] +#define _init_box8(pool,size,bsize) _init_box (pool,size,(bsize) | BOX_ALIGN_8) + +/* Variables */ +extern U32 mp_tcb[]; +extern U64 mp_stk[]; +extern U32 os_fifo[]; +extern void *os_active_TCB[]; + +/* Constants */ +extern U16 const os_maxtaskrun; +extern U32 const os_trv; +extern U8 const os_flags; +extern U32 const os_stackinfo; +extern U32 const os_rrobin; +extern U32 const os_clockrate; +extern U32 const os_timernum; +extern U16 const mp_tcb_size; +extern U32 const mp_stk_size; +extern U32 const *m_tmr; +extern U16 const mp_tmr_size; +extern U8 const os_fifo_size; + +/* Functions */ +extern void os_idle_demon (void); +extern int os_tick_init (void); +extern void os_tick_irqack (void); +extern void os_tmr_call (U16 info); +extern void os_error (U32 err_code); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/HAL_CA9.c b/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/HAL_CA9.c new file mode 100644 index 0000000..eaca180 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/HAL_CA9.c @@ -0,0 +1,416 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CA9.c + * Purpose: Hardware Abstraction Layer for Cortex-A9 + * Rev.: 3 Sept 2013 + *---------------------------------------------------------------------------- + * + * Copyright (c) 2012 - 2013 ARM Limited + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_List.h" +#include "rt_MemBox.h" +#include "rt_HAL_CA.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + +//For A-class, set USR/SYS stack +__asm void rt_set_PSP (U32 stack) { + ARM + + MRS R1, CPSR + CPS #MODE_SYS ;no effect in USR mode + ISB + MOV SP, R0 + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR + +} + +//For A-class, get USR/SYS stack +__asm U32 rt_get_PSP (void) { + ARM + + MRS R1, CPSR + CPS #MODE_SYS ;no effect in USR mode + ISB + MOV R0, SP + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR +} + +/*--------------------------- _alloc_box ------------------------------------*/ +__asm void *_alloc_box (void *box_mem) { + /* Function wrapper for Unprivileged/Privileged mode. */ + ARM + + LDR R12,=__cpp(rt_alloc_box) + MRS R2, CPSR + LSLS R2, #28 + BXNE R12 + SVC 0 + BX LR +} + + +/*--------------------------- _free_box -------------------------------------*/ +__asm int _free_box (void *box_mem, void *box) { + /* Function wrapper for Unprivileged/Privileged mode. */ + ARM + + LDR R12,=__cpp(rt_free_box) + MRS R2, CPSR + LSLS R2, #28 + BXNE R12 + SVC 0 + BX LR + +} + +/*-------------------------- SVC_Handler -----------------------------------*/ + +#pragma push +#pragma arm +__asm void SVC_Handler (void) { + PRESERVE8 + ARM + + IMPORT rt_tsk_lock + IMPORT rt_tsk_unlock + IMPORT SVC_Count + IMPORT SVC_Table + IMPORT rt_stk_check + IMPORT FPUEnable + +Mode_SVC EQU 0x13 + + SRSFD SP!, #Mode_SVC ; Push LR_SVC and SPRS_SVC onto SVC mode stack + PUSH {R4} ; Push R4 so we can use it as a temp + + MRS R4,SPSR ; Get SPSR + TST R4,#CPSR_T_BIT ; Check Thumb Bit + LDRNEH R4,[LR,#-2] ; Thumb: Load Halfword + BICNE R4,R4,#0xFF00 ; Extract SVC Number + LDREQ R4,[LR,#-4] ; ARM: Load Word + BICEQ R4,R4,#0xFF000000 ; Extract SVC Number + + /* Lock out systick and re-enable interrupts */ + PUSH {R0-R3,R12,LR} + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR to SVC stack + + BLX rt_tsk_lock + CPSIE i + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + POP {R0-R3,R12,LR} + + CMP R4,#0 + BNE SVC_User + + MRS R4,SPSR + PUSH {R4} ; Push R4 so we can use it as a temp + AND R4, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R4 ; Adjust stack + PUSH {R4, LR} ; Store stack adjustment and dummy LR + BLX R12 + POP {R4, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R4 ; Unadjust stack + POP {R4} ; Restore R4 + MSR SPSR_CXSF,R4 + + /* Here we will be in SVC mode (even if coming in from PendSV_Handler or OS_Tick_Handler) */ +Sys_Switch + LDR LR,=__cpp(&os_tsk) + LDM LR,{R4,LR} ; os_tsk.run, os_tsk.new + CMP R4,LR + BNE switching + + PUSH {R0-R3,R12,LR} + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR to SVC stack + + CPSID i + BLX rt_tsk_unlock + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + POP {R0-R3,R12,LR} + POP {R4} + RFEFD SP! ; Return from exception, no task switch + +switching + CLREX + CMP R4,#0 + ADDEQ SP,SP,#12 ; Original R4, LR & SPSR do not need to be popped when we are paging in a different task + BEQ SVC_Next ; Runtask deleted? + + + PUSH {R8-R11} //R4 and LR already stacked + MOV R10,R4 ; Preserve os_tsk.run + MOV R11,LR ; Preserve os_tsk.new + + ADD R8,SP,#16 ; Unstack R4,LR + LDMIA R8,{R4,LR} + + SUB SP,SP,#4 ; Make space on the stack for the next instn + STMIA SP,{SP}^ ; Put User SP onto stack + POP {R8} ; Pop User SP into R8 + + MRS R9,SPSR + STMDB R8!,{R9} ; User CPSR + STMDB R8!,{LR} ; User PC + STMDB R8,{LR}^ ; User LR + SUB R8,R8,#4 ; No writeback for store of User LR + STMDB R8!,{R0-R3,R12} ; User R0-R3,R12 + MOV R3,R10 ; os_tsk.run + MOV LR,R11 ; os_tsk.new + POP {R9-R12} + ADD SP,SP,#12 ; Fix up SP for unstack of R4, LR & SPSR + STMDB R8!,{R4-R7,R9-R12} ; User R4-R11 + + //If applicable, stack VFP state + MRC p15,0,R1,c1,c0,2 ; VFP/NEON access enabled? (CPACR) + AND R2,R1,#0x00F00000 + CMP R2,#0x00F00000 + BNE no_outgoing_vfp + VMRS R2,FPSCR + STMDB R8!,{R2,R4} ; Push FPSCR, maintain 8-byte alignment + VSTMDB R8!,{S0-S31} + LDRB R2,[R3,#TCB_STACKF] ; Record in TCB that VFP state is stacked + ORR R2,#2 + STRB R2,[R3,#TCB_STACKF] + +no_outgoing_vfp + STR R8,[R3,#TCB_TSTACK] + MOV R4,LR + + PUSH {R4} ; Push R4 so we can use it as a temp + AND R4, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R4 ; Adjust stack + PUSH {R4, LR} ; Store stack adjustment and dummy LR to SVC stack + + BLX rt_stk_check + + POP {R4, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R4 ; Unadjust stack + POP {R4} ; Restore R4 + + MOV LR,R4 + +SVC_Next //R4 == os_tsk.run, LR == os_tsk.new, R0-R3, R5-R12 corruptible + LDR R1,=__cpp(&os_tsk) ; os_tsk.run = os_tsk.new + STR LR,[R1] + LDRB R1,[LR,#TCB_TID] ; os_tsk.run->task_id + LSL R1,#8 ; Store PROCID + MCR p15,0,R1,c13,c0,1 ; Write CONTEXTIDR + + LDR R0,[LR,#TCB_TSTACK] ; os_tsk.run->tsk_stack + + //Does incoming task have VFP state in stack? + LDRB R3,[LR,#TCB_STACKF] + TST R3,#0x2 + MRC p15,0,R1,c1,c0,2 ; Read CPACR + ANDEQ R1,R1,#0xFF0FFFFF ; Disable VFP access if incoming task does not have stacked VFP state + ORRNE R1,R1,#0x00F00000 ; Enable VFP access if incoming task does have stacked VFP state + MCR p15,0,R1,c1,c0,2 ; Write CPACR + BEQ no_incoming_vfp + ISB ; We only need the sync if we enabled, otherwise we will context switch before next VFP instruction anyway + VLDMIA R0!,{S0-S31} + LDR R2,[R0] + VMSR FPSCR,R2 + ADD R0,R0,#8 + +no_incoming_vfp + LDR R1,[R0,#60] ; Restore User CPSR + MSR SPSR_CXSF,R1 + LDMIA R0!,{R4-R11} ; Restore User R4-R11 + ADD R0,R0,#4 ; Restore User R1-R3,R12 + LDMIA R0!,{R1-R3,R12} + LDMIA R0,{LR}^ ; Restore User LR + ADD R0,R0,#4 ; No writeback for load to user LR + LDMIA R0!,{LR} ; Restore User PC + ADD R0,R0,#4 ; Correct User SP for unstacked user CPSR + + PUSH {R0} ; Push R0 onto stack + LDMIA SP,{SP}^ ; Get R0 off stack into User SP + ADD SP,SP,#4 ; Put SP back + + LDR R0,[R0,#-32] ; Restore R0 + + PUSH {R0-R3,R12,LR} + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR to SVC stack + + CPSID i + BLX rt_tsk_unlock + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + POP {R0-R3,R12,LR} + + MOVS PC,LR ; Return from exception + + + /*------------------- User SVC -------------------------------*/ + +SVC_User + LDR R12,=SVC_Count + LDR R12,[R12] + CMP R4,R12 ; Check for overflow + BHI SVC_Done + + LDR R12,=SVC_Table-4 + LDR R12,[R12,R4,LSL #2] ; Load SVC Function Address + MRS R4,SPSR ; Save SPSR + PUSH {R4} ; Push R4 so we can use it as a temp + AND R4, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R4 ; Adjust stack + PUSH {R4, LR} ; Store stack adjustment and dummy LR + BLX R12 ; Call SVC Function + POP {R4, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R4 ; Unadjust stack + POP {R4} ; Restore R4 + MSR SPSR_CXSF,R4 ; Restore SPSR + +SVC_Done + PUSH {R0-R3,R12,LR} + + PUSH {R4} ; Push R4 so we can use it as a temp + AND R4, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R4 ; Adjust stack + PUSH {R4, LR} ; Store stack adjustment and dummy LR + + CPSID i + BLX rt_tsk_unlock + + POP {R4, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R4 ; Unadjust stack + POP {R4} ; Restore R4 + + POP {R0-R3,R12,LR} + POP {R4} + RFEFD SP! ; Return from exception +} +#pragma pop + +#pragma push +#pragma arm +__asm void PendSV_Handler (U32 IRQn) { + ARM + + IMPORT rt_tsk_lock + IMPORT IRQNestLevel + + ADD SP,SP,#8 //fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment) + + //Disable systick interrupts, then write EOIR. We want interrupts disabled before we enter the context switcher. + PUSH {R0, R1} + BLX rt_tsk_lock + POP {R0, R1} + LDR R1, =__cpp(&GICInterface_BASE) + LDR R1, [R1, #0] + STR R0, [R1, #0x10] + + LDR R0, =IRQNestLevel ; Get address of nesting counter + LDR R1, [R0] + SUB R1, R1, #1 ; Decrement nesting counter + STR R1, [R0] + + BLX __cpp(rt_pop_req) + + POP {R1, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R1 ; Unadjust stack + + LDR R0,[SP,#24] + MSR SPSR_CXSF,R0 + POP {R0-R3,R12} ; Leave SPSR & LR on the stack + PUSH {R4} + B Sys_Switch +} +#pragma pop + + +#pragma push +#pragma arm +__asm void OS_Tick_Handler (U32 IRQn) { + ARM + + IMPORT rt_tsk_lock + IMPORT IRQNestLevel + + ADD SP,SP,#8 //fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment) + + PUSH {R0, R1} + BLX rt_tsk_lock + POP {R0, R1} + LDR R1, =__cpp(&GICInterface_BASE) + LDR R1, [R1, #0] + STR R0, [R1, #0x10] + + LDR R0, =IRQNestLevel ; Get address of nesting counter + LDR R1, [R0] + SUB R1, R1, #1 ; Decrement nesting counter + STR R1, [R0] + + BLX __cpp(os_tick_irqack) + BLX __cpp(rt_systick) + + POP {R1, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R1 ; Unadjust stack + + LDR R0,[SP,#24] + MSR SPSR_CXSF,R0 + POP {R0-R3,R12} ; Leave SPSR & LR on the stack + PUSH {R4} + B Sys_Switch +} +#pragma pop + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/SVC_Table.S new file mode 100644 index 0000000..1c1ddc9 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/SVC_Table.S @@ -0,0 +1,57 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + AREA SVC_TABLE, CODE, READONLY + + EXPORT SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + EXPORT SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; InitMemorySubsystem + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/HAL_CA9.S b/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/HAL_CA9.S new file mode 100644 index 0000000..c0e9836 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/HAL_CA9.S @@ -0,0 +1,474 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CA9.c + * Purpose: Hardware Abstraction Layer for Cortex-A9 + * Rev.: 3 Sept 2013 + *---------------------------------------------------------------------------- + * + * Copyright (c) 2012 - 2013 ARM Limited + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + .global rt_set_PSP + .global rt_get_PSP + .global _alloc_box + .global _free_box + .global PendSV_Handler + .global OS_Tick_Handler + + .EQU CPSR_T_BIT, 0x20 + .EQU CPSR_I_BIT, 0x80 + .EQU CPSR_F_BIT, 0x40 + + .EQU MODE_USR, 0x10 + .EQU MODE_FIQ, 0x11 + .EQU MODE_IRQ, 0x12 + .EQU MODE_SVC, 0x13 + .EQU MODE_ABT, 0x17 + .EQU MODE_UND, 0x1B + .EQU MODE_SYS, 0x1F + + .EQU TCB_TID, 3 /* 'task id' offset */ + .EQU TCB_STACKF, 32 /* 'stack_frame' offset */ + .EQU TCB_TSTACK, 36 /* 'tsk_stack' offset */ + + .extern rt_alloc_box + .extern os_tsk + .extern GICInterface_BASE + .extern rt_pop_req + .extern os_tick_irqack + .extern rt_systick + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + .text +@ For A-class, set USR/SYS stack +@ __asm void rt_set_PSP (U32 stack) { +rt_set_PSP: + .arm + + MRS R1, CPSR + CPS #MODE_SYS @no effect in USR mode + ISB + MOV SP, R0 + MSR CPSR_c, R1 @no effect in USR mode + ISB + BX LR + +@ } + +@ For A-class, get USR/SYS stack +@ __asm U32 rt_get_PSP (void) { +rt_get_PSP: + .arm + + MRS R1, CPSR + CPS #MODE_SYS @no effect in USR mode + ISB + MOV R0, SP + MSR CPSR_c, R1 @no effect in USR mode + ISB + BX LR + +@ } + +/*--------------------------- _alloc_box ------------------------------------*/ +@ __asm void *_alloc_box (void *box_mem) { +_alloc_box: + /* Function wrapper for Unprivileged/Privileged mode. */ + .arm + + LDR R12,=rt_alloc_box @ __cpp(rt_alloc_box) + MRS R2, CPSR + LSLS R2, #28 + BXNE R12 + SVC 0 + BX LR +@ } + + +/*--------------------------- _free_box -------------------------------------*/ +@ __asm int _free_box (void *box_mem, void *box) { +_free_box: + /* Function wrapper for Unprivileged/Privileged mode. */ + .arm + + LDR R12,=rt_free_box @ __cpp(rt_free_box) + MRS R2, CPSR + LSLS R2, #28 + BXNE R12 + SVC 0 + BX LR + +@ } + +/*-------------------------- SVC_Handler -----------------------------------*/ + +@ #pragma push +@ #pragma arm +@ __asm void SVC_Handler (void) { + + .type SVC_Handler, %function + .global SVC_Handler +SVC_Handler: +@ PRESERVE8 + .arm + .extern rt_tsk_lock + .extern rt_tsk_unlock + .extern SVC_Count + .extern SVC_Table + .extern rt_stk_check + .extern FPUEnable + + .EQU Mode_SVC, 0x13 + + SRSDB SP!, #Mode_SVC @ Push LR_SVC and SPRS_SVC onto SVC mode stack + PUSH {R4} @ Push R4 so we can use it as a temp + + + MRS R4,SPSR @ Get SPSR + TST R4,#CPSR_T_BIT @ Check Thumb Bit + LDRNEH R4,[LR,#-2] @ Thumb: Load Halfword + BICNE R4,R4,#0xFF00 @ Extract SVC Number + LDREQ R4,[LR,#-4] @ ARM: Load Word + BICEQ R4,R4,#0xFF000000 @ Extract SVC Number + + /* Lock out systick and re-enable interrupts */ + PUSH {R0-R3,R12,LR} + + AND R12, SP, #4 @ Ensure stack is 8-byte aligned + SUB SP, SP, R12 @ Adjust stack + PUSH {R12, LR} @ Store stack adjustment and dummy LR to SVC stack + + BLX rt_tsk_lock + CPSIE i + + POP {R12, LR} @ Get stack adjustment & discard dummy LR + ADD SP, SP, R12 @ Unadjust stack + + POP {R0-R3,R12,LR} + + CMP R4,#0 + BNE SVC_User + + MRS R4,SPSR + PUSH {R4} @ Push R4 so we can use it as a temp + AND R4, SP, #4 @ Ensure stack is 8-byte aligned + SUB SP, SP, R4 @ Adjust stack + PUSH {R4, LR} @ Store stack adjustment and dummy LR + BLX R12 + POP {R4, LR} @ Get stack adjustment & discard dummy LR + ADD SP, SP, R4 @ Unadjust stack + POP {R4} @ Restore R4 + MSR SPSR_cxsf,R4 + + /* Here we will be in SVC mode (even if coming in from PendSV_Handler or OS_Tick_Handler) */ +Sys_Switch: + LDR LR,=os_tsk @ __cpp(&os_tsk) + LDM LR,{R4,LR} @ os_tsk.run, os_tsk.new + CMP R4,LR + BNE switching + + PUSH {R0-R3,R12,LR} + + AND R12, SP, #4 @ Ensure stack is 8-byte aligned + SUB SP, SP, R12 @ Adjust stack + PUSH {R12, LR} @ Store stack adjustment and dummy LR to SVC stack + + CPSID i + BLX rt_tsk_unlock + + POP {R12, LR} @ Get stack adjustment & discard dummy LR + ADD SP, SP, R12 @ Unadjust stack + + POP {R0-R3,R12,LR} + POP {R4} + RFEFD SP! @ Return from exception, no task switch + +switching: + CLREX + CMP R4,#0 + ADDEQ SP,SP,#12 @ Original R4, LR & SPSR do not need to be popped when we are paging in a different task + BEQ SVC_Next @ Runtask deleted? + + + PUSH {R8-R11} @ R4 and LR already stacked + MOV R10,R4 @ Preserve os_tsk.run + MOV R11,LR @ Preserve os_tsk.new + + ADD R8,SP,#16 @ Unstack R4,LR + LDMIA R8,{R4,LR} + + SUB SP,SP,#4 @ Make space on the stack for the next instn + STMIA SP,{SP}^ @ Put User SP onto stack + POP {R8} @ Pop User SP into R8 + + MRS R9,SPSR + STMDB R8!,{R9} @ User CPSR + STMDB R8!,{LR} @ User PC + STMDB R8,{LR}^ @ User LR + SUB R8,R8,#4 @ No writeback for store of User LR + STMDB R8!,{R0-R3,R12} @ User R0-R3,R12 + MOV R3,R10 @ os_tsk.run + MOV LR,R11 @ os_tsk.new + POP {R9-R12} + ADD SP,SP,#12 @ Fix up SP for unstack of R4, LR & SPSR + STMDB R8!,{R4-R7,R9-R12} @ User R4-R11 + + @ If applicable, stack VFP state + MRC p15,0,R1,c1,c0,2 @ VFP/NEON access enabled? (CPACR) + AND R2,R1,#0x00F00000 + CMP R2,#0x00F00000 + BNE no_outgoing_vfp + VMRS R2,FPSCR + STMDB R8!,{R2,R4} @ Push FPSCR, maintain 8-byte alignment + VSTMDB R8!,{S0-S31} + LDRB R2,[R3,#TCB_STACKF] @ Record in TCB that VFP state is stacked + ORR R2,#2 + STRB R2,[R3,#TCB_STACKF] + +no_outgoing_vfp: + STR R8,[R3,#TCB_TSTACK] + MOV R4,LR + + PUSH {R4} @ Push R4 so we can use it as a temp + AND R4, SP, #4 @ Ensure stack is 8-byte aligned + SUB SP, SP, R4 @ Adjust stack + PUSH {R4, LR} @ Store stack adjustment and dummy LR to SVC stack + + BLX rt_stk_check + + POP {R4, LR} @ Get stack adjustment & discard dummy LR + ADD SP, SP, R4 @ Unadjust stack + POP {R4} @ Restore R4 + + MOV LR,R4 + +SVC_Next: @ R4 == os_tsk.run, LR == os_tsk.new, R0-R3, R5-R12 corruptible + LDR R1,=os_tsk @ __cpp(&os_tsk), os_tsk.run = os_tsk.new + STR LR,[R1] + LDRB R1,[LR,#TCB_TID] @ os_tsk.run->task_id + LSL R1,#8 @ Store PROCID + MCR p15,0,R1,c13,c0,1 @ Write CONTEXTIDR + + LDR R0,[LR,#TCB_TSTACK] @ os_tsk.run->tsk_stack + + @ Does incoming task have VFP state in stack? + LDRB R3,[LR,#TCB_STACKF] + TST R3,#0x2 + MRC p15,0,R1,c1,c0,2 @ Read CPACR + ANDEQ R1,R1,#0xFF0FFFFF @ Disable VFP access if incoming task does not have stacked VFP state + ORRNE R1,R1,#0x00F00000 @ Enable VFP access if incoming task does have stacked VFP state + MCR p15,0,R1,c1,c0,2 @ Write CPACR + BEQ no_incoming_vfp + ISB @ We only need the sync if we enabled, otherwise we will context switch before next VFP instruction anyway + VLDMIA R0!,{S0-S31} + LDR R2,[R0] + VMSR FPSCR,R2 + ADD R0,R0,#8 + +no_incoming_vfp: + LDR R1,[R0,#60] @ Restore User CPSR + MSR SPSR_cxsf,R1 + LDMIA R0!,{R4-R11} @ Restore User R4-R11 + ADD R0,R0,#4 @ Restore User R1-R3,R12 + LDMIA R0!,{R1-R3,R12} + LDMIA R0,{LR}^ @ Restore User LR + ADD R0,R0,#4 @ No writeback for load to user LR + LDMIA R0!,{LR} @ Restore User PC + ADD R0,R0,#4 @ Correct User SP for unstacked user CPSR + + PUSH {R0} @ Push R0 onto stack + LDMIA SP,{SP}^ @ Get R0 off stack into User SP + ADD SP,SP,#4 @ Put SP back + + LDR R0,[R0,#-32] @ Restore R0 + + PUSH {R0-R3,R12,LR} + + AND R12, SP, #4 @ Ensure stack is 8-byte aligned + SUB SP, SP, R12 @ Adjust stack + PUSH {R12, LR} @ Store stack adjustment and dummy LR to SVC stack + + CPSID i + BLX rt_tsk_unlock + + POP {R12, LR} @ Get stack adjustment & discard dummy LR + ADD SP, SP, R12 @ Unadjust stack + + POP {R0-R3,R12,LR} + + MOVS PC,LR @ Return from exception + + + /*------------------- User SVC -------------------------------*/ + +SVC_User: + LDR R12,=SVC_Count + LDR R12,[R12] + CMP R4,R12 @ Check for overflow + BHI SVC_Done + + LDR R12,=SVC_Table-4 + LDR R12,[R12,R4,LSL #2] @ Load SVC Function Address + MRS R4,SPSR @ Save SPSR + PUSH {R4} @ Push R4 so we can use it as a temp + AND R4, SP, #4 @ Ensure stack is 8-byte aligned + SUB SP, SP, R4 @ Adjust stack + PUSH {R4, LR} @ Store stack adjustment and dummy LR + BLX R12 @ Call SVC Function + POP {R4, LR} @ Get stack adjustment & discard dummy LR + ADD SP, SP, R4 @ Unadjust stack + POP {R4} @ Restore R4 + MSR SPSR_cxsf,R4 @ Restore SPSR + +SVC_Done: + PUSH {R0-R3,R12,LR} + + PUSH {R4} @ Push R4 so we can use it as a temp + AND R4, SP, #4 @ Ensure stack is 8-byte aligned + SUB SP, SP, R4 @ Adjust stack + PUSH {R4, LR} @ Store stack adjustment and dummy LR + + CPSID i + BLX rt_tsk_unlock + + POP {R4, LR} @ Get stack adjustment & discard dummy LR + ADD SP, SP, R4 @ Unadjust stack + POP {R4} @ Restore R4 + + POP {R0-R3,R12,LR} + POP {R4} + RFEFD SP! @ Return from exception + +@ } + +@ #pragma pop + + +@ #pragma push +@ #pragma arm +@ __asm void PendSV_Handler (U32 IRQn) { +PendSV_Handler: + .arm + + .extern rt_tsk_lock + .extern IRQNestLevel + + ADD SP,SP,#8 @ fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment) + + @ Disable systick interrupts, then write EOIR. We want interrupts disabled before we enter the context switcher. + PUSH {R0, R1} + BLX rt_tsk_lock + POP {R0, R1} + LDR R1, =GICInterface_BASE @ __cpp(&GICInterface_BASE) + LDR R1, [R1, #0] + STR R0, [R1, #0x10] + + LDR R0, =IRQNestLevel @ Get address of nesting counter + LDR R1, [R0] + SUB R1, R1, #1 @ Decrement nesting counter + STR R1, [R0] + + BLX rt_pop_req @ __cpp(rt_pop_req) + + POP {R1, LR} @ Get stack adjustment & discard dummy LR + ADD SP, SP, R1 @ Unadjust stack + + LDR R0,[SP,#24] + MSR SPSR_cxsf,R0 + POP {R0-R3,R12} @ Leave SPSR & LR on the stack + PUSH {R4} + B Sys_Switch +@ } +@ #pragma pop + +@ #pragma push +@ #pragma arm +@ __asm void OS_Tick_Handler (U32 IRQn) { +OS_Tick_Handler: + .arm + + ADD SP,SP,#8 @ fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment) + + PUSH {R0, R1} + BLX rt_tsk_lock + POP {R0, R1} + LDR R1, =GICInterface_BASE @ __cpp(&GICInterface_BASE) + LDR R1, [R1, #0] + STR R0, [R1, #0x10] + + LDR R0, =IRQNestLevel @ Get address of nesting counter + LDR R1, [R0] + SUB R1, R1, #1 @ Decrement nesting counter + STR R1, [R0] + + BLX os_tick_irqack @ __cpp(os_tick_irqack) + BLX rt_systick @ __cpp(rt_systick) + + POP {R1, LR} @ Get stack adjustment & discard dummy LR + ADD SP, SP, R1 @ Unadjust stack + + LDR R0,[SP,#24] + MSR SPSR_cxsf,R0 + POP {R0-R3,R12} @ Leave SPSR & LR on the stack + PUSH {R4} + B Sys_Switch +@ } +@ #pragma pop + + .global __set_PSP +@ __STATIC_ASM void __set_PSP(uint32_t topOfProcStack) +@ { +__set_PSP: +@ PRESERVE8 + .arm + + BIC R0, R0, #7 @ensure stack is 8-byte aligned + MRS R1, CPSR + CPS #MODE_SYS @no effect in USR mode + MOV SP, R0 + MSR CPSR_c, R1 @no effect in USR mode + ISB + BX LR + +@ } + + .global __set_CPS_USR +@ __STATIC_ASM void __set_CPS_USR(void) +@ { +__set_CPS_USR: + .arm + + CPS #MODE_USR + BX LR +@ } + + .END +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/SVC_Table.S new file mode 100644 index 0000000..85c030f --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/SVC_Table.S @@ -0,0 +1,60 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: SVC_TABLE.S + * Purpose: Pre-defined SVC Table for Cortex-M + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + + .section SVC_TABLE @, CODE, READONLY + .align 5 + + .global SVC_Count + +.EQU SVC_Cnt, (SVC_End-SVC_Table)/4 + +SVC_Count: + .word SVC_Cnt + +@ Import user SVC functions here. +@ .extern __SVC_1 + .global SVC_Table +SVC_Table: +@ Insert user SVC functions here. SVC 0 used by RTL Kernel. +@ .word __SVC_1 @ InitMemorySubsystem + +@SVC_End +SVC_End: + + .END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_A/cmsis_os.h b/rtos/rtx/TARGET_CORTEX_A/cmsis_os.h new file mode 100644 index 0000000..5beb71c --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/cmsis_os.h @@ -0,0 +1,807 @@ +/* ---------------------------------------------------------------------- + * $Date: 5. June 2012 + * $Revision: V1.01 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h RTX header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedef's + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + *---------------------------------------------------------------------------- + * + * Copyright (c) 2012 ARM LIMITED + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/** +\page cmsis_os_h Header File Template: cmsis_os.h + +The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). +Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents +its implementation. + +The file cmsis_os.h contains: + - CMSIS-RTOS API function definitions + - struct definitions for parameters and return types + - status and priority values used by CMSIS-RTOS API functions + - macros for defining threads and other kernel objects + + +Name conventions and header file modifications + +All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. +Definitions that are prefixed \b os_ are not used in the application code but local to this header file. +All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. + +Definitions that are marked with CAN BE CHANGED can be adapted towards the needs of the actual CMSIS-RTOS implementation. +These definitions can be specific to the underlying RTOS kernel. + +Definitions that are marked with MUST REMAIN UNCHANGED cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer +compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. + + +Function calls from interrupt service routines + +The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): + - \ref osSignalSet + - \ref osSemaphoreRelease + - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree + - \ref osMessagePut, \ref osMessageGet + - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree + +Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called +from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. + +Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. +If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. + + +Define and reference object definitions + +With \#define osObjectsExternal objects are defined as external symbols. This allows to create a consistent header file +that is used throughout a project as shown below: + +Header File +\code +#include // CMSIS RTOS header file + +// Thread definition +extern void thread_sample (void const *argument); // function prototype +osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); + +// Pool definition +osPoolDef(MyPool, 10, long); +\endcode + + +This header file defines all objects when included in a C/C++ source file. When \#define osObjectsExternal is +present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be +used throughout the whole project. + +Example +\code +#include "osObjects.h" // Definition of the CMSIS-RTOS objects +\endcode + +\code +#define osObjectExternal // Objects will be defined as external symbols +#include "osObjects.h" // Reference to the CMSIS-RTOS objects +\endcode + +*/ + +#ifndef _CMSIS_OS_H +#define _CMSIS_OS_H + +/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x10001 ///< API version (main [31:16] .sub [15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_RTX ((4<<16)|61) ///< RTOS identification and version (main [31:16] .sub [15:0]) + +/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. +#define osKernelSystemId "RTX V4.61" ///< RTOS identification string + +#define CMSIS_OS_RTX +#define CMSIS_OS_RTX_CA /* new define for Coretex-A */ + +// The stack space occupied is mainly dependent on the underling C standard library +#if defined(__GNUC__) || defined(__CC_ARM) || defined(__ARMCC_VERSION) +# define WORDS_STACK_SIZE 512 +#elif defined(TOOLCHAIN_ARM_MICRO) +# define WORDS_STACK_SIZE 128 +#endif + +#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4) + +/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_Signals 16 ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 65535 ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available + +#if defined (__CC_ARM) +#define os_InRegs __value_in_regs // Compiler specific: force struct in registers +#else +#define os_InRegs +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumeration, structures, defines ==== + +/// Priority used for thread control. +/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. +typedef enum { + osPriorityIdle = -3, ///< priority: idle (lowest) + osPriorityLow = -2, ///< priority: low + osPriorityBelowNormal = -1, ///< priority: below normal + osPriorityNormal = 0, ///< priority: normal (default) + osPriorityAboveNormal = +1, ///< priority: above normal + osPriorityHigh = +2, ///< priority: high + osPriorityRealtime = +3, ///< priority: realtime (highest) + osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority +} osPriority; + +/// Timeout value. +/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value + +/// Status code values returned by CMSIS-RTOS functions. +/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osEventMessage = 0x10, ///< function completed; message event occurred. + osEventMail = 0x20, ///< function completed; mail event occurred. + osEventTimeout = 0x40, ///< function completed; timeout occurred. + osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< value of a parameter is out of range. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; + + +/// Timer type value for the timer definition. +/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. +typedef enum { + osTimerOnce = 0, ///< one-shot timer + osTimerPeriodic = 1 ///< repeating timer +} os_timer_type; + +/// Entry point of a thread. +/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. +typedef void (*os_ptimer) (void const *argument); + +// >>> the following data type definitions may shall adapted towards a specific RTOS + +/// Thread ID identifies the thread (pointer to a thread control block). +/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_cb *osThreadId; + +/// Timer ID identifies the timer (pointer to a timer control block). +/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_cb *osTimerId; + +/// Mutex ID identifies the mutex (pointer to a mutex control block). +/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_cb *osMutexId; + +/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). +/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_cb *osSemaphoreId; + +/// Pool ID identifies the memory pool (pointer to a memory pool control block). +/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_cb *osPoolId; + +/// Message ID identifies the message queue (pointer to a message queue control block). +/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_cb *osMessageQId; + +/// Mail ID identifies the mail queue (pointer to a mail queue control block). +/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_cb *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t instances; ///< maximum number of instances of that thread function + uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size +#ifdef __MBED_CMSIS_RTOS_CA9 + uint32_t *stack_pointer; ///< pointer to the stack memory block +#endif +} osThreadDef_t; + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + void *timer; ///< pointer to internal data +} osTimerDef_t; + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_def { + void *mutex; ///< pointer to internal data +} osMutexDef_t; + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_def { + void *semaphore; ///< pointer to internal data +} osSemaphoreDef_t; + +/// Definition structure for memory block allocation. +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + void *pool; ///< memory array for messages +} osMessageQDef_t; + +/// Definition structure for mail queue. +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; + +/// Event structure contains detailed information about an event. +/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. +/// However the struct may be extended at the end. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Control Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. +osStatus osKernelInitialize (void); + +/// Start the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. +osStatus osKernelStart (void); + +/// Check if the RTOS kernel is already started. +/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. +/// \return 0 RTOS is not started, 1 RTOS is started. +int32_t osKernelRunning(void); + + +// ==== Thread Management ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name +#else // define the object +#ifdef __MBED_CMSIS_RTOS_CA9 +#define osThreadDef(name, priority, stacksz) \ +uint32_t os_thread_def_stack_##name [stacksz / sizeof(uint32_t)]; \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), 1, (stacksz), (os_thread_def_stack_##name) } +#else +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (instances), (stacksz) } +#endif +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. +osThreadId osThreadGetId (void); + +/// Terminate execution of a thread and remove it from Active Threads. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. +osStatus osThreadTerminate (osThreadId thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. +osStatus osThreadYield (void); + +/// Change priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); + +/// Get current priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the thread function. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. +osPriority osThreadGetPriority (osThreadId thread_id); + +#ifdef __MBED_CMSIS_RTOS_CA9 +/// Get current thread state. +uint8_t osThreadGetState (osThreadId thread_id); +#endif + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec time delay value +/// \return status code that indicates the execution status of the function. +osStatus osDelay (uint32_t millisec); + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern const osTimerDef_t os_timer_def_##name +#else // define the object +#define osTimerDef(name, function) \ +uint32_t os_timer_cb_##name[5]; \ +const osTimerDef_t os_timer_def_##name = \ +{ (function), (os_timer_cb_##name) } +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec time delay value of the timer. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); + +/// Stop the timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. +osStatus osTimerStop (osTimerId timer_id); + +/// Delete a timer that was created by \ref osTimerCreate. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. +osStatus osTimerDelete (osTimerId timer_id); + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Get Signal Flags status of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalGet shall be consistent in every CMSIS-RTOS. +int32_t osSignalGet (osThreadId thread_id); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event flag information or error code. +/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Mutex Management ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern const osMutexDef_t os_mutex_def_##name +#else // define the object +#define osMutexDef(name) \ +uint32_t os_mutex_cb_##name[3]; \ +const osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) } +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. +osStatus osMutexRelease (osMutexId mutex_id); + +/// Delete a Mutex that was created by \ref osMutexCreate. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. +osStatus osMutexDelete (osMutexId mutex_id); + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ +uint32_t os_semaphore_cb_##name[2]; \ +const osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) } +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object used for managing resources. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count number of available resources. +/// \return semaphore ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); + +/// Delete a Semaphore that was created by \ref osSemaphoreCreate. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern const osPoolDef_t os_pool_def_##name +#else // define the object +#define osPoolDef(name, no, type) \ +uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), (os_pool_m_##name) } +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a memory pool. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a memory pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a specific memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block that is returned to the memory pool. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool Management available + + +// ==== Message Queue Management Functions ==== + +#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern const osMessageQDef_t os_messageQ_def_##name +#else // define the object +#define osMessageQDef(name, queue_sz, type) \ +uint32_t os_messageQ_q_##name[4+(queue_sz)]; \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), (os_messageQ_q_##name) } +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue. +/// \param[in] queue_def queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message or Wait for a Message from a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event information that includes status code. +/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +#endif // Message Queues available + + +// ==== Mail Queue Management Functions ==== + +#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue +/// \param queue_sz maximum number of messages in queue +/// \param type data type of a single message element +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern const osMailQDef_t os_mailQ_def_##name +#else // define the object +#define osMailQDef(name, queue_sz, type) \ +uint32_t os_mailQ_q_##name[4+(queue_sz)]; \ +uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \ +void * os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize mail queue. +/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block from a mail and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a mail to a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. +osStatus osMailPut (osMailQId queue_id, void *mail); + +/// Get a mail from a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queues available + + +#ifdef __cplusplus +} +#endif + +#endif // _CMSIS_OS_H diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_CMSIS.c b/rtos/rtx/TARGET_CORTEX_A/rt_CMSIS.c new file mode 100644 index 0000000..1bd8244 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_CMSIS.c @@ -0,0 +1,2103 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: rt_CMSIS.c + * Purpose: CMSIS RTOS API + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 __CMSIS_GENERIC + +#include "cmsis.h" + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Time.h" +#include "rt_Mutex.h" +#include "rt_Semaphore.h" +#include "rt_Mailbox.h" +#include "rt_MemBox.h" +#include "rt_Memory.h" +#include "rt_HAL_CM.h" + +#define os_thread_cb OS_TCB + +#include "cmsis_os.h" + +#if (osFeature_Signals != 16) +#error Invalid "osFeature_Signals" value! +#endif +#if (osFeature_Semaphore > 65535) +#error Invalid "osFeature_Semaphore" value! +#endif +#if (osFeature_Wait != 0) +#error osWait not supported! +#endif + + +// ==== Enumeration, structures, defines ==== + +// Service Calls defines + +#if defined (__CC_ARM) /* ARM Compiler */ + +#define __NO_RETURN __declspec(noreturn) + +#define osEvent_type osEvent +#define osEvent_ret_status ret +#define osEvent_ret_value ret +#define osEvent_ret_msg ret +#define osEvent_ret_mail ret + +#define osCallback_type osCallback +#define osCallback_ret ret + +#define SVC_0_1(f,t,...) \ +__svc_indirect(0) t _##f (t(*)()); \ + t f (void); \ +__attribute__((always_inline)) \ +static __inline t __##f (void) { \ + return _##f(f); \ +} + +#define SVC_1_1(f,t,t1,...) \ +__svc_indirect(0) t _##f (t(*)(t1),t1); \ + t f (t1 a1); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1) { \ + return _##f(f,a1); \ +} + +#define SVC_2_1(f,t,t1,t2,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \ + t f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2) { \ + return _##f(f,a1,a2); \ +} + +#define SVC_3_1(f,t,t1,t2,t3,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \ + t f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2, t3 a3) { \ + return _##f(f,a1,a2,a3); \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ + t f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + return _##f(f,a1,a2,a3,a4); \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#elif defined (__GNUC__) /* GNU Compiler */ + +#define __NO_RETURN __attribute__((noreturn)) + +typedef uint32_t __attribute__((vector_size(8))) ret64; +typedef uint32_t __attribute__((vector_size(16))) ret128; + +#define RET_pointer __r0 +#define RET_int32_t __r0 +#define RET_uint32_t __r0 +#define RET_osStatus __r0 +#define RET_osPriority __r0 +#define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}} +#define RET_osCallback {(void *)__r0, (void *)__r1} + +#if defined (__ARM_PCS_VFP) + +#define osEvent_type void +#define osEvent_ret_status { __asm ("MOV r0, %0;" \ + : /* no outputs */ \ + : "r"(ret.status) \ + : "r0" \ + ); \ + } +#define osEvent_ret_value { __asm ("MOV r1, %0;" \ + "MOV r0, %1;" \ + : /* no outputs */ \ + : "r"(ret.value.v), \ + "r"(ret.status) \ + : "r0", "r1" \ + ); \ + } +#define osEvent_ret_msg { __asm ("MOV r2, %0;" \ + "MOV r1, %1;" \ + "MOV r0, %2;" \ + : /* no outputs */ \ + : "r"(ret.def.message_id), \ + "r"(ret.value.v), \ + "r"(ret.status) \ + : "r0", "r1" , "r2" \ + ); \ + } + +#define osEvent_ret_mail { __asm ("MOV r2, %0;" \ + "MOV r1, %1;" \ + "MOV r0, %2;" \ + : /* no outputs */ \ + : "r"(ret.def.mail_id), \ + "r"(ret.value.v), \ + "r"(ret.status) \ + : "r0", "r1" , "r2" \ + ); \ + } + +#define osCallback_type void +#define osCallback_ret { __asm ("MOV r1, %0;" \ + "MOV r0, %1;" \ + : /* no outputs */ \ + : "r"(ret.arg), \ + "r"(ret.fp) \ + : "r0", "r1" \ + ); \ + } + +#else /* defined (__ARM_PCS_VFP) */ + +#define osEvent_type ret128 +#define osEvent_ret_status (ret128){ret.status} +#define osEvent_ret_value (ret128){ret.status, ret.value.v} +#define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id} +#define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id} + +#define osCallback_type ret64 +#define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg} + +#endif /* defined (__ARM_PCS_VFP) */ + +#define SVC_ArgN(n) \ + register int __r##n __asm("r"#n); + +#define SVC_ArgR(n,t,a) \ + register t __r##n __asm("r"#n) = a; + +#define SVC_Arg0() \ + SVC_ArgN(0) \ + SVC_ArgN(1) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg1(t1) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgN(1) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg2(t1,t2) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg3(t1,t2,t3) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgR(2,t3,a3) \ + SVC_ArgN(3) + +#define SVC_Arg4(t1,t2,t3,t4) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgR(2,t3,a3) \ + SVC_ArgR(3,t4,a4) + +#if (defined (__CORTEX_M0)) +#define SVC_Call(f) \ + __asm volatile \ + ( \ + "ldr r7,="#f"\n\t" \ + "mov r12,r7\n\t" \ + "svc 0" \ + : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ + : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ + : "r7", "r12", "lr", "cc" \ + ); +#else +#define SVC_Call(f) \ + __asm volatile \ + ( \ + "ldr r12,="#f"\n\t" \ + "svc 0" \ + : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ + : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ + : "r12", "lr", "cc" \ + ); +#endif + +#define SVC_0_1(f,t,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (void) { \ + SVC_Arg0(); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_1_1(f,t,t1,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1) { \ + SVC_Arg1(t1); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_2_1(f,t,t1,t2,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2) { \ + SVC_Arg2(t1,t2); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_3_1(f,t,t1,t2,t3,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Arg3(t1,t2,t3); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Arg4(t1,t2,t3,t4); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#define __NO_RETURN __noreturn + +#define RET_osEvent "=r"(ret.status), "=r"(ret.value), "=r"(ret.def) +#define RET_osCallback "=r"(ret.fp), "=r"(ret.arg) + +#define osEvent_type osEvent +#define osEvent_ret_status ret +#define osEvent_ret_value ret +#define osEvent_ret_msg ret +#define osEvent_ret_mail ret + +#define osCallback_type uint64_t +#define osCallback_ret ((uint64_t)ret.fp | ((uint64_t)ret.arg)<<32) + +#define SVC_Setup(f) \ + __asm( \ + "mov r12,%0\n" \ + :: "r"(&f): "r12" \ + ); + +#define SVC_Ret3() \ + __asm( \ + "ldr r0,[sp,#0]\n" \ + "ldr r1,[sp,#4]\n" \ + "ldr r2,[sp,#8]\n" \ + ); + +#define SVC_0_1(f,t,...) \ +t f (void); \ +_Pragma("swi_number=0") __swi t _##f (void); \ +static inline t __##f (void) { \ + SVC_Setup(f); \ + return _##f(); \ +} + +#define SVC_1_1(f,t,t1,...) \ +t f (t1 a1); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + SVC_Setup(f); \ + return _##f(a1); \ +} + +#define SVC_2_1(f,t,t1,t2,...) \ +t f (t1 a1, t2 a2); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \ +static inline t __##f (t1 a1, t2 a2) { \ + SVC_Setup(f); \ + return _##f(a1,a2); \ +} + +#define SVC_3_1(f,t,t1,t2,t3,...) \ +t f (t1 a1, t2 a2, t3 a3); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \ +static inline t __##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Setup(f); \ + return _##f(a1,a2,a3); \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ +t f (t1 a1, t2 a2, t3 a3, t4 a4); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Setup(f); \ + return _##f(a1,a2,a3,a4); \ +} + +#define SVC_1_2(f,t,t1,rr) \ +uint64_t f (t1 a1); \ +_Pragma("swi_number=0") __swi uint64_t _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + t ret; \ + SVC_Setup(f); \ + _##f(a1); \ + __asm("" : rr : :); \ + return ret; \ +} + +#define SVC_1_3(f,t,t1,rr) \ +t f (t1 a1); \ +void f##_ (t1 a1) { \ + f(a1); \ + SVC_Ret3(); \ +} \ +_Pragma("swi_number=0") __swi void _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + t ret; \ + SVC_Setup(f##_); \ + _##f(a1); \ + __asm("" : rr : :); \ + return ret; \ +} + +#define SVC_2_3(f,t,t1,t2,rr) \ +t f (t1 a1, t2 a2); \ +void f##_ (t1 a1, t2 a2) { \ + f(a1,a2); \ + SVC_Ret3(); \ +} \ +_Pragma("swi_number=0") __swi void _##f (t1 a1, t2 a2); \ +static inline t __##f (t1 a1, t2 a2) { \ + t ret; \ + SVC_Setup(f##_); \ + _##f(a1,a2); \ + __asm("" : rr : :); \ + return ret; \ +} + +#endif + + +// Callback structure +typedef struct { + void *fp; // Function pointer + void *arg; // Function argument +} osCallback; + + +// OS Section definitions +#ifdef OS_SECTIONS_LINK_INFO +extern const uint32_t os_section_id$$Base; +extern const uint32_t os_section_id$$Limit; +#endif + +#ifndef __MBED_CMSIS_RTOS_CA9 +// OS Stack Memory for Threads definitions +extern uint64_t os_stack_mem[]; +extern const uint32_t os_stack_sz; +#endif + +// OS Timers external resources +extern const osThreadDef_t os_thread_def_osTimerThread; +extern osThreadId osThreadId_osTimerThread; +extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ; +extern osMessageQId osMessageQId_osTimerMessageQ; + +extern U32 IRQNestLevel; /* Indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR. */ + + +// ==== Helper Functions ==== + +/// Convert timeout in millisec to system ticks +static uint32_t rt_ms2tick (uint32_t millisec) { + uint32_t tick; + + if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout + if (millisec > 4000000) return 0xFFFE; // Max ticks supported + + tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate; + if (tick > 0xFFFE) return 0xFFFE; + + return tick; +} + +/// Convert Thread ID to TCB pointer +static P_TCB rt_tid2ptcb (osThreadId thread_id) { + P_TCB ptcb; + + if (thread_id == NULL) return NULL; + + if ((uint32_t)thread_id & 3) return NULL; + +#ifdef OS_SECTIONS_LINK_INFO + if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { + if (thread_id < (osThreadId)os_section_id$$Base) return NULL; + if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL; + } +#endif + + ptcb = thread_id; + + if (ptcb->cb_type != TCB) return NULL; + + return ptcb; +} + +/// Convert ID pointer to Object pointer +static void *rt_id2obj (void *id) { + + if ((uint32_t)id & 3) return NULL; + +#ifdef OS_SECTIONS_LINK_INFO + if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { + if (id < (void *)os_section_id$$Base) return NULL; + if (id >= (void *)os_section_id$$Limit) return NULL; + } +#endif + + return id; +} + +// === Helper functions for system call interface === + +static __inline char __get_mode(void) { + return (char)(__get_CPSR() & 0x1f); +} + +static __inline char __exceptional_mode(void) { + switch(__get_mode()) { + case MODE_USR: + case MODE_SYS: + return 0; + case MODE_SVC: + if (IRQNestLevel == 0) + return 0; /* handling a regular service call */ + else + return 1; /* handling an ISR in SVC mode */ + default: + return 1; + } +} + +// ==== Kernel Control ==== + +uint8_t os_initialized; // Kernel Initialized flag +uint8_t os_running; // Kernel Running flag + +// Kernel Control Service Calls declarations +SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus) +SVC_0_1(svcKernelStart, osStatus, RET_osStatus) +SVC_0_1(svcKernelRunning, int32_t, RET_int32_t) + +static void sysThreadError (osStatus status); +osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument); +osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +// Kernel Control Service Calls + +/// Initialize the RTOS Kernel for creating objects +osStatus svcKernelInitialize (void) { +#ifdef __MBED_CMSIS_RTOS_CA9 + if (!os_initialized) { + rt_sys_init(); // RTX System Initialization + } +#else + int ret; + + if (!os_initialized) { + + // Init Thread Stack Memory (must be 8-byte aligned) + if ((uint32_t)os_stack_mem & 7) return osErrorNoMemory; + ret = rt_init_mem(os_stack_mem, os_stack_sz); + if (ret != 0) return osErrorNoMemory; + + rt_sys_init(); // RTX System Initialization + } +#endif + + os_tsk.run->prio = 255; // Highest priority + + if (!os_initialized) { + // Create OS Timers resources (Message Queue & Thread) + osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); + osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL); + } + + sysThreadError(osOK); + + os_initialized = 1; + + return osOK; +} + +/// Start the RTOS Kernel +osStatus svcKernelStart (void) { + + if (os_running) return osOK; + + rt_tsk_prio(0, 0); // Lowest priority + __set_PSP(os_tsk.run->tsk_stack + 8*4); // New context + os_tsk.run = NULL; // Force context switch + + rt_sys_start(); + + os_running = 1; + + return osOK; +} + +/// Check if the RTOS kernel is already started +int32_t svcKernelRunning(void) { + return os_running; +} + +// Kernel Control Public API + +/// Initialize the RTOS Kernel for creating objects +osStatus osKernelInitialize (void) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + if (__get_mode() != MODE_USR) { + return svcKernelInitialize(); + } else { + return __svcKernelInitialize(); + } +} + +/// Start the RTOS Kernel +osStatus osKernelStart (void) { + char mode = __get_mode(); + + switch(mode) { + case MODE_USR: + if (os_flags & 1) return osErrorOS; // Privileged Thread mode requested from Unprivileged + break; + case MODE_SYS: + if (!(os_flags & 1)) { + __set_CPS_USR(); + } + break; + default: + return osErrorISR; // Not allowed in ISR + } + return __svcKernelStart(); +} + +/// Check if the RTOS kernel is already started +int32_t osKernelRunning(void) { + if(__get_mode() != MODE_USR) { + return os_running; + } else { + return __svcKernelRunning(); + } +} + + +// ==== Thread Management ==== + +/// Set Thread Error (for Create functions which return IDs) +static void sysThreadError (osStatus status) { + // To Do +} + +__NO_RETURN void osThreadExit (void); + +// Thread Service Calls declarations +SVC_2_1(svcThreadCreate, osThreadId, const osThreadDef_t *, void *, RET_pointer) +SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) +SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) +SVC_0_1(svcThreadYield, osStatus, RET_osStatus) +SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) +SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) + +// Thread Service Calls + +/// Create a thread and add it to Active Threads and set it to state READY +osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument) { + P_TCB ptcb; + OS_TID tsk; + void *stk; + + if ((thread_def == NULL) || + (thread_def->pthread == NULL) || + (thread_def->tpriority < osPriorityIdle) || + (thread_def->tpriority > osPriorityRealtime)) { + sysThreadError(osErrorParameter); + return NULL; + } + +#ifdef __MBED_CMSIS_RTOS_CA9 + if (thread_def->stacksize != 0) { // Custom stack size + stk = (void *)thread_def->stack_pointer; + } else { // Default stack size + stk = NULL; + } +#else + if (thread_def->stacksize != 0) { // Custom stack size + stk = rt_alloc_mem( // Allocate stack + os_stack_mem, + thread_def->stacksize + ); + if (stk == NULL) { + sysThreadError(osErrorNoMemory); // Out of memory + return NULL; + } + } else { // Default stack size + stk = NULL; + } +#endif + + tsk = rt_tsk_create( // Create task + (FUNCP)thread_def->pthread, // Task function pointer + (thread_def->tpriority-osPriorityIdle+1) | // Task priority + (thread_def->stacksize << 8), // Task stack size in bytes + stk, // Pointer to task's stack + argument // Argument to the task + ); + + if (tsk == 0) { // Invalid task ID +#ifndef __MBED_CMSIS_RTOS_CA9 + if (stk != NULL) { + rt_free_mem(os_stack_mem, stk); // Free allocated stack + } +#endif + sysThreadError(osErrorNoMemory); // Create task failed (Out of memory) + return NULL; + } + + ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer + + *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit; + + return ptcb; +} + +/// Return the thread ID of the current running thread +osThreadId svcThreadGetId (void) { + OS_TID tsk; + + tsk = rt_tsk_self(); + if (tsk == 0) return NULL; + return (P_TCB)os_active_TCB[tsk - 1]; +} + +/// Terminate execution of a thread and remove it from ActiveThreads +osStatus svcThreadTerminate (osThreadId thread_id) { + OS_RESULT res; + P_TCB ptcb; +#ifndef __MBED_CMSIS_RTOS_CA9 + void *stk; +#endif + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + +#ifndef __MBED_CMSIS_RTOS_CA9 + stk = ptcb->priv_stack ? ptcb->stack : NULL; // Private stack +#endif + + res = rt_tsk_delete(ptcb->task_id); // Delete task + + if (res == OS_R_NOK) return osErrorResource; // Delete task failed + +#ifndef __MBED_CMSIS_RTOS_CA9 + if (stk != NULL) { + rt_free_mem(os_stack_mem, stk); // Free private stack + } +#endif + + return osOK; +} + +/// Pass control to next thread that is in state READY +osStatus svcThreadYield (void) { + rt_tsk_pass(); // Pass control to next task + return osOK; +} + +/// Change priority of an active thread +osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) { + OS_RESULT res; + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) { + return osErrorValue; + } + + res = rt_tsk_prio( // Change task priority + ptcb->task_id, // Task ID + priority - osPriorityIdle + 1 // New task priority + ); + + if (res == OS_R_NOK) return osErrorResource; // Change task priority failed + + return osOK; +} + +/// Get current priority of an active thread +osPriority svcThreadGetPriority (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osPriorityError; + + return (osPriority)(ptcb->prio - 1 + osPriorityIdle); +} + + +// Thread Public API + +/// Create a thread and add it to Active Threads and set it to state READY +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcThreadCreate(thread_def, argument); + } else { + return __svcThreadCreate(thread_def, argument); + } +} + +/// Return the thread ID of the current running thread +osThreadId osThreadGetId (void) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + return __svcThreadGetId(); +} + +/// Terminate execution of a thread and remove it from ActiveThreads +osStatus osThreadTerminate (osThreadId thread_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcThreadTerminate(thread_id); +} + +/// Pass control to next thread that is in state READY +osStatus osThreadYield (void) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcThreadYield(); +} + +/// Change priority of an active thread +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcThreadSetPriority(thread_id, priority); +} + +/// Get current priority of an active thread +osPriority osThreadGetPriority (osThreadId thread_id) { + if (__exceptional_mode()) return osPriorityError;// Not allowed in ISR + return __svcThreadGetPriority(thread_id); +} + +/// INTERNAL - Not Public +/// Auto Terminate Thread on exit (used implicitly when thread exists) +__NO_RETURN void osThreadExit (void) { + __svcThreadTerminate(__svcThreadGetId()); + for (;;); // Should never come here +} + +#ifdef __MBED_CMSIS_RTOS_CA9 +/// Get current thread state +uint8_t osThreadGetState (osThreadId thread_id) { + P_TCB ptcb; + + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + return ptcb->state; +} +#endif + +// ==== Generic Wait Functions ==== + +// Generic Wait Service Calls declarations +SVC_1_1(svcDelay, osStatus, uint32_t, RET_osStatus) +#if osFeature_Wait != 0 +SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent) +#endif + +// Generic Wait Service Calls + +/// Wait for Timeout (Time Delay) +osStatus svcDelay (uint32_t millisec) { + if (millisec == 0) return osOK; + rt_dly_wait(rt_ms2tick(millisec)); + return osEventTimeout; +} + +/// Wait for Signal, Message, Mail, or Timeout +#if osFeature_Wait != 0 +os_InRegs osEvent_type svcWait (uint32_t millisec) { + osEvent ret; + + if (millisec == 0) { + ret.status = osOK; +#if defined (__GNUC__) && defined (__ARM_PCS_VFP) + osEvent_ret_status; + return; +#else + return osEvent_ret_status; +#endif + } + + /* To Do: osEventSignal, osEventMessage, osEventMail */ + rt_dly_wait(rt_ms2tick(millisec)); + ret.status = osEventTimeout; + +#if defined (__GNUC__) && defined (__ARM_PCS_VFP) + osEvent_ret_status; + return; +#else + return osEvent_ret_status; +#endif +} +#endif + + +// Generic Wait API + +/// Wait for Timeout (Time Delay) +osStatus osDelay (uint32_t millisec) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcDelay(millisec); +} + +/// Wait for Signal, Message, Mail, or Timeout +os_InRegs osEvent osWait (uint32_t millisec) { + osEvent ret; + +#if osFeature_Wait == 0 + ret.status = osErrorOS; + return ret; +#else + if (__exceptional_mode()) { // Not allowed in ISR + ret.status = osErrorISR; + return ret; + } + return __svcWait(millisec); +#endif +} + + +// ==== Timer Management ==== + +// Timer definitions +#define osTimerInvalid 0 +#define osTimerStopped 1 +#define osTimerRunning 2 + +// Timer structures + +typedef struct os_timer_cb_ { // Timer Control Block + struct os_timer_cb_ *next; // Pointer to next active Timer + uint8_t state; // Timer State + uint8_t type; // Timer Type (Periodic/One-shot) + uint16_t reserved; // Reserved + uint16_t tcnt; // Timer Delay Count + uint16_t icnt; // Timer Initial Count + void *arg; // Timer Function Argument + const osTimerDef_t *timer; // Pointer to Timer definition +} os_timer_cb; + +// Timer variables +os_timer_cb *os_timer_head; // Pointer to first active Timer + + +// Timer Helper Functions + +// Insert Timer into the list sorted by time +static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) { + os_timer_cb *p, *prev; + + prev = NULL; + p = os_timer_head; + while (p != NULL) { + if (tcnt < p->tcnt) break; + tcnt -= p->tcnt; + prev = p; + p = p->next; + } + pt->next = p; + pt->tcnt = (uint16_t)tcnt; + if (p != NULL) { + p->tcnt -= pt->tcnt; + } + if (prev != NULL) { + prev->next = pt; + } else { + os_timer_head = pt; + } +} + +// Remove Timer from the list +static int rt_timer_remove (os_timer_cb *pt) { + os_timer_cb *p, *prev; + + prev = NULL; + p = os_timer_head; + while (p != NULL) { + if (p == pt) break; + prev = p; + p = p->next; + } + if (p == NULL) return -1; + if (prev != NULL) { + prev->next = pt->next; + } else { + os_timer_head = pt->next; + } + if (pt->next != NULL) { + pt->next->tcnt += pt->tcnt; + } + + return 0; +} + + +// Timer Service Calls declarations +SVC_3_1(svcTimerCreate, osTimerId, const osTimerDef_t *, os_timer_type, void *, RET_pointer) +SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus) +SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus) +SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus) +SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback) + +// Timer Management Service Calls + +/// Create timer +osTimerId svcTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { + os_timer_cb *pt; + + if ((timer_def == NULL) || (timer_def->ptimer == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + pt = timer_def->timer; + if (pt == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if ((type != osTimerOnce) && (type != osTimerPeriodic)) { + sysThreadError(osErrorValue); + return NULL; + } + + if (osThreadId_osTimerThread == NULL) { + sysThreadError(osErrorResource); + return NULL; + } + + if (pt->state != osTimerInvalid){ + sysThreadError(osErrorResource); + return NULL; + } + + pt->state = osTimerStopped; + pt->type = (uint8_t)type; + pt->arg = argument; + pt->timer = timer_def; + + return (osTimerId)pt; +} + +/// Start or restart timer +osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) { + os_timer_cb *pt; + uint32_t tcnt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + tcnt = rt_ms2tick(millisec); + if (tcnt == 0) return osErrorValue; + + switch (pt->state) { + case osTimerRunning: + if (rt_timer_remove(pt) != 0) { + return osErrorResource; + } + break; + case osTimerStopped: + pt->state = osTimerRunning; + pt->icnt = (uint16_t)tcnt; + break; + default: + return osErrorResource; + } + + rt_timer_insert(pt, tcnt); + + return osOK; +} + +/// Stop timer +osStatus svcTimerStop (osTimerId timer_id) { + os_timer_cb *pt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + if (pt->state != osTimerRunning) return osErrorResource; + + pt->state = osTimerStopped; + + if (rt_timer_remove(pt) != 0) { + return osErrorResource; + } + + return osOK; +} + +/// Delete timer +osStatus svcTimerDelete (osTimerId timer_id) { + os_timer_cb *pt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + switch (pt->state) { + case osTimerRunning: + rt_timer_remove(pt); + break; + case osTimerStopped: + break; + default: + return osErrorResource; + } + + pt->state = osTimerInvalid; + + return osOK; +} + +/// Get timer callback parameters +os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) { + os_timer_cb *pt; + osCallback ret; + + pt = rt_id2obj(timer_id); + if (pt == NULL) { + ret.fp = NULL; + ret.arg = NULL; +#if defined (__GNUC__) && defined (__ARM_PCS_VFP) + osCallback_ret; + return; +#else + return osCallback_ret; +#endif + } + + ret.fp = (void *)pt->timer->ptimer; + ret.arg = pt->arg; + +#if defined (__GNUC__) && defined (__ARM_PCS_VFP) + osCallback_ret; + return; +#else + return osCallback_ret; +#endif +} + +static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Timer Tick (called each SysTick) +void sysTimerTick (void) { + os_timer_cb *pt, *p; + + p = os_timer_head; + if (p == NULL) return; + + p->tcnt--; + while ((p != NULL) && (p->tcnt == 0)) { + pt = p; + p = p->next; + os_timer_head = p; + isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0); + if (pt->type == osTimerPeriodic) { + rt_timer_insert(pt, pt->icnt); + } else { + pt->state = osTimerStopped; + } + } +} + + +// Timer Management Public API + +/// Create timer +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcTimerCreate(timer_def, type, argument); + } else { + return __svcTimerCreate(timer_def, type, argument); + } +} + +/// Start or restart timer +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcTimerStart(timer_id, millisec); +} + +/// Stop timer +osStatus osTimerStop (osTimerId timer_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcTimerStop(timer_id); +} + +/// Delete timer +osStatus osTimerDelete (osTimerId timer_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcTimerDelete(timer_id); +} + +/// INTERNAL - Not Public +/// Get timer callback parameters (used by OS Timer Thread) +os_InRegs osCallback osTimerCall (osTimerId timer_id) { + return __svcTimerCall(timer_id); +} + + +// Timer Thread +__NO_RETURN void osTimerThread (void const *argument) { + osCallback cb; + osEvent evt; + + for (;;) { + evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever); + if (evt.status == osEventMessage) { + cb = osTimerCall(evt.value.p); + if (cb.fp != NULL) { + (*(os_ptimer)cb.fp)(cb.arg); + } + } + } +} + + +// ==== Signal Management ==== + +// Signal Service Calls declarations +SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t) +SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t) +SVC_1_1(svcSignalGet, int32_t, osThreadId, RET_int32_t) +SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent) + +// Signal Service Calls + +/// Set the specified Signal Flags of an active thread +int32_t svcSignalSet (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + rt_evt_set(signals, ptcb->task_id); // Set event flags + + return sig; +} + +/// Clear the specified Signal Flags of an active thread +int32_t svcSignalClear (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + rt_evt_clr(signals, ptcb->task_id); // Clear event flags + + return sig; +} + +/// Get Signal Flags status of an active thread +int32_t svcSignalGet (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + return ptcb->events; // Return event flags +} + +/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread +os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) { + ret.status = osErrorValue; +#if defined (__GNUC__) && defined (__ARM_PCS_VFP) + osEvent_ret_status; + return; +#else + return osEvent_ret_status; +#endif + } + + if (signals != 0) { // Wait for all specified signals + res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE); + } else { // Wait for any signal + res = rt_evt_wait(0xFFFF, rt_ms2tick(millisec), __FALSE); + } + + if (res == OS_R_EVT) { + ret.status = osEventSignal; + ret.value.signals = signals ? signals : os_tsk.run->waits; + } else { + ret.status = millisec ? osEventTimeout : osOK; + ret.value.signals = 0; + } + +#if defined (__GNUC__) && defined (__ARM_PCS_VFP) + osEvent_ret_value; + return; +#else + return osEvent_ret_value; +#endif +} + + +// Signal ISR Calls + +/// Set the specified Signal Flags of an active thread +static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + isr_evt_set(signals, ptcb->task_id); // Set event flags + + return sig; +} + + +// Signal Public API + +/// Set the specified Signal Flags of an active thread +int32_t osSignalSet (osThreadId thread_id, int32_t signals) { + if (__exceptional_mode()) { // in ISR + return isrSignalSet(thread_id, signals); + } else { // in Thread + return __svcSignalSet(thread_id, signals); + } +} + +/// Clear the specified Signal Flags of an active thread +int32_t osSignalClear (osThreadId thread_id, int32_t signals) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcSignalClear(thread_id, signals); +} + +/// Get Signal Flags status of an active thread +int32_t osSignalGet (osThreadId thread_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcSignalGet(thread_id); +} + +/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) { + osEvent ret; + + if (__exceptional_mode()) { // Not allowed in ISR + ret.status = osErrorISR; + return ret; + } + return __svcSignalWait(signals, millisec); +} + + +// ==== Mutex Management ==== + +// Mutex Service Calls declarations +SVC_1_1(svcMutexCreate, osMutexId, const osMutexDef_t *, RET_pointer) +SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus) +SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus) +SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus) + +// Mutex Service Calls + +/// Create and Initialize a Mutex object +osMutexId svcMutexCreate (const osMutexDef_t *mutex_def) { + OS_ID mut; + + if (mutex_def == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + mut = mutex_def->mutex; + if (mut == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_MUCB)mut)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + rt_mut_init(mut); // Initialize Mutex + + return mut; +} + +/// Wait until a Mutex becomes available +osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) { + OS_ID mut; + OS_RESULT res; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex + + if (res == OS_R_TMO) { + return (millisec ? osErrorTimeoutResource : osErrorResource); + } + + return osOK; +} + +/// Release a Mutex that was obtained with osMutexWait +osStatus svcMutexRelease (osMutexId mutex_id) { + OS_ID mut; + OS_RESULT res; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + res = rt_mut_release(mut); // Release Mutex + + if (res == OS_R_NOK) return osErrorResource; // Thread not owner or Zero Counter + + return osOK; +} + +/// Delete a Mutex that was created by osMutexCreate +osStatus svcMutexDelete (osMutexId mutex_id) { + OS_ID mut; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + rt_mut_delete(mut); // Release Mutex + + return osOK; +} + + +// Mutex Public API + +/// Create and Initialize a Mutex object +osMutexId osMutexCreate (const osMutexDef_t *mutex_def) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcMutexCreate(mutex_def); + } else { + return __svcMutexCreate(mutex_def); + } +} + +/// Wait until a Mutex becomes available +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcMutexWait(mutex_id, millisec); +} + +/// Release a Mutex that was obtained with osMutexWait +osStatus osMutexRelease (osMutexId mutex_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcMutexRelease(mutex_id); +} + +/// Delete a Mutex that was created by osMutexCreate +osStatus osMutexDelete (osMutexId mutex_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcMutexDelete(mutex_id); +} + + +// ==== Semaphore Management ==== + +// Semaphore Service Calls declarations +SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer) +SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t) +SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus) +SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus) + +// Semaphore Service Calls + +/// Create and Initialize a Semaphore object +osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + OS_ID sem; + + if (semaphore_def == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + sem = semaphore_def->semaphore; + if (sem == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_SCB)sem)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (count > osFeature_Semaphore) { + sysThreadError(osErrorValue); + return NULL; + } + + rt_sem_init(sem, count); // Initialize Semaphore + + return sem; +} + +/// Wait until a Semaphore becomes available +int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + OS_ID sem; + OS_RESULT res; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return -1; + + if (((P_SCB)sem)->cb_type != SCB) return -1; + + res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore + + if (res == OS_R_TMO) return 0; // Timeout + + return (((P_SCB)sem)->tokens + 1); +} + +/// Release a Semaphore +osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + + rt_sem_send(sem); // Release Semaphore + + return osOK; +} + +/// Delete a Semaphore that was created by osSemaphoreCreate +osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + rt_sem_delete(sem); // Delete Semaphore + + return osOK; +} + + +// Semaphore ISR Calls + +/// Release a Semaphore +static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + + isr_sem_send(sem); // Release Semaphore + + return osOK; +} + + +// Semaphore Public API + +/// Create and Initialize a Semaphore object +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcSemaphoreCreate(semaphore_def, count); + } else { + return __svcSemaphoreCreate(semaphore_def, count); + } +} + +/// Wait until a Semaphore becomes available +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + if (__exceptional_mode()) return -1; // Not allowed in ISR + return __svcSemaphoreWait(semaphore_id, millisec); +} + +/// Release a Semaphore +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) { + if (__exceptional_mode()) { // in ISR + return isrSemaphoreRelease(semaphore_id); + } else { // in Thread + return __svcSemaphoreRelease(semaphore_id); + } +} + +/// Delete a Semaphore that was created by osSemaphoreCreate +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) { + if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR + return __svcSemaphoreDelete(semaphore_id); +} + + +// ==== Memory Management Functions ==== + +// Memory Management Helper Functions + +// Clear Memory Box (Zero init) +static void rt_clr_box (void *box_mem, void *box) { + uint32_t *p, n; + + if (box) { + p = box; + for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) { + *p++ = 0; + } + } +} + +// Memory Management Service Calls declarations +SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer) +SVC_2_1(sysPoolAlloc, void *, osPoolId, uint32_t, RET_pointer) +SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus) + +// Memory Management Service & ISR Calls + +/// Create and Initialize memory pool +osPoolId svcPoolCreate (const osPoolDef_t *pool_def) { + uint32_t blk_sz; + + if ((pool_def == NULL) || + (pool_def->pool_sz == 0) || + (pool_def->item_sz == 0) || + (pool_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + blk_sz = (pool_def->item_sz + 3) & ~3; + + _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz); + + return pool_def->pool; +} + +/// Allocate a memory block from a memory pool +void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) { + void *ptr; + + if (pool_id == NULL) return NULL; + + ptr = rt_alloc_box(pool_id); + if (clr) { + rt_clr_box(pool_id, ptr); + } + + return ptr; +} + +/// Return an allocated memory block back to a specific memory pool +osStatus sysPoolFree (osPoolId pool_id, void *block) { + int32_t res; + + if (pool_id == NULL) return osErrorParameter; + + res = rt_free_box(pool_id, block); + if (res != 0) return osErrorValue; + + return osOK; +} + + +// Memory Management Public API + +/// Create and Initialize memory pool +osPoolId osPoolCreate (const osPoolDef_t *pool_def) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcPoolCreate(pool_def); + } else { + return __svcPoolCreate(pool_def); + } +} + +/// Allocate a memory block from a memory pool +void *osPoolAlloc (osPoolId pool_id) { + if (__get_mode() != MODE_USR) { // in ISR or Privileged + return sysPoolAlloc(pool_id, 0); + } else { // in Thread + return __sysPoolAlloc(pool_id, 0); + } +} + +/// Allocate a memory block from a memory pool and set memory block to zero +void *osPoolCAlloc (osPoolId pool_id) { + if (__get_mode() != MODE_USR) { // in ISR or Privileged + return sysPoolAlloc(pool_id, 1); + } else { // in Thread + return __sysPoolAlloc(pool_id, 1); + } +} + +/// Return an allocated memory block back to a specific memory pool +osStatus osPoolFree (osPoolId pool_id, void *block) { + if (__get_mode() != MODE_USR) { // in ISR or Privileged + return sysPoolFree(pool_id, block); + } else { // in Thread + return __sysPoolFree(pool_id, block); + } +} + + +// ==== Message Queue Management Functions ==== + +// Message Queue Management Service Calls declarations +SVC_2_1(svcMessageCreate, osMessageQId, const osMessageQDef_t *, osThreadId, RET_pointer) +SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus) +SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent) + +// Message Queue Service Calls + +/// Create and Initialize Message Queue +osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { + + if ((queue_def == NULL) || + (queue_def->queue_sz == 0) || + (queue_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_MCB)queue_def->pool)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4)); + + return queue_def->pool; +} + +/// Put a Message to a Queue +osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + OS_RESULT res; + + if (queue_id == NULL) return osErrorParameter; + + if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + + res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec)); + + if (res == OS_R_TMO) { + return (millisec ? osErrorTimeoutResource : osErrorResource); + } + + return osOK; +} + +/// Get a Message or Wait for a Message from a Queue +os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if (queue_id == NULL) { + ret.status = osErrorParameter; +#if defined (__GNUC__) && defined (__ARM_PCS_VFP) + osEvent_ret_status; + return; +#else + return osEvent_ret_status; +#endif + } + + if (((P_MCB)queue_id)->cb_type != MCB) { + ret.status = osErrorParameter; +#if defined (__GNUC__) && defined (__ARM_PCS_VFP) + osEvent_ret_status; + return; +#else + return osEvent_ret_status; +#endif + } + + res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec)); + + if (res == OS_R_TMO) { + ret.status = millisec ? osEventTimeout : osOK; +#if defined (__GNUC__) && defined (__ARM_PCS_VFP) + osEvent_ret_value; + return; +#else + return osEvent_ret_value; +#endif + } + + ret.status = osEventMessage; + +#if defined (__GNUC__) && defined (__ARM_PCS_VFP) + osEvent_ret_value; + return; +#else + return osEvent_ret_value; +#endif +} + + +// Message Queue ISR Calls + +/// Put a Message to a Queue +static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + + if ((queue_id == NULL) || (millisec != 0)) { + return osErrorParameter; + } + + if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + + if (rt_mbx_check(queue_id) == 0) { // Check if Queue is full + return osErrorResource; + } + + isr_mbx_send(queue_id, (void *)info); + + return osOK; +} + +/// Get a Message or Wait for a Message from a Queue +static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if ((queue_id == NULL) || (millisec != 0)) { + ret.status = osErrorParameter; + return ret; + } + + if (((P_MCB)queue_id)->cb_type != MCB) { + ret.status = osErrorParameter; + return ret; + } + + res = isr_mbx_receive(queue_id, &ret.value.p); + + if (res != OS_R_MBX) { + ret.status = osOK; + return ret; + } + + ret.status = osEventMessage; + + return ret; +} + + +// Message Queue Management Public API + +/// Create and Initialize Message Queue +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcMessageCreate(queue_def, thread_id); + } else { + return __svcMessageCreate(queue_def, thread_id); + } +} + +/// Put a Message to a Queue +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + if (__exceptional_mode()) { // in ISR + return isrMessagePut(queue_id, info, millisec); + } else { // in Thread + return __svcMessagePut(queue_id, info, millisec); + } +} + +/// Get a Message or Wait for a Message from a Queue +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { + if (__exceptional_mode()) { // in ISR + return isrMessageGet(queue_id, millisec); + } else { // in Thread + return __svcMessageGet(queue_id, millisec); + } +} + + +// ==== Mail Queue Management Functions ==== + +// Mail Queue Management Service Calls declarations +SVC_2_1(svcMailCreate, osMailQId, const osMailQDef_t *, osThreadId, RET_pointer) +SVC_4_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, uint32_t, RET_pointer) +SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus) + +// Mail Queue Management Service & ISR Calls + +/// Create and Initialize mail queue +osMailQId svcMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { + uint32_t blk_sz; + P_MCB pmcb; + void *pool; + + if ((queue_def == NULL) || + (queue_def->queue_sz == 0) || + (queue_def->item_sz == 0) || + (queue_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + pmcb = *(((void **)queue_def->pool) + 0); + pool = *(((void **)queue_def->pool) + 1); + + if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) { + sysThreadError(osErrorParameter); + return NULL; + } + + blk_sz = (queue_def->item_sz + 3) & ~3; + + _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz); + + rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4)); + + + return queue_def->pool; +} + +/// Allocate a memory block from a mail +void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) { + P_MCB pmcb; + void *pool; + void *mem; + + if (queue_id == NULL) return NULL; + + pmcb = *(((void **)queue_id) + 0); + pool = *(((void **)queue_id) + 1); + + if ((pool == NULL) || (pmcb == NULL)) return NULL; + + if (isr && (millisec != 0)) return NULL; + + mem = rt_alloc_box(pool); + if (clr) { + rt_clr_box(pool, mem); + } + + if ((mem == NULL) && (millisec != 0)) { + // Put Task to sleep when Memory not available + if (pmcb->p_lnk != NULL) { + rt_put_prio((P_XCB)pmcb, os_tsk.run); + } else { + pmcb->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)pmcb; + // Task is waiting to allocate a message + pmcb->state = 3; + } + rt_block(rt_ms2tick(millisec), WAIT_MBX); + } + + return mem; +} + +/// Free a memory block from a mail +osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) { + P_MCB pmcb; + P_TCB ptcb; + void *pool; + void *mem; + int32_t res; + + if (queue_id == NULL) return osErrorParameter; + + pmcb = *(((void **)queue_id) + 0); + pool = *(((void **)queue_id) + 1); + + if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter; + + res = rt_free_box(pool, mail); + + if (res != 0) return osErrorValue; + + if (pmcb->state == 3) { + // Task is waiting to allocate a message + if (isr) { + rt_psq_enq (pmcb, (U32)pool); + rt_psh_req (); + } else { + mem = rt_alloc_box(pool); + if (mem != NULL) { + ptcb = rt_get_first((P_XCB)pmcb); + if (pmcb->p_lnk == NULL) { + pmcb->state = 0; + } + rt_ret_val(ptcb, (U32)mem); + rt_rmv_dly(ptcb); + rt_dispatch(ptcb); + } + } + } + + return osOK; +} + + +// Mail Queue Management Public API + +/// Create and Initialize mail queue +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { + if (__exceptional_mode()) return NULL; // Not allowed in ISR + if ((__get_mode() != MODE_USR) && (os_running == 0)) { + // Privileged and not running + return svcMailCreate(queue_def, thread_id); + } else { + return __svcMailCreate(queue_def, thread_id); + } +} + +/// Allocate a memory block from a mail +void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { + if (__exceptional_mode()) { // in ISR + return sysMailAlloc(queue_id, millisec, 1, 0); + } else { // in Thread + return __sysMailAlloc(queue_id, millisec, 0, 0); + } +} + +/// Allocate a memory block from a mail and set memory block to zero +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { + if (__exceptional_mode()) { // in ISR + return sysMailAlloc(queue_id, millisec, 1, 1); + } else { // in Thread + return __sysMailAlloc(queue_id, millisec, 0, 1); + } +} + +/// Free a memory block from a mail +osStatus osMailFree (osMailQId queue_id, void *mail) { + if (__exceptional_mode()) { // in ISR + return sysMailFree(queue_id, mail, 1); + } else { // in Thread + return __sysMailFree(queue_id, mail, 0); + } +} + +/// Put a mail to a queue +osStatus osMailPut (osMailQId queue_id, void *mail) { + if (queue_id == NULL) return osErrorParameter; + if (mail == NULL) return osErrorValue; + return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0); +} + +#ifdef __CC_ARM +#pragma push +#pragma Ospace +#endif // __arm__ +/// Get a mail from a queue +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { + osEvent ret; + + if (queue_id == NULL) { + ret.status = osErrorParameter; + return ret; + } + + ret = osMessageGet(*((void **)queue_id), millisec); + if (ret.status == osEventMessage) ret.status = osEventMail; + + return ret; +} +#ifdef __CC_ARM +#pragma pop +#endif // __arm__ diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Event.c b/rtos/rtx/TARGET_CORTEX_A/rt_Event.c new file mode 100644 index 0000000..1ea088f --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Event.c @@ -0,0 +1,194 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_EVENT.C + * Purpose: Implements waits and wake-ups for event flags + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Task.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_evt_wait -----------------------------------*/ + +OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) { + /* Wait for one or more event flags with optional time-out. */ + /* "wait_flags" identifies the flags to wait for. */ + /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */ + /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */ + /* to complete the wait. (OR-ing if set to 0). */ + U32 block_state; + + if (and_wait) { + /* Check for AND-connected events */ + if ((os_tsk.run->events & wait_flags) == wait_flags) { + os_tsk.run->events &= ~wait_flags; + return (OS_R_EVT); + } + block_state = WAIT_AND; + } + else { + /* Check for OR-connected events */ + if (os_tsk.run->events & wait_flags) { + os_tsk.run->waits = os_tsk.run->events & wait_flags; + os_tsk.run->events &= ~wait_flags; + return (OS_R_EVT); + } + block_state = WAIT_OR; + } + /* Task has to wait */ + os_tsk.run->waits = wait_flags; + rt_block (timeout, (U8)block_state); + return (OS_R_TMO); +} + + +/*--------------------------- rt_evt_set ------------------------------------*/ + +void rt_evt_set (U16 event_flags, OS_TID task_id) { + /* Set one or more event flags of a selectable task. */ + P_TCB p_tcb; + + p_tcb = os_active_TCB[task_id-1]; + if (p_tcb == NULL) { + return; + } + p_tcb->events |= event_flags; + event_flags = p_tcb->waits; + /* If the task is not waiting for an event, it should not be put */ + /* to ready state. */ + if (p_tcb->state == WAIT_AND) { + /* Check for AND-connected events */ + if ((p_tcb->events & event_flags) == event_flags) { + goto wkup; + } + } + if (p_tcb->state == WAIT_OR) { + /* Check for OR-connected events */ + if (p_tcb->events & event_flags) { + p_tcb->waits &= p_tcb->events; +wkup: p_tcb->events &= ~event_flags; + rt_rmv_dly (p_tcb); + p_tcb->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val2(p_tcb, 0x08/*osEventSignal*/, p_tcb->waits); +#else + rt_ret_val (p_tcb, OS_R_EVT); +#endif + rt_dispatch (p_tcb); + } + } +} + + +/*--------------------------- rt_evt_clr ------------------------------------*/ + +void rt_evt_clr (U16 clear_flags, OS_TID task_id) { + /* Clear one or more event flags (identified by "clear_flags") of a */ + /* selectable task (identified by "task"). */ + P_TCB task = os_active_TCB[task_id-1]; + + if (task == NULL) { + return; + } + task->events &= ~clear_flags; +} + + +/*--------------------------- isr_evt_set -----------------------------------*/ + +void isr_evt_set (U16 event_flags, OS_TID task_id) { + /* Same function as "os_evt_set", but to be called by ISRs. */ + P_TCB p_tcb = os_active_TCB[task_id-1]; + + if (p_tcb == NULL) { + return; + } + rt_psq_enq (p_tcb, event_flags); + rt_psh_req (); +} + + +/*--------------------------- rt_evt_get ------------------------------------*/ + +U16 rt_evt_get (void) { + /* Get events of a running task after waiting for OR connected events. */ + return (os_tsk.run->waits); +} + + +/*--------------------------- rt_evt_psh ------------------------------------*/ + +void rt_evt_psh (P_TCB p_CB, U16 set_flags) { + /* Check if task has to be waken up */ + U16 event_flags; + + p_CB->events |= set_flags; + event_flags = p_CB->waits; + if (p_CB->state == WAIT_AND) { + /* Check for AND-connected events */ + if ((p_CB->events & event_flags) == event_flags) { + goto rdy; + } + } + if (p_CB->state == WAIT_OR) { + /* Check for OR-connected events */ + if (p_CB->events & event_flags) { + p_CB->waits &= p_CB->events; +rdy: p_CB->events &= ~event_flags; + rt_rmv_dly (p_CB); + p_CB->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val2(p_CB, 0x08/*osEventSignal*/, p_CB->waits); +#else + rt_ret_val (p_CB, OS_R_EVT); +#endif + rt_put_prio (&os_rdy, p_CB); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Event.h b/rtos/rtx/TARGET_CORTEX_A/rt_Event.h new file mode 100644 index 0000000..8b92f3c --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Event.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_EVENT.H + * Purpose: Implements waits and wake-ups for event flags + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait); +extern void rt_evt_set (U16 event_flags, OS_TID task_id); +extern void rt_evt_clr (U16 clear_flags, OS_TID task_id); +extern void isr_evt_set (U16 event_flags, OS_TID task_id); +extern U16 rt_evt_get (void); +extern void rt_evt_psh (P_TCB p_CB, U16 set_flags); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_HAL_CA.h b/rtos/rtx/TARGET_CORTEX_A/rt_HAL_CA.h new file mode 100644 index 0000000..57d0cf1 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_HAL_CA.h @@ -0,0 +1,207 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_HAL_CM.H + * Purpose: Hardware Abstraction Layer for Cortex-A definitions + * Rev.: 21 Aug 2013 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Definitions */ +#define INIT_CPSR_SYS 0x4000001F +#define INIT_CPSR_USER 0x40000010 + +#define CPSR_T_BIT 0x20 +#define CPSR_I_BIT 0x80 +#define CPSR_F_BIT 0x40 + +#define MODE_USR 0x10 +#define MODE_FIQ 0x11 +#define MODE_IRQ 0x12 +#define MODE_SVC 0x13 +#define MODE_ABT 0x17 +#define MODE_UND 0x1B +#define MODE_SYS 0x1F + +#define MAGIC_WORD 0xE25A2EA5 + +#include "core_ca9.h" + +#if defined (__CC_ARM) /* ARM Compiler */ + +#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M || __TARGET_ARCH_7_A) && !defined(NO_EXCLUSIVE_ACCESS)) + #define __USE_EXCLUSIVE_ACCESS +#else + #undef __USE_EXCLUSIVE_ACCESS +#endif + +#elif defined (__GNUC__) /* GNU Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline +#define __weak __attribute__((weak)) + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#error IAR Compiler support not implemented for Cortex-A + +#endif + +static U8 priority = 0xff; + +extern const U32 GICDistributor_BASE; +extern const U32 GICInterface_BASE; + +/* GIC registers - Distributor */ +#define GICD_ICDICER0 (*((volatile U32 *)(GICDistributor_BASE + 0x180))) /* - RW - Interrupt Clear-Enable Registers */ +#define GICD_ICDISER0 (*((volatile U32 *)(GICDistributor_BASE + 0x100))) /* - RW - Interrupt Set-Enable Registers */ +#define GICD_ICDIPR0 (*((volatile U32 *)(GICDistributor_BASE + 0x400))) /* - RW - Interrupt Priority Registers */ +#define GICD_ICDSGIR (*((volatile U32 *)(GICDistributor_BASE + 0xf00))) /* - RW - Interrupt Software Interrupt Register */ +#define GICD_ICDICERx(irq) *(volatile U32 *)(&GICD_ICDICER0 + irq/32) +#define GICD_ICDISERx(irq) *(volatile U32 *)(&GICD_ICDISER0 + irq/32) + +/* GIC register - CPU Interface */ +#define GICI_ICCPMR (*((volatile U32 *)(GICInterface_BASE + 0x004))) /* - RW - Interrupt Priority Mask Register */ + +#define SGI_PENDSV 0 /* SGI0 */ +#define SGI_PENDSV_BIT ((U32)(1 << (SGI_PENDSV & 0xf))) + +//Increase priority filter to prevent timer and PendSV interrupts signaling. Guarantees that interrupts will not be forwarded. +#define OS_LOCK() int irq_dis = __disable_irq();\ + priority = GICI_ICCPMR; \ + GICI_ICCPMR = 0xff; \ + GICI_ICCPMR = GICI_ICCPMR - 1; \ + __DSB();\ + if(!irq_dis) __enable_irq(); \ + +//Restore priority filter. Re-enable timer and PendSV signaling +#define OS_UNLOCK() __DSB(); \ + GICI_ICCPMR = priority; \ + +#define OS_PEND_IRQ() GICD_ICDSGIR = 0x0010000 | SGI_PENDSV +#define OS_PEND(fl,p) if(p) OS_PEND_IRQ(); +#define OS_UNPEND(fl) + +/* HW initialization needs to be done in os_tick_init (void) -RTX_Conf_CM.c- + * OS_X_INIT enables the IRQ n in the GIC */ +#define OS_X_INIT(n) volatile char *reg; \ + reg = (char *)(&GICD_ICDIPR0 + n / 4); \ + reg += n % 4; \ + *reg = (char)0xff; \ + *reg = *reg - 1; \ + GICD_ICDISERx(n) = (U32)(1 << n % 32); +#define OS_X_LOCK(n) OS_LOCK() +#define OS_X_UNLOCK(n) OS_UNLOCK() +#define OS_X_PEND_IRQ() OS_PEND_IRQ() +#define OS_X_PEND(fl,p) if(p) OS_X_PEND_IRQ(); +#define OS_X_UNPEND(fl) + + +/* Functions */ +#ifdef __USE_EXCLUSIVE_ACCESS + #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) + #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) +#else + #define rt_inc(p) { int irq_dis = __disable_irq();(*p)++;if(!irq_dis) __enable_irq(); } + #define rt_dec(p) { int irq_dis = __disable_irq();(*p)--;if(!irq_dis) __enable_irq(); } +#endif + +__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { + U32 cnt,c2; +#ifdef __USE_EXCLUSIVE_ACCESS + do { + if ((cnt = __ldrex(count)) == size) { + __clrex(); + return (cnt); } + } while (__strex(cnt+1, count)); + do { + c2 = (cnt = __ldrex(first)) + 1; + if (c2 == size) c2 = 0; + } while (__strex(c2, first)); +#else + int irq_dis; + irq_dis = __disable_irq(); + if ((cnt = *count) < size) { + *count = cnt+1; + c2 = (cnt = *first) + 1; + if (c2 == size) c2 = 0; + *first = c2; + } + if(!irq_dis) __enable_irq (); +#endif + return (cnt); +} + +__inline static void rt_systick_init (void) { + /* Cortex-A doesn't have a Systick. User needs to provide an alternative timer using RTX_Conf_CM configuration */ + /* HW initialization needs to be done in os_tick_init (void) -RTX_Conf_CM.c- */ +} + +__inline static void rt_svc_init (void) { + /* Register pendSV - through SGI */ + volatile char *reg; + + reg = (char *)(&GICD_ICDIPR0 + SGI_PENDSV/4); + reg += SGI_PENDSV % 4; + /* Write 0xff to read priority level */ + *reg = (char)0xff; + /* Read priority level and set the lowest possible*/ + *reg = *reg - 1; + + GICD_ICDISERx(SGI_PENDSV) = (U32)SGI_PENDSV_BIT; +} + +extern void rt_set_PSP (U32 stack); +extern U32 rt_get_PSP (void); +extern void os_set_env (P_TCB p_TCB); +extern void *_alloc_box (void *box_mem); +extern int _free_box (void *box_mem, void *box); + +extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); +extern void rt_ret_val (P_TCB p_TCB, U32 v0); +extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); + +extern void dbg_init (void); +extern void dbg_task_notify (P_TCB p_tcb, BOOL create); +extern void dbg_task_switch (U32 task_id); + +#define DBG_INIT() +#define DBG_TASK_NOTIFY(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_HAL_CM.h b/rtos/rtx/TARGET_CORTEX_A/rt_HAL_CM.h new file mode 100644 index 0000000..eade36d --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_HAL_CM.h @@ -0,0 +1,276 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_HAL_CM.H + * Purpose: Hardware Abstraction Layer for Cortex-M definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Definitions */ +#define INITIAL_xPSR 0x01000000 +#define DEMCR_TRCENA 0x01000000 +#define ITM_ITMENA 0x00000001 +#define MAGIC_WORD 0xE25A2EA5 + +#if defined (__CC_ARM) /* ARM Compiler */ + +#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS) + #define __USE_EXCLUSIVE_ACCESS +#else + #undef __USE_EXCLUSIVE_ACCESS +#endif + +#elif defined (__GNUC__) /* GNU Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if defined (__CORTEX_M0) +#define __TARGET_ARCH_6S_M 1 +#else +#define __TARGET_ARCH_6S_M 0 +#endif + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline +#define __weak __attribute__((weak)) + +#ifndef __CMSIS_GENERIC + +__attribute__((always_inline)) static inline void __enable_irq(void) +{ + __asm volatile ("cpsie i"); +} + +__attribute__((always_inline)) static inline U32 __disable_irq(void) +{ + U32 result; + + __asm volatile ("mrs %0, primask" : "=r" (result)); + __asm volatile ("cpsid i"); + return(result & 1); +} + +#endif + +__attribute__(( always_inline)) static inline U8 __clz(U32 value) +{ + U8 result; + + __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); + return(result); +} + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if (__CORE__ == __ARM6M__) +#define __TARGET_ARCH_6S_M 1 +#else +#define __TARGET_ARCH_6S_M 0 +#endif + +#if defined __ARMVFP__ +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline + +#ifndef __CMSIS_GENERIC + +static inline void __enable_irq(void) +{ + __asm volatile ("cpsie i"); +} + +static inline U32 __disable_irq(void) +{ + U32 result; + + __asm volatile ("mrs %0, primask" : "=r" (result)); + __asm volatile ("cpsid i"); + return(result & 1); +} + +#endif + +static inline U8 __clz(U32 value) +{ + U8 result; + + __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); + return(result); +} + +#endif + +/* NVIC registers */ +#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010)) +#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014)) +#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018)) +#define NVIC_ISER ((volatile U32 *)0xE000E100) +#define NVIC_ICER ((volatile U32 *)0xE000E180) +#if (__TARGET_ARCH_6S_M) +#define NVIC_IP ((volatile U32 *)0xE000E400) +#else +#define NVIC_IP ((volatile U8 *)0xE000E400) +#endif +#define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04)) +#define NVIC_AIR_CTRL (*((volatile U32 *)0xE000ED0C)) +#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1C)) +#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20)) + +#define OS_PEND_IRQ() NVIC_INT_CTRL = (1<<28) +#define OS_PENDING ((NVIC_INT_CTRL >> 26) & (1<<2 | 1)) +#define OS_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_PENDING) << 25 +#define OS_PEND(fl,p) NVIC_INT_CTRL = (fl | p<<2) << 26 +#define OS_LOCK() NVIC_ST_CTRL = 0x0005 +#define OS_UNLOCK() NVIC_ST_CTRL = 0x0007 + +#define OS_X_PENDING ((NVIC_INT_CTRL >> 28) & 1) +#define OS_X_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_X_PENDING) << 27 +#define OS_X_PEND(fl,p) NVIC_INT_CTRL = (fl | p) << 28 +#if (__TARGET_ARCH_6S_M) +#define OS_X_INIT(n) NVIC_IP[n>>2] |= 0xFF << (8*(n & 0x03)); \ + NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#else +#define OS_X_INIT(n) NVIC_IP[n] = 0xFF; \ + NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#endif +#define OS_X_LOCK(n) NVIC_ICER[n>>5] = 1 << (n & 0x1F) +#define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = 1 << (n & 0x1F) + +/* Core Debug registers */ +#define DEMCR (*((volatile U32 *)0xE000EDFC)) + +/* ITM registers */ +#define ITM_CONTROL (*((volatile U32 *)0xE0000E80)) +#define ITM_ENABLE (*((volatile U32 *)0xE0000E00)) +#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078)) +#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007C)) +#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007C)) +#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007C)) + +/* Variables */ +extern BIT dbg_msg; + +/* Functions */ +#ifdef __USE_EXCLUSIVE_ACCESS + #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) + #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) +#else + #define rt_inc(p) __disable_irq();(*p)++;__enable_irq(); + #define rt_dec(p) __disable_irq();(*p)--;__enable_irq(); +#endif + +__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { + U32 cnt,c2; +#ifdef __USE_EXCLUSIVE_ACCESS + do { + if ((cnt = __ldrex(count)) == size) { + __clrex(); + return (cnt); } + } while (__strex(cnt+1, count)); + do { + c2 = (cnt = __ldrex(first)) + 1; + if (c2 == size) c2 = 0; + } while (__strex(c2, first)); +#else + __disable_irq(); + if ((cnt = *count) < size) { + *count = cnt+1; + c2 = (cnt = *first) + 1; + if (c2 == size) c2 = 0; + *first = c2; + } + __enable_irq (); +#endif + return (cnt); +} + +__inline static void rt_systick_init (void) { + NVIC_ST_RELOAD = os_trv; + NVIC_ST_CURRENT = 0; + NVIC_ST_CTRL = 0x0007; + NVIC_SYS_PRI3 |= 0xFF000000; +} + +__inline static void rt_svc_init (void) { +#if !(__TARGET_ARCH_6S_M) + int sh,prigroup; +#endif + NVIC_SYS_PRI3 |= 0x00FF0000; +#if (__TARGET_ARCH_6S_M) + NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000; +#else + sh = 8 - __clz (~((NVIC_SYS_PRI3 << 8) & 0xFF000000)); + prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07); + if (prigroup >= sh) { + sh = prigroup + 1; + } + NVIC_SYS_PRI2 = ((0xFEFFFFFF << sh) & 0xFF000000) | (NVIC_SYS_PRI2 & 0x00FFFFFF); +#endif +} + +extern void rt_set_PSP (U32 stack); +extern U32 rt_get_PSP (void); +extern void os_set_env (void); +extern void *_alloc_box (void *box_mem); +extern int _free_box (void *box_mem, void *box); + +extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); +extern void rt_ret_val (P_TCB p_TCB, U32 v0); +extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); + +extern void dbg_init (void); +extern void dbg_task_notify (P_TCB p_tcb, BOOL create); +extern void dbg_task_switch (U32 task_id); + +#ifdef DBG_MSG +#define DBG_INIT() dbg_init() +#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new!=os_tsk.run)) \ + dbg_task_switch(task_id) +#else +#define DBG_INIT() +#define DBG_TASK_NOTIFY(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_List.c b/rtos/rtx/TARGET_CORTEX_A/rt_List.c new file mode 100644 index 0000000..7dede12 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_List.c @@ -0,0 +1,324 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_LIST.C + * Purpose: Functions for the management of different lists + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Time.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* List head of chained ready tasks */ +struct OS_XCB os_rdy; +/* List head of chained delay tasks */ +struct OS_XCB os_dly; + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_put_prio -----------------------------------*/ + +void rt_put_prio (P_XCB p_CB, P_TCB p_task) { + /* Put task identified with "p_task" into list ordered by priority. */ + /* "p_CB" points to head of list; list has always an element at end with */ + /* a priority less than "p_task->prio". */ + P_TCB p_CB2; + U32 prio; + BOOL sem_mbx = __FALSE; + + if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + sem_mbx = __TRUE; + } + prio = p_task->prio; + p_CB2 = p_CB->p_lnk; + /* Search for an entry in the list */ + while (p_CB2 != NULL && prio <= p_CB2->prio) { + p_CB = (P_XCB)p_CB2; + p_CB2 = p_CB2->p_lnk; + } + /* Entry found, insert the task into the list */ + p_task->p_lnk = p_CB2; + p_CB->p_lnk = p_task; + if (sem_mbx) { + if (p_CB2 != NULL) { + p_CB2->p_rlnk = p_task; + } + p_task->p_rlnk = (P_TCB)p_CB; + } + else { + p_task->p_rlnk = NULL; + } +} + + +/*--------------------------- rt_get_first ----------------------------------*/ + +P_TCB rt_get_first (P_XCB p_CB) { + /* Get task at head of list: it is the task with highest priority. */ + /* "p_CB" points to head of list. */ + P_TCB p_first; + + p_first = p_CB->p_lnk; + p_CB->p_lnk = p_first->p_lnk; + if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + if (p_first->p_lnk != NULL) { + p_first->p_lnk->p_rlnk = (P_TCB)p_CB; + p_first->p_lnk = NULL; + } + p_first->p_rlnk = NULL; + } + else { + p_first->p_lnk = NULL; + } + return (p_first); +} + + +/*--------------------------- rt_put_rdy_first ------------------------------*/ + +void rt_put_rdy_first (P_TCB p_task) { + /* Put task identified with "p_task" at the head of the ready list. The */ + /* task must have at least a priority equal to highest priority in list. */ + p_task->p_lnk = os_rdy.p_lnk; + p_task->p_rlnk = NULL; + os_rdy.p_lnk = p_task; +} + + +/*--------------------------- rt_get_same_rdy_prio --------------------------*/ + +P_TCB rt_get_same_rdy_prio (void) { + /* Remove a task of same priority from ready list if any exists. Other- */ + /* wise return NULL. */ + P_TCB p_first; + + p_first = os_rdy.p_lnk; + if (p_first->prio == os_tsk.run->prio) { + os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; + return (p_first); + } + return (NULL); +} + + +/*--------------------------- rt_resort_prio --------------------------------*/ + +void rt_resort_prio (P_TCB p_task) { + /* Re-sort ordered lists after the priority of 'p_task' has changed. */ + P_TCB p_CB; + + if (p_task->p_rlnk == NULL) { + if (p_task->state == READY) { + /* Task is chained into READY list. */ + p_CB = (P_TCB)&os_rdy; + goto res; + } + } + else { + p_CB = p_task->p_rlnk; + while (p_CB->cb_type == TCB) { + /* Find a header of this task chain list. */ + p_CB = p_CB->p_rlnk; + } +res:rt_rmv_list (p_task); + rt_put_prio ((P_XCB)p_CB, p_task); + } +} + + +/*--------------------------- rt_put_dly ------------------------------------*/ + +void rt_put_dly (P_TCB p_task, U16 delay) { + /* Put a task identified with "p_task" into chained delay wait list using */ + /* a delay value of "delay". */ + P_TCB p; + U32 delta,idelay = delay; + + p = (P_TCB)&os_dly; + if (p->p_dlnk == NULL) { + /* Delay list empty */ + delta = 0; + goto last; + } + delta = os_dly.delta_time; + while (delta < idelay) { + if (p->p_dlnk == NULL) { + /* End of list found */ +last: p_task->p_dlnk = NULL; + p->p_dlnk = p_task; + p_task->p_blnk = p; + p->delta_time = (U16)(idelay - delta); + p_task->delta_time = 0; + return; + } + p = p->p_dlnk; + delta += p->delta_time; + } + /* Right place found */ + p_task->p_dlnk = p->p_dlnk; + p->p_dlnk = p_task; + p_task->p_blnk = p; + if (p_task->p_dlnk != NULL) { + p_task->p_dlnk->p_blnk = p_task; + } + p_task->delta_time = (U16)(delta - idelay); + p->delta_time -= p_task->delta_time; +} + + +/*--------------------------- rt_dec_dly ------------------------------------*/ + +void rt_dec_dly (void) { + /* Decrement delta time of list head: remove tasks having a value of zero.*/ + P_TCB p_rdy; + + if (os_dly.p_dlnk == NULL) { + return; + } + os_dly.delta_time--; + while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { + p_rdy = os_dly.p_dlnk; + if (p_rdy->p_rlnk != NULL) { + /* Task is really enqueued, remove task from semaphore/mailbox */ + /* timeout waiting list. */ + p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; + if (p_rdy->p_lnk != NULL) { + p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; + p_rdy->p_lnk = NULL; + } + p_rdy->p_rlnk = NULL; + } + rt_put_prio (&os_rdy, p_rdy); + os_dly.delta_time = p_rdy->delta_time; + if (p_rdy->state == WAIT_ITV) { + /* Calculate the next time for interval wait. */ + p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; + } + p_rdy->state = READY; + os_dly.p_dlnk = p_rdy->p_dlnk; + if (p_rdy->p_dlnk != NULL) { + p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; + p_rdy->p_dlnk = NULL; + } + p_rdy->p_blnk = NULL; + } +} + + +/*--------------------------- rt_rmv_list -----------------------------------*/ + +void rt_rmv_list (P_TCB p_task) { + /* Remove task identified with "p_task" from ready, semaphore or mailbox */ + /* waiting list if enqueued. */ + P_TCB p_b; + + if (p_task->p_rlnk != NULL) { + /* A task is enqueued in semaphore / mailbox waiting list. */ + p_task->p_rlnk->p_lnk = p_task->p_lnk; + if (p_task->p_lnk != NULL) { + p_task->p_lnk->p_rlnk = p_task->p_rlnk; + } + return; + } + + p_b = (P_TCB)&os_rdy; + while (p_b != NULL) { + /* Search the ready list for task "p_task" */ + if (p_b->p_lnk == p_task) { + p_b->p_lnk = p_task->p_lnk; + return; + } + p_b = p_b->p_lnk; + } +} + + +/*--------------------------- rt_rmv_dly ------------------------------------*/ + +void rt_rmv_dly (P_TCB p_task) { + /* Remove task identified with "p_task" from delay list if enqueued. */ + P_TCB p_b; + + p_b = p_task->p_blnk; + if (p_b != NULL) { + /* Task is really enqueued */ + p_b->p_dlnk = p_task->p_dlnk; + if (p_task->p_dlnk != NULL) { + /* 'p_task' is in the middle of list */ + p_b->delta_time += p_task->delta_time; + p_task->p_dlnk->p_blnk = p_b; + p_task->p_dlnk = NULL; + } + else { + /* 'p_task' is at the end of list */ + p_b->delta_time = 0; + } + p_task->p_blnk = NULL; + } +} + + +/*--------------------------- rt_psq_enq ------------------------------------*/ + +void rt_psq_enq (OS_ID entry, U32 arg) { + /* Insert post service request "entry" into ps-queue. */ + U32 idx; + + idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); + if (idx < os_psq->size) { + os_psq->q[idx].id = entry; + os_psq->q[idx].arg = arg; + } + else { + os_error (OS_ERR_FIFO_OVF); + } +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_List.h b/rtos/rtx/TARGET_CORTEX_A/rt_List.h new file mode 100644 index 0000000..cb3008e --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_List.h @@ -0,0 +1,67 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_LIST.H + * Purpose: Functions for the management of different lists + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Definitions */ + +/* Values for 'cb_type' */ +#define TCB 0 +#define MCB 1 +#define SCB 2 +#define MUCB 3 +#define HCB 4 + +/* Variables */ +extern struct OS_XCB os_rdy; +extern struct OS_XCB os_dly; + +/* Functions */ +extern void rt_put_prio (P_XCB p_CB, P_TCB p_task); +extern P_TCB rt_get_first (P_XCB p_CB); +extern void rt_put_rdy_first (P_TCB p_task); +extern P_TCB rt_get_same_rdy_prio (void); +extern void rt_resort_prio (P_TCB p_task); +extern void rt_put_dly (P_TCB p_task, U16 delay); +extern void rt_dec_dly (void); +extern void rt_rmv_list (P_TCB p_task); +extern void rt_rmv_dly (P_TCB p_task); +extern void rt_psq_enq (OS_ID entry, U32 arg); + +/* This is a fast macro generating in-line code */ +#define rt_rdy_prio(void) (os_rdy.p_lnk->prio) + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Mailbox.c b/rtos/rtx/TARGET_CORTEX_A/rt_Mailbox.c new file mode 100644 index 0000000..81a00b9 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Mailbox.c @@ -0,0 +1,296 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MAILBOX.C + * Purpose: Implements waits and wake-ups for mailbox messages + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Mailbox.h" +#include "rt_MemBox.h" +#include "rt_Task.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_mbx_init -----------------------------------*/ + +void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { + /* Initialize a mailbox */ + P_MCB p_MCB = mailbox; + + p_MCB->cb_type = MCB; + p_MCB->state = 0; + p_MCB->isr_st = 0; + p_MCB->p_lnk = NULL; + p_MCB->first = 0; + p_MCB->last = 0; + p_MCB->count = 0; + p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) / + (U32)sizeof (void *); +} + + +/*--------------------------- rt_mbx_send -----------------------------------*/ + +OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { + /* Send message to a mailbox */ + P_MCB p_MCB = mailbox; + P_TCB p_TCB; + + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1)) { + /* A task is waiting for message */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); +#else + *p_TCB->msg = p_msg; + rt_ret_val (p_TCB, OS_R_MBX); +#endif + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + /* Store message in mailbox queue */ + if (p_MCB->count == p_MCB->size) { + /* No free message entry, wait for one. If message queue is full, */ + /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ + /* pointer can now be reused for send message waits task list. */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + /* Task is waiting to send a message */ + p_MCB->state = 2; + } + os_tsk.run->msg = p_msg; + rt_block (timeout, WAIT_MBX); + return (OS_R_TMO); + } + /* Yes, there is a free entry in a mailbox. */ + p_MCB->msg[p_MCB->first] = p_msg; + rt_inc (&p_MCB->count); + if (++p_MCB->first == p_MCB->size) { + p_MCB->first = 0; + } + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mbx_wait -----------------------------------*/ + +OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { + /* Receive a message; possibly wait for it */ + P_MCB p_MCB = mailbox; + P_TCB p_TCB; + + /* If a message is available in the fifo buffer */ + /* remove it from the fifo buffer and return. */ + if (p_MCB->count) { + *message = p_MCB->msg[p_MCB->last]; + if (++p_MCB->last == p_MCB->size) { + p_MCB->last = 0; + } + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2)) { + /* A task is waiting to send message */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_OK); +#endif + p_MCB->msg[p_MCB->first] = p_TCB->msg; + if (++p_MCB->first == p_MCB->size) { + p_MCB->first = 0; + } + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + rt_dec (&p_MCB->count); + } + return (OS_R_OK); + } + /* No message available: wait for one */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + /* Task is waiting to receive a message */ + p_MCB->state = 1; + } + rt_block(timeout, WAIT_MBX); +#ifndef __CMSIS_RTOS + os_tsk.run->msg = message; +#endif + return (OS_R_TMO); +} + + +/*--------------------------- rt_mbx_check ----------------------------------*/ + +OS_RESULT rt_mbx_check (OS_ID mailbox) { + /* Check for free space in a mailbox. Returns the number of messages */ + /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ + P_MCB p_MCB = mailbox; + + return (p_MCB->size - p_MCB->count); +} + + +/*--------------------------- isr_mbx_send ----------------------------------*/ + +void isr_mbx_send (OS_ID mailbox, void *p_msg) { + /* Same function as "os_mbx_send", but to be called by ISRs. */ + P_MCB p_MCB = mailbox; + + rt_psq_enq (p_MCB, (U32)p_msg); + rt_psh_req (); +} + + +/*--------------------------- isr_mbx_receive -------------------------------*/ + +OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { + /* Receive a message in the interrupt function. The interrupt function */ + /* should not wait for a message since this would block the rtx os. */ + P_MCB p_MCB = mailbox; + + if (p_MCB->count) { + /* A message is available in the fifo buffer. */ + *message = p_MCB->msg[p_MCB->last]; + if (p_MCB->state == 2) { + /* A task is locked waiting to send message */ + rt_psq_enq (p_MCB, 0); + rt_psh_req (); + } + rt_dec (&p_MCB->count); + if (++p_MCB->last == p_MCB->size) { + p_MCB->last = 0; + } + return (OS_R_MBX); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mbx_psh ------------------------------------*/ + +void rt_mbx_psh (P_MCB p_CB, void *p_msg) { + /* Store the message to the mailbox queue or pass it to task directly. */ + P_TCB p_TCB; + void *mem; + + if (p_CB->p_lnk != NULL) switch (p_CB->state) { +#ifdef __CMSIS_RTOS + case 3: + /* Task is waiting to allocate memory, remove it from the waiting list */ + mem = rt_alloc_box(p_msg); + if (mem == NULL) break; + p_TCB = rt_get_first ((P_XCB)p_CB); + rt_ret_val(p_TCB, (U32)mem); + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; +#endif + case 2: + /* Task is waiting to send a message, remove it from the waiting list */ + p_TCB = rt_get_first ((P_XCB)p_CB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_OK); +#endif + p_CB->msg[p_CB->first] = p_TCB->msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0; + } + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; + case 1: + /* Task is waiting for a message, pass the message to the task directly */ + p_TCB = rt_get_first ((P_XCB)p_CB); +#ifdef __CMSIS_RTOS + rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); +#else + *p_TCB->msg = p_msg; + rt_ret_val (p_TCB, OS_R_MBX); +#endif + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; + } else { + /* No task is waiting for a message, store it to the mailbox queue */ + if (p_CB->count < p_CB->size) { + p_CB->msg[p_CB->first] = p_msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0; + } + } + else { + os_error (OS_ERR_MBX_OVF); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Mailbox.h b/rtos/rtx/TARGET_CORTEX_A/rt_Mailbox.h new file mode 100644 index 0000000..0c8e2f3 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Mailbox.h @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MAILBOX.H + * Purpose: Implements waits and wake-ups for mailbox messages + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_mbx_init (OS_ID mailbox, U16 mbx_size); +extern OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout); +extern OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout); +extern OS_RESULT rt_mbx_check (OS_ID mailbox); +extern void isr_mbx_send (OS_ID mailbox, void *p_msg); +extern OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message); +extern void rt_mbx_psh (P_MCB p_CB, void *p_msg); + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_MemBox.c b/rtos/rtx/TARGET_CORTEX_A/rt_MemBox.c new file mode 100644 index 0000000..ad5ced1 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_MemBox.c @@ -0,0 +1,170 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMBOX.C + * Purpose: Interface functions for fixed memory block management system + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_MemBox.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- _init_box -------------------------------------*/ + +int _init_box (void *box_mem, U32 box_size, U32 blk_size) { + /* Initialize memory block system, returns 0 if OK, 1 if fails. */ + void *end; + void *blk; + void *next; + U32 sizeof_bm; + + /* Create memory structure. */ + if (blk_size & BOX_ALIGN_8) { + /* Memory blocks 8-byte aligned. */ + blk_size = ((blk_size & ~BOX_ALIGN_8) + 7) & ~7; + sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7; + } + else { + /* Memory blocks 4-byte aligned. */ + blk_size = (blk_size + 3) & ~3; + sizeof_bm = sizeof (struct OS_BM); + } + if (blk_size == 0) { + return (1); + } + if ((blk_size + sizeof_bm) > box_size) { + return (1); + } + /* Create a Memory structure. */ + blk = ((U8 *) box_mem) + sizeof_bm; + ((P_BM) box_mem)->free = blk; + end = ((U8 *) box_mem) + box_size; + ((P_BM) box_mem)->end = end; + ((P_BM) box_mem)->blk_size = blk_size; + + /* Link all free blocks using offsets. */ + end = ((U8 *) end) - blk_size; + while (1) { + next = ((U8 *) blk) + blk_size; + if (next > end) break; + *((void **)blk) = next; + blk = next; + } + /* end marker */ + *((void **)blk) = 0; + return (0); +} + +/*--------------------------- rt_alloc_box ----------------------------------*/ + +void *rt_alloc_box (void *box_mem) { + /* Allocate a memory block and return start address. */ + void **free; +#ifndef __USE_EXCLUSIVE_ACCESS + int irq_dis; + + irq_dis = __disable_irq (); + free = ((P_BM) box_mem)->free; + if (free) { + ((P_BM) box_mem)->free = *free; + } + if (!irq_dis) __enable_irq (); +#else + do { + if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0) { + __clrex(); + break; + } + } while (__strex((U32)*free, &((P_BM) box_mem)->free)); +#endif + return (free); +} + + +/*--------------------------- _calloc_box -----------------------------------*/ + +void *_calloc_box (void *box_mem) { + /* Allocate a 0-initialized memory block and return start address. */ + void *free; + U32 *p; + U32 i; + + free = _alloc_box (box_mem); + if (free) { + p = free; + for (i = ((P_BM) box_mem)->blk_size; i; i -= 4) { + *p = 0; + p++; + } + } + return (free); +} + + +/*--------------------------- rt_free_box -----------------------------------*/ + +int rt_free_box (void *box_mem, void *box) { + /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */ +#ifndef __USE_EXCLUSIVE_ACCESS + int irq_dis; +#endif + + if (box < box_mem || box >= ((P_BM) box_mem)->end) { + return (1); + } + +#ifndef __USE_EXCLUSIVE_ACCESS + irq_dis = __disable_irq (); + *((void **)box) = ((P_BM) box_mem)->free; + ((P_BM) box_mem)->free = box; + if (!irq_dis) __enable_irq (); +#else + do { + *((void **)box) = (void *)__ldrex(&((P_BM) box_mem)->free); + } while (__strex ((U32)box, &((P_BM) box_mem)->free)); +#endif + return (0); +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_MemBox.h b/rtos/rtx/TARGET_CORTEX_A/rt_MemBox.h new file mode 100644 index 0000000..c10a1cb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_MemBox.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMBOX.H + * Purpose: Interface functions for fixed memory block management system + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +#define rt_init_box _init_box +#define rt_calloc_box _calloc_box +extern int _init_box (void *box_mem, U32 box_size, U32 blk_size); +extern void *rt_alloc_box (void *box_mem); +extern void * _calloc_box (void *box_mem); +extern int rt_free_box (void *box_mem, void *box); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Memory.c b/rtos/rtx/TARGET_CORTEX_A/rt_Memory.c new file mode 100644 index 0000000..f6499fb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Memory.c @@ -0,0 +1,140 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMORY.C + * Purpose: Interface functions for Dynamic Memory Management System + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "rt_Memory.h" + + +/* Functions */ + +// Initialize Dynamic Memory pool +// Parameters: +// pool: Pointer to memory pool +// size: Size of memory pool in bytes +// Return: 0 - OK, 1 - Error + +int rt_init_mem (void *pool, U32 size) { + MEMP *ptr; + + if ((pool == NULL) || (size < sizeof(MEMP))) return (1); + + ptr = (MEMP *)pool; + ptr->next = (MEMP *)((U32)pool + size - sizeof(MEMP *)); + ptr->next->next = NULL; + ptr->len = 0; + + return (0); +} + +// Allocate Memory from Memory pool +// Parameters: +// pool: Pointer to memory pool +// size: Size of memory in bytes to allocate +// Return: Pointer to allocated memory + +void *rt_alloc_mem (void *pool, U32 size) { + MEMP *p, *p_search, *p_new; + U32 hole_size; + + if ((pool == NULL) || (size == 0)) return NULL; + + /* Add header offset to 'size' */ + size += sizeof(MEMP); + /* Make sure that block is 4-byte aligned */ + size = (size + 3) & ~3; + + p_search = (MEMP *)pool; + while (1) { + hole_size = (U32)p_search->next - (U32)p_search; + hole_size -= p_search->len; + /* Check if hole size is big enough */ + if (hole_size >= size) break; + p_search = p_search->next; + if (p_search->next == NULL) { + /* Failed, we are at the end of the list */ + return NULL; + } + } + + if (p_search->len == 0) { + /* No block is allocated, set the Length of the first element */ + p_search->len = size; + p = (MEMP *)(((U32)p_search) + sizeof(MEMP)); + } else { + /* Insert new list element into the memory list */ + p_new = (MEMP *)((U32)p_search + p_search->len); + p_new->next = p_search->next; + p_new->len = size; + p_search->next = p_new; + p = (MEMP *)(((U32)p_new) + sizeof(MEMP)); + } + + return (p); +} + +// Free Memory and return it to Memory pool +// Parameters: +// pool: Pointer to memory pool +// mem: Pointer to memory to free +// Return: 0 - OK, 1 - Error + +int rt_free_mem (void *pool, void *mem) { + MEMP *p_search, *p_prev, *p_return; + + if ((pool == NULL) || (mem == NULL)) return (1); + + p_return = (MEMP *)((U32)mem - sizeof(MEMP)); + + /* Set list header */ + p_prev = NULL; + p_search = (MEMP *)pool; + while (p_search != p_return) { + p_prev = p_search; + p_search = p_search->next; + if (p_search == NULL) { + /* Valid Memory block not found */ + return (1); + } + } + + if (p_prev == NULL) { + /* First block to be released, only set length to 0 */ + p_search->len = 0; + } else { + /* Discard block from chain list */ + p_prev->next = p_search->next; + } + + return (0); +} diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Memory.h b/rtos/rtx/TARGET_CORTEX_A/rt_Memory.h new file mode 100644 index 0000000..28466cb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Memory.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMORY.H + * Purpose: Interface functions for Dynamic Memory Management System + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Types */ +typedef struct mem { /* << Memory Pool management struct >> */ + struct mem *next; /* Next Memory Block in the list */ + U32 len; /* Length of data block */ +} MEMP; + +/* Functions */ +extern int rt_init_mem (void *pool, U32 size); +extern void *rt_alloc_mem (void *pool, U32 size); +extern int rt_free_mem (void *pool, void *mem); diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Mutex.c b/rtos/rtx/TARGET_CORTEX_A/rt_Mutex.c new file mode 100644 index 0000000..4b2fbf8 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Mutex.c @@ -0,0 +1,204 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MUTEX.C + * Purpose: Implements mutex synchronization objects + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Mutex.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_mut_init -----------------------------------*/ + +void rt_mut_init (OS_ID mutex) { + /* Initialize a mutex object */ + P_MUCB p_MCB = mutex; + + p_MCB->cb_type = MUCB; + p_MCB->prio = 0; + p_MCB->level = 0; + p_MCB->p_lnk = NULL; + p_MCB->owner = NULL; +} + + +/*--------------------------- rt_mut_delete ---------------------------------*/ + +#ifdef __CMSIS_RTOS +OS_RESULT rt_mut_delete (OS_ID mutex) { + /* Delete a mutex object */ + P_MUCB p_MCB = mutex; + P_TCB p_TCB; + + __DMB(); + /* Restore owner task's priority. */ + if (p_MCB->level != 0) { + p_MCB->owner->prio = p_MCB->prio; + if (p_MCB->owner != os_tsk.run) { + rt_resort_prio (p_MCB->owner); + } + } + + while (p_MCB->p_lnk != NULL) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); + rt_ret_val(p_TCB, 0/*osOK*/); + rt_rmv_dly(p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + } + + if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + /* preempt running task */ + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + + p_MCB->cb_type = 0; + + return (OS_R_OK); +} +#endif + + +/*--------------------------- rt_mut_release --------------------------------*/ + +OS_RESULT rt_mut_release (OS_ID mutex) { + /* Release a mutex object */ + P_MUCB p_MCB = mutex; + P_TCB p_TCB; + + if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { + /* Unbalanced mutex release or task is not the owner */ + return (OS_R_NOK); + } + __DMB(); + if (--p_MCB->level != 0) { + return (OS_R_OK); + } + /* Restore owner task's priority. */ + os_tsk.run->prio = p_MCB->prio; + if (p_MCB->p_lnk != NULL) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_MUT); +#endif + rt_rmv_dly (p_TCB); + /* A waiting task becomes the owner of this mutex. */ + p_MCB->level = 1; + p_MCB->owner = p_TCB; + p_MCB->prio = p_TCB->prio; + /* Priority inversion, check which task continues. */ + if (os_tsk.run->prio >= rt_rdy_prio()) { + rt_dispatch (p_TCB); + } + else { + /* Ready task has higher priority than running task. */ + rt_put_prio (&os_rdy, os_tsk.run); + rt_put_prio (&os_rdy, p_TCB); + os_tsk.run->state = READY; + p_TCB->state = READY; + rt_dispatch (NULL); + } + } + else { + /* Check if own priority raised by priority inversion. */ + if (rt_rdy_prio() > os_tsk.run->prio) { + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mut_wait -----------------------------------*/ + +OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { + /* Wait for a mutex, continue when mutex is free. */ + P_MUCB p_MCB = mutex; + + if (p_MCB->level == 0) { + p_MCB->owner = os_tsk.run; + p_MCB->prio = os_tsk.run->prio; + goto inc; + } + if (p_MCB->owner == os_tsk.run) { + /* OK, running task is the owner of this mutex. */ +inc:p_MCB->level++; + __DMB(); + return (OS_R_OK); + } + /* Mutex owned by another task, wait until released. */ + if (timeout == 0) { + return (OS_R_TMO); + } + /* Raise the owner task priority if lower than current priority. */ + /* This priority inversion is called priority inheritance. */ + if (p_MCB->prio < os_tsk.run->prio) { + p_MCB->owner->prio = os_tsk.run->prio; + rt_resort_prio (p_MCB->owner); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + } + rt_block(timeout, WAIT_MUT); + return (OS_R_TMO); +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Mutex.h b/rtos/rtx/TARGET_CORTEX_A/rt_Mutex.h new file mode 100644 index 0000000..bf15c4d --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Mutex.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MUTEX.H + * Purpose: Implements mutex synchronization objects + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_mut_init (OS_ID mutex); +extern OS_RESULT rt_mut_delete (OS_ID mutex); +extern OS_RESULT rt_mut_release (OS_ID mutex); +extern OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Robin.c b/rtos/rtx/TARGET_CORTEX_A/rt_Robin.c new file mode 100644 index 0000000..66b1d89 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Robin.c @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_ROBIN.C + * Purpose: Round Robin Task switching + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Time.h" +#include "rt_Robin.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +struct OS_ROBIN os_robin; + + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +/*--------------------------- rt_init_robin ---------------------------------*/ + +__weak void rt_init_robin (void) { + /* Initialize Round Robin variables. */ + os_robin.task = NULL; + os_robin.tout = (U16)os_rrobin; +} + +/*--------------------------- rt_chk_robin ----------------------------------*/ + +__weak void rt_chk_robin (void) { + /* Check if Round Robin timeout expired and switch to the next ready task.*/ + P_TCB p_new; + + if (os_robin.task != os_rdy.p_lnk) { + /* New task was suspended, reset Round Robin timeout. */ + os_robin.task = os_rdy.p_lnk; + os_robin.time = (U16)os_time + os_robin.tout - 1; + } + if (os_robin.time == (U16)os_time) { + /* Round Robin timeout has expired, swap Robin tasks. */ + os_robin.task = NULL; + p_new = rt_get_first (&os_rdy); + rt_put_prio ((P_XCB)&os_rdy, p_new); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Robin.h b/rtos/rtx/TARGET_CORTEX_A/rt_Robin.h new file mode 100644 index 0000000..3ccbffc --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Robin.h @@ -0,0 +1,45 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_ROBIN.H + * Purpose: Round Robin Task switching definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern struct OS_ROBIN os_robin; + +/* Functions */ +extern void rt_init_robin (void); +extern void rt_chk_robin (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Semaphore.c b/rtos/rtx/TARGET_CORTEX_A/rt_Semaphore.c new file mode 100644 index 0000000..192fdbb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Semaphore.c @@ -0,0 +1,191 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SEMAPHORE.C + * Purpose: Implements binary and counting semaphores + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Semaphore.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_sem_init -----------------------------------*/ + +void rt_sem_init (OS_ID semaphore, U16 token_count) { + /* Initialize a semaphore */ + P_SCB p_SCB = semaphore; + + p_SCB->cb_type = SCB; + p_SCB->p_lnk = NULL; + p_SCB->tokens = token_count; +} + + +/*--------------------------- rt_sem_delete ---------------------------------*/ + +#ifdef __CMSIS_RTOS +OS_RESULT rt_sem_delete (OS_ID semaphore) { + /* Delete semaphore */ + P_SCB p_SCB = semaphore; + P_TCB p_TCB; + + __DMB(); + while (p_SCB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_SCB); + rt_ret_val(p_TCB, 0); + rt_rmv_dly(p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + } + + if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + /* preempt running task */ + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + + p_SCB->cb_type = 0; + + return (OS_R_OK); +} +#endif + + +/*--------------------------- rt_sem_send -----------------------------------*/ + +OS_RESULT rt_sem_send (OS_ID semaphore) { + /* Return a token to semaphore */ + P_SCB p_SCB = semaphore; + P_TCB p_TCB; + + __DMB(); + if (p_SCB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_SCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 1); +#else + rt_ret_val(p_TCB, OS_R_SEM); +#endif + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + /* Store token. */ + p_SCB->tokens++; + } + return (OS_R_OK); +} + + +/*--------------------------- rt_sem_wait -----------------------------------*/ + +OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) { + /* Obtain a token; possibly wait for it */ + P_SCB p_SCB = semaphore; + + if (p_SCB->tokens) { + p_SCB->tokens--; + __DMB(); + return (OS_R_OK); + } + /* No token available: wait for one */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_SCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_SCB, os_tsk.run); + } + else { + p_SCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_SCB; + } + rt_block(timeout, WAIT_SEM); + return (OS_R_TMO); +} + + +/*--------------------------- isr_sem_send ----------------------------------*/ + +void isr_sem_send (OS_ID semaphore) { + /* Same function as "os_sem"send", but to be called by ISRs */ + P_SCB p_SCB = semaphore; + + rt_psq_enq (p_SCB, 0); + rt_psh_req (); +} + + +/*--------------------------- rt_sem_psh ------------------------------------*/ + +void rt_sem_psh (P_SCB p_CB) { + /* Check if task has to be waken up */ + P_TCB p_TCB; + + __DMB(); + if (p_CB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_CB); + rt_rmv_dly (p_TCB); + p_TCB->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 1); +#else + rt_ret_val(p_TCB, OS_R_SEM); +#endif + rt_put_prio (&os_rdy, p_TCB); + } + else { + /* Store token */ + p_CB->tokens++; + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Semaphore.h b/rtos/rtx/TARGET_CORTEX_A/rt_Semaphore.h new file mode 100644 index 0000000..ec45480 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Semaphore.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SEMAPHORE.H + * Purpose: Implements binary and counting semaphores + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_sem_init (OS_ID semaphore, U16 token_count); +extern OS_RESULT rt_sem_delete(OS_ID semaphore); +extern OS_RESULT rt_sem_send (OS_ID semaphore); +extern OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout); +extern void isr_sem_send (OS_ID semaphore); +extern void rt_sem_psh (P_SCB p_CB); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_System.c b/rtos/rtx/TARGET_CORTEX_A/rt_System.c new file mode 100644 index 0000000..db8c32b --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_System.c @@ -0,0 +1,304 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SYSTEM.C + * Purpose: System Task Manager + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_Task.h" +#include "rt_System.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Mailbox.h" +#include "rt_Semaphore.h" +#include "rt_Time.h" +#include "rt_Timer.h" +#include "rt_Robin.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +int os_tick_irqn; + +/*---------------------------------------------------------------------------- + * Local Variables + *---------------------------------------------------------------------------*/ + +static volatile BIT os_lock; +static volatile BIT os_psh_flag; +#ifndef __CORTEX_A9 +static U8 pend_flags; +#endif +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) +__asm void $$RTX$$version (void) { + /* Export a version number symbol for a version control. */ + + EXPORT __RL_RTX_VER + +__RL_RTX_VER EQU 0x450 +} +#endif + + +/*--------------------------- rt_suspend ------------------------------------*/ + +U32 rt_suspend (void) { + /* Suspend OS scheduler */ + U32 delta = 0xFFFF; + + rt_tsk_lock(); + + if (os_dly.p_dlnk) { + delta = os_dly.delta_time; + } +#ifndef __CMSIS_RTOS + if (os_tmr.next) { + if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; + } +#endif + + return (delta); +} + + +/*--------------------------- rt_resume -------------------------------------*/ + +void rt_resume (U32 sleep_time) { + /* Resume OS scheduler after suspend */ + P_TCB next; + U32 delta; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + os_robin.task = NULL; + + /* Update delays. */ + if (os_dly.p_dlnk) { + delta = sleep_time; + if (delta >= os_dly.delta_time) { + delta -= os_dly.delta_time; + os_time += os_dly.delta_time; + os_dly.delta_time = 1; + while (os_dly.p_dlnk) { + rt_dec_dly(); + if (delta == 0) break; + delta--; + os_time++; + } + } else { + os_time += delta; + os_dly.delta_time -= delta; + } + } else { + os_time += sleep_time; + } + +#ifndef __CMSIS_RTOS + /* Check the user timers. */ + if (os_tmr.next) { + delta = sleep_time; + if (delta >= os_tmr.tcnt) { + delta -= os_tmr.tcnt; + os_tmr.tcnt = 1; + while (os_tmr.next) { + rt_tmr_tick(); + if (delta == 0) break; + delta--; + } + } else { + os_tmr.tcnt -= delta; + } + } +#endif + + /* Switch back to highest ready task */ + next = rt_get_first (&os_rdy); + rt_switch_req (next); + + rt_tsk_unlock(); +} + + +/*--------------------------- rt_tsk_lock -----------------------------------*/ + +void rt_tsk_lock (void) { + /* Prevent task switching by locking out scheduler */ + if (os_tick_irqn < 0) { + OS_LOCK(); + os_lock = __TRUE; + OS_UNPEND (&pend_flags); + } else { + OS_X_LOCK(os_tick_irqn); + os_lock = __TRUE; + OS_X_UNPEND (&pend_flags); + } +} + + +/*--------------------------- rt_tsk_unlock ---------------------------------*/ + +void rt_tsk_unlock (void) { + /* Unlock scheduler and re-enable task switching */ + if (os_tick_irqn < 0) { + OS_UNLOCK(); + os_lock = __FALSE; + OS_PEND (pend_flags, os_psh_flag); + os_psh_flag = __FALSE; + } else { + OS_X_UNLOCK(os_tick_irqn); + os_lock = __FALSE; + OS_X_PEND (pend_flags, os_psh_flag); + os_psh_flag = __FALSE; + } +} + + +/*--------------------------- rt_psh_req ------------------------------------*/ + +void rt_psh_req (void) { + /* Initiate a post service handling request if required. */ + if (os_lock == __FALSE) { + OS_PEND_IRQ (); + } + else { + os_psh_flag = __TRUE; + } +} + + +/*--------------------------- rt_pop_req ------------------------------------*/ + +void rt_pop_req (void) { + /* Process an ISR post service requests. */ + struct OS_XCB *p_CB; + P_TCB next; + U32 idx; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + idx = os_psq->last; + while (os_psq->count) { + p_CB = os_psq->q[idx].id; + if (p_CB->cb_type == TCB) { + /* Is of TCB type */ + rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg); + } + else if (p_CB->cb_type == MCB) { + /* Is of MCB type */ + rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg); + } + else { + /* Must be of SCB type */ + rt_sem_psh ((P_SCB)p_CB); + } + if (++idx == os_psq->size) idx = 0; + rt_dec (&os_psq->count); + } + os_psq->last = idx; + + next = rt_get_first (&os_rdy); + rt_switch_req (next); +} + + +/*--------------------------- os_tick_init ----------------------------------*/ + +__weak int os_tick_init (void) { + /* Initialize SysTick timer as system tick timer. */ + rt_systick_init (); + return (-1); /* Return IRQ number of SysTick timer */ +} + + +/*--------------------------- os_tick_irqack --------------------------------*/ + +__weak void os_tick_irqack (void) { + /* Acknowledge timer interrupt. */ +} + + +/*--------------------------- rt_systick ------------------------------------*/ + +extern void sysTimerTick(void); + +void rt_systick (void) { + /* Check for system clock update, suspend running task. */ + P_TCB next; + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + /* Check Round Robin timeout. */ + rt_chk_robin (); + + /* Update delays. */ + os_time++; + rt_dec_dly (); + + /* Check the user timers. */ +#ifdef __CMSIS_RTOS + sysTimerTick(); +#else + rt_tmr_tick (); +#endif + + /* Switch back to highest ready task */ + next = rt_get_first (&os_rdy); + rt_switch_req (next); +} + +/*--------------------------- rt_stk_check ----------------------------------*/ + +__weak void rt_stk_check (void) { + /* Check for stack overflow. */ + if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || + (os_tsk.run->stack[0] != MAGIC_WORD)) { + os_error (OS_ERR_STK_OVF); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_System.h b/rtos/rtx/TARGET_CORTEX_A/rt_System.h new file mode 100644 index 0000000..91db648 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_System.h @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SYSTEM.H + * Purpose: System Task Manager definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Variables */ +#define os_psq ((P_PSQ)&os_fifo) +extern int os_tick_irqn; + +/* Functions */ +extern U32 rt_suspend (void); +extern void rt_resume (U32 sleep_time); +extern void rt_tsk_lock (void); +extern void rt_tsk_unlock (void); +extern void rt_psh_req (void); +extern void rt_pop_req (void); +extern void rt_systick (void); +extern void rt_stk_check (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Task.c b/rtos/rtx/TARGET_CORTEX_A/rt_Task.c new file mode 100644 index 0000000..ce2455a --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Task.c @@ -0,0 +1,372 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TASK.C + * Purpose: Task functions and system start up. + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_List.h" +#include "rt_MemBox.h" +#include "rt_Robin.h" +#ifdef __CORTEX_A9 +#include "rt_HAL_CA.h" +#else +#include "rt_HAL_CM.h" +#endif + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* Running and next task info. */ +struct OS_TSK os_tsk; + +/* Task Control Blocks of idle demon */ +struct OS_TCB os_idle_TCB; + + +/*---------------------------------------------------------------------------- + * Local Functions + *---------------------------------------------------------------------------*/ + +static OS_TID rt_get_TID (void) { + U32 tid; + + for (tid = 1; tid <= os_maxtaskrun; tid++) { + if (os_active_TCB[tid-1] == NULL) { + return ((OS_TID)tid); + } + } + return (0); +} + + +/*--------------------------- rt_init_context -------------------------------*/ + +static void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) { + /* Initialize general part of the Task Control Block. */ + p_TCB->cb_type = TCB; + p_TCB->state = READY; + p_TCB->prio = priority; + p_TCB->p_lnk = NULL; + p_TCB->p_rlnk = NULL; + p_TCB->p_dlnk = NULL; + p_TCB->p_blnk = NULL; + p_TCB->delta_time = 0; + p_TCB->interval_time = 0; + p_TCB->events = 0; + p_TCB->waits = 0; + p_TCB->stack_frame = 0; + + if (p_TCB->priv_stack == 0) { + /* Allocate the memory space for the stack. */ + p_TCB->stack = rt_alloc_box (mp_stk); + } + rt_init_stack (p_TCB, task_body); +} + + +/*--------------------------- rt_switch_req ---------------------------------*/ + +void rt_switch_req (P_TCB p_new) { + /* Switch to next task (identified by "p_new"). */ + os_tsk.new = p_new; + p_new->state = RUNNING; + DBG_TASK_SWITCH(p_new->task_id); +} + + +/*--------------------------- rt_dispatch -----------------------------------*/ + +void rt_dispatch (P_TCB next_TCB) { + /* Dispatch next task if any identified or dispatch highest ready task */ + /* "next_TCB" identifies a task to run or has value NULL (=no next task) */ + if (next_TCB == NULL) { + /* Running task was blocked: continue with highest ready task */ + next_TCB = rt_get_first (&os_rdy); + rt_switch_req (next_TCB); + } + else { + /* Check which task continues */ + if (next_TCB->prio > os_tsk.run->prio) { + /* preempt running task */ + rt_put_rdy_first (os_tsk.run); + os_tsk.run->state = READY; + rt_switch_req (next_TCB); + } + else { + /* put next task into ready list, no task switch takes place */ + next_TCB->state = READY; + rt_put_prio (&os_rdy, next_TCB); + } + } +} + + +/*--------------------------- rt_block --------------------------------------*/ + +void rt_block (U16 timeout, U8 block_state) { + /* Block running task and choose next ready task. */ + /* "timeout" sets a time-out value or is 0xffff (=no time-out). */ + /* "block_state" defines the appropriate task state */ + P_TCB next_TCB; + + if (timeout) { + if (timeout < 0xffff) { + rt_put_dly (os_tsk.run, timeout); + } + os_tsk.run->state = block_state; + next_TCB = rt_get_first (&os_rdy); + rt_switch_req (next_TCB); + } +} + + +/*--------------------------- rt_tsk_pass -----------------------------------*/ + +void rt_tsk_pass (void) { + /* Allow tasks of same priority level to run cooperatively.*/ + P_TCB p_new; + + p_new = rt_get_same_rdy_prio(); + if (p_new != NULL) { + rt_put_prio ((P_XCB)&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_switch_req (p_new); + } +} + + +/*--------------------------- rt_tsk_self -----------------------------------*/ + +OS_TID rt_tsk_self (void) { + /* Return own task identifier value. */ + if (os_tsk.run == NULL) { + return (0); + } + return (os_tsk.run->task_id); +} + + +/*--------------------------- rt_tsk_prio -----------------------------------*/ + +OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) { + /* Change execution priority of a task to "new_prio". */ + P_TCB p_task; + + if (task_id == 0) { + /* Change execution priority of calling task. */ + os_tsk.run->prio = new_prio; +run:if (rt_rdy_prio() > new_prio) { + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + return (OS_R_OK); + } + + /* Find the task in the "os_active_TCB" array. */ + if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + /* Task with "task_id" not found or not started. */ + return (OS_R_NOK); + } + p_task = os_active_TCB[task_id-1]; + p_task->prio = new_prio; + if (p_task == os_tsk.run) { + goto run; + } + rt_resort_prio (p_task); + if (p_task->state == READY) { + /* Task enqueued in a ready list. */ + p_task = rt_get_first (&os_rdy); + rt_dispatch (p_task); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_tsk_create ---------------------------------*/ + +OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv) { + /* Start a new task declared with "task". */ + P_TCB task_context; + U32 i; + + /* Priority 0 is reserved for idle task! */ + if ((prio_stksz & 0xFF) == 0) { + prio_stksz += 1; + } + task_context = rt_alloc_box (mp_tcb); + if (task_context == NULL) { + return (0); + } + /* If "size != 0" use a private user provided stack. */ + task_context->stack = stk; + task_context->priv_stack = prio_stksz >> 8; + /* Pass parameter 'argv' to 'rt_init_context' */ + task_context->msg = argv; + /* For 'size == 0' system allocates the user stack from the memory pool. */ + rt_init_context (task_context, prio_stksz & 0xFF, task); + + /* Find a free entry in 'os_active_TCB' table. */ + i = rt_get_TID (); + os_active_TCB[i-1] = task_context; + task_context->task_id = i; + DBG_TASK_NOTIFY(task_context, __TRUE); + rt_dispatch (task_context); + return ((OS_TID)i); +} + + +/*--------------------------- rt_tsk_delete ---------------------------------*/ + +OS_RESULT rt_tsk_delete (OS_TID task_id) { + /* Terminate the task identified with "task_id". */ + P_TCB task_context; + + if (task_id == 0 || task_id == os_tsk.run->task_id) { + /* Terminate itself. */ + os_tsk.run->state = INACTIVE; + os_tsk.run->tsk_stack = rt_get_PSP (); + rt_stk_check (); + os_active_TCB[os_tsk.run->task_id-1] = NULL; + rt_free_box (mp_stk, os_tsk.run->stack); + os_tsk.run->stack = NULL; + DBG_TASK_NOTIFY(os_tsk.run, __FALSE); + rt_free_box (mp_tcb, os_tsk.run); + os_tsk.run = NULL; + rt_dispatch (NULL); + /* The program should never come to this point. */ + } + else { + /* Find the task in the "os_active_TCB" array. */ + if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + /* Task with "task_id" not found or not started. */ + return (OS_R_NOK); + } + task_context = os_active_TCB[task_id-1]; + rt_rmv_list (task_context); + rt_rmv_dly (task_context); + os_active_TCB[task_id-1] = NULL; + rt_free_box (mp_stk, task_context->stack); + task_context->stack = NULL; + DBG_TASK_NOTIFY(task_context, __FALSE); + rt_free_box (mp_tcb, task_context); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_sys_init -----------------------------------*/ + +#ifdef __CMSIS_RTOS +void rt_sys_init (void) { +#else +void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { +#endif + /* Initialize system and start up task declared with "first_task". */ + U32 i; + + DBG_INIT(); + + /* Initialize dynamic memory and task TCB pointers to NULL. */ + for (i = 0; i < os_maxtaskrun; i++) { + os_active_TCB[i] = NULL; + } + rt_init_box (&mp_tcb, mp_tcb_size, sizeof(struct OS_TCB)); + rt_init_box (&mp_stk, mp_stk_size, BOX_ALIGN_8 | (U16)(os_stackinfo)); + rt_init_box ((U32 *)m_tmr, mp_tmr_size, sizeof(struct OS_TMR)); + + /* Set up TCB of idle demon */ + os_idle_TCB.task_id = 255; + os_idle_TCB.priv_stack = 0; + rt_init_context (&os_idle_TCB, 0, os_idle_demon); + + /* Set up ready list: initially empty */ + os_rdy.cb_type = HCB; + os_rdy.p_lnk = NULL; + /* Set up delay list: initially empty */ + os_dly.cb_type = HCB; + os_dly.p_dlnk = NULL; + os_dly.p_blnk = NULL; + os_dly.delta_time = 0; + + /* Fix SP and system variables to assume idle task is running */ + /* Transform main program into idle task by assuming idle TCB */ +#ifndef __CMSIS_RTOS + rt_set_PSP (os_idle_TCB.tsk_stack+32); +#endif + os_tsk.run = &os_idle_TCB; + os_tsk.run->state = RUNNING; + + /* Initialize ps queue */ + os_psq->first = 0; + os_psq->last = 0; + os_psq->size = os_fifo_size; + + rt_init_robin (); + + /* Initialize SVC and PendSV */ + rt_svc_init (); + +#ifndef __CMSIS_RTOS + /* Initialize and start system clock timer */ + os_tick_irqn = os_tick_init (); + if (os_tick_irqn >= 0) { + OS_X_INIT(os_tick_irqn); + } + + /* Start up first user task before entering the endless loop */ + rt_tsk_create (first_task, prio_stksz, stk, NULL); +#endif +} + + +/*--------------------------- rt_sys_start ----------------------------------*/ + +#ifdef __CMSIS_RTOS +void rt_sys_start (void) { + /* Start system */ + + /* Initialize and start system clock timer */ + os_tick_irqn = os_tick_init (); + if (os_tick_irqn >= 0) { + OS_X_INIT(os_tick_irqn); + } +} +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Task.h b/rtos/rtx/TARGET_CORTEX_A/rt_Task.h new file mode 100644 index 0000000..6d7bc2f --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Task.h @@ -0,0 +1,87 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TASK.H + * Purpose: Task functions and system start up. + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Definitions */ + +/* Values for 'state' */ +#define INACTIVE 0 +#define READY 1 +#define RUNNING 2 +#define WAIT_DLY 3 +#define WAIT_ITV 4 +#define WAIT_OR 5 +#define WAIT_AND 6 +#define WAIT_SEM 7 +#define WAIT_MBX 8 +#define WAIT_MUT 9 + +/* Return codes */ +#define OS_R_TMO 0x01 +#define OS_R_EVT 0x02 +#define OS_R_SEM 0x03 +#define OS_R_MBX 0x04 +#define OS_R_MUT 0x05 + +#define OS_R_OK 0x00 +#define OS_R_NOK 0xff + +/* Variables */ +extern struct OS_TSK os_tsk; +extern struct OS_TCB os_idle_TCB; + +/* Functions */ +extern void rt_switch_req (P_TCB p_new); +extern void rt_dispatch (P_TCB next_TCB); +extern void rt_block (U16 timeout, U8 block_state); +extern void rt_tsk_pass (void); +extern OS_TID rt_tsk_self (void); +extern OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio); +extern OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv); +extern OS_RESULT rt_tsk_delete (OS_TID task_id); +#ifdef __CMSIS_RTOS +extern void rt_sys_init (void); +extern void rt_sys_start (void); +#else +extern void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk); +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + + + + + + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Time.c b/rtos/rtx/TARGET_CORTEX_A/rt_Time.c new file mode 100644 index 0000000..d99dc75 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Time.c @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIME.C + * Purpose: Delay and interval wait functions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_Task.h" +#include "rt_Time.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* Free running system tick counter */ +U32 os_time; + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_time_get -----------------------------------*/ + +U32 rt_time_get (void) { + /* Get system time tick */ + return (os_time); +} + + +/*--------------------------- rt_dly_wait -----------------------------------*/ + +void rt_dly_wait (U16 delay_time) { + /* Delay task by "delay_time" */ + rt_block (delay_time, WAIT_DLY); +} + + +/*--------------------------- rt_itv_set ------------------------------------*/ + +void rt_itv_set (U16 interval_time) { + /* Set interval length and define start of first interval */ + os_tsk.run->interval_time = interval_time; + os_tsk.run->delta_time = interval_time + (U16)os_time; +} + + +/*--------------------------- rt_itv_wait -----------------------------------*/ + +void rt_itv_wait (void) { + /* Wait for interval end and define start of next one */ + U16 delta; + + delta = os_tsk.run->delta_time - (U16)os_time; + os_tsk.run->delta_time += os_tsk.run->interval_time; + if ((delta & 0x8000) == 0) { + rt_block (delta, WAIT_ITV); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Time.h b/rtos/rtx/TARGET_CORTEX_A/rt_Time.h new file mode 100644 index 0000000..2770637 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Time.h @@ -0,0 +1,47 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIME.H + * Purpose: Delay and interval wait functions definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern U32 os_time; + +/* Functions */ +extern U32 rt_time_get (void); +extern void rt_dly_wait (U16 delay_time); +extern void rt_itv_set (U16 interval_time); +extern void rt_itv_wait (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_Timer.h b/rtos/rtx/TARGET_CORTEX_A/rt_Timer.h new file mode 100644 index 0000000..e627b0d --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_Timer.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIMER.H + * Purpose: User timer functions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern struct OS_XTMR os_tmr; + +/* Functions */ +extern void rt_tmr_tick (void); +extern OS_ID rt_tmr_create (U16 tcnt, U16 info); +extern OS_ID rt_tmr_kill (OS_ID timer); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_A/rt_TypeDef.h b/rtos/rtx/TARGET_CORTEX_A/rt_TypeDef.h new file mode 100644 index 0000000..9f5d91e --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_A/rt_TypeDef.h @@ -0,0 +1,167 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TYPEDEF.H + * Purpose: Type Definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Types */ +typedef char S8; +typedef unsigned char U8; +typedef short S16; +typedef unsigned short U16; +typedef int S32; +typedef unsigned int U32; +typedef long long S64; +typedef unsigned long long U64; +typedef unsigned char BIT; +typedef unsigned int BOOL; +typedef void (*FUNCP)(void); + +typedef U32 OS_TID; +typedef void *OS_ID; +typedef U32 OS_RESULT; + +typedef struct OS_TCB { + /* General part: identical for all implementations. */ + U8 cb_type; /* Control Block Type */ + U8 state; /* Task state */ + U8 prio; /* Execution priority */ + U8 task_id; /* Task ID value for optimized TCB access */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ + U16 interval_time; /* Time interval for periodic waits */ + U16 events; /* Event flags */ + U16 waits; /* Wait flags */ + void **msg; /* Direct message passing when task waits */ + + /* Hardware dependant part: specific for Cortex processor */ + U8 stack_frame; /* Stack frame: 0x1 Basic/Extended, 0x2 FP stacked/not stacked */ + U8 reserved; + U16 priv_stack; /* Private stack size, 0= system assigned */ + U32 tsk_stack; /* Current task Stack pointer (R13) */ + U32 *stack; /* Pointer to Task Stack memory block */ + + /* Task entry point used for uVision debugger */ + FUNCP ptask; /* Task entry address */ +} *P_TCB; +#define TCB_TID 3 /* 'task id' offset */ +#define TCB_STACKF 32 /* 'stack_frame' offset */ +#define TCB_TSTACK 36 /* 'tsk_stack' offset */ + +typedef struct OS_PSFE { /* Post Service Fifo Entry */ + void *id; /* Object Identification */ + U32 arg; /* Object Argument */ +} *P_PSFE; + +typedef struct OS_PSQ { /* Post Service Queue */ + U8 first; /* FIFO Head Index */ + U8 last; /* FIFO Tail Index */ + U8 count; /* Number of stored items in FIFO */ + U8 size; /* FIFO Size */ + struct OS_PSFE q[1]; /* FIFO Content */ +} *P_PSQ; + +typedef struct OS_TSK { + P_TCB run; /* Current running task */ + P_TCB new; /* Scheduled task to run */ +} *P_TSK; + +typedef struct OS_ROBIN { /* Round Robin Control */ + P_TCB task; /* Round Robin task */ + U16 time; /* Round Robin switch time */ + U16 tout; /* Round Robin timeout */ +} *P_ROBIN; + +typedef struct OS_XCB { + U8 cb_type; /* Control Block Type */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ +} *P_XCB; + +typedef struct OS_MCB { + U8 cb_type; /* Control Block Type */ + U8 state; /* State flag variable */ + U8 isr_st; /* State flag variable for isr functions */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for message */ + U16 first; /* Index of the message list begin */ + U16 last; /* Index of the message list end */ + U16 count; /* Actual number of stored messages */ + U16 size; /* Maximum number of stored messages */ + void *msg[1]; /* FIFO for Message pointers 1st element */ +} *P_MCB; + +typedef struct OS_SCB { + U8 cb_type; /* Control Block Type */ + U8 mask; /* Semaphore token mask */ + U16 tokens; /* Semaphore tokens */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for tokens */ +} *P_SCB; + +typedef struct OS_MUCB { + U8 cb_type; /* Control Block Type */ + U8 prio; /* Owner task default priority */ + U16 level; /* Call nesting level */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for mutex */ + struct OS_TCB *owner; /* Mutex owner task */ +} *P_MUCB; + +typedef struct OS_XTMR { + struct OS_TMR *next; + U16 tcnt; +} *P_XTMR; + +typedef struct OS_TMR { + struct OS_TMR *next; /* Link pointer to Next timer */ + U16 tcnt; /* Timer delay count */ + U16 info; /* User defined call info */ +} *P_TMR; + +typedef struct OS_BM { + void *free; /* Pointer to first free memory block */ + void *end; /* Pointer to memory block end */ + U32 blk_size; /* Memory block size */ +} *P_BM; + +/* Definitions */ +#define __TRUE 1 +#define __FALSE 0 +#define NULL ((void *) 0) + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/HAL_CM.c b/rtos/rtx/TARGET_CORTEX_M/HAL_CM.c new file mode 100644 index 0000000..421dc34 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/HAL_CM.c @@ -0,0 +1,176 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM.C + * Purpose: Hardware Abstraction Layer for Cortex-M + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +#ifdef DBG_MSG +BIT dbg_msg; +#endif + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_init_stack ---------------------------------*/ + +void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { + /* Prepare TCB and saved context for a first time start of a task. */ + U32 *stk,i,size; + + /* Prepare a complete interrupt frame for first task start */ + size = p_TCB->priv_stack >> 2; + + /* Write to the top of stack. */ + stk = &p_TCB->stack[size]; + + /* Auto correct to 8-byte ARM stack alignment. */ + if ((U32)stk & 0x04) { + stk--; + } + + stk -= 16; + + /* Default xPSR and initial PC */ + stk[15] = INITIAL_xPSR; + stk[14] = (U32)task_body; + + /* Clear R4-R11,R0-R3,R12,LR registers. */ + for (i = 0; i < 14; i++) { + stk[i] = 0; + } + + /* Assign a void pointer to R0. */ + stk[8] = (U32)p_TCB->msg; + + /* Initial Task stack pointer. */ + p_TCB->tsk_stack = (U32)stk; + + /* Task entry point. */ + p_TCB->ptask = task_body; + + /* Set a magic word for checking of stack overflow. + For the main thread (ID: 0x01) the stack is in a memory area shared with the + heap, therefore the last word of the stack is a moving target. + We want to do stack/heap collision detection instead. + */ + if (p_TCB->task_id != 0x01) { + p_TCB->stack[0] = MAGIC_WORD; +#ifdef DEBUG + for (i = 1; i < (stk - p_TCB->stack); i++) { + p_TCB->stack[i] = 0xCCCCCCCC; + } +#endif + } +} + + +/*--------------------------- rt_ret_val ----------------------------------*/ + +static __inline U32 *rt_ret_regs (P_TCB p_TCB) { + /* Get pointer to task return value registers (R0..R3) in Stack */ +#if (__TARGET_FPU_VFP) + if (p_TCB->stack_frame) { + /* Extended Stack Frame: R4-R11,S16-S31,R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR */ + return (U32 *)(p_TCB->tsk_stack + 8*4 + 16*4); + } else { + /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4); + } +#else + /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ + return (U32 *)(p_TCB->tsk_stack + 8*4); +#endif +} + +void rt_ret_val (P_TCB p_TCB, U32 v0) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; +} + +void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { + U32 *ret; + + ret = rt_ret_regs(p_TCB); + ret[0] = v0; + ret[1] = v1; +} + + +/*--------------------------- dbg_init --------------------------------------*/ + +#ifdef DBG_MSG +void dbg_init (void) { + if ((DEMCR & DEMCR_TRCENA) && + (ITM_CONTROL & ITM_ITMENA) && + (ITM_ENABLE & (1UL << 31))) { + dbg_msg = __TRUE; + } +} +#endif + +/*--------------------------- dbg_task_notify -------------------------------*/ + +#ifdef DBG_MSG +void dbg_task_notify (P_TCB p_tcb, BOOL create) { + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U32 = (U32)p_tcb->ptask; + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U16 = (create << 8) | p_tcb->task_id; +} +#endif + +/*--------------------------- dbg_task_switch -------------------------------*/ + +#ifdef DBG_MSG +void dbg_task_switch (U32 task_id) { + while (ITM_PORT31_U32 == 0); + ITM_PORT31_U8 = task_id; +} +#endif + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/Makefile b/rtos/rtx/TARGET_CORTEX_M/Makefile new file mode 100644 index 0000000..c4a4a3e --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/Makefile @@ -0,0 +1,36 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)TARGET_M4/TOOLCHAIN_GCC/*.S)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y += -DOS_CLOCK_NOMINAL=$(OS_CLOCK_NOMINAL) + +ifneq ($(OS_TASKCNT),) +CFLAGS_RTX_Conf_CM.o += -DOS_TASKCNT=$(OS_TASKCNT) +endif + +ifneq ($(OS_SCHEDULERSTKSIZE),) +CFLAGS_RTX_Conf_CM.o += -DOS_SCHEDULERSTKSIZE=$(OS_SCHEDULERSTKSIZE) +endif + +ifneq ($(OS_IDLESTKSIZE),) +CFLAGS_RTX_Conf_CM.o += -DOS_IDLESTKSIZE=$(OS_IDLESTKSIZE) +endif + +ifneq ($(OS_FIFOSZ),) +CFLAGS_RTX_Conf_CM.o += -DOS_FIFOSZ=$(OS_FIFOSZ) +endif + +ifneq ($(DEBUG_SLEEP),) +CFLAGS_RTX_Conf_CM.o += -DDEBUG_SLEEP=$(DEBUG_SLEEP) +CFLAGS_rt_System.o += -DDEBUG_SLEEP=$(DEBUG_SLEEP) +endif + +ifeq ($(OS_API_IN_INTLOCK),1) +CFLAGS_rt_CMSIS.o += -DOS_API_IN_INTLOCK +endif + diff --git a/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h b/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h new file mode 100644 index 0000000..dbdcce8 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h @@ -0,0 +1,394 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_CM_LIB.H + * Purpose: RTX Kernel System Configuration + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "cmsis_os.h" + +#if defined (__CC_ARM) +#pragma O3 +#define __USED __attribute__((used)) +#elif defined (__GNUC__) +#pragma GCC optimize ("O3") +#define __USED __attribute__((used)) +#elif defined (__ICCARM__) +#define __USED __root +#endif + + +/*---------------------------------------------------------------------------- + * Definitions + *---------------------------------------------------------------------------*/ + +#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3] +#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2] +#if __RTX_CPU_STATISTICS__ +#define OS_TCB_SIZE 64 +#else +#define OS_TCB_SIZE 48 +#endif +#define OS_TMR_SIZE 8 + +#if defined (__CC_ARM) && !defined (__MICROLIB) + +typedef void *OS_ID; +typedef uint32_t OS_TID; +typedef uint32_t OS_MUT[3]; +typedef uint32_t OS_RESULT; + +#define runtask_id() rt_tsk_self() +#define mutex_init(m) rt_mut_init(m) +#define mutex_wait(m) os_mut_wait(m,0xFFFF) +#define mutex_rel(m) os_mut_release(m) + +extern OS_TID rt_tsk_self (void); +extern void rt_mut_init (OS_ID mutex); +extern OS_RESULT rt_mut_release (OS_ID mutex); +extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout); + +#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout) +#define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex) + +OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0); +OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0); + +#endif + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +#if (OS_TIMERS != 0) +#define OS_TASK_CNT (OS_TASKCNT + 1) +#else +#define OS_TASK_CNT OS_TASKCNT +#endif + +uint16_t const os_maxtaskrun = OS_TASK_CNT; +uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT; +uint8_t const os_flags = OS_RUNPRIV; + +/* Export following defines to uVision debugger. */ +__USED uint32_t const os_clockrate = OS_TICK; +__USED uint32_t const os_timernum = 0; + +/* Stack for the os_idle_demon */ +unsigned int idle_task_stack[OS_IDLESTKSIZE]; +unsigned short const idle_task_stack_size = sizeof(idle_task_stack); //OS_IDLESTKSIZE; + +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +/* Fifo Queue buffer for ISR requests.*/ +uint32_t os_fifo[OS_FIFOSZ*2+1]; +uint8_t const os_fifo_size = OS_FIFOSZ; + +/* An array of Active task pointers. */ +void *os_active_TCB[OS_TASK_CNT]; + +uint32_t task_rtime[OS_TASK_CNT]; + +/* User Timers Resources */ +#if (OS_TIMERS != 0) +extern void osTimerThread (void const *argument); +osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ, "os_timer"); +osThreadId osThreadId_osTimerThread; +osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *); +osMessageQId osMessageQId_osTimerMessageQ; +#else +osThreadDef_t os_thread_def_osTimerThread = { NULL }; +osThreadId osThreadId_osTimerThread; +osMessageQDef(osTimerMessageQ, 0, void *); +osMessageQId osMessageQId_osTimerMessageQ; +#endif + + +/*---------------------------------------------------------------------------- + * RTX Optimizations (empty functions) + *---------------------------------------------------------------------------*/ + +#if OS_ROBIN == 0 + void rt_init_robin (void) {;} + void rt_chk_robin (void) {;} +#endif + +#if OS_STKCHECK == 0 + void rt_stk_check (void) {;} +#endif + + +/*---------------------------------------------------------------------------- + * Standard Library multithreading interface + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) && !defined (__MICROLIB) + static OS_MUT std_libmutex[OS_MUTEXCNT]; + static uint32_t nr_mutex; + + /*--------------------------- _mutex_initialize -----------------------------*/ + +int _mutex_initialize (OS_ID *mutex) { + /* Allocate and initialize a system mutex. */ + + if (nr_mutex >= OS_MUTEXCNT) { + /* If you are here, you need to increase the number OS_MUTEXCNT. */ + os_error_str("Not enough stdlib mutexes\n"); + } + *mutex = &std_libmutex[nr_mutex++]; + mutex_init (*mutex); + return (1); +} + + +/*--------------------------- _mutex_acquire --------------------------------*/ + +__attribute__((used)) void _mutex_acquire (OS_ID *mutex) { + /* Acquire a system mutex, lock stdlib resources. */ + if (runtask_id ()) { + /* RTX running, acquire a mutex. */ + mutex_wait (*mutex); + } +} + + +/*--------------------------- _mutex_release --------------------------------*/ + +__attribute__((used)) void _mutex_release (OS_ID *mutex) { + /* Release a system mutex, unlock stdlib resources. */ + if (runtask_id ()) { + /* RTX running, release a mutex. */ + mutex_rel (*mutex); + } +} + +#endif + + +/*---------------------------------------------------------------------------- + * RTX Startup + *---------------------------------------------------------------------------*/ + +/* Main Thread definition */ +extern int main (void); +osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 0, NULL}; + +// This define should be probably moved to the CMSIS layer +extern uint32_t __StackTop[]; +#define INITIAL_SP ((unsigned int)__StackTop) + +#ifdef __CC_ARM +extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[]; +#define MAIN_STACK_BUF (Image$$RW_IRAM1$$ZI$$Limit) +#elif defined(__GNUC__) +extern uint32_t __StackLimit[]; +#define MAIN_STACK_BUF (__StackLimit) +#elif defined(__ICCARM__) +#pragma section="HEAP" +#define MAIN_STACK_BUF (void *)__section_begin("HEAP") +#endif + +void set_main_stack(void) { + // That is the bottom of the main stack block: no collision detection + os_thread_def_main.stack_pointer = MAIN_STACK_BUF; + + // Leave OS_SCHEDULERSTKSIZE words for the scheduler and interrupts + os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)MAIN_STACK_BUF) - (OS_SCHEDULERSTKSIZE * 4); +} + +#if defined (__CC_ARM) +#ifdef __MICROLIB +void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); +void _main_init (void) { + osKernelInitialize(); + set_main_stack(); + osThreadCreate(&os_thread_def_main, NULL); + osKernelStart(); + for (;;); +} +#else + +/* The single memory model is checking for stack collision at run time, verifing + that the heap pointer is underneath the stack pointer. + + With the RTOS there is not only one stack above the heap, there are multiple + stacks and some of them are underneath the heap pointer. +*/ +#pragma import(__use_two_region_memory) + +__asm void __rt_entry (void) { + + IMPORT __user_setup_stackheap + IMPORT __rt_lib_init + IMPORT os_thread_def_main + IMPORT osKernelInitialize + IMPORT set_main_stack + IMPORT osKernelStart + IMPORT osThreadCreate + IMPORT exit + + BL __user_setup_stackheap + MOV R1,R2 + BL __rt_lib_init + BL osKernelInitialize + BL set_main_stack + LDR R0,=os_thread_def_main + MOVS R1,#0 + BL osThreadCreate + BL osKernelStart + BL exit + + ALIGN +} +#endif + +#elif defined (__GNUC__) + +#ifdef __CS3__ + +/* CS3 start_c routine. + * + * Copyright (c) 2006, 2007 CodeSourcery Inc + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include "cs3.h" + +extern void __libc_init_array (void); + +__attribute ((noreturn)) void __cs3_start_c (void){ + unsigned regions = __cs3_region_num; + const struct __cs3_region *rptr = __cs3_regions; + + /* Initialize memory */ + for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) { + long long *src = (long long *)rptr->init; + long long *dst = (long long *)rptr->data; + unsigned limit = rptr->init_size; + unsigned count; + + if (src != dst) + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = *src++; + else + dst = (long long *)((char *)dst + limit); + limit = rptr->zero_size; + for (count = 0; count != limit; count += sizeof (long long)) + *dst++ = 0; + } + + /* Run initializers. */ + __libc_init_array (); + + osKernelInitialize(); + set_main_stack(); + osThreadCreate(&os_thread_def_main, NULL); + osKernelStart(); + for (;;); +} + +#else + +__attribute__((naked)) void software_init_hook (void) { + __asm ( + ".syntax unified\n" + ".thumb\n" + "movs r0,#0\n" + "movs r1,#0\n" + "mov r4,r0\n" + "mov r5,r1\n" + "ldr r0,= __libc_fini_array\n" + "bl atexit\n" + "bl __libc_init_array\n" + "mov r0,r4\n" + "mov r1,r5\n" + "bl osKernelInitialize\n" + "bl set_main_stack\n" + "ldr r0,=os_thread_def_main\n" + "movs r1,#0\n" + "bl osThreadCreate\n" + "bl osKernelStart\n" + "bl exit\n" + ); +} + +#endif + +#elif defined (__ICCARM__) + +extern void* __vector_table; +extern int __low_level_init(void); +extern void __iar_data_init3(void); +extern __weak void __iar_init_core( void ); +extern __weak void __iar_init_vfp( void ); +extern void __iar_dynamic_initialization(void); +//extern void mbed_sdk_init(void); +extern void exit(int arg); + +#pragma required=__vector_table +void __iar_program_start( void ) +{ + __iar_init_core(); + __iar_init_vfp(); + + int a; + + if (__low_level_init() != 0) { + __iar_data_init3(); + //mbed_sdk_init(); + __iar_dynamic_initialization(); + } + osKernelInitialize(); + set_main_stack(); + osThreadCreate(&os_thread_def_main, NULL); + a = osKernelStart(); + exit(a); + +} + +#endif + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + + diff --git a/rtos/rtx/TARGET_CORTEX_M/RTX_Conf.h b/rtos/rtx/TARGET_CORTEX_M/RTX_Conf.h new file mode 100644 index 0000000..3fb7ba3 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/RTX_Conf.h @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_CONFIG.H + * Purpose: Exported functions of RTX_Config.c + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Error Codes */ +#define OS_ERR_STK_OVF 1U +#define OS_ERR_FIFO_OVF 2U +#define OS_ERR_MBX_OVF 3U +#define OS_ERR_TIMER_OVF 4U + +/* Definitions */ +#define BOX_ALIGN_8 0x80000000 +#define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)*(cnt) + 3] +#define _declare_box8(pool,size,cnt) U64 pool[(((size)+7)/8)*(cnt) + 2] +#define _init_box8(pool,size,bsize) _init_box (pool,size,(bsize) | BOX_ALIGN_8) + +/* Variables */ +extern U32 idle_task_stack[]; +extern U32 os_fifo[]; +extern void *os_active_TCB[]; +extern U32 task_rtime[]; + +/* Constants */ +extern U16 const os_maxtaskrun; +extern U8 const os_flags; +extern U32 const os_rrobin; +extern U32 const os_clockrate; +extern U32 const os_timernum; +extern U16 const idle_task_stack_size; + +extern U8 const os_fifo_size; + +/* Functions */ +extern U32 os_get_trv (void); +extern void os_idle_demon (void); +extern int os_tick_init (void); +extern void os_tick_irqack (void); +extern void os_tmr_call (U16 info); +extern void os_error (U32 err_code); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c b/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c new file mode 100644 index 0000000..d4acf88 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c @@ -0,0 +1,303 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RTX_Conf_CM.C + * Purpose: Configuration of CMSIS RTX Kernel for Cortex-M + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "stdarg.h" +#include "stdio.h" +#include "cmsis_os.h" +#include "rt_System.h" +#include "rt_Time.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_sleep.h" +#include "cmsis.h" +#include "hwtimer_list.h" + +#define WEAK __attribute__((weak)) + +void WEAK sleep(void) +{ + hal_sleep_enter_sleep(); +} + +/*---------------------------------------------------------------------------- + * RTX User configuration part BEGIN + *---------------------------------------------------------------------------*/ + +//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- +// +// Thread Configuration +// ======================= +// +// Number of concurrent running threads <0-250> +// Defines max. number of threads that will run at the same time. +// counting "main", but not counting "osTimerThread" +// Default: 6 +#ifndef OS_TASKCNT +# define OS_TASKCNT __BEST_D_OS_TASKCNT +#endif + +// Scheduler (+ interrupts) stack size [bytes] <64-4096:8><#/4> +#ifndef OS_SCHEDULERSTKSIZE +# define OS_SCHEDULERSTKSIZE __BEST_D_OS_SCHEDULERSTKSIZE +#endif + +// Idle stack size [bytes] <64-4096:8><#/4> +// Defines default stack size for the Idle thread. +#ifndef OS_IDLESTKSIZE + #define OS_IDLESTKSIZE 256 +#endif + +// Timer Thread stack size [bytes] <64-4096:8><#/4> +// Defines stack size for Timer thread. +// Default: 200 +#ifndef OS_TIMERSTKSZ + #define OS_TIMERSTKSZ WORDS_STACK_SIZE +#endif + +// Check for stack overflow +// Includes the stack checking code for stack overflow. +// Note that additional code reduces the Kernel performance. +#ifndef OS_STKCHECK + #define OS_STKCHECK 1 +#endif + +// Processor mode for thread execution +// <0=> Unprivileged mode +// <1=> Privileged mode +// Default: Privileged mode +#ifndef OS_RUNPRIV + #define OS_RUNPRIV 1 +#endif + +// Timer tick value [us] <1-1000000> +// Defines the timer tick value. +// Default: 1000 (1ms) +#ifndef OS_TICK + #define OS_TICK 1000 +#endif + +// + +// System Configuration +// ======================= +// +// Round-Robin Thread switching +// =============================== +// +// Enables Round-Robin Thread switching. +#ifndef OS_ROBIN + #define OS_ROBIN 1 +#endif + +// Round-Robin Timeout [ticks] <1-1000> +// Defines how long a thread will execute before a thread switch. +// Default: 5 +#ifndef OS_ROBINTOUT + #define OS_ROBINTOUT 5 +#endif + +// + +// User Timers +// ============== +// Enables user Timers +#ifndef OS_TIMERS + #define OS_TIMERS 1 +#endif + +// Timer Thread Priority +// <1=> Low +// <2=> Below Normal +// <3=> Normal +// <4=> Above Normal +// <5=> High +// <6=> Realtime (highest) +// Defines priority for Timer Thread +// Default: High +#ifndef OS_TIMERPRIO + #define OS_TIMERPRIO 5 +#endif + +// Timer Callback Queue size <1-32> +// Number of concurrent active timer callback functions. +// Default: 4 +#ifndef OS_TIMERCBQSZ + #define OS_TIMERCBQS 16 +#endif + +// + +// ISR FIFO Queue size<4=> 4 entries <8=> 8 entries +// <12=> 12 entries <16=> 16 entries +// <24=> 24 entries <32=> 32 entries +// <48=> 48 entries <64=> 64 entries +// <96=> 96 entries +// ISR functions store requests to this buffer, +// when they are called from the interrupt handler. +// Default: 16 entries +#ifndef OS_FIFOSZ + #define OS_FIFOSZ 16 +#endif + +// + +//------------- <<< end of configuration section >>> ----------------------- + +// Standard library system mutexes +// =============================== +// Define max. number system mutexes that are used to protect +// the arm standard runtime library. For microlib they are not used. +#ifndef OS_MUTEXCNT + #define OS_MUTEXCNT 12 +#endif + +/*---------------------------------------------------------------------------- + * RTX User configuration part END + *---------------------------------------------------------------------------*/ + +#define OS_TRV ((uint32_t)((((float)OS_CLOCK*(float)OS_TICK))/(float)1E6+0.5f)-1) + +U32 os_get_trv (void) +{ + return OS_TRV; +} + +extern void rtx_show_all_threads(void); + +#if TASK_HUNG_CHECK_ENABLED +extern void check_hung_tasks(void); +#endif + +/*---------------------------------------------------------------------------- + * OS Idle daemon + *---------------------------------------------------------------------------*/ +void os_idle_demon (void) { + /* The idle demon is a system thread, running when no other thread is */ + /* ready to run. */ + + unsigned int os_ticks; + HWTIMER_ID timer; + int ret; +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 2) + unsigned int start_time; + unsigned int start_os_time; + unsigned int start_tick; +#endif +#if defined(FPGA) || !(defined(ROM_BUILD) || defined(PROGRAMMER)) + ret = hal_trace_crash_dump_register(HAL_TRACE_CRASH_DUMP_MODULE_SYS, rtx_show_all_threads); + ASSERT(ret == 0, "IdleTask: Failed to register crash dump callback"); +#endif + timer = hwtimer_alloc((HWTIMER_CALLBACK_T)rt_psh_req, NULL); + ASSERT(timer, "IdleTask: Failed to alloc sleep timer"); + /* Sleep: ideally, we should put the chip to sleep. + Unfortunately, this usually requires disconnecting the interface chip (debugger). + This can be done, but it would break the local file system. + */ + for (;;) { +#if TASK_HUNG_CHECK_ENABLED + check_hung_tasks(); +#endif + + if (hal_sleep_light_sleep() == HAL_SLEEP_STATUS_DEEP) { + os_ticks = rt_suspend(); + if (os_ticks) { +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 2) + __disable_irq(); +#endif + ret = hwtimer_start(timer, MS_TO_HWTICKS(os_ticks * OS_TICK / 1000)); +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 2) + start_time = hal_sys_timer_get(); + start_tick = SysTick->VAL; + start_os_time = os_time; + __enable_irq(); +#endif + if (ret == 0) { + sleep(); + ret = hwtimer_stop(timer); + } +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 2) + if (hal_sys_timer_get() - start_time >= MS_TO_HWTICKS(1)) { + TRACE(4,"[%u/0x%X][%2u/%u] os_idle_demon start timer", + TICKS_TO_MS(start_time), start_time, start_tick, start_os_time); + } +#endif + } + rt_resume(os_ticks); + } + } +} + +/*---------------------------------------------------------------------------- + * RTX Errors + *---------------------------------------------------------------------------*/ +extern void rtx_show_current_thread(void); +void os_error (uint32_t err_code) { + /* This function is called when a runtime error is detected. Parameter */ + /* 'err_code' holds the runtime error code (defined in RTX_Conf.h). */ + + rtx_show_current_thread(); + ASSERT(0, "os_error: %d ThreadId:%d\n", err_code, osGetThreadIntId()); + + //mbed_die(); +} + +void os_error_str (const char *str, ...) { + va_list ap; + static char buf[50]; + + va_start(ap, str); + vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + + ASSERT(0, "%s\n", buf); +} + +void sysThreadError(osStatus status) { + if (status != osOK) { + TRACE_IMM(1,"osStatus: %08x\n", status); + rtx_show_current_thread(); + ASSERT(0, "sysThreadError ThreadId:%d\n", osGetThreadIntId()); + } +} + +/*---------------------------------------------------------------------------- + * RTX Configuration Functions + *---------------------------------------------------------------------------*/ + +#include "RTX_CM_lib.h" + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c new file mode 100644 index 0000000..492e94a --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c @@ -0,0 +1,301 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.C + * Purpose: Hardware Abstraction Layer for Cortex-M0 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_HAL_CM.h" +#include "rt_Task.h" +#include "rt_MemBox.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +__asm void rt_set_PSP (U32 stack) { + MSR PSP,R0 + BX LR +} + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +__asm U32 rt_get_PSP (void) { + MRS R0,PSP + BX LR +} + + +/*--------------------------- os_set_env ------------------------------------*/ + +__asm void os_set_env (void) { + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + MOV R0,SP ; PSP = MSP + MSR PSP,R0 + LDR R0,=__cpp(&os_flags) + LDRB R0,[R0] + LSLS R0,#31 + BNE PrivilegedE + MOVS R0,#0x03 ; Unprivileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR +PrivilegedE + MOVS R0,#0x02 ; Privileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR + + ALIGN +} + + +/*--------------------------- _alloc_box ------------------------------------*/ + +__asm void *_alloc_box (void *box_mem) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R3,=__cpp(rt_alloc_box) + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedA + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedA + SVC 0 + BX LR +PrivilegedA + BX R12 + + ALIGN +} + + +/*--------------------------- _free_box -------------------------------------*/ + +__asm int _free_box (void *box_mem, void *box) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R3,=__cpp(rt_free_box) + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedF + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedF + SVC 0 + BX LR +PrivilegedF + BX R12 + + ALIGN +} + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +__asm void SVC_Handler (void) { + PRESERVE8 + + IMPORT SVC_Count + IMPORT SVC_Table + IMPORT rt_stk_check + + MRS R0,PSP ; Read PSP + LDR R1,[R0,#24] ; Read Saved PC from Stack + SUBS R1,R1,#2 ; Point to SVC Instruction + LDRB R1,[R1] ; Load SVC Number + CMP R1,#0 + BNE SVC_User ; User SVC Number > 0 + + MOV LR,R4 + LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack + MOV R12,R4 + MOV R4,LR + BLX R12 ; Call SVC Function + + MRS R3,PSP ; Read PSP + STMIA R3!,{R0-R2} ; Store return values + + LDR R3,=__cpp(&os_tsk) + LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ SVC_Exit ; no task switch + + SUBS R3,#8 + CMP R1,#0 ; Runtask deleted? + BEQ SVC_Next + + MRS R0,PSP ; Read PSP + SUBS R0,R0,#32 ; Adjust Start Address + STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + STMIA R0!,{R4-R7} ; Save old context (R4-R7) + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save old context (R8-R11) + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + +SVC_Next + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + ADDS R0,R0,#16 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Write PSP + SUBS R0,R0,#32 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) + +SVC_Exit + MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value + MVNS R0,R0 + BX R0 ; RETI to Thread Mode, use PSP + + /*------------------- User SVC ------------------------------*/ + +SVC_User + PUSH {R4,LR} ; Save Registers + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done ; Overflow + + LDR R4,=SVC_Table-4 + LSLS R1,R1,#2 + LDR R4,[R4,R1] ; Load SVC Function Address + MOV LR,R4 + + LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack + MOV R12,R4 + BLX LR ; Call SVC Function + + MRS R4,PSP ; Read PSP + STMIA R4!,{R0-R3} ; Function return values +SVC_Done + POP {R4,PC} ; RETI + + ALIGN +} + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +__asm void PendSV_Handler (void) { + PRESERVE8 + + BL __cpp(rt_pop_req) + +Sys_Switch + LDR R3,=__cpp(&os_tsk) + LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ Sys_Exit ; no task switch + + SUBS R3,#8 + + MRS R0,PSP ; Read PSP + SUBS R0,R0,#32 ; Adjust Start Address + STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + STMIA R0!,{R4-R7} ; Save old context (R4-R7) + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save old context (R8-R11) + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + ADDS R0,R0,#16 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Write PSP + SUBS R0,R0,#32 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) + +Sys_Exit + MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value + MVNS R0,R0 + BX R0 ; RETI to Thread Mode, use PSP + + ALIGN +} + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +__asm void SysTick_Handler (void) { + PRESERVE8 + + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +__asm void OS_Tick_Handler (void) { + PRESERVE8 + + BL __cpp(os_tick_irqack) + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S new file mode 100644 index 0000000..78c39bb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S @@ -0,0 +1,57 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + AREA SVC_TABLE, CODE, READONLY + + EXPORT SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + EXPORT SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S new file mode 100644 index 0000000..ce4c3d7 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S @@ -0,0 +1,370 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.S + * Purpose: Hardware Abstraction Layer for Cortex-M0 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + .file "HAL_CM0.S" + .syntax unified + + .equ TCB_TSTACK, 40 + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + .thumb + + .section ".text" + .align 2 + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +# void rt_set_PSP (U32 stack); + + .thumb_func + .type rt_set_PSP, %function + .global rt_set_PSP +rt_set_PSP: + .fnstart + .cantunwind + + MSR PSP,R0 + BX LR + + .fnend + .size rt_set_PSP, .-rt_set_PSP + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +# U32 rt_get_PSP (void); + + .thumb_func + .type rt_get_PSP, %function + .global rt_get_PSP +rt_get_PSP: + .fnstart + .cantunwind + + MRS R0,PSP + BX LR + + .fnend + .size rt_get_PSP, .-rt_get_PSP + + +/*--------------------------- os_set_env ------------------------------------*/ + +# void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + .thumb_func + .type os_set_env, %function + .global os_set_env +os_set_env: + .fnstart + .cantunwind + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + BNE PrivilegedE + MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR +PrivilegedE: + MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + .fnend + .size os_set_env, .-os_set_env + + +/*--------------------------- _alloc_box ------------------------------------*/ + +# void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _alloc_box, %function + .global _alloc_box +_alloc_box: + .fnstart + .cantunwind + + LDR R3,=rt_alloc_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedA + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedA + SVC 0 + BX LR +PrivilegedA: + BX R12 + + .fnend + .size _alloc_box, .-_alloc_box + + +/*--------------------------- _free_box -------------------------------------*/ + +# int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _free_box, %function + .global _free_box +_free_box: + .fnstart + .cantunwind + + LDR R3,=rt_free_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedF + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedF + SVC 0 + BX LR +PrivilegedF: + BX R12 + + .fnend + .size _free_box, .-_free_box + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +# void SVC_Handler (void); + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler +SVC_Handler: + .fnstart + .cantunwind + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + SUBS R1,R1,#2 /* Point to SVC Instruction */ + LDRB R1,[R1] /* Load SVC Number */ + CMP R1,#0 + BNE SVC_User /* User SVC Number > 0 */ + + MOV LR,R4 + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + MOV R4,LR + BLX R12 /* Call SVC Function */ + + MRS R3,PSP /* Read PSP */ + STMIA R3!,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ SVC_Exit /* no task switch */ + + SUBS R3,#8 + CMP R1,#0 /* Runtask deleted? */ + BEQ SVC_Next + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +SVC_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LSLS R1,R1,#2 + LDR R4,[R4,R1] /* Load SVC Function Address */ + MOV LR,R4 + + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + BLX LR /* Call SVC Function */ + + MRS R4,PSP /* Read PSP */ + STMIA R4!,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + .fnend + .size SVC_Handler, .-SVC_Handler + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +# void PendSV_Handler (void); + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .global Sys_Switch +PendSV_Handler: + .fnstart + .cantunwind + + BL rt_pop_req + +Sys_Switch: + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ Sys_Exit /* no task switch */ + + SUBS R3,#8 + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +Sys_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +# void SysTick_Handler (void); + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler +SysTick_Handler: + .fnstart + .cantunwind + + BL rt_systick + B Sys_Switch + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +# void OS_Tick_Handler (void); + + .thumb_func + .type OS_Tick_Handler, %function + .global OS_Tick_Handler +OS_Tick_Handler: + .fnstart + .cantunwind + + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + .fnend + .size OS_Tick_Handler, .-OS_Tick_Handler + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S new file mode 100644 index 0000000..6cafc00 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S @@ -0,0 +1,56 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + .file "SVC_Table.S" + + + .section ".svc_table" + + .global SVC_Table +SVC_Table: +/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ +# .long __SVC_1 /* user SVC function */ +SVC_End: + + .global SVC_Count +SVC_Count: + .long (SVC_End-SVC_Table)/4 + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S new file mode 100644 index 0000000..c39fcdd --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S @@ -0,0 +1,312 @@ +/*---------------------------------------------------------------------------- + * CMSIS-RTOS - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.S + * Purpose: Hardware Abstraction Layer for Cortex-M0 + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + NAME HAL_CM0.S + + #define TCB_TSTACK 40 + + EXTERN os_flags + EXTERN os_tsk + EXTERN rt_alloc_box + EXTERN rt_free_box + EXTERN rt_stk_check + EXTERN rt_pop_req + EXTERN rt_systick + EXTERN os_tick_irqack + EXTERN SVC_Table + EXTERN SVC_Count + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + SECTION .text:CODE:NOROOT(2) + THUMB + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +; void rt_set_PSP (U32 stack); + + PUBLIC rt_set_PSP +rt_set_PSP: + + MSR PSP,R0 + BX LR + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +; U32 rt_get_PSP (void); + + PUBLIC rt_get_PSP +rt_get_PSP: + + MRS R0,PSP + BX LR + + +/*--------------------------- os_set_env ------------------------------------*/ + +; void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + PUBLIC os_set_env +os_set_env: + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + BNE PrivilegedE + MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR +PrivilegedE: + MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + +/*--------------------------- _alloc_box ------------------------------------*/ + +; void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + PUBLIC _alloc_box +_alloc_box: + + LDR R3,=rt_alloc_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedA + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedA + SVC 0 + BX LR +PrivilegedA: + BX R12 + + +/*--------------------------- _free_box -------------------------------------*/ + +; int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + PUBLIC _free_box +_free_box: + + LDR R3,=rt_free_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedF + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedF + SVC 0 + BX LR +PrivilegedF: + BX R12 + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +; void SVC_Handler (void); + + PUBLIC SVC_Handler +SVC_Handler: + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + SUBS R1,R1,#2 /* Point to SVC Instruction */ + LDRB R1,[R1] /* Load SVC Number */ + CMP R1,#0 + BNE SVC_User /* User SVC Number > 0 */ + + MOV LR,R4 + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + MOV R4,LR + BLX R12 /* Call SVC Function */ + + MRS R3,PSP /* Read PSP */ + STMIA R3!,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ SVC_Exit /* no task switch */ + + SUBS R3,#8 + CMP R1,#0 /* Runtask deleted? */ + BEQ SVC_Next + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +SVC_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LSLS R1,R1,#2 + LDR R4,[R4,R1] /* Load SVC Function Address */ + MOV LR,R4 + + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + BLX LR /* Call SVC Function */ + + MRS R4,PSP /* Read PSP */ + STMIA R4!,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +; void PendSV_Handler (void); + + PUBLIC PendSV_Handler +PendSV_Handler: + + BL rt_pop_req + +Sys_Switch: + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ Sys_Exit /* no task switch */ + + SUBS R3,#8 + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +Sys_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +; void SysTick_Handler (void); + + PUBLIC SysTick_Handler +SysTick_Handler: + + BL rt_systick + B Sys_Switch + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +; void OS_Tick_Handler (void); + + PUBLIC OS_Tick_Handler +OS_Tick_Handler: + + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/SVC_Table.S new file mode 100644 index 0000000..18710cb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/SVC_Table.S @@ -0,0 +1,58 @@ +;/*---------------------------------------------------------------------------- +; * CMSIS-RTOS - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.70 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + NAME SVC_TABLE + SECTION .text:CONST (2) + + PUBLIC SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + PUBLIC SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c new file mode 100644 index 0000000..492e94a --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c @@ -0,0 +1,301 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.C + * Purpose: Hardware Abstraction Layer for Cortex-M0 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_HAL_CM.h" +#include "rt_Task.h" +#include "rt_MemBox.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +__asm void rt_set_PSP (U32 stack) { + MSR PSP,R0 + BX LR +} + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +__asm U32 rt_get_PSP (void) { + MRS R0,PSP + BX LR +} + + +/*--------------------------- os_set_env ------------------------------------*/ + +__asm void os_set_env (void) { + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + MOV R0,SP ; PSP = MSP + MSR PSP,R0 + LDR R0,=__cpp(&os_flags) + LDRB R0,[R0] + LSLS R0,#31 + BNE PrivilegedE + MOVS R0,#0x03 ; Unprivileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR +PrivilegedE + MOVS R0,#0x02 ; Privileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR + + ALIGN +} + + +/*--------------------------- _alloc_box ------------------------------------*/ + +__asm void *_alloc_box (void *box_mem) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R3,=__cpp(rt_alloc_box) + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedA + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedA + SVC 0 + BX LR +PrivilegedA + BX R12 + + ALIGN +} + + +/*--------------------------- _free_box -------------------------------------*/ + +__asm int _free_box (void *box_mem, void *box) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R3,=__cpp(rt_free_box) + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedF + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedF + SVC 0 + BX LR +PrivilegedF + BX R12 + + ALIGN +} + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +__asm void SVC_Handler (void) { + PRESERVE8 + + IMPORT SVC_Count + IMPORT SVC_Table + IMPORT rt_stk_check + + MRS R0,PSP ; Read PSP + LDR R1,[R0,#24] ; Read Saved PC from Stack + SUBS R1,R1,#2 ; Point to SVC Instruction + LDRB R1,[R1] ; Load SVC Number + CMP R1,#0 + BNE SVC_User ; User SVC Number > 0 + + MOV LR,R4 + LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack + MOV R12,R4 + MOV R4,LR + BLX R12 ; Call SVC Function + + MRS R3,PSP ; Read PSP + STMIA R3!,{R0-R2} ; Store return values + + LDR R3,=__cpp(&os_tsk) + LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ SVC_Exit ; no task switch + + SUBS R3,#8 + CMP R1,#0 ; Runtask deleted? + BEQ SVC_Next + + MRS R0,PSP ; Read PSP + SUBS R0,R0,#32 ; Adjust Start Address + STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + STMIA R0!,{R4-R7} ; Save old context (R4-R7) + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save old context (R8-R11) + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + +SVC_Next + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + ADDS R0,R0,#16 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Write PSP + SUBS R0,R0,#32 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) + +SVC_Exit + MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value + MVNS R0,R0 + BX R0 ; RETI to Thread Mode, use PSP + + /*------------------- User SVC ------------------------------*/ + +SVC_User + PUSH {R4,LR} ; Save Registers + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done ; Overflow + + LDR R4,=SVC_Table-4 + LSLS R1,R1,#2 + LDR R4,[R4,R1] ; Load SVC Function Address + MOV LR,R4 + + LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack + MOV R12,R4 + BLX LR ; Call SVC Function + + MRS R4,PSP ; Read PSP + STMIA R4!,{R0-R3} ; Function return values +SVC_Done + POP {R4,PC} ; RETI + + ALIGN +} + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +__asm void PendSV_Handler (void) { + PRESERVE8 + + BL __cpp(rt_pop_req) + +Sys_Switch + LDR R3,=__cpp(&os_tsk) + LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ Sys_Exit ; no task switch + + SUBS R3,#8 + + MRS R0,PSP ; Read PSP + SUBS R0,R0,#32 ; Adjust Start Address + STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + STMIA R0!,{R4-R7} ; Save old context (R4-R7) + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save old context (R8-R11) + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + ADDS R0,R0,#16 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Write PSP + SUBS R0,R0,#32 ; Adjust Start Address + LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) + +Sys_Exit + MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value + MVNS R0,R0 + BX R0 ; RETI to Thread Mode, use PSP + + ALIGN +} + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +__asm void SysTick_Handler (void) { + PRESERVE8 + + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +__asm void OS_Tick_Handler (void) { + PRESERVE8 + + BL __cpp(os_tick_irqack) + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S new file mode 100644 index 0000000..78c39bb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S @@ -0,0 +1,57 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + AREA SVC_TABLE, CODE, READONLY + + EXPORT SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + EXPORT SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S new file mode 100644 index 0000000..ce4c3d7 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S @@ -0,0 +1,370 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.S + * Purpose: Hardware Abstraction Layer for Cortex-M0 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + .file "HAL_CM0.S" + .syntax unified + + .equ TCB_TSTACK, 40 + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + .thumb + + .section ".text" + .align 2 + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +# void rt_set_PSP (U32 stack); + + .thumb_func + .type rt_set_PSP, %function + .global rt_set_PSP +rt_set_PSP: + .fnstart + .cantunwind + + MSR PSP,R0 + BX LR + + .fnend + .size rt_set_PSP, .-rt_set_PSP + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +# U32 rt_get_PSP (void); + + .thumb_func + .type rt_get_PSP, %function + .global rt_get_PSP +rt_get_PSP: + .fnstart + .cantunwind + + MRS R0,PSP + BX LR + + .fnend + .size rt_get_PSP, .-rt_get_PSP + + +/*--------------------------- os_set_env ------------------------------------*/ + +# void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + .thumb_func + .type os_set_env, %function + .global os_set_env +os_set_env: + .fnstart + .cantunwind + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + BNE PrivilegedE + MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR +PrivilegedE: + MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + .fnend + .size os_set_env, .-os_set_env + + +/*--------------------------- _alloc_box ------------------------------------*/ + +# void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _alloc_box, %function + .global _alloc_box +_alloc_box: + .fnstart + .cantunwind + + LDR R3,=rt_alloc_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedA + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedA + SVC 0 + BX LR +PrivilegedA: + BX R12 + + .fnend + .size _alloc_box, .-_alloc_box + + +/*--------------------------- _free_box -------------------------------------*/ + +# int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _free_box, %function + .global _free_box +_free_box: + .fnstart + .cantunwind + + LDR R3,=rt_free_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedF + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedF + SVC 0 + BX LR +PrivilegedF: + BX R12 + + .fnend + .size _free_box, .-_free_box + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +# void SVC_Handler (void); + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler +SVC_Handler: + .fnstart + .cantunwind + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + SUBS R1,R1,#2 /* Point to SVC Instruction */ + LDRB R1,[R1] /* Load SVC Number */ + CMP R1,#0 + BNE SVC_User /* User SVC Number > 0 */ + + MOV LR,R4 + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + MOV R4,LR + BLX R12 /* Call SVC Function */ + + MRS R3,PSP /* Read PSP */ + STMIA R3!,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ SVC_Exit /* no task switch */ + + SUBS R3,#8 + CMP R1,#0 /* Runtask deleted? */ + BEQ SVC_Next + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +SVC_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LSLS R1,R1,#2 + LDR R4,[R4,R1] /* Load SVC Function Address */ + MOV LR,R4 + + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + BLX LR /* Call SVC Function */ + + MRS R4,PSP /* Read PSP */ + STMIA R4!,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + .fnend + .size SVC_Handler, .-SVC_Handler + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +# void PendSV_Handler (void); + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .global Sys_Switch +PendSV_Handler: + .fnstart + .cantunwind + + BL rt_pop_req + +Sys_Switch: + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ Sys_Exit /* no task switch */ + + SUBS R3,#8 + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +Sys_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +# void SysTick_Handler (void); + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler +SysTick_Handler: + .fnstart + .cantunwind + + BL rt_systick + B Sys_Switch + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +# void OS_Tick_Handler (void); + + .thumb_func + .type OS_Tick_Handler, %function + .global OS_Tick_Handler +OS_Tick_Handler: + .fnstart + .cantunwind + + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + .fnend + .size OS_Tick_Handler, .-OS_Tick_Handler + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S new file mode 100644 index 0000000..6cafc00 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S @@ -0,0 +1,56 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + .file "SVC_Table.S" + + + .section ".svc_table" + + .global SVC_Table +SVC_Table: +/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ +# .long __SVC_1 /* user SVC function */ +SVC_End: + + .global SVC_Count +SVC_Count: + .long (SVC_End-SVC_Table)/4 + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S new file mode 100644 index 0000000..c39fcdd --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S @@ -0,0 +1,312 @@ +/*---------------------------------------------------------------------------- + * CMSIS-RTOS - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM0.S + * Purpose: Hardware Abstraction Layer for Cortex-M0 + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + NAME HAL_CM0.S + + #define TCB_TSTACK 40 + + EXTERN os_flags + EXTERN os_tsk + EXTERN rt_alloc_box + EXTERN rt_free_box + EXTERN rt_stk_check + EXTERN rt_pop_req + EXTERN rt_systick + EXTERN os_tick_irqack + EXTERN SVC_Table + EXTERN SVC_Count + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + SECTION .text:CODE:NOROOT(2) + THUMB + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +; void rt_set_PSP (U32 stack); + + PUBLIC rt_set_PSP +rt_set_PSP: + + MSR PSP,R0 + BX LR + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +; U32 rt_get_PSP (void); + + PUBLIC rt_get_PSP +rt_get_PSP: + + MRS R0,PSP + BX LR + + +/*--------------------------- os_set_env ------------------------------------*/ + +; void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + PUBLIC os_set_env +os_set_env: + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + BNE PrivilegedE + MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR +PrivilegedE: + MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + +/*--------------------------- _alloc_box ------------------------------------*/ + +; void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + PUBLIC _alloc_box +_alloc_box: + + LDR R3,=rt_alloc_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedA + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedA + SVC 0 + BX LR +PrivilegedA: + BX R12 + + +/*--------------------------- _free_box -------------------------------------*/ + +; int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + PUBLIC _free_box +_free_box: + + LDR R3,=rt_free_box + MOV R12,R3 + MRS R3,IPSR + LSLS R3,#24 + BNE PrivilegedF + MRS R3,CONTROL + LSLS R3,#31 + BEQ PrivilegedF + SVC 0 + BX LR +PrivilegedF: + BX R12 + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +; void SVC_Handler (void); + + PUBLIC SVC_Handler +SVC_Handler: + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + SUBS R1,R1,#2 /* Point to SVC Instruction */ + LDRB R1,[R1] /* Load SVC Number */ + CMP R1,#0 + BNE SVC_User /* User SVC Number > 0 */ + + MOV LR,R4 + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + MOV R4,LR + BLX R12 /* Call SVC Function */ + + MRS R3,PSP /* Read PSP */ + STMIA R3!,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ SVC_Exit /* no task switch */ + + SUBS R3,#8 + CMP R1,#0 /* Runtask deleted? */ + BEQ SVC_Next + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +SVC_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LSLS R1,R1,#2 + LDR R4,[R4,R1] /* Load SVC Function Address */ + MOV LR,R4 + + LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ + MOV R12,R4 + BLX LR /* Call SVC Function */ + + MRS R4,PSP /* Read PSP */ + STMIA R4!,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +; void PendSV_Handler (void); + + PUBLIC PendSV_Handler +PendSV_Handler: + + BL rt_pop_req + +Sys_Switch: + LDR R3,=os_tsk + LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ Sys_Exit /* no task switch */ + + SUBS R3,#8 + + MRS R0,PSP /* Read PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + ADDS R0,R0,#16 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 /* Write PSP */ + SUBS R0,R0,#32 /* Adjust Start Address */ + LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ + +Sys_Exit: + MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ + MVNS R0,R0 + BX R0 /* RETI to Thread Mode, use PSP */ + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +; void SysTick_Handler (void); + + PUBLIC SysTick_Handler +SysTick_Handler: + + BL rt_systick + B Sys_Switch + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +; void OS_Tick_Handler (void); + + PUBLIC OS_Tick_Handler +OS_Tick_Handler: + + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.S new file mode 100644 index 0000000..18710cb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.S @@ -0,0 +1,58 @@ +;/*---------------------------------------------------------------------------- +; * CMSIS-RTOS - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.70 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + NAME SVC_TABLE + SECTION .text:CONST (2) + + PUBLIC SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + PUBLIC SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c new file mode 100644 index 0000000..feb1457 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c @@ -0,0 +1,249 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM3.C + * Purpose: Hardware Abstraction Layer for Cortex-M3 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_HAL_CM.h" +#include "rt_Task.h" +#include "rt_MemBox.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +__asm void rt_set_PSP (U32 stack) { + MSR PSP,R0 + BX LR +} + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +__asm U32 rt_get_PSP (void) { + MRS R0,PSP + BX LR +} + + +/*--------------------------- os_set_env ------------------------------------*/ + +__asm void os_set_env (void) { + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + MOV R0,SP ; PSP = MSP + MSR PSP,R0 + LDR R0,=__cpp(&os_flags) + LDRB R0,[R0] + LSLS R0,#31 + MOVNE R0,#0x02 ; Privileged Thread mode, use PSP + MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR + + ALIGN +} + + +/*--------------------------- _alloc_box ------------------------------------*/ + +__asm void *_alloc_box (void *box_mem) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R12,=__cpp(rt_alloc_box) + MRS R3,IPSR + LSLS R3,#24 + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + BXEQ R12 + SVC 0 + BX LR + + ALIGN +} + + +/*--------------------------- _free_box -------------------------------------*/ + +__asm int _free_box (void *box_mem, void *box) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R12,=__cpp(rt_free_box) + MRS R3,IPSR + LSLS R3,#24 + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + BXEQ R12 + SVC 0 + BX LR + + ALIGN +} + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +__asm void SVC_Handler (void) { + PRESERVE8 + + IMPORT SVC_Count + IMPORT SVC_Table + IMPORT rt_stk_check + + MRS R0,PSP ; Read PSP + LDR R1,[R0,#24] ; Read Saved PC from Stack + LDRB R1,[R1,#-2] ; Load SVC Number + CBNZ R1,SVC_User + + LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack + BLX R12 ; Call SVC Function + + MRS R12,PSP ; Read PSP + STM R12,{R0-R2} ; Store return values + + LDR R3,=__cpp(&os_tsk) + LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ SVC_Exit ; no task switch + + CBZ R1,SVC_Next ; Runtask deleted? + STMDB R12!,{R4-R11} ; Save Old context + STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + +SVC_Next + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + LDMIA R12!,{R4-R11} ; Restore New Context + MSR PSP,R12 ; Write PSP + +SVC_Exit + MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value + BX LR + + /*------------------- User SVC ------------------------------*/ + +SVC_User + PUSH {R4,LR} ; Save Registers + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done ; Overflow + + LDR R4,=SVC_Table-4 + LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address + + LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack + BLX R4 ; Call SVC Function + + MRS R12,PSP + STM R12,{R0-R3} ; Function return values +SVC_Done + POP {R4,PC} ; RETI + + ALIGN +} + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +__asm void PendSV_Handler (void) { + PRESERVE8 + + BL __cpp(rt_pop_req) + +Sys_Switch + LDR R3,=__cpp(&os_tsk) + LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 + BEQ Sys_Exit + + MRS R12,PSP ; Read PSP + STMDB R12!,{R4-R11} ; Save Old context + STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + LDMIA R12!,{R4-R11} ; Restore New Context + MSR PSP,R12 ; Write PSP + +Sys_Exit + MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value + BX LR ; Return to Thread Mode + + ALIGN +} + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +__asm void SysTick_Handler (void) { + PRESERVE8 + + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +__asm void OS_Tick_Handler (void) { + PRESERVE8 + + BL __cpp(os_tick_irqack) + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S new file mode 100644 index 0000000..78c39bb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S @@ -0,0 +1,57 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + AREA SVC_TABLE, CODE, READONLY + + EXPORT SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + EXPORT SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S new file mode 100644 index 0000000..5f12fd3 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S @@ -0,0 +1,323 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM3.S + * Purpose: Hardware Abstraction Layer for Cortex-M3 + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + .file "HAL_CM3.S" + .syntax unified + + .equ TCB_TSTACK, 40 + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + .thumb + + .section ".text" + .align 2 + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +# void rt_set_PSP (U32 stack); + + .thumb_func + .type rt_set_PSP, %function + .global rt_set_PSP +rt_set_PSP: + .fnstart + .cantunwind + + MSR PSP,R0 + BX LR + + .fnend + .size rt_set_PSP, .-rt_set_PSP + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +# U32 rt_get_PSP (void); + + .thumb_func + .type rt_get_PSP, %function + .global rt_get_PSP +rt_get_PSP: + .fnstart + .cantunwind + + MRS R0,PSP + BX LR + + .fnend + .size rt_get_PSP, .-rt_get_PSP + + +/*--------------------------- os_set_env ------------------------------------*/ + +# void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + .thumb_func + .type os_set_env, %function + .global os_set_env +os_set_env: + .fnstart + .cantunwind + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + ITE NE + MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ + MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + .fnend + .size os_set_env, .-os_set_env + + +/*--------------------------- _alloc_box ------------------------------------*/ + +# void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _alloc_box, %function + .global _alloc_box +_alloc_box: + .fnstart + .cantunwind + + LDR R12,=rt_alloc_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + .fnend + .size _alloc_box, .-_alloc_box + + +/*--------------------------- _free_box -------------------------------------*/ + +# int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _free_box, %function + .global _free_box +_free_box: + .fnstart + .cantunwind + + LDR R12,=rt_free_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + .fnend + .size _free_box, .-_free_box + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +# void SVC_Handler (void); + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler +SVC_Handler: + .fnstart + .cantunwind + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + LDRB R1,[R1,#-2] /* Load SVC Number */ + CBNZ R1,SVC_User + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + BLX R12 /* Call SVC Function */ + + MRS R12,PSP /* Read PSP */ + STM R12,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ SVC_Exit /* no task switch */ + + CBZ R1,SVC_Next /* Runtask deleted? */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + MSR PSP,R12 /* Write PSP */ + +SVC_Exit: + MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + BX LR + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + BLX R4 /* Call SVC Function */ + + MRS R12,PSP + STM R12,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + .fnend + .size SVC_Handler, .-SVC_Handler + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +# void PendSV_Handler (void); + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .global Sys_Switch +PendSV_Handler: + .fnstart + .cantunwind + + BL rt_pop_req + +Sys_Switch: + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ Sys_Exit + + MRS R12,PSP /* Read PSP */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + MSR PSP,R12 /* Write PSP */ + +Sys_Exit: + MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + BX LR /* Return to Thread Mode */ + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +# void SysTick_Handler (void); + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler +SysTick_Handler: + .fnstart + .cantunwind + + BL rt_systick + B Sys_Switch + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +# void OS_Tick_Handler (void); + + .thumb_func + .type OS_Tick_Handler, %function + .global OS_Tick_Handler +OS_Tick_Handler: + .fnstart + .cantunwind + + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + .fnend + .size OS_Tick_Handler, .-OS_Tick_Handler + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S new file mode 100644 index 0000000..6cafc00 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S @@ -0,0 +1,56 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.60 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + .file "SVC_Table.S" + + + .section ".svc_table" + + .global SVC_Table +SVC_Table: +/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ +# .long __SVC_1 /* user SVC function */ +SVC_End: + + .global SVC_Count +SVC_Count: + .long (SVC_End-SVC_Table)/4 + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S new file mode 100644 index 0000000..57015af --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S @@ -0,0 +1,265 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM3.S + * Purpose: Hardware Abstraction Layer for Cortex-M3 + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + NAME HAL_CM3.S + + #define TCB_TSTACK 40 + + EXTERN os_flags + EXTERN os_tsk + EXTERN rt_alloc_box + EXTERN rt_free_box + EXTERN rt_stk_check + EXTERN rt_pop_req + EXTERN rt_systick + EXTERN os_tick_irqack + EXTERN SVC_Table + EXTERN SVC_Count + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + SECTION .text:CODE:NOROOT(2) + THUMB + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +; void rt_set_PSP (U32 stack); + + PUBLIC rt_set_PSP +rt_set_PSP: + + MSR PSP,R0 + BX LR + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +; U32 rt_get_PSP (void); + + PUBLIC rt_get_PSP +rt_get_PSP: + + MRS R0,PSP + BX LR + + +/*--------------------------- os_set_env ------------------------------------*/ + +; void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + PUBLIC os_set_env +os_set_env: + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + ITE NE + MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ + MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + +/*--------------------------- _alloc_box ------------------------------------*/ + +; void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + PUBLIC _alloc_box +_alloc_box: + + LDR R12,=rt_alloc_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + +/*--------------------------- _free_box -------------------------------------*/ + +; int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + PUBLIC _free_box +_free_box: + + LDR R12,=rt_free_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +; void SVC_Handler (void); + + PUBLIC SVC_Handler +SVC_Handler: + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + LDRB R1,[R1,#-2] /* Load SVC Number */ + CBNZ R1,SVC_User + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + BLX R12 /* Call SVC Function */ + + MRS R12,PSP /* Read PSP */ + STM R12,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ SVC_Exit /* no task switch */ + + CBZ R1,SVC_Next /* Runtask deleted? */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + MSR PSP,R12 /* Write PSP */ + +SVC_Exit: + MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + BX LR + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + BLX R4 /* Call SVC Function */ + + MRS R12,PSP + STM R12,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +; void PendSV_Handler (void); + + PUBLIC PendSV_Handler +PendSV_Handler: + + BL rt_pop_req + +Sys_Switch: + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + BEQ Sys_Exit + + MRS R12,PSP /* Read PSP */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + MSR PSP,R12 /* Write PSP */ + +Sys_Exit: + MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + BX LR /* Return to Thread Mode */ + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +; void SysTick_Handler (void); + + PUBLIC SysTick_Handler +SysTick_Handler: + + BL rt_systick + B Sys_Switch + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +; void OS_Tick_Handler (void); + + PUBLIC OS_Tick_Handler +OS_Tick_Handler: + + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/SVC_Table.S new file mode 100644 index 0000000..18710cb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/SVC_Table.S @@ -0,0 +1,58 @@ +;/*---------------------------------------------------------------------------- +; * CMSIS-RTOS - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.70 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + NAME SVC_TABLE + SECTION .text:CONST (2) + + PUBLIC SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + PUBLIC SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/HAL_CM4.c b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/HAL_CM4.c new file mode 100644 index 0000000..32327d8 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/HAL_CM4.c @@ -0,0 +1,309 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM4.C + * Purpose: Hardware Abstraction Layer for Cortex-M4 + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_HAL_CM.h" +#include "rt_Task.h" +#include "rt_MemBox.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +__asm void rt_set_PSP (U32 stack) { + MSR PSP,R0 + BX LR +} + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +__asm U32 rt_get_PSP (void) { + MRS R0,PSP + BX LR +} + + +/*--------------------------- os_set_env ------------------------------------*/ + +__asm void os_set_env (void) { + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + MOV R0,SP ; PSP = MSP + MSR PSP,R0 + LDR R0,=__cpp(&os_flags) + LDRB R0,[R0] + LSLS R0,#31 + MOVNE R0,#0x02 ; Privileged Thread mode, use PSP + MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP + MSR CONTROL,R0 + BX LR + + ALIGN +} + + +/*--------------------------- _alloc_box ------------------------------------*/ + +__asm void *_alloc_box (void *box_mem) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R12,=__cpp(rt_alloc_box) + MRS R3,IPSR + LSLS R3,#24 + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + BXEQ R12 + SVC 0 + BX LR + + ALIGN +} + + +/*--------------------------- _free_box -------------------------------------*/ + +__asm int _free_box (void *box_mem, void *box) { + /* Function wrapper for Unprivileged/Privileged mode. */ + LDR R12,=__cpp(rt_free_box) + MRS R3,IPSR + LSLS R3,#24 + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + BXEQ R12 + SVC 0 + BX LR + + ALIGN +} + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +__asm void SVC_Handler (void) { + PRESERVE8 + + IMPORT SVC_Count + IMPORT SVC_Table + IMPORT rt_stk_check + +#ifdef IFX_XMC4XXX + EXPORT SVC_Handler_Veneer +SVC_Handler_Veneer +#endif + + MRS R0,PSP ; Read PSP + LDR R1,[R0,#24] ; Read Saved PC from Stack + LDRB R1,[R1,#-2] ; Load SVC Number + CBNZ R1,SVC_User + + LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack + PUSH {R4,LR} ; Save EXC_RETURN + BLX R12 ; Call SVC Function + POP {R4,LR} ; Restore EXC_RETURN + + MRS R12,PSP ; Read PSP + STM R12,{R0-R2} ; Store return values + + LDR R3,=__cpp(&os_tsk) + LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 +#ifdef IFX_XMC4XXX + PUSHEQ {LR} + POPEQ {PC} +#else + BXEQ LR ; RETI, no task switch +#endif + + CBZ R1,SVC_Next ; Runtask deleted? + TST LR,#0x10 ; is it extended frame? + VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs + MOVEQ R0,#0x01 ; os_tsk->stack_frame val + MOVNE R0,#0x00 + STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val + STMDB R12!,{R4-R11} ; Save Old context + STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + +SVC_Next + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + LDMIA R12!,{R4-R11} ; Restore New Context + LDRB R0,[R2,#TCB_STACKF] ; Stack Frame + CMP R0,#0 ; Basic/Extended Stack Frame + VLDMIANE R12!,{S16-S31} ; restore VFP hi-registers + MVNNE LR,#:NOT:0xFFFFFFED ; set EXC_RETURN value + MVNEQ LR,#:NOT:0xFFFFFFFD + MSR PSP,R12 ; Write PSP + +SVC_Exit +#ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} +#else + BX LR +#endif + + /*------------------- User SVC ------------------------------*/ + +SVC_User + PUSH {R4,LR} ; Save Registers + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done ; Overflow + + LDR R4,=SVC_Table-4 + LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address + + LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack + BLX R4 ; Call SVC Function + + MRS R12,PSP + STM R12,{R0-R3} ; Function return values +SVC_Done + POP {R4,PC} ; RETI + + ALIGN +} + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +__asm void PendSV_Handler (void) { + PRESERVE8 + +#ifdef IFX_XMC4XXX + EXPORT PendSV_Handler_Veneer +PendSV_Handler_Veneer +#endif + + PUSH {R4,LR} ; Save EXC_RETURN + BL __cpp(rt_pop_req) + +Sys_Switch + POP {R4,LR} ; Restore EXC_RETURN + + LDR R3,=__cpp(&os_tsk) + LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new + CMP R1,R2 +#ifdef IFX_XMC4XXX + PUSHEQ {LR} + POPEQ {PC} +#else + BXEQ LR ; RETI, no task switch +#endif + + MRS R12,PSP ; Read PSP + TST LR,#0x10 ; is it extended frame? + VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs + MOVEQ R0,#0x01 ; os_tsk->stack_frame val + MOVNE R0,#0x00 + STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val + STMDB R12!,{R4-R11} ; Save Old context + STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack + + PUSH {R2,R3} + BL rt_stk_check ; Check for Stack overflow + POP {R2,R3} + + STR R2,[R3] ; os_tsk.run = os_tsk.new + + LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack + LDMIA R12!,{R4-R11} ; Restore New Context + LDRB R0,[R2,#TCB_STACKF] ; Stack Frame + CMP R0,#0 ; Basic/Extended Stack Frame + VLDMIANE R12!,{S16-S31} ; restore VFP hi-regs + MVNNE LR,#:NOT:0xFFFFFFED ; set EXC_RETURN value + MVNEQ LR,#:NOT:0xFFFFFFFD + MSR PSP,R12 ; Write PSP + +Sys_Exit +#ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} +#else + BX LR ; Return to Thread Mode +#endif + + ALIGN +} + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +__asm void SysTick_Handler (void) { + PRESERVE8 + +#ifdef IFX_XMC4XXX + EXPORT SysTick_Handler_Veneer +SysTick_Handler_Veneer +#endif + + PUSH {R4,LR} ; Save EXC_RETURN + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +__asm void OS_Tick_Handler (void) { + PRESERVE8 + + PUSH {R4,LR} ; Save EXC_RETURN + BL __cpp(os_tick_irqack) + BL __cpp(rt_systick) + B Sys_Switch + + ALIGN +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/SVC_Table.S new file mode 100644 index 0000000..d6df830 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_ARM/SVC_Table.S @@ -0,0 +1,57 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.70 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + AREA SVC_TABLE, CODE, READONLY + + EXPORT SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + EXPORT SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/HAL_CM4.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/HAL_CM4.S new file mode 100644 index 0000000..9f45b78 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/HAL_CM4.S @@ -0,0 +1,419 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM4.S + * Purpose: Hardware Abstraction Layer for Cortex-M4 + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "cmsis.h" + + .file "HAL_CM4.S" + .syntax unified + + .equ TCB_STACKF, 32 + .equ TCB_TSTACK, 40 + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + .thumb + + .section ".text" + .align 2 + + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +# void rt_set_PSP (U32 stack); + + .thumb_func + .type rt_set_PSP, %function + .global rt_set_PSP +rt_set_PSP: + .fnstart + .cantunwind + + MSR PSP,R0 + BX LR + + .fnend + .size rt_set_PSP, .-rt_set_PSP + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +# U32 rt_get_PSP (void); + + .thumb_func + .type rt_get_PSP, %function + .global rt_get_PSP +rt_get_PSP: + .fnstart + .cantunwind + + MRS R0,PSP + BX LR + + .fnend + .size rt_get_PSP, .-rt_get_PSP + + +/*--------------------------- os_set_env ------------------------------------*/ + +# void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + .thumb_func + .type os_set_env, %function + .global os_set_env +os_set_env: + .fnstart + .cantunwind + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + ITE NE + MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ + MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + .fnend + .size os_set_env, .-os_set_env + + +/*--------------------------- _alloc_box ------------------------------------*/ + +# void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _alloc_box, %function + .global _alloc_box +_alloc_box: + .fnstart + .cantunwind + + LDR R12,=rt_alloc_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + .fnend + .size _alloc_box, .-_alloc_box + + +/*--------------------------- _free_box -------------------------------------*/ + +# int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + .thumb_func + .type _free_box, %function + .global _free_box +_free_box: + .fnstart + .cantunwind + + LDR R12,=rt_free_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + .fnend + .size _free_box, .-_free_box + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +# void SVC_Handler (void); + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler +SVC_Handler: + .ifdef IFX_XMC4XXX + .global SVC_Handler_Veneer +SVC_Handler_Veneer: + .endif + .fnstart + .cantunwind + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + LDRB R1,[R1,#-2] /* Load SVC Number */ + CBNZ R1,SVC_User + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + PUSH {R4,LR} /* Save EXC_RETURN */ + BLX R12 /* Call SVC Function */ + POP {R4,LR} /* Restore EXC_RETURN */ + + MRS R12,PSP /* Read PSP */ + STM R12,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + .ifdef IFX_XMC4XXX + ITT EQ + PUSHEQ {LR} + POPEQ {PC} + .else + IT EQ + BXEQ LR /* RETI, no task switch */ + .endif + + CBNZ R1,SVC_ContextSave /* Runtask not deleted? */ + + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + TST LR,#0x10 /* is it extended frame? */ + BNE SVC_ContextRestore + LDR R1,=0xE000EF34 + LDR R0,[R1] /* Load FPCCR */ + BIC R0,#1 /* Clear LSPACT (Lazy state) */ + STR R0,[R1] /* Store FPCCR */ + #endif + B SVC_ContextRestore + +SVC_ContextSave: + TST LR,#0x10 /* is it extended frame? */ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + ITTE EQ + VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ + #else + ITE EQ + #endif + MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ + MOVNE R0,#0x00 + STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_ContextRestore: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ + CMP R0,#0 /* Basic/Extended Stack Frame */ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + ITTE NE + VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ + #else + ITE NE + #endif + MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ + MVNEQ LR,#~0xFFFFFFFD + MSR PSP,R12 /* Write PSP */ + +SVC_Exit: + .ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} + .else + BX LR + .endif + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + BLX R4 /* Call SVC Function */ + + MRS R12,PSP + STM R12,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + .fnend + .size SVC_Handler, .-SVC_Handler + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +# void PendSV_Handler (void); + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .global Sys_Switch +PendSV_Handler: + .ifdef IFX_XMC4XXX + .global PendSV_Handler_Veneer +PendSV_Handler_Veneer: + .endif + .fnstart + .cantunwind + + PUSH {R4,LR} /* Save EXC_RETURN */ + BL rt_pop_req + +Sys_Switch: + POP {R4,LR} /* Restore EXC_RETURN */ + + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 + .ifdef IFX_XMC4XXX + ITT EQ + PUSHEQ {LR} + POPEQ {PC} + .else + IT EQ + BXEQ LR /* RETI, no task switch */ + .endif + + MRS R12,PSP /* Read PSP */ + TST LR,#0x10 /* is it extended frame? */ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + ITTE EQ + VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ + #else + ITE EQ + #endif + MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ + MOVNE R0,#0x00 + STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ + CMP R0,#0 /* Basic/Extended Stack Frame */ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + ITTE NE + VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ + #else + ITE NE + #endif + MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ + MVNEQ LR,#~0xFFFFFFFD + MSR PSP,R12 /* Write PSP */ + +Sys_Exit: + .ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} + .else + BX LR /* Return to Thread Mode */ + .endif + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +# void SysTick_Handler (void); + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler +SysTick_Handler: + .ifdef IFX_XMC4XXX + .global SysTick_Handler_Veneer +SysTick_Handler_Veneer: + .endif + .fnstart + .cantunwind + + PUSH {R4,LR} /* Save EXC_RETURN */ + BL rt_systick + B Sys_Switch + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +# void OS_Tick_Handler (void); + + .thumb_func + .type OS_Tick_Handler, %function + .global OS_Tick_Handler +OS_Tick_Handler: + .fnstart + .cantunwind + + PUSH {R4,LR} /* Save EXC_RETURN */ + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + .fnend + .size OS_Tick_Handler, .-OS_Tick_Handler + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/SVC_Table.S new file mode 100644 index 0000000..2b99321 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_GCC/SVC_Table.S @@ -0,0 +1,56 @@ +;/*---------------------------------------------------------------------------- +; * RL-ARM - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.70 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + .file "SVC_Table.S" + + + .section ".svc_table" + + .global SVC_Table +SVC_Table: +/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ +# .long __SVC_1 /* user SVC function */ +SVC_End: + + .global SVC_Count +SVC_Count: + .long (SVC_End-SVC_Table)/4 + + + .end + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_IAR/HAL_CM4.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_IAR/HAL_CM4.S new file mode 100644 index 0000000..a8d6b23 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_IAR/HAL_CM4.S @@ -0,0 +1,333 @@ +/*---------------------------------------------------------------------------- + * CMSIS-RTOS - RTX + *---------------------------------------------------------------------------- + * Name: HAL_CM4.S + * Purpose: Hardware Abstraction Layer for Cortex-M4 + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + + NAME HAL_CM4.S + + #define TCB_STACKF 32 + #define TCB_TSTACK 40 + + EXTERN os_flags + EXTERN os_tsk + EXTERN rt_alloc_box + EXTERN rt_free_box + EXTERN rt_stk_check + EXTERN rt_pop_req + EXTERN rt_systick + EXTERN os_tick_irqack + EXTERN SVC_Table + EXTERN SVC_Count + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + SECTION .text:CODE:NOROOT(2) + THUMB + +/*--------------------------- rt_set_PSP ------------------------------------*/ + +; void rt_set_PSP (U32 stack); + + PUBLIC rt_set_PSP +rt_set_PSP: + + MSR PSP,R0 + BX LR + + +/*--------------------------- rt_get_PSP ------------------------------------*/ + +; U32 rt_get_PSP (void); + + PUBLIC rt_get_PSP +rt_get_PSP: + + MRS R0,PSP + BX LR + + +/*--------------------------- os_set_env ------------------------------------*/ + +; void os_set_env (void); + /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ + + PUBLIC os_set_env +os_set_env: + + MOV R0,SP /* PSP = MSP */ + MSR PSP,R0 + LDR R0,=os_flags + LDRB R0,[R0] + LSLS R0,#31 + ITE NE + MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ + MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ + MSR CONTROL,R0 + BX LR + + +/*--------------------------- _alloc_box ------------------------------------*/ + +; void *_alloc_box (void *box_mem); + /* Function wrapper for Unprivileged/Privileged mode. */ + + PUBLIC _alloc_box +_alloc_box: + + LDR R12,=rt_alloc_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + +/*--------------------------- _free_box -------------------------------------*/ + +; int _free_box (void *box_mem, void *box); + /* Function wrapper for Unprivileged/Privileged mode. */ + + PUBLIC _free_box +_free_box: + + LDR R12,=rt_free_box + MRS R3,IPSR + LSLS R3,#24 + IT NE + BXNE R12 + MRS R3,CONTROL + LSLS R3,#31 + IT EQ + BXEQ R12 + SVC 0 + BX LR + + +/*-------------------------- SVC_Handler ------------------------------------*/ + +; void SVC_Handler (void); + + PUBLIC SVC_Handler +SVC_Handler: + +#ifdef IFX_XMC4XXX + PUBLIC SVC_Handler_Veneer +SVC_Handler_Veneer: +#endif + + MRS R0,PSP /* Read PSP */ + LDR R1,[R0,#24] /* Read Saved PC from Stack */ + LDRB R1,[R1,#-2] /* Load SVC Number */ + CBNZ R1,SVC_User + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + PUSH {R4,LR} /* Save EXC_RETURN */ + BLX R12 /* Call SVC Function */ + POP {R4,LR} /* Restore EXC_RETURN */ + + MRS R12,PSP /* Read PSP */ + STM R12,{R0-R2} /* Store return values */ + + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 +#ifdef IFX_XMC4XXX + ITT EQ + PUSHEQ {LR} + POPEQ {PC} +#else + IT EQ + BXEQ LR /* RETI, no task switch */ +#endif + + CBZ R1,SVC_Next /* Runtask deleted? */ + TST LR,#0x10 /* is it extended frame? */ + ITTE EQ + VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ + MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ + MOVNE R0,#0x00 + STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + +SVC_Next: + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ + CMP R0,#0 /* Basic/Extended Stack Frame */ + ITTE NE + VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ + MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ + MVNEQ LR,#~0xFFFFFFFD + MSR PSP,R12 /* Write PSP */ + +SVC_Exit: +#ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} +#else + BX LR +#endif + + /*------------------- User SVC ------------------------------*/ + +SVC_User: + PUSH {R4,LR} /* Save Registers */ + LDR R2,=SVC_Count + LDR R2,[R2] + CMP R1,R2 + BHI SVC_Done /* Overflow */ + + LDR R4,=SVC_Table-4 + LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ + + LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ + BLX R4 /* Call SVC Function */ + + MRS R12,PSP + STM R12,{R0-R3} /* Function return values */ +SVC_Done: + POP {R4,PC} /* RETI */ + + +/*-------------------------- PendSV_Handler ---------------------------------*/ + +; void PendSV_Handler (void); + + PUBLIC PendSV_Handler +PendSV_Handler: + +#ifdef IFX_XMC4XXX + PUBLIC PendSV_Handler_Veneer +PendSV_Handler_Veneer: +#endif + + PUSH {R4,LR} /* Save EXC_RETURN */ + BL rt_pop_req + +Sys_Switch: + POP {R4,LR} /* Restore EXC_RETURN */ + + LDR R3,=os_tsk + LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ + CMP R1,R2 +#ifdef IFX_XMC4XXX + ITT EQ + PUSHEQ {LR} + POPEQ {PC} +#else + IT EQ + BXEQ LR /* RETI, no task switch */ +#endif + + MRS R12,PSP /* Read PSP */ + TST LR,#0x10 /* is it extended frame? */ + ITTE EQ + VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ + MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ + MOVNE R0,#0x00 + STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ + STMDB R12!,{R4-R11} /* Save Old context */ + STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ + + PUSH {R2,R3} + BL rt_stk_check /* Check for Stack overflow */ + POP {R2,R3} + + STR R2,[R3] /* os_tsk.run = os_tsk.new */ + + LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ + LDMIA R12!,{R4-R11} /* Restore New Context */ + LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ + CMP R0,#0 /* Basic/Extended Stack Frame */ + ITTE NE + VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ + MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ + MVNEQ LR,#~0xFFFFFFFD + MSR PSP,R12 /* Write PSP */ + +Sys_Exit: +#ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} +#else + BX LR /* Return to Thread Mode */ +#endif + + +/*-------------------------- SysTick_Handler --------------------------------*/ + +; void SysTick_Handler (void); + + PUBLIC SysTick_Handler +SysTick_Handler: +#ifdef IFX_XMC4XXX + PUBLIC SysTick_Handler_Veneer +SysTick_Handler_Veneer: +#endif + + PUSH {R4,LR} /* Save EXC_RETURN */ + BL rt_systick + B Sys_Switch + + +/*-------------------------- OS_Tick_Handler --------------------------------*/ + +; void OS_Tick_Handler (void); + + PUBLIC OS_Tick_Handler +OS_Tick_Handler: + + PUSH {R4,LR} /* Save EXC_RETURN */ + BL os_tick_irqack + BL rt_systick + B Sys_Switch + + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_IAR/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_IAR/SVC_Table.S new file mode 100644 index 0000000..18710cb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/TARGET_M4/TOOLCHAIN_IAR/SVC_Table.S @@ -0,0 +1,58 @@ +;/*---------------------------------------------------------------------------- +; * CMSIS-RTOS - RTX +; *---------------------------------------------------------------------------- +; * Name: SVC_TABLE.S +; * Purpose: Pre-defined SVC Table for Cortex-M +; * Rev.: V4.70 +; *---------------------------------------------------------------------------- +; * +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH +; * All rights reserved. +; * Redistribution and use in source and binary forms, with or without +; * modification, are permitted provided that the following conditions are met: +; * - Redistributions of source code must retain the above copyright +; * notice, this list of conditions and the following disclaimer. +; * - Redistributions in binary form must reproduce the above copyright +; * notice, this list of conditions and the following disclaimer in the +; * documentation and/or other materials provided with the distribution. +; * - Neither the name of ARM 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. +; *---------------------------------------------------------------------------*/ + + + NAME SVC_TABLE + SECTION .text:CONST (2) + + PUBLIC SVC_Count + +SVC_Cnt EQU (SVC_End-SVC_Table)/4 +SVC_Count DCD SVC_Cnt + +; Import user SVC functions here. +; IMPORT __SVC_1 + + PUBLIC SVC_Table +SVC_Table +; Insert user SVC functions here. SVC 0 used by RTL Kernel. +; DCD __SVC_1 ; user SVC function + +SVC_End + + END + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c b/rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c new file mode 100644 index 0000000..381c21b --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c @@ -0,0 +1,1985 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: rt_CMSIS.c + * Purpose: CMSIS RTOS API + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 __CMSIS_GENERIC + +#include "cmsis.h" + +#include "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Time.h" +#include "rt_Mutex.h" +#include "rt_Semaphore.h" +#include "rt_Mailbox.h" +#include "rt_MemBox.h" +#include "rt_HAL_CM.h" + +#define os_thread_cb OS_TCB + +#include "cmsis_os.h" + +#if (osFeature_Signals != 16) +#error Invalid "osFeature_Signals" value! +#endif +#if (osFeature_Semaphore > 65535) +#error Invalid "osFeature_Semaphore" value! +#endif +#if (osFeature_Wait != 0) +#error osWait not supported! +#endif + +// OS_API_IN_INTLOCK can be enabled in target.mk by: +// export OS_API_IN_INTLOCK ?= 1 + +#ifdef OS_API_IN_INTLOCK +// CAUTION: +// It will be treated as in ISR when calling OS APIs in intlock(), but +// the stack might still be using PSP instead of MSP. +#define IN_ISR() (__get_IPSR() != 0 || __get_PRIMASK() != 0) +#else +#define IN_ISR() (__get_IPSR() != 0) +#endif + +// ==== Enumeration, structures, defines ==== + +// Service Calls defines + +#if defined (__CC_ARM) /* ARM Compiler */ + +#define __NO_RETURN __declspec(noreturn) + +#define osEvent_type osEvent +#define osEvent_ret_status ret +#define osEvent_ret_value ret +#define osEvent_ret_msg ret +#define osEvent_ret_mail ret + +#define osCallback_type osCallback +#define osCallback_ret ret + +#define SVC_0_1(f,t,...) \ +__svc_indirect(0) t _##f (t(*)()); \ + t f (void); \ +__attribute__((always_inline)) \ +static __inline t __##f (void) { \ + return _##f(f); \ +} + +#define SVC_1_1(f,t,t1,...) \ +__svc_indirect(0) t _##f (t(*)(t1),t1); \ + t f (t1 a1); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1) { \ + return _##f(f,a1); \ +} + +#define SVC_2_1(f,t,t1,t2,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \ + t f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2) { \ + return _##f(f,a1,a2); \ +} + +#define SVC_3_1(f,t,t1,t2,t3,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \ + t f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2, t3 a3) { \ + return _##f(f,a1,a2,a3); \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ +__svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ + t f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + return _##f(f,a1,a2,a3,a4); \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#elif defined (__GNUC__) /* GNU Compiler */ + +//#define __NO_RETURN __attribute__((noreturn)) + +typedef uint32_t __attribute__((vector_size(8))) ret64; +typedef uint32_t __attribute__((vector_size(16))) ret128; + +#define RET_pointer __r0 +#define RET_int32_t __r0 +#define RET_osStatus __r0 +#define RET_osPriority __r0 +#define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}} +#define RET_osCallback {(void *)__r0, (void *)__r1} + +#define osEvent_type __attribute__((pcs("aapcs"))) ret128 +#define osEvent_ret_status (ret128){ret.status} +#define osEvent_ret_value (ret128){ret.status, ret.value.v} +#define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id} +#define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id} + +#define osCallback_type __attribute__((pcs("aapcs"))) ret64 +#define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg} + +#define SVC_ArgN(n) \ + register int __r##n __asm("r"#n); + +#define SVC_ArgR(n,t,a) \ + register t __r##n __asm("r"#n) = a; + +#define SVC_Arg0() \ + SVC_ArgN(0) \ + SVC_ArgN(1) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg1(t1) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgN(1) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg2(t1,t2) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgN(2) \ + SVC_ArgN(3) + +#define SVC_Arg3(t1,t2,t3) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgR(2,t3,a3) \ + SVC_ArgN(3) + +#define SVC_Arg4(t1,t2,t3,t4) \ + SVC_ArgR(0,t1,a1) \ + SVC_ArgR(1,t2,a2) \ + SVC_ArgR(2,t3,a3) \ + SVC_ArgR(3,t4,a4) + +#if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS) +#define SVC_Call(f) \ + __asm volatile \ + ( \ + "ldr r7,="#f"\n\t" \ + "mov r12,r7\n\t" \ + "svc 0" \ + : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ + : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ + : "r7", "r12", "lr", "cc" \ + ); +#else +#define SVC_Call(f) \ + __asm volatile \ + ( \ + "ldr r12,="#f"\n\t" \ + "svc 0" \ + : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ + : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ + : "r12", "lr", "cc" \ + ); +#endif + +#define SVC_0_1(f,t,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (void) { \ + SVC_Arg0(); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_1_1(f,t,t1,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1) { \ + SVC_Arg1(t1); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_2_1(f,t,t1,t2,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2) { \ + SVC_Arg2(t1,t2); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_3_1(f,t,t1,t2,t3,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Arg3(t1,t2,t3); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,rv) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Arg4(t1,t2,t3,t4); \ + SVC_Call(f); \ + return (t) rv; \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#define __NO_RETURN __noreturn + +#define osEvent_type osEvent +#define osEvent_ret_status ret +#define osEvent_ret_value ret +#define osEvent_ret_msg ret +#define osEvent_ret_mail ret + +#define osCallback_type osCallback +#define osCallback_ret ret + +#define RET_osEvent osEvent +#define RET_osCallback osCallback + +#define SVC_Setup(f) \ + __asm( \ + "mov r12,%0\n" \ + :: "r"(&f): "r12" \ + ); + + +#define SVC_0_1(f,t,...) \ +t f (void); \ +_Pragma("swi_number=0") __swi t _##f (void); \ +static inline t __##f (void) { \ + SVC_Setup(f); \ + return _##f(); \ +} + +#define SVC_1_1(f,t,t1,...) \ +t f (t1 a1); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + SVC_Setup(f); \ + return _##f(a1); \ +} + +#define SVC_2_1(f,t,t1,t2,...) \ +t f (t1 a1, t2 a2); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \ +static inline t __##f (t1 a1, t2 a2) { \ + SVC_Setup(f); \ + return _##f(a1,a2); \ +} + +#define SVC_3_1(f,t,t1,t2,t3,...) \ +t f (t1 a1, t2 a2, t3 a3); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \ +static inline t __##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Setup(f); \ + return _##f(a1,a2,a3); \ +} + +#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ +t f (t1 a1, t2 a2, t3 a3, t4 a4); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Setup(f); \ + return _##f(a1,a2,a3,a4); \ +} + +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 + +#endif + + +// Callback structure +typedef struct { + void *fp; // Function pointer + void *arg; // Function argument +} osCallback; + + +// OS Section definitions +#ifdef OS_SECTIONS_LINK_INFO +extern const uint32_t os_section_id$$Base; +extern const uint32_t os_section_id$$Limit; +#endif + +// OS Timers external resources +extern osThreadDef_t os_thread_def_osTimerThread; +extern osThreadId osThreadId_osTimerThread; +extern osMessageQDef_t os_messageQ_def_osTimerMessageQ; +extern osMessageQId osMessageQId_osTimerMessageQ; + + +// ==== Helper Functions ==== + +/// Convert timeout in millisec to system ticks +static uint32_t rt_ms2tick (uint32_t millisec) { + uint32_t tick; + + if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout + if (millisec > 4000000) return 0xFFFE; // Max ticks supported + + tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate; + if (tick > 0xFFFE) return 0xFFFE; + + return tick; +} + +/// Convert Thread ID to TCB pointer +static P_TCB rt_tid2ptcb (osThreadId thread_id) { + P_TCB ptcb; + + if (thread_id == NULL) return NULL; + + if ((uint32_t)thread_id & 3) return NULL; + +#ifdef OS_SECTIONS_LINK_INFO + if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { + if (thread_id < (osThreadId)os_section_id$$Base) return NULL; + if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL; + } +#endif + + ptcb = thread_id; + + if (ptcb->cb_type != TCB) return NULL; + + return ptcb; +} + +/// Convert ID pointer to Object pointer +static void *rt_id2obj (void *id) { + + if ((uint32_t)id & 3) return NULL; + +#ifdef OS_SECTIONS_LINK_INFO + if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { + if (id < (void *)os_section_id$$Base) return NULL; + if (id >= (void *)os_section_id$$Limit) return NULL; + } +#endif + + return id; +} + + +// ==== Kernel Control ==== + +uint8_t os_initialized; // Kernel Initialized flag +uint8_t os_running; // Kernel Running flag + +// Kernel Control Service Calls declarations +SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus) +SVC_0_1(svcKernelStart, osStatus, RET_osStatus) +SVC_0_1(svcKernelRunning, int32_t, RET_int32_t) + +extern void sysThreadError (osStatus status); +osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument); +osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +// Kernel Control Service Calls + +/// Initialize the RTOS Kernel for creating objects +osStatus svcKernelInitialize (void) { + if (os_initialized) return osOK; + + rt_sys_init(); // RTX System Initialization + os_tsk.run->prio = 255; // Highest priority + + sysThreadError(osOK); + + os_initialized = 1; + + return osOK; +} + +/// Start the RTOS Kernel +osStatus svcKernelStart (void) { + + if (os_running) return osOK; + + // Create OS Timers resources (Message Queue & Thread) + osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); + osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL); + + rt_tsk_prio(0, 0); // Lowest priority +#ifdef __ARM_ARCH_8M_MAIN__ + __set_PSPLIM((uint32_t)os_tsk.run->stack); +#endif + __set_PSP(os_tsk.run->tsk_stack + 8*4); // New context + os_tsk.run = NULL; // Force context switch + + rt_sys_start(); + + os_running = 1; + + return osOK; +} + +/// Check if the RTOS kernel is already started +int32_t svcKernelRunning(void) { + return os_running; +} + +// Kernel Control Public API + +/// Initialize the RTOS Kernel for creating objects +osStatus osKernelInitialize (void) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if ((__get_CONTROL() & 1) == 0) { // Privileged mode + return svcKernelInitialize(); + } else { + return __svcKernelInitialize(); + } +} + +/// Start the RTOS Kernel +osStatus osKernelStart (void) { + uint32_t stack[8]; + + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + switch (__get_CONTROL() & 0x03) { + case 0x00: // Privileged Thread mode & MSP +#ifdef __ARM_ARCH_8M_MAIN__ + __set_PSPLIM(__get_MSPLIM()); +#endif + __set_PSP((uint32_t)(stack + 8)); // Initial PSP + if (os_flags & 1) { + __set_CONTROL(0x02); // Set Privileged Thread mode & PSP + } else { + __set_CONTROL(0x03); // Set Unprivileged Thread mode & PSP + } + __DSB(); + __ISB(); + break; + case 0x01: // Unprivileged Thread mode & MSP + return osErrorOS; + case 0x02: // Privileged Thread mode & PSP + if ((os_flags & 1) == 0) { // Unprivileged Thread mode requested + __set_CONTROL(0x03); // Set Unprivileged Thread mode & PSP + __DSB(); + __ISB(); + } + break; + case 0x03: // Unprivileged Thread mode & PSP + if (os_flags & 1) return osErrorOS; // Privileged Thread mode requested + break; + } + return __svcKernelStart(); +} + +/// Check if the RTOS kernel is already started +int32_t osKernelRunning(void) { + if ((IN_ISR()) || ((__get_CONTROL() & 1) == 0)) { + // in ISR or Privileged + return os_running; + } else { + return __svcKernelRunning(); + } +} + + +// ==== Thread Management ==== + +__NO_RETURN void osThreadExit (void); + +// Thread Service Calls declarations +SVC_2_1(svcThreadCreate, osThreadId, osThreadDef_t *, void *, RET_pointer) +SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) +SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) +SVC_0_1(svcThreadYield, osStatus, RET_osStatus) +SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) +SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) +SVC_1_1(svcThreadShow, osStatus, osThreadId, RET_osStatus) +SVC_3_1(svcThreadSetHungCheck,osStatus, osThreadId, int32_t, uint32_t, RET_osStatus) + +// Thread Service Calls +extern OS_TID rt_get_TID (void); +extern void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body); + +/// Create a thread and add it to Active Threads and set it to state READY +osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument) { + P_TCB ptcb; + + if ((thread_def == NULL) || + (thread_def->pthread == NULL) || + (thread_def->tpriority < osPriorityIdle) || + (thread_def->tpriority > osPriorityRealtime) || + (thread_def->stacksize == 0) || + (thread_def->stack_pointer == NULL) ) { + sysThreadError(osErrorParameter); + return NULL; + } + + U8 priority = thread_def->tpriority - osPriorityIdle + 1; + P_TCB task_context = &thread_def->tcb; + + /* Utilize the user provided stack. */ + task_context->stack = (U32*)thread_def->stack_pointer; + task_context->priv_stack = thread_def->stacksize; + /* Find a free entry in 'os_active_TCB' table. */ + OS_TID tsk = rt_get_TID (); + if (tsk == 0) { + sysThreadError(osErrorResource); + return NULL; + } + os_active_TCB[tsk-1] = task_context; + task_context->task_id = tsk; + /* Pass parameter 'argv' to 'rt_init_context' */ + task_context->msg = argument; +#if __RTX_CPU_STATISTICS__ + task_context->name = (U8 *)thread_def->name_str; +#endif + /* Initialize thread context structure, including the thread's stack. */ + rt_init_context (task_context, priority, (FUNCP)thread_def->pthread); + + /* Dispatch this task to the scheduler for execution. */ + DBG_TASK_NOTIFY(task_context, __TRUE); + rt_dispatch (task_context); + + ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer + + *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit; + + return ptcb; +} + +/// Return the thread ID of the current running thread +osThreadId svcThreadGetId (void) { + OS_TID tsk; + + tsk = rt_tsk_self(); + if (tsk == 0) return NULL; + return (P_TCB)os_active_TCB[tsk - 1]; +} + +/// Terminate execution of a thread and remove it from ActiveThreads +osStatus svcThreadTerminate (osThreadId thread_id) { + OS_RESULT res; + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + res = rt_tsk_delete(ptcb->task_id); // Delete task + + if (res == OS_R_NOK) return osErrorResource; // Delete task failed + + return osOK; +} + +/// Pass control to next thread that is in state READY +osStatus svcThreadYield (void) { + rt_tsk_pass(); // Pass control to next task + return osOK; +} + +/// Change priority of an active thread +osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) { + OS_RESULT res; + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) { + return osErrorValue; + } + + res = rt_tsk_prio( // Change task priority + ptcb->task_id, // Task ID + priority - osPriorityIdle + 1 // New task priority + ); + + if (res == OS_R_NOK) return osErrorResource; // Change task priority failed + + return osOK; +} + +/// Get current priority of an active thread +osPriority svcThreadGetPriority (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osPriorityError; + + return (osPriority)(ptcb->prio - 1 + osPriorityIdle); +} + +/// Show a thread +osStatus svcThreadShow (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + rt_tsk_show(ptcb); + + return osOK; +} + + +// Thread Public API + +/// Create a thread and add it to Active Threads and set it to state READY +osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcThreadCreate(thread_def, argument); + } else { + return __svcThreadCreate(thread_def, argument); + } +} + +/// Return the thread ID of the current running thread +osThreadId osThreadGetId (void) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + return __svcThreadGetId(); +} + +int osGetThreadIntId (void) { + OS_TID tid; + uint32_t lock; + + if (__get_IPSR() != 0) return 0; + lock = int_lock(); + tid = rt_tsk_self(); + int_unlock(lock); + return tid; +} + +/// Terminate execution of a thread and remove it from ActiveThreads +osStatus osThreadTerminate (osThreadId thread_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcThreadTerminate(thread_id); +} + +/// Pass control to next thread that is in state READY +osStatus osThreadYield (void) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcThreadYield(); +} + +/// Change priority of an active thread +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcThreadSetPriority(thread_id, priority); +} + +/// Get current priority of an active thread +osPriority osThreadGetPriority (osThreadId thread_id) { + if (__get_IPSR() != 0) return osPriorityError;// Not allowed in ISR + return __svcThreadGetPriority(thread_id); +} + +/// Dump a thread +osStatus osThreadShow (osThreadId thread_id) { + if (__get_IPSR() != 0) return osPriorityError;// Not allowed in ISR + return __svcThreadShow(thread_id); +} + +/// INTERNAL - Not Public +/// Auto Terminate Thread on exit (used implicitly when thread exists) +__NO_RETURN void osThreadExit (void) { + __svcThreadTerminate(__svcThreadGetId()); + for (;;); // Should never come here +} + + +// ==== Generic Wait Functions ==== + +// Generic Wait Service Calls declarations +SVC_1_1(svcDelay, osStatus, uint32_t, RET_osStatus) +#if osFeature_Wait != 0 +SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent) +#endif + +// Generic Wait Service Calls + +/// Wait for Timeout (Time Delay) +osStatus svcDelay (uint32_t millisec) { + if (millisec == 0) return osOK; + rt_dly_wait(rt_ms2tick(millisec)); + return osEventTimeout; +} + +/// Wait for Signal, Message, Mail, or Timeout +#if osFeature_Wait != 0 +os_InRegs osEvent_type svcWait (uint32_t millisec) { + osEvent ret; + + if (millisec == 0) { + ret.status = osOK; + return osEvent_ret_status; + } + + /* To Do: osEventSignal, osEventMessage, osEventMail */ + rt_dly_wait(rt_ms2tick(millisec)); + ret.status = osEventTimeout; + + return osEvent_ret_status; +} +#endif + + +// Generic Wait API + +/// Wait for Timeout (Time Delay) +osStatus osDelay (uint32_t millisec) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcDelay(millisec); +} + +/// Wait for Signal, Message, Mail, or Timeout +os_InRegs osEvent osWait (uint32_t millisec) { + osEvent ret; + +#if osFeature_Wait == 0 + ret.status = osErrorOS; + return ret; +#else + if (__get_IPSR() != 0) { // Not allowed in ISR + ret.status = osErrorISR; + return ret; + } + return __svcWait(millisec); +#endif +} + + +// ==== Timer Management ==== + +// Timer definitions +#define osTimerInvalid 0 +#define osTimerStopped 1 +#define osTimerRunning 2 + +// Timer structures + +typedef struct os_timer_cb_ { // Timer Control Block + struct os_timer_cb_ *next; // Pointer to next active Timer + uint8_t state; // Timer State + uint8_t type; // Timer Type (Periodic/One-shot) + uint16_t reserved; // Reserved + uint16_t tcnt; // Timer Delay Count + uint16_t icnt; // Timer Initial Count + void *arg; // Timer Function Argument + const osTimerDef_t *timer; // Pointer to Timer definition +} os_timer_cb; + +// Timer variables +os_timer_cb *os_timer_head; // Pointer to first active Timer + + +// Timer Helper Functions + +// Insert Timer into the list sorted by time +static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) { + os_timer_cb *p, *prev; + + prev = NULL; + p = os_timer_head; + while (p != NULL) { + if (tcnt < p->tcnt) break; + tcnt -= p->tcnt; + prev = p; + p = p->next; + } + pt->next = p; + pt->tcnt = (uint16_t)tcnt; + if (p != NULL) { + p->tcnt -= pt->tcnt; + } + if (prev != NULL) { + prev->next = pt; + } else { + os_timer_head = pt; + } +} + +// Remove Timer from the list +static int32_t rt_timer_remove (os_timer_cb *pt) { + os_timer_cb *p, *prev; + + prev = NULL; + p = os_timer_head; + while (p != NULL) { + if (p == pt) break; + prev = p; + p = p->next; + } + if (p == NULL) return -1; + if (prev != NULL) { + prev->next = pt->next; + } else { + os_timer_head = pt->next; + } + if (pt->next != NULL) { + pt->next->tcnt += pt->tcnt; + } + + return 0; +} + + +// Timer Service Calls declarations +SVC_3_1(svcTimerCreate, osTimerId, const osTimerDef_t *, os_timer_type, void *, RET_pointer) +SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus) +SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus) +SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus) +SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback) + +// Timer Management Service Calls + +/// Create timer +osTimerId svcTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { + os_timer_cb *pt; + + if ((timer_def == NULL) || (timer_def->ptimer == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + pt = timer_def->timer; + if (pt == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if ((type != osTimerOnce) && (type != osTimerPeriodic)) { + sysThreadError(osErrorValue); + return NULL; + } + + if (osThreadId_osTimerThread == NULL) { + sysThreadError(osErrorResource); + return NULL; + } + + if (pt->state != osTimerInvalid){ + sysThreadError(osErrorResource); + return NULL; + } + + pt->next = NULL; + pt->state = osTimerStopped; + pt->type = (uint8_t)type; + pt->arg = argument; + pt->timer = timer_def; + + return (osTimerId)pt; +} + +/// Start or restart timer +osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) { + os_timer_cb *pt; + uint32_t tcnt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + tcnt = rt_ms2tick(millisec); + if (tcnt == 0) return osErrorValue; + + switch (pt->state) { + case osTimerRunning: + if (rt_timer_remove(pt) != 0) { + return osErrorResource; + } + break; + case osTimerStopped: + pt->state = osTimerRunning; + pt->icnt = (uint16_t)tcnt; + break; + default: + return osErrorResource; + } + + rt_timer_insert(pt, tcnt); + + return osOK; +} + +/// Stop timer +osStatus svcTimerStop (osTimerId timer_id) { + os_timer_cb *pt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + if (pt->state != osTimerRunning) return osErrorResource; + + pt->state = osTimerStopped; + + if (rt_timer_remove(pt) != 0) { + return osErrorResource; + } + + return osOK; +} + +/// Delete timer +osStatus svcTimerDelete (osTimerId timer_id) { + os_timer_cb *pt; + + pt = rt_id2obj(timer_id); + if (pt == NULL) return osErrorParameter; + + switch (pt->state) { + case osTimerRunning: + rt_timer_remove(pt); + break; + case osTimerStopped: + break; + default: + return osErrorResource; + } + + pt->state = osTimerInvalid; + + return osOK; +} + +/// Get timer callback parameters +os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) { + os_timer_cb *pt; + osCallback ret; + + pt = rt_id2obj(timer_id); + if (pt == NULL) { + ret.fp = NULL; + ret.arg = NULL; + return osCallback_ret; + } + + ret.fp = (void *)pt->timer->ptimer; + ret.arg = pt->arg; + + return osCallback_ret; +} + +static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Timer Tick (called each SysTick) +void sysTimerTick (void) { + os_timer_cb *pt, *p; + osStatus status; + + p = os_timer_head; + if (p == NULL) return; + + p->tcnt--; + while ((p != NULL) && (p->tcnt == 0)) { + pt = p; + p = p->next; + os_timer_head = p; + status = isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0U); + if (status != osOK) { + os_error(OS_ERR_TIMER_OVF); + } + if (pt->type == (uint8_t)osTimerPeriodic) { + rt_timer_insert(pt, pt->icnt); + } else { + pt->state = osTimerStopped; + } + } +} + +uint32_t rt_timer_delay_count(void) +{ + if (os_timer_head) { + return os_timer_head->tcnt; + } + return 0; +} + +// Timer Management Public API + +/// Create timer +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcTimerCreate(timer_def, type, argument); + } else { + return __svcTimerCreate(timer_def, type, argument); + } +} + +/// Start or restart timer +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcTimerStart(timer_id, millisec); +} + +/// Stop timer +osStatus osTimerStop (osTimerId timer_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcTimerStop(timer_id); +} + +/// Delete timer +osStatus osTimerDelete (osTimerId timer_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcTimerDelete(timer_id); +} + +/// INTERNAL - Not Public +/// Get timer callback parameters (used by OS Timer Thread) +os_InRegs osCallback osTimerCall (osTimerId timer_id) { + return __svcTimerCall(timer_id); +} + + +// Timer Thread +__NO_RETURN void osTimerThread (void const *argument) { + osCallback cb; + osEvent evt; + + for (;;) { + evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever); + if (evt.status == osEventMessage) { + cb = osTimerCall(evt.value.p); + if (cb.fp != NULL) { + (*(os_ptimer)cb.fp)(cb.arg); + } + } + } +} + + +// ==== Signal Management ==== + +// Signal Service Calls declarations +SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t) +SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t) +SVC_1_1(svcSignalGet, int32_t, osThreadId, RET_int32_t) +SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent) + +// Signal Service Calls + +/// Set the specified Signal Flags of an active thread +int32_t svcSignalSet (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + rt_evt_set(signals, ptcb->task_id); // Set event flags + + return sig; +} + +/// Clear the specified Signal Flags of an active thread +int32_t svcSignalClear (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + rt_evt_clr(signals, ptcb->task_id); // Clear event flags + + return sig; +} + +/// Get Signal Flags status of an active thread +int32_t svcSignalGet (osThreadId thread_id) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + return ptcb->events; // Return event flags +} + +/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread +os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) { + ret.status = osErrorValue; + return osEvent_ret_status; + } + + if (signals != 0) { // Wait for all specified signals + res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE); + } else { // Wait for any signal + res = rt_evt_wait(0xFFFF, rt_ms2tick(millisec), __FALSE); + } + + if (res == OS_R_EVT) { + ret.status = osEventSignal; + ret.value.signals = signals ? signals : os_tsk.run->waits; + } else { + ret.status = millisec ? osEventTimeout : osOK; + ret.value.signals = 0; + } + + return osEvent_ret_value; +} + + +// Signal ISR Calls + +/// Set the specified Signal Flags of an active thread +static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { + P_TCB ptcb; + int32_t sig; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return 0x80000000; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + + sig = ptcb->events; // Previous signal flags + + isr_evt_set(signals, ptcb->task_id); // Set event flags + + return sig; +} + + +// Signal Public API + +/// Set the specified Signal Flags of an active thread +int32_t osSignalSet (osThreadId thread_id, int32_t signals) { + if (IN_ISR()) { // in ISR + return isrSignalSet(thread_id, signals); + } else { // in Thread + return __svcSignalSet(thread_id, signals); + } +} + +/// Clear the specified Signal Flags of an active thread +int32_t osSignalClear (osThreadId thread_id, int32_t signals) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcSignalClear(thread_id, signals); +} + +/// Get Signal Flags status of an active thread +int32_t osSignalGet (osThreadId thread_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcSignalGet(thread_id); +} + +/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) { + osEvent ret; + + if (__get_IPSR() != 0) { // Not allowed in ISR + ret.status = osErrorISR; + return ret; + } + return __svcSignalWait(signals, millisec); +} + + +// ==== Mutex Management ==== + +// Mutex Service Calls declarations +SVC_1_1(svcMutexCreate, osMutexId, const osMutexDef_t *, RET_pointer) +SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus) +SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus) +SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus) +SVC_1_1(svcMutexGetOwner, osThreadId, osMutexId, RET_pointer) + +// Mutex Service Calls + +/// Create and Initialize a Mutex object +osMutexId svcMutexCreate (const osMutexDef_t *mutex_def) { + OS_ID mut; + + if (mutex_def == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + mut = mutex_def->mutex; + if (mut == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_MUCB)mut)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + rt_mut_init(mut); // Initialize Mutex + + return mut; +} + +/// Wait until a Mutex becomes available +osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) { + OS_ID mut; + OS_RESULT res; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex + + if (res == OS_R_TMO) { + return (millisec ? osErrorTimeoutResource : osErrorResource); + } + if (res == OS_R_NOK) { + return osErrorResource; + } + + return osOK; +} + +/// Release a Mutex that was obtained with osMutexWait +osStatus svcMutexRelease (osMutexId mutex_id) { + OS_ID mut; + OS_RESULT res; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + res = rt_mut_release(mut); // Release Mutex + + if (res == OS_R_NOK) return osErrorResource; // Thread not owner or Zero Counter + + return osOK; +} + +/// Delete a Mutex that was created by osMutexCreate +osStatus svcMutexDelete (osMutexId mutex_id) { + OS_ID mut; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return osErrorParameter; + + if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + + rt_mut_delete(mut); // Release Mutex + + return osOK; +} + +/// Get owner thread of a Mutex object. +osThreadId svcMutexGetOwner (osMutexId mutex_id) { + OS_ID mut; + + mut = rt_id2obj(mutex_id); + if (mut == NULL) return NULL; + + if (((P_MUCB)mut)->cb_type != MUCB) return NULL; + + return (osThreadId)(((P_MUCB)mut)->owner); +} + + +// Mutex Public API + +/// Create and Initialize a Mutex object +osMutexId osMutexCreate (const osMutexDef_t *mutex_def) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcMutexCreate(mutex_def); + } else { + return __svcMutexCreate(mutex_def); + } +} + +/// Wait until a Mutex becomes available +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcMutexWait(mutex_id, millisec); +} + +/// Release a Mutex that was obtained with osMutexWait +osStatus osMutexRelease (osMutexId mutex_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcMutexRelease(mutex_id); +} + +/// Delete a Mutex that was created by osMutexCreate +osStatus osMutexDelete (osMutexId mutex_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcMutexDelete(mutex_id); +} + +/// Get owner thread of a Mutex object. +osThreadId osMutexGetOwner (osMutexId mutex_id) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + return __svcMutexGetOwner(mutex_id); +} + + +// ==== Semaphore Management ==== + +// Semaphore Service Calls declarations +SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer) +SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t) +SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus) +SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus) + +// Semaphore Service Calls + +/// Create and Initialize a Semaphore object +osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + OS_ID sem; + + if (semaphore_def == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + sem = semaphore_def->semaphore; + if (sem == NULL) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_SCB)sem)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (count > osFeature_Semaphore) { + sysThreadError(osErrorValue); + return NULL; + } + + rt_sem_init(sem, count); // Initialize Semaphore + + return sem; +} + +/// Wait until a Semaphore becomes available +int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + OS_ID sem; + OS_RESULT res; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return -1; + + if (((P_SCB)sem)->cb_type != SCB) return -1; + + res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore + + if (res == OS_R_TMO) return 0; // Timeout + + return (((P_SCB)sem)->tokens + 1); +} + +/// Release a Semaphore +osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + + rt_sem_send(sem); // Release Semaphore + + return osOK; +} + +/// Delete a Semaphore that was created by osSemaphoreCreate +osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + rt_sem_delete(sem); // Delete Semaphore + + return osOK; +} + + +// Semaphore ISR Calls + +/// Release a Semaphore +static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { + OS_ID sem; + + sem = rt_id2obj(semaphore_id); + if (sem == NULL) return osErrorParameter; + + if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + + if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + + isr_sem_send(sem); // Release Semaphore + + return osOK; +} + + +// Semaphore Public API + +/// Create and Initialize a Semaphore object +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcSemaphoreCreate(semaphore_def, count); + } else { + return __svcSemaphoreCreate(semaphore_def, count); + } +} + +/// Wait until a Semaphore becomes available +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + if (__get_IPSR() != 0) return -1; // Not allowed in ISR + return __svcSemaphoreWait(semaphore_id, millisec); +} + +/// Release a Semaphore +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) { + if (IN_ISR()) { // in ISR + return isrSemaphoreRelease(semaphore_id); + } else { // in Thread + return __svcSemaphoreRelease(semaphore_id); + } +} + +/// Delete a Semaphore that was created by osSemaphoreCreate +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcSemaphoreDelete(semaphore_id); +} + + +// ==== Memory Management Functions ==== + +// Memory Management Helper Functions + +// Clear Memory Box (Zero init) +static void rt_clr_box (void *box_mem, void *box) { + uint32_t *p, n; + + if ((box_mem != NULL) && (box != NULL)) { + p = box; + for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) { + *p++ = 0; + } + } +} + +// Memory Management Service Calls declarations +SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer) +SVC_2_1(sysPoolAlloc, void *, osPoolId, uint32_t, RET_pointer) +SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus) + +// Memory Management Service & ISR Calls + +/// Create and Initialize memory pool +osPoolId svcPoolCreate (const osPoolDef_t *pool_def) { + uint32_t blk_sz; + + if ((pool_def == NULL) || + (pool_def->pool_sz == 0) || + (pool_def->item_sz == 0) || + (pool_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + blk_sz = (pool_def->item_sz + 3) & ~3; + + _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz); + + return pool_def->pool; +} + +/// Allocate a memory block from a memory pool +void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) { + void *ptr; + + if (pool_id == NULL) return NULL; + + ptr = rt_alloc_box(pool_id); + if (clr) { + rt_clr_box(pool_id, ptr); + } + + return ptr; +} + +/// Return an allocated memory block back to a specific memory pool +osStatus sysPoolFree (osPoolId pool_id, void *block) { + int32_t res; + + if (pool_id == NULL) return osErrorParameter; + + res = rt_free_box(pool_id, block); + if (res != 0) return osErrorValue; + + return osOK; +} + + +// Memory Management Public API + +/// Create and Initialize memory pool +osPoolId osPoolCreate (const osPoolDef_t *pool_def) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcPoolCreate(pool_def); + } else { + return __svcPoolCreate(pool_def); + } +} + +/// Allocate a memory block from a memory pool +void *osPoolAlloc (osPoolId pool_id) { + if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged + return sysPoolAlloc(pool_id, 0); + } else { // in Thread + return __sysPoolAlloc(pool_id, 0); + } +} + +/// Allocate a memory block from a memory pool and set memory block to zero +void *osPoolCAlloc (osPoolId pool_id) { + if ((IN_ISR()) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged + return sysPoolAlloc(pool_id, 1); + } else { // in Thread + return __sysPoolAlloc(pool_id, 1); + } +} + +/// Return an allocated memory block back to a specific memory pool +osStatus osPoolFree (osPoolId pool_id, void *block) { + if ((IN_ISR()) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged + return sysPoolFree(pool_id, block); + } else { // in Thread + return __sysPoolFree(pool_id, block); + } +} + + +// ==== Message Queue Management Functions ==== + +// Message Queue Management Service Calls declarations +SVC_2_1(svcMessageCreate, osMessageQId, const osMessageQDef_t *, osThreadId, RET_pointer) +SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus) +SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent) + +// Message Queue Service Calls + +/// Create and Initialize Message Queue +osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { + + if ((queue_def == NULL) || + (queue_def->queue_sz == 0) || + (queue_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + if (((P_MCB)queue_def->pool)->cb_type != 0) { + sysThreadError(osErrorParameter); + return NULL; + } + + rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4)); + + return queue_def->pool; +} + +/// Put a Message to a Queue +osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + OS_RESULT res; + + if (queue_id == NULL) return osErrorParameter; + + if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + + res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec)); + + if (res == OS_R_TMO) { + return (millisec ? osErrorTimeoutResource : osErrorResource); + } + + return osOK; +} + +/// Get a Message or Wait for a Message from a Queue +os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if (queue_id == NULL) { + ret.status = osErrorParameter; + return osEvent_ret_status; + } + + if (((P_MCB)queue_id)->cb_type != MCB) { + ret.status = osErrorParameter; + return osEvent_ret_status; + } + + res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec)); + + if (res == OS_R_TMO) { + ret.status = millisec ? osEventTimeout : osOK; + return osEvent_ret_value; + } + + ret.status = osEventMessage; + + return osEvent_ret_value; +} + + +// Message Queue ISR Calls + +/// Put a Message to a Queue +static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + + if ((queue_id == NULL) || (millisec != 0)) { + return osErrorParameter; + } + + if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + + if (rt_mbx_check(queue_id) == 0) { // Check if Queue is full + return osErrorResource; + } + + isr_mbx_send(queue_id, (void *)info); + + return osOK; +} + +/// Get a Message or Wait for a Message from a Queue +static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) { + OS_RESULT res; + osEvent ret; + + if ((queue_id == NULL) || (millisec != 0)) { + ret.status = osErrorParameter; + return ret; + } + + if (((P_MCB)queue_id)->cb_type != MCB) { + ret.status = osErrorParameter; + return ret; + } + + res = isr_mbx_receive(queue_id, &ret.value.p); + + if (res != OS_R_MBX) { + ret.status = osOK; + return ret; + } + + ret.status = osEventMessage; + + return ret; +} + + +// Message Queue Management Public API + +/// Create and Initialize Message Queue +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcMessageCreate(queue_def, thread_id); + } else { + return __svcMessageCreate(queue_def, thread_id); + } +} + +/// Put a Message to a Queue +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + if (IN_ISR()) { // in ISR + return isrMessagePut(queue_id, info, millisec); + } else { // in Thread + return __svcMessagePut(queue_id, info, millisec); + } +} + +/// Get a Message or Wait for a Message from a Queue +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { + if (IN_ISR()) { // in ISR + return isrMessageGet(queue_id, millisec); + } else { // in Thread + return __svcMessageGet(queue_id, millisec); + } +} + + +uint32_t osMessageGetSpace (osMessageQId queue_id) +{ + return rt_mbx_check(queue_id); +} + +// ==== Mail Queue Management Functions ==== + +// Mail Queue Management Service Calls declarations +SVC_2_1(svcMailCreate, osMailQId, const osMailQDef_t *, osThreadId, RET_pointer) +SVC_4_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, uint32_t, RET_pointer) +SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus) + +// Mail Queue Management Service & ISR Calls + +/// Create and Initialize mail queue +osMailQId svcMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { + uint32_t blk_sz; + P_MCB pmcb; + void *pool; + + if ((queue_def == NULL) || + (queue_def->queue_sz == 0) || + (queue_def->item_sz == 0) || + (queue_def->pool == NULL)) { + sysThreadError(osErrorParameter); + return NULL; + } + + pmcb = *(((void **)queue_def->pool) + 0); + pool = *(((void **)queue_def->pool) + 1); + + if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) { + sysThreadError(osErrorParameter); + return NULL; + } + + blk_sz = (queue_def->item_sz + 3) & ~3; + + _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz); + + rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4)); + + + return queue_def->pool; +} + +/// Allocate a memory block from a mail +void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) { + P_MCB pmcb; + void *pool; + void *mem; + + if (queue_id == NULL) return NULL; + + pmcb = *(((void **)queue_id) + 0); + pool = *(((void **)queue_id) + 1); + + if ((pool == NULL) || (pmcb == NULL)) return NULL; + + if (isr && (millisec != 0)) return NULL; + + mem = rt_alloc_box(pool); + if (clr) { + rt_clr_box(pool, mem); + } + + if ((mem == NULL) && (millisec != 0)) { + // Put Task to sleep when Memory not available + if (pmcb->p_lnk != NULL) { + rt_put_prio((P_XCB)pmcb, os_tsk.run); + } else { + pmcb->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)pmcb; + // Task is waiting to allocate a message + pmcb->state = 3; + } + rt_block(rt_ms2tick(millisec), WAIT_MBX); + } + + return mem; +} + +/// Free a memory block from a mail +osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) { + P_MCB pmcb; + P_TCB ptcb; + void *pool; + void *mem; + int32_t res; + + if (queue_id == NULL) return osErrorParameter; + + pmcb = *(((void **)queue_id) + 0); + pool = *(((void **)queue_id) + 1); + + if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter; + + res = rt_free_box(pool, mail); + + if (res != 0) return osErrorValue; + + if ((pmcb->p_lnk != NULL) && (pmcb->state == 3U)) { + // Task is waiting to allocate a message + if (isr) { + rt_psq_enq (pmcb, (U32)pool); + rt_psh_req (); + } else { + mem = rt_alloc_box(pool); + if (mem != NULL) { + ptcb = rt_get_first((P_XCB)pmcb); + rt_ret_val(ptcb, (U32)mem); + rt_rmv_dly(ptcb); + rt_dispatch(ptcb); + } + } + } + + return osOK; +} + + +// Mail Queue Management Public API + +/// Create and Initialize mail queue +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { + if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { + // Privileged and not running + return svcMailCreate(queue_def, thread_id); + } else { + return __svcMailCreate(queue_def, thread_id); + } +} + +/// Allocate a memory block from a mail +void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { + if (IN_ISR()) { // in ISR + return sysMailAlloc(queue_id, millisec, 1, 0); + } else { // in Thread + return __sysMailAlloc(queue_id, millisec, 0, 0); + } +} + +/// Allocate a memory block from a mail and set memory block to zero +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { + if (IN_ISR()) { // in ISR + return sysMailAlloc(queue_id, millisec, 1, 1); + } else { // in Thread + return __sysMailAlloc(queue_id, millisec, 0, 1); + } +} + +/// Free a memory block from a mail +osStatus osMailFree (osMailQId queue_id, void *mail) { + if (IN_ISR()) { // in ISR + return sysMailFree(queue_id, mail, 1); + } else { // in Thread + return __sysMailFree(queue_id, mail, 0); + } +} + +/// Put a mail to a queue +osStatus osMailPut (osMailQId queue_id, void *mail) { + if (queue_id == NULL) return osErrorParameter; + if (mail == NULL) return osErrorValue; + return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0); +} + +#if TASK_HUNG_CHECK_ENABLED +osStatus svcThreadSetHungCheck (osThreadId thread_id, int32_t enable, uint32_t timeout) { + P_TCB ptcb; + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + ptcb->hung_check = !!enable; + ptcb->hung_check_timeout = timeout; + return osOK; +} + +/// enable/disable the hung check feature of an active thread +osStatus osThreadSetHungCheck (osThreadId thread_id, int32_t enable, uint32_t timeout) { + if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + return __svcThreadSetHungCheck(thread_id, enable, timeout); +} +#endif + +#ifdef __CC_ARM +#pragma push +#pragma Ospace +#endif // __arm__ +/// Get a mail from a queue +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { + osEvent ret; + + if (queue_id == NULL) { + ret.status = osErrorParameter; + return ret; + } + + ret = osMessageGet(*((void **)queue_id), millisec); + if (ret.status == osEventMessage) ret.status = osEventMail; + + return ret; +} +#ifdef __CC_ARM +#pragma pop +#endif // __arm__ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Event.c b/rtos/rtx/TARGET_CORTEX_M/rt_Event.c new file mode 100644 index 0000000..acd8ccc --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Event.c @@ -0,0 +1,190 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_EVENT.C + * Purpose: Implements waits and wake-ups for event flags + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_evt_wait -----------------------------------*/ + +OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) { + /* Wait for one or more event flags with optional time-out. */ + /* "wait_flags" identifies the flags to wait for. */ + /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */ + /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */ + /* to complete the wait. (OR-ing if set to 0). */ + U32 block_state; + + if (and_wait) { + /* Check for AND-connected events */ + if ((os_tsk.run->events & wait_flags) == wait_flags) { + os_tsk.run->events &= ~wait_flags; + return (OS_R_EVT); + } + block_state = WAIT_AND; + } + else { + /* Check for OR-connected events */ + if (os_tsk.run->events & wait_flags) { + os_tsk.run->waits = os_tsk.run->events & wait_flags; + os_tsk.run->events &= ~wait_flags; + return (OS_R_EVT); + } + block_state = WAIT_OR; + } + /* Task has to wait */ + os_tsk.run->waits = wait_flags; + rt_block (timeout, (U8)block_state); + return (OS_R_TMO); +} + + +/*--------------------------- rt_evt_set ------------------------------------*/ + +void rt_evt_set (U16 event_flags, OS_TID task_id) { + /* Set one or more event flags of a selectable task. */ + P_TCB p_tcb; + + p_tcb = os_active_TCB[task_id-1]; + if (p_tcb == NULL) { + return; + } + p_tcb->events |= event_flags; + event_flags = p_tcb->waits; + /* If the task is not waiting for an event, it should not be put */ + /* to ready state. */ + if (p_tcb->state == WAIT_AND) { + /* Check for AND-connected events */ + if ((p_tcb->events & event_flags) == event_flags) { + goto wkup; + } + } + if (p_tcb->state == WAIT_OR) { + /* Check for OR-connected events */ + if (p_tcb->events & event_flags) { + p_tcb->waits &= p_tcb->events; +wkup: p_tcb->events &= ~event_flags; + rt_rmv_dly (p_tcb); + p_tcb->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val2(p_tcb, 0x08/*osEventSignal*/, p_tcb->waits); +#else + rt_ret_val (p_tcb, OS_R_EVT); +#endif + rt_dispatch (p_tcb); + } + } +} + + +/*--------------------------- rt_evt_clr ------------------------------------*/ + +void rt_evt_clr (U16 clear_flags, OS_TID task_id) { + /* Clear one or more event flags (identified by "clear_flags") of a */ + /* selectable task (identified by "task"). */ + P_TCB task = os_active_TCB[task_id-1]; + + if (task == NULL) { + return; + } + task->events &= ~clear_flags; +} + + +/*--------------------------- isr_evt_set -----------------------------------*/ + +void isr_evt_set (U16 event_flags, OS_TID task_id) { + /* Same function as "os_evt_set", but to be called by ISRs. */ + P_TCB p_tcb = os_active_TCB[task_id-1]; + + if (p_tcb == NULL) { + return; + } + rt_psq_enq (p_tcb, event_flags); + rt_psh_req (); +} + + +/*--------------------------- rt_evt_get ------------------------------------*/ + +U16 rt_evt_get (void) { + /* Get events of a running task after waiting for OR connected events. */ + return (os_tsk.run->waits); +} + + +/*--------------------------- rt_evt_psh ------------------------------------*/ + +void rt_evt_psh (P_TCB p_CB, U16 set_flags) { + /* Check if task has to be waken up */ + U16 event_flags; + + p_CB->events |= set_flags; + event_flags = p_CB->waits; + if (p_CB->state == WAIT_AND) { + /* Check for AND-connected events */ + if ((p_CB->events & event_flags) == event_flags) { + goto rdy; + } + } + if (p_CB->state == WAIT_OR) { + /* Check for OR-connected events */ + if (p_CB->events & event_flags) { + p_CB->waits &= p_CB->events; +rdy: p_CB->events &= ~event_flags; + rt_rmv_dly (p_CB); + p_CB->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val2(p_CB, 0x08/*osEventSignal*/, p_CB->waits); +#else + rt_ret_val (p_CB, OS_R_EVT); +#endif + rt_put_prio (&os_rdy, p_CB); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Event.h b/rtos/rtx/TARGET_CORTEX_M/rt_Event.h new file mode 100644 index 0000000..8b92f3c --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Event.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_EVENT.H + * Purpose: Implements waits and wake-ups for event flags + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait); +extern void rt_evt_set (U16 event_flags, OS_TID task_id); +extern void rt_evt_clr (U16 clear_flags, OS_TID task_id); +extern void isr_evt_set (U16 event_flags, OS_TID task_id); +extern U16 rt_evt_get (void); +extern void rt_evt_psh (P_TCB p_CB, U16 set_flags); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h b/rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h new file mode 100644 index 0000000..8ffef86 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h @@ -0,0 +1,287 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_HAL_CM.H + * Purpose: Hardware Abstraction Layer for Cortex-M definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Definitions */ +#define INITIAL_xPSR 0x01000000 +#define DEMCR_TRCENA 0x01000000 +#define ITM_ITMENA 0x00000001 +#define MAGIC_WORD 0xE25A2EA5 + +#define SYSTICK_EXTERNAL_CLOCK 1 + +#if defined (__CC_ARM) /* ARM Compiler */ + +#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS) + #define __USE_EXCLUSIVE_ACCESS +#else + #undef __USE_EXCLUSIVE_ACCESS +#endif + +#elif defined (__GNUC__) /* GNU Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if defined (__CORTEX_M0) || defined (__CORTEX_M0PLUS) +#define __TARGET_ARCH_6S_M 1 +#else +#define __TARGET_ARCH_6S_M 0 +#endif + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline +#define __weak __attribute__((weak)) + +#ifndef __CMSIS_GENERIC + +__attribute__((always_inline)) static inline void __enable_irq(void) +{ + __asm volatile ("cpsie i"); +} + +__attribute__((always_inline)) static inline U32 __disable_irq(void) +{ + U32 result; + + __asm volatile ("mrs %0, primask" : "=r" (result)); + __asm volatile ("cpsid i"); + return(result & 1); +} + +#endif + +__attribute__(( always_inline)) static inline U8 __clz(U32 value) +{ + U8 result; + + __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); + return(result); +} + +#elif defined (__ICCARM__) /* IAR Compiler */ + +#undef __USE_EXCLUSIVE_ACCESS + +#if (__CORE__ == __ARM6M__) +#define __TARGET_ARCH_6S_M 1 +#else +#define __TARGET_ARCH_6S_M 0 +#endif + +#if defined __ARMVFP__ +#define __TARGET_FPU_VFP 1 +#else +#define __TARGET_FPU_VFP 0 +#endif + +#define __inline inline + +#ifndef __CMSIS_GENERIC + +static inline void __enable_irq(void) +{ + __asm volatile ("cpsie i"); +} + +static inline U32 __disable_irq(void) +{ + U32 result; + + __asm volatile ("mrs %0, primask" : "=r" (result)); + __asm volatile ("cpsid i"); + return(result & 1); +} + +#endif + +static inline U8 __clz(U32 value) +{ + U8 result; + + __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); + return(result); +} + +#endif + +/* NVIC registers */ +#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010)) +#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014)) +#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018)) +#define NVIC_ISER ((volatile U32 *)0xE000E100) +#define NVIC_ICER ((volatile U32 *)0xE000E180) +#if (__TARGET_ARCH_6S_M) +#define NVIC_IP ((volatile U32 *)0xE000E400) +#else +#define NVIC_IP ((volatile U8 *)0xE000E400) +#endif +#define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04)) +#define NVIC_AIR_CTRL (*((volatile U32 *)0xE000ED0C)) +#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1C)) +#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20)) + +#define OS_PEND_IRQ() NVIC_INT_CTRL = (1<<28) +#define OS_PENDING ((NVIC_INT_CTRL >> 26) & (1<<2 | 1)) +#define OS_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_PENDING) << 25 +#define OS_PEND(fl,p) NVIC_INT_CTRL = (fl | p<<2) << 26 +#if (SYSTICK_EXTERNAL_CLOCK) +#define OS_LOCK() NVIC_ST_CTRL = 0x0001 +#define OS_UNLOCK() NVIC_ST_CTRL = 0x0003 +#else +#define OS_LOCK() NVIC_ST_CTRL = 0x0005 +#define OS_UNLOCK() NVIC_ST_CTRL = 0x0007 +#endif + +#define OS_X_PENDING ((NVIC_INT_CTRL >> 28) & 1) +#define OS_X_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_X_PENDING) << 27 +#define OS_X_PEND(fl,p) NVIC_INT_CTRL = (fl | p) << 28 +#if (__TARGET_ARCH_6S_M) +#define OS_X_INIT(n) NVIC_IP[n>>2] |= 0xFF << (8*(n & 0x03)); \ + NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#else +#define OS_X_INIT(n) NVIC_IP[n] = 0xFF; \ + NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#endif +#define OS_X_LOCK(n) NVIC_ICER[n>>5] = 1 << (n & 0x1F) +#define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = 1 << (n & 0x1F) + +/* Core Debug registers */ +#define DEMCR (*((volatile U32 *)0xE000EDFC)) + +/* ITM registers */ +#define ITM_CONTROL (*((volatile U32 *)0xE0000E80)) +#define ITM_ENABLE (*((volatile U32 *)0xE0000E00)) +#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078)) +#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007C)) +#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007C)) +#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007C)) + +/* Variables */ +extern BIT dbg_msg; + +/* Functions */ +#ifdef __USE_EXCLUSIVE_ACCESS + #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) + #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) +#else + #define rt_inc(p) __disable_irq();(*p)++;__enable_irq(); + #define rt_dec(p) __disable_irq();(*p)--;__enable_irq(); +#endif + +__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { + U32 cnt,c2; +#ifdef __USE_EXCLUSIVE_ACCESS + do { + if ((cnt = __ldrex(count)) == size) { + __clrex(); + return (cnt); } + } while (__strex(cnt+1, count)); + do { + c2 = (cnt = __ldrex(first)) + 1; + if (c2 == size) c2 = 0; + } while (__strex(c2, first)); +#else + __disable_irq(); + if ((cnt = *count) < size) { + *count = cnt+1; + c2 = (cnt = *first) + 1; + if (c2 == size) c2 = 0; + *first = c2; + } + __enable_irq (); +#endif + return (cnt); +} + +__inline static void rt_systick_init (void) { + NVIC_ST_RELOAD = os_get_trv(); + NVIC_ST_CURRENT = 0; +#if (SYSTICK_EXTERNAL_CLOCK) + NVIC_ST_CTRL = 0x0003; +#else + NVIC_ST_CTRL = 0x0007; +#endif + NVIC_SYS_PRI3 |= 0xFF000000; +} + +__inline static void rt_svc_init (void) { +#if !(__TARGET_ARCH_6S_M) + int sh,prigroup; +#endif + NVIC_SYS_PRI3 |= 0x00FF0000; +#if (__TARGET_ARCH_6S_M) + NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000; +#else + sh = 8 - __clz (~((NVIC_SYS_PRI3 << 8) & 0xFF000000)); + prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07); + if (prigroup >= sh) { + sh = prigroup + 1; + } + NVIC_SYS_PRI2 = ((0xFEFFFFFF << sh) & 0xFF000000) | (NVIC_SYS_PRI2 & 0x00FFFFFF); +#endif +} + +extern void rt_set_PSP (U32 stack); +extern U32 rt_get_PSP (void); +extern void os_set_env (void); +extern void *_alloc_box (void *box_mem); +extern int _free_box (void *box_mem, void *box); + +extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); +extern void rt_ret_val (P_TCB p_TCB, U32 v0); +extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); + +extern void dbg_init (void); +extern void dbg_task_notify (P_TCB p_tcb, BOOL create); +extern void dbg_task_switch (U32 task_id); + +#ifdef DBG_MSG +#define DBG_INIT() dbg_init() +#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new_tsk != os_tsk.run)) \ + dbg_task_switch(task_id) +#else +#define DBG_INIT() +#define DBG_TASK_NOTIFY(p_tcb,create) +#define DBG_TASK_SWITCH(task_id) +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_List.c b/rtos/rtx/TARGET_CORTEX_M/rt_List.c new file mode 100644 index 0000000..47e54af --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_List.c @@ -0,0 +1,343 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_LIST.C + * Purpose: Functions for the management of different lists + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Time.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* List head of chained ready tasks */ +struct OS_XCB os_rdy; +/* List head of chained delay tasks */ +struct OS_XCB os_dly; + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_put_prio -----------------------------------*/ + +void rt_put_prio (P_XCB p_CB, P_TCB p_task) { + /* Put task identified with "p_task" into list ordered by priority. */ + /* "p_CB" points to head of list; list has always an element at end with */ + /* a priority less than "p_task->prio". */ + P_TCB p_CB2; + U32 prio; + BOOL sem_mbx = __FALSE; + + if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + sem_mbx = __TRUE; + } + prio = p_task->prio; + p_CB2 = p_CB->p_lnk; + /* Search for an entry in the list */ + while (p_CB2 != NULL && prio <= p_CB2->prio) { + p_CB = (P_XCB)p_CB2; + p_CB2 = p_CB2->p_lnk; + } + /* Entry found, insert the task into the list */ + p_task->p_lnk = p_CB2; + p_CB->p_lnk = p_task; + if (sem_mbx) { + if (p_CB2 != NULL) { + p_CB2->p_rlnk = p_task; + } + p_task->p_rlnk = (P_TCB)p_CB; + } + else { + p_task->p_rlnk = NULL; + } +} + + +/*--------------------------- rt_get_first ----------------------------------*/ + +P_TCB rt_get_first (P_XCB p_CB) { + /* Get task at head of list: it is the task with highest priority. */ + /* "p_CB" points to head of list. */ + P_TCB p_first; + + p_first = p_CB->p_lnk; + p_CB->p_lnk = p_first->p_lnk; + if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + if (p_first->p_lnk != NULL) { + p_first->p_lnk->p_rlnk = (P_TCB)p_CB; + p_first->p_lnk = NULL; + } + p_first->p_rlnk = NULL; + } + else { + p_first->p_lnk = NULL; + } + return (p_first); +} + + +/*--------------------------- rt_put_rdy_first ------------------------------*/ + +void rt_put_rdy_first (P_TCB p_task) { + /* Put task identified with "p_task" at the head of the ready list. The */ + /* task must have at least a priority equal to highest priority in list. */ + p_task->p_lnk = os_rdy.p_lnk; + p_task->p_rlnk = NULL; + os_rdy.p_lnk = p_task; +} + + +/*--------------------------- rt_put_rdy_last ------------------------------*/ + +void rt_put_rdy_last (P_TCB p_task) { + /* Put task identified with "p_task" at the tail of the ready list. The */ + /* task must have at least a priority equal to lowest priority in list. */ + P_TCB p_last; + + p_last = os_rdy.p_lnk; + + p_task->p_rlnk = NULL; + p_task->p_lnk = NULL; + + if (p_last == NULL) { + os_rdy.p_lnk = p_task; + } else { + while (p_last->p_lnk != NULL) { + p_last = p_last->p_lnk; + } + p_last->p_lnk = p_task; + } +} + + +/*--------------------------- rt_get_same_rdy_prio --------------------------*/ + +P_TCB rt_get_same_rdy_prio (void) { + /* Remove a task of same priority from ready list if any exists. Other- */ + /* wise return NULL. */ + P_TCB p_first; + + p_first = os_rdy.p_lnk; + if (p_first->prio == os_tsk.run->prio) { + os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; + return (p_first); + } + return (NULL); +} + + +/*--------------------------- rt_resort_prio --------------------------------*/ + +void rt_resort_prio (P_TCB p_task) { + /* Re-sort ordered lists after the priority of 'p_task' has changed. */ + P_TCB p_CB; + + if (p_task->p_rlnk == NULL) { + if (p_task->state == READY) { + /* Task is chained into READY list. */ + p_CB = (P_TCB)&os_rdy; + goto res; + } + } + else { + p_CB = p_task->p_rlnk; + while (p_CB->cb_type == TCB) { + /* Find a header of this task chain list. */ + p_CB = p_CB->p_rlnk; + } +res:rt_rmv_list (p_task); + rt_put_prio ((P_XCB)p_CB, p_task); + } +} + + +/*--------------------------- rt_put_dly ------------------------------------*/ + +void rt_put_dly (P_TCB p_task, U16 delay) { + /* Put a task identified with "p_task" into chained delay wait list using */ + /* a delay value of "delay". */ + P_TCB p; + U32 delta,idelay = delay; + + p = (P_TCB)&os_dly; + if (p->p_dlnk == NULL) { + /* Delay list empty */ + delta = 0; + goto last; + } + delta = os_dly.delta_time; + while (delta < idelay) { + if (p->p_dlnk == NULL) { + /* End of list found */ +last: p_task->p_dlnk = NULL; + p->p_dlnk = p_task; + p_task->p_blnk = p; + p->delta_time = (U16)(idelay - delta); + p_task->delta_time = 0; + return; + } + p = p->p_dlnk; + delta += p->delta_time; + } + /* Right place found */ + p_task->p_dlnk = p->p_dlnk; + p->p_dlnk = p_task; + p_task->p_blnk = p; + if (p_task->p_dlnk != NULL) { + p_task->p_dlnk->p_blnk = p_task; + } + p_task->delta_time = (U16)(delta - idelay); + p->delta_time -= p_task->delta_time; +} + + +/*--------------------------- rt_dec_dly ------------------------------------*/ + +void rt_dec_dly (void) { + /* Decrement delta time of list head: remove tasks having a value of zero.*/ + P_TCB p_rdy; + + if (os_dly.p_dlnk == NULL) { + return; + } + os_dly.delta_time--; + while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { + p_rdy = os_dly.p_dlnk; + if (p_rdy->p_rlnk != NULL) { + /* Task is really enqueued, remove task from semaphore/mailbox */ + /* timeout waiting list. */ + p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; + if (p_rdy->p_lnk != NULL) { + p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; + p_rdy->p_lnk = NULL; + } + p_rdy->p_rlnk = NULL; + } + rt_put_prio (&os_rdy, p_rdy); + os_dly.delta_time = p_rdy->delta_time; + if (p_rdy->state == WAIT_ITV) { + /* Calculate the next time for interval wait. */ + p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; + } + p_rdy->state = READY; + os_dly.p_dlnk = p_rdy->p_dlnk; + if (p_rdy->p_dlnk != NULL) { + p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; + p_rdy->p_dlnk = NULL; + } + p_rdy->p_blnk = NULL; + } +} + + +/*--------------------------- rt_rmv_list -----------------------------------*/ + +void rt_rmv_list (P_TCB p_task) { + /* Remove task identified with "p_task" from ready, semaphore or mailbox */ + /* waiting list if enqueued. */ + P_TCB p_b; + + if (p_task->p_rlnk != NULL) { + /* A task is enqueued in semaphore / mailbox waiting list. */ + p_task->p_rlnk->p_lnk = p_task->p_lnk; + if (p_task->p_lnk != NULL) { + p_task->p_lnk->p_rlnk = p_task->p_rlnk; + } + return; + } + + p_b = (P_TCB)&os_rdy; + while (p_b != NULL) { + /* Search the ready list for task "p_task" */ + if (p_b->p_lnk == p_task) { + p_b->p_lnk = p_task->p_lnk; + return; + } + p_b = p_b->p_lnk; + } +} + + +/*--------------------------- rt_rmv_dly ------------------------------------*/ + +void rt_rmv_dly (P_TCB p_task) { + /* Remove task identified with "p_task" from delay list if enqueued. */ + P_TCB p_b; + + p_b = p_task->p_blnk; + if (p_b != NULL) { + /* Task is really enqueued */ + p_b->p_dlnk = p_task->p_dlnk; + if (p_task->p_dlnk != NULL) { + /* 'p_task' is in the middle of list */ + p_b->delta_time += p_task->delta_time; + p_task->p_dlnk->p_blnk = p_b; + p_task->p_dlnk = NULL; + } + else { + /* 'p_task' is at the end of list */ + p_b->delta_time = 0; + } + p_task->p_blnk = NULL; + } +} + + +/*--------------------------- rt_psq_enq ------------------------------------*/ + +void rt_psq_enq (OS_ID entry, U32 arg) { + /* Insert post service request "entry" into ps-queue. */ + U32 idx; + + idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); + if (idx < os_psq->size) { + os_psq->q[idx].id = entry; + os_psq->q[idx].arg = arg; + } + else { + os_error (OS_ERR_FIFO_OVF); + } +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_List.h b/rtos/rtx/TARGET_CORTEX_M/rt_List.h new file mode 100644 index 0000000..d68a127 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_List.h @@ -0,0 +1,68 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_LIST.H + * Purpose: Functions for the management of different lists + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Definitions */ + +/* Values for 'cb_type' */ +#define TCB 0 +#define MCB 1 +#define SCB 2 +#define MUCB 3 +#define HCB 4 + +/* Variables */ +extern struct OS_XCB os_rdy; +extern struct OS_XCB os_dly; + +/* Functions */ +extern void rt_put_prio (P_XCB p_CB, P_TCB p_task); +extern P_TCB rt_get_first (P_XCB p_CB); +extern void rt_put_rdy_first (P_TCB p_task); +extern void rt_put_rdy_last (P_TCB p_task); +extern P_TCB rt_get_same_rdy_prio (void); +extern void rt_resort_prio (P_TCB p_task); +extern void rt_put_dly (P_TCB p_task, U16 delay); +extern void rt_dec_dly (void); +extern void rt_rmv_list (P_TCB p_task); +extern void rt_rmv_dly (P_TCB p_task); +extern void rt_psq_enq (OS_ID entry, U32 arg); + +/* This is a fast macro generating in-line code */ +#define rt_rdy_prio(void) (os_rdy.p_lnk->prio) + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c b/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c new file mode 100644 index 0000000..ef28b76 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c @@ -0,0 +1,292 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MAILBOX.C + * Purpose: Implements waits and wake-ups for mailbox messages + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Mailbox.h" +#include "rt_MemBox.h" +#include "rt_Task.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_mbx_init -----------------------------------*/ + +void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { + /* Initialize a mailbox */ + P_MCB p_MCB = mailbox; + + p_MCB->cb_type = MCB; + p_MCB->state = 0; + p_MCB->isr_st = 0; + p_MCB->p_lnk = NULL; + p_MCB->first = 0; + p_MCB->last = 0; + p_MCB->count = 0; + p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) / + (U32)sizeof (void *); +} + + +/*--------------------------- rt_mbx_send -----------------------------------*/ + +OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { + /* Send message to a mailbox */ + P_MCB p_MCB = mailbox; + P_TCB p_TCB; + + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1)) { + /* A task is waiting for message */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); +#else + *p_TCB->msg = p_msg; + rt_ret_val (p_TCB, OS_R_MBX); +#endif + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + /* Store message in mailbox queue */ + if (p_MCB->count == p_MCB->size) { + /* No free message entry, wait for one. If message queue is full, */ + /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ + /* pointer can now be reused for send message waits task list. */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + /* Task is waiting to send a message */ + p_MCB->state = 2; + } + os_tsk.run->msg = p_msg; + rt_block (timeout, WAIT_MBX); + return (OS_R_TMO); + } + /* Yes, there is a free entry in a mailbox. */ + p_MCB->msg[p_MCB->first] = p_msg; + rt_inc (&p_MCB->count); + if (++p_MCB->first == p_MCB->size) { + p_MCB->first = 0; + } + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mbx_wait -----------------------------------*/ + +OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { + /* Receive a message; possibly wait for it */ + P_MCB p_MCB = mailbox; + P_TCB p_TCB; + + /* If a message is available in the fifo buffer */ + /* remove it from the fifo buffer and return. */ + if (p_MCB->count) { + *message = p_MCB->msg[p_MCB->last]; + if (++p_MCB->last == p_MCB->size) { + p_MCB->last = 0; + } + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2)) { + /* A task is waiting to send message */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_OK); +#endif + p_MCB->msg[p_MCB->first] = p_TCB->msg; + if (++p_MCB->first == p_MCB->size) { + p_MCB->first = 0; + } + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + rt_dec (&p_MCB->count); + } + return (OS_R_OK); + } + /* No message available: wait for one */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + /* Task is waiting to receive a message */ + p_MCB->state = 1; + } + rt_block(timeout, WAIT_MBX); +#ifndef __CMSIS_RTOS + os_tsk.run->msg = message; +#endif + return (OS_R_TMO); +} + + +/*--------------------------- rt_mbx_check ----------------------------------*/ + +OS_RESULT rt_mbx_check (OS_ID mailbox) { + /* Check for free space in a mailbox. Returns the number of messages */ + /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ + P_MCB p_MCB = mailbox; + + return (p_MCB->size - p_MCB->count); +} + + +/*--------------------------- isr_mbx_send ----------------------------------*/ + +void isr_mbx_send (OS_ID mailbox, void *p_msg) { + /* Same function as "os_mbx_send", but to be called by ISRs. */ + P_MCB p_MCB = mailbox; + + rt_psq_enq (p_MCB, (U32)p_msg); + rt_psh_req (); +} + + +/*--------------------------- isr_mbx_receive -------------------------------*/ + +OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { + /* Receive a message in the interrupt function. The interrupt function */ + /* should not wait for a message since this would block the rtx os. */ + P_MCB p_MCB = mailbox; + + if (p_MCB->count) { + /* A message is available in the fifo buffer. */ + *message = p_MCB->msg[p_MCB->last]; + if (p_MCB->state == 2) { + /* A task is locked waiting to send message */ + rt_psq_enq (p_MCB, 0); + rt_psh_req (); + } + rt_dec (&p_MCB->count); + if (++p_MCB->last == p_MCB->size) { + p_MCB->last = 0; + } + return (OS_R_MBX); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mbx_psh ------------------------------------*/ + +void rt_mbx_psh (P_MCB p_CB, void *p_msg) { + /* Store the message to the mailbox queue or pass it to task directly. */ + P_TCB p_TCB; + void *mem; + + if (p_CB->p_lnk != NULL) switch (p_CB->state) { +#ifdef __CMSIS_RTOS + case 3: + /* Task is waiting to allocate memory, remove it from the waiting list */ + mem = rt_alloc_box(p_msg); + if (mem == NULL) break; + p_TCB = rt_get_first ((P_XCB)p_CB); + rt_ret_val(p_TCB, (U32)mem); + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; +#endif + case 2: + /* Task is waiting to send a message, remove it from the waiting list */ + p_TCB = rt_get_first ((P_XCB)p_CB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_OK); +#endif + p_CB->msg[p_CB->first] = p_TCB->msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0; + } + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; + case 1: + /* Task is waiting for a message, pass the message to the task directly */ + p_TCB = rt_get_first ((P_XCB)p_CB); +#ifdef __CMSIS_RTOS + rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); +#else + *p_TCB->msg = p_msg; + rt_ret_val (p_TCB, OS_R_MBX); +#endif + p_TCB->state = READY; + rt_rmv_dly (p_TCB); + rt_put_prio (&os_rdy, p_TCB); + break; + } else { + /* No task is waiting for a message, store it to the mailbox queue */ + if (p_CB->count < p_CB->size) { + p_CB->msg[p_CB->first] = p_msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0; + } + } + else { + os_error (OS_ERR_MBX_OVF); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h b/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h new file mode 100644 index 0000000..0c8e2f3 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MAILBOX.H + * Purpose: Implements waits and wake-ups for mailbox messages + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_mbx_init (OS_ID mailbox, U16 mbx_size); +extern OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout); +extern OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout); +extern OS_RESULT rt_mbx_check (OS_ID mailbox); +extern void isr_mbx_send (OS_ID mailbox, void *p_msg); +extern OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message); +extern void rt_mbx_psh (P_MCB p_CB, void *p_msg); + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c b/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c new file mode 100644 index 0000000..5b96ae0 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c @@ -0,0 +1,166 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMBOX.C + * Purpose: Interface functions for fixed memory block management system + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_MemBox.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- _init_box -------------------------------------*/ + +int _init_box (void *box_mem, U32 box_size, U32 blk_size) { + /* Initialize memory block system, returns 0 if OK, 1 if fails. */ + void *end; + void *blk; + void *next; + U32 sizeof_bm; + + /* Create memory structure. */ + if (blk_size & BOX_ALIGN_8) { + /* Memory blocks 8-byte aligned. */ + blk_size = ((blk_size & ~BOX_ALIGN_8) + 7) & ~7; + sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7; + } + else { + /* Memory blocks 4-byte aligned. */ + blk_size = (blk_size + 3) & ~3; + sizeof_bm = sizeof (struct OS_BM); + } + if (blk_size == 0) { + return (1); + } + if ((blk_size + sizeof_bm) > box_size) { + return (1); + } + /* Create a Memory structure. */ + blk = ((U8 *) box_mem) + sizeof_bm; + ((P_BM) box_mem)->free = blk; + end = ((U8 *) box_mem) + box_size; + ((P_BM) box_mem)->end = end; + ((P_BM) box_mem)->blk_size = blk_size; + + /* Link all free blocks using offsets. */ + end = ((U8 *) end) - blk_size; + while (1) { + next = ((U8 *) blk) + blk_size; + if (next > end) break; + *((void **)blk) = next; + blk = next; + } + /* end marker */ + *((void **)blk) = 0; + return (0); +} + +/*--------------------------- rt_alloc_box ----------------------------------*/ + +void *rt_alloc_box (void *box_mem) { + /* Allocate a memory block and return start address. */ + void **free; +#ifndef __USE_EXCLUSIVE_ACCESS + int irq_dis; + + irq_dis = __disable_irq (); + free = ((P_BM) box_mem)->free; + if (free) { + ((P_BM) box_mem)->free = *free; + } + if (!irq_dis) __enable_irq (); +#else + do { + if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0) { + __clrex(); + break; + } + } while (__strex((U32)*free, &((P_BM) box_mem)->free)); +#endif + return (free); +} + + +/*--------------------------- _calloc_box -----------------------------------*/ + +void *_calloc_box (void *box_mem) { + /* Allocate a 0-initialized memory block and return start address. */ + void *free; + U32 *p; + U32 i; + + free = _alloc_box (box_mem); + if (free) { + p = free; + for (i = ((P_BM) box_mem)->blk_size; i; i -= 4) { + *p = 0; + p++; + } + } + return (free); +} + + +/*--------------------------- rt_free_box -----------------------------------*/ + +int rt_free_box (void *box_mem, void *box) { + /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */ +#ifndef __USE_EXCLUSIVE_ACCESS + int irq_dis; +#endif + + if (box < box_mem || box >= ((P_BM) box_mem)->end) { + return (1); + } + +#ifndef __USE_EXCLUSIVE_ACCESS + irq_dis = __disable_irq (); + *((void **)box) = ((P_BM) box_mem)->free; + ((P_BM) box_mem)->free = box; + if (!irq_dis) __enable_irq (); +#else + do { + *((void **)box) = (void *)__ldrex(&((P_BM) box_mem)->free); + } while (__strex ((U32)box, &((P_BM) box_mem)->free)); +#endif + return (0); +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h b/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h new file mode 100644 index 0000000..c10a1cb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMBOX.H + * Purpose: Interface functions for fixed memory block management system + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +#define rt_init_box _init_box +#define rt_calloc_box _calloc_box +extern int _init_box (void *box_mem, U32 box_size, U32 blk_size); +extern void *rt_alloc_box (void *box_mem); +extern void * _calloc_box (void *box_mem); +extern int rt_free_box (void *box_mem, void *box); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c b/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c new file mode 100644 index 0000000..c7a996b --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c @@ -0,0 +1,197 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MUTEX.C + * Purpose: Implements mutex synchronization objects + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Mutex.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_mut_init -----------------------------------*/ + +void rt_mut_init (OS_ID mutex) { + /* Initialize a mutex object */ + P_MUCB p_MCB = mutex; + + p_MCB->cb_type = MUCB; + p_MCB->prio = 0; + p_MCB->level = 0; + p_MCB->p_lnk = NULL; + p_MCB->owner = NULL; +} + + +/*--------------------------- rt_mut_delete ---------------------------------*/ + +#ifdef __CMSIS_RTOS +OS_RESULT rt_mut_delete (OS_ID mutex) { + /* Delete a mutex object */ + P_MUCB p_MCB = mutex; + P_TCB p_TCB; + + /* Restore owner task's priority. */ + if (p_MCB->level != 0) { + p_MCB->owner->prio = p_MCB->prio; + if (p_MCB->owner != os_tsk.run) { + rt_resort_prio (p_MCB->owner); + } + } + + while (p_MCB->p_lnk != NULL) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); + rt_ret_val(p_TCB, 0/*osOK*/); + rt_rmv_dly(p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + } + + if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + /* preempt running task */ + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + + p_MCB->cb_type = 0; + + return (OS_R_OK); +} +#endif + + +/*--------------------------- rt_mut_release --------------------------------*/ + +OS_RESULT rt_mut_release (OS_ID mutex) { + /* Release a mutex object */ + P_MUCB p_MCB = mutex; + P_TCB p_TCB; + + if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { + /* Unbalanced mutex release or task is not the owner */ + return (OS_R_NOK); + } + if (--p_MCB->level != 0) { + return (OS_R_OK); + } + /* Restore owner task's priority. */ + os_tsk.run->prio = p_MCB->prio; + if (p_MCB->p_lnk != NULL) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 0/*osOK*/); +#else + rt_ret_val(p_TCB, OS_R_MUT); +#endif + rt_rmv_dly (p_TCB); + /* A waiting task becomes the owner of this mutex. */ + p_MCB->level = 1; + p_MCB->owner = p_TCB; + p_MCB->prio = p_TCB->prio; + /* Priority inversion, check which task continues. */ + if (os_tsk.run->prio >= rt_rdy_prio()) { + rt_dispatch (p_TCB); + } + else { + /* Ready task has higher priority than running task. */ + rt_put_prio (&os_rdy, os_tsk.run); + rt_put_prio (&os_rdy, p_TCB); + os_tsk.run->state = READY; + p_TCB->state = READY; + rt_dispatch (NULL); + } + } + else { + /* Check if own priority raised by priority inversion. */ + if (rt_rdy_prio() > os_tsk.run->prio) { + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + } + return (OS_R_OK); +} + + +/*--------------------------- rt_mut_wait -----------------------------------*/ + +OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { + /* Wait for a mutex, continue when mutex is free. */ + P_MUCB p_MCB = mutex; + + if (p_MCB->level == 0) { + p_MCB->owner = os_tsk.run; + p_MCB->prio = os_tsk.run->prio; + goto inc; + } + if (p_MCB->owner == os_tsk.run) { + /* OK, running task is the owner of this mutex. */ +inc:p_MCB->level++; + return (OS_R_OK); + } + /* Mutex owned by another task, wait until released. */ + if (timeout == 0) { + return (OS_R_TMO); + } + /* Raise the owner task priority if lower than current priority. */ + /* This priority inversion is called priority inheritance. */ + if (p_MCB->prio < os_tsk.run->prio) { + p_MCB->owner->prio = os_tsk.run->prio; + rt_resort_prio (p_MCB->owner); + } + if (p_MCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_MCB, os_tsk.run); + } + else { + p_MCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_MCB; + } + rt_block(timeout, WAIT_MUT); + return (OS_R_TMO); +} + + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h b/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h new file mode 100644 index 0000000..bf15c4d --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_MUTEX.H + * Purpose: Implements mutex synchronization objects + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_mut_init (OS_ID mutex); +extern OS_RESULT rt_mut_delete (OS_ID mutex); +extern OS_RESULT rt_mut_release (OS_ID mutex); +extern OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Robin.c b/rtos/rtx/TARGET_CORTEX_M/rt_Robin.c new file mode 100644 index 0000000..d693dc6 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Robin.c @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_ROBIN.C + * Purpose: Round Robin Task switching + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Time.h" +#include "rt_Robin.h" +#include "rt_HAL_CM.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +struct OS_ROBIN os_robin; + + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +/*--------------------------- rt_init_robin ---------------------------------*/ + +__weak void rt_init_robin (void) { + /* Initialize Round Robin variables. */ + os_robin.task = NULL; + os_robin.tout = (U16)os_rrobin; +} + +/*--------------------------- rt_chk_robin ----------------------------------*/ + +__weak void rt_chk_robin (void) { + /* Check if Round Robin timeout expired and switch to the next ready task.*/ + P_TCB p_new; + + if (os_robin.task != os_rdy.p_lnk) { + /* New task was suspended, reset Round Robin timeout. */ + os_robin.task = os_rdy.p_lnk; + os_robin.time = (U16)os_time + os_robin.tout - 1; + } + if (os_robin.time == (U16)os_time) { + /* Round Robin timeout has expired, swap Robin tasks. */ + os_robin.task = NULL; + p_new = rt_get_first (&os_rdy); + rt_put_prio ((P_XCB)&os_rdy, p_new); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Robin.h b/rtos/rtx/TARGET_CORTEX_M/rt_Robin.h new file mode 100644 index 0000000..3ccbffc --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Robin.h @@ -0,0 +1,45 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_ROBIN.H + * Purpose: Round Robin Task switching definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern struct OS_ROBIN os_robin; + +/* Functions */ +extern void rt_init_robin (void); +extern void rt_chk_robin (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c b/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c new file mode 100644 index 0000000..93ff2bf --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c @@ -0,0 +1,183 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SEMAPHORE.C + * Purpose: Implements binary and counting semaphores + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_List.h" +#include "rt_Task.h" +#include "rt_Semaphore.h" +#include "rt_HAL_CM.h" + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_sem_init -----------------------------------*/ + +void rt_sem_init (OS_ID semaphore, U16 token_count) { + /* Initialize a semaphore */ + P_SCB p_SCB = semaphore; + + p_SCB->cb_type = SCB; + p_SCB->p_lnk = NULL; + p_SCB->tokens = token_count; +} + + +/*--------------------------- rt_sem_delete ---------------------------------*/ + +#ifdef __CMSIS_RTOS +OS_RESULT rt_sem_delete (OS_ID semaphore) { + /* Delete semaphore */ + P_SCB p_SCB = semaphore; + P_TCB p_TCB; + + while (p_SCB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_SCB); + rt_ret_val(p_TCB, 0); + rt_rmv_dly(p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + } + + if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + /* preempt running task */ + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + + p_SCB->cb_type = 0; + + return (OS_R_OK); +} +#endif + + +/*--------------------------- rt_sem_send -----------------------------------*/ + +OS_RESULT rt_sem_send (OS_ID semaphore) { + /* Return a token to semaphore */ + P_SCB p_SCB = semaphore; + P_TCB p_TCB; + + if (p_SCB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_SCB); +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 1); +#else + rt_ret_val(p_TCB, OS_R_SEM); +#endif + rt_rmv_dly (p_TCB); + rt_dispatch (p_TCB); + } + else { + /* Store token. */ + p_SCB->tokens++; + } + return (OS_R_OK); +} + + +/*--------------------------- rt_sem_wait -----------------------------------*/ + +OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) { + /* Obtain a token; possibly wait for it */ + P_SCB p_SCB = semaphore; + + if (p_SCB->tokens) { + p_SCB->tokens--; + return (OS_R_OK); + } + /* No token available: wait for one */ + if (timeout == 0) { + return (OS_R_TMO); + } + if (p_SCB->p_lnk != NULL) { + rt_put_prio ((P_XCB)p_SCB, os_tsk.run); + } + else { + p_SCB->p_lnk = os_tsk.run; + os_tsk.run->p_lnk = NULL; + os_tsk.run->p_rlnk = (P_TCB)p_SCB; + } + rt_block(timeout, WAIT_SEM); + return (OS_R_TMO); +} + + +/*--------------------------- isr_sem_send ----------------------------------*/ + +void isr_sem_send (OS_ID semaphore) { + /* Same function as "os_sem"send", but to be called by ISRs */ + P_SCB p_SCB = semaphore; + + rt_psq_enq (p_SCB, 0); + rt_psh_req (); +} + + +/*--------------------------- rt_sem_psh ------------------------------------*/ + +void rt_sem_psh (P_SCB p_CB) { + /* Check if task has to be waken up */ + P_TCB p_TCB; + + if (p_CB->p_lnk != NULL) { + /* A task is waiting for token */ + p_TCB = rt_get_first ((P_XCB)p_CB); + rt_rmv_dly (p_TCB); + p_TCB->state = READY; +#ifdef __CMSIS_RTOS + rt_ret_val(p_TCB, 1); +#else + rt_ret_val(p_TCB, OS_R_SEM); +#endif + rt_put_prio (&os_rdy, p_TCB); + } + else { + /* Store token */ + p_CB->tokens++; + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h b/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h new file mode 100644 index 0000000..ec45480 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SEMAPHORE.H + * Purpose: Implements binary and counting semaphores + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Functions */ +extern void rt_sem_init (OS_ID semaphore, U16 token_count); +extern OS_RESULT rt_sem_delete(OS_ID semaphore); +extern OS_RESULT rt_sem_send (OS_ID semaphore); +extern OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout); +extern void isr_sem_send (OS_ID semaphore); +extern void rt_sem_psh (P_SCB p_CB); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_System.c b/rtos/rtx/TARGET_CORTEX_M/rt_System.c new file mode 100644 index 0000000..022c433 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_System.c @@ -0,0 +1,445 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SYSTEM.C + * Purpose: System Task Manager + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_Task.h" +#include "rt_System.h" +#include "rt_Event.h" +#include "rt_List.h" +#include "rt_Mailbox.h" +#include "rt_Semaphore.h" +#include "rt_Time.h" +#include "rt_Robin.h" +#include "rt_HAL_CM.h" + +#include "hal_sleep.h" +#include "hal_timer.h" +#include "hal_trace.h" + +extern void sysTimerTick(void); +extern uint32_t rt_timer_delay_count(void); + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +int os_tick_irqn; + +/*---------------------------------------------------------------------------- + * Local Variables + *---------------------------------------------------------------------------*/ + +static volatile BIT os_lock; +static volatile BIT os_psh_flag; +static U8 pend_flags; +static U32 systick_lock_tick; +static U32 systick_lock_ts; + +/*---------------------------------------------------------------------------- + * Global Functions + *---------------------------------------------------------------------------*/ + +#if defined (__CC_ARM) +__asm void $$RTX$$version (void) { + /* Export a version number symbol for a version control. */ + + EXPORT __RL_RTX_VER + +__RL_RTX_VER EQU 0x450 +} +#endif + +/*--------------------------- rt_suspend ------------------------------------*/ +U32 rt_suspend (void) { + /* Suspend OS scheduler */ + U32 delta = 0xFFFF; + U32 start_tick; + + __disable_irq(); + start_tick = NVIC_ST_CURRENT; + rt_tsk_lock(); + systick_lock_tick = NVIC_ST_CURRENT; + systick_lock_ts = hal_sys_timer_get(); + if (start_tick != 0 && (systick_lock_tick == 0 || start_tick < systick_lock_tick)) { +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 1) + TRACE(6,"[%u/0x%X][%2u/%u] rt_suspend corner case: %02u -> %02u", + TICKS_TO_MS(hal_sys_timer_get()), hal_sys_timer_get(), NVIC_ST_CURRENT, os_time, + start_tick, systick_lock_tick); +#endif + pend_flags |= 1; + } + if (pend_flags) { + delta = 0; + } + __enable_irq(); + + if (delta == 0) { + return 0; + } + + if (os_dly.p_dlnk) { + delta = os_dly.delta_time; + } +#ifdef __CMSIS_RTOS + { + uint32_t tcnt = rt_timer_delay_count(); + if (tcnt && tcnt < delta) { + delta = tcnt; + } + } +#else + if (os_tmr.next) { + if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; + } +#endif + + return (delta); +} + +/*--------------------------- rt_resume -------------------------------------*/ +void rt_resume (U32 sleep_time) { + /* Resume OS scheduler after suspend */ + //P_TCB next; + U32 delta; + U32 resume_ts; + U32 unlock_ts; + U32 systick_remain; + U32 sleep_ticks; + U8 tick_running = 0; + const U32 reload = (NVIC_ST_RELOAD + 1); + + __disable_irq(); + resume_ts = hal_sys_timer_get(); + __enable_irq(); + + sleep_ticks = (resume_ts - systick_lock_ts) * (OS_CLOCK_NOMINAL / CONFIG_SYSTICK_HZ_NOMINAL); + if (systick_lock_tick == 0) { + sleep_time = sleep_ticks / reload; + systick_remain = reload - sleep_ticks % reload; + } else if (sleep_ticks >= systick_lock_tick) { + delta = sleep_ticks - systick_lock_tick; + sleep_time = delta / reload + 1; + systick_remain = reload - delta % reload; + } else { + sleep_time = 0; + systick_remain = systick_lock_tick - sleep_ticks; + } + + if (sleep_time == 0) { + tick_running = 1; + goto _task_unlock; + } + + // Task switching is allowed in SVC/PENDSV/SYSTICK handlers only +#if 0 + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); +#endif + +_inc_sleep_time: + + os_robin.task = NULL; + + if (sleep_time) { + /* Update delays. */ + if (os_dly.p_dlnk) { + delta = sleep_time; + if (delta >= os_dly.delta_time) { + delta -= os_dly.delta_time; + os_time += os_dly.delta_time; + os_dly.delta_time = 1; + while (os_dly.p_dlnk) { + rt_dec_dly(); + if (delta == 0) break; + delta--; + os_time++; + } + while (delta) { + delta--; + os_time++; + } + rt_psh_req(); + } else { + os_time += delta; + os_dly.delta_time -= delta; + } + } else { + os_time += sleep_time; + } + + os_idle_TCB.rtime += sleep_time; +#ifdef __CMSIS_RTOS + delta = sleep_time; + while (delta && rt_timer_delay_count()) { + sysTimerTick(); + delta--; + } +#else + /* Check the user timers. */ + if (os_tmr.next) { + delta = sleep_time; + if (delta >= os_tmr.tcnt) { + delta -= os_tmr.tcnt; + os_tmr.tcnt = 1; + while (os_tmr.next) { + rt_tmr_tick(); + if (delta == 0) break; + delta--; + } + } else { + os_tmr.tcnt -= delta; + } + } +#endif + } // sleep_time + + // Task switching is allowed in SVC/PENDSV/SYSTICK handlers only +#if 0 + /* Switch back to highest ready task */ + next = rt_get_first (&os_rdy); + rt_switch_req (next); +#endif + +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 1) + if (sleep_time > 0) { + TRACE(7,"[%u/0x%X][%2u/%u] rt_resume: sleep_ticks=%u sleep_time=%u systick_remain=%u", + TICKS_TO_MS(hal_sys_timer_get()), hal_sys_timer_get(), NVIC_ST_CURRENT, os_time, + sleep_ticks, sleep_time, systick_remain); + } +#endif + +_task_unlock: + + sleep_time = 0; + + __disable_irq(); + // Handle corner case: systick counter wraps inside rt_resume() + unlock_ts = hal_sys_timer_get(); + sleep_ticks = (unlock_ts - resume_ts) * 2; + // systick_remain value range: [1, reload] + if (sleep_ticks >= systick_remain) { +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 1) + TRACE(6,"[%u/0x%X][%2u/%u] rt_resume corner case: sleep_ticks=%u systick_remain=%u", + TICKS_TO_MS(hal_sys_timer_get()), hal_sys_timer_get(), NVIC_ST_CURRENT, os_time, + sleep_ticks, systick_remain); + // Update timestamp since traces also consume time + unlock_ts = hal_sys_timer_get(); + sleep_ticks = (unlock_ts - resume_ts) * (OS_CLOCK_NOMINAL / CONFIG_SYSTICK_HZ_NOMINAL); +#endif + delta = sleep_ticks - systick_remain; + sleep_time = delta / reload + 1; + systick_remain = reload - delta % reload; + resume_ts = unlock_ts; + } else { + if (tick_running == 0) { + systick_remain -= sleep_ticks; + // Adjust systick_remain value range to [0, reload - 1] + if (systick_remain == reload) { + systick_remain = 0; + } + if (systick_remain) { + NVIC_ST_RELOAD = systick_remain; + NVIC_ST_CURRENT = 0; + while (NVIC_ST_CURRENT == 0); + NVIC_ST_RELOAD = reload - 1; + } else { + NVIC_ST_CURRENT = 0; + } + } + rt_tsk_unlock(); + } + __enable_irq(); + + if (sleep_time) { + goto _inc_sleep_time; + } +} + + +/*--------------------------- rt_tsk_lock -----------------------------------*/ + +void rt_tsk_lock (void) { + /* Prevent task switching by locking out scheduler */ + if (os_tick_irqn < 0) { + OS_LOCK(); + os_lock = __TRUE; + OS_UNPEND (&pend_flags); + } else { + OS_X_LOCK(os_tick_irqn); + os_lock = __TRUE; + OS_X_UNPEND (&pend_flags); + } +} + + +/*--------------------------- rt_tsk_unlock ---------------------------------*/ + +void rt_tsk_unlock (void) { + /* Unlock scheduler and re-enable task switching */ + if (os_tick_irqn < 0) { + OS_UNLOCK(); + os_lock = __FALSE; + OS_PEND (pend_flags, os_psh_flag); + os_psh_flag = __FALSE; + } else { + OS_X_UNLOCK(os_tick_irqn); + os_lock = __FALSE; + OS_X_PEND (pend_flags, os_psh_flag); + os_psh_flag = __FALSE; + } + // Allow cpu sleep + hal_cpu_wake_unlock(HAL_CPU_WAKE_LOCK_USER_RTOS); +} + + +/*--------------------------- rt_psh_req ------------------------------------*/ + +void rt_psh_req (void) { + /* Initiate a post service handling request if required. */ + if (os_lock == __FALSE) { + OS_PEND_IRQ (); + } + else { + os_psh_flag = __TRUE; + // Prohibit cpu sleep when an OS service request is enqueued during os lock (rt_suspend) + hal_cpu_wake_lock(HAL_CPU_WAKE_LOCK_USER_RTOS); + } +} + + +/*--------------------------- rt_pop_req ------------------------------------*/ + +void rt_pop_req (void) { + /* Process an ISR post service requests. */ + struct OS_XCB *p_CB; + P_TCB next; + U32 idx; + + os_tsk.run->state = READY; + if (os_tsk.run == &os_idle_TCB) { + rt_put_rdy_last (os_tsk.run); + } else { + rt_put_rdy_first (os_tsk.run); + } + + idx = os_psq->last; + while (os_psq->count) { + p_CB = os_psq->q[idx].id; + if (p_CB->cb_type == TCB) { + /* Is of TCB type */ + rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg); + } + else if (p_CB->cb_type == MCB) { + /* Is of MCB type */ + rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg); + } + else { + /* Must be of SCB type */ + rt_sem_psh ((P_SCB)p_CB); + } + if (++idx == os_psq->size) idx = 0; + rt_dec (&os_psq->count); + } + os_psq->last = idx; + + next = rt_get_first (&os_rdy); + rt_switch_req (next); +} + + +/*--------------------------- os_tick_init ----------------------------------*/ + +__weak int os_tick_init (void) { + /* Initialize SysTick timer as system tick timer. */ + rt_systick_init (); + return (-1); /* Return IRQ number of SysTick timer */ +} + + +/*--------------------------- os_tick_irqack --------------------------------*/ + +__weak void os_tick_irqack (void) { + /* Acknowledge timer interrupt. */ +} + + +/*--------------------------- rt_systick ------------------------------------*/ +void rt_systick (void) { + /* Check for system clock update, suspend running task. */ + P_TCB next; + +#if __RTX_CPU_STATISTICS__ + os_tsk.run->rtime += 1; +#endif + + os_tsk.run->state = READY; + rt_put_rdy_first (os_tsk.run); + + /* Check Round Robin timeout. */ + rt_chk_robin (); + + /* Update delays. */ + os_time++; + rt_dec_dly (); + + /* Check the user timers. */ +#ifdef __CMSIS_RTOS + sysTimerTick(); +#else + rt_tmr_tick (); +#endif + + /* Switch back to highest ready task */ + next = rt_get_first (&os_rdy); + rt_switch_req (next); +} + +/*--------------------------- rt_stk_check ----------------------------------*/ +__weak void rt_stk_check (void) { + /* Check for stack overflow. */ + if (os_tsk.run->task_id == 0x01) { + // TODO: For the main thread the check should be done against the main heap pointer + } else { + if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || + (os_tsk.run->stack[0] != MAGIC_WORD)) { + os_error (OS_ERR_STK_OVF); + } + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_System.h b/rtos/rtx/TARGET_CORTEX_M/rt_System.h new file mode 100644 index 0000000..91db648 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_System.h @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_SYSTEM.H + * Purpose: System Task Manager definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Variables */ +#define os_psq ((P_PSQ)&os_fifo) +extern int os_tick_irqn; + +/* Functions */ +extern U32 rt_suspend (void); +extern void rt_resume (U32 sleep_time); +extern void rt_tsk_lock (void); +extern void rt_tsk_unlock (void); +extern void rt_psh_req (void); +extern void rt_pop_req (void); +extern void rt_systick (void); +extern void rt_stk_check (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Task.c b/rtos/rtx/TARGET_CORTEX_M/rt_Task.c new file mode 100644 index 0000000..98c8160 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Task.c @@ -0,0 +1,735 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TASK.C + * Purpose: Task functions and system start up. + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_System.h" +#include "rt_Task.h" +#include "rt_List.h" +#include "rt_MemBox.h" +#include "rt_Robin.h" +#include "rt_HAL_CM.h" + +#include "hal_timer.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* Running and next task info. */ +struct OS_TSK os_tsk; + +/* Task Control Blocks of idle demon */ +struct OS_TCB os_idle_TCB; + +static U32 rtx_get_hwticks(void) +{ + return hal_sys_timer_get(); +} + + +/*---------------------------------------------------------------------------- + * Local Functions + *---------------------------------------------------------------------------*/ + +OS_TID rt_get_TID (void) { + U32 tid; + + for (tid = 1; tid <= os_maxtaskrun; tid++) { + if (os_active_TCB[tid-1] == NULL) { + return ((OS_TID)tid); + } + } + return (0); +} + +#if defined (__CC_ARM) && !defined (__MICROLIB) +/*--------------------------- __user_perthread_libspace ---------------------*/ +extern void *__libspace_start; + +void *__user_perthread_libspace (void) { + /* Provide a separate libspace for each task. */ + if (os_tsk.run == NULL) { + /* RTX not running yet. */ + return (&__libspace_start); + } + return (void *)(os_tsk.run->std_libspace); +} +#endif + +/*--------------------------- rt_init_context -------------------------------*/ + +void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) { + /* Initialize general part of the Task Control Block. */ + p_TCB->cb_type = TCB; + p_TCB->state = READY; + p_TCB->prio = priority; + p_TCB->p_lnk = NULL; + p_TCB->p_rlnk = NULL; + p_TCB->p_dlnk = NULL; + p_TCB->p_blnk = NULL; + p_TCB->delta_time = 0; + p_TCB->interval_time = 0; + p_TCB->events = 0; + p_TCB->waits = 0; + p_TCB->stack_frame = 0; + + rt_init_stack (p_TCB, task_body); +} + + +/*--------------------------- rt_switch_req ---------------------------------*/ + +void rt_switch_req (P_TCB p_new) { + /* Switch to next task (identified by "p_new"). */ + os_tsk.new_tsk = p_new; +#if __RTX_CPU_STATISTICS__ + if (os_tsk.run != p_new) { + os_tsk.run->swap_out_time = HWTICKS_TO_MS(rtx_get_hwticks()); + p_new->swap_in_time = HWTICKS_TO_MS(rtx_get_hwticks()); + } +#endif + p_new->state = RUNNING; + DBG_TASK_SWITCH(p_new->task_id); +} + + +/*--------------------------- rt_dispatch -----------------------------------*/ + +void rt_dispatch (P_TCB next_TCB) { + /* Dispatch next task if any identified or dispatch highest ready task */ + /* "next_TCB" identifies a task to run or has value NULL (=no next task) */ + if (next_TCB == NULL) { + /* Running task was blocked: continue with highest ready task */ + next_TCB = rt_get_first (&os_rdy); + rt_switch_req (next_TCB); + } + else { + /* Check which task continues */ + if (next_TCB->prio > os_tsk.run->prio) { + /* preempt running task */ + rt_put_rdy_first (os_tsk.run); + os_tsk.run->state = READY; + rt_switch_req (next_TCB); + } + else { + /* put next task into ready list, no task switch takes place */ + next_TCB->state = READY; + rt_put_prio (&os_rdy, next_TCB); + } + } +} + + +/*--------------------------- rt_block --------------------------------------*/ + +void rt_block (U16 timeout, U8 block_state) { + /* Block running task and choose next ready task. */ + /* "timeout" sets a time-out value or is 0xffff (=no time-out). */ + /* "block_state" defines the appropriate task state */ + P_TCB next_TCB; + + if (timeout) { + if (timeout < 0xffff) { + rt_put_dly (os_tsk.run, timeout); + } + os_tsk.run->state = block_state; + next_TCB = rt_get_first (&os_rdy); + rt_switch_req (next_TCB); + } +} + + +/*--------------------------- rt_tsk_pass -----------------------------------*/ + +void rt_tsk_pass (void) { + /* Allow tasks of same priority level to run cooperatively.*/ + P_TCB p_new; + + p_new = rt_get_same_rdy_prio(); + if (p_new != NULL) { + rt_put_prio ((P_XCB)&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_switch_req (p_new); + } +} + + +/*--------------------------- rt_tsk_self -----------------------------------*/ + +OS_TID rt_tsk_self (void) { + /* Return own task identifier value. */ + if (os_tsk.run == NULL) { + return (0); + } + return (os_tsk.run->task_id); +} + + +/*--------------------------- rt_tsk_prio -----------------------------------*/ + +OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) { + /* Change execution priority of a task to "new_prio". */ + P_TCB p_task; + + if (task_id == 0) { + /* Change execution priority of calling task. */ + os_tsk.run->prio = new_prio; +run:if (rt_rdy_prio() > new_prio) { + rt_put_prio (&os_rdy, os_tsk.run); + os_tsk.run->state = READY; + rt_dispatch (NULL); + } + return (OS_R_OK); + } + + /* Find the task in the "os_active_TCB" array. */ + if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + /* Task with "task_id" not found or not started. */ + return (OS_R_NOK); + } + p_task = os_active_TCB[task_id-1]; + p_task->prio = new_prio; + if (p_task == os_tsk.run) { + goto run; + } + rt_resort_prio (p_task); + if (p_task->state == READY) { + /* Task enqueued in a ready list. */ + p_task = rt_get_first (&os_rdy); + rt_dispatch (p_task); + } + return (OS_R_OK); +} + +/*--------------------------- rt_tsk_delete ---------------------------------*/ + +OS_RESULT rt_tsk_delete (OS_TID task_id) { + /* Terminate the task identified with "task_id". */ + P_TCB task_context; + + if (task_id == 0 || task_id == os_tsk.run->task_id) { + /* Terminate itself. */ + os_tsk.run->state = INACTIVE; + os_tsk.run->tsk_stack = rt_get_PSP (); + rt_stk_check (); + os_active_TCB[os_tsk.run->task_id-1] = NULL; + + os_tsk.run->stack = NULL; + DBG_TASK_NOTIFY(os_tsk.run, __FALSE); + os_tsk.run = NULL; + rt_dispatch (NULL); + /* The program should never come to this point. */ + } + else { + /* Find the task in the "os_active_TCB" array. */ + if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + /* Task with "task_id" not found or not started. */ + return (OS_R_NOK); + } + task_context = os_active_TCB[task_id-1]; + rt_rmv_list (task_context); + rt_rmv_dly (task_context); + os_active_TCB[task_id-1] = NULL; + + task_context->stack = NULL; + DBG_TASK_NOTIFY(task_context, __FALSE); + } + return (OS_R_OK); +} + + +/*--------------------------- rt_sys_init -----------------------------------*/ + +#ifdef __CMSIS_RTOS +void rt_sys_init (void) { +#else +void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { +#endif + /* Initialize system and start up task declared with "first_task". */ + U32 i; + + DBG_INIT(); + + /* Initialize dynamic memory and task TCB pointers to NULL. */ + for (i = 0; i < os_maxtaskrun; i++) { + os_active_TCB[i] = NULL; + } + + /* Set up TCB of idle demon */ + os_idle_TCB.task_id = 255; + os_idle_TCB.priv_stack = idle_task_stack_size; + os_idle_TCB.stack = idle_task_stack; +#if __RTX_CPU_STATISTICS__ + os_idle_TCB.name = (U8 *)"os_idle"; +#endif + rt_init_context (&os_idle_TCB, 0, os_idle_demon); + + /* Set up ready list: initially empty */ + os_rdy.cb_type = HCB; + os_rdy.p_lnk = NULL; + /* Set up delay list: initially empty */ + os_dly.cb_type = HCB; + os_dly.p_dlnk = NULL; + os_dly.p_blnk = NULL; + os_dly.delta_time = 0; + + /* Fix SP and systemvariables to assume idle task is running */ + /* Transform main program into idle task by assuming idle TCB */ +#ifndef __CMSIS_RTOS + rt_set_PSP (os_idle_TCB.tsk_stack+32); +#endif + os_tsk.run = &os_idle_TCB; + os_tsk.run->state = RUNNING; + + /* Initialize ps queue */ + os_psq->first = 0; + os_psq->last = 0; + os_psq->size = os_fifo_size; +#if __RTX_CPU_STATISTICS__ + os_tsk.run->swap_in_time = HWTICKS_TO_MS(rtx_get_hwticks()); +#endif + rt_init_robin (); + + /* Intitialize SVC and PendSV */ + rt_svc_init (); + +#ifndef __CMSIS_RTOS + /* Intitialize and start system clock timer */ + os_tick_irqn = os_tick_init (); + if (os_tick_irqn >= 0) { + OS_X_INIT(os_tick_irqn); + } + + /* Start up first user task before entering the endless loop */ + rt_tsk_create (first_task, prio_stksz, stk, NULL); +#endif +} + + +/*--------------------------- rt_sys_start ----------------------------------*/ + +#ifdef __CMSIS_RTOS +void rt_sys_start (void) { + /* Start system */ + + /* Intitialize and start system clock timer */ + os_tick_irqn = os_tick_init (); + if (os_tick_irqn >= 0) { + OS_X_INIT(os_tick_irqn); + } +} +#endif + +//------------------------------------------------------------------------------ +// Debug functions +//------------------------------------------------------------------------------ + +#include "plat_addr_map.h" +#include "hal_location.h" +#include "hal_trace.h" + +#define RTX_DUMP_VERBOSE + +struct IRQ_STACK_FRAME_T { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t xpsr; +}; + +extern uint32_t __StackTop[]; + +static inline uint32_t get_IPSR(void) +{ + uint32_t result; + + asm volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + +static inline uint32_t get_PSP(void) +{ + uint32_t result; + + asm volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + +static inline struct IRQ_STACK_FRAME_T *_rtx_get_irq_stack_frame(P_TCB tcb) +{ + uint32_t sp; + + if (tcb == NULL) { + return NULL; + } + if (tcb == os_tsk.run && get_IPSR() == 0) { + return NULL; + } + if (tcb == os_tsk.run) { + sp = get_PSP(); + } else { + sp = tcb->tsk_stack; + } + if ((sp & 3) || !hal_trace_address_writable(sp)) { + return NULL; + } + + if (tcb != os_tsk.run) { + // r4-r11 + sp += 4 * 8; + if (tcb->stack_frame) { + // s16-s31 + sp += 4 * 16; + } + } + + return (struct IRQ_STACK_FRAME_T *)sp; +} + +FLASH_TEXT_LOC +void rt_tsk_show(P_TCB tcb) +{ + static const char * const state_list[] = { + "INACTIVE", "READY", "RUNNING", "WAIT_DLY", "WAIT_ITV", "WAIT_OR", "WAIT_AND", "WAIT_SEM", "WAIT_MBX", "WAIT_MUT", "BAD", + }; + const char *task_st_str; + uint32_t idx; + struct IRQ_STACK_FRAME_T *frame; + + if (tcb) { + if (tcb->cb_type == TCB && ((tcb->task_id >= 1 && tcb->task_id <= os_maxtaskrun) || tcb->task_id == 255) && + tcb->ptask && tcb->stack) { + if (tcb->state < ARRAY_SIZE(state_list)) { + idx = tcb->state; + } else { + idx = ARRAY_SIZE(state_list) - 1; + } + task_st_str = state_list[idx]; + REL_TRACE_NOCRLF_NOTS(1,"--- Task %3u", tcb->task_id); + + REL_TRACE_NOTS(4," tcb=0x%08X prio=%u state=%-8s ptask=0x%08X", (uint32_t)tcb, tcb->prio, task_st_str, (uint32_t)tcb->ptask); +#if __RTX_CPU_STATISTICS__ + if(tcb->name || tcb->task_id == 1) { + REL_TRACE_NOTS(1," name=%s", tcb->name ? (const char *)tcb->name : "main"); + } +#endif +#ifdef RTX_DUMP_VERBOSE + REL_TRACE_NOTS(3," p_lnk=0x%08X p_rlnk=0x%08X p_dlnk=0x%08X", + (uint32_t)tcb->p_lnk, (uint32_t)tcb->p_rlnk, (uint32_t)tcb->p_dlnk); + REL_TRACE_NOTS(3," p_blnk=0x%08X delta_time=%u interval_time=%u", + (uint32_t)tcb->p_blnk, tcb->delta_time, tcb->interval_time); + REL_TRACE_NOTS(3," events=0x%04X waits=0x%04X msg=0x%08X", + tcb->events, tcb->waits, (uint32_t)tcb->msg); + REL_TRACE_NOTS(2," priv_stack(stack_size)=%4u tsk_stack(sp)=0x%08X", + tcb->priv_stack, tcb->tsk_stack); + REL_TRACE_NOTS(3," stack(top)=0x%08X stack_frame=%u stk_msk:0x%04x", + (uint32_t)tcb->stack, tcb->stack_frame, tcb->stack[0]); +#ifdef __RTX_CPU_STATISTICS__ + REL_TRACE_NOTS(2," swap_in_time=%u swap_out_time=%u", + tcb->swap_in_time, tcb->swap_out_time); + REL_TRACE_NOCRLF_NOTS(0," after last switch "); + if (tcb->swap_in_time <= tcb->swap_out_time) + REL_TRACE_NOTS(1,"task runtime %u ms", tcb->swap_out_time - tcb->swap_in_time); + else + REL_TRACE_NOTS(1,"task still runing, now %d", HWTICKS_TO_MS(rtx_get_hwticks())); +#endif +#endif /*RTX_DUMP_VERBOSE*/ + + frame = _rtx_get_irq_stack_frame(tcb); + if (frame) { + uint32_t stack_end; + uint32_t search_cnt, print_cnt; + + REL_TRACE_NOTS(0," "); + REL_TRACE_NOTS(4," R0 =0x%08X R1=0x%08X R2=0x%08X R3 =0x%08X", frame->r0, frame->r1, frame->r2, frame->r3); + REL_TRACE_NOTS(4," R12=0x%08X LR=0x%08X PC=0x%08X XPSR=0x%08X", frame->r12, frame->lr, frame->pc, frame->xpsr); + + stack_end = (uint32_t)tcb->stack + tcb->priv_stack; + if (stack_end > tcb->tsk_stack) { + search_cnt = (stack_end - tcb->tsk_stack) / 4; + if (search_cnt > 512) { + search_cnt = 512; + } + print_cnt = 10; + hal_trace_print_backtrace(tcb->tsk_stack, search_cnt, print_cnt); + } + } + } else { + REL_TRACE_NOTS(0,"--- Task BAD"); + } + } else { + REL_TRACE_NOTS(0,"--- Task NONE"); + } +} + +FLASH_TEXT_LOC +void rtx_show_current_thread(void) +{ + REL_TRACE_NOTS(1,"Current Task : %u", os_tsk.run ? os_tsk.run->task_id : 0); + REL_TRACE_NOTS(1,"New Running Task: %u", os_tsk.new_tsk ? os_tsk.new_tsk->task_id : 0); + REL_TRACE_IMM_NOTS(0," "); +} + +FLASH_TEXT_LOC +void rtx_show_ready_threads(void) +{ + P_TCB tcb; + uint32_t i; + + REL_TRACE_NOTS(0,"Ready Tasks:"); + if (os_rdy.p_lnk) { + tcb = os_rdy.p_lnk; + i = 0; + do { + REL_TRACE_NOCRLF_NOTS(1,"%u ", tcb->task_id); + tcb = tcb->p_lnk; + i++; + } while (tcb && i < os_maxtaskrun); + REL_TRACE_NOTS(0," "); + if (tcb) { + REL_TRACE_NOTS(2,"*** Error: List corrupted? count=%u next=0x%08X\n", i, (uint32_t)tcb); + } + } else { + REL_TRACE_NOTS(0,""); + } + REL_TRACE_IMM_NOTS(0," "); +} + +FLASH_TEXT_LOC +void rtx_show_delay_threads(void) +{ + P_TCB tcb; + uint32_t i; + + REL_TRACE_NOTS(0,"Delay Tasks:"); + if (os_dly.p_dlnk) { + tcb = os_dly.p_dlnk; + i = 0; + do { + REL_TRACE_NOCRLF_NOTS(1,"%u ", tcb->task_id); + tcb = tcb->p_dlnk; + i++; + } while (tcb && i < os_maxtaskrun); + REL_TRACE_NOTS(0," "); + if (tcb) { + REL_TRACE_NOTS(2,"*** Error: List corrupted? count=%u next=0x%08X\n", i, (uint32_t)tcb); + } + } else { + REL_TRACE_NOTS(0,""); + } + REL_TRACE_IMM_NOTS(0," "); +} + +FLASH_TEXT_LOC +void rtx_show_all_threads(void) +{ + int i; +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) + if (hal_trace_crash_dump_onprocess()){ + for (i = 0; i < 10; i++){ + REL_TRACE_IMM_NOTS(0," "); + REL_TRACE_IMM_NOTS(0," \n"); + hal_sys_timer_delay(MS_TO_TICKS(200)); + } + } +#endif + + REL_TRACE_NOTS(0,"Task List:"); + for (i = 0; i < os_maxtaskrun; i++) { + if (os_active_TCB[i]) { + rt_tsk_show(os_active_TCB[i]); + REL_TRACE_IMM_NOTS(0," "); +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) + if (hal_trace_crash_dump_onprocess()){ + hal_sys_timer_delay(MS_TO_TICKS(500)); + } +#endif + } + } + rt_tsk_show(&os_idle_TCB); + REL_TRACE_IMM_NOTS(0," "); + + rtx_show_current_thread(); + rtx_show_ready_threads(); + rtx_show_delay_threads(); +} + +#if __RTX_CPU_STATISTICS__ + +#if TASK_HUNG_CHECK_ENABLED +FLASH_TEXT_LOC NOINLINE +static void print_hung_task(const P_TCB tcb, U32 curr_time) +{ + REL_TRACE_IMM_NOTS(2,"Task \"%s\" blocked for %dms", + tcb->name==NULL ? (tcb->task_id == 1 ? "main" : "null") : (char *)tcb->name, + curr_time - tcb->swap_out_time); + ASSERT(0, "Find task hung"); +} + +static void check_hung_task(const P_TCB tcb) +{ + uint32_t curr_hwticks, curr_time; + + if (!tcb->hung_check) + return; + + curr_hwticks = hal_sys_timer_get(); + curr_time = HWTICKS_TO_MS(curr_hwticks); + if((curr_time - tcb->swap_out_time) > tcb->hung_check_timeout) { + print_hung_task(tcb, curr_time); + } +} + +void check_hung_tasks(void) +{ + int i; + + for (i = 0; i < os_maxtaskrun; i++) { + if (os_active_TCB[i]) { + P_TCB tcb = os_active_TCB[i]; + check_hung_task(tcb); + } + } +} +#endif + +static inline void print_task_sw_statitics(P_TCB tcb) +{ + /* + REL_TRACE_NOTS(3,"--- Task swap in:%d out=%d runings %d", + tcb->swap_in_time, + tcb->swap_out_time, + tcb->rtime); + */ +} + +FLASH_TEXT_LOC +static void _rtx_show_thread_usage(P_TCB tcb, U32 sample_time) +{ + if (tcb) { + if (tcb->cb_type == TCB && ((tcb->task_id >= 1 && tcb->task_id <= os_maxtaskrun)) && + tcb->ptask && tcb->stack) { + REL_TRACE_NOTS(5,"--- Task id:%d task_name=%s cpu=%%%d", + tcb->task_id, + tcb->name==NULL ? (tcb->task_id == 1 ? "main" : "null") : (char *)tcb->name, + sample_time != 0 ? ((tcb->rtime - task_rtime[tcb->task_id]) * 100 / sample_time) : 0); + print_task_sw_statitics(tcb); + task_rtime[tcb->task_id] = tcb->rtime; + } else if (tcb->task_id == 255 ) { + REL_TRACE_NOTS(5,"--- Task id:%d task_name=%s cpu=%%%d", + tcb->task_id, + "idle", + sample_time != 0 ? (tcb->rtime - task_rtime[0]) * 100 / sample_time : 0); + print_task_sw_statitics(tcb); + task_rtime[0] = tcb->rtime; + } else { + REL_TRACE_NOTS(0,"--- Task BAD"); + } + } else { + REL_TRACE_NOTS(0,"--- Task NONE"); + } +} + +FLASH_TEXT_LOC +void rtx_show_all_threads_usage(void) +{ + int i; + static BOOL first_time = 1; + uint32_t sample_time; + static U32 start_sample_time = 0; + + if (first_time) { + for (i = 0; i < os_maxtaskrun; i++) { + if (os_active_TCB[i]) { + P_TCB tcb = os_active_TCB[i]; + task_rtime[tcb->task_id] = tcb->rtime; + } + } + task_rtime[0] = os_idle_TCB.rtime; + start_sample_time = rtx_get_hwticks(); + first_time = 0; + return; + } + + sample_time = HWTICKS_TO_MS(rtx_get_hwticks() - start_sample_time); + REL_TRACE_IMM_NOTS(0," "); + REL_TRACE_NOTS(0,"Task List:"); + for (i = 0; i < os_maxtaskrun; i++) { + if (os_active_TCB[i]) { + _rtx_show_thread_usage(os_active_TCB[i], sample_time); + } + } + _rtx_show_thread_usage(&os_idle_TCB, sample_time); + start_sample_time = rtx_get_hwticks(); + REL_TRACE_IMM_NOTS(0," "); +} + +#endif + +/* + * health time period for idle thread scheduled + */ +#define TASK_IDLE_HEALTH_PERIOD (60 * 1000) + +FLASH_TEXT_LOC +int rtx_task_idle_health_check(void) +{ + P_TCB tcb = &os_idle_TCB; + uint32_t now, period; + + now = HWTICKS_TO_MS(rtx_get_hwticks()); + + if (now >= tcb->swap_in_time) { + period = now - tcb->swap_in_time; + } else { + uint64_t temp; + temp = now + HWTICKS_TO_MS((-1u)); + period = temp - tcb->swap_in_time; + } + + if ( period > TASK_IDLE_HEALTH_PERIOD) { + REL_TRACE_NOTS(1,"--- Task idle hung %d seconds", period / 1000); + return -1; + } + return 0; +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Task.h b/rtos/rtx/TARGET_CORTEX_M/rt_Task.h new file mode 100644 index 0000000..b84e615 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Task.h @@ -0,0 +1,74 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TASK.H + * Purpose: Task functions and system start up. + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +/* Definitions */ +#define __CMSIS_RTOS 1 + +/* Values for 'state' */ +#define INACTIVE 0 +#define READY 1 +#define RUNNING 2 +#define WAIT_DLY 3 +#define WAIT_ITV 4 +#define WAIT_OR 5 +#define WAIT_AND 6 +#define WAIT_SEM 7 +#define WAIT_MBX 8 +#define WAIT_MUT 9 + +/* Return codes */ +#define OS_R_TMO 0x01 +#define OS_R_EVT 0x02 +#define OS_R_SEM 0x03 +#define OS_R_MBX 0x04 +#define OS_R_MUT 0x05 + +#define OS_R_OK 0x00 +#define OS_R_NOK 0xff + +/* Variables */ +extern struct OS_TSK os_tsk; +extern struct OS_TCB os_idle_TCB; + +/* Functions */ +extern void rt_switch_req (P_TCB p_new); +extern void rt_dispatch (P_TCB next_TCB); +extern void rt_block (U16 timeout, U8 block_state); +extern void rt_tsk_pass (void); +extern OS_TID rt_tsk_self (void); +extern OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio); +extern OS_RESULT rt_tsk_delete (OS_TID task_id); +extern void rt_sys_init (void); +extern void rt_sys_start (void); +extern void rt_tsk_show (P_TCB tcb); diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Time.c b/rtos/rtx/TARGET_CORTEX_M/rt_Time.c new file mode 100644 index 0000000..b02cceb --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Time.c @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIME.C + * Purpose: Delay and interval wait functions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 "rt_TypeDef.h" +#include "RTX_Conf.h" +#include "rt_Task.h" +#include "rt_Time.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* Free running system tick counter */ +U32 os_time; + + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + + +/*--------------------------- rt_time_get -----------------------------------*/ + +U32 rt_time_get (void) { + /* Get system time tick */ + return (os_time); +} + + +/*--------------------------- rt_dly_wait -----------------------------------*/ + +void rt_dly_wait (U16 delay_time) { + /* Delay task by "delay_time" */ + rt_block (delay_time, WAIT_DLY); +} + + +/*--------------------------- rt_itv_set ------------------------------------*/ + +void rt_itv_set (U16 interval_time) { + /* Set interval length and define start of first interval */ + os_tsk.run->interval_time = interval_time; + os_tsk.run->delta_time = interval_time + (U16)os_time; +} + + +/*--------------------------- rt_itv_wait -----------------------------------*/ + +void rt_itv_wait (void) { + /* Wait for interval end and define start of next one */ + U16 delta; + + delta = os_tsk.run->delta_time - (U16)os_time; + os_tsk.run->delta_time += os_tsk.run->interval_time; + if ((delta & 0x8000) == 0) { + rt_block (delta, WAIT_ITV); + } +} + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Time.h b/rtos/rtx/TARGET_CORTEX_M/rt_Time.h new file mode 100644 index 0000000..2c352e1 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_Time.h @@ -0,0 +1,60 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIME.H + * Purpose: Delay and interval wait functions definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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. + *---------------------------------------------------------------------------*/ + +// +// SysTick Timer Configuration +// ============================== +// +// Timer clock value [Hz] <1-1000000000> +// Defines the timer clock value. +// Default: 6000000 (6MHz) +#ifdef CALIB_SLOW_TIMER + #define OS_CLOCK (CONFIG_SYSTICK_HZ * (OS_CLOCK_NOMINAL / CONFIG_SYSTICK_HZ_NOMINAL)) +#else + #define OS_CLOCK OS_CLOCK_NOMINAL +#endif + +/* Variables */ +extern U32 os_time; + +/* Functions */ +extern U32 rt_time_get (void); +extern void rt_dly_wait (U16 delay_time); +extern void rt_itv_set (U16 interval_time); +extern void rt_itv_wait (void); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ + diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h b/rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h new file mode 100644 index 0000000..27416c5 --- /dev/null +++ b/rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h @@ -0,0 +1,128 @@ +/*---------------------------------------------------------------------------- + * RL-ARM - RTX + *---------------------------------------------------------------------------- + * Name: RT_TYPEDEF.H + * Purpose: Type Definitions + * Rev.: V4.60 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM 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 RT_TYPE_DEF_H +#define RT_TYPE_DEF_H + +#include "os_tcb.h" + +typedef U32 OS_TID; +typedef void *OS_ID; +typedef U32 OS_RESULT; + +#define TCB_STACKF 32 /* 'stack_frame' offset */ +#define TCB_TSTACK 40 /* 'tsk_stack' offset */ + +typedef struct OS_PSFE { /* Post Service Fifo Entry */ + void *id; /* Object Identification */ + U32 arg; /* Object Argument */ +} *P_PSFE; + +typedef struct OS_PSQ { /* Post Service Queue */ + U8 first; /* FIFO Head Index */ + U8 last; /* FIFO Tail Index */ + U8 count; /* Number of stored items in FIFO */ + U8 size; /* FIFO Size */ + struct OS_PSFE q[1]; /* FIFO Content */ +} *P_PSQ; + +typedef struct OS_TSK { + P_TCB run; /* Current running task */ + P_TCB new_tsk; /* Scheduled task to run */ +} *P_TSK; + +typedef struct OS_ROBIN { /* Round Robin Control */ + P_TCB task; /* Round Robin task */ + U16 time; /* Round Robin switch time */ + U16 tout; /* Round Robin timeout */ +} *P_ROBIN; + +typedef struct OS_XCB { + U8 cb_type; /* Control Block Type */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ +} *P_XCB; + +typedef struct OS_MCB { + U8 cb_type; /* Control Block Type */ + U8 state; /* State flag variable */ + U8 isr_st; /* State flag variable for isr functions */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for message */ + U16 first; /* Index of the message list begin */ + U16 last; /* Index of the message list end */ + U16 count; /* Actual number of stored messages */ + U16 size; /* Maximum number of stored messages */ + void *msg[1]; /* FIFO for Message pointers 1st element */ +} *P_MCB; + +typedef struct OS_SCB { + U8 cb_type; /* Control Block Type */ + U8 mask; /* Semaphore token mask */ + U16 tokens; /* Semaphore tokens */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for tokens */ +} *P_SCB; + +typedef struct OS_MUCB { + U8 cb_type; /* Control Block Type */ + U8 prio; /* Owner task default priority */ + U16 level; /* Call nesting level */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for mutex */ + struct OS_TCB *owner; /* Mutex owner task */ +} *P_MUCB; + +typedef struct OS_XTMR { + struct OS_TMR *next; + U16 tcnt; +} *P_XTMR; + +typedef struct OS_TMR { + struct OS_TMR *next; /* Link pointer to Next timer */ + U16 tcnt; /* Timer delay count */ + U16 info; /* User defined call info */ +} *P_TMR; + +typedef struct OS_BM { + void *free; /* Pointer to first free memory block */ + void *end; /* Pointer to memory block end */ + U32 blk_size; /* Memory block size */ +} *P_BM; + +/* Definitions */ +#define __TRUE 1 +#define __FALSE 0 +#define NULL ((void *) 0) + +#endif diff --git a/rtos/rtx5/ARM/irq_armv8mbl.s b/rtos/rtx5/ARM/irq_armv8mbl.s new file mode 100644 index 0000000..5a0d1f0 --- /dev/null +++ b/rtos/rtx5/ARM/irq_armv8mbl.s @@ -0,0 +1,333 @@ +;/* +; * Copyright (c) 2016-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: ARMv8M Baseline Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + + IF :LNOT::DEF:DOMAIN_NS +DOMAIN_NS EQU 0 + ENDIF + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SM_OFS EQU 48 ; TCB.stack_mem offset +TCB_SP_OFS EQU 56 ; TCB.SP offset +TCB_SF_OFS EQU 34 ; TCB.stack_frame offset +TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset + + + PRESERVE8 + THUMB + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.text|, CODE, READONLY + + +SVC_Handler PROC + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + IF :DEF:MPU_LOAD + IMPORT osRtxMpuLoad + ENDIF + IF DOMAIN_NS = 1 + IMPORT TZ_LoadContext_S + IMPORT TZ_StoreContext_S + ENDIF + + MOV R0,LR + LSRS R0,R0,#3 ; Determine return stack from EXC_RETURN bit 2 + BCC SVC_MSP ; Branch if return stack is MSP + MRS R0,PSP ; Get PSP + +SVC_Number + LDR R1,[R0,#24] ; Load saved PC from stack + SUBS R1,R1,#2 ; Point to SVC instruction + LDRB R1,[R1] ; Load SVC number + CMP R1,#0 + BNE SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R7 ; Call service function + POP {R2,R3} ; Restore SP and EXC_RETURN + STMIA R2!,{R0-R1} ; Store function return values + MOV LR,R3 ; Set EXC_RETURN + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ SVC_Exit ; Branch when threads are the same + + CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + IF DOMAIN_NS = 1 + LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context + PUSH {R1,R2,R3,R7} ; Save registers + MOV R7,LR ; Get EXC_RETURN + BL TZ_StoreContext_S ; Store secure context + MOV LR,R7 ; Set EXC_RETURN + POP {R1,R2,R3,R7} ; Restore registers + ENDIF + +SVC_ContextSave1 + MRS R0,PSP ; Get PSP + SUBS R0,R0,#32 ; Calculate SP + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STMIA R0!,{R4-R7} ; Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save R8..R11 + +SVC_ContextSave2 + MOV R0,LR ; Get EXC_RETURN + ADDS R1,R1,#TCB_SF_OFS ; Adjust address + STRB R0,[R1] ; Store stack frame information + +SVC_ContextSwitch + SUBS R3,R3,#8 ; Adjust address + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + + IF :DEF:MPU_LOAD + PUSH {R2,R3} ; Save registers + MOV R0,R2 ; osRtxMpuLoad parameter + BL osRtxMpuLoad ; Load MPU for next thread + POP {R2,R3} ; Restore registers + ENDIF + +SVC_ContextRestore + IF DOMAIN_NS = 1 + LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context + PUSH {R2,R3} ; Save registers + BL TZ_LoadContext_S ; Load secure context + POP {R2,R3} ; Restore registers + ENDIF + +SVC_ContextRestore1 + MOV R1,R2 + ADDS R1,R1,#TCB_SF_OFS ; Adjust address + LDRB R0,[R1] ; Load stack frame information + MOVS R1,#0xFF + MVNS R1,R1 ; R1=0xFFFFFF00 + ORRS R0,R1 + MOV LR,R0 ; Set EXC_RETURN + + IF DOMAIN_NS = 1 + LSLS R0,R0,#25 ; Check domain of interrupted thread + BPL SVC_ContextRestore2 ; Branch if non-secure + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + MSR PSP,R0 ; Set PSP + BX LR ; Exit from handler + ELSE + LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base + MSR PSPLIM,R0 ; Set PSPLIM + ENDIF + +SVC_ContextRestore2 + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ADDS R0,R0,#16 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Set PSP + SUBS R0,R0,#32 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R4..R7 + +SVC_Exit + BX LR ; Exit from handler + +SVC_MSP + MRS R0,MSP ; Get MSP + B SVC_Number + +SVC_User + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Exit ; Branch if out of range + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LSLS R1,R1,#2 + LDR R3,[R2,R1] ; Load address of SVC function + MOV R12,R3 + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R12 ; Call service function + POP {R2,R3} ; Restore SP and EXC_RETURN + STR R0,[R2] ; Store function return value + MOV LR,R3 ; Set EXC_RETURN + + BX LR ; Return from handler + + ALIGN + ENDP + + +PendSV_Handler PROC + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B Sys_Context + + ALIGN + ENDP + + +SysTick_Handler PROC + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B Sys_Context + + ALIGN + ENDP + + +Sys_Context PROC + EXPORT Sys_Context + IMPORT osRtxInfo + IF :DEF:MPU_LOAD + IMPORT osRtxMpuLoad + ENDIF + IF DOMAIN_NS = 1 + IMPORT TZ_LoadContext_S + IMPORT TZ_StoreContext_S + ENDIF + + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ Sys_ContextExit ; Branch when threads are the same + +Sys_ContextSave + IF DOMAIN_NS = 1 + LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context + PUSH {R1,R2,R3,R7} ; Save registers + MOV R7,LR ; Get EXC_RETURN + BL TZ_StoreContext_S ; Store secure context + MOV LR,R7 ; Set EXC_RETURN + POP {R1,R2,R3,R7} ; Restore registers + MOV R0,LR ; Get EXC_RETURN + LSLS R0,R0,#25 ; Check domain of interrupted thread + BPL Sys_ContextSave1 ; Branch if non-secure + MRS R0,PSP ; Get PSP + STR R0,[R1,#TCB_SP_OFS] ; Store SP + B Sys_ContextSave2 + ENDIF + +Sys_ContextSave1 + MRS R0,PSP ; Get PSP + SUBS R0,R0,#32 ; Adjust address + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STMIA R0!,{R4-R7} ; Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save R8..R11 + +Sys_ContextSave2 + MOV R0,LR ; Get EXC_RETURN + ADDS R1,R1,#TCB_SF_OFS ; Adjust address + STRB R0,[R1] ; Store stack frame information + +Sys_ContextSwitch + SUBS R3,R3,#8 ; Adjust address + STR R2,[R3] ; osRtxInfo.run: curr = next + + IF :DEF:MPU_LOAD + PUSH {R2,R3} ; Save registers + MOV R0,R2 ; osRtxMpuLoad parameter + BL osRtxMpuLoad ; Load MPU for next thread + POP {R2,R3} ; Restore registers + ENDIF + +Sys_ContextRestore + IF DOMAIN_NS = 1 + LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context + PUSH {R2,R3} ; Save registers + BL TZ_LoadContext_S ; Load secure context + POP {R2,R3} ; Restore registers + ENDIF + +Sys_ContextRestore1 + MOV R1,R2 + ADDS R1,R1,#TCB_SF_OFS ; Adjust offset + LDRB R0,[R1] ; Load stack frame information + MOVS R1,#0xFF + MVNS R1,R1 ; R1=0xFFFFFF00 + ORRS R0,R1 + MOV LR,R0 ; Set EXC_RETURN + + IF DOMAIN_NS = 1 + LSLS R0,R0,#25 ; Check domain of interrupted thread + BPL Sys_ContextRestore2 ; Branch if non-secure + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + MSR PSP,R0 ; Set PSP + BX LR ; Exit from handler + ELSE + LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base + MSR PSPLIM,R0 ; Set PSPLIM + ENDIF + +Sys_ContextRestore2 + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ADDS R0,R0,#16 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Set PSP + SUBS R0,R0,#32 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R4..R7 + +Sys_ContextExit + BX LR ; Exit from handler + + ALIGN + ENDP + + + END diff --git a/rtos/rtx5/ARM/irq_armv8mbl_ns.s b/rtos/rtx5/ARM/irq_armv8mbl_ns.s new file mode 100644 index 0000000..e94cb56 --- /dev/null +++ b/rtos/rtx5/ARM/irq_armv8mbl_ns.s @@ -0,0 +1,3 @@ +DOMAIN_NS EQU 1 + INCLUDE irq_armv8mbl.s + END diff --git a/rtos/rtx5/ARM/irq_armv8mml.s b/rtos/rtx5/ARM/irq_armv8mml.s new file mode 100644 index 0000000..b0c88f9 --- /dev/null +++ b/rtos/rtx5/ARM/irq_armv8mml.s @@ -0,0 +1,306 @@ +;/* +; * Copyright (c) 2016-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: ARMv8M Mainline Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + + IF :LNOT::DEF:DOMAIN_NS +DOMAIN_NS EQU 0 + ENDIF + + IF ({FPU}="FPv5-SP") || ({FPU}="FPv5_D16") +__FPU_USED EQU 1 + ELSE +__FPU_USED EQU 0 + ENDIF + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SM_OFS EQU 48 ; TCB.stack_mem offset +TCB_SP_OFS EQU 56 ; TCB.SP offset +TCB_SF_OFS EQU 34 ; TCB.stack_frame offset +TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset + + + PRESERVE8 + THUMB + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.text|, CODE, READONLY + + +SVC_Handler PROC + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + IF :DEF:MPU_LOAD + IMPORT osRtxMpuLoad + ENDIF + IF DOMAIN_NS = 1 + IMPORT TZ_LoadContext_S + IMPORT TZ_StoreContext_S + ENDIF + + TST LR,#0x04 ; Determine return stack from EXC_RETURN bit 2 + ITE EQ + MRSEQ R0,MSP ; Get MSP if return stack is MSP + MRSNE R0,PSP ; Get PSP if return stack is PSP + + LDR R1,[R0,#24] ; Load saved PC from stack + LDRB R1,[R1,#-2] ; Load SVC number + CMP R1,#0 + BNE SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDM R0,{R0-R3,R12} ; Load function parameters and address from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STM R12,{R0-R1} ; Store function return values + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + IT EQ + BXEQ LR ; Exit when threads are the same + + IF __FPU_USED = 1 + CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted + TST LR,#0x10 ; Check if extended stack frame + BNE SVC_ContextSwitch + LDR R1,=0xE000EF34 ; FPCCR Address + LDR R0,[R1] ; Load FPCCR + BIC R0,R0,#1 ; Clear LSPACT (Lazy state) + STR R0,[R1] ; Store FPCCR + B SVC_ContextSwitch + ELSE + CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted + ENDIF + +SVC_ContextSave + IF DOMAIN_NS = 1 + LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context + PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN + BL TZ_StoreContext_S ; Store secure context + POP {R1,R2,R3,LR} ; Restore registers and EXC_RETURN + ENDIF + +SVC_ContextSave1 + MRS R0,PSP ; Get PSP + STMDB R0!,{R4-R11} ; Save R4..R11 + IF __FPU_USED = 1 + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31 + ENDIF + +SVC_ContextSave2 + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STRB LR,[R1,#TCB_SF_OFS] ; Store stack frame information + +SVC_ContextSwitch + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + + IF :DEF:MPU_LOAD + PUSH {R2,R3} ; Save registers + MOV R0,R2 ; osRtxMpuLoad parameter + BL osRtxMpuLoad ; Load MPU for next thread + POP {R2,R3} ; Restore registers + ENDIF + +SVC_ContextRestore + IF DOMAIN_NS = 1 + LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context + PUSH {R2,R3} ; Save registers + BL TZ_LoadContext_S ; Load secure context + POP {R2,R3} ; Restore registers + ENDIF + +SVC_ContextRestore1 + LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base + LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information + MSR PSPLIM,R0 ; Set PSPLIM + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN + + IF DOMAIN_NS = 1 + TST LR,#0x40 ; Check domain of interrupted thread + BNE SVC_ContextRestore2 ; Branch if secure + ENDIF + + IF __FPU_USED = 1 + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 + ENDIF + LDMIA R0!,{R4-R11} ; Restore R4..R11 + +SVC_ContextRestore2 + MSR PSP,R0 ; Set PSP + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Exit ; Branch if out of range + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDR R12,[R2,R1,LSL #2] ; Load address of SVC function + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STR R0,[R12] ; Store function return value + + BX LR ; Return from handler + + ALIGN + ENDP + + +PendSV_Handler PROC + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,LR} ; Restore EXC_RETURN + B Sys_Context + + ALIGN + ENDP + + +SysTick_Handler PROC + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,LR} ; Restore EXC_RETURN + B Sys_Context + + ALIGN + ENDP + + +Sys_Context PROC + EXPORT Sys_Context + IMPORT osRtxInfo + IF :DEF:MPU_LOAD + IMPORT osRtxMpuLoad + ENDIF + IF DOMAIN_NS = 1 + IMPORT TZ_LoadContext_S + IMPORT TZ_StoreContext_S + ENDIF + + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + IT EQ + BXEQ LR ; Exit when threads are the same + +Sys_ContextSave + IF DOMAIN_NS = 1 + LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context + PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN + BL TZ_StoreContext_S ; Store secure context + POP {R1,R2,R3,LR} ; Restore registers and EXC_RETURN + TST LR,#0x40 ; Check domain of interrupted thread + IT NE + MRSNE R0,PSP ; Get PSP + BNE Sys_ContextSave2 ; Branch if secure + ENDIF + +Sys_ContextSave1 + MRS R0,PSP ; Get PSP + STMDB R0!,{R4-R11} ; Save R4..R11 + IF __FPU_USED = 1 + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31 + ENDIF + +Sys_ContextSave2 + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STRB LR,[R1,#TCB_SF_OFS] ; Store stack frame information + +Sys_ContextSwitch + STR R2,[R3] ; osRtxInfo.run: curr = next + + IF :DEF:MPU_LOAD + PUSH {R2,R3} ; Save registers + MOV R0,R2 ; osRtxMpuLoad parameter + BL osRtxMpuLoad ; Load MPU for next thread + POP {R2,R3} ; Restore registers + ENDIF + +Sys_ContextRestore + IF DOMAIN_NS = 1 + LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context + PUSH {R2,R3} ; Save registers + BL TZ_LoadContext_S ; Load secure context + POP {R2,R3} ; Restore registers + ENDIF + +Sys_ContextRestore1 + LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base + LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information + MSR PSPLIM,R0 ; Set PSPLIM + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN + + IF DOMAIN_NS = 1 + TST LR,#0x40 ; Check domain of interrupted thread + BNE Sys_ContextRestore2 ; Branch if secure + ENDIF + + IF __FPU_USED = 1 + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 + ENDIF + LDMIA R0!,{R4-R11} ; Restore R4..R11 + +Sys_ContextRestore2 + MSR PSP,R0 ; Set PSP + +Sys_ContextExit + BX LR ; Exit from handler + + ALIGN + ENDP + + + END diff --git a/rtos/rtx5/ARM/irq_armv8mml_ns.s b/rtos/rtx5/ARM/irq_armv8mml_ns.s new file mode 100644 index 0000000..89a1414 --- /dev/null +++ b/rtos/rtx5/ARM/irq_armv8mml_ns.s @@ -0,0 +1,3 @@ +DOMAIN_NS EQU 1 + INCLUDE irq_armv8mml.s + END diff --git a/rtos/rtx5/ARM/irq_ca.s b/rtos/rtx5/ARM/irq_ca.s new file mode 100644 index 0000000..e54c42d --- /dev/null +++ b/rtos/rtx5/ARM/irq_ca.s @@ -0,0 +1,458 @@ +;/* +; * Copyright (c) 2013-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-A Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + +MODE_FIQ EQU 0x11 +MODE_IRQ EQU 0x12 +MODE_SVC EQU 0x13 +MODE_ABT EQU 0x17 +MODE_UND EQU 0x1B + +CPSR_BIT_T EQU 0x20 + +K_STATE_RUNNING EQU 2 ; osKernelState_t::osKernelRunning +I_K_STATE_OFS EQU 8 ; osRtxInfo.kernel.state offset +I_TICK_IRQN_OFS EQU 16 ; osRtxInfo.tick_irqn offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SP_FRAME EQU 34 ; osRtxThread_t.stack_frame offset +TCB_SP_OFS EQU 56 ; osRtxThread_t.sp offset + + + PRESERVE8 + ARM + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.data|, DATA, READWRITE + EXPORT IRQ_PendSV +IRQ_NestLevel DCD 0 ; IRQ nesting level counter +IRQ_PendSV DCB 0 ; Pending SVC flag + + + AREA |.text|, CODE, READONLY + + +Undef_Handler\ + PROC + EXPORT Undef_Handler + IMPORT CUndefHandler + + SRSFD SP!, #MODE_UND + PUSH {R0-R4, R12} ; Save APCS corruptible registers to UND mode stack + + MRS R0, SPSR + TST R0, #CPSR_BIT_T ; Check mode + MOVEQ R1, #4 ; R1 = 4 ARM mode + MOVNE R1, #2 ; R1 = 2 Thumb mode + SUB R0, LR, R1 + LDREQ R0, [R0] ; ARM mode - R0 points to offending instruction + BEQ Undef_Cont + + ; Thumb instruction + ; Determine if it is a 32-bit Thumb instruction + LDRH R0, [R0] + MOV R2, #0x1C + CMP R2, R0, LSR #11 + BHS Undef_Cont ; 16-bit Thumb instruction + + ; 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction + LDRH R2, [LR] + ORR R0, R2, R0, LSL #16 +Undef_Cont + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + ; R0 =Offending instruction, R1 =2(Thumb) or =4(ARM) + BL CUndefHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + LDR LR, [SP, #24] ; Restore stacked LR and possibly adjust for retry + SUB LR, LR, R0 + LDR R0, [SP, #28] ; Restore stacked SPSR + MSR SPSR_CXSF, R0 + CLREX ; Clear exclusive monitor + POP {R0-R4, R12} ; Restore stacked APCS registers + ADD SP, SP, #8 ; Adjust SP for already-restored banked registers + MOVS PC, LR + + ENDP + + +PAbt_Handler\ + PROC + EXPORT PAbt_Handler + IMPORT CPAbtHandler + + SUB LR, LR, #4 ; Pre-adjust LR + SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack + MRC p15, 0, R0, c5, c0, 1 ; IFSR + MRC p15, 0, R1, c6, c0, 2 ; IFAR + + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + BL CPAbtHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + CLREX ; Clear exclusive monitor + POP {R0-R4, R12} ; Restore stack APCS registers + RFEFD SP! ; Return from exception + + ENDP + + +DAbt_Handler\ + PROC + EXPORT DAbt_Handler + IMPORT CDAbtHandler + + SUB LR, LR, #8 ; Pre-adjust LR + SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack + MRC p15, 0, R0, c5, c0, 0 ; DFSR + MRC p15, 0, R1, c6, c0, 0 ; DFAR + + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + BL CDAbtHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + CLREX ; Clear exclusive monitor + POP {R0-R4, R12} ; Restore stacked APCS registers + RFEFD SP! ; Return from exception + + ENDP + + +IRQ_Handler\ + PROC + EXPORT IRQ_Handler + IMPORT IRQ_GetActiveIRQ + IMPORT IRQ_GetHandler + IMPORT IRQ_EndOfInterrupt + + SUB LR, LR, #4 ; Pre-adjust LR + SRSFD SP!, #MODE_SVC ; Save LR_irq and SPSR_irq on to the SVC stack + CPS #MODE_SVC ; Change to SVC mode + PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + ADD R1, R1, #1 ; Increment IRQ nesting level + STR R1, [R0] + + MOV R3, SP ; Move SP into R3 + AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R3 ; Adjust stack + PUSH {R3, R4} ; Store stack adjustment(R3) and user data(R4) + + BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0 + MOV R4, R0 ; Move interrupt ID to R4 + + BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID + CMP R0, #0 ; Check if handler address is 0 + BEQ IRQ_End ; If 0, end interrupt and return + + CPSIE i ; Re-enable interrupts + BLX R0 ; Call IRQ handler + CPSID i ; Disable interrupts + +IRQ_End + MOV R0, R4 ; Move interrupt ID to R0 + BLX IRQ_EndOfInterrupt ; Signal end of interrupt + + POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 ; Unadjust stack + + BL osRtxContextSwitch ; Continue in context switcher + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + SUBS R1, R1, #1 ; Decrement IRQ nesting level + STR R1, [R0] + + CLREX ; Clear exclusive monitor for interrupted code + POP {R0-R3, R12, LR} ; Restore stacked APCS registers + RFEFD SP! ; Return from IRQ handler + + ENDP + + +SVC_Handler\ + PROC + EXPORT SVC_Handler + IMPORT IRQ_Disable + IMPORT IRQ_Enable + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + SRSFD SP!, #MODE_SVC ; Store SPSR_svc and LR_svc onto SVC stack + PUSH {R12, LR} + + MRS R12, SPSR ; Load SPSR + TST R12, #CPSR_BIT_T ; Thumb bit set? + LDRHNE R12, [LR,#-2] ; Thumb: load halfword + BICNE R12, R12, #0xFF00 ; extract SVC number + LDREQ R12, [LR,#-4] ; ARM: load word + BICEQ R12, R12, #0xFF000000 ; extract SVC number + CMP R12, #0 ; Compare SVC number + BNE SVC_User ; Branch if User SVC + + PUSH {R0-R3} + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + ADD R1, R1, #1 ; Increment IRQ nesting level + STR R1, [R0] + + LDR R0, =osRtxInfo + LDR R1, [R0, #I_K_STATE_OFS] ; Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING ; Check osKernelRunning + BLT SVC_FuncCall ; Continue if kernel is not running + LDR R0, [R0, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + BLX IRQ_Disable ; Disable OS Tick interrupt +SVC_FuncCall + POP {R0-R3} + + LDR R12, [SP] ; Reload R12 from stack + + CPSIE i ; Re-enable interrupts + BLX R12 ; Branch to SVC function + CPSID i ; Disable interrupts + + SUB SP, SP, #4 + STM SP, {SP}^ ; Store SP_usr onto stack + POP {R12} ; Pop SP_usr into R12 + SUB R12, R12, #16 ; Adjust pointer to SP_usr + LDMDB R12, {R2,R3} ; Load return values from SVC function + PUSH {R0-R3} ; Push return values to stack + + LDR R0, =osRtxInfo + LDR R1, [R0, #I_K_STATE_OFS] ; Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING ; Check osKernelRunning + BLT SVC_ContextCheck ; Continue if kernel is not running + LDR R0, [R0, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + BLX IRQ_Enable ; Enable OS Tick interrupt + +SVC_ContextCheck + BL osRtxContextSwitch ; Continue in context switcher + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + SUB R1, R1, #1 ; Decrement IRQ nesting level + STR R1, [R0] + + CLREX ; Clear exclusive monitor + POP {R0-R3, R12, LR} ; Restore stacked APCS registers + RFEFD SP! ; Return from exception + +SVC_User + PUSH {R4, R5} + LDR R5,=osRtxUserSVC ; Load address of SVC table + LDR R4,[R5] ; Load SVC maximum number + CMP R12,R4 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + LDR R12,[R5,R12,LSL #2] ; Load SVC Function Address + BLX R12 ; Call SVC Function +SVC_Done + CLREX ; Clear exclusive monitor + POP {R4, R5, R12, LR} + RFEFD SP! ; Return from exception + + ENDP + + +osRtxContextSwitch\ + PROC + EXPORT osRtxContextSwitch + IMPORT osRtxPendSV_Handler + IMPORT osRtxInfo + IMPORT IRQ_Disable + IMPORT IRQ_Enable + + PUSH {LR} + + ; Check interrupt nesting level + LDR R0, =IRQ_NestLevel + LDR R1, [R0] ; Load IRQ nest level + CMP R1, #1 + BNE osRtxContextExit ; Nesting interrupts, exit context switcher + + LDR R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run + LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next + LDR R2, =IRQ_PendSV ; Load address of IRQ_PendSV flag + LDRB R3, [R2] ; Load PendSV flag + + CMP R0, R1 ; Check if context switch is required + BNE osRtxContextCheck ; Not equal, check if context save required + CMP R3, #1 ; Compare IRQ_PendSV value + BNE osRtxContextExit ; No post processing (and no context switch requested) + +osRtxContextCheck + STR R1, [R12] ; Store run.next as run.curr + ; R0 = curr, R1 = next, R2 = &IRQ_PendSV, R3 = IRQ_PendSV, R12 = &osRtxInfo.thread.run + PUSH {R1-R3, R12} + + CMP R0, #0 ; Is osRtxInfo.thread.run.curr == 0 + BEQ osRtxPostProcess ; Current deleted, skip context save + +osRtxContextSave + MOV LR, R0 ; Move &osRtxInfo.thread.run.curr to LR + MOV R0, SP ; Move SP_svc into R0 + ADD R0, R0, #20 ; Adjust SP_svc to R0 of the basic frame + SUB SP, SP, #4 + STM SP, {SP}^ ; Save SP_usr to current stack + POP {R1} ; Pop SP_usr into R1 + + SUB R1, R1, #64 ; Adjust SP_usr to R4 of the basic frame + STMIA R1!, {R4-R11} ; Save R4-R11 to user stack + LDMIA R0!, {R4-R8} ; Load stacked R0-R3,R12 into R4-R8 + STMIA R1!, {R4-R8} ; Store them to user stack + STM R1, {LR}^ ; Store LR_usr directly + ADD R1, R1, #4 ; Adjust user sp to PC + LDMIB R0!, {R5-R6} ; Load current PC, CPSR + STMIA R1!, {R5-R6} ; Restore user PC and CPSR + + SUB R1, R1, #64 ; Adjust SP_usr to stacked R4 + + ; Check if VFP state need to be saved + MRC p15, 0, R2, c1, c0, 2 ; VFP/NEON access enabled? (CPACR) + AND R2, R2, #0x00F00000 + CMP R2, #0x00F00000 + BNE osRtxContextSave1 ; Continue, no VFP + + VMRS R2, FPSCR + STMDB R1!, {R2,R12} ; Push FPSCR, maintain 8-byte alignment + + VSTMDB R1!, {D0-D15} ; Save D0-D15 + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + VSTMDB R1!, {D16-D31} ; Save D16-D31 + ENDIF + + LDRB R2, [LR, #TCB_SP_FRAME] ; Load osRtxInfo.thread.run.curr frame info + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + ORR R2, R2, #4 ; NEON state + ELSE + ORR R2, R2, #2 ; VFP state + ENDIF + STRB R2, [LR, #TCB_SP_FRAME] ; Store VFP/NEON state + +osRtxContextSave1 + STR R1, [LR, #TCB_SP_OFS] ; Store user sp to osRtxInfo.thread.run.curr + +osRtxPostProcess + ; RTX IRQ post processing check + POP {R8-R11} ; Pop R8 = run.next, R9 = &IRQ_PendSV, R10 = IRQ_PendSV, R11 = &osRtxInfo.thread.run + CMP R10, #1 ; Compare PendSV value + BNE osRtxContextRestore ; Skip post processing if not pending + + MOV R4, SP ; Move SP_svc into R4 + AND R4, R4, #4 ; Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R4 ; Adjust stack + + ; Disable OS Tick + LDR R5, =osRtxInfo ; Load address of osRtxInfo + LDR R5, [R5, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + MOV R0, R5 ; Set it as function parameter + BLX IRQ_Disable ; Disable OS Tick interrupt + MOV R6, #0 ; Set PendSV clear value + B osRtxPendCheck +osRtxPendExec + STRB R6, [R9] ; Clear PendSV flag + CPSIE i ; Re-enable interrupts + BLX osRtxPendSV_Handler ; Post process pending objects + CPSID i ; Disable interrupts +osRtxPendCheck + LDR R8, [R11, #4] ; Load osRtxInfo.thread.run.next + STR R8, [R11] ; Store run.next as run.curr + LDRB R0, [R9] ; Load PendSV flag + CMP R0, #1 ; Compare PendSV value + BEQ osRtxPendExec ; Branch to PendExec if PendSV is set + + ; Re-enable OS Tick + MOV R0, R5 ; Restore irqn as function parameter + BLX IRQ_Enable ; Enable OS Tick interrupt + + ADD SP, SP, R4 ; Restore stack adjustment + +osRtxContextRestore + LDR LR, [R8, #TCB_SP_OFS] ; Load next osRtxThread_t.sp + LDRB R2, [R8, #TCB_SP_FRAME] ; Load next osRtxThread_t.stack_frame + + ANDS R2, R2, #0x6 ; Check stack frame for VFP context + MRC p15, 0, R2, c1, c0, 2 ; Read CPACR + ANDEQ R2, R2, #0xFF0FFFFF ; VFP/NEON state not stacked, disable VFP/NEON + ORRNE R2, R2, #0x00F00000 ; VFP/NEON state is stacked, enable VFP/NEON + MCR p15, 0, R2, c1, c0, 2 ; Write CPACR + BEQ osRtxContextRestore1 ; No VFP + ISB ; Sync if VFP was enabled + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + VLDMIA LR!, {D16-D31} ; Restore D16-D31 + ENDIF + VLDMIA LR!, {D0-D15} ; Restore D0-D15 + LDR R2, [LR] + VMSR FPSCR, R2 ; Restore FPSCR + ADD LR, LR, #8 ; Adjust sp pointer to R4 + +osRtxContextRestore1 + LDMIA LR!, {R4-R11} ; Restore R4-R11 + ADD R12, LR, #32 ; Adjust sp and save it into R12 + PUSH {R12} ; Push sp onto stack + LDM SP, {SP}^ ; Restore SP_usr directly + ADD SP, SP, #4 ; Adjust SP_svc + LDMIA LR!, {R0-R3, R12} ; Load user registers R0-R3,R12 + STMIB SP!, {R0-R3, R12} ; Store them to SP_svc + LDM LR, {LR}^ ; Restore LR_usr directly + LDMIB LR!, {R0-R1} ; Load user registers PC,CPSR + ADD SP, SP, #4 + STMIB SP!, {R0-R1} ; Store them to SP_svc + SUB SP, SP, #32 ; Adjust SP_svc to stacked LR + +osRtxContextExit + POP {PC} ; Return + + ENDP + + END diff --git a/rtos/rtx5/ARM/irq_cm0.s b/rtos/rtx5/ARM/irq_cm0.s new file mode 100644 index 0000000..c5146b3 --- /dev/null +++ b/rtos/rtx5/ARM/irq_cm0.s @@ -0,0 +1,174 @@ +;/* +; * Copyright (c) 2013-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M0 Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset + + + PRESERVE8 + THUMB + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.text|, CODE, READONLY + + +SVC_Handler PROC + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + IF :DEF:MPU_LOAD + IMPORT osRtxMpuLoad + ENDIF + + MOV R0,LR + LSRS R0,R0,#3 ; Determine return stack from EXC_RETURN bit 2 + BCC SVC_MSP ; Branch if return stack is MSP + MRS R0,PSP ; Get PSP + +SVC_Number + LDR R1,[R0,#24] ; Load saved PC from stack + SUBS R1,R1,#2 ; Point to SVC instruction + LDRB R1,[R1] ; Load SVC number + CMP R1,#0 + BNE SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R7 ; Call service function + POP {R2,R3} ; Restore SP and EXC_RETURN + STMIA R2!,{R0-R1} ; Store function return values + MOV LR,R3 ; Set EXC_RETURN + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ SVC_Exit ; Branch when threads are the same + + CMP R1,#0 + BEQ SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + MRS R0,PSP ; Get PSP + SUBS R0,R0,#32 ; Calculate SP + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STMIA R0!,{R4-R7} ; Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save R8..R11 + +SVC_ContextSwitch + SUBS R3,R3,#8 ; Adjust address + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + + IF :DEF:MPU_LOAD + PUSH {R2,R3} ; Save registers + MOV R0,R2 ; osRtxMpuLoad parameter + BL osRtxMpuLoad ; Load MPU for next thread + POP {R2,R3} ; Restore registers + ENDIF + +SVC_ContextRestore + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ADDS R0,R0,#16 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Set PSP + SUBS R0,R0,#32 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R4..R7 + + MOVS R0,#~0xFFFFFFFD + MVNS R0,R0 ; Set EXC_RETURN value + BX R0 ; Exit from handler + +SVC_MSP + MRS R0,MSP ; Get MSP + B SVC_Number + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Exit ; Branch if out of range + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LSLS R1,R1,#2 + LDR R3,[R2,R1] ; Load address of SVC function + MOV R12,R3 + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R12 ; Call service function + POP {R2,R3} ; Restore SP and EXC_RETURN + STR R0,[R2] ; Store function return value + MOV LR,R3 ; Set EXC_RETURN + + BX LR ; Return from handler + + ALIGN + ENDP + + +PendSV_Handler PROC + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + ALIGN + ENDP + + +SysTick_Handler PROC + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + ALIGN + ENDP + + + END diff --git a/rtos/rtx5/ARM/irq_cm3.s b/rtos/rtx5/ARM/irq_cm3.s new file mode 100644 index 0000000..0a5ed34 --- /dev/null +++ b/rtos/rtx5/ARM/irq_cm3.s @@ -0,0 +1,146 @@ +;/* +; * Copyright (c) 2013-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M3 Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset + + + PRESERVE8 + THUMB + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.text|, CODE, READONLY + + +SVC_Handler PROC + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + IF :DEF:MPU_LOAD + IMPORT osRtxMpuLoad + ENDIF + + TST LR,#0x04 ; Determine return stack from EXC_RETURN bit 2 + ITE EQ + MRSEQ R0,MSP ; Get MSP if return stack is MSP + MRSNE R0,PSP ; Get PSP if return stack is PSP + + LDR R1,[R0,#24] ; Load saved PC from stack + LDRB R1,[R1,#-2] ; Load SVC number + CBNZ R1,SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDM R0,{R0-R3,R12} ; Load function parameters and address from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STM R12,{R0-R1} ; Store function return values + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + IT EQ + BXEQ LR ; Exit when threads are the same + + CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + STMDB R12!,{R4-R11} ; Save R4..R11 + STR R12,[R1,#TCB_SP_OFS] ; Store SP + +SVC_ContextSwitch + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + + IF :DEF:MPU_LOAD + PUSH {R2,R3} ; Save registers + MOV R0,R2 ; osRtxMpuLoad parameter + BL osRtxMpuLoad ; Load MPU for next thread + POP {R2,R3} ; Restore registers + ENDIF + +SVC_ContextRestore + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + LDMIA R0!,{R4-R11} ; Restore R4..R11 + MSR PSP,R0 ; Set PSP + + MVN LR,#~0xFFFFFFFD ; Set EXC_RETURN value + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Exit ; Branch if out of range + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDR R12,[R2,R1,LSL #2] ; Load address of SVC function + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STR R0,[R12] ; Store function return value + + BX LR ; Return from handler + + ALIGN + ENDP + + +PendSV_Handler PROC + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + ALIGN + ENDP + + +SysTick_Handler PROC + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + ALIGN + ENDP + + + END diff --git a/rtos/rtx5/ARM/irq_cm4f.s b/rtos/rtx5/ARM/irq_cm4f.s new file mode 100644 index 0000000..7d405b7 --- /dev/null +++ b/rtos/rtx5/ARM/irq_cm4f.s @@ -0,0 +1,162 @@ +;/* +; * Copyright (c) 2013-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M4F Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset +TCB_SF_OFS EQU 34 ; TCB.stack_frame offset + + + PRESERVE8 + THUMB + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.text|, CODE, READONLY + + +SVC_Handler PROC + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + IF :DEF:MPU_LOAD + IMPORT osRtxMpuLoad + ENDIF + + TST LR,#0x04 ; Determine return stack from EXC_RETURN bit 2 + ITE EQ + MRSEQ R0,MSP ; Get MSP if return stack is MSP + MRSNE R0,PSP ; Get PSP if return stack is PSP + + LDR R1,[R0,#24] ; Load saved PC from stack + LDRB R1,[R1,#-2] ; Load SVC number + CBNZ R1,SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDM R0,{R0-R3,R12} ; Load function parameters and address from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STM R12,{R0-R1} ; Store function return values + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + IT EQ + BXEQ LR ; Exit when threads are the same + + CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted + TST LR,#0x10 ; Check if extended stack frame + BNE SVC_ContextSwitch + LDR R1,=0xE000EF34 ; FPCCR Address + LDR R0,[R1] ; Load FPCCR + BIC R0,R0,#1 ; Clear LSPACT (Lazy state) + STR R0,[R1] ; Store FPCCR + B SVC_ContextSwitch + +SVC_ContextSave + STMDB R12!,{R4-R11} ; Save R4..R11 + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 + STR R12,[R1,#TCB_SP_OFS] ; Store SP + STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information + +SVC_ContextSwitch + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + + IF :DEF:MPU_LOAD + PUSH {R2,R3} ; Save registers + MOV R0,R2 ; osRtxMpuLoad parameter + BL osRtxMpuLoad ; Load MPU for next thread + POP {R2,R3} ; Restore registers + ENDIF + +SVC_ContextRestore + LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN + + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 + LDMIA R0!,{R4-R11} ; Restore R4..R11 + MSR PSP,R0 ; Set PSP + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Exit ; Branch if out of range + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDR R12,[R2,R1,LSL #2] ; Load address of SVC function + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STR R0,[R12] ; Store function return value + + BX LR ; Return from handler + + ALIGN + ENDP + + +PendSV_Handler PROC + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + ALIGN + ENDP + + +SysTick_Handler PROC + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + ALIGN + ENDP + + + END diff --git a/rtos/rtx5/GCC/Makefile b/rtos/rtx5/GCC/Makefile new file mode 100644 index 0000000..881a7ef --- /dev/null +++ b/rtos/rtx5/GCC/Makefile @@ -0,0 +1,15 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +ifeq ($(CPU),m33) +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)irq_armv8mml_fp.S)) +else ifeq ($(CPU),m4) +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)irq_cm4f.S)) +else ifeq ($(CPU),a7) +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)irq_ca.S)) +else +$(error Invalid CPU: $(CPU)) +endif + +obj-y := $(obj_s:.S=.o) + +subdir-asflags-y += -Irtos/rtx5/GCC diff --git a/rtos/rtx5/GCC/irq_armv8mbl.S b/rtos/rtx5/GCC/irq_armv8mbl.S new file mode 100644 index 0000000..56b486d --- /dev/null +++ b/rtos/rtx5/GCC/irq_armv8mbl.S @@ -0,0 +1,317 @@ +;/* +; * Copyright (c) 2016-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: ARMv8M Baseline Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + + .file "irq_armv8mbl.S" + .syntax unified + + .ifndef DOMAIN_NS + .equ DOMAIN_NS, 0 + .endif + + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset + .equ TCB_SM_OFS, 48 // TCB.stack_mem offset + .equ TCB_SP_OFS, 56 // TCB.SP offset + .equ TCB_SF_OFS, 34 // TCB.stack_frame offset + .equ TCB_TZM_OFS, 64 // TCB.tz_memory offset + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + + .thumb + .section ".text" + .align 2 + + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + MOV R0,LR + LSRS R0,R0,#3 // Determine return stack from EXC_RETURN bit 2 + BCC SVC_MSP // Branch if return stack is MSP + MRS R0,PSP // Get PSP + +SVC_Number: + LDR R1,[R0,#24] // Load saved PC from stack + SUBS R1,R1,#2 // Point to SVC instruction + LDRB R1,[R1] // Load SVC number + CMP R1,#0 + BNE SVC_User // Branch if not SVC 0 + + PUSH {R0,LR} // Save SP and EXC_RETURN + LDM R0,{R0-R3} // Load function parameters from stack + BLX R7 // Call service function + POP {R2,R3} // Restore SP and EXC_RETURN + STMIA R2!,{R0-R1} // Store function return values + MOV LR,R3 // Set EXC_RETURN + +SVC_Context: + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + BEQ SVC_Exit // Branch when threads are the same + + CBZ R1,SVC_ContextSwitch // Branch if running thread is deleted + +SVC_ContextSave: + .if DOMAIN_NS == 1 + LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier + CBZ R0,SVC_ContextSave1 // Branch if there is no secure context + PUSH {R1,R2,R3,R7} // Save registers + MOV R7,LR // Get EXC_RETURN + BL TZ_StoreContext_S // Store secure context + MOV LR,R7 // Set EXC_RETURN + POP {R1,R2,R3,R7} // Restore registers + .endif + +SVC_ContextSave1: + MRS R0,PSP // Get PSP + SUBS R0,R0,#32 // Calculate SP + STR R0,[R1,#TCB_SP_OFS] // Store SP + STMIA R0!,{R4-R7} // Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} // Save R8..R11 + +SVC_ContextSave2: + MOV R0,LR // Get EXC_RETURN + ADDS R1,R1,#TCB_SF_OFS // Adjust address + STRB R0,[R1] // Store stack frame information + +SVC_ContextSwitch: + SUBS R3,R3,#8 // Adjust address + STR R2,[R3] // osRtxInfo.thread.run: curr = next + +SVC_ContextRestore: + .if DOMAIN_NS == 1 + LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier + CBZ R0,SVC_ContextRestore1 // Branch if there is no secure context + PUSH {R2,R3} // Save registers + BL TZ_LoadContext_S // Load secure context + POP {R2,R3} // Restore registers + .endif + +SVC_ContextRestore1: + MOV R1,R2 + ADDS R1,R1,#TCB_SF_OFS // Adjust address + LDRB R0,[R1] // Load stack frame information + MOVS R1,#0xFF + MVNS R1,R1 // R1=0xFFFFFF00 + ORRS R0,R1 + MOV LR,R0 // Set EXC_RETURN + + .if DOMAIN_NS == 1 + LSLS R0,R0,#25 // Check domain of interrupted thread + BPL SVC_ContextRestore2 // Branch if non-secure + LDR R0,[R2,#TCB_SP_OFS] // Load SP + MSR PSP,R0 // Set PSP + BX LR // Exit from handler + .else + LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base + MSR PSPLIM,R0 // Set PSPLIM + .endif + +SVC_ContextRestore2: + LDR R0,[R2,#TCB_SP_OFS] // Load SP + ADDS R0,R0,#16 // Adjust address + LDMIA R0!,{R4-R7} // Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 // Set PSP + SUBS R0,R0,#32 // Adjust address + LDMIA R0!,{R4-R7} // Restore R4..R7 + +SVC_Exit: + BX LR // Exit from handler + +SVC_MSP: + MRS R0,MSP // Get MSP + B SVC_Number + +SVC_User: + LDR R2,=osRtxUserSVC // Load address of SVC table + LDR R3,[R2] // Load SVC maximum number + CMP R1,R3 // Check SVC number range + BHI SVC_Exit // Branch if out of range + + PUSH {R0,LR} // Save SP and EXC_RETURN + LSLS R1,R1,#2 + LDR R3,[R2,R1] // Load address of SVC function + MOV R12,R3 + LDMIA R0,{R0-R3} // Load function parameters from stack + BLX R12 // Call service function + POP {R2,R3} // Restore SP and EXC_RETURN + STR R0,[R2] // Store function return value + MOV LR,R3 // Set EXC_RETURN + + BX LR // Return from handler + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .fnstart + .cantunwind +PendSV_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxPendSV_Handler // Call osRtxPendSV_Handler + POP {R0,R1} // Restore EXC_RETURN + MOV LR,R1 // Set EXC_RETURN + B Sys_Context + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler + .fnstart + .cantunwind +SysTick_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxTick_Handler // Call osRtxTick_Handler + POP {R0,R1} // Restore EXC_RETURN + MOV LR,R1 // Set EXC_RETURN + B Sys_Context + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + + .thumb_func + .type Sys_Context, %function + .global Sys_Context + .fnstart + .cantunwind +Sys_Context: + + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R3!,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + BEQ Sys_ContextExit // Branch when threads are the same + +Sys_ContextSave: + .if DOMAIN_NS == 1 + LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier + CBZ R0,Sys_ContextSave1 // Branch if there is no secure context + PUSH {R1,R2,R3,R7} // Save registers + MOV R7,LR // Get EXC_RETURN + BL TZ_StoreContext_S // Store secure context + MOV LR,R7 // Set EXC_RETURN + POP {R1,R2,R3,R7} // Restore registers + MOV R0,LR // Get EXC_RETURN + LSLS R0,R0,#25 // Check domain of interrupted thread + BPL Sys_ContextSave1 // Branch if non-secure + MRS R0,PSP // Get PSP + STR R0,[R1,#TCB_SP_OFS] // Store SP + B Sys_ContextSave2 + .endif + +Sys_ContextSave1: + MRS R0,PSP // Get PSP + SUBS R0,R0,#32 // Adjust address + STR R0,[R1,#TCB_SP_OFS] // Store SP + STMIA R0!,{R4-R7} // Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} // Save R8..R11 + +Sys_ContextSave2: + MOV R0,LR // Get EXC_RETURN + ADDS R1,R1,#TCB_SF_OFS // Adjust address + STRB R0,[R1] // Store stack frame information + +Sys_ContextSwitch: + SUBS R3,R3,#8 // Adjust address + STR R2,[R3] // osRtxInfo.run: curr = next + +Sys_ContextRestore: + .if DOMAIN_NS == 1 + LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier + CBZ R0,Sys_ContextRestore1 // Branch if there is no secure context + PUSH {R2,R3} // Save registers + BL TZ_LoadContext_S // Load secure context + POP {R2,R3} // Restore registers + .endif + +Sys_ContextRestore1: + MOV R1,R2 + ADDS R1,R1,#TCB_SF_OFS // Adjust offset + LDRB R0,[R1] // Load stack frame information + MOVS R1,#0xFF + MVNS R1,R1 // R1=0xFFFFFF00 + ORRS R0,R1 + MOV LR,R0 // Set EXC_RETURN + + .if DOMAIN_NS == 1 + LSLS R0,R0,#25 // Check domain of interrupted thread + BPL Sys_ContextRestore2 // Branch if non-secure + LDR R0,[R2,#TCB_SP_OFS] // Load SP + MSR PSP,R0 // Set PSP + BX LR // Exit from handler + .else + LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base + MSR PSPLIM,R0 // Set PSPLIM + .endif + +Sys_ContextRestore2: + LDR R0,[R2,#TCB_SP_OFS] // Load SP + ADDS R0,R0,#16 // Adjust address + LDMIA R0!,{R4-R7} // Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 // Set PSP + SUBS R0,R0,#32 // Adjust address + LDMIA R0!,{R4-R7} // Restore R4..R7 + +Sys_ContextExit: + BX LR // Exit from handler + + .fnend + .size Sys_Context, .-Sys_Context + + + .end diff --git a/rtos/rtx5/GCC/irq_armv8mbl_ns.S b/rtos/rtx5/GCC/irq_armv8mbl_ns.S new file mode 100644 index 0000000..e888893 --- /dev/null +++ b/rtos/rtx5/GCC/irq_armv8mbl_ns.S @@ -0,0 +1,3 @@ + .equ DOMAIN_NS, 1 + .include "./irq_armv8mbl.S" + .end diff --git a/rtos/rtx5/GCC/irq_armv8mml.S b/rtos/rtx5/GCC/irq_armv8mml.S new file mode 100644 index 0000000..c9c497c --- /dev/null +++ b/rtos/rtx5/GCC/irq_armv8mml.S @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2016-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: ARMv8M Mainline Exception handlers + * + * ----------------------------------------------------------------------------- + */ + + + .file "irq_armv8mml.S" + .syntax unified + + .ifndef DOMAIN_NS + .equ DOMAIN_NS, 0 + .endif + + .ifndef __FPU_USED + .equ __FPU_USED, 0 + .endif + + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset + .equ TCB_SM_OFS, 48 // TCB.stack_mem offset + .equ TCB_SP_OFS, 56 // TCB.SP offset + .equ TCB_SF_OFS, 34 // TCB.stack_frame offset + .equ TCB_TZM_OFS, 64 // TCB.tz_memory offset + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + + .thumb + .section ".text" + .align 2 + + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + TST LR,#0x04 // Determine return stack from EXC_RETURN bit 2 + ITE EQ + MRSEQ R0,MSP // Get MSP if return stack is MSP + MRSNE R0,PSP // Get PSP if return stack is PSP + + LDR R1,[R0,#24] // Load saved PC from stack + LDRB R1,[R1,#-2] // Load SVC number + CMP R1,#0 + BNE SVC_User // Branch if not SVC 0 + + PUSH {R0,LR} // Save SP and EXC_RETURN + LDM R0,{R0-R3,R12} // Load function parameters and address from stack + BLX R12 // Call service function + POP {R12,LR} // Restore SP and EXC_RETURN + STM R12,{R0-R1} // Store function return values + +SVC_Context: + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + IT EQ + BXEQ LR // Exit when threads are the same + + .if __FPU_USED == 1 + CBNZ R1,SVC_ContextSave // Branch if running thread is not deleted + TST LR,#0x10 // Check if extended stack frame + BNE SVC_ContextSwitch + LDR R1,=0xE000EF34 // FPCCR Address + LDR R0,[R1] // Load FPCCR + BIC R0,R0,#1 // Clear LSPACT (Lazy state) + STR R0,[R1] // Store FPCCR + B SVC_ContextSwitch + .else + CBZ R1,SVC_ContextSwitch // Branch if running thread is deleted + .endif + +SVC_ContextSave: + .if DOMAIN_NS == 1 + LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier + CBZ R0,SVC_ContextSave1 // Branch if there is no secure context + PUSH {R1,R2,R3,LR} // Save registers and EXC_RETURN + BL TZ_StoreContext_S // Store secure context + POP {R1,R2,R3,LR} // Restore registers and EXC_RETURN + .endif + +SVC_ContextSave1: + MRS R0,PSP // Get PSP + STMDB R0!,{R4-R11} // Save R4..R11 + .if __FPU_USED == 1 + TST LR,#0x10 // Check if extended stack frame + IT EQ + VSTMDBEQ R0!,{S16-S31} // Save VFP S16.S31 + .endif + +SVC_ContextSave2: + STR R0,[R1,#TCB_SP_OFS] // Store SP + STRB LR,[R1,#TCB_SF_OFS] // Store stack frame information + +SVC_ContextSwitch: + STR R2,[R3] // osRtxInfo.thread.run: curr = next + +SVC_ContextRestore: + .if DOMAIN_NS == 1 + LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier + CBZ R0,SVC_ContextRestore1 // Branch if there is no secure context + PUSH {R2,R3} // Save registers + BL TZ_LoadContext_S // Load secure context + POP {R2,R3} // Restore registers + .endif + +SVC_ContextRestore1: + LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base + LDRB R1,[R2,#TCB_SF_OFS] // Load stack frame information + MSR PSPLIM,R0 // Set PSPLIM + LDR R0,[R2,#TCB_SP_OFS] // Load SP + ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN + + .if DOMAIN_NS == 1 + TST LR,#0x40 // Check domain of interrupted thread + BNE SVC_ContextRestore2 // Branch if secure + .endif + + .if __FPU_USED == 1 + TST LR,#0x10 // Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31 + .endif + LDMIA R0!,{R4-R11} // Restore R4..R11 + +SVC_ContextRestore2: + MSR PSP,R0 // Set PSP + +SVC_Exit: + BX LR // Exit from handler + +SVC_User: + LDR R2,=osRtxUserSVC // Load address of SVC table + LDR R3,[R2] // Load SVC maximum number + CMP R1,R3 // Check SVC number range + BHI SVC_Exit // Branch if out of range + + PUSH {R0,LR} // Save SP and EXC_RETURN + LDR R12,[R2,R1,LSL #2] // Load address of SVC function + LDM R0,{R0-R3} // Load function parameters from stack + BLX R12 // Call service function + POP {R12,LR} // Restore SP and EXC_RETURN + STR R0,[R12] // Store function return value + + BX LR // Return from handler + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .fnstart + .cantunwind +PendSV_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxPendSV_Handler // Call osRtxPendSV_Handler + POP {R0,LR} // Restore EXC_RETURN + B Sys_Context + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler + .fnstart + .cantunwind +SysTick_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxTick_Handler // Call osRtxTick_Handler + POP {R0,LR} // Restore EXC_RETURN + B Sys_Context + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + + .thumb_func + .type Sys_Context, %function + .global Sys_Context + .fnstart + .cantunwind +Sys_Context: + + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + IT EQ + BXEQ LR // Exit when threads are the same + +Sys_ContextSave: + .if DOMAIN_NS == 1 + LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier + CBZ R0,Sys_ContextSave1 // Branch if there is no secure context + PUSH {R1,R2,R3,LR} // Save registers and EXC_RETURN + BL TZ_StoreContext_S // Store secure context + POP {R1,R2,R3,LR} // Restore registers and EXC_RETURN + TST LR,#0x40 // Check domain of interrupted thread + IT NE + MRSNE R0,PSP // Get PSP + BNE Sys_ContextSave2 // Branch if secure + .endif + +Sys_ContextSave1: + MRS R0,PSP // Get PSP + STMDB R0!,{R4-R11} // Save R4..R11 + .if __FPU_USED == 1 + TST LR,#0x10 // Check if extended stack frame + IT EQ + VSTMDBEQ R0!,{S16-S31} // Save VFP S16.S31 + .endif + +Sys_ContextSave2: + STR R0,[R1,#TCB_SP_OFS] // Store SP + STRB LR,[R1,#TCB_SF_OFS] // Store stack frame information + +Sys_ContextSwitch: + STR R2,[R3] // osRtxInfo.run: curr = next + +Sys_ContextRestore: + .if DOMAIN_NS == 1 + LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier + CBZ R0,Sys_ContextRestore1 // Branch if there is no secure context + PUSH {R2,R3} // Save registers + BL TZ_LoadContext_S // Load secure context + POP {R2,R3} // Restore registers + .endif + +Sys_ContextRestore1: + LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base + LDRB R1,[R2,#TCB_SF_OFS] // Load stack frame information + MSR PSPLIM,R0 // Set PSPLIM + LDR R0,[R2,#TCB_SP_OFS] // Load SP + ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN + + .if DOMAIN_NS == 1 + TST LR,#0x40 // Check domain of interrupted thread + BNE Sys_ContextRestore2 // Branch if secure + .endif + + .if __FPU_USED == 1 + TST LR,#0x10 // Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31 + .endif + LDMIA R0!,{R4-R11} // Restore R4..R11 + +Sys_ContextRestore2: + MSR PSP,R0 // Set PSP + +Sys_ContextExit: + BX LR // Exit from handler + + .fnend + .size Sys_Context, .-Sys_Context + + + .end diff --git a/rtos/rtx5/GCC/irq_armv8mml_fp.S b/rtos/rtx5/GCC/irq_armv8mml_fp.S new file mode 100644 index 0000000..88ef9de --- /dev/null +++ b/rtos/rtx5/GCC/irq_armv8mml_fp.S @@ -0,0 +1,3 @@ + .equ __FPU_USED, 1 + .include "./irq_armv8mml.S" + .end diff --git a/rtos/rtx5/GCC/irq_armv8mml_fp_ns.S b/rtos/rtx5/GCC/irq_armv8mml_fp_ns.S new file mode 100644 index 0000000..95d844a --- /dev/null +++ b/rtos/rtx5/GCC/irq_armv8mml_fp_ns.S @@ -0,0 +1,4 @@ + .equ __FPU_USED, 1 + .equ DOMAIN_NS, 1 + .include "./irq_armv8mml.S" + .end diff --git a/rtos/rtx5/GCC/irq_armv8mml_ns.S b/rtos/rtx5/GCC/irq_armv8mml_ns.S new file mode 100644 index 0000000..a3747b2 --- /dev/null +++ b/rtos/rtx5/GCC/irq_armv8mml_ns.S @@ -0,0 +1,3 @@ + .equ DOMAIN_NS, 1 + .include "./irq_armv8mml.S" + .end diff --git a/rtos/rtx5/GCC/irq_ca.S b/rtos/rtx5/GCC/irq_ca.S new file mode 100644 index 0000000..ceae758 --- /dev/null +++ b/rtos/rtx5/GCC/irq_ca.S @@ -0,0 +1,465 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-A Exception handlers + * + * ----------------------------------------------------------------------------- + */ + + .file "irq_ca.S" + .syntax unified + + .equ MODE_FIQ, 0x11 + .equ MODE_IRQ, 0x12 + .equ MODE_SVC, 0x13 + .equ MODE_ABT, 0x17 + .equ MODE_UND, 0x1B + + .equ CPSR_BIT_T, 0x20 + + .equ K_STATE_RUNNING, 2 // osKernelState_t::osKernelRunning + .equ I_K_STATE_OFS, 8 // osRtxInfo.kernel.state offset + .equ I_TICK_IRQN_OFS, 16 // osRtxInfo.tick_irqn offset + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset + .equ TCB_SP_FRAME, 34 // osRtxThread_t.stack_frame offset + .equ TCB_SP_OFS, 56 // osRtxThread_t.sp offset + + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + .section ".data" + .global IRQ_PendSV +IRQ_NestLevel: + .word 0 // IRQ nesting level counter +IRQ_PendSV: + .byte 0 // Pending SVC flag + + .arm + .section ".text" + .align 4 + + + .type Undef_Handler, %function + .global Undef_Handler + .fnstart + .cantunwind +Undef_Handler: + + SRSFD SP!, #MODE_UND + PUSH {R0-R4, R12} // Save APCS corruptible registers to UND mode stack + + MRS R0, SPSR + TST R0, #CPSR_BIT_T // Check mode + MOVEQ R1, #4 // R1 = 4 ARM mode + MOVNE R1, #2 // R1 = 2 Thumb mode + SUB R0, LR, R1 + LDREQ R0, [R0] // ARM mode - R0 points to offending instruction + BEQ Undef_Cont + + // Thumb instruction + // Determine if it is a 32-bit Thumb instruction + LDRH R0, [R0] + MOV R2, #0x1C + CMP R2, R0, LSR #11 + BHS Undef_Cont // 16-bit Thumb instruction + + // 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction + LDRH R2, [LR] + ORR R0, R2, R0, LSL #16 +Undef_Cont: + MOV R2, LR // Set LR to third argument + + AND R12, SP, #4 // Ensure stack is 8-byte aligned + SUB SP, SP, R12 // Adjust stack + PUSH {R12, LR} // Store stack adjustment and dummy LR + + // R0 =Offending instruction, R1 =2(Thumb) or =4(ARM) + BL CUndefHandler + + POP {R12, LR} // Get stack adjustment & discard dummy LR + ADD SP, SP, R12 // Unadjust stack + + LDR LR, [SP, #24] // Restore stacked LR and possibly adjust for retry + SUB LR, LR, R0 + LDR R0, [SP, #28] // Restore stacked SPSR + MSR SPSR_cxsf, R0 + CLREX // Clear exclusive monitor + POP {R0-R4, R12} // Restore stacked APCS registers + ADD SP, SP, #8 // Adjust SP for already-restored banked registers + MOVS PC, LR + + .fnend + .size Undef_Handler, .-Undef_Handler + + + .type PAbt_Handler, %function + .global PAbt_Handler + .fnstart + .cantunwind +PAbt_Handler: + + SUB LR, LR, #4 // Pre-adjust LR + SRSFD SP!, #MODE_ABT // Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} // Save APCS corruptible registers to ABT mode stack + MRC p15, 0, R0, c5, c0, 1 // IFSR + MRC p15, 0, R1, c6, c0, 2 // IFAR + + MOV R2, LR // Set LR to third argument + + AND R12, SP, #4 // Ensure stack is 8-byte aligned + SUB SP, SP, R12 // Adjust stack + PUSH {R12, LR} // Store stack adjustment and dummy LR + + BL CPAbtHandler + + POP {R12, LR} // Get stack adjustment & discard dummy LR + ADD SP, SP, R12 // Unadjust stack + + CLREX // Clear exclusive monitor + POP {R0-R4, R12} // Restore stack APCS registers + RFEFD SP! // Return from exception + + .fnend + .size PAbt_Handler, .-PAbt_Handler + + + .type DAbt_Handler, %function + .global DAbt_Handler + .fnstart + .cantunwind +DAbt_Handler: + SUB LR, LR, #8 // Pre-adjust LR + SRSFD SP!, #MODE_ABT // Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} // Save APCS corruptible registers to ABT mode stack + MRC p15, 0, R0, c5, c0, 0 // DFSR + MRC p15, 0, R1, c6, c0, 0 // DFAR + + MOV R2, LR // Set LR to third argument + + AND R12, SP, #4 // Ensure stack is 8-byte aligned + SUB SP, SP, R12 // Adjust stack + PUSH {R12, LR} // Store stack adjustment and dummy LR + + BL CDAbtHandler + + POP {R12, LR} // Get stack adjustment & discard dummy LR + ADD SP, SP, R12 // Unadjust stack + + CLREX // Clear exclusive monitor + POP {R0-R4, R12} // Restore stacked APCS registers + RFEFD SP! // Return from exception + + .fnend + .size DAbt_Handler, .-DAbt_Handler + + + .type IRQ_Handler, %function + .global IRQ_Handler + .fnstart + .cantunwind +IRQ_Handler: + + SUB LR, LR, #4 // Pre-adjust LR + SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack + CPS #MODE_SVC // Change to SVC mode + PUSH {R0-R3, R12, LR} // Save APCS corruptible registers + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + ADD R1, R1, #1 // Increment IRQ nesting level + STR R1, [R0] + + MOV R3, SP // Move SP into R3 + AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R3 // Adjust stack + PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4) + + BLX IRQ_GetActiveIRQ // Retrieve interrupt ID into R0 + MOV R4, R0 // Move interrupt ID to R4 + + BLX IRQ_GetHandler // Retrieve interrupt handler address for current ID + CMP R0, #0 // Check if handler address is 0 + BEQ IRQ_End // If 0, end interrupt and return + + CPSIE i // Re-enable interrupts + BLX R0 // Call IRQ handler + CPSID i // Disable interrupts + +IRQ_End: + MOV R0, R4 // Move interrupt ID to R0 + BLX IRQ_EndOfInterrupt // Signal end of interrupt + + POP {R3, R4} // Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 // Unadjust stack + + BL osRtxContextSwitch // Continue in context switcher + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + SUBS R1, R1, #1 // Decrement IRQ nesting level + STR R1, [R0] + + CLREX // Clear exclusive monitor for interrupted code + POP {R0-R3, R12, LR} // Restore stacked APCS registers + RFEFD SP! // Return from IRQ handler + + .fnend + .size IRQ_Handler, .-IRQ_Handler + + + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + SRSFD SP!, #MODE_SVC // Store SPSR_svc and LR_svc onto SVC stack + PUSH {R12, LR} + + MRS R12, SPSR // Load SPSR + TST R12, #CPSR_BIT_T // Thumb bit set? + LDRHNE R12, [LR,#-2] // Thumb: load halfword + BICNE R12, R12, #0xFF00 // extract SVC number + LDREQ R12, [LR,#-4] // ARM: load word + BICEQ R12, R12, #0xFF000000 // extract SVC number + CMP R12, #0 // Compare SVC number + BNE SVC_User // Branch if User SVC + + PUSH {R0-R3} + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + ADD R1, R1, #1 // Increment IRQ nesting level + STR R1, [R0] + + LDR R0, =osRtxInfo + LDR R1, [R0, #I_K_STATE_OFS] // Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING // Check osKernelRunning + BLT SVC_FuncCall // Continue if kernel is not running + LDR R0, [R0, #I_TICK_IRQN_OFS] // Load OS Tick irqn + BLX IRQ_Disable // Disable OS Tick interrupt +SVC_FuncCall: + POP {R0-R3} + + LDR R12, [SP] // Reload R12 from stack + + CPSIE i // Re-enable interrupts + BLX R12 // Branch to SVC function + CPSID i // Disable interrupts + + SUB SP, SP, #4 + STM SP, {SP}^ // Store SP_usr onto stack + POP {R12} // Pop SP_usr into R12 + SUB R12, R12, #16 // Adjust pointer to SP_usr + LDMDB R12, {R2,R3} // Load return values from SVC function + PUSH {R0-R3} // Push return values to stack + + LDR R0, =osRtxInfo + LDR R1, [R0, #I_K_STATE_OFS] // Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING // Check osKernelRunning + BLT SVC_ContextCheck // Continue if kernel is not running + LDR R0, [R0, #I_TICK_IRQN_OFS] // Load OS Tick irqn + BLX IRQ_Enable // Enable OS Tick interrupt + +SVC_ContextCheck: + BL osRtxContextSwitch // Continue in context switcher + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + SUB R1, R1, #1 // Decrement IRQ nesting level + STR R1, [R0] + + CLREX // Clear exclusive monitor + POP {R0-R3, R12, LR} // Restore stacked APCS registers + RFEFD SP! // Return from exception + +SVC_User: + PUSH {R4, R5} + LDR R5,=osRtxUserSVC // Load address of SVC table + LDR R4,[R5] // Load SVC maximum number + CMP R12,R4 // Check SVC number range + BHI SVC_Done // Branch if out of range + + LDR R12,[R5,R12,LSL #2] // Load SVC Function Address + BLX R12 // Call SVC Function + +SVC_Done: + CLREX // Clear exclusive monitor + POP {R4, R5, R12, LR} + RFEFD SP! // Return from exception + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .type osRtxContextSwitch, %function + .global osRtxContextSwitch + .fnstart + .cantunwind +osRtxContextSwitch: + + PUSH {LR} + + // Check interrupt nesting level + LDR R0, =IRQ_NestLevel + LDR R1, [R0] // Load IRQ nest level + CMP R1, #1 + BNE osRtxContextExit // Nesting interrupts, exit context switcher + + LDR R12, =osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R12, {R0, R1} // Load osRtxInfo.thread.run: curr & next + LDR R2, =IRQ_PendSV // Load address of IRQ_PendSV flag + LDRB R3, [R2] // Load PendSV flag + + CMP R0, R1 // Check if context switch is required + BNE osRtxContextCheck // Not equal, check if context save required + CMP R3, #1 // Compare IRQ_PendSV value + BNE osRtxContextExit // No post processing (and no context switch requested) + +osRtxContextCheck: + STR R1, [R12] // Store run.next as run.curr + // R0 = curr, R1 = next, R2 = &IRQ_PendSV, R3 = IRQ_PendSV, R12 = &osRtxInfo.thread.run + PUSH {R1-R3, R12} + + CMP R0, #0 // Is osRtxInfo.thread.run.curr == 0 + BEQ osRtxPostProcess // Current deleted, skip context save + +osRtxContextSave: + MOV LR, R0 // Move &osRtxInfo.thread.run.curr to LR + MOV R0, SP // Move SP_svc into R0 + ADD R0, R0, #20 // Adjust SP_svc to R0 of the basic frame + SUB SP, SP, #4 + STM SP, {SP}^ // Save SP_usr to current stack + POP {R1} // Pop SP_usr into R1 + + SUB R1, R1, #64 // Adjust SP_usr to R4 of the basic frame + STMIA R1!, {R4-R11} // Save R4-R11 to user stack + LDMIA R0!, {R4-R8} // Load stacked R0-R3,R12 into R4-R8 + STMIA R1!, {R4-R8} // Store them to user stack + STM R1, {LR}^ // Store LR_usr directly + ADD R1, R1, #4 // Adjust user sp to PC + LDMIB R0!, {R5-R6} // Load current PC, CPSR + STMIA R1!, {R5-R6} // Restore user PC and CPSR + + SUB R1, R1, #64 // Adjust SP_usr to stacked R4 + + // Check if VFP state need to be saved + MRC p15, 0, R2, c1, c0, 2 // VFP/NEON access enabled? (CPACR) + AND R2, R2, #0x00F00000 + CMP R2, #0x00F00000 + BNE osRtxContextSave1 // Continue, no VFP + + VMRS R2, FPSCR + STMDB R1!, {R2,R12} // Push FPSCR, maintain 8-byte alignment + + VSTMDB R1!, {D0-D15} // Save D0-D15 + #if __ARM_NEON == 1 + VSTMDB R1!, {D16-D31} // Save D16-D31 + #endif + + LDRB R2, [LR, #TCB_SP_FRAME] // Load osRtxInfo.thread.run.curr frame info + #if __ARM_NEON == 1 + ORR R2, R2, #4 // NEON state + #else + ORR R2, R2, #2 // VFP state + #endif + STRB R2, [LR, #TCB_SP_FRAME] // Store VFP/NEON state + +osRtxContextSave1: + STR R1, [LR, #TCB_SP_OFS] // Store user sp to osRtxInfo.thread.run.curr + +osRtxPostProcess: + // RTX IRQ post processing check + POP {R8-R11} // Pop R8 = run.next, R9 = &IRQ_PendSV, R10 = IRQ_PendSV, R11 = &osRtxInfo.thread.run + CMP R10, #1 // Compare PendSV value + BNE osRtxContextRestore // Skip post processing if not pending + + MOV R4, SP // Move SP_svc into R4 + AND R4, R4, #4 // Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R4 // Adjust stack + + // Disable OS Tick + LDR R5, =osRtxInfo // Load address of osRtxInfo + LDR R5, [R5, #I_TICK_IRQN_OFS] // Load OS Tick irqn + MOV R0, R5 // Set it as function parameter + BLX IRQ_Disable // Disable OS Tick interrupt + MOV R6, #0 // Set PendSV clear value + B osRtxPendCheck +osRtxPendExec: + STRB R6, [R9] // Clear PendSV flag + CPSIE i // Re-enable interrupts + BLX osRtxPendSV_Handler // Post process pending objects + CPSID i // Disable interrupts +osRtxPendCheck: + LDR R8, [R11, #4] // Load osRtxInfo.thread.run.next + STR R8, [R11] // Store run.next as run.curr + LDRB R0, [R9] // Load PendSV flag + CMP R0, #1 // Compare PendSV value + BEQ osRtxPendExec // Branch to PendExec if PendSV is set + + // Re-enable OS Tick + MOV R0, R5 // Restore irqn as function parameter + BLX IRQ_Enable // Enable OS Tick interrupt + + ADD SP, SP, R4 // Restore stack adjustment + +osRtxContextRestore: + LDR LR, [R8, #TCB_SP_OFS] // Load next osRtxThread_t.sp + LDRB R2, [R8, #TCB_SP_FRAME] // Load next osRtxThread_t.stack_frame + + ANDS R2, R2, #0x6 // Check stack frame for VFP context + MRC p15, 0, R2, c1, c0, 2 // Read CPACR + ANDEQ R2, R2, #0xFF0FFFFF // VFP/NEON state not stacked, disable VFP/NEON + ORRNE R2, R2, #0x00F00000 // VFP/NEON state is stacked, enable VFP/NEON + MCR p15, 0, R2, c1, c0, 2 // Write CPACR + BEQ osRtxContextRestore1 // No VFP + ISB // Sync if VFP was enabled + #if __ARM_NEON == 1 + VLDMIA LR!, {D16-D31} // Restore D16-D31 + #endif + VLDMIA LR!, {D0-D15} // Restore D0-D15 + LDR R2, [LR] + VMSR FPSCR, R2 // Restore FPSCR + ADD LR, LR, #8 // Adjust sp pointer to R4 + +osRtxContextRestore1: + LDMIA LR!, {R4-R11} // Restore R4-R11 + ADD R12, LR, #32 // Adjust sp and save it into R12 + PUSH {R12} // Push sp onto stack + LDM SP, {SP}^ // Restore SP_usr directly + ADD SP, SP, #4 // Adjust SP_svc + LDMIA LR!, {R0-R3, R12} // Load user registers R0-R3,R12 + STMIB SP!, {R0-R3, R12} // Store them to SP_svc + LDM LR, {LR}^ // Restore LR_usr directly + LDMIB LR!, {R0-R1} // Load user registers PC,CPSR + ADD SP, SP, #4 + STMIB SP!, {R0-R1} // Store them to SP_svc + SUB SP, SP, #32 // Adjust SP_svc to stacked LR + +osRtxContextExit: + POP {PC} // Return + + .fnend + .size osRtxContextSwitch, .-osRtxContextSwitch + + .end diff --git a/rtos/rtx5/GCC/irq_cm0.S b/rtos/rtx5/GCC/irq_cm0.S new file mode 100644 index 0000000..f166d2d --- /dev/null +++ b/rtos/rtx5/GCC/irq_cm0.S @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-M0 Exception handlers + * + * ----------------------------------------------------------------------------- + */ + + + .file "irq_cm0.S" + .syntax unified + + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset + .equ TCB_SP_OFS, 56 // TCB.SP offset + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + + .thumb + .section ".text" + .align 2 + + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + MOV R0,LR + LSRS R0,R0,#3 // Determine return stack from EXC_RETURN bit 2 + BCC SVC_MSP // Branch if return stack is MSP + MRS R0,PSP // Get PSP + +SVC_Number: + LDR R1,[R0,#24] // Load saved PC from stack + SUBS R1,R1,#2 // Point to SVC instruction + LDRB R1,[R1] // Load SVC number + CMP R1,#0 + BNE SVC_User // Branch if not SVC 0 + + PUSH {R0,LR} // Save SP and EXC_RETURN + LDMIA R0,{R0-R3} // Load function parameters from stack + BLX R7 // Call service function + POP {R2,R3} // Restore SP and EXC_RETURN + STMIA R2!,{R0-R1} // Store function return values + MOV LR,R3 // Set EXC_RETURN + +SVC_Context: + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + BEQ SVC_Exit // Branch when threads are the same + + CMP R1,#0 + BEQ SVC_ContextSwitch // Branch if running thread is deleted + +SVC_ContextSave: + MRS R0,PSP // Get PSP + SUBS R0,R0,#32 // Calculate SP + STR R0,[R1,#TCB_SP_OFS] // Store SP + STMIA R0!,{R4-R7} // Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} // Save R8..R11 + +SVC_ContextSwitch: + SUBS R3,R3,#8 // Adjust address + STR R2,[R3] // osRtxInfo.thread.run: curr = next + +SVC_ContextRestore: + LDR R0,[R2,#TCB_SP_OFS] // Load SP + ADDS R0,R0,#16 // Adjust address + LDMIA R0!,{R4-R7} // Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 // Set PSP + SUBS R0,R0,#32 // Adjust address + LDMIA R0!,{R4-R7} // Restore R4..R7 + + MOVS R0,#~0xFFFFFFFD + MVNS R0,R0 // Set EXC_RETURN value + BX R0 // Exit from handler + +SVC_MSP: + MRS R0,MSP // Get MSP + B SVC_Number + +SVC_Exit: + BX LR // Exit from handler + +SVC_User: + LDR R2,=osRtxUserSVC // Load address of SVC table + LDR R3,[R2] // Load SVC maximum number + CMP R1,R3 // Check SVC number range + BHI SVC_Exit // Branch if out of range + + PUSH {R0,LR} // Save SP and EXC_RETURN + LSLS R1,R1,#2 + LDR R3,[R2,R1] // Load address of SVC function + MOV R12,R3 + LDMIA R0,{R0-R3} // Load function parameters from stack + BLX R12 // Call service function + POP {R2,R3} // Restore SP and EXC_RETURN + STR R0,[R2] // Store function return value + MOV LR,R3 // Set EXC_RETURN + + BX LR // Return from handler + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .fnstart + .cantunwind +PendSV_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxPendSV_Handler // Call osRtxPendSV_Handler + POP {R0,R1} // Restore EXC_RETURN + MOV LR,R1 // Set EXC_RETURN + B SVC_Context + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler + .fnstart + .cantunwind +SysTick_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxTick_Handler // Call osRtxTick_Handler + POP {R0,R1} // Restore EXC_RETURN + MOV LR,R1 // Set EXC_RETURN + B SVC_Context + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + + .end diff --git a/rtos/rtx5/GCC/irq_cm3.S b/rtos/rtx5/GCC/irq_cm3.S new file mode 100644 index 0000000..95c5c15 --- /dev/null +++ b/rtos/rtx5/GCC/irq_cm3.S @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-M3 Exception handlers + * + * ----------------------------------------------------------------------------- + */ + + + .file "irq_cm3.S" + .syntax unified + + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset + .equ TCB_SP_OFS, 56 // TCB.SP offset + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + + .thumb + .section ".text" + .align 2 + + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + TST LR,#0x04 // Determine return stack from EXC_RETURN bit 2 + ITE EQ + MRSEQ R0,MSP // Get MSP if return stack is MSP + MRSNE R0,PSP // Get PSP if return stack is PSP + + LDR R1,[R0,#24] // Load saved PC from stack + LDRB R1,[R1,#-2] // Load SVC number + CBNZ R1,SVC_User // Branch if not SVC 0 + + PUSH {R0,LR} // Save SP and EXC_RETURN + LDM R0,{R0-R3,R12} // Load function parameters and address from stack + BLX R12 // Call service function + POP {R12,LR} // Restore SP and EXC_RETURN + STM R12,{R0-R1} // Store function return values + +SVC_Context: + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + IT EQ + BXEQ LR // Exit when threads are the same + + CBZ R1,SVC_ContextSwitch // Branch if running thread is deleted + +SVC_ContextSave: + STMDB R12!,{R4-R11} // Save R4..R11 + STR R12,[R1,#TCB_SP_OFS] // Store SP + +SVC_ContextSwitch: + STR R2,[R3] // osRtxInfo.thread.run: curr = next + +SVC_ContextRestore: + LDR R0,[R2,#TCB_SP_OFS] // Load SP + LDMIA R0!,{R4-R11} // Restore R4..R11 + MSR PSP,R0 // Set PSP + MVN LR,#~0xFFFFFFFD // Set EXC_RETURN value + +SVC_Exit: + BX LR // Exit from handler + +SVC_User: + LDR R2,=osRtxUserSVC // Load address of SVC table + LDR R3,[R2] // Load SVC maximum number + CMP R1,R3 // Check SVC number range + BHI SVC_Exit // Branch if out of range + + PUSH {R0,LR} // Save SP and EXC_RETURN + LDR R12,[R2,R1,LSL #2] // Load address of SVC function + LDM R0,{R0-R3} // Load function parameters from stack + BLX R12 // Call service function + POP {R12,LR} // Restore SP and EXC_RETURN + STR R0,[R12] // Store function return value + + BX LR // Return from handler + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .fnstart + .cantunwind +PendSV_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxPendSV_Handler // Call osRtxPendSV_Handler + POP {R0,LR} // Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler + .fnstart + .cantunwind +SysTick_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxTick_Handler // Call osRtxTick_Handler + POP {R0,LR} // Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + + .end diff --git a/rtos/rtx5/GCC/irq_cm4f.S b/rtos/rtx5/GCC/irq_cm4f.S new file mode 100644 index 0000000..568419a --- /dev/null +++ b/rtos/rtx5/GCC/irq_cm4f.S @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-M4F Exception handlers + * + * ----------------------------------------------------------------------------- + */ + + + .file "irq_cm4f.S" + .syntax unified + + .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset + .equ TCB_SP_OFS, 56 // TCB.SP offset + .equ TCB_SF_OFS, 34 // TCB.stack_frame offset + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + + .thumb + .section ".text" + .align 2 + + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + TST LR,#0x04 // Determine return stack from EXC_RETURN bit 2 + ITE EQ + MRSEQ R0,MSP // Get MSP if return stack is MSP + MRSNE R0,PSP // Get PSP if return stack is PSP + + LDR R1,[R0,#24] // Load saved PC from stack + LDRB R1,[R1,#-2] // Load SVC number + CBNZ R1,SVC_User // Branch if not SVC 0 + + PUSH {R0,LR} // Save SP and EXC_RETURN + LDM R0,{R0-R3,R12} // Load function parameters and address from stack + BLX R12 // Call service function + POP {R12,LR} // Restore SP and EXC_RETURN + STM R12,{R0-R1} // Store function return values + +SVC_Context: + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + IT EQ + BXEQ LR // Exit when threads are the same + + CBNZ R1,SVC_ContextSave // Branch if running thread is not deleted + TST LR,#0x10 // Check if extended stack frame + BNE SVC_ContextSwitch + LDR R1,=0xE000EF34 // FPCCR Address + LDR R0,[R1] // Load FPCCR + BIC R0,R0,#1 // Clear LSPACT (Lazy state) + STR R0,[R1] // Store FPCCR + B SVC_ContextSwitch + +SVC_ContextSave: + STMDB R12!,{R4-R11} // Save R4..R11 + TST LR,#0x10 // Check if extended stack frame + IT EQ + VSTMDBEQ R12!,{S16-S31} // Save VFP S16.S31 + STR R12,[R1,#TCB_SP_OFS] // Store SP + STRB LR, [R1,#TCB_SF_OFS] // Store stack frame information + +SVC_ContextSwitch: + STR R2,[R3] // osRtxInfo.thread.run: curr = next + +SVC_ContextRestore: + LDRB R1,[R2,#TCB_SF_OFS] // Load stack frame information + LDR R0,[R2,#TCB_SP_OFS] // Load SP + ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN + + TST LR,#0x10 // Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31 + LDMIA R0!,{R4-R11} // Restore R4..R11 + MSR PSP,R0 // Set PSP + +SVC_Exit: + BX LR // Exit from handler + +SVC_User: + LDR R2,=osRtxUserSVC // Load address of SVC table + LDR R3,[R2] // Load SVC maximum number + CMP R1,R3 // Check SVC number range + BHI SVC_Exit // Branch if out of range + + PUSH {R0,LR} // Save SP and EXC_RETURN + LDR R12,[R2,R1,LSL #2] // Load address of SVC function + LDM R0,{R0-R3} // Load function parameters from stack + BLX R12 // Call service function + POP {R12,LR} // Restore SP and EXC_RETURN + STR R0,[R12] // Store function return value + + BX LR // Return from handler + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .fnstart + .cantunwind +PendSV_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxPendSV_Handler // Call osRtxPendSV_Handler + POP {R0,LR} // Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler + .fnstart + .cantunwind +SysTick_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxTick_Handler // Call osRtxTick_Handler + POP {R0,LR} // Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + + .end diff --git a/rtos/rtx5/IAR/irq_armv8mbl.s b/rtos/rtx5/IAR/irq_armv8mbl.s new file mode 100644 index 0000000..2a75518 --- /dev/null +++ b/rtos/rtx5/IAR/irq_armv8mbl.s @@ -0,0 +1,4 @@ + NAME irq_armv8mbl.s +#define DOMAIN_NS 0 +#include "irq_armv8mbl_common.s" + END diff --git a/rtos/rtx5/IAR/irq_armv8mbl_common.s b/rtos/rtx5/IAR/irq_armv8mbl_common.s new file mode 100644 index 0000000..ec38438 --- /dev/null +++ b/rtos/rtx5/IAR/irq_armv8mbl_common.s @@ -0,0 +1,299 @@ +;/* +; * Copyright (c) 2016-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: ARMv8M Baseline Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + +#ifndef DOMAIN_NS +#define DOMAIN_NS 0 +#endif + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SM_OFS EQU 48 ; TCB.stack_mem offset +TCB_SP_OFS EQU 56 ; TCB.SP offset +TCB_SF_OFS EQU 34 ; TCB.stack_frame offset +TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset + + + PRESERVE8 + + + SECTION .rodata:DATA:NOROOT(2) + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + SECTION .text:CODE:NOROOT(2) + THUMB + + +SVC_Handler + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + #if (DOMAIN_NS == 1) + IMPORT TZ_LoadContext_S + IMPORT TZ_StoreContext_S + #endif + + MOV R0,LR + LSRS R0,R0,#3 ; Determine return stack from EXC_RETURN bit 2 + BCC SVC_MSP ; Branch if return stack is MSP + MRS R0,PSP ; Get PSP + +SVC_Number + LDR R1,[R0,#24] ; Load saved PC from stack + SUBS R1,R1,#2 ; Point to SVC instruction + LDRB R1,[R1] ; Load SVC number + CMP R1,#0 + BNE SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R7 ; Call service function + POP {R2,R3} ; Restore SP and EXC_RETURN + STMIA R2!,{R0-R1} ; Store function return values + MOV LR,R3 ; Set EXC_RETURN + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ SVC_Exit ; Branch when threads are the same + + CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + #if (DOMAIN_NS == 1) + LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context + PUSH {R1,R2,R3,R7} ; Save registers + MOV R7,LR ; Get EXC_RETURN + BL TZ_StoreContext_S ; Store secure context + MOV LR,R7 ; Set EXC_RETURN + POP {R1,R2,R3,R7} ; Restore registers + #endif + +SVC_ContextSave1 + MRS R0,PSP ; Get PSP + SUBS R0,R0,#32 ; Calculate SP + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STMIA R0!,{R4-R7} ; Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save R8..R11 + +SVC_ContextSave2 + MOV R0,LR ; Get EXC_RETURN + ADDS R1,R1,#TCB_SF_OFS ; Adjust address + STRB R0,[R1] ; Store stack frame information + +SVC_ContextSwitch + SUBS R3,R3,#8 ; Adjust address + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + #if (DOMAIN_NS == 1) + LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context + PUSH {R2,R3} ; Save registers + BL TZ_LoadContext_S ; Load secure context + POP {R2,R3} ; Restore registers + #endif + +SVC_ContextRestore1 + MOV R1,R2 + ADDS R1,R1,#TCB_SF_OFS ; Adjust address + LDRB R0,[R1] ; Load stack frame information + MOVS R1,#0xFF + MVNS R1,R1 ; R1=0xFFFFFF00 + ORRS R0,R1 + MOV LR,R0 ; Set EXC_RETURN + + #if (DOMAIN_NS == 1) + LSLS R0,R0,#25 ; Check domain of interrupted thread + BPL SVC_ContextRestore2 ; Branch if non-secure + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + MSR PSP,R0 ; Set PSP + BX LR ; Exit from handler + #else + LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base + MSR PSPLIM,R0 ; Set PSPLIM + #endif + +SVC_ContextRestore2 + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ADDS R0,R0,#16 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Set PSP + SUBS R0,R0,#32 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R4..R7 + +SVC_Exit + BX LR ; Exit from handler + +SVC_MSP + MRS R0,MSP ; Get MSP + B SVC_Number + +SVC_User + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Exit ; Branch if out of range + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LSLS R1,R1,#2 + LDR R3,[R2,R1] ; Load address of SVC function + MOV R12,R3 + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R12 ; Call service function + POP {R2,R3} ; Restore SP and EXC_RETURN + STR R0,[R2] ; Store function return value + MOV LR,R3 ; Set EXC_RETURN + + BX LR ; Return from handler + + +PendSV_Handler + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B Sys_Context + + +SysTick_Handler + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B Sys_Context + + + +Sys_Context + EXPORT Sys_Context + IMPORT osRtxInfo + #if (DOMAIN_NS == 1) + IMPORT TZ_LoadContext_S + IMPORT TZ_StoreContext_S + #endif + + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ Sys_ContextExit ; Branch when threads are the same + +Sys_ContextSave + #if (DOMAIN_NS == 1) + LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context + PUSH {R1,R2,R3,R7} ; Save registers + MOV R7,LR ; Get EXC_RETURN + BL TZ_StoreContext_S ; Store secure context + MOV LR,R7 ; Set EXC_RETURN + POP {R1,R2,R3,R7} ; Restore registers + MOV R0,LR ; Get EXC_RETURN + LSLS R0,R0,#25 ; Check domain of interrupted thread + BPL Sys_ContextSave1 ; Branch if non-secure + MRS R0,PSP ; Get PSP + STR R0,[R1,#TCB_SP_OFS] ; Store SP + B Sys_ContextSave2 + #endif + +Sys_ContextSave1 + MRS R0,PSP ; Get PSP + SUBS R0,R0,#32 ; Adjust address + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STMIA R0!,{R4-R7} ; Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save R8..R11 + +Sys_ContextSave2 + MOV R0,LR ; Get EXC_RETURN + ADDS R1,R1,#TCB_SF_OFS ; Adjust address + STRB R0,[R1] ; Store stack frame information + +Sys_ContextSwitch + SUBS R3,R3,#8 ; Adjust address + STR R2,[R3] ; osRtxInfo.run: curr = next + +Sys_ContextRestore + #if (DOMAIN_NS == 1) + LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context + PUSH {R2,R3} ; Save registers + BL TZ_LoadContext_S ; Load secure context + POP {R2,R3} ; Restore registers + #endif + +Sys_ContextRestore1 + MOV R1,R2 + ADDS R1,R1,#TCB_SF_OFS ; Adjust offset + LDRB R0,[R1] ; Load stack frame information + MOVS R1,#0xFF + MVNS R1,R1 ; R1=0xFFFFFF00 + ORRS R0,R1 + MOV LR,R0 ; Set EXC_RETURN + + #if (DOMAIN_NS == 1) + LSLS R0,R0,#25 ; Check domain of interrupted thread + BPL Sys_ContextRestore2 ; Branch if non-secure + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + MSR PSP,R0 ; Set PSP + BX LR ; Exit from handler + #else + LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base + MSR PSPLIM,R0 ; Set PSPLIM + #endif + +Sys_ContextRestore2 + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ADDS R0,R0,#16 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Set PSP + SUBS R0,R0,#32 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R4..R7 + +Sys_ContextExit + BX LR ; Exit from handler diff --git a/rtos/rtx5/IAR/irq_armv8mbl_ns.s b/rtos/rtx5/IAR/irq_armv8mbl_ns.s new file mode 100644 index 0000000..d515df3 --- /dev/null +++ b/rtos/rtx5/IAR/irq_armv8mbl_ns.s @@ -0,0 +1,4 @@ + NAME irq_armv8mbl_ns.s +#define DOMAIN_NS 1 +#include "irq_armv8mbl_common.s" + END diff --git a/rtos/rtx5/IAR/irq_armv8mml.s b/rtos/rtx5/IAR/irq_armv8mml.s new file mode 100644 index 0000000..27dc76e --- /dev/null +++ b/rtos/rtx5/IAR/irq_armv8mml.s @@ -0,0 +1,4 @@ + NAME irq_armv8mml.s +#define DOMAIN_NS 0 +#include "irq_armv8mml_common.s" + END diff --git a/rtos/rtx5/IAR/irq_armv8mml_common.s b/rtos/rtx5/IAR/irq_armv8mml_common.s new file mode 100644 index 0000000..629bfe9 --- /dev/null +++ b/rtos/rtx5/IAR/irq_armv8mml_common.s @@ -0,0 +1,272 @@ +;/* +; * Copyright (c) 2016-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: ARMv8M Mainline Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + +#ifndef DOMAIN_NS +#define DOMAIN_NS 0 +#endif + +#ifdef __ARMVFP__ +__FPU_USED EQU 1 +#else +__FPU_USED EQU 0 +#endif + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SM_OFS EQU 48 ; TCB.stack_mem offset +TCB_SP_OFS EQU 56 ; TCB.SP offset +TCB_SF_OFS EQU 34 ; TCB.stack_frame offset +TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset + + + PRESERVE8 + + + SECTION .rodata:DATA:NOROOT(2) + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + SECTION .text:CODE:NOROOT(2) + THUMB + + +SVC_Handler + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + #if (DOMAIN_NS == 1) + IMPORT TZ_LoadContext_S + IMPORT TZ_StoreContext_S + #endif + + TST LR,#0x04 ; Determine return stack from EXC_RETURN bit 2 + ITE EQ + MRSEQ R0,MSP ; Get MSP if return stack is MSP + MRSNE R0,PSP ; Get PSP if return stack is PSP + + LDR R1,[R0,#24] ; Load saved PC from stack + LDRB R1,[R1,#-2] ; Load SVC number + CMP R1,#0 + BNE SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDM R0,{R0-R3,R12} ; Load function parameters and address from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STM R12,{R0-R1} ; Store function return values + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + IT EQ + BXEQ LR ; Exit when threads are the same + + #if (__FPU_USED == 1) + CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted + TST LR,#0x10 ; Check if extended stack frame + BNE SVC_ContextSwitch + LDR R1,=0xE000EF34 ; FPCCR Address + LDR R0,[R1] ; Load FPCCR + BIC R0,R0,#1 ; Clear LSPACT (Lazy state) + STR R0,[R1] ; Store FPCCR + B SVC_ContextSwitch + #else + CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted + #endif + +SVC_ContextSave + #if (DOMAIN_NS == 1) + LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context + PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN + BL TZ_StoreContext_S ; Store secure context + POP {R1,R2,R3,LR} ; Restore registers and EXC_RETURN + #endif + +SVC_ContextSave1 + MRS R0,PSP ; Get PSP + STMDB R0!,{R4-R11} ; Save R4..R11 + #if (__FPU_USED == 1) + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31 + #endif + +SVC_ContextSave2 + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STRB LR,[R1,#TCB_SF_OFS] ; Store stack frame information + +SVC_ContextSwitch + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + #if (DOMAIN_NS == 1) + LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context + PUSH {R2,R3} ; Save registers + BL TZ_LoadContext_S ; Load secure context + POP {R2,R3} ; Restore registers + #endif + +SVC_ContextRestore1 + LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base + LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information + MSR PSPLIM,R0 ; Set PSPLIM + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN + + #if (DOMAIN_NS == 1) + TST LR,#0x40 ; Check domain of interrupted thread + BNE SVC_ContextRestore2 ; Branch if secure + #endif + + #if (__FPU_USED == 1) + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 + #endif + LDMIA R0!,{R4-R11} ; Restore R4..R11 + +SVC_ContextRestore2 + MSR PSP,R0 ; Set PSP + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Exit ; Branch if out of range + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDR R12,[R2,R1,LSL #2] ; Load address of SVC function + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STR R0,[R12] ; Store function return value + + BX LR ; Return from handler + + +PendSV_Handler + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,LR} ; Restore EXC_RETURN + B Sys_Context + + +SysTick_Handler + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,LR} ; Restore EXC_RETURN + B Sys_Context + + + +Sys_Context + EXPORT Sys_Context + IMPORT osRtxInfo + #if (DOMAIN_NS == 1) + IMPORT TZ_LoadContext_S + IMPORT TZ_StoreContext_S + #endif + + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + IT EQ + BXEQ LR ; Exit when threads are the same + +Sys_ContextSave + #if (DOMAIN_NS == 1) + LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context + PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN + BL TZ_StoreContext_S ; Store secure context + POP {R1,R2,R3,LR} ; Restore registers and EXC_RETURN + TST LR,#0x40 ; Check domain of interrupted thread + IT NE + MRSNE R0,PSP ; Get PSP + BNE Sys_ContextSave2 ; Branch if secure + #endif + +Sys_ContextSave1 + MRS R0,PSP ; Get PSP + STMDB R0!,{R4-R11} ; Save R4..R11 + #if (__FPU_USED == 1) + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31 + #endif + +Sys_ContextSave2 + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STRB LR,[R1,#TCB_SF_OFS] ; Store stack frame information + +Sys_ContextSwitch + STR R2,[R3] ; osRtxInfo.run: curr = next + +Sys_ContextRestore + #if (DOMAIN_NS == 1) + LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier + CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context + PUSH {R2,R3} ; Save registers + BL TZ_LoadContext_S ; Load secure context + POP {R2,R3} ; Restore registers + #endif + +Sys_ContextRestore1 + LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base + LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information + MSR PSPLIM,R0 ; Set PSPLIM + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN + + #if (DOMAIN_NS == 1) + TST LR,#0x40 ; Check domain of interrupted thread + BNE Sys_ContextRestore2 ; Branch if secure + #endif + + #if (__FPU_USED == 1) + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 + #endif + LDMIA R0!,{R4-R11} ; Restore R4..R11 + +Sys_ContextRestore2 + MSR PSP,R0 ; Set PSP + +Sys_ContextExit + BX LR ; Exit from handler diff --git a/rtos/rtx5/IAR/irq_armv8mml_ns.s b/rtos/rtx5/IAR/irq_armv8mml_ns.s new file mode 100644 index 0000000..452f9b0 --- /dev/null +++ b/rtos/rtx5/IAR/irq_armv8mml_ns.s @@ -0,0 +1,4 @@ + NAME irq_armv8mml_ns.s +#define DOMAIN_NS 1 +#include "irq_armv8mml_common.s" + END diff --git a/rtos/rtx5/IAR/irq_ca.s b/rtos/rtx5/IAR/irq_ca.s new file mode 100644 index 0000000..975b30d --- /dev/null +++ b/rtos/rtx5/IAR/irq_ca.s @@ -0,0 +1,441 @@ +;/* +; * Copyright (c) 2013-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-A Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + NAME irq_ca.s + +MODE_FIQ EQU 0x11 +MODE_IRQ EQU 0x12 +MODE_SVC EQU 0x13 +MODE_ABT EQU 0x17 +MODE_UND EQU 0x1B + +CPSR_BIT_T EQU 0x20 + +K_STATE_RUNNING EQU 2 ; osKernelState_t::osKernelRunning +I_K_STATE_OFS EQU 8 ; osRtxInfo.kernel.state offset +I_TICK_IRQN_OFS EQU 16 ; osRtxInfo.tick_irqn offset +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SP_FRAME EQU 34 ; osRtxThread_t.stack_frame offset +TCB_SP_OFS EQU 56 ; osRtxThread_t.sp offset + + + PRESERVE8 + + + SECTION .rodata:DATA:NOROOT(2) + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + SECTION .data:DATA:NOROOT(2) + EXPORT IRQ_PendSV +IRQ_NestLevel DCD 0 ; IRQ nesting level counter +IRQ_PendSV DCB 0 ; Pending SVC flag + + + SECTION .text:CODE:NOROOT(2) + + +Undef_Handler + EXPORT Undef_Handler + IMPORT CUndefHandler + + SRSFD SP!, #MODE_UND + PUSH {R0-R4, R12} ; Save APCS corruptible registers to UND mode stack + + MRS R0, SPSR + TST R0, #CPSR_BIT_T ; Check mode + MOVEQ R1, #4 ; R1 = 4 ARM mode + MOVNE R1, #2 ; R1 = 2 Thumb mode + SUB R0, LR, R1 + LDREQ R0, [R0] ; ARM mode - R0 points to offending instruction + BEQ Undef_Cont + + ; Thumb instruction + ; Determine if it is a 32-bit Thumb instruction + LDRH R0, [R0] + MOV R2, #0x1C + CMP R2, R0, LSR #11 + BHS Undef_Cont ; 16-bit Thumb instruction + + ; 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction + LDRH R2, [LR] + ORR R0, R2, R0, LSL #16 +Undef_Cont + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + ; R0 =Offending instruction, R1 =2(Thumb) or =4(ARM) + BL CUndefHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + LDR LR, [SP, #24] ; Restore stacked LR and possibly adjust for retry + SUB LR, LR, R0 + LDR R0, [SP, #28] ; Restore stacked SPSR + MSR SPSR_CXSF, R0 + CLREX ; Clear exclusive monitor + POP {R0-R4, R12} ; Restore stacked APCS registers + ADD SP, SP, #8 ; Adjust SP for already-restored banked registers + MOVS PC, LR + + +PAbt_Handler + EXPORT PAbt_Handler + IMPORT CPAbtHandler + + SUB LR, LR, #4 ; Pre-adjust LR + SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack + MRC p15, 0, R0, c5, c0, 1 ; IFSR + MRC p15, 0, R1, c6, c0, 2 ; IFAR + + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + BL CPAbtHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + CLREX ; Clear exclusive monitor + POP {R0-R4, R12} ; Restore stack APCS registers + RFEFD SP! ; Return from exception + + +DAbt_Handler + EXPORT DAbt_Handler + IMPORT CDAbtHandler + + SUB LR, LR, #8 ; Pre-adjust LR + SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack + PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack + MRC p15, 0, R0, c5, c0, 0 ; DFSR + MRC p15, 0, R1, c6, c0, 0 ; DFAR + + MOV R2, LR ; Set LR to third argument + + AND R12, SP, #4 ; Ensure stack is 8-byte aligned + SUB SP, SP, R12 ; Adjust stack + PUSH {R12, LR} ; Store stack adjustment and dummy LR + + BL CDAbtHandler + + POP {R12, LR} ; Get stack adjustment & discard dummy LR + ADD SP, SP, R12 ; Unadjust stack + + CLREX ; Clear exclusive monitor + POP {R0-R4, R12} ; Restore stacked APCS registers + RFEFD SP! ; Return from exception + + +IRQ_Handler + EXPORT IRQ_Handler + IMPORT IRQ_GetActiveIRQ + IMPORT IRQ_GetHandler + IMPORT IRQ_EndOfInterrupt + + SUB LR, LR, #4 ; Pre-adjust LR + SRSFD SP!, #MODE_SVC ; Save LR_irq and SPSR_irq on to the SVC stack + CPS #MODE_SVC ; Change to SVC mode + PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + ADD R1, R1, #1 ; Increment IRQ nesting level + STR R1, [R0] + + MOV R3, SP ; Move SP into R3 + AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R3 ; Adjust stack + PUSH {R3, R4} ; Store stack adjustment(R3) and user data(R4) + + BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0 + MOV R4, R0 ; Move interrupt ID to R4 + + BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID + CMP R0, #0 ; Check if handler address is 0 + BEQ IRQ_End ; If 0, end interrupt and return + + CPSIE i ; Re-enable interrupts + BLX R0 ; Call IRQ handler + CPSID i ; Disable interrupts + +IRQ_End + MOV R0, R4 ; Move interrupt ID to R0 + BLX IRQ_EndOfInterrupt ; Signal end of interrupt + + POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4) + ADD SP, SP, R3 ; Unadjust stack + + BL osRtxContextSwitch ; Continue in context switcher + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + SUBS R1, R1, #1 ; Decrement IRQ nesting level + STR R1, [R0] + + CLREX ; Clear exclusive monitor for interrupted code + POP {R0-R3, R12, LR} ; Restore stacked APCS registers + RFEFD SP! ; Return from IRQ handler + + +SVC_Handler + EXPORT SVC_Handler + IMPORT IRQ_Disable + IMPORT IRQ_Enable + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + SRSFD SP!, #MODE_SVC ; Store SPSR_svc and LR_svc onto SVC stack + PUSH {R12, LR} + + MRS R12, SPSR ; Load SPSR + TST R12, #CPSR_BIT_T ; Thumb bit set? + LDRHNE R12, [LR,#-2] ; Thumb: load halfword + BICNE R12, R12, #0xFF00 ; extract SVC number + LDREQ R12, [LR,#-4] ; ARM: load word + BICEQ R12, R12, #0xFF000000 ; extract SVC number + CMP R12, #0 ; Compare SVC number + BNE SVC_User ; Branch if User SVC + + PUSH {R0-R3} + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + ADD R1, R1, #1 ; Increment IRQ nesting level + STR R1, [R0] + + LDR R0, =osRtxInfo + LDR R1, [R0, #I_K_STATE_OFS] ; Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING ; Check osKernelRunning + BLT SVC_FuncCall ; Continue if kernel is not running + LDR R0, [R0, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + BLX IRQ_Disable ; Disable OS Tick interrupt +SVC_FuncCall + POP {R0-R3} + + LDR R12, [SP] ; Reload R12 from stack + + CPSIE i ; Re-enable interrupts + BLX R12 ; Branch to SVC function + CPSID i ; Disable interrupts + + SUB SP, SP, #4 + STM SP, {SP}^ ; Store SP_usr onto stack + POP {R12} ; Pop SP_usr into R12 + SUB R12, R12, #16 ; Adjust pointer to SP_usr + LDMDB R12, {R2,R3} ; Load return values from SVC function + PUSH {R0-R3} ; Push return values to stack + + LDR R0, =osRtxInfo + LDR R1, [R0, #I_K_STATE_OFS] ; Load RTX5 kernel state + CMP R1, #K_STATE_RUNNING ; Check osKernelRunning + BLT SVC_ContextCheck ; Continue if kernel is not running + LDR R0, [R0, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + BLX IRQ_Enable ; Enable OS Tick interrupt + +SVC_ContextCheck + BL osRtxContextSwitch ; Continue in context switcher + + LDR R0, =IRQ_NestLevel + LDR R1, [R0] + SUB R1, R1, #1 ; Decrement IRQ nesting level + STR R1, [R0] + + CLREX ; Clear exclusive monitor + POP {R0-R3, R12, LR} ; Restore stacked APCS registers + RFEFD SP! ; Return from exception + +SVC_User + PUSH {R4, R5} + LDR R5,=osRtxUserSVC ; Load address of SVC table + LDR R4,[R5] ; Load SVC maximum number + CMP R12,R4 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + LDR R12,[R5,R12,LSL #2] ; Load SVC Function Address + BLX R12 ; Call SVC Function +SVC_Done + CLREX ; Clear exclusive monitor + POP {R4, R5, R12, LR} + RFEFD SP! ; Return from exception + + +osRtxContextSwitch + EXPORT osRtxContextSwitch + IMPORT osRtxPendSV_Handler + IMPORT osRtxInfo + IMPORT IRQ_Disable + IMPORT IRQ_Enable + + PUSH {LR} + + ; Check interrupt nesting level + LDR R0, =IRQ_NestLevel + LDR R1, [R0] ; Load IRQ nest level + CMP R1, #1 + BNE osRtxContextExit ; Nesting interrupts, exit context switcher + + LDR R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run + LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next + LDR R2, =IRQ_PendSV ; Load address of IRQ_PendSV flag + LDRB R3, [R2] ; Load PendSV flag + + CMP R0, R1 ; Check if context switch is required + BNE osRtxContextCheck ; Not equal, check if context save required + CMP R3, #1 ; Compare IRQ_PendSV value + BNE osRtxContextExit ; No post processing (and no context switch requested) + +osRtxContextCheck + STR R1, [R12] ; Store run.next as run.curr + ; R0 = curr, R1 = next, R2 = &IRQ_PendSV, R3 = IRQ_PendSV, R12 = &osRtxInfo.thread.run + PUSH {R1-R3, R12} + + CMP R0, #0 ; Is osRtxInfo.thread.run.curr == 0 + BEQ osRtxPostProcess ; Current deleted, skip context save + +osRtxContextSave + MOV LR, R0 ; Move &osRtxInfo.thread.run.curr to LR + MOV R0, SP ; Move SP_svc into R0 + ADD R0, R0, #20 ; Adjust SP_svc to R0 of the basic frame + SUB SP, SP, #4 + STM SP, {SP}^ ; Save SP_usr to current stack + POP {R1} ; Pop SP_usr into R1 + + SUB R1, R1, #64 ; Adjust SP_usr to R4 of the basic frame + STMIA R1!, {R4-R11} ; Save R4-R11 to user stack + LDMIA R0!, {R4-R8} ; Load stacked R0-R3,R12 into R4-R8 + STMIA R1!, {R4-R8} ; Store them to user stack + STM R1, {LR}^ ; Store LR_usr directly + ADD R1, R1, #4 ; Adjust user sp to PC + LDMIB R0!, {R5-R6} ; Load current PC, CPSR + STMIA R1!, {R5-R6} ; Restore user PC and CPSR + + SUB R1, R1, #64 ; Adjust SP_usr to stacked R4 + + ; Check if VFP state need to be saved + MRC p15, 0, R2, c1, c0, 2 ; VFP/NEON access enabled? (CPACR) + AND R2, R2, #0x00F00000 + CMP R2, #0x00F00000 + BNE osRtxContextSave1 ; Continue, no VFP + + VMRS R2, FPSCR + STMDB R1!, {R2,R12} ; Push FPSCR, maintain 8-byte alignment + + VSTMDB R1!, {D0-D15} ; Save D0-D15 + #ifdef __ARM_ADVANCED_SIMD__ + VSTMDB R1!, {D16-D31} ; Save D16-D31 + #endif + + LDRB R2, [LR, #TCB_SP_FRAME] ; Load osRtxInfo.thread.run.curr frame info + #ifdef __ARM_ADVANCED_SIMD__ + ORR R2, R2, #4 ; NEON state + #else + ORR R2, R2, #2 ; VFP state + #endif + STRB R2, [LR, #TCB_SP_FRAME] ; Store VFP/NEON state + +osRtxContextSave1 + STR R1, [LR, #TCB_SP_OFS] ; Store user sp to osRtxInfo.thread.run.curr + +osRtxPostProcess + ; RTX IRQ post processing check + POP {R8-R11} ; Pop R8 = run.next, R9 = &IRQ_PendSV, R10 = IRQ_PendSV, R11 = &osRtxInfo.thread.run + CMP R10, #1 ; Compare PendSV value + BNE osRtxContextRestore ; Skip post processing if not pending + + MOV R4, SP ; Move SP_svc into R4 + AND R4, R4, #4 ; Get stack adjustment to ensure 8-byte alignment + SUB SP, SP, R4 ; Adjust stack + + ; Disable OS Tick + LDR R5, =osRtxInfo ; Load address of osRtxInfo + LDR R5, [R5, #I_TICK_IRQN_OFS] ; Load OS Tick irqn + MOV R0, R5 ; Set it as function parameter + BLX IRQ_Disable ; Disable OS Tick interrupt + MOV R6, #0 ; Set PendSV clear value + B osRtxPendCheck +osRtxPendExec + STRB R6, [R9] ; Clear PendSV flag + CPSIE i ; Re-enable interrupts + BLX osRtxPendSV_Handler ; Post process pending objects + CPSID i ; Disable interrupts +osRtxPendCheck + LDR R8, [R11, #4] ; Load osRtxInfo.thread.run.next + STR R8, [R11] ; Store run.next as run.curr + LDRB R0, [R9] ; Load PendSV flag + CMP R0, #1 ; Compare PendSV value + BEQ osRtxPendExec ; Branch to PendExec if PendSV is set + + ; Re-enable OS Tick + MOV R0, R5 ; Restore irqn as function parameter + BLX IRQ_Enable ; Enable OS Tick interrupt + + ADD SP, SP, R4 ; Restore stack adjustment + +osRtxContextRestore + LDR LR, [R8, #TCB_SP_OFS] ; Load next osRtxThread_t.sp + LDRB R2, [R8, #TCB_SP_FRAME] ; Load next osRtxThread_t.stack_frame + + ANDS R2, R2, #0x6 ; Check stack frame for VFP context + MRC p15, 0, R2, c1, c0, 2 ; Read CPACR + ANDEQ R2, R2, #0xFF0FFFFF ; VFP/NEON state not stacked, disable VFP/NEON + ORRNE R2, R2, #0x00F00000 ; VFP/NEON state is stacked, enable VFP/NEON + MCR p15, 0, R2, c1, c0, 2 ; Write CPACR + BEQ osRtxContextRestore1 ; No VFP + ISB ; Sync if VFP was enabled + #ifdef __ARM_ADVANCED_SIMD__ + VLDMIA LR!, {D16-D31} ; Restore D16-D31 + #endif + VLDMIA LR!, {D0-D15} ; Restore D0-D15 + LDR R2, [LR] + VMSR FPSCR, R2 ; Restore FPSCR + ADD LR, LR, #8 ; Adjust sp pointer to R4 + +osRtxContextRestore1 + LDMIA LR!, {R4-R11} ; Restore R4-R11 + ADD R12, LR, #32 ; Adjust sp and save it into R12 + PUSH {R12} ; Push sp onto stack + LDM SP, {SP}^ ; Restore SP_usr directly + ADD SP, SP, #4 ; Adjust SP_svc + LDMIA LR!, {R0-R3, R12} ; Load user registers R0-R3,R12 + STMIB SP!, {R0-R3, R12} ; Store them to SP_svc + LDM LR, {LR}^ ; Restore LR_usr directly + LDMIB LR!, {R0-R1} ; Load user registers PC,CPSR + ADD SP, SP, #4 + STMIB SP!, {R0-R1} ; Store them to SP_svc + SUB SP, SP, #32 ; Adjust SP_svc to stacked LR + +osRtxContextExit + POP {PC} ; Return + + END diff --git a/rtos/rtx5/IAR/irq_cm0.s b/rtos/rtx5/IAR/irq_cm0.s new file mode 100644 index 0000000..3ca51f6 --- /dev/null +++ b/rtos/rtx5/IAR/irq_cm0.s @@ -0,0 +1,158 @@ +;/* +; * Copyright (c) 2013-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M0 Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + + NAME irq_cm0.s + + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset + + + PRESERVE8 + SECTION .rodata:DATA:NOROOT(2) + + + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + THUMB + SECTION .text:CODE:NOROOT(2) + + +SVC_Handler + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + MOV R0,LR + LSRS R0,R0,#3 ; Determine return stack from EXC_RETURN bit 2 + BCC SVC_MSP ; Branch if return stack is MSP + MRS R0,PSP ; Get PSP + +SVC_Number + LDR R1,[R0,#24] ; Load saved PC from stack + SUBS R1,R1,#2 ; Point to SVC instruction + LDRB R1,[R1] ; Load SVC number + CMP R1,#0 + BNE SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R7 ; Call service function + POP {R2,R3} ; Restore SP and EXC_RETURN + STMIA R2!,{R0-R1} ; Store function return values + MOV LR,R3 ; Set EXC_RETURN + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ SVC_Exit ; Branch when threads are the same + + CMP R1,#0 + BEQ SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + MRS R0,PSP ; Get PSP + SUBS R0,R0,#32 ; Calculate SP + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STMIA R0!,{R4-R7} ; Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save R8..R11 + +SVC_ContextSwitch + SUBS R3,R3,#8 ; Adjust address + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ADDS R0,R0,#16 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Set PSP + SUBS R0,R0,#32 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R4..R7 + + MOVS R0,#~0xFFFFFFFD + MVNS R0,R0 ; Set EXC_RETURN value + BX R0 ; Exit from handler + +SVC_MSP + MRS R0,MSP ; Get MSP + B SVC_Number + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Exit ; Branch if out of range + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LSLS R1,R1,#2 + LDR R3,[R2,R1] ; Load address of SVC function + MOV R12,R3 + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R12 ; Call service function + POP {R2,R3} ; Restore SP and EXC_RETURN + STR R0,[R2] ; Store function return value + MOV LR,R3 ; Set EXC_RETURN + + BX LR ; Return from handler + + +PendSV_Handler + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + +SysTick_Handler + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + + END diff --git a/rtos/rtx5/IAR/irq_cm3.s b/rtos/rtx5/IAR/irq_cm3.s new file mode 100644 index 0000000..29fe1b7 --- /dev/null +++ b/rtos/rtx5/IAR/irq_cm3.s @@ -0,0 +1,130 @@ +;/* +; * Copyright (c) 2013-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M3 Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + + NAME irq_cm3.s + + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset + + + PRESERVE8 + SECTION .rodata:DATA:NOROOT(2) + + + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + THUMB + SECTION .text:CODE:NOROOT(2) + + +SVC_Handler + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + TST LR,#0x04 ; Determine return stack from EXC_RETURN bit 2 + ITE EQ + MRSEQ R0,MSP ; Get MSP if return stack is MSP + MRSNE R0,PSP ; Get PSP if return stack is PSP + + LDR R1,[R0,#24] ; Load saved PC from stack + LDRB R1,[R1,#-2] ; Load SVC number + CBNZ R1,SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDM R0,{R0-R3,R12} ; Load function parameters and address from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STM R12,{R0-R1} ; Store function return values + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + IT EQ + BXEQ LR ; Exit when threads are the same + + CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + STMDB R12!,{R4-R11} ; Save R4..R11 + STR R12,[R1,#TCB_SP_OFS] ; Store SP + +SVC_ContextSwitch + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + LDMIA R0!,{R4-R11} ; Restore R4..R11 + MSR PSP,R0 ; Set PSP + + MVN LR,#~0xFFFFFFFD ; Set EXC_RETURN value + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Exit ; Branch if out of range + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDR R12,[R2,R1,LSL #2] ; Load address of SVC function + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STR R0,[R12] ; Store function return value + + BX LR ; Return from handler + + +PendSV_Handler + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + +SysTick_Handler + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + + END diff --git a/rtos/rtx5/IAR/irq_cm4f.s b/rtos/rtx5/IAR/irq_cm4f.s new file mode 100644 index 0000000..5a95648 --- /dev/null +++ b/rtos/rtx5/IAR/irq_cm4f.s @@ -0,0 +1,146 @@ +;/* +; * Copyright (c) 2013-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. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M4F Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + + NAME irq_cm4f.s + + +I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset +TCB_SF_OFS EQU 34 ; TCB.stack_frame offset + + + PRESERVE8 + SECTION .rodata:DATA:NOROOT(2) + + + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + THUMB + SECTION .text:CODE:NOROOT(2) + + +SVC_Handler + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + TST LR,#0x04 ; Determine return stack from EXC_RETURN bit 2 + ITE EQ + MRSEQ R0,MSP ; Get MSP if return stack is MSP + MRSNE R0,PSP ; Get PSP if return stack is PSP + + LDR R1,[R0,#24] ; Load saved PC from stack + LDRB R1,[R1,#-2] ; Load SVC number + CBNZ R1,SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDM R0,{R0-R3,R12} ; Load function parameters and address from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STM R12,{R0-R1} ; Store function return values + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + IT EQ + BXEQ LR ; Exit when threads are the same + + CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted + TST LR,#0x10 ; Check if extended stack frame + BNE SVC_ContextSwitch + LDR R1,=0xE000EF34 ; FPCCR Address + LDR R0,[R1] ; Load FPCCR + BIC R0,R0,#1 ; Clear LSPACT (Lazy state) + STR R0,[R1] ; Store FPCCR + B SVC_ContextSwitch + +SVC_ContextSave + STMDB R12!,{R4-R11} ; Save R4..R11 + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 + STR R12,[R1,#TCB_SP_OFS] ; Store SP + STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information + +SVC_ContextSwitch + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN + + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 + LDMIA R0!,{R4-R11} ; Restore R4..R11 + MSR PSP,R0 ; Set PSP + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Exit ; Branch if out of range + + PUSH {R0,LR} ; Save SP and EXC_RETURN + LDR R12,[R2,R1,LSL #2] ; Load address of SVC function + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore SP and EXC_RETURN + STR R0,[R12] ; Store function return value + + BX LR ; Return from handler + + +PendSV_Handler + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + +SysTick_Handler + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + + END diff --git a/rtos/rtx5/Makefile b/rtos/rtx5/Makefile new file mode 100644 index 0000000..2be9548 --- /dev/null +++ b/rtos/rtx5/Makefile @@ -0,0 +1,34 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +obj-y += GCC/ + +obj-y += rtx_config/ + +CFLAGS_rtx_lib.o += -DOS_IDLE_THREAD_NAME=\"idle\" \ + -DOS_TIMER_THREAD_NAME=\"timer\" + +subdir-ccflags-y += -DOS_CLOCK_NOMINAL=$(OS_CLOCK_NOMINAL) + +ifneq ($(OS_IDLESTKSIZE),) +subdir-ccflags-y += -DOS_IDLE_THREAD_STACK_SIZE=$(OS_IDLESTKSIZE) +endif + +ifneq ($(OS_FIFOSZ),) +subdir-ccflags-y += -DOS_ISR_FIFO_QUEUE=$(OS_FIFOSZ) +endif + +ifneq ($(OS_SCHEDULERSTKSIZE),) +CFLAGS_rtx_lib.o += -DOS_SCHEDULERSTKSIZE=$(OS_SCHEDULERSTKSIZE) +endif + +ifneq ($(DEBUG_SLEEP),) +subdir-ccflags-y += -DDEBUG_SLEEP=$(DEBUG_SLEEP) +endif + +subdir-ccflags-y += -Irtos/rtx5/rtx_config + diff --git a/rtos/rtx5/RTE_Components.h b/rtos/rtx5/RTE_Components.h new file mode 100644 index 0000000..717ad12 --- /dev/null +++ b/rtos/rtx5/RTE_Components.h @@ -0,0 +1,7 @@ +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + +#include "plat_addr_map.h" +#define CMSIS_device_header _TO_STRING(CONCAT_SUFFIX(CHIP_ID_LITERAL, h)) + +#endif diff --git a/rtos/rtx5/cmsis_os1.c b/rtos/rtx5/cmsis_os1.c new file mode 100644 index 0000000..b645d7c --- /dev/null +++ b/rtos/rtx5/cmsis_os1.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2013-2017 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 10. January 2017 + * $Revision: V1.2 + * + * Project: CMSIS-RTOS API V1 + * Title: cmsis_os_v1.c V1 module file + *---------------------------------------------------------------------------*/ + +#include +#include "cmsis_os.h" +#include "rtx_os.h" + +#if (osCMSIS >= 0x20000U) + + +// Thread +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) { + + if (thread_def == NULL) { + return (osThreadId)NULL; + } + return osThreadNew((osThreadFunc_t)thread_def->pthread, argument, &thread_def->attr); +} + + +// Signals + +#define SignalMask ((1U< 0U) && (flags < 0x80000000U)) { + event.status = osEventSignal; + event.value.signals = (int32_t)flags; + } else { + switch ((int32_t)flags) { + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = osEventTimeout; + break; + case osErrorParameter: + event.status = osErrorValue; + break; + default: + event.status = (osStatus)flags; + break; + } + } + return event; +} + + +// Timer +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { + + if (timer_def == NULL) { + return (osTimerId)NULL; + } + return osTimerNew((osTimerFunc_t)timer_def->ptimer, type, argument, &timer_def->attr); +} + + +// Mutex +osMutexId osMutexCreate (const osMutexDef_t *mutex_def) { + + if (mutex_def == NULL) { + return (osMutexId)NULL; + } + return osMutexNew(mutex_def); +} + + +// Semaphore + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0U)) + +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + + if (semaphore_def == NULL) { + return (osSemaphoreId)NULL; + } + return osSemaphoreNew(osRtxSemaphoreTokenLimit, (uint32_t)count, semaphore_def); +} + +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + osStatus_t status; + uint32_t count; + + status = osSemaphoreAcquire(semaphore_id, millisec); + switch (status) { + case osOK: + count = osSemaphoreGetCount(semaphore_id); + return ((int32_t)count + 1); + case osErrorResource: + case osErrorTimeout: + return 0; + default: + break; + } + return -1; +} + +#endif // Semaphore + + +// Memory Pool + +#if (defined(osFeature_Pool) && (osFeature_Pool != 0)) + +osPoolId osPoolCreate (const osPoolDef_t *pool_def) { + + if (pool_def == NULL) { + return (osPoolId)NULL; + } + return ((osPoolId)(osMemoryPoolNew(pool_def->pool_sz, pool_def->item_sz, &pool_def->attr))); +} + +void *osPoolAlloc (osPoolId pool_id) { + return osMemoryPoolAlloc((osMemoryPoolId_t)pool_id, 0U); +} + +void *osPoolCAlloc (osPoolId pool_id) { + void *block; + uint32_t block_size; + + block_size = osMemoryPoolGetBlockSize((osMemoryPoolId_t)pool_id); + if (block_size == 0U) { + return NULL; + } + block = osMemoryPoolAlloc((osMemoryPoolId_t)pool_id, 0U); + if (block != NULL) { + memset(block, 0, block_size); + } + return block; +} + +osStatus osPoolFree (osPoolId pool_id, void *block) { + return osMemoryPoolFree((osMemoryPoolId_t)pool_id, block); +} + +#endif // Memory Pool + + +// Message Queue + +#if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0)) + +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { + (void)thread_id; + + if (queue_def == NULL) { + return (osMessageQId)NULL; + } + return ((osMessageQId)(osMessageQueueNew(queue_def->queue_sz, sizeof(uint32_t), &queue_def->attr))); +} + +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + return osMessageQueuePut((osMessageQueueId_t)queue_id, &info, 0U, millisec); +} + +osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { + osStatus_t status; + osEvent event; + uint32_t message; + + status = osMessageQueueGet((osMessageQueueId_t)queue_id, &message, NULL, millisec); + switch (status) { + case osOK: + event.status = osEventMessage; + event.value.v = message; + break; + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = osEventTimeout; + break; + default: + event.status = status; + break; + } + return event; +} + +uint32_t osMessageGetSpace (osMessageQId queue_id) +{ + return osMessageQueueGetSpace(queue_id); +} + +#endif // Message Queue + + +// Mail Queue + +#if (defined(osFeature_MailQ) && (osFeature_MailQ != 0)) + +typedef struct os_mail_queue_s { + osMemoryPoolId_t mp_id; + osMessageQueueId_t mq_id; +} os_mail_queue_t; + +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { + os_mail_queue_t *ptr; + (void)thread_id; + + if (queue_def == NULL) { + return (osMailQId)NULL; + } + + ptr = queue_def->mail; + if (ptr == NULL) { + return (osMailQId)NULL; + } + + ptr->mp_id = osMemoryPoolNew (queue_def->queue_sz, queue_def->item_sz, &queue_def->mp_attr); + ptr->mq_id = osMessageQueueNew(queue_def->queue_sz, sizeof(void *), &queue_def->mq_attr); + if ((ptr->mp_id == (osMemoryPoolId_t)NULL) || (ptr->mq_id == (osMessageQueueId_t)NULL)) { + if (ptr->mp_id != (osMemoryPoolId_t)NULL) { + osMemoryPoolDelete(ptr->mp_id); + } + if (ptr->mq_id != (osMessageQueueId_t)NULL) { + osMessageQueueDelete(ptr->mq_id); + } + return (osMailQId)NULL; + } + + return (osMailQId)ptr; +} + +void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + + if (ptr == NULL) { + return NULL; + } + return osMemoryPoolAlloc(ptr->mp_id, millisec); +} + +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + void *block; + uint32_t block_size; + + if (ptr == NULL) { + return NULL; + } + block_size = osMemoryPoolGetBlockSize(ptr->mp_id); + if (block_size == 0U) { + return NULL; + } + block = osMemoryPoolAlloc(ptr->mp_id, millisec); + if (block != NULL) { + memset(block, 0, block_size); + } + + return block; + +} + +osStatus osMailPut (osMailQId queue_id, const void *mail) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + + if (ptr == NULL) { + return osErrorParameter; + } + if (mail == NULL) { + return osErrorValue; + } + return osMessageQueuePut(ptr->mq_id, &mail, 0U, 0U); +} + +osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + osStatus_t status; + osEvent event; + void *mail; + + if (ptr == NULL) { + event.status = osErrorParameter; + return event; + } + + status = osMessageQueueGet(ptr->mq_id, &mail, NULL, millisec); + switch (status) { + case osOK: + event.status = osEventMail; + event.value.p = mail; + break; + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = osEventTimeout; + break; + default: + event.status = status; + break; + } + return event; +} + +osStatus osMailFree (osMailQId queue_id, void *mail) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + + if (ptr == NULL) { + return osErrorParameter; + } + if (mail == NULL) { + return osErrorValue; + } + return osMemoryPoolFree(ptr->mp_id, mail); +} + +#endif // Mail Queue + +#endif // osCMSIS diff --git a/rtos/rtx5/os_systick.c b/rtos/rtx5/os_systick.c new file mode 100644 index 0000000..b44a361 --- /dev/null +++ b/rtos/rtx5/os_systick.c @@ -0,0 +1,151 @@ +/**************************************************************************//** + * @file os_systick.c + * @brief CMSIS OS Tick SysTick implementation + * @version V1.0.1 + * @date 24. November 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017-2017 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 "hal_timer.h" + +#include "os_tick.h" + +//lint -emacro((923,9078),SCB,SysTick) "cast from unsigned long to pointer" +#include "RTE_Components.h" +#include CMSIS_device_header + +#ifdef SysTick + +#ifndef SYSTICK_IRQ_PRIORITY +#define SYSTICK_IRQ_PRIORITY 0xFFU +#endif + +#ifdef CALIB_SLOW_TIMER +#define OS_CLOCK (CONFIG_SYSTICK_HZ * (OS_CLOCK_NOMINAL / CONFIG_SYSTICK_HZ_NOMINAL)) +#else +#define OS_CLOCK OS_CLOCK_NOMINAL +#endif + +uint32_t SystemCoreClock; + +#define SYSTICK_EXTERNAL_CLOCK 1 + +void SystemCoreClockUpdate() +{ + SystemCoreClock = OS_CLOCK; +} + +static uint8_t PendST; +// Setup OS Tick. +__WEAK int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { + uint32_t load; + (void)handler; + + if (freq == 0U) { + //lint -e{904} "Return statement before end of function" + return (-1); + } + + load = (SystemCoreClock / freq) - 1U; + if (load > 0x00FFFFFFU) { + //lint -e{904} "Return statement before end of function" + return (-1); + } + + // Set SysTick Interrupt Priority +#if ((defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0)) || \ + (defined(__CORTEX_M) && (__CORTEX_M == 7U))) + SCB->SHPR[11] = SYSTICK_IRQ_PRIORITY; +#elif (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + SCB->SHPR[1] |= ((uint32_t)SYSTICK_IRQ_PRIORITY << 24); +#elif ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ + (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0))) + SCB->SHP[11] = SYSTICK_IRQ_PRIORITY; +#elif (defined(__ARM_ARCH_6M__) && (__ARM_ARCH_6M__ != 0)) + SCB->SHP[1] |= ((uint32_t)SYSTICK_IRQ_PRIORITY << 24); +#else +#error "Unknown ARM Core!" +#endif + +#if (SYSTICK_EXTERNAL_CLOCK) + SysTick->CTRL = SysTick_CTRL_TICKINT_Msk; +#else + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk; +#endif + SysTick->LOAD = load; + SysTick->VAL = 0U; + + PendST = 0U; + + return (0); +} + +/// Enable OS Tick. +__WEAK void OS_Tick_Enable (void) { + + if (PendST != 0U) { + PendST = 0U; + SCB->ICSR = SCB_ICSR_PENDSTSET_Msk; + } + + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + +/// Disable OS Tick. +__WEAK void OS_Tick_Disable (void) { + + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + + if ((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) != 0U) { + SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk; + PendST = 1U; + } +} + +// Acknowledge OS Tick IRQ. +__WEAK void OS_Tick_AcknowledgeIRQ (void) { + (void)SysTick->CTRL; +} + +// Get OS Tick IRQ number. +__WEAK int32_t OS_Tick_GetIRQn (void) { + return ((int32_t)SysTick_IRQn); +} + +// Get OS Tick clock. +__WEAK uint32_t OS_Tick_GetClock (void) { + return (SystemCoreClock); +} + +// Get OS Tick interval. +__WEAK uint32_t OS_Tick_GetInterval (void) { + return (SysTick->LOAD + 1U); +} + +// Get OS Tick count value. +__WEAK uint32_t OS_Tick_GetCount (void) { + uint32_t load = SysTick->LOAD; + return (load - SysTick->VAL); +} + +// Get OS Tick overflow status. +__WEAK uint32_t OS_Tick_GetOverflow (void) { + return ((SysTick->CTRL >> 16) & 1U); +} + +#endif // SysTick diff --git a/rtos/rtx5/rtx_config/Makefile b/rtos/rtx5/rtx_config/Makefile new file mode 100644 index 0000000..ef2b9c7 --- /dev/null +++ b/rtos/rtx5/rtx_config/Makefile @@ -0,0 +1,11 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.S)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +subdir-ccflags-y += -Irtos/rtx5/ + diff --git a/rtos/rtx5/rtx_config/rtx_config.c b/rtos/rtx5/rtx_config/rtx_config.c new file mode 100644 index 0000000..5e6a67e --- /dev/null +++ b/rtos/rtx5/rtx_config/rtx_config.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * $Revision: V5.1.0 + * + * Project: CMSIS-RTOS RTX + * Title: RTX Configuration + * + * ----------------------------------------------------------------------------- + */ + +#include "cmsis_compiler.h" +#include "RTE_Components.h" +#include CMSIS_device_header +#include "rtx_os.h" +#include "rtx_config.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_sleep.h" + +#include "cmsis_os2.h" +#include "hwtimer_list.h" + +void WEAK sleep(void) +{ + hal_sleep_enter_sleep(); +} + +extern void rtx_show_all_threads(void); +#if TASK_HUNG_CHECK_ENABLED +extern void check_hung_threads(void); +#endif + +// OS Idle Thread +__NO_RETURN void osRtxIdleThread (void *argument) { + unsigned int os_ticks; + HWTIMER_ID timer; + int ret; +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 2) + unsigned int start_time; + unsigned int start_os_time; + unsigned int start_tick; +#endif +#if !(defined(ROM_BUILD) || defined(PROGRAMMER)) + ret = hal_trace_crash_dump_register(HAL_TRACE_CRASH_DUMP_MODULE_SYS, rtx_show_all_threads); + ASSERT(ret == 0, "IdleTask: Failed to register crash dump callback"); +#endif + timer = hwtimer_alloc(NULL, NULL); + ASSERT(timer, "IdleTask: Failed to alloc sleep timer"); + + for (;;) { +#if TASK_HUNG_CHECK_ENABLED + check_hung_threads(); +#endif + + if (hal_sleep_light_sleep() == HAL_SLEEP_STATUS_DEEP) { + os_ticks = osKernelSuspend(); + if (os_ticks) { +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 2) + __disable_irq(); +#endif + ret = hwtimer_start(timer, MS_TO_HWTICKS(os_ticks * OS_TICK_FREQ / 1000)); +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 2) + start_time = hal_sys_timer_get(); + start_tick = SysTick->VAL; + start_os_time = osRtxInfo.kernel.tick; + __enable_irq(); +#endif + if (ret == 0) { + sleep(); + ret = hwtimer_stop(timer); + } +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 2) + if (hal_sys_timer_get() - start_time >= MS_TO_HWTICKS(1)) { + TRACE(5,"[%u/0x%X][%2u/%u] os_idle_demon start timer. tick:%u", + TICKS_TO_MS(start_time), start_time, start_tick, start_os_time, os_ticks); + } +#endif + } + osKernelResume(os_ticks); + } + } +} + +// OS Error Callback function +__WEAK uint32_t osRtxErrorNotify (uint32_t code, void *object_id) { + (void)object_id; + + switch (code) { + case osRtxErrorStackUnderflow: + // Stack overflow detected for thread (thread_id=object_id) + break; + case osRtxErrorISRQueueOverflow: + // ISR Queue overflow detected when inserting object (object_id) + break; + case osRtxErrorTimerQueueOverflow: + // User Timer Callback Queue overflow detected for timer (timer_id=object_id) + break; + case osRtxErrorClibSpace: + // Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM + break; + case osRtxErrorClibMutex: + // Standard C/C++ library mutex initialization failed + break; + default: + // Reserved + break; + } + ASSERT(0, "osRtxErrorNotify, code: %08x\n", code); +//return 0U; +} diff --git a/rtos/rtx5/rtx_config/rtx_config.h b/rtos/rtx5/rtx_config/rtx_config.h new file mode 100644 index 0000000..0583504 --- /dev/null +++ b/rtos/rtx5/rtx_config/rtx_config.h @@ -0,0 +1,578 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * $Revision: V5.5.0 + * + * Project: CMSIS-RTOS RTX + * Title: RTX Configuration definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_CONFIG_H_ +#define RTX_CONFIG_H_ + +#ifdef _RTE_ +#include "RTE_Components.h" +#ifdef RTE_RTX_CONFIG_H +#include RTE_RTX_CONFIG_H +#endif +#endif + +//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- + +// System Configuration +// ======================= + +// Global Dynamic Memory size [bytes] <0-1073741824:8> +// Defines the combined global dynamic memory size. +// Default: 4096 +#ifndef OS_DYNAMIC_MEM_SIZE +#define OS_DYNAMIC_MEM_SIZE 0x3000 +#endif + +// Kernel Tick Frequency [Hz] <1-1000000> +// Defines base time unit for delays and timeouts. +// Default: 1000 (1ms tick) +#ifndef OS_TICK_FREQ +#define OS_TICK_FREQ 1000 +#endif + +// Round-Robin Thread switching +// Enables Round-Robin Thread switching. +#ifndef OS_ROBIN_ENABLE +#define OS_ROBIN_ENABLE 1 +#endif + +// Round-Robin Timeout <1-1000> +// Defines how many ticks a thread will execute before a thread switch. +// Default: 5 +#ifndef OS_ROBIN_TIMEOUT +#define OS_ROBIN_TIMEOUT 5 +#endif + +// + +// ISR FIFO Queue +// <4=> 4 entries <8=> 8 entries <12=> 12 entries <16=> 16 entries +// <24=> 24 entries <32=> 32 entries <48=> 48 entries <64=> 64 entries +// <96=> 96 entries <128=> 128 entries <196=> 196 entries <256=> 256 entries +// RTOS Functions called from ISR store requests to this buffer. +// Default: 16 entries +#ifndef OS_ISR_FIFO_QUEUE +#define OS_ISR_FIFO_QUEUE 16 +#endif + +// Object Memory usage counters +// Enables object memory usage counters (requires RTX source variant). +#ifndef OS_OBJ_MEM_USAGE +#define OS_OBJ_MEM_USAGE 0 +#endif + +// + +// Thread Configuration +// ======================= + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_THREAD_OBJ_MEM +#define OS_THREAD_OBJ_MEM 0 +#endif + +// Number of user Threads <1-1000> +// Defines maximum number of user threads that can be active at the same time. +// Applies to user threads with system provided memory for control blocks. +#ifndef OS_THREAD_NUM +#define OS_THREAD_NUM 1 +#endif + +// Number of user Threads with default Stack size <0-1000> +// Defines maximum number of user threads with default stack size. +// Applies to user threads with zero stack size specified. +#ifndef OS_THREAD_DEF_STACK_NUM +#define OS_THREAD_DEF_STACK_NUM 0 +#endif + +// Total Stack size [bytes] for user Threads with user-provided Stack size <0-1073741824:8> +// Defines the combined stack size for user threads with user-provided stack size. +// Applies to user threads with user-provided stack size and system provided memory for stack. +// Default: 0 +#ifndef OS_THREAD_USER_STACK_SIZE +#define OS_THREAD_USER_STACK_SIZE 0 +#endif + +// + +// Default Thread Stack size [bytes] <96-1073741824:8> +// Defines stack size for threads with zero stack size specified. +// Default: 256 +#ifndef OS_STACK_SIZE +#define OS_STACK_SIZE 0x1000 +#endif + +// Idle Thread Stack size [bytes] <72-1073741824:8> +// Defines stack size for Idle thread. +// Default: 256 +#ifndef OS_IDLE_THREAD_STACK_SIZE +#define OS_IDLE_THREAD_STACK_SIZE 256 +#endif + +// Idle Thread TrustZone Module Identifier +// Defines TrustZone Thread Context Management Identifier. +// Applies only to cores with TrustZone technology. +// Default: 0 (not used) +#ifndef OS_IDLE_THREAD_TZ_MOD_ID +#define OS_IDLE_THREAD_TZ_MOD_ID 0 +#endif + +// Stack overrun checking +// Enables stack overrun check at thread switch. +// Enabling this option increases slightly the execution time of a thread switch. +#ifndef OS_STACK_CHECK +#define OS_STACK_CHECK 1 +#endif + +// Stack usage watermark +// Initializes thread stack with watermark pattern for analyzing stack usage. +// Enabling this option increases significantly the execution time of thread creation. +#ifndef OS_STACK_WATERMARK +#define OS_STACK_WATERMARK 0 +#endif + +// Processor mode for Thread execution +// <0=> Unprivileged mode +// <1=> Privileged mode +// Default: Privileged mode +#ifndef OS_PRIVILEGE_MODE +#define OS_PRIVILEGE_MODE 1 +#endif + +// + +// Timer Configuration +// ====================== + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_TIMER_OBJ_MEM +#define OS_TIMER_OBJ_MEM 0 +#endif + +// Number of Timer objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_TIMER_NUM +#define OS_TIMER_NUM 6 +#endif + +// + +// Timer Thread Priority +// <8=> Low +// <16=> Below Normal <24=> Normal <32=> Above Normal +// <40=> High +// <48=> Realtime +// Defines priority for timer thread +// Default: High +#ifndef OS_TIMER_THREAD_PRIO +#define OS_TIMER_THREAD_PRIO 40 +#endif + +// Timer Thread Stack size [bytes] <0-1073741824:8> +// Defines stack size for Timer thread. +// May be set to 0 when timers are not used. +// Default: 256 +#ifndef OS_TIMER_THREAD_STACK_SIZE +#define OS_TIMER_THREAD_STACK_SIZE 0x1000 +#endif + +// Timer Thread TrustZone Module Identifier +// Defines TrustZone Thread Context Management Identifier. +// Applies only to cores with TrustZone technology. +// Default: 0 (not used) +#ifndef OS_TIMER_THREAD_TZ_MOD_ID +#define OS_TIMER_THREAD_TZ_MOD_ID 0 +#endif + +// Timer Callback Queue entries <0-256> +// Number of concurrent active timer callback functions. +// May be set to 0 when timers are not used. +// Default: 4 +#ifndef OS_TIMER_CB_QUEUE +#define OS_TIMER_CB_QUEUE 16 +#endif + +// + +// Event Flags Configuration +// ============================ + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_EVFLAGS_OBJ_MEM +#define OS_EVFLAGS_OBJ_MEM 0 +#endif + +// Number of Event Flags objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_EVFLAGS_NUM +#define OS_EVFLAGS_NUM 1 +#endif + +// + +// + +// Mutex Configuration +// ====================== + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_MUTEX_OBJ_MEM +#define OS_MUTEX_OBJ_MEM 0 +#endif + +// Number of Mutex objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_MUTEX_NUM +#define OS_MUTEX_NUM 1 +#endif + +// + +// + +// Semaphore Configuration +// ========================== + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_SEMAPHORE_OBJ_MEM +#define OS_SEMAPHORE_OBJ_MEM 0 +#endif + +// Number of Semaphore objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_SEMAPHORE_NUM +#define OS_SEMAPHORE_NUM 1 +#endif + +// + +// + +// Memory Pool Configuration +// ============================ + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_MEMPOOL_OBJ_MEM +#define OS_MEMPOOL_OBJ_MEM 0 +#endif + +// Number of Memory Pool objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_MEMPOOL_NUM +#define OS_MEMPOOL_NUM 1 +#endif + +// Data Storage Memory size [bytes] <0-1073741824:8> +// Defines the combined data storage memory size. +// Applies to objects with system provided memory for data storage. +// Default: 0 +#ifndef OS_MEMPOOL_DATA_SIZE +#define OS_MEMPOOL_DATA_SIZE 0 +#endif + +// + +// + +// Message Queue Configuration +// ============================== + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_MSGQUEUE_OBJ_MEM +#define OS_MSGQUEUE_OBJ_MEM 0 +#endif + +// Number of Message Queue objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_MSGQUEUE_NUM +#define OS_MSGQUEUE_NUM 1 +#endif + +// Data Storage Memory size [bytes] <0-1073741824:8> +// Defines the combined data storage memory size. +// Applies to objects with system provided memory for data storage. +// Default: 0 +#ifndef OS_MSGQUEUE_DATA_SIZE +#define OS_MSGQUEUE_DATA_SIZE 0 +#endif + +// + +// + +// Event Recorder Configuration +// =============================== + +// Global Initialization +// Initialize Event Recorder during 'osKernelInitialize'. +#ifndef OS_EVR_INIT +#define OS_EVR_INIT 0 +#endif + +// Start recording +// Start event recording after initialization. +#ifndef OS_EVR_START +#define OS_EVR_START 1 +#endif + +// Global Event Filter Setup +// Initial recording level applied to all components. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_LEVEL +#define OS_EVR_LEVEL 0x00U +#endif + +// RTOS Event Filter Setup +// Recording levels for RTX components. +// Only applicable if events for the respective component are generated. + +// Memory Management +// Recording level for Memory Management events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_MEMORY_LEVEL +#define OS_EVR_MEMORY_LEVEL 0x01U +#endif + +// Kernel +// Recording level for Kernel events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_KERNEL_LEVEL +#define OS_EVR_KERNEL_LEVEL 0x01U +#endif + +// Thread +// Recording level for Thread events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_THREAD_LEVEL +#define OS_EVR_THREAD_LEVEL 0x05U +#endif + +// Generic Wait +// Recording level for Generic Wait events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_WAIT_LEVEL +#define OS_EVR_WAIT_LEVEL 0x01U +#endif + +// Thread Flags +// Recording level for Thread Flags events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_THFLAGS_LEVEL +#define OS_EVR_THFLAGS_LEVEL 0x01U +#endif + +// Event Flags +// Recording level for Event Flags events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_EVFLAGS_LEVEL +#define OS_EVR_EVFLAGS_LEVEL 0x01U +#endif + +// Timer +// Recording level for Timer events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_TIMER_LEVEL +#define OS_EVR_TIMER_LEVEL 0x01U +#endif + +// Mutex +// Recording level for Mutex events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_MUTEX_LEVEL +#define OS_EVR_MUTEX_LEVEL 0x01U +#endif + +// Semaphore +// Recording level for Semaphore events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_SEMAPHORE_LEVEL +#define OS_EVR_SEMAPHORE_LEVEL 0x01U +#endif + +// Memory Pool +// Recording level for Memory Pool events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_MEMPOOL_LEVEL +#define OS_EVR_MEMPOOL_LEVEL 0x01U +#endif + +// Message Queue +// Recording level for Message Queue events. +// Error events +// API function call events +// Operation events +// Detailed operation events +// +#ifndef OS_EVR_MSGQUEUE_LEVEL +#define OS_EVR_MSGQUEUE_LEVEL 0x01U +#endif + +// + +// + +// RTOS Event Generation +// Enables event generation for RTX components (requires RTX source variant). + +// Memory Management +// Enables Memory Management event generation. +#ifndef OS_EVR_MEMORY +#define OS_EVR_MEMORY 1 +#endif + +// Kernel +// Enables Kernel event generation. +#ifndef OS_EVR_KERNEL +#define OS_EVR_KERNEL 1 +#endif + +// Thread +// Enables Thread event generation. +#ifndef OS_EVR_THREAD +#define OS_EVR_THREAD 1 +#endif + +// Generic Wait +// Enables Generic Wait event generation. +#ifndef OS_EVR_WAIT +#define OS_EVR_WAIT 1 +#endif + +// Thread Flags +// Enables Thread Flags event generation. +#ifndef OS_EVR_THFLAGS +#define OS_EVR_THFLAGS 1 +#endif + +// Event Flags +// Enables Event Flags event generation. +#ifndef OS_EVR_EVFLAGS +#define OS_EVR_EVFLAGS 1 +#endif + +// Timer +// Enables Timer event generation. +#ifndef OS_EVR_TIMER +#define OS_EVR_TIMER 1 +#endif + +// Mutex +// Enables Mutex event generation. +#ifndef OS_EVR_MUTEX +#define OS_EVR_MUTEX 1 +#endif + +// Semaphore +// Enables Semaphore event generation. +#ifndef OS_EVR_SEMAPHORE +#define OS_EVR_SEMAPHORE 1 +#endif + +// Memory Pool +// Enables Memory Pool event generation. +#ifndef OS_EVR_MEMPOOL +#define OS_EVR_MEMPOOL 1 +#endif + +// Message Queue +// Enables Message Queue event generation. +#ifndef OS_EVR_MSGQUEUE +#define OS_EVR_MSGQUEUE 1 +#endif + +// + +// + +// Number of Threads which use standard C/C++ library libspace +// (when thread specific memory allocation is not used). +#if (OS_THREAD_OBJ_MEM == 0) +#define OS_THREAD_LIBSPACE_NUM 4 +#else +#define OS_THREAD_LIBSPACE_NUM OS_THREAD_NUM +#endif + +//------------- <<< end of configuration section >>> --------------------------- + +#endif // RTX_CONFIG_H_ diff --git a/rtos/rtx5/rtx_core_c.h b/rtos/rtx5/rtx_core_c.h new file mode 100644 index 0000000..343f316 --- /dev/null +++ b/rtos/rtx5/rtx_core_c.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex Core definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_CORE_C_H_ +#define RTX_CORE_C_H_ + +//lint -emacro((923,9078),SCB) "cast from unsigned long to pointer" [MISRA Note 9] +#include "RTE_Components.h" +#include CMSIS_device_header + +#if ((!defined(__ARM_ARCH_6M__)) && \ + (!defined(__ARM_ARCH_7A__)) && \ + (!defined(__ARM_ARCH_7M__)) && \ + (!defined(__ARM_ARCH_7EM__)) && \ + (!defined(__ARM_ARCH_8M_BASE__)) && \ + (!defined(__ARM_ARCH_8M_MAIN__))) +#error "Unknown Arm Architecture!" +#endif + +#if (defined(__ARM_ARCH_7A__) && (__ARM_ARCH_7A__ != 0)) +#include "rtx_core_ca.h" +#else +#include "rtx_core_cm.h" +#endif + +#endif // RTX_CORE_C_H_ diff --git a/rtos/rtx5/rtx_core_ca.h b/rtos/rtx5/rtx_core_ca.h new file mode 100644 index 0000000..fd496a6 --- /dev/null +++ b/rtos/rtx5/rtx_core_ca.h @@ -0,0 +1,1121 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-A Core definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_CORE_CA_H_ +#define RTX_CORE_CA_H_ + +#ifndef RTX_CORE_C_H_ +#include "RTE_Components.h" +#include CMSIS_device_header +#endif + +#include +typedef bool bool_t; +#define FALSE ((bool_t)0) +#define TRUE ((bool_t)1) + +#define DOMAIN_NS 0 +#define EXCLUSIVE_ACCESS 1 + +#define OS_TICK_HANDLER osRtxTick_Handler + +// CPSR bit definitions +#define CPSR_T_BIT 0x20U +#define CPSR_I_BIT 0x80U +#define CPSR_F_BIT 0x40U + +// CPSR mode bitmasks +#define CPSR_MODE_USER 0x10U +#define CPSR_MODE_SYSTEM 0x1FU + +/// xPSR_Initialization Value +/// \param[in] privileged true=privileged, false=unprivileged +/// \param[in] thumb true=Thumb, false=Arm +/// \return xPSR Init Value +__STATIC_INLINE uint32_t xPSR_InitVal (bool_t privileged, bool_t thumb) { + uint32_t psr; + + if (privileged) { + if (thumb) { + psr = CPSR_MODE_SYSTEM | CPSR_T_BIT; + } else { + psr = CPSR_MODE_SYSTEM; + } + } else { + if (thumb) { + psr = CPSR_MODE_USER | CPSR_T_BIT; + } else { + psr = CPSR_MODE_USER; + } + } + + return psr; +} + +// Stack Frame: +// - VFP-D32: D16-31, D0-D15, FPSCR, Reserved, R4-R11, R0-R3, R12, LR, PC, CPSR +// - VFP-D16: D0-D15, FPSCR, Reserved, R4-R11, R0-R3, R12, LR, PC, CPSR +// - Basic: R4-R11, R0-R3, R12, LR, PC, CPSR + +/// Stack Frame Initialization Value +#define STACK_FRAME_INIT_VAL 0x00U + +/// Stack Offset of Register R0 +/// \param[in] stack_frame Stack Frame +/// \return R0 Offset +__STATIC_INLINE uint32_t StackOffsetR0 (uint8_t stack_frame) { + uint32_t offset; + + if ((stack_frame & 0x04U) != 0U) { + offset = (32U*8U) + (2U*4U) + (8U*4U); + } else if ((stack_frame & 0x02U) != 0U) { + offset = (16U*8U) + (2U*4U) + (8U*4U); + } else { + offset = (8U*4U); + } + return offset; +} + + +// ==== Emulated Cortex-M functions ==== + +/// Get xPSR Register - emulate M profile: SP_usr - (8*4) +/// \return xPSR Register value +#if defined(__CC_ARM) +#pragma push +#pragma arm +static __asm uint32_t __get_PSP (void) { + sub sp, sp, #4 + stm sp, {sp}^ + pop {r0} + sub r0, r0, #32 + bx lr +} +#pragma pop +#else +#ifdef __ICCARM__ +__arm +#else +__attribute__((target("arm"))) +#endif +__STATIC_INLINE uint32_t __get_PSP (void) { + register uint32_t ret; + + __ASM volatile ( + "sub sp,sp,#4\n\t" + "stm sp,{sp}^\n\t" + "pop {%[ret]}\n\t" + "sub %[ret],%[ret],#32\n\t" + : [ret] "=&l" (ret) + : + : "memory" + ); + + return ret; +} +#endif + +/// Set Control Register - not needed for A profile +/// \param[in] control Control Register value to set +__STATIC_INLINE void __set_CONTROL(uint32_t control) { + (void)control; +} + + +// ==== Core functions ==== + +/// Check if running Privileged +/// \return true=privileged, false=unprivileged +__STATIC_INLINE bool_t IsPrivileged (void) { + return (__get_mode() != CPSR_MODE_USER); +} + +/// Check if in IRQ Mode +/// \return true=IRQ, false=thread +__STATIC_INLINE bool_t IsIrqMode (void) { + return ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM)); +} + +/// Check if IRQ is Masked +/// \return true=masked, false=not masked +__STATIC_INLINE bool_t IsIrqMasked (void) { + return FALSE; +} + + +// ==== Core Peripherals functions ==== + +extern uint8_t IRQ_PendSV; + +/// Setup SVC and PendSV System Service Calls (not needed on Cortex-A) +__STATIC_INLINE void SVC_Setup (void) { +} + +/// Get Pending SV (Service Call) Flag +/// \return Pending SV Flag +__STATIC_INLINE uint8_t GetPendSV (void) { + return (IRQ_PendSV); +} + +/// Clear Pending SV (Service Call) Flag +__STATIC_INLINE void ClrPendSV (void) { + IRQ_PendSV = 0U; +} + +/// Set Pending SV (Service Call) Flag +__STATIC_INLINE void SetPendSV (void) { + IRQ_PendSV = 1U; +} + + +// ==== Service Calls definitions ==== + +#if defined(__CC_ARM) + +#define __SVC_INDIRECT(n) __svc_indirect(n) + +#define SVC0_0N(f,t) \ +__SVC_INDIRECT(0) t svc##f (t(*)()); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + svc##f(svcRtx##f); \ +} + +#define SVC0_0(f,t) \ +__SVC_INDIRECT(0) t svc##f (t(*)()); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + return svc##f(svcRtx##f); \ +} + +#define SVC0_1N(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + svc##f(svcRtx##f,a1); \ +} + +#define SVC0_1(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + return svc##f(svcRtx##f,a1); \ +} + +#define SVC0_2(f,t,t1,t2) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2),t1,t2); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + return svc##f(svcRtx##f,a1,a2); \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2,t3),t1,t2,t3); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + return svc##f(svcRtx##f,a1,a2,a3); \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + return svc##f(svcRtx##f,a1,a2,a3,a4); \ +} + +#elif defined(__ICCARM__) + +#define SVC_ArgF(f) \ + __asm( \ + "mov r12,%0\n" \ + :: "r"(&f): "r12" \ + ); + +#define STRINGIFY(a) #a +#define __SVC_INDIRECT(n) _Pragma(STRINGIFY(swi_number = n)) __swi + +#define SVC0_0N(f,t) \ +__SVC_INDIRECT(0) t svc##f (); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgF(svcRtx##f); \ + svc##f(); \ +} + +#define SVC0_0(f,t) \ +__SVC_INDIRECT(0) t svc##f (); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgF(svcRtx##f); \ + return svc##f(); \ +} + +#define SVC0_1N(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgF(svcRtx##f); \ + svc##f(a1); \ +} + +#define SVC0_1(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgF(svcRtx##f); \ + return svc##f(a1); \ +} + +#define SVC0_2(f,t,t1,t2) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_ArgF(svcRtx##f); \ + return svc##f(a1,a2); \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_ArgF(svcRtx##f); \ + return svc##f(a1,a2,a3); \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_ArgF(svcRtx##f); \ + return svc##f(a1,a2,a3,a4); \ +} + +#else // !(defined(__CC_ARM) || defined(__ICCARM__)) + +#define SVC_RegF "r12" + +#define SVC_ArgN(n) \ +register uint32_t __r##n __ASM("r"#n) + +#define SVC_ArgR(n,a) \ +register uint32_t __r##n __ASM("r"#n) = (uint32_t)a + +#define SVC_ArgF(f) \ +register uint32_t __rf __ASM(SVC_RegF) = (uint32_t)f + +#define SVC_In0 "r"(__rf) +#define SVC_In1 "r"(__rf),"r"(__r0) +#define SVC_In2 "r"(__rf),"r"(__r0),"r"(__r1) +#define SVC_In3 "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2) +#define SVC_In4 "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2),"r"(__r3) + +#define SVC_Out0 +#define SVC_Out1 "=r"(__r0) + +#define SVC_CL0 +#define SVC_CL1 "r1" +#define SVC_CL2 "r0","r1" + +#define SVC_Call0(in, out, cl) \ + __ASM volatile ("svc 0" : out : in : cl) + +#define SVC0_0N(f,t) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In0, SVC_Out0, SVC_CL2); \ +} + +#define SVC0_0(f,t) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgN(0); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In0, SVC_Out1, SVC_CL1); \ + return (t) __r0; \ +} + +#define SVC0_1N(f,t,t1) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgR(0,a1); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In1, SVC_Out0, SVC_CL1); \ +} + +#define SVC0_1(f,t,t1) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgR(0,a1); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In1, SVC_Out1, SVC_CL1); \ + return (t) __r0; \ +} + +#define SVC0_2(f,t,t1,t2) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In2, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgR(2,a3); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In3, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgR(2,a3); \ + SVC_ArgR(3,a4); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In4, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#endif + + +// ==== Exclusive Access Operation ==== + +#if (EXCLUSIVE_ACCESS == 1) + +/// Atomic Access Operation: Write (8-bit) +/// \param[in] mem Memory address +/// \param[in] val Value to write +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint8_t atomic_wr8 (uint8_t *mem, uint8_t val) { + mov r2,r0 +1 + ldrexb r0,[r2] + strexb r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint8_t atomic_wr8 (uint8_t *mem, uint8_t val) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint8_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexb %[ret],[%[mem]]\n\t" + "strexb %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n\t" + : [ret] "=&l" (ret), + [res] "=&l" (res) + : [mem] "l" (mem), + [val] "l" (val) + : "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Set bits (32-bit) +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return New value +#if defined(__CC_ARM) +static __asm uint32_t atomic_set32 (uint32_t *mem, uint32_t bits) { + mov r2,r0 +1 + ldrex r0,[r2] + orr r0,r0,r1 + strex r3,r0,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_set32 (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[val],[%[mem]]\n\t" + "orr %[ret],%[val],%[bits]\n\t" + "strex %[res],%[ret],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Clear bits (32-bit) +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_clr32 (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + bic r4,r0,r1 + strex r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_clr32 (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "bic %[val],%[ret],%[bits]\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Check if all specified bits (32-bit) are active and clear them +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Active bits before clearing or 0 if not active +#if defined(__CC_ARM) +static __asm uint32_t atomic_chk32_all (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + and r4,r0,r1 + cmp r4,r1 + beq %F2 + clrex + movs r0,#0 + pop {r4,pc} +2 + bic r4,r0,r1 + strex r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_chk32_all (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "and %[val],%[ret],%[bits]\n\t" + "cmp %[val],%[bits]\n\t" + "beq 2f\n\t" + "clrex\n\t" + "movs %[ret],#0\n\t" + "b 3f\n" + "2:\n\t" + "bic %[val],%[ret],%[bits]\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Check if any specified bits (32-bit) are active and clear them +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Active bits before clearing or 0 if not active +#if defined(__CC_ARM) +static __asm uint32_t atomic_chk32_any (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + tst r0,r1 + bne %F2 + clrex + movs r0,#0 + pop {r4,pc} +2 + bic r4,r0,r1 + strex r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_chk32_any (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "tst %[ret],%[bits]\n\t" + "bne 2f\n\t" + "clrex\n\t" + "movs %[ret],#0\n\t" + "b 3f\n" + "2:\n\t" + "bic %[val],%[ret],%[bits]\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (32-bit) +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_inc32 (uint32_t *mem) { + mov r2,r0 +1 + ldrex r0,[r2] + adds r1,r0,#1 + strex r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_inc32 (uint32_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "adds %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (16-bit) if Less Than +/// \param[in] mem Memory address +/// \param[in] max Maximum value +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_inc16_lt (uint16_t *mem, uint16_t max) { + push {r4,lr} + mov r2,r0 +1 + ldrexh r0,[r2] + cmp r1,r0 + bhi %F2 + clrex + pop {r4,pc} +2 + adds r4,r0,#1 + strexh r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint16_t atomic_inc16_lt (uint16_t *mem, uint16_t max) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "cmp %[max],%[ret]\n\t" + "bhi 2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "adds %[val],%[ret],#1\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [max] "l" (max) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (16-bit) and clear on Limit +/// \param[in] mem Memory address +/// \param[in] max Maximum value +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_inc16_lim (uint16_t *mem, uint16_t lim) { + push {r4,lr} + mov r2,r0 +1 + ldrexh r0,[r2] + adds r4,r0,#1 + cmp r1,r4 + bhi %F2 + movs r4,#0 +2 + strexh r3,r4,[r2] + cmp r3,#0 + bne %B1 + pop {r4,pc} +} +#else +__STATIC_INLINE uint16_t atomic_inc16_lim (uint16_t *mem, uint16_t lim) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "adds %[val],%[ret],#1\n\t" + "cmp %[lim],%[val]\n\t" + "bhi 2f\n\t" + "movs %[val],#0\n" + "2:\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [lim] "l" (lim) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Decrement (32-bit) +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_dec32 (uint32_t *mem) { + mov r2,r0 +1 + ldrex r0,[r2] + subs r1,r0,#1 + strex r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_dec32 (uint32_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "subs %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Decrement (32-bit) if Not Zero +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_dec32_nz (uint32_t *mem) { + mov r2,r0 +1 + ldrex r0,[r2] + cmp r0,#0 + bne %F2 + clrex + bx lr +2 + subs r1,r0,#1 + strex r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_dec32_nz (uint32_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "cmp %[ret],#0\n\t" + "bne 2f\n" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "subs %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Decrement (16-bit) if Not Zero +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_dec16_nz (uint16_t *mem) { + mov r2,r0 +1 + ldrexh r0,[r2] + cmp r0,#0 + bne %F2 + clrex + bx lr +2 + subs r1,r0,#1 + strexh r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE uint16_t atomic_dec16_nz (uint16_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "cmp %[ret],#0\n\t" + "bne 2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "subs %[val],%[ret],#1\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Link Get +/// \param[in] root Root address +/// \return Link +#if defined(__CC_ARM) +static __asm void *atomic_link_get (void **root) { + mov r2,r0 +1 + ldrex r0,[r2] + cmp r0,#0 + bne %F2 + clrex + bx lr +2 + ldr r1,[r0] + strex r3,r1,[r2] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE void *atomic_link_get (void **root) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register void *ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[root]]\n\t" + "cmp %[ret],#0\n\t" + "bne 2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "ldr %[val],[%[ret]]\n\t" + "strex %[res],%[val],[%[root]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [root] "l" (root) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Link Put +/// \param[in] root Root address +/// \param[in] lnk Link +#if defined(__CC_ARM) +static __asm void atomic_link_put (void **root, void *link) { +1 + ldr r2,[r0] + str r2,[r1] + dmb + ldrex r2,[r0] + ldr r3,[r1] + cmp r3,r2 + bne %B1 + strex r3,r1,[r0] + cmp r3,#0 + bne %B1 + bx lr +} +#else +__STATIC_INLINE void atomic_link_put (void **root, void *link) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val1, val2, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldr %[val1],[%[root]]\n\t" + "str %[val1],[%[link]]\n\t" + "dmb\n\t" + "ldrex %[val1],[%[root]]\n\t" + "ldr %[val2],[%[link]]\n\t" + "cmp %[val2],%[val1]\n\t" + "bne 1b\n\t" + "strex %[res],%[link],[%[root]]\n\t" + "cmp %[res],#0\n\t" + "bne 1b\n" + : [val1] "=&l" (val1), + [val2] "=&l" (val2), + [res] "=&l" (res) + : [root] "l" (root), + [link] "l" (link) + : "cc", "memory" + ); +} +#endif + +#endif // (EXCLUSIVE_ACCESS == 1) + + +#endif // RTX_CORE_CA_H_ diff --git a/rtos/rtx5/rtx_core_cm.h b/rtos/rtx5/rtx_core_cm.h new file mode 100644 index 0000000..c4dea34 --- /dev/null +++ b/rtos/rtx5/rtx_core_cm.h @@ -0,0 +1,1201 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-M Core definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_CORE_CM_H_ +#define RTX_CORE_CM_H_ + +#ifndef RTX_CORE_C_H_ +#include "RTE_Components.h" +#include CMSIS_device_header +#endif + +#include +typedef bool bool_t; +#define FALSE ((bool_t)0) +#define TRUE ((bool_t)1) + +#ifdef RTE_CMSIS_RTOS2_RTX5_ARMV8M_NS +#define DOMAIN_NS 1 +#endif + +#ifndef DOMAIN_NS +#define DOMAIN_NS 0 +#endif + +#if (DOMAIN_NS == 1) +#if ((!defined(__ARM_ARCH_8M_BASE__) || (__ARM_ARCH_8M_BASE__ == 0)) && \ + (!defined(__ARM_ARCH_8M_MAIN__) || (__ARM_ARCH_8M_MAIN__ == 0))) +#error "Non-secure domain requires ARMv8-M Architecture!" +#endif +#endif + +#ifndef EXCLUSIVE_ACCESS +#if ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ + (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0)) || \ + (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) || \ + (defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0))) +#define EXCLUSIVE_ACCESS 1 +#else +#define EXCLUSIVE_ACCESS 0 +#endif +#endif + +#define OS_TICK_HANDLER SysTick_Handler + +/// xPSR_Initialization Value +/// \param[in] privileged true=privileged, false=unprivileged +/// \param[in] thumb true=Thumb, false=ARM +/// \return xPSR Init Value +__STATIC_INLINE uint32_t xPSR_InitVal (bool_t privileged, bool_t thumb) { + (void)privileged; + (void)thumb; + return (0x01000000U); +} + +// Stack Frame: +// - Extended: S16-S31, R4-R11, R0-R3, R12, LR, PC, xPSR, S0-S15, FPSCR +// - Basic: R4-R11, R0-R3, R12, LR, PC, xPSR + +/// Stack Frame Initialization Value (EXC_RETURN[7..0]) +#if (DOMAIN_NS == 1) +#define STACK_FRAME_INIT_VAL 0xBCU +#else +#define STACK_FRAME_INIT_VAL 0xFDU +#endif + +/// Stack Offset of Register R0 +/// \param[in] stack_frame Stack Frame (EXC_RETURN[7..0]) +/// \return R0 Offset +__STATIC_INLINE uint32_t StackOffsetR0 (uint8_t stack_frame) { +#if (__FPU_USED == 1U) + return (((stack_frame & 0x10U) == 0U) ? ((16U+8U)*4U) : (8U*4U)); +#else + (void)stack_frame; + return (8U*4U); +#endif +} + + +// ==== Core functions ==== + +//lint -sem(__get_CONTROL, pure) +//lint -sem(__get_IPSR, pure) +//lint -sem(__get_PRIMASK, pure) +//lint -sem(__get_BASEPRI, pure) + +/// Check if running Privileged +/// \return true=privileged, false=unprivileged +__STATIC_INLINE bool_t IsPrivileged (void) { + return ((__get_CONTROL() & 1U) == 0U); +} + +/// Check if in IRQ Mode +/// \return true=IRQ, false=thread +__STATIC_INLINE bool_t IsIrqMode (void) { + return (__get_IPSR() != 0U); +} + +/// Check if IRQ is Masked +/// \return true=masked, false=not masked +__STATIC_INLINE bool_t IsIrqMasked (void) { +#if ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ + (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0)) || \ + (defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0))) + return ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U)); +#else + return (__get_PRIMASK() != 0U); +#endif +} + + +// ==== Core Peripherals functions ==== + +/// Setup SVC and PendSV System Service Calls +__STATIC_INLINE void SVC_Setup (void) { +#if ((defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0)) || \ + (defined(__CORTEX_M) && (__CORTEX_M == 7U))) + uint32_t p, n; + + SCB->SHPR[10] = 0xFFU; + n = 32U - (uint32_t)__CLZ(~(SCB->SHPR[10] | 0xFFFFFF00U)); + p = NVIC_GetPriorityGrouping(); + if (p >= n) { + n = p + 1U; + } + SCB->SHPR[7] = (uint8_t)(0xFEU << n); +#elif (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + uint32_t n; + + SCB->SHPR[1] |= 0x00FF0000U; + n = SCB->SHPR[1]; + SCB->SHPR[0] |= (n << (8+1)) & 0xFC000000U; +#elif ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ + (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0))) + uint32_t p, n; + + SCB->SHP[10] = 0xFFU; + n = 32U - (uint32_t)__CLZ(~(SCB->SHP[10] | 0xFFFFFF00U)); + p = NVIC_GetPriorityGrouping(); + if (p >= n) { + n = p + 1U; + } + SCB->SHP[7] = (uint8_t)(0xFEU << n); +#elif (defined(__ARM_ARCH_6M__) && (__ARM_ARCH_6M__ != 0)) + uint32_t n; + + SCB->SHP[1] |= 0x00FF0000U; + n = SCB->SHP[1]; + SCB->SHP[0] |= (n << (8+1)) & 0xFC000000U; +#endif +} + +/// Get Pending SV (Service Call) Flag +/// \return Pending SV Flag +__STATIC_INLINE uint8_t GetPendSV (void) { + return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk)) >> 24)); +} + +/// Clear Pending SV (Service Call) Flag +__STATIC_INLINE void ClrPendSV (void) { + SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk; +} + +/// Set Pending SV (Service Call) Flag +__STATIC_INLINE void SetPendSV (void) { + SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; +} + + +// ==== Service Calls definitions ==== + +//lint -save -e9023 -e9024 -e9026 "Function-like macros using '#/##'" [MISRA Note 10] + +#if defined(__CC_ARM) + +#if ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ + (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0)) || \ + (defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0))) +#define __SVC_INDIRECT(n) __svc_indirect(n) +#elif ((defined(__ARM_ARCH_6M__) && (__ARM_ARCH_6M__ != 0)) || \ + (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0))) +#define __SVC_INDIRECT(n) __svc_indirect_r7(n) +#endif + +#define SVC0_0N(f,t) \ +__SVC_INDIRECT(0) t svc##f (t(*)()); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + svc##f(svcRtx##f); \ +} + +#define SVC0_0(f,t) \ +__SVC_INDIRECT(0) t svc##f (t(*)()); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + return svc##f(svcRtx##f); \ +} + +#define SVC0_1N(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + svc##f(svcRtx##f,a1); \ +} + +#define SVC0_1(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + return svc##f(svcRtx##f,a1); \ +} + +#define SVC0_2(f,t,t1,t2) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2),t1,t2); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + return svc##f(svcRtx##f,a1,a2); \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2,t3),t1,t2,t3); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + return svc##f(svcRtx##f,a1,a2,a3); \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + return svc##f(svcRtx##f,a1,a2,a3,a4); \ +} + +#elif defined(__ICCARM__) + +#if ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ + (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0)) || \ + (defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0))) +#define SVC_ArgF(f) \ + __asm( \ + "mov r12,%0\n" \ + :: "r"(&f): "r12" \ + ); +#elif ((defined(__ARM_ARCH_6M__) && (__ARM_ARCH_6M__ != 0)) || \ + (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0))) +#define SVC_ArgF(f) \ + __asm( \ + "mov r7,%0\n" \ + :: "r"(&f): "r7" \ + ); +#endif + +#define STRINGIFY(a) #a +#define __SVC_INDIRECT(n) _Pragma(STRINGIFY(swi_number = n)) __swi + +#define SVC0_0N(f,t) \ +__SVC_INDIRECT(0) t svc##f (); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgF(svcRtx##f); \ + svc##f(); \ +} + +#define SVC0_0(f,t) \ +__SVC_INDIRECT(0) t svc##f (); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgF(svcRtx##f); \ + return svc##f(); \ +} + +#define SVC0_1N(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgF(svcRtx##f); \ + svc##f(a1); \ +} + +#define SVC0_1(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgF(svcRtx##f); \ + return svc##f(a1); \ +} + +#define SVC0_2(f,t,t1,t2) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_ArgF(svcRtx##f); \ + return svc##f(a1,a2); \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_ArgF(svcRtx##f); \ + return svc##f(a1,a2,a3); \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_ArgF(svcRtx##f); \ + return svc##f(a1,a2,a3,a4); \ +} + +#else // !(defined(__CC_ARM) || defined(__ICCARM__)) + +//lint -esym(522,__svc*) "Functions '__svc*' are impure (side-effects)" + +#if ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ + (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0)) || \ + (defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0))) +#define SVC_RegF "r12" +#elif ((defined(__ARM_ARCH_6M__) && (__ARM_ARCH_6M__ != 0)) || \ + (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0))) +#define SVC_RegF "r7" +#endif + +#define SVC_ArgN(n) \ +register uint32_t __r##n __ASM("r"#n) + +#define SVC_ArgR(n,a) \ +register uint32_t __r##n __ASM("r"#n) = (uint32_t)a + +#define SVC_ArgF(f) \ +register uint32_t __rf __ASM(SVC_RegF) = (uint32_t)f + +#define SVC_In0 "r"(__rf) +#define SVC_In1 "r"(__rf),"r"(__r0) +#define SVC_In2 "r"(__rf),"r"(__r0),"r"(__r1) +#define SVC_In3 "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2) +#define SVC_In4 "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2),"r"(__r3) + +#define SVC_Out0 +#define SVC_Out1 "=r"(__r0) + +#define SVC_CL0 +#define SVC_CL1 "r1" +#define SVC_CL2 "r0","r1" + +#define SVC_Call0(in, out, cl) \ + __ASM volatile ("svc 0" : out : in : cl) + +#define SVC0_0N(f,t) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In0, SVC_Out0, SVC_CL2); \ +} + +#define SVC0_0(f,t) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgN(0); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In0, SVC_Out1, SVC_CL1); \ + return (t) __r0; \ +} + +#define SVC0_1N(f,t,t1) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgR(0,a1); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In1, SVC_Out0, SVC_CL1); \ +} + +#define SVC0_1(f,t,t1) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgR(0,a1); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In1, SVC_Out1, SVC_CL1); \ + return (t) __r0; \ +} + +#define SVC0_2(f,t,t1,t2) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In2, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgR(2,a3); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In3, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgR(2,a3); \ + SVC_ArgR(3,a4); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In4, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#endif + +//lint -restore [MISRA Note 10] + + +// ==== Exclusive Access Operation ==== + +#if (EXCLUSIVE_ACCESS == 1) + +//lint ++flb "Library Begin" [MISRA Note 12] + +/// Atomic Access Operation: Write (8-bit) +/// \param[in] mem Memory address +/// \param[in] val Value to write +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint8_t atomic_wr8 (uint8_t *mem, uint8_t val) { + mov r2,r0 +1 + ldrexb r0,[r2] + strexb r3,r1,[r2] + cbz r3,%F2 + b %B1 +2 + bx lr +} +#else +__STATIC_INLINE uint8_t atomic_wr8 (uint8_t *mem, uint8_t val) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint8_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexb %[ret],[%[mem]]\n\t" + "strexb %[res],%[val],[%[mem]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [ret] "=&l" (ret), + [res] "=&l" (res) + : [mem] "l" (mem), + [val] "l" (val) + : "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Set bits (32-bit) +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return New value +#if defined(__CC_ARM) +static __asm uint32_t atomic_set32 (uint32_t *mem, uint32_t bits) { + mov r2,r0 +1 + ldrex r0,[r2] + orr r0,r0,r1 + strex r3,r0,[r2] + cbz r3,%F2 + b %B1 +2 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_set32 (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[val],[%[mem]]\n\t" +#if (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + "mov %[ret],%[val]\n\t" + "orrs %[ret],%[bits]\n\t" +#else + "orr %[ret],%[val],%[bits]\n\t" +#endif + "strex %[res],%[ret],[%[mem]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) +#if (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + : "memory", "cc" +#else + : "memory" +#endif + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Clear bits (32-bit) +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_clr32 (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + bic r4,r0,r1 + strex r3,r4,[r2] + cbz r3,%F2 + b %B1 +2 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_clr32 (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" +#if (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + "mov %[val],%[ret]\n\t" + "bics %[val],%[bits]\n\t" +#else + "bic %[val],%[ret],%[bits]\n\t" +#endif + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) +#if (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + : "memory", "cc" +#else + : "memory" +#endif + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Check if all specified bits (32-bit) are active and clear them +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Active bits before clearing or 0 if not active +#if defined(__CC_ARM) +static __asm uint32_t atomic_chk32_all (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + and r4,r0,r1 + cmp r4,r1 + beq %F2 + clrex + movs r0,#0 + pop {r4,pc} +2 + bic r4,r0,r1 + strex r3,r4,[r2] + cbz r3,%F3 + b %B1 +3 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_chk32_all (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" +#if (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + "mov %[val],%[ret]\n\t" + "ands %[val],%[bits]\n\t" +#else + "and %[val],%[ret],%[bits]\n\t" +#endif + "cmp %[val],%[bits]\n\t" + "beq 2f\n\t" + "clrex\n\t" + "movs %[ret],#0\n\t" + "b 3f\n" + "2:\n\t" +#if (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + "mov %[val],%[ret]\n\t" + "bics %[val],%[bits]\n\t" +#else + "bic %[val],%[ret],%[bits]\n\t" +#endif + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Check if any specified bits (32-bit) are active and clear them +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Active bits before clearing or 0 if not active +#if defined(__CC_ARM) +static __asm uint32_t atomic_chk32_any (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + tst r0,r1 + bne %F2 + clrex + movs r0,#0 + pop {r4,pc} +2 + bic r4,r0,r1 + strex r3,r4,[r2] + cbz r3,%F3 + b %B1 +3 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_chk32_any (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "tst %[ret],%[bits]\n\t" + "bne 2f\n\t" + "clrex\n\t" + "movs %[ret],#0\n\t" + "b 3f\n" + "2:\n\t" +#if (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + "mov %[val],%[ret]\n\t" + "bics %[val],%[bits]\n\t" +#else + "bic %[val],%[ret],%[bits]\n\t" +#endif + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (32-bit) +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_inc32 (uint32_t *mem) { + mov r2,r0 +1 + ldrex r0,[r2] + adds r1,r0,#1 + strex r3,r1,[r2] + cbz r3,%F2 + b %B1 +2 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_inc32 (uint32_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "adds %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (16-bit) if Less Than +/// \param[in] mem Memory address +/// \param[in] max Maximum value +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_inc16_lt (uint16_t *mem, uint16_t max) { + push {r4,lr} + mov r2,r0 +1 + ldrexh r0,[r2] + cmp r1,r0 + bhi %F2 + clrex + pop {r4,pc} +2 + adds r4,r0,#1 + strexh r3,r4,[r2] + cbz r3,%F3 + b %B1 +3 + pop {r4,pc} +} +#else +__STATIC_INLINE uint16_t atomic_inc16_lt (uint16_t *mem, uint16_t max) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "cmp %[max],%[ret]\n\t" + "bhi 2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "adds %[val],%[ret],#1\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [max] "l" (max) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (16-bit) and clear on Limit +/// \param[in] mem Memory address +/// \param[in] max Maximum value +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_inc16_lim (uint16_t *mem, uint16_t lim) { + push {r4,lr} + mov r2,r0 +1 + ldrexh r0,[r2] + adds r4,r0,#1 + cmp r1,r4 + bhi %F2 + movs r4,#0 +2 + strexh r3,r4,[r2] + cbz r3,%F3 + b %B1 +3 + pop {r4,pc} +} +#else +__STATIC_INLINE uint16_t atomic_inc16_lim (uint16_t *mem, uint16_t lim) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "adds %[val],%[ret],#1\n\t" + "cmp %[lim],%[val]\n\t" + "bhi 2f\n\t" + "movs %[val],#0\n" + "2:\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [lim] "l" (lim) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Decrement (32-bit) +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_dec32 (uint32_t *mem) { + mov r2,r0 +1 + ldrex r0,[r2] + subs r1,r0,#1 + strex r3,r1,[r2] + cbz r3,%F2 + b %B1 +2 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_dec32 (uint32_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "subs %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Decrement (32-bit) if Not Zero +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_dec32_nz (uint32_t *mem) { + mov r2,r0 +1 + ldrex r0,[r2] + cbnz r0,%F2 + clrex + bx lr +2 + subs r1,r0,#1 + strex r3,r1,[r2] + cbz r3,%F3 + b %B1 +3 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_dec32_nz (uint32_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "cbnz %[ret],2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "subs %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Decrement (16-bit) if Not Zero +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_dec16_nz (uint16_t *mem) { + mov r2,r0 +1 + ldrexh r0,[r2] + cbnz r0,%F2 + clrex + bx lr +2 + subs r1,r0,#1 + strexh r3,r1,[r2] + cbz r3,%F3 + b %B1 +3 + bx lr +} +#else +__STATIC_INLINE uint16_t atomic_dec16_nz (uint16_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "cbnz %[ret],2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "subs %[val],%[ret],#1\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Link Get +/// \param[in] root Root address +/// \return Link +#if defined(__CC_ARM) +static __asm void *atomic_link_get (void **root) { + mov r2,r0 +1 + ldrex r0,[r2] + cbnz r0,%F2 + clrex + bx lr +2 + ldr r1,[r0] + strex r3,r1,[r2] + cbz r3,%F3 + b %B1 +3 + bx lr +} +#else +__STATIC_INLINE void *atomic_link_get (void **root) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register void *ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[root]]\n\t" + "cbnz %[ret],2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "ldr %[val],[%[ret]]\n\t" + "strex %[res],%[val],[%[root]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [root] "l" (root) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Link Put +/// \param[in] root Root address +/// \param[in] lnk Link +#if defined(__CC_ARM) +static __asm void atomic_link_put (void **root, void *link) { +1 + ldr r2,[r0] + str r2,[r1] + dmb + ldrex r2,[r0] + ldr r3,[r1] + cmp r3,r2 + bne %B1 + strex r3,r1,[r0] + cbz r3,%F2 + b %B1 +2 + bx lr +} +#else +__STATIC_INLINE void atomic_link_put (void **root, void *link) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val1, val2, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldr %[val1],[%[root]]\n\t" + "str %[val1],[%[link]]\n\t" + "dmb\n\t" + "ldrex %[val1],[%[root]]\n\t" + "ldr %[val2],[%[link]]\n\t" + "cmp %[val2],%[val1]\n\t" + "bne 1b\n\t" + "strex %[res],%[link],[%[root]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [val1] "=&l" (val1), + [val2] "=&l" (val2), + [res] "=&l" (res) + : [root] "l" (root), + [link] "l" (link) + : "cc", "memory" + ); +} +#endif + +//lint --flb "Library End" [MISRA Note 12] + +#endif // (EXCLUSIVE_ACCESS == 1) + + +#endif // RTX_CORE_CM_H_ diff --git a/rtos/rtx5/rtx_delay.c b/rtos/rtx5/rtx_delay.c new file mode 100644 index 0000000..9d0cf41 --- /dev/null +++ b/rtos/rtx5/rtx_delay.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Delay functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Service Calls ==== + +/// Wait for Timeout (Time Delay). +/// \note API identical to osDelay +static osStatus_t svcRtxDelay (uint32_t ticks) { + + if (ticks != 0U) { + if (osRtxThreadWaitEnter(osRtxThreadWaitingDelay, ticks)) { + EvrRtxDelayStarted(ticks); + } else { + EvrRtxDelayCompleted(osRtxThreadGetRunning()); + } + } + + return osOK; +} + +/// Wait until specified time. +/// \note API identical to osDelayUntil +static osStatus_t svcRtxDelayUntil (uint32_t ticks) { + + ticks -= osRtxInfo.kernel.tick; + if ((ticks == 0U) || (ticks > 0x7FFFFFFFU)) { + EvrRtxDelayError((int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + if (osRtxThreadWaitEnter(osRtxThreadWaitingDelay, ticks)) { + EvrRtxDelayUntilStarted(ticks); + } else { + EvrRtxDelayCompleted(osRtxThreadGetRunning()); + } + + return osOK; +} + +// Service Calls definitions +//lint ++flb "Library Begin" [MISRA Note 11] +SVC0_1(Delay, osStatus_t, uint32_t) +SVC0_1(DelayUntil, osStatus_t, uint32_t) +//lint --flb "Library End" + + +// ==== Public API ==== + +/// Wait for Timeout (Time Delay). +osStatus_t osDelay (uint32_t ticks) { + osStatus_t status; + + EvrRtxDelay(ticks); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxDelayError((int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcDelay(ticks); + } + return status; +} + +/// Wait until specified time. +osStatus_t osDelayUntil (uint32_t ticks) { + osStatus_t status; + + EvrRtxDelayUntil(ticks); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxDelayError((int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcDelayUntil(ticks); + } + return status; +} diff --git a/rtos/rtx5/rtx_evflags.c b/rtos/rtx5/rtx_evflags.c new file mode 100644 index 0000000..87e94d3 --- /dev/null +++ b/rtos/rtx5/rtx_evflags.c @@ -0,0 +1,582 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Event Flags functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// OS Runtime Object Memory Usage +#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))) +osRtxObjectMemUsage_t osRtxEventFlagsMemUsage \ +__attribute__((section(".data.os.evflags.obj"))) = +{ 0U, 0U, 0U }; +#endif + + +// ==== Helper functions ==== + +/// Set Event Flags. +/// \param[in] ef event flags object. +/// \param[in] flags specifies the flags to set. +/// \return event flags after setting. +static uint32_t EventFlagsSet (os_event_flags_t *ef, uint32_t flags) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t event_flags; + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + ef->event_flags |= flags; + event_flags = ef->event_flags; + + if (primask == 0U) { + __enable_irq(); + } +#else + event_flags = atomic_set32(&ef->event_flags, flags); +#endif + + return event_flags; +} + +/// Clear Event Flags. +/// \param[in] ef event flags object. +/// \param[in] flags specifies the flags to clear. +/// \return event flags before clearing. +static uint32_t EventFlagsClear (os_event_flags_t *ef, uint32_t flags) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t event_flags; + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + event_flags = ef->event_flags; + ef->event_flags &= ~flags; + + if (primask == 0U) { + __enable_irq(); + } +#else + event_flags = atomic_clr32(&ef->event_flags, flags); +#endif + + return event_flags; +} + +/// Check Event Flags. +/// \param[in] ef event flags object. +/// \param[in] flags specifies the flags to check. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \return event flags before clearing or 0 if specified flags have not been set. +static uint32_t EventFlagsCheck (os_event_flags_t *ef, uint32_t flags, uint32_t options) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask; +#endif + uint32_t event_flags; + + if ((options & osFlagsNoClear) == 0U) { +#if (EXCLUSIVE_ACCESS == 0) + primask = __get_PRIMASK(); + __disable_irq(); + + event_flags = ef->event_flags; + if ((((options & osFlagsWaitAll) != 0U) && ((event_flags & flags) != flags)) || + (((options & osFlagsWaitAll) == 0U) && ((event_flags & flags) == 0U))) { + event_flags = 0U; + } else { + ef->event_flags &= ~flags; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if ((options & osFlagsWaitAll) != 0U) { + event_flags = atomic_chk32_all(&ef->event_flags, flags); + } else { + event_flags = atomic_chk32_any(&ef->event_flags, flags); + } +#endif + } else { + event_flags = ef->event_flags; + if ((((options & osFlagsWaitAll) != 0U) && ((event_flags & flags) != flags)) || + (((options & osFlagsWaitAll) == 0U) && ((event_flags & flags) == 0U))) { + event_flags = 0U; + } + } + + return event_flags; +} + + +// ==== Post ISR processing ==== + +/// Event Flags post ISR processing. +/// \param[in] ef event flags object. +static void osRtxEventFlagsPostProcess (os_event_flags_t *ef) { + os_thread_t *thread; + os_thread_t *thread_next; + uint32_t event_flags; + + // Check if Threads are waiting for Event Flags + thread = ef->thread_list; + while (thread != NULL) { + thread_next = thread->thread_next; + event_flags = EventFlagsCheck(ef, thread->wait_flags, thread->flags_options); + if (event_flags != 0U) { + osRtxThreadListRemove(thread); + osRtxThreadWaitExit(thread, event_flags, FALSE); + EvrRtxEventFlagsWaitCompleted(ef, thread->wait_flags, thread->flags_options, event_flags); + } + thread = thread_next; + } +} + + +// ==== Service Calls ==== + +/// Create and Initialize an Event Flags object. +/// \note API identical to osEventFlagsNew +static osEventFlagsId_t svcRtxEventFlagsNew (const osEventFlagsAttr_t *attr) { + os_event_flags_t *ef; + uint8_t flags; + const char *name; + + // Process attributes + if (attr != NULL) { + name = attr->name; + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + ef = attr->cb_mem; + if (ef != NULL) { + //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7] + if ((((uint32_t)ef & 3U) != 0U) || (attr->cb_size < sizeof(os_event_flags_t))) { + EvrRtxEventFlagsError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxEventFlagsError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + } else { + name = NULL; + ef = NULL; + } + + // Allocate object memory if not provided + if (ef == NULL) { + if (osRtxInfo.mpi.event_flags != NULL) { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + ef = osRtxMemoryPoolAlloc(osRtxInfo.mpi.event_flags); + } else { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + ef = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_event_flags_t), 1U); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + if (ef != NULL) { + uint32_t used; + osRtxEventFlagsMemUsage.cnt_alloc++; + used = osRtxEventFlagsMemUsage.cnt_alloc - osRtxEventFlagsMemUsage.cnt_free; + if (osRtxEventFlagsMemUsage.max_used < used) { + osRtxEventFlagsMemUsage.max_used = used; + } + } +#endif + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + if (ef != NULL) { + // Initialize control block + ef->id = osRtxIdEventFlags; + ef->flags = flags; + ef->name = name; + ef->thread_list = NULL; + ef->event_flags = 0U; + + // Register post ISR processing function + osRtxInfo.post_process.event_flags = osRtxEventFlagsPostProcess; + + EvrRtxEventFlagsCreated(ef, ef->name); + } else { + EvrRtxEventFlagsError(NULL, (int32_t)osErrorNoMemory); + } + + return ef; +} + +/// Get name of an Event Flags object. +/// \note API identical to osEventFlagsGetName +static const char *svcRtxEventFlagsGetName (osEventFlagsId_t ef_id) { + os_event_flags_t *ef = osRtxEventFlagsId(ef_id); + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags)) { + EvrRtxEventFlagsGetName(ef, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + EvrRtxEventFlagsGetName(ef, ef->name); + + return ef->name; +} + +/// Set the specified Event Flags. +/// \note API identical to osEventFlagsSet +static uint32_t svcRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) { + os_event_flags_t *ef = osRtxEventFlagsId(ef_id); + os_thread_t *thread; + os_thread_t *thread_next; + uint32_t event_flags; + uint32_t event_flags0; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || + ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) { + EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorParameter); + } + + // Set Event Flags + event_flags = EventFlagsSet(ef, flags); + + // Check if Threads are waiting for Event Flags + thread = ef->thread_list; + while (thread != NULL) { + thread_next = thread->thread_next; + event_flags0 = EventFlagsCheck(ef, thread->wait_flags, thread->flags_options); + if (event_flags0 != 0U) { + if ((thread->flags_options & osFlagsNoClear) == 0U) { + event_flags = event_flags0 & ~thread->wait_flags; + } else { + event_flags = event_flags0; + } + osRtxThreadListRemove(thread); + osRtxThreadWaitExit(thread, event_flags0, FALSE); + EvrRtxEventFlagsWaitCompleted(ef, thread->wait_flags, thread->flags_options, event_flags0); + } + thread = thread_next; + } + osRtxThreadDispatch(NULL); + + EvrRtxEventFlagsSetDone(ef, event_flags); + + return event_flags; +} + +/// Clear the specified Event Flags. +/// \note API identical to osEventFlagsClear +static uint32_t svcRtxEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) { + os_event_flags_t *ef = osRtxEventFlagsId(ef_id); + uint32_t event_flags; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || + ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) { + EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorParameter); + } + + // Clear Event Flags + event_flags = EventFlagsClear(ef, flags); + + EvrRtxEventFlagsClearDone(ef, event_flags); + + return event_flags; +} + +/// Get the current Event Flags. +/// \note API identical to osEventFlagsGet +static uint32_t svcRtxEventFlagsGet (osEventFlagsId_t ef_id) { + os_event_flags_t *ef = osRtxEventFlagsId(ef_id); + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags)) { + EvrRtxEventFlagsGet(ef, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxEventFlagsGet(ef, ef->event_flags); + + return ef->event_flags; +} + +/// Wait for one or more Event Flags to become signaled. +/// \note API identical to osEventFlagsWait +static uint32_t svcRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { + os_event_flags_t *ef = osRtxEventFlagsId(ef_id); + os_thread_t *thread; + uint32_t event_flags; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || + ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) { + EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorParameter); + } + + // Check Event Flags + event_flags = EventFlagsCheck(ef, flags, options); + if (event_flags != 0U) { + EvrRtxEventFlagsWaitCompleted(ef, flags, options, event_flags); + } else { + // Check if timeout is specified + if (timeout != 0U) { + EvrRtxEventFlagsWaitPending(ef, flags, options, timeout); + // Suspend current Thread + if (osRtxThreadWaitEnter(osRtxThreadWaitingEventFlags, timeout)) { + thread = osRtxThreadGetRunning(); + osRtxThreadListPut(osRtxObject(ef), thread); + // Store waiting flags and options + thread->wait_flags = flags; + thread->flags_options = (uint8_t)options; + } else { + EvrRtxEventFlagsWaitTimeout(ef); + } + event_flags = (uint32_t)osErrorTimeout; + } else { + EvrRtxEventFlagsWaitNotCompleted(ef, flags, options); + event_flags = (uint32_t)osErrorResource; + } + } + + return event_flags; +} + +/// Delete an Event Flags object. +/// \note API identical to osEventFlagsDelete +static osStatus_t svcRtxEventFlagsDelete (osEventFlagsId_t ef_id) { + os_event_flags_t *ef = osRtxEventFlagsId(ef_id); + os_thread_t *thread; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags)) { + EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Unblock waiting threads + if (ef->thread_list != NULL) { + do { + thread = osRtxThreadListGet(osRtxObject(ef)); + osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE); + } while (ef->thread_list != NULL); + osRtxThreadDispatch(NULL); + } + + // Mark object as invalid + ef->id = osRtxIdInvalid; + + // Free object memory + if ((ef->flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.event_flags != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.event_flags, ef); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, ef); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxEventFlagsMemUsage.cnt_free++; +#endif + } + + EvrRtxEventFlagsDestroyed(ef); + + return osOK; +} + +// Service Calls definitions +//lint ++flb "Library Begin" [MISRA Note 11] +SVC0_1(EventFlagsNew, osEventFlagsId_t, const osEventFlagsAttr_t *) +SVC0_1(EventFlagsGetName, const char *, osEventFlagsId_t) +SVC0_2(EventFlagsSet, uint32_t, osEventFlagsId_t, uint32_t) +SVC0_2(EventFlagsClear, uint32_t, osEventFlagsId_t, uint32_t) +SVC0_1(EventFlagsGet, uint32_t, osEventFlagsId_t) +SVC0_4(EventFlagsWait, uint32_t, osEventFlagsId_t, uint32_t, uint32_t, uint32_t) +SVC0_1(EventFlagsDelete, osStatus_t, osEventFlagsId_t) +//lint --flb "Library End" + + +// ==== ISR Calls ==== + +/// Set the specified Event Flags. +/// \note API identical to osEventFlagsSet +__STATIC_INLINE +uint32_t isrRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) { + os_event_flags_t *ef = osRtxEventFlagsId(ef_id); + uint32_t event_flags; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || + ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) { + EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorParameter); + } + + // Set Event Flags + event_flags = EventFlagsSet(ef, flags); + + // Register post ISR processing + osRtxPostProcess(osRtxObject(ef)); + + EvrRtxEventFlagsSetDone(ef, event_flags); + + return event_flags; +} + +/// Wait for one or more Event Flags to become signaled. +/// \note API identical to osEventFlagsWait +__STATIC_INLINE +uint32_t isrRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { + os_event_flags_t *ef = osRtxEventFlagsId(ef_id); + uint32_t event_flags; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || (timeout != 0U) || + ((flags & ~(((uint32_t)1U << osRtxEventFlagsLimit) - 1U)) != 0U)) { + EvrRtxEventFlagsError(ef, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorParameter); + } + + // Check Event Flags + event_flags = EventFlagsCheck(ef, flags, options); + if (event_flags != 0U) { + EvrRtxEventFlagsWaitCompleted(ef, flags, options, event_flags); + } else { + EvrRtxEventFlagsWaitNotCompleted(ef, flags, options); + event_flags = (uint32_t)osErrorResource; + } + + return event_flags; +} + + +// ==== Public API ==== + +/// Create and Initialize an Event Flags object. +osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) { + osEventFlagsId_t ef_id; + + EvrRtxEventFlagsNew(attr); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxEventFlagsError(NULL, (int32_t)osErrorISR); + ef_id = NULL; + } else { + ef_id = __svcEventFlagsNew(attr); + } + return ef_id; +} + +/// Get name of an Event Flags object. +const char *osEventFlagsGetName (osEventFlagsId_t ef_id) { + const char *name; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxEventFlagsGetName(ef_id, NULL); + name = NULL; + } else { + name = __svcEventFlagsGetName(ef_id); + } + return name; +} + +/// Set the specified Event Flags. +uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) { + uint32_t event_flags; + + EvrRtxEventFlagsSet(ef_id, flags); + if (IsIrqMode() || IsIrqMasked()) { + event_flags = isrRtxEventFlagsSet(ef_id, flags); + } else { + event_flags = __svcEventFlagsSet(ef_id, flags); + } + return event_flags; +} + +/// Clear the specified Event Flags. +uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) { + uint32_t event_flags; + + EvrRtxEventFlagsClear(ef_id, flags); + if (IsIrqMode() || IsIrqMasked()) { + event_flags = svcRtxEventFlagsClear(ef_id, flags); + } else { + event_flags = __svcEventFlagsClear(ef_id, flags); + } + return event_flags; +} + +/// Get the current Event Flags. +uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) { + uint32_t event_flags; + + if (IsIrqMode() || IsIrqMasked()) { + event_flags = svcRtxEventFlagsGet(ef_id); + } else { + event_flags = __svcEventFlagsGet(ef_id); + } + return event_flags; +} + +/// Wait for one or more Event Flags to become signaled. +uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { + uint32_t event_flags; + + EvrRtxEventFlagsWait(ef_id, flags, options, timeout); + if (IsIrqMode() || IsIrqMasked()) { + event_flags = isrRtxEventFlagsWait(ef_id, flags, options, timeout); + } else { + event_flags = __svcEventFlagsWait(ef_id, flags, options, timeout); + } + return event_flags; +} + +/// Delete an Event Flags object. +osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) { + osStatus_t status; + + EvrRtxEventFlagsDelete(ef_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxEventFlagsError(ef_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcEventFlagsDelete(ef_id); + } + return status; +} diff --git a/rtos/rtx5/rtx_evr.c b/rtos/rtx5/rtx_evr.c new file mode 100644 index 0000000..a313dae --- /dev/null +++ b/rtos/rtx5/rtx_evr.c @@ -0,0 +1,2116 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: RTX Event Recorder + * + * ----------------------------------------------------------------------------- + */ + +#include +#include "cmsis_compiler.h" +#include "rtx_evr.h" // RTX Event Recorder definitions +#include "rtx_lib.h" +#include "hal_trace.h" + +#ifdef RTE_Compiler_EventRecorder + +//lint -e923 -e9074 -e9078 [MISRA Note 13] + +/// Event IDs for "RTX Memory Management" +#define EvtRtxMemoryInit EventID(EventLevelOp, EvtRtxMemoryNo, 0x00U) +#define EvtRtxMemoryAlloc EventID(EventLevelOp, EvtRtxMemoryNo, 0x01U) +#define EvtRtxMemoryFree EventID(EventLevelOp, EvtRtxMemoryNo, 0x02U) +#define EvtRtxMemoryBlockInit EventID(EventLevelOp, EvtRtxMemoryNo, 0x03U) +#define EvtRtxMemoryBlockAlloc EventID(EventLevelOp, EvtRtxMemoryNo, 0x04U) +#define EvtRtxMemoryBlockFree EventID(EventLevelOp, EvtRtxMemoryNo, 0x05U) + +/// Event IDs for "RTX Kernel" +#define EvtRtxKernelError EventID(EventLevelError, EvtRtxKernelNo, 0x00U) +#define EvtRtxKernelInitialize EventID(EventLevelAPI, EvtRtxKernelNo, 0x01U) +#define EvtRtxKernelInitialized EventID(EventLevelOp, EvtRtxKernelNo, 0x02U) +#define EvtRtxKernelGetInfo EventID(EventLevelAPI, EvtRtxKernelNo, 0x03U) +#define EvtRtxKernelInfoRetrieved EventID(EventLevelOp, EvtRtxKernelNo, 0x04U) +#define EvtRtxKernelInfoRetrieved_Detail EventID(EventLevelDetail, EvtRtxKernelNo, 0x05U) +#define EvtRtxKernelGetState EventID(EventLevelAPI, EvtRtxKernelNo, 0x06U) +#define EvtRtxKernelStart EventID(EventLevelAPI, EvtRtxKernelNo, 0x07U) +#define EvtRtxKernelStarted EventID(EventLevelOp, EvtRtxKernelNo, 0x08U) +#define EvtRtxKernelLock EventID(EventLevelAPI, EvtRtxKernelNo, 0x09U) +#define EvtRtxKernelLocked EventID(EventLevelOp, EvtRtxKernelNo, 0x0AU) +#define EvtRtxKernelUnlock EventID(EventLevelAPI, EvtRtxKernelNo, 0x0BU) +#define EvtRtxKernelUnlocked EventID(EventLevelOp, EvtRtxKernelNo, 0x0CU) +#define EvtRtxKernelRestoreLock EventID(EventLevelAPI, EvtRtxKernelNo, 0x0DU) +#define EvtRtxKernelLockRestored EventID(EventLevelOp, EvtRtxKernelNo, 0x0EU) +#define EvtRtxKernelSuspend EventID(EventLevelAPI, EvtRtxKernelNo, 0x0FU) +#define EvtRtxKernelSuspended EventID(EventLevelOp, EvtRtxKernelNo, 0x10U) +#define EvtRtxKernelResume EventID(EventLevelAPI, EvtRtxKernelNo, 0x11U) +#define EvtRtxKernelResumed EventID(EventLevelOp, EvtRtxKernelNo, 0x12U) +#define EvtRtxKernelGetTickCount EventID(EventLevelAPI, EvtRtxKernelNo, 0x13U) +#define EvtRtxKernelGetTickFreq EventID(EventLevelAPI, EvtRtxKernelNo, 0x14U) +#define EvtRtxKernelGetSysTimerCount EventID(EventLevelAPI, EvtRtxKernelNo, 0x15U) +#define EvtRtxKernelGetSysTimerFreq EventID(EventLevelAPI, EvtRtxKernelNo, 0x16U) + +/// Event IDs for "RTX Thread" +#define EvtRtxThreadError EventID(EventLevelError, EvtRtxThreadNo, 0x00U) +#define EvtRtxThreadNew EventID(EventLevelAPI, EvtRtxThreadNo, 0x01U) +#define EvtRtxThreadCreated_Addr EventID(EventLevelOp, EvtRtxThreadNo, 0x03U) +#define EvtRtxThreadCreated_Name EventID(EventLevelOp, EvtRtxThreadNo, 0x2CU) +#define EvtRtxThreadGetName EventID(EventLevelAPI, EvtRtxThreadNo, 0x04U) +#define EvtRtxThreadGetId EventID(EventLevelAPI, EvtRtxThreadNo, 0x06U) +#define EvtRtxThreadGetState EventID(EventLevelAPI, EvtRtxThreadNo, 0x07U) +#define EvtRtxThreadGetStackSize EventID(EventLevelAPI, EvtRtxThreadNo, 0x08U) +#define EvtRtxThreadGetStackSpace EventID(EventLevelAPI, EvtRtxThreadNo, 0x09U) +#define EvtRtxThreadSetPriority EventID(EventLevelAPI, EvtRtxThreadNo, 0x0AU) +#define EvtRtxThreadPriorityUpdated EventID(EventLevelOp, EvtRtxThreadNo, 0x2DU) +#define EvtRtxThreadGetPriority EventID(EventLevelAPI, EvtRtxThreadNo, 0x0BU) +#define EvtRtxThreadYield EventID(EventLevelAPI, EvtRtxThreadNo, 0x0CU) +#define EvtRtxThreadSuspend EventID(EventLevelAPI, EvtRtxThreadNo, 0x0DU) +#define EvtRtxThreadSuspended EventID(EventLevelOp, EvtRtxThreadNo, 0x0EU) +#define EvtRtxThreadResume EventID(EventLevelAPI, EvtRtxThreadNo, 0x0FU) +#define EvtRtxThreadResumed EventID(EventLevelOp, EvtRtxThreadNo, 0x10U) +#define EvtRtxThreadDetach EventID(EventLevelAPI, EvtRtxThreadNo, 0x11U) +#define EvtRtxThreadDetached EventID(EventLevelOp, EvtRtxThreadNo, 0x12U) +#define EvtRtxThreadJoin EventID(EventLevelAPI, EvtRtxThreadNo, 0x13U) +#define EvtRtxThreadJoinPending EventID(EventLevelOp, EvtRtxThreadNo, 0x14U) +#define EvtRtxThreadJoined EventID(EventLevelOp, EvtRtxThreadNo, 0x15U) +#define EvtRtxThreadBlocked EventID(EventLevelDetail, EvtRtxThreadNo, 0x16U) +#define EvtRtxThreadUnblocked EventID(EventLevelDetail, EvtRtxThreadNo, 0x17U) +#define EvtRtxThreadPreempted EventID(EventLevelDetail, EvtRtxThreadNo, 0x18U) +#define EvtRtxThreadSwitched EventID(EventLevelOp, EvtRtxThreadNo, 0x19U) +#define EvtRtxThreadExit EventID(EventLevelAPI, EvtRtxThreadNo, 0x1AU) +#define EvtRtxThreadTerminate EventID(EventLevelAPI, EvtRtxThreadNo, 0x1BU) +#define EvtRtxThreadDestroyed EventID(EventLevelOp, EvtRtxThreadNo, 0x1CU) +#define EvtRtxThreadGetCount EventID(EventLevelAPI, EvtRtxThreadNo, 0x1DU) +#define EvtRtxThreadEnumerate EventID(EventLevelAPI, EvtRtxThreadNo, 0x1EU) + +/// Event IDs for "RTX Thread Flags" +#define EvtRtxThreadFlagsError EventID(EventLevelError, EvtRtxThreadFlagsNo, 0x00U) +#define EvtRtxThreadFlagsSet EventID(EventLevelAPI, EvtRtxThreadFlagsNo, 0x01U) +#define EvtRtxThreadFlagsSetDone EventID(EventLevelOp, EvtRtxThreadFlagsNo, 0x02U) +#define EvtRtxThreadFlagsClear EventID(EventLevelAPI, EvtRtxThreadFlagsNo, 0x03U) +#define EvtRtxThreadFlagsClearDone EventID(EventLevelOp, EvtRtxThreadFlagsNo, 0x04U) +#define EvtRtxThreadFlagsGet EventID(EventLevelAPI, EvtRtxThreadFlagsNo, 0x05U) +#define EvtRtxThreadFlagsWait EventID(EventLevelAPI, EvtRtxThreadFlagsNo, 0x06U) +#define EvtRtxThreadFlagsWaitPending EventID(EventLevelOp, EvtRtxThreadFlagsNo, 0x07U) +#define EvtRtxThreadFlagsWaitTimeout EventID(EventLevelOp, EvtRtxThreadFlagsNo, 0x08U) +#define EvtRtxThreadFlagsWaitCompleted EventID(EventLevelOp, EvtRtxThreadFlagsNo, 0x09U) +#define EvtRtxThreadFlagsWaitNotCompleted EventID(EventLevelOp, EvtRtxThreadFlagsNo, 0x0AU) + +/// Event IDs for "RTX Generic Wait" +#define EvtRtxDelayError EventID(EventLevelError, EvtRtxWaitNo, 0x00U) +#define EvtRtxDelay EventID(EventLevelAPI, EvtRtxWaitNo, 0x01U) +#define EvtRtxDelayUntil EventID(EventLevelAPI, EvtRtxWaitNo, 0x02U) +#define EvtRtxDelayStarted EventID(EventLevelOp, EvtRtxWaitNo, 0x03U) +#define EvtRtxDelayUntilStarted EventID(EventLevelOp, EvtRtxWaitNo, 0x04U) +#define EvtRtxDelayCompleted EventID(EventLevelOp, EvtRtxWaitNo, 0x05U) + +/// Event IDs for "RTX Timer" +#define EvtRtxTimerError EventID(EventLevelError, EvtRtxTimerNo, 0x00U) +#define EvtRtxTimerCallback EventID(EventLevelOp, EvtRtxTimerNo, 0x01U) +#define EvtRtxTimerNew EventID(EventLevelAPI, EvtRtxTimerNo, 0x02U) +#define EvtRtxTimerCreated EventID(EventLevelOp, EvtRtxTimerNo, 0x04U) +#define EvtRtxTimerGetName EventID(EventLevelAPI, EvtRtxTimerNo, 0x05U) +#define EvtRtxTimerStart EventID(EventLevelAPI, EvtRtxTimerNo, 0x07U) +#define EvtRtxTimerStarted EventID(EventLevelOp, EvtRtxTimerNo, 0x08U) +#define EvtRtxTimerStop EventID(EventLevelAPI, EvtRtxTimerNo, 0x09U) +#define EvtRtxTimerStopped EventID(EventLevelOp, EvtRtxTimerNo, 0x0AU) +#define EvtRtxTimerIsRunning EventID(EventLevelAPI, EvtRtxTimerNo, 0x0BU) +#define EvtRtxTimerDelete EventID(EventLevelAPI, EvtRtxTimerNo, 0x0CU) +#define EvtRtxTimerDestroyed EventID(EventLevelOp, EvtRtxTimerNo, 0x0DU) + +/// Event IDs for "RTX Event Flags" +#define EvtRtxEventFlagsError EventID(EventLevelError, EvtRtxEventFlagsNo, 0x00U) +#define EvtRtxEventFlagsNew EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x01U) +#define EvtRtxEventFlagsCreated EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x03U) +#define EvtRtxEventFlagsGetName EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x04U) +#define EvtRtxEventFlagsSet EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x06U) +#define EvtRtxEventFlagsSetDone EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x07U) +#define EvtRtxEventFlagsClear EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x08U) +#define EvtRtxEventFlagsClearDone EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x09U) +#define EvtRtxEventFlagsGet EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x0AU) +#define EvtRtxEventFlagsWait EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x0BU) +#define EvtRtxEventFlagsWaitPending EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x0CU) +#define EvtRtxEventFlagsWaitTimeout EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x0DU) +#define EvtRtxEventFlagsWaitCompleted EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x0EU) +#define EvtRtxEventFlagsWaitNotCompleted EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x0FU) +#define EvtRtxEventFlagsDelete EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x10U) +#define EvtRtxEventFlagsDestroyed EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x11U) + +/// Event IDs for "RTX Mutex" +#define EvtRtxMutexError EventID(EventLevelError, EvtRtxMutexNo, 0x00U) +#define EvtRtxMutexNew EventID(EventLevelAPI, EvtRtxMutexNo, 0x01U) +#define EvtRtxMutexCreated EventID(EventLevelOp, EvtRtxMutexNo, 0x03U) +#define EvtRtxMutexGetName EventID(EventLevelAPI, EvtRtxMutexNo, 0x04U) +#define EvtRtxMutexAcquire EventID(EventLevelAPI, EvtRtxMutexNo, 0x06U) +#define EvtRtxMutexAcquirePending EventID(EventLevelOp, EvtRtxMutexNo, 0x07U) +#define EvtRtxMutexAcquireTimeout EventID(EventLevelOp, EvtRtxMutexNo, 0x08U) +#define EvtRtxMutexAcquired EventID(EventLevelOp, EvtRtxMutexNo, 0x09U) +#define EvtRtxMutexNotAcquired EventID(EventLevelOp, EvtRtxMutexNo, 0x0AU) +#define EvtRtxMutexRelease EventID(EventLevelAPI, EvtRtxMutexNo, 0x0BU) +#define EvtRtxMutexReleased EventID(EventLevelOp, EvtRtxMutexNo, 0x0CU) +#define EvtRtxMutexGetOwner EventID(EventLevelAPI, EvtRtxMutexNo, 0x0DU) +#define EvtRtxMutexDelete EventID(EventLevelAPI, EvtRtxMutexNo, 0x0EU) +#define EvtRtxMutexDestroyed EventID(EventLevelOp, EvtRtxMutexNo, 0x0FU) + +/// Event IDs for "RTX Semaphore" +#define EvtRtxSemaphoreError EventID(EventLevelError, EvtRtxSemaphoreNo, 0x00U) +#define EvtRtxSemaphoreNew EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x01U) +#define EvtRtxSemaphoreCreated EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x03U) +#define EvtRtxSemaphoreGetName EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x04U) +#define EvtRtxSemaphoreAcquire EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x06U) +#define EvtRtxSemaphoreAcquirePending EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x07U) +#define EvtRtxSemaphoreAcquireTimeout EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x08U) +#define EvtRtxSemaphoreAcquired EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x09U) +#define EvtRtxSemaphoreNotAcquired EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x0AU) +#define EvtRtxSemaphoreRelease EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x0BU) +#define EvtRtxSemaphoreReleased EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x0CU) +#define EvtRtxSemaphoreGetCount EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x0DU) +#define EvtRtxSemaphoreDelete EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x0EU) +#define EvtRtxSemaphoreDestroyed EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x0FU) + +/// Event IDs for "RTX Memory Pool" +#define EvtRtxMemoryPoolError EventID(EventLevelError, EvtRtxMemoryPoolNo, 0x00U) +#define EvtRtxMemoryPoolNew EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x01U) +#define EvtRtxMemoryPoolCreated EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x03U) +#define EvtRtxMemoryPoolGetName EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x04U) +#define EvtRtxMemoryPoolAlloc EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x06U) +#define EvtRtxMemoryPoolAllocPending EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x07U) +#define EvtRtxMemoryPoolAllocTimeout EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x08U) +#define EvtRtxMemoryPoolAllocated EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x09U) +#define EvtRtxMemoryPoolAllocFailed EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x0AU) +#define EvtRtxMemoryPoolFree EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x0BU) +#define EvtRtxMemoryPoolDeallocated EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x0CU) +#define EvtRtxMemoryPoolFreeFailed EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x0DU) +#define EvtRtxMemoryPoolGetCapacity EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x0EU) +#define EvtRtxMemoryPoolGetBlockSize EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x0FU) +#define EvtRtxMemoryPoolGetCount EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x10U) +#define EvtRtxMemoryPoolGetSpace EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x11U) +#define EvtRtxMemoryPoolDelete EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x12U) +#define EvtRtxMemoryPoolDestroyed EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x13U) + +/// Event IDs for "RTX Message Queue" +#define EvtRtxMessageQueueError EventID(EventLevelError, EvtRtxMessageQueueNo, 0x00U) +#define EvtRtxMessageQueueNew EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x01U) +#define EvtRtxMessageQueueCreated EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x03U) +#define EvtRtxMessageQueueGetName EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x04U) +#define EvtRtxMessageQueuePut EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x06U) +#define EvtRtxMessageQueuePutPending EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x07U) +#define EvtRtxMessageQueuePutTimeout EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x08U) +#define EvtRtxMessageQueueInsertPending EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x09U) +#define EvtRtxMessageQueueInserted EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x0AU) +#define EvtRtxMessageQueueNotInserted EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x0BU) +#define EvtRtxMessageQueueGet EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x0CU) +#define EvtRtxMessageQueueGetPending EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x0DU) +#define EvtRtxMessageQueueGetTimeout EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x0EU) +#define EvtRtxMessageQueueRetrieved EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x0FU) +#define EvtRtxMessageQueueNotRetrieved EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x10U) +#define EvtRtxMessageQueueGetCapacity EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x11U) +#define EvtRtxMessageQueueGetMsgSize EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x12U) +#define EvtRtxMessageQueueGetCount EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x13U) +#define EvtRtxMessageQueueGetSpace EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x14U) +#define EvtRtxMessageQueueReset EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x15U) +#define EvtRtxMessageQueueResetDone EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x16U) +#define EvtRtxMessageQueueDelete EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x17U) +#define EvtRtxMessageQueueDestroyed EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x18U) + +#endif // RTE_Compiler_EventRecorder + +//lint -esym(522, EvrRtx*) "Functions 'EvrRtx*' can be overridden (do not lack side-effects)" + + +// ==== Memory Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_INIT_DISABLE)) +__WEAK void EvrRtxMemoryInit (void *mem, uint32_t size, uint32_t result) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMemoryInit, (uint32_t)mem, size, result, 0U); +#else + (void)mem; + (void)size; + (void)result; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_ALLOC_DISABLE)) +__WEAK void EvrRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type, void *block) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMemoryAlloc, (uint32_t)mem, size, type, (uint32_t)block); +#else + (void)mem; + (void)size; + (void)type; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_FREE_DISABLE)) +__WEAK void EvrRtxMemoryFree (void *mem, void *block, uint32_t result) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMemoryFree, (uint32_t)mem, (uint32_t)block, result, 0U); +#else + (void)mem; + (void)block; + (void)result; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_INIT_DISABLE)) +__WEAK void EvrRtxMemoryBlockInit (osRtxMpInfo_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMemoryBlockInit, (uint32_t)mp_info, block_count, block_size, (uint32_t)block_mem); +#else + (void)mp_info; + (void)block_count; + (void)block_size; + (void)block_mem; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_ALLOC_DISABLE)) +__WEAK void EvrRtxMemoryBlockAlloc (osRtxMpInfo_t *mp_info, void *block) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryBlockAlloc, (uint32_t)mp_info, (uint32_t)block); +#else + (void)mp_info; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_FREE_DISABLE)) +__WEAK void EvrRtxMemoryBlockFree (osRtxMpInfo_t *mp_info, void *block, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMemoryBlockFree, (uint32_t)mp_info, (uint32_t)block, (uint32_t)status, 0U); +#else + (void)mp_info; + (void)block; + (void)status; +#endif +} +#endif + + +// ==== Kernel Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_ERROR_DISABLE)) +__WEAK void EvrRtxKernelError (int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelError, (uint32_t)status, 0U); +#else + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INITIALIZE_DISABLE)) +__WEAK void EvrRtxKernelInitialize (void) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelInitialize, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INITIALIZED_DISABLE)) +__WEAK void EvrRtxKernelInitialized (void) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelInitialized, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_INFO_DISABLE)) +__WEAK void EvrRtxKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxKernelGetInfo, (uint32_t)version, (uint32_t)id_buf, id_size, 0U); +#else + (void)version; + (void)id_buf; + (void)id_size; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INFO_RETRIEVED_DISABLE)) +__WEAK void EvrRtxKernelInfoRetrieved (const osVersion_t *version, const char *id_buf, uint32_t id_size) { +#if defined(RTE_Compiler_EventRecorder) + if (version != NULL) { + (void)EventRecord2(EvtRtxKernelInfoRetrieved, version->api, version->kernel); + } + if (id_buf != NULL) { + (void)EventRecordData(EvtRtxKernelInfoRetrieved_Detail, id_buf, id_size); + } +#else + (void)version; + (void)id_buf; + (void)id_size; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_STATE_DISABLE)) +__WEAK void EvrRtxKernelGetState (osKernelState_t state) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelGetState, (uint32_t)state, 0U); +#else + (void)state; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_START_DISABLE)) +__WEAK void EvrRtxKernelStart (void) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelStart, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_STARTED_DISABLE)) +__WEAK void EvrRtxKernelStarted (void) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelStarted, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCK_DISABLE)) +__WEAK void EvrRtxKernelLock (void) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelLock, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCKED_DISABLE)) +__WEAK void EvrRtxKernelLocked (int32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelLocked, (uint32_t)lock, 0U); +#else + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_UNLOCK_DISABLE)) +__WEAK void EvrRtxKernelUnlock (void) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelUnlock, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_UNLOCKED_DISABLE)) +__WEAK void EvrRtxKernelUnlocked (int32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelUnlocked, (uint32_t)lock, 0U); +#else + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESTORE_LOCK_DISABLE)) +__WEAK void EvrRtxKernelRestoreLock (int32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelRestoreLock, (uint32_t)lock, 0U); +#else + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCK_RESTORED_DISABLE)) +__WEAK void EvrRtxKernelLockRestored (int32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelLockRestored, (uint32_t)lock, 0U); +#else + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_SUSPEND_DISABLE)) +__WEAK void EvrRtxKernelSuspend (void) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelSuspend, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_SUSPENDED_DISABLE)) +__WEAK void EvrRtxKernelSuspended (uint32_t sleep_ticks) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelSuspended, sleep_ticks, 0U); +#else + (void)sleep_ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESUME_DISABLE)) +__WEAK void EvrRtxKernelResume (uint32_t sleep_ticks) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelResume, sleep_ticks, 0U); +#else + (void)sleep_ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESUMED_DISABLE)) +__WEAK void EvrRtxKernelResumed (void) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelResumed, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE)) +__WEAK void EvrRtxKernelGetTickCount (uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelGetTickCount, count, 0U); +#else + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_FREQ_DISABLE)) +__WEAK void EvrRtxKernelGetTickFreq (uint32_t freq) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelGetTickFreq, freq, 0U); +#else + (void)freq; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_SYS_TIMER_COUNT_DISABLE)) +__WEAK void EvrRtxKernelGetSysTimerCount (uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelGetSysTimerCount, count, 0U); +#else + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_SYS_TIMER_FREQ_DISABLE)) +__WEAK void EvrRtxKernelGetSysTimerFreq (uint32_t freq) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxKernelGetSysTimerFreq, freq, 0U); +#else + (void)freq; +#endif +} +#endif + + +// ==== Thread Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_ERROR_DISABLE)) +__WEAK void EvrRtxThreadError (osThreadId_t thread_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadError, (uint32_t)thread_id, (uint32_t)status); +#else + os_thread_t *thread = osRtxThreadId(thread_id); + TRACE(2,"EvrRtxThreadError, thread name:%s, status:%d", thread ? thread->name : "NULL", status); +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_NEW_DISABLE)) +__WEAK void EvrRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxThreadNew, (uint32_t)func, (uint32_t)argument, (uint32_t)attr, 0U); +#else + (void)func; + (void)argument; + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_CREATED_DISABLE)) +__WEAK void EvrRtxThreadCreated (osThreadId_t thread_id, uint32_t thread_addr, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + if (name != NULL) { + (void)EventRecord2(EvtRtxThreadCreated_Name, (uint32_t)thread_id, (uint32_t)name); + } else { + (void)EventRecord2(EvtRtxThreadCreated_Addr, (uint32_t)thread_id, thread_addr); + } +#else + (void)thread_id; + (void)thread_addr; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_NAME_DISABLE)) +__WEAK void EvrRtxThreadGetName (osThreadId_t thread_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadGetName, (uint32_t)thread_id, (uint32_t)name); +#else + (void)thread_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_ID_DISABLE)) +__WEAK void EvrRtxThreadGetId (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadGetId, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STATE_DISABLE)) +__WEAK void EvrRtxThreadGetState (osThreadId_t thread_id, osThreadState_t state) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadGetState, (uint32_t)thread_id, (uint32_t)state); +#else + (void)thread_id; + (void)state; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STACK_SIZE_DISABLE)) +__WEAK void EvrRtxThreadGetStackSize (osThreadId_t thread_id, uint32_t stack_size) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadGetStackSize, (uint32_t)thread_id, stack_size); +#else + (void)thread_id; + (void)stack_size; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STACK_SPACE_DISABLE)) +__WEAK void EvrRtxThreadGetStackSpace (osThreadId_t thread_id, uint32_t stack_space) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadGetStackSpace, (uint32_t)thread_id, stack_space); +#else + (void)thread_id; + (void)stack_space; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SET_PRIORITY_DISABLE)) +__WEAK void EvrRtxThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadSetPriority, (uint32_t)thread_id, (uint32_t)priority); +#else + (void)thread_id; + (void)priority; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_PRIORITY_UPDATED_DISABLE)) +__WEAK void EvrRtxThreadPriorityUpdated (osThreadId_t thread_id, osPriority_t priority) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadPriorityUpdated, (uint32_t)thread_id, (uint32_t)priority); +#else + (void)thread_id; + (void)priority; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_PRIORITY_DISABLE)) +__WEAK void EvrRtxThreadGetPriority (osThreadId_t thread_id, osPriority_t priority) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadGetPriority, (uint32_t)thread_id, (uint32_t)priority); +#else + (void)thread_id; + (void)priority; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_YIELD_DISABLE)) +__WEAK void EvrRtxThreadYield (void) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadYield, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SUSPEND_DISABLE)) +__WEAK void EvrRtxThreadSuspend (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadSuspend, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SUSPENDED_DISABLE)) +__WEAK void EvrRtxThreadSuspended (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadSuspended, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_RESUME_DISABLE)) +__WEAK void EvrRtxThreadResume (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadResume, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_RESUMED_DISABLE)) +__WEAK void EvrRtxThreadResumed (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadResumed, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DETACH_DISABLE)) +__WEAK void EvrRtxThreadDetach (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadDetach, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DETACHED_DISABLE)) +__WEAK void EvrRtxThreadDetached (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadDetached, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOIN_DISABLE)) +__WEAK void EvrRtxThreadJoin (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadJoin, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOIN_PENDING_DISABLE)) +__WEAK void EvrRtxThreadJoinPending (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadJoinPending, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOINED_DISABLE)) +__WEAK void EvrRtxThreadJoined (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadJoined, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_BLOCKED_DISABLE)) +__WEAK void EvrRtxThreadBlocked (osThreadId_t thread_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadBlocked, (uint32_t)thread_id, timeout); +#else + (void)thread_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_UNBLOCKED_DISABLE)) +__WEAK void EvrRtxThreadUnblocked (osThreadId_t thread_id, uint32_t ret_val) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadUnblocked, (uint32_t)thread_id, ret_val); +#else + (void)thread_id; + (void)ret_val; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_PREEMPTED_DISABLE)) +__WEAK void EvrRtxThreadPreempted (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadPreempted, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SWITCHED_DISABLE)) +__WEAK void EvrRtxThreadSwitched (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadSwitched, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_EXIT_DISABLE)) +__WEAK void EvrRtxThreadExit (void) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadExit, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_TERMINATE_DISABLE)) +__WEAK void EvrRtxThreadTerminate (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadTerminate, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DESTROYED_DISABLE)) +__WEAK void EvrRtxThreadDestroyed (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadDestroyed, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_COUNT_DISABLE)) +__WEAK void EvrRtxThreadGetCount (uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadGetCount, count, 0U); +#else + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_ENUMERATE_DISABLE)) +__WEAK void EvrRtxThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items, uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxThreadEnumerate, (uint32_t)thread_array, array_items, count, 0U); +#else + (void)thread_array; + (void)array_items; + (void)count; +#endif +} +#endif + + +// ==== Thread Flags Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_ERROR_DISABLE)) +__WEAK void EvrRtxThreadFlagsError (osThreadId_t thread_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadFlagsError, (uint32_t)thread_id, (uint32_t)status); +#else + (void)thread_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_SET_DISABLE)) +__WEAK void EvrRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadFlagsSet, (uint32_t)thread_id, flags); +#else + (void)thread_id; + (void)flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_SET_DONE_DISABLE)) +__WEAK void EvrRtxThreadFlagsSetDone (osThreadId_t thread_id, uint32_t thread_flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadFlagsSetDone, (uint32_t)thread_id, thread_flags); +#else + (void)thread_id; + (void)thread_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_CLEAR_DISABLE)) +__WEAK void EvrRtxThreadFlagsClear (uint32_t flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadFlagsClear, flags, 0U); +#else + (void)flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_CLEAR_DONE_DISABLE)) +__WEAK void EvrRtxThreadFlagsClearDone (uint32_t thread_flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadFlagsClearDone, thread_flags, 0U); +#else + (void)thread_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_GET_DISABLE)) +__WEAK void EvrRtxThreadFlagsGet (uint32_t thread_flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadFlagsGet, thread_flags, 0U); +#else + (void)thread_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_DISABLE)) +__WEAK void EvrRtxThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxThreadFlagsWait, flags, options, timeout, 0U); +#else + (void)flags; + (void)options; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_PENDING_DISABLE)) +__WEAK void EvrRtxThreadFlagsWaitPending (uint32_t flags, uint32_t options, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxThreadFlagsWaitPending, flags, options, timeout, 0U); +#else + (void)flags; + (void)options; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_TIMEOUT_DISABLE)) +__WEAK void EvrRtxThreadFlagsWaitTimeout (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadFlagsWaitTimeout, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_COMPLETED_DISABLE)) +__WEAK void EvrRtxThreadFlagsWaitCompleted (uint32_t flags, uint32_t options, uint32_t thread_flags, osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxThreadFlagsWaitCompleted, flags, options, thread_flags, (uint32_t)thread_id); +#else + (void)flags; + (void)options; + (void)thread_flags; + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THFLAGS != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_NOT_COMPLETED_DISABLE)) +__WEAK void EvrRtxThreadFlagsWaitNotCompleted (uint32_t flags, uint32_t options) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxThreadFlagsWaitNotCompleted, flags, options); +#else + (void)flags; + (void)options; +#endif +} +#endif + + +// ==== Generic Wait Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_ERROR_DISABLE)) +__WEAK void EvrRtxDelayError (int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxDelayError, (uint32_t)status, 0U); +#else + (void)status; +#endif +} +#endif + + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_DISABLE)) +__WEAK void EvrRtxDelay (uint32_t ticks) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxDelay, ticks, 0U); +#else + (void)ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_UNTIL_DISABLE)) +__WEAK void EvrRtxDelayUntil (uint32_t ticks) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxDelayUntil, ticks, 0U); +#else + (void)ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_STARTED_DISABLE)) +__WEAK void EvrRtxDelayStarted (uint32_t ticks) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxDelayStarted, ticks, 0U); +#else + (void)ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_UNTIL_STARTED_DISABLE)) +__WEAK void EvrRtxDelayUntilStarted (uint32_t ticks) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxDelayUntilStarted, ticks, 0U); +#else + (void)ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_WAIT != 0) && !defined(EVR_RTX_DELAY_COMPLETED_DISABLE)) +__WEAK void EvrRtxDelayCompleted (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxDelayCompleted, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + + +// ==== Timer Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_ERROR_DISABLE)) +__WEAK void EvrRtxTimerError (osTimerId_t timer_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerError, (uint32_t)timer_id, (uint32_t)status); +#else + (void)timer_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_CALLBACK_DISABLE)) +__WEAK void EvrRtxTimerCallback (osTimerFunc_t func, void *argument) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerCallback, (uint32_t)func, (uint32_t)argument); +#else + (void)func; + (void)argument; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_NEW_DISABLE)) +__WEAK void EvrRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxTimerNew, (uint32_t)func, (uint32_t)type, (uint32_t)argument, (uint32_t)attr); +#else + (void)func; + (void)type; + (void)argument; + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_CREATED_DISABLE)) +__WEAK void EvrRtxTimerCreated (osTimerId_t timer_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerCreated, (uint32_t)timer_id, (uint32_t)name); +#else + (void)timer_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_GET_NAME_DISABLE)) +__WEAK void EvrRtxTimerGetName (osTimerId_t timer_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerGetName, (uint32_t)timer_id, (uint32_t)name); +#else + (void)timer_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_START_DISABLE)) +__WEAK void EvrRtxTimerStart (osTimerId_t timer_id, uint32_t ticks) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerStart, (uint32_t)timer_id, ticks); +#else + (void)timer_id; + (void)ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STARTED_DISABLE)) +__WEAK void EvrRtxTimerStarted (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerStarted, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STOP_DISABLE)) +__WEAK void EvrRtxTimerStop (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerStop, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STOPPED_DISABLE)) +__WEAK void EvrRtxTimerStopped (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerStopped, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_IS_RUNNING_DISABLE)) +__WEAK void EvrRtxTimerIsRunning (osTimerId_t timer_id, uint32_t running) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerIsRunning, (uint32_t)timer_id, running); +#else + (void)timer_id; + (void)running; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_DELETE_DISABLE)) +__WEAK void EvrRtxTimerDelete (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerDelete, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_DESTROYED_DISABLE)) +__WEAK void EvrRtxTimerDestroyed (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxTimerDestroyed, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + + +// ==== Event Flags Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_ERROR_DISABLE)) +__WEAK void EvrRtxEventFlagsError (osEventFlagsId_t ef_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsError, (uint32_t)ef_id, (uint32_t)status); +#else + (void)ef_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_NEW_DISABLE)) +__WEAK void EvrRtxEventFlagsNew (const osEventFlagsAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsNew, (uint32_t)attr, 0U); +#else + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CREATED_DISABLE)) +__WEAK void EvrRtxEventFlagsCreated (osEventFlagsId_t ef_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsCreated, (uint32_t)ef_id, (uint32_t)name); +#else + (void)ef_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_GET_NAME_DISABLE)) +__WEAK void EvrRtxEventFlagsGetName (osEventFlagsId_t ef_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsGetName, (uint32_t)ef_id, (uint32_t)name); +#else + (void)ef_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_SET_DISABLE)) +__WEAK void EvrRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsSet, (uint32_t)ef_id, flags); +#else + (void)ef_id; + (void)flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_SET_DONE_DISABLE)) +__WEAK void EvrRtxEventFlagsSetDone (osEventFlagsId_t ef_id, uint32_t event_flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsSetDone, (uint32_t)ef_id, event_flags); +#else + (void)ef_id; + (void)event_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CLEAR_DISABLE)) +__WEAK void EvrRtxEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsClear, (uint32_t)ef_id, flags); +#else + (void)ef_id; + (void)flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CLEAR_DONE_DISABLE)) +__WEAK void EvrRtxEventFlagsClearDone (osEventFlagsId_t ef_id, uint32_t event_flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsClearDone, (uint32_t)ef_id, event_flags); +#else + (void)ef_id; + (void)event_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_GET_DISABLE)) +__WEAK void EvrRtxEventFlagsGet (osEventFlagsId_t ef_id, uint32_t event_flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsGet, (uint32_t)ef_id, event_flags); +#else + (void)ef_id; + (void)event_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_DISABLE)) +__WEAK void EvrRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxEventFlagsWait, (uint32_t)ef_id, flags, options, timeout); +#else + (void)ef_id; + (void)flags; + (void)options; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_PENDING_DISABLE)) +__WEAK void EvrRtxEventFlagsWaitPending (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxEventFlagsWaitPending, (uint32_t)ef_id, flags, options, timeout); +#else + (void)ef_id; + (void)flags; + (void)options; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_TIMEOUT_DISABLE)) +__WEAK void EvrRtxEventFlagsWaitTimeout (osEventFlagsId_t ef_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsWaitTimeout, (uint32_t)ef_id, 0U); +#else + (void)ef_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_COMPLETED_DISABLE)) +__WEAK void EvrRtxEventFlagsWaitCompleted (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t event_flags) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxEventFlagsWaitCompleted, (uint32_t)ef_id, flags, options, event_flags); +#else + (void)ef_id; + (void)flags; + (void)options; + (void)event_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_NOT_COMPLETED_DISABLE)) +__WEAK void EvrRtxEventFlagsWaitNotCompleted (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxEventFlagsWaitNotCompleted, (uint32_t)ef_id, flags, options, 0U); +#else + (void)ef_id; + (void)flags; + (void)options; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_DELETE_DISABLE)) +__WEAK void EvrRtxEventFlagsDelete (osEventFlagsId_t ef_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsDelete, (uint32_t)ef_id, 0U); +#else + (void)ef_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_DESTROYED_DISABLE)) +__WEAK void EvrRtxEventFlagsDestroyed (osEventFlagsId_t ef_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxEventFlagsDestroyed, (uint32_t)ef_id, 0U); +#else + (void)ef_id; +#endif +} +#endif + + +// ==== Mutex Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ERROR_DISABLE)) +__WEAK void EvrRtxMutexError (osMutexId_t mutex_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexError, (uint32_t)mutex_id, (uint32_t)status); +#else + (void)mutex_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_NEW_DISABLE)) +__WEAK void EvrRtxMutexNew (const osMutexAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexNew, (uint32_t)attr, 0U); +#else + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_CREATED_DISABLE)) +__WEAK void EvrRtxMutexCreated (osMutexId_t mutex_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexCreated, (uint32_t)mutex_id, (uint32_t)name); +#else + (void)mutex_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_GET_NAME_DISABLE)) +__WEAK void EvrRtxMutexGetName (osMutexId_t mutex_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexGetName, (uint32_t)mutex_id, (uint32_t)name); +#else + (void)mutex_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_DISABLE)) +__WEAK void EvrRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexAcquire, (uint32_t)mutex_id, timeout); +#else + (void)mutex_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_PENDING_DISABLE)) +__WEAK void EvrRtxMutexAcquirePending (osMutexId_t mutex_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexAcquirePending, (uint32_t)mutex_id, timeout); +#else + (void)mutex_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_TIMEOUT_DISABLE)) +__WEAK void EvrRtxMutexAcquireTimeout (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexAcquireTimeout, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRED_DISABLE)) +__WEAK void EvrRtxMutexAcquired (osMutexId_t mutex_id, uint32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexAcquired, (uint32_t)mutex_id, lock); +#else + (void)mutex_id; + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_NOT_ACQUIRED_DISABLE)) +__WEAK void EvrRtxMutexNotAcquired (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexNotAcquired, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_RELEASE_DISABLE)) +__WEAK void EvrRtxMutexRelease (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexRelease, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_RELEASED_DISABLE)) +__WEAK void EvrRtxMutexReleased (osMutexId_t mutex_id, uint32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexReleased, (uint32_t)mutex_id, lock); +#else + (void)mutex_id; + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_GET_OWNER_DISABLE)) +__WEAK void EvrRtxMutexGetOwner (osMutexId_t mutex_id, osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexGetOwner, (uint32_t)mutex_id, (uint32_t)thread_id); +#else + (void)mutex_id; + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_DELETE_DISABLE)) +__WEAK void EvrRtxMutexDelete (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexDelete, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_DESTROYED_DISABLE)) +__WEAK void EvrRtxMutexDestroyed (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMutexDestroyed, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + + +// ==== Semaphore Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ERROR_DISABLE)) +__WEAK void EvrRtxSemaphoreError (osSemaphoreId_t semaphore_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreError, (uint32_t)semaphore_id, (uint32_t)status); +#else + (void)semaphore_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_NEW_DISABLE)) +__WEAK void EvrRtxSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxSemaphoreNew, max_count, initial_count, (uint32_t)attr, 0U); +#else + (void)max_count; + (void)initial_count; + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_CREATED_DISABLE)) +__WEAK void EvrRtxSemaphoreCreated (osSemaphoreId_t semaphore_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreCreated, (uint32_t)semaphore_id, (uint32_t)name); +#else + (void)semaphore_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_GET_NAME_DISABLE)) +__WEAK void EvrRtxSemaphoreGetName (osSemaphoreId_t semaphore_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreGetName, (uint32_t)semaphore_id, (uint32_t)name); +#else +#endif + (void)semaphore_id; + (void)name; +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_DISABLE)) +__WEAK void EvrRtxSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreAcquire, (uint32_t)semaphore_id, timeout); +#else + (void)semaphore_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_PENDING_DISABLE)) +__WEAK void EvrRtxSemaphoreAcquirePending (osSemaphoreId_t semaphore_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreAcquirePending, (uint32_t)semaphore_id, (uint32_t)timeout); +#else + (void)semaphore_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_TIMEOUT_DISABLE)) +__WEAK void EvrRtxSemaphoreAcquireTimeout (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreAcquireTimeout, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRED_DISABLE)) +__WEAK void EvrRtxSemaphoreAcquired (osSemaphoreId_t semaphore_id, uint32_t tokens) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreAcquired, (uint32_t)semaphore_id, tokens); +#else + (void)semaphore_id; + (void)tokens; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_NOT_ACQUIRED_DISABLE)) +__WEAK void EvrRtxSemaphoreNotAcquired (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreNotAcquired, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_RELEASE_DISABLE)) +__WEAK void EvrRtxSemaphoreRelease (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreRelease, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_RELEASED_DISABLE)) +__WEAK void EvrRtxSemaphoreReleased (osSemaphoreId_t semaphore_id, uint32_t tokens) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreReleased, (uint32_t)semaphore_id, tokens); +#else + (void)semaphore_id; + (void)tokens; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_GET_COUNT_DISABLE)) +__WEAK void EvrRtxSemaphoreGetCount (osSemaphoreId_t semaphore_id, uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreGetCount, (uint32_t)semaphore_id, count); +#else + (void)semaphore_id; + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_DELETE_DISABLE)) +__WEAK void EvrRtxSemaphoreDelete (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreDelete, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_DESTROYED_DISABLE)) +__WEAK void EvrRtxSemaphoreDestroyed (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxSemaphoreDestroyed, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + + +// ==== Memory Pool Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ERROR_DISABLE)) +__WEAK void EvrRtxMemoryPoolError (osMemoryPoolId_t mp_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolError, (uint32_t)mp_id, (uint32_t)status); +#else + (void)mp_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_NEW_DISABLE)) +__WEAK void EvrRtxMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMemoryPoolNew, block_count, block_size, (uint32_t)attr, 0U); +#else + (void)block_count; + (void)block_size; + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_CREATED_DISABLE)) +__WEAK void EvrRtxMemoryPoolCreated (osMemoryPoolId_t mp_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolCreated, (uint32_t)mp_id, (uint32_t)name); +#else + (void)mp_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_NAME_DISABLE)) +__WEAK void EvrRtxMemoryPoolGetName (osMemoryPoolId_t mp_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolGetName, (uint32_t)mp_id, (uint32_t)name); +#else + (void)mp_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_DISABLE)) +__WEAK void EvrRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolAlloc, (uint32_t)mp_id, timeout); +#else + (void)mp_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_PENDING_DISABLE)) +__WEAK void EvrRtxMemoryPoolAllocPending (osMemoryPoolId_t mp_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolAllocPending, (uint32_t)mp_id, timeout); +#else + (void)mp_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_TIMEOUT_DISABLE)) +__WEAK void EvrRtxMemoryPoolAllocTimeout (osMemoryPoolId_t mp_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolAllocTimeout, (uint32_t)mp_id, 0U); +#else + (void)mp_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOCATED_DISABLE)) +__WEAK void EvrRtxMemoryPoolAllocated (osMemoryPoolId_t mp_id, void *block) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolAllocated, (uint32_t)mp_id, (uint32_t)block); +#else + (void)mp_id; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_FAILED_DISABLE)) +__WEAK void EvrRtxMemoryPoolAllocFailed (osMemoryPoolId_t mp_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolAllocFailed, (uint32_t)mp_id, 0U); +#else + (void)mp_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_FREE_DISABLE)) +__WEAK void EvrRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolFree, (uint32_t)mp_id, (uint32_t)block); +#else + (void)mp_id; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DEALLOCATED_DISABLE)) +__WEAK void EvrRtxMemoryPoolDeallocated (osMemoryPoolId_t mp_id, void *block) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolDeallocated, (uint32_t)mp_id, (uint32_t)block); +#else + (void)mp_id; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_FREE_FAILED_DISABLE)) +__WEAK void EvrRtxMemoryPoolFreeFailed (osMemoryPoolId_t mp_id, void *block) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolFreeFailed, (uint32_t)mp_id, (uint32_t)block); +#else + (void)mp_id; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_CAPACITY_DISABLE)) +__WEAK void EvrRtxMemoryPoolGetCapacity (osMemoryPoolId_t mp_id, uint32_t capacity) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolGetCapacity, (uint32_t)mp_id, capacity); +#else + (void)mp_id; + (void)capacity; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_BLOCK_SZIE_DISABLE)) +__WEAK void EvrRtxMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id, uint32_t block_size) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolGetBlockSize, (uint32_t)mp_id, block_size); +#else + (void)mp_id; + (void)block_size; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_COUNT_DISABLE)) +__WEAK void EvrRtxMemoryPoolGetCount (osMemoryPoolId_t mp_id, uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolGetCount, (uint32_t)mp_id, count); +#else + (void)mp_id; + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_SPACE_DISABLE)) +__WEAK void EvrRtxMemoryPoolGetSpace (osMemoryPoolId_t mp_id, uint32_t space) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolGetSpace, (uint32_t)mp_id, space); +#else + (void)mp_id; + (void)space; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DELETE_DISABLE)) +__WEAK void EvrRtxMemoryPoolDelete (osMemoryPoolId_t mp_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolDelete, (uint32_t)mp_id, 0U); +#else + (void)mp_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DESTROYED_DISABLE)) +__WEAK void EvrRtxMemoryPoolDestroyed (osMemoryPoolId_t mp_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMemoryPoolDestroyed, (uint32_t)mp_id, 0U); +#else + (void)mp_id; +#endif +} +#endif + + +// ==== Message Queue Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_ERROR_DISABLE)) +__WEAK void EvrRtxMessageQueueError (osMessageQueueId_t mq_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2 (EvtRtxMessageQueueError, (uint32_t)mq_id, (uint32_t)status); +#else + (void)mq_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NEW_DISABLE)) +__WEAK void EvrRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMessageQueueNew, msg_count, msg_size, (uint32_t)attr, 0U); +#else + (void)msg_count; + (void)msg_size; + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_CREATED_DISABLE)) +__WEAK void EvrRtxMessageQueueCreated (osMessageQueueId_t mq_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueCreated, (uint32_t)mq_id, (uint32_t)name); +#else + (void)mq_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_NAME_DISABLE)) +__WEAK void EvrRtxMessageQueueGetName (osMessageQueueId_t mq_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueGetName, (uint32_t)mq_id, (uint32_t)name); +#else + (void)mq_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_DISABLE)) +__WEAK void EvrRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMessageQueuePut, (uint32_t)mq_id, (uint32_t)msg_ptr, (uint32_t)msg_prio, timeout); +#else + (void)mq_id; + (void)msg_ptr; + (void)msg_prio; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_PENDING_DISABLE)) +__WEAK void EvrRtxMessageQueuePutPending (osMessageQueueId_t mq_id, const void *msg_ptr, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMessageQueuePutPending, (uint32_t)mq_id, (uint32_t)msg_ptr, timeout, 0U); +#else + (void)mq_id; + (void)msg_ptr; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_TIMEOUT_DISABLE)) +__WEAK void EvrRtxMessageQueuePutTimeout (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueuePutTimeout, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_INSERT_PENDING_DISABLE)) +__WEAK void EvrRtxMessageQueueInsertPending (osMessageQueueId_t mq_id, const void *msg_ptr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueInsertPending, (uint32_t)mq_id, (uint32_t)msg_ptr); +#else + (void)mq_id; + (void)msg_ptr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_INSERTED_DISABLE)) +__WEAK void EvrRtxMessageQueueInserted (osMessageQueueId_t mq_id, const void *msg_ptr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueInserted, (uint32_t)mq_id, (uint32_t)msg_ptr); +#else + (void)mq_id; + (void)msg_ptr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NOT_INSERTED_DISABLE)) +__WEAK void EvrRtxMessageQueueNotInserted (osMessageQueueId_t mq_id, const void *msg_ptr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueNotInserted, (uint32_t)mq_id, (uint32_t)msg_ptr); +#else + (void)mq_id; + (void)msg_ptr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_DISABLE)) +__WEAK void EvrRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMessageQueueGet, (uint32_t)mq_id, (uint32_t)msg_ptr, (uint32_t)msg_prio, timeout); +#else + (void)mq_id; + (void)msg_ptr; + (void)msg_prio; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_PENDING_DISABLE)) +__WEAK void EvrRtxMessageQueueGetPending (osMessageQueueId_t mq_id, void *msg_ptr, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord4(EvtRtxMessageQueueGetPending, (uint32_t)mq_id, (uint32_t)msg_ptr, timeout, 0U); +#else + (void)mq_id; + (void)msg_ptr; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_TIMEOUT_DISABLE)) +__WEAK void EvrRtxMessageQueueGetTimeout (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueGetTimeout, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RETRIEVED_DISABLE)) +__WEAK void EvrRtxMessageQueueRetrieved (osMessageQueueId_t mq_id, void *msg_ptr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueRetrieved, (uint32_t)mq_id, (uint32_t)msg_ptr); +#else + (void)mq_id; + (void)msg_ptr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NOT_RETRIEVED_DISABLE)) +__WEAK void EvrRtxMessageQueueNotRetrieved (osMessageQueueId_t mq_id, void *msg_ptr) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueNotRetrieved, (uint32_t)mq_id, (uint32_t)msg_ptr); +#else + (void)mq_id; + (void)msg_ptr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_CAPACITY_DISABLE)) +__WEAK void EvrRtxMessageQueueGetCapacity (osMessageQueueId_t mq_id, uint32_t capacity) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueGetCapacity, (uint32_t)mq_id, capacity); +#else + (void)mq_id; + (void)capacity; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_MSG_SIZE_DISABLE)) +__WEAK void EvrRtxMessageQueueGetMsgSize (osMessageQueueId_t mq_id, uint32_t msg_size) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueGetMsgSize, (uint32_t)mq_id, msg_size); +#else + (void)mq_id; + (void)msg_size; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_COUNT_DISABLE)) +__WEAK void EvrRtxMessageQueueGetCount (osMessageQueueId_t mq_id, uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueGetCount, (uint32_t)mq_id, count); +#else + (void)mq_id; + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_SPACE_DISABLE)) +__WEAK void EvrRtxMessageQueueGetSpace (osMessageQueueId_t mq_id, uint32_t space) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueGetSpace, (uint32_t)mq_id, space); +#else + (void)mq_id; + (void)space; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RESET_DISABLE)) +__WEAK void EvrRtxMessageQueueReset (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueReset, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RESET_DONE_DISABLE)) +__WEAK void EvrRtxMessageQueueResetDone (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueResetDone, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_DELETE_DISABLE)) +__WEAK void EvrRtxMessageQueueDelete (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueDelete, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_DESTROYED_DISABLE)) +__WEAK void EvrRtxMessageQueueDestroyed (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + (void)EventRecord2(EvtRtxMessageQueueDestroyed, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif diff --git a/rtos/rtx5/rtx_kernel.c b/rtos/rtx5/rtx_kernel.c new file mode 100644 index 0000000..4735c73 --- /dev/null +++ b/rtos/rtx5/rtx_kernel.c @@ -0,0 +1,733 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Kernel functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" +#include "os_tick.h" +#include "hal_timer.h" +#include "hal_trace.h" + +// OS Runtime Information +osRtxInfo_t osRtxInfo __attribute__((section(".data.os"))) = +//lint -e{785} "Initialize only OS ID, OS Version and Kernel State" +{ .os_id = osRtxKernelId, .version = osRtxVersionKernel, .kernel.state = osRtxKernelInactive }; + +#define OS_BSS_LOC __attribute__((section(".bss.os"))) +OS_BSS_LOC static uint32_t systick_lock_val; +OS_BSS_LOC static uint32_t systick_lock_ts; + +// ==== Helper functions ==== + +/// Block Kernel (disable: thread switching, time tick, post ISR processing). +static void KernelBlock (void) { + + OS_Tick_Disable(); + + osRtxInfo.kernel.blocked = 1U; + __DSB(); + + if (GetPendSV() != 0U) { + ClrPendSV(); + osRtxInfo.kernel.pendSV = 1U; + } +} + +/// Unblock Kernel +static void KernelUnblock (void) { + + osRtxInfo.kernel.blocked = 0U; + __DSB(); + + if (osRtxInfo.kernel.pendSV != 0U) { + osRtxInfo.kernel.pendSV = 0U; + SetPendSV(); + } + + OS_Tick_Enable(); +} + + +// ==== Service Calls ==== + +/// Initialize the RTOS Kernel. +/// \note API identical to osKernelInitialize +static osStatus_t svcRtxKernelInitialize (void) { + + if (osRtxInfo.kernel.state == osRtxKernelReady) { + EvrRtxKernelInitialized(); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osOK; + } + if (osRtxInfo.kernel.state != osRtxKernelInactive) { + EvrRtxKernelError((int32_t)osError); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osError; + } + +#if (DOMAIN_NS == 1) + // Initialize Secure Process Stack + if (TZ_InitContextSystem_S() == 0U) { + EvrRtxKernelError(osRtxErrorTZ_InitContext_S); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osError; + } +#endif + + // Initialize osRtxInfo + memset((uint8_t *)&osRtxInfo + offsetof(osRtxInfo_t, kernel), 0, sizeof(osRtxInfo) - offsetof(osRtxInfo_t, kernel)); + + osRtxInfo.isr_queue.data = osRtxConfig.isr_queue.data; + osRtxInfo.isr_queue.max = osRtxConfig.isr_queue.max; + + osRtxInfo.thread.robin.timeout = osRtxConfig.robin_timeout; + + // Initialize Memory Pools (Variable Block Size) + if (osRtxMemoryInit(osRtxConfig.mem.common_addr, osRtxConfig.mem.common_size) != 0U) { + osRtxInfo.mem.common = osRtxConfig.mem.common_addr; + } + if (osRtxMemoryInit(osRtxConfig.mem.stack_addr, osRtxConfig.mem.stack_size) != 0U) { + osRtxInfo.mem.stack = osRtxConfig.mem.stack_addr; + } else { + osRtxInfo.mem.stack = osRtxInfo.mem.common; + } + if (osRtxMemoryInit(osRtxConfig.mem.mp_data_addr, osRtxConfig.mem.mp_data_size) != 0U) { + osRtxInfo.mem.mp_data = osRtxConfig.mem.mp_data_addr; + } else { + osRtxInfo.mem.mp_data = osRtxInfo.mem.common; + } + if (osRtxMemoryInit(osRtxConfig.mem.mq_data_addr, osRtxConfig.mem.mq_data_size) != 0U) { + osRtxInfo.mem.mq_data = osRtxConfig.mem.mq_data_addr; + } else { + osRtxInfo.mem.mq_data = osRtxInfo.mem.common; + } + + // Initialize Memory Pools (Fixed Block Size) + if (osRtxConfig.mpi.stack != NULL) { + (void)osRtxMemoryPoolInit(osRtxConfig.mpi.stack, + osRtxConfig.mpi.stack->max_blocks, + osRtxConfig.mpi.stack->block_size, + osRtxConfig.mpi.stack->block_base); + osRtxInfo.mpi.stack = osRtxConfig.mpi.stack; + } + if (osRtxConfig.mpi.thread != NULL) { + (void)osRtxMemoryPoolInit(osRtxConfig.mpi.thread, + osRtxConfig.mpi.thread->max_blocks, + osRtxConfig.mpi.thread->block_size, + osRtxConfig.mpi.thread->block_base); + osRtxInfo.mpi.thread = osRtxConfig.mpi.thread; + } + if (osRtxConfig.mpi.timer != NULL) { + (void)osRtxMemoryPoolInit(osRtxConfig.mpi.timer, + osRtxConfig.mpi.timer->max_blocks, + osRtxConfig.mpi.timer->block_size, + osRtxConfig.mpi.timer->block_base); + osRtxInfo.mpi.timer = osRtxConfig.mpi.timer; + } + if (osRtxConfig.mpi.event_flags != NULL) { + (void)osRtxMemoryPoolInit(osRtxConfig.mpi.event_flags, + osRtxConfig.mpi.event_flags->max_blocks, + osRtxConfig.mpi.event_flags->block_size, + osRtxConfig.mpi.event_flags->block_base); + osRtxInfo.mpi.event_flags = osRtxConfig.mpi.event_flags; + } + if (osRtxConfig.mpi.mutex != NULL) { + (void)osRtxMemoryPoolInit(osRtxConfig.mpi.mutex, + osRtxConfig.mpi.mutex->max_blocks, + osRtxConfig.mpi.mutex->block_size, + osRtxConfig.mpi.mutex->block_base); + osRtxInfo.mpi.mutex = osRtxConfig.mpi.mutex; + } + if (osRtxConfig.mpi.semaphore != NULL) { + (void)osRtxMemoryPoolInit(osRtxConfig.mpi.semaphore, + osRtxConfig.mpi.semaphore->max_blocks, + osRtxConfig.mpi.semaphore->block_size, + osRtxConfig.mpi.semaphore->block_base); + osRtxInfo.mpi.semaphore = osRtxConfig.mpi.semaphore; + } + if (osRtxConfig.mpi.memory_pool != NULL) { + (void)osRtxMemoryPoolInit(osRtxConfig.mpi.memory_pool, + osRtxConfig.mpi.memory_pool->max_blocks, + osRtxConfig.mpi.memory_pool->block_size, + osRtxConfig.mpi.memory_pool->block_base); + osRtxInfo.mpi.memory_pool = osRtxConfig.mpi.memory_pool; + } + if (osRtxConfig.mpi.message_queue != NULL) { + (void)osRtxMemoryPoolInit(osRtxConfig.mpi.message_queue, + osRtxConfig.mpi.message_queue->max_blocks, + osRtxConfig.mpi.message_queue->block_size, + osRtxConfig.mpi.message_queue->block_base); + osRtxInfo.mpi.message_queue = osRtxConfig.mpi.message_queue; + } + + osRtxInfo.kernel.state = osRtxKernelReady; + + EvrRtxKernelInitialized(); + + return osOK; +} + +/// Get RTOS Kernel Information. +/// \note API identical to osKernelGetInfo +static osStatus_t svcRtxKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) { + uint32_t size; + + if (version != NULL) { + version->api = osRtxVersionAPI; + version->kernel = osRtxVersionKernel; + } + + if ((id_buf != NULL) && (id_size != 0U)) { + if (id_size > sizeof(osRtxKernelId)) { + size = sizeof(osRtxKernelId); + } else { + size = id_size; + } + memcpy(id_buf, osRtxKernelId, size); + } + + EvrRtxKernelInfoRetrieved(version, id_buf, id_size); + + return osOK; +} + +/// Get the current RTOS Kernel state. +/// \note API identical to osKernelGetState +static osKernelState_t svcRtxKernelGetState (void) { + osKernelState_t state = osRtxKernelState(); + EvrRtxKernelGetState(state); + return state; +} + +/// Start the RTOS Kernel scheduler. +/// \note API identical to osKernelStart +static osStatus_t svcRtxKernelStart (void) { + os_thread_t *thread; + + if (osRtxInfo.kernel.state != osRtxKernelReady) { + EvrRtxKernelError(osRtxErrorKernelNotReady); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osError; + } + + // Thread startup (Idle and Timer Thread) + if (!osRtxThreadStartup()) { + EvrRtxKernelError((int32_t)osError); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osError; + } + + // Setup SVC and PendSV System Service Calls + SVC_Setup(); + + // Setup RTOS Tick + if (OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER) != 0) { + EvrRtxKernelError((int32_t)osError); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osError; + } + osRtxInfo.tick_irqn = OS_Tick_GetIRQn(); + + // Enable RTOS Tick + OS_Tick_Enable(); + + // Switch to Ready Thread with highest Priority + thread = osRtxThreadListGet(&osRtxInfo.thread.ready); + osRtxThreadSwitch(thread); + + if ((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U) { + // Privileged Thread mode & PSP + __set_CONTROL(0x02U); + } else { + // Unprivileged Thread mode & PSP + __set_CONTROL(0x03U); + } + + osRtxInfo.kernel.state = osRtxKernelRunning; + + EvrRtxKernelStarted(); + + return osOK; +} + +/// Lock the RTOS Kernel scheduler. +/// \note API identical to osKernelLock +static int32_t svcRtxKernelLock (void) { + int32_t lock; + + switch (osRtxInfo.kernel.state) { + case osRtxKernelRunning: + osRtxInfo.kernel.state = osRtxKernelLocked; + EvrRtxKernelLocked(0); + lock = 0; + break; + case osRtxKernelLocked: + EvrRtxKernelLocked(1); + lock = 1; + break; + default: + EvrRtxKernelError((int32_t)osError); + lock = (int32_t)osError; + break; + } + return lock; +} + +/// Unlock the RTOS Kernel scheduler. +/// \note API identical to osKernelUnlock +static int32_t svcRtxKernelUnlock (void) { + int32_t lock; + + switch (osRtxInfo.kernel.state) { + case osRtxKernelRunning: + EvrRtxKernelUnlocked(0); + lock = 0; + break; + case osRtxKernelLocked: + osRtxInfo.kernel.state = osRtxKernelRunning; + EvrRtxKernelUnlocked(1); + lock = 1; + break; + default: + EvrRtxKernelError((int32_t)osError); + lock = (int32_t)osError; + break; + } + return lock; +} + +/// Restore the RTOS Kernel scheduler lock state. +/// \note API identical to osKernelRestoreLock +static int32_t svcRtxKernelRestoreLock (int32_t lock) { + int32_t lock_new; + + switch (osRtxInfo.kernel.state) { + case osRtxKernelRunning: + case osRtxKernelLocked: + switch (lock) { + case 0: + osRtxInfo.kernel.state = osRtxKernelRunning; + EvrRtxKernelLockRestored(0); + lock_new = 0; + break; + case 1: + osRtxInfo.kernel.state = osRtxKernelLocked; + EvrRtxKernelLockRestored(1); + lock_new = 1; + break; + default: + EvrRtxKernelError((int32_t)osError); + lock_new = (int32_t)osError; + break; + } + break; + default: + EvrRtxKernelError((int32_t)osError); + lock_new = (int32_t)osError; + break; + } + return lock_new; +} + +/// Suspend the RTOS Kernel scheduler. +/// \note API identical to osKernelSuspend +static uint32_t svcRtxKernelSuspend (void) { + const os_thread_t *thread; + const os_timer_t *timer; + uint32_t delay; + + if (osRtxInfo.kernel.state != osRtxKernelRunning) { + EvrRtxKernelError(osRtxErrorKernelNotRunning); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + KernelBlock(); + + systick_lock_val = OS_Tick_GetInterval() - 1 - OS_Tick_GetCount(); + systick_lock_ts = hal_sys_timer_get(); + + delay = osWaitForever; + + // Check Thread Delay list + thread = osRtxInfo.thread.delay_list; + if (thread != NULL) { + delay = thread->delay; + } + + // Check Active Timer list + timer = osRtxInfo.timer.list; + if (timer != NULL) { + if (timer->tick < delay) { + delay = timer->tick; + } + } + + osRtxInfo.kernel.state = osRtxKernelSuspended; + + EvrRtxKernelSuspended(delay); + + return delay; +} + +/// Resume the RTOS Kernel scheduler. +/// \note API identical to osKernelResume +static void svcRtxKernelResume (uint32_t sleep_ticks) { + os_thread_t *thread; + os_timer_t *timer; + uint32_t delay; + uint32_t ticks; + + uint32_t resume_ts; + uint32_t tick_interval; + uint32_t sysclk_remain; + uint32_t delta_clk; + uint32_t sleep_clk; + + if (osRtxInfo.kernel.state != osRtxKernelSuspended) { + EvrRtxKernelResumed(); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return; + } + + tick_interval = OS_Tick_GetInterval(); + resume_ts = hal_sys_timer_get(); + sleep_clk = (resume_ts - systick_lock_ts) * (OS_CLOCK_NOMINAL / CONFIG_SYSTICK_HZ_NOMINAL); + if (systick_lock_val == 0) { + sleep_ticks = sleep_clk / tick_interval; + sysclk_remain = sleep_clk % tick_interval; + } else if (sleep_clk >= systick_lock_val) { + delta_clk = sleep_clk - systick_lock_val; + sleep_ticks = delta_clk / tick_interval + 1; + sysclk_remain = tick_interval - delta_clk % tick_interval; + } else { + sleep_ticks = 0; + sysclk_remain = systick_lock_val - sleep_clk; + } +#if __RTX_CPU_STATISTICS__ + osRtxInfo.thread.run.curr->rtime += sleep_ticks; +#endif + osRtxInfo.kernel.tick += sleep_ticks; + + // Process Thread Delay list + thread = osRtxInfo.thread.delay_list; + if (thread != NULL) { + delay = sleep_ticks; + do { + if (delay >= thread->delay) { + delay -= thread->delay; + thread->delay = 1U; + osRtxThreadDelayTick(); + thread = osRtxInfo.thread.delay_list; + } else { + thread->delay -= delay; + delay = 0U; + } + } while ((thread != NULL) && (delay != 0U)); + } + + // Process Active Timer list + timer = osRtxInfo.timer.list; + if (timer != NULL) { + ticks = sleep_ticks; + do { + if (ticks >= timer->tick) { + ticks -= timer->tick; + timer->tick = 1U; + osRtxInfo.timer.tick(); + timer = osRtxInfo.timer.list; + } else { + timer->tick -= ticks; + ticks = 0U; + } + } while ((timer != NULL) && (ticks != 0U)); + } + + osRtxInfo.kernel.state = osRtxKernelRunning; + + osRtxThreadDispatch(NULL); + + if (sysclk_remain == tick_interval) { + sysclk_remain = 0; + } + if (sysclk_remain) { + SysTick->LOAD = sysclk_remain; + SysTick->VAL = 0; + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + while (SysTick->VAL == 0); + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + SysTick->LOAD = tick_interval - 1; + } else + SysTick->VAL = 0; + +#if defined(DEBUG_SLEEP) && (DEBUG_SLEEP >= 1) + if (sleep_clk > 0) { + TRACE(7,"[%u/0x%X][%2u/%u] resume: suspend tick:%u, sleep_clk=%u ticks=%u", + TICKS_TO_MS(hal_sys_timer_get()), hal_sys_timer_get(), sysclk_remain, SysTick->VAL, systick_lock_val, + sleep_clk, sleep_ticks); + } +#endif + + KernelUnblock(); + + EvrRtxKernelResumed(); + +} + +/// Get the RTOS kernel tick count. +/// \note API identical to osKernelGetTickCount +static uint32_t svcRtxKernelGetTickCount (void) { + EvrRtxKernelGetTickCount(osRtxInfo.kernel.tick); + return osRtxInfo.kernel.tick; +} + +/// Get the RTOS kernel tick frequency. +/// \note API identical to osKernelGetTickFreq +static uint32_t svcRtxKernelGetTickFreq (void) { + EvrRtxKernelGetTickFreq(osRtxConfig.tick_freq); + return osRtxConfig.tick_freq; +} + +/// Get the RTOS kernel system timer count. +/// \note API identical to osKernelGetSysTimerCount +static uint32_t svcRtxKernelGetSysTimerCount (void) { + uint32_t tick; + uint32_t count; + + tick = (uint32_t)osRtxInfo.kernel.tick; + count = OS_Tick_GetCount(); + if (OS_Tick_GetOverflow() != 0U) { + count = OS_Tick_GetCount(); + tick++; + } + count += tick * OS_Tick_GetInterval(); + EvrRtxKernelGetSysTimerCount(count); + return count; +} + +/// Get the RTOS kernel system timer frequency. +/// \note API identical to osKernelGetSysTimerFreq +static uint32_t svcRtxKernelGetSysTimerFreq (void) { + uint32_t freq = OS_Tick_GetClock(); + EvrRtxKernelGetSysTimerFreq(freq); + return freq; +} + +// Service Calls definitions +//lint ++flb "Library Begin" [MISRA Note 11] +SVC0_0 (KernelInitialize, osStatus_t) +SVC0_3 (KernelGetInfo, osStatus_t, osVersion_t *, char *, uint32_t) +SVC0_0 (KernelStart, osStatus_t) +SVC0_0 (KernelLock, int32_t) +SVC0_0 (KernelUnlock, int32_t) +SVC0_1 (KernelRestoreLock, int32_t, int32_t) +SVC0_0 (KernelSuspend, uint32_t) +SVC0_1N(KernelResume, void, uint32_t) +SVC0_0 (KernelGetState, osKernelState_t) +SVC0_0 (KernelGetTickCount, uint32_t) +SVC0_0 (KernelGetTickFreq, uint32_t) +SVC0_0 (KernelGetSysTimerCount, uint32_t) +SVC0_0 (KernelGetSysTimerFreq, uint32_t) +//lint --flb "Library End" + + +// ==== Library functions ==== + +/// RTOS Kernel Pre-Initialization Hook +//lint -esym(759,osRtxKernelPreInit) "Prototype in header" +//lint -esym(765,osRtxKernelPreInit) "Global scope (can be overridden)" +//lint -esym(522,osRtxKernelPreInit) "Can be overridden (do not lack side-effects)" +__WEAK void osRtxKernelPreInit (void) { +} + + +// ==== Public API ==== + +/// Initialize the RTOS Kernel. +osStatus_t osKernelInitialize (void) { + osStatus_t status; + + osRtxKernelPreInit(); + EvrRtxKernelInitialize(); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxKernelError((int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcKernelInitialize(); + } + return status; +} + +/// Get RTOS Kernel Information. +osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) { + osStatus_t status; + + EvrRtxKernelGetInfo(version, id_buf, id_size); + if (IsIrqMode() || IsIrqMasked() || IsPrivileged()) { + status = svcRtxKernelGetInfo(version, id_buf, id_size); + } else { + status = __svcKernelGetInfo(version, id_buf, id_size); + } + return status; +} + +/// Get the current RTOS Kernel state. +osKernelState_t osKernelGetState (void) { + osKernelState_t state; + + if (IsIrqMode() || IsIrqMasked() || IsPrivileged()) { + state = svcRtxKernelGetState(); + } else { + state = __svcKernelGetState(); + } + return state; +} + +/// Start the RTOS Kernel scheduler. +osStatus_t osKernelStart (void) { + osStatus_t status; + + EvrRtxKernelStart(); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxKernelError((int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcKernelStart(); + } + return status; +} + +/// Lock the RTOS Kernel scheduler. +int32_t osKernelLock (void) { + int32_t lock; + + EvrRtxKernelLock(); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxKernelError((int32_t)osErrorISR); + lock = (int32_t)osErrorISR; + } else { + lock = __svcKernelLock(); + } + return lock; +} + +/// Unlock the RTOS Kernel scheduler. +int32_t osKernelUnlock (void) { + int32_t lock; + + EvrRtxKernelUnlock(); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxKernelError((int32_t)osErrorISR); + lock = (int32_t)osErrorISR; + } else { + lock = __svcKernelUnlock(); + } + return lock; +} + +/// Restore the RTOS Kernel scheduler lock state. +int32_t osKernelRestoreLock (int32_t lock) { + int32_t lock_new; + + EvrRtxKernelRestoreLock(lock); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxKernelError((int32_t)osErrorISR); + lock_new = (int32_t)osErrorISR; + } else { + lock_new = __svcKernelRestoreLock(lock); + } + return lock_new; +} + +/// Suspend the RTOS Kernel scheduler. +uint32_t osKernelSuspend (void) { + uint32_t ticks; + + EvrRtxKernelSuspend(); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxKernelError((int32_t)osErrorISR); + ticks = 0U; + } else { + ticks = __svcKernelSuspend(); + } + return ticks; +} + +/// Resume the RTOS Kernel scheduler. +void osKernelResume (uint32_t sleep_ticks) { + + EvrRtxKernelResume(sleep_ticks); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxKernelError((int32_t)osErrorISR); + } else { + __svcKernelResume(sleep_ticks); + } +} + +/// Get the RTOS kernel tick count. +uint32_t osKernelGetTickCount (void) { + uint32_t count; + + if (IsIrqMode() || IsIrqMasked()) { + count = svcRtxKernelGetTickCount(); + } else { + count = __svcKernelGetTickCount(); + } + return count; +} + +/// Get the RTOS kernel tick frequency. +uint32_t osKernelGetTickFreq (void) { + uint32_t freq; + + if (IsIrqMode() || IsIrqMasked()) { + freq = svcRtxKernelGetTickFreq(); + } else { + freq = __svcKernelGetTickFreq(); + } + return freq; +} + +/// Get the RTOS kernel system timer count. +uint32_t osKernelGetSysTimerCount (void) { + uint32_t count; + + if (IsIrqMode() || IsIrqMasked()) { + count = svcRtxKernelGetSysTimerCount(); + } else { + count = __svcKernelGetSysTimerCount(); + } + return count; +} + +/// Get the RTOS kernel system timer frequency. +uint32_t osKernelGetSysTimerFreq (void) { + uint32_t freq; + + if (IsIrqMode() || IsIrqMasked()) { + freq = svcRtxKernelGetSysTimerFreq(); + } else { + freq = __svcKernelGetSysTimerFreq(); + } + return freq; +} diff --git a/rtos/rtx5/rtx_lib.c b/rtos/rtx5/rtx_lib.c new file mode 100644 index 0000000..431b240 --- /dev/null +++ b/rtos/rtx5/rtx_lib.c @@ -0,0 +1,824 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: RTX Library Configuration + * + * ----------------------------------------------------------------------------- + */ + +#include "cmsis_compiler.h" +#include "rtx_config.h" +#include "rtx_os.h" + +#ifdef RTE_Compiler_EventRecorder +#include "EventRecorder.h" +#include "EventRecorderConf.h" +#endif +#include "rtx_evr.h" + + +// System Configuration +// ==================== + +// Dynamic Memory +#if (OS_DYNAMIC_MEM_SIZE != 0) +#if ((OS_DYNAMIC_MEM_SIZE % 8) != 0) +#error "Invalid Dynamic Memory size!" +#endif +static uint64_t os_mem[OS_DYNAMIC_MEM_SIZE/8] \ +__attribute__((section(".bss.os"))); +#endif + +// Kernel Tick Frequency +#if (OS_TICK_FREQ < 1) +#error "Invalid Kernel Tick Frequency!" +#endif + +// ISR FIFO Queue +#if (OS_ISR_FIFO_QUEUE < 4) +#error "Invalid ISR FIFO Queue size!" +#endif +static void *os_isr_queue[OS_ISR_FIFO_QUEUE] \ +__attribute__((section(".bss.os"))); + + +// Thread Configuration +// ==================== + +#if (((OS_STACK_SIZE % 8) != 0) || (OS_STACK_SIZE < 72)) +#error "Invalid default Thread Stack size!" +#endif + +#if (((OS_IDLE_THREAD_STACK_SIZE % 8) != 0) || (OS_IDLE_THREAD_STACK_SIZE < 72)) +#error "Invalid Idle Thread Stack size!" +#endif + + +#if (OS_THREAD_OBJ_MEM != 0) + +#if (OS_THREAD_NUM == 0) +#error "Invalid number of user Threads!" +#endif + +#if ((OS_THREAD_USER_STACK_SIZE != 0) && ((OS_THREAD_USER_STACK_SIZE % 8) != 0)) +#error "Invalid total Stack size!" +#endif + +// Thread Control Blocks +static osRtxThread_t os_thread_cb[OS_THREAD_NUM] \ +__attribute__((section(".bss.os.thread.cb"))); + +// Thread Default Stack +#if (OS_THREAD_DEF_STACK_NUM != 0) +static uint64_t os_thread_def_stack[OS_THREAD_DEF_STACK_NUM*(OS_STACK_SIZE/8)] \ +__attribute__((section(".bss.os.thread.stack"))); +#endif + +// Memory Pool for Thread Control Blocks +static osRtxMpInfo_t os_mpi_thread \ +__attribute__((section(".data.os.thread.mpi"))) = +{ (uint32_t)OS_THREAD_NUM, 0U, (uint32_t)osRtxThreadCbSize, &os_thread_cb[0], NULL, NULL }; + +// Memory Pool for Thread Default Stack +#if (OS_THREAD_DEF_STACK_NUM != 0) +static osRtxMpInfo_t os_mpi_def_stack \ +__attribute__((section(".data.os.thread.mpi"))) = +{ (uint32_t)OS_THREAD_DEF_STACK_NUM, 0U, (uint32_t)OS_STACK_SIZE, &os_thread_def_stack[0], NULL, NULL }; +#endif + +// Memory Pool for Thread Stack +#if (OS_THREAD_USER_STACK_SIZE != 0) +static uint64_t os_thread_stack[2 + OS_THREAD_NUM + (OS_THREAD_USER_STACK_SIZE/8)] \ +__attribute__((section(".bss.os.thread.stack"))); +#endif + +#endif // (OS_THREAD_OBJ_MEM != 0) + + +// Stack overrun checking +#if (OS_STACK_CHECK == 0) +// Override library function +extern void osRtxThreadStackCheck (void); + void osRtxThreadStackCheck (void) {} +#endif + + +// Idle Thread Control Block +static osRtxThread_t os_idle_thread_cb \ +__attribute__((section(".bss.os.thread.cb"))); + +// Idle Thread Stack +static uint64_t os_idle_thread_stack[OS_IDLE_THREAD_STACK_SIZE/8] \ +__attribute__((section(".bss.os.thread.stack"))); + +// Idle Thread Attributes +static const osThreadAttr_t os_idle_thread_attr = { +#if defined(OS_IDLE_THREAD_NAME) + OS_IDLE_THREAD_NAME, +#else + NULL, +#endif + osThreadDetached, + &os_idle_thread_cb, + (uint32_t)sizeof(os_idle_thread_cb), + &os_idle_thread_stack[0], + (uint32_t)sizeof(os_idle_thread_stack), + osPriorityIdle, +#if defined(OS_IDLE_THREAD_TZ_MOD_ID) + (uint32_t)OS_IDLE_THREAD_TZ_MOD_ID, +#else + 0U, +#endif + 0U +}; + + +// Timer Configuration +// =================== + +#if (OS_TIMER_OBJ_MEM != 0) + +#if (OS_TIMER_NUM == 0) +#error "Invalid number of Timer objects!" +#endif + +// Timer Control Blocks +static osRtxTimer_t os_timer_cb[OS_TIMER_NUM] \ +__attribute__((section(".bss.os.timer.cb"))); + +// Memory Pool for Timer Control Blocks +static osRtxMpInfo_t os_mpi_timer \ +__attribute__((section(".data.os.timer.mpi"))) = +{ (uint32_t)OS_TIMER_NUM, 0U, (uint32_t)osRtxTimerCbSize, &os_timer_cb[0], NULL, NULL }; + +#endif // (OS_TIMER_OBJ_MEM != 0) + + +#if ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0)) + +#if (((OS_TIMER_THREAD_STACK_SIZE % 8) != 0) || (OS_TIMER_THREAD_STACK_SIZE < 96)) +#error "Invalid Timer Thread Stack size!" +#endif + +// Timer Thread Control Block +static osRtxThread_t os_timer_thread_cb \ +__attribute__((section(".bss.os.thread.cb"))); + +// Timer Thread Stack +static uint64_t os_timer_thread_stack[OS_TIMER_THREAD_STACK_SIZE/8] \ +__attribute__((section(".bss.os.thread.stack"))); + +// Timer Thread Attributes +static const osThreadAttr_t os_timer_thread_attr = { +#if defined(OS_TIMER_THREAD_NAME) + OS_TIMER_THREAD_NAME, +#else + NULL, +#endif + osThreadDetached, + &os_timer_thread_cb, + (uint32_t)sizeof(os_timer_thread_cb), + &os_timer_thread_stack[0], + (uint32_t)sizeof(os_timer_thread_stack), + //lint -e{9030} -e{9034} "cast from signed to enum" + (osPriority_t)OS_TIMER_THREAD_PRIO, +#if defined(OS_TIMER_THREAD_TZ_MOD_ID) + (uint32_t)OS_TIMER_THREAD_TZ_MOD_ID, +#else + 0U, +#endif + 0U +}; + +// Timer Message Queue Control Block +static osRtxMessageQueue_t os_timer_mq_cb \ +__attribute__((section(".bss.os.msgqueue.cb"))); + +// Timer Message Queue Data +static uint32_t os_timer_mq_data[osRtxMessageQueueMemSize(OS_TIMER_CB_QUEUE,8)/4] \ +__attribute__((section(".bss.os.msgqueue.mem"))); + +// Timer Message Queue Attributes +static const osMessageQueueAttr_t os_timer_mq_attr = { + NULL, + 0U, + &os_timer_mq_cb, + (uint32_t)sizeof(os_timer_mq_cb), + &os_timer_mq_data[0], + (uint32_t)sizeof(os_timer_mq_data) +}; + +#else + +extern void osRtxTimerThread (void *argument); + void osRtxTimerThread (void *argument) { (void)argument; } + +#endif // ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0)) + + +// Event Flags Configuration +// ========================= + +#if (OS_EVFLAGS_OBJ_MEM != 0) + +#if (OS_EVFLAGS_NUM == 0) +#error "Invalid number of Event Flags objects!" +#endif + +// Event Flags Control Blocks +static osRtxEventFlags_t os_ef_cb[OS_EVFLAGS_NUM] \ +__attribute__((section(".bss.os.evflags.cb"))); + +// Memory Pool for Event Flags Control Blocks +static osRtxMpInfo_t os_mpi_ef \ +__attribute__((section(".data.os.evflags.mpi"))) = +{ (uint32_t)OS_EVFLAGS_NUM, 0U, (uint32_t)osRtxEventFlagsCbSize, &os_ef_cb[0], NULL, NULL }; + +#endif // (OS_EVFLAGS_OBJ_MEM != 0) + + +// Mutex Configuration +// =================== + +#if (OS_MUTEX_OBJ_MEM != 0) + +#if (OS_MUTEX_NUM == 0) +#error "Invalid number of Mutex objects!" +#endif + +// Mutex Control Blocks +static osRtxMutex_t os_mutex_cb[OS_MUTEX_NUM] \ +__attribute__((section(".bss.os.mutex.cb"))); + +// Memory Pool for Mutex Control Blocks +static osRtxMpInfo_t os_mpi_mutex \ +__attribute__((section(".data.os.mutex.mpi"))) = +{ (uint32_t)OS_MUTEX_NUM, 0U, (uint32_t)osRtxMutexCbSize, &os_mutex_cb[0], NULL, NULL }; + +#endif // (OS_MUTEX_OBJ_MEM != 0) + + +// Semaphore Configuration +// ======================= + +#if (OS_SEMAPHORE_OBJ_MEM != 0) + +#if (OS_SEMAPHORE_NUM == 0) +#error "Invalid number of Semaphore objects!" +#endif + +// Semaphore Control Blocks +static osRtxSemaphore_t os_semaphore_cb[OS_SEMAPHORE_NUM] \ +__attribute__((section(".bss.os.semaphore.cb"))); + +// Memory Pool for Semaphore Control Blocks +static osRtxMpInfo_t os_mpi_semaphore \ +__attribute__((section(".data.os.semaphore.mpi"))) = +{ (uint32_t)OS_SEMAPHORE_NUM, 0U, (uint32_t)osRtxSemaphoreCbSize, &os_semaphore_cb[0], NULL, NULL }; + +#endif // (OS_SEMAPHORE_OBJ_MEM != 0) + + +// Memory Pool Configuration +// ========================= + +#if (OS_MEMPOOL_OBJ_MEM != 0) + +#if (OS_MEMPOOL_NUM == 0) +#error "Invalid number of Memory Pool objects!" +#endif + +// Memory Pool Control Blocks +static osRtxMemoryPool_t os_mp_cb[OS_MEMPOOL_NUM] \ +__attribute__((section(".bss.os.mempool.cb"))); + +// Memory Pool for Memory Pool Control Blocks +static osRtxMpInfo_t os_mpi_mp \ +__attribute__((section(".data.os.mempool.mpi"))) = +{ (uint32_t)OS_MEMPOOL_NUM, 0U, (uint32_t)osRtxMemoryPoolCbSize, &os_mp_cb[0], NULL, NULL }; + +// Memory Pool for Memory Pool Data Storage +#if (OS_MEMPOOL_DATA_SIZE != 0) +#if ((OS_MEMPOOL_DATA_SIZE % 8) != 0) +#error "Invalid Data Memory size for Memory Pools!" +#endif +static uint64_t os_mp_data[2 + OS_MEMPOOL_NUM + (OS_MEMPOOL_DATA_SIZE/8)] \ +__attribute__((section(".bss.os.mempool.mem"))); +#endif + +#endif // (OS_MEMPOOL_OBJ_MEM != 0) + + +// Message Queue Configuration +// =========================== + +#if (OS_MSGQUEUE_OBJ_MEM != 0) + +#if (OS_MSGQUEUE_NUM == 0) +#error "Invalid number of Message Queue objects!" +#endif + +// Message Queue Control Blocks +static osRtxMessageQueue_t os_mq_cb[OS_MSGQUEUE_NUM] \ +__attribute__((section(".bss.os.msgqueue.cb"))); + +// Memory Pool for Message Queue Control Blocks +static osRtxMpInfo_t os_mpi_mq \ +__attribute__((section(".data.os.msgqueue.mpi"))) = +{ (uint32_t)OS_MSGQUEUE_NUM, 0U, (uint32_t)osRtxMessageQueueCbSize, &os_mq_cb[0], NULL, NULL }; + +// Memory Pool for Message Queue Data Storage +#if (OS_MSGQUEUE_DATA_SIZE != 0) +#if ((OS_MSGQUEUE_DATA_SIZE % 8) != 0) +#error "Invalid Data Memory size for Message Queues!" +#endif +static uint64_t os_mq_data[2 + OS_MSGQUEUE_NUM + (OS_MSGQUEUE_DATA_SIZE/8)] \ +__attribute__((section(".bss.os.msgqueue.mem"))); +#endif + +#endif // (OS_MSGQUEUE_OBJ_MEM != 0) + + +// Event Recorder Configuration +// ============================ + +#if (defined(OS_EVR_INIT) && (OS_EVR_INIT != 0)) + +// Initial Thread configuration covered also Thread Flags and Generic Wait +#if defined(OS_EVR_THREAD_FILTER) +#if !defined(OS_EVR_THFLAGS_FILTER) +#define OS_EVR_THFLAGS_FILTER OS_EVR_THREAD_FILTER +#endif +#if !defined(OS_EVR_WAIT_FILTER) +#define OS_EVR_WAIT_FILTER OS_EVR_THREAD_FILTER +#endif +#endif + +// Migrate initial filter configuration +#if defined(OS_EVR_MEMORY_FILTER) +#define OS_EVR_MEMORY_LEVEL (((OS_EVR_MEMORY_FILTER & 0x80U) != 0U) ? (OS_EVR_MEMORY_FILTER & 0x0FU) : 0U) +#endif +#if defined(OS_EVR_KERNEL_FILTER) +#define OS_EVR_KERNEL_LEVEL (((OS_EVR_KERNEL_FILTER & 0x80U) != 0U) ? (OS_EVR_KERNEL_FILTER & 0x0FU) : 0U) +#endif +#if defined(OS_EVR_THREAD_FILTER) +#define OS_EVR_THREAD_LEVEL (((OS_EVR_THREAD_FILTER & 0x80U) != 0U) ? (OS_EVR_THREAD_FILTER & 0x0FU) : 0U) +#endif +#if defined(OS_EVR_WAIT_FILTER) +#define OS_EVR_WAIT_LEVEL (((OS_EVR_WAIT_FILTER & 0x80U) != 0U) ? (OS_EVR_WAIT_FILTER & 0x0FU) : 0U) +#endif +#if defined(OS_EVR_THFLAGS_FILTER) +#define OS_EVR_THFLAGS_LEVEL (((OS_EVR_THFLAGS_FILTER & 0x80U) != 0U) ? (OS_EVR_THFLAGS_FILTER & 0x0FU) : 0U) +#endif +#if defined(OS_EVR_EVFLAGS_FILTER) +#define OS_EVR_EVFLAGS_LEVEL (((OS_EVR_EVFLAGS_FILTER & 0x80U) != 0U) ? (OS_EVR_EVFLAGS_FILTER & 0x0FU) : 0U) +#endif +#if defined(OS_EVR_TIMER_FILTER) +#define OS_EVR_TIMER_LEVEL (((OS_EVR_TIMER_FILTER & 0x80U) != 0U) ? (OS_EVR_TIMER_FILTER & 0x0FU) : 0U) +#endif +#if defined(OS_EVR_MUTEX_FILTER) +#define OS_EVR_MUTEX_LEVEL (((OS_EVR_MUTEX_FILTER & 0x80U) != 0U) ? (OS_EVR_MUTEX_FILTER & 0x0FU) : 0U) +#endif +#if defined(OS_EVR_SEMAPHORE_FILTER) +#define OS_EVR_SEMAPHORE_LEVEL (((OS_EVR_SEMAPHORE_FILTER & 0x80U) != 0U) ? (OS_EVR_SEMAPHORE_FILTER & 0x0FU) : 0U) +#endif +#if defined(OS_EVR_MEMPOOL_FILTER) +#define OS_EVR_MEMPOOL_LEVEL (((OS_EVR_MEMPOOL_FILTER & 0x80U) != 0U) ? (OS_EVR_MEMPOOL_FILTER & 0x0FU) : 0U) +#endif +#if defined(OS_EVR_MSGQUEUE_FILTER) +#define OS_EVR_MSGQUEUE_LEVEL (((OS_EVR_MSGQUEUE_FILTER & 0x80U) != 0U) ? (OS_EVR_MSGQUEUE_FILTER & 0x0FU) : 0U) +#endif + +#if defined(RTE_Compiler_EventRecorder) + +// Event Recorder Initialize +__STATIC_INLINE void evr_initialize (void) { + + (void)EventRecorderInitialize(OS_EVR_LEVEL, (uint32_t)OS_EVR_START); + + (void)EventRecorderEnable(OS_EVR_MEMORY_LEVEL, EvtRtxMemoryNo, EvtRtxMemoryNo); + (void)EventRecorderEnable(OS_EVR_KERNEL_LEVEL, EvtRtxKernelNo, EvtRtxKernelNo); + (void)EventRecorderEnable(OS_EVR_THREAD_LEVEL, EvtRtxThreadNo, EvtRtxThreadNo); + (void)EventRecorderEnable(OS_EVR_WAIT_LEVEL, EvtRtxWaitNo, EvtRtxWaitNo); + (void)EventRecorderEnable(OS_EVR_THFLAGS_LEVEL, EvtRtxThreadFlagsNo, EvtRtxThreadFlagsNo); + (void)EventRecorderEnable(OS_EVR_EVFLAGS_LEVEL, EvtRtxEventFlagsNo, EvtRtxEventFlagsNo); + (void)EventRecorderEnable(OS_EVR_TIMER_LEVEL, EvtRtxTimerNo, EvtRtxTimerNo); + (void)EventRecorderEnable(OS_EVR_MUTEX_LEVEL, EvtRtxMutexNo, EvtRtxMutexNo); + (void)EventRecorderEnable(OS_EVR_SEMAPHORE_LEVEL, EvtRtxSemaphoreNo, EvtRtxSemaphoreNo); + (void)EventRecorderEnable(OS_EVR_MEMPOOL_LEVEL, EvtRtxMemoryPoolNo, EvtRtxMemoryPoolNo); + (void)EventRecorderEnable(OS_EVR_MSGQUEUE_LEVEL, EvtRtxMessageQueueNo, EvtRtxMessageQueueNo); +} + +#else +#warning "Event Recorder cannot be initialized (Event Recorder component is not selected)!" +#define evr_initialize() +#endif + +#endif // (OS_EVR_INIT != 0) + + +// OS Configuration +// ================ + + +const osRtxConfig_t osRtxConfig \ +__USED \ +__attribute__((section(".rodata"))) = +{ + //lint -e{835} "Zero argument to operator" + 0U // Flags +#if (OS_PRIVILEGE_MODE != 0) + | osRtxConfigPrivilegedMode +#endif +#if (OS_STACK_CHECK != 0) + | osRtxConfigStackCheck +#endif +#if (OS_STACK_WATERMARK != 0) + | osRtxConfigStackWatermark +#endif + , + (uint32_t)OS_TICK_FREQ, +#if (OS_ROBIN_ENABLE != 0) + (uint32_t)OS_ROBIN_TIMEOUT, +#else + 0U, +#endif + { &os_isr_queue[0], (uint16_t)(sizeof(os_isr_queue)/sizeof(void *)), 0U }, + { + // Memory Pools (Variable Block Size) +#if ((OS_THREAD_OBJ_MEM != 0) && (OS_THREAD_USER_STACK_SIZE != 0)) + &os_thread_stack[0], sizeof(os_thread_stack), +#else + NULL, 0U, +#endif +#if ((OS_MEMPOOL_OBJ_MEM != 0) && (OS_MEMPOOL_DATA_SIZE != 0)) + &os_mp_data[0], sizeof(os_mp_data), +#else + NULL, 0U, +#endif +#if ((OS_MSGQUEUE_OBJ_MEM != 0) && (OS_MSGQUEUE_DATA_SIZE != 0)) + &os_mq_data[0], sizeof(os_mq_data), +#else + NULL, 0U, +#endif +#if (OS_DYNAMIC_MEM_SIZE != 0) + &os_mem[0], (uint32_t)OS_DYNAMIC_MEM_SIZE, +#else + NULL, 0U +#endif + }, + { + // Memory Pools (Fixed Block Size) +#if (OS_THREAD_OBJ_MEM != 0) +#if (OS_THREAD_DEF_STACK_NUM != 0) + &os_mpi_def_stack, +#else + NULL, +#endif + &os_mpi_thread, +#else + NULL, + NULL, +#endif +#if (OS_TIMER_OBJ_MEM != 0) + &os_mpi_timer, +#else + NULL, +#endif +#if (OS_EVFLAGS_OBJ_MEM != 0) + &os_mpi_ef, +#else + NULL, +#endif +#if (OS_MUTEX_OBJ_MEM != 0) + &os_mpi_mutex, +#else + NULL, +#endif +#if (OS_SEMAPHORE_OBJ_MEM != 0) + &os_mpi_semaphore, +#else + NULL, +#endif +#if (OS_MEMPOOL_OBJ_MEM != 0) + &os_mpi_mp, +#else + NULL, +#endif +#if (OS_MSGQUEUE_OBJ_MEM != 0) + &os_mpi_mq, +#else + NULL, +#endif + }, + (uint32_t)OS_STACK_SIZE, + &os_idle_thread_attr, +#if ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0)) + &os_timer_thread_attr, + &os_timer_mq_attr, + (uint32_t)OS_TIMER_CB_QUEUE +#else + NULL, + NULL, + 0U +#endif +}; + + +// Non weak reference to library irq module +//lint -esym(526,irqRtxLib) "Defined by Exception handlers" +//lint -esym(714,irqRtxLibRef) "Non weak reference" +//lint -esym(765,irqRtxLibRef) "Global scope" +extern uint8_t irqRtxLib; +extern const uint8_t *irqRtxLibRef; + const uint8_t *irqRtxLibRef = &irqRtxLib; + +// Default User SVC Table +//lint -esym(714,osRtxUserSVC) "Referenced by Exception handlers" +//lint -esym(765,osRtxUserSVC) "Global scope" +//lint -e{9067} "extern array declared without size" +extern void * const osRtxUserSVC[]; +__WEAK void * const osRtxUserSVC[1] = { (void *)0 }; + + +// OS Sections +// =========== + +#if defined(__CC_ARM) || \ + (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) +static uint32_t __os_thread_cb_start__ __attribute__((weakref(".bss.os.thread.cb$$Base"))); //lint -esym(728,__os_thread_cb_start__) +static uint32_t __os_thread_cb_end__ __attribute__((weakref(".bss.os.thread.cb$$Limit"))); //lint -esym(728,__os_thread_cb_end__) +static uint32_t __os_timer_cb_start__ __attribute__((weakref(".bss.os.timer.cb$$Base"))); //lint -esym(728,__os_timer_cb_start__) +static uint32_t __os_timer_cb_end__ __attribute__((weakref(".bss.os.timer.cb$$Limit"))); //lint -esym(728,__os_timer_cb_end__) +static uint32_t __os_evflags_cb_start__ __attribute__((weakref(".bss.os.evflags.cb$$Base"))); //lint -esym(728,__os_evflags_cb_start__) +static uint32_t __os_evflags_cb_end__ __attribute__((weakref(".bss.os.evflags.cb$$Limit"))); //lint -esym(728,__os_evflags_cb_end__) +static uint32_t __os_mutex_cb_start__ __attribute__((weakref(".bss.os.mutex.cb$$Base"))); //lint -esym(728,__os_mutex_cb_start__) +static uint32_t __os_mutex_cb_end__ __attribute__((weakref(".bss.os.mutex.cb$$Limit"))); //lint -esym(728,__os_mutex_cb_end__) +static uint32_t __os_semaphore_cb_start__ __attribute__((weakref(".bss.os.semaphore.cb$$Base"))); //lint -esym(728,__os_semaphore_cb_start__) +static uint32_t __os_semaphore_cb_end__ __attribute__((weakref(".bss.os.semaphore.cb$$Limit"))); //lint -esym(728,__os_semaphore_cb_end__) +static uint32_t __os_mempool_cb_start__ __attribute__((weakref(".bss.os.mempool.cb$$Base"))); //lint -esym(728,__os_mempool_cb_start__) +static uint32_t __os_mempool_cb_end__ __attribute__((weakref(".bss.os.mempool.cb$$Limit"))); //lint -esym(728,__os_mempool_cb_end__) +static uint32_t __os_msgqueue_cb_start__ __attribute__((weakref(".bss.os.msgqueue.cb$$Base"))); //lint -esym(728,__os_msgqueue_cb_start__) +static uint32_t __os_msgqueue_cb_end__ __attribute__((weakref(".bss.os.msgqueue.cb$$Limit"))); //lint -esym(728,__os_msgqueue_cb_end__) +#else +extern uint32_t __os_thread_cb_start__ __attribute__((weak)); +extern uint32_t __os_thread_cb_end__ __attribute__((weak)); +extern uint32_t __os_timer_cb_start__ __attribute__((weak)); +extern uint32_t __os_timer_cb_end__ __attribute__((weak)); +extern uint32_t __os_evflags_cb_start__ __attribute__((weak)); +extern uint32_t __os_evflags_cb_end__ __attribute__((weak)); +extern uint32_t __os_mutex_cb_start__ __attribute__((weak)); +extern uint32_t __os_mutex_cb_end__ __attribute__((weak)); +extern uint32_t __os_semaphore_cb_start__ __attribute__((weak)); +extern uint32_t __os_semaphore_cb_end__ __attribute__((weak)); +extern uint32_t __os_mempool_cb_start__ __attribute__((weak)); +extern uint32_t __os_mempool_cb_end__ __attribute__((weak)); +extern uint32_t __os_msgqueue_cb_start__ __attribute__((weak)); +extern uint32_t __os_msgqueue_cb_end__ __attribute__((weak)); +#endif + +//lint -e{9067} "extern array declared without size" +extern const uint32_t * const os_cb_sections[]; + +//lint -esym(714,os_cb_sections) "Referenced by debugger" +//lint -esym(765,os_cb_sections) "Global scope" +const uint32_t * const os_cb_sections[] \ +__USED \ +__attribute__((section(".rodata"))) = +{ + &__os_thread_cb_start__, + &__os_thread_cb_end__, + &__os_timer_cb_start__, + &__os_timer_cb_end__, + &__os_evflags_cb_start__, + &__os_evflags_cb_end__, + &__os_mutex_cb_start__, + &__os_mutex_cb_end__, + &__os_semaphore_cb_start__, + &__os_semaphore_cb_end__, + &__os_mempool_cb_start__, + &__os_mempool_cb_end__, + &__os_msgqueue_cb_start__, + &__os_msgqueue_cb_end__ +}; + + +// OS Initialization +// ================= + +#if defined(__CC_ARM) || \ + (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + +#ifndef __MICROLIB +//lint -esym(714,_platform_post_stackheap_init) "Referenced by C library" +//lint -esym(765,_platform_post_stackheap_init) "Global scope" +extern void _platform_post_stackheap_init (void); +__WEAK void _platform_post_stackheap_init (void) { + (void)osKernelInitialize(); +} +#endif + +#elif defined(__GNUC__) +osThreadAttr_t os_thread_attr_main = { + "main", + osThreadDetached, + NULL, + 0, + NULL, + 0, + osPriorityNormal, + 0, + 0 +}; + +#ifndef OS_SCHEDULERSTKSIZE +#define OS_SCHEDULERSTKSIZE 512 +#endif + +extern uint32_t __StackTop[]; +#define INITIAL_SP ((uint32_t)__StackTop) + +extern uint32_t __StackLimit[]; +#define MAIN_STACK_BUF (__StackLimit) + +#define ROUND_UP(x, align) (((uint32_t)(x) + (align - 1)) & ~(align - 1)) +#define ROUND_DOWN(x, align) ((uint32_t)(x) & ~(align - 1)) + +void set_main_stack(void) { + // That is the bottom of the main stack block: no collision detection + os_thread_attr_main.stack_mem = (uint32_t *)ROUND_UP(MAIN_STACK_BUF, 8); + + // Leave OS_SCHEDULERSTKSIZE words for the scheduler and interrupts + os_thread_attr_main.stack_size = ROUND_DOWN((INITIAL_SP - (unsigned int)ROUND_UP(MAIN_STACK_BUF, 8)) - (OS_SCHEDULERSTKSIZE * 4), 8); +} + +extern void software_init_hook (void); +__WEAK void software_init_hook (void) { + __asm ( + ".syntax unified\n" + ".thumb\n" + "movs r0,#0\n" + "movs r1,#0\n" + "mov r4,r0\n" + "mov r5,r1\n" + "bl SystemCoreClockUpdate\n" + "bl osKernelInitialize\n" + "ldr r0,= __libc_fini_array\n" + "bl atexit\n" + "bl __libc_init_array\n" + "mov r0,r4\n" + "mov r1,r5\n" + "bl set_main_stack\n" + "ldr r0,=main\n" + "movs r1,#0\n" + "ldr r2,=os_thread_attr_main\n" + "bl osThreadNew\n" + "bl osKernelStart\n" + "bl exit\n" + ); +} +#endif + +// OS Hooks +// ======== + +// RTOS Kernel Pre-Initialization Hook +#if (defined(OS_EVR_INIT) && (OS_EVR_INIT != 0)) +void osRtxKernelPreInit (void); +void osRtxKernelPreInit (void) { + if (osKernelGetState() == osKernelInactive) { + evr_initialize(); + } +} +#endif + + +// C/C++ Standard Library Multithreading Interface +// =============================================== + +#if ( !defined(RTX_NO_MULTITHREAD_CLIB) && \ + ( defined(__CC_ARM) || \ + (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \ + !defined(__MICROLIB)) + +#define LIBSPACE_SIZE 96 + +//lint -esym(714,__user_perthread_libspace,_mutex_*) "Referenced by C library" +//lint -esym(765,__user_perthread_libspace,_mutex_*) "Global scope" +//lint -esym(9003, os_libspace*) "variables 'os_libspace*' defined at module scope" + +// Memory for libspace +static uint32_t os_libspace[OS_THREAD_LIBSPACE_NUM+1][LIBSPACE_SIZE/4] \ +__attribute__((section(".bss.os.libspace"))); + +// Thread IDs for libspace +static osThreadId_t os_libspace_id[OS_THREAD_LIBSPACE_NUM] \ +__attribute__((section(".bss.os.libspace"))); + +// Check if Kernel has been started +static uint32_t os_kernel_is_active (void) { + static uint8_t os_kernel_active = 0U; + + if (os_kernel_active == 0U) { + if (osKernelGetState() > osKernelReady) { + os_kernel_active = 1U; + } + } + return (uint32_t)os_kernel_active; +} + +// Provide libspace for current thread +void *__user_perthread_libspace (void); +void *__user_perthread_libspace (void) { + osThreadId_t id; + uint32_t n; + + if (os_kernel_is_active() != 0U) { + id = osThreadGetId(); + for (n = 0U; n < (uint32_t)OS_THREAD_LIBSPACE_NUM; n++) { + if (os_libspace_id[n] == NULL) { + os_libspace_id[n] = id; + } + if (os_libspace_id[n] == id) { + break; + } + } + if (n == (uint32_t)OS_THREAD_LIBSPACE_NUM) { + (void)osRtxErrorNotify(osRtxErrorClibSpace, id); + } + } else { + n = OS_THREAD_LIBSPACE_NUM; + } + + //lint -e{9087} "cast between pointers to different object types" + return (void *)&os_libspace[n][0]; +} + +// Mutex identifier +typedef void *mutex; + +//lint -save "Function prototypes defined in C library" +//lint -e970 "Use of 'int' outside of a typedef" +//lint -e818 "Pointer 'm' could be declared as pointing to const" + +// Initialize mutex +__USED +int _mutex_initialize(mutex *m); +int _mutex_initialize(mutex *m) { + int result; + + *m = osMutexNew(NULL); + if (*m != NULL) { + result = 1; + } else { + result = 0; + (void)osRtxErrorNotify(osRtxErrorClibMutex, m); + } + return result; +} + +// Acquire mutex +__USED +void _mutex_acquire(mutex *m); +void _mutex_acquire(mutex *m) { + if (os_kernel_is_active() != 0U) { + (void)osMutexAcquire(*m, osWaitForever); + } +} + +// Release mutex +__USED +void _mutex_release(mutex *m); +void _mutex_release(mutex *m) { + if (os_kernel_is_active() != 0U) { + (void)osMutexRelease(*m); + } +} + +// Free mutex +__USED +void _mutex_free(mutex *m); +void _mutex_free(mutex *m) { + (void)osMutexDelete(*m); +} + +//lint -restore + +#endif diff --git a/rtos/rtx5/rtx_lib.h b/rtos/rtx5/rtx_lib.h new file mode 100644 index 0000000..6a671ba --- /dev/null +++ b/rtos/rtx5/rtx_lib.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: RTX Library definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_LIB_H_ +#define RTX_LIB_H_ + +#include +#include "rtx_core_c.h" // Cortex core definitions +#if ((defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) || \ + (defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0))) +#include "tz_context.h" // TrustZone Context API +#endif +#include "os_tick.h" // CMSIS OS Tick API +#include "cmsis_os2.h" // CMSIS RTOS API +#include "rtx_config.h" // RTX Configuration +#include "rtx_os.h" // RTX OS definitions +#include "rtx_evr.h" // RTX Event Recorder definitions + + +// ==== Library defines ==== + +#define os_thread_t osRtxThread_t +#define os_timer_t osRtxTimer_t +#define os_timer_finfo_t osRtxTimerFinfo_t +#define os_event_flags_t osRtxEventFlags_t +#define os_mutex_t osRtxMutex_t +#define os_semaphore_t osRtxSemaphore_t +#define os_mp_info_t osRtxMpInfo_t +#define os_memory_pool_t osRtxMemoryPool_t +#define os_message_t osRtxMessage_t +#define os_message_queue_t osRtxMessageQueue_t +#define os_object_t osRtxObject_t + +// ==== Inline functions ==== + +// Thread ID +__STATIC_INLINE os_thread_t *osRtxThreadId (osThreadId_t thread_id) { + //lint -e{9079} -e{9087} "cast from pointer to void to pointer to object type" [MISRA Note 2] + return ((os_thread_t *)thread_id); +} +// Timer ID +__STATIC_INLINE os_timer_t *osRtxTimerId (osTimerId_t timer_id) { + //lint -e{9079} -e{9087} "cast from pointer to void to pointer to object type" [MISRA Note 2] + return ((os_timer_t *)timer_id); +} +// Event Flags ID +__STATIC_INLINE os_event_flags_t *osRtxEventFlagsId (osEventFlagsId_t ef_id) { + //lint -e{9079} -e{9087} "cast from pointer to void to pointer to object type" [MISRA Note 2] + return ((os_event_flags_t *)ef_id); +} +// Mutex ID +__STATIC_INLINE os_mutex_t *osRtxMutexId (osMutexId_t mutex_id) { + //lint -e{9079} -e{9087} "cast from pointer to void to pointer to object type" [MISRA Note 2] + return ((os_mutex_t *)mutex_id); +} +// Semaphore ID +__STATIC_INLINE os_semaphore_t *osRtxSemaphoreId (osSemaphoreId_t semaphore_id) { + //lint -e{9079} -e{9087} "cast from pointer to void to pointer to object type" [MISRA Note 2] + return ((os_semaphore_t *)semaphore_id); +} +// Memory Pool ID +__STATIC_INLINE os_memory_pool_t *osRtxMemoryPoolId (osMemoryPoolId_t mp_id) { + //lint -e{9079} -e{9087} "cast from pointer to void to pointer to object type" [MISRA Note 2] + return ((os_memory_pool_t *)mp_id); +} +// Message Queue ID +__STATIC_INLINE os_message_queue_t *osRtxMessageQueueId (osMessageQueueId_t mq_id) { + //lint -e{9079} -e{9087} "cast from pointer to void to pointer to object type" [MISRA Note 2] + return ((os_message_queue_t *)mq_id); +} + +// Generic Object +__STATIC_INLINE os_object_t *osRtxObject (void *object) { + //lint -e{9079} -e{9087} "cast from pointer to void to pointer to object type" [MISRA Note 3] + return ((os_object_t *)object); +} + +// Thread Object +__STATIC_INLINE os_thread_t *osRtxThreadObject (os_object_t *object) { + //lint -e{740} -e{826} -e{9087} "cast from pointer to generic object to specific object" [MISRA Note 4] + return ((os_thread_t *)object); +} +// Timer Object +__STATIC_INLINE os_timer_t *osRtxTimerObject (os_object_t *object) { + //lint -e{740} -e{826} -e{9087} "cast from pointer to generic object to specific object" [MISRA Note 4] + return ((os_timer_t *)object); +} +// Event Flags Object +__STATIC_INLINE os_event_flags_t *osRtxEventFlagsObject (os_object_t *object) { + //lint -e{740} -e{826} -e{9087} "cast from pointer to generic object to specific object" [MISRA Note 4] + return ((os_event_flags_t *)object); +} +// Mutex Object +__STATIC_INLINE os_mutex_t *osRtxMutexObject (os_object_t *object) { + //lint -e{740} -e{826} -e{9087} "cast from pointer to generic object to specific object" [MISRA Note 4] + return ((os_mutex_t *)object); +} +// Semaphore Object +__STATIC_INLINE os_semaphore_t *osRtxSemaphoreObject (os_object_t *object) { + //lint -e{740} -e{826} -e{9087} "cast from pointer to generic object to specific object" [MISRA Note 4] + return ((os_semaphore_t *)object); +} +// Memory Pool Object +__STATIC_INLINE os_memory_pool_t *osRtxMemoryPoolObject (os_object_t *object) { + //lint -e{740} -e{826} -e{9087} "cast from pointer to generic object to specific object" [MISRA Note 4] + return ((os_memory_pool_t *)object); +} +// Message Queue Object +__STATIC_INLINE os_message_queue_t *osRtxMessageQueueObject (os_object_t *object) { + //lint -e{740} -e{826} -e{9087} "cast from pointer to generic object to specific object" [MISRA Note 4] + return ((os_message_queue_t *)object); +} +// Message Object +__STATIC_INLINE os_message_t *osRtxMessageObject (os_object_t *object) { + //lint -e{740} -e{826} -e{9087} "cast from pointer to generic object to specific object" [MISRA Note 4] + return ((os_message_t *)object); +} + +// Kernel State +__STATIC_INLINE osKernelState_t osRtxKernelState (void) { + //lint -e{9030} -e{9034} "cast to enum" + return ((osKernelState_t)(osRtxInfo.kernel.state)); +} + +// Thread State +__STATIC_INLINE osThreadState_t osRtxThreadState (const os_thread_t *thread) { + uint8_t state = thread->state & osRtxThreadStateMask; + //lint -e{9030} -e{9034} "cast to enum" + return ((osThreadState_t)state); +} + +// Thread Priority +__STATIC_INLINE osPriority_t osRtxThreadPriority (const os_thread_t *thread) { + //lint -e{9030} -e{9034} "cast to enum" + return ((osPriority_t)thread->priority); +} + +// Kernel Get State +__STATIC_INLINE uint8_t osRtxKernelGetState (void) { + return osRtxInfo.kernel.state; +} + +// Thread Get/Set Running +__STATIC_INLINE os_thread_t *osRtxThreadGetRunning (void) { + return osRtxInfo.thread.run.curr; +} +__STATIC_INLINE void osRtxThreadSetRunning (os_thread_t *thread) { + osRtxInfo.thread.run.curr = thread; +} + + +// ==== Library functions ==== + +// Kernel Library functions +extern void osRtxKernelPreInit (void); + +// Thread Library functions +extern void osRtxThreadListPut (os_object_t *object, os_thread_t *thread); +extern os_thread_t *osRtxThreadListGet (os_object_t *object); +extern void osRtxThreadListSort (os_thread_t *thread); +extern void osRtxThreadListRemove (os_thread_t *thread); +extern void osRtxThreadReadyPut (os_thread_t *thread); +extern void osRtxThreadDelayTick (void); +extern uint32_t *osRtxThreadRegPtr (const os_thread_t *thread); +extern void osRtxThreadSwitch (os_thread_t *thread); +#if __RTX_CPU_STATISTICS__ +uint32_t rtx_get_hwticks(void); +#endif +extern void osRtxThreadDispatch (os_thread_t *thread); +extern void osRtxThreadWaitExit (os_thread_t *thread, uint32_t ret_val, bool_t dispatch); +extern bool_t osRtxThreadWaitEnter (uint8_t state, uint32_t timeout); +extern void osRtxThreadStackCheck (void); +extern bool_t osRtxThreadStartup (void); + +// Timer Library functions +extern void osRtxTimerThread (void *argument); + +// Mutex Library functions +extern void osRtxMutexOwnerRelease (os_mutex_t *mutex_list); + +// Memory Heap Library functions +extern uint32_t osRtxMemoryInit (void *mem, uint32_t size); +extern void *osRtxMemoryAlloc(void *mem, uint32_t size, uint32_t type); +extern uint32_t osRtxMemoryFree (void *mem, void *block); + +// Memory Pool Library functions +extern uint32_t osRtxMemoryPoolInit (os_mp_info_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem); +extern void *osRtxMemoryPoolAlloc (os_mp_info_t *mp_info); +extern osStatus_t osRtxMemoryPoolFree (os_mp_info_t *mp_info, void *block); + +// System Library functions +extern void osRtxTick_Handler (void); +extern void osRtxPendSV_Handler (void); +extern void osRtxPostProcess (os_object_t *object); + + +#endif // RTX_LIB_H_ diff --git a/rtos/rtx5/rtx_memory.c b/rtos/rtx5/rtx_memory.c new file mode 100644 index 0000000..b22bfda --- /dev/null +++ b/rtos/rtx5/rtx_memory.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Memory functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// Memory Pool Header structure +typedef struct { + uint32_t size; // Memory Pool size + uint32_t used; // Used Memory +} mem_head_t; + +// Memory Block Header structure +typedef struct mem_block_s { + struct mem_block_s *next; // Next Memory Block in list + uint32_t info; // Block Info or max used Memory (in last block) +} mem_block_t; + +// Memory Block Info: Length = <31:2>:'00', Type = <1:0> +#define MB_INFO_LEN_MASK 0xFFFFFFFCU // Length mask +#define MB_INFO_TYPE_MASK 0x00000003U // Type mask + +// Memory Head Pointer +__STATIC_INLINE mem_head_t *MemHeadPtr (void *mem) { + //lint -e{9079} -e{9087} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + return ((mem_head_t *)mem); +} + +// Memory Block Pointer +__STATIC_INLINE mem_block_t *MemBlockPtr (void *mem, uint32_t offset) { + uint32_t addr; + mem_block_t *ptr; + + //lint --e{923} --e{9078} "cast between pointer and unsigned int" [MISRA Note 8] + addr = (uint32_t)mem + offset; + ptr = (mem_block_t *)addr; + + return ptr; +} + + +// ==== Library functions ==== + +/// Initialize Memory Pool with variable block size. +/// \param[in] mem pointer to memory pool. +/// \param[in] size size of a memory pool in bytes. +/// \return 1 - success, 0 - failure. +__WEAK uint32_t osRtxMemoryInit (void *mem, uint32_t size) { + mem_head_t *head; + mem_block_t *ptr; + + // Check parameters + //lint -e{923} "cast from pointer to unsigned int" [MISRA Note 7] + if ((mem == NULL) || (((uint32_t)mem & 7U) != 0U) || ((size & 7U) != 0U) || + (size < (sizeof(mem_head_t) + (2U*sizeof(mem_block_t))))) { + EvrRtxMemoryInit(mem, size, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + // Initialize memory pool header + head = MemHeadPtr(mem); + head->size = size; + head->used = sizeof(mem_head_t) + sizeof(mem_block_t); + + // Initialize first and last block header + ptr = MemBlockPtr(mem, sizeof(mem_head_t)); + ptr->next = MemBlockPtr(mem, size - sizeof(mem_block_t)); + ptr->next->next = NULL; + ptr->next->info = sizeof(mem_head_t) + sizeof(mem_block_t); + ptr->info = 0U; + + EvrRtxMemoryInit(mem, size, 1U); + + return 1U; +} + +/// Allocate a memory block from a Memory Pool. +/// \param[in] mem pointer to memory pool. +/// \param[in] size size of a memory block in bytes. +/// \param[in] type memory block type: 0 - generic, 1 - control block +/// \return allocated memory block or NULL in case of no memory is available. +__WEAK void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type) { + mem_block_t *ptr; + mem_block_t *p, *p_new; + uint32_t block_size; + uint32_t hole_size; + + // Check parameters + if ((mem == NULL) || (size == 0U) || ((type & ~MB_INFO_TYPE_MASK) != 0U)) { + EvrRtxMemoryAlloc(mem, size, type, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + // Add block header to size + block_size = size + sizeof(mem_block_t); + // Make sure that block is 8-byte aligned + block_size = (block_size + 7U) & ~((uint32_t)7U); + + // Search for hole big enough + p = MemBlockPtr(mem, sizeof(mem_head_t)); + for (;;) { + //lint -e{923} -e{9078} "cast from pointer to unsigned int" + hole_size = (uint32_t)p->next - (uint32_t)p; + hole_size -= p->info & MB_INFO_LEN_MASK; + if (hole_size >= block_size) { + // Hole found + break; + } + p = p->next; + if (p->next == NULL) { + // Failed (end of list) + EvrRtxMemoryAlloc(mem, size, type, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + + // Update used memory + (MemHeadPtr(mem))->used += block_size; + + // Update max used memory + p_new = MemBlockPtr(mem, (MemHeadPtr(mem))->size - sizeof(mem_block_t)); + if (p_new->info < (MemHeadPtr(mem))->used) { + p_new->info = (MemHeadPtr(mem))->used; + } + + // Allocate block + if (p->info == 0U) { + // No block allocated, set info of first element + p->info = block_size | type; + ptr = MemBlockPtr(p, sizeof(mem_block_t)); + } else { + // Insert new element into the list + p_new = MemBlockPtr(p, p->info & MB_INFO_LEN_MASK); + p_new->next = p->next; + p_new->info = block_size | type; + p->next = p_new; + ptr = MemBlockPtr(p_new, sizeof(mem_block_t)); + } + + EvrRtxMemoryAlloc(mem, size, type, ptr); + + return ptr; +} + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] mem pointer to memory pool. +/// \param[in] block memory block to be returned to the memory pool. +/// \return 1 - success, 0 - failure. +__WEAK uint32_t osRtxMemoryFree (void *mem, void *block) { + const mem_block_t *ptr; + mem_block_t *p, *p_prev; + + // Check parameters + if ((mem == NULL) || (block == NULL)) { + EvrRtxMemoryFree(mem, block, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + // Memory block header + ptr = MemBlockPtr(block, 0U); + ptr--; + + // Search for block header + p_prev = NULL; + p = MemBlockPtr(mem, sizeof(mem_head_t)); + while (p != ptr) { + p_prev = p; + p = p->next; + if (p == NULL) { + // Not found + EvrRtxMemoryFree(mem, block, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + } + + // Update used memory + (MemHeadPtr(mem))->used -= p->info & MB_INFO_LEN_MASK; + + // Free block + if (p_prev == NULL) { + // Release first block, only set info to 0 + p->info = 0U; + } else { + // Discard block from chained list + p_prev->next = p->next; + } + + EvrRtxMemoryFree(mem, block, 1U); + + return 1U; +} diff --git a/rtos/rtx5/rtx_mempool.c b/rtos/rtx5/rtx_mempool.c new file mode 100644 index 0000000..f7a1872 --- /dev/null +++ b/rtos/rtx5/rtx_mempool.c @@ -0,0 +1,705 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Memory Pool functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// OS Runtime Object Memory Usage +#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))) +osRtxObjectMemUsage_t osRtxMemoryPoolMemUsage \ +__attribute__((section(".data.os.mempool.obj"))) = +{ 0U, 0U, 0U }; +#endif + + +// ==== Library functions ==== + +/// Initialize Memory Pool. +/// \param[in] mp_info memory pool info. +/// \param[in] block_count maximum number of memory blocks in memory pool. +/// \param[in] block_size size of a memory block in bytes. +/// \param[in] block_mem pointer to memory for block storage. +/// \return 1 - success, 0 - failure. +uint32_t osRtxMemoryPoolInit (os_mp_info_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem) { + //lint --e{9079} --e{9087} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + void *mem; + void *block; + + // Check parameters + if ((mp_info == NULL) || (block_count == 0U) || (block_size == 0U) || (block_mem == NULL)) { + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + // Initialize information structure + mp_info->max_blocks = block_count; + mp_info->used_blocks = 0U; + mp_info->block_size = block_size; + mp_info->block_base = block_mem; + mp_info->block_free = block_mem; + mp_info->block_lim = &(((uint8_t *)block_mem)[block_count * block_size]); + + EvrRtxMemoryBlockInit(mp_info, block_count, block_size, block_mem); + + // Link all free blocks + mem = block_mem; + while (--block_count != 0U) { + block = &((uint8_t *)mem)[block_size]; + *((void **)mem) = block; + mem = block; + } + *((void **)mem) = NULL; + + return 1U; +} + +/// Allocate a memory block from a Memory Pool. +/// \param[in] mp_info memory pool info. +/// \return address of the allocated memory block or NULL in case of no memory is available. +void *osRtxMemoryPoolAlloc (os_mp_info_t *mp_info) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#endif + void *block; + + if (mp_info == NULL) { + EvrRtxMemoryBlockAlloc(NULL, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + block = mp_info->block_free; + if (block != NULL) { + //lint --e{9079} --e{9087} "conversion from pointer to void to pointer to other type" + mp_info->block_free = *((void **)block); + mp_info->used_blocks++; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + block = atomic_link_get(&mp_info->block_free); + if (block != NULL) { + (void)atomic_inc32(&mp_info->used_blocks); + } +#endif + + EvrRtxMemoryBlockAlloc(mp_info, block); + + return block; +} + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] mp_info memory pool info. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus_t osRtxMemoryPoolFree (os_mp_info_t *mp_info, void *block) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#endif + + //lint -e{946} "Relational operator applied to pointers" + if ((mp_info == NULL) || (block < mp_info->block_base) || (block >= mp_info->block_lim)) { + EvrRtxMemoryBlockFree(mp_info, block, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + //lint --e{9079} --e{9087} "conversion from pointer to void to pointer to other type" + *((void **)block) = mp_info->block_free; + mp_info->block_free = block; + mp_info->used_blocks--; + + if (primask == 0U) { + __enable_irq(); + } +#else + atomic_link_put(&mp_info->block_free, block); + (void)atomic_dec32(&mp_info->used_blocks); +#endif + + EvrRtxMemoryBlockFree(mp_info, block, (int32_t)osOK); + + return osOK; +} + + +// ==== Post ISR processing ==== + +/// Memory Pool post ISR processing. +/// \param[in] mp memory pool object. +static void osRtxMemoryPoolPostProcess (os_memory_pool_t *mp) { + void *block; + os_thread_t *thread; + + // Check if Thread is waiting to allocate memory + if (mp->thread_list != NULL) { + // Allocate memory + block = osRtxMemoryPoolAlloc(&mp->mp_info); + if (block != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(mp)); + //lint -e{923} "cast from pointer to unsigned int" + osRtxThreadWaitExit(thread, (uint32_t)block, FALSE); + EvrRtxMemoryPoolAllocated(mp, block); + } + } +} + + +// ==== Service Calls ==== + +/// Create and Initialize a Memory Pool object. +/// \note API identical to osMemoryPoolNew +static osMemoryPoolId_t svcRtxMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) { + os_memory_pool_t *mp; + void *mp_mem; + uint32_t mp_size; + uint32_t b_count; + uint32_t b_size; + uint32_t size; + uint8_t flags; + const char *name; + + // Check parameters + if ((block_count == 0U) || (block_size == 0U)) { + EvrRtxMemoryPoolError(NULL, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + b_count = block_count; + b_size = (block_size + 3U) & ~3UL; + if ((__CLZ(b_count) + __CLZ(b_size)) < 32U) { + EvrRtxMemoryPoolError(NULL, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + size = b_count * b_size; + + // Process attributes + if (attr != NULL) { + name = attr->name; + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + mp = attr->cb_mem; + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + mp_mem = attr->mp_mem; + mp_size = attr->mp_size; + if (mp != NULL) { + //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7] + if ((((uint32_t)mp & 3U) != 0U) || (attr->cb_size < sizeof(os_memory_pool_t))) { + EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + if (mp_mem != NULL) { + //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7] + if ((((uint32_t)mp_mem & 3U) != 0U) || (mp_size < size)) { + EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidDataMemory); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } else { + if (mp_size != 0U) { + EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidDataMemory); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + } else { + name = NULL; + mp = NULL; + mp_mem = NULL; + } + + // Allocate object memory if not provided + if (mp == NULL) { + if (osRtxInfo.mpi.memory_pool != NULL) { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + mp = osRtxMemoryPoolAlloc(osRtxInfo.mpi.memory_pool); + } else { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + mp = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_memory_pool_t), 1U); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + if (mp != NULL) { + uint32_t used; + osRtxMemoryPoolMemUsage.cnt_alloc++; + used = osRtxMemoryPoolMemUsage.cnt_alloc - osRtxMemoryPoolMemUsage.cnt_free; + if (osRtxMemoryPoolMemUsage.max_used < used) { + osRtxMemoryPoolMemUsage.max_used = used; + } + } +#endif + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + // Allocate data memory if not provided + if ((mp != NULL) && (mp_mem == NULL)) { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + mp_mem = osRtxMemoryAlloc(osRtxInfo.mem.mp_data, size, 0U); + if (mp_mem == NULL) { + if ((flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.memory_pool != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, mp); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxMemoryPoolMemUsage.cnt_free++; +#endif + } + mp = NULL; + } else { + memset(mp_mem, 0, size); + } + flags |= osRtxFlagSystemMemory; + } + + if (mp != NULL) { + // Initialize control block + mp->id = osRtxIdMemoryPool; + mp->flags = flags; + mp->name = name; + mp->thread_list = NULL; + (void)osRtxMemoryPoolInit(&mp->mp_info, b_count, b_size, mp_mem); + + // Register post ISR processing function + osRtxInfo.post_process.memory_pool = osRtxMemoryPoolPostProcess; + + EvrRtxMemoryPoolCreated(mp, mp->name); + } else { + EvrRtxMemoryPoolError(NULL, (int32_t)osErrorNoMemory); + } + + return mp; +} + +/// Get name of a Memory Pool object. +/// \note API identical to osMemoryPoolGetName +static const char *svcRtxMemoryPoolGetName (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id); + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolGetName(mp, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + EvrRtxMemoryPoolGetName(mp, mp->name); + + return mp->name; +} + +/// Allocate a memory block from a Memory Pool. +/// \note API identical to osMemoryPoolAlloc +static void *svcRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) { + os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id); + void *block; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + // Allocate memory + block = osRtxMemoryPoolAlloc(&mp->mp_info); + if (block != NULL) { + EvrRtxMemoryPoolAllocated(mp, block); + } else { + // No memory available + if (timeout != 0U) { + EvrRtxMemoryPoolAllocPending(mp, timeout); + // Suspend current Thread + if (osRtxThreadWaitEnter(osRtxThreadWaitingMemoryPool, timeout)) { + osRtxThreadListPut(osRtxObject(mp), osRtxThreadGetRunning()); + } else { + EvrRtxMemoryPoolAllocTimeout(mp); + } + } else { + EvrRtxMemoryPoolAllocFailed(mp); + } + } + + return block; +} + +/// Return an allocated memory block back to a Memory Pool. +/// \note API identical to osMemoryPoolFree +static osStatus_t svcRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) { + os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id); + void *block0; + os_thread_t *thread; + osStatus_t status; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Free memory + status = osRtxMemoryPoolFree(&mp->mp_info, block); + if (status == osOK) { + EvrRtxMemoryPoolDeallocated(mp, block); + // Check if Thread is waiting to allocate memory + if (mp->thread_list != NULL) { + // Allocate memory + block0 = osRtxMemoryPoolAlloc(&mp->mp_info); + if (block0 != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(mp)); + //lint -e{923} "cast from pointer to unsigned int" + osRtxThreadWaitExit(thread, (uint32_t)block0, TRUE); + EvrRtxMemoryPoolAllocated(mp, block0); + } + } + } else { + EvrRtxMemoryPoolFreeFailed(mp, block); + } + + return status; +} + +/// Get maximum number of memory blocks in a Memory Pool. +/// \note API identical to osMemoryPoolGetCapacity +static uint32_t svcRtxMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id); + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolGetCapacity(mp, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxMemoryPoolGetCapacity(mp, mp->mp_info.max_blocks); + + return mp->mp_info.max_blocks; +} + +/// Get memory block size in a Memory Pool. +/// \note API identical to osMemoryPoolGetBlockSize +static uint32_t svcRtxMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id); + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolGetBlockSize(mp, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxMemoryPoolGetBlockSize(mp, mp->mp_info.block_size); + + return mp->mp_info.block_size; +} + +/// Get number of memory blocks used in a Memory Pool. +/// \note API identical to osMemoryPoolGetCount +static uint32_t svcRtxMemoryPoolGetCount (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id); + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolGetCount(mp, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxMemoryPoolGetCount(mp, mp->mp_info.used_blocks); + + return mp->mp_info.used_blocks; +} + +/// Get number of memory blocks available in a Memory Pool. +/// \note API identical to osMemoryPoolGetSpace +static uint32_t svcRtxMemoryPoolGetSpace (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id); + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolGetSpace(mp, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxMemoryPoolGetSpace(mp, mp->mp_info.max_blocks - mp->mp_info.used_blocks); + + return (mp->mp_info.max_blocks - mp->mp_info.used_blocks); +} + +/// Delete a Memory Pool object. +/// \note API identical to osMemoryPoolDelete +static osStatus_t svcRtxMemoryPoolDelete (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id); + os_thread_t *thread; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Unblock waiting threads + if (mp->thread_list != NULL) { + do { + thread = osRtxThreadListGet(osRtxObject(mp)); + osRtxThreadWaitExit(thread, 0U, FALSE); + } while (mp->thread_list != NULL); + osRtxThreadDispatch(NULL); + } + + // Mark object as invalid + mp->id = osRtxIdInvalid; + + // Free data memory + if ((mp->flags & osRtxFlagSystemMemory) != 0U) { + (void)osRtxMemoryFree(osRtxInfo.mem.mp_data, mp->mp_info.block_base); + } + + // Free object memory + if ((mp->flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.memory_pool != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, mp); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxMemoryPoolMemUsage.cnt_free++; +#endif + } + + EvrRtxMemoryPoolDestroyed(mp); + + return osOK; +} + +// Service Calls definitions +//lint ++flb "Library Begin" [MISRA Note 11] +SVC0_3(MemoryPoolNew, osMemoryPoolId_t, uint32_t, uint32_t, const osMemoryPoolAttr_t *) +SVC0_1(MemoryPoolGetName, const char *, osMemoryPoolId_t) +SVC0_2(MemoryPoolAlloc, void *, osMemoryPoolId_t, uint32_t) +SVC0_2(MemoryPoolFree, osStatus_t, osMemoryPoolId_t, void *) +SVC0_1(MemoryPoolGetCapacity, uint32_t, osMemoryPoolId_t) +SVC0_1(MemoryPoolGetBlockSize, uint32_t, osMemoryPoolId_t) +SVC0_1(MemoryPoolGetCount, uint32_t, osMemoryPoolId_t) +SVC0_1(MemoryPoolGetSpace, uint32_t, osMemoryPoolId_t) +SVC0_1(MemoryPoolDelete, osStatus_t, osMemoryPoolId_t) +//lint --flb "Library End" + + +// ==== ISR Calls ==== + +/// Allocate a memory block from a Memory Pool. +/// \note API identical to osMemoryPoolAlloc +__STATIC_INLINE +void *isrRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) { + os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id); + void *block; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool) || (timeout != 0U)) { + EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + // Allocate memory + block = osRtxMemoryPoolAlloc(&mp->mp_info); + if (block == NULL) { + EvrRtxMemoryPoolAllocFailed(mp); + } else { + EvrRtxMemoryPoolAllocated(mp, block); + } + + return block; +} + +/// Return an allocated memory block back to a Memory Pool. +/// \note API identical to osMemoryPoolFree +__STATIC_INLINE +osStatus_t isrRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) { + os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id); + osStatus_t status; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Free memory + status = osRtxMemoryPoolFree(&mp->mp_info, block); + if (status == osOK) { + // Register post ISR processing + osRtxPostProcess(osRtxObject(mp)); + EvrRtxMemoryPoolDeallocated(mp, block); + } else { + EvrRtxMemoryPoolFreeFailed(mp, block); + } + + return status; +} + + +// ==== Public API ==== + +/// Create and Initialize a Memory Pool object. +osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) { + osMemoryPoolId_t mp_id; + + EvrRtxMemoryPoolNew(block_count, block_size, attr); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMemoryPoolError(NULL, (int32_t)osErrorISR); + mp_id = NULL; + } else { + mp_id = __svcMemoryPoolNew(block_count, block_size, attr); + } + return mp_id; +} + +/// Get name of a Memory Pool object. +const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id) { + const char *name; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMemoryPoolGetName(mp_id, NULL); + name = NULL; + } else { + name = __svcMemoryPoolGetName(mp_id); + } + return name; +} + +/// Allocate a memory block from a Memory Pool. +void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) { + void *memory; + + EvrRtxMemoryPoolAlloc(mp_id, timeout); + if (IsIrqMode() || IsIrqMasked()) { + memory = isrRtxMemoryPoolAlloc(mp_id, timeout); + } else { + memory = __svcMemoryPoolAlloc(mp_id, timeout); + } + return memory; +} + +/// Return an allocated memory block back to a Memory Pool. +osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) { + osStatus_t status; + + EvrRtxMemoryPoolFree(mp_id, block); + if (IsIrqMode() || IsIrqMasked()) { + status = isrRtxMemoryPoolFree(mp_id, block); + } else { + status = __svcMemoryPoolFree(mp_id, block); + } + return status; +} + +/// Get maximum number of memory blocks in a Memory Pool. +uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) { + uint32_t capacity; + + if (IsIrqMode() || IsIrqMasked()) { + capacity = svcRtxMemoryPoolGetCapacity(mp_id); + } else { + capacity = __svcMemoryPoolGetCapacity(mp_id); + } + return capacity; +} + +/// Get memory block size in a Memory Pool. +uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) { + uint32_t block_size; + + if (IsIrqMode() || IsIrqMasked()) { + block_size = svcRtxMemoryPoolGetBlockSize(mp_id); + } else { + block_size = __svcMemoryPoolGetBlockSize(mp_id); + } + return block_size; +} + +/// Get number of memory blocks used in a Memory Pool. +uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) { + uint32_t count; + + if (IsIrqMode() || IsIrqMasked()) { + count = svcRtxMemoryPoolGetCount(mp_id); + } else { + count = __svcMemoryPoolGetCount(mp_id); + } + return count; +} + +/// Get number of memory blocks available in a Memory Pool. +uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) { + uint32_t space; + + if (IsIrqMode() || IsIrqMasked()) { + space = svcRtxMemoryPoolGetSpace(mp_id); + } else { + space = __svcMemoryPoolGetSpace(mp_id); + } + return space; +} + +/// Delete a Memory Pool object. +osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) { + osStatus_t status; + + EvrRtxMemoryPoolDelete(mp_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMemoryPoolError(mp_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcMemoryPoolDelete(mp_id); + } + return status; +} diff --git a/rtos/rtx5/rtx_msgqueue.c b/rtos/rtx5/rtx_msgqueue.c new file mode 100644 index 0000000..5451998 --- /dev/null +++ b/rtos/rtx5/rtx_msgqueue.c @@ -0,0 +1,948 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Message Queue functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// OS Runtime Object Memory Usage +#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))) +osRtxObjectMemUsage_t osRtxMessageQueueMemUsage \ +__attribute__((section(".data.os.msgqueue.obj"))) = +{ 0U, 0U, 0U }; +#endif + + +// ==== Helper functions ==== + +/// Put a Message into Queue sorted by Priority (Highest at Head). +/// \param[in] mq message queue object. +/// \param[in] msg message object. +static void MessageQueuePut (os_message_queue_t *mq, os_message_t *msg) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#endif + os_message_t *prev, *next; + + if (mq->msg_last != NULL) { + prev = mq->msg_last; + next = NULL; + while ((prev != NULL) && (prev->priority < msg->priority)) { + next = prev; + prev = prev->prev; + } + msg->prev = prev; + msg->next = next; + if (prev != NULL) { + prev->next = msg; + } else { + mq->msg_first = msg; + } + if (next != NULL) { + next->prev = msg; + } else { + mq->msg_last = msg; + } + } else { + msg->prev = NULL; + msg->next = NULL; + mq->msg_first= msg; + mq->msg_last = msg; + } + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + mq->msg_count++; + + if (primask == 0U) { + __enable_irq(); + } +#else + (void)atomic_inc32(&mq->msg_count); +#endif +} + +/// Get a Message from Queue with Highest Priority. +/// \param[in] mq message queue object. +/// \return message object or NULL. +static os_message_t *MessageQueueGet (os_message_queue_t *mq) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#endif + os_message_t *msg; + uint32_t count; + uint8_t flags; + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + count = mq->msg_count; + if (count != 0U) { + mq->msg_count--; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + count = atomic_dec32_nz(&mq->msg_count); +#endif + + if (count != 0U) { + msg = mq->msg_first; + + while (msg != NULL) { +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + flags = msg->flags; + msg->flags = 1U; + + if (primask == 0U) { + __enable_irq(); + } +#else + flags = atomic_wr8(&msg->flags, 1U); +#endif + if (flags == 0U) { + break; + } + msg = msg->next; + } + } else { + msg = NULL; + } + + return msg; +} + +/// Remove a Message from Queue +/// \param[in] mq message queue object. +/// \param[in] msg message object. +static void MessageQueueRemove (os_message_queue_t *mq, const os_message_t *msg) { + + if (msg->prev != NULL) { + msg->prev->next = msg->next; + } else { + mq->msg_first = msg->next; + } + if (msg->next != NULL) { + msg->next->prev = msg->prev; + } else { + mq->msg_last = msg->prev; + } +} + + +// ==== Post ISR processing ==== + +/// Message Queue post ISR processing. +/// \param[in] msg message object. +static void osRtxMessageQueuePostProcess (os_message_t *msg) { + os_message_queue_t *mq; + os_message_t *msg0; + os_thread_t *thread; + const uint32_t *reg; + const void *ptr_src; + void *ptr_dst; + + if (msg->flags != 0U) { + // Remove Message + //lint -e{9079} -e{9087} "cast between pointers to different object types" + mq = *((os_message_queue_t **)(void *)&msg[1]); + MessageQueueRemove(mq, msg); + // Free memory + msg->id = osRtxIdInvalid; + (void)osRtxMemoryPoolFree(&mq->mp_info, msg); + // Check if Thread is waiting to send a Message + if (mq->thread_list != NULL) { + // Try to allocate memory + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + msg0 = osRtxMemoryPoolAlloc(&mq->mp_info); + if (msg0 != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(mq)); + osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE); + // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio) + reg = osRtxThreadRegPtr(thread); + //lint -e{923} "cast from unsigned int to pointer" + ptr_src = (const void *)reg[2]; + memcpy(&msg0[1], ptr_src, mq->msg_size); + // Store Message into Queue + msg0->id = osRtxIdMessage; + msg0->flags = 0U; + msg0->priority = (uint8_t)reg[3]; + MessageQueuePut(mq, msg0); + EvrRtxMessageQueueInserted(mq, ptr_src); + } + } + } else { + // New Message + //lint -e{9079} -e{9087} "cast between pointers to different object types" + mq = (void *)msg->next; + //lint -e{9087} "cast between pointers to different object types" + ptr_src = (const void *)msg->prev; + // Check if Thread is waiting to receive a Message + if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessageGet)) { + EvrRtxMessageQueueInserted(mq, ptr_src); + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(mq)); + osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE); + // Copy Message (R2: void *msg_ptr, R3: uint8_t *msg_prio) + reg = osRtxThreadRegPtr(thread); + //lint -e{923} "cast from unsigned int to pointer" + ptr_dst = (void *)reg[2]; + memcpy(ptr_dst, &msg[1], mq->msg_size); + if (reg[3] != 0U) { + //lint -e{923} -e{9078} "cast from unsigned int to pointer" + *((uint8_t *)reg[3]) = msg->priority; + } + EvrRtxMessageQueueRetrieved(mq, ptr_dst); + // Free memory + msg->id = osRtxIdInvalid; + (void)osRtxMemoryPoolFree(&mq->mp_info, msg); + } else { + EvrRtxMessageQueueInserted(mq, ptr_src); + MessageQueuePut(mq, msg); + } + } +} + + +// ==== Service Calls ==== + +/// Create and Initialize a Message Queue object. +/// \note API identical to osMessageQueueNew +static osMessageQueueId_t svcRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) { + os_message_queue_t *mq; + void *mq_mem; + uint32_t mq_size; + uint32_t block_size; + uint32_t size; + uint8_t flags; + const char *name; + + // Check parameters + if ((msg_count == 0U) || (msg_size == 0U)) { + EvrRtxMessageQueueError(NULL, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + block_size = ((msg_size + 3U) & ~3UL) + sizeof(os_message_t); + if ((__CLZ(msg_count) + __CLZ(block_size)) < 32U) { + EvrRtxMessageQueueError(NULL, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + size = msg_count * block_size; + + // Process attributes + if (attr != NULL) { + name = attr->name; + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + mq = attr->cb_mem; + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + mq_mem = attr->mq_mem; + mq_size = attr->mq_size; + if (mq != NULL) { + //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7] + if ((((uint32_t)mq & 3U) != 0U) || (attr->cb_size < sizeof(os_message_queue_t))) { + EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + if (mq_mem != NULL) { + //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7] + if ((((uint32_t)mq_mem & 3U) != 0U) || (mq_size < size)) { + EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } else { + if (mq_size != 0U) { + EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + } else { + name = NULL; + mq = NULL; + mq_mem = NULL; + } + + // Allocate object memory if not provided + if (mq == NULL) { + if (osRtxInfo.mpi.message_queue != NULL) { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + mq = osRtxMemoryPoolAlloc(osRtxInfo.mpi.message_queue); + } else { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + mq = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_message_queue_t), 1U); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + if (mq != NULL) { + uint32_t used; + osRtxMessageQueueMemUsage.cnt_alloc++; + used = osRtxMessageQueueMemUsage.cnt_alloc - osRtxMessageQueueMemUsage.cnt_free; + if (osRtxMessageQueueMemUsage.max_used < used) { + osRtxMessageQueueMemUsage.max_used = used; + } + } +#endif + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + // Allocate data memory if not provided + if ((mq != NULL) && (mq_mem == NULL)) { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + mq_mem = osRtxMemoryAlloc(osRtxInfo.mem.mq_data, size, 0U); + if (mq_mem == NULL) { + if ((flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.message_queue != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, mq); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxMessageQueueMemUsage.cnt_free++; +#endif + } + mq = NULL; + } else { + memset(mq_mem, 0, size); + } + flags |= osRtxFlagSystemMemory; + } + + if (mq != NULL) { + // Initialize control block + mq->id = osRtxIdMessageQueue; + mq->flags = flags; + mq->name = name; + mq->thread_list = NULL; + mq->msg_size = msg_size; + mq->msg_count = 0U; + mq->msg_first = NULL; + mq->msg_last = NULL; + (void)osRtxMemoryPoolInit(&mq->mp_info, msg_count, block_size, mq_mem); + + // Register post ISR processing function + osRtxInfo.post_process.message = osRtxMessageQueuePostProcess; + + EvrRtxMessageQueueCreated(mq, mq->name); + } else { + EvrRtxMessageQueueError(NULL, (int32_t)osErrorNoMemory); + } + + return mq; +} + +/// Get name of a Message Queue object. +/// \note API identical to osMessageQueueGetName +static const char *svcRtxMessageQueueGetName (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueGetName(mq, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + EvrRtxMessageQueueGetName(mq, mq->name); + + return mq->name; +} + +/// Put a Message into a Queue or timeout if Queue is full. +/// \note API identical to osMessageQueuePut +static osStatus_t svcRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + os_message_t *msg; + os_thread_t *thread; + uint32_t *reg; + void *ptr; + osStatus_t status; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) { + EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check if Thread is waiting to receive a Message + if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessageGet)) { + EvrRtxMessageQueueInserted(mq, msg_ptr); + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(mq)); + osRtxThreadWaitExit(thread, (uint32_t)osOK, TRUE); + // Copy Message (R2: void *msg_ptr, R3: uint8_t *msg_prio) + reg = osRtxThreadRegPtr(thread); + //lint -e{923} "cast from unsigned int to pointer" + ptr = (void *)reg[2]; + memcpy(ptr, msg_ptr, mq->msg_size); + if (reg[3] != 0U) { + //lint -e{923} -e{9078} "cast from unsigned int to pointer" + *((uint8_t *)reg[3]) = msg_prio; + } + EvrRtxMessageQueueRetrieved(mq, ptr); + status = osOK; + } else { + // Try to allocate memory + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + msg = osRtxMemoryPoolAlloc(&mq->mp_info); + if (msg != NULL) { + // Copy Message + memcpy(&msg[1], msg_ptr, mq->msg_size); + // Put Message into Queue + msg->id = osRtxIdMessage; + msg->flags = 0U; + msg->priority = msg_prio; + MessageQueuePut(mq, msg); + EvrRtxMessageQueueInserted(mq, msg_ptr); + status = osOK; + } else { + // No memory available + if (timeout != 0U) { + EvrRtxMessageQueuePutPending(mq, msg_ptr, timeout); + // Suspend current Thread + if (osRtxThreadWaitEnter(osRtxThreadWaitingMessagePut, timeout)) { + osRtxThreadListPut(osRtxObject(mq), osRtxThreadGetRunning()); + // Save arguments (R2: const void *msg_ptr, R3: uint8_t msg_prio) + //lint -e{923} -e{9078} "cast from unsigned int to pointer" + reg = (uint32_t *)(__get_PSP()); + //lint -e{923} -e{9078} "cast from pointer to unsigned int" + reg[2] = (uint32_t)msg_ptr; + //lint -e{923} -e{9078} "cast from pointer to unsigned int" + reg[3] = (uint32_t)msg_prio; + } else { + EvrRtxMessageQueuePutTimeout(mq); + } + status = osErrorTimeout; + } else { + EvrRtxMessageQueueNotInserted(mq, msg_ptr); + status = osErrorResource; + } + } + } + + return status; +} + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \note API identical to osMessageQueueGet +static osStatus_t svcRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + os_message_t *msg; + os_thread_t *thread; + uint32_t *reg; + const void *ptr; + osStatus_t status; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) { + EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Get Message from Queue + msg = MessageQueueGet(mq); + if (msg != NULL) { + MessageQueueRemove(mq, msg); + // Copy Message + memcpy(msg_ptr, &msg[1], mq->msg_size); + if (msg_prio != NULL) { + *msg_prio = msg->priority; + } + EvrRtxMessageQueueRetrieved(mq, msg_ptr); + // Free memory + msg->id = osRtxIdInvalid; + (void)osRtxMemoryPoolFree(&mq->mp_info, msg); + // Check if Thread is waiting to send a Message + if (mq->thread_list != NULL) { + // Try to allocate memory + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + msg = osRtxMemoryPoolAlloc(&mq->mp_info); + if (msg != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(mq)); + osRtxThreadWaitExit(thread, (uint32_t)osOK, TRUE); + // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio) + reg = osRtxThreadRegPtr(thread); + //lint -e{923} "cast from unsigned int to pointer" + ptr = (const void *)reg[2]; + memcpy(&msg[1], ptr, mq->msg_size); + // Store Message into Queue + msg->id = osRtxIdMessage; + msg->flags = 0U; + msg->priority = (uint8_t)reg[3]; + MessageQueuePut(mq, msg); + EvrRtxMessageQueueInserted(mq, ptr); + } + } + status = osOK; + } else { + // No Message available + if (timeout != 0U) { + EvrRtxMessageQueueGetPending(mq, msg_ptr, timeout); + // Suspend current Thread + if (osRtxThreadWaitEnter(osRtxThreadWaitingMessageGet, timeout)) { + osRtxThreadListPut(osRtxObject(mq), osRtxThreadGetRunning()); + // Save arguments (R2: void *msg_ptr, R3: uint8_t *msg_prio) + //lint -e{923} -e{9078} "cast from unsigned int to pointer" + reg = (uint32_t *)(__get_PSP()); + //lint -e{923} -e{9078} "cast from pointer to unsigned int" + reg[2] = (uint32_t)msg_ptr; + //lint -e{923} -e{9078} "cast from pointer to unsigned int" + reg[3] = (uint32_t)msg_prio; + } else { + EvrRtxMessageQueueGetTimeout(mq); + } + status = osErrorTimeout; + } else { + EvrRtxMessageQueueNotRetrieved(mq, msg_ptr); + status = osErrorResource; + } + } + + return status; +} + +/// Get maximum number of messages in a Message Queue. +/// \note API identical to osMessageQueueGetCapacity +static uint32_t svcRtxMessageQueueGetCapacity (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueGetCapacity(mq, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxMessageQueueGetCapacity(mq, mq->mp_info.max_blocks); + + return mq->mp_info.max_blocks; +} + +/// Get maximum message size in a Memory Pool. +/// \note API identical to osMessageQueueGetMsgSize +static uint32_t svcRtxMessageQueueGetMsgSize (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueGetMsgSize(mq, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxMessageQueueGetMsgSize(mq, mq->msg_size); + + return mq->msg_size; +} + +/// Get number of queued messages in a Message Queue. +/// \note API identical to osMessageQueueGetCount +static uint32_t svcRtxMessageQueueGetCount (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueGetCount(mq, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxMessageQueueGetCount(mq, mq->msg_count); + + return mq->msg_count; +} + +/// Get number of available slots for messages in a Message Queue. +/// \note API identical to osMessageQueueGetSpace +static uint32_t svcRtxMessageQueueGetSpace (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueGetSpace(mq, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxMessageQueueGetSpace(mq, mq->mp_info.max_blocks - mq->msg_count); + + return (mq->mp_info.max_blocks - mq->msg_count); +} + +/// Reset a Message Queue to initial empty state. +/// \note API identical to osMessageQueueReset +static osStatus_t svcRtxMessageQueueReset (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + os_message_t *msg; + os_thread_t *thread; + const uint32_t *reg; + const void *ptr; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Remove Messages from Queue + for (;;) { + // Get Message from Queue + msg = MessageQueueGet(mq); + if (msg == NULL) { + break; + } + MessageQueueRemove(mq, msg); + EvrRtxMessageQueueRetrieved(mq, NULL); + // Free memory + msg->id = osRtxIdInvalid; + (void)osRtxMemoryPoolFree(&mq->mp_info, msg); + } + + // Check if Threads are waiting to send Messages + if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessagePut)) { + do { + // Try to allocate memory + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + msg = osRtxMemoryPoolAlloc(&mq->mp_info); + if (msg != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(mq)); + osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE); + // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio) + reg = osRtxThreadRegPtr(thread); + //lint -e{923} "cast from unsigned int to pointer" + ptr = (const void *)reg[2]; + memcpy(&msg[1], ptr, mq->msg_size); + // Store Message into Queue + msg->id = osRtxIdMessage; + msg->flags = 0U; + msg->priority = (uint8_t)reg[3]; + MessageQueuePut(mq, msg); + EvrRtxMessageQueueInserted(mq, ptr); + } + } while ((msg != NULL) && (mq->thread_list != NULL)); + osRtxThreadDispatch(NULL); + } + + EvrRtxMessageQueueResetDone(mq); + + return osOK; +} + +/// Delete a Message Queue object. +/// \note API identical to osMessageQueueDelete +static osStatus_t svcRtxMessageQueueDelete (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + os_thread_t *thread; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Unblock waiting threads + if (mq->thread_list != NULL) { + do { + thread = osRtxThreadListGet(osRtxObject(mq)); + osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE); + } while (mq->thread_list != NULL); + osRtxThreadDispatch(NULL); + } + + // Mark object as invalid + mq->id = osRtxIdInvalid; + + // Free data memory + if ((mq->flags & osRtxFlagSystemMemory) != 0U) { + (void)osRtxMemoryFree(osRtxInfo.mem.mq_data, mq->mp_info.block_base); + } + + // Free object memory + if ((mq->flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.message_queue != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, mq); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxMessageQueueMemUsage.cnt_free++; +#endif + } + + EvrRtxMessageQueueDestroyed(mq); + + return osOK; +} + +// Service Calls definitions +//lint ++flb "Library Begin" [MISRA Note 11] +SVC0_3(MessageQueueNew, osMessageQueueId_t, uint32_t, uint32_t, const osMessageQueueAttr_t *) +SVC0_1(MessageQueueGetName, const char *, osMessageQueueId_t) +SVC0_4(MessageQueuePut, osStatus_t, osMessageQueueId_t, const void *, uint8_t, uint32_t) +SVC0_4(MessageQueueGet, osStatus_t, osMessageQueueId_t, void *, uint8_t *, uint32_t) +SVC0_1(MessageQueueGetCapacity, uint32_t, osMessageQueueId_t) +SVC0_1(MessageQueueGetMsgSize, uint32_t, osMessageQueueId_t) +SVC0_1(MessageQueueGetCount, uint32_t, osMessageQueueId_t) +SVC0_1(MessageQueueGetSpace, uint32_t, osMessageQueueId_t) +SVC0_1(MessageQueueReset, osStatus_t, osMessageQueueId_t) +SVC0_1(MessageQueueDelete, osStatus_t, osMessageQueueId_t) +//lint --flb "Library End" + + +// ==== ISR Calls ==== + +/// Put a Message into a Queue or timeout if Queue is full. +/// \note API identical to osMessageQueuePut +__STATIC_INLINE +osStatus_t isrRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + os_message_t *msg; + osStatus_t status; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) { + EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Try to allocate memory + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + msg = osRtxMemoryPoolAlloc(&mq->mp_info); + if (msg != NULL) { + // Copy Message + memcpy(&msg[1], msg_ptr, mq->msg_size); + msg->id = osRtxIdMessage; + msg->flags = 0U; + msg->priority = msg_prio; + // Register post ISR processing + //lint -e{9079} -e{9087} "cast between pointers to different object types" + *((const void **)(void *)&msg->prev) = msg_ptr; + //lint -e{9079} -e{9087} "cast between pointers to different object types" + *( (void **) &msg->next) = mq; + osRtxPostProcess(osRtxObject(msg)); + EvrRtxMessageQueueInsertPending(mq, msg_ptr); + status = osOK; + } else { + // No memory available + EvrRtxMessageQueueNotInserted(mq, msg_ptr); + status = osErrorResource; + } + + return status; +} + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \note API identical to osMessageQueueGet +__STATIC_INLINE +osStatus_t isrRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { + os_message_queue_t *mq = osRtxMessageQueueId(mq_id); + os_message_t *msg; + osStatus_t status; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) { + EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Get Message from Queue + msg = MessageQueueGet(mq); + if (msg != NULL) { + // Copy Message + memcpy(msg_ptr, &msg[1], mq->msg_size); + if (msg_prio != NULL) { + *msg_prio = msg->priority; + } + // Register post ISR processing + //lint -e{9079} -e{9087} "cast between pointers to different object types" + *((os_message_queue_t **)(void *)&msg[1]) = mq; + osRtxPostProcess(osRtxObject(msg)); + EvrRtxMessageQueueRetrieved(mq, msg_ptr); + status = osOK; + } else { + // No Message available + EvrRtxMessageQueueNotRetrieved(mq, msg_ptr); + status = osErrorResource; + } + + return status; +} + + +// ==== Public API ==== + +/// Create and Initialize a Message Queue object. +osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) { + osMessageQueueId_t mq_id; + + EvrRtxMessageQueueNew(msg_count, msg_size, attr); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMessageQueueError(NULL, (int32_t)osErrorISR); + mq_id = NULL; + } else { + mq_id = __svcMessageQueueNew(msg_count, msg_size, attr); + } + return mq_id; +} + +/// Get name of a Message Queue object. +const char *osMessageQueueGetName (osMessageQueueId_t mq_id) { + const char *name; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMessageQueueGetName(mq_id, NULL); + name = NULL; + } else { + name = __svcMessageQueueGetName(mq_id); + } + return name; +} + +/// Put a Message into a Queue or timeout if Queue is full. +osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { + osStatus_t status; + + EvrRtxMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout); + if (IsIrqMode() || IsIrqMasked()) { + status = isrRtxMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout); + } else { + status = __svcMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout); + } + return status; +} + +/// Get a Message from a Queue or timeout if Queue is empty. +osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { + osStatus_t status; + + EvrRtxMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout); + if (IsIrqMode() || IsIrqMasked()) { + status = isrRtxMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout); + } else { + status = __svcMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout); + } + return status; +} + +/// Get maximum number of messages in a Message Queue. +uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) { + uint32_t capacity; + + if (IsIrqMode() || IsIrqMasked()) { + capacity = svcRtxMessageQueueGetCapacity(mq_id); + } else { + capacity = __svcMessageQueueGetCapacity(mq_id); + } + return capacity; +} + +/// Get maximum message size in a Memory Pool. +uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) { + uint32_t msg_size; + + if (IsIrqMode() || IsIrqMasked()) { + msg_size = svcRtxMessageQueueGetMsgSize(mq_id); + } else { + msg_size = __svcMessageQueueGetMsgSize(mq_id); + } + return msg_size; +} + +/// Get number of queued messages in a Message Queue. +uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) { + uint32_t count; + + if (IsIrqMode() || IsIrqMasked()) { + count = svcRtxMessageQueueGetCount(mq_id); + } else { + count = __svcMessageQueueGetCount(mq_id); + } + return count; +} + +/// Get number of available slots for messages in a Message Queue. +uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) { + uint32_t space; + + if (IsIrqMode() || IsIrqMasked()) { + space = svcRtxMessageQueueGetSpace(mq_id); + } else { + space = __svcMessageQueueGetSpace(mq_id); + } + return space; +} + +/// Reset a Message Queue to initial empty state. +osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) { + osStatus_t status; + + EvrRtxMessageQueueReset(mq_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMessageQueueError(mq_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcMessageQueueReset(mq_id); + } + return status; +} + +/// Delete a Message Queue object. +osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) { + osStatus_t status; + + EvrRtxMessageQueueDelete(mq_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMessageQueueError(mq_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcMessageQueueDelete(mq_id); + } + return status; +} diff --git a/rtos/rtx5/rtx_mutex.c b/rtos/rtx5/rtx_mutex.c new file mode 100644 index 0000000..1941488 --- /dev/null +++ b/rtos/rtx5/rtx_mutex.c @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Mutex functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// OS Runtime Object Memory Usage +#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))) +osRtxObjectMemUsage_t osRtxMutexMemUsage \ +__attribute__((section(".data.os.mutex.obj"))) = +{ 0U, 0U, 0U }; +#endif + + +// ==== Library functions ==== + +/// Release Mutex list when owner Thread terminates. +/// \param[in] mutex mutex object. +/// \return 1 - success, 0 - failure. +void osRtxMutexOwnerRelease (os_mutex_t *mutex_list) { + os_mutex_t *mutex; + os_mutex_t *mutex_next; + os_thread_t *thread; + + mutex = mutex_list; + while (mutex != NULL) { + mutex_next = mutex->owner_next; + // Check if Mutex is Robust + if ((mutex->attr & osMutexRobust) != 0U) { + // Clear Lock counter + mutex->lock = 0U; + EvrRtxMutexReleased(mutex, 0U); + // Check if Thread is waiting for a Mutex + if (mutex->thread_list != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(mutex)); + osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE); + // Thread is the new Mutex owner + mutex->owner_thread = thread; + mutex->owner_prev = NULL; + mutex->owner_next = thread->mutex_list; + if (thread->mutex_list != NULL) { + thread->mutex_list->owner_prev = mutex; + } + thread->mutex_list = mutex; + mutex->lock = 1U; + EvrRtxMutexAcquired(mutex, 1U); + } + } + mutex = mutex_next; + } +} + + +// ==== Service Calls ==== + +/// Create and Initialize a Mutex object. +/// \note API identical to osMutexNew +static osMutexId_t svcRtxMutexNew (const osMutexAttr_t *attr) { + os_mutex_t *mutex; + uint32_t attr_bits; + uint8_t flags; + const char *name; + + // Process attributes + if (attr != NULL) { + name = attr->name; + attr_bits = attr->attr_bits; + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + mutex = attr->cb_mem; + if (mutex != NULL) { + //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7] + if ((((uint32_t)mutex & 3U) != 0U) || (attr->cb_size < sizeof(os_mutex_t))) { + EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + } else { + name = NULL; + attr_bits = 0U; + mutex = NULL; + } + + // Allocate object memory if not provided + if (mutex == NULL) { + if (osRtxInfo.mpi.mutex != NULL) { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + mutex = osRtxMemoryPoolAlloc(osRtxInfo.mpi.mutex); + } else { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + mutex = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_mutex_t), 1U); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + if (mutex != NULL) { + uint32_t used; + osRtxMutexMemUsage.cnt_alloc++; + used = osRtxMutexMemUsage.cnt_alloc - osRtxMutexMemUsage.cnt_free; + if (osRtxMutexMemUsage.max_used < used) { + osRtxMutexMemUsage.max_used = used; + } + } +#endif + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + if (mutex != NULL) { + // Initialize control block + mutex->id = osRtxIdMutex; + mutex->flags = flags; + mutex->attr = (uint8_t)attr_bits; + mutex->name = name; + mutex->thread_list = NULL; + mutex->owner_thread = NULL; + mutex->owner_prev = NULL; + mutex->owner_next = NULL; + mutex->lock = 0U; + + EvrRtxMutexCreated(mutex, mutex->name); + } else { + EvrRtxMutexError(NULL, (int32_t)osErrorNoMemory); + } + + return mutex; +} + +/// Get name of a Mutex object. +/// \note API identical to osMutexGetName +static const char *svcRtxMutexGetName (osMutexId_t mutex_id) { + os_mutex_t *mutex = osRtxMutexId(mutex_id); + + // Check parameters + if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { + EvrRtxMutexGetName(mutex, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + EvrRtxMutexGetName(mutex, mutex->name); + + return mutex->name; +} + +/// Acquire a Mutex or timeout if it is locked. +/// \note API identical to osMutexAcquire +static osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { + os_mutex_t *mutex = osRtxMutexId(mutex_id); + os_thread_t *thread; + osStatus_t status; + + // Check running thread + thread = osRtxThreadGetRunning(); + if (thread == NULL) { + EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osError; + } + + // Check parameters + if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { + EvrRtxMutexError(mutex, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check if Mutex is not locked + if (mutex->lock == 0U) { + // Acquire Mutex + mutex->owner_thread = thread; + mutex->owner_prev = NULL; + mutex->owner_next = thread->mutex_list; + if (thread->mutex_list != NULL) { + thread->mutex_list->owner_prev = mutex; + } + thread->mutex_list = mutex; + mutex->lock = 1U; + EvrRtxMutexAcquired(mutex, mutex->lock); + status = osOK; + } else { + // Check if Mutex is recursive and running Thread is the owner + if (((mutex->attr & osMutexRecursive) != 0U) && (mutex->owner_thread == thread)) { + // Try to increment lock counter + if (mutex->lock == osRtxMutexLockLimit) { + EvrRtxMutexError(mutex, osRtxErrorMutexLockLimit); + status = osErrorResource; + } else { + mutex->lock++; + EvrRtxMutexAcquired(mutex, mutex->lock); + status = osOK; + } + } else { + // Check if timeout is specified + if (timeout != 0U) { + // Check if Priority inheritance protocol is enabled + if ((mutex->attr & osMutexPrioInherit) != 0U) { + // Raise priority of owner Thread if lower than priority of running Thread + if (mutex->owner_thread->priority < thread->priority) { + mutex->owner_thread->priority = thread->priority; + osRtxThreadListSort(mutex->owner_thread); + } + } + EvrRtxMutexAcquirePending(mutex, timeout); + // Suspend current Thread + if (osRtxThreadWaitEnter(osRtxThreadWaitingMutex, timeout)) { + osRtxThreadListPut(osRtxObject(mutex), thread); + } else { + EvrRtxMutexAcquireTimeout(mutex); + } + status = osErrorTimeout; + } else { + EvrRtxMutexNotAcquired(mutex); + status = osErrorResource; + } + } + } + + return status; +} + +/// Release a Mutex that was acquired by osMutexAcquire. +/// \note API identical to osMutexRelease +static osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) { + os_mutex_t *mutex = osRtxMutexId(mutex_id); + const os_mutex_t *mutex0; + os_thread_t *thread; + int8_t priority; + + // Check running thread + thread = osRtxThreadGetRunning(); + if (thread == NULL) { + EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osError; + } + + // Check parameters + if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { + EvrRtxMutexError(mutex, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check if Mutex is not locked + if (mutex->lock == 0U) { + EvrRtxMutexError(mutex, osRtxErrorMutexNotLocked); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorResource; + } + + // Check if running Thread is not the owner + if (mutex->owner_thread != thread) { + EvrRtxMutexError(mutex, osRtxErrorMutexNotOwned); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorResource; + } + + // Decrement Lock counter + mutex->lock--; + EvrRtxMutexReleased(mutex, mutex->lock); + + // Check Lock counter + if (mutex->lock == 0U) { + + // Remove Mutex from Thread owner list + if (mutex->owner_next != NULL) { + mutex->owner_next->owner_prev = mutex->owner_prev; + } + if (mutex->owner_prev != NULL) { + mutex->owner_prev->owner_next = mutex->owner_next; + } else { + thread->mutex_list = mutex->owner_next; + } + + // Restore running Thread priority + if ((mutex->attr & osMutexPrioInherit) != 0U) { + priority = thread->priority_base; + mutex0 = thread->mutex_list; + while (mutex0 != NULL) { + // Mutexes owned by running Thread + if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) { + // Higher priority Thread is waiting for Mutex + priority = mutex0->thread_list->priority; + } + mutex0 = mutex0->owner_next; + } + thread->priority = priority; + } + + // Check if Thread is waiting for a Mutex + if (mutex->thread_list != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(mutex)); + osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE); + // Thread is the new Mutex owner + mutex->owner_thread = thread; + mutex->owner_prev = NULL; + mutex->owner_next = thread->mutex_list; + if (thread->mutex_list != NULL) { + thread->mutex_list->owner_prev = mutex; + } + thread->mutex_list = mutex; + mutex->lock = 1U; + EvrRtxMutexAcquired(mutex, 1U); + } + + osRtxThreadDispatch(NULL); + } + + return osOK; +} + +/// Get Thread which owns a Mutex object. +/// \note API identical to osMutexGetOwner +static osThreadId_t svcRtxMutexGetOwner (osMutexId_t mutex_id) { + os_mutex_t *mutex = osRtxMutexId(mutex_id); + + // Check parameters + if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { + EvrRtxMutexGetOwner(mutex, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + // Check if Mutex is not locked + if (mutex->lock == 0U) { + EvrRtxMutexGetOwner(mutex, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + EvrRtxMutexGetOwner(mutex, mutex->owner_thread); + + return mutex->owner_thread; +} + +/// Delete a Mutex object. +/// \note API identical to osMutexDelete +static osStatus_t svcRtxMutexDelete (osMutexId_t mutex_id) { + os_mutex_t *mutex = osRtxMutexId(mutex_id); + const os_mutex_t *mutex0; + os_thread_t *thread; + int8_t priority; + + // Check parameters + if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { + EvrRtxMutexError(mutex, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check if Mutex is locked + if (mutex->lock != 0U) { + + thread = mutex->owner_thread; + + // Remove Mutex from Thread owner list + if (mutex->owner_next != NULL) { + mutex->owner_next->owner_prev = mutex->owner_prev; + } + if (mutex->owner_prev != NULL) { + mutex->owner_prev->owner_next = mutex->owner_next; + } else { + thread->mutex_list = mutex->owner_next; + } + + // Restore owner Thread priority + if ((mutex->attr & osMutexPrioInherit) != 0U) { + priority = thread->priority_base; + mutex0 = thread->mutex_list; + while (mutex0 != NULL) { + // Mutexes owned by running Thread + if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) { + // Higher priority Thread is waiting for Mutex + priority = mutex0->thread_list->priority; + } + mutex0 = mutex0->owner_next; + } + if (thread->priority != priority) { + thread->priority = priority; + osRtxThreadListSort(thread); + } + } + + // Unblock waiting threads + while (mutex->thread_list != NULL) { + thread = osRtxThreadListGet(osRtxObject(mutex)); + osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE); + } + + osRtxThreadDispatch(NULL); + } + + // Mark object as invalid + mutex->id = osRtxIdInvalid; + + // Free object memory + if ((mutex->flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.mutex != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.mutex, mutex); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, mutex); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxMutexMemUsage.cnt_free++; +#endif + } + + EvrRtxMutexDestroyed(mutex); + + return osOK; +} + +// Service Calls definitions +//lint ++flb "Library Begin" [MISRA Note 11] +SVC0_1(MutexNew, osMutexId_t, const osMutexAttr_t *) +SVC0_1(MutexGetName, const char *, osMutexId_t) +SVC0_2(MutexAcquire, osStatus_t, osMutexId_t, uint32_t) +SVC0_1(MutexRelease, osStatus_t, osMutexId_t) +SVC0_1(MutexGetOwner, osThreadId_t, osMutexId_t) +SVC0_1(MutexDelete, osStatus_t, osMutexId_t) +//lint --flb "Library End" + + +// ==== Public API ==== + +/// Create and Initialize a Mutex object. +osMutexId_t osMutexNew (const osMutexAttr_t *attr) { + osMutexId_t mutex_id; + + EvrRtxMutexNew(attr); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMutexError(NULL, (int32_t)osErrorISR); + mutex_id = NULL; + } else { + mutex_id = __svcMutexNew(attr); + } + return mutex_id; +} + +/// Get name of a Mutex object. +const char *osMutexGetName (osMutexId_t mutex_id) { + const char *name; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMutexGetName(mutex_id, NULL); + name = NULL; + } else { + name = __svcMutexGetName(mutex_id); + } + return name; +} + +/// Acquire a Mutex or timeout if it is locked. +osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { + osStatus_t status; + + EvrRtxMutexAcquire(mutex_id, timeout); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMutexError(mutex_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcMutexAcquire(mutex_id, timeout); + } + return status; +} + +/// Release a Mutex that was acquired by \ref osMutexAcquire. +osStatus_t osMutexRelease (osMutexId_t mutex_id) { + osStatus_t status; + + EvrRtxMutexRelease(mutex_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMutexError(mutex_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcMutexRelease(mutex_id); + } + return status; +} + +/// Get Thread which owns a Mutex object. +osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) { + osThreadId_t thread; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMutexGetOwner(mutex_id, NULL); + thread = NULL; + } else { + thread = __svcMutexGetOwner(mutex_id); + } + return thread; +} + +/// Delete a Mutex object. +osStatus_t osMutexDelete (osMutexId_t mutex_id) { + osStatus_t status; + + EvrRtxMutexDelete(mutex_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxMutexError(mutex_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcMutexDelete(mutex_id); + } + return status; +} diff --git a/rtos/rtx5/rtx_semaphore.c b/rtos/rtx5/rtx_semaphore.c new file mode 100644 index 0000000..ebca855 --- /dev/null +++ b/rtos/rtx5/rtx_semaphore.c @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2013-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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Semaphore functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// OS Runtime Object Memory Usage +#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))) +osRtxObjectMemUsage_t osRtxSemaphoreMemUsage \ +__attribute__((section(".data.os.semaphore.obj"))) = +{ 0U, 0U, 0U }; +#endif + + +// ==== Helper functions ==== + +/// Decrement Semaphore tokens. +/// \param[in] semaphore semaphore object. +/// \return 1 - success, 0 - failure. +static uint32_t SemaphoreTokenDecrement (os_semaphore_t *semaphore) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t ret; + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + if (semaphore->tokens != 0U) { + semaphore->tokens--; + ret = 1U; + } else { + ret = 0U; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if (atomic_dec16_nz(&semaphore->tokens) != 0U) { + ret = 1U; + } else { + ret = 0U; + } +#endif + + return ret; +} + +/// Increment Semaphore tokens. +/// \param[in] semaphore semaphore object. +/// \return 1 - success, 0 - failure. +static uint32_t SemaphoreTokenIncrement (os_semaphore_t *semaphore) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t ret; + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + if (semaphore->tokens < semaphore->max_tokens) { + semaphore->tokens++; + ret = 1U; + } else { + ret = 0U; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if (atomic_inc16_lt(&semaphore->tokens, semaphore->max_tokens) < semaphore->max_tokens) { + ret = 1U; + } else { + ret = 0U; + } +#endif + + return ret; +} + + +// ==== Post ISR processing ==== + +/// Semaphore post ISR processing. +/// \param[in] semaphore semaphore object. +static void osRtxSemaphorePostProcess (os_semaphore_t *semaphore) { + os_thread_t *thread; + + // Check if Thread is waiting for a token + if (semaphore->thread_list != NULL) { + // Try to acquire token + if (SemaphoreTokenDecrement(semaphore) != 0U) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(semaphore)); + osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE); + EvrRtxSemaphoreAcquired(semaphore, semaphore->tokens); + } + } +} + + +// ==== Service Calls ==== + +/// Create and Initialize a Semaphore object. +/// \note API identical to osSemaphoreNew +static osSemaphoreId_t svcRtxSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) { + os_semaphore_t *semaphore; + uint8_t flags; + const char *name; + + // Check parameters + if ((max_count == 0U) || (max_count > osRtxSemaphoreTokenLimit) || (initial_count > max_count)) { + EvrRtxSemaphoreError(NULL, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + // Process attributes + if (attr != NULL) { + name = attr->name; + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + semaphore = attr->cb_mem; + if (semaphore != NULL) { + //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7] + if ((((uint32_t)semaphore & 3U) != 0U) || (attr->cb_size < sizeof(os_semaphore_t))) { + EvrRtxSemaphoreError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxSemaphoreError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + } else { + name = NULL; + semaphore = NULL; + } + + // Allocate object memory if not provided + if (semaphore == NULL) { + if (osRtxInfo.mpi.semaphore != NULL) { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + semaphore = osRtxMemoryPoolAlloc(osRtxInfo.mpi.semaphore); + } else { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + semaphore = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_semaphore_t), 1U); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + if (semaphore != NULL) { + uint32_t used; + osRtxSemaphoreMemUsage.cnt_alloc++; + used = osRtxSemaphoreMemUsage.cnt_alloc - osRtxSemaphoreMemUsage.cnt_free; + if (osRtxSemaphoreMemUsage.max_used < used) { + osRtxSemaphoreMemUsage.max_used = used; + } + } +#endif + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + if (semaphore != NULL) { + // Initialize control block + semaphore->id = osRtxIdSemaphore; + semaphore->flags = flags; + semaphore->name = name; + semaphore->thread_list = NULL; + semaphore->tokens = (uint16_t)initial_count; + semaphore->max_tokens = (uint16_t)max_count; + + // Register post ISR processing function + osRtxInfo.post_process.semaphore = osRtxSemaphorePostProcess; + + EvrRtxSemaphoreCreated(semaphore, semaphore->name); + } else { + EvrRtxSemaphoreError(NULL,(int32_t)osErrorNoMemory); + } + + return semaphore; +} + +/// Get name of a Semaphore object. +/// \note API identical to osSemaphoreGetName +static const char *svcRtxSemaphoreGetName (osSemaphoreId_t semaphore_id) { + os_semaphore_t *semaphore = osRtxSemaphoreId(semaphore_id); + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreGetName(semaphore, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + EvrRtxSemaphoreGetName(semaphore, semaphore->name); + + return semaphore->name; +} + +/// Acquire a Semaphore token or timeout if no tokens are available. +/// \note API identical to osSemaphoreAcquire +static osStatus_t svcRtxSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) { + os_semaphore_t *semaphore = osRtxSemaphoreId(semaphore_id); + osStatus_t status; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreError(semaphore, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Try to acquire token + if (SemaphoreTokenDecrement(semaphore) != 0U) { + EvrRtxSemaphoreAcquired(semaphore, semaphore->tokens); + status = osOK; + } else { + // No token available + if (timeout != 0U) { + EvrRtxSemaphoreAcquirePending(semaphore, timeout); + // Suspend current Thread + if (osRtxThreadWaitEnter(osRtxThreadWaitingSemaphore, timeout)) { + osRtxThreadListPut(osRtxObject(semaphore), osRtxThreadGetRunning()); + } else { + EvrRtxSemaphoreAcquireTimeout(semaphore); + } + status = osErrorTimeout; + } else { + EvrRtxSemaphoreNotAcquired(semaphore); + status = osErrorResource; + } + } + + return status; +} + +/// Release a Semaphore token that was acquired by osSemaphoreAcquire. +/// \note API identical to osSemaphoreRelease +static osStatus_t svcRtxSemaphoreRelease (osSemaphoreId_t semaphore_id) { + os_semaphore_t *semaphore = osRtxSemaphoreId(semaphore_id); + os_thread_t *thread; + osStatus_t status; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreError(semaphore, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check if Thread is waiting for a token + if (semaphore->thread_list != NULL) { + EvrRtxSemaphoreReleased(semaphore, semaphore->tokens); + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet(osRtxObject(semaphore)); + osRtxThreadWaitExit(thread, (uint32_t)osOK, TRUE); + EvrRtxSemaphoreAcquired(semaphore, semaphore->tokens); + status = osOK; + } else { + // Try to release token + if (SemaphoreTokenIncrement(semaphore) != 0U) { + EvrRtxSemaphoreReleased(semaphore, semaphore->tokens); + status = osOK; + } else { + EvrRtxSemaphoreError(semaphore, osRtxErrorSemaphoreCountLimit); + status = osErrorResource; + } + } + + return status; +} + +/// Get current Semaphore token count. +/// \note API identical to osSemaphoreGetCount +static uint32_t svcRtxSemaphoreGetCount (osSemaphoreId_t semaphore_id) { + os_semaphore_t *semaphore = osRtxSemaphoreId(semaphore_id); + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreGetCount(semaphore, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxSemaphoreGetCount(semaphore, semaphore->tokens); + + return semaphore->tokens; +} + +/// Delete a Semaphore object. +/// \note API identical to osSemaphoreDelete +static osStatus_t svcRtxSemaphoreDelete (osSemaphoreId_t semaphore_id) { + os_semaphore_t *semaphore = osRtxSemaphoreId(semaphore_id); + os_thread_t *thread; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreError(semaphore, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Unblock waiting threads + if (semaphore->thread_list != NULL) { + do { + thread = osRtxThreadListGet(osRtxObject(semaphore)); + osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE); + } while (semaphore->thread_list != NULL); + osRtxThreadDispatch(NULL); + } + + // Mark object as invalid + semaphore->id = osRtxIdInvalid; + + // Free object memory + if ((semaphore->flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.semaphore != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.semaphore, semaphore); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, semaphore); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxSemaphoreMemUsage.cnt_free++; +#endif + } + + EvrRtxSemaphoreDestroyed(semaphore); + + return osOK; +} + +// Service Calls definitions +//lint ++flb "Library Begin" [MISRA Note 11] +SVC0_3(SemaphoreNew, osSemaphoreId_t, uint32_t, uint32_t, const osSemaphoreAttr_t *) +SVC0_1(SemaphoreGetName, const char *, osSemaphoreId_t) +SVC0_2(SemaphoreAcquire, osStatus_t, osSemaphoreId_t, uint32_t) +SVC0_1(SemaphoreRelease, osStatus_t, osSemaphoreId_t) +SVC0_1(SemaphoreGetCount, uint32_t, osSemaphoreId_t) +SVC0_1(SemaphoreDelete, osStatus_t, osSemaphoreId_t) +//lint --flb "Library End" + + +// ==== ISR Calls ==== + +/// Acquire a Semaphore token or timeout if no tokens are available. +/// \note API identical to osSemaphoreAcquire +__STATIC_INLINE +osStatus_t isrRtxSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) { + os_semaphore_t *semaphore = osRtxSemaphoreId(semaphore_id); + osStatus_t status; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore) || (timeout != 0U)) { + EvrRtxSemaphoreError(semaphore, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Try to acquire token + if (SemaphoreTokenDecrement(semaphore) != 0U) { + EvrRtxSemaphoreAcquired(semaphore, semaphore->tokens); + status = osOK; + } else { + // No token available + EvrRtxSemaphoreNotAcquired(semaphore); + status = osErrorResource; + } + + return status; +} + +/// Release a Semaphore token that was acquired by osSemaphoreAcquire. +/// \note API identical to osSemaphoreRelease +__STATIC_INLINE +osStatus_t isrRtxSemaphoreRelease (osSemaphoreId_t semaphore_id) { + os_semaphore_t *semaphore = osRtxSemaphoreId(semaphore_id); + osStatus_t status; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreError(semaphore, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Try to release token + if (SemaphoreTokenIncrement(semaphore) != 0U) { + // Register post ISR processing + osRtxPostProcess(osRtxObject(semaphore)); + EvrRtxSemaphoreReleased(semaphore, semaphore->tokens); + status = osOK; + } else { + EvrRtxSemaphoreError(semaphore, osRtxErrorSemaphoreCountLimit); + status = osErrorResource; + } + + return status; +} + + +// ==== Public API ==== + +/// Create and Initialize a Semaphore object. +osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) { + osSemaphoreId_t semaphore_id; + + EvrRtxSemaphoreNew(max_count, initial_count, attr); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxSemaphoreError(NULL, (int32_t)osErrorISR); + semaphore_id = NULL; + } else { + semaphore_id = __svcSemaphoreNew(max_count, initial_count, attr); + } + return semaphore_id; +} + +/// Get name of a Semaphore object. +const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id) { + const char *name; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxSemaphoreGetName(semaphore_id, NULL); + name = NULL; + } else { + name = __svcSemaphoreGetName(semaphore_id); + } + return name; +} + +/// Acquire a Semaphore token or timeout if no tokens are available. +osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) { + osStatus_t status; + + EvrRtxSemaphoreAcquire(semaphore_id, timeout); + if (IsIrqMode() || IsIrqMasked()) { + status = isrRtxSemaphoreAcquire(semaphore_id, timeout); + } else { + status = __svcSemaphoreAcquire(semaphore_id, timeout); + } + return status; +} + +/// Release a Semaphore token that was acquired by osSemaphoreAcquire. +osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id) { + osStatus_t status; + + EvrRtxSemaphoreRelease(semaphore_id); + if (IsIrqMode() || IsIrqMasked()) { + status = isrRtxSemaphoreRelease(semaphore_id); + } else { + status = __svcSemaphoreRelease(semaphore_id); + } + return status; +} + +/// Get current Semaphore token count. +uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) { + uint32_t count; + + if (IsIrqMode() || IsIrqMasked()) { + count = svcRtxSemaphoreGetCount(semaphore_id); + } else { + count = __svcSemaphoreGetCount(semaphore_id); + } + return count; +} + +/// Delete a Semaphore object. +osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id) { + osStatus_t status; + + EvrRtxSemaphoreDelete(semaphore_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxSemaphoreError(semaphore_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcSemaphoreDelete(semaphore_id); + } + return status; +} diff --git a/rtos/rtx5/rtx_system.c b/rtos/rtx5/rtx_system.c new file mode 100644 index 0000000..06e18b7 --- /dev/null +++ b/rtos/rtx5/rtx_system.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: System functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Helper functions ==== + +/// Put Object into ISR Queue. +/// \param[in] object object. +/// \return 1 - success, 0 - failure. +static uint32_t isr_queue_put (os_object_t *object) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#else + uint32_t n; +#endif + uint16_t max; + uint32_t ret; + + max = osRtxInfo.isr_queue.max; + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + if (osRtxInfo.isr_queue.cnt < max) { + osRtxInfo.isr_queue.cnt++; + osRtxInfo.isr_queue.data[osRtxInfo.isr_queue.in] = object; + if (++osRtxInfo.isr_queue.in == max) { + osRtxInfo.isr_queue.in = 0U; + } + ret = 1U; + } else { + ret = 0U; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if (atomic_inc16_lt(&osRtxInfo.isr_queue.cnt, max) < max) { + n = atomic_inc16_lim(&osRtxInfo.isr_queue.in, max); + osRtxInfo.isr_queue.data[n] = object; + ret = 1U; + } else { + ret = 0U; + } +#endif + + return ret; +} + +/// Get Object from ISR Queue. +/// \return object or NULL. +static os_object_t *isr_queue_get (void) { +#if (EXCLUSIVE_ACCESS != 0) + uint32_t n; +#endif + uint16_t max; + os_object_t *ret; + + max = osRtxInfo.isr_queue.max; + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + if (osRtxInfo.isr_queue.cnt != 0U) { + osRtxInfo.isr_queue.cnt--; + ret = osRtxObject(osRtxInfo.isr_queue.data[osRtxInfo.isr_queue.out]); + if (++osRtxInfo.isr_queue.out == max) { + osRtxInfo.isr_queue.out = 0U; + } + } else { + ret = NULL; + } + + __enable_irq(); +#else + if (atomic_dec16_nz(&osRtxInfo.isr_queue.cnt) != 0U) { + n = atomic_inc16_lim(&osRtxInfo.isr_queue.out, max); + ret = osRtxObject(osRtxInfo.isr_queue.data[n]); + } else { + ret = NULL; + } +#endif + + return ret; +} + + +// ==== Library Functions ==== + +/// Tick Handler. +//lint -esym(714,osRtxTick_Handler) "Referenced by Exception handlers" +//lint -esym(759,osRtxTick_Handler) "Prototype in header" +//lint -esym(765,osRtxTick_Handler) "Global scope" +void osRtxTick_Handler (void) { + os_thread_t *thread; + + OS_Tick_AcknowledgeIRQ(); + osRtxInfo.kernel.tick++; + +#if __RTX_CPU_STATISTICS__ + osRtxInfo.thread.run.curr->rtime += 1; +#endif + + // Process Timers + if (osRtxInfo.timer.tick != NULL) { + osRtxInfo.timer.tick(); + } + + // Process Thread Delays + osRtxThreadDelayTick(); + + osRtxThreadDispatch(NULL); + + // Check Round Robin timeout + if (osRtxInfo.thread.robin.timeout != 0U) { + if (osRtxInfo.thread.robin.thread != osRtxInfo.thread.run.next) { + // Reset Round Robin + osRtxInfo.thread.robin.thread = osRtxInfo.thread.run.next; + osRtxInfo.thread.robin.tick = osRtxInfo.thread.robin.timeout; + } else { + if (osRtxInfo.thread.robin.tick != 0U) { + osRtxInfo.thread.robin.tick--; + } + if (osRtxInfo.thread.robin.tick == 0U) { + // Round Robin Timeout + if (osRtxKernelGetState() == osRtxKernelRunning) { + thread = osRtxInfo.thread.ready.thread_list; + if ((thread != NULL) && (thread->priority == osRtxInfo.thread.robin.thread->priority)) { + osRtxThreadListRemove(thread); + osRtxThreadReadyPut(osRtxInfo.thread.robin.thread); + EvrRtxThreadPreempted(osRtxInfo.thread.robin.thread); + osRtxThreadSwitch(thread); + osRtxInfo.thread.robin.thread = thread; + osRtxInfo.thread.robin.tick = osRtxInfo.thread.robin.timeout; + } + } + } + } + } +} + +/// Pending Service Call Handler. +//lint -esym(714,osRtxPendSV_Handler) "Referenced by Exception handlers" +//lint -esym(759,osRtxPendSV_Handler) "Prototype in header" +//lint -esym(765,osRtxPendSV_Handler) "Global scope" +void osRtxPendSV_Handler (void) { + os_object_t *object; + + for (;;) { + object = isr_queue_get(); + if (object == NULL) { + break; + } + switch (object->id) { + case osRtxIdThread: + osRtxInfo.post_process.thread(osRtxThreadObject(object)); + break; + case osRtxIdEventFlags: + osRtxInfo.post_process.event_flags(osRtxEventFlagsObject(object)); + break; + case osRtxIdSemaphore: + osRtxInfo.post_process.semaphore(osRtxSemaphoreObject(object)); + break; + case osRtxIdMemoryPool: + osRtxInfo.post_process.memory_pool(osRtxMemoryPoolObject(object)); + break; + case osRtxIdMessage: + osRtxInfo.post_process.message(osRtxMessageObject(object)); + break; + default: + // Should never come here + break; + } + } + + osRtxThreadDispatch(NULL); +} + +/// Register post ISR processing. +/// \param[in] object generic object. +void osRtxPostProcess (os_object_t *object) { + + if (isr_queue_put(object) != 0U) { + if (osRtxInfo.kernel.blocked == 0U) { + SetPendSV(); + } else { + osRtxInfo.kernel.pendSV = 1U; + } + } else { + (void)osRtxErrorNotify(osRtxErrorISRQueueOverflow, object); + } +} diff --git a/rtos/rtx5/rtx_thread.c b/rtos/rtx5/rtx_thread.c new file mode 100644 index 0000000..5b3ae27 --- /dev/null +++ b/rtos/rtx5/rtx_thread.c @@ -0,0 +1,1952 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Thread functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" +#include "hal_timer.h" + +// OS Runtime Object Memory Usage +#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))) +osRtxObjectMemUsage_t osRtxThreadMemUsage \ +__attribute__((section(".data.os.thread.obj"))) = +{ 0U, 0U, 0U }; +#endif + +#if __RTX_CPU_STATISTICS__ +uint32_t rtx_get_hwticks(void) +{ + return hal_sys_timer_get(); +} +#endif + +// ==== Helper functions ==== + +/// Set Thread Flags. +/// \param[in] thread thread object. +/// \param[in] flags specifies the flags to set. +/// \return thread flags after setting. +static uint32_t ThreadFlagsSet (os_thread_t *thread, uint32_t flags) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t thread_flags; + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + thread->thread_flags |= flags; + thread_flags = thread->thread_flags; + + if (primask == 0U) { + __enable_irq(); + } +#else + thread_flags = atomic_set32(&thread->thread_flags, flags); +#endif + + return thread_flags; +} + +/// Clear Thread Flags. +/// \param[in] thread thread object. +/// \param[in] flags specifies the flags to clear. +/// \return thread flags before clearing. +static uint32_t ThreadFlagsClear (os_thread_t *thread, uint32_t flags) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t thread_flags; + +#if (EXCLUSIVE_ACCESS == 0) + __disable_irq(); + + thread_flags = thread->thread_flags; + thread->thread_flags &= ~flags; + + if (primask == 0U) { + __enable_irq(); + } +#else + thread_flags = atomic_clr32(&thread->thread_flags, flags); +#endif + + return thread_flags; +} + +/// Check Thread Flags. +/// \param[in] thread thread object. +/// \param[in] flags specifies the flags to check. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \return thread flags before clearing or 0 if specified flags have not been set. +static uint32_t ThreadFlagsCheck (os_thread_t *thread, uint32_t flags, uint32_t options) { +#if (EXCLUSIVE_ACCESS == 0) + uint32_t primask; +#endif + uint32_t thread_flags; + + if ((options & osFlagsNoClear) == 0U) { +#if (EXCLUSIVE_ACCESS == 0) + primask = __get_PRIMASK(); + __disable_irq(); + + thread_flags = thread->thread_flags; + if ((((options & osFlagsWaitAll) != 0U) && ((thread_flags & flags) != flags)) || + (((options & osFlagsWaitAll) == 0U) && ((thread_flags & flags) == 0U))) { + thread_flags = 0U; + } else { + thread->thread_flags &= ~flags; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if ((options & osFlagsWaitAll) != 0U) { + thread_flags = atomic_chk32_all(&thread->thread_flags, flags); + } else { + thread_flags = atomic_chk32_any(&thread->thread_flags, flags); + } +#endif + } else { + thread_flags = thread->thread_flags; + if ((((options & osFlagsWaitAll) != 0U) && ((thread_flags & flags) != flags)) || + (((options & osFlagsWaitAll) == 0U) && ((thread_flags & flags) == 0U))) { + thread_flags = 0U; + } + } + + return thread_flags; +} + + +// ==== Library functions ==== + +/// Put a Thread into specified Object list sorted by Priority (Highest at Head). +/// \param[in] object generic object. +/// \param[in] thread thread object. +void osRtxThreadListPut (os_object_t *object, os_thread_t *thread) { + os_thread_t *prev, *next; + int32_t priority; + + priority = thread->priority; + + prev = osRtxThreadObject(object); + next = prev->thread_next; + while ((next != NULL) && (next->priority >= priority)) { + prev = next; + next = next->thread_next; + } + thread->thread_prev = prev; + thread->thread_next = next; + prev->thread_next = thread; + if (next != NULL) { + next->thread_prev = thread; + } +} + +/// Get a Thread with Highest Priority from specified Object list and remove it. +/// \param[in] object generic object. +/// \return thread object. +os_thread_t *osRtxThreadListGet (os_object_t *object) { + os_thread_t *thread; + + thread = object->thread_list; + object->thread_list = thread->thread_next; + if (thread->thread_next != NULL) { + thread->thread_next->thread_prev = osRtxThreadObject(object); + } + thread->thread_prev = NULL; + + return thread; +} + +#if (!defined(EVR_RTX_DISABLE) && \ + (((OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_TIMEOUT_DISABLE)) || \ + ((OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_TIMEOUT_DISABLE)) || \ + ((OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_TIMEOUT_DISABLE)) || \ + ((OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_TIMEOUT_DISABLE)) || \ + ((OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_TIMEOUT_DISABLE)) || \ + ((OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_TIMEOUT_DISABLE)))) + +/// Retrieve Thread list root. +/// \param[in] thread thread object. +static void *osRtxThreadListRoot (os_thread_t *thread) { + os_thread_t *thread0; + + thread0 = thread; + while (thread0->id == osRtxIdThread) { + thread0 = thread0->thread_prev; + } + return thread0; +} + +#endif + +/// Re-sort a Thread in linked Object list by Priority (Highest at Head). +/// \param[in] thread thread object. +void osRtxThreadListSort (os_thread_t *thread) { + os_object_t *object; + os_thread_t *thread0; + + // Search for object + thread0 = thread; + while ((thread0 != NULL) && (thread0->id == osRtxIdThread)) { + thread0 = thread0->thread_prev; + } + object = osRtxObject(thread0); + + if (object != NULL) { + osRtxThreadListRemove(thread); + osRtxThreadListPut(object, thread); + } +} + +/// Remove a Thread from linked Object list. +/// \param[in] thread thread object. +void osRtxThreadListRemove (os_thread_t *thread) { + + if (thread->thread_prev != NULL) { + thread->thread_prev->thread_next = thread->thread_next; + if (thread->thread_next != NULL) { + thread->thread_next->thread_prev = thread->thread_prev; + } + thread->thread_prev = NULL; + } +} + +/// Unlink a Thread from specified linked list. +/// \param[in] thread thread object. +static void osRtxThreadListUnlink (os_thread_t **thread_list, os_thread_t *thread) { + + if (thread->thread_next != NULL) { + thread->thread_next->thread_prev = thread->thread_prev; + } + if (thread->thread_prev != NULL) { + thread->thread_prev->thread_next = thread->thread_next; + thread->thread_prev = NULL; + } else { + *thread_list = thread->thread_next; + } +} + +/// Mark a Thread as Ready and put it into Ready list (sorted by Priority). +/// \param[in] thread thread object. +void osRtxThreadReadyPut (os_thread_t *thread) { + + thread->state = osRtxThreadReady; + osRtxThreadListPut(&osRtxInfo.thread.ready, thread); +} + +/// Insert a Thread into the Delay list sorted by Delay (Lowest at Head). +/// \param[in] thread thread object. +/// \param[in] delay delay value. +static void osRtxThreadDelayInsert (os_thread_t *thread, uint32_t delay) { + os_thread_t *prev, *next; + + if (delay == osWaitForever) { + prev = NULL; + next = osRtxInfo.thread.wait_list; + while (next != NULL) { + prev = next; + next = next->delay_next; + } + thread->delay = delay; + thread->delay_prev = prev; + thread->delay_next = NULL; + if (prev != NULL) { + prev->delay_next = thread; + } else { + osRtxInfo.thread.wait_list = thread; + } + } else { + prev = NULL; + next = osRtxInfo.thread.delay_list; + while ((next != NULL) && (next->delay <= delay)) { + delay -= next->delay; + prev = next; + next = next->delay_next; + } + thread->delay = delay; + thread->delay_prev = prev; + thread->delay_next = next; + if (prev != NULL) { + prev->delay_next = thread; + } else { + osRtxInfo.thread.delay_list = thread; + } + if (next != NULL) { + next->delay -= delay; + next->delay_prev = thread; + } + } +} + +/// Remove a Thread from the Delay list. +/// \param[in] thread thread object. +static void osRtxThreadDelayRemove (os_thread_t *thread) { + + if (thread->delay == osWaitForever) { + if (thread->delay_next != NULL) { + thread->delay_next->delay_prev = thread->delay_prev; + } + if (thread->delay_prev != NULL) { + thread->delay_prev->delay_next = thread->delay_next; + thread->delay_prev = NULL; + } else { + osRtxInfo.thread.wait_list = thread->delay_next; + } + } else { + if (thread->delay_next != NULL) { + thread->delay_next->delay += thread->delay; + thread->delay_next->delay_prev = thread->delay_prev; + } + if (thread->delay_prev != NULL) { + thread->delay_prev->delay_next = thread->delay_next; + thread->delay_prev = NULL; + } else { + osRtxInfo.thread.delay_list = thread->delay_next; + } + } +} + +/// Process Thread Delay Tick (executed each System Tick). +void osRtxThreadDelayTick (void) { + os_thread_t *thread; + + thread = osRtxInfo.thread.delay_list; + if (thread == NULL) { + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return; + } + + thread->delay--; + + if (thread->delay == 0U) { + do { + switch (thread->state) { + case osRtxThreadWaitingDelay: + EvrRtxDelayCompleted(thread); + break; + case osRtxThreadWaitingThreadFlags: + EvrRtxThreadFlagsWaitTimeout(thread); + break; + case osRtxThreadWaitingEventFlags: + EvrRtxEventFlagsWaitTimeout((osEventFlagsId_t)osRtxThreadListRoot(thread)); + break; + case osRtxThreadWaitingMutex: + EvrRtxMutexAcquireTimeout((osMutexId_t)osRtxThreadListRoot(thread)); + break; + case osRtxThreadWaitingSemaphore: + EvrRtxSemaphoreAcquireTimeout((osSemaphoreId_t)osRtxThreadListRoot(thread)); + break; + case osRtxThreadWaitingMemoryPool: + EvrRtxMemoryPoolAllocTimeout((osMemoryPoolId_t)osRtxThreadListRoot(thread)); + break; + case osRtxThreadWaitingMessageGet: + EvrRtxMessageQueueGetTimeout((osMessageQueueId_t)osRtxThreadListRoot(thread)); + break; + case osRtxThreadWaitingMessagePut: + EvrRtxMessageQueuePutTimeout((osMessageQueueId_t)osRtxThreadListRoot(thread)); + break; + default: + // Invalid + break; + } + EvrRtxThreadUnblocked(thread, (osRtxThreadRegPtr(thread))[0]); + osRtxThreadListRemove(thread); + osRtxThreadReadyPut(thread); + thread = thread->delay_next; + } while ((thread != NULL) && (thread->delay == 0U)); + if (thread != NULL) { + thread->delay_prev = NULL; + } + osRtxInfo.thread.delay_list = thread; + } +} + +/// Get pointer to Thread registers (R0..R3) +/// \param[in] thread thread object. +/// \return pointer to registers R0-R3. +uint32_t *osRtxThreadRegPtr (const os_thread_t *thread) { + uint32_t addr = thread->sp + StackOffsetR0(thread->stack_frame); + //lint -e{923} -e{9078} "cast from unsigned int to pointer" + return ((uint32_t *)addr); +} + +/// Block running Thread execution and register it as Ready to Run. +/// \param[in] thread running thread object. +static void osRtxThreadBlock (os_thread_t *thread) { + os_thread_t *prev, *next; + int32_t priority; + + thread->state = osRtxThreadReady; + + priority = thread->priority; + + prev = osRtxThreadObject(&osRtxInfo.thread.ready); + next = prev->thread_next; + + while ((next != NULL) && (next->priority > priority)) { + prev = next; + next = next->thread_next; + } + thread->thread_prev = prev; + thread->thread_next = next; + prev->thread_next = thread; + if (next != NULL) { + next->thread_prev = thread; + } + + EvrRtxThreadPreempted(thread); +} + +/// Switch to specified Thread. +/// \param[in] thread thread object. +void osRtxThreadSwitch (os_thread_t *thread) { + + thread->state = osRtxThreadRunning; + osRtxInfo.thread.run.next = thread; +#if __RTX_CPU_STATISTICS__ + if (osRtxInfo.thread.run.curr != thread) { + if (osRtxInfo.thread.run.curr) + osRtxInfo.thread.run.curr->swap_out_time = HWTICKS_TO_MS(rtx_get_hwticks()); + thread->swap_in_time = HWTICKS_TO_MS(rtx_get_hwticks()); + } +#endif + osRtxThreadStackCheck(); + EvrRtxThreadSwitched(thread); +} + +/// Dispatch specified Thread or Ready Thread with Highest Priority. +/// \param[in] thread thread object or NULL. +void osRtxThreadDispatch (os_thread_t *thread) { + uint8_t kernel_state; + os_thread_t *thread_running; + os_thread_t *thread_ready; + + kernel_state = osRtxKernelGetState(); + thread_running = osRtxThreadGetRunning(); + + if (thread == NULL) { + thread_ready = osRtxInfo.thread.ready.thread_list; + if ((kernel_state == osRtxKernelRunning) && + (thread_ready != NULL) && + (thread_ready->priority > thread_running->priority)) { + // Preempt running Thread + osRtxThreadListRemove(thread_ready); + osRtxThreadBlock(thread_running); + osRtxThreadSwitch(thread_ready); + } + } else { + if ((kernel_state == osRtxKernelRunning) && + (thread->priority > thread_running->priority)) { + // Preempt running Thread + osRtxThreadBlock(thread_running); + osRtxThreadSwitch(thread); + } else { + // Put Thread into Ready list + osRtxThreadReadyPut(thread); + } + } +} + +/// Exit Thread wait state. +/// \param[in] thread thread object. +/// \param[in] ret_val return value. +/// \param[in] dispatch dispatch flag. +void osRtxThreadWaitExit (os_thread_t *thread, uint32_t ret_val, bool_t dispatch) { + uint32_t *reg; + + EvrRtxThreadUnblocked(thread, ret_val); + + reg = osRtxThreadRegPtr(thread); + reg[0] = ret_val; + + osRtxThreadDelayRemove(thread); + if (dispatch) { + osRtxThreadDispatch(thread); + } else { + osRtxThreadReadyPut(thread); + } +} + +/// Enter Thread wait state. +/// \param[in] state new thread state. +/// \param[in] timeout timeout. +/// \return true - success, false - failure. +bool_t osRtxThreadWaitEnter (uint8_t state, uint32_t timeout) { + os_thread_t *thread; + + // Check if Kernel is running + if (osRtxKernelGetState() != osRtxKernelRunning) { + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return FALSE; + } + + // Check if any thread is ready + if (osRtxInfo.thread.ready.thread_list == NULL) { + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return FALSE; + } + + // Get running thread + thread = osRtxThreadGetRunning(); + + EvrRtxThreadBlocked(thread, timeout); + + thread->state = state; + osRtxThreadDelayInsert(thread, timeout); + thread = osRtxThreadListGet(&osRtxInfo.thread.ready); + osRtxThreadSwitch(thread); + + return TRUE; +} + +/// Check current running Thread Stack. +//lint -esym(759,osRtxThreadStackCheck) "Prototype in header" +//lint -esym(765,osRtxThreadStackCheck) "Global scope (can be overridden)" +__WEAK void osRtxThreadStackCheck (void) { + os_thread_t *thread; + + thread = osRtxThreadGetRunning(); + if (thread != NULL) { + //lint -e{923} "cast from pointer to unsigned int" + //lint -e{9079} -e{9087} "cast between pointers to different object types" + if ((thread->sp <= (uint32_t)thread->stack_mem) || + (*((uint32_t *)thread->stack_mem) != osRtxStackMagicWord)) { + (void)osRtxErrorNotify(osRtxErrorStackUnderflow, thread); + } + } +} + +#ifdef RTX_TF_M_EXTENSION +/// Get TrustZone Module Identifier of running Thread. +/// \return TrustZone Module Identifier. +uint32_t osRtxTzGetModuleId (void) { + os_thread_t *thread; + uint32_t tz_module; + + thread = osRtxThreadGetRunning(); + if (thread != NULL) { + tz_module = thread->tz_module; + } else { + tz_module = 0U; + } + + return tz_module; +} +#endif + + +// ==== Post ISR processing ==== + +/// Thread post ISR processing. +/// \param[in] thread thread object. +static void osRtxThreadPostProcess (os_thread_t *thread) { + uint32_t thread_flags; + + // Check if Thread is waiting for Thread Flags + if (thread->state == osRtxThreadWaitingThreadFlags) { + thread_flags = ThreadFlagsCheck(thread, thread->wait_flags, thread->flags_options); + if (thread_flags != 0U) { + osRtxThreadWaitExit(thread, thread_flags, FALSE); + EvrRtxThreadFlagsWaitCompleted(thread->wait_flags, thread->flags_options, thread_flags, thread); + } + } +} + + +// ==== Service Calls ==== + +/// Create a thread and add it to Active Threads. +/// \note API identical to osThreadNew +static osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { + os_thread_t *thread; + uint32_t attr_bits; + void *stack_mem; + uint32_t stack_size; + osPriority_t priority; + uint8_t flags; + const char *name; + uint32_t *ptr; + uint32_t n; +#if (DOMAIN_NS == 1) + TZ_ModuleId_t tz_module; + TZ_MemoryId_t tz_memory; +#endif + + // Check parameters + if (func == NULL) { + EvrRtxThreadError(NULL, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + // Process attributes + if (attr != NULL) { + name = attr->name; + attr_bits = attr->attr_bits; + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + thread = attr->cb_mem; + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + stack_mem = attr->stack_mem; + stack_size = attr->stack_size; + priority = attr->priority; +#if (DOMAIN_NS == 1) + tz_module = attr->tz_module; +#endif + if (thread != NULL) { + //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7] + if ((((uint32_t)thread & 3U) != 0U) || (attr->cb_size < sizeof(os_thread_t))) { + EvrRtxThreadError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxThreadError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + if (stack_mem != NULL) { + //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7] + if ((((uint32_t)stack_mem & 7U) != 0U) || (stack_size == 0U)) { + EvrRtxThreadError(NULL, osRtxErrorInvalidThreadStack); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + if (priority == osPriorityNone) { + priority = osPriorityNormal; + } else { + if ((priority < osPriorityIdle) || (priority > osPriorityISR)) { + EvrRtxThreadError(NULL, osRtxErrorInvalidPriority); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + } else { + name = NULL; + attr_bits = 0U; + thread = NULL; + stack_mem = NULL; + stack_size = 0U; + priority = osPriorityNormal; +#if (DOMAIN_NS == 1) + tz_module = 0U; +#endif + } + + // Check stack size + if ((stack_size != 0U) && (((stack_size & 7U) != 0U) || (stack_size < (64U + 8U)))) { + EvrRtxThreadError(NULL, osRtxErrorInvalidThreadStack); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + // Allocate object memory if not provided + if (thread == NULL) { + if (osRtxInfo.mpi.thread != NULL) { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + thread = osRtxMemoryPoolAlloc(osRtxInfo.mpi.thread); + } else { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + thread = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_thread_t), 1U); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + if (thread != NULL) { + uint32_t used; + osRtxThreadMemUsage.cnt_alloc++; + used = osRtxThreadMemUsage.cnt_alloc - osRtxThreadMemUsage.cnt_free; + if (osRtxThreadMemUsage.max_used < used) { + osRtxThreadMemUsage.max_used = used; + } + } +#endif + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + // Allocate stack memory if not provided + if ((thread != NULL) && (stack_mem == NULL)) { + if (stack_size == 0U) { + stack_size = osRtxConfig.thread_stack_size; + if (osRtxInfo.mpi.stack != NULL) { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + stack_mem = osRtxMemoryPoolAlloc(osRtxInfo.mpi.stack); + if (stack_mem != NULL) { + flags |= osRtxThreadFlagDefStack; + } + } else { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + stack_mem = osRtxMemoryAlloc(osRtxInfo.mem.stack, stack_size, 0U); + } + } else { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + stack_mem = osRtxMemoryAlloc(osRtxInfo.mem.stack, stack_size, 0U); + } + if (stack_mem == NULL) { + if ((flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.thread != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, thread); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxThreadMemUsage.cnt_free++; +#endif + } + thread = NULL; + } + flags |= osRtxFlagSystemMemory; + } + +#if (DOMAIN_NS == 1) + // Allocate secure process stack + if ((thread != NULL) && (tz_module != 0U)) { + tz_memory = TZ_AllocModuleContext_S(tz_module); + if (tz_memory == 0U) { + EvrRtxThreadError(NULL, osRtxErrorTZ_AllocContext_S); + if ((flags & osRtxFlagSystemMemory) != 0U) { + if ((flags & osRtxThreadFlagDefStack) != 0U) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.stack, thread->stack_mem); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.stack, thread->stack_mem); + } + } + if ((flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.thread != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, thread); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxThreadMemUsage.cnt_free++; +#endif + } + thread = NULL; + } + } else { + tz_memory = 0U; + } +#endif + + if (thread != NULL) { + // Initialize control block + //lint --e{923} --e{9078} "cast between pointers and unsigned int" + //lint --e{9079} --e{9087} "cast between pointers to different object types" + //lint --e{9074} "conversion between a pointer to function and another type" + thread->id = osRtxIdThread; + thread->state = osRtxThreadReady; + thread->flags = flags; + thread->attr = (uint8_t)attr_bits; + thread->name = name; + thread->thread_next = NULL; + thread->thread_prev = NULL; + thread->delay_next = NULL; + thread->delay_prev = NULL; + thread->thread_join = NULL; + thread->delay = 0U; + thread->priority = (int8_t)priority; + thread->priority_base = (int8_t)priority; + thread->stack_frame = STACK_FRAME_INIT_VAL; + thread->flags_options = 0U; + thread->wait_flags = 0U; + thread->thread_flags = 0U; + thread->mutex_list = NULL; + thread->stack_mem = stack_mem; + thread->stack_size = stack_size; + thread->sp = (uint32_t)stack_mem + stack_size - 64U; + thread->thread_addr = (uint32_t)func; + #if (DOMAIN_NS == 1) + thread->tz_memory = tz_memory; + #ifdef RTX_TF_M_EXTENSION + thread->tz_module = tz_module; + #endif + #endif +#if __RTX_CPU_STATISTICS__ + thread->rtime = 0; + thread->step_rtime = 0; +#endif + // Initialize stack + //lint --e{613} false detection: "Possible use of null pointer" + ptr = (uint32_t *)stack_mem; + ptr[0] = osRtxStackMagicWord; + if ((osRtxConfig.flags & osRtxConfigStackWatermark) != 0U) { + for (n = (stack_size/4U) - (16U + 1U); n != 0U; n--) { + ptr++; + *ptr = osRtxStackFillPattern; + } + } + ptr = (uint32_t *)thread->sp; + for (n = 0U; n != 13U; n++) { + ptr[n] = 0U; // R4..R11, R0..R3, R12 + } + ptr[13] = (uint32_t)osThreadExit; // LR + ptr[14] = (uint32_t)func; // PC + ptr[15] = xPSR_InitVal( + (bool_t)((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U), + (bool_t)(((uint32_t)func & 1U) != 0U) + ); // xPSR + ptr[8] = (uint32_t)argument; // R0 + + // Register post ISR processing function + osRtxInfo.post_process.thread = osRtxThreadPostProcess; + + EvrRtxThreadCreated(thread, thread->thread_addr, thread->name); + } else { + EvrRtxThreadError(NULL, (int32_t)osErrorNoMemory); + } + + if (thread != NULL) { + osRtxThreadDispatch(thread); + } + + return thread; +} + +/// Get name of a thread. +/// \note API identical to osThreadGetName +static const char *svcRtxThreadGetName (osThreadId_t thread_id) { + os_thread_t *thread = osRtxThreadId(thread_id); + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadGetName(thread, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + EvrRtxThreadGetName(thread, thread->name); + + return thread->name; +} + +/// Return the thread ID of the current running thread. +/// \note API identical to osThreadGetId +static osThreadId_t svcRtxThreadGetId (void) { + os_thread_t *thread; + + thread = osRtxThreadGetRunning(); + EvrRtxThreadGetId(thread); + return thread; +} + +/// Get current thread state of a thread. +/// \note API identical to osThreadGetState +static osThreadState_t svcRtxThreadGetState (osThreadId_t thread_id) { + os_thread_t *thread = osRtxThreadId(thread_id); + osThreadState_t state; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadGetState(thread, osThreadError); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osThreadError; + } + + state = osRtxThreadState(thread); + + EvrRtxThreadGetState(thread, state); + + return state; +} + +/// Get stack size of a thread. +/// \note API identical to osThreadGetStackSize +static uint32_t svcRtxThreadGetStackSize (osThreadId_t thread_id) { + os_thread_t *thread = osRtxThreadId(thread_id); + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadGetStackSize(thread, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxThreadGetStackSize(thread, thread->stack_size); + + return thread->stack_size; +} + +/// Get available stack space of a thread based on stack watermark recording during execution. +/// \note API identical to osThreadGetStackSpace +static uint32_t svcRtxThreadGetStackSpace (osThreadId_t thread_id) { + os_thread_t *thread = osRtxThreadId(thread_id); + const uint32_t *stack; + uint32_t space; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadGetStackSpace(thread, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + // Check if stack watermark is not enabled + if ((osRtxConfig.flags & osRtxConfigStackWatermark) == 0U) { + EvrRtxThreadGetStackSpace(thread, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + //lint -e{9079} "conversion from pointer to void to pointer to other type" + stack = thread->stack_mem; + if (*stack++ == osRtxStackMagicWord) { + for (space = 4U; space < thread->stack_size; space += 4U) { + if (*stack++ != osRtxStackFillPattern) { + break; + } + } + } else { + space = 0U; + } + + EvrRtxThreadGetStackSpace(thread, space); + + return space; +} + +/// Change priority of a thread. +/// \note API identical to osThreadSetPriority +static osStatus_t svcRtxThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) { + os_thread_t *thread = osRtxThreadId(thread_id); + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread) || + (priority < osPriorityIdle) || (priority > osPriorityISR)) { + EvrRtxThreadError(thread, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check object state + if (thread->state == osRtxThreadTerminated) { + EvrRtxThreadError(thread, (int32_t)osErrorResource); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorResource; + } + + if (thread->priority != (int8_t)priority) { + thread->priority = (int8_t)priority; + thread->priority_base = (int8_t)priority; + EvrRtxThreadPriorityUpdated(thread, priority); + osRtxThreadListSort(thread); + osRtxThreadDispatch(NULL); + } + + return osOK; +} + +/// Get current priority of a thread. +/// \note API identical to osThreadGetPriority +static osPriority_t svcRtxThreadGetPriority (osThreadId_t thread_id) { + os_thread_t *thread = osRtxThreadId(thread_id); + osPriority_t priority; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadGetPriority(thread, osPriorityError); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osPriorityError; + } + + // Check object state + if (thread->state == osRtxThreadTerminated) { + EvrRtxThreadGetPriority(thread, osPriorityError); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osPriorityError; + } + + priority = osRtxThreadPriority(thread); + + EvrRtxThreadGetPriority(thread, priority); + + return priority; +} + +/// Pass control to next thread that is in state READY. +/// \note API identical to osThreadYield +static osStatus_t svcRtxThreadYield (void) { + os_thread_t *thread_running; + os_thread_t *thread_ready; + + if (osRtxKernelGetState() == osRtxKernelRunning) { + thread_running = osRtxThreadGetRunning(); + thread_ready = osRtxInfo.thread.ready.thread_list; + if ((thread_ready != NULL) && + (thread_ready->priority == thread_running->priority)) { + osRtxThreadListRemove(thread_ready); + osRtxThreadReadyPut(thread_running); + EvrRtxThreadPreempted(thread_running); + osRtxThreadSwitch(thread_ready); + } + } + + return osOK; +} + +/// Suspend execution of a thread. +/// \note API identical to osThreadSuspend +static osStatus_t svcRtxThreadSuspend (osThreadId_t thread_id) { + os_thread_t *thread = osRtxThreadId(thread_id); + osStatus_t status; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadError(thread, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check object state + switch (thread->state & osRtxThreadStateMask) { + case osRtxThreadRunning: + if ((osRtxKernelGetState() != osRtxKernelRunning) || + (osRtxInfo.thread.ready.thread_list == NULL)) { + EvrRtxThreadError(thread, (int32_t)osErrorResource); + status = osErrorResource; + } else { + status = osOK; + } + break; + case osRtxThreadReady: + osRtxThreadListRemove(thread); + status = osOK; + break; + case osRtxThreadBlocked: + osRtxThreadListRemove(thread); + osRtxThreadDelayRemove(thread); + status = osOK; + break; + case osRtxThreadInactive: + case osRtxThreadTerminated: + default: + EvrRtxThreadError(thread, (int32_t)osErrorResource); + status = osErrorResource; + break; + } + + if (status == osOK) { + EvrRtxThreadSuspended(thread); + + if (thread->state == osRtxThreadRunning) { + osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready)); + } + + // Update Thread State and put it into Delay list + thread->state = osRtxThreadBlocked; + thread->thread_prev = NULL; + thread->thread_next = NULL; + osRtxThreadDelayInsert(thread, osWaitForever); + } + + return status; +} + +/// Resume execution of a thread. +/// \note API identical to osThreadResume +static osStatus_t svcRtxThreadResume (osThreadId_t thread_id) { + os_thread_t *thread = osRtxThreadId(thread_id); + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadError(thread, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check object state + if ((thread->state & osRtxThreadStateMask) != osRtxThreadBlocked) { + EvrRtxThreadError(thread, (int32_t)osErrorResource); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorResource; + } + + EvrRtxThreadResumed(thread); + + // Wakeup Thread + osRtxThreadListRemove(thread); + osRtxThreadDelayRemove(thread); + osRtxThreadDispatch(thread); + + return osOK; +} + +/// Free Thread resources. +/// \param[in] thread thread object. +static void osRtxThreadFree (os_thread_t *thread) { + + // Mark object as inactive and invalid + thread->state = osRtxThreadInactive; + thread->id = osRtxIdInvalid; + +#if (DOMAIN_NS == 1) + // Free secure process stack + if (thread->tz_memory != 0U) { + (void)TZ_FreeModuleContext_S(thread->tz_memory); + } +#endif + + // Free stack memory + if ((thread->flags & osRtxFlagSystemMemory) != 0U) { + if ((thread->flags & osRtxThreadFlagDefStack) != 0U) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.stack, thread->stack_mem); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.stack, thread->stack_mem); + } + } + + // Free object memory + if ((thread->flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.thread != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, thread); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxThreadMemUsage.cnt_free++; +#endif + } +} + +/// Detach a thread (thread storage can be reclaimed when thread terminates). +/// \note API identical to osThreadDetach +static osStatus_t svcRtxThreadDetach (osThreadId_t thread_id) { + os_thread_t *thread = osRtxThreadId(thread_id); + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadError(thread, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check object attributes + if ((thread->attr & osThreadJoinable) == 0U) { + EvrRtxThreadError(thread, osRtxErrorThreadNotJoinable); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorResource; + } + + if (thread->state == osRtxThreadTerminated) { + osRtxThreadListUnlink(&osRtxInfo.thread.terminate_list, thread); + osRtxThreadFree(thread); + } else { + thread->attr &= ~osThreadJoinable; + } + + EvrRtxThreadDetached(thread); + + return osOK; +} + +/// Wait for specified thread to terminate. +/// \note API identical to osThreadJoin +static osStatus_t svcRtxThreadJoin (osThreadId_t thread_id) { + os_thread_t *thread = osRtxThreadId(thread_id); + osStatus_t status; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadError(thread, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check object attributes + if ((thread->attr & osThreadJoinable) == 0U) { + EvrRtxThreadError(thread, osRtxErrorThreadNotJoinable); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorResource; + } + + // Check object state + if (thread->state == osRtxThreadRunning) { + EvrRtxThreadError(thread, (int32_t)osErrorResource); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorResource; + } + + if (thread->state == osRtxThreadTerminated) { + osRtxThreadListUnlink(&osRtxInfo.thread.terminate_list, thread); + osRtxThreadFree(thread); + EvrRtxThreadJoined(thread); + status = osOK; + } else { + // Suspend current Thread + if (osRtxThreadWaitEnter(osRtxThreadWaitingJoin, osWaitForever)) { + thread->thread_join = osRtxThreadGetRunning(); + thread->attr &= ~osThreadJoinable; + EvrRtxThreadJoinPending(thread); + } else { + EvrRtxThreadError(thread, (int32_t)osErrorResource); + } + status = osErrorResource; + } + + return status; +} + +/// Terminate execution of current running thread. +/// \note API identical to osThreadExit +static void svcRtxThreadExit (void) { + os_thread_t *thread; + + // Check if switch to next Ready Thread is possible + if ((osRtxKernelGetState() != osRtxKernelRunning) || + (osRtxInfo.thread.ready.thread_list == NULL)) { + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return; + } + + // Get running thread + thread = osRtxThreadGetRunning(); + + // Release owned Mutexes + osRtxMutexOwnerRelease(thread->mutex_list); + + // Wakeup Thread waiting to Join + if (thread->thread_join != NULL) { + osRtxThreadWaitExit(thread->thread_join, (uint32_t)osOK, FALSE); + EvrRtxThreadJoined(thread->thread_join); + } + + // Switch to next Ready Thread + thread->sp = __get_PSP(); + osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready)); + osRtxThreadSetRunning(NULL); + + if ((thread->attr & osThreadJoinable) == 0U) { + osRtxThreadFree(thread); + } else { + // Update Thread State and put it into Terminate Thread list + thread->state = osRtxThreadTerminated; + thread->thread_prev = NULL; + thread->thread_next = osRtxInfo.thread.terminate_list; + if (osRtxInfo.thread.terminate_list != NULL) { + osRtxInfo.thread.terminate_list->thread_prev = thread; + } + osRtxInfo.thread.terminate_list = thread; + } + + EvrRtxThreadDestroyed(thread); +} + +/// Terminate execution of a thread. +/// \note API identical to osThreadTerminate +static osStatus_t svcRtxThreadTerminate (osThreadId_t thread_id) { + os_thread_t *thread = osRtxThreadId(thread_id); + osStatus_t status; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadError(thread, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check object state + switch (thread->state & osRtxThreadStateMask) { + case osRtxThreadRunning: + if ((osRtxKernelGetState() != osRtxKernelRunning) || + (osRtxInfo.thread.ready.thread_list == NULL)) { + EvrRtxThreadError(thread, (int32_t)osErrorResource); + status = osErrorResource; + } else { + status = osOK; + } + break; + case osRtxThreadReady: + osRtxThreadListRemove(thread); + status = osOK; + break; + case osRtxThreadBlocked: + osRtxThreadListRemove(thread); + osRtxThreadDelayRemove(thread); + status = osOK; + break; + case osRtxThreadInactive: + case osRtxThreadTerminated: + default: + EvrRtxThreadError(thread, (int32_t)osErrorResource); + status = osErrorResource; + break; + } + + if (status == osOK) { + // Release owned Mutexes + osRtxMutexOwnerRelease(thread->mutex_list); + + // Wakeup Thread waiting to Join + if (thread->thread_join != NULL) { + osRtxThreadWaitExit(thread->thread_join, (uint32_t)osOK, FALSE); + EvrRtxThreadJoined(thread->thread_join); + } + + // Switch to next Ready Thread when terminating running Thread + if (thread->state == osRtxThreadRunning) { + thread->sp = __get_PSP(); + osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready)); + osRtxThreadSetRunning(NULL); + } else { + osRtxThreadDispatch(NULL); + } + + if ((thread->attr & osThreadJoinable) == 0U) { + osRtxThreadFree(thread); + } else { + // Update Thread State and put it into Terminate Thread list + thread->state = osRtxThreadTerminated; + thread->thread_prev = NULL; + thread->thread_next = osRtxInfo.thread.terminate_list; + if (osRtxInfo.thread.terminate_list != NULL) { + osRtxInfo.thread.terminate_list->thread_prev = thread; + } + osRtxInfo.thread.terminate_list = thread; + } + + EvrRtxThreadDestroyed(thread); + } + + return status; +} + +/// Get number of active threads. +/// \note API identical to osThreadGetCount +static uint32_t svcRtxThreadGetCount (void) { + const os_thread_t *thread; + uint32_t count; + + // Running Thread + count = 1U; + + // Ready List + for (thread = osRtxInfo.thread.ready.thread_list; + thread != NULL; thread = thread->thread_next) { + count++; + } + + // Delay List + for (thread = osRtxInfo.thread.delay_list; + thread != NULL; thread = thread->delay_next) { + count++; + } + + // Wait List + for (thread = osRtxInfo.thread.wait_list; + thread != NULL; thread = thread->delay_next) { + count++; + } + + EvrRtxThreadGetCount(count); + + return count; +} + +/// Enumerate active threads. +/// \note API identical to osThreadEnumerate +static uint32_t svcRtxThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) { + os_thread_t *thread; + uint32_t count; + + // Check parameters + if ((thread_array == NULL) || (array_items == 0U)) { + EvrRtxThreadEnumerate(thread_array, array_items, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + // Running Thread + *thread_array = osRtxThreadGetRunning(); + thread_array++; + count = 1U; + + // Ready List + for (thread = osRtxInfo.thread.ready.thread_list; + (thread != NULL) && (count < array_items); thread = thread->thread_next) { + *thread_array = thread; + thread_array++; + count++; + } + + // Delay List + for (thread = osRtxInfo.thread.delay_list; + (thread != NULL) && (count < array_items); thread = thread->delay_next) { + *thread_array = thread; + thread_array++; + count++; + } + + // Wait List + for (thread = osRtxInfo.thread.wait_list; + (thread != NULL) && (count < array_items); thread = thread->delay_next) { + *thread_array = thread; + thread_array++; + count++; + } + + EvrRtxThreadEnumerate(thread_array - count, array_items, count); + + return count; +} + +/// Set the specified Thread Flags of a thread. +/// \note API identical to osThreadFlagsSet +static uint32_t svcRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { + os_thread_t *thread = osRtxThreadId(thread_id); + uint32_t thread_flags; + uint32_t thread_flags0; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread) || + ((flags & ~(((uint32_t)1U << osRtxThreadFlagsLimit) - 1U)) != 0U)) { + EvrRtxThreadFlagsError(thread, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorParameter); + } + + // Check object state + if (thread->state == osRtxThreadTerminated) { + EvrRtxThreadFlagsError(thread, (int32_t)osErrorResource); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorResource); + } + + // Set Thread Flags + thread_flags = ThreadFlagsSet(thread, flags); + + // Check if Thread is waiting for Thread Flags + if (thread->state == osRtxThreadWaitingThreadFlags) { + thread_flags0 = ThreadFlagsCheck(thread, thread->wait_flags, thread->flags_options); + if (thread_flags0 != 0U) { + if ((thread->flags_options & osFlagsNoClear) == 0U) { + thread_flags = thread_flags0 & ~thread->wait_flags; + } else { + thread_flags = thread_flags0; + } + osRtxThreadWaitExit(thread, thread_flags0, TRUE); + EvrRtxThreadFlagsWaitCompleted(thread->wait_flags, thread->flags_options, thread_flags0, thread); + } + } + + EvrRtxThreadFlagsSetDone(thread, thread_flags); + + return thread_flags; +} + +/// Clear the specified Thread Flags of current running thread. +/// \note API identical to osThreadFlagsClear +static uint32_t svcRtxThreadFlagsClear (uint32_t flags) { + os_thread_t *thread; + uint32_t thread_flags; + + // Check running thread + thread = osRtxThreadGetRunning(); + if (thread == NULL) { + EvrRtxThreadFlagsError(NULL, osRtxErrorKernelNotRunning); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osError); + } + + // Check parameters + if ((flags & ~(((uint32_t)1U << osRtxThreadFlagsLimit) - 1U)) != 0U) { + EvrRtxThreadFlagsError(thread, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorParameter); + } + + // Clear Thread Flags + thread_flags = ThreadFlagsClear(thread, flags); + + EvrRtxThreadFlagsClearDone(thread_flags); + + return thread_flags; +} + +/// Get the current Thread Flags of current running thread. +/// \note API identical to osThreadFlagsGet +static uint32_t svcRtxThreadFlagsGet (void) { + const os_thread_t *thread; + + // Check running thread + thread = osRtxThreadGetRunning(); + if (thread == NULL) { + EvrRtxThreadFlagsGet(0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + EvrRtxThreadFlagsGet(thread->thread_flags); + + return thread->thread_flags; +} + +/// Wait for one or more Thread Flags of the current running thread to become signaled. +/// \note API identical to osThreadFlagsWait +static uint32_t svcRtxThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) { + os_thread_t *thread; + uint32_t thread_flags; + + // Check running thread + thread = osRtxThreadGetRunning(); + if (thread == NULL) { + EvrRtxThreadFlagsError(NULL, osRtxErrorKernelNotRunning); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osError); + } + + // Check parameters + if ((flags & ~(((uint32_t)1U << osRtxThreadFlagsLimit) - 1U)) != 0U) { + EvrRtxThreadFlagsError(thread, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorParameter); + } + + // Check Thread Flags + thread_flags = ThreadFlagsCheck(thread, flags, options); + if (thread_flags != 0U) { + EvrRtxThreadFlagsWaitCompleted(flags, options, thread_flags, thread); + } else { + // Check if timeout is specified + if (timeout != 0U) { + // Store waiting flags and options + EvrRtxThreadFlagsWaitPending(flags, options, timeout); + thread->wait_flags = flags; + thread->flags_options = (uint8_t)options; + // Suspend current Thread + if (!osRtxThreadWaitEnter(osRtxThreadWaitingThreadFlags, timeout)) { + EvrRtxThreadFlagsWaitTimeout(thread); + } + thread_flags = (uint32_t)osErrorTimeout; + } else { + EvrRtxThreadFlagsWaitNotCompleted(flags, options); + thread_flags = (uint32_t)osErrorResource; + } + } + return thread_flags; +} +#if TASK_HUNG_CHECK_ENABLED +osStatus_t svcRtxThreadSetHungCheck (osThreadId_t thread_id, int32_t enable, uint32_t timeout) { + os_thread_t *thread = osRtxThreadId(thread_id); + + if (thread == NULL) + return osErrorParameter; + + thread->hung_check = !!enable; + thread->hung_check_timeout = timeout; + return osOK; +} +#endif + +int rtx_task_idle_health_check(void) +{ + return 0; +} + +// Service Calls definitions +//lint ++flb "Library Begin" [MISRA Note 11] +SVC0_3 (ThreadNew, osThreadId_t, osThreadFunc_t, void *, const osThreadAttr_t *) +SVC0_1 (ThreadGetName, const char *, osThreadId_t) +SVC0_0 (ThreadGetId, osThreadId_t) +SVC0_1 (ThreadGetState, osThreadState_t, osThreadId_t) +SVC0_1 (ThreadGetStackSize, uint32_t, osThreadId_t) +SVC0_1 (ThreadGetStackSpace, uint32_t, osThreadId_t) +SVC0_2 (ThreadSetPriority, osStatus_t, osThreadId_t, osPriority_t) +SVC0_1 (ThreadGetPriority, osPriority_t, osThreadId_t) +SVC0_0 (ThreadYield, osStatus_t) +SVC0_1 (ThreadSuspend, osStatus_t, osThreadId_t) +SVC0_1 (ThreadResume, osStatus_t, osThreadId_t) +SVC0_1 (ThreadDetach, osStatus_t, osThreadId_t) +SVC0_1 (ThreadJoin, osStatus_t, osThreadId_t) +SVC0_0N(ThreadExit, void) +SVC0_1 (ThreadTerminate, osStatus_t, osThreadId_t) +SVC0_0 (ThreadGetCount, uint32_t) +SVC0_2 (ThreadEnumerate, uint32_t, osThreadId_t *, uint32_t) +SVC0_2 (ThreadFlagsSet, uint32_t, osThreadId_t, uint32_t) +SVC0_1 (ThreadFlagsClear, uint32_t, uint32_t) +SVC0_0 (ThreadFlagsGet, uint32_t) +SVC0_3 (ThreadFlagsWait, uint32_t, uint32_t, uint32_t, uint32_t) +#if TASK_HUNG_CHECK_ENABLED +SVC0_3 (ThreadSetHungCheck, osStatus_t, osThreadId_t, int32_t, uint32_t) +#endif +//lint --flb "Library End" + + +// ==== ISR Calls ==== + +/// Set the specified Thread Flags of a thread. +/// \note API identical to osThreadFlagsSet +__STATIC_INLINE +uint32_t isrRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { + os_thread_t *thread = osRtxThreadId(thread_id); + uint32_t thread_flags; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread) || + ((flags & ~(((uint32_t)1U << osRtxThreadFlagsLimit) - 1U)) != 0U)) { + EvrRtxThreadFlagsError(thread, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorParameter); + } + + // Check object state + if (thread->state == osRtxThreadTerminated) { + EvrRtxThreadFlagsError(thread, (int32_t)osErrorResource); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return ((uint32_t)osErrorResource); + } + + // Set Thread Flags + thread_flags = ThreadFlagsSet(thread, flags); + + // Register post ISR processing + osRtxPostProcess(osRtxObject(thread)); + + EvrRtxThreadFlagsSetDone(thread, thread_flags); + + return thread_flags; +} + + +// ==== Library functions ==== + +/// Thread startup (Idle and Timer Thread). +/// \return true - success, false - failure. +bool_t osRtxThreadStartup (void) { + bool_t ret = TRUE; + + // Create Idle Thread + osRtxInfo.thread.idle = osRtxThreadId( + svcRtxThreadNew(osRtxIdleThread, NULL, osRtxConfig.idle_thread_attr) + ); + + // Create Timer Thread + if (osRtxConfig.timer_mq_mcnt != 0U) { + osRtxInfo.timer.thread = osRtxThreadId( + svcRtxThreadNew(osRtxTimerThread, NULL, osRtxConfig.timer_thread_attr) + ); + if (osRtxInfo.timer.thread == NULL) { + ret = FALSE; + } + } + + return ret; +} + + +// ==== Public API ==== + +/// Create a thread and add it to Active Threads. +osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { + osThreadId_t thread_id; + + EvrRtxThreadNew(func, argument, attr); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadError(NULL, (int32_t)osErrorISR); + thread_id = NULL; + } else { + thread_id = __svcThreadNew(func, argument, attr); + } + return thread_id; +} + +/// Get name of a thread. +const char *osThreadGetName (osThreadId_t thread_id) { + const char *name; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadGetName(thread_id, NULL); + name = NULL; + } else { + name = __svcThreadGetName(thread_id); + } + return name; +} + +/// Return the thread ID of the current running thread. +osThreadId_t osThreadGetId (void) { + osThreadId_t thread_id; + + if (IsIrqMode() || IsIrqMasked()) { + thread_id = svcRtxThreadGetId(); + } else { + thread_id = __svcThreadGetId(); + } + return thread_id; +} + +const char *osGetThreadName (void) { + os_thread_t *thread = osRtxThreadId(osThreadGetId()); + return thread->name; +} + +/// Get current thread state of a thread. +osThreadState_t osThreadGetState (osThreadId_t thread_id) { + osThreadState_t state; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadGetState(thread_id, osThreadError); + state = osThreadError; + } else { + state = __svcThreadGetState(thread_id); + } + return state; +} + +/// Get stack size of a thread. +uint32_t osThreadGetStackSize (osThreadId_t thread_id) { + uint32_t stack_size; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadGetStackSize(thread_id, 0U); + stack_size = 0U; + } else { + stack_size = __svcThreadGetStackSize(thread_id); + } + return stack_size; +} + + +/// Get available stack space of a thread based on stack watermark recording during execution. +uint32_t osThreadGetStackSpace (osThreadId_t thread_id) { + uint32_t stack_space; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadGetStackSpace(thread_id, 0U); + stack_space = 0U; + } else { + stack_space = __svcThreadGetStackSpace(thread_id); + } + return stack_space; +} + +/// Change priority of a thread. +osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) { + osStatus_t status; + + EvrRtxThreadSetPriority(thread_id, priority); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadError(thread_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcThreadSetPriority(thread_id, priority); + } + return status; +} + +/// Get current priority of a thread. +osPriority_t osThreadGetPriority (osThreadId_t thread_id) { + osPriority_t priority; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadGetPriority(thread_id, osPriorityError); + priority = osPriorityError; + } else { + priority = __svcThreadGetPriority(thread_id); + } + return priority; +} + +/// Pass control to next thread that is in state READY. +osStatus_t osThreadYield (void) { + osStatus_t status; + + EvrRtxThreadYield(); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadError(NULL, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcThreadYield(); + } + return status; +} + +/// Suspend execution of a thread. +osStatus_t osThreadSuspend (osThreadId_t thread_id) { + osStatus_t status; + + EvrRtxThreadSuspend(thread_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadError(thread_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcThreadSuspend(thread_id); + } + return status; +} + +/// Resume execution of a thread. +osStatus_t osThreadResume (osThreadId_t thread_id) { + osStatus_t status; + + EvrRtxThreadResume(thread_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadError(thread_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcThreadResume(thread_id); + } + return status; +} + +/// Detach a thread (thread storage can be reclaimed when thread terminates). +osStatus_t osThreadDetach (osThreadId_t thread_id) { + osStatus_t status; + + EvrRtxThreadDetach(thread_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadError(thread_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcThreadDetach(thread_id); + } + return status; +} + +/// Wait for specified thread to terminate. +osStatus_t osThreadJoin (osThreadId_t thread_id) { + osStatus_t status; + + EvrRtxThreadJoin(thread_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadError(thread_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcThreadJoin(thread_id); + } + return status; +} + +/// Terminate execution of current running thread. +__NO_RETURN void osThreadExit (void) { + EvrRtxThreadExit(); + __svcThreadExit(); + EvrRtxThreadError(NULL, (int32_t)osError); + for (;;) {} +} + +/// Terminate execution of a thread. +osStatus_t osThreadTerminate (osThreadId_t thread_id) { + osStatus_t status; + + EvrRtxThreadTerminate(thread_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadError(thread_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcThreadTerminate(thread_id); + } + return status; +} + +/// Get number of active threads. +uint32_t osThreadGetCount (void) { + uint32_t count; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadGetCount(0U); + count = 0U; + } else { + count = __svcThreadGetCount(); + } + return count; +} + +/// Enumerate active threads. +uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) { + uint32_t count; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadEnumerate(thread_array, array_items, 0U); + count = 0U; + } else { + count = __svcThreadEnumerate(thread_array, array_items); + } + return count; +} + +/// Set the specified Thread Flags of a thread. +uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { + uint32_t thread_flags; + + EvrRtxThreadFlagsSet(thread_id, flags); + if (IsIrqMode() || IsIrqMasked()) { + thread_flags = isrRtxThreadFlagsSet(thread_id, flags); + } else { + thread_flags = __svcThreadFlagsSet(thread_id, flags); + } + return thread_flags; +} + +/// Clear the specified Thread Flags of current running thread. +uint32_t osThreadFlagsClear (uint32_t flags) { + uint32_t thread_flags; + + EvrRtxThreadFlagsClear(flags); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadFlagsError(NULL, (int32_t)osErrorISR); + thread_flags = (uint32_t)osErrorISR; + } else { + thread_flags = __svcThreadFlagsClear(flags); + } + return thread_flags; +} + +/// Get the current Thread Flags of current running thread. +uint32_t osThreadFlagsGet (void) { + uint32_t thread_flags; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadFlagsGet(0U); + thread_flags = 0U; + } else { + thread_flags = __svcThreadFlagsGet(); + } + return thread_flags; +} + +/// Wait for one or more Thread Flags of the current running thread to become signaled. +uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) { + uint32_t thread_flags; + + EvrRtxThreadFlagsWait(flags, options, timeout); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxThreadFlagsError(NULL, (int32_t)osErrorISR); + thread_flags = (uint32_t)osErrorISR; + } else { + thread_flags = __svcThreadFlagsWait(flags, options, timeout); + } + return thread_flags; +} +#if TASK_HUNG_CHECK_ENABLED +/// enable/disable the hung check feature of an active thread +osStatus_t osThreadSetHungCheck (osThreadId_t thread_id, int32_t enable, uint32_t timeout) { + if (IsIrqMode() || IsIrqMasked()) + return osErrorISR; // Not allowed in ISR + return __svcThreadSetHungCheck(thread_id, enable, timeout); +} +#endif diff --git a/rtos/rtx5/rtx_thread_dump.c b/rtos/rtx5/rtx_thread_dump.c new file mode 100644 index 0000000..b70cb4e --- /dev/null +++ b/rtos/rtx5/rtx_thread_dump.c @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Thread functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" +#include "plat_addr_map.h" +#include "hal_location.h" +#include "hal_trace.h" +#include "hal_timer.h" + +#define RTX_DUMP_VERBOSE + +struct IRQ_STACK_FRAME_T { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t xpsr; +}; + +extern uint32_t __StackTop[]; + +static inline uint32_t get_IPSR(void) +{ + uint32_t result; + + asm volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + +static inline uint32_t get_PSP(void) +{ + uint32_t result; + + asm volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + +static inline struct IRQ_STACK_FRAME_T *_rtx_get_irq_stack_frame(const os_thread_t *thread) +{ + uint32_t sp; + + if (thread == NULL) { + return NULL; + } + if (thread == osRtxThreadGetRunning() && get_IPSR() == 0) { + return NULL; + } + if (thread == osRtxThreadGetRunning()) { + sp = get_PSP(); + } else { + sp = thread->sp; + } + if ((sp & 3) || !hal_trace_address_writable(sp)) { + return NULL; + } + + if (thread != osRtxThreadGetRunning()) { + // r4-r11 + sp += 4 * 8; + if ((thread->stack_frame & 0x10) == 0) { + // s16-s31 + sp += 4 * 16; + } + } + + return (struct IRQ_STACK_FRAME_T *)sp; +} + +FLASH_TEXT_LOC +void rtx_thread_show(const os_thread_t *thread) +{ + const char *thread_st_str; + struct IRQ_STACK_FRAME_T *frame; + + if (thread) { + switch (thread->state) { + case osRtxThreadInactive: + thread_st_str = "INACTIVE"; + break; + case osRtxThreadReady: + thread_st_str = "READY"; + break; + case osRtxThreadRunning: + thread_st_str = "RUNNING"; + break; + case osRtxThreadTerminated: + thread_st_str = "TERMINAT"; + break; + case osRtxThreadWaitingDelay: + thread_st_str = "WAIT_DLY"; + break; + case osRtxThreadWaitingJoin: + thread_st_str = "WAIT_JOIN"; + break; + case osRtxThreadWaitingThreadFlags: + thread_st_str = "WAIT_FLAG"; + break; + case osRtxThreadWaitingEventFlags: + thread_st_str = "WAIT_EVE"; + break; + case osRtxThreadWaitingMutex: + thread_st_str = "WAIT_MUT"; + break; + case osRtxThreadWaitingSemaphore: + thread_st_str = "WAIT_SEM"; + break; + case osRtxThreadWaitingMemoryPool: + thread_st_str = "WAIT_MEM"; + break; + case osRtxThreadWaitingMessageGet: + thread_st_str = "WAIT_MGET"; + break; + case osRtxThreadWaitingMessagePut: + thread_st_str = "WAIT_MPUT"; + break; + default: + thread_st_str = "BAD"; + break; + } + REL_TRACE_NOCRLF_NOTS(0,"--- Thread "); + REL_TRACE_NOCRLF_NOTS(1,"name=%s", thread->name ? thread->name : "NULL"); + + REL_TRACE_NOTS(4," thread=0x%x, prio=%u state=%-9s thread_addr=0x%08X", (uint32_t)thread, thread->priority, thread_st_str, thread->thread_addr); +#ifdef RTX_DUMP_VERBOSE + REL_TRACE_NOTS(4," thread_next=0x%08X thread_prev=0x%08X delay_next=0x%08X delay_prev=0x%08X", + (uint32_t)thread->thread_next, (uint32_t)thread->thread_prev, (uint32_t)thread->delay_next, (uint32_t)thread->delay_prev); + REL_TRACE_NOTS(4," thread_join=0x%08X flags_options=%u wait_flags=%u thread_flags=%u", + (uint32_t)thread->thread_join, thread->flags_options, thread->wait_flags, thread->thread_flags); + REL_TRACE_NOTS(3," stack_mem=0x%08X stack_size=%u sp:0x%04x", + (uint32_t)thread->stack_mem, thread->stack_size, thread->sp); +#ifdef __RTX_CPU_STATISTICS__ + REL_TRACE_NOTS(2," swap_in_time=%u swap_out_time=%u", + thread->swap_in_time, thread->swap_out_time); + REL_TRACE_NOCRLF_NOTS(0," after last switch "); + if (thread->swap_in_time <= thread->swap_out_time) + REL_TRACE_NOTS(1,"thread runtime %ums", thread->swap_out_time - thread->swap_in_time); + else + REL_TRACE_NOTS(1,"thread still runing, now %d", HWTICKS_TO_MS(rtx_get_hwticks())); +#endif +#endif /*RTX_DUMP_VERBOSE*/ + + frame = _rtx_get_irq_stack_frame(thread); + if (frame) { + uint32_t stack_end; + uint32_t search_cnt, print_cnt; + + REL_TRACE_NOTS(1," frame:0x%08X", (uint32_t)frame); + REL_TRACE_NOTS(4," R0 =0x%08X R1=0x%08X R2=0x%08X R3 =0x%08X", frame->r0, frame->r1, frame->r2, frame->r3); + REL_TRACE_NOTS(4," R12=0x%08X LR=0x%08X PC=0x%08X XPSR=0x%08X", frame->r12, frame->lr, frame->pc, frame->xpsr); + + stack_end = (uint32_t)thread->stack_mem + thread->stack_size; + if (stack_end > thread->sp) { + search_cnt = (stack_end - thread->sp) / 4; + if (search_cnt > 512) { + search_cnt = 512; + } + print_cnt = 10; + hal_trace_print_backtrace(thread->sp, search_cnt, print_cnt); + } + } + } else { + REL_TRACE_NOTS(0,"--- Thread NONE"); + } + + + REL_TRACE_IMM_NOTS(0," "); +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) + if (hal_trace_crash_dump_onprocess()){ + hal_sys_timer_delay(MS_TO_TICKS(500)); + } +#endif +} + +void rtx_show_all_threads(void) +{ + int i; + const os_thread_t *thread; +#if (defined(DEBUG) || defined(REL_TRACE_ENABLE)) + if (hal_trace_crash_dump_onprocess()){ + for (i = 0; i < 10; i++){ + REL_TRACE_IMM_NOTS(0," "); + REL_TRACE_IMM_NOTS(0," \n"); + hal_sys_timer_delay(MS_TO_TICKS(200)); + } + } +#endif + + REL_TRACE_NOTS(0,"Thread List:"); + + // Current List + REL_TRACE_NOTS(0,"Current List"); + rtx_thread_show(osRtxInfo.thread.run.curr); + + // Next List + if (osRtxInfo.thread.run.next != osRtxInfo.thread.run.curr) { + REL_TRACE_NOTS(0,"Next List"); + rtx_thread_show(osRtxInfo.thread.run.next); + } + + // Ready List + REL_TRACE_NOTS(0,"Ready List"); + for (thread = osRtxInfo.thread.ready.thread_list; + thread != NULL; thread = thread->thread_next) { + rtx_thread_show(thread); + } + + // Delay List + REL_TRACE_NOTS(0,"Delay List"); + for (thread = osRtxInfo.thread.delay_list; + thread != NULL; thread = thread->delay_next) { + rtx_thread_show(thread); + } + + // Wait List + REL_TRACE_NOTS(0,"Wait List"); + for (thread = osRtxInfo.thread.wait_list; + thread != NULL; thread = thread->delay_next) { + rtx_thread_show(thread); + } + + // Terminate List + REL_TRACE_NOTS(0,"Terminate List"); + for (thread = osRtxInfo.thread.terminate_list; + thread != NULL; thread = thread->thread_next) { + rtx_thread_show(thread); + } + + REL_TRACE_IMM_NOTS(0," "); +} + +#if __RTX_CPU_STATISTICS__ + +#if TASK_HUNG_CHECK_ENABLED +FLASH_TEXT_LOC NOINLINE +static void print_hung_task(const os_thread_t *thread, U32 curr_time) +{ + REL_TRACE_IMM_NOTS(2,"Thread \"%s\" blocked for %dms", + thread->name==NULL ? "NULL" : (char *)thread->name, + curr_time - thread->swap_out_time); + ASSERT(0, "Find thread hung "); +} + +static void check_hung_thread(const os_thread_t *thread) +{ + uint32_t curr_hwticks, curr_time; + + if (!thread->hung_check) + return; + + curr_hwticks = hal_sys_timer_get(); + curr_time = HWTICKS_TO_MS(curr_hwticks); + if((curr_time - thread->swap_out_time) > thread->hung_check_timeout) { + print_hung_task(thread, curr_time); + } +} + +void check_hung_threads(void) +{ + const os_thread_t *thread; + // Current List + check_hung_thread(osRtxInfo.thread.run.curr); + + // Next List + if (osRtxInfo.thread.run.next != osRtxInfo.thread.run.curr) + check_hung_thread(osRtxInfo.thread.run.next); + + // Ready List + for (thread = osRtxInfo.thread.ready.thread_list; + thread != NULL; thread = thread->thread_next) { + check_hung_thread(thread); + } + + // Delay List + for (thread = osRtxInfo.thread.delay_list; + thread != NULL; thread = thread->delay_next) { + check_hung_thread(thread); + } + + // Wait List + for (thread = osRtxInfo.thread.wait_list; + thread != NULL; thread = thread->delay_next) { + check_hung_thread(thread); + } + + // Terminate List + for (thread = osRtxInfo.thread.terminate_list; + thread != NULL; thread = thread->thread_next) { + check_hung_thread(thread); + } +} +#endif + +static inline void print_thread_sw_statitics(const os_thread_t *thread) +{ + /* + REL_TRACE_NOTS(3,"--- Thread swap in:%d out=%d runings %d", + thread->swap_in_time, + thread->swap_out_time, + thread->rtime); + */ +} + +FLASH_TEXT_LOC +static void _rtx_show_thread_usage(const os_thread_t *thread, uint32_t sample_time) +{ + if (thread) { + if (thread->thread_addr && thread->stack_mem) { + REL_TRACE_NOTS(4,"--- Thread name=%s cpu=%%%d", + thread->name==NULL ? "null" : (char *)thread->name, + sample_time != 0 ? ((thread->rtime - thread->step_rtime) * 100 / sample_time) : 0); + print_thread_sw_statitics(thread); + ((os_thread_t *)thread)->step_rtime = thread->rtime; + } else { + REL_TRACE_NOTS(0,"--- Thread BAD"); + } + } else { + REL_TRACE_NOTS(0,"--- Thread NONE"); + } +} + +FLASH_TEXT_LOC +void rtx_show_all_threads_usage(void) +{ + const os_thread_t *thread; + static bool first_time = 1; + uint32_t sample_time; + static uint32_t start_sample_time = 0; + + if (first_time) { + start_sample_time = rtx_get_hwticks(); + first_time = 0; + return; + } + + sample_time = HWTICKS_TO_MS(rtx_get_hwticks() - start_sample_time); + REL_TRACE_IMM_NOTS(0," "); + REL_TRACE_NOTS(0,"Thread List:"); + + // Current List + _rtx_show_thread_usage(osRtxInfo.thread.run.curr, sample_time); + + // Next List + if (osRtxInfo.thread.run.next != osRtxInfo.thread.run.curr) + _rtx_show_thread_usage(osRtxInfo.thread.run.next, sample_time); + + // Ready List + for (thread = osRtxInfo.thread.ready.thread_list; + thread != NULL; thread = thread->thread_next) { + _rtx_show_thread_usage(thread, sample_time); + } + + // Delay List + for (thread = osRtxInfo.thread.delay_list; + thread != NULL; thread = thread->delay_next) { + _rtx_show_thread_usage(thread, sample_time); + } + + // Wait List + for (thread = osRtxInfo.thread.wait_list; + thread != NULL; thread = thread->delay_next) { + _rtx_show_thread_usage(thread, sample_time); + } + + // Terminate List + for (thread = osRtxInfo.thread.terminate_list; + thread != NULL; thread = thread->thread_next) { + _rtx_show_thread_usage(thread, sample_time); + } + start_sample_time = rtx_get_hwticks(); + REL_TRACE_IMM_NOTS(0," "); +} + +#endif + diff --git a/rtos/rtx5/rtx_timer.c b/rtos/rtx5/rtx_timer.c new file mode 100644 index 0000000..de3c987 --- /dev/null +++ b/rtos/rtx5/rtx_timer.c @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2013-2019 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. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Timer functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// OS Runtime Object Memory Usage +#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))) +osRtxObjectMemUsage_t osRtxTimerMemUsage \ +__attribute__((section(".data.os.timer.obj"))) = +{ 0U, 0U, 0U }; +#endif + + +// ==== Helper functions ==== + +/// Insert Timer into the Timer List sorted by Time. +/// \param[in] timer timer object. +/// \param[in] tick timer tick. +static void TimerInsert (os_timer_t *timer, uint32_t tick) { + os_timer_t *prev, *next; + + prev = NULL; + next = osRtxInfo.timer.list; + while ((next != NULL) && (next->tick <= tick)) { + tick -= next->tick; + prev = next; + next = next->next; + } + timer->tick = tick; + timer->prev = prev; + timer->next = next; + if (next != NULL) { + next->tick -= timer->tick; + next->prev = timer; + } + if (prev != NULL) { + prev->next = timer; + } else { + osRtxInfo.timer.list = timer; + } +} + +/// Remove Timer from the Timer List. +/// \param[in] timer timer object. +static void TimerRemove (const os_timer_t *timer) { + + if (timer->next != NULL) { + timer->next->tick += timer->tick; + timer->next->prev = timer->prev; + } + if (timer->prev != NULL) { + timer->prev->next = timer->next; + } else { + osRtxInfo.timer.list = timer->next; + } +} + +/// Unlink Timer from the Timer List Head. +/// \param[in] timer timer object. +static void TimerUnlink (const os_timer_t *timer) { + + if (timer->next != NULL) { + timer->next->prev = timer->prev; + } + osRtxInfo.timer.list = timer->next; +} + + +// ==== Library functions ==== + +/// Timer Tick (called each SysTick). +static void osRtxTimerTick (void) { + os_timer_t *timer; + osStatus_t status; + + timer = osRtxInfo.timer.list; + if (timer == NULL) { + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return; + } + + timer->tick--; + while ((timer != NULL) && (timer->tick == 0U)) { + TimerUnlink(timer); + status = osMessageQueuePut(osRtxInfo.timer.mq, &timer->finfo, 0U, 0U); + if (status != osOK) { + (void)osRtxErrorNotify(osRtxErrorTimerQueueOverflow, timer); + } + if (timer->type == osRtxTimerPeriodic) { + TimerInsert(timer, timer->load); + } else { + timer->state = osRtxTimerStopped; + } + timer = osRtxInfo.timer.list; + } +} + +/// Timer Thread +__WEAK __NO_RETURN void osRtxTimerThread (void *argument) { + os_timer_finfo_t finfo; + osStatus_t status; + (void) argument; + + osRtxInfo.timer.mq = osRtxMessageQueueId( + osMessageQueueNew(osRtxConfig.timer_mq_mcnt, sizeof(os_timer_finfo_t), osRtxConfig.timer_mq_attr) + ); + osRtxInfo.timer.tick = osRtxTimerTick; + + for (;;) { + //lint -e{934} "Taking address of near auto variable" + status = osMessageQueueGet(osRtxInfo.timer.mq, &finfo, NULL, osWaitForever); + if (status == osOK) { + EvrRtxTimerCallback(finfo.func, finfo.arg); + (finfo.func)(finfo.arg); + } + } +} + +// ==== Service Calls ==== + +/// Create and Initialize a timer. +/// \note API identical to osTimerNew +static osTimerId_t svcRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) { + os_timer_t *timer; + uint8_t flags; + const char *name; + + // Check parameters + if ((func == NULL) || ((type != osTimerOnce) && (type != osTimerPeriodic))) { + EvrRtxTimerError(NULL, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + // Process attributes + if (attr != NULL) { + name = attr->name; + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6] + timer = attr->cb_mem; + if (timer != NULL) { + //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7] + if ((((uint32_t)timer & 3U) != 0U) || (attr->cb_size < sizeof(os_timer_t))) { + EvrRtxTimerError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxTimerError(NULL, osRtxErrorInvalidControlBlock); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + } + } else { + name = NULL; + timer = NULL; + } + + // Allocate object memory if not provided + if (timer == NULL) { + if (osRtxInfo.mpi.timer != NULL) { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + timer = osRtxMemoryPoolAlloc(osRtxInfo.mpi.timer); + } else { + //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5] + timer = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_timer_t), 1U); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + if (timer != NULL) { + uint32_t used; + osRtxTimerMemUsage.cnt_alloc++; + used = osRtxTimerMemUsage.cnt_alloc - osRtxTimerMemUsage.cnt_free; + if (osRtxTimerMemUsage.max_used < used) { + osRtxTimerMemUsage.max_used = used; + } + } +#endif + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + if (timer != NULL) { + // Initialize control block + timer->id = osRtxIdTimer; + timer->state = osRtxTimerStopped; + timer->flags = flags; + timer->type = (uint8_t)type; + timer->name = name; + timer->prev = NULL; + timer->next = NULL; + timer->tick = 0U; + timer->load = 0U; + timer->finfo.func = func; + timer->finfo.arg = argument; + + EvrRtxTimerCreated(timer, timer->name); + } else { + EvrRtxTimerError(NULL, (int32_t)osErrorNoMemory); + } + + return timer; +} + +/// Get name of a timer. +/// \note API identical to osTimerGetName +static const char *svcRtxTimerGetName (osTimerId_t timer_id) { + os_timer_t *timer = osRtxTimerId(timer_id); + + // Check parameters + if ((timer == NULL) || (timer->id != osRtxIdTimer)) { + EvrRtxTimerGetName(timer, NULL); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return NULL; + } + + EvrRtxTimerGetName(timer, timer->name); + + return timer->name; +} + +/// Start or restart a timer. +/// \note API identical to osTimerStart +static osStatus_t svcRtxTimerStart (osTimerId_t timer_id, uint32_t ticks) { + os_timer_t *timer = osRtxTimerId(timer_id); + + // Check parameters + if ((timer == NULL) || (timer->id != osRtxIdTimer) || (ticks == 0U)) { + EvrRtxTimerError(timer, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + if (timer->state == osRtxTimerRunning) { + TimerRemove(timer); + } else { + if (osRtxInfo.timer.tick == NULL) { + EvrRtxTimerError(timer, (int32_t)osErrorResource); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorResource; + } else { + timer->state = osRtxTimerRunning; + timer->load = ticks; + } + } + + TimerInsert(timer, ticks); + + EvrRtxTimerStarted(timer); + + return osOK; +} + +/// Stop a timer. +/// \note API identical to osTimerStop +static osStatus_t svcRtxTimerStop (osTimerId_t timer_id) { + os_timer_t *timer = osRtxTimerId(timer_id); + + // Check parameters + if ((timer == NULL) || (timer->id != osRtxIdTimer)) { + EvrRtxTimerError(timer, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + // Check object state + if (timer->state != osRtxTimerRunning) { + EvrRtxTimerError(timer, (int32_t)osErrorResource); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorResource; + } + + timer->state = osRtxTimerStopped; + + TimerRemove(timer); + + EvrRtxTimerStopped(timer); + + return osOK; +} + +/// Check if a timer is running. +/// \note API identical to osTimerIsRunning +static uint32_t svcRtxTimerIsRunning (osTimerId_t timer_id) { + os_timer_t *timer = osRtxTimerId(timer_id); + uint32_t is_running; + + // Check parameters + if ((timer == NULL) || (timer->id != osRtxIdTimer)) { + EvrRtxTimerIsRunning(timer, 0U); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return 0U; + } + + if (timer->state == osRtxTimerRunning) { + EvrRtxTimerIsRunning(timer, 1U); + is_running = 1U; + } else { + EvrRtxTimerIsRunning(timer, 0U); + is_running = 0; + } + + return is_running; +} + +/// Delete a timer. +/// \note API identical to osTimerDelete +static osStatus_t svcRtxTimerDelete (osTimerId_t timer_id) { + os_timer_t *timer = osRtxTimerId(timer_id); + + // Check parameters + if ((timer == NULL) || (timer->id != osRtxIdTimer)) { + EvrRtxTimerError(timer, (int32_t)osErrorParameter); + //lint -e{904} "Return statement before end of function" [MISRA Note 1] + return osErrorParameter; + } + + if (timer->state == osRtxTimerRunning) { + TimerRemove(timer); + } + + // Mark object as inactive and invalid + timer->state = osRtxTimerInactive; + timer->id = osRtxIdInvalid; + + // Free object memory + if ((timer->flags & osRtxFlagSystemObject) != 0U) { + if (osRtxInfo.mpi.timer != NULL) { + (void)osRtxMemoryPoolFree(osRtxInfo.mpi.timer, timer); + } else { + (void)osRtxMemoryFree(osRtxInfo.mem.common, timer); + } +#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)) + osRtxTimerMemUsage.cnt_free++; +#endif + } + + EvrRtxTimerDestroyed(timer); + + return osOK; +} + +// Service Calls definitions +//lint ++flb "Library Begin" [MISRA Note 11] +SVC0_4(TimerNew, osTimerId_t, osTimerFunc_t, osTimerType_t, void *, const osTimerAttr_t *) +SVC0_1(TimerGetName, const char *, osTimerId_t) +SVC0_2(TimerStart, osStatus_t, osTimerId_t, uint32_t) +SVC0_1(TimerStop, osStatus_t, osTimerId_t) +SVC0_1(TimerIsRunning, uint32_t, osTimerId_t) +SVC0_1(TimerDelete, osStatus_t, osTimerId_t) +//lint --flb "Library End" + + +// ==== Public API ==== + +/// Create and Initialize a timer. +osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) { + osTimerId_t timer_id; + + EvrRtxTimerNew(func, type, argument, attr); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxTimerError(NULL, (int32_t)osErrorISR); + timer_id = NULL; + } else { + timer_id = __svcTimerNew(func, type, argument, attr); + } + return timer_id; +} + +/// Get name of a timer. +const char *osTimerGetName (osTimerId_t timer_id) { + const char *name; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxTimerGetName(timer_id, NULL); + name = NULL; + } else { + name = __svcTimerGetName(timer_id); + } + return name; +} + +/// Start or restart a timer. +osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) { + osStatus_t status; + + EvrRtxTimerStart(timer_id, ticks); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxTimerError(timer_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcTimerStart(timer_id, ticks); + } + return status; +} + +/// Stop a timer. +osStatus_t osTimerStop (osTimerId_t timer_id) { + osStatus_t status; + + EvrRtxTimerStop(timer_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxTimerError(timer_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcTimerStop(timer_id); + } + return status; +} + +/// Check if a timer is running. +uint32_t osTimerIsRunning (osTimerId_t timer_id) { + uint32_t is_running; + + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxTimerIsRunning(timer_id, 0U); + is_running = 0U; + } else { + is_running = __svcTimerIsRunning(timer_id); + } + return is_running; +} + +/// Delete a timer. +osStatus_t osTimerDelete (osTimerId_t timer_id) { + osStatus_t status; + + EvrRtxTimerDelete(timer_id); + if (IsIrqMode() || IsIrqMasked()) { + EvrRtxTimerError(timer_id, (int32_t)osErrorISR); + status = osErrorISR; + } else { + status = __svcTimerDelete(timer_id); + } + return status; +} diff --git a/scripts/build.mk b/scripts/build.mk new file mode 100644 index 0000000..708fb78 --- /dev/null +++ b/scripts/build.mk @@ -0,0 +1,519 @@ +cur_makefile := $(lastword $(MAKEFILE_LIST)) + +# ========================================================================== +# Building +# ========================================================================== + +src := $(obj) + +PHONY := __build +__build: + +$(cur_makefile): ; + +# Init all relevant variables used in kbuild files so +# 1) they have correct type +# 2) they do not inherit any value from the environment +obj-y := +lib-y := +subdir-y := +archive-custom := +archive-custom-valid := +always := +targets := +EXTRA_AFLAGS := +EXTRA_CFLAGS := +EXTRA_CPPFLAGS := +EXTRA_LDFLAGS := +asflags-y := +ccflags-y := +cppflags-y := +ldflags-y := + +subdir-asflags-y := +subdir-ccflags-y := + +include scripts/include.mk + +# For backward compatibility check that these variables do not change +save-cflags := $(CFLAGS) + +kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) +kbuild-file := $(kbuild-dir)/Makefile +include $(kbuild-file) + +$(kbuild-file): ; + +# If the save-* variables changed error out +ifeq ($(KBUILD_NOPEDANTIC),) + ifneq ("$(save-cflags)","$(CFLAGS)") + $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use ccflags-y) + endif +endif + +include scripts/lib.mk + +ifeq ($(WIN_PLAT),y) +create_dir = if not exist $(subst /,\,$(1)) mkdir $(subst /,\,$(1)) +else +create_dir = [ -d $(1) ] || mkdir -p $(1) +endif + +ifneq ($(KBUILD_SRC),) +# Create output directory if not already present +_dummy := $(shell $(call create_dir,$(obj))) + +# Create directories for object files if directory does not exist +# Needed when obj-y := dir/file.o syntax is used +_dummy := $(foreach d,$(obj-dirs), $(shell $(call create_dir,$(d)))) +endif + +ifndef obj +$(warning kbuild: build.mk is included improperly) +endif + +# =========================================================================== + +ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) +lib-target := $(obj)/lib.a +endif + +ifneq ($(strip $(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),) +builtin-target := $(obj)/built-in$(built_in_suffix) +endif + +submodgoals = +SUBMODS := $(filter $(obj)/%,$(SUBMODS)) + +ifneq ($(SUBMODS),) + +lst_target := $(filter %.s %.i %.lst, $(SUBMODS)) +ifeq ($(lib-target),) +ifneq ($(filter $(obj)/lib.lst,$(lst_target)),) +$(error Cannot make lib.lst: lib-target not exists) +endif +endif +ifeq ($(builtin-target),) +ifneq ($(filter $(obj)/built-in.lst,$(lst_target)),) +$(error Cannot make built-in.lst: builtin-target not exists) +endif +endif + +lst_target_obj := $(lst_target) +lst_target_obj := $(filter-out $(obj)/built-in.lst $(obj)/lib.lst,$(lst_target_obj)) +lst_target_obj := $(lst_target_obj:.s=.o) +lst_target_obj := $(lst_target_obj:.i=.o) +lst_target_obj := $(lst_target_obj:.lst=.o) +lst_target_obj := $(sort $(lst_target_obj)) + +cur_submods := $(filter-out $(lst_target),$(SUBMODS)) +cur_submods += $(lst_target_obj) + +include scripts/submods.mk + +buildextra-y := $(filter $(cur_submods),$(extra-y)) + +ifeq ($(filter $(obj)/built-in.lst,$(lst_target)),) + +# Just compile some of the object files +buildsubdir-y := $(call get_subdirs,$(subdir-y),$(cur_submods)) +buildobj-y := $(filter $(cur_submods) $(addsuffix /built-in$(built_in_suffix),$(buildsubdir-y)),$(obj-y)) +buildobj-y += $(foreach m,$(multi-used-y),$(if $(filter $(cur_submods),$(call get_multi_objs,$m))),$m,) + +else + +# Compile all the object files +buildsubdir-y := $(subdir-y) +buildobj-y := $(obj-y) + +endif + +ifeq ($(filter $(obj)/lib.lst,$(lst_target)),) +# Just compile some of the lib files +buildlib-y := $(filter $(cur_submods),$(lib-y)) +else +# Compile all the lib files +buildlib-y := $(lib-y) +endif + +# Check for invalid targets +errobj-y := $(cur_submods) +errobj-y := $(filter-out $(buildsubdir-y) $(addsuffix /%,$(buildsubdir-y)),$(errobj-y)) +errobj-y := $(filter-out $(buildextra-y) $(buildobj-y) $(buildlib-y),$(errobj-y)) +errobj-y := $(filter-out $(foreach m,$(multi-used-y),$(call get_multi_objs,$m)),$(errobj-y)) +ifneq ($(errobj-y),) +$(warning Unknown targets in [$(obj)]: $(errobj-y)) +endif + +# Update lst targets +all_buildobj-y := $(buildextra-y) $(buildobj-y) $(filter-out %.a,$(builtin-target)) +all_buildlib-y := $(filter %.a,$(builtin-target)) $(lib-target) +lst_target := $(filter $(lst_target), \ + $(all_buildobj-y:.o=.s) \ + $(all_buildobj-y:.o=.i) \ + $(all_buildobj-y:.o=.lst) \ + $(patsubst %.a,%.lst,$(all_buildlib-y))) + +# Avoid .o compile error affecting .i generation +lst_i_target := $(filter %.i, $(lst_target)) +ifneq ($(lst_i_target),) +$(lst_i_target:.i=.o) : | $(lst_i_target) +endif + +ifeq ($(COMPILE_ONLY),1) +submodgoals = $(call get_submodgoals,$@,$(SUBMODS)) +endif + +else # SUBMODS + +buildsubdir-y := $(subdir-y) +buildextra-y := $(extra-y) +buildobj-y := $(obj-y) +buildlib-y := $(lib-y) + +endif # SUBMODS + +archive-src-target := +archive-custom-target := +ifeq ($(GEN_LIB),1) +archive-src-target := $(addprefix $(srctree)/$(src)/lib/,$(notdir $(archive-src-y))) +archive-src-target += $(archive-custom-valid) +archive-src-target := $(strip $(archive-src-target)) +archive-custom-target := $(addprefix $(srctree)/$(src)/lib/,$(notdir $(archive-custom-valid))) +endif + +__build: $(builtin-target) $(lib-target) $(buildextra-y) $(buildsubdir-y) $(lst_target) $(archive-src-target) $(archive-custom-target) $(always) + @: + +# Compile C sources (.c) +# --------------------------------------------------------------------------- + +# Default is built-in, unless we know otherwise +quiet_modtag := $(empty) $(empty) + +quiet_cmd_cc_dummy = CC $(quiet_modtag) $@ +cmd_cc_dummy = $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -c -x c -o $@ $(devnull) + +# For dummy object files. Recipe is: $(call if_changed,cc_dummy) + +quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ +cmd_cc_s_c = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< + +$(obj)/%.s: $(src)/%.c FORCE + $(call if_changed_dep,cc_s_c) + +quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@ +cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $< + +$(obj)/%.i: $(src)/%.c FORCE + $(call if_changed_dep,cc_i_c) + +# C (.c) files +# The C file is compiled and updated dependency information is generated. +# (See cmd_cc_o_c + relevant part of rule_cc_o_c) + +quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ +cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< + +define rule_cc_o_c + $(call echo-cmd,cc_o_c) $(cmd_cc_o_c) +endef + +# Built-in and composite module parts +$(obj)/%.o: $(src)/%.c FORCE + $(call if_changed_rule,cc_o_c) + +# Compile C++ sources (.cpp) +# --------------------------------------------------------------------------- + +quiet_cmd_cc_s_c++ = C++ $(quiet_modtag) $@ +cmd_cc_s_c++ = $(CC) $(c++_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< + +$(obj)/%.s: $(src)/%.cpp FORCE + $(call if_changed_dep,cc_s_c++) + +$(obj)/%.s: $(src)/%.cc FORCE + $(call if_changed_dep,cc_s_c++) + +quiet_cmd_cc_i_c++ = CPP $(quiet_modtag) $@ +cmd_cc_i_c++ = $(CPP) $(c++_flags) -o $@ $< + +$(obj)/%.i: $(src)/%.cpp FORCE + $(call if_changed_dep,cc_i_c++) + +$(obj)/%.i: $(src)/%.cc FORCE + $(call if_changed_dep,cc_i_c++) + +# C++ (.cpp) files +# The C++ file is compiled and updated dependency information is generated. +# (See cmd_cc_o_c++ + relevant part of rule_cc_o_c) + +quiet_cmd_cc_o_c++ = C++ $(quiet_modtag) $@ +cmd_cc_o_c++ = $(C++) $(c++_flags) -c -o $@ $< + +define rule_cc_o_c++ + $(call echo-cmd,cc_o_c++) $(cmd_cc_o_c++) +endef + +# Built-in and composite module parts +$(obj)/%.o: $(src)/%.cpp FORCE + $(call if_changed_rule,cc_o_c++) + +$(obj)/%.o: $(src)/%.cc FORCE + $(call if_changed_rule,cc_o_c++) + +# Compile assembler sources (.S) +# --------------------------------------------------------------------------- + +quiet_cmd_as_s_S = CPP $(quiet_modtag) $@ +cmd_as_s_S = $(CPP) $(a_cpp_flags) -o $@ $< + +$(obj)/%.s: $(src)/%.S FORCE + $(call if_changed_dep,as_s_S) + +quiet_cmd_as_o_S = AS $(quiet_modtag) $@ +cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< + +$(obj)/%.o: $(src)/%.S FORCE + $(call if_changed_dep,as_o_S) + +targets += $(real-objs-y) $(real-objs-m) $(lib-y) $(lst_target) +targets += $(MAKECMDGOALS) $(always) + +# Common list command +# --------------------------------------------------------------------------- + +quiet_cmd_dump_lst_o = MKLST $@ +ifeq ($(TOOLCHAIN),armclang) + cmd_dump_lst_o = $(OBJDUMP) --datasymbols --text -c -d --interleave=source --output=$@ $< +else + cmd_dump_lst_o = $(OBJDUMP) -Sdlxr $< > $@ +endif + +lst-cmd = @$(call echo-cmd,dump_lst_o) $(cmd_dump_lst_o) + +$(obj)/%.lst: $(obj)/%.o + $(call lst-cmd) + +# Build the compiled-in targets +# --------------------------------------------------------------------------- + +# To build objects in subdirs, we need to descend into the directories +$(sort $(subdir-obj-y)): $(buildsubdir-y) ; + +# Archive command + +ifeq ($(TOOLCHAIN),armclang) +archive-cmd = $(AR) --create --debug_symbols $@ $(1) +else +ifeq ($(WIN_PLAT),y) +archive-cmd = ( ( echo create $@ && \ + echo addmod $(subst $(space),$(comma),$(strip $(filter-out %.a,$(1)))) && \ + $(foreach o,$(filter %.a,$(1)),echo addlib $o && ) \ + echo save && \ + echo end ) | $(AR) -M ) +else +# Command "/bin/echo -e" cannot work on Apple Mac machines, so we use "/usr/bin/printf" instead +archive-cmd = ( /usr/bin/printf 'create $@\n\ + addmod $(subst $(space),$(comma),$(strip $(filter-out %.a,$(1))))\n\ + $(foreach o,$(filter %.a,$(1)),addlib $o\n)save\nend' | $(AR) -M ) +endif +endif + +# Archive check + +ifeq ($(CHECK_LIB_SRC),1) +ifneq ($(archive-bin-y),) +$(info ) +$(info Library source check OK: $(archive-bin-y)) +$(info ) +endif + +ifneq ($(archive-src-y),) +$(info ) +$(error Error: The source files exist for libraries: $(archive-src-y)) +endif +endif + +# Archive without source files + + cmd_use_lib_file = $(call CMDCPFILE,$<,$@) +quiet_cmd_use_lib_file = USELIB $(@) + +ifneq ($(archive-bin-y),) + +ifeq ($(GEN_LIB),1) +$(info ) +$(warning WARNING: No source files found for libraries: $(archive-bin-y)) +$(info ) +endif + +$(archive-bin-y): $(obj)/%: $(srctree)/$(src)/lib/% FORCE +ifeq ($(FORCE_TO_USE_LIB),1) + $(call cmd,use_lib_file) +else + $(call if_changed,use_lib_file) +endif + +targets += $(archive-bin-y) + +endif # archive-bin-y + +# Archive generation (with source files) + +ifeq ($(GEN_LIB),1) +ifeq ($(FORCE_TO_USE_LIB),1) +$(error Conflicted options: GEN_LIB and FORCE_TO_USE_LIB) +endif +ifneq ($(archive-src-target),) + + cmd_gen_lib_file = ( $(call create_dir,$(dir $(@))) ) && $(call archive-cmd,$(filter-out $(PHONY),$^)) +quiet_cmd_gen_lib_file = GENLIB $(@) + +define archive-src-target-rule +$(1): $(addprefix $(obj)/,$(patsubst %/,%/$(notdir $(builtin-target)),$($(notdir $(1:.a=-y))))) +endef + +$(foreach m, $(archive-src-target), $(eval $(call archive-src-target-rule,$(m)))) + +$(archive-src-target): FORCE +ifeq ($(CHECK_GEN_LIB_DEP),1) + $(call if_changed,gen_lib_file) +else +# Always pack lib + $(call cmd,gen_lib_file) +endif + +targets += $(archive-src-target) + +endif # archive-src-y +endif # GEN_LIB + +# +# Rule to compile a set of .o files into one .o/.a built-in file +# +ifdef builtin-target + +ifeq ($(BUILT-IN-OBJ),1) + +quiet_cmd_link_o_target = LD $@ +# If the list of objects to link is empty, just create an empty built-in.o +ifeq ($(TOOLCHAIN),armclang) + cmd_link_o_target = $(if $(strip $(obj-y)),\ + $(LD) -Wl$(comma)$(subst $(space),$(comma),$(strip $(ld_flags) --partial)) -nostdlib $(LINK_CFLAGS) -o $@ $(obj-y), \ + $(call CMDRMFILE,$@) && $(AR) --create --debug_symbols $@) +else + cmd_link_o_target = $(if $(strip $(obj-y)),\ + $(LD) -Wl$(comma)$(subst $(space),$(comma),$(strip $(ld_flags) -r)) -nostdlib -nostartfiles $(LINK_CFLAGS) -o $@ $(obj-y), \ + $(call CMDRMFILE,$@) && $(AR) rcs$(KBUILD_ARFLAGS) $@) +endif + +$(builtin-target): $(buildobj-y) FORCE + $(call if_changed,link_o_target) + +else # BUILT-IN-OBJ + +quiet_cmd_ar_o_target = AR $@ +cmd_ar_o_target = $(call archive-cmd,$(obj-y)) + +$(builtin-target): $(buildobj-y) FORCE + $(call if_changed,ar_o_target) + +endif # BUILT-IN-OBJ + +targets += $(builtin-target) + +$(obj)/built-in.lst: $(builtin-target) + $(call lst-cmd) + +endif # builtin-target + +# +# Rule to compile a set of .o files into one .a file +# +ifdef lib-target + +quiet_cmd_link_l_target = AR $@ +ifeq ($(TOOLCHAIN),armclang) + cmd_link_l_target = $(call CMDRMFILE,$@) && $(AR) --create --debug_symbols $@ $(lib-y) +else + cmd_link_l_target = $(call CMDRMFILE,$@) && $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y) +endif + +$(lib-target): $(buildlib-y) FORCE + $(call if_changed,link_l_target) + +targets += $(lib-target) + +$(obj)/lib.lst: $(lib-target) + $(call lst-cmd) + +endif + +# +# Rule to link composite objects +# +# Composite objects are specified in kbuild makefile as follows: +# -objs := +# or +# -y := +link_multi_deps = \ +$(filter $(addprefix $(obj)/, \ +$($(subst $(obj)/,,$(@:.o=-objs))) \ +$($(subst $(obj)/,,$(@:.o=-y)))), $^) + +quiet_cmd_link_multi-y = LD $@ +ifeq ($(TOOLCHAIN),armclang) + cmd_link_multi-y = $(LD) -Wl,$(subst $(space),$(comma),$(strip $(ld_flags) --partial)) -nostdlib $(LINK_CFLAGS) -o $@ $(link_multi_deps) +else + cmd_link_multi-y = $(LD) -Wl,$(subst $(space),$(comma),$(strip $(ld_flags) -r --whole-archive)) -nostdlib -nostartfiles $(LINK_CFLAGS) -o $@ $(link_multi_deps) +endif + +$(multi-used-y): FORCE + $(call if_changed,link_multi-y) +$(call multi_depend, $(multi-used-y), .o, -objs -y) + +targets += $(multi-used-y) + +$(multi-used-y:.o=.lst): %.lst : %.o + $(call lst-cmd) + +# Descending +# --------------------------------------------------------------------------- + +PHONY += $(subdir-y) + +$(subdir-y): + $(Q)$(MAKE) $(build)=$@ $(submodgoals) + +# Add FORCE to the prequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +PHONY += FORCE + +FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +targets := $(wildcard $(sort $(targets))) +cmd_files := $(wildcard $(foreach f,$(targets),$(call get_depfile_name,$(f)))) + +ifneq ($(cmd_files),) +include $(cmd_files) +$(cmd_files): ; +endif + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable se we can use it in if_changed and friends. + +.PHONY: $(PHONY) + +# Last-resort default rule for unknown targets + +%:: + @$(call echo-help,*** Error: No rule is defined for target: $@) + @exit 1 + diff --git a/scripts/clean.mk b/scripts/clean.mk new file mode 100644 index 0000000..272ad15 --- /dev/null +++ b/scripts/clean.mk @@ -0,0 +1,179 @@ +cur_makefile := $(lastword $(MAKEFILE_LIST)) + +# ========================================================================== +# Cleaning up +# ========================================================================== + +src := $(obj) + +PHONY := __clean +__clean: + +$(cur_makefile): ; + +# Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir +# Usage: +# $(Q)$(MAKE) $(clean)=dir +clean := -f $(srctree)/scripts/clean.mk obj + +kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) +include $(kbuild-dir)/Makefile + +# Figure out what we need to build from the various variables +# ========================================================================== + +__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) +subdir-y += $(__subdir-y) +__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m))) +subdir-m += $(__subdir-m) +__subdir- := $(patsubst %/,%,$(filter %/, $(obj-))) +subdir- += $(__subdir-) + +# Subdirectories we need to descend into + +subdir-ym := $(sort $(subdir-y) $(subdir-m)) +subdir-ymn := $(sort $(subdir-ym) $(subdir-)) + +obj-ymn := $(obj-y) $(obj-m) $(obj-) +lib-ymn := $(lib-y) $(lib-m) $(lib-) + +# if $(foo-objs) exists, foo.o is a composite object +multi-used-ymn := $(sort $(foreach m,$(obj-ymn), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) +multi-objs-ymn := $(foreach m, $(multi-used-ymn), $($(m:.o=-objs)) $($(m:.o=-y))) + +obj-ymn := $(patsubst %/, %/built-in.o %/built-in.a, $(obj-y) $(obj-m) $(obj-)) + +extra-ymn := $(extra-y) $(extra-m) $(extra-) + +# build a list of files to remove, usually relative to the current +# directory + +__clean-files := $(obj-ymn) $(lib-ymn) $(multi-used-ymn) \ + $(multi-objs-ymn) $(extra-ymn) \ + built-in.o built-in.a lib.a \ + $(always) $(targets) $(clean-files) + +__clean-files := $(filter-out $(no-clean-files), $(__clean-files)) + +# clean-files is given relative to the current directory, unless it +# starts with $(objtree)/ (which means "./", so do not add "./" unless +# you want to delete a file from the toplevel object directory). + +__clean-files := $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \ + $(filter $(objtree)/%, $(__clean-files)) + +# same as clean-files + +__clean-dirs := $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(clean-dirs))) \ + $(filter $(objtree)/%, $(clean-dirs)) + +# Add subdir path +subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn)) +obj-ymn := $(addprefix $(obj)/,$(obj-ymn)) +lib-ymn := $(addprefix $(obj)/,$(lib-ymn)) +multi-used-ymn := $(addprefix $(obj)/,$(multi-used-ymn)) +multi-objs-ymn := $(addprefix $(obj)/,$(multi-objs-ymn)) + +SUBMODS := $(filter $(obj)/%,$(SUBMODS)) + +ifneq ($(SUBMODS),) +include scripts/submods.mk + +buildsubdir-ymn := $(call get_subdirs,$(subdir-ymn),$(SUBMODS)) +__full-clean-files := $(__clean-files) +__clean-files := $(filter $(SUBMODS),$(__full-clean-files)) +__clean-files += $(obj)/built-in.o $(obj)/built-in.a $(obj)/lib.a +__clean-files += $(foreach m,$(multi-used-ymn),$(if $(filter $(SUBMODS),$(call get_multi_objs,$m))),$m,) + +# Check for invalid targets +errobj-ymn := $(SUBMODS) +errobj-ymn := $(filter-out $(buildsubdir-ymn) $(addsuffix /%,$(buildsubdir-ymn)),$(errobj-ymn)) +errobj-ymn := $(filter-out $(__clean-files),$(errobj-ymn)) +errobj-ymn := $(filter-out $(foreach m,$(multi-used-ymn),$(call get_multi_objs,$m)),$(errobj-ymn)) +ifneq ($(errobj-ymn),) +$(warning Unknown targets in [$(obj)]: $(errobj-ymn)) +endif + +else # SUBMODS + +ifeq ($(ALLCLEAN),1) +RM_ALL := 1 +ifneq ($(KBUILD_OUTPUT),) +RM_DIR := 1 +endif +endif + +ifeq ($(RM_DIR),1) +buildsubdir-ymn := +else +buildsubdir-ymn := $(subdir-ymn) +endif + +endif # SUBMODS + +# Include intermediate files +include scripts/include.mk +__clean-files += $(foreach f,$(__clean-files),$(call get_depfile_name,$f)) + +#$(info RM_DIR=$(RM_DIR), RM_ALL=$(RM_ALL)) +#$(info buildsubdir-ymn=$(buildsubdir-ymn)) +#$(info __clean-files=$(__clean-files)) + +__clean-files := $(wildcard $(__clean-files)) +__clean-dirs := $(wildcard $(__clean-dirs)) + +# ========================================================================== + +ifeq ($(RM_DIR),1) + +quiet_cmd_clean = RMDIR $(obj) + cmd_clean = $(call CMDRMDIR,$(obj)) + +else # RM_DIR + +quiet_cmd_clean = CLEAN $(obj) +ifeq ($(RM_ALL),1) + cmd_clean = $(call CMDRMFILER,$(obj),*.o *.a *.s *.d) +else + cmd_clean = $(call CMDRMFILE,$(__clean-files)) +endif +quiet_cmd_cleandir = CLEAN $(__clean-dirs) + cmd_cleandir = $(call CMDRMDIR,$(__clean-dirs)) + +endif # RM_DIR + + +__clean: $(buildsubdir-ymn) + @: +ifeq ($(RM_DIR),1) + +$(call cmd,clean) +else # RM_DIR +ifeq ($(RM_ALL),1) + +$(call cmd,clean) +else +ifneq ($(strip $(__clean-files)),) + +$(call cmd,clean) +endif +endif +ifneq ($(strip $(__clean-dirs)),) + +$(call cmd,cleandir) +endif +endif # RM_DIR + + +# =========================================================================== +# Generic stuff +# =========================================================================== + +# Descending +# --------------------------------------------------------------------------- + +PHONY += $(subdir-ymn) +$(subdir-ymn): + $(Q)$(MAKE) $(clean)=$@ + + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable se we can use it in if_changed and friends. + +.PHONY: $(PHONY) diff --git a/scripts/extrawarn.mk b/scripts/extrawarn.mk new file mode 100644 index 0000000..9fe4bf6 --- /dev/null +++ b/scripts/extrawarn.mk @@ -0,0 +1,76 @@ +cur_makefile := $(lastword $(MAKEFILE_LIST)) + +$(cur_makefile): ; + +# ========================================================================== +# +# make W=... settings +# +# W=1 - warnings that may be relevant and does not occur too often +# W=2 - warnings that occur quite often but may still be relevant +# W=3 - the more obscure warnings, can most likely be ignored +# +# $(call cc-option, -W...) handles gcc -W.. options which +# are not supported by all versions of the compiler +# ========================================================================== + +ifeq ("$(origin W)","command line") + export KBUILD_ENABLE_EXTRA_GCC_CHECKS := $(W) +endif + +ifdef KBUILD_ENABLE_EXTRA_GCC_CHECKS +warning- := $(empty) + +warning-1 := -Wextra -Wunused -Wno-unused-parameter +warning-1 += -Wmissing-declarations +warning-1 += -Wmissing-format-attribute +warning-1 += -Wmissing-include-dirs +warning-1 += -Wunused-but-set-variable +warning-1 += -Wno-missing-field-initializers +c_warning-1 := -Wmissing-prototypes -Wold-style-definition + +warning-2 := -Waggregate-return +warning-2 += -Wcast-align +warning-2 += -Wdisabled-optimization +warning-2 += -Wshadow +warning-2 += -Wlogical-op +warning-2 += -Wmissing-field-initializers +c_warning-2 := -Wnested-externs + +warning-3 := -Wcast-qual +warning-3 += -Wconversion +warning-3 += -Wpacked +warning-3 += -Wpadded +warning-3 += -Wpointer-arith +warning-3 += -Wredundant-decls +warning-3 += -Wswitch-default +warning-3 += -Wpacked-bitfield-compat +warning-3 += -Wvla +c_warning-3 := -Wbad-function-cast + +warning := $(warning-$(findstring 1, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) +warning += $(warning-$(findstring 2, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) +warning += $(warning-$(findstring 3, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) + +c_warning := $(warning-$(findstring 1, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) +c_warning += $(warning-$(findstring 2, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) +c_warning += $(warning-$(findstring 3, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) + +ifeq ("$(strip $(warning) $(c_warning))","") + $(error W=$(KBUILD_ENABLE_EXTRA_GCC_CHECKS) is unknown) +endif + +KBUILD_CFLAGS += $(warning) +C_ONLY_FLAGS += $(c_warning) +else + +ifeq ($(COMPILER),clang) +KBUILD_CFLAGS += -Wno-initializer-overrides +KBUILD_CFLAGS += -Wno-unused-value +KBUILD_CFLAGS += -Wno-format +KBUILD_CFLAGS += -Wno-unknown-warning-option +KBUILD_CFLAGS += -Wno-sign-compare) +KBUILD_CFLAGS += -Wno-format-zero-length +KBUILD_CFLAGS += -Wno-uninitialized +endif +endif diff --git a/scripts/include.mk b/scripts/include.mk new file mode 100644 index 0000000..896fd84 --- /dev/null +++ b/scripts/include.mk @@ -0,0 +1,268 @@ +ifndef __INCLUDE_MK__ +__INCLUDE_MK__ := 1 + +cur_makefile := $(lastword $(MAKEFILE_LIST)) + +$(cur_makefile): ; + +#### +# Generic definitions + +ifeq ($(WIN_PLAT),y) +ifeq ($(WIN_SHELL),y) +# make will choose sh.exe as SHELL if it finds sh.exe in the directories of PATH, regardless of +# the setting in environment or parent (e.g., when git.exe is in the PATH) +SHELL := cmd.exe +endif +endif + +# Convenient variables +lparen := ( +rparen := ) +comma := , +quote := " +squote := ' +empty := +space := $(empty) $(empty) + +ifeq ($(WIN_PLAT),y) +devnull := nul +else +devnull := /dev/null +endif + +### +# Remove/copy commands +ifeq ($(WIN_PLAT),y) +CMDRMFILE = del /f /q $(subst /,\,$1) >nul 2>&1 +CMDRMFILER = cd $(subst /,\,$1) && del /f /q /s $(subst /,\,$2) +CMDRMDIR = rmdir /s /q $(subst /,\,$1) >nul 2>&1 || del /f /q /s $(subst /,\,$1)\* +CMDCPFILE = copy /y $(subst /,\,$1 $2) +else +CMDRMFILE = rm -f $1 +CMDRMFILER = find $1 $(RCS_FIND_IGNORE) \ + \( $(addprefix -name ,'$(firstword $2)') \ + $(addprefix -o -name ',$(addsuffix ',$(filter-out $(firstword $2),$2))) \) \ + -type f -print | xargs rm -f +CMDRMDIR = rm -fr $1 +CMDCPFILE = cp -f $1 $2 +endif + +### +# Build-in obj suffix +ifeq ($(BUILT-IN-OBJ),1) +built_in_suffix := .o +else +built_in_suffix := .a +endif + +### +# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o +dot-target = $(dir $(1)).$(notdir $(1)) + +### +# The temporary file to save gcc -MF generated dependencies must not +# contain a comma +get_depfile_name = $(subst $(comma),_,$(dot-target).d) +depfile = $(call get_depfile_name,$@) + +### +# filename of target with directory and extension stripped +basetarget = $(basename $(notdir $@)) + +### +# filename of first prerequisite with directory and extension stripped +baseprereq = $(basename $(notdir $<)) + +### +# Escape special characters for use in echo statements +ifeq ($(WIN_PLAT),y) +# Escape redirection character in echo in Windows +escchar = $(subst $(lparen),^$(lparen),$(subst $(rparen),^$(rparen),$(subst &,^&,$(subst |,^|,$(subst <,^<,$(subst >,^>,$1)))))) +else +# Escape single quote for use in echo statements +escchar = $(subst $(squote),'\$(squote)',$1) +endif + +### +# Easy method for doing a status message + kecho := : +ifeq ($(WIN_PLAT),y) + quiet_kecho := echo. +else + quiet_kecho := echo +endif +silent_kecho := : +kecho := $($(quiet)kecho) + +ifeq ($(WIN_PLAT),y) +echo-help = @echo. $(call escchar,$(1)) & +else +echo-help = @echo ' $(call escchar,$(1))' +endif + +### +# try-run +ifeq ($(WIN_PLAT),y) +try-run = $(shell ($(1) >$(devnull) 2>&1) && echo. $(2) || echo. $(3)) +# Or, using define to construct multi-line WIN commands, +# with if command: if not errorlevel 1 +else +try-run = $(shell if ($(1)) >$(devnull) 2>&1; \ + then echo "$(2)"; \ + else echo "$(3)"; \ + fi) +endif + +### +# cc-option +cc-option = $(call try-run, \ + $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c \ + -o $(devnull) $(devnull),$(1),$(2)) + +### +# Shorthand for $(Q)$(MAKE) -f scripts/build.mk obj= +# Usage: +# $(Q)$(MAKE) $(build)=dir +build := -f $(srctree)/scripts/build.mk obj + +# Prefix -I with $(srctree) if it is not an absolute path. +# skip if -I has no parameter +#addtree = $(if $(patsubst -I%,%,$(1)), \ +#$(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1)) +ifeq ($(WIN_PLAT),y) +addtree = $(if $(patsubst -I%,%,$(1)), \ + $(if $(filter-out -I$(KBUILD_ROOT)/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1))) +else +addtree = $(if $(patsubst -I%,%,$(1)), \ + $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1))) +endif + +# Find all -I options and call addtree +flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) + +# echo command. +# Short version is used, if $(quiet) equals `quiet_', otherwise full one. +ifeq ($(WIN_PLAT),y) +echo-cmd = $(if $($(quiet)cmd_$(1)),\ + echo. $(call escchar,$($(quiet)cmd_$(1)))$(echo-why) &&) +echo-cmd-nowhy = $(if $($(quiet)cmd_$(1)),\ + echo. $(call escchar,$($(quiet)cmd_$(1))) &&) +else +echo-cmd = $(if $($(quiet)cmd_$(1)),\ + echo ' $(call escchar,$($(quiet)cmd_$(1)))$(echo-why)' ;) +echo-cmd-nowhy = $(if $($(quiet)cmd_$(1)),\ + echo ' $(call escchar,$($(quiet)cmd_$(1)))' ;) +endif + +# printing commands +cmd = @$(echo-cmd) $(cmd_$(1)) + +# Add $(obj)/ for paths that are not absolute +objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) + +### +# if_changed - execute command if any prerequisite is newer than +# target, or command line has changed +# if_changed_dep - as if_changed, but uses fixdep to reveal dependencies +# including used config symbols +# if_changed_rule - as if_changed but execute rule instead +# See Documentation/kbuild/makefiles.txt for more info + +ifneq ($(KBUILD_NOCMDDEP),1) +# Check if both arguments has same arguments. Result is empty string if equal. +# User may override this check using make KBUILD_NOCMDDEP=1 +arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ + $(filter-out $(cmd_$@), $(cmd_$(1))) ) +else +arg-check = $(if $(strip $(cmd_$@)),,1) +endif + +# Replace >$< with >$$< to preserve $ when reloading the .cmd file +# (needed for make) +# Replace >#< with >\#< to avoid starting a comment in the .cmd file +# (needed for make) +# Replace >'< with >'\''< to be able to enclose the whole string in '...' +# (needed for the shell) +make-cmd = $(call escchar,$(subst \#,\\\#,$(subst $$,$$$$,$(cmd_$(1))))) + +# Find any prerequisites that is newer than target or that does not exist. +# PHONY targets skipped in both cases. +any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^) + +ifeq ($(WIN_PLAT),y) +depfile-new = echo. > $(depfile) && \ + echo cmd_$@ := $(make-cmd) >> $(depfile) && \ + echo. >> $(depfile) +depfile-add = echo. >> $(depfile) && \ + echo cmd_$@ := $(make-cmd) >> $(depfile) && \ + echo. >> $(depfile) +else +depfile-new = printf '\n%s\n' 'cmd_$@ := $(make-cmd)' > $(depfile) +depfile-add = printf '\n%s\n' 'cmd_$@ := $(make-cmd)' >> $(depfile) +endif + +# Execute command if command has changed or prerequisite(s) are updated. +# +if_changed = $(if $(strip $(any-prereq) $(arg-check)), \ + @ ( $(echo-cmd) $(cmd_$(1)) ) && \ + ( $(depfile-new) )) + +if_changed2 = $(if $(strip $(any-prereq) $(call arg-check,$(2))), \ + @ ( $(call echo-cmd,$(1)) $(cmd_$(1)) && \ + $(call echo-cmd,$(2)) $(cmd_$(2)) ) && \ + ( $(call depfile-new,$(2)) )) + +# Execute the command and also postprocess generated .d dependencies file. +if_changed_dep = $(if $(strip $(any-prereq) $(arg-check)), \ + @ ( $(echo-cmd) $(cmd_$(1)) ) && \ + ( $(depfile-add) )) + +# Usage: $(call if_changed_rule,foo) +# Will check if $(cmd_foo) or any of the prerequisites changed, +# and if so will execute $(rule_foo). +if_changed_rule = $(if $(strip $(any-prereq) $(arg-check)), \ + @ ( $(rule_$(1)) ) && \ + ( $(depfile-add) )) + +### +# why - tell why a a target got build +# enabled by make V=2 +# Output (listed in the order they are checked): +# (1) - due to target is PHONY +# (2) - due to target missing +# (3) - due to: file1.h file2.h +# (4) - due to command line change +# (5) - due to missing .cmd file +# (6) - due to target not in $(targets) +# (1) PHONY targets are always build +# (2) No target, so we better build it +# (3) Prerequisite is newer than target +# (4) The command line stored in the file named dir/.target.cmd +# differed from actual command line. This happens when compiler +# options changes +# (5) No dir/.target.d file (used to store command line) +# (6) No dir/.target.d file and target not listed in $(targets) +# This is a good hint that there is a bug in the kbuild file +ifeq ($(KBUILD_VERBOSE),2) +why = \ + $(if $(filter $@, $(PHONY)),- due to target is PHONY, \ + $(if $(wildcard $@), \ + $(if $(strip $(any-prereq)),- due to: $(any-prereq), \ + $(if $(arg-check), \ + $(if $(cmd_$@),- due to command line change, \ + $(if $(filter $@, $(targets)), \ + - due to missing .d file, \ + - due to $(notdir $@) not in $$(targets) \ + ) \ + ) \ + ) \ + ), \ + - due to target missing \ + ) \ + ) + +echo-why = $(call escchar, $(strip $(why))) +endif + +endif # __INCLUDE_MK__ diff --git a/scripts/lib.mk b/scripts/lib.mk new file mode 100644 index 0000000..1649460 --- /dev/null +++ b/scripts/lib.mk @@ -0,0 +1,217 @@ +cur_makefile := $(lastword $(MAKEFILE_LIST)) + +$(cur_makefile): ; + +# Backward compatibility +asflags-y += $(EXTRA_AFLAGS) +ccflags-y += $(EXTRA_CFLAGS) +cppflags-y += $(EXTRA_CPPFLAGS) +ldflags-y += $(EXTRA_LDFLAGS) + +# +# flags that take effect in sub directories +export KBUILD_SUBDIR_ASFLAGS := $(KBUILD_SUBDIR_ASFLAGS) $(subdir-asflags-y) +export KBUILD_SUBDIR_CCFLAGS := $(KBUILD_SUBDIR_CCFLAGS) $(subdir-ccflags-y) + +# Figure out what we need to build from the various variables +# =========================================================================== + +# Handle archives +# --------------------------------------------------------------------------- + +# Extract archives from $(obj-y) +archive-y := $(filter %.a, $(obj-y)) +archive-custom-valid := $(filter $(archive-custom), $(archive-y)) + +ifeq ($(archive-y),) +archive-src-y := +archive-bin-y := +else # archive-y +ifeq ($(FORCE_TO_USE_LIB),1) +archive-bin-y := $(archive-y) +else +# Filter out archive-custom-valid +archive-y := $(filter-out $(archive-custom-valid), $(archive-y)) + +# Extract archives that have source files available +archive-src-y := $(foreach m, $(archive-y), $(if $(wildcard $(addprefix $(srctree)/$(src)/,$($(m:.a=-y):.o=.*))), $(m))) + +# Extract archives that do NOT have source files +archive-bin-y := $(filter-out $(archive-src-y), $(archive-y)) +endif + +# If the source files of the archive (including archive-custom-valid) exist, build the source files directly +obj-y := $(filter-out $(archive-src-y) $(archive-custom-valid), $(obj-y)) $(foreach m, $(archive-src-y) $(archive-custom-valid), $($(m:.a=-y))) +endif # archive-y + +# Handle composite objects +# --------------------------------------------------------------------------- + +# if $(foo-objs) exists, foo.o is a composite object +multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) + +# Build list of the parts of our composite objects, our composite +# objects depend on those (obviously) +multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y))) +multi-objs-subdir := $(patsubst %/,%,$(filter %/, $(multi-objs-y))) +multi-objs-archive := $(filter %.a, $(multi-objs-y)) +multi-objs-y := $(patsubst %/, %/built-in$(built_in_suffix), $(multi-objs-y)) +multi-objs := $(multi-objs-y) + +define multi_subdir_built_in +$(foreach m, $(1), $(if $($(m:.o=$(strip $2))), $(eval $(m:.o=$(strip $2)) := $(patsubst %/, %/built-in$(built_in_suffix), $($(m:.o=$(strip $2))))))) +endef + +ifneq ($(multi-objs-subdir),) +$(call multi_subdir_built_in,$(multi-used-y),-objs) +$(call multi_subdir_built_in,$(multi-used-y),-y) +endif + +ifneq ($(multi-objs-archive),) +ifneq ($(filter $(archive-custom), $(multi-objs-archive)),) +$(error Composite objects cannot be built from customized archives) +endif +mobjs-archive-src-y := +mobjs-archive-bin-y := +mobjs-archive-y := $(multi-objs-archive) + +ifeq ($(FORCE_TO_USE_LIB),1) +mobjs-archive-bin-y += $(mobjs-archive-y) +else +# Extract archives that have source files available +mobjs-archive-src-y += $(foreach m, $(mobjs-archive-y), $(if $(wildcard $(addprefix $(srctree)/$(src)/,$($(m:.a=-y):.o=.*))), $(m))) + +# Extract archives that do NOT have source files +mobjs-archive-bin-y := $(filter-out $(mobjs-archive-src-y), $(mobjs-archive-y)) +endif + +# If the source files of the archive (including archive-custom-valid) exist, build the source files directly +mobjs-obj-y := $(foreach m, $(mobjs-archive-src-y), $($(m:.a=-y))) + +archive-y += $(mobjs-archive-y) +archive-bin-y += $(mobjs-archive-bin-y) +archive-src-y += $(mobjs-archive-src-y) +obj-y += $(mobjs-obj-y) +endif + +# Handle objects in subdirs +# --------------------------------------------------------------------------- +# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o or .a +# and add the directory to the list of dirs to descend into: $(subdir-y) + +__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) +subdir-y += $(__subdir-y) +obj-y := $(patsubst %/, %/built-in$(built_in_suffix), $(obj-y)) + +# Subdirectories we need to descend into +subdir-y := $(sort $(subdir-y) $(multi-objs-subdir)) + +# $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to +# tell kbuild to descend +subdir-obj-y := $(filter %/built-in$(built_in_suffix), $(obj-y) $(multi-objs-y)) + +# $(obj-dirs) is a list of directories that contain object files +obj-dirs := $(dir $(multi-objs) $(obj-y)) + +# Replace multi-part objects by their individual parts, look at local dir only +real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y) + +# Add subdir path + +extra-y := $(addprefix $(obj)/,$(extra-y)) +always := $(addprefix $(obj)/,$(always)) +targets := $(addprefix $(obj)/,$(targets)) +obj-y := $(addprefix $(obj)/,$(obj-y)) +lib-y := $(addprefix $(obj)/,$(lib-y)) +subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) +real-objs-y := $(addprefix $(obj)/,$(real-objs-y)) +multi-used-y := $(addprefix $(obj)/,$(multi-used-y)) +multi-objs-y := $(addprefix $(obj)/,$(multi-objs-y)) +subdir-y := $(addprefix $(obj)/,$(subdir-y)) +obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) +archive-y := $(addprefix $(obj)/,$(archive-y)) +archive-src-y := $(addprefix $(obj)/,$(archive-src-y)) +archive-bin-y := $(addprefix $(obj)/,$(archive-bin-y)) +archive-custom-valid := $(addprefix $(obj)/,$(archive-custom-valid)) + +orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ + $(ccflags-y) $(CFLAGS_$(basetarget).o) +_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags) $(C_ONLY_FLAGS)) +_c++_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags) $(C++_ONLY_FLAGS)) +_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \ + $(asflags-y) $(AFLAGS_$(basetarget).o) +_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) + +# If building the kernel in a separate objtree expand all occurrences +# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). + +ifeq ($(KBUILD_SRC),) +__c_flags = $(_c_flags) +__c++_flags = $(_c++_flags) +__a_flags = $(_a_flags) +__cpp_flags = $(_cpp_flags) +else + +# -I$(obj) locates generated .h files +# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files +# and locates generated .h files +# FIXME: Replace both with specific CFLAGS* statements in the makefiles +__c_flags = $(call addtree,-I$(obj)) $(call flags,_c_flags) +__c++_flags = $(call addtree,-I$(obj)) $(call flags,_c++_flags) +__a_flags = $(call flags,_a_flags) +__cpp_flags = $(call flags,_cpp_flags) +endif + +ifeq ($(WIN_PLAT),y) +# Not to include system header files in dependency files, +# for there are space characters in system path by default. +depfile_flags = -MMD -MP -MF $(depfile) +else +depfile_flags = -MD -MP -MF $(depfile) +endif + +c_flags = $(depfile_flags) $(NOSTDINC_FLAGS) $(__c_flags) + +c++_flags = $(depfile_flags) $(NOSTDINC_FLAGS) $(__c++_flags) + +a_flags = $(depfile_flags) $(NOSTDINC_FLAGS) $(__a_flags) + +a_cpp_flags = $(a_flags) + +cpp_flags = $(depfile_flags) $(NOSTDINC_FLAGS) $(__cpp_flags) + +ld_flags = $(LDFLAGS) $(ldflags-y) + +# Useful for describing the dependency of composite objects +# Usage: +# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) +define multi_depend +$(foreach m, $(notdir $1), \ + $(eval $(obj)/$m: \ + $(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s))))))) +endef + +# Commands useful for building a boot image +# =========================================================================== +# +# Use as following: +# +# target: source(s) FORCE +# $(if_changed,ld/objcopy/gzip) +# +# and add target to extra-y so that we know we have to +# read in the saved command line + +# Linking +# --------------------------------------------------------------------------- + +quiet_cmd_ld = LD $@ +cmd_ld = $(LD) $(LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) \ + $(filter-out FORCE,$^) -o $@ + +# Objcopy +# --------------------------------------------------------------------------- + +quiet_cmd_objcopy = OBJCOPY $@ +cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ + diff --git a/scripts/link/armca.lds.S b/scripts/link/armca.lds.S new file mode 100644 index 0000000..2271de9 --- /dev/null +++ b/scripts/link/armca.lds.S @@ -0,0 +1,355 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#define __TTB_SIZE 0x5000 + +#define __HEAP_SIZE 0x1000 +#define __STACK_SIZE 0x1000 +#define __FIQ_STACK_SIZE 0 +#define __IRQ_STACK_SIZE 0x1000 +#define __SVC_STACK_SIZE 0 +#define __ABT_STACK_SIZE 0 +#define __UND_STACK_SIZE 0 + +/* TODO: Add FLASH_REGION_OFFSET if there are multiple levels of boot loaders */ +#if !defined(OTA_BOOT_SIZE) && defined(OTA_CODE_OFFSET) +#define FLASH_REGION_BASE (FLASH_BASE + OTA_CODE_OFFSET) +#else +#define FLASH_REGION_BASE (FLASH_BASE) +#endif + +#ifndef FLASH_REGION_SIZE +#define FLASH_REGION_SIZE (FLASH_SIZE - (FLASH_REGION_BASE - FLASH_BASE)) +#endif + +#ifdef EXEC_IN_RAM +#define EXEC_REGION RAM +#elif defined(EXEC_IN_PSRAM) +#define EXEC_REGION PSRAM +#else +#define EXEC_REGION PSRAMUHS +#endif + +#define PSRAMUHSX_SECTION_SIZE 0x100000 + +MEMORY +{ + BOOT (rwx) : ORIGIN = DSP_BOOT_BASE, LENGTH = DSP_BOOT_SIZE + FLASH (rx) : ORIGIN = FLASH_REGION_BASE, LENGTH = FLASH_REGION_SIZE + RAM (rwx) : ORIGIN = DSP_RAM_BASE, LENGTH = DSP_RAM_SIZE - __TTB_SIZE + L_TTB (rw) : ORIGIN = DSP_RAM_BASE + DSP_RAM_SIZE - __TTB_SIZE, LENGTH = __TTB_SIZE +#ifdef PSRAM_BASE + PSRAM (rwx) : ORIGIN = PSRAM_BASE, LENGTH = PSRAM_SIZE +#endif +#ifdef PSRAMUHS_BASE + PSRAMUHS (rwx) : ORIGIN = PSRAMUHS_BASE, LENGTH = PSRAMUHS_SIZE - PSRAMUHSX_SECTION_SIZE + PSRAMUHSX (rx) : ORIGIN = PSRAMUHSX_BASE+PSRAMUHS_SIZE-PSRAMUHSX_SECTION_SIZE, LENGTH = PSRAMUHSX_SECTION_SIZE +#endif +} + +/* Library configurations */ +GROUP(libgcc.a) + +#ifdef GEN_BOOT_SECTION +ENTRY(Vectors) +#else +ENTRY(Reset_Handler) +#endif + +SECTIONS +{ +#ifdef GEN_BOOT_SECTION + + .boot : + { + KEEP(*(.vectors)) + } > BOOT + + /DISCARD/ : + { + *(*) + } + +#else // !GEN_BOOT_SECTION + + .boot_loader : + { + *(.boot_loader) + *(.boot_text_flash*) + + . = ALIGN(4); + } > EXEC_REGION + + .sram_text : + { + __sram_text_data_start__ = .; + /* memcpy.o or libc_nano.a(lib_a-memcpy.o/lib_a-memcpy-stub.o) */ + *:memcpy.o(.text*) + *:lib_a-memcpy*.o(.text*) + *:libc_rom.o(.text*) + + /* memset.o or libc_nano.a(lib_a-memset.o) */ + *:memset.o(.text*) + *:lib_a-memset*.o(.text*) + + *(.boot_text_sram*) + *(.sram_text*) + *(.fast_text_sram*) + + . = ALIGN(4); + } > RAM AT > EXEC_REGION + + __sram_text_data_start_load__ = LOADADDR(.sram_text); + + .sram_data : + { + *(.boot_data*) + . = ALIGN(4); + *(.sram_data*) + . = ALIGN(4); + } > RAM AT > EXEC_REGION + + __sram_text_data_end_load__ = LOADADDR(.sram_data) + SIZEOF(.sram_data); + + .text : + { + *(SVC_TABLE) + *(.text*) + *(.flash_text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + . = ALIGN(4); + + __rodata_start = .; + *(.rodata*) + *(.boot_rodata*) + __rodata_end = .; + + . = ALIGN(4); + + KEEP(*(.eh_frame*)) + KEEP(*(.build_info)) + + *(.note.gnu.build-id) + + . = ALIGN(4); + } > EXEC_REGION + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > EXEC_REGION + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > EXEC_REGION + __exidx_end = .; + + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + __copy_table_end__ = .; + } > EXEC_REGION + + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + __zero_table_end__ = .; + } > EXEC_REGION + + __etext = .; + + .data : + { + Image$$RW_DATA$$Base = .; + __data_start__ = .; + *(.data*) + Image$$RW_DATA$$Limit = .; + + . = ALIGN(4); + /* preinit data */ + PROVIDE (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE (__fini_array_end = .); + + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > EXEC_REGION + + .sram_bss (NOLOAD) : AT (ADDR(.sram_bss)) + { + __sram_bss_start__ = .; + *(.boot_bss*) + . = ALIGN(4); + *(.sram_bss*) + . = ALIGN(4); + __sram_bss_end__ = .; + } > RAM + +#ifndef EXEC_IN_RAM + __ram_end = .; +#endif + + .bss ALIGN(0x400) (NOLOAD) : + { + Image$$ZI_DATA$$Base = .; + __bss_start__ = .; + *(.bss*) + *(COMMON) + __bss_end__ = .; + Image$$ZI_DATA$$Limit = .; + __end__ = .; + end = __end__; + } > EXEC_REGION + +#if defined(__HEAP_SIZE) && (__HEAP_SIZE > 0) + .heap (NOLOAD) : + { + . = ALIGN(8); + Image$$HEAP$$ZI$$Base = .; + . += __HEAP_SIZE; + Image$$HEAP$$ZI$$Limit = .; + __HeapLimit = .; + } > EXEC_REGION +#endif + + .sync_flags ALIGN(0x1000) (NOLOAD) : + { + __sync_flags_start = .; + *(.sync_flags*) + . = ALIGN(0x1000); + __sync_flags_end = .; + } > EXEC_REGION + +#ifdef EXEC_IN_RAM + __ram_end = .; +#else + __free_exec_region = ORIGIN(EXEC_REGION) + LENGTH(EXEC_REGION) - .; +#endif + + __psramuhs_text_data_start_load__ = LOADADDR(.data) + SIZEOF(.data); + .psramuhs_text (ORIGIN(PSRAMUHSX)) : AT (__psramuhs_text_data_start_load__) + { + __psramuhs_text_start = PSRAMUHSX_TO_PSRAMUHS(.); + *(.psramuhs_text*) + . = ALIGN(4); + __psramuhs_text_end = PSRAMUHSX_TO_PSRAMUHS(.); + } > PSRAMUHSX + __psramuhs_text_data_end_load__ = __psramuhs_text_data_start_load__ + SIZEOF(.psramuhs_text); + + /* The following section MUST be the last loaded section */ + .code_start_addr : AT (__psramuhs_text_data_end_load__) + { + LONG(ADDR(.boot_loader)); + } > EXEC_REGION + + .stack (ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE - __FIQ_STACK_SIZE - __IRQ_STACK_SIZE - __SVC_STACK_SIZE - __ABT_STACK_SIZE - __UND_STACK_SIZE) (NOLOAD) : AT (ADDR(.stack)) + { + . = ALIGN(8); + + __StackTop = .; + Image$$SYS_STACK$$ZI$$Base = .; + . += __STACK_SIZE; + Image$$SYS_STACK$$ZI$$Limit = .; + __stack = .; + + Image$$FIQ_STACK$$ZI$$Base = .; + . += __FIQ_STACK_SIZE; + Image$$FIQ_STACK$$ZI$$Limit = .; + + Image$$IRQ_STACK$$ZI$$Base = .; + . += __IRQ_STACK_SIZE; + Image$$IRQ_STACK$$ZI$$Limit = .; + + Image$$SVC_STACK$$ZI$$Base = .; + . += __SVC_STACK_SIZE; + Image$$SVC_STACK$$ZI$$Limit = .; + + Image$$ABT_STACK$$ZI$$Base = .; + . += __ABT_STACK_SIZE; + Image$$ABT_STACK$$ZI$$Limit = .; + + Image$$UND_STACK$$ZI$$Base = .; + . += __UND_STACK_SIZE; + Image$$UND_STACK$$ZI$$Limit = .; + } > RAM + + __free_ram = ADDR(.stack) - __ram_end; +#ifdef EXEC_IN_RAM + __free_exec_region = __free_ram; +#endif + + .ttb_l2 (NOLOAD) : + { + Image$$TTB$$ZI$$Base = .; + *(.ttb_l2) + } > L_TTB + + .ttb_l1 (NOLOAD) : + { + *(.ttb_l1) + Image$$TTB$$ZI$$Limit = .; + } > L_TTB + + __free_ttb = ORIGIN(L_TTB) + LENGTH(L_TTB) - .; + +#endif // !GEN_BOOT_SECTION +} + diff --git a/scripts/link/best1000.lds.S b/scripts/link/best1000.lds.S new file mode 100644 index 0000000..a692c1c --- /dev/null +++ b/scripts/link/best1000.lds.S @@ -0,0 +1,2016 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#ifdef RB_CODEC +#define HEAP_SECTION_SIZE 0x1000 +#else +#define HEAP_SECTION_SIZE 0x1000 +#endif + +#define STACK_SECTION_SIZE 0x1000 +#define CP_STACK_SECTION_SIZE 0x1000 + +#if defined(ROM_UTILS_ON) +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) +#define ROM_UTILS_RESV_RAM_SIZE 0x64 +#else +#define ROM_UTILS_RESV_RAM_SIZE 0x0 +#endif +#endif + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) +#define OVERLAY_DATA_SECTION_SIZE 0x10000 +#elif defined(RB_CODEC) +#define OVERLAY_DATA_SECTION_SIZE 0xA000 +#else +#define OVERLAY_DATA_SECTION_SIZE 0x8000 +#endif + +#if !defined(FAST_XRAM_SECTION_SIZE) +#if (RAM_SIZE >= 0x48000) +#define RTOS_IN_RAM +#if defined(BTUSB_AUDIO_MODE) +#define FAST_XRAM_SECTION_SIZE 0x20000 +#elif (defined(CHIP_BEST1402) && defined(SPEECH_TX_2MIC_NS2)) +#define FAST_XRAM_SECTION_SIZE 0xF800 +#else +#define FAST_XRAM_SECTION_SIZE 0x16000 +#endif +#elif (RAM_SIZE >= 0x40000) +#if defined(CHIP_BEST1402) || defined(CHIP_BEST1400) +#define FAST_XRAM_SECTION_SIZE 0x5200 +#else +#define FAST_XRAM_SECTION_SIZE 0x3800 +#endif +#else +#define FAST_XRAM_SECTION_SIZE 0x6000 +#endif +#endif + +/* TODO: Add FLASH_REGION_OFFSET if there are multiple levels of boot loaders */ +#if !defined(OTA_BOOT_SIZE) && defined(OTA_CODE_OFFSET) +#define FLASH_REGION_BASE (FLASH_BASE + OTA_CODE_OFFSET) +#else +#define FLASH_REGION_BASE (FLASH_BASE) +#endif + +#ifndef FLASH_REGION_SIZE +#define FLASH_REGION_SIZE (FLASH_SIZE - (FLASH_REGION_BASE - FLASH_BASE)) +#endif + +#define FLASH_NC_REGION_BASE FLASH_C_TO_NC(FLASH_REGION_BASE) +#define FLASHX_REGION_BASE FLASH_TO_FLASHX(FLASH_REGION_BASE) + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) +#define OVERLAY_FOR_CP +#endif + +#ifdef OVERLAY_FOR_CP +#define REGION_OVERLAY_TEXT RAMCPX +#define REGION_OVERLAY_DATA RAMCP +#else +#define REGION_OVERLAY_TEXT FRAMX +#define REGION_OVERLAY_DATA RAM +#endif + +/* Linker script to configure memory regions. */ +/* See plat_addr_map.h and common.mk for the macro definitions */ +MEMORY +{ + ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE + FLASH (r) : ORIGIN = FLASH_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASH_NC (r) : ORIGIN = FLASH_NC_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASHX (rx) : ORIGIN = FLASHX_REGION_BASE, LENGTH = FLASH_REGION_SIZE + RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + RAMX (rx) : ORIGIN = RAMX_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + FRAMX (rwx) : ORIGIN = RAMX_BASE + RAM_SIZE - FAST_XRAM_SECTION_SIZE, LENGTH = FAST_XRAM_SECTION_SIZE +#ifdef PSRAM_BASE + PSRAM (rwx) : ORIGIN = PSRAM_BASE, LENGTH = PSRAM_SIZE + PSRAM_NC (rwx) : ORIGIN = PSRAM_NC_BASE, LENGTH = PSRAM_SIZE + PSRAMX (rx) : ORIGIN = PSRAMX_BASE, LENGTH = PSRAM_SIZE +#endif +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + RAMCP (rwx) : ORIGIN = RAMCP_BASE, LENGTH = RAMCP_SIZE + RAMCPX (rwx) : ORIGIN = RAMCPX_BASE, LENGTH = RAMCPX_SIZE +#endif +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __export_fn_rom + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __free_ram + * __factory_start + * __factory_end + * __calib_start + * __calib_end + * __flash_start + * __flash_end + * __free_flash + * __boot_sram_start_flash__ + * __boot_sram_end_flash__ + * __boot_sram_start__ + * __boot_bss_sram_start__ + * __boot_bss_sram_end__ + * __sram_text_data_start_flash__ + * __sram_text_data_end_flash__ + * __fast_sram_text_data_start__ + * __fast_sram_text_data_end__ + * __fast_sram_text_data_start_flash__ + * __fast_sram_text_data_end_flash__ + * __sram_text_data_start__ + * __sram_bss_start__ + * __sram_bss_end__ + * __overlay_text_start__ + * __overlay_text_exec_start__ + * __overlay_data_start__ + */ +ENTRY(Boot_Loader) + +SECTIONS +{ + __export_fn_rom = (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE); + + .boot_struct (ORIGIN(FLASH)) : + { + __flash_start = .; + KEEP(*(.boot_struct)) + . = ALIGN(4); + } > FLASH + + . = FLASH_TO_FLASHX(.); + + .boot_text_flash (.) : AT (FLASHX_TO_FLASH(ADDR(.boot_text_flash))) + { + *(.boot_loader) + *(.boot_text_flash*) + *(.boot_rodata_flash*) + . = ALIGN(4); + } > FLASHX + +#if defined(__BES_OTA_MODE__) + .ota_boot_info (ALIGN(4096)) : + { + *(.ota_boot_info) + . = (0x1000); + } > FLASHX + + .ota_boot_rev (ALIGN(4096)) : + { + *(.ota_boot_rev) + . = (0x1000); + } > FLASHX +#endif + + . = FLASHX_TO_FLASH(.); + + .got_info (.) : + { + __got_info_start = .; + __got_start = .; + *(.got) + . = ALIGN(4); + __got_end = .; + __got_plt_start = .; + *(.got.plt) + . = ALIGN(4); + __igot_plt_start = .; + *(.igot.plt) + . = ALIGN(4); + __dynamic_start = .; + *(.dynamic) + . = ALIGN(4); + __got_info_end = .; + } > FLASH + + .vector_table (ORIGIN(RAM)) (NOLOAD) : + { + KEEP(*(.vector_table)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .reboot_param (.) (NOLOAD) : + { + KEEP(*(.reboot_param)) + . = REBOOT_PARAM_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .userdata_pool (.) (NOLOAD) : + { + *(.userdata_pool) + . = ALIGN(4); + __userdata_pool_end__ = .; + } > RAM + + __boot_sram_start_flash__ = LOADADDR(.got_info) + SIZEOF(.got_info); + __boot_sram_start__ = __userdata_pool_end__; + + .boot_text_sram (RAM_TO_RAMX(__boot_sram_start__)) : AT (__boot_sram_start_flash__) + { + /* memcpy.o or libc_nano.a(lib_a-memcpy.o/lib_a-memcpy-stub.o) */ + *:memcpy.o(.text*) + *:lib_a-memcpy*.o(.text*) + *:libc_rom.o(.text*) + + /* memset.o or libc_nano.a(lib_a-memset.o) */ + *:memset.o(.text*) + *:lib_a-memset*.o(.text*) + + *:hal_norflash*.o(.text*) + *:norflash_*.o(EXCLUDE_FILE(*:norflash_api.o) .text*) + +#ifdef BOOT_CODE_IN_RAM + *:hal_cmu_*.o(.text*) + *:hal_iomux_*.o(.text*) + *:hal_analogif_*.o(.text*) + *:hal_spi.o(.text*) + *:hal_timer.o(.text*) + *:hal_sysfreq.o(.text*) +#endif + + *(.boot_text_sram*) + . = ALIGN(4); + __boot_text_sram_end = .; + } > RAMX + + .boot_data_sram (RAMX_TO_RAM(ADDR(.boot_text_sram) + SIZEOF(.boot_text_sram))) : + AT (__boot_sram_start_flash__ + SIZEOF(.boot_text_sram)) + { + *:hal_norflash*.o(.data* .rodata*) + *:norflash_*.o(EXCLUDE_FILE(*:norflash_api.o) .data* EXCLUDE_FILE(*:norflash_api.o) .rodata*) + *:hal_psram.o(.data* .rodata*) + *:libc_rom.o(.rodata*) + + *(.boot_rodata_sram*) + *(.boot_data*) + . = ALIGN(4); + __boot_data_sram_end = .; + } > RAM + + __boot_sram_end_flash__ = __boot_sram_start_flash__ + + SIZEOF(.boot_text_sram) + SIZEOF(.boot_data_sram); + + .boot_bss_sram (.) (NOLOAD) : AT (ADDR(.boot_bss_sram)) + { + __boot_bss_sram_start__ = .; + *:hal_norflash*.o(.bss*) + *:norflash_*.o(EXCLUDE_FILE(*:norflash_api.o) .bss*) + *:hal_psram.o(.bss*) + *(.boot_bss*) + . = ALIGN(32); + __boot_bss_sram_end__ = .; + } > RAM + + __sram_text_data_start_flash__ = __boot_sram_end_flash__; + __sram_text_data_start__ = __boot_bss_sram_end__; + + .sram_text (RAM_TO_RAMX(__sram_text_data_start__)) : AT (__sram_text_data_start_flash__) + { +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + *:hal_memsc.o(.text*) + *:hal_trace.o(.text*) + *:hal_trace_mod.o(.text*) + *:mpu_armv*.o(.text*) + *:codec_sbc.o(.text*) + *:multi_heap.o(.text*) + *:pool_api.o(.text*) + *libgcc.a:(.text*) + + /* for LIBC_ROM=0 */ + *libc_nano.a:(.text*) + + /* for SCO_CP_ACCEL=1 */ + *:cmsis_dsp_lib.o(.text*) + *libm.a:(.text*) +#endif + +#ifdef KWS_IN_RAM + *:kws_lib.o(.text*) +#endif + +#if defined(GSOUND_HOTWORD_EXTERNAL) + *:voice_sbc.o(.text*) + *:gsound_custom_audio.o(.text*) + *:gsound_custom_hotword_external.o(.text*) + *:libspeech*.o(.text*) +#endif + + *:norflash_api.o(.text*) + *(.sram_text*) + /* + If you want protect one section by armv8's mpu, the section should + be aligned to 32bytes + */ + . = ALIGN(32); + __sram_text_end__ = .; + } > RAMX + + .sram_data (RAMX_TO_RAM(ADDR(.sram_text) + SIZEOF(.sram_text))) : + AT (__sram_text_data_start_flash__ + SIZEOF(.sram_text)) + { +#ifdef RTOS_IN_RAM + *:rtos_lib.o(.data* .rodata*) +#endif + +#if defined(GLOBAL_SRAM_KISS_FFT) + *:fftwrap.o(.data* .rodata*) + *:kiss_fft.o(.data* .rodata*) + *:kiss_fftr.o(.data* .rodata*) +#endif + +#if defined(GLOBAL_SRAM_CMSIS_FFT) || defined(AI_CAPTURE_DATA_AEC) + *:CommonTables.o(.rodata.armBitRevIndexTable256) + *:CommonTables.o(.rodata.twiddleCoef_256) + *:CommonTables.o(.rodata.twiddleCoef_rfft_512) + *:CommonTables.o(.rodata.armBitRevIndexTable128) + *:CommonTables.o(.rodata.twiddleCoef_128) + *:CommonTables.o(.rodata.twiddleCoef_rfft_256) +#endif + +#if defined(BTUSB_AUDIO_MODE) + *:hal_usb.o(.rodata*) +#endif + +#if defined(SCO_CP_ACCEL) + *:plc_8000.o(.data* .rodata*) +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.data* .rodata* .bss*) +#endif +#if defined(HFP_1_6_ENABLE) + *:table.o(.data* .rodata*) + *:plc_16000.o(.data* .rodata*) +#endif + /* Move algos from overlay to here */ +#endif + + *:utils.o(.data* .rodata*) + *:cqueue.o(.data* .rodata*) + *:iir_process.o(.data* .rodata*) +#if defined(HFP_1_6_ENABLE) + *:sbcplc.o(.data* .rodata*) + *:sbc.o(.data* .rodata*) + *:sbc_math.o(.data* .rodata*) +#endif + *:crossover_filter.o(.data* .rodata*) + *:exp_func_tables.o(.data* .rodata*) +#if defined(KWS_BES) + *:cnn.o(.data* .rodata.second_conv_wt) + *:command_recognition.o(.data* .rodata*) + *:arm_bitreversal_16.o(.data* .rodata*) + *:arm_cfft_radix8_f32.o(.data* .rodata*) + *:arm_bitreversal2.o(.data* .rodata*) + *:arm_mult_f32.o(.data* .rodata*) + *:arm_cmplx_mag_squared_f32.o(.data* .rodata*) + *:arm_cmplx_mult_cmplx_f32.o(.data* .rodata*) + *:arm_abs_f32.o(.data* .rodata*) + *:arm_cos_f32.o(.data* .rodata*) + *:arm_sin_f32.o(.data* .rodata*) + *:nsx_core.o(.data* .rodata*) +#endif + +#if defined(__BESNNDenoise__) + *:denoise_10ms.o(.data* .rodata*) + *:denoise_20ms.o(.data* .rodata*) +#endif + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + *:hal_memsc.o(.rodata*) + *:hal_trace.o(.rodata*) + *:hal_trace_mod.o(.rodata*) + *:mpu.o(.rodata*) + *:multi_heap.o(.rodata*) + *:pool_api.o(.rodata*) + *:a2dp_decoder_cp.o(.rodata*) + *libgcc.a:(.rodata*) + + /* for LIBC_ROM=0 */ + *libc_nano.a:(.rodata*) + + /* for SCO_CP_ACCEL=1 */ + *:cmsis_dsp_lib.o(.rodata*) + *libm.a:(.rodata*) +#endif + +#if defined(GSOUND_HOTWORD_EXTERNAL) + *:voice_sbc.o(.data* .rodata*) + *:gsound_custom_audio.o(.data* .rodata*) + *:gsound_custom_hotword_external.o(.data* .rodata*) + *:libspeech*.o(.data* .rodata*) +#endif + + *:norflash_api.o(.rodata*) + *(.sram_data*) + . = ALIGN(4); + } > RAM + + __sram_text_data_end_flash__ = __sram_text_data_start_flash__ + + SIZEOF(.sram_text) + SIZEOF(.sram_data); + + .sram_bss (.) (NOLOAD) : AT (ADDR(.sram_bss)) + { + __sram_bss_start__ = .; + *:utils.o(.bss*) + *(.sram_bss*) + . = ALIGN(4); + __sram_bss_end__ = .; + } > RAM + + __fast_sram_text_data_start_flash__ = __sram_text_data_end_flash__; + + .fast_text_sram (ORIGIN(FRAMX)) : AT (__fast_sram_text_data_start_flash__) + { + __fast_sram_text_exec_start__ = .; + +#ifdef RTOS_IN_RAM + *:rtos_lib.o(.text*) +#endif + +#if defined(GLOBAL_SRAM_KISS_FFT) + *:fftwrap.o(.text*) + *:kiss_fft.o(.text*) + *:kiss_fftr.o(.text*) +#endif + +#if defined(GLOBAL_SRAM_CMSIS_FFT) || defined(AI_CAPTURE_DATA_AEC) + *:cmsis_fftwrap.o(.text*) + *:arm_rfft_fast_f32.o(.text*) + *:arm_cfft_f32.o(.text*) +#endif + +#if defined(SCO_CP_ACCEL) + *:frame_resize.o(.text*) + *:buffer_manager.o(.text*) + *:plc_8000.o(.text*) +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.text*) +#endif +#if defined(HFP_1_6_ENABLE) + *:dspfns.o(.text*) + *:lpc_plc.o(.text*) + *:plc_16000.o(.text*) + *:sbc_filter.o(.text*) +#endif +/* Move algos from overlay to here */ + +#endif + +#if defined(ROM_UTILS_ON) + *:rom_utils.o(.text*) +#endif + +#if defined(BTUSB_AUDIO_MODE) + *:hal_dma.o(.text*) + *:hal_uart.o(.text*) + *:hal_trace.o(.text*) +#endif + +#if defined(BTUSB_AUDIO_MODE) + *:hal_usb.o(.text*) + + *:usb_audio.o(.text*) + *:usb_audio_sync.o(.text*) + *:usb_audio_cdc.o(.text*) + + *:usbaudio_entry.o(.text*) + *:usb_audio_app.o(.text*) +#endif + + /* memmove.o or libc_nano.a(lib_a-memmove.o) */ + *:memmove.o(.text*) + *:lib_a-memmove.o(.text*) + *:utils.o(.text*) + *:cqueue.o(.text*) + *:audio_resample_ex.o(.text*) +#if defined(MIX_MIC_DURING_MUSIC) + *:app_bt_stream.o(.text*) +#endif +#if defined(HFP_1_6_ENABLE) +#if defined(__SBC_FUNC_IN_ROM__) || (defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0)) + *:sbc.o(.text*) +#else + *:sbc.o(.text*.sbc_is_stream_info_valid) + *:sbc.o(.text*.sbc_frame_length_get) + *:sbc.o(.text*.sbc_4bit_crc_calc) + *:sbc.o(.text*.sbc_bits_for_mono_alloc) + *:sbc.o(.text*.sbc_bits_for_stereo_alloc) + *:sbc.o(.text*.sbc_header_process) + *:sbc.o(.text*.sbc_factors_process) + *:sbc.o(.text*.sbc_sample_extract) + *:sbc.o(.text*.sbc_sbsamples_make) + *:sbc.o(.text*.sbc_joint_process) + *:sbc.o(.text*.sbc_4band_synth_filter) + *:sbc.o(.text*.sbc_8band_synth_filter) + *:sbc.o(.text*.sbc_decoder_state_reset) + *:sbc.o(.text*.sbc_frame_mute) + *:sbc.o(.text*.sbc_frames_decode) + *:sbc.o(.text*.sbc_samples_quant) + *:sbc.o(.text*.sbc_decoder_init) + *:sbc.o(.text*.sbc_encoder_init) + *:sbc.o(.text*.sbc_frames_encode) +#endif + *:sbc_math.o(.text*) +#endif +#if defined(A2DP_AAC_ON) + *:fixpoint_math.o(.text*) + *:FDK_bitbuffer.o(.text*) + *:FDK_tools_rom.o(.text*FDKgetWindowSlope*) + *:FDK_tools_rom.o(.text*getBitstreamElementList*) + *:dct.o(.text*dct_IV*) +#if !defined(__SBC_FUNC_IN_ROM_VBEST2000__) + *:fft.o(.text*._Z3fftiPlPi) + *:fft_rad2.o(.text*dit_fft*) + *:dct.o(.text*getTables*) +#endif +#if defined(OPUS_IN_OVERLAY) + *:voice_opus.o(.text*) +#elif defined(VOICE_DATAPATH) || defined(__ALEXA_WWE) || defined(__KWS_ALEXA__) + *:opus_encoder.o(.text*) +#elif defined(__AI_VOICE__) && (RAM_SIZE >= 0x48000) + *:voice_opus.o(.text*) + /**:opus_encoder.o(.text*)*/ + *:opus_encoder.o(.text*.frame_size_select) + *:opus_encoder.o(.text*.opus_encode_native) + *:opus_encoder.o(.text*.user_bitrate_to_bitrate) + *:opus_encoder.o(.text*.compute_equiv_rate) + *:opus_encoder.o(.text*.decide_fec) + *:opus_encoder.o(.text*.dc_reject) + *:opus_encoder.o(.text*.gen_toc) + *:opus_encoder.o(.text*.opus_encode) + *:opus_encoder.o(.text*.opus_encoder_create) + *:opus_encoder.o(.text*.opus_encoder_get_size) + *:opus_encoder.o(.text*.opus_encoder_init) + *:opus_encoder.o(.text*.opus_encoder_ctl) + *:analysis.o(.text*) + /**:celt_encoder.o(.text*)*/ + *:celt_encoder.o(.text*.opus_custom_encoder_ctl) + *:celt_encoder.o(.text*.celt_encoder_get_size) + *:celt_encoder.o(.text*.opus_custom_encoder_get_size) + *:celt_encoder.o(.text*.celt_encoder_init) + *:celt_encoder.o(.text*.opus_custom_encoder_init_arch) + /**:repacketizer.o(.text*)*/ + *:repacketizer.o(.text*.opus_packet_pad) + *:repacketizer.o(.text*.opus_repacketizer_init) + *:repacketizer.o(.text*.opus_repacketizer_cat) + *:repacketizer.o(.text*.opus_repacketizer_cat_impl) + *:repacketizer.o(.text*.opus_repacketizer_out_range_impl) + *:opus.o(.text*) + *:enc_API.o(.text*) + /**:entenc.o(.text*)*/ + *:entenc.o(.text*.ec_enc_init) + *:entenc.o(.text*.ec_enc_icdf) + *:entenc.o(.text*.ec_enc_normalize) + *:entenc.o(.text*.ec_enc_carry_out) + *:entenc.o(.text*.ec_write_byte) + *:entenc.o(.text*.ec_enc_patch_initial_bits) + *:entenc.o(.text*.ec_enc_done) + *:control_audio_bandwidth.o(.text*) + *:encode_pulses.o(.text*) + *:LPC_analysis_filter.o(.text*) + *:burg_modified_FIX.o(.text*.silk_burg_modified_c) + *:vector_ops_FIX.o(.text*.silk_scale_copy_vector16) + *:vector_ops_FIX.o(.text*.silk_inner_prod_aligned) + *:vector_ops_FIX.o(.text*.silk_inner_prod16_aligned_64_c) + *:NLSF_del_dec_quant.o(.text*.silk_NLSF_del_dec_quant) + *:encode_frame_FIX.o(.text*.silk_encode_frame_FIX) + *:encode_frame_FIX.o(.text*.silk_encode_do_VAD_FIX) + *:encode_frame_FIX.o(.text*.silk_LBRR_encode_FIX) + /**:pitch.o(.text*)*/ + *:pitch.o(.text*.celt_pitch_xcorr_c) + *:resampler.o(.text*) + *:VAD.o(.text*) + *:encode_indices.o(.text*) + /**:control_codec.o(.text*)*/ + *:control_codec.o(.text*.silk_control_encoder) + *:control_codec.o(.text*.silk_setup_resamplers) + *:control_codec.o(.text*.silk_setup_fs) + *:control_codec.o(.text*.silk_setup_complexity) + *:control_codec.o(.text*.silk_setup_LBRR) + /**:celt_lpc.o(.text*)*/ + *:celt_lpc.o(.text*._celt_autocorr) + /**:shell_coder.o(.text*)*/ + *:shell_coder.o(.text*.combine_pulses) + *:shell_coder.o(.text*.silk_shell_encoder) + *:shell_coder.o(.text*.encode_split) + *:init_encoder.o(.text*) + *:log2lin.o(.text*) + *:biquad_alt.o(.text*) + *:stereo_encode_pred.o(.text*) + *:NLSF_unpack.o(.text*) + *:code_signs.o(.text*) + *:lin2log.o(.text*) + *:HP_variable_cutoff.o(.text*) + *:sum_sqr_shift.o(.text*) + *:inner_prod_aligned.o(.text*) + *:stereo_quant_pred.o(.text*) + *:entcode.o(.text*) + *:celt.o(.text*) + *:laplace.o(.text*) + /**:NSQ.o(.text*)*/ /*complexity 1*/ + /**:NSQ_del_dec.o(.text*)*/ /*complexity 2*/ +#endif +#endif + +#if defined(AI_CAPTURE_DATA_AEC) + *:coherence.o(.text*) + *:echo_canceller.o(.text*) + *:echo_suppression.o(.text*) + *:lcmmse.o(.text*) + *:logmmse.o(.text*) + *:mdf2.o(.text*) + *:noise_generator.o(.text*) + *:pink_noise_gen.o(.text*) + *:white_noise_gen.o(.text*) +#endif + +#if defined(__AUDIO_SPECTRUM__) + *:spectrum_fix.o(.text*) + *:audio_spectrum.o(.text*) +#endif +#if defined(A2DP_SCALABLE_ON) && defined(A2DP_AAC_ON) + *:mdct.o(.text*) +#endif + *:crossover_filter.o(.text*) + *:data_compressor.o(.text*) + *:drc.o(.text*) + *:limiter.o(.text*) + *:iir_process.o(.text*.iir_run .text*.*iir_run_per_*) + +#if defined(KWS_BES) + *:arm_*.o(.text*) + *:mfcc.o(.text*) + *:cnn.o(.text*) +#ifndef __KWS_TIANMAO__ + *:command_recognition.o(.text*) +#endif + *:arm_radix8_butterfly_f32.o(.text*) + *:arm_bitreversal_32.o(.text*) + *:arm_bitreversal_16.o(.text*) + *:dct.o(.text*dct_IV*) + *:fft.o(.text*._Z3fftiPlPi) + *:fft_rad2.o(.text*dit_fft*) + *:dct.o(.text*getTables*) + *:arm_cfft_radix8_f32.o(.text*) + *:arm_bitreversal2.o(.text*) + *:arm_mult_f32.o(.text*) + *:arm_cmplx_mag_squared_f32.o(.text*) + *:arm_cmplx_mult_cmplx_f32.o(.text*) + *:lib_a-wf_sqrt.o(.text*) + *:arm_abs_f32.o(.text*) + *:arm_cos_f32.o(.text*) + *:arm_sin_f32.o(.text*) + + *:coherence.o(.text*) + *:echo_canceller.o(.text*) + *:echo_suppression.o(.text*) + *:lcmmse.o(.text*) + *:logmmse.o(.text*) + *:mdf2.o(.text*) + *:noise_generator.o(.text*) + *:pink_noise_gen.o(.text*) + *:white_noise_gen.o(.text*) + + *:ae_common.o(.text*) + *:ae_rand.o(.text*) + *:fastmath.o(.text*) + *:integer_delay.o(.text*) + *:iirfilt.o(.text*) + *:ringbuf.o(.text*) + *:scale_int16.o(.text*) + *:speech_conv.o(.text*) + *:speech_trans_buf.o(.text*) + + *:ns3.o(.text*) + *:noise_suppression_x.o(.text*) + *:nsx_core.o(.text*) + *:nsx_core_c.o(.text*) + *:copy_set_operations.o(.text*) + *:cross_correlation.o(.text*) + *:division_operations.o(.text*) + *:dot_product_with_scale.o(.text*) + *:downsample_fast.o(.text*) + *:energy.o(.text*) + *:get_scaling_square.o(.text*) + *:min_max_operations.o(.text*) + *:real_fft.o(.text*) + *:resample_by_2.o(.text*) + *:resample_by_2_internal.o(.text*) + *:spl_init.o(.text*) + *:spl_sqrt.o(.text*) + *:spl_sqrt_floor.o(.text*) + *:vector_scaling_operations.o(.text*) +#endif +#if !defined(SCO_OPTIMIZE_FOR_RAM) + :audio_prompt_sbc.o(.text*) +#endif + *(.fast_text_sram*) + /* + If you want protect one section by armv8's mpu, the section should + be aligned to 32bytes + */ + . = ALIGN(32); + __fast_sram_text_exec_end__ = .; + } > FRAMX + + __fast_sram_text_data_end_flash__ = __fast_sram_text_data_start_flash__ + SIZEOF(.fast_text_sram); + __fast_sram_text_data_start__ = RAMX_TO_RAM(__fast_sram_text_exec_start__); + __fast_sram_text_data_end__ = RAMX_TO_RAM(__fast_sram_text_exec_end__); + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + __cp_text_sram_start_flash__ = __fast_sram_text_data_end_flash__; + + .cp_text_sram (ORIGIN(RAMCPX)) : AT (__cp_text_sram_start_flash__) + { + __cp_text_sram_exec_start__ = .; + *(.cp_text_sram*) + *:cp_queue.o(.text*) +#if defined(GSOUND_HOTWORD_EXTERNAL) + //*:libspeech*.o(.text*) +#endif + . = ALIGN(4); + __cp_text_sram_exec_end__ = .; + } > RAMCPX + + __cp_text_sram_start = RAMX_TO_RAM(__cp_text_sram_exec_start__); + __cp_text_sram_end = RAMX_TO_RAM(__cp_text_sram_exec_end__); + + .vector_table_cp (ORIGIN(RAMCP)) (NOLOAD) : + { + KEEP(*(.vector_table_cp)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAMCP + + __cp_data_sram_start_flash__ = __cp_text_sram_start_flash__ + SIZEOF(.cp_text_sram); + + .cp_data_sram (.) : AT (__cp_data_sram_start_flash__) + { + __cp_data_sram_start = .; + *(.cp_data*) + *:cp_queue.o(.data* .rodata*) +#if defined(GSOUND_HOTWORD_EXTERNAL) + //*:libspeech*.o(.data* .rodata*) +#endif + . = ALIGN(4); + __cp_data_sram_end = .; + } > RAMCP + + __cp_sram_end_flash__ = __cp_data_sram_start_flash__ + SIZEOF(.cp_data_sram); + + .cp_bss_sram (.) (NOLOAD) : AT (ADDR(.cp_bss_sram)) + { + __cp_bss_sram_start = .; + *(.cp_bss*) + . = ALIGN(4); + __cp_bss_sram_end = .; + } > RAMCP + + __overlay_text_start_flash__ = __cp_sram_end_flash__; +#else + __overlay_text_start_flash__ = __fast_sram_text_data_end_flash__; +#endif + +#ifdef OVERLAY_FOR_CP + __overlay_text_start__ = __cp_text_sram_end; +#else + __overlay_text_start__ = __fast_sram_text_data_end__; +#endif + __overlay_text_exec_start__ = RAM_TO_RAMX(__overlay_text_start__); + + OVERLAY (__overlay_text_exec_start__) : NOCROSSREFS AT (__overlay_text_start_flash__) + { +#ifndef NO_OVERLAY + .overlay_text0 + { + LONG(0); + +#if !defined(GLOBAL_SRAM_KISS_FFT) + *:kiss_fft.o(.text*) + *:kiss_fftr.o(.text*) + *:fftwrap.o(.text*) +#endif + +#if !defined(GLOBAL_SRAM_CMSIS_FFT) + *:cmsis_fftwrap.o(.text*) + *:arm_rfft_fast_f32.o(.text*) + *:arm_cfft_f32.o(.text*) +#endif + +#if defined(SCO_OPTIMIZE_FOR_RAM) + *:arm_biquad_cascade_df1_f32.o(.text*) + *:integer_delay.o(.text*) + *:lc_mmse_ns_float.o(.text*.speech_ns2float_process) + *:coherence.o(.text*) + *:echo_suppression.o(.text*.float_cmp) + *:echo_suppression.o(.text*.es_process) + *:lcmmse.o(.text*.lcmmse_noise_estimate) + *:lcmmse.o(.text*.lcmmse_get_speech_prob) + *:logmmse.o(.text*.filterbank_compute_bank_pflt) + *:logmmse.o(.text*.filterbank_compute_psd_pflt) + *:logmmse.o(.text*.logmmse_analysis) + *:logmmse.o(.text*.logmmse_process) +#if defined(CHIP_BEST1402) || defined(CHIP_BEST1400) + *:lpc_plc.o(.text*.WB_PLC_common) + *:lpc_plc.o(.text*.WB_PLC_erasure) + *:lpc_plc.o(.text*.apfilterQ1_Q0) + *:lpc_plc.o(.text*.apfilterQ0_Q0) + *:lpc_plc.o(.text*.azfilterQ0_Q1) + *:lpc_plc.o(.text*.decim) + *:lpc_plc.o(.text*.merit) +#endif +#else + /* common */ +#if !defined(AUDIO_ANC_FB_ADJ_MC) + *:ae_common.o(.text*) + *:ae_rand.o(.text*) + *:fastmath.o(.text*) + *:integer_delay.o(.text*) + *:iirfilt.o(.text*) + *:ringbuf.o(.text*) +#endif + *:scale_int16.o(.text*) + *:speech_conv.o(.text*) + *:speech_trans_buf.o(.text*) + +#if !defined(SCO_CP_ACCEL) + *:frame_resize.o(.text*) + *:buffer_manager.o(.text*) + *:plc_8000.o(.text*) +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.text*) +#endif +#if defined(HFP_1_6_ENABLE) + *:dspfns.o(.text*) + *:lpc_plc.o(.text*) + *:plc_16000.o(.text*) + *:sbc_filter.o(.text*) +#endif +#endif + *:preprocess.o(.text*) + *:filterbank.o(.text*) + *:mdf.o(.text*) +#if defined(SPEECH_TX_2MIC_NS) + *:webrtc_vad.o(.text*.WebRtcVad_Process) + *:webrtc_vad.o(.text*.WebRtcVad_ValidRateAndFrameLength) + *:webrtc_vad.o(.text*.WebRtcVad_CalcVad16khz) + *:webrtc_vad.o(.text*.WebRtcVad_Downsampling) + *:webrtc_vad.o(.text*.WebRtcVad_CalcVad8khz) + *:vad_filterbank.o(.text*) + *:energy.o(.text*) + *:get_scaling_square.o(.text*) + *:dual_mic_denoise.o(.text*) + *:cross_correlation.o(.text*) + *:min_max_operations.o(.text*) + *:resample_by_2_internal.o(.text*) + *:division_operations.o(.text*) + *:downsample_fast.o(.text*) + *:resample_fractional.o(.text*) + *:resample_48khz.o(.text*) + *:vad_sp.o(.text*) + *:vad_core.o(.text*) + *:webrtc_vad.o(.text*) + *:vad_gmm.o(.text*) +#endif +#if defined(SPEECH_TX_2MIC_NS2) + *:speech_2mic_ns2_denoise.o(.text*) +#endif +#if defined(SPEECH_TX_2MIC_NS4) + *:sensormic_denoise.o(.text*) +#endif +#if defined(SPEECH_TX_2MIC_NS5) + *:leftright_denoise.o(.text*) +#endif +#if defined(SPEECH_TX_NS2) || defined(SPEECH_RX_NS2) + *:lc_mmse_ns.o(.text*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) || defined(SPEECH_RX_NS2FLOAT) + *:lc_mmse_ns_float.o(.text*) +#endif +#if defined(SPEECH_TX_NS3) || defined(SPEECH_RX_NS3) + *:ns3.o(.text*) + *:noise_suppression_x.o(.text*) + *:nsx_core.o(.text*) + *:nsx_core_c.o(.text*) + *:copy_set_operations.o(.text*) + *:cross_correlation.o(.text*) + *:division_operations.o(.text*) + *:dot_product_with_scale.o(.text*) + *:downsample_fast.o(.text*) + *:energy.o(.text*) + *:get_scaling_square.o(.text*) + *:min_max_operations.o(.text*) + *:real_fft.o(.text*) + *:resample_by_2.o(.text*) + *:resample_by_2_internal.o(.text*) + *:spl_init.o(.text*) + *:spl_sqrt.o(.text*) + *:spl_sqrt_floor.o(.text*) + *:vector_scaling_operations.o(.text*) +#endif +#if defined(SPEECH_TX_AEC2FLOAT) && !defined(AUDIO_ANC_FB_ADJ_MC) + *:coherence.o(.text*) + *:echo_canceller.o(.text*) + *:echo_suppression.o(.text*) + *:lcmmse.o(.text*) + *:logmmse.o(.text*) + *:mdf2.o(.text*) + *:noise_generator.o(.text*) + *:pink_noise_gen.o(.text*) + *:white_noise_gen.o(.text*) +#endif +#if defined(SPEECH_TX_AEC3) + *:SubBandBasedAEC.o(.text*) +#endif +#if defined(SPEECH_TX_3MIC_NS) + *:speech_3mic_ns.o(.text*) +#endif +#if defined(MSBC_8K_SAMPLE_RATE) + *:iir_resample.o(.text*) +#endif +#if defined(SPEECH_TX_COMPEXP) + *:compexp.o(.text*) +#endif +#if defined(SPEECH_TX_EQ) || defined(SPEECH_RX_EQ) || defined(MSBC_8K_SAMPLE_RATE) + *:speech_eq.o(.text*) + *:speech_arm_eq.o(.text*) + *:arm_biquad_cascade_df1_f32.o(.text*) +#endif +#if defined(SPEECH_TX_POST_GAIN) || defined(SPEECH_RX_POST_GAIN) + *:speech_gain.o(.text*) +#endif +#if defined(__SMARTVOICE__) +#if defined(SPEECH_TX_2MIC_NS2) || defined(SPEECH_TX_NS2) + *:app_smartvoice.o(.text*._Z23mic_data_process_deinitv) + *:app_smartvoice.o(.text*._Z21mic_data_process_initv) + *:app_smartvoice.o(.text*._Z20mic_data_process_runPsm) +#endif +#endif + +#endif // #if !defined(SCO_OPTIMIZE_FOR_RAM) + *(.overlay_text0) + . = ALIGN(4); + } + .overlay_text1 + { + LONG(0); +#if !defined(RB_CODEC) +#if !defined(HFP_1_6_ENABLE) + *:sbc.o(.text*) + *:sbc_math.o(.text*) +#endif + *:fixedpoint.o(.text*) + *:replaygain.o(.text*) + *:dsp_core.o(.text*) + *:dsp_misc.o(.text*) + *:dsp_filter.o(.text*) + *:dsp_sample_input.o(.text*) + *:dsp_sample_output.o(.text*) + *:eq.o(.text*) + *:pga.o(.text*) +#if !defined(A2DP_AAC_ON) && !defined(A2DP_LHDC_ON) + *:fir_process.o(.text*) +#endif +#endif +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) +#endif + *(.overlay_a2dp_sbc*) + *(.overlay_text1) + . = ALIGN(4); + } + .overlay_text2 + { + LONG(0); + *:fmdec.o(.text* .data* .rodata* .bss*) + *(.overlay_text2) + . = ALIGN(4); + } + .overlay_text3 + { + LONG(0); + *:fft128dot.o(.text*) + *(.overlay_text3) + . = ALIGN(4); + } + .overlay_text4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:block.o(.text*.*CBlock_GetEscape*) + *:tpdec_lib.o(.text*.*transportDec_GetBitstream*) + *:tpdec_lib.o(.text*.*transportDec_GetAuBitsRemaining*) + *:tpdec_latm.o(.text*.*CLatmDemux_GetValue*) + *:tpdec_latm.o(.text*.*CLatmDemux_Read*) + *:tpdec_lib.o(.text*.*transportDec_FillData*) + *:tpdec_lib.o(.text*.*transportDec_ReadAccessUnit*) + *:tpdec_lib.o(.text*.*transportDec_readHeader*) + *:block.o(.text*.*ApplyTools*) + *:aacdec_pns.o(.text*.*CPns_Apply*) + *:aacdec_tns.o(.text*.*CTns_Apply*) + *:aacdec_tns.o(.text*.*CTns_Reset*) + *:aacdec_pns.o(.text*.*CPns_ResetData*) + *:pulsedata.o(.text*.*CPulseData_Read*) +#if !defined(AAC_TEXT_PARTIAL_IN_FLASH) + *:channel.o(.text*.*CChannelElement_Read*) + *:tpdec_asc.o(.text*.*CProgramConfig_Reset*) + *:tpdec_lib.o(.text*.*transportDec_CrcCheck*) + *:block.o(.text*.*CBlock_FrequencyToTime*) + *:block.o(.text*.*CBlock_ReadSectionData*) + *:channel.o(.text*.*CChannelElement_Decode*) + *:tpdec_lib.o(.text*.*transportDec_CrcEndReg*) + *:aacdecoder.o(.text*.*CAacDecoder_DecodeFrame*) + *:mdct.o(.text*) +#endif + +#if !defined(__SBC_FUNC_IN_ROM_VBEST2000__) && !defined(AAC_TEXT_PARTIAL_IN_FLASH) + *:block.o(.text*.*CBlock_ReadSpectralData*) + *:block.o(.text*.*CBlock_ScaleSpectralData*) + *:aacdec_tns.o(.text*.*CTns_ReadDataPresentFlag*) + *:tpdec_lib.o(.text*.*transportDec_CrcStartReg*) + *:block.o(.text*.*CBlock_ReadScaleFactorData*) + *:tpdec_lib.o(.text*.*transportDec_EndAccessUnit*) + *:tpdec_latm.o(.text*.*CLatmDemux_GetNrOfSubFrames*) + *:tpdec_lib.o(.text*.*transportDec_GetAuBitsTotal*) + *:tpdec_asc.o(.text*.*CProgramConfig_LookupElement*) + *:tpdec_latm.o(.text*.*CLatmDemux_GetFrameLengthInBits*) + *:tpdec_latm.o(.text*.*CLatmDemux_ReadPayloadLengthInfo*) + *:block.o(.text*.*CBlock_InverseQuantizeSpectralData*) + *:channelinfo.o(.text*.*IcsRead*) + *:aacdec_tns.o(.text*.*CTns_Read*) + *:tpdec_lib.o(.text*.*transportDec_AdjustEndOfAccessUnit*) + *:pulsedata.o(.text*.*CPulseData_Apply*) + *:tpdec_asc.o(.text*.*AudioSpecificConfig_Init*) + *:tpdec_asc.o(.text*.*AudioSpecificConfig_Parse*) + *:tpdec_latm.o(.text*.*CLatmDemux_ReadStreamMuxConfig*) + *:tpdec_asc.o(.text*.*getSampleRate*) + *:tpdec_asc.o(.text*.*getAOT*) + *:aacdecoder.o(.text*.*CAacDecoder_Init*) + *:tpdec_asc.o(.text*.*CProgramConfig_Init*) + *:aacdecoder_lib.o(.text*.*aacDecoder_ConfigCallback*) + *:aacdecoder.o(.text*.*CAacDecoder_ExtPayloadParse*) + *:stereo.o(.text*.*CJointStereo_Read*) +#endif +#endif +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + *:a2dp_decoder_aac_lc.o(.text*) + *:fdkaac_codec.o(.text*) +#endif + *(.overlay_a2dp_aac*) + *(.overlay_text4) + . = ALIGN(4); + } + .overlay_text5 + { + LONG(0); + *:mpa.o(.text*) + *:bit.o(.text*) + *:frame.o(.text*) + *:huffman.o(.text*) + *:layer12.o(.text*) + *:layer3.o(.text*) + *:stream.o(.text*) + *:synth.o(.text*) + *(.overlay_text5) + . = ALIGN(4); + } + .overlay_text6 + { + LONG(0); +#if defined(A2DP_SCALABLE_ON) + *:rc_decode.o(.text*) + *:audio_int32.o(.text*) + *:ssc_ifft.o(.text*) + *:util.o(.text*) + *:vector_quant.o(.text*) + *:ssc_quant.o(.text*) + *:ssc_pulsealloc.o(.text*) + *:audio.o(.text*) + *:set_sbm.o(.text*) + *:rc_code.o(.text*) + *:SBM_pitchBased.o(.text*) + *:ssc_imdct.o(.text*) + *:audio_decoder.o(.text*) + *:SoundBooster_DRC_classic.o(.text*) + *:ssc_cwrs.o(.text*) + *:ssc_mode.o(.text*) + *:ssc_math.o(.text*) + *:ssc_lap.o(.text*) + *:SeamlessBufferManagement.o(.text*) +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + *:a2dp_decoder_scalable.o(.text*) +#endif + *(.overlay_a2dp_ssc*) +#endif + +#if defined(A2DP_LHDC_ON) + *(.overlay_a2dp_lhdc*) + *:a2dp_decoder_lhdc.o(.text*) + *:testkey.o(.text*) + *:lhdcUtil.o(.text*) + *:lzh_dec.o(.text*) + *:licdecrypt.o(.text*) + *:lic_check.o(.text*) + *:fast_upsampling_2x.o(.text*) + *:encdec.o(.text*) + *:dec.o(.text*) + *:cirbuf.o(.text*) + *:DecodeUps2xLPF.o(.text*) + *:Arc.o(.text*) +#endif + + *(.overlay_text6) + . = ALIGN(4); + } + .overlay_text7 + { + LONG(0); +#if defined(A2DP_LDAC_ON) + *:a2dp_decoder_ldac.o(.text*) + *:bitalloc_ldac.o(.text*) + *:bitalloc_sub_ldac.o(.text*) + *:encode_ldac.o(.text*) + *:ldacBT.o(.text*) + *:ldaclib.o(.text*) + *:pack_ldac.o(.text*) + *:quant_ldac.o(.text*) + *:mdct_ldac.o(.text*) + *:ldacBT_api.o(.text*) + *:decode_ldac.o(.text*) + *:dequant_ldac.o(.text*) + *:imdct_ldac.o(.text*) + *:ldacBT_internal.o(.text*) + *:ldaclib_api.o(.text*) + *:memory_ldac.o(.text*) + *:setpcm_ldac.o(.text*) + *:sigana_ldac.o(.text*) + *:tables_ldac.o(.text*) + *:tables_sigproc_ldac.o(.text*) + *:unpack_ldac.o(.text*) + *(.overlay_a2dp_ldac*) +#endif +#if defined(OPUS_IN_OVERLAY) + /**:voice_opus.o(.text*)*/ + *:opus_encoder.o(.text*) + *:analysis.o(.text*) + /**:celt_encoder.o(.text*)*/ + *:celt_encoder.o(.text*.opus_custom_encoder_ctl) + *:celt_encoder.o(.text*.celt_encoder_get_size) + *:celt_encoder.o(.text*.opus_custom_encoder_get_size) + *:celt_encoder.o(.text*.celt_encoder_init) + *:celt_encoder.o(.text*.opus_custom_encoder_init_arch) + *:celt_encoder.o(.text*.transient_analysis) + *:celt_encoder.o(.text*.patch_transient_decision) + *:celt_encoder.o(.text*.celt_preemphasis) + *:celt_encoder.o(.text*.l1_metric) + *:celt_encoder.o(.text*.tf_analysis) + *:celt_encoder.o(.text*.tf_encode) + *:celt_encoder.o(.text*.alloc_trim_analysis) + *:celt_encoder.o(.text*.stereo_analysis) + *:celt_encoder.o(.text*.median_of_5) + *:celt_encoder.o(.text*.median_of_3) + *:celt_encoder.o(.text*.dynalloc_analysis) + *:celt_encoder.o(.text*.run_prefilter) + *:celt_encoder.o(.text*.compute_vbr) + *:celt_encoder.o(.text*.celt_encode_with_ec) + *:celt_encoder.o(.text*.opus_custom_encoder_ctl) + *:repacketizer.o(.text*) + *:opus.o(.text*) + *:enc_API.o(.text*) + *:entenc.o(.text*) + *:control_audio_bandwidth.o(.text*) + *:encode_pulses.o(.text*) + *:LPC_analysis_filter.o(.text*) + *:burg_modified_FIX.o(.text*) + *:vector_ops_FIX.o(.text*) + *:NLSF_del_dec_quant.o(.text*) + *:encode_frame_FIX.o(.text*) + *:pitch.o(.text*) + *:resampler.o(.text*) + *:VAD.o(.text*) + *:encode_indices.o(.text*) + *:control_codec.o(.text*) + *:celt_lpc.o(.text*) + *:shell_coder.o(.text*) + *:init_encoder.o(.text*) + *:log2lin.o(.text*) + *:biquad_alt.o(.text*) + *:stereo_encode_pred.o(.text*) + *:NLSF_unpack.o(.text*) + *:code_signs.o(.text*) + *:lin2log.o(.text*) + *:HP_variable_cutoff.o(.text*) + *:sum_sqr_shift.o(.text*) + *:inner_prod_aligned.o(.text*) + *:stereo_quant_pred.o(.text*) + *:entcode.o(.text*) + *:celt.o(.text*) + *:laplace.o(.text*) + *:NSQ.o(.text*) /*complexity 1*/ + *:NSQ_del_dec.o(.text*) /*complexity 2*/ +#endif + *(.overlay_text7) + . = ALIGN(4); + } +#endif + .overlay_text_last + { + LONG(0); + . = ALIGN(4); + } + } > REGION_OVERLAY_TEXT + + .dummy_overlay_text_end (.) (NOLOAD) : AT (ADDR(.dummy_overlay_text_end)) + { + __overlay_text_exec_end__ = .; + } > REGION_OVERLAY_TEXT + +#ifdef OVERLAY_FOR_CP + __fast_sram_end__ = __fast_sram_text_data_end__; +#else + __fast_sram_end__ = RAMX_TO_RAM(__overlay_text_exec_end__); +#endif + + ASSERT(__fast_sram_end__ - __fast_sram_text_data_start__ <= FAST_XRAM_SECTION_SIZE, "fast xram sections too large") + __free_fram = FAST_XRAM_SECTION_SIZE - (__fast_sram_end__ - __fast_sram_text_data_start__); + +#ifdef OVERLAY_FOR_CP + __overlay_data_start__ = __cp_bss_sram_end; +#else + __overlay_data_start__ = __sram_bss_end__; +#endif + + OVERLAY (__overlay_data_start__) : NOCROSSREFS AT (__load_stop_overlay_text_last) + { +#ifndef NO_OVERLAY + .overlay_data0 + { + /* Explicitly place 4 bytes at section start to avoid "section type changed to PROGBITS" warnings */ + LONG(0); +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + *:bt_sco_chain.o(.data* .rodata*) + *:bt_sco_chain_cp.o(.data* .rodata*) +#endif +#if !defined(SCO_OPTIMIZE_FOR_RAM) + +#if !defined(GLOBAL_SRAM_KISS_FFT) + *:fftwrap.o(.data* .rodata*) + *:kiss_fft.o(.data* .rodata*) + *:kiss_fftr.o(.data* .rodata*) +#endif + +#if !defined(GLOBAL_SRAM_CMSIS_FFT) + *:CommonTables.o(.rodata.armBitRevIndexTable256) + *:CommonTables.o(.rodata.twiddleCoef_256) + *:CommonTables.o(.rodata.twiddleCoef_rfft_512) + *:CommonTables.o(.rodata.armBitRevIndexTable128) + *:CommonTables.o(.rodata.twiddleCoef_128) + *:CommonTables.o(.rodata.twiddleCoef_rfft_256) +#endif + + /* common */ + *:fastmath_const.o(.data* .rodata*) + + *:preprocess.o(.data* .rodata*) + *:filterbank.o(.data* .rodata*) + +#if !defined(SCO_CP_ACCEL) + *:plc_8000.o(.data* .rodata*) +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.data* .rodata* .bss*) +#endif +#if defined(HFP_1_6_ENABLE) + *:table.o(.data* .rodata*) + *:plc_16000.o(.data* .rodata*) +#endif +#endif +#if !defined(AUDIO_ANC_FB_ADJ_MC) + *:mdf.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_2MIC_NS) + *:dual_mic_denoise.o(.data* .rodata*) + *:vad_filterbank.o(.data* .rodata*) + *:energy.o(.data* .rodata*) + *:get_scaling_square.o(.data* .rodata*) + + *:cross_correlation.o(.data* .rodata*) + *:min_max_operations.o(.data* .rodata*) + *:resample_by_2_internal.o(.data* .rodata*) + *:division_operations.o(.data* .rodata*) + *:downsample_fast.o(.data* .rodata*) + *:resample_fractional.o(.data* .rodata*) + *:resample_48khz.o(.data* .rodata*) + *:vad_sp.o(.data* .rodata*) + *:vad_core.o(.data* .rodata*) + *:webrtc_vad.o(.data* .rodata*) + *:vad_gmm.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_2MIC_NS2) + *:speech_2mic_ns2_denoise.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_2MIC_NS4) + *:sensormic_denoise.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_2MIC_NS5) + *:leftright_denoise.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS2) || defined(SPEECH_RX_NS2) + *:lc_mmse_ns.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS3) || defined(SPEECH_RX_NS3) + *:nsx_core.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) || defined(SPEECH_RX_NS2FLOAT) + *:lc_mmse_ns_float.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_3MIC_NS) + *:speech_3mic_ns.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_AEC3) + *:SubBandBasedAEC.o(.data* .rodata*) +#endif +#if defined(MSBC_8K_SAMPLE_RATE) + *:iir_resample.o(.data* .rodata*) +#endif + +#endif // #if !defined(SCO_OPTIMIZE_FOR_RAM) + *(.overlay_data0 .overlay_rodata0) + . = ALIGN(4); + } + .overlay_data1 + { + LONG(0); +#if !defined(RB_CODEC) +#if !defined(HFP_1_6_ENABLE) + *:sbc.o(.data* .rodata*) + *:sbc_math.o(.data* .rodata*) +#endif + *:fixedpoint.o(.data* .rodata*) + *:replaygain.o(.data* .rodata*) + *:dsp_core.o(.data* .rodata*) + *:dsp_misc.o(.data* .rodata*) + *:dsp_filter.o(.data* .rodata*) + *:dsp_sample_input.o(.data* .rodata*) + *:dsp_sample_output.o(.data* .rodata*) + *:eq.o(.data* .rodata*) + *:pga.o(.data* .rodata*) +#if !defined(A2DP_AAC_ON) + *:fir_process.o(.data* .rodata*) +#endif +#endif +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + *:a2dp_decoder_sbc.o(.rodata*) +#endif + *(.overlay_data1 .overlay_rodata1) + . = ALIGN(4); + } + .overlay_data2 + { + LONG(0); + *(.overlay_data2 .overlay_rodata2) + . = ALIGN(4); + } + .overlay_data3 + { + LONG(0); + *:fft128dot.o(.data* .rodata*) + *(.overlay_data3 .overlay_rodata3) + . = ALIGN(4); + } + .overlay_data4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:block.o(.data* .rodata*) + *:tpdec_lib.o(.data* .rodata*) + *:tpdec_latm.o(.data* .rodata*) + *:aacdec_pns.o(.data* .rodata*) + *:aacdec_tns.o(.data* .rodata*) + *:pulsedata.o(.data* .rodata*) + *:channel.o(.data* .rodata*) + *:tpdec_asc.o(.data* .rodata*) + *:aacdecoder.o(.data* .rodata*) + *:channelinfo.o(.data* .rodata*) + *:aacdecoder_lib.o(.data* .rodata*) + *:stereo.o(.data* .rodata*) + *:fixpoint_math.o(.data* .rodata*) + *:FDK_bitbuffer.o(.data* .rodata*) +#endif +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + *:a2dp_decoder_aac_lc.o(.rodata*) + *:fdkaac_codec.o(.rodata*) +#endif + *(.overlay_data4 .overlay_rodata4) + . = ALIGN(4); + } + .overlay_data5 + { + LONG(0); + *:mpa.o(.data* .bss*) + *:bit.o(.data* .bss*) + *:frame.o(.data* .bss*) + *:huffman.o(.data* .bss*) + *:layer12.o(.data* .bss*) + *:layer3.o(.data* .bss*) + *:stream.o(.data* .bss*) + *:synth.o(.data* .bss*) + *(.overlay_data5 .overlay_rodata5) + . = ALIGN(4); + } + .overlay_data6 + { + LONG(0); +#if defined(A2DP_SCALABLE_ON) + *:rc_decode.o(.data* .rodata*) + *:audio_int32.o(.data* .rodata*) + *:ssc_ifft.o(.data* .rodata*) + *:util.o(.data* .rodata*) + *:vector_quant.o(.data* .rodata*) + *:ssc_quant.o(.data* .rodata*) + *:ssc_pulsealloc.o(.data* .rodata*) + *:audio.o(.data* .rodata*) + *:set_sbm.o(.data* .rodata*) + *:rc_code.o(.data* .rodata*) + *:SBM_pitchBased.o(.data* .rodata*) + *:ssc_imdct.o(.data* .rodata*) + *:audio_decoder.o(.data* .rodata*) + *:SoundBooster_DRC_classic.o(.data* .rodata*) + *:ssc_cwrs.o(.data* .rodata*) + *:ssc_mode.o(.data* .rodata*) + *:ssc_math.o(.data* .rodata*) + *:ssc_lap.o(.data* .rodata*) + *:SeamlessBufferManagement.o(.data* .rodata*) +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + *:a2dp_decoder_scalable.o(.rodata*) +#endif +#endif +#if defined(A2DP_LHDC_ON) + *:a2dp_decoder_lhdc.o(.data* .rodata*) + *:testkey.o(.data* .rodata*) + *:lhdcUtil.o(.data* .rodata*) + *:lzh_dec.o(.data* .rodata*) + *:licdecrypt.o(.data* .rodata*) + *:lic_check.o(.data* .rodata*) + *:fast_upsampling_2x.o(.data* .rodata*) + *:encdec.o(.data* .rodata*) + *:dec.o(.data* .rodata*) + *:cirbuf.o(.data* .rodata*) + *:DecodeUps2xLPF.o(.data* .rodata*) + *:Arc.o(.data* .rodata*) +#endif + + *(.overlay_data6 .overlay_rodata6) + . = ALIGN(4); + } + .overlay_data7 + { + LONG(0); +#if defined(A2DP_LDAC_ON) + *:a2dp_decoder_ldac.o(.data* .rodata*) + *:bitalloc_ldac.o(.data* .rodata*) + *:bitalloc_sub_ldac.o(.data* .rodata*) + *:encode_ldac.o(.data* .rodata*) + *:ldacBT.o(.data* .rodata*) + *:ldaclib.o(.data* .rodata*) + *:pack_ldac.o(.data* .rodata*) + *:quant_ldac.o(.data* .rodata*) + *:mdct_ldac.o(.data* .rodata*) + *:ldacBT_api.o(.data* .rodata*) + *:decode_ldac.o(.data* .rodata*) + *:dequant_ldac.o(.data* .rodata*) + *:imdct_ldac.o(.data* .rodata*) + *:ldacBT_internal.o(.data* .rodata*) + *:ldaclib_api.o(.data* .rodata*) + *:memory_ldac.o(.data* .rodata*) + *:setpcm_ldac.o(.data* .rodata*) + *:sigana_ldac.o(.data* .rodata*) + *:tables_ldac.o(.data* .rodata*) + *:tables_sigproc_ldac.o(.data* .rodata*) + *:unpack_ldac.o(.data* .rodata*) +#endif + +#if defined(OPUS_IN_OVERLAY) + *:voice_opus.o(.data* .rodata*) + *:opus_encoder.o(.data* .rodata*) + *:analysis.o(.data* .rodata*) + *:celt_encoder.o(.data* .rodata*) + *:repacketizer.o(.data* .rodata*) + *:opus.o(.data* .rodata*) + *:enc_API.o(data* .rodata) + *:entenc.o(.data* .rodata*) + *:control_audio_bandwidth.o(.data* .rodata*) + *:encode_pulses.o(.data* .rodata*) + *:LPC_analysis_filter.o(.data* .rodata*) + *:burg_modified_FIX.o(.data* .rodata*) + *:vector_ops_FIX.o(.data* .rodata*) + *:NLSF_del_dec_quant.o(.data* .rodata*) + *:encode_frame_FIX.o(.data* .rodata*) + *:pitch.o(.data* .rodata*) + *:resampler.o(.data* .rodata*) + *:VAD.o(.data* .rodata*) + *:encode_indices.o(.data* .rodata*) + *:control_codec.o(.data* .rodata*) + *:celt_lpc.o(.data* .rodata*) + *:shell_coder.o(.data* .rodata*) + *:init_encoder.o(.data* .rodata*) + *:log2lin.o(.data* .rodata*) + *:biquad_alt.o(.data* .rodata*) + *:stereo_encode_pred.o(.data* .rodata*) + *:NLSF_unpack.o(.data* .rodata*) + *:code_signs.o(.data* .rodata*) + *:lin2log.o(.data* .rodata*) + *:HP_variable_cutoff.o(.data* .rodata*) + *:sum_sqr_shift.o(.data* .rodata*) + *:inner_prod_aligned.o(.data* .rodata*) + *:stereo_quant_pred.o(.data* .rodata*) + *:entcode.o(.data* .rodata*) + *:celt.o(.data* .rodata*) + *:laplace.o(.data* .rodata*) + *:NSQ.o(.data* .rodata*) /*complexity 1*/ + *:NSQ_del_dec.o(.data* .rodata*) /*complexity 2*/ +#endif + *(.overlay_data7 .overlay_rodata7) + . = ALIGN(4); + } +#endif + .overlay_data_last + { + LONG(0); + . = ALIGN(4); + } + } > REGION_OVERLAY_DATA + + .dummy_overlay_data_end (.) (NOLOAD) : AT (ADDR(.dummy_overlay_data_end)) + { + __overlay_data_end__ = .; + } > REGION_OVERLAY_DATA + + ASSERT(__overlay_data_end__ - __overlay_data_start__ <= OVERLAY_DATA_SECTION_SIZE, "overlay data sections too large") + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + .cp_ramx_last_dummy (NOLOAD) : AT (ADDR(.cp_ramx_last_dummy)) + { + __cp_ramx_last_dummy_start = .; + } > RAMCPX + + .cp_ram_last_dummy (NOLOAD) : AT (ADDR(.cp_ram_last_dummy)) + { + . = ALIGN(8); + __cp_ram_last_dummy_start = .; + } > RAMCP + + __cp_stack_top = ORIGIN(RAMCP) + LENGTH(RAMCP); + __cp_stack_limit = __cp_stack_top - CP_STACK_SECTION_SIZE; + + /* LD v2.24 (GCC 4.9) cannot handle address conversion correctly if involving immediate value. + E.g., + + */ + __free_ramcpx = ORIGIN(RAMCPX) + LENGTH(RAMCPX) - ABSOLUTE(__cp_ramx_last_dummy_start); + ASSERT(__cp_stack_limit >= __cp_ram_last_dummy_start, "region RAMCP overflowed with stack") + __free_ramcp = __cp_stack_limit - __cp_ram_last_dummy_start; +#endif + + .text (FLASH_TO_FLASHX(__load_stop_overlay_data_last)) : AT (FLASHX_TO_FLASH(ADDR(.text))) + { + *(.text*) + *(.flash_text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + } > FLASHX + + .ARM.extab (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.extab))) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASHX + + __exidx_start = .; + /* .ARM.exidx contains R_ARM_PREL31 (+-0x40000000) offset to functions, which means + * the session location cannot be too far away from the function addresses */ + .ARM.exidx (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.exidx))) + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASHX + __exidx_end = .; + + . = FLASHX_TO_FLASH(.); +#ifdef TRACE_STR_SECTION + .rodata_str (.): + { + __rodata_str_start__ = .; + *(.rodata.__func__.*) + *(.rodata.*__func__) + *(.rodata.__FUNCTION__.*) + *(.rodata.*__FUNCTION__) + __rodata_str_end__ = .; + } > FLASH + + RODATA_ADDRESS = .; + . = 0xFFFC0000; + .trc_str (.): + { + *(.rodata.__func__.*) + *(.rodata.*__func__) + *(.rodata.__FUNCTION__.*) + *(.rodata.*__FUNCTION__) + *(.trc_str*) + } + . = RODATA_ADDRESS; +#endif + .rodata (.) : + { + *(.rodata*) + *(.flash_rodata*) + + . = ALIGN(4); + __cust_cmd_hldr_tbl_start = .; + KEEP(*(.cust_cmd_hldr_tbl)) + __cust_cmd_hldr_tbl_end = .; + . = ALIGN(4); + __ai_gatt_server_table_start = .; + KEEP(*(.ai_gatt_server_table)) + __ai_gatt_server_table_end = .; + . = ALIGN(4); + __ai_ble_handler_table_start = .; + KEEP(*(.ai_ble_handler_table)) + __ai_ble_handler_table_end = .; + . = ALIGN(4); + __ai_spp_register_table_start = .; + KEEP(*(.ai_spp_register_table)) + __ai_spp_register_table_end = .; + . = ALIGN(4); + __tota_handler_table_start = .; + KEEP(*(.tota_handler_table)) + __tota_handler_table_end = .; + . = ALIGN(4); + __ai_handler_function_table_start = .; + KEEP(*(.ai_handler_function_table)) + __ai_handler_function_table_end = .; + . = ALIGN(4); + __custom_handler_table_start = .; + KEEP(*(.custom_handler_table)) + __custom_handler_table_end = .; + . = ALIGN(4); + __mixprompt_property_table_start = .; + KEEP(*(.mixprompt_property_table)) + __mixprompt_property_table_end = .; + KEEP(*(.eh_frame*)) + *(.note.gnu.build-id) + *(.constdata) + } > FLASH + +#if defined(FIRMWARE_REV) + .firmware_rev (.) : + { + . = ALIGN(64); + *(.fw_rev) + } > FLASH +#endif + + /* To copy multiple FLASH to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table (.) : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table (.) : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + /* Location counter can end up 2byte aligned with narrow Thumb code but + __etext is assumed by startup code to be the LMA of a section in RAM + which must be 4byte aligned */ + __etext = ALIGN(4); + + /* The VMA is either the end of overlay_data or the end of sram bss */ + + .data : AT (__etext) + { + __data_start__ = .; + + *(vtable) + . = ALIGN(4); + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + + /* All data end */ + . = ALIGN(4); + __data_end__ = .; + + } > RAM + + .bss (.) (NOLOAD) : AT (ADDR(.bss)) + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .reboot_custom_param (.) (NOLOAD) : + { + KEEP(*(.reboot_custom_param*)) + . = ALIGN(4); + __reboot_custom_param_end__ = .; + } > RAM + + .heap (.) (NOLOAD) : + { + . = ALIGN(8); + __HeapBase = .; + __end__ = .; + end = __end__; + . += HEAP_SECTION_SIZE; + . = ALIGN(8); + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (.) (COPY) : + { + . = STACK_SECTION_SIZE; + . = ALIGN(8); + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ +#if defined(ROM_UTILS_ON) + __StackTop = ORIGIN(RAM) + LENGTH(RAM) - ROM_UTILS_RESV_RAM_SIZE; +#else + __StackTop = ORIGIN(RAM) + LENGTH(RAM); +#endif + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + __free_ram = __StackLimit - __HeapLimit; + + . = __etext + SIZEOF(.data); + + .system_info (.) : + { + KEEP(*(.system_info_list_size)) + KEEP(*(.system_info_list)) + . = ALIGN(4); + } > FLASH + + .build_info (.) : + { + KEEP(*(.build_info)) + . = ALIGN(4); + } > FLASH = 0x00000000 + +#ifdef SLAVE_BIN_FLASH_OFFSET + .slave_code (ORIGIN(FLASH) + SLAVE_BIN_FLASH_OFFSET): + { + KEEP(*(.slave_code_flash_rodata)) + } > FLASH +#endif + + /* The following section MUST be the last loaded section */ + .code_start_addr (.) : + { +#ifdef TRACE_STR_SECTION + LONG(ABSOLUTE(__rodata_str_start__)); +#else + LONG(0); +#endif + LONG(BUILD_INFO_MAGIC); + LONG(ABSOLUTE(__flash_start)); + } > FLASH + + __flash_end = .; + + .hotword_model (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + LHDC_LICENSE_SECTION_SIZE - CRASH_DUMP_SECTION_SIZE - LOG_DUMP_SECTION_SIZE - + OTA_UPGRADE_LOG_SIZE - CORE_DUMP_SECTION_SIZE - HOTWORD_SECTION_SIZE) (NOLOAD): + { + __hotword_model_start = .; + . = HOTWORD_SECTION_SIZE; + __hotword_model_end = .; + } > FLASH_NC + + .coredump_section (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + LHDC_LICENSE_SECTION_SIZE - CRASH_DUMP_SECTION_SIZE - LOG_DUMP_SECTION_SIZE - + OTA_UPGRADE_LOG_SIZE - CORE_DUMP_SECTION_SIZE) (NOLOAD) : + { + __coredump_section_start = .; + . = CORE_DUMP_SECTION_SIZE; + __coredump_section_end = .; + } > FLASH_NC + + .ota_upgrade_log (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + LHDC_LICENSE_SECTION_SIZE - CRASH_DUMP_SECTION_SIZE - LOG_DUMP_SECTION_SIZE - + OTA_UPGRADE_LOG_SIZE) (NOLOAD) : + { + __ota_upgrade_log_start = .; + . = OTA_UPGRADE_LOG_SIZE; + __ota_upgrade_log_end = .; + } > FLASH_NC + + .log_dump (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + LHDC_LICENSE_SECTION_SIZE - CRASH_DUMP_SECTION_SIZE - LOG_DUMP_SECTION_SIZE) (NOLOAD) : + { + __log_dump_start = .; + . = LOG_DUMP_SECTION_SIZE; + __log_dump_end = .; + } > FLASH_NC + + .crash_dump (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + LHDC_LICENSE_SECTION_SIZE - CRASH_DUMP_SECTION_SIZE) (NOLOAD) : + { + __crash_dump_start = .; + . = CRASH_DUMP_SECTION_SIZE; + __crash_dump_end = .; + } > FLASH_NC + + .custom_parameter (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + LHDC_LICENSE_SECTION_SIZE) (NOLOAD) : + { + __custom_parameter_start = .; + . = CUSTOM_PARAMETER_SECTION_SIZE; + __custom_parameter_end = .; + } > FLASH_NC + + .lhdc_license (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - LHDC_LICENSE_SECTION_SIZE) (NOLOAD) : + { + __lhdc_license_start = .; + . = LHDC_LICENSE_SECTION_SIZE; + __lhdc_license_end = .; + } > FLASH_NC + + .userdata (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2) (NOLOAD) : + { + __userdata_start = .; + . = USERDATA_SECTION_SIZE*2; + __userdata_end = .; + } > FLASH_NC + + .audio (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE) (NOLOAD) : + { + __aud_start = .; + . = AUD_SECTION_SIZE; + __aud_end = .; + } > FLASH_NC + + .reserved (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE) (NOLOAD) : + { + __reserved_start = .; + . = RESERVED_SECTION_SIZE; + __reserved_end = .; + } > FLASH_NC + + .factory (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE) (NOLOAD) : + { + __factory_start = .; + . = FACTORY_SECTION_SIZE; + __factory_end = .; + } > FLASH_NC + +#ifdef OTA_BOOT_SIZE +#if (OTA_BOOT_SIZE > FLASH_SIZE) +#error "OTA_BOOT_SIZE should <= FLASH_SIZE" +#endif +#if defined(OTA_CODE_OFFSET) && (OTA_BOOT_SIZE > OTA_CODE_OFFSET) +#error "OTA_BOOT_SIZE should <= OTA_CODE_OFFSET" +#endif + __tail_section_start = FLASH_BASE + OTA_BOOT_SIZE; +#else + __tail_section_start = __hotword_model_start; +#endif + + ASSERT(FLASH_NC_TO_C(__tail_section_start) >= __flash_end, "region FLASH overflowed") + __free_flash = FLASH_NC_TO_C(__tail_section_start) - __flash_end; + +#if !defined(OTA_BOOT_SIZE) && defined(OTA_REMAP_OFFSET) + ASSERT((FLASH_BASE & 0x03FFFFFF) == 0, "bad FLASH_BASE") + ASSERT((FLASH_SIZE & (FLASH_SIZE - 1)) == 0, "bad FLASH_SIZE") +#ifdef CHIP_BEST2300P + ASSERT(__flash_end <= FLASH_BASE + OTA_REMAP_OFFSET, "flash code size too large to remap") + ASSERT(__flash_start - FLASH_BASE >= FLASH_NC_BASE + FLASH_SIZE - __tail_section_start, "flash code conflicted with tail sections in remap") + ASSERT(__flash_start - FLASH_BASE >= FLASH_SIZE / (1 << (4 + 1)), "flash code cannot remap within 4 regions (max code size is half of flash size)") + ASSERT((__flash_start - FLASH_BASE) % (FLASH_SIZE / (1 << (4 + 1))) == 0, "flash code start address not aligned with remap region boundary") +#else + ASSERT(((OTA_REMAP_OFFSET) & (0x1000 - 1)) == 0, "OTA_REMAP_OFFSET not aligned with 4K sector boundary") + ASSERT(__flash_end <= FLASH_BASE + (OTA_REMAP_OFFSET), "flash code size too large to remap") + ASSERT((__tail_section_start & (0x1000 - 1)) == 0, "__tail_section_start not aligned with 4K sector boundary") + ASSERT(__flash_end + (OTA_REMAP_OFFSET) <= __tail_section_start, "flash code conflicted with tail sections in remap") +#endif +#endif +} + diff --git a/scripts/link/best1000_fpga_rom.lds.S b/scripts/link/best1000_fpga_rom.lds.S new file mode 100644 index 0000000..55d9f93 --- /dev/null +++ b/scripts/link/best1000_fpga_rom.lds.S @@ -0,0 +1,320 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#define HEAP_SECTION_SIZE 0x400 +#define STACK_SECTION_SIZE 0x1000 +#define FAST_XRAM_SECTION_SIZE 0x3000 +/* Linker script to configure memory regions. */ +MEMORY +{ + ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE + RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE + RAMX (rwx) : ORIGIN = RAMX_BASE, LENGTH = RAM_SIZE + FRAMX (rwx) : ORIGIN = RAM_BASE + RAM_SIZE - FAST_XRAM_SECTION_SIZE, LENGTH = FAST_XRAM_SECTION_SIZE +} + +/* Library configurations */ +GROUP(libgcc.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions ROM and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __export_fn_rom + * __exidx_start + * __exidx_end + * __rom_etext + * __rom_data_start__ + * __rom_data_end__ + * __rom_bss_start__ + * __rom_bss_end__ + * __rom_HeapLimit + * __rom_StackLimit + * __rom_StackTop + * __rom_stack + * __Vectors_End + * __Vectors_Size + * __free_rom_ram + * __rom_end + * __free_rom + * __audio_const_rom_start + * __audio_const_rom_end + * __audio_const_rom_size + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .rom_text (ORIGIN(ROM)) : + { + __vector_table = .; + KEEP(*(.vectors_table)) + *(.text.Reset_Handler) + *(.text.System_Init) + . = ALIGN(4); + + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + + *(.text*) + +#ifndef NOSTD + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) +#endif + + . = ALIGN(4); + + *(.rodata*) + +#ifdef CHIP_HAS_AUDIO_CONST_ROM + __audio_const_rom_start = .; + KEEP(*audio_const_rom.o(.audio_const_index)) + KEEP(*audio_const_rom.o(.rodata*)) + __audio_const_rom_end = .; + __audio_const_rom_size = __audio_const_rom_end - __audio_const_rom_start; +#endif +#ifndef NOSTD + KEEP(*(.eh_frame*)) +#endif + *(.note.gnu.build-id) + + . = ALIGN(4); + } > ROM + + .rom_got_info (.) : + { + __rom_got_info_start = .; + __rom_got_start = .; + *(.got) + . = ALIGN(4); + __rom_got_end = .; + __rom_got_plt_start = .; + *(.got.plt) + . = ALIGN(4); + __rom_igot_plt_start = .; + *(.igot.plt) + . = ALIGN(4); + __rom_dynamic_start = .; + *(.dynamic) + . = ALIGN(4); + __rom_got_info_end = .; + } > ROM + + .ARM.extab (.) : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > ROM + + __exidx_start = .; + .ARM.exidx (.) : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ROM + __exidx_end = .; + + . = ALIGN(4); + + .custom.cmd.table (.) : + { + . = ALIGN(4); + __custom_handler_table_start = .; + KEEP(*(.custom_handler_table)) + __custom_handler_table_end = .; + } > ROM + + __rom_text0_end = .; + + .vector_table (ORIGIN(RAM)) (NOLOAD) : + { + KEEP(*(.vector_table)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .reboot_param (.) (NOLOAD) : + { + KEEP(*(.reboot_param)) + . = REBOOT_PARAM_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .rom_ramx (RAM_TO_RAMX(.)) : AT (__rom_text0_end) + { + __rom_ramx_start = .; + *(.rom_ramx) + . = ALIGN(4); + __rom_ramx_end = .; + } > RAMX + + __rom_etext = __rom_text0_end + SIZEOF(.rom_ramx); + + .rom_data (RAMX_TO_RAM(.)) : AT (__rom_etext) + { + __rom_data_start__ = .; + *(.data*) + . = ALIGN(4); + +#ifndef NOSTD + *(vtable) + + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); +#endif + + /* All data end */ + __rom_data_end__ = .; + } > RAM + + .rom_bss (.) (NOLOAD) : + { + . = ALIGN(4); + __rom_bss_start__ = .; + *(.bss*) + *(COMMON) + *(AHBSDRAM1) + . = ALIGN(4); + __rom_bss_end__ = .; +#ifndef NOSTD + __bss_start__ = __rom_bss_start__; + __bss_end__ = __rom_bss_end__; +#endif + } > RAM + + .rom_heap (.) (NOLOAD) : + { + . = ALIGN(8); + __rom_HeapBase = .; +#ifndef NOSTD + __end__ = .; + end = __end__; + . += HEAP_SECTION_SIZE; +#endif + . = ALIGN(8); + __rom_HeapLimit = .; +#ifndef NOSTD + __HeapLimit = __rom_HeapLimit; +#endif + } > RAM + + .scratch_buf (.) (NOLOAD) : + { + . = ALIGN(4); + *(.scratch_buf) + . = ALIGN(4); + } > RAM + + .rodata (.) (NOLOAD) : + { + . = ALIGN(4); + __mixprompt_property_table_start = .; + KEEP(*(.mixprompt_property_table)) + __mixprompt_property_table_end = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .rom_stack_dummy (.) (COPY) : + { + . = STACK_SECTION_SIZE; + . = ALIGN(8); + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __rom_StackTop = ORIGIN(RAM) + LENGTH(RAM); + __rom_StackLimit = __rom_StackTop - SIZEOF(.rom_stack_dummy); + PROVIDE(__rom_stack = __rom_StackTop); +#ifndef NOSTD + __StackLimit = __rom_StackLimit; + __StackTop = __rom_StackTop; + PROVIDE(__stack = __rom_StackTop); +#endif + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__rom_StackLimit >= __rom_HeapLimit, "region RAM overflowed with stack") + __free_rom_ram = __rom_StackLimit - __rom_HeapLimit; + + __rom_end = __rom_etext + SIZEOF(.rom_data); + + .rom_export_fn (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE - CRASH_DUMP_SECTION_SIZE + - CUSTOM_PARAMETER_SECTION_SIZE) : + { + __export_fn_rom = .; + KEEP(*(.export_fn)) + . = ROM_EXPORT_FN_SECTION_SIZE; + } > ROM = 0x00000000 + + .rom_build_info (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - CRASH_DUMP_SECTION_SIZE - CUSTOM_PARAMETER_SECTION_SIZE) : + { + KEEP(*(.build_info)) + . = ROM_BUILD_INFO_SECTION_SIZE; + } > ROM = 0x00000000 + .crash_dump (ORIGIN(ROM) + LENGTH(ROM) - CRASH_DUMP_SECTION_SIZE - CUSTOM_PARAMETER_SECTION_SIZE) : + { + __crash_dump_start = .; + . = CRASH_DUMP_SECTION_SIZE; + __crash_dump_end = .; + } > ROM = 0x00000000 + .custom_parameter (ORIGIN(ROM) + LENGTH(ROM) - CUSTOM_PARAMETER_SECTION_SIZE) : + { + __custom_parameter_start = .; + . = CUSTOM_PARAMETER_SECTION_SIZE; + __custom_parameter_end = .; + } > ROM = 0x00000000 + + ASSERT(ADDR(.rom_export_fn) >= __rom_end, "region ROM overflowed with .rom_export_fn") + __free_rom = ADDR(.rom_export_fn) - __rom_end; +} + diff --git a/scripts/link/best1000_intsram.lds.S b/scripts/link/best1000_intsram.lds.S new file mode 100644 index 0000000..acc04c3 --- /dev/null +++ b/scripts/link/best1000_intsram.lds.S @@ -0,0 +1,632 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#define HEAP_SECTION_SIZE 0x40 + +#define STACK_SECTION_SIZE 0xD00 + +#define OVERLAY_DATA_SECTION_SIZE 0x1000 + +#define FAST_XRAM_SECTION_SIZE 0x0010 + +#ifndef OTA_CODE_OFFSET +#define OTA_CODE_OFFSET 0 +#endif +#define FLASH_REGION_BASE (FLASH_BASE + OTA_CODE_OFFSET) +#ifndef FLASH_REGION_SIZE +#define FLASH_REGION_SIZE (FLASH_SIZE - (FLASH_REGION_BASE - FLASH_BASE)) +#endif +#define FLASH_NC_REGION_BASE FLASH_C_TO_NC(FLASH_REGION_BASE) +#define FLASHX_REGION_BASE FLASH_TO_FLASHX(FLASH_REGION_BASE) + +/* Linker script to configure memory regions. */ +/* See plat_addr_map.h and common.mk for the macro definitions */ +MEMORY +{ + ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE + FLASH (r) : ORIGIN = FLASH_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASH_NC (r) : ORIGIN = FLASH_NC_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASHX (rx) : ORIGIN = FLASHX_REGION_BASE, LENGTH = FLASH_REGION_SIZE + RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + RAMX (rx) : ORIGIN = RAMX_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + FRAMX (rwx) : ORIGIN = RAMX_BASE + RAM_SIZE - FAST_XRAM_SECTION_SIZE, LENGTH = FAST_XRAM_SECTION_SIZE +#ifdef PSRAM_BASE + PSRAM (rwx) : ORIGIN = PSRAM_BASE, LENGTH = PSRAM_SIZE + PSRAM_NC (rwx) : ORIGIN = PSRAM_NC_BASE, LENGTH = PSRAM_SIZE + PSRAMX (rx) : ORIGIN = PSRAMX_BASE, LENGTH = PSRAM_SIZE +#endif +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __export_fn_rom + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __free_ram + * __factory_start + * __factory_end + * __calib_start + * __calib_end + * __flash_start + * __flash_end + * __free_flash + * __boot_sram_start_flash__ + * __boot_sram_end_flash__ + * __boot_sram_start__ + * __boot_bss_sram_start__ + * __boot_bss_sram_end__ + * __sram_text_data_start_flash__ + * __sram_text_data_end_flash__ + * __fast_sram_text_data_start__ + * __fast_sram_text_data_end__ + * __fast_sram_text_data_start_flash__ + * __fast_sram_text_data_end_flash__ + * __sram_text_data_start__ + * __sram_bss_start__ + * __sram_bss_end__ + * __overlay_text_start__ + * __overlay_text_exec_start__ + * __overlay_data_start__ + */ +ENTRY(Boot_Loader) + +SECTIONS +{ + __export_fn_rom = (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE); + + .boot_struct (ORIGIN(FLASH)) : + { + __flash_start = .; + KEEP(*(.boot_struct)) + . = ALIGN(4); + } > FLASH + + . = FLASH_TO_FLASHX(.); + + .boot_text_flash (.) : AT (FLASHX_TO_FLASH(ADDR(.boot_text_flash))) + { + *(.boot_loader) + *(.boot_text_flash*) + *(.boot_rodata*) + . = ALIGN(4); + } > FLASHX + + . = FLASHX_TO_FLASH(.); + + .got_info (.) : + { + __got_info_start = .; + __got_start = .; + *(.got) + . = ALIGN(4); + __got_end = .; + __got_plt_start = .; + *(.got.plt) + . = ALIGN(4); + __igot_plt_start = .; + *(.igot.plt) + . = ALIGN(4); + __dynamic_start = .; + *(.dynamic) + . = ALIGN(4); + __got_info_end = .; + } > FLASH + + .vector_table (ORIGIN(RAM)) (NOLOAD) : + { + KEEP(*(.vector_table)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .reboot_param (.) (NOLOAD) : + { + KEEP(*(.reboot_param)) + . = REBOOT_PARAM_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .userdata_pool (.) (NOLOAD) : + { + *(.userdata_pool) + . = ALIGN(4); + __userdata_pool_end__ = .; + } > RAM + + __boot_sram_start_flash__ = LOADADDR(.got_info) + SIZEOF(.got_info); + __boot_sram_start__ = __userdata_pool_end__; + .boot_text_sram (RAM_TO_RAMX(__boot_sram_start__)) : AT (__boot_sram_start_flash__) + { + /* memcpy.o or libc_nano.a(lib_a-memcpy.o/lib_a-memcpy-stub.o) */ + *:memcpy.o(.text*) + *:lib_a-memcpy*.o(.text*) + *:libc_rom.o(.text*) + + /* memset.o or libc_nano.a(lib_a-memset.o) */ + *:memset.o(.text*) + *:lib_a-memset*.o(.text*) + + *:hal_norflash*.o(.text*) + *:norflash_*.o(.text*) + + *(.boot_text_sram*) + + /* All the codes that are run both in boot and non-boot */ + *:hal_*(.text*) + *:system_ARMCM.o(.text*) + *:system_utils.o(.text*) + *:cmsis_nvic.o(.text*) + /* For 64-bit div in boot, e.g., __aeabi_uldivmod */ + *libgcc.a:(.text*) + . = ALIGN(4); + } > RAMX + + .boot_data_sram (RAMX_TO_RAM(ADDR(.boot_text_sram) + SIZEOF(.boot_text_sram))) : + AT (__boot_sram_start_flash__ + SIZEOF(.boot_text_sram)) + { + *:hal_norflash*.o(.data* .rodata*) + *:norflash_*.o(.data* .rodata*) + *:hal_psram.o(.data* .rodata*) + *(.boot_data*) + /* All the data that is accessed both in boot and non-boot */ + *:hal_*(.rodata*) + *:system_ARMCM.o(.rodata*) + *:system_utils.o(.rodata*) + *:cmsis_nvic.o(.rodata*) + *libgcc.a:(.rodata*) + . = ALIGN(4); + } > RAM + + __boot_sram_end_flash__ = __boot_sram_start_flash__ + + SIZEOF(.boot_text_sram) + SIZEOF(.boot_data_sram); + + .boot_bss_sram (.) (NOLOAD) : + { + __boot_bss_sram_start__ = .; + *:hal_norflash*.o(.bss*) + *:norflash_*.o(.bss*) + *:hal_psram.o(.bss*) + *(.boot_bss*) + . = ALIGN(4); + __boot_bss_sram_end__ = .; + } > RAM + + __fast_sram_text_data_start_flash__ = __boot_sram_end_flash__; + .fast_text_sram (ORIGIN(FRAMX)) : AT (__fast_sram_text_data_start_flash__) + { + __fast_sram_text_data_start__ = .; + . = ALIGN(4); + __fast_sram_text_data_end__ = .; + } > FRAMX + __fast_sram_text_data_end_flash__ = __fast_sram_text_data_start_flash__ + SIZEOF(.fast_text_sram); + + __overlay_text_start__ = RAMX_TO_RAM(__fast_sram_text_data_end__); + __overlay_text_exec_start__ = RAM_TO_RAMX(__overlay_text_start__); + OVERLAY (__overlay_text_exec_start__) : NOCROSSREFS AT (__fast_sram_text_data_end_flash__) + { + .overlay_text0 + { + LONG(0); + *(.overlay_text0) + . = ALIGN(4); + } + .overlay_text1 + { + LONG(0); + *(.overlay_text1) + . = ALIGN(4); + } + .overlay_text2 + { + LONG(0); + *(.overlay_text2) + . = ALIGN(4); + } + .overlay_text3 + { + LONG(0); + *(.overlay_text3) + . = ALIGN(4); + } + .overlay_text4 + { + LONG(0); + *(.overlay_text4) + . = ALIGN(4); + } + .overlay_text5 + { + LONG(0); + *(.overlay_text5) + . = ALIGN(4); + } + .overlay_text6 + { + LONG(0); + *(.overlay_text6) + . = ALIGN(4); + } + .overlay_text7 + { + LONG(0); + *(.overlay_text7) + . = ALIGN(4); + } + .overlay_text_end + { + LONG(0); + . = ALIGN(4); + } + } > FRAMX + + .dummy_overlay_text (.) (NOLOAD) : + { + __dummy_overlay_text_end__ = .; + } > FRAMX + + ASSERT(__dummy_overlay_text_end__ - __fast_sram_text_data_start__ <= FAST_XRAM_SECTION_SIZE, "fast xram sections too large") + __overlay_data_start__ = __boot_bss_sram_end__; + OVERLAY (__overlay_data_start__) : NOCROSSREFS AT (__load_stop_overlay_text_end) + { + .overlay_data0 + { + /* Explicitly place 4 bytes at section start to avoid "section type changed to PROGBITS" warnings */ + LONG(0); + *(.overlay_data0 .overlay_rodata0) + . = ALIGN(4); + } + .overlay_data1 + { + LONG(0); + *(.overlay_data1 .overlay_rodata1) + . = ALIGN(4); + } + .overlay_data2 + { + LONG(0); + *(.overlay_data2 .overlay_rodata2) + . = ALIGN(4); + } + .overlay_data3 + { + LONG(0); + *(.overlay_data3 .overlay_rodata3) + . = ALIGN(4); + } + .overlay_data4 + { + LONG(0); + *(.overlay_data4 .overlay_rodata4) + . = ALIGN(4); + } + .overlay_data5 + { + LONG(0); + *(.overlay_data5 .overlay_rodata5) + . = ALIGN(4); + } + .overlay_data6 + { + LONG(0); + *(.overlay_data6 .overlay_rodata6) + . = ALIGN(4); + } + .overlay_data7 + { + LONG(0); + *(.overlay_data7 .overlay_rodata7) + . = ALIGN(4); + } + .overlay_data_end + { + LONG(0); + . = ALIGN(4); + } + } > RAM + + .dummy_overlay_data (.) (NOLOAD) : + { + __dummy_overlay_data_end__ = .; + } > RAM + + ASSERT(__dummy_overlay_data_end__ - __overlay_data_start__ <= OVERLAY_DATA_SECTION_SIZE, "overlay sections too large") + + __sram_text_data_start_flash__ = __load_stop_overlay_data_end; + __sram_text_data_start__ = __dummy_overlay_data_end__; + .sram_text (RAM_TO_RAMX(__sram_text_data_start__)) : + AT (__sram_text_data_start_flash__) + { + *(.sram_text*) + *:filter_process.o(.text*) + + *(.fast_text_sram*) + + *(.text*) + *(.flash_text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + . = ALIGN(4); + } > RAMX + + .sram_data (RAMX_TO_RAM(ADDR(.sram_text) + SIZEOF(.sram_text))) : + AT (__sram_text_data_start_flash__ + SIZEOF(.sram_text)) + { + *(.rodata*) + *(.sram_data*) + . = ALIGN(4); + } > RAM + + __sram_text_data_end_flash__ = __sram_text_data_start_flash__ + + SIZEOF(.sram_text) + SIZEOF(.sram_data); + + .sram_bss (.) (NOLOAD) : + { + __sram_bss_start__ = .; + *(.sram_bss*) + . = ALIGN(4); + __sram_bss_end__ = .; + } > RAM + + .text (FLASH_TO_FLASHX(__sram_text_data_end_flash__)) : AT (FLASHX_TO_FLASH(ADDR(.text))) + { + __dummy_text = .; + } > FLASHX + + .ARM.extab (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.extab))) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASHX + + __exidx_start = .; + /* .ARM.exidx contains R_ARM_PREL31 (+-0x40000000) offset to functions, which means + * the session location cannot be too far away from the function addresses */ + .ARM.exidx (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.exidx))) + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASHX + __exidx_end = .; + + . = FLASHX_TO_FLASH(.); + + .rodata (.) : + { + __dummy_rodata = .; + *(.flash_rodata*) + KEEP(*(.eh_frame*)) + *(.note.gnu.build-id) + } > FLASH + + /* To copy multiple FLASH to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table (.) : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table (.) : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + +#ifdef DATA_BUF_START + .data_dummy (NOLOAD) : + { + __data_dummy_start = ABSOLUTE(.); + . = DATA_BUF_START - __data_dummy_start; + } > RAM +#endif + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss (.) (NOLOAD) : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (.) (NOLOAD) : + { + . = ALIGN(8); + __HeapBase = .; + __end__ = .; + end = __end__; + . += HEAP_SECTION_SIZE; + . = ALIGN(8); + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (.) (COPY) : + { + . = STACK_SECTION_SIZE; + . = ALIGN(8); + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + __free_ram = __StackLimit - __HeapLimit; + + . = __etext + SIZEOF(.data); + .build_info (.) : + { + KEEP(*(.build_info)) + . = ALIGN(4); + } > FLASH = 0x00000000 + + /* The following section be the last loaded section */ + .code_start_addr (.) : + { + LONG(BUILD_INFO_MAGIC); + LONG(ABSOLUTE(__flash_start)); + } > FLASH + + __flash_end = .; + + .custom_parameter (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE) (NOLOAD) : + { + __custom_parameter_start = .; + . = CUSTOM_PARAMETER_SECTION_SIZE; + __custom_parameter_end = .; + } > FLASH_NC + + .userdata (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2) (NOLOAD) : + { + __userdata_start = .; + . = USERDATA_SECTION_SIZE*2; + __userdata_end = .; + } > FLASH_NC + + .audio (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE) (NOLOAD) : + { + __aud_start = .; + . = AUD_SECTION_SIZE; + __aud_end = .; + } > FLASH_NC + + .reserved (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE) (NOLOAD) : + { + __reserved_start = .; + . = RESERVED_SECTION_SIZE; + __reserved_end = .; + } > FLASH_NC + + .factory (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE) (NOLOAD) : + { + __factory_start = .; + . = FACTORY_SECTION_SIZE; + __factory_end = .; + } > FLASH_NC + + ASSERT(FLASH_NC_TO_C(__custom_parameter_start) >= __flash_end, "region FLASH overflowed") + __free_flash = FLASH_NC_TO_C(__custom_parameter_start) - __flash_end; +} + diff --git a/scripts/link/best1000_intsram.lds_scat.S b/scripts/link/best1000_intsram.lds_scat.S new file mode 100644 index 0000000..dea109b --- /dev/null +++ b/scripts/link/best1000_intsram.lds_scat.S @@ -0,0 +1,409 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#define HEAP_SECTION_SIZE 0x40 + +#define STACK_SECTION_SIZE 0xD00 +#define CP_STACK_SECTION_SIZE 0x1000 + +#define OVERLAY_DATA_SECTION_SIZE 0x1000 + +#define FAST_XRAM_SECTION_SIZE 0x0010 + +#ifndef OTA_CODE_OFFSET +#define OTA_CODE_OFFSET 0 +#endif +#define FLASH_REGION_BASE (FLASH_BASE + OTA_CODE_OFFSET) +#ifndef FLASH_REGION_SIZE +#define FLASH_REGION_SIZE (FLASH_SIZE - (FLASH_REGION_BASE - FLASH_BASE)) +#endif +#define FLASH_NC_REGION_BASE FLASH_C_TO_NC(FLASH_REGION_BASE) +#define FLASHX_REGION_BASE FLASH_TO_FLASHX(FLASH_REGION_BASE) + +#define RESERVED_SECTION_SIZE 0x1000 + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +LR_boot_struct FLASHX_REGION_BASE NOCOMPRESS +{ + boot_struct FLASH_REGION_BASE + { + *(.boot_struct, +FIRST) + } +} + +LR_boot_flash +0 +{ + boot_text_flash +0 FIXED + { + *(.boot_loader, +FIRST) + *(.boot_text_flash*) + *(.boot_rodata*) + } + + vector_table RAM_BASE UNINIT VECTOR_SECTION_SIZE + { + *(.bss.vector_table, +FIRST) + } + + reboot_param (ImageBase(vector_table) + VECTOR_SECTION_SIZE) UNINIT REBOOT_PARAM_SECTION_SIZE + { + *(.bss.reboot_param, +FIRST) + } + + userdata_pool (ImageBase(reboot_param) + REBOOT_PARAM_SECTION_SIZE) UNINIT + { + *(.bss.userdata_pool) + } +} + +LR_boot_sram +0 +{ + boot_text_sram RAM_TO_RAMX(ImageLimit(userdata_pool)) + { + *armlib/c_*(:gdef:*memcpy*) + *armlib/c_*(:gdef:*memset*) + memcpy.o(.text*) + memset.o(.text*) + libc_rom.o(.text*) + + hal_norflash*.o(.text*) + norflash_*.o(.text*) + + *(.boot_text_sram*) + + /* All the codes that are run both in boot and non-boot */ + hal_*(.text*) + system_ARMCM.o(.text*) + system_utils.o(.text*) + cmsis_nvic.o(.text*) + /* For 64-bit div in boot, e.g., __aeabi_uldivmod */ + /* *libgcc.a:((.text*)) */ + } + + boot_data_sram RAMX_TO_RAM(+0) + { + hal_norflash*.o(.data*, .rodata*) + norflash_*.o(.data*, .rodata*) + hal_psram.o(.data*, .rodata*) + *(.boot_data*) + /* All the data that is accessed both in boot and non-boot */ + hal_*(.rodata*) + system_ARMCM.o(.rodata*) + system_utils.o(.rodata*) + cmsis_nvic.o(.rodata*) + /* *libgcc.a:(.rodata*) */ + } + + boot_bss_sram +0 UNINIT + { + hal_norflash*.o(+BSS) + norflash_*.o(+BSS) + hal_psram.o(+BSS) + *(.bss.boot_bss*) + } +} + +LR_fast_sram +0 +{ + fast_text_sram (RAMX_BASE + RAM_SIZE - FAST_XRAM_SECTION_SIZE) + { + *(.fast_text_sram) + } + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + cp_text_sram RAMCPX_BASE + { + *(.cp_text_sram*) + } + + cp_text_sram_start RAMX_TO_RAM(ImageBase(cp_text_sram)) EMPTY ImageLength(cp_text_sram) + { + } + + vector_table_cp RAMCP_BASE UNINIT VECTOR_SECTION_SIZE + { + *(.vector_table_cp, +FIRST) + } + + cp_data_sram (ImageBase(vector_table_cp) + VECTOR_SECTION_SIZE) + { + *(.cp_data*) + } + + cp_bss_sram +0 UNINIT + { + *(.bss.cp_bss*) + } + + cp_stack (RAMCP_BASE + RAMCP_SIZE - CP_STACK_SECTION_SIZE) EMPTY CP_STACK_SECTION_SIZE + { + } + + ScatterAssert(ImageLimit(cp_stack) <= RAMCP_BASE + RAMCP_SIZE) + +#define OVERLAY_TEXT_EXEC_START ImageLimit(cp_text_sram) +#define OVERLAY_DATA_START ImageLimit(cp_bss_sram) +#define SRAM_TEXT_START RAM_TO_RAMX(ImageLimit(boot_bss_sram)) +#else +#define OVERLAY_TEXT_EXEC_START ImageLimit(fast_text_sram) +#define OVERLAY_DATA_START ImageLimit(boot_bss_sram) +#define SRAM_TEXT_START RAM_TO_RAMX(ImageLimit(overlay_data_end)) +#endif +#define OVERLAY_TEXT_START RAMX_TO_RAM(OVERLAY_TEXT_EXEC_START) +} + +LR_overlay +0 +{ + overlay_start OVERLAY_TEXT_START EMPTY 0 + { + } + + overlay_text0 OVERLAY_TEXT_EXEC_START OVERLAY + { + *(.overlay_text0) + } + overlay_text1 OVERLAY_TEXT_EXEC_START OVERLAY + { + *(.overlay_text1) + } + overlay_text2 OVERLAY_TEXT_EXEC_START OVERLAY + { + *(.overlay_text2) + } + overlay_text3 OVERLAY_TEXT_EXEC_START OVERLAY + { + *(.overlay_text3) + } + overlay_text4 OVERLAY_TEXT_EXEC_START OVERLAY + { + *(.overlay_text4) + } + overlay_text5 OVERLAY_TEXT_EXEC_START OVERLAY + { + *(.overlay_text5) + } + overlay_text6 OVERLAY_TEXT_EXEC_START OVERLAY + { + *(.overlay_text6) + } + overlay_text7 OVERLAY_TEXT_EXEC_START OVERLAY + { + *(.overlay_text7) + } + + overlay_text_end (MAX(ImageLimit(overlay_text0), \ + MAX(ImageLimit(overlay_text1), \ + MAX(ImageLimit(overlay_text2), \ + MAX(ImageLimit(overlay_text3), \ + MAX(ImageLimit(overlay_text4), \ + MAX(ImageLimit(overlay_text5), \ + MAX(ImageLimit(overlay_text6), \ + ImageLimit(overlay_text7))))))))) EMPTY 0 + { + } +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + ScatterAssert(ImageLimit(overlay_text_end) <= RAMCPX_BASE + RAMCPX_SIZE) +#else + ScatterAssert(ImageLimit(overlay_text_end) <= ImageBase(fast_text_sram) + FAST_XRAM_SECTION_SIZE) +#endif + + overlay_data0 OVERLAY_DATA_START OVERLAY + { + *(.overlay_data0, .overlay_rodata0) + } + overlay_data1 OVERLAY_DATA_START OVERLAY + { + *(.overlay_data1, .overlay_rodata1) + } + overlay_data2 OVERLAY_DATA_START OVERLAY + { + *(.overlay_data2, .overlay_rodata2) + } + overlay_data3 OVERLAY_DATA_START OVERLAY + { + *(.overlay_data3, .overlay_rodata3) + } + overlay_data4 OVERLAY_DATA_START OVERLAY + { + *(.overlay_data4, .overlay_rodata4) + } + overlay_data5 OVERLAY_DATA_START OVERLAY + { + *(.overlay_data5, .overlay_rodata5) + } + overlay_data6 OVERLAY_DATA_START OVERLAY + { + *(.overlay_data6, .overlay_rodata6) + } + overlay_data7 OVERLAY_DATA_START OVERLAY + { + *(.overlay_data7, .overlay_rodata7) + } + + overlay_data_end (MAX(ImageLimit(overlay_data0), \ + MAX(ImageLimit(overlay_data1), \ + MAX(ImageLimit(overlay_data2), \ + MAX(ImageLimit(overlay_data3), \ + MAX(ImageLimit(overlay_data4), \ + MAX(ImageLimit(overlay_data5), \ + MAX(ImageLimit(overlay_data6), \ + ImageLimit(overlay_data7))))))))) EMPTY 0 + { + } + ScatterAssert(ImageLimit(overlay_data_end) <= ImageBase(overlay_data0) + OVERLAY_DATA_SECTION_SIZE) +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + ScatterAssert(ImageLimit(overlay_data_end) <= ImageBase(cp_stack)) +#endif +} + +LR_sram +0 +{ + sram_text AlignExpr(SRAM_TEXT_START, 8) + { + *(InRoot$$Sections) + *armlib*(+TEXT) + + *(.sram_text*) + filter_process.o(.text*) + + *(.fast_text_sram*) + + *(.text*) + *(.flash_text*) + + } + + sram_data RAMX_TO_RAM(+0) + { + *armlib*(+DATA +CONST) + + *(.rodata*) + *(.sram_data*) + } + + sram_bss +0 UNINIT + { + *armlib*(+BSS) + + *(.bss.sram_bss*) + } +} + +LR_text +0 +{ + text +0 EMPTY 0 + { + } + + .ARM.extab +0 + { + *(.ARM.extab*, .gnu.linkonce.armextab.*) + } + + /* .ARM.exidx contains R_ARM_PREL31 (+-0x40000000) offset to functions, which means + * the session location cannot be too far away from the function addresses */ + .ARM.exidx +0 + { + *(.ARM.exidx*, .gnu.linkonce.armexidx.*) + } + + rodata FLASHX_TO_FLASH(+0) : + { + *(.flash_rodata*) + *(.eh_frame*) + *(.note.gnu.build-id) + } +} + +LR_data +0 +{ +#ifdef DATA_BUF_START +#define DATA_SEC_START DATA_BUF_START +#else +#define DATA_SEC_START ImageLimit(sram_bss) +#endif + + data DATA_SEC_START + { + *(vtable) + *(.data*) + } + + bss +0 UNINIT + { + *(.bss*) + *(COMMON) + } + + ARM_LIB_HEAP +0 ALIGN 8 EMPTY HEAP_SECTION_SIZE + { + } + + ARM_LIB_STACK (RAM_BASE + RAM_SIZE - FAST_XRAM_SECTION_SIZE - STACK_SECTION_SIZE) ALIGN 8 EMPTY STACK_SECTION_SIZE + { + } + + /* Check if data + heap + stack exceeds RAM limit */ + ScatterAssert(ImageBase(ARM_LIB_STACK) >= ImageLimit(ARM_LIB_HEAP)) + ScatterAssert(ImageLimit(ARM_LIB_STACK) <= (RAM_BASE + RAM_SIZE - FAST_XRAM_SECTION_SIZE)) + + free_ram ImageLimit(ARM_LIB_HEAP) EMPTY (ImageBase(ARM_LIB_STACK) - ImageLimit(ARM_LIB_HEAP)) + { + } +} + +LR_tail +0 +{ + build_info FLASHX_TO_FLASH(+0) + { + *(.build_info, +FIRST) + } + + /* The following section be the last loaded section */ + code_start_addr +0 + { + *(.code_start_addr, +LAST) + } + + custom_parameter (FLASH_NC_REGION_BASE + FLASH_REGION_SIZE - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE) EMPTY CUSTOM_PARAMETER_SECTION_SIZE + { + } + + userdata (FLASH_NC_REGION_BASE + FLASH_REGION_SIZE - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2) EMPTY (USERDATA_SECTION_SIZE*2) + { + } + + audio (FLASH_NC_REGION_BASE + FLASH_REGION_SIZE - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE) EMPTY AUD_SECTION_SIZE + { + } + + reserved (FLASH_NC_REGION_BASE + FLASH_REGION_SIZE - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE) EMPTY RESERVED_SECTION_SIZE + { + } + + factory (FLASH_NC_REGION_BASE + FLASH_REGION_SIZE - FACTORY_SECTION_SIZE) EMPTY FACTORY_SECTION_SIZE + { + } + + ScatterAssert(FLASH_C_TO_NC(ImageLimit(code_start_addr)) <= ImageBase(custom_parameter)) +} + diff --git a/scripts/link/best1000_msbc_aac.lds.S b/scripts/link/best1000_msbc_aac.lds.S new file mode 100644 index 0000000..929b1cc --- /dev/null +++ b/scripts/link/best1000_msbc_aac.lds.S @@ -0,0 +1,921 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#define HEAP_SECTION_SIZE 0x40 +#define STACK_SECTION_SIZE 0xD00 + +#define OVERLAY_DATA_SECTION_SIZE 0x8000 +#define FAST_XRAM_SECTION_SIZE 0xa000 + +#ifndef OTA_CODE_OFFSET +#define OTA_CODE_OFFSET 0 +#endif +#define FLASH_REGION_BASE (FLASH_BASE + OTA_CODE_OFFSET) +#ifndef FLASH_REGION_SIZE +#define FLASH_REGION_SIZE (FLASH_SIZE - (FLASH_REGION_BASE - FLASH_BASE)) +#endif +#define FLASH_NC_REGION_BASE FLASH_C_TO_NC(FLASH_REGION_BASE) +#define FLASHX_REGION_BASE FLASH_TO_FLASHX(FLASH_REGION_BASE) + +/* Linker script to configure memory regions. */ +/* See plat_addr_map.h and common.mk for the macro definitions */ +MEMORY +{ + ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE + FLASH (r) : ORIGIN = FLASH_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASH_NC (r) : ORIGIN = FLASH_NC_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASHX (rx) : ORIGIN = FLASHX_REGION_BASE, LENGTH = FLASH_REGION_SIZE + RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + RAMX (rx) : ORIGIN = RAMX_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + FRAMX (rwx) : ORIGIN = RAMX_BASE + RAM_SIZE - FAST_XRAM_SECTION_SIZE, LENGTH = FAST_XRAM_SECTION_SIZE +#ifdef PSRAM_BASE + PSRAM (rwx) : ORIGIN = PSRAM_BASE, LENGTH = PSRAM_SIZE + PSRAM_NC (rwx) : ORIGIN = PSRAM_NC_BASE, LENGTH = PSRAM_SIZE + PSRAMX (rx) : ORIGIN = PSRAMX_BASE, LENGTH = PSRAM_SIZE +#endif +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __export_fn_rom + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __free_ram + * __factory_start + * __factory_end + * __calib_start + * __calib_end + * __flash_start + * __flash_end + * __free_flash + * __boot_sram_start_flash__ + * __boot_sram_end_flash__ + * __boot_sram_start__ + * __boot_bss_sram_start__ + * __boot_bss_sram_end__ + * __sram_text_data_start_flash__ + * __sram_text_data_end_flash__ + * __fast_sram_text_data_start__ + * __fast_sram_text_data_end__ + * __fast_sram_text_data_start_flash__ + * __fast_sram_text_data_end_flash__ + * __sram_text_data_start__ + * __sram_bss_start__ + * __sram_bss_end__ + * __sram_userdata_pool_start__ + * __overlay_text_start__ + * __overlay_text_exec_start__ + * __overlay_data_start__ + * __overlay_bss_start__ + */ +ENTRY(Boot_Loader) + +SECTIONS +{ + __export_fn_rom = (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE); + + .boot_struct (ORIGIN(FLASH)) : + { + __flash_start = .; + KEEP(*(.boot_struct)) + . = ALIGN(4); + } > FLASH + + . = FLASH_TO_FLASHX(.); + + .boot_text_flash (.) : AT (FLASHX_TO_FLASH(ADDR(.boot_text_flash))) + { + *(.boot_loader) + *(.boot_text_flash*) + *(.boot_rodata*) + . = ALIGN(4); + } > FLASHX + + . = FLASHX_TO_FLASH(.); + + .got_info (.) : + { + __got_info_start = .; + __got_start = .; + *(.got) + . = ALIGN(4); + __got_end = .; + __got_plt_start = .; + *(.got.plt) + . = ALIGN(4); + __igot_plt_start = .; + *(.igot.plt) + . = ALIGN(4); + __dynamic_start = .; + *(.dynamic) + . = ALIGN(4); + __got_info_end = .; + } > FLASH + + .vector_table (ORIGIN(RAM)) (NOLOAD) : + { + KEEP(*(.vector_table)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .reboot_param (.) (NOLOAD) : + { + KEEP(*(.reboot_param)) + . = REBOOT_PARAM_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .userdata_pool (.) (NOLOAD) : + { + *(.userdata_pool) + . = ALIGN(4); + __userdata_pool_end__ = .; + } > RAM + + __boot_sram_start_flash__ = LOADADDR(.got_info) + SIZEOF(.got_info); + __boot_sram_start__ = __userdata_pool_end__; + .boot_text_sram (RAM_TO_RAMX(__boot_sram_start__)) : AT (__boot_sram_start_flash__) + { + /* memcpy.o or libc_nano.a(lib_a-memcpy.o/lib_a-memcpy-stub.o) */ + *:memcpy.o(.text*) + *:lib_a-memcpy*.o(.text*) + *:libc_rom.o(.text*) + + /* memset.o or libc_nano.a(lib_a-memset.o) */ + *:memset.o(.text*) + *:lib_a-memset*.o(.text*) + + *:hal_norflash*.o(.text*) + *:norflash_*.o(.text*) + + *(.boot_text_sram*) + . = ALIGN(4); + __boot_text_sram_end = .; + } > RAMX + + .boot_data_sram (RAMX_TO_RAM(ADDR(.boot_text_sram) + SIZEOF(.boot_text_sram))) : + AT (__boot_sram_start_flash__ + SIZEOF(.boot_text_sram)) + { + *:hal_norflash*.o(.data* .rodata*) + *:norflash_*.o(.data* .rodata*) + *:hal_psram.o(.data* .rodata*) + *(.boot_data*) + . = ALIGN(4); + __boot_data_sram_end = .; + } > RAM + + __boot_sram_end_flash__ = __boot_sram_start_flash__ + + SIZEOF(.boot_text_sram) + SIZEOF(.boot_data_sram); + + .boot_bss_sram (.) (NOLOAD) : + { + __boot_bss_sram_start__ = .; + *:hal_norflash*.o(.bss*) + *:norflash_*.o(.bss*) + *:hal_psram.o(.bss*) + *(.boot_bss*) + . = ALIGN(4); + __boot_bss_sram_end__ = .; + } > RAM + + __sram_text_data_start_flash__ = __boot_sram_end_flash__; + __sram_text_data_start__ = __boot_bss_sram_end__; + .sram_text (RAM_TO_RAMX(__sram_text_data_start__)) : + AT (__sram_text_data_start_flash__) + { + *(.sram_text*) +#if defined(A2DP_AAC_ON) + *:utils.o(.text*) + *:cqueue.o(.text*) +#endif + . = ALIGN(4); + } > RAMX + + .sram_data (RAMX_TO_RAM(ADDR(.sram_text) + SIZEOF(.sram_text))) : + AT (__sram_text_data_start_flash__ + SIZEOF(.sram_text)) + { + *:utils.o(.data* .rodata*) + *:cqueue.o(.data* .rodata*) + *:iir_process.o(.data* .rodata*) + *(.sram_data*) + . = ALIGN(4); + } > RAM + + __sram_text_data_end_flash__ = __sram_text_data_start_flash__ + + SIZEOF(.sram_text) + SIZEOF(.sram_data); + + .sram_bss (.) (NOLOAD) : + { + __sram_bss_start__ = .; + *:utils.o(.bss*) + *(.sram_bss*) + . = ALIGN(4); + __sram_bss_end__ = .; + } > RAM + + __fast_sram_text_data_start_flash__ = __sram_text_data_end_flash__; + .fast_text_sram (ORIGIN(FRAMX)) : AT (__fast_sram_text_data_start_flash__) + { + __fast_sram_text_data_start__ = .; + *:audio_resample_ex.o(.text*) +#if defined(HFP_1_6_ENABLE) +#if !defined(__SBC_FUNC_IN_ROM__) + *:sbc.o(.text.sbc_is_stream_info_valid) + *:sbc.o(.text.sbc_frame_length_get) + *:sbc.o(.text.sbc_4bit_crc_calc) + *:sbc.o(.text.sbc_bits_for_mono_alloc) + *:sbc.o(.text.sbc_bits_for_stereo_alloc) + *:sbc.o(.text.sbc_header_process) + *:sbc.o(.text.sbc_factors_process) + *:sbc.o(.text.sbc_sample_extract) + *:sbc.o(.text.sbc_sbsamples_make) + *:sbc.o(.text.sbc_joint_process) + *:sbc.o(.text.sbc_4band_synth_filter) + *:sbc.o(.text.sbc_8band_synth_filter) + *:sbc.o(.text.sbc_decoder_state_reset) + *:sbc.o(.text.sbc_frame_mute) + *:sbc.o(.text.sbc_frames_decode) +#endif + *:sbc_math.o(.text*) +#endif +#if !defined(A2DP_AAC_ON) && !defined(A2DP_LHDC_ON) + *:fir_process.o(.text*) + *:iir_process.o(.text.iir_run .text.*iir_run_per_*) +#else + /* libc_nano.a(lib_a-memmove.o) or memmove.o */ + *memmove.o(.text*) + *:utils.o(.text*) + *:cqueue.o(.text*) +#endif + *(.fast_text_sram*) + . = ALIGN(4); + __fast_sram_text_data_end__ = .; + } > FRAMX + __fast_sram_text_data_end_flash__ = __fast_sram_text_data_start_flash__ + SIZEOF(.fast_text_sram); + + __overlay_text_start__ = RAMX_TO_RAM(__fast_sram_text_data_end__); + __overlay_text_exec_start__ = RAM_TO_RAMX(__overlay_text_start__); + OVERLAY (__overlay_text_exec_start__) : NOCROSSREFS AT (__fast_sram_text_data_end_flash__) + { + .overlay_text0 + { + LONG(0); + *:preprocess.o(.text.speex_preprocess_run) + *:fftwrap.o(.text*) + *:mdf.o(.text.speex_echo_cancellation) + *:plc.o(.text*) +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.text*) +#endif +#if defined(HFP_1_6_ENABLE) && defined(__SBC_FUNC_IN_ROM__) + *:sbc.o(.text.sbc_encoder_init) + *:sbc.o(.text.sbc_filter_4band_analysis) + *:sbc.o(.text.sbc_filter_8band_analysis) + *:sbc.o(.text.sbc_factors_calc) + *:sbc.o(.text.sbc_header_make) + *:sbc.o(.text.sbc_sample_pack) + *:sbc.o(.text.sbc_samples_quant) + *:sbc.o(.text.sbc_frames_encode) +#endif + *(.overlay_text0) + . = ALIGN(4); + } + .overlay_text1 + { + LONG(0); +#if !defined(RB_CODEC) +#if !defined(HFP_1_6_ENABLE) + *:sbc.o(.text.sbc_is_stream_info_valid) + *:sbc.o(.text.sbc_frame_length_get) + *:sbc.o(.text.sbc_4bit_crc_calc) + *:sbc.o(.text.sbc_bits_for_mono_alloc) + *:sbc.o(.text.sbc_bits_for_stereo_alloc) + *:sbc.o(.text.sbc_header_process) + *:sbc.o(.text.sbc_factors_process) + *:sbc.o(.text.sbc_sample_extract) + *:sbc.o(.text.sbc_sbsamples_make) + *:sbc.o(.text.sbc_joint_process) + *:sbc.o(.text.sbc_4band_synth_filter) + *:sbc.o(.text.sbc_8band_synth_filter) + *:sbc.o(.text.sbc_decoder_state_reset) + *:sbc.o(.text.sbc_frame_mute) + *:sbc.o(.text.sbc_frames_decode) + *:sbc_math.o(.text*) +#endif + *:fixedpoint.o(.text*) + *:replaygain.o(.text*) + *:dsp_core.o(.text*) + *:dsp_misc.o(.text*) + *:dsp_filter.o(.text*) + *:dsp_sample_input.o(.text*) + *:dsp_sample_output.o(.text*) + *:eq.o(.text*) + *:pga.o(.text*) +#if !defined(A2DP_AAC_ON) && !defined(A2DP_LHDC_ON) + *:fir_process.o(.text*) + *:iir_process.o(.text.iir_run .text.*iir_run_per_*) +#endif +#endif + *(.overlay_a2dp_sbc*) + *(.overlay_text1) + . = ALIGN(4); + } + .overlay_text2 + { + LONG(0); + *:fmdec.o(.text* .data* .rodata* .bss*) + *(.overlay_text2) + . = ALIGN(4); + } + .overlay_text3 + { + LONG(0); + *:fft128dot.o(.text*) + *(.overlay_text3) + . = ALIGN(4); + } + .overlay_text4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:aacdec.o(.text*) + *:aactabs.o(.text*) + *:bitstream.o(.text*) + *:buffers.o(.text*) + *:dct4.o(.text*) + *:decelmnt.o(.text*) + *:dequant.o(.text*) + *:fft.o(.text*) + *:filefmt.o(.text*) + *:huffman.o(.text*) + *:hufftabs.o(.text*) + *:imdct.o(.text*) + *:noiseless.o(.text*) + *:pns.o(.text*) + *:stproc.o(.text*) + *:tns.o(.text*) + *:trigtabs.o(.text*) + *:trigtabs_fltgen.o(.text*) +#endif + *(.overlay_a2dp_aac*) + *(.overlay_text4) + . = ALIGN(4); + } + .overlay_text5 + { + LONG(0); + *(.overlay_text5) + . = ALIGN(4); + } + .overlay_text6 + { + LONG(0); + *(.overlay_text6) + . = ALIGN(4); + } + .overlay_text7 + { + LONG(0); + *(.overlay_text7) + . = ALIGN(4); + } + .overlay_text_end + { + LONG(0); + . = ALIGN(4); + } + } > FRAMX + + .dummy_overlay_text (.) (NOLOAD) : + { + __dummy_overlay_text_end__ = .; + } > FRAMX + + ASSERT(__dummy_overlay_text_end__ - __fast_sram_text_data_start__ <= FAST_XRAM_SECTION_SIZE, "fast xram sections too large") + __free_fram = FAST_XRAM_SECTION_SIZE - (__dummy_overlay_text_end__ - __fast_sram_text_data_start__); + + __overlay_data_start__ = __sram_bss_end__; + OVERLAY (__overlay_data_start__) : NOCROSSREFS AT (__load_stop_overlay_text_end) + { + .overlay_data0 + { + /* Explicitly place 4 bytes at section start to avoid "section type changed to PROGBITS" warnings */ + LONG(0); + *:preprocess.o(.data* .rodata*) + *:filterbank.o(.data* .rodata*) + *:kiss_fft.o(.data* .rodata*) + *:kiss_fftr.o(.data* .rodata*) + *:fftwrap.o(.data* .rodata*) + *:mdf.o(.data* .rodata*) + *:plc.o(.data* .rodata*) +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.data* .rodata* .bss*) +#endif + *(.overlay_data0 .overlay_rodata0) + . = ALIGN(4); + } + + .overlay_data1 + { + LONG(0); +#if !defined(RB_CODEC) +#if !defined(HFP_1_6_ENABLE) + *:sbc.o(.data* .rodata*) + *:sbc_math.o(.data* .rodata*) +#endif + *:fixedpoint.o(.data* .rodata*) + *:replaygain.o(.data* .rodata*) + *:dsp_core.o(.data* .rodata*) + *:dsp_misc.o(.data* .rodata*) + *:dsp_filter.o(.data* .rodata*) + *:dsp_sample_input.o(.data* .rodata*) + *:dsp_sample_output.o(.data* .rodata*) + *:eq.o(.data* .rodata*) + *:pga.o(.data* .rodata*) +#if !defined(A2DP_AAC_ON) + *:fir_process.o(.data* .rodata*) +#endif +#endif + *(.overlay_data1 .overlay_rodata1) + . = ALIGN(4); + } + .overlay_data2 + { + LONG(0); + *(.overlay_data2 .overlay_rodata2) + . = ALIGN(4); + } + .overlay_data3 + { + LONG(0); + *:fft128dot.o(.data* .rodata*) + *(.overlay_data3 .overlay_rodata3) + . = ALIGN(4); + } + .overlay_data4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:aacdec.o(.data*) + *:aactabs.o(.data*) + *:bitstream.o(.data*) + *:dct4.o(.data*) + *:decelmnt.o(.data*) + *:dequant.o(.data*) + *:fft.o(.data*) + *:filefmt.o(.data*) + *:huffman.o(.data*) + *:hufftabs.o(.data*) + *:imdct.o(.data*) + *:noiseless.o(.data*) + *:pns.o(.data*) + *:stproc.o(.data*) + *:tns.o(.data*) + *:trigtabs.o(.data*) + *:trigtabs_fltgen.o(.data*) + *:buffers.o(.data* . .rodata*) +#endif + *(.overlay_data4 .overlay_rodata4) + . = ALIGN(4); + } + .overlay_data5 + { + LONG(0); + *(.overlay_data5 .overlay_rodata5) + . = ALIGN(4); + } + .overlay_data6 + { + LONG(0); + *(.overlay_data6 .overlay_rodata6) + . = ALIGN(4); + } + .overlay_data7 + { + LONG(0); + *(.overlay_data7 .overlay_rodata7) + . = ALIGN(4); + } + .overlay_data_end + { + LONG(0); + . = ALIGN(4); + } + } > RAM + + .dummy_overlay_data (.) (NOLOAD) : + { + __dummy_overlay_data_end__ = .; + } > RAM + + __overlay_bss_start__ = __dummy_overlay_data_end__; + OVERLAY (__overlay_bss_start__) :NOCROSSREFS AT (__load_stop_overlay_data_end) + { + .overlay_bss0 + { + LONG(0); + *:voicebtpcmplay.o(.bss*) + *:preprocess.o(.bss*) + *:filterbank.o(.bss*) + *:kiss_fft.o(.bss*) + *:kiss_fftr.o(.bss*) + *:fftwrap.o(.bss*) + *:mdf.o(.bss*) + *:plc.o(.bss*) +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.bss*) +#endif + *(.overlay_bss0 .overlay_rwbss0) + . = ALIGN(4); + } + + .overlay_bss1 + { + LONG(0); + *(.overlay_bss1 .overlay_rwbss1) + . = ALIGN(4); + } + .overlay_bss2 + { + LONG(0); + *(.overlay_bss2 .overlay_rwbss2) + . = ALIGN(4); + } + .overlay_bss3 + { + LONG(0); + *:fft128dot.o(.data* .rodata*) + *(.overlay_bss3 .overlay_rwbss3) + . = ALIGN(4); + } + .overlay_bss4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:aacdec.o(.bss*) + *:aactabs.o(.bss*) + *:bitstream.o( .bss*) + *:dct4.o( .bss*) + *:decelmnt.o( .bss*) + *:dequant.o( .bss*) + *:fft.o(.bss*) + *:filefmt.o(.bss*) + *:huffman.o(.bss*) + *:hufftabs.o(.bss*) + *:imdct.o(.bss*) + *:noiseless.o(.bss*) + *:pns.o(.bss*) + *:stproc.o(.bss*) + *:tns.o(.bss*) + *:trigtabs.o(.bss*) + *:trigtabs_fltgen.o(.bss*) + *:buffers.o(.bss*) + *:a2dpplay.o(.bss.*raw_aac_pcm_data) +#endif + *(.overlay_bss4 .overlay_rwbss4) + . = ALIGN(4); + } + .overlay_bss5 + { + LONG(0); + *(.overlay_bss5 .overlay_rwbss5) + . = ALIGN(4); + } + .overlay_bss6 + { + LONG(0); + *(.overlay_bss6 .overlay_rwbss6) + . = ALIGN(4); + } + .overlay_bss7 + { + LONG(0); + *(.overlay_bss7 .overlay_rwbss7) + . = ALIGN(4); + } + .overlay_bss_end + { + LONG(0); + . = ALIGN(4); + } + } > RAM + + .dummy_overlay_bss (.) (NOLOAD) : + { + __dummy_overlay_bss_end__ = .; + } > RAM + + .text (FLASH_TO_FLASHX(__load_stop_overlay_bss_end)) : AT (FLASHX_TO_FLASH(ADDR(.text))) + { + *(.text*) + *(.flash_text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + } > FLASHX + + .ARM.extab (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.extab))) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASHX + + __exidx_start = .; + /* .ARM.exidx contains R_ARM_PREL31 (+-0x40000000) offset to functions, which means + * the session location cannot be too far away from the function addresses */ + .ARM.exidx (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.exidx))) + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASHX + __exidx_end = .; + + . = FLASHX_TO_FLASH(.); + + .rodata (.) : + { + *(.rodata*) + *(.flash_rodata*) + KEEP(*(.eh_frame*)) + *(.note.gnu.build-id) + } > FLASH + +#ifdef TRACE_STR_SECTION + .trc_str (.) : + { + *(.trc_str*) + } > FLASH +#endif + + .custom.cmd.table (.) : + { + . = ALIGN(4); + __custom_handler_table_start = .; + KEEP(*(.custom_handler_table)) + __custom_handler_table_end = .; + } > FLASH + + .thirdparty.event.table (.) : + { + . = ALIGN(4); + __thirdparty_handler_table_start = .; + KEEP(*(.thirdparty_handler_table)) + __thirdparty_handler_table_end = .; + } > FLASH + +#if defined(FIRMWARE_REV) + .firmware_rev (.) : + { + . = ALIGN(64); + *(.fw_rev) + } > FLASH +#endif + + /* To copy multiple FLASH to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table (.) : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table (.) : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss (.) (NOLOAD) : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (.) (NOLOAD) : + { + . = ALIGN(8); + __HeapBase = .; + __end__ = .; + end = __end__; + . += HEAP_SECTION_SIZE; + . = ALIGN(8); + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (.) (COPY) : + { + . = STACK_SECTION_SIZE; + . = ALIGN(8); + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + __free_ram = __StackLimit - __HeapLimit; + + . = __etext + SIZEOF(.data); + + .system_info (.) : + { + KEEP(*(.system_info_list_size)) + KEEP(*(.system_info_list)) + . = ALIGN(4); + } > FLASH + + .build_info (.) : + { + KEEP(*(.build_info)) + . = ALIGN(4); + } > FLASH = 0x00000000 + +#ifdef SLAVE_BIN_FLASH_OFFSET + .slave_code (ORIGIN(FLASH) + SLAVE_BIN_FLASH_OFFSET): + { + KEEP(*(.slave_code_flash_rodata)) + } > FLASH +#endif + + /* The following section be the last loaded section */ + .code_start_addr (.) : + { + LONG(BUILD_INFO_MAGIC); + LONG(ABSOLUTE(__flash_start)); + } > FLASH + + __flash_end = .; + + + .crash_dump (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + CRASH_DUMP_SECTION_SIZE) (NOLOAD) : + { + __crash_dump_start = .; + . = CRASH_DUMP_SECTION_SIZE; + __crash_dump_end = .; + } > FLASH_NC + + .custom_parameter (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE) (NOLOAD) : + { + __custom_parameter_start = .; + . = CUSTOM_PARAMETER_SECTION_SIZE; + __custom_parameter_end = .; + } > FLASH_NC + + .userdata (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2) (NOLOAD) : + { + __userdata_start = .; + . = USERDATA_SECTION_SIZE*2; + __userdata_end = .; + } > FLASH_NC + + .audio (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE) (NOLOAD) : + { + __aud_start = .; + . = AUD_SECTION_SIZE; + __aud_end = .; + } > FLASH_NC + + .reserved (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE) (NOLOAD) : + { + __reserved_start = .; + . = RESERVED_SECTION_SIZE; + __reserved_end = .; + } > FLASH_NC + + .factory (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE) (NOLOAD) : + { + __factory_start = .; + . = FACTORY_SECTION_SIZE; + __factory_end = .; + } > FLASH_NC + + ASSERT(FLASH_NC_TO_C(__crash_dump_start) >= __flash_end, "region FLASH overflowed") + __free_flash = FLASH_NC_TO_C(__crash_dump_start) - __flash_end; +} + diff --git a/scripts/link/best1000savepower.lds.S b/scripts/link/best1000savepower.lds.S new file mode 100644 index 0000000..114b83b --- /dev/null +++ b/scripts/link/best1000savepower.lds.S @@ -0,0 +1,2175 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#ifdef RB_CODEC +#define HEAP_SECTION_SIZE 0x1000 +#else +#define HEAP_SECTION_SIZE 0x1000 +#endif + +#define STACK_SECTION_SIZE 0xD00 +#define CP_STACK_SECTION_SIZE 0x1000 + +#if defined(ROM_UTILS_ON) +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) +#define ROM_UTILS_RESV_RAM_SIZE 0x64 +#else +#define ROM_UTILS_RESV_RAM_SIZE 0x0 +#endif +#endif + +#ifdef RB_CODEC +#define OVERLAY_DATA_SECTION_SIZE 0xA000 +#else +#define OVERLAY_DATA_SECTION_SIZE 0x8000 +#endif + +#if (RAM_SIZE >= 0x48000) +#define FAST_XRAM_SECTION_SIZE 0x78000 +#endif + +/* TODO: Add FLASH_REGION_OFFSET if there are multiple levels of boot loaders */ +#if !defined(OTA_BOOT_SIZE) && defined(OTA_CODE_OFFSET) +#define FLASH_REGION_BASE (FLASH_BASE + OTA_CODE_OFFSET) +#else +#define FLASH_REGION_BASE (FLASH_BASE) +#endif + +#ifndef FLASH_REGION_SIZE +#define FLASH_REGION_SIZE (FLASH_SIZE - (FLASH_REGION_BASE - FLASH_BASE)) +#endif + +#define FLASH_NC_REGION_BASE FLASH_C_TO_NC(FLASH_REGION_BASE) +#define FLASHX_REGION_BASE FLASH_TO_FLASHX(FLASH_REGION_BASE) + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) +#define OVERLAY_FOR_CP +#endif + +#ifdef OVERLAY_FOR_CP +#define REGION_OVERLAY_TEXT RAMCPX +#define REGION_OVERLAY_DATA RAMCP +#else +#define REGION_OVERLAY_TEXT FRAMX +#define REGION_OVERLAY_DATA RAM +#endif + +/* Linker script to configure memory regions. */ +/* See plat_addr_map.h and common.mk for the macro definitions */ +MEMORY +{ + ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE + FLASH (r) : ORIGIN = FLASH_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASH_NC (r) : ORIGIN = FLASH_NC_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASHX (rx) : ORIGIN = FLASHX_REGION_BASE, LENGTH = FLASH_REGION_SIZE + RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + RAMX (rx) : ORIGIN = RAMX_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + FRAMX (rwx) : ORIGIN = RAMX_BASE + RAM_SIZE - FAST_XRAM_SECTION_SIZE, LENGTH = FAST_XRAM_SECTION_SIZE +#ifdef PSRAM_BASE + PSRAM (rwx) : ORIGIN = PSRAM_BASE, LENGTH = PSRAM_SIZE + PSRAM_NC (rwx) : ORIGIN = PSRAM_NC_BASE, LENGTH = PSRAM_SIZE + PSRAMX (rx) : ORIGIN = PSRAMX_BASE, LENGTH = PSRAM_SIZE +#endif +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + RAMCP (rwx) : ORIGIN = RAMCP_BASE, LENGTH = RAMCP_SIZE + RAMCPX (rwx) : ORIGIN = RAMCPX_BASE, LENGTH = RAMCPX_SIZE +#endif +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __export_fn_rom + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __free_ram + * __factory_start + * __factory_end + * __calib_start + * __calib_end + * __flash_start + * __flash_end + * __free_flash + * __boot_sram_start_flash__ + * __boot_sram_end_flash__ + * __boot_sram_start__ + * __boot_bss_sram_start__ + * __boot_bss_sram_end__ + * __sram_text_data_start_flash__ + * __sram_text_data_end_flash__ + * __fast_sram_text_data_start__ + * __fast_sram_text_data_end__ + * __fast_sram_text_data_start_flash__ + * __fast_sram_text_data_end_flash__ + * __sram_text_data_start__ + * __sram_bss_start__ + * __sram_bss_end__ + * __overlay_text_start__ + * __overlay_text_exec_start__ + * __overlay_data_start__ + */ +ENTRY(Boot_Loader) + +SECTIONS +{ + __export_fn_rom = (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE); + + .boot_struct (ORIGIN(FLASH)) : + { + __flash_start = .; + KEEP(*(.boot_struct)) + . = ALIGN(4); + } > FLASH + + . = FLASH_TO_FLASHX(.); + + .boot_text_flash (.) : AT (FLASHX_TO_FLASH(ADDR(.boot_text_flash))) + { + *(.boot_loader) + *(.boot_text_flash*) + *(.boot_rodata*) + . = ALIGN(4); + } > FLASHX + +#if defined(__BES_OTA_MODE__) + .ota_boot_info (ALIGN(4096)) : + { + *(.ota_boot_info) + . = (0x1000); + } > FLASHX + + .ota_boot_rev (ALIGN(4096)) : + { + *(.ota_boot_rev) + . = (0x1000); + } > FLASHX +#endif + + . = FLASHX_TO_FLASH(.); + + .got_info (.) : + { + __got_info_start = .; + __got_start = .; + *(.got) + . = ALIGN(4); + __got_end = .; + __got_plt_start = .; + *(.got.plt) + . = ALIGN(4); + __igot_plt_start = .; + *(.igot.plt) + . = ALIGN(4); + __dynamic_start = .; + *(.dynamic) + . = ALIGN(4); + __got_info_end = .; + } > FLASH + + .vector_table (ORIGIN(RAM)) (NOLOAD) : + { + KEEP(*(.vector_table)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .reboot_param (.) (NOLOAD) : + { + KEEP(*(.reboot_param)) + . = REBOOT_PARAM_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .userdata_pool (.) (NOLOAD) : + { + *(.userdata_pool) + . = ALIGN(4); + __userdata_pool_end__ = .; + } > RAM + + __boot_sram_start_flash__ = LOADADDR(.got_info) + SIZEOF(.got_info); + __boot_sram_start__ = __userdata_pool_end__; + + .boot_text_sram (RAM_TO_RAMX(__boot_sram_start__)) : AT (__boot_sram_start_flash__) + { + /* memcpy.o or libc_nano.a(lib_a-memcpy.o/lib_a-memcpy-stub.o) */ + *:memcpy.o(.text*) + *:lib_a-memcpy*.o(.text*) + *:libc_rom.o(.text*) + + /* memset.o or libc_nano.a(lib_a-memset.o) */ + *:memset.o(.text*) + *:lib_a-memset*.o(.text*) + + *:hal_norflash*.o(.text*) + *:norflash_*.o(EXCLUDE_FILE(*:norflash_api.o) .text*) + +#ifdef BOOT_CODE_IN_RAM + *:hal_cmu_*.o(.text*) + *:hal_iomux_*.o(.text*) + *:hal_analogif_*.o(.text*) + *:hal_spi.o(.text*) + *:hal_timer.o(.text*) + *:hal_sysfreq.o(.text*) +#endif + *:hal_iomux_best2300p.o(.text* .rodata*) + *:hal_analogif_best2300p.o(.text* .rodata*) + *:hal_timer.o(.text* .rodata*) + *:hal_spi.o(.text* .rodata*) + *:hal_sysfreq.o(.text* .rodata*) + *:hal_cmu_best2300p.o(.text* .rodata*) + *:hal_cmu_common.o(.text* .rodata*) + *:hal_chipid.o (.text* .rodata) + *:hal_cache.o (.text* .rodata) + *:hal_btpcm.o (.text* .rodata) + *:hal_bootmode.o (.text* .rodata) + + *(.boot_text_sram*) + . = ALIGN(4); + __boot_text_sram_end = .; + } > RAMX + + .boot_data_sram (RAMX_TO_RAM(ADDR(.boot_text_sram) + SIZEOF(.boot_text_sram))) : + AT (__boot_sram_start_flash__ + SIZEOF(.boot_text_sram)) + { + *:hal_norflash*.o(.data* .rodata*) + *:norflash_*.o(EXCLUDE_FILE(*:norflash_api.o) .data* EXCLUDE_FILE(*:norflash_api.o) .rodata*) + *:hal_psram.o(.data* .rodata*) + *(.boot_data*) + . = ALIGN(4); + __boot_data_sram_end = .; + } > RAM + + __boot_sram_end_flash__ = __boot_sram_start_flash__ + + SIZEOF(.boot_text_sram) + SIZEOF(.boot_data_sram); + + .boot_bss_sram (.) (NOLOAD) : + { + __boot_bss_sram_start__ = .; + *:hal_norflash*.o(.bss*) + *:norflash_*.o(EXCLUDE_FILE(*:norflash_api.o) .bss*) + *:hal_psram.o(.bss*) + *(.boot_bss*) + . = ALIGN(4); + __boot_bss_sram_end__ = .; + } > RAM + + __sram_text_data_start_flash__ = __boot_sram_end_flash__; + __sram_text_data_start__ = __boot_bss_sram_end__; + + .sram_text (RAM_TO_RAMX(__sram_text_data_start__)) : AT (__sram_text_data_start_flash__) + { + *:norflash_api.o(.text*) + *(.sram_text*) + . = ALIGN(4); + } > RAMX + + .sram_data (RAMX_TO_RAM(ADDR(.sram_text) + SIZEOF(.sram_text))) : + AT (__sram_text_data_start_flash__ + SIZEOF(.sram_text)) + { +#if defined(GLOBAL_SRAM_KISS_FFT) + *:fftwrap.o(.data* .rodata*) + *:kiss_fft.o(.data* .rodata*) + *:kiss_fftr.o(.data* .rodata*) +#endif + +#if defined(GLOBAL_SRAM_CMSIS_FFT) + *:arm_common_tables.o(.rodata.armBitRevIndexTable256) + *:arm_common_tables.o(.rodata.twiddleCoef_256) + *:arm_common_tables.o(.rodata.twiddleCoef_rfft_512) + *:arm_common_tables.o(.rodata.armBitRevIndexTable128) + *:arm_common_tables.o(.rodata.twiddleCoef_128) + *:arm_common_tables.o(.rodata.twiddleCoef_rfft_256) +#endif + +#if defined(BTUSB_AUDIO_MODE) + *:hal_usb.o(.rodata*) +#endif + *:utils.o(.data* .rodata*) + *:cqueue.o(.data* .rodata*) + *:iir_process.o(.data* .rodata*) +#if defined(HFP_1_6_ENABLE) + *:sbcplc.o(.data* .rodata*) + *:sbc.o(.data* .rodata*) + *:sbc_math.o(.data* .rodata*) +#endif +#if defined(A2DP_AAC_ON) + *:fixpoint_math.o(.data* .rodata*) + *:FDK_bitbuffer.o(.data* .rodata*) +#endif + *:crossover_filter.o(.data* .rodata*) + *:exp_func_tables.o(.data* .rodata*) +#if defined(KWS_BES) + *:cnn.o(.data* .rodata.second_conv_wt) + *:command_recognition.o(.data* .rodata*) + *:arm_bitreversal_16.o(.data* .rodata*) + *:arm_cfft_radix8_f32.o(.data* .rodata*) + *:arm_bitreversal2.o(.data* .rodata*) + *:arm_mult_f32.o(.data* .rodata*) + *:arm_cmplx_mag_squared_f32.o(.data* .rodata*) + *:arm_cmplx_mult_cmplx_f32.o(.data* .rodata*) + *:arm_abs_f32.o(.data* .rodata*) + *:arm_cos_f32.o(.data* .rodata*) + *:arm_sin_f32.o(.data* .rodata*) +#endif + *:norflash_api.o(.rodata*) + *(.sram_data*) + . = ALIGN(4); + } > RAM + + __sram_text_data_end_flash__ = __sram_text_data_start_flash__ + + SIZEOF(.sram_text) + SIZEOF(.sram_data); + + .sram_bss (.) (NOLOAD) : + { + __sram_bss_start__ = .; + *:utils.o(.bss*) + *(.sram_bss*) + . = ALIGN(4); + __sram_bss_end__ = .; + } > RAM + + __fast_sram_text_data_start_flash__ = __sram_text_data_end_flash__; + + .fast_text_sram (ORIGIN(FRAMX)) : AT (__fast_sram_text_data_start_flash__) + { + __fast_sram_text_exec_start__ = .; + +#if defined(GLOBAL_SRAM_KISS_FFT) + *:fftwrap.o(.text*) + *:kiss_fft.o(.text*) + *:kiss_fftr.o(.text*) +#endif + +#if defined(GLOBAL_SRAM_CMSIS_FFT) + *:cmsis_fftwrap.o(.text*) + *:arm_rfft_fast_f32.o(.text*) + *:arm_cfft_f32.o(.text*) +#endif + + +#if defined(ROM_UTILS_ON) + *:rom_utils.o(.text*) +#endif + +#if defined(BTUSB_AUDIO_MODE) + *:hal_dma.o(.text*) + *:hal_uart.o(.text*) + *:hal_trace.o(.text*) +#endif + +#if defined(BTUSB_AUDIO_MODE) + *:hal_usb.o(.text*) + + *:usb_audio.o(.text*) + *:usb_audio_sync.o(.text*) + *:usb_audio_cdc.o(.text*) + + *:usbaudio_entry.o(.text*) + *:usb_audio_app.o(.text*) +#endif + + /* memmove.o or libc_nano.a(lib_a-memmove.o) */ + *:memmove.o(.text*) + *:lib_a-memmove.o(.text*) + *:utils.o(.text*) + *:cqueue.o(.text*) + *:audio_resample_ex.o(.text*) +#if defined(MIX_MIC_DURING_MUSIC) + *:app_bt_stream.o(.text*) +#endif +#if defined(HFP_1_6_ENABLE) +#if defined(__SBC_FUNC_IN_ROM__) + *:sbc.o(.text*) +#else + *:sbc.o(.text.SbcIsValidStreamInfo) + *:sbc.o(.text.SBC_FrameLen) + *:sbc.o(.text.SbcCrcSum4) + *:sbc.o(.text.SbcMonoBitAlloc) + *:sbc.o(.text.SbcStereoBitAlloc) + *:sbc.o(.text.SbcParseHeader) + *:sbc.o(.text.SbcParseScaleFactors) + *:sbc.o(.text.SbcUnpackSample) + *:sbc.o(.text.SbcBuildSubbandSamples) + *:sbc.o(.text.SbcJointProcessing) + *:sbc.o(.text.SbcSynthesisFilter4) + *:sbc.o(.text.SbcSynthesisFilter8) + *:sbc.o(.text.SbcResetDecoderState) + *:sbc.o(.text.SbcMuteFrame) + *:sbc.o(.text.SBC_DecodeFrames) + *:sbc.o(.text.SbcQuantizeSamples) + *:sbc.o(.text.SBC_InitDecoder) + *:sbc.o(.text.SBC_InitEncoder) + *:sbc.o(.text.SBC_EncodeFrames) +#endif + *:sbc_math.o(.text*) +#endif +#if defined(A2DP_AAC_ON) + *:fixpoint_math.o(.text*) + *:FDK_bitbuffer.o(.text*) + *:FDK_tools_rom.o(.text*FDKgetWindowSlope*) + *:FDK_tools_rom.o(.text*getBitstreamElementList*) + *:dct.o(.text*dct_IV*) +#if !defined(__SBC_FUNC_IN_ROM_VBEST2000__) + *:fft.o(.text._Z3fftiPlPi) + *:fft_rad2.o(.text*dit_fft*) + *:dct.o(.text*getTables*) +#endif +#ifdef VOICE_DATAPATH + *:opus_encoder.o(.text*) +#else +#if defined(__AI_VOICE__) && (RAM_SIZE >= 0x48000) + *:voice_opus.o(.text*) + /**:opus_encoder.o(.text*)*/ + *:opus_encoder.o(.text.frame_size_select) + *:opus_encoder.o(.text.opus_encode_native) + *:opus_encoder.o(.text.user_bitrate_to_bitrate) + *:opus_encoder.o(.text.compute_equiv_rate) + *:opus_encoder.o(.text.decide_fec) + *:opus_encoder.o(.text.dc_reject) + *:opus_encoder.o(.text.gen_toc) + *:opus_encoder.o(.text.opus_encode) + *:opus_encoder.o(.text.opus_encoder_create) + *:opus_encoder.o(.text.opus_encoder_get_size) + *:opus_encoder.o(.text.opus_encoder_init) + *:opus_encoder.o(.text.opus_encoder_ctl) + *:analysis.o(.text*) + /**:celt_encoder.o(.text*)*/ + *:celt_encoder.o(.text.opus_custom_encoder_ctl) + *:celt_encoder.o(.text.celt_encoder_get_size) + *:celt_encoder.o(.text.opus_custom_encoder_get_size) + *:celt_encoder.o(.text.celt_encoder_init) + *:celt_encoder.o(.text.opus_custom_encoder_init_arch) + /**:repacketizer.o(.text*)*/ + *:repacketizer.o(.text.opus_packet_pad) + *:repacketizer.o(.text.opus_repacketizer_init) + *:repacketizer.o(.text.opus_repacketizer_cat) + *:repacketizer.o(.text.opus_repacketizer_cat_impl) + *:repacketizer.o(.text.opus_repacketizer_out_range_impl) + *:opus.o(.text*) + *:enc_API.o(.text*) + /**:entenc.o(.text*)*/ + *:entenc.o(.text.ec_enc_init) + *:entenc.o(.text.ec_enc_icdf) + *:entenc.o(.text.ec_enc_normalize) + *:entenc.o(.text.ec_enc_carry_out) + *:entenc.o(.text.ec_write_byte) + *:entenc.o(.text.ec_enc_patch_initial_bits) + *:entenc.o(.text.ec_enc_done) + *:control_audio_bandwidth.o(.text*) + *:encode_pulses.o(.text*) + *:LPC_analysis_filter.o(.text*) + *:burg_modified_FIX.o(.text.silk_burg_modified_c) + *:vector_ops_FIX.o(.text.silk_scale_copy_vector16) + *:vector_ops_FIX.o(.text.silk_inner_prod_aligned) + *:vector_ops_FIX.o(.text.silk_inner_prod16_aligned_64_c) + *:NLSF_del_dec_quant.o(.text.silk_NLSF_del_dec_quant) + *:encode_frame_FIX.o(.text.silk_encode_frame_FIX) + *:encode_frame_FIX.o(.text.silk_encode_do_VAD_FIX) + *:encode_frame_FIX.o(.text.silk_LBRR_encode_FIX) + /**:pitch.o(.text*)*/ + *:pitch.o(.text.celt_pitch_xcorr_c) + *:resampler.o(.text*) + *:VAD.o(.text*) + *:encode_indices.o(.text*) + /**:control_codec.o(.text*)*/ + *:control_codec.o(.text.silk_control_encoder) + *:control_codec.o(.text.silk_setup_resamplers) + *:control_codec.o(.text.silk_setup_fs) + *:control_codec.o(.text.silk_setup_complexity) + *:control_codec.o(.text.silk_setup_LBRR) + /**:celt_lpc.o(.text*)*/ + *:celt_lpc.o(.text._celt_autocorr) + /**:shell_coder.o(.text*)*/ + *:shell_coder.o(.text.combine_pulses) + *:shell_coder.o(.text.silk_shell_encoder) + *:shell_coder.o(.text.encode_split) + *:init_encoder.o(.text*) + *:log2lin.o(.text*) + *:biquad_alt.o(.text*) + *:stereo_encode_pred.o(.text*) + *:NLSF_unpack.o(.text*) + *:code_signs.o(.text*) + *:lin2log.o(.text*) + *:HP_variable_cutoff.o(.text*) + *:sum_sqr_shift.o(.text*) + *:inner_prod_aligned.o(.text*) + *:stereo_quant_pred.o(.text*) + *:entcode.o(.text*) + *:celt.o(.text*) + *:laplace.o(.text*) + /**:NSQ.o(.text*)*/ /*complexity 1*/ + /**:NSQ_del_dec.o(.text*)*/ /*complexity 2*/ +#endif +#endif +#endif + +#if defined(__AUDIO_SPECTRUM__) + *:spectrum_fix.o(.text*) + *:audio_spectrum.o(.text*) +#endif + *:mdct.o(.text*) + *:crossover_filter.o(.text*) + *:data_compressor.o(.text*) + *:drc.o(.text*) + *:limiter.o(.text*) +#if defined(KWS_BES) + *:arm_*.o(.text*) + *:mfcc.o(.text*) + *:cnn.o(.text*) + *:command_recognition.o(.text*) + *:arm_radix8_butterfly_f32.o(.text*) + *:arm_bitreversal_32.o(.text*) + *:arm_bitreversal_16.o(.text*) + *:dct.o(.text*dct_IV*) + *:fft.o(.text._Z3fftiPlPi) + *:fft_rad2.o(.text*dit_fft*) + *:dct.o(.text*getTables*) + *:arm_cfft_radix8_f32.o(.text*) + *:arm_bitreversal2.o(.text*) + *:arm_mult_f32.o(.text*) + *:arm_cmplx_mag_squared_f32.o(.text*) + *:arm_cmplx_mult_cmplx_f32.o(.text*) + *:lib_a-wf_sqrt.o(.text*) + *:arm_abs_f32.o(.text*) + *:arm_cos_f32.o(.text*) + *:arm_sin_f32.o(.text*) +#endif +#if !defined(SCO_OPTIMIZE_FOR_RAM) + :audio_prompt_sbc.o(.text*) +#endif + + + /*apps*/ + +*:app_battery.o(.text* .rodata*) +*:app_pwl.o(.text* .rodata*) +*:app_key.o(.text* .rodata*) +*:app_status_ind.o(.text* .rodata*) +*:apps.o(.text* .rodata*) +*:app_spec_ostimer.o(.text* .rodata*) +*:app_utils.o(.text* .rodata*) +*:app_thread.o(.text* .rodata*) +*:app_audio.o(.text* .rodata*) +*:plc_utils.o(.text* .rodata*) +*:a2dp_decoder.o(.text* .rodata*) +*:a2dp_decoder_sbc.o(.text* .rodata*) +*:a2dp_decoder_aac_lc.o(.text* .rodata*) +*:a2dp_decoder_cp.o(.text* .rodata*) + +/*cq*/ +*:cqueue.o(.text* .rodata*) +/*heap api*/ +*:heap_api.o(.text* .rodata*) +*:multi_heap.o(.text* .rodata*) +*:pool_api.o(.text* .rodata*) +/*hwtimer*/ +*:hwtimer_list.o(.text* .rodata*) +/*kfifo*/ +*:kfifo.o(.text* .rodata*) +/*list*/ +*:list.o(.text* .rodata*) + + +*:sbcaac_dummy.o(.text* .rodata*) + +*:system_cp.o(.text* .rodata*) +*:system_ARMCM.o(.text* .rodata*) +*:patch.o(.text* .rodata*) +*:cmsis_nvic.o(.text* .rodata*) +*:arm_var_q31.o(.text* .rodata*) +*:arm_var_q15.o(.text* .rodata*) +*:arm_var_f32.o(.text* .rodata*) +*:arm_std_q31.o(.text* .rodata*) +*:arm_std_q15.o(.text* .rodata*) +*:arm_std_f32.o(.text* .rodata*) +*:arm_rms_q31.o(.text* .rodata*) +*:arm_rms_q15.o(.text* .rodata*) +*:arm_rms_f32.o(.text* .rodata*) +*:arm_power_q7.o(.text* .rodata*) +*:arm_power_q31.o(.text* .rodata*) +*:arm_power_q15.o(.text* .rodata*) +*:arm_power_f32.o(.text* .rodata*) +*:arm_min_q7.o(.text* .rodata*) +*:arm_min_q31.o(.text* .rodata*) +*:arm_min_q15.o(.text* .rodata*) +*:arm_min_f32.o(.text* .rodata*) +*:arm_mean_q7.o(.text* .rodata*) +*:arm_mean_q31.o(.text* .rodata*) +*:arm_mean_q15.o(.text* .rodata*) +*:arm_mean_f32.o(.text* .rodata*) +*:arm_max_q7.o(.text* .rodata*) +*:arm_max_q31.o(.text* .rodata*) +*:arm_max_q15.o(.text* .rodata*) +*:arm_max_f32.o(.text* .rodata*) +*:arm_const_structs.o(.text* .rodata*) +*:arm_common_tables.o(.text* .rodata*) +*:arm_dot_prod_q15.o(.text* .rodata*) +*:arm_biquad_cascade_df1_init_f32.o(.text* .rodata*) +*:arm_fir_init_q15.o(.text* .rodata*) +*:arm_fir_fast_q15.o(.text* .rodata*) +*:arm_bitreversal2.o(.text* .rodata*) +*:arm_cfft_q15.o(.text* .rodata*) +*:arm_cfft_radix4_q15.o(.text* .rodata*) +*:arm_cfft_radix8_f32.o(.text* .rodata*) +*:arm_rfft_fast_init_f32.o(.text* .rodata*) +*:arm_rfft_init_q15.o(.text* .rodata*) +*:arm_rfft_q15.o(.text* .rodata*) +*:arm_copy_q31.o(.text* .rodata*) +*:arm_fill_q31.o(.text* .rodata*) +*:arm_q15_to_float.o(.text* .rodata*) +*:arm_dot_prod_q7.o(.text* .rodata*) +*:arm_add_q15.o(.text* .rodata*) +*:arm_shift_q15.o(.text* .rodata*) +*:arm_negate_q15.o(.text* .rodata*) +*:arm_offset_q15.o(.text* .rodata*) +*:arm_mult_q15.o(.text* .rodata*) + +#if 1 + /*bt app*/ + *:a2dp_codec_scalable.o(.text* .rodata*) + *:a2dp_codec_sbc.o(.text* .rodata*) + *:a2dp_codec_opus.o(.text* .rodata*) + *:codec_lhdc.o(.text* .rodata*) + *:a2dp_codec_lhdc.o(.text* .rodata*) + *:a2dp_codec_ldac.o(.text* .rodata*) + *:a2dp_codec_aac.o(.text* .rodata*) + *:app_a2dp_codecs.o(.text* .rodata*) + *:app_a2dp.o(.text* .rodata*) + *:app_bt.o(.text* .rodata*) + *:app_bt_func.o(.text* .rodata*) + *:app_bt_media_manager.o(.text* .rodata*) + *:app_bt_stream.o(.text* .rodata*) + *:app_keyhandle.o(.text* .rodata*) + *:app_ring_merge.o(.text* .rodata*) + *:app_sec.o(.text* .rodata*) + *:app_spp.o(.text* .rodata*) + *:audio_prompt_sbc.o(.text* .rodata*) + *:besmain.o(.text* .rodata*) + + + /*bt if*/ + *:bt_status_conv.o(.text* .rodata*) + *:bt_if.o(.text* .rodata*) + *:a2dp_api.o(.text* .rodata*) + *:codec_sbc.o(.text* .rodata*) + *:avrcp_api.o(.text* .rodata*) + *:cmgr_api.o(.text* .rodata*) + *:hci_api.o(.text* .rodata*) + *:l2cap_api.o(.text* .rodata*) + *:me_api.o(.text* .rodata*) + *:utils.o(.text* .rodata*) + *:sdp_api.o(.text* .rodata*) + *:spp.o(.text* .rodata*) + *:spp_api.o(.text* .rodata*) + *:hfp_api.o(.text* .rodata*) + *:os_api.o(.text* .rodata*) + *:rfcomm_api.o(.text* .rodata*) + *:bt_xtal_sync.o(.text* .rodata*) + *:besaud_api.o(.text* .rodata*) +#if 0 + /*bt prf*/ + *:a2dp.o(.text*) + *:sbc.o(.text*) + *:avctp.o(.text*) + *:avrcp.o(.text*) + *:besaud.o(.text*) + *:besaudalloc.o(.text*) + *:besaudcon.o(.text*) + *:btm.o(.text*) + *:btm_devicedb.o(.text*) + *:btm_handle_hcievent.o(.text*) + *:btm_sco_interface.o(.text*) + *:btm_security.o(.text*) + *:avdtp.o(.text*) + *:connect.o(.text*) + *:hfp.o(.text*) + *:hshf.o(.text*) + *:hsp.o(.text*) + *:l2cap.o(.text*) + *:l2cap_er.o(.text*) + *:bt_common.o(.text*) + *:co_lib.o(.text*) + *:co_ppbuff.o(.text*) + *:md5.o(.text*) + *:obex.o(.text*) + *:pbap.o(.text*) + *:rfcomm.o(.text*) + *:sco.o(.text*) + *:sdp.o(.text*) + *:co_printf.o(.text*) + *:co_queue.o(.text*) + *:co_timer.o(.text*) + *:cobuf.o(.text*) + *:bes_os.o(.text*) + *:hci.o(.text*) + *:hci_buff.o(.text*) + *:bt_schedule.o(.text*) +#else +*:a2dp.o(.text* .rodata*) +*:sbc.o(.text* .rodata*) +*:avctp.o(.text* .rodata*) +*:avrcp.o(.text* .rodata*) +*:besaud.o(.text* .rodata*) +*:besaudalloc.o(.text* .rodata*) +*:besaudcon.o(.text* .rodata*) +*:btm.o(.text* .rodata*) +*:btm_devicedb.o(.text* .rodata*) +*:btm_handle_hcievent.o(.text* .rodata*) +*:btm_sco_interface.o(.text* .rodata*) +*:btm_security.o(.text* .rodata*) +*:avdtp.o(.text* .rodata*) +*:connect.o(.text* .rodata*) +*:hfp.o(.text* .rodata*) +*:hshf.o(.text* .rodata*) +*:hsp.o(.text* .rodata*) +*:l2cap.o(.text* .rodata*) +*:l2cap_er.o(.text* .rodata*) +*:bt_common.o(.text* .rodata*) +*:co_lib.o(.text* .rodata*) +*:co_ppbuff.o(.text* .rodata*) +*:md5.o(.text* .rodata*) +*:obex.o(.text* .rodata*) +*:pbap.o(.text* .rodata*) +*:rfcomm.o(.text* .rodata*) +*:sco.o(.text* .rodata*) +*:sdp.o(.text* .rodata*) +*:co_printf.o(.text* .rodata*) +*:co_queue.o(.text* .rodata*) +*:co_timer.o(.text* .rodata*) +*:cobuf.o(.text* .rodata*) +*:bes_os.o(.text* .rodata*) +*:hci.o(.text* .rodata*) +*:hci_buff.o(.text* .rodata*) +*:bt_schedule.o(.text* .rodata*) + +#endif + +#endif + +#if 1 + /*af */ + *:audioflinger.o(.text* .rodata*) + + /*intersys*/ + *:hal_intersys.o(.text* .rodata*) + *:intersyshci.o(.text* .rodata*) + *:trans_adapt_v2.o(.text* .rodata*) + + /*tws ibrt*/ + + *:app_ibrt_bt_profile_sync.o(.text* .rodata*) + *:app_ibrt_ui.o(.text* .rodata*) + *:app_tws_besaud.o(.text* .rodata*) + *:app_tws_ctrl_thread.o(.text* .rodata*) + *:app_tws_ibrt.o(.text* .rodata*) + *:app_tws_ibrt_audio_analysis.o(.text* .rodata*) + *:app_tws_ibrt_audio_sync.o(.text* .rodata*) + *:app_tws_ibrt_cmd_handler.o(.text* .rodata*) + *:app_tws_ibrt_mock.o(.text* .rodata*) + *:app_tws_ibrt_queue.o(.text* .rodata*) + *:app_tws_ibrt_trace.o(.text* .rodata*) + *:app_tws_profile_sync.o(.text* .rodata*) + *:app_vendor_cmd_evt.o(.text* .rodata*) + + + /*app ibrt*/ + *:app_ibrt_customif_cmd.o(.text* .rodata*) + *:app_ibrt_customif_ui.o(.text* .rodata*) + *:app_ibrt_if.o(.text* .rodata*) + *:app_ibrt_keyboard.o(.text* .rodata*) + *:app_ibrt_nvrecord.o(.text* .rodata*) + *:app_ibrt_ota_update.o(.text* .rodata*) + *:app_ibrt_peripheral_manager.o(.text* .rodata*) + *:app_ibrt_search_pair_ui.o(.text* .rodata*) + *:app_ibrt_ui_test.o(.text* .rodata*) + *:app_ibrt_voice_report.o(.text* .rodata*) +#endif + /*rtos*/ + *:SVC_Table.o(.text* .rodata*) + *:HAL_CM4.o(.text* .rodata*) + *:RTX_Conf_CM.o(.text* .rodata*) + *:rt_Time.o(.text* .rodata*) + *:rt_Task.o(.text* .rodata*) + *:rt_System.o(.text* .rodata*) + *:rt_Semaphore.o(.text* .rodata*) + *:rt_Robin.o(.text* .rodata*) + *:rt_Mutex.o(.text* .rodata*) + *:rt_MemBox.o(.text* .rodata*) + *:rt_Mailbox.o(.text* .rodata*) + *:rt_List.o(.text* .rodata*) + *:rt_Event.o(.text* .rodata*) + *:rt_CMSIS.o(.text* .rodata*) + *:HAL_CM.o(.text* .rodata*) + +/*services multimedia*/ + + *:g711.o(.text* .rodata*) + *:g726.o(.text* .rodata*) + *:g726_16.o(.text* .rodata*) + *:g726_24.o(.text* .rodata*) + *:g726_32.o(.text* .rodata*) + *:g72x.o(.text* .rodata*) + *:armfirfilt.o(.text* .rodata*) + *:buffer_manager.o(.text* .rodata*) + *:exp_func_tables.o(.text* .rodata*) + *:fastmath_const.o(.text* .rodata*) + *:firfilt.o(.text* .rodata*) + *:fraction_delay.o(.text* .rodata*) + *:frame_resize.o(.text* .rodata*) + *:fftfilt.o(.text* .rodata*) + *:speech_iir_calibration.o(.text* .rodata*) + *:speech_aec.o(.text* .rodata*) + *:codec_op_cpx.o(.text* .rodata*) + *:codec_op_etsi.o(.text* .rodata*) + *:codec_op_float.o(.text* .rodata*) + *:codec_op_lib.o(.text* .rodata*) + *:codec_op_netsi.o(.text* .rodata*) + *:codec_op_vec.o(.text* .rodata*) + *:med_aec_delay.o(.text* .rodata*) + *:med_aec_hf_af.o(.text* .rodata*) + *:med_aec_hf_nlp.o(.text* .rodata*) + *:med_aec_hpf.o(.text* .rodata*) + *:med_aec_main.o(.text* .rodata*) + *:med_emph_filter.o(.text* .rodata*) + *:med_fft.o(.text* .rodata*) + *:med_fft_tab.o(.text* .rodata*) + *:med_kissfft.o(.text* .rodata*) + *:mdf1.o(.text* .rodata*) + *:digital_agc.o(.text* .rodata*) + *:triple_mic_denoise3.o(.text* .rodata*) + *:buffer.o(.text* .rodata*) + *:jitter.o(.text* .rodata*) + *:scal.o(.text* .rodata*) + *:smallft.o(.text* .rodata*) + *:speech_ns.o(.text* .rodata*) + *:cng.o(.text* .rodata*) + *:ns3f.o(.text* .rodata*) + *:wnr.o(.text* .rodata*) + *:table.o(.text* .rodata*) + *:dtw.o(.text* .rodata*) + *:mfcc.o(.text* .rodata*) + *:recognition.o(.text* .rodata*) + *:vad.o(.text* .rodata*) + *:resample.o(.text* .rodata*) + *:spectrum.o(.text* .rodata*) + *:spectrum_fix.o(.text* .rodata*) + *:window_generator.o(.text* .rodata*) + *:speech_dc_filter.o(.text* .rodata*) + *:iirfilt_design.o(.text* .rodata*) + *:genericStds.o(.text* .rodata*) + *:conv_string.o(.text* .rodata*) + *:cmdl_parser.o(.text* .rodata*) + *:tran_det.o(.text* .rodata*) + *:ton_corr.o(.text* .rodata*) + *:sbrenc_freq_sca.o(.text* .rodata*) + *:sbr_rom.o(.text* .rodata*) + *:sbr_ram.o(.text* .rodata*) + *:sbr_misc.o(.text* .rodata*) + *:sbr_encoder.o(.text* .rodata*) + *:resampler.o(.text* .rodata*) + *:ps_main.o(.text* .rodata*) + *:ps_encode.o(.text* .rodata*) + *:ps_bitenc.o(.text* .rodata*) + *:nf_est.o(.text* .rodata*) + *:mh_det.o(.text* .rodata*) + *:invf_est.o(.text* .rodata*) + *:fram_gen.o(.text* .rodata*) + *:env_est.o(.text* .rodata*) + *:env_bit.o(.text* .rodata*) + *:code_env.o(.text* .rodata*) + *:bit_sbr.o(.text* .rodata*) + *:sbrdecoder.o(.text* .rodata*) + *:sbrdec_freq_sca.o(.text* .rodata*) + *:sbrdec_drc.o(.text* .rodata*) + *:sbr_rom.o(.text* .rodata*) + *:sbr_ram.o(.text* .rodata*) + *:sbr_dec.o(.text* .rodata*) + *:sbr_deb.o(.text* .rodata*) + *:sbr_crc.o(.text* .rodata*) + *:psdec_hybrid.o(.text* .rodata*) + *:psdec.o(.text* .rodata*) + *:psbitdec.o(.text* .rodata*) + *:lpp_tran.o(.text* .rodata*) + *:huff_dec.o(.text* .rodata*) + *:env_extr.o(.text* .rodata*) + *:env_dec.o(.text* .rodata*) + *:env_calc.o(.text* .rodata*) + *:pcmutils_lib.o(.text* .rodata*) + *:limiter.o(.text* .rodata*) + *:tpenc_lib.o(.text* .rodata*) + *:tpenc_latm.o(.text* .rodata*) + *:tpenc_asc.o(.text* .rodata*) + *:tpenc_adts.o(.text* .rodata*) + *:tpenc_adif.o(.text* .rodata*) + *:tpdec_drm.o(.text* .rodata*) + *:tpdec_adts.o(.text* .rodata*) + *:tpdec_adif.o(.text* .rodata*) + *:scale.o(.text* .rodata*) + *:qmf.o(.text* .rodata*) + *:mdct.o(.text* .rodata*) + *:fixpoint_math.o(.text* .rodata*) + *:fft_rad2.o(.text* .rodata*) + *:fft.o(.text* .rodata*) + *:FDK_trigFcts.o(.text* .rodata*) + *:FDK_tools_rom.o(.text* .rodata*) + *:FDK_hybrid.o(.text* .rodata*) + *:FDK_crc.o(.text* .rodata*) + *:FDK_core.o(.text* .rodata*) + *:FDK_bitbuffer.o(.text* .rodata*) + *:dct.o(.text* .rodata*) + *:autocorr2nd.o(.text* .rodata*) + *:transform.o(.text* .rodata*) + *:tonality.o(.text* .rodata*) + *:spreading.o(.text* .rodata*) + *:sf_estim.o(.text* .rodata*) + *:quantize.o(.text* .rodata*) + *:qc_main.o(.text* .rodata*) + *:psy_main.o(.text* .rodata*) + *:psy_configuration.o(.text* .rodata*) + *:pre_echo_control.o(.text* .rodata*) + *:pnsparam.o(.text* .rodata*) + *:noisedet.o(.text* .rodata*) + *:ms_stereo.o(.text* .rodata*) + *:metadata_main.o(.text* .rodata*) + *:metadata_compressor.o(.text* .rodata*) + *:line_pe.o(.text* .rodata*) + *:intensity.o(.text* .rodata*) + *:grp_data.o(.text* .rodata*) + *:dyn_bits.o(.text* .rodata*) + *:chaosmeasure.o(.text* .rodata*) + *:channel_map.o(.text* .rodata*) + *:block_switch.o(.text* .rodata*) + *:bitenc.o(.text* .rodata*) + *:bit_cnt.o(.text* .rodata*) + *:bandwidth.o(.text* .rodata*) + *:band_nrg.o(.text* .rodata*) + *:adj_thr.o(.text* .rodata*) + *:aacenc_tns.o(.text* .rodata*) + *:aacEnc_rom.o(.text* .rodata*) + *:aacEnc_ram.o(.text* .rodata*) + *:aacenc_pns.o(.text* .rodata*) + *:aacenc_lib.o(.text* .rodata*) + *:aacenc.o(.text* .rodata*) + *:rvlcconceal.o(.text* .rodata*) + *:rvlcbit.o(.text* .rodata*) + *:rvlc.o(.text* .rodata*) + *:ldfiltbank.o(.text* .rodata*) + *:conceal.o(.text* .rodata*) + *:aacdec_hcrs.o(.text* .rodata*) + *:aacdec_hcr_bit.o(.text* .rodata*) + *:aacdec_hcr.o(.text* .rodata*) + *:aacdec_drc.o(.text* .rodata*) + *:aac_rom.o(.text* .rodata*) + *:aac_ram.o(.text* .rodata*) + *:floatlimiter.o(.text* .rodata*) + *:audio_resample_ex_32bit.o(.text* .rodata*) + *:audio_resample_ex.o(.text* .rodata*) + *:audio_resample.o(.text* .rodata*) + *:limiter.o(.text* .rodata*) + *:hw_iir_process_best2300p.o(.text* .rodata*) + *:hw_codec_iir_process_best2300p.o(.text* .rodata*) + *:fir_process_best2300p.o(.text* .rodata*) + *:dsd_process_best2300p.o(.text* .rodata*) + *:crossover_filter.o(.text* .rodata*) + *:audio_memory.o(.text* .rodata*) + *:anc_process_best2300p.o(.text* .rodata*) + *:adp_smallft.o(.text* .rodata*) + *:adp_filter.o(.text* .rodata*) + *:adp_fftwrap.o(.text* .rodata*) + *:fft128dot.o(.text* .rodata*) + *:resample_coef.o(.text* .rodata*) + *:eq_cfg.o(.text* .rodata*) + +/*platform*/ +#if 1 + *:main.o (.text* .rodata) + *:hwtimer_list.o (.text* .rodata) + *:hal_mcu2cp_cp.o (.text* .rodata) + *:hal_mcu2cp_mcu.o (.text* .rodata) + *:hal_sleep_mcu_pd.o (.text* .rodata) + *:hal_wdt.o (.text* .rodata) + *:hal_usbhost.o (.text* .rodata) + *:hal_usb.o (.text* .rodata) + *:hal_uart.o (.text* .rodata) + *:hal_transq.o (.text* .rodata) + *:hal_trace.o (.text* .rodata) + *:hal_tdm.o (.text* .rodata) + *:hal_sleep.o (.text* .rodata) + *:hal_sdmmc.o (.text* .rodata) + *:hal_rtc.o (.text* .rodata) + *:hal_pwm.o (.text* .rodata) + *:hal_overlay.o (.text* .rodata) + *:hal_key.o (.text* .rodata) + *:hal_i2s_tdm.o (.text* .rodata) + *:hal_i2s.o (.text* .rodata) + *:hal_i2c.o (.text* .rodata) + *:hal_gpio.o (.text* .rodata) + *:hal_gpadc.o (.text* .rodata) + *:hal_dma.o (.text* .rodata) + *:hal_codec_common.o (.text* .rodata) + *:hal_cmd.o (.text* .rodata) + +*:hal_intersys.o (.text* .rodata) +*:hal_psram.o (.text* .rodata) +*:hal_memsc.o (.text* .rodata) +*:hal_spdif.o (.text* .rodata) +*:hal_phyif.o (.text* .rodata) +#else + +#endif +/* + *:hal_cmu_common.o (.text* .rodata) + *:hal_timer.o (.text* .rodata) + *:hal_sysfreq.o (.text* .rodata) + *:hal_spi.o (.text* .rodata) + + *:hal_analogif_best2300p.o (.text* .rodata) + *:hal_cmu_best2300p.o (.text* .rodata) + *:hal_iomux_best2300p.o (.text* .rodata) + */ + #if 1 + *:hal_psc_best2300p.o (.text* .rodata) + *:hal_sensor_eng_best2300p.o (.text* .rodata) + *:usbphy_best2300p.o (.text* .rodata) + *:pmu_best2300p.o (.text* .rodata) + *:analog_best2300p.o (.text* .rodata) + *:codec_best2300p.o (.text* .rodata) + *:codec_tlv32aic32.o (.text* .rodata) + *:hal_codec_best2300p.o (.text* .rodata) + *:bt_drv_reg_op.o (.text* .rodata) + *:bt_drv_calibration.o (.text* .rodata) + *:bt_drv.o (.text* .rodata) + *:iqcorrect.o (.text* .rodata) + *:bt_drv_uart_bridge_intsys.o (.text* .rodata) + *:bt_drv_rfconfig.o (.text* .rodata) + *:bt_drv_patch.o (.text* .rodata) + *:bt_drv_config.o (.text* .rodata) + *:bt_drv_common.o (.text* .rodata) + *:btpcm.o (.text* .rodata) + *:sbcaac_dummy.o (.text* .rodata) + *:usb_cdc.o (.text* .rodata) + *:usb_audio_sync.o (.text* .rodata) + *:usb_audio.o (.text* .rodata) + *:usb_dev_desc.o (.text* .rodata) + #endif +/* +*:system_utils.o (.text* .rodata) + */ + *:system_cp.o (.text* .rodata) + *:system_ARMCM.o (.text* .rodata) + *:patch.o (.text* .rodata) + *:mpu.o (.text* .rodata) + *:cmsis_nvic.o (.text* .rodata) + *:arm_var_q31.o (.text* .rodata) + *:arm_var_q15.o (.text* .rodata) + *:arm_var_f32.o (.text* .rodata) + *:arm_std_q31.o (.text* .rodata) + *:arm_std_q15.o (.text* .rodata) + *:arm_std_f32.o (.text* .rodata) + *:arm_rms_q31.o (.text* .rodata) + *:arm_rms_q15.o (.text* .rodata) + *:arm_rms_f32.o (.text* .rodata) + *:arm_power_q7.o (.text* .rodata) + *:arm_power_q31.o (.text* .rodata) + *:arm_power_q15.o (.text* .rodata) + *:arm_power_f32.o (.text* .rodata) + *:arm_min_q7.o (.text* .rodata) + *:arm_min_q31.o (.text* .rodata) + *:arm_min_q15.o (.text* .rodata) + *:arm_min_f32.o (.text* .rodata) + *:arm_mean_q7.o (.text* .rodata) + *:arm_mean_q31.o (.text* .rodata) + *:arm_mean_q15.o (.text* .rodata) + *:arm_mean_f32.o (.text* .rodata) + *:arm_max_q7.o (.text* .rodata) + *:arm_max_q31.o (.text* .rodata) + *:arm_max_q15.o (.text* .rodata) + *:arm_max_f32.o (.text* .rodata) + *:arm_const_structs.o (.text* .rodata) + *:arm_common_tables.o (.text* .rodata) + *:arm_dot_prod_q15.o (.text* .rodata) + *:arm_biquad_cascade_df1_init_f32.o (.text* .rodata) + *:arm_fir_init_q15.o (.text* .rodata) + *:arm_fir_fast_q15.o (.text* .rodata) + *:arm_bitreversal2.o (.text* .rodata) + *:arm_cfft_q15.o (.text* .rodata) + *:arm_cfft_radix4_q15.o (.text* .rodata) + *:arm_cfft_radix8_f32.o (.text* .rodata) + *:arm_rfft_fast_init_f32.o (.text* .rodata) + *:arm_rfft_init_q15.o (.text* .rodata) + *:arm_rfft_q15.o (.text* .rodata) + *:arm_copy_q31.o (.text* .rodata) + *:arm_fill_q31.o (.text* .rodata) + *:arm_q15_to_float.o (.text* .rodata) + *:arm_dot_prod_q7.o (.text* .rodata) + *:arm_add_q15.o (.text* .rodata) + *:arm_shift_q15.o (.text* .rodata) + *:arm_negate_q15.o (.text* .rodata) + *:arm_offset_q15.o (.text* .rodata) + *:arm_mult_q15.o (.text* .rodata) + + + *(.fast_text_sram*) + . = ALIGN(4); + __fast_sram_text_exec_end__ = .; + } > FRAMX + + __fast_sram_text_data_end_flash__ = __fast_sram_text_data_start_flash__ + SIZEOF(.fast_text_sram); + __fast_sram_text_data_start__ = RAMX_TO_RAM(__fast_sram_text_exec_start__); + __fast_sram_text_data_end__ = RAMX_TO_RAM(__fast_sram_text_exec_end__); + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + __cp_text_sram_start_flash__ = __fast_sram_text_data_end_flash__; + + .cp_text_sram (ORIGIN(RAMCPX)) : AT (__cp_text_sram_start_flash__) + { + __cp_text_sram_exec_start__ = .; + *(.cp_text_sram*) + . = ALIGN(4); + __cp_text_sram_exec_end__ = .; + } > RAMCPX + + __cp_text_sram_start = RAMX_TO_RAM(__cp_text_sram_exec_start__); + __cp_text_sram_end = RAMX_TO_RAM(__cp_text_sram_exec_end__); + + .vector_table_cp (ORIGIN(RAMCP)) (NOLOAD) : + { + KEEP(*(.vector_table_cp)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAMCP + + __cp_data_sram_start_flash__ = __cp_text_sram_start_flash__ + SIZEOF(.cp_text_sram); + + .cp_data_sram (.) : AT (__cp_data_sram_start_flash__) + { + __cp_data_sram_start = .; + *(.cp_data*) + . = ALIGN(4); + __cp_data_sram_end = .; + } > RAMCP + + __cp_sram_end_flash__ = __cp_data_sram_start_flash__ + SIZEOF(.cp_data_sram); + + .cp_bss_sram (.) (NOLOAD) : + { + __cp_bss_sram_start = .; + *(.cp_bss*) + . = ALIGN(4); + __cp_bss_sram_end = .; + } > RAMCP + + __overlay_text_start_flash__ = __cp_sram_end_flash__; +#else + __overlay_text_start_flash__ = __fast_sram_text_data_end_flash__; +#endif + +#ifdef OVERLAY_FOR_CP + __overlay_text_start__ = __cp_text_sram_end; +#else + __overlay_text_start__ = __fast_sram_text_data_end__; +#endif + __overlay_text_exec_start__ = RAM_TO_RAMX(__overlay_text_start__); + + OVERLAY (__overlay_text_exec_start__) : NOCROSSREFS AT (__overlay_text_start_flash__) + { +#ifndef NO_OVERLAY + .overlay_text0 + { + LONG(0); + +#if !defined(GLOBAL_SRAM_KISS_FFT) + *:kiss_fft.o(.text*) + *:kiss_fftr.o(.text*) + *:fftwrap.o(.text*) +#endif + +#if !defined(GLOBAL_SRAM_CMSIS_FFT) + *:cmsis_fftwrap.o(.text*) + *:arm_rfft_fast_f32.o(.text*) + *:arm_cfft_f32.o(.text*) +#endif + +#if defined(SCO_OPTIMIZE_FOR_RAM) + *:arm_biquad_cascade_df1_f32.o(.text* .rodata*) + *:integer_delay.o(.text* .rodata*) + *:lc_mmse_ns_float.o(.text.speech_ns2float_process .rodata*) + *:coherence.o(.text* .rodata*) + *:echo_suppression.o(.text.float_cmp .rodata*) + *:echo_suppression.o(.text.es_process .rodata*) + *:lcmmse.o(.text.lcmmse_noise_estimate .rodata*) + *:lcmmse.o(.text.lcmmse_get_speech_prob .rodata*) + *:logmmse.o(.text.filterbank_compute_bank_pflt .rodata*) + *:logmmse.o(.text.filterbank_compute_psd_pflt .rodata*) + *:logmmse.o(.text.logmmse_analysis .rodata*) + *:logmmse.o(.text.logmmse_process .rodata*) +#else + /* common */ + *:ae_common.o(.text* .rodata*) + *:ae_rand.o(.text* .rodata*) + *:fastmath.o(.text* .rodata*) + *:integer_delay.o(.text* .rodata*) + *:iirfilt.o(.text* .rodata*) + *:ringbuf.o(.text* .rodata*) + *:scale_int16.o(.text* .rodata*) + *:speech_conv.o(.text* .rodata*) + *:speech_trans_buf.o(.text* .rodata*) + + *:preprocess.o(.text* .rodata*) + *:filterbank.o(.text* .rodata*) + *:mdf.o(.text* .rodata*) + *:plc_8000.o(.text* .rodata*) +#if defined(HFP_1_6_ENABLE) + *:dspfns.o(.text* .rodata*) + *:lpc_plc.o(.text* .rodata*) + *:plc_16000.o(.text* .rodata*) +#endif +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.text* .rodata*) +#endif +#if defined(SPEECH_TX_2MIC_NS) + *:webrtc_vad.o(.text.WebRtcVad_Process) + *:webrtc_vad.o(.text.WebRtcVad_ValidRateAndFrameLength) + *:webrtc_vad.o(.text.WebRtcVad_CalcVad16khz) + *:webrtc_vad.o(.text.WebRtcVad_Downsampling) + *:webrtc_vad.o(.text.WebRtcVad_CalcVad8khz) + *:vad_filterbank.o(.text.*) + *:energy.o(.text.*) + *:get_scaling_square.o(.text.*) + *:dual_mic_denoise.o(.text*) + *:cross_correlation.o(.text*) + *:min_max_operations.o(.text*) + *:resample_by_2_internal.o(.text*) + *:division_operations.o(.text*) + *:downsample_fast.o(.text*) + *:resample_fractional.o(.text*) + *:resample_48khz.o(.text*) + *:vad_sp.o(.text*) + *:vad_core.o(.text*) + *:webrtc_vad.o(.text*) + *:vad_gmm.o(.text*) +#endif +#if defined(SPEECH_TX_2MIC_NS2) + *:speech_2mic_ns2_denoise.o(.text*) +#endif +#if defined(SPEECH_TX_2MIC_NS5) + *:leftright_denoise.o(.text*) +#endif +#if defined(SPEECH_TX_NS2) || defined(SPEECH_RX_NS2) + *:lc_mmse_ns.o(.text* .rodata*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) || defined(SPEECH_RX_NS2FLOAT) + *:lc_mmse_ns_float.o(.text* .rodata*) +#endif +#if defined(SPEECH_TX_NS3) || defined(SPEECH_RX_NS3) + *:ns3.o(.text* .rodata*) + *:noise_suppression_x.o(.text* .rodata*) + *:nsx_core.o(.text* .rodata*) + *:nsx_core_c.o(.text* .rodata*) + *:copy_set_operations.o(.text* .rodata*) + *:cross_correlation.o(.text* .rodata*) + *:division_operations.o(.text* .rodata*) + *:dot_product_with_scale.o(.text* .rodata*) + *:downsample_fast.o(.text* .rodata*) + *:energy.o(.text* .rodata*) + *:get_scaling_square.o(.text* .rodata*) + *:min_max_operations.o(.text* .rodata*) + *:real_fft.o(.text* .rodata*) + *:resample_by_2.o(.text* .rodata*) + *:resample_by_2_internal.o(.text* .rodata*) + *:spl_init.o(.text* .rodata*) + *:spl_sqrt.o(.text* .rodata*) + *:spl_sqrt_floor.o(.text* .rodata*) + *:vector_scaling_operations.o(.text* .rodata*) +#endif +#if defined(SPEECH_TX_AEC2FLOAT) + *:coherence.o(.text* .rodata*) + *:echo_canceller.o(.text* .rodata*) + *:echo_suppression.o(.text* .rodata*) + *:lcmmse.o(.text* .rodata*) + *:logmmse.o(.text* .rodata*) + *:mdf2.o(.text* .rodata*) + *:noise_generator.o(.text* .rodata*) + *:pink_noise_gen.o(.text* .rodata*) + *:white_noise_gen.o(.text* .rodata*) +#endif +#if defined(SPEECH_TX_3MIC_NS) + *:speech_3mic_ns.o(.text* .rodata*) +#endif +#if defined(MSBC_8K_SAMPLE_RATE) + *:iir_resample.o(.text* .rodata*) +#endif +#if defined(SPEECH_TX_COMPEXP) + *:compexp.o(.text* .rodata*) +#endif +#if defined(SPEECH_TX_EQ) || defined(SPEECH_RX_EQ) || defined(MSBC_8K_SAMPLE_RATE) + *:speech_eq.o(.text* .rodata*) + *:speech_arm_eq.o(.text* .rodata*) + *:arm_biquad_cascade_df1_f32.o(.text* .rodata*) +#endif +#if defined(SPEECH_TX_POST_GAIN) || defined(SPEECH_RX_POST_GAIN) + *:speech_gain.o(.text* .rodata*) +#endif +#if defined(__SMARTVOICE__) +#if defined(SPEECH_TX_2MIC_NS2) || defined(SPEECH_TX_NS2) + *:app_smartvoice.o(.text._Z23mic_data_process_deinitv) + *:app_smartvoice.o(.text._Z21mic_data_process_initv) + *:app_smartvoice.o(.text._Z20mic_data_process_runPsm) +#endif +#endif + +#endif // #if !defined(SCO_OPTIMIZE_FOR_RAM) + *(.overlay_text0) + . = ALIGN(4); + } + .overlay_text1 + { + LONG(0); +#if !defined(RB_CODEC) +#if !defined(HFP_1_6_ENABLE) + *:sbc.o(.text* .rodata*) + *:sbc_math.o(.text* .rodata*) +#endif + *:fixedpoint.o(.text* .rodata*) + *:replaygain.o(.text* .rodata*) + *:dsp_core.o(.text* .rodata*) + *:dsp_misc.o(.text* .rodata*) + *:dsp_filter.o(.text* .rodata*) + *:dsp_sample_input.o(.text* .rodata*) + *:dsp_sample_output.o(.text* .rodata*) + *:eq.o(.text* .rodata*) + *:pga.o(.text* .rodata*) +#if !defined(A2DP_AAC_ON) && !defined(A2DP_LHDC_ON) + *:fir_process.o(.text* .rodata*) + *:iir_process.o(.text.iir_run .text.*iir_run_per_* .rodata*) +#endif +#endif + *(.overlay_a2dp_sbc*) + *(.overlay_text1) + . = ALIGN(4); + } + .overlay_text2 + { + LONG(0); + *:fmdec.o(.text* .data* .rodata* .bss*) + *(.overlay_text2) + . = ALIGN(4); + } + .overlay_text3 + { + LONG(0); + *:fft128dot.o(.text*) + *(.overlay_text3) + . = ALIGN(4); + } + .overlay_text4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:block.o(.text.*CBlock_GetEscape* .rodata*) + *:tpdec_lib.o(.text.*transportDec_GetBitstream* .rodata*) + *:tpdec_lib.o(.text.*transportDec_GetAuBitsRemaining* .rodata*) + *:tpdec_latm.o(.text.*CLatmDemux_GetValue* .rodata*) + *:tpdec_latm.o(.text.*CLatmDemux_Read* .rodata*) + *:tpdec_lib.o(.text.*transportDec_FillData* .rodata*) + *:tpdec_lib.o(.text.*transportDec_ReadAccessUnit* .rodata*) + *:tpdec_lib.o(.text.*transportDec_readHeader* .rodata*) + *:block.o(.text.*ApplyTools* .rodata*) + *:aacdec_pns.o(.text.*CPns_Apply* .rodata*) + *:aacdec_tns.o(.text.*CTns_Apply* .rodata*) + *:aacdec_tns.o(.text.*CTns_Reset* .rodata*) + *:aacdec_pns.o(.text.*CPns_ResetData* .rodata*) + *:pulsedata.o(.text.*CPulseData_Read* .rodata*) +#if !defined(AAC_TEXT_PARTIAL_IN_FLASH) + *:channel.o(.text.*CChannelElement_Read* .rodata*) + *:tpdec_asc.o(.text.*CProgramConfig_Reset* .rodata*) + *:tpdec_lib.o(.text.*transportDec_CrcCheck* .rodata*) + *:block.o(.text.*CBlock_FrequencyToTime* .rodata*) + *:block.o(.text.*CBlock_ReadSectionData* .rodata*) + *:channel.o(.text.*CChannelElement_Decode* .rodata*) + *:tpdec_lib.o(.text.*transportDec_CrcEndReg* .rodata*) + *:aacdecoder.o(.text.*CAacDecoder_DecodeFrame* .rodata*) +#endif + +#if !defined(__SBC_FUNC_IN_ROM_VBEST2000__) && !defined(AAC_TEXT_PARTIAL_IN_FLASH) + *:block.o(.text.*CBlock_ReadSpectralData* .rodata*) + *:block.o(.text.*CBlock_ScaleSpectralData* .rodata*) + *:aacdec_tns.o(.text.*CTns_ReadDataPresentFlag* .rodata*) + *:tpdec_lib.o(.text.*transportDec_CrcStartReg* .rodata*) + *:block.o(.text.*CBlock_ReadScaleFactorData* .rodata*) + *:tpdec_lib.o(.text.*transportDec_EndAccessUnit* .rodata*) + *:tpdec_latm.o(.text.*CLatmDemux_GetNrOfSubFrames* .rodata*) + *:tpdec_lib.o(.text.*transportDec_GetAuBitsTotal* .rodata*) + *:tpdec_asc.o(.text.*CProgramConfig_LookupElement* .rodata*) + *:tpdec_latm.o(.text.*CLatmDemux_GetFrameLengthInBits* .rodata*) + *:tpdec_latm.o(.text.*CLatmDemux_ReadPayloadLengthInfo* .rodata*) + *:block.o(.text.*CBlock_InverseQuantizeSpectralData* .rodata*) + *:channelinfo.o(.text.*IcsRead* .rodata*) + *:aacdec_tns.o(.text.*CTns_Read* .rodata*) + *:tpdec_lib.o(.text.*transportDec_AdjustEndOfAccessUnit* .rodata*) + *:pulsedata.o(.text.*CPulseData_Apply* .rodata*) + *:tpdec_asc.o(.text.*AudioSpecificConfig_Init* .rodata*) + *:tpdec_asc.o(.text.*AudioSpecificConfig_Parse* .rodata*) + *:tpdec_latm.o(.text.*CLatmDemux_ReadStreamMuxConfig* .rodata*) + *:tpdec_asc.o(.text.*getSampleRate* .rodata*) + *:tpdec_asc.o(.text.*getAOT* .rodata*) + *:aacdecoder.o(.text.*CAacDecoder_Init* .rodata*) + *:tpdec_asc.o(.text.*CProgramConfig_Init* .rodata*) + *:aacdecoder_lib.o(.text.*aacDecoder_ConfigCallback* .rodata*) + *:aacdecoder.o(.text.*CAacDecoder_ExtPayloadParse* .rodata*) + *:stereo.o(.text.*CJointStereo_Read* .rodata*) +#endif +#endif + *(.overlay_a2dp_aac*) + *(.overlay_text4) + . = ALIGN(4); + } + .overlay_text5 + { + LONG(0); + *:mpa.o(.text*) + *:bit.o(.text*) + *:frame.o(.text*) + *:huffman.o(.text*) + *:layer12.o(.text*) + *:layer3.o(.text*) + *:stream.o(.text*) + *:synth.o(.text*) + *(.overlay_text5) + . = ALIGN(4); + } + .overlay_text6 + { + LONG(0); +#if defined(A2DP_SCALABLE_ON) + *:Audio_asm.o(.text*) + *:vq.o(.text*) + *:util.o(.text*) + *:rate.o(.text*) + *:quant_bands.o(.text*) + *:modes.o(.text*) + *:mathops.o(.text*) + *:laplace.o(.text*) + *:entdec.o(.text*) + *:entcode.o(.text*) + *:cwrs.o(.text*) + *:audio_int32.o(.text*) + *:audio_decoder.o(.text*) + *:audio.o(.text*) + *(.overlay_a2dp_ssc*) +#endif + +#if defined(A2DP_LHDC_ON) + *:lhdcUtil.o(.text*) + *:dec.o(.text*) + *:cirbuf.o(.text*) + *(.overlay_a2dp_lhdc*) +#endif +#if defined(A2DP_LDAC_ON) + *:ldacBT_api.o(.text*) + *:decode_ldac.o(.text*) + *:dequant_ldac.o(.text*) + *:imdct_ldac.o(.text*) + *:ldacBT_internal.o(.text*) + *:ldaclib_api.o(.text*) + *:memory_ldac.o(.text*) + *:setpcm_ldac.o(.text*) + *:sigana_ldac.o(.text*) + *:tables_ldac.o(.text*) + *:tables_sigproc_ldac.o(.text*) + *:unpack_ldac.o(.text*) + *(.overlay_a2dp_ldac*) +#endif + + *(.overlay_text6) + . = ALIGN(4); + } + .overlay_text7 + { + LONG(0); + *(.overlay_text7) + . = ALIGN(4); + } +#endif + .overlay_text_last + { + LONG(0); + . = ALIGN(4); + } + } > REGION_OVERLAY_TEXT + + .dummy_overlay_text_end (.) (NOLOAD) : + { + __overlay_text_exec_end__ = .; + } > REGION_OVERLAY_TEXT + +#ifdef OVERLAY_FOR_CP + __fast_sram_end__ = __fast_sram_text_data_end__; +#else + __fast_sram_end__ = RAMX_TO_RAM(__overlay_text_exec_end__); +#endif + + ASSERT(__fast_sram_end__ - __fast_sram_text_data_start__ <= FAST_XRAM_SECTION_SIZE, "fast xram sections too large") + __free_fram = FAST_XRAM_SECTION_SIZE - (__fast_sram_end__ - __fast_sram_text_data_start__); + +#ifdef OVERLAY_FOR_CP + __overlay_data_start__ = __cp_bss_sram_end; +#else + __overlay_data_start__ = __sram_bss_end__; +#endif + + OVERLAY (__overlay_data_start__) : NOCROSSREFS AT (__load_stop_overlay_text_last) + { +#ifndef NO_OVERLAY + .overlay_data0 + { + /* Explicitly place 4 bytes at section start to avoid "section type changed to PROGBITS" warnings */ + LONG(0); +#if !defined(SCO_OPTIMIZE_FOR_RAM) + +#if !defined(GLOBAL_SRAM_KISS_FFT) + *:fftwrap.o(.data* .rodata*) + *:kiss_fft.o(.data* .rodata*) + *:kiss_fftr.o(.data* .rodata*) +#endif + +#if !defined(GLOBAL_SRAM_CMSIS_FFT) + *:arm_common_tables.o(.rodata.armBitRevIndexTable256) + *:arm_common_tables.o(.rodata.twiddleCoef_256) + *:arm_common_tables.o(.rodata.twiddleCoef_rfft_512) + *:arm_common_tables.o(.rodata.armBitRevIndexTable128) + *:arm_common_tables.o(.rodata.twiddleCoef_128) + *:arm_common_tables.o(.rodata.twiddleCoef_rfft_256) +#endif + + /* common */ + *:fastmath_const.o(.data* .rodata*) + + *:preprocess.o(.data* .rodata*) + *:filterbank.o(.data* .rodata*) + *:mdf.o(.data* .rodata*) + *:plc_8000.o(.data* .rodata*) +#if defined(HFP_1_6_ENABLE) + *:table.o(.data* .rodata*) + *:plc_16000.o(.data* .rodata*) +#endif +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.data* .rodata* .bss*) +#endif +#if defined(SPEECH_TX_2MIC_NS) + *:dual_mic_denoise.o(.data* .rodata*) + *:vad_filterbank.o(.data* .rodata*) + *:energy.o(.data* .rodata*) + *:get_scaling_square.o(.data* .rodata*) + + *:cross_correlation.o(.data* .rodata*) + *:min_max_operations.o(.data* .rodata*) + *:resample_by_2_internal.o(.data* .rodata*) + *:division_operations.o(.data* .rodata*) + *:downsample_fast.o(.data* .rodata*) + *:resample_fractional.o(.data* .rodata*) + *:resample_48khz.o(.data* .rodata*) + *:vad_sp.o(.data* .rodata*) + *:vad_core.o(.data* .rodata*) + *:webrtc_vad.o(.data* .rodata*) + *:vad_gmm.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_2MIC_NS2) + *:speech_2mic_ns2_denoise.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_2MIC_NS5) + *:leftright_denoise.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS2) || defined(SPEECH_RX_NS2) + *:lc_mmse_ns.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS3) || defined(SPEECH_RX_NS3) + *:nsx_core.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) || defined(SPEECH_RX_NS2FLOAT) + *:lc_mmse_ns_float.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_3MIC_NS) + *:speech_3mic_ns.o(.data* .rodata*) +#endif +#if defined(MSBC_8K_SAMPLE_RATE) + *:iir_resample.o(.data* .rodata*) +#endif + +#endif // #if !defined(SCO_OPTIMIZE_FOR_RAM) + *(.overlay_data0 .overlay_rodata0) + . = ALIGN(4); + } + .overlay_data1 + { + LONG(0); +#if !defined(RB_CODEC) +#if !defined(HFP_1_6_ENABLE) + *:sbc.o(.data* .rodata*) + *:sbc_math.o(.data* .rodata*) +#endif + *:fixedpoint.o(.data* .rodata*) + *:replaygain.o(.data* .rodata*) + *:dsp_core.o(.data* .rodata*) + *:dsp_misc.o(.data* .rodata*) + *:dsp_filter.o(.data* .rodata*) + *:dsp_sample_input.o(.data* .rodata*) + *:dsp_sample_output.o(.data* .rodata*) + *:eq.o(.data* .rodata*) + *:pga.o(.data* .rodata*) +#if !defined(A2DP_AAC_ON) + *:fir_process.o(.data* .rodata*) +#endif +#endif + *(.overlay_data1 .overlay_rodata1) + . = ALIGN(4); + } + .overlay_data2 + { + LONG(0); + *(.overlay_data2 .overlay_rodata2) + . = ALIGN(4); + } + .overlay_data3 + { + LONG(0); + *:fft128dot.o(.data* .rodata*) + *(.overlay_data3 .overlay_rodata3) + . = ALIGN(4); + } + .overlay_data4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:block.o(.data* .rodata*) + *:tpdec_lib.o(.data* .rodata*) + *:tpdec_latm.o(.data* .rodata*) + *:aacdec_pns.o(.data* .rodata*) + *:aacdec_tns.o(.data* .rodata*) + *:pulsedata.o(.data* .rodata*) + *:channel.o(.data* .rodata*) + *:tpdec_asc.o(.data* .rodata*) + *:aacdecoder.o(.data* .rodata*) + *:channelinfo.o(.data* .rodata*) + *:aacdecoder_lib.o(.data* .rodata*) + *:stereo.o(.data* .rodata*) +#endif + *(.overlay_data4 .overlay_rodata4) + . = ALIGN(4); + } + .overlay_data5 + { + LONG(0); + *:mpa.o(.data* .bss*) + *:bit.o(.data* .bss*) + *:frame.o(.data* .bss*) + *:huffman.o(.data* .bss*) + *:layer12.o(.data* .bss*) + *:layer3.o(.data* .bss*) + *:stream.o(.data* .bss*) + *:synth.o(.data* .bss*) + *(.overlay_data5 .overlay_rodata5) + . = ALIGN(4); + } + .overlay_data6 + { + LONG(0); +#if defined(A2DP_SCALABLE_ON) + *(.constdata) + *:Audio_asm.o(.data* .rodata*) + *:vq.o(.data* .rodata*) + *:util.o(.data* .rodata*) + *:rate.o(.data* .rodata*) + *:quant_bands.o(.data* .rodata*) + *:modes.o(.data* .rodata*) + *:mathops.o(.data* .rodata*) + *:laplace.o(.data* .rodata*) + *:entdec.o(.data* .rodata*) + *:entcode.o(.data* .rodata*) + *:cwrs.o(.data* .rodata*) + *:audio_int32.o(.data* .rodata*) + *:audio_decoder.o(.data* .rodata*) + *:audio.o(.data* .rodata*) +#endif +#if defined(A2DP_LHDC_ON) + *:lhdcUtil.o(.data* .rodata*) + *:dec.o(.data* .rodata*) + *:cirbuf.o(.data* .rodata*) +#endif +#if defined(A2DP_LDAC_ON) + *:ldacBT_api.o(.data* .rodata*) + *:decode_ldac.o(.data* .rodata*) + *:dequant_ldac.o(.data* .rodata*) + *:imdct_ldac.o(.data* .rodata*) + *:ldacBT_internal.o(.data* .rodata*) + *:ldaclib_api.o(.data* .rodata*) + *:memory_ldac.o(.data* .rodata*) + *:setpcm_ldac.o(.data* .rodata*) + *:sigana_ldac.o(.data* .rodata*) + *:tables_ldac.o(.data* .rodata*) + *:tables_sigproc_ldac.o(.data* .rodata*) + *:unpack_ldac.o(.data* .rodata*) +#endif + *(.overlay_data6 .overlay_rodata6) + . = ALIGN(4); + } + .overlay_data7 + { + LONG(0); + *(.overlay_data7 .overlay_rodata7) + . = ALIGN(4); + } +#endif + .overlay_data_last + { + LONG(0); + . = ALIGN(4); + } + } > REGION_OVERLAY_DATA + + .dummy_overlay_data_end (.) (NOLOAD) : + { + __overlay_data_end__ = .; + } > REGION_OVERLAY_DATA + + ASSERT(__overlay_data_end__ - __overlay_data_start__ <= OVERLAY_DATA_SECTION_SIZE, "overlay sections too large") + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + .cp_ramx_last_dummy (NOLOAD) : + { + __cp_ramx_last_dummy_start = .; + } > RAMCPX + + .cp_ram_last_dummy (NOLOAD) : + { + . = ALIGN(8); + __cp_ram_last_dummy_start = .; + } > RAMCP + + __cp_stack_top = ORIGIN(RAMCP) + LENGTH(RAMCP); + __cp_stack_limit = __cp_stack_top - CP_STACK_SECTION_SIZE; + + __free_ramcpx = ORIGIN(RAMCPX) + LENGTH(RAMCPX) - __cp_ramx_last_dummy_start; + ASSERT(__cp_stack_limit >= __cp_ram_last_dummy_start, "region RAMCP overflowed with stack") + __free_ramcp = __cp_stack_limit - __cp_ram_last_dummy_start; +#endif + + .text (FLASH_TO_FLASHX(__load_stop_overlay_data_last)) : AT (FLASHX_TO_FLASH(ADDR(.text))) + { + *(.text*) + *(.flash_text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + } > FLASHX + + .ARM.extab (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.extab))) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASHX + + __exidx_start = .; + /* .ARM.exidx contains R_ARM_PREL31 (+-0x40000000) offset to functions, which means + * the session location cannot be too far away from the function addresses */ + .ARM.exidx (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.exidx))) + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASHX + __exidx_end = .; + + . = FLASHX_TO_FLASH(.); + + .rodata (.) : + { + *(.rodata*) + *(.flash_rodata*) + KEEP(*(.eh_frame*)) + *(.note.gnu.build-id) + } > FLASH + +#ifdef TRACE_STR_SECTION + .trc_str (.) : + { + *(.trc_str*) + } > FLASH +#endif + + .ai.gatt.server.table (.) : + { + . = ALIGN(4); + __ai_gatt_server_table_start = .; + KEEP(*(.ai_gatt_server_table)) + __ai_gatt_server_table_end = .; + } > FLASH + + .ai.ble.handler.table (.) : + { + . = ALIGN(4); + __ai_ble_handler_table_start = .; + KEEP(*(.ai_ble_handler_table)) + __ai_ble_handler_table_end = .; + } > FLASH + + .ai.spp.register.table (.) : + { + . = ALIGN(4); + __ai_spp_register_table_start = .; + KEEP(*(.ai_spp_register_table)) + __ai_spp_register_table_end = .; + } > FLASH + + .tota.cmd.table (.) : + { + . = ALIGN(4); + __tota_handler_table_start = .; + KEEP(*(.tota_handler_table)) + __tota_handler_table_end = .; + } > FLASH + + .ai.handler.function.table (.) : + { + . = ALIGN(4); + __ai_handler_function_table_start = .; + KEEP(*(.ai_handler_function_table)) + __ai_handler_function_table_end = .; + } > FLASH + + .custom.cmd.table (.) : + { + . = ALIGN(4); + __custom_handler_table_start = .; + KEEP(*(.custom_handler_table)) + __custom_handler_table_end = .; + } > FLASH + + .thirdparty.event.table (.) : + { + . = ALIGN(4); + __thirdparty_handler_table_start = .; + KEEP(*(.thirdparty_handler_table)) + __thirdparty_handler_table_end = .; + } > FLASH + +#if defined(FIRMWARE_REV) + .firmware_rev (.) : + { + . = ALIGN(64); + *(.fw_rev) + } > FLASH +#endif + + /* To copy multiple FLASH to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table (.) : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table (.) : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + /* Location counter can end up 2byte aligned with narrow Thumb code but + __etext is assumed by startup code to be the LMA of a section in RAM + which must be 4byte aligned */ + __etext = ALIGN(4); + + /* The VMA is either the end of overlay_data or the end of sram bss */ + + .data : AT (__etext) + { + __data_start__ = .; + + *(vtable) + . = ALIGN(4); + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + + /* All data end */ + . = ALIGN(4); + __data_end__ = .; + + } > RAM + + .bss (.) (NOLOAD) : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (.) (NOLOAD) : + { + . = ALIGN(8); + __HeapBase = .; + __end__ = .; + end = __end__; + . += HEAP_SECTION_SIZE; + . = ALIGN(8); + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (.) (COPY) : + { + . = STACK_SECTION_SIZE; + . = ALIGN(8); + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ +#if defined(ROM_UTILS_ON) + __StackTop = ORIGIN(RAM) + LENGTH(RAM) - ROM_UTILS_RESV_RAM_SIZE; +#else + __StackTop = ORIGIN(RAM) + LENGTH(RAM); +#endif + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + __free_ram = __StackLimit - __HeapLimit; + + . = __etext + SIZEOF(.data); + + .system_info (.) : + { + KEEP(*(.system_info_list_size)) + KEEP(*(.system_info_list)) + . = ALIGN(4); + } > FLASH + + .build_info (.) : + { + KEEP(*(.build_info)) + . = ALIGN(4); + } > FLASH = 0x00000000 + +#ifdef SLAVE_BIN_FLASH_OFFSET + .slave_code (ORIGIN(FLASH) + SLAVE_BIN_FLASH_OFFSET): + { + KEEP(*(.slave_code_flash_rodata)) + } > FLASH +#endif + + /* The following section MUST be the last loaded section */ + .code_start_addr (.) : + { + LONG(BUILD_INFO_MAGIC); + LONG(ABSOLUTE(__flash_start)); + } > FLASH + + __flash_end = .; + + .coredump_section (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + CRASH_DUMP_SECTION_SIZE - LOG_DUMP_SECTION_SIZE - OTA_UPGRADE_LOG_SIZE - CORE_DUMP_SECTION_SIZE) (NOLOAD) : + { + __coredump_section_start = .; + . = CORE_DUMP_SECTION_SIZE; + __coredump_section_end = .; + } > FLASH_NC + + .ota_upgrade_log (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + CRASH_DUMP_SECTION_SIZE - LOG_DUMP_SECTION_SIZE - OTA_UPGRADE_LOG_SIZE) (NOLOAD) : + { + __ota_upgrade_log_start = .; + . = OTA_UPGRADE_LOG_SIZE; + __ota_upgrade_log_end = .; + } > FLASH_NC + + .log_dump (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + CRASH_DUMP_SECTION_SIZE - LOG_DUMP_SECTION_SIZE) (NOLOAD) : + { + __log_dump_start = .; + . = LOG_DUMP_SECTION_SIZE; + __log_dump_end = .; + } > FLASH_NC + + .crash_dump (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + CRASH_DUMP_SECTION_SIZE) (NOLOAD) : + { + __crash_dump_start = .; + . = CRASH_DUMP_SECTION_SIZE; + __crash_dump_end = .; + } > FLASH_NC + + .custom_parameter (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE) (NOLOAD) : + { + __custom_parameter_start = .; + . = CUSTOM_PARAMETER_SECTION_SIZE; + __custom_parameter_end = .; + } > FLASH_NC + + .userdata (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2) (NOLOAD) : + { + __userdata_start = .; + . = USERDATA_SECTION_SIZE*2; + __userdata_end = .; + } > FLASH_NC + + .audio (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE) (NOLOAD) : + { + __aud_start = .; + . = AUD_SECTION_SIZE; + __aud_end = .; + } > FLASH_NC + + .reserved (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE) (NOLOAD) : + { + __reserved_start = .; + . = RESERVED_SECTION_SIZE; + __reserved_end = .; + } > FLASH_NC + + .factory (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE) (NOLOAD) : + { + __factory_start = .; + . = FACTORY_SECTION_SIZE; + __factory_end = .; + } > FLASH_NC + +#ifdef OTA_BOOT_SIZE +#if (OTA_BOOT_SIZE > FLASH_SIZE) +#error "OTA_BOOT_SIZE should <= FLASH_SIZE" +#endif +#if defined(OTA_CODE_OFFSET) && (OTA_BOOT_SIZE > OTA_CODE_OFFSET) +#error "OTA_BOOT_SIZE should <= OTA_CODE_OFFSET" +#endif + __tail_section_start = FLASH_BASE + OTA_BOOT_SIZE; +#else + __tail_section_start = __ota_upgrade_log_start; +#endif + + ASSERT(FLASH_NC_TO_C(__tail_section_start) >= __flash_end, "region FLASH overflowed") + __free_flash = FLASH_NC_TO_C(__tail_section_start) - __flash_end; + +#if !defined(OTA_BOOT_SIZE) && defined(OTA_REMAP_OFFSET) + ASSERT((FLASH_BASE & 0x03FFFFFF) == 0, "bad FLASH_BASE") + ASSERT((FLASH_SIZE & (FLASH_SIZE - 1)) == 0, "bad FLASH_SIZE") +#ifdef CHIP_BEST2300P + ASSERT(__flash_end <= FLASH_BASE + OTA_REMAP_OFFSET, "flash code size too large to remap") + ASSERT(__flash_start - FLASH_BASE >= FLASH_NC_BASE + FLASH_SIZE - __tail_section_start, "flash code conflicted with tail sections in remap") + ASSERT(__flash_start - FLASH_BASE >= FLASH_SIZE / (1 << (4 + 1)), "flash code cannot remap within 4 regions (max code size is half of flash size)") + ASSERT((__flash_start - FLASH_BASE) % (FLASH_SIZE / (1 << (4 + 1))) == 0, "flash code start address not aligned with remap region boundary") +#else + ASSERT(((OTA_REMAP_OFFSET) & (0x1000 - 1)) == 0, "OTA_REMAP_OFFSET not aligned with 4K sector boundary") + ASSERT(__flash_end <= FLASH_BASE + (OTA_REMAP_OFFSET), "flash code size too large to remap") + ASSERT((__tail_section_start & (0x1000 - 1)) == 0, "__tail_section_start not aligned with 4K sector boundary") + ASSERT(__flash_end + (OTA_REMAP_OFFSET) <= __tail_section_start, "flash code conflicted with tail sections in remap") +#endif +#endif +} + diff --git a/scripts/link/best2000_bisto.lds.S b/scripts/link/best2000_bisto.lds.S new file mode 100644 index 0000000..0310f79 --- /dev/null +++ b/scripts/link/best2000_bisto.lds.S @@ -0,0 +1,1096 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#ifdef RB_CODEC +#define HEAP_SECTION_SIZE 0x1000 +#else +#define HEAP_SECTION_SIZE 0x1000 +#endif + +#define STACK_SECTION_SIZE 0xD00 + +#ifdef RB_CODEC +#define OVERLAY_DATA_SECTION_SIZE 0xA000 +#else +#define OVERLAY_DATA_SECTION_SIZE 0x8000 +#endif + +#if (RAM_SIZE >= 0x48000) +#if defined(CHIP_BEST2000) +#if defined(BTUSB_AUDIO_MODE) +#define FAST_XRAM_SECTION_SIZE 0xC200 +#else +#define FAST_XRAM_SECTION_SIZE 0xC200 +#endif +#else +#if defined(BTUSB_AUDIO_MODE) +#define FAST_XRAM_SECTION_SIZE 0x1A000 +#else +#define FAST_XRAM_SECTION_SIZE 0x16000 +#endif +#endif +#else +#define FAST_XRAM_SECTION_SIZE 0x8000 +#endif + +#ifndef OTA_CODE_OFFSET +#define OTA_CODE_OFFSET 0 +#endif +#define FLASH_REGION_BASE (FLASH_BASE + OTA_CODE_OFFSET) +#ifndef FLASH_REGION_SIZE +#define FLASH_REGION_SIZE (FLASH_SIZE - (FLASH_REGION_BASE - FLASH_BASE)) +#endif +#define FLASH_NC_REGION_BASE FLASH_C_TO_NC(FLASH_REGION_BASE) +#define FLASHX_REGION_BASE FLASH_TO_FLASHX(FLASH_REGION_BASE) + + +/* Linker script to configure memory regions. */ +/* See plat_addr_map.h and common.mk for the macro definitions */ +MEMORY +{ + ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE + FLASH (r) : ORIGIN = FLASH_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASH_NC (r) : ORIGIN = FLASH_NC_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASHX (rx) : ORIGIN = FLASHX_REGION_BASE, LENGTH = FLASH_REGION_SIZE + RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + RAMX (rx) : ORIGIN = RAMX_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + FRAMX (rwx) : ORIGIN = RAMX_BASE + RAM_SIZE - FAST_XRAM_SECTION_SIZE, LENGTH = FAST_XRAM_SECTION_SIZE +#ifdef PSRAM_BASE + PSRAM (rwx) : ORIGIN = PSRAM_BASE, LENGTH = PSRAM_SIZE + PSRAM_NC (rwx) : ORIGIN = PSRAM_NC_BASE, LENGTH = PSRAM_SIZE + PSRAMX (rx) : ORIGIN = PSRAMX_BASE, LENGTH = PSRAM_SIZE +#endif +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __export_fn_rom + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __free_ram + * __factory_start + * __factory_end + * __calib_start + * __calib_end + * __flash_start + * __flash_end + * __free_flash + * __boot_sram_start_flash__ + * __boot_sram_end_flash__ + * __boot_sram_start__ + * __boot_bss_sram_start__ + * __boot_bss_sram_end__ + * __sram_text_data_start_flash__ + * __sram_text_data_end_flash__ + * __fast_sram_text_data_start__ + * __fast_sram_text_data_end__ + * __fast_sram_text_data_start_flash__ + * __fast_sram_text_data_end_flash__ + * __sram_text_data_start__ + * __sram_bss_start__ + * __sram_bss_end__ + * __overlay_text_start__ + * __overlay_text_exec_start__ + * __overlay_data_start__ + */ +ENTRY(Boot_Loader) + +SECTIONS +{ + __export_fn_rom = (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE); + + .boot_struct (ORIGIN(FLASH)) : + { + __flash_start = .; + KEEP(*(.boot_struct)) + . = ALIGN(4); + } > FLASH + + . = FLASH_TO_FLASHX(.); + + .boot_text_flash (.) : AT (FLASHX_TO_FLASH(ADDR(.boot_text_flash))) + { + *(.boot_loader) + *(.boot_text_flash*) + *(.boot_rodata*) + . = ALIGN(4); + } > FLASHX + + . = FLASHX_TO_FLASH(.); + + .got_info (.) : + { + __got_info_start = .; + __got_start = .; + *(.got) + . = ALIGN(4); + __got_end = .; + __got_plt_start = .; + *(.got.plt) + . = ALIGN(4); + __igot_plt_start = .; + *(.igot.plt) + . = ALIGN(4); + __dynamic_start = .; + *(.dynamic) + . = ALIGN(4); + __got_info_end = .; + } > FLASH + + .vector_table (ORIGIN(RAM)) (NOLOAD) : + { + KEEP(*(.vector_table)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .reboot_param (.) (NOLOAD) : + { + KEEP(*(.reboot_param)) + . = REBOOT_PARAM_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .userdata_pool (.) (NOLOAD) : + { + *(.userdata_pool) + . = ALIGN(4); + __userdata_pool_end__ = .; + } > RAM + + __boot_sram_start_flash__ = LOADADDR(.got_info) + SIZEOF(.got_info); + __boot_sram_start__ = __userdata_pool_end__; + .boot_text_sram (RAM_TO_RAMX(__boot_sram_start__)) : AT (__boot_sram_start_flash__) + { + /* memcpy.o or libc_nano.a(lib_a-memcpy.o/lib_a-memcpy-stub.o) */ + *:memcpy.o(.text*) + *:lib_a-memcpy*.o(.text*) + *:libc_rom.o(.text*) + + /* memset.o or libc_nano.a(lib_a-memset.o) */ + *:memset.o(.text*) + *:lib_a-memset*.o(.text*) + + *:hal_norflash*.o(.text*) + *:norflash_*.o(.text*) + + *(.boot_text_sram*) + . = ALIGN(4); + __boot_text_sram_end = .; + } > RAMX + + .boot_data_sram (RAMX_TO_RAM(ADDR(.boot_text_sram) + SIZEOF(.boot_text_sram))) : + AT (__boot_sram_start_flash__ + SIZEOF(.boot_text_sram)) + { + *:hal_norflash*.o(.data* .rodata*) + *:norflash_*.o(.data* .rodata*) + *:hal_psram.o(.data* .rodata*) + *(.boot_data*) + . = ALIGN(4); + __boot_data_sram_end = .; + } > RAM + + __boot_sram_end_flash__ = __boot_sram_start_flash__ + + SIZEOF(.boot_text_sram) + SIZEOF(.boot_data_sram); + + .boot_bss_sram (.) (NOLOAD) : + { + __boot_bss_sram_start__ = .; + *:hal_norflash*.o(.bss*) + *:norflash_*.o(.bss*) + *:hal_psram.o(.bss*) + *(.boot_bss*) + . = ALIGN(4); + __boot_bss_sram_end__ = .; + } > RAM + + __sram_text_data_start_flash__ = __boot_sram_end_flash__; + __sram_text_data_start__ = __boot_bss_sram_end__; + .sram_text (RAM_TO_RAMX(__sram_text_data_start__)) : + AT (__sram_text_data_start_flash__) + { + *(.sram_text*) + . = ALIGN(4); + } > RAMX + + .sram_data (RAMX_TO_RAM(ADDR(.sram_text) + SIZEOF(.sram_text))) : + AT (__sram_text_data_start_flash__ + SIZEOF(.sram_text)) + { +#if defined(BTUSB_AUDIO_MODE) + *:hal_usb.o(.rodata*) +#endif + *:utils.o(.data* .rodata*) + *:cqueue.o(.data* .rodata*) + *:iir_process.o(.data* .rodata*) +#if defined(HFP_1_6_ENABLE) + *:sbcplc.o(.data* .rodata*) + *:sbc.o(.data* .rodata*) + *:sbc_math.o(.data* .rodata*) +#endif +#if defined(A2DP_AAC_ON) + *:fixpoint_math.o(.data* .rodata*) + *:FDK_bitbuffer.o(.data* .rodata*) +#endif + *(.sram_data*) + . = ALIGN(4); + } > RAM + + __sram_text_data_end_flash__ = __sram_text_data_start_flash__ + + SIZEOF(.sram_text) + SIZEOF(.sram_data); + + .sram_bss (.) (NOLOAD) : + { + __sram_bss_start__ = .; + *:utils.o(.bss*) + *(.sram_bss*) + . = ALIGN(4); + __sram_bss_end__ = .; + } > RAM + + __fast_sram_text_data_start_flash__ = __sram_text_data_end_flash__; + .fast_text_sram (ORIGIN(FRAMX)) : AT (__fast_sram_text_data_start_flash__) + { + __fast_sram_text_data_start__ = .; + +#if defined(BTUSB_AUDIO_MODE) + *:hal_dma.o(.text*) + *:hal_uart.o(.text*) + *:hal_trace.o(.text*) +#endif + +#if defined(BTUSB_AUDIO_MODE) + *:hal_usb.o(.text*) + + *:usb_audio.o(.text*) + *:usb_audio_sync.o(.text*) + *:usb_audio_cdc.o(.text*) + + *:usbaudio_entry.o(.text*) + *:usb_audio_app.o(.text*) +#endif + + /* memmove.o or libc_nano.a(lib_a-memmove.o) */ + *:memmove.o(.text*) + *:lib_a-memmove.o(.text*) + *:utils.o(.text*) + *:cqueue.o(.text*) + *:audio_resample_ex.o(.text*) +#if defined(MIX_MIC_DURING_MUSIC) + *:app_bt_stream.o(.text*) +#endif +#if defined(HFP_1_6_ENABLE) +#if defined(__SBC_FUNC_IN_ROM__) + *:sbc.o(.text*) +#else + *:sbc.o(.text.sbc_is_stream_info_valid) + *:sbc.o(.text.sbc_frame_length_get) + *:sbc.o(.text.sbc_4bit_crc_calc) + *:sbc.o(.text.sbc_bits_for_mono_alloc) + *:sbc.o(.text.sbc_bits_for_stereo_alloc) + *:sbc.o(.text.sbc_header_process) + *:sbc.o(.text.sbc_factors_process) + *:sbc.o(.text.sbc_sample_extract) + *:sbc.o(.text.sbc_sbsamples_make) + *:sbc.o(.text.sbc_joint_process) + *:sbc.o(.text.sbc_4band_synth_filter) + *:sbc.o(.text.sbc_8band_synth_filter) + *:sbc.o(.text.sbc_decoder_state_reset) + *:sbc.o(.text.sbc_frame_mute) + *:sbc.o(.text.sbc_frames_decode) + *:sbc.o(.text.sbc_samples_quant) + *:sbc.o(.text.sbc_decoder_init) + *:sbc.o(.text.sbc_encoder_init) + *:sbc.o(.text.sbc_frames_encode) +#endif + *:sbc_math.o(.text*) +#endif +#if defined(A2DP_AAC_ON) + *:fixpoint_math.o(.text*) + *:FDK_bitbuffer.o(.text*) + *:FDK_tools_rom.o(.text*FDKgetWindowSlope*) + *:FDK_tools_rom.o(.text*getBitstreamElementList*) + *:dct.o(.text*dct_IV*) +#if !defined(__SBC_FUNC_IN_ROM_VBEST2000__) + *:fft.o(.text._Z3fftiPlPi) + *:fft_rad2.o(.text*dit_fft*) + *:dct.o(.text*getTables*) +#endif +#ifdef VOICE_DATAPATH + *:opus_encoder.o(.text*) +#endif +#endif + +#if defined(__AUDIO_SPECTRUM__) + *:kiss_fft.o(.text*) + *:kiss_fftr.o(.text*) + *:fftwrap.o(.text*) + *:spectrum_fix.o(.text*) + *:audio_spectrum.o(.text*) +#endif + *:exp_func.o(.data* .rodata*) + *(.fast_text_sram*) + . = ALIGN(4); + __fast_sram_text_data_end__ = .; + } > FRAMX + __fast_sram_text_data_end_flash__ = __fast_sram_text_data_start_flash__ + SIZEOF(.fast_text_sram); + + __overlay_text_start__ = RAMX_TO_RAM(__fast_sram_text_data_end__); + __overlay_text_exec_start__ = RAM_TO_RAMX(__overlay_text_start__); + OVERLAY (__overlay_text_exec_start__) : NOCROSSREFS AT (__fast_sram_text_data_end_flash__) + { +#ifndef NO_OVERLAY + .overlay_text0 + { + LONG(0); + *:preprocess.o(.text*) + *:filterbank.o(.text*) +#if !defined(A2DP_SCALABLE_ON) + *:kiss_fft.o(.text*) +#endif + *:kiss_fftr.o(.text*) + *:fftwrap.o(.text*) + *:mdf.o(.text*) + *:plc_8000.o(.text*) +#if defined(HFP_1_6_ENABLE) + *:plc_16000.o(.text*) +#endif +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.text*) +#endif +#if defined(SPEECH_TX_2MIC_NS) + *:webrtc_vad.o(.text.WebRtcVad_Process) + *:webrtc_vad.o(.text.WebRtcVad_ValidRateAndFrameLength) + *:webrtc_vad.o(.text.WebRtcVad_CalcVad16khz) + *:webrtc_vad.o(.text.WebRtcVad_Downsampling) + *:webrtc_vad.o(.text.WebRtcVad_CalcVad8khz) + *:vad_filterbank.o(.text.*) + *:energy.o(.text.*) + *:get_scaling_square.o(.text.*) + *:dual_mic_denoise.o(.text*) + *:cross_correlation.o(.text*) + *:min_max_operations.o(.text*) + *:resample_by_2_internal.o(.text*) + *:division_operations.o(.text*) + *:downsample_fast.o(.text*) + *:resample_fractional.o(.text*) + *:resample_48khz.o(.text*) + *:vad_sp.o(.text*) + *:vad_core.o(.text*) + *:webrtc_vad.o(.text*) + *:vad_gmm.o(.text*) +#endif +#if defined(SPEECH_TX_2MIC_NS2) + *:speech_2mic_ns2_denoise.o(.text*) +#endif +#if defined(SPEECH_TX_2MIC_NS4) + *:sensormic_denoise.o(.text*) +#endif +#if defined(SPEECH_TX_NS2) + *:lc_mmse_ns.o(.text*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) + *:lc_mmse_ns_float.o(.text*) + *:cmsis_fftwrap.o(.text*) + *:arm_rfft_fast_f32.o(.text*) + *:arm_cfft_f32.o(.text*) +#endif +#if defined(SPEECH_TX_NS3) || defined(SPEECH_RX_NS3) + *:ns3.o(.text*) + *:noise_suppression_x.o(.text*) + *:nsx_core.o(.text*) + *:nsx_core_c.o(.text*) + *:copy_set_operations.o(.text*) + *:cross_correlation.o(.text*) + *:division_operations.o(.text*) + *:dot_product_with_scale.o(.text*) + *:downsample_fast.o(.text*) + *:energy.o(.text*) + *:get_scaling_square.o(.text*) + *:min_max_operations.o(.text*) + *:real_fft.o(.text*) + *:resample_by_2.o(.text*) + *:resample_by_2_internal.o(.text*) + *:spl_init.o(.text*) + *:spl_sqrt.o(.text*) + *:spl_sqrt_floor.o(.text*) + *:vector_scaling_operations.o(.text*) +#endif +#if defined(SPEECH_TX_AEC2FLOAT) + *:coherence.o(.text*) + *:echo_canceller.o(.text*) + *:echo_suppression(.text*) + *:iirfilt.o(.text*) + *:integer_delay.o(.text*) + *:mdf2.o(.text*) + *:ringbuf.o(.text*) +#endif +#if defined(SPEECH_TX_EQ) + *:speech_arm_eq.o(.text*) + *:arm_biquad_cascade_df1_f32.o(.text*) +#endif +#if defined(__SMARTVOICE__) +#if defined(SPEECH_TX_2MIC_NS2) || defined(SPEECH_TX_2MIC_NS4) || defined(SPEECH_TX_NS2) + *:app_smartvoice.o(.text._Z23mic_data_process_deinitv) + *:app_smartvoice.o(.text._Z21mic_data_process_initv) + *:app_smartvoice.o(.text._Z20mic_data_process_runPsm) +#endif +#endif + *(.overlay_text0) + . = ALIGN(4); + } + .overlay_text1 + { + LONG(0); +#if !defined(RB_CODEC) +#if !defined(HFP_1_6_ENABLE) + *:sbc.o(.text*) + *:sbc_math.o(.text*) +#endif + *:fixedpoint.o(.text*) + *:replaygain.o(.text*) + *:dsp_core.o(.text*) + *:dsp_misc.o(.text*) + *:dsp_filter.o(.text*) + *:dsp_sample_input.o(.text*) + *:dsp_sample_output.o(.text*) + *:eq.o(.text*) + *:pga.o(.text*) +#if !defined(A2DP_AAC_ON) && !defined(A2DP_LHDC_ON) + *:fir_process.o(.text*) + *:iir_process.o(.text.iir_run .text.*iir_run_per_*) +#endif +#endif + *(.overlay_a2dp_sbc*) + *(.overlay_text1) + . = ALIGN(4); + } + .overlay_text2 + { + LONG(0); + *:fmdec.o(.text* .data* .rodata* .bss*) + *(.overlay_text2) + . = ALIGN(4); + } + .overlay_text3 + { + LONG(0); + *:fft128dot.o(.text*) + *(.overlay_text3) + . = ALIGN(4); + } + .overlay_text4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:aacdec.o(.text*) + *:aactabs.o(.text*) + *:bitstream.o(.text*) + *:buffers.o(.text*) + *:dct4.o(.text*) + *:decelmnt.o(.text*) + *:dequant.o(.text*) + *:fft.o(.text*) + *:filefmt.o(.text*) + *:huffman.o(.text*) + *:hufftabs.o(.text*) + *:imdct.o(.text*) + *:noiseless.o(.text*) + *:pns.o(.text*) + *:stproc.o(.text*) + *:tns.o(.text*) + *:trigtabs.o(.text*) + *:trigtabs_fltgen.o(.text*) +#endif + *(.overlay_a2dp_aac*) + *(.overlay_text4) + . = ALIGN(4); + } + .overlay_text5 + { + LONG(0); + *:mpa.o(.text*) + *:bit.o(.text*) + *:frame.o(.text*) + *:huffman.o(.text*) + *:layer12.o(.text*) + *:layer3.o(.text*) + *:stream.o(.text*) + *:synth.o(.text*) + *(.overlay_text5) + . = ALIGN(4); + } + .overlay_text6 + { + LONG(0); +#if defined(A2DP_SCALABLE_ON) + *:Audio_asm.o(.text*) + *:vq.o(.text*) + *:util.o(.text*) + *:rate.o(.text*) + *:quant_bands.o(.text*) + *:modes.o(.text*) + *:mathops.o(.text*) + *:laplace.o(.text*) + *:entdec.o(.text*) + *:entcode.o(.text*) + *:cwrs.o(.text*) + *:audio_int32.o(.text*) + *:audio_decoder.o(.text*) + *:audio.o(.text*) + *(.overlay_a2dp_ssc*) +#endif + +#if defined(A2DP_LHDC_ON) + *:lhdcUtil.o(.text*) + *:dec.o(.text*) + *:cirbuf.o(.text*) + *(.overlay_a2dp_lhdc*) +#endif +#if defined(A2DP_LDAC_ON) + *:ldacBT_api.o(.text*) + *:decode_ldac.o(.text*) + *:dequant_ldac.o(.text*) + *:imdct_ldac.o(.text*) + *:ldacBT_internal.o(.text*) + *:ldaclib_api.o(.text*) + *:memory_ldac.o(.text*) + *:setpcm_ldac.o(.text*) + *:sigana_ldac.o(.text*) + *:tables_ldac.o(.text*) + *:tables_sigproc_ldac.o(.text*) + *:unpack_ldac.o(.text*) + *(.overlay_a2dp_ldac*) +#endif + + *(.overlay_text6) + . = ALIGN(4); + } + .overlay_text7 + { + LONG(0); + *(.overlay_text7) + . = ALIGN(4); + } +#endif + .overlay_text_end + { + LONG(0); + . = ALIGN(4); + } + } > FRAMX + + .dummy_overlay_text (.) (NOLOAD) : + { + __dummy_overlay_text_end__ = .; + } > FRAMX + + ASSERT(__dummy_overlay_text_end__ - __fast_sram_text_data_start__ <= FAST_XRAM_SECTION_SIZE, "fast xram sections too large") + __free_fram = FAST_XRAM_SECTION_SIZE - (__dummy_overlay_text_end__ - __fast_sram_text_data_start__); + + __overlay_data_start__ = __sram_bss_end__; + OVERLAY (__overlay_data_start__) : NOCROSSREFS AT (__load_stop_overlay_text_end) + { +#ifndef NO_OVERLAY + .overlay_data0 + { + /* Explicitly place 4 bytes at section start to avoid "section type changed to PROGBITS" warnings */ + LONG(0); + /* common */ + *:fastmath_const.o(.data* .rodata*) + *:speech_win.o(.data* .rodata*) + + *:preprocess.o(.data* .rodata*) + *:filterbank.o(.data* .rodata*) +#if !defined(A2DP_SCALABLE_ON) + *:kiss_fft.o(.data* .rodata*) +#endif + *:kiss_fftr.o(.data* .rodata*) + *:fftwrap.o(.data* .rodata*) + *:mdf.o(.data* .rodata*) + *:plc_8000.o(.data* .rodata*) +#if defined(HFP_1_6_ENABLE) + *:plc_16000.o(.data* .rodata*) +#endif +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.data* .rodata* .bss*) +#endif +#if defined(SPEECH_TX_2MIC_NS) + *:dual_mic_denoise.o(.data* .rodata*) + *:vad_filterbank.o(.data* .rodata*) + *:energy.o(.data* .rodata*) + *:get_scaling_square.o(.data* .rodata*) + + *:cross_correlation.o(.data* .rodata*) + *:min_max_operations.o(.data* .rodata*) + *:resample_by_2_internal.o(.data* .rodata*) + *:division_operations.o(.data* .rodata*) + *:downsample_fast.o(.data* .rodata*) + *:resample_fractional.o(.data* .rodata*) + *:resample_48khz.o(.data* .rodata*) + *:vad_sp.o(.data* .rodata*) + *:vad_core.o(.data* .rodata*) + *:webrtc_vad.o(.data* .rodata*) + *:vad_gmm.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_2MIC_NS2) + *:speech_2mic_ns2_denoise.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS2) || defined(SPEECH_RX_NS2) + *:lc_mmse_ns.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS3) || defined(SPEECH_RX_NS3) + *:nsx_core.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) || defined(SPEECH_RX_NS2FLOAT) + *:lc_mmse_ns_float.o(.data* .rodata*) +#endif +#if defined(MSBC_8K_SAMPLE_RATE) + *:iir_resample.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) || defined(SPEECH_RX_NS2FLOAT) || defined(SPEECH_TX_AEC2FLOAT) + *:arm_common_tables.o(.rodata.armBitRevIndexTable256) + *:arm_common_tables.o(.rodata.twiddleCoef_256) + *:arm_common_tables.o(.rodata.twiddleCoef_rfft_512) + *:arm_common_tables.o(.rodata.armBitRevIndexTable128) + *:arm_common_tables.o(.rodata.twiddleCoef_128) + *:arm_common_tables.o(.rodata.twiddleCoef_rfft_256) +#endif + *(.overlay_data0 .overlay_rodata0) + . = ALIGN(4); + } + .overlay_data1 + { + LONG(0); +#if !defined(RB_CODEC) +#if !defined(HFP_1_6_ENABLE) + *:sbc.o(.data* .rodata*) + *:sbc_math.o(.data* .rodata*) +#endif + *:fixedpoint.o(.data* .rodata*) + *:replaygain.o(.data* .rodata*) + *:dsp_core.o(.data* .rodata*) + *:dsp_misc.o(.data* .rodata*) + *:dsp_filter.o(.data* .rodata*) + *:dsp_sample_input.o(.data* .rodata*) + *:dsp_sample_output.o(.data* .rodata*) + *:eq.o(.data* .rodata*) + *:pga.o(.data* .rodata*) +#if !defined(A2DP_AAC_ON) + *:fir_process.o(.data* .rodata*) +#endif +#endif + *(.overlay_data1 .overlay_rodata1) + . = ALIGN(4); + } + .overlay_data2 + { + LONG(0); + *(.overlay_data2 .overlay_rodata2) + . = ALIGN(4); + } + .overlay_data3 + { + LONG(0); + *:fft128dot.o(.data* .rodata*) + *(.overlay_data3 .overlay_rodata3) + . = ALIGN(4); + } + .overlay_data4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:block.o(.data* .rodata*) + *:tpdec_lib.o(.data* .rodata*) + *:tpdec_latm.o(.data* .rodata*) + *:aacdec_pns.o(.data* .rodata*) + *:aacdec_tns.o(.data* .rodata*) + *:mdct.o(.data* .rodata*) + *:pulsedata.o(.data* .rodata*) + *:channel.o(.data* .rodata*) + *:tpdec_asc.o(.data* .rodata*) + *:aacdecoder.o(.data* .rodata*) + *:channelinfo.o(.data* .rodata*) + *:aacdecoder_lib.o(.data* .rodata*) + *:stereo.o(.data* .rodata*) +#endif + *(.overlay_data4 .overlay_rodata4) + . = ALIGN(4); + } + .overlay_data5 + { + LONG(0); + *:mpa.o(.data* .bss*) + *:bit.o(.data* .bss*) + *:frame.o(.data* .bss*) + *:huffman.o(.data* .bss*) + *:layer12.o(.data* .bss*) + *:layer3.o(.data* .bss*) + *:stream.o(.data* .bss*) + *:synth.o(.data* .bss*) + *(.overlay_data5 .overlay_rodata5) + . = ALIGN(4); + } + .overlay_data6 + { + LONG(0); +#if defined(A2DP_SCALABLE_ON) + *(.constdata) + *:Audio_asm.o(.data* .rodata*) + *:vq.o(.data* .rodata*) + *:util.o(.data* .rodata*) + *:rate.o(.data* .rodata*) + *:quant_bands.o(.data* .rodata*) + *:modes.o(.data* .rodata*) + *:mathops.o(.data* .rodata*) + *:laplace.o(.data* .rodata*) + *:entdec.o(.data* .rodata*) + *:entcode.o(.data* .rodata*) + *:cwrs.o(.data* .rodata*) + *:audio_int32.o(.data* .rodata*) + *:audio_decoder.o(.data* .rodata*) + *:audio.o(.data* .rodata*) + *:a2dpplay.o(.bss.*scalable_decoder_place) + *:a2dpplay.o(.bss.*scalable_input_mid_buf) +#endif +#if defined(A2DP_LHDC_ON) + *:lhdcUtil.o(.data* .rodata*) + *:dec.o(.data* .rodata*) + *:cirbuf.o(.data* .rodata*) +#endif + *(.overlay_data6 .overlay_rodata6) + . = ALIGN(4); + } + .overlay_data7 + { + LONG(0); + *(.overlay_data7 .overlay_rodata7) + . = ALIGN(4); + } +#endif + .overlay_data_end + { + LONG(0); + . = ALIGN(4); + } + } > RAM + + .dummy_overlay_data (.) (NOLOAD) : + { + __dummy_overlay_data_end__ = .; + } > RAM + + ASSERT(__dummy_overlay_data_end__ - __overlay_data_start__ <= OVERLAY_DATA_SECTION_SIZE, "overlay sections too large") + + .text (FLASH_TO_FLASHX(__load_stop_overlay_data_end)) : AT (FLASHX_TO_FLASH(ADDR(.text))) + { + *(.text*) + *(.flash_text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + } > FLASHX + + .ARM.extab (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.extab))) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASHX + + __exidx_start = .; + /* .ARM.exidx contains R_ARM_PREL31 (+-0x40000000) offset to functions, which means + * the session location cannot be too far away from the function addresses */ + .ARM.exidx (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.exidx))) + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASHX + __exidx_end = .; + + . = FLASHX_TO_FLASH(.); + + .rodata (.) : + { + *(.rodata*) + *(.flash_rodata*) + KEEP(*(.eh_frame*)) + *(.note.gnu.build-id) + } > FLASH + +#ifdef TRACE_STR_SECTION + .trc_str (.) : + { + *(.trc_str*) + } > FLASH +#endif + + .custom.cmd.table (.) : + { + . = ALIGN(4); + __custom_handler_table_start = .; + KEEP(*(.custom_handler_table)) + __custom_handler_table_end = .; + } > FLASH + + .thirdparty.event.table (.) : + { + . = ALIGN(4); + __thirdparty_handler_table_start = .; + KEEP(*(.thirdparty_handler_table)) + __thirdparty_handler_table_end = .; + } > FLASH + +#if defined(FIRMWARE_REV) + .firmware_rev (.) : + { + . = ALIGN(64); + *(.fw_rev) + } > FLASH +#endif + + /* To copy multiple FLASH to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table (.) : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table (.) : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss (.) (NOLOAD) : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (.) (NOLOAD) : + { + . = ALIGN(8); + __HeapBase = .; + __end__ = .; + end = __end__; + . += HEAP_SECTION_SIZE; + . = ALIGN(8); + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (.) (COPY) : + { + . = STACK_SECTION_SIZE; + . = ALIGN(8); + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + __free_ram = __StackLimit - __HeapLimit; + + . = __etext + SIZEOF(.data); + + .system_info (.) : + { + KEEP(*(.system_info_list_size)) + KEEP(*(.system_info_list)) + . = ALIGN(4); + } > FLASH + + .build_info (.) : + { + KEEP(*(.build_info)) + . = ALIGN(4); + } > FLASH = 0x00000000 + +#ifdef SLAVE_BIN_FLASH_OFFSET + .slave_code (ORIGIN(FLASH) + SLAVE_BIN_FLASH_OFFSET): + { + KEEP(*(.slave_code_flash_rodata)) + } > FLASH +#endif + + /* The following section be the last loaded section */ + .code_start_addr (.) : + { + LONG(BUILD_INFO_MAGIC); + LONG(ABSOLUTE(__flash_start)); + } > FLASH + + __flash_end = .; + + + .crash_dump (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + CRASH_DUMP_SECTION_SIZE) (NOLOAD) : + { + __crash_dump_start = .; + . = CRASH_DUMP_SECTION_SIZE; + __crash_dump_end = .; + } > FLASH_NC + + .custom_parameter (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE) (NOLOAD) : + { + __custom_parameter_start = .; + . = CUSTOM_PARAMETER_SECTION_SIZE; + __custom_parameter_end = .; + } > FLASH_NC + + .userdata (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2) (NOLOAD) : + { + __userdata_start = .; + . = USERDATA_SECTION_SIZE*2; + __userdata_end = .; + } > FLASH_NC + + .audio (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE) (NOLOAD) : + { + __aud_start = .; + . = AUD_SECTION_SIZE; + __aud_end = .; + } > FLASH_NC + + .reserved (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE) (NOLOAD) : + { + __reserved_start = .; + . = RESERVED_SECTION_SIZE; + __reserved_end = .; + } > FLASH_NC + + .factory (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE) (NOLOAD) : + { + __factory_start = .; + . = FACTORY_SECTION_SIZE; + __factory_end = .; + } > FLASH_NC + + ASSERT(FLASH_NC_TO_C(__crash_dump_start) >= __flash_end, "region FLASH overflowed") + __free_flash = FLASH_NC_TO_C(__crash_dump_start) - __flash_end; +} + diff --git a/scripts/link/best2000_dma.lds.S b/scripts/link/best2000_dma.lds.S new file mode 100644 index 0000000..49b5862 --- /dev/null +++ b/scripts/link/best2000_dma.lds.S @@ -0,0 +1,1268 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#ifdef RB_CODEC +#define HEAP_SECTION_SIZE 0x1000 +#else +#define HEAP_SECTION_SIZE 0x1000 +#endif + +#define STACK_SECTION_SIZE 0xD00 + +#if defined(ROM_UTILS_ON) +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) +#define ROM_UTILS_RESV_RAM_SIZE 0x64 +#else +#define ROM_UTILS_RESV_RAM_SIZE 0x0 +#endif +#endif + +#ifdef RB_CODEC +#define OVERLAY_DATA_SECTION_SIZE 0xA000 +#else +#define OVERLAY_DATA_SECTION_SIZE 0x8000 +#endif + +#if (RAM_SIZE >= 0x48000) +#if defined(BTUSB_AUDIO_MODE) +#define FAST_XRAM_SECTION_SIZE 0x20000 +#else +#define FAST_XRAM_SECTION_SIZE 0x12000 +#endif +#elif (RAM_SIZE >= 0x40000) +#define FAST_XRAM_SECTION_SIZE 0x8000 +#else +#define FAST_XRAM_SECTION_SIZE 0x4000 +#endif + +#ifndef OTA_CODE_OFFSET +#define OTA_CODE_OFFSET 0 +#endif +#define FLASH_REGION_BASE (FLASH_BASE + OTA_CODE_OFFSET) +#ifndef FLASH_REGION_SIZE +#define FLASH_REGION_SIZE (FLASH_SIZE - (FLASH_REGION_BASE - FLASH_BASE)) +#endif +#define FLASH_NC_REGION_BASE FLASH_C_TO_NC(FLASH_REGION_BASE) +#define FLASHX_REGION_BASE FLASH_TO_FLASHX(FLASH_REGION_BASE) + +/* Linker script to configure memory regions. */ +/* See plat_addr_map.h and common.mk for the macro definitions */ +MEMORY +{ + ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE + FLASH (r) : ORIGIN = FLASH_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASH_NC (r) : ORIGIN = FLASH_NC_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASHX (rx) : ORIGIN = FLASHX_REGION_BASE, LENGTH = FLASH_REGION_SIZE + RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + RAMX (rx) : ORIGIN = RAMX_BASE, LENGTH = RAM_SIZE - FAST_XRAM_SECTION_SIZE + FRAMX (rwx) : ORIGIN = RAMX_BASE + RAM_SIZE - FAST_XRAM_SECTION_SIZE, LENGTH = FAST_XRAM_SECTION_SIZE +#ifdef PSRAM_BASE + PSRAM (rwx) : ORIGIN = PSRAM_BASE, LENGTH = PSRAM_SIZE + PSRAM_NC (rwx) : ORIGIN = PSRAM_NC_BASE, LENGTH = PSRAM_SIZE + PSRAMX (rx) : ORIGIN = PSRAMX_BASE, LENGTH = PSRAM_SIZE +#endif +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __export_fn_rom + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __free_ram + * __factory_start + * __factory_end + * __calib_start + * __calib_end + * __flash_start + * __flash_end + * __free_flash + * __boot_sram_start_flash__ + * __boot_sram_end_flash__ + * __boot_sram_start__ + * __boot_bss_sram_start__ + * __boot_bss_sram_end__ + * __sram_text_data_start_flash__ + * __sram_text_data_end_flash__ + * __fast_sram_text_data_start__ + * __fast_sram_text_data_end__ + * __fast_sram_text_data_start_flash__ + * __fast_sram_text_data_end_flash__ + * __sram_text_data_start__ + * __sram_bss_start__ + * __sram_bss_end__ + * __overlay_text_start__ + * __overlay_text_exec_start__ + * __overlay_data_start__ + */ +ENTRY(Boot_Loader) + +SECTIONS +{ + __export_fn_rom = (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE); + + .boot_struct (ORIGIN(FLASH)) : + { + __flash_start = .; + KEEP(*(.boot_struct)) + . = ALIGN(4); + } > FLASH + + . = FLASH_TO_FLASHX(.); + + .boot_text_flash (.) : AT (FLASHX_TO_FLASH(ADDR(.boot_text_flash))) + { + *(.boot_loader) + *(.boot_text_flash*) + *(.boot_rodata*) + . = ALIGN(4); + } > FLASHX + + . = FLASHX_TO_FLASH(.); + + .got_info (.) : + { + __got_info_start = .; + __got_start = .; + *(.got) + . = ALIGN(4); + __got_end = .; + __got_plt_start = .; + *(.got.plt) + . = ALIGN(4); + __igot_plt_start = .; + *(.igot.plt) + . = ALIGN(4); + __dynamic_start = .; + *(.dynamic) + . = ALIGN(4); + __got_info_end = .; + } > FLASH + + .vector_table (ORIGIN(RAM)) (NOLOAD) : + { + KEEP(*(.vector_table)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .reboot_param (.) (NOLOAD) : + { + KEEP(*(.reboot_param)) + . = REBOOT_PARAM_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .userdata_pool (.) (NOLOAD) : + { + *(.userdata_pool) + . = ALIGN(4); + __userdata_pool_end__ = .; + } > RAM + + __boot_sram_start_flash__ = LOADADDR(.got_info) + SIZEOF(.got_info); + __boot_sram_start__ = __userdata_pool_end__; + .boot_text_sram (RAM_TO_RAMX(__boot_sram_start__)) : AT (__boot_sram_start_flash__) + { + /* memcpy.o or libc_nano.a(lib_a-memcpy.o/lib_a-memcpy-stub.o) */ + *:memcpy.o(.text*) + *:lib_a-memcpy*.o(.text*) + *:libc_rom.o(.text*) + + /* memset.o or libc_nano.a(lib_a-memset.o) */ + *:memset.o(.text*) + *:lib_a-memset*.o(.text*) + + *:hal_norflash*.o(.text*) + *:norflash_*.o(.text*) + + *(.boot_text_sram*) + . = ALIGN(4); + __boot_text_sram_end = .; + } > RAMX + + .boot_data_sram (RAMX_TO_RAM(ADDR(.boot_text_sram) + SIZEOF(.boot_text_sram))) : + AT (__boot_sram_start_flash__ + SIZEOF(.boot_text_sram)) + { + *:hal_norflash*.o(.data* .rodata*) + *:norflash_*.o(.data* .rodata*) + *:hal_psram.o(.data* .rodata*) + *(.boot_data*) + . = ALIGN(4); + __boot_data_sram_end = .; + } > RAM + + __boot_sram_end_flash__ = __boot_sram_start_flash__ + + SIZEOF(.boot_text_sram) + SIZEOF(.boot_data_sram); + + .boot_bss_sram (.) (NOLOAD) : + { + __boot_bss_sram_start__ = .; + *:hal_norflash*.o(.bss*) + *:norflash_*.o(.bss*) + *:hal_psram.o(.bss*) + *(.boot_bss*) + . = ALIGN(4); + __boot_bss_sram_end__ = .; + } > RAM + + __sram_text_data_start_flash__ = __boot_sram_end_flash__; + __sram_text_data_start__ = __boot_bss_sram_end__; + .sram_text (RAM_TO_RAMX(__sram_text_data_start__)) : + AT (__sram_text_data_start_flash__) + { + *(.sram_text*) + . = ALIGN(4); + } > RAMX + + .sram_data (RAMX_TO_RAM(ADDR(.sram_text) + SIZEOF(.sram_text))) : + AT (__sram_text_data_start_flash__ + SIZEOF(.sram_text)) + { +#if defined(BTUSB_AUDIO_MODE) + *:hal_usb.o(.rodata*) +#endif + *:utils.o(.data* .rodata*) + *:cqueue.o(.data* .rodata*) + *:iir_process.o(.data* .rodata*) +#if defined(HFP_1_6_ENABLE) + *:sbcplc.o(.data* .rodata*) + *:sbc.o(.data* .rodata*) + *:sbc_math.o(.data* .rodata*) +#endif +#if defined(A2DP_AAC_ON) + *:fixpoint_math.o(.data* .rodata*) + *:FDK_bitbuffer.o(.data* .rodata*) +#endif + *:crossover_filter.o(.data* .rodata*) + *:exp_func_tables.o(.data* .rodata*) + *(.sram_data*) + . = ALIGN(4); + } > RAM + + __sram_text_data_end_flash__ = __sram_text_data_start_flash__ + + SIZEOF(.sram_text) + SIZEOF(.sram_data); + + .sram_bss (.) (NOLOAD) : + { + __sram_bss_start__ = .; + *:utils.o(.bss*) + *(.sram_bss*) + . = ALIGN(4); + __sram_bss_end__ = .; + } > RAM + + __fast_sram_text_data_start_flash__ = __sram_text_data_end_flash__; + .fast_text_sram (ORIGIN(FRAMX)) : AT (__fast_sram_text_data_start_flash__) + { + __fast_sram_text_data_start__ = .; +#if defined(ROM_UTILS_ON) + *:rom_utils.o(.text*) +#endif + +#if defined(BTUSB_AUDIO_MODE) + *:hal_dma.o(.text*) + *:hal_uart.o(.text*) + *:hal_trace.o(.text*) +#endif + +#if defined(BTUSB_AUDIO_MODE) + *:hal_usb.o(.text*) + + *:usb_audio.o(.text*) + *:usb_audio_sync.o(.text*) + *:usb_audio_cdc.o(.text*) + + *:usbaudio_entry.o(.text*) + *:usb_audio_app.o(.text*) +#endif + + /* memmove.o or libc_nano.a(lib_a-memmove.o) */ + *:memmove.o(.text*) + *:lib_a-memmove.o(.text*) + *:utils.o(.text*) + *:cqueue.o(.text*) + *:audio_resample_ex.o(.text*) +#if defined(MIX_MIC_DURING_MUSIC) + *:app_bt_stream.o(.text*) +#endif +#if defined(HFP_1_6_ENABLE) +#if defined(__SBC_FUNC_IN_ROM__) + *:sbc.o(.text*) +#else + *:sbc.o(.text.sbc_is_stream_info_valid) + *:sbc.o(.text.sbc_frame_length_get) + *:sbc.o(.text.sbc_4bit_crc_calc) + *:sbc.o(.text.sbc_bits_for_mono_alloc) + *:sbc.o(.text.sbc_bits_for_stereo_alloc) + *:sbc.o(.text.sbc_header_process) + *:sbc.o(.text.sbc_factors_process) + *:sbc.o(.text.sbc_sample_extract) + *:sbc.o(.text.sbc_sbsamples_make) + *:sbc.o(.text.sbc_joint_process) + *:sbc.o(.text.sbc_4band_synth_filter) + *:sbc.o(.text.sbc_8band_synth_filter) + *:sbc.o(.text.sbc_decoder_state_reset) + *:sbc.o(.text.sbc_frame_mute) + *:sbc.o(.text.sbc_frames_decode) + *:sbc.o(.text.sbc_samples_quant) + *:sbc.o(.text.sbc_decoder_init) + *:sbc.o(.text.sbc_encoder_init) + *:sbc.o(.text.sbc_frames_encode) +#endif + *:sbc_math.o(.text*) +#endif +#if defined(A2DP_AAC_ON) + *:fixpoint_math.o(.text*) + *:FDK_bitbuffer.o(.text*) + *:FDK_tools_rom.o(.text*FDKgetWindowSlope*) + *:FDK_tools_rom.o(.text*getBitstreamElementList*) + *:dct.o(.text*dct_IV*) +#if !defined(__SBC_FUNC_IN_ROM_VBEST2000__) + *:fft.o(.text._Z3fftiPlPi) + *:fft_rad2.o(.text*dit_fft*) + *:dct.o(.text*getTables*) +#endif +#ifdef VOICE_DATAPATH + *:opus_encoder.o(.text*) +#endif +#endif + +#if defined(__AUDIO_SPECTRUM__) + *:kiss_fft.o(.text*) + *:kiss_fftr.o(.text*) + *:fftwrap.o(.text*) + *:spectrum_fix.o(.text*) + *:audio_spectrum.o(.text*) +#endif + *:mdct.o(.text*) + *:crossover_filter.o(.text*) + *:data_compressor.o(.text*) + *:drc.o(.text*) + *:limiter.o(.text*) + *(.fast_text_sram*) + . = ALIGN(4); + __fast_sram_text_data_end__ = .; + } > FRAMX + __fast_sram_text_data_end_flash__ = __fast_sram_text_data_start_flash__ + SIZEOF(.fast_text_sram); + + __overlay_text_start__ = RAMX_TO_RAM(__fast_sram_text_data_end__); + __overlay_text_exec_start__ = RAM_TO_RAMX(__overlay_text_start__); + OVERLAY (__overlay_text_exec_start__) : NOCROSSREFS AT (__fast_sram_text_data_end_flash__) + { +#ifndef NO_OVERLAY + .overlay_text0 + { + LONG(0); +#if !defined(SCO_OPTIMIZE_FOR_RAM) + /* common */ + *:ae_common.o(.text*) + *:ae_rand.o(.text*) + *:cmsis_fftwrap.o(.text*) + *:fastmath.o(.text*) + *:integer_delay.o(.text*) + *:iirfilt.o(.text*) + *:ringbuf.o(.text*) + *:scale_int16.o(.text*) + *:speech_conv.o(.text*) + *:speech_trans_buf.o(.text*) + *:speech_win.o(.text*) + + *:preprocess.o(.text*) + *:filterbank.o(.text*) +#if !defined(__AUDIO_SPECTRUM__) +#if !defined(A2DP_SCALABLE_ON) + *:kiss_fft.o(.text*) +#endif + *:kiss_fftr.o(.text*) + *:fftwrap.o(.text*) +#endif + *:mdf.o(.text*) + *:plc_8000.o(.text*) +#if defined(HFP_1_6_ENABLE) + *:plc_16000.o(.text*) +#endif +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.text*) +#endif +#if defined(SPEECH_TX_2MIC_NS) + *:webrtc_vad.o(.text.WebRtcVad_Process) + *:webrtc_vad.o(.text.WebRtcVad_ValidRateAndFrameLength) + *:webrtc_vad.o(.text.WebRtcVad_CalcVad16khz) + *:webrtc_vad.o(.text.WebRtcVad_Downsampling) + *:webrtc_vad.o(.text.WebRtcVad_CalcVad8khz) + *:vad_filterbank.o(.text.*) + *:energy.o(.text.*) + *:get_scaling_square.o(.text.*) + *:dual_mic_denoise.o(.text*) + *:cross_correlation.o(.text*) + *:min_max_operations.o(.text*) + *:resample_by_2_internal.o(.text*) + *:division_operations.o(.text*) + *:downsample_fast.o(.text*) + *:resample_fractional.o(.text*) + *:resample_48khz.o(.text*) + *:vad_sp.o(.text*) + *:vad_core.o(.text*) + *:webrtc_vad.o(.text*) + *:vad_gmm.o(.text*) +#endif +#if defined(SPEECH_TX_2MIC_NS2) + *:speech_2mic_ns2_denoise.o(.text*) +#endif +#if defined(SPEECH_TX_NS2) || defined(SPEECH_RX_NS2) + *:lc_mmse_ns.o(.text*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) || defined(SPEECH_RX_NS2FLOAT) + *:lc_mmse_ns_float.o(.text*) +#endif +#if defined(SPEECH_TX_NS3) || defined(SPEECH_RX_NS3) + *:ns3.o(.text*) + *:noise_suppression_x.o(.text*) + *:nsx_core.o(.text*) + *:nsx_core_c.o(.text*) + *:copy_set_operations.o(.text*) + *:cross_correlation.o(.text*) + *:division_operations.o(.text*) + *:dot_product_with_scale.o(.text*) + *:downsample_fast.o(.text*) + *:energy.o(.text*) + *:get_scaling_square.o(.text*) + *:min_max_operations.o(.text*) + *:real_fft.o(.text*) + *:resample_by_2.o(.text*) + *:resample_by_2_internal.o(.text*) + *:spl_init.o(.text*) + *:spl_sqrt.o(.text*) + *:spl_sqrt_floor.o(.text*) + *:vector_scaling_operations.o(.text*) +#endif +#if defined(SPEECH_TX_AEC2FLOAT) + *:coherence.o(.text*) + *:echo_canceller.o(.text*) + *:echo_suppression.o(.text*) + *:lcmmse.o(.text*) + *:logmmse.o(.text*) + *:mdf2.o(.text*) + *:noise_generator.o(.text*) + *:pink_noise_gen.o(.text*) + *:white_noise_gen.o(.text*) +#endif +#if defined(MSBC_8K_SAMPLE_RATE) + *:iir_resample.o(.text*) +#endif +#if defined(SPEECH_TX_COMPEXP) + *:compexp.o(.text*) +#endif +#if defined(SPEECH_TX_EQ) || defined(SPEECH_RX_EQ) || defined(MSBC_8K_SAMPLE_RATE) + *:speech_eq.o(.text*) + *:speech_arm_eq.o(.text*) + *:arm_biquad_cascade_df1_f32.o(.text*) +#endif +#if defined(SPEECH_TX_POST_GAIN) || defined(SPEECH_RX_POST_GAIN) + *:speech_gain.o(.text*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) || defined(SPEECH_RX_NS2FLOAT) || defined(SPEECH_TX_AEC2FLOAT) + *:arm_rfft_fast_f32.o(.text*) + *:arm_cfft_f32.o(.text*) +#endif +#if defined(__SMARTVOICE__) +#if defined(SPEECH_TX_2MIC_NS2) || defined(SPEECH_TX_NS2) + *:app_smartvoice.o(.text._Z23mic_data_process_deinitv) + *:app_smartvoice.o(.text._Z21mic_data_process_initv) + *:app_smartvoice.o(.text._Z20mic_data_process_runPsm) +#endif +#endif + +#endif // #if !defined(SCO_OPTIMIZE_FOR_RAM) + *(.overlay_text0) + . = ALIGN(4); + } + .overlay_text1 + { + LONG(0); +#if !defined(RB_CODEC) +#if !defined(HFP_1_6_ENABLE) + *:sbc.o(.text*) + *:sbc_math.o(.text*) +#endif + *:fixedpoint.o(.text*) + *:replaygain.o(.text*) + *:dsp_core.o(.text*) + *:dsp_misc.o(.text*) + *:dsp_filter.o(.text*) + *:dsp_sample_input.o(.text*) + *:dsp_sample_output.o(.text*) + *:eq.o(.text*) + *:pga.o(.text*) +#if !defined(A2DP_AAC_ON) && !defined(A2DP_LHDC_ON) + *:fir_process.o(.text*) + *:iir_process.o(.text.iir_run .text.*iir_run_per_*) +#endif +#endif + *(.overlay_a2dp_sbc*) + *(.overlay_text1) + . = ALIGN(4); + } + .overlay_text2 + { + LONG(0); + *:fmdec.o(.text* .data* .rodata* .bss*) + *(.overlay_text2) + . = ALIGN(4); + } + .overlay_text3 + { + LONG(0); + *:fft128dot.o(.text*) + *(.overlay_text3) + . = ALIGN(4); + } + .overlay_text4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:block.o(.text.*CBlock_GetEscape*) + *:tpdec_lib.o(.text.*transportDec_GetBitstream*) + *:tpdec_lib.o(.text.*transportDec_GetAuBitsRemaining*) + *:tpdec_latm.o(.text.*CLatmDemux_GetValue*) + *:tpdec_latm.o(.text.*CLatmDemux_Read*) + *:tpdec_lib.o(.text.*transportDec_FillData*) + *:tpdec_lib.o(.text.*transportDec_ReadAccessUnit*) + *:tpdec_lib.o(.text.*transportDec_readHeader*) + *:block.o(.text.*ApplyTools*) + *:aacdec_pns.o(.text.*CPns_Apply*) + *:aacdec_tns.o(.text.*CTns_Apply*) + *:aacdec_tns.o(.text.*CTns_Reset*) + *:aacdec_pns.o(.text.*CPns_ResetData*) + *:pulsedata.o(.text.*CPulseData_Read*) + *:channel.o(.text.*CChannelElement_Read*) + *:tpdec_asc.o(.text.*CProgramConfig_Reset*) + *:tpdec_lib.o(.text.*transportDec_CrcCheck*) + *:block.o(.text.*CBlock_FrequencyToTime*) + *:block.o(.text.*CBlock_ReadSectionData*) + *:channel.o(.text.*CChannelElement_Decode*) + *:tpdec_lib.o(.text.*transportDec_CrcEndReg*) + *:aacdecoder.o(.text.*CAacDecoder_DecodeFrame*) +#if !defined(__SBC_FUNC_IN_ROM_VBEST2000__) + *:block.o(.text.*CBlock_ReadSpectralData*) + *:block.o(.text.*CBlock_ScaleSpectralData*) + *:aacdec_tns.o(.text.*CTns_ReadDataPresentFlag*) + *:tpdec_lib.o(.text.*transportDec_CrcStartReg*) + *:block.o(.text.*CBlock_ReadScaleFactorData*) + *:tpdec_lib.o(.text.*transportDec_EndAccessUnit*) + *:tpdec_latm.o(.text.*CLatmDemux_GetNrOfSubFrames*) + *:tpdec_lib.o(.text.*transportDec_GetAuBitsTotal*) + *:tpdec_asc.o(.text.*CProgramConfig_LookupElement*) + *:tpdec_latm.o(.text.*CLatmDemux_GetFrameLengthInBits*) + *:tpdec_latm.o(.text.*CLatmDemux_ReadPayloadLengthInfo*) + *:block.o(.text.*CBlock_InverseQuantizeSpectralData*) + *:channelinfo.o(.text.*IcsRead*) + *:aacdec_tns.o(.text.*CTns_Read*) + *:tpdec_lib.o(.text.*transportDec_AdjustEndOfAccessUnit*) + *:pulsedata.o(.text.*CPulseData_Apply*) + *:tpdec_asc.o(.text.*AudioSpecificConfig_Init*) + *:tpdec_asc.o(.text.*AudioSpecificConfig_Parse*) + *:tpdec_latm.o(.text.*CLatmDemux_ReadStreamMuxConfig*) + *:tpdec_asc.o(.text.*getSampleRate*) + *:tpdec_asc.o(.text.*getAOT*) + *:aacdecoder.o(.text.*CAacDecoder_Init*) + *:tpdec_asc.o(.text.*CProgramConfig_Init*) + *:aacdecoder_lib.o(.text.*aacDecoder_ConfigCallback*) + *:aacdecoder.o(.text.*CAacDecoder_ExtPayloadParse*) + *:stereo.o(.text.*CJointStereo_Read*) +#endif +#endif + *(.overlay_a2dp_aac*) + *(.overlay_text4) + . = ALIGN(4); + } + .overlay_text5 + { + LONG(0); + *:mpa.o(.text*) + *:bit.o(.text*) + *:frame.o(.text*) + *:huffman.o(.text*) + *:layer12.o(.text*) + *:layer3.o(.text*) + *:stream.o(.text*) + *:synth.o(.text*) + *(.overlay_text5) + . = ALIGN(4); + } + .overlay_text6 + { + LONG(0); +#if defined(A2DP_SCALABLE_ON) + *:Audio_asm.o(.text*) + *:vq.o(.text*) + *:util.o(.text*) + *:rate.o(.text*) + *:quant_bands.o(.text*) + *:modes.o(.text*) + *:mathops.o(.text*) + *:laplace.o(.text*) + *:entdec.o(.text*) + *:entcode.o(.text*) + *:cwrs.o(.text*) + *:audio_int32.o(.text*) + *:audio_decoder.o(.text*) + *:audio.o(.text*) + *(.overlay_a2dp_ssc*) +#endif + +#if defined(A2DP_LHDC_ON) + *:lhdcUtil.o(.text*) + *:dec.o(.text*) + *:cirbuf.o(.text*) + *(.overlay_a2dp_lhdc*) +#endif +#if defined(A2DP_LDAC_ON) + *:ldacBT_api.o(.text*) + *:decode_ldac.o(.text*) + *:dequant_ldac.o(.text*) + *:imdct_ldac.o(.text*) + *:ldacBT_internal.o(.text*) + *:ldaclib_api.o(.text*) + *:memory_ldac.o(.text*) + *:setpcm_ldac.o(.text*) + *:sigana_ldac.o(.text*) + *:tables_ldac.o(.text*) + *:tables_sigproc_ldac.o(.text*) + *:unpack_ldac.o(.text*) + *(.overlay_a2dp_ldac*) +#endif + + *(.overlay_text6) + . = ALIGN(4); + } + .overlay_text7 + { + LONG(0); + *(.overlay_text7) + . = ALIGN(4); + } +#endif + .overlay_text_end + { + LONG(0); + . = ALIGN(4); + } + } > FRAMX + + .dummy_overlay_text (.) (NOLOAD) : + { + __dummy_overlay_text_end__ = .; + } > FRAMX + + ASSERT(__dummy_overlay_text_end__ - __fast_sram_text_data_start__ <= FAST_XRAM_SECTION_SIZE, "fast xram sections too large") + __free_fram = FAST_XRAM_SECTION_SIZE - (__dummy_overlay_text_end__ - __fast_sram_text_data_start__); + + __overlay_data_start__ = __sram_bss_end__; + OVERLAY (__overlay_data_start__) : NOCROSSREFS AT (__load_stop_overlay_text_end) + { +#ifndef NO_OVERLAY + .overlay_data0 + { + /* Explicitly place 4 bytes at section start to avoid "section type changed to PROGBITS" warnings */ + LONG(0); +#if !defined(SCO_OPTIMIZE_FOR_RAM) + /* common */ + *:fastmath_const.o(.data* .rodata*) + *:speech_win.o(.data* .rodata*) + + *:preprocess.o(.data* .rodata*) + *:filterbank.o(.data* .rodata*) +#if !defined(A2DP_SCALABLE_ON) + *:kiss_fft.o(.data* .rodata*) +#endif + *:kiss_fftr.o(.data* .rodata*) + *:fftwrap.o(.data* .rodata*) + *:mdf.o(.data* .rodata*) + *:plc_8000.o(.data* .rodata*) +#if defined(HFP_1_6_ENABLE) + *:plc_16000.o(.data* .rodata*) +#endif +#if defined(_CVSD_BYPASS_) || defined(CVSD_BYPASS) + *:Pcm8k_Cvsd.o(.data* .rodata* .bss*) +#endif +#if defined(SPEECH_TX_2MIC_NS) + *:dual_mic_denoise.o(.data* .rodata*) + *:vad_filterbank.o(.data* .rodata*) + *:energy.o(.data* .rodata*) + *:get_scaling_square.o(.data* .rodata*) + + *:cross_correlation.o(.data* .rodata*) + *:min_max_operations.o(.data* .rodata*) + *:resample_by_2_internal.o(.data* .rodata*) + *:division_operations.o(.data* .rodata*) + *:downsample_fast.o(.data* .rodata*) + *:resample_fractional.o(.data* .rodata*) + *:resample_48khz.o(.data* .rodata*) + *:vad_sp.o(.data* .rodata*) + *:vad_core.o(.data* .rodata*) + *:webrtc_vad.o(.data* .rodata*) + *:vad_gmm.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_2MIC_NS2) + *:speech_2mic_ns2_denoise.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS2) || defined(SPEECH_RX_NS2) + *:lc_mmse_ns.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS3) || defined(SPEECH_RX_NS3) + *:nsx_core.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) || defined(SPEECH_RX_NS2FLOAT) + *:lc_mmse_ns_float.o(.data* .rodata*) +#endif +#if defined(MSBC_8K_SAMPLE_RATE) + *:iir_resample.o(.data* .rodata*) +#endif +#if defined(SPEECH_TX_NS2FLOAT) || defined(SPEECH_RX_NS2FLOAT) || defined(SPEECH_TX_AEC2FLOAT) + *:arm_common_tables.o(.rodata.armBitRevIndexTable256) + *:arm_common_tables.o(.rodata.twiddleCoef_256) + *:arm_common_tables.o(.rodata.twiddleCoef_rfft_512) + *:arm_common_tables.o(.rodata.armBitRevIndexTable128) + *:arm_common_tables.o(.rodata.twiddleCoef_128) + *:arm_common_tables.o(.rodata.twiddleCoef_rfft_256) +#endif + +#endif // #if !defined(SCO_OPTIMIZE_FOR_RAM) + *(.overlay_data0 .overlay_rodata0) + . = ALIGN(4); + } + .overlay_data1 + { + LONG(0); +#if !defined(RB_CODEC) +#if !defined(HFP_1_6_ENABLE) + *:sbc.o(.data* .rodata*) + *:sbc_math.o(.data* .rodata*) +#endif + *:fixedpoint.o(.data* .rodata*) + *:replaygain.o(.data* .rodata*) + *:dsp_core.o(.data* .rodata*) + *:dsp_misc.o(.data* .rodata*) + *:dsp_filter.o(.data* .rodata*) + *:dsp_sample_input.o(.data* .rodata*) + *:dsp_sample_output.o(.data* .rodata*) + *:eq.o(.data* .rodata*) + *:pga.o(.data* .rodata*) +#if !defined(A2DP_AAC_ON) + *:fir_process.o(.data* .rodata*) +#endif +#endif + *(.overlay_data1 .overlay_rodata1) + . = ALIGN(4); + } + .overlay_data2 + { + LONG(0); + *(.overlay_data2 .overlay_rodata2) + . = ALIGN(4); + } + .overlay_data3 + { + LONG(0); + *:fft128dot.o(.data* .rodata*) + *(.overlay_data3 .overlay_rodata3) + . = ALIGN(4); + } + .overlay_data4 + { + LONG(0); +#if defined(A2DP_AAC_ON) + *:block.o(.data* .rodata*) + *:tpdec_lib.o(.data* .rodata*) + *:tpdec_latm.o(.data* .rodata*) + *:aacdec_pns.o(.data* .rodata*) + *:aacdec_tns.o(.data* .rodata*) + *:pulsedata.o(.data* .rodata*) + *:channel.o(.data* .rodata*) + *:tpdec_asc.o(.data* .rodata*) + *:aacdecoder.o(.data* .rodata*) + *:channelinfo.o(.data* .rodata*) + *:aacdecoder_lib.o(.data* .rodata*) + *:stereo.o(.data* .rodata*) +#endif + *(.overlay_data4 .overlay_rodata4) + . = ALIGN(4); + } + .overlay_data5 + { + LONG(0); + *:mpa.o(.data* .bss*) + *:bit.o(.data* .bss*) + *:frame.o(.data* .bss*) + *:huffman.o(.data* .bss*) + *:layer12.o(.data* .bss*) + *:layer3.o(.data* .bss*) + *:stream.o(.data* .bss*) + *:synth.o(.data* .bss*) + *(.overlay_data5 .overlay_rodata5) + . = ALIGN(4); + } + .overlay_data6 + { + LONG(0); +#if defined(A2DP_SCALABLE_ON) + *(.constdata) + *:Audio_asm.o(.data* .rodata*) + *:vq.o(.data* .rodata*) + *:util.o(.data* .rodata*) + *:rate.o(.data* .rodata*) + *:quant_bands.o(.data* .rodata*) + *:modes.o(.data* .rodata*) + *:mathops.o(.data* .rodata*) + *:laplace.o(.data* .rodata*) + *:entdec.o(.data* .rodata*) + *:entcode.o(.data* .rodata*) + *:cwrs.o(.data* .rodata*) + *:audio_int32.o(.data* .rodata*) + *:audio_decoder.o(.data* .rodata*) + *:audio.o(.data* .rodata*) +#endif +#if defined(A2DP_LHDC_ON) + *:lhdcUtil.o(.data* .rodata*) + *:dec.o(.data* .rodata*) + *:cirbuf.o(.data* .rodata*) +#endif +#if defined(A2DP_LDAC_ON) + *:ldacBT_api.o(.data* .rodata*) + *:decode_ldac.o(.data* .rodata*) + *:dequant_ldac.o(.data* .rodata*) + *:imdct_ldac.o(.data* .rodata*) + *:ldacBT_internal.o(.data* .rodata*) + *:ldaclib_api.o(.data* .rodata*) + *:memory_ldac.o(.data* .rodata*) + *:setpcm_ldac.o(.data* .rodata*) + *:sigana_ldac.o(.data* .rodata*) + *:tables_ldac.o(.data* .rodata*) + *:tables_sigproc_ldac.o(.data* .rodata*) + *:unpack_ldac.o(.data* .rodata*) +#endif + *(.overlay_data6 .overlay_rodata6) + . = ALIGN(4); + } + .overlay_data7 + { + LONG(0); + *(.overlay_data7 .overlay_rodata7) + . = ALIGN(4); + } +#endif + .overlay_data_end + { + LONG(0); + . = ALIGN(4); + } + } > RAM + + .dummy_overlay_data (.) (NOLOAD) : + { + __dummy_overlay_data_end__ = .; + } > RAM + + ASSERT(__dummy_overlay_data_end__ - __overlay_data_start__ <= OVERLAY_DATA_SECTION_SIZE, "overlay sections too large") + + __text_start_flash__ = __load_stop_overlay_data_end; + + .text (FLASH_TO_FLASHX(__text_start_flash__)) : AT (FLASHX_TO_FLASH(ADDR(.text))) + { + *(.text*) + *(.flash_text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + } > FLASHX + + .ARM.extab (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.extab))) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASHX + + __exidx_start = .; + /* .ARM.exidx contains R_ARM_PREL31 (+-0x40000000) offset to functions, which means + * the session location cannot be too far away from the function addresses */ + .ARM.exidx (.) : AT (FLASHX_TO_FLASH(ADDR(.ARM.exidx))) + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASHX + __exidx_end = .; + + . = FLASHX_TO_FLASH(.); + + .rodata (.) : + { + *(.rodata*) + *(.flash_rodata*) + KEEP(*(.eh_frame*)) + *(.note.gnu.build-id) + } > FLASH + +#ifdef TRACE_STR_SECTION + .trc_str (.) : + { + *(.trc_str*) + } > FLASH +#endif + + .ai.gatt.server.table (.) : + { + . = ALIGN(4); + __ai_gatt_server_table_start = .; + KEEP(*(.ai_gatt_server_table)) + __ai_gatt_server_table_end = .; + } > FLASH + + .ai.ble.handler.table (.) : + { + . = ALIGN(4); + __ai_ble_handler_table_start = .; + KEEP(*(.ai_ble_handler_table)) + __ai_ble_handler_table_end = .; + } > FLASH + + .ai.spp.register.table (.) : + { + . = ALIGN(4); + __ai_spp_register_table_start = .; + KEEP(*(.ai_spp_register_table)) + __ai_spp_register_table_end = .; + } > FLASH + + .tota.cmd.table (.) : + { + . = ALIGN(4); + __tota_handler_table_start = .; + KEEP(*(.tota_handler_table)) + __tota_handler_table_end = .; + } > FLASH + + .ai.handler.function.table (.) : + { + . = ALIGN(4); + __ai_handler_function_table_start = .; + KEEP(*(.ai_handler_function_table)) + __ai_handler_function_table_end = .; + } > FLASH + + .custom.cmd.table (.) : + { + . = ALIGN(4); + __custom_handler_table_start = .; + KEEP(*(.custom_handler_table)) + __custom_handler_table_end = .; + } > FLASH + + .thirdparty.event.table (.) : + { + . = ALIGN(4); + __thirdparty_handler_table_start = .; + KEEP(*(.thirdparty_handler_table)) + __thirdparty_handler_table_end = .; + } > FLASH + +#if defined(FIRMWARE_REV) + .firmware_rev (.) : + { + . = ALIGN(64); + *(.fw_rev) + } > FLASH +#endif + + /* To copy multiple FLASH to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table (.) : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table (.) : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + + *(vtable) + . = ALIGN(4); + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + + + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss (.) (NOLOAD) : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (.) (NOLOAD) : + { + . = ALIGN(8); + __HeapBase = .; + __end__ = .; + end = __end__; + . += HEAP_SECTION_SIZE; + . = ALIGN(8); + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (.) (COPY) : + { + . = STACK_SECTION_SIZE; + . = ALIGN(8); + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ +#if defined(ROM_UTILS_ON) + __StackTop = ORIGIN(RAM) + LENGTH(RAM) - ROM_UTILS_RESV_RAM_SIZE; +#else + __StackTop = ORIGIN(RAM) + LENGTH(RAM); +#endif + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + __free_ram = __StackLimit - __HeapLimit; + + . = __etext + SIZEOF(.data); + + .system_info (.) : + { + KEEP(*(.system_info_list_size)) + KEEP(*(.system_info_list)) + . = ALIGN(4); + } > FLASH + + .build_info (.) : + { + KEEP(*(.build_info)) + . = ALIGN(4); + } > FLASH = 0x00000000 + +#ifdef SLAVE_BIN_FLASH_OFFSET + .slave_code (ORIGIN(FLASH) + SLAVE_BIN_FLASH_OFFSET): + { + KEEP(*(.slave_code_flash_rodata)) + } > FLASH +#endif + + /* The following section be the last loaded section */ + .code_start_addr (.) : + { + LONG(BUILD_INFO_MAGIC); + LONG(ABSOLUTE(__flash_start)); + } > FLASH + + __flash_end = .; + + .ota_upgrade_log (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + CRASH_DUMP_SECTION_SIZE - LOG_DUMP_SECTION_SIZE - OTA_UPGRADE_LOG_SIZE) (NOLOAD) : + { + __ota_upgrade_log_start = .; + . = OTA_UPGRADE_LOG_SIZE; + __ota_upgrade_log_end = .; + } > FLASH_NC + + .log_dump (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + CRASH_DUMP_SECTION_SIZE - LOG_DUMP_SECTION_SIZE) (NOLOAD) : + { + __log_dump_start = .; + . = LOG_DUMP_SECTION_SIZE; + __log_dump_end = .; + } > FLASH_NC + + .crash_dump (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE - + CRASH_DUMP_SECTION_SIZE) (NOLOAD) : + { + __crash_dump_start = .; + . = CRASH_DUMP_SECTION_SIZE; + __crash_dump_end = .; + } > FLASH_NC + + .custom_parameter (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2 - CUSTOM_PARAMETER_SECTION_SIZE) (NOLOAD) : + { + __custom_parameter_start = .; + . = CUSTOM_PARAMETER_SECTION_SIZE; + __custom_parameter_end = .; + } > FLASH_NC + + .userdata (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE - USERDATA_SECTION_SIZE*2) (NOLOAD) : + { + __userdata_start = .; + . = USERDATA_SECTION_SIZE*2; + __userdata_end = .; + } > FLASH_NC + + .audio (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE - + AUD_SECTION_SIZE) (NOLOAD) : + { + __aud_start = .; + . = AUD_SECTION_SIZE; + __aud_end = .; + } > FLASH_NC + + .reserved (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE - RESERVED_SECTION_SIZE) (NOLOAD) : + { + __reserved_start = .; + . = RESERVED_SECTION_SIZE; + __reserved_end = .; + } > FLASH_NC + + .factory (ORIGIN(FLASH_NC) + LENGTH(FLASH_NC) - FACTORY_SECTION_SIZE) (NOLOAD) : + { + __factory_start = .; + . = FACTORY_SECTION_SIZE; + __factory_end = .; + } > FLASH_NC + +#ifdef OTA_BOOT_SIZE +#if (OTA_BOOT_SIZE > FLASH_SIZE) +#error "OTA_BOOT_SIZE should <= FLASH_SIZE" +#endif +#if defined(OTA_CODE_OFFSET) && (OTA_BOOT_SIZE > OTA_CODE_OFFSET) +#error "OTA_BOOT_SIZE should <= OTA_CODE_OFFSET" +#endif + __tail_section_start = FLASH_BASE + OTA_BOOT_SIZE; +#else + __tail_section_start = __ota_upgrade_log_start; +#endif + + ASSERT(FLASH_NC_TO_C(__tail_section_start) >= __flash_end, "region FLASH overflowed") + __free_flash = FLASH_NC_TO_C(__tail_section_start) - __flash_end; + +#if !defined(OTA_BOOT_SIZE) && defined(OTA_REMAP_OFFSET) + ASSERT((FLASH_BASE & 0x00FFFFFF) == 0, "bad FLASH_BASE") + ASSERT((FLASH_SIZE & (FLASH_SIZE - 1)) == 0, "bad FLASH_SIZE") + ASSERT(__flash_end <= FLASH_BASE + FLASH_SIZE / 2, "flash code size too large to remap") + ASSERT(__flash_start - FLASH_BASE >= FLASH_NC_BASE + FLASH_SIZE - __tail_section_start, "flash code conflicted with tail sections in remap") + ASSERT(__flash_start - FLASH_BASE >= FLASH_SIZE / (1 << (4 + 1)), "flash code cannot remap within 4 regions (max code size is half of flash size)") + ASSERT((__flash_start - FLASH_BASE) % (FLASH_SIZE / (1 << (4 + 1))) == 0, "flash code start address not aligned with remap region boundary") +#endif +} + diff --git a/scripts/link/programmer.lds.S b/scripts/link/programmer.lds.S new file mode 100644 index 0000000..e2cf948 --- /dev/null +++ b/scripts/link/programmer.lds.S @@ -0,0 +1,283 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#define MIN_BURN_BUFFER_SIZE 0x2000 + +#define HEAP_SECTION_SIZE 0x40 +#define STACK_SECTION_SIZE 0x1000 + +#define CODE_MSG_OVERHEAD 8 + +/* Linker script to configure memory regions. */ +MEMORY +{ + ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE /* see plat_addr_map.h and common.mk */ + RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE + RAMX (rx) : ORIGIN = RAMX_BASE, LENGTH = RAM_SIZE +} + +/* Library configurations */ +GROUP(libgcc.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions ROM and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __export_fn_rom + * __exec_struct_start + * __cust_cmd_init_tbl_start + * __cust_cmd_init_tbl_end + * __cust_cmd_hldr_tbl_start + * __cust_cmd_hldr_tbl_end + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __free_ram + */ +ENTRY(programmer_start) + +SECTIONS +{ + __export_fn_rom = (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE); + + .vector_table (ORIGIN(RAM)) (NOLOAD) : + { + KEEP(*(.vector_table)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .reboot_param (.) (NOLOAD) : + { + KEEP(*(.reboot_param)) + . = REBOOT_PARAM_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .burn_buffer (.) (NOLOAD) : + { + /* The size of .burn_buffer should be greater than __rom_HeapLimit. In most cases 8K is enough. */ + *(.burn_buffer) + . = MAX(., MIN_BURN_BUFFER_SIZE); + . = ALIGN(4); + } > RAM + +/* + .code_dummy (.) (NOLOAD) : + { + . = CODE_MSG_OVERHEAD; + . = ALIGN(4); + } > RAM +*/ + + .boot_struct (.) : + { + KEEP(*(.boot_struct)) + + __exec_struct_start = .; + KEEP(*(.exec_struct)) + . = ALIGN(4); + } > RAM + + .got_info (.) : + { + __got_info_start = .; + __got_start = .; + *(.got) + . = ALIGN(4); + __got_end = .; + __got_plt_start = .; + *(.got.plt) + . = ALIGN(4); + __igot_plt_start = .; + *(.igot.plt) + . = ALIGN(4); + __dynamic_start = .; + *(.dynamic) + . = ALIGN(4); + __got_info_end = .; + } > RAM + + . = RAM_TO_RAMX(.); + + .text (.) : AT (RAMX_TO_RAM(ADDR(.text))) + { + *(.text*) + +#ifndef NOSTD + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) +#endif + + . = ALIGN(4); + } > RAMX + + .ARM.extab (.) : AT (RAMX_TO_RAM(ADDR(.ARM.extab))) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > RAMX + + __exidx_start = .; + /* .ARM.exidx contains R_ARM_PREL31 (+-0x40000000) offset to functions, which means + * the session location cannot be too far away from the function addresses */ + .ARM.exidx (.) : AT (RAMX_TO_RAM(ADDR(.ARM.exidx))) + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > RAMX + __exidx_end = .; + + . = RAMX_TO_RAM(.); + + .rodata (.) : + { + *(.rodata*) + + . = ALIGN(4); + __cust_cmd_init_tbl_start = .; + KEEP(*(.cust_cmd_init_tbl)) + __cust_cmd_init_tbl_end = .; + + . = ALIGN(4); + __cust_cmd_hldr_tbl_start = .; + KEEP(*(.cust_cmd_hldr_tbl)) + __cust_cmd_hldr_tbl_end = .; + +#ifndef NOSTD + KEEP(*(.eh_frame*)) +#endif + *(.note.gnu.build-id) + . = ALIGN(4); + } > RAM + + __etext = .; + + .data (.) : + { + __data_start__ = .; + *(.data*) + . = ALIGN(4); + +#ifndef NOSTD + *(vtable) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); +#endif + /* All data end */ + __data_end__ = .; + + } > RAM + + .build_info (.) : + { + KEEP(*(.build_info)) + . = ALIGN(4); + } > RAM = 0x00000000 + + /* The following section be the last loaded section */ + .code_start_addr (.) : + { + LONG(ABSOLUTE(__exec_struct_start)); + } > RAM + + .bss (.) (NOLOAD) : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (.) (NOLOAD) : + { + . = ALIGN(8); + __HeapBase = .; + __end__ = .; + end = __end__; + . += HEAP_SECTION_SIZE; + . = ALIGN(8); + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (.) (COPY) : + { + . = STACK_SECTION_SIZE; + . = ALIGN(8); + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + __free_ram = __StackLimit - __HeapLimit; +} diff --git a/scripts/link/programmer.lds_scat.S b/scripts/link/programmer.lds_scat.S new file mode 100644 index 0000000..a679ff9 --- /dev/null +++ b/scripts/link/programmer.lds_scat.S @@ -0,0 +1,160 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#define MIN_BURN_BUFFER_SIZE 0x2000 +#define BURN_BUFFER_END 0x11000 + +#define HEAP_SECTION_SIZE 0x40 +#define STACK_SECTION_SIZE 0x1000 + +#define CODE_MSG_OVERHEAD 8 + +LR_vector (RAMX_BASE + BURN_BUFFER_END) NOCOMPRESS +{ + vector_table RAM_BASE UNINIT VECTOR_SECTION_SIZE + { + *(.bss.vector_table, +FIRST) + } + + reboot_param (ImageBase(vector_table) + VECTOR_SECTION_SIZE) UNINIT REBOOT_PARAM_SECTION_SIZE + { + *(.bss.reboot_param, +FIRST) + } + + burn_buffer (ImageBase(reboot_param) + REBOOT_PARAM_SECTION_SIZE) UNINIT + { + /* The size of .burn_buffer should be greater than __rom_HeapLimit. In most cases 8K is enough. */ + *(.bss.burn_buffer) + } + + ScatterAssert(ImageLimit(burn_buffer) <= (ImageBase(vector_table) + BURN_BUFFER_END)) +} + +LR_boot_struct +0 +{ + boot_struct RAMX_TO_RAM(+0) + { + *(.boot_struct, +FIRST) + } + + exec_struct +0 + { + *(.exec_struct, +FIRST) + } + + got_info +0 + { + *(.got) + *(.got.plt) + *(.igot.plt) + *(.dynamic) + } +} + +LR_text +0 +{ + text +0 FIXED + { + *(.text*) + +#ifndef NOSTD + *(InRoot$$Sections) + *armlib*(+TEXT) +#endif + } + + .ARM.extab +0 + { + *(.ARM.extab*, .gnu.linkonce.armextab.*) + } + + /* .ARM.exidx contains R_ARM_PREL31 (+-0x40000000) offset to functions, which means + * the session location cannot be too far away from the function addresses */ + .ARM.exidx +0 + { + *(.ARM.exidx*, .gnu.linkonce.armexidx.*) + } + + rodata RAMX_TO_RAM(+0) + { + *(.rodata*) + +#ifndef NOSTD + *armlib*(+CONST) + KEEP(*(.eh_frame*)) +#endif + *(.note.gnu.build-id) + . = ALIGN(4); + } + + cust_cmd_init_tbl +0 + { + *(.cust_cmd_init_tbl) + } + + cust_cmd_hdlr_tbl +0 + { + *(.cust_cmd_hldr_tbl) + } + + data +0 + { + *(.data*) + +#ifndef NOSTD + *armlib*(+DATA) +#endif + } + + .build_info +0 + { + *(.build_info, +FIRST) + } + + /* The following section be the last loaded section */ + code_start_addr +0 + { + *(.code_start_addr, +LAST) + } + + bss +0 UNINIT + { + *(.bss*) + *(COMMON) + +#ifndef NOSTD + *armlib*(+BSS) +#endif + } + + ARM_LIB_HEAP +0 ALIGN 8 EMPTY HEAP_SECTION_SIZE + { + } + + ARM_LIB_STACK (RAM_BASE + RAM_SIZE - STACK_SECTION_SIZE) ALIGN 8 EMPTY STACK_SECTION_SIZE + { + } + + /* Check if data + heap + stack exceeds RAM limit */ + ScatterAssert(ImageBase(ARM_LIB_STACK) >= ImageLimit(ARM_LIB_HEAP)) + ScatterAssert(ImageLimit(ARM_LIB_STACK) <= (RAM_BASE + RAM_SIZE)) + + free_ram ImageLimit(ARM_LIB_HEAP) EMPTY (ImageBase(ARM_LIB_STACK) - ImageLimit(ARM_LIB_HEAP)) + { + } +} diff --git a/scripts/link/programmer_inflash.lds.S b/scripts/link/programmer_inflash.lds.S new file mode 100644 index 0000000..0349e3e --- /dev/null +++ b/scripts/link/programmer_inflash.lds.S @@ -0,0 +1,300 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#define HEAP_SECTION_SIZE 0x40 +#define STACK_SECTION_SIZE 0x1000 + +#define CODE_MSG_OVERHEAD 8 + +/* TODO: Add FLASH_REGION_OFFSET if there are multiple levels of boot loaders */ +#if !defined(OTA_BOOT_SIZE) && defined(OTA_CODE_OFFSET) +#define FLASH_REGION_BASE (FLASH_BASE + OTA_CODE_OFFSET) +#else +#define FLASH_REGION_BASE (FLASH_BASE) +#endif + +#ifndef FLASH_REGION_SIZE +#define FLASH_REGION_SIZE (FLASH_SIZE - (FLASH_REGION_BASE - FLASH_BASE)) +#endif +#define FLASH_NC_REGION_BASE FLASH_C_TO_NC(FLASH_REGION_BASE) +#define FLASHX_REGION_BASE FLASH_TO_FLASHX(FLASH_REGION_BASE) +/* Linker script to configure memory regions. */ +MEMORY +{ + ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE /* see plat_addr_map.h and common.mk */ + FLASH (r) : ORIGIN = FLASH_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASH_NC (r) : ORIGIN = FLASH_NC_REGION_BASE, LENGTH = FLASH_REGION_SIZE + FLASHX (rx) : ORIGIN = FLASHX_REGION_BASE, LENGTH = FLASH_REGION_SIZE + RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE + RAMX (rx) : ORIGIN = RAMX_BASE, LENGTH = RAM_SIZE +} + +/* Library configurations */ +GROUP(libgcc.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions ROM and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __export_fn_rom + * __exec_struct_start + * __cust_cmd_init_tbl_start + * __cust_cmd_init_tbl_end + * __cust_cmd_hldr_tbl_start + * __cust_cmd_hldr_tbl_end + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __free_ram + */ + +ENTRY(Boot_Loader) + +SECTIONS +{ + __export_fn_rom = (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE); + + .boot_struct (ORIGIN(FLASH)) : + { + __flash_start = .; + KEEP(*(.boot_struct)) + . = ALIGN(4); + } > FLASH + + . = FLASH_TO_FLASHX(.); + + .boot_text_flash (.) : AT (FLASHX_TO_FLASH(ADDR(.boot_text_flash))) + { + *(.boot_loader) + *(.boot_text_flash*) + *(.boot_rodata_flash*) + *:main.o(.text* .rodata*) + *:hal_bootmode.o(.text* .rodata*) + *:hal_cmu_*.o(.text.hal_cmu_get_bootmode_addr .rodata.hal_cmu_get_bootmode_addr) + *:cmsis_nvic.o(.text.NVIC_DisableAllIRQs .rodata.NVIC_DisableAllIRQs) + . = ALIGN(4); + } > FLASHX + + .ota_boot_info (ALIGN(4096)) : + { + *(.ota_boot_info) + . = (0x1000); + } > FLASHX + + .ota_boot_rev (ALIGN(4096)) : + { + *(.ota_boot_rev) + . = (0x1000); + } > FLASHX + + . = FLASHX_TO_FLASH(.); + + .got_info (.) : + { + __got_info_start = .; + __got_start = .; + *(.got) + . = ALIGN(4); + __got_end = .; + __got_plt_start = .; + *(.got.plt) + . = ALIGN(4); + __igot_plt_start = .; + *(.igot.plt) + . = ALIGN(4); + __dynamic_start = .; + *(.dynamic) + . = ALIGN(4); + __got_info_end = .; + } > FLASH + + .vector_table (ORIGIN(RAM)) (NOLOAD) : + { + KEEP(*(.vector_table)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .reboot_param (.) (NOLOAD) : + { + KEEP(*(.reboot_param)) + . = REBOOT_PARAM_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .burn_buffer (.) (NOLOAD) : + { + /* The size of .burn_buffer should be greater than __rom_HeapLimit. In most cases 8K is enough. */ + KEEP(*(.burn_buffer)) + . = ALIGN(4); + } > RAM + +/* + .code_dummy (.) (NOLOAD) : + { + . = CODE_MSG_OVERHEAD; + . = ALIGN(4); + } > RAM +*/ + + __boot_sram_start__ = .; + + . = RAM_TO_RAMX(.); + + __boot_sram_start_flash__ = LOADADDR(.got_info) + SIZEOF(.got_info); + + .text (.) : AT (__boot_sram_start_flash__) + { + *(.text*) + . = ALIGN(4); + } > RAMX + + .ARM.extab (.) : AT (LOADADDR(.text) + SIZEOF(.text)) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > RAMX + + __exidx_start = .; + /* .ARM.exidx contains R_ARM_PREL31 (+-0x40000000) offset to functions, which means + * the session location cannot be too far away from the function addresses */ + .ARM.exidx (.) : AT (LOADADDR(.ARM.extab) + SIZEOF(.ARM.extab)) + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > RAMX + __exidx_end = .; + + . = RAMX_TO_RAM(.); + + .rodata (.) : AT (LOADADDR(.ARM.exidx) + SIZEOF(.ARM.exidx)) + { + *(.rodata*) + *(.boot_rodata_sram*) + + . = ALIGN(4); + __cust_cmd_init_tbl_start = .; + KEEP(*(.cust_cmd_init_tbl)) + __cust_cmd_init_tbl_end = .; + + . = ALIGN(4); + __cust_cmd_hldr_tbl_start = .; + KEEP(*(.cust_cmd_hldr_tbl)) + __cust_cmd_hldr_tbl_end = .; + + *(.note.gnu.build-id) + . = ALIGN(4); + } > RAM + + __etext = .; + + .data (.) : AT (LOADADDR(.rodata) + SIZEOF(.rodata)) + { + __data_start__ = .; + *(.data*) + + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + __boot_sram_end__ = .; + + __boot_sram_end_flash__ = LOADADDR(.data) + SIZEOF(.data); + + .build_info (LOADADDR(.data) + SIZEOF(.data)) : AT (LOADADDR(.data) + SIZEOF(.data)) + { + KEEP(*(.build_info)) + . = ALIGN(4); + } > FLASH = 0x00000000 + + /* The following section be the last loaded section */ + .code_start_addr (.) : + { + __app_entry_address__ = .; + LONG(APP_ENTRY_ADDRESS); + __download_uart_bandrate__ = .; + LONG(DOWNLOAD_UART_BANDRATE); + LONG(BUILD_INFO_MAGIC); + LONG(ABSOLUTE(__flash_start)); + } > FLASH + + __flash_end = .; + + .bss (ADDR(.data)+SIZEOF(.data)) (NOLOAD) : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (.) (NOLOAD) : + { + . = ALIGN(8); + __HeapBase = .; + __end__ = .; + end = __end__; + . += HEAP_SECTION_SIZE; + . = ALIGN(8); + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (.) (COPY) : + { + . = STACK_SECTION_SIZE; + . = ALIGN(8); + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + __free_ram = __StackLimit - __HeapLimit; + + __boot_bss_sram_start__ = .; + __boot_bss_sram_end__ = .; + __sram_text_data_start_flash__ = .; + __sram_text_data_end_flash__ = .; + __sram_text_data_start__ = .; + __sram_bss_start__ = .; + __sram_bss_end__ = .; + __fast_sram_text_data_start_flash__ = .; + __fast_sram_text_data_end_flash__ = .; + __fast_sram_text_data_start__ = .; +} diff --git a/scripts/link/rom.lds.S b/scripts/link/rom.lds.S new file mode 100644 index 0000000..44ac7b2 --- /dev/null +++ b/scripts/link/rom.lds.S @@ -0,0 +1,304 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#define HEAP_SECTION_SIZE 0x40 +#define STACK_SECTION_SIZE 0x1000 +#define CP_STACK_SECTION_SIZE 0x1000 + +/* Linker script to configure memory regions. */ +MEMORY +{ + ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE /* see plat_addr_map.h and common.mk */ + RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE + RAMX (rwx) : ORIGIN = RAMX_BASE, LENGTH = RAM_SIZE +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + RAMCP (rwx) : ORIGIN = RAMCP_BASE, LENGTH = RAMCP_SIZE + RAMCPX (rwx) : ORIGIN = RAMCPX_BASE, LENGTH = RAMCPX_SIZE +#endif +} + +/* Library configurations */ +GROUP(libgcc.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions ROM and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __export_fn_rom + * __exidx_start + * __exidx_end + * __rom_etext + * __rom_data_start__ + * __rom_data_end__ + * __rom_bss_start__ + * __rom_bss_end__ + * __rom_HeapLimit + * __rom_StackLimit + * __rom_StackTop + * __rom_stack + * __Vectors_End + * __Vectors_Size + * __free_rom_ram + * __rom_end + * __free_rom + * __audio_const_rom_start + * __audio_const_rom_end + * __audio_const_rom_size + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .rom_text (ORIGIN(ROM)) : + { + KEEP(*(.vectors)) + + *(.text*) + +#ifndef NOSTD + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) +#endif + + . = ALIGN(4); + + *(.rodata*) + +#ifdef CHIP_HAS_AUDIO_CONST_ROM + __audio_const_rom_start = .; + KEEP(*audio_const_rom.o(.audio_const_index)) + KEEP(*audio_const_rom.o(.rodata*)) + __audio_const_rom_end = .; + __audio_const_rom_size = __audio_const_rom_end - __audio_const_rom_start; +#endif +#ifndef NOSTD + KEEP(*(.eh_frame*)) +#endif + *(.note.gnu.build-id) + + . = ALIGN(4); + } > ROM + + .rom_got_info (.) : + { + __rom_got_info_start = .; + __rom_got_start = .; + *(.got) + . = ALIGN(4); + __rom_got_end = .; + __rom_got_plt_start = .; + *(.got.plt) + . = ALIGN(4); + __rom_igot_plt_start = .; + *(.igot.plt) + . = ALIGN(4); + __rom_dynamic_start = .; + *(.dynamic) + . = ALIGN(4); + __rom_got_info_end = .; + } > ROM + + .ARM.extab (.) : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > ROM + + __exidx_start = .; + .ARM.exidx (.) : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ROM + __exidx_end = .; + + . = ALIGN(4); + __rom_text0_end = .; + + .vector_table (ORIGIN(RAM)) (NOLOAD) : + { + KEEP(*(.vector_table)) + . = VECTOR_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .reboot_param (.) (NOLOAD) : + { + KEEP(*(.reboot_param)) + . = REBOOT_PARAM_SECTION_SIZE; + . = ALIGN(4); + } > RAM + + .rom_ramx (RAM_TO_RAMX(.)) : AT (__rom_text0_end) + { + __rom_ramx_start = .; + *(.rom_ramx) + . = ALIGN(4); + __rom_ramx_end = .; + } > RAMX + + __rom_etext = __rom_text0_end + SIZEOF(.rom_ramx); + + .rom_data (RAMX_TO_RAM(.)) : AT (__rom_etext) + { + __rom_data_start__ = .; + + *(.data*) + . = ALIGN(4); + +#ifndef NOSTD + *(vtable) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); +#endif + + /* All data end */ + __rom_data_end__ = .; + } > RAM + + .rom_bss (.) (NOLOAD) : AT (ADDR(.rom_bss)) + { + . = ALIGN(4); + __rom_bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __rom_bss_end__ = .; +#ifndef NOSTD + __bss_start__ = __rom_bss_start__; + __bss_end__ = __rom_bss_end__; +#endif + } > RAM + + .rom_heap (.) (NOLOAD) : + { + . = ALIGN(8); + __rom_HeapBase = .; +#ifndef NOSTD + __end__ = .; + end = __end__; + . += HEAP_SECTION_SIZE; +#endif + . = ALIGN(8); + __rom_HeapLimit = .; + } > RAM + + .scratch_buf (.) (NOLOAD) : + { + . = ALIGN(4); + *(.scratch_buf) + . = ALIGN(4); + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .rom_stack_dummy (.) (COPY) : + { + . = STACK_SECTION_SIZE; + . = ALIGN(8); + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __rom_StackTop = ORIGIN(RAM) + LENGTH(RAM); + __rom_StackLimit = __rom_StackTop - SIZEOF(.rom_stack_dummy); + PROVIDE(__rom_stack = __rom_StackTop); +#ifndef NOSTD + __StackTop = __rom_StackTop; + PROVIDE(__stack = __rom_StackTop); +#endif + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__rom_StackLimit >= __rom_HeapLimit, "region RAM overflowed with stack") + __free_rom_ram = __rom_StackLimit - __rom_HeapLimit; + + __rom_end = __rom_etext + SIZEOF(.rom_data); + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + .cp_ramx_last_dummy (NOLOAD) : + { + __cp_ramx_last_dummy_start = .; + } > RAMCPX + + .cp_ram_last_dummy (NOLOAD) : + { + . = ALIGN(8); + __cp_ram_last_dummy_start = .; + } > RAMCP + + __cp_stack_top = ORIGIN(RAMCP) + LENGTH(RAMCP); + __cp_stack_limit = __cp_stack_top - CP_STACK_SECTION_SIZE; + + __free_ramcpx = ORIGIN(RAMCPX) + LENGTH(RAMCPX) - __cp_ramx_last_dummy_start; + ASSERT(__cp_stack_limit >= __cp_ram_last_dummy_start, "region RAMCP overflowed with stack") + __free_ramcp = __cp_stack_limit - __cp_ram_last_dummy_start; +#endif + + .rom_export_fn (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE) : + { + __export_fn_rom = .; + KEEP(*(.export_fn)) + . = ROM_EXPORT_FN_SECTION_SIZE; + } > ROM = 0x00000000 + + .rom_build_info (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE) : + { + KEEP(*(.build_info)) + . = ROM_BUILD_INFO_SECTION_SIZE; + } > ROM = 0x00000000 + + ASSERT(ADDR(.rom_export_fn) >= __rom_end, "region ROM overflowed with .rom_export_fn") + __free_rom = ADDR(.rom_export_fn) - __rom_end; +} + diff --git a/scripts/link/rom.lds_scat.S b/scripts/link/rom.lds_scat.S new file mode 100644 index 0000000..f8cb897 --- /dev/null +++ b/scripts/link/rom.lds_scat.S @@ -0,0 +1,180 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "plat_addr_map.h" + +#ifdef NOSTD +#define HEAP_SECTION_SIZE 0 +#else +#define HEAP_SECTION_SIZE 0x40 +#endif +#define STACK_SECTION_SIZE 0x1000 +#define CP_STACK_SECTION_SIZE 0x1000 + +LR_rom ROM_BASE NOCOMPRESS +{ + rom_vectors +0 + { + *(.vectors, +FIRST) + } + + rom_text +0 FIXED + { + *(.text*) + +#ifndef NOSTD + *(InRoot$$Sections) + *armlib*(+TEXT) + *armlib*(+CONST) +#endif + + *(.rodata*) + } + +#ifdef CHIP_HAS_AUDIO_CONST_ROM + rom_audio_const +0 + { + *audio_const_rom.o(.audio_const_index) + *audio_const_rom.o(.rodata*) + } +#endif + + rom_build_id +0 + { +#ifndef NOSTD + *(.eh_frame*) +#endif + *(.note.gnu.build-id) + } + + rom_got_info +0 + { + *(.got) + *(.got.plt) + *(.igot.plt) + *(.dynamic) + } + + .ARM.extab +0 + { + *(.ARM.extab*, .gnu.linkonce.armextab.*) + } + + .ARM.exidx +0 + { + *(.ARM.exidx*, .gnu.linkonce.armexidx.*) + } + + rom_text0_end +0 EMPTY 0 + { + } + + vector_table RAM_BASE UNINIT VECTOR_SECTION_SIZE + { + *(.bss.vector_table, +FIRST) + } + + reboot_param (ImageBase(vector_table) + VECTOR_SECTION_SIZE) UNINIT REBOOT_PARAM_SECTION_SIZE + { + *(.bss.reboot_param, +FIRST) + } + + rom_ramx RAM_TO_RAMX(ImageBase(reboot_param) + REBOOT_PARAM_SECTION_SIZE) + { + *(.rom_ramx) + } + + rom_data RAMX_TO_RAM(+0) + { + *(.data*) + +#ifndef NOSTD + *armlib*(+DATA) +#endif + } + + rom_bss +0 UNINIT + { + *(.bss*) + *(COMMON) + +#ifndef NOSTD + *armlib*(+BSS) +#endif + } + + ARM_LIB_HEAP +0 ALIGN 8 EMPTY HEAP_SECTION_SIZE + { + } + + scratch_buf +0 UNINIT + { + *(.bss.scratch_buf) + } + + ARM_LIB_STACK (RAM_BASE + RAM_SIZE - STACK_SECTION_SIZE) ALIGN 8 EMPTY STACK_SECTION_SIZE + { + } + + /* Check if data + heap + stack exceeds RAM limit */ + ScatterAssert(ImageBase(ARM_LIB_STACK) >= ImageLimit(ARM_LIB_HEAP)) + ScatterAssert(ImageLimit(ARM_LIB_STACK) <= (RAM_BASE + RAM_SIZE)) + + free_ram ImageLimit(scratch_buf) EMPTY (ImageBase(ARM_LIB_STACK) - ImageLimit(scratch_buf)) + { + } + +#if defined(CHIP_HAS_CP) && (RAMCP_SIZE > 0) + cp_ramx_last_dummy RAMCPX_BASE EMPTY 0 + { + } + + cp_ram_last_dummy RAMCP_BASE EMPTY 0 + { + } + + cp_stack (RAMCP_BASE + RAMCP_SIZE - CP_STACK_SECTION_SIZE) EMPTY CP_STACK_SECTION_SIZE + { + } + + ScatterAssert(ImageBase(cp_stack) >= ImageLimit(cp_ram_last_dummy)) + ScatterAssert(ImageLimit(cp_stack) <= RAMCP_BASE + RAMCP_SIZE) +#endif +} + +LR_build_info +0 +{ + lr_build_info_start +0 FIXED EMPTY 0 + { + } + + rom_export_fn (ROM_BASE + ROM_SIZE - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE) FIXED + { + *(.export_fn) + } + + rom_build_info (ROM_BASE + ROM_SIZE - ROM_BUILD_INFO_SECTION_SIZE) FIXED + { + *(.build_info, +FIRST) + } + + free_rom ImageLimit(lr_build_info_start) EMPTY (ImageBase(rom_export_fn) - ImageLimit(lr_build_info_start)) + { + } + + ScatterAssert(LoadLimit(rom_build_info) <= (ROM_BASE + ROM_SIZE)) +} + diff --git a/scripts/submods.mk b/scripts/submods.mk new file mode 100644 index 0000000..1ac24c4 --- /dev/null +++ b/scripts/submods.mk @@ -0,0 +1,13 @@ +cur_makefile := $(lastword $(MAKEFILE_LIST)) + +$(cur_makefile): ; + +get_subdirs = $(foreach m, $(1), $(if $(filter $m/% $m,$(2)),$m,)) + +get_submodgoals = $(foreach m, \ + $(patsubst $(1)/%,%,$(filter $(1)/%,$(2))), \ + $(addprefix $(1)/,$(firstword $(subst /,$(space),$m)))) + +get_multi_objs = $(addprefix $(obj)/, $($(subst $(obj)/,,$(1:.o=-objs))) \ + $($(subst $(obj)/,,$(1:.o=-objs)))) + diff --git a/scripts/submods_init.mk b/scripts/submods_init.mk new file mode 100644 index 0000000..790de6b --- /dev/null +++ b/scripts/submods_init.mk @@ -0,0 +1,24 @@ +cur_makefile := $(lastword $(MAKEFILE_LIST)) + +$(cur_makefile): ; + +ifeq ($(WIN_PLAT),y) +SUBMODGOALS := $(sort $(foreach m, $(MAKECMDGOALS), \ + $(if $(filter-out ./,$(wildcard $(dir $(subst \,/,$m)) $(subst \,/,$m))),$m,))) +else + SUBMODGOALS := $(sort $(foreach m, $(MAKECMDGOALS), \ + $(if $(filter-out ./,$(wildcard $(dir $m) $m)),$m,))) +endif + +ifneq ($(SUBMODGOALS),) +MAKECMDGOALS := $(filter-out $(SUBMODGOALS),$(MAKECMDGOALS)) +ifeq ($(WIN_PLAT),y) +SUBMODGOALS := $(subst \,/,$(SUBMODGOALS)) +endif +SUBMODS := $(patsubst $(CURDIR)/%,%,$(SUBMODGOALS)) +SUBMODS := $(patsubst %/,%,$(SUBMODS)) +# Filter out subdirectories if their parent directories already in SUBMODS +SUBMODS := $(filter-out $(addsuffix /%,$(SUBMODS)),$(SUBMODS)) +export SUBMODS +endif + diff --git a/services/Makefile b/services/Makefile new file mode 100644 index 0000000..55c7150 --- /dev/null +++ b/services/Makefile @@ -0,0 +1,133 @@ +obj-y := audio_dump/ \ + audioflinger/ \ + audio_process/ \ + hw_dsp/ \ + bt_app/ \ + overlay/ \ + resources/ \ + ../utils/crc32/ \ + ../utils/crc16/ \ + ../utils/heap/ \ + osif/ \ + norflash_api/ \ + +ifeq ($(BONE_SENSOR_TDM),1) +obj-y += bone_sensor/ +endif + +ifneq ($(INTERCONNECTION)_$(AI_VOICE),0_0) +obj-y += interconnection/ +endif + +ifeq ($(ENHANCED_STACK),1) +obj-y += bt_profiles_enhanced/ +obj-y += bt_if_enhanced/ +else +obj-y += bt_profiles/ +obj-y += bt_if/ +endif + +ifeq ($(MBED),1) +obj-y += fs/ +endif + +ifneq ($(MBED)_$(AI_VOICE),0_0) +obj-y +=../utils/kfifo/ +endif + +ifeq ($(VOICE_DATAPATH_ENABLED),1) +obj-y += voicepath/ +obj-y += voicepath/$(VOICE_DATAPATH_TYPE)/ +endif + +ifneq ($(VOICE_DATAPATH_ENABLED)_$(AI_VOICE),0_0) +obj-y += app_ai/ +endif + +ifeq ($(BLE),1) +obj-y += ble_app/ \ + bridge/ \ + ble_stack/ \ + ../utils/retention_ram/ \ + ble_profiles/ +endif + +ifeq ($(AUTO_TEST),1) +obj-y += auto_test/ +endif + +obj-y += nv_section/ + +ifneq ($(FPGA),1) +obj-y += nvrecord/ +endif + +ifeq ($(VOICE_RECOGNITION),1) +obj-y += voice_recognition/ +endif + +ifeq ($(APP_ANC_TEST),1) +obj-y += anc_spp_tool/ +endif + +ifeq ($(TEST_OVER_THE_AIR),1) +obj-y += tota/ +endif + +ifeq ($(OTA_ENABLE),1) +ifeq ($(IBRT),1) +ifeq ($(FPGA_IBRT_OTA),1) +obj-y += fpga_ibrt_ota/ +else +obj-y += ibrt_ota/ +endif +else +endif +ifeq ($(OTA_ENABLE), 1) +obj-y += ota/ +endif +endif + +ifeq ($(TILE_DATAPATH_ENABLED),1) +obj-y += ../thirdparty/tile/ +endif + +ifeq ($(AI_VOICE),1) +obj-y += ai_voice/ +endif + +ifeq ($(CHIP_HAS_CP),1) +obj-y += cp_accel/ +endif + +ifeq ($(IBRT),1) +obj-y += ibrt_core/ +obj-y += app_ibrt/ +obj-y += ibrt_ui/ +endif + +ifeq ($(TWS_SYSTEM_ENABLED),1) +obj-y += app_tws/ +endif + +ifeq ($(RSA_SHA),1) +obj-y +=../utils/sha256/ ../utils/rsa2048/ +endif + +ifeq ($(AES256_FOR_BIN),1) +obj-y +=../utils/aes256/ +endif + +obj-y += communication/ + +ifeq ($(RPC_SUPPORT),1) +obj-y += rpc/ +endif + +ifeq ($(A2DP_LHDC_ON),1) +obj-y += lhdc_license/ +endif + +ifeq ($(THROUGH_PUT),1) +obj-y += through_put/ +endif diff --git a/services/anc_spp_tool/Makefile b/services/anc_spp_tool/Makefile new file mode 100644 index 0000000..2c1a0f9 --- /dev/null +++ b/services/anc_spp_tool/Makefile @@ -0,0 +1,46 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +src_obj := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ANC_TEST_LIB_NAME := libanc_spp_tool + +$(ANC_TEST_LIB_NAME)-y := $(src_obj) + +obj-y += $(ANC_TEST_LIB_NAME).a + +ccflags-y += -Iutils/hexdump \ + -Iapps/key \ + -Iservices/bt_app \ + -Iservices/bt_if/inc \ + -Iplatform/drivers/ana \ + -Iservices/multimedia/audio/process/anc/include \ + -Iservices/audioflinger \ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/include \ + -Iservices/audio_eq \ + -Iservices/tota \ + -Iplatform/hal \ + -Iplatform/drivers/norflash \ + -Iservices/multimedia/audio/process/filters/include \ + -Iutils/crc32 \ + -Iutils/boot_struct \ + -Iutils/libc/inc \ + -Iutils/hwtimer_list \ + -Iutils/heap \ + -Iservices/tws/inc \ + -Iutils/cqueue \ + -Iapps/audioplayers + + +ifeq ($(ANC_FF_ENABLED),1) +CFLAGS_anc_usb_app.o += -DANC_FF_ENABLED +endif + +ifeq ($(ANC_FB_ENABLED),1) +CFLAGS_anc_usb_app.o += -DANC_FB_ENABLED +endif + diff --git a/services/anc_spp_tool/anc_parse_data.h b/services/anc_spp_tool/anc_parse_data.h new file mode 100644 index 0000000..4d026fe --- /dev/null +++ b/services/anc_spp_tool/anc_parse_data.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ANC_PARSE_DATA_H__ +#define __ANC_PARSE_DATA_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "tool_msg.h" +#include "crc32.h" +// #include "app_tws.h" + +#define COMMAND_PARSER_VERSION 0x0100 + +#define ANC_PARSE_DATA_BUFF_SIZE ((8 * 1024 + BURN_DATA_MSG_OVERHEAD + 63) / 64 * 64) +#define ANC_PARSE_DATA_BUFF_OFFSET (PCM_BUFFER_SZ_TWS+TRANS_BUFFER_SZ_TWS+A2DP_BUFFER_SZ_TWS - ANC_PARSE_DATA_BUFF_SIZE) + +#define ANC_SHARE_BUF 0 + +#define BURN_BUFFER_LOC + +enum PROGRAMMER_STATE{ + PROGRAMMER_NONE, + PROGRAMMER_ERASE_BURN_START, + PROGRAMMER_BULK_WRITE_START, +}; + +enum DATA_BUF_STATE { + DATA_BUF_FREE, + DATA_BUF_RECV, + DATA_BUF_BURN, + DATA_BUF_DONE, +}; + +enum FLASH_CMD_TYPE { + FLASH_CMD_ERASE_SECTOR = 0x21, + FLASH_CMD_BURN_DATA = 0x22, + FLASH_CMD_ERASE_CHIP = 0x31, +}; + +enum CUST_CMD_STAGE { + CUST_CMD_STAGE_HEADER, + CUST_CMD_STAGE_DATA, + CUST_CMD_STAGE_EXTRA, + + CUST_CMD_STAGE_QTY +}; + +struct CUST_CMD_PARAM { + enum CUST_CMD_STAGE stage; + const struct message_t *msg; + int extra; + unsigned char *buf; + size_t expect; + size_t size; + unsigned int timeout; +}; + +typedef enum ERR_CODE (*CUST_CMD_HANDLER_T)(struct CUST_CMD_PARAM *param); + +#define CUST_CMD_HDLR_TBL_LOC __attribute__((section(".cust_cmd_hldr_tbl"), used)) +#define TIMEOUT_INFINITE ((uint32_t)-1) + +extern struct message_t recv_msg; + +/** + * @brief + * Data transmission will be slightly slower in sniff mode. PC Tool may disconnet SPP connection + * because of command response timed out. We should always in active mode to work around this case. + */ +extern void anc_data_buff_init(void); +extern void anc_data_buff_deinit(void); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/app_ai/Makefile b/services/app_ai/Makefile new file mode 100644 index 0000000..1ae58ca --- /dev/null +++ b/services/app_ai/Makefile @@ -0,0 +1,58 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)/src/*.cpp)) + +ifeq ($(BISTO_ENABLE),0) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)voice_sbc/*.cpp)) +endif + +ifeq ($(ANC_APP),1) +CFLAGS_app_ai_if.o += -DANC_APP +endif + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +subdir-ccflags-y += -Iapps/audioplayers \ + -Iapps/common \ + -Iapps/key \ + -Iapps/main \ + -Iplatform/drivers/bt \ + -Iplatform/hal \ + -Iservices/ai_voice/audio \ + -Iservices/ai_voice/transport \ + -Iservices/ai_voice/manager \ + -Iservices/ai_voice/protocol/ama/ama_stream \ + -Iservices/audio_dump/include \ + -Iservices/app_ai/inc \ + -Iservices/app_ibrt/inc \ + -Iservices/app_tws/inc \ + -Iservices/ble_app/app_main \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/ble_ip \ + $(BT_IF_INCLUDES) \ + -Iservices/bt_app \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/speech/inc \ + -Iservices/norflash_api \ + -Iservices/nvrecord \ + -Iservices/ibrt_core/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/ble_stack/common/api \ + -Iservices/ble_stack/hl/inc \ + -Iservices/ble_stack/ke/api \ + -Iservices/cp_accel \ + -Iservices/resources \ + -Iservices/through_put \ + -Iservices/voicepath \ + -Iservices/voicepath/gsound/gsound_custom/inc \ + -Iservices/voicepath/gsound/gsound_target \ + -Iservices/voicepath/gsound/gsound_target_api_read_only \ + -Ithirdparty/userapi \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iapps/anc/inc diff --git a/services/app_ai/inc/app_ai_algorithm.h b/services/app_ai/inc/app_ai_algorithm.h new file mode 100644 index 0000000..9774cfc --- /dev/null +++ b/services/app_ai/inc/app_ai_algorithm.h @@ -0,0 +1,61 @@ +#ifndef APP_AI_ALGORITHM_H_ +#define APP_AI_ALGORITHM_H_ + +//the ai aec data cache state +typedef enum { + AI_AEC_CACHE_IDLE, + AI_AEC_CACHE_CACHED, + AI_AEC_CACHE_PROCESSED, +} AI_AEC_CACHE_STATE_E; + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + * app_ai_algorithm_mic_data_handle + *--------------------------------------------------------------------------- + * + *Synopsis: + * use algorithm to handle the data that cuptrued from mic + * + * Parameters: + * uint8_t *buf + * uint32_t length + * + * Return: + * void + */ +void app_ai_algorithm_mic_data_handle(uint8_t *buf, uint32_t length); + +/*--------------------------------------------------------------------------- + * app_ai_algorithm_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * initialize AI algorithm + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_algorithm_init(void); + +void cp_aec_init(void); +void cp_aec_deinit(void); + +#ifdef __cplusplus + } +#endif + + +#endif //APP_AI_ALGORITHM_H_ + diff --git a/services/app_ai/inc/app_ai_if.h b/services/app_ai/inc/app_ai_if.h new file mode 100644 index 0000000..2f3bfb9 --- /dev/null +++ b/services/app_ai/inc/app_ai_if.h @@ -0,0 +1,197 @@ +#ifndef AI_IF_H_ +#define AI_IF_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "app_ai_if_config.h" +#include "bluetooth.h" + +#if (VOB_ENCODING_ALGORITHM == ENCODING_ALGORITHM_OPUS) +#if defined(SPEECH_CAPTURE_TWO_CHANNEL) +#define APP_AI_IF_CAPTURE_BUFFER_SIZE (76*1024) +#elif defined(__DUAL_MIC_RECORDING__) +#define APP_AI_IF_CAPTURE_BUFFER_SIZE (79*1024) +#else +#define APP_AI_IF_CAPTURE_BUFFER_SIZE (63*1024) +#endif +#elif (VOB_ENCODING_ALGORITHM == ENCODING_ALGORITHM_SBC) +#if defined(CHIP_BEST1400) +#define APP_AI_IF_CAPTURE_BUFFER_SIZE (13*1024) +#else +#define APP_AI_IF_CAPTURE_BUFFER_SIZE (17*1024) +#endif +#endif + +//the ai type now use +typedef enum { + AI_SPEC_INIT, + AI_SPEC_GSOUND, + AI_SPEC_AMA, + AI_SPEC_BES, + AI_SPEC_BAIDU, + AI_SPEC_TENCENT, + AI_SPEC_ALI, + AI_SPEC_COMMON, + AI_SPEC_RECORDING, + AI_SPEC_COUNT, +} AI_SPEC_TYPE_E; + +typedef struct{ + uint8_t connPathType; + uint8_t connPathState; + uint8_t connBtState; + uint8_t connBdAddr[6]; +}AI_CONNECTION_STATE_T; + +typedef struct{ + uint8_t *buff; + uint32_t buff_size_total; + uint32_t buff_size_used; + uint32_t buff_size_free; +}AI_CAPTURE_BUFFER_T; + +#ifdef __cplusplus +extern "C" { +#endif + +const char *ai_spec_type2str(AI_SPEC_TYPE_E ai_spec); + +/*--------------------------------------------------------------------------- + * app_ai_key_event_handle + *--------------------------------------------------------------------------- + * + *Synopsis: + * for AI handle key event + * + * Parameters: + * void *param1 + * uint32_t param2 + * + * Return: + * void + */ +void app_ai_key_event_handle(void *param1, uint32_t param2); + +/*--------------------------------------------------------------------------- + * app_ai_if_get_ai_spec + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get the ai current spec + * + * Parameters: + * void + * + * Return: + * uint32_t -- ai spec + */ +uint32_t app_ai_if_get_ai_spec(void); + +/*--------------------------------------------------------------------------- + * app_ai_if_mobile_connect_handle + *--------------------------------------------------------------------------- + * + *Synopsis: + * handle ai when mobile connect + * + * Parameters: + * _addr -- the address of connected mobile + * + * Return: + * void + */ +void app_ai_if_mobile_connect_handle(bt_bdaddr_t *_addr); + +/*--------------------------------------------------------------------------- + * app_ai_voice_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * init ai voice + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_voice_init(void); + +/*--------------------------------------------------------------------------- + * ai_if_is_ai_stream_mic_open + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get whether ai stream is opened + * + * Parameters: + * void + * + * Return: + * bool true means ai stream is opened + */ +bool ai_if_is_ai_stream_mic_open(void); + +/*--------------------------------------------------------------------------- + * app_ai_if_get_ble_connection_index + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get ai ble connection index + * + * Parameters: + * void + * + * Return: + * uint8_t -- ble connection index + */ +uint8_t app_ai_if_get_ble_connection_index(void); + +/*--------------------------------------------------------------------------- +* app_ai_if_mempool_deinit +*--------------------------------------------------------------------------- +* +*Synopsis: +* init ai voice capture mempool +* +* Parameters: +* void +* +* Return: +* void +*/ +void app_ai_if_mempool_deinit(void); + +/*--------------------------------------------------------------------------- +* app_ai_if_mempool_get_buff +*--------------------------------------------------------------------------- +* +*Synopsis: +* get buf form ai voice capture mempool +* +* Parameters: +* buff -- the pointer of buf that get from mempool +* size -- the size of buf that get from mempool +* +* Return: +* void +*/ +void app_ai_if_mempool_get_buff(uint8_t **buff, uint32_t size); + +void app_ai_if_inform_music_or_prompt_status(bool isOn, uint32_t sampleRate); + +bool app_ai_if_is_music_or_prompt_ongoing(void); + +uint32_t app_ai_if_get_music_or_prompt_sample_rate(void); + +void app_ai_if_pre_music_or_prompt_check(void); + +#ifdef __cplusplus + } +#endif + + +#endif //AI_IF_H_ + diff --git a/services/app_ai/inc/app_ai_if_config.h b/services/app_ai/inc/app_ai_if_config.h new file mode 100644 index 0000000..22288e2 --- /dev/null +++ b/services/app_ai/inc/app_ai_if_config.h @@ -0,0 +1,43 @@ +#ifndef APP_AI_IF_CONFIG_H_ +#define APP_AI_IF_CONFIG_H_ + +#ifdef __KNOWLES +#define DIG_MIC_WORKAROUND +#define KNOWLES_UART_DATA +#endif + +#ifdef __AMA_VOICE__ +//#define PUSH_AND_HOLD_ENABLED +//#define AI_32KBPS_VOICE +//#define NO_LOCAL_START_TONE +#endif + +#ifdef __DMA_VOICE__ +//#define PUSH_AND_HOLD_ENABLED +//#define AI_32KBPS_VOICE + +#define FLOW_CONTROL_ON_UPLEVEL +#define ASSAM_PKT_ON_UPLEVEL +#define CLOSE_BLE_ADV_WHEN_VOICE_CALL +#define CLOSE_BLE_ADV_WHEN_SPP_CONNECTED +#define BAIDU_RFCOMM_DIRECT_CONN +#define BYPASS_SLOW_ADV_MODE +#endif + +#ifdef __SMART_VOICE__ +#define PUSH_AND_HOLD_ENABLED +//#define AI_32KBPS_VOICE +#endif + +#ifdef __TENCENT_VOICE__ +#define PUSH_AND_HOLD_ENABLED +//#define AI_32KBPS_VOICE +#endif + +#ifdef __GMA_VOICE__ +//#define PUSH_AND_HOLD_ENABLED +//#define AI_32KBPS_VOICE +#endif + +#endif //APP_AI_IF_CONFIG_H_ + diff --git a/services/app_ai/inc/app_ai_if_custom_ui.h b/services/app_ai/inc/app_ai_if_custom_ui.h new file mode 100644 index 0000000..88c9307 --- /dev/null +++ b/services/app_ai/inc/app_ai_if_custom_ui.h @@ -0,0 +1,51 @@ +#ifndef APP_AI_IF_CUSTOM_UI_H_ +#define APP_AI_IF_CUSTOM_UI_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + * app_ai_if_custom_ui_send_cmd + *--------------------------------------------------------------------------- + * + *Synopsis: + * for custom to send cmd + * + * Parameters: + * cmd_buf -- cmd data buff + * cmd_len -- cmd data length + * + * Return: + * void + */ +bool app_ai_if_custom_ui_send_cmd(uint8_t *cmd_buf,uint16_t cmd_len); + +/*--------------------------------------------------------------------------- + * app_ai_if_custom_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * init custom + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_if_custom_init(void); + +#ifdef __cplusplus + } +#endif + + +#endif //APP_AI_IF_CUSTOM_UI_H_ + diff --git a/services/app_ai/inc/app_ai_if_gsound.h b/services/app_ai/inc/app_ai_if_gsound.h new file mode 100644 index 0000000..46b3c3f --- /dev/null +++ b/services/app_ai/inc/app_ai_if_gsound.h @@ -0,0 +1,35 @@ +#ifndef APP_AI_IF_GSOUND_H_ +#define APP_AI_IF_GSOUND_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + * app_ai_if_gsound_service_enable_switch + *--------------------------------------------------------------------------- + * + *Synopsis: + * give the interface to AI to control gsound switch + * + * Parameters: + * onOff -- control gsound enable or not + * + * Return: + * void + */ +void app_ai_if_gsound_service_enable_switch(bool onOff); + +#ifdef __cplusplus + } +#endif + + +#endif //APP_AI_IF_GSOUND_H_ + diff --git a/services/app_ai/inc/app_ai_if_thirdparty.h b/services/app_ai/inc/app_ai_if_thirdparty.h new file mode 100644 index 0000000..c8757c1 --- /dev/null +++ b/services/app_ai/inc/app_ai_if_thirdparty.h @@ -0,0 +1,150 @@ +#ifndef APP_AI_IF_THIRDPARTY_H_ +#define APP_AI_IF_THIRDPARTY_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "app_thirdparty.h" + +#if defined(__ALEXA_WWE_LITE) +#ifdef VOICE_DETECTOR_EN +#if defined(CHIP_BEST2300A) +#define APP_AI_IF_THIRDPARTY_MEMPOOL_BUFFER_SIZE (127*1024) +#else +#define APP_AI_IF_THIRDPARTY_MEMPOOL_BUFFER_SIZE (111*1024) +#endif +#else +#define APP_AI_IF_THIRDPARTY_MEMPOOL_BUFFER_SIZE (99*1024) +#endif +#elif defined(GSOUND_HOTWORD_EXTERNAL) +#define APP_AI_IF_THIRDPARTY_MEMPOOL_BUFFER_SIZE (68*1024) +#else +#define APP_AI_IF_THIRDPARTY_MEMPOOL_BUFFER_SIZE (0) +#endif + +typedef struct{ + uint8_t *buff; + uint32_t buff_size_total; + uint32_t buff_size_used; + uint32_t buff_size_free; +}THIRDPARTY_AI_MEMPOOL_BUFFER_T; + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- +* app_ai_if_thirdparty_mempool_init +*--------------------------------------------------------------------------- +* +*Synopsis: +* init ai voice thirdparty mempool +* +* Parameters: +* void +* +* Return: +* void +*/ +POSSIBLY_UNUSED void app_ai_if_thirdparty_mempool_init(void); + +/*--------------------------------------------------------------------------- +* app_ai_if_thirdparty_mempool_deinit +*--------------------------------------------------------------------------- +* +*Synopsis: +* init ai voice thirdparty mempool +* +* Parameters: +* void +* +* Return: +* void +*/ +void app_ai_if_thirdparty_mempool_deinit(void); + +/*--------------------------------------------------------------------------- +* app_ai_if_thirdparty_mempool_get_buff +*--------------------------------------------------------------------------- +* +*Synopsis: +* get buf form ai voice thirdparty mempool +* +* Parameters: +* buff -- the pointer of buf that get from mempool +* size -- the size of buf that get from mempool +* +* Return: +* void +*/ +void app_ai_if_thirdparty_mempool_get_buff(uint8_t **buff, uint32_t size); + +/*--------------------------------------------------------------------------- +* app_ai_if_thirdparty_start_stream_by_app_audio_manager +*--------------------------------------------------------------------------- +* +*Synopsis: +* start mic stream of thirdparty +* +* Parameters: +* void +* +* Return: +* void +*/ +void app_ai_if_thirdparty_start_stream_by_app_audio_manager(void); + +/*--------------------------------------------------------------------------- +* app_ai_if_thirdparty_stop_stream_by_app_audio_manager +*--------------------------------------------------------------------------- +* +*Synopsis: +* stop mic stream of thirdparty +* +* Parameters: +* void +* +* Return: +* void +*/ +void app_ai_if_thirdparty_stop_stream_by_app_audio_manager(void); + +/*--------------------------------------------------------------------------- + * app_ai_if_thirdparty_event_handle + *--------------------------------------------------------------------------- + * + *Synopsis: + * for AI use thirdparty event handle + * + * Parameters: + * funcId -- function ID + * event_type event type ID + * + * Return: + * void + */ +int app_ai_if_thirdparty_event_handle(THIRDPARTY_FUNC_ID funcId, THIRDPARTY_EVENT_TYPE event_type); + +/*--------------------------------------------------------------------------- + * app_ai_if_thirdparty_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * for AI init thirdparty + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_if_thirdparty_init(void); + +#ifdef __cplusplus + } +#endif + + +#endif //APP_AI_IF_THIRDPARTY_H_ + diff --git a/services/app_ai/inc/app_ai_manager_api.h b/services/app_ai/inc/app_ai_manager_api.h new file mode 100644 index 0000000..6ed819e --- /dev/null +++ b/services/app_ai/inc/app_ai_manager_api.h @@ -0,0 +1,251 @@ +#ifndef APP_AI_MANAGER_API_H_ +#define APP_AI_MANAGER_API_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "app_ai_if.h" + + +#define MAI_TYPE_REBOOT_WITHOUT_OEM_APP + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + * app_ai_manager_is_in_multi_ai_mode + *--------------------------------------------------------------------------- + * + *Synopsis: + * to know ai manager is in multi ai mode or not + * + * Parameters: + * void + * + * Return: + * bool -- true is in multi ai mode + */ +bool app_ai_manager_is_in_multi_ai_mode(void); + +/*--------------------------------------------------------------------------- + * app_ai_manager_voicekey_is_enable + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get the voicekey is enable or not + * + * Parameters: + * void + * + * Return: + * bool -- true: voice key is enable + */ +bool app_ai_manager_voicekey_is_enable(void); + +/*--------------------------------------------------------------------------- + * app_ai_manager_voicekey_save_status + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager save voice key status + * + * Parameters: + * state -- the voice key status + * + * Return: + * void + */ +void app_ai_manager_voicekey_save_status(bool state); + +/*--------------------------------------------------------------------------- + * app_ai_manager_switch_spec + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager switch ai spec + * + * Parameters: + * ai_spec -- the ai spec want to switch + * + * Return: + * void + */ +void app_ai_manager_switch_spec(AI_SPEC_TYPE_E ai_spec); + +/*--------------------------------------------------------------------------- + * app_ai_manager_set_current_spec + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager set current ai spec + * + * Parameters: + * ai_spec -- the ai spec need to set + * + * Return: + * void + */ +void app_ai_manager_set_current_spec(AI_SPEC_TYPE_E ai_spec); + +/*--------------------------------------------------------------------------- + * app_ai_manager_get_current_spec + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager get current ai spec + * + * Parameters: + * bool + * + * Return: + * ai_spec -- the current ai spec + */ +uint8_t app_ai_manager_get_current_spec(void); + +/*--------------------------------------------------------------------------- + * app_ai_manager_is_need_reboot + *--------------------------------------------------------------------------- + * + *Synopsis: + * check if ai manager need to reboot + * + * Parameters: + * void + * + * Return: + * bool -- true is need to reboot + */ +bool app_ai_manager_is_need_reboot(void); + +/*--------------------------------------------------------------------------- + * app_ai_manager_enable + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager set a ai_spec enable or disable + * + * Parameters: + * isEnabled -- true is set the spec enable; false is disable + * ai_spec -- the ai spec you want to operate + * + * Return: + * void + */ +void app_ai_manager_enable(bool isEnabled, AI_SPEC_TYPE_E ai_spec); + +/*--------------------------------------------------------------------------- + * app_ai_manager_set_spec_connected_status + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager set a ai_spec connect status + * + * Parameters: + * ai_spec -- the ai spec you want to operate + * connected -- true is set the spec connected; false is disconnected + * + * Return: + * void + */ +void app_ai_manager_set_spec_connected_status(AI_SPEC_TYPE_E ai_spec, uint8_t connected); + +/*--------------------------------------------------------------------------- + * app_ai_manager_get_spec_connected_status + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager get a ai_spec connect status + * + * Parameters: + * ai_spec -- the ai spec you want to operate + * + * Return: + * int8_t -- 1 is the spec connected; 0 is disconnected; -1 is invalue + */ +int8_t app_ai_manager_get_spec_connected_status(uint8_t ai_spec); + +/*--------------------------------------------------------------------------- + * app_ai_manager_spec_get_status_is_in_invalid + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager get a ai_spec invalue status + * + * Parameters: + * ai_spec -- the ai spec you want to operate + * + * Return: + * bool -- true is the spec invalue; false is value + */ +bool app_ai_manager_spec_get_status_is_in_invalid(void); + +/*--------------------------------------------------------------------------- + * app_ai_manager_set_spec_update_flag + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager set spec update flag, when this flag seted, AI entry switch spec status. + * And then reboot + * + * Parameters: + * onOff -- true is AI entry switch spec status + * + * Return: + * void + */ +void app_ai_manager_set_spec_update_flag(bool onOff); + +/*--------------------------------------------------------------------------- + * app_ai_manager_get_spec_update_flag + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager get spec update flag + * + * Parameters: + * void + * + * Return: + * bool -- true is AI entry switch spec status + */ +bool app_ai_manager_get_spec_update_flag(void); + +/*--------------------------------------------------------------------------- + * app_ai_manager_spec_update_start_reboot + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager update spec, start reboot now + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_manager_spec_update_start_reboot(void); + +/*--------------------------------------------------------------------------- + * app_ai_manager_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager init + * + * Parameters: + * void + * + * Return: + * bool + */ +void app_ai_manager_init(void); + +#ifdef __cplusplus + } +#endif + + +#endif //APP_AI_MANAGER_API_H_ + diff --git a/services/app_ai/inc/app_ai_tws.h b/services/app_ai/inc/app_ai_tws.h new file mode 100644 index 0000000..859a7e9 --- /dev/null +++ b/services/app_ai/inc/app_ai_tws.h @@ -0,0 +1,422 @@ +#ifndef APP_AI_TWS_H_ +#define APP_AI_TWS_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#define APP_AI_TWS_MASTER 0 +#define APP_AI_TWS_SLAVE 1 +#define APP_AI_TWS_UNKNOW 0xff + + +typedef struct +{ + bool is_ai_reboot; + uint8_t box_state; +} APP_AI_TWS_REBOOT_T; + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + * app_ai_ibrt_role_switch_direct + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai ibrt role switch direct + * + * Parameters: + * void + * + * Return: + * bool false -- switch direct, don't need prepare + * true -- tws role switch need prepare + */ +bool app_ai_tws_role_switch_direct(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_role_switch_dis_ble + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai disconnect ble before role switch + * + * Parameters: + * void + * + * Return: + * bool false -- switch direct, don't need prepare + * true -- tws role switch need prepare + */ +bool app_ai_tws_role_switch_dis_ble(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_master_role_switch_prepare + *--------------------------------------------------------------------------- + * + *Synopsis: + * master role switch API for AI module + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_tws_master_role_switch_prepare(void); + +/*--------------------------------------------------------------------------- + * app_ai_role_switch_prepare + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai role switch prepare, give a time to ibrt for role switch + * + * Parameters: + * void + * + * Return: + * uint32_t return the AI now use + */ +uint32_t app_ai_ibrt_role_switch_prepare(uint32_t *wait_ms); + +/*--------------------------------------------------------------------------- + * app_ai_tws_role_switch_prepare_done + *--------------------------------------------------------------------------- + * + *Synopsis: + * master role switch prepare done, slave receive a masegge from master + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_tws_role_switch_prepare_done(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_role_switch_prepare + *--------------------------------------------------------------------------- + * + *Synopsis: + * AI interface controlled tws role switch API + * + * Parameters: + * wait_ms - time delay before role switch started for AI module + * + * Return: + * true - need delay + * false - not need delay + */ +uint32_t app_ai_tws_role_switch_prepare(uint32_t *wait_ms); + +/*--------------------------------------------------------------------------- + * app_ai_tws_role_switch + *--------------------------------------------------------------------------- + * + *Synopsis: + * role switch API for AI module + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_tws_role_switch(void); + +/*--------------------------------------------------------------------------- +* app_ai_tws_role_switch_complete +*--------------------------------------------------------------------------- +* +*Synopsis: +* when ibrt role switch done, call this function +* +* Parameters: +* void +* +* Return: +* bool +*/ +void app_ai_tws_role_switch_complete(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_sync_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai tws sync init + * + * Parameters: + * void + * + * Return: + * bool + */ +void app_ai_tws_sync_init(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_sync_info + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai tws synchronize AI info + * + * Parameters: + * void + * + * Return: + * bool + */ +void app_ai_tws_sync_ai_info(void); + +/*--------------------------------------------------------------------------- + * ai_manager_sync_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai manager sync init + * + * Parameters: + * void + * + * Return: + * bool + */ +void ai_manager_sync_init(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_sync_ai_manager_info + *--------------------------------------------------------------------------- + * + *Synopsis: + * app ai tws synchronize AI manager info + * + * Parameters: + * void + * + * Return: + * bool + */ +void app_ai_tws_sync_ai_manager_info(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_gsound_sync_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * gsound related environment initialization for AI interface + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_tws_gsound_sync_init(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_send_cmd_to_peer + *--------------------------------------------------------------------------- + * + *Synopsis: + * for AI send cmd to peer + * + * Parameters: + * uint8_t *p_buff -- the cmd pointer + * uint16_t length -- the cmd length + * + * Return: + * void + */ +void app_ai_tws_send_cmd_to_peer(uint8_t *p_buff, uint16_t length); + +/*--------------------------------------------------------------------------- + * app_ai_tws_rev_peer_cmd_hanlder + *--------------------------------------------------------------------------- + * + *Synopsis: + * for AI handle the cmd receive from peer + * + * Parameters: + * uint16_t rsp_seq -- seq number + * uint8_t *p_buff -- the cmd pointer + * uint16_t length -- the cmd length + * + * Return: + * void + */ +void app_ai_tws_rev_peer_cmd_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +void app_ai_tws_send_cmd_with_rsp_to_peer(uint8_t *p_buff, uint16_t length); + +void app_ai_tws_send_cmd_rsp_to_peer(uint8_t *p_buff, uint16_t rsp_seq, uint16_t length); + +void app_ai_tws_rev_peer_cmd_with_rsp_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +void app_ai_tws_rev_cmd_rsp_from_peer_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +void app_ai_tws_rev_cmd_rsp_timeout_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +/*--------------------------------------------------------------------------- + * app_ai_tws_init_done + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get tws init status + * + * Parameters: + * void + * + * Return: + * bool -- true is tws init done + */ +bool app_ai_tws_init_done(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_link_connected + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get tws connect status + * + * Parameters: + * void + * + * Return: + * bool -- true is tws connected + */ +bool app_ai_tws_link_connected(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_local_address + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get tws local address + * + * Parameters: + * void + * + * Return: + * uint8_t -- the address of local + */ +uint8_t *app_ai_tws_local_address(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_peer_address + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get tws peer address + * + * Parameters: + * void + * + * Return: + * uint8_t -- the address of peer + */ +uint8_t *app_ai_tws_peer_address(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_reboot_record_box_state + *--------------------------------------------------------------------------- + * + *Synopsis: + * record the current state of box before reboot + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_tws_reboot_record_box_state(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_reboot_get_box_action + *--------------------------------------------------------------------------- + * + *Synopsis: + * return a box action due to the box state before reboot + * + * Parameters: + * void + * + * Return: + * uint8_t box action + */ +uint8_t app_ai_tws_reboot_get_box_action(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_clear_reboot_box_state + *--------------------------------------------------------------------------- + * + *Synopsis: + * clear the current state of box before reboot + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_tws_clear_reboot_box_state(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_disconnect_all_bt_connection + *--------------------------------------------------------------------------- + * + *Synopsis: + * ai disconnect all bt connection + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_tws_disconnect_all_bt_connection(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_get_local_role + *--------------------------------------------------------------------------- + * + *Synopsis: + * get tws local role + * + * Parameters: + * void + * + * Return: + * uint8_t -- the role of local + */ +uint8_t app_ai_tws_get_local_role(void); + +/*--------------------------------------------------------------------------- + * app_ai_tws_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * init tws for ai + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ai_tws_init(void); + +#ifdef __cplusplus + } +#endif + + +#endif //APP_AI_TWS_H_ + diff --git a/services/app_ai/src/app_ai_algorithm.cpp b/services/app_ai/src/app_ai_algorithm.cpp new file mode 100644 index 0000000..d5d8819 --- /dev/null +++ b/services/app_ai/src/app_ai_algorithm.cpp @@ -0,0 +1,411 @@ +#ifdef AI_ALGORITHM_ENABLE + +#include "cmsis_os.h" +#include "hal_aud.h" +#include "hal_location.h" +#include "hal_trace.h" +#include "app_ai_algorithm.h" +#include "cqueue.h" +#include "heap_api.h" +#include "audio_dump.h" +#include "norflash_api.h" + +#ifdef BISTO_ENABLED +#include "app_voicepath.h" +#endif + +#ifdef AI_CAPTURE_DATA_AEC +#include "echo_canceller.h" +#endif + +#ifdef AI_AEC_CP_ACCEL +#include "cp_accel.h" +#define AI_TEXT_SRAM_LOC CP_TEXT_SRAM_LOC +#define AI_CP_BSS_LOC CP_BSS_LOC +#else +#define AI_TEXT_SRAM_LOC +#define AI_CP_BSS_LOC +#endif + +#define AI_CP_CACHE_ATTR ALIGNED(4) AI_CP_BSS_LOC + +#define AI_ABS(x) (x>=0?x:(-x)) + +#define FRAME_LEN (256) +#if AI_CAPTURE_CHANNEL_NUM == 2 +#define CAPTURE_CHANNEL_NUM (2) +#else +#define CAPTURE_CHANNEL_NUM (1) +#endif +#ifdef AI_CAPTURE_DATA_AEC +#define AUDIO_CHANNEL_NUM (2) +#else +#define AUDIO_CHANNEL_NUM (0) +#endif +#define CAPTURE_AUDIO_CHANNEL_NUM (CAPTURE_CHANNEL_NUM+AUDIO_CHANNEL_NUM) +#define MIC_DATA_PROCESS_SIZE (FRAME_LEN * CAPTURE_AUDIO_CHANNEL_NUM * sizeof(short)) + +#define AI_AEC_CACHE_NUM 6 +typedef struct +{ + uint8_t cp_data_cache[AI_AEC_CACHE_NUM][MIC_DATA_PROCESS_SIZE]; + uint8_t cp_data_in_cache_num; + uint8_t cp_data_process_cache_num; + uint8_t cp_data_out_cache_num; + uint8_t cp_data_use_cache_num; + uint8_t cp_data_use_max_cache_num; + AI_AEC_CACHE_STATE_E cache_state[AI_AEC_CACHE_NUM]; +} AI_AEC_struct ; + +#define MED_MEM_POOL_SIZE (1024*136) +static uint8_t g_medMemPool[MED_MEM_POOL_SIZE] __attribute__((aligned(4))); + +osMutexId mic_data_handle_mutex_id = NULL; +osMutexDef(mic_data_handle_queue_mutex); + +#define LOCK_MIC_DATA_HANDLE_QUEUE() \ + osMutexWait(mic_data_handle_mutex_id, osWaitForever); + +#define UNLOCK_MIC_DATA_HANDLE_QUEUE() \ + osMutexRelease(mic_data_handle_mutex_id); + +CQueue mic_data_handle_queue; +unsigned char mic_data_handle_queue_buff[MIC_DATA_PROCESS_SIZE * 6] __attribute__((aligned(4))); +unsigned char mic_data_handle_temp_buff[MIC_DATA_PROCESS_SIZE] __attribute__((aligned(4))); + +#ifdef AI_CAPTURE_DATA_AEC +static bool ai_aec_inited = false; +Ec2FloatState *speech_aec2float_st1 = NULL; + +static AI_CP_BSS_LOC short data_mic1[FRAME_LEN] = {0}; +static AI_CP_BSS_LOC short echo_ref1[FRAME_LEN] = {0}; +static AI_CP_BSS_LOC short echo_ref2[FRAME_LEN] = {0}; +static AI_CP_BSS_LOC short aec2_out_buf1[FRAME_LEN] = {0}; + +#if AI_CAPTURE_CHANNEL_NUM == 2 +Ec2FloatState *speech_aec2float_st2 = NULL; +static AI_CP_BSS_LOC short data_mic2[FRAME_LEN] = {0}; +static AI_CP_BSS_LOC short aec2_out_buf2[FRAME_LEN] = {0}; +#endif + +Ec2FloatConfig speech_aec2float_cfg = { + .bypass = 0, + .hpf_enabled = false, + .af_enabled = true, + .nlp_enabled = false, + .clip_enabled = false, + .stsupp_enabled = false, + .ns_enabled = false, + .cng_enabled = false, + .blocks = 6, + .delay = 0, + .min_ovrd = 2, + .target_supp = -40, + .noise_supp = -15, + .cng_type = 1, + .cng_level = -60, + .clip_threshold = -20.f, + .banks = 32, +}; +#endif + +#ifdef AI_AEC_CP_ACCEL +static AI_CP_CACHE_ATTR AI_AEC_struct ai_aec_struct; +#endif + +#define IGNORE_ECHO_VOL 60 +CP_TEXT_SRAM_LOC +void app_ai_aec_process(uint8_t *buf, uint32_t length) +{ + uint16_t i = 0; + short *tmp_in = (short *)buf; + float echo_vol=0; + + for (i = 0; i < FRAME_LEN; i++) + { + data_mic1[i] = tmp_in[i*CAPTURE_AUDIO_CHANNEL_NUM]; + echo_ref1[i] = tmp_in[i*CAPTURE_AUDIO_CHANNEL_NUM+2]; + echo_ref2[i] = tmp_in[i*CAPTURE_AUDIO_CHANNEL_NUM+3]; + echo_vol += AI_ABS((float)echo_ref1[i])/FRAME_LEN; + } + + //TRACE(3, "%s len %d echo_vol %d", __func__, length, (uint16_t)echo_vol); + + if (echo_vol < IGNORE_ECHO_VOL) + { + //TRACE(1, "%s echo_vol is too small", __func__); + return; + } + + ec2float_stereo(speech_aec2float_st1, data_mic1, echo_ref1, echo_ref2,FRAME_LEN, aec2_out_buf1); + for (i = 0; i < FRAME_LEN; i++) + { + tmp_in[i*CAPTURE_AUDIO_CHANNEL_NUM] = aec2_out_buf1[i]; + } + +#if AI_CAPTURE_CHANNEL_NUM == 2 + for (i = 0; i < FRAME_LEN; i++) + { + data_mic2[i] = tmp_in[i*CAPTURE_AUDIO_CHANNEL_NUM+1]; + echo_ref1[i] = tmp_in[i+FRAME_LEN*2]; + echo_ref2[i] = tmp_in[i+FRAME_LEN*3]; + } + ec2float_stereo(speech_aec2float_st2, data_mic2, echo_ref1, echo_ref2,FRAME_LEN, aec2_out_buf2); + + for (i = 0; i < FRAME_LEN; i++) + { + tmp_in[i*CAPTURE_AUDIO_CHANNEL_NUM+1] = aec2_out_buf2[i]; + } +#endif + +#if defined(AUDIO_DEBUG) + audio_dump_clear_up(); + audio_dump_add_channel_data(0, data_mic1, FRAME_LEN); + audio_dump_add_channel_data(1, aec2_out_buf1, FRAME_LEN); +#if AI_CAPTURE_CHANNEL_NUM == 2 + audio_dump_add_channel_data(2, data_mic2, FRAME_LEN); + audio_dump_add_channel_data(3, aec2_out_buf2, FRAME_LEN); +#endif + audio_dump_run(); +#endif +} + +bool app_ai_aec_get_data_from_cache(uint8_t *buf, uint32_t length) +{ + bool ret = false; + uint8_t out_cache_num = ai_aec_struct.cp_data_out_cache_num; + uint8_t *out_data_cache = ai_aec_struct.cp_data_cache[out_cache_num]; + AI_AEC_CACHE_STATE_E out_cache_state = ai_aec_struct.cache_state[out_cache_num]; + +#ifdef AI_AEC_CP_ACCEL + //TRACE(2, "%s cache_num %d state %d", __func__, ai_aec_struct.cp_data_out_cache_num, out_cache_state); + + if (AI_AEC_CACHE_PROCESSED == out_cache_state) + { + memcpy(buf, out_data_cache, length); + ai_aec_struct.cache_state[out_cache_num] = AI_AEC_CACHE_IDLE; + if (++ai_aec_struct.cp_data_out_cache_num >= AI_AEC_CACHE_NUM) + { + ai_aec_struct.cp_data_out_cache_num = 0; + } + ai_aec_struct.cp_data_use_cache_num--; + ret = true; + } + else + { + ret = false; + } +#else + ret = true; +#endif + + return ret; +} + +void app_ai_aec_mic_data_handle(uint8_t *buf, uint32_t length) +{ + uint8_t in_cache_num = ai_aec_struct.cp_data_in_cache_num; + uint8_t *in_data_cache = ai_aec_struct.cp_data_cache[in_cache_num]; + AI_AEC_CACHE_STATE_E in_cache_state = ai_aec_struct.cache_state[in_cache_num]; + +#ifdef AI_AEC_CP_ACCEL + //TRACE(2, "%s cache_num %d state %d max_num %d", __func__, ai_aec_struct.cp_data_in_cache_num, in_cache_state, ai_aec_struct.cp_data_use_max_cache_num); + if (AI_AEC_CACHE_IDLE == in_cache_state) + { + memcpy(in_data_cache, buf, length); + ai_aec_struct.cache_state[in_cache_num] = AI_AEC_CACHE_CACHED; + if (++ai_aec_struct.cp_data_in_cache_num >= AI_AEC_CACHE_NUM) + { + ai_aec_struct.cp_data_in_cache_num = 0; + } + ai_aec_struct.cp_data_use_cache_num++; + if (ai_aec_struct.cp_data_use_cache_num > ai_aec_struct.cp_data_use_max_cache_num) + { + ai_aec_struct.cp_data_use_max_cache_num = ai_aec_struct.cp_data_use_cache_num; + } + cp_accel_send_event_mcu2cp(CP_BUILD_ID(CP_TASK_AEC, CP_EVENT_AEC_PROCESSING)); + } + else + { + TRACE(3, "%s cache %d state error %d", __func__, in_cache_num, in_cache_state); + } +#else + app_ai_aec_process(buf, length); +#endif + + return; +} + +void app_ai_algorithm_mic_data_handle(uint8_t *buf, uint32_t length) +{ + bool ret = false; + uint16_t i = 0; + uint32_t queue_len = 0; + short *tmp_out = (short *)mic_data_handle_temp_buff; + + //TRACE(2, "%s len %d", __func__, length); + LOCK_MIC_DATA_HANDLE_QUEUE(); + if (EnCQueue(&mic_data_handle_queue,(CQItemType *) buf, length) == CQ_ERR) + { + TRACE(2, "###far_field_queue overflow, want %d bytes, has %d bytes\n", + length, AvailableOfCQueue(&mic_data_handle_queue)); + } + queue_len = LengthOfCQueue(&mic_data_handle_queue); + UNLOCK_MIC_DATA_HANDLE_QUEUE(); + + while (queue_len >= MIC_DATA_PROCESS_SIZE) + { + LOCK_MIC_DATA_HANDLE_QUEUE(); + ret = (DeCQueue(&mic_data_handle_queue, mic_data_handle_temp_buff, MIC_DATA_PROCESS_SIZE)==CQ_OK)?true:false; + queue_len = LengthOfCQueue(&mic_data_handle_queue); + UNLOCK_MIC_DATA_HANDLE_QUEUE(); + +#ifdef AI_CAPTURE_DATA_AEC + if (ai_aec_inited && ret) + { + app_ai_aec_mic_data_handle(mic_data_handle_temp_buff, MIC_DATA_PROCESS_SIZE); + ret = app_ai_aec_get_data_from_cache(mic_data_handle_temp_buff, MIC_DATA_PROCESS_SIZE); + } +#endif + + while (ret) + { + //ret = other algorithm handle result + + if (ret) + { + for (i = 0; i < FRAME_LEN; i++) + { + tmp_out[i] = tmp_out[i*CAPTURE_AUDIO_CHANNEL_NUM]; + } + app_voicepath_enqueue_pcm_data(mic_data_handle_temp_buff, FRAME_LEN*2); + } + + if (ai_aec_inited) + { + ret = app_ai_aec_get_data_from_cache(mic_data_handle_temp_buff, MIC_DATA_PROCESS_SIZE); + } + else + { + ret = false; + } + } + } +} + +#ifdef AI_AEC_CP_ACCEL +AI_TEXT_SRAM_LOC +void cp_aec_data_process(void) +{ + uint8_t process_cache_num = ai_aec_struct.cp_data_process_cache_num; + uint8_t *data_cache = ai_aec_struct.cp_data_cache[process_cache_num]; + AI_AEC_CACHE_STATE_E process_cache_state = ai_aec_struct.cache_state[process_cache_num]; + + while (AI_AEC_CACHE_CACHED == process_cache_state) + { + app_ai_aec_process(data_cache, MIC_DATA_PROCESS_SIZE); + ai_aec_struct.cache_state[process_cache_num] = AI_AEC_CACHE_PROCESSED; + if (++ai_aec_struct.cp_data_process_cache_num >= AI_AEC_CACHE_NUM) + { + ai_aec_struct.cp_data_process_cache_num = 0; + } + process_cache_num = ai_aec_struct.cp_data_process_cache_num; + data_cache = ai_aec_struct.cp_data_cache[process_cache_num]; + process_cache_state = ai_aec_struct.cache_state[process_cache_num]; + } + //else + //{ + //TRACE(3, "%s cache state %d error %d", __func__, process_cache_num, process_cache_state); + //} +} + +AI_TEXT_SRAM_LOC +unsigned int cp_aec_main(uint8_t event) +{ + switch (event) + { + case CP_EVENT_AEC_PROCESSING: + cp_aec_data_process(); + break; + default: + break; + } + return 0; +} + +static struct cp_task_desc TASK_DESC_AEC = {CP_ACCEL_STATE_CLOSED, cp_aec_main, NULL, NULL, NULL}; +void cp_aec_init(void) +{ + uint8_t i = 0; + TRACE(2, "%s ai_aec_inited %d", __func__, ai_aec_inited); + + if (!ai_aec_inited) + { + memset(&ai_aec_struct, 0, sizeof(ai_aec_struct)); + ai_aec_struct.cp_data_in_cache_num = 0; + ai_aec_struct.cp_data_process_cache_num = 0; + ai_aec_struct.cp_data_out_cache_num = 0; + for (i=0; i free size = %d", __func__, size, buff_size_free); + + *buff = app_ai_if_capture_buf.buff + app_ai_if_capture_buf.buff_size_used; + + app_ai_if_capture_buf.buff_size_used += size; + app_ai_if_capture_buf.buff_size_free -= size; + + TRACE(3,"AI allocate %d, now used %d left %d", size, + app_ai_if_capture_buf.buff_size_used, + app_ai_if_capture_buf.buff_size_free); +} + +void app_ai_if_mobile_connect_handle(bt_bdaddr_t *_addr) +{ + MOBILE_CONN_TYPE_E type = MOBILE_CONNECT_IDLE; + uint16_t vend_id = 0; + uint16_t vend_id_source = 0; + + btif_dip_get_record_vend_id_and_source(_addr, &vend_id, &vend_id_source); + TRACE(3, "%s vend_id 0x%x vend_id_source 0x%x", __func__, vend_id, vend_id_source); + if (vend_id) + { + type = btif_dip_check_is_ios_by_vend_id(vend_id, vend_id_source)?MOBILE_CONNECT_IOS:MOBILE_CONNECT_ANDROID; +#ifdef __AI_VOICE__ + app_ai_mobile_connect_handle(type, _addr); +#endif +#ifdef BISTO_ENABLED + gsound_custom_bt_link_connected_handler(_addr->address); + gsound_mobile_type_get_callback(type); +#endif + } + +#ifdef BLE_ENABLE + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); +#endif +} + +void app_ai_voice_init(void) +{ +#ifdef __AI_VOICE__ + uint32_t ai_spec = app_ai_if_get_ai_spec(); + + app_ai_manager_init(); + if (ai_spec != AI_SPEC_INIT) + { + ai_open(ai_spec); + app_ai_tws_init(); + +#ifdef OPUS_IN_OVERLAY + app_ai_set_opus_in_overlay(true); +#endif + +#if VOB_ENCODING_ALGORITHM==ENCODING_ALGORITHM_OPUS + app_ai_set_encode_type(ENCODING_ALGORITHM_OPUS); +#elif VOB_ENCODING_ALGORITHM==ENCODING_ALGORITHM_SBC + app_ai_set_encode_type(ENCODING_ALGORITHM_SBC); +#else + app_ai_set_encode_type(NO_ENCODING); +#endif + +#ifdef AI_32KBPS_VOICE + app_ai_set_use_ai_32kbps_voice(true); +#endif + +#ifdef NO_LOCAL_START_TONE + app_ai_set_local_start_tone(false); +#endif + + app_ai_if_custom_init(); + +#ifdef __THROUGH_PUT__ + app_throughput_test_init(); +#endif + } + + app_capture_audio_mempool_init(); + +#ifdef __THIRDPARTY + app_ai_if_thirdparty_init(); +#endif + + app_ai_if_mempool_init(); +#endif +} + +static bool isMusicOrPromptOnGoing = false; +static uint32_t musicOrPromptSampleRate; + +void app_ai_if_inform_music_or_prompt_status(bool isOn, uint32_t sampleRate) +{ + isMusicOrPromptOnGoing = isOn; + musicOrPromptSampleRate = sampleRate; +} + +bool app_ai_if_is_music_or_prompt_ongoing(void) +{ +#ifdef ANC_APP + return isMusicOrPromptOnGoing||app_anc_is_on(); +#else + return isMusicOrPromptOnGoing; +#endif +} + +uint32_t app_ai_if_get_music_or_prompt_sample_rate(void) +{ +#ifdef ANC_APP + if (isMusicOrPromptOnGoing) + { + return musicOrPromptSampleRate; + } + else if (app_anc_is_on()) + { + return app_anc_get_sample_rate(); + } + else + { + return 0; + } +#else + return musicOrPromptSampleRate; +#endif +} + +extern void alexa_wwe_pre_music_or_prompt_check(void); +extern "C" void app_voicepath_pre_music_or_prompt_check(void); + +void app_ai_if_pre_music_or_prompt_check(void) +{ +#ifdef __ALEXA_WWE_LITE + alexa_wwe_pre_music_or_prompt_check(); +#endif + +#ifdef BISTO_ENABLED + app_voicepath_pre_music_or_prompt_check(); +#endif +} + diff --git a/services/app_ai/src/app_ai_if_custom_ui.cpp b/services/app_ai/src/app_ai_if_custom_ui.cpp new file mode 100644 index 0000000..3af7449 --- /dev/null +++ b/services/app_ai/src/app_ai_if_custom_ui.cpp @@ -0,0 +1,118 @@ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "app_spp.h" +#include "app_through_put.h" +#include "app_ai_if.h" +#include "app_ai_tws.h" +#include "app_ai_if_config.h" +#include "app_ble_mode_switch.h" +#include "app_ai_if_custom_ui.h" +#ifdef RTOS +#include "cmsis_os.h" +#endif +#include "app_status_ind.h" + +#ifdef __AI_VOICE__ +#include "ai_control.h" +#include "ai_thread.h" +#include "ai_transport.h" +#endif + +#ifdef __AI_VOICE__ +static void app_ai_if_custom_ui_global_handler_ind(uint32_t cmd, void *param1, uint32_t param2) +{ + switch (cmd) + { + case AI_CUSTOM_CODE_AI_ROLE_SWITCH: + break; + + case AI_CUSTOM_CODE_CMD_RECEIVE: +#ifdef __THROUGH_PUT__ + app_throughput_receive_cmd(param1, param2); +#endif + break; + + case AI_CUSTOM_CODE_DATA_RECEIVE: + break; + + case AI_CUSTOM_CODE_AI_CONNECT: + break; + + case AI_CUSTOM_CODE_AI_DISCONNECT: +#ifdef __THROUGH_PUT__ + app_stop_throughput_test(); +#endif + break; + + case AI_CUSTOM_CODE_UPDATE_MTU: + break; + + case AI_CUSTOM_CODE_WAKE_UP: + break; + + case AI_CUSTOM_CODE_START_SPEECH: + break; + + case AI_CUSTOM_CODE_ENDPOINT_SPEECH: + break; + + case AI_CUSTOM_CODE_STOP_SPEECH: + break; + case AI_CUSTOM_CODE_DATA_SEND_DONE: +#ifdef __THROUGH_PUT__ + app_throughput_cmd_send_done(param1, param2); +#endif + break; + + case AI_CUSTOM_CODE_KEY_EVENT_HANDLE: + break; + + case AI_CUSTOM_CODE_AI_ROLE_SWITCH_COMPLETE: + break; + + case AI_CUSTOM_CODE_MOBILE_CONNECT: + break; + + case AI_CUSTOM_CODE_MOBILE_DISCONNECT: + break; + + case AI_CUSTOM_CODE_SETUP_COMPLETE: + break; + + default: + break; + } +} +#endif + +bool app_ai_if_custom_ui_send_cmd(uint8_t *cmd_buf,uint16_t cmd_len) +{ + osStatus status = (osStatus)osErrorValue; +#ifdef __AI_VOICE__ + TRACE(1, "%s", __func__); + + uint8_t send_buf[L2CAP_MTU] = {0}; + uint16_t *output_size_p = NULL; + uint8_t *output_buf_p = NULL; + + output_size_p = (uint16_t *)send_buf; + output_buf_p = &send_buf[AI_CMD_CODE_SIZE]; + + memcpy(output_buf_p, cmd_buf, cmd_len); + *output_size_p = cmd_len; + + if (ai_transport_cmd_put(send_buf, (cmd_len+AI_CMD_CODE_SIZE))) + { + status = ai_mailbox_put(SIGN_AI_TRANSPORT, cmd_len); + } +#endif + return (osOK == status); +} + +void app_ai_if_custom_init(void) +{ +#ifdef __AI_VOICE__ + app_ai_register_ui_global_handler_ind(app_ai_if_custom_ui_global_handler_ind); +#endif +} + diff --git a/services/app_ai/src/app_ai_if_gsound.cpp b/services/app_ai/src/app_ai_if_gsound.cpp new file mode 100644 index 0000000..0bf2d8c --- /dev/null +++ b/services/app_ai/src/app_ai_if_gsound.cpp @@ -0,0 +1,16 @@ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "app_ai_if_gsound.h" + + +#ifdef BISTO_ENABLED +#include "gsound_custom_service.h" +#endif + +void app_ai_if_gsound_service_enable_switch(bool onOff) +{ +#ifdef BISTO_ENABLED + gsound_service_enable_switch(onOff); +#endif +} + diff --git a/services/app_ai/src/app_ai_if_thirdparty.cpp b/services/app_ai/src/app_ai_if_thirdparty.cpp new file mode 100644 index 0000000..2f75fb0 --- /dev/null +++ b/services/app_ai/src/app_ai_if_thirdparty.cpp @@ -0,0 +1,108 @@ +#include "cmsis_os.h" +#include "spp_api.h" +#include "hal_trace.h" +#include "app_ai_if.h" +#include "app_ai_tws.h" +#include "app_ai_manager_api.h" +#include "app_ai_if_thirdparty.h" +#include "app_thirdparty.h" +#include "app_bt_media_manager.h" + +#ifdef __AI_VOICE__ +#include "ai_manager.h" +#include "ai_control.h" +#include "ai_thread.h" +#include "app_ai_voice.h" +#endif + +uint8_t app_ai_if_thirdparty_mempool_buf[APP_AI_IF_THIRDPARTY_MEMPOOL_BUFFER_SIZE]; +THIRDPARTY_AI_MEMPOOL_BUFFER_T app_ai_if_thirdparty_mempool_buf_t; + +POSSIBLY_UNUSED void app_ai_if_thirdparty_mempool_init(void) +{ + memset((uint8_t *)app_ai_if_thirdparty_mempool_buf, 0, APP_AI_IF_THIRDPARTY_MEMPOOL_BUFFER_SIZE); + + app_ai_if_thirdparty_mempool_buf_t.buff = app_ai_if_thirdparty_mempool_buf; + app_ai_if_thirdparty_mempool_buf_t.buff_size_total = APP_AI_IF_THIRDPARTY_MEMPOOL_BUFFER_SIZE; + app_ai_if_thirdparty_mempool_buf_t.buff_size_used = 0; + app_ai_if_thirdparty_mempool_buf_t.buff_size_free = APP_AI_IF_THIRDPARTY_MEMPOOL_BUFFER_SIZE; + + TRACE(3, "%s buf %p size %d", __func__, app_ai_if_thirdparty_mempool_buf, APP_AI_IF_THIRDPARTY_MEMPOOL_BUFFER_SIZE); +} + +void app_ai_if_thirdparty_mempool_deinit(void) +{ + TRACE(2, "%s size %d", __func__, app_ai_if_thirdparty_mempool_buf_t.buff_size_total); + + memset((uint8_t *)app_ai_if_thirdparty_mempool_buf_t.buff, 0, app_ai_if_thirdparty_mempool_buf_t.buff_size_total); + + app_ai_if_thirdparty_mempool_buf_t.buff_size_used = 0; + app_ai_if_thirdparty_mempool_buf_t.buff_size_free = app_ai_if_thirdparty_mempool_buf_t.buff_size_total; +} + +void app_ai_if_thirdparty_mempool_get_buff(uint8_t **buff, uint32_t size) +{ + uint32_t buff_size_free; + + buff_size_free = app_ai_if_thirdparty_mempool_buf_t.buff_size_free; + + if (size % 4){ + size = size + (4 - size % 4); + } + + TRACE(3,"%s free %d to allocate %d", __func__, buff_size_free, size); + + ASSERT(size <= buff_size_free, "[%s] size = %d > free size = %d", __func__, size, buff_size_free); + + *buff = app_ai_if_thirdparty_mempool_buf_t.buff + app_ai_if_thirdparty_mempool_buf_t.buff_size_used; + + app_ai_if_thirdparty_mempool_buf_t.buff_size_used += size; + app_ai_if_thirdparty_mempool_buf_t.buff_size_free -= size; + + TRACE(3,"thirdparty allocate %d, now used %d left %d", size, + app_ai_if_thirdparty_mempool_buf_t.buff_size_used, + app_ai_if_thirdparty_mempool_buf_t.buff_size_free); +} + +void app_ai_if_thirdparty_start_stream_by_app_audio_manager(void) +{ +#ifdef __THIRDPARTY + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START, + BT_STREAM_THIRDPARTY_VOICE, + 0, + 0); +#endif +} + +void app_ai_if_thirdparty_stop_stream_by_app_audio_manager(void) +{ +#ifdef __THIRDPARTY + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP, + BT_STREAM_THIRDPARTY_VOICE, + 0, + 0); +#endif +} + +int app_ai_if_thirdparty_event_handle(THIRDPARTY_FUNC_ID funcId, THIRDPARTY_EVENT_TYPE event_type) +{ + int ret = 0; +#ifdef __THIRDPARTY + ret = app_thirdparty_specific_lib_event_handle(funcId, event_type); +#endif + return ret; +} + +void app_ai_if_thirdparty_init(void) +{ +#if defined(__THIRDPARTY) && defined(__AI_VOICE__) + app_ai_set_use_thirdparty(true); + app_ai_if_thirdparty_mempool_init(); + app_thirdparty_callback_init(THIRDPARTY_DATA_COME_CALLBACK, app_ai_voice_thirdparty_data_come_callback); + app_thirdparty_callback_init(THIRDPARTY_WAKE_UP_CALLBACK, app_ai_voice_thirdparty_wake_up_callback); + app_thirdparty_callback_init(THIRDPARTY_START_SPEECH_CALLBACK, app_ai_voice_thirdparty_start_speech_callback); + app_thirdparty_callback_init(THIRDPARTY_STOP_SPEECH_CALLBACK, app_ai_voice_thirdparty_stop_speech_callback); + app_ai_if_thirdparty_event_handle(THIRDPARTY_FUNC_KWS, THIRDPARTY_INIT); +#endif +} + diff --git a/services/app_ai/src/app_ai_manager_api.cpp b/services/app_ai/src/app_ai_manager_api.cpp new file mode 100644 index 0000000..5fdb6a1 --- /dev/null +++ b/services/app_ai/src/app_ai_manager_api.cpp @@ -0,0 +1,131 @@ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "app_ai_if.h" +#include "app_ai_tws.h" +#include "app_ai_manager_api.h" + +#ifdef __AI_VOICE__ +#include "ai_manager.h" +#include "ai_thread.h" +#endif + +bool app_ai_manager_is_in_multi_ai_mode(void) +{ + bool ret = false; +#ifdef IS_MULTI_AI_ENABLED + ret = true; +#endif + return ret; +} + +bool app_ai_manager_voicekey_is_enable(void) +{ + bool ret = true; +#ifdef IS_MULTI_AI_ENABLED + ret = ai_voicekey_is_enable(); +#endif + return ret; +} + +void app_ai_manager_voicekey_save_status(bool state) +{ +#ifdef IS_MULTI_AI_ENABLED + ai_voicekey_save_status(state); +#endif +} + +void app_ai_manager_switch_spec(AI_SPEC_TYPE_E ai_spec) +{ +#ifdef IS_MULTI_AI_ENABLED + ai_manager_switch_spec(ai_spec); +#endif +} + +void app_ai_manager_set_current_spec(AI_SPEC_TYPE_E ai_spec) +{ +#ifdef IS_MULTI_AI_ENABLED + ai_manager_set_current_spec(ai_spec); +#endif +} + +uint8_t app_ai_manager_get_current_spec(void) +{ + uint8_t ret = -1; +#ifdef IS_MULTI_AI_ENABLED + ret = ai_manager_get_current_spec(); +#endif + return ret; +} + +bool app_ai_manager_is_need_reboot(void) +{ + bool ret = false; +#ifdef IS_MULTI_AI_ENABLED + ret = ai_manager_is_need_reboot(); +#endif + return ret; +} + +void app_ai_manager_enable(bool isEnabled, AI_SPEC_TYPE_E ai_spec) +{ +#ifdef IS_MULTI_AI_ENABLED + ai_manager_enable(isEnabled, ai_spec); +#endif +} + +void app_ai_manager_set_spec_connected_status(AI_SPEC_TYPE_E ai_spec, uint8_t connected) +{ +#ifdef IS_MULTI_AI_ENABLED + ai_manager_set_spec_connected_status(ai_spec, connected); +#endif +} + +int8_t app_ai_manager_get_spec_connected_status(uint8_t ai_spec) +{ + uint8_t ret = -1; +#ifdef IS_MULTI_AI_ENABLED + ret = ai_manager_get_spec_connected_status(ai_spec); +#endif + return ret; +} + +bool app_ai_manager_spec_get_status_is_in_invalid(void) +{ + bool ret = true; +#ifdef IS_MULTI_AI_ENABLED + ret = ai_manager_spec_get_status_is_in_invalid(); +#endif + return ret; +} + +void app_ai_manager_set_spec_update_flag(bool onOff) +{ +#ifdef IS_MULTI_AI_ENABLED + ai_manager_set_spec_update_flag(onOff); +#endif +} + +bool app_ai_manager_get_spec_update_flag(void) +{ + bool ret = false; +#ifdef IS_MULTI_AI_ENABLED + ret = ai_manager_get_spec_update_flag(); +#endif + return ret; +} + +void app_ai_manager_spec_update_start_reboot(void) +{ +#ifdef IS_MULTI_AI_ENABLED + ai_manager_spec_update_start_reboot(); +#endif +} + +void app_ai_manager_init(void) +{ +#ifdef IS_MULTI_AI_ENABLED + ai_manager_init(); +#endif +} + + diff --git a/services/app_ai/src/app_ai_tws.cpp b/services/app_ai/src/app_ai_tws.cpp new file mode 100644 index 0000000..118b689 --- /dev/null +++ b/services/app_ai/src/app_ai_tws.cpp @@ -0,0 +1,656 @@ +#include "cmsis_os.h" +#include "spp_api.h" +#include "hal_trace.h" +#include "app_ai_if.h" +#include "app_ai_tws.h" +#include "app_ble_mode_switch.h" +#include "app_ai_if_thirdparty.h" +#include "hal_location.h" + +#ifdef __AI_VOICE__ +#include "ai_manager.h" +#include "ai_control.h" +#include "ai_thread.h" +#include "app_ai_voice.h" +#endif + +#if defined(IBRT) +#include "app_tws_ibrt.h" +#include "app_tws_ctrl_thread.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_if.h" +#include "app_ibrt_ui.h" +#include "app_ibrt_if.h" +#include "app_tws_ctrl_thread.h" +#endif + +#ifdef BISTO_ENABLED +#include "gsound_custom.h" +#include "gsound_custom_tws.h" +#include "gsound_custom_bt.h" +#endif + + +#define CASE_S(s) case s:return "["#s"]"; +#define CASE_D() default:return "[INVALID]"; +#define APP_AI_ROLE_SWITCH_TIME_IN_MS (500) + +APP_AI_TWS_REBOOT_T REBOOT_CUSTOM_PARAM_LOC app_ai_tws_reboot = {false, 0xFF}; + +#if defined(IBRT) && defined(__AI_VOICE__) +static void app_ai_role_switch_timeout_cb(void const *n); +osTimerDef(APP_AI_ROLE_SWITCH_TIMER, app_ai_role_switch_timeout_cb); +osTimerId app_ai_role_switch_timer_id = NULL; + +static void app_ai_role_switch_timeout_cb(void const *n) +{ + app_ai_tws_role_switch_dis_ble(); +} + +#define APP_AI_BLE_DISC_TIME_IN_MS (100) +static void app_ai_ble_disc_timeout_cb(void const *n); +osTimerDef(APP_AI_BLE_DISC_TIMER, app_ai_ble_disc_timeout_cb); +osTimerId app_ai_ble_disc_timer_id = NULL; + +extern "C" bool app_ai_ble_is_connected(void); +extern "C" uint16_t app_ai_ble_get_conhdl(void); + +static void app_ai_ble_disc_timeout_cb(void const *n) +{ + TRACE(1,"%s", __func__); + + app_ai_tws_role_switch_direct(); +} +#endif + +void app_ai_let_slave_continue_roleswitch(void) +{ +#if defined(IBRT) && defined(__AI_VOICE__) + uint8_t role = app_ai_get_ai_spec(); + tws_ctrl_send_cmd(APP_TWS_CMD_LET_SLAVE_CONTINUE_RS, &role, 1); +#endif +} + +bool app_ai_tws_role_switch_direct(void) +{ + bool ret = false; +#if defined(IBRT) && defined(__AI_VOICE__) + if (!app_ai_is_role_switching()) + { + TRACE(1,"%s isn't switching now", __func__); + return ret; + } + + TRACE(2,"%s initiative %d", __func__, app_ai_is_initiative_switch()); + if (app_ai_is_role_switch_direct()) + { + TRACE(1,"%s has done", __func__); + return ret; + } + app_ai_set_role_switch_direct(true); + + osTimerStop(app_ai_role_switch_timer_id); + osTimerStop(app_ai_ble_disc_timer_id); + + if (app_ai_is_initiative_switch()) + { + app_ibrt_if_tws_switch_prepare_done_in_bt_thread(IBRT_ROLE_SWITCH_USER_AI, app_ai_get_ai_spec()); + return ret; + } + else + { + app_ai_let_slave_continue_roleswitch(); + //ret = true; + } +#endif + + return ret; +} + +bool app_ai_tws_role_switch_dis_ble(void) +{ + bool ret = false; +#if defined(IBRT) && defined(__AI_VOICE__) + uint16_t ble_Conhandle = 0; + bool ble_connected = app_ai_ble_is_connected(); + TRACE(2,"%s ble_connected %d", __func__, ble_connected); + + osTimerStop(app_ai_role_switch_timer_id); + + if (ble_connected) + { + // disconnect ble connection if existing + ble_Conhandle = app_ai_ble_get_conhdl(); + bt_drv_reg_op_ble_sup_timeout_set(ble_Conhandle, 15); //fix ble disconnection takes long time:connSupervisionTime=150ms + app_ble_disconnect_all(); + osTimerStart(app_ai_ble_disc_timer_id, APP_AI_BLE_DISC_TIME_IN_MS); + ret = true; + } + else + { + ret = app_ai_tws_role_switch_direct(); + } +#endif + + return ret; +} + +#if defined(IBRT) && defined(__AI_VOICE__) +static void app_ai_tws_slave_request_master_role_switch(void) +{ + TRACE(3,"%s complete %d switching %d", __func__, \ + app_ai_is_setup_complete(), \ + app_ai_is_role_switching()); + + uint8_t role = app_ai_get_ai_spec(); + tws_ctrl_send_cmd(APP_TWS_CMD_LET_MASTER_PREPARE_RS, &role, 1); + osTimerStart(app_ai_ble_disc_timer_id, APP_AI_ROLE_SWITCH_TIME_IN_MS+APP_AI_BLE_DISC_TIME_IN_MS); +} +#endif + +bool app_ai_tws_master_role_switch(void) +{ + bool ret = false; +#if defined(IBRT) && defined(__AI_VOICE__) + TRACE(3,"%s complete %d switching %d", __func__, \ + app_ai_is_setup_complete(), \ + app_ai_is_role_switching()); + + if (app_ai_is_use_thirdparty()) + { + app_ai_if_thirdparty_stop_stream_by_app_audio_manager(); + app_ai_if_thirdparty_event_handle(THIRDPARTY_FUNC_KWS, THIRDPARTY_AI_DISCONNECT); + } + + app_ai_set_role_switching(true); + osTimerStart(app_ai_role_switch_timer_id, APP_AI_ROLE_SWITCH_TIME_IN_MS); + if (app_ai_is_stream_running() || (app_ai_get_speech_state() != AI_SPEECH_STATE__IDLE)) + { + TRACE(2,"%s stream runing %d", __func__, app_ai_is_stream_running()); + + ai_function_handle(CALLBACK_STOP_SPEECH, NULL, 0); + } + + if (ERROR_RETURN != ai_function_handle(API_AI_ROLE_SWITCH, NULL, 0)) + { + return true; + } + + ret = app_ai_tws_role_switch_dis_ble(); +#endif + + return ret; +} + +bool app_ai_role_switch(void) +{ + bool ret = false; +#ifdef __AI_VOICE__ + TRACE(3,"%s complete %d switching %d", __func__, \ + app_ai_is_setup_complete(), \ + app_ai_is_role_switching()); + + if (app_ai_is_role_switching()) + { + TRACE(1,"%s is switching now", __func__); + return ret; + } + app_ai_set_role_switching(true); + app_ai_set_initiative_switch(true); + + if(!app_ai_is_setup_complete() && !app_ai_is_peer_setup_complete()) + { + TRACE(1,"%s ai not setup complete", __func__); + return ret; + } + +#if defined(IBRT) + if (app_ai_tws_get_local_role() == APP_AI_TWS_MASTER) + { + ret = app_ai_tws_master_role_switch(); + } + else + { + app_ai_tws_slave_request_master_role_switch(); + ret = true; + } +#endif +#endif + + return ret; +} + +uint32_t app_ai_tws_role_switch_prepare(uint32_t *wait_ms) +{ + uint32_t ret = 0; + +#ifdef BISTO_ENABLED + *wait_ms = 800; + ret |= (1 << AI_SPEC_GSOUND); +#endif + +#ifdef __AI_VOICE__ + if (app_ai_role_switch()) + { + *wait_ms = 800; + ret |= (1 << app_ai_get_ai_spec()); + } +#endif + + TRACE(3,"[%s] ret=%d, wait_ms=%d", __func__, ret, *wait_ms); + return ret; +} + +void app_ai_tws_master_role_switch_prepare(void) +{ +#ifdef __AI_VOICE__ + app_ai_tws_master_role_switch(); +#endif +} + +void app_ai_tws_role_switch_prepare_done(void) +{ +#if defined(IBRT) && defined(__AI_VOICE__) + TRACE(1,"%s", __func__); + + app_ai_tws_role_switch_direct(); +#endif +} + +void app_ai_tws_role_switch(void) +{ + TRACE(1,"[%s]", __func__); + +#ifdef BISTO_ENABLED + gsound_tws_request_roleswitch(); +#endif +} + +void app_ai_tws_role_switch_complete(void) +{ +#ifdef __AI_VOICE__ + TRACE(1,"%s", __func__); + + app_ai_set_role_switching(false); + app_ai_set_initiative_switch(false); + app_ai_set_role_switch_direct(false); + app_ai_set_can_role_switch(false); + app_ai_set_ble_adv(); + + if (app_ai_is_setup_complete()) + { + app_ai_set_speech_state(AI_SPEECH_STATE__IDLE); + app_ai_voice_stream_deinit(); +#if defined(IBRT) + if (app_tws_ibrt_tws_link_connected() && (app_ai_tws_get_local_role() == APP_AI_TWS_MASTER)) +#endif + { + if (app_ai_is_in_multi_ai_mode()) + { + if (AI_SPEC_GSOUND == ai_manager_get_current_spec() || \ + AI_SPEC_INIT == ai_manager_get_current_spec()) + { + return; + } + } + + if (app_ai_is_use_thirdparty()) + { + app_ai_if_thirdparty_event_handle(THIRDPARTY_FUNC_KWS, THIRDPARTY_AI_CONNECT); + app_ai_if_thirdparty_start_stream_by_app_audio_manager(); + } + } + } + + app_ai_ui_global_handler_ind(AI_CUSTOM_CODE_AI_ROLE_SWITCH_COMPLETE, NULL, 0); +#endif +} + +void app_ai_tws_sync_info_prepare_handler(uint8_t *buf, uint16_t *length) +{ +#ifdef __AI_VOICE__ + uint16_t buf_len = 0; + + *length = ai_save_ctx(buf, buf_len); +#endif +} + +void app_ai_tws_sync_info_received_handler(uint8_t *buf, uint16_t length) +{ +#ifdef __AI_VOICE__ + ai_restore_ctx(buf, length); +#endif +} + +void app_ai_tws_sync_init(void) +{ +#if defined(IBRT) && defined(__AI_VOICE__) + TWS_SYNC_USER_T user_app_ai_t = { + app_ai_tws_sync_info_prepare_handler, + app_ai_tws_sync_info_received_handler, + NULL, + NULL, + NULL, + }; + + app_tws_if_register_sync_user(TWS_SYNC_USER_AI_INFO, &user_app_ai_t); + + if(NULL == app_ai_role_switch_timer_id) + { + app_ai_role_switch_timer_id = + osTimerCreate(osTimer(APP_AI_ROLE_SWITCH_TIMER), osTimerOnce, NULL); + } + if(NULL == app_ai_ble_disc_timer_id) + { + app_ai_ble_disc_timer_id = + osTimerCreate(osTimer(APP_AI_BLE_DISC_TIMER), osTimerOnce, NULL); + } +#endif +} + +void app_ai_tws_sync_ai_info(void) +{ +#if defined(IBRT) && defined(__AI_VOICE__) + app_tws_if_sync_info(TWS_SYNC_USER_AI_INFO); +#endif +} + +void ai_manager_sync_info_prepare_handler(uint8_t *buf, uint16_t *length) +{ +#ifdef IS_MULTI_AI_ENABLED + uint16_t buf_len = 0; + + *length = ai_manager_save_ctx(buf, buf_len); +#endif +} + +void ai_manager_sync_info_received_handler(uint8_t *buf, uint16_t length) +{ +#ifdef IS_MULTI_AI_ENABLED + ai_manager_restore_ctx(buf, length); +#endif +} + +void ai_manager_sync_info_received_rsp_handler(uint8_t *buf, uint16_t length) +{ +#ifdef IS_MULTI_AI_ENABLED + ai_manager_save_ctx_rsp_handle(buf, length); +#endif +} + +void ai_manager_sync_init(void) +{ +#if defined(IBRT) && defined(IS_MULTI_AI_ENABLED) + TWS_SYNC_USER_T user_ai_manager_t = { + ai_manager_sync_info_prepare_handler, + ai_manager_sync_info_received_handler, + NULL, + ai_manager_sync_info_received_rsp_handler, + ai_manager_sync_info_received_rsp_handler, + }; + + app_tws_if_register_sync_user(TWS_SYNC_USER_AI_MANAGER, &user_ai_manager_t); +#endif +} + +void app_ai_tws_sync_ai_manager_info(void) +{ +#if defined(IBRT) && defined(IS_MULTI_AI_ENABLED) + app_tws_if_sync_info(TWS_SYNC_USER_AI_MANAGER); +#endif +} + +#ifdef IBRT +static void gsound_connect_sync_info_prepare_handler(uint8_t *buf, uint16_t *length) +{ +#ifdef BISTO_ENABLED + *length = 0; + + AI_CONNECTION_STATE_T *pAiInfo = (AI_CONNECTION_STATE_T*)buf; + + pAiInfo->connBtState = gsound_is_bt_connected(); + pAiInfo->connPathType = gsound_custom_get_connection_path(); + memcpy(pAiInfo->connBdAddr, gsound_get_connected_bd_addr(), 6); + + if (CONNECTION_BLE == pAiInfo->connPathType) + { + pAiInfo->connPathState = gsound_get_ble_connect_state(); + } + else if (CONNECTION_BT == pAiInfo->connPathType) + { + pAiInfo->connPathState = gsound_get_bt_connect_state(); + } + else + { + pAiInfo->connPathState = 0; + } + + *length = sizeof(AI_CONNECTION_STATE_T); +#endif +} + +static void gsound_connect_sync_info_received_handler(uint8_t *buf, uint16_t length) +{ +#ifdef BISTO_ENABLED + gsound_custom_connection_state_received_handler(buf); +#endif +} +#endif + +void app_ai_tws_gsound_sync_init(void) +{ +#ifdef IBRT + TWS_SYNC_USER_T userAiConnect = { + gsound_connect_sync_info_prepare_handler, + gsound_connect_sync_info_received_handler, + NULL, + NULL, + NULL, + }; + + app_tws_if_register_sync_user(TWS_SYNC_USER_AI_CONNECTION, &userAiConnect); +#endif +} + +void app_ai_tws_send_cmd_to_peer(uint8_t *p_buff, uint16_t length) +{ +#ifdef IBRT + if (app_tws_ibrt_tws_link_connected()) + { + app_tws_if_ai_send_cmd_to_peer(p_buff, length); + } +#endif +} + +void app_ai_tws_rev_peer_cmd_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ +#ifdef __AI_VOICE__ + app_ai_rev_peer_cmd_hanlder(rsp_seq, p_buff, length); +#endif +} + +void app_ai_tws_send_cmd_with_rsp_to_peer(uint8_t *p_buff, uint16_t length) +{ +#ifdef IBRT + if (app_tws_ibrt_tws_link_connected()) + { + app_tws_if_ai_send_cmd_with_rsp_to_peer(p_buff, length); + } +#endif +} + +void app_ai_tws_send_cmd_rsp_to_peer(uint8_t *p_buff, uint16_t rsp_seq, uint16_t length) +{ +#ifdef IBRT + if (app_tws_ibrt_tws_link_connected()) + { + app_tws_if_ai_send_cmd_rsp_to_peer(p_buff, rsp_seq, length); + } +#endif +} + +void app_ai_tws_rev_peer_cmd_with_rsp_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ +#ifdef __AI_VOICE__ + app_ai_rev_peer_cmd_hanlder(rsp_seq, p_buff, length); +#endif +} + +void app_ai_tws_rev_cmd_rsp_from_peer_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ +#ifdef __AI_VOICE__ + app_ai_rev_peer_cmd_hanlder(rsp_seq, p_buff, length); +#endif +} + +void app_ai_tws_rev_cmd_rsp_timeout_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ +#ifdef __AI_VOICE__ + app_ai_rev_peer_cmd_rsp_timeout_hanlder(rsp_seq, p_buff, length); +#endif +} + + +bool app_ai_tws_init_done(void) +{ +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + return (p_ibrt_ctrl->init_done != 0); +#endif + return false; +} + +bool app_ai_tws_link_connected(void) +{ +#if defined(IBRT) + return app_tws_ibrt_tws_link_connected(); +#endif + return false; +} + +uint8_t *app_ai_tws_local_address(void) +{ + uint8_t *local_addr = NULL; +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + local_addr = p_ibrt_ctrl->local_addr.address; +#endif + return local_addr; +} + +uint8_t *app_ai_tws_peer_address(void) +{ + uint8_t *peer_addr = NULL; +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + peer_addr = p_ibrt_ctrl->local_addr.address; +#endif + return peer_addr; +} + +void app_ai_tws_reboot_record_box_state(void) +{ + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + app_ai_tws_reboot.is_ai_reboot = true; + app_ai_tws_reboot.box_state = p_ibrt_ui->box_state; + TRACE(2, "%s box state %d", __func__, p_ibrt_ui->box_state); +} + +uint8_t app_ai_tws_reboot_get_box_action(void) +{ + uint8_t box_state = 0xFF; + + if (app_ai_tws_reboot.is_ai_reboot) + { + box_state = app_ai_tws_reboot.box_state; + } + + TRACE(2, "%s box state %d", __func__, box_state); + if (box_state == IBRT_IN_BOX_OPEN) + { + return IBRT_OPEN_BOX_EVENT; + } + else if (box_state == IBRT_OUT_BOX) + { + return IBRT_FETCH_OUT_EVENT; + } + else if (box_state == IBRT_OUT_BOX_WEARED) + { + return IBRT_WEAR_UP_EVENT; + } + + return 0xFF; +} + +void app_ai_tws_clear_reboot_box_state(void) +{ + TRACE(2, "%s box state %d", __func__, app_ai_tws_reboot.box_state); + app_ai_tws_reboot.is_ai_reboot = false; + app_ai_tws_reboot.box_state = 0xFF; +} + +void app_ai_tws_disconnect_all_bt_connection(void) +{ +#if defined(IBRT) + app_tws_ibrt_disconnect_all_connection(); +#endif +} + +uint8_t app_ai_tws_get_local_role(void) +{ + uint8_t local_role = APP_AI_TWS_UNKNOW; +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (app_ibrt_ui_is_profile_exchanged()) + { + if (app_tws_ibrt_mobile_link_connected()) + { + local_role = APP_AI_TWS_MASTER; + } + else if (app_tws_ibrt_slave_ibrt_link_connected()) + { + local_role = APP_AI_TWS_SLAVE; + } + else + { + local_role = APP_AI_TWS_UNKNOW; + } + } + else if (app_tws_ibrt_tws_link_connected()) + { + if (app_tws_ibrt_mobile_link_connected()) + { + local_role = APP_AI_TWS_MASTER; + } + else if(p_ibrt_ctrl->current_role == IBRT_MASTER) + { + local_role = APP_AI_TWS_MASTER; + } + else + { + local_role = APP_AI_TWS_SLAVE; + } + + } + else + { + local_role = APP_AI_TWS_UNKNOW; + } + + TRACE(5, "[%s] %d exchanged %d tws %d mobile %d", + __func__, local_role, app_ibrt_ui_is_profile_exchanged(), + app_tws_ibrt_tws_link_connected(), + app_tws_ibrt_mobile_link_connected()); +#endif + return local_role; +} + +void app_ai_tws_init(void) +{ +#if defined(IBRT) && defined(__AI_VOICE__) + app_ai_set_in_tws_mode(true); +#endif +} + diff --git a/services/app_ai/voice_sbc/voice_sbc.cpp b/services/app_ai/voice_sbc/voice_sbc.cpp new file mode 100644 index 0000000..c36d1a3 --- /dev/null +++ b/services/app_ai/voice_sbc/voice_sbc.cpp @@ -0,0 +1,196 @@ +#ifndef VOICE_DATAPATH +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "voice_sbc.h" +#include "hal_trace.h" + +static VOICE_SBC_CONFIG_T voice_sbc_config = +{ + VOICE_SBC_CHANNEL_COUNT , + VOICE_SBC_CHANNEL_MODE , + VOICE_SBC_BIT_POOL , + VOICE_SBC_SIZE_PER_SAMPLE , + VOICE_SBC_SAMPLE_RATE , + VOICE_SBC_NUM_BLOCKS , + VOICE_SBC_NUM_SUB_BANDS , + VOICE_SBC_MSBC_FLAG , + VOICE_SBC_ALLOC_METHOD , +}; + +static int voice_sbc_init_encoder(void); + +static btif_sbc_encoder_t voice_sbc_encoder; +static btif_sbc_decoder_t voice_sbc_decoder; +static uint32_t voice_sbc_frame_len = 0; + +static float voice_sbc_eq_band_gain[8] = {1, 1, 1, 1, 1, 1, 1, 1}; + +static int voice_sbc_init_encoder(void) +{ + btif_sbc_init_encoder(&voice_sbc_encoder); + voice_sbc_encoder.streamInfo.numChannels = voice_sbc_config.channelCnt; + voice_sbc_encoder.streamInfo.channelMode = voice_sbc_config.channelMode; + voice_sbc_encoder.streamInfo.bitPool = voice_sbc_config.bitPool; + voice_sbc_encoder.streamInfo.sampleFreq = voice_sbc_config.sampleRate; + voice_sbc_encoder.streamInfo.allocMethod = voice_sbc_config.allocMethod; + voice_sbc_encoder.streamInfo.numBlocks = voice_sbc_config.numBlocks; + voice_sbc_encoder.streamInfo.numSubBands = voice_sbc_config.numSubBands; + voice_sbc_encoder.streamInfo.mSbcFlag = voice_sbc_config.mSbcFlag; + + voice_sbc_frame_len = btif_sbc_frame_len(&(voice_sbc_encoder.streamInfo)); + + TRACE(1,"frame len is %d", voice_sbc_frame_len); + return 0; +} + +static int voice_sbc_init_decoder(void) +{ + btif_sbc_init_decoder(&voice_sbc_decoder); + voice_sbc_decoder.streamInfo.numChannels = voice_sbc_config.channelCnt; + voice_sbc_decoder.streamInfo.channelMode = voice_sbc_config.channelMode; + voice_sbc_decoder.streamInfo.bitPool = voice_sbc_config.bitPool; + voice_sbc_decoder.streamInfo.sampleFreq = voice_sbc_config.sampleRate; + voice_sbc_decoder.streamInfo.allocMethod = voice_sbc_config.allocMethod; + voice_sbc_decoder.streamInfo.numBlocks = voice_sbc_config.numBlocks; + voice_sbc_decoder.streamInfo.numSubBands = voice_sbc_config.numSubBands; + voice_sbc_decoder.streamInfo.mSbcFlag = voice_sbc_config.mSbcFlag; + return 0; +} + +uint32_t voice_sbc_get_frame_len(void) +{ + return voice_sbc_frame_len; +} + +uint32_t voice_sbc_encode(uint8_t *input, uint32_t inputBytes, uint32_t* purchasedBytes, uint8_t *output, uint8_t isReset) +{ + if (isReset) + { + voice_sbc_init_encoder(); + } + + btif_sbc_pcm_data_t PcmEncData; + uint16_t outputSbcBytes, bytes_encoded; + + PcmEncData.numChannels = voice_sbc_encoder.streamInfo.numChannels; + PcmEncData.sampleFreq = voice_sbc_encoder.streamInfo.sampleFreq; + + if (voice_sbc_encoder.streamInfo.mSbcFlag) + { + uint16_t outputOffset = 0; + uint16_t oneChunkOutput = 0; + uint16_t oneChunkConsumed; + bytes_encoded = 0; + + for (uint32_t index = 0;index < inputBytes;index += (uint32_t)VOICE_SBC_PCM_DATA_SIZE_PER_FRAME) + { + PcmEncData.data = input+index; + PcmEncData.dataLen = VOICE_SBC_PCM_DATA_SIZE_PER_FRAME; + //output[outputOffset++] = 0xAD; + //output[outputOffset++] = 0x02; + btif_sbc_encode_frames(&voice_sbc_encoder, &PcmEncData, &oneChunkConsumed, + &output[outputOffset], &oneChunkOutput, 0xFFFF) ; + outputOffset += oneChunkOutput; + //output[outputOffset++] = 0x00; + + bytes_encoded += oneChunkConsumed; + } + + outputSbcBytes = outputOffset; + } + else + { + PcmEncData.data = input; + PcmEncData.dataLen = inputBytes; + + btif_sbc_encode_frames(&voice_sbc_encoder, &PcmEncData, &bytes_encoded, + output, &outputSbcBytes, 0xFFFF) ; + } + + TRACE(2,"Encode %d bytes PCM data into %d bytes SBC data.", inputBytes, outputSbcBytes); + TRACE(1,"Consumed PCM data %d bytes", bytes_encoded); + + *purchasedBytes = bytes_encoded; + + return outputSbcBytes; +} + +uint32_t voice_sbc_decode(uint8_t* pcm_buffer, CQueue* encodedDataQueue, uint32_t expectedOutputSize, uint8_t isReset) +{ + if (isReset) + { + voice_sbc_init_decoder(); + } + int r = 0; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + uint32_t sbcDataBytesToDecode; + unsigned int pcm_offset = 0; + uint16_t byte_decode; + int8_t ret; + btif_sbc_pcm_data_t voice_PcmDecData; + +get_again: + voice_PcmDecData.data = pcm_buffer+pcm_offset; + voice_PcmDecData.dataLen = 0; + + if (LengthOfCQueue(encodedDataQueue) > VOICE_SBC_ENCODED_DATA_SIZE_PER_FRAME) + { + sbcDataBytesToDecode = VOICE_SBC_ENCODED_DATA_SIZE_PER_FRAME; + } + else + { + sbcDataBytesToDecode = LengthOfCQueue(encodedDataQueue); + } + + len1 = len2 = 0; + r = PeekCQueue(encodedDataQueue, sbcDataBytesToDecode, &e1, &len1, &e2, &len2); + if ((r == CQ_ERR) || (0 == len1)) { + goto exit; + } + + ret = btif_sbc_decode_frames(&voice_sbc_decoder, (unsigned char *)e1, len1, &byte_decode, + &voice_PcmDecData, expectedOutputSize-pcm_offset, voice_sbc_eq_band_gain); + + TRACE(4,"len1 %d byte_decode %d expectedOutputSize %d pcm_offset %d", + len1, byte_decode, expectedOutputSize, pcm_offset); + TRACE(1,"voice_PcmDecData.dataLen %d", voice_PcmDecData.dataLen); + + DeCQueue(encodedDataQueue, 0, byte_decode); + + pcm_offset += voice_PcmDecData.dataLen; + + if (expectedOutputSize == pcm_offset) + { + goto exit; + } + + if ((ret == BT_STS_SDP_CONT_STATE) || (ret == BT_STS_SUCCESS)) { + goto get_again; + } + +exit: + TRACE(1,"Get pcm data size %d", pcm_offset); + return pcm_offset; +} + +int voice_sbc_init(VOICE_SBC_CONFIG_T* pConfig) +{ + voice_sbc_config = *pConfig; + return 0; +} + +#endif diff --git a/services/app_ai/voice_sbc/voice_sbc.h b/services/app_ai/voice_sbc/voice_sbc.h new file mode 100644 index 0000000..4ee12c9 --- /dev/null +++ b/services/app_ai/voice_sbc/voice_sbc.h @@ -0,0 +1,72 @@ +#ifndef __VOICE_SBC_H__ +#define __VOICE_SBC_H__ + +#include "cqueue.h" + +#ifdef __cplusplus +extern "C" { +#endif +#include "codec_sbc.h" + +typedef struct +{ + uint8_t channelCnt; + uint8_t channelMode; + uint8_t bitPool; + uint8_t sizePerSample; + uint8_t sampleRate; + uint8_t numBlocks; + uint8_t numSubBands; + uint8_t mSbcFlag; + uint8_t allocMethod; +} VOICE_SBC_CONFIG_T; + + +#define VOICE_SBC_CHANNEL_COUNT (1) +#define VOICE_SBC_CHANNEL_MODE (BTIF_SBC_CHNL_MODE_MONO) +// bitpool vs block size: +/* +block size = 4 + (4 * nrof_subbands * nrof_channels ) / 8 + round_up(nrof_blocks * nrof_channels * bitpool / 8) + +block size = 4 + (4 * 8 * 1) / 8 + round_up(16 * 1 * bitpool / 8) + +block size = 56 +*/ +// 10 - 28: 3.5KB/s (suggested to be used for android ble) +// 12 - 32: 4KB/s (suggested to be used for ios ble) +// 24 - 56: 7KB/s (suggested to be used for android RFComm) + +#define VOICE_SBC_BIT_POOL (26) +#define VOICE_SBC_BLOCK_SIZE 60 + +#define VOICE_SBC_SIZE_PER_SAMPLE (2) // 16 bits, 1 channel +#define VOICE_SBC_SAMPLE_RATE (BTIF_SBC_CHNL_SAMPLE_FREQ_16) +#define VOICE_SBC_NUM_BLOCKS 15 +#define VOICE_SBC_NUM_SUB_BANDS 8 +#define VOICE_SBC_MSBC_FLAG 1 +#define VOICE_SBC_ALLOC_METHOD BTIF_SBC_ALLOC_METHOD_LOUDNESS + +#define VOICE_SBC_SAMPLE_RATE_VALUE 16000 +#define VOICE_SBC_FRAME_PERIOD_IN_MS (7.5) + +#define VOICE_SBC_PCM_DATA_SIZE_PER_FRAME \ + (((VOICE_SBC_FRAME_PERIOD_IN_MS*VOICE_SBC_SAMPLE_RATE_VALUE)/1000)*VOICE_SBC_SIZE_PER_SAMPLE) + +#define VOICE_SBC_ENCODED_DATA_SIZE_PER_FRAME (VOICE_SBC_BLOCK_SIZE) + + + +// Set the codec capture and encoding interval as 48ms, +// to avoid too small time-slice from interrupting the bluetooth transmission +#define VOICE_SBC_CAPTURE_INTERVAL_IN_MS (120) +uint32_t voice_sbc_encode(uint8_t *input, uint32_t inputBytes, uint32_t* purchasedBytes, uint8_t *output, uint8_t isReset); +uint32_t voice_sbc_decode(uint8_t* pcm_buffer, CQueue* encodedDataQueue, uint32_t expectedOutputSize, uint8_t isReset); +int voice_sbc_init(VOICE_SBC_CONFIG_T* pConfig); +uint32_t voice_sbc_get_frame_len(void); + +#ifdef __cplusplus +} +#endif + +#endif // __VOICE_SBC_H__ + diff --git a/services/app_ibrt/Makefile b/services/app_ibrt/Makefile new file mode 100644 index 0000000..9191dff --- /dev/null +++ b/services/app_ibrt/Makefile @@ -0,0 +1,102 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.c)) + +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.cpp)) + +src_obj := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +IBRT_LIB_NAME := libtws_ibrt_ui + +$(IBRT_LIB_NAME)-y := $(src_obj) + +obj-y := $(IBRT_LIB_NAME).a + +subdir-ccflags-y += \ + -Iservices/osif \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iservices/multimedia/audio/process/resample/include \ + $(BT_IF_INCLUDES) \ + -Iservices/nv_section/factory_section \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iapps/key \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/audioplayers/a2dp_decoder \ + -Iapps/anc/inc \ + -Iapps/factory \ + -Iservices/ble_app \ + -Iservices/ble_app \ + -Iservices/interconnection/green \ + -Iutils/hwtimer_list \ + -Ithirdparty/audio_codec_lib/liblhdc-dec/inc \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/ble_stack/common/api \ + -Iservices/ble_app/app_tws \ + -Iservices/nv_section/log_section \ + -Iservices/ai_voice/manager \ + -Iservices/app_ai/inc \ + -Iapps/battery/ \ + -Iutils/crc16 \ + -Iutils/crc32 \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/voicepath/gsound/gsound_target \ + -Iservices/ble_app/app_main \ + -Iservices/app_tws/inc \ + -Iservices/ai_voice/protocol/gma/gma_manager \ + -Iservices/ai_voice/protocol/gma/gma_crypto \ + -Iservices/ai_voice/protocol/smartvoice/smartvoice_ble\ + -Iservices/ota \ + -Iservices/tota \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/norflash_api \ + -Iservices/ai_voice/transport \ + -Iservices/ai_voice/manager \ + -Iservices/ai_voice/protocol/dual_mic_recording/voice_manager \ + -Iapps/anc/inc + + +ifeq ($(IBRT),1) +subdir-ccflags-y += \ + -Iservices/ibrt_core/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/app_ibrt/inc \ + -Iservices/bt_app +endif + +ifeq ($(OTA_ENABLE),1) +subdir-ccflags-y += \ + -Iservices/ibrt_ota/inc +endif + +ifeq ($(ANC_APP),1) +CFLAGS_app_ibrt_ui_test.o += -DANC_APP +endif + +ifeq ($(VOICE_DATAPATH_ENABLED),1) +subdir-ccflags-y += \ + -Iservices/voicepath/gsound/gsound_custom/inc \ + -Iservices/voicepath/gsound/gsound_target_api_read_only +endif \ No newline at end of file diff --git a/services/app_ibrt/inc/app_ibrt_a2dp.h b/services/app_ibrt/inc/app_ibrt_a2dp.h new file mode 100644 index 0000000..9de9c60 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_a2dp.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_A2DP__ +#define __APP_IBRT_A2DP__ + +a2dp_stream_t *app_bt_get_mobile_a2dp_stream(uint32_t deviceId); +int a2dp_ibrt_sync_set_status(ibrt_a2dp_status_t *a2dp_status); +int a2dp_ibrt_sync_get_status(ibrt_a2dp_status_t *a2dp_status); +int a2dp_ibrt_stream_open_mock(void); +int a2dp_ibrt_session_reset(void); +int a2dp_ibrt_session_new(void); +uint32_t a2dp_ibrt_session_get(void); +int a2dp_ibrt_session_set(uint8_t session); +int a2dp_ibrt_stream_need_autotrigger_set_flag(void); +int a2dp_ibrt_stream_need_autotrigger_getandclean_flag(void); + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_auto_test.h b/services/app_ibrt/inc/app_ibrt_auto_test.h new file mode 100644 index 0000000..5f7a0fb --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_auto_test.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_AUTO_TEST_H__ +#define __APP_IBRT_AUTO_TEST_H__ +#include + +typedef struct +{ + uint8_t local_volume; + uint8_t a2dp_volume; + uint8_t hfp_volume; + uint8_t a2dp_streamming; + uint8_t a2dp_codec_type; + uint8_t a2dp_sample_rate; + uint8_t a2dp_sample_bit; + uint8_t sco_streaming; + uint8_t sco_codec_type; + uint8_t call_status; +} __attribute__((__packed__)) AUTO_TEST_BT_STREAM_STATE_T; + +typedef struct +{ + uint16_t media_active; + uint16_t curr_active_media; // low 8 bits are out direciton, while high 8 bits are in direction + uint8_t promt_exist; // low 8 bits are out direciton, while high 8 bits are in direction +} __attribute__((__packed__)) AUTO_TEST_MEDIA_STATE_T; + +typedef struct +{ + uint32_t current_ms; + uint8_t cpu_freq; + uint8_t super_state; + uint8_t active_event; + uint8_t ibrt_sm_running; + uint8_t ui_state; + uint8_t mobile_link_bt_role; + uint8_t mobile_link_bt_mode; + uint32_t mobile_constate; + uint8_t tws_role; + uint8_t tws_link_bt_role; + uint8_t tws_link_bt_mode; + uint32_t tws_constate; + uint8_t role_switch_state; // 1:ongoing, 0:idle + uint8_t ble_state; + uint8_t ble_operation; + uint8_t ble_connection_state; // bits are in the order of connection index +} __attribute__((__packed__)) AUTO_TEST_UI_STATE_T; + + +typedef struct +{ + uint8_t head[3]; + uint8_t length; + AUTO_TEST_BT_STREAM_STATE_T bt_stream_state; + AUTO_TEST_MEDIA_STATE_T bt_media_state; + AUTO_TEST_UI_STATE_T ui_state; +} __attribute__((__packed__)) AUTO_TEST_STATE_T; + + +extern AUTO_TEST_STATE_T auto_test_state_t; + +#ifdef __cplusplus +extern "C" { +#endif + +void app_tws_ibrt_disconnect_mobile(void); +uint16_t app_ibrt_auto_test_get_tws_page_timeout_value(void); +void app_ibrt_auto_test_init(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/app_ibrt/inc/app_ibrt_auto_test_cmd_handle.h b/services/app_ibrt/inc/app_ibrt_auto_test_cmd_handle.h new file mode 100644 index 0000000..534c851 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_auto_test_cmd_handle.h @@ -0,0 +1,117 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_AUTO_TEST_CMD_HANDLE_H__ +#define __APP_IBRT_AUTO_TEST_CMD_HANDLE_H__ +#include + +#ifdef BES_AUTOMATE_TEST + +//automate test group code +#define AUTO_TEST_A2DP 0 +#define AUTO_TEST_HFP 1 +#define AUTO_TEST_BLE 2 + +#define AUTO_TEST_UI 20 +#define AUTO_TEST_VOICE_PROMPT 21 + +#define AUTO_TEST_AI 30 +#define AUTO_TEST_FLASH 31 +#define AUTO_TEST_OTA 32 + +#define AUTO_TEST_UNUSE 127 + +//voice promt automate test operation code + +// A2DP automate test operation code, configure the respective +// .ini file used for auto test script +#define A2DP_AUTO_TEST_AUDIO_PLAY 0 +#define A2DP_AUTO_TEST_AUDIO_PAUSE 1 +#define A2DP_AUTO_TEST_AUDIO_FORWARD 2 +#define A2DP_AUTO_TEST_AUDIO_BACKWARD 3 +#define A2DP_AUTO_TEST_AVRCP_VOL_UP 4 +#define A2DP_AUTO_TEST_AVRCP_VOL_DOWN 5 + +// HFP automate test operation code, configure the respective +// .ini file used for auto test script +#define HFP_AUTO_TEST_SCO_CREATE 0 +#define HFP_AUTO_TEST_SCO_DISC 1 +#define HFP_AUTO_TEST_CALL_REDIAL 2 +#define HFP_AUTO_TEST_CALL_ANSWER 3 +#define HFP_AUTO_TEST_CALL_HANGUP 4 +#define HFP_AUTO_TEST_VOLUME_UP 5 +#define HFP_AUTO_TEST_VOLUME_DOWN 6 + +// UI automate test operation code , configure the respective +// .ini file used for auto test script +#define UI_AUTO_TEST_OPEN_BOX 0 +#define UI_AUTO_TEST_CLOSE_BOX 1 +#define UI_AUTO_TEST_FETCH_OUT_BOX 2 +#define UI_AUTO_TEST_PUT_IN_BOX 3 +#define UI_AUTO_TEST_WEAR_UP 4 +#define UI_AUTO_TEST_WEAR_DOWN 5 +#define UI_AUTO_TEST_ROLE_SWITCH 6 +#define UI_AUTO_TEST_PHONE_CONN_EVENT 7 +#define UI_AUTO_TEST_RECONN_EVENT 8 +#define UI_AUTO_TEST_CONN_SECOND_MOBILE 9 +#define UI_AUTO_TEST_MOBILE_TWS_DISC 10 +#define UI_AUTO_TEST_PAIRING_MODE 11 +#define UI_AUTO_TEST_FREEMAN_MODE 12 +#define UI_AUTO_TEST_SUSPEND_IBRT 13 +#define UI_AUTO_TEST_RESUME_IBRT 14 +#define UI_AUTO_TEST_SHUT_DOWN 15 +#define UI_AUTO_TEST_REBOOT 16 +#define UI_AUTO_TEST_FACTORY_RESET 17 +#define UI_AUTO_TEST_ASSERT 18 +#define UI_AUTO_TEST_CONNECT_MOBILE 19 +#define UI_AUTO_TEST_DISCONNECT_MOBILE 20 +#define UI_AUTO_TEST_CONNECT_TWS 21 +#define UI_AUTO_TEST_DISCONNECT_TWS 22 +#define UI_AUTO_TEST_ENABLE_TPORTS 23 + +// AI automate test operation code, configure the respective +// .ini file used for auto test script +#define AI_AUTO_TEST_PTT_BUTTON_ACTION 0 +#define AI_AUTO_TEST_DISCONNECT_AI 1 + +// BLE automate test operation code, configure the respective +// .ini file used for auto test script +#define BLE_AUTO_TEST_START_ADV 0 +#define BLE_AUTO_TEST_STOP_ADV 1 +#define BLE_AUTO_TEST_DISCONNECT 2 +#define BLE_AUTO_TEST_START_CONNECT 3 +#define BLE_AUTO_TEST_STOP_CONNECT 4 +#define BLE_AUTO_TEST_START_SCAN 5 +#define BLE_AUTO_TEST_STOP_SCAN 6 +#define BLE_AUTO_TEST_UPDATE_CONN_PARAM 7 + +// flash automate test operation code, configure the respective +// .ini file used for auto test script +#define FLASH_AUTO_TEST_PROGRAM 0 +#define FLASH_AUTO_TEST_ERASE 1 +#define FLASH_AUTO_TEST_FLUSH_NV 2 + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif +#endif + diff --git a/services/app_ibrt/inc/app_ibrt_ble_adv.h b/services/app_ibrt/inc/app_ibrt_ble_adv.h new file mode 100644 index 0000000..9463a8b --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_ble_adv.h @@ -0,0 +1,73 @@ +#ifndef __APP_IBRT__BLE_ADV__H__ +#define __APP_IBRT__BLE_ADV__H__ + +#include "stdint.h" +#include "bluetooth.h" +#ifdef __cplusplus +extern "C" { +#endif + + +#define APP_IBRT_BLE_ADV_INTERVAL 100 + +//HCI opcode +#define HCI_BLE_ADV_CMD_OPCODE 0x200a + +typedef enum { + BLE_STATE_IDLE = 0, + BLE_ADVERTISING = 1, + BLE_STARTING_ADV = 2, + BLE_STOPPING_ADV = 3, +} SLAVE_BLE_STATE_E; + +typedef enum { + BLE_OP_IDLE = 0, + BLE_START_ADV = 1, + BLE_STOP_ADV = 2, +} SLAVE_BLE_OP_E; + +typedef struct +{ + SLAVE_BLE_STATE_E state; + SLAVE_BLE_OP_E op; +} SLAVE_BLE_MODE_T; + +typedef struct { + // le_adv_param + uint16_t advInterval_Ms; + uint8_t adv_type; + bt_bdaddr_t bd_addr; + uint8_t own_addr_type; + uint8_t peer_addr_type; + uint8_t adv_chanmap; + uint8_t adv_filter_policy; + // adv data + uint8_t adv_data_len; + uint8_t adv_data[31]; + + // scan response data + uint8_t scan_rsp_data_len; + uint8_t scan_rsp_data[31]; +}app_ble_adv_para_data_t; +typedef struct +{ + uint8_t num_hci_cmd_packets; + uint16_t cmd_opcode; + uint8_t param[1]; +} __attribute__ ((packed)) slave_ble_cmd_comp_t; + + +void app_ibrt_ble_adv_para_data_init(void); +void app_ibrt_ble_adv_start(uint8_t adv_type, uint16_t advInterval); +void app_ibrt_ble_adv_stop(void); +void app_ibrt_ble_adv_data_config(uint8_t *advData, uint8_t advDataLen, + uint8_t *scanRspData, uint8_t scanRspDataLen); +void app_ibrt_ble_switch_activities(void); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/services/app_ibrt/inc/app_ibrt_custom_cmd.h b/services/app_ibrt/inc/app_ibrt_custom_cmd.h new file mode 100644 index 0000000..05a9403 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_custom_cmd.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_CUSTOM_CMD__ +#define __APP_IBRT_CUSTOM_CMD__ + +#define APP_IBRT_CMD_BASE 0x8000 +#define APP_IBRT_CMD_MASK 0x0F00 +#define APP_IBRT_CUSTOM_CMD_PREFIX 0x0100 +#define APP_IBRT_OTA_CMD_PREFIX 0x0200 +#define APP_IBRT_OTA_TWS_CMD_PREFIX 0x0300 + +int app_ibrt_customif_cmd_table_get(void **cmd_tbl, uint16_t *cmd_size); +int app_ibrt_ota_cmd_table_get(void **cmd_tbl, uint16_t *cmd_size); +int app_ibrt_ota_tws_cmd_table_get(void **cmd_tbl, uint16_t *cmd_size); + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_customif_cmd.h b/services/app_ibrt/inc/app_ibrt_customif_cmd.h new file mode 100644 index 0000000..14f89a6 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_customif_cmd.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_IF_CUSTOM_CMD__ +#define __APP_IBRT_IF_CUSTOM_CMD__ + +#include "app_ibrt_custom_cmd.h" + +typedef enum +{ + APP_IBRT_CUSTOM_CMD_TEST1 = APP_IBRT_CMD_BASE|APP_IBRT_CUSTOM_CMD_PREFIX|0x01, + APP_IBRT_CUSTOM_CMD_TEST2 = APP_IBRT_CMD_BASE|APP_IBRT_CUSTOM_CMD_PREFIX|0x02, + APP_IBRT_CUSTOM_CMD_TEST3 = APP_IBRT_CMD_BASE|APP_IBRT_CUSTOM_CMD_PREFIX|0x03, + APP_IBRT_CUSTOM_CMD_TEST4 = APP_IBRT_CMD_BASE|APP_IBRT_CUSTOM_CMD_PREFIX|0x04, + APP_IBRT_CUSTOM_CMD_TEST5 = APP_IBRT_CMD_BASE|APP_IBRT_CUSTOM_CMD_PREFIX|0x05, + + APP_TWS_CMD_SHARE_FASTPAIR_INFO = APP_IBRT_CMD_BASE|APP_IBRT_CUSTOM_CMD_PREFIX|0x03, + +#ifdef BISTO_ENABLED + APP_TWS_CMD_BISTO_DIP_SYNC = APP_IBRT_CMD_BASE|APP_IBRT_CUSTOM_CMD_PREFIX|0x04, +#endif +#ifdef __DUAL_MIC_RECORDING__ + APP_IBRT_CUSTOM_CMD_DMA_AUDIO = APP_IBRT_CMD_BASE | APP_IBRT_CUSTOM_CMD_PREFIX | 0x05, +#endif + //new customer cmd add here +} app_ibrt_custom_cmd_code_e; + +typedef struct +{ + uint8_t rsv; + uint8_t buff[6]; +} __attribute__((packed))ibrt_custom_cmd_test_t; + +void app_ibrt_customif_cmd_test(ibrt_custom_cmd_test_t *cmd_test); +void app_ibrt_customif_test3_cmd_send(uint8_t *p_buff, uint16_t length); +void app_ibrt_customif_test4_cmd_send(uint8_t *p_buff, uint16_t length); + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_customif_ui.h b/services/app_ibrt/inc/app_ibrt_customif_ui.h new file mode 100644 index 0000000..0f3a82c --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_customif_ui.h @@ -0,0 +1,94 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_CUSTOMIF_UI_UI__ +#define __APP_IBRT_CUSTOMIF_UI_UI__ + +#define IBRT_UI_ROLE_SWITCH_TIME_THRESHOLD (2) // +#define IBRT_UI_ROLE_SWITCH_THRESHOLD_WITH_RSSI (10) //dbm +#define IBRT_UI_CLOSE_BOX_EVENT_WAIT_RESPONSE_TIMEOUT (400)//ms +#define IBRT_UI_MOBILE_RECONNECT_WAIT_READY_TIMEOUT (1000)//ms +#define IBRT_UI_TWS_RECONNECT_WAIT_READY_TIMEOUT (500)//ms +#define IBRT_UI_RECONNECT_MOBILE_WAIT_RESPONSE_TIMEOUT (5000)//5s +#define IBRT_UI_RECONNECT_IBRT_WAIT_RESPONSE_TIMEOUT (300)//ms +#define IBRT_UI_NV_SLAVE_RECONNECT_TWS_WAIT_RESPONSE_TIMEOUT (1000)//ms +#define IBRT_UI_NV_MASTER_RECONNECT_TWS_WAIT_RESPONSE_TIMEOUT (300)//ms +#define IBRT_UI_DISABLE_BT_SCAN_TIMEOUT (3000000)//5min +#define IBRT_UI_STOP_IBRT_TIMEOUT (3000000)//40min + + +#define IBRT_UI_OPEN_RECONNECT_MOBILE_MAX_TIMES (0) +#define IBRT_UI_OPEN_RECONNECT_TWS_MAX_TIMES (0) +#define IBRT_UI_RECONNECT_MOBILE_MAX_TIMES (30) +#define IBRT_UI_RECONNECT_TWS_MAX_TIMES (30) +#define IBRT_UI_RECONNECT_IBRT_MAX_TIMES (1) + +#define IBRT_UI_LONG_POLL_INTERVAL (0x68) +#define IBRT_UI_DEFAULT_POLL_INTERVAL (0x34) +#define IBRT_UI_SHORT_POLL_INTERVAL (0x34) + +#define IBRT_UI_DEFAULT_POLL_INTERVAL_IN_SCO (0x9c) +#define IBRT_UI_SHORT_POLL_INTERVAL_IN_SCO (0x3C) + +#define IBRT_TWS_PAGE_TIMEOUT_ON_CONNECT_SUCCESS_LAST (0x2000) +#define IBRT_TWS_PAGE_TIMEOUT_ON_CONNECT_FAILED_LAST (0x2000) +#define IBRT_MOBILE_PAGE_TIMEOUT (0x2000) +#define IBRT_TWS_PAGE_TIMEOUT_ON_RECONNECT_MOBILE_FAILED (0x2000) +#define IBRT_TWS_PAGE_TIMEOUT_ON_RECONNECT_MOBILE_SUCCESS (0x2000) + +#define IBRT_UI_TWS_CONNECTION_TIMEOUT (3200)//1600 slot=1s/3200 slot = 2s/8000slot=5s + + +#define IBRT_TWS_RECONNECT_ONE_CYCLE (3) +#define IBRT_MOBILE_RECONNECT_ONE_CYCLE (5) + +#define IBRT_CONTROLLER_DBG_STATE_TIMEOUT (200) + +#define IBRT_UI_RX_SEQ_ERROR_TIMEOUT (10000) +#define IBRT_UI_RX_SEQ_ERROR_THRESHOLD (50) +#define IBRT_UI_RX_SEQ_ERROR_RECOVER_TIMEOUT (5000) + + +#define IBRT_STOP_IBRT_WAIT_TIME (500) +#define TWS_CONN_FAILED_WAIT_TIME (5) +#define IBRT_EVENT_HUNG_TIMEOUT (200)//ms + +#define IBRT_TWS_SWITCH_RSSI_THRESHOLD (30) +#define IBRT_UI_RADICAL_SAN_INTERVAL_NV_MASTER (BTIF_BT_DEFAULT_PAGE_SCAN_INTERVAL/4) +#define IBRT_UI_RADICAL_SAN_INTERVAL_NV_SLAVE ((BTIF_BT_DEFAULT_PAGE_SCAN_INTERVAL/4)-0x48) + +/* +* ibrt ui event error handling timeout +*/ +#define SM_RUNNING_TIMEOUT (20000) +#define PEER_SM_RUNNING_TIMEOUT (2 * (IBRT_UI_OPEN_RECONNECT_MOBILE_MAX_TIMES+2) * (IBRT_UI_RECONNECT_MOBILE_WAIT_RESPONSE_TIMEOUT+5000)) +#define RECONNECT_PEER_SM_RUNNING_TIMEOUT (2 * (IBRT_UI_RECONNECT_MOBILE_MAX_TIMES+2) * (IBRT_UI_RECONNECT_MOBILE_WAIT_RESPONSE_TIMEOUT+5000)) +#define CONNECT_NO_03_TIMEOUT (15000) +#define DISCONNECT_NO_05_TIMEOUT (8000) + +#define IBRT_UI_TWS_CMD_SEND_TIMEOUT (10000) +#define IBRT_UI_TWS_COUNTER_THRESHOLD (500000) +#define IBRT_UI_TWS_SWITCH_STABLE_TIMEOUT (300) +#define IBRT_UI_DISC_TWS_TIMEOUT (10000) +#ifdef TEST_OVER_THE_AIR_ENANBLED +#define IBRT_UI_RSSI_MONITOR_TIMEOUT (1000)//ms +#else +#define IBRT_UI_RSSI_MONITOR_TIMEOUT (5000)//ms +#endif +int app_ibrt_customif_ui_start(void); +bool app_ibrt_customif_ui_tws_switch(void); +bool app_ibrt_customif_ui_is_tws_switching(void); + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_hf.h b/services/app_ibrt/inc/app_ibrt_hf.h new file mode 100644 index 0000000..bd8a3c1 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_hf.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_HF__ +#define __APP_IBRT_HF__ + +#ifdef __cplusplus +extern "C" { +#endif + +int hfp_ibrt_service_connected_mock(void); + +int hfp_ibrt_sync_get_status(ibrt_hfp_status_t *hfp_status); + +int hfp_ibrt_sync_set_status(ibrt_hfp_status_t *hfp_status); + +int hfp_ibrt_sco_audio_disconnected(void); + +int hfp_ibrt_sco_audio_connected(hfp_sco_codec_t codec, uint16_t sco_connhdl); + +bool btapp_hfp_is_sco_active(void); + +uint8_t btapp_hfp_get_call_state(void); + +uint8_t btapp_hfp_get_call_setup(void); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_if.h b/services/app_ibrt/inc/app_ibrt_if.h new file mode 100644 index 0000000..f3b20b7 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_if.h @@ -0,0 +1,190 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_IF__ +#define __APP_IBRT_IF__ +#include "cmsis_os.h" +#include "app_tws_ibrt.h" +#include "app_ibrt_ui.h" +#include "app_key.h" + +typedef enum { + APP_IBRT_IF_STATUS_SUCCESS = 0, + APP_IBRT_IF_STATUS_PENDING = 1, + APP_IBRT_IF_STATUS_ERROR_INVALID_PARAMETERS = 2, + APP_IBRT_IF_STATUS_ERROR_NO_CONNECTION = 3, + APP_IBRT_IF_STATUS_ERROR_CONNECTION_EXISTS = 4, + APP_IBRT_IF_STATUS_IN_PROGRESS = 5, + APP_IBRT_IF_STATUS_ERROR_DUPLICATE_REQUEST = 6, + APP_IBRT_IF_STATUS_ERROR_INVALID_STATE = 7, + APP_IBRT_IF_STATUS_ERROR_TIMEOUT = 8, + APP_IBRT_IF_STATUS_ERROR_ROLE_SWITCH_FAILED = 9, + APP_IBRT_IF_STATUS_ERROR_UNEXPECTED_VALUE = 10, + APP_IBRT_IF_STATUS_ERROR_OP_NOT_ALLOWED = 11, +} AppIbrtStatus; + + +typedef enum { + APP_IBRT_IF_A2DP_IDLE = 0, + APP_IBRT_IF_A2DP_CODEC_CONFIGURED = 1, + APP_IBRT_IF_A2DP_OPEN = 2, + APP_IBRT_IF_A2DP_STREAMING = 3, + APP_IBRT_IF_A2DP_CLOSED = 4, +}AppIbrtA2dpState; + +typedef enum { + APP_IBRT_IF_AVRCP_DISCONNECTED = 0, + APP_IBRT_IF_AVRCP_CONNECTED = 1, + APP_IBRT_IF_AVRCP_PLAYING = 2, + APP_IBRT_IF_AVRCP_PAUSED = 3, + APP_IBRT_IF_AVRCP_VOLUME_UPDATED = 4, +}AppIbrtAvrcpState; + +typedef enum { + APP_IBRT_IF_HFP_SLC_DISCONNECTED = 0, + APP_IBRT_IF_HFP_CLOSED = 1, + APP_IBRT_IF_HFP_SCO_CLOSED = 2, + APP_IBRT_IF_HFP_PENDING = 3, + APP_IBRT_IF_HFP_SLC_OPEN = 4, + APP_IBRT_IF_HFP_NEGOTIATE = 5, + APP_IBRT_IF_HFP_CODEC_CONFIGURED = 6, + APP_IBRT_IF_HFP_SCO_OPEN = 7, + APP_IBRT_IF_HFP_INCOMING_CALL = 8, + APP_IBRT_IF_HFP_OUTGOING_CALL = 9, + APP_IBRT_IF_HFP_RING_INDICATION = 10, +} AppIbrtHfpState; + +typedef enum { + APP_IBRT_IF_NO_CALL = 0, + APP_IBRT_IF_CALL_ACTIVE = 1, + APP_IBRT_IF_HOLD = 2, + APP_IBRT_IF_SETUP_INCOMMING = 3, + APP_IBRT_IF_SETUP_OUTGOING = 4, + APP_IBRT_IF_SETUP_ALERT = 5, +} AppIbrtCallStatus; + + +#ifdef __cplusplus +extern "C" { +#endif +typedef APP_IBRT_UI_VENDER_EVENT_HANDLER_IND APP_IBRT_IF_VENDER_EVENT_HANDLER_IND; +typedef APP_IBRT_UI_GLOBAL_HANDLER_IND APP_IBRT_IF_GLOBAL_HANDLER_IND; +typedef APP_IBRT_UI_GLOBAL_EVENT_UPDATE_IND APP_IBRT_IF_GLOBAL_EVENT_UPDATE_IND; +typedef APP_IBRT_UI_PROFILE_STATE_CHANGE_IND APP_IBRT_IF_PROFILE_STATE_CHANGE_IND; +typedef APP_IBRT_UI_CONNECT_MOBILE_HANDLER_IND APP_IBRT_IF_CONNECT_MOBILE_NEEDED_IND; +typedef APP_IBRT_UI_TWS_SWITCH_HANDLER_IND APP_IBRT_IF_TWS_SWITCH_NEEDED_IND; + +typedef app_ibrt_ui_t app_ibrt_if_ui_t; +typedef ibrt_ctrl_t app_ibrt_if_ctrl_t; + +enum APP_IBRT_IF_SNIFF_CHECKER_USER_T +{ + APP_IBRT_IF_SNIFF_CHECKER_USER_HFP, + APP_IBRT_IF_SNIFF_CHECKER_USER_A2DP, + APP_IBRT_IF_SNIFF_CHECKER_USER_SPP, + + APP_IBRT_IF_SNIFF_CHECKER_USER_QTY +}; + +enum APP_IBRT_IF_SLEEP_HOOK_BLOCKER_T +{ + APP_IBRT_IF_SLEEP_HOOK_BLOCKER_A2DP_STREAMING = 1<<0, + APP_IBRT_IF_SLEEP_HOOK_BLOCKER_HFP_SCO = 1<<1, + + APP_IBRT_IF_SLEEP_HOOK_BLOCKER_ALL = (1<<0)|(1<<1), +}; + +void app_ibrt_if_register_global_handler_ind(APP_IBRT_IF_GLOBAL_HANDLER_IND handler); +void app_ibrt_if_register_vender_handler_ind(APP_IBRT_IF_VENDER_EVENT_HANDLER_IND handler); +void app_ibrt_if_register_connect_mobile_needed_ind(APP_IBRT_IF_CONNECT_MOBILE_NEEDED_IND connect_moible_need_ind); +void app_ibrt_if_register_tws_switch_needed_ind(APP_IBRT_IF_TWS_SWITCH_NEEDED_IND tws_switch_need_ind); +void app_ibrt_if_register_global_event_update_ind(APP_IBRT_IF_GLOBAL_EVENT_UPDATE_IND handler); +void app_ibrt_if_register_link_connected_ind(APP_IBRT_UI_CONNECTED_HANDLER_IND mobile_connected_ind, + APP_IBRT_UI_CONNECTED_HANDLER_IND ibrt_connected_ind, + APP_IBRT_UI_CONNECTED_HANDLER_IND tws_connected_ind); +void app_ibrt_if_register_profile_state_change_ind(APP_IBRT_IF_PROFILE_STATE_CHANGE_IND handler); +void app_ibrt_if_register_pairing_mode_ind(APP_IBRT_UI_PAIRING_MODE_HANDLER_IND set_callback, APP_IBRT_UI_PAIRING_MODE_HANDLER_IND clear_callback); + +int app_ibrt_if_config_load(ibrt_config_t *config); +int app_ibrt_if_reconfig(ibrt_config_t *config); +int app_ibrt_if_ui_reconfig(ibrt_ui_config_t *config); +int app_ibrt_core_if_reconfig(ibrt_config_t *config); +int app_ibrt_if_config(ibrt_ui_config_t *ui_config); +int app_ibrt_if_event_entry(ibrt_event_type event); +void app_ibrt_if_choice_connect_second_mobile(void); +void app_ibrt_if_choice_mobile_connect(uint8_t index); +void app_ibrt_if_disconnect_mobile_tws_link(void); +app_ibrt_if_ui_t* app_ibrt_if_ui_get_ctx(void); +app_ibrt_if_ctrl_t *app_ibrt_if_get_bt_ctrl_ctx(void); +void app_ibrt_if_enter_pairing_after_tws_connected(void); +void app_ibrt_if_enter_freeman_pairing(void); +int app_ibrt_if_voice_report_trig_retrigger(void); +int app_ibrt_if_force_audio_retrigger(void); +int app_ibrt_if_force_audio_retrigger_slave_sync(void); +int app_ibrt_if_keyboard_notify(APP_KEY_STATUS *status, void *param); +void app_ibrt_if_a2dp_lowlatency_scan(uint16_t interval, uint16_t window, uint8_t interlanced); +void app_ibrt_if_a2dp_restore_scan(void); +void app_ibrt_if_sco_lowlatency_scan(uint16_t interval, uint16_t window, uint8_t interlanced); +void app_ibrt_if_sco_restore_scan(void); +#ifdef IBRT_SEARCH_UI +void app_start_tws_serching_direactly(); +void app_bt_manager_ibrt_role_process(const btif_event_t *Event); +void app_ibrt_search_ui_init(bool boxOperation,ibrt_event_type evt_type); +void app_ibrt_enter_limited_mode(void); +void app_ibrt_reconfig_btAddr_from_nv(); +void app_bt_enter_mono_pairing_mode(void); +#endif + +void app_ibrt_ui_automate_test_cmd_handler(uint8_t group_code, uint8_t operation_code, uint8_t *param, uint8_t param_len); +void app_ibrt_auto_test_inform_cmd_received(uint8_t group_code, uint8_t operation_code); +int app_ibrt_ui_test_cmd_handler(unsigned char *buf, unsigned int length); +void app_ibrt_if_ctx_checker(void); +extern "C" bool btdrv_get_page_pscan_coex_enable(void); +int app_ibrt_if_tws_sniff_block(uint32_t block_next_sec); +int app_ibrt_if_sniff_checker_start(enum APP_IBRT_IF_SNIFF_CHECKER_USER_T user); +int app_ibrt_if_sniff_checker_stop(enum APP_IBRT_IF_SNIFF_CHECKER_USER_T user); +int app_ibrt_if_sniff_checker_init(uint32_t delay_ms); +int app_ibrt_if_sniff_checker_reset(void); + +void app_ibrt_if_exec_sleep_hook_blocker_set(APP_IBRT_IF_SLEEP_HOOK_BLOCKER_T blocker); +void app_ibrt_if_exec_sleep_hook_blocker_clr(APP_IBRT_IF_SLEEP_HOOK_BLOCKER_T blocker); +bool app_ibrt_if_exec_sleep_hook_blocker_is_a2dp_streaming(void); +bool app_ibrt_if_exec_sleep_hook_blocker_is_hfp_sco(void); +bool app_ibrt_if_exec_sleep_hook_allowed(void); +int app_ibrt_if_config_keeper_clear(void); +int app_ibrt_if_config_keeper_mobile_update(bt_bdaddr_t *addr); +int app_ibrt_if_config_keeper_tws_update(bt_bdaddr_t *addr); +void app_ibrt_ui_adaptive_fa_rx_gain(void); +void app_tws_ibrt_record_sync_id(void); +void app_tws_ibrt_resume_sync_id(void); +void app_ibrt_if_pairing_mode_refresh(void); +bool app_ibrt_if_tws_switch_prepare_needed(uint32_t *wait_ms); +void app_ibrt_if_tws_swtich_prepare(void); +void app_ibrt_if_tws_switch_prepare_done_in_bt_thread(IBRT_ROLE_SWITCH_USER_E user, uint32_t role); +bool app_ibrt_if_start_ibrt_onporcess(void); +bool app_ibrt_if_tws_switch_onporcess(void); +AppIbrtStatus app_ibrt_if_get_a2dp_state(AppIbrtA2dpState *a2dp_state); +AppIbrtStatus app_ibrt_if_get_avrcp_state(AppIbrtAvrcpState *avrcp_state); +AppIbrtStatus app_ibrt_if_get_hfp_state(AppIbrtHfpState *hfp_state); +AppIbrtStatus app_ibrt_if_get_hfp_call_status(AppIbrtCallStatus *call_status); +ibrt_role_e app_ibrt_if_get_ibrt_role(); + + + +#ifdef __cplusplus +} +#endif /* */ + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_if_internal.h b/services/app_ibrt/inc/app_ibrt_if_internal.h new file mode 100644 index 0000000..3720a91 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_if_internal.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_IF_INTERNAL__ +#define __APP_IBRT_IF_INTERNAL__ +#ifdef __cplusplus +extern "C" { +#endif + +bool app_ibrt_if_false_trigger_protect(ibrt_event_type evt_type); +bool app_ibrt_if_tws_reconnect_allowed(void); +void app_ibrt_if_sniff_event_callback(const btif_event_t *event); +bool app_ibrt_if_tws_sniff_allowed(void); +void app_ibrt_if_audio_mute(void); +void app_ibrt_if_audio_recover(void); +void app_ibrt_if_pairing_mode_refresh(void); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_keyboard.h b/services/app_ibrt/inc/app_ibrt_keyboard.h new file mode 100644 index 0000000..5720c73 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_keyboard.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_KEYBOARD__ +#define __APP_IBRT_KEYBOARD__ +#include "app_key.h" + +#ifdef IBRT_SEARCH_UI +void app_ibrt_search_ui_handle_key(APP_KEY_STATUS *status, void *param); +#else +void app_ibrt_normal_ui_handle_key(APP_KEY_STATUS *status, void *param); +#endif + +void app_ibrt_send_keyboard_request(uint8_t *p_buff, uint16_t length); + +void app_ibrt_keyboard_request_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +#define IBRT_ACTION_PLAY 0x01 +#define IBRT_ACTION_PAUSE 0x02 +#define IBRT_ACTION_FORWARD 0x03 +#define IBRT_ACTION_BACKWARD 0x04 +#define IBRT_ACTION_AVRCP_VOLUP 0x05 +#define IBRT_ACTION_AVRCP_VOLDN 0x06 +#define IBRT_ACTION_HFSCO_CREATE 0x07 +#define IBRT_ACTION_HFSCO_DISC 0x08 +#define IBRT_ACTION_REDIAL 0x09 +#define IBRT_ACTION_ANSWER 0x0a +#define IBRT_ACTION_HANGUP 0x0b +#define IBRT_ACTION_LOCAL_VOLUP 0x0c +#define IBRT_ACTION_LOCAL_VOLDN 0x0d +#define IBRT_ACTION_ANC_NOTIRY_MASTER_EXCHANGE_COEF 0x0e +#define IBRT_ACTION_SYNC_WNR 0x0f + + +void app_ibrt_if_start_user_action(uint8_t *p_buff, uint16_t length); +void app_ibrt_ui_perform_user_action(uint8_t *p_buff, uint16_t length); + +extern bool Is_Slave_Key_Down_Event; + +#define TWS_Sync_Shutdowm 1 +#define QXW_TOUCH_INEAR_DET 0 +#define BT_FACTORY_CLEAR_RECORD 0 + +#define Auto_Shutdowm_TIME 300 + +#if(TWS_Sync_Shutdowm) +int app_ibrt_poweroff_notify_force(void); +int app_ibrt_reboot_notify_force(void); +#endif +#endif diff --git a/services/app_ibrt/inc/app_ibrt_nvrecord.h b/services/app_ibrt/inc/app_ibrt_nvrecord.h new file mode 100644 index 0000000..86e36de --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_nvrecord.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_IF_NVRECORD__ +#define __APP_IBRT_IF_NVRECORD__ +#include "cmsis_os.h" +#include "app_tws_ibrt.h" + +#ifdef __cplusplus +extern "C" { +#endif +void app_ibrt_nvrecord_config_load(void *config); + +void app_ibrt_nvrecord_update_ibrt_mode_tws(bool status); + +bt_status_t app_ibrt_nvrecord_get_mobile_addr(bt_bdaddr_t *mobile_addr); + +int app_ibrt_nvrecord_get_latest_mobiles_addr(bt_bdaddr_t *mobile_addr1, bt_bdaddr_t* mobile_addr2); + +int app_ibrt_nvrecord_choice_mobile_addr(bt_bdaddr_t *mobile_addr, uint8_t index); + +void app_ibrt_nvrecord_delete_all_mobile_record(void); + + +#ifdef __cplusplus +} +#endif /* */ + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_ota_cmd.h b/services/app_ibrt/inc/app_ibrt_ota_cmd.h new file mode 100644 index 0000000..48b7935 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_ota_cmd.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_OTA_CMD__ +#define __APP_IBRT_OTA_CMD__ + +#include "app_ibrt_custom_cmd.h" + +#define RESEND_TIME 2 + +#define app_ibrt_ota_image_buff_cmd_rsp_timeout_handler_null (0) +#define app_ibrt_ota_image_buff_cmd_rsp_handler_null (0) + +typedef enum +{ +#ifdef IBRT_OTA + IBRT_OTA_TWS_GET_VERSION_CMD = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x01, + IBRT_OTA_TWS_SELECT_SIDE_CMD = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x02, + IBRT_OTA_TWS_BP_CHECK_CMD = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x03, + IBRT_OTA_TWS_START_OTA_CMD = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x04, + IBRT_OTA_TWS_OTA_CONFIG_CMD = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x05, + IBRT_OTA_TWS_SEGMENT_CRC_CMD = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x06, + IBRT_OTA_TWS_IMAGE_CRC_CMD = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x07, + IBRT_OTA_TWS_IMAGE_OVERWRITE_CMD = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x08, + IBRT_OTA_TWS_ROLE_SWITCH_CMD = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x0C, + IBRT_OTA_TWS_ACK_CMD = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x0D, +#endif + IBRT_OTA_TWS_IMAGE_BUFF = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x09, + IBRT_COMMON_OTA = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x0B, +// IBRT_OTA_TWS_IMAGE_BUFF_SLAVE = APP_IBRT_CMD_BASE|APP_IBRT_OTA_TWS_CMD_PREFIX|0x0A, +} app_ibrt_ota_tws_cmd_code_e; + +#ifdef IBRT_OTA +extern uint32_t ibrt_ota_cmd_type; +extern uint32_t twsBreakPoint; +//extern uint8_t ibrt_connect_slave; +extern uint8_t errOtaCode; +#endif + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_ota_update.h b/services/app_ibrt/inc/app_ibrt_ota_update.h new file mode 100644 index 0000000..cdb089a --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_ota_update.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_OTA_UPDATE_CMD__ +#define __APP_IBRT_OTA_UPDATE_CMD__ +#define APP_TWS_CTRL_BUFFER_LEN 512 + +#include "app_ibrt_custom_cmd.h" + +typedef enum +{ + APP_TWS_CMD_OTA_UPDATE_NOW = APP_IBRT_OTA_CMD_PREFIX | 0x01, + APP_TWS_CMD_UPDATE_SECTION = APP_IBRT_OTA_CMD_PREFIX | 0x02, + APP_TWS_CMD_CHECK_UPDATE_INFO = APP_IBRT_OTA_CMD_PREFIX | 0x03, + APP_TWS_CMD_CHECK_UPDATE_INFO2 = APP_IBRT_OTA_CMD_PREFIX | 0x04, + APP_TWS_CMD_SYNC_BREAKPIONT = APP_IBRT_OTA_CMD_PREFIX | 0x05, + APP_TWS_CMD_VALIDATION_DONE = APP_IBRT_OTA_CMD_PREFIX | 0x06, + //new customer cmd add here +} app_ibrt_ota_cmd_code_e; + +typedef struct +{ + uint8_t* address; + uint32_t length; +} __attribute__((packed))ibrt_ota_check_cmd_t; + +typedef struct +{ + uint32_t local_point; + uint32_t remote_point; +} __attribute__((packed))ibrt_ota_sync_breakpoint_cmd_t; + +typedef struct +{ + uint8_t flag; +} __attribute__((packed))ibrt_ota_sync_validation_cmd_t; + +typedef struct +{ + uint32_t address; + uint32_t length; + uint8_t number; + uint32_t point; + uint32_t crc; + uint8_t buff[APP_TWS_CTRL_BUFFER_LEN]; +} __attribute__((packed))ibrt_ota_update_cmd_t; + +#ifdef __cplusplus +extern "C" { +#endif + +void reset_error_list(); +uint32_t get_error_list(); +void set_all_error_list(); +void set_error_list(uint16_t list); +void app_ibrt_view_update_sector(); +void app_ibrt_view_update_list(); +void app_ibrt_ota_check_update_list(); +void app_ibrt_ota_update_immediately(); +void app_ibrt_ota_force_update(); +void app_ibrt_ota_check_update_info(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_peripheral_manager.h b/services/app_ibrt/inc/app_ibrt_peripheral_manager.h new file mode 100644 index 0000000..940c6c1 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_peripheral_manager.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_PERIPHERAL_MANAGER_H__ +#define __APP_IBRT_PERIPHERAL_MANAGER_H__ + +/************************* +* automate_cmd format +* item len(byte) +* group_code 1 +* opera_code 1 +* test_times 1 +* param_len 1 +* *param param_len(0-255) +*************************/ +#define AUTOMATE_TEST_CMD_CRC_RECORD_LEN (2) +#define AUTOMATE_TEST_CMD_PARAM_MAX_LEN (255) + +typedef struct { + uint8_t group_code; + uint8_t opera_code; + uint8_t test_times; + uint8_t param_len; + uint8_t param[0]; +} AUTO_TEST_CMD_T; + +typedef struct { + uint32_t message_id; + uint32_t message_ptr; + uint32_t message_Param0; + uint32_t message_Param1; + uint32_t message_Param2; +} TWS_PD_MSG_BODY; + +typedef struct { + TWS_PD_MSG_BODY msg_body; +} TWS_PD_MSG_BLOCK; + +int app_ibrt_peripheral_mailbox_put(TWS_PD_MSG_BLOCK* msg_src); +int app_ibrt_peripheral_mailbox_free(TWS_PD_MSG_BLOCK* msg_p); +int app_ibrt_peripheral_mailbox_get(TWS_PD_MSG_BLOCK** msg_p); +void app_ibrt_peripheral_thread_init(void); +void app_ibrt_peripheral_run0(uint32_t ptr); +void app_ibrt_peripheral_run1(uint32_t ptr, uint32_t param0); +void app_ibrt_peripheral_run2(uint32_t ptr, uint32_t param0, uint32_t param1); +void app_ibrt_peripheral_auto_test_stop(void); + +#endif diff --git a/services/app_ibrt/inc/app_ibrt_rssi.h b/services/app_ibrt/inc/app_ibrt_rssi.h new file mode 100644 index 0000000..1727626 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_rssi.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_RSSI_H__ +#define __APP_IBRT_RSSI_H__ +#if defined(IBRT) + +typedef struct +{ + int8_t fa_gain; + float sample_ref; + int8_t cur_buf_size_l; +}tota_stutter_t; + +void app_ibrt_rssi_get_stutter(uint8_t * data,uint32_t * data_len); +void app_ibrt_debug_parse(uint8_t *data, uint32_t data_len); + +#ifdef __cplusplus +extern "C" { +#endif +void app_ibrt_ui_rssi_reset(void); +void app_ibrt_ui_rssi_process(void); +void app_ibrt_ui_check_roleswitch_timer_cb(void const *current_evt); +void app_ibrt_get_peer_mobile_rssi(uint8_t *p_buff, uint16_t length); +void app_ibrt_get_peer_mobile_rssi_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_get_peer_mobile_rssi_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +#ifdef __cplusplus + } +#endif + +#endif +#endif diff --git a/services/app_ibrt/inc/app_ibrt_ui_test.h b/services/app_ibrt/inc/app_ibrt_ui_test.h new file mode 100644 index 0000000..cedf2fb --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_ui_test.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_UI_TEST_H__ +#define __APP_IBRT_UI_TEST_H__ +#include + +#if defined(IBRT) + +typedef void (*app_uart_test_function_handle)(void); + +typedef struct +{ + const char* string; + app_uart_test_function_handle function; +} app_uart_handle_t; + +app_uart_test_function_handle app_ibrt_ui_find_uart_handle(unsigned char* buf); + +void app_ibrt_ui_test_key_init(void); + +void app_ibrt_ui_test_init(void); + +int app_ibrt_ui_test_config_load(void *config); + +void app_ibrt_ui_sync_status(uint8_t status); + +void app_ibrt_ui_test_voice_assistant_key(APP_KEY_STATUS *status, void *param); + +void app_ibrt_search_ui_gpio_key_handle(APP_KEY_STATUS *status, void *param); +void pwrkey_detinit(void); +void startpwrkey_det(int ms); +#endif +#endif diff --git a/services/app_ibrt/inc/app_ibrt_ui_test_cmd_if.h b/services/app_ibrt/inc/app_ibrt_ui_test_cmd_if.h new file mode 100644 index 0000000..866e276 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_ui_test_cmd_if.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_UI_TEST_CMD_IF_H__ +#define __APP_IBRT_UI_TEST_CMD_IF_H__ +#include + +extern void app_bt_volumedown(); +extern void app_bt_volumeup(); +extern void app_ibrt_nvrecord_rebuild(void); + +#ifdef __cplusplus +extern "C" { +#endif + +void btif_pts_hf_create_link_with_pts(void); +void btif_pts_av_create_channel_with_pts(void); +void btif_pts_ar_connect_with_pts(void); + + +void app_ibrt_ui_audio_play_test(void); +void app_ibrt_ui_audio_pause_test(void); +void app_ibrt_ui_audio_forward_test(void); +void app_ibrt_ui_audio_backward_test(void); +void app_ibrt_ui_avrcp_volume_up_test(void); +void app_ibrt_ui_avrcp_volume_down_test(void); +void app_ibrt_ui_hfsco_create_test(void); +void app_ibrt_ui_hfsco_disc_test(void); +void app_ibrt_ui_call_redial_test(void); +void app_ibrt_ui_call_answer_test(void); +void app_ibrt_ui_call_hangup_test(void); +void app_ibrt_ui_local_volume_up_test(void); +void app_ibrt_ui_local_volume_down_test(void); +void app_ibrt_ui_get_tws_conn_state_test(void); + + +void app_ibrt_ui_soft_reset_test(void); +void app_ibrt_ui_iic_uart_switch_test(void); +void app_ibrt_ui_get_a2dp_state_test(void); +void app_ibrt_ui_get_avrcp_state_test(void); +void app_ibrt_ui_get_hfp_state_test(void); +void app_ibrt_ui_get_call_status_test(); +void app_ibrt_ui_get_ibrt_role_test(void); + +void app_ibrt_ui_soft_reset_test(void); +void app_ibrt_ui_iic_uart_switch_test(void); +void app_ibrt_ui_open_box_event_test(void); +void app_ibrt_ui_fetch_out_box_event_test(void); +void app_ibrt_ui_put_in_box_event_test(void); +void app_ibrt_ui_close_box_event_test(void); +void app_ibrt_ui_reconnect_event_test(void); +void app_ibrt_ui_ware_up_event_test(void); +void app_ibrt_ui_ware_down_event_test(void); +void app_ibrt_ui_phone_connect_event_test(void); +void app_ibrt_ui_shut_down_test(void); +void app_ibrt_enable_tports_test(void); +void app_ibrt_ui_tws_swtich_test(void); +void app_ibrt_ui_suspend_ibrt_test(void); +void app_ibrt_ui_resume_ibrt_test(void); +void app_ibrt_ui_pairing_mode_test(void); +void app_ibrt_ui_freeman_pairing_mode_test(void); +void app_ibrt_inquiry_start_test(void); +void app_ibrt_role_switch_test(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/app_ibrt/inc/app_ibrt_voice_report.h b/services/app_ibrt/inc/app_ibrt_voice_report.h new file mode 100644 index 0000000..c540b89 --- /dev/null +++ b/services/app_ibrt/inc/app_ibrt_voice_report.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_VOICE_REPORT_H__ +#define __APP_IBRT_VOICE_REPORT_H__ + +typedef struct +{ + uint32_t aud_id; + uint32_t aud_pram; + uint32_t tg_tick; + uint32_t vol; +} __attribute__((packed)) app_ibrt_voice_report_info_t; + +typedef struct +{ + uint32_t aud_id; + uint32_t aud_pram; + uint32_t vol; +} __attribute__((packed)) app_ibrt_voice_report_request_t; + +#ifdef __cplusplus +extern "C" { +#endif + +int app_ibrt_voice_report_trigger_checker(void); +int app_ibrt_voice_report_trigger_init(uint32_t aud_id, uint32_t aud_pram); +int app_ibrt_voice_report_trigger_deinit(void); +void app_ibrt_send_voice_report_request_req(uint8_t *p_buff, uint16_t length); +void app_ibrt_voice_report_request_req_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_send_voice_report_start_req(uint8_t *p_buff, uint16_t length); +void app_ibrt_voice_report_request_start_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +int app_ibrt_if_voice_report_handler(uint32_t aud_id, uint16_t aud_pram); +bool app_ibrt_voice_report_is_me(uint32_t voice_chnlsel); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/app_ibrt/src/app_ibrt_auto_test.cpp b/services/app_ibrt/src/app_ibrt_auto_test.cpp new file mode 100644 index 0000000..71f761f --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_auto_test.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "app_tws_ibrt_trace.h" +#include "factory_section.h" +#include "hal_timer.h" +#include "apps.h" +#include "app_battery.h" +#include "app_anc.h" +#include "app_a2dp.h" +#include "app_key.h" +#include "app_ibrt_auto_test.h" +#include "app_ibrt_if.h" +#include "app_ibrt_ui.h" +#include "app_ibrt_ui_test.h" +#include "app_ibrt_peripheral_manager.h" +#include "a2dp_decoder.h" +#include "app_ibrt_keyboard.h" +#include "nvrecord_env.h" +#include "nvrecord_ble.h" +#include "app_tws_if.h" +#include "besbt.h" +#include "app_bt.h" +#include "app_ai_if.h" +#include "app_ai_manager_api.h" +#include "app_bt_media_manager.h" +#include "app_audio.h" +#include "app_ble_mode_switch.h" + +#if defined(IBRT) +#include "btapp.h" +extern struct BT_DEVICE_T app_bt_device; +extern int hfp_volume_get(enum BT_DEVICE_ID_T id); +int bt_sco_player_get_codetype(void); + +AUTO_TEST_STATE_T auto_test_state_t = {0}; + + +uint16_t app_ibrt_auto_test_get_tws_page_timeout_value(void) +{ + return app_ibrt_ui_get_tws_page_timeout_value(); +} + +#ifdef BES_AUTOMATE_TEST +void app_ibrt_auto_test_print_earphone_state(void const *n) +{ + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + auto_test_state_t.head[0] = 0xE1; + auto_test_state_t.head[1] = 0x38; + auto_test_state_t.head[2] = 0x7C; + auto_test_state_t.length = sizeof(auto_test_state_t); + + //a2dp & hfp state + auto_test_state_t.bt_stream_state.local_volume = app_bt_stream_local_volume_get(); + auto_test_state_t.bt_stream_state.a2dp_volume = a2dp_volume_get(BT_DEVICE_ID_1); + auto_test_state_t.bt_stream_state.hfp_volume = hfp_volume_get(BT_DEVICE_ID_1); + auto_test_state_t.bt_stream_state.a2dp_streamming = a2dp_is_music_ongoing(); + auto_test_state_t.bt_stream_state.a2dp_codec_type = app_bt_device.codec_type[BT_DEVICE_ID_1]; + auto_test_state_t.bt_stream_state.a2dp_sample_rate = app_bt_device.sample_rate[BT_DEVICE_ID_1]; + auto_test_state_t.bt_stream_state.a2dp_sample_bit = app_bt_device.sample_bit[BT_DEVICE_ID_1]; + + auto_test_state_t.bt_stream_state.sco_streaming = is_sco_mode(); + auto_test_state_t.bt_stream_state.sco_codec_type = (uint8_t)bt_sco_player_get_codetype(); + app_ibrt_if_get_hfp_call_status((AppIbrtCallStatus *)&auto_test_state_t.bt_stream_state.call_status); + + //media state + auto_test_state_t.bt_media_state.media_active = bt_media_get_media_active(BT_DEVICE_ID_1); + auto_test_state_t.bt_media_state.curr_active_media = bt_media_get_current_media(); + auto_test_state_t.bt_media_state.promt_exist = app_audio_list_playback_exist(); + + // ui state + auto_test_state_t.ui_state.current_ms = TICKS_TO_MS(hal_sys_timer_get()); + auto_test_state_t.ui_state.cpu_freq = hal_sysfreq_get(); + auto_test_state_t.ui_state.super_state = p_ibrt_ui->super_state; + auto_test_state_t.ui_state.active_event = p_ibrt_ui->active_event; + auto_test_state_t.ui_state.ibrt_sm_running = p_ibrt_ui->ibrt_sm_running; + auto_test_state_t.ui_state.ui_state = p_ibrt_ui->box_state; + + if (IBRT_SLAVE != p_ibrt_ctrl->current_role) + { + auto_test_state_t.ui_state.mobile_link_bt_role = app_tws_ibrt_get_local_mobile_role(); + auto_test_state_t.ui_state.mobile_link_bt_mode = p_ibrt_ctrl->mobile_mode; + auto_test_state_t.ui_state.mobile_constate = p_ibrt_ctrl->mobile_constate; + //auto_test_state_t.ui_state.mobile_connect = app_tws_ibrt_mobile_link_connected(); + } + auto_test_state_t.ui_state.tws_role = p_ibrt_ctrl->current_role; + auto_test_state_t.ui_state.tws_link_bt_role = app_tws_ibrt_get_local_tws_role(); + auto_test_state_t.ui_state.tws_link_bt_mode = p_ibrt_ctrl->tws_mode; + auto_test_state_t.ui_state.tws_constate = p_ibrt_ctrl->tws_constate; + auto_test_state_t.ui_state.role_switch_state = + (p_ibrt_ctrl->slave_tws_switch_pending || + p_ibrt_ctrl->master_tws_switch_pending); +#ifdef __IAG_BLE_INCLUDE__ + auto_test_state_t.ui_state.ble_state = app_ble_get_current_state(); + auto_test_state_t.ui_state.ble_operation = app_ble_get_current_operation(); + auto_test_state_t.ui_state.ble_connection_state = 0; + for (uint8_t i = 0; i < BLE_CONNECTION_MAX; i++) + { + if (app_ble_is_connection_on(i)) + { + auto_test_state_t.ui_state.ble_connection_state |= + (1 << i); + } + } +#endif + + //TRACE(1, "earphone len %d state :", auto_test_state_t.length); + DUMP8("%02x", (uint8_t *)&auto_test_state_t, auto_test_state_t.length); +} + +#define APP_AUTO_TEST_PRINT_STATE_TIME_IN_MS 500 +osTimerDef (APP_AUTO_TEST_PRINT_STATE_TIMEOUT, app_ibrt_auto_test_print_earphone_state); +osTimerId app_auto_test_print_state_timeout_timer_id = NULL; +#endif + +void app_ibrt_auto_test_init(void) +{ +#ifdef BES_AUTOMATE_TEST + memset((uint8_t *)&auto_test_state_t, 0, sizeof(auto_test_state_t)); + if (app_auto_test_print_state_timeout_timer_id == NULL) + { + app_auto_test_print_state_timeout_timer_id = osTimerCreate(osTimer(APP_AUTO_TEST_PRINT_STATE_TIMEOUT), osTimerPeriodic, NULL); + osTimerStart(app_auto_test_print_state_timeout_timer_id, APP_AUTO_TEST_PRINT_STATE_TIME_IN_MS); + } +#endif +} + +void app_ibrt_auto_test_inform_cmd_received(uint8_t group_code, + uint8_t operation_code) +{ + AUTO_TEST_TRACE(2, "AUTO_TEST_CMD received:%d:%d:", group_code, operation_code); +} + +#endif + diff --git a/services/app_ibrt/src/app_ibrt_auto_test_cmd_handle.cpp b/services/app_ibrt/src/app_ibrt_auto_test_cmd_handle.cpp new file mode 100644 index 0000000..63d12e9 --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_auto_test_cmd_handle.cpp @@ -0,0 +1,651 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "app_tws_ibrt_trace.h" +#include "factory_section.h" +#include "apps.h" +#include "app_battery.h" +#include "app_anc.h" +#include "app_key.h" +#include "app_ibrt_if.h" +#include "app_ibrt_ui_test.h" +#include "app_ibrt_auto_test.h" +#include "app_ibrt_auto_test_cmd_handle.h" +#include "app_ibrt_ui_test_cmd_if.h" +#include "app_ibrt_peripheral_manager.h" +#include "a2dp_decoder.h" +#include "app_ibrt_keyboard.h" +#include "nvrecord_env.h" +#include "nvrecord_ble.h" +#include "norflash_api.h" +#include "app_tws_if.h" +#include "besbt.h" +#include "app_bt.h" +#include "app_ai_if.h" +#include "app_ai_manager_api.h" +#include "app_ble_uart.h" +#if defined(BISTO_ENABLED) +#include "gsound_custom_actions.h" +#include "gsound_custom_bt.h" +#include "gsound_custom_ble.h" + +#endif +#ifdef __IAG_BLE_INCLUDE__ +#include "app.h" +#include "app_ble_mode_switch.h" +#endif + +#ifdef BES_OTA +#include "ota_control.h" +#endif + +#if defined(IBRT) +#ifdef BES_AUTOMATE_TEST + +/***************************************************************************** + Prototype : app_ibrt_ui_reboot_test + Description : system reboot test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/5/8 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_reboot_test(void) +{ + app_ibrt_peripheral_auto_test_stop(); + app_reset(); +} + +/***************************************************************************** + Prototype : app_ibrt_ui_factory_reset_test + Description : Factory reset test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/5/8 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_factory_reset_test(void) +{ + app_ibrt_peripheral_auto_test_stop(); + nv_record_rebuild(); + app_reset(); +} + +/***************************************************************************** + Prototype : app_tws_ibrt_disconnect_tws + Description : disconnect tws + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/24 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_disconnect_tws(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + btif_remote_device_t *remdev = NULL; + + if(app_tws_ibrt_tws_link_connected()) + { + remdev = btif_me_get_remote_device_by_handle(p_ibrt_ctrl->tws_conhandle); + + if (remdev != NULL) + { + app_tws_ibrt_disconnect_connection(remdev); + } + } + +} + +/***************************************************************************** + Prototype : app_ibrt_ui_auto_test_voice_promt_handle + Description : handle voice promt test cmd handle + Input : uint8_t operation_code + : uint8_t *param + : uint8_t param_len + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2020/3/3 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +static void app_ibrt_ui_auto_test_voice_promt_handle(uint8_t operation_code, + uint8_t *param, + uint8_t param_len) +{ + TRACE(2, "%s op_code 0x%x", __func__, operation_code); + switch (operation_code) + { + default: + break; + } +} + +/***************************************************************************** +Prototype : app_ibrt_ui_auto_test_a2dp_handle +Description : handle a2dp test cmd handle +Input : uint8_t operation_code + : uint8_t *param + : uint8_t param_len +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2020/3/3 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +static void app_ibrt_ui_auto_test_a2dp_handle(uint8_t operation_code, + uint8_t *param, + uint8_t param_len) +{ + TRACE(2, "%s op_code 0x%x", __func__, operation_code); + + switch (operation_code) + { + case A2DP_AUTO_TEST_AUDIO_PLAY: + app_ibrt_ui_audio_play_test(); + break; + case A2DP_AUTO_TEST_AUDIO_PAUSE: + app_ibrt_ui_audio_pause_test(); + break; + case A2DP_AUTO_TEST_AUDIO_FORWARD: + app_ibrt_ui_audio_forward_test(); + break; + case A2DP_AUTO_TEST_AUDIO_BACKWARD: + app_ibrt_ui_audio_backward_test(); + break; + case A2DP_AUTO_TEST_AVRCP_VOL_UP: + app_bt_volumeup(); + break; + case A2DP_AUTO_TEST_AVRCP_VOL_DOWN: + app_bt_volumedown(); + break; + default: + break; + } +} + +/***************************************************************************** +Prototype : app_ibrt_ui_auto_test_hfp_handle +Description : handle hfp test cmd handle +Input : uint8_t operation_code + : uint8_t *param + : uint8_t param_len +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2020/3/3 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +static void app_ibrt_ui_auto_test_hfp_handle(uint8_t operation_code, + uint8_t *param, + uint8_t param_len) +{ + TRACE(2, "%s op_code 0x%x", __func__, operation_code); + + switch (operation_code) + { + case HFP_AUTO_TEST_SCO_CREATE: + app_ibrt_ui_hfsco_create_test(); + break; + case HFP_AUTO_TEST_SCO_DISC: + app_ibrt_ui_hfsco_disc_test(); + break; + case HFP_AUTO_TEST_CALL_REDIAL: + app_ibrt_ui_call_redial_test(); + break; + case HFP_AUTO_TEST_CALL_ANSWER: + app_ibrt_ui_call_answer_test(); + break; + case HFP_AUTO_TEST_CALL_HANGUP: + app_ibrt_ui_call_hangup_test(); + break; + case HFP_AUTO_TEST_VOLUME_UP: + app_ibrt_ui_local_volume_up_test(); + break; + case HFP_AUTO_TEST_VOLUME_DOWN: + app_ibrt_ui_local_volume_down_test(); + break; + default: + break; + } +} +/***************************************************************************** +Prototype : app_ibrt_ui_auto_test_ui_handle +Description : handle UI test cmd handle +Input : uint8_t operation_code + : uint8_t *param + : uint8_t param_len +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2020/3/3 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +static void app_ibrt_ui_auto_test_ui_handle(uint8_t operation_code, + uint8_t *param, + uint8_t param_len) +{ + TRACE(2, "%s op_code 0x%x", __func__, operation_code); + + switch (operation_code) + { + case UI_AUTO_TEST_OPEN_BOX: + app_ibrt_ui_open_box_event_test(); + break; + case UI_AUTO_TEST_CLOSE_BOX: + app_ibrt_ui_close_box_event_test(); + break; + case UI_AUTO_TEST_FETCH_OUT_BOX: + app_ibrt_ui_fetch_out_box_event_test(); + break; + case UI_AUTO_TEST_PUT_IN_BOX: + app_ibrt_ui_put_in_box_event_test(); + break; + case UI_AUTO_TEST_WEAR_UP: + app_ibrt_ui_ware_up_event_test(); + break; + case UI_AUTO_TEST_WEAR_DOWN: + app_ibrt_ui_ware_down_event_test(); + break; + case UI_AUTO_TEST_ROLE_SWITCH: + app_tws_if_trigger_role_switch(); + break; + case UI_AUTO_TEST_PHONE_CONN_EVENT: + app_ibrt_ui_phone_connect_event_test(); + break; + case UI_AUTO_TEST_RECONN_EVENT: + app_ibrt_ui_reconnect_event_test(); + break; + case UI_AUTO_TEST_CONN_SECOND_MOBILE: + app_ibrt_ui_choice_connect_second_mobile(); + break; + case UI_AUTO_TEST_MOBILE_TWS_DISC: + app_ibrt_if_disconnect_mobile_tws_link(); + break; + case UI_AUTO_TEST_PAIRING_MODE: + app_ibrt_ui_pairing_mode_test(); + break; + case UI_AUTO_TEST_FREEMAN_MODE: + app_ibrt_ui_freeman_pairing_mode_test(); + break; + case UI_AUTO_TEST_SUSPEND_IBRT: + app_ibrt_ui_suspend_ibrt_test(); + break; + case UI_AUTO_TEST_RESUME_IBRT: + app_ibrt_ui_resume_ibrt_test(); + break; + case UI_AUTO_TEST_SHUT_DOWN: + app_ibrt_ui_shut_down_test(); + break; + case UI_AUTO_TEST_REBOOT: + app_ibrt_ui_reboot_test(); + break; + case UI_AUTO_TEST_FACTORY_RESET: + app_ibrt_ui_factory_reset_test(); + break; + case UI_AUTO_TEST_ASSERT: + app_ibrt_peripheral_auto_test_stop(); + ASSERT(false, "Force Panic!!!"); + break; + case UI_AUTO_TEST_CONNECT_MOBILE: + app_ibrt_if_choice_mobile_connect(0); + break; + case UI_AUTO_TEST_DISCONNECT_MOBILE: + app_tws_ibrt_disconnect_mobile(); + break; + case UI_AUTO_TEST_CONNECT_TWS: + app_tws_ibrt_create_tws_connection(app_ibrt_auto_test_get_tws_page_timeout_value()); + break; + case UI_AUTO_TEST_DISCONNECT_TWS: + app_ibrt_ui_disconnect_tws(); + break; + case UI_AUTO_TEST_ENABLE_TPORTS: + app_ibrt_enable_tports_test(); + break; + default: + break; + } +} + +/***************************************************************************** +Prototype : app_ibrt_ui_auto_test_ai_simulate_button_action +Description : simulate ai button action +Input : enum APP_KEY_EVENT_T eventCode +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2020/5/8 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_auto_test_ai_simulate_button_action(enum APP_KEY_EVENT_T eventCode) +{ + APP_KEY_STATUS keyEvent; + keyEvent.code = APP_KEY_CODE_GOOGLE; + keyEvent.event = eventCode; + app_ibrt_ui_test_voice_assistant_key(&keyEvent, NULL); +} + +/***************************************************************************** +Prototype : app_ibrt_ui_auto_test_ai_disconnect +Description : disconnect AI connection +Input : None +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2020/5/8 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_auto_test_ai_disconnect(void) +{ +#ifdef __AI_VOICE__ + //if (app_ai_ble_is_connected() && AI_TRANSPORT_BLE != app_ai_get_transport_type()) + //{ + //app_ai_disconnect_ble(); + //} + //if (app_ai_spp_is_connected() && AI_TRANSPORT_SPP != app_ai_get_transport_type()) + //{ + //app_ai_spp_disconnlink(); + //} +#endif + +#ifdef BISTO_ENABLED + //gsound_custom_ble_disconnect_ble_link(); + //gsound_custom_bt_disconnect_all_channel(); +#endif +} + +/***************************************************************************** +Prototype : app_ibrt_ui_auto_test_ai_handle +Description : handle AI test cmd handle +Input : uint8_t operation_code + : uint8_t *param + : uint8_t param_len +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2020/3/3 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +static void app_ibrt_ui_auto_test_ai_handle(uint8_t operation_code, + uint8_t *param, + uint8_t param_len) +{ + TRACE(2, "%s op_code 0x%x", __func__, operation_code); + switch (operation_code) + { + case AI_AUTO_TEST_PTT_BUTTON_ACTION: + app_ibrt_ui_auto_test_ai_simulate_button_action((enum APP_KEY_EVENT_T)*param); + break; + case AI_AUTO_TEST_DISCONNECT_AI: + app_ibrt_ui_auto_test_ai_disconnect(); + break; + default: + break; + } +} + +typedef struct +{ + uint8_t scanFilterPolicy; + uint16_t scanWindowInMs; + uint16_t scanIntervalInMs; +} APP_IBRT_UI_AUTO_TEST_BLE_SCAN_PARAM_T; + +typedef struct +{ + uint8_t conidx; + uint32_t min_interval_in_ms; + uint32_t max_interval_in_ms; + uint32_t supervision_timeout_in_ms; + uint8_t slaveLantency; +} APP_IBRT_UI_AUTO_TEST_BLE_UPDATED_CONN_PARAM_T; + +/***************************************************************************** +Prototype : app_ibrt_ui_auto_test_ble_handle +Description : handle ble test cmd handle +Input : uint8_t operation_code + : uint8_t *param + : uint8_t param_len +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2020/3/3 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +static void app_ibrt_ui_auto_test_ble_handle(uint8_t operation_code, + uint8_t *param, + uint8_t param_len) +{ + TRACE(2, "%s op_code 0x%x", __func__, operation_code); +#ifdef __IAG_BLE_INCLUDE__ + switch (operation_code) + { + case BLE_AUTO_TEST_START_ADV: + { + uint16_t advIntervalMs = *(uint16_t *)param; + app_ble_start_connectable_adv(advIntervalMs); + break; + } + case BLE_AUTO_TEST_STOP_ADV: + { + app_ble_stop_activities(); + break; + } + case BLE_AUTO_TEST_DISCONNECT: + { + app_ble_disconnect_all(); + break; + } + case BLE_AUTO_TEST_START_CONNECT: + { + // six bytes ble address as the parameter + app_ble_start_connect(param); + break; + } + case BLE_AUTO_TEST_STOP_CONNECT: + { + app_ble_stop_activities(); + break; + } + case BLE_AUTO_TEST_START_SCAN: + { + APP_IBRT_UI_AUTO_TEST_BLE_SCAN_PARAM_T* pScanParam = + (APP_IBRT_UI_AUTO_TEST_BLE_SCAN_PARAM_T *)param; + app_ble_start_scan((enum BLE_SCAN_FILTER_POLICY)(pScanParam->scanFilterPolicy), + pScanParam->scanWindowInMs, pScanParam->scanIntervalInMs); + break; + } + case BLE_AUTO_TEST_STOP_SCAN: + { + app_ble_stop_activities(); + break; + } + case BLE_AUTO_TEST_UPDATE_CONN_PARAM: + { + #ifdef __IAG_BLE_INCLUDE__ + APP_IBRT_UI_AUTO_TEST_BLE_UPDATED_CONN_PARAM_T* pConnParam + = (APP_IBRT_UI_AUTO_TEST_BLE_UPDATED_CONN_PARAM_T *)param; + if (app_ble_is_connection_on(pConnParam->conidx)) + { + l2cap_update_param(pConnParam->conidx, + pConnParam->min_interval_in_ms, + pConnParam->max_interval_in_ms, + pConnParam->supervision_timeout_in_ms, + pConnParam->slaveLantency); + } + #endif + break; + } + default: + break; + } +#endif +} +/***************************************************************************** +Prototype : app_ibrt_ui_auto_test_flash_handle +Description : handle flash test cmd handle +Input : uint8_t operation_code + : uint8_t *param + : uint8_t param_len +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2020/3/3 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +static void app_ibrt_ui_auto_test_flash_handle(uint8_t operation_code, + uint8_t *param, + uint8_t param_len) +{ + TRACE(2, "%s op_code 0x%x", __func__, operation_code); + switch (operation_code) + { + case FLASH_AUTO_TEST_PROGRAM: + break; + case FLASH_AUTO_TEST_ERASE: + break; + case FLASH_AUTO_TEST_FLUSH_NV: + { + nv_record_flash_flush(); + norflash_flush_all_pending_op(); + break; + } + default: + break; + } +} + +/***************************************************************************** +Prototype : app_ibrt_ui_automate_test_cmd_handler +Description : ibrt ui automate test cmd handler +Input : uint8_t group_code +: uint8_t operation_code +: uint8_t *param +: uint8_t param_len +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2020/3/3 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +extern "C" void app_ibrt_ui_automate_test_cmd_handler(uint8_t group_code, + uint8_t operation_code, + uint8_t *param, + uint8_t param_len) +{ + switch (group_code) + { + case AUTO_TEST_VOICE_PROMPT: + app_ibrt_ui_auto_test_voice_promt_handle(operation_code, param, param_len); + break; + case AUTO_TEST_A2DP: + app_ibrt_ui_auto_test_a2dp_handle(operation_code, param, param_len); + break; + case AUTO_TEST_HFP: + app_ibrt_ui_auto_test_hfp_handle(operation_code, param, param_len); + break; + case AUTO_TEST_UI: + app_ibrt_ui_auto_test_ui_handle(operation_code, param, param_len); + break; + case AUTO_TEST_AI: + app_ibrt_ui_auto_test_ai_handle(operation_code, param, param_len); + break; + case AUTO_TEST_BLE: + app_ibrt_ui_auto_test_ble_handle(operation_code, param, param_len); + break; + case AUTO_TEST_FLASH: + app_ibrt_ui_auto_test_flash_handle(operation_code, param, param_len); + break; + case AUTO_TEST_UNUSE: + break; + default: + break; + } +} + +#endif +#endif + diff --git a/services/app_ibrt/src/app_ibrt_ble_adv.cpp b/services/app_ibrt/src/app_ibrt_ble_adv.cpp new file mode 100644 index 0000000..46693d4 --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_ble_adv.cpp @@ -0,0 +1,311 @@ +#include "app_ibrt_ble_adv.h" +#include "hal_trace.h" +#include "me_api.h" +#include "cmsis_os.h" +#include "factory_section.h" +#include "co_bt_defines.h" +#include "app_tws_ibrt.h" + +SLAVE_BLE_MODE_T slaveBleMode; +static app_ble_adv_para_data_t app_ble_adv_para_data_cfg; +#define APP_IBRT_BLE_ADV_DATA_MAX_LEN (31) +#define APP_IBRT_BLE_SCAN_RSP_DATA_MAX_LEN (31) + +const char *g_slave_ble_state_str[] = +{ + "BLE_STATE_IDLE", + "BLE_ADVERTISING", + "BLE_STARTING_ADV", + "BLE_STOPPING_ADV", +}; + +const char *g_slave_ble_op_str[] = +{ + "BLE_OP_IDLE", + "BLE_START_ADV", + "BLE_STOP_ADV", + "BLE_STOPPING_ADV", +}; + +#define SET_SLAVE_BLE_STATE(newState) \ + do \ + { \ + TRACE(3,"[BLE][STATE]%s->%s at line %d", g_slave_ble_state_str[slaveBleMode.state], g_slave_ble_state_str[newState], __LINE__); \ + slaveBleMode.state = (newState); \ + } while (0); + +#define SET_SLAVE_BLE_OP(newOp) \ + do \ + { \ + TRACE(3,"[BLE][OP]%s->%s at line %d", g_slave_ble_op_str[slaveBleMode.op], g_slave_ble_op_str[newOp], __LINE__); \ + slaveBleMode.op = (newOp); \ + } while (0); +/***************************************************************************** + Prototype : app_slave_ble_cmd_complete_callback + Description : stop ble adv + Input : const void *para + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/12/28 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_slave_ble_cmd_complete_callback(const void *para) +{ + slave_ble_cmd_comp_t *p_cmd_complete = (slave_ble_cmd_comp_t *)para; + + switch (p_cmd_complete->cmd_opcode) + { + case HCI_BLE_ADV_CMD_OPCODE: + if(!p_cmd_complete->param[0]) + app_ibrt_ble_switch_activities(); + else + { + TRACE(2,"%s error p_cmd_complete->param[0] %d", __func__, p_cmd_complete->param[0]); + SET_SLAVE_BLE_STATE(BLE_STATE_IDLE); + SET_SLAVE_BLE_OP(BLE_OP_IDLE); + } + default: + break; + } +} + +/***************************************************************************** + Prototype : app_ibrt_ble_adv_para_data_init + Description : initialize ble adv parameter and adv data + Input : None + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/12/28 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ble_adv_para_data_init(void) +{ + app_ble_adv_para_data_t *adv_para_cfg = &app_ble_adv_para_data_cfg; + + adv_para_cfg->adv_type = ADV_CONN_UNDIR; + adv_para_cfg->advInterval_Ms = APP_IBRT_BLE_ADV_INTERVAL; + adv_para_cfg->own_addr_type = ADDR_PUBLIC; + adv_para_cfg->peer_addr_type = ADDR_PUBLIC; + adv_para_cfg->adv_chanmap = ADV_ALL_CHNLS_EN; + adv_para_cfg->adv_filter_policy = ADV_ALLOW_SCAN_ANY_CON_ANY; + memset(adv_para_cfg->bd_addr.address, 0, BTIF_BD_ADDR_SIZE); + + const char* ble_name_in_nv = (const char*)factory_section_get_ble_name(); + uint32_t nameLen = strlen(ble_name_in_nv); + + ASSERT(APP_IBRT_BLE_ADV_DATA_MAX_LEN >= nameLen, "ble adv data exceed"); + + adv_para_cfg->adv_data_len = 0; + adv_para_cfg->adv_data[adv_para_cfg->adv_data_len++] = nameLen+1; + adv_para_cfg->adv_data[adv_para_cfg->adv_data_len++] = 0x08; + memcpy(&adv_para_cfg->adv_data[adv_para_cfg->adv_data_len], ble_name_in_nv, nameLen); + adv_para_cfg->adv_data_len += nameLen; + + adv_para_cfg->scan_rsp_data_len = 0; + memset(adv_para_cfg->scan_rsp_data,0,sizeof(adv_para_cfg->scan_rsp_data)); + + memset(&slaveBleMode, 0, sizeof(slaveBleMode)); + btif_me_register_cmd_complete_callback(HCI_CMD_COMPLETE_USER_BLE, app_ibrt_slave_ble_cmd_complete_callback); +} + +/***************************************************************************** + Prototype : app_ibrt_ble_set_adv_para_handler + Description : config ble adv parameter + Input : app_ble_adv_para_data_t *adv_para_cfg + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/12/28 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ble_set_adv_para_handler(app_ble_adv_para_data_t *adv_para_cfg) +{ + btif_adv_para_struct_t adv_para; + adv_para.adv_type = adv_para_cfg->adv_type; + adv_para.interval_max = adv_para_cfg->advInterval_Ms * 8 / 5; + adv_para.interval_min = adv_para_cfg->advInterval_Ms * 8 / 5; + adv_para.own_addr_type = adv_para_cfg->own_addr_type; + adv_para.peer_addr_type = adv_para_cfg->peer_addr_type; + adv_para.adv_chanmap = adv_para_cfg->adv_chanmap; + adv_para.adv_filter_policy = adv_para_cfg->adv_filter_policy; + memcpy(adv_para.bd_addr.address, adv_para_cfg->bd_addr.address, BTIF_BD_ADDR_SIZE); + + btif_me_ble_set_adv_parameters(&adv_para); +} +/***************************************************************************** + Prototype : app_ibrt_ble_set_adv_data_handler + Description : config ble adv data and scan response data + Input : app_ble_adv_para_data_t *adv_data_cfg + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/12/28 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ble_set_adv_data_handler(app_ble_adv_para_data_t *adv_data_cfg) +{ + btif_me_ble_set_adv_data(adv_data_cfg->adv_data_len, adv_data_cfg->adv_data); + btif_me_ble_set_scan_rsp_data(adv_data_cfg->scan_rsp_data_len, adv_data_cfg->scan_rsp_data); +} +/***************************************************************************** + Prototype : app_ibrt_ble_adv_start + Description : enable ble adv + Input : uint8_t adv_type, uint16_t advInterval + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/12/28 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ble_adv_start(uint8_t adv_type, uint16_t advInterval) +{ + TRACE(2,"ble adv start with adv_type %d advIntervalms %dms", adv_type, advInterval); + app_ble_adv_para_data_cfg.adv_type = adv_type; + app_ble_adv_para_data_cfg.advInterval_Ms = advInterval; + + switch(slaveBleMode.state) + { + case BLE_ADVERTISING: + SET_SLAVE_BLE_STATE(BLE_STOPPING_ADV); + SET_SLAVE_BLE_OP(BLE_START_ADV); + btif_me_ble_set_adv_en(false); + break; + case BLE_STARTING_ADV: + case BLE_STOPPING_ADV: + SET_SLAVE_BLE_OP(BLE_START_ADV); + break; + case BLE_STATE_IDLE: + SET_SLAVE_BLE_STATE(BLE_STARTING_ADV); + app_ibrt_ble_set_adv_para_handler(&app_ble_adv_para_data_cfg); + app_ibrt_ble_set_adv_data_handler(&app_ble_adv_para_data_cfg); + btif_me_ble_set_adv_en(true); + break; + default: + break; + } + +} +/***************************************************************************** + Prototype : app_ibrt_ble_adv_stop + Description : disable ble adv + Input : None + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/12/28 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ble_adv_stop(void) +{ + TRACE(1,"%s",__func__); + SET_SLAVE_BLE_STATE(BLE_STOPPING_ADV); + SET_SLAVE_BLE_OP(BLE_STOP_ADV); + btif_me_ble_set_adv_en(false); +} +/***************************************************************************** + Prototype : app_ibrt_ble_switch_activities + Description : ble adv state machine switch + Input : None + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/12/28 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ble_switch_activities(void) +{ + switch(slaveBleMode.state) + { + case BLE_STARTING_ADV: + SET_SLAVE_BLE_STATE(BLE_ADVERTISING); + if(slaveBleMode.op == BLE_START_ADV) + { + SET_SLAVE_BLE_OP(BLE_OP_IDLE); + } + break; + case BLE_STOPPING_ADV: + SET_SLAVE_BLE_STATE(BLE_STATE_IDLE); + if(slaveBleMode.op == BLE_STOP_ADV) + { + SET_SLAVE_BLE_OP(BLE_OP_IDLE); + } + break; + default: + break; + } + switch(slaveBleMode.op) + { + case BLE_START_ADV: + app_ibrt_ble_adv_start(ADV_CONN_UNDIR, app_ble_adv_para_data_cfg.advInterval_Ms); + break; + default: + break; + } +} + +/***************************************************************************** + Prototype : app_ibrt_ble_adv_data_config + Description : config ble adv data and scan response data by customer + Input : uint8_t *advData, uint8_t advDataLen + : uint8_t *scanRspData, uint8_t scanRspDataLen + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/12/28 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ble_adv_data_config(uint8_t *advData, uint8_t advDataLen, + uint8_t *scanRspData, uint8_t scanRspDataLen) +{ + ASSERT(APP_IBRT_BLE_ADV_DATA_MAX_LEN >= advDataLen, "ble adv data len exceed"); + ASSERT(APP_IBRT_BLE_SCAN_RSP_DATA_MAX_LEN >= scanRspDataLen, "scan response data len exceed") + memcpy(app_ble_adv_para_data_cfg.adv_data, advData, advDataLen); + memcpy(app_ble_adv_para_data_cfg.scan_rsp_data, scanRspData, scanRspDataLen); + app_ble_adv_para_data_cfg.adv_data_len = advDataLen; + app_ble_adv_para_data_cfg.scan_rsp_data_len = scanRspDataLen; +} + + + diff --git a/services/app_ibrt/src/app_ibrt_customif_cmd.cpp b/services/app_ibrt/src/app_ibrt_customif_cmd.cpp new file mode 100644 index 0000000..928b4ac --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_customif_cmd.cpp @@ -0,0 +1,258 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "string.h" +#include "app_tws_ibrt_trace.h" +#include "app_tws_ctrl_thread.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_ibrt_customif_cmd.h" +#include "app_tws_if.h" +#include "app_dip.h" +#ifdef BISTO_ENABLED +#include "gsound_custom.h" +#endif +#ifdef __DUAL_MIC_RECORDING__ +#include "ai_control.h" +#include "app_recording_handle.h" +#endif +#include "apps.h" +#if defined(IBRT) +/* +* custom cmd handler add here, this is just a example +*/ + +#define app_ibrt_custom_cmd_rsp_timeout_handler_null (0) +#define app_ibrt_custom_cmd_rsp_handler_null (0) +#define app_ibrt_custom_cmd_rx_handler_null (0) + +#ifdef BISTO_ENABLED +static void app_ibrt_bisto_dip_sync(uint8_t *p_buff, uint16_t length); +static void app_ibrt_bisto_dip_sync_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +#endif +#ifdef __DUAL_MIC_RECORDING__ +static void app_ibrt_customif_audio_send(uint8_t* p_buff, uint16_t length); +static void app_ibrt_customif_audio_send_done(uint16_t cmdcode, uint16_t rsp_seq, uint8_t *ptrParam, uint16_t paramLen); +static void app_ibrt_customif_audio_send_handler(uint16_t rsp_seq, uint8_t* p_buff, uint16_t length); +#endif +void app_ibrt_customif_test1_cmd_send(uint8_t *p_buff, uint16_t length); +static void app_ibrt_customif_test1_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_customif_test2_cmd_send(uint8_t *p_buff, uint16_t length); +static void app_ibrt_customif_test2_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_customif_test2_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_customif_test2_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_customif_test3_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_customif_test4_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static const app_tws_cmd_instance_t g_ibrt_custom_cmd_handler_table[]= +{ +#ifdef GFPS_ENABLED + { + APP_TWS_CMD_SHARE_FASTPAIR_INFO, "SHARE_FASTPAIR_INFO", + app_ibrt_share_fastpair_info, + app_ibrt_shared_fastpair_info_received_handler, 0, + app_ibrt_custom_cmd_rsp_timeout_handler_null, app_ibrt_custom_cmd_rsp_handler_null + }, +#endif + +#ifdef BISTO_ENABLED + { + APP_TWS_CMD_BISTO_DIP_SYNC, "BISTO_DIP_SYNC", + app_ibrt_bisto_dip_sync, + app_ibrt_bisto_dip_sync_handler, 0, + app_ibrt_cmd_rsp_timeout_handler_null, app_ibrt_cmd_rsp_handler_null + }, +#endif +#ifdef __DUAL_MIC_RECORDING__ + { + APP_IBRT_CUSTOM_CMD_DMA_AUDIO, "TWS_CMD_DMA_AUDIO", + app_ibrt_customif_audio_send, + app_ibrt_customif_audio_send_handler, 0, + app_ibrt_custom_cmd_rsp_timeout_handler_null, app_ibrt_custom_cmd_rsp_handler_null, + app_ibrt_customif_audio_send_done, + }, +#endif + { + APP_IBRT_CUSTOM_CMD_TEST1, "TWS_CMD_TEST1", + app_ibrt_customif_test1_cmd_send, + app_ibrt_customif_test1_cmd_send_handler, 0, + app_ibrt_custom_cmd_rsp_timeout_handler_null, app_ibrt_custom_cmd_rsp_handler_null + }, + { + APP_IBRT_CUSTOM_CMD_TEST2, "TWS_CMD_TEST2", + app_ibrt_customif_test2_cmd_send, + app_ibrt_customif_test2_cmd_send_handler, RSP_TIMEOUT_DEFAULT, + app_ibrt_customif_test2_cmd_send_rsp_timeout_handler, app_ibrt_customif_test2_cmd_send_rsp_handler + }, + { + APP_IBRT_CUSTOM_CMD_TEST3, "TWS_CMD_TEST3", + app_ibrt_customif_test3_cmd_send, + app_ibrt_customif_test3_cmd_send_handler, 0, + app_ibrt_custom_cmd_rsp_timeout_handler_null, app_ibrt_custom_cmd_rsp_handler_null + }, + { + APP_IBRT_CUSTOM_CMD_TEST4, "TWS_CMD_TEST4", + app_ibrt_customif_test4_cmd_send, + app_ibrt_customif_test4_cmd_send_handler, 0, + app_ibrt_custom_cmd_rsp_timeout_handler_null, app_ibrt_custom_cmd_rsp_handler_null + }, +}; + +int app_ibrt_customif_cmd_table_get(void **cmd_tbl, uint16_t *cmd_size) +{ + *cmd_tbl = (void *)&g_ibrt_custom_cmd_handler_table; + *cmd_size = ARRAY_SIZE(g_ibrt_custom_cmd_handler_table); + return 0; +} + + +#ifdef BISTO_ENABLED +static void app_ibrt_bisto_dip_sync(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_without_rsp(APP_TWS_CMD_BISTO_DIP_SYNC, p_buff, length); +} + +static void app_ibrt_bisto_dip_sync_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + gsound_mobile_type_get_callback(*(MOBILE_CONN_TYPE_E *)p_buff); +} +#endif +#ifdef __DUAL_MIC_RECORDING__ +static void app_ibrt_customif_audio_send(uint8_t* p_buff, uint16_t length) { + TRACE(1, "%s", __func__); + app_recording_send_data_to_master(); +} + +static void app_ibrt_customif_audio_send_handler(uint16_t rsp_seq, uint8_t* p_buff, uint16_t length) { + ai_function_handle(CALLBACK_STORE_SLAVE_DATA, (void*)p_buff, length); + //TRACE(1, "%s", __func__); +} + +static void app_ibrt_customif_audio_send_done(uint16_t cmdcode, uint16_t rsp_seq, uint8_t* ptrParam, + uint16_t paramLen) { + TRACE(1, "%s", __func__); + app_recording_audio_send_done(); +} +#endif +void app_ibrt_customif_cmd_test(ibrt_custom_cmd_test_t *cmd_test) +{ + tws_ctrl_send_cmd(APP_IBRT_CUSTOM_CMD_TEST1, (uint8_t*)cmd_test, sizeof(ibrt_custom_cmd_test_t)); + tws_ctrl_send_cmd(APP_IBRT_CUSTOM_CMD_TEST2, (uint8_t*)cmd_test, sizeof(ibrt_custom_cmd_test_t)); + tws_ctrl_send_cmd(APP_IBRT_CUSTOM_CMD_TEST3, (uint8_t*)cmd_test, sizeof(ibrt_custom_cmd_test_t)); +} + +void app_ibrt_customif_test1_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_without_rsp(APP_IBRT_CUSTOM_CMD_TEST1, p_buff, length); + TRACE(1,"%s", __func__); +} + +static void app_ibrt_customif_test1_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"%s", __func__); + app_ibrt_search_ui_handle_key((APP_KEY_STATUS *)p_buff, NULL); +} + +static void app_ibrt_customif_test2_cmd_send(uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"%s", __func__); +} + +static void app_ibrt_customif_test2_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + tws_ctrl_send_rsp(APP_IBRT_CUSTOM_CMD_TEST2, rsp_seq, NULL, 0); + TRACE(1,"%s", __func__); + +} + +static void app_ibrt_customif_test2_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"%s", __func__); + +} + +static void app_ibrt_customif_test2_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"%s", __func__); +} + +void app_ibrt_customif_test3_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_without_rsp(APP_IBRT_CUSTOM_CMD_TEST3, p_buff, length); + TRACE(1,"%s", __func__); +} + +extern void app_ibrt_ui_test_mtu_change_sync_notify(void); +static void app_ibrt_customif_test3_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + /*TRACE(3,"%s,latency_mode_is_open = %d", __func__,latency_mode_is_open); + if(*p_buff == latency_mode_is_open)return; + if(*p_buff == 0) + latency_mode_is_open = 1; + else if(*p_buff == 1) + latency_mode_is_open = 0; + app_ibrt_ui_test_mtu_change_sync_notify();*/ +} + +void app_ibrt_customif_test4_cmd_send(uint8_t *p_buff, uint16_t length) +{ + TRACE(3,"%s", __func__); + app_ibrt_send_cmd_without_rsp(APP_IBRT_CUSTOM_CMD_TEST4, p_buff, length); +} +extern void app_ibrt_sync_volume_info(); +static void app_ibrt_customif_test4_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(3,"!!!!app_ibrt_customif_test4_cmd_send_handler"); + app_ibrt_sync_volume_info(); +} + +#ifdef CUSTOM_BITRATE +//#include "product_config.h" +#include "nvrecord_extension.h" +extern void a2dp_avdtpcodec_aac_user_configure(uint32_t bitrate,uint8_t user_configure); +extern void a2dp_avdtpcodec_sbc_user_configure(uint32_t bitpool,uint8_t user_configure); +extern void app_audio_dynamic_update_dest_packet_mtu(uint8_t codec_index, uint8_t packet_mtu, uint8_t user_configure); + +void app_ibrt_user_a2dp_info_sync_tws_share_cmd_send(uint8_t *p_buff, uint16_t length) +{ + tws_ctrl_send_cmd(APP_TWS_CMD_A2DP_CONFIG_SYNC, p_buff, length); +} + +static void app_ibrt_user_a2dp_info_sync(uint8_t *p_buff, uint16_t length) +{ + if((app_tws_ibrt_mobile_link_connected())){ + app_ibrt_send_cmd_without_rsp(APP_TWS_CMD_A2DP_CONFIG_SYNC, p_buff, length); + } +} + +static void app_ibrt_user_a2dp_info_sync_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + ibrt_custome_codec_t *a2dp_user_config_ptr=(ibrt_custome_codec_t *)p_buff; + TRACE(4,"%s %d %d %d",__func__,a2dp_user_config_ptr->aac_bitrate,a2dp_user_config_ptr->sbc_bitpool,a2dp_user_config_ptr->audio_latentcy); + if((app_tws_ibrt_slave_ibrt_link_connected())){ + a2dp_avdtpcodec_sbc_user_configure(a2dp_user_config_ptr->sbc_bitpool, true); + a2dp_avdtpcodec_aac_user_configure(a2dp_user_config_ptr->aac_bitrate, true); + app_audio_dynamic_update_dest_packet_mtu(0, (a2dp_user_config_ptr->audio_latentcy-USER_CONFIG_AUDIO_LATENCY_ERROR)/3, true);//sbc + app_audio_dynamic_update_dest_packet_mtu(1, (a2dp_user_config_ptr->audio_latentcy-USER_CONFIG_AUDIO_LATENCY_ERROR)/23, true);//aac + uint32_t lock = nv_record_pre_write_operation(); + nv_record_get_extension_entry_ptr()->a2dp_user_info.aac_bitrate = a2dp_user_config_ptr->aac_bitrate; + nv_record_get_extension_entry_ptr()->a2dp_user_info.sbc_bitpool = a2dp_user_config_ptr->sbc_bitpool; + nv_record_get_extension_entry_ptr()->a2dp_user_info.audio_latentcy = a2dp_user_config_ptr->audio_latentcy; + nv_record_post_write_operation(lock); + nv_record_flash_flush(); + } +} +#endif +#endif diff --git a/services/app_ibrt/src/app_ibrt_customif_ui.cpp b/services/app_ibrt/src/app_ibrt_customif_ui.cpp new file mode 100644 index 0000000..8a5ccf6 --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_customif_ui.cpp @@ -0,0 +1,889 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include +#include "apps.h" +#include "app_tws_ibrt_trace.h" +#include "app_ibrt_if.h" +#include "app_ibrt_customif_ui.h" +#include "me_api.h" +#include "app_ibrt_ui.h" +#include "app_vendor_cmd_evt.h" +#include "besaud_api.h" +#include "app_battery.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_ctrl_thread.h" +#include "app_hfp.h" +#include "app_tws_if.h" +#include "app_bt_media_manager.h" +#include "app_spp.h" +#include "anc_wnr.h" +#include "nvrecord.h" +#include "nvrecord_extension.h" +#include "app_bt.h" +#include "app_ibrt_customif_cmd.h" + +#ifdef MEDIA_PLAYER_SUPPORT +#include "app_media_player.h" +#endif +#ifdef BLE_ENABLE +#include "app_ble_mode_switch.h" +#endif + +#if defined(IBRT) +#ifdef ANC_APP +extern "C" void app_anc_sync_status(void); +#endif +void app_ibrt_customif_ui_vender_event_handler_ind(uint8_t evt_type, uint8_t *buffer, uint8_t length) +{ + uint8_t subcode = evt_type; + POSSIBLY_UNUSED ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + switch (subcode) + { + case HCI_DBG_SNIFFER_INIT_CMP_EVT_SUBCODE: + break; + + case HCI_DBG_IBRT_CONNECTED_EVT_SUBCODE: + app_tws_if_ibrt_connected_handler(); + break; + + case HCI_DBG_IBRT_DISCONNECTED_EVT_SUBCODE: + app_tws_if_ibrt_disconnected_handler(); + break; + + case HCI_DBG_IBRT_SWITCH_COMPLETE_EVT_SUBCODE: + + /* + * New Master do some special action,such as update battery to phone, + * since TWS switch may lead to old TWS master update battery fail + */ +#if defined(SUPPORT_BATTERY_REPORT) || defined(SUPPORT_HF_INDICATORS) + if(p_ibrt_ctrl->current_role == IBRT_MASTER) + { + uint8_t battery_level; + TRACE(0,"New TWS master update battery report after tws switch"); + app_battery_get_info(NULL, &battery_level, NULL); + app_hfp_battery_report(battery_level); + } +#endif + + app_tws_if_tws_role_switch_complete_handler(p_ibrt_ctrl->current_role); + break; + + case HCI_NOTIFY_CURRENT_ADDR_EVT_CODE: + break; + + case HCI_DBG_TRACE_WARNING_EVT_CODE: + break; + + case HCI_SCO_SNIFFER_STATUS_EVT_CODE: + break; + + case HCI_DBG_RX_SEQ_ERROR_EVT_SUBCODE: + break; + + case HCI_LL_MONITOR_EVT_CODE: + break; + + case HCI_GET_TWS_SLAVE_MOBILE_RSSI_CODE: + break; + + default: + break; + } +} +extern void startonce_delay_event_Timer_(int ms); +extern void startreconnectfail_delay_report(int ms); + +extern uint8_t once_event_case; +extern bool IsMobileLinkLossing; +extern bool IsTwsLinkdiscon; + +extern bool IsTwsLinkLossing; +extern void app_ibrt_customif_test4_cmd_send(uint8_t *p_buff, uint16_t length); +void app_ibrt_customif_ui_global_handler_ind(ibrt_link_type_e link_type, uint8_t evt_type, uint8_t status) +{ + static ibrt_ctrl_t *p_ibrt_ctrl = app_ibrt_if_get_bt_ctrl_ctx(); + static app_ibrt_ui_t *p_ui_ctrl = app_ibrt_ui_get_ctx(); + TRACE(0,"%s,evt_type = %d,link_type = %d,status = %d",__func__,evt_type,link_type,status); + switch (evt_type) + { + case BTIF_BTEVENT_LINK_CONNECT_CNF:// An outgoing ACL connection is up + //fall through + if((!IsMobileLinkLossing) && (MOBILE_LINK == link_type) && (p_ui_ctrl->box_state != IBRT_IN_BOX_CLOSED) && ((status == BTIF_BEC_NO_ERROR)||(status == BTIF_BEC_PAGE_TIMEOUT))) + { + TRACE(3,"xqd log 1 -- reconnected mobile fail\n"); + //app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + startreconnectfail_delay_report(1200); + } + if((!IsTwsLinkLossing) && (TWS_LINK == link_type) && (p_ui_ctrl->box_state != IBRT_IN_BOX_CLOSED) && ((status == BTIF_BEC_NO_ERROR)||(status == BTIF_BEC_PAGE_TIMEOUT))) + { + TRACE(3,"xqd log 1 -- reconnected TWS fail\n"); + } + break; + case BTIF_BTEVENT_LINK_CONNECT_IND://An incoming ACL connection is up + if (MOBILE_LINK == link_type) + { + if (BTIF_BEC_NO_ERROR == status) + { + app_status_indication_set(APP_STATUS_INDICATION_CONNECTED); + app_tws_if_mobile_connected_handler(p_ibrt_ctrl->mobile_addr.address); + } + } + break; + case BTIF_BTEVENT_LINK_DISCONNECT: + if((MOBILE_LINK == link_type) && (p_ui_ctrl->box_state != IBRT_IN_BOX_CLOSED) && ((status == BTIF_BEC_CONNECTION_TIMEOUT)|| (status == BTIF_BEC_LOW_RESOURCES))) + { + TRACE(3,"xqd log 1 -- mobile linkloss\n"); + IsMobileLinkLossing = TRUE; + nv_record_flash_flush(); + } + if (!app_tws_ibrt_mobile_link_connected()) + { + app_ibrt_if_sniff_checker_reset(); + } + if (MOBILE_LINK == link_type) + { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP, BT_STREAM_VOICE, BT_DEVICE_ID_1, MAX_RECORD_NUM); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP, BT_STREAM_SBC, BT_DEVICE_ID_1, MAX_RECORD_NUM); + app_tws_if_mobile_disconnected_handler(p_ibrt_ctrl->mobile_addr.address); + } + if (TWS_LINK == link_type) + { +#ifdef MEDIA_PLAYER_SUPPORT + app_tws_sync_prompt_manager_reset(); +#endif + } + + break; + case BTIF_STACK_LINK_DISCONNECT_COMPLETE: + // app_status_indication_set(APP_STATUS_INDICATION_DISCONNECTED); + if((MOBILE_LINK == link_type) && (p_ui_ctrl->box_state != IBRT_IN_BOX_CLOSED) && ((status == BTIF_BEC_USER_TERMINATED)||(status == BTIF_BEC_LOCAL_TERMINATED))){ + if((app_tws_ibrt_tws_link_connected()) && (p_ibrt_ctrl->current_role == IBRT_SLAVE)) + { + TRACE(0,"4TWS connected and This is Slave!!!"); + }/*else{ + once_event_case = 2; + startonce_delay_event_Timer_(1500); + }*/ + } + + if((MOBILE_LINK == link_type) && (p_ui_ctrl->box_state != IBRT_IN_BOX_CLOSED) && ((status == BTIF_BEC_CONNECTION_TIMEOUT)|| (status == BTIF_BEC_LOW_RESOURCES))) + { + TRACE(3,"xqd log 2 -- mobile linkloss\n"); + IsMobileLinkLossing = TRUE; + nv_record_flash_flush(); + if(p_ibrt_ctrl->current_role != IBRT_SLAVE){ + once_event_case = 4; + startonce_delay_event_Timer_(5000); + } + } + else if((TWS_LINK == link_type) && (p_ui_ctrl->box_state != IBRT_IN_BOX_CLOSED) && ((status == BTIF_BEC_CONNECTION_TIMEOUT)|| (status == BTIF_BEC_LOW_RESOURCES))) + { + TRACE(3,"xqd log 3 -- tws linkloss\n"); + IsTwsLinkLossing = true; + once_event_case = 4; + nv_record_flash_flush(); + startonce_delay_event_Timer_(10000); + TRACE(3,"MyLog: The TWS connection is lost, reset the indication!!!"); + if (!app_device_bt_is_connected() && !IsMobileLinkLossing) { + TRACE(3,"MyLog: The TWS connection is lost, reset the indication!!!"); + //app_status_indication_set(APP_STATUS_INDICATION_BOTHSCAN); + } + } + break; + + case BTIF_BTEVENT_ROLE_CHANGE: + break; + + case BTIF_BTEVENT_BES_AUD_CONNECTED: + { + //tws link callback when besaud connection complete + if(TWS_LINK == link_type){ + /*if((p_ibrt_ctrl->current_role == IBRT_MASTER)) + { + app_ibrt_customif_test4_cmd_send(&status,1); + }*/ + if(latency_mode_is_open) + app_ibrt_customif_test3_cmd_send(&latency_mode_is_open,1); + if(!IsTwsLinkdiscon){ + //startdelay_report_tone(1000,APP_STATUS_INDICATION_DUDU); + //app_status_indication_set(APP_STATUS_INDICATION_TWS_CONNECTED); + } + IsTwsLinkdiscon = false; + //app_voice_report(APP_STATUS_INDICATION_CONNECTED, 0); + } + if (BTIF_BEC_NO_ERROR == status) + { + TRACE(3,"tjmLOG----------------------TJM!!!!!current_role = 0x%x",p_ibrt_ctrl->current_role); +#ifdef ANC_APP + app_anc_sync_status(); +#endif +#ifdef ANC_WNR_ENABLED + app_wnr_sync_state(); +#endif + if (p_ibrt_ctrl->current_role == IBRT_MASTER && + app_ibrt_ui_get_enter_pairing_mode()) + { +#if defined(MEDIA_PLAYER_SUPPORT) + app_voice_report(APP_STATUS_INDICATION_CONNECTED, 0); +#endif + app_status_indication_set(APP_STATUS_INDICATION_BOTHSCAN); + } + else + { + app_status_indication_set(APP_STATUS_INDICATION_CONNECTED); + } + + app_tws_if_tws_connected_handler(); + } + + } + break; + + case BTIF_BTEVENT_BES_AUD_DISCONNECTED: + app_tws_if_tws_disconnected_handler(); + if(!app_poweroff_flag && !IsTwsLinkLossing && !IsMobileLinkLossing) + { + TRACE(3,"xqd--log: TWS is disconnected and it isn't tws link lossed."); + }else{ + IsTwsLinkdiscon = true; + } + break; + + case BTIF_BTEVENT_ENCRYPTION_CHANGE: + break; + + case BTIF_BTEVENT_MODE_CHANGE: + break; + + default: + break; + } +} +void app_ibrt_customif_open_box_complete_ind(void) +{ + +} +void app_ibrt_customif_close_box_complete_ind(void) +{ + +} +void app_ibrt_customif_fetch_out_complete_ind(void) +{ + +} +void app_ibrt_customif_put_in_complete_ind(void) +{ + +} +void app_ibrt_customif_wear_up_complete_ind(void) +{ + +} +void app_ibrt_customif_wear_down_complete_ind(void) +{ + +} +void app_ibrt_customif_ui_global_event_update(ibrt_event_type evt_type, ibrt_ui_state_e old_state, \ + ibrt_ui_state_e new_state,ibrt_action_e action,\ + ibrt_ui_error_e status) +{ + switch (new_state) + { + case IBRT_UI_IDLE: + if (IBRT_UI_IDLE != old_state) + { + //callback when UI event completed + switch (evt_type) + { + case IBRT_OPEN_BOX_EVENT: + app_ibrt_customif_open_box_complete_ind(); + break; + case IBRT_FETCH_OUT_EVENT: + app_ibrt_customif_fetch_out_complete_ind(); + break; + case IBRT_PUT_IN_EVENT: + app_ibrt_customif_put_in_complete_ind(); + break; + case IBRT_CLOSE_BOX_EVENT: + app_ibrt_customif_close_box_complete_ind(); + break; + case IBRT_WEAR_UP_EVENT: + app_ibrt_customif_wear_up_complete_ind(); + break; + case IBRT_WEAR_DOWN_EVENT: + app_ibrt_customif_wear_down_complete_ind(); + break; + default: + break; + } + } + break; + + case IBRT_UI_IDLE_WAIT: + break; + + case IBRT_UI_W4_TWS_CONNECTION: + break; + + case IBRT_UI_W4_TWS_INFO_EXCHANGE_COMPLETE: + break; + + case IBRT_UI_W4_TWS_BT_MSS_COMPLETE: + break; + + case IBRT_UI_W4_SET_ENV_COMPLETE: + break; + + case IBRT_UI_W4_MOBILE_CONNECTION: + break; + + case IBRT_UI_W4_MOBILE_MSS_COMPLETE: + break; + + case IBRT_UI_W4_MOBILE_ENTER_ACTIVE_MODE: + break; + + case IBRT_UI_W4_START_IBRT_COMPLETE: + break; + + case IBRT_UI_W4_IBRT_DATA_EXCHANGE_COMPLETE: + break; + + case IBRT_UI_W4_TWS_SWITCH_COMPLETE: + break; + + case IBRT_UI_W4_SM_STOP: + break; + + default: + break; + } +} +/* +* custom tws switch interface +* tws switch cmd send sucess, return true, else return false +*/ +bool app_ibrt_customif_ui_tws_switch(void) +{ + return app_ibrt_ui_tws_switch(); +} + +/* +* custom tws switching check interface +* whether doing tws switch now, return true, else return false +*/ +bool app_ibrt_customif_ui_is_tws_switching(void) +{ + return app_ibrt_ui_is_tws_switching(); +} + +/* +* custom reconfig bd_addr +*/ +void app_ibrt_customif_ui_reconfig_bd_addr(bt_bdaddr_t local_addr, bt_bdaddr_t peer_addr, ibrt_role_e nv_role) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + + p_ibrt_ctrl->local_addr = local_addr; + p_ibrt_ctrl->peer_addr = peer_addr; + p_ibrt_ctrl->nv_role = nv_role; + + if (!p_ibrt_ctrl->is_ibrt_search_ui) + { + if (IBRT_MASTER == p_ibrt_ctrl->nv_role) + { + p_ibrt_ctrl->peer_addr = local_addr; + btif_me_set_bt_address(p_ibrt_ctrl->local_addr.address); + } + else if (IBRT_SLAVE == p_ibrt_ctrl->nv_role) + { + p_ibrt_ctrl->local_addr = peer_addr; + btif_me_set_bt_address(p_ibrt_ctrl->local_addr.address); + } + else + { + ASSERT(0, "%s nv_role error", __func__); + } + } + p_ibrt_ui->bonding_success = true; +} +/*custom can block connect mobile if needed*/ +bool app_ibrt_customif_connect_mobile_needed_ind(void) +{ + return true; +} + +void app_ibrt_customif_mobile_connected_ind(bt_bdaddr_t * addr) +{ +#ifdef BLE_ENABLE + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); +#endif + + app_ibrt_if_config_keeper_mobile_update(addr); +} + +void app_ibrt_customif_ibrt_connected_ind(bt_bdaddr_t * addr) +{ + app_ibrt_if_config_keeper_mobile_update(addr); +} + +void app_ibrt_customif_tws_connected_ind(bt_bdaddr_t * addr) +{ + app_ibrt_if_config_keeper_tws_update(addr); +} + +void app_ibrt_customif_profile_state_change_ind(uint32_t profile,uint8_t connected) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TRACE(2,"custom if profle=%x state change to =%x",profile,connected); + + switch (profile) + { + case BTIF_APP_A2DP_PROFILE_ID: + if (connected) + { + //TRACE(0,"cutomif A2DP profile connected"); + //ibrt slave + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + //TO DO + } + //ibrt master + else if (p_ibrt_ctrl->current_role == IBRT_MASTER) + { + //TO DO + } + //no tws connected + else + { + //TO DO + } + } + else + { + //TRACE(0,"cutomif A2DP profile disconnected"); + //ibrt slave + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + //TO DO + } + //ibrt master + else if (p_ibrt_ctrl->current_role == IBRT_MASTER) + { + //TO DO + } + //no tws connected + else + { + //TO DO + } + } + break; + + case BTIF_APP_AVRCP_PROFILE_ID: + if (connected) + { + //TRACE(0,"cutomif AVRCP profile connected"); + //ibrt slave + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + //TO DO + } + //ibrt master + else if (p_ibrt_ctrl->current_role == IBRT_MASTER) + { + //TO DO + } + //no tws connected + else + { + //TO DO + } + } + else + { + //TRACE(0,"cutomif AVRCP profile disconnected"); + //ibrt slave + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + //TO DO + } + //ibrt master + else if (p_ibrt_ctrl->current_role == IBRT_MASTER) + { + //TO DO + } + //no tws connected + else + { + //TO DO + } + } + break; + + case BTIF_APP_HFP_PROFILE_ID: + if (connected) + { + //TRACE(0,"cutomif HFP profile connected"); + //ibrt slave + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + //TO DO + } + //ibrt master + else if (p_ibrt_ctrl->current_role == IBRT_MASTER) + { + //TO DO + } + //no tws connected + else + { + //TO DO + } + } + else + { + //TRACE(0,"cutomif HFP profile disconnected"); + //ibrt slave + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + //TO DO + } + //ibrt master + else if (p_ibrt_ctrl->current_role == IBRT_MASTER) + { + //TO DO + } + //no tws connected + else + { + //TO DO + } + + } + break; + + case BTIF_APP_SPP_CLIENT_AI_VOICE_ID: + case BTIF_APP_SPP_SERVER_AI_VOICE_ID: + case BTIF_APP_SPP_SERVER_GREEN_ID: + case BTIF_APP_SPP_CLIENT_CCMP_ID: + case BTIF_APP_SPP_CLIENT_RED_ID: + case BTIF_APP_SPP_SERVER_RED_ID: + case BTIF_APP_SPP_SERVER_TOTA_ID: + case BTIF_APP_SPP_SERVER_GSOUND_CTL_ID: + case BTIF_APP_SPP_SERVER_GSOUND_AUD_ID: + case BTIF_APP_SPP_SERVER_BES_OTA_ID: + case BTIF_APP_SPP_SERVER_FP_RFCOMM_ID: + case BTIF_APP_SPP_SERVER_TOTA_GENERAL_ID: + if (connected) + { + //TRACE(0,"cutomif SPP profile connected"); + //ibrt slave + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + //TO DO + } + //ibrt master + else if (p_ibrt_ctrl->current_role == IBRT_MASTER) + { + //TO DO + } + //no tws connected + else + { + //TO DO + } + + } + else + { + //TRACE(0,"cutomif SPP profile disconnected"); + //ibrt slave + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + //TO DO + } + //ibrt master + else if (p_ibrt_ctrl->current_role == IBRT_MASTER) + { + //TO DO + } + //no tws connected + else + { + //TO DO + } + + } + break; + + default: + TRACE(1,"unknown profle=%x state change",profile); + break; + } + +} + +/******************************reconnectfail_delay_report_timer*********************************************************/ +osTimerId reconnectfail_delay_reportid = NULL; +void startreconnectfail_delay_report(int ms); +void stopreconnectfail_delay_report(void); +static void reconnectfail_delay_reportfun(const void *); +osTimerDef(defreconnectfail_delay_report,reconnectfail_delay_reportfun); +void reconnectfail_delay_reportinit(void) +{ + reconnectfail_delay_reportid = osTimerCreate(osTimer(defreconnectfail_delay_report),osTimerOnce,(void *)0); +} + +static void reconnectfail_delay_reportfun(const void *) +{ + static ibrt_ctrl_t *p_ibrt_ctrl = app_ibrt_if_get_bt_ctrl_ctx(); + TRACE(3,"\n\n!!!!!!enter %s\n\n",__func__); + if((p_ibrt_ctrl->access_mode == 0x3)&&(p_ibrt_ctrl->current_role != IBRT_SLAVE)){ + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN,0); + app_status_indication_set(APP_STATUS_INDICATION_BOTHSCAN); + } +} + +void startreconnectfail_delay_report(int ms) +{ + TRACE(3,"\n\n !!!!!!!!!!start %s\n\n",__func__); + osTimerStart(reconnectfail_delay_reportid,ms); +} + +void stopreconnectfail_delay_report(void) +{ + + TRACE(3,"\n\n!!!!!!!!!! stop %s\n\n",__func__); + osTimerStop(reconnectfail_delay_reportid); +} + + + +/********************************reconnectfail_delay_report_timer*******************************************************/ +void app_ibrt_customif_ui_pairing_set(trigger_pairing_mode_type_e trigger_type) +{ + TRACE(2,"%s: %d", __func__, __LINE__); +} + +void app_ibrt_customif_ui_pairing_clear(trigger_pairing_mode_type_e trigger_type) +{ + TRACE(2,"%s: %d", __func__, __LINE__); +} + +/* +* custom config main function +*/ + +int app_ibrt_customif_ui_start(void) +{ + ibrt_ui_config_t config; + + // zero init the config + memset(&config, 0, sizeof(ibrt_ui_config_t)); + + //freeman mode config, default should be false + config.freeman_enable = false; + + //dont do role switch with mobile when enter freeman mode + config.freeman_dont_role_switch = false; + + //tws earphone set the same addr, UI will be flexible, default should be true + config.tws_use_same_addr = true; + + //ibrt slave will reconnect to mobile if tws connect failed, default should be true + config.slave_reconnect_enable = true; + + //do tws switch when wearup or weardown, must be true because MIC will be with IBRT master + config.wear_updown_tws_switch_enable = true; + + //pairing mode default value, default should be set false + config.enter_pairing_mode = false; + + //following cases the reconnect will be fail for freeman, please set to true if you want to reconnect successful: + //1. freeman has link key but mobile deleted the link key + //2. freeman changed its bt address after reboot and use the new address to reconnect mobile + config.freeman_accept_mobile_new_pairing = false; + + //for some proj no box key, default should be false; + config.enter_pairing_on_empty_mobile_addr = true; + + //for some proj no box key, default should be false + config.enter_pairing_on_reconnect_mobile_failed = true; + + //when mobile has connected, enter_pairing_on_reconnect_mobile_failed will be cleared, default false + config.enter_pairing_on_reconnect_mobile_failed_once = false; + + //for some proj no box key, default should be false + config.enter_pairing_on_mobile_disconnect = true; + + //for 08 error reconnect event, default must be true + config.disc_tws_before_reconnect_mobile = true; + config.wait_time_before_disc_tws = 3000; + + //do tws switch when RSII value change, default should be true + config.tws_switch_according_to_rssi_value = false; + + //disable tws switch, NOT recommended to open + config.disable_tws_switch = false; + + //disable tws switch, NOT recommended to open + config.disable_stop_ibrt = true; + + //exchange snoop info by BLE_box, special custom config, default should be false + config.snoop_via_ble_enable = false; + //controller basband monitor + config.lowlayer_monitor_enable = false; + + config.delay_exit_sniff = true; + config.delay_ms_exit_sniff = 3000; + + config.check_plugin_excute_closedbox_event = true; + + config.share_tws_info_done = false; + + config.nv_slave_enter_pairing_on_mobile_disconnect = true; + config.nv_slave_enter_pairing_on_empty_mobile_addr = true; + + //only allow paired mobile device incoming when not in paring mode,default should be false + config.mobile_incoming_filter_unpaired = false; + //close box debounce time config + config.close_box_event_wait_response_timeout = IBRT_UI_CLOSE_BOX_EVENT_WAIT_RESPONSE_TIMEOUT; + + //do tws switch when RSII value change, timer threshold + config.role_switch_timer_threshold = IBRT_UI_ROLE_SWITCH_TIME_THRESHOLD; + + //do tws switch when rssi value change over threshold + config.rssi_threshold = IBRT_UI_ROLE_SWITCH_THRESHOLD_WITH_RSSI; + + //wait time before launch reconnect event + config.reconnect_mobile_wait_response_timeout = IBRT_UI_RECONNECT_MOBILE_WAIT_RESPONSE_TIMEOUT; + + //reconnect event internal config wait timer when tws disconnect + config.reconnect_wait_ready_timeout = IBRT_UI_MOBILE_RECONNECT_WAIT_READY_TIMEOUT; + config.reconnect_mobile_wait_ready_timeout = IBRT_UI_MOBILE_RECONNECT_WAIT_READY_TIMEOUT; + config.reconnect_tws_wait_ready_timeout = IBRT_UI_TWS_RECONNECT_WAIT_READY_TIMEOUT; + config.reconnect_ibrt_wait_response_timeout = IBRT_UI_RECONNECT_IBRT_WAIT_RESPONSE_TIMEOUT; + config.nv_master_reconnect_tws_wait_response_timeout = IBRT_UI_NV_MASTER_RECONNECT_TWS_WAIT_RESPONSE_TIMEOUT; + config.nv_slave_reconnect_tws_wait_response_timeout = IBRT_UI_NV_SLAVE_RECONNECT_TWS_WAIT_RESPONSE_TIMEOUT; + + //pairing mode timeout config + config.disable_bt_scan_timeout = IBRT_UI_DISABLE_BT_SCAN_TIMEOUT; + + //open box reconnect mobile times config + config.open_reconnect_mobile_max_times = IBRT_UI_OPEN_RECONNECT_MOBILE_MAX_TIMES; + + //open box reconnect tws times config + config.open_reconnect_tws_max_times = IBRT_UI_OPEN_RECONNECT_TWS_MAX_TIMES; + + //connection timeout reconnect mobile times config + config.reconnect_mobile_max_times = IBRT_UI_RECONNECT_MOBILE_MAX_TIMES; + + //connection timeout reconnect tws times config + config.reconnect_tws_max_times = IBRT_UI_RECONNECT_TWS_MAX_TIMES; + + //connection timeout reconnect ibrt times config + config.reconnect_ibrt_max_times = IBRT_UI_RECONNECT_IBRT_MAX_TIMES; + + //reconnect tws one cycle + config.tws_reconnect_cycle = IBRT_TWS_RECONNECT_ONE_CYCLE; + + //reconnect mobile one cycle + config.mobile_reconnect_cycle = IBRT_MOBILE_RECONNECT_ONE_CYCLE; + + //BES internal config, DO NOT modify + config.long_private_poll_interval = IBRT_UI_LONG_POLL_INTERVAL; + config.default_private_poll_interval = IBRT_UI_DEFAULT_POLL_INTERVAL; + config.short_private_poll_interval = IBRT_UI_SHORT_POLL_INTERVAL; + config.default_private_poll_interval_in_sco = IBRT_UI_DEFAULT_POLL_INTERVAL_IN_SCO; + config.short_private_poll_interval_in_sco = IBRT_UI_SHORT_POLL_INTERVAL_IN_SCO; + config.default_bt_tpoll = IBRT_TWS_BT_TPOLL_DEFAULT; + + //for fast connect when only one headset in the nearby + config.tws_page_timeout_on_last_success = IBRT_TWS_PAGE_TIMEOUT_ON_CONNECT_SUCCESS_LAST; + config.tws_page_timeout_on_last_failed = IBRT_TWS_PAGE_TIMEOUT_ON_CONNECT_FAILED_LAST; + config.mobile_page_timeout = IBRT_MOBILE_PAGE_TIMEOUT; + config.tws_page_timeout_on_reconnect_mobile_failed = IBRT_TWS_PAGE_TIMEOUT_ON_RECONNECT_MOBILE_FAILED; + config.tws_page_timeout_on_reconnect_mobile_success = IBRT_TWS_PAGE_TIMEOUT_ON_RECONNECT_MOBILE_SUCCESS; + + //tws connection timeout + config.tws_connection_timeout = IBRT_UI_TWS_CONNECTION_TIMEOUT; + + config.rx_seq_error_timeout = IBRT_UI_RX_SEQ_ERROR_TIMEOUT; + config.rx_seq_error_threshold = IBRT_UI_RX_SEQ_ERROR_THRESHOLD; + config.rx_seq_recover_wait_timeout = IBRT_UI_RX_SEQ_ERROR_RECOVER_TIMEOUT; + + config.rssi_monitor_timeout = IBRT_UI_RSSI_MONITOR_TIMEOUT; + + + config.wear_updown_detect_supported = false; + config.stop_ibrt_timeout = IBRT_UI_STOP_IBRT_TIMEOUT; + + + config.radical_scan_interval_nv_slave = IBRT_UI_RADICAL_SAN_INTERVAL_NV_SLAVE; + config.radical_scan_interval_nv_master = IBRT_UI_RADICAL_SAN_INTERVAL_NV_MASTER; + config.event_hung_timeout = IBRT_EVENT_HUNG_TIMEOUT; + config.rssi_tws_switch_threshold = IBRT_TWS_SWITCH_RSSI_THRESHOLD; + config.stop_ibrt_wait_time_after_tws_switch = IBRT_STOP_IBRT_WAIT_TIME; + config.tws_conn_failed_wait_time = TWS_CONN_FAILED_WAIT_TIME; + + config.sm_running_timeout = SM_RUNNING_TIMEOUT; + config.peer_sm_running_timeout = PEER_SM_RUNNING_TIMEOUT; + config.reconnect_peer_sm_running_timeout = RECONNECT_PEER_SM_RUNNING_TIMEOUT; + config.connect_no_03_timeout = CONNECT_NO_03_TIMEOUT; + config.disconnect_no_05_timeout = DISCONNECT_NO_05_TIMEOUT; + + config.tws_switch_tx_data_protect = true; + config.tws_cmd_send_timeout = IBRT_UI_TWS_CMD_SEND_TIMEOUT; + config.tws_cmd_send_counter_threshold = IBRT_UI_TWS_COUNTER_THRESHOLD; + config.tws_switch_stable_timeout = IBRT_UI_TWS_SWITCH_STABLE_TIMEOUT; + + config.invoke_event_when_box_closed = true; + + + //if open_box/close box detect supported, may open this config to speed up connection setup + config.tws_stay_when_close_box = false; + config.free_tws_timeout = IBRT_UI_DISC_TWS_TIMEOUT; + + config.profile_concurrency_supported = false; + + config.audio_sync_mismatch_resume_version = 2; + config.filter_duplicate_event = true; + + app_ibrt_if_register_global_handler_ind(app_ibrt_customif_ui_global_handler_ind); + app_ibrt_if_register_vender_handler_ind(app_ibrt_customif_ui_vender_event_handler_ind); + app_ibrt_if_register_global_event_update_ind(app_ibrt_customif_ui_global_event_update); + app_ibrt_if_register_link_connected_ind(app_ibrt_customif_mobile_connected_ind, + app_ibrt_customif_ibrt_connected_ind, + app_ibrt_customif_tws_connected_ind); + app_ibrt_if_register_profile_state_change_ind(app_ibrt_customif_profile_state_change_ind); + app_ibrt_if_register_connect_mobile_needed_ind(app_ibrt_customif_connect_mobile_needed_ind); + app_ibrt_if_register_pairing_mode_ind(app_ibrt_customif_ui_pairing_set, app_ibrt_customif_ui_pairing_clear); + app_ibrt_if_config(&config); + + if (config.delay_exit_sniff) + { + app_ibrt_if_sniff_checker_init(config.delay_ms_exit_sniff); + } + reconnectfail_delay_reportinit(); + return 0; +} + +#endif diff --git a/services/app_ibrt/src/app_ibrt_if.cpp b/services/app_ibrt/src/app_ibrt_if.cpp new file mode 100644 index 0000000..8dd5932 --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_if.cpp @@ -0,0 +1,1203 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include +#include "hal_trace.h" +#include "hal_location.h" +#include "hal_timer.h" +#include "nvrecord.h" +#include "crc32.h" +#include "app_tws_ibrt_trace.h" +#include "app_ibrt_if.h" +#include "app_ibrt_if_internal.h" +#include "app_ibrt_ui_test.h" +#include "a2dp_decoder.h" +#include "app_ibrt_nvrecord.h" +#include "bt_drv_reg_op.h" +#include "bt_drv_interface.h" +#include "btapp.h" +#include "app_tws_ibrt_cmd_sync_a2dp_status.h" +#include "app_ibrt_a2dp.h" +#include "app_tws_ibrt_cmd_sync_hfp_status.h" +#include "app_ibrt_hf.h" +#include "app_bt_stream.h" +#include "app_tws_ctrl_thread.h" +#include "app_bt_media_manager.h" +#include "app_bt_func.h" +#include "app_ai_if.h" +#include "app_ai_tws.h" +#include "app_tws_if.h" +#include "besaud_api.h" +#ifdef BLE_ENABLE +#include "app_ble_include.h" +#endif + +#ifdef IBRT_OTA +#include "ota_control.h" +#endif + +#if defined(TOTA) || defined(TEST_OVER_THE_AIR_ENANBLED) +#include "app_spp_tota.h" +#endif + +extern struct BT_DEVICE_T app_bt_device; + +extern uint8_t avrcp_get_media_status(void); + + +#if defined(IBRT) + +static uint32_t tws_sniff_block_start = 0; +static uint32_t tws_sniff_block_next_sec = 0; +void app_ibrt_if_register_tws_switch_needed_ind(APP_IBRT_IF_TWS_SWITCH_NEEDED_IND tws_switch_need_ind) +{ + app_ibrt_ui_register_tws_switch_needed_ind(tws_switch_need_ind); +} + +void app_ibrt_if_register_connect_mobile_needed_ind(APP_IBRT_IF_CONNECT_MOBILE_NEEDED_IND connect_moible_need_ind) +{ + app_ibrt_ui_register_connect_mobile_needed_ind(connect_moible_need_ind); +} + +void app_ibrt_if_register_vender_handler_ind(APP_IBRT_IF_VENDER_EVENT_HANDLER_IND handler) +{ + app_ibrt_ui_register_vender_event_update_ind(handler); +} + +void app_ibrt_if_register_global_handler_ind(APP_IBRT_IF_GLOBAL_HANDLER_IND handler) +{ + app_ibrt_ui_register_global_handler_ind(handler); +} + +void app_ibrt_if_register_global_event_update_ind(APP_IBRT_IF_GLOBAL_EVENT_UPDATE_IND handler) +{ + app_ibrt_ui_register_global_event_update_ind(handler); +} + +void app_ibrt_if_register_pairing_mode_ind(APP_IBRT_UI_PAIRING_MODE_HANDLER_IND set_callback, APP_IBRT_UI_PAIRING_MODE_HANDLER_IND clear_callback) +{ + app_ibrt_ui_register_pairing_mode_ind(set_callback, clear_callback); +} + +void app_ibrt_if_register_cmd_complete_ind(APP_IBRT_UI_CMD_COMPLETE_HANDLER_IND cmd_complete_ind) +{ + app_ibrt_ui_register_cmd_complete_ind(cmd_complete_ind); + +} + +void app_ibrt_if_register_link_connected_ind(APP_IBRT_UI_CONNECTED_HANDLER_IND mobile_connected_ind, + APP_IBRT_UI_CONNECTED_HANDLER_IND ibrt_connected_ind, + APP_IBRT_UI_CONNECTED_HANDLER_IND tws_connected_ind) +{ + app_ibrt_ui_register_link_connected_ind(mobile_connected_ind, ibrt_connected_ind, tws_connected_ind); +} + +void app_ibrt_if_register_profile_state_change_ind(APP_IBRT_IF_PROFILE_STATE_CHANGE_IND handler) +{ + app_ibrt_ui_register_profile_state_change_ind(handler); +} + +typedef struct +{ + ibrt_config_t ibrt_config; + nvrec_btdevicerecord rec_mobile; + nvrec_btdevicerecord rec_peer; + uint8_t reserved __attribute__((aligned(4))); + uint32_t crc; +} ibrt_config_ram_bak_t; + +ibrt_config_ram_bak_t REBOOT_CUSTOM_PARAM_LOC ibrt_config_ram_bak; + +int app_ibrt_if_config_keeper_clear(void) +{ + memset(&ibrt_config_ram_bak, 0, sizeof(ibrt_config_ram_bak)); + return 0; +} + +void app_ibrt_if_set_silent_mode(void) +{ + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + + p_ibrt_ui->silent_mode = true; + app_ibrt_ui_event_entry(IBRT_TWS_PAIRING_EVENT); +} + +void app_ibrt_if_clear_silent_mode(void) +{ + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + + p_ibrt_ui->silent_mode = false; + app_ibrt_ui_judge_scan_type(IBRT_RESTORE_SCAN, NO_LINK_TYPE, IBRT_UI_NO_ERROR); +} + +int app_ibrt_if_config_keeper_flush(void) +{ + ibrt_config_ram_bak.crc = crc32(0,(uint8_t *)(&ibrt_config_ram_bak),(sizeof(ibrt_config_ram_bak_t)-sizeof(uint32_t))); + TRACE(2,"%s crc:%08x", __func__, ibrt_config_ram_bak.crc); + return 0; +} + +int app_ibrt_if_volume_ptr_update(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + btif_remote_device_t *remDev = NULL; + + if (app_tws_ibrt_mobile_link_connected()) + { + remDev = btif_me_get_remote_device_by_handle(p_ibrt_ctrl->mobile_conhandle); + } + else if (app_tws_ibrt_slave_ibrt_link_connected()) + { + remDev = btif_me_get_remote_device_by_handle(p_ibrt_ctrl->ibrt_conhandle); + } + + if (remDev) + { + app_bt_stream_volume_ptr_update((uint8_t *) btif_me_get_remote_device_bdaddr(remDev)); + } + + return 0; +} + +void app_ibrt_if_pairing_mode_refresh(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (p_ibrt_ctrl->nv_role == IBRT_MASTER) + { + app_ibrt_ui_event_entry(IBRT_TWS_PAIRING_EVENT); + } + else + { + if (!btif_besaud_is_connected()) + { + app_ibrt_ui_set_enter_pairing_mode(IBRT_TWS_PAIR_MODE_ENTER); + app_ibrt_ui_judge_scan_type(IBRT_ENTER_PAIRING_MODE_TRIGGER, NO_LINK_TYPE, 0); + } + else + { + tws_ctrl_send_cmd(APP_TWS_CMD_PAIRING_MODE_REFRESH, NULL, 0); + } + } +} + +int app_ibrt_if_config_keeper_mobile_update(bt_bdaddr_t *addr) +{ + nvrec_btdevicerecord *nv_record = NULL; + nvrec_btdevicerecord *rambak_record = NULL; + + rambak_record = &ibrt_config_ram_bak.rec_mobile; + + if (!nv_record_btdevicerecord_find(addr,&nv_record)) + { + TRACE(1,"%s success", __func__); + DUMP8("%02x ", nv_record->record.bdAddr.address, sizeof(nv_record->record.bdAddr.address)); + DUMP8("%02x ", nv_record->record.linkKey, sizeof(nv_record->record.linkKey)); + ibrt_config_ram_bak.ibrt_config.mobile_addr = *addr; + *rambak_record = *nv_record; + app_ibrt_if_config_keeper_flush(); + app_ibrt_if_volume_ptr_update(); + } + else + { + TRACE(1,"%s failure", __func__); + } + + return 0; +} + +int app_ibrt_if_config_keeper_tws_update(bt_bdaddr_t *addr) +{ + nvrec_btdevicerecord *nv_record = NULL; + nvrec_btdevicerecord *rambak_record = NULL; + + rambak_record = &ibrt_config_ram_bak.rec_peer; + + if (!nv_record_btdevicerecord_find(addr,&nv_record)) + { + TRACE(1,"%s success", __func__); + DUMP8("%02x ", nv_record->record.bdAddr.address, sizeof(nv_record->record.bdAddr.address)); + DUMP8("%02x ", nv_record->record.linkKey, sizeof(nv_record->record.linkKey)); + ibrt_config_ram_bak.ibrt_config.peer_addr = *addr; + *rambak_record = *nv_record; + app_ibrt_if_config_keeper_flush(); + app_ibrt_if_volume_ptr_update(); + } + else + { + TRACE(1,"%s failure", __func__); + } + + return 0; +} +/* +* tws preparation before tws switch if needed +*/ +#ifdef IBRT_OTA +extern void ota_control_send_start_role_switch(void); +#endif +bool app_ibrt_if_tws_switch_prepare_needed(uint32_t *wait_ms) +{ + __attribute__((unused)) ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + bool ret = false; + +#ifdef BLE_ENABLE + ble_callback_evnet_t event; + event.evt_type = BLE_CALLBACK_RS_START; + app_ble_core_global_callback_event(&event, NULL); +#endif + +#if defined(__AI_VOICE__) || defined(BISTO_ENABLED) + p_ibrt_ctrl->ibrt_ai_role_switch_handle = app_ai_tws_role_switch_prepare(wait_ms); + if (p_ibrt_ctrl->ibrt_ai_role_switch_handle) + { + p_ibrt_ctrl->ibrt_role_switch_handle_user |= (1 << IBRT_ROLE_SWITCH_USER_AI); + } +#endif + +#ifdef IBRT_OTA + if (app_get_bes_ota_state()) + { + p_ibrt_ctrl->ibrt_role_switch_handle_user |= (1 << IBRT_ROLE_SWITCH_USER_OTA); + *wait_ms = 800; + } +#endif + + if (p_ibrt_ctrl->ibrt_role_switch_handle_user) + { + ret = true; + } + + app_tws_if_role_switch_started_handler(); + + TRACE(2,"tws_switch_prepare_needed=%d, wait_ms=%d", ret, *wait_ms); + return ret; +} +/* +* tws preparation before tws switch +*/ +void app_ibrt_if_tws_swtich_prepare(void) +{ +#if defined(BISTO_ENABLED) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (p_ibrt_ctrl->ibrt_ai_role_switch_handle & (1 << AI_SPEC_GSOUND)) + { + app_ai_tws_role_switch(); + } +#endif + +#ifdef IBRT_OTA + ibrt_ctrl_t *ota_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if ((app_get_bes_ota_state()) &&\ + (ota_ibrt_ctrl->ibrt_role_switch_handle_user & IBRT_ROLE_SWITCH_USER_OTA)) + { + app_set_ota_role_switch_initiator(true); + bes_ota_send_role_switch_req(); + } +#endif +} +/* +* notify UI SM tws preparation done +*/ +extern osTimerId ibrt_ui_tws_switch_prepare_timer_id; +static void app_ibrt_if_tws_switch_prepare_done(IBRT_ROLE_SWITCH_USER_E user, uint32_t role) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (p_ibrt_ctrl->ibrt_role_switch_handle_user) + { +#if defined(__AI_VOICE__) || defined(BISTO_ENABLED) + TRACE(4,"%s ai_handle 0x%x role %d%s", __func__, \ + p_ibrt_ctrl->ibrt_ai_role_switch_handle, \ + role, \ + ai_spec_type2str((AI_SPEC_TYPE_E)role)); + + if (user == IBRT_ROLE_SWITCH_USER_AI) + { + if (role >= AI_SPEC_COUNT) + { + TRACE(1,"%s role error", __func__); + return; + } + if (!p_ibrt_ctrl->ibrt_ai_role_switch_handle) + { + TRACE(1,"%s ai_handle is 0", __func__); + return; + } + + p_ibrt_ctrl->ibrt_ai_role_switch_handle &= ~(1 << role); + if (!p_ibrt_ctrl->ibrt_ai_role_switch_handle) + { + p_ibrt_ctrl->ibrt_role_switch_handle_user &= ~IBRT_ROLE_SWITCH_USER_AI; + } + } + else +#endif + { + p_ibrt_ctrl->ibrt_role_switch_handle_user &= ~user; + } + + if (!p_ibrt_ctrl->ibrt_role_switch_handle_user) + { + osTimerStop(ibrt_ui_tws_switch_prepare_timer_id); + app_ibrt_ui_event_handler(IBRT_ACTION_TWS_SWITCH_PREPARE_COMPLETE,IBRT_UI_NO_ERROR); + } + } +} + +void app_ibrt_if_tws_switch_prepare_done_in_bt_thread(IBRT_ROLE_SWITCH_USER_E user, uint32_t role) +{ + app_bt_start_custom_function_in_bt_thread(user, + role, + (uint32_t)app_ibrt_if_tws_switch_prepare_done); +} + +int app_ibrt_if_config_keeper_resume(ibrt_config_t *config) +{ + uint32_t crc; + nvrec_btdevicerecord *nv_record = NULL; + nvrec_btdevicerecord *rambak_record = NULL; + bool mobile_check_ok = false; + bool peer_check_ok = false; + bool flash_need_flush = false; + bt_bdaddr_t zeroAddr = {0,0,0,0,0,0}; + + crc = crc32(0,(uint8_t *)(&ibrt_config_ram_bak),(sizeof(ibrt_config_ram_bak_t)-sizeof(uint32_t))); + + TRACE(3,"%s start crc:%08x/%08x", __func__, ibrt_config_ram_bak.crc, crc); + if (crc == ibrt_config_ram_bak.crc) + { + TRACE_IMM(1,"%s success", __func__); + TRACE(1,"%s config loc", __func__); + DUMP8("%02x ", config->local_addr.address, 6); + TRACE(1,"%s config mobile", __func__); + DUMP8("%02x ", config->mobile_addr.address, 6); + TRACE(1,"%s config peer", __func__); + DUMP8("%02x ", config->peer_addr.address, 6); + + rambak_record = &ibrt_config_ram_bak.rec_mobile; + if (!nv_record_btdevicerecord_find(&config->mobile_addr,&nv_record)) + { + TRACE(1,"%s find mobile", __func__); + DUMP8("%02x ", nv_record->record.bdAddr.address, sizeof(nv_record->record.bdAddr.address)); + DUMP8("%02x ", nv_record->record.linkKey, sizeof(nv_record->record.linkKey)); + if (!memcmp(rambak_record->record.linkKey, nv_record->record.linkKey, sizeof(nv_record->record.linkKey))) + { + TRACE(1,"%s check mobile success", __func__); + mobile_check_ok = true; + } + } + if (!mobile_check_ok) + { + TRACE(1,"%s check mobile failure", __func__); + DUMP8("%02x ", rambak_record->record.bdAddr.address, sizeof(zeroAddr)); + DUMP8("%02x ", rambak_record->record.linkKey, sizeof(rambak_record->record.linkKey)); + if (memcmp(rambak_record->record.bdAddr.address, zeroAddr.address, sizeof(zeroAddr))) + { + nv_record_add(section_usrdata_ddbrecord, rambak_record); + config->mobile_addr = rambak_record->record.bdAddr; + flash_need_flush = true; + TRACE(1,"%s resume mobile", __func__); + } + } + + rambak_record = &ibrt_config_ram_bak.rec_peer; + if (!nv_record_btdevicerecord_find(&config->peer_addr,&nv_record)) + { + TRACE(1,"%s find tws peer", __func__); + DUMP8("%02x ", nv_record->record.bdAddr.address, sizeof(nv_record->record.bdAddr.address)); + DUMP8("%02x ", nv_record->record.linkKey, sizeof(nv_record->record.linkKey)); + if (!memcmp(rambak_record->record.linkKey, nv_record->record.linkKey, sizeof(nv_record->record.linkKey))) + { + TRACE(1,"%s check tws peer success", __func__); + peer_check_ok = true; + } + } + if (!peer_check_ok) + { + TRACE(1,"%s check tws peer failure", __func__); + DUMP8("%02x ", rambak_record->record.bdAddr.address, sizeof(rambak_record->record.bdAddr)); + DUMP8("%02x ", rambak_record->record.linkKey, sizeof(rambak_record->record.linkKey)); + if (memcmp(rambak_record->record.bdAddr.address, zeroAddr.address, sizeof(zeroAddr))) + { + nv_record_add(section_usrdata_ddbrecord, rambak_record); + config->peer_addr = rambak_record->record.bdAddr; + flash_need_flush = true; + TRACE(1,"%s resume tws peer", __func__); + } + } + + } + + ibrt_config_ram_bak.ibrt_config = *config; + rambak_record = &ibrt_config_ram_bak.rec_mobile; + if (!nv_record_btdevicerecord_find(&config->mobile_addr,&nv_record)) + { + *rambak_record = *nv_record; + } + else + { + memset(rambak_record, 0, sizeof(nvrec_btdevicerecord)); + } + rambak_record = &ibrt_config_ram_bak.rec_peer; + if (!nv_record_btdevicerecord_find(&config->peer_addr,&nv_record)) + { + *rambak_record = *nv_record; + } + else + { + memset(rambak_record, 0, sizeof(nvrec_btdevicerecord)); + } + app_ibrt_if_config_keeper_flush(); + if (flash_need_flush) + { + nv_record_flash_flush(); + } + TRACE_IMM(2,"%s end crc:%08x", __func__, ibrt_config_ram_bak.crc); + + TRACE(1,"%s mobile", __func__); + DUMP8("%02x ", ibrt_config_ram_bak.rec_mobile.record.bdAddr.address, sizeof(ibrt_config_ram_bak.rec_mobile.record.bdAddr)); + DUMP8("%02x ", ibrt_config_ram_bak.rec_mobile.record.linkKey, sizeof(ibrt_config_ram_bak.rec_mobile.record.linkKey)); + TRACE(1,"%s peer", __func__); + DUMP8("%02x ", ibrt_config_ram_bak.rec_peer.record.bdAddr.address, sizeof(ibrt_config_ram_bak.rec_peer.record.bdAddr)); + DUMP8("%02x ", ibrt_config_ram_bak.rec_peer.record.linkKey, sizeof(ibrt_config_ram_bak.rec_peer.record.linkKey)); + return 0; +} + +int app_ibrt_if_config_load(ibrt_config_t *config) +{ + memset(config->mobile_addr.address, 0, BD_ADDR_LEN); +#ifdef IBRT_SEARCH_UI + app_ibrt_nvrecord_config_load((void *)config); + config->audio_chnl_sel = A2DP_AUDIO_CHANNEL_SELECT_LRMERGE; +#else + app_ibrt_ui_test_config_load((void *)config); +#endif + return 0; +} + +int app_ibrt_if_reconfig(ibrt_config_t *config) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + p_ibrt_ctrl->nv_role = config->nv_role ; + memcpy(p_ibrt_ctrl->peer_addr.address, config->peer_addr.address, 6); + return 0; +} + +int app_ibrt_if_ui_reconfig(ibrt_ui_config_t *config) +{ + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + + p_ibrt_ui->config = *config; + + return 0; +} + +int app_ibrt_core_if_reconfig(ibrt_core_config_t *config) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + p_ibrt_ctrl->config = *config; + + return 0; +} + +int app_ibrt_if_config(ibrt_ui_config_t *ui_config) +{ + app_ibrt_if_ui_reconfig(ui_config); + + ibrt_core_config_t core_config; + core_config.lowlayer_monitor_enable = ui_config->lowlayer_monitor_enable; + core_config.long_private_poll_interval = ui_config->long_private_poll_interval; + core_config.default_private_poll_interval = ui_config->default_private_poll_interval; + core_config.short_private_poll_interval = ui_config->short_private_poll_interval; + core_config.default_private_poll_interval_in_sco = ui_config->default_private_poll_interval_in_sco; + core_config.short_private_poll_interval_in_sco = ui_config->short_private_poll_interval_in_sco; + core_config.default_bt_tpoll = ui_config->default_bt_tpoll; + core_config.tws_switch_tx_data_protect = ui_config->tws_switch_tx_data_protect; + core_config.tws_cmd_send_timeout = ui_config->tws_cmd_send_timeout; + core_config.tws_cmd_send_counter_threshold = ui_config->tws_cmd_send_counter_threshold; + core_config.tws_switch_stable_timeout = ui_config->tws_switch_stable_timeout; + core_config.mobile_page_timeout = ui_config->mobile_page_timeout; + core_config.tws_connection_timeout = ui_config->tws_connection_timeout; + core_config.delay_exit_sniff = ui_config->delay_exit_sniff; + core_config.delay_ms_exit_sniff = ui_config->delay_ms_exit_sniff; + core_config.audio_sync_mismatch_resume_version = ui_config->audio_sync_mismatch_resume_version; + app_ibrt_core_if_reconfig(&core_config); + + return 0; +} + +int app_ibrt_if_event_entry(ibrt_event_type event) +{ + TRACE(1,"ibrt_ui_log:custom event entry enter=%s", g_log_event_str[event]); + //int status = app_ibrt_ui_event_entry(event); + + app_bt_start_custom_function_in_bt_thread((uint32_t)event, 0, (uint32_t)app_ibrt_ui_event_entry); + +#ifdef BLE_ENABLE + ble_callback_evnet_t ble_callback_event; + ble_callback_event.evt_type = BLE_CALLBACK_IBRT_EVENT_ENTRY; + ble_callback_event.p.ibrt_event_entry_handled.event = event; + app_ble_core_global_callback_event(&ble_callback_event, NULL); +#endif + + return 0; +} + +void app_ibrt_if_choice_connect_second_mobile(void) +{ + TRACE(0,"ibrt_ui_log:app_ibrt_if_choice_connect_second_mobile"); + app_ibrt_ui_choice_connect_second_mobile(); +} + +void app_ibrt_if_choice_mobile_connect(uint8_t index) +{ + TRACE(0,"ibrt_ui_log:app_ibrt_if_choice_mobile_connect"); + app_ibrt_ui_choice_mobile_connect(index); +} + +void app_ibrt_if_disconnect_mobile(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (app_tws_ibrt_mobile_link_connected()) + { + app_tws_ibrt_disconnect_connection(btif_me_get_remote_device_by_handle(p_ibrt_ctrl->mobile_conhandle)); + } + else if (btif_besaud_is_connected()) + { + tws_ctrl_send_cmd(APP_TWS_CMD_DISC_MOBILE, NULL, 0); + } +} + +void app_ibrt_if_disconnect_mobile_tws_link(void) +{ + TRACE(0,"ibrt_ui_log:app_ibrt_if_disconnect_mobile_tws_link"); + app_ibrt_ui_event_entry(IBRT_DISCONNECT_MOBILE_TWS_EVENT); +} + +app_ibrt_if_ui_t* app_ibrt_if_ui_get_ctx(void) +{ + return (app_ibrt_if_ui_t *)app_ibrt_ui_get_ctx(); +} + +app_ibrt_if_ctrl_t *app_ibrt_if_get_bt_ctrl_ctx(void) +{ + return (app_ibrt_if_ctrl_t *)app_tws_ibrt_get_bt_ctrl_ctx(); +} +/* +* this function is only for tws ibrt pairing mode +* when tws earphone is in the nearby, tws link will be connected firstly +* when mobile link exist, this function will disconnect mobile link +*/ +void app_ibrt_if_enter_pairing_after_tws_connected(void) +{ + app_ibrt_ui_event_entry(IBRT_TWS_PAIRING_EVENT); +} +/* +* this function is only for freeman pairing +* no tws link or ibrt link should be connected +* when mobile link or tws link exist, this function will disconnect mobile link and tws link +*/ +void app_ibrt_if_enter_freeman_pairing(void) +{ + app_ibrt_ui_event_entry(IBRT_FREEMAN_PAIRING_EVENT); +} +void app_ibrt_if_ctx_checker(void) +{ + app_ibrt_if_ui_t* ibrt_if_ui_ctx = app_ibrt_if_ui_get_ctx(); + ibrt_ctrl_t *p_ibrt_ctrl = app_ibrt_if_get_bt_ctrl_ctx(); + + TRACE(3,"checker: nv_role:%d current_role:%d access_mode:%d", + p_ibrt_ctrl->nv_role, + p_ibrt_ctrl->current_role, + p_ibrt_ctrl->access_mode); + + DUMP8("%02x ", p_ibrt_ctrl->local_addr.address, BD_ADDR_LEN); + DUMP8("%02x ", p_ibrt_ctrl->peer_addr.address, BD_ADDR_LEN); + + TRACE(4,"checker: super_state:%s/%s evt:%s plf:%d", + g_log_super_state_str[ibrt_if_ui_ctx->super_state], + g_log_super_state_str[ibrt_if_ui_ctx->wait_state], + g_log_event_str[ibrt_if_ui_ctx->active_event&0x0F], + ibrt_if_ui_ctx->profile_exchanged); + + TRACE(4,"checker: box_state:%s/%s sm_run:%d/%d", g_log_box_state_str[ibrt_if_ui_ctx->box_state], + g_log_box_state_str[ibrt_if_ui_ctx->peer_tws_info.box_state], + ibrt_if_ui_ctx->ibrt_sm_running, + ibrt_if_ui_ctx->peer_tws_info.ibrt_sm_running); + + if (p_ibrt_ctrl->mobile_mode == IBRT_ACTIVE_MODE || + p_ibrt_ctrl->tws_mode == IBRT_ACTIVE_MODE) + { + bt_drv_reg_op_controller_state_checker(); + } +} + +int app_ibrt_if_force_audio_retrigger(void) +{ + a2dp_audio_detect_next_packet_callback_register(NULL); + a2dp_audio_detect_store_packet_callback_register(NULL); + app_ibrt_if_voice_report_trig_retrigger(); + return 0; +} + +int app_ibrt_if_force_audio_retrigger_slave_sync(void) +{ + a2dp_audio_detect_next_packet_callback_register(NULL); + a2dp_audio_detect_store_packet_callback_register(NULL); + //app_ibrt_if_voice_report_trig_retrigger(); + return 0; +} + +bool app_ibrt_if_is_audio_active(void) +{ + btif_avdtp_stream_state_t state = btif_a2dp_get_stream_state(app_bt_get_mobile_a2dp_stream(BTIF_DEVICE_ID_1)); + return ((state == BTIF_AVDTP_STRM_STATE_STREAMING) || \ + btapp_hfp_is_sco_active()); +} +bool app_ibrt_if_false_trigger_protect(ibrt_event_type evt_type) +{ + app_ibrt_ui_t *p_ui_ctrl = app_ibrt_ui_get_ctx(); + ibrt_box_state box_state; + if (app_ibrt_ui_event_queue_empty() || \ + (IBRT_BOX_UNKNOWN == p_ui_ctrl->box_state_future)) + { + box_state = p_ui_ctrl->box_state; + p_ui_ctrl->box_state_future = IBRT_BOX_UNKNOWN; + } + else + { + TRACE(2,"event queue not empty, use future box state to judge, rear=%d, front=%d",\ + p_ui_ctrl->event_q_manager.rear, p_ui_ctrl->event_q_manager.front); + + box_state = p_ui_ctrl->box_state_future; + } + + TRACE(1,"ibrt_ui_log:current box state=%s", g_log_box_state_str[box_state]); + +#ifdef IBRT_SEARCH_UI + return false; +#else + switch (evt_type) + { + case IBRT_OPEN_BOX_EVENT: + return (box_state != IBRT_IN_BOX_CLOSED); + + case IBRT_FETCH_OUT_EVENT: + return (box_state != IBRT_IN_BOX_OPEN); + + case IBRT_PUT_IN_EVENT: + return (box_state != IBRT_OUT_BOX); + + case IBRT_CLOSE_BOX_EVENT: + return (box_state != IBRT_IN_BOX_OPEN); + + case IBRT_WEAR_UP_EVENT: + return (box_state != IBRT_OUT_BOX); + + case IBRT_WEAR_DOWN_EVENT: + return (box_state != IBRT_OUT_BOX_WEARED); + + default: + break; + } + return false; +#endif +} +void app_ibrt_if_sco_lowlatency_scan(uint16_t interval, uint16_t window, uint8_t interlanced) +{ + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + TRACE(3,"ibrt_ui_log:custom pscan int 0x%02x win 0x%02x type %d\n", interval, window, interlanced); + p_ibrt_ui->pscan_cust_interval = interval; + p_ibrt_ui->pscan_cust_window = window; + p_ibrt_ui->pscan_cust_type = interlanced; + app_ibrt_ui_judge_scan_type(IBRT_SCO_PLAYING_TRIGGER, NO_LINK_TYPE, IBRT_UI_NO_ERROR); +} + +void app_ibrt_if_sco_restore_scan(void) +{ + TRACE(0,"ibrt_ui_log:restore pscan\n"); + app_ibrt_ui_judge_scan_type(IBRT_SCO_SUSPEND_TRIGGER, NO_LINK_TYPE, IBRT_UI_NO_ERROR); +} + +void app_ibrt_if_a2dp_lowlatency_scan(uint16_t interval, uint16_t window, uint8_t interlanced) +{ + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + TRACE(3,"ibrt_ui_log:custom pscan int 0x%02x win 0x%02x type %d\n", interval, window, interlanced); + p_ibrt_ui->pscan_cust_interval = interval; + p_ibrt_ui->pscan_cust_window = window; + p_ibrt_ui->pscan_cust_type = interlanced; + app_ibrt_ui_judge_scan_type(IBRT_A2DP_PLAYING_TRIGGER, NO_LINK_TYPE, IBRT_UI_NO_ERROR); +} + +void app_ibrt_if_a2dp_restore_scan(void) +{ + TRACE(0,"ibrt_ui_log:restore pscan\n"); + app_ibrt_ui_judge_scan_type(IBRT_A2DP_SUSPEND_TRIGGER, NO_LINK_TYPE, IBRT_UI_NO_ERROR); +} + +/*check if tws link reconnect is allowed*/ +bool app_ibrt_if_tws_reconnect_allowed(void) +{ + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + + if (app_ibrt_ui_is_box_closed()) + { + TRACE(2," connect tws disallowed_1, box_state=%d, f_box_state=%d",\ + p_ibrt_ui->box_state, p_ibrt_ui->box_state_future); + return false; + } + else if (app_tws_ibrt_mobile_link_connected() && \ + app_ibrt_if_is_audio_active()) + { + + TRACE(2," connect tws disallowed_2, box_state=%d, f_box_state=%d",\ + p_ibrt_ui->box_state, p_ibrt_ui->box_state_future); + return false; + } + else + { + TRACE(0," connect tws allowed"); + return true; + } +} + +void app_ibrt_if_sniff_event_callback(const btif_event_t *event) +{ + +} + +void app_ibrt_if_audio_mute(void) +{ + +} + +void app_ibrt_if_audio_recover(void) +{ + +} + +int app_ibrt_if_tws_sniff_block(uint32_t block_next_sec) +{ + tws_sniff_block_start = hal_sys_timer_get(); + tws_sniff_block_next_sec = block_next_sec; + return 0; +} + +static bool app_ibrt_if_tws_sniff_block_need(void) +{ + bool tws_sniff_block = false; + uint32_t passed_ticks = 0; + + if (tws_sniff_block_start) + { + tws_sniff_block = true; + passed_ticks = hal_timer_get_passed_ticks(hal_sys_timer_get(), tws_sniff_block_start); + if (TICKS_TO_MS(passed_ticks) > (tws_sniff_block_next_sec * 1000)) + { + tws_sniff_block_start = 0; + tws_sniff_block_next_sec = 0; + tws_sniff_block = false; + } + } + else + { + tws_sniff_block = false; + } + + return tws_sniff_block; +} + +bool app_ibrt_if_tws_sniff_allowed(void) +{ + btif_avdtp_stream_state_t a2dp_state = BTIF_AVDTP_STRM_STATE_IDLE; + if (app_bt_get_mobile_a2dp_stream(BTIF_DEVICE_ID_1)) + { + a2dp_state = btif_a2dp_get_stream_state(app_bt_get_mobile_a2dp_stream(BTIF_DEVICE_ID_1)); + } + if (a2dp_state == BTIF_AVDTP_STRM_STATE_STREAMING || + btapp_hfp_is_sco_active() || + btapp_hfp_get_call_state() || + btapp_hfp_get_call_setup() != BTIF_HF_CALL_SETUP_NONE || + bt_media_cur_is_bt_stream_media()|| + app_ibrt_if_tws_sniff_block_need() || + app_ibrt_ui_wait_ibrt_connected() + #if defined(IBRT_OTA) + || ota_is_in_progress() + #endif + #ifdef TEST_OVER_THE_AIR_ENANBLED + || spp_tota_in_progress() + #endif + ) + { + TRACE(0,"ibrt_ui_log:sniff not allow\n"); + return false; + } + else + { + TRACE(0,"ibrt_ui_log:sniff allowed\n"); + return true; + } +} + +#define IBRT_IF_SNIFF_CHECKER_INTERVAL_MS (3000) +static void app_ibrt_if_sniff_checker_handler(void const *param); +osTimerDef(APP_IBRT_IF_SNIFF_CHECKER_TIMER, app_ibrt_if_sniff_checker_handler); +static osTimerId app_ibrt_if_sniff_checker_timer = NULL; +static uint32_t app_ibrt_if_sniff_checker_interval_ms = IBRT_IF_SNIFF_CHECKER_INTERVAL_MS; +static uint32_t app_ibrt_if_sniff_checker_user_map = 0; + +static void app_ibrt_if_sniff_checker_handler(void const *param) +{ + app_ibrt_if_ctrl_t *p_ibrt_ctrl = app_ibrt_if_get_bt_ctrl_ctx(); + if (app_ibrt_if_tws_sniff_allowed()) + { + app_ibrt_if_sniff_checker_reset(); + } + else + { + if (app_tws_ibrt_mobile_link_connected()) + { + if (p_ibrt_ctrl->mobile_mode == IBRT_SNIFF_MODE) + { + TRACE(0,"ibrt_ui_log:force exit_sniff_with_mobile\n"); + app_tws_ibrt_exit_sniff_with_mobile(); + } + if (p_ibrt_ctrl->tws_mode == IBRT_SNIFF_MODE) + { + TRACE(0,"ibrt_ui_log:force exit_sniff_with_tws\n"); + app_tws_ibrt_exit_sniff_with_tws(); + } + osTimerStart(app_ibrt_if_sniff_checker_timer, app_ibrt_if_sniff_checker_interval_ms); + } + else if(app_tws_ibrt_slave_ibrt_link_connected()) + { + osTimerStart(app_ibrt_if_sniff_checker_timer, app_ibrt_if_sniff_checker_interval_ms); + } + else + { + app_ibrt_if_sniff_checker_reset(); + } + } +} + +int app_ibrt_if_sniff_checker_init(uint32_t delay_ms) +{ + TRACE(1,"ibrt_ui_log:sniff_checker_init interval:%d \n", delay_ms); + if (app_ibrt_if_sniff_checker_timer == NULL) + { + app_ibrt_if_sniff_checker_timer = osTimerCreate(osTimer(APP_IBRT_IF_SNIFF_CHECKER_TIMER), osTimerOnce, NULL); + } + app_ibrt_if_sniff_checker_interval_ms = delay_ms; + app_ibrt_if_sniff_checker_user_map = 0; + return 0; +} + +int app_ibrt_if_sniff_checker_start(enum APP_IBRT_IF_SNIFF_CHECKER_USER_T user) +{ + if (app_ibrt_if_sniff_checker_timer) + { + TRACE(1,"ibrt_ui_log:sniff_checker_start usr:%d\n", user); + app_ibrt_if_sniff_checker_user_map |= (1 << user); + osTimerStart(app_ibrt_if_sniff_checker_timer, app_ibrt_if_sniff_checker_interval_ms); + } + return 0; +} + +int app_ibrt_if_sniff_checker_stop(enum APP_IBRT_IF_SNIFF_CHECKER_USER_T user) +{ + if (app_ibrt_if_sniff_checker_timer) + { + app_ibrt_if_sniff_checker_user_map &= ~(1 << user); + if (!app_ibrt_if_sniff_checker_user_map) + { + TRACE(1,"ibrt_ui_log:sniff_checker_stop usr:%d\n", user); + osTimerStop(app_ibrt_if_sniff_checker_timer); + } + } + return 0; +} + +int app_ibrt_if_sniff_checker_reset(void) +{ + if (app_ibrt_if_sniff_checker_timer) + { + TRACE(0,"ibrt_ui_log:sniff_checker_reset\n"); + app_ibrt_if_sniff_checker_user_map = 0; + osTimerStop(app_ibrt_if_sniff_checker_timer); + } + return 0; +} + +static uint32_t sleep_hook_blocker = 0; +void app_ibrt_if_exec_sleep_hook_blocker_set(APP_IBRT_IF_SLEEP_HOOK_BLOCKER_T blocker) +{ + sleep_hook_blocker |= (uint32_t)blocker; +} + +void app_ibrt_if_exec_sleep_hook_blocker_clr(APP_IBRT_IF_SLEEP_HOOK_BLOCKER_T blocker) +{ + sleep_hook_blocker &= ~(uint32_t)blocker; +} + +bool app_ibrt_if_exec_sleep_hook_blocker_is_hfp_sco(void) +{ + return sleep_hook_blocker & APP_IBRT_IF_SLEEP_HOOK_BLOCKER_HFP_SCO ? true : false; +} + +bool app_ibrt_if_exec_sleep_hook_blocker_is_a2dp_streaming(void) +{ + return sleep_hook_blocker & APP_IBRT_IF_SLEEP_HOOK_BLOCKER_A2DP_STREAMING ? true : false; +} + +bool app_ibrt_if_exec_sleep_hook_allowed(void) +{ + if (!sleep_hook_blocker) + { + return true; + } + return false; +} + +void app_ibrt_ui_adaptive_fa_rx_gain(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if(app_tws_ibrt_tws_link_connected()) + { + rx_agc_t tws_agc = {0}; + bt_drv_reg_op_read_rssi_in_dbm(p_ibrt_ctrl->tws_conhandle,&tws_agc); + static int8_t old_tws_rssi = tws_agc.rssi; + if(tws_agc.rssi != old_tws_rssi) + { + bt_drv_adaptive_fa_rx_gain(tws_agc.rssi); + old_tws_rssi = tws_agc.rssi; + } + } +} + +void app_tws_ibrt_record_sync_id(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + uint8_t sync_id = bt_drv_reg_op_get_sync_id_op(READ_OP, 0); + if(is_sco_mode() && sync_id != 0xff) + { + uint16_t sync_id_mask = (1<<8)|(sync_id&0xff); + TRACE(3,"%s:sync id=%d, mask=0x%x",__func__, sync_id, sync_id_mask); + p_ibrt_ctrl->sync_id_mask = sync_id_mask; + } +} + +void app_tws_ibrt_resume_sync_id(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + uint8_t sync_id_mask = p_ibrt_ctrl->sync_id_mask>>8; + uint8_t sync_id = p_ibrt_ctrl->sync_id_mask&0xff; + if (sync_id_mask) + { + p_ibrt_ctrl->sync_id_mask = 0; + if(is_sco_mode() && (sync_id != 0xff)) + { + TRACE(2,"%s: sync id=%d",__func__, sync_id); + bt_drv_reg_op_get_sync_id_op(WRITE_OP, sync_id); + } + } +} + +bool app_ibrt_if_start_ibrt_onporcess(void) +{ + app_ibrt_if_ui_t *p_ibrt_ui_ctx = app_ibrt_if_ui_get_ctx(); + if (p_ibrt_ui_ctx->super_state == IBRT_UI_W4_SET_ENV_COMPLETE) + { + return true; + } + + if (p_ibrt_ui_ctx->super_state == IBRT_UI_W4_START_IBRT_COMPLETE) + { + return true; + } + + if (p_ibrt_ui_ctx->super_state == IBRT_UI_W4_IBRT_DATA_EXCHANGE_COMPLETE) + { + return true; + } + + return false; +} + +bool app_ibrt_if_tws_switch_onporcess(void) +{ + app_ibrt_if_ui_t *p_ibrt_ui_ctx = app_ibrt_if_ui_get_ctx(); + if (p_ibrt_ui_ctx->super_state == IBRT_UI_W4_TWS_SWITCH_COMPLETE) + { + return true; + } + + return false; +} + +AppIbrtStatus app_ibrt_if_get_a2dp_state(AppIbrtA2dpState *a2dp_state) +{ + if(app_tws_ibrt_mobile_link_connected() ||app_tws_ibrt_slave_ibrt_link_connected()) + { +#if defined(A2DP_AAC_ON) + if (btif_a2dp_get_stream_state(app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream) > BTIF_AVDTP_STRM_STATE_IDLE) + { + if(a2dp_state != NULL) + { + *a2dp_state = (AppIbrtA2dpState)btif_a2dp_get_stream_state(app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream); + } + } +#else + if(0); +#endif + else if(btif_a2dp_get_stream_state(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream) > BTIF_AVDTP_STRM_STATE_IDLE) + { + if(a2dp_state != NULL) + { + *a2dp_state = (AppIbrtA2dpState)btif_a2dp_get_stream_state(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream); + } + } + else + { + if(a2dp_state != NULL) + { + *a2dp_state = APP_IBRT_IF_A2DP_IDLE; + } + } + } + else + { + if(a2dp_state != NULL) + { + *a2dp_state = APP_IBRT_IF_A2DP_IDLE; + } + } + + return APP_IBRT_IF_STATUS_SUCCESS; +} + + +AppIbrtStatus app_ibrt_if_get_avrcp_state(AppIbrtAvrcpState *avrcp_state) +{ + if(BTIF_AVRCP_STATE_DISCONNECTED != app_bt_device.avrcp_state[BT_DEVICE_ID_1]) + { + if(avrcp_state != NULL) + { + if(avrcp_get_media_status() == BTIF_AVRCP_MEDIA_PLAYING) + { + *avrcp_state = APP_IBRT_IF_AVRCP_PLAYING; + } + else if(avrcp_get_media_status() == BTIF_AVRCP_MEDIA_PAUSED) + { + *avrcp_state = APP_IBRT_IF_AVRCP_PAUSED; + } + else + { + *avrcp_state = APP_IBRT_IF_AVRCP_CONNECTED; + } + } + } + else + { + if(avrcp_state != NULL) + { + *avrcp_state = APP_IBRT_IF_AVRCP_DISCONNECTED; + } + } + return APP_IBRT_IF_STATUS_SUCCESS; +} + + +AppIbrtStatus app_ibrt_if_get_hfp_state(AppIbrtHfpState *hfp_state) +{ + if(btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_1]) == BTIF_HF_STATE_OPEN) + { + if(app_bt_device.hf_audio_state[BT_DEVICE_ID_1] == BTIF_HF_AUDIO_CON) + { + if(hfp_state != NULL) + { + *hfp_state = APP_IBRT_IF_HFP_SCO_OPEN; + } + } + else + { + if(hfp_state != NULL) + { + *hfp_state = APP_IBRT_IF_HFP_SCO_CLOSED; + } + } + } + else + { + if(hfp_state != NULL) + { + *hfp_state = APP_IBRT_IF_HFP_SLC_DISCONNECTED; + } + } + return APP_IBRT_IF_STATUS_SUCCESS; +} + +AppIbrtStatus app_ibrt_if_get_hfp_call_status(AppIbrtCallStatus *call_status) +{ + if(call_status == NULL) + { + return APP_IBRT_IF_STATUS_ERROR_INVALID_PARAMETERS; + } + + if (app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_IN) + { + *call_status = APP_IBRT_IF_SETUP_INCOMMING; + } + else if(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_OUT) + { + *call_status = APP_IBRT_IF_SETUP_OUTGOING; + } + else if(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_ALERT) + { + *call_status = APP_IBRT_IF_SETUP_ALERT; + } + else if((app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_ACTIVE) \ + && (app_bt_device.hf_audio_state[BT_DEVICE_ID_1] == BTIF_HF_AUDIO_CON) + ) + { + *call_status = APP_IBRT_IF_CALL_ACTIVE; + } + else if(app_bt_device.hf_callheld[BT_DEVICE_ID_1] == BTIF_HF_CALL_HELD_ACTIVE) + { + *call_status = APP_IBRT_IF_HOLD; + } + else + { + *call_status = APP_IBRT_IF_NO_CALL; + } + + return APP_IBRT_IF_STATUS_SUCCESS; +} + + +ibrt_role_e app_ibrt_if_get_ibrt_role() +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + return (p_ibrt_ctrl->current_role); +} + + +#endif diff --git a/services/app_ibrt/src/app_ibrt_keyboard.cpp b/services/app_ibrt/src/app_ibrt_keyboard.cpp new file mode 100644 index 0000000..559f33d --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_keyboard.cpp @@ -0,0 +1,400 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include +#include "app_ibrt_keyboard.h" +#include "app_tws_ibrt_trace.h" +#include "app_ibrt_if.h" +#include "app_ibrt_ui_test.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_ctrl_thread.h" +#include "btapp.h" +#include "apps.h" +#include "app_tws_if.h" +#include "app_anc.h" +#include "anc_wnr.h" +#include "app_bt.h" +#include "norflash_api.h" +#include "hal_bootmode.h" +#include "pmu.h" +#include "app_factory_bt.h" +#if defined(IBRT) +#ifdef TILE_DATAPATH +extern "C" void app_tile_key_handler(APP_KEY_STATUS *status, void *param); +#endif +extern struct BT_DEVICE_T app_bt_device; +extern void app_bt_volumedown(); +extern void app_bt_volumeup(); +extern void app_otaMode_enter(APP_KEY_STATUS *status, void *param); + +#if defined(__BT_DEBUG_TPORTS__) && !defined(TPORTS_KEY_COEXIST) +extern void app_ibrt_simulate_charger_plug_in_test(void); +extern void app_ibrt_simulate_charger_plug_out_test(void); +#endif + +static bool qxw_dut_mode_enable = false; + +#ifdef IBRT_SEARCH_UI +void app_ibrt_search_ui_handle_key(APP_KEY_STATUS *status, void *param) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + + + if (APP_KEY_CODE_GOOGLE != status->code) + { + switch(status->event) + { + case APP_KEY_EVENT_CLICK: + app_tws_if_handle_click(); + break; + + case APP_KEY_EVENT_DOUBLECLICK: + TRACE(0,"double kill"); + if(IBRT_UNKNOW==p_ibrt_ctrl->current_role) + { + app_start_tws_serching_direactly(); + } + else + { +#if defined(__BT_DEBUG_TPORTS__) && !defined(TPORTS_KEY_COEXIST) + app_ibrt_simulate_charger_plug_in_test(); +#else + bt_key_handle_func_doubleclick(); +#endif + } + break; + + case APP_KEY_EVENT_LONGPRESS: + // dont use this key for customer release due to + // it is auto triggered by circuit of 3s high-level voltage. + bt_key_handle_func_longpress(); +#if 0 + app_ibrt_ui_judge_scan_type(IBRT_FREEMAN_PAIR_TRIGGER,NO_LINK_TYPE, IBRT_UI_NO_ERROR); + app_ibrt_ui_set_freeman_enable(); +#endif +#if 0 + app_bt_volumeup(); + if(IBRT_MASTER==p_ibrt_ctrl->current_role) + { + TRACE(0,"ibrt master sync volume to slave !"); + app_ibrt_sync_volume_info(); + } +#endif +#if defined(__BT_DEBUG_TPORTS__) && !defined(TPORTS_KEY_COEXIST) + app_ibrt_simulate_charger_plug_out_test(); +#endif + break; + + case APP_KEY_EVENT_TRIPLECLICK: + //bt_key_handle_func_tripleclick(); + /*#ifdef TILE_DATAPATH + app_tile_key_handler(status,NULL); + #else + app_otaMode_enter(NULL,NULL); + #endif*/ + break; + case HAL_KEY_EVENT_LONGLONGPRESS: + TRACE(0,"long long press"); + //if(qxw_dut_mode_enable){ + // qxw_dut_mode_enable = false; + app_bt_power_off_customize(); + + ///} + break; + + case APP_KEY_EVENT_ULTRACLICK: + TRACE(0,"ultra kill"); + if(IBRT_UNKNOW==p_ibrt_ctrl->nv_role){ + app_bt_enter_mono_pairing_mode(); + } + break; + + case APP_KEY_EVENT_RAMPAGECLICK: + TRACE(0,"rampage kill!you are crazy!"); + if(!app_device_bt_is_connected()&&(!app_tws_ibrt_tws_link_connected())){ + app_nvrecord_rebuild(); + osDelay(200); + hal_cmu_sys_reboot(); + } + break; + case APP_KEY_EVENT_SIXTHCLICK: + if(!app_device_bt_is_connected()&&(!app_tws_ibrt_tws_link_connected())){ + qxw_dut_mode_enable = true; + app_factorymode_bt_signalingtest(NULL,NULL); + } + break; + case APP_KEY_EVENT_EIGHTHCLICK: + if(!app_device_bt_is_connected()){ + app_otaMode_enter(NULL,NULL); + } + break; + case APP_KEY_EVENT_UP: + break; + } + } + +#ifdef TILE_DATAPATH + if(APP_KEY_CODE_TILE == status->code) + app_tile_key_handler(status,NULL); +#endif +} +#endif + +void app_ibrt_normal_ui_handle_key(APP_KEY_STATUS *status, void *param) +{ + if (APP_KEY_CODE_GOOGLE != status->code) + { + switch(status->event) + { + case APP_KEY_EVENT_CLICK: + TRACE(0,"first blood."); + app_tws_if_handle_click(); + break; + + case APP_KEY_EVENT_DOUBLECLICK: + TRACE(0,"double kill"); + app_ibrt_if_enter_freeman_pairing(); + break; + + case APP_KEY_EVENT_LONGPRESS: + app_ibrt_if_enter_pairing_after_tws_connected(); + break; + + case APP_KEY_EVENT_TRIPLECLICK: + #ifdef TILE_DATAPATH + app_tile_key_handler(status,NULL); + #endif + break; + + case HAL_KEY_EVENT_LONGLONGPRESS: + TRACE(0,"long long press"); + break; + + case APP_KEY_EVENT_ULTRACLICK: + TRACE(0,"ultra kill"); + app_shutdown(); + break; + + case APP_KEY_EVENT_RAMPAGECLICK: + TRACE(0,"rampage kill!you are crazy!"); +#ifndef HAL_TRACE_RX_ENABLE + hal_trace_rx_reopen(); +#endif + break; + + case APP_KEY_EVENT_UP: + break; + } + } + +#ifdef TILE_DATAPATH + if(APP_KEY_CODE_TILE == status->code) + app_tile_key_handler(status,NULL); +#endif +} + +extern void app_ibrt_customif_test1_cmd_send(uint8_t *p_buff, uint16_t length); +int app_ibrt_if_keyboard_notify(APP_KEY_STATUS *status, void *param) +{ + if (app_tws_ibrt_slave_ibrt_link_connected()) + { + tws_ctrl_send_cmd(APP_TWS_CMD_KEYBOARD_REQUEST, (uint8_t *)status, sizeof(APP_KEY_STATUS)); + } + return 0; +} + +#if(TWS_Sync_Shutdowm) +int app_ibrt_poweroff_notify_force(void) +{ + APP_KEY_STATUS status[] = {APP_KEY_CODE_FN2,HAL_KEY_EVENT_LONGLONGPRESS}; + + if (app_tws_ibrt_tws_link_connected()) + { + app_ibrt_customif_test1_cmd_send((uint8_t *)status, sizeof(APP_KEY_STATUS)); + } + return 0; +} + +int app_ibrt_reboot_notify_force(void) +{ + APP_KEY_STATUS status[] = {APP_KEY_CODE_FN1,HAL_KEY_EVENT_LONGLONGPRESS}; + + if (app_tws_ibrt_tws_link_connected()) + { + app_ibrt_customif_test1_cmd_send((uint8_t *)status, sizeof(APP_KEY_STATUS)); + } + return 0; +} + +#endif +void app_ibrt_send_keyboard_request(uint8_t *p_buff, uint16_t length) +{ + if (app_tws_ibrt_slave_ibrt_link_connected()) + { + app_ibrt_send_cmd_without_rsp(APP_TWS_CMD_KEYBOARD_REQUEST, p_buff, length); + } +} + +bool Is_Slave_Key_Down_Event = false; +void app_ibrt_keyboard_request_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + APP_KEY_STATUS *key_status=(APP_KEY_STATUS *)p_buff; + if(key_status == NULL) + return ; + + if (app_tws_ibrt_mobile_link_connected()) + { +#ifdef IBRT_SEARCH_UI + Is_Slave_Key_Down_Event = true; + if(key_status->code==APP_KEY_CODE_PWR) + { + app_ibrt_search_ui_handle_key(key_status, NULL); + } + else + { + app_ibrt_search_ui_gpio_key_handle(key_status,NULL); + } + +#else + app_ibrt_normal_ui_handle_key(key_status, NULL); +#endif + + app_ibrt_ui_test_voice_assistant_key(key_status, NULL); + } +} + +void app_ibrt_if_start_user_action(uint8_t *p_buff, uint16_t length) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TRACE(3,"%s role %d code %d",__func__, p_ibrt_ctrl->current_role, p_buff[0]); + + if (IBRT_SLAVE == p_ibrt_ctrl->current_role) + { + app_ibrt_ui_send_user_action(p_buff, length); + } + else + { + app_ibrt_ui_perform_user_action(p_buff, length); + } +} + +extern void app_bt_volumeup(); +extern void app_bt_volumedown(); + +void app_ibrt_ui_perform_user_action(uint8_t *p_buff, uint16_t length) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + +#ifdef ANC_APP + app_anc_cmd_receive_process(p_buff, length); +#endif +#ifdef ANC_WNR_ENABLED + app_wnr_cmd_receive_process(p_buff, length); +#endif + + if (IBRT_MASTER != p_ibrt_ctrl->current_role) + { + TRACE(2,"%s not ibrt master, skip cmd %02x\n", __func__, p_buff[0]); + return; + } + + switch (p_buff[0]) + { + case IBRT_ACTION_PLAY: + a2dp_handleKey(AVRCP_KEY_PLAY); + break; + case IBRT_ACTION_PAUSE: + a2dp_handleKey(AVRCP_KEY_PAUSE); + break; + case IBRT_ACTION_FORWARD: + a2dp_handleKey(AVRCP_KEY_FORWARD); + break; + case IBRT_ACTION_BACKWARD: + a2dp_handleKey(AVRCP_KEY_BACKWARD); + break; + case IBRT_ACTION_AVRCP_VOLUP: + a2dp_handleKey(AVRCP_KEY_VOLUME_UP); + break; + case IBRT_ACTION_AVRCP_VOLDN: + a2dp_handleKey(AVRCP_KEY_VOLUME_DOWN); + break; + case IBRT_ACTION_HFSCO_CREATE: + if (!btif_hf_audio_link_is_up()) + { + btif_pts_hf_create_audio_link(); + } + else + { + TRACE(1,"%s cannot create audio link\n", __func__); + } + break; + case IBRT_ACTION_HFSCO_DISC: + if (btif_hf_audio_link_is_up()) + { + btif_pts_hf_disc_audio_link(); + } + else + { + TRACE(1,"%s cannot disc audio link\n", __func__); + } + break; + case IBRT_ACTION_REDIAL: + if (btif_hf_service_link_is_up()) + { + btif_pts_hf_redial_call(); + } + else + { + TRACE(1,"%s cannot redial call\n", __func__); + } + break; + case IBRT_ACTION_ANSWER: + if (btif_hf_service_link_is_up()) + { + btif_pts_hf_answer_call(); + } + else + { + TRACE(1,"%s cannot answer call\n", __func__); + } + break; + case IBRT_ACTION_HANGUP: + if (btif_hf_service_link_is_up()) + { + btif_pts_hf_hangup_call(); + } + else + { + TRACE(1,"%s cannot hangup call\n", __func__); + } + break; + case IBRT_ACTION_LOCAL_VOLUP: + app_bt_volumeup(); + app_ibrt_sync_volume_info(); + break; + case IBRT_ACTION_LOCAL_VOLDN: + app_bt_volumedown(); + app_ibrt_sync_volume_info(); + break; + default: + TRACE(2,"%s unknown user action %d\n", __func__, p_buff[0]); + break; + } +} + +#endif + diff --git a/services/app_ibrt/src/app_ibrt_nvrecord.cpp b/services/app_ibrt/src/app_ibrt_nvrecord.cpp new file mode 100644 index 0000000..815aa96 --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_nvrecord.cpp @@ -0,0 +1,323 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "app_tws_ibrt_trace.h" +#include "app_ibrt_ui.h" +#include "factory_section.h" +#include "app_ibrt_if.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "app_ibrt_nvrecord.h" +#include "ddbif.h" + +/***************************************************************************** + +Prototype : app_ibrt_ui_config_ibrt_info +Description : app ui init +Input : void +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2019/3/29 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +void app_ibrt_nvrecord_config_load(void *config) +{ + struct nvrecord_env_t *nvrecord_env; + ibrt_config_t *ibrt_config = (ibrt_config_t *)config; + //factory_section_original_btaddr_get(ibrt_config->local_addr.address); + nv_record_env_get(&nvrecord_env); + if(nvrecord_env->ibrt_mode.mode!=IBRT_UNKNOW) + { + ibrt_config->nv_role=nvrecord_env->ibrt_mode.mode; + ibrt_config->peer_addr=nvrecord_env->ibrt_mode.record.bdAddr; + ibrt_config->local_addr=nvrecord_env->ibrt_mode.record.bdAddr; + if(nvrecord_env->ibrt_mode.tws_connect_success == 0) + { + app_ibrt_ui_clear_tws_connect_success_last(); + } + else + { + app_ibrt_ui_set_tws_connect_success_last(); + } + } + else + { + ibrt_config->nv_role=IBRT_UNKNOW; + } +} +/***************************************************************************** + +Prototype : app_ibrt_ui_config_ibrt_info +Description : app ui init +Input : void +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2019/3/29 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +int app_ibrt_nvrecord_find(const bt_bdaddr_t *bd_ddr, nvrec_btdevicerecord **record) +{ + return nv_record_btdevicerecord_find(bd_ddr, record); +} +/***************************************************************************** + +Prototype : app_ibrt_nvrecord_update_ibrt_mode_tws +Description : app_ibrt_nvrecord_update_ibrt_mode_tws +Input : status +Output : None +Return Value : +Calls : +Called By : + +History : +Date : 2019/3/29 +Author : bestechnic +Modification : Created function + +*****************************************************************************/ +void app_ibrt_nvrecord_update_ibrt_mode_tws(bool status) +{ + struct nvrecord_env_t *nvrecord_env; + + TRACE(2,"##%s,%d",__func__,status); + nv_record_env_get(&nvrecord_env); + nvrecord_env->ibrt_mode.tws_connect_success = status; + nv_record_env_set(nvrecord_env); + +} +/***************************************************************************** + Prototype : app_ibrt_nvrecord_get_latest_mobiles_addr + Description : get latest mobile addr from nv + Input : bt_bdaddr_t *mobile_addr + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/25 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +int app_ibrt_nvrecord_get_latest_mobiles_addr(bt_bdaddr_t *mobile_addr1, bt_bdaddr_t* mobile_addr2) +{ + btif_device_record_t record; + int found_mobile_addr_count = 0; + int paired_dev_count = nv_record_get_paired_dev_count(); + + /* the tail is latest, the head is oldest */ + for (int i = paired_dev_count - 1; i >= 0; --i) + { + if (BT_STS_SUCCESS != nv_record_enum_dev_records(i, &record)) + { + break; + } + + if (MOBILE_LINK == app_tws_ibrt_get_link_type_by_addr(&record.bdAddr)) + { + found_mobile_addr_count += 1; + + if (found_mobile_addr_count == 1) + { + *mobile_addr1 = record.bdAddr; + } + else if (found_mobile_addr_count == 2) + { + *mobile_addr2 = record.bdAddr; + break; + } + } + } + + return found_mobile_addr_count; +} + +int app_ibrt_nvrecord_choice_mobile_addr(bt_bdaddr_t *mobile_addr, uint8_t index) +{ + btif_device_record_t record; + int paired_dev_count = nv_record_get_paired_dev_count(); + int mobile_found_count = 0; + if (paired_dev_count < index + 1) + { + return 0; + } + + /* the tail is latest, the head is oldest */ + for (int i = paired_dev_count - 1; i >= 0; --i) + { + if (BT_STS_SUCCESS != nv_record_enum_dev_records(i, &record)) + { + break; + } + + if (MOBILE_LINK == app_tws_ibrt_get_link_type_by_addr(&record.bdAddr)) + { + if (mobile_found_count == index) + { + *mobile_addr = record.bdAddr; + return 1; + } + + mobile_found_count += 1; + } + } + + return 0; +} +/***************************************************************************** + Prototype : app_ibrt_nvrecord_get_mobile_addr + Description : get mobile addr from nv + Input : bt_bdaddr_t *mobile_addr + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/25 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +bt_status_t app_ibrt_nvrecord_get_mobile_addr(bt_bdaddr_t *mobile_addr) +{ +#if !defined(FPGA) + btif_device_record_t record1; + btif_device_record_t record2; + btif_device_record_t record; + ibrt_link_type_e link_type; + + uint8_t null_addr[6] = {0}; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + int record_num = nv_record_enum_latest_two_paired_dev(&record1, &record2); + + if (memcmp(&p_ibrt_ctrl->mobile_addr.address[0], &null_addr[0], BTIF_BD_ADDR_SIZE) && + (ddbif_find_record((const bt_bdaddr_t *)&p_ibrt_ctrl->mobile_addr, &record) == BT_STS_SUCCESS)) + { + //first check if mobile addr exist in RAM + *mobile_addr = p_ibrt_ctrl->mobile_addr; + return BT_STS_SUCCESS; + } + + if ((record_num == 1) || (record_num == 2)) + { + //check nv mobile addr + link_type = app_tws_ibrt_get_link_type_by_addr(&record1.bdAddr); + if (link_type == MOBILE_LINK) + { + *mobile_addr = record1.bdAddr; + return BT_STS_SUCCESS; + } + else if (record_num == 2) + { + link_type = app_tws_ibrt_get_link_type_by_addr(&record2.bdAddr); + if (link_type == MOBILE_LINK) + { + *mobile_addr = record2.bdAddr; + return BT_STS_SUCCESS; + } + } + } +#else +#if 0//for fpga test reconnect phone + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + uint8_t nv_slave_connect_addr[] = {0xaf,0x55,0x68,0x68,0x76,0x7c};//huawei + //uint8_t nv_slave_connect_addr[] = {0x62, 0xb2, 0x60, 0x37, 0xab, 0x20};//LJH iphone + memcpy(mobile_addr, &nv_slave_connect_addr[0], BTIF_BD_ADDR_SIZE); + + if (p_ibrt_ctrl->nv_role == IBRT_SLAVE) + { + return BT_STS_SUCCESS; + } +#endif +#endif + return BT_STS_FAILED; +} +/***************************************************************************** + Prototype : app_ibrt_nvrecord_delete_all_mobile_record + Description : app_ibrt_nvrecord_delete_all_mobile_record + Input : None + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/25 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_nvrecord_delete_all_mobile_record(void) +{ + btif_device_record_t record = {0}; + int paired_dev_count = nv_record_get_paired_dev_count(); + + for (int i = paired_dev_count - 1; i >= 0; --i) + { + nv_record_enum_dev_records(i, &record); + + if (MOBILE_LINK == app_tws_ibrt_get_link_type_by_addr(&record.bdAddr)) + { + nv_record_ddbrec_delete(&record.bdAddr); + } + } + app_ibrt_if_config_keeper_clear(); +} + +/***************************************************************************** + Prototype : app_ibrt_nvrecord_rebuild + Description : app_ibrt_nvrecord_rebuild + Input : None + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/25 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_nvrecord_rebuild(void) +{ + struct nvrecord_env_t *nvrecord_env; + nv_record_env_get(&nvrecord_env); + + nv_record_sector_clear(); + nv_record_env_init(); + nv_record_update_factory_tester_status(NVRAM_ENV_FACTORY_TESTER_STATUS_DEFAULT); + nv_record_env_set(nvrecord_env); + nv_record_flash_flush(); + app_ibrt_if_config_keeper_clear(); + app_ibrt_ui_reboot_sdk(); +} + diff --git a/services/app_ibrt/src/app_ibrt_ota_cmd.cpp b/services/app_ibrt/src/app_ibrt_ota_cmd.cpp new file mode 100644 index 0000000..70c31de --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_ota_cmd.cpp @@ -0,0 +1,661 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "string.h" +#include "app_tws_ibrt_trace.h" +#include "app_tws_ctrl_thread.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_ibrt_ota_cmd.h" + +#ifdef IBRT_OTA +#include "../../ibrt_ota/inc/ota_control.h" +#include "ota_spp.h" +#include "ota_common.h" + +static void app_ibrt_ota_get_version_cmd_send(uint8_t *p_buff, uint16_t length); +void app_ibrt_ota_get_version_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_get_version_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_get_version_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_ota_select_side_cmd_send(uint8_t *p_buff, uint16_t length); +void app_ibrt_ota_select_side_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_select_side_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_select_side_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_ota_bp_check_cmd_send(uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_bp_check_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_bp_check_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_bp_check_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_ota_start_cmd_send(uint8_t *p_buff, uint16_t length); +void app_ibrt_ota_start_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_start_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_start_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_ota_config_cmd_send(uint8_t *p_buff, uint16_t length); +void app_ibrt_ota_config_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_config_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_config_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_ota_segment_crc_cmd_send(uint8_t *p_buff, uint16_t length); +void app_ibrt_ota_segment_crc_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_segment_crc_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_segment_crc_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_ota_image_crc_cmd_send(uint8_t *p_buff, uint16_t length); +void app_ibrt_ota_image_crc_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_image_crc_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_image_crc_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_ota_image_overwrite_cmd_send(uint8_t *p_buff, uint16_t length); +void app_ibrt_ota_image_overwrite_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_image_overwrite_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_image_overwrite_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_ota_start_role_switch_cmd_send(uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_start_role_switch_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_ota_image_buff_cmd_send(uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_image_buff_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_common_ota_cmd_send(uint8_t *p_buff, uint16_t length); +static void app_ibrt_common_ota_cmd_received(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + + +static app_tws_cmd_instance_t g_ibrt_ota_tws_cmd_handler_table[]= +{ + { + IBRT_OTA_TWS_GET_VERSION_CMD, "OTA_GET_VERSION", + app_ibrt_ota_get_version_cmd_send, + app_ibrt_ota_get_version_cmd_send_handler, RSP_TIMEOUT_DEFAULT, + app_ibrt_ota_get_version_cmd_send_rsp_timeout_handler, app_ibrt_ota_get_version_cmd_send_rsp_handler + }, + { + IBRT_OTA_TWS_SELECT_SIDE_CMD, "OTA_SELECT_SIDE", + app_ibrt_ota_select_side_cmd_send, + app_ibrt_ota_select_side_cmd_send_handler, RSP_TIMEOUT_DEFAULT, + app_ibrt_ota_select_side_cmd_send_rsp_timeout_handler, app_ibrt_ota_select_side_cmd_send_rsp_handler + }, + { + IBRT_OTA_TWS_BP_CHECK_CMD, "OTA_BP_CHECK",//Break-point + app_ibrt_ota_bp_check_cmd_send, + app_ibrt_ota_bp_check_cmd_send_handler, RSP_TIMEOUT_DEFAULT, + app_ibrt_ota_bp_check_cmd_send_rsp_timeout_handler, app_ibrt_ota_bp_check_cmd_send_rsp_handler + }, + { + IBRT_OTA_TWS_START_OTA_CMD, "OTA_START", + app_ibrt_ota_start_cmd_send, + app_ibrt_ota_start_cmd_send_handler, RSP_TIMEOUT_DEFAULT, + app_ibrt_ota_start_cmd_send_rsp_timeout_handler, app_ibrt_ota_start_cmd_send_rsp_handler + }, + { + IBRT_OTA_TWS_OTA_CONFIG_CMD, "OTA_CONFIG", + app_ibrt_ota_config_cmd_send, + app_ibrt_ota_config_cmd_send_handler, RSP_TIMEOUT_DEFAULT, + app_ibrt_ota_config_cmd_send_rsp_timeout_handler, app_ibrt_ota_config_cmd_send_rsp_handler + }, + { + IBRT_OTA_TWS_SEGMENT_CRC_CMD, "OTA_SEGMENT_CRC", + app_ibrt_ota_segment_crc_cmd_send, + app_ibrt_ota_segment_crc_cmd_send_handler, RSP_TIMEOUT_DEFAULT, + app_ibrt_ota_segment_crc_cmd_send_rsp_timeout_handler, app_ibrt_ota_segment_crc_cmd_send_rsp_handler + }, + { + IBRT_OTA_TWS_IMAGE_CRC_CMD, "OTA_IMAGE_CRC", + app_ibrt_ota_image_crc_cmd_send, + app_ibrt_ota_image_crc_cmd_send_handler, RSP_TIMEOUT_DEFAULT, + app_ibrt_ota_image_crc_cmd_send_rsp_timeout_handler, app_ibrt_ota_image_crc_cmd_send_rsp_handler + }, + { + IBRT_OTA_TWS_IMAGE_OVERWRITE_CMD, "OTA_IMAGE_OVERWRITE", + app_ibrt_ota_image_overwrite_cmd_send, + app_ibrt_ota_image_overwrite_cmd_send_handler, RSP_TIMEOUT_DEFAULT, + app_ibrt_ota_image_overwrite_cmd_send_rsp_timeout_handler, app_ibrt_ota_image_overwrite_cmd_send_rsp_handler + }, + { + IBRT_OTA_TWS_ROLE_SWITCH_CMD, "OTA_ROLE_SWITCH", + app_ibrt_ota_start_role_switch_cmd_send, + app_ibrt_ota_start_role_switch_cmd_send_handler, 0, + app_ibrt_ota_image_buff_cmd_rsp_timeout_handler_null, app_ibrt_ota_image_buff_cmd_rsp_handler_null + }, + { + IBRT_OTA_TWS_IMAGE_BUFF, "OTA_IMAGE_BUFF", + app_ibrt_ota_image_buff_cmd_send, + app_ibrt_ota_image_buff_cmd_send_handler, 0, + app_ibrt_ota_image_buff_cmd_rsp_timeout_handler_null, app_ibrt_ota_image_buff_cmd_rsp_handler_null + }, + { + IBRT_COMMON_OTA, "COMMON_OTA_CMD", + app_ibrt_common_ota_cmd_send, + app_ibrt_common_ota_cmd_received, 0, + app_ibrt_ota_image_buff_cmd_rsp_timeout_handler_null, app_ibrt_ota_image_buff_cmd_rsp_handler_null + }, +}; + +int app_ibrt_ota_tws_cmd_table_get(void **cmd_tbl, uint16_t *cmd_size) +{ + *cmd_tbl = (void *)&g_ibrt_ota_tws_cmd_handler_table; + *cmd_size = ARRAY_SIZE(g_ibrt_ota_tws_cmd_handler_table); + return 0; +} + +extern OTA_IBRT_TWS_CMD_EXECUTED_RESULT_FROM_SLAVE_T receivedResultAlreadyProcessedBySlave; + +uint32_t ibrt_ota_cmd_type = 0; +uint32_t twsBreakPoint = 0; +uint8_t errOtaCode = 0; +static uint8_t resend = RESEND_TIME; + +static void app_ibrt_ota_cache_slave_info(uint8_t typeCode, uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + memcpy(&receivedResultAlreadyProcessedBySlave.typeCode, &typeCode, sizeof(typeCode)); + memcpy(&receivedResultAlreadyProcessedBySlave.rsp_seq, &rsp_seq, sizeof(rsp_seq)); + memcpy(&receivedResultAlreadyProcessedBySlave.length, &length, sizeof(length)); + memcpy(receivedResultAlreadyProcessedBySlave.p_buff, p_buff, length); +} + +static void app_ibrt_ota_get_version_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_with_rsp(IBRT_OTA_TWS_GET_VERSION_CMD, p_buff, length); + TRACE(1,"%s", __func__); +} + +void app_ibrt_ota_get_version_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(ibrt_ota_cmd_type == OTA_RSP_VERSION) + { + ibrt_ota_send_version_rsp(); + tws_ctrl_send_rsp(IBRT_OTA_TWS_GET_VERSION_CMD, rsp_seq, p_buff, length); + ibrt_ota_cmd_type = 0; + } + else + { + app_ibrt_ota_cache_slave_info(OTA_RSP_VERSION, rsp_seq, p_buff, length); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_get_version_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + resend = RESEND_TIME; + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_get_version_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(resend > 0) + { + tws_ctrl_send_cmd(IBRT_OTA_TWS_GET_VERSION_CMD, p_buff, length); + resend--; + } + else + { + resend = RESEND_TIME; + } + TRACE(2,"%s, %d", __func__, resend); +} + +static void app_ibrt_ota_select_side_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_with_rsp(IBRT_OTA_TWS_SELECT_SIDE_CMD, p_buff, length); + TRACE(1,"%s", __func__); +} + +void app_ibrt_ota_select_side_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(ibrt_ota_cmd_type == OTA_RSP_SIDE_SELECTION) + { + if(1 == p_buff[1]) + { + ota_control_side_selection_rsp(true); + } + else + { + ota_control_side_selection_rsp(false); + } + tws_ctrl_send_rsp(IBRT_OTA_TWS_SELECT_SIDE_CMD, rsp_seq, p_buff, length); + ibrt_ota_cmd_type = 0; + } + else + { + app_ibrt_ota_cache_slave_info(OTA_RSP_SIDE_SELECTION, rsp_seq, p_buff, length); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_select_side_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + resend = RESEND_TIME; + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_select_side_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(resend > 0) + { + tws_ctrl_send_cmd(IBRT_OTA_TWS_SELECT_SIDE_CMD, p_buff, length); + resend--; + } + else + { + resend = RESEND_TIME; + } + TRACE(2,"%s, %d", __func__, resend); +} + +static void app_ibrt_ota_bp_check_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_with_rsp(IBRT_OTA_TWS_BP_CHECK_CMD, p_buff, length); + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_bp_check_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + OTA_RSP_RESUME_VERIFY_T* tRsp = (OTA_RSP_RESUME_VERIFY_T *)p_buff; + if(ibrt_ota_cmd_type == OTA_RSP_RESUME_VERIFY) + { + TRACE(2,"breakPoint %d, tRsp->breakPoint %d", twsBreakPoint, tRsp->breakPoint); + if(twsBreakPoint == tRsp->breakPoint) + { + if(twsBreakPoint == 0) + { + LOG_DBG(0,"reset random code:"); + LOG_DUMP("%02x ", (uint8_t *)tRsp, sizeof(OTA_RSP_RESUME_VERIFY_T)); + ota_randomCode_log((uint8_t *)&tRsp->randomCode); + } + ota_control_send_resume_response(tRsp->breakPoint, tRsp->randomCode); + ibrt_ota_cmd_type = 0; + } + else + { + TRACE(1,"%s tws break-point is not synchronized", __func__); + ota_upgradeLog_destroy(); + ota_randomCode_log((uint8_t *)&tRsp->randomCode); + ota_control_reset_env(); + ota_status_change(true); + tRsp->breakPoint = 0xFFFFFFFF; + twsBreakPoint = 0; + } + tws_ctrl_send_rsp(IBRT_OTA_TWS_BP_CHECK_CMD, rsp_seq, (uint8_t *)tRsp, length); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_bp_check_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + resend = RESEND_TIME; + OTA_RSP_RESUME_VERIFY_T* tRsp = (OTA_RSP_RESUME_VERIFY_T *)p_buff; + if(tRsp->breakPoint == 0xFFFFFFFF) + { + TRACE(1,"%s tws break-point is not synchronized", __func__); + ota_upgradeLog_destroy(); + ota_randomCode_log((uint8_t *)&tRsp->randomCode); + ota_control_reset_env(); + ota_status_change(true); + tRsp->breakPoint = 0; + tws_ctrl_send_cmd(IBRT_OTA_TWS_BP_CHECK_CMD, (uint8_t *)tRsp, length); + } + TRACE(1,"%s", __func__); +} +static void app_ibrt_ota_bp_check_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(resend > 0) + { + tws_ctrl_send_cmd(IBRT_OTA_TWS_BP_CHECK_CMD, p_buff, length); + resend--; + } + else + { + resend = RESEND_TIME; + } + TRACE(2,"%s, %d", __func__, resend); +} + +static void app_ibrt_ota_start_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_with_rsp(IBRT_OTA_TWS_START_OTA_CMD, p_buff, length); + TRACE(1,"%s", __func__); +} + +void app_ibrt_ota_start_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(ibrt_ota_cmd_type == OTA_RSP_START) + { + ibrt_ota_send_start_response(*p_buff); + ibrt_ota_cmd_type = 0; + tws_ctrl_send_rsp(IBRT_OTA_TWS_START_OTA_CMD, rsp_seq, p_buff, length); + } + else + { + app_ibrt_ota_cache_slave_info(OTA_RSP_START, rsp_seq, p_buff, length); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_start_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + resend = RESEND_TIME; + TRACE(1,"%s", __func__); +} +static void app_ibrt_ota_start_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(resend > 0) + { + tws_ctrl_send_cmd(IBRT_OTA_TWS_START_OTA_CMD, p_buff, length); + resend--; + } + else + { + resend = RESEND_TIME; + } + TRACE(2,"%s, %d", __func__, resend); +} + +static void app_ibrt_ota_config_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_with_rsp(IBRT_OTA_TWS_OTA_CONFIG_CMD, p_buff, length); + TRACE(1,"%s", __func__); +} + +void app_ibrt_ota_config_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(ibrt_ota_cmd_type == OTA_RSP_CONFIG) + { + if(*p_buff == 1 && errOtaCode == 1) + { + ibrt_ota_send_configuration_response(true); + tws_ctrl_send_rsp(IBRT_OTA_TWS_OTA_CONFIG_CMD, rsp_seq, p_buff, length); + } + else if(*p_buff == OTA_RESULT_ERR_IMAGE_SIZE || errOtaCode == OTA_RESULT_ERR_IMAGE_SIZE) + { + uint8_t errImageSize = OTA_RESULT_ERR_IMAGE_SIZE; + ibrt_ota_send_result_response(OTA_RESULT_ERR_IMAGE_SIZE); + tws_ctrl_send_rsp(IBRT_OTA_TWS_OTA_CONFIG_CMD, rsp_seq, (uint8_t *)&errImageSize, length); + } + else if(*p_buff == OTA_RESULT_ERR_BREAKPOINT || errOtaCode == OTA_RESULT_ERR_BREAKPOINT) + { + uint8_t errBreakPoint = OTA_RESULT_ERR_BREAKPOINT; + ota_upgradeLog_destroy(); + ibrt_ota_send_result_response(OTA_RESULT_ERR_BREAKPOINT); + tws_ctrl_send_rsp(IBRT_OTA_TWS_OTA_CONFIG_CMD, rsp_seq, (uint8_t *)&errBreakPoint, length); + } + else + { + ibrt_ota_send_configuration_response(false); + tws_ctrl_send_rsp(IBRT_OTA_TWS_OTA_CONFIG_CMD, rsp_seq, p_buff, length); + } + errOtaCode = 0; + ibrt_ota_cmd_type = 0; + } + else + { + app_ibrt_ota_cache_slave_info(OTA_RSP_CONFIG, rsp_seq, p_buff, length); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_config_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + resend = RESEND_TIME; + if(*p_buff == OTA_RESULT_ERR_BREAKPOINT) + { + ota_upgradeLog_destroy(); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_config_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(resend > 0) + { + tws_ctrl_send_cmd(IBRT_OTA_TWS_OTA_CONFIG_CMD, p_buff, length); + resend--; + } + else + { + resend = RESEND_TIME; + } + TRACE(2,"%s, %d", __func__, resend); +} + +static void app_ibrt_ota_segment_crc_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_with_rsp(IBRT_OTA_TWS_SEGMENT_CRC_CMD, p_buff, length); + TRACE(1,"%s", __func__); +} + +void app_ibrt_ota_segment_crc_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(ibrt_ota_cmd_type == OTA_RSP_SEGMENT_VERIFY) + { + TRACE(3,"%s: %d %d", __func__,*p_buff,errOtaCode); + if(*p_buff == 1 && errOtaCode == 1) + { + ibrt_ota_send_segment_verification_response(true); + tws_ctrl_send_rsp(IBRT_OTA_TWS_SEGMENT_CRC_CMD, rsp_seq, p_buff, length); + } + else if(*p_buff == OTA_RESULT_ERR_SEG_VERIFY || errOtaCode == OTA_RESULT_ERR_SEG_VERIFY) + { + uint8_t errSegVerify = OTA_RESULT_ERR_SEG_VERIFY; + ota_upgradeLog_destroy(); + ibrt_ota_send_result_response(OTA_RESULT_ERR_SEG_VERIFY); + tws_ctrl_send_rsp(IBRT_OTA_TWS_SEGMENT_CRC_CMD, rsp_seq, (uint8_t *)&errSegVerify, length); + } + else if(*p_buff == OTA_RESULT_ERR_FLASH_OFFSET || errOtaCode == OTA_RESULT_ERR_FLASH_OFFSET) + { + uint8_t errFlashOffset = OTA_RESULT_ERR_FLASH_OFFSET; + ota_upgradeLog_destroy(); + ibrt_ota_send_result_response(OTA_RESULT_ERR_FLASH_OFFSET); + tws_ctrl_send_rsp(IBRT_OTA_TWS_SEGMENT_CRC_CMD, rsp_seq, (uint8_t *)&errFlashOffset, length); + } + else + { + ibrt_ota_send_segment_verification_response(false); + tws_ctrl_send_rsp(IBRT_OTA_TWS_SEGMENT_CRC_CMD, rsp_seq, p_buff, length); + } + errOtaCode = 0; + ibrt_ota_cmd_type = 0; + } + else + { + app_ibrt_ota_cache_slave_info(OTA_RSP_SEGMENT_VERIFY, rsp_seq, p_buff, length); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_segment_crc_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + resend = RESEND_TIME; + if(*p_buff == OTA_RESULT_ERR_SEG_VERIFY || *p_buff == OTA_RESULT_ERR_FLASH_OFFSET) + { + ota_upgradeLog_destroy(); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_segment_crc_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(resend > 0) + { + tws_ctrl_send_cmd(IBRT_OTA_TWS_SEGMENT_CRC_CMD, p_buff, length); + resend--; + } + else + { + resend = RESEND_TIME; + } + TRACE(2,"%s, %d", __func__, resend); +} + +static void app_ibrt_ota_image_crc_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_with_rsp(IBRT_OTA_TWS_IMAGE_CRC_CMD, p_buff, length); + TRACE(1,"%s", __func__); +} + +void app_ibrt_ota_image_crc_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(ibrt_ota_cmd_type == OTA_RSP_RESULT) + { + if(*p_buff == 1 && errOtaCode == 1) + { + ibrt_ota_send_result_response(true); + tws_ctrl_send_rsp(IBRT_OTA_TWS_IMAGE_CRC_CMD, rsp_seq, p_buff, length); + errOtaCode = 0; + } + else + { + uint8_t crcErr = 0; + ibrt_ota_send_result_response(false); + ota_upgradeLog_destroy(); + ota_control_reset_env(); + tws_ctrl_send_rsp(IBRT_OTA_TWS_IMAGE_CRC_CMD, rsp_seq, (uint8_t *)&crcErr, length); + } + ibrt_ota_cmd_type = 0; + } + else + { + app_ibrt_ota_cache_slave_info(OTA_RSP_RESULT, rsp_seq, p_buff, length); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_image_crc_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + resend = RESEND_TIME; + if(*p_buff == 0) + { + ota_upgradeLog_destroy(); + ota_control_reset_env(); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_image_crc_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(resend > 0) + { + tws_ctrl_send_cmd(IBRT_OTA_TWS_IMAGE_CRC_CMD, p_buff, length); + resend--; + } + else + { + resend = RESEND_TIME; + } + TRACE(2,"%s, %d", __func__, resend); +} + +static void app_ibrt_ota_image_overwrite_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_with_rsp(IBRT_OTA_TWS_IMAGE_OVERWRITE_CMD, p_buff, length); + TRACE(1,"%s", __func__); +} + +void app_ibrt_ota_image_overwrite_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(ibrt_ota_cmd_type == OTA_RSP_IMAGE_APPLY) + { + if(*p_buff == 1 && errOtaCode == 1) + { + int ret = tws_ctrl_send_rsp(IBRT_OTA_TWS_IMAGE_OVERWRITE_CMD, rsp_seq, p_buff, length); + if(0 == ret) + { + ota_update_info(); + ota_control_image_apply_rsp(true); + ota_check_and_reboot_to_use_new_image(); + } + } + else + { + uint8_t cantOverWrite = 0; + ota_control_image_apply_rsp(false); + tws_ctrl_send_rsp(IBRT_OTA_TWS_IMAGE_OVERWRITE_CMD, rsp_seq, (uint8_t *)&cantOverWrite, length); + } + errOtaCode = 0; + ibrt_ota_cmd_type = 0; + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_image_overwrite_cmd_send_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + resend = RESEND_TIME; + if(*p_buff == 1) + { + ota_update_info(); + ota_check_and_reboot_to_use_new_image(); + } + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_image_overwrite_cmd_send_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + if(resend > 0) + { + tws_ctrl_send_cmd(IBRT_OTA_TWS_IMAGE_OVERWRITE_CMD, p_buff, length); + resend--; + } + else + { + resend = RESEND_TIME; + } + TRACE(2,"%s, %d", __func__, resend); +} + +static void app_ibrt_ota_image_buff_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_without_rsp(IBRT_OTA_TWS_IMAGE_BUFF, p_buff, length); + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_image_buff_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + ota_bes_handle_received_data(p_buff, true, length); + TRACE(1,"%s", __func__); +} + +static void app_ibrt_common_ota_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_without_rsp(IBRT_COMMON_OTA, p_buff, length); + TRACE(1,"%s", __func__); +} + +static void app_ibrt_common_ota_cmd_received(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + ota_common_on_relay_data_received(p_buff, length); +} + +#ifdef IBRT_OTA +static void app_ibrt_ota_start_role_switch_cmd_send(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_without_rsp(IBRT_OTA_TWS_ROLE_SWITCH_CMD, p_buff, length); + TRACE(1,"%s", __func__); +} + +static void app_ibrt_ota_start_role_switch_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(2,"%s:%d %d", __func__,p_buff[0],length); + + if ((p_buff[0] == OTA_RS_INFO_MASTER_SEND_RS_REQ_CMD)&&(length == 1)) + { + bes_ota_send_role_switch_req(); + } + else if ((p_buff[0] == OTA_RS_INFO_MASTER_DISCONECT_CMD)&&(length == 1)) + { + ota_disconnect(); + } +} +#endif +#endif diff --git a/services/app_ibrt/src/app_ibrt_ota_update.cpp b/services/app_ibrt/src/app_ibrt_ota_update.cpp new file mode 100644 index 0000000..f3cff5e --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_ota_update.cpp @@ -0,0 +1,428 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef __INTERACTION__ +#if defined(IBRT) +#include "cmsis_os.h" +#include +#include "me_api.h" +#include "app_tws_ibrt_trace.h" +#include "audioflinger.h" +#include "app_bt_stream.h" +#include "app_media_player.h" +#include "bt_drv_interface.h" +#include "app_ibrt_if.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_ctrl_thread.h" +#include "app_ibrt_ota_update.h" +#include "app_interaction_ota.h" +#include "app_interaction.h" +#include "hal_norflash.h" +#include "cmsis.h" +#include "pmu.h" +#include "crc32.h" +extern uint32_t __ota_upgrade_log_start[]; +extern INTERACTION_OTA_VALIDATION_DONE_CFM_T Ota_validation_done_cfm; +extern uint32_t get_upgradeSize_log(void); +extern uint32_t breakPoint_local; +extern uint32_t breakPoint_remote; +extern app_ibrt_ota_cmd_code_e cmd_rsp_type; + +uint8_t* ota_address = NULL; +uint32_t ota_address_offset = 0; +bool ota_check_md5 = 1; +uint32_t error_list[16] = {0}; +static void app_ota_reset_timer_handler(void const *param) +{ + app_interaction_ota_finished_handler(); +} + +osTimerDef (APP_OTA_RESET, app_ota_reset_timer_handler); +static osTimerId app_ota_reset_timer = NULL; + +/* +* custom cmd handler add here, this is just a example +*/ + +static void app_ibrt_ota_update_now(uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_update_now_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_update_now_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_ota_update_now_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_check_update_info(uint8_t *p_buff, uint16_t length); +static void app_ibrt_check_update_info_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_check_update_info2_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_sync_breakpoint(uint8_t *p_buff, uint16_t length); +static void app_ibrt_sync_breakpoint_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_sync_breakpoint_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_sync_breakpoint_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_validation(uint8_t *p_buff, uint16_t length); +static void app_ibrt_validation_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_validation_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_validation_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +static void app_ibrt_update_section(uint8_t *p_buff, uint16_t length); +static void app_ibrt_update_section_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_update_section_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +static void app_ibrt_update_section_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +void app_ibrt_view_update_list(void) +{ + TRACE(0,"view_update_list start: ====================="); + for(uint8_t i=0;i<16;i+=8) + TRACE(8,"0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x",error_list[i],error_list[i+1],error_list[i+2],error_list[i+3],error_list[i+4],error_list[i+5],error_list[i+6],error_list[i+7]); + TRACE(0,"view_update_list end: ====================="); +} + +void app_ibrt_view_update_sector(void) +{ + TRACE(0,"view_update_sector start: ====================="); + TRACE(2,"0x%08x 0x%08x\n",__ota_upgrade_log_start[0],__ota_upgrade_log_start[1]); + for(uint16_t i=2;i<512;i+=8){ + if(i!=506){ + TRACE(9,"%d 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x",i,__ota_upgrade_log_start[i],__ota_upgrade_log_start[i+1],__ota_upgrade_log_start[i+2],__ota_upgrade_log_start[i+3],__ota_upgrade_log_start[i+4],__ota_upgrade_log_start[i+5],__ota_upgrade_log_start[i+6],__ota_upgrade_log_start[i+7]); + }else{ + TRACE(7,"%d 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x",i,__ota_upgrade_log_start[i],__ota_upgrade_log_start[i+1],__ota_upgrade_log_start[i+2],__ota_upgrade_log_start[i+3],__ota_upgrade_log_start[i+4],__ota_upgrade_log_start[i+5]); + } + } + TRACE(0,"view_update_sector end: ====================="); +} + +void reset_error_list() +{ + memset(error_list,0,sizeof(error_list)); +} + +void set_all_error_list() +{ + memset(error_list,0xFFFFFFFF,sizeof(error_list)); +} + +void set_error_list(uint16_t list) +{ + if(list < 512) + error_list[list/32] |= (1 << (31-list%32)); +} + +void clr_error_list(uint16_t list) +{ + if(list < 512) + error_list[list/32] &= ~(1 << (31-list%32)); +} + +uint32_t get_error_list() +{ + int8_t i,j; + for(i=0;i<16;i++){ + for(j=31;j>=0;j--){ + if(error_list[i]&(1<nv_role == IBRT_MASTER) + { + if (app_ota_reset_timer == NULL) + app_ota_reset_timer = osTimerCreate (osTimer(APP_OTA_RESET), osTimerOnce, NULL); + osTimerStop(app_ota_reset_timer); + osTimerStart(app_ota_reset_timer, 500); + tws_ctrl_send_cmd(APP_TWS_CMD_OTA_UPDATE_NOW, NULL, 0); + } +} + +void app_ibrt_ota_update_now(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_with_rsp(APP_TWS_CMD_OTA_UPDATE_NOW, NULL, 0); +} + +void app_ibrt_ota_update_now_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + app_interaction_ota_finished_handler(); +} + +void app_ibrt_ota_update_now_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"ibrt_ui_log:%s",__func__); +} + +void app_ibrt_ota_update_now_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(2,"ibrt_ui_log:0x%08x,%d",p_buff,length); +} + +/*===============================================================================*/ +void app_ibrt_ota_check_update_info(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + reset_error_list(); + if (p_ibrt_ctrl->nv_role == IBRT_MASTER) + tws_ctrl_send_cmd(APP_TWS_CMD_CHECK_UPDATE_INFO, NULL, 0); +} + +void app_ibrt_check_update_info(uint8_t *p_buff, uint16_t length) +{ + if(ota_address_offset >= FLASH_SECTOR_SIZE_IN_BYTES){ + TRACE(0,"ibrt_ui_log:app_ibrt_get_update_list before ota completed!!!!!!\n"); + ota_check_md5 = 1; + ota_address_offset = 0; + ota_address = (uint8_t*)__ota_upgrade_log_start; + app_ibrt_view_update_list(); + tws_ctrl_send_cmd(cmd_rsp_type, NULL, 0); + }else{ + ibrt_ota_check_cmd_t cmd; + cmd.length = APP_TWS_CTRL_BUFFER_LEN; + cmd.address = ota_address = (uint8_t*)__ota_upgrade_log_start + ota_address_offset; + breakPoint_local = breakPoint_remote = 0; + TRACE(2,"== > addr:0x%08x length:%d\n", cmd.address, cmd.length); + app_ibrt_send_cmd_without_rsp(APP_TWS_CMD_CHECK_UPDATE_INFO, (uint8_t*)&cmd, sizeof(ibrt_ota_check_cmd_t)); + } +} + +void app_ibrt_check_update_info_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + ibrt_ota_check_cmd_t *p_ibrt_ota_check_cmd = (ibrt_ota_check_cmd_t *)p_buff; + app_ibrt_send_cmd_without_rsp(APP_TWS_CMD_CHECK_UPDATE_INFO2, p_ibrt_ota_check_cmd->address, p_ibrt_ota_check_cmd->length); +} + +void app_ibrt_check_update_info2_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + for(uint16_t i=0;i>>0 0x%08x 0x%08x",*((uint32_t*)ota_address),*((uint32_t*)p_buff)); + set_all_error_list(); + ota_address_offset = FLASH_SECTOR_SIZE_IN_BYTES; + break; + } + }else{ + if((*((uint32_t*)ota_address+i) != *((uint32_t*)p_buff+i))||(*((uint32_t*)ota_address+i+1) != *((uint32_t*)p_buff+i+1))){ + TRACE(1,"%d offset or crc error!!!!!",i); + TRACE(2,"== >>>1 0x%08x 0x%08x",*((uint32_t*)ota_address+i),*((uint32_t*)p_buff+i)); + TRACE(2,"== >>>2 0x%08x 0x%08x",*((uint32_t*)ota_address+i+1),*((uint32_t*)p_buff+i+1)); + set_error_list(ota_address_offset/8+(i-2)/2); + } + } + } + ota_address_offset += APP_TWS_CTRL_BUFFER_LEN; + app_ibrt_check_update_info(NULL,0); +} + + +/*===============================================================================*/ +void app_ibrt_sync_breakpoint(uint8_t *p_buff, uint16_t length) +{ + ibrt_ota_sync_breakpoint_cmd_t cmd; + cmd.local_point = breakPoint_local = get_upgradeSize_log(); + cmd.remote_point = breakPoint_remote = get_error_list(); + app_ibrt_send_cmd_with_rsp(APP_TWS_CMD_SYNC_BREAKPIONT, (uint8_t*)&cmd, sizeof(ibrt_ota_check_cmd_t)); +} + +void app_ibrt_sync_breakpoint_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + ibrt_ota_sync_breakpoint_cmd_t* cmd = (ibrt_ota_sync_breakpoint_cmd_t *)p_buff; + breakPoint_local = cmd->local_point; + breakPoint_remote = cmd->remote_point; + tws_ctrl_send_rsp(APP_TWS_CMD_SYNC_BREAKPIONT, rsp_seq, NULL, 0); +} + +void app_ibrt_sync_breakpoint_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + app_interaction_ota_upgrade_sys_rsp(); +} + +void app_ibrt_sync_breakpoint_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ +} + +void app_ibrt_validation(uint8_t *p_buff, uint16_t length) +{ + ibrt_ota_sync_validation_cmd_t cmd; + if(get_error_list() == 0){ + cmd.flag = INTERACTION_SUCESS; + Ota_validation_done_cfm.status = INTERACTION_SUCESS; + }else{ + cmd.flag = INTERACTION_VALIDATION_FAILURE; + Ota_validation_done_cfm.status = INTERACTION_VALIDATION_FAILURE; + } + app_interaction_ota_upgrade_is_validation_done_rsp(); + app_ibrt_send_cmd_with_rsp(APP_TWS_CMD_VALIDATION_DONE, (uint8_t*)&cmd, sizeof(ibrt_ota_sync_validation_cmd_t)); +} + +void app_ibrt_validation_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + ibrt_ota_sync_validation_cmd_t* cmd = (ibrt_ota_sync_validation_cmd_t *)p_buff; + if(cmd->flag == INTERACTION_SUCESS){ + app_interaction_ota_upgrade_is_complete_hanlder(); //for send 0x0305 cmd to phone; + } + tws_ctrl_send_rsp(APP_TWS_CMD_VALIDATION_DONE, rsp_seq, NULL, 0); + app_interaction_ota_finished_handler(); +} + +void app_ibrt_validation_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + app_interaction_ota_upgrade_is_complete_hanlder(); //for send 0x0305 cmd to phone; + app_interaction_ota_finished_handler(); +} + +void app_ibrt_validation_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ +} + + +/*===============================================================================*/ +void app_ibrt_ota_force_update(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (p_ibrt_ctrl->nv_role == IBRT_MASTER) + { + static uint8_t number = 0; + ibrt_ota_update_cmd_t cmd = {0}; + cmd.point = get_error_list(); + TRACE(1,"update_point: 0x%08x\n", cmd.point); + if(cmd.point != 0){ + cmd.length = APP_TWS_CTRL_BUFFER_LEN; + cmd.address = OTA_FLASH_ENTRY2_OFFSET + cmd.point + number*APP_TWS_CTRL_BUFFER_LEN; + memcpy(cmd.buff,(uint8_t*)cmd.address,APP_TWS_CTRL_BUFFER_LEN); + cmd.number = number%(FLASH_SECTOR_SIZE_IN_BYTES/APP_TWS_CTRL_BUFFER_LEN); + number++; + TRACE(3,"ibrt_ui_log:app_ibrt_ota_force_update addr:0x%08x length:%d no:%d\n", cmd.address, cmd.length, cmd.number); + tws_ctrl_send_cmd(APP_TWS_CMD_UPDATE_SECTION, (uint8_t*)&cmd, sizeof(ibrt_ota_update_cmd_t)); + //TRACE(0,"Calculate the crc32 of the segment."); + //uint32_t startFlashAddr = cmd.address/FLASH_SECTOR_SIZE_IN_BYTES; + //ota_crc = cmd.crc = crc32(0, (uint8_t *)(startFlashAddr), FLASH_SECTOR_SIZE_IN_BYTES); + //TRACE(1,"CRC32 of the segement is 0x%x", cmd.crc); + //TRACE(2,"startFlashAddr is 0x%x, length is %d",startFlashAddr,FLASH_SECTOR_SIZE_IN_BYTES); + }else{ + TRACE(0,"ibrt_ui_log:app_ibrt_ota_force_update completed!!!!!!\n"); + app_ibrt_ota_update_immediately(); + } + } +} + +void app_ibrt_update_section(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_with_rsp(APP_TWS_CMD_UPDATE_SECTION, p_buff, length); +} + +void app_ibrt_update_section_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + ibrt_ota_update_cmd_t *p_ibrt_ota_update_cmd = (ibrt_ota_update_cmd_t *)p_buff; + uint32_t lock; + enum HAL_NORFLASH_RET_T ret = HAL_NORFLASH_OK; + TRACE(4,"ibrt_ui_log:app_ibrt_update_section_handler addr:0x%08x length:%d no:%d point:%d\n", p_ibrt_ota_update_cmd->address, p_ibrt_ota_update_cmd->length, p_ibrt_ota_update_cmd->number, p_ibrt_ota_update_cmd->point); + + lock = int_lock(); + pmu_flash_write_config(); + if(p_ibrt_ota_update_cmd->number == 0){ + ret = hal_norflash_erase(HAL_NORFLASH_ID_0, p_ibrt_ota_update_cmd->address, FLASH_SECTOR_SIZE_IN_BYTES); + TRACE(1,"hal_norflash_erase Sector. %d",ret); + } + + ret = hal_norflash_write(HAL_NORFLASH_ID_0, p_ibrt_ota_update_cmd->address, (uint8_t*)p_ibrt_ota_update_cmd->buff, p_ibrt_ota_update_cmd->length); + TRACE(1,"hal_norflash_write Sector. %d",ret); + pmu_flash_read_config(); + int_unlock(lock); + + ibrt_ota_update_cmd_t cmd = {0}; + cmd.number = p_ibrt_ota_update_cmd->number; + cmd.point = p_ibrt_ota_update_cmd->point; +/* + if(p_ibrt_ota_update_cmd->number == FLASH_SECTOR_SIZE_IN_BYTES/APP_TWS_CTRL_BUFFER_LEN-1){ + TRACE(0,"Calculate the crc32 of the segment."); + uint32_t startFlashAddr = p_ibrt_ota_update_cmd->address - FLASH_SECTOR_SIZE_IN_BYTES + APP_TWS_CTRL_BUFFER_LEN; + cmd.crc = crc32(0, (uint8_t *)(startFlashAddr), FLASH_SECTOR_SIZE_IN_BYTES); + TRACE(1,"CRC32 of the segement is 0x%x", cmd.crc); + TRACE(2,"startFlashAddr is 0x%x, length is %d",startFlashAddr,FLASH_SECTOR_SIZE_IN_BYTES); + } +*/ + tws_ctrl_send_rsp(APP_TWS_CMD_UPDATE_SECTION, rsp_seq, (uint8_t*)&cmd, sizeof(ibrt_ota_update_cmd_t)); +} + +void app_ibrt_update_section_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"ibrt_ui_log:%s",__func__); +} + +void app_ibrt_update_section_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + ibrt_ota_update_cmd_t *p_ibrt_ota_update_rsp = (ibrt_ota_update_cmd_t *)p_buff; + TRACE(3,"ibrt_ui_log:app_ibrt_update_section_rsp_handler addr:0x%08x length:%d no:%d\n", p_ibrt_ota_update_rsp->address, p_ibrt_ota_update_rsp->length, p_ibrt_ota_update_rsp->number); + if(p_ibrt_ota_update_rsp->number == FLASH_SECTOR_SIZE_IN_BYTES/APP_TWS_CTRL_BUFFER_LEN-1){ + TRACE(1,"CRC32 of the update is 0x%08x",p_ibrt_ota_update_rsp->crc); + //if(p_ibrt_ota_update_rsp->crc == ota_crc) + clr_error_list(p_ibrt_ota_update_rsp->point); + app_ibrt_view_update_list(); + } + app_ibrt_ota_force_update(); +} +#endif +#endif diff --git a/services/app_ibrt/src/app_ibrt_peripheral_manager.cpp b/services/app_ibrt/src/app_ibrt_peripheral_manager.cpp new file mode 100644 index 0000000..6070a09 --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_peripheral_manager.cpp @@ -0,0 +1,335 @@ +/*************************************************************************** +* +* Copyright 2015-2019 BES. +* All rights reserved. All unpublished rights reserved. +* +* No part of this work may be used or reproduced in any form or by any +* means, or stored in a database or retrieval system, without prior written +* permission of BES. +* +* Use of this work is governed by a license granted by BES. +* This work contains confidential and proprietary information of +* BES. which is protected by copyright, trade secret, +* trademark and other intellectual property rights. +* +****************************************************************************/ +#include +#include "cmsis_os.h" +#include "app_tws_ibrt_trace.h" +#include "bluetooth.h" +#include "crc16.h" +#include "heap_api.h" +#include "hci_api.h" +#include "me_api.h" +#include "app_tws_ibrt.h" +#include "app_tws_besaud.h" +#include "app_vendor_cmd_evt.h" +#include "tws_role_switch.h" +#include "l2cap_api.h" +#include "rfcomm_api.h" +#include "conmgr_api.h" +#include "bt_if.h" +#include "app_ibrt_if.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_ibrt.h" +#include "bt_drv_interface.h" +#include "bt_drv_reg_op.h" +#include "app_ibrt_peripheral_manager.h" +#include "app_ibrt_ui.h" +#if defined(IBRT) +osThreadId app_ibrt_peripheral_tid; +static void app_ibrt_peripheral_thread(void const *argument); +osThreadDef(app_ibrt_peripheral_thread, osPriorityHigh,1, 2048,"app_ibrt_peripheral_thread"); + +#define TWS_PERIPHERAL_DEVICE_MAILBOX_MAX (10) +osMailQDef (app_ibrt_peripheral_mailbox, TWS_PERIPHERAL_DEVICE_MAILBOX_MAX, TWS_PD_MSG_BLOCK); +static osMailQId app_ibrt_peripheral_mailbox = NULL; +static uint8_t app_ibrt_peripheral_mailbox_cnt = 0; + +static int app_ibrt_peripheral_mailbox_init(void) +{ + app_ibrt_peripheral_mailbox = osMailCreate(osMailQ(app_ibrt_peripheral_mailbox), NULL); + if (app_ibrt_peripheral_mailbox == NULL) { + TRACE(0,"Failed to Create app_ibrt_peripheral_mailbox\n"); + return -1; + } + app_ibrt_peripheral_mailbox_cnt = 0; + return 0; +} + +int app_ibrt_peripheral_mailbox_put(TWS_PD_MSG_BLOCK* msg_src) +{ + if(!msg_src){ + TRACE(0,"msg_src is a null pointer in app_ibrt_peripheral_mailbox_put!"); + return -1; + } + + osStatus status; + TWS_PD_MSG_BLOCK *msg_p = NULL; + msg_p = (TWS_PD_MSG_BLOCK*)osMailAlloc(app_ibrt_peripheral_mailbox, 0); + ASSERT(msg_p, "osMailAlloc error"); + msg_p->msg_body.message_id = msg_src->msg_body.message_id; + msg_p->msg_body.message_ptr = msg_src->msg_body.message_ptr; + msg_p->msg_body.message_Param0 = msg_src->msg_body.message_Param0; + msg_p->msg_body.message_Param1 = msg_src->msg_body.message_Param1; + msg_p->msg_body.message_Param2 = msg_src->msg_body.message_Param2; + + status = osMailPut(app_ibrt_peripheral_mailbox, msg_p); + if (osOK == status) + app_ibrt_peripheral_mailbox_cnt++; + return (int)status; +} + +int app_ibrt_peripheral_mailbox_free(TWS_PD_MSG_BLOCK* msg_p) +{ + if(!msg_p){ + TRACE(0,"msg_p is a null pointer in app_ibrt_peripheral_mailbox_free!"); + return -1; + } + osStatus status; + + status = osMailFree(app_ibrt_peripheral_mailbox, msg_p); + if (osOK == status) + app_ibrt_peripheral_mailbox_cnt--; + + return (int)status; +} + +int app_ibrt_peripheral_mailbox_get(TWS_PD_MSG_BLOCK** msg_p) +{ + if(!msg_p){ + TRACE(0,"msg_p is a null pointer in app_ibrt_peripheral_mailbox_get!"); + return -1; + } + + osEvent evt; + evt = osMailGet(app_ibrt_peripheral_mailbox, osWaitForever); + if (evt.status == osEventMail) { + *msg_p = (TWS_PD_MSG_BLOCK *)evt.value.p; + return 0; + } + return -1; +} + +#ifdef BES_AUTOMATE_TEST +#define APP_IBRT_PERIPHERAL_BUF_SIZE 2048 +static heap_handle_t app_ibrt_peripheral_heap; +uint8_t app_ibrt_peripheral_buf[APP_IBRT_PERIPHERAL_BUF_SIZE]; +bool app_ibrt_auto_test_started = false; +void app_ibrt_peripheral_heap_init(void) +{ + app_ibrt_auto_test_started = true; + app_ibrt_peripheral_heap = heap_register(app_ibrt_peripheral_buf, APP_IBRT_PERIPHERAL_BUF_SIZE); +} + +void *app_ibrt_peripheral_heap_malloc(uint32_t size) +{ + void *ptr = heap_malloc(app_ibrt_peripheral_heap,size); + ASSERT(ptr, "%s size:%d", __func__, size); + return ptr; +} + +void *app_ibrt_peripheral_heap_cmalloc(uint32_t size) +{ + void *ptr = heap_malloc(app_ibrt_peripheral_heap,size); + ASSERT(ptr, "%s size:%d", __func__, size); + memset(ptr, 0, size); + return ptr; +} + +void *app_ibrt_peripheral_heap_realloc(void *rmem, uint32_t newsize) +{ + void *ptr = heap_realloc(app_ibrt_peripheral_heap, rmem, newsize); + ASSERT(ptr, "%s rmem:%p size:%d", __func__, rmem,newsize); + return ptr; +} + +void app_ibrt_peripheral_heap_free(void *rmem) +{ + ASSERT(rmem, "%s rmem:%p", __func__, rmem); + heap_free(app_ibrt_peripheral_heap, rmem); +} +#endif + +void app_ibrt_peripheral_auto_test_stop(void) +{ +#ifdef BES_AUTOMATE_TEST + app_ibrt_auto_test_started = false; +#endif +} + +/***************************************************************************** + Prototype : app_ibrt_peripheral_thread + Description : peripheral manager thread + Input : void const *argument + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/18 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +typedef void (*app_ibrt_peripheral_cb0)(void); +typedef void (*app_ibrt_peripheral_cb1)(void *); +typedef void (*app_ibrt_peripheral_cb2)(void *, void *); +void app_ibrt_peripheral_automate_test_handler(uint8_t *cmd_buf, uint32_t cmd_len); + +void app_ibrt_peripheral_thread(void const *argument) +{ + while(1){ + TWS_PD_MSG_BLOCK *msg_p = NULL; + if ((!app_ibrt_peripheral_mailbox_get(&msg_p))&&(!argument)) { + switch(msg_p->msg_body.message_id){ + case 0: + if(msg_p->msg_body.message_ptr){ + ((app_ibrt_peripheral_cb0)(msg_p->msg_body.message_ptr))(); + } + break; + case 1: + if(msg_p->msg_body.message_ptr){ + ((app_ibrt_peripheral_cb1)(msg_p->msg_body.message_ptr))((void *)msg_p->msg_body.message_Param0); + } + break; + case 2: + if(msg_p->msg_body.message_ptr){ + ((app_ibrt_peripheral_cb2)(msg_p->msg_body.message_ptr))((void *)msg_p->msg_body.message_Param0, + (void *)msg_p->msg_body.message_Param1); + } + break; + case 0xfe: + app_ibrt_peripheral_automate_test_handler((uint8_t*)msg_p->msg_body.message_Param0, + (uint32_t)msg_p->msg_body.message_Param1); + break; + case 0xff: {// ibrt test + char ibrt_cmd[20] = {0}; + memcpy(ibrt_cmd+0, &msg_p->msg_body.message_Param0, 4); + memcpy(ibrt_cmd+4, &msg_p->msg_body.message_Param1, 4); + memcpy(ibrt_cmd+8, &msg_p->msg_body.message_Param2, 4); + TRACE(1,"ibrt_ui_log: %s\n", ibrt_cmd); + app_ibrt_ui_test_cmd_handler((unsigned char*)ibrt_cmd, strlen(ibrt_cmd)+1); + } + break; + default: + break; + } + app_ibrt_peripheral_mailbox_free(msg_p); + } + } +} + +void app_ibrt_peripheral_automate_test_handler(uint8_t* cmd_buf, uint32_t cmd_len) +{ +#ifdef BES_AUTOMATE_TEST + AUTO_TEST_CMD_T *test_cmd = (AUTO_TEST_CMD_T *)cmd_buf; + static uint8_t last_group_code = 0xFF; + static uint8_t last_operation_code = 0xFF; + + //TRACE(4, "%s group 0x%x op 0x%x times %d len %d", __func__, + //test_cmd->group_code, test_cmd->opera_code, test_cmd->test_times, test_cmd->param_len); + //TRACE(2, "last group 0x%x last op 0x%x", last_group_code, last_operation_code); + if (last_group_code != test_cmd->group_code || last_operation_code != test_cmd->opera_code) + { + for (uint8_t i=0; itest_times; i++) + { + last_group_code = test_cmd->group_code; + last_operation_code = test_cmd->opera_code; + app_ibrt_ui_automate_test_cmd_handler(test_cmd->group_code, test_cmd->opera_code, test_cmd->param, test_cmd->param_len); + } + } + app_ibrt_peripheral_heap_free(cmd_buf); +#endif +} + +extern "C" void app_ibrt_peripheral_automate_test(const char* ibrt_cmd, uint32_t cmd_len) +{ +#ifdef BES_AUTOMATE_TEST + uint16_t crc16_rec = 0; + uint16_t crc16_result = 0; + uint8_t *cmd_buf = NULL; + uint32_t _cmd_data_len = 0; + uint32_t _cmd_data_min_len = sizeof(AUTO_TEST_CMD_T)+AUTOMATE_TEST_CMD_CRC_RECORD_LEN; + TWS_PD_MSG_BLOCK msg; + + if (ibrt_cmd && cmd_len>=_cmd_data_min_len && cmd_len<=(_cmd_data_min_len+AUTOMATE_TEST_CMD_PARAM_MAX_LEN)) + { + _cmd_data_len = cmd_len-AUTOMATE_TEST_CMD_CRC_RECORD_LEN; + crc16_rec = *(uint16_t *)(&ibrt_cmd[_cmd_data_len]); + crc16_result = _crc16(crc16_result, (const unsigned char *)ibrt_cmd, _cmd_data_len); + //DUMP8("0x%x ", ibrt_cmd, cmd_len); + //TRACE(4, "%s crc16 rec 0x%x result 0x%x buf_len %d", __func__, crc16_rec, crc16_result, cmd_len); + if (crc16_rec == crc16_result && app_ibrt_auto_test_started) + { + app_ibrt_auto_test_inform_cmd_received(ibrt_cmd[0], ibrt_cmd[1]); + cmd_buf = (uint8_t *)app_ibrt_peripheral_heap_cmalloc(_cmd_data_len); + memcpy(cmd_buf, ibrt_cmd, _cmd_data_len); + msg.msg_body.message_id = 0xfe; + msg.msg_body.message_Param0 = (uint32_t)cmd_buf; + msg.msg_body.message_Param1 = _cmd_data_len; + app_ibrt_peripheral_mailbox_put(&msg); + } + return; + } + + //ASSERT(0, "%s ibrt_cmd %p cmd_len %d", __func__, ibrt_cmd, cmd_len); +#endif +} + +extern "C" void app_ibrt_peripheral_perform_test(const char* ibrt_cmd) +{ + TWS_PD_MSG_BLOCK msg; + msg.msg_body.message_id = 0xff; + memcpy(&msg.msg_body.message_Param0, ibrt_cmd+0, 4); + memcpy(&msg.msg_body.message_Param1, ibrt_cmd+4, 4); + memcpy(&msg.msg_body.message_Param2, ibrt_cmd+8, 4); + app_ibrt_peripheral_mailbox_put(&msg); +} + +void app_ibrt_peripheral_run0(uint32_t ptr) +{ + TWS_PD_MSG_BLOCK msg; + msg.msg_body.message_id = 0; + msg.msg_body.message_ptr = ptr; + app_ibrt_peripheral_mailbox_put(&msg); +} + +void app_ibrt_peripheral_run1(uint32_t ptr, uint32_t param0) +{ + TWS_PD_MSG_BLOCK msg; + msg.msg_body.message_id = 1; + msg.msg_body.message_ptr = ptr; + msg.msg_body.message_Param0 = param0; + app_ibrt_peripheral_mailbox_put(&msg); +} + +void app_ibrt_peripheral_run2(uint32_t ptr, uint32_t param0, uint32_t param1) +{ + TWS_PD_MSG_BLOCK msg; + msg.msg_body.message_id = 2; + msg.msg_body.message_ptr = ptr; + msg.msg_body.message_Param0 = param0; + msg.msg_body.message_Param1 = param1; + app_ibrt_peripheral_mailbox_put(&msg); +} + +void app_ibrt_peripheral_thread_init(void) +{ + if (app_ibrt_peripheral_mailbox_init()) + return; + + app_ibrt_peripheral_tid = osThreadCreate(osThread(app_ibrt_peripheral_thread), NULL); + if (app_ibrt_peripheral_tid == NULL) { + TRACE(0,"Failed to Create app_ibrt_peripheral_thread\n"); + return; + } + +#ifdef BES_AUTOMATE_TEST + app_ibrt_peripheral_heap_init(); +#endif + return; +} +#endif + diff --git a/services/app_ibrt/src/app_ibrt_rssi.cpp b/services/app_ibrt/src/app_ibrt_rssi.cpp new file mode 100644 index 0000000..c71f36f --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_rssi.cpp @@ -0,0 +1,586 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +//#include "mbed.h" +#if defined(IBRT) +#include +#include + +#include "hal_trace.h" +#include "app_ibrt_if.h" +#include "app_tws_ctrl_thread.h" +#include "app_ibrt_rssi.h" +#include "a2dp_decoder.h" + +#define RSSI_WINDOW_SIZE 30 + +static tota_stutter_t g_stutter = {0,}; +extern float a2dp_audio_get_sample_reference(void); +extern int8_t a2dp_audio_get_current_buf_size(void); +extern diff_us_t * app_tws_ibrt_audio_sync_get_diff_us(void); + +struct rssi_window_struct +{ + int8_t buf[RSSI_WINDOW_SIZE]; + uint8_t index; +}; + +extern osTimerId ibrt_ui_check_roleswitch_timer_id; +static struct rssi_window_struct tws_rssi_window = {0}; +static struct rssi_window_struct mobile_rssi_window = {0}; +static bool need_roleswitch_with_rssi_bak = false; + +static void rssi_window_push(struct rssi_window_struct *p, int8_t data) +{ + if(p == NULL) + { + return; + } + + if(p->index < RSSI_WINDOW_SIZE) + { + for(uint8_t i=p->index; i>0; i--) + { + p->buf[i] = p->buf[i-1]; + } + p->buf[0] = data; + p->index++; + } + else + { + for(uint8_t i=p->index-1; i>0; i--) + { + p->buf[i] = p->buf[i-1]; + } + p->buf[0] = data; + } +} + +void app_ibrt_ui_rssi_reset(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + memset(&tws_rssi_window,0,sizeof(rssi_window_struct)); + memset(&mobile_rssi_window,0,sizeof(rssi_window_struct)); + need_roleswitch_with_rssi_bak = false; + p_ibrt_ctrl->raw_rssi.agc_idx0 = 0; + p_ibrt_ctrl->raw_rssi.rssi0 = 0; + p_ibrt_ctrl->raw_rssi.rssi0_max = 0x7f; + p_ibrt_ctrl->raw_rssi.rssi0_min = 0x80; + p_ibrt_ctrl->raw_rssi.agc_idx1 = 0; + p_ibrt_ctrl->raw_rssi.rssi1 = 0; + p_ibrt_ctrl->raw_rssi.rssi1_max = 0x7f; + p_ibrt_ctrl->raw_rssi.rssi1_min = 0x80; + p_ibrt_ctrl->raw_rssi.rssi2 = 0; + p_ibrt_ctrl->raw_rssi.rssi2_max = 0x7f; + p_ibrt_ctrl->raw_rssi.rssi2_min = 0x80; + p_ibrt_ctrl->raw_rssi.ser = 0; + p_ibrt_ctrl->raw_rssi.rx_data_sum = 0; + + p_ibrt_ctrl->peer_raw_rssi.agc_idx0 = 0; + p_ibrt_ctrl->peer_raw_rssi.rssi0 = 0; + p_ibrt_ctrl->peer_raw_rssi.rssi0_max = 0x7f; + p_ibrt_ctrl->peer_raw_rssi.rssi0_min = 0x80; + p_ibrt_ctrl->peer_raw_rssi.agc_idx1 = 0; + p_ibrt_ctrl->peer_raw_rssi.rssi1 = 0; + p_ibrt_ctrl->peer_raw_rssi.rssi1_max = 0x7f; + p_ibrt_ctrl->peer_raw_rssi.rssi1_min =0x80; + p_ibrt_ctrl->peer_raw_rssi.rssi2 = 0; + p_ibrt_ctrl->peer_raw_rssi.rssi2_max = 0x7f; + p_ibrt_ctrl->peer_raw_rssi.rssi2_min =0x80; + p_ibrt_ctrl->peer_raw_rssi.ser = 0; + p_ibrt_ctrl->peer_raw_rssi.rx_data_sum = 0; + p_ibrt_ctrl->role_switch_debonce_time = 0; +} + +/***************************************************************************** + Prototype : app_ibrt_ui_check_roleswitch_timer_cb + Description : close bt scan when timeout + Input : current_evt + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/17 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_rssi_process(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if(app_tws_ibrt_tws_link_connected()){ + rx_agc_t tws_agc = {0}; + bt_drv_reg_op_read_rssi_in_dbm(p_ibrt_ctrl->tws_conhandle,&tws_agc); + rssi_window_push(&tws_rssi_window, tws_agc.rssi); + if(tws_rssi_window.index >= RSSI_WINDOW_SIZE){ + int32_t tws_rssi_sum = 0; + for(uint8_t i=0; iraw_rssi.rssi1 = tws_rssi_sum/RSSI_WINDOW_SIZE; + p_ibrt_ctrl->raw_rssi.agc_idx1 = tws_agc.rxgain; + + if(p_ibrt_ctrl->raw_rssi.rssi1 >= p_ibrt_ctrl->raw_rssi.rssi1_max) + p_ibrt_ctrl->raw_rssi.rssi1_max = p_ibrt_ctrl->raw_rssi.rssi1; + if(p_ibrt_ctrl->raw_rssi.rssi1 <= p_ibrt_ctrl->raw_rssi.rssi1_min) + p_ibrt_ctrl->raw_rssi.rssi1_min = p_ibrt_ctrl->raw_rssi.rssi1; + }else{ + p_ibrt_ctrl->raw_rssi.rssi1 = 0; + p_ibrt_ctrl->raw_rssi.rssi1_max = 0x80; + p_ibrt_ctrl->raw_rssi.rssi1_min = 0x7f; + p_ibrt_ctrl->raw_rssi.agc_idx1 = 0; + } + } + + bool mobile_link_flag = app_tws_ibrt_mobile_link_connected(); + bool slave_ibrt_link_flag = app_tws_ibrt_slave_ibrt_link_connected(); + + if(mobile_link_flag||slave_ibrt_link_flag){ + rx_agc_t mobile_agc= {0}; + if(mobile_link_flag){ + bt_drv_reg_op_read_rssi_in_dbm(p_ibrt_ctrl->mobile_conhandle,&mobile_agc); + }else if(slave_ibrt_link_flag){ + bt_drv_reg_op_read_rssi_in_dbm(p_ibrt_ctrl->ibrt_conhandle,&mobile_agc); + } + rssi_window_push(&mobile_rssi_window, mobile_agc.rssi); + if(mobile_rssi_window.index >= RSSI_WINDOW_SIZE){ + int32_t mobile_rssi_sum = 0; + for(uint8_t i=0; iraw_rssi.rssi0 = mobile_rssi_sum/RSSI_WINDOW_SIZE; + p_ibrt_ctrl->raw_rssi.agc_idx0 = mobile_agc.rxgain; + + if(p_ibrt_ctrl->raw_rssi.rssi0 >= p_ibrt_ctrl->raw_rssi.rssi0_max) + p_ibrt_ctrl->raw_rssi.rssi0_max = p_ibrt_ctrl->raw_rssi.rssi0; + if(p_ibrt_ctrl->raw_rssi.rssi0 <= p_ibrt_ctrl->raw_rssi.rssi0_min) + p_ibrt_ctrl->raw_rssi.rssi0_min = p_ibrt_ctrl->raw_rssi.rssi0; + }else{ + p_ibrt_ctrl->raw_rssi.rssi0 = 0; + p_ibrt_ctrl->raw_rssi.rssi0_max = 0x80; + p_ibrt_ctrl->raw_rssi.rssi0_min = 0x7f; + p_ibrt_ctrl->raw_rssi.agc_idx0 = 0; + } + } + //TRACE(5,"mobile -> %d:%d tws -> %d:%d SER:%d/100", p_ibrt_ctrl->raw_rssi.rssi0, p_ibrt_ctrl->raw_rssi.agc_idx0, p_ibrt_ctrl->raw_rssi.rssi1, p_ibrt_ctrl->raw_rssi.agc_idx1,p_ibrt_ctrl->raw_rssi.ser); +} +/***************************************************************************** + Prototype : app_ibrt_ui_tws_switch_according_rssi_needed + Description : + Input : void + Output : bool + Return Value : + Calls : + Called By : + + History : + Date : 2019/6/5 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +bool app_ibrt_ui_tws_switch_according_rssi_needed(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + + if ((p_ibrt_ctrl->raw_rssi.rssi0 != IBRT_UI_INVALID_RSSI)&& + (p_ibrt_ctrl->peer_raw_rssi.rssi0 != IBRT_UI_INVALID_RSSI)&& + (p_ibrt_ctrl->peer_raw_rssi.rssi0 >= IBRT_UI_MIN_RSSI) && + (p_ibrt_ctrl->raw_rssi.rssi0 >= IBRT_UI_MIN_RSSI)) + { + int8_t rssi_d_value_diff = p_ibrt_ctrl->peer_raw_rssi.rssi0 - p_ibrt_ctrl->raw_rssi.rssi0; + + if(rssi_d_value_diff >= p_ibrt_ui->config.rssi_threshold) + { + //local RSSI is stronger than peer and local role is SLAVE + return true; + } + } + return false; +} + +/***************************************************************************** + Prototype : app_ibrt_ui_check_roleswitch_timer_cb + Description : close bt scan when timeout + Input : current_evt + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/17 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_check_roleswitch_timer_cb(void const *current_evt) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + + //app_ibrt_ui_rssi_process(); + + if (app_tws_ibrt_mobile_link_connected() && + app_ibrt_ui_is_profile_exchanged() && + (p_ibrt_ctrl->tws_mode == BTIF_BLM_ACTIVE_MODE)) + { + tws_ctrl_send_cmd(APP_TWS_CMD_GET_PEER_MOBILE_RSSI, NULL, 0); + } + + osTimerStart(ibrt_ui_check_roleswitch_timer_id, p_ibrt_ui->config.rssi_monitor_timeout); +} + +/***************************************************************************** + Prototype : app_ibrt_get_peer_mobile_rssi + Description : + Input : uint8_t *p_buff + uint16_t length + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/6/4 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_get_peer_mobile_rssi(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_without_rsp(APP_TWS_CMD_GET_PEER_MOBILE_RSSI, p_buff, length); +} + +/***************************************************************************** + Prototype : app_ibrt_get_peer_mobile_rssi_handler + Description : + Input : uint8_t *p_buff + uint16_t length + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/6/4 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_get_peer_mobile_rssi_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + diff_us_t * p_diff_us = app_tws_ibrt_audio_sync_get_diff_us(); + + if (app_tws_ibrt_slave_ibrt_link_connected() && + app_ibrt_ui_is_profile_exchanged() && + (p_ibrt_ctrl->tws_mode == BTIF_BLM_ACTIVE_MODE)) + { + app_ui_rssi_battery_info_t rssi_battery_buffer; + rssi_battery_buffer.battery_volt = p_ibrt_ctrl->local_battery_volt; + rssi_battery_buffer.raw_rssi = p_ibrt_ctrl->raw_rssi; + rssi_battery_buffer.mobile_conhandle = p_ibrt_ctrl->ibrt_conhandle; + rssi_battery_buffer.tws_conhandle = p_ibrt_ctrl->tws_conhandle; + rssi_battery_buffer.mobile_diff_us = p_diff_us->mobile_diff_us; + rssi_battery_buffer.tws_diff_us = p_diff_us->tws_diff_us; + rssi_battery_buffer.cur_buf_size = a2dp_audio_get_current_buf_size(); + + tws_ctrl_send_rsp(APP_TWS_CMD_GET_PEER_MOBILE_RSSI, \ + rsp_seq, \ + (uint8_t *)&rssi_battery_buffer, \ + sizeof(app_ui_rssi_battery_info_t)); + } +} + +/***************************************************************************** + Prototype : app_ibrt_get_peer_mobile_rssi_rsp_handler + Description : + Input : uint8_t *p_buff + uint16_t length + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/6/4 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +static void app_ibrt_print_rssi_info(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TRACE(0, "RSSI local mobile : local tws <> peer mobile : peer tws"); + TRACE(19,"RSSI %d %d %d %d : %d %d %d %d %d/100 <> %d %d %d %d : %d %d %d %d %d/100 %d", + p_ibrt_ctrl->raw_rssi.agc_idx0, + p_ibrt_ctrl->raw_rssi.rssi0, + p_ibrt_ctrl->raw_rssi.rssi0_max, + p_ibrt_ctrl->raw_rssi.rssi0_min, + p_ibrt_ctrl->raw_rssi.agc_idx1, + p_ibrt_ctrl->raw_rssi.rssi1, + p_ibrt_ctrl->raw_rssi.rssi1_max, + p_ibrt_ctrl->raw_rssi.rssi1_min, + p_ibrt_ctrl->raw_rssi.ser, + p_ibrt_ctrl->peer_raw_rssi.agc_idx0, + p_ibrt_ctrl->peer_raw_rssi.rssi0, + p_ibrt_ctrl->peer_raw_rssi.rssi0_max, + p_ibrt_ctrl->peer_raw_rssi.rssi0_min, + p_ibrt_ctrl->peer_raw_rssi.agc_idx1, + p_ibrt_ctrl->peer_raw_rssi.rssi1, + p_ibrt_ctrl->peer_raw_rssi.rssi1_max, + p_ibrt_ctrl->peer_raw_rssi.rssi1_min, + p_ibrt_ctrl->peer_raw_rssi.ser, + p_ibrt_ctrl->current_role); +} + +void app_ibrt_get_peer_mobile_rssi_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (app_tws_ibrt_mobile_link_connected() && + app_ibrt_ui_is_profile_exchanged() && + (p_ibrt_ctrl->tws_mode == BTIF_BLM_ACTIVE_MODE)) + { + if(p_ibrt_ctrl->role_switch_debonce_time == 0) + { + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + app_ui_rssi_battery_info_t rssi_battery_info = *(app_ui_rssi_battery_info_t *)p_buff; + p_ibrt_ctrl->peer_mobile_conhandle = rssi_battery_info.mobile_conhandle; + p_ibrt_ctrl->peer_tws_conhandle = rssi_battery_info.tws_conhandle; + p_ibrt_ctrl->peer_battery_volt = rssi_battery_info.battery_volt; + p_ibrt_ctrl->peer_raw_rssi = rssi_battery_info.raw_rssi; + p_ibrt_ctrl->mobile_diff_us = rssi_battery_info.mobile_diff_us; + p_ibrt_ctrl->tws_diff_us = rssi_battery_info.tws_diff_us; + p_ibrt_ctrl->cur_buf_size = rssi_battery_info.cur_buf_size; + + app_ibrt_print_rssi_info(); + + if(p_ibrt_ui->config.tws_switch_according_to_rssi_value) + { + bool need_roleswitch_with_rssi = app_ibrt_ui_tws_switch_according_rssi_needed(); + + if(need_roleswitch_with_rssi != need_roleswitch_with_rssi_bak){ + if(need_roleswitch_with_rssi){ + TRACE(2,"ibrt_ui_log:one headset far away cause tws switch used rssi %d %d",p_ibrt_ctrl->raw_rssi.rssi0,p_ibrt_ctrl->peer_raw_rssi.rssi0); + app_ibrt_ui_tws_switch(); + p_ibrt_ctrl->role_switch_debonce_time = p_ibrt_ui->config.role_switch_timer_threshold; + } + need_roleswitch_with_rssi_bak = need_roleswitch_with_rssi; + } + } + } + else + { + p_ibrt_ctrl->role_switch_debonce_time--; + } + } +} + +void app_ibrt_rssi_get_stutter(uint8_t * data,uint32_t * data_len) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + uint8_t temp; + + data[0] = p_ibrt_ctrl->raw_rssi.agc_idx0; + data[1] = p_ibrt_ctrl->raw_rssi.rssi0; + data[2] = p_ibrt_ctrl->raw_rssi.rssi0_max; + data[3] = p_ibrt_ctrl->raw_rssi.rssi0_min; + + data[4] = p_ibrt_ctrl->raw_rssi.agc_idx1; + data[5] = p_ibrt_ctrl->raw_rssi.rssi1; + data[6] = p_ibrt_ctrl->raw_rssi.rssi1_max; + data[7] = p_ibrt_ctrl->raw_rssi.rssi1_min; + data[8] = p_ibrt_ctrl->raw_rssi.ser; + + data[9] = p_ibrt_ctrl->peer_raw_rssi.agc_idx0; + data[10] = p_ibrt_ctrl->peer_raw_rssi.rssi0; + data[11] = p_ibrt_ctrl->peer_raw_rssi.rssi0_max; + data[12] = p_ibrt_ctrl->peer_raw_rssi.rssi0_min; + + data[13] = p_ibrt_ctrl->peer_raw_rssi.agc_idx1; + data[14] = p_ibrt_ctrl->peer_raw_rssi.rssi1; + data[15] = p_ibrt_ctrl->peer_raw_rssi.rssi1_max; + data[16] = p_ibrt_ctrl->peer_raw_rssi.rssi1_min; + data[17] = p_ibrt_ctrl->peer_raw_rssi.ser; + + g_stutter.sample_ref = a2dp_audio_get_sample_reference(); + g_stutter.cur_buf_size_l = a2dp_audio_get_current_buf_size(); + + TRACE(2,"diff us: mobile:%d,tws:%d.", p_ibrt_ctrl->mobile_diff_us, p_ibrt_ctrl->tws_diff_us); + + TRACE(19,"%d %d %d %d : %d %d %d %d %d/100 <> %d %d %d %d : %d %d %d %d %d/100 %d", + p_ibrt_ctrl->raw_rssi.agc_idx0, + p_ibrt_ctrl->raw_rssi.rssi0, + p_ibrt_ctrl->raw_rssi.rssi0_max, + p_ibrt_ctrl->raw_rssi.rssi0_min, + p_ibrt_ctrl->raw_rssi.agc_idx1, + p_ibrt_ctrl->raw_rssi.rssi1, + p_ibrt_ctrl->raw_rssi.rssi1_max, + p_ibrt_ctrl->raw_rssi.rssi1_min, + p_ibrt_ctrl->raw_rssi.ser, + p_ibrt_ctrl->peer_raw_rssi.agc_idx0, + p_ibrt_ctrl->peer_raw_rssi.rssi0, + p_ibrt_ctrl->peer_raw_rssi.rssi0_max, + p_ibrt_ctrl->peer_raw_rssi.rssi0_min, + p_ibrt_ctrl->peer_raw_rssi.agc_idx1, + p_ibrt_ctrl->peer_raw_rssi.rssi1, + p_ibrt_ctrl->peer_raw_rssi.rssi1_max, + p_ibrt_ctrl->peer_raw_rssi.rssi1_min, + p_ibrt_ctrl->peer_raw_rssi.ser, + p_ibrt_ctrl->current_role); + + if (p_ibrt_ctrl->current_role == IBRT_SLAVE) + { + for (int i = 0; i < 9; i++) + { + temp = data[i + 9]; + data[i + 9] = data[i]; + data[i] = temp; + } + } + data[18] = p_ibrt_ctrl->current_role; + + data[19] = bt_drv_reg_op_fa_gain_direct_get(); + data[20] = g_stutter.cur_buf_size_l; //L buffer size + data[21] = p_ibrt_ctrl->cur_buf_size; //R buffer size + //sample_reference + data[22] = *((int8_t *)&g_stutter.sample_ref); + data[23] = *((int8_t *)&g_stutter.sample_ref + 1); + data[24] = *((int8_t *)&g_stutter.sample_ref + 2); + data[25] = *((int8_t *)&g_stutter.sample_ref + 3); + //mobile diff / us + data[26] = *((int8_t *)&p_ibrt_ctrl->mobile_diff_us); + data[27] = *((int8_t *)&p_ibrt_ctrl->mobile_diff_us + 1); + data[28] = *((int8_t *)&p_ibrt_ctrl->mobile_diff_us + 2); + data[29] = *((int8_t *)&p_ibrt_ctrl->mobile_diff_us + 3); + //tws diff / us + data[30] = *((int8_t *)&p_ibrt_ctrl->tws_diff_us); + data[31] = *((int8_t *)&p_ibrt_ctrl->tws_diff_us + 1); + data[32] = *((int8_t *)&p_ibrt_ctrl->tws_diff_us + 2); + data[33] = *((int8_t *)&p_ibrt_ctrl->tws_diff_us + 3); + + //L error_sum + data[34] = *((int8_t *)&p_ibrt_ctrl->raw_rssi.ser); + data[35] = *((int8_t *)&p_ibrt_ctrl->raw_rssi.ser+1); + //L Total_sum + data[36] = *((int8_t *)&p_ibrt_ctrl->raw_rssi.rx_data_sum); + data[37] = *((int8_t *)&p_ibrt_ctrl->raw_rssi.rx_data_sum+1); + //R error_sum + data[38] = *((int8_t *)&p_ibrt_ctrl->peer_raw_rssi.ser); + data[39] = *((int8_t *)&p_ibrt_ctrl->peer_raw_rssi.ser+1); + //R Total_sum + data[40] = *((int8_t *)&p_ibrt_ctrl->peer_raw_rssi.rx_data_sum); + data[41] = *((int8_t *)&p_ibrt_ctrl->peer_raw_rssi.rx_data_sum+1); + + TRACE(1,"0x%08x", p_ibrt_ctrl->mobile_diff_us); + TRACE(1,"0x%08x", p_ibrt_ctrl->tws_diff_us); + TRACE(1,"0x%08x", p_ibrt_ctrl->raw_rssi.ser); + TRACE(1,"0x%08x", p_ibrt_ctrl->raw_rssi.rx_data_sum); + TRACE(1,"0x%08x", p_ibrt_ctrl->peer_raw_rssi.ser); + TRACE(1,"0x%08x", p_ibrt_ctrl->peer_raw_rssi.rx_data_sum); + + TRACE(23,"%d %d %d %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + data[19], + data[20], + data[21], + data[22], + data[23], + data[24], + data[25], + data[26], + data[27], + data[28], + data[29], + data[30], + data[31], + data[32], + data[33], + data[34], + data[35], + data[36], + data[37], + data[38], + data[39], + data[40], + data[41]); + *data_len = 42; +} + +void app_ibrt_debug_parse(uint8_t *data, uint32_t data_len) +{ + bool do_it = false; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + uint8_t *parse_p = data; + + TRACE(2,"%s len:%d", __func__, data_len); + DUMP8("%02x ",data, data_len); + + if (p_ibrt_ctrl->audio_chnl_sel == A2DP_AUDIO_CHANNEL_SELECT_LCHNL){ + if (*parse_p & 0x01){ + do_it = true; + } + } + if (p_ibrt_ctrl->audio_chnl_sel == A2DP_AUDIO_CHANNEL_SELECT_RCHNL){ + if (*parse_p & 0x02){ + do_it = true; + } + } + parse_p++; + if (do_it){ + uint8_t funcCode = *parse_p; + parse_p++; + switch (funcCode) + { + case 1: + if (app_tws_ibrt_mobile_link_connected()){ + bt_drv_reg_op_dgb_link_gain_ctrl_set(p_ibrt_ctrl->mobile_conhandle, 0, *parse_p, *parse_p == 0xff ? 0 : 1); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + bt_drv_reg_op_dgb_link_gain_ctrl_set(p_ibrt_ctrl->ibrt_conhandle, 0, *parse_p, *parse_p == 0xff ? 0 : 1); + } + break; + case 2: + bt_drv_reg_op_dgb_link_gain_ctrl_set(p_ibrt_ctrl->tws_conhandle, 0, *parse_p, *parse_p == 0xff ? 0 : 1); + break; + case 3: + bt_drv_reg_op_fa_gain_direct_set(*parse_p); + break; + case 4: + { + uint32_t data_format = 0; + data_format = be_to_host32(parse_p); + TRACE(1,"lowlayer_monitor len:%d", data_format); + if (app_tws_ibrt_mobile_link_connected()){ + btif_me_set_link_lowlayer_monitor(btif_me_get_remote_device_by_handle(p_ibrt_ctrl->mobile_conhandle), FLAG_START_DATA, REP_FORMAT_PACKET, data_format, 0); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + btif_me_set_link_lowlayer_monitor(btif_me_get_remote_device_by_handle(p_ibrt_ctrl->ibrt_conhandle), FLAG_START_DATA, REP_FORMAT_PACKET, data_format, 0); + } + } + break; + default: + TRACE(1,"wrong cmd 0x%x",funcCode); + break; + } + } +} +#endif + diff --git a/services/app_ibrt/src/app_ibrt_search_pair_ui.cpp b/services/app_ibrt/src/app_ibrt_search_pair_ui.cpp new file mode 100644 index 0000000..308d3af --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_search_pair_ui.cpp @@ -0,0 +1,770 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "app_tws_ibrt_trace.h" +#include "bluetooth.h" +#include "btapp.h" +#include "app_ibrt_ui.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_ctrl_thread.h" +#include "app_vendor_cmd_evt.h" +#include "cmsis_os.h" +#include "besbt.h" +#include "stdlib.h" +#include "app_bt.h" +#include "factory_section.h" +#include "app_ibrt_if.h" +#include "a2dp_decoder.h" +#include "app_battery.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "app_status_ind.h" +#include "app_ibrt_peripheral_manager.h" +#include "nvrecord_ble.h" + + +extern "C" { + +} +#ifdef IBRT_SEARCH_UI +static void app_tws_inquiry_timeout_handler(void const *param); +osTimerDef (APP_TWS_INQ, app_tws_inquiry_timeout_handler); +static osTimerId app_tws_timer = NULL; + +static void app_tws_delay_connect_handler(void const *param); +osTimerDef (APP_TWS_DELAY_CONNECT, app_tws_delay_connect_handler); +static osTimerId app_tws_delay_connect_timer = NULL; + + +static uint8_t tws_find_process=0; +static uint8_t tws_inquiry_count=0; +#define MAX_TWS_INQUIRY_TIMES 3 +#define IBRT_MAX_SEARCH_TIME 10 /* 12.8s */ + +uint8_t tws_inq_addr_used; +typedef struct +{ + uint8_t used; + bt_bdaddr_t bdaddr; +} TWS_INQ_ADDR_STRUCT; +TWS_INQ_ADDR_STRUCT tws_inq_addr[5]; + + +#define IBRT_SEARCH_DEBUG +#ifdef IBRT_SEARCH_DEBUG +#define TWSCON_DBLOG TRACE +#else +#define TWSCON_DBLOG(...) +#endif + + +uint8_t box_event=IBRT_NONE_EVENT; +static void app_box_handle_timehandler(void const *param); +osTimerDef (APP_BOX_HANDLE, app_box_handle_timehandler); +static osTimerId app_box_handle_timer = NULL; + +static void app_box_handle_timehandler(void const *param) +{ + uint8_t *box_event_ptr=(uint8_t *)param; + uint8_t boxStatus=*box_event_ptr; + TRACE(1,"box event:%d",boxStatus); + app_ibrt_search_ui_init(true,boxStatus); + app_ibrt_if_event_entry(boxStatus); + if(IBRT_IN_BOX_CLOSED==boxStatus) + app_ibrt_search_ui_init(true,boxStatus); + +} + +static void app_tws_inquiry_timeout_handler(void const *param) +{ + + TWSCON_DBLOG(0,"app_tws_inquiry_timeout_handler\n"); + btif_me_inquiry(BTIF_BT_IAC_LIAC, IBRT_MAX_SEARCH_TIME, 0); + +} + +static void app_tws_delay_connect_handler(void const *parma) +{ + TWSCON_DBLOG(1,"%s",__func__); + app_ibrt_if_enter_pairing_after_tws_connected(); + +} + +bool app_tws_is_addr_in_tws_inq_array(const bt_bdaddr_t* addr) +{ + uint8_t i; + for(i=0; iaddress,BTIF_BD_ADDR_SIZE)) + return true; + } + } + return false; +} +void app_tws_clear_tws_inq_array(void) +{ + memset(&tws_inq_addr,0,sizeof(tws_inq_addr)); +} + +int app_tws_fill_addr_to_array(const bt_bdaddr_t*addr) +{ + uint8_t i; + for(i=0; iaddress,BTIF_BD_ADDR_SIZE); + return 0; + } + } + + return -1; +} + +uint8_t app_tws_get_tws_addr_inq_num(void) +{ + uint8_t i,count=0; + for(i=0; inv_role ==IBRT_UNKNOW) + p_ibrt_ctrl->nv_role = ibrtRole; + if(NULL!=ibrtPeerAddr) + { + memcpy(p_ibrt_ctrl->peer_addr.address,ibrtPeerAddr->address, BD_ADDR_LEN); + nv_record_update_ibrt_info(p_ibrt_ctrl->nv_role,ibrtPeerAddr); + } +} + +void tws_app_stop_find(void) +{ + tws_find_process=0; + btif_me_unregister_globa_handler((btif_handler *)btif_me_get_bt_handler()); +} + +void app_bt_manager_ibrt_role_process(const btif_event_t *Event) +{ + switch (btif_me_get_callback_event_type(Event)) + { + case BTIF_BTEVENT_LINK_CONNECT_IND: + case BTIF_BTEVENT_LINK_CONNECT_CNF: + if (BTIF_BEC_NO_ERROR == btif_me_get_callback_event_err_code(Event)) + { + bt_bdaddr_t *p_remote_dev_addr=NULL; + ibrt_ctrl_t *p_ibrt_ctrl=NULL; + p_remote_dev_addr = btif_me_get_callback_event_rem_dev_bd_addr(Event); + p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if(p_ibrt_ctrl->nv_role ==IBRT_UNKNOW) + factory_section_original_btaddr_get(p_ibrt_ctrl->local_addr.address); + + TRACE(2,"local:%x remd:%x",p_ibrt_ctrl->local_addr.address[5],p_remote_dev_addr->address[5]); + if((p_ibrt_ctrl->local_addr.address[3]==p_remote_dev_addr->address[3]) + &&(p_ibrt_ctrl->local_addr.address[4]==p_remote_dev_addr->address[4]) + &&(p_ibrt_ctrl->local_addr.address[5]==p_remote_dev_addr->address[5])) + { + app_tws_ibrt_update_info(IBRT_SLAVE,p_remote_dev_addr); + if(app_ibrt_ui_get_tws_use_same_addr_enable()) + { + memcpy(p_ibrt_ctrl->local_addr.address,p_remote_dev_addr->address,6); + } + +#if 0 + p_ibrt_ctrl->audio_chnl_sel = A2DP_AUDIO_CHANNEL_SELECT_LRMERGE; +#else + if(IBRT_MASTER == p_ibrt_ctrl->nv_role) + { + TRACE(0,"#right"); + p_ibrt_ctrl->audio_chnl_sel = A2DP_AUDIO_CHANNEL_SELECT_RCHNL; + } + else if(IBRT_SLAVE == p_ibrt_ctrl->nv_role) + { + TRACE(0,"#left"); + p_ibrt_ctrl->audio_chnl_sel = A2DP_AUDIO_CHANNEL_SELECT_LCHNL; + + } +#endif + } + + } + break; + default: + break; + } + +} + +void app_ibrt_config_the_same_bd_addr(bt_bdaddr_t *ibrtSearchedAddr) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + app_tws_ibrt_set_access_mode(BTIF_BAM_NOT_ACCESSIBLE); + + memcpy(p_ibrt_ctrl->local_addr.address, ibrtSearchedAddr->address, BD_ADDR_LEN); + memcpy(p_ibrt_ctrl->peer_addr.address, ibrtSearchedAddr->address, BD_ADDR_LEN); + btif_me_set_bt_address(ibrtSearchedAddr->address); + +#ifdef __GMA_VOICE__ + btif_me_set_ble_bd_address(ibrtSearchedAddr->address); + bt_set_ble_local_address(ibrtSearchedAddr->address); + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + memcpy(pNvExtRec->tws_info.ble_info.ble_addr, ibrtSearchedAddr->address, BLE_IRK_SIZE); + nv_record_tws_exchange_ble_info(); +#endif + TRACE(1,"%s", __func__); + DUMP8("%02x ", p_ibrt_ctrl->local_addr.address, BD_ADDR_LEN); + + //after change the bd_addr, we should reset access mode again + app_tws_ibrt_set_access_mode(BTIF_BAM_CONNECTABLE_ONLY); +} + +void app_ibrt_reconfig_btAddr_from_nv() +{ + struct nvrecord_env_t *nvrecord_env; + if(nv_record_env_get(&nvrecord_env)!=-1) + { + if(nvrecord_env->ibrt_mode.mode !=IBRT_UNKNOW) + { + TRACE(0,"reconfig addr from nv"); + DUMP8("%02x ",nvrecord_env->ibrt_mode.record.bdAddr.address, 6); + bt_set_local_address(nvrecord_env->ibrt_mode.record.bdAddr.address); + + bt_set_ble_local_address(nvrecord_env->ibrt_mode.record.bdAddr.address); + + } + + } + +} +void app_bt_inquiry_call_back(const btif_event_t* event) +{ + TWSCON_DBLOG(2,"\nenter: %s %d\n",__func__,__LINE__); + uint8_t device_name[64]; + uint8_t device_name_len; + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + factory_section_original_btaddr_get(p_ibrt_ctrl->local_addr.address); + + + switch(btif_me_get_callback_event_type(event)) + { + case BTIF_BTEVENT_NAME_RESULT: + TWSCON_DBLOG(2,"\n%s %d BTEVENT_NAME_RESULT\n",__func__,__LINE__); + break; + case BTIF_BTEVENT_INQUIRY_RESULT: + TWSCON_DBLOG(2,"\n%s %d BTEVENT_INQUIRY_RESULT\n",__func__,__LINE__); + DUMP8("%02x ", btif_me_get_callback_event_inq_result_bd_addr_addr(event), 6); + TWSCON_DBLOG(1,"inqmode = %x",btif_me_get_callback_event_inq_result_inq_mode(event)); + DUMP8("%02x ", btif_me_get_callback_event_inq_result_ext_inq_resp(event), 20); + ///check the uap and nap if equal ,get the name for tws slave + TRACE(1,"##RSSI:%d",(int8_t)btif_me_get_callback_event_rssi(event)); + TRACE(6,"local %02x %02x %02x %02x %02x %02x\n", + p_ibrt_ctrl->local_addr.address[0], + p_ibrt_ctrl->local_addr.address[1], + p_ibrt_ctrl->local_addr.address[2], + p_ibrt_ctrl->local_addr.address[3], + p_ibrt_ctrl->local_addr.address[4], + p_ibrt_ctrl->local_addr.address[5]); + if((btif_me_get_callback_event_inq_result_bd_addr(event)->address[5]== p_ibrt_ctrl->local_addr.address[5]) + && (btif_me_get_callback_event_inq_result_bd_addr(event)->address[4]== p_ibrt_ctrl->local_addr.address[4]) + && (btif_me_get_callback_event_inq_result_bd_addr(event)->address[3]== p_ibrt_ctrl->local_addr.address[3])) + { + ///check the device is already checked + TWSCON_DBLOG(0,"<1>"); + if(app_tws_is_addr_in_tws_inq_array(btif_me_get_callback_event_inq_result_bd_addr(event))) + { + break; + } + ////if rssi event is eir,so find name derictly + if(btif_me_get_callback_event_inq_result_inq_mode(event) == BTIF_INQ_MODE_EXTENDED) + { + + TWSCON_DBLOG(0,"<2>"); + uint8_t *eir = (uint8_t *)btif_me_get_callback_event_inq_result_ext_inq_resp(event); + //device_name_len = ME_GetExtInqData(eir,0x09,device_name,sizeof(device_name)); + device_name_len = btif_me_get_ext_inq_data(eir,0x09,device_name,sizeof(device_name)); + if(device_name_len>0) + { + TWSCON_DBLOG(3,"<3> search name len %d %s local name %s\n", device_name_len, device_name, bt_get_local_name()); + ////if name is the same as the local name so we think the device is the tws slave + if(!memcmp(device_name,bt_get_local_name(),device_name_len)) + { + TWSCON_DBLOG(0,"<4>"); + + //modify local addr + app_ibrt_config_the_same_bd_addr(btif_me_get_callback_event_inq_result_bd_addr(event)); + btif_me_cancel_inquiry(); + osTimerStop(app_tws_timer); + tws_app_stop_find(); + app_tws_ibrt_update_info(IBRT_MASTER,btif_me_get_callback_event_inq_result_bd_addr(event)); + p_ibrt_ctrl->audio_chnl_sel = A2DP_AUDIO_CHANNEL_SELECT_LRMERGE; + if(NULL !=app_tws_delay_connect_timer) + { + osTimerStop(app_tws_delay_connect_timer); + osTimerStart(app_tws_delay_connect_timer, 500); + } + + } + else + { + if(app_tws_get_tws_addr_inq_num()=MAX_TWS_INQUIRY_TIMES) + { + tws_app_stop_find(); + return; + } + if(p_ibrt_ui->super_state ==IBRT_UI_IDLE) + { + ////inquiry complete if bt don't find any slave ,so do inquiry again + + uint8_t rand_delay = rand() % 5; + tws_inquiry_count++; + + if(rand_delay == 0) + { + //btif_me_inquiry(BTIF_BT_IAC_GIAC, IBRT_MAX_SEARCH_TIME, 0); + btif_me_inquiry(BTIF_BT_IAC_LIAC, IBRT_MAX_SEARCH_TIME, 0); + } + else + { + osTimerStart(app_tws_timer, rand_delay*1000); + } + } + break; + /** The Inquiry process is canceled. */ + case BTIF_BTEVENT_INQUIRY_CANCELED: + TWSCON_DBLOG(2,"\n%s %d BTEVENT_INQUIRY_CANCELED\n",__FUNCTION__,__LINE__); + // tws.notify(&tws); + break; + case BTIF_BTEVENT_LINK_CONNECT_CNF: + TWSCON_DBLOG(3,"\n%s %d BTEVENT_LINK_CONNECT_CNF stats=%x\n",__FUNCTION__,__LINE__,btif_me_get_callback_event_err_code(event)); + + //connect fail start inquiry again + if(btif_me_get_callback_event_err_code(event) ==4 && tws_find_process == 1) + { + if(tws_inquiry_count>=MAX_TWS_INQUIRY_TIMES) + { + tws_app_stop_find(); + return; + } + uint8_t rand_delay = rand() % 5; + tws_inquiry_count++; + if(rand_delay == 0) + { + //btif_me_inquiry(BTIF_BT_IAC_GIAC, IBRT_MAX_SEARCH_TIME, 0); + btif_me_inquiry(BTIF_BT_IAC_LIAC, IBRT_MAX_SEARCH_TIME, 0); + } + else + { + osTimerStart(app_tws_timer, rand_delay*1000); + } + } + ///connect succ,so stop the finding tws procedure + else if(btif_me_get_callback_event_err_code(event) ==0) + { + tws_app_stop_find(); + } + break; + case BTIF_BTEVENT_LINK_CONNECT_IND: + TWSCON_DBLOG(3,"\n%s %d BTEVENT_LINK_CONNECT_IND stats=%x\n",__FUNCTION__,__LINE__,btif_me_get_callback_event_err_code(event)); + ////there is a incoming connect so cancel the inquiry and the timer and the connect creating + btif_me_cancel_inquiry(); + osTimerStop(app_tws_timer); + break; + default: + //TWS_DBLOG("\n%s %d etype:%d\n",__FUNCTION__,__LINE__,event->eType); + break; + + + } + + //TWS_DBLOG("\nexit: %s %d\n",__FUNCTION__,__LINE__); + +} + + + +uint8_t is_find_tws_peer_device_onprocess(void) +{ + return tws_find_process; +} + +void find_tws_peer_device_start(void) +{ + TWSCON_DBLOG(2,"\nibrt_ui_log: %s %d\n",__func__,__LINE__); + bt_status_t status; + app_tws_clear_tws_inq_array(); + if(tws_find_process ==0) + { + tws_find_process = 1; + tws_inquiry_count = 0; + if (app_tws_timer == NULL) + app_tws_timer = osTimerCreate(osTimer(APP_TWS_INQ), osTimerOnce, NULL); + btif_me_set_handler(btif_me_get_bt_handler(),app_bt_inquiry_call_back); + btif_me_register_global_handler(btif_me_get_bt_handler()); + + btif_me_set_event_mask(btif_me_get_bt_handler(), BTIF_BEM_LINK_DISCONNECT|BTIF_BEM_ROLE_CHANGE|BTIF_BEM_INQUIRY_RESULT| + BTIF_BEM_INQUIRY_COMPLETE|BTIF_BEM_INQUIRY_CANCELED|BTIF_BEM_LINK_CONNECT_CNF|BTIF_BEM_LINK_CONNECT_IND); + + again: + TWSCON_DBLOG(2,"\n%s %d\n",__func__,__LINE__); + + status = btif_me_inquiry(BTIF_BT_IAC_LIAC, IBRT_MAX_SEARCH_TIME, 0); + TWSCON_DBLOG(2,"\n%s %d\n",__func__,__LINE__); + if (status != BT_STS_PENDING) + { + osDelay(500); + goto again; + } + TWSCON_DBLOG(2,"\n%s %d\n",__func__,__LINE__); + } +} + + +void find_tws_peer_device_stop(void) +{ + btif_me_cancel_inquiry(); + tws_app_stop_find(); +} + +void app_start_tws_serching_direactly() +{ + btif_accessible_mode_t mode; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + mode = p_ibrt_ctrl->access_mode; + TWSCON_DBLOG(1,"ibrt_ui_log:search tws direactly access_mode:%d",mode); + //if ((BTIF_DEFAULT_ACCESS_MODE_PAIR==mode)||(BTIF_BAM_LIMITED_ACCESSIBLE==mode)) + if(BTIF_BAM_LIMITED_ACCESSIBLE==mode) + { + if(NULL==app_tws_delay_connect_timer) + app_tws_delay_connect_timer=osTimerCreate(osTimer(APP_TWS_DELAY_CONNECT),osTimerOnce,NULL ); + if (is_find_tws_peer_device_onprocess()) + { + find_tws_peer_device_stop(); + } + else + { + p_ibrt_ctrl->nv_role=IBRT_UNKNOW; + find_tws_peer_device_start(); + + //app_status_indication_set(APP_STATUS_INDICATION_CONNECTING); + } + } +} + + +static void app_ibrt_battery_handle_process_normal(uint32_t status, union APP_BATTERY_MSG_PRAMS prams) +{ + app_ibrt_ui_t *p_ui_ctrl = app_ibrt_ui_get_ctx(); + + + switch (status) + { + case APP_BATTERY_STATUS_CHARGING: + + TWSCON_DBLOG(1,"charger:%d",prams.charger); + if (prams.charger == APP_BATTERY_CHARGER_PLUGIN) + { + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TWSCON_DBLOG(1,"APP_BATTERY_CHARGER_PLUGIN nv_role %02x", p_ibrt_ctrl->nv_role); + /*if (p_ibrt_ctrl->nv_role == IBRT_UNKNOW) + { + return; + }*/ + if(p_ui_ctrl->config.check_plugin_excute_closedbox_event==true) + box_event=IBRT_CLOSE_BOX_EVENT; + else + box_event=IBRT_PUT_IN_EVENT; + + if(app_box_handle_timer!=NULL) + { + osTimerStop(app_box_handle_timer); + osTimerStart(app_box_handle_timer,500); + } + + } + else if (prams.charger == APP_BATTERY_CHARGER_PLUGOUT) + { + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TWSCON_DBLOG(1,"APP_BATTERY_CHARGER_PLUGOUT nv_role %02x", p_ibrt_ctrl->nv_role); + if (p_ibrt_ctrl->nv_role == IBRT_UNKNOW) + { + return; + } + box_event=IBRT_FETCH_OUT_EVENT; + + if(app_box_handle_timer!=NULL) + { + osTimerStop(app_box_handle_timer); + osTimerStart(app_box_handle_timer,500); + } + } + break; + case APP_BATTERY_STATUS_INVALID: + default: + break; + + } + + +} + + +void app_ibrt_battery_callback(APP_BATTERY_MV_T currvolt, uint8_t currlevel,enum APP_BATTERY_STATUS_T curstatus,uint32_t status, union APP_BATTERY_MSG_PRAMS prams) +{ + switch (curstatus) + { + case APP_BATTERY_STATUS_NORMAL: + case APP_BATTERY_STATUS_CHARGING: + app_ibrt_battery_handle_process_normal(status,prams); + break; + + default: + break; + } + + +} + +#ifdef BOX_DET_USE_GPIO +#define BOX_DET_PIN HAL_IOMUX_PIN_P1_0 + +static void box_det_pin_irq_set(enum HAL_GPIO_IRQ_POLARITY_T polarity); + +static void box_det_pin_irq_update(void) +{ + if (hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)BOX_DET_PIN)) + box_det_pin_irq_set(HAL_GPIO_IRQ_POLARITY_LOW_FALLING); + else + box_det_pin_irq_set(HAL_GPIO_IRQ_POLARITY_HIGH_RISING); +} + +static void box_det_handler(uint32_t val) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TRACE(2,"%s: %d", __func__, p_ibrt_ctrl->nv_role); + box_det_pin_irq_update(); + if (val) + { + box_event = IBRT_FETCH_OUT_EVENT; + } + else + { + box_event=IBRT_CLOSE_BOX_EVENT; + } + + if (p_ibrt_ctrl->nv_role == IBRT_UNKNOW) + return; + + if (app_box_handle_timer) + { + osTimerStop(app_box_handle_timer); + osTimerStart(app_box_handle_timer,500); + } +} + +static void box_det_irq_handler(enum HAL_GPIO_PIN_T pin) +{ + uint8_t val = hal_gpio_pin_get_val(pin); + TRACE(3,"%s: %d, %d", __func__, pin, val); + app_ibrt_peripheral_run1((uint32_t)box_det_handler, (uint32_t)val); +} + +static void box_det_pin_irq_set(enum HAL_GPIO_IRQ_POLARITY_T polarity) +{ + struct HAL_GPIO_IRQ_CFG_T box_det_pin_cfg; + box_det_pin_cfg.irq_debounce = true; + box_det_pin_cfg.irq_handler = box_det_irq_handler; + box_det_pin_cfg.irq_type = HAL_GPIO_IRQ_TYPE_EDGE_SENSITIVE; + + box_det_pin_cfg.irq_enable = true; + box_det_pin_cfg.irq_polarity = polarity; + hal_gpio_setup_irq((enum HAL_GPIO_PIN_T)BOX_DET_PIN, &box_det_pin_cfg); +} + +static void box_det_pin_init(void) +{ + const struct HAL_IOMUX_PIN_FUNCTION_MAP box_det_gpio_cfg = + { + BOX_DET_PIN, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE + }; + + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&box_det_gpio_cfg, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)box_det_gpio_cfg.pin, HAL_GPIO_DIR_IN, 1); + + box_det_pin_irq_update(); +} +#endif + +void app_ibrt_search_ui_init(bool boxOperation,ibrt_event_type evt_type) +{ + app_ibrt_ui_t *p_ui_ctrl = app_ibrt_ui_get_ctx(); + if((true==p_ui_ctrl->config.check_plugin_excute_closedbox_event) || + (false==boxOperation)) + p_ui_ctrl->box_state = IBRT_IN_BOX_OPEN; + + if(false==boxOperation) + { +#ifdef BOX_DET_USE_GPIO + box_det_pin_init(); +#else + app_battery_register(app_ibrt_battery_callback); +#endif + + if (app_box_handle_timer == NULL) + app_box_handle_timer = osTimerCreate(osTimer(APP_BOX_HANDLE), osTimerOnce, &box_event); + } + else if(evt_type !=IBRT_IN_BOX_CLOSED) + { + app_ibrt_ui_judge_scan_type(IBRT_OPEN_BOX_TRIGGER,NO_LINK_TYPE,IBRT_UI_NO_ERROR); + } + +} + + + + +void app_ibrt_remove_history_paired_device(void) +{ + bt_status_t retStatus; + btif_device_record_t record; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + int paired_dev_count = nv_record_get_paired_dev_count(); + + TWSCON_DBLOG(0,"Remove all history tws nv records."); + TWSCON_DBLOG(0,"Master addr:"); + DUMP8("%02x ",p_ibrt_ctrl->local_addr.address, BTIF_BD_ADDR_SIZE); + TWSCON_DBLOG(0,"Slave addr:"); + DUMP8("%02x ",p_ibrt_ctrl->peer_addr.address, BTIF_BD_ADDR_SIZE); + + for (int32_t index = paired_dev_count - 1; index >= 0; index--) + { + retStatus = nv_record_enum_dev_records(index, &record); + if (BT_STS_SUCCESS == retStatus) + { + TWSCON_DBLOG(1,"The index %d of nv records:", index); + DUMP8("%02x ", record.bdAddr.address, BTIF_BD_ADDR_SIZE); + if (!memcmp(record.bdAddr.address, p_ibrt_ctrl->local_addr.address, BTIF_BD_ADDR_SIZE) || + !memcmp(record.bdAddr.address, p_ibrt_ctrl->peer_addr.address, BTIF_BD_ADDR_SIZE)) + { + nv_record_ddbrec_delete(&record.bdAddr); + TWSCON_DBLOG(1,"Delete the nv record entry %d", index); + } + } + } + + memset(p_ibrt_ctrl->local_addr.address, 0, BTIF_BD_ADDR_SIZE); + memset(p_ibrt_ctrl->peer_addr.address, 0, BTIF_BD_ADDR_SIZE); +} + + +void app_bt_enter_mono_pairing_mode(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + + p_ibrt_ui->box_state = IBRT_OUT_BOX; + + TRACE(0,"ibrt_ui_log:app_bt_enter_mono_pairing_mode"); + + if(!app_device_bt_is_connected()) + { + if(p_ibrt_ctrl->nv_role == IBRT_UNKNOW) + { + app_ibrt_ui_judge_scan_type(IBRT_FREEMAN_PAIR_TRIGGER,NO_LINK_TYPE, IBRT_UI_NO_ERROR); + app_ibrt_ui_set_freeman_enable(); + } + else + { + //app_tws_ibrt_set_access_mode(BTIF_BAM_GENERAL_ACCESSIBLE); + app_ibrt_ui_set_enter_pairing_mode(IBRT_CONNECT_MOBILE_FAILED); + app_ibrt_ui_judge_scan_type(IBRT_CONNECTE_TRIGGER,MOBILE_LINK, 0); + } + } + +} +void app_ibrt_enter_limited_mode(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + + p_ibrt_ctrl->nv_role=IBRT_UNKNOW; + p_ibrt_ui->box_state = IBRT_OUT_BOX; + + app_ibrt_remove_history_paired_device(); + TRACE(0,"ibrt_ui_log:power on enter pairing"); + app_ibrt_ui_judge_scan_type(IBRT_SEARCH_SLAVE_TRIGGER,NO_LINK_TYPE,IBRT_UI_NO_ERROR); + +} + +#endif + + diff --git a/services/app_ibrt/src/app_ibrt_ui_test.cpp b/services/app_ibrt/src/app_ibrt_ui_test.cpp new file mode 100644 index 0000000..e3e759e --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_ui_test.cpp @@ -0,0 +1,868 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "app_tws_ibrt_trace.h" +#include "factory_section.h" +#include "apps.h" +#include "app_battery.h" +#include "app_anc.h" +#include "app_key.h" +#include "app_ibrt_if.h" +#include "app_ibrt_ui_test.h" +#include "app_ibrt_auto_test.h" +#include "app_ibrt_ui_test_cmd_if.h" +#include "app_ibrt_peripheral_manager.h" +#include "a2dp_decoder.h" +#include "app_ibrt_keyboard.h" +#include "nvrecord_env.h" +#include "nvrecord_ble.h" +#include "app_tws_if.h" +#include "besbt.h" +#include "app_bt.h" +#include "app_ai_if.h" +#include "app_ai_manager_api.h" +#include "nvrecord_extension.h" +#include "app_key.h" +#include "app_ble_mode_switch.h" +#include "app.h" +#include "norflash_api.h" +#include "btapp.h" +#if defined(BISTO_ENABLED) +#include "gsound_custom_actions.h" +#include "gsound_custom_ble.h" +#include "gsound_custom_bt.h" +#endif + +#ifdef __AI_VOICE__ +#include "ai_spp.h" +#include "ai_thread.h" +#include "app_ai_ble.h" +#endif + +#ifdef IBRT_OTA +#include "ota_control.h" +#endif + +void app_voice_assistant_key(APP_KEY_STATUS *status, void *param); +extern void app_bt_volumedown(); +extern void app_bt_volumeup(); +#ifdef IBRT_OTA +extern uint8_t ota_role_switch_flag; +extern uint8_t avoid_even_packets_protect_flag; +#endif +#if defined(IBRT) +#include "btapp.h" +extern struct BT_DEVICE_T app_bt_device; + +bt_bdaddr_t master_ble_addr = {0x76, 0x33, 0x33, 0x22, 0x11, 0x11}; +bt_bdaddr_t slave_ble_addr = {0x77, 0x33, 0x33, 0x22, 0x11, 0x11}; +bt_bdaddr_t box_ble_addr = {0x78, 0x33, 0x33, 0x22, 0x11, 0x11}; + +#ifdef IBRT_SEARCH_UI +void app_ibrt_battery_callback(APP_BATTERY_MV_T currvolt, uint8_t currlevel,enum APP_BATTERY_STATUS_T curstatus,uint32_t status, union APP_BATTERY_MSG_PRAMS prams); +void app_ibrt_simulate_charger_plug_in_test(void) +{ + union APP_BATTERY_MSG_PRAMS msg_prams; + msg_prams.charger = APP_BATTERY_CHARGER_PLUGIN; + app_ibrt_battery_callback(0, 0, APP_BATTERY_STATUS_CHARGING, 1, msg_prams); +} +void app_ibrt_simulate_charger_plug_out_test(void) +{ + union APP_BATTERY_MSG_PRAMS msg_prams; + msg_prams.charger = APP_BATTERY_CHARGER_PLUGOUT; + app_ibrt_battery_callback(0, 0, APP_BATTERY_STATUS_CHARGING, 1, msg_prams); +} +void app_ibrt_simulate_charger_plug_box_test(void) +{ + static int count = 0; + if (count++ % 2 == 0) + { + app_ibrt_simulate_charger_plug_in_test(); + } + else + { + app_ibrt_simulate_charger_plug_out_test(); + } +} +extern void app_ibrt_sync_volume_info(); + +void app_ibrt_search_ui_gpio_key_handle(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s,event:%d,code:%d",__func__,status->event,status->code); + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (IBRT_SLAVE == p_ibrt_ctrl->current_role && status->event == APP_KEY_EVENT_DOUBLECLICK) + { + app_ibrt_if_keyboard_notify(status,param); + } + else + { + switch (status->event) + { + case APP_KEY_EVENT_CLICK: + /*if (status->code == APP_KEY_CODE_FN1) + { + app_ibrt_simulate_charger_plug_in_test(); + } + else if(status->code == APP_KEY_CODE_FN2) + { + app_ibrt_simulate_charger_plug_out_test(); + } + else + { + + }*/ + break; + case APP_KEY_EVENT_DOUBLECLICK: + if (status->code == APP_KEY_CODE_FN1) + { + app_bt_volumeup(); + if(IBRT_MASTER==p_ibrt_ctrl->current_role) + { + TRACE(0,"ibrt master sync volume up to slave !"); + app_ibrt_sync_volume_info(); + } + + } + else if(status->code == APP_KEY_CODE_FN2) + { + app_bt_volumedown(); + if(IBRT_MASTER==p_ibrt_ctrl->current_role) + { + TRACE(0,"ibrt master sync volume up to slave !"); + app_ibrt_sync_volume_info(); + } + } + else + { + + } + break; + case APP_KEY_EVENT_LONGPRESS: + if (status->code == APP_KEY_CODE_FN1) + { +#ifdef TPORTS_KEY_COEXIST + app_ibrt_simulate_charger_plug_out_test(); +#else + app_ibrt_ui_tws_switch(); +#endif + } + else if(status->code == APP_KEY_CODE_FN2) + { + + } + else + { + + } + break; + default: + break; + } + } +} +#endif + + + +const app_uart_handle_t app_ibrt_uart_test_handle[]= +{ + {"factoryreset_test",app_ibrt_nvrecord_rebuild}, + {"roleswitch_test",app_ibrt_role_switch_test}, + {"inquiry_start_test",app_ibrt_inquiry_start_test}, + {"open_box_event_test",app_ibrt_ui_open_box_event_test}, + {"fetch_out_box_event_test",app_ibrt_ui_fetch_out_box_event_test}, + {"put_in_box_event_test",app_ibrt_ui_put_in_box_event_test}, + {"close_box_event_test",app_ibrt_ui_close_box_event_test}, + {"reconnect_event_test",app_ibrt_ui_reconnect_event_test}, + {"wear_up_event_test",app_ibrt_ui_ware_up_event_test}, + {"wear_down_event_test",app_ibrt_ui_ware_down_event_test}, + {"shut_down_test",app_ibrt_ui_shut_down_test}, + {"phone_connect_event_test",app_ibrt_ui_phone_connect_event_test}, + {"switch_ibrt_test",app_ibrt_ui_tws_swtich_test}, + {"suspend_ibrt_test",app_ibrt_ui_suspend_ibrt_test}, + {"resume_ibrt_test",app_ibrt_ui_resume_ibrt_test}, + {"conn_second_mobile_test",app_ibrt_ui_choice_connect_second_mobile}, + {"mobile_tws_disc_test",app_ibrt_if_disconnect_mobile_tws_link}, + {"pairing_mode_test",app_ibrt_ui_pairing_mode_test}, + {"freeman_mode_test",app_ibrt_ui_freeman_pairing_mode_test}, + {"audio_play",app_ibrt_ui_audio_play_test}, + {"audio_pause",app_ibrt_ui_audio_pause_test}, + {"audio_forward",app_ibrt_ui_audio_forward_test}, + {"audio_backward",app_ibrt_ui_audio_backward_test}, + {"avrcp_volup",app_ibrt_ui_avrcp_volume_up_test}, + {"avrcp_voldn",app_ibrt_ui_avrcp_volume_down_test}, + {"hfsco_create",app_ibrt_ui_hfsco_create_test}, + {"hfsco_disc",app_ibrt_ui_hfsco_disc_test}, + {"call_redial",app_ibrt_ui_call_redial_test}, + {"call_answer",app_ibrt_ui_call_answer_test}, + {"call_hangup",app_ibrt_ui_call_hangup_test}, + {"volume_up",app_ibrt_ui_local_volume_up_test}, + {"volume_down",app_ibrt_ui_local_volume_down_test}, + {"get_a2dp_state",app_ibrt_ui_get_a2dp_state_test}, + {"get_avrcp_state",app_ibrt_ui_get_avrcp_state_test}, + {"get_hfp_state",app_ibrt_ui_get_hfp_state_test}, + {"get_call_status",app_ibrt_ui_get_call_status_test}, + {"get_ibrt_role",app_ibrt_ui_get_ibrt_role_test}, + {"get_tws_state",app_ibrt_ui_get_tws_conn_state_test}, + {"iic_switch", app_ibrt_ui_iic_uart_switch_test}, + {"soft_reset", app_ibrt_ui_soft_reset_test}, +#ifdef IBRT_SEARCH_UI + {"plug_in_test",app_ibrt_simulate_charger_plug_in_test}, + {"plug_out_test",app_ibrt_simulate_charger_plug_out_test}, + {"plug_box_test",app_ibrt_simulate_charger_plug_box_test}, +#endif +#ifdef IBRT_ENHANCED_STACK_PTS + {"hf_create_service_link",btif_pts_hf_create_link_with_pts}, + {"hf_disc_service_link",btif_pts_hf_disc_service_link}, + {"hf_create_audio_link",btif_pts_hf_create_audio_link}, + {"hf_disc_audio_link",btif_pts_hf_disc_audio_link}, + {"hf_answer_call",btif_pts_hf_answer_call}, + {"hf_hangup_call",btif_pts_hf_hangup_call}, + {"rfc_register",btif_pts_rfc_register_channel}, + {"rfc_close",btif_pts_rfc_close}, + {"av_create_channel",btif_pts_av_create_channel_with_pts}, + {"av_disc_channel",btif_pts_av_disc_channel}, + {"ar_connect",btif_pts_ar_connect_with_pts}, + {"ar_disconnect",btif_pts_ar_disconnect}, + {"ar_panel_play",btif_pts_ar_panel_play}, + {"ar_panel_pause",btif_pts_ar_panel_pause}, + {"ar_panel_stop",btif_pts_ar_panel_stop}, + {"ar_panel_forward",btif_pts_ar_panel_forward}, + {"ar_panel_backward",btif_pts_ar_panel_backward}, + {"ar_volume_up",btif_pts_ar_volume_up}, + {"ar_volume_down",btif_pts_ar_volume_down}, + {"ar_volume_notify",btif_pts_ar_volume_notify}, + {"ar_volume_change",btif_pts_ar_volume_change}, + {"ar_set_absolute_volume",btif_pts_ar_set_absolute_volume}, +#endif +}; + + +/***************************************************************************** + Prototype : app_ibrt_ui_find_uart_handle + Description : find the test cmd handle + Input : uint8_t* buf + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/3/30 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +app_uart_test_function_handle app_ibrt_ui_find_uart_handle(unsigned char* buf) +{ + app_uart_test_function_handle p = NULL; + for(uint8_t i = 0; icode, status->event); + TWS_PD_MSG_BLOCK msg; + msg.msg_body.message_id = 0; + msg.msg_body.message_ptr = (uint32_t)NULL; + app_ibrt_peripheral_mailbox_put(&msg); +} + +void app_ibrt_key2(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + TWS_PD_MSG_BLOCK msg; + msg.msg_body.message_id = 1; + msg.msg_body.message_ptr = (uint32_t)NULL; + app_ibrt_peripheral_mailbox_put(&msg); +} + +void app_ibrt_key3(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + TWS_PD_MSG_BLOCK msg; + msg.msg_body.message_id = 2; + msg.msg_body.message_ptr = (uint32_t)NULL; + app_ibrt_peripheral_mailbox_put(&msg); +} + +void app_ibrt_key4(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + TWS_PD_MSG_BLOCK msg; + msg.msg_body.message_id = 3; + msg.msg_body.message_ptr = (uint32_t)NULL; + app_ibrt_peripheral_mailbox_put(&msg); +} + +void app_ibrt_key5(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + TWS_PD_MSG_BLOCK msg; + msg.msg_body.message_id = 4; + msg.msg_body.message_ptr = (uint32_t)NULL; + app_ibrt_peripheral_mailbox_put(&msg); +} + +void app_ibrt_key6(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + TWS_PD_MSG_BLOCK msg; + msg.msg_body.message_id = 5; + msg.msg_body.message_ptr = (uint32_t)NULL; + app_ibrt_peripheral_mailbox_put(&msg); +} +#endif + + +void app_bt_sleep(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + //app_ibrt_ui_event_entry(IBRT_CLOSE_BOX_EVENT); + a2dp_handleKey(AVRCP_KEY_PAUSE); +} + +void app_wakeup_sleep(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + //app_ibrt_ui_event_entry(IBRT_FETCH_OUT_EVENT); + a2dp_handleKey(AVRCP_KEY_PLAY); +} + +void app_test_key(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + //app_ibrt_ui_event_entry(IBRT_FETCH_OUT_EVENT); + a2dp_handleKey(AVRCP_KEY_PLAY); +} + +#if defined(__BT_DEBUG_TPORTS__) && !defined(TPORTS_KEY_COEXIST) + +void app_ibrt_ui_test_key(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + { +#ifdef IBRT_SEARCH_UI + app_ibrt_search_ui_handle_key(status,param); +#else + app_ibrt_normal_ui_handle_key(status,param); +#endif + } +} + +#else + +void app_ibrt_ui_test_key(APP_KEY_STATUS *status, void *param) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); +#ifdef TILE_DATAPATH + uint8_t shutdown_key = HAL_KEY_EVENT_TRIPLECLICK; +#else + uint8_t shutdown_key = HAL_KEY_EVENT_LONGLONGPRESS; +#endif + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + +#if 0//def IBRT_OTA + if ((status->code == HAL_KEY_CODE_PWR)&&\ + (status->event == APP_KEY_EVENT_CLICK)&&\ + (app_check_user_can_role_switch_in_ota())) + { + TRACE(0, "[OTA] role switch in progress!"); + return ; + } +#endif + +if (IBRT_SLAVE == p_ibrt_ctrl->current_role && status->event != shutdown_key) + { + /* if(((status->code == HAL_KEY_CODE_PWR)&&(status->event == APP_KEY_EVENT_CLICK)) &&\ + ((p_ibrt_ctrl->master_tws_switch_pending != false) || \ + (p_ibrt_ctrl->slave_tws_switch_pending != false) || \ + (ota_role_switch_flag != 0)||\ + (avoid_even_packets_protect_flag != 0))) + { + TRACE(0, "[OTA] role switch in progress!"); + return ; + } +*/ + app_ibrt_if_keyboard_notify(status,param); + } + + else + { +#ifdef IBRT_SEARCH_UI + app_ibrt_search_ui_handle_key(status,param); +#else + app_ibrt_normal_ui_handle_key(status,param); +#endif + } +} +#endif + +void app_ibrt_ui_test_key_io_event(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + switch(status->event) + { + case APP_KEY_EVENT_CLICK: + if (status->code== APP_KEY_CODE_FN1) + { + app_ibrt_if_event_entry(IBRT_OPEN_BOX_EVENT); + } + else if (status->code== APP_KEY_CODE_FN2) + { + app_ibrt_if_event_entry(IBRT_FETCH_OUT_EVENT); + } + else + { + app_ibrt_if_event_entry(IBRT_WEAR_UP_EVENT); + } + break; + + case APP_KEY_EVENT_DOUBLECLICK: + if (status->code== APP_KEY_CODE_FN1) + { + app_ibrt_if_event_entry(IBRT_CLOSE_BOX_EVENT); + } + else if (status->code== APP_KEY_CODE_FN2) + { + app_ibrt_if_event_entry(IBRT_PUT_IN_EVENT); + } + else + { + app_ibrt_if_event_entry(IBRT_WEAR_DOWN_EVENT); + } + break; + + case APP_KEY_EVENT_LONGPRESS: + break; + + case APP_KEY_EVENT_TRIPLECLICK: + break; + + case HAL_KEY_EVENT_LONGLONGPRESS: + break; + + case APP_KEY_EVENT_ULTRACLICK: + break; + + case APP_KEY_EVENT_RAMPAGECLICK: + break; + } +} + +void app_ibrt_ui_test_key_custom_event(APP_KEY_STATUS *status, void *param) +{ + TRACE(3,"%s %d,%d",__func__, status->code, status->event); + switch(status->event) + { + case APP_KEY_EVENT_CLICK: + break; + + case APP_KEY_EVENT_DOUBLECLICK: + break; + + case APP_KEY_EVENT_LONGPRESS: + break; + + case APP_KEY_EVENT_TRIPLECLICK: + break; + + case HAL_KEY_EVENT_LONGLONGPRESS: + break; + + case APP_KEY_EVENT_ULTRACLICK: + break; + + case APP_KEY_EVENT_RAMPAGECLICK: + break; + } +} + +void app_ibrt_ui_test_voice_assistant_key(APP_KEY_STATUS *status, void *param) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + TRACE(3,"%s code 0x%x event %d", __func__, status->code, status->event); + + if (APP_KEY_CODE_GOOGLE != status->code) + { + return; + } + else + { + ibrt_ctrl_t *pIbrtCtrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (IBRT_ACTIVE_MODE != pIbrtCtrl->tws_mode) + { + app_tws_ibrt_exit_sniff_with_mobile(); + } + } + + if (p_ibrt_ctrl->current_role != IBRT_MASTER) + { + app_ibrt_if_keyboard_notify(status, param); + TRACE(2,"%s isn't master %d", __func__, p_ibrt_ctrl->current_role); + return; + } + +#ifdef IS_MULTI_AI_ENABLED + if (app_ai_manager_spec_get_status_is_in_invalid()) + { + TRACE(0,"AI feature has been diabled"); + return; + } + + if (app_ai_manager_is_need_reboot()) + { + TRACE(1, "%s ai need to reboot", __func__); + return; + } + +#ifdef MAI_TYPE_REBOOT_WITHOUT_OEM_APP + if (app_ai_manager_get_spec_update_flag()) + { + TRACE(0,"device reboot is ongoing..."); + return; + } +#endif + + if(app_ai_manager_voicekey_is_enable()) + { + if (AI_SPEC_GSOUND == app_ai_manager_get_current_spec()) + { +#ifdef BISTO_ENABLED + gsound_custom_actions_handle_key(status, param); +#endif + } + else if(AI_SPEC_INIT != app_ai_manager_get_current_spec()) + { + app_ai_key_event_handle(status, 0); + } + } +#else +#ifdef __AI_VOICE__ + app_ai_key_event_handle(status, 0); +#endif +#ifdef BISTO_ENABLED + gsound_custom_actions_handle_key(status, param); +#endif +#endif +} + +const APP_KEY_HANDLE app_ibrt_ui_test_key_cfg[] = +{ +#if defined(__AI_VOICE__) || defined(BISTO_ENABLED) + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_FIRST_DOWN}, "google assistant key", app_ibrt_ui_test_voice_assistant_key, NULL}, + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_UP}, "google assistant key", app_ibrt_ui_test_voice_assistant_key, NULL}, + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_LONGPRESS}, "google assistant key", app_ibrt_ui_test_voice_assistant_key, NULL}, + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_CLICK}, "google assistant key", app_ibrt_ui_test_voice_assistant_key, NULL}, + {{APP_KEY_CODE_GOOGLE, APP_KEY_EVENT_DOUBLECLICK}, "google assistant key", app_ibrt_ui_test_voice_assistant_key, NULL}, +#endif +#ifdef TILE_DATAPATH + {{APP_KEY_CODE_TILE,APP_KEY_EVENT_DOWN},"tile function key",app_ibrt_ui_test_key, NULL}, + {{APP_KEY_CODE_TILE,APP_KEY_EVENT_UP},"tile function key",app_ibrt_ui_test_key, NULL}, +#endif +#if defined( __BT_ANC_KEY__)&&defined(ANC_APP) + {{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"bt anc key",app_anc_key, NULL}, +#else + //{{APP_KEY_CODE_PWR,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key, NULL}, +#endif + + // {{APP_KEY_CODE_PWR,APP_KEY_EVENT_UP},"app_ibrt_ui_test_key", app_bt_sleep, NULL}, + //{{APP_KEY_CODE_PWR,APP_KEY_EVENT_LONGLONGPRESS},"app_ibrt_ui_test_key", app_ibrt_ui_test_key, NULL}, + //{{APP_KEY_CODE_PWR,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key, NULL}, + //{{APP_KEY_CODE_PWR,APP_KEY_EVENT_TRIPLECLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key, NULL}, + //{{APP_KEY_CODE_PWR,APP_KEY_EVENT_ULTRACLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key, NULL}, + // {{APP_KEY_CODE_PWR,APP_KEY_EVENT_DOWN},"app_ibrt_ui_test_key", app_wakeup_sleep, NULL}, + //{{APP_KEY_CODE_PWR,APP_KEY_EVENT_LONGPRESS},"app_ibrt_ui_test_key", app_test_key, NULL}, + //{{APP_KEY_CODE_PWR,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key", app_test_key, NULL}, + // {{APP_KEY_CODE_PWR,APP_KEY_EVENT_NONE},"app_ibrt_ui_test_key", app_test_key, NULL}, + + +#if defined(CHIP_BEST1400) +#ifdef IBRT_SEARCH_UI + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_search_ui_gpio_key_handle, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_search_ui_gpio_key_handle, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key",app_ibrt_search_ui_gpio_key_handle, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key", app_ibrt_search_ui_gpio_key_handle, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_LONGPRESS},"app_ibrt_ui_test_key",app_ibrt_search_ui_gpio_key_handle, NULL}, +#endif +#elif defined(CHIP_BEST1402) +#ifdef IBRT_SEARCH_UI + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_search_ui_gpio_key_handle, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_search_ui_gpio_key_handle, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key",app_ibrt_search_ui_gpio_key_handle, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key", app_ibrt_search_ui_gpio_key_handle, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_LONGPRESS},"app_ibrt_ui_test_key",app_ibrt_search_ui_gpio_key_handle, NULL}, +#endif +#else +#ifdef IBRT_SEARCH_UI +#ifdef TPORTS_KEY_COEXIST + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_search_ui_gpio_key_handle, NULL}, + {{APP_KEY_CODE_FN1,HAL_KEY_EVENT_LONGPRESS},"app_ibrt_ui_test_key", app_ibrt_search_ui_gpio_key_handle, NULL}, +#else + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key, NULL}, + //{{APP_KEY_CODE_FN2,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_search_ui_gpio_key_handle, NULL}, + // {{APP_KEY_CODE_FN1,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key",app_ibrt_search_ui_gpio_key_handle, NULL}, + // {{APP_KEY_CODE_FN2,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key", app_ibrt_search_ui_gpio_key_handle, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_LONGLONGPRESS},"app_ibrt_ui_test_key",app_ibrt_ui_test_key, NULL}, + +#endif +#else + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key_io_event, NULL}, + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key_io_event, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key_io_event, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key_io_event, NULL}, +#endif +#endif + {{APP_KEY_CODE_FN3,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key_io_event, NULL}, + {{APP_KEY_CODE_FN3,APP_KEY_EVENT_DOUBLECLICK},"app_ibrt_ui_test_key", app_ibrt_ui_test_key_io_event, NULL}, + /* + #ifdef BES_AUDIO_DEV_Main_Board_9v0 + {{APP_KEY_CODE_FN1,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_key1, NULL}, + {{APP_KEY_CODE_FN2,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_key2, NULL}, + {{APP_KEY_CODE_FN3,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_key3, NULL}, + {{APP_KEY_CODE_FN4,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_key4, NULL}, + {{APP_KEY_CODE_FN5,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_key5, NULL}, + {{APP_KEY_CODE_FN6,APP_KEY_EVENT_CLICK},"app_ibrt_ui_test_key", app_ibrt_key6, NULL}, + #endif + */ +}; + +/* +* customer addr config here +*/ +ibrt_pairing_info_t g_ibrt_pairing_info[] = +{ + {{0x51, 0x33, 0x33, 0x22, 0x11, 0x11},{0x50, 0x33, 0x33, 0x22, 0x11, 0x11}}, + {{0x53, 0x33, 0x33, 0x22, 0x11, 0x11},{0x52, 0x33, 0x33, 0x22, 0x11, 0x11}}, /*LJH*/ + {{0x61, 0x33, 0x33, 0x22, 0x11, 0x11},{0x60, 0x33, 0x33, 0x22, 0x11, 0x11}}, + {{0x67, 0x66, 0x66, 0x22, 0x11, 0x11},{0x66, 0x66, 0x66, 0x22, 0x11, 0x11}}, /*bisto*/ + {{0x71, 0x33, 0x33, 0x22, 0x11, 0x11},{0x70, 0x33, 0x33, 0x22, 0x11, 0x11}}, + {{0x81, 0x33, 0x33, 0x22, 0x11, 0x11},{0x80, 0x33, 0x33, 0x22, 0x11, 0x11}}, + {{0x91, 0x33, 0x33, 0x22, 0x11, 0x11},{0x90, 0x33, 0x33, 0x22, 0x11, 0x11}}, /*Customer use*/ + {{0x05, 0x33, 0x33, 0x22, 0x11, 0x11},{0x04, 0x33, 0x33, 0x22, 0x11, 0x11}}, /*Rui*/ + {{0x07, 0x33, 0x33, 0x22, 0x11, 0x11},{0x06, 0x33, 0x33, 0x22, 0x11, 0x11}}, /*zsl*/ + {{0x88, 0xaa, 0x33, 0x22, 0x11, 0x11},{0x87, 0xaa, 0x33, 0x22, 0x11, 0x11}}, /*Lufang*/ + {{0x77, 0x22, 0x66, 0x22, 0x11, 0x11},{0x77, 0x33, 0x66, 0x22, 0x11, 0x11}}, /*xiao*/ + {{0xAA, 0x22, 0x66, 0x22, 0x11, 0x11},{0xBB, 0x33, 0x66, 0x22, 0x11, 0x11}}, /*LUOBIN*/ + {{0x08, 0x33, 0x66, 0x22, 0x11, 0x11},{0x07, 0x33, 0x66, 0x22, 0x11, 0x11}}, /*Yangbin1*/ + {{0x0B, 0x33, 0x66, 0x22, 0x11, 0x11},{0x0A, 0x33, 0x66, 0x22, 0x11, 0x11}}, /*Yangbin2*/ + {{0x35, 0x33, 0x66, 0x22, 0x11, 0x11},{0x34, 0x33, 0x66, 0x22, 0x11, 0x11}}, /*Lulu*/ + {{0xF8, 0x33, 0x66, 0x22, 0x11, 0x11},{0xF7, 0x33, 0x66, 0x22, 0x11, 0x11}}, /*jtx*/ + {{0xd3, 0x53, 0x86, 0x42, 0x71, 0x31},{0xd2, 0x53, 0x86, 0x42, 0x71, 0x31}}, /*shhx*/ + {{0xcc, 0xaa, 0x99, 0x88, 0x77, 0x66},{0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66}}, /*mql*/ + {{0x95, 0x33, 0x69, 0x22, 0x11, 0x11},{0x94, 0x33, 0x69, 0x22, 0x11, 0x11}}, /*wyl*/ + {{0x82, 0x35, 0x68, 0x24, 0x19, 0x17},{0x81, 0x35, 0x68, 0x24, 0x19, 0x17}}, /*hy*/ + {{0x66, 0x66, 0x88, 0x66, 0x66, 0x88},{0x65, 0x66, 0x88, 0x66, 0x66, 0x88}}, /*xdl*/ + {{0x61, 0x66, 0x66, 0x66, 0x66, 0x81},{0x16, 0x66, 0x66, 0x66, 0x66, 0x18}}, /*test1*/ + {{0x62, 0x66, 0x66, 0x66, 0x66, 0x82},{0x26, 0x66, 0x66, 0x66, 0x66, 0x28}}, /*test2*/ + {{0x63, 0x66, 0x66, 0x66, 0x66, 0x83},{0x36, 0x66, 0x66, 0x66, 0x66, 0x38}}, /*test3*/ + {{0x64, 0x66, 0x66, 0x66, 0x66, 0x84},{0x46, 0x66, 0x66, 0x66, 0x66, 0x48}}, /*test4*/ + {{0x65, 0x66, 0x66, 0x66, 0x66, 0x85},{0x56, 0x66, 0x66, 0x66, 0x66, 0x58}}, /*test5*/ + {{0xaa, 0x66, 0x66, 0x66, 0x66, 0x86},{0xaa, 0x66, 0x66, 0x66, 0x66, 0x68}}, /*test6*/ + {{0x67, 0x66, 0x66, 0x66, 0x66, 0x87},{0x76, 0x66, 0x66, 0x66, 0x66, 0x78}}, /*test7*/ + {{0x68, 0x66, 0x66, 0x66, 0x66, 0xa8},{0x86, 0x66, 0x66, 0x66, 0x66, 0x8a}}, /*test8*/ + {{0x69, 0x66, 0x66, 0x66, 0x66, 0x89},{0x86, 0x66, 0x66, 0x66, 0x66, 0x18}}, /*test9*/ + {{0x93, 0x33, 0x33, 0x33, 0x33, 0x33},{0x92, 0x33, 0x33, 0x33, 0x33, 0x33}}, /*gxl*/ + {{0xae, 0x28, 0x00, 0xe9, 0xc6, 0x5c},{0xd8, 0x29, 0x00, 0xe9, 0xc6, 0x5c}}, /*lsk*/ + {{0x07, 0x13, 0x66, 0x22, 0x11, 0x11},{0x06, 0x13, 0x66, 0x22, 0x11, 0x11}}, /*yangguo*/ + {{0x02, 0x15, 0x66, 0x22, 0x11, 0x11},{0x01, 0x15, 0x66, 0x22, 0x11, 0x11}}, /*mql fpga*/ + +}; + +/******************************pwrkey_det_timer*********************************************************/ +osTimerId pwrkey_detid = NULL; +void startpwrkey_det(int ms); +void stoppwrkey_det(void); +static void pwrkey_detfun(const void *); +osTimerDef(defpwrkey_det,pwrkey_detfun); +void pwrkey_detinit(void) +{ + TRACE(3,"%s",__func__); + pwrkey_detid = osTimerCreate(osTimer(defpwrkey_det),osTimerOnce,(void *)0); +} + +extern void app_ibrt_customif_test1_cmd_send(uint8_t *p_buff, uint16_t length); +static void pwrkey_detfun(const void *) +{ + + static ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + static bool last_pwrkey = false; + bool curr_pwrkey_sta; + curr_pwrkey_sta = hal_pwrkey_pressed(); + APP_KEY_STATUS inear_status[] = {APP_KEY_CODE_FN3,HAL_KEY_EVENT_CLICK}; + APP_KEY_STATUS outear_status[] = {APP_KEY_CODE_FN4,HAL_KEY_EVENT_CLICK}; + //TRACE(3,"pwrkey = %d",curr_pwrkey_sta); + if(curr_pwrkey_sta != last_pwrkey){ + if(curr_pwrkey_sta == true){ + //app_wakeup_sleep(NULL,NULL); + TRACE(3,"%s PLAY",__func__); + if (IBRT_SLAVE == p_ibrt_ctrl->current_role){ + app_ibrt_customif_test1_cmd_send((uint8_t *)inear_status, sizeof(APP_KEY_STATUS)); + }else{ + a2dp_handleKey(AVRCP_KEY_PLAY); + } + }else{ + //app_bt_sleep(NULL,NULL); + TRACE(3,"%s PAUSE",__func__); + //a2dp_handleKey(AVRCP_KEY_PAUSE); + if (IBRT_SLAVE == p_ibrt_ctrl->current_role){ + app_ibrt_customif_test1_cmd_send((uint8_t *)outear_status, sizeof(APP_KEY_STATUS)); + }else{ + a2dp_handleKey(AVRCP_KEY_PAUSE); + } + } + last_pwrkey = curr_pwrkey_sta; + } + startpwrkey_det(200); +} + +void startpwrkey_det(int ms) +{ + //TRACE(3,"\n\n !!!!!!!!!!start %s\n\n",__func__); + osTimerStart(pwrkey_detid,ms); +} + +void stoppwrkey_det(void) +{ + //TRACE("\n\n!!!!!!!!!! stop %s\n\n",__func__); + osTimerStop(pwrkey_detid); +} + + + +/********************************pwrkey_det_timer*******************************************************/ + +int app_ibrt_ui_test_config_load(void *config) +{ + ibrt_pairing_info_t *ibrt_pairing_info_lst = g_ibrt_pairing_info; + uint32_t lst_size = sizeof(g_ibrt_pairing_info)/sizeof(ibrt_pairing_info_t); + ibrt_config_t *ibrt_config = (ibrt_config_t *)config; + struct nvrecord_env_t *nvrecord_env; + uint8_t ble_address[6] = {0, 0, 0, 0, 0, 0}; + + nv_record_env_get(&nvrecord_env); + if(nvrecord_env->ibrt_mode.tws_connect_success == 0) + { + app_ibrt_ui_clear_tws_connect_success_last(); + } + else + { + app_ibrt_ui_set_tws_connect_success_last(); + } + + if (memcmp(nv_record_tws_get_self_ble_info(), bt_get_ble_local_address(), BD_ADDR_LEN) && + memcmp(nv_record_tws_get_self_ble_info(), ble_address, BD_ADDR_LEN)) + { + nv_record_tws_exchange_ble_info(); + } + + factory_section_original_btaddr_get(ibrt_config->local_addr.address); + for(uint32_t i =0; ilocal_addr.address, BD_ADDR_LEN)) + { + ibrt_config->nv_role = IBRT_MASTER; + ibrt_config->audio_chnl_sel = AUDIO_CHANNEL_SELECT_RCHNL; + memcpy(ibrt_config->peer_addr.address, ibrt_pairing_info_lst[i].slave_bdaddr.address, BD_ADDR_LEN); + return 0; + } + else if (!memcmp(ibrt_pairing_info_lst[i].slave_bdaddr.address, ibrt_config->local_addr.address, BD_ADDR_LEN)) + { + ibrt_config->nv_role = IBRT_SLAVE; + ibrt_config->audio_chnl_sel = AUDIO_CHANNEL_SELECT_LCHNL; + memcpy(ibrt_config->peer_addr.address, ibrt_pairing_info_lst[i].master_bdaddr.address, BD_ADDR_LEN); + return 0; + } + } + return -1; +} + +void app_ibrt_ui_test_key_init(void) +{ + app_key_handle_clear(); + for (uint8_t i=0; i +#include "bt_if.h" +#include "app_tws_ibrt_trace.h" +#include "factory_section.h" +#include "apps.h" +#include "app_battery.h" +#include "app_anc.h" +#include "app_key.h" +#include "app_ibrt_if.h" +#include "app_ibrt_ui_test.h" +#include "app_ibrt_auto_test.h" +#include "app_ibrt_auto_test_cmd_handle.h" +#include "app_ibrt_ui_test_cmd_if.h" +#include "app_ibrt_peripheral_manager.h" +#include "a2dp_decoder.h" +#include "app_ibrt_keyboard.h" +#include "nvrecord_env.h" +#include "nvrecord_ble.h" +#include "norflash_api.h" +#include "me_api.h" +#include "app_tws_if.h" +#include "besbt.h" +#include "btapp.h" +#include "app_bt.h" +#include "app_ai_if.h" +#include "app_ai_manager_api.h" +#include "app_ble_uart.h" +#if defined(BISTO_ENABLED) +#include "gsound_custom_actions.h" +#include "gsound_custom_bt.h" +#include "gsound_custom_ble.h" + +#endif +#ifdef __IAG_BLE_INCLUDE__ +#include "app.h" +#include "app_ble_mode_switch.h" +#endif + +#ifdef BES_OTA +#include "ota_control.h" +#endif + +#define IBRT_ENHANCED_STACK_PTS +static bt_bdaddr_t pts_bt_addr = {{ +#if 0 + 0x14, 0x71, 0xda, 0x7d, 0x1a, 0x00 +#else + 0x13, 0x71, 0xda, 0x7d, 0x1a, 0x00 +#endif + } +}; +void btif_pts_hf_create_link_with_pts(void) +{ + btif_pts_hf_create_service_link(&pts_bt_addr); +} +void btif_pts_av_create_channel_with_pts(void) +{ + btif_pts_av_create_channel(&pts_bt_addr); +} +void btif_pts_ar_connect_with_pts(void) +{ + btif_pts_ar_connect(&pts_bt_addr); +} + +void app_ibrt_ui_audio_play_test(void) +{ + uint8_t action[] = {IBRT_ACTION_PLAY}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_audio_pause_test(void) +{ + uint8_t action[] = {IBRT_ACTION_PAUSE}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_audio_forward_test(void) +{ + uint8_t action[] = {IBRT_ACTION_FORWARD}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_audio_backward_test(void) +{ + uint8_t action[] = {IBRT_ACTION_BACKWARD}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_avrcp_volume_up_test(void) +{ + uint8_t action[] = {IBRT_ACTION_AVRCP_VOLUP}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_avrcp_volume_down_test(void) +{ + uint8_t action[] = {IBRT_ACTION_AVRCP_VOLDN}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_hfsco_create_test(void) +{ + uint8_t action[] = {IBRT_ACTION_HFSCO_CREATE}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_hfsco_disc_test(void) +{ + uint8_t action[] = {IBRT_ACTION_HFSCO_DISC}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_call_redial_test(void) +{ + uint8_t action[] = {IBRT_ACTION_REDIAL}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_call_answer_test(void) +{ + uint8_t action[] = {IBRT_ACTION_ANSWER}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_call_hangup_test(void) +{ + uint8_t action[] = {IBRT_ACTION_HANGUP}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_local_volume_up_test(void) +{ + uint8_t action[] = {IBRT_ACTION_LOCAL_VOLUP}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} +void app_ibrt_ui_local_volume_down_test(void) +{ + uint8_t action[] = {IBRT_ACTION_LOCAL_VOLDN}; + app_ibrt_if_start_user_action(action, sizeof(action)); +} + +void app_ibrt_ui_get_tws_conn_state_test(void) +{ + if(app_tws_ibrt_tws_link_connected()) + { + TRACE(0,"ibrt_ui_log:TWS CONNECTED"); + } + else + { + TRACE(0,"ibrt_ui_log:TWS DISCONNECTED"); + } +} + +/***************************************************************************** + Prototype : app_ibrt_ui_soft_reset_test + Description : soft reset device + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/7/7 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_soft_reset_test(void) +{ + app_reset(); +} + + +extern void bt_change_to_iic(APP_KEY_STATUS *status, void *param); +void app_ibrt_ui_iic_uart_switch_test(void) +{ + bt_change_to_iic(NULL,NULL); +} + +void app_ibrt_ui_get_a2dp_state_test(void) +{ + const char* a2dp_state_strings[] = {"IDLE", "CODEC_CONFIGURED", "OPEN","STREAMING","CLOSED","ABORTING"}; + AppIbrtA2dpState a2dp_state; + + AppIbrtStatus status = app_ibrt_if_get_a2dp_state(&a2dp_state); + if(APP_IBRT_IF_STATUS_SUCCESS == status) + { + TRACE(0,"ibrt_ui_log:a2dp_state=%s",a2dp_state_strings[a2dp_state]); + } + else + { + TRACE(0,"ibrt_ui_log:get a2dp state error"); + } +} + +void app_ibrt_ui_get_avrcp_state_test(void) +{ + const char* avrcp_state_strings[] = {"DISCONNECTED", "CONNECTED", "PLAYING","PAUSED", "VOLUME_UPDATED"}; + AppIbrtAvrcpState avrcp_state; + + AppIbrtStatus status = app_ibrt_if_get_avrcp_state(&avrcp_state); + if(APP_IBRT_IF_STATUS_SUCCESS == status) + { + TRACE(0,"ibrt_ui_log:avrcp_state=%s",avrcp_state_strings[avrcp_state]); + } + else + { + TRACE(0,"ibrt_ui_log:get avrcp state error"); + } +} + +void app_ibrt_ui_get_hfp_state_test(void) +{ + const char* hfp_state_strings[] = {"SLC_DISCONNECTED", "CLOSED", "SCO_CLOSED","PENDING","SLC_OPEN", \ + "NEGOTIATE","CODEC_CONFIGURED","SCO_OPEN","INCOMING_CALL","OUTGOING_CALL","RING_INDICATION"}; + AppIbrtHfpState hfp_state; + AppIbrtStatus status = app_ibrt_if_get_hfp_state(&hfp_state); + + if(APP_IBRT_IF_STATUS_SUCCESS == status) + { + TRACE(0,"ibrt_ui_log:hfp_state=%s",hfp_state_strings[hfp_state]); + } + else + { + TRACE(0,"ibrt_ui_log:get hfp state error"); + } +} + +void app_ibrt_ui_get_call_status_test() +{ + const char* call_status_strings[] = {"NO_CALL","CALL_ACTIVE","HOLD","INCOMMING","OUTGOING","ALERT"}; + AppIbrtCallStatus call_status; + + AppIbrtStatus status = app_ibrt_if_get_hfp_call_status(&call_status); + if(APP_IBRT_IF_STATUS_SUCCESS == status) + { + TRACE(0,"ibrt_ui_log:call_status=%s",call_status_strings[call_status]); + } + else + { + TRACE(0,"ibrt_ui_log:get call status error"); + } +} + +void app_ibrt_ui_get_ibrt_role_test(void) +{ + ibrt_role_e role = app_ibrt_if_get_ibrt_role(); + + if(IBRT_MASTER == role) + { + TRACE(0,"ibrt_ui_log:ibrt role is MASTER"); + } + else if(IBRT_SLAVE == role) + { + TRACE(0,"ibrt_ui_log:ibrt role is SLAVE"); + } + else + { + TRACE(0,"ibrt_ui_log:ibrt role is UNKNOW"); + } +} + +/***************************************************************************** + Prototype : app_ibrt_ui_open_box_event_test + Description : app ibrt ui open box test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/3/30 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_open_box_event_test(void) +{ + app_ibrt_if_event_entry(IBRT_OPEN_BOX_EVENT); +} +/***************************************************************************** + Prototype : app_ibrt_ui_fetch_out_box_event_test + Description : fetch out box test function + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/3/30 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_fetch_out_box_event_test(void) +{ + app_ibrt_if_event_entry(IBRT_FETCH_OUT_EVENT); +} +/***************************************************************************** + Prototype : app_ibrt_ui_put_in_box_event_test + Description : app ibrt put in box test function + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/3/30 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_put_in_box_event_test(void) +{ + app_ibrt_if_event_entry(IBRT_PUT_IN_EVENT); +} +/***************************************************************************** + Prototype : app_ibrt_ui_close_box_event_test + Description : app ibrt close box test function + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/3/30 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_close_box_event_test(void) +{ + app_ibrt_if_event_entry(IBRT_CLOSE_BOX_EVENT); +} +/***************************************************************************** + Prototype : app_ibrt_ui_reconnect_event_test + Description : app ibrt reconnect function test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/3/30 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_reconnect_event_test(void) +{ + app_ibrt_if_event_entry(IBRT_RECONNECT_EVENT); +} +/***************************************************************************** + Prototype : app_ibrt_ui_ware_up_event_test + Description : app ibrt wear up function test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/3/30 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_ware_up_event_test(void) +{ + app_ibrt_if_event_entry(IBRT_WEAR_UP_EVENT); +} +/***************************************************************************** + Prototype : app_ibrt_ui_ware_down_event_test + Description : app ibrt wear down function test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/3/30 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_ware_down_event_test(void) +{ + app_ibrt_if_event_entry(IBRT_WEAR_DOWN_EVENT); +} +/***************************************************************************** + Prototype : app_ibrt_ui_phone_connect_event_test + Description : app ibrt ui phone connect event + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/3 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +void app_ibrt_ui_phone_connect_event_test(void) +{ + app_ibrt_if_event_entry(IBRT_PHONE_CONNECT_EVENT); +} +/***************************************************************************** + Prototype : app_ibrt_ui_shut_down_test + Description : shut down test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/10 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +extern "C" int app_shutdown(void); +void app_ibrt_ui_shut_down_test(void) +{ + app_ibrt_peripheral_auto_test_stop(); + app_shutdown(); +} + +/***************************************************************************** + Prototype : app_ibrt_enable_tports_test + Description : enable BT tports + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/10 + Author : bestechnic + Modification : Created function + +*****************************************************************************/ +extern void bt_enable_tports(void); +void app_ibrt_enable_tports_test(void) +{ + bt_enable_tports(); +} +/***************************************************************************** + Prototype : app_ibrt_ui_tws_swtich_test + Description : tws switch test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/10 + Author : bestechnic + Modification : Created function + + *****************************************************************************/ + void app_ibrt_ui_tws_swtich_test(void) + { + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (p_ibrt_ctrl->current_role == IBRT_MASTER) + { + btif_me_ibrt_role_switch(p_ibrt_ctrl->mobile_conhandle); + } + else + { + TRACE(0,"ibrt_ui_log:local role is ibrt_slave, pls send tws switch in another dev"); + } + } + + /***************************************************************************** + Prototype : app_ibrt_ui_suspend_ibrt_test + Description : suspend ibrt fastack + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/24 + Author : bestechnic + Modification : Created function + + *****************************************************************************/ + void app_ibrt_ui_suspend_ibrt_test(void) + { + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (p_ibrt_ctrl->current_role== IBRT_MASTER) + { + btif_me_suspend_ibrt(); + } + else + { + TRACE(0,"ibrt_ui_log:local role is ibrt_slave, suspend ibrt failed"); + } + } + /***************************************************************************** + Prototype : app_ibrt_ui_resume_ibrt_test + Description : resume ibrt test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/4/27 + Author : bestechnic + Modification : Created function + + *****************************************************************************/ + void app_ibrt_ui_resume_ibrt_test(void) + { + btif_me_resume_ibrt(1); + } + /***************************************************************************** + Prototype : app_ibrt_ui_pairing_mode_test + Description : pairing mode test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/11/20 + Author : bestechnic + Modification : Created function + + *****************************************************************************/ + void app_ibrt_ui_pairing_mode_test(void) + { + app_ibrt_ui_event_entry(IBRT_TWS_PAIRING_EVENT); + } + /***************************************************************************** + Prototype : app_ibrt_ui_freeman_pairing_mode_test + Description : ibrt freeman pairing mode test + Input : void + Output : None + Return Value : + Calls : + Called By : + + History : + Date : 2019/11/21 + Author : bestechnic + Modification : Created function + + *****************************************************************************/ + void app_ibrt_ui_freeman_pairing_mode_test(void) + { + app_ibrt_ui_event_entry(IBRT_FREEMAN_PAIRING_EVENT); + } + + void app_ibrt_inquiry_start_test(void) + { + app_bt_start_search(); + } + +void app_ibrt_role_switch_test(void) +{ + app_tws_if_trigger_role_switch(); +} + diff --git a/services/app_ibrt/src/app_ibrt_voice_report.cpp b/services/app_ibrt/src/app_ibrt_voice_report.cpp new file mode 100644 index 0000000..3a07378 --- /dev/null +++ b/services/app_ibrt/src/app_ibrt_voice_report.cpp @@ -0,0 +1,511 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include +#include "me_api.h" +#include "app_tws_ibrt_trace.h" +#include "audioflinger.h" +#include "app_bt_stream.h" +#include "app_media_player.h" +#include "app_bt_media_manager.h" +#include "bt_drv_interface.h" +#include "app_ibrt_if.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_ctrl_thread.h" +#include "app_ibrt_voice_report.h" +#include "app_bt.h" +#ifdef TWS_PROMPT_SYNC +#include "audio_prompt_sbc.h" +#endif +#include "app_audio.h" + +#if defined(IBRT) +extern uint8_t g_findme_fadein_vol; + +typedef uint8_t voice_report_role_t; +#define VOICE_REPORT_MASTER 0x00 +#define VOICE_REPORT_SLAVE 0x01 +#define VOICE_REPORT_LOCAL 0x02 + + +#define APP_PLAY_AUDIO_SYNC_DELAY_US (250*1000) +#define APP_PLAY_AUDIO_SYNC_TRIGGER_TIMEROUT (APP_PLAY_AUDIO_SYNC_DELAY_US/1000*2) + +static uint32_t app_ibrt_voice_tg_tick = 0; +static uint32_t app_ibrt_voice_trigger_enable = 0; + +static void app_ibrt_voice_report_trigger_timeout_cb(void const *n); +osTimerDef(APP_IBRT_VOICE_REPORT_TRIGGER_TIMEOUT, app_ibrt_voice_report_trigger_timeout_cb); +osTimerId app_ibrt_voice_report_trigger_timeout_id = NULL; + +static void app_ibrt_voice_report_trigger_timeout_cb(void const *n) +{ + TRACE_VOICE_RPT_D("[TRIG][TIMEOUT]"); + app_play_audio_stop(); +} + +static int app_ibrt_voice_report_trigger_checker_init(void) +{ + if (app_ibrt_voice_report_trigger_timeout_id == NULL){ + app_ibrt_voice_report_trigger_timeout_id = osTimerCreate(osTimer(APP_IBRT_VOICE_REPORT_TRIGGER_TIMEOUT), osTimerOnce, NULL); + } + return 0; +} + +static int app_ibrt_voice_report_trigger_checker_start(void) +{ + app_ibrt_voice_trigger_enable = true; + osTimerStart(app_ibrt_voice_report_trigger_timeout_id, APP_PLAY_AUDIO_SYNC_TRIGGER_TIMEROUT); + return 0; +} + +static int app_ibrt_voice_report_trigger_checker_stop(void) +{ + app_ibrt_voice_trigger_enable = false; + osTimerStop(app_ibrt_voice_report_trigger_timeout_id); + return 0; +} + +int app_ibrt_voice_report_trigger_checker(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (!p_ibrt_ctrl->init_done){ + return 0; + } + + if (app_ibrt_voice_trigger_enable){ + TRACE_VOICE_RPT_I("[TRIG][OK]"); + app_ibrt_voice_trigger_enable = false; + osTimerStop(app_ibrt_voice_report_trigger_timeout_id); + } + return 0; +} + +voice_report_role_t app_ibrt_voice_report_get_role(void) +{ + voice_report_role_t report_role = VOICE_REPORT_LOCAL; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (app_ibrt_ui_is_profile_exchanged()){ + if (app_tws_ibrt_mobile_link_connected()){ + report_role = VOICE_REPORT_MASTER; + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + report_role = VOICE_REPORT_SLAVE; + }else{ + TRACE_VOICE_RPT_I("[GET_ROLE] skip it (profile_exchanged)"); + } + }else if (app_tws_ibrt_tws_link_connected()){ + if (app_tws_ibrt_mobile_link_connected()){ + report_role = VOICE_REPORT_MASTER; + }else if(p_ibrt_ctrl->current_role == IBRT_MASTER){ + report_role = VOICE_REPORT_MASTER; + }else{ + report_role = VOICE_REPORT_SLAVE; + } + + }else{ + TRACE_VOICE_RPT_I("[GET_ROLE] loc only"); + } + + TRACE_VOICE_RPT_I("[GET_ROLE] report_role: %d", report_role); + return report_role; +} + +static void app_ibrt_voice_report_set_trigger_time(uint32_t tg_tick) +{ + if (tg_tick){ + ibrt_ctrl_t *p_ibrt_ctrl = app_ibrt_if_get_bt_ctrl_ctx(); + btif_connection_role_t connection_role = app_tws_ibrt_get_local_tws_role(); + btdrv_syn_trigger_codec_en(0); + btdrv_syn_clr_trigger(); + btdrv_enable_playback_triggler(ACL_TRIGGLE_MODE); + if (connection_role == BTIF_BCR_MASTER){ + bt_syn_set_tg_ticks(tg_tick, p_ibrt_ctrl->tws_conhandle, BT_TRIG_MASTER_ROLE); + }else if (connection_role == BTIF_BCR_SLAVE){ + bt_syn_set_tg_ticks(tg_tick, p_ibrt_ctrl->tws_conhandle, BT_TRIG_SLAVE_ROLE); + } + btdrv_syn_trigger_codec_en(1); + app_ibrt_voice_report_trigger_checker_start(); + TRACE_VOICE_RPT_I("[TRIG] set trigger tg_tick:%08x", tg_tick); + }else{ + btdrv_syn_trigger_codec_en(0); + btdrv_syn_clr_trigger(); + app_ibrt_voice_report_trigger_checker_stop(); + TRACE_VOICE_RPT_I("[TRIG] trigger clear"); + } +} + +int app_ibrt_voice_report_trigger_init(uint32_t aud_id, uint32_t aud_pram) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (!p_ibrt_ctrl->init_done){ + TRACE_VOICE_RPT_I("ibrt not init done."); + return 0; + } + + app_ibrt_voice_report_trigger_checker_init(); + if (app_tws_ibrt_tws_link_connected()){ + ibrt_ctrl_t *p_ibrt_ctrl = app_ibrt_if_get_bt_ctrl_ctx(); + voice_report_role_t report_role = app_ibrt_voice_report_get_role(); + uint32_t curr_ticks = 0; + uint32_t tg_tick = 0; + app_ibrt_voice_report_trigger_deinit(); + + curr_ticks = bt_syn_get_curr_ticks(p_ibrt_ctrl->tws_conhandle); + + if (report_role == VOICE_REPORT_MASTER){ + app_ibrt_voice_report_info_t voice_report_info; + + tg_tick = curr_ticks + US_TO_BTCLKS(APP_PLAY_AUDIO_SYNC_DELAY_US); +#ifdef PLAYBACK_USE_I2S + af_i2s_sync_config(AUD_STREAM_PLAYBACK, AF_I2S_SYNC_TYPE_BT, false); + af_i2s_sync_config(AUD_STREAM_PLAYBACK, AF_I2S_SYNC_TYPE_BT, true); +#else + af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, false); + af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, true); +#endif + app_ibrt_voice_report_set_trigger_time(tg_tick); + voice_report_info.aud_id = aud_id; + voice_report_info.aud_pram = aud_pram; + voice_report_info.tg_tick = tg_tick; +#ifdef __INTERACTION__ + voice_report_info.vol = g_findme_fadein_vol; +#endif + if (p_ibrt_ctrl->tws_mode == IBRT_SNIFF_MODE) + { + TRACE_VOICE_RPT_I("[TRIG][INIT][EXIT_SNIFF] force_exit_with_tws\n"); + app_tws_ibrt_exit_sniff_with_tws(); + } + tws_ctrl_send_cmd(APP_TWS_CMD_VOICE_REPORT_START, (uint8_t *)&voice_report_info, sizeof(app_ibrt_voice_report_info_t)); + TRACE_VOICE_RPT_I("[TRIG][INIT] MASTER aud_id:%d trigger [%08x]-->[%08x]", aud_id, bt_syn_get_curr_ticks(p_ibrt_ctrl->tws_conhandle), tg_tick); + }else if (report_role == VOICE_REPORT_SLAVE){ + tg_tick = app_ibrt_voice_tg_tick; + if (curr_ticks < tg_tick && tg_tick != 0) + { +#ifdef PLAYBACK_USE_I2S + af_i2s_sync_config(AUD_STREAM_PLAYBACK, AF_I2S_SYNC_TYPE_BT, false); + af_i2s_sync_config(AUD_STREAM_PLAYBACK, AF_I2S_SYNC_TYPE_BT, true); +#else + af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, false); + af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, true); +#endif + app_ibrt_voice_report_set_trigger_time(tg_tick); + } + app_ibrt_voice_tg_tick = 0; + if (tg_tick <= curr_ticks) + { + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE, 0); + TRACE_VOICE_RPT_I("[TRIG][INIT] Prompt TRIGGER ERROR !!!"); + } + + TRACE_VOICE_RPT_I("[TRIG][INIT] SLAVE aud_id:%d trigger [%08x]-->[%08x]", aud_id, bt_syn_get_curr_ticks(p_ibrt_ctrl->tws_conhandle), tg_tick); + } + } + else + { + TRACE_VOICE_RPT_I("[TRIG][INIT] tws not connected."); + } + + return 0; +} + +int app_ibrt_voice_report_trigger_deinit(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (!p_ibrt_ctrl->init_done){ + return 0; + } + +#ifdef PLAYBACK_USE_I2S + af_i2s_sync_config(AUD_STREAM_PLAYBACK, AF_I2S_SYNC_TYPE_BT, false); +#else + af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, false); +#endif + app_ibrt_voice_report_set_trigger_time(0); + + return 0; +} + +int app_ibrt_if_voice_report_filter(uint32_t aud_id) +{ + int nRet = 0; + ibrt_ctrl_t *p_ibrt_ctrl = app_ibrt_if_get_bt_ctrl_ctx(); + + switch (aud_id){ + case AUD_ID_BT_PAIRING_SUC: + nRet = 1; + break; + default: + break; + } + + if (app_tws_ibrt_slave_ibrt_link_connected()){ + switch (aud_id){ + case AUD_ID_BT_CALL_INCOMING_CALL: + case AUD_ID_BT_CALL_INCOMING_NUMBER: + case AUD_ID_BT_CALL_OVER: + case AUD_ID_BT_CALL_ANSWER: + case AUD_ID_BT_CONNECTED: + case AUD_ID_BT_CALL_HUNG_UP: + case AUD_ID_BT_CALL_REFUSE: + nRet = 1; + break; + default: + break; + } + } + + if (!app_tws_ibrt_slave_ibrt_link_connected() && + !app_tws_ibrt_mobile_link_connected()){ + if (p_ibrt_ctrl->nv_role == IBRT_SLAVE){ + switch (aud_id){ + case AUD_ID_BT_CONNECTED: + nRet = 1; + break; + default: + break; + } + } + } + + return nRet; +} + +int app_ibrt_if_voice_report_local_only(uint32_t aud_id) +{ + int nRet = 0; + + switch (aud_id){ + default: + break; + } + + return nRet; +} + +int app_ibrt_if_voice_report_force_audio_retrigger_hander(uint32_t msg_id, uint32_t aud_id) +{ + if (msg_id == APP_BT_STREAM_MANAGER_STOP_MEDIA){ + if (aud_id == AUDIO_ID_BT_MUTE){ + TRACE_VOICE_RPT_I("[ID_BT_MUTE]"); +#ifdef MEDIA_PLAYER_SUPPORT + trigger_media_play((AUD_ID_ENUM)aud_id, 0, PROMOT_ID_BIT_MASK_CHNLSEl_ALL); +#endif + } + } + return 0; +} + +static int app_ibrt_if_voice_report_init(uint32_t aud_id, uint16_t aud_pram, uint8_t init_play) +{ +#ifdef MEDIA_PLAYER_SUPPORT + + + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (!p_ibrt_ctrl->init_done) + { + trigger_media_play((AUD_ID_ENUM)aud_id, 0, aud_pram); + } + else if (app_ibrt_if_voice_report_filter(aud_id) && init_play) + { + TRACE_VOICE_RPT_I("[INIT] skip aud_id:%d%s", aud_id, aud_id2str(aud_id)); + } + else if (app_ibrt_if_voice_report_local_only(aud_id)) + { + trigger_media_play((AUD_ID_ENUM)aud_id, 0, aud_pram); + } + else if (!app_tws_ibrt_tws_link_connected()) + { + trigger_media_play((AUD_ID_ENUM)aud_id, 0, aud_pram); + } + else + { + voice_report_role_t report_role = app_ibrt_voice_report_get_role(); + + app_ibrt_if_tws_sniff_block(5); + if (report_role == VOICE_REPORT_MASTER) + { + TRACE_VOICE_RPT_I("[INIT] loc aud_id:%d%s aud_pram:%04x", aud_id, aud_id2str(aud_id), aud_pram); + + if (aud_id == AUDIO_ID_BT_MUTE) + { +#ifdef TWS_PROMPT_SYNC + audio_prompt_stop_playing(); +#endif + app_audio_manager_sendrequest_need_callback(APP_BT_STREAM_MANAGER_STOP_MEDIA, + BT_STREAM_MEDIA, + BT_DEVICE_ID_1, + 0, + (uintptr_t)app_ibrt_if_voice_report_force_audio_retrigger_hander, + AUDIO_ID_BT_MUTE); + } + else + { + trigger_media_play((AUD_ID_ENUM)aud_id, 0, aud_pram); + } + } + else if (report_role == VOICE_REPORT_SLAVE) + { + app_ibrt_voice_report_request_t voice_report_request; + TRACE_VOICE_RPT_I("[INIT] rmt aud_id:%d%s aud_pram:%04x", aud_id, aud_id2str(aud_id), aud_pram); + app_ibrt_voice_tg_tick = 0; + if (aud_id == AUDIO_ID_BT_MUTE) + { +#ifdef TWS_PROMPT_SYNC + audio_prompt_stop_playing(); +#endif + app_audio_manager_sendrequest_need_callback(APP_BT_STREAM_MANAGER_STOP_MEDIA, + BT_STREAM_MEDIA, + BT_DEVICE_ID_1, + 0, + 0, + 0); + } + + voice_report_request.aud_id = aud_id; + voice_report_request.aud_pram = aud_pram; + voice_report_request.vol = 0; + if((aud_id & AUDIO_ID_FIND_MY_BUDS) == AUDIO_ID_FIND_MY_BUDS) + { + trigger_media_play(( AUD_ID_ENUM )aud_id, 0, aud_pram); + } + else + tws_ctrl_send_cmd(APP_TWS_CMD_VOICE_REPORT_REQUEST, (uint8_t *)&voice_report_request, sizeof(voice_report_request)); + + } + else + { + TRACE_VOICE_RPT_I("[INIT] loc only aud_id:%d aud_pram:%04x", aud_id, aud_pram); +#ifdef MEDIA_PLAYER_SUPPORT + trigger_media_play((AUD_ID_ENUM)aud_id, 0, aud_pram); +#endif + } + } +#endif + return 0; +} + +int app_ibrt_if_voice_report_trig_retrigger(void) +{ + return app_ibrt_if_voice_report_handler(AUDIO_ID_BT_MUTE, PROMOT_ID_BIT_MASK_CHNLSEl_ALL); +} + +int app_ibrt_if_voice_report_handler(uint32_t aud_id, uint16_t aud_pram) +{ + return app_ibrt_if_voice_report_init(aud_id, aud_pram, true); +} + +void app_ibrt_send_voice_report_request_req(uint8_t *p_buff, uint16_t length) +{ + voice_report_role_t report_role = app_ibrt_voice_report_get_role(); + + if (report_role == VOICE_REPORT_SLAVE) + { + app_ibrt_send_cmd_without_rsp(APP_TWS_CMD_VOICE_REPORT_REQUEST, p_buff, length); + } +} + +void app_ibrt_voice_report_request_req_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + voice_report_role_t report_role = app_ibrt_voice_report_get_role(); + + if (report_role == VOICE_REPORT_MASTER) + { + app_ibrt_voice_report_request_t *voice_report_request = (app_ibrt_voice_report_request_t *)p_buff; + app_ibrt_if_voice_report_init(voice_report_request->aud_id, voice_report_request->aud_pram, false); + } + else + { + TRACE_VOICE_RPT_I("[REQUEST_REQ][HANDLER] role is :%d", report_role); + } +} + +void app_ibrt_send_voice_report_start_req(uint8_t *p_buff, uint16_t length) +{ + voice_report_role_t report_role = app_ibrt_voice_report_get_role(); + + if (report_role == VOICE_REPORT_MASTER) + + { + app_ibrt_send_cmd_without_rsp(APP_TWS_CMD_VOICE_REPORT_START, p_buff, length); + } + else + { + TRACE_VOICE_RPT_I("[START_REQ] role is :%d", report_role); + } +} + +void app_ibrt_voice_report_request_start_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ +#ifdef MEDIA_PLAYER_SUPPORT + voice_report_role_t report_role = app_ibrt_voice_report_get_role(); + + if (report_role == VOICE_REPORT_SLAVE) + { + app_ibrt_voice_report_info_t *voice_report_info = (app_ibrt_voice_report_info_t *)p_buff; + app_ibrt_voice_tg_tick = voice_report_info->tg_tick; +#ifdef __INTERACTION__ + g_findme_fadein_vol = voice_report_info->vol; +#endif + + if (voice_report_info->aud_id == AUDIO_ID_BT_MUTE) + { + app_audio_manager_sendrequest_need_callback(APP_BT_STREAM_MANAGER_STOP_MEDIA, + BT_STREAM_MEDIA, + BT_DEVICE_ID_1, + 0, + (uintptr_t)app_ibrt_if_voice_report_force_audio_retrigger_hander, + AUDIO_ID_BT_MUTE); + } + else + { + TRACE_VOICE_RPT_I("[START_REQ][HANDLER] aud id:%d", voice_report_info->aud_id); + trigger_media_play((AUD_ID_ENUM)voice_report_info->aud_id, 0, voice_report_info->aud_pram); + } + } + else + { + TRACE_VOICE_RPT_I("[START_REQ][HANDLER] role is :%d", report_role); + } +#endif +} + +bool app_ibrt_voice_report_is_me(uint32_t voice_chnlsel) +{ + bool is_me = true; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + switch ((AUDIO_CHANNEL_SELECT_E)p_ibrt_ctrl->audio_chnl_sel) + { + case AUDIO_CHANNEL_SELECT_LCHNL: + if (IS_PROMPT_CHNLSEl_RCHNL(voice_chnlsel)){ + is_me = false; + } + break; + case AUDIO_CHANNEL_SELECT_RCHNL: + if (IS_PROMPT_CHNLSEl_LCHNL(voice_chnlsel)){ + is_me = false; + } + break; + default: + break; + } + return is_me; +} +#endif + diff --git a/services/app_tws/Makefile b/services/app_tws/Makefile new file mode 100644 index 0000000..d931fa3 --- /dev/null +++ b/services/app_tws/Makefile @@ -0,0 +1,42 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.cpp)) + +src_obj := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +obj-y := $(src_obj) + +subdir-ccflags-y += \ + -Iapps/key \ + -Iplatform/hal \ + -Iplatform/drivers/bt \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/ke/api \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/hl/inc \ + -Iservices/ble_stack/common/api \ + -Iservices/ai_voice/manager \ + -Iservices/app_ibrt/inc \ + -Iservices/app_tws/inc \ + -Iservices/ble_app/app_gfps \ + -Iservices/ble_app/app_main \ + -Iservices/ble_app/app_sec \ + -Iservices/bt_if_enhanced/inc \ + -Iservices/bt_app \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/ibrt_core/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/voicepath \ + -Iservices/voicepath/gsound/gsound_target_api_read_only \ + -Iservices/voicepath/gsound/gsound_custom/inc \ + -Iservices/voicepath/gsound/gsound_target \ + -Ithirdparty/userapi \ + -Iservices/app_ai/inc \ + -Iutils/cqueue \ + -Iservices/ota\ + -Iservices/ibrt_ota/inc \ + -Iservices/ai_voice/protocol/gma/gma_manager diff --git a/services/app_tws/inc/app_tws_if.h b/services/app_tws/inc/app_tws_if.h new file mode 100644 index 0000000..af352dd --- /dev/null +++ b/services/app_tws/inc/app_tws_if.h @@ -0,0 +1,460 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +#ifndef __APP_TWS_IF_H__ +#define __APP_TWS_IF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************header include********************************/ + +/******************************macro defination*****************************/ +#define TWS_SYNC_BUF_SIZE 300 + +/******************************type defination******************************/ +typedef enum { + EAR_SIDE_UNKNOWN = 0, + EAR_SIDE_LEFT = 1, + EAR_SIDE_RIGHT = 2, + EAR_SIDE_NUM, +} APP_TWS_SIDE_T; + +enum { + DISCONNECTED = 0, + CONNECTED = 1, + + CONNECTION_STATE_NUM, +}; + +typedef enum { + TWS_SYNC_USER_BLE_INFO = 0, + TWS_SYNC_USER_OTA = 1, + TWS_SYNC_USER_AI_CONNECTION = 2, + TWS_SYNC_USER_GFPS_INFO = 3, + TWS_SYNC_USER_AI_INFO = 4, + TWS_SYNC_USER_AI_MANAGER = 5, + TWS_SYNC_USER_DIP = 6, + + TWS_SYNC_USER_NUM, +} TWS_SYNC_USER_E; + +typedef void (*TWS_SYNC_INFO_PREPARE_FUNC_T)(uint8_t *buf, uint16_t *len); +typedef void (*TWS_INFO_SYNC_FUNC_T)(uint8_t *buf, uint16_t len); +typedef struct { + TWS_SYNC_INFO_PREPARE_FUNC_T sync_info_prepare_handler; + TWS_INFO_SYNC_FUNC_T sync_info_received_handler; + TWS_SYNC_INFO_PREPARE_FUNC_T sync_info_prepare_rsp_handler; + TWS_INFO_SYNC_FUNC_T sync_info_rsp_received_handler; + TWS_INFO_SYNC_FUNC_T sync_info_rsp_timeout_handler; +} TWS_SYNC_USER_T; + +typedef struct { + TWS_SYNC_USER_T syncUser[TWS_SYNC_USER_NUM]; +} TWS_ENV_T; + +typedef struct { + TWS_SYNC_USER_E userId; + uint8_t info[TWS_SYNC_BUF_SIZE-1]; +}TWS_SYNC_DATA_T; + +/****************************function declearation**************************/ +/*--------------------------------------------------------------------------- + * app_tws_if_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * initialize the tws interface related parameter + * + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_init(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_role_switch_started_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * handler for role switch started event of tws system + * + * Parameters: + * void + * + * Return: + * voide + */ +void app_tws_if_role_switch_started_handler(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_tws_role_switch_complete_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * callback function of role switch complete event for tws system + * NOTE: tws system include relay_tws and IBRT + * + * Parameters: + * newRole - current role of device after role switch complete + * + * Return: + * void + */ +void app_tws_if_tws_role_switch_complete_handler(uint8_t newRole); + +/*--------------------------------------------------------------------------- + * app_tws_if_tws_role_updated_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * callback function of tws role updated event for tws system + * NOTE: tws system include relay_tws and IBRT + * + * Parameters: + * newRole - current role of device after role updated + * + * Return: + * void + */ +void app_tws_if_tws_role_updated_handler(uint8_t newRole); + +/*--------------------------------------------------------------------------- + * app_tws_if_sync_info_received_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * handler for tws common info received event + * NOTE: see @ to get more info for common info received + * + * Parameters: + * rsp_seq - sequence number of response + * p_buff - pointer for received data + * lenght - length of received data + * + * Return: + * void + */ +void app_tws_if_sync_info_received_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +/*--------------------------------------------------------------------------- + * app_tws_if_common_info_rsp_recieved_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * shared common info response received handler + * + * Parameters: + * rsp_seq - sequence number of response + * p_buff - pointer for received data + * lenght - length of received data + * + * Return: + * void + */ +void app_tws_if_sync_info_rsp_received_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +/*--------------------------------------------------------------------------- + * app_tws_if_sync_info_rsp_timeout_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * shared common info response timeout handler + * + * Parameters: + * rsp_seq - sequence number of response + * p_buff - pointer for received data + * lenght - length of received data + * + * Return: + * void + */ +void app_tws_if_sync_info_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +/*--------------------------------------------------------------------------- + * app_tws_if_mobile_connected_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * handler of tws connected with mobile phone + * + * Parameters: + * addr - connected mobile address + * + * Return: + * void + */ +void app_tws_if_mobile_connected_handler(uint8_t *addr); + +/*--------------------------------------------------------------------------- + * app_tws_if_mobile_disconnected_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * handler of tws disconnected with mobile phone + * + * Parameters: + * addr - disconnected mobile phone + * + * Return: + * void + */ +void app_tws_if_mobile_disconnected_handler(uint8_t *addr); + +/*--------------------------------------------------------------------------- + * app_tws_if_ibrt_connected_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * handler of ibrt connected + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_ibrt_connected_handler(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_ibrt_disconnected_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * handler of ibrt disconnected + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_ibrt_disconnected_handler(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_ble_connected_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * handler of ble connected event for tws system + * + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_ble_connected_handler(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_ble_disconnected_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * ble disconnected handler for tws system + * + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_ble_disconnected_handler(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_tws_connected_sync_info + *--------------------------------------------------------------------------- + * + *Synopsis: + * sync BLE\BISTO\AI info after tws connected + * + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_tws_connected_sync_info(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_tws_connected_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * handler of tws connected event + * + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_tws_connected_handler(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_tws_disconnected_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * handler of tws disconnected event + * + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_tws_disconnected_handler(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_trigger_role_switch + *--------------------------------------------------------------------------- + * + *Synopsis: + * role switch trigger for tws system + * + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_trigger_role_switch(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_handle_click + *--------------------------------------------------------------------------- + * + *Synopsis: + * handle the power key click event + * + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_handle_click(void); + +/*--------------------------------------------------------------------------- + * app_tws_if_master_prepare_rs + *--------------------------------------------------------------------------- + * + *Synopsis: + * master prepare for role switch for BISTO and AI + * + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_master_prepare_rs(uint8_t *p_buff, uint16_t length); + +#ifdef IBRT +/*--------------------------------------------------------------------------- + * app_tws_if_slave_continue_rs + *--------------------------------------------------------------------------- + * + *Synopsis: + * slave continue role switch progress + * + * Parameters: + * void + * + * Return: + * void + */ +void app_tws_if_slave_continue_rs(uint8_t *p_buff, uint16_t length); +#endif + +/*--------------------------------------------------------------------------- + * app_tws_if_register_sync_user + *--------------------------------------------------------------------------- + * + *Synopsis: + * register info sync user for tws system + * + * Parameters: + * id - user ID, see @TWS_SYNC_USER_E + * user - user related functions + * + * Return: + * void + */ +void app_tws_if_register_sync_user(uint8_t id, TWS_SYNC_USER_T *user); + +/*--------------------------------------------------------------------------- + * app_tws_if_deregister_sync_user + *--------------------------------------------------------------------------- + * + *Synopsis: + * deregister info sync user for tws system + * + * Parameters: + * id - id of user to deregister, see @TWS_SYNC_USER_E + * + * Return: + * void + */ +void app_tws_if_deregister_sync_user(uint8_t id); + +/*--------------------------------------------------------------------------- + * app_tws_if_sync_info + *--------------------------------------------------------------------------- + * + *Synopsis: + * sync tws if + * + * Parameters: + * id - user ID + * + * Return: + * void + */ +void app_tws_if_sync_info(TWS_SYNC_USER_E id); + +void app_tws_if_ai_send_cmd_to_peer(uint8_t *p_buff, uint16_t length); +void app_tws_if_ai_rev_peer_cmd_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_tws_if_ai_send_cmd_with_rsp_to_peer(uint8_t *p_buff, uint16_t length); +void app_tws_if_ai_send_cmd_rsp_to_peer(uint8_t *p_buff, uint16_t rsp_seq, uint16_t length); +void app_tws_if_ai_rev_peer_cmd_with_rsp_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_tws_if_ai_rev_cmd_rsp_from_peer_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_tws_if_ai_rev_cmd_rsp_timeout_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +#ifdef GFPS_ENABLED +void app_ibrt_share_fastpair_info(uint8_t *p_buff, uint16_t length); +void app_tws_send_fastpair_info_to_slave(void); +void app_ibrt_shared_fastpair_info_received_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +#endif + +bool app_tws_is_master_mode(void); +bool app_tws_is_slave_mode(void); +bool app_tws_is_freeman_mode(void); +void app_ibrt_sync_volume_info(void); +bool app_tws_is_left_side(void); +bool app_tws_is_right_side(void); +bool app_tws_is_unknown_side(void); +void app_tws_set_side_from_addr(uint8_t *addr); +bool app_tws_nv_is_master_role(void); +void app_tws_set_side_from_gpio(void); + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __APP_TWS_IF_H__ */ diff --git a/services/app_tws/src/app_tws_if.cpp b/services/app_tws/src/app_tws_if.cpp new file mode 100644 index 0000000..12ae076 --- /dev/null +++ b/services/app_tws/src/app_tws_if.cpp @@ -0,0 +1,710 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +/*****************************header include********************************/ +#include "cmsis.h" +#include "hal_trace.h" +#include "me_api.h" +#include "besbt.h" +#include "app.h" +#include "app_sec.h" +#include "app_tws_ctrl_thread.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_if.h" +#include "app_ibrt_ui.h" +#include "btapp.h" +#include "nvrecord_env.h" +#include "nvrecord_extension.h" +#include "nvrecord_ble.h" +#include "app_ai_if.h" +#include "app_ai_tws.h" +#include "app_ai_manager_api.h" +#include "app_bt.h" +#include "app_bt_func.h" +#include "app_dip.h" +#include "app_bt_stream.h" +#include "tgt_hardware.h" +#ifdef __THIRDPARTY +#include "app_thirdparty.h" +#endif + +#ifdef IBRT +#include "app_ibrt_customif_cmd.h" +#include "app_ibrt_if.h" +#include "app_ibrt_customif_ui.h" +#endif + +#ifdef BLE_ENABLE +#include "app_ble_include.h" +#endif + +#ifdef OTA_ENABLED +#include "ota_common.h" +#endif + +#ifdef BISTO_ENABLED +#include "gsound_custom.h" +#include "gsound_custom_tws.h" +#endif + +#ifdef __AI_VOICE__ +#include "ai_thread.h" +#endif + +#ifdef IBRT_OTA +#include "ota_control.h" +#endif + +#ifdef IS_MULTI_AI_ENABLED +#include "ai_manager.h" +#endif + +#ifdef GFPS_ENABLED +#include "nvrecord_fp_account_key.h" +#include "app_gfps.h" +#endif + +#ifdef __GMA_VOICE__ +#include "app_gma_ota.h" +#endif + + +/************************private macro defination***************************/ + +/************************private struct defination****************************/ + +/**********************private function declearation************************/ + +/************************private variable defination************************/ +static TWS_ENV_T twsEnv; +static TWS_SYNC_DATA_T twsSyncBuf; + +osMutexId twsSyncBufMutexId = NULL; +osMutexDef(twsSyncBufMutex); + +#define POST_ROLESWITCH_STATE_STAYING_MS 15000 +osTimerId app_post_roleswitch_handling_timer_id = NULL; +static int app_post_roleswitch_handling_timer_handler(void const *param); +osTimerDef (APP_POST_ROLESWITCH_HANDLING_TIMER, (void (*)(void const *))app_post_roleswitch_handling_timer_handler); // define timers + + +/****************************function defination****************************/ +extern int hfp_volume_get(enum BT_DEVICE_ID_T id); +extern int a2dp_volume_get(enum BT_DEVICE_ID_T id); +static const char *tws_sync_user2str(TWS_SYNC_USER_E user) +{ + const char *str = NULL; +#define CASES(user) \ + case user: \ + str = "[" #user "]"; \ + break + + switch (user) + { + CASES(TWS_SYNC_USER_BLE_INFO); + CASES(TWS_SYNC_USER_OTA); + CASES(TWS_SYNC_USER_AI_CONNECTION); + CASES(TWS_SYNC_USER_GFPS_INFO); + CASES(TWS_SYNC_USER_AI_INFO); + CASES(TWS_SYNC_USER_AI_MANAGER); + CASES(TWS_SYNC_USER_DIP); + + default: + str = "[INVALID]"; + break; + } + + return str; +} + +void app_tws_if_init(void) +{ + // reset the environment + memset(&twsEnv, 0, sizeof(twsEnv)); + memset(&twsSyncBuf, 0, TWS_SYNC_BUF_SIZE); + + // init the tws sync buffer mutex + if (NULL == twsSyncBufMutexId) + { + twsSyncBufMutexId = osMutexCreate(osMutex(twsSyncBufMutex)); + } + + // register all users +#ifdef BLE_ENABLE + // init ble tws interface + app_ble_mode_tws_sync_init(); +#endif + +#ifdef OTA_ENABLED + ota_common_tws_sync_init(); +#endif + +#ifdef BISTO_ENABLED + // init gsound tws interface + app_ai_tws_gsound_sync_init(); +#endif + +#ifdef GFPS_ENABLED + app_gfps_tws_sync_init(); +#endif + +#ifdef __AI_VOICE__ + app_ai_tws_sync_init(); +#endif + +#ifdef IS_MULTI_AI_ENABLED + ai_manager_sync_init(); +#endif + +#ifdef BTIF_DIP_DEVICE + app_dip_sync_init(); +#endif +} + +void app_tws_if_role_switch_started_handler(void) +{ + TRACE(1,"[%s]+++", __func__); + if (NULL == app_post_roleswitch_handling_timer_id) + { + app_post_roleswitch_handling_timer_id = + osTimerCreate(osTimer(APP_POST_ROLESWITCH_HANDLING_TIMER), osTimerOnce, NULL); + } + + osTimerStop(app_post_roleswitch_handling_timer_id); + + app_bt_active_mode_clear(ACTIVE_MODE_KEEPER_ROLE_SWITCH, UPDATE_ACTIVE_MODE_FOR_ALL_LINKS); + + TRACE(1,"[%s]---", __func__); +} + +static int app_post_roleswitch_handling_timer_handler(void const *param) +{ + app_bt_start_custom_function_in_bt_thread( + ACTIVE_MODE_KEEPER_ROLE_SWITCH, + UPDATE_ACTIVE_MODE_FOR_ALL_LINKS, + (uint32_t)app_bt_active_mode_clear); + return 0; +} + +static void app_tws_if_post_roleswitch_handler(void) +{ + if (NULL == app_post_roleswitch_handling_timer_id) + { + app_post_roleswitch_handling_timer_id = + osTimerCreate(osTimer(APP_POST_ROLESWITCH_HANDLING_TIMER), osTimerOnce, NULL); + } + + osTimerStart(app_post_roleswitch_handling_timer_id, POST_ROLESWITCH_STATE_STAYING_MS); + // keep bt link in active mode right after role switch + app_bt_active_mode_set(ACTIVE_MODE_KEEPER_ROLE_SWITCH, UPDATE_ACTIVE_MODE_FOR_ALL_LINKS); +} + +void app_tws_if_tws_role_switch_complete_handler(uint8_t newRole) +{ + TRACE(2,"[%s]+++ role %d", __func__, newRole); + +#ifdef BISTO_ENABLED + gsound_on_system_role_switch_done(newRole); +#endif + + // update BLE info saved in flash after role switch complete + nv_record_tws_exchange_ble_info(); + +#ifdef BLE_USE_RPA + appm_refresh_ble_irk(); +#else + btif_me_set_ble_bd_address(bt_get_ble_local_address()); +#endif + +#ifdef __AI_VOICE__ + app_ai_tws_role_switch_complete(); +#endif + +#ifdef BLE_ENABLE + ble_callback_evnet_t event; + event.evt_type = BLE_CALLBACK_RS_COMPLETE; + event.p.rs_complete_handled.newRole = newRole; + app_ble_core_global_callback_event(&event, NULL); +#endif + + app_tws_if_post_roleswitch_handler(); + + TRACE(1,"[%s]---", __func__); + +#ifdef IBRT_OTA + ota_control_send_role_switch_complete(); +#endif +} + +void app_tws_if_register_sync_user(uint8_t id, TWS_SYNC_USER_T *user) +{ + memcpy(&twsEnv.syncUser[id], user, sizeof(TWS_SYNC_USER_T)); +} + +void app_tws_if_deregister_sync_user(uint8_t id) +{ + memset(&twsEnv.syncUser[id], 0, sizeof(TWS_SYNC_USER_T)); +} + +void app_tws_if_sync_info(TWS_SYNC_USER_E id) +{ + TRACE(1,"[%s]+++", __func__); + TRACE(1,"user:%s", tws_sync_user2str(id)); + + osMutexWait(twsSyncBufMutexId, osWaitForever); + if (twsEnv.syncUser[id].sync_info_prepare_handler) + { + uint16_t length = 0; + twsEnv.syncUser[id].sync_info_prepare_handler(twsSyncBuf.info, &length); + + if (length) + { + twsSyncBuf.userId = id; + length++; + + tws_ctrl_send_cmd(APP_TWS_CMD_SHARE_COMMON_INFO, ( uint8_t * )&twsSyncBuf, length); + } + else + { + TRACE(0,"no info to sync"); + } + } + else + { + TRACE(0,"prepare handler is null pointer"); + } + osMutexRelease(twsSyncBufMutexId); + + TRACE(1,"[%s]---", __func__); +} + +void app_tws_if_sync_info_received_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"[%s]+++", __func__); + + TWS_SYNC_DATA_T *pInfo = ( TWS_SYNC_DATA_T * )p_buff; + TRACE(1,"user:%s", tws_sync_user2str(pInfo->userId)); + + // handle received data + if (twsEnv.syncUser[pInfo->userId].sync_info_received_handler) + { + twsEnv.syncUser[pInfo->userId].sync_info_received_handler(pInfo->info, (length - 1)); + } + + // send response to peer device + uint16_t len = 0; + osMutexWait(twsSyncBufMutexId, osWaitForever); + + if (twsEnv.syncUser[pInfo->userId].sync_info_prepare_rsp_handler) + { + twsEnv.syncUser[pInfo->userId].sync_info_prepare_rsp_handler(twsSyncBuf.info, &len); + } + + twsSyncBuf.userId = pInfo->userId; + len++; + + tws_ctrl_send_rsp(APP_TWS_CMD_SHARE_COMMON_INFO, + rsp_seq, + ( uint8_t * )&twsSyncBuf, + len); + osMutexRelease(twsSyncBufMutexId); + + TRACE(1,"[%s]---", __func__); +} + +void app_tws_if_sync_info_rsp_received_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"[%s]+++", __func__); + + TWS_SYNC_DATA_T *pInfo = ( TWS_SYNC_DATA_T * )p_buff; + + // handle received data + if (twsEnv.syncUser[pInfo->userId].sync_info_rsp_received_handler) + { + twsEnv.syncUser[pInfo->userId].sync_info_rsp_received_handler(pInfo->info, (length - 1)); + } + + TRACE(1,"[%s]---", __func__); +} + +void app_tws_if_sync_info_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"[%s]+++", __func__); + + TWS_SYNC_DATA_T *pInfo = ( TWS_SYNC_DATA_T * )p_buff; + + if (twsEnv.syncUser[pInfo->userId].sync_info_rsp_timeout_handler) + { + twsEnv.syncUser[pInfo->userId].sync_info_rsp_timeout_handler(pInfo->info, (length - 1)); + } + + TRACE(1,"[%s]---", __func__); +} + +void app_tws_if_tws_role_updated_handler(uint8_t newRole) +{ +#ifdef BLE_ENABLE + ble_callback_evnet_t event; + event.evt_type = BLE_CALLBACK_ROLE_UPDATE; + event.p.role_update_handled.newRole = newRole; + app_ble_core_global_callback_event(&event, NULL); +#endif + +#if defined(BISTO_ENABLED) && defined(IBRT) + gsound_on_tws_role_updated(newRole); +#endif +} + +void app_tws_if_tws_connected_sync_info(void) +{ + TRACE(2,"[%s]+++ role %d", __func__, app_tws_ibrt_role_get_callback(NULL)); + + if (IBRT_MASTER == app_tws_ibrt_role_get_callback(NULL)) + { + // inform peer to update the common info + app_tws_if_sync_info(TWS_SYNC_USER_BLE_INFO); + app_tws_if_sync_info(TWS_SYNC_USER_OTA); + // app_tws_if_sync_info(TWS_SYNC_USER_AI_CONNECTION); + app_tws_if_sync_info(TWS_SYNC_USER_GFPS_INFO); + app_tws_if_sync_info(TWS_SYNC_USER_AI_INFO); + app_tws_if_sync_info(TWS_SYNC_USER_AI_MANAGER); + app_tws_if_sync_info(TWS_SYNC_USER_DIP); + +#ifdef GFPS_ENABLED + if (!app_tws_ibrt_mobile_link_connected()) + { + app_enter_fastpairing_mode(); + } +#endif + } + + TRACE(1,"[%s]---", __func__); +} + +void app_tws_if_tws_connected_handler(void) +{ + TRACE(1, "twsif_tws_connected, role %d", app_tws_ibrt_role_get_callback(NULL)); +} + +void app_tws_if_tws_disconnected_handler(void) +{ + TRACE(0, "twsif_tws_disconnected."); + +#ifdef IBRT + if (IBRT_SLAVE == app_tws_ibrt_role_get_callback(NULL)) + { +#ifdef BISTO_ENABLED + gsound_set_ble_connect_state(GSOUND_CHANNEL_AUDIO, false); + gsound_set_ble_connect_state(GSOUND_CHANNEL_CONTROL, false); +#endif + } +#ifdef __GMA_VOICE__ + app_gma_ota_exception_reboot(); // shuailong +#endif +#endif +} + +void app_tws_if_mobile_connected_handler(uint8_t *addr) +{ + TRACE(0, "twsif_mobile_connected"); + +#ifdef IBRT + if (IBRT_MASTER == app_tws_ibrt_role_get_callback(NULL)) +#endif + { + // inform peer to update the common info + // app_tws_if_sync_info(TWS_SYNC_USER_AI_CONNECTION); + app_tws_if_sync_info(TWS_SYNC_USER_GFPS_INFO); + } +} + +void app_tws_if_mobile_disconnected_handler(uint8_t *addr) +{ + TRACE(0, "twsif_mobile_disconnected"); +} + +void app_tws_if_ibrt_connected_handler(void) +{ + TRACE(0, "twsif_ibrt_connected"); + +#ifdef IBRT + if (IBRT_MASTER == app_tws_ibrt_role_get_callback(NULL)) +#endif + { + // inform peer to update the common info + app_tws_if_sync_info(TWS_SYNC_USER_AI_INFO); + app_tws_if_sync_info(TWS_SYNC_USER_AI_MANAGER); + } +} + +void app_tws_if_ibrt_disconnected_handler(void) +{ + TRACE(0, "twsif_ibrt_disconnected"); +} + +void app_tws_if_ble_connected_handler(void) +{ + TRACE(0, "twsif_ble_connected"); + +#ifdef IBRT + if (IBRT_MASTER == app_tws_ibrt_role_get_callback(NULL)) +#endif + { + // inform peer to update the common info + //app_tws_if_sync_info(TWS_SYNC_USER_BLE_INFO); + app_tws_if_sync_info(TWS_SYNC_USER_OTA); + // app_tws_if_sync_info(TWS_SYNC_USER_AI_CONNECTION); + app_tws_if_sync_info(TWS_SYNC_USER_GFPS_INFO); + } +} + +void app_tws_if_ble_disconnected_handler(void) +{ + TRACE(0, "twsif_ble_disconnected"); + +#ifdef IBRT + if (IBRT_MASTER == app_tws_ibrt_role_get_callback(NULL)) +#endif + { + // inform peer to update the common info + // app_tws_if_sync_info(TWS_SYNC_USER_AI_CONNECTION); + } +} + +void app_tws_if_trigger_role_switch(void) +{ + if (false == app_ibrt_ui_can_tws_switch()) + { + TRACE(1,"%s can't switch", __func__); + return; + } + + app_ibrt_customif_ui_tws_switch(); +} + +void app_tws_if_handle_click(void) +{ + TRACE(1,"%s", __func__); + +#if defined(BISTO_ENABLED) || defined(__AI_VOICE__) + app_tws_if_trigger_role_switch(); +#else + bt_key_handle_func_click(); +#endif +} + +#ifdef IBRT +void app_tws_if_ai_send_cmd_to_peer(uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"[%s]", __func__); + + tws_ctrl_send_cmd(APP_TWS_CMD_AI_SEND_CMD_TO_PEER, p_buff, length); +} + +void app_tws_if_ai_rev_peer_cmd_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"[%s]", __func__); + +#ifdef __AI_VOICE__ + app_ai_tws_rev_peer_cmd_hanlder(rsp_seq, p_buff, length); +#endif +} + +void app_tws_if_ai_send_cmd_with_rsp_to_peer(uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"[%s]", __func__); + + tws_ctrl_send_cmd(APP_TWS_CMD_AI_SEND_CMD_TO_PEER_WITH_RSP, p_buff, length); +} + +void app_tws_if_ai_send_cmd_rsp_to_peer(uint8_t *p_buff, uint16_t rsp_seq, uint16_t length) +{ + TRACE(1,"[%s]", __func__); + + tws_ctrl_send_rsp(APP_TWS_CMD_AI_SEND_CMD_TO_PEER_WITH_RSP, rsp_seq, p_buff, length); +} + +void app_tws_if_ai_rev_peer_cmd_with_rsp_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"[%s]", __func__); + +#ifdef __AI_VOICE__ + app_ai_tws_rev_peer_cmd_with_rsp_hanlder(rsp_seq, p_buff, length); +#endif +} + +void app_tws_if_ai_rev_cmd_rsp_from_peer_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"[%s]", __func__); + +#ifdef __AI_VOICE__ + app_ai_tws_rev_cmd_rsp_from_peer_hanlder(rsp_seq, p_buff, length); +#endif +} + +void app_tws_if_ai_rev_cmd_rsp_timeout_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + TRACE(1,"[%s]", __func__); + +#ifdef __AI_VOICE__ + app_ai_tws_rev_cmd_rsp_timeout_hanlder(rsp_seq, p_buff, length); +#endif +} + +void app_tws_if_master_prepare_rs(uint8_t *p_buff, uint16_t length) +{ +#ifdef BLE_ENABLE + ble_callback_evnet_t event; + event.evt_type = BLE_CALLBACK_RS_START; + app_ble_core_global_callback_event(&event, NULL); +#endif +#ifdef BISTO_ENABLED + if (*p_buff == AI_SPEC_GSOUND) + { + gsound_tws_update_roleswitch_initiator(IBRT_SLAVE); + gsound_tws_request_roleswitch(); + } +#endif +#ifdef __AI_VOICE__ + if (*p_buff != AI_SPEC_GSOUND) + { + app_ai_tws_master_role_switch_prepare(); + } +#endif +} + +void app_tws_if_slave_continue_rs(uint8_t *p_buff, uint16_t length) +{ + TRACE(2,"%s len %d", __func__, length); + DUMP8("%x ", p_buff, length); + +#ifdef __AI_VOICE__ + if (*p_buff != AI_SPEC_GSOUND) + { + app_ai_tws_role_switch_prepare_done(); + } + else +#endif + { + app_ibrt_if_tws_switch_prepare_done_in_bt_thread(IBRT_ROLE_SWITCH_USER_AI, (uint32_t)*p_buff); + } +} +#endif + +#if defined(GFPS_ENABLED) && defined(IBRT) +void app_ibrt_share_fastpair_info(uint8_t *p_buff, uint16_t length) +{ + app_ibrt_send_cmd_without_rsp(APP_TWS_CMD_SHARE_FASTPAIR_INFO, p_buff, length); +} + +void app_tws_send_fastpair_info_to_slave(void) +{ + TRACE(0,"Send fastpair info to secondary device."); + NV_FP_ACCOUNT_KEY_RECORD_T *pFpData = nv_record_get_fp_data_structure_info(); + app_ibrt_share_fastpair_info(( uint8_t * )pFpData, sizeof(NV_FP_ACCOUNT_KEY_RECORD_T)); +} + +void app_ibrt_shared_fastpair_info_received_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length) +{ + NV_FP_ACCOUNT_KEY_RECORD_T *pFpData = ( NV_FP_ACCOUNT_KEY_RECORD_T * )p_buff; + nv_record_update_fp_data_structure(pFpData); +} +#endif + +#ifdef IBRT +bool app_tws_is_master_mode(void) +{ + return (IBRT_MASTER == app_tws_ibrt_role_get_callback(NULL))?true:false; +} + +bool app_tws_is_slave_mode(void) +{ + return (IBRT_SLAVE == app_tws_ibrt_role_get_callback(NULL))?true:false; +} + +bool app_tws_is_freeman_mode(void) +{ + return (IBRT_UNKNOW == app_tws_ibrt_role_get_callback(NULL))?true:false; +} + +bool app_tws_nv_is_master_role(void) +{ + TRACE(1, "[ZYH]%s -> %d",__func__,app_tws_ibrt_nv_role_get_callback(NULL)); + return (IBRT_MASTER == app_tws_ibrt_nv_role_get_callback(NULL))?true:false; +} + + +void app_ibrt_sync_volume_info(void) +{ + if(app_tws_ibrt_tws_link_connected()) + { + ibrt_volume_info_t ibrt_volume_req; + ibrt_volume_req.a2dp_volume = a2dp_volume_get(BT_DEVICE_ID_1); + ibrt_volume_req.hfp_volume = hfp_volume_get(BT_DEVICE_ID_1); + tws_ctrl_send_cmd(APP_TWS_CMD_SYNC_VOLUME_INFO,(uint8_t*)&ibrt_volume_req, sizeof(ibrt_volume_req)); + } +} + +static APP_TWS_SIDE_T app_tws_side = EAR_SIDE_UNKNOWN; + +void app_tws_set_side(APP_TWS_SIDE_T side) +{ + ASSERT((EAR_SIDE_LEFT == side) || (EAR_SIDE_RIGHT == side), "Error: setting invalid side"); + app_tws_side = side; +} + +bool app_tws_is_left_side(void) +{ + return (app_tws_side == EAR_SIDE_LEFT); +} + +bool app_tws_is_right_side(void) +{ + return (app_tws_side == EAR_SIDE_RIGHT); +} + +bool app_tws_is_unknown_side(void) +{ + return (app_tws_side == EAR_SIDE_UNKNOWN); +} + +void app_tws_set_side_from_addr(uint8_t *addr) +{ + ASSERT(addr, "Error: address invalid"); + if (addr[0] & 0x1) { + app_tws_set_side(EAR_SIDE_RIGHT); + TRACE(0, "Right earbud"); + } else { + app_tws_set_side(EAR_SIDE_LEFT); + TRACE(0, "Left earbud"); + } +} + +void app_tws_set_side_from_gpio(void) +{ + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&cfg_hw_tws_channel_cfg, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)cfg_hw_tws_channel_cfg.pin, HAL_GPIO_DIR_IN, 1); + if (tgt_tws_get_channel_is_right()) { + app_tws_set_side(EAR_SIDE_RIGHT); + TRACE(0, "Right earbud"); + } else { + app_tws_set_side(EAR_SIDE_LEFT); + TRACE(0, "Left earbud"); + } +} + +#endif + diff --git a/services/audio_dump/Makefile b/services/audio_dump/Makefile new file mode 100644 index 0000000..650108a --- /dev/null +++ b/services/audio_dump/Makefile @@ -0,0 +1,15 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.c)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -Iservices/tota \ + -Iservices/audio_dump/include + diff --git a/services/audio_dump/include/audio_dump.h b/services/audio_dump/include/audio_dump.h new file mode 100644 index 0000000..bee8707 --- /dev/null +++ b/services/audio_dump/include/audio_dump.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __AUDIO_DUMP_H__ +#define __AUDIO_DUMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef AUDIO_DEBUG +#define AUDIO_DUMP +#endif + +void audio_dump_init(int frame_len, int sample_bytes, int channel_num); +void audio_dump_deinit(void); +void audio_dump_clear_up(void); +void audio_dump_add_channel_data_from_multi_channels(int channel_id, void *pcm_buf, int pcm_len, int channel_num, int channel_index); +void audio_dump_add_channel_data(int channel_id, void *pcm_buf, int pcm_len); +void audio_dump_run(void); + +void data_dump_init(void); +void data_dump_deinit(void); +void data_dump_run(const char *str, void *data_buf, uint32_t data_len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/audio_dump/src/audio_dump.c b/services/audio_dump/src/audio_dump.c new file mode 100644 index 0000000..dabfe31 --- /dev/null +++ b/services/audio_dump/src/audio_dump.c @@ -0,0 +1,278 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_trace.h" +#include "audio_dump.h" +#include "string.h" + +#ifdef AUDIO_DEBUG_V0_1_0 + +// #define DATA_DUMP_TOTA +// #define DUMP_PLC_ENABLE + +#ifdef DATA_DUMP_TOTA +#include "app_tota_audio_dump.h" +#endif + +#ifdef AUDIO_DUMP +#define AUDIO_DUMP_HEAD_STR ("[audio dump]") +#define AUDIO_DUMP_HEAD_LEN (sizeof(AUDIO_DUMP_HEAD_STR)-1) +#define AUDIO_DUMP_INDEX_LEN (4) +#define AUDIO_DUMP_CRC_LEN (4) +#define AUDIO_DUMP_DATA_LEN (4) +#define AUDIO_DUMP_MAX_SAMPLE_BYTES (sizeof(int)) +#define AUDIO_DUMP_MAX_FRAME_LEN (512) +#define AUDIO_DUMP_MAX_CHANNEL_NUM (8) +#define AUDIO_DUMP_MAX_DATA_SIZE (AUDIO_DUMP_MAX_FRAME_LEN * AUDIO_DUMP_MAX_CHANNEL_NUM * AUDIO_DUMP_MAX_SAMPLE_BYTES / sizeof(char)) +#define AUDIO_DUMP_BUFFER_SIZE (AUDIO_DUMP_HEAD_LEN + AUDIO_DUMP_INDEX_LEN + AUDIO_DUMP_CRC_LEN + AUDIO_DUMP_DATA_LEN + AUDIO_DUMP_MAX_DATA_SIZE) + +static int audio_dump_index = 0; +static int audio_dump_crc = 0; +static int audio_dump_frame_len = 256; +static int audio_dump_sample_bytes = sizeof(short) / sizeof(char); +static int audio_dump_channel_num = 2; +static int audio_dump_data_size = 0; +static int audio_dump_buf_size = 0; +static char *audio_dump_data_ptr = NULL; +static char audio_dump_buf[AUDIO_DUMP_BUFFER_SIZE]; +#endif + +void audio_dump_clear_up(void) +{ +#ifdef AUDIO_DUMP + memset(audio_dump_data_ptr, 0, audio_dump_data_size); +#endif +} + +void audio_dump_init(int frame_len, int sample_bytes, int channel_num) +{ +#ifdef AUDIO_DUMP + ASSERT(frame_len <= AUDIO_DUMP_MAX_FRAME_LEN, "[%s] frame_len(%d) is invalid", __func__, frame_len); + ASSERT(sample_bytes <= AUDIO_DUMP_MAX_SAMPLE_BYTES, "[%s] sample_bytes(%d) is invalid", __func__, sample_bytes); + ASSERT(channel_num <= AUDIO_DUMP_MAX_CHANNEL_NUM, "[%s] channel_num(%d) is invalid", __func__, channel_num); + + char *buf_ptr = audio_dump_buf; + audio_dump_index = 0; + audio_dump_crc = 0; + audio_dump_frame_len = frame_len; + audio_dump_sample_bytes = sample_bytes / sizeof(char); + audio_dump_channel_num = channel_num; + + memcpy(buf_ptr, AUDIO_DUMP_HEAD_STR, AUDIO_DUMP_HEAD_LEN); + +#ifdef DUMP_PLC_ENABLE + buf_ptr += AUDIO_DUMP_HEAD_LEN + AUDIO_DUMP_INDEX_LEN + AUDIO_DUMP_CRC_LEN; +#else + buf_ptr += AUDIO_DUMP_HEAD_LEN; +#endif + + int *data_len = (int *)buf_ptr; + *data_len = frame_len * channel_num * audio_dump_sample_bytes; + audio_dump_data_size = *data_len; +#ifdef DUMP_PLC_ENABLE + audio_dump_buf_size = AUDIO_DUMP_HEAD_LEN + AUDIO_DUMP_INDEX_LEN + AUDIO_DUMP_CRC_LEN + AUDIO_DUMP_DATA_LEN + audio_dump_data_size; +#else + audio_dump_buf_size = AUDIO_DUMP_HEAD_LEN + AUDIO_DUMP_DATA_LEN + audio_dump_data_size; +#endif + + buf_ptr += AUDIO_DUMP_DATA_LEN; + + audio_dump_data_ptr = buf_ptr; + + audio_dump_clear_up(); +#endif +} + +void audio_dump_deinit(void) +{ + ; +} + +void audio_dump_add_channel_data_from_multi_channels(int channel_id, void *pcm_buf, int pcm_len, int channel_num, int channel_index) +{ +#ifdef AUDIO_DUMP + ASSERT(audio_dump_frame_len >= pcm_len, "[%s] frame_len(%d) < pcm_len(%d)", __func__, audio_dump_frame_len, pcm_len); + + if (channel_id >= audio_dump_channel_num) + { + return; + } + + if (audio_dump_sample_bytes == sizeof(short)) + { + short *_pcm_buf = (short *)pcm_buf; + short *_dump_buf = (short *)audio_dump_data_ptr; + + for (int i = 0; i < pcm_len; i++) + { + _dump_buf[audio_dump_channel_num * i + channel_id] = _pcm_buf[i * channel_num + channel_index]; + } + } + else if (audio_dump_sample_bytes == sizeof(int)) + { + int *_pcm_buf = (int *)pcm_buf; + int *_dump_buf = (int *)audio_dump_data_ptr; + + for (int i = 0; i < pcm_len; i++) + { + _dump_buf[audio_dump_channel_num * i + channel_id] = _pcm_buf[i * channel_num + channel_index]; + } + } + else + { + ASSERT(0, "[%s] audio_dump_sample_bytes(%d) is invalid", __func__, audio_dump_sample_bytes); + } +#endif +} + +void audio_dump_add_channel_data(int channel_id, void *pcm_buf, int pcm_len) +{ + audio_dump_add_channel_data_from_multi_channels(channel_id, pcm_buf, pcm_len, 1, 0); +} + +#ifdef DUMP_PLC_ENABLE +static void audio_debug_add_index(void) +{ + int *index_ptr = (int *)(audio_dump_buf + AUDIO_DUMP_HEAD_LEN); + + *index_ptr = audio_dump_index; +} + +// unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len) +// { +// unsigned long c; + +// c = crc ^ 0xffffffffL; + +// while (len) +// { +// c = crc_table[(c ^ (*buf++)) & 0xff] ^ (c >> 8); +// len--; +// } + +// return c ^ 0xffffffffL; +// } + +static void audio_debug_add_crc(void) +{ + int *crc_ptr = (int *)(audio_dump_buf + AUDIO_DUMP_HEAD_LEN + AUDIO_DUMP_CRC_LEN); + + *crc_ptr = 0; +} +#endif + +void audio_dump_run(void) +{ +#ifdef AUDIO_DUMP +#ifdef DATA_DUMP_TOTA + int offset = AUDIO_DUMP_HEAD_LEN + AUDIO_DUMP_DATA_LEN; + +#ifdef DUMP_PLC_ENABLE + offset += AUDIO_DUMP_INDEX_LEN + AUDIO_DUMP_CRC_LEN; +#endif + + app_tota_audio_dump_send((uint8_t *)&audio_dump_buf[offset], audio_dump_buf_size - offset); +#else +#ifdef DUMP_PLC_ENABLE + audio_debug_add_index(); + audio_debug_add_crc(); + audio_dump_index++; + + // if (audio_dump_index % 20 == 0) + // { + // audio_dump_index++; + // } +#endif + AUDIO_DEBUG_DUMP((const unsigned char *)audio_dump_buf, audio_dump_buf_size); +#endif +#endif +} + +#ifdef AUDIO_DUMP +// Make sure DATA_DUMP_BUF_SIZE < TRACE_BUF_SIZE +#define DATA_DUMP_BUF_SIZE (1024 * 6) +static uint8_t data_dump_buf[DATA_DUMP_BUF_SIZE]; + +static int data_dump_index = 0; +#endif + +void data_dump_init(void) +{ +#ifdef AUDIO_DUMP + data_dump_index = 0; +#endif +} + +void data_dump_deinit(void) +{ + ; +} + +void data_dump_run(const char *str, void *data_buf, uint32_t data_len) +{ +#ifdef AUDIO_DUMP + uint8_t *buf_ptr = data_dump_buf; + uint32_t len = 0; + + // head + memcpy(buf_ptr + len, str, strlen(str)); + len += strlen(str); + +#ifdef DUMP_PLC_ENABLE + int32_t *int_ptr = NULL; + + // index + int_ptr = (int32_t *)(buf_ptr + len); + *int_ptr = data_dump_index; + len += sizeof(int32_t); + + // crc + int_ptr = (int32_t *)(buf_ptr + len); + *int_ptr = 0; + len += sizeof(int32_t); + + data_dump_index++; + + // if (data_dump_index % 20 == 0) + // { + // data_dump_index++; + // } +#endif + + // length + memcpy(buf_ptr + len, &data_len, sizeof(uint32_t)); + len += sizeof(uint32_t); + + // data + memcpy(buf_ptr + len, (uint8_t *)data_buf, data_len); + len += data_len; + + ASSERT(len < DATA_DUMP_BUF_SIZE, "[%s] len(%d) > DATA_DUMP_BUF_SIZE", __func__, len); + + // TRACE(5,"[%s] %d, %d, %d, %d", __func__, strlen(str), sizeof(uint32_t), data_len, len); + AUDIO_DEBUG_DUMP(buf_ptr, len); +#endif +} +#else // AUDIO_DEBUG +void audio_dump_clear_up(void) {;} +void audio_dump_init(int frame_len, int sample_bytes, int channel_num) {;} +void audio_dump_deinit(void) {;} +void audio_dump_add_channel_data_from_multi_channels(int channel_id, void *pcm_buf, int pcm_len, int channel_num, int channel_index) {;} +void audio_dump_add_channel_data(int channel_id, void *pcm_buf, int pcm_len) {;} +void audio_dump_run(void) {;} +void data_dump_init(void) {;} +void data_dump_deinit(void) {;} +void data_dump_run(const char *str, void *data_buf, uint32_t data_len) {;} +#endif diff --git a/services/audio_process/Makefile b/services/audio_process/Makefile new file mode 100644 index 0000000..ae360f2 --- /dev/null +++ b/services/audio_process/Makefile @@ -0,0 +1,75 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/audio/process/common/include \ + -Iservices/multimedia/audio/process/drc/include \ + -Iservices/multimedia/audio/process/limiter/include \ + -Iservices/multimedia/speech/inc \ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/include \ + -Iutils/heap/ + +ifeq ($(HW_FIR_EQ_PROCESS),1) +ccflags-y += -D__HW_FIR_EQ_PROCESS__ +endif + +ifeq ($(HW_IIR_EQ_PROCESS),1) +ccflags-y += -D__HW_IIR_EQ_PROCESS__ +endif + +ifeq ($(SW_IIR_EQ_PROCESS),1) +ccflags-y += -D__SW_IIR_EQ_PROCESS__ +endif + +ifeq ($(AUDIO_DRC),1) +ccflags-y += -D__AUDIO_DRC__ +endif + +ifeq ($(AUDIO_DRC2),1) +ccflags-y += -D__AUDIO_DRC2__ +endif + +ifeq ($(AUDIO_RESAMPLE),1) +ccflags-y += -D__AUDIO_RESAMPLE__ +endif + +ifeq ($(HW_DAC_IIR_EQ_PROCESS),1) +ccflags-y += -D__HW_DAC_IIR_EQ_PROCESS__ +ifneq ($(filter best2300p best1400 best3001 best2300 best2000 best1000,$(CHIP)),) +ifneq ($(CHIP_SUBTYPE),best1402) +ifeq ($(ANC_APP),1) +$(error "error: ANC and Hardware codec iir can't be used in the same") +endif +endif +endif +endif + +ifeq ($(FIR_HIGHSPEED),1) +ccflags-y += -DFIR_HIGHSPEED +endif + +ifeq ($(PC_CMD_UART),1) +CFLAGS_audio_process.o += -D__PC_CMD_UART__ +endif + +ifeq ($(USB_AUDIO_APP), 1) +CFLAGS_audio_process.o += -DUSB_AUDIO_APP +endif + +ifeq ($(SPEECH_LIB),1) +CFLAGS_audio_spectrum.o += -DSPEECH_LIB +endif + +ifeq ($(USB_EQ_TUNING), 1) +ccflags-y += -DUSB_EQ_TUNING +endif + +CFLAGS_audio_spectrum.o += -DUSE_MED_MALLOC diff --git a/services/audio_process/audio_cfg.c b/services/audio_process/audio_cfg.c new file mode 100644 index 0000000..454dc99 --- /dev/null +++ b/services/audio_process/audio_cfg.c @@ -0,0 +1,110 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "audio_cfg.h" +#include "iir_process.h" +#include "drc.h" +#include "limiter.h" +#include "aud_section.h" +#include "string.h" +#include "hal_trace.h" + + +#define TOOL_SUPPORT_MAX_IIR_EQ_BAND_NUM (20) + +struct AUDIO_CFG_T_{ + IIR_CFG_T iir_eq; // Now just support one type + IIR_PARAM_T reserved[TOOL_SUPPORT_MAX_IIR_EQ_BAND_NUM - IIR_PARAM_NUM]; + DrcConfig drc; + LimiterConfig limiter; +}; + +typedef struct { + uint8_t reserved[AUDIO_SECTION_CFG_RESERVED_LEN]; + AUDIO_CFG_T cfg; +} AUDIO_SECTION_AUDIO_CFG_T; + +static AUDIO_SECTION_AUDIO_CFG_T audio_section_audio_cfg; + +// Can not use sizeof(AUDIO_CFG_T), so define this function +int sizeof_audio_cfg(void) +{ + return sizeof(AUDIO_CFG_T); +} + +int store_audio_cfg_into_audio_section(AUDIO_CFG_T *cfg) +{ + int res = 0; + + memcpy(&audio_section_audio_cfg.cfg, cfg, sizeof(AUDIO_CFG_T)); + + res = audio_section_store_cfg(AUDIO_SECTION_DEVICE_AUDIO, + (uint8_t *)&audio_section_audio_cfg, + sizeof(AUDIO_SECTION_AUDIO_CFG_T)); + + + if(res) + { + TRACE(2,"[%s] ERROR: res = %d", __func__, res); + } + else + { + TRACE(1,"[%s] Store audio cfg into audio section!!!", __func__); + } + + return res; +} + +void *load_audio_cfg_from_audio_section(enum AUDIO_PROCESS_TYPE_T type) +{ + ASSERT(type < AUDIO_PROCESS_TYPE_NUM, "[%s] type(%d) is invalid", __func__, type); + int res = 0; + res = audio_section_load_cfg(AUDIO_SECTION_DEVICE_AUDIO, + (uint8_t *)&audio_section_audio_cfg, + sizeof(AUDIO_SECTION_AUDIO_CFG_T)); + + void *res_ptr = NULL; + + if (res) + { + TRACE(2,"[%s] ERROR: res = %d", __func__, res); + res_ptr = NULL; + } + else + { + if (type == AUDIO_PROCESS_TYPE_IIR_EQ) + { + TRACE(1,"[%s] Load iir_eq from audio section!!!", __func__); + res_ptr = (void *)&audio_section_audio_cfg.cfg.iir_eq; + } + else if (type == AUDIO_PROCESS_TYPE_DRC) + { + TRACE(1,"[%s] Load drc from audio section!!!", __func__); + res_ptr = (void *)&audio_section_audio_cfg.cfg.drc; + } + else if (type == AUDIO_PROCESS_TYPE_LIMITER) + { + TRACE(1,"[%s] Load limiter from audio section!!!", __func__); + res_ptr = (void *)&audio_section_audio_cfg.cfg.limiter; + } + else + { + TRACE(2,"[%s] ERROR: Invalid type(%d)", __func__, type); + res_ptr = NULL; + } + } + + return res_ptr; +} diff --git a/services/audio_process/audio_cfg.h b/services/audio_process/audio_cfg.h new file mode 100644 index 0000000..b0afe13 --- /dev/null +++ b/services/audio_process/audio_cfg.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __AUDIO_CFG_H__ +#define __AUDIO_CFG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" + +enum AUDIO_PROCESS_TYPE_T { + AUDIO_PROCESS_TYPE_IIR_EQ = 0, + AUDIO_PROCESS_TYPE_DRC, + AUDIO_PROCESS_TYPE_LIMITER, + AUDIO_PROCESS_TYPE_NUM, +}; + +struct AUDIO_CFG_T_; +typedef struct AUDIO_CFG_T_ AUDIO_CFG_T; + +int sizeof_audio_cfg(void); +int store_audio_cfg_into_audio_section(AUDIO_CFG_T *cfg); +void *load_audio_cfg_from_audio_section(enum AUDIO_PROCESS_TYPE_T type); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/audio_process/audio_process.c b/services/audio_process/audio_process.c new file mode 100644 index 0000000..4070f17 --- /dev/null +++ b/services/audio_process/audio_process.c @@ -0,0 +1,1244 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/******************************************************************************* +** namer : Audio Process +** description : Manage auido process algorithms, include :hw iir eq, sw iir eq, +** hw fir eq, drc... +** version : V1.0 +** author : Yunjie Huo +** modify : 2018.12.4 +** todo : NULL +** MIPS : NO PROCESS: 34M(TWS, one ear, Mono, AAC, 48k) +** DRC1: 36M(3 bands) +** DRC2: 12M +*******************************************************************************/ +/* +Audio Flow: + DECODE --> SW IIR EQ --> DRC --> LIMTER --> VOLUME --> HW IIR EQ --> SPK + + +-----------------------------+ + | DAC | + | | ++--------+ +-----------+ +-----+ +--------+ | +--------+ +-----------+ | +-----+ +| | PCM | | | | | | | | | | | | | | +| DECODE +---->+ SW IIR EQ +--->+ DRC +--->+ LIMTER +--->+ VOLUME +--->+ HW IIR EQ +--->+ SPK | +| | | | | | | | | | | | | | | | ++--------+ +-----------+ +-----+ +--------+ | +--------+ +-----------+ | +-----+ + +-----------------------------+ + +| ------------ | ------------------------- | -------- | ----------- | +| Algorithm | description | MIPS(M) | RAM(kB) | +| ------------ | ------------------------- | -------- | ----------- | +| DRC | Dynamic Range Compression | 12M/band | 13 | +| Limiter/DRC2 | Limiter | 12M | 5 | +| EQ | Equalizer | 1M/band | Almost zero | +*/ + +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "string.h" +#include "audio_process.h" +#include "stdbool.h" +#include "hal_location.h" +#include "hw_codec_iir_process.h" +#include "hw_iir_process.h" +#include "tgt_hardware.h" +#include "drc.h" +#include "limiter.h" +#include "audio_cfg.h" + +#if defined(USB_EQ_TUNING) +#if !defined(__HW_DAC_IIR_EQ_PROCESS__) && !defined(__SW_IIR_EQ_PROCESS__) +#error "Either HW_DAC_IIR_EQ_PROCESS or SW_IIR_EQ_PROCESS should be defined when enabling USB_EQ_TUNING" +#endif +#endif + +#if defined(__PC_CMD_UART__) || defined(USB_EQ_TUNING) +#include "hal_cmd.h" + +#if defined(__SW_IIR_EQ_PROCESS__) +#define AUDIO_EQ_SW_IIR_UPDATE_CFG +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) +#define AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG +#endif + +#if defined(__HW_IIR_EQ_PROCESS__) +#define AUDIO_EQ_HW_IIR_UPDATE_CFG +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ +#define AUDIO_EQ_HW_FIR_UPDATE_CFG +#endif + +#ifdef __AUDIO_DRC__ +#define AUDIO_DRC_UPDATE_CFG +#endif + +#ifdef __AUDIO_DRC2__ +#define AUDIO_DRC2_UPDATE_CFG +#endif + +#endif + +#if defined(__SW_IIR_EQ_PROCESS__) +extern const IIR_CFG_T * const audio_eq_sw_iir_cfg_list[EQ_SW_IIR_LIST_NUM]; +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) +extern const IIR_CFG_T * const POSSIBLY_UNUSED audio_eq_hw_dac_iir_cfg_list[EQ_HW_DAC_IIR_LIST_NUM]; +#endif + +#if defined(__HW_IIR_EQ_PROCESS__) +extern const IIR_CFG_T * const POSSIBLY_UNUSED audio_eq_hw_iir_cfg_list[EQ_HW_IIR_LIST_NUM]; +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ +extern const FIR_CFG_T * const audio_eq_hw_fir_cfg_list[EQ_HW_FIR_LIST_NUM]; +#endif + +#ifdef __AUDIO_DRC__ +extern const DrcConfig audio_drc_cfg; +#endif + +#ifdef __AUDIO_DRC2__ +extern const LimiterConfig audio_drc2_cfg; +#endif + +#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) || defined(AUDIO_EQ_HW_FIR_UPDATE_CFG)|| defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG)|| defined(AUDIO_EQ_HW_IIR_UPDATE_CFG) || defined(AUDIO_DRC_UPDATE_CFG) || defined(AUDIO_DRC2_UPDATE_CFG) +#define AUDIO_UPDATE_CFG +#endif + +#ifdef __AUDIO_DRC__ +#define AUDIO_DRC_NEEDED_SIZE (1024*13) +#else +#define AUDIO_DRC_NEEDED_SIZE (0) +#endif + +#ifdef __AUDIO_DRC2__ +#define AUDIO_DRC2_NEEDED_SIZE (1024*5) +#else +#define AUDIO_DRC2_NEEDED_SIZE (0) +#endif + +#define AUDIO_MEMORY_SIZE (AUDIO_DRC_NEEDED_SIZE + AUDIO_DRC2_NEEDED_SIZE) + +#if AUDIO_MEMORY_SIZE > 0 +#include "audio_memory.h" +#endif + +#ifndef CODEC_OUTPUT_DEV +#define CODEC_OUTPUT_DEV CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV +#endif + +typedef signed int pcm_24bits_t; +typedef signed short int pcm_16bits_t; + +typedef struct{ + enum AUD_BITS_T sample_bits; + enum AUD_SAMPRATE_T sample_rate; + enum AUD_CHANNEL_NUM_T sw_ch_num; + enum AUD_CHANNEL_NUM_T hw_ch_num; + +#if defined(__SW_IIR_EQ_PROCESS__) + bool sw_iir_enable; +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) + bool hw_dac_iir_enable; +#endif + +#if defined(__HW_IIR_EQ_PROCESS__) + bool hw_iir_enable; +#endif + +#if defined(__HW_FIR_EQ_PROCESS__) + bool hw_fir_enable; +#endif + +#if AUDIO_MEMORY_SIZE > 0 + uint8_t *audio_heap; +#endif + +#ifdef __AUDIO_DRC__ + DrcState *drc_st; +#endif + +#ifdef __AUDIO_DRC2__ + LimiterState *drc2_st; +#endif + +#ifdef AUDIO_UPDATE_CFG + bool update_cfg; +#endif + +#ifdef USB_EQ_TUNING + bool eq_updated_cfg; +#endif + + +#ifdef AUDIO_EQ_SW_IIR_UPDATE_CFG + IIR_CFG_T sw_iir_cfg; +#endif + +#ifdef AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG + IIR_CFG_T hw_dac_iir_cfg; +#endif + +#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG + IIR_CFG_T hw_iir_cfg; +#endif + +#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG + FIR_CFG_T hw_fir_cfg; +#endif + +#ifdef AUDIO_DRC_UPDATE_CFG + bool drc_update; + DrcConfig drc_cfg; +#endif + +#ifdef AUDIO_DRC2_UPDATE_CFG + bool drc2_update; + LimiterConfig drc2_cfg; +#endif +} AUDIO_PROCESS_T; + +static AUDIO_PROCESS_T audio_process = { + .sample_bits = AUD_BITS_NULL, + .sample_rate = AUD_SAMPRATE_NULL, + .sw_ch_num = AUD_CHANNEL_NUM_NULL, + .hw_ch_num = AUD_CHANNEL_NUM_NULL, + +#if defined(__SW_IIR_EQ_PROCESS__) + .sw_iir_enable = false, +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) + .hw_dac_iir_enable = false, +#endif + +#if defined(__HW_IIR_EQ_PROCESS__) + .hw_iir_enable = false, +#endif + +#if defined(__HW_FIR_EQ_PROCESS__) + .hw_fir_enable = false, +#endif + +#ifdef AUDIO_UPDATE_CFG + .update_cfg = false, +#endif + +#ifdef AUDIO_EQ_SW_IIR_UPDATE_CFG + .sw_iir_cfg = {.num = 0}, +#endif + +#ifdef AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG + .hw_dac_iir_cfg = {.num = 0}, +#endif + +#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG + .hw_iir_cfg = {.num = 0}, +#endif + +#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG + .hw_fir_cfg = {.len = 0}, +#endif + +#ifdef AUDIO_DRC_UPDATE_CFG + .drc_update = false, + .drc_cfg = { + .knee = 0, + .filter_type = {-1, -1}, + .band_num = 1, + .look_ahead_time = 0, + .band_settings = { + {0, 0, 1, 1, 1, 1}, + {0, 0, 1, 1, 1, 1}, + } + }, +#endif + +#ifdef AUDIO_DRC2_UPDATE_CFG + .drc2_update = false, + .drc2_cfg = { + .knee = 0, + .look_ahead_time = 0, + .threshold = 0, + .makeup_gain = 0, + .ratio = 1000, + .attack_time = 1, + .release_time = 1, + }, +#endif +}; + +int audio_eq_set_cfg(const FIR_CFG_T *fir_cfg, const IIR_CFG_T *iir_cfg, AUDIO_EQ_TYPE_T audio_eq_type) +{ +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__)|| defined(__HW_DAC_IIR_EQ_PROCESS__)|| defined(__HW_IIR_EQ_PROCESS__) + switch (audio_eq_type) + { +#if defined(__SW_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_SW_IIR: + { + if(iir_cfg) + { + audio_process.sw_iir_enable = false; +#ifdef USB_EQ_TUNING + if (audio_process.eq_updated_cfg) { + iir_set_cfg(&audio_process.sw_iir_cfg); + } else +#endif + { + iir_set_cfg(iir_cfg); + } + audio_process.sw_iir_enable = true; + } + else + { + audio_process.sw_iir_enable = false; + } + } + break; +#endif + +#if defined(__HW_FIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_FIR: + { + if(fir_cfg) + { + audio_process.hw_fir_enable = false; + fir_set_cfg(fir_cfg); + audio_process.hw_fir_enable = true; + } + else + { + audio_process.hw_fir_enable = false; + } + } + break; +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_DAC_IIR: + { + if(iir_cfg) + { + HW_CODEC_IIR_CFG_T *hw_iir_cfg_dac=NULL; + enum AUD_SAMPRATE_T sample_rate_hw_dac_iir; +#ifdef __AUDIO_RESAMPLE__ + int i; + for(i=1;i<129;i++) + { + if(audio_process.sample_rate==AUD_SAMPRATE_7350*i)break; + if(audio_process.sample_rate==AUD_SAMPRATE_8000*i)break; + } + TRACE(1,"audio_process.sample_rate i:%d",i); + if(i==129) i=6; //set default eq parameter; + sample_rate_hw_dac_iir=i*8463.541666f;//AUD_SAMPRATE_8463 +#else + sample_rate_hw_dac_iir=audio_process.sample_rate; +#endif + audio_process.hw_dac_iir_enable = false; +#ifdef USB_EQ_TUNING + if (audio_process.eq_updated_cfg) { + hw_iir_cfg_dac = hw_codec_iir_get_cfg(sample_rate_hw_dac_iir, &audio_process.hw_dac_iir_cfg); + } else +#endif + { + hw_iir_cfg_dac = hw_codec_iir_get_cfg(sample_rate_hw_dac_iir,iir_cfg); + } + ASSERT(hw_iir_cfg_dac != NULL, "[%s] codec IIR parameter error!", __func__); + hw_codec_iir_set_cfg(hw_iir_cfg_dac, sample_rate_hw_dac_iir, HW_CODEC_IIR_DAC); + audio_process.hw_dac_iir_enable = true; + } + else + { + audio_process.hw_dac_iir_enable = false; + } + } + break; +#endif + +#if defined(__HW_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_IIR: + { + if(iir_cfg) + { + HW_IIR_CFG_T *hw_iir_cfg=NULL; + audio_process.hw_iir_enable = false; + hw_iir_cfg = hw_iir_get_cfg(audio_process.sample_rate,iir_cfg); + ASSERT(hw_iir_cfg != NULL,"[%s] 0x%x codec IIR parameter error!", __func__, (unsigned int)hw_iir_cfg); + hw_iir_set_cfg(hw_iir_cfg); + audio_process.hw_iir_enable = true; + } + else + { + audio_process.hw_iir_enable = false; + } + + } + break; +#endif + + default: + { + ASSERT(false,"[%s]Error eq type!",__func__); + } + } +#endif + + return 0; +} + +int SRAM_TEXT_LOC audio_process_run(uint8_t *buf, uint32_t len) +{ + int POSSIBLY_UNUSED pcm_len = 0; + + if(audio_process.sample_bits == AUD_BITS_16) + { + pcm_len = len / sizeof(pcm_16bits_t); + } + else if(audio_process.sample_bits == AUD_BITS_24) + { + pcm_len = len / sizeof(pcm_24bits_t); + } + else + { + ASSERT(0, "[%s] bits(%d) is invalid", __func__, audio_process.sample_bits); + } + + if (audio_process.sw_ch_num == audio_process.hw_ch_num) { + // do nothing + } else if (audio_process.sw_ch_num == AUD_CHANNEL_NUM_1 && + audio_process.hw_ch_num == AUD_CHANNEL_NUM_2) { + if (audio_process.sample_bits == AUD_BITS_16) { + int16_t *pcm_buf = (int16_t *)buf; + for (uint32_t i = 0, j = 0; i < pcm_len; i += 2, j++) { + pcm_buf[j] = pcm_buf[i]; + } + } else { + int32_t *pcm_buf = (int32_t *)buf; + for (uint32_t i = 0, j = 0; i < pcm_len; i += 2, j++) { + pcm_buf[j] = pcm_buf[i]; + } + } + + pcm_len /= 2; + } else { + ASSERT(0, "[%s] sw_ch_num(%d) or hw_ch_num(%d) is invalid", __FUNCTION__, audio_process.sw_ch_num, audio_process.hw_ch_num); + } + +#ifdef AUDIO_PROCESS_DUMP + int *buf32 = (int *)buf; + for(int i=0;i<1024;i++) + dump_buf[i] = buf32[2 * i]>>8; + audio_dump_clear_up(); + audio_dump_add_channel_data(0, dump_buf, 1024); + +#endif + + //int32_t s_time,e_time; + //s_time = hal_fast_sys_timer_get(); + +#ifdef __SW_IIR_EQ_PROCESS__ + if(audio_process.sw_iir_enable) + { + iir_run(buf, pcm_len); + } +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ + if(audio_process.hw_fir_enable) + { + fir_run(buf, pcm_len); + } +#endif + +#ifdef __AUDIO_DRC__ +#ifdef AUDIO_DRC_UPDATE_CFG + if(audio_process.drc_update) + { + drc_set_config(audio_process.drc_st, &audio_process.drc_cfg); + audio_process.drc_update =false; + } +#endif + + drc_process(audio_process.drc_st, buf, pcm_len); +#endif + + //int32_t m_time = hal_fast_sys_timer_get(); + +#ifdef __AUDIO_DRC2__ +#ifdef AUDIO_DRC2_UPDATE_CFG + if(audio_process.drc2_update) + { + limiter_set_config(audio_process.drc2_st, &audio_process.drc2_cfg); + audio_process.drc2_update =false; + } +#endif + + limiter_process(audio_process.drc2_st, buf, pcm_len); +#endif + +#ifdef __HW_IIR_EQ_PROCESS__ + if(audio_process.hw_iir_enable) + { + hw_iir_run(buf, pcm_len); + } +#endif + + if (audio_process.sw_ch_num == audio_process.hw_ch_num) { + // do nothing + } else if (audio_process.sw_ch_num == AUD_CHANNEL_NUM_1 && + audio_process.hw_ch_num == AUD_CHANNEL_NUM_2) { + if (audio_process.sample_bits == AUD_BITS_16) { + int16_t *pcm_buf = (int16_t *)buf; + for (int32_t i = pcm_len - 1, j = 2 * pcm_len - 1; i >= 0; i--, j -= 2) { + pcm_buf[j + 1] = pcm_buf[i]; + pcm_buf[j + 0] = pcm_buf[i]; + } + } else { + int32_t *pcm_buf = (int32_t *)buf; + for (int32_t i = pcm_len - 1, j = 2 * pcm_len - 2; i >= 0; i--, j -= 2) { + pcm_buf[j + 1] = pcm_buf[i]; + pcm_buf[j + 0] = pcm_buf[i]; + } + } + + pcm_len *= 2; + } else { + ASSERT(0, "[%s] sw_ch_num(%d) or hw_ch_num(%d) is invalid", __FUNCTION__, audio_process.sw_ch_num, audio_process.hw_ch_num); + } + +#ifdef AUDIO_PROCESS_DUMP + //for(int i=0;i<1024;i++) + // dump_buf[i] = buf32[2 * i+0]>>8; + //audio_dump_add_channel_data(1, dump_buf, 1024); + audio_dump_run(); +#endif + + //e_time = hal_fast_sys_timer_get(); + //TRACE(4,"[%s] Sample len = %d, drc1 %d us, drc2 %d us", + // __func__, pcm_len, FAST_TICKS_TO_US(m_time - s_time), FAST_TICKS_TO_US(e_time - m_time)); + + return 0; +} + +/* + * frame_size stands for samples per channel + */ +int audio_process_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_BITS_T sample_bits, enum AUD_CHANNEL_NUM_T sw_ch_num, enum AUD_CHANNEL_NUM_T hw_ch_num, int32_t frame_size, void *eq_buf, uint32_t len) +{ + TRACE(5,"[%s] sample_rate = %d, sample_bits = %d, sw_ch_num = %d, hw_ch_num = %d", __func__, sample_rate, sample_bits, sw_ch_num, hw_ch_num); +#ifdef AUDIO_PROCESS_DUMP + audio_dump_init(1024, sizeof(short), 2); +#endif + audio_process.sample_rate = sample_rate; + audio_process.sample_bits = sample_bits; + audio_process.sw_ch_num = sw_ch_num; + audio_process.hw_ch_num = hw_ch_num; + +#if defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) + void *fir_eq_buf = eq_buf; + uint32_t fir_len = len/2; + void *iir_eq_buf = (uint8_t *)eq_buf+fir_len; + uint32_t iir_len = len/2; +#elif defined(__HW_FIR_EQ_PROCESS__) && !defined(__HW_IIR_EQ_PROCESS__) + void *fir_eq_buf = eq_buf; + uint32_t fir_len = len; +#elif !defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) + void *iir_eq_buf = eq_buf; + uint32_t iir_len = len; +#endif + +#ifdef __SW_IIR_EQ_PROCESS__ + iir_open(sample_rate, sample_bits,sw_ch_num); +#ifdef AUDIO_EQ_SW_IIR_UPDATE_CFG + audio_eq_set_cfg(NULL, &audio_process.sw_iir_cfg, AUDIO_EQ_TYPE_SW_IIR); +#endif +#endif + +#ifdef __HW_DAC_IIR_EQ_PROCESS__ + enum AUD_SAMPRATE_T sample_rate_hw_dac_iir; +#ifdef __AUDIO_RESAMPLE__ + int i; + for(i=1;i<129;i++) + { + if(audio_process.sample_rate==AUD_SAMPRATE_7350*i)break; + if(audio_process.sample_rate==AUD_SAMPRATE_8000*i)break; + } + TRACE(1,"sample_rate i:%d",i); + if(i==129) i=6; //set default eq parameter; + sample_rate_hw_dac_iir=i*8463.541666f;//AUD_SAMPRATE_8463 +#else + sample_rate_hw_dac_iir = audio_process.sample_rate; +#endif + + hw_codec_iir_open(sample_rate_hw_dac_iir, HW_CODEC_IIR_DAC, CODEC_OUTPUT_DEV); +#ifdef AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG + audio_eq_set_cfg(NULL, &audio_process.hw_dac_iir_cfg, AUDIO_EQ_TYPE_HW_DAC_IIR); +#endif +#endif + +#ifdef __HW_IIR_EQ_PROCESS__ + hw_iir_open(sample_rate, sample_bits, sw_ch_num, iir_eq_buf, iir_len); +#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG + audio_eq_set_cfg(NULL, &audio_process.hw_iir_cfg, AUDIO_EQ_TYPE_HW_IIR); +#endif +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ +#if defined(CHIP_BEST1000) && defined(FIR_HIGHSPEED) + hal_cmu_fir_high_speed_enable(HAL_CMU_FIR_USER_EQ); +#endif + fir_open(sample_rate, sample_bits, sw_ch_num, fir_eq_buf, fir_len); +#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG + audio_eq_set_cfg(&audio_process.hw_fir_cfg, NULL, AUDIO_EQ_TYPE_HW_FIR); +#endif +#endif + +#if AUDIO_MEMORY_SIZE > 0 + syspool_get_buff(&audio_process.audio_heap, AUDIO_MEMORY_SIZE); + audio_heap_init(audio_process.audio_heap, AUDIO_MEMORY_SIZE); +#endif + +#ifdef __AUDIO_DRC__ + audio_process.drc_st = drc_create(sample_rate, frame_size, sample_bits, sw_ch_num, +#ifdef AUDIO_DRC_UPDATE_CFG + &audio_process.drc_cfg +#else + &audio_drc_cfg +#endif + ); +#ifdef AUDIO_DRC_UPDATE_CFG + audio_process.drc_update = false; +#endif +#endif + +#ifdef __AUDIO_DRC2__ + audio_process.drc2_st = limiter_create(sample_rate, frame_size, sample_bits, sw_ch_num, +#ifdef AUDIO_DRC2_UPDATE_CFG + &audio_process.drc2_cfg +#else + &audio_drc2_cfg +#endif + ); +#ifdef AUDIO_DRC2_UPDATE_CFG + audio_process.drc2_update = false; +#endif +#endif + +#if defined(__PC_CMD_UART__) && defined(USB_AUDIO_APP) + hal_cmd_open(); +#endif + + return 0; +} + +int audio_process_close(void) +{ +#ifdef __SW_IIR_EQ_PROCESS__ + audio_process.sw_iir_enable = false; + iir_close(); +#endif + +#ifdef __HW_DAC_IIR_EQ_PROCESS__ + audio_process.hw_dac_iir_enable = false; + hw_codec_iir_close(HW_CODEC_IIR_DAC); +#endif + +#ifdef __HW_IIR_EQ_PROCESS__ + audio_process.hw_iir_enable = false; + hw_iir_close(); +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ + audio_process.hw_fir_enable = false; + fir_close(); +#if defined(CHIP_BEST1000) && defined(FIR_HIGHSPEED) + hal_cmu_fir_high_speed_disable(HAL_CMU_FIR_USER_EQ); +#endif +#endif + +#ifdef __AUDIO_DRC__ +#ifdef AUDIO_DRC_UPDATE_CFG + audio_process.drc_update = false; +#endif + drc_destroy(audio_process.drc_st); + audio_process.drc_st = NULL; +#endif + +#ifdef __AUDIO_DRC2__ +#ifdef AUDIO_DRC2_UPDATE_CFG + audio_process.drc2_update = false; +#endif + limiter_destroy(audio_process.drc2_st); + audio_process.drc2_st = NULL; +#endif + +#if AUDIO_MEMORY_SIZE > 0 + size_t total = 0, used = 0, max_used = 0; + audio_memory_info(&total, &used, &max_used); + TRACE(3,"AUDIO MALLOC MEM: total - %d, used - %d, max_used - %d.", total, used, max_used); + ASSERT(used == 0, "[%s] used != 0", __func__); +#endif + +#if defined(__PC_CMD_UART__) && defined(USB_AUDIO_APP) + hal_cmd_close(); +#endif + + return 0; +} + +#if defined(__PC_CMD_UART__) || defined(USB_EQ_TUNING) +int audio_ping_callback(uint8_t *buf, uint32_t len) +{ + //TRACE(0,""); + return 0; +} + +#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) && !defined(USB_EQ_TUNING) +#ifndef USB_AUDIO_APP +int audio_eq_sw_iir_callback(uint8_t *buf, uint32_t len) +{ + TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(IIR_CFG_T)); + + if (len != sizeof(IIR_CFG_T)) + { + return 1; + } + + memcpy(&audio_process.sw_iir_cfg, buf, sizeof(IIR_CFG_T)); + TRACE(3,"band num:%d gain0:%d, gain1:%d", + (int32_t)audio_process.sw_iir_cfg.num, + (int32_t)(audio_process.sw_iir_cfg.gain0*10), + (int32_t)(audio_process.sw_iir_cfg.gain1*10)); + for (uint8_t i = 0; igain0, rx_iir_cfg->gain1); + + // for(int i=0; inum; i++) + // { + // TRACE(5,"[%s] iir[%d] gain = %f, f = %f, Q = %f", __func__, i, rx_iir_cfg->param[i].gain, rx_iir_cfg->param[i].fc, rx_iir_cfg->param[i].Q); + // } + + // audio_eq_set_cfg(NULL,(const IIR_CFG_T *)rx_iir_cfg,AUDIO_EQ_TYPE_SW_IIR); + + iir_update_cfg_tbl(buf, len); + + return 0; +} +#endif +#endif + +#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG +int audio_eq_hw_fir_callback(uint8_t *buf, uint32_t len) +{ + TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(FIR_CFG_T)); + + if (len != sizeof(FIR_CFG_T)) + { + return 1; + } + + FIR_CFG_T *rx_fir_cfg = NULL; + + rx_fir_cfg = (FIR_CFG_T *)buf; + + TRACE(3,"[%s] left gain = %d, right gain = %d", __func__, rx_fir_cfg->gain0, rx_fir_cfg->gain1); + + TRACE(6,"[%s] len = %d, coef: %d, %d......%d, %d", __func__, rx_fir_cfg->len, rx_fir_cfg->coef[0], rx_fir_cfg->coef[1], rx_fir_cfg->coef[rx_fir_cfg->len-2], rx_fir_cfg->coef[rx_fir_cfg->len-1]); + + rx_fir_cfg->gain0 = 6; + rx_fir_cfg->gain1 = 6; + + if(rx_fir_cfg) + { + memcpy(&audio_process.fir_cfg, rx_fir_cfg, sizeof(audio_process.fir_cfg)); + audio_process.fir_enable = true; + fir_set_cfg(&audio_process.fir_cfg); + } + else + { + audio_process.fir_enable = false; + } + + return 0; +} +#endif + +#ifdef AUDIO_DRC_UPDATE_CFG +int audio_drc_callback(uint8_t *buf, uint32_t len) +{ + TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(DrcConfig)); + + if (len != sizeof(DrcConfig)) + { + TRACE(1,"[%s] WARNING: Length is different", __func__); + + return 1; + } + + if (audio_process.drc_st == NULL) + { + TRACE(1,"[%s] WARNING: audio_process.drc2_st = NULL", __func__); + TRACE(1,"[%s] WARNING: Please Play music, then tuning Limiter", __func__); + + return 2; + } + + memcpy(&audio_process.drc_cfg, buf, sizeof(DrcConfig)); + audio_process.drc_update = true; + + return 0; +} +#endif + +#ifdef AUDIO_DRC2_UPDATE_CFG +int audio_drc2_callback(uint8_t *buf, uint32_t len) +{ + TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(LimiterConfig)); + + if (len != sizeof(LimiterConfig)) + { + TRACE(1,"[%s] WARNING: Length is different", __func__); + + return 1; + } + + if (audio_process.drc2_st == NULL) + { + TRACE(1,"[%s] WARNING: audio_process.drc2_st = NULL", __func__); + TRACE(1,"[%s] WARNING: Please Play music, then tuning Limiter", __func__); + + return 2; + } + + memcpy(&audio_process.drc2_cfg, buf, sizeof(LimiterConfig)); + audio_process.drc2_update = true; + + return 0; +} +#endif + +#if defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG) && !defined(USB_EQ_TUNING) +int audio_eq_hw_dac_iir_callback(uint8_t *buf, uint32_t len) +{ + TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof(IIR_CFG_T)); + + if (len != sizeof(IIR_CFG_T)) + { + return 1; + } + + memcpy(&audio_process.hw_dac_iir_cfg, buf, sizeof(IIR_CFG_T)); + TRACE(3,"band num:%d gain0:%d, gain1:%d", + (int32_t)audio_process.hw_dac_iir_cfg.num, + (int32_t)(audio_process.hw_dac_iir_cfg.gain0*10), + (int32_t)(audio_process.hw_dac_iir_cfg.gain1*10)); + for (uint8_t i = 0; i sample_rate[%d], num[%d]", /*cur_cfg->samplerate,*/ audio_process.sample_rate, cur_cfg->num); + +#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) + audio_process.sw_iir_cfg.gain0 = cur_cfg->gain0; + audio_process.sw_iir_cfg.gain1 = cur_cfg->gain1; +#endif + +#if defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG) +#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) + audio_process.hw_dac_iir_cfg.gain0 = 0; + audio_process.hw_dac_iir_cfg.gain1 = 0; +#else + audio_process.hw_dac_iir_cfg.gain0 = cur_cfg->gain0; + audio_process.hw_dac_iir_cfg.gain1 = cur_cfg->gain1; +#endif +#endif + +#if defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG) + if (cur_cfg->num > AUD_DAC_IIR_NUM_EQ) { + audio_process.hw_dac_iir_cfg.num = AUD_DAC_IIR_NUM_EQ; + } else { + audio_process.hw_dac_iir_cfg.num = cur_cfg->num; + } + TRACE(1,"-> hw_dac_iir_num[%d]", audio_process.hw_dac_iir_cfg.num); +#endif + +#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) + audio_process.sw_iir_cfg.num = cur_cfg->num - audio_process.hw_dac_iir_cfg.num; + TRACE(1,"-> sw_iir_num[%d]", audio_process.sw_iir_cfg.num); +#endif + //TRACE(2,"-> iir_num[%d - %d]", audio_process.hw_dac_iir_cfg.num, audio_process.sw_iir_cfg.num); + +#if defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG) + if (audio_process.hw_dac_iir_cfg.num) { + memcpy((void*)(&audio_process.hw_dac_iir_cfg.param[0]), + (void*)(&cur_cfg->param[0]), + audio_process.hw_dac_iir_cfg.num*sizeof(IIR_PARAM_T)); + } +#endif + +#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) + if (audio_process.sw_iir_cfg.num) { + + memcpy((void*)(&audio_process.sw_iir_cfg.param[0]), + (void*)(&cur_cfg->param[audio_process.hw_dac_iir_cfg.num]), + audio_process.sw_iir_cfg.num * sizeof(IIR_PARAM_T)); + + } else { + + // set a default filter + audio_process.sw_iir_cfg.num = 1; + + audio_process.sw_iir_cfg.param[0].fc = 1000.0; + audio_process.sw_iir_cfg.param[0].gain = 0.0; + audio_process.sw_iir_cfg.param[0].type = IIR_TYPE_PEAK; + audio_process.sw_iir_cfg.param[0].Q = 1.0; + + } +#endif + + if (audio_process.sample_rate) { + audio_process.update_cfg = true; + } + + audio_process.eq_updated_cfg = true; + + return 0; +} + +void audio_eq_usb_eq_update (void) +{ + if (audio_process.update_cfg) { + +#if defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG) + HW_CODEC_IIR_CFG_T *hw_iir_cfg_dac = NULL; + + if (audio_process.hw_dac_iir_cfg.num) { + enum AUD_SAMPRATE_T sample_rate_hw_dac_iir; +#ifdef __AUDIO_RESAMPLE__ + int i; + for(i=1;i<129;i++) + { + if(audio_process.sample_rate==AUD_SAMPRATE_7350*i)break; + if(audio_process.sample_rate==AUD_SAMPRATE_8000*i)break; + } + TRACE(1,"audio_process.sample_rate i:%d",i); + if(i==129) i=6; //set default eq parameter; + sample_rate_hw_dac_iir=i*8463.541666f;//AUD_SAMPRATE_8463 +#else + sample_rate_hw_dac_iir = audio_process.sample_rate; +#endif + hw_iir_cfg_dac = hw_codec_iir_get_cfg(sample_rate_hw_dac_iir, &audio_process.hw_dac_iir_cfg); + + hw_codec_iir_set_cfg(hw_iir_cfg_dac, sample_rate_hw_dac_iir, HW_CODEC_IIR_DAC); + audio_process.hw_dac_iir_enable = true; + + } else { + + audio_process.hw_dac_iir_enable = false; + } +#endif + +#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) + iir_set_cfg(&audio_process.sw_iir_cfg); + audio_process.sw_iir_enable = true; +#endif + + audio_process.update_cfg = false; + +/* + TRACE(4,"USB EQ Update: en[%d-%d], num[%d-%d]", + audio_process.hw_dac_iir_enable, audio_process.sw_iir_enable, + audio_process.hw_dac_iir_cfg.num, audio_process.sw_iir_cfg.num); +*/ + } + +} + +#endif // USB_EQ_TUNING + + +typedef struct { + uint8_t type; + uint8_t maxEqBandNum; + uint16_t sample_rate_num; + uint8_t sample_rate[50]; +} query_eq_info_t; + + +extern int getMaxEqBand(void); +extern int getSampleArray(uint8_t* buf, uint16_t *num); + +extern void hal_cmd_set_res_playload(uint8_t* data, int len); +#define CMD_TYPE_QUERY_DUT_EQ_INFO 0x00 +int audio_cmd_callback(uint8_t *buf, uint32_t len) +{ + uint8_t type; + //uint32_t* sample_rate; + //uint8_t* p; + query_eq_info_t info; + + type = buf[0]; + //p = buf + 1; + + TRACE(2,"%s type: %d", __func__, type); + switch (type) { + case CMD_TYPE_QUERY_DUT_EQ_INFO: + info.type = CMD_TYPE_QUERY_DUT_EQ_INFO; + info.maxEqBandNum = getMaxEqBand(); + getSampleArray(info.sample_rate, &info.sample_rate_num); + + hal_cmd_set_res_playload((uint8_t*)&info, 4 + info.sample_rate_num * 4); + break; + default: + break; + } + + return 0; +} + +#ifdef AUDIO_SECTION_ENABLE +int audio_cfg_burn_callback(uint8_t *buf, uint32_t len) +{ + TRACE(3,"[%s] len = %d, sizeof(struct) = %d", __func__, len, sizeof_audio_cfg()); + + if (len != sizeof_audio_cfg()) + { + return 1; + } + + int res = 0; + res = store_audio_cfg_into_audio_section((AUDIO_CFG_T *)buf); + + if(res) + { + TRACE(2,"[%s] ERROR: res = %d", __func__, res); + res += 100; + } + else + { + TRACE(1,"[%s] Store audio cfg into audio section!!!", __func__); + } + + return res; +} +#endif + +int audio_process_init(void) +{ +#ifdef __PC_CMD_UART__ + hal_cmd_init(); + +#ifdef AUDIO_EQ_SW_IIR_UPDATE_CFG + hal_cmd_register("iir_eq", audio_eq_sw_iir_callback); // Will be removed + hal_cmd_register("sw_iir_eq", audio_eq_sw_iir_callback); +#endif + +#ifdef AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG + hal_cmd_register("iir_eq", audio_eq_hw_dac_iir_callback); // Will be removed + hal_cmd_register("dac_iir_eq", audio_eq_hw_dac_iir_callback); +#endif + +#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG + hal_cmd_register("iir_eq", audio_eq_hw_iir_callback); // Will be removed + hal_cmd_register("hw_iir_eq", audio_eq_hw_iir_callback); +#endif + +#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG + hal_cmd_register("fir_eq", audio_eq_hw_fir_callback); +#endif + +#ifdef AUDIO_DRC_UPDATE_CFG + hal_cmd_register("drc", audio_drc_callback); +#endif + +#ifdef AUDIO_DRC2_UPDATE_CFG + hal_cmd_register("limiter", audio_drc2_callback); +#endif + +#ifdef AUDIO_SECTION_ENABLE + hal_cmd_register("burn", audio_cfg_burn_callback); + hal_cmd_register("audio_burn", audio_cfg_burn_callback); +#endif + + hal_cmd_register("cmd", audio_cmd_callback); + hal_cmd_register("ping", audio_ping_callback); +#endif + +#ifdef USB_EQ_TUNING + + hal_cmd_init(); + +#if defined(AUDIO_EQ_SW_IIR_UPDATE_CFG) || defined(AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG) + hal_cmd_register("iir_eq", audio_eq_usb_iir_callback); +#endif + + hal_cmd_register("cmd", audio_cmd_callback); + hal_cmd_register("ping", audio_ping_callback); + +#endif + + // load default cfg +#ifdef AUDIO_EQ_SW_IIR_UPDATE_CFG + memcpy(&audio_process.sw_iir_cfg, audio_eq_sw_iir_cfg_list[0], sizeof(IIR_CFG_T)); +#endif + +#ifdef AUDIO_EQ_HW_DAC_IIR_UPDATE_CFG + memcpy(&audio_process.hw_dac_iir_cfg, audio_eq_hw_dac_iir_cfg_list[0], sizeof(IIR_CFG_T)); +#endif + +#ifdef AUDIO_EQ_HW_IIR_UPDATE_CFG + memcpy(&audio_process.hw_iir_cfg, audio_eq_hw_iir_cfg_list[0], sizeof(IIR_CFG_T)); +#endif + +#ifdef AUDIO_EQ_HW_FIR_UPDATE_CFG + memcpy(&audio_process.hw_fir_cfg, audio_eq_hw_fir_cfg_list[0], sizeof(FIR_CFG_T)); +#endif + +#ifdef AUDIO_DRC_UPDATE_CFG + memcpy(&audio_process.drc_cfg, &audio_drc_cfg, sizeof(DrcConfig)); +#endif + +#ifdef AUDIO_DRC2_UPDATE_CFG + memcpy(&audio_process.drc2_cfg, &audio_drc2_cfg, sizeof(LimiterConfig)); +#endif + + return 0; +} diff --git a/services/audio_process/audio_process.h b/services/audio_process/audio_process.h new file mode 100644 index 0000000..d0aea51 --- /dev/null +++ b/services/audio_process/audio_process.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __AUDIO_PROCESS_H__ +#define __AUDIO_PROCESS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "iir_process.h" +#include "fir_process.h" + +typedef enum { + AUDIO_EQ_TYPE_SW_IIR = 0, + AUDIO_EQ_TYPE_HW_FIR, + AUDIO_EQ_TYPE_HW_DAC_IIR, + AUDIO_EQ_TYPE_HW_IIR, +} AUDIO_EQ_TYPE_T; + +int audio_process_init(void); +int audio_process_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_BITS_T sample_bits,enum AUD_CHANNEL_NUM_T sw_ch_num, enum AUD_CHANNEL_NUM_T hw_ch_num,int32_t frame_size, void *eq_buf, uint32_t len); +int audio_process_run(uint8_t *buf, uint32_t len); +int audio_process_close(void); + +int audio_eq_set_cfg(const FIR_CFG_T *fir_cfg,const IIR_CFG_T *iir_cfg,AUDIO_EQ_TYPE_T audio_eq_type); + +#ifdef USB_EQ_TUNING +void audio_eq_usb_eq_update (void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/audio_process/audio_spectrum.cpp b/services/audio_process/audio_spectrum.cpp new file mode 100644 index 0000000..9996efc --- /dev/null +++ b/services/audio_process/audio_spectrum.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef SPEECH_LIB + +#include "spectrum_fix.h" +#include "speech_memory.h" +#include "hal_aud.h" +#include "hal_trace.h" + +#define AUDIO_SPECTRUM_FRAME_SIZE (256) + +struct AudioSpectrum { + SpectrumFixState *state; + enum AUD_BITS_T bits; + int16_t *frame; + int16_t *data; +}; + +static AudioSpectrum audio_spectrum; + +extern const SpectrumFixConfig audio_spectrum_cfg; + +void audio_spectrum_open(int sample_rate, enum AUD_BITS_T sample_bits) +{ + uint8_t *speech_buf = NULL; + int speech_buf_size = 1024 * 5; + + syspool_get_buff((uint8_t **)&(audio_spectrum.frame), AUDIO_SPECTRUM_FRAME_SIZE * sizeof(int16_t)); + syspool_get_buff((uint8_t **)&(audio_spectrum.data), audio_spectrum_cfg.freq_num * sizeof(int16_t)); + syspool_get_buff(&speech_buf, speech_buf_size); + speech_heap_init(speech_buf, speech_buf_size); + + audio_spectrum.state = spectrum_fix_init(sample_rate, AUDIO_SPECTRUM_FRAME_SIZE, &audio_spectrum_cfg); + audio_spectrum.bits = sample_bits; +} + +void audio_spectrum_close(void) +{ + spectrum_fix_destroy(audio_spectrum.state); + + size_t total = 0, used = 0, max_used = 0; + speech_memory_info(&total, &used, &max_used); + TRACE(3,"SPEECH MALLOC MEM: total - %d, used - %d, max_used - %d.", total, used, max_used); + ASSERT(used == 0, "[%s] used != 0", __func__); +} + +static inline int16_t convertTo16Bit(int16_t x) +{ + return x; +} + +static inline int16_t convertTo16Bit(int32_t x) +{ + return (x >> 8); +} + + +// convert stream to 16bit mono stream +template +static void convertToMono16Bit(int16_t *out, DataType *in, int frame_size) +{ + for (int i = 0; i < frame_size; i++) { + out[i] = convertTo16Bit(in[i * 2]) / 2 + convertTo16Bit(in[i * 2 + 1]) / 2; + } +} + +template +void audio_spectrum_run_impl(const uint8_t *buf, int len) +{ + int frame_size = len / sizeof(DataType); + DataType *pBuf = (DataType *)buf; + + ASSERT(frame_size % (2 * AUDIO_SPECTRUM_FRAME_SIZE) == 0, + "[%s] only support N*%d frame size", __FUNCTION__, AUDIO_SPECTRUM_FRAME_SIZE); + + int audio_spectrum_block_cnt = frame_size / 2 / AUDIO_SPECTRUM_FRAME_SIZE; + + for (int i = 0; i < audio_spectrum_block_cnt; i++) { + //stereo to mono, 24bit to 16bit + convertToMono16Bit(audio_spectrum.frame, pBuf + i * AUDIO_SPECTRUM_FRAME_SIZE * 2, AUDIO_SPECTRUM_FRAME_SIZE); + + //TRACE(0,"pcm:"); + //DUMP16("0x%x, ", audio_spectrum.frame, 8); + + spectrum_fix_analysis(audio_spectrum.state, audio_spectrum.frame); + if (i == 0) { + spectrum_fix_process(audio_spectrum.state, audio_spectrum.data, audio_spectrum_cfg.freq_num); + //TRACE(1,"spectrum: %d", sizeof(DataType)); + //DUMP16("0x%x, ", audio_spectrum.data, audio_spectrum_cfg.freq_num); + } + } +} + +void audio_spectrum_run(const uint8_t *buf, int len) +{ + if (audio_spectrum.bits == AUD_BITS_16) + audio_spectrum_run_impl(buf, len); + else if (audio_spectrum.bits == AUD_BITS_24) + audio_spectrum_run_impl(buf, len); + else + TRACE(1,"[%s] warning not suitable callback available", __func__); +} + +#endif + diff --git a/services/audio_process/audio_spectrum.h b/services/audio_process/audio_spectrum.h new file mode 100644 index 0000000..b913f1f --- /dev/null +++ b/services/audio_process/audio_spectrum.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef AUDIO_SPECTRUM_H +#define AUDIO_SPECTRUM_H + +void audio_spectrum_open(int sample_rate, enum AUD_BITS_T sample_bits); + +void audio_spectrum_close(void); + +void audio_spectrum_run(const uint8_t *buf, int len); + +#endif diff --git a/services/audioflinger/Makefile b/services/audioflinger/Makefile new file mode 100644 index 0000000..1b31ba7 --- /dev/null +++ b/services/audioflinger/Makefile @@ -0,0 +1,123 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + -Iutils/uarthci \ + -Iutils/cqueue \ + -Iplatform/drivers/codec \ + -Iservices/multimedia/audio/process/floatlimiter/include \ + -Iplatform/drivers/ana + +ifeq ($(RAND_FROM_MIC),1) +ccflags-y += \ + -Iapps/common +endif + +ifneq ($(AF_STACK_SIZE),) +CFLAGS_audioflinger.o += -DAF_STACK_SIZE=$(AF_STACK_SIZE) +endif + +ifeq ($(AUDIO_CODEC_ASYNC_CLOSE),1) +CFLAGS_audioflinger.o += -D__CODEC_ASYNC_CLOSE__ +endif + +ifeq ($(CODEC_PLAY_BEFORE_CAPTURE),1) +CFLAGS_audioflinger.o += -DCODEC_PLAY_BEFORE_CAPTURE +endif + +ifeq ($(AUDIO_OUTPUT_SMALL_GAIN_ATTN),1) +CFLAGS_audioflinger.o += -DAUDIO_OUTPUT_SMALL_GAIN_ATTN +endif + +ifeq ($(AUDIO_OUTPUT_SW_GAIN),1) +CFLAGS_audioflinger.o += -DAUDIO_OUTPUT_SW_GAIN +endif + +ifeq ($(ANC_APP),1) +CFLAGS_audioflinger.o += -DANC_APP +ifeq ($(CODEC_ANC_BOOST),1) +CFLAGS_audioflinger.o += -DCODEC_ANC_BOOST +endif +endif + +ifeq ($(AUDIO_RESAMPLE),1) +CFLAGS_audioflinger.o += -D__AUDIO_RESAMPLE__ +endif + +ifeq ($(AUDIO_OUTPUT_DC_CALIB),1) +CFLAGS_audioflinger.o += -DAUDIO_OUTPUT_DC_CALIB +endif +ifeq ($(AUDIO_OUTPUT_DC_CALIB_ANA),1) +CFLAGS_audioflinger.o += -DAUDIO_OUTPUT_DC_CALIB_ANA +endif + +ifeq ($(AUDIO_OUTPUT_GAIN_M60DB_CHECK),1) +CFLAGS_audioflinger.o += -DAUDIO_OUTPUT_GAIN_M60DB_CHECK +endif + +ifeq ($(CODEC_DSD),1) +CFLAGS_audioflinger.o += -DCODEC_DSD +endif + +ifeq ($(AUDIO_OUTPUT_INVERT_RIGHT_CHANNEL),1) +CFLAGS_audioflinger.o += -DAUDIO_OUTPUT_INVERT_RIGHT_CHANNEL +endif + +ifeq ($(AUDIO_OUTPUT_CALIB_GAIN_MISSMATCH),1) +CFLAGS_audioflinger.o += -DAUDIO_OUTPUT_CALIB_GAIN_MISSMATCH +endif + +ifneq ($(CHIP_HAS_I2S),) +CFLAGS_audioflinger.o += -DCHIP_HAS_I2S=$(CHIP_HAS_I2S) +endif + +#------------------------------- +# Audioflinger device selection +#------------------------------- +# Internal codec default on +AF_DEVICE_INT_CODEC ?= 1 + +# BT PCM default on for BT applications +ifeq ($(RTOS),1) +AF_DEVICE_BT_PCM ?= 1 +endif + +# Individual device macro +ifeq ($(AF_DEVICE_EXT_CODEC),1) +CFLAGS_audioflinger.o += -DAF_DEVICE_EXT_CODEC +endif +ifeq ($(AF_DEVICE_I2S),1) +CFLAGS_audioflinger.o += -DAF_DEVICE_I2S +endif +ifeq ($(AF_DEVICE_TDM),1) +CFLAGS_audioflinger.o += -DAF_DEVICE_TDM +endif +ifeq ($(AF_DEVICE_INT_CODEC),1) +CFLAGS_audioflinger.o += -DAF_DEVICE_INT_CODEC +endif +ifeq ($(AF_DEVICE_SPDIF),1) +CFLAGS_audioflinger.o += -DAF_DEVICE_SPDIF +endif +ifeq ($(AF_DEVICE_BT_PCM),1) +CFLAGS_audioflinger.o += -DAF_DEVICE_BT_PCM +endif +ifeq ($(AF_DEVICE_DPD_RX),1) +CFLAGS_audioflinger.o += -DAF_DEVICE_DPD_RX +endif +ifeq ($(AUDIO_ANC_FB_MC),1) +CFLAGS_audioflinger.o += -DAF_DEVICE_MC +endif + +#------------------------------- +# End +#------------------------------- + diff --git a/services/audioflinger/audioflinger.c b/services/audioflinger/audioflinger.c new file mode 100644 index 0000000..4669a29 --- /dev/null +++ b/services/audioflinger/audioflinger.c @@ -0,0 +1,3258 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "audioflinger.h" +#include "hal_dma.h" +#include "hal_i2s.h" +#include "hal_tdm.h" +#include "hal_codec.h" +#include "hal_spdif.h" +#include "hal_btpcm.h" +#include "codec_tlv32aic32.h" +#include "codec_int.h" + +#include "string.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_timer.h" +#include "pmu.h" +#include "analog.h" +#include "tgt_hardware.h" + +#include "cmsis.h" + +#ifdef __RAND_FROM_MIC__ +#include "randfrommic.h" +#endif + +#ifdef TWS_PROMPT_SYNC +extern void tws_playback_ticks_check_for_mix_prompt(void); +#endif + + +#ifdef RTOS +#include "cmsis_os.h" +#else +#include "hal_sleep.h" +#endif + +#ifdef AUDIO_OUTPUT_SW_LIMITER +#include "floatlimiter.h" +#endif + +#if defined(CHIP_BEST2001) && defined(FPGA) +#undef FPGA +#endif + +#define AF_TRACE_DEBUG() // TRACE(2,"%s:%d\n", __func__, __LINE__) + +//#define AF_STREAM_ID_0_PLAYBACK_FADEOUT + +//#define CORRECT_SAMPLE_VALUE + +#ifdef FPGA +#define AF_DEVICE_EXT_CODEC +#endif +#ifdef AUDIO_OUTPUT_DC_CALIB +#ifdef CHIP_BEST1000 +#define AUDIO_OUTPUT_DC_CALIB_SW +#define AUDIO_OUTPUT_PA_ON_FADE_IN +#if !(defined(__TWS__) || defined(IBRT)) +#define AUDIO_OUTPUT_PA_OFF_FADE_OUT +#endif +#elif (defined(__TWS__) || defined(IBRT)) && !defined(ANC_APP) +#define AUDIO_OUTPUT_PA_ON_FADE_IN +#endif // !CHIP_BEST1000 && __TWS__ +#elif defined(AUDIO_OUTPUT_DC_CALIB_ANA) && (defined(__TWS__) || defined(IBRT)) && !defined(ANC_APP) +#define AUDIO_OUTPUT_PA_ON_FADE_IN +#endif // !AUDIO_OUTPUT_DC_CALIB && AUDIO_OUTPUT_DC_CALIB_ANA && __TWS__ + +#define AF_FADE_OUT_SIGNAL_ID 15 +#define AF_FADE_IN_SIGNAL_ID 14 + +/* config params */ +#define AF_CODEC_INST HAL_CODEC_ID_0 +#define AF_SPDIF_INST HAL_SPDIF_ID_0 +#define AF_BTPCM_INST HAL_BTPCM_ID_0 + +#define AF_CPU_WAKE_USER HAL_CPU_WAKE_LOCK_USER_AUDIOFLINGER + +#define AF_CODEC_RIGHT_CHAN_ATTN 0.968277856 // -0.28 dB + +#define AF_CODEC_VOL_UPDATE_STEP 0.00002 + +#define AF_CODEC_DC_MAX_SCALE 32767 + +#define AF_CODEC_DC_STABLE_INTERVAL MS_TO_TICKS(4) +#ifdef AUDIO_OUTPUT_PA_OFF_FADE_OUT +#define AF_CODEC_PA_RESTART_INTERVAL MS_TO_TICKS(160) +#else +#define AF_CODEC_PA_RESTART_INTERVAL MS_TO_TICKS(8) +#endif + +// The following might have been defined in tgt_hardware.h +#ifndef AF_CODEC_FADE_IN_MS +#define AF_CODEC_FADE_IN_MS 20 +#endif +#ifndef AF_CODEC_FADE_OUT_MS +#define AF_CODEC_FADE_OUT_MS 20 +#endif +#define AF_CODEC_FADE_MIN_SAMPLE_CNT 200 + +#define PP_PINGPANG(v) (v == PP_PING ? PP_PANG : PP_PING) + +#ifdef AUDIO_ANC_FB_ADJ_MC +#define AF_STACK_SIZE (1024*10) +#else +#ifndef AF_STACK_SIZE +#define AF_STACK_SIZE (1024*3) +#endif +#endif + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) +#define DYNAMIC_AUDIO_BUFFER_COUNT +#endif + +#ifdef DYNAMIC_AUDIO_BUFFER_COUNT +#define MAX_AUDIO_BUFFER_COUNT 16 +#define MIN_AUDIO_BUFFER_COUNT 2 +#define AUDIO_BUFFER_COUNT (role->dma_desc_cnt) +#else +#define MAX_AUDIO_BUFFER_COUNT 4 +#define AUDIO_BUFFER_COUNT MAX_AUDIO_BUFFER_COUNT +#if (AUDIO_BUFFER_COUNT & 0x1) +#error "AUDIO_BUFFER_COUNT must be an even number" +#endif +#endif + +/* internal use */ +enum AF_BOOL_T{ + AF_FALSE = 0, + AF_TRUE = 1 +}; + +enum AF_RESULT_T{ + AF_RES_SUCCESS = 0, + AF_RES_FAILD = 1 +}; + +enum AF_DAC_PA_STATE_T { + AF_DAC_PA_NULL, + AF_DAC_PA_ON_TRIGGER, + AF_DAC_PA_ON_SOFT_START, + AF_DAC_PA_OFF_TRIGGER, + AF_DAC_PA_OFF_SOFT_END, + AF_DAC_PA_OFF_SOFT_END_DONE, + AF_DAC_PA_OFF_DC_START, +}; + +//status machine +enum AF_STATUS_T{ + AF_STATUS_NULL = 0x00, + AF_STATUS_OPEN_CLOSE = 0x01, + AF_STATUS_STREAM_OPEN_CLOSE = 0x02, + AF_STATUS_STREAM_START_STOP = 0x04, + AF_STATUS_STREAM_PAUSE_RESTART = 0x08, + AF_STATUS_MASK = 0x0F, +}; + +struct af_stream_ctl_t{ + enum AF_PP_T pp_index; //pingpong operate + uint8_t pp_cnt; //use to count the lost signals + uint8_t status; //status machine + enum AUD_STREAM_USE_DEVICE_T use_device; +}; + +struct af_stream_cfg_t { + //used inside + struct af_stream_ctl_t ctl; + + //dma buf parameters, RAM can be alloced in different way + uint8_t *dma_buf_ptr; + uint32_t dma_buf_size; + + //store stream cfg parameters + struct AF_STREAM_CONFIG_T cfg; + + //dma cfg parameters +#ifdef DYNAMIC_AUDIO_BUFFER_COUNT + uint8_t dma_desc_cnt; +#endif + struct HAL_DMA_DESC_T dma_desc[MAX_AUDIO_BUFFER_COUNT]; + struct HAL_DMA_CH_CFG_T dma_cfg; + + //callback function + AF_STREAM_HANDLER_T handler; +}; + +static struct af_stream_cfg_t af_stream[AUD_STREAM_ID_NUM][AUD_STREAM_NUM]; +static uint8_t af_sig_lost_cnt[AUD_STREAM_ID_NUM][AUD_STREAM_NUM]; + +static AF_CODEC_PLAYBACK_POST_HANDLER_T codec_play_post_hdlr; + +#ifdef AUDIO_OUTPUT_SW_GAIN +volatile static float saved_output_coef; +#ifdef AUDIO_OUTPUT_SW_LIMITER +static FloatLimiterPtr FloatLimiterP; +#else +typedef struct { + float coefs_b[3]; + float coefs_a[3]; + float history_x[2]; + float history_y[2]; +}SW_GAIN_IIR_T; +SW_GAIN_IIR_T sw_gain_iir= + { + .coefs_b={0.00000042780818597736f, 0.00000085561637195472f, 0.00000042780818597736f}, + .coefs_a={1.00000000000000000000f, -1.99738371810092970000f, 0.99738542933367369000f}, + .history_x={0,0}, + .history_y={0,0} , + }; +#endif +#endif + +#ifdef AUDIO_OUTPUT_DC_CALIB +static bool dac_dc_valid; +#ifdef AUDIO_OUTPUT_DC_CALIB_SW +static int16_t dac_dc[2]; +#endif +#endif + +#if defined(AUDIO_OUTPUT_PA_ON_FADE_IN) || defined(AUDIO_OUTPUT_PA_OFF_FADE_OUT) +static volatile enum AF_DAC_PA_STATE_T dac_pa_state; +static uint32_t dac_dc_start_time; +static uint32_t dac_pa_stop_time; +#endif + +#if defined(AUDIO_OUTPUT_PA_OFF_FADE_OUT) && defined(RTOS) +static osThreadId fade_thread_id; +#ifdef AF_STREAM_ID_0_PLAYBACK_FADEOUT +#error "Cannot enable 2 kinds of fade out codes at the same time" +#endif +#endif + +#ifdef RTOS + +#ifdef AF_STREAM_ID_0_PLAYBACK_FADEOUT +struct af_stream_fade_out_t{ + bool stop_on_process; + uint8_t stop_process_cnt; + osThreadId stop_request_tid; + uint32_t need_fadeout_len; + uint32_t need_fadeout_len_processed; +}; + +static struct af_stream_fade_out_t af_stream_fade_out ={ + .stop_on_process = false, + .stop_process_cnt = 0, + .stop_request_tid = NULL, + .need_fadeout_len = 0, + .need_fadeout_len_processed = 0, +}; +#endif + +static osThreadId af_thread_tid; + +static void af_thread(void const *argument); +osThreadDef(af_thread, osPriorityAboveNormal, 1, AF_STACK_SIZE, "audio_flinger"); +static int af_default_priority; + +osMutexId audioflinger_mutex_id = NULL; +osMutexDef(audioflinger_mutex); + +static AF_IRQ_NOTIFICATION_T irq_notif; + +#else // !RTOS + +static volatile uint32_t af_flag_lock; + +#endif // RTOS + +#ifdef CODEC_DSD +static bool af_dsd_enabled; +#endif + +void af_lock_thread(void) +{ + void * POSSIBLY_UNUSED lr = __builtin_return_address(0); +#ifdef RTOS + osMutexWait(audioflinger_mutex_id, osWaitForever); +#else + static void * POSSIBLY_UNUSED locked_lr; + ASSERT(af_flag_lock == 0, "audioflinger has been locked by %p. LR=%p", (void *)locked_lr, (void *)lr); + af_flag_lock = 1; + locked_lr = lr; +#endif +} + +void af_unlock_thread(void) +{ + void * POSSIBLY_UNUSED lr = __builtin_return_address(0); +#ifdef RTOS + osMutexRelease(audioflinger_mutex_id); +#else + static void * POSSIBLY_UNUSED unlocked_lr; + ASSERT(af_flag_lock == 1, "audioflinger not locked before (lastly unlocked by %p). LR=%p", (void *)unlocked_lr, (void *)lr); + af_flag_lock = 0; + unlocked_lr = lr; +#endif +} + +#if defined(RTOS) && defined(AF_STREAM_ID_0_PLAYBACK_FADEOUT) +int af_stream_fadeout_start(uint32_t sample) +{ + TRACE(1,"fadein_config sample:%d", sample); + af_stream_fade_out.need_fadeout_len = sample; + af_stream_fade_out.need_fadeout_len_processed = sample; + return 0; +} + +int af_stream_fadeout_stop(void) +{ + af_stream_fade_out.stop_process_cnt = 0; + af_stream_fade_out.stop_on_process = false; + return 0; +} + +uint32_t af_stream_fadeout(int16_t *buf, uint32_t len, enum AUD_CHANNEL_NUM_T num) +{ + uint32_t i; + uint32_t j = 0; + uint32_t start; + uint32_t end; + + start = af_stream_fade_out.need_fadeout_len_processed; + end = af_stream_fade_out.need_fadeout_len_processed > len ? + af_stream_fade_out.need_fadeout_len_processed - len : 0; + + if (start <= end){ +// TRACE(0,"skip fadeout"); + memset(buf, 0, len*2); + return len; + } +// TRACE(3,"fadeout l:%d start:%d end:%d", len, start, end); +// DUMP16("%05d ", buf, 10); +// DUMP16("%05d ", buf+len-10, 10); + + + if (num == AUD_CHANNEL_NUM_1){ + for (i = start; i > end; i--){ + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + } + }else if (num == AUD_CHANNEL_NUM_2){ + for (i = start; i > end; i-=2){ + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + } + }else if (num == AUD_CHANNEL_NUM_4){ + for (i = start; i > end; i-=4){ + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + } + }else if (num == AUD_CHANNEL_NUM_8){ + for (i = start; i > end; i-=8){ + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + *(buf+j) = *(buf+j)*i/af_stream_fade_out.need_fadeout_len; + j++; + } + + } + af_stream_fade_out.need_fadeout_len_processed -= j; + +// TRACE(3,"out i:%d process:%d x:%d", i, af_stream_fade_out.need_fadeout_len_processed, end+((start-end)/AUD_CHANNEL_NUM_2)); +// DUMP16("%05d ", buf, 10); +// DUMP16("%05d ", buf+len-10, 10); + + return len; +} + +void af_stream_stop_wait_finish() +{ + af_stream_fade_out.stop_on_process = true; + af_stream_fade_out.stop_request_tid = osThreadGetId(); + osSignalClear(af_stream_fade_out.stop_request_tid, (1 << AF_FADE_OUT_SIGNAL_ID)); + af_unlock_thread(); + osSignalWait((1 << AF_FADE_OUT_SIGNAL_ID), 300); + af_lock_thread(); +} + +void af_stream_stop_process(struct af_stream_cfg_t *af_cfg, uint8_t *buf, uint32_t len) +{ + af_lock_thread(); + if (af_stream_fade_out.stop_on_process){ +// TRACE(5,"%s num:%d size:%d len:%d cnt:%d", __func__, af_cfg->cfg.channel_num, af_cfg->cfg.data_size, len, af_stream_fade_out.stop_process_cnt); + af_stream_fadeout((int16_t *)buf, len/2, af_cfg->cfg.channel_num); + +// TRACE(3,"process ret:%d %d %d", *(int16_t *)(buf+len-2-2-2), *(int16_t *)(buf+len-2-2), *(int16_t *)(buf+len-2)); + if (af_stream_fade_out.stop_process_cnt++>3){ + TRACE(0,"stop_process end"); + osSignalSet(af_stream_fade_out.stop_request_tid, (1 << AF_FADE_OUT_SIGNAL_ID)); + } + } + af_unlock_thread(); +} +#endif // RTOS && AF_STREAM_ID_0_PLAYBACK_FADEOUT + +//used by dma irq and af_thread +static inline struct af_stream_cfg_t *af_get_stream_role(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + ASSERT(id < AUD_STREAM_ID_NUM, "[%s] Bad id=%d", __func__, id); + ASSERT(stream < AUD_STREAM_NUM, "[%s] Bad stream=%d", __func__, stream); + + return &af_stream[id][stream]; +} + +static void af_set_status(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, enum AF_STATUS_T status) +{ + struct af_stream_cfg_t *role = NULL; + + role = af_get_stream_role(id, stream); + + role->ctl.status |= status; +} + +static void af_clear_status(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, enum AF_STATUS_T status) +{ + struct af_stream_cfg_t *role = NULL; + + role = af_get_stream_role(id, stream); + + role->ctl.status &= ~status; +} + +//get current stream config parameters +uint32_t af_stream_get_cfg(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, struct AF_STREAM_CONFIG_T **cfg, bool needlock) +{ + AF_TRACE_DEBUG(); + + struct af_stream_cfg_t *role; + enum AF_RESULT_T ret; + + if (needlock) { + af_lock_thread(); + } + role = af_get_stream_role(id, stream); + //check stream is open + if (role->ctl.status & AF_STATUS_STREAM_OPEN_CLOSE) { + *cfg = &(role->cfg); + ret = AF_RES_SUCCESS; + } else { + ret = AF_RES_FAILD; + } + if (needlock) { + af_unlock_thread(); + } + return ret; +} + +#if 0 +static void af_dump_cfg() +{ + struct af_stream_cfg_t *role = NULL; + + TRACE(0,"dump cfg.........start"); + //initial parameter + for(uint8_t id=0; id< AUD_STREAM_ID_NUM; id++) + { + for(uint8_t stream=0; stream < AUD_STREAM_NUM; stream++) + { + role = af_get_stream_role((enum AUD_STREAM_ID_T)id, (enum AUD_STREAM_T)stream); + + TRACE(2,"id = %d, stream = %d:", id, stream); + TRACE(1,"ctl.use_device = %d", role->ctl.use_device); + TRACE(1,"cfg.device = %d", role->cfg.device); + TRACE(1,"dma_cfg.ch = %d", role->dma_cfg.ch); + } + } + TRACE(0,"dump cfg.........end"); +} +#endif + +#ifdef AUDIO_OUTPUT_SW_GAIN +static void af_codec_output_gain_changed(float coef) +{ + saved_output_coef = coef; +} +#ifndef AUDIO_OUTPUT_SW_LIMITER +static float af_codec_sw_gain_filter(float gain_in) +{ + float gain_out = saved_output_coef*sw_gain_iir.coefs_b[0] + +sw_gain_iir.history_x[0]*sw_gain_iir.coefs_b[1] + +sw_gain_iir.history_x[1]*sw_gain_iir.coefs_b[2] + -sw_gain_iir.history_y[0]*sw_gain_iir.coefs_a[1] + -sw_gain_iir.history_y[1]*sw_gain_iir.coefs_a[2]; + + sw_gain_iir.history_y[1]=sw_gain_iir.history_y[0]; + sw_gain_iir.history_y[0]=gain_out; + sw_gain_iir.history_x[1]=sw_gain_iir.history_x[0]; + sw_gain_iir.history_x[0]=saved_output_coef; + + return gain_out; +} +static void af_codec_sw_gain_process(uint8_t *buf, uint32_t size, enum AUD_BITS_T bits, enum AUD_CHANNEL_NUM_T chans) +{ + uint32_t i,pcm_len; + int32_t pcm_out; + float output_gain=1.0f; + + //TRACE(1,"af_codec_sw_gain_process:%d",(int32_t)(saved_output_coef*1000)); + + if(chans==AUD_CHANNEL_NUM_1) + { + if (bits <= AUD_BITS_16) + { + pcm_len = size / sizeof(int16_t); + int16_t *pcm_buf = (int16_t *)buf; + for (i = 0; i < pcm_len; i++) + { + output_gain=af_codec_sw_gain_filter(saved_output_coef); + + pcm_out = (int32_t)(pcm_buf[i] * output_gain); + pcm_buf[i] = __SSAT(pcm_out, 16); + } + } + else + { + pcm_len = size / sizeof(int32_t); + int32_t *pcm_buf = (int32_t *)buf; + for (i = 0; i < pcm_len; i++) + { + output_gain=af_codec_sw_gain_filter(saved_output_coef); + + pcm_out = (int32_t)(pcm_buf[i] * output_gain); + pcm_buf[i] = __SSAT(pcm_out, 24); + } + } + } + else if(chans==AUD_CHANNEL_NUM_2) + { + if (bits <= AUD_BITS_16) + { + pcm_len = size / sizeof(int16_t); + int16_t *pcm_buf = (int16_t *)buf; + for (i = 0; i < pcm_len; i=i+2) + { + output_gain=af_codec_sw_gain_filter(saved_output_coef); + + pcm_out = (int32_t)(pcm_buf[i] * output_gain); + pcm_buf[i] = __SSAT(pcm_out, 16); + pcm_out = (int32_t)(pcm_buf[i+1] * output_gain); + pcm_buf[i+1] = __SSAT(pcm_out, 16); + } + } + else + { + pcm_len = size / sizeof(int32_t); + int32_t *pcm_buf = (int32_t *)buf; + for (i = 0; i < pcm_len; i=i+2) + { + output_gain=af_codec_sw_gain_filter(saved_output_coef); + + pcm_out = (int32_t)(pcm_buf[i] * output_gain); + pcm_buf[i] = __SSAT(pcm_out, 24); + pcm_out = (int32_t)(pcm_buf[i+1] * output_gain); + pcm_buf[i+1] = __SSAT(pcm_out, 24); + } + } + } +} +#endif +#endif // AUDIO_OUTPUT_SW_GAIN + +static uint32_t POSSIBLY_UNUSED af_codec_get_sample_count(uint32_t size, enum AUD_BITS_T bits, enum AUD_CHANNEL_NUM_T chans) +{ + uint32_t div; + + if (bits <= AUD_BITS_16) { + div = 2; + } else { + div = 4; + } + div *= chans; + return size / div; +} + +static void POSSIBLY_UNUSED af_zero_mem(void *dst, unsigned int size) +{ + uint32_t *d = dst; + uint32_t count = size / 4; + + while (count--) { + *d++ = 0; + } +} + +static bool af_codec_playback_pre_handler(uint8_t *buf, uint32_t len, const struct af_stream_cfg_t *role) +{ + uint32_t POSSIBLY_UNUSED time; + + if (0) { + +#ifdef AUDIO_OUTPUT_PA_ON_FADE_IN + } else if (dac_pa_state == AF_DAC_PA_ON_TRIGGER && + (time = hal_sys_timer_get()) - dac_dc_start_time >= AF_CODEC_DC_STABLE_INTERVAL && + time - dac_pa_stop_time >= AF_CODEC_PA_RESTART_INTERVAL) { + analog_aud_codec_speaker_enable(true); + dac_pa_state = AF_DAC_PA_NULL; +#endif // AUDIO_OUTPUT_PA_ON_FADE_IN + +#ifdef AUDIO_OUTPUT_PA_OFF_FADE_OUT + } else if (dac_pa_state == AF_DAC_PA_OFF_TRIGGER) { + dac_dc_start_time = hal_sys_timer_get(); + dac_pa_state = AF_DAC_PA_OFF_DC_START; + } else if (dac_pa_state == AF_DAC_PA_OFF_DC_START) { + time = hal_sys_timer_get(); + if (time - dac_dc_start_time >= AF_CODEC_DC_STABLE_INTERVAL) { + dac_pa_state = AF_DAC_PA_NULL; + analog_aud_codec_speaker_enable(false); + dac_pa_stop_time = time; +#ifdef RTOS + osSignalSet(fade_thread_id, (1 << AF_FADE_OUT_SIGNAL_ID)); +#endif + } +#endif // AUDIO_OUTPUT_PA_OFF_FADE_OUT + + } + +#if defined(AUDIO_OUTPUT_PA_ON_FADE_IN) || defined(AUDIO_OUTPUT_PA_OFF_FADE_OUT) + if (dac_pa_state == AF_DAC_PA_ON_TRIGGER || dac_pa_state == AF_DAC_PA_OFF_DC_START) { + af_zero_mem(buf, len); + return true; + } +#endif + + return false; +} + +#ifdef AUDIO_OUTPUT_DC_CALIB_SW +static void af_codec_playback_sw_dc_calib(uint8_t *buf, uint32_t len, enum AUD_BITS_T bits, enum AUD_CHANNEL_NUM_T chans) +{ + uint32_t cnt; + + if (bits <= AUD_BITS_16) { + int16_t *ptr16 = (int16_t *)buf; +#ifdef AUDIO_OUTPUT_DC_CALIB_SW + int16_t dc_l = dac_dc[0]; + int16_t dc_r = dac_dc[1]; +#endif + if (chans == AUD_CHANNEL_NUM_1) { + cnt = len / sizeof(int16_t); + while (cnt-- > 0) { +#ifdef AUDIO_OUTPUT_DC_CALIB_SW + *ptr16 = __SSAT(*ptr16 + dc_l, 16); +#endif + ptr16++; + } + } else { + cnt = len / sizeof(int16_t) / 2; + while (cnt-- > 0) { +#ifdef AUDIO_OUTPUT_DC_CALIB_SW + *ptr16 = __SSAT(*ptr16 + dc_l, 16); + *(ptr16 + 1) = __SSAT(*(ptr16 + 1) + dc_r, 16); +#endif + ptr16 += 2; + } + } + } else { + int32_t *ptr32 = (int32_t *)buf; + int32_t dac_bits = +#ifdef CHIP_BEST1000 + CODEC_PLAYBACK_BIT_DEPTH; +#else + 24; +#endif + int32_t val_shift; + + if (dac_bits < 24) { + val_shift = 24 - dac_bits; + } else { + val_shift = 0; + } + +#ifdef AUDIO_OUTPUT_DC_CALIB_SW + int32_t dc_l = dac_dc[0] << 8; + int32_t dc_r = dac_dc[1] << 8; +#endif + if (chans == AUD_CHANNEL_NUM_1) { + cnt = len / sizeof(int32_t); + while (cnt-- > 0) { +#ifdef CORRECT_SAMPLE_VALUE + *ptr32 = ((*ptr32) << (32 - dac_bits)) >> (32 - dac_bits); +#endif +#ifdef AUDIO_OUTPUT_DC_CALIB_SW + *ptr32 = __SSAT((*ptr32 + dc_l) >> val_shift, dac_bits); +#elif defined(CORRECT_SAMPLE_VALUE) + *ptr32 = __SSAT(*ptr32 >> val_shift, dac_bits); +#else + *ptr32 = *ptr32 >> val_shift; +#endif + ptr32++; + } + } else { + cnt = len / sizeof(int32_t) / 2; + while (cnt-- > 0) { +#ifdef CORRECT_SAMPLE_VALUE + *ptr32 = ((*ptr32) << (32 - dac_bits)) >> (32 - dac_bits); + *(ptr32 + 1) = ((*(ptr32 + 1)) << (32 - dac_bits)) >> (32 - dac_bits); +#endif +#ifdef AUDIO_OUTPUT_DC_CALIB_SW + *ptr32 = __SSAT((*ptr32 + dc_l) >> val_shift, dac_bits); + *(ptr32 + 1) = __SSAT((*(ptr32 + 1) + dc_r) >> val_shift, dac_bits); +#elif defined(CORRECT_SAMPLE_VALUE) + *ptr32 = __SSAT(*ptr32 >> val_shift, dac_bits); + *(ptr32 + 1) = __SSAT(*(ptr32 + 1) >> val_shift, dac_bits); +#else + *ptr32 = *ptr32 >> val_shift; + *(ptr32 + 1) = *(ptr32 + 1) >> val_shift; +#endif + ptr32 += 2; + } + } + } +} +#endif // AUDIO_OUTPUT_DC_CALIB_SW + +static void af_codec_playback_post_handler(uint8_t *buf, uint32_t len, const struct af_stream_cfg_t *role) +{ + POSSIBLY_UNUSED enum AUD_BITS_T bits; + POSSIBLY_UNUSED enum AUD_CHANNEL_NUM_T chans; + POSSIBLY_UNUSED uint32_t cnt; + + bits = role->cfg.bits; + chans = role->cfg.channel_num; + +#ifdef AUDIO_OUTPUT_SW_GAIN +#ifdef AUDIO_OUTPUT_SW_LIMITER + if (bits <= AUD_BITS_16) { + cnt = len / sizeof(int16_t); + } else { + cnt = len / sizeof(int32_t); + } + ApplyFloatLimiter(FloatLimiterP, buf, saved_output_coef, cnt); +#else + af_codec_sw_gain_process(buf,len,bits,chans); +#endif +#endif + + if (codec_play_post_hdlr) { + codec_play_post_hdlr(buf, len, (void *)&role->cfg); + } + +#if defined(AUDIO_OUTPUT_INVERT_RIGHT_CHANNEL) + if (chans == AUD_CHANNEL_NUM_2) { + if (bits == AUD_BITS_16) { + int16_t *buf16 = (int16_t *)buf; + for (int i = 1; i < len / sizeof(int16_t); i += 2) { + int32_t tmp = -buf16[i]; + buf16[i] = __SSAT(tmp, 16); + } + } else { + int32_t *buf32 = (int32_t *)buf; + for (int i = 1; i < len / sizeof(int32_t); i += 2) { + int32_t tmp = -buf32[i]; + buf32[i] = __SSAT(tmp, 24); + } + } + } +#endif + +#if (defined(CHIP_BEST1000) || defined(CHIP_BEST2000)) && defined(AUDIO_OUTPUT_CALIB_GAIN_MISSMATCH) + // gain must less than 1.0 + float gain = 0.9441f; + if (chans == AUD_CHANNEL_NUM_2) { + if (bits == AUD_BITS_16) { + int16_t *buf16 = (int16_t *)buf; + for (int i = 1; i < len / sizeof(int16_t); i += 2) { + int32_t tmp = (int)(buf16[i + 1] * gain); + buf16[i + 1] = __SSAT(tmp, 16); + } + } else { + int32_t *buf32 = (int32_t *)buf; + for (int i = 1; i < len / sizeof(int32_t); i += 2) { + int32_t tmp = (int)(buf32[i + 1] * gain); + buf32[i + 1] = __SSAT(tmp, 24); + } + } + } +#endif + +#if defined(AUDIO_OUTPUT_DC_CALIB_SW) + af_codec_playback_sw_dc_calib(buf, len, bits, chans); +#elif defined(CHIP_BEST1000) + if (bits == AUD_BITS_24 || bits == AUD_BITS_32) { + int32_t *ptr32 = (int32_t *)buf; + int32_t val_shift; + + if (bits == AUD_BITS_24) { + val_shift = 24 - CODEC_PLAYBACK_BIT_DEPTH; + } else { + val_shift = 32 - CODEC_PLAYBACK_BIT_DEPTH; + } + + cnt = len / sizeof(int32_t); + while (cnt-- > 0) { + *ptr32 >>= val_shift; + ptr32++; + } + } +#endif + +#if defined(CHIP_BEST1000) && defined(AUDIO_OUTPUT_GAIN_M60DB_CHECK) + hal_codec_dac_gain_m60db_check(HAL_CODEC_PERF_TEST_M60DB); +#endif +} + +static inline void af_thread_stream_handler(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + uint32_t lock; + struct af_stream_cfg_t *role; + uint32_t dma_addr, hw_pos; + uint8_t *buf; + uint32_t len; + uint32_t pp_cnt; + bool codec_playback; + bool skip_handler; + enum AF_PP_T pp_index; + + role = af_get_stream_role(id, stream); + + af_lock_thread(); + + if (role->handler && (role->ctl.status & AF_STATUS_STREAM_START_STOP)) { + lock = int_lock(); + pp_cnt = role->ctl.pp_cnt; + role->ctl.pp_cnt = 0; + int_unlock(lock); + + af_sig_lost_cnt[id][stream] = pp_cnt - 1; + if (af_sig_lost_cnt[id][stream]) { + TRACE(3,"af_thread:WARNING: id=%d stream=%d lost %u signals", id, stream, af_sig_lost_cnt[id][stream]); + } + + pp_index = PP_PINGPANG(role->ctl.pp_index); + + // Get PP index from accurate DMA pos + dma_addr = af_stream_get_cur_dma_addr(id, stream); + hw_pos = dma_addr - (uint32_t)role->dma_buf_ptr; + if (hw_pos > role->dma_buf_size) { + TRACE(3,"af_thread: Failed to get valid dma addr for id=%d stream=%d: 0x%08x", id, stream, dma_addr); + } +#ifndef CHIP_BEST1000 + if (role->cfg.chan_sep_buf && role->cfg.channel_num > AUD_CHANNEL_NUM_1) { + uint32_t chan_size; + + chan_size = role->dma_buf_size / role->cfg.channel_num; + + if (hw_pos <= role->dma_buf_size) { + hw_pos = hw_pos % chan_size; + if (hw_pos < chan_size / 2) { + pp_index = PP_PANG; + } else if (hw_pos < chan_size) { + pp_index = PP_PING; + } + } + if (pp_index == PP_PING) { + buf = role->dma_buf_ptr; + } else { + buf = role->dma_buf_ptr + chan_size / 2; + } + } else +#endif + { + if (hw_pos < role->dma_buf_size / 2) { + pp_index = PP_PANG; + } else if (hw_pos < role->dma_buf_size) { + pp_index = PP_PING; + } + if (pp_index == PP_PING) { + buf = role->dma_buf_ptr; + } else { + buf = role->dma_buf_ptr + role->dma_buf_size / 2; + } + } + + if (stream == AUD_STREAM_PLAYBACK && role->ctl.use_device == AUD_STREAM_USE_INT_CODEC) { + codec_playback = true; + } else { + codec_playback = false; + } + + skip_handler = false; + len = role->dma_buf_size / 2; + + if (codec_playback) { + skip_handler = af_codec_playback_pre_handler(buf, len, role); + } + + if (!skip_handler) { +#ifdef __RAND_FROM_MIC__ + if ((AUD_STREAM_CAPTURE == stream) && (AUD_STREAM_USE_INT_CODEC == role->cfg.device)) + { + random_data_process(buf, role->dma_buf_size / 2, role->cfg.bits, role->cfg.channel_num); + } +#endif + role->handler(buf, len); + } + + if (codec_playback) { + af_codec_playback_post_handler(buf, len, role); + } + +#if defined(RTOS) && defined(AF_STREAM_ID_0_PLAYBACK_FADEOUT) + af_stream_stop_process(role, buf, len); +#endif + + if (role->ctl.pp_cnt) { + TRACE(3,"af_thread:WARNING: id=%d stream=%d hdlr ran too long (pp_cnt=%u)", id, stream, role->ctl.pp_cnt); + } + } + + af_unlock_thread(); +} + +#ifdef RTOS + +static void af_thread(void const *argument) +{ + osEvent evt; + uint32_t signals = 0; + enum AUD_STREAM_ID_T id; + enum AUD_STREAM_T stream; + + while(1) + { + //wait any signal + evt = osSignalWait(0x0, osWaitForever); + signals = evt.value.signals; +// TRACE(3,"[%s] status = %x, signals = %d", __func__, evt.status, evt.value.signals); + + if(evt.status == osEventSignal) + { + for(uint8_t i=0; i> 1); + stream = (enum AUD_STREAM_T)(i & 1); + + af_thread_stream_handler(id, stream); + + } + } + } + else + { + TRACE(2,"[%s] ERROR: evt.status = %d", __func__, evt.status); + continue; + } + } +} + +#else // !RTOS + +#include "cmsis.h" +static volatile uint32_t af_flag_open; +static volatile uint32_t af_flag_signal; + +static void af_set_flag(volatile uint32_t *flag, uint32_t set) +{ + uint32_t lock; + + lock = int_lock(); + *flag |= set; + int_unlock(lock); +} + +static void af_clear_flag(volatile uint32_t *flag, uint32_t clear) +{ + uint32_t lock; + + lock = int_lock(); + *flag &= ~clear; + int_unlock(lock); +} + +static bool af_flag_active(volatile uint32_t *flag, uint32_t bits) +{ + return !!(*flag & bits); +} + +void af_thread(void const *argument) +{ + uint32_t lock; + uint32_t i; + enum AUD_STREAM_ID_T id; + enum AUD_STREAM_T stream; + + if (af_flag_open == 0) { + return; + } + + for (i = 0; i < AUD_STREAM_ID_NUM * AUD_STREAM_NUM; i++) { + if (!af_flag_active(&af_flag_signal, 1 << i)) { + continue; + } + af_clear_flag(&af_flag_signal, 1 << i); + + id = (enum AUD_STREAM_ID_T)(i >> 1); + stream = (enum AUD_STREAM_T)(i & 1); + + af_thread_stream_handler(id, stream); + } + + lock = int_lock(); + if (af_flag_signal == 0) { + hal_cpu_wake_unlock(AF_CPU_WAKE_USER); + } + int_unlock(lock); +} + +#endif // !RTOS + +static void af_dma_irq_handler(uint8_t ch, uint32_t remain_dst_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli) +{ + struct af_stream_cfg_t *role = NULL; + + //initial parameter + for(uint8_t id=0; id< AUD_STREAM_ID_NUM; id++) + { + for(uint8_t stream=0; stream < AUD_STREAM_NUM; stream++) + { + role = af_get_stream_role((enum AUD_STREAM_ID_T)id, (enum AUD_STREAM_T)stream); + + if(role->dma_cfg.ch == ch) + { + role->ctl.pp_index = PP_PINGPANG(role->ctl.pp_index); + role->ctl.pp_cnt++; + //TRACE(4,"[%s] id = %d, stream = %d, ch = %d", __func__, id, stream, ch); + //TRACE(2,"[%s] PLAYBACK pp_cnt = %d", __func__, role->ctl.pp_cnt); +#ifdef RTOS + if (irq_notif) { + irq_notif(id, stream); + } + osSignalSet(af_thread_tid, 0x01 << (id * 2 + stream)); +#else + af_set_flag(&af_flag_signal, 0x01 << (id * 2 + stream)); + hal_cpu_wake_lock(AF_CPU_WAKE_USER); +#endif + return; + } + } + } + + //invalid dma irq + ASSERT(0, "[%s] ERROR: channel id = %d", __func__, ch); +} + +#ifdef __CODEC_ASYNC_CLOSE__ +static void af_codec_async_close(void) +{ + af_lock_thread(); + codec_int_close(CODEC_CLOSE_ASYNC_REAL); + af_unlock_thread(); +} +#endif + +void *af_thread_tid_get(void) +{ +#ifdef RTOS + return (void *)af_thread_tid; +#else + return NULL; +#endif +} + +#ifdef CODEC_ANC_BOOST +static void af_codec_anc_boost_delay(uint32_t ms) +{ + af_unlock_thread(); + + osDelay(ms); + + af_lock_thread(); +} +#endif + +uint32_t af_open(void) +{ + AF_TRACE_DEBUG(); + struct af_stream_cfg_t *role = NULL; + +#ifdef RTOS + if (audioflinger_mutex_id == NULL) + { + audioflinger_mutex_id = osMutexCreate((osMutex(audioflinger_mutex))); + } +#endif + + af_lock_thread(); + +#ifdef AUDIO_OUTPUT_DC_CALIB + if (!dac_dc_valid) { + int16_t dc_l, dc_r; + uint16_t max_dc; + float attn; + + dac_dc_valid = true; + analog_aud_get_dc_calib_value(&dc_l, &dc_r); + if (ABS(dc_l) >= ABS(dc_r)) { + max_dc = ABS(dc_l); + } else { + max_dc = ABS(dc_r); + } + ASSERT(max_dc + 1 < AF_CODEC_DC_MAX_SCALE, "Bad dc values: (%d, %d)", dc_l, dc_r); + if (max_dc) { + attn = 1 - (float)(max_dc + 1) / AF_CODEC_DC_MAX_SCALE; + } else { + attn = 1; + } + hal_codec_set_dac_dc_gain_attn(attn); +#ifdef AUDIO_OUTPUT_DC_CALIB_SW + dac_dc[0] = dc_l; + dac_dc[1] = dc_r; +#else + hal_codec_set_dac_dc_offset(dc_l, dc_r); +#endif + } +#endif + +#ifdef AUDIO_OUTPUT_SW_GAIN + hal_codec_set_sw_output_coef_callback(af_codec_output_gain_changed); +#endif + +#ifdef __CODEC_ASYNC_CLOSE__ + codec_int_set_close_handler(af_codec_async_close); +#endif + +#ifdef CODEC_ANC_BOOST + codec_set_anc_boost_delay_func(af_codec_anc_boost_delay); +#endif + + //initial parameters + for(uint8_t id=0; id< AUD_STREAM_ID_NUM; id++) + { + for(uint8_t stream=0; stream < AUD_STREAM_NUM; stream++) + { + role = af_get_stream_role((enum AUD_STREAM_ID_T)id, (enum AUD_STREAM_T)stream); + + if(role->ctl.status == AF_STATUS_NULL) + { + role->dma_buf_ptr = NULL; + role->dma_buf_size = 0; + role->ctl.pp_index = PP_PING; + role->ctl.status = AF_STATUS_OPEN_CLOSE; + role->ctl.use_device = AUD_STREAM_USE_DEVICE_NULL; + role->dma_cfg.ch = HAL_DMA_CHAN_NONE; + } + else + { + ASSERT(0, "[%s] ERROR: id = %d, stream = %d", __func__, id, stream); + } + } + } + +#ifdef RTOS + af_thread_tid = osThreadCreate(osThread(af_thread), NULL); + af_default_priority = af_get_priority(); + osSignalSet(af_thread_tid, 0x0); +#endif +#ifdef __RAND_FROM_MIC__ + randInit(); +#endif + af_unlock_thread(); + + return AF_RES_SUCCESS; +} + +static void af_stream_update_dma_buffer(enum AUD_STREAM_T stream, struct af_stream_cfg_t *role, const struct AF_STREAM_CONFIG_T *cfg) +{ + int i; + enum HAL_DMA_RET_T dma_ret; + struct HAL_DMA_DESC_T *dma_desc, *next_desc; + struct HAL_DMA_CH_CFG_T *dma_cfg; + int irq; + uint32_t desc_xfer_size; + uint32_t align; + uint8_t samp_size; + enum HAL_DMA_WDITH_T width; +#ifndef CHIP_BEST1000 + bool dma_2d_en; + uint32_t chan_desc_xfer_size = 0; +#endif + + dma_desc = &role->dma_desc[0]; + dma_cfg = &role->dma_cfg; + +#ifdef CODEC_DSD + if (stream == AUD_STREAM_PLAYBACK && role->cfg.device == AUD_STREAM_USE_INT_CODEC) { + if (dma_cfg->dst_periph == HAL_AUDMA_DSD_TX) { + dma_cfg->dst_bsize = HAL_DMA_BSIZE_1; + } else { + dma_cfg->dst_bsize = HAL_DMA_BSIZE_4; + } + } +#endif + + + if(role->cfg.device == AUD_STREAM_USE_BT_PCM) + { + dma_cfg->dst_bsize = HAL_DMA_BSIZE_1; + dma_cfg->src_bsize = HAL_DMA_BSIZE_1; + dma_cfg->try_burst = 0; + } + + role->dma_buf_ptr = cfg->data_ptr; + role->dma_buf_size = cfg->data_size; + + if (cfg->bits == AUD_BITS_24 || cfg->bits == AUD_BITS_32) { + width = HAL_DMA_WIDTH_WORD; + samp_size = 4; + } else if (cfg->bits == AUD_BITS_16) { + width = HAL_DMA_WIDTH_HALFWORD; + samp_size = 2; + } else { + ASSERT(false, "%s: Invalid stream config bits=%d", __func__, cfg->bits); + width = HAL_DMA_WIDTH_BYTE; + samp_size = 1; + } + +#ifdef DYNAMIC_AUDIO_BUFFER_COUNT + uint32_t desc_cnt; + + desc_cnt = (cfg->data_size / samp_size + HAL_DMA_MAX_DESC_XFER_SIZE - 1) / HAL_DMA_MAX_DESC_XFER_SIZE; + if (desc_cnt < 2) { + desc_cnt = 2; + } else if (desc_cnt & (desc_cnt - 1)) { + desc_cnt = 1 << (31 - __CLZ(desc_cnt) + 1); + } + TRACE(4,"%s: desc_cnt=%u data_size=%u samp_size=%u", __func__, desc_cnt, cfg->data_size, samp_size); + ASSERT(MIN_AUDIO_BUFFER_COUNT <= desc_cnt && desc_cnt <= MAX_AUDIO_BUFFER_COUNT, "%s: Bad desc_cnt=%u", __func__, desc_cnt); + role->dma_desc_cnt = desc_cnt; +#endif + + desc_xfer_size = cfg->data_size / AUDIO_BUFFER_COUNT; + +#ifndef CHIP_BEST1000 + if (cfg->chan_sep_buf && cfg->channel_num > AUD_CHANNEL_NUM_1) { + dma_2d_en = true; + } else { + dma_2d_en = false; + } + + if (dma_2d_en) { + enum HAL_DMA_BSIZE_T bsize; + uint8_t burst_size; + + chan_desc_xfer_size = desc_xfer_size / cfg->channel_num; + + if (stream == AUD_STREAM_PLAYBACK) { + bsize = dma_cfg->src_bsize; + } else { + bsize = dma_cfg->dst_bsize; + } + if (bsize == HAL_DMA_BSIZE_1) { + burst_size = 1; + } else if (bsize == HAL_DMA_BSIZE_4) { + burst_size = 4; + } else { + burst_size = 8; + } + align = burst_size * samp_size * cfg->channel_num; + // Ensure word-aligned too + if (align & 0x1) { + align *= 4; + } else if (align & 0x2) { + align *= 2; + } + } else +#endif + { + align = 4; + } + ASSERT(desc_xfer_size * AUDIO_BUFFER_COUNT == cfg->data_size && (desc_xfer_size % align) == 0, + "%s: Dma data size is not aligned: data_size=%u AUDIO_BUFFER_COUNT=%u align=%u", + __func__, cfg->data_size, AUDIO_BUFFER_COUNT, align); + + dma_cfg->dst_width = width; + dma_cfg->src_width = width; + dma_cfg->src_tsize = desc_xfer_size / samp_size; + + for (i = 0; i < AUDIO_BUFFER_COUNT; i++) { + if (i == AUDIO_BUFFER_COUNT - 1) { + next_desc = &dma_desc[0]; + irq = 1; + } else { + next_desc = &dma_desc[i + 1]; + if (i == AUDIO_BUFFER_COUNT / 2 - 1) { + irq = 1; + } else { + irq = 0; + } + } + + if (stream == AUD_STREAM_PLAYBACK) { +#ifndef CHIP_BEST1000 + if (dma_2d_en) { + dma_cfg->src = (uint32_t)(role->dma_buf_ptr + chan_desc_xfer_size * i); + } else +#endif + { + dma_cfg->src = (uint32_t)(role->dma_buf_ptr + desc_xfer_size * i); + } + } else { +#ifndef CHIP_BEST1000 + if (dma_2d_en) { + dma_cfg->dst = (uint32_t)(role->dma_buf_ptr + chan_desc_xfer_size * i); + } else +#endif + { + dma_cfg->dst = (uint32_t)(role->dma_buf_ptr + desc_xfer_size * i); + } + } + + dma_ret = hal_audma_init_desc(&dma_desc[i], dma_cfg, next_desc, irq); + ASSERT(dma_ret == HAL_DMA_OK, "[%s] Failed to init dma desc for stream %d: ret=%d", __func__, stream, dma_ret); + } +} + +// Support memory<-->peripheral +// Note: Do not support peripheral <--> peripheral +uint32_t af_stream_open(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, const struct AF_STREAM_CONFIG_T *cfg) +{ + AF_TRACE_DEBUG(); + struct af_stream_cfg_t *role; + enum AF_RESULT_T ret; + enum AUD_STREAM_USE_DEVICE_T device; + struct HAL_DMA_CH_CFG_T *dma_cfg = NULL; + +#ifdef __RAND_FROM_MIC__ + random_status_sync(); +#endif + + role = af_get_stream_role(id, stream); + TRACE(3,"[%s] id = %d, stream = %d", __func__, id, stream); + + ASSERT(cfg->data_ptr != NULL, "[%s] ERROR: data_ptr == NULL!!!", __func__); + ASSERT(((uint32_t)cfg->data_ptr) % 4 == 0, "[%s] ERROR: data_ptr(%p) is not align!!!", __func__, cfg->data_ptr); + ASSERT(cfg->data_size != 0, "[%s] ERROR: data_size == 0!!!", __func__); +#ifndef CHIP_BEST1000 + if (cfg->chan_sep_buf && cfg->channel_num > AUD_CHANNEL_NUM_1) { + ASSERT(cfg->device == AUD_STREAM_USE_INT_CODEC || + cfg->device == AUD_STREAM_USE_I2S0_MASTER || cfg->device == AUD_STREAM_USE_I2S0_SLAVE || + cfg->device == AUD_STREAM_USE_I2S1_MASTER || cfg->device == AUD_STREAM_USE_I2S1_SLAVE || + cfg->device == AUD_STREAM_USE_TDM0_MASTER || cfg->device == AUD_STREAM_USE_TDM0_SLAVE || + cfg->device == AUD_STREAM_USE_TDM1_MASTER || cfg->device == AUD_STREAM_USE_TDM1_SLAVE, + "[%s] ERROR: Unsupport chan_sep_buf for device %d", __func__, cfg->device); + } +#endif + + ret = AF_RES_FAILD; + + af_lock_thread(); + + //check af is open + if(role->ctl.status != AF_STATUS_OPEN_CLOSE) + { + TRACE(2,"[%s] ERROR: status = %d",__func__, role->ctl.status); + goto _exit; + } + + role->cfg = *cfg; + + device = cfg->device; + role->ctl.use_device = device; + + dma_cfg = &role->dma_cfg; + memset(dma_cfg, 0, sizeof(*dma_cfg)); + + if(device == AUD_STREAM_USE_BT_PCM) + { + dma_cfg->dst_bsize = HAL_DMA_BSIZE_1; + dma_cfg->src_bsize = HAL_DMA_BSIZE_1; + dma_cfg->try_burst = 0; + } + else + { + dma_cfg->dst_bsize = HAL_DMA_BSIZE_4; + +#ifndef CHIP_BEST1000 + // If channel num > 1, burst size should be set to 1 for: + // 1) all playback streams with 2D DMA enabled; or + // 2) internal codec capture streams with 2D DMA disabled. + if (cfg->channel_num > AUD_CHANNEL_NUM_1 && + ((stream == AUD_STREAM_PLAYBACK && cfg->chan_sep_buf) || + (device == AUD_STREAM_USE_INT_CODEC && stream == AUD_STREAM_CAPTURE && !cfg->chan_sep_buf))) { + dma_cfg->src_bsize = HAL_DMA_BSIZE_1; + } else +#endif + { + dma_cfg->src_bsize = HAL_DMA_BSIZE_4; + } + dma_cfg->try_burst = 1; + } + + dma_cfg->handler = af_dma_irq_handler; + + if (stream == AUD_STREAM_PLAYBACK) + { + AF_TRACE_DEBUG(); + dma_cfg->src_periph = (enum HAL_DMA_PERIPH_T)0; + dma_cfg->type = HAL_DMA_FLOW_M2P_DMA; + + //open device and stream + if(0) + { + + } +#ifdef AF_DEVICE_EXT_CODEC + else if(device == AUD_STREAM_USE_EXT_CODEC) + { + AF_TRACE_DEBUG(); + tlv32aic32_open(); + tlv32aic32_stream_open(stream); + + dma_cfg->dst_periph = HAL_AUDMA_I2S0_TX; + } +#endif +#ifdef AF_DEVICE_I2S + else if(device == AUD_STREAM_USE_I2S0_MASTER) + { + AF_TRACE_DEBUG(); + hal_i2s_open(HAL_I2S_ID_0, stream, HAL_I2S_MODE_MASTER); + dma_cfg->dst_periph = HAL_AUDMA_I2S0_TX; + } + else if(device == AUD_STREAM_USE_I2S0_SLAVE) + { + AF_TRACE_DEBUG(); + hal_i2s_open(HAL_I2S_ID_0, stream, HAL_I2S_MODE_SLAVE); + dma_cfg->dst_periph = HAL_AUDMA_I2S0_TX; + } +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + else if(device == AUD_STREAM_USE_I2S1_MASTER) + { + AF_TRACE_DEBUG(); + hal_i2s_open(HAL_I2S_ID_1, stream, HAL_I2S_MODE_MASTER); + dma_cfg->dst_periph = HAL_AUDMA_I2S1_TX; + } + else if(device == AUD_STREAM_USE_I2S1_SLAVE) + { + AF_TRACE_DEBUG(); + hal_i2s_open(HAL_I2S_ID_1, stream, HAL_I2S_MODE_SLAVE); + dma_cfg->dst_periph = HAL_AUDMA_I2S1_TX; + } +#endif +#endif +#ifdef AF_DEVICE_TDM + else if(device == AUD_STREAM_USE_TDM0_MASTER) + { + AF_TRACE_DEBUG(); + hal_tdm_open(HAL_I2S_ID_0, stream, HAL_I2S_MODE_MASTER); + dma_cfg->dst_periph = HAL_AUDMA_I2S0_TX; + } + else if(device == AUD_STREAM_USE_TDM0_SLAVE) + { + AF_TRACE_DEBUG(); + hal_tdm_open(HAL_I2S_ID_0, stream, HAL_I2S_MODE_SLAVE); + dma_cfg->dst_periph = HAL_AUDMA_I2S0_TX; + } +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + else if(device == AUD_STREAM_USE_TDM1_MASTER) + { + AF_TRACE_DEBUG(); + hal_tdm_open(HAL_I2S_ID_1, stream, HAL_I2S_MODE_MASTER); + dma_cfg->dst_periph = HAL_AUDMA_I2S1_TX; + } + else if(device == AUD_STREAM_USE_TDM1_SLAVE) + { + AF_TRACE_DEBUG(); + hal_tdm_open(HAL_I2S_ID_1, stream, HAL_I2S_MODE_SLAVE); + dma_cfg->dst_periph = HAL_AUDMA_I2S1_TX; + } +#endif +#endif +#ifdef AF_DEVICE_INT_CODEC + else if(device == AUD_STREAM_USE_INT_CODEC) + { + AF_TRACE_DEBUG(); + codec_int_open(); + codec_int_stream_open(stream); + +#ifdef AUDIO_OUTPUT_SW_GAIN +#ifdef AUDIO_OUTPUT_SW_LIMITER + FLOATLIMITER_ERROR limiter_err; + + if (FloatLimiterP == NULL) { + FloatLimiterP = CreateFloatLimiter(FL_ATTACK_DEFAULT_MS, FL_RELEASE_DEFAULT_MS, FL_THRESHOLD, MAX_CHANEL, MAX_SAMPLERATE, MAX_SAMPLEBIT); + } + + limiter_err = SetFloatLimiterNChannels(FloatLimiterP, cfg->channel_num); + if (limiter_err != FLOATLIMIT_OK) { + goto _exit; + } + limiter_err = SetFloatLimiterSampleRate(FloatLimiterP, cfg->sample_rate); + if (limiter_err != FLOATLIMIT_OK) { + goto _exit; + } + limiter_err = SetFloatLimiterSampleBit(FloatLimiterP, cfg->bits); + if (limiter_err != FLOATLIMIT_OK) { + goto _exit; + } +#else + sw_gain_iir.history_x[0]=0.0f; + sw_gain_iir.history_x[1]=0.0f; + sw_gain_iir.history_y[0]=0.0f; + sw_gain_iir.history_y[1]=0.0f; +#endif +#endif + + +#ifdef CODEC_DSD + if (af_dsd_enabled) { + dma_cfg->dst_periph = HAL_AUDMA_DSD_TX; + dma_cfg->dst_bsize = HAL_DMA_BSIZE_1; + } else +#endif + { + dma_cfg->dst_periph = HAL_AUDMA_CODEC_TX; + } + } +#endif +#ifdef AF_DEVICE_SPDIF + else if(device == AUD_STREAM_USE_INT_SPDIF) + { + AF_TRACE_DEBUG(); + hal_spdif_open(AF_SPDIF_INST, stream); + dma_cfg->dst_periph = HAL_AUDMA_SPDIF0_TX; + } +#endif +#ifdef AF_DEVICE_BT_PCM + else if(device == AUD_STREAM_USE_BT_PCM) + { + AF_TRACE_DEBUG(); + hal_btpcm_open(AF_BTPCM_INST, stream); + dma_cfg->dst_periph = HAL_AUDMA_BTPCM_TX; + } +#endif +#ifdef AUDIO_ANC_FB_MC + else if(device == AUD_STREAM_USE_MC) + { + AF_TRACE_DEBUG(); + dma_cfg->dst_periph = HAL_AUDMA_MC_RX; + } +#endif + else + { + ASSERT(0, "[%s] ERROR: device %d is not defined!", __func__, device); + } + + dma_cfg->ch = hal_audma_get_chan(dma_cfg->dst_periph, HAL_DMA_HIGH_PRIO); + } + else + { + AF_TRACE_DEBUG(); + dma_cfg->dst_periph = (enum HAL_DMA_PERIPH_T)0; + dma_cfg->type = HAL_DMA_FLOW_P2M_DMA; + + //open device and stream + if(0) + { + } +#ifdef AF_DEVICE_EXT_CODEC + else if(device == AUD_STREAM_USE_EXT_CODEC) + { + AF_TRACE_DEBUG(); + tlv32aic32_open(); + tlv32aic32_stream_open(stream); + + dma_cfg->src_periph = HAL_AUDMA_I2S0_RX; + } +#endif +#ifdef AF_DEVICE_I2S + else if(device == AUD_STREAM_USE_I2S0_MASTER) + { + AF_TRACE_DEBUG(); + hal_i2s_open(HAL_I2S_ID_0, stream, HAL_I2S_MODE_MASTER); + dma_cfg->src_periph = HAL_AUDMA_I2S0_RX; + } + else if(device == AUD_STREAM_USE_I2S0_SLAVE) + { + AF_TRACE_DEBUG(); + hal_i2s_open(HAL_I2S_ID_0, stream, HAL_I2S_MODE_SLAVE); + dma_cfg->src_periph = HAL_AUDMA_I2S0_RX; + } +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + else if(device == AUD_STREAM_USE_I2S1_MASTER) + { + AF_TRACE_DEBUG(); + hal_i2s_open(HAL_I2S_ID_1, stream, HAL_I2S_MODE_MASTER); + dma_cfg->src_periph = HAL_AUDMA_I2S1_RX; + } + else if(device == AUD_STREAM_USE_I2S1_SLAVE) + { + AF_TRACE_DEBUG(); + hal_i2s_open(HAL_I2S_ID_1, stream, HAL_I2S_MODE_SLAVE); + dma_cfg->src_periph = HAL_AUDMA_I2S1_RX; + } +#endif +#endif +#ifdef AF_DEVICE_TDM + else if(device == AUD_STREAM_USE_TDM0_MASTER) + { + AF_TRACE_DEBUG(); + hal_tdm_open(HAL_I2S_ID_0, stream, HAL_I2S_MODE_MASTER); + dma_cfg->src_periph = HAL_AUDMA_I2S0_RX; + AF_TRACE_DEBUG(); + } + else if(device == AUD_STREAM_USE_TDM0_SLAVE) + { + AF_TRACE_DEBUG(); + hal_tdm_open(HAL_I2S_ID_0, stream, HAL_I2S_MODE_SLAVE); + dma_cfg->src_periph = HAL_AUDMA_I2S0_RX; + } +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + else if(device == AUD_STREAM_USE_TDM1_MASTER) + { + AF_TRACE_DEBUG(); + hal_tdm_open(HAL_I2S_ID_1, stream, HAL_I2S_MODE_MASTER); + dma_cfg->src_periph = HAL_AUDMA_I2S1_RX; + } + else if(device == AUD_STREAM_USE_TDM1_SLAVE) + { + AF_TRACE_DEBUG(); + hal_tdm_open(HAL_I2S_ID_1, stream, HAL_I2S_MODE_SLAVE); + dma_cfg->src_periph = HAL_AUDMA_I2S1_RX; + } +#endif +#endif +#ifdef AF_DEVICE_INT_CODEC + else if(device == AUD_STREAM_USE_INT_CODEC) + { + AF_TRACE_DEBUG(); + codec_int_open(); + codec_int_stream_open(stream); + + dma_cfg->src_periph = HAL_AUDMA_CODEC_RX; + } +#endif +#ifdef AF_DEVICE_SPDIF + else if(device == AUD_STREAM_USE_INT_SPDIF) + { + AF_TRACE_DEBUG(); + hal_spdif_open(AF_SPDIF_INST, stream); + + dma_cfg->src_periph = HAL_AUDMA_SPDIF0_RX; + } +#endif +#ifdef AF_DEVICE_BT_PCM + else if(device == AUD_STREAM_USE_BT_PCM) + { + AF_TRACE_DEBUG(); + hal_btpcm_open(AF_BTPCM_INST, stream); + + dma_cfg->src_periph = HAL_AUDMA_BTPCM_RX; + } +#endif +#ifdef AF_DEVICE_DPD_RX + else if(device == AUD_STREAM_USE_DPD_RX) + { + AF_TRACE_DEBUG(); + dma_cfg->src_periph = HAL_AUDMA_DPD_RX; + } +#endif + else + { + ASSERT(0, "[%s] ERROR: device %d is not defined!", __func__, device); + } + dma_cfg->ch = hal_audma_get_chan(dma_cfg->src_periph, HAL_DMA_HIGH_PRIO); + } + af_stream_update_dma_buffer(stream, role, cfg); + role->handler = cfg->handler; + + af_set_status(id, stream, AF_STATUS_STREAM_OPEN_CLOSE); +#ifndef RTOS + af_clear_flag(&af_flag_signal, 1 << (id * 2 + stream)); + af_set_flag(&af_flag_open, 1 << (id * 2 + stream)); +#endif + + AF_TRACE_DEBUG(); + ret = AF_RES_SUCCESS; + +_exit: + af_unlock_thread(); + if (ret == AF_RES_SUCCESS) { + af_stream_setup(id, stream, &role->cfg); + } + + return ret; +} + +//volume, path, sample rate, channel num ... +uint32_t af_stream_setup(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, const struct AF_STREAM_CONFIG_T *cfg) +{ + AF_TRACE_DEBUG(); + + struct af_stream_cfg_t *role; + enum AF_RESULT_T ret; + enum AUD_STREAM_USE_DEVICE_T device; + + role = af_get_stream_role(id, stream); + TRACE(3,"[%s] id = %d, stream = %d", __func__, id, stream); + + ret = AF_RES_FAILD; + + af_lock_thread(); + + //check stream is open + if(!(role->ctl.status & AF_STATUS_STREAM_OPEN_CLOSE)) + { + TRACE(2,"[%s] ERROR: status = %d", __func__, role->ctl.status); + goto _exit; + } + + device = role->ctl.use_device; + + if (&role->cfg != cfg) { + bool update_dma = false; + + if (role->cfg.bits != cfg->bits) { + TRACE(4,"[%s] Change bits from %d to %d for stream %d", __func__, role->cfg.bits, cfg->bits, stream); + update_dma = true; + } + if (role->cfg.data_ptr != cfg->data_ptr) { + TRACE(4,"[%s] Change data_ptr from %p to %p for stream %d", __func__, role->cfg.data_ptr, cfg->data_ptr, stream); + update_dma = true; + } + if (role->cfg.data_size != cfg->data_size) { + TRACE(4,"[%s] Change data_size from %d to %d for stream %d", __func__, role->cfg.data_size, cfg->data_size, stream); + update_dma = true; + } + if (update_dma) { + // To avoid FIFO corruption, streams must be stopped before changing sample size + ASSERT((role->ctl.status & AF_STATUS_STREAM_START_STOP) == 0, + "[%s] ERROR: Update dma while stream %d started", __func__, stream); + + af_stream_update_dma_buffer(stream, role, cfg); + } + + if (role->cfg.sample_rate != cfg->sample_rate) { + TRACE(4,"[%s] Change sample rate from %d to %d for stream %d", __func__, role->cfg.sample_rate, cfg->sample_rate, stream); + + // To avoid L/R sample misalignment, streams must be stopped before changing sample rate + ASSERT((role->ctl.status & AF_STATUS_STREAM_START_STOP) == 0, + "[%s] ERROR: Change sample rate from %d to %d while stream %d started", __func__, role->cfg.sample_rate, cfg->sample_rate, stream); + } + + role->cfg = *cfg; + } + + AF_TRACE_DEBUG(); + if(0) + { + } +#ifdef AF_DEVICE_EXT_CODEC + else if(device == AUD_STREAM_USE_EXT_CODEC) + { + AF_TRACE_DEBUG(); + + struct tlv32aic32_config_t tlv32aic32_cfg; + + memset(&tlv32aic32_cfg, 0, sizeof(tlv32aic32_cfg)); + tlv32aic32_cfg.bits = cfg->bits; + tlv32aic32_cfg.channel_num = cfg->channel_num; + tlv32aic32_cfg.channel_map = cfg->channel_map; + tlv32aic32_cfg.sample_rate = cfg->sample_rate; + tlv32aic32_cfg.use_dma = AF_TRUE; + tlv32aic32_cfg.chan_sep_buf = cfg->chan_sep_buf; + tlv32aic32_cfg.sync_start = cfg->sync_start; + tlv32aic32_cfg.slot_cycles = cfg->slot_cycles; + tlv32aic32_stream_setup(stream, &tlv32aic32_cfg); + } +#endif +#ifdef AF_DEVICE_I2S + else if(device == AUD_STREAM_USE_I2S0_MASTER || device == AUD_STREAM_USE_I2S0_SLAVE +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + || device == AUD_STREAM_USE_I2S1_MASTER || device == AUD_STREAM_USE_I2S1_SLAVE +#endif + ) + { + AF_TRACE_DEBUG(); + + struct HAL_I2S_CONFIG_T i2s_cfg; + enum HAL_I2S_ID_T i2s_id; + + i2s_id = HAL_I2S_ID_0; +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + if(device == AUD_STREAM_USE_I2S1_MASTER || device == AUD_STREAM_USE_I2S1_SLAVE) { + i2s_id = HAL_I2S_ID_1; + } +#endif + + memset(&i2s_cfg, 0, sizeof(i2s_cfg)); + i2s_cfg.use_dma = AF_TRUE; + i2s_cfg.chan_sep_buf = cfg->chan_sep_buf; + i2s_cfg.sync_start = cfg->sync_start; + i2s_cfg.cycles = cfg->slot_cycles; + i2s_cfg.bits = cfg->bits; + i2s_cfg.channel_num = cfg->channel_num; + i2s_cfg.channel_map = cfg->channel_map; + i2s_cfg.sample_rate = cfg->sample_rate; + hal_i2s_setup_stream(i2s_id, stream, &i2s_cfg); + } +#endif +#ifdef AF_DEVICE_TDM + else if(device == AUD_STREAM_USE_TDM0_MASTER || device == AUD_STREAM_USE_TDM0_SLAVE +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + || device == AUD_STREAM_USE_TDM1_MASTER || device == AUD_STREAM_USE_TDM1_SLAVE +#endif + ) + { + AF_TRACE_DEBUG(); + + struct HAL_TDM_CONFIG_T tdm_cfg; + enum HAL_I2S_ID_T i2s_id; + + i2s_id = HAL_I2S_ID_0; +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + if(device == AUD_STREAM_USE_TDM1_MASTER || device == AUD_STREAM_USE_TDM1_SLAVE) { + i2s_id = HAL_I2S_ID_1; + } +#endif + + memset(&tdm_cfg, 0, sizeof(tdm_cfg)); + tdm_cfg.mode = HAL_TDM_MODE_FS_ASSERTED_AT_FIRST; + tdm_cfg.edge = HAL_TDM_FS_EDGE_POSEDGE; + tdm_cfg.cycles = (cfg->channel_num * cfg->slot_cycles); + tdm_cfg.fs_cycles = cfg->fs_cycles; + tdm_cfg.slot_cycles = cfg->slot_cycles; + tdm_cfg.data_offset = 0; + tdm_cfg.sync_start = cfg->sync_start; + TRACE(5,"%s: cycle = %d, fs_cycles = %d, slot_cycles = %d,wait = %d.", + __func__, tdm_cfg.cycles, tdm_cfg.fs_cycles, tdm_cfg.slot_cycles,tdm_cfg.sync_start); + hal_tdm_setup_stream(i2s_id, stream, cfg->sample_rate, &tdm_cfg); + } + +#endif +#ifdef AF_DEVICE_INT_CODEC + else if(device == AUD_STREAM_USE_INT_CODEC) + { + AF_TRACE_DEBUG(); + struct HAL_CODEC_CONFIG_T codec_cfg; + memset(&codec_cfg, 0, sizeof(codec_cfg)); + codec_cfg.bits = cfg->bits; + codec_cfg.sample_rate = cfg->sample_rate; + codec_cfg.channel_num = cfg->channel_num; + codec_cfg.channel_map = cfg->channel_map; + codec_cfg.use_dma = AF_TRUE; + codec_cfg.vol = cfg->vol; + codec_cfg.io_path = cfg->io_path; + + AF_TRACE_DEBUG(); + codec_int_stream_setup(stream, &codec_cfg); + } +#endif +#ifdef AF_DEVICE_SPDIF + else if(device == AUD_STREAM_USE_INT_SPDIF) + { + AF_TRACE_DEBUG(); + struct HAL_SPDIF_CONFIG_T spdif_cfg; + + memset(&spdif_cfg, 0, sizeof(spdif_cfg)); + spdif_cfg.use_dma = AF_TRUE; + spdif_cfg.bits = cfg->bits; + spdif_cfg.channel_num = cfg->channel_num; + spdif_cfg.sample_rate = cfg->sample_rate; + hal_spdif_setup_stream(AF_SPDIF_INST, stream, &spdif_cfg); + } +#endif +#ifdef AF_DEVICE_BT_PCM + else if(device == AUD_STREAM_USE_BT_PCM) + { + AF_TRACE_DEBUG(); + struct HAL_BTPCM_CONFIG_T btpcm_cfg; + + memset(&btpcm_cfg, 0, sizeof(btpcm_cfg)); + btpcm_cfg.use_dma = AF_TRUE; + btpcm_cfg.bits = cfg->bits; + btpcm_cfg.channel_num = cfg->channel_num; + btpcm_cfg.sample_rate = cfg->sample_rate; + hal_btpcm_setup_stream(AF_BTPCM_INST, stream, &btpcm_cfg); + } +#endif +#ifdef AF_DEVICE_DPD_RX + else if(device == AUD_STREAM_USE_DPD_RX) + { + AF_TRACE_DEBUG(); + } +#endif +#ifdef AUDIO_ANC_FB_MC + else if(device == AUD_STREAM_USE_MC) + { + AF_TRACE_DEBUG(); + hal_codec_setup_mc(cfg->channel_num, cfg->bits); + } +#endif + else + { + ASSERT(0, "[%s] ERROR: device %d is not defined!", __func__, device); + } + + AF_TRACE_DEBUG(); + + ret = AF_RES_SUCCESS; + +_exit: + af_unlock_thread(); + + return ret; +} + +uint32_t af_stream_mute(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, bool mute) +{ + AF_TRACE_DEBUG(); + + struct af_stream_cfg_t *role; + enum AF_RESULT_T ret; + enum AUD_STREAM_USE_DEVICE_T device; + + ret = AF_RES_FAILD; + role = af_get_stream_role(id, stream); + + af_lock_thread(); + + if ((role->ctl.status & AF_STATUS_STREAM_OPEN_CLOSE) == 0) { + TRACE(2,"[%s] ERROR: status = %d", __func__, role->ctl.status); + goto _exit; + } + + device = role->ctl.use_device; + + if (device == AUD_STREAM_USE_INT_CODEC) { + codec_int_stream_mute(stream, mute); + ret = AF_RES_SUCCESS; + } + +_exit: + af_unlock_thread(); + + return ret; +} + +uint32_t af_stream_set_chan_vol(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, enum AUD_CHANNEL_MAP_T ch_map, uint8_t vol) +{ + AF_TRACE_DEBUG(); + + struct af_stream_cfg_t *role; + enum AF_RESULT_T ret; + enum AUD_STREAM_USE_DEVICE_T device; + + ret = AF_RES_FAILD; + role = af_get_stream_role(id, stream); + + af_lock_thread(); + + if ((role->ctl.status & AF_STATUS_STREAM_OPEN_CLOSE) == 0) { + TRACE(2,"[%s] ERROR: status = %d", __func__, role->ctl.status); + goto _exit; + } + + device = role->ctl.use_device; + + if (device == AUD_STREAM_USE_INT_CODEC) { + codec_int_stream_set_chan_vol(stream, ch_map, vol); + ret = AF_RES_SUCCESS; + } + +_exit: + af_unlock_thread(); + + return ret; +} + +uint32_t af_stream_restore_chan_vol(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + AF_TRACE_DEBUG(); + + struct af_stream_cfg_t *role; + enum AF_RESULT_T ret; + enum AUD_STREAM_USE_DEVICE_T device; + + ret = AF_RES_FAILD; + role = af_get_stream_role(id, stream); + + af_lock_thread(); + + if ((role->ctl.status & AF_STATUS_STREAM_OPEN_CLOSE) == 0) { + TRACE(2,"[%s] ERROR: status = %d", __func__, role->ctl.status); + goto _exit; + } + + device = role->ctl.use_device; + + if (device == AUD_STREAM_USE_INT_CODEC) { + codec_int_stream_restore_chan_vol(stream); + ret = AF_RES_SUCCESS; + } + +_exit: + af_unlock_thread(); + + return ret; +} + +#ifdef CODEC_PLAY_BEFORE_CAPTURE +static struct af_stream_cfg_t *codec_capture_role; + +static void af_codec_stream_pre_start(enum AUD_STREAM_T stream) +{ + struct af_stream_cfg_t *role = NULL; + + if (stream == AUD_STREAM_CAPTURE) { + return; + } + + for(uint8_t id=0; id< AUD_STREAM_ID_NUM; id++) + { + role = af_get_stream_role((enum AUD_STREAM_ID_T)id, AUD_STREAM_CAPTURE); + if (role->cfg.device == AUD_STREAM_USE_INT_CODEC && + role->ctl.status == (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE | AF_STATUS_STREAM_START_STOP)) { + hal_audma_stop(role->dma_cfg.ch); + codec_int_stream_stop(AUD_STREAM_CAPTURE); + codec_capture_role = role; + return; + } + } +} + +static void af_codec_stream_post_start(enum AUD_STREAM_T stream) +{ + if (stream == AUD_STREAM_CAPTURE) { + return; + } + + if (codec_capture_role) { + hal_audma_sg_start(&codec_capture_role->dma_desc[0], &codec_capture_role->dma_cfg); + codec_int_stream_start(AUD_STREAM_CAPTURE); + codec_capture_role = NULL; + } +} + +static void af_codec_stream_pre_stop(enum AUD_STREAM_T stream) +{ + struct af_stream_cfg_t *role = NULL; + + if (stream == AUD_STREAM_CAPTURE) { + return; + } + + for(uint8_t id=0; id< AUD_STREAM_ID_NUM; id++) + { + role = af_get_stream_role((enum AUD_STREAM_ID_T)id, AUD_STREAM_CAPTURE); + if (role->cfg.device == AUD_STREAM_USE_INT_CODEC && + role->ctl.status == (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE | AF_STATUS_STREAM_START_STOP)) { + hal_audma_stop(role->dma_cfg.ch); + codec_int_stream_stop(AUD_STREAM_CAPTURE); + codec_capture_role = role; + return; + } + } +} + +static void af_codec_stream_post_stop(enum AUD_STREAM_T stream) +{ + if (stream == AUD_STREAM_CAPTURE) { + return; + } + + if (codec_capture_role) { + hal_audma_sg_start(&codec_capture_role->dma_desc[0], &codec_capture_role->dma_cfg); + codec_int_stream_start(AUD_STREAM_CAPTURE); + codec_capture_role = NULL; + } +} +#endif + +uint32_t af_stream_start(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + struct af_stream_cfg_t *role; + enum AF_RESULT_T ret; + enum AUD_STREAM_USE_DEVICE_T device; + enum HAL_DMA_RET_T dma_ret; + + role = af_get_stream_role(id, stream); + TRACE(3,"[%s] id = %d, stream = %d", __func__, id, stream); + + af_lock_thread(); + + //check stream is open and not start. + if(role->ctl.status != (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE)) + { + TRACE(2,"[%s] ERROR: status = %d",__func__, role->ctl.status); + ret = AF_RES_FAILD; + goto _exit; + } + + device = role->ctl.use_device; + + role->ctl.pp_index = PP_PING; + role->ctl.pp_cnt = 0; + +#ifndef RTOS + af_clear_flag(&af_flag_signal, 1 << (id * 2 + stream)); +#endif + + if (device == AUD_STREAM_USE_INT_CODEC && stream == AUD_STREAM_PLAYBACK) { +#ifdef AUDIO_OUTPUT_PA_ON_FADE_IN + dac_pa_state = AF_DAC_PA_ON_TRIGGER; + // Has the buffer been zero-ed out? + af_zero_mem(role->dma_buf_ptr, role->dma_buf_size); +#ifdef AUDIO_OUTPUT_DC_CALIB_SW + af_codec_playback_sw_dc_calib(role->dma_buf_ptr, role->dma_buf_size, role->cfg.bits, role->cfg.channel_num); +#endif + dac_dc_start_time = hal_sys_timer_get(); +#endif + } + +#ifndef CHIP_BEST1000 + if (role->cfg.chan_sep_buf && role->cfg.channel_num > AUD_CHANNEL_NUM_1) { + struct HAL_DMA_2D_CFG_T *src, *dst; + struct HAL_DMA_2D_CFG_T dma_2d_cfg; + uint8_t burst_size = 1; + uint32_t chan_xfer_cnt; + + src = NULL; + dst = NULL; + if (stream == AUD_STREAM_PLAYBACK) { + if (role->cfg.channel_num == AUD_CHANNEL_NUM_2) { + ASSERT(role->dma_cfg.src_bsize == HAL_DMA_BSIZE_1, + "Play 2D DMA: Bad src burst size: %d", role->dma_cfg.src_bsize); + burst_size = 1; + src = &dma_2d_cfg; + } + } else { + if (role->cfg.channel_num > AUD_CHANNEL_NUM_1) { + ASSERT(role->dma_cfg.src_bsize == role->dma_cfg.dst_bsize, + "Cap 2D DMA: src burst size (%d) != dst (%d)", role->dma_cfg.src_bsize, role->dma_cfg.dst_bsize); + if (role->dma_cfg.dst_bsize == HAL_DMA_BSIZE_1) { + burst_size = 1; + } else if (role->dma_cfg.dst_bsize == HAL_DMA_BSIZE_4) { + burst_size = 4; + } else if (role->dma_cfg.dst_bsize == HAL_DMA_BSIZE_8) { + burst_size = 8; + } else { + ASSERT(false, "Cap 2D DMA: Bad dst burst size: %d", role->dma_cfg.dst_bsize); + } + dst = &dma_2d_cfg; + } + } + + if (src || dst) { + chan_xfer_cnt = role->dma_cfg.src_tsize * AUDIO_BUFFER_COUNT / role->cfg.channel_num; + dma_2d_cfg.xcount = role->cfg.channel_num; + dma_2d_cfg.xmodify = chan_xfer_cnt - burst_size; + dma_2d_cfg.ycount = chan_xfer_cnt / burst_size; + dma_2d_cfg.ymodify = -chan_xfer_cnt * (role->cfg.channel_num - 1); + } + + dma_ret = hal_dma_sg_2d_start(&role->dma_desc[0], &role->dma_cfg, src, dst); + } else +#endif + { + dma_ret = hal_dma_sg_start(&role->dma_desc[0], &role->dma_cfg); + } + ASSERT(dma_ret == HAL_DMA_OK, "[%s] Failed to start dma for stream %d: ret=%d", __func__, stream, dma_ret); + + AF_TRACE_DEBUG(); + if(0) + { + } +#ifdef AF_DEVICE_EXT_CODEC + else if(device == AUD_STREAM_USE_EXT_CODEC) + { + AF_TRACE_DEBUG(); + tlv32aic32_stream_start(stream); + } +#endif +#ifdef AF_DEVICE_I2S + else if(device == AUD_STREAM_USE_I2S0_MASTER || device == AUD_STREAM_USE_I2S0_SLAVE) + { + hal_i2s_start_stream(HAL_I2S_ID_0, stream); + } +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + else if(device == AUD_STREAM_USE_I2S1_MASTER || device == AUD_STREAM_USE_I2S1_SLAVE) + { + hal_i2s_start_stream(HAL_I2S_ID_1, stream); + } +#endif +#endif +#ifdef AF_DEVICE_TDM + else if(device == AUD_STREAM_USE_TDM0_MASTER || device == AUD_STREAM_USE_TDM0_SLAVE) + { + hal_tdm_start_stream(HAL_I2S_ID_0, stream); + } +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + else if(device == AUD_STREAM_USE_TDM1_MASTER || device == AUD_STREAM_USE_TDM1_SLAVE) + { + hal_tdm_start_stream(HAL_I2S_ID_1, stream); + } +#endif +#endif +#ifdef AF_DEVICE_INT_CODEC + else if(device == AUD_STREAM_USE_INT_CODEC) + { + AF_TRACE_DEBUG(); +#ifdef CODEC_PLAY_BEFORE_CAPTURE + af_codec_stream_pre_start(stream); +#endif + codec_int_stream_start(stream); +#ifdef CODEC_PLAY_BEFORE_CAPTURE + af_codec_stream_post_start(stream); +#endif + } +#endif +#ifdef AF_DEVICE_SPDIF + else if(device == AUD_STREAM_USE_INT_SPDIF) + { + AF_TRACE_DEBUG(); + hal_spdif_start_stream(AF_SPDIF_INST, stream); + } +#endif +#ifdef AF_DEVICE_BT_PCM + else if(device == AUD_STREAM_USE_BT_PCM) + { + AF_TRACE_DEBUG(); + hal_btpcm_start_stream(AF_BTPCM_INST, stream); + } +#endif +#ifdef AF_DEVICE_DPD_RX + else if(device == AUD_STREAM_USE_DPD_RX) + { + AF_TRACE_DEBUG(); + hal_btpcm_start_stream(AF_BTPCM_INST, stream); + } +#endif +#ifdef AUDIO_ANC_FB_MC + else if(device == AUD_STREAM_USE_MC) + { + AF_TRACE_DEBUG(); + } +#endif + else + { + ASSERT(0, "[%s] ERROR: device %d is not defined!", __func__, device); + } + + AF_TRACE_DEBUG(); + af_set_status(id, stream, AF_STATUS_STREAM_START_STOP); + + ret = AF_RES_SUCCESS; + +_exit: + af_unlock_thread(); + + return ret; +} + +uint32_t af_stream_stop(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + struct af_stream_cfg_t *role; + enum AF_RESULT_T ret; + enum AUD_STREAM_USE_DEVICE_T device; + + role = af_get_stream_role(id, stream); + TRACE(3,"[%s] id = %d, stream = %d", __func__, id, stream); + + af_lock_thread(); + + device = role->ctl.use_device; + + if (device == AUD_STREAM_USE_INT_CODEC && + role->ctl.status == (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE | AF_STATUS_STREAM_START_STOP | AF_STATUS_STREAM_PAUSE_RESTART)) + { + af_clear_status(id, stream, AF_STATUS_STREAM_PAUSE_RESTART); + goto _pause_stop; + } + + //check stream is start and not stop + if (role->ctl.status != (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE | AF_STATUS_STREAM_START_STOP)) + { + TRACE(2,"[%s] ERROR: status = %d",__func__, role->ctl.status); + ret = AF_RES_FAILD; + goto _exit; + } + +#if defined(RTOS) && defined(AF_STREAM_ID_0_PLAYBACK_FADEOUT) + if (id == AUD_STREAM_ID_0 && stream == AUD_STREAM_PLAYBACK){ + af_stream_fadeout_start(512); + af_stream_stop_wait_finish(); + } +#endif + + if (device == AUD_STREAM_USE_INT_CODEC && stream == AUD_STREAM_PLAYBACK) { +#ifdef AUDIO_OUTPUT_PA_OFF_FADE_OUT + dac_pa_state = AF_DAC_PA_OFF_TRIGGER; + af_unlock_thread(); + while (dac_pa_state != AF_DAC_PA_NULL) { +#ifdef RTOS + osSignalWait((1 << AF_FADE_OUT_SIGNAL_ID), 300); + osSignalClear(fade_thread_id, (1 << AF_FADE_OUT_SIGNAL_ID)); +#else + af_thread(NULL); +#endif + } + af_lock_thread(); +#elif defined(AUDIO_OUTPUT_PA_ON_FADE_IN) + dac_pa_state = AF_DAC_PA_NULL; + analog_aud_codec_speaker_enable(false); + dac_pa_stop_time = hal_sys_timer_get(); +#endif // !AUDIO_OUTPUT_PA_OFF_FADE_OUT && AUDIO_OUTPUT_PA_ON_FADE_IN + } + + hal_audma_stop(role->dma_cfg.ch); + +#if defined(RTOS) && defined(AF_STREAM_ID_0_PLAYBACK_FADEOUT) + if (id == AUD_STREAM_ID_0 && stream == AUD_STREAM_PLAYBACK){ + af_stream_fadeout_stop(); + } +#endif + + if(0) + { + } +#ifdef AF_DEVICE_EXT_CODEC + else if(device == AUD_STREAM_USE_EXT_CODEC) + { + AF_TRACE_DEBUG(); + tlv32aic32_stream_stop(stream); + } +#endif +#ifdef AF_DEVICE_I2S + else if(device == AUD_STREAM_USE_I2S0_MASTER || device == AUD_STREAM_USE_I2S0_SLAVE) + { + AF_TRACE_DEBUG(); + hal_i2s_stop_stream(HAL_I2S_ID_0, stream); + } +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + else if(device == AUD_STREAM_USE_I2S1_MASTER || device == AUD_STREAM_USE_I2S1_SLAVE) + { + AF_TRACE_DEBUG(); + hal_i2s_stop_stream(HAL_I2S_ID_1, stream); + } +#endif +#endif +#ifdef AF_DEVICE_TDM + else if(device == AUD_STREAM_USE_TDM0_MASTER || device == AUD_STREAM_USE_TDM0_SLAVE) + { + AF_TRACE_DEBUG(); + hal_tdm_stop_stream(HAL_I2S_ID_0, stream); + } +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + else if(device == AUD_STREAM_USE_TDM1_MASTER || device == AUD_STREAM_USE_TDM1_SLAVE) + { + AF_TRACE_DEBUG(); + hal_tdm_stop_stream(HAL_I2S_ID_1, stream); + } +#endif +#endif +#ifdef AF_DEVICE_INT_CODEC + else if(device == AUD_STREAM_USE_INT_CODEC) + { + AF_TRACE_DEBUG(); +#ifdef CODEC_PLAY_BEFORE_CAPTURE + af_codec_stream_pre_stop(stream); +#endif + codec_int_stream_stop(stream); +#ifdef CODEC_PLAY_BEFORE_CAPTURE + af_codec_stream_post_stop(stream); +#endif + } +#endif +#ifdef AF_DEVICE_SPDIF + else if(device == AUD_STREAM_USE_INT_SPDIF) + { + AF_TRACE_DEBUG(); + hal_spdif_stop_stream(AF_SPDIF_INST, stream); + } +#endif +#ifdef AF_DEVICE_BT_PCM + else if(device == AUD_STREAM_USE_BT_PCM) + { + AF_TRACE_DEBUG(); + hal_btpcm_stop_stream(AF_BTPCM_INST, stream); + } +#endif +#ifdef AF_DEVICE_DPD_RX + else if(device == AUD_STREAM_USE_DPD_RX) + { + AF_TRACE_DEBUG(); + hal_btpcm_stop_stream(AF_BTPCM_INST, stream); + } +#endif +#ifdef AUDIO_ANC_FB_MC + else if(device == AUD_STREAM_USE_MC) + { + AF_TRACE_DEBUG(); + } +#endif + else + { + ASSERT(0, "[%s] ERROR: device %d is not defined!", __func__, device); + } + +_pause_stop: + AF_TRACE_DEBUG(); + af_clear_status(id, stream, AF_STATUS_STREAM_START_STOP); + +#ifndef RTOS + af_clear_flag(&af_flag_signal, 1 << (id * 2 + stream)); +#endif + + ret = AF_RES_SUCCESS; + +_exit: + af_unlock_thread(); + + return ret; +} + +uint32_t af_stream_pause(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ +#ifdef CHIP_BEST1000 + + struct af_stream_cfg_t *role = NULL; + enum AF_RESULT_T ret; + + role = af_get_stream_role(id, stream); + TRACE(3,"[%s] id = %d, stream = %d", __func__, id, stream); + + af_lock_thread(); + + if (role->cfg.device != AUD_STREAM_USE_INT_CODEC) + { + ret = AF_RES_FAILD; + goto _exit; + } + if (role->ctl.status != (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE | AF_STATUS_STREAM_START_STOP)) + { + TRACE(2,"[%s] ERROR: status = %d",__func__, role->ctl.status); + ret = AF_RES_FAILD; + goto _exit; + } + +#if defined(AUDIO_OUTPUT_PA_ON_FADE_IN) || defined(AUDIO_OUTPUT_PA_OFF_FADE_OUT) + if (AUD_STREAM_PLAYBACK == stream) + { + dac_pa_state = AF_DAC_PA_NULL; + analog_aud_codec_speaker_enable(false); + dac_pa_stop_time = hal_sys_timer_get(); + } +#endif + + hal_audma_stop(role->dma_cfg.ch); + +#ifndef FPGA + codec_int_stream_stop(stream); +#endif + + af_set_status(id, stream, AF_STATUS_STREAM_PAUSE_RESTART); + + ret = AF_RES_SUCCESS; + +_exit: + af_unlock_thread(); + + return ret; + +#else + + return af_stream_stop(id, stream); + +#endif +} + +uint32_t af_stream_restart(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ +#ifdef CHIP_BEST1000 + + struct af_stream_cfg_t *role = NULL; + enum AF_RESULT_T ret; + + role = af_get_stream_role(id, stream); + TRACE(3,"[%s] id = %d, stream = %d", __func__, id, stream); + + af_lock_thread(); + + if (role->cfg.device != AUD_STREAM_USE_INT_CODEC) + { + ret = AF_RES_FAILD; + goto _exit; + } + if (role->ctl.status != (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE | AF_STATUS_STREAM_START_STOP | AF_STATUS_STREAM_PAUSE_RESTART)) + { + TRACE(2,"[%s] ERROR: status = %d",__func__, role->ctl.status); + ret = AF_RES_FAILD; + goto _exit; + } + + role->ctl.pp_index = PP_PING; + role->ctl.pp_cnt = 0; + +#ifdef AUDIO_OUTPUT_PA_ON_FADE_IN + if (AUD_STREAM_PLAYBACK == stream) + { + dac_pa_state = AF_DAC_PA_ON_TRIGGER; + af_zero_mem(role->dma_buf_ptr, role->dma_buf_size); +#ifdef AUDIO_OUTPUT_DC_CALIB_SW + af_codec_playback_sw_dc_calib(role->dma_buf_ptr, role->dma_buf_size, role->cfg.bits, role->cfg.channel_num); +#endif + dac_dc_start_time = hal_sys_timer_get(); + } +#endif + + hal_audma_sg_start(&role->dma_desc[0], &role->dma_cfg); + +#ifndef FPGA + codec_int_stream_start(stream); +#endif + + af_clear_status(id, stream, AF_STATUS_STREAM_PAUSE_RESTART); + + ret = AF_RES_SUCCESS; + +_exit: + af_unlock_thread(); + + return ret; + +#else + + return af_stream_start(id, stream); + +#endif +} + +uint32_t af_stream_close(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + struct af_stream_cfg_t *role; + enum AF_RESULT_T ret; + enum AUD_STREAM_USE_DEVICE_T device; + + role = af_get_stream_role(id, stream); + TRACE(3,"[%s] id = %d, stream = %d", __func__, id, stream); + + af_lock_thread(); + + //check stream is stop and not close. + if(role->ctl.status != (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE)) + { + TRACE(2,"[%s] ERROR: status = %d",__func__, role->ctl.status); + ret = AF_RES_FAILD; + goto _exit; + } + + device = role->ctl.use_device; + + memset(role->dma_buf_ptr, 0, role->dma_buf_size); + hal_audma_free_chan(role->dma_cfg.ch); + + // TODO: more parameter should be set!!! +// memset(role, 0xff, sizeof(struct af_stream_cfg_t)); + role->handler = NULL; + role->ctl.pp_index = PP_PING; + role->ctl.use_device = AUD_STREAM_USE_DEVICE_NULL; + role->dma_buf_ptr = NULL; + role->dma_buf_size = 0; + + role->dma_cfg.ch = HAL_DMA_CHAN_NONE; + + if(0) + { + } +#ifdef AF_DEVICE_EXT_CODEC + else if(device == AUD_STREAM_USE_EXT_CODEC) + { + AF_TRACE_DEBUG(); + tlv32aic32_stream_close(stream); + } +#endif +#ifdef AF_DEVICE_I2S + else if(device == AUD_STREAM_USE_I2S0_MASTER || device == AUD_STREAM_USE_I2S0_SLAVE) + { + AF_TRACE_DEBUG(); + hal_i2s_close(HAL_I2S_ID_0, stream); + } +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + else if(device == AUD_STREAM_USE_I2S1_MASTER || device == AUD_STREAM_USE_I2S1_SLAVE) + { + AF_TRACE_DEBUG(); + hal_i2s_close(HAL_I2S_ID_1, stream); + } +#endif +#endif +#ifdef AF_DEVICE_TDM + else if(device == AUD_STREAM_USE_TDM0_MASTER || device == AUD_STREAM_USE_TDM0_SLAVE) + { + AF_TRACE_DEBUG(); + hal_tdm_close(HAL_I2S_ID_0, stream); + } +#if defined(CHIP_HAS_I2S) && (CHIP_HAS_I2S > 1) + else if(device == AUD_STREAM_USE_TDM1_MASTER || device == AUD_STREAM_USE_TDM1_SLAVE) + { + AF_TRACE_DEBUG(); + hal_tdm_close(HAL_I2S_ID_1, stream); + } +#endif +#endif +#ifdef AF_DEVICE_INT_CODEC + else if(device == AUD_STREAM_USE_INT_CODEC) + { + AF_TRACE_DEBUG(); + codec_int_stream_close(stream); + codec_int_close(CODEC_CLOSE_NORMAL); + } +#endif +#ifdef AF_DEVICE_SPDIF + else if(device == AUD_STREAM_USE_INT_SPDIF) + { + AF_TRACE_DEBUG(); + hal_spdif_close(AF_SPDIF_INST, stream); + } +#endif +#ifdef AF_DEVICE_BT_PCM + else if(device == AUD_STREAM_USE_BT_PCM) + { + AF_TRACE_DEBUG(); + hal_btpcm_close(AF_BTPCM_INST, stream); + } +#endif +#ifdef AF_DEVICE_DPD_RX + else if(device == AUD_STREAM_USE_DPD_RX) + { + AF_TRACE_DEBUG(); + } +#endif +#ifdef AUDIO_ANC_FB_MC + else if(device == AUD_STREAM_USE_MC) + { + AF_TRACE_DEBUG(); + } +#endif + else + { + ASSERT(0, "[%s] ERROR: device %d is not defined!", __func__, device); + } + + AF_TRACE_DEBUG(); + af_clear_status(id, stream, AF_STATUS_STREAM_OPEN_CLOSE); + +#ifndef RTOS + af_clear_flag(&af_flag_open, 1 << (id * 2 + stream)); + if (af_flag_open == 0) { + hal_cpu_wake_unlock(AF_CPU_WAKE_USER); + } +#endif + + ret = AF_RES_SUCCESS; + +_exit: + af_unlock_thread(); + + return ret; +} + +uint32_t af_close(void) +{ + struct af_stream_cfg_t *role; + + // Avoid blocking shutdown process + //af_lock_thread(); + + for (uint8_t id=0; id < AUD_STREAM_ID_NUM; id++) + { + for (uint8_t stream=0; stream < AUD_STREAM_NUM; stream++) + { + role = af_get_stream_role((enum AUD_STREAM_ID_T)id, (enum AUD_STREAM_T)stream); + role->ctl.status = AF_STATUS_NULL; + } + } + + codec_int_close(CODEC_CLOSE_FORCED); + + //af_unlock_thread(); + + return AF_RES_SUCCESS; +} + +uint32_t af_stream_get_cur_dma_addr(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + struct af_stream_cfg_t *role; + int i; + uint32_t addr = 0; + + role = af_get_stream_role(id, stream); + + //check stream is start and not stop + if (role->ctl.status == (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE | AF_STATUS_STREAM_START_STOP)) { + if (role->dma_cfg.ch != HAL_DMA_CHAN_NONE) { + for (i = 0; i < 2; i++) { + if (stream == AUD_STREAM_PLAYBACK) { + addr = hal_audma_get_cur_src_addr(role->dma_cfg.ch); + } else { + addr = hal_audma_get_cur_dst_addr(role->dma_cfg.ch); + } + if (addr) { + break; + } + // Previous link list item was just finished. Read current DMA address again. + } + } + } + + return addr; +} + +int af_stream_get_cur_dma_pos(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + struct af_stream_cfg_t *role; + uint32_t addr; + int pos; + + role = af_get_stream_role(id, stream); + + addr = af_stream_get_cur_dma_addr(id, stream); + + pos = addr - (uint32_t)role->dma_buf_ptr; + + if (pos < 0 || pos > role->dma_buf_size) { + return -1; + } + +#ifndef CHIP_BEST1000 + if (role->cfg.chan_sep_buf && role->cfg.channel_num > AUD_CHANNEL_NUM_1) { + uint32_t chan_size; + uint8_t chan_idx; + uint8_t desc_idx; + uint16_t chan_desc_offset; + uint16_t chan_desc_xfer_size; + uint32_t chan_offset; + + chan_size = role->dma_buf_size / role->cfg.channel_num; + chan_desc_xfer_size = chan_size / AUDIO_BUFFER_COUNT; + + chan_idx = pos / chan_size; + chan_offset = pos % chan_size; + desc_idx = chan_offset / chan_desc_xfer_size; + chan_desc_offset = chan_offset % chan_desc_xfer_size; + + pos = desc_idx * (role->dma_buf_size / AUDIO_BUFFER_COUNT) + chan_idx * chan_desc_xfer_size + chan_desc_offset; + } +#endif + + return pos; +} + +int af_stream_buffer_error(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + return af_sig_lost_cnt[id][stream]; +} + +uint32_t af_stream_dma_tc_irq_enable(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + struct af_stream_cfg_t *role; + + role = af_get_stream_role(id, stream); + + // Check if opened + if ((role->ctl.status & (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE)) == + (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE)) { + hal_dma_tc_irq_enable(role->dma_cfg.ch); + return AF_RES_SUCCESS; + } + + return AF_RES_FAILD; +} + +uint32_t af_stream_dma_tc_irq_disable(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + struct af_stream_cfg_t *role; + + role = af_get_stream_role(id, stream); + + // Check if opened + if ((role->ctl.status & (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE)) == + (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE)) { + hal_dma_tc_irq_disable(role->dma_cfg.ch); + return AF_RES_SUCCESS; + } + + return AF_RES_FAILD; +} + +#ifdef RTOS +void af_set_irq_notification(AF_IRQ_NOTIFICATION_T notif) +{ + irq_notif = notif; +} + +static int af_priority[AF_USER_NUM]; + +void af_set_priority(AF_USER_E user, int priority) +{ + uint8_t i = 0; + int max_priority = 0; + af_priority[user] = priority; + + for (i=0; ictl.status & AF_STATUS_STREAM_OPEN_CLOSE) { + if (role->cfg.device == AUD_STREAM_USE_INT_CODEC && role->dma_cfg.dst_periph == HAL_AUDMA_CODEC_TX) { + ASSERT(role->ctl.status == (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE), + "Bad stream status when DSD enabled: 0x%X", role->ctl.status); + role->dma_cfg.dst_periph = HAL_AUDMA_DSD_TX; + af_stream_update_dma_buffer(AUD_STREAM_PLAYBACK, role, &role->cfg); + opened = true; + break; + } + } + } + + hal_codec_dsd_enable(); + af_dsd_enabled = true; + + af_unlock_thread(); + + if (opened) { + // Enable DSD sample rate handling + af_stream_setup(id, AUD_STREAM_PLAYBACK, &role->cfg); + } +} + +void af_dsd_disable(void) +{ + enum AUD_STREAM_ID_T id; + struct af_stream_cfg_t *role; + bool opened = false; + + af_lock_thread(); + + for (id = AUD_STREAM_ID_0; id < AUD_STREAM_ID_NUM; id++) { + role = af_get_stream_role(id, AUD_STREAM_PLAYBACK); + if (role->ctl.status & AF_STATUS_STREAM_OPEN_CLOSE) { + if (role->cfg.device == AUD_STREAM_USE_INT_CODEC && role->dma_cfg.dst_periph == HAL_AUDMA_DSD_TX) { + ASSERT(role->ctl.status == (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE), + "Bad stream status when DSD disabled: 0x%X", role->ctl.status); + role->dma_cfg.dst_periph = HAL_AUDMA_CODEC_TX; + af_stream_update_dma_buffer(AUD_STREAM_PLAYBACK, role, &role->cfg); + opened = true; + break; + } + } + } + + hal_codec_dsd_disable(); + af_dsd_enabled = false; + + af_unlock_thread(); + + if (opened) { + // Disable DSD sample rate handling + af_stream_setup(id, AUD_STREAM_PLAYBACK, &role->cfg); + } +} +#endif +#ifdef __RAND_FROM_MIC__ + uint8_t random_mic_is_on(uint8_t *deviceId) + { + struct af_stream_cfg_t *role = NULL; + + *deviceId = 0; + + for(uint8_t id=0; id< AUD_STREAM_ID_NUM; id++) + { + role = af_get_stream_role((enum AUD_STREAM_ID_T)id, AUD_STREAM_CAPTURE); + if (role->cfg.device == AUD_STREAM_USE_INT_CODEC && + role->ctl.status == (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE | AF_STATUS_STREAM_START_STOP)) { + return RAND_STATUS_MIC_STARTED; + } + else if (role->cfg.device == AUD_STREAM_USE_INT_CODEC && + role->ctl.status == (AF_STATUS_OPEN_CLOSE | AF_STATUS_STREAM_OPEN_CLOSE)) + { + *deviceId = id; + return RAND_STATUS_MIC_OPENED; + } + } + + return RAND_STATUS_CLOSE; + } +#endif + diff --git a/services/audioflinger/audioflinger.h b/services/audioflinger/audioflinger.h new file mode 100644 index 0000000..dd32630 --- /dev/null +++ b/services/audioflinger/audioflinger.h @@ -0,0 +1,154 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef AUDIO_FLINGER_H +#define AUDIO_FLINGER_H + +#include "plat_types.h" +#include "stdbool.h" +#include "hal_aud.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint32_t (*AF_STREAM_HANDLER_T)(uint8_t *buf, uint32_t len); +typedef void (*AF_IRQ_NOTIFICATION_T)(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +typedef void (*AF_CODEC_PLAYBACK_POST_HANDLER_T)(uint8_t *buf, uint32_t len, void *config); + +//pingpong machine +enum AF_PP_T{ + PP_PING = 0, + PP_PANG = 1 +}; + +typedef enum { + AF_USER_AI, + AF_USER_THIRDPART, + AF_USER_AUDIO, + AF_USER_SBC, + AF_USER_SCO, + AF_USER_TEST, + AF_USER_NUM +} AF_USER_E; + +struct AF_STREAM_CONFIG_T { + enum AUD_BITS_T bits; + enum AUD_SAMPRATE_T sample_rate; + enum AUD_CHANNEL_NUM_T channel_num; + enum AUD_CHANNEL_MAP_T channel_map; + enum AUD_STREAM_USE_DEVICE_T device; + enum AUD_IO_PATH_T io_path; + bool chan_sep_buf; + bool sync_start; + uint8_t slot_cycles; + uint16_t fs_cycles; + AF_STREAM_HANDLER_T handler; + + uint8_t *data_ptr; + uint32_t data_size; + + //should define type + uint8_t vol; +}; + +//Should define return status +uint32_t af_open(void); +void *af_thread_tid_get(void); +uint32_t af_stream_open(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, const struct AF_STREAM_CONFIG_T *cfg); +uint32_t af_stream_setup(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, const struct AF_STREAM_CONFIG_T *cfg); +uint32_t af_stream_mute(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, bool mute); +uint32_t af_stream_set_chan_vol(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, enum AUD_CHANNEL_MAP_T ch_map, uint8_t vol); +uint32_t af_stream_restore_chan_vol(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +uint32_t af_stream_get_cfg(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream, struct AF_STREAM_CONFIG_T **cfg, bool needlock); +uint32_t af_stream_start(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +uint32_t af_stream_stop(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +uint32_t af_stream_pause(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +uint32_t af_stream_restart(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +uint32_t af_stream_close(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +uint32_t af_close(void); +uint32_t af_stream_get_cur_dma_addr(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +int af_stream_get_cur_dma_pos(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +int af_stream_buffer_error(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +uint32_t af_stream_dma_tc_irq_enable(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +uint32_t af_stream_dma_tc_irq_disable(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); +void af_set_irq_notification(AF_IRQ_NOTIFICATION_T notif); + +void af_lock_thread(void); +void af_unlock_thread(void); +void af_set_priority(AF_USER_E user, int priority); +int af_get_priority(void); +int af_get_default_priority(void); +void af_reset_priority(void); + +void af_codec_tune_resample_rate(enum AUD_STREAM_T stream, float ratio); +void af_codec_direct_tune_resample_rate(enum AUD_STREAM_T stream, float ratio); +void af_codec_tune_both_resample_rate(float ratio); +void af_codec_tune_pll(float ratio); +void af_codec_tune_xtal(float ratio); +void af_codec_tune(enum AUD_STREAM_T stream, float ratio); +void af_codec_direct_tune(enum AUD_STREAM_T stream, float ratio); + +void af_codec_set_perf_test_power(int type); +void af_codec_set_noise_reduction(bool enable); +void af_codec_swap_output(bool swap); +void af_codec_set_playback_post_handler(AF_CODEC_PLAYBACK_POST_HANDLER_T hdlr); + +enum AF_CODEC_SYNC_TYPE_T { + AF_CODEC_SYNC_TYPE_NONE, + AF_CODEC_SYNC_TYPE_GPIO, + AF_CODEC_SYNC_TYPE_BT, + AF_CODEC_SYNC_TYPE_WIFI, +}; + +enum AF_I2S_SYNC_TYPE_T { + AF_I2S_SYNC_TYPE_NONE, + AF_I2S_SYNC_TYPE_BT, + AF_I2S_SYNC_TYPE_GPIO, +}; + + +void af_codec_sync_config(enum AUD_STREAM_T stream, enum AF_CODEC_SYNC_TYPE_T type, bool enable); +void af_codec_sync_resample_rate_config(enum AUD_STREAM_T stream, enum AF_CODEC_SYNC_TYPE_T type, bool enable); +void af_codec_sync_gain_config(enum AUD_STREAM_T stream, enum AF_CODEC_SYNC_TYPE_T type, bool enable); +void af_i2s_sync_config(enum AUD_STREAM_T stream, enum AF_I2S_SYNC_TYPE_T type, bool enable); + +typedef void (*AF_ANC_HANDLER)(enum AUD_STREAM_T stream, enum AUD_SAMPRATE_T rate, enum AUD_SAMPRATE_T *new_play, enum AUD_SAMPRATE_T *new_cap); + +int af_anc_open(enum ANC_TYPE_T type, enum AUD_SAMPRATE_T play_rate, enum AUD_SAMPRATE_T capture_rate, AF_ANC_HANDLER handler); +int af_anc_close(enum ANC_TYPE_T type); + +int af_vad_open(const struct AUD_VAD_CONFIG_T *cfg); +int af_vad_close(void); +int af_vad_start(void); +int af_vad_stop(void); +uint32_t af_vad_get_data(uint8_t *buf, uint32_t len); +void af_vad_get_data_info(struct CODEC_VAD_BUF_INFO_T * vad_buf_info); + +void af_dsd_enable(void); +void af_dsd_disable(void); + +typedef void (*AF_CODEC_BT_TRIGGER_CALLBACK)(void); +void af_codec_bt_trigger_config(bool en, AF_CODEC_BT_TRIGGER_CALLBACK callback); + +#ifdef __RAND_FROM_MIC__ +uint8_t random_mic_is_on(uint8_t *deviceId); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* AUDIO_FLINGER_H */ diff --git a/services/auto_test/Makefile b/services/auto_test/Makefile new file mode 100644 index 0000000..0c791e0 --- /dev/null +++ b/services/auto_test/Makefile @@ -0,0 +1,57 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) + +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y += \ + -Iservices/audio_process \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/bt_app \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/resources \ + -Iservices/multimedia/rbcodec/inc \ + -Iservices/multimedia/audio/process/resample/include \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/audio/process/drc/include \ + -Iservices/multimedia/audio/process/anc/include\ + -Iservices/osif\ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/include \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iapps/key \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/audioplayers/rbplay \ + -Iapps/battery \ + -Iapps/factory \ + -Iservices/ble_app \ + -Iservices/tws/inc \ + -Iutils/hwtimer_list \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + $(BT_IF_INCLUDES) \ + -Iservices/norflash_api + + + + + + diff --git a/services/auto_test/at_thread.cpp b/services/auto_test/at_thread.cpp new file mode 100644 index 0000000..d61ea4f --- /dev/null +++ b/services/auto_test/at_thread.cpp @@ -0,0 +1,137 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "at_thread.h" + +static void at_thread(void const *argument); +osThreadDef(at_thread, osPriorityNormal, 1, 1024, "AT_cmd"); + +osMailQDef (at_mailbox, AT_MAILBOX_MAX, AT_MESSAGE); +static osMailQId at_mailbox = NULL; +static uint8_t at_mailbox_cnt = 0; +#define AT_DEBUG TRACE +static int at_mailbox_init(void) +{ + AT_DEBUG("%s,%d",__func__,__LINE__); + at_mailbox = osMailCreate(osMailQ(at_mailbox), NULL); + if (at_mailbox == NULL) { + AT_DEBUG("Failed to Create at_mailbox\n"); + return -1; + } + at_mailbox_cnt = 0; + return 0; +} + +static int at_mailbox_put(AT_MESSAGE* msg_src) +{ + osStatus status; + AT_MESSAGE *msg_p = NULL; + + AT_DEBUG("%s,%d",__func__,__LINE__); + if(at_mailbox_cnt >= 1) + { + AT_DEBUG("%s,%d at_mailbox_cnt = %d.", + __func__,__LINE__,at_mailbox_cnt); + return 0; + } + msg_p = (AT_MESSAGE*)osMailAlloc(at_mailbox, 0); + ASSERT(msg_p, "osMailAlloc error"); + msg_p->id = msg_src->id; + msg_p->ptr = msg_src->ptr; + msg_p->param0 = msg_src->param0; + msg_p->param1 = msg_src->param1; + + status = osMailPut(at_mailbox, msg_p); + if (osOK == status) + at_mailbox_cnt++; + AT_DEBUG("%s,%d,at_mailbox_cnt = %d.",__func__,__LINE__,at_mailbox_cnt); + return (int)status; +} + +static int at_mailbox_free(AT_MESSAGE* msg_p) +{ + osStatus status; + + AT_DEBUG("%s,%d",__func__,__LINE__); + status = osMailFree(at_mailbox, msg_p); + if (osOK == status) + at_mailbox_cnt--; + AT_DEBUG("%s,%d,at_mailbox_cnt = %d.",__func__,__LINE__,at_mailbox_cnt); + return (int)status; +} + +static int at_mailbox_get(AT_MESSAGE **msg_p) +{ + osEvent evt; + evt = osMailGet(at_mailbox, osWaitForever); + if (evt.status == osEventMail) { + *msg_p = (AT_MESSAGE*)evt.value.p; + return 0; + } + return -1; +} + +static void at_thread(void const *argument) +{ + AT_FUNC_T pfunc; + // USB_FUNC_T usb_funcp; + AT_DEBUG("%s,%d",__func__,__LINE__); + while(1){ + AT_MESSAGE *msg_p = NULL; + if (!at_mailbox_get(&msg_p)) { + AT_DEBUG("_debug: %s,%d",__func__,__LINE__); + AT_DEBUG("at_thread: id = 0x%x, ptr = 0x%x,param0 = 0x%x,param1 = 0x%x.", + msg_p->id,msg_p->ptr,msg_p->param0,msg_p->param1); + pfunc = (AT_FUNC_T)msg_p->ptr; + pfunc(msg_p->param0,msg_p->param1); + at_mailbox_free(msg_p); + } + } +} + +int at_os_init(void) +{ + osThreadId at_tid; + + AT_DEBUG("%s,%d",__func__,__LINE__); + if (at_mailbox_init()) { + AT_DEBUG("_debug: %s,%d",__func__,__LINE__); + return -1; + } + at_tid = osThreadCreate(osThread(at_thread), NULL); + if (at_tid == NULL) { + AT_DEBUG("Failed to Create at_thread\n"); + return -2; + } + return 0; +} + +int at_enqueue_cmd(uint32_t cmd_id, uint32_t param,uint32_t pfunc) +{ + AT_MESSAGE at_msg; + int32_t ret; + + at_msg.id = AT_MESSAGE_ID_CMD; + at_msg.param0 = param; + at_msg.param1 = cmd_id; + at_msg.ptr = pfunc; + ret = at_mailbox_put(&at_msg); + return ret; +} + + + diff --git a/services/auto_test/at_thread.h b/services/auto_test/at_thread.h new file mode 100644 index 0000000..3c2283a --- /dev/null +++ b/services/auto_test/at_thread.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __AT_THREAD_H__ +#define __AT_THREAD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define AT_MAILBOX_MAX (20) + +typedef struct { + uint32_t id; + uint32_t ptr; + uint32_t param0; + uint32_t param1; +} AT_MESSAGE; + +#define AT_MESSAGE_ID_CMD 0 + + +typedef void (*AT_FUNC_T)(uint32_t, uint32_t); + +typedef void (*AT_THREAD)(void*); +int at_os_init(void); +int at_enqueue_cmd(uint32_t cmd_id, uint32_t param,uint32_t pfunc); +#ifdef __cplusplus + } +#endif + +#endif // __AT_THREAD_H__ + diff --git a/services/auto_test/at_thread_user.cpp b/services/auto_test/at_thread_user.cpp new file mode 100644 index 0000000..5793430 --- /dev/null +++ b/services/auto_test/at_thread_user.cpp @@ -0,0 +1,275 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "at_thread.h" +#include "at_thread_user.h" + +#if 1 +#define AT_THREAD_TRACE TRACE +#else +#define AT_THREAD_TRACE(str,...) +#endif + +//static osThreadId at_tid_user1 = NULL; +static void at_thread_user0(void const *argument); +static void at_thread_user1(void const *argument); +static void at_thread_user2(void const *argument); +static void at_thread_user3(void const *argument); +static void at_thread_user4(void const *argument); +//static osMailQId at_mailbox_user0 = NULL; +//static osMailQId at_mailbox_user1 = NULL; +//static osMailQId at_mailbox_user2 = NULL; +//static osMailQId at_mailbox_user3 = NULL; +//static osMailQId at_mailbox_user4 = NULL; + +osThreadDef(at_thread_user0, osPriorityLow, 1, 1024, "at_user0"); +osMailQDef (at_mailbox_user0, AT_MAILBOX_MAX, AT_USER_MESSAGE); + +osThreadDef(at_thread_user1, osPriorityLow, 1, 1024, "at_user1"); +osMailQDef (at_mailbox_user1, AT_MAILBOX_MAX, AT_USER_MESSAGE); +osThreadDef(at_thread_user2, osPriorityLow, 1, 1024, "at_user2"); +osMailQDef (at_mailbox_user2, AT_MAILBOX_MAX, AT_USER_MESSAGE); +osThreadDef(at_thread_user3, osPriorityNormal, 1, 512, "at_user3"); +osMailQDef (at_mailbox_user3, AT_MAILBOX_MAX, AT_USER_MESSAGE); +osThreadDef(at_thread_user4, osPriorityNormal, 1, 512, "at user4"); +osMailQDef (at_mailbox_user4, AT_MAILBOX_MAX, AT_USER_MESSAGE); + +typedef struct{ + bool is_inited; + osMailQId mid; + osThreadId til; + uint32_t mail_count; +}AT_TREAD_INFO; + +AT_TREAD_INFO at_thread_info[THREAD_USER_COUNT] = + { + {false,NULL,NULL,0}, + {false,NULL,NULL,0}, + {false,NULL,NULL,0}, + {false,NULL,NULL,0}, + {false,NULL,NULL,0}, + }; + +static int at_mailbox_user_put(enum THREAD_USER_ID user_id,AT_MESSAGE* msg_src) +{ + osStatus status; + AT_MESSAGE *msg_p = NULL; + + AT_THREAD_TRACE(3,"%s,%d,user_id = %d.",__func__,__LINE__,user_id); + if(at_thread_info[user_id].mail_count >= 1) + { + AT_THREAD_TRACE(3,"%s,%d mail_count = %d.", + __func__,__LINE__,at_thread_info[user_id].mail_count); + return 0; + } + msg_p = (AT_MESSAGE*)osMailAlloc(at_thread_info[user_id].mid, 0); + ASSERT(msg_p, "osMailAlloc error"); + msg_p->id = msg_src->id; + msg_p->ptr = msg_src->ptr; + msg_p->param0 = msg_src->param0; + msg_p->param1 = msg_src->param1; + + status = osMailPut(at_thread_info[user_id].mid, msg_p); + if (osOK == status) + at_thread_info[user_id].mail_count ++; + AT_THREAD_TRACE(3,"%s,%d,at_mailbox_cnt = %d.",__func__,__LINE__,at_thread_info[user_id].mail_count); + return (int)status; +} + +static int at_mailbox_user_free(enum THREAD_USER_ID user_id,AT_MESSAGE* msg_p) +{ + osStatus status; + + AT_THREAD_TRACE(3,"%s,%d,user_id = %d.",__func__,__LINE__,user_id); + status = osMailFree(at_thread_info[user_id].mid, msg_p); + if (osOK == status) + at_thread_info[user_id].mail_count --; + AT_THREAD_TRACE(3,"%s,%d,at_mailbox_cnt = %d.",__func__,__LINE__,at_thread_info[user_id].mail_count); + return (int)status; +} + +static int at_mailbox_user_get(enum THREAD_USER_ID user_id,AT_MESSAGE **msg_p) +{ + osEvent evt; + evt = osMailGet(at_thread_info[user_id].mid, osWaitForever); + if (evt.status == osEventMail) { + *msg_p = (AT_MESSAGE*)evt.value.p; + return 0; + } + return -1; +} + +static void at_thread_user0(const void *argument) +{ + AT_FUNC_T pfunc; + //enum THREAD_USER_ID user_id = THREAD_USER_COUNT; + //uint32_t arg; + + AT_THREAD_TRACE(2,"%s,%d.",__func__,__LINE__); + //arg = (uint32_t)argument; + + //AT_THREAD_TRACE(3,"%s,%d,user_id = %d.",__func__,__LINE__,user_id); + while(1){ + AT_THREAD_TRACE(2,"%s,%d.",__func__,__LINE__); + AT_MESSAGE *msg_p = NULL; + if (!at_mailbox_user_get(THREAD_USER0,&msg_p)) { + AT_THREAD_TRACE(2,"_debug: %s,%d",__func__,__LINE__); + AT_THREAD_TRACE(4,"at_thread_user1: id = 0x%x, ptr = 0x%x,param0 = 0x%x,param1 = 0x%x.", + msg_p->id,msg_p->ptr,msg_p->param0,msg_p->param1); + pfunc = (AT_FUNC_T)msg_p->ptr; + pfunc(msg_p->param0,msg_p->param1); + at_mailbox_user_free(THREAD_USER0,msg_p); + } + AT_THREAD_TRACE(2,"%s,%d.",__func__,__LINE__); + } +} + +static void at_thread_user1(void const *argument) +{ + AT_FUNC_T pfunc; + + AT_THREAD_TRACE(2,"%s,%d",__func__,__LINE__); + while(1){ + AT_MESSAGE *msg_p = NULL; + if (!at_mailbox_user_get(THREAD_USER1,&msg_p)) { + AT_THREAD_TRACE(2,"_debug: %s,%d",__func__,__LINE__); + AT_THREAD_TRACE(4,"at_thread_user1: id = 0x%x, ptr = 0x%x,param0 = 0x%x,param1 = 0x%x.", + msg_p->id,msg_p->ptr,msg_p->param0,msg_p->param1); + pfunc = (AT_FUNC_T)msg_p->ptr; + pfunc(msg_p->param0,msg_p->param1); + at_mailbox_user_free(THREAD_USER1,msg_p); + } + } +} +#if 1 +static void at_thread_user2(void const *argument) +{ + AT_FUNC_T pfunc; + AT_THREAD_TRACE(2,"%s,%d",__func__,__LINE__); + while(1){ + AT_MESSAGE *msg_p = NULL; + if (!at_mailbox_user_get(THREAD_USER2,&msg_p)) { + AT_THREAD_TRACE(2,"_debug: %s,%d",__func__,__LINE__); + AT_THREAD_TRACE(4,"at_thread_user1: id = 0x%x, ptr = 0x%x,param0 = 0x%x,param1 = 0x%x.", + msg_p->id,msg_p->ptr,msg_p->param0,msg_p->param1); + pfunc = (AT_FUNC_T)msg_p->ptr; + pfunc(msg_p->param0,msg_p->param1); + at_mailbox_user_free(THREAD_USER2,msg_p); + } + } +} +static void at_thread_user3(void const *argument) +{ + AT_FUNC_T pfunc; + AT_THREAD_TRACE(2,"%s,%d",__func__,__LINE__); + while(1){ + AT_MESSAGE *msg_p = NULL; + if (!at_mailbox_user_get(THREAD_USER3,&msg_p)) { + AT_THREAD_TRACE(2,"_debug: %s,%d",__func__,__LINE__); + AT_THREAD_TRACE(4,"at_thread_user1: id = 0x%x, ptr = 0x%x,param0 = 0x%x,param1 = 0x%x.", + msg_p->id,msg_p->ptr,msg_p->param0,msg_p->param1); + pfunc = (AT_FUNC_T)msg_p->ptr; + pfunc(msg_p->param0,msg_p->param1); + at_mailbox_user_free(THREAD_USER3,msg_p); + } + } +} + +static void at_thread_user4(void const *argument) +{ + AT_FUNC_T pfunc; + AT_THREAD_TRACE(2,"%s,%d",__func__,__LINE__); + while(1){ + AT_MESSAGE *msg_p = NULL; + if (!at_mailbox_user_get(THREAD_USER4,&msg_p)) { + AT_THREAD_TRACE(2,"_debug: %s,%d",__func__,__LINE__); + AT_THREAD_TRACE(4,"at_thread_user1: id = 0x%x, ptr = 0x%x,param0 = 0x%x,param1 = 0x%x.", + msg_p->id,msg_p->ptr,msg_p->param0,msg_p->param1); + pfunc = (AT_FUNC_T)msg_p->ptr; + pfunc(msg_p->param0,msg_p->param1); + at_mailbox_user_free(THREAD_USER4,msg_p); + } + } +} +#endif + +int at_thread_user_init(enum THREAD_USER_ID user_id) +{ + AT_THREAD_TRACE(3,"%s,%d,user_id = %d.",__func__,__LINE__,user_id); + + if(user_id == THREAD_USER0) + { + at_thread_info[user_id].mid = osMailCreate(osMailQ(at_mailbox_user0), NULL); + at_thread_info[user_id].til = osThreadCreate(osThread(at_thread_user0), (void*)user_id); + } + if(user_id == THREAD_USER1) + { + at_thread_info[user_id].mid = osMailCreate(osMailQ(at_mailbox_user1), NULL); + at_thread_info[user_id].til = osThreadCreate(osThread(at_thread_user1), (void*)user_id); + } + + if(user_id == THREAD_USER2) + { + at_thread_info[user_id].mid = osMailCreate(osMailQ(at_mailbox_user2), NULL); + at_thread_info[user_id].til = osThreadCreate(osThread(at_thread_user2), (void*)user_id); + } + if(user_id == THREAD_USER3) + { + at_thread_info[user_id].mid = osMailCreate(osMailQ(at_mailbox_user3), NULL); + at_thread_info[user_id].til = osThreadCreate(osThread(at_thread_user3), (void*)user_id); + } + if(user_id == THREAD_USER4) + { + at_thread_info[user_id].mid = osMailCreate(osMailQ(at_mailbox_user4), NULL); + at_thread_info[user_id].til = osThreadCreate(osThread(at_thread_user4), (void*)user_id); + } + + if (at_thread_info[user_id].mid == NULL) { + AT_THREAD_TRACE(1,"Failed to Create mailbox, user_id = %d.",user_id); + return -1; + } + if (at_thread_info[user_id].til == NULL) { + AT_THREAD_TRACE(1,"Failed to Create thread for user. user_id = %d",user_id); + return -2; + } + at_thread_info[user_id].mail_count = 0; + at_thread_info[user_id].is_inited = true; + return 0; +} + +bool at_thread_user_is_inited(enum THREAD_USER_ID user_id) +{ + return at_thread_info[user_id].is_inited; +} + +int at_thread_user_enqueue_cmd(enum THREAD_USER_ID user_id, + uint32_t cmd_id, + uint32_t param0, + uint32_t param1, + uint32_t pfunc + ) +{ + AT_MESSAGE at_msg; + int32_t ret; + + at_msg.id = cmd_id; + at_msg.param0 = param0; + at_msg.param1 = param1; + at_msg.ptr = pfunc; + ret = at_mailbox_user_put(user_id,&at_msg); + return ret; +} diff --git a/services/auto_test/at_thread_user.h b/services/auto_test/at_thread_user.h new file mode 100644 index 0000000..d4bde03 --- /dev/null +++ b/services/auto_test/at_thread_user.h @@ -0,0 +1,101 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __AT_THREAD_USER_H__ +#define __AT_THREAD_USER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum THREAD_USER_ID +{ + THREAD_USER0, + THREAD_USER1, + THREAD_USER2, + THREAD_USER3, + THREAD_USER4, + THREAD_USER_COUNT, +}; + +typedef struct { + uint32_t id; + uint32_t ptr; + uint32_t param0; + uint32_t param1; +} AT_USER_MESSAGE; + +typedef enum +{ + RF_FREQUENCY_2402 = 0x31,//'1' + RF_FREQUENCY_2441, + RF_FREQUENCY_2480, + RF_FREQUENCY_2440, + RF_CHANNEL_BLE_STOP, //'5' + RF_FREQUENCY_2402_RX,//'6' + RF_FREQUENCY_2480_RX, + RF_FREQUENCY_2440_RX + +}RF_FREQUENCY_E; +typedef enum +{ + RF_CHANNEL_DH3, + RF_CHANNEL_DH5, + RF_CHANNEL_2DH5, + RF_CHANNEL_3DH5 + +}RF_CHANNEL_E; + +typedef enum +{ + RF_TX, + RF_RX + +}RF_TXRX_E; + +typedef enum +{ + MODEUNKNOW, + TWSMODEMASTER, + TWSMODESLAVE, + TWSMODEFREEMAN + +}GTK_FACTORY_TEST_TWS_MODE; + +void BleFrequencyTestStartRx(uint8_t index); +void BleFrequencyTestStart(uint8_t index); +void BleFrequencyTestStop(); +void BtFrequencyTestStart(uint8_t index); +void BtFrequencyTestStop(); +bool BleNosignalTestConfigPara(uint8_t index); +bool BtNosignalTestConfigPara(uint8_t channel, uint8_t frequency, uint8_t tx_rx); +bool StopBTRfTest(void); + +#define AT_USER_MESSAGE_ID_CMD 0 + +bool at_thread_user_is_inited(enum THREAD_USER_ID user_id); +int at_thread_user_init(enum THREAD_USER_ID user_id); +int at_thread_user_enqueue_cmd(enum THREAD_USER_ID user_id, + uint32_t cmd_id, + uint32_t param0, + uint32_t param1, + uint32_t pfunc + ); +#ifdef __cplusplus + } +#endif + +#endif // __AT_THREAD_USER_H__ + diff --git a/services/auto_test/auto_test.cpp b/services/auto_test/auto_test.cpp new file mode 100644 index 0000000..50e9888 --- /dev/null +++ b/services/auto_test/auto_test.cpp @@ -0,0 +1,2436 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(_AUTO_TEST_) +#include "cmsis_os.h" +#include "pmu.h" +#include "hal_trace.h" +#include "hal_aud.h" +#include "hal_key.h" +#include "apps.h" +#include "app_thread.h" +#include "app_status_ind.h" +#include "nvrecord.h" +#include "hal_timer.h" +#include "hal_chipid.h" +extern "C" { +#include "besbt_cfg.h" +#ifndef ENHANCED_STACK +#include "eventmgr.h" +#include "me.h" +#include "sec.h" +#include "avrcpi.h" +#include "sys/mei.h" +#endif +#include "a2dp.h" +#include "avdtp.h" +#include "avctp.h" +#include "avrcp.h" +} +#include "app_bt.h" +#include "btapp.h" +#include "hal_norflash.h" +#include "norflash_api.h" +#include "app_utils.h" +#include "at_thread.h" +#include "at_thread_user.h" + +#include "tgt_hardware.h" +#include "app_bt_stream.h" +#include "app_audio.h" +#include "hal_bootmode.h" +#include "bt_drv_interface.h" +#include "app_battery.h" +#include "hal_sleep.h" +#include "app_bt_stream.h" +#include "app_hfp.h" +#include "app_a2dp.h" +// ------------------------------------------------- +// auto test command list. +// AUTO_TEST AT_TEST Auto test ok. +// BT_INIT AT_INIT BT Init ok. +// POWER_ON POWER_ON Power on. +// POWER_OFF SYS_POWER_OFF System shutdown. +// REBOOT SYS_RESET System reset. +// Power on. +// PMU_SHUTDOWN PMU_SHUTDOWN Pmu shutdown. +// Power on. +// CONNECT CONNECT Connect ok. +// Page timeout +// PAIRING PAIRING Paring ok. +// CONNECT_TWS CONNECT_TWS Connect tws ok. +// CALL_SETUP CALL_SETUP:112 Call setup ok. +// CALL_HANGUP CALL_HANGUP Call hangup ok. +// MUSIC_ON MUSIC_ON Music on ok. +// MUSIC_SUSPEND MUSIC_SUSPEND Music suspend ok. +// SLEEP SLEEP_CHECK Sleep ok. +// SLEEP_CLEAN SLEEP_CLEAN Sleep clean ok. +// WAKEUP WAKEUP Wakeup ok. +// STANDBY STANDBY +// SWITCH_FREQ SWITCH_FREQ Switch freq ok. +// SIMULATE_KEY SIMULATE_KEY=, Simulate key ok. +// NORFALSH NORFLASH Norflash ok. +// NORFALSH_SUSPEND NORFLASH_SUSPEND Norflash suspend ok. +// MEMORY MEMORY Memory ok. +//--------------------------------------------------------- +typedef enum +{ + AT_CMD_ID_TEST , + AT_CMD_ID_POWER_OFF , + AT_CMD_ID_REBOOT , + AT_CMD_ID_PMU_SHUTDOWN, + AT_CMD_ID_CONNECT , + AT_CMD_ID_DISCONNECT , + AT_CMD_ID_PAIRING , + AT_CMD_ID_CONNECT_TWS , + AT_CMD_ID_CALL_SETUP , + AT_CMD_ID_CALL_HANGUP , + AT_CMD_ID_MUSIC_ON , + AT_CMD_ID_MUSIC_SUSPEND, + AT_CMD_ID_SLEEP , + AT_CMD_ID_SLEEP_CLEAN , + AT_CMD_ID_WAKEUP , + AT_CMD_ID_SWITCH_FREQ , + AT_CMD_ID_POWER_ON , + AT_CMD_ID_BT_INIT , + AT_CMD_ID_SIMULATE_KEY , + AT_CMD_ID_NORFLASH, + AT_CMD_ID_NORFLASH_SUSPEND, + AT_CMD_ID_MEMORY, + AT_CMD_ID_GET_MAC, + AT_CMD_ID_GET_NAME, + AT_CMD_ID_SET_LOOPBACK, + AT_CMD_ID_SET_LED, + AT_CMD_ID_ENTER_SIGNAL, + AT_CMD_ID_ENTER_NO_SIGNAL, + AT_CMD_ID_NO_SIGNAL_BLE, + AT_CMD_ID_NO_SIGNAL_BT, + AT_CMD_ID_GET_BATTERY, + AT_CMD_ID_SET_VOLUME, + AT_CMD_ID_GET_FWVER, + AT_CMD_ID_GET_BOOTMODE, + AT_CMD_ID_COUNT, + +}AT_CMD_ID_ENUM_T; + + +#define AT_CMD_TEST "AUTO_TEST" +#define AT_CMD_POWER_OFF "POWER_OFF" +#define AT_CMD_REBOOT "SYS_RESET" +#define AT_CMD_PMU_SHUTDOWN "PMU_SHUTDOWN" +#define AT_CMD_CONNECT "CONNECT" +#define AT_CMD_DISCONNECT "DISCONNECT" +#define AT_CMD_PAIRING "PAIRING" +#define AT_CMD_CONNECT_TWS "CONNECT_TWS" +#define AT_CMD_CALL_SETUP "CALL_SETUP" +#define AT_CMD_CALL_HANGUP "CALL_HANGUP" +#define AT_CMD_MUSIC_ON "MUSIC_ON" +#define AT_CMD_MUSIC_SUSPEND "MUSIC_SUSPEND" +#define AT_CMD_SLEEP "SLEEP_ENTER" +#define AT_CMD_SLEEP_CLEAN "SLEEP_CLEAN" +#define AT_CMD_WAKEUP "WAKEUP" +#define AT_CMD_SWITCH_FREQ "SWITCH_FREQ" +#define AT_CMD_POWER_ON "POWER_ON" +#define AT_CMD_BT_INIT "BT_INIT" +#define AT_CMD_SIMULATE_KEY "SIMULATE_KEY" +#define AT_CMD_NORFLASH "NORFLASH" +#define AT_CMD_NORFLASH_SUSPEND "NORFLASH_SUSPEND" +#define AT_CMD_MEMORY "MEMORY" +#define AT_CMD_GET_MAC "GET_MAC" +#define AT_CMD_GET_NAME "GET_NAME" +#define AT_CMD_SET_LOOPBACK "SET_LOOPBACK" +#define AT_CMD_SET_LED "SET_LED" +#define AT_CMD_ENTER_SIGNAL "ENTER_SIGNAL" +#define AT_CMD_ENTER_NO_SIGNAL "ENTER_NO_SIGNAL" +#define AT_CMD_NO_SIGNAL_BLE "NO_SIGNAL_BLE" +#define AT_CMD_NO_SIGNAL_BT "NO_SIGNAL_BT" +#define AT_CMD_GET_BATTERY "GET_BATTERY" +#define AT_CMD_SET_VOLUME "SET_VOLUME" +#define AT_CMD_GET_FWVER "GET_FWVER" +#define AT_CMD_GET_BOOTMODE "GET_BOOTMODE" + +#define AT_CMD_RESP_TEST "Auto test ok." +#define AT_CMD_RESP_POWER_OFF "System shutdown" +#define AT_CMD_RESP_REBOOT "System reset." +#define AT_CMD_RESP_PMU_SHUTDOWN "Pmu shutdown." +#define AT_CMD_RESP_CONNECT "Connect ok." +#define AT_CMD_RESP_DISCONNECT "Disconnect ok." +#define AT_CMD_RESP_PAIRING "Pairing ok." +#define AT_CMD_RESP_CONNECT_TWS "Connect tws ok." +#define AT_CMD_RESP_CALL_SETUP "Call setup ok." +#define AT_CMD_RESP_CALL_HANGUP "Call hangup ok." +#define AT_CMD_RESP_MUSIC_ON "Music on ok." +#define AT_CMD_RESP_MUSIC_SUSPEND "Music suspend ok." +#define AT_CMD_RESP_SLEEP "Sleep ok." +#define AT_CMD_RESP_SLEEP_CLEAN "Sleep clean ok." +#define AT_CMD_RESP_WAKEUP "Wakeup ok." +#define AT_CMD_RESP_SWITCH_FREQ "Switch freq ok." +#define AT_CMD_RESP_POWER_ON "Power on." +#define AT_CMD_RESP_BT_INIT "BT Init ok." +#define AT_CMD_RESP_SIMULATE_KEY "Simulate key ok." +#define AT_CMD_RESP_STANDBY "" +#define AT_CMD_RESP_NORFLASH "Norflash ok." +#define AT_CMD_RESP_NORFLASH_SUSPEND "Norflash suspend ok." +#define AT_CMD_RESP_MEMORY "Memory ok." +#define AT_CMD_RESP_LED "LED Display ok." +#define AT_CMD_RESP_BATTERY "Battery ok." +#define AT_CMD_RESP_LOOPBACK "LoopBack ok." +#define AT_CMD_RESP_MAC "Get MAC ok." +#define AT_CMD_RESP_FWVER "Get FWVER ok." +#define AT_CMD_RESP_BOOTMODE "Get Bootmode ok." +#define AT_CMD_RESP_TIME_OUT "Time out." +#define AT_CMD_RESP_ERROR "Error." + +#define CMD_OUT_TIME_MS (30*1000) // millisecond. + +typedef void (*APP_BT_AUTO_TEST_T)(uint32_t, uint32_t); +typedef enum +{ + AT_STATUS_FREE, + AT_STATUS_BUSY, +}AT_STATUS_T; + +typedef struct +{ + AT_CMD_ID_ENUM_T cmd_id; + const char* cmd; + APP_BT_AUTO_TEST_T pFunc; +} AT_CMD_FRAME_T; + +typedef struct +{ + AT_CMD_ID_ENUM_T cmd_id; + const char* resp; + uint32_t count; +}AT_CMD_RESP; + +typedef struct +{ + AT_CMD_ID_ENUM_T cur_cmd_id; + AT_STATUS_T status; + uint32_t start_time; + uint32_t param; + uint32_t pfunc; +}AT_STAUTS; + +#if 1 +#define AT_TRACE TRACE +#else +#define AT_TRACE(str,...) +#endif +void at_test(uint32_t param0,uint32_t param1); +void at_power_off(uint32_t param0,uint32_t param1); +void at_reboot(uint32_t param0,uint32_t param1); +void at_pmu_shutdown(uint32_t param0,uint32_t param1); +void at_connet(uint32_t param0,uint32_t param1); +void at_disconnet(uint32_t param0,uint32_t param1); +void at_pairing(uint32_t param0,uint32_t param1); +void at_connect_tws(uint32_t param0,uint32_t param1); +void at_call_setup(uint32_t param0,uint32_t param1); +void at_call_hangup(uint32_t param0,uint32_t param1); +void at_music_on(uint32_t param0,uint32_t param1); +void at_music_suspend(uint32_t param0,uint32_t param1); +void at_sleep(uint32_t param0,uint32_t param1); +void at_sleep_clean(uint32_t param0,uint32_t param1); +void at_wakeup(uint32_t param0,uint32_t param1); +void at_switch_freq(uint32_t param0,uint32_t param1); +void at_power_on(uint32_t param0,uint32_t param1); +void at_bt_init(uint32_t param0,uint32_t param1); +void at_simulate_key(uint32_t param0,uint32_t param1); +void at_norflash(uint32_t param0,uint32_t param1); +void at_norflash_suspend(uint32_t param0,uint32_t param1); +void at_memory(uint32_t param0,uint32_t param1); +void at_get_mac(uint32_t param0,uint32_t param1); +void at_get_devicename(uint32_t param0,uint32_t param1); +void at_set_loopback(uint32_t param0,uint32_t param1); +void at_set_led(uint32_t param0,uint32_t param1); +void at_enter_signaling_mode(uint32_t param0,uint32_t param1); +void at_enter_no_signaling_mode(uint32_t param0,uint32_t param1); +void at_no_signaling_ble_test(uint32_t param0,uint32_t param1); +void at_no_signaling_bt_test(uint32_t param0,uint32_t param1); +void at_get_battery(uint32_t param0,uint32_t param1); +void at_set_volume(uint32_t param0,uint32_t param1); +void at_get_fwversion(uint32_t param0,uint32_t param1); +void at_get_bootmode(uint32_t param0,uint32_t param1); + +extern "C" int system_shutdown(void); +extern int system_reset(void); +extern void bt_key_send(uint32_t code, uint16_t event); +extern void system_get_fwversion(uint8_t *fw_rev_0, uint8_t *fw_rev_1, + uint8_t *fw_rev_2, uint8_t *fw_rev_3); + +#if defined(BT_USB_AUDIO_DUAL_MODE_TEST) +extern "C" void test_btusb_switch(void); +extern "C" void test_btusb_switch_to_bt(void); +extern "C" void test_btusb_switch_to_usb(void); + +#endif + +static const AT_CMD_FRAME_T g_at_cmd_frame[] = { + {AT_CMD_ID_TEST ,AT_CMD_TEST ,at_test }, + {AT_CMD_ID_POWER_OFF ,AT_CMD_POWER_OFF ,at_power_off }, + {AT_CMD_ID_REBOOT ,AT_CMD_REBOOT ,at_reboot }, + {AT_CMD_ID_PMU_SHUTDOWN ,AT_CMD_PMU_SHUTDOWN ,at_pmu_shutdown }, + {AT_CMD_ID_CONNECT ,AT_CMD_CONNECT ,at_connet }, + {AT_CMD_ID_DISCONNECT ,AT_CMD_DISCONNECT ,at_disconnet }, + {AT_CMD_ID_PAIRING ,AT_CMD_PAIRING ,at_pairing }, + {AT_CMD_ID_CONNECT_TWS ,AT_CMD_CONNECT_TWS ,at_connect_tws }, + {AT_CMD_ID_CALL_SETUP ,AT_CMD_CALL_SETUP ,at_call_setup }, + {AT_CMD_ID_CALL_HANGUP ,AT_CMD_CALL_HANGUP ,at_call_hangup }, + {AT_CMD_ID_MUSIC_ON ,AT_CMD_MUSIC_ON ,at_music_on }, + {AT_CMD_ID_MUSIC_SUSPEND ,AT_CMD_MUSIC_SUSPEND ,at_music_suspend }, + {AT_CMD_ID_SLEEP ,AT_CMD_SLEEP ,at_sleep }, + {AT_CMD_ID_SLEEP_CLEAN ,AT_CMD_SLEEP_CLEAN ,at_sleep_clean }, + {AT_CMD_ID_WAKEUP ,AT_CMD_WAKEUP ,at_wakeup }, + {AT_CMD_ID_SWITCH_FREQ ,AT_CMD_SWITCH_FREQ ,at_switch_freq }, + {AT_CMD_ID_POWER_ON ,AT_CMD_POWER_ON ,at_power_on }, + {AT_CMD_ID_BT_INIT ,AT_CMD_BT_INIT ,at_bt_init }, + {AT_CMD_ID_SIMULATE_KEY ,AT_CMD_SIMULATE_KEY ,at_simulate_key }, + {AT_CMD_ID_NORFLASH ,AT_CMD_NORFLASH ,at_norflash }, + {AT_CMD_ID_NORFLASH_SUSPEND ,AT_CMD_NORFLASH_SUSPEND ,at_norflash_suspend }, + {AT_CMD_ID_MEMORY ,AT_CMD_MEMORY ,at_memory }, + {AT_CMD_ID_GET_MAC ,AT_CMD_GET_MAC ,at_get_mac }, + {AT_CMD_ID_GET_NAME ,AT_CMD_GET_NAME ,at_get_devicename }, + {AT_CMD_ID_SET_LOOPBACK ,AT_CMD_SET_LOOPBACK ,at_set_loopback }, + {AT_CMD_ID_SET_LED ,AT_CMD_SET_LED ,at_set_led }, + {AT_CMD_ID_ENTER_SIGNAL ,AT_CMD_ENTER_SIGNAL ,at_enter_signaling_mode }, + {AT_CMD_ID_ENTER_NO_SIGNAL ,AT_CMD_ENTER_NO_SIGNAL ,at_enter_no_signaling_mode }, + {AT_CMD_ID_NO_SIGNAL_BLE ,AT_CMD_NO_SIGNAL_BLE ,at_no_signaling_ble_test }, + {AT_CMD_ID_NO_SIGNAL_BT ,AT_CMD_NO_SIGNAL_BT ,at_no_signaling_bt_test }, + {AT_CMD_ID_GET_BATTERY ,AT_CMD_GET_BATTERY ,at_get_battery }, + {AT_CMD_ID_SET_VOLUME ,AT_CMD_SET_VOLUME ,at_set_volume }, + {AT_CMD_ID_GET_FWVER ,AT_CMD_GET_FWVER ,at_get_fwversion }, + {AT_CMD_ID_GET_BOOTMODE ,AT_CMD_GET_BOOTMODE ,at_get_bootmode }, + {AT_CMD_ID_COUNT ,(const char*)NULL ,NULL}, +}; + +static AT_CMD_RESP g_at_cmd_resp[] = { + {AT_CMD_ID_TEST ,AT_CMD_RESP_TEST ,0 }, + {AT_CMD_ID_POWER_OFF ,AT_CMD_RESP_POWER_OFF ,0 }, + {AT_CMD_ID_REBOOT ,AT_CMD_RESP_REBOOT ,0 }, + {AT_CMD_ID_PMU_SHUTDOWN ,AT_CMD_RESP_PMU_SHUTDOWN ,0 }, + {AT_CMD_ID_CONNECT ,AT_CMD_RESP_CONNECT ,0 }, + {AT_CMD_ID_DISCONNECT ,AT_CMD_RESP_DISCONNECT ,0 }, + {AT_CMD_ID_PAIRING ,AT_CMD_RESP_PAIRING ,0 }, + {AT_CMD_ID_CONNECT_TWS ,AT_CMD_RESP_CONNECT_TWS ,0 }, + {AT_CMD_ID_CALL_SETUP ,AT_CMD_RESP_CALL_SETUP ,0 }, + {AT_CMD_ID_CALL_HANGUP ,AT_CMD_RESP_CALL_HANGUP ,0 }, + {AT_CMD_ID_MUSIC_ON ,AT_CMD_RESP_MUSIC_ON ,0 }, + {AT_CMD_ID_MUSIC_SUSPEND ,AT_CMD_RESP_MUSIC_SUSPEND ,0 }, + {AT_CMD_ID_SLEEP ,AT_CMD_RESP_SLEEP ,0 }, + {AT_CMD_ID_SLEEP_CLEAN ,AT_CMD_RESP_SLEEP_CLEAN ,0 }, + {AT_CMD_ID_WAKEUP ,AT_CMD_RESP_WAKEUP ,0 }, + {AT_CMD_ID_SWITCH_FREQ ,AT_CMD_RESP_SWITCH_FREQ ,0 }, + {AT_CMD_ID_POWER_ON ,AT_CMD_RESP_POWER_ON ,0 }, + {AT_CMD_ID_BT_INIT ,AT_CMD_RESP_BT_INIT ,0 }, + {AT_CMD_ID_SIMULATE_KEY ,AT_CMD_RESP_SIMULATE_KEY ,0 }, + {AT_CMD_ID_NORFLASH ,AT_CMD_RESP_NORFLASH ,0 }, + {AT_CMD_ID_NORFLASH_SUSPEND ,AT_CMD_RESP_NORFLASH_SUSPEND ,0 }, + {AT_CMD_ID_MEMORY ,AT_CMD_RESP_MEMORY ,0 }, + {AT_CMD_ID_COUNT ,(const char*)NULL ,0 }, + +}; + +AT_STAUTS g_at_status = {AT_CMD_ID_COUNT,AT_STATUS_FREE,0,0,0}; + +void _at_trim(uint8_t* buff) +{ + uint8_t* p; + uint32_t len; + // int32_t i; + + len = strlen((char*)buff); + p = buff + (len - 1); + + while(1) + { + if(*p == 0x20 || *p == 0x09 || *p == 0x0A || *p == 0x0D) + { + *p = 0; + p--; + } + else + { + break; + } + if(p == buff) + { + break; + } + } + + p = buff; + while(1) + { + if(*p == 0x20 || *p == 0x09) + { + p++; + } + else + { + break; + } + } + + while(*p) + { + *buff = *p; + buff ++; + p++; + } +} + +/* +static int _at_strtohex(uint8_t* hex, char* str, int len) +{ + int i = 0; + char* begin; + char* end; + //char* tmp; + char* hex_unit; + + begin = str; + end = str; + for(i = 0; i < len; i++) + { + hex_unit = begin; + end = strstr(begin,","); + if(end) + { + *end = 0; + begin = end + 1; + } + else + { + } + hex[i] = (uint8_t)strtol(hex_unit,NULL,16); + } + if(i == len) + return 0; + else + return -1; +} +*/ +static char* _at_get_cmd_resp(AT_CMD_ID_ENUM_T cmd_id) +{ + uint32_t i; + uint32_t cmd_count = 0; + char* resp = NULL; + + cmd_count = sizeof(g_at_cmd_resp)/sizeof(AT_CMD_RESP); + + for(i = 0; i < cmd_count; i++) + { + if(AT_CMD_ID_COUNT == g_at_cmd_resp[i].cmd_id) + { + AT_TRACE(1,"_debug: undefined at cmd resp, cmd_id = %d.",cmd_id); + resp = NULL; + goto _func_end; + } + if(cmd_id == g_at_cmd_resp[i].cmd_id) + { + if(g_at_cmd_resp[i].count > 0) + { + resp = (char*)g_at_cmd_resp[i].resp; + g_at_cmd_resp[i].count = 0; + AT_TRACE(2,"_debug: ount > 0,cmd_id = %d,resp = %s.",cmd_id,resp); + } + else + { + resp = NULL; + } + break; + } + } +_func_end: + return resp; +} + +/* +static AT_STATUS_T _at_get_status(void) +{ + if(g_at_status.cur_cmd_id == AT_CMD_ID_COUNT) + return AT_STATUS_FREE; + return g_at_status.status; +} +*/ + +static AT_CMD_ID_ENUM_T _at_get_cur_cmd_id(void) +{ + return g_at_status.cur_cmd_id; +} + +static void _at_set_status(AT_CMD_ID_ENUM_T cmd_id,AT_STATUS_T status,uint32_t param,uint32_t pfuc) +{ + g_at_status.status = status; + if(status == AT_STATUS_BUSY) + { + g_at_status.cur_cmd_id = cmd_id; + g_at_status.start_time = hal_sys_timer_get(); + } + g_at_status.param = param; + g_at_status.pfunc = pfuc; +} + +static void _at_resp(void) +{ + AT_CMD_ID_ENUM_T cur_cmd_id; + uint32_t wait_time; + char* resp; + + cur_cmd_id = _at_get_cur_cmd_id(); + if(cur_cmd_id == AT_CMD_ID_COUNT) + { + TRACE_IMM(1,"AUTO_TEST:%s",AT_CMD_RESP_ERROR); + return; + } + resp = _at_get_cmd_resp(cur_cmd_id); + if(resp) + { + //osDelay(64); + TRACE_IMM(1,"AUTO_TEST: %s",resp); + //osDelay(64); + _at_set_status(AT_CMD_ID_COUNT,AT_STATUS_FREE,0,0); + } + else + { + wait_time = TICKS_TO_MS(hal_sys_timer_get() - g_at_status.start_time); + if(wait_time < CMD_OUT_TIME_MS) + { + //osDelay(4); + //app_bt_send_request(APP_BT_REQ_AUTO_TEST, (uint32_t)g_at_status.param,cur_cmd_id, + //g_at_status.pfunc); + AT_TRACE(1,"_debug: _at_resp,auto_test wait : %d(ms)",wait_time); + } + else + { + _at_set_status(AT_CMD_ID_COUNT,AT_STATUS_FREE,0,0); + AT_TRACE(2,"AUTO_TEST:%s,wait time = %d(ms)",AT_CMD_RESP_TIME_OUT,wait_time); + } + } +} + +#define AT_PARAM_LEN 256 +uint8_t at_param_buff[AT_PARAM_LEN]; +extern "C" int auto_test_prase(uint8_t *cmd) +{ + int ret = 0; + uint8_t i; + uint8_t* cmd_name = NULL; + uint8_t* cmd_param = NULL; + uint8_t* p; + AT_CMD_ID_ENUM_T cmd_id; + uint32_t param_len; + + if(NULL == cmd) + { + ret = -1; + goto _func_end; + } + + AT_TRACE(1,"_debug: cmd = %s",cmd); + cmd_name = cmd; + p = (uint8_t*)strstr((char*)cmd,(char*)"="); + if(p) + { + *p = 0; + cmd_param = (p + 1); + _at_trim(cmd_param); + } + else + { + cmd_param = NULL; + } + _at_trim(cmd_name); + + + for(i = 0; i < sizeof(g_at_cmd_frame)/sizeof(AT_CMD_FRAME_T); i++) + { + if(AT_CMD_ID_COUNT == g_at_cmd_frame[i].cmd_id) + { + AT_TRACE(1,"_debug: undefined at cmd: %s.",cmd); + ret = -2; + goto _func_end; + } + if(!strcmp((const char *)cmd, (const char *)g_at_cmd_frame[i].cmd)) + { + if(NULL == g_at_cmd_frame[i].pFunc) + { + ret = -3; + goto _func_end; + } + + /* + if(AT_CMD_ID_REBOOT != g_at_cmd_frame[i].cmd_id) + { + if(_at_get_status() != AT_STATUS_FREE) + { + ret = -2; + AT_TRACE(3,"_debug: auto_test is busy. cmd = %s,cmd_id = %d,cur_cmd_id = %d", + g_at_cmd_frame[i].cmd_id,cmd,g_at_status.cur_cmd_id); + goto _func_end; + } + } + */ + cmd_id = g_at_cmd_frame[i].cmd_id; + // AT_TRACE(2,"_debug: %s,line= %d.",__func__,__LINE__); + //memset(at_param_buff,0,sizeof(at_param_buff)); + if(NULL != cmd_param) + { + param_len = strlen((char*)cmd_param); + param_len = param_len < sizeof(at_param_buff) ? param_len : sizeof(at_param_buff) - 1; + if(param_len > 0) + { + strncpy((char*)at_param_buff,(char*)cmd_param,param_len); + } + } + _at_set_status(cmd_id,AT_STATUS_BUSY,(uint32_t)cmd_param,(uint32_t)g_at_cmd_frame[i].pFunc); + at_enqueue_cmd((uint32_t)cmd_id,(uint32_t)at_param_buff,(uint32_t)g_at_cmd_frame[i].pFunc); + //g_at_cmd_frame[i].pFunc((uint32_t)cmd_param,cmd_id); + + break; + } + } +_func_end: + if(ret != 0) + { + AT_TRACE(1,"_debug: parse failed,ret = %d.",ret); + } + return ret; +} + +extern "C" int auto_test_send(char *resp) +{ + uint32_t i; + uint32_t cmd_count = 0; + int32_t ret = 0; + + cmd_count = sizeof(g_at_cmd_resp)/sizeof(AT_CMD_RESP); + // AT_TRACE(1,"_debug: auto_test_send : %s",resp); + for(i = 0; i < cmd_count; i++) + { + if(AT_CMD_ID_COUNT == g_at_cmd_resp[i].cmd_id) + { + AT_TRACE(1,"_debug: auto_test_send: undefined at cmd resp, resp = %s.",resp); + ret = -1; + goto _func_end; + } + if(!strncmp((const char *)resp, (const char *)g_at_cmd_resp[i].resp,strlen((char*)g_at_cmd_resp[i].resp))) + { + if( g_at_cmd_resp[i].cmd_id == AT_CMD_ID_POWER_ON || + // g_at_cmd_resp[i].cmd_id == AT_CMD_ID_POWER_OFF || + // g_at_cmd_resp[i].cmd_id == AT_CMD_ID_REBOOT || + g_at_cmd_resp[i].cmd_id == g_at_status.cur_cmd_id) + { + TRACE_IMM(1,"AUTO_TEST:%s",resp); + _at_set_status(AT_CMD_ID_COUNT,AT_STATUS_FREE,0,0); + } + else + { + g_at_cmd_resp[i].count = 1; + AT_TRACE(2,"_debug: auto_test_send: set count to 1, i = %d, resp = %s.",i,resp); + } + break; + } + } +_func_end: + if(ret != 0) + { + AT_TRACE(1,"_debug: auto_test_send: %s undefine !!!!!",resp); + } + return ret; +} + +void at_test(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am app_auto_test"); + + AUTO_TEST_SEND(AT_CMD_RESP_TEST); +} + +void at_power_off(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + AT_TRACE(0,"_debug: I am at_power_off"); + pmu_at_skip_shutdown(false); + system_shutdown(); +} + +void at_reboot(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + AT_TRACE(0,"_debug: I am at_reboot"); + //system_reset(); + app_reset(); +} + +void at_pmu_shutdown(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am at_reboot"); + //system_reset(); + + AUTO_TEST_SEND(AT_CMD_RESP_PMU_SHUTDOWN); + + // pmu_rtc_enable(); + // pmu_rtc_set(5); + // pmu_rtc_set_alarm(10); + pmu_at_skip_shutdown(true); + pmu_shutdown(); +} + +void at_connet(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + //AT_TRACE(0,"_debug: I am at_connet"); + //app_tws_charger_box_opened(); + _at_resp(); +} + +void at_disconnet(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am at_disconnet"); + _at_resp(); +} + +void at_pairing(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am at_pairing"); + _at_resp(); +} + +void at_connect_tws(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am at_connect_tws"); + _at_resp(); +} + +void at_call_setup(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am at_call_setup"); + _at_resp(); +} + +void at_call_hangup(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am at_call_hangup"); + _at_resp(); +} + +static void music_on_callback(void); +#define MUSIC_ON_DELAY_MS 500 +osTimerDef(MUSIC_ON_TIMER, (void (*)(void const *))music_on_callback); +static osTimerId music_on_timer = NULL; +static bool music_on_flag = 1; +static void music_on_callback(void) +{ + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); +} + +void at_music_on(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + AT_TRACE(0,"_debug: I am at_music_on"); + + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); + if(music_on_flag) + { + music_on_timer = osTimerCreate (osTimer(MUSIC_ON_TIMER), osTimerPeriodic, 0); + music_on_flag = 0; + } + osTimerStart(music_on_timer, MUSIC_ON_DELAY_MS); + + _at_resp(); +} + +void at_music_suspend(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + AT_TRACE(0,"_debug: I am at_music_suspend"); + osTimerStop(music_on_timer); + _at_resp(); +} + +void at_sleep(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + AT_TRACE(0,"_debug: I am at_sleep"); + + //hal_sleep_enter_sleep(); + //app_bt_stop_sniff(); + + _at_resp(); +} + +void at_sleep_clean(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + unsigned int i; + + //AT_TRACE(0,"_debug: I am at_sleep_clean"); + + for(i = 0; i < sizeof(g_at_cmd_resp)/sizeof(AT_CMD_RESP); i++) + { + if(AT_CMD_ID_SLEEP_CLEAN == g_at_cmd_resp[i].cmd_id) + { + g_at_cmd_resp[i].count = 0; + break; + } + } + AUTO_TEST_SEND(AT_CMD_RESP_SLEEP_CLEAN); +} + +void at_wakeup(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am at_wakeup"); + _at_resp(); +} + +void at_switch_freq(uint32_t param0,uint32_t param1) +{ + char* p = (char*)param0; + char* user_str; + char* freq_str; + uint32_t user = 0xffffffff; + uint32_t freq = 0xffffffff; + int i; + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am at_switch_freq"); + user_str = (char*)param0; + p = strstr(user_str,","); + if(p) + { + *p = 0; + p ++; + } + else + { + AT_TRACE(0,"_debug: at_switch_freq: param error 0."); + goto _func_end; + } + _at_trim((uint8_t*)user_str); + if(*user_str) + { + user = atoi(user_str); + } + else + { + AT_TRACE(0,"_debug: at_switch_freq: param error 1."); + goto _func_end; + } + + freq_str = p; + _at_trim((uint8_t*)freq_str); + if(*freq_str) + { + freq = atoi(freq_str); + } + else + { + AT_TRACE(0,"_debug: at_switch_freq: param error 2."); + goto _func_end; + } + if(user >= APP_SYSFREQ_USER_QTY || freq >= APP_SYSFREQ_FREQ_QTY) + { + AT_TRACE(0,"_debug: at_switch_freq: param error 3."); + goto _func_end; + } + + //AT_TRACE(2,"_debug: at_switch_freq: user = %d, freq = %d.",user,freq); + app_sysfreq_req((APP_SYSFREQ_USER_T)user,(APP_SYSFREQ_FREQ_T)freq); + + for(i = 0; i < 10000; i ++) + { + + } + AUTO_TEST_SEND("Switch freq ok."); +_func_end: + return; + +} + +void at_power_on(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am at_power_on"); + AUTO_TEST_SEND(AT_CMD_RESP_POWER_ON); +} + +void at_bt_init(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + + //AT_TRACE(0,"_debug: I am at_bt_init"); + _at_resp(); + +} + +#include "app_key.h" + typedef struct + { + uint32_t key; + const char* key_str; + }AT_KEY_MAP; + AT_KEY_MAP key_code_map[] = + { + {(uint32_t)HAL_KEY_CODE_NONE,"KEY_CODE_NONE"}, + {(uint32_t)HAL_KEY_CODE_PWR ,"KEY_CODE_PWR" }, + {(uint32_t)HAL_KEY_CODE_FN1 ,"KEY_CODE_FN1" }, + {(uint32_t)HAL_KEY_CODE_FN2 ,"KEY_CODE_FN2" }, + {(uint32_t)HAL_KEY_CODE_FN3 ,"KEY_CODE_FN3" }, + {(uint32_t)HAL_KEY_CODE_FN4 ,"KEY_CODE_FN4" }, + {(uint32_t)HAL_KEY_CODE_FN5 ,"KEY_CODE_FN5" }, + {(uint32_t)HAL_KEY_CODE_FN6 ,"KEY_CODE_FN6" }, + {(uint32_t)HAL_KEY_CODE_FN7 ,"KEY_CODE_FN7" }, + {(uint32_t)HAL_KEY_CODE_FN8 ,"KEY_CODE_FN8" }, + {(uint32_t)HAL_KEY_CODE_FN9 ,"KEY_CODE_FN9" }, + {(uint32_t)HAL_KEY_CODE_FN10,"KEY_CODE_FN10"}, + {(uint32_t)HAL_KEY_CODE_FN11,"KEY_CODE_FN11"}, + {(uint32_t)HAL_KEY_CODE_FN12,"KEY_CODE_FN12"}, + {(uint32_t)HAL_KEY_CODE_FN13,"KEY_CODE_FN13"}, + {(uint32_t)HAL_KEY_CODE_FN14,"KEY_CODE_FN14"}, + {(uint32_t)HAL_KEY_CODE_FN15,"KEY_CODE_FN15"} + }; + AT_KEY_MAP key_event_map[] = + { + {(uint32_t)HAL_KEY_EVENT_NONE ,"KEY_EVENT_NONE" }, + {(uint32_t)HAL_KEY_EVENT_DOWN ,"KEY_EVENT_DOWN" }, + {(uint32_t)HAL_KEY_EVENT_FIRST_DOWN ,"KEY_EVENT_FIRST_DOWN" }, + {(uint32_t)HAL_KEY_EVENT_CONTINUED_DOWN ,"KEY_EVENT_CONTINUED_DOWN" }, + {(uint32_t)HAL_KEY_EVENT_UP ,"KEY_EVENT_UP" }, + {(uint32_t)HAL_KEY_EVENT_LONGPRESS ,"KEY_EVENT_LONGPRESS" }, + {(uint32_t)HAL_KEY_EVENT_LONGLONGPRESS ,"KEY_EVENT_LONGLONGPRESS" }, + {(uint32_t)HAL_KEY_EVENT_CLICK ,"KEY_EVENT_CLICK" }, + {(uint32_t)HAL_KEY_EVENT_DOUBLECLICK ,"KEY_EVENT_DOUBLECLICK" }, + {(uint32_t)HAL_KEY_EVENT_TRIPLECLICK ,"KEY_EVENT_TRIPLECLICK" }, + {(uint32_t)HAL_KEY_EVENT_ULTRACLICK ,"KEY_EVENT_ULTRACLICK" }, + {(uint32_t)HAL_KEY_EVENT_RAMPAGECLICK ,"KEY_EVENT_RAMPAGECLICK" }, + {(uint32_t)HAL_KEY_EVENT_REPEAT ,"KEY_EVENT_REPEAT" }, + {(uint32_t)HAL_KEY_EVENT_GROUPKEY_DOWN ,"KEY_EVENT_GROUPKEY_DOWN" }, + {(uint32_t)HAL_KEY_EVENT_GROUPKEY_REPEAT ,"KEY_EVENT_GROUPKEY_REPEAT" }, + {(uint32_t)HAL_KEY_EVENT_INITDOWN ,"KEY_EVENT_INITDOWN" }, + {(uint32_t)HAL_KEY_EVENT_INITUP ,"KEY_EVENT_INITUP" }, + {(uint32_t)HAL_KEY_EVENT_INITLONGPRESS ,"KEY_EVENT_INITLONGPRESS" }, + {(uint32_t)HAL_KEY_EVENT_INITLONGLONGPRESS,"KEY_EVENT_INITLONGLONGPRESS"}, + {(uint32_t)HAL_KEY_EVENT_INITFINISHED ,"KEY_EVENT_INITFINISHED" } + }; +void at_simulate_key(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + char* code_str; + char* event_str; + uint32_t key_code = 0; + uint16_t key_event = 0; + char* p; + uint32_t i; + + cmd_id = cmd_id; + AT_TRACE(0,"_debug: I am at_simulate_key"); + p = (char*)param0; + code_str = p; + p = strstr(p,","); + if(p) + { + *p = 0; + p++; + } + else + { + goto _func_end; + } + + event_str = p; + _at_trim((uint8_t*)code_str); + _at_trim((uint8_t*)event_str); + AT_TRACE(2,"_debug: code_str = %s, event_str = %s.",code_str,event_str); + for(i = 0; i < sizeof(key_code_map)/sizeof(AT_KEY_MAP); i ++) + { + if(strncmp(code_str,key_code_map[i].key_str,strlen(code_str)) == 0) + { + key_code = key_code_map[i].key; + break; + } + } + + if(i == sizeof(key_code_map)/sizeof(AT_KEY_MAP)) + { + goto _func_end; + } + + for(i = 0; i < sizeof(key_event_map)/sizeof(AT_KEY_MAP); i ++) + { + if(strncmp(event_str,key_event_map[i].key_str,strlen(event_str)) == 0) + { + key_event = (key_event_map[i].key & 0xffff); + break; + } + } + + if(i == sizeof(key_event_map)/sizeof(AT_KEY_MAP)) + { + goto _func_end; + } + AT_TRACE(2,"_debug: key_code = %d, key_event = %d.",key_code,key_event); + + if(key_code == HAL_KEY_CODE_FN15 && key_event == HAL_KEY_EVENT_CLICK) + { +#if defined(BT_USB_AUDIO_DUAL_MODE_TEST) + test_btusb_switch_to_bt(); + //osDelay(5000); +#endif + } + if(key_code == HAL_KEY_CODE_FN14 && key_event == HAL_KEY_EVENT_CLICK) + { +#if defined(BT_USB_AUDIO_DUAL_MODE_TEST) + test_btusb_switch_to_usb(); +#endif + } + AUTO_TEST_SEND(AT_CMD_RESP_SIMULATE_KEY); + //simul_key_event_process((uint32_t)key_code,(uint16_t)key_event); + + +_func_end: + return; +} + +enum AT_FLASH_REGION_ID +{ + FLASH_REGION_ID_CODE, + FLASH_REGION_ID_FREE, + FLASH_REGION_ID_CRASH_DUMP, + FLASH_REGION_ID_AUD, + FLASH_REGION_ID_USERDATA, + FLASH_REGION_ID_FACTORY, + FLASH_REGION_ID_NUMBER, + }; + +typedef struct _flash_region_info +{ + enum AT_FLASH_REGION_ID id; + uint32_t start_addr; + uint32_t end_addr; +}AT_FLASH_REGION_INFO; +#define AT_ALIGN(x,a) (uint32_t)(((x + a - 1)/a) * a) +extern uint32_t __flash_start; +extern uint32_t __flash_end; + +extern uint32_t __crash_dump_start; +extern uint32_t __crash_dump_end; + +extern uint32_t __custom_parameter_start; +extern uint32_t __custom_parameter_end; + +extern uint32_t __aud_start; +extern uint32_t __aud_end; + +extern uint32_t __userdata_start; +extern uint32_t __userdata_end; + +extern uint32_t __factory_start; +extern uint32_t __factory_end; +extern uint32_t __free_flash; +#define AT_FLASH_SECTOR_SIZE 0x1000 +#define AT_FLASH_BLOCK_SIZE 0x10000 +AT_FLASH_REGION_INFO region_info[] = { + {FLASH_REGION_ID_CODE, + FLASH_C_TO_NC(AT_ALIGN((uint32_t)(&__flash_start),AT_FLASH_SECTOR_SIZE)), + FLASH_C_TO_NC(AT_ALIGN((uint32_t)(&__flash_end),AT_FLASH_SECTOR_SIZE))}, + {FLASH_REGION_ID_FREE, + FLASH_C_TO_NC(AT_ALIGN((uint32_t)(&__flash_end + AT_FLASH_SECTOR_SIZE),AT_FLASH_SECTOR_SIZE)), + FLASH_C_TO_NC(AT_ALIGN((uint32_t)(&__flash_end + AT_FLASH_SECTOR_SIZE + 16*AT_FLASH_SECTOR_SIZE),AT_FLASH_SECTOR_SIZE))},//AT_ALIGN((uint32_t)(&__crash_dump_start),AT_FLASH_SECTOR_SIZE)}, + {FLASH_REGION_ID_CRASH_DUMP, + FLASH_C_TO_NC(AT_ALIGN((uint32_t)(&__flash_end + AT_FLASH_SECTOR_SIZE + 16*AT_FLASH_SECTOR_SIZE),AT_FLASH_SECTOR_SIZE)),//AT_ALIGN((uint32_t)(&__crash_dump_start),AT_FLASH_SECTOR_SIZE), + FLASH_C_TO_NC(AT_ALIGN((uint32_t)(&__flash_end + AT_FLASH_SECTOR_SIZE + 32*AT_FLASH_SECTOR_SIZE),AT_FLASH_SECTOR_SIZE))},//AT_ALIGN((uint32_t)(&__crash_dump_end),AT_FLASH_SECTOR_SIZE)}, + {FLASH_REGION_ID_AUD, + AT_ALIGN((uint32_t)(&__aud_start),AT_FLASH_SECTOR_SIZE), + AT_ALIGN((uint32_t)(&__aud_end),AT_FLASH_SECTOR_SIZE)}, + {FLASH_REGION_ID_USERDATA, + AT_ALIGN((uint32_t)(&__userdata_start),AT_FLASH_SECTOR_SIZE), + AT_ALIGN((uint32_t)(&__userdata_end),AT_FLASH_SECTOR_SIZE)}, + {FLASH_REGION_ID_FACTORY, + AT_ALIGN((uint32_t)(&__factory_start) + 20*AT_FLASH_SECTOR_SIZE,AT_FLASH_SECTOR_SIZE),//AT_ALIGN((uint32_t)(&__factory_start),AT_FLASH_SECTOR_SIZE), + AT_ALIGN((uint32_t)(&__flash_end) + 30*AT_FLASH_SECTOR_SIZE,AT_FLASH_SECTOR_SIZE)},//AT_ALIGN((uint32_t)(&__factory_end),AT_FLASH_SECTOR_SIZE)}, + }; + +uint8_t at_buff_r[AT_FLASH_SECTOR_SIZE]; +uint8_t at_buff_r1[AT_FLASH_SECTOR_SIZE]; +uint8_t at_buff_w[AT_FLASH_SECTOR_SIZE]; +uint8_t at_buff_b[AT_FLASH_SECTOR_SIZE]; + +int32_t _at_norflash_test(uint32_t addr,uint32_t size,uint8_t is_restore) +{ + uint32_t start_addr; + uint32_t i,j; + uint8_t value = 0; + int32_t ret = 0; + enum HAL_NORFLASH_RET_T result = HAL_NORFLASH_OK; + + for(i = 0; i < size/AT_FLASH_SECTOR_SIZE; i++) + { + // erase checking. + start_addr = addr + i * AT_FLASH_SECTOR_SIZE; + if(is_restore != 0) + { + result = hal_norflash_read(HAL_NORFLASH_ID_0,start_addr,at_buff_b,AT_FLASH_SECTOR_SIZE); + if(result != HAL_NORFLASH_OK) + { + ret = -2; + goto _func_end; + } + } + result = hal_norflash_erase(HAL_NORFLASH_ID_0,start_addr,AT_FLASH_SECTOR_SIZE); + if(result != HAL_NORFLASH_OK) + { + ret = -1; + goto _func_end; + } + result = hal_norflash_read(HAL_NORFLASH_ID_0,start_addr,at_buff_r,AT_FLASH_SECTOR_SIZE); + if(result != HAL_NORFLASH_OK) + { + ret = -2; + goto _func_end; + } + for(j = 0; j < AT_FLASH_SECTOR_SIZE; j++) + { + if(at_buff_r[j] != 0xff) + { + ret = -3; + goto _func_end; + } + } + + // write/read checking + for(j = 0; j < AT_FLASH_SECTOR_SIZE; j++) + { + at_buff_w[j] = value ++; + } + result = hal_norflash_write(HAL_NORFLASH_ID_0,start_addr,at_buff_w,AT_FLASH_SECTOR_SIZE); + if(result != HAL_NORFLASH_OK) + { + ret = -4; + goto _func_end; + } + + result = hal_norflash_read(HAL_NORFLASH_ID_0,start_addr,at_buff_r,AT_FLASH_SECTOR_SIZE); + if(result != HAL_NORFLASH_OK) + { + ret = -5; + goto _func_end; + } + for(j = 0; j < AT_FLASH_SECTOR_SIZE; j++) + { + if(at_buff_r[j] != at_buff_w[j]) + { + ret = -6; + goto _func_end; + } + } + if(is_restore != 0) + { + result = hal_norflash_erase(HAL_NORFLASH_ID_0,start_addr,AT_FLASH_SECTOR_SIZE); + if(result != HAL_NORFLASH_OK) + { + ret = -7; + break; + } + result = hal_norflash_write(HAL_NORFLASH_ID_0,start_addr,at_buff_b,AT_FLASH_SECTOR_SIZE); + if(result != HAL_NORFLASH_OK) + { + ret = -8; + break; + } + result = hal_norflash_read(HAL_NORFLASH_ID_0,start_addr,at_buff_r,AT_FLASH_SECTOR_SIZE); + if(result != HAL_NORFLASH_OK) + { + ret = -9; + goto _func_end; + } + for(j = 0; j < AT_FLASH_SECTOR_SIZE; j++) + { + if(at_buff_r[j] != at_buff_b[j]) + { + ret = -10; + goto _func_end; + } + } + + } + + } + +_func_end: + + //AT_TRACE(1,"_debug: flash checking end. ret = %d.",ret); + return ret; + +} + + +AT_FLASH_REGION_INFO* _at_norflash_get_region_info(enum AT_FLASH_REGION_ID id) +{ + uint32_t i; + + for(i = 0; i < sizeof(region_info)/sizeof(AT_FLASH_REGION_INFO); i++) + { + if(region_info[i].id == id) + { + return ®ion_info[i]; + } + } + return NULL; +} + +void at_norflash(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + // uint32_t start_addr = 0; + // uint32_t end_addr = 0; + // uint32_t size = 0; + //uint8_t check_code = 1; + //uint8_t check_free = 1; + //uint8_t check_crash_dump = 1; + //uint8_t check_aud = 1; + //uint8_t check_userdata = 1; + //uint8_t check_factory = 1; + AT_FLASH_REGION_INFO* region_info; + int32_t result = 0; + uint8_t error_code = 0; + cmd_id = cmd_id; + uint32_t lock_pri; + + int idex; + char *p; + + p = (char*)param0; + idex = atoi(p); + + error_code = error_code; + AT_TRACE(0,"_debug:at_norflash begin."); + switch(idex) + { + case 1: + { + AT_TRACE(0,"_debug:at_norflash check code region."); + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_CODE); + AT_TRACE(4,"%s: region_info, id = %d,start = 0x%x,end = 0x%x.", + __func__,region_info->id,region_info->start_addr,region_info->end_addr); + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 1); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 1; + goto _func_fail; + } + break; + } + case 2: + { + AT_TRACE(0,"_debug:at_norflash check free region."); + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_FREE); + AT_TRACE(4,"%s: region_info, id = %d,start = 0x%x,end = 0x%x.", + __func__,region_info->id,region_info->start_addr,region_info->end_addr); + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 0); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 2; + goto _func_fail; + } + break; + } + case 3: + { + AT_TRACE(0,"_debug:at_norflash check crash_dump region."); + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_CRASH_DUMP); + AT_TRACE(4,"%s: region_info, id = %d,start = 0x%x,end = 0x%x.", + __func__,region_info->id,region_info->start_addr,region_info->end_addr); + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 1); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 3; + goto _func_fail; + } + break; + } + case 4: + { + AT_TRACE(0,"_debug:at_norflash check aud region."); + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_AUD); + AT_TRACE(4,"%s: region_info, id = %d,start = 0x%x,end = 0x%x.", + __func__,region_info->id,region_info->start_addr,region_info->end_addr); + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 1); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 4; + goto _func_fail; + } + break; + } + case 5: + { + AT_TRACE(0,"_debug:at_norflash check userdata region."); + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_USERDATA); + AT_TRACE(4,"%s: region_info, id = %d,start = 0x%x,end = 0x%x.", + __func__,region_info->id,region_info->start_addr,region_info->end_addr); + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 1); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 5; + goto _func_fail; + } + break; + } + case 6: + { + AT_TRACE(0,"_debug:at_norflash check factory region."); + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_FACTORY); + AT_TRACE(4,"%s: region_info, id = %d,start = 0x%x,end = 0x%x.", + __func__,region_info->id,region_info->start_addr,region_info->end_addr); + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 1); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 6; + goto _func_fail; + } + break; + } + default: + AT_TRACE(0,"_debug:at_norflash idex default."); + break; + } + //AT_TRACE(0,"_debug: I am at_norflash"); + error_code = 0; + AUTO_TEST_SEND(AT_CMD_RESP_NORFLASH); +_func_fail: + AT_TRACE(1,"_debug:Flash testing fail.error_code = %d.",error_code); + +} + +#if 0 +extern "C" int32_t at_norflash_life_test(uint32_t count) +{ + uint8_t check_free = 1; + uint8_t check_crash_dump = 0; + uint8_t check_aud = 0; + uint8_t check_userdata = 0; + uint8_t check_factory = 0; + AT_FLASH_REGION_INFO* region_info; + int32_t result = 0; + uint8_t error_code = 0; + uint32_t lock_pri; + uint32_t i; + static bool is_first = true; + + error_code = error_code; + //AT_TRACE(0,"at_norflash_life_test begin."); + for(i = 0; i < count; i++) + { + if(check_free) + { + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_FREE); + if(is_first) + { + TRACE(0,"free region"); + TRACE(4,"%s: region_info, id = %d,start_addr = 0x%x,end_addr = 0x%x.", + __func__,region_info->id,region_info->start_addr,region_info->end_addr); + is_first = false; + } + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 0); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 2; + goto _func_fail; + } + } + if(check_crash_dump) + { + TRACE(0,"at_norflash_life_test check crash_dump region."); + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_CRASH_DUMP); + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 1); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 3; + goto _func_fail; + } + } + if(check_aud) + { + TRACE(0,"at_norflash_life_test check aud region."); + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_AUD); + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 1); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 4; + goto _func_fail; + } + } + if(check_userdata) + { + TRACE(0,"at_norflash_life_test check userdata region."); + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_USERDATA); + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 1); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 5; + goto _func_fail; + } + } + if(check_factory) + { + TRACE(0,"at_norflash_life_test check factory region."); + region_info = _at_norflash_get_region_info(FLASH_REGION_ID_FACTORY); + lock_pri = int_lock(); + result = _at_norflash_test(region_info->start_addr, + (region_info->end_addr - region_info->start_addr), + 1); + int_unlock(lock_pri); + if(result != 0) + { + error_code = 6; + goto _func_fail; + } + } + } + error_code = 0; + //TRACE(1,"at_norflash_life_test testing success. erase_count = write_count = %d.",count); + return 0; +_func_fail: + TRACE(1,"at_norflash_life_test testing fail.error_code = %d.",error_code); + return 1; +} + + +void norflash_life_test(void) +{ + uint32_t i; + uint32_t step_count; + int32_t ret; + + step_count = 10; + TRACE(1,"%s: begin.",__func__); + + for(i = 0; i < E_W_COUNT/step_count; i++) + { + ret = at_norflash_life_test(step_count); + if(ret == 0) + { + TRACE(2,"%s: e_w ok! e_w_count = %d.",__func__,(i + 1)*step_count); + } + else + { + TRACE(2,"%s: failed! e_w_count = %d.",__func__,(i + 1)*step_count); + break; + } + osDelay(4); + } + TRACE(1,"%s: done.",__func__); + +} +#endif + +enum NORFLASH_ASYNC_CMD +{ + NORFLASH_ASYNC_CMD_WRITE, + NORFLASH_ASYNC_CMD_ERASE, + NORFLASH_ASYNC_CMD_FLUSH, +}; + +// regin[0]: start = 0x3c000000, end = 0x3c0cf000. -- code + +// regin[1]: start = 0x3c0cf000, end = 0x3c3ed000. -- __crash_dump + +// regin[2]: start = 0x3c3ed000, end = 0x3c3fd000. -- __custom_parameter + +// regin[3]: start = 0x3c3fe000, end = 0x3c3fe000. -- __aud + +// regin[4]: start = 0x3c3fe000, end = 0x3c3ff000. -- __userdata + +// regin[5]: start = 0x3c3ff000, end = 0x3c400000. -- __factory + +enum NORFLASH_ASYNC_STATE +{ + NORFLASH_ASYNC_STATE_INIT, + NORFLASH_ASYNC_STATE_ERASE, + NORFLASH_ASYNC_STATE_WRITTING, + NORFLASH_ASYNC_STATE_WAIT, + NORFLASH_ASYNC_STATE_END, + NORFLASH_ASYNC_STATE_FAILED, +}; + +typedef struct +{ + enum NORFLASH_ASYNC_STATE state; + AT_FLASH_REGION_INFO *region; + enum NORFLASH_API_MODULE_ID_T mod_id; + uint32_t buff_len; + uint32_t e_addr; + uint32_t w_offs; + uint32_t len_index; + uint32_t succ_count; + uint32_t fail_count; + uint32_t tried_count; +}ASYNC_SCENE; + +uint32_t g_at_len[] = {1,255,256,512,1024,2048}; +ASYNC_SCENE at_async_scene[3] = +{ + {NORFLASH_ASYNC_STATE_INIT,®ion_info[FLASH_REGION_ID_FREE],NORFLASH_API_MODULE_ID_FREE,AT_FLASH_SECTOR_SIZE*2,0,0,0,0,0,0}, + {NORFLASH_ASYNC_STATE_INIT,®ion_info[FLASH_REGION_ID_CRASH_DUMP],NORFLASH_API_MODULE_ID_CRASH_DUMP,AT_FLASH_SECTOR_SIZE*2,0,0,0,0,0,0}, + {NORFLASH_ASYNC_STATE_INIT,®ion_info[FLASH_REGION_ID_FACTORY],NORFLASH_API_MODULE_ID_FACTORY,AT_FLASH_SECTOR_SIZE*1,0,0,0,0,0,0} +}; +bool g_at_test_break; +//uint8_t w_buff[AT_FLASH_SECTOR_SIZE]; +//uint8_t r_buff[AT_FLASH_SECTOR_SIZE]; +void at_w_buff_set(uint8_t* buff,uint32_t len) +{ + uint32_t i; + uint8_t val; + + val = 0; + for(i= 0; i < len; i++) + { + buff[i] = val; + val ++; + } +} + +uint32_t at_get_scene_index(uint32_t addr) +{ + uint32_t i; + + for(i = 0; i < 3; i++) + { + if(addr >= at_async_scene[i].region->start_addr + && addr < at_async_scene[i].region->end_addr) + { + return i; + } + } + return i; +} +void at_user_func(uint32_t param0,uint32_t param1); +void at_opera_result_notify(void* param) +{ + NORFLASH_API_OPERA_RESULT *opera_result; + enum NORFLASH_API_RET_T result; + uint32_t offs; + uint32_t index; + uint32_t i; + //enum THREAD_USER_ID user_id; + //uint32_t suspend = 1; + + opera_result = (NORFLASH_API_OPERA_RESULT*)param; + + AT_TRACE(6,"%s:type = %d, addr = 0x%x,len = 0x%x,remain_num = %d,result = %d.", + __func__, + opera_result->type, + opera_result->addr, + opera_result->len, + opera_result->remain_num, + opera_result->result); + // check. + index = at_get_scene_index(opera_result->addr); + ASSERT(index < 3, "%s:at_get_scene_index faile!,addr = 0x%x.",__func__,opera_result->addr); + offs = (opera_result->addr&0xffffff) - ((opera_result->addr&0xffffff)/4096)*4096; + + if(opera_result->remain_num == 0) + { + result = norflash_sync_read(at_async_scene[index].mod_id,opera_result->addr,at_buff_r,opera_result->len); + if(result != NORFLASH_API_OK) + { + ASSERT(0, "%s: hal_norflash_read failed, result = %d",__func__,result); + } + if(opera_result->type == NORFLASH_API_WRITTING) + { + if(memcmp(at_buff_r,at_buff_w + offs,opera_result->len) == 0) + { + AT_TRACE(4,"%s: writting read back check ok.addr = 0x%x,len = 0x%x, offs = 0x%x.", + __func__,opera_result->addr,opera_result->len,offs); + at_async_scene[index].succ_count ++; + } + else + { + uint32_t remain_len; + AT_TRACE(4,"%s: writting read back check failed.addr = 0x%x,len = 0x%x,offs = 0x%x.", + __func__,opera_result->addr,opera_result->len,offs); + for(i = 0; i < opera_result->len/32; i++) + { + DUMP8("0x%02x, ",at_buff_r + i*32,32); + + DUMP8("0x%02x, ",at_buff_w + offs + i*32,32); + } + remain_len = opera_result->len - (opera_result->len/32)*32; + if(remain_len > 0) + { + DUMP8("0x%02x, ",at_buff_r + i*32,remain_len); + + DUMP8("0x%02x, ",at_buff_w + offs + i*32,remain_len); + } + at_async_scene[index].fail_count ++; + } + } + else + { + for(i = 0; i < AT_FLASH_SECTOR_SIZE; i++) + { + if(at_buff_r[i] != 0xff) + { + break; + } + } + if(i == AT_FLASH_SECTOR_SIZE) + { + at_async_scene[index].succ_count ++; + } + else + { + AT_TRACE(1,"%s: erasing operation read back check failed.",__func__); + at_async_scene[index].fail_count ++; + } + } + } + + //user_id = (enum THREAD_USER_ID)index; + //suspend = 1; + //at_thread_user_enqueue_cmd(user_id,0,user_id,suspend,(uint32_t)at_user_func); + +} + +void at_user_func(uint32_t param0,uint32_t param1) +{ + enum NORFLASH_API_RET_T result; + ASYNC_SCENE *pscane; + enum THREAD_USER_ID user_id; + uint32_t suspend = 1; + + user_id = (enum THREAD_USER_ID)param0; + suspend = param1; + pscane = &at_async_scene[user_id]; + pscane->state = NORFLASH_ASYNC_STATE_INIT; + + suspend = suspend; + AT_TRACE(4,"%s,%d:user_id = %d,suspend = %d.",__func__,__LINE__,user_id,suspend); + while(1) + { + if(g_at_test_break || pscane->fail_count > 0) + { + pscane->state = NORFLASH_ASYNC_STATE_END; + break; + } + + if(pscane->state == NORFLASH_ASYNC_STATE_INIT) + { + AT_TRACE(2,"%s,%d,NORFLASH_ASYNC_STATE_INIT",__func__,__LINE__); + pscane->e_addr = pscane->region->start_addr; + pscane->w_offs = 0; + pscane->len_index = 0; + pscane->succ_count = 0; + pscane->fail_count = 0; + pscane->tried_count = 0; + pscane->state = NORFLASH_ASYNC_STATE_ERASE; + } + else if(pscane->state == NORFLASH_ASYNC_STATE_ERASE) + { + if(pscane->e_addr >= pscane->region->end_addr) + { + AT_TRACE(3,"%s,%d: NORFLASH_ASYNC_STATE_ERASE, has arrived to end_addr.addr = 0x%x", + __func__, + __LINE__, + pscane->e_addr); + pscane->state = NORFLASH_ASYNC_STATE_WAIT; + continue; + } + result = norflash_api_erase(pscane->mod_id, + pscane->e_addr, + AT_FLASH_SECTOR_SIZE, + true); + if(result == NORFLASH_API_OK) + { + AT_TRACE(3,"%s,%d: NORFLASH_ASYNC_STATE_ERASE,erase ok!addr = 0x%x", + __func__, + __LINE__, + pscane->e_addr); + pscane->w_offs = 0; + pscane->len_index = 0; + pscane->state = NORFLASH_ASYNC_STATE_WRITTING; + pscane->tried_count = 0; + } + else if(result == NORFLASH_API_BUFFER_FULL) + { + if(pscane->tried_count == 0) + { + AT_TRACE(3,"%s,%d: NORFLASH_ASYNC_STATE_ERASE,too more!addr = 0x%x", + __func__, + __LINE__, + pscane->e_addr); + } + pscane->tried_count++; + norflash_api_flush(); + //osDelay(100); + } + else + { + AT_TRACE(4,"%s,%d: NORFLASH_ASYNC_STATE_ERASE,erase failed!addr = 0x%x,result = %d.", + __func__, + __LINE__, + pscane->e_addr,result); + } + } + else if(pscane->state == NORFLASH_ASYNC_STATE_WRITTING) + { + if(pscane->len_index >= sizeof(g_at_len)/sizeof(g_at_len[0])) + { + AT_TRACE(3,"%s,%d:NORFLASH_ASYNC_STATE_WRITTING,has arrived to sector end. w_offs = 0x%x", + __func__, + __LINE__, + pscane->w_offs); + pscane->e_addr += AT_FLASH_SECTOR_SIZE; + pscane->state = NORFLASH_ASYNC_STATE_ERASE; + continue; + } + + if(norflash_api_get_used_buffer_count(pscane->mod_id,NORFLASH_API_ALL) > 0) + { + norflash_api_flush(); + continue; + } + + result = norflash_api_write(pscane->mod_id, + pscane->e_addr + pscane->w_offs, + at_buff_w + pscane->w_offs, + g_at_len[pscane->len_index], + true); + if(result == NORFLASH_API_OK) + { + AT_TRACE(3,"%s,%d NORFLASH_ASYNC_STATE_WRITTING,norflash_api_write ok!addr = 0x%x", + __func__, + __LINE__, + pscane->e_addr + pscane->w_offs); + pscane->w_offs += g_at_len[pscane->len_index]; + pscane->len_index ++; + pscane->tried_count = 0; + } + else if(result == NORFLASH_API_BUFFER_FULL) + { + + if(pscane->tried_count == 0) + { + AT_TRACE(3,"%s,%d: NORFLASH_ASYNC_STATE_WRITTING, too more!addr = 0x%x", + __func__, + __LINE__, + pscane->e_addr + pscane->w_offs); + } + pscane->tried_count++; + norflash_api_flush(); + //osDelay(100); + } + else + { + AT_TRACE(4,"%s,%d: NORFLASH_ASYNC_STATE_WRITTING writting failed!addr = 0x%x,result = %d.", + __func__, + __LINE__, + pscane->e_addr + pscane->w_offs, + result); + goto _func_fail; + } + } + else if(pscane->state == NORFLASH_ASYNC_STATE_WAIT) + { + //AT_TRACE(2,"%s,%d,NORFLASH_ASYNC_STATE_WAIT",__func__,__LINE__); + if(norflash_api_buffer_is_free(pscane->mod_id)) + { + AT_TRACE(2,"%s,%d: NORFLASH_ASYNC_STATE_WAIT,norflash_api_buffer_is_free is true.", + __func__, + __LINE__); + pscane->state = NORFLASH_ASYNC_STATE_END; + pscane->tried_count = 0; + } + else + { + if(pscane->tried_count == 0) + { + AT_TRACE(2,"%s,%d: NORFLASH_ASYNC_STATE_WAIT,norflash_api_buffer_is_free is false ", + __func__, + __LINE__); + } + pscane->tried_count++; + norflash_api_flush(); + //osDelay(100); + } + } + else if(pscane->state == NORFLASH_ASYNC_STATE_END) + { + AT_TRACE(2,"%s,%d,NORFLASH_ASYNC_STATE_END",__func__,__LINE__); + break; + } + } + AT_TRACE(3,"%s,%d,user_id = %d",__func__,__LINE__,user_id); + return; +_func_fail: + AT_TRACE(2,"%s: norflash_api failed! state = %d.", __func__, pscane->state); + +} + +void at_norflash_async_init(enum THREAD_USER_ID user_id) +{ + ASYNC_SCENE *pscene; + enum NORFLASH_API_RET_T result; + uint32_t sector_size = 0; + uint32_t block_size = 0; + uint32_t page_size = 0; + + ASSERT(user_id < 3,"%s:user_id == %d.",__func__,user_id); + AT_TRACE(3,"%s,%d: user_id = %d.",__func__,__LINE__,user_id); + hal_norflash_get_size(HAL_NORFLASH_ID_0, + NULL, + &block_size, + §or_size, + &page_size); + pscene = &at_async_scene[user_id]; + result = norflash_api_register(pscene->mod_id, + HAL_NORFLASH_ID_0, + pscene->region->start_addr, + pscene->region->end_addr - pscene->region->start_addr, + block_size, + sector_size, + page_size, + pscene->buff_len, + at_opera_result_notify); + ASSERT(result == NORFLASH_API_OK, "%s:user_id == %d,result = %d.",__func__,user_id,(int)result); + +} + +void at_norflash_suspend(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + uint32_t i; + uint32_t start_time; + static bool is_fst = true; + + param0 = param0; + cmd_id = cmd_id; + AT_TRACE(0,"I am at_norflash_suspend"); + g_at_test_break = false; + for(i = 0; i < sizeof(region_info)/sizeof(AT_FLASH_REGION_INFO); i++) + { + AT_TRACE(3,"regin[%d]: start = 0x%x, end = 0x%x.",region_info[i].id,region_info[i].start_addr,region_info[i].end_addr); + + } + if(is_fst) + { + at_w_buff_set(at_buff_w,AT_FLASH_SECTOR_SIZE); + + at_norflash_async_init(THREAD_USER0); + at_norflash_async_init(THREAD_USER1); + // at_norflash_async_init(THREAD_USER2); + is_fst = false; + } + if(!at_thread_user_is_inited(THREAD_USER0)) + { + at_thread_user_init(THREAD_USER0); + } + + if(!at_thread_user_is_inited(THREAD_USER1)) + { + at_thread_user_init(THREAD_USER1); + } + + // if(!at_thread_user_is_inited(THREAD_USER2)) + { + // at_thread_user_init(THREAD_USER2); + } + // param0: user_id + // praram1: suspend + osDelay(100); + at_thread_user_enqueue_cmd(THREAD_USER0,0,THREAD_USER0,1,(uint32_t)at_user_func); + //osDelay(100); + at_thread_user_enqueue_cmd(THREAD_USER1,0,THREAD_USER1,1,(uint32_t)at_user_func); + //osDelay(100); + // at_thread_user_enqueue_cmd(THREAD_USER2,0,THREAD_USER2,1,(uint32_t)at_user_func); + start_time = hal_sys_timer_get(); + while(1) + { + if(TICKS_TO_MS(hal_sys_timer_get() - start_time) >= 1000*60) // timeout 60second + { + AT_TRACE(1,"%s: wait out time!"); + break; + } + if(at_async_scene[0].state == NORFLASH_ASYNC_STATE_END + && at_async_scene[1].state == NORFLASH_ASYNC_STATE_END + ) + { + if(at_async_scene[0].fail_count == 0 + && at_async_scene[1].fail_count == 0 + ) + { + AUTO_TEST_SEND(AT_CMD_RESP_NORFLASH_SUSPEND); + break; + } + else + { + break; + } + } + else if(at_async_scene[0].fail_count > 0 + || at_async_scene[1].fail_count > 0 + ) + { + g_at_test_break = true; + } + else + { + AT_TRACE(2,"%s: is runnig.time = %d(ms).",__func__,TICKS_TO_MS(hal_sys_timer_get() - start_time)); + osDelay(500); + } + + } + +//_func_fail: +// AT_TRACE(1,"_debug:Flash testing fail.error_code = %d.",error_code); + +} + +int32_t _at_memory_test(uint8_t* buff,uint32_t size) +{ + uint8_t value; + uint32_t i; + int32_t ret = 0; + + value = 0; + for(i = 0; i < size; i++) + { + buff[i] = value++; + } + value = 0; + for(i = 0; i < size; i++) + { + if(buff[i] != value++) + { + ret = 2; + goto _func_end; + } + } +_func_end: + return ret; +} + +void at_memory(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + uint8_t *buff; + uint8_t error_code = 1; + int32_t result; + + error_code = error_code; + //AT_TRACE(0,"_debug: I am at_memory"); + buff = (uint8_t*)at_buff_r; + result = _at_memory_test(buff,AT_FLASH_SECTOR_SIZE); + if(result != 0) + { + error_code = 2; + goto _func_fail; + } + + buff = (uint8_t*)at_buff_w; + result = _at_memory_test(buff,AT_FLASH_SECTOR_SIZE); + if(result != 0) + { + error_code = 2; + goto _func_fail; + } + + buff = (uint8_t*)at_buff_b; + result = _at_memory_test(buff,AT_FLASH_SECTOR_SIZE); + if(result != 0) + { + error_code = 3; + goto _func_fail; + } + error_code = 0; + AUTO_TEST_SEND(AT_CMD_RESP_MEMORY); +_func_fail: + AT_TRACE(1,"_debug:Memory testing fail.error_code = %d.",error_code); + +} + +void at_get_mac(uint32_t param0,uint32_t param1) +{ + unsigned char *btd_addr; + + btd_addr = bt_addr; + if(NULL != btd_addr) + { + AT_TRACE(6,"GETMAC_TEST_OK:%x:%x:%x:%x:%x:%x",bt_addr[0],bt_addr[1],bt_addr[2],bt_addr[3],bt_addr[4],bt_addr[5]); + AUTO_TEST_SEND(AT_CMD_RESP_MAC); + } + else + { + AT_TRACE(0,"GETMAC_TEST_NG!"); + AUTO_TEST_SEND(AT_CMD_RESP_ERROR); + } + + return; +} + +void at_get_devicename(uint32_t param0,uint32_t param1) +{ + const char *localname; + + localname = BT_LOCAL_NAME; + if(NULL != localname) + { + AT_TRACE(1,"GETNAME_TEST_OK:%s",localname); + } + else + { + AT_TRACE(0,"GETNAME_TEST_NG!"); + } + + return; +} + +void at_set_loopback(uint32_t param0,uint32_t param1) +{ + int idex; + char *p; + + p = (char*)param0; + idex = atoi(p); + + AT_TRACE(1,"[%s]", __func__); + + switch(idex) + { + case 1: + app_audio_sendrequest(APP_FACTORYMODE_AUDIO_LOOP, (uint8_t)APP_BT_SETTING_OPEN, 0); + AT_TRACE(0,"LOOPBACK_TEST_OPEN!"); + AUTO_TEST_SEND(AT_CMD_RESP_LOOPBACK); + break; + case 2: + app_audio_sendrequest(APP_FACTORYMODE_AUDIO_LOOP, (uint8_t)APP_BT_SETTING_CLOSE, 0); + AT_TRACE(0,"LOOPBACK_TEST_CLOSED!"); + AUTO_TEST_SEND(AT_CMD_RESP_LOOPBACK); + break; + default: + AT_TRACE(1,"LOOPBACK_TEST param error: %s!",idex); + AUTO_TEST_SEND(AT_CMD_RESP_ERROR); + } + + return; +} + +void at_set_led(uint32_t param0,uint32_t param1) +{ + char *p; + p = (char*)param0; + + switch(*p) + { + case 0x31://'1': + AT_TRACE(0,"LED light 1"); + app_status_indication_set(APP_STATUS_INDICATION_CHARGING); + AUTO_TEST_SEND(AT_CMD_RESP_LED); + break; + case 0x32://'2': + AT_TRACE(0,"LED light 2"); + app_status_indication_set(APP_STATUS_INDICATION_FULLCHARGE); + AUTO_TEST_SEND(AT_CMD_RESP_LED); + break; + default: + AT_TRACE(0,"LED light all"); + app_status_indication_set(APP_STATUS_INDICATION_TESTMODE); + AUTO_TEST_SEND(AT_CMD_RESP_LED); + break; + } + + AT_TRACE(0,"SETLED_TEST_OK!"); + return ; +} + +void at_enter_signaling_mode(uint32_t param0,uint32_t param1) +{ + AT_TRACE(1,"%s",__func__); + hal_sw_bootmode_set(HAL_SW_BOOTMODE_TEST_MODE|HAL_SW_BOOTMODE_TEST_SIGNALINGMODE); + app_reset(); +} + +void at_enter_no_signaling_mode(uint32_t param0,uint32_t param1) +{ + AT_TRACE(1,"[%s]", __func__); + + hal_sw_bootmode_set(HAL_SW_BOOTMODE_TEST_MODE|HAL_SW_BOOTMODE_TEST_NOSIGNALINGMODE); + app_reset(); +} + +const uint8_t hci_cmd_nonsig_ble_stop_pn9[] = { 0x01, 0x1f, 0x20, 0x00 }; +const uint8_t hci_cmd_stop_bt_no_signaling_test_configuration[] = { +0x01, 0x87, 0xfc, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +const uint8_t hci_cmd_ble_no_signaling_test_configuration[3][7] = { +// 2402-----INDEX0 tx +{0x01, 0x1e, 0x20, 0x03, 0x00, 0x25, 0x03}, +// 2440-----INDEX1 +{0x01, 0x1e, 0x20, 0x03, 0x13, 0x25, 0x03}, +// 2480-----INDEX2 +{0x01, 0x1e, 0x20, 0x03, 0x27, 0x25, 0x03}, +}; +const uint8_t hci_cmd_ble_rx_no_signaling_test_configuration[3][5] = { +// 2402-----INDEX0 rx +{0x01, 0x1d, 0x20, 0x01, 0x00}, +// 2440-----INDEX1 +{0x01, 0x1d, 0x20, 0x01, 0x13}, +// 2480-----INDEX2 +{0x01, 0x1d, 0x20, 0x01, 0x27}, +}; + +const uint8_t hci_cmd_bt_no_signaling_test_configuration[24][24] = { +// BR DH3, 2402, TX-----INDEX0 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0b, 0x04, 0xB7, 0x00}, +// BR DH3, 2402, RX-----INDEX1 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0b, 0x04, 0xb7, 0x00}, + +// BR DH3, 2441, TX-----INDEX2 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x27, 0x27, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0b, 0x04, 0xB7, 0x00}, +// BR DH3, 2441, RX-----INDEX3 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x27, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0b, 0x04, 0xb7, 0x00}, + +// BR DH3, 2480, TX-----INDEX4 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x4e, 0x4e, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0b, 0x04, 0xB7, 0x00}, +// BR DH3, 2480, RX-----INDEX5 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x4e, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0b, 0x04, 0xb7, 0x00}, + +// BR DH5, 2402, TX-----INDEX6 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0f, 0x04, 0x53, 0x01}, +// BR DH5, 2402, RX-----INDEX7 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0f, 0x04, 0x53, 0x01}, + +// BR DH5, 2441, TX-----INDEX8 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x27, 0x27, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0f, 0x04, 0x53, 0x01}, +// BR DH5, 2441, RX-----INDEX9 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x27, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0f, 0x04, 0x53, 0x01}, + +// BR DH5, 2480, TX-----INDEX10 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x4e, 0x4e, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0f, 0x04, 0x53, 0x01}, +// BR DH5, 2480, RX-----INDEX11 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x4e, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x0f, 0x04, 0x53, 0x01}, + +// BR 2DH5, 2402, TX----INDEX12 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0e, 0x04, 0xa7, 0x02}, +// BR 2DH5, 2402, RX----INDEX13 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0e, 0x04, 0xa7, 0x02}, + +// BR 2DH5, 2441, TX----INDEX14 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x27, 0x27, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0e, 0x04, 0xa7, 0x02}, +// BR 2DH5, 2441, RX----INDEX15 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x27, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0e, 0x04, 0xa7, 0x02}, + +// BR 2DH5, 2480, TX----INDEX16 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x4e, 0x4e, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0e, 0x04, 0xa7, 0x02}, +// BR 2DH5, 2480, RX----INDEX17 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x4e, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0e, 0x04, 0xa7, 0x02}, + +// BR 3DH5, 2402, TX----INDEX18 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0f, 0x04, 0xfd, 0x03}, +// BR 3DH5, 2402, RX----INDEX19 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0f, 0x04, 0xfd, 0x03}, + +// BR 3DH5, 2441, TX----INDEX20 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x27, 0x27, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0f, 0x04, 0xfd, 0x03}, +// BR 3DH5, 2441, RX----INDEX21 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x27, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0f, 0x04, 0xfd, 0x03}, + +// BR 3DH5, 2480, TX----INDEX22 +{0x01, 0x87, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x4e, 0x4e, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0f, 0x04, 0xfd, 0x03}, +// BR 3DH5, 2480, RX----INDEX23 +{0x01, 0x87, 0xfc, 0x14, 0x01, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x4e, 0x02, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x0f, 0x04, 0xfd, 0x03}, +}; + +static const uint8_t hci_cmd_nonsig_tx_dh1_pn9[] = +{ + 0x01, 0x60, 0xfc, 0x14, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x04, 0x04, 0x1b, 0x00 +}; + +void BleFrequencyTestStop() +{ + btdrv_SendData(hci_cmd_nonsig_ble_stop_pn9, sizeof(hci_cmd_nonsig_ble_stop_pn9)); +} +void BtFrequencyTestStop() +{ + btdrv_SendData(hci_cmd_stop_bt_no_signaling_test_configuration, sizeof(hci_cmd_stop_bt_no_signaling_test_configuration)); +} + +void BleFrequencyTestStart(uint8_t index) +{ + TRACE(2,"[%s] index is %d", __func__, index); + + btdrv_SendData(hci_cmd_ble_no_signaling_test_configuration[index], sizeof(hci_cmd_ble_no_signaling_test_configuration[0])); +} +void BleFrequencyTestStartRx(uint8_t index) +{ + TRACE(2,"[%s] index is %d", __func__, index); + + btdrv_SendData(hci_cmd_ble_rx_no_signaling_test_configuration[index], sizeof(hci_cmd_ble_rx_no_signaling_test_configuration[0])); +} +void BtFrequencyTestStart(uint8_t index) +{ + + TRACE(2,"[%s] index is %d", __func__, index); + if (index < sizeof(hci_cmd_bt_no_signaling_test_configuration)/sizeof(hci_cmd_bt_no_signaling_test_configuration[0])) + { + btdrv_SendData(hci_cmd_bt_no_signaling_test_configuration[index], sizeof(hci_cmd_bt_no_signaling_test_configuration[0])); + } + else + { + btdrv_SendData(hci_cmd_nonsig_tx_dh1_pn9, sizeof(hci_cmd_nonsig_tx_dh1_pn9)); + } +} + +void at_no_signaling_ble_test(uint32_t param0,uint32_t param1) +{ + AT_TRACE(1,"[%s]", __func__); + + char *p; + p = (char*)param0; + + switch(*p) + { + case RF_CHANNEL_BLE_STOP: + { + BleFrequencyTestStop(); + break; + } + case RF_FREQUENCY_2402: + { + BleFrequencyTestStart(0); + break; + } + case RF_FREQUENCY_2440: + { + BleFrequencyTestStart(1); + break; + } + case RF_FREQUENCY_2480: + { + BleFrequencyTestStart(2); + break; + } + case RF_FREQUENCY_2402_RX: + { + BleFrequencyTestStartRx(0); + break; + } + case RF_FREQUENCY_2440_RX: + { + BleFrequencyTestStartRx(1); + break; + } + case RF_FREQUENCY_2480_RX: + { + BleFrequencyTestStartRx(2); + break; + } + default: + break; + + } + + return; +} + +void at_no_signaling_bt_test(uint32_t param0,uint32_t param1) +{ + AT_TRACE(1,"[%s]", __func__); + + int idex; + char *p; + + p = (char*)param0; + idex = atoi(p); + BtFrequencyTestStart(idex); + + return; +} + +void at_get_battery(uint32_t param0,uint32_t param1) +{ + AT_TRACE(1,"[%s]", __func__); + + uint16_t batteryInfo = 0; + int getstatus = app_battery_get_info( &batteryInfo,NULL, NULL); + if(getstatus) + { + AUTO_TEST_SEND(AT_CMD_RESP_ERROR); + } + else + { + AT_TRACE(1,"battery voltage:%d mV",batteryInfo); + AUTO_TEST_SEND(AT_CMD_RESP_BATTERY); + } + return; +} + +void at_set_volume(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + int idex; + char *p; + + AT_TRACE(0,"_debug: I at_set_volume"); + + p = (char*)param0; + idex = atoi(p); + AT_TRACE(1,"_debug: volume set: %d",idex); + + if(idex > TGT_VOLUME_LEVEL_15 ) + { + idex = 17; + } + if(idex < TGT_VOLUME_LEVEL_MUTE ) + { + idex = 1; + } + + //app_bt_set_volume(APP_BT_STREAM_HFP_PCM,idex); + app_bt_set_volume(APP_BT_STREAM_A2DP_SBC,idex); + //btapp_hfp_report_speak_gain(); + btapp_a2dp_report_speak_gain(); + + _at_resp(); + return; +} + +void at_get_fwversion(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + uint8_t fw_rev[4]; + + AT_TRACE(0,"_debug: I at_get_fwversion"); + + system_get_fwversion(&fw_rev[0], &fw_rev[1], &fw_rev[2], &fw_rev[3]); + AT_TRACE(4,"_debug: FwVersion: %d.%d.%d.%d",fw_rev[0], fw_rev[1], fw_rev[2], fw_rev[3]); + AUTO_TEST_SEND(AT_CMD_RESP_FWVER); + + _at_resp(); + return; +} + +void at_get_bootmode(uint32_t param0,uint32_t param1) +{ + AT_CMD_ID_ENUM_T cmd_id = (AT_CMD_ID_ENUM_T)param1; + cmd_id = cmd_id; + uint32_t bootmode; + + AT_TRACE(0,"_debug: I at_get_bootmode"); + + bootmode = hal_sw_bootmode_get(); + AT_TRACE(1,"_debug: bootmode: 0x%x.",bootmode); + AUTO_TEST_SEND(AT_CMD_RESP_BOOTMODE); + + _at_resp(); + return; +} + +int32_t at_Init(void) +{ + int32_t ret; + + AT_TRACE(0,"at_Init."); + ret = at_os_init(); + return ret; +} +#endif// (_AUTO_TEST_) + + diff --git a/services/ble_app/Makefile b/services/ble_app/Makefile new file mode 100644 index 0000000..49c6dca --- /dev/null +++ b/services/ble_app/Makefile @@ -0,0 +1,156 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + + +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_main/*.c)) +ifneq ($(__BES_OTA_MODE__),1) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_htp/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_datapath/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_hrps/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_hid/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_sec/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_batt/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_voice/app_$(VOICE_DATAPATH_TYPE)/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_ota/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_ancc/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_amsc/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_gfps/*.c)) +ifneq ($(VOICE_DATAPATH_TYPE), ) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)app_voice/*.c)) +endif +endif + +ifeq ($(TEST_OVER_THE_AIR),1) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)/app_tota/*.c)) +subdir-ccflags-y += \ + -Iservices/tota/ \ + -Iservices/ble_profiles/tota/\ + -Iservices/ble_app/app_tota/ +endif + +obj-y := $(obj_c:.c=.o) + +subdir-ccflags-y += \ + -Iservices/audio_process \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + $(BT_IF_INCLUDES) \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iservices/voicepath/ \ + -Iservices/voicepath/$(VOICE_DATAPATH_TYPE) \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/retention_ram \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iutils/heap \ + -Iutils/crc16 \ + -Iapps/battery \ + -Iapps/key \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/factory \ + -Iservices/ble_app \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/bridge/ \ + -Iservices/ble_stack/hl/src/gap/ \ + -Iservices/ble_stack/hl/src/gap/gapc/ \ + -Iservices/ble_stack/hl/src/gap/gapm/ \ + -Iservices/ble_stack/hl/src/gap/smpc/ \ + -Iservices/ble_stack/ke/src/ \ + -Iservices/ble_stack/hl/src/gatt/attc/ \ + -Iservices/ble_stack/hl/src/gatt/attm/ \ + -Iservices/ble_stack/hl/src/gatt/atts/ \ + -Iservices/ble_stack/hl/src/gatt/gattc/ \ + -Iservices/ble_stack/hl/src/gatt/gattm/ \ + -Iservices/ble_stack/hl/src/gatt/ \ + -Iservices/ble_stack/hl/src/l2c/l2cc/ \ + -Iservices/ble_stack/hl/src/l2c/l2cm/ \ + -Iservices/ble_stack/hci/api/ \ + -Iservices/ble_stack/hci/src/ \ + -Iservices/ble_stack/app/src/ \ + -Iservices/ble_profiles/htp/htpt/api/ \ + -Iservices/ble_profiles/htp/htpt/src/ \ + -Iservices/ble_profiles/htp/ \ + -Iservices/ble_profiles/datapath/datapathps/api/ \ + -Iservices/ble_app/app_main/ \ + -Iservices/ble_app/app_htp/ \ + -Iservices/ble_app/app_datapath/ \ + -Iservices/ble_app/app_hrps/ \ + -Iservices/ble_profiles/hrp/hrps/api/ \ + -Iservices/ble_profiles/hrp/hrps/src \ + -Iservices/ble_profiles/hrp/ \ + -Iservices/ble_app/app_sec/ \ + -Iservices/ble_app/app_batt/ \ + -Iservices/ble_app/app_hid/ \ + -Iservices/ble_app/app_gfps/ \ + -Iservices/ble_profiles/gfps/gfps_provider/api/ \ + -Iservices/ble_profiles/gfps/api/ \ + -Iservices/ble_profiles/bas/bass/api/ \ + -Iservices/ble_profiles/hogp/hogpd/api/ \ + -Iservices/ble_profiles/hogp/ \ + -Iservices/multimedia/speech/inc \ + -Iservices/ble_app/app_voice \ + -Iservices/ble_profiles/voicepath/$(VOICE_DATAPATH_TYPE)/ \ + -Iservices/ble_app/app_voice/app_$(VOICE_DATAPATH_TYPE)/ \ + -Iservices/ble_profiles/ota \ + -Iservices/ble_app/app_ota \ + -Iservices/ble_profiles/anc/\ + -Iservices/ble_profiles/anc/ancc/\ + -Iservices/ble_app/app_ancc/ \ + -Iservices/ble_profiles/ams/\ + -Iservices/ble_profiles/ams/amsc/\ + -Iservices/ble_app/app_amsc/ \ + -Iservices/bt_app \ + -Iservices/voicepath/gsound/gsound_custom/inc \ + -Iservices/voicepath/gsound/gsound_custom/src \ + -Iservices/voicepath/gsound/gsound_target_api_read_only \ + -Iservices/ai_voice/manager \ + -Iservices/ai_voice/transport \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/app_tws/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/ibrt_core/inc \ + -Iservices/app_ibrt/inc \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/ble_profiles/tile \ + -Ithirdparty/tile \ + -Ithirdparty/tile/tile_target \ + -Ithirdparty/tile/tile_common/tile_assert \ + -Ithirdparty/tile/tile_common/tile_features \ + -Ithirdparty/tile/tile_common/tile_gatt_db \ + -Ithirdparty/tile/tile_common/tile_player \ + -Ithirdparty/tile/tile_common/tile_service \ + -Ithirdparty/tile/tile_common/tile_storage \ + -Iservices/voicepath/gsound/gsound_target + +ifeq ($(AUDIO_RESAMPLE),1) +CFLAGS_voice_over_ble.o += -D__AUDIO_RESAMPLE__ +endif +ifeq ($(SW_PLAYBACK_RESAMPLE),1) +CFLAGS_voice_over_ble.o += -DSW_PLAYBACK_RESAMPLE +endif +ifeq ($(SW_CAPTURE_RESAMPLE),1) +CFLAGS_voice_over_ble.o += -DSW_CAPTURE_RESAMPLE +endif +ifeq ($(OTA_ENABLE),1) +ifeq ($(IBRT),1) +ccflags-y += -Iservices/ibrt_ota/inc +else +ccflags-y += -Iservices/ota +endif +endif + diff --git a/services/ble_app/app_amsc/app_amsc.c b/services/ble_app/app_amsc/app_amsc.c new file mode 100644 index 0000000..001e702 --- /dev/null +++ b/services/ble_app/app_amsc/app_amsc.c @@ -0,0 +1,96 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_APP_PRESENT) +#if (BLE_AMS_CLIENT) + +#include "app_amsc.h" // Health Thermometer Application Definitions +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "amsc_task.h" // health thermometer functions +#include "co_bt.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "arch.h" // Platform Definitions + +#include "co_math.h" +#include "ke_timer.h" + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** +*/ + +void app_amsc_add_amsc(void) +{ + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, TASK_APP, + gapm_profile_task_add_cmd, 0); + + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX>1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE)|PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + req->prf_task_id = TASK_ID_AMSC; + req->app_task = TASK_APP; + req->start_hdl = 0; + + // Send the message + ke_msg_send(req); +} + +/** + **************************************************************************************** + * @brief Initialize application and enable AMSC profile. + * + **************************************************************************************** + */ +void app_amsc_enable(uint8_t conidx) +{ + // Allocate the message + struct amsc_enable_req * req = KE_MSG_ALLOC(AMSC_ENABLE_REQ, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_AMSC), conidx), TASK_APP, + amsc_enable_req); + + // Fill in the parameter structure + req->conidx = conidx; + + // Send the message + ke_msg_send(req); +} + +#endif //BLE_AMS_CLIENT +#endif //BLE_APP_PRESENT + +/// @} APP diff --git a/services/ble_app/app_amsc/app_amsc.h b/services/ble_app/app_amsc/app_amsc.h new file mode 100644 index 0000000..617cc7b --- /dev/null +++ b/services/ble_app/app_amsc/app_amsc.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef APP_AMSC_H_ +#define APP_AMSC_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * + * @brief AMSC Application entry point. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#if BLE_AMS_CLIENT +#include "amsc.h" + +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "co_bt.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "arch.h" // Platform Definitions +#include "prf.h" +#include "string.h" + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * + * AMSC Application Functions + * + **************************************************************************************** + */ + +void app_amsc_add_amsc(void); + +/** + **************************************************************************************** + * @brief Inialize application and enable AMSC profile. + * + **************************************************************************************** + */ +void app_amsc_enable(uint8_t conidx); + +#endif //BLE_AMS_CLIENT + +/// @} APP + +#endif // APP_AMSC_H_ diff --git a/services/ble_app/app_amsc/app_amsc_task.c b/services/ble_app/app_amsc/app_amsc_task.c new file mode 100644 index 0000000..e02bba6 --- /dev/null +++ b/services/ble_app/app_amsc/app_amsc_task.c @@ -0,0 +1,82 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +/** + **************************************************************************************** + * @addtogroup APPTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_PRESENT) + +#if (BLE_AMS_CLIENT) + +#include "app_amsc.h" +#include "app_amsc_task.h" +#include "app_task.h" // Application Task API +#include "app_sec.h" +#include "ke_msg.h" + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles AMS Eable reponse + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ + +int amsc_anc_enable_rsp_handler(ke_msg_id_t const msgid, + struct amsc_enable_rsp const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + return (KE_MSG_CONSUMED); +} + +/// Default State handlers definition +const struct ke_msg_handler app_amsc_msg_handler_list[] = +{ + {AMSC_ENABLE_RSP, (ke_msg_func_t)amsc_anc_enable_rsp_handler}, +}; + +const struct ke_state_handler app_amsc_table_handler = + {&app_amsc_msg_handler_list[0], (sizeof(app_amsc_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif //BLE_AMS_CLIENT + +#endif //(BLE_APP_PRESENT) + +/// @} APPTASK diff --git a/services/ble_app/app_amsc/app_amsc_task.h b/services/ble_app/app_amsc/app_amsc_task.h new file mode 100644 index 0000000..dfc8c11 --- /dev/null +++ b/services/ble_app/app_amsc/app_amsc_task.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#include "rwip_config.h" + +#ifndef APP_AMSC_TASK_H_ +#define APP_AMSC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * + * @brief + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#if BLE_AMS_CLIENT + +#include "amsc_task.h" + +/// Table of message handlers +extern const struct ke_state_handler app_amsc_table_handler; + +#endif //BLE_AMS_CLIENT + +/// @} APP + +#endif // APP_AMSC_TASK_H_ diff --git a/services/ble_app/app_ancc/app_ancc.c b/services/ble_app/app_ancc/app_ancc.c new file mode 100644 index 0000000..f7996b7 --- /dev/null +++ b/services/ble_app/app_ancc/app_ancc.c @@ -0,0 +1,103 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_APP_PRESENT) +#if (BLE_ANC_CLIENT) + +#include "app_ancc.h" // Health Thermometer Application Definitions +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "ancc_task.h" // health thermometer functions +#include "co_bt.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "arch.h" // Platform Definitions + +#include "co_math.h" +#include "ke_timer.h" + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** +*/ + +void app_ancc_add_ancc(void) +{ + BLE_APP_DBG("app_ancc_add_ancc"); + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, + TASK_APP, + gapm_profile_task_add_cmd, + 0); + + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX > 1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE) | PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + + req->prf_task_id = TASK_ID_ANCC; + req->app_task = TASK_APP; + req->start_hdl = 0; + + // Send the message + ke_msg_send(req); +} + +/** + **************************************************************************************** + * @brief Initialize application and enable ANCC profile. + * + **************************************************************************************** + */ +void app_ancc_enable(uint8_t conidx) +{ + BLE_FUNC_ENTER(); + + // Allocate the message + struct ancc_enable_req *req = KE_MSG_ALLOC(ANCC_ENABLE_REQ, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_ANCC), conidx), + TASK_APP, + ancc_enable_req); + + // Fill in the parameter structure + + req->conidx = conidx; + + // Send the message + ke_msg_send(req); +} + +#endif //BLE_ANC_CLIENT +#endif //BLE_APP_PRESENT + +/// @} APP diff --git a/services/ble_app/app_ancc/app_ancc.h b/services/ble_app/app_ancc/app_ancc.h new file mode 100644 index 0000000..7ba430f --- /dev/null +++ b/services/ble_app/app_ancc/app_ancc.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef APP_ANCC_H_ +#define APP_ANCC_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * + * @brief ANCC Application entry point. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#if BLE_ANC_CLIENT +#include "ancc.h" + +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "co_bt.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "arch.h" // Platform Definitions +#include "prf.h" +#include "string.h" + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * + * ANCC Application Functions + * + **************************************************************************************** + */ + +void app_ancc_add_ancc(void); + +/** + **************************************************************************************** + * @brief Inialize application and enable ANCC profile. + * + **************************************************************************************** + */ +void app_ancc_enable(uint8_t conidx); + +#endif //BLE_ANC_CLIENT + +/// @} APP + +#endif // APP_ANCC_H_ diff --git a/services/ble_app/app_ancc/app_ancc_task.c b/services/ble_app/app_ancc/app_ancc_task.c new file mode 100644 index 0000000..824c2b9 --- /dev/null +++ b/services/ble_app/app_ancc/app_ancc_task.c @@ -0,0 +1,82 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +/** + **************************************************************************************** + * @addtogroup APPTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_PRESENT) + +#if (BLE_ANC_CLIENT) + +#include "app_ancc.h" +#include "app_ancc_task.h" +#include "app_task.h" // Application Task API +#include "app_sec.h" + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles ANCS Enable response + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ + +int ancc_anc_enable_rsp_handler(ke_msg_id_t const msgid, + struct ancc_enable_rsp const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + + return (KE_MSG_CONSUMED); +} + +/// Default State handlers definition +const struct ke_msg_handler app_ancc_msg_handler_list[] = +{ + {ANCC_ENABLE_RSP, (ke_msg_func_t)ancc_anc_enable_rsp_handler}, +}; + +const struct ke_state_handler app_ancc_table_handler = + {&app_ancc_msg_handler_list[0], (sizeof(app_ancc_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif //BLE_ANC_CLIENT + +#endif //(BLE_APP_PRESENT) + +/// @} APPTASK diff --git a/services/ble_app/app_ancc/app_ancc_task.h b/services/ble_app/app_ancc/app_ancc_task.h new file mode 100644 index 0000000..857faa0 --- /dev/null +++ b/services/ble_app/app_ancc/app_ancc_task.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#include "rwip_config.h" + +#ifndef APP_ANCC_TASK_H_ +#define APP_ANCC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * + * @brief + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#if BLE_ANC_CLIENT + +#include "ancc_task.h" + +/// Table of message handlers +extern const struct ke_state_handler app_ancc_table_handler; + +#endif //BLE_ANC_CLIENT + +/// @} APP + +#endif // APP_ANCC_TASK_H_ diff --git a/services/ble_app/app_batt/app_batt.c b/services/ble_app/app_batt/app_batt.c new file mode 100644 index 0000000..0f26a7c --- /dev/null +++ b/services/ble_app/app_batt/app_batt.c @@ -0,0 +1,205 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_BATT) + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "app_batt.h" // Battery Application Module Definitions +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "bass_task.h" // health thermometer functions +#include "co_bt.h" +#include "prf_types.h" // Profile common types definition +#include "arch.h" // Platform Definitions +#include "prf.h" +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Battery Application Module Environment Structure +struct app_batt_env_tag app_batt_env; + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +void app_batt_init(void) +{ + // Reset the environment + memset(&app_batt_env, 0, sizeof(struct app_batt_env_tag)); + + // Initial battery level: 100 + app_batt_env.batt_lvl = 100; +} + +void app_batt_add_bas(void) +{ + struct bass_db_cfg* db_cfg; + // Allocate the BASS_CREATE_DB_REQ + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, TASK_APP, + gapm_profile_task_add_cmd, sizeof(struct bass_db_cfg)); + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX>1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE)|PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + + req->prf_task_id = TASK_ID_BASS; + req->app_task = TASK_APP; + req->start_hdl = 0; + + // Set parameters + db_cfg = (struct bass_db_cfg* ) req->param; + + // Add a BAS instance + db_cfg->bas_nb = 1; + // Sending of notifications is supported + db_cfg->features[0] = BAS_BATT_LVL_NTF_SUP; + + // Send the message + ke_msg_send(req); +} + +void app_batt_enable_prf(uint8_t conidx) +{ + app_batt_env.conidx = conidx; + + // Allocate the message + struct bass_enable_req * req = KE_MSG_ALLOC(BASS_ENABLE_REQ, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_BASS), conidx), + TASK_APP, + bass_enable_req); + + // Fill in the parameter structure + req->conidx = conidx; + + // NTF initial status - Disabled + req->ntf_cfg = PRF_CLI_STOP_NTFIND; + req->old_batt_lvl[0] = 50; + + // Send the message + ke_msg_send(req); +} + +void app_batt_send_lvl(uint8_t conidx, uint8_t batt_lvl) +{ + ASSERT_ERR(batt_lvl <= BAS_BATTERY_LVL_MAX); + + // Allocate the message + struct bass_batt_level_upd_req * req = KE_MSG_ALLOC(BASS_BATT_LEVEL_UPD_REQ, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_BASS), conidx), + TASK_APP, + bass_batt_level_upd_req); + + // Fill in the parameter structure + req->bas_instance = 0; + req->batt_level = batt_lvl; + + // Send the message + ke_msg_send(req); +} + +static int bass_batt_level_ntf_cfg_ind_handler(ke_msg_id_t const msgid, + struct bass_batt_level_ntf_cfg_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + return (KE_MSG_CONSUMED); +} + +static int batt_level_upd_handler(ke_msg_id_t const msgid, + struct bass_batt_level_upd_rsp const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + return (KE_MSG_CONSUMED); +} + + +static int bass_enable_rsp_handler(ke_msg_id_t const msgid, + struct bass_enable_rsp const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int app_batt_msg_dflt_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Drop the message + + return (KE_MSG_CONSUMED); +} + +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +const struct ke_msg_handler app_batt_msg_handler_list[] = +{ + // Note: first message is latest message checked by kernel so default is put on top. + {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_batt_msg_dflt_handler}, + {BASS_BATT_LEVEL_NTF_CFG_IND, (ke_msg_func_t)bass_batt_level_ntf_cfg_ind_handler}, + {BASS_BATT_LEVEL_UPD_RSP, (ke_msg_func_t)batt_level_upd_handler}, +}; + +const struct ke_state_handler app_batt_table_handler = + {&app_batt_msg_handler_list[0], (sizeof(app_batt_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif //BLE_APP_BATT + +/// @} APP diff --git a/services/ble_app/app_batt/app_batt.h b/services/ble_app/app_batt/app_batt.h new file mode 100644 index 0000000..4c927a5 --- /dev/null +++ b/services/ble_app/app_batt/app_batt.h @@ -0,0 +1,112 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef APP_BATT_H_ +#define APP_BATT_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * @ingroup RICOW + * + * @brief Battery Application Module entry point + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_BATT) + +#include // Standard Integer Definition +#include "ke_task.h" // Kernel Task Definition + +/* + * STRUCTURES DEFINITION + **************************************************************************************** + */ + +/// Battery Application Module Environment Structure +struct app_batt_env_tag +{ + /// Connection handle + uint8_t conidx; + /// Current Battery Level + uint8_t batt_lvl; +}; + +/* + * GLOBAL VARIABLES DECLARATIONS + **************************************************************************************** + */ + +/// Battery Application environment +extern struct app_batt_env_tag app_batt_env; + +/// Table of message handlers +extern const struct ke_state_handler app_batt_table_handler; + +/* + * FUNCTIONS DECLARATION + **************************************************************************************** + */ + +/** + **************************************************************************************** + * + * Health Thermometer Application Functions + * + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialize Battery Application Module + **************************************************************************************** + */ +void app_batt_init(void); + +/** + **************************************************************************************** + * @brief Add a Battery Service instance in the DB + **************************************************************************************** + */ +void app_batt_add_bas(void); + +/** + **************************************************************************************** + * @brief Enable the Battery Service + **************************************************************************************** + */ +void app_batt_enable_prf(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Send a Battery level value + **************************************************************************************** + */ +void app_batt_send_lvl(uint8_t conidx, uint8_t batt_lvl); + +#endif //(BLE_APP_BATT) + +/// @} APP + +#endif // APP_BATT_H_ diff --git a/services/ble_app/app_ble_key.cpp b/services/ble_app/app_ble_key.cpp new file mode 100644 index 0000000..69b4603 --- /dev/null +++ b/services/ble_app/app_ble_key.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include +#include +#include "app_key.h" +#include "hal_trace.h" + +#define TEST_KEY_UP HAL_KEY_CODE_FN3 +#define TEST_KEY_DOWN HAL_KEY_CODE_FN4 + +#define TEST_KEY_UP_VALUE 0x12 +#define TEST_KEY_DOWN_VALUE 0x34 + +extern void register_ble_key_handle_cb(void (*cb)(APP_KEY_STATUS)); + +extern "C" { + extern void app_ble_key_notify(uint8_t len, uint8_t* value); +} + +void app_ble_key_handle(APP_KEY_STATUS ble_key); + +uint32_t app_ble_key_init() +{ + register_ble_key_handle_cb(app_ble_key_handle); +} + +void ble_key_handle_up_key(enum APP_KEY_EVENT_T event) +{ + uint8_t value = TEST_KEY_UP_VALUE; + switch(event) { + case APP_KEY_EVENT_UP: + app_ble_key_notify(sizeof(value), &value); + break; + case APP_KEY_EVENT_CLICK: + //app_ble_key_notify(sizeof(value), &value); + break; + case APP_KEY_EVENT_DOUBLECLICK: + break; + default: + TRACE(1,"unregister up key event=%x",event); + } +} + +void ble_key_handle_down_key(enum APP_KEY_EVENT_T event) +{ + uint8_t value = TEST_KEY_DOWN_VALUE; + switch(event) { + case APP_KEY_EVENT_UP: + app_ble_key_notify(sizeof(value), &value); + break; + case APP_KEY_EVENT_CLICK: + //app_ble_key_notify(sizeof(value), &value); + break; + case APP_KEY_EVENT_DOUBLECLICK: + break; + default: + TRACE(1,"unregister up key event=%x",event); + } +} + +void app_ble_key_handle(APP_KEY_STATUS ble_key) +{ + if(ble_key.code != 0xff) { + TRACE(2,"app_ble_key_handle code:%x event:%x",ble_key.code, ble_key.event); + switch (ble_key.code) { + case TEST_KEY_UP: + ble_key_handle_up_key((enum APP_KEY_EVENT_T)ble_key.event); + break; + case TEST_KEY_DOWN: + ble_key_handle_down_key((enum APP_KEY_EVENT_T)ble_key.event); + break; + default: + TRACE(0,"app_ble_key_handle undefined key"); + break; + } + } +} diff --git a/services/ble_app/app_ble_uart.cpp b/services/ble_app/app_ble_uart.cpp new file mode 100644 index 0000000..5160226 --- /dev/null +++ b/services/ble_app/app_ble_uart.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +//#include "mbed.h" +#include +#include +#include +#include "hal_uart.h" +#include "hal_trace.h" + +#define APP_BLE_UART_BUFF_SIZE 50 //16 + +enum HAL_UART_ID_T app_ble_uart_id = HAL_UART_ID_0; + +extern "C" { +typedef void (*GATT_UART_HANDLER_T)(uint8_t *buf, uint32_t len); +extern void gatt_uart_register_write_request_cb(GATT_UART_HANDLER_T handler); +extern int gatt_uart_write(uint8_t *buffer, uint32_t length); +extern int gatt_loop_write(uint8_t *buffer, uint32_t length); +} + +static uint32_t app_ble_debug_cnt = 0; + +void app_ble_send_data(uint8_t *buffer, uint32_t length) +{ + TRACE(1,"[%s]", __func__); + gatt_uart_write(buffer, length); +// gatt_loop_write(buffer, length); +} + +typedef struct +{ + volatile bool rx_done; + volatile bool tx_done; + uint8_t rx_data[APP_BLE_UART_BUFF_SIZE]; + uint32_t rx_len; +} app_ble_uart_t; + +app_ble_uart_t app_ble_uart; + +static void uart_rx(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status) +{ + app_ble_debug_cnt = 4; + if (dma_error) { +// TRACE(1,"uart_rx dma error: xfer_size=%d", xfer_size); + app_ble_debug_cnt = 0xfe; + app_ble_uart.rx_len = 0; + } else if (status.BE || status.FE || status.OE || status.PE) { +// TRACE(2,"uart_rx uart error: xfer_size=%d, status=0x%08x", xfer_size, status.reg); + app_ble_debug_cnt = 0xfd; + app_ble_uart.rx_len = 0; + } else { + app_ble_debug_cnt = 0xfc; + app_ble_uart.rx_len = xfer_size; +// hal_uart_dma_recv(app_ble_uart_id, app_ble_uart.rx_data, app_ble_uart.rx_len - 5, NULL, NULL); +// gatt_uart_write(app_ble_uart.rx_data, app_ble_uart.rx_len - 5); + +// hal_uart_dma_recv(app_ble_uart_id, app_ble_uart.rx_data, 5, NULL, NULL); +// gatt_uart_write(app_ble_uart.rx_data, 5); + + hal_uart_dma_recv(app_ble_uart_id, app_ble_uart.rx_data, sizeof(app_ble_uart.rx_data), NULL, NULL); +// //hal_uart_dma_send(app_ble_uart_id, app_ble_uart.rx_data, app_ble_uart.rx_len, NULL, NULL); + gatt_uart_write(app_ble_uart.rx_data, app_ble_uart.rx_len); + } + + app_ble_uart.rx_done = true; +} + +static void uart_tx(uint32_t xfer_size, int dma_error) +{ + if (dma_error) + { +// TRACE(1,"uart_tx dma error: xfer_size=%d", xfer_size); + app_ble_debug_cnt = 0xfb; + } + app_ble_uart.tx_done = true; +} + +void app_ble_uart_write_request_cb(uint8_t *buf, uint32_t len) +{ + //send data over uart. + hal_uart_dma_send(app_ble_uart_id, buf, len, NULL, NULL); + //DUMP8("%x ", buf, len); + +} + +uint32_t app_ble_uart_open() +{ +#if 1 + int ret; + union HAL_UART_IRQ_T mask; + + struct HAL_UART_CFG_T uart_cfg; + + uart_cfg.parity = HAL_UART_PARITY_NONE, + uart_cfg.stop = HAL_UART_STOP_BITS_1, + uart_cfg.data = HAL_UART_DATA_BITS_8, + uart_cfg.flow = HAL_UART_FLOW_CONTROL_NONE, + uart_cfg.tx_level = HAL_UART_FIFO_LEVEL_1_2, + uart_cfg.rx_level = HAL_UART_FIFO_LEVEL_1_4, + uart_cfg.baud = 115200, + uart_cfg.dma_rx = true, + uart_cfg.dma_tx = true, + uart_cfg.dma_rx_stop_on_err = false; + + app_ble_debug_cnt = 1; + + ret = hal_uart_open(app_ble_uart_id, &uart_cfg); + if (ret) { + app_ble_debug_cnt = 0xff; +// TRACE(0,"Failed to open uart"); + return 1; + } + + app_ble_debug_cnt = 2; + hal_uart_irq_set_dma_handler(app_ble_uart_id, uart_rx, uart_tx); +// hal_uart_dma_recv(app_ble_uart_id, app_ble_uart.rx_data, sizeof(app_ble_uart.rx_data), NULL, NULL); + mask.reg = 0; + mask.BE = 1; + mask.FE = 1; + mask.OE = 1; + mask.PE = 1; + mask.RT = 1; + hal_uart_irq_set_mask(app_ble_uart_id, mask); + app_ble_debug_cnt = 3; + + app_ble_uart.rx_done = false; + app_ble_uart.tx_done = false; +#endif + gatt_uart_register_write_request_cb(app_ble_uart_write_request_cb); + return 0; +} diff --git a/services/ble_app/app_ble_uart.h b/services/ble_app/app_ble_uart.h new file mode 100644 index 0000000..d6d3820 --- /dev/null +++ b/services/ble_app/app_ble_uart.h @@ -0,0 +1,22 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BLE_UART_H__ +#define __APP_BLE_UART_H__ + +uint32_t app_ble_uart_open(); + + +#endif diff --git a/services/ble_app/app_datapath/app_ble_cmd_handler.c b/services/ble_app/app_datapath/app_ble_cmd_handler.c new file mode 100644 index 0000000..8f25f08 --- /dev/null +++ b/services/ble_app/app_datapath/app_ble_cmd_handler.c @@ -0,0 +1,583 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "string.h" +#include "bluetooth.h" +#include "cmsis_os.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "apps.h" +#include "stdbool.h" +#include "app_ble_cmd_handler.h" +#include "app_ble_custom_cmd.h" +#include "rwapp_config.h" + + +#ifdef BTIF_BLE_APP_DATAPATH_SERVER + + +#define BLE_CUSTOM_CMD_WAITING_RSP_TIMEOUT_COUNT 8 + +#define BLE_RAW_DATA_XFER_BUF_SIZE 80 +/** + * @brief waiting response timeout supervision data structure + * + */ +typedef struct +{ + uint16_t entryIndex; /**< The command waiting for the response */ + uint16_t msTillTimeout; /**< run-time timeout left milliseconds */ +} BLE_CUSTOM_CMD_WAITING_RSP_SUPERVISOR_T; + +/** + * @brief Custom command handling environment + * + */ +typedef struct +{ + uint8_t isInRawDataXferStage; /**< true if the received data is raw data, + false if the received data is in the format of BLE_CUSTOM_CMD_PAYLOAD_T*/ + uint16_t lengthOfRawDataXferToReceive; + uint16_t lengthOfReceivedRawDataXfer; + uint8_t* ptrRawXferDstBuf; + BLE_RawDataReceived_Handler_t rawDataHandler; + BLE_CUSTOM_CMD_WAITING_RSP_SUPERVISOR_T waitingRspTimeoutInstance[BLE_CUSTOM_CMD_WAITING_RSP_TIMEOUT_COUNT]; + uint32_t lastSysTicks; + uint8_t timeoutSupervisorCount; + osTimerId supervisor_timer_id; + osMutexId mutex; + +} BLE_CUSTOM_CMD_ENV_T; + +static uint8_t rawDataXferBuf[BLE_RAW_DATA_XFER_BUF_SIZE]; +static BLE_CUSTOM_CMD_ENV_T ble_custom_cmd_env; + +osMutexDef(app_ble_cmd_mutex); + +static void ble_custom_cmd_rsp_supervision_timer_cb(void const *n); +osTimerDef (APP_CUSTOM_CMD_RSP_SUPERVISION_TIMER, ble_custom_cmd_rsp_supervision_timer_cb); + +static void BLE_remove_waiting_rsp_timeout_supervision(uint16_t entryIndex); + +extern void app_datapath_server_send_data_via_notification(uint8_t* ptrData, uint32_t length); +extern void app_datapath_server_send_data_via_indication(uint8_t* ptrData, uint32_t length); +extern void app_datapath_server_send_data_via_write_command(uint8_t* ptrData, uint32_t length); +extern void app_datapath_server_send_data_via_write_request(uint8_t* ptrData, uint32_t length); + + +/** + * @brief Callback function of the waiting response supervisor timer. + * + */ +static void ble_custom_cmd_rsp_supervision_timer_cb(void const *n) +{ + uint32_t entryIndex = ble_custom_cmd_env.waitingRspTimeoutInstance[0].entryIndex; + + BLE_remove_waiting_rsp_timeout_supervision(entryIndex); + + // it means time-out happens before the response is received from the peer device, + // trigger the response handler + CUSTOM_COMMAND_PTR_FROM_ENTRY_INDEX(entryIndex)->cmdRspHandler(TIMEOUT_WAITING_RESPONSE, NULL, 0); +} + +void BLE_get_response_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + // parameter length check + if (paramLen > sizeof(BLE_CUSTOM_CMD_RSP_T)) + { + return; + } + + if (0 == ble_custom_cmd_env.timeoutSupervisorCount) + { + return; + } + + BLE_CUSTOM_CMD_RSP_T* rsp = (BLE_CUSTOM_CMD_RSP_T *)ptrParam; + + BLE_CUSTOM_CMD_INSTANCE_T* ptCmdInstance = + BLE_custom_command_get_entry_pointer_from_cmd_code(rsp->cmdCodeToRsp); + if (NULL == ptCmdInstance) + { + return; + } + + // remove the function code from the time-out supervision chain + BLE_remove_waiting_rsp_timeout_supervision(rsp->cmdCodeToRsp); + + // call the response handler + if (ptCmdInstance->cmdRspHandler) + { + ptCmdInstance->cmdRspHandler(rsp->cmdRetStatus, rsp->rspData, rsp->rspDataLen); + } +} + +void BLE_control_raw_data_xfer(bool isStartXfer) +{ + ble_custom_cmd_env.isInRawDataXferStage = isStartXfer; + + if (true == isStartXfer) + { + ble_custom_cmd_env.lengthOfReceivedRawDataXfer = 0; + // default configuration, can be customized by BLE_config_raw_data_xfer + ble_custom_cmd_env.lengthOfRawDataXferToReceive = sizeof(rawDataXferBuf); + ble_custom_cmd_env.ptrRawXferDstBuf = (uint8_t *)&rawDataXferBuf; + ble_custom_cmd_env.rawDataHandler = NULL; + } +} + +void BLE_set_raw_data_xfer_received_callback(BLE_RawDataReceived_Handler_t callback) +{ + ble_custom_cmd_env.rawDataHandler = callback; +} + +void BLE_raw_data_xfer_control_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + bool isStartXfer = false; + + if (OP_START_RAW_DATA_XFER == funcCode) + { + isStartXfer = true; + } + + BLE_control_raw_data_xfer(isStartXfer); + + BLE_send_response_to_command(funcCode, NO_ERROR, NULL, 0, TRANSMISSION_VIA_NOTIFICATION); +} + +void BLE_start_raw_data_xfer_control_rsp_handler(BLE_CUSTOM_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen) +{ + if (NO_ERROR == retStatus) + { + /**< now the sending data api won't wrap BLE_CUSTOM_CMD_PAYLOAD_T but will directly send the raw data */ + ble_custom_cmd_env.isInRawDataXferStage = true; + } +} + +void BLE_stop_raw_data_xfer_control_rsp_handler(BLE_CUSTOM_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen) +{ + if (NO_ERROR == retStatus) + { + ble_custom_cmd_env.isInRawDataXferStage = false; + } +} + +/** + * @brief Refresh the waiting response supervisor list + * + */ +static void ble_custom_cmd_refresh_supervisor_env(void) +{ + // do nothing if no supervisor was added + if (ble_custom_cmd_env.timeoutSupervisorCount > 0) + { + uint32_t currentTicks = GET_CURRENT_TICKS(); + uint32_t passedTicks; + if (currentTicks >= ble_custom_cmd_env.lastSysTicks) + { + passedTicks = (currentTicks - ble_custom_cmd_env.lastSysTicks); + } + else + { + passedTicks = (hal_sys_timer_get_max() - ble_custom_cmd_env.lastSysTicks + 1) + currentTicks; + } + + uint32_t deltaMs = TICKS_TO_MS(passedTicks); + + BLE_CUSTOM_CMD_WAITING_RSP_SUPERVISOR_T* pRspSupervisor = &(ble_custom_cmd_env.waitingRspTimeoutInstance[0]); + for (uint32_t index = 0;index < ble_custom_cmd_env.timeoutSupervisorCount;index++) + { + ASSERT(pRspSupervisor[index].msTillTimeout > deltaMs, + "the waiting command response supervisor timer is missing!!!, \ + %d ms passed but the ms to trigger is %d", deltaMs, pRspSupervisor[index].msTillTimeout); + pRspSupervisor[index].msTillTimeout -= deltaMs; + } + } + + ble_custom_cmd_env.lastSysTicks = GET_CURRENT_TICKS(); +} + +/** + * @brief Remove the time-out supervision of waiting response + * + * @param entryIndex Entry index of the command table + * + */ +static void BLE_remove_waiting_rsp_timeout_supervision(uint16_t entryIndex) +{ + ASSERT(ble_custom_cmd_env.timeoutSupervisorCount > 0, + "%s The BLE custom command time-out supervisor is already empty!!!", __FUNCTION__); + + osMutexWait(ble_custom_cmd_env.mutex, osWaitForever); + + uint32_t index; + for (index = 0;index < ble_custom_cmd_env.timeoutSupervisorCount;index++) + { + if (ble_custom_cmd_env.waitingRspTimeoutInstance[index].entryIndex == entryIndex) + { + memcpy(&(ble_custom_cmd_env.waitingRspTimeoutInstance[index]), + &(ble_custom_cmd_env.waitingRspTimeoutInstance[index + 1]), + (ble_custom_cmd_env.timeoutSupervisorCount - index - 1)*sizeof(BLE_CUSTOM_CMD_WAITING_RSP_SUPERVISOR_T)); + break; + } + } + + // cannot find it, directly return + if (index == ble_custom_cmd_env.timeoutSupervisorCount) + { + goto exit; + } + + ble_custom_cmd_env.timeoutSupervisorCount--; + + if (ble_custom_cmd_env.timeoutSupervisorCount > 0) + { + // refresh supervisor environment firstly + ble_custom_cmd_refresh_supervisor_env(); + + // start timer, the first entry is the most close one + osTimerStart(ble_custom_cmd_env.supervisor_timer_id, ble_custom_cmd_env.waitingRspTimeoutInstance[0].msTillTimeout); + } + else + { + // no supervisor, directly stop the timer + osTimerStop(ble_custom_cmd_env.supervisor_timer_id); + } + +exit: + osMutexRelease(ble_custom_cmd_env.mutex); +} + +/** + * @brief Add the time-out supervision of waiting response + * + * @param entryIndex Index of the command entry + * + */ +static void BLE_add_waiting_rsp_timeout_supervision(uint16_t entryIndex) +{ + ASSERT(ble_custom_cmd_env.timeoutSupervisorCount < BLE_CUSTOM_CMD_WAITING_RSP_TIMEOUT_COUNT, + "%s The BLE custom command time-out supervisor is full!!!", __FUNCTION__); + + osMutexWait(ble_custom_cmd_env.mutex, osWaitForever); + + // refresh supervisor environment firstly + ble_custom_cmd_refresh_supervisor_env(); + + BLE_CUSTOM_CMD_INSTANCE_T* pInstance = CUSTOM_COMMAND_PTR_FROM_ENTRY_INDEX(entryIndex); + + BLE_CUSTOM_CMD_WAITING_RSP_SUPERVISOR_T waitingRspTimeoutInstance[BLE_CUSTOM_CMD_WAITING_RSP_TIMEOUT_COUNT]; + + uint32_t index = 0, insertedIndex = 0; + for (index = 0;index < ble_custom_cmd_env.timeoutSupervisorCount;index++) + { + uint32_t msTillTimeout = ble_custom_cmd_env.waitingRspTimeoutInstance[index].msTillTimeout; + + // in the order of low to high + if ((ble_custom_cmd_env.waitingRspTimeoutInstance[index].entryIndex != entryIndex) && + (pInstance->timeoutWaitingRspInMs >= msTillTimeout)) + { + waitingRspTimeoutInstance[insertedIndex++] = ble_custom_cmd_env.waitingRspTimeoutInstance[index]; + } + else if (pInstance->timeoutWaitingRspInMs < msTillTimeout) + { + waitingRspTimeoutInstance[insertedIndex].entryIndex = entryIndex; + waitingRspTimeoutInstance[insertedIndex].msTillTimeout = pInstance->timeoutWaitingRspInMs; + + insertedIndex++; + } + } + + // biggest one? then put it at the end of the list + if (ble_custom_cmd_env.timeoutSupervisorCount == index) + { + waitingRspTimeoutInstance[insertedIndex].entryIndex = entryIndex; + waitingRspTimeoutInstance[insertedIndex].msTillTimeout = pInstance->timeoutWaitingRspInMs; + + insertedIndex++; + } + + // copy to the global variable + memcpy((uint8_t *)&(ble_custom_cmd_env.waitingRspTimeoutInstance), (uint8_t *)&waitingRspTimeoutInstance, + insertedIndex*sizeof(BLE_CUSTOM_CMD_WAITING_RSP_SUPERVISOR_T)); + + ble_custom_cmd_env.timeoutSupervisorCount = insertedIndex; + + // start timer, the first entry is the most close one + osTimerStart(ble_custom_cmd_env.supervisor_timer_id, ble_custom_cmd_env.waitingRspTimeoutInstance[0].msTillTimeout); + + osMutexRelease(ble_custom_cmd_env.mutex); +} + +/** + * @brief Return the pointer of the received raw data + * + * @return uint8_t* Pointer of the raw data buffer + */ +uint8_t* BLE_custom_command_raw_data_buffer_pointer(void) +{ + return ble_custom_cmd_env.ptrRawXferDstBuf; +} + +/** + * @brief Return the size of the received raw data + * + * @return uint16_t Pointer of the raw data buffer + */ +uint16_t BLE_custom_command_received_raw_data_size(void) +{ + return ble_custom_cmd_env.lengthOfReceivedRawDataXfer; +} + +/** + * @brief Receive the data from the peer device and parse them + * + * @param ptrData Pointer of the received data + * @param dataLength Length of the received data + * + * @return BLE_CUSTOM_CMD_RET_STATUS_E + */ +BLE_CUSTOM_CMD_RET_STATUS_E BLE_custom_command_receive_data(uint8_t* ptrData, uint32_t dataLength) +{ + TRACE(1,"Receive length %d data: ", dataLength); + DUMP8("0x%02x ", ptrData, dataLength); + BLE_CUSTOM_CMD_PAYLOAD_T* pPayload = (BLE_CUSTOM_CMD_PAYLOAD_T *)ptrData; + + if ((OP_START_RAW_DATA_XFER == pPayload->cmdCode) || + (OP_STOP_RAW_DATA_XFER == pPayload->cmdCode) || + (!(ble_custom_cmd_env.isInRawDataXferStage))) + { + // check command code + if (pPayload->cmdCode >= OP_COMMAND_COUNT) + { + return INVALID_CMD_CODE; + } + + // check parameter length + if (pPayload->paramLen > sizeof(pPayload->param)) + { + return PARAMETER_LENGTH_OUT_OF_RANGE; + } + + BLE_CUSTOM_CMD_INSTANCE_T* pInstance = + BLE_custom_command_get_entry_pointer_from_cmd_code(pPayload->cmdCode); + + // execute the command handler + if(!pInstance) + pInstance->cmdHandler(pPayload->cmdCode, pPayload->param, pPayload->paramLen); + } + else + { + // the payload of the raw data xfer is 2 bytes cmd code + raw data + if (dataLength < sizeof(pPayload->cmdCode)) + { + return PARAMETER_LENGTH_TOO_SHORT; + } + + dataLength -= sizeof(pPayload->cmdCode); + ptrData += sizeof(pPayload->cmdCode); + + if (NULL == ble_custom_cmd_env.rawDataHandler) + { + // default handler + + // save the received raw data into raw data buffer + uint32_t bytesToSave; + if ((dataLength + ble_custom_cmd_env.lengthOfReceivedRawDataXfer) > \ + ble_custom_cmd_env.lengthOfRawDataXferToReceive) + { + bytesToSave = ble_custom_cmd_env.lengthOfRawDataXferToReceive - \ + ble_custom_cmd_env.lengthOfReceivedRawDataXfer; + } + else + { + bytesToSave = dataLength; + } + memcpy((uint8_t *)&ble_custom_cmd_env.ptrRawXferDstBuf[ble_custom_cmd_env.lengthOfReceivedRawDataXfer], \ + ptrData, bytesToSave); + + + ble_custom_cmd_env.lengthOfReceivedRawDataXfer += bytesToSave; + } + else + { + // custom handler that is set by BLE_set_raw_data_xfer_received_callback + ble_custom_cmd_env.rawDataHandler(ptrData, dataLength); + } + } + + return NO_ERROR; +} + +static void BLE_send_out_data(BLE_CUSTOM_CMD_TRANSMISSION_PATH_E path, BLE_CUSTOM_CMD_PAYLOAD_T* ptPayLoad) +{ + switch (path) + { + case TRANSMISSION_VIA_NOTIFICATION: + app_datapath_server_send_data_via_notification((uint8_t *)ptPayLoad, + (uint32_t)(&(((BLE_CUSTOM_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + break; + case TRANSMISSION_VIA_INDICATION: + app_datapath_server_send_data_via_indication((uint8_t *)ptPayLoad, + (uint32_t)(&(((BLE_CUSTOM_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + break; + case TRANSMISSION_VIA_WRITE_CMD: + app_datapath_server_send_data_via_write_command((uint8_t *)ptPayLoad, + (uint32_t)(&(((BLE_CUSTOM_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + break; + case TRANSMISSION_VIA_WRITE_REQ: + app_datapath_server_send_data_via_write_request((uint8_t *)ptPayLoad, + (uint32_t)(&(((BLE_CUSTOM_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + break; + default: + break; + } +} + +/** + * @brief Send response to the command request + * + * @param responsedCmdCode Command code of the responsed command request + * @param returnStatus Handling result + * @param rspData Pointer of the response data + * @param rspDataLen Length of the response data + * @param path Path of the data transmission + * + * @return BLE_CUSTOM_CMD_RET_STATUS_E + */ +BLE_CUSTOM_CMD_RET_STATUS_E BLE_send_response_to_command + (uint32_t responsedCmdCode, BLE_CUSTOM_CMD_RET_STATUS_E returnStatus, + uint8_t* rspData, uint32_t rspDataLen, BLE_CUSTOM_CMD_TRANSMISSION_PATH_E path) +{ + // check responsedCmdCode's validity + if (responsedCmdCode >= OP_COMMAND_COUNT) + { + return INVALID_CMD_CODE; + } + + BLE_CUSTOM_CMD_PAYLOAD_T payload; + + BLE_CUSTOM_CMD_RSP_T* pResponse = (BLE_CUSTOM_CMD_RSP_T *)&(payload.param); + + // check parameter length + if (rspDataLen > sizeof(pResponse->rspData)) + { + return PARAMETER_LENGTH_OUT_OF_RANGE; + } + + pResponse->cmdCodeToRsp = responsedCmdCode; + pResponse->cmdRetStatus = returnStatus; + pResponse->rspDataLen = rspDataLen; + memcpy(pResponse->rspData, rspData, rspDataLen); + + payload.paramLen = 3*sizeof(uint16_t) + rspDataLen; + + payload.cmdCode = OP_RESPONSE_TO_CMD; + + BLE_send_out_data(path, &payload); + + return NO_ERROR; +} + +/** + * @brief Send the custom command to the peer device + * + * @param cmdCode Command code + * @param ptrParam Pointer of the output parameter + * @param paramLen Length of the output parameter + * @param path Path of the data transmission + * + * @return BLE_CUSTOM_CMD_RET_STATUS_E + */ +BLE_CUSTOM_CMD_RET_STATUS_E BLE_send_custom_command(uint32_t cmdCode, + uint8_t* ptrParam, uint32_t paramLen, BLE_CUSTOM_CMD_TRANSMISSION_PATH_E path) +{ + // check cmdCode's validity + if (cmdCode >= OP_COMMAND_COUNT) + { + return INVALID_CMD_CODE; + } + + BLE_CUSTOM_CMD_PAYLOAD_T payload; + + // check parameter length + if (paramLen > sizeof(payload.param)) + { + return PARAMETER_LENGTH_OUT_OF_RANGE; + } + + uint16_t entryIndex = BLE_custom_command_get_entry_index_from_cmd_code(cmdCode); + BLE_CUSTOM_CMD_INSTANCE_T* pInstance = CUSTOM_COMMAND_PTR_FROM_ENTRY_INDEX(entryIndex); + + // wrap the command payload + payload.cmdCode = cmdCode; + payload.paramLen = paramLen; + memcpy(payload.param, ptrParam, paramLen); + + // send out the data + BLE_send_out_data(path, &payload); + + // insert into time-out supervison + if (pInstance->isNeedResponse) + { + BLE_add_waiting_rsp_timeout_supervision(cmdCode); + } + + return NO_ERROR; +} + +BLE_CUSTOM_CMD_INSTANCE_T* BLE_custom_command_get_entry_pointer_from_cmd_code(uint16_t cmdCode) +{ + for (uint32_t index = 0; + index < ((uint32_t)__custom_handler_table_end-(uint32_t)__custom_handler_table_start)/sizeof(BLE_CUSTOM_CMD_INSTANCE_T);index++) + { + if (CUSTOM_COMMAND_PTR_FROM_ENTRY_INDEX(index)->cmdCode == cmdCode) + { + return CUSTOM_COMMAND_PTR_FROM_ENTRY_INDEX(index); + } + } + + return NULL; +} + +uint16_t BLE_custom_command_get_entry_index_from_cmd_code(uint16_t cmdCode) +{ + for (uint32_t index = 0; + index < (__custom_handler_table_end-__custom_handler_table_start)/sizeof(BLE_CUSTOM_CMD_INSTANCE_T);index++) + { + if (CUSTOM_COMMAND_PTR_FROM_ENTRY_INDEX(index)->cmdCode == cmdCode) + { + return index; + } + } + + return INVALID_CUSTOM_ENTRY_INDEX; +} + +/** + * @brief Initialize the BLE custom command framework + * + */ +void BLE_custom_command_init(void) +{ + memset((uint8_t *)&ble_custom_cmd_env, 0, sizeof(ble_custom_cmd_env)); + + ble_custom_cmd_env.supervisor_timer_id = + osTimerCreate(osTimer(APP_CUSTOM_CMD_RSP_SUPERVISION_TIMER), osTimerOnce, NULL); + + ble_custom_cmd_env.mutex = osMutexCreate((osMutex(app_ble_cmd_mutex))); +} +#endif + diff --git a/services/ble_app/app_datapath/app_ble_cmd_handler.h b/services/ble_app/app_datapath/app_ble_cmd_handler.h new file mode 100644 index 0000000..5cfdc84 --- /dev/null +++ b/services/ble_app/app_datapath/app_ble_cmd_handler.h @@ -0,0 +1,161 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BLE_CMD_HANDLER_H__ +#define __APP_BLE_CMD_HANDLER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_timer.h" + +#define GET_CURRENT_TICKS() hal_sys_timer_get() + +#define GET_CURRENT_MS() TICKS_TO_MS(GET_CURRENT_TICKS()) + +extern uint32_t __custom_handler_table_start[]; +extern uint32_t __custom_handler_table_end[]; + +#define CUSTOM_COMMAND_TO_ADD(cmdCode, cmdHandler, isNeedResponse, timeoutWaitingRspInMs, cmdRspHandler) \ + static const BLE_CUSTOM_CMD_INSTANCE_T cmdCode##_entry __attribute__((used, section(".custom_handler_table"))) = \ + {(cmdCode), (cmdHandler), (isNeedResponse), (timeoutWaitingRspInMs), (cmdRspHandler)}; + +#define CUSTOM_COMMAND_PTR_FROM_ENTRY_INDEX(index) \ + ((BLE_CUSTOM_CMD_INSTANCE_T *)((uint32_t)__custom_handler_table_start + (index)*sizeof(BLE_CUSTOM_CMD_INSTANCE_T))) + +#define INVALID_CUSTOM_ENTRY_INDEX 0xFFFF + +/** + * @brief The BLE custom command handling return status + * + */ +typedef enum +{ + NO_ERROR = 0, + INVALID_CMD_CODE, + PARAMETER_LENGTH_OUT_OF_RANGE, + PARAMETER_LENGTH_TOO_SHORT, + HANDLING_FAILED, + TIMEOUT_WAITING_RESPONSE, + // TO ADD: new return status +} BLE_CUSTOM_CMD_RET_STATUS_E; + +/** + * @brief Type of the BLE data transmission path + * + */ +typedef enum +{ + TRANSMISSION_VIA_NOTIFICATION = 0, + TRANSMISSION_VIA_INDICATION, + TRANSMISSION_VIA_WRITE_CMD, + TRANSMISSION_VIA_WRITE_REQ, +} BLE_CUSTOM_CMD_TRANSMISSION_PATH_E; + +/** + * @brief Format of the custom command handler function, called when the command is received + * + * @param cmdCode Custom command code, from BLE_CUSTOM_CMD_CODE_E + * @param ptrParam Pointer of the received parameter + * @param paramLen Length of the recevied parameter + * + */ +typedef void (*BLE_CustomCmdHandler_t)(uint32_t cmdCode, uint8_t* ptrParam, uint32_t paramLen); + +/** + * @brief Format of the custom command response handler function, + * called when the response to formerly sent command is received + * + * @param retStatus Handling return status of the command + * @param ptrParam Pointer of the received parameter + * @param paramLen Length of the recevied parameter + * + */ +typedef void (*BLE_CustomCmd_Response_Handler_t)(BLE_CUSTOM_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen); + +/** + * @brief Format of the raw data xfer received handler function + * + * @param ptrData Pointer of the received raw data + * @param dataLen Length of the received raw data + * + */ +typedef void (*BLE_RawDataReceived_Handler_t)(uint8_t* ptrData, uint32_t dataLen); + + +/** + * @brief Custom command definition data structure + * + */ +typedef struct +{ + uint16_t cmdCode; + BLE_CustomCmdHandler_t cmdHandler; /**< command handler function */ + uint8_t isNeedResponse; /**< true if needs the response from the peer device */ + uint16_t timeoutWaitingRspInMs; /**< time-out of waiting for response in milli-seconds */ + BLE_CustomCmd_Response_Handler_t cmdRspHandler; /**< command response handler function */ +} BLE_CUSTOM_CMD_INSTANCE_T; + +/**< maximum payload size of one BLE custom command */ +#define BLE_CUSTOM_CMD_MAXIMUM_PAYLOAD_SIZE 20 // assure that one BLE packet can include all the data + +/** + * @brief BLE custom command playload + * + */ +typedef struct +{ + uint16_t cmdCode; /**< command code, from BLE_CUSTOM_CMD_CODE_E */ + uint16_t paramLen; /**< length of the following parameter */ + uint8_t param[BLE_CUSTOM_CMD_MAXIMUM_PAYLOAD_SIZE - 2*sizeof(uint16_t)]; +} BLE_CUSTOM_CMD_PAYLOAD_T; + +/** + * @brief Command response parameter structure + * + */ +typedef struct +{ + uint16_t cmdCodeToRsp; /**< tell which command code to response */ + uint16_t cmdRetStatus; /**< handling result of the command, from BLE_CUSTOM_CMD_RET_STATUS_E */ + uint16_t rspDataLen; /**< length of the response data */ + uint8_t rspData[BLE_CUSTOM_CMD_MAXIMUM_PAYLOAD_SIZE - 5*sizeof(uint16_t)]; +} BLE_CUSTOM_CMD_RSP_T; + +void BLE_get_response_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen); +void BLE_raw_data_xfer_control_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen); +void BLE_control_raw_data_xfer(bool isStartXfer); +void BLE_set_raw_data_xfer_received_callback(BLE_RawDataReceived_Handler_t callback); +void BLE_start_raw_data_xfer_control_rsp_handler(BLE_CUSTOM_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen); +void BLE_stop_raw_data_xfer_control_rsp_handler(BLE_CUSTOM_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen); +uint8_t* BLE_custom_command_raw_data_buffer_pointer(void); +uint16_t BLE_custom_command_received_raw_data_size(void); +BLE_CUSTOM_CMD_RET_STATUS_E BLE_send_response_to_command(uint32_t responsedCmdCode, BLE_CUSTOM_CMD_RET_STATUS_E returnStatus, + uint8_t* rspData, uint32_t rspDataLen, BLE_CUSTOM_CMD_TRANSMISSION_PATH_E path); +BLE_CUSTOM_CMD_RET_STATUS_E BLE_send_custom_command(uint32_t cmdCode, uint8_t* ptrParam, uint32_t paramLen, BLE_CUSTOM_CMD_TRANSMISSION_PATH_E path); +BLE_CUSTOM_CMD_RET_STATUS_E BLE_custom_command_receive_data(uint8_t* ptrData, uint32_t dataLength); +void BLE_custom_command_init(void); +BLE_CUSTOM_CMD_INSTANCE_T* BLE_custom_command_get_entry_pointer_from_cmd_code(uint16_t cmdCode); +uint16_t BLE_custom_command_get_entry_index_from_cmd_code(uint16_t cmdCode); + + + +#ifdef __cplusplus + } +#endif + +#endif // #ifndef __APP_BLE_CMD_HANDLER_H__ + diff --git a/services/ble_app/app_datapath/app_ble_custom_cmd.c b/services/ble_app/app_datapath/app_ble_custom_cmd.c new file mode 100644 index 0000000..507c562 --- /dev/null +++ b/services/ble_app/app_datapath/app_ble_custom_cmd.c @@ -0,0 +1,139 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "string.h" +#include "cmsis_os.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "stdbool.h" +#include "apps.h" +#include "rwapp_config.h" +#include "hal_cmu.h" +#include "hal_bootmode.h" + +#include "app_ble_cmd_handler.h" +#include "app_ble_custom_cmd.h" +#include "retention_ram.h" + + +#if (BTIF_BLE_APP_DATAPATH_SERVER) + +extern void app_datapath_server_send_data_via_notification(uint8_t* ptrData, uint32_t length); + + +void BLE_dummy_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + +} + +void BLE_test_no_response_print_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + TRACE(1,"%s Get OP_TEST_NO_RESPONSE_PRINT command!!!", __FUNCTION__); +} + +void BLE_test_with_response_print_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + TRACE(1,"%s Get OP_TEST_WITH_RESPONSE_PRINT command!!!", __FUNCTION__); + + uint32_t currentTicks = GET_CURRENT_TICKS(); + BLE_send_response_to_command(funcCode, NO_ERROR, (uint8_t *)¤tTicks, sizeof(currentTicks), TRANSMISSION_VIA_NOTIFICATION); +} + +void BLE_test_with_response_print_rsp_handler(BLE_CUSTOM_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen) +{ + if (NO_ERROR == retStatus) + { + TRACE(1,"%s Get the response of OP_TEST_WITH_RESPONSE_PRINT command!!!", __FUNCTION__); + } + else if (TIMEOUT_WAITING_RESPONSE == retStatus) + { + TRACE(1,"%s Timeout happens, doesn't get the response of OP_TEST_WITH_RESPONSE_PRINT command!!!", __FUNCTION__); + } +} + +static void app_otaMode_enter(void) +{ + TRACE(1,"%s",__func__); + hal_norflash_disable_protection(HAL_NORFLASH_ID_0); + hal_sw_bootmode_set(HAL_SW_BOOTMODE_ENTER_HIDE_BOOT); + /*hal_cmu_reset_set(HAL_CMU_MOD_P_GLOBAL);*/ +} + +void BLE_enter_OTA_mode_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + fillBleBdAddrForOta(ptrParam); + app_otaMode_enter(); +} + +#ifdef __SW_IIR_EQ_PROCESS__ +int audio_config_eq_iir_via_config_structure(uint8_t *buf, uint32_t len); +void BLE_iir_eq_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + + audio_config_eq_iir_via_config_structure(BLE_custom_command_raw_data_buffer_pointer(), BLE_custom_command_received_raw_data_size()); +} + +#endif + +extern uint8_t bt_addr[6]; +void BLE_get_bt_address_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + app_datapath_server_send_data_via_notification((uint8_t *)&bt_addr, sizeof(bt_addr)); +} + +CUSTOM_COMMAND_TO_ADD(OP_RESPONSE_TO_CMD, BLE_get_response_handler, false, 0, NULL ); +CUSTOM_COMMAND_TO_ADD(OP_START_RAW_DATA_XFER, BLE_raw_data_xfer_control_handler, true, 2000, BLE_start_raw_data_xfer_control_rsp_handler ); +CUSTOM_COMMAND_TO_ADD(OP_STOP_RAW_DATA_XFER, BLE_raw_data_xfer_control_handler, true, 2000, BLE_stop_raw_data_xfer_control_rsp_handler ); +CUSTOM_COMMAND_TO_ADD(OP_TEST_NO_RESPONSE_PRINT, BLE_test_no_response_print_handler, false, 0, NULL ); +CUSTOM_COMMAND_TO_ADD(OP_TEST_WITH_RESPONSE_PRINT, BLE_test_with_response_print_handler, true, 5000, BLE_test_with_response_print_rsp_handler ); +CUSTOM_COMMAND_TO_ADD(OP_ENTER_OTA_MODE, BLE_enter_OTA_mode_handler, false, 0, NULL ); +#ifdef __SW_IIR_EQ_PROCESS__ +CUSTOM_COMMAND_TO_ADD(OP_SW_IIR_EQ, BLE_iir_eq_handler, false, 0, NULL ); +#endif +CUSTOM_COMMAND_TO_ADD(OP_GET_BT_ADDRESS, BLE_get_bt_address_handler, false, 0, NULL ); + + + + + +#if 0 +/** \brief Instances list of BLE custom command handler, should be in the order of the + * command code definition in BLE_CUSTOM_CMD_CODE_E + */ +BLE_CUSTOM_CMD_INSTANCE_T customCommandArray[] = +{ + // { command handler, wait for response or not, time out of waiting response in ms, callback when the response is received } + // non-touchable instances + { BLE_get_response_handler, false, 0, NULL }, + { BLE_raw_data_xfer_control_handler, true, 2000, BLE_start_raw_data_xfer_control_rsp_handler }, + { BLE_raw_data_xfer_control_handler, true, 2000, BLE_stop_raw_data_xfer_control_rsp_handler }, + + // TO ADD: the new custom command instance + { BLE_test_no_response_print_handler, false, 0, NULL }, + { BLE_test_with_response_print_handler, true, 5000, BLE_test_with_response_print_rsp_handler }, + + { BLE_enter_OTA_mode_handler, false, 0, NULL }, + +#ifdef __SW_IIR_EQ_PROCESS__ + { BLE_iir_eq_handler, false, 0, NULL }, +#else + { BLE_dummy_handler, false, 0, NULL }, +#endif + + { BLE_get_bt_address_handler, false, 0, NULL }, +}; +#endif +#endif + diff --git a/services/ble_app/app_datapath/app_ble_custom_cmd.h b/services/ble_app/app_datapath/app_ble_custom_cmd.h new file mode 100644 index 0000000..766424b --- /dev/null +++ b/services/ble_app/app_datapath/app_ble_custom_cmd.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BLE_CUSTOM_CMD_H__ +#define __APP_BLE_CUSTOM_CMD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief The custom command code + * + */ +typedef enum +{ + /* 0 */ OP_RESPONSE_TO_CMD = 0, /**< the payload is: OP_RESPONSE_TO_CMD + paramLen + BLE_CUSTOM_CMD_RSP_T */ + /* 1 */ OP_START_RAW_DATA_XFER, /**< raw data means no BLE_CUSTOM_CMD_PAYLOAD_T.cmdCode but just the data + starting raw data xfer is done via: + 1. send OP_START_RAW_DATA_XFER to target peer device + 2. get OP_RESPONSE_TO_CMD from the target device + 3. send raw data + */ + /* 2 */ OP_STOP_RAW_DATA_XFER, /**< raw data means no BLE_CUSTOM_CMD_PAYLOAD_T.cmdCode but just the data + stopping raw data xfer is done via: + 1. send OP_STOP_RAW_DATA_XFER to target peer device + 2. get OP_RESPONSE_TO_CMD from the target device + 3. stop sending raw data + */ + /* 3 */ OP_TEST_NO_RESPONSE_PRINT, + + /* 4 */ OP_TEST_WITH_RESPONSE_PRINT, + + /* 5 */ OP_ENTER_OTA_MODE, + // TO ADD: new custom command code + + /* 6 */ OP_SW_IIR_EQ, + + /* 7 */ OP_GET_BT_ADDRESS, + + /* 8 */ OP_COMMAND_COUNT, + +} BLE_CUSTOM_CMD_CODE_E; + + +#ifdef __cplusplus + } +#endif + + +#endif // #ifndef __APP_BLE_CUSTOM_CMD_H__ + diff --git a/services/ble_app/app_datapath/app_datapath_server.c b/services/ble_app/app_datapath/app_datapath_server.c new file mode 100644 index 0000000..f4dab11 --- /dev/null +++ b/services/ble_app/app_datapath/app_datapath_server.c @@ -0,0 +1,293 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration +#include "app_ble_cmd_handler.h" + +#if (BLE_APP_DATAPATH_SERVER) + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "app_datapath_server.h" // Data Path Application Definitions +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "datapathps_task.h" +#include "co_bt.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "arch.h" // Platform Definitions +#include "prf.h" +#include "string.h" +#ifdef IBRT +#include "app_ibrt_ui.h" +#endif + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// health thermometer application environment structure +struct app_datapath_server_env_tag app_datapath_server_env = +{ + BLE_INVALID_CONNECTION_INDEX, + false +}; + +static app_datapath_server_tx_done_t tx_done_callback = NULL; + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +void app_datapath_server_mtu_exchanged_handler(uint8_t conidx, uint16_t mtu) +{ + +} + +void app_datapath_server_connected_evt_handler(uint8_t conidx) +{ + TRACE(0,"app datapath server connected."); + app_datapath_server_env.connectionIndex = conidx; +#ifdef IBRT + if (app_ibrt_ui_get_snoop_via_ble_enable()) + { + app_ibrt_ui_set_master_notify_flag(TRUE); + } +#endif +} + +void app_datapath_server_disconnected_evt_handler(uint8_t conidx) +{ + if (conidx == app_datapath_server_env.connectionIndex) + { + TRACE(0,"app datapath server dis-connected."); + app_datapath_server_env.connectionIndex = BLE_INVALID_CONNECTION_INDEX; + app_datapath_server_env.isNotificationEnabled = false; + + tx_done_callback = NULL; + } +} + +void app_datapath_server_init(void) +{ + // Reset the environment + app_datapath_server_env.connectionIndex = BLE_INVALID_CONNECTION_INDEX; + app_datapath_server_env.isNotificationEnabled = false; +} + +void app_datapath_add_datapathps(void) +{ + BLE_APP_DBG("app_datapath_add_datapathps"); + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, TASK_APP, + gapm_profile_task_add_cmd, 0); + + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; + req->sec_lvl = PERM(SVC_AUTH, ENABLE); + req->prf_task_id = TASK_ID_DATAPATHPS; + req->app_task = TASK_APP; + req->start_hdl = 0; + + // Send the message + ke_msg_send(req); +} + +void app_datapath_server_send_data_via_notification(uint8_t* ptrData, uint32_t length) +{ + struct ble_datapath_send_data_req_t * req = KE_MSG_ALLOC_DYN(DATAPATHPS_SEND_DATA_VIA_NOTIFICATION, + prf_get_task_from_id(TASK_ID_DATAPATHPS), + TASK_APP, + ble_datapath_send_data_req_t, + length); + req->connecionIndex = app_datapath_server_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + + ke_msg_send(req); +} + +void app_datapath_server_send_data_via_indication(uint8_t* ptrData, uint32_t length) +{ + struct ble_datapath_send_data_req_t * req = KE_MSG_ALLOC_DYN(DATAPATHPS_SEND_DATA_VIA_INDICATION, + prf_get_task_from_id(TASK_ID_DATAPATHPS), + TASK_APP, + ble_datapath_send_data_req_t, + length); + req->connecionIndex = app_datapath_server_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + + ke_msg_send(req); +} + +void app_datapath_server_send_data_via_write_command(uint8_t* ptrData, uint32_t length) +{ + struct ble_datapath_send_data_req_t * req = KE_MSG_ALLOC_DYN(DATAPATHPS_SEND_DATA_VIA_WRITE_COMMAND, + prf_get_task_from_id(TASK_ID_DATAPATHPS), + TASK_APP, + ble_datapath_send_data_req_t, + length); + req->connecionIndex = app_datapath_server_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + ke_msg_send(req); +} + +void app_datapath_server_send_data_via_write_request(uint8_t* ptrData, uint32_t length) +{ + struct ble_datapath_send_data_req_t * req = KE_MSG_ALLOC_DYN(DATAPATHPS_SEND_DATA_VIA_WRITE_REQUEST, + prf_get_task_from_id(TASK_ID_DATAPATHPS), + TASK_APP, + ble_datapath_send_data_req_t, + length); + req->connecionIndex = app_datapath_server_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + ke_msg_send(req); +} + +void app_datapath_server_control_notification(uint8_t conidx,bool isEnable) +{ + struct ble_datapath_control_notification_t * req = KE_MSG_ALLOC(DATAPATHPS_CONTROL_NOTIFICATION, + prf_get_task_from_id(TASK_ID_DATAPATHPS), + TASK_APP, + ble_datapath_control_notification_t); + req->isEnable = isEnable; + req->connecionIndex = conidx; + ke_msg_send(req); +} + + +/** + **************************************************************************************** + * @brief Handles health thermometer timer + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int app_datapath_server_msg_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Do nothing + + return (KE_MSG_CONSUMED); +} + +static int app_datapath_server_tx_ccc_changed_handler(ke_msg_id_t const msgid, + struct ble_datapath_tx_notif_config_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + app_datapath_server_env.isNotificationEnabled = param->isNotificationEnabled; + + if (app_datapath_server_env.isNotificationEnabled) + { + // the app datapath server is connected when receiving the first enable CCC request + if (BLE_INVALID_CONNECTION_INDEX == app_datapath_server_env.connectionIndex) + { + uint8_t conidx = KE_IDX_GET(src_id); + app_datapath_server_connected_evt_handler(conidx); + } + } + + return (KE_MSG_CONSUMED); +} + +static int app_datapath_server_tx_data_sent_handler(ke_msg_id_t const msgid, + struct ble_datapath_tx_sent_ind_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if (NULL != tx_done_callback) + { + tx_done_callback(); + } + + return (KE_MSG_CONSUMED); +} + +extern void appm_restart_advertising(void); +static int app_datapath_server_rx_data_received_handler(ke_msg_id_t const msgid, + struct ble_datapath_rx_data_ind_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + // loop back the received data + // app_datapath_server_send_data(param->data, param->length); + + TRACE(2,"%s length %d", __func__, param->length); + //DUMP8("%02x ", (param->data+i), len); + +#ifndef __INTERCONNECTION__ + BLE_custom_command_receive_data(param->data, param->length); +#endif + +#ifdef IBRT + if (app_ibrt_ui_get_snoop_via_ble_enable()) + { + app_ibrt_ui_snoop_info_handler(param->data, param->length); + } +#endif + return (KE_MSG_CONSUMED); +} + +void app_datapath_server_register_tx_done(app_datapath_server_tx_done_t callback) +{ + tx_done_callback = callback; +} + +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +const struct ke_msg_handler app_datapath_server_msg_handler_list[] = +{ + // Note: first message is latest message checked by kernel so default is put on top. + {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_datapath_server_msg_handler}, + + {DATAPATHPS_TX_CCC_CHANGED, (ke_msg_func_t)app_datapath_server_tx_ccc_changed_handler}, + {DATAPATHPS_TX_DATA_SENT, (ke_msg_func_t)app_datapath_server_tx_data_sent_handler}, + {DATAPATHPS_RX_DATA_RECEIVED, (ke_msg_func_t)app_datapath_server_rx_data_received_handler}, + {DATAPATHPS_NOTIFICATION_RECEIVED, (ke_msg_func_t)app_datapath_server_rx_data_received_handler}, +}; + +const struct ke_state_handler app_datapath_server_table_handler = + {&app_datapath_server_msg_handler_list[0], (sizeof(app_datapath_server_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif //BLE_APP_DATAPATH_SERVER + +/// @} APP diff --git a/services/ble_app/app_datapath/app_datapath_server.h b/services/ble_app/app_datapath/app_datapath_server.h new file mode 100644 index 0000000..da87c8b --- /dev/null +++ b/services/ble_app/app_datapath/app_datapath_server.h @@ -0,0 +1,134 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef APP_DATAPATH_SERVER_H_ +#define APP_DATAPATH_SERVER_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * @ingroup RICOW + * + * @brief DataPath Server Application entry point. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_DATAPATH_SERVER) + +#include // Standard Integer Definition +#include "ke_task.h" + +#define BLE_INVALID_CONNECTION_INDEX 0xFF + +#define HIGH_SPEED_BLE_CONNECTION_INTERVAL_MIN_IN_MS 20 +#define HIGH_SPEED_BLE_CONNECTION_INTERVAL_MAX_IN_MS 30 +#define HIGH_SPEED_BLE_CONNECTION_SUPERVISOR_TIMEOUT_IN_MS 2000 +#define HIGH_SPEED_BLE_CONNECTION_SLAVELATENCY 0 + + + +#define LOW_SPEED_BLE_CONNECTION_INTERVAL_MIN_IN_MS 400 +#define LOW_SPEED_BLE_CONNECTION_INTERVAL_MAX_IN_MS 500 +#define LOW_SPEED_BLE_CONNECTION_SUPERVISOR_TIMEOUT_IN_MS 2000 +#define LOW_SPEED_BLE_CONNECTION_SLAVELATENCY 0 + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +extern struct app_env_tag app_env; + +/// health thermometer application environment structure +struct app_datapath_server_env_tag +{ + uint8_t connectionIndex; + uint8_t isNotificationEnabled; +}; + +typedef void(*app_datapath_server_tx_done_t)(void); + +typedef void(*app_datapath_server_activity_stopped_t)(void); + +/* + * GLOBAL VARIABLES DECLARATIONS + **************************************************************************************** + */ + +/// Health Thermomter Application environment +extern struct app_datapath_server_env_tag app_datapath_server_env; + +/// Table of message handlers +extern const struct ke_state_handler app_datapath_server_table_handler; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * FUNCTIONS DECLARATION + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialize DataPath Server Application + **************************************************************************************** + */ +void app_datapath_server_init(void); + +/** + **************************************************************************************** + * @brief Add a DataPath Server instance in the DB + **************************************************************************************** + */ +void app_datapath_add_datapathps(void); + +void app_datapath_server_connected_evt_handler(uint8_t conidx); + +void app_datapath_server_disconnected_evt_handler(uint8_t conidx); + +void app_datapath_server_send_data_via_notification(uint8_t* ptrData, uint32_t length); + +void app_datapath_server_send_data_via_indication(uint8_t* ptrData, uint32_t length); + +void app_datapath_server_send_data_via_write_command(uint8_t* ptrData, uint32_t length); + +void app_datapath_server_send_data_via_write_request(uint8_t* ptrData, uint32_t length); + +void app_datapath_server_register_tx_done(app_datapath_server_tx_done_t callback); + +void app_datapath_server_control_notification(uint8_t conidx,bool isEnable); + +void app_datapath_server_mtu_exchanged_handler(uint8_t conidx, uint16_t mtu); + +#ifdef __cplusplus +} +#endif + +#endif //(BLE_APP_DATAPATH_SERVER) + +/// @} APP + +#endif // APP_DATAPATH_SERVER_H_ diff --git a/services/ble_app/app_dis/app_dis.c b/services/ble_app/app_dis/app_dis.c new file mode 100644 index 0000000..21b3a9e --- /dev/null +++ b/services/ble_app/app_dis/app_dis.c @@ -0,0 +1,198 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_DIS) + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "app.h" // Application Manager Definitions +#include "app_dis.h" // Device Information Service Application Definitions +#include "diss_task.h" // Device Information Profile Functions +#include "prf_types.h" // Profile Common Types Definitions +#include "gapm_task.h" // GAP Manager Task API +#include + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +static int diss_value_req_ind_handler(ke_msg_id_t const msgid, + struct diss_value_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Initialize length + uint8_t len = 0; + // Pointer to the data + uint8_t *data = NULL; + + // Check requested value + switch (param->value) + { + case DIS_MANUFACTURER_NAME_CHAR: + { + // Set information + len = APP_DIS_MANUFACTURER_NAME_LEN; + data = (uint8_t *)APP_DIS_MANUFACTURER_NAME; + } break; + + case DIS_MODEL_NB_STR_CHAR: + { + // Set information + len = APP_DIS_MODEL_NB_STR_LEN; + data = (uint8_t *)APP_DIS_MODEL_NB_STR; + } break; + + case DIS_SYSTEM_ID_CHAR: + { + // Set information + len = APP_DIS_SYSTEM_ID_LEN; + data = (uint8_t *)APP_DIS_SYSTEM_ID; + } break; + + case DIS_PNP_ID_CHAR: + { + // Set information + len = APP_DIS_PNP_ID_LEN; + data = (uint8_t *)APP_DIS_PNP_ID; + } break; + + case DIS_SERIAL_NB_STR_CHAR: + { + // Set information + len = APP_DIS_SERIAL_NB_STR_LEN; + data = (uint8_t *)APP_DIS_SERIAL_NB_STR; + } break; + + case DIS_HARD_REV_STR_CHAR: + { + // Set information + len = APP_DIS_HARD_REV_STR_LEN; + data = (uint8_t *)APP_DIS_HARD_REV_STR; + } break; + + case DIS_FIRM_REV_STR_CHAR: + { + // Set information + len = APP_DIS_FIRM_REV_STR_LEN; + data = (uint8_t *)APP_DIS_FIRM_REV_STR; + } break; + + case DIS_SW_REV_STR_CHAR: + { + // Set information + len = APP_DIS_SW_REV_STR_LEN; + data = (uint8_t *)APP_DIS_SW_REV_STR; + } break; + + case DIS_IEEE_CHAR: + { + // Set information + len = APP_DIS_IEEE_LEN; + data = (uint8_t *)APP_DIS_IEEE; + } break; + + default: + ASSERT_ERR(0); + break; + } + + // Allocate confirmation to send the value + struct diss_value_cfm *cfm_value = KE_MSG_ALLOC_DYN(DISS_VALUE_CFM, + src_id, dest_id, + diss_value_cfm, + len); + + // Set parameters + cfm_value->value = param->value; + cfm_value->length = len; + if (len) + { + // Copy data + memcpy(&cfm_value->data[0], data, len); + } + // Send message + ke_msg_send(cfm_value); + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +void app_dis_init(void) +{ + // Nothing to do +} + +void app_dis_add_dis(void) +{ + struct diss_db_cfg* db_cfg; + // Allocate the DISS_CREATE_DB_REQ + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, TASK_APP, + gapm_profile_task_add_cmd, sizeof(struct diss_db_cfg)); + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX>1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE)|PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + + req->prf_task_id = TASK_ID_DISS; + req->app_task = TASK_APP; + req->start_hdl = 0; + + // Set parameters + db_cfg = (struct diss_db_cfg* ) req->param; + db_cfg->features = APP_DIS_FEATURES; + + // Send the message + ke_msg_send(req); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +const struct ke_msg_handler app_dis_msg_handler_list[] = +{ + {DISS_VALUE_REQ_IND, (ke_msg_func_t)diss_value_req_ind_handler}, +}; + +const struct ke_state_handler app_dis_table_handler = + {&app_dis_msg_handler_list[0], (sizeof(app_dis_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif //BLE_APP_DIS + +/// @} APP diff --git a/services/ble_app/app_dis/app_dis.h b/services/ble_app/app_dis/app_dis.h new file mode 100644 index 0000000..4ac3de8 --- /dev/null +++ b/services/ble_app/app_dis/app_dis.h @@ -0,0 +1,135 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef APP_DIS_H_ +#define APP_DIS_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * + * @brief Device Information Application Module Entry point. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW Configuration + +#if (BLE_APP_DIS) + +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/// Manufacturer Name Value +#define APP_DIS_MANUFACTURER_NAME ("RivieraWaves SAS") +#define APP_DIS_MANUFACTURER_NAME_LEN (16) + +/// Model Number String Value +#define APP_DIS_MODEL_NB_STR ("RW-BLE-1.0") +#define APP_DIS_MODEL_NB_STR_LEN (10) + +/// Serial Number +#define APP_DIS_SERIAL_NB_STR ("1.0.0.0-LE") +#define APP_DIS_SERIAL_NB_STR_LEN (10) + +/// Firmware Revision +#define APP_DIS_FIRM_REV_STR ("6.1.2") +#define APP_DIS_FIRM_REV_STR_LEN (5) + +/// System ID Value - LSB -> MSB +#define APP_DIS_SYSTEM_ID ("\x12\x34\x56\xFF\xFE\x9A\xBC\xDE") +#define APP_DIS_SYSTEM_ID_LEN (8) + +/// Hardware Revision String +#define APP_DIS_HARD_REV_STR ("1.0.0") +#define APP_DIS_HARD_REV_STR_LEN (5) + +/// Software Revision String +#define APP_DIS_SW_REV_STR ("6.3.0") +#define APP_DIS_SW_REV_STR_LEN (5) + +/// IEEE +#define APP_DIS_IEEE ("\xFF\xEE\xDD\xCC\xBB\xAA") +#define APP_DIS_IEEE_LEN (6) + +/** + * PNP ID Value - LSB -> MSB + * Vendor ID Source : 0x02 (USB Implementer’s Forum assigned Vendor ID value) + * Vendor ID : 0x045E (Microsoft Corp) + * Product ID : 0x0040 + * Product Version : 0x0300 + */ +#define APP_DIS_PNP_ID ("\x02\x5E\x04\x40\x00\x00\x03") +#define APP_DIS_PNP_ID_LEN (7) + +#if (BLE_APP_HID) +#define APP_DIS_FEATURES (DIS_MANUFACTURER_NAME_CHAR_SUP |\ + DIS_MODEL_NB_STR_CHAR_SUP |\ + DIS_SYSTEM_ID_CHAR_SUP |\ + DIS_PNP_ID_CHAR_SUP) +#else +#define APP_DIS_FEATURES (DIS_ALL_FEAT_SUP) +#endif //(BLE_APP_HID) + + +/* + * GLOBAL VARIABLES DECLARATION + **************************************************************************************** + */ + +/// Table of message handlers +extern const struct ke_state_handler app_dis_table_handler; + +/* + * GLOBAL FUNCTIONS DECLARATION + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialize Device Information Service Application + **************************************************************************************** + */ +void app_dis_init(void); + +/** + **************************************************************************************** + * @brief Add a Device Information Service instance in the DB + **************************************************************************************** + */ +void app_dis_add_dis(void); + +/** + **************************************************************************************** + * @brief Enable the Device Information Service + **************************************************************************************** + */ +void app_dis_enable_prf(uint16_t conhdl); + +#endif //BLE_APP_DIS + +/// @} APP + +#endif //APP_DIS_H_ diff --git a/services/ble_app/app_gfps/app_gfps.c b/services/ble_app/app_gfps/app_gfps.c new file mode 100644 index 0000000..68e3399 --- /dev/null +++ b/services/ble_app/app_gfps/app_gfps.c @@ -0,0 +1,1308 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_GFPS) + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "cmsis_os.h" +#include "app.h" // Application Manager Definitions +#include "apps.h" +#include "app_gfps.h" // Device Information Service Application Definitions +#include "gfps_provider_task.h" // Device Information Profile Functions +#include "prf_types.h" // Profile Common Types Definitions +#include "gapm_task.h" // GAP Manager Task API +#include +#include "gfps_crypto.h" +#include "gfps_provider.h" +#include "gfps_provider_errors.h" +#include "gap.h" +#include "app_ble_mode_switch.h" +#include "nvrecord.h" +#include "nvrecord_fp_account_key.h" +#include "gfps_crypto.h" +#include "gapm.h" +#include "me_api.h" +#include "app_bt.h" +#include "bt_if.h" + +#ifdef IBRT +#include "app_tws_ibrt.h" +#include "app_tws_if.h" +#endif + +/************************private macro defination***************************/ +#define USE_BLE_ADDR_AS_SALT 0 +#define USE_RANDOM_NUM_AS_SALT 1 +#define GFPS_ACCOUNTKEY_SALT_TYPE USE_BLE_ADDR_AS_SALT + +#define FP_SERVICE_LEN 0x06 +#define FP_SERVICE_UUID 0x2CFE +#define FP_DEVICE_MODEL_ID 0x2B677D + + +#define GFPS_INITIAL_ADV_RAND_SALT 0xFF + +#define BLE_FASTPAIR_NORMAL_ADVERTISING_INTERVAL (160) +#define BLE_FASTPAIR_FAST_ADVERTISING_INTERVAL (48) + +/************************private type defination****************************/ + +/************************extern function declearation***********************/ +extern void AES128_ECB_decrypt(uint8_t *input, const uint8_t *key, uint8_t *output); + +/**********************private function declearation************************/ +/*--------------------------------------------------------------------------- + * gfps_ble_data_fill_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * BLE advertisement and scan response data fill handler for Google fast pair + * + * Parameters: + * param - pointer of BLE parameter to be configure + * + * Return: + * void + */ +static void gfps_ble_data_fill_handler(void *param); + +/************************private variable defination************************/ +struct app_gfps_env_tag app_gfps_env; + +static char app_gfps_power_uuid[APP_GFPS_ADV_POWER_UUID_LEN] = APP_GFPS_ADV_POWER_UUID; + +/****************************function defination****************************/ +static void app_gfps_init_env(void) +{ + memset(( uint8_t * )&app_gfps_env, 0, sizeof(struct app_gfps_env_tag)); + app_gfps_env.connectionIndex = BLE_INVALID_CONNECTION_INDEX; + app_gfps_env.batteryDataType = HIDE_UI_INDICATION; + app_gfps_env.advRandSalt = GFPS_INITIAL_ADV_RAND_SALT; + app_ble_register_data_fill_handle(USER_GFPS, ( BLE_DATA_FILL_FUNC_T )gfps_ble_data_fill_handler, false); +} + +static void big_little_switch(const uint8_t *in, uint8_t *out, uint8_t len) +{ + if (len < 1) + return; + for (int i = 0; i < len; i++) + { + out[i] = in[len - i - 1]; + } + return; +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +extern uint8_t bt_addr[6]; + +void app_gfps_connected_evt_handler(uint8_t conidx) +{ + app_gfps_env.connectionIndex = conidx; + TRACE(0,"local LE addr: "); + + bd_addr_t *pBdAddr = gapm_get_connected_bdaddr(conidx); + big_little_switch(pBdAddr->addr, &app_gfps_env.local_le_addr.addr[0], 6); + DUMP8("0x%02x ", pBdAddr->addr, 6); +#if !defined(IBRT) + big_little_switch((&bt_addr[0]), &app_gfps_env.local_bt_addr.addr[0], 6); + TRACE(0,"local bt addr: "); + DUMP8("0x%02x ", &bt_addr[0], 6); +#else + big_little_switch(app_tws_ibrt_get_bt_ctrl_ctx()->local_addr.address, + &app_gfps_env.local_bt_addr.addr[0], 6); + TRACE(0,"local bt addr: "); + DUMP8("0x%02x ", app_tws_ibrt_get_bt_ctrl_ctx()->local_addr.address, 6); +#endif +} + +void app_gfps_disconnected_evt_handler(uint8_t conidx) +{ + if (conidx == app_gfps_env.connectionIndex) + { + //recover classic bt iocap + if (app_gfps_env.bt_set_iocap != NULL) + { + app_gfps_env.bt_set_iocap(app_gfps_env.bt_iocap); + } + if(app_gfps_env.bt_set_authrequirements!=NULL) + { + app_gfps_env.bt_set_authrequirements(app_gfps_env.bt_authrequirements); + } + + app_gfps_env.isKeyBasedPairingNotificationEnabled = false; + app_gfps_env.isPassKeyNotificationEnabled = false; + app_gfps_env.isPendingForWritingNameReq = false; + app_gfps_env.connectionIndex = BLE_INVALID_CONNECTION_INDEX; + } +} + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +static int gfpsp_value_req_ind_handler(ke_msg_id_t const msgid, + struct gfpsp_value_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Initialize length + uint8_t len = 0; + // Pointer to the data + uint8_t *data = NULL; + TRACE(1,"val %d", param->value); + // Check requested value + switch (param->value) + { + case GFPSP_MANUFACTURER_NAME_CHAR: + case GFPSP_MODEL_NB_STR_CHAR: + case GFPSP_SYSTEM_ID_CHAR: + case GFPSP_PNP_ID_CHAR: + case GFPSP_SERIAL_NB_STR_CHAR: + case GFPSP_HARD_REV_STR_CHAR: + case GFPSP_FIRM_REV_STR_CHAR: + case GFPSP_SW_REV_STR_CHAR: + case GFPSP_IEEE_CHAR: + { + // Set information + len = APP_GFPS_IEEE_LEN; + data = ( uint8_t * )APP_GFPS_IEEE; + } + break; + + default: + ASSERT_ERR(0); + break; + } + + // Allocate confirmation to send the value + struct gfpsp_value_cfm *cfm_value = KE_MSG_ALLOC_DYN(GFPSP_VALUE_CFM, + src_id, + dest_id, + gfpsp_value_cfm, + len); + + // Set parameters + cfm_value->value = param->value; + cfm_value->length = len; + if (len) + { + // Copy data + memcpy(&cfm_value->data[0], data, len); + } + // Send message + ke_msg_send(cfm_value); + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +//MSB->LSB +const uint8_t bes_demo_Public_anti_spoofing_key[64] = { + 0x3E,0x08,0x3B,0x0A,0x5C,0x04,0x78,0x84,0xBE,0x41, + 0xBE,0x7E,0x52,0xD1,0x0C,0x68,0x64,0x6C,0x4D,0xB6, + 0xD9,0x20,0x95,0xA7,0x32,0xE9,0x42,0x40,0xAC,0x02, + 0x54,0x48,0x99,0x49,0xDA,0xE1,0x0D,0x9C,0xF5,0xEB, + 0x29,0x35,0x7F,0xB1,0x70,0x55,0xCB,0x8C,0x8F,0xBF, + 0xEB,0x17,0x15,0x3F,0xA0,0xAA,0xA5,0xA2,0xC4,0x3C, + 0x1B,0x48,0x60,0xDA +}; + +//MSB->LSB +const uint8_t bes_demo_private_anti_spoofing_key[32]= { + 0xCD,0xF8,0xAA,0xC0,0xDF,0x4C,0x93,0x63,0x2F,0x48, + 0x20,0xA6,0xD8,0xAB,0x22,0xF3,0x3A,0x94,0xBF,0x8E, + 0x4C,0x90,0x25,0xB3,0x44,0xD2,0x2E,0xDE,0x0F,0xB7, + 0x22,0x1F + }; + +extern void fast_pair_enter_pairing_mode_handler(void); + +void app_gfps_init(void) +{ + nv_record_fp_account_key_init(); + app_gfps_init_env(); + app_gfps_env.enter_pairing_mode =NULL; + app_gfps_env.bt_set_iocap =NULL; + app_gfps_env.bt_set_authrequirements =NULL; + gfps_crypto_init(); + + app_bt_get_fast_pair_info(); +#ifndef IS_USE_CUSTOM_FP_INFO + gfps_crypto_set_p256_key(bes_demo_Public_anti_spoofing_key, bes_demo_private_anti_spoofing_key); +#else + gfps_crypto_set_p256_key(app_bt_get_fast_pair_public_key(),app_bt_get_fast_pair_private_key()); +#endif + app_gfps_set_bt_access_mode(fast_pair_enter_pairing_mode_handler); + app_gfps_set_io_cap(( gfps_bt_io_cap_set )btif_sec_set_io_capabilities); + + app_gfps_set_authrequirements((gfps_bt_io_authrequirements_set)btif_sec_set_authrequirements); + + app_gfps_enable_battery_info(true); +} + +void app_gfps_set_bt_access_mode(gfps_enter_pairing_mode cb) +{ + app_gfps_env.enter_pairing_mode = cb; +} + +void app_gfps_set_io_cap(gfps_bt_io_cap_set cb) +{ + app_gfps_env.bt_set_iocap = cb; +} + +void app_gfps_set_authrequirements(gfps_bt_io_authrequirements_set cb) +{ + app_gfps_env.bt_set_authrequirements = cb; +} + +void app_gfps_set_battery_info_acquire_handler(gfps_get_battery_info_handler cb) +{ + app_gfps_env.get_battery_info_handler = cb; +} + +void app_gfps_add_gfps(void) +{ + struct gfpsp_db_cfg *db_cfg; + // Allocate the DISS_CREATE_DB_REQ + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, + TASK_APP, + gapm_profile_task_add_cmd, + sizeof(struct gfpsp_db_cfg)); + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX > 1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE) | PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + + req->prf_task_id = TASK_ID_GFPSP; + req->app_task = TASK_APP; + req->start_hdl = 0; + + // Set parameters + db_cfg = ( struct gfpsp_db_cfg * )req->param; + db_cfg->features = APP_GFPS_FEATURES; + + // Send the message + ke_msg_send(req); +} + +void app_gfps_send_keybase_pairing_via_notification(uint8_t *ptrData, uint32_t length) +{ + struct gfpsp_send_data_req_t *req = + KE_MSG_ALLOC_DYN(GFPSP_KEY_BASED_PAIRING_WRITE_NOTIFY, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_GFPSP), + app_gfps_env.connectionIndex), + TASK_APP, + gfpsp_send_data_req_t, + length); + + req->connecionIndex = app_gfps_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + + ke_msg_send(req); +} + +int app_gfps_send_passkey_via_notification(uint8_t *ptrData, uint32_t length) +{ + struct gfpsp_send_data_req_t *req = + KE_MSG_ALLOC_DYN(GFPSP_KEY_PASS_KEY_WRITE_NOTIFY, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_GFPSP), + app_gfps_env.connectionIndex), + TASK_APP, + gfpsp_send_data_req_t, + length); + + req->connecionIndex = app_gfps_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + + ke_msg_send(req); + + return (KE_MSG_CONSUMED); +} + +static void app_gfps_send_naming_packet_via_notification(uint8_t *ptrData, uint32_t length) +{ + struct gfpsp_send_data_req_t *req = + KE_MSG_ALLOC_DYN(GFPSP_NAME_NOTIFY, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_GFPSP), + app_gfps_env.connectionIndex), + TASK_APP, + gfpsp_send_data_req_t, + length); + + req->connecionIndex = app_gfps_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + + ke_msg_send(req); +} + +void app_gfps_handling_on_mobile_link_disconnection(btif_remote_device_t* pRemDev) +{ + bool isDisconnectedWithMobile = false; +#ifdef IBRT + + ibrt_link_type_e link_type = + app_tws_ibrt_get_remote_link_type(pRemDev); + if (MOBILE_LINK == link_type) + { + isDisconnectedWithMobile = true; + } +#else + isDisconnectedWithMobile = true; +#endif + + if (isDisconnectedWithMobile) + { + if (app_gfps_is_last_response_pending()) + { + app_gfps_enter_connectable_mode_req_handler(app_gfps_get_last_response()); + } + } +} + +void app_gfps_enter_connectable_mode_req_handler(uint8_t *response) +{ + TRACE(2,"%s isLastResponsePending:%d", __func__, app_gfps_env.isLastResponsePending); + TRACE(0,"response data:"); + DUMP8("%02x ", response, GFPSP_ENCRYPTED_RSP_LEN); + +#ifdef __BT_ONE_BRING_TWO__ + app_gfps_send_keybase_pairing_via_notification(response, GFPSP_ENCRYPTED_RSP_LEN); +#else + +#ifndef IBRT + if (btif_me_get_activeCons() > 0) +#else + if (app_tws_ibrt_mobile_link_connected()) +#endif + { + memcpy(app_gfps_env.pendingLastResponse, response, GFPSP_ENCRYPTED_RSP_LEN); + app_gfps_env.isLastResponsePending = true; + #ifndef IBRT + app_disconnect_all_bt_connections(); + #else + app_tws_ibrt_disconnect_mobile(); + #endif + } + else + { + app_gfps_env.isLastResponsePending = false; + app_gfps_send_keybase_pairing_via_notification(response, GFPSP_ENCRYPTED_RSP_LEN); + TRACE(0,"wait for pair req maybe classic or ble"); + app_gfps_env.isWaitingForFpToConnect = true; + if (app_gfps_env.enter_pairing_mode != NULL) + { + app_gfps_env.enter_pairing_mode(); + } + + if (app_gfps_env.bt_set_iocap != NULL) + { + TRACE(0,"SET IOC"); + app_gfps_env.bt_iocap = app_gfps_env.bt_set_iocap(1); //IO_display_yesno + } + + if(app_gfps_env.bt_set_authrequirements!=NULL) + { + TRACE(0,"SET authrequirements"); + app_gfps_env.bt_authrequirements = app_gfps_env.bt_set_authrequirements(1);//Man in the Middle protection req + } + + } +#endif +} + +uint8_t *app_gfps_get_last_response(void) +{ + return app_gfps_env.pendingLastResponse; +} + +bool app_gfps_is_last_response_pending(void) +{ + return app_gfps_env.isLastResponsePending; +} + +static uint8_t app_gfps_handle_decrypted_keybase_pairing_request(gfpsp_req_resp *raw_req, + uint8_t *out_key) +{ + gfpsp_encrypted_resp en_rsp; + gfpsp_raw_resp raw_rsp; + memcpy(app_gfps_env.keybase_pair_key, out_key, 16); + memcpy(&app_gfps_env.seeker_bt_addr.addr[0] ,&raw_req->rx_tx.key_based_pairing_req.seeker_addr[0],6); + if(raw_req->rx_tx.key_based_pairing_req.flags_discoverability ==RAW_REQ_FLAGS_DISCOVERABILITY_BIT0_EN) + { + TRACE(0,"TODO discoverable 10S"); + //TODO start a timer keep discoverable 10S... + //TODO make sure there is no ble ADV with the MODEL ID data + } + raw_rsp.message_type = KEY_BASED_PAIRING_RSP;// Key-based Pairing Response + memcpy(raw_rsp.provider_addr, app_gfps_env.local_bt_addr.addr, 6); + + TRACE(0,"raw_rsp.provider_addr:"); + DUMP8("%02x ",raw_rsp.provider_addr, 6); + + for (uint8_t index = 0; index < 9; index++) + { + raw_rsp.salt[index] = ( uint8_t )rand(); + } + + gfps_crypto_encrypt(( const uint8_t * )(&raw_rsp.message_type), + sizeof(raw_rsp), + app_gfps_env.keybase_pair_key, + en_rsp.uint128_array); + + TRACE(1,"message type is 0x%x", raw_req->rx_tx.raw_req.message_type); + TRACE(4,"bit 0: %d, bit 1: %d, bit 2: %d, bit 3: %d", + raw_req->rx_tx.key_based_pairing_req.flags_discoverability, + raw_req->rx_tx.key_based_pairing_req.flags_bonding_addr, + raw_req->rx_tx.key_based_pairing_req.flags_get_existing_name, + raw_req->rx_tx.key_based_pairing_req.flags_retroactively_write_account_key); + + bool isReturnName = raw_req->rx_tx.key_based_pairing_req.flags_get_existing_name; + + if(raw_req->rx_tx.key_based_pairing_req.flags_bonding_addr == RAW_REQ_FLAGS_INTBONDING_SEEKERADDR_BIT1_EN) + { + TRACE(0,"try connect to remote BR/EDR addr"); + // TODO: + app_gfps_send_keybase_pairing_via_notification(( uint8_t * )en_rsp.uint128_array, sizeof(en_rsp)); + } + else if (raw_req->rx_tx.key_based_pairing_req.flags_retroactively_write_account_key) + { + // check whether the seeker's bd address is the same as already connected mobile + uint8_t swapedBtAddr[6]; + big_little_switch(app_gfps_env.seeker_bt_addr.addr, swapedBtAddr, sizeof(swapedBtAddr)); + + uint8_t isMatchMobileAddr = false; + for (uint32_t devId = 0; devId < btif_me_get_activeCons(); devId++) + { + uint8_t connectedAddr[6]; + app_bt_get_device_bdaddr(devId, connectedAddr); + if (!memcmp(connectedAddr, swapedBtAddr, 6)) + { + isMatchMobileAddr = true; + break; + } + } + + if (isMatchMobileAddr) + { + app_gfps_send_keybase_pairing_via_notification(( uint8_t * )en_rsp.uint128_array, sizeof(en_rsp)); + } + else + { + // reject the write request + return ATT_ERR_WRITE_NOT_PERMITTED; + } + } + else if (raw_req->rx_tx.key_based_pairing_req.flags_bonding_addr == RAW_REQ_FLAGS_INTBONDING_SEEKERADDR_BIT1_DIS) + { + app_gfps_enter_connectable_mode_req_handler((uint8_t *)en_rsp.uint128_array); + } + else + { + app_gfps_send_keybase_pairing_via_notification(( uint8_t * )en_rsp.uint128_array, sizeof(en_rsp)); + } + + if (isReturnName) + { + app_gfps_env.isPendingForWritingNameReq = true; + TRACE(0,"get existing name."); + uint8_t response[16+FP_MAX_NAME_LEN]; + uint8_t* ptrRawName; + uint32_t rawNameLen; + ptrRawName = nv_record_fp_get_name_ptr(&rawNameLen); + + gfps_encrypt_name(app_gfps_env.keybase_pair_key, + ptrRawName, + rawNameLen, + &response[16], + response, + &response[8]); + + app_gfps_send_naming_packet_via_notification(response, 16 + rawNameLen); + } + else + { + TRACE(0,"Unusable bit."); + } + + return GAP_ERR_NO_ERROR; +} + +static void app_gfps_update_local_bt_name(void) +{ + uint8_t* ptrRawName; + uint32_t rawNameLen; + // name has been updated to fp nv record + ptrRawName = nv_record_fp_get_name_ptr(&rawNameLen); + if(rawNameLen > 0) + { + bt_set_local_dev_name((const unsigned char*)(ptrRawName), + strlen((char *)(ptrRawName)) + 1); + btif_update_bt_name((const unsigned char*)(ptrRawName), + strlen((char *)(ptrRawName)) + 1); + } +} + +static bool app_gfps_decrypt_keybase_pairing_request(uint8_t *pairing_req, uint8_t *output) +{ + uint8_t keyCount = nv_record_fp_account_key_count(); + if (0 == keyCount) + { + return false; + } + + gfpsp_req_resp raw_req; + uint8_t accountKey[FP_ACCOUNT_KEY_SIZE]; + for (uint8_t keyIndex = 0; keyIndex < keyCount; keyIndex++) + { + nv_record_fp_account_key_get_by_index(keyIndex, accountKey); + + AES128_ECB_decrypt(pairing_req, ( const uint8_t * )accountKey, ( uint8_t * )&raw_req); + TRACE(0,"Decrypted keybase pairing req result:"); + DUMP8("0x%02x ", ( uint8_t * )&raw_req, 16); + + if ((memcmp(raw_req.rx_tx.key_based_pairing_req.provider_addr, + app_gfps_env.local_bt_addr.addr , 6)==0) || + (memcmp(raw_req.rx_tx.key_based_pairing_req.provider_addr, + app_gfps_env.local_le_addr.addr , 6)==0)) + { + memcpy(output, accountKey, FP_ACCOUNT_KEY_SIZE); + TRACE(1,"fp message type 0x%02x.", raw_req.rx_tx.raw_req.message_type); + if (KEY_BASED_PAIRING_REQ == raw_req.rx_tx.raw_req.message_type) + { + app_gfps_handle_decrypted_keybase_pairing_request(&raw_req, accountKey); + return true; + } + else if (ACTION_REQUEST == raw_req.rx_tx.raw_req.message_type) + { + memcpy(app_gfps_env.keybase_pair_key, accountKey, 16); + memcpy(&app_gfps_env.seeker_bt_addr.addr[0], + &(raw_req.rx_tx.key_based_pairing_req.seeker_addr[0]), 6); + gfpsp_encrypted_resp en_rsp; + gfpsp_raw_resp raw_rsp; + + raw_rsp.message_type = KEY_BASED_PAIRING_RSP;// Key-based Pairing Response + memcpy(raw_rsp.provider_addr, app_gfps_env.local_bt_addr.addr, 6); + + TRACE(0,"raw_rsp.provider_addr:"); + DUMP8("%02x ",raw_rsp.provider_addr, 6); + + for (uint8_t index = 0;index < 9;index++) + { + raw_rsp.salt[index] = (uint8_t)rand(); + } + + gfps_crypto_encrypt((const uint8_t *)(&raw_rsp.message_type), sizeof(raw_rsp), + app_gfps_env.keybase_pair_key,en_rsp.uint128_array); + + app_gfps_send_keybase_pairing_via_notification((uint8_t *)en_rsp.uint128_array, sizeof(en_rsp)); + + if (raw_req.rx_tx.action_req.isDeviceAction) + { + // TODO: device action via BLE + } + else if (raw_req.rx_tx.action_req.isFollowedByAdditionalDataCh) + { + // write name request will be received + TRACE(0,"FP write name request will be received."); + app_gfps_env.isPendingForWritingNameReq = true; + } + return true; + } + } + + + } + + return false; +} + +int app_gfps_write_key_based_pairing_ind_hander(ke_msg_id_t const msgid, + struct gfpsp_write_ind_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + gfpsp_Key_based_Pairing_req en_req; + gfpsp_req_resp *ptr_raw_req; + + en_req.en_req = ( gfpsp_encrypted_req_uint128 * )&(param->data[0]); + en_req.pub_key = ( gfpsp_64B_public_key * )&(param->data[16]); + uint8_t out_key[16] = {0}; + uint8_t decryptdata[16] = {0}; + uint8_t write_rsp_status = GAP_ERR_NO_ERROR; + + TRACE(3,"length = %d value = 0x%x 0x%x", param->length, param->data[0], param->data[1]); + DUMP8("%02x ", param->data, 80); + + if (param->length == GFPSP_KEY_BASED_PAIRING_REQ_LEN_WITH_PUBLIC_KEY) + { + memset(app_gfps_env.keybase_pair_key, 0, 6); + uint32_t gfps_state = gfps_crypto_get_secret_decrypt(( const uint8_t * )en_req.en_req, + ( const uint8_t * )en_req.pub_key, + out_key, + decryptdata); + if (gfps_state == GFPS_SUCCESS) + { + memcpy(app_gfps_env.aesKeyFromECDH, out_key, 16); + app_gfps_env.isInitialPairing = true; + ptr_raw_req = (gfpsp_req_resp *)decryptdata; + TRACE(0,"raw req provider's addr:"); + DUMP8("%02x ", ptr_raw_req->rx_tx.key_based_pairing_req.provider_addr, 6); + TRACE(0,"raw req seeker's addr:"); + DUMP8("%02x ", ptr_raw_req->rx_tx.key_based_pairing_req.seeker_addr, 6); + TRACE(1,"fp message type 0x%02x.", ptr_raw_req->rx_tx.raw_req.message_type); + if ((KEY_BASED_PAIRING_REQ == ptr_raw_req->rx_tx.raw_req.message_type) && + ((memcmp(ptr_raw_req->rx_tx.key_based_pairing_req.provider_addr, + app_gfps_env.local_bt_addr.addr , 6)==0) || + (memcmp(ptr_raw_req->rx_tx.key_based_pairing_req.provider_addr, + app_gfps_env.local_le_addr.addr , 6)==0))) + { + write_rsp_status = app_gfps_handle_decrypted_keybase_pairing_request(ptr_raw_req, out_key); + }else{ + TRACE(0,"decrypt false..ingore"); + } + + }else{ + TRACE(1,"error = %x",gfps_state); + } + + } + else if (param->length == GFPSP_KEY_BASED_PAIRING_REQ_LEN_WITHOUT_PUBLIC_KEY) + { + + app_gfps_env.isInitialPairing = false; + bool isDecryptedSuccessful = + app_gfps_decrypt_keybase_pairing_request(( uint8_t * )en_req.en_req, out_key); + TRACE(1,"Decrypt keybase pairing req without public key result: %d", isDecryptedSuccessful); + } + else + { + TRACE(0,"who you are??"); + } + + struct gfpsp_send_write_rsp_t *response = KE_MSG_ALLOC( + GFPSP_SEND_WRITE_RESPONSE, src_id, dest_id, gfpsp_send_write_rsp_t); + *response = param->pendingWriteRsp; + response->status = write_rsp_status; + ke_msg_send(response); + + return (KE_MSG_CONSUMED); +} + +int app_gfps_write_passkey_ind_hander(ke_msg_id_t const msgid, + struct gfpsp_write_ind_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + gfpsp_raw_pass_key_resp raw_rsp; + gfpsp_encrypted_resp en_rsp; + uint8_t decryptdata[16] = {0}; + TRACE(1,"length = %d value = 0x", param->length); + DUMP8("%02X, ", param->data, 16); + gfps_crypto_decrypt(param->data, 16, app_gfps_env.keybase_pair_key, decryptdata); + TRACE(0,"decrypt data =0x"); + TRACE(0,"==============================="); + DUMP8("%02X", decryptdata, 16); + TRACE(0,"==============================="); + + TRACE(0,"pass key = 1-3 bytes"); + + raw_rsp.message_type = 0x03; //Provider's passkey + raw_rsp.passkey[0] = decryptdata[1]; + raw_rsp.passkey[1] = decryptdata[2]; + raw_rsp.passkey[2] = decryptdata[3]; + raw_rsp.reserved[0] = 0x38; //my magic num temp test + raw_rsp.reserved[1] = 0x30; + raw_rsp.reserved[2] = 0x23; + raw_rsp.reserved[3] = 0x30; + raw_rsp.reserved[4] = 0x06; + raw_rsp.reserved[5] = 0x10; + raw_rsp.reserved[6] = 0x05; + raw_rsp.reserved[7] = 0x13; + raw_rsp.reserved[8] = 0x06; + raw_rsp.reserved[9] = 0x12; + raw_rsp.reserved[10] = 0x12; + raw_rsp.reserved[11] = 0x01; + gfps_crypto_encrypt(( const uint8_t * )(&raw_rsp.message_type), sizeof(raw_rsp), app_gfps_env.keybase_pair_key, en_rsp.uint128_array); + app_gfps_send_passkey_via_notification(( uint8_t * )en_rsp.uint128_array, sizeof(en_rsp)); + + return (KE_MSG_CONSUMED); +} + +static int app_gfps_write_name_ind_hander(ke_msg_id_t const msgid, + struct gfpsp_write_ind_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + bool isSuccessful = false; + + if (!app_gfps_env.isPendingForWritingNameReq) + { + TRACE(0,"Pre fp write name request is not received."); + } + else + { + uint8_t rawName[FP_MAX_NAME_LEN]; + + struct gfpsp_write_ind_t* pWriteInd = (struct gfpsp_write_ind_t *)param; + if (app_gfps_env.isInitialPairing) + { + isSuccessful = gfps_decrypt_name(app_gfps_env.aesKeyFromECDH, + pWriteInd->data, &(pWriteInd->data[8]), &(pWriteInd->data[16]), + rawName, pWriteInd->length-16); + } + else + { + isSuccessful = gfps_decrypt_name(app_gfps_env.keybase_pair_key, + pWriteInd->data, &(pWriteInd->data[8]), &(pWriteInd->data[16]), + rawName, pWriteInd->length-16); + } + + TRACE(1,"write name successful flag %d", isSuccessful); + + if (isSuccessful) + { + nv_record_fp_update_name(rawName, pWriteInd->length-16); + TRACE(1,"Rename BT name: [%s]", rawName); + app_gfps_update_local_bt_name(); + #ifdef IBRT + app_tws_send_fastpair_info_to_slave(); + #endif + } + + app_gfps_env.isPendingForWritingNameReq = false; + } + + struct gfpsp_send_write_rsp_t *response = KE_MSG_ALLOC( + GFPSP_SEND_WRITE_RESPONSE, src_id, dest_id, gfpsp_send_write_rsp_t); + *response = param->pendingWriteRsp; + if (isSuccessful) + { + response->status = ATT_ERR_NO_ERROR; + } + else + { + response->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + ke_msg_send(response); + + return (KE_MSG_CONSUMED); +} + +static int app_gfps_write_accountkey_ind_hander(ke_msg_id_t const msgid, + struct gfpsp_write_ind_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + NV_FP_ACCOUNT_KEY_ENTRY_T accountkey; + + TRACE(1,"length = %d value = 0x", param->length); + DUMP8("%02X, ", param->data, FP_ACCOUNT_KEY_SIZE); + gfps_crypto_decrypt(param->data, FP_ACCOUNT_KEY_SIZE, app_gfps_env.keybase_pair_key, accountkey.key); + TRACE(0,"decrypt account key:"); + //TRACE(0,"==============================="); + DUMP8("%02X", accountkey.key, FP_ACCOUNT_KEY_SIZE); + //TRACE(0,"==============================="); + + nv_record_fp_account_key_add(&accountkey); + +#ifdef IBRT + app_tws_send_fastpair_info_to_slave(); +#endif + + // update the BLE ADV as account key has been added + if (!app_is_in_fastpairing_mode()) + { + // restart the BLE adv if it's retro-active pairing + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); + } + return (KE_MSG_CONSUMED); +} + +void app_gfps_set_battery_datatype(GFPS_BATTERY_DATA_TYPE_E batteryDataType) +{ + if (app_gfps_env.batteryDataType != batteryDataType) + { + app_gfps_env.batteryDataType = batteryDataType; + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); + } +} + +GFPS_BATTERY_DATA_TYPE_E app_gfps_get_battery_datatype(void) +{ + return app_gfps_env.batteryDataType; +} + +void app_gfps_enable_battery_info(bool isEnable) +{ + app_gfps_env.isBatteryInfoIncluded = isEnable; + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); +} + +void app_gfps_get_battery_levels(uint8_t *pCount, uint8_t *pBatteryLevel) +{ + *pCount = 0; + if (app_gfps_env.get_battery_info_handler) + { + app_gfps_env.get_battery_info_handler( + pCount, pBatteryLevel); + } +} + +void app_gfps_update_random_salt(void) +{ + app_gfps_env.advRandSalt = (uint8_t)rand(); +} + +uint8_t app_gfps_generate_accountkey_data(uint8_t *outputData) +{ + uint8_t keyCount = nv_record_fp_account_key_count(); + if (0 == keyCount) + { + outputData[0] = 0; + outputData[1] = 0; + return 2; + } + + uint8_t accountKeyData[32]; + accountKeyData[0] = 0; + + uint8_t accountKeyDataLen = 2; + uint8_t hash256Result[32]; + + uint8_t sizeOfFilter = (((uint8_t)(( float )1.2 * keyCount)) + 3); + uint8_t FArray[2 * FP_ACCOUNT_KEY_RECORD_NUM + 3]; + memset(FArray, 0, sizeof(FArray)); + +#if GFPS_ACCOUNTKEY_SALT_TYPE == USE_BLE_ADDR_AS_SALT + uint8_t VArray[FP_ACCOUNT_KEY_SIZE + 6 + 4]; +#else + uint8_t VArray[FP_ACCOUNT_KEY_SIZE + 1 + 4]; + uint8_t randomSalt; + if (GFPS_INITIAL_ADV_RAND_SALT != app_gfps_env.advRandSalt) + { + randomSalt = app_gfps_env.advRandSalt; + } + else + { + randomSalt = (uint8_t)rand(); + } +#endif + + uint8_t index; + + uint8_t batteryFollowingData[1 + GFPS_BATTERY_VALUE_MAX_COUNT]; + uint8_t batteryFollowingDataLen = 0; + + for (uint8_t keyIndex = 0; keyIndex < keyCount; keyIndex++) + { + uint8_t offsetOfVArray; + + nv_record_fp_account_key_get_by_index(keyIndex, VArray); + +#if GFPS_ACCOUNTKEY_SALT_TYPE == USE_BLE_ADDR_AS_SALT + uint8_t *currentBleAddr = appm_get_current_ble_addr(); + for (index = 0; index < 6; index++) + { + VArray[FP_ACCOUNT_KEY_SIZE + index] = currentBleAddr[5 - index]; + } + offsetOfVArray = FP_ACCOUNT_KEY_SIZE + 6; +#else + VArray[FP_ACCOUNT_KEY_SIZE] = randomSalt; + offsetOfVArray = FP_ACCOUNT_KEY_SIZE + 1; +#endif + + if (app_gfps_env.isBatteryInfoIncluded) + { + uint8_t batteryLevelCount = 0; + uint8_t batteryLevel[GFPS_BATTERY_VALUE_MAX_COUNT]; + app_gfps_get_battery_levels(&batteryLevelCount, batteryLevel); + + uint8_t startOffsetOfBatteryInfo = offsetOfVArray; + + VArray[offsetOfVArray++] = app_gfps_env.batteryDataType | (batteryLevelCount << 4); + for (index = 0; index < batteryLevelCount; index++) + { + VArray[offsetOfVArray++] = batteryLevel[index]; + } + + batteryFollowingDataLen = offsetOfVArray - startOffsetOfBatteryInfo; + memcpy(batteryFollowingData, &VArray[startOffsetOfBatteryInfo], batteryFollowingDataLen); + } + + TRACE(0,"To hash256 on:"); + DUMP8("%02x ", VArray, offsetOfVArray); + + gfps_SHA256_hash(VArray, offsetOfVArray, hash256Result); + + // K = Xi % (s * 8) + // F[K/8] = F[K/8] | (1 << (K % 8)) + uint32_t pX[8]; + for (index = 0; index < 8; index++) + { + pX[index] = (((uint32_t)(hash256Result[index * 4])) << 24) | + (((uint32_t)(hash256Result[index * 4 + 1])) << 16) | + (((uint32_t)(hash256Result[index * 4 + 2])) << 8) | + (((uint32_t)(hash256Result[index * 4 + 3])) << 0); + } + + for (index = 0; index < 8; index++) + { + uint32_t K = pX[index] % (sizeOfFilter * 8); + FArray[K / 8] = FArray[K / 8] | (1 << (K % 8)); + } + } + + memcpy(&accountKeyData[2], FArray, sizeOfFilter); + + accountKeyDataLen += sizeOfFilter; + + accountKeyData[1] = (sizeOfFilter<<4); + + +#if GFPS_ACCOUNTKEY_SALT_TYPE==USE_RANDOM_NUM_AS_SALT + accountKeyData[2+sizeOfFilter] = 0x11; + accountKeyData[2 + sizeOfFilter + 1] = randomSalt; + + accountKeyDataLen += 2; +#endif + + TRACE(1,"Generated accountkey data len:%d", accountKeyDataLen); + DUMP8("%02x ", accountKeyData, accountKeyDataLen); + + memcpy(outputData, accountKeyData, accountKeyDataLen); + + memcpy(outputData + accountKeyDataLen, batteryFollowingData, batteryFollowingDataLen); + + return (accountKeyDataLen + batteryFollowingDataLen); +} + +static void gfpsp_update_connection_state(uint8_t conidx) +{ + if (BLE_INVALID_CONNECTION_INDEX == app_gfps_env.connectionIndex) + { + app_gfps_connected_evt_handler(conidx); + } +} + +static int app_gfpsp_key_based_pairing_ntf_handler(ke_msg_id_t const msgid, + struct app_gfps_key_based_notif_config_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + app_gfps_env.isKeyBasedPairingNotificationEnabled = param->isNotificationEnabled; + if (app_gfps_env.isKeyBasedPairingNotificationEnabled) + { + uint8_t conidx = KE_IDX_GET(src_id); + gfpsp_update_connection_state(conidx); + } + + return (KE_MSG_CONSUMED); +} + +static int app_gfpsp_pass_key_ntf_handler(ke_msg_id_t const msgid, + struct app_gfps_pass_key_notif_config_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + app_gfps_env.isPassKeyNotificationEnabled = param->isNotificationEnabled; + if (app_gfps_env.isPassKeyNotificationEnabled) + { + uint8_t conidx = KE_IDX_GET(src_id); + gfpsp_update_connection_state(conidx); + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +const struct ke_msg_handler app_gfps_msg_handler_list[] = + { + {GFPSP_VALUE_REQ_IND, ( ke_msg_func_t )gfpsp_value_req_ind_handler}, + {GFPSP_KEY_BASED_PAIRING_WRITE_IND, ( ke_msg_func_t )app_gfps_write_key_based_pairing_ind_hander}, + {GFPSP_KEY_PASS_KEY_WRITE_IND, ( ke_msg_func_t )app_gfps_write_passkey_ind_hander}, + {GFPSP_KEY_ACCOUNT_KEY_WRITE_IND, ( ke_msg_func_t )app_gfps_write_accountkey_ind_hander}, + {GFPSP_KEY_BASED_PAIRING_NTF_CFG, ( ke_msg_func_t )app_gfpsp_key_based_pairing_ntf_handler}, + {GFPSP_KEY_PASS_KEY_NTF_CFG, ( ke_msg_func_t )app_gfpsp_pass_key_ntf_handler}, + {GFPSP_NAME_WRITE_IND, ( ke_msg_func_t )app_gfps_write_name_ind_hander}, + +}; + +const struct ke_state_handler app_gfps_table_handler = { + &app_gfps_msg_handler_list[0], + (sizeof(app_gfps_msg_handler_list) / sizeof(struct ke_msg_handler)), +}; + +static uint8_t is_in_fastpairing_mode = false; + +bool app_is_in_fastpairing_mode(void) +{ + return is_in_fastpairing_mode; +} + +void app_set_in_fastpairing_mode_flag(bool isEnabled) +{ + is_in_fastpairing_mode = isEnabled; + TRACE(1,"[FP]mode is set to %d", is_in_fastpairing_mode); +} + +void app_exit_fastpairing_mode(void) +{ + + if (app_is_in_fastpairing_mode()) + { + TRACE(0,"[FP]exit fast pair mode"); + app_stop_10_second_timer(APP_FASTPAIR_LASTING_TIMER_ID); + + app_set_in_fastpairing_mode_flag(false); + + // reset ble adv + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); + } +} + +void app_fast_pairing_timeout_timehandler(void) +{ + app_exit_fastpairing_mode(); +} + +void app_enter_fastpairing_mode(void) +{ + TRACE(0,"[FP] enter fast pair mode"); + app_set_in_fastpairing_mode_flag(true); + + app_ble_start_connectable_adv(BLE_FAST_ADVERTISING_INTERVAL); + app_start_10_second_timer(APP_FASTPAIR_LASTING_TIMER_ID); +} + +/*--------------------------------------------------------------------------- + * gfps_ble_data_fill_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * BLE advertisement and scan response data fill handler for Google fast pair + * + * Parameters: + * param - pointer of BLE parameter to be configure + * + * Return: + * void + */ +static void gfps_ble_data_fill_handler(void *param) +{ + TRACE(1,"[%s]+++", __func__); + ASSERT(param, "invalid param"); + + bool adv_enable = false; + BLE_ADV_PARAM_T *advInfo = ( BLE_ADV_PARAM_T * )param; + TRACE(2,"adv data offset:%d, scan response data offset:%d", + advInfo->advDataLen, + advInfo->scanRspDataLen); + +#ifdef IBRT + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TRACE(1,"current role:%s", app_tws_ibrt_role2str(p_ibrt_ctrl->current_role)); + + if (IBRT_SLAVE != p_ibrt_ctrl->current_role && p_ibrt_ctrl->init_done) +#endif + { + TRACE(0,"GFPS data will add in adv data"); + + adv_enable = true; + if (app_is_in_fastpairing_mode()) + { + TRACE(0,"fast pair mode"); + advInfo->advInterval = BLE_FASTPAIR_FAST_ADVERTISING_INTERVAL; + + advInfo->advData[advInfo->advDataLen++] = FP_SERVICE_LEN; + advInfo->advData[advInfo->advDataLen++] = BLE_ADV_SVC_FLAG; + advInfo->advData[advInfo->advDataLen++] = (FP_SERVICE_UUID >> 8) & 0xFF; + advInfo->advData[advInfo->advDataLen++] = (FP_SERVICE_UUID >> 0) & 0xFF; + uint32_t modelId; +#ifndef IS_USE_CUSTOM_FP_INFO + modelId = FP_DEVICE_MODEL_ID; +#else + modelId = app_bt_get_model_id(); +#endif + advInfo->advData[advInfo->advDataLen++] = (modelId >> 16) & 0xFF; + advInfo->advData[advInfo->advDataLen++] = (modelId >> 8) & 0xFF; + advInfo->advData[advInfo->advDataLen++] = (modelId >> 0) & 0xFF; + +#ifndef IS_USE_CUSTOM_FP_INFO + memcpy(&advInfo->advData[advInfo->advDataLen], + APP_GFPS_ADV_POWER_UUID, + APP_GFPS_ADV_POWER_UUID_LEN); +#else + memcpy(&advInfo->advData[advInfo->advDataLen], + app_gfps_power_uuid, + APP_GFPS_ADV_POWER_UUID_LEN); +#endif + advInfo->advDataLen += APP_GFPS_ADV_POWER_UUID_LEN; + } + else + { + TRACE(0,"not in fast pair mode"); + advInfo->advInterval = BLE_FASTPAIR_NORMAL_ADVERTISING_INTERVAL; + +#if BLE_APP_GFPS_VER == FAST_PAIR_REV_2_0 + uint8_t serviceData[32]; + + // service UUID part + serviceData[0] = 0x03; // original length of service length + serviceData[1] = BLE_ADV_SVC_FLAG; + serviceData[2] = (FP_SERVICE_UUID >> 8) & 0xFF;; + serviceData[3] = (FP_SERVICE_UUID >> 0) & 0xFF; + + // account key part + uint8_t dataLen = app_gfps_generate_accountkey_data(&serviceData[4]); + serviceData[0] += dataLen; + memcpy(&advInfo->advData[advInfo->advDataLen], + serviceData, + serviceData[0] + 1); + advInfo->advDataLen += (serviceData[0] + 1); + + // power part + memcpy(&advInfo->advData[advInfo->advDataLen], + APP_GFPS_ADV_POWER_UUID, + APP_GFPS_ADV_POWER_UUID_LEN); + advInfo->advDataLen += APP_GFPS_ADV_POWER_UUID_LEN; +#endif + } + } + + app_ble_data_fill_enable(USER_GFPS, adv_enable); + TRACE(1,"[%s]---", __func__); +} + +void gfps_info_prepare_handler(uint8_t *buf, uint16_t *length) +{ + *length = sizeof(NV_FP_ACCOUNT_KEY_RECORD_T); + + NV_FP_ACCOUNT_KEY_RECORD_T *info = nv_record_get_fp_data_structure_info(); + memcpy(buf, info, *length); +} + +void gfps_info_received_handler(uint8_t *buf, uint16_t length) +{ + NV_FP_ACCOUNT_KEY_RECORD_T *pInfo = ( NV_FP_ACCOUNT_KEY_RECORD_T * )buf; + nv_record_fp_update_all(( uint8_t * )pInfo); +} + +void app_gfps_tws_sync_init(void) +{ +#ifdef IBRT + // TODO: freddie move to isolated ota file + TWS_SYNC_USER_T userGfps = { + gfps_info_prepare_handler, + gfps_info_received_handler, + NULL, + NULL, + NULL, + }; + + app_tws_if_register_sync_user(TWS_SYNC_USER_GFPS_INFO, &userGfps); +#endif +} +static FastPairInfo g_fast_pair_info; +uint32_t app_bt_get_model_id(void) +{ + return g_fast_pair_info.model_id; +} + +extern uint32_t Get_ModelId(); +void app_bt_get_fast_pair_info(void) +{ + g_fast_pair_info.model_id = Get_ModelId(); + switch(g_fast_pair_info.model_id) + { + //default model id(bes moddel id) + case FP_DEVICE_MODEL_ID: + { + memcpy (g_fast_pair_info.public_anti_spoofing_key, + bes_demo_Public_anti_spoofing_key, sizeof(bes_demo_Public_anti_spoofing_key)); + memcpy (g_fast_pair_info.private_anti_spoofing_key, + bes_demo_private_anti_spoofing_key, sizeof(bes_demo_private_anti_spoofing_key)); + } + break; + + //customer add customer model id here; + + default: + { + g_fast_pair_info.model_id = FP_DEVICE_MODEL_ID; + memcpy (g_fast_pair_info.public_anti_spoofing_key, + bes_demo_Public_anti_spoofing_key, sizeof(bes_demo_Public_anti_spoofing_key)); + memcpy (g_fast_pair_info.private_anti_spoofing_key, + bes_demo_private_anti_spoofing_key, sizeof(bes_demo_private_anti_spoofing_key)); + } + } +} + +void app_bt_set_fast_pair_info(FastPairInfo fast_pair_info) +{ + memcpy(&g_fast_pair_info, &fast_pair_info,sizeof(fast_pair_info)); +} + +void app_gfps_set_tx_power_in_adv(char rssi) +{ + app_gfps_power_uuid[APP_GFPS_ADV_POWER_UUID_LEN-1] = rssi; +} + +void app_bt_set_fast_pair_tx_power(int8_t tx_power) { + app_gfps_set_tx_power_in_adv(tx_power); +} + +const uint8_t* app_bt_get_fast_pair_public_key(void) { + return g_fast_pair_info.public_anti_spoofing_key; +} + +const uint8_t* app_bt_get_fast_pair_private_key(void) { + return g_fast_pair_info.private_anti_spoofing_key; +} + +#endif //BLE_APP_GFPS + +/// @} APP diff --git a/services/ble_app/app_gfps/app_gfps.h b/services/ble_app/app_gfps/app_gfps.h new file mode 100644 index 0000000..9e24a55 --- /dev/null +++ b/services/ble_app/app_gfps/app_gfps.h @@ -0,0 +1,264 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef APP_GFPS_H_ +#define APP_GFPS_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * + * @brief Device Information Application Module Entry point. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW Configuration + +#if (BLE_APP_GFPS) + +#include +#ifndef BLE_BD_ADDR_T +///BD Address structure +typedef struct +{ + ///6-byte array address value + uint8_t addr[6]; +} bd_addr_t; +#endif +/* + * DEFINES + **************************************************************************************** + */ +// enable IS_USE_CUSTOM_FP_INFO if wanna use custom fastpair tx power, model id and anti-proof key +#define IS_USE_CUSTOM_FP_INFOx + +/// Manufacturer Name Value +#define APP_GFPS_MANUFACTURER_NAME ("RivieraWaves SAS") +#define APP_GFPS_MANUFACTURER_NAME_LEN (16) + +/// Model Number String Value +#define APP_GFPS_MODEL_NB_STR ("RW-BLE-1.0") +#define APP_GFPS_MODEL_NB_STR_LEN (10) + +/// Serial Number +#define APP_GFPS_SERIAL_NB_STR ("1.0.0.0-LE") +#define APP_GFPS_SERIAL_NB_STR_LEN (10) + +/// Firmware Revision +#define APP_GFPS_FIRM_REV_STR ("6.1.2") +#define APP_GFPS_FIRM_REV_STR_LEN (5) + +/// System ID Value - LSB -> MSB +#define APP_GFPS_SYSTEM_ID ("\x12\x34\x56\xFF\xFE\x9A\xBC\xDE") +#define APP_GFPS_SYSTEM_ID_LEN (8) + +/// Hardware Revision String +#define APP_GFPS_HARD_REV_STR ("1.0.0") +#define APP_GFPS_HARD_REV_STR_LEN (5) + +/// Software Revision String +#define APP_GFPS_SW_REV_STR ("6.3.0") +#define APP_GFPS_SW_REV_STR_LEN (5) + +/// IEEE +#define APP_GFPS_IEEE ("\xFF\xEE\xDD\xCC\xBB\xAA") +#define APP_GFPS_IEEE_LEN (6) + +/** + * PNP ID Value - LSB -> MSB + * Vendor ID Source : 0x02 (USB Implementer’s Forum assigned Vendor ID value) + * Vendor ID : 0x045E (Microsoft Corp) + * Product ID : 0x0040 + * Product Version : 0x0300 + */ +#define APP_GFPS_PNP_ID ("\x02\x5E\x04\x40\x00\x00\x03") +#define APP_GFPS_PNP_ID_LEN (7) + +#define APP_GFPS_ADV_POWER_UUID "\x02\x0a\xf5" +#define APP_GFPS_ADV_POWER_UUID_LEN (3) +#define APP_GFPS_ADV_APPEARANCE_UUID "\x03\x19\xda\x96" +#define APP_GFPS_ADV_APPEARANCE_UUID_LEN (4) +#define APP_GFPS_ADV_MANU_SPE_UUID_TEST "\x07\xFF\xe0\x00\x01\x5B\x32\x01" +#define APP_GFPS_ADV_MANU_SPE_UUID_LEN (8) + +#if (BLE_APP_HID) +#define APP_GFPS_FEATURES (GFPSP_MANUFACTURER_NAME_CHAR_SUP |\ + GFPSP_MODEL_NB_STR_CHAR_SUP |\ + GFPSP_SYSTEM_ID_CHAR_SUP |\ + GFPSP_PNP_ID_CHAR_SUP) +#else +#define APP_GFPS_FEATURES (GFPSP_ALL_FEAT_SUP) +#endif //(BLE_APP_HID) +typedef void (*gfps_enter_pairing_mode)(void); +typedef uint8_t (*gfps_bt_io_cap_set)(uint8_t mode); +typedef uint8_t (*gfps_bt_io_authrequirements_set)(uint8_t authrequirements); + +typedef void (*gfps_get_battery_info_handler)(uint8_t* batteryValueCount, + uint8_t* batteryValue); + +typedef enum +{ + HIDE_SUBSEQUENT_INDICATION = 2, + SHOW_UI_INDICATION = 3, + HIDE_UI_INDICATION = 4 +} GFPS_BATTERY_DATA_TYPE_E; + +typedef enum +{ + BATTERY_NOT_CHARGING = 0, + BATTERY_CHARGING = 1, +} GFPS_BATTERY_STATUS_E; + +#define GFPS_BATTERY_VALUE_MAX_COUNT 3 + +struct app_gfps_env_tag +{ + uint8_t connectionIndex; + uint8_t isKeyBasedPairingNotificationEnabled; + uint8_t isPassKeyNotificationEnabled; + uint8_t isInitialPairing; + bd_addr_t seeker_bt_addr; + bd_addr_t local_le_addr; + bd_addr_t local_bt_addr; + uint8_t keybase_pair_key[16]; + uint8_t aesKeyFromECDH[16]; + gfps_enter_pairing_mode enter_pairing_mode; + gfps_bt_io_cap_set bt_set_iocap; + gfps_bt_io_authrequirements_set bt_set_authrequirements; + uint8_t bt_iocap; + uint8_t bt_authrequirements; + uint8_t pendingLastResponse[16]; + uint8_t isLastResponsePending; + uint8_t isWaitingForFpToConnect; + uint8_t isPendingForWritingNameReq; + uint8_t isBatteryInfoIncluded; + gfps_get_battery_info_handler get_battery_info_handler; + GFPS_BATTERY_DATA_TYPE_E batteryDataType; + uint8_t advRandSalt; + uint8_t isInFastPairing; +}; + +typedef struct { + uint32_t model_id; + uint8_t public_anti_spoofing_key[64]; + uint8_t private_anti_spoofing_key[32]; +} FastPairInfo; + +/* + * GLOBAL VARIABLES DECLARATION + **************************************************************************************** + */ + +/// Table of message handlers +extern const struct ke_state_handler app_gfps_table_handler; + +/* + * GLOBAL FUNCTIONS DECLARATION + **************************************************************************************** + */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + **************************************************************************************** + * @brief Initialize Device Information Service Application + **************************************************************************************** + */ +void app_gfps_init(void); + +/** + **************************************************************************************** + * @brief Add a Device Information Service instance in the DB + **************************************************************************************** + */ +void app_gfps_add_gfps(void); + +/** + **************************************************************************************** + * @brief Enable the Device Information Service + **************************************************************************************** + */ +void app_gfps_enable_prf(uint16_t conhdl); + +void app_gfps_connected_evt_handler(uint8_t conidx); +void app_gfps_disconnected_evt_handler(uint8_t conidx); + +void app_gfps_set_bt_access_mode(gfps_enter_pairing_mode cb); +void app_gfps_set_io_cap(gfps_bt_io_cap_set cb); +void app_gfps_set_authrequirements(gfps_bt_io_authrequirements_set cb); + +void app_gfps_generate_accountkey_filter(uint8_t* accountKeyFilter, uint8_t* filterSize); + +uint8_t app_gfps_generate_accountkey_data(uint8_t* outputData); + +void app_gfps_set_battery_info_acquire_handler(gfps_get_battery_info_handler cb); +void app_gfps_set_battery_datatype(GFPS_BATTERY_DATA_TYPE_E batteryDataType); +GFPS_BATTERY_DATA_TYPE_E app_gfps_get_battery_datatype(void); + +void app_enter_fastpairing_mode(void); + +void app_exit_fastpairing_mode(void); + +bool app_is_in_fastpairing_mode(void); + +void app_set_in_fastpairing_mode_flag(bool isEnabled); + +uint8_t* app_gfps_get_last_response(void); + +void app_gfps_enter_connectable_mode_req_handler(uint8_t* response); + +bool app_gfps_is_last_response_pending(void); + +void app_gfps_enable_battery_info(bool isEnable); + +void app_fast_pair_timeout_handler(void); + +bool app_is_mobile_connected_via_fastpair(void); + +void app_gfps_get_battery_levels(uint8_t* pCount, uint8_t* pBatteryLevel); + +void app_gfps_update_random_salt(void); + +void app_gfps_tws_sync_init(void); + +void app_bt_set_fast_pair_info(FastPairInfo fast_pair_info); + +uint32_t app_bt_get_model_id(void); + +const uint8_t* app_bt_get_fast_pair_public_key(void); + +const uint8_t* app_bt_get_fast_pair_private_key(void); + +void app_bt_get_fast_pair_info(void); + + + +#ifdef __cplusplus +} +#endif + +#endif //BLE_APP_GFPS + +/// @} APP + +#endif //APP_GFPS_H_ diff --git a/services/ble_app/app_hid/app_hid.c b/services/ble_app/app_hid/app_hid.c new file mode 100644 index 0000000..206c667 --- /dev/null +++ b/services/ble_app/app_hid/app_hid.c @@ -0,0 +1,944 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#include +#include + +#if (BLE_APP_HID) + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "app.h" // Application Definitions +#include "app_sec.h" // Application Security Module API +#include "app_task.h" // Application task definitions +#include "app_hid.h" // HID Application Module Definitions +#include "hogpd_task.h" // HID Over GATT Profile Device Role Functions +#include "prf_types.h" // Profile common types Definition +#include "arch.h" // Platform Definitions +#include "prf.h" +#include "ke_timer.h" // kernel timer + +#if (NVDS_SUPPORT) +#include "nvds.h" // NVDS Definitions +#endif //(NVDS_SUPPORT) + +#if (DISPLAY_SUPPORT) +#include "app_display.h" // Application Display Module +#endif //(DISPLAY_SUPPORT) + +#include "co_utils.h" // Common functions + +#if (KE_PROFILING) +#include "ke_mem.h" +#endif //(KE_PROFILING) + +/* + * DEFINES + **************************************************************************************** + */ + +/// Length of the HID Mouse Report +#define APP_HID_MOUSE_REPORT_LEN (6) +/// Length of the Report Descriptor for an HID Mouse +#define APP_HID_MOUSE_REPORT_MAP_LEN (sizeof(app_hid_mouse_report_map)) + +/// Duration before connection update procedure if no report received (mouse is silent) - 20s +#define APP_HID_SILENCE_DURATION_1 (2000) +/// Duration before disconnection if no report is received after connection update - 60s +#define APP_HID_SILENCE_DURATION_2 (6000) + +/// Number of reports that can be sent +#define APP_HID_NB_SEND_REPORT (10) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// States of the Application HID Module +enum app_hid_states +{ + /// Module is disabled (Service not added in DB) + APP_HID_DISABLED, + /// Module is idle (Service added but profile not enabled) + APP_HID_IDLE, + /// Module is enabled (Device is connected and the profile is enabled) + APP_HID_ENABLED, + /// The application can send reports + APP_HID_READY, + /// Waiting for a report + APP_HID_WAIT_REP, + + APP_HID_STATE_MAX, +}; + +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// HID Application Module Environment Structure +static struct app_hid_env_tag app_hid_env; + +/// HID Mouse Report Descriptor +static const uint8_t app_hid_mouse_report_map[] = +{ + /** + * -------------------------------------------------------------------------- + * Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * -------------------------------------------------------------------------- + * Byte 0 | Not Used | Middle| Right | Left | + * -------------------------------------------------------------------------- + * Byte 1 | X Axis Relative Movement | + * -------------------------------------------------------------------------- + * Byte 2 | Y Axis Relative Movement | + * -------------------------------------------------------------------------- + * Byte 3 | Wheel Relative Movement | + * -------------------------------------------------------------------------- + */ + + 0x05, 0x01, /// USAGE PAGE (Generic Desktop) + 0x09, 0x02, /// USAGE (Mouse) + 0xA1, 0x01, /// COLLECTION (Application) + 0x85, 0x01, /// REPORT ID (1) - MANDATORY + 0x09, 0x01, /// USAGE (Pointer) + 0xA1, 0x00, /// COLLECTION (Physical) + + /** + * ---------------------------------------------------------------------------- + * BUTTONS + * ---------------------------------------------------------------------------- + */ + 0x05, 0x09, /// USAGE PAGE (Buttons) + 0x19, 0x01, /// USAGE MINIMUM (1) + 0x29, 0x08, /// USAGE MAXIMUM (8) + 0x15, 0x00, /// LOGICAL MINIMUM (0) + 0x25, 0x01, /// LOGICAL MAXIMUM (1) + 0x75, 0x01, /// REPORT SIZE (1) + 0x95, 0x08, /// REPORT COUNT (8) + 0x81, 0x02, /// INPUT (Data, Variable, Absolute) + + /** + * ---------------------------------------------------------------------------- + * MOVEMENT DATA + * ---------------------------------------------------------------------------- + */ + 0x05, 0x01, /// USAGE PAGE (Generic Desktop) + 0x16, 0x08, 0xFF, /// LOGICAL MINIMUM (-255) + 0x26, 0xFF, 0x00, /// LOGICAL MAXIMUM (255) + 0x75, 0x10, /// REPORT SIZE (16) + 0x95, 0x02, /// REPORT COUNT (2) + 0x09, 0x30, /// USAGE (X) + 0x09, 0x31, /// USAGE (Y) + 0x81, 0x06, /// INPUT (Data, Variable, Relative) + + 0x15, 0x81, /// LOGICAL MINIMUM (-127) + 0x25, 0x7F, /// LOGICAL MAXIMUM (127) + 0x75, 0x08, /// REPORT SIZE (8) + 0x95, 0x01, /// REPORT COUNT (1) + 0x09, 0x38, /// USAGE (Wheel) + 0x81, 0x06, /// INPUT (Data, Variable, Relative) + + 0xC0, /// END COLLECTION (Physical) + 0xC0 /// END COLLECTION (Application) +}; + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +void app_hid_init(void) +{ +#if (NVDS_SUPPORT) + // Length of the mouse timeout value + uint8_t length = NVDS_LEN_MOUSE_TIMEOUT; +#endif + + // Reset the environment + memset(&app_hid_env, 0, sizeof(app_hid_env)); + + app_hid_env.nb_report = APP_HID_NB_SEND_REPORT; + + /* + * Get the timeout value from the NVDS - This value is used each time a report is received + * from the PS2 driver, store it in the environment. + */ +#if (NVDS_SUPPORT) + if (nvds_get(NVDS_TAG_MOUSE_TIMEOUT, &length, (uint8_t *)&app_hid_env.timeout) != NVDS_OK) +#endif + { + app_hid_env.timeout = APP_HID_SILENCE_DURATION_1; + } +} + + +/* + **************************************************************************************** + * @brief Function called when get GAP manager command complete events. + * + **************************************************************************************** + */ +void app_hid_start_mouse(void) +{ + /*----------------------------------------------------------------------------------- + * CONFIGURE THE MOUSE + *----------------------------------------------------------------------------------*/ + #if (PS2_SUPPORT) + // Default mouse rate (200 report/s) + uint8_t rate = 200; + + #if (NVDS_SUPPORT) + uint8_t length = NVDS_LEN_MOUSE_SAMPLE_RATE; + + // Get sample rate from NVDS + if (nvds_get(NVDS_TAG_MOUSE_SAMPLE_RATE, &length, &rate) == NVDS_OK) + { + // Check if value is among supported set + if ((rate != 10) && (rate != 20) && (rate != 40) && (rate != 60) && + (rate != 80) && (rate != 100) && (rate != 200) ) + { + // Default value + rate = 200; + } + } + #endif //(NVDS_SUPPORT) + + // Start PS2_mouse + ps2_mouse_start(rate, &app_hid_send_mouse_report); + #endif //(PS2_SUPPORT) +} + +void app_hid_add_hids(void) +{ + struct hogpd_db_cfg *db_cfg; + // Prepare the HOGPD_CREATE_DB_REQ message + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, TASK_APP, + gapm_profile_task_add_cmd, sizeof(struct hogpd_db_cfg)); + + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX>1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE)|PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + + req->prf_task_id = TASK_ID_HOGPD; + req->app_task = TASK_APP; + req->start_hdl = 0; + + // Set parameters + db_cfg = (struct hogpd_db_cfg* ) req->param; + + // Only one HIDS instance is useful + db_cfg->hids_nb = 1; + + // The device is a mouse + db_cfg->cfg[0].svc_features = HOGPD_CFG_MOUSE; + + // Only one Report Characteristic is requested + db_cfg->cfg[0].report_nb = 1; + /// db_cfg->cfg[0].report_id = 1; + db_cfg->cfg[0].report_id[0] = 1; + + // The report is an input report + db_cfg->cfg[0].report_char_cfg[0] = HOGPD_CFG_REPORT_IN; + + // HID Information + db_cfg->cfg[0].hid_info.bcdHID = 0x0111; // HID Version 1.11 + db_cfg->cfg[0].hid_info.bCountryCode = 0x00; + db_cfg->cfg[0].hid_info.flags = HIDS_REMOTE_WAKE_CAPABLE | HIDS_NORM_CONNECTABLE; + + // Send the message + ke_msg_send(req); +} + + + + +/* + **************************************************************************************** + * @brief Function called when get connection complete event from the GAP + * + **************************************************************************************** + */ +void app_hid_enable_prf(uint8_t conidx) +{ + // Requested connection parameters + struct gapc_conn_param conn_param; + + uint16_t ntf_cfg; + + // Store the connection handle + app_hid_env.conidx = conidx; + + // Allocate the message + struct hogpd_enable_req * req = KE_MSG_ALLOC(HOGPD_ENABLE_REQ, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_HOGPD), conidx), + TASK_APP, + hogpd_enable_req); + + // Fill in the parameter structure + req->conidx = conidx; + // Notifications are disabled + ntf_cfg = 0; + + // Go to Enabled state + app_hid_env.state = APP_HID_ENABLED; + + #if (NVDS_SUPPORT) + // If first connection with the peer device + if (app_sec_get_bond_status()) + { + // Length of the value read in NVDS + uint8_t length = NVDS_LEN_MOUSE_NTF_CFG; + // Notification configuration + + if (nvds_get(NVDS_TAG_MOUSE_NTF_CFG, &length, (uint8_t *)&ntf_cfg) != NVDS_OK) + { + // If we are bonded this information should be present in the NVDS + ASSERT_ERR(0); + } + + // CCC enable notification + if ((ntf_cfg & HOGPD_CFG_REPORT_NTF_EN ) != 0) + { + // The device is ready to send reports to the peer device + app_hid_env.state = APP_HID_READY; + app_hid_env.nb_report = APP_HID_NB_SEND_REPORT; + + // Restart the mouse timeout timer if needed + if (app_hid_env.timeout != 0) + { + ke_timer_set(APP_HID_MOUSE_TIMEOUT_TIMER, TASK_APP, (uint16_t)(app_hid_env.timeout)); + app_hid_env.timer_enabled = true; + } + } + } + #endif //(NVDS_SUPPORT) + + req->ntf_cfg[conidx] = ntf_cfg; + + /* + * Requested connection interval: 10ms + * Latency: 25 + * Supervision Timeout: 2s + */ + conn_param.intv_min = 8; + conn_param.intv_max = 8; + conn_param.latency = 25; + conn_param.time_out = 200; + + appm_update_param(conidx, &conn_param); + + // Send the message + ke_msg_send(req); +} + +/* + **************************************************************************************** + * @brief Function called from PS2 driver + * + **************************************************************************************** + */ +void app_hid_send_mouse_report(struct ps2_mouse_msg report) +{ + +// app_display_update_hid_value_screen(report.b, report.x, report.y, report.w); + + switch (app_hid_env.state) + { + case (APP_HID_READY): + { + // Check if the report can be sent + if (app_hid_env.nb_report) + { + // Buffer used to create the Report + uint8_t report_buff[APP_HID_MOUSE_REPORT_LEN]; + // X, Y and wheel relative movements + int16_t x; + int16_t y; + + #if (DISPLAY_SUPPORT) + // Display all the received information on the LCD screen + //app_display_update_hid_value_screen(report.b, report.x, report.y, report.w); + #endif //(DISPLAY_SUPPORT) + + // Clean the report buffer + memset(&report_buff[0], 0, APP_HID_MOUSE_REPORT_LEN); + + // Set the button states + report_buff[0] = (report.b & 0x07); + + // If X value is negative + if (report.b & 0x10) + { + report.x = ~report.x; + report.x += 1; + x = (int16_t)report.x; + x *= (-1); + } + else + { + x = (int16_t)report.x; + } + + // If Y value is negative + if (report.b & 0x20) + { + report.y = ~report.y; + report.y += 1; + y = (int16_t)report.y; + } + else + { + y = (int16_t)report.y; + y *= (-1); + } + + + // Set the X and Y movement value in the report + co_write16p(&report_buff[1], x); + co_write16p(&report_buff[3], y); + report_buff[5] =(signed char) (-1) * report.w; + + // Allocate the HOGPD_REPORT_UPD_REQ message + struct hogpd_report_upd_req * req = KE_MSG_ALLOC_DYN(HOGPD_REPORT_UPD_REQ, + prf_get_task_from_id(TASK_ID_HOGPD), + TASK_APP, + hogpd_report_upd_req, + APP_HID_MOUSE_REPORT_LEN); + + req->conidx = app_hid_env.conidx; + //now fill report + req->report.hid_idx = app_hid_env.conidx; + req->report.type = HOGPD_REPORT; //HOGPD_BOOT_MOUSE_INPUT_REPORT;// + req->report.idx = 0; //0 for boot reports and report map + req->report.length = APP_HID_MOUSE_REPORT_LEN; + memcpy(&req->report.value[0], &report_buff[0], APP_HID_MOUSE_REPORT_LEN); + + ke_msg_send(req); + + app_hid_env.nb_report--; + + // Restart the mouse timeout timer if needed + if (app_hid_env.timeout != 0) + { + ke_timer_set(APP_HID_MOUSE_TIMEOUT_TIMER, TASK_APP, (uint16_t)(app_hid_env.timeout)); + app_hid_env.timer_enabled = true; + } + } + } break; + + case (APP_HID_WAIT_REP): + { + // Requested connection parameters + struct gapc_conn_param conn_param; + + /* + * Requested connection interval: 10ms + * Latency: 25 + * Supervision Timeout: 2s + */ + conn_param.intv_min = 8; + conn_param.intv_max = 8; + conn_param.latency = 25; + conn_param.time_out = 200; + + appm_update_param(app_hid_env.conidx, &conn_param); + + // Restart the mouse timeout timer if needed + if (app_hid_env.timeout != 0) + { + ke_timer_set(APP_HID_MOUSE_TIMEOUT_TIMER, TASK_APP, (uint16_t)(app_hid_env.timeout)); + app_hid_env.timer_enabled = true; + } + + // Go back to the ready state + app_hid_env.state = APP_HID_READY; + } break; + + case (APP_HID_IDLE): + { + // Try to restart advertising if needed + } break; + + // DISABLE and ENABLED states + default: + { + // Drop the message + } break; + } + + #if (KE_PROFILING) +// app_display_hdl_env_size(0xFFFF, ke_get_mem_usage(KE_MEM_ENV)); +// app_display_hdl_db_size(0xFFFF, ke_get_mem_usage(KE_MEM_ATT_DB)); +// app_display_hdl_msg_size((uint16_t)ke_get_max_mem_usage(), ke_get_mem_usage(KE_MEM_KE_MSG)); + #endif //(KE_PROFILING) +} + + +/* + * MESSAGE HANDLERS + **************************************************************************************** + */ + + +static int hogpd_ctnl_pt_ind_handler(ke_msg_id_t const msgid, + struct hogpd_ctnl_pt_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + + if (param->conidx == app_hid_env.conidx) + { + //make use of param->hid_ctnl_pt + struct hogpd_report_cfm *req = KE_MSG_ALLOC_DYN(HOGPD_REPORT_CFM, + prf_get_task_from_id(TASK_ID_HOGPD),/* src_id */ + TASK_APP, + hogpd_report_cfm, + 0); + + req->conidx = param->conidx; ///app_hid_env.conidx; ///??? + /// Operation requested (read/write @see enum hogpd_op) + req->operation = HOGPD_OP_REPORT_WRITE; + /// Status of the request + req->status = GAP_ERR_NO_ERROR; ///??? + /// Report Info + //req->report; + /// HIDS Instance + req->report.hid_idx = app_hid_env.conidx; ///??? + /// type of report (@see enum hogpd_report_type) + req->report.type = -1;//outside + /// Report Length (uint8_t) + req->report.length = 0; + /// Report Instance - 0 for boot reports and report map + req->report.idx = 0; + /// Report data + + + // Send the message + ke_msg_send(req); + } + return (KE_MSG_CONSUMED); +} + + + + +static int hogpd_ntf_cfg_ind_handler(ke_msg_id_t const msgid, + struct hogpd_ntf_cfg_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if (app_hid_env.conidx == param->conidx) + { + if ((param->ntf_cfg[param->conidx] & HOGPD_CFG_REPORT_NTF_EN ) != 0) + { + // The device is ready to send reports to the peer device + app_hid_env.state = APP_HID_READY; + } + else + { + // Come back to the Enabled state + if (app_hid_env.state == APP_HID_READY) + { + app_hid_env.state = APP_HID_ENABLED; + } + } + +#if (NVDS_SUPPORT) + // Store the notification configuration in the database + if (nvds_put(NVDS_TAG_MOUSE_NTF_CFG, NVDS_LEN_MOUSE_NTF_CFG, + (uint8_t *)¶m->ntf_cfg[param->conidx]) != NVDS_OK) + { + // Should not happen + ASSERT_ERR(0); + } +#endif + } + + return (KE_MSG_CONSUMED); +} + +static int hogpd_report_req_ind_handler(ke_msg_id_t const msgid, + struct hogpd_report_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + if ((param->operation == HOGPD_OP_REPORT_READ) && (param->report.type == HOGPD_REPORT_MAP)) + { + struct hogpd_report_cfm *req = KE_MSG_ALLOC_DYN(HOGPD_REPORT_CFM, + src_id, ///prf_get_task_from_id(TASK_ID_HOGPD),/* src_id */ + dest_id, ///TASK_APP, + hogpd_report_cfm, + APP_HID_MOUSE_REPORT_MAP_LEN); + + req->conidx = app_hid_env.conidx; ///??? + /// Operation requested (read/write @see enum hogpd_op) + req->operation = HOGPD_OP_REPORT_READ; + /// Status of the request + req->status = GAP_ERR_NO_ERROR; ///??? + /// Report Info + //req->report; + /// HIDS Instance + req->report.hid_idx = param->report.hid_idx;/// ???///app_hid_env.conidx; ///??? + /// type of report (@see enum hogpd_report_type) + req->report.type = HOGPD_REPORT_MAP; + /// Report Length (uint8_t) + req->report.length = APP_HID_MOUSE_REPORT_MAP_LEN; + /// Report Instance - 0 for boot reports and report map + req->report.idx = 0; + /// Report data + memcpy(&req->report.value[0], &app_hid_mouse_report_map[0], APP_HID_MOUSE_REPORT_MAP_LEN); + + // Send the message + ke_msg_send(req); + } + else + { + if (param->report.type == HOGPD_BOOT_MOUSE_INPUT_REPORT) + { //request of boot mouse report + struct hogpd_report_cfm *req = KE_MSG_ALLOC_DYN(HOGPD_REPORT_CFM, + prf_get_task_from_id(TASK_ID_HOGPD),/* src_id */ + TASK_APP, + hogpd_report_cfm, + 0/*param->report.length*/); + + req->conidx = param->conidx; ///app_hid_env.conidx; ///??? + /// Operation requested (read/write @see enum hogpd_op) + req->operation = HOGPD_OP_REPORT_READ; + /// Status of the request + req->status = GAP_ERR_NO_ERROR; ///??? + /// HIDS Instance + req->report.hid_idx = app_hid_env.conidx; ///??? + /// type of report (@see enum hogpd_report_type) + req->report.type = param->report.type;//-1;//outside + /// Report Length (uint8_t) + req->report.length = 0; //param->report.length; + /// Report Instance - 0 for boot reports and report map + req->report.idx = param->report.idx; //0; + /// Report data + + // Send the message + ke_msg_send(req); + } + else + if (param->report.type == HOGPD_REPORT) + { //request of mouse report + struct hogpd_report_cfm *req = KE_MSG_ALLOC_DYN(HOGPD_REPORT_CFM, + prf_get_task_from_id(TASK_ID_HOGPD),/* src_id */ + TASK_APP, + hogpd_report_cfm, + 8/*param->report.length*/); + + req->conidx = param->conidx; ///app_hid_env.conidx; ///??? + /// Operation requested (read/write @see enum hogpd_op) + req->operation = HOGPD_OP_REPORT_READ; + /// Status of the request + req->status = GAP_ERR_NO_ERROR; ///??? + /// Report Info + //req->report; + /// HIDS Instance + req->report.hid_idx = app_hid_env.conidx; ///??? + /// type of report (@see enum hogpd_report_type) + req->report.type = param->report.type;//-1;//outside + /// Report Length (uint8_t) + req->report.length = 8; //param->report.length; + /// Report Instance - 0 for boot reports and report map + req->report.idx = param->report.idx; //0; + /// Report data + memset(&req->report.value[0], 0, 8); //??? + req->report.value[0] = param->report.hid_idx; /// HIDS Instance + req->report.value[1] = param->report.type; /// type of report (@see enum hogpd_report_type) + req->report.value[2] = param->report.length; /// Report Length (uint8_t) + req->report.value[3] = param->report.idx; /// Report Instance - 0 for boot reports and report map + + // Send the message + ke_msg_send(req); + } + else + { + struct hogpd_report_cfm *req = KE_MSG_ALLOC_DYN(HOGPD_REPORT_CFM, + prf_get_task_from_id(TASK_ID_HOGPD),/* src_id */ + TASK_APP, + hogpd_report_cfm, + 8/*param->report.length*/); + + req->conidx = param->conidx; ///app_hid_env.conidx; ///??? + /// Operation requested (read/write @see enum hogpd_op) + req->operation = HOGPD_OP_REPORT_READ; + /// Status of the request + req->status = GAP_ERR_NO_ERROR; ///??? + /// Report Info + //req->report; + /// HIDS Instance + req->report.hid_idx = app_hid_env.conidx; ///??? + /// type of report (@see enum hogpd_report_type) + req->report.type = param->report.type;//-1;//outside + /// Report Length (uint8_t) + req->report.length = 8; //param->report.length; + /// Report Instance - 0 for boot reports and report map + req->report.idx = param->report.idx; //0; + /// Report data + memset(&req->report.value[0], 0, 8); //??? + req->report.value[0] = param->report.hid_idx; /// HIDS Instance + req->report.value[1] = param->report.type; /// type of report (@see enum hogpd_report_type) + req->report.value[2] = param->report.length; /// Report Length (uint8_t) + req->report.value[3] = param->report.idx; /// Report Instance - 0 for boot reports and report map + + // Send the message + ke_msg_send(req); + } + } + + return (KE_MSG_CONSUMED); +} + +static int hogpd_proto_mode_req_ind_handler(ke_msg_id_t const msgid, + struct hogpd_proto_mode_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + if ((param->conidx == app_hid_env.conidx) && (param->operation == HOGPD_OP_PROT_UPDATE)) + { + + //make use of param->proto_mode + struct hogpd_proto_mode_cfm *req = KE_MSG_ALLOC_DYN(HOGPD_PROTO_MODE_CFM, + prf_get_task_from_id(TASK_ID_HOGPD),/* src_id */ + TASK_APP, + hogpd_proto_mode_cfm, + 0); + /// Connection Index + req->conidx = app_hid_env.conidx; + /// Status of the request + req->status = GAP_ERR_NO_ERROR; + /// HIDS Instance + req->hid_idx = app_hid_env.conidx; + /// New Protocol Mode Characteristic Value + req->proto_mode = param->proto_mode; + + + // Send the message + ke_msg_send(req); + } + else + { + struct hogpd_proto_mode_cfm *req = KE_MSG_ALLOC_DYN(HOGPD_PROTO_MODE_CFM, + prf_get_task_from_id(TASK_ID_HOGPD),/* src_id */ + TASK_APP, + hogpd_proto_mode_cfm, + 0); + /// Status of the request + req->status = ATT_ERR_APP_ERROR; + + /// Connection Index + req->conidx = app_hid_env.conidx; + /// HIDS Instance + req->hid_idx = app_hid_env.conidx; + /// New Protocol Mode Characteristic Value + req->proto_mode = param->proto_mode; + + // Send the message + ke_msg_send(req); + } + return (KE_MSG_CONSUMED); +} + + +static int hogpd_report_upd_handler(ke_msg_id_t const msgid, + struct hogpd_report_upd_rsp const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if (app_hid_env.conidx == param->conidx) + { + if (GAP_ERR_NO_ERROR == param->status) + { + if (app_hid_env.nb_report < APP_HID_NB_SEND_REPORT) + { + app_hid_env.nb_report++; + } + } + else + { + // we get this message if error occur while sending report + // most likely - disconnect + // Go back to the ready state + app_hid_env.state = APP_HID_IDLE; + // change mode + // restart adv + // Try to restart advertising if needed + //report was not success - need to restart??? + } + } + return (KE_MSG_CONSUMED); +} + +static int hogpd_enable_rsp_handler(ke_msg_id_t const msgid, + struct hogpd_enable_rsp const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Function called when the APP_HID_MOUSE_TIMEOUT_TIMER expires. + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int app_hid_mouse_timeout_timer_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + app_hid_env.timer_enabled = false; + + if (app_hid_env.state == APP_HID_READY) + { + // Requested connection parameters + struct gapc_conn_param conn_param; + // Length +#if (NVDS_SUPPORT) + uint8_t length = NVDS_LEN_MOUSE_TIMEOUT; +#endif + // Timer value + uint16_t timer_val; + + /* + * Request an update of the connection parameters + * Requested connection interval: 10ms + * Latency: 200 + * Supervision Timeout: 5s + */ + conn_param.intv_min = 8; + conn_param.intv_max = 8; + conn_param.latency = 200; + conn_param.time_out = 500; + + appm_update_param(app_hid_env.conidx, &conn_param); + + // Go to the Wait for Report state + app_hid_env.state = APP_HID_WAIT_REP; + +#if (NVDS_SUPPORT) + // Get the timer value from the NVDS + if (nvds_get(NVDS_TAG_MOUSE_ENERGY_SAFE, &length, (uint8_t *)&timer_val) != NVDS_OK) +#endif + { + timer_val = APP_HID_SILENCE_DURATION_2; + } + + // Relaunch the timer + ke_timer_set(APP_HID_MOUSE_TIMEOUT_TIMER, TASK_APP, timer_val); + app_hid_env.timer_enabled = true; + } + else if (app_hid_env.state == APP_HID_WAIT_REP) + { + // Disconnect the link with the device + appm_disconnect(app_hid_env.conidx); + + + // Go back to the ready state + app_hid_env.state = APP_HID_IDLE; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int app_hid_msg_dflt_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Drop the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Set the value of the Report Map Characteristic in the database + **************************************************************************************** + */ +void app_hid_set_report_map(void); + +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +const struct ke_msg_handler app_hid_msg_handler_list[] = +{ + // Note: first message is latest message checked by kernel so default is put on top. + {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_hid_msg_dflt_handler}, + + {HOGPD_ENABLE_RSP, (ke_msg_func_t)hogpd_enable_rsp_handler}, +/// notification configuration changed + {HOGPD_NTF_CFG_IND, (ke_msg_func_t)hogpd_ntf_cfg_ind_handler}, + {HOGPD_REPORT_REQ_IND, (ke_msg_func_t)hogpd_report_req_ind_handler}, + {HOGPD_PROTO_MODE_REQ_IND, (ke_msg_func_t)hogpd_proto_mode_req_ind_handler}, + + {HOGPD_CTNL_PT_IND, (ke_msg_func_t)hogpd_ctnl_pt_ind_handler}, + + {HOGPD_REPORT_UPD_RSP, (ke_msg_func_t)hogpd_report_upd_handler}, + {APP_HID_MOUSE_TIMEOUT_TIMER, (ke_msg_func_t)app_hid_mouse_timeout_timer_handler}, +}; + +const struct ke_state_handler app_hid_table_handler = + {&app_hid_msg_handler_list[0], (sizeof(app_hid_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif //(BLE_APP_HID) + +/// @} APP diff --git a/services/ble_app/app_hid/app_hid.h b/services/ble_app/app_hid/app_hid.h new file mode 100644 index 0000000..16bf26f --- /dev/null +++ b/services/ble_app/app_hid/app_hid.h @@ -0,0 +1,138 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef APP_HID_H_ +#define APP_HID_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * @ingroup RICOW + * + * @brief HID Application Module entry point + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_HID) + +#include // Standard Integer Definition +#include "ke_task.h" // Kernel Task Definition + +#if (PS2_SUPPORT) +#include "ps2.h" // PS2 Mouse Driver +#endif //(PS2_SUPPORT) + +/* + * STRUCTURES DEFINITION + **************************************************************************************** + */ + +/// HID Application Module Environment Structure +struct app_hid_env_tag +{ + /// Connection handle + uint8_t conidx; + /// Mouse timeout value + uint16_t timeout; + /// Internal state of the module + uint8_t state; + /// Timer enabled + bool timer_enabled; + /// Number of report that can be sent + uint8_t nb_report; +}; + +struct ps2_mouse_msg +{ + int16_t x; + int16_t y; + int16_t b; + int16_t w; +}; + +/* + * GLOBAL VARIABLES DECLARATIONS + **************************************************************************************** + */ + +/// Table of message handlers +extern const struct ke_state_handler app_hid_table_handler; + +/* + * GLOBAL FUNCTIONS DECLARATION + **************************************************************************************** + */ + +/** + **************************************************************************************** + * + * Health Thermometer Application Functions + * + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialize HID Application Module + **************************************************************************************** + */ +void app_hid_init(void); + +/** + **************************************************************************************** + * @brief Initialize the PS2 mouse driver so that it can be used by the application + **************************************************************************************** + */ +void app_hid_start_mouse(void); + +/** + **************************************************************************************** + * @brief Add a HID Service instance in the DB + **************************************************************************************** + */ +void app_hid_add_hids(void); + +/** + **************************************************************************************** + * @brief Enable the HID Over GATT Profile device role + * + * @param[in]: conhdl - Connection handle for the connection + **************************************************************************************** + */ +void app_hid_enable_prf(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Send a mouse report to the peer device + * + * @param[in]: report - Mouse report sent by the PS2 driver + **************************************************************************************** + */ +void app_hid_send_mouse_report(struct ps2_mouse_msg report); + +#endif //(BLE_APP_HID) + +/// @} APP + +#endif // APP_HID_H_ diff --git a/services/ble_app/app_hrps/app_hrps.c b/services/ble_app/app_hrps/app_hrps.c new file mode 100644 index 0000000..ff5fc76 --- /dev/null +++ b/services/ble_app/app_hrps/app_hrps.c @@ -0,0 +1,156 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_HR) +#include "app_hrps.h" +#include "hrps.h" +#include "hrps_task.h" + +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "co_bt.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "arch.h" // Platform Definitions +#include "prf.h" +#include "string.h" + +struct app_hrps_env_tag app_hrps_env; + +void app_hrps_init(void) +{ + // Reset the environment + memset(&app_hrps_env, 0x00, sizeof(app_hrps_env)); + + app_hrps_env.connectionIndex = INVALID_CONNECTION_INDEX; + app_hrps_env.isNotificationEnabled = false; +} + +void app_hrps_connected_evt_handler(uint8_t conidx) +{ + app_hrps_env.connectionIndex = conidx; +} + +void app_hrps_disconnected_evt_handler(void) +{ + app_hrps_env.connectionIndex = INVALID_CONNECTION_INDEX; + app_hrps_env.isNotificationEnabled = false; +} + + +void app_hrps_send_measument_via_notification(void) +{ + if (app_hrps_env.isNotificationEnabled) { + struct hrps_meas_send_req *req = KE_MSG_ALLOC(HRPS_MEAS_SEND_REQ, + prf_get_task_from_id(TASK_ID_HRPS), + TASK_APP, + hrps_meas_send_req); + + memcpy(req, &app_hrps_env.meas, sizeof(struct hrps_meas_send_req)); + + ke_msg_send(req); + } +} + +void app_hrps_add_profile(void) +{ + TRACE(0,"app_hrps_add_profile"); + struct hrps_db_cfg* db_cfg; + + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, TASK_APP, + gapm_profile_task_add_cmd, sizeof(struct hrps_db_cfg)); + + + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX>1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE)|PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + + req->prf_task_id = TASK_ID_HRPS; + req->app_task = TASK_APP; + req->start_hdl = 0; + + db_cfg = (struct hrps_db_cfg*) req->param; + + db_cfg->features = HRPS_BODY_SENSOR_LOC_CHAR_SUP | HRPS_ENGY_EXP_FEAT_SUP | HRPS_HR_MEAS_NTF_CFG; + + db_cfg->body_sensor_loc = 0; + + // Send the message + ke_msg_send(req); +} + +static int app_hrps_msg_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Do nothing + + return (KE_MSG_CONSUMED); +} + +static int app_hrps_measurement_ccc_changed_handler(ke_msg_id_t const msgid, + struct hrps_cfg_indntf_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + TRACE(2,"%s cfg: %d", __func__, param->cfg_val); + + app_hrps_env.isNotificationEnabled = param->cfg_val; + return (KE_MSG_CONSUMED); +} + +static int app_hrps_measurement_sent_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + return (KE_MSG_CONSUMED); +} + +static int app_hrps_ctrl_point_received_handler(ke_msg_id_t const msgid, + struct hrps_energy_exp_reset_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + TRACE(1,"%s", __func__); + + app_hrps_send_measument_via_notification(); + return (KE_MSG_CONSUMED); +} +/// Default State handlers definition +const struct ke_msg_handler hrps_msg_handler_list[] = +{ + // Note: first message is latest message checked by kernel so default is put on top. + {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_hrps_msg_handler}, + + {HRPS_CFG_INDNTF_IND, (ke_msg_func_t)app_hrps_measurement_ccc_changed_handler}, + {HRP_MEASUREMENT_DATA_SENT, (ke_msg_func_t)app_hrps_measurement_sent_handler}, + {HRPS_ENERGY_EXP_RESET_IND, (ke_msg_func_t)app_hrps_ctrl_point_received_handler}, + +}; + +const struct ke_state_handler app_hrps_table_handler = + {&hrps_msg_handler_list[0], (sizeof(hrps_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif diff --git a/services/ble_app/app_hrps/app_hrps.h b/services/ble_app/app_hrps/app_hrps.h new file mode 100644 index 0000000..e167d58 --- /dev/null +++ b/services/ble_app/app_hrps/app_hrps.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_HRP_H +#define __APP_HRP_H + +#if (BLE_APP_HR) + +#include "hrps.h" +#include "hrps_task.h" + +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "co_bt.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "arch.h" // Platform Definitions +#include "prf.h" +#include "string.h" + +#define INVALID_CONNECTION_INDEX 0xFF + +void app_hrps_add_profile(void); + +extern const struct ke_state_handler app_hrps_table_handler; + +void app_hrps_init(void); + +void app_hrps_connected_evt_handler(uint8_t conidx); + +void app_hrps_disconnected_evt_handler(void); + +/// Messages for HRP Server Profile +enum hrp_msg_id +{ + HRP_MEASUREMENT_CCC_CHANGED = TASK_FIRST_MSG(TASK_ID_HRPS), + + HRP_MEASUREMENT_DATA_SENT, + + HRP_CTRL_POINT_RECEIVED, + +}; + +struct ble_hrp_measurement_notif_config_t +{ + bool isNotificationEnabled; +}; + +struct app_hrps_env_tag +{ + uint8_t connectionIndex; + uint8_t isNotificationEnabled; + struct hrps_meas_send_req meas; +}; + + +#endif + +#endif diff --git a/services/ble_app/app_htp/app_ht.c b/services/ble_app/app_htp/app_ht.c new file mode 100644 index 0000000..3ea8f1a --- /dev/null +++ b/services/ble_app/app_htp/app_ht.c @@ -0,0 +1,467 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_HT) + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "app_ht.h" // Health Thermometer Application Definitions +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "htpt_task.h" // health thermometer functions +#include "co_bt.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "arch.h" // Platform Definitions + +#include "co_math.h" +#include "ke_timer.h" + +#if (DISPLAY_SUPPORT) +#include "app_display.h" +#include "display.h" +#endif //DISPLAY_SUPPORT + +/* + * DEFINES + **************************************************************************************** + */ + +/// Initial Temperature Value : 37c +#define APP_HT_TEMP_VALUE_INIT (3700) +/// Temperature Step +#define APP_HT_TEMP_STEP_INIT (10) +/// Measurement Interval Value Min +#define APP_HT_MEAS_INTV_MIN (1) +/// Measurement Interval Value Max +#define APP_HT_MEAS_INTV_MAX (30) + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// health thermometer application environment structure +struct app_ht_env_tag app_ht_env; + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +static void app_ht_temp_send(void) +{ + // Temperature Value + int32_t value = (int32_t)(app_ht_env.temp_value); + + // The value is a float value, set the exponent + value |= 0xFE000000; + + // Allocate the HTPT_TEMP_SEND_REQ message + struct htpt_temp_send_req * req = KE_MSG_ALLOC(HTPT_TEMP_SEND_REQ, + prf_get_task_from_id(TASK_ID_HTPT), + TASK_APP, + htpt_temp_send_req); + + // Stable => Temperature Measurement Char. + req->stable_meas = 0x01; + + // Temperature Measurement Value + req->temp_meas.temp = value; +// req->temp_meas.time_stamp = 0; + req->temp_meas.flags = HTP_FLAG_CELSIUS | HTP_FLAG_TYPE; + req->temp_meas.type = app_ht_env.temp_meas_type; + + ke_msg_send(req); +} + +static void app_ht_update_type_string(uint8_t temp_type) +{ + switch (temp_type) + { + case 0: + strcpy(app_ht_env.temp_type_string, "NONE"); + break; + case 1: + strcpy(app_ht_env.temp_type_string, "ARMPIT"); + break; + case 2: + strcpy(app_ht_env.temp_type_string, "BODY"); + break; + case 3: + strcpy(app_ht_env.temp_type_string, "EAR"); + break; + case 4: + strcpy(app_ht_env.temp_type_string, "FINGER"); + break; + case 5: + strcpy(app_ht_env.temp_type_string, "GASTRO-INT"); + break; + case 6: + strcpy(app_ht_env.temp_type_string, "MOUTH"); + break; + case 7: + strcpy(app_ht_env.temp_type_string, "RECTUM"); + break; + case 8: + strcpy(app_ht_env.temp_type_string, "TOE"); + break; + case 9: + strcpy(app_ht_env.temp_type_string, "TYMPANUM"); + break; + default: + strcpy(app_ht_env.temp_type_string, "UNKNOWN"); + break; + } +} + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +void app_ht_init(void) +{ + // Reset the environment + memset(&app_ht_env, 0, sizeof(app_ht_env)); + + // Initial measurement interval : 0s + app_ht_env.htpt_meas_intv = 5; + // Initial temperature value : 37.00 C + app_ht_env.temp_value = APP_HT_TEMP_VALUE_INIT; + // Initial temperature step : 0.20 C + app_ht_env.temp_step = APP_HT_TEMP_STEP_INIT; + // Initial temperature type : ARMPIT + app_ht_env.temp_meas_type = 1; + + //TODO: Add a state for the module +} + +void app_stop_timer (void) +{ + // Stop the timer used for the measurement interval if enabled + if (app_ht_env.timer_enable) + { + ke_timer_clear(APP_HT_MEAS_INTV_TIMER, TASK_APP); + app_ht_env.timer_enable = false; + } +} + +void app_ht_add_hts(void) +{ + struct htpt_db_cfg* db_cfg; + // Allocate the HTPT_CREATE_DB_REQ + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, TASK_APP, + gapm_profile_task_add_cmd, sizeof(struct htpt_db_cfg)); + + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX>1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE)|PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + + req->prf_task_id = TASK_ID_HTPT; + req->app_task = TASK_APP; + req->start_hdl = 0; + + // Set parameters + db_cfg = (struct htpt_db_cfg* ) req->param; + // All features are supported + db_cfg->features = HTPT_ALL_FEAT_SUP; + + // Measurement Interval range + db_cfg->valid_range_min = APP_HT_MEAS_INTV_MIN; + db_cfg->valid_range_max = APP_HT_MEAS_INTV_MAX; + + // Measurement + db_cfg->temp_type = app_ht_env.temp_meas_type; + db_cfg->meas_intv = app_ht_env.htpt_meas_intv; + + // Send the message + ke_msg_send(req); +} + +void app_ht_enable_prf(uint8_t conidx) +{ + // Allocate the message + struct htpt_enable_req * req = KE_MSG_ALLOC(HTPT_ENABLE_REQ, + prf_get_task_from_id(TASK_ID_HTPT), + TASK_APP, + htpt_enable_req); + + // Fill in the parameter structure + req->conidx = conidx; + // NTF/IND initial status - Disabled + req->ntf_ind_cfg = PRF_CLI_STOP_NTFIND; + + // Send the message + ke_msg_send(req); +} + +/** + **************************************************************************************** + * Health Thermometer Application Functions + **************************************************************************************** + */ + +void app_ht_temp_inc(void) +{ + app_ht_env.temp_value += app_ht_env.temp_step; + + #if (DISPLAY_SUPPORT) + app_display_update_temp_val_screen(app_ht_env.temp_value); + #endif //DISPLAY_SUPPORT + + app_ht_temp_send(); +} + +void app_ht_temp_dec(void) +{ + app_ht_env.temp_value -= app_ht_env.temp_step; + + #if (DISPLAY_SUPPORT) + app_display_update_temp_val_screen(app_ht_env.temp_value); + #endif //DISPLAY_SUPPORT + + app_ht_temp_send(); +} + +void app_ht_temp_type_inc(void) +{ + app_ht_env.temp_meas_type = (uint8_t)(((int)app_ht_env.temp_meas_type + 1)%10); + + #if (DISPLAY_SUPPORT) + app_ht_update_type_string(app_ht_env.temp_meas_type); + app_display_update_temp_type_screen(app_ht_env.temp_type_string); + #endif //DISPLAY_SUPPORT +} + +void app_ht_temp_type_dec(void) +{ + if (((int)app_ht_env.temp_meas_type-1) < 0) + { + app_ht_env.temp_meas_type = 0x09; + } + else + { + app_ht_env.temp_meas_type = app_ht_env.temp_meas_type - 1; + } + + #if DISPLAY_SUPPORT + app_ht_update_type_string(app_ht_env.temp_meas_type); + app_display_update_temp_type_screen(app_ht_env.temp_type_string); + #endif //DISPLAY_SUPPORT +} + +/**************************************************************************************** + * MESSAGE HANDLERS + ****************************************************************************************/ + +/** + **************************************************************************************** + * @brief Handles measurement interval start indication from the Health Thermometer + * profile. + * Start or stop a timer following the value of the param intv. + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int htpt_meas_intv_chg_req_ind_handler(ke_msg_id_t const msgid, + struct htpt_meas_intv_chg_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Store the received Measurement Interval value + app_ht_env.htpt_meas_intv = param->intv; + + // Check the new Measurement Interval Value + if (app_ht_env.htpt_meas_intv != 0) + { + // Check if a Timer already exists + if (!app_ht_env.timer_enable) + { + // Set a Timer + ke_timer_set(APP_HT_MEAS_INTV_TIMER, TASK_APP, app_ht_env.htpt_meas_intv*100); + app_ht_env.timer_enable = true; + } + else + { + // Clear the previous timer + ke_timer_clear(APP_HT_MEAS_INTV_TIMER, TASK_APP); + // Create a new timer with the received measurement interval + ke_timer_set(APP_HT_MEAS_INTV_TIMER, TASK_APP, app_ht_env.htpt_meas_intv*100); + } + } + else + { + // Check if a Timer exists + if (app_ht_env.timer_enable) + { + // Measurement Interval is 0, clear the timer + ke_timer_clear(APP_HT_MEAS_INTV_TIMER, TASK_APP); + app_ht_env.timer_enable = false; + } + } + + // Allocate the message + struct htpt_meas_intv_chg_cfm * cfm = KE_MSG_ALLOC(HTPT_MEAS_INTV_CHG_CFM, + prf_get_task_from_id(TASK_ID_HTPT), + TASK_APP, + htpt_meas_intv_chg_cfm); + + // Set data + cfm->conidx = KE_IDX_GET(dest_id); + cfm->status = 0; + + // Send the message + ke_msg_send(cfm); + + + return (KE_MSG_CONSUMED); +} + +static int htpt_temp_send_rsp_handler(ke_msg_id_t const msgid, + struct htpt_temp_send_rsp const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Do nothing + return (KE_MSG_CONSUMED); +} + +static int htpt_cfg_indntf_ind_handler(ke_msg_id_t const msgid, + struct htpt_cfg_indntf_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Do nothing + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles health thermometer timer + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int app_ht_meas_intv_timer_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Random generation of a temperature value + uint32_t rand_temp_step; + // Sign used to know if the temperature will be increased or decreased + int8_t sign; + + // Generate temperature step + rand_temp_step = (uint32_t)(co_rand_word()%20); + // Increase or decrease the temperature value + sign = (int8_t)(rand_temp_step & 0x00000001); + + if (!sign) + { + sign = -1; + } + + app_ht_env.temp_value += sign*rand_temp_step; + + // Send the new temperature + app_ht_temp_send(); + + #if (DISPLAY_SUPPORT) + app_display_update_temp_val_screen(app_ht_env.temp_value); + #endif //DISPLAY_SUPPORT + + // Reset the Timer (Measurement Interval is not 0 if we are here) + ke_timer_set(APP_HT_MEAS_INTV_TIMER, TASK_APP, app_ht_env.htpt_meas_intv*100); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles health thermometer timer + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int app_ht_msg_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Do nothing + + return (KE_MSG_CONSUMED); +} + +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +const struct ke_msg_handler app_ht_msg_handler_list[] = +{ + // Note: first message is latest message checked by kernel so default is put on top. + {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_ht_msg_handler}, + +// {HTPT_ENABLE_RSP, (ke_msg_func_t)htpt_enable_rsp_handler}, + {HTPT_TEMP_SEND_RSP, (ke_msg_func_t)htpt_temp_send_rsp_handler}, + {HTPT_MEAS_INTV_CHG_REQ_IND, (ke_msg_func_t)htpt_meas_intv_chg_req_ind_handler}, + {HTPT_CFG_INDNTF_IND, (ke_msg_func_t)htpt_cfg_indntf_ind_handler}, + + {APP_HT_MEAS_INTV_TIMER, (ke_msg_func_t)app_ht_meas_intv_timer_handler}, +}; + +const struct ke_state_handler app_ht_table_handler = + {&app_ht_msg_handler_list[0], (sizeof(app_ht_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif //BLE_APP_HT + +/// @} APP diff --git a/services/ble_app/app_htp/app_ht.h b/services/ble_app/app_htp/app_ht.h new file mode 100644 index 0000000..d321d2a --- /dev/null +++ b/services/ble_app/app_htp/app_ht.h @@ -0,0 +1,152 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef APP_HT_H_ +#define APP_HT_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * @ingroup RICOW + * + * @brief Health Thermometer Application entry point. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_HT) + +#include // Standard Integer Definition +#include "ke_task.h" + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +extern struct app_env_tag app_env; + +/// health thermometer application environment structure +struct app_ht_env_tag +{ + /// Measurement interval + uint16_t htpt_meas_intv; + + /// Temperature value + uint32_t temp_value; + /// Temperature step + uint32_t temp_step; + /// Temperature type + uint8_t temp_meas_type; + /// Temperature type string + char temp_type_string[16]; + + /// Measurement interval timer enable + bool timer_enable; +}; + +/* + * GLOBAL VARIABLES DECLARATIONS + **************************************************************************************** + */ + +/// Health Thermomter Application environment +extern struct app_ht_env_tag app_ht_env; + +/// Table of message handlers +extern const struct ke_state_handler app_ht_table_handler; + +/* + * FUNCTIONS DECLARATION + **************************************************************************************** + */ + +/** + **************************************************************************************** + * + * Health Thermometer Application Functions + * + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialize Health Thermometer Application + **************************************************************************************** + */ +void app_ht_init(void); + +/** + **************************************************************************************** + * @brief Add a Health Thermometer instance in the DB + **************************************************************************************** + */ +void app_ht_add_hts(void); + +/** + **************************************************************************************** + * @brief Stop the interval measurement timer if used + **************************************************************************************** + */ +void app_stop_timer (void); + +/** + **************************************************************************************** + * @brief Enable the health thermometer profile + **************************************************************************************** + */ +void app_ht_enable_prf(uint8_t); + +/** + **************************************************************************************** + * @brief Increase temp_value by temp_step + **************************************************************************************** + */ +void app_ht_temp_inc(void); + +/** + **************************************************************************************** + * @brief Decrease temp_value by temp_step + **************************************************************************************** + */ +void app_ht_temp_dec(void); + +/** + **************************************************************************************** + * @brief Decrease temp_type by 1 + **************************************************************************************** + */ +void app_ht_temp_type_dec(void); + +/** + **************************************************************************************** + * @brief Increase temp_type by 1 + **************************************************************************************** + */ +void app_ht_temp_type_inc(void); + +#endif //(BLE_APP_HT) + +/// @} APP + +#endif // APP_HT_H_ diff --git a/services/ble_app/app_main/app.c b/services/ble_app/app_main/app.c new file mode 100644 index 0000000..b23a700 --- /dev/null +++ b/services/ble_app/app_main/app.c @@ -0,0 +1,1458 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration +#if (BLE_APP_PRESENT) +#include + +#include "app_task.h" // Application task Definition +#include "app.h" // Application Definition +#include "gap.h" // GAP Definition +#include "tgt_hardware.h" +#include "gapm.h" +#include "gapm_task.h" // GAP Manager Task API +#include "gapc_task.h" // GAP Controller Task API + +#include "gattc_task.h" + +#include "co_bt.h" // Common BT Definition +#include "co_math.h" // Common Maths Definition +#include "l2cc.h" +#include "l2cc_pdu.h" + +#include "nvrecord_ble.h" +#include "prf.h" + +#include "nvrecord_env.h" +#ifndef _BLE_NVDS_ +#include "tgt_hardware.h" +#endif +#ifdef __AI_VOICE__ +#include "app_ai_ble.h" // AI Voice Application Definitions +#endif //(__AI_VOICE__) + +#if (BLE_APP_SEC) +#include "app_sec.h" // Application security Definition +#endif // (BLE_APP_SEC) + + +#if (BLE_APP_DATAPATH_SERVER) +#include "app_datapath_server.h" // Data Path Server Application Definitions +#endif //(BLE_APP_DATAPATH_SERVER) + +#if (BLE_APP_DIS) +#include "app_dis.h" // Device Information Service Application Definitions +#endif //(BLE_APP_DIS) + +#if (BLE_APP_BATT) +#include "app_batt.h" // Battery Application Definitions +#endif //(BLE_APP_DIS) + +#if (BLE_APP_HID) +#include "app_hid.h" // HID Application Definitions +#endif //(BLE_APP_HID) + +#if (BLE_APP_VOICEPATH) +#include "app_voicepath_ble.h" // Voice Path Application Definitions +#endif //(BLE_APP_VOICEPATH) + +#if (BLE_APP_OTA) +#include "app_ota.h" // OTA Application Definitions +#endif //(BLE_APP_OTA) + +#if (BLE_APP_TOTA) +#include "app_tota_ble.h" // OTA Application Definitions +#endif //(BLE_APP_TOTA) + +#if (BLE_APP_ANCC) +#include "app_ancc.h" // ANCC Application Definitions +#endif //(BLE_APP_ANCC) + +#if (BLE_APP_AMS) +#include "app_amsc.h" // AMS Module Definition +#endif // (BLE_APP_AMS) + +#if (BLE_APP_GFPS) +#include "app_gfps.h" // Google Fast Pair Service Definitions +#endif +#if (DISPLAY_SUPPORT) +#include "app_display.h" // Application Display Definition +#endif //(DISPLAY_SUPPORT) + +#ifdef BLE_APP_AM0 +#include "am0_app.h" // Audio Mode 0 Application +#endif //defined(BLE_APP_AM0) + +#if (NVDS_SUPPORT) +#include "nvds.h" // NVDS Definitions +#endif //(NVDS_SUPPORT) + +#include "cmsis_os.h" +#include "ke_timer.h" +#include "nvrecord.h" +#include "ble_app_dbg.h" +#include "app_bt.h" +#include "app_ble_mode_switch.h" +#include "apps.h" +#include "crc16.h" +#include "besbt.h" + +#ifdef BISTO_ENABLED +#include "gsound_service.h" +#endif + +#if defined(__INTERCONNECTION__) +#include "app_bt.h" +#include "app_battery.h" +#endif + +#if (BLE_APP_TILE) +#include "tile_target_ble.h" +#include "tile_service.h" +#endif + +#if defined(IBRT) +#include "app_tws_ibrt.h" +#endif + +#ifdef FPGA +#include "hal_timer.h" +#endif + +#ifdef __GATT_OVER_BR_EDR__ +#include "btgatt_api.h" +#endif + +/* + * DEFINES + **************************************************************************************** + */ +/// Default Device Name if no value can be found in NVDS +#define APP_DFLT_DEVICE_NAME ("BES_BLE") +#define APP_DFLT_DEVICE_NAME_LEN (sizeof(APP_DFLT_DEVICE_NAME)) + +#if (BLE_APP_HID) +// HID Mouse +#define DEVICE_NAME "Hid Mouse" +#else +#define DEVICE_NAME "RW DEVICE" +#endif + +#define DEVICE_NAME_SIZE sizeof(DEVICE_NAME) + +/** + * UUID List part of ADV Data + * -------------------------------------------------------------------------------------- + * x03 - Length + * x03 - Complete list of 16-bit UUIDs available + * x09\x18 - Health Thermometer Service UUID + * or + * x12\x18 - HID Service UUID + * -------------------------------------------------------------------------------------- + */ + +#if (BLE_APP_HT) +#define APP_HT_ADV_DATA_UUID "\x03\x03\x09\x18" +#define APP_HT_ADV_DATA_UUID_LEN (4) +#endif //(BLE_APP_HT) + + +#if (BLE_APP_HID) +#define APP_HID_ADV_DATA_UUID "\x03\x03\x12\x18" +#define APP_HID_ADV_DATA_UUID_LEN (4) +#endif //(BLE_APP_HID) + +#if (BLE_APP_DATAPATH_SERVER) +/* + * x11 - Length + * x07 - Complete list of 16-bit UUIDs available + * .... the 128 bit UUIDs + */ +#define APP_DATAPATH_SERVER_ADV_DATA_UUID "\x11\x07\x9e\x34\x9B\x5F\x80\x00\x00\x80\x00\x10\x00\x00\x00\x01\x00\x01" +#define APP_DATAPATH_SERVER_ADV_DATA_UUID_LEN (18) +#endif //(BLE_APP_HT) + +/** + * Appearance part of ADV Data + * -------------------------------------------------------------------------------------- + * x03 - Length + * x19 - Appearance + * x03\x00 - Generic Thermometer + * or + * xC2\x04 - HID Mouse + * -------------------------------------------------------------------------------------- + */ + +#if (BLE_APP_HT) +#define APP_HT_ADV_DATA_APPEARANCE "\x03\x19\x00\x03" +#endif //(BLE_APP_HT) + +#if (BLE_APP_HID) +#define APP_HID_ADV_DATA_APPEARANCE "\x03\x19\xC2\x03" +#endif //(BLE_APP_HID) + +#define APP_ADV_DATA_APPEARANCE_LEN (4) + + + +/** + * Advertising Parameters + */ +#if (BLE_APP_HID) +/// Default Advertising duration - 30s (in multiple of 10ms) +#define APP_DFLT_ADV_DURATION (3000) +#endif //(BLE_APP_HID) +/// Advertising channel map - 37, 38, 39 +#define APP_ADV_CHMAP (0x07) + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +typedef void (*appm_add_svc_func_t)(void); + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// List of service to add in the database +enum appm_svc_list +{ + #if (BLE_APP_HT) + APPM_SVC_HTS, + #endif //(BLE_APP_HT) + #if (BLE_APP_DIS) + APPM_SVC_DIS, + #endif //(BLE_APP_DIS) + #if (BLE_APP_BATT) + APPM_SVC_BATT, + #endif //(BLE_APP_BATT) + #if (BLE_APP_HID) + APPM_SVC_HIDS, + #endif //(BLE_APP_HID) + #ifdef BLE_APP_AM0 + APPM_SVC_AM0_HAS, + #endif //defined(BLE_APP_AM0) + #if (BLE_APP_HR) + APPM_SVC_HRP, + #endif + #if (BLE_APP_DATAPATH_SERVER) + APPM_SVC_DATAPATH_SERVER, + #endif //(BLE_APP_DATAPATH_SERVER) + #if (BLE_APP_VOICEPATH) + APPM_SVC_VOICEPATH, + #ifdef BISTO_ENABLED + APPM_SVC_BMS, + #endif + #endif //(BLE_APP_VOICEPATH) + #if (ANCS_PROXY_ENABLE) + APPM_SVC_ANCSP, + APPM_SVC_AMSP, + #endif + #if (BLE_APP_ANCC) + APPM_SVC_ANCC, + #endif //(BLE_APP_ANCC) + #if (BLE_APP_AMS) + APPM_SVC_AMSC, + #endif //(BLE_APP_AMS) + #if (BLE_APP_OTA) + APPM_SVC_OTA, + #endif //(BLE_APP_OTA) + #if (BLE_APP_GFPS) + APPM_SVC_GFPS, + #endif //(BLE_APP_GFPS) + #if (BLE_AI_VOICE) + APPM_AI_SMARTVOICE, + #endif //(BLE_AI_VOICE) + #if (BLE_APP_TOTA) + APPM_SVC_TOTA, + #endif //(BLE_APP_TOTA) + + #if (BLE_APP_TILE) + APPM_SVC_TILE, + #endif //(BLE_APP_TILE) + + APPM_SVC_LIST_STOP, +}; + +/* + * LOCAL VARIABLES DEFINITIONS + **************************************************************************************** + */ +//gattc_msg_handler_tab +//#define KE_MSG_HANDLER_TAB(task) __STATIC const struct ke_msg_handler task##_msg_handler_tab[] = +/// Application Task Descriptor + +//static const struct ke_task_desc TASK_DESC_APP = {&appm_default_handler, +// appm_state, APPM_STATE_MAX, APP_IDX_MAX}; +extern const struct ke_task_desc TASK_DESC_APP; + +/// List of functions used to create the database +static const appm_add_svc_func_t appm_add_svc_func_list[APPM_SVC_LIST_STOP] = +{ + #if (BLE_APP_HT) + (appm_add_svc_func_t)app_ht_add_hts, + #endif //(BLE_APP_HT) + #if (BLE_APP_DIS) + (appm_add_svc_func_t)app_dis_add_dis, + #endif //(BLE_APP_DIS) + #if (BLE_APP_BATT) + (appm_add_svc_func_t)app_batt_add_bas, + #endif //(BLE_APP_BATT) + #if (BLE_APP_HID) + (appm_add_svc_func_t)app_hid_add_hids, + #endif //(BLE_APP_HID) + #ifdef BLE_APP_AM0 + (appm_add_svc_func_t)am0_app_add_has, + #endif //defined(BLE_APP_AM0) + #if (BLE_APP_HR) + (appm_add_svc_func_t)app_hrps_add_profile, + #endif + #if (BLE_APP_DATAPATH_SERVER) + (appm_add_svc_func_t)app_datapath_add_datapathps, + #endif //(BLE_APP_DATAPATH_SERVER) + #if (BLE_APP_VOICEPATH) + (appm_add_svc_func_t)app_ble_voicepath_add_svc, + #ifdef BISTO_ENABLED + (appm_add_svc_func_t)app_ble_bms_add_svc, + #endif + #endif //(BLE_APP_VOICEPATH) + #if (ANCS_PROXY_ENABLE) + (appm_add_svc_func_t)app_ble_ancsp_add_svc, + (appm_add_svc_func_t)app_ble_amsp_add_svc, + #endif + #if (BLE_APP_ANCC) + (appm_add_svc_func_t)app_ancc_add_ancc, + #endif + #if (BLE_APP_AMS) + (appm_add_svc_func_t)app_amsc_add_amsc, + #endif + #if (BLE_APP_OTA) + (appm_add_svc_func_t)app_ota_add_ota, + #endif //(BLE_APP_OTA) + #if (BLE_APP_GFPS) + (appm_add_svc_func_t)app_gfps_add_gfps, + #endif + #if (BLE_APP_AI_VOICE) + (appm_add_svc_func_t)app_ai_add_ai, + #endif //(BLE_APP_AI_VOICE) + #if (BLE_APP_TOTA) + (appm_add_svc_func_t)app_tota_add_tota, + #endif //(BLE_APP_TOTA) + #if (BLE_APP_TILE) + (appm_add_svc_func_t)app_ble_tile_add_svc, + #endif +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Application Environment Structure +struct app_env_tag app_env; + +static APP_BLE_NEGOTIATED_CONN_PARAM_T negotiatedBleConnParam[BLE_CONNECTION_MAX]; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ +void appm_refresh_ble_irk(void) +{ + nv_record_blerec_get_local_irk(app_env.loc_irk); + LOG_I("local irk:"); + DUMP8("0x%02x ", app_env.loc_irk, 16); + gapm_update_irk(app_env.loc_irk); +} + +uint8_t *appm_get_current_ble_irk(void) +{ + return app_env.loc_irk; +} + +void appm_init() +{ + BLE_APP_FUNC_ENTER(); + + // Reset the application manager environment + memset(&app_env, 0, sizeof(app_env)); + + // Create APP task + ke_task_create(TASK_APP, &TASK_DESC_APP); + + // Initialize Task state + ke_state_set(TASK_APP, APPM_INIT); + + // Load the device name from NVDS + + // Get the Device Name to add in the Advertising Data (Default one or NVDS one) +#ifdef _BLE_NVDS_ + const char* ble_name_in_nv = nvrec_dev_get_ble_name(); +#else + const char* ble_name_in_nv = BLE_DEFAULT_NAME; +#endif + uint32_t nameLen = strlen(ble_name_in_nv) + 1; + if (nameLen > APP_DEVICE_NAME_MAX_LEN) + { + nameLen = APP_DEVICE_NAME_MAX_LEN; + } + // Get default Device Name (No name if not enough space) + memcpy(app_env.dev_name, ble_name_in_nv, nameLen); + app_env.dev_name[nameLen - 1] = '\0'; + app_env.dev_name_len = nameLen; + LOG_I("device ble name:%s", app_env.dev_name); +#ifdef _BLE_NVDS_ + nv_record_blerec_init(); + + nv_record_blerec_get_local_irk(app_env.loc_irk); +#else + uint8_t counter; + + //avoid ble irk collision low probability + uint32_t generatedSeed = hal_sys_timer_get(); + for (uint8_t index = 0; index < sizeof(bt_addr); index++) + { + generatedSeed ^= (((uint32_t)(bt_addr[index])) << (hal_sys_timer_get()&0xF)); + } + srand(generatedSeed); + + // generate a new IRK + for (counter = 0; counter < KEY_LEN; counter++) + { + app_env.loc_irk[counter] = (uint8_t)co_rand_word(); + } +#endif + + /*------------------------------------------------------ + * INITIALIZE ALL MODULES + *------------------------------------------------------*/ + + // load device information: + + #if (DISPLAY_SUPPORT) + app_display_init(); + #endif //(DISPLAY_SUPPORT) + + #if (BLE_APP_SEC) + // Security Module + app_sec_init(); + #endif // (BLE_APP_SEC) + + #if (BLE_APP_HT) + // Health Thermometer Module + app_ht_init(); + #endif //(BLE_APP_HT) + + #if (BLE_APP_DIS) + // Device Information Module + app_dis_init(); + #endif //(BLE_APP_DIS) + + #if (BLE_APP_HID) + // HID Module + app_hid_init(); + #endif //(BLE_APP_HID) + + #if (BLE_APP_BATT) + // Battery Module + app_batt_init(); + #endif //(BLE_APP_BATT) + + #ifdef BLE_APP_AM0 + // Audio Mode 0 Module + am0_app_init(); + #endif // defined(BLE_APP_AM0) + + #if (BLE_APP_VOICEPATH) + // Voice Path Module + app_ble_voicepath_init(); + #endif //(BLE_APP_VOICEPATH) + + #if (BLE_APP_TILE) + app_ble_tile_init(); + #endif + + #if (BLE_APP_DATAPATH_SERVER) + // Data Path Server Module + app_datapath_server_init(); + #endif //(BLE_APP_DATAPATH_SERVER) + #if (BLE_APP_AI_VOICE) + // AI Voice Module + app_ai_init(); + #endif //(BLE_APP_AI_VOICE) + + #if (BLE_APP_OTA) + // OTA Module + app_ota_init(); + #endif //(BLE_APP_OTA) + + #if (BLE_APP_TOTA) + // TOTA Module + app_tota_ble_init(); + #endif //(BLE_APP_TOTA) + + #if (BLE_APP_GFPS) + // + app_gfps_init(); + #endif + + #if (BLE_APP_TILE) + app_tile_init(); + #endif + + BLE_APP_FUNC_LEAVE(); +} + +bool appm_add_svc(void) +{ + // Indicate if more services need to be added in the database + bool more_svc = false; + + // Check if another should be added in the database + if (app_env.next_svc != APPM_SVC_LIST_STOP) + { + ASSERT_INFO(appm_add_svc_func_list[app_env.next_svc] != NULL, app_env.next_svc, 1); + + BLE_APP_DBG("appm_add_svc adds service"); + + // Call the function used to add the required service + appm_add_svc_func_list[app_env.next_svc](); + + // Select following service to add + app_env.next_svc++; + more_svc = true; + } + else + { + BLE_APP_DBG("appm_add_svc doesn't execute, next svc is %d", app_env.next_svc); + } + + + return more_svc; +} + +uint16_t appm_get_conhdl_from_conidx(uint8_t conidx) +{ + return app_env.context[conidx].conhdl; +} + +void appm_disconnect(uint8_t conidx) +{ + if (BLE_DISCONNECTED != app_env.context[conidx].connectStatus) + { + struct gapc_disconnect_cmd *cmd = KE_MSG_ALLOC(GAPC_DISCONNECT_CMD, + KE_BUILD_ID(TASK_GAPC, conidx), + TASK_APP, + gapc_disconnect_cmd); + + cmd->operation = GAPC_DISCONNECT; + cmd->reason = CO_ERROR_REMOTE_USER_TERM_CON; + + // Send the message + ke_msg_send(cmd); + } +} + +// TODO: freddie modify this part +#if (BLE_APP_GFPS) +#define UPDATE_BLE_ADV_DATA_RIGHT_BEFORE_STARTING_ADV_ENABLED 1 +#else +#define UPDATE_BLE_ADV_DATA_RIGHT_BEFORE_STARTING_ADV_ENABLED 0 +#endif + +void gapm_update_ble_adv_data_right_before_started(uint8_t* pAdvData, uint8_t* advDataLen, + uint8_t* pScanRspData, uint8_t* scanRspDataLen, void* adv_cmd) +{ + // for the user case that the BLE adv data or scan rsp data need to be generated from the + // run-time BLE address. + // Just enable macro UPDATE_BLE_ADV_DATA_RIGHT_BEFORE_STARTING_ADV_ENABLED, + // and call appm_get_current_ble_addr to get the run-time used BLE address + // For fastpair GFPS_ACCOUNTKEY_SALT_TYPE==USE_BLE_ADDR_AS_SALT case, + // this macro must be enabled + +// #if UPDATE_BLE_ADV_DATA_RIGHT_BEFORE_STARTING_ADV_ENABLED +// appm_fill_ble_adv_scan_rsp_data(pAdvData, advDataLen, pScanRspData, scanRspDataLen, adv_cmd); +// #endif + // TODO: freddie implement this API +} + +/** + **************************************************************************************** + * Advertising Functions + **************************************************************************************** + */ +void appm_start_advertising(void *param) +{ + BLE_APP_FUNC_ENTER(); + + LOG_I("%s state: %d", __func__, ke_state_get(TASK_APP)); + + // Prepare the GAPM_START_ADVERTISE_CMD message + struct gapm_start_advertise_cmd *cmd = KE_MSG_ALLOC(GAPM_START_ADVERTISE_CMD, + TASK_GAPM, TASK_APP, + gapm_start_advertise_cmd); + + BLE_ADV_PARAM_T* advParam = (BLE_ADV_PARAM_T*)param; + +#ifdef BLE_USE_RPA + cmd->op.addr_src = GAPM_GEN_RSLV_ADDR; + cmd->op.randomAddrRenewIntervalInSecond = (uint16_t)(60*15); +#else + cmd->op.addr_src = GAPM_STATIC_ADDR; + + // To use non-resolvable address + //cmd->op.addr_src = GAPM_GEN_NON_RSLV_ADDR; + //cmd->op.randomAddrRenewIntervalInSecond = (uint16_t)(60*15); +#endif + + cmd->channel_map = APP_ADV_CHMAP; + cmd->intv_min = advParam->advInterval * 8 / 5; + cmd->intv_max = advParam->advInterval * 8 / 5; + cmd->op.code = advParam->advType; + cmd->info.host.mode = GAP_GEN_DISCOVERABLE; + + cmd->isIncludedFlags = advParam->withFlag; + cmd->info.host.flags = GAP_LE_GEN_DISCOVERABLE_FLG | GAP_BR_EDR_NOT_SUPPORTED; + + cmd->info.host.adv_data_len = advParam->advDataLen; + memcpy(cmd->info.host.adv_data, advParam->advData, cmd->info.host.adv_data_len); + cmd->info.host.scan_rsp_data_len = advParam->scanRspDataLen; + memcpy(cmd->info.host.scan_rsp_data, advParam->scanRspData, cmd->info.host.scan_rsp_data_len); + + if (advParam->withFlag) + { + ASSERT(cmd->info.host.adv_data_len <= BLE_ADV_DATA_WITH_FLAG_LEN, "adv data exceed"); + } + else + { + ASSERT(cmd->info.host.adv_data_len <= BLE_ADV_DATA_WITHOUT_FLAG_LEN, "adv data exceed"); + } + ASSERT(cmd->info.host.scan_rsp_data_len <= SCAN_RSP_DATA_LEN, "scan rsp data exceed"); + LOG_I("[ADDR_TYPE]:%d", cmd->op.addr_src); + if (GAPM_GEN_RSLV_ADDR == cmd->op.addr_src) + { + LOG_I("[IRK]:"); + DUMP8("0x%02x ", appm_get_current_ble_irk(), KEY_LEN); + } + else if (GAPM_STATIC_ADDR == cmd->op.addr_src) + { + LOG_I("[ADDR]:"); + DUMP8("0x%02x ", bt_get_ble_local_address(), 6); + } + + LOG_I("[ADV_TYPE]:%d", cmd->op.code); + LOG_I("[ADV_INTERVAL]:%d", cmd->intv_min); + + // Send the message + ke_msg_send(cmd); + + // Set the state of the task to APPM_ADVERTISING + ke_state_set(TASK_APP, APPM_ADVERTISING); + + BLE_APP_FUNC_LEAVE(); +} + + +void appm_stop_advertising(void) +{ + + #if (BLE_APP_HID) + // Stop the advertising timer if needed + if (ke_timer_active(APP_ADV_TIMEOUT_TIMER, TASK_APP)) + { + ke_timer_clear(APP_ADV_TIMEOUT_TIMER, TASK_APP); + } + #endif //(BLE_APP_HID) + + // Go in ready state + ke_state_set(TASK_APP, APPM_READY); + + // Prepare the GAPM_CANCEL_CMD message + struct gapm_cancel_cmd *cmd = KE_MSG_ALLOC(GAPM_CANCEL_CMD, + TASK_GAPM, TASK_APP, + gapm_cancel_cmd); + + cmd->operation = GAPM_CANCEL; + + // Send the message + ke_msg_send(cmd); + + #if (DISPLAY_SUPPORT) + // Update advertising state screen + app_display_set_adv(false); + #endif //(DISPLAY_SUPPORT) + +} +void appm_start_scanning(uint16_t intervalInMs, uint16_t windowInMs, uint32_t filtPolicy) +{ + struct gapm_start_scan_cmd *cmd = KE_MSG_ALLOC(GAPM_START_SCAN_CMD, + TASK_GAPM, + TASK_APP, + gapm_start_scan_cmd); + + cmd->op.code = GAPM_SCAN_PASSIVE; + cmd->op.addr_src = GAPM_STATIC_ADDR; + + cmd->interval = intervalInMs*1000/625; + cmd->window = windowInMs*1000/625; + cmd->mode = GAP_OBSERVER_MODE; //GAP_GEN_DISCOVERY; + cmd->filt_policy = filtPolicy; + cmd->filter_duplic = SCAN_FILT_DUPLIC_DIS; + + ke_state_set(TASK_APP, APPM_SCANNING); + + ke_msg_send(cmd); +} + +void appm_stop_scanning(void) +{ + //if (ke_state_get(TASK_APP) == APPM_SCANNING) + { + // Go in ready state + ke_state_set(TASK_APP, APPM_READY); + + // Prepare the GAPM_CANCEL_CMD message + struct gapm_cancel_cmd *cmd = KE_MSG_ALLOC(GAPM_CANCEL_CMD, + TASK_GAPM, TASK_APP, + gapm_cancel_cmd); + + cmd->operation = GAPM_CANCEL; + + // Send the message + ke_msg_send(cmd); + } +} + +void appm_add_dev_into_whitelist(struct gap_bdaddr* ptBdAddr) +{ + struct gapm_white_list_mgt_cmd *cmd = KE_MSG_ALLOC_DYN(GAPM_WHITE_LIST_MGT_CMD, + TASK_GAPM, + TASK_APP, + gapm_white_list_mgt_cmd, + sizeof(struct gap_bdaddr)); + cmd->operation = GAPM_ADD_DEV_IN_WLIST; + cmd->nb = 1; + + memcpy(cmd->devices, ptBdAddr, sizeof(struct gap_bdaddr)); + + ke_msg_send(cmd); +} + + +struct gap_bdaddr BLE_BdAddr;//{{0x14, 0x71, 0xda, 0x7d, 0x1a, 0x00}, 0}; +void pts_ble_addr_init(void) +{ + uint8_t addr[6] = {0x14, 0x71, 0xda, 0x7d, 0x1a, 0x00}; + memcpy(BLE_BdAddr.addr.addr, addr, 6); + BLE_BdAddr.addr_type = 0; +} + +void appm_start_connecting(struct gap_bdaddr* ptBdAddr) +{ + struct gapm_start_connection_cmd *cmd = KE_MSG_ALLOC_DYN(GAPM_START_CONNECTION_CMD, + TASK_GAPM, + TASK_APP, + gapm_start_connection_cmd, + sizeof(struct gap_bdaddr)); + cmd->ce_len_max = 4; + cmd->ce_len_min = 0; + cmd->con_intv_max = 6; // in the unit of 1.25ms + cmd->con_intv_min = 6; // in the unit of 1.25ms + cmd->con_latency = 0; + cmd->superv_to = 1000; // in the unit of 10ms + cmd->op.code = GAPM_CONNECTION_DIRECT; + cmd->op.addr_src = GAPM_STATIC_ADDR; + cmd->nb_peers = 1; + cmd->scan_interval = ((60) * 1000 / 625); + cmd->scan_window = ((30) * 1000 / 625); + + memcpy(cmd->peers, ptBdAddr, sizeof(struct gap_bdaddr)); + + ke_state_set(TASK_APP, APPM_CONNECTING); + + ke_msg_send(cmd); +} + +void appm_stop_connecting(void) +{ + // Go in ready state + ke_state_set(TASK_APP, APPM_READY); + + // Prepare the GAPM_CANCEL_CMD message + struct gapm_cancel_cmd *cmd = KE_MSG_ALLOC(GAPM_CANCEL_CMD, + TASK_GAPM, + TASK_APP, + gapm_cancel_cmd); + + cmd->operation = GAPM_CANCEL; + + // Send the message + ke_msg_send(cmd); +} + + +void appm_update_param(uint8_t conidx, struct gapc_conn_param *conn_param) +{ + // Prepare the GAPC_PARAM_UPDATE_CMD message + struct gapc_param_update_cmd *cmd = KE_MSG_ALLOC(GAPC_PARAM_UPDATE_CMD, + KE_BUILD_ID(TASK_GAPC, conidx), + TASK_APP, + gapc_param_update_cmd); + + cmd->operation = GAPC_UPDATE_PARAMS; + cmd->intv_min = conn_param->intv_min; + cmd->intv_max = conn_param->intv_max; + cmd->latency = conn_param->latency; + cmd->time_out = conn_param->time_out; + + // not used by a slave device + cmd->ce_len_min = 0xFFFF; + cmd->ce_len_max = 0xFFFF; + + // Send the message + ke_msg_send(cmd); +} + +void l2cap_update_param(uint8_t conidx, + uint32_t min_interval_in_ms, + uint32_t max_interval_in_ms, + uint32_t supervision_timeout_in_ms, + uint8_t slaveLantency) +{ + struct l2cc_update_param_req *req = L2CC_SIG_PDU_ALLOC(conidx, + L2C_CODE_CONN_PARAM_UPD_REQ, + KE_BUILD_ID(TASK_GAPC, conidx), + l2cc_update_param_req); + + // generate packet identifier + uint8_t pkt_id = co_rand_word() & 0xFF; + if (pkt_id == 0) + { + pkt_id = 1; + } + + /* fill up the parameters */ + req->intv_max = (uint16_t)(max_interval_in_ms/1.25); + req->intv_min = (uint16_t)(min_interval_in_ms/1.25); + req->latency = slaveLantency; + req->timeout = supervision_timeout_in_ms/10; + req->pkt_id = pkt_id; + LOG_I("%s val: 0x%x 0x%x 0x%x 0x%x 0x%x", + __func__, + req->intv_max, + req->intv_min, + req->latency, + req->timeout, + req->pkt_id); + l2cc_pdu_send(req); +} + +uint8_t appm_get_dev_name(uint8_t* name) +{ + // copy name to provided pointer + memcpy(name, app_env.dev_name, app_env.dev_name_len); + // return name length + return app_env.dev_name_len; +} + +void appm_exchange_mtu(uint8_t conidx) +{ + struct gattc_exc_mtu_cmd *cmd = KE_MSG_ALLOC(GATTC_EXC_MTU_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), + TASK_APP, + gattc_exc_mtu_cmd); + + cmd->operation = GATTC_MTU_EXCH; + cmd->seq_num= 0; + + ke_msg_send(cmd); +} + +void appm_check_and_resolve_ble_address(uint8_t conidx) +{ + APP_BLE_CONN_CONTEXT_T* pContext = &(app_env.context[conidx]); + +#ifdef __GATT_OVER_BR_EDR__ + if (conidx == btif_btgatt_get_connection_index()) + { + pContext->isGotSolvedBdAddr = true; + pContext->isBdAddrResolvingInProgress = false; + btif_btgatt_get_device_address(pContext->solvedBdAddr); + } +#endif + + // solved already, return + if (pContext->isGotSolvedBdAddr) + { + LOG_I("Already get solved bd addr."); + return; + } + // not solved yet and the solving is in progress, return and wait + else if (app_is_resolving_ble_bd_addr()) + { + LOG_I("Random bd addr solving on going."); + return; + } + + if (BLE_RANDOM_ADDR == pContext->peerAddrType) + { + memset(pContext->solvedBdAddr, 0, BD_ADDR_LEN); + bool isSuccessful = appm_resolve_random_ble_addr_from_nv(conidx, pContext->bdAddr); + LOG_I("%s isSuccessful %d", __func__, isSuccessful); + if (isSuccessful) + { + pContext->isBdAddrResolvingInProgress = true; + } + else + { + pContext->isGotSolvedBdAddr = true; + pContext->isBdAddrResolvingInProgress = false; + } + } + else + { + pContext->isGotSolvedBdAddr = true; + pContext->isBdAddrResolvingInProgress = false; + memcpy(pContext->solvedBdAddr, pContext->bdAddr, BD_ADDR_LEN); + } + +} + +bool appm_resolve_random_ble_addr_from_nv(uint8_t conidx, uint8_t* randomAddr) +{ +#ifdef _BLE_NVDS_ + struct gapm_resolv_addr_cmd *cmd = KE_MSG_ALLOC_DYN(GAPM_RESOLV_ADDR_CMD, + KE_BUILD_ID(TASK_GAPM, conidx), + TASK_APP, + gapm_resolv_addr_cmd, + BLE_RECORD_NUM * GAP_KEY_LEN); + + uint8_t irkeyNum = nv_record_ble_fill_irk((uint8_t *)(cmd->irk)); + if (0 == irkeyNum) + { + LOG_I("No history irk, cannot solve bd addr."); + KE_MSG_FREE(cmd); + return false; + } + + LOG_I("Start random bd addr solving."); + + cmd->operation = GAPM_RESOLV_ADDR; + cmd->nb_key = irkeyNum; + memcpy(cmd->addr.addr, randomAddr, GAP_BD_ADDR_LEN); + ke_msg_send(cmd); + return true; +#else + return false; +#endif + +} + +void appm_resolve_random_ble_addr_with_sepcific_irk(uint8_t conidx, uint8_t* randomAddr, uint8_t* pIrk) +{ + struct gapm_resolv_addr_cmd *cmd = KE_MSG_ALLOC_DYN(GAPM_RESOLV_ADDR_CMD, + KE_BUILD_ID(TASK_GAPM, conidx), TASK_APP, + gapm_resolv_addr_cmd, + GAP_KEY_LEN); + cmd->operation = GAPM_RESOLV_ADDR; + cmd->nb_key = 1; + memcpy(cmd->addr.addr, randomAddr, GAP_BD_ADDR_LEN); + memcpy(cmd->irk, pIrk, GAP_KEY_LEN); + ke_msg_send(cmd); +} + +void appm_random_ble_addr_solved(bool isSolvedSuccessfully, uint8_t* irkUsedForSolving) +{ + APP_BLE_CONN_CONTEXT_T* pContext; + uint32_t conidx; + for (conidx = 0;conidx < BLE_CONNECTION_MAX;conidx++) + { + pContext = &(app_env.context[conidx]); + if (pContext->isBdAddrResolvingInProgress) + { + break; + } + } + + if (conidx < BLE_CONNECTION_MAX) + { + pContext->isBdAddrResolvingInProgress = false; + pContext->isGotSolvedBdAddr = true; + + LOG_I("%s conidx %d isSolvedSuccessfully %d", __func__, conidx, isSolvedSuccessfully); + if (isSolvedSuccessfully) + { +#ifdef _BLE_NVDS_ + bool isSuccessful = nv_record_blerec_get_bd_addr_from_irk(app_env.context[conidx].solvedBdAddr, irkUsedForSolving); + if (isSuccessful) + { + LOG_I("[CONNECT]Connected random address's original addr is:"); + DUMP8("%02x ", app_env.context[conidx].solvedBdAddr, GAP_BD_ADDR_LEN); + } + else +#endif + { + LOG_I("[CONNECT]Resolving of the connected BLE random addr failed."); + } + } + else + { + LOG_I("[CONNECT]random resolving failed."); + } + } + +#if defined(CFG_VOICEPATH) + ke_task_msg_retrieve(prf_get_task_from_id(TASK_ID_VOICEPATH)); +#endif + ke_task_msg_retrieve(TASK_GAPC); + ke_task_msg_retrieve(TASK_APP); + + app_ble_start_connectable_adv(BLE_ADVERTISING_INTERVAL); +} + +uint8_t app_ble_connection_count(void) +{ + return app_env.conn_cnt; +} + +bool app_is_arrive_at_max_ble_connections(void) +{ + LOG_I("connection count %d", app_env.conn_cnt); + +#if defined(GFPS_ENABLED) && (BLE_APP_GFPS_VER==FAST_PAIR_REV_2_0) + return (app_env.conn_cnt >= BLE_CONNECTION_MAX); +#else + return (app_env.conn_cnt >= 1); +#endif +} + +bool app_is_resolving_ble_bd_addr(void) +{ + for (uint32_t index = 0;index < BLE_CONNECTION_MAX;index++) + { + if (app_env.context[index].isBdAddrResolvingInProgress) + { + return true; + } + } + + return false; +} + +void app_trigger_ble_service_discovery(uint8_t conidx, uint16_t shl, uint16_t ehl) +{ + struct gattc_send_svc_changed_cmd *cmd = KE_MSG_ALLOC(GATTC_SEND_SVC_CHANGED_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), + TASK_APP, + gattc_send_svc_changed_cmd); + cmd->operation = GATTC_SVC_CHANGED; + cmd->svc_shdl = shl; + cmd->svc_ehdl = ehl; + ke_msg_send(cmd); +} + +void appm_update_adv_data(uint8_t *pAdvData, + uint32_t advDataLen, + uint8_t *pScanRspData, + uint32_t scanRspDataLen) +{ + LOG_I("%s", __func__); + ASSERT(advDataLen <= BLE_DATA_LEN, "adv data exceed"); + ASSERT(scanRspDataLen <= SCAN_RSP_DATA_LEN, "scan rsp data exceed"); + + struct gapm_update_advertise_data_cmd *cmd = KE_MSG_ALLOC(GAPM_UPDATE_ADVERTISE_DATA_CMD, + TASK_GAPM, TASK_APP, + gapm_update_advertise_data_cmd); + cmd->operation = GAPM_UPDATE_ADVERTISE_DATA; + memcpy(cmd->adv_data, pAdvData, advDataLen); + cmd->adv_data_len = advDataLen; + + memcpy(cmd->scan_rsp_data, pScanRspData, scanRspDataLen); + cmd->scan_rsp_data_len = scanRspDataLen; + + ke_msg_send(cmd); +} + +__attribute__((weak)) void app_ble_connected_evt_handler(uint8_t conidx, const uint8_t* pPeerBdAddress) +{ + +} + +__attribute__((weak)) void app_ble_disconnected_evt_handler(uint8_t conidx) +{ + +} + +__attribute__((weak)) void app_advertising_stopped(void) +{ + +} + +__attribute__((weak)) void app_advertising_started(void) +{ + +} + +__attribute__((weak)) void app_connecting_started(void) +{ + +} + +__attribute__((weak)) void app_scanning_stopped(void) +{ + +} + +__attribute__((weak)) void app_connecting_stopped(void) +{ + +} + + +__attribute__((weak)) void app_scanning_started(void) +{ + +} + +__attribute__((weak)) void app_ble_system_ready(void) +{ + +} + +__attribute__((weak)) void app_adv_reported_scanned(struct gapm_adv_report_ind* ptInd) +{ + +} + +uint8_t* appm_get_current_ble_addr(void) +{ +#ifdef BLE_USE_RPA + return (uint8_t *)gapm_get_bdaddr(); +#else + return ble_addr; +#endif +} + +#define IS_WORKAROUND_SAME_BT_BLE_ADDR_FOR_RPA_CASEx +uint8_t* appm_get_local_identity_ble_addr(void) +{ +#if defined(BLE_USE_RPA)&&defined(IS_WORKAROUND_SAME_BT_BLE_ADDR_FOR_RPA_CASE) + return (uint8_t *)gapm_get_bdaddr(); +#else + return ble_addr; +#endif +} + +// bit mask of the existing conn param modes +static uint32_t existingBleConnParamModes[BLE_CONNECTION_MAX] = {0}; + +static BLE_CONN_PARAM_CONFIG_T ble_conn_param_config[] = +{ + // default value: for the case of BLE just connected and the BT idle state + {BLE_CONN_PARAM_MODE_DEFAULT, BLE_CONN_PARAM_PRIORITY_NORMAL, 24}, + + {BLE_CONN_PARAM_MODE_AI_STREAM_ON, BLE_CONN_PARAM_PRIORITY_ABOVE_NORMAL1, 24}, + + //{BLE_CONN_PARAM_MODE_A2DP_ON, BLE_CONN_PARAM_PRIORITY_ABOVE_NORMAL0, 36}, + + {BLE_CONN_PARAM_MODE_HFP_ON, BLE_CONN_PARAM_PRIORITY_ABOVE_NORMAL2, 36}, + + {BLE_CONN_PARAM_MODE_OTA, BLE_CONN_PARAM_PRIORITY_HIGH, 12}, + + {BLE_CONN_PARAM_MODE_OTA_SLOWER, BLE_CONN_PARAM_PRIORITY_HIGH, 20}, + + {BLE_CONN_PARAM_MODE_SNOOP_EXCHANGE, BLE_CONN_PARAM_PRIORITY_HIGH, 8}, + + // TODO: add mode cases if needed +}; + +void app_ble_reset_conn_param_mode(uint8_t conidx) +{ + uint32_t lock = int_lock_global(); + existingBleConnParamModes[conidx] = 0; + int_unlock_global(lock); +} + +void app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_E mode, bool isEnable) +{ + for (uint8_t index = 0;index < BLE_CONNECTION_MAX;index++) + { + if (BLE_CONNECTED == app_env.context[index].connectStatus) + { + app_ble_update_conn_param_mode_of_specific_connection( + index, mode, isEnable); + } + } +} + +bool app_ble_is_parameter_mode_enabled(uint8_t conidx, BLE_CONN_PARAM_MODE_E mode) +{ + bool isEnabled = false; + uint32_t lock = int_lock_global(); + isEnabled = existingBleConnParamModes[conidx]&(1 << mode); + int_unlock_global(lock); + + return isEnabled; +} + +void app_ble_parameter_mode_clear(uint8_t conidx, BLE_CONN_PARAM_MODE_E mode) +{ + uint32_t lock = int_lock_global(); + existingBleConnParamModes[conidx] &= (~(1 << mode)); + int_unlock_global(lock); +} + +void app_ble_update_conn_param_mode_of_specific_connection(uint8_t conidx, + BLE_CONN_PARAM_MODE_E mode, + bool isEnable) +{ + ASSERT(mode < BLE_CONN_PARAM_MODE_NUM, "Wrong ble conn param mode %d!", mode); + + uint32_t lock = int_lock_global(); + + // locate the conn param mode + BLE_CONN_PARAM_CONFIG_T *pConfig = NULL; + uint8_t index; + + for (index = 0; + index < sizeof(ble_conn_param_config) / sizeof(BLE_CONN_PARAM_CONFIG_T); + index++) + { + if (mode == ble_conn_param_config[index].ble_conn_param_mode) + { + pConfig = &ble_conn_param_config[index]; + break; + } + } + + if (NULL == pConfig) + { + int_unlock_global(lock); + LOG_W("conn param mode %d not defined!", mode); + return; + } + + if (isEnable) + { + if (0 == existingBleConnParamModes[conidx]) + { + // no other params existing, just configure this one + existingBleConnParamModes[conidx] = 1 << mode; + } + else + { + // already existing, directly return + if (existingBleConnParamModes[conidx]&(1 << mode)) + { + int_unlock_global(lock); + return; + } + else + { + // update the bit-mask + existingBleConnParamModes[conidx] |= (1 << mode); + + // not existing yet, need to go throuth the existing params to see whether + // we need to update the param + for (index = 0; + index < sizeof(ble_conn_param_config)/sizeof(BLE_CONN_PARAM_CONFIG_T); + index++) + { + if ((( uint32_t )1 << ( uint8_t )ble_conn_param_config[index].ble_conn_param_mode) & + existingBleConnParamModes[conidx]) + { + if (ble_conn_param_config[index].priority > pConfig->priority) + { + // one of the exiting param has higher priority than this one, + // so do nothing but update the bit-mask + int_unlock_global(lock); + return; + } + } + } + + // no higher priority conn param existing, so we need to apply this one + } + } + } + else + { + if (0 == existingBleConnParamModes[conidx]) + { + // no other params existing, just return + int_unlock_global(lock); + return; + } + else + { + // doesn't exist, directly return + if (!(existingBleConnParamModes[conidx]&(1 << mode))) + { + int_unlock_global(lock); + return; + } + else + { + // update the bit-mask + existingBleConnParamModes[conidx] &= (~(1 << mode)); + + if (0 == existingBleConnParamModes[conidx]) + { + int_unlock_global(lock); + return; + } + + pConfig = NULL; + + // existing, need to apply for the highest priority conn param + for (index = 0; + index < sizeof(ble_conn_param_config) / sizeof(BLE_CONN_PARAM_CONFIG_T); + index++) + { + if ((( uint32_t )1 << ( uint8_t )ble_conn_param_config[index].ble_conn_param_mode) & + existingBleConnParamModes[conidx]) + { + if (NULL != pConfig) + { + if (ble_conn_param_config[index].priority > pConfig->priority) + { + pConfig = &ble_conn_param_config[index]; + } + } + else + { + pConfig = &ble_conn_param_config[index]; + } + } + } + } + } + } + + int_unlock_global(lock); + + // if we can arrive here, it means we have got one config to apply + ASSERT(NULL != pConfig, "It's strange that config pointer is still NULL."); + + APP_BLE_CONN_CONTEXT_T* pContext = &(app_env.context[conidx]); + + if (pContext->connInterval != pConfig->conn_param_interval) + { + l2cap_update_param(conidx, pConfig->conn_param_interval*10/8, + pConfig->conn_param_interval*10/8, + BLE_CONN_PARAM_SUPERVISE_TIMEOUT_MS, + BLE_CONN_PARAM_SLAVE_LATENCY_CNT); + + LOG_I("try to update conn interval to %d", pConfig->conn_param_interval); + } + + LOG_I("conn param mode of conidx %d switched to:0x%x", + conidx, existingBleConnParamModes[conidx]); + +} + +void app_ble_save_negotiated_conn_param(uint8_t conidx, APP_BLE_NEGOTIATED_CONN_PARAM_T* pConnParam) +{ + if (conidx < BLE_CONNECTION_MAX) + { + negotiatedBleConnParam[conidx] = *pConnParam; + } +} + +bool app_ble_get_connection_interval(uint8_t conidx, APP_BLE_NEGOTIATED_CONN_PARAM_T* pConnParam) +{ + if ((conidx < BLE_CONNECTION_MAX) && + (BLE_CONNECTED == app_env.context[conidx].connectStatus)) + { + *pConnParam = negotiatedBleConnParam[conidx]; + return true; + } + else + { + return false; + } +} + +#if GFPS_ENABLED +uint8_t delay_update_conidx = BLE_INVALID_CONNECTION_INDEX; +#define FP_DELAY_UPDATE_BLE_CONN_PARAM_TIMER_VALUE (10000) +osTimerId fp_update_ble_param_timer = NULL; +static void fp_update_ble_connect_param_timer_handler(void const *param); +osTimerDef (FP_UPDATE_BLE_CONNECT_PARAM_TIMER, (void (*)(void const *))fp_update_ble_connect_param_timer_handler); +extern uint8_t is_sco_mode (void); +static void fp_update_ble_connect_param_timer_handler(void const *param) +{ + LOG_I("fp_update_ble_connect_param_timer_handler"); + for (uint8_t index = 0;index < BLE_CONNECTION_MAX;index++) + { + if ((BLE_CONNECTED == app_env.context[index].connectStatus) && + (index == delay_update_conidx)) + { + LOG_I("update connection interval of conidx %d", delay_update_conidx); + + if (is_sco_mode()) + { + app_ble_update_conn_param_mode_of_specific_connection(delay_update_conidx, BLE_CONN_PARAM_MODE_HFP_ON, true); + } + else + { + app_ble_update_conn_param_mode_of_specific_connection(delay_update_conidx, BLE_CONN_PARAM_MODE_DEFAULT, true); + } + break; + } + } + delay_update_conidx = BLE_INVALID_CONNECTION_INDEX; +} + +void fp_update_ble_connect_param_start(uint8_t ble_conidx) +{ + if (fp_update_ble_param_timer == NULL) + { + fp_update_ble_param_timer = osTimerCreate(osTimer(FP_UPDATE_BLE_CONNECT_PARAM_TIMER), osTimerOnce, NULL); + return; + } + + delay_update_conidx = ble_conidx; + if (fp_update_ble_param_timer) + osTimerStart(fp_update_ble_param_timer, FP_DELAY_UPDATE_BLE_CONN_PARAM_TIMER_VALUE); +} + +void fp_update_ble_connect_param_stop(uint8_t ble_conidx) +{ + if (delay_update_conidx == ble_conidx) + { + if (fp_update_ble_param_timer) + osTimerStop(fp_update_ble_param_timer); + delay_update_conidx = BLE_INVALID_CONNECTION_INDEX; + } +} +#endif + +#endif //(BLE_APP_PRESENT) +/// @} APP diff --git a/services/ble_app/app_main/app.h b/services/ble_app/app_main/app.h new file mode 100644 index 0000000..7ca9efa --- /dev/null +++ b/services/ble_app/app_main/app.h @@ -0,0 +1,395 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef APP_H_ +#define APP_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * @ingroup RICOW + * + * @brief Application entry point. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#ifdef BLE_APP_PRESENT + +#include // Standard Integer Definition +#include // Common BT Definitions +#include "arch.h" // Platform Definitions +#include "gapc.h" // GAPC Definitions +#include "gapm_task.h" +#if (NVDS_SUPPORT) +#include "nvds.h" +#endif // (NVDS_SUPPORT) + +#if defined(CFG_APP_SEC) +#if defined(CFG_SEC_CON) +#define BLE_AUTHENTICATION_LEVEL GAP_AUTH_REQ_SEC_CON_BOND +#else +#define BLE_AUTHENTICATION_LEVEL GAP_AUTH_REQ_MITM_BOND +#endif +#else +#define BLE_AUTHENTICATION_LEVEL GAP_AUTH_REQ_NO_MITM_NO_BOND +#endif + +/* + * DEFINES + **************************************************************************************** + */ +/// Maximal length of the Device Name value +#define APP_DEVICE_NAME_MAX_LEN (24) + +// Advertising mode +#define APP_FAST_ADV_MODE (1) +#define APP_SLOW_ADV_MODE (2) +#define APP_STOP_ADV_MODE (3) +#define APP_MAX_TX_OCTETS 251 +#define APP_MAX_TX_TIME 2120 + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ +typedef enum +{ + BLE_CONN_PARAM_MODE_DEFAULT = 0, + BLE_CONN_PARAM_MODE_AI_STREAM_ON, + BLE_CONN_PARAM_MODE_A2DP_ON, + BLE_CONN_PARAM_MODE_HFP_ON, + BLE_CONN_PARAM_MODE_OTA, + BLE_CONN_PARAM_MODE_OTA_SLOWER, + BLE_CONN_PARAM_MODE_SNOOP_EXCHANGE, + BLE_CONN_PARAM_MODE_NUM, +} BLE_CONN_PARAM_MODE_E; + +typedef enum +{ + BLE_CONN_PARAM_PRIORITY_NORMAL = 0, + BLE_CONN_PARAM_PRIORITY_ABOVE_NORMAL0, + BLE_CONN_PARAM_PRIORITY_ABOVE_NORMAL1, + BLE_CONN_PARAM_PRIORITY_ABOVE_NORMAL2, + BLE_CONN_PARAM_PRIORITY_HIGH, +} BLE_CONN_PARAM_PRIORITY_E; + +enum BLE_CONNECT_STATE { + BLE_DISCONNECTED = 0, + BLE_DISCONNECTING = 1, + BLE_CONNECTED = 2, +}; + +typedef struct +{ + uint8_t ble_conn_param_mode; + uint8_t priority; + uint16_t conn_param_interval; // in the unit of 1.25ms +} BLE_CONN_PARAM_CONFIG_T; + +#define BLE_CONN_PARAM_SLAVE_LATENCY_CNT 0 +#define BLE_CONN_PARAM_SUPERVISE_TIMEOUT_MS 6000 + +/// Application environment structure +typedef struct { + /// Connection handle + uint16_t conhdl; + uint8_t connectStatus; + uint8_t isFeatureExchanged; + /// Bonding status + uint8_t bonded; + uint8_t peerAddrType; + uint8_t isBdAddrResolvingInProgress; + uint8_t isGotSolvedBdAddr; + uint8_t bdAddr[BD_ADDR_LEN]; + uint8_t solvedBdAddr[BD_ADDR_LEN]; + uint16_t connInterval; + +} APP_BLE_CONN_CONTEXT_T; + +/// Application environment structure +struct app_env_tag +{ + uint8_t conn_cnt; + /// Last initialized profile + uint8_t next_svc; + + /// Device Name length + uint8_t dev_name_len; + /// Device Name + uint8_t dev_name[APP_DEVICE_NAME_MAX_LEN]; + + /// Local device IRK + uint8_t loc_irk[KEY_LEN]; + + APP_BLE_CONN_CONTEXT_T context[BLE_CONNECTION_MAX]; +}; + +// TODO: +typedef struct +{ + uint8_t role :2; + uint8_t earSide :1; + uint8_t isConnectedWithMobile :1; + uint8_t isConnectedWithTWS :1; + uint8_t reserved :3; +}__attribute__((__packed__)) BLE_ADV_CURRENT_STATE_T; + +typedef struct +{ + ///Connection interval value + uint16_t con_interval; + ///Connection latency value + uint16_t con_latency; + ///Supervision timeout + uint16_t sup_to; +} APP_BLE_NEGOTIATED_CONN_PARAM_T; + +// max adv data length is 31, and 3 byte is used for adv type flag(0x01) +#define ADV_DATA_MAX_LEN (28) + +/* + * GLOBAL VARIABLE DECLARATION + **************************************************************************************** + */ + +/// Application environment +extern struct app_env_tag app_env; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialize the BLE demo application. + **************************************************************************************** + */ +void appm_init(void); + +/** + **************************************************************************************** + * @brief Add a required service in the database + **************************************************************************************** + */ +bool appm_add_svc(void); + +/** + **************************************************************************************** + * @brief Put the device in general discoverable and connectable mode + **************************************************************************************** + */ +void appm_start_advertising(void *param); + +/** + **************************************************************************************** + * @brief Put the device in non discoverable and non connectable mode + **************************************************************************************** + */ +void appm_stop_advertising(void); + +/** + **************************************************************************************** + * @brief Send to request to update the connection parameters + **************************************************************************************** + */ +void appm_update_param(uint8_t conidx, struct gapc_conn_param *conn_param); + +/** + **************************************************************************************** + * @brief Send a disconnection request + **************************************************************************************** + */ +void appm_disconnect(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Retrieve device name + * + * @param[out] device name + * + * @return name length + **************************************************************************************** + */ +uint8_t appm_get_dev_name(uint8_t* name); + +/** + **************************************************************************************** + * @brief Return if the device is currently bonded + **************************************************************************************** + */ +bool app_sec_get_bond_status(void); + +/*--------------------------------------------------------------------------- + * app_ble_connected_evt_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * callback function of BLE connected event + * + * Parameters: + * conidx - connection index + * pPeerBdAddress - connected BLE device address + * + * Return: + * void + */ +void app_ble_connected_evt_handler(uint8_t conidx, const uint8_t* pPeerBdAddress); + +/*--------------------------------------------------------------------------- + * app_ble_disconnected_evt_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * ble disconnect event received callback + * + * Parameters: + * conidx - connection index + * + * Return: + * void + */ +void app_ble_disconnected_evt_handler(uint8_t conidx); + +void l2cap_update_param(uint8_t conidx, + uint32_t min_interval_in_ms, + uint32_t max_interval_in_ms, + uint32_t supervision_timeout_in_ms, + uint8_t slaveLantency); + +void appm_start_connecting(struct gap_bdaddr* ptBdAddr); + +void appm_stop_connecting(void); + +void appm_start_scanning(uint16_t intervalInMs, uint16_t windowInMs, uint32_t filtPolicy); + +void appm_stop_scanning(void); + +void appm_create_advertising(void); + +void appm_create_connecting(void); + +void app_advertising_stopped(void); + +void app_advertising_starting_failed(void); + +void app_adv_data_updated(void); + +void app_scanning_stopped(void); + +void app_scanning_starting_failed(void); + +void app_connecting_stopped(void); + +void app_connecting_failed(void); + +void appm_exchange_mtu(uint8_t conidx); + +void app_ble_system_ready(void); + +void app_adv_reported_scanned(struct gapm_adv_report_ind* ptInd); + +void appm_set_private_bd_addr(uint8_t* bdAddr); + +void appm_add_dev_into_whitelist(struct gap_bdaddr* ptBdAddr); + +void app_scanning_started(void); + +void app_advertising_started(void); + +void app_connecting_stopped(void); + +void app_connecting_started(void); + +bool appm_resolve_random_ble_addr_from_nv(uint8_t conidx, uint8_t* randomAddr); + +void appm_resolve_random_ble_addr_with_sepcific_irk(uint8_t conidx, uint8_t* randomAddr, uint8_t* pIrk); + +void appm_random_ble_addr_solved(bool isSolvedSuccessfully, uint8_t* irkUsedForSolving); + +uint8_t app_ble_connection_count(void); + +bool app_is_arrive_at_max_ble_connections(void); + +bool app_is_resolving_ble_bd_addr(void); + +void app_enter_fastpairing_mode(void); + +bool app_is_in_fastpairing_mode(void); + +void app_set_in_fastpairing_mode_flag(bool isEnabled); + +uint16_t appm_get_conhdl_from_conidx(uint8_t conidx); + +void appm_check_and_resolve_ble_address(uint8_t conidx); + +uint8_t* appm_get_current_ble_addr(void); + +void app_trigger_ble_service_discovery(uint8_t conidx, uint16_t shl, uint16_t ehl); + +uint8_t* appm_get_local_identity_ble_addr(void); + +void app_exchange_remote_feature(uint8_t conidx); + +void app_ble_update_conn_param_mode_of_specific_connection(uint8_t conidx, BLE_CONN_PARAM_MODE_E mode, bool isEnable); + +void app_ble_reset_conn_param_mode_of_specifc_connection(uint8_t conidx); + +void app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_E mode, bool isEnable); + +void app_ble_reset_conn_param_mode(uint8_t conidx); + +void appm_refresh_ble_irk(void); + +void app_ble_save_negotiated_conn_param(uint8_t conidx, APP_BLE_NEGOTIATED_CONN_PARAM_T* pConnParam); + +bool app_ble_get_connection_interval(uint8_t conidx, APP_BLE_NEGOTIATED_CONN_PARAM_T* pConnParam); + +void appm_update_adv_data(uint8_t* pAdvData, uint32_t advDataLen, + uint8_t* pScanRspData, uint32_t scanRspDataLen); + +bool gattc_check_if_notification_processing_is_busy(uint8_t conidx); + +#ifdef GFPS_ENABLED +void fp_update_ble_connect_param_start(uint8_t ble_conidx); +void fp_update_ble_connect_param_stop(uint8_t ble_conidx); +#endif + +bool app_ble_is_parameter_mode_enabled(uint8_t conidx, BLE_CONN_PARAM_MODE_E mode); + +void app_ble_parameter_mode_clear(uint8_t conidx, BLE_CONN_PARAM_MODE_E mode); + +#ifdef __cplusplus +} +#endif + +/// @} APP + +#endif //(BLE_APP_PRESENT) + +#endif // APP_H_ diff --git a/services/ble_app/app_main/app_ble_core.c b/services/ble_app/app_main/app_ble_core.c new file mode 100644 index 0000000..87fbbed --- /dev/null +++ b/services/ble_app/app_main/app_ble_core.c @@ -0,0 +1,335 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +/*****************************header include********************************/ +#include "string.h" +#include "co_math.h" // Common Maths Definition +#include "cmsis_os.h" +#include "ble_app_dbg.h" +#include "stdbool.h" +#include "app_thread.h" +#include "app_utils.h" +#include "app_a2dp.h" + +#include "apps.h" +#include "app.h" +#include "app_sec.h" +#include "app_ble_mode_switch.h" +#include "app_ble_core.h" +#include "nvrecord.h" +#include "app_bt_func.h" +#include "hal_timer.h" +#include "app_bt.h" +#include "app_hfp.h" +#include "rwprf_config.h" +#include "nvrecord_ble.h" +#include "app_sec.h" +#ifdef IBRT +#include "app_ibrt_ui.h" +#include "app_tws_if.h" +#endif + +extern uint8_t is_sco_mode (void); + +static APP_BLE_CORE_GLOBAL_HANDLER_FUNC g_ble_core_global_handler_ind = NULL; +static APP_BLE_CORE_GLOBAL_CALLBACK_HANDLER_FUNC g_ble_core_global_callback_handler_ind = NULL; + +void app_ble_core_register_global_handler_ind(APP_BLE_CORE_GLOBAL_HANDLER_FUNC handler) +{ + g_ble_core_global_handler_ind = handler; +} + +void app_ble_core_register_global_callback_handle_ind(APP_BLE_CORE_GLOBAL_CALLBACK_HANDLER_FUNC handler) +{ + g_ble_core_global_callback_handler_ind = handler; +} + +static void ble_connect_event_handler(ble_evnet_t *event, void *output) +{ +#ifdef TWS_SYSTEM_ENABLED + app_tws_if_ble_connected_handler(); +#endif +#ifdef IBRT + bd_addr_t *box_ble_addr = (bd_addr_t *)app_ibrt_ui_get_box_ble_addr(); + if (app_ibrt_ui_get_snoop_via_ble_enable()) + { + if(!memcmp(box_ble_addr, event->p.connect_handled.peer_bdaddr, BTIF_BD_ADDR_SIZE)) + { + app_ibrt_ui_set_ble_connect_index(event->p.connect_handled.conidx); + app_ibrt_ui_set_box_connect_state(IBRT_BOX_CONNECT_MASTER, FALSE); + } + } +#endif +} + +static void ble_disconnect_event_handler(ble_evnet_t *event, void *output) +{ +#ifdef IBRT + if (app_ibrt_ui_get_snoop_via_ble_enable()) + { + app_ibrt_ui_set_master_notify_flag(false); + app_ibrt_ui_clear_box_connect_state(IBRT_BOX_CONNECT_MASTER, FALSE); + } +#endif +} + +static void ble_conn_param_update_req_event_handler(ble_evnet_t *event, void *output) +{ + if (a2dp_is_music_ongoing() || is_sco_mode()) + { + *(bool *)output = false; + } +} + +static void ble_set_random_bd_addr_event_handler(ble_evnet_t *event, void *output) +{ + // Indicate that a new random BD address set in lower layers +} + +static const ble_event_handler_t ble_event_handler_tab[] = +{ + {BLE_CONNECT_EVENT, ble_connect_event_handler}, + {BLE_DISCONNECT_EVENT, ble_disconnect_event_handler}, + {BLE_CONN_PARAM_UPDATE_REQ_EVENT, ble_conn_param_update_req_event_handler}, + {BLE_SET_RANDOM_BD_ADDR_EVENT, ble_set_random_bd_addr_event_handler}, +}; + +//handle the event that from ble lower layers +void app_ble_core_global_handle(ble_evnet_t *event, void *output) +{ + uint8_t evt_type = event->evt_type; + uint16_t index = 0; + const ble_event_handler_t *p_ble_event_hand = NULL; + + for (index=0; indexevt_type == evt_type) + { + p_ble_event_hand->func(event, output); + break; + } + } + + if (g_ble_core_global_handler_ind) + { + g_ble_core_global_handler_ind(event, output); + } +} + + +static void ble_callback_roleswitch_start_handler(ble_callback_evnet_t *event, void *output) +{ + LOG_I("%s", __func__); + // disable adv after role switch start + app_ble_force_switch_adv(BLE_SWITCH_USER_RS, false); +} + +static void ble_callback_roleswitch_complete_handler(ble_callback_evnet_t *event, void *output) +{ +#if defined(IBRT) + // enable adv after role switch complete + uint8_t newRole = event->p.rs_complete_handled.newRole; + LOG_I("%s newRole %d", __func__, newRole); + app_ble_force_switch_adv(BLE_SWITCH_USER_RS, true); + if (newRole == IBRT_SLAVE) + { + app_ble_disconnect_all(); + } +#endif +} + +static void ble_callback_role_update_handler(ble_callback_evnet_t *event, void *output) +{ +#if defined(IBRT) + uint8_t newRole = event->p.role_update_handled.newRole; + LOG_I("%s newRole %d", __func__, newRole); + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); + if (newRole == IBRT_SLAVE) + { + app_ble_disconnect_all(); + } +#endif +} + +static void ble_callback_ibrt_event_entry_handler(ble_callback_evnet_t *event, void *output) +{ +#if defined(IBRT) + uint8_t ibrt_evt_type = event->p.ibrt_event_entry_handled.event; + LOG_I("%s evt_type %d", __func__, ibrt_evt_type); + if (IBRT_OPEN_BOX_EVENT == ibrt_evt_type) + { + app_ble_force_switch_adv(BLE_SWITCH_USER_BOX, true); + } + else if (IBRT_FETCH_OUT_EVENT == ibrt_evt_type) + { + app_ble_force_switch_adv(BLE_SWITCH_USER_BOX, true); + } + else if (IBRT_CLOSE_BOX_EVENT == ibrt_evt_type) + { + app_ble_force_switch_adv(BLE_SWITCH_USER_BOX, false); + } +#endif +} + +static const ble_callback_event_handler_t ble_callback_event_handler_tab[] = +{ + {BLE_CALLBACK_RS_START, ble_callback_roleswitch_start_handler}, + {BLE_CALLBACK_RS_COMPLETE, ble_callback_roleswitch_complete_handler}, + {BLE_CALLBACK_ROLE_UPDATE, ble_callback_role_update_handler}, + {BLE_CALLBACK_IBRT_EVENT_ENTRY, ble_callback_ibrt_event_entry_handler}, +}; + +//handle the event that from other module +void app_ble_core_global_callback_event(ble_callback_evnet_t *event, void *output) +{ + uint8_t evt_type = event->evt_type; + uint16_t index = 0; + const ble_callback_event_handler_t *p_ble_callback_event_hand = NULL; + + for (index=0; indexevt_type == evt_type) + { + p_ble_callback_event_hand->func(event, output); + break; + } + } + + if (g_ble_core_global_callback_handler_ind) + { + g_ble_core_global_callback_handler_ind(event, output); + } +} + +static void app_ble_stub_user_data_fill_handler(void *param) +{ + LOG_I("%s", __func__); + bool adv_enable = false; + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (!p_ibrt_ctrl->init_done) + { + LOG_I("%s ibrt don't init", __func__); + } + else if (p_ibrt_ctrl->current_role != IBRT_MASTER) + { + LOG_I("%s role %d isn't MASTER", __func__, p_ibrt_ctrl->current_role); + } + else +#endif + if (app_ble_get_user_register() & ~(1 << USER_STUB)) + { + LOG_I("%s have other user register 0x%x", __func__, app_ble_get_user_register()); + } + else + { + adv_enable = true; + } + + app_ble_data_fill_enable(USER_STUB, adv_enable); +} + +void app_ble_stub_user_init(void) +{ + LOG_I("%s", __func__); + app_ble_register_data_fill_handle(USER_STUB, (BLE_DATA_FILL_FUNC_T)app_ble_stub_user_data_fill_handler, false); +} + +#ifdef TWS_SYSTEM_ENABLED +static void ble_sync_info_prepare_handler(uint8_t *buf, uint16_t *length) +{ + *length = sizeof(NV_RECORD_PAIRED_BLE_DEV_INFO_T); + + NV_RECORD_PAIRED_BLE_DEV_INFO_T *pBleInfo = nv_record_blerec_get_ptr(); + + memcpy(buf, pBleInfo, *length); +} + +static void ble_sync_info_received_handler(uint8_t *buf, uint16_t length) +{ + NV_RECORD_PAIRED_BLE_DEV_INFO_T *pReceivedBleInfo = (NV_RECORD_PAIRED_BLE_DEV_INFO_T *)buf; + + // basic info + nv_record_extension_update_tws_ble_info(pReceivedBleInfo); + + // pair info + for (uint32_t index = 0; index < pReceivedBleInfo->saved_list_num; index++) + { + nv_record_blerec_add(&pReceivedBleInfo->ble_nv[index]); + } + +#ifdef CFG_APP_SEC + app_sec_init(); +#endif +} + +static void ble_sync_info_rsp_received_handler(uint8_t *buf, uint16_t length) +{ + NV_RECORD_PAIRED_BLE_DEV_INFO_T *pReceivedBleInfo = (NV_RECORD_PAIRED_BLE_DEV_INFO_T *)buf; + + nv_record_extension_update_tws_ble_info(pReceivedBleInfo); + for (uint32_t index = 0; index < pReceivedBleInfo->saved_list_num; index++) + { + nv_record_blerec_add(&pReceivedBleInfo->ble_nv[index]); + } +} + +void app_ble_mode_tws_sync_init(void) +{ + TWS_SYNC_USER_T userBle = { + ble_sync_info_prepare_handler, + ble_sync_info_received_handler, + ble_sync_info_prepare_handler, + ble_sync_info_rsp_received_handler, + NULL, + }; + + app_tws_if_register_sync_user(TWS_SYNC_USER_BLE_INFO, &userBle); +} + +void app_ble_sync_ble_info(void) +{ + app_tws_if_sync_info(TWS_SYNC_USER_BLE_INFO); +} +#endif + +void ble_adv_data_parse(uint8_t *bleBdAddr, + int8_t rssi, + unsigned char *adv_buf, + unsigned char len) +{ +#ifdef IBRT + bd_addr_t *box_ble_addr = (bd_addr_t *)app_ibrt_ui_get_box_ble_addr(); + LOG_I("%s", __func__); + //DUMP8("%02x ", (uint8_t *)box_ble_addr, BTIF_BD_ADDR_SIZE); + DUMP8("%02x ", bleBdAddr, BTIF_BD_ADDR_SIZE); + + if (app_ibrt_ui_get_snoop_via_ble_enable()) + { + if (!memcmp(box_ble_addr, bleBdAddr, BTIF_BD_ADDR_SIZE) && app_ibrt_ui_is_slave_scaning()) + { + app_ibrt_ui_set_slave_scaning(FALSE); + app_scanning_stopped(); + app_ble_start_connect((uint8_t *)box_ble_addr); + } + } +#endif +} + diff --git a/services/ble_app/app_main/app_ble_core.h b/services/ble_app/app_main/app_ble_core.h new file mode 100644 index 0000000..e633ddc --- /dev/null +++ b/services/ble_app/app_main/app_ble_core.h @@ -0,0 +1,250 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +#ifndef __APP_BLE_CORE_H__ +#define __APP_BLE_CORE_H__ + +/*****************************header include********************************/ + +/******************************macro defination*****************************/ + +/******************************type defination******************************/ +/** + * @brief The event type of the ble + * + */ +typedef enum{ + BLE_CONNECT_EVENT = 0, + BLE_DISCONNECT_EVENT, + BLE_CONN_PARAM_UPDATE_REQ_EVENT, + BLE_SET_RANDOM_BD_ADDR_EVENT, + + BLE_EVENT_NUM_MAX, +} ble_evnet_type_e; + +/** + * @brief The event type of other module + * + */ +typedef enum{ + BLE_CALLBACK_RS_START = 0, + BLE_CALLBACK_RS_COMPLETE, + BLE_CALLBACK_ROLE_UPDATE, + BLE_CALLBACK_IBRT_EVENT_ENTRY, + + BLE_CALLBACK_EVENT_NUM_MAX, +} ble_callback_evnet_type_e; + +typedef struct { + ble_evnet_type_e evt_type; + union { + struct { + uint8_t conidx; + const uint8_t *peer_bdaddr; + } connect_handled; + struct { + uint8_t conidx; + } disconnect_handled; + struct { + /// Connection interval minimum + uint16_t intv_min; + /// Connection interval maximum + uint16_t intv_max; + /// Latency + uint16_t latency; + /// Supervision timeout + uint16_t time_out; + } conn_param_update_req_handled; + struct { + uint8_t *new_bdaddr; + } set_random_bd_addr_handled; + } p; +} ble_evnet_t; + +typedef struct { + ble_callback_evnet_type_e evt_type; + union { + struct { + uint8_t newRole; + } rs_complete_handled; + struct { + uint8_t newRole; + } role_update_handled; + struct { + uint8_t event; + } ibrt_event_entry_handled; + } p; +} ble_callback_evnet_t; + +typedef void (*APP_BLE_CORE_GLOBAL_HANDLER_FUNC)(ble_evnet_t *, void *); +typedef void (*APP_BLE_CORE_GLOBAL_CALLBACK_HANDLER_FUNC)(ble_callback_evnet_t *, void *); + + +// Element of a message handler table. +typedef struct { + // evt_type of the ble event + ble_evnet_type_e evt_type; + // Pointer to the handler function for the ble event above. + APP_BLE_CORE_GLOBAL_HANDLER_FUNC func; +} ble_event_handler_t; + +// Element of a message handler table. +typedef struct { + // evt_type of the ble callback event + ble_callback_evnet_type_e evt_type; + // Pointer to the handler function for the ble callback event above. + APP_BLE_CORE_GLOBAL_CALLBACK_HANDLER_FUNC func; +} ble_callback_event_handler_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + * app_ble_core_register_global_handler_ind + *--------------------------------------------------------------------------- + * + *Synopsis: + * to register custom handler function + * + * Parameters: + * handler -- custom handler function + * + * Return: + * void + */ +void app_ble_core_register_global_handler_ind(APP_BLE_CORE_GLOBAL_HANDLER_FUNC handler); + +/*--------------------------------------------------------------------------- + * app_ble_core_register_global_callback_handle_ind + *--------------------------------------------------------------------------- + * + *Synopsis: + * to register custom callback handler function + * + * Parameters: + * handler -- custom callback handler function + * + * Return: + * void + */ +void app_ble_core_register_global_callback_handle_ind(APP_BLE_CORE_GLOBAL_CALLBACK_HANDLER_FUNC handler); + +/*--------------------------------------------------------------------------- + * app_ble_core_global_handle + *--------------------------------------------------------------------------- + * + *Synopsis: + * for ble core to handle event + * + * Parameters: + * *event -- the event ble core need to handle + * + * Return: + * uint32_t + */ +void app_ble_core_global_handle(ble_evnet_t *event, void *output); + +/*--------------------------------------------------------------------------- + * app_ble_core_global_callback_event + *--------------------------------------------------------------------------- + * + *Synopsis: + * for ble core to handle callback event + * + * Parameters: + * *event -- the event ble core need to handle + * + * Return: + * void + */ +void app_ble_core_global_callback_event(ble_callback_evnet_t *event, void *output); + +/*--------------------------------------------------------------------------- + * app_ble_stub_user_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * None + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ble_stub_user_init(void); + +/****************************function declearation**************************/ +/*--------------------------------------------------------------------------- + * app_ble_sync_ble_info + *--------------------------------------------------------------------------- + * + *Synopsis: + * for tws sync ble info + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ble_sync_ble_info(void); + +/*--------------------------------------------------------------------------- + * app_ble_mode_tws_sync_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * tws related environment initialization for ble module + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ble_mode_tws_sync_init(void); + +/****************************function declearation**************************/ +/*--------------------------------------------------------------------------- + * ble_adv_data_parse + *--------------------------------------------------------------------------- + * + *Synopsis: + * for ble core to parse adv data + * + * Parameters: + * bleBdAddr -- ble address + * rssi -- ble rssi + * adv_buf -- adv data + * len -- adv data length + * + * Return: + * void + */ +void ble_adv_data_parse(uint8_t *bleBdAddr, + int8_t rssi, + unsigned char *adv_buf, + unsigned char len); + + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __APP_BLE_CORE_H__ */ + diff --git a/services/ble_app/app_main/app_ble_customif.c b/services/ble_app/app_main/app_ble_customif.c new file mode 100644 index 0000000..ed98545 --- /dev/null +++ b/services/ble_app/app_main/app_ble_customif.c @@ -0,0 +1,133 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +/*****************************header include********************************/ +#include "string.h" +#include "co_math.h" // Common Maths Definition +#include "cmsis_os.h" +#include "ble_app_dbg.h" +#include "stdbool.h" +#include "app_thread.h" +#include "app_utils.h" +#include "apps.h" +#include "app.h" +#include "app_sec.h" +#include "app_ble_include.h" +#include "nvrecord.h" +#include "app_bt_func.h" +#include "hal_timer.h" +#include "app_bt.h" +#include "app_hfp.h" +#include "rwprf_config.h" +#include "nvrecord_ble.h" +#include "app_sec.h" +#ifdef IBRT +#include "app_ibrt_ui.h" +#include "app_tws_if.h" +#endif + +static void app_ble_customif_connect_event_handler(ble_evnet_t *event, void *output) +{ +} + +static void app_ble_customif_disconnect_event_handler(ble_evnet_t *event, void *output) +{ +} + +static void app_ble_customif_conn_param_update_req_event_handler(ble_evnet_t *event, void *output) +{ +} + +static void app_ble_customif_set_random_bd_addr_event_handler(ble_evnet_t *event, void *output) +{ + // Indicate that a new random BD address set in lower layers +} + +static const ble_event_handler_t app_ble_customif_event_handler_tab[] = +{ + {BLE_CONNECT_EVENT, app_ble_customif_connect_event_handler}, + {BLE_DISCONNECT_EVENT, app_ble_customif_disconnect_event_handler}, + {BLE_CONN_PARAM_UPDATE_REQ_EVENT, app_ble_customif_conn_param_update_req_event_handler}, + {BLE_SET_RANDOM_BD_ADDR_EVENT, app_ble_customif_set_random_bd_addr_event_handler}, +}; + +//handle the event that from ble lower layers +void app_ble_customif_global_handler_ind(ble_evnet_t *event, void *output) +{ + uint8_t evt_type = event->evt_type; + uint16_t index = 0; + const ble_event_handler_t *p_ble_event_hand = NULL; + + for (index=0; indexevt_type == evt_type) + { + p_ble_event_hand->func(event, output); + break; + } + } +} + +static void app_ble_customif_callback_roleswitch_start_handler(ble_callback_evnet_t *event, void *output) +{ +} + +static void app_ble_customif_callback_roleswitch_complete_handler(ble_callback_evnet_t *event, void *output) +{ +} + +static void app_ble_customif_callback_role_update_handler(ble_callback_evnet_t *event, void *output) +{ +} + +static void app_ble_customif_callback_ibrt_event_entry_handler(ble_callback_evnet_t *event, void *output) +{ +} + +static const ble_callback_event_handler_t app_ble_customif_callback_event_handler_tab[] = +{ + {BLE_CALLBACK_RS_START, app_ble_customif_callback_roleswitch_start_handler}, + {BLE_CALLBACK_RS_COMPLETE, app_ble_customif_callback_roleswitch_complete_handler}, + {BLE_CALLBACK_ROLE_UPDATE, app_ble_customif_callback_role_update_handler}, + {BLE_CALLBACK_IBRT_EVENT_ENTRY, app_ble_customif_callback_ibrt_event_entry_handler}, +}; + +//handle the event that from other module +void app_ble_customif_global_callback_handler_ind(ble_callback_evnet_t *event, void *output) +{ + uint8_t evt_type = event->evt_type; + uint16_t index = 0; + const ble_callback_event_handler_t *p_ble_callback_event_hand = NULL; + + for (index=0; indexevt_type == evt_type) + { + p_ble_callback_event_hand->func(event, output); + break; + } + } +} + +void app_ble_customif_init(void) +{ + LOG_I("%s", __func__); + app_ble_core_register_global_handler_ind(app_ble_customif_global_handler_ind); + app_ble_core_register_global_callback_handle_ind(app_ble_customif_global_callback_handler_ind); +} + diff --git a/services/ble_app/app_main/app_ble_customif.h b/services/ble_app/app_main/app_ble_customif.h new file mode 100644 index 0000000..f0900d7 --- /dev/null +++ b/services/ble_app/app_main/app_ble_customif.h @@ -0,0 +1,52 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +#ifndef __APP_BLE_CUSTOMIF_H__ +#define __APP_BLE_CUSTOMIF_H__ + +/*****************************header include********************************/ + +/******************************macro defination*****************************/ + +/******************************type defination******************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*--------------------------------------------------------------------------- + * app_ble_customif_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * None + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ble_customif_init(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __APP_BLE_CUSTOMIF_H__ */ + diff --git a/services/ble_app/app_main/app_ble_include.h b/services/ble_app/app_main/app_ble_include.h new file mode 100644 index 0000000..c9fa981 --- /dev/null +++ b/services/ble_app/app_main/app_ble_include.h @@ -0,0 +1,36 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +#ifndef __APP_BLE_INCLUDE_H__ +#define __APP_BLE_INCLUDE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************header include********************************/ +#include "app_ble_core.h" +#include "app_ble_mode_switch.h" +#include "app_ble_customif.h" + + + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __APP_BLE_INCLUDE_H__ */ + diff --git a/services/ble_app/app_main/app_ble_mode_switch.c b/services/ble_app/app_main/app_ble_mode_switch.c new file mode 100644 index 0000000..e66be14 --- /dev/null +++ b/services/ble_app/app_main/app_ble_mode_switch.c @@ -0,0 +1,1210 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +/*****************************header include********************************/ +#include "string.h" +#include "co_math.h" // Common Maths Definition +#include "cmsis_os.h" +#include "ble_app_dbg.h" +#include "stdbool.h" +#include "app_thread.h" +#include "app_utils.h" +#include "apps.h" +#include "app.h" +#include "app_sec.h" +#include "app_ble_include.h" +#include "nvrecord.h" +#include "app_bt_func.h" +#include "hal_timer.h" +#include "app_bt.h" +#include "app_hfp.h" +#include "rwprf_config.h" +#include "nvrecord_ble.h" +#include "app_sec.h" + +/************************private macro defination***************************/ +#define DEBUG_BLE_STATE_MACHINE true + +#if DEBUG_BLE_STATE_MACHINE +#define SET_BLE_STATE(newState) \ + do \ + { \ + LOG_I("[STATE]%s->%s at line %d", ble_state2str(bleModeEnv.state), ble_state2str(newState), __LINE__); \ + bleModeEnv.state = (newState); \ + } while (0); + +#define SET_BLE_OP(newOp) \ + do \ + { \ + LOG_I("[OP]%s->%s at line %d", ble_op2str(bleModeEnv.op), ble_op2str(newOp), __LINE__); \ + bleModeEnv.op = (newOp); \ + } while (0); +#else +#define SET_BLE_STATE(newState) \ + do \ + { \ + bleModeEnv.state = (newState); \ + } while (0); + +#define SET_BLE_OP(newOp) \ + do \ + { \ + bleModeEnv.op = (newOp); \ + } while (0); +#endif + + +extern void bt_drv_reg_op_set_rand_seed(uint32_t seed); + +/************************private type defination****************************/ + +/************************extern function declearation***********************/ +extern uint8_t bt_addr[6]; + +/**********************private function declearation************************/ +/*--------------------------------------------------------------------------- + * ble_state2str + *--------------------------------------------------------------------------- + * + *Synopsis: + * get the string of the ble state + * + * Parameters: + * state - state to get string + * + * Return: + * the string of the BLE state + */ +static char *ble_state2str(uint8_t state); + +/*--------------------------------------------------------------------------- + * ble_op2str + *--------------------------------------------------------------------------- + * + *Synopsis: + * get the string of the ble operation + * + * Parameters: + * op - operation to get string + * + * Return: + * the string of the BLE operation + */ +static char *ble_op2str(uint8_t op); + +/*--------------------------------------------------------------------------- + * ble_adv_user2str + *--------------------------------------------------------------------------- + * + *Synopsis: + * get the string of the ble_adv_user + * + * Parameters: + * op - operation to get string + * + * Return: + * the string of the ble_adv_user + */ +static char *ble_adv_user2str(enum BLE_ADV_USER_E user); + +/*--------------------------------------------------------------------------- + * ble_adv_config_param + *--------------------------------------------------------------------------- + * + *Synopsis: + * configure BLE adv related parameter in @advParam for further use + * + * Parameters: + * advType - advertisment mode, see @ for more info + * advInterval - advertisement interval in MS + * + * Return: + * void + */ +static void ble_adv_config_param(uint8_t advType, uint16_t advInterval); + +/*--------------------------------------------------------------------------- + * ble_adv_is_allowed + *--------------------------------------------------------------------------- + * + *Synopsis: + * check if BLE advertisment is allowed or not + * + * Parameters: + * void + * + * Return: + * true - if advertisement is allowed + * flase - if adverstisement is not allowed + */ +static bool ble_adv_is_allowed(void); + +/*--------------------------------------------------------------------------- + * ble_start_adv + *--------------------------------------------------------------------------- + * + *Synopsis: + * start BLE advertisement + * + * Parameters: + * param - see @BLE_ADV_PARAM_T to get more info + * + * Return: + * void + */ +static void ble_start_adv(void *param); + +/*--------------------------------------------------------------------------- + * ble_start_adv_failed_cb + *--------------------------------------------------------------------------- + * + *Synopsis: + * callback function of start BLE advertisement failed + * + * Parameters: + * void + * + * Return: + * void + */ +static void ble_start_adv_failed_cb(void); + +/*--------------------------------------------------------------------------- + * ble_start_scan + *--------------------------------------------------------------------------- + * + *Synopsis: + * start BLE scan api + * + * Parameters: + * param - see @BLE_SCAN_PARAM_T to get more info + * + * Return: + * void + */ +static void ble_start_scan(void *param); + +/*--------------------------------------------------------------------------- + * ble_start_connect + *--------------------------------------------------------------------------- + * + *Synopsis: + * start BLE connection + * + * Parameters: + * bleBdAddr - address of BLE device to connect + * + * Return: + * void + */ +static void ble_start_connect(uint8_t *bleBdAddr); + +/*--------------------------------------------------------------------------- + * ble_stop_all_activities + *--------------------------------------------------------------------------- + * + *Synopsis: + * stop all BLE pending operations, stop ongoing adv and scan + * NOTE: will not disconnect BLE connections + * + * Parameters: + * void + * + * Return: + * void + */ +static void ble_stop_all_activities(void); + +/*--------------------------------------------------------------------------- + * ble_execute_pending_op + *--------------------------------------------------------------------------- + * + *Synopsis: + * execute pended BLE op + * + * Parameters: + * void + * + * Return: + * void + */ +static void ble_execute_pending_op(void); + +/*--------------------------------------------------------------------------- + * ble_switch_activities + *--------------------------------------------------------------------------- + * + *Synopsis: + * switch BLE activities after last state complete + * + * Parameters: + * void + * + * Return: + * void + */ +static void ble_switch_activities(void); + +/************************private variable defination************************/ +static BLE_MODE_ENV_T bleModeEnv; +static BLE_ADV_PARAM_T advParam; +static BLE_SCAN_PARAM_T scanParam; + +/****************************function defination****************************/ +// common used function +#ifdef USE_LOG_I_ID +static inline char *ble_state2str(uint8_t state) +{ + return (char *)(uint32_t)state; +} +static inline char *ble_op2str(uint8_t op) +{ + return (char *)(uint32_t)op; +} +static inline char *ble_adv_user2str(enum BLE_ADV_USER_E user) +{ + return (char *)(uint32_t)user; +} + +#else +static char *ble_state2str(uint8_t state) +{ + char *str = NULL; + +#define CASES(state) \ + case state: \ + str = "[" #state "]"; \ + break + + switch (state) + { + CASES(STATE_IDLE); + CASES(ADVERTISING); + CASES(STARTING_ADV); + CASES(STOPPING_ADV); + CASES(SCANNING); + CASES(STARTING_SCAN); + CASES(STOPPING_SCAN); + CASES(CONNECTING); + CASES(STARTING_CONNECT); + CASES(STOPPING_CONNECT); + + default: + str = "[INVALID]"; + break; + } + + return str; +} + +static char *ble_op2str(uint8_t op) +{ + char *str = NULL; + +#define CASEO(op) \ + case op: \ + str = "[" #op "]"; \ + break + + switch (op) + { + CASEO(OP_IDLE); + CASEO(START_ADV); + CASEO(START_SCAN); + CASEO(START_CONNECT); + CASEO(STOP_ADV); + CASEO(STOP_SCAN); + CASEO(STOP_CONNECT); + + default: + str = "[INVALID]"; + break; + } + + return str; +} + +static char *ble_adv_user2str(enum BLE_ADV_USER_E user) +{ +#define CASE_S(s) \ + case s: \ + return "[" #s "]"; +#define CASE_D() \ + default: \ + return "[INVALID]"; + + switch (user) + { + CASE_S(USER_STUB) + CASE_S(USER_GFPS) + CASE_S(USER_GSOUND) + CASE_S(USER_AI) + CASE_S(USER_INTERCONNECTION) + CASE_S(USER_TILE) + CASE_S(USER_OTA) + CASE_D() + } +} +#endif + + +void app_ble_mode_init(void) +{ + LOG_I("%s", __func__); + + memset(&bleModeEnv, 0, sizeof(bleModeEnv)); + SET_BLE_STATE(STATE_IDLE); + SET_BLE_OP(OP_IDLE); + + bleModeEnv.bleEnv = &app_env; +} + +// ble advertisement used functions +static void ble_adv_config_param(uint8_t advType, uint16_t advInterval) +{ + uint8_t avail_space; + memset(&advParam, 0, sizeof(advParam)); + + advParam.advType = advType; + advParam.advInterval = advInterval; + advParam.withFlag = true; + + // connectable adv is not allowed if max connection reaches + if (app_is_arrive_at_max_ble_connections() && (GAPM_ADV_UNDIRECT == advType)) + { + LOG_W("will change adv type to none-connectable because max ble connection reaches"); + advParam.advType = GAPM_ADV_NON_CONN; + } + + for (uint8_t user = 0; user < BLE_ADV_USER_NUM; user++) + { + if (bleModeEnv.bleDataFillFunc[user]) + { + bleModeEnv.bleDataFillFunc[user]((void *)&advParam); + + // check if the adv/scan_rsp data length is legal + if(advParam.withFlag) + { + ASSERT(BLE_ADV_DATA_WITH_FLAG_LEN >= advParam.advDataLen, "[BLE][ADV]adv data exceed"); + } + else + { + ASSERT(BLE_ADV_DATA_WITHOUT_FLAG_LEN >= advParam.advDataLen, "[BLE][ADV]adv data exceed"); + } + ASSERT(SCAN_RSP_DATA_LEN >= advParam.scanRspDataLen, "[BLE][ADV]scan response data exceed"); + } + } + + if(advParam.withFlag) + { + avail_space = BLE_ADV_DATA_WITH_FLAG_LEN - advParam.advDataLen - BLE_ADV_DATA_STRUCT_HEADER_LEN; + } + else + { + avail_space = BLE_ADV_DATA_WITHOUT_FLAG_LEN - advParam.advDataLen - BLE_ADV_DATA_STRUCT_HEADER_LEN; + } + + // Check if data can be added to the adv Data + if (avail_space > 2) + { + avail_space = co_min(avail_space, bleModeEnv.bleEnv->dev_name_len); + advParam.advData[advParam.advDataLen++] = avail_space + 1; + // Fill Device Name Flag + advParam.advData[advParam.advDataLen++] = + (avail_space == bleModeEnv.bleEnv->dev_name_len) ? '\x08' : '\x09'; + // Copy device name + memcpy(&advParam.advData[advParam.advDataLen], bleModeEnv.bleEnv->dev_name, avail_space); + // Update adv Data Length + advParam.advDataLen += avail_space; + } +} + +static bool ble_adv_is_allowed(void) +{ + bool allowed_adv = true; + if (!app_is_stack_ready()) + { + LOG_I("reason: stack not ready"); + allowed_adv = false; + } + + if (app_is_power_off_in_progress()) + { + LOG_I("reason: in power off mode"); + allowed_adv = false; + } + + if (bleModeEnv.advSwitch) + { + LOG_I("adv switched off:%d", bleModeEnv.advSwitch); + allowed_adv = false; + } + + if (btapp_hfp_is_sco_active()) + { + LOG_I("SCO ongoing"); + allowed_adv = false; + } + + if (false == allowed_adv) + { + app_ble_stop_activities(); + } + + return allowed_adv; +} + +static void ble_start_adv(void *param) +{ + switch (bleModeEnv.state) + { + case ADVERTISING: + SET_BLE_STATE(STOPPING_ADV); + SET_BLE_OP(START_ADV); + appm_stop_advertising(); + break; + + case SCANNING: + SET_BLE_STATE(STOPPING_SCAN); + SET_BLE_OP(START_ADV); + appm_stop_scanning(); + break; + + case CONNECTING: + SET_BLE_STATE(STOPPING_CONNECT); + SET_BLE_OP(START_ADV); + appm_stop_connecting(); + break; + + case STARTING_ADV: + case STARTING_SCAN: + case STARTING_CONNECT: + case STOPPING_ADV: + case STOPPING_SCAN: + case STOPPING_CONNECT: + SET_BLE_OP(START_ADV); + break; + + case STATE_IDLE: + if (!ble_adv_is_allowed()) + { + LOG_I("[ADV] not allowed."); + if (START_ADV == bleModeEnv.op) + { + SET_BLE_OP(OP_IDLE); + } + break; + } + + memcpy(&bleModeEnv.advInfo, param, sizeof(bleModeEnv.advInfo)); + appm_start_advertising(&bleModeEnv.advInfo); + + SET_BLE_STATE(STARTING_ADV); + break; + + default: + break; + } +} + +static void ble_start_adv_failed_cb(void) +{ + if (STARTING_ADV == bleModeEnv.state) + { + SET_BLE_STATE(STATE_IDLE); + } + + // start pending op(start adv again) +} + +static void ble_start_scan(void *param) +{ + switch (bleModeEnv.state) + { + case ADVERTISING: + SET_BLE_STATE(STOPPING_ADV); + SET_BLE_OP(START_SCAN); + appm_stop_advertising(); + break; + + case SCANNING: + SET_BLE_STATE(STOPPING_SCAN); + SET_BLE_OP(START_SCAN); + appm_stop_scanning(); + break; + + case CONNECTING: + SET_BLE_STATE(STOPPING_CONNECT); + SET_BLE_OP(START_SCAN); + appm_stop_connecting(); + break; + + case STARTING_ADV: + case STARTING_SCAN: + case STARTING_CONNECT: + case STOPPING_ADV: + case STOPPING_SCAN: + case STOPPING_CONNECT: + SET_BLE_OP(START_SCAN); + break; + + case STATE_IDLE: + + SET_BLE_STATE(STARTING_SCAN); + memcpy(&bleModeEnv.scanInfo, param, sizeof(BLE_SCAN_PARAM_T)); + appm_start_scanning(bleModeEnv.scanInfo.scanInterval, + bleModeEnv.scanInfo.scanWindow, + bleModeEnv.scanInfo.scanType); + break; + + default: + break; + } +} + +static void ble_start_connect(uint8_t *bleBdAddr) +{ + SET_BLE_OP(START_CONNECT); + + if ((CONNECTING != bleModeEnv.state) && + (STARTING_CONNECT != bleModeEnv.state)) + { + switch (bleModeEnv.state) + { + case ADVERTISING: + SET_BLE_STATE(STOPPING_ADV); + appm_stop_advertising(); + break; + + case SCANNING: + SET_BLE_STATE(STOPPING_SCAN); + appm_stop_scanning(); + break; + + case STATE_IDLE: + SET_BLE_STATE(STARTING_CONNECT); + struct gap_bdaddr bdAddr; + memcpy(bdAddr.addr.addr, bleBdAddr, BTIF_BD_ADDR_SIZE); + bdAddr.addr_type = 0; + LOG_I("Master paired with mobile dev is scanned, connect it via BLE."); + appm_start_connecting(&bdAddr); + break; + + default: + break; + } + } +} + +static void ble_stop_all_activities(void) +{ + switch (bleModeEnv.state) + { + case ADVERTISING: + SET_BLE_OP(OP_IDLE); + SET_BLE_STATE(STOPPING_ADV); + appm_stop_advertising(); + break; + + case SCANNING: + SET_BLE_OP(OP_IDLE); + SET_BLE_STATE(STOPPING_SCAN); + appm_stop_scanning(); + break; + + case CONNECTING: + SET_BLE_OP(OP_IDLE); + SET_BLE_STATE(STOPPING_CONNECT); + appm_stop_connecting(); + break; + + case STARTING_ADV: + SET_BLE_OP(STOP_ADV); + break; + + case STARTING_SCAN: + SET_BLE_OP(STOP_SCAN); + break; + + case STARTING_CONNECT: + SET_BLE_OP(STOP_CONNECT); + break; + + case STOPPING_ADV: + case STOPPING_SCAN: + case STOPPING_CONNECT: + SET_BLE_OP(OP_IDLE); + break; + + default: + break; + } +} + +static void ble_execute_pending_op(void) +{ + LOG_I("%s", __func__); + uint8_t op = bleModeEnv.op; + SET_BLE_OP(OP_IDLE); + + switch (op) + { + case START_ADV: + ble_start_adv(&advParam); + break; + + case START_SCAN: + ble_start_scan(&scanParam); + break; + + case START_CONNECT: + ble_start_connect(bleModeEnv.bleAddrToConnect); + break; + + case STOP_ADV: + case STOP_SCAN: + case STOP_CONNECT: + ble_stop_all_activities(); + break; + + default: + break; + } +} + +static void ble_switch_activities(void) +{ + switch (bleModeEnv.state) + { + case STARTING_ADV: + SET_BLE_STATE(ADVERTISING); + break; + + case STARTING_SCAN: + SET_BLE_STATE(SCANNING); + break; + + case STARTING_CONNECT: + SET_BLE_STATE(CONNECTING); + break; + + case STOPPING_ADV: + SET_BLE_STATE(STATE_IDLE); + break; + + case STOPPING_SCAN: + SET_BLE_STATE(STATE_IDLE); + break; + + case STOPPING_CONNECT: + SET_BLE_STATE(STATE_IDLE); + break; + + default: + break; + } + + ble_execute_pending_op(); +} + +// BLE advertisement event callbacks +void app_advertising_started(void) +{ + app_bt_start_custom_function_in_bt_thread(0, + 0, + (uint32_t)ble_switch_activities); +} + +void app_advertising_starting_failed(void) +{ + memset(&bleModeEnv.advInfo, 0, sizeof(bleModeEnv.advInfo)); + app_bt_start_custom_function_in_bt_thread(0, + 0, + (uint32_t)ble_start_adv_failed_cb); +} + +void app_advertising_stopped(void) +{ + memset(&bleModeEnv.advInfo, 0, sizeof(bleModeEnv.advInfo)); + app_bt_start_custom_function_in_bt_thread(0, + 0, + ( uint32_t )ble_switch_activities); +} + +// BLE adv data updated event callback +void app_adv_data_updated(void) +{ + app_bt_start_custom_function_in_bt_thread(0, + 0, + (uint32_t)ble_switch_activities); +} + +// BLE scan event callbacks +void app_scanning_started(void) +{ + app_bt_start_custom_function_in_bt_thread(0, + 0, + (uint32_t)ble_switch_activities); +} + +void app_scanning_stopped(void) +{ + app_bt_start_custom_function_in_bt_thread(0, + 0, + (uint32_t)ble_switch_activities); +} + +// BLE connect event callbacks +void app_connecting_started(void) +{ + app_bt_start_custom_function_in_bt_thread(0, + 0, + (uint32_t)ble_switch_activities); +} + +void app_connecting_stopped(void) +{ + app_bt_start_custom_function_in_bt_thread(0, + 0, + (uint32_t)ble_switch_activities); +} + +/** + * @brief : callback function of BLE connect failed + * + */ +static void app_ble_connecting_failed_handler(void) +{ + if ((CONNECTING == bleModeEnv.state) || + (STOPPING_CONNECT == bleModeEnv.state) || + (STARTING_CONNECT == bleModeEnv.state) ) + { + SET_BLE_STATE(STATE_IDLE); + } +} + +void app_connecting_failed(void) +{ + app_bt_start_custom_function_in_bt_thread(0, + 0, + (uint32_t)app_ble_connecting_failed_handler); +} +void app_ble_connected_evt_handler(uint8_t conidx, const uint8_t *pPeerBdAddress) +{ + ble_evnet_t event; + + if ((ADVERTISING == bleModeEnv.state) || + (STARTING_ADV == bleModeEnv.state) || + (CONNECTING == bleModeEnv.state)) + { + SET_BLE_STATE(STATE_IDLE); + } + + if (START_CONNECT == bleModeEnv.op) + { + SET_BLE_OP(OP_IDLE); + } + + event.evt_type = BLE_CONNECT_EVENT; + event.p.connect_handled.conidx = conidx; + event.p.connect_handled.peer_bdaddr = pPeerBdAddress; + app_ble_core_global_handle(&event, NULL); + + + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); + app_stop_fast_connectable_ble_adv_timer(); +} + +void app_ble_disconnected_evt_handler(uint8_t conidx) +{ + ble_evnet_t event; + + event.evt_type = BLE_DISCONNECT_EVENT; + event.p.disconnect_handled.conidx = conidx; + app_ble_core_global_handle(&event, NULL); + + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); +} + +// BLE APIs for external use +void app_ble_data_fill_enable(enum BLE_ADV_USER_E user, bool enable) +{ + LOG_I("%s user %d%s enable %d", __func__, user, ble_adv_user2str(user), enable); + + ASSERT(user < BLE_ADV_USER_NUM, "%s user %d", __func__, user); + if (enable) + { + bleModeEnv.adv_user_enable |= (1 << user); + } + else + { + bleModeEnv.adv_user_enable &= ~(1 << user); + } +} + +bool app_ble_get_data_fill_enable(enum BLE_ADV_USER_E user) +{ + bool enable = bleModeEnv.adv_user_enable & (1 << user); + LOG_I("%s user %d enable %d", __func__, user, enable); + return enable; +} + + +/** + * @brief : callback function of BLE scan starting failed + * + */ +static void app_ble_scanning_starting_failed_handler(void) +{ + if (STARTING_SCAN == bleModeEnv.state) + { + SET_BLE_STATE(STATE_IDLE); + } +} + +void app_scanning_starting_failed(void) +{ + app_bt_start_custom_function_in_bt_thread(0, + 0, + (uint32_t)app_ble_scanning_starting_failed_handler); +} + +// BLE APIs for external use +void app_ble_register_data_fill_handle(enum BLE_ADV_USER_E user, BLE_DATA_FILL_FUNC_T func, bool enable) +{ + bool needUpdateAdv = false; + + if (BLE_ADV_USER_NUM <= user) + { + LOG_W("invalid user"); + } + else + { + if (func != bleModeEnv.bleDataFillFunc[user] && + NULL != func) + { + needUpdateAdv = true; + bleModeEnv.bleDataFillFunc[user] = func; + } + } + + bleModeEnv.adv_user_register |= (1 << user); + if (needUpdateAdv) + { + app_ble_data_fill_enable(user, enable); + } +} + +void app_ble_system_ready(void) +{ + uint32_t generatedSeed = hal_sys_timer_get(); + + for (uint8_t index = 0; index < sizeof(bt_addr); index++) + { + generatedSeed ^= (((uint32_t)(bt_addr[index])) << (hal_sys_timer_get() & 0xF)); + } + + bt_drv_reg_op_set_rand_seed(generatedSeed); + +#if defined(ENHANCED_STACK) + app_notify_stack_ready(STACK_READY_BLE); +#else + app_notify_stack_ready(STACK_READY_BLE | STACK_READY_BT); +#endif +} + +static void ble_adv_refreshing(void *param) +{ + BLE_ADV_PARAM_T *pAdvParam = (BLE_ADV_PARAM_T *)param; + // four conditions that we just need to update the ble adv data instead of restarting ble adv + // 1. BLE advertising is on + // 2. No on-going BLE operation + // 3. BLE adv type is the same + // 4. BLE adv interval is the same + if ((ADVERTISING == bleModeEnv.state) && \ + (OP_IDLE == bleModeEnv.op) && \ + bleModeEnv.advInfo.advType == pAdvParam->advType && \ + bleModeEnv.advInfo.advInterval == pAdvParam->advInterval) + { + memcpy(&bleModeEnv.advInfo, param, sizeof(bleModeEnv.advInfo)); + SET_BLE_STATE(STARTING_ADV); + appm_update_adv_data(pAdvParam->advData, + pAdvParam->advDataLen, + pAdvParam->scanRspData, + pAdvParam->scanRspDataLen); + } + else + { + // otherwise, restart ble adv + ble_start_adv(param); + } +} + +static bool app_ble_start_adv(uint8_t advType, uint16_t advInterval) +{ + uint32_t adv_user_enable = bleModeEnv.adv_user_enable; + LOG_I("[ADV]type:%d, interval:%d ca:%p", advType, advInterval, __builtin_return_address(0)); + + if (!ble_adv_is_allowed()) + { + LOG_I("[ADV] not allowed."); + return false; + } + + ble_adv_config_param(advType, advInterval); + + LOG_I("%s old_user_enable 0x%x new 0x%x", __func__, adv_user_enable, bleModeEnv.adv_user_enable); + if (!bleModeEnv.adv_user_enable) + { + LOG_I("no adv user enable"); + LOG_I("[ADV] not allowed."); + app_ble_stop_activities(); + return false; + } + + // param of adv request is exactly same as current adv + if (ADVERTISING == bleModeEnv.state && + !memcmp(&bleModeEnv.advInfo, &advParam, sizeof(advParam))) + { + LOG_I("reason: adv param not changed"); + LOG_I("[ADV] not allowed."); + return false; + } + + LOG_I("[ADV_LEN] %d [DATA]:", advParam.advDataLen); + DUMP8("%02x ", advParam.advData, advParam.advDataLen); + LOG_I("[SCAN_RSP_LEN] %d [DATA]:", advParam.scanRspDataLen); + DUMP8("%02x ", advParam.scanRspData, advParam.scanRspDataLen); + + ble_adv_refreshing(&advParam); + + return true; +} + +void app_ble_start_connectable_adv(uint16_t advInterval) +{ + LOG_D("%s", __func__); + app_bt_start_custom_function_in_bt_thread( + (uint32_t)GAPM_ADV_UNDIRECT, (uint32_t)advInterval, + (uint32_t)app_ble_start_adv); +} + +void app_ble_refresh_adv_state(uint16_t advInterval) +{ + LOG_D("%s", __func__); + app_bt_start_custom_function_in_bt_thread( + (uint32_t)GAPM_ADV_UNDIRECT, (uint32_t)advInterval, + (uint32_t)app_ble_start_adv); +} + +void app_ble_start_scan(enum BLE_SCAN_FILTER_POLICY scanFilterPolicy, uint16_t scanWindow, uint16_t scanInterval) +{ + scanParam.scanWindow = scanWindow; + scanParam.scanInterval = scanInterval; + scanParam.scanType = scanFilterPolicy; //BLE_SCAN_ALLOW_ADV_WLST + + app_bt_start_custom_function_in_bt_thread((uint32_t)(&scanParam), + 0, + (uint32_t)ble_start_scan); +} + +void app_ble_start_connect(uint8_t *bdAddrToConnect) +{ + memcpy(bleModeEnv.bleAddrToConnect, bdAddrToConnect, BTIF_BD_ADDR_SIZE); + app_bt_start_custom_function_in_bt_thread((uint32_t)bleModeEnv.bleAddrToConnect, + 0, + (uint32_t)ble_start_connect); +} + +bool app_ble_is_connection_on(uint8_t index) +{ + return (BLE_CONNECTED == + bleModeEnv.bleEnv->context[index].connectStatus); +} + +bool app_ble_is_any_connection_exist(void) +{ + bool ret = false; + for (uint8_t i = 0; i < BLE_CONNECTION_MAX; i++) + { + if (app_ble_is_connection_on(i)) + { + ret = true; + } + } + + return ret; +} + +void app_ble_start_disconnect(uint8_t conIdx) +{ + if (BLE_CONNECTED == bleModeEnv.bleEnv->context[conIdx].connectStatus) + { + LOG_I("will disconnect connection:%d", conIdx); + bleModeEnv.bleEnv->context[conIdx].connectStatus = BLE_DISCONNECTING; + app_bt_start_custom_function_in_bt_thread((uint32_t)conIdx, + 0, + (uint32_t)appm_disconnect); + } + else + { + LOG_I("will not execute disconnect since state is:%d", + bleModeEnv.bleEnv->context[conIdx].connectStatus); + } +} + +void app_ble_disconnect_all(void) +{ + for (uint8_t i = 0; i < BLE_CONNECTION_MAX; i++) + { + app_ble_start_disconnect(i); + } +} + +void app_ble_stop_activities(void) +{ + LOG_I("%s %p", __func__, __builtin_return_address(0)); + + app_stop_fast_connectable_ble_adv_timer(); + if (bleModeEnv.state != OP_IDLE) + { + app_bt_start_custom_function_in_bt_thread(0, + 0, + (uint32_t)ble_stop_all_activities); + } +} + +void app_ble_force_switch_adv(uint8_t user, bool onOff) +{ + ASSERT(user < BLE_SWITCH_USER_NUM, "ble switch user exceed"); + + if (onOff) + { + bleModeEnv.advSwitch &= ~(1 << user); + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); + } + else if ((bleModeEnv.advSwitch & (1 << user)) == 0) + { + bleModeEnv.advSwitch |= (1 << user); + app_ble_stop_activities(); + + // disconnect all of the BLE connections if box is closed + if (BLE_SWITCH_USER_BOX == user) + { + app_ble_disconnect_all(); + } + } + + LOG_I("%s user %d onoff %d switch 0x%x", __func__, user, onOff, bleModeEnv.advSwitch); +} + +bool app_ble_is_in_advertising_state(void) +{ + return (ADVERTISING == bleModeEnv.state) || + (STARTING_ADV == bleModeEnv.state) || + (STOPPING_ADV == bleModeEnv.state); +} + +static uint32_t POSSIBLY_UNUSED ble_get_manufacture_data_ptr(uint8_t *advData, + uint32_t dataLength, + uint8_t *manufactureData) +{ + uint8_t followingDataLengthOfSection; + uint8_t rawContentDataLengthOfSection; + uint8_t flag; + while (dataLength > 0) + { + followingDataLengthOfSection = *advData++; + dataLength--; + if (dataLength < followingDataLengthOfSection) + { + return 0; // wrong adv data format + } + + if (followingDataLengthOfSection > 0) + { + flag = *advData++; + dataLength--; + + rawContentDataLengthOfSection = followingDataLengthOfSection - 1; + if (BLE_ADV_MANU_FLAG == flag) + { + uint32_t lengthToCopy; + if (dataLength < rawContentDataLengthOfSection) + { + lengthToCopy = dataLength; + } + else + { + lengthToCopy = rawContentDataLengthOfSection; + } + + memcpy(manufactureData, advData - 2, lengthToCopy + 2); + return lengthToCopy + 2; + } + else + { + advData += rawContentDataLengthOfSection; + dataLength -= rawContentDataLengthOfSection; + } + } + } + + return 0; +} + +//received adv data +void app_adv_reported_scanned(struct gapm_adv_report_ind *ptInd) +{ + /* + LOG_I("Scanned RSSI %d BD addr:", (int8_t)ptInd->report.rssi); + DUMP8("0x%02x ", ptInd->report.adv_addr.addr, BTIF_BD_ADDR_SIZE); + LOG_I("Scanned adv data:"); + DUMP8("0x%02x ", ptInd->report.data, ptInd->report.data_len); + */ + + ble_adv_data_parse(ptInd->report.adv_addr.addr, + (int8_t)ptInd->report.rssi, + ptInd->report.data, + (unsigned char)ptInd->report.data_len); +} + +void app_ibrt_ui_disconnect_ble(void) +{ + app_ble_disconnect_all(); +} + +uint32_t app_ble_get_user_register(void) +{ + return bleModeEnv.adv_user_register; +} + +enum BLE_STATE_E app_ble_get_current_state(void) +{ + return bleModeEnv.state; +} + +enum BLE_OP_E app_ble_get_current_operation(void) +{ + return bleModeEnv.op; +} + +void app_ble_get_runtime_adv_param(uint8_t* pAdvType, uint16_t* pAdvIntervalMs) +{ + *pAdvType = advParam.advType; + *pAdvIntervalMs = advParam.advInterval; +} + diff --git a/services/ble_app/app_main/app_ble_mode_switch.h b/services/ble_app/app_main/app_ble_mode_switch.h new file mode 100644 index 0000000..2ee9ea0 --- /dev/null +++ b/services/ble_app/app_main/app_ble_mode_switch.h @@ -0,0 +1,456 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +#ifndef __APP_BLE_MODE_SWITCH_H__ +#define __APP_BLE_MODE_SWITCH_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************header include********************************/ +#include "bluetooth.h" +#include "co_bt_defines.h" + +/******************************macro defination*****************************/ +#define BLE_ADV_DATA_STRUCT_HEADER_LEN (2) + +#ifndef BLE_CONNECTION_MAX +#define BLE_CONNECTION_MAX (1) +#endif + +// the default interval is 160ms, note that for Bisto user case, to +// let GVA iOS version pop-out notification smoothly, the maximum interval should be this value +#define BLE_ADVERTISING_INTERVAL (160) +#define BLE_FAST_ADVERTISING_INTERVAL (48) + +#define BLE_ADV_SVC_FLAG 0x16 +#define BLE_ADV_MANU_FLAG 0xFF + +// Maximal length of the Device Name value +#define APP_DEVICE_NAME_MAX_LEN (24) + +/******************************type defination******************************/ +/** + * @brief The state type of the ble + * + */ +enum BLE_STATE_E { + STATE_IDLE = 0, + ADVERTISING = 1, + STARTING_ADV = 2, + STOPPING_ADV = 3, + SCANNING = 4, + STARTING_SCAN = 5, + STOPPING_SCAN = 6, + CONNECTING = 7, + STARTING_CONNECT = 8, + STOPPING_CONNECT = 9, +}; + +/** + * @brief The operation type of the ble + * + */ +enum BLE_OP_E { + OP_IDLE = 0, + START_ADV = 1, + START_SCAN = 2, + START_CONNECT = 3, + STOP_ADV = 4, + STOP_SCAN = 5, + STOP_CONNECT = 6, +}; + +enum BLE_ADV_USER_E { + USER_STUB = 0, + USER_GFPS = 1, + USER_GSOUND = 2, + USER_AI = 3, + USER_INTERCONNECTION = 4, + USER_TILE = 5, + USER_OTA = 6, + BLE_ADV_USER_NUM, +}; + +enum BLE_ADV_SWITCH_USER_E { + BLE_SWITCH_USER_RS = 0, // used for role switch + BLE_SWITCH_USER_BOX = 1, // used for box open/close + BLE_SWITCH_USER_AI = 2, // used for ai + BLE_SWITCH_USER_BT_CONNECT = 3, // used for bt connect + BLE_SWITCH_USER_SCO = 4, // used for sco + BLE_SWITCH_USER_IBRT = 5, // used for ibrt + + BLE_SWITCH_USER_NUM, +}; + +//Scan filter policy +enum BLE_SCAN_FILTER_POLICY { + ///Allow advertising packets from anyone + BLE_SCAN_ALLOW_ADV_ALL = 0x00, + ///Allow advertising packets from White List devices only + BLE_SCAN_ALLOW_ADV_WLST, + ///Allow advertising packets from anyone and Direct adv using RPA in InitA + BLE_SCAN_ALLOW_ADV_ALL_AND_INIT_RPA, + ///Allow advertising packets from White List devices only and Direct adv using RPA in InitA + BLE_SCAN_ALLOW_ADV_WLST_AND_INIT_RPA, +}; + +typedef struct { + bool withFlag; + uint8_t advType; + uint16_t advInterval; + uint8_t advDataLen; + uint8_t advData[BLE_DATA_LEN]; + uint8_t scanRspDataLen; + uint8_t scanRspData[BLE_DATA_LEN]; +} BLE_ADV_PARAM_T; + +typedef void (*BLE_DATA_FILL_FUNC_T)(void *advParam); + +typedef struct { + uint8_t scanType; + uint16_t scanWindow; + uint16_t scanInterval; +} BLE_SCAN_PARAM_T; + +typedef struct { + uint32_t advSwitch; + uint8_t state; + uint8_t op; + uint8_t bleAddrToConnect[BTIF_BD_ADDR_SIZE]; + uint32_t adv_user_register; //one bit represent one user + uint32_t adv_user_enable; //one bit represent one user + + BLE_DATA_FILL_FUNC_T bleDataFillFunc[BLE_ADV_USER_NUM]; + + // param used for BLE adv + BLE_ADV_PARAM_T advInfo; + + // prarm used for BLE scan + BLE_SCAN_PARAM_T scanInfo; + + // pointer of @see app_env + struct app_env_tag *bleEnv; +} __attribute__((__packed__)) BLE_MODE_ENV_T; + + +/*--------------------------------------------------------------------------- + * app_ble_mode_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * init the bleModeEnv + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ble_mode_init(void); + +/*--------------------------------------------------------------------------- + * app_ble_register_data_fill_handler + *--------------------------------------------------------------------------- + * + *Synopsis: + * register a BLE advertisement and scan response data fill handler for a + * specific user(see @BLE_ADV_USER_E), so that the adv/scan response data + * could present in BLE adv/scan response data + * + * Parameters: + * user - see the defination in BLE_ADV_USER_E + * func - adv/scan response data fill handler for specific user + * + * Return: + * void + */ +void app_ble_register_data_fill_handle(enum BLE_ADV_USER_E user, BLE_DATA_FILL_FUNC_T func, bool enable); + +/*--------------------------------------------------------------------------- + * app_ble_data_fill_enable + *--------------------------------------------------------------------------- + * + *Synopsis: + * enable/disable specific user to fill the adv/scan response data + * + * Parameters: + * user : user to enable/disable fill data + * enable : true - enable user + * false - disable user + * + * Return: + * void + */ +void app_ble_data_fill_enable(enum BLE_ADV_USER_E user, bool enable); + +/*--------------------------------------------------------------------------- + * app_ble_get_data_fill_enable + *--------------------------------------------------------------------------- + * + *Synopsis: + * get if specific user is enabled to fill adv/scan response data + * + * Parameters: + * user : user + * + * Return: + * true - user is enabled to fill data + * false - user is disabled to fill data + */ +bool app_ble_get_data_fill_enable(enum BLE_ADV_USER_E user); + +/*--------------------------------------------------------------------------- + * app_ble_start_connectable_adv + *--------------------------------------------------------------------------- + * + *Synopsis: + * start connetable BLE advertise + * + * Parameters: + * advertisement interval in ms + * + * Return: + * None + */ +void app_ble_start_connectable_adv(uint16_t advInterval); + +/*--------------------------------------------------------------------------- + * app_ble_refresh_adv_state + *--------------------------------------------------------------------------- + * + *Synopsis: + * refresh adv state + * + * Parameters: + * advertisement interval in ms + * + * Return: + * None + */ +void app_ble_refresh_adv_state(uint16_t advInterval); + +/*--------------------------------------------------------------------------- + * app_ble_force_switch_adv + *--------------------------------------------------------------------------- + * + *Synopsis: + * enable/disable all BLE adv request for specific UI user + * + * Parameters: + * user : UI user + * onOff : true - enable BLE adv for specific UI user + * false - disable BLE adv for specific UI user + * + * Return: + * void + */ +void app_ble_force_switch_adv(uint8_t user, bool onOff); + +/*--------------------------------------------------------------------------- + * app_ble_start_scan + *--------------------------------------------------------------------------- + * + *Synopsis: + * start BLE scan + * + * Parameters: + * scanFilterPolicy : Scan filter policy + * scanWindow : BLE scan window size(in ms) + * scanWnInterval : BLE scan window interval(in ms) + * + * Return: + * void + */ +void app_ble_start_scan(enum BLE_SCAN_FILTER_POLICY scanFilterPolicy, uint16_t scanWindow, uint16_t scanWnterval); + +/*--------------------------------------------------------------------------- + * app_ble_start_connect + *--------------------------------------------------------------------------- + * + *Synopsis: + * start connect BLE with the given address + * + * Parameters: + * bdAddrToConnect : BLE address to connnect + * + * Return: + * void + */ +void app_ble_start_connect(uint8_t *bdAddrToConnect); + +/*--------------------------------------------------------------------------- + * app_ble_is_connection_on + *--------------------------------------------------------------------------- + * + *Synopsis: + * is a specific BLE connection exist + * + * Parameters: + * index: Index of the BLE connection to check + * + * Return: + * true - BLE connection exists + * false - BLE connection doesn't exist + */ +bool app_ble_is_connection_on(uint8_t index); + +/*--------------------------------------------------------------------------- + * app_ble_is_any_connection_exist + *--------------------------------------------------------------------------- + * + *Synopsis: + * is there any BLE connection exist + * + * Parameters: + * void + * + * Return: + * true - at least one BLE connection exist + * false - no BLE connection exists + */ +bool app_ble_is_any_connection_exist(); + +/*--------------------------------------------------------------------------- + * app_ble_start_disconnect + *--------------------------------------------------------------------------- + * + *Synopsis: + * disconnect the BLE connection with given connection index + * + * Parameters: + * conIdx: connection index to disconnect + * + * Return: + * void + */ +void app_ble_start_disconnect(uint8_t conIdx); + +/*--------------------------------------------------------------------------- + * app_ble_disconnect_all + *--------------------------------------------------------------------------- + * + *Synopsis: + * disconnect all BLE connections + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ble_disconnect_all(void); + +/*--------------------------------------------------------------------------- + * app_ble_stop_activities + *--------------------------------------------------------------------------- + * + *Synopsis: + * stop all BLE activities + * NOTE: will not disconnect the existed connections + * + * Parameters: + * void + * + * Return: + * void + */ +void app_ble_stop_activities(void); + +/*--------------------------------------------------------------------------- + * app_ble_is_in_advertising_state + *--------------------------------------------------------------------------- + * + *Synopsis: + * is BLE in advertising progress + * + * Parameters: + * void + * + * Return: + * true - BLE adv is in progress + * false - BLE adv is not in progress + */ +bool app_ble_is_in_advertising_state(void); + +/*--------------------------------------------------------------------------- + * app_ble_get_user_register + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get adv user register + * + * Parameters: + * void + * + * Return: + * uint32_t -- adv user register + */ +uint32_t app_ble_get_user_register(void); + +/*--------------------------------------------------------------------------- + * app_ble_get_current_state + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get current ble state + * + * Parameters: + * void + * + * Return: + * enum BLE_STATE_E -- ble state + */ +enum BLE_STATE_E app_ble_get_current_state(void); + +/*--------------------------------------------------------------------------- + * app_ble_get_current_operation + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get current ble operation + * + * Parameters: + * void + * + * Return: + * enum BLE_OP_E -- ble operation + */ +enum BLE_OP_E app_ble_get_current_operation(void); + +/*--------------------------------------------------------------------------- + * app_ble_get_runtime_adv_param + *--------------------------------------------------------------------------- + * + *Synopsis: + * to get current ble advertising parameters + * + * Parameters: + * pAdvType: Output pointer of adv type + * pAdvIntervalMs: Output pointer of adv internal in ms + * + * Return: + * void + */ +void app_ble_get_runtime_adv_param(uint8_t* pAdvType, uint16_t* pAdvIntervalMs); + + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __APP_BLE_MODE_SWITCH_H__ */ diff --git a/services/ble_app/app_main/app_ble_rx_handler.c b/services/ble_app/app_main/app_ble_rx_handler.c new file mode 100644 index 0000000..4513e8d --- /dev/null +++ b/services/ble_app/app_main/app_ble_rx_handler.c @@ -0,0 +1,174 @@ +#include "cmsis_os.h" +#include "cmsis.h" +#include "ble_app_dbg.h" +#include "app_ble_rx_handler.h" +#include "cqueue.h" +#include "app_bt_func.h" + +#ifdef BISTO_ENABLED +#include "gsound_service.h" +#include "gsound_custom_ble.h" +#endif + +#define BLE_RX_EVENT_MAX_MAILBOX 16 +#define BLE_RX_BUF_SIZE (2048) + +static uint8_t app_ble_rx_buf[BLE_RX_BUF_SIZE]; +static CQueue app_ble_rx_cqueue; + +#define VOICEPATH_COMMON_OTA_BUFF_SIZE 4096 + +uint8_t* app_voicepath_get_common_ota_databuf(void) +{ + static uint8_t voicepath_common_ota_buf[VOICEPATH_COMMON_OTA_BUFF_SIZE]; + return voicepath_common_ota_buf; +} + +#ifdef BES_OTA_BASIC +extern void ota_bes_handle_received_data(uint8_t *otaBuf, bool isViaBle,uint16_t dataLenth); + +#if defined(IBRT) +#ifdef IBRT_OTA +extern void ota_ibrt_handle_received_data(uint8_t *otaBuf, bool isViaBle, uint16_t len); +#endif +#endif + +#endif + +#if (BLE_APP_TOTA) +extern void app_tota_handle_received_data(uint8_t* buffer, uint16_t maxBytes); +#endif + +static osThreadId app_ble_rx_thread = NULL; +static bool ble_rx_thread_init_done = false; + +extern void gsound_send_control_rx_cfm(uint8_t conidx); +extern uint8_t app_ota_get_conidx(void); +extern void app_ota_send_rx_cfm(uint8_t conidx); + +static void app_ble_rx_handler_thread(const void *arg); +osThreadDef(app_ble_rx_handler_thread, osPriorityNormal, 1, 2048, "ble_rx"); + +osMailQDef (ble_rx_event_mailbox, BLE_RX_EVENT_MAX_MAILBOX, BLE_RX_EVENT_T); +static osMailQId app_ble_rx_event_mailbox = NULL; +static int32_t app_ble_rx_event_mailbox_init(void) +{ + app_ble_rx_event_mailbox = osMailCreate(osMailQ(ble_rx_event_mailbox), NULL); + if (app_ble_rx_event_mailbox == NULL) { + LOG_I("Failed to Create app_ble_rx_event_mailbox"); + return -1; + } + return 0; +} + +static void update_init_state(bool state) +{ + ble_rx_thread_init_done = state; +} + +static bool get_init_state(void) +{ + return ble_rx_thread_init_done; +} + +static void app_ble_rx_mailbox_free(BLE_RX_EVENT_T* rx_event) +{ + osStatus status; + + status = osMailFree(app_ble_rx_event_mailbox, rx_event); + ASSERT(osOK == status, "Free ble rx event mailbox failed!"); +} + +void app_ble_rx_handler_init(void) +{ + if (!get_init_state()) + { + InitCQueue(&app_ble_rx_cqueue, BLE_RX_BUF_SIZE, ( CQItemType * )app_ble_rx_buf); + app_ble_rx_event_mailbox_init(); + + app_ble_rx_thread = osThreadCreate(osThread(app_ble_rx_handler_thread), NULL); + update_init_state(true); + } + else + { + LOG_I("rx already initialized"); + } +} + +void app_ble_push_rx_data(uint8_t flag, uint8_t conidx, uint8_t* ptr, uint16_t len) +{ + uint32_t lock = int_lock(); + int32_t ret = EnCQueue(&app_ble_rx_cqueue, ptr, len); + int_unlock(lock); + ASSERT(CQ_OK == ret, "BLE rx buffer overflow! %d,%d",AvailableOfCQueue(&app_ble_rx_cqueue),len); + + BLE_RX_EVENT_T* event = (BLE_RX_EVENT_T*)osMailAlloc(app_ble_rx_event_mailbox, 0); + event->flag = flag; + event->conidx = conidx; + event->ptr = ptr; + event->len = len; + + osMailPut(app_ble_rx_event_mailbox, event); +} + +static int32_t app_ble_rx_mailbox_get(BLE_RX_EVENT_T** rx_event) +{ + osEvent evt; + evt = osMailGet(app_ble_rx_event_mailbox, osWaitForever); + if (evt.status == osEventMail) { + *rx_event = (BLE_RX_EVENT_T *)evt.value.p; + LOG_I("flag %d ptr %p len %d", (*rx_event)->flag, + (*rx_event)->ptr, (*rx_event)->len); + return 0; + } + return -1; +} + +extern int app_ibrt_if_tws_sniff_block(uint32_t block_next_sec); +static void app_ble_rx_handler_thread(void const *argument) +{ + while (true) + { + BLE_RX_EVENT_T* rx_event = NULL; + if (!app_ble_rx_mailbox_get(&rx_event)) + { + uint8_t tmpData[512]; + uint32_t lock = int_lock(); + DeCQueue(&app_ble_rx_cqueue, tmpData, rx_event->len); + int_unlock(lock); + switch (rx_event->flag) + { + #ifdef BISTO_ENABLED + case BLE_RX_DATA_GSOUND_CONTROL: + #ifdef IBRT + app_ibrt_if_tws_sniff_block(5); + #endif + LOG_I("gsound processes %d control data.", rx_event->len); + app_gsound_rx_control_data_handler(rx_event->ptr, rx_event->len); + break; + #endif + #if (BLE_APP_OTA) + case BLE_RX_DATA_SELF_OTA: + #if defined(IBRT) + #ifdef IBRT_OTA + ota_ibrt_handle_received_data(tmpData, true, rx_event->len); + app_ota_send_rx_cfm(app_ota_get_conidx()); + #endif + #else + ota_bes_handle_received_data(tmpData, true,rx_event->len); + #endif + break; + #endif + #if (BLE_APP_TOTA) + case BLE_RX_DATA_SELF_TOTA: + app_tota_handle_received_data(tmpData, rx_event->len); + break; + #endif + default: + break; + } + app_ble_rx_mailbox_free(rx_event); + } + } +} + diff --git a/services/ble_app/app_main/app_ble_rx_handler.h b/services/ble_app/app_main/app_ble_rx_handler.h new file mode 100644 index 0000000..7d38a9d --- /dev/null +++ b/services/ble_app/app_main/app_ble_rx_handler.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BLE_RX_HANDLER_H__ +#define __APP_BLE_RX_HANDLER_H__ + +#include "rwapp_config.h" + +#ifdef __cplusplus +extern "C" { +#endif // #ifdef __cplusplus + +enum ble_rx_data_handler_num { + BLE_RX_DATA_GSOUND_CONTROL = 0, +#if (BLE_APP_OTA) + BLE_RX_DATA_SELF_OTA, +#endif +#if (BLE_APP_TOTA) + BLE_RX_DATA_SELF_TOTA, +#endif +}; + +typedef struct { + uint8_t flag; + uint8_t conidx; + uint16_t len; + uint8_t *ptr; +} BLE_RX_EVENT_T; + +void app_ble_rx_handler_init(void); + +void app_ble_push_rx_data(uint8_t flag, uint8_t conidx, uint8_t *ptr, uint16_t len); + +uint8_t *app_voicepath_get_common_ota_databuf(void); + +#ifdef __cplusplus +} +#endif // #ifdef __cplusplus + +#endif // #ifndef __APP_BLE_RX_HANDLER_H__ diff --git a/services/ble_app/app_main/app_task.c b/services/ble_app/app_main/app_task.c new file mode 100644 index 0000000..9863ffb --- /dev/null +++ b/services/ble_app/app_main/app_task.c @@ -0,0 +1,1235 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + **************************************************************************************** + * @addtogroup APPTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_PRESENT) + +#include "app_task.h" // Application Manager Task API +#include "app.h" // Application Manager Definition +#include "gapc_task.h" // GAP Controller Task API +#include "gapm_task.h" // GAP Manager Task API +#include "arch.h" // Platform Definitions +#include +#include "ke_timer.h" // Kernel timer +#include "gattc_task.h" +#include "app_ble_include.h" +#include "../l2cm/l2cm_int.h" + +#include "co_utils.h" +#if (BLE_APP_SEC) +#include "app_sec.h" // Security Module Definition +#endif //(BLE_APP_SEC) + +#if (BLE_APP_HT) +#include "app_ht.h" // Health Thermometer Module Definition +#include "htpt_task.h" +#endif //(BLE_APP_HT) + +#if (BLE_APP_DIS) +#include "app_dis.h" // Device Information Module Definition +#include "diss_task.h" +#endif //(BLE_APP_DIS) + +#if (BLE_APP_BATT) +#include "app_batt.h" // Battery Module Definition +#include "bass_task.h" +#endif //(BLE_APP_BATT) + +#if (BLE_APP_HID) +#include "app_hid.h" // HID Module Definition +#include "hogpd_task.h" +#endif //(BLE_APP_HID) + +#if (BLE_APP_HR) +#include "app_hrps.h" +#endif + +#if (BLE_APP_VOICEPATH) +#include "app_voicepath_ble.h" // Voice Path Module Definition +#endif // (BLE_APP_VOICEPATH) + +#if (BLE_APP_DATAPATH_SERVER) +#include "app_datapath_server.h" // Data Path Server Module Definition +#include "datapathps_task.h" +#endif // (BLE_APP_DATAPATH_SERVER) + +#if (BLE_APP_AI_VOICE) +#include "app_ai_ble.h" // ama Voice Module Definition +#endif // (BLE_APP_AI_VOICE) + +#if (BLE_APP_OTA) +#include "app_ota.h" // OTA Module Definition +#include "ota_task.h" +#endif // (BLE_APP_OTA) + +#if (BLE_APP_TOTA) +#include "app_tota_ble.h" // TOTA Module Definition +#include "tota_task.h" +#endif // (BLE_APP_TOTA) + +#if (BLE_APP_ANCC) +#include "app_ancc.h" // ANC Module Definition +#include "app_ancc_task.h" +#include "ancc_task.h" +#endif // (BLE_APP_ANCC) + +#if (BLE_APP_AMS) +#include "app_amsc.h" // AMS Module Definition +#include "app_amsc_task.h" +#include "amsc_task.h" +#endif // (BLE_APP_AMS) +#if (BLE_APP_GFPS) +#include "app_gfps.h" // google fast pair service provider +#include "gfps_provider_task.h" +#endif // (BLE_APP_GFPS) +#ifdef BLE_APP_AM0 +#include "am0_app.h" // Audio Mode 0 Application +#endif //defined(BLE_APP_AM0) + +#if (DISPLAY_SUPPORT) +#include "app_display.h" // Application Display Definition +#endif //(DISPLAY_SUPPORT) + +#include "bt_drv_interface.h" +#include "ble_app_dbg.h" +#include "nvrecord_ble.h" +#include "app_fp_rfcomm.h" + +#if (BLE_APP_TILE) +#include "tile_target_ble.h" +#include "tile_gatt_server.h" +#endif + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +#define APP_CONN_PARAM_INTERVEL_MIN (20) + +uint8_t ble_stack_ready = 0; + +extern bool app_factorymode_get(void); + +static uint8_t appm_get_handler(const struct ke_state_handler *handler_list, + ke_msg_id_t msgid, + void *param, + ke_task_id_t src_id) +{ + // Counter + uint8_t counter; + + // Get the message handler function by parsing the message table + for (counter = handler_list->msg_cnt; 0 < counter; counter--) + { + struct ke_msg_handler handler = (struct ke_msg_handler)(*(handler_list->msg_table + counter - 1)); + + if ((handler.id == msgid) || + (handler.id == KE_MSG_DEFAULT_HANDLER)) + { + // If handler is NULL, message should not have been received in this state + ASSERT_ERR(handler.func); + + return (uint8_t)(handler.func(msgid, param, TASK_APP, src_id)); + } + } + + // If we are here no handler has been found, drop the message + return (KE_MSG_CONSUMED); +} + +/* + * MESSAGE HANDLERS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int app_adv_timeout_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + #if (BLE_APP_HID) + #else + // Stop advertising + appm_stop_advertising(); + #endif + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles ready indication from the GAP. - Reset the stack + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gapm_device_ready_ind_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if (ble_stack_ready) + { + return KE_MSG_CONSUMED; + } + +#ifdef __FACTORY_MODE_SUPPORT__ + if (app_factorymode_get()) + { + return (KE_MSG_CONSUMED); + } +#endif + + BLE_APP_FUNC_ENTER(); + + // Application has not been initialized + ASSERT_ERR(ke_state_get(dest_id) == APPM_INIT); + + ble_stack_ready = 1; + + // Reset the stack + struct gapm_reset_cmd* cmd = KE_MSG_ALLOC(GAPM_RESET_CMD, + TASK_GAPM, TASK_APP, + gapm_reset_cmd); + + cmd->operation = GAPM_RESET; + + ke_msg_send(cmd); + + BLE_APP_FUNC_LEAVE(); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles GAP manager command complete events. + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gapm_cmp_evt_handler(ke_msg_id_t const msgid, + struct gapm_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + BLE_APP_FUNC_ENTER(); + BLE_APP_DBG("param->operation: %d status is %d app_env.next_svc is %d", + param->operation, param->status, app_env.next_svc); + + switch(param->operation) + { + // Reset completed + case (GAPM_RESET): + { + if(param->status == GAP_ERR_NO_ERROR) + { + #if (BLE_APP_HID) + app_hid_start_mouse(); + #endif //(BLE_APP_HID) + + // Set Device configuration + struct gapm_set_dev_config_cmd* cmd = KE_MSG_ALLOC(GAPM_SET_DEV_CONFIG_CMD, + TASK_GAPM, TASK_APP, + gapm_set_dev_config_cmd); + // Set the operation + cmd->operation = GAPM_SET_DEV_CONFIG; + // Set the device role - Peripheral + cmd->role = GAP_ROLE_ALL; + // Set Data length parameters + cmd->sugg_max_tx_octets = APP_MAX_TX_OCTETS; + cmd->sugg_max_tx_time = APP_MAX_TX_TIME; + cmd->pairing_mode = GAPM_PAIRING_LEGACY; + #ifdef CFG_SEC_CON + cmd->pairing_mode |= GAPM_PAIRING_SEC_CON; + #endif + cmd->max_mtu = 512; + cmd->att_cfg = 0; + cmd->att_cfg |= GAPM_MASK_ATT_SVC_CHG_EN; + #if (BLE_APP_HID) + // Enable Slave Preferred Connection Parameters present + cmd->att_cfg |= GAPM_MASK_ATT_SLV_PREF_CON_PAR_EN; + #endif //(BLE_APP_HID) + + #ifdef BLE_APP_AM0 + cmd->addr_type = GAPM_CFG_ADDR_HOST_PRIVACY; + cmd->audio_cfg = GAPM_MASK_AUDIO_AM0_SUP; + #endif // BLE_APP_AM0 + + // load IRK + memcpy(cmd->irk.key, app_env.loc_irk, KEY_LEN); + + // Send message + ke_msg_send(cmd); + } + else + { + ASSERT_ERR(0); + } + } + break; + case (GAPM_PROFILE_TASK_ADD): + { + // ASSERT_INFO(param->status == GAP_ERR_NO_ERROR, param->operation, param->status); + // Add the next requested service + if (!appm_add_svc()) + { + // Go to the ready state + ke_state_set(TASK_APP, APPM_READY); + + // No more service to add + app_ble_system_ready(); + } + } + break; + // Device Configuration updated + case (GAPM_SET_DEV_CONFIG): + { + ASSERT_INFO(param->status == GAP_ERR_NO_ERROR, param->operation, param->status); + + // Go to the create db state + ke_state_set(TASK_APP, APPM_CREATE_DB); + + // Add the first required service in the database + // and wait for the PROFILE_ADDED_IND + appm_add_svc(); + } + break; + + case (GAPM_ADV_NON_CONN): + case (GAPM_ADV_UNDIRECT): + #if !(BLE_APP_HID) + case (GAPM_ADV_DIRECT): + #endif// !(BLE_APP_HID) + case (GAPM_ADV_DIRECT_LDC): + { + LOG_I("adv evt cmp status 0x%x", param->status); + ASSERT(GAP_ERR_ADV_DATA_INVALID != param->status, + "The BLE adv data or scan rsp data is invalid! Better check their length."); + + if (GAP_ERR_CANCELED == param->status) + { + app_advertising_stopped(); + } + else if (GAP_ERR_NO_ERROR == param->status) + { + if (ke_state_get(TASK_APP) == APPM_ADVERTISING) + { + app_advertising_started(); + } + else + { + app_advertising_stopped(); + } + } + else + { + app_advertising_starting_failed(); + } + + break; + } + case GAPM_UPDATE_ADVERTISE_DATA: + { + app_adv_data_updated(); + break; + } + case GAPM_SCAN_ACTIVE: + case GAPM_SCAN_PASSIVE: + { + LOG_I("scan evt cmp status %d", param->status); + if (GAP_ERR_CANCELED == param->status) + { + app_scanning_stopped(); + } + else if (GAP_ERR_NO_ERROR == param->status) + { + app_scanning_started(); + } + else + { + app_scanning_starting_failed(); + } + } + break; + case GAPM_CONNECTION_DIRECT: + case GAPM_CONNECTION_AUTO: + case GAPM_CONNECTION_SELECTIVE: + case GAPM_CONNECTION_NAME_REQUEST: + case GAPM_CONNECTION_GENERAL: + { + BLE_GAP_DBG("connecting cmp status %d", param->status); + if (GAP_ERR_CANCELED == param->status) + { + app_connecting_stopped(); + } + else if (GAP_ERR_NO_ERROR == param->status) + { + app_connecting_started(); + } + else + { + app_connecting_failed(); + } + } + break; + + #if (BLE_APP_HID) + case (GAPM_ADV_DIRECT): + { + if (param->status == GAP_ERR_TIMEOUT) + { + ke_state_set(TASK_APP, APPM_READY); + } + } break; + #endif //(BLE_APP_HID) + case GAPM_RESOLV_ADDR: + { + LOG_I("Resolve result %d", param->status); + if (GAP_ERR_NOT_FOUND == param->status) + { + appm_random_ble_addr_solved(false, NULL); + } + break; + } + default: + { + // Drop the message + } + break; + } + + BLE_APP_FUNC_LEAVE(); + + return (KE_MSG_CONSUMED); +} + +static int gapc_get_dev_info_req_ind_handler(ke_msg_id_t const msgid, + struct gapc_get_dev_info_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + switch(param->req) + { + case GAPC_DEV_NAME: + { + struct gapc_get_dev_info_cfm * cfm = KE_MSG_ALLOC_DYN(GAPC_GET_DEV_INFO_CFM, + src_id, dest_id, + gapc_get_dev_info_cfm, APP_DEVICE_NAME_MAX_LEN); + cfm->req = param->req; + cfm->info.name.length = appm_get_dev_name(cfm->info.name.value); + + // Send message + ke_msg_send(cfm); + } break; + + case GAPC_DEV_APPEARANCE: + { + // Allocate message + struct gapc_get_dev_info_cfm *cfm = KE_MSG_ALLOC(GAPC_GET_DEV_INFO_CFM, + src_id, dest_id, + gapc_get_dev_info_cfm); + cfm->req = param->req; + // Set the device appearance + #if (BLE_APP_HT) + // Generic Thermometer - TODO: Use a flag + cfm->info.appearance = 728; + #elif (BLE_APP_HID) + // HID Mouse + cfm->info.appearance = 962; + #else + // No appearance + cfm->info.appearance = 0; + #endif + + // Send message + ke_msg_send(cfm); + } break; + + case GAPC_DEV_SLV_PREF_PARAMS: + { + // Allocate message + struct gapc_get_dev_info_cfm *cfm = KE_MSG_ALLOC(GAPC_GET_DEV_INFO_CFM, + src_id, dest_id, + gapc_get_dev_info_cfm); + cfm->req = param->req; + // Slave preferred Connection interval Min + cfm->info.slv_params.con_intv_min = 8; + // Slave preferred Connection interval Max + cfm->info.slv_params.con_intv_max = 10; + // Slave preferred Connection latency + cfm->info.slv_params.slave_latency = 0; + // Slave preferred Link supervision timeout + cfm->info.slv_params.conn_timeout = 200; // 2s (500*10ms) + + // Send message + ke_msg_send(cfm); + } break; + + default: /* Do Nothing */ break; + } + + return (KE_MSG_CONSUMED); +} +/** + **************************************************************************************** + * @brief Handles GAPC_SET_DEV_INFO_REQ_IND message. + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gapc_set_dev_info_req_ind_handler(ke_msg_id_t const msgid, + struct gapc_set_dev_info_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Set Device configuration + struct gapc_set_dev_info_cfm* cfm = KE_MSG_ALLOC(GAPC_SET_DEV_INFO_CFM, src_id, dest_id, + gapc_set_dev_info_cfm); + // Reject to change parameters + cfm->status = GAP_ERR_REJECTED; + cfm->req = param->req; + // Send message + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + +static void POSSIBLY_UNUSED gapc_refresh_remote_dev_feature(uint8_t conidx) +{ + // Send a GAPC_GET_INFO_CMD in order to read the device name characteristic value + struct gapc_get_info_cmd *p_cmd = KE_MSG_ALLOC(GAPC_GET_INFO_CMD, + KE_BUILD_ID(TASK_GAPC, conidx), TASK_GAPM, + gapc_get_info_cmd); + + // request peer device name. + p_cmd->operation = GAPC_GET_PEER_FEATURES; + + // send command + ke_msg_send(p_cmd); +} + +static void POSSIBLY_UNUSED gpac_exchange_data_packet_length(uint8_t conidx) +{ +#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) + return; +#endif + + struct gapc_set_le_pkt_size_cmd *set_le_pakt_size_req = KE_MSG_ALLOC(GAPC_SET_LE_PKT_SIZE_CMD, + KE_BUILD_ID(TASK_GAPC, conidx), + TASK_APP, + gapc_set_le_pkt_size_cmd); + + set_le_pakt_size_req->operation = GAPC_SET_LE_PKT_SIZE; + set_le_pakt_size_req->tx_octets = APP_MAX_TX_OCTETS; + set_le_pakt_size_req->tx_time = APP_MAX_TX_TIME; + // Send message + ke_msg_send(set_le_pakt_size_req); +} + +static int gapc_peer_features_ind_handler(ke_msg_id_t const msgid, + struct gapc_peer_features_ind* param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + LOG_I("Peer dev feature is:"); + DUMP8("0x%02x ", param->features, GAP_LE_FEATS_LEN); + uint8_t conidx = KE_IDX_GET(src_id); + + if (param->features[0] & GAPC_EXT_DATA_LEN_MASK) + { + gpac_exchange_data_packet_length(conidx); + } + return (KE_MSG_CONSUMED); +} + +void app_exchange_remote_feature(uint8_t conidx) +{ + APP_BLE_CONN_CONTEXT_T *pContext = &(app_env.context[conidx]); + + LOG_I("connectStatus:%d, isFeatureExchanged:%d, isGotSolvedBdAddr:%d", + pContext->connectStatus, + pContext->isFeatureExchanged, + pContext->isGotSolvedBdAddr); + + if ((BLE_CONNECTED == pContext->connectStatus) && !pContext->isFeatureExchanged) + { + if (pContext->isGotSolvedBdAddr) + { + gapc_refresh_remote_dev_feature(conidx); + pContext->isFeatureExchanged = true; + } + } +} + +/** + **************************************************************************************** + * @brief Handles connection complete event from the GAP. Enable all required profiles + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gapc_connection_req_ind_handler(ke_msg_id_t const msgid, + struct gapc_connection_req_ind* param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(src_id); + + APP_BLE_CONN_CONTEXT_T* pContext = &(app_env.context[conidx]); + + pContext->connectStatus = BLE_CONNECTED; + + APP_BLE_NEGOTIATED_CONN_PARAM_T connParam; + connParam.con_interval = param->con_interval; + connParam.sup_to= param->sup_to; + connParam.con_latency = param->con_latency; + app_ble_save_negotiated_conn_param(conidx, &connParam); + + ke_state_set(dest_id, APPM_CONNECTED); + + app_env.conn_cnt++; + + if (app_is_resolving_ble_bd_addr()) + { + LOG_I("A ongoing ble addr solving is in progress, refuse the new connection."); + appm_disconnect(conidx); + return KE_MSG_CONSUMED; + } + + LOG_I("[CONNECT]device info:"); + LOG_I("peer addr:"); + DUMP8("%02x ", param->peer_addr.addr, 6); + LOG_I("peer addr type:%d", param->peer_addr_type); + LOG_I("connection index:%d, isGotSolvedBdAddr:%d", conidx, pContext->isGotSolvedBdAddr); + LOG_I("conn interval:%d, timeout:%d", param->con_interval, param->sup_to); + + BLE_APP_FUNC_ENTER(); + + // Check if the received Connection Handle was valid + if (conidx != GAP_INVALID_CONIDX) + { + pContext->peerAddrType = param->peer_addr_type; + memcpy(pContext->bdAddr, param->peer_addr.addr, BD_ADDR_LEN); + + // Retrieve the connection info from the parameters + pContext->conhdl = param->conhdl; + + if (BLE_RANDOM_ADDR == pContext->peerAddrType) + { + pContext->isGotSolvedBdAddr = false; + } + else + { + pContext->isGotSolvedBdAddr = true; + } + + // Clear the advertising timeout timer + if (ke_timer_active(APP_ADV_TIMEOUT_TIMER, TASK_APP)) + { + ke_timer_clear(APP_ADV_TIMEOUT_TIMER, TASK_APP); + } + + #if (BLE_APP_SEC) + app_sec_reset_env_on_connection(); + #endif + + // Send connection confirmation + struct gapc_connection_cfm *cfm = KE_MSG_ALLOC(GAPC_CONNECTION_CFM, + KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP, + gapc_connection_cfm); + + #if (BLE_APP_SEC) + cfm->auth = app_sec_get_bond_status() ? BLE_AUTHENTICATION_LEVEL : GAP_AUTH_REQ_NO_MITM_NO_BOND; + #else // !(BLE_APP_SEC) + cfm->auth = GAP_AUTH_REQ_NO_MITM_NO_BOND; + #endif // (BLE_APP_SEC) + // Send the message + ke_msg_send(cfm); + + // We are now in connected State + ke_state_set(dest_id, APPM_CONNECTED); + app_exchange_remote_feature(conidx); + + app_ble_connected_evt_handler(conidx, param->peer_addr.addr); + } + +#if (BLE_APP_TILE) + app_tile_connected_evt_handler(conidx, param); +#endif + + app_env.context[conidx].connInterval = param->con_interval; + + app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_DEFAULT, true); + BLE_APP_FUNC_LEAVE(); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles GAP controller command complete events. + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gapc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gapc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + switch(param->operation) + { + case (GAPC_UPDATE_PARAMS): + { + if (param->status != GAP_ERR_NO_ERROR) + { +// appm_disconnect(); + } + } break; + + default: + { + } break; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles disconnection complete event from the GAP. + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GAP). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gapc_disconnect_ind_handler(ke_msg_id_t const msgid, + struct gapc_disconnect_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + LOG_I("[DISCONNECT] device info:"); + uint8_t conidx = KE_IDX_GET(src_id); + LOG_I("connection index:%d, reason:0x%x", conidx, param->reason); + + app_env.context[conidx].isBdAddrResolvingInProgress = false; + app_env.context[conidx].isGotSolvedBdAddr = false; + + app_env.context[conidx].connectStatus = BLE_DISCONNECTED; + app_env.context[conidx].isFeatureExchanged = false; + app_env.context[conidx].connInterval = 0; + l2cm_buffer_reset(conidx); + + // Go to the ready state + ke_state_set(TASK_APP, APPM_READY); + + app_env.conn_cnt--; + + #if (BLE_VOICEPATH) + app_voicepath_disconnected_evt_handler(conidx); + #endif + + #if (BLE_DATAPATH_SERVER) + app_datapath_server_disconnected_evt_handler(conidx); + #endif + + #if (BLE_OTA) + app_ota_disconnected_evt_handler(conidx); + #endif + + #if (BLE_APP_TOTA) + app_tota_disconnected_evt_handler(conidx); + #endif + + #if(BLE_APP_GFPS) + app_gfps_disconnected_evt_handler(conidx); + #endif + + + #if (BLE_AI_VOICE) + app_ai_disconnected_evt_handler(conidx); + #endif + + #if (BLE_APP_TILE) + app_tile_disconnected_evt_handler(conidx); + #endif + + app_ble_disconnected_evt_handler(conidx); + + app_ble_reset_conn_param_mode(conidx); + return (KE_MSG_CONSUMED); +} + + +static int gapm_profile_added_ind_handler(ke_msg_id_t const msgid, + struct gapm_profile_added_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + LOG_I("prf_task_id %d is added.", param->prf_task_id); + + return KE_MSG_CONSUMED; +} + +/** + **************************************************************************************** + * @brief Handles reception of all messages sent from the lower layers to the application + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int appm_msg_handler(ke_msg_id_t const msgid, + void *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Retrieve identifier of the task from received message + ke_task_id_t src_task_id = MSG_T(msgid); + // Message policy + uint8_t msg_pol = KE_MSG_CONSUMED; + + + switch (src_task_id) + { + case (TASK_ID_GAPC): + { + #if (BLE_APP_SEC) + if ((msgid >= GAPC_BOND_CMD) && + (msgid <= GAPC_SECURITY_IND)) + { + // Call the Security Module + msg_pol = appm_get_handler(&app_sec_table_handler, msgid, param, src_id); + } + #endif //(BLE_APP_SEC) + // else drop the message + } break; + + case (TASK_ID_GATTC): + { + // Service Changed - Drop + } break; + + #if (BLE_APP_HT) + case (TASK_ID_HTPT): + { + // Call the Health Thermometer Module + msg_pol = appm_get_handler(&app_ht_table_handler, msgid, param, src_id); + } break; + #endif //(BLE_APP_HT) + + #if (BLE_APP_DIS) + case (TASK_ID_DISS): + { + // Call the Device Information Module + msg_pol = appm_get_handler(&app_dis_table_handler, msgid, param, src_id); + } break; + #endif //(BLE_APP_DIS) + + #if (BLE_APP_HID) + case (TASK_ID_HOGPD): + { + // Call the HID Module + msg_pol = appm_get_handler(&app_hid_table_handler, msgid, param, src_id); + } break; + #endif //(BLE_APP_HID) + + #if (BLE_APP_BATT) + case (TASK_ID_BASS): + { + // Call the Battery Module + msg_pol = appm_get_handler(&app_batt_table_handler, msgid, param, src_id); + } break; + #endif //(BLE_APP_BATT) + + #if defined(BLE_APP_AM0) + case (TASK_ID_AM0): + { + // Call the Audio Mode 0 Module + msg_pol = appm_get_handler(&am0_app_table_handler, msgid, param, src_id); + } break; + case (TASK_ID_AM0_HAS): + { + // Call the Audio Mode 0 Module + msg_pol = appm_get_handler(&am0_app_has_table_handler, msgid, param, src_id); + } break; + #endif // defined(BLE_APP_AM0) + + #if (BLE_APP_HR) + case (TASK_ID_HRPS): + { + // Call the HRPS Module + msg_pol = appm_get_handler(&app_hrps_table_handler, msgid, param, src_id); + } break; + #endif + + #if (BLE_APP_VOICEPATH) + case (TASK_ID_VOICEPATH): + { + // Call the Voice Path Module + msg_pol = appm_get_handler(app_voicepath_ble_get_msg_handler_table(), msgid, param, src_id); + } break; + #endif //(BLE_APP_VOICEPATH) + + #if (BLE_APP_DATAPATH_SERVER) + case (TASK_ID_DATAPATHPS): + { + // Call the Data Path Module + msg_pol = appm_get_handler(&app_datapath_server_table_handler, msgid, param, src_id); + } break; + #endif //(BLE_APP_DATAPATH_SERVER) + #if (BLE_APP_TILE) + case (TASK_ID_TILE): + { + // Call the TILE Module + msg_pol = appm_get_handler(&app_tile_table_handler, msgid, param, src_id); + } + break; + #endif + + #if (BLE_APP_AI_VOICE) + case (TASK_ID_AI): + { + // Call the AI Voice + msg_pol = appm_get_handler(app_ai_table_handler, msgid, param, src_id); + } break; + #endif //(BLE_APP_AI_VOICE) + + #if (BLE_APP_OTA) + case (TASK_ID_OTA): + { + // Call the OTA + msg_pol = appm_get_handler(&app_ota_table_handler, msgid, param, src_id); + } break; + #endif //(BLE_APP_OTA) + + #if (BLE_APP_TOTA) + case (TASK_ID_TOTA): + { + // Call the TOTA + msg_pol = appm_get_handler(&app_tota_table_handler, msgid, param, src_id); + } break; + #endif //(BLE_APP_TOTA) + + #if (BLE_APP_ANCC) + case (TASK_ID_ANCC): + { + // Call the ANCC + msg_pol = appm_get_handler(&app_ancc_table_handler, msgid, param, src_id); + } break; + #endif //(BLE_APP_ANCC) + + #if (BLE_APP_AMS) + case (TASK_ID_AMSC): + { + // Call the AMS + msg_pol = appm_get_handler(&app_amsc_table_handler, msgid, param, src_id); + } break; + #endif //(BLE_APP_AMS) + #if (BLE_APP_GFPS) + case (TASK_ID_GFPSP): + { + msg_pol = appm_get_handler(&app_gfps_table_handler, msgid, param, src_id); + } break; + #endif + + default: + { + #if (BLE_APP_HT) + if (msgid == APP_HT_MEAS_INTV_TIMER) + { + msg_pol = appm_get_handler(&app_ht_table_handler, msgid, param, src_id); + } + #endif //(BLE_APP_HT) + + #if (BLE_APP_HID) + if (msgid == APP_HID_MOUSE_TIMEOUT_TIMER) + { + msg_pol = appm_get_handler(&app_hid_table_handler, msgid, param, src_id); + } + #endif //(BLE_APP_HID) + } break; + } + + return (msg_pol); +} + +static int gapm_adv_report_ind_handler(ke_msg_id_t const msgid, + struct gapm_adv_report_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + app_adv_reported_scanned(param); + return KE_MSG_CONSUMED; +} + +static int gapm_addr_solved_ind_handler(ke_msg_id_t const msgid, + struct gapm_addr_solved_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + /// Indicate that resolvable random address has been solved + appm_random_ble_addr_solved(true, param->irk.key); + return KE_MSG_CONSUMED; +} + +__STATIC int gattc_mtu_changed_ind_handler(ke_msg_id_t const msgid, + struct gattc_mtu_changed_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(src_id); + + LOG_I("MTU has been negotiated as %d conidx %d", param->mtu, conidx); + + +#if (BLE_APP_DATAPATH_SERVER) + app_datapath_server_mtu_exchanged_handler(conidx, param->mtu); +#endif + +#if (BLE_VOICEPATH) + app_voicepath_mtu_exchanged_handler(conidx, param->mtu); +#endif + +#if (BLE_OTA) + app_ota_mtu_exchanged_handler(conidx, param->mtu); +#endif + +#if (BLE_APP_TOTA) + app_tota_mtu_exchanged_handler(conidx, param->mtu); +#endif + +#if (BLE_AI_VOICE) + app_ai_mtu_exchanged_handler(conidx, param->mtu); +#endif + + return (KE_MSG_CONSUMED); +} + +#define APP_CONN_PARAM_INTERVEL_MAX (30) +__STATIC int gapc_conn_param_update_req_ind_handler(ke_msg_id_t const msgid, + struct gapc_param_update_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + bool accept = true; + ble_evnet_t event; + + LOG_I("Receive the conn param update request: min %d max %d latency %d timeout %d", + param->intv_min, + param->intv_max, + param->latency, + param->time_out); + + struct gapc_param_update_cfm* cfm = KE_MSG_ALLOC(GAPC_PARAM_UPDATE_CFM, src_id, dest_id, + gapc_param_update_cfm); + + event.evt_type = BLE_CONN_PARAM_UPDATE_REQ_EVENT; + event.p.conn_param_update_req_handled.intv_min = param->intv_min; + event.p.conn_param_update_req_handled.intv_max = param->intv_max; + event.p.conn_param_update_req_handled.latency = param->latency; + event.p.conn_param_update_req_handled.time_out = param->time_out; + + app_ble_core_global_handle(&event, &accept); + LOG_I("%s ret %d ", __func__, accept); + + cfm->accept = accept; + +#ifdef GFPS_ENABLED + // if fastpair doesn't have the requirement of finishing + // pairing in a really short period, just comment out this + // code block to avoid audio glitch if this event happens during music + // playback and interval is smaller than 15ms + if (param->intv_min < (uint16_t)(15/1.25)) + { + LOG_I("accept"); + cfm->accept = true; + fp_update_ble_connect_param_start(KE_IDX_GET(src_id)); + } + else + { + fp_update_ble_connect_param_stop(KE_IDX_GET(src_id)); + } +#endif + + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + +static int gapc_conn_param_updated_handler(ke_msg_id_t const msgid, + struct gapc_param_updated_ind* param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(src_id); + LOG_I("Conidx %d conn parameter is updated as interval %d timeout %d", + conidx, + param->con_interval, + param->sup_to); + + APP_BLE_NEGOTIATED_CONN_PARAM_T connParam; + connParam.con_interval = param->con_interval; + connParam.sup_to= param->sup_to; + connParam.con_latency = param->con_latency; + app_ble_save_negotiated_conn_param(conidx, &connParam); + +#if (BLE_VOICEPATH) + app_voicepath_ble_conn_parameter_updated(conidx, param->con_interval, param->con_latency); +#endif +#if BLE_APP_TILE + app_tile_ble_conn_parameter_updated(conidx, param); +#endif + + app_env.context[conidx].connInterval = param->con_interval; + + if (param->con_interval >= 32) + { + if (app_ble_is_parameter_mode_enabled(conidx, BLE_CONN_PARAM_MODE_OTA)) + { + app_ble_parameter_mode_clear(conidx, BLE_CONN_PARAM_MODE_OTA); + app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_OTA_SLOWER, true); + } + else if (app_ble_is_parameter_mode_enabled(conidx, BLE_CONN_PARAM_MODE_AI_STREAM_ON)) + { + app_ble_parameter_mode_clear(conidx, BLE_CONN_PARAM_MODE_AI_STREAM_ON); + app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_AI_STREAM_ON, true); + } + } + + return (KE_MSG_CONSUMED); +} + +static int gapm_dev_addr_ind_handler(ke_msg_id_t const msgid, + struct gapm_dev_bdaddr_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + ble_evnet_t event; + + // Indicate that a new random BD address set in lower layers + LOG_I("New dev addr:"); + DUMP8("%02x ", param->addr.addr.addr, 6); + +#ifdef GFPS_ENABLED + app_fp_msg_send_updated_ble_addr(); + app_gfps_update_random_salt(); +#endif + + + event.evt_type = BLE_SET_RANDOM_BD_ADDR_EVENT; + event.p.set_random_bd_addr_handled.new_bdaddr = param->addr.addr.addr; + app_ble_core_global_handle(&event, NULL); + + return KE_MSG_CONSUMED; +} + + +/* + * GLOBAL VARIABLES DEFINITION + **************************************************************************************** + */ +/* Default State handlers definition. */ +KE_MSG_HANDLER_TAB(appm) +{ + // Note: first message is latest message checked by kernel so default is put on top. + {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)appm_msg_handler}, + + {APP_ADV_TIMEOUT_TIMER, (ke_msg_func_t)app_adv_timeout_handler}, + + {GAPM_DEVICE_READY_IND, (ke_msg_func_t)gapm_device_ready_ind_handler}, + {GAPM_CMP_EVT, (ke_msg_func_t)gapm_cmp_evt_handler}, + {GAPC_GET_DEV_INFO_REQ_IND, (ke_msg_func_t)gapc_get_dev_info_req_ind_handler}, + {GAPC_SET_DEV_INFO_REQ_IND, (ke_msg_func_t)gapc_set_dev_info_req_ind_handler}, + {GAPC_CONNECTION_REQ_IND, (ke_msg_func_t)gapc_connection_req_ind_handler}, + {GAPC_CMP_EVT, (ke_msg_func_t)gapc_cmp_evt_handler}, + {GAPC_DISCONNECT_IND, (ke_msg_func_t)gapc_disconnect_ind_handler}, + {GAPM_PROFILE_ADDED_IND, (ke_msg_func_t)gapm_profile_added_ind_handler}, + {GATTC_MTU_CHANGED_IND, (ke_msg_func_t)gattc_mtu_changed_ind_handler}, + {GAPC_PARAM_UPDATE_REQ_IND, (ke_msg_func_t)gapc_conn_param_update_req_ind_handler}, + {GAPC_PARAM_UPDATED_IND, (ke_msg_func_t)gapc_conn_param_updated_handler}, + {GAPM_ADV_REPORT_IND, (ke_msg_func_t)gapm_adv_report_ind_handler}, + {GAPC_PEER_FEATURES_IND, (ke_msg_func_t)gapc_peer_features_ind_handler}, + {GAPM_ADDR_SOLVED_IND, (ke_msg_func_t)gapm_addr_solved_ind_handler}, + {GAPM_DEV_BDADDR_IND, (ke_msg_func_t)gapm_dev_addr_ind_handler}, +}; + + +/* Defines the place holder for the states of all the task instances. */ +ke_state_t appm_state[APP_IDX_MAX]; + +const struct ke_task_desc TASK_DESC_APP = {appm_msg_handler_tab, appm_state, APP_IDX_MAX, ARRAY_LEN(appm_msg_handler_tab)}; + +#endif //(BLE_APP_PRESENT) + +/// @} APPTASK diff --git a/services/ble_app/app_main/app_task.h b/services/ble_app/app_main/app_task.h new file mode 100644 index 0000000..513ec8c --- /dev/null +++ b/services/ble_app/app_main/app_task.h @@ -0,0 +1,107 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef APP_TASK_H_ +#define APP_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup APPTASK Task + * @ingroup APP + * @brief Routes ALL messages to/from APP block. + * + * The APPTASK is the block responsible for bridging the final application with the + * RWBLE software host stack. It communicates with the different modules of the BLE host, + * i.e. @ref SMP, @ref GAP and @ref GATT. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_PRESENT) + +#include // Standard Integer +#include "rwip_task.h" // Task definitions +#include "ke_task.h" // Kernel Task + +/* + * DEFINES + **************************************************************************************** + */ + +/// Number of APP Task Instances +#define APP_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// States of APP task +enum appm_state +{ + /// Initialization state + APPM_INIT, + /// Database create state + APPM_CREATE_DB, + /// Ready State + APPM_READY, + /// Advertising state + APPM_ADVERTISING, + /// Scanning state + APPM_SCANNING, + /// connecting state + APPM_CONNECTING, + /// Connected state + APPM_CONNECTED, + + /// Number of defined states. + APPM_STATE_MAX +}; + + +/// APP Task messages +enum appm_msg +{ + APPM_DUMMY_MSG = TASK_FIRST_MSG(TASK_ID_APP), + + /// Timer used to automatically stop advertising + APP_ADV_TIMEOUT_TIMER, + + #if (BLE_APP_HT) + /// Timer used to refresh the temperature measurement value + APP_HT_MEAS_INTV_TIMER, + #endif //(BLE_APP_HT) + + #if (BLE_APP_HID) + /// Timer used to disconnect the moue if no activity is detecter + APP_HID_MOUSE_TIMEOUT_TIMER, + #endif //(BLE_APP_HID) +}; + + + +/// @} APPTASK + +#endif //(BLE_APP_PRESENT) + +#endif // APP_TASK_H_ diff --git a/services/ble_app/app_ota/app_ota.c b/services/ble_app/app_ota/app_ota.c new file mode 100644 index 0000000..ae1e092 --- /dev/null +++ b/services/ble_app/app_ota/app_ota.c @@ -0,0 +1,286 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_OTA) + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "app_ota.h" // OTA Application Definitions +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "ota_task.h" +#include "co_bt.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "arch.h" // Platform Definitions +#include "prf.h" +#include "string.h" +#include "ota_control.h" +#include "ota_bes.h" + +#include "app_ble_rx_handler.h" +#include "app_ble_mode_switch.h" +#if defined(IBRT) +#include "app_tws_ibrt.h" +#endif + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ +struct app_ota_env_tag app_ota_env; + +static app_ota_tx_done_t ota_data_tx_done_callback = NULL; + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +void app_ota_connected_evt_handler(uint8_t conidx) +{ + app_ota_env.connectionIndex = conidx; + app_ota_connected(APP_OTA_CONNECTED); + ota_control_set_datapath_type(DATA_PATH_BLE); + ota_control_register_transmitter(app_ota_send_notification); + l2cap_update_param(conidx, 10, 15, 20000, 0); +} + +void app_ota_disconnected_evt_handler(uint8_t conidx) +{ + if (conidx == app_ota_env.connectionIndex) + { + app_ota_env.connectionIndex = BLE_INVALID_CONNECTION_INDEX; + app_ota_env.isNotificationEnabled = false; + app_ota_env.mtu[conidx] = 0; + app_ota_disconnected(APP_OTA_DISCONNECTED); + } +} + +static void app_ota_ble_data_fill_handler(void *param) +{ + // normally we won't allow OTA owned adv when there is already + // an existing BLE connection. For special requirement, you can + // disable this limitation + if (app_ble_connection_count() > 0) + { + app_ble_data_fill_enable(USER_OTA, false); + return; + } + + bool adv_enable = false; + +#if defined(IBRT) + if (app_tws_ibrt_get_bt_ctrl_ctx()->init_done) + { + if (app_tws_ibrt_role_get_callback(NULL) != IBRT_MASTER) + { + TRACE(2,"%s role %d isn't MASTER", __func__, app_tws_ibrt_role_get_callback(NULL)); + } + else if (!app_tws_ibrt_mobile_link_connected()) + { + TRACE(1,"%s don't connect mobile", __func__); + } + else + { + adv_enable = true; + } + } +#else + adv_enable = true; +#endif + + app_ble_data_fill_enable(USER_OTA, adv_enable); +} + +void app_ota_init(void) +{ + // Reset the environment + app_ota_env.connectionIndex = BLE_INVALID_CONNECTION_INDEX; + app_ota_env.isNotificationEnabled = false; + memset((uint8_t *)&(app_ota_env.mtu), 0, sizeof(app_ota_env.mtu)); + + app_ble_register_data_fill_handle(USER_OTA, + ( BLE_DATA_FILL_FUNC_T )app_ota_ble_data_fill_handler, false); +} + +void app_ota_add_ota(void) +{ + BLE_APP_DBG("app_ota_add_ota"); + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, TASK_APP, + gapm_profile_task_add_cmd, 0); + + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX>1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE)|PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + + req->prf_task_id = TASK_ID_OTA; + req->app_task = TASK_APP; + req->start_hdl = 0; + + // Send the message + ke_msg_send(req); +} + +void app_ota_send_notification(uint8_t* ptrData, uint32_t length) +{ + TRACE(0,"Send ota rsp:"); + DUMP8("%02x ", ptrData, length); + + struct ble_ota_send_data_req_t * req = KE_MSG_ALLOC_DYN(OTA_SEND_NOTIFICATION, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_OTA), app_ota_env.connectionIndex), + TASK_APP, + ble_ota_send_data_req_t, + length); + req->connecionIndex = app_ota_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + + ke_msg_send(req); +} + +void app_ota_send_indication(uint8_t* ptrData, uint32_t length) +{ + struct ble_ota_send_data_req_t * req = KE_MSG_ALLOC_DYN(OTA_SEND_INDICATION, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_OTA), app_ota_env.connectionIndex), + TASK_APP, + ble_ota_send_data_req_t, + length); + req->connecionIndex = app_ota_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + + ke_msg_send(req); +} + +static int app_ota_msg_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Do nothing + return (KE_MSG_CONSUMED); +} + +static int app_ota_ccc_changed_handler(ke_msg_id_t const msgid, + struct ble_ota_tx_notif_config_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + TRACE(1,"ota data ccc changed to %d", param->isNotificationEnabled); + app_ota_env.isNotificationEnabled = param->isNotificationEnabled; + + if (app_ota_env.isNotificationEnabled) + { + if (BLE_INVALID_CONNECTION_INDEX == app_ota_env.connectionIndex) + { + uint8_t conidx = KE_IDX_GET(src_id); + app_ota_connected_evt_handler(conidx); + + if (app_ota_env.mtu[conidx]) + { + ota_control_update_MTU(app_ota_env.mtu[conidx]); + } + } + } + + return (KE_MSG_CONSUMED); +} + +static int app_ota_tx_data_sent_handler(ke_msg_id_t const msgid, + struct ble_ota_tx_sent_ind_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if (NULL != ota_data_tx_done_callback) + { + ota_data_tx_done_callback(); + } + + //ota_data_transmission_done_callback(); + + return (KE_MSG_CONSUMED); +} + +static int app_ota_data_received_handler(ke_msg_id_t const msgid, + struct ble_ota_rx_data_ind_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + app_ble_push_rx_data(BLE_RX_DATA_SELF_OTA, app_ota_env.connectionIndex, param->data, param->length); + return (KE_MSG_CONSUMED); +} + +void app_ota_register_tx_done(app_ota_tx_done_t callback) +{ + ota_data_tx_done_callback = callback; +} + +void app_ota_mtu_exchanged_handler(uint8_t conidx, uint16_t MTU) +{ + if (conidx == app_ota_env.connectionIndex) + { + ota_control_update_MTU(MTU); + } + else + { + app_ota_env.mtu[conidx] = MTU; + } +} + +uint8_t app_ota_get_conidx(void) +{ + return app_ota_env.connectionIndex; +} +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +const struct ke_msg_handler app_ota_msg_handler_list[] = +{ + // Note: first message is latest message checked by kernel so default is put on top. + {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_ota_msg_handler}, + + {OTA_CCC_CHANGED, (ke_msg_func_t)app_ota_ccc_changed_handler}, + {OTA_TX_DATA_SENT, (ke_msg_func_t)app_ota_tx_data_sent_handler}, + {OTA_DATA_RECEIVED, (ke_msg_func_t)app_ota_data_received_handler}, +}; + +const struct ke_state_handler app_ota_table_handler = + {&app_ota_msg_handler_list[0], (sizeof(app_ota_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif //BLE_APP_OTA + +/// @} APP diff --git a/services/ble_app/app_ota/app_ota.h b/services/ble_app/app_ota/app_ota.h new file mode 100644 index 0000000..a32da7d --- /dev/null +++ b/services/ble_app/app_ota/app_ota.h @@ -0,0 +1,120 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef APP_OTA_H_ +#define APP_OTA_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * @ingroup RICOW + * + * @brief OTA Application entry point. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_OTA) + +#include // Standard Integer Definition +#include "ke_task.h" +#include "app_ble_mode_switch.h" +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ +#ifdef __cplusplus +extern "C" { +#endif + +#define OTA_HIGH_SPEED_BLE_CONNECTION_INTERVAL_MIN_IN_MS 25 +#define OTA_HIGH_SPEED_BLE_CONNECTION_INTERVAL_MAX_IN_MS 30 +#define OTA_HIGH_SPEED_BLE_CONNECTION_SUPERVISOR_TIMEOUT_IN_MS 5000 + +#define OTA_LOW_SPEED_BLE_CONNECTION_INTERVAL_MIN_IN_MS 400 +#define OTA_LOW_SPEED_BLE_CONNECTION_INTERVAL_MAX_IN_MS 500 +#define OTA_LOW_SPEED_BLE_CONNECTION_SUPERVISOR_TIMEOUT_IN_MS 5000 + + +extern struct app_env_tag app_env; + +/// health thermometer application environment structure +struct app_ota_env_tag +{ + uint8_t connectionIndex; + uint8_t isNotificationEnabled; + uint16_t mtu[BLE_CONNECTION_MAX]; +}; + +typedef void(*app_ota_tx_done_t)(void); + +/* + * GLOBAL VARIABLES DECLARATIONS + **************************************************************************************** + */ + +/// Health Thermomter Application environment +extern struct app_ota_env_tag app_ota_env; + +/// Table of message handlers +extern const struct ke_state_handler app_ota_table_handler; + +/* + * FUNCTIONS DECLARATION + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialize DataPath Server Application + **************************************************************************************** + */ +void app_ota_init(void); + +void app_ota_add_ota(void); + +void app_ota_connected_evt_handler(uint8_t conidx); + +void app_ota_disconnected_evt_handler(uint8_t conidx); + +void app_ota_send_notification(uint8_t* ptrData, uint32_t length); + +void app_ota_send_indication(uint8_t* ptrData, uint32_t length); + +void app_ota_register_tx_done(app_ota_tx_done_t callback); + +void app_ota_mtu_exchanged_handler(uint8_t conidx, uint16_t MTU); + +uint8_t app_ota_get_conidx(void); + +#ifdef __cplusplus + } +#endif + + +#endif //(BLE_APP_OTA) + +/// @} APP + +#endif // APP_OTA_H_ diff --git a/services/ble_app/app_sec/app_sec.c b/services/ble_app/app_sec/app_sec.c new file mode 100644 index 0000000..cf1cd49 --- /dev/null +++ b/services/ble_app/app_sec/app_sec.c @@ -0,0 +1,448 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_APP_SEC) + +#include +#include "co_math.h" +#include "gapc_task.h" // GAP Controller Task API Definition +#include "gap.h" // GAP Definition +#include "gapc.h" // GAPC Definition +#include "prf_types.h" + +#include "app.h" // Application API Definition +#include "app_ble_include.h" +#include "app_sec.h" // Application Security API Definition +#include "app_task.h" // Application Manager API Definition + +#if (DISPLAY_SUPPORT) +#include "app_display.h" // Display Application Definitions +#endif //(DISPLAY_SUPPORT) + +#if (NVDS_SUPPORT) +#include "nvds.h" // NVDS API Definitions +#endif //(NVDS_SUPPORT) + +#ifdef BLE_APP_AM0 +#include "am0_app.h" +#endif // BLE_APP_AM0 + +#if (BLE_APP_ANCC) +#include "app_ancc.h" // ANC Module Definition +#endif // (BLE_APP_ANCC) + +#if (BLE_APP_AMS) +#include "app_amsc.h" // AMS Module Definition +#endif // (BLE_APP_AMS) + +#include "app_gfps.h" +#include "nvrecord_ble.h" +#include "tgt_hardware.h" +#include "nvrecord_extension.h" + +#ifdef _BLE_NVDS_ +#define BLE_KEY_PRINT +BleDeviceinfo ble_save_info; +#endif + +#ifdef TWS_SYSTEM_ENABLED +#include "app_tws_if.h" +#endif + + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Application Security Environment Structure +struct app_sec_env_tag app_sec_env; + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +void app_sec_init(void) +{ +#ifdef _BLE_NVDS_ + if (nv_record_ble_record_Once_a_device_has_been_bonded()) + { + app_sec_env.bonded = true; + } + else + { + app_sec_env.bonded = false; + } + + TRACE(2,"[%s] once bonded:%d", __func__, app_sec_env.bonded); +#endif +} + +bool app_sec_get_bond_status(void) +{ + return app_sec_env.bonded; +} + +void app_sec_send_security_req(uint8_t conidx, enum gap_auth authority) +{ + // Send security request + struct gapc_security_cmd *cmd = KE_MSG_ALLOC(GAPC_SECURITY_CMD, + KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP, + gapc_security_cmd); + + cmd->operation = GAPC_SECURITY_REQ; + + cmd->auth = authority; + + // Send the message + ke_msg_send(cmd); +} + +/* + * MESSAGE HANDLERS + **************************************************************************************** + */ + +static int gapc_bond_req_ind_handler(ke_msg_id_t const msgid, + struct gapc_bond_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + TRACE(1,"Get bond req %d", param->request); + + // Prepare the GAPC_BOND_CFM message + struct gapc_bond_cfm *cfm = KE_MSG_ALLOC(GAPC_BOND_CFM, + src_id, TASK_APP, + gapc_bond_cfm); + + switch (param->request) + { + case (GAPC_PAIRING_REQ): + { + cfm->request = GAPC_PAIRING_RSP; + + cfm->accept = true; + + cfm->data.pairing_feat.auth = BLE_AUTHENTICATION_LEVEL; + + #if (BLE_APP_GFPS) + cfm->data.pairing_feat.iocap = GAP_IO_CAP_DISPLAY_YES_NO; + #else + cfm->data.pairing_feat.iocap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT; + #endif + + cfm->data.pairing_feat.key_size = 16; + cfm->data.pairing_feat.oob = GAP_OOB_AUTH_DATA_NOT_PRESENT; + #if (BLE_APP_GFPS) + cfm->data.pairing_feat.sec_req = GAP_SEC1_SEC_CON_PAIR_ENC; + #else + cfm->data.pairing_feat.sec_req = GAP_SEC1_NOAUTH_PAIR_ENC; + #endif + + cfm->data.pairing_feat.ikey_dist = GAP_KDIST_ENCKEY | GAP_KDIST_IDKEY | GAP_KDIST_LINKKEY; + cfm->data.pairing_feat.rkey_dist = GAP_KDIST_ENCKEY | GAP_KDIST_IDKEY | GAP_KDIST_LINKKEY; + } break; + + case (GAPC_LTK_EXCH): + { + // Counter + uint8_t counter; + + cfm->accept = true; + cfm->request = GAPC_LTK_EXCH; + + // Generate all the values + cfm->data.ltk.ediv = (uint16_t)co_rand_word(); + + for (counter = 0; counter < RAND_NB_LEN; counter++) + { + cfm->data.ltk.randnb.nb[counter] = (uint8_t)co_rand_word(); + } + + for (counter = 0; counter < GAP_KEY_LEN; counter++) + { + cfm->data.ltk.ltk.key[counter] = (uint8_t)co_rand_word(); + } + +#ifdef _BLE_NVDS_ +#ifdef BLE_KEY_PRINT + TRACE(0,"<==============>LTK IS:"); + DUMP8("%02x ",(uint8_t *)&cfm->data.ltk,16); + TRACE(1,"<==============>EDIV IS: %04x:",cfm->data.ltk.ediv); + TRACE(0,"<==============>RANDOM IS:"); + DUMP8("%02x ",(uint8_t *)&cfm->data.ltk.randnb.nb,8); +#endif + ble_save_info.EDIV = cfm->data.ltk.ediv; + memcpy(&ble_save_info.RANDOM, (uint8_t *)&cfm->data.ltk.randnb.nb, 8); + memcpy(&ble_save_info.LTK, (uint8_t *)&cfm->data.ltk, 16); + + ble_save_info.bonded = false; +#endif + } break; + + case (GAPC_IRK_EXCH): + { + cfm->accept = true; + cfm->request = GAPC_IRK_EXCH; + + // Load IRK + memcpy(cfm->data.irk.irk.key, app_env.loc_irk, KEY_LEN); + // load identity ble address + memcpy(cfm->data.irk.addr.addr.addr, ble_addr, BLE_ADDR_SIZE); + cfm->data.irk.addr.addr_type = ADDR_PUBLIC; + } break; + case (GAPC_TK_EXCH): + { + // Generate a PIN Code- (Between 100000 and 999999) + uint32_t pin_code = (100000 + (co_rand_word()%900000)); + + cfm->accept = true; + cfm->request = GAPC_TK_EXCH; + + // Set the TK value + memset(cfm->data.tk.key, 0, KEY_LEN); + + cfm->data.tk.key[0] = (uint8_t)((pin_code & 0x000000FF) >> 0); + cfm->data.tk.key[1] = (uint8_t)((pin_code & 0x0000FF00) >> 8); + cfm->data.tk.key[2] = (uint8_t)((pin_code & 0x00FF0000) >> 16); + cfm->data.tk.key[3] = (uint8_t)((pin_code & 0xFF000000) >> 24); + } break; + case GAPC_NC_EXCH: + cfm->accept = true; + cfm->request = GAPC_NC_EXCH; + break; + default: + { + ASSERT_ERR(0); + } break; + } + + // Send the message + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + +void app_sec_reset_env_on_connection(void) +{ +#ifdef _BLE_NVDS_ + memset(&ble_save_info, 0, sizeof(BleDeviceinfo)); +#endif +} + +static int gapc_bond_ind_handler(ke_msg_id_t const msgid, + struct gapc_bond_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(src_id); + switch (param->info) + { + case (GAPC_PAIRING_SUCCEED): + { + TRACE(0,"GAPC_PAIRING_SUCCEED"); + // Update the bonding status in the environment + app_sec_env.bonded = true; +#ifdef _BLE_NVDS_ + ble_save_info.bonded = true; + + if (!nv_record_blerec_add(&ble_save_info)) + { +#ifdef TWS_SYSTEM_ENABLED + app_ble_sync_ble_info(); + TRACE(0,"BLE NVDS SETUP SUCCESS!!!,the key is the newest"); +#endif + } +#endif + break; + } + case (GAPC_REPEATED_ATTEMPT): + { + appm_disconnect(conidx); + break; + } + case (GAPC_IRK_EXCH): + { + TRACE(0,"Peer device IRK is:"); +#ifdef _BLE_NVDS_ + DUMP8("%02x ", param->data.irk.irk.key, BLE_IRK_SIZE); + DUMP8("%02x ", (uint8_t *)&(param->data.irk.addr), BLE_ADDR_SIZE+1); + app_env.context[conidx].isBdAddrResolvingInProgress = false; + app_env.context[conidx].isGotSolvedBdAddr = true; + memcpy(app_env.context[conidx].solvedBdAddr, param->data.irk.addr.addr.addr, BLE_ADDR_SIZE); + memcpy(ble_save_info.IRK, param->data.irk.irk.key, BLE_IRK_SIZE); + memcpy(ble_save_info.peer_bleAddr, param->data.irk.addr.addr.addr, BLE_ADDR_SIZE); +#endif + app_exchange_remote_feature(conidx); + break; + } + case (GAPC_PAIRING_FAILED): + { + TRACE(1,"GAPC_PAIRING_FAILED!!! Error code 0x%x", param->data.reason); +#ifdef _BLE_NVDS_ + nv_record_ble_delete_entry(app_env.context[conidx].solvedBdAddr); + app_sec_env.bonded = false; +#endif + break; + } + case GAPC_LTK_EXCH: + { +#ifdef _BLE_NVDS_ + TRACE(1,"isLocal %d", param->data.ltk.isLocal); + TRACE(0,"Peer device LTK is:"); + + DUMP8("%02x ", param->data.ltk.ltk.key, BLE_LTK_SIZE); + TRACE(1,"EDIV %04x ", param->data.ltk.ediv); + TRACE(0,"Peer device random number is:"); + DUMP8("%02x ", param->data.ltk.randnb.nb, BLE_ENC_RANDOM_SIZE); + + + if (param->data.ltk.isLocal) + { + ble_save_info.EDIV = param->data.ltk.ediv; + memcpy(&ble_save_info.RANDOM, (uint8_t *)¶m->data.ltk.randnb.nb, BLE_ENC_RANDOM_SIZE); + memcpy(&ble_save_info.LTK, (uint8_t *)¶m->data.ltk, BLE_LTK_SIZE); + } +#endif + break; + } + default: + { + ASSERT_ERR(0); + break; + } + } + + return (KE_MSG_CONSUMED); +} + +static int gapc_encrypt_req_ind_handler(ke_msg_id_t const msgid, + struct gapc_encrypt_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + TRACE(1,"%s, master ask for LTK TO encrypt!!!!", __FUNCTION__); + + uint8_t conidx = KE_IDX_GET(src_id); + + appm_check_and_resolve_ble_address(conidx); + + if (!app_env.context[conidx].isGotSolvedBdAddr) + { + return (KE_MSG_SAVED); + } + + TRACE(0,"Random ble address solved. Can rsp enc req."); + + // Prepare the GAPC_ENCRYPT_CFM message + struct gapc_encrypt_cfm *cfm = KE_MSG_ALLOC(GAPC_ENCRYPT_CFM, + src_id, TASK_APP, + gapc_encrypt_cfm); + + cfm->found = false; + +#ifdef _BLE_NVDS_ + + struct gapc_ltk ltk; + + bool ret; + ret = nv_record_ble_record_find_ltk_through_static_bd_addr( + app_env.context[conidx].solvedBdAddr, ltk.ltk.key); + if(ret){ + TRACE(0,"FIND LTK SUCCESSED!!!"); +#ifdef BLE_KEY_PRINT + DUMP8("%02x ", (uint8_t *)ltk.ltk.key, 16); +#endif + cfm->found = true; + cfm->key_size = 16; + memcpy(&cfm->ltk, ltk.ltk.key, sizeof(struct gap_sec_key)); + + }else{ + TRACE(0,"FIND LTK failed!!!"); + } +#endif + + TRACE(2,"%s app_sec_env.bonded %d", __FUNCTION__, app_sec_env.bonded); + + // Send the message + ke_msg_send(cfm); + + // encryption has been completed, we can start exchanging remote features now + app_exchange_remote_feature(conidx); + + return (KE_MSG_CONSUMED); +} + + +static int gapc_encrypt_ind_handler(ke_msg_id_t const msgid, + struct gapc_encrypt_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + TRACE(2,"%s param->auth %d", __FUNCTION__, param->auth); + + return (KE_MSG_CONSUMED); +} + +static int app_sec_msg_dflt_handler(ke_msg_id_t const msgid, + void *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Drop the message + + return (KE_MSG_CONSUMED); +} + + /* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +const struct ke_msg_handler app_sec_msg_handler_list[] = +{ + // Note: first message is latest message checked by kernel so default is put on top. + {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_sec_msg_dflt_handler}, + + {GAPC_BOND_REQ_IND, (ke_msg_func_t)gapc_bond_req_ind_handler}, + {GAPC_BOND_IND, (ke_msg_func_t)gapc_bond_ind_handler}, + + {GAPC_ENCRYPT_REQ_IND, (ke_msg_func_t)gapc_encrypt_req_ind_handler}, + {GAPC_ENCRYPT_IND, (ke_msg_func_t)gapc_encrypt_ind_handler}, +}; + +const struct ke_state_handler app_sec_table_handler = + {&app_sec_msg_handler_list[0], (sizeof(app_sec_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif //(BLE_APP_SEC) + +/// @} APP diff --git a/services/ble_app/app_sec/app_sec.h b/services/ble_app/app_sec/app_sec.h new file mode 100644 index 0000000..0fade99 --- /dev/null +++ b/services/ble_app/app_sec/app_sec.h @@ -0,0 +1,111 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/** + **************************************************************************************** + * @addtogroup APP_SEC + * @{ + **************************************************************************************** + */ + +#ifndef APP_SEC_H_ +#define APP_SEC_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_APP_SEC) + +#include // Standard Integer Definition + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * STRUCTURES DEFINITIONS + **************************************************************************************** + */ + +struct app_sec_env_tag +{ + // Bond status + bool bonded; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/// Application Security Environment +extern struct app_sec_env_tag app_sec_env; + +/// Table of message handlers +extern const struct ke_state_handler app_sec_table_handler; + +/* + * GLOBAL FUNCTIONS DECLARATIONS + **************************************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + **************************************************************************************** + * @brief Initialize the Application Security Module + **************************************************************************************** + */ +void app_sec_init(void); + + +#if (NVDS_SUPPORT) +/** + **************************************************************************************** + * @brief Remove all bond data stored in NVDS + **************************************************************************************** + */ +void app_sec_remove_bond(void); +#endif //(NVDS_SUPPORT) + +/** + **************************************************************************************** + * @brief Send a security request to the peer device. This function is used to require the + * central to start the encryption with a LTK that would have shared during a previous + * bond procedure. + * + * @param[in] - conidx: Connection Index + **************************************************************************************** + */ +void app_sec_send_security_req(uint8_t conidx, enum gap_auth authority); + +void app_sec_reset_env_on_connection(void); + +#ifdef __cplusplus +} +#endif + +#endif //(BLE_APP_SEC) + +#endif // APP_SEC_H_ + +/// @} APP_SEC diff --git a/services/ble_app/app_tota/app_tota_ble.c b/services/ble_app/app_tota/app_tota_ble.c new file mode 100644 index 0000000..69a4f02 --- /dev/null +++ b/services/ble_app/app_tota/app_tota_ble.c @@ -0,0 +1,254 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +/** + **************************************************************************************** + * @addtogroup APP + * @{ + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_TOTA) + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "string.h" +#include "arch.h" // Platform Definitions +#include "co_bt.h" +#include "prf.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "app.h" // Application Definitions +#include "app_task.h" // application task definitions +#include "app_ble_rx_handler.h" +#include "tota_task.h" +#include "app_tota_ble.h" // TOTA Application Definitions +#include "app_tota_data_handler.h" +#include "app_tota_cmd_handler.h" +#include "app_tota.h" + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +struct app_tota_env_tag app_tota_env; + +static app_tota_tx_done_t tota_data_tx_done_callback = NULL; + +/* + * GLOBAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +void app_tota_connected_evt_handler(uint8_t conidx) +{ + TOTA_LOG_DBG(1,"[%s]TOTA",__func__); + app_tota_env.connectionIndex = conidx; + app_tota_update_datapath(APP_TOTA_VIA_NOTIFICATION); + //tota_register_transmitter(app_tota_send_notification); +} + +void app_tota_disconnected_evt_handler(uint8_t conidx) +{ + TOTA_LOG_DBG(3,"[%s], condix = %d Index = %d",__func__, conidx, app_tota_env.connectionIndex); + if (conidx == app_tota_env.connectionIndex) + { + app_tota_env.connectionIndex = BLE_INVALID_CONNECTION_INDEX; + app_tota_env.isNotificationEnabled = false; + app_tota_env.mtu[conidx] = 0; + app_tota_update_datapath(APP_TOTA_PATH_IDLE); + //tota_disconnection_handler(); + } +} + +void app_tota_ble_init(void) +{ + app_tota_env.connectionIndex = BLE_INVALID_CONNECTION_INDEX; + app_tota_env.isNotificationEnabled = false; + memset((uint8_t *)&(app_tota_env.mtu), 0, sizeof(app_tota_env.mtu)); +} + +void app_tota_add_tota(void) +{ + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, TASK_APP, + gapm_profile_task_add_cmd, 0); + + // Fill message + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX>1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE)|PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + + req->prf_task_id = TASK_ID_TOTA; + req->app_task = TASK_APP; + req->start_hdl = 0; + + // Send the message + ke_msg_send(req); +} + +void app_tota_send_notification(uint8_t* ptrData, uint32_t length) +{ + TOTA_LOG_DBG(1,"[%s]TOTA",__func__); + + struct ble_tota_send_data_req_t * req = KE_MSG_ALLOC_DYN(TOTA_SEND_NOTIFICATION, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_TOTA), app_tota_env.connectionIndex), + TASK_APP, + ble_tota_send_data_req_t, + length); + req->connecionIndex = app_tota_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + + ke_msg_send(req); +} + +void app_tota_send_indication(uint8_t* ptrData, uint32_t length) +{ + TOTA_LOG_DBG(1,"[%s]TOTA",__func__); + struct ble_tota_send_data_req_t * req = KE_MSG_ALLOC_DYN(TOTA_SEND_INDICATION, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_TOTA), app_tota_env.connectionIndex), + TASK_APP, + ble_tota_send_data_req_t, + length); + req->connecionIndex = app_tota_env.connectionIndex; + req->length = length; + memcpy(req->value, ptrData, length); + + ke_msg_send(req); +} + +static int app_tota_msg_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Do nothing + TOTA_LOG_DBG(1,"[%s]TOTA",__func__); + return (KE_MSG_CONSUMED); +} + +void tota_update_MTU(uint16_t mtu) +{ + // remove the 3 bytes of overhead + app_tota_env.mtu[app_tota_env.connectionIndex] = mtu; + TRACE(1,"updated data packet size is %d", app_tota_env.mtu[app_tota_env.connectionIndex]); +} + +static int app_tota_ccc_changed_handler(ke_msg_id_t const msgid, + struct ble_tota_tx_notif_config_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + TOTA_LOG_DBG(1,"tota data ccc changed to %d", param->isNotificationEnabled); + app_tota_env.isNotificationEnabled = param->isNotificationEnabled; + + if (app_tota_env.isNotificationEnabled) + { + if (BLE_INVALID_CONNECTION_INDEX == app_tota_env.connectionIndex) + { + uint8_t conidx = KE_IDX_GET(src_id); + app_tota_connected_evt_handler(conidx); + + if (app_tota_env.mtu[conidx]) + { + // tota_update_MTU(app_tota_env.mtu[conidx]); + } + } + } + else + { + app_tota_update_datapath(APP_TOTA_VIA_INDICATION); + } + + + return (KE_MSG_CONSUMED); +} + +static int app_tota_tx_data_sent_handler(ke_msg_id_t const msgid, + struct ble_tota_tx_sent_ind_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if (NULL != tota_data_tx_done_callback) + { + tota_data_tx_done_callback(); + } + + //tota_data_transmission_done_callback(); + + return (KE_MSG_CONSUMED); +} + +static int app_tota_data_received_handler(ke_msg_id_t const msgid, + struct ble_tota_rx_data_ind_t *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + app_ble_push_rx_data(BLE_RX_DATA_SELF_TOTA, app_tota_env.connectionIndex, param->data, param->length); + return (KE_MSG_CONSUMED); +} + +void app_tota_register_tx_done(app_tota_tx_done_t callback) +{ + tota_data_tx_done_callback = callback; +} + +void app_tota_mtu_exchanged_handler(uint8_t conidx, uint16_t MTU) +{ + TOTA_LOG_DBG(1,"[%s]TOTA",__func__); + if (conidx == app_tota_env.connectionIndex) + { + tota_update_MTU(MTU); + } + else + { + app_tota_env.mtu[conidx] = MTU; + } +} + +/* + * LOCAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +const struct ke_msg_handler app_tota_msg_handler_list[] = +{ + // Note: first message is latest message checked by kernel so default is put on top. + {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_tota_msg_handler}, + + {TOTA_CCC_CHANGED, (ke_msg_func_t)app_tota_ccc_changed_handler}, + {TOTA_TX_DATA_SENT, (ke_msg_func_t)app_tota_tx_data_sent_handler}, + {TOTA_DATA_RECEIVED, (ke_msg_func_t)app_tota_data_received_handler}, +}; + +const struct ke_state_handler app_tota_table_handler = + {&app_tota_msg_handler_list[0], (sizeof(app_tota_msg_handler_list)/sizeof(struct ke_msg_handler))}; + +#endif //BLE_APP_TOTA + +/// @} APP diff --git a/services/ble_app/app_tota/app_tota_ble.h b/services/ble_app/app_tota/app_tota_ble.h new file mode 100644 index 0000000..2891cc5 --- /dev/null +++ b/services/ble_app/app_tota/app_tota_ble.h @@ -0,0 +1,118 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef APP_TOTA_H_ +#define APP_TOTA_H_ + +/** + **************************************************************************************** + * @addtogroup APP + * @ingroup RICOW + * + * @brief TOTA Application entry point. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (BLE_APP_TOTA) + +#include // Standard Integer Definition +#include "ke_task.h" + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ +#ifdef __cplusplus +extern "C" { +#endif + +#define TOTA_HIGH_SPEED_BLE_CONNECTION_INTERVAL_MIN_IN_MS 25 +#define TOTA_HIGH_SPEED_BLE_CONNECTION_INTERVAL_MAX_IN_MS 30 +#define TOTA_HIGH_SPEED_BLE_CONNECTION_SUPERVISOR_TIMEOUT_IN_MS 5000 + +#define TOTA_LOW_SPEED_BLE_CONNECTION_INTERVAL_MIN_IN_MS 400 +#define TOTA_LOW_SPEED_BLE_CONNECTION_INTERVAL_MAX_IN_MS 500 +#define TOTA_LOW_SPEED_BLE_CONNECTION_SUPERVISOR_TIMEOUT_IN_MS 5000 + + +extern struct app_env_tag app_env; + +/// health thermometer application environment structure +struct app_tota_env_tag +{ + uint8_t connectionIndex; + uint8_t isNotificationEnabled; + uint16_t mtu[BLE_CONNECTION_MAX]; +}; + +typedef void(*app_tota_tx_done_t)(void); + +/* + * GLOBAL VARIABLES DECLARATIONS + **************************************************************************************** + */ + +/// Health Thermomter Application environment +extern struct app_tota_env_tag app_tota_env; + +/// Table of message handlers +extern const struct ke_state_handler app_tota_table_handler; + +/* + * FUNCTIONS DECLARATION + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialize DataPath Server Application + **************************************************************************************** + */ +void app_tota_ble_init(void); + +void app_tota_add_tota(void); + +void app_tota_connected_evt_handler(uint8_t conidx); + +void app_tota_disconnected_evt_handler(uint8_t conidx); + +void app_tota_send_notification(uint8_t* ptrData, uint32_t length); + +void app_tota_send_indication(uint8_t* ptrData, uint32_t length); + +void app_tota_register_tx_done(app_tota_tx_done_t callback); + +void app_tota_mtu_exchanged_handler(uint8_t conidx, uint16_t MTU); + +#ifdef __cplusplus + } +#endif + + +#endif //(BLE_APP_TOTA) + +/// @} APP + +#endif // APP_TOTA_H_ \ No newline at end of file diff --git a/services/ble_app/app_vob/voice_over_ble.c b/services/ble_app/app_vob/voice_over_ble.c new file mode 100644 index 0000000..81d8cfb --- /dev/null +++ b/services/ble_app/app_vob/voice_over_ble.c @@ -0,0 +1,1230 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if __VOICE_OVER_BLE_ENABLED__ + +#include "string.h" +#include "cmsis_os.h" +#include "hal_trace.h" +#include "hal_iomux.h" +#include "app_thread.h" +#include "app_utils.h" +#include "Pcm8k_Cvsd.h" +#include "app_audio.h" +#include "apps.h" +#include "app.h" +#include "audioflinger.h" +#include "voice_over_ble.h" +#include "app_ble_cmd_handler.h" +#include "app_ble_custom_cmd.h" +#include "app_datapath_server.h" + + +/** + * @brief The states of the VOB state machine + * + */ +typedef enum +{ + VOB_STATE_IDLE = 0, + VOB_STATE_ADVERTISING, + VOB_STATE_STOPPING_ADV, + VOB_STATE_ADV_STOPPED, + VOB_STATE_CONNECTING, + VOB_STATE_STOPPING_CONNECTING, + VOB_STATE_CONNECTED, + VOB_STATE_DISCONNECTED, + VOB_STATE_VOICE_STREAM, +} VOB_STATE_E; + +/** + * @brief Buffer management of the VOB + * + */ +typedef struct +{ + /**< for SRC: the encoder will encode the PCM data into the audio data and fill them into encodedDataBuf + for DST: the received encoded data will be pushed into encodedDataBuf pending for decoding and playing */ + uint32_t encodedDataIndexToFill; + + /**< for SRC: the BLE will fetch data at this index from the encodedDataBuf and send them + for DST: the player will fetch data at this index from the encodedDataBuf, decode them and play */ + uint32_t encodedDataIndexToFetch; + + uint32_t encodedDataLength; + + uint8_t isCachingDone; + +} VOB_DATA_BUF_MANAGEMENT_T; + +/** + * @brief Format of the audio encoder function + * + * @param pcmDataPtr Pointer of the input PCM data to be encoded + * @param pcmDataLen Length of the input PCM data to be encoded + * @param encodedDataPtr Pointer of the output encoded data + * @param encodedDataLen Length of the output encoded data + * + */ +typedef void (*PCM_Encoder_Handler_t)(uint8_t* pcmDataPtr, uint32_t pcmDataLen, encodedDataPtr, encodedDataLen); + + +/**< configure the voice settings */ +#define VOB_VOICE_BIT_NUMBER (AUD_BITS_16) +#define VOB_VOICE_SAMPLE_RATE (AUD_SAMPRATE_8000) +#define VOB_VOICE_VOLUME (10) + +/**< signal of the VOB application thread */ +#define VOB_SIGNAL_GET_RESPONSE 0x80 + +/**< signal of the BLE thread */ +#define BLE_SIGNAL_VOB_GET_ENCODED_AUDIO_DATA 0x01 +#define BLE_SIGNAL_VOB_DATA_SENT_OUT 0x02 +#define BLE_SIGNAL_VOB_RECEIVED_DATA 0x04 +#define BLE_SIGNAL_VOB_CONNECTED 0x08 +#define BLE_SIGNAL_VOB_DISCONNECTED 0x10 + + +/**< for SRC, the buffer is used to save the collected PCM data via the MIC + for DST, the buffer is used to save the decoded PCM data pending for playing back*/ +#define VOB_VOICE_PCM_DATA_CHUNK_SIZE (2048) +#define VOB_VOICE_PCM_DATA_CHUNK_COUNT (8) +#define VOB_VOICE_PCM_DATA_STORAGE_BUF_SIZE (VOB_VOICE_PCM_DATA_CHUNK_SIZE*VOB_VOICE_PCM_DATA_CHUNK_SIZE) + +#define VOB_ENCODED_DATA_CACHE_SIZE (2048) + +/**< for SRC, the buffer is used to save the encoded audio data, + for DST, the buffer is used to save the received encoded audio data via the BLE*/ +#define VOB_ENCODED_DATA_STORAGE_BUF_SIZE (2048*2) + +/**< timeout in ms of waiting for the response */ +#define VOB_WAITING_RESPONSE_TIMEOUT_IN_MS (5000) + +/**< connection parameter */ +#define VOB_CONNECTION_INTERVAL_IN_MS 5 +#define VOB_CONNECTION_SUPERVISION_TIMEOUT_IN_MS 5000 + +/**< depends on the compression ratio of the codec algrithm */ +/**< now the cvsd is used, so the ratio is 50% */ +#define VOB_PCM_SIZE_TO_AUDIO_SIZE(size) ((size)/2) +#define VOB_AUDIO_SIZE_TO_PCM_SIZE(size) ((size)*2) + + +static osThreadId ble_app_tid; +static void ble_app_thread(void const *argument); +osThreadDef(ble_app_thread, osPriorityNormal, 1, 512, "ble_app"); + +/**< connecting supervisor timer, if timeout happened, the connecting try will be stopped */ +#define VOB_CONNECTING_TIMEOUT_IN_MS (10*1000) +static void connecting_supervisor_timer_cb(void const *n); +osTimerDef (APP_VOB_CONNECTING_SUPERVISOR_TIMER, connecting_supervisor_timer_cb); +static osTimerId vob_connecting_supervisor_timer; + +/**< state machine of the VOB */ +static VOB_STATE_E vob_state; + +static VOB_ROLE_E vob_role; + +/**< SRC mic stream environment */ +AUDIO_STREAM_ENV_T src_mic_stream_env; + +/**< DST speaker stream environment */ +AUDIO_STREAM_ENV_T dst_speaker_stream_env; + +VOB_DATA_BUF_MANAGEMENT_T vob_data_management; + +/**< mutex of the voice over ble data buffer environment */ +osMutexId vob_env_mutex_id; +osMutexDef(vob_env_mutex); + + +#define STREAM_A2DP_SPEAKER 0 + + +#define STREAM_A2DP_PCM_DATA_BUF_SIZE 1024 +#define STREAM_A2DP_ENCODED_DATA_BUF_SIZE 1024 +static const VOB_FUNCTIONALITY_CONFIG_T vob_func_config[] = +{ + { + STREAM_A2DP_PCM_DATA_BUF_SIZE, + STREAM_A2DP_ENCODED_DATA_BUF_SIZE + + }, +}; + +static VOB_DATA_BUF_MANAGEMENT_T stream_a2dp_data_management; + +#define STREAM_DATA_PROCESSING_UNIT_IN_BYTES 1024 + +struct gap_bdaddr DST_BLE_BdAddr = {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}, 0}; + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + +#define RESAMPLE_ITER_LEN (128 * 2 * 2) + +static struct APP_RESAMPLE_T *ble_resample; + +static int ble_resample_iter(uint8_t *buf, uint32_t len) +{ + uint32_t acquiredPCMDataLength = decode_sbc_frame(buf, len); + + if (acquiredPCMDataLength < len) + { + TRACE(0,"Start encoded data caching again."); + stream_a2dp_data_management.isCachingDone = false; + return 1; + } + return 0; +} + +#endif + +uint32_t a2dp_audio_prepare_pcm_data(uint8_t *buf, uint32_t len) +{ + if (stream_a2dp_data_management.isCachingDone) + { + // the caching stage has been done, decode the encoded data and feed the PCM +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + if (allow_resample) + { + app_playback_resample_run(ble_resample, buf, len); + } + else +#endif + { + uint32_t acquiredPCMDataLength = decode_sbc_frame(buf, len); + // the queued encoded data does't meet the PCM data requirement, + // need to cache again + if (acquiredPCMDataLength < len) + { + TRACE(2,"Need %d PCM data, but the queue encoded data can only provide %d bytes", + len, acquiredPCMDataLength); + + memset(buf+acquiredPCMDataLength, 0, len-acquiredPCMDataLength); + + TRACE(0,"Start encoded data caching again."); + stream_a2dp_data_management.isCachingDone = false; + } + } + } + else + { + memset(buf, 0, len); + } + + return len; +} + +static uint32_t stream_a2dp_speaker_more_pcm_data(uint8_t* buf, uint32_t len) +{ +#ifdef BT_XTAL_SYNC +#ifndef __TWS__ + bt_xtal_sync(BT_XTAL_SYNC_MODE_MUSIC); +#endif // #ifndef __TWS__ +#endif // #ifdef BT_XTAL_SYNC + +#ifdef __TWS__ + tws_audout_pcm_more_data(buf, len); +#else // __TWS__ + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + app_playback_resample_run(ble_resample, buf, len); +#else + a2dp_audio_more_data(buf, len); +#endif + + app_ring_merge_more_data(buf, len); + +#ifdef __AUDIO_OUTPUT_MONO_MODE__ + merge_stereo_to_mono_16bits((int16_t *)buf, (int16_t *)buf, len/2); +#endif // #ifdef __AUDIO_OUTPUT_MONO_MODE__ + +#endif // #ifdef __TWS__ + +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || defined(__AUDIO_DRC__) + // app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_104M); + + audio_process_run(buf, len); + + // app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_52M); +#endif // #if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || defined(__AUDIO_DRC__) + + return len; +} + +int encoded_data_received(unsigned char *buf, unsigned int len) +{ + int32_t ret, size; + LOCK_APP_AUDIO_QUEUE(); + + // push the encoded data into the queue + ret = APP_AUDIO_EnCQueueByForce(&sbc_queue, buf, len); + size = APP_AUDIO_LengthOfCQueue(&sbc_queue); + UNLOCK_APP_AUDIO_QUEUE(); + + // the queue is full, overwrite the oldest data + if (CQ_ERR == ret) + { + TRACE(0,"Encoded data cache is overflow."); + } + + if ((!(stream_a2dp_data_management.isCachingDone)) && + (size >= stream_a2dp_data_management.initialCachedEncodedDataSize)) + { + // the cached encoded data is ready, time to start decoding and feeding to the codec + stream_a2dp_data_management.isCachingDone = true; + } + + return 0; +} + + +/** + * @brief Start the A2DP speaker output stream + * + */ +void kick_off_a2dp_speaker_stream(void) +{ + // clean up the data management structure + memset((uint8_t *)&stream_a2dp_data_management, 0, sizeof(stream_a2dp_data_management)); + + // prepare the buffer + app_audio_mempool_init(); + + app_audio_mempool_get_buff(&(stream_a2dp_data_management.pcmDataBuf), + vob_func_config[STREAM_A2DP_SPEAKER].pcmDataBufSize); + app_audio_mempool_get_buff(&(stream_a2dp_data_management.encodedDataBuf), + vob_func_config[STREAM_A2DP_SPEAKER].encodedDataBufSize); + + + // acuqire the sufficient system clock + app_sysfreq_req(APP_SYSFREQ_VOICE_OVER_BLE, APP_SYSFREQ_52M); + + // create the audio flinger stream + struct AF_STREAM_CONFIG_T stream_cfg; + + stream_cfg.bits = stream_a2dp_data_management.pcmBitNumber; + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; + stream_cfg.sample_rate = stream_a2dp_data_management.pcmSampleRate; + stream_cfg.vol = VOB_VOICE_VOLUME; + + stream_cfg.device = AUD_STREAM_USE_OPTIMIZED_STREAM; + + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.handler = vob_func_config[STREAM_A2DP_SPEAKER].dataCallback; + + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(vob_data_management.pcmDataBufSize); + + stream_cfg.data_size = STREAM_DATA_PROCESSING_UNIT_IN_BYTES; + stream_cfg.data_chunk_count = 2; + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); +} + + +static osThreadId vob_ThreadId; + +/**< The negotiated MTU size between SRC and DST */ +static uint16_t negotiatedMTUSize; + +/** + * @brief API to send data via BLE + * + * @param ptrBuf Pointer of the data to send + * @param length Length of the data in bytes + * + * @return ture if the data is successfully sent out. + */ +bool ble_send_data(uint8_t* ptrBuf, uint32_t length) +{ + app_datapath_server_send_data(ptrBuf, length); + return true; +} + +/** + * @brief API to receive data via BLE + * + * @param ptrBuf Pointer of the data to send + * @param length Length of the data in bytes + * + * @return ture if the data is successfully sent out. + */ +bool ble_receive_data(uint8_t* ptrBuf, uint32_t length) +{ + +} + +/** + * @brief Stop the MIC voice input stream + * + */ +void vob_stop_mic_input_stream(void) +{ + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + + // release the acquired system clock + app_sysfreq_req(APP_SYSFREQ_VOICE_OVER_BLE, APP_SYSFREQ_32K); +} + +/** + * @brief Stop the speaker output stream + * + */ +void vob_stop_speaker_output_stream(void) +{ + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + + // release the acquired system clock + app_sysfreq_req(APP_SYSFREQ_VOICE_OVER_BLE, APP_SYSFREQ_32K); +} + +/** + * @brief Stop the voice stream + * + */ +static void vob_stop_voice_stream(void) +{ + if (VOB_ROLE_SRC == vob_role) + { + // stop the MIC voice input stream + vob_stop_mic_input_stream(); + } + else + { + // stop the speaker output stream + vob_stop_speaker_output_stream(); + } + + VOB_CMD_RSP_T cmd; + + // send start voice stream command to the DST + cmd.magicCode = VOB_MAGICCODE_OF_CMD_RSP; + cmd.cmdRspCode = VOB_CMD_STOP_VOICE_STREAM; + + bool ret = ble_send_data((uint8_t *)&cmd, &(((VOB_CMD_RSP_T *)0)->lengthOfParm)) + ASSERT_SIMPLIFIED(ret); + + // waiting until it recieves the response from the other side or timeout happens + osEvent event = osSignalWait(VOB_SIGNAL_GET_RESPONSE, VOB_WAITING_RESPONSE_TIMEOUT_IN_MS); + if (osEventSignal != event.status) + { + TRACE(0,"Time-out happens when waiting the response of stopping voice stream from DST."); + } + + // reset the state anyway + vob_state = VOB_STATE_CONNECTED; +} + +/** + * @brief Handler when receiving the stop the voice stream command + * + */ +static void vob_receiving_stop_voice_stream_handler(void) +{ + if (VOB_ROLE_SRC == vob_role) + { + // stop the MIC voice input stream + vob_stop_mic_input_stream(); + } + else + { + // stop the speaker output stream + vob_stop_speaker_output_stream(); + } + + VOB_CMD_RSP_T cmd; + + // send start voice stream command to the DST + + cmd.magicCode = VOB_MAGICCODE_OF_CMD_RSP; + cmd.cmdRspCode = VOB_RSP_READY_TO_STOP_VOICE_STREAM; + + bool ret = ble_send_data((uint8_t *)&cmd, &(((VOB_CMD_RSP_T *)0)->lengthOfParm)) + ASSERT_SIMPLIFIED(ret); + + // reset the state anyway + vob_state = VOB_STATE_CONNECTED; +} + + +/** + * @brief Start advertising + * + */ +static void vob_start_advertising(void) +{ + // start advertising + appm_start_advertising(); + + vob_state = VOB_STATE_ADVERTISING; +} + +/** + * @brief Process the recevied audio data from BLE, encode them and feed them to the speaker + * + * @param ptrBuf Pointer of the PCM data buffer to feed. + * @param length Length of the asked PCM data. + * + * @return uint32_t 0 means no error happens + */ +static uint32_t vob_need_more_voice_data(uint8_t* ptrBuf, uint32_t length) +{ + if (vob_data_management.isCachingDone) + { + // caching has been done, can decoded the received encoded data to PCM and feed them to the buffer + uint32_t remainingPCMBytesToFeed = length; + uint32_t pcmBytesToDecode; + do + { + pcmBytesToDecode = (remainingPCMBytesToFeed > (2*MAXNUMOFSAMPLES*src_mic_stream_env.bitNumber/AUD_BITS_8))?\ + (2*MAXNUMOFSAMPLES*src_mic_stream_env.bitNumber/AUD_BITS_8):remainingPCMBytesToFeed; + + // cvsd's compression ratio is 50% + if ((VOB_PCM_SIZE_TO_AUDIO_SIZE(pcmBytesToDecode) + vob_data_management.encodedDataIndexToFetch) > + src_mic_stream_env.encodedDataBufSize) + { + pcmBytesToDecode = VOB_AUDIO_SIZE_TO_PCM_SIZE(src_mic_stream_env.encodedDataBufSize - + vob_data_management.encodedDataIndexToFetch); + } + + // decode to generate the PCM data + CvsdToPcm8k(vob_data_management.encodedDataBuf + vob_data_management.encodedDataIndexToFetch, (short *)ptrBuf, + pcmBytesToDecode / sizeof(short)); + + // update the index + ptrBuf += pcmBytesToDecode; + remainingPCMBytesToFeed -= pcmBytesToDecode; + + vob_data_management.encodedDataIndexToFetch += VOB_PCM_SIZE_TO_AUDIO_SIZE(pcmBytesToDecode); + + if (src_mic_stream_env.encodedDataBufSize == vob_data_management.encodedDataIndexToFetch) + { + vob_data_management.encodedDataIndexToFetch = 0; + } + + } while (remainingPCMBytesToFeed > 0); + + osMutexWait(vob_env_mutex_id, osWaitForever); + + // update the bytes to decode and feed to codec + vob_data_management.encodedDataLength -= VOB_PCM_SIZE_TO_AUDIO_SIZE(length); + + osMutexRelease(vob_env_mutex_id); + } + else + { + // caching is not done yet, just fill all ZERO + memset(ptrBuf, 0, length); + } + + return len; +} + +/** + * @brief Start the speaker output stream + * + */ +void vob_kick_off_speaker_output_stream(void) +{ + // prepare the memory buffer + app_audio_mempool_init(); + // PCM data buffer + app_audio_mempool_get_buff(&(dst_speaker_stream_env.pcmDataBuf), + src_mic_stream_env.pcmDataChunkCount*dst_speaker_stream_env.pcmDataChunkSize); + + // encoded data buffer + app_audio_mempool_get_buff(&(dst_speaker_stream_env.encodedDataBuf), + dst_speaker_stream_env.encodedDataBufSize); + + // encoded data queue + APP_AUDIO_InitCQueue(&(dst_speaker_stream_env.queue), dst_speaker_stream_env.encodedDataBufSize, + dst_speaker_stream_env.encodedDataBuf); + + // acuqire the sufficient system clock + app_sysfreq_req(APP_SYSFREQ_VOICE_OVER_BLE, APP_SYSFREQ_26M); + + // create the audio flinger stream + struct AF_STREAM_CONFIG_T stream_cfg; + + stream_cfg.bits = dst_speaker_stream_env.bitNumber; + stream_cfg.sample_rate = dst_speaker_stream_env.sampleRate; + stream_cfg.channel_num = dst_speaker_stream_env.channelCount; + stream_cfg.vol = VOB_VOICE_VOLUME; + + stream_cfg.device = AUD_STREAM_USE_OPTIMIZED_STREAM; + + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.handler = dst_speaker_stream_env.morePcmHandler; + + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(dst_speaker_stream_env.pcmDataBuf); + stream_cfg.data_size = dst_speaker_stream_env.pcmDataChunkSize; + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); +} + +/** + * @brief Send the encoded audio data to DST via BLE + * + */ +static void vob_send_encoded_audio_data(void) +{ + uint32_t dataBytesToSend = 0; + uint32_t offsetInEncodedDatabuf = vob_data_management.indexToFetch; + + osMutexWait(vob_env_mutex_id, osWaitForever); + + if (vob_data_management.encodedDataLength > 0) + { + if (vob_data_management.encodedDataLength > negotiatedMTUSize) + { + dataBytesToSend = negotiatedMTUSize; + } + else + { + dataBytesToSend = vob_data_management.encodedDataLength; + } + + if ((vob_data_management.indexToFetch + dataBytesToSend) > src_mic_stream_env.encodedDataBufSize) + { + dataBytesToSend = src_mic_stream_env.encodedDataBufSize - vob_data_management.indexToFetch; + } + + // update the index + vob_data_management.encodedDataLength += dataBytesToSend; + if (src_mic_stream_env.encodedDataBufSize == (vob_data_management.indexToFetch + dataBytesToSend)) + { + vob_data_management.indexToFetch = 0; + } + else + { + vob_data_management.indexToFetch += dataBytesToSend; + } + } + + osMutexRelease(vob_env_mutex_id); + + if (dataBytesToSend > 0) + { + // send out the data via the BLE + ble_send_data((vob_data_management.encodedDataBuf + offsetInEncodedDatabuf), + dataBytesToSend); + } +} + +/** + * @brief Hanlder of the BLE data sent out event + * + */ +void vob_data_sent_out_handler(void) +{ + vob_send_encoded_audio_data(); +} + +/** + * @brief Hanlder of the response to start VOB voice stream command, called on the SRC side + * + */ +void vob_start_voice_stream_rsp_handler(BLE_CUSTOM_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen) +{ + + if (NO_ERROR == retStatus) + { + TRACE(0,"voice stream is successfully started!" + + // kick off the voice input stream from MIC + vob_kick_off_mic_input_stream(); + + // update the state + vob_state = VOB_STATE_VOICE_STREAM; + } + else + { + TRACE(0,"starting voice stream failed!" + } +} + +void vob_audio_data_reiceived_handler(uint8_t* ptrBuf, uint32_t length) +{ + // only for DST, receive the encoded audio data + if (VOB_ROLE_DST == vob_role) + { + // push into the encoded data buffer + ASSERT((vob_data_management.encodedDataLength + length) <= dst_speaker_stream_env.encodedDataBufSize, + "The left voice over ble buffer space is not suitable for the coming audio data."); + + uint32_t bytesToTheEnd = dst_speaker_stream_env.encodedDataBufSize - + vob_data_management.encodedDataIndexToFill; + if (length > bytesToTheEnd) + { + memcpy((dst_speaker_stream_env.encodedDataBuf + vob_data_management.encodedDataIndexToFill), + ptrBuf, length); + } + else + { + memcpy((dst_speaker_stream_env.encodedDataBuf + vob_data_management.encodedDataIndexToFill), + ptrBuf, bytesToTheEnd); + memcpy(dst_speaker_stream_env.encodedDataBuf, ptrBuf + bytesToTheEnd, length - bytesToTheEnd); + } + + osMutexWait(vob_env_mutex_id, osWaitForever); + + // update the bytes to transmit via BLE + vob_data_management.encodedDataLength += length; + + osMutexRelease(vob_env_mutex_id); + + if ((!vob_data_management.isCachingDone) && + (vob_data_management.encodedDataLength >= src_mic_stream_env.cachedEncodedDataSize)) + { + vob_data_management.isCachingDone = true; + } + } +} + +/** + * @brief Hanlder of the start VOB voice stream command, called on the DST side + * + */ +void vob_start_voice_stream_cmd_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + BLE_CUSTOM_CMD_RET_STATUS_E retStatus = NO_ERROR; + + if (VOB_STATE_CONNECTED == vob_state) + { + // update the state + vob_state = VOB_STATE_VOICE_STREAM; + + // start raw data xfer + BLE_control_raw_data_xfer(true); + + // configure raw data handler + BLE_set_raw_data_xfer_received_callback(vob_audio_data_reiceived_handler); + + // kick off the speaker stream + vob_kick_off_speaker_output_stream(); + } + else + { + retStatus = HANDLING_FAILED; + } + + BLE_send_response_to_command(funcCode, retStatus, NULL, TRANSMISSION_VIA_WRITE_CMD); +} + +/** + * @brief Hanlder of the response to stop VOB voice stream command, called on the SRC side + * + */ +void vob_stop_voice_stream_rsp_handler(BLE_CUSTOM_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen) +{ + // stop the MIC voice input stream + vob_stop_mic_input_stream(); + + vob_state = VOB_STATE_CONNECTED; +} + +/** + * @brief Hanlder of the stop VOB voice stream command, called on the DST side + * + */ +void vob_stop_voice_stream_cmd_handler(uint32_t funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + BLE_CUSTOM_CMD_RET_STATUS_E retStatus = NO_ERROR; + + if (VOB_STATE_VOICE_STREAM == vob_state) + { + // update the state + vob_state = VOB_STATE_CONNECTED; + + // stop raw data xfer + BLE_control_raw_data_xfer(false); + + // stop the speaker output stream + vob_stop_speaker_output_stream(); + } + else + { + retStatus = HANDLING_FAILED; + } + + BLE_send_response_to_command(funcCode, retStatus, NULL, TRANSMISSION_VIA_WRITE_CMD); +} + +static void vob_encoded_data_sent_done(void) +{ + if ((VOB_STATE_VOICE_STREAM == vob_state) && + (vob_data_management.encodedDataLength > 0)) + { + // inform the ble application thread to continue sending the encoded data if any in the buffer + osSignalSet(ble_app_tid, BLE_SIGNAL_VOB_DATA_SENT_OUT); + } +} + +/** + * @brief Hanlder of the BLE connected event + * + */ +void vob_connected_evt_handler(void) +{ + if (VOB_ROLE_SRC == vob_role) + { + l2cap_update_param(VOB_CONNECTION_INTERVAL_IN_MS, + VOB_CONNECTION_INTERVAL_IN_MS, VOB_CONNECTION_SUPERVISION_TIMEOUT_IN_MS); + + vob_data_management.encodedDataIndexToFetch = 0; + vob_data_management.encodedDataIndexToFill = 0; + vob_data_management.encodedDataLength = 0; + + // register the BLE tx done callback function + app_datapath_server_register_tx_done(vob_encoded_data_sent_done); + + // delete the timer + osTimerDelete(vob_connecting_supervisor_timer); + } + + vob_data_management.isCachingDone = false; + + // play the connected sound + app_voice_report(APP_STATUS_INDICATION_CONNECTED, 0); + + // update the state + vob_state = VOB_STATE_CONNECTED; +} + +/** + * @brief Hanlder of the BLE disconnected event + * + */ +void vob_disconnected_evt_handler(void) +{ + ASSERT_SIMPLIFIED((VOB_STATE_VOICE_STREAM == vob_state) || (VOB_STATE_CONNECTED == vob_state)); + + vob_state = VOB_STATE_DISCONNECTED; + + // stop raw data xfer + BLE_control_raw_data_xfer(false); + + // play the disconnected sound + app_voice_report(APP_STATUS_INDICATION_DISCONNECTED, 0); + + // stop the voice stream if it's in progress + if (VOB_STATE_VOICE_STREAM == vob_state) + { + if (VOB_ROLE_SRC == vob_role) + { + vob_stop_mic_input_stream(); + } + else + { + vob_stop_speaker_output_stream(); + } + } + + if (VOB_ROLE_SRC == vob_role) + { + // try to re-connect + vob_start_connecting(); + } + else + { + // re-start advertising + vob_start_advertising(); + } +} + +/** + * @brief BLE application thread handler + * + * @param argument Parameter imported during the thread creation. + * + */ +static void ble_app_thread(void const *argument) +{ + while(1) + { + osEvent evt; + // wait any signal + evt = osSignalWait(0x0, osWaitForever); + + // get role from signal value + if (evt.status == osEventSignal) + { + if (evt.value.signals & BLE_SIGNAL_VOB_GET_ENCODED_AUDIO_DATA) + { + vob_send_encoded_audio_data(); + break; + } + else if (evt.value.signals & BLE_SIGNAL_VOB_DATA_SENT_OUT) + { + vob_data_sent_out_handler(); + break; + } + else if (evt.value.signals & BLE_SIGNAL_VOB_RECEIVED_DATA) + { + vob_data_reiceived_handler(); + break; + } + else if (evt.value.signals & BLE_SIGNAL_VOB_CONNECTED) + { + vob_connected_evt_handler(); + break; + } + else if (evt.value.signals & BLE_SIGNAL_VOB_DISCONNECTED) + { + vob_disconnected_evt_handler(); + break; + } + } + } +} + +/** + * @brief The role of the voice over BLE + * + * @return 0 if successful, -1 if failed + * + */ +int ble_app_init(void) +{ + ble_app_tid = osThreadCreate(osThread(ble_app_thread), NULL); + if (ble_app_tid == NULL) { + TRACE(0,"Failed to Create ble_app_thread\n"); + return 0; + } + return 0; +} + +/** + * @brief Call back function of the connecting supervisor timer + * + * @param n Parameter imported during the timer creation osTimerCreate. + * + */ +static void connecting_supervisor_timer_cb(void const *n) +{ + if (VOB_STATE_CONNECTING == vob_state) + { + // time-out happens at the time of connecting. + // it means the slave is not present or cannot be connected, so just stop connecting + appm_stop_connecting(); + + vob_state = VOB_STATE_STOPPING_CONNECTING; + } + + osTimerDelete(vob_connecting_supervisor_timer); +} + +/** + * @brief Start connecting to DST + * this can happen for two cases: + * 1. Key press to start connecting + * 2. Re-connecting when disconnection happened + * + */ +void vob_start_connecting(void) +{ + // play the connecting sound + app_voice_report(APP_STATUS_INDICATION_CONNECTING, 0); + + // start connecting + appm_start_connecting(&DST_BLE_BdAddr); + + // create and start a timer to supervise the connecting procedure + vob_connecting_supervisor_timer = + osTimerCreate(osTimer(APP_VOB_CONNECTING_SUPERVISOR_TIMER), osTimerOnce, NULL); + + osTimerStart(vob_connecting_supervisor_timer, VOB_CONNECTING_TIMEOUT_IN_MS); + + vob_state = VOB_STATE_CONNECTING; +} + +/** + * @brief Process the collected PCM data from MIC + * + * @param ptrBuf Pointer of the PCM data buffer to access. + * @param length Length of the PCM data in the buffer in bytes. + * + * @return uint32_t 0 means no error happens + */ +static uint32_t vob_voice_data_come(uint8_t* ptrBuf, uint32_t length) +{ + // encode the voice PCM data into cvsd + uint32_t remainingBytesToEncode = length; + uint32_t pcmBytesToEncode; + do + { + pcmBytesToEncode = (remainingBytesToEncode > (MAXNUMOFSAMPLES*src_mic_stream_env.bitNumber/AUD_BITS_8))?\ + (MAXNUMOFSAMPLES*src_mic_stream_env.bitNumber/AUD_BITS_8):remainingBytesToEncode; + + // cvsd's compression ratio is 50% + if ((VOB_PCM_SIZE_TO_AUDIO_SIZE(pcmBytesToEncode) + vob_data_management.encodedDataIndexToFill) > + src_mic_stream_env.encodedDataBufSize) + { + pcmBytesToEncode = VOB_AUDIO_SIZE_TO_PCM_SIZE(src_mic_stream_env.encodedDataBufSize - + vob_data_management.encodedDataIndexToFill); + } + + // encode the PCM data + Pcm8kToCvsd((short *)ptrBuf, vob_data_management.encodedDataBuf + vob_data_management.encodedDataIndexToFill, + pcmBytesToEncode / sizeof(short)); + + // update the index + ptrBuf += pcmBytesToEncode; + remainingBytesToEncode -= pcmBytesToEncode; + + vob_data_management.encodedDataIndexToFill += VOB_PCM_SIZE_TO_AUDIO_SIZE(pcmBytesToEncode); + + if (src_mic_stream_env.encodedDataBufSize == vob_data_management.encodedDataIndexToFill) + { + vob_data_management.encodedDataIndexToFill = 0; + } + + } while (remainingBytesToEncode > 0); + + osMutexWait(vob_env_mutex_id, osWaitForever); + + // update the bytes to transmit via BLE + vob_data_management.encodedDataLength += VOB_PCM_SIZE_TO_AUDIO_SIZE(length); + + osMutexRelease(vob_env_mutex_id); + + if ((!vob_data_management.isCachingDone) && + (vob_data_management.encodedDataLength >= src_mic_stream_env.cachedEncodedDataSize)) + { + vob_data_management.isCachingDone = true; + + // inform the ble application thread to send out the encoded data + osSignalSet(ble_app_tid, BLE_SIGNAL_VOB_GET_ENCODED_AUDIO_DATA) + } + return 0; +} + +/** + * @brief Init the MIC and Speaker audio streams + * + */ +static void vob_init_audio_streams(void) +{ + src_mic_stream_env.bitNumber = VOB_VOICE_BIT_NUMBER; + src_mic_stream_env.sampleRate = VOB_VOICE_SAMPLE_RATE; + src_mic_stream_env.channelCount = AUD_CHANNEL_NUM_1; + src_mic_stream_env.morePcmHandler = vob_voice_data_come; + src_mic_stream_env.pcmDataChunkCount = VOB_VOICE_PCM_DATA_CHUNK_COUNT; + src_mic_stream_env.pcmDataChunkSize = VOB_VOICE_PCM_DATA_CHUNK_SIZE; + src_mic_stream_env.cachedEncodedDataSize = VOB_ENCODED_DATA_CACHE_SIZE; + src_mic_stream_env.encodedDataBufSize = VOB_ENCODED_DATA_STORAGE_BUF_SIZE; + + dst_speaker_stream_env.bitNumber = VOB_VOICE_BIT_NUMBER; + dst_speaker_stream_env.sampleRate = VOB_VOICE_SAMPLE_RATE; + dst_speaker_stream_env.channelCount = AUD_CHANNEL_NUM_2; + dst_speaker_stream_env.morePcmHandler = vob_need_more_voice_data; + dst_speaker_stream_env.pcmDataChunkCount = VOB_VOICE_PCM_DATA_CHUNK_COUNT; + dst_speaker_stream_env.pcmDataChunkSize = VOB_VOICE_PCM_DATA_CHUNK_SIZE; + dst_speaker_stream_env.cachedEncodedDataSize = VOB_ENCODED_DATA_CACHE_SIZE; + dst_speaker_stream_env.encodedDataBufSize = VOB_ENCODED_DATA_STORAGE_BUF_SIZE; +} + +/** + * @brief Start the voice input stream from the MIC + * + */ +void vob_kick_off_mic_input_stream(void) +{ + // prepare the memory buffer + app_audio_mempool_init(); + // PCM data buffer + app_audio_mempool_get_buff(&(src_mic_stream_env.pcmDataBuf), + src_mic_stream_env.pcmDataChunkCount*src_mic_stream_env.pcmDataChunkSize); + + // encoded data buffer + app_audio_mempool_get_buff(&(src_mic_stream_env.encodedDataBuf), + src_mic_stream_env.encodedDataBufSize); + + // encoded data queue + APP_AUDIO_InitCQueue(&(src_mic_stream_env.queue), src_mic_stream_env.encodedDataBufSize, + src_mic_stream_env.encodedDataBuf); + + // acuqire the sufficient system clock + app_sysfreq_req(APP_SYSFREQ_VOICE_OVER_BLE, APP_SYSFREQ_26M); + + // create the audio flinger stream + struct AF_STREAM_CONFIG_T stream_cfg; + + stream_cfg.bits = src_mic_stream_env.bitNumber; + stream_cfg.sample_rate = src_mic_stream_env.sampleRate; + stream_cfg.channel_num = src_mic_stream_env.channelCount; + stream_cfg.vol = VOB_VOICE_VOLUME; + + stream_cfg.device = AUD_STREAM_USE_OPTIMIZED_STREAM; + + stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; + stream_cfg.handler = src_mic_stream_env.morePcmHandler; + + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(src_mic_stream_env.pcmDataBuf); + stream_cfg.data_size = src_mic_stream_env.pcmDataChunkSize; + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); +} + +/** + * @brief Start the voice stream, this can only be triggered by SRC + * + */ +static void vob_start_voice_stream(void) +{ + BLE_send_custom_command(OP_VOB_CMD_START_VOICE_STREAM, NULL, 0); +} + +/** + * @brief Callback function called when the BLE activity(adv/connecting/scanning is stopped) + * + */ +static void vob_ble_activity_stopped(void) +{ + if (VOB_STATE_STOPPING_ADV == vob_state) + { + vob_state = VOB_STATE_ADV_STOPPED; + + // should switch to connecting state + vob_switch_state_handler(); + } + else if (VOB_STATE_STOPPING_CONNECTING == vob_state) + { + // start advertising + vob_start_advertising(); + } +} + +/** + * @brief The handler of switching VOB state + * + */ +void vob_switch_state_handler(void) +{ + switch (vob_state) + { + case VOB_STATE_ADV_STOPPED: + { + if (VOB_ROLE_SRC == vob_role) + { + // start connecting + vob_start_connecting(); + } + break; + } + case VOB_STATE_CONNECTED: + { + // start voice stream + vob_start_voice_stream(); + break; + } + case VOB_STATE_VOICE_STREAM: + { + // stop voice stream + vob_stop_voice_stream(); + break; + } + } +} + +/** + * @brief Process the message sent to the VOB application thread + * + */ +static int voice_over_ble_handler(APP_MESSAGE_BODY *msg_body) +{ + switch (msg_body->message_id) + { + case VOB_START_AS_SRC: + // change role + vob_role = VOB_ROLE_SRC; + // stop advertising, and start connecting when adv is stopped + appm_stop_advertising(); + // change state + vob_state = VOB_STATE_STOPPING_ADV; + break; + case VOB_SWITCH_STATE: + vob_switch_state_handler(); + break; + default: + break; + } + return 0; +} + +/** + * @brief Notify VOB that it should switch to the next state: + * VOB_IDLE -> VOB_CONNECTED -> VOB_VOICE_STREAM -> VOB_CONNECTED + * + * @param ptrParam Pointer of the parameter + * @param paramLen Length of the parameter in bytes + * + */ +void notify_vob(VOB_MESSAGE_ID_E message, uint8_t* ptrParam, uint32_t paramLen) +{ + APP_MESSAGE_BLOCK msg; + + msg.mod_id = APP_MODUAL_VOB; + + msg.msg_body.message_id = message; + + /**< reserved for future usage */ + // ASSERT(paramLen <= 8, "The parameter length %d exceeds the maximum supported length 8!", paramLen); + // memcpy((uint8_t *)&(msg.msg_body.message_Param0), ptrParam, paramLen); + + app_mailbox_put(&msg); +} + +/** + * @brief Initialize the voice over BLE system + * + */ +void voice_over_ble_init(void) +{ + // create the mutext + vob_env_mutex_id = osMutexCreate((osMutex(vob_env_mutex))); + + // initialize the audio streams + vob_init_audio_streams(); + + // initialize the state machine + vob_state = VOB_STATE_IDLE; + + // thread id used for os signal communication between VOB thread and BLE thread + vob_ThreadId = osThreadGetId(); + + // add the voice over ble handler into the application thread + app_set_threadhandle(APP_MODUAL_VOB, voice_over_ble_handler); + + // initialize the cvsd library + Pcm8k_CvsdInit(); + + // default role is DST + vob_role = VOB_ROLE_DST; + + // register the BLE adv and connecting activity stopped callback function + app_datapath_server_register_activity_stopped_cb(vob_ble_activity_stopped); + + // start advertising if DST + vob_start_advertising(); +} + +#endif // #if __VOICE_OVER_BLE_ENABLED__ + diff --git a/services/ble_app/app_voice/app_voicepath_ble.c b/services/ble_app/app_voice/app_voicepath_ble.c new file mode 100644 index 0000000..141b67e --- /dev/null +++ b/services/ble_app/app_voice/app_voicepath_ble.c @@ -0,0 +1,151 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +/*****************************header include********************************/ +#include "cmsis_os.h" +#include "rwip_config.h" +#include "ke_msg.h" +#include "att.h" +#include "gapm_task.h" +#include "app_voicepath_ble.h" + +#ifdef BISTO_ENABLED +#include "gsound_gatt_server.h" +#include "gsound_custom_ble.h" +#endif + +/************************private macro defination***************************/ + +/************************private type defination****************************/ + +/**********************private function declearation************************/ + +/************************private variable defination************************/ + +/****************************function defination****************************/ +void app_ble_voicepath_init(void) +{ + app_gsound_ble_init(); +} + +const struct ke_state_handler *app_voicepath_ble_get_msg_handler_table(void) +{ + return gsound_ble_get_msg_handler_table(); +} + +void app_ble_voicepath_add_svc(void) +{ + return app_gsound_ble_add_svc(); +} + +const struct prf_task_cbs *voicepath_prf_itf_get(void) +{ + return gsound_prf_itf_get(); +} + +void app_ble_bms_add_svc(void) +{ + + // Register the BMS service + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, + TASK_APP, + gapm_profile_task_add_cmd, + 0); + + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX > 1 + req->sec_lvl = PERM(SVC_AUTH, SEC_CON) | PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, SEC_CON); +#endif + req->prf_task_id = TASK_ID_BMS; + req->app_task = TASK_APP; + req->start_hdl = 0; + + ke_msg_send(req); +} + +#if (ANCS_PROXY_ENABLE) +void app_ble_ancsp_add_svc(void) +{ + TRACE(0,"Registering ANCS Proxy GATT Service"); + struct gapm_profile_task_add_cmd *req = + KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, + TASK_APP, + gapm_profile_task_add_cmd, + 0); + + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX > 1 + req->sec_lvl = PERM(SVC_AUTH, SEC_CON) | PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, SEC_CON); +#endif + req->prf_task_id = TASK_ID_ANCSP; + req->app_task = TASK_APP; + req->start_hdl = 0; + + ke_msg_send(req); +} + +void app_ble_amsp_add_svc(void) +{ + TRACE(0,"Registering AMS Proxy GATT Service"); + struct gapm_profile_task_add_cmd *req = + KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, + TASK_GAPM, + TASK_APP, + gapm_profile_task_add_cmd, + 0); + + req->operation = GAPM_PROFILE_TASK_ADD; +#if BLE_CONNECTION_MAX > 1 + req->sec_lvl = PERM(SVC_AUTH, ENABLE) | PERM(SVC_MI, ENABLE); +#else + req->sec_lvl = PERM(SVC_AUTH, ENABLE); +#endif + req->prf_task_id = TASK_ID_AMSP; + req->app_task = TASK_APP; + req->start_hdl = 0; + + ke_msg_send(req); +} +#endif + +void app_voicepath_mtu_exchanged_handler(uint8_t conidx, uint16_t MTU) +{ + app_gsound_ble_mtu_exchanged_handler(conidx, MTU); +} + +void app_voicepath_disconnected_evt_handler(uint8_t conidx) +{ + if (app_gsound_ble_get_connection_index() == conidx) + { + app_gsound_ble_disconnected_evt_handler(conidx); + } + else + { + TRACE(2,"disconnect idx:%d, gsound idx:%d", conidx, app_gsound_ble_get_connection_index()); + } +} + +void app_voicepath_ble_conn_parameter_updated(uint8_t conidx, + uint16_t connInterval, uint16_t connSlavelatency) +{ + gsound_ble_conn_parameter_updated(conidx, connInterval, connSlavelatency); +} \ No newline at end of file diff --git a/services/ble_app/app_voice/app_voicepath_ble.h b/services/ble_app/app_voice/app_voicepath_ble.h new file mode 100644 index 0000000..5781319 --- /dev/null +++ b/services/ble_app/app_voice/app_voicepath_ble.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_VOICEPATH_BLE_H__ +#define __APP_VOICEPATH_BLE_H__ + +#include "ke_task.h" + +void app_ble_voicepath_init(void); + +const struct ke_state_handler *app_voicepath_ble_get_msg_handler_table(void); + +void app_ble_voicepath_add_svc(void); + +void app_ble_bms_add_svc(void); + +#if (ANCS_PROXY_ENABLE) +void app_ble_ancsp_add_svc(void); + +void app_ble_amsp_add_svc(void); +#endif + +void app_voicepath_disconnected_evt_handler(uint8_t conidx); + +void app_voicepath_mtu_exchanged_handler(uint8_t conidx, uint16_t MTU); + +void app_voicepath_ble_conn_parameter_updated(uint8_t conidx, + uint16_t connInterval, + uint16_t connSlavelatency); + +#endif diff --git a/services/ble_app/ble_app_dbg.h b/services/ble_app/ble_app_dbg.h new file mode 100644 index 0000000..743ba3f --- /dev/null +++ b/services/ble_app/ble_app_dbg.h @@ -0,0 +1,45 @@ +/** + * @file ble_app_dbg.h + * @author BES AI team + * @version 0.1 + * @date 2020-05-05 + * + * @copyright Copyright (c) 2015-2020 BES Technic. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + */ + + +#ifndef __BLE_APP_DBG_H__ +#define __BLE_APP_DBG_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +/*****************************header include********************************/ + +/******************************macro defination*****************************/ +#define LOG_V(str, ...) LOG_VERBOSE(LOG_MOD(BLEAPP), str, ##__VA_ARGS__) +#define LOG_D(str, ...) LOG_DEBUG(LOG_MOD(BLEAPP), str, ##__VA_ARGS__) +#define LOG_I(str, ...) LOG_INFO(LOG_MOD(BLEAPP), str, ##__VA_ARGS__) +#define LOG_W(str, ...) LOG_WARN(LOG_MOD(BLEAPP), str, ##__VA_ARGS__) +#define LOG_E(str, ...) LOG_ERROR(LOG_MOD(BLEAPP), str, ##__VA_ARGS__) + +/******************************type defination******************************/ + +/****************************function declearation**************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __BLE_APP_DBG_H__ */ \ No newline at end of file diff --git a/services/ble_profiles/Makefile b/services/ble_profiles/Makefile new file mode 100644 index 0000000..101a46b --- /dev/null +++ b/services/ble_profiles/Makefile @@ -0,0 +1,126 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)datapath/datapathps/src/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hrp/hrps/src/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hogp/hogpbh/src/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hogp/hogpd/src/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hogp/hogrh/src/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)bas/bass/src/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)prf/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)voicepath/$(VOICE_DATAPATH_TYPE)/*.c)) +ifeq ($(TILE_DATAPATH_ENABLED),1) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)/tile/*.c)) +endif +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)ota/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)anc/ancc/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)ams/amsc/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)gfps/gfps_provider/src/*.c)) +#obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)gfps/gfps_crypto/*.c)) + +ifeq ($(TEST_OVER_THE_AIR),1) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)tota/*.c)) +subdir-ccflags-y +=-Iservices/tota +endif +obj-y := $(obj_c:.c=.o) +ifeq ($(GFPS_ENABLE),1) +obj-y += gfps/ +endif +subdir-ccflags-y += \ + -Iservices/audio_process \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + $(BT_IF_INCLUDES) \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/retention_ram \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iapps/key \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/factory \ + -Iservices/ble_app \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/bridge/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/hl/src/gap/ \ + -Iservices/ble_stack/hl/src/gap/gapc/ \ + -Iservices/ble_stack/hl/src/gap/gapm/ \ + -Iservices/ble_stack/hl/src/gap/smpc/ \ + -Iservices/ble_stack/ke/src/ \ + -Iservices/ble_stack/hl/src/gatt/attc/ \ + -Iservices/ble_stack/hl/src/gatt/attm/ \ + -Iservices/ble_stack/hl/src/gatt/atts/ \ + -Iservices/ble_stack/hl/src/gatt/gattc/ \ + -Iservices/ble_stack/hl/src/gatt/gattm/ \ + -Iservices/ble_stack/hl/src/gatt/ \ + -Iservices/ble_stack/hl/src/l2c/l2cc/ \ + -Iservices/ble_stack/hl/src/l2c/l2cm/ \ + -Iservices/ble_stack/hci/api/ \ + -Iservices/ble_stack/hci/src/ \ + -Iservices/ble_stack/app/src/ \ + -Iservices/ble_stack/profiles/htp/htpt/api/ \ + -Iservices/ble_stack/profiles/htp/htpt/src/ \ + -Iservices/ble_stack/profiles/htp/ \ + -Iservices/ble_profiles/datapath/datapathps/api/ \ + -Iservices/ble_app/app_main/ \ + -Iservices/ble_app/app_voice \ + -Iservices/ble_app/app_htp/ \ + -Iservices/ble_app/app_datapath/ \ + -Iservices/ble_profiles/hrp/hrps/src/ \ + -Iservices/ble_profiles/hrp/hrps/api \ + -Iservices/ble_profiles/hrp/ \ + -Iservices/ble_app/app_hrps/ \ + -Iservices/ble_app/app_amsc/ \ + -Iservices/ble_app/app_ancc/ \ + -Iservices/ble_profiles/hogp/ \ + -Iservices/ble_profiles/hogp/hogpd/api/ \ + -Iservices/ble_profiles/bas/bass/src/ \ + -Iservices/ble_profiles/bas/bass/api/ \ + -Iservices/ble_profiles/anc/ \ + -Iservices/ble_profiles/anc/ancc/ \ + -Iservices/ble_profiles/ams/ \ + -Iservices/ble_profiles/ams/amsc/ \ + -Iservices/ble_profiles/voicepath/gsound \ + -Iservices/voicepath/$(VOICE_DATAPATH_TYPE)/ \ + -Iservices/voicepath/gsound/gsound_target/ \ + -Iservices/voicepath/gsound/gsound_custom/inc \ + -Iservices/voicepath/gsound/gsound_target_api_read_only \ + -Iservices/ble_profiles/gfps/gfps_provider/src/ \ + -Iservices/ble_profiles/gfps/gfps_provider/api/ \ + -Iservices/ble_profiles/gfps/gfps_crypto/ \ + -Iservices/ble_profiles/gfps/api/ \ + -Iservices/ai_voice/manager \ + -Iservices/app_ai/inc \ + -Iservices/ble_profiles/tile \ + -Ithirdparty/tile/tile_target/ \ + -Ithirdparty/tile/tile_common/tile_assert \ + -Ithirdparty/tile/tile_common/tile_features \ + -Ithirdparty/tile/tile_common/tile_gatt_db \ + -Ithirdparty/tile/tile_common/tile_player \ + -Ithirdparty/tile/tile_common/tile_service \ + -Ithirdparty/tile/tile_common/tile_storage \ + -Iservices/bt_app + +ifeq ($(OTA_ENABLE),1) +ifeq ($(IBRT),1) +ccflags-y += -Iservices/ibrt_ota/inc +else +ccflags-y += -Iservices/ota +endif +endif + diff --git a/services/ble_profiles/ams/ams_common.h b/services/ble_profiles/ams/ams_common.h new file mode 100644 index 0000000..5f10a1a --- /dev/null +++ b/services/ble_profiles/ams/ams_common.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef _AMS_COMMON_H_ +#define _AMS_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup AMS Profile + * @ingroup AMS + * @brief AMS Profile + ***************************************************************************************** + */ + +#include "rwip_config.h" + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#if (BLE_AMS_CLIENT || BLE_ANC_SERVER) + +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/// Error Codes +// The MR has not properly set up the AMS +#define AMS_INVALID_STATE (0xA0) +// The command was improperly formatted +#define AMS_INVALID_CMD (0xA1) +// The corresponding attribute is empty +#define AMS_ABSENT_ATTRIBUTE (0xA2) + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Remote Command Characteristic Value Structure +struct ams_remote_cmd +{ + /// Remote command + uint8_t remote_command_id; +}; + +/// Entity Update Characteristic Value Structure +struct ams_entity_update +{ + /// Remote command + uint8_t entity_id; + uint8_t attribute_id; + uint8_t entity_update_flags; + uint8_t value; +}; + +#endif //(BLE_AMS_CLIENT || BLE_AMS_SERVER) + +/// @} ams_common + +#endif //(_AMS_COMMON_H_) diff --git a/services/ble_profiles/ams/amsc/amsc.c b/services/ble_profiles/ams/amsc/amsc.c new file mode 100644 index 0000000..1936b69 --- /dev/null +++ b/services/ble_profiles/ams/amsc/amsc.c @@ -0,0 +1,188 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +/** + **************************************************************************************** + * @addtogroup AMSC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_AMS_CLIENT) +#include "ams_common.h" +#include "amsc.h" +#include "amsc_task.h" +#include "ke_timer.h" +#include "ke_mem.h" + +/** + **************************************************************************************** + * @brief Initialization of the AMSC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t amsc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + BLE_FUNC_ENTER(); + + struct amsc_env_tag* amsc_env = + (struct amsc_env_tag* ) ke_malloc(sizeof(struct amsc_env_tag), KE_MEM_ATT_DB); + + // allocate AMSC required environment variable + env->env = (prf_env_t*) amsc_env; + + amsc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + amsc_env->prf_env.prf_task = env->task | + (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + + // initialize environment variable + env->id = TASK_ID_AMSC; + amsc_task_init(&(env->desc)); + + for(idx = 0; idx < AMSC_IDX_MAX ; idx++) + { + amsc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), AMSC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void amsc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct amsc_env_tag* amsc_env = (struct amsc_env_tag*) env->env; + + BLE_FUNC_ENTER(); + + // clean-up environment variable allocated for task instance + if(amsc_env->env[conidx] != NULL) + { + ke_timer_clear(AMSC_TIMEOUT_TIMER_IND, prf_src_task_get(&amsc_env->prf_env, conidx)); + ke_free(amsc_env->env[conidx]); + amsc_env->env[conidx] = NULL; + } + + /* Put AMS Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), AMSC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the AMSC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void amsc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct amsc_env_tag* amsc_env = (struct amsc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < AMSC_IDX_MAX ; idx++) + { + amsc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(amsc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void amsc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put AMS Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), AMSC_IDLE); +} + +/// AMSC Task interface required by profile manager +const struct prf_task_cbs amsc_itf = +{ + amsc_init, + amsc_destroy, + amsc_create, + amsc_cleanup, +}; + +const struct prf_task_cbs* amsc_prf_itf_get(void) +{ + return &amsc_itf; +} + +void amsc_enable_rsp_send(struct amsc_env_tag *amsc_env, uint8_t conidx, uint8_t status) +{ + BLE_FUNC_ENTER(); + + //ASSERT(status == GAP_ERR_NO_ERROR, "%s error %d", __func__, status); + if (status == GAP_ERR_NO_ERROR) + { + // Register AMSC task in gatt for indication/notifications + prf_register_atthdl2gatt(&(amsc_env->prf_env), conidx, &(amsc_env->env[conidx]->ams.svc)); + // Go to connected state + ke_state_set(prf_src_task_get(&(amsc_env->prf_env), conidx), AMSC_IDLE); + } +} + +#endif //(BLE_AMS_CLIENT) + +/// @} AMSC diff --git a/services/ble_profiles/ams/amsc/amsc.h b/services/ble_profiles/ams/amsc/amsc.h new file mode 100644 index 0000000..2fa2aed --- /dev/null +++ b/services/ble_profiles/ams/amsc/amsc.h @@ -0,0 +1,181 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef _AMSC_H_ +#define _AMSC_H_ + +/** + **************************************************************************************** + * @addtogroup AMSC. + * @ingroup AMS + * @brief AMS - Client Role. + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "ams_common.h" + +#if (BLE_AMS_CLIENT) + +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "prf_utils_128.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of AMSC task instances +#define AMSC_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the amsc task +enum amsc_states +{ + /// Idle state + AMSC_FREE, + /// Connected state + AMSC_IDLE, + /// Discovery + AMSC_DISCOVERING, + /// Number of defined states. + AMSC_STATE_MAX +}; + +/// AMS Characteristics +enum amsc_chars +{ + /// Remote Command + AMSC_REMOTE_COMMAND_CHAR = 0, + /// Entity Update + AMSC_ENTITY_UPDATE_CHAR, + /// Entity Attribute + AMSC_ENTITY_ATTRIBUTE_CHAR, + /// Number of defined states. + AMSC_CHAR_MAX, +}; + +/// AMS Characteristic Descriptors +enum amsc_descs +{ + /// Remote Command - Client Characteristic Configuration + AMSC_DESC_REMOTE_CMD_CL_CFG, + /// Entity Update - Client Characteristic Configuration + AMSC_DESC_ENTITY_UPDATE_CL_CFG, + + AMSC_DESC_MAX, + + AMSC_DESC_MASK = 0x10, +}; + +/// Pointer to the connection clean-up function +#define AMSC_CLEANUP_FNCT (amsc_cleanup) + +#define AMSC_INVALID_STATE 0xA0 +#define AMSC_INVALID_COMMAND 0xA1 +#define AMSC_ABSENT_ATTRIBUTE 0xA2 + +/* + * STRUCTURES + **************************************************************************************** + */ + +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Apple Media Service + */ +struct amsc_ams_content +{ + /// Service info + struct prf_svc svc; + + /// Characteristic info: + /// - Remote Command + /// - Entity Update + /// - Entity Attribute + struct prf_char_inf chars[AMSC_CHAR_MAX]; + + /// Descriptor handles: + /// - Remote Command Client Char Cfg + /// - Entity Update Client Char Cfg + struct prf_char_desc_inf descs[AMSC_DESC_MAX]; +}; + +struct amsc_cnx_env +{ + /// Current Operation + void *operation; + + /// Provide an indication about the last operation + uint16_t last_req; + /// Last characteristic code discovered + uint8_t last_char_code; + /// Counter used to check service uniqueness + uint8_t nb_svc; + + /// AMS Characteristics + struct amsc_ams_content ams; +}; + +/// AMS Client environment variable +struct amsc_env_tag +{ + /// profile environment + prf_env_t prf_env; + + // TODO(jkessinger): Verify this will work). + uint16_t last_write_handle[AMSC_IDX_MAX]; + + /// Environment variable pointer for each connections + struct amsc_cnx_env* env[AMSC_IDX_MAX]; + /// State of different task instances + ke_state_t state[AMSC_IDX_MAX]; + +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve AMS client profile interface + * + * @return AMS client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* amsc_prf_itf_get(void); +void amsc_enable_rsp_send(struct amsc_env_tag *amsc_env, uint8_t conidx, uint8_t status); +void amsc_task_init(struct ke_task_desc *task_desc); + +#endif //(BLE_AMS_CLIENT) + +/// @} AMSC + +#endif //(_AMSC_H_) diff --git a/services/ble_profiles/ams/amsc/amsc_task.c b/services/ble_profiles/ams/amsc/amsc_task.c new file mode 100644 index 0000000..ed518ea --- /dev/null +++ b/services/ble_profiles/ams/amsc/amsc_task.c @@ -0,0 +1,521 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +/** + **************************************************************************************** + * @addtogroup AMSCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_AMS_CLIENT) + +#include "ams_common.h" +#include "ams_gatt_server.h" +#include "amsc.h" +#include "amsc_task.h" + +#include "attm.h" +#include "gap.h" +#include "gattc_task.h" +#include "prf_utils.h" +#include "prf_utils_128.h" + +#include "compiler.h" +#include "ke_timer.h" + +#include "co_utils.h" +#include "ke_mem.h" + +static uint16_t amsc_last_read_handle = BTIF_INVALID_HCI_HANDLE; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// AMSC UUID +const struct att_uuid_128 amsc_ams_svc = {{0xdc, 0xf8, 0x55, 0xad, 0x02, 0xc5, + 0xf4, 0x8e, 0x3a, 0x43, 0x36, 0x0f, + 0x2b, 0x50, 0xd3, 0x89}}; + +/// State machine used to retrieve AMS characteristics information +const struct prf_char_def_128 amsc_ams_char[AMSC_CHAR_MAX] = { + /// Remote Command + [AMSC_REMOTE_COMMAND_CHAR] = {{0xc2, 0x51, 0xca, 0xf7, 0x56, 0x0e, 0xdf, + 0xb8, 0x8a, 0x4a, 0xb1, 0x57, 0xd8, 0x81, + 0x3c, 0x9b}, + ATT_MANDATORY, + ATT_CHAR_PROP_WR | ATT_CHAR_PROP_NTF}, + + /// Entity Update + [AMSC_ENTITY_UPDATE_CHAR] = {{0x02, 0xc1, 0x96, 0xba, 0x92, 0xbb, 0x0c, + 0x9a, 0x1f, 0x41, 0x8d, 0x80, 0xce, 0xab, + 0x7c, 0x2f}, + ATT_OPTIONAL, + ATT_CHAR_PROP_WR | ATT_CHAR_PROP_NTF}, + + /// Entity Attribute + [AMSC_ENTITY_ATTRIBUTE_CHAR] = {{0xd7, 0xd5, 0xbb, 0x70, 0xa8, 0xa3, 0xab, + 0xa6, 0xd8, 0x46, 0xab, 0x23, 0x8c, 0xf3, + 0xb2, 0xc6}, + ATT_OPTIONAL, + ATT_CHAR_PROP_WR | ATT_CHAR_PROP_RD}, +}; + +/// State machine used to retrieve AMS characteristic descriptor information +const struct prf_char_desc_def amsc_ams_char_desc[AMSC_DESC_MAX] = { + /// Remote Command Char. - Client Characteristic Configuration + [AMSC_DESC_REMOTE_CMD_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_MANDATORY, + AMSC_REMOTE_COMMAND_CHAR}, + /// Entity Update Char. - Client Characteristic Configuration + [AMSC_DESC_ENTITY_UPDATE_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_OPTIONAL, + AMSC_ENTITY_UPDATE_CHAR}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref AMSC_ENABLE_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int amsc_enable_req_handler(ke_msg_id_t const msgid, + struct amsc_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + // Status + uint8_t status = GAP_ERR_NO_ERROR; + struct amsc_env_tag *amsc_env = PRF_ENV_GET(AMSC, amsc); + // Get connection index + uint8_t conidx = param->conidx; + uint8_t state = ke_state_get(dest_id); + TRACE(3,"AMSC %s Entry. state=%d, conidx=%d", + __func__, state, conidx); + + TRACE(3,"AMSC %s amsc_env->env[%d] = 0x%8.8x", __func__, conidx, + (uint32_t)amsc_env->env[conidx]); + if ((state == AMSC_IDLE) && (amsc_env->env[conidx] == NULL)) { + TRACE(1,"AMSC %s passed state check", __func__); + // allocate environment variable for task instance + amsc_env->env[conidx] = (struct amsc_cnx_env *)ke_malloc( + sizeof(struct amsc_cnx_env), KE_MEM_ATT_DB); + ASSERT(amsc_env->env[conidx], "%s alloc error", __func__); + memset(amsc_env->env[conidx], 0, sizeof(struct amsc_cnx_env)); + + amsc_env->env[conidx]->last_char_code = AMSC_ENABLE_OP_CODE; + + // Start discovering + // Discover AMS service by 128-bit UUID + prf_disc_svc_send_128(&(amsc_env->prf_env), conidx, + (uint8_t *)&amsc_ams_svc.uuid); + + // Go to DISCOVERING state + ke_state_set(dest_id, AMSC_DISCOVERING); + + // Configure the environment for a discovery procedure + amsc_env->env[conidx]->last_req = ATT_DECL_PRIMARY_SERVICE; + } + + else if (state != AMSC_FREE) { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if (status != GAP_ERR_NO_ERROR) { + amsc_enable_rsp_send(amsc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref AMSC_READ_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int amsc_read_cmd_handler(ke_msg_id_t const msgid, + struct gattc_read_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + TRACE(5,"AMSC %s Entry. hdl=0x%4.4x, op=%d, len=%d, off=%d", __func__, + param->req.simple.handle, param->operation, param->req.simple.length, + param->req.simple.offset); + + uint8_t conidx = KE_IDX_GET(dest_id); + + // Get the address of the environment + struct amsc_env_tag *amsc_env = PRF_ENV_GET(AMSC, amsc); + + if (amsc_env != NULL) { + amsc_last_read_handle = param->req.simple.handle; + // Send the read request + prf_read_char_send( + &(amsc_env->prf_env), conidx, amsc_env->env[conidx]->ams.svc.shdl, + amsc_env->env[conidx]->ams.svc.ehdl, param->req.simple.handle); + } else { + // amsc_send_no_conn_cmp_evt(dest_id, src_id, param->handle, + // AMSC_WRITE_CL_CFG_OP_CODE); + ASSERT(0, "%s implement me", __func__); + } + + return KE_MSG_CONSUMED; +} + +static int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + // Get the address of the environment + struct amsc_env_tag *amsc_env = PRF_ENV_GET(AMSC, amsc); + TRACE(3,"AMSC %s param->handle=%x param->length=%d", __func__, param->handle, + param->length); + uint8_t conidx = KE_IDX_GET(src_id); + + if (amsc_env != NULL) { + amsc_last_read_handle = BTIF_INVALID_HCI_HANDLE; + struct gattc_read_cfm *cfm = + KE_MSG_ALLOC_DYN(GATTC_READ_CFM, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_AMSP), conidx), + dest_id, gattc_read_cfm, param->length); + cfm->status = 0; // read_ind has no status??? + cfm->handle = param->handle; + cfm->length = param->length; + memcpy(cfm->value, param->value, param->length); + ke_msg_send(cfm); + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref AMSC_WRITE_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int amsc_write_cmd_handler(ke_msg_id_t const msgid, + struct gattc_write_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + TRACE(4,"AMSC %s Entry. hdl=0x%4.4x, op=%d, len=%d", __func__, + param->handle, param->operation, param->length); + + uint8_t conidx = KE_IDX_GET(dest_id); + + // Get the address of the environment + struct amsc_env_tag *amsc_env = PRF_ENV_GET(AMSC, amsc); + + if (amsc_env != NULL) { + amsc_env->last_write_handle[conidx] = param->handle; + // TODO(jkessinger): Use ke_msg_forward. + struct gattc_write_cmd *wr_char = KE_MSG_ALLOC_DYN( + GATTC_WRITE_CMD, KE_BUILD_ID(TASK_GATTC, conidx), + dest_id, gattc_write_cmd, param->length); + memcpy(wr_char, param, sizeof(struct gattc_write_cmd) + param->length); + // Send the message + ke_msg_send(wr_char); + } else { + // amsc_send_no_conn_cmp_evt(dest_id, src_id, param->handle, + // AMSC_WRITE_CL_CFG_OP_CODE); + ASSERT(0, "%s implement me", __func__); + } + + return KE_MSG_CONSUMED; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + uint8_t state = ke_state_get(dest_id); + + TRACE(4,"AMSC %s Entry. end_hdl=0x%4.4x, start_hdl=0x%4.4x, att.att_type=%d", + __func__, ind->end_hdl, ind->start_hdl, ind->info[0].att.att_type); + TRACE(3,"AMSC att_char.prop=%d, att_char.handle=0x%4.4x, att_char.att_type=%d", + ind->info[0].att_char.prop, ind->info[0].att_char.handle, + ind->info[0].att_char.att_type); + TRACE(4,"AMSC inc_svc.att_type=%d, inc_svc.end_hdl=0x%4.4x, inc_svc.start_hdl=0x%4.4x, state=%d", + ind->info[0].att_type, ind->info[0].inc_svc.att_type, + ind->info[0].inc_svc.start_hdl, state); + + if (state == AMSC_DISCOVERING) { + uint8_t conidx = KE_IDX_GET(src_id); + + struct amsc_env_tag *amsc_env = PRF_ENV_GET(AMSC, amsc); + + ASSERT_INFO(amsc_env != NULL, dest_id, src_id); + ASSERT_INFO(amsc_env->env[conidx] != NULL, dest_id, src_id); + + if (amsc_env->env[conidx]->nb_svc == 0) { + TRACE(0,"AMSC retrieving characteristics and descriptors."); + // Retrieve AMS characteristics and descriptors + prf_extract_svc_info_128(ind, AMSC_CHAR_MAX, &amsc_ams_char[0], + &amsc_env->env[conidx]->ams.chars[0], + AMSC_DESC_MAX, &amsc_ams_char_desc[0], + &amsc_env->env[conidx]->ams.descs[0]); + + // Even if we get multiple responses we only store 1 range + amsc_env->env[conidx]->ams.svc.shdl = ind->start_hdl; + amsc_env->env[conidx]->ams.svc.ehdl = ind->end_hdl; + } + + amsc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int amsc_gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + // Get the address of the environment + struct amsc_env_tag *amsc_env = PRF_ENV_GET(AMSC, amsc); + uint8_t conidx = KE_IDX_GET(dest_id); + TRACE(5,"AMSC %s entry. op=%d, seq=%d, status=%d, conidx=%d", + __func__, param->operation, param->seq_num, param->status, conidx); + // Status + uint8_t status; + + if (amsc_env->env[conidx] != NULL) { + uint8_t state = ke_state_get(dest_id); + + TRACE(2,"AMSC %s state=%d", __func__, state); + if (state == AMSC_DISCOVERING) { + status = param->status; + + if ((status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || + (status == ATT_ERR_NO_ERROR)) { + // Discovery + // check characteristic validity + if (amsc_env->env[conidx]->nb_svc == 1) { + status = prf_check_svc_char_validity_128( + AMSC_CHAR_MAX, amsc_env->env[conidx]->ams.chars, amsc_ams_char); + } + // too much services + else if (amsc_env->env[conidx]->nb_svc > 1) { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if (status == GAP_ERR_NO_ERROR) { + status = prf_check_svc_char_desc_validity( + AMSC_DESC_MAX, amsc_env->env[conidx]->ams.descs, + amsc_ams_char_desc, amsc_env->env[conidx]->ams.chars); + } + } + + amsc_enable_rsp_send(amsc_env, conidx, status); +#if (ANCS_PROXY_ENABLE) + TRACE(4,"AMSC %s rmtChar=0x%4.4x, rmtVal=0x%4.4x, rmtCfg=0x%4.4x", + __func__, + amsc_env->env[conidx]->ams.chars[AMSC_REMOTE_COMMAND_CHAR].char_hdl, + amsc_env->env[conidx]->ams.chars[AMSC_REMOTE_COMMAND_CHAR].val_hdl, + amsc_env->env[conidx] + ->ams.descs[AMSC_DESC_REMOTE_CMD_CL_CFG] + .desc_hdl); + TRACE(4,"AMSC %s EnUpChar=0x%4.4x EnUpVal=0x%4.4x, EnUpCfg=0x%4.4x", + __func__, + amsc_env->env[conidx]->ams.chars[AMSC_ENTITY_UPDATE_CHAR].char_hdl, + amsc_env->env[conidx]->ams.chars[AMSC_ENTITY_UPDATE_CHAR].val_hdl, + amsc_env->env[conidx] + ->ams.descs[AMSC_DESC_ENTITY_UPDATE_CL_CFG] + .desc_hdl); + TRACE(3,"AMSC %s EnAtrChar=0x%4.4x, EnAtrVal=0x%4.4x", __func__, + amsc_env->env[conidx]->ams.chars[AMSC_ENTITY_ATTRIBUTE_CHAR].char_hdl, + amsc_env->env[conidx]->ams.chars[AMSC_ENTITY_ATTRIBUTE_CHAR].val_hdl); + ams_proxy_set_ready_flag(conidx, + amsc_env->env[conidx]->ams.chars[AMSC_REMOTE_COMMAND_CHAR].char_hdl, + amsc_env->env[conidx]->ams.chars[AMSC_REMOTE_COMMAND_CHAR].val_hdl, + amsc_env->env[conidx] + ->ams.descs[AMSC_DESC_REMOTE_CMD_CL_CFG] + .desc_hdl, + amsc_env->env[conidx]->ams.chars[AMSC_ENTITY_UPDATE_CHAR].char_hdl, + amsc_env->env[conidx]->ams.chars[AMSC_ENTITY_UPDATE_CHAR].val_hdl, + amsc_env->env[conidx] + ->ams.descs[AMSC_DESC_ENTITY_UPDATE_CL_CFG] + .desc_hdl, + amsc_env->env[conidx]->ams.chars[AMSC_ENTITY_ATTRIBUTE_CHAR].char_hdl, + amsc_env->env[conidx]->ams.chars[AMSC_ENTITY_ATTRIBUTE_CHAR].val_hdl); + ke_state_set(dest_id, AMSC_IDLE); +#endif + } else { + switch (param->operation) { + case GATTC_READ: { + TRACE(3,"AMSC %s read complete status=%d amsc_last_read_handle %d", + __func__, param->status, amsc_last_read_handle); + if ((0 != param->status) && + (BTIF_INVALID_HCI_HANDLE != amsc_last_read_handle)) { + struct gattc_read_cfm *cfm = KE_MSG_ALLOC_DYN( + GATTC_READ_CFM, KE_BUILD_ID(prf_get_task_from_id(TASK_ID_AMSP), conidx), + dest_id, + gattc_read_cfm, 0); + cfm->status = 0; + cfm->handle = amsc_last_read_handle; + cfm->length = 0; + ke_msg_send(cfm); + } + amsc_last_read_handle = BTIF_INVALID_HCI_HANDLE; + break; + } + case GATTC_WRITE: { + struct gattc_write_cfm *cfm = + KE_MSG_ALLOC(GATTC_WRITE_CFM, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_AMSP), conidx), + dest_id, gattc_write_cfm); + cfm->handle = amsc_env->last_write_handle[conidx]; + amsc_env->last_write_handle[conidx] = ATT_INVALID_HANDLE; + cfm->status = param->status; + ke_msg_send(cfm); + break; + } + case GATTC_WRITE_NO_RESPONSE: + // There's currently no need to notify the proxy task that this completed. + break; + case GATTC_NOTIFY: + case GATTC_INDICATE: + // Nothing to do. Notify sent. + case GATTC_REGISTER: + case GATTC_UNREGISTER: + case GATTC_SDP_DISC_SVC: + // Do nothing + break; + + default: + ASSERT_ERR(0); + break; + } + } + } + // else ignore the message + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + BLE_FUNC_ENTER(); + TRACE(5,"AMSC %s Entry. handle=0x%x, len=%d, type=%d, val[0]=0x%x", + __func__, param->handle, param->length, param->type, param->value[0]); + uint8_t conidx = KE_IDX_GET(src_id); + + struct gattc_send_evt_cmd *cmd; + cmd = KE_MSG_ALLOC_DYN(AMS_PROXY_IND_EVT, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_AMSP), conidx), + dest_id, gattc_send_evt_cmd, param->length); + cmd->handle = param->handle; + cmd->operation = GATTC_NOTIFY; + cmd->seq_num = 0; + cmd->length = param->length; + memcpy(cmd->value, param->value, param->length); + ke_msg_send(cmd); + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(amsc){ + {AMSC_ENABLE_REQ, (ke_msg_func_t)amsc_enable_req_handler}, + {AMSC_READ_CMD, (ke_msg_func_t)amsc_read_cmd_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {AMSC_WRITE_CMD, (ke_msg_func_t)amsc_write_cmd_handler}, + + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)amsc_gattc_cmp_evt_handler}, +}; + +void amsc_task_init(struct ke_task_desc *task_desc) { + TRACE(1,"AMSC %s Entry.", __func__); + // Get the address of the environment + struct amsc_env_tag *amsc_env = PRF_ENV_GET(AMSC, amsc); + + task_desc->msg_handler_tab = amsc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(amsc_msg_handler_tab); + task_desc->state = amsc_env->state; + task_desc->idx_max = AMSC_IDX_MAX; +} + +#endif //(BLE_AMS_CLIENT) + +/// @} AMSCTASK diff --git a/services/ble_profiles/ams/amsc/amsc_task.h b/services/ble_profiles/ams/amsc/amsc_task.h new file mode 100644 index 0000000..e92529b --- /dev/null +++ b/services/ble_profiles/ams/amsc/amsc_task.h @@ -0,0 +1,109 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef _AMSC_TASK_H_ +#define _AMSC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup AMSCTASK AMS Client Task + * @ingroup AMSC + * @brief AMS Client Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#if (BLE_AMS_CLIENT) + +#include "ke_task.h" +#include "gattm_task.h" +#include "amsc.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "prf_utils_128.h" + +/// Message IDs +enum +{ + /// Enable the AMS Client task - at connection + AMSC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_AMSC), + + /// Enable the AMS Client task - at connection + AMSC_ENABLE_RSP, + + /// Read the value of a Client Characteristic Configuration Descriptor in the peer device database + AMSC_READ_CMD, + + /// Write the value of a Client Characteristic Configuration Descriptor in the peer device database + AMSC_WRITE_CMD, + + /// Procedure Timeout Timer + AMSC_TIMEOUT_TIMER_IND, +}; + +/// Operation Codes +enum +{ + /// Reserved operation code + AMSC_RESERVED_OP_CODE = 0x00, + + /// Discovery Procedure + AMSC_ENABLE_OP_CODE, +}; + +/* + * API MESSAGE STRUCTURES + **************************************************************************************** + */ + +/// Parameters of the @ref AMSC_ENABLE_REQ message +struct amsc_enable_req +{ + /// Connection handle + uint16_t conhdl; + uint8_t conidx; +}; + + +/// Parameters of the @ref AMSC_ENABLE_RSP message +struct amsc_enable_rsp +{ + /// status + uint8_t status; + /// Existing handle values AMS + struct amsc_ams_content ams; +}; + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +//extern const struct ke_state_handler amsc_state_handler[AMSC_STATE_MAX]; +//extern const struct ke_state_handler amsc_default_handler; +//extern ke_state_t amsc_state[AMSC_IDX_MAX]; + +#endif //(BLE_ANC_CLIENT) + +/// @} AMSCTASK + +#endif //(_AMSC_TASK_H_) diff --git a/services/ble_profiles/anc/anc_common.h b/services/ble_profiles/anc/anc_common.h new file mode 100644 index 0000000..95c100c --- /dev/null +++ b/services/ble_profiles/anc/anc_common.h @@ -0,0 +1,225 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef _ANC_COMMON_H_ +#define _ANC_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup ANCS Profile + * @ingroup ANCS + * @brief ANCS Profile + ***************************************************************************************** + */ + +#include "rwip_config.h" + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#if (BLE_ANC_CLIENT || BLE_ANC_SERVER) + +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/// Error Codes +// Command not recognized by the NP - Protocol +#define ANC_CMD_UNKNOWN (0xA0) +// Command improperly formatted - Proprietary +#define ANC_CMD_INVALID (0xA1) +// One of the parameters does not refer to an existing object on the NP - Proprietary +#define ANC_PARAM_INVALID (0xA2) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Category ID Values +enum +{ + /// Other + CAT_ID_OTHER = 0, + /// Incoming Call + CAT_ID_CALL = 1, + /// Missed Call + CAT_ID_MISSED_CALL = 2, + /// Voice Mail + CAT_ID_VOICE_MAIL = 3, + /// Social network + CAT_ID_SOCIAL = 4, + /// Schedule + CAT_ID_SCHEDULE = 5, + /// Email + CAT_ID_EMAIL = 6, + /// News Feed + CAT_ID_NEWS = 7, + /// Health and Fitness + CAT_ID_HEALTH_FITNESS = 8, + /// Business and Finance + CAT_ID_BUSINESS_FINANCE = 9, + /// Location + CAT_ID_LOCATION = 10, + /// Entertainment + CAT_ID_ENTERTAINMENT = 11, + + CAT_ID_NB, + + /// All supported categories + CAT_ID_ALL_SUPPORTED_CAT = 255, +}; + +/// Event ID Values +enum +{ + /// Notification Added + EVT_ID_NTF_ADDED = 0, + /// Notification Modified + EVT_ID_NTF_MODIFIED = 1, + /// Notification Removed + EVT_ID_NTF_REMOVED = 2, + + EVT_ID_NB, + + EVT_ID_ALL_SUPPORTED_EVT = 255, +}; + +/// Event Flags +enum +{ + /// Silent + EVT_FLAG_SILENT = (1 << 0), + /// Important + EVT_FLAG_IMPORTANT = (1 << 1), + + EVT_FLAG_NB, + + EVT_FLAG_ALL_SUPPORTED_EVT_FLAG = (1 << 7), +}; + +/// Command ID Values +enum +{ + /// Get Notification Attributes + CMD_ID_GET_NTF_ATTS = 0, + /// Get App Attributes + CMD_ID_GET_APP_ATTS = 1, + + + CMD_ID_NB, + + /// All supported commands + CMD_ID_ALL_SUPPORTED_CMD = 255, +}; + +/// Notification Attribute ID Values +enum +{ + /// App Identifier + NTF_ATT_ID_APP_ID = 0, + /// Title (Needs to be followed by a 2-bytes max length parameter) + NTF_ATT_ID_TITLE = 1, + /// Subtitle (Needs to be followed by a 2-bytes max length parameter) + NTF_ATT_ID_SUBTITLE = 2, + /// Message (Needs to be followed by a 2-bytes max length parameter) + NTF_ATT_ID_MSG = 3, + /// Message Size + NTF_ATT_ID_MSG_SIZE = 4, + /// Date + NTF_ATT_ID_DATE = 5, + + + NTF_ATT_ID_NB, + + /// All supported Notification Attributes + NTF_ATT_ID_ALL_SUPPORTED_NTF_ATT = 255, +}; + +/// Notification Attribute Bit Mask Flags +enum ancc_ntf_attr_present +{ + /// App Identifier present + NTF_ATT_ID_APP_ID_PRESENT = 0x01, + /// Title present + NTF_ATT_ID_TITLE_PRESENT = 0x02, + /// Subtitle present + NTF_ATT_ID_SUBTITLE_PRESENT = 0x04, + /// Message present + NTF_ATT_ID_MSG_PRESENT = 0x08, + /// Message Size present + NTF_ATT_ID_MSG_SIZE_PRESENT = 0x10, + /// Date present + NTF_ATT_ID_DATE_PRESENT = 0x20, +}; + + +/// App Attribute ID Values +enum +{ + /// Display Name present + APP_ATT_ID_DISPLAY_NAME = 0, + + APP_ADD_ID_NB, + + /// All supported App Attributes + APP_ATT_ID_ALL_SUPPORTED_APP_ATT = 255, +}; + +// App Attribute Bit Mask Flags +enum +{ + /// App Identifier + APP_ATT_ID_DISPLAY_NAME_PRESENT = 0x01, + +}; + + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Notification Source Characteristic Value Structure +struct anc_ntf_src +{ + /// Event ID + uint8_t event_id; + + /// Event Flags + uint8_t event_flags; + + /// Category ID + uint8_t cat_id; + + /// Category Count: Number of active notifications in the given category + uint8_t cat_cnt; + + /// Notification UID + uint32_t ntf_uid; +}; + +#endif //(BLE_ANC_CLIENT || BLE_ANC_SERVER) + +/// @} anc_common + +#endif //(_ANC_COMMON_H_) diff --git a/services/ble_profiles/anc/ancc/ancc.c b/services/ble_profiles/anc/ancc/ancc.c new file mode 100644 index 0000000..6337bc7 --- /dev/null +++ b/services/ble_profiles/anc/ancc/ancc.c @@ -0,0 +1,188 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +/** + **************************************************************************************** + * @addtogroup ANCC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_ANC_CLIENT) +#include "anc_common.h" +#include "ancc.h" +#include "ancc_task.h" +#include "ke_timer.h" +#include "ke_mem.h" + +/** + **************************************************************************************** + * @brief Initialization of the ANCC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t ancc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + BLE_FUNC_ENTER(); + + struct ancc_env_tag* ancc_env = + (struct ancc_env_tag* ) ke_malloc(sizeof(struct ancc_env_tag), KE_MEM_ATT_DB); + + // allocate ANCC required environment variable + env->env = (prf_env_t*) ancc_env; + + ancc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + ancc_env->prf_env.prf_task = env->task | + (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + + // initialize environment variable + env->id = TASK_ID_ANCC; + ancc_task_init(&(env->desc)); + + for(idx = 0; idx < ANCC_IDX_MAX ; idx++) + { + ancc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), ANCC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void ancc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct ancc_env_tag* ancc_env = (struct ancc_env_tag*) env->env; + + BLE_FUNC_ENTER(); + + // clean-up environment variable allocated for task instance + if(ancc_env->env[conidx] != NULL) + { + ke_timer_clear(ANCC_TIMEOUT_TIMER_IND, prf_src_task_get(&ancc_env->prf_env, conidx)); + ke_free(ancc_env->env[conidx]); + ancc_env->env[conidx] = NULL; + } + + /* Put ANC Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), ANCC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the ANCC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void ancc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct ancc_env_tag* ancc_env = (struct ancc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < ANCC_IDX_MAX ; idx++) + { + ancc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(ancc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void ancc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put ANC Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), ANCC_IDLE); +} + +/// ANCC Task interface required by profile manager +const struct prf_task_cbs ancc_itf = +{ + ancc_init, + ancc_destroy, + ancc_create, + ancc_cleanup, +}; + +const struct prf_task_cbs* ancc_prf_itf_get(void) +{ + return &ancc_itf; +} + +void ancc_enable_rsp_send(struct ancc_env_tag *ancc_env, uint8_t conidx, uint8_t status) +{ + BLE_FUNC_ENTER(); + + //ASSERT(status == GAP_ERR_NO_ERROR, "%s error %d", __func__, status); + if (status == GAP_ERR_NO_ERROR) + { + // Register ANCC task in gatt for indication/notifications + prf_register_atthdl2gatt(&(ancc_env->prf_env), conidx, &(ancc_env->env[conidx]->anc.svc)); + // Go to connected state + ke_state_set(prf_src_task_get(&(ancc_env->prf_env), conidx), ANCC_IDLE); + } +} + +#endif //(BLE_ANC_CLIENT) + +/// @} ANCC diff --git a/services/ble_profiles/anc/ancc/ancc.h b/services/ble_profiles/anc/ancc/ancc.h new file mode 100644 index 0000000..42d6905 --- /dev/null +++ b/services/ble_profiles/anc/ancc/ancc.h @@ -0,0 +1,175 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef _ANCC_H_ +#define _ANCC_H_ + +/** + **************************************************************************************** + * @addtogroup ANCC. + * @ingroup ANC + * @brief ANCS - Client Role. + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "anc_common.h" + +#if (BLE_ANC_CLIENT) + +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "prf_utils_128.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of ANCC task instances +#define ANCC_IDX_MAX (BLE_CONNECTION_MAX) + +/// Possible states of the ancc task +enum ancc_states +{ + /// Idle state + ANCC_FREE, + /// Connected state + ANCC_IDLE, + /// Discovery + ANCC_DISCOVERING, + + /// Number of defined states. + ANCC_STATE_MAX +}; + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// ANCS Characteristics +enum ancc_anc_chars +{ + /// Notification Source + ANCC_CHAR_NTF_SRC, + /// Control Point + ANCC_CHAR_CTRL_PT, + /// Data Source + ANCC_CHAR_DATA_SRC, + + ANCC_CHAR_MAX, +}; + +/// ANCS Characteristic Descriptors +enum ancc_anc_descs +{ + /// Notification Source - Client Characteristic Configuration + ANCC_DESC_NTF_SRC_CL_CFG, + /// Data Source - Client Characteristic Configuration + ANCC_DESC_DATA_SRC_CL_CFG, + + ANCC_DESC_MAX, + + ANCC_DESC_MASK = 0x10, +}; + +/// Pointer to the connection clean-up function +#define ANCC_CLEANUP_FNCT (ancc_cleanup) +/* + * STRUCTURES + **************************************************************************************** + */ + +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Alert Notification Service + */ +struct ancc_anc_content +{ + /// Service info + struct prf_svc svc; + + /// Characteristic info: + /// - Notification Source + /// - Control Point + /// - Data Source + struct prf_char_inf chars[ANCC_CHAR_MAX]; + + /// Descriptor handles: + /// - Notification Source Client Char Cfg + /// - Data Source Client Char Cfg + struct prf_char_desc_inf descs[ANCC_DESC_MAX]; +}; + +struct ancc_cnx_env +{ + /// Current Operation + void *operation; + + /// Provide an indication about the last operation + uint16_t last_req; + /// Last characteristic code discovered + uint8_t last_char_code; + /// Counter used to check service uniqueness + uint8_t nb_svc; + + /// ANCS Characteristics + struct ancc_anc_content anc; +}; + +/// ANCS Client environment variable +struct ancc_env_tag +{ + /// profile environment + prf_env_t prf_env; + + // TODO(jkessinger): Is this safe? Reliable? WTF? + uint16_t last_write_handle[ANCC_IDX_MAX]; + /// Environment variable pointer for each connections + struct ancc_cnx_env* env[ANCC_IDX_MAX]; + /// State of different task instances + ke_state_t state[ANCC_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve ANCS client profile interface + * + * @return ANCS client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* ancc_prf_itf_get(void); +void ancc_enable_rsp_send(struct ancc_env_tag *ancc_env, uint8_t conidx, uint8_t status); +void ancc_task_init(struct ke_task_desc *task_desc); + +#endif //(BLE_ANC_CLIENT) + +/// @} ANCC + +#endif //(_ANCC_H_) diff --git a/services/ble_profiles/anc/ancc/ancc_task.c b/services/ble_profiles/anc/ancc/ancc_task.c new file mode 100644 index 0000000..9cc578a --- /dev/null +++ b/services/ble_profiles/anc/ancc/ancc_task.c @@ -0,0 +1,491 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +/** + **************************************************************************************** + * @addtogroup ANCCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_ANC_CLIENT) + +#include "anc_common.h" +#include "ancc.h" +#include "ancc_task.h" + +#include "attm.h" +#include "gap.h" +#include "gattc_task.h" +#include "prf_utils.h" +#include "prf_utils_128.h" + +#include "compiler.h" +#include "ke_timer.h" + +#include "co_utils.h" +#include "ke_mem.h" + +#if (ANCS_PROXY_ENABLE) +#include "ancs_gatt_server.h" +#endif +/* + * STRUCTURES + **************************************************************************************** + */ + +/// ANCS UUID +const struct att_uuid_128 ancc_anc_svc = {{0xD0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, + 0x0F, 0xA4, 0x99, 0x4E, 0xCE, 0xB5, + 0x31, 0xF4, 0x05, 0x79}}; + +/// State machine used to retrieve ANCS characteristics information +const struct prf_char_def_128 ancc_anc_char[ANCC_CHAR_MAX] = { + /// Notification Source + [ANCC_CHAR_NTF_SRC] = {{0xBD, 0x1D, 0xA2, 0x99, 0xE6, 0x25, 0x58, 0x8C, + 0xD9, 0x42, 0x01, 0x63, 0x0D, 0x12, 0xBF, 0x9F}, + ATT_MANDATORY, + ATT_CHAR_PROP_NTF}, + + /// Control Point + [ANCC_CHAR_CTRL_PT] = {{0xD9, 0xD9, 0xAA, 0xFD, 0xBD, 0x9B, 0x21, 0x98, + 0xA8, 0x49, 0xE1, 0x45, 0xF3, 0xD8, 0xD1, 0x69}, + ATT_OPTIONAL, + ATT_CHAR_PROP_WR}, + + /// Data Source + [ANCC_CHAR_DATA_SRC] = {{0xFB, 0x7B, 0x7C, 0xCE, 0x6A, 0xB3, 0x44, 0xBE, + 0xB5, 0x4B, 0xD6, 0x24, 0xE9, 0xC6, 0xEA, 0x22}, + ATT_OPTIONAL, + ATT_CHAR_PROP_NTF}, + +}; + +/// State machine used to retrieve ANCS characteristic descriptor information +const struct prf_char_desc_def ancc_anc_char_desc[ANCC_DESC_MAX] = { + /// Notification Source Char. - Client Characteristic Configuration + [ANCC_DESC_NTF_SRC_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_MANDATORY, + ANCC_CHAR_NTF_SRC}, + /// Data Source Char. - Client Characteristic Configuration + [ANCC_DESC_DATA_SRC_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_OPTIONAL, + ANCC_CHAR_DATA_SRC}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref ANCC_ENABLE_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int ancc_enable_req_handler(ke_msg_id_t const msgid, + struct ancc_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + // Status + uint8_t status = GAP_ERR_NO_ERROR; + struct ancc_env_tag *ancc_env = PRF_ENV_GET(ANCC, ancc); + // Get connection index + uint8_t conidx = param->conidx; + uint8_t state = ke_state_get(dest_id); + TRACE(3,"ANCSC %s Entry. state=%d, conidx=%d", + __func__, state, conidx); + + if ((state == ANCC_IDLE) && (ancc_env->env[conidx] == NULL)) { + TRACE(1,"ANCSC %s passed state check", __func__); + // allocate environment variable for task instance + ancc_env->env[conidx] = (struct ancc_cnx_env *)ke_malloc( + sizeof(struct ancc_cnx_env), KE_MEM_ATT_DB); + ASSERT(ancc_env->env[conidx], "%s alloc error", __func__); + memset(ancc_env->env[conidx], 0, sizeof(struct ancc_cnx_env)); + + ancc_env->env[conidx]->last_char_code = ANCC_ENABLE_OP_CODE; + + // Start discovering + // Discover ANCS service by 128-bit UUID + prf_disc_svc_send_128(&(ancc_env->prf_env), conidx, + (uint8_t *)&ancc_anc_svc.uuid); + + // Go to DISCOVERING state + ke_state_set(dest_id, ANCC_DISCOVERING); + + // Configure the environment for a discovery procedure + ancc_env->env[conidx]->last_req = ATT_DECL_PRIMARY_SERVICE; + } + + else if (state != ANCC_FREE) { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if (status != GAP_ERR_NO_ERROR) { + ancc_enable_rsp_send(ancc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref ANCC_READ_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int ancc_read_cmd_handler(ke_msg_id_t const msgid, + struct gattc_read_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + + uint8_t conidx = KE_IDX_GET(dest_id); + TRACE(6,"ANCSC %s Entry. conidex %d hdl=0x%4.4x, op=%d, len=%d, off=%d", __func__, + conidx, param->req.simple.handle, param->operation, param->req.simple.length, + param->req.simple.offset); + + // Get the address of the environment + struct ancc_env_tag *ancc_env = PRF_ENV_GET(ANCC, ancc); + + if (ancc_env != NULL) { + // Send the read request + prf_read_char_send( + &(ancc_env->prf_env), conidx, ancc_env->env[conidx]->anc.svc.shdl, + ancc_env->env[conidx]->anc.svc.ehdl, param->req.simple.handle); + } else { + // amsc_send_no_conn_cmp_evt(dest_id, src_id, param->handle, + // ANCC_WRITE_CL_CFG_OP_CODE); + ASSERT(0, "%s implement me", __func__); + } + + return KE_MSG_CONSUMED; +} + +static int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + // Get the address of the environment + struct amsc_env_tag *amsc_env = PRF_ENV_GET(ANCC, amsc); + TRACE(3,"ANCSC %s param->handle=0x%x param->length=%d", __func__, param->handle, + param->length); + + if (amsc_env != NULL) { + uint8_t conidx = KE_IDX_GET(src_id); + struct gattc_read_cfm *cfm = + KE_MSG_ALLOC_DYN(GATTC_READ_CFM, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_ANCSP), conidx), + dest_id, gattc_read_cfm, param->length); + cfm->status = 0; // read_ind has no status??? + cfm->handle = param->handle; + cfm->length = param->length; + memcpy(cfm->value, param->value, param->length); + ke_msg_send(cfm); + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref ANCC_WRITE_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int ancc_write_cmd_handler(ke_msg_id_t const msgid, + struct gattc_write_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + TRACE(4,"ANCSC %s Entry. hdl=0x%4.4x, op=%d, len=%d", __func__, + param->handle, param->operation, param->length); + + uint8_t conidx = KE_IDX_GET(dest_id); + + // Get the address of the environment + struct ancc_env_tag *ancc_env = PRF_ENV_GET(ANCC, ancc); + + if (ancc_env != NULL) { + ancc_env->last_write_handle[conidx] = param->handle; + // TODO(jkessinger): Use ke_msg_forward. + struct gattc_write_cmd *wr_char = KE_MSG_ALLOC_DYN( + GATTC_WRITE_CMD, KE_BUILD_ID(TASK_GATTC, conidx), + dest_id, gattc_write_cmd, param->length); + memcpy(wr_char, param, sizeof(struct gattc_write_cmd) + param->length); + // Send the message + ke_msg_send(wr_char); + } else { + // ancc_send_no_conn_cmp_evt(dest_id, src_id, param->handle, + // ANCC_WRITE_CL_CFG_OP_CODE); + ASSERT(0, "%s implement me", __func__); + } + + return KE_MSG_CONSUMED; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + uint8_t state = ke_state_get(dest_id); + + TRACE(4,"ANCSC %s Entry. end_hdl=0x%4.4x, start_hdl=0x%4.4x, att.att_type=%d", + __func__, ind->end_hdl, ind->start_hdl, ind->info[0].att.att_type); + TRACE(3,"ANCSC att_char.prop=%d, att_char.handle=0x%4.4x, att_char.att_type=%d", + ind->info[0].att_char.prop, ind->info[0].att_char.handle, + ind->info[0].att_char.att_type); + TRACE(4,"ANCSC inc_svc.att_type=%d, inc_svc.end_hdl=0x%4.4x, inc_svc.start_hdl=0x%4.4x, state=%d", + ind->info[0].att_type, ind->info[0].inc_svc.att_type, + ind->info[0].inc_svc.start_hdl, state); + + if (state == ANCC_DISCOVERING) { + uint8_t conidx = KE_IDX_GET(src_id); + + struct ancc_env_tag *ancc_env = PRF_ENV_GET(ANCC, ancc); + + ASSERT_INFO(ancc_env != NULL, dest_id, src_id); + ASSERT_INFO(ancc_env->env[conidx] != NULL, dest_id, src_id); + + if (ancc_env->env[conidx]->nb_svc == 0) { + TRACE(0,"ANCSC retrieving characteristics and descriptors."); + // Retrieve ANC characteristics and descriptors + prf_extract_svc_info_128(ind, ANCC_CHAR_MAX, &ancc_anc_char[0], + &ancc_env->env[conidx]->anc.chars[0], + ANCC_DESC_MAX, &ancc_anc_char_desc[0], + &ancc_env->env[conidx]->anc.descs[0]); + + // Even if we get multiple responses we only store 1 range + ancc_env->env[conidx]->anc.svc.shdl = ind->start_hdl; + ancc_env->env[conidx]->anc.svc.ehdl = ind->end_hdl; + } + + ancc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + // Get the address of the environment + struct ancc_env_tag *ancc_env = PRF_ENV_GET(ANCC, ancc); + uint8_t conidx = KE_IDX_GET(dest_id); + TRACE(5,"ANCSC %s entry. op=%d, seq=%d, status=%d, conidx=%d", + __func__, param->operation, param->seq_num, param->status, conidx); + // Status + uint8_t status; + + if (ancc_env->env[conidx] != NULL) { + uint8_t state = ke_state_get(dest_id); + + TRACE(2,"ANCSC %s state=%d", __func__, state); + if (state == ANCC_DISCOVERING) { + status = param->status; + + if ((status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || + (status == ATT_ERR_NO_ERROR)) { + // Discovery + // check characteristic validity + if (ancc_env->env[conidx]->nb_svc == 1) { + status = prf_check_svc_char_validity_128( + ANCC_CHAR_MAX, ancc_env->env[conidx]->anc.chars, ancc_anc_char); + } + // too much services + else if (ancc_env->env[conidx]->nb_svc > 1) { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if (status == GAP_ERR_NO_ERROR) { + status = prf_check_svc_char_desc_validity( + ANCC_DESC_MAX, ancc_env->env[conidx]->anc.descs, + ancc_anc_char_desc, ancc_env->env[conidx]->anc.chars); + } + } + + ancc_enable_rsp_send(ancc_env, conidx, status); +#if (ANCS_PROXY_ENABLE) + TRACE(4,"ANCSC %s NSChar=0x%4.4x, NSVal=0x%4.4x, NSCfg=0x%4.4x", __func__, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_NTF_SRC].char_hdl, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_NTF_SRC].val_hdl, + ancc_env->env[conidx]->anc.descs[ANCC_DESC_NTF_SRC_CL_CFG].desc_hdl); + TRACE(4,"ANCSC %s DSChar=0x%4.4x DSVal=0x%4.4x, DSCfg=0x%4.4x", __func__, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_DATA_SRC].char_hdl, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_DATA_SRC].val_hdl, + ancc_env->env[conidx]->anc.descs[ANCC_DESC_DATA_SRC_CL_CFG].desc_hdl); + TRACE(3,"ANCSC %s CPChar=0x%4.4x, CPVal=0x%4.4x", __func__, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_CTRL_PT].char_hdl, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_CTRL_PT].val_hdl); + ancs_proxy_set_ready_flag(conidx, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_NTF_SRC].char_hdl, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_NTF_SRC].val_hdl, + ancc_env->env[conidx]->anc.descs[ANCC_DESC_NTF_SRC_CL_CFG].desc_hdl, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_DATA_SRC].char_hdl, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_DATA_SRC].val_hdl, + ancc_env->env[conidx]->anc.descs[ANCC_DESC_DATA_SRC_CL_CFG].desc_hdl, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_CTRL_PT].char_hdl, + ancc_env->env[conidx]->anc.chars[ANCC_CHAR_CTRL_PT].val_hdl); + ke_state_set(dest_id, ANCC_IDLE); +#endif + } else { + switch (param->operation) { + case GATTC_READ: { + TRACE(2,"ANCSC %s read complete status=%d", __func__, + param->status); + break; + } + case GATTC_WRITE: { + struct gattc_write_cfm *cfm = + KE_MSG_ALLOC(GATTC_WRITE_CFM, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_ANCSP), conidx), + dest_id, gattc_write_cfm); + cfm->handle = ancc_env->last_write_handle[conidx]; + ancc_env->last_write_handle[conidx] = ATT_INVALID_HANDLE; + cfm->status = param->status; + ke_msg_send(cfm); + break; + } + case GATTC_WRITE_NO_RESPONSE: + // There's currently no need to notify the proxy task that this completed. + break; + case GATTC_NOTIFY: + case GATTC_INDICATE: + // Nothing to do. Notification sent. + case GATTC_REGISTER: + case GATTC_UNREGISTER: + case GATTC_SDP_DISC_SVC: + // Do nothing + break; + + default: + ASSERT_ERR(0); + break; + } + } + } + // else ignore the message + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) { + BLE_FUNC_ENTER(); + TRACE(5,"ANCSC %s Entry. handle=0x%x, len=%d, type=%d, val[0]=0x%x", + __func__, param->handle, param->length, param->type, param->value[0]); + uint8_t conidx = KE_IDX_GET(src_id); + struct gattc_send_evt_cmd *cmd; + cmd = + KE_MSG_ALLOC_DYN(ANCS_PROXY_IND_EVT, + KE_BUILD_ID(prf_get_task_from_id(TASK_ID_ANCSP), conidx), + dest_id, gattc_send_evt_cmd, param->length); + cmd->handle = param->handle; + cmd->operation = GATTC_NOTIFY; + cmd->seq_num = 0; + cmd->length = param->length; + memcpy(cmd->value, param->value, param->length); + ke_msg_send(cmd); + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(ancc){ + {ANCC_ENABLE_REQ, (ke_msg_func_t)ancc_enable_req_handler}, + {ANCC_WRITE_CMD, (ke_msg_func_t)ancc_write_cmd_handler}, + {ANCC_READ_CMD, (ke_msg_func_t)ancc_read_cmd_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void ancc_task_init(struct ke_task_desc *task_desc) { + TRACE(1,"ANCSC %s Entry.", __func__); + // Get the address of the environment + struct ancc_env_tag *ancc_env = PRF_ENV_GET(ANCC, ancc); + + task_desc->msg_handler_tab = ancc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(ancc_msg_handler_tab); + task_desc->state = ancc_env->state; + task_desc->idx_max = ANCC_IDX_MAX; +} + +#endif //(BLE_ANC_CLIENT) + +/// @} ANCCTASK diff --git a/services/ble_profiles/anc/ancc/ancc_task.h b/services/ble_profiles/anc/ancc/ancc_task.h new file mode 100644 index 0000000..24d6850 --- /dev/null +++ b/services/ble_profiles/anc/ancc/ancc_task.h @@ -0,0 +1,121 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef _ANCC_TASK_H_ +#define _ANCC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup ANCCTASK ANCS Client Task + * @ingroup ANCC + * @brief ANCS Client Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "anc_common.h" + +#if (BLE_ANC_CLIENT) + +#include "ke_task.h" +#include "gattm_task.h" +#include "ancc.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "prf_utils_128.h" + +/// Message IDs +enum +{ + /// Enable the ANCS Client task - at connection + ANCC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_ANCC), + + /// Enable the ANCS Client task - at connection + ANCC_ENABLE_RSP, + + /// Disable Indication + ANCC_DISABLE_IND, + + /// Read the value of a Client Characteristic Configuration Descriptor in the peer device database + ANCC_READ_CMD, + + /// Write the value of a Client Characteristic Configuration Descriptor in the peer device database + ANCC_WRITE_CMD, + + /// Procedure Timeout Timer + ANCC_TIMEOUT_TIMER_IND, +}; + +/// Operation Codes +enum +{ + /// Reserved operation code + ANCC_RESERVED_OP_CODE = 0x00, + + /// Discovery Procedure + ANCC_ENABLE_OP_CODE, +}; + +/* + * API MESSAGE STRUCTURES + **************************************************************************************** + */ + +/// Parameters of the @ref ANCC_ENABLE_REQ message +struct ancc_enable_req +{ + uint8_t conidx; +}; + + +/// Parameters of the @ref ANCC_ENABLE_RSP message +struct ancc_enable_rsp +{ + /// status + uint8_t status; + /// Existing handle values ANC + struct ancc_anc_content anc; +}; + +/// Parameters of the @ref ANCC_DISABLE_IND message +struct ancc_disable_ind +{ + /// Connection handle + uint16_t conhdl; + /// Operation Code + uint8_t status; +}; + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +//extern const struct ke_state_handler ancc_state_handler[ANCC_STATE_MAX]; +//extern const struct ke_state_handler ancc_default_handler; +//extern ke_state_t ancc_state[ANCC_IDX_MAX]; + +#endif //(BLE_ANC_CLIENT) + +/// @} ANCCTASK + +#endif //(_ANCC_TASK_H_) diff --git a/services/ble_profiles/anp/anp_common.h b/services/ble_profiles/anp/anp_common.h new file mode 100644 index 0000000..c87da43 --- /dev/null +++ b/services/ble_profiles/anp/anp_common.h @@ -0,0 +1,181 @@ +#ifndef _ANP_COMMON_H_ +#define _ANP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup ANP Alert Notification Profile + * @ingroup ANP + * @brief Alert Notification Profile + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/// Error Code +// Command Not Supported - Protocol +#define ANP_CMD_NOT_SUPPORTED (0xA0) +// Category Not Supported - Proprietary +#define ANP_CAT_NOT_SUPPORTED (0xA1) + +/// Alert Category ID Bit Mask 0 Masks +#define ANP_CAT_ID_SPL_ALERT_SUP (0x01) +#define ANP_CAT_ID_EMAIL_SUP (0x02) +#define ANP_CAT_ID_NEWS_SUP (0x04) +#define ANP_CAT_ID_CALL_SUP (0x08) +#define ANP_CAT_ID_MISSED_CALL_SUP (0x10) +#define ANP_CAT_ID_SMS_MMS_SUP (0x20) +#define ANP_CAT_ID_VOICE_MAIL_SUP (0x40) +#define ANP_CAT_ID_SCHEDULE_SUP (0x80) + +/// Alert Category ID Bit Mask 1 Masks +#define ANP_CAT_ID_HIGH_PRTY_ALERT (0x01) +#define ANP_CAT_ID_INST_MSG (0x02) +/// Alert Category ID 1 Mask +#define ANP_CAT_ID_1_MASK (ANP_CAT_ID_HIGH_PRTY_ALERT | ANP_CAT_ID_INST_MSG) + +/// New Alert Characteristic Value - Text String Information Max Length +#define ANS_NEW_ALERT_STRING_INFO_MAX_LEN (18) +/// New Alert Characteristic Value Max Length +#define ANS_NEW_ALERT_MAX_LEN (ANS_NEW_ALERT_STRING_INFO_MAX_LEN + 2) +/// Bonded data configured +#define ANPS_FLAG_CFG_PERFORMED_OK (0x10) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Category ID Field Keys +enum +{ + /// Simple Alert + CAT_ID_SPL_ALERT = 0, + /// Email + CAT_ID_EMAIL, + /// News Feed + CAT_ID_NEWS, + /// Incoming Call + CAT_ID_CALL, + /// Missed Call + CAT_ID_MISSED_CALL, + /// SMS/MMS + CAT_ID_SMS_MMS, + /// Voice Mail + CAT_ID_VOICE_MAIL, + /// Schedule + CAT_ID_SCHEDULE, + /// High Priority Alert + CAT_ID_HIGH_PRTY_ALERT, + /// Instant Message + CAT_ID_INST_MSG, + + CAT_ID_NB, + + /// All supported category + CAT_ID_ALL_SUPPORTED_CAT = 255, +}; + +/// Command ID Field Keys +enum +{ + /// Enable New Incoming Alert Notification + CMD_ID_EN_NEW_IN_ALERT_NTF = 0, + /// Enable Unread Category Status Notification + CMD_ID_EN_UNREAD_CAT_STATUS_NTF, + /// Disable New Incoming Alert Notification + CMD_ID_DIS_NEW_IN_ALERT_NTF, + /// Disable Unread Category Status Notification + CMD_ID_DIS_UNREAD_CAT_STATUS_NTF, + /// Notify New Incoming Alert immediately + CMD_ID_NTF_NEW_IN_ALERT_IMM, + /// Notify Unread Category Status immediately + CMD_ID_NTF_UNREAD_CAT_STATUS_IMM, + + CMD_ID_NB, +}; + +/// Characteristic Codes +enum +{ + /// Supported New Alert Category Characteristic + ANS_SUPP_NEW_ALERT_CAT_CHAR, + /// New Alert Characteristic + ANS_NEW_ALERT_CHAR, + /// Supported Unread Alert Category Characteristic + ANS_SUPP_UNREAD_ALERT_CAT_CHAR, + /// Unread Alert Status Characteristic + ANS_UNREAD_ALERT_STATUS_CHAR, + /// Alert Notification Control Point Characteristic + ANS_ALERT_NTF_CTNL_PT_CHAR, + + ANS_CHAR_MAX, +}; + +/// Alert codes +enum anp_alert_codes +{ + /// New Alert + ANP_NEW_ALERT = 0, + ANP_UNREAD_ALERT, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Alert Category ID Bit Mask Structure +struct anp_cat_id_bit_mask +{ + /// Category ID Bit Mask 0 + uint8_t cat_id_mask_0; + /// Category ID Bit Mask 1 + uint8_t cat_id_mask_1; +}; + +/// New Alert Characteristic Value Structure +struct anp_new_alert +{ + /// Information String Length + uint8_t info_str_len; + + /// Category ID + uint8_t cat_id; + /// Number of alerts + uint8_t nb_new_alert; + /// Text String Information + uint8_t str_info[1]; +}; + +/// Unread Alert Characteristic Value Structure +struct anp_unread_alert +{ + /// Category ID + uint8_t cat_id; + /// Number of alert + uint8_t nb_unread_alert; +}; + +/// Alert Notification Control Point Characteristic Value Structure +struct anp_ctnl_pt +{ + /// Command ID + uint8_t cmd_id; + /// Category ID + uint8_t cat_id; +}; + +/// @} anp_common + +#endif //(_ANP_COMMON_H_) diff --git a/services/ble_profiles/anp/anpc/api/anpc_task.h b/services/ble_profiles/anp/anpc/api/anpc_task.h new file mode 100644 index 0000000..fcb8eec --- /dev/null +++ b/services/ble_profiles/anp/anpc/api/anpc_task.h @@ -0,0 +1,223 @@ +#ifndef _ANPC_TASK_H_ +#define _ANPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup ANPCTASK Alert Notification Profile Client Task + * @ingroup ANPC + * @brief Alert Notification Profile Client Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" + +#include "anp_common.h" + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Message IDs +enum anpc_msg_ids +{ + /// Enable the Alert Notification Profile Client task - at connection + ANPC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_ANPC), + /// Enable the Alert Notification Profile Client task - at connection + ANPC_ENABLE_RSP, + + /// Read the value of an attribute in the peer device database + ANPC_READ_CMD, + /// Write the value of an attribute in the peer device database + ANPC_WRITE_CMD, + + /// Indicate that an attribute value has been received either upon notification or read response + ANPC_VALUE_IND, + + /// Complete Event Information + ANPC_CMP_EVT, +}; + +/// Operation Codes +enum anpc_op_codes +{ + /// Reserved operation code + ANPC_RESERVED_OP_CODE = 0x00, + + /** + * EXTERNAL OPERATION CODES + */ + + /// Discovery Procedure + ANPC_ENABLE_OP_CODE, + /// Read attribute value Procedure + ANPC_READ_OP_CODE, + /// Write attribute value Procedure + ANPC_WRITE_OP_CODE, + + /** + * INTERNAL OPERATION CODES + */ + + /// Discovery Procedure - Read Supported New Alert Category + ANPC_ENABLE_RD_NEW_ALERT_OP_CODE, + /// Discovery Procedure - Read Supported Unread Alert Category + ANPC_ENABLE_RD_UNREAD_ALERT_OP_CODE, + /// Discovery Procedure - Enable New Alert Categories for Notifications + ANPC_ENABLE_WR_NEW_ALERT_OP_CODE, + /// Discovery Procedure - Ask to be notified immediately for New Alert Values + ANPC_ENABLE_WR_NTF_NEW_ALERT_OP_CODE, + /// Discovery Procedure - Enable Unread Alert Categories for Notifications + ANPC_ENABLE_WR_UNREAD_ALERT_OP_CODE, + /// Discovery Procedure - Ask to be notified immediately for Unread Alert Values + ANPC_ENABLE_WR_NTF_UNREAD_ALERT_OP_CODE, +}; + +/// Alert Notification Service Characteristics +enum anpc_ans_chars +{ + /// Supported New Alert Category + ANPC_CHAR_SUP_NEW_ALERT_CAT, + /// New Alert + ANPC_CHAR_NEW_ALERT, + /// Supported Unread Alert Category + ANPC_CHAR_SUP_UNREAD_ALERT_CAT, + /// Unread Alert Status + ANPC_CHAR_UNREAD_ALERT_STATUS, + /// Alert Notification Control Point + ANPC_CHAR_ALERT_NTF_CTNL_PT, + + ANPC_CHAR_MAX, +}; + +/// Alert Notification Service Characteristic Descriptors +enum anpc_ans_descs +{ + /// New Alert Char. - Client Characteristic Configuration + ANPC_DESC_NEW_ALERT_CL_CFG, + /// Unread Alert Status Char. - Client Characteristic Configuration + ANPC_DESC_UNREAD_ALERT_STATUS_CL_CFG, + + ANPC_DESC_MAX, + + ANPC_DESC_MASK = 0x10, +}; + +/* + * API MESSAGE STRUCTURES + **************************************************************************************** + */ +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Alert Notification Service + */ +struct anpc_ans_content +{ + /// Service info + struct prf_svc svc; + + /// Characteristic info: + /// - Supported New Alert Category + /// - New Alert + /// - Supported Unread Alert Category + /// - Unread Alert Status + /// - Alert Notification Control Point + struct prf_char_inf chars[ANPC_CHAR_MAX]; + + /// Descriptor handles: + /// - New Alert Client Cfg + /// - Unread Alert Status Client Cfg + struct prf_char_desc_inf descs[ANPC_DESC_MAX]; +}; + +/// Parameters of the @ref ANPC_ENABLE_REQ message +struct anpc_enable_req +{ + /// Connection type + uint8_t con_type; + + /// New Alert Category to Enable for Notifications + struct anp_cat_id_bit_mask new_alert_enable; + /// Unread Alert Category to Enable for Notifications + struct anp_cat_id_bit_mask unread_alert_enable; + + /// Existing handle values ANS + struct anpc_ans_content ans; +}; + +/// Parameters of the @ref ANPC_ENABLE_RSP message +struct anpc_enable_rsp +{ + /// status + uint8_t status; + /// Existing handle values ANS + struct anpc_ans_content ans; +}; + +/// Parameters of the @ref ANPC_READ_CMD message +struct anpc_read_cmd +{ + /// Operation Code + uint8_t operation; + /// Read code + uint8_t read_code; +}; + +/// Parameters of the @ref ANPC_WRITE_CMD message +struct anpc_write_cmd +{ + /// Operation Code + uint8_t operation; + /// Write code + uint8_t write_code; + /// Value + union anpc_write_value_tag + { + /// Alert Notification Control Point + struct anp_ctnl_pt ctnl_pt; + /// New Alert Notification Configuration + uint16_t new_alert_ntf_cfg; + /// Unread Alert Status Notification Configuration + uint16_t unread_alert_status_ntf_cfg; + } value; +}; + +/// Parameters of the @ref ANPC_VALUE_IND message +struct anpc_value_ind +{ + /// Attribute Code + uint8_t att_code; + /// Value + union anpc_value_tag + { + /// List of supported categories + struct anp_cat_id_bit_mask supp_cat; + /// New Alert + struct anp_new_alert new_alert; + /// Unread Alert + struct anp_unread_alert unread_alert; + /// Client Characteristic Configuration Descriptor Value + uint16_t ntf_cfg; + } value; +}; + +/// Parameters of the @ref ANPC_CMP_EVT message +struct anpc_cmp_evt +{ + /// Operation code + uint8_t operation; + /// Status + uint8_t status; +}; + +/// @} ANPCTASK + +#endif //(_ANPC_TASK_H_) diff --git a/services/ble_profiles/anp/anpc/src/anpc.c b/services/ble_profiles/anp/anpc/src/anpc.c new file mode 100644 index 0000000..a9d2f69 --- /dev/null +++ b/services/ble_profiles/anp/anpc/src/anpc.c @@ -0,0 +1,258 @@ +/** + **************************************************************************************** + * @addtogroup ANPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_AN_CLIENT) + +#include "anp_common.h" +#include "anpc.h" +#include "anpc_task.h" + +#include "ke_mem.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the ANPC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t anpc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct anpc_env_tag* anpc_env = + (struct anpc_env_tag* ) ke_malloc(sizeof(struct anpc_env_tag), KE_MEM_ATT_DB); + + // allocate ANPC required environment variable + env->env = (prf_env_t*) anpc_env; + + anpc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + anpc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_ANPC; + anpc_task_init(&(env->desc)); + + for(idx = 0; idx < ANPC_IDX_MAX ; idx++) + { + anpc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), ANPC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void anpc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct anpc_env_tag* anpc_env = (struct anpc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(anpc_env->env[conidx] != NULL) + { + ke_free(anpc_env->env[conidx]); + anpc_env->env[conidx] = NULL; + } + + /* Put ANP Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), ANPC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the ANPC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void anpc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct anpc_env_tag* anpc_env = (struct anpc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < ANPC_IDX_MAX ; idx++) + { + anpc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(anpc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void anpc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put ANP Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), ANPC_IDLE); +} + +/// ANPC Task interface required by profile manager +const struct prf_task_cbs anpc_itf = +{ + anpc_init, + anpc_destroy, + anpc_create, + anpc_cleanup, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* anpc_prf_itf_get(void) +{ + return &anpc_itf; +} + +void anpc_enable_rsp_send(struct anpc_env_tag *anpc_env, uint8_t conidx, uint8_t status) +{ + // Send to APP the details of the discovered attributes on ANPS + struct anpc_enable_rsp * rsp = KE_MSG_ALLOC( + ANPC_ENABLE_RSP, + prf_dst_task_get(&(anpc_env->prf_env), conidx), + prf_src_task_get(&(anpc_env->prf_env), conidx), + anpc_enable_rsp); + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->ans = anpc_env->env[conidx]->ans; + // Register ANPC task in gatt for indication/notifications + prf_register_atthdl2gatt(&(anpc_env->prf_env), conidx, &(anpc_env->env[conidx]->ans.svc)); + // Go to connected state + ke_state_set(prf_src_task_get(&(anpc_env->prf_env), conidx), ANPC_IDLE); + } + + ke_msg_send(rsp); +} + +bool anpc_found_next_alert_cat(struct anpc_env_tag *idx_env, uint8_t conidx, struct anp_cat_id_bit_mask cat_id) +{ + // Next Category Found ? + bool found = false; + + if (idx_env->env[conidx]->last_uuid_req < CAT_ID_HIGH_PRTY_ALERT) + { + // Look in the first part of the categories + while ((idx_env->env[conidx]->last_uuid_req < CAT_ID_HIGH_PRTY_ALERT) && (!found)) + { + if (((cat_id.cat_id_mask_0 >> idx_env->env[conidx]->last_uuid_req) & 1) == 1) + { + found = true; + } + + idx_env->env[conidx]->last_uuid_req++; + } + } + + if (idx_env->env[conidx]->last_uuid_req >= CAT_ID_HIGH_PRTY_ALERT) + { + // Look in the first part of the categories + while ((idx_env->env[conidx]->last_uuid_req < CAT_ID_NB) && (!found)) + { + if (((cat_id.cat_id_mask_1 >> (idx_env->env[conidx]->last_uuid_req - CAT_ID_HIGH_PRTY_ALERT)) & 1) == 1) + { + found = true; + } + + idx_env->env[conidx]->last_uuid_req++; + } + } + + return found; +} + +void anpc_write_alert_ntf_ctnl_pt(struct anpc_env_tag *idx_env, uint8_t conidx, uint8_t cmd_id, uint8_t cat_id) +{ + struct anp_ctnl_pt ctnl_pt = {cmd_id, cat_id}; + + // Send the write request + prf_gatt_write(&(idx_env->prf_env), conidx, + idx_env->env[conidx]->ans.chars[ANPC_CHAR_ALERT_NTF_CTNL_PT].val_hdl, + (uint8_t *)&ctnl_pt, sizeof(struct anp_ctnl_pt), GATTC_WRITE); +} + +void anpc_send_cmp_evt(struct anpc_env_tag *anpc_env, uint8_t conidx, uint8_t operation, uint8_t status) +{ + if (anpc_env->env[conidx] != NULL) + { + // Free the stored operation if needed + if (anpc_env->env[conidx]->operation != NULL) + { + ke_msg_free(ke_param2msg(anpc_env->env[conidx]->operation)); + anpc_env->env[conidx]->operation = NULL; + } + } + + // Go back to the CONNECTED state if the state is busy + if (ke_state_get(prf_src_task_get(&(anpc_env->prf_env), conidx)) == ANPC_BUSY) + { + ke_state_set(prf_src_task_get(&anpc_env->prf_env, conidx), ANPC_IDLE); + } + + // Send the message + struct anpc_cmp_evt *evt = KE_MSG_ALLOC(ANPC_CMP_EVT, + prf_dst_task_get(&(anpc_env->prf_env), conidx), + prf_src_task_get(&(anpc_env->prf_env), conidx), + anpc_cmp_evt); + + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + +#endif //(BLE_AN_CLIENT) + +/// @} ANPC diff --git a/services/ble_profiles/anp/anpc/src/anpc.h b/services/ble_profiles/anp/anpc/src/anpc.h new file mode 100644 index 0000000..485f63e --- /dev/null +++ b/services/ble_profiles/anp/anpc/src/anpc.h @@ -0,0 +1,182 @@ +#ifndef _ANPC_H_ +#define _ANPC_H_ + +/** + **************************************************************************************** + * @addtogroup ANPC Alert Notification Profile Client + * @ingroup ANP + * @brief Phone Alert Notification Profile Client + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_AN_CLIENT) +#include "anp_common.h" +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "anpc_task.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of Alert Notification Client task instances +#define ANPC_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the ANPC task +enum anpc_states +{ + /// Free state + ANPC_FREE, + /// Idle state + ANPC_IDLE, + /// Connected state + ANPC_DISCOVERING, + /// Busy state + ANPC_BUSY, + + /// Number of defined states. + ANPC_STATE_MAX +}; + +/// Codes for reading/writing a ANS characteristic with one single request +enum anpc_rd_wr_ntf_codes +{ + /// Read ANS Supported New Alert Category + ANPC_RD_SUP_NEW_ALERT_CAT = ANPC_CHAR_SUP_NEW_ALERT_CAT, + /// NTF New Alert + ANPC_NTF_NEW_ALERT = ANPC_CHAR_NEW_ALERT, + /// Read ANS Supported Unread Alert Category + ANPC_RD_SUP_UNREAD_ALERT_CAT = ANPC_CHAR_SUP_UNREAD_ALERT_CAT, + /// NTF Unread Alert Categories + ANPC_NTF_UNREAD_ALERT = ANPC_CHAR_UNREAD_ALERT_STATUS, + /// Write ANS Alert Notification Control Point + ANPC_WR_ALERT_NTF_CTNL_PT = ANPC_CHAR_ALERT_NTF_CTNL_PT, + + /// Read/Write ANS New Alert Client Characteristic Configuration Descriptor + ANPC_RD_WR_NEW_ALERT_CFG = (ANPC_DESC_NEW_ALERT_CL_CFG | ANPC_DESC_MASK), + /// Read ANS Unread Alert Status Client Characteristic Configuration Descriptor + ANPC_RD_WR_UNREAD_ALERT_STATUS_CFG = (ANPC_DESC_UNREAD_ALERT_STATUS_CL_CFG | ANPC_DESC_MASK), +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + + +/// Command Message Basic Structure +struct anpc_cmd +{ + /// Operation Code + uint8_t operation; + + /// MORE DATA +}; + +struct anpc_cnx_env +{ + /// Last requested UUID(to keep track of the two services and char) + uint16_t last_uuid_req; + /// Last characteristic code used in a read or a write request + uint16_t last_char_code; + /// Counter used to check service uniqueness + uint8_t nb_svc; + /// Current operation code + void *operation; + /// Phone Alert Status Service Characteristics + struct anpc_ans_content ans; +}; + +/// Alert Notification Profile Client environment variable +struct anpc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct anpc_cnx_env* env[ANPC_IDX_MAX]; + /// State of different task instances + ke_state_t state[ANPC_IDX_MAX]; +}; + +/* + * GLOBAL FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Send Alert Notification ATT DB discovery results to ANPC host. + * @param[in] paspc_env environment variable + * @param[in] conidx Connection index + * @param[in] status Satus + **************************************************************************************** + */ +void anpc_enable_rsp_send(struct anpc_env_tag *anpc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Initialization of the ANPC module. + * This function performs all the initializations of the ANPC module. + **************************************************************************************** + */ +bool anpc_found_next_alert_cat(struct anpc_env_tag *idx_env, uint8_t conidx, + struct anp_cat_id_bit_mask cat_id); + +/** + **************************************************************************************** + * @brief Initialization of the ANPC module. + * This function performs all the initializations of the ANPC module. + **************************************************************************************** + */ +void anpc_write_alert_ntf_ctnl_pt(struct anpc_env_tag *idx_env, uint8_t conidx, + uint8_t cmd_id, uint8_t cat_id); + +/** + **************************************************************************************** + * @brief Send a ANPC_CMP_EVT message to the task which enabled the profile + **************************************************************************************** + */ +void anpc_send_cmp_evt(struct anpc_env_tag *anpc_env, uint8_t conidx, uint8_t operation, uint8_t status); + +/** + **************************************************************************************** + * @brief Retrieve ANP client profile interface + * @return ANP client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* anpc_prf_itf_get(void); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void anpc_task_init(struct ke_task_desc *task_desc); + +#endif //(BLE_AN_CLIENT) + +/// @} ANPC + +#endif //(_ANPC_H_) diff --git a/services/ble_profiles/anp/anpc/src/anpc_task.c b/services/ble_profiles/anp/anpc/src/anpc_task.c new file mode 100644 index 0000000..7dac6bf --- /dev/null +++ b/services/ble_profiles/anp/anpc/src/anpc_task.c @@ -0,0 +1,872 @@ +/** + **************************************************************************************** + * @addtogroup ANPCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_AN_CLIENT) +#include "anp_common.h" + +#include "gap.h" +#include "anpc.h" +#include "anpc_task.h" +#include "gattm_task.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// State machine used to retrieve Alert Notification service characteristics information +const struct prf_char_def anpc_ans_char[ANPC_CHAR_MAX] = +{ + /// Supported New Alert Category + [ANPC_CHAR_SUP_NEW_ALERT_CAT] = {ATT_CHAR_SUP_NEW_ALERT_CAT, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, + /// New Alert + [ANPC_CHAR_NEW_ALERT] = {ATT_CHAR_NEW_ALERT, + ATT_MANDATORY, + ATT_CHAR_PROP_NTF}, + /// Supported Unread Alert Category + [ANPC_CHAR_SUP_UNREAD_ALERT_CAT] = {ATT_CHAR_SUP_UNREAD_ALERT_CAT, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, + /// Unread Alert Status + [ANPC_CHAR_UNREAD_ALERT_STATUS] = {ATT_CHAR_UNREAD_ALERT_STATUS, + ATT_MANDATORY, + ATT_CHAR_PROP_NTF}, + /// Alert Notification Control Point + [ANPC_CHAR_ALERT_NTF_CTNL_PT] = {ATT_CHAR_ALERT_NTF_CTNL_PT, + ATT_MANDATORY, + ATT_CHAR_PROP_WR}, +}; + +/// State machine used to retrieve Phone Alert Status service characteristic descriptor information +const struct prf_char_desc_def anpc_ans_char_desc[ANPC_DESC_MAX] = +{ + /// New Alert Char. - Client Characteristic Configuration + [ANPC_DESC_NEW_ALERT_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_MANDATORY, + ANPC_CHAR_NEW_ALERT}, + /// Unread Alert Status Char. - Client Characteristic Configuration + [ANPC_DESC_UNREAD_ALERT_STATUS_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_MANDATORY, + ANPC_CHAR_UNREAD_ALERT_STATUS}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref ANPC_ENABLE_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int anpc_enable_req_handler(ke_msg_id_t const msgid, + struct anpc_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Phone Alert Status Profile Client Role Task Environment + struct anpc_env_tag *anpc_env = PRF_ENV_GET(ANPC, anpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if ((state == ANPC_IDLE) && (anpc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + anpc_env->env[conidx] = (struct anpc_cnx_env*) ke_malloc(sizeof(struct anpc_cnx_env),KE_MEM_ATT_DB); + memset(anpc_env->env[conidx], 0, sizeof(struct anpc_cnx_env)); + + anpc_env->env[conidx]->last_char_code = ANPC_ENABLE_OP_CODE; + + // Start discovering + if (param->con_type == PRF_CON_DISCOVERY) + { + prf_disc_svc_send(&(anpc_env->prf_env), conidx, ATT_SVC_ALERT_NTF); + + // Go to DISCOVERING state + ke_state_set(dest_id, ANPC_DISCOVERING); + + // Configure the environment for a discovery procedure + anpc_env->env[conidx]->last_uuid_req = ATT_SVC_ALERT_NTF; + } + // Bond information is provided + else + { + // Keep the provided database content + memcpy(&anpc_env->env[conidx]->ans, ¶m->ans, sizeof(struct anpc_ans_content)); + + //send APP confirmation that can start normal connection to TH + anpc_enable_rsp_send(anpc_env, conidx, GAP_ERR_NO_ERROR); + } + } + + else if (state != ANPC_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + anpc_enable_rsp_send(anpc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref ANPC_READ_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int anpc_read_cmd_handler(ke_msg_id_t const msgid, + struct anpc_read_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct anpc_env_tag *anpc_env = PRF_ENV_GET(ANPC, anpc); + + if (anpc_env->env[conidx] != NULL) + { + // Attribute Handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + // Check the provided connection handle + do + { + // Check the current state + if (ke_state_get(dest_id) == ANPC_BUSY) + { + // Keep the request for later, status is GAP_ERR_NO_ERROR + msg_status = KE_MSG_SAVED; + break; + } + + switch (param->read_code) + { + // Read Supported New Alert + case (ANPC_RD_SUP_NEW_ALERT_CAT): + { + handle = anpc_env->env[conidx]->ans.chars[ANPC_CHAR_SUP_NEW_ALERT_CAT].val_hdl; + } break; + + // Read Supported Unread Alert + case (ANPC_RD_SUP_UNREAD_ALERT_CAT): + { + handle = anpc_env->env[conidx]->ans.chars[ANPC_CHAR_SUP_UNREAD_ALERT_CAT].val_hdl; + } break; + + // Read New Alert Characteristic Client Char. Cfg. Descriptor Value + case (ANPC_RD_WR_NEW_ALERT_CFG): + { + handle = anpc_env->env[conidx]->ans.descs[ANPC_DESC_NEW_ALERT_CL_CFG].desc_hdl; + } break; + + // Read Unread Alert Characteristic Client Char. Cfg. Descriptor Value + case (ANPC_RD_WR_UNREAD_ALERT_STATUS_CFG): + { + handle = anpc_env->env[conidx]->ans.descs[ANPC_DESC_UNREAD_ALERT_STATUS_CL_CFG].desc_hdl; + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + + // Check if handle is viable + if ((handle != ATT_INVALID_SEARCH_HANDLE) && + (status == GAP_ERR_NO_ERROR)) + { + // Force the operation value + param->operation = ANPC_READ_OP_CODE; + + // Store the command structure + anpc_env->env[conidx]->operation = param; + msg_status = KE_MSG_NO_FREE; + + // Send the read request + prf_read_char_send(&(anpc_env->prf_env), conidx, + anpc_env->env[conidx]->ans.svc.shdl, + anpc_env->env[conidx]->ans.svc.ehdl, + handle); + + // Go to the Busy state + ke_state_set(dest_id, ANPC_BUSY); + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + }while(0); + + if (status != GAP_ERR_NO_ERROR) + { + anpc_send_cmp_evt(anpc_env, conidx, ANPC_READ_OP_CODE, status); + } + } + else + { + // No connection exists + anpc_send_cmp_evt(anpc_env, conidx, ANPC_READ_OP_CODE, PRF_ERR_REQ_DISALLOWED); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref ANPC_WRITE_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int anpc_write_cmd_handler(ke_msg_id_t const msgid, + struct anpc_write_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + // Get the address of the environment + struct anpc_env_tag *anpc_env = PRF_ENV_GET(ANPC, anpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (anpc_env->env[conidx] != NULL) + { + do + { + // Check the current state + if (ke_state_get(dest_id) != ANPC_IDLE) + { + msg_status = KE_MSG_SAVED; + break; + } + // Attribute handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + // Length + uint8_t length; + + switch (param->write_code) + { + // Write Alert Notification Control Point Characteristic Value + case (ANPC_WR_ALERT_NTF_CTNL_PT): + { + // Check the Category ID and the Command ID + if ((param->value.ctnl_pt.cmd_id < CMD_ID_NB) && + ((param->value.ctnl_pt.cat_id < CAT_ID_NB) || (param->value.ctnl_pt.cat_id == CAT_ID_ALL_SUPPORTED_CAT))) + { + handle = anpc_env->env[conidx]->ans.chars[ANPC_CHAR_ALERT_NTF_CTNL_PT].val_hdl; + length = sizeof(struct anp_ctnl_pt); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + // Write New Alert Characteristic Client Char. Cfg. Descriptor Value + case (ANPC_RD_WR_NEW_ALERT_CFG): + { + if (param->value.new_alert_ntf_cfg <= PRF_CLI_START_NTF) + { + handle = anpc_env->env[conidx]->ans.descs[ANPC_DESC_NEW_ALERT_CL_CFG].desc_hdl; + length = sizeof(uint16_t); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + // Write Unread Alert Status Characteristic Client Char. Cfg. Descriptor Value + case (ANPC_RD_WR_UNREAD_ALERT_STATUS_CFG): + { + if (param->value.unread_alert_status_ntf_cfg <= PRF_CLI_START_NTF) + { + handle = anpc_env->env[conidx]->ans.descs[ANPC_DESC_UNREAD_ALERT_STATUS_CL_CFG].desc_hdl; + length = sizeof(uint16_t); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + + if (status == GAP_ERR_NO_ERROR) + { + // Check if handle is viable + if (handle != ATT_INVALID_SEARCH_HANDLE) + { + // Send the write request + prf_gatt_write(&(anpc_env->prf_env), conidx, handle, + (uint8_t *)¶m->value, length, GATTC_WRITE); + + // Force the operation value + param->operation = ANPC_WRITE_OP_CODE; + // Store the command structure + anpc_env->env[conidx]->operation = param; + + msg_status = KE_MSG_NO_FREE; + + // Go to the Busy state + ke_state_set(dest_id, ANPC_BUSY); + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + }while(0); + } + else + { + status = PRF_ERR_REQ_DISALLOWED; + } + + if (status != GAP_ERR_NO_ERROR) + { + anpc_send_cmp_evt(anpc_env, conidx, ANPC_WRITE_OP_CODE, status); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct anpc_env_tag *anpc_env = PRF_ENV_GET(ANPC, anpc); + uint8_t conidx = KE_IDX_GET(dest_id); + // Status + uint8_t status; + + + if (anpc_env->env[conidx] != NULL) + { + uint8_t state = ke_state_get(dest_id); + + if (state == ANPC_DISCOVERING) + { + status = param->status; + + if ((status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || + (status == ATT_ERR_NO_ERROR)) + { + // Discovery + // check characteristic validity + if(anpc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(ANPC_CHAR_MAX, + anpc_env->env[conidx]->ans.chars, + anpc_ans_char); + } + // too much services + else if (anpc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if (status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(ANPC_DESC_MAX, + anpc_env->env[conidx]->ans.descs, + anpc_ans_char_desc, + anpc_env->env[conidx]->ans.chars); + } + } + + anpc_enable_rsp_send(anpc_env, conidx, status); + } + + else if (state == ANPC_BUSY) + { + switch (param->operation) + { + case GATTC_READ: + { + switch (((struct anpc_cmd *)anpc_env->env[conidx]->operation)->operation) + { + // Read Supported New Alert Category Characteristic value + case (ANPC_ENABLE_RD_NEW_ALERT_OP_CODE): + { + if (param->status == GAP_ERR_NO_ERROR) + { + // Force the operation value + ((struct anpc_cmd *)anpc_env->env[conidx]->operation)->operation = ANPC_ENABLE_RD_UNREAD_ALERT_OP_CODE; + // Check Supported Unread Alert Category + prf_read_char_send(&(anpc_env->prf_env), conidx, + anpc_env->env[conidx]->ans.svc.shdl, anpc_env->env[conidx]->ans.svc.ehdl, + anpc_env->env[conidx]->ans.chars[ANPC_CHAR_SUP_UNREAD_ALERT_CAT].val_hdl); + } + else + { + anpc_send_cmp_evt(anpc_env, conidx, ANPC_ENABLE_OP_CODE, param->status); + } + } break; + + case (ANPC_ENABLE_RD_UNREAD_ALERT_OP_CODE): + { + if (param->status == GAP_ERR_NO_ERROR) + { + // If peer device was unknown, stop the procedure + if (((struct anpc_enable_req *)anpc_env->env[conidx]->operation)->con_type == PRF_CON_DISCOVERY) + { + anpc_send_cmp_evt(anpc_env, conidx, ANPC_ENABLE_OP_CODE, GAP_ERR_NO_ERROR); + } + // If peer device was already known (bonded), start Recovery from Connection Loss procedure + else + { + // Reset the environment + anpc_env->env[conidx]->last_uuid_req = CAT_ID_SPL_ALERT; + + if (anpc_found_next_alert_cat(anpc_env, conidx, ((struct anpc_enable_req *)anpc_env->env[conidx]->operation)->new_alert_enable)) + { + // Force the operation value + ((struct anpc_cmd *)anpc_env->env[conidx]->operation)->operation = ANPC_ENABLE_WR_NEW_ALERT_OP_CODE; + // Enable sending of notifications for the found category ID + anpc_write_alert_ntf_ctnl_pt(anpc_env, conidx, CMD_ID_EN_NEW_IN_ALERT_NTF, anpc_env->env[conidx]->last_uuid_req - 1); + } + else + { + // Reset the environment + anpc_env->env[conidx]->last_uuid_req = CAT_ID_SPL_ALERT; + + if (anpc_found_next_alert_cat(anpc_env, conidx, ((struct anpc_enable_req *)anpc_env->env[conidx]->operation)->unread_alert_enable)) + { + // Force the operation value + ((struct anpc_cmd *)anpc_env->env[conidx]->operation)->operation = ANPC_ENABLE_WR_UNREAD_ALERT_OP_CODE; + // Enable sending of notifications for the found category ID + anpc_write_alert_ntf_ctnl_pt(anpc_env, conidx, CMD_ID_EN_UNREAD_CAT_STATUS_NTF, anpc_env->env[conidx]->last_uuid_req - 1); + } + else + { + anpc_send_cmp_evt(anpc_env, conidx, ANPC_ENABLE_OP_CODE, GAP_ERR_NO_ERROR); + } + } + } + } + else + { + anpc_send_cmp_evt(anpc_env, conidx, ANPC_ENABLE_OP_CODE, param->status); + } + } break; + + case (ANPC_READ_OP_CODE): + { + // Inform the requester that the read procedure is over + anpc_send_cmp_evt(anpc_env, conidx, ANPC_READ_OP_CODE, param->status); + } break; + + default: + { + ASSERT_ERR(0); + } + } + } break; + + case GATTC_WRITE: + case GATTC_WRITE_NO_RESPONSE: + { + // Retrieve the operation currently performed + uint8_t operation = ((struct anpc_cmd *)anpc_env->env[conidx]->operation)->operation; + + switch (operation) + { + case (ANPC_WRITE_OP_CODE): + { + uint8_t wr_code = ((struct anpc_write_cmd *)anpc_env->env[conidx]->operation)->write_code; + + if ((wr_code == ANPC_RD_WR_NEW_ALERT_CFG) || + (wr_code == ANPC_RD_WR_UNREAD_ALERT_STATUS_CFG) || + (wr_code == ANPC_WR_ALERT_NTF_CTNL_PT)) + { + anpc_send_cmp_evt(anpc_env, conidx, ANPC_WRITE_OP_CODE, param->status); + } + else + { + ASSERT_ERR(0); + } + } break; + + case (ANPC_ENABLE_WR_NEW_ALERT_OP_CODE): + { + // Look for the next category to enable + if (anpc_found_next_alert_cat(anpc_env, conidx, ((struct anpc_enable_req *)anpc_env->env[conidx]->operation)->new_alert_enable)) + { + // Enable sending of notifications for the found category ID + anpc_write_alert_ntf_ctnl_pt(anpc_env, conidx, CMD_ID_EN_NEW_IN_ALERT_NTF, anpc_env->env[conidx]->last_uuid_req - 1); + } + else + { + // Force the operation value + ((struct anpc_cmd *)anpc_env->env[conidx]->operation)->operation = ANPC_ENABLE_WR_NTF_NEW_ALERT_OP_CODE; + // Send a "Notify New Alert Immediately" command with the Category ID field set to 0xFF + anpc_write_alert_ntf_ctnl_pt(anpc_env, conidx, CMD_ID_NTF_NEW_IN_ALERT_IMM, CAT_ID_ALL_SUPPORTED_CAT); + } + } break; + + case (ANPC_ENABLE_WR_NTF_NEW_ALERT_OP_CODE): + { + // Reset the environment + anpc_env->env[conidx]->last_uuid_req = CAT_ID_SPL_ALERT; + + if (anpc_found_next_alert_cat(anpc_env, conidx, ((struct anpc_enable_req *)anpc_env->env[conidx]->operation)->unread_alert_enable)) + { + // Force the operation value + ((struct anpc_cmd *)anpc_env->env[conidx]->operation)->operation = ANPC_ENABLE_WR_UNREAD_ALERT_OP_CODE; + // Enable sending of notifications for the found category ID + anpc_write_alert_ntf_ctnl_pt(anpc_env, conidx, CMD_ID_EN_UNREAD_CAT_STATUS_NTF, anpc_env->env[conidx]->last_uuid_req - 1); + } + else + { + anpc_send_cmp_evt(anpc_env, conidx, ANPC_ENABLE_OP_CODE, GAP_ERR_NO_ERROR); + } + } break; + + case (ANPC_ENABLE_WR_UNREAD_ALERT_OP_CODE): + { + // Look for the next category to enable + if (anpc_found_next_alert_cat(anpc_env, conidx, ((struct anpc_enable_req *)anpc_env->env[conidx]->operation)->unread_alert_enable)) + { + // Enable sending of notifications for the found category ID + anpc_write_alert_ntf_ctnl_pt(anpc_env, conidx, CMD_ID_EN_UNREAD_CAT_STATUS_NTF, anpc_env->env[conidx]->last_uuid_req - 1); + } + else + { + // Force the operation value + ((struct anpc_cmd *)anpc_env->env[conidx]->operation)->operation = ANPC_ENABLE_WR_NTF_UNREAD_ALERT_OP_CODE; + // Send a "Notify New Alert Immediately" command with the Category ID field set to 0xFF + anpc_write_alert_ntf_ctnl_pt(anpc_env, conidx, CMD_ID_NTF_UNREAD_CAT_STATUS_IMM, CAT_ID_ALL_SUPPORTED_CAT); + } + } break; + + case (ANPC_ENABLE_WR_NTF_UNREAD_ALERT_OP_CODE): + { + // The discovery procedure is over + anpc_send_cmp_evt(anpc_env, conidx, ANPC_ENABLE_OP_CODE, param->status); + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } break; + + case GATTC_REGISTER: + case GATTC_UNREGISTER: + { + // Do nothing + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + } + // else ignore the message + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == ANPC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct anpc_env_tag *anpc_env = PRF_ENV_GET(ANPC, anpc); + + ASSERT_INFO(anpc_env != NULL, dest_id, src_id); + ASSERT_INFO(anpc_env->env[conidx] != NULL, dest_id, src_id); + + if(anpc_env->env[conidx]->nb_svc == 0) + { + // Retrieve ANS characteristics and descriptors + prf_extract_svc_info(ind, ANPC_CHAR_MAX, &anpc_ans_char[0], &anpc_env->env[conidx]->ans.chars[0], + ANPC_DESC_MAX, &anpc_ans_char_desc[0], &anpc_env->env[conidx]->ans.descs[0]); + + //Even if we get multiple responses we only store 1 range + anpc_env->env[conidx]->ans.svc.shdl = ind->start_hdl; + anpc_env->env[conidx]->ans.svc.ehdl = ind->end_hdl; + } + + anpc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct anpc_env_tag *anpc_env = PRF_ENV_GET(ANPC, anpc); + uint8_t conidx = KE_IDX_GET(dest_id); + + if (anpc_env->env[conidx] != NULL) + { + ASSERT_ERR(ke_state_get(dest_id) == ANPC_BUSY); + + // Prepare the indication to send to the application + struct anpc_value_ind *ind = KE_MSG_ALLOC(ANPC_VALUE_IND, + prf_dst_task_get(&(anpc_env->prf_env), conidx), + dest_id, + anpc_value_ind); + + switch (((struct anpc_cmd *)anpc_env->env[conidx]->operation)->operation) + { + // Read Supported New Alert Category Characteristic value + case (ANPC_ENABLE_RD_NEW_ALERT_OP_CODE): + { + ind->att_code = ANPC_RD_SUP_NEW_ALERT_CAT; + ind->value.supp_cat.cat_id_mask_0 = param->value[0]; + // If cat_id_mask_1 not present, shall be considered as 0 + ind->value.supp_cat.cat_id_mask_1 = (param->length > 1) + ? param->value[1] : 0x00; + } break; + + case (ANPC_ENABLE_RD_UNREAD_ALERT_OP_CODE): + { + ind->att_code = ANPC_RD_SUP_UNREAD_ALERT_CAT; + ind->value.supp_cat.cat_id_mask_0 = param->value[0]; + // If cat_id_mask_1 not present, shall be considered as 0 + ind->value.supp_cat.cat_id_mask_1 = (param->length > 1) + ? param->value[1] : 0; + } break; + + case (ANPC_READ_OP_CODE): + { + ind->att_code = ((struct anpc_read_cmd *)anpc_env->env[conidx]->operation)->read_code; + ind->value.ntf_cfg = co_read16(¶m->value[0]); + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + + // Send the indication + ke_msg_send(ind); + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct anpc_env_tag *anpc_env = PRF_ENV_GET(ANPC, anpc); + uint8_t conidx = KE_IDX_GET(dest_id); + + if (anpc_env->env[conidx] != NULL) + { + // Check the category ID + if (param->value[0] < CAT_ID_NB) + { + // New Alert Characteristic Value + if (param->handle == anpc_env->env[conidx]->ans.chars[ANPC_CHAR_NEW_ALERT].val_hdl) + { + // Text String information Length + uint8_t length = param->length - 2; + + if (length > ANS_NEW_ALERT_STRING_INFO_MAX_LEN) + { + length = ANS_NEW_ALERT_STRING_INFO_MAX_LEN; + } + + // Send an indication to the application + struct anpc_value_ind *new_alert_ind = KE_MSG_ALLOC_DYN(ANPC_VALUE_IND, + prf_dst_task_get(&anpc_env->prf_env, conidx), + prf_src_task_get(&anpc_env->prf_env, conidx), + anpc_value_ind, + length); + + new_alert_ind->att_code = ANPC_NTF_NEW_ALERT; + + // Fulfill the characteristic value + new_alert_ind->value.new_alert.cat_id = param->value[0]; + new_alert_ind->value.new_alert.nb_new_alert = param->value[1]; + new_alert_ind->value.new_alert.info_str_len = length; + memcpy(&new_alert_ind->value.new_alert.str_info[0], ¶m->value[2], length); + + // Send the message + ke_msg_send(new_alert_ind); + } + // Unread Alert Status Characteristic Value + else if (param->handle == anpc_env->env[conidx]->ans.chars[ANPC_CHAR_UNREAD_ALERT_STATUS].val_hdl) + { + // Send an indication to the application + struct anpc_value_ind *unrd_alert_ind = KE_MSG_ALLOC(ANPC_VALUE_IND, + prf_dst_task_get(&anpc_env->prf_env, conidx), + prf_src_task_get(&anpc_env->prf_env, conidx), + anpc_value_ind); + + unrd_alert_ind->att_code = ANPC_NTF_UNREAD_ALERT; + + // Fulfill the characteristic value + unrd_alert_ind->value.unread_alert.cat_id = param->value[0]; + unrd_alert_ind->value.unread_alert.nb_unread_alert = param->value[1]; + + // Send the message + ke_msg_send(unrd_alert_ind); + } + else + { + ASSERT_ERR(0); + } + } + // else ignore the message + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(anpc) +{ + {ANPC_ENABLE_REQ, (ke_msg_func_t)anpc_enable_req_handler}, + {ANPC_READ_CMD, (ke_msg_func_t)anpc_read_cmd_handler}, + {ANPC_WRITE_CMD, (ke_msg_func_t)anpc_write_cmd_handler}, + + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void anpc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct anpc_env_tag *anpc_env = PRF_ENV_GET(ANPC, anpc); + + task_desc->msg_handler_tab = anpc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(anpc_msg_handler_tab); + task_desc->state = anpc_env->state; + task_desc->idx_max = ANPC_IDX_MAX; +} + + +#endif //(BLE_AN_CLIENT) + +/// @} ANPCTASK diff --git a/services/ble_profiles/anp/anps/api/anps_task.h b/services/ble_profiles/anp/anps/api/anps_task.h new file mode 100644 index 0000000..411e6de --- /dev/null +++ b/services/ble_profiles/anp/anps/api/anps_task.h @@ -0,0 +1,134 @@ +#ifndef ANPS_TASK_H_ +#define ANPS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup ANPSTASK Task + * @ingroup ANPS + * @brief Alert Notification Profile Server Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "rwip_task.h" // Task definitions +#include "anp_common.h" + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Messages for Alert Notification Profile Server +enum anps_msg_ids +{ + /// Start the Alert Notification Profile Server Role + ANPS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_ANPS), + /// Start the Alert Notification Profile Server Role + ANPS_ENABLE_RSP, + + /// Update the value of a characteristic + ANPS_NTF_ALERT_CMD, + /// The peer device requests to be notified about new alert values + ANPS_NTF_IMMEDIATE_REQ_IND, + /// Indicate that the notification configuration has been modified by the peer device + ANPS_NTF_STATUS_UPDATE_IND, + + /// Complete Event Information + ANPS_CMP_EVT, +}; + +/// Operation Codes +enum anps_op_codes +{ + ANPS_RESERVED_OP_CODE = 0x00, + + /// Update New Alert Char. value + ANPS_UPD_NEW_ALERT_OP_CODE, + /// Update Unread Alert Status Char. value + ANPS_UPD_UNREAD_ALERT_STATUS_OP_CODE, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Parameters of the @ref ANPS_CREATE_DB_REQ message +struct anps_db_cfg +{ + /// Supported New Alert Category Characteristic Value - Shall not be 0 + struct anp_cat_id_bit_mask supp_new_alert_cat; + /// Supported Unread Alert Category Characteristic Value - Can be 0 + struct anp_cat_id_bit_mask supp_unread_alert_cat; +}; + +/// Parameters of the @ref ANPS_ENABLE_REQ message +struct anps_enable_req +{ + /// New Alert Characteristic - Saved Client Characteristic Configuration Descriptor Value + uint16_t new_alert_ntf_cfg; + /// Unread Alert Status Characteristic - Saved Client Characteristic Configuration Descriptor Value + uint16_t unread_alert_status_ntf_cfg; +}; + +/// Parameters of the @ref ANPS_ENABLE_RSP message +struct anps_enable_rsp +{ + /// status + uint8_t status; +}; + +///Parameters of the @ref ANPS_NTF_ALERT_CMD message +struct anps_ntf_alert_cmd +{ + /// Operation Code (ANPS_UPD_NEW_ALERT_OP_CODE or ANPS_UPD_UNREAD_ALERT_STATUS_OP_CODE) + uint8_t operation; + /// New Alert Characteristic Value or Unread Alert Status Characteristic Value + union anps_value_tag + { + /// New Alert + struct anp_new_alert new_alert; + /// Unread Alert Status + struct anp_unread_alert unread_alert_status; + } value; +}; + +///Parameters of the @ref ANPS_NTF_IMMEDIATE_REQ_IND message +struct anps_ntf_immediate_req_ind +{ + /// Alert type (New Alert or Unread Alert Status) + uint8_t alert_type; + /// Status for each category + struct anp_cat_id_bit_mask cat_ntf_cfg; +}; + +///Parameters of the @ref ANPS_NTF_STATUS_UPDATE_IND message +struct anps_ntf_status_update_ind +{ + /// Alert type (New Alert or Unread Alert Status) + uint8_t alert_type; + /// Client Characteristic Configuration Descriptor Status + uint16_t ntf_ccc_cfg; + /// Status for each category + struct anp_cat_id_bit_mask cat_ntf_cfg; +}; + +///Parameters of the @ref ANPS_CMP_EVT message +struct anps_cmp_evt +{ + /// Operation + uint8_t operation; + /// Status + uint8_t status; +}; + +/// @} ANPSTASK + +#endif //(ANPS_TASK_H_) diff --git a/services/ble_profiles/anp/anps/src/anps.c b/services/ble_profiles/anp/anps/src/anps.c new file mode 100644 index 0000000..b89281c --- /dev/null +++ b/services/ble_profiles/anp/anps/src/anps.c @@ -0,0 +1,332 @@ +/** + **************************************************************************************** + * @addtogroup ANPS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_AN_SERVER) + +#include "anps.h" +#include "anps_task.h" +#include "anp_common.h" +#include "prf_utils.h" +#include "prf_types.h" + +#include "ke_mem.h" + +/* + * ANS DATABASE + **************************************************************************************** + */ + +/// Full ANS Database Description - Used to add attributes into the database +const struct attm_desc anps_att_db[ANS_IDX_NB] = +{ + /// Alert Notification Service Declaration + [ANS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + /// Supported New Alert Category Characteristic Declaration + [ANS_IDX_SUPP_NEW_ALERT_CAT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + /// Supported New Alert Category Characteristic Value + [ANS_IDX_SUPP_NEW_ALERT_CAT_VAL] = {ATT_CHAR_SUP_NEW_ALERT_CAT, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(struct anp_cat_id_bit_mask)}, + + /// New Alert Characteristic Declaration + [ANS_IDX_NEW_ALERT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + /// New Alert Characteristic Value + [ANS_IDX_NEW_ALERT_VAL] = {ATT_CHAR_NEW_ALERT, PERM(NTF, ENABLE), PERM(RI, ENABLE), ANS_NEW_ALERT_MAX_LEN}, + /// New Alert Characteristic - Client Char. Configuration Descriptor + [ANS_IDX_NEW_ALERT_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + /// Supported Unread Alert Category Characteristic Declaration + [ANS_IDX_SUPP_UNREAD_ALERT_CAT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + /// Supported New Alert Category Characteristic Value + [ANS_IDX_SUPP_UNREAD_ALERT_CAT_VAL] = {ATT_CHAR_SUP_UNREAD_ALERT_CAT, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(struct anp_cat_id_bit_mask)}, + + /// Unread Alert Status Characteristic Declaration + [ANS_IDX_UNREAD_ALERT_STATUS_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + /// Unread Alert Status Characteristic Value + [ANS_IDX_UNREAD_ALERT_STATUS_VAL] = {ATT_CHAR_UNREAD_ALERT_STATUS, PERM(NTF, ENABLE), PERM(RI, ENABLE), sizeof(struct anp_unread_alert)}, + /// Unread Alert Status Characteristic - Client Char. Configuration Descriptor + [ANS_IDX_UNREAD_ALERT_STATUS_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + /// Alert Notification Control Point Characteristic Declaration + [ANS_IDX_ALERT_NTF_CTNL_PT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + /// Alert Notification Control Point Characteristic Value + [ANS_IDX_ALERT_NTF_CTNL_PT_VAL] = {ATT_CHAR_ALERT_NTF_CTNL_PT, PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), 2*sizeof(uint8_t)}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the ANPS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t anps_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct anps_db_cfg* params) +{ + //------------------ create the attribute database for the profile ------------------- + // Service content flag + uint32_t cfg_flag = ANPS_DB_CONFIG_MASK; + // DB Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + // Add service in the database + status = attm_svc_create_db(start_hdl, ATT_SVC_ALERT_NTF, (uint8_t *)&cfg_flag, + ANS_IDX_NB, NULL, env->task, &anps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, ENABLE)); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // Allocate ANPS required environment variable + struct anps_env_tag* anps_env = + (struct anps_env_tag* ) ke_malloc(sizeof(struct anps_env_tag), KE_MEM_ATT_DB); + + // Initialize ANPS environment + env->env = (prf_env_t*) anps_env; + anps_env->shdl = *start_hdl; + + memcpy(&anps_env->supp_new_alert_cat, ¶ms->supp_new_alert_cat, sizeof(struct anp_cat_id_bit_mask)); + memcpy(&anps_env->supp_unread_alert_cat, ¶ms->supp_unread_alert_cat, sizeof(struct anp_cat_id_bit_mask)); + + anps_env->operation = ANPS_RESERVED_OP_CODE; + + anps_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Multi Instantiated task + anps_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_ANPS; + anps_task_init(&(env->desc)); + + for(uint8_t idx = 0; idx < BLE_CONNECTION_MAX ; idx++) + { + anps_env->env[idx] = NULL; + /* Put ANS in disabled state */ + ke_state_set(KE_BUILD_ID(env->task, idx), ANPS_FREE); + } + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the ANPS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void anps_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct anps_env_tag* anps_env = (struct anps_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < BLE_CONNECTION_MAX ; idx++) + { + if(anps_env->env[idx] != NULL) + { + ke_free(anps_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(anps_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void anps_create(struct prf_task_env* env, uint8_t conidx) +{ + struct anps_env_tag* anps_env = (struct anps_env_tag*) env->env; + anps_env->env[conidx] = (struct anps_cnx_env*) + ke_malloc(sizeof(struct anps_cnx_env), KE_MEM_ATT_DB); + + memset(anps_env->env[conidx], 0, sizeof(struct anps_cnx_env)); + /* Put ANS in idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), ANPS_IDLE); + +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void anps_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct anps_env_tag* anps_env = (struct anps_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(anps_env->env[conidx] != NULL) + { + ke_free(anps_env->env[conidx]); + anps_env->env[conidx] = NULL; + } + + /* Put ANS in disabled state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), ANPS_FREE); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// ANPS Task interface required by profile manager +const struct prf_task_cbs anps_itf = +{ + (prf_init_fnct) anps_init, + anps_destroy, + anps_create, + anps_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* anps_prf_itf_get(void) +{ + return &anps_itf; +} + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +void anps_send_cmp_evt(ke_task_id_t src_id, ke_task_id_t dest_id, + uint8_t operation, uint8_t status) +{ + // Come back to the Connected state if the state was busy. + if (ke_state_get(src_id) == ANPS_BUSY) + { + ke_state_set(src_id, ANPS_IDLE); + } + + // Send the message to the application + struct anps_cmp_evt *evt = KE_MSG_ALLOC(ANPS_CMP_EVT, + dest_id, src_id, + anps_cmp_evt); + + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + +void anps_send_ntf_status_update_ind(uint8_t conidx, struct anps_env_tag *idx_env, uint8_t alert_type) +{ + // Send the message to the application + struct anps_ntf_status_update_ind *ind = KE_MSG_ALLOC(ANPS_NTF_STATUS_UPDATE_IND, + prf_dst_task_get(&idx_env->prf_env, conidx), + prf_src_task_get(&idx_env->prf_env, conidx), + anps_ntf_status_update_ind); + + ind->alert_type = alert_type; + ind->ntf_ccc_cfg = ANPS_IS_ALERT_ENABLED(conidx, idx_env, alert_type) ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; + + if (alert_type == ANP_NEW_ALERT) + { + ind->cat_ntf_cfg.cat_id_mask_0 = (uint8_t)(idx_env->env[conidx]->ntf_new_alert_cfg & 0x00FF); + ind->cat_ntf_cfg.cat_id_mask_1 = (uint8_t)((idx_env->env[conidx]->ntf_new_alert_cfg & 0xFF00) >> 8); + } + else + { + ind->cat_ntf_cfg.cat_id_mask_0 = (uint8_t)(idx_env->env[conidx]->ntf_unread_alert_cfg & 0x00FF); + ind->cat_ntf_cfg.cat_id_mask_1 = (uint8_t)(idx_env->env[conidx]->ntf_unread_alert_cfg >> 8); + } + + ke_msg_send(ind); +} + +void anps_send_ntf_immediate_req_ind(uint8_t conidx, struct anps_env_tag *idx_env, uint8_t alert_type, + uint8_t category_id) +{ + uint16_t req_cat; + + // Send the message to the application + struct anps_ntf_immediate_req_ind *ind = KE_MSG_ALLOC(ANPS_NTF_IMMEDIATE_REQ_IND, + prf_dst_task_get(&idx_env->prf_env, conidx), + prf_src_task_get(&idx_env->prf_env, conidx), + anps_ntf_immediate_req_ind); + + ind->alert_type = alert_type; + + if (alert_type == ANP_NEW_ALERT) + { + if (category_id == CAT_ID_ALL_SUPPORTED_CAT) + { + // All category that are supported and enabled shall be notified + req_cat = idx_env->env[conidx]->ntf_new_alert_cfg; + } + else + { + req_cat = (1 << category_id); + } + } + else // Unread alert + { + if (category_id == CAT_ID_ALL_SUPPORTED_CAT) + { + // All category that are supported and enabled shall be notified + req_cat = idx_env->env[conidx]->ntf_unread_alert_cfg; + } + else + { + req_cat = (1 << category_id); + } + } + + ind->cat_ntf_cfg.cat_id_mask_0 = (uint8_t)(req_cat & 0x00FF); + ind->cat_ntf_cfg.cat_id_mask_1 = (uint8_t)((req_cat & 0xFF00) >> 8); + + ke_msg_send(ind); +} + +#endif //(BLE_AN_SERVER) + +/// @} ANPS diff --git a/services/ble_profiles/anp/anps/src/anps.h b/services/ble_profiles/anp/anps/src/anps.h new file mode 100644 index 0000000..65f8633 --- /dev/null +++ b/services/ble_profiles/anp/anps/src/anps.h @@ -0,0 +1,249 @@ +#ifndef ANPS_H_ +#define ANPS_H_ + +/** + **************************************************************************************** + * @addtogroup ANPS Alert Notification Profile Server + * @ingroup ANP + * @brief Alert Notification Profile Server + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "anp_common.h" + +#if (BLE_AN_SERVER) + +#include "prf_types.h" +#include "prf.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximal number of Alert Notification Server task instances +#define ANPS_IDX_MAX (BLE_CONNECTION_MAX) +/// Database Configuration Flag +#define ANPS_DB_CONFIG_MASK (0x1FFF) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the ANPS task +enum anps_states +{ + /// Not connected state + ANPS_FREE, + /// Idle state + ANPS_IDLE, + /// Busy state + ANPS_BUSY, + + /// Number of defined states. + ANPS_STATE_MAX +}; +/// Alert Notification Service Attributes +enum anps_ans_att_list +{ + ANS_IDX_SVC, + + ANS_IDX_SUPP_NEW_ALERT_CAT_CHAR, + ANS_IDX_SUPP_NEW_ALERT_CAT_VAL, + + ANS_IDX_NEW_ALERT_CHAR, + ANS_IDX_NEW_ALERT_VAL, + ANS_IDX_NEW_ALERT_CFG, + + ANS_IDX_SUPP_UNREAD_ALERT_CAT_CHAR, + ANS_IDX_SUPP_UNREAD_ALERT_CAT_VAL, + + ANS_IDX_UNREAD_ALERT_STATUS_CHAR, + ANS_IDX_UNREAD_ALERT_STATUS_VAL, + ANS_IDX_UNREAD_ALERT_STATUS_CFG, + + ANS_IDX_ALERT_NTF_CTNL_PT_CHAR, + ANS_IDX_ALERT_NTF_CTNL_PT_VAL, + + ANS_IDX_NB, +}; + + +/* + * MACROS + * ************************************************************************************** + */ + +#define ANPS_IS_NEW_ALERT_CATEGORY_SUPPORTED(category_id) \ + (((anps_env->supp_new_alert_cat >> category_id) & 1) == 1) + +#define ANPS_IS_UNREAD_ALERT_CATEGORY_SUPPORTED(category_id) \ + (((anps_env->supp_unread_alert_cat >> category_id) & 1) == 1) + +#define ANPS_IS_ALERT_ENABLED(conidx, idx_env, alert_type) \ + (((idx_env->env[conidx]->ntf_cfg >> alert_type) & 1) == 1) + +#define ANPS_IS_NEW_ALERT_CATEGORY_ENABLED(conidx, category_id, idx_env) \ + (((idx_env->env[conidx]->ntf_new_alert_cfg >> category_id) & 1) == 1) + +#define ANPS_IS_UNREAD_ALERT_CATEGORY_ENABLED(conidx, category_id, idx_env) \ + (((idx_env->env[conidx]->ntf_unread_alert_cfg >> category_id) & 1) == 1) + +#define ANPS_ENABLE_ALERT(conidx, idx_env, alert_type) \ + (idx_env->env[conidx]->ntf_cfg |= (1 << alert_type)) + +#define ANPS_DISABLE_ALERT(conidx, idx_env, alert_type) \ + (idx_env->env[conidx]->ntf_cfg &= ~(1 << alert_type)) + +#define ANPS_ENABLE_NEW_ALERT_CATEGORY(conidx, category_id, idx_env) \ + (idx_env->env[conidx]->ntf_new_alert_cfg |= (1 << category_id)) + +#define ANPS_ENABLE_UNREAD_ALERT_CATEGORY(conidx, category_id, idx_env) \ + (idx_env->env[conidx]->ntf_unread_alert_cfg |= (1 << category_id)) + +#define ANPS_DISABLE_NEW_ALERT_CATEGORY(conidx, category_id, idx_env) \ + (idx_env->env[conidx]->ntf_new_alert_cfg &= ~(1 << category_id)) + +#define ANPS_DISABLE_UNREAD_ALERT_CATEGORY(conidx, category_id, idx_env) \ + (idx_env->env[conidx]->ntf_unread_alert_cfg &= ~(1 << category_id)) + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Alert Notification Profile Server Connection Dependent Environment Variable +struct anps_cnx_env +{ + /** + * Client Characteristic Configuration Status + * Bit 0 : New Alert Characteristic + * Bit 1 : Unread Alert Status Characteristic + */ + uint8_t ntf_cfg; + + /** + * Category Notification Configuration + * Bit 0 : Simple Alert + * Bit 1 : Email + * Bit 2 : News + * Bit 3 : Call + * Bit 4 : Missed Call + * Bit 5 : SMS/MMS + * Bit 6 : Voice Mail + * Bit 7 : Schedule + * Bit 8 : High Prioritized Alert + * Bit 9 : Instance Message + */ + uint16_t ntf_new_alert_cfg; + uint16_t ntf_unread_alert_cfg; +}; + +/// Alert Notification Profile Server. Environment variable +struct anps_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// ANS Start Handle + uint16_t shdl; + /// Environment variable pointer for each connection + struct anps_cnx_env* env[BLE_CONNECTION_MAX]; + + /// Current Operation Code + uint8_t operation; + /// Supported New Alert Category Characteristic Value + uint16_t supp_new_alert_cat; + /// Supported Unread Alert Category Characteristic Value + uint16_t supp_unread_alert_cat; + + /// State of different task instances + ke_state_t state[ANPS_IDX_MAX]; + +}; + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve ANP service profile interface + * + * @return ANP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* anps_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Initialization of the ANPS module. + * This function performs all the initializations of the ANPS module. + **************************************************************************************** + */ +//void anps_init(void); + +/** + **************************************************************************************** + * @brief Send an ANPS_NTF_STATUS_UPDATE_IND message to a requester. + * + * @param[in] src_id Source ID of the message (instance of TASK_ANPS) + * @param[in] dest_id Destination ID of the message + * @param[in] operation Code of the completed operation + * @param[in] status Status of the request + **************************************************************************************** + */ +void anps_send_ntf_status_update_ind(uint8_t conidx, struct anps_env_tag *idx_env, uint8_t alert_type); + +/** + **************************************************************************************** + * @brief Send an ANPS_NTF_IMMEDIATE_REQ_IND message to a requester. + * + * @param[in] src_id Source ID of the message (instance of TASK_ANPS) + * @param[in] dest_id Destination ID of the message + * @param[in] operation Code of the completed operation + * @param[in] status Status of the request + **************************************************************************************** + */ +void anps_send_ntf_immediate_req_ind(uint8_t conidx, struct anps_env_tag *idx_env, uint8_t alert_type, + uint8_t category_id); + +/** + **************************************************************************************** + * @brief Send an ANPS_CMP_EVT message to a requester. + * + * @param[in] src_id Source ID of the message (instance of TASK_ANPS) + * @param[in] dest_id Destination ID of the message + * @param[in] operation Code of the completed operation + * @param[in] status Status of the request + **************************************************************************************** + */ +void anps_send_cmp_evt(ke_task_id_t src_id, ke_task_id_t dest_id, uint8_t operation, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void anps_task_init(struct ke_task_desc *task_desc); + + +#endif //(BLE_AN_SERVER) + +/// @} ANPS + +#endif //(ANPS_H_) diff --git a/services/ble_profiles/anp/anps/src/anps_task.c b/services/ble_profiles/anp/anps/src/anps_task.c new file mode 100644 index 0000000..000e5e6 --- /dev/null +++ b/services/ble_profiles/anp/anps/src/anps_task.c @@ -0,0 +1,655 @@ +/** + **************************************************************************************** + * @addtogroup ANPSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_AN_SERVER) + +#include "gapm.h" +#include "gattc_task.h" +#include "anps.h" +#include "anps_task.h" + +#include "prf_utils.h" +#include "prf_types.h" + +#include "co_utils.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref ANPS_ENABLE_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int anps_enable_req_handler(ke_msg_id_t const msgid, + struct anps_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Alert Notification Profile Server Role Task Index Environment + struct anps_env_tag *anps_env = PRF_ENV_GET(ANPS, anps); + uint8_t conidx = KE_IDX_GET(src_id); + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(ke_state_get(dest_id) == ANPS_IDLE) + { + if (anps_env->env[conidx] != NULL) + { + // Bonded data was not used before + if (!ANPS_IS_ALERT_ENABLED(conidx, anps_env, ANPS_FLAG_CFG_PERFORMED_OK)) + { + status = GAP_ERR_NO_ERROR; + // Update the state in the environment + if (param->new_alert_ntf_cfg != PRF_CLI_STOP_NTFIND) + { + // Force to PRF_CLI_START_NTF + param->new_alert_ntf_cfg = PRF_CLI_START_NTF; + + ANPS_ENABLE_ALERT(conidx, anps_env, ANP_NEW_ALERT); + } + + if (param->unread_alert_status_ntf_cfg != PRF_CLI_STOP_NTFIND) + { + // Force to PRF_CLI_START_NTF + param->unread_alert_status_ntf_cfg = PRF_CLI_START_NTF; + + ANPS_ENABLE_ALERT(conidx, anps_env, ANP_UNREAD_ALERT); + } + } + // Enable Bonded Data + ANPS_ENABLE_ALERT(conidx, anps_env, ANPS_FLAG_CFG_PERFORMED_OK); + } + } + + // send completed information to APP task that contains error status + struct anps_enable_rsp *cmp_evt = KE_MSG_ALLOC(ANPS_ENABLE_RSP, src_id, dest_id, anps_enable_rsp); + cmp_evt->status = status; + ke_msg_send(cmp_evt); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref ANPS_NTF_ALERT_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int anps_ntf_alert_cmd_handler(ke_msg_id_t const msgid, + struct anps_ntf_alert_cmd const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = PRF_ERR_INVALID_PARAM; + // Message Status + uint8_t msg_status = KE_MSG_CONSUMED; + // Task environment + struct anps_env_tag *anps_env = PRF_ENV_GET(ANPS, anps); + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if(state == ANPS_IDLE) + { + // Category ID + uint8_t cat_id; + // Is the category supported ? + bool cat_supported; + // Handle + uint16_t handle = ATT_ERR_INVALID_HANDLE; + + ASSERT_ERR(anps_env != NULL); + ASSERT_ERR(anps_env->env[conidx] != NULL); + + do + { + // Check the operation code, get the category ID. + if (param->operation == ANPS_UPD_NEW_ALERT_OP_CODE) + { + // Check the length of the string info value + if (param->value.new_alert.info_str_len > ANS_NEW_ALERT_STRING_INFO_MAX_LEN) + { + status = PRF_ERR_INVALID_PARAM; + break; + } + + // Get the category ID + cat_id = param->value.new_alert.cat_id; + // Check if the category is supported + cat_supported = ANPS_IS_NEW_ALERT_CATEGORY_SUPPORTED(cat_id); + } + else if (param->operation == ANPS_UPD_UNREAD_ALERT_STATUS_OP_CODE) + { + // Get the category ID + cat_id = param->value.unread_alert_status.cat_id; + // Check if the category is supported + cat_supported = ANPS_IS_UNREAD_ALERT_CATEGORY_SUPPORTED(cat_id); + } + else + { + status = PRF_ERR_INVALID_PARAM; + break; + } + + // Check the category ID + if ((cat_id >= CAT_ID_NB) || (!cat_supported)) + { + status = PRF_ERR_INVALID_PARAM; + break; + } + + if (param->operation == ANPS_UPD_NEW_ALERT_OP_CODE) + { + // Check if sending of notification is enabled for the provided category + if (ANPS_IS_NEW_ALERT_CATEGORY_ENABLED(conidx, cat_id, anps_env) && + ANPS_IS_ALERT_ENABLED(conidx, anps_env, ANP_NEW_ALERT)) + { + handle = anps_env->shdl + ANS_IDX_NEW_ALERT_VAL; + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), dest_id, + gattc_send_evt_cmd, 2 + param->value.new_alert.info_str_len); + + // Fill in the parameter structure + ntf->operation = GATTC_NOTIFY; + ntf->handle = handle; + // pack measured value in database + ntf->length = 2 + param->value.new_alert.info_str_len; + // Fill data + memcpy(&ntf->value, ¶m->value.new_alert.cat_id, ntf->length); + + // The notification can be sent, send the notification + status = GAP_ERR_NO_ERROR; + ke_msg_send(ntf); + } + else + { + status = PRF_ERR_NTF_DISABLED; + break; + } + } + else + { + if (ANPS_IS_UNREAD_ALERT_CATEGORY_ENABLED(conidx, cat_id, anps_env) && + ANPS_IS_ALERT_ENABLED(conidx, anps_env, ANP_UNREAD_ALERT)) + { + handle = anps_env->shdl + ANS_IDX_UNREAD_ALERT_STATUS_VAL; + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), dest_id, + gattc_send_evt_cmd, sizeof(struct anp_unread_alert)); + + // Fill in the parameter structure + ntf->operation = GATTC_NOTIFY; + ntf->handle = handle; + // pack measured value in database + ntf->length = sizeof(struct anp_unread_alert); + // Fill data + memcpy(&ntf->value, ¶m->value.unread_alert_status, ntf->length); + + // The notification can be sent, send the notification + status = GAP_ERR_NO_ERROR; + ke_msg_send(ntf); + } + else + { + status = PRF_ERR_NTF_DISABLED; + break; + } + } + + // Configure the environment + anps_env->operation = param->operation; + // Go to Busy state + ke_state_set(dest_id, ANPS_BUSY); + } while(0); + } + else if (state == ANPS_BUSY) + { + // Save it for later + msg_status = KE_MSG_SAVED; + status = GAP_ERR_NO_ERROR; + } + // no connection + else + { + status = GAP_ERR_DISCONNECTED; + } + + if(status != GAP_ERR_NO_ERROR) + { + // Send the message to the application + anps_send_cmp_evt(dest_id, src_id, param->operation, status); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT message meaning that a notification or an indication + * has been correctly sent to peer device (but not confirmed by peer device). + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct anps_env_tag *anps_env = PRF_ENV_GET(ANPS, anps); + uint8_t conidx = KE_IDX_GET(src_id); + + if (anps_env != NULL) + { + // Send a complete event status to the application + anps_send_cmp_evt(prf_src_task_get(&anps_env->prf_env, conidx), + prf_dst_task_get(&anps_env->prf_env, conidx), + anps_env->operation, param->status); + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == ANPS_IDLE) + { + // Get the address of the environment + struct anps_env_tag *anps_env = PRF_ENV_GET(ANPS, anps); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t att_idx = param->handle - anps_env->shdl; + + uint8_t value[2]; + uint8_t value_size = 0; + uint8_t status = ATT_ERR_NO_ERROR; + + switch(att_idx) + { + case ANS_IDX_SUPP_NEW_ALERT_CAT_VAL: + { + // Fill data + value_size = sizeof(uint16_t); + co_write16p(value, anps_env->supp_new_alert_cat); + } break; + + case ANS_IDX_NEW_ALERT_CFG: + { + // Fill data + value_size = sizeof(uint16_t); + co_write16p(value, ANPS_IS_ALERT_ENABLED(conidx, anps_env, ANP_NEW_ALERT)); + } break; + + case ANS_IDX_SUPP_UNREAD_ALERT_CAT_VAL: + { + // Fill data + value_size = sizeof(uint16_t); + co_write16p(value, anps_env->supp_unread_alert_cat); + } break; + + case ANS_IDX_UNREAD_ALERT_STATUS_CFG: + { + // Fill data + value_size = sizeof(uint16_t); + co_write16p(value, ANPS_IS_ALERT_ENABLED(conidx, anps_env, ANP_UNREAD_ALERT)); + } break; + + default: + { + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } break; + } + + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, value_size); + cfm->length = value_size; + memcpy(cfm->value, value, value_size); + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_WRITE_REQ_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get the conidx + uint8_t conidx = KE_IDX_GET(src_id); + // Get the address of the environment + struct anps_env_tag *anps_env = PRF_ENV_GET(ANPS, anps); + + // Check if the connection exists + if (anps_env != NULL) + { + /* + * --------------------------------------------------------------------------------------------- + * New Alert Client Characteristic Configuration Descriptor Value - Write + * --------------------------------------------------------------------------------------------- + * Unread Status Alert Client Characteristic Configuration Descriptor Value - Write + * --------------------------------------------------------------------------------------------- + */ + if ((param->handle == (anps_env->shdl + ANS_IDX_NEW_ALERT_CFG)) || + (param->handle == (anps_env->shdl + ANS_IDX_UNREAD_ALERT_STATUS_CFG))) + { + // Received configuration value + uint16_t ntf_cfg = co_read16p(¶m->value[0]); + + if (ntf_cfg <= PRF_CLI_START_NTF) + { + // Alert type + uint8_t alert_type = (param->handle == (anps_env->shdl + ANS_IDX_NEW_ALERT_CFG)) + ? ANP_NEW_ALERT : ANP_UNREAD_ALERT; + + // Update the status in the environment + if (ntf_cfg == PRF_CLI_START_NTF) + { + ANPS_ENABLE_ALERT(conidx, anps_env, alert_type); + } + else + { + ANPS_DISABLE_ALERT(conidx, anps_env, alert_type); + } + + // Inform the HL that the notification configuration status has been written + anps_send_ntf_status_update_ind(conidx, anps_env, alert_type); + // Enable bond Data + ANPS_ENABLE_ALERT(conidx, anps_env, ANPS_FLAG_CFG_PERFORMED_OK); + } + else + { + status = PRF_APP_ERROR; + } + } + /* + * --------------------------------------------------------------------------------------------- + * Alert Notification Control Point Characteristic Value - Write + * --------------------------------------------------------------------------------------------- + */ + else if (param->handle == (anps_env->shdl + ANS_IDX_ALERT_NTF_CTNL_PT_VAL)) + { + do + { + // Check the command ID value + if (param->value[0] >= CMD_ID_NB) + { + status = ANP_CMD_NOT_SUPPORTED; + break; + } + + // Check the category ID value + if ((param->value[1] >= CAT_ID_NB) && + (param->value[1] != CAT_ID_ALL_SUPPORTED_CAT)) + { + status = ANP_CAT_NOT_SUPPORTED; + break; + } + + if (param->value[1] < CAT_ID_NB) + { + // New Alert + if ((param->value[0] % 2) == 0) + { + // Check if the category is supported + if (!ANPS_IS_NEW_ALERT_CATEGORY_SUPPORTED(param->value[1])) + { + status = ANP_CAT_NOT_SUPPORTED; + break; + } + } + // Unread Alert Status + else + { + // Check if the category is supported + if (!ANPS_IS_UNREAD_ALERT_CATEGORY_SUPPORTED(param->value[1])) + { + status = ANP_CAT_NOT_SUPPORTED; + break; + } + } + } + + // React according to the received command id value + switch (param->value[0]) + { + // Enable New Alert Notification + case (CMD_ID_EN_NEW_IN_ALERT_NTF): + { + if (param->value[1] != CAT_ID_ALL_SUPPORTED_CAT) + { + // Enable sending of new alert notification for the specified category + ANPS_ENABLE_NEW_ALERT_CATEGORY(conidx, param->value[1], anps_env); + } + else + { + // Enable sending of new alert notification for all supported category + anps_env->env[conidx]->ntf_new_alert_cfg |= anps_env->supp_new_alert_cat; + } + + anps_send_ntf_status_update_ind(conidx, anps_env, ANP_NEW_ALERT); + } break; + + // Enable Unread Alert Status Notification + case (CMD_ID_EN_UNREAD_CAT_STATUS_NTF): + { + if (param->value[1] != CAT_ID_ALL_SUPPORTED_CAT) + { + // Enable sending of unread alert notification for the specified category + ANPS_ENABLE_UNREAD_ALERT_CATEGORY(conidx, param->value[1], anps_env); + } + else + { + // Enable sending of unread alert notification for all supported category + anps_env->env[conidx]->ntf_unread_alert_cfg |= anps_env->supp_unread_alert_cat; + } + + anps_send_ntf_status_update_ind(conidx, anps_env, ANP_UNREAD_ALERT); + } break; + + // Disable New Alert Notification + case (CMD_ID_DIS_NEW_IN_ALERT_NTF): + { + if (param->value[1] != CAT_ID_ALL_SUPPORTED_CAT) + { + // Disable sending of new alert notification for the specified category + ANPS_DISABLE_NEW_ALERT_CATEGORY(conidx, param->value[1], anps_env); + } + else + { + // Disable sending of new alert notification for all supported category + anps_env->env[conidx]->ntf_new_alert_cfg &= ~anps_env->supp_new_alert_cat; + } + + anps_send_ntf_status_update_ind(conidx, anps_env, ANP_NEW_ALERT); + } break; + + // Disable Unread Alert Status Notification + case (CMD_ID_DIS_UNREAD_CAT_STATUS_NTF): + { + if (param->value[1] != CAT_ID_ALL_SUPPORTED_CAT) + { + // Disable sending of unread alert notification for the specified category + ANPS_DISABLE_UNREAD_ALERT_CATEGORY(conidx, param->value[1], anps_env); + } + else + { + // Enable sending of unread alert notification for all supported category + anps_env->env[conidx]->ntf_unread_alert_cfg &= ~anps_env->supp_unread_alert_cat; + } + + anps_send_ntf_status_update_ind(conidx, anps_env, ANP_UNREAD_ALERT); + } break; + + // Notify New Alert immediately + case (CMD_ID_NTF_NEW_IN_ALERT_IMM): + { + // Check if sending of notification is enabled + if (ANPS_IS_ALERT_ENABLED(conidx, anps_env, ANP_NEW_ALERT)) + { + if (param->value[1] == CAT_ID_ALL_SUPPORTED_CAT) + { + // Check if at least one category can be notified + if (anps_env->env[conidx]->ntf_new_alert_cfg != 0) + { + anps_send_ntf_immediate_req_ind(conidx, anps_env, ANP_NEW_ALERT, + CAT_ID_ALL_SUPPORTED_CAT); + } + } + else + { + // Check if sending of notifications has been enabled for the specified category. + if (ANPS_IS_NEW_ALERT_CATEGORY_ENABLED(conidx, param->value[1], anps_env)) + { + anps_send_ntf_immediate_req_ind(conidx, anps_env, ANP_NEW_ALERT, + param->value[1]); + } + } + } + } break; + + // Notify Unread Alert Status immediately + case (CMD_ID_NTF_UNREAD_CAT_STATUS_IMM): + { + if (ANPS_IS_ALERT_ENABLED(conidx, anps_env, ANP_UNREAD_ALERT)) + { + // Check if sending of notification is enabled + if (ANPS_IS_ALERT_ENABLED(conidx, anps_env, ANP_UNREAD_ALERT)) + { + if (param->value[1] == CAT_ID_ALL_SUPPORTED_CAT) + { + // Check if at least one category can be notified + if (anps_env->env[conidx]->ntf_unread_alert_cfg != 0) + { + anps_send_ntf_immediate_req_ind(conidx, anps_env, ANP_UNREAD_ALERT, + CAT_ID_ALL_SUPPORTED_CAT); + } + } + else + { + // Check if sending of notifications has been enabled for the specified category. + if (ANPS_IS_UNREAD_ALERT_CATEGORY_ENABLED(conidx, param->value[1], anps_env)) + { + anps_send_ntf_immediate_req_ind(conidx, anps_env, ANP_UNREAD_ALERT, + param->value[1]); + } + } + } + } + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } while (0); + } + else + { + ASSERT_ERR(0); + } + // Send the write response to the peer device + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(anps) +{ + {ANPS_ENABLE_REQ, (ke_msg_func_t)anps_enable_req_handler}, + {ANPS_NTF_ALERT_CMD, (ke_msg_func_t)anps_ntf_alert_cmd_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t)gattc_read_req_ind_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t)gattc_write_req_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void anps_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct anps_env_tag *anps_env = PRF_ENV_GET(ANPS, anps); + + task_desc->msg_handler_tab = anps_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(anps_msg_handler_tab); + task_desc->state = anps_env->state; + task_desc->idx_max = ANPS_IDX_MAX; +} + +#endif //(BLE_AN_SERVER) + +/// @} ANPSTASK diff --git a/services/ble_profiles/bas/basc/api/basc_task.h b/services/ble_profiles/bas/basc/api/basc_task.h new file mode 100644 index 0000000..808aa84 --- /dev/null +++ b/services/ble_profiles/bas/basc/api/basc_task.h @@ -0,0 +1,202 @@ +#ifndef _BASC_TASK_H_ +#define _BASC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup BASCTASK Battery Service Client Task + * @ingroup BASC + * @brief Battery Service Client Task + * + * The BASCTASK is responsible for handling the messages coming in and out of the + * @ref BASC block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +///Maximum number of Battery Service instances we can handle +#define BASC_NB_BAS_INSTANCES_MAX (2) + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +enum basc_msg_id +{ + /// Start the Battery Service Client Role - at connection + BASC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_BASC), + ///Confirm that cfg connection has finished with discovery results, or that normal cnx started + BASC_ENABLE_RSP, + + /// Read Characteristic Value Request + BASC_READ_INFO_REQ, + /// Read Characteristic Value Request + BASC_READ_INFO_RSP, + + /// Write Battery Level Notification Configuration Value request + BASC_BATT_LEVEL_NTF_CFG_REQ, + /// Write Battery Level Notification Configuration Value response + BASC_BATT_LEVEL_NTF_CFG_RSP, + + /// Indicate to APP that the Battery Level value has been received + BASC_BATT_LEVEL_IND, +}; + +/// Peer battery info that can be read +enum basc_info +{ + /// Battery Level value + BASC_BATT_LVL_VAL, + /// Battery Level Client Characteristic Configuration + BASC_NTF_CFG, + /// Battery Level Characteristic Presentation Format + BASC_BATT_LVL_PRES_FORMAT, + + BASC_INFO_MAX, +}; + + +/// Battery Service Characteristics +enum bass_char_type +{ + /// Battery Level + BAS_CHAR_BATT_LEVEL, + + BAS_CHAR_MAX, +}; + +/// Battery Service Descriptors +enum bass_desc_type +{ + /// Battery Level Characteristic Presentation Format + BAS_DESC_BATT_LEVEL_PRES_FORMAT, + /// Battery Level Client Characteristic Configuration + BAS_DESC_BATT_LEVEL_CFG, + + BAS_DESC_MAX, +}; + +/* + * APIs Structure + **************************************************************************************** + */ + +///Structure containing the characteristics handles, value handles and descriptors +struct bas_content +{ + /// service info + struct prf_svc svc; + + /// Characteristic Info: + /// - Battery Level + struct prf_char_inf chars[BAS_CHAR_MAX]; + + /// Descriptor handles: + /// - Battery Level Client Characteristic Configuration + /// - Battery Level Characteristic Presentation Format + struct prf_char_desc_inf descs[BAS_DESC_MAX]; +}; + + +/// Parameters of the @ref BASC_ENABLE_REQ message +struct basc_enable_req +{ + ///Connection type + uint8_t con_type; + + /// Number of BAS instances that have previously been found + uint8_t bas_nb; + /// Existing handle values bas + struct bas_content bas[BASC_NB_BAS_INSTANCES_MAX]; +}; + +/// Parameters of the @ref BASC_ENABLE_RSP message +struct basc_enable_rsp +{ + /// Status + uint8_t status; + /// Number of BAS that have been found + uint8_t bas_nb; + ///Existing handle values bas + struct bas_content bas[BASC_NB_BAS_INSTANCES_MAX]; +}; + + +///Parameters of the @ref BASC_READ_INFO_REQ message +struct basc_read_info_req +{ + ///Characteristic info @see enum basc_info + uint8_t info; + ///Battery Service Instance - From 0 to BASC_NB_BAS_INSTANCES_MAX-1 + uint8_t bas_nb; +}; + +///Parameters of the @ref BASC_READ_INFO_RSP message +struct basc_read_info_rsp +{ + /// status of the request + uint8_t status; + ///Characteristic info @see enum basc_info + uint8_t info; + ///Battery Service Instance - From 0 to BASC_NB_BAS_INSTANCES_MAX-1 + uint8_t bas_nb; + + /// Information data + union basc_data + { + /// Battery Level - if info = BASC_BATT_LVL_VAL + uint8_t batt_level; + ///Notification Configuration Value - if info = BASC_NTF_CFG + uint16_t ntf_cfg; + ///Characteristic Presentation Format - if info = BASC_BATT_LVL_PRES_FORMAT + struct prf_char_pres_fmt char_pres_format; + } data; +}; + +///Parameters of the @ref BASC_BATT_LEVEL_NTF_CFG_REQ message +struct basc_batt_level_ntf_cfg_req +{ + ///Notification Configuration + uint16_t ntf_cfg; + ///Battery Service Instance - From 0 to BASC_NB_BAS_INSTANCES_MAX-1 + uint8_t bas_nb; +}; + +///Parameters of the @ref BASC_BATT_LEVEL_NTF_CFG_RSP message +struct basc_batt_level_ntf_cfg_rsp +{ + ///Status + uint8_t status; + ///Battery Service Instance - From 0 to BASC_NB_BAS_INSTANCES_MAX-1 + uint8_t bas_nb; +}; + +///Parameters of the @ref BASC_BATT_LEVEL_IND message +struct basc_batt_level_ind +{ + ///Battery Level + uint8_t batt_level; + ///Battery Service Instance - From 0 to BASC_NB_BAS_INSTANCES_MAX-1 + uint8_t bas_nb; +}; + + +/// @} BASCTASK + +#endif /* _BASC_TASK_H_ */ diff --git a/services/ble_profiles/bas/basc/src/basc.c b/services/ble_profiles/bas/basc/src/basc.c new file mode 100644 index 0000000..1c445f9 --- /dev/null +++ b/services/ble_profiles/bas/basc/src/basc.c @@ -0,0 +1,207 @@ +/** + **************************************************************************************** + * @addtogroup BASC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_BATT_CLIENT) + +#include "gap.h" +#include "basc.h" +#include "basc_task.h" +#include "co_math.h" + +#include "ke_mem.h" + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialization of the BASC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t basc_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct basc_env_tag* basc_env = + (struct basc_env_tag* ) ke_malloc(sizeof(struct basc_env_tag), KE_MEM_ATT_DB); + + // allocate BASC required environment variable + env->env = (prf_env_t*) basc_env; + + basc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + basc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_BASC; + basc_task_init(&(env->desc)); + + for(idx = 0; idx < BASC_IDX_MAX ; idx++) + { + basc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), BASC_FREE); + } + + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Destruction of the BASC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void basc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct basc_env_tag* basc_env = (struct basc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < BASC_IDX_MAX ; idx++) + { + if(basc_env->env[idx] != NULL) + { + if(basc_env->env[idx]->operation != NULL) + { + ke_free(basc_env->env[idx]->operation); + } + ke_free(basc_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(basc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void basc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put BAS Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), BASC_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void basc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct basc_env_tag* basc_env = (struct basc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(basc_env->env[conidx] != NULL) + { + if(basc_env->env[conidx]->operation != NULL) + { + ke_free(basc_env->env[conidx]->operation); + } + ke_free(basc_env->env[conidx]); + basc_env->env[conidx] = NULL; + } + + /* Put BAS Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), BASC_FREE); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// BASC Task interface required by profile manager +const struct prf_task_cbs basc_itf = +{ + basc_init, + basc_destroy, + basc_create, + basc_cleanup, +}; + + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* basc_prf_itf_get(void) +{ + return &basc_itf; +} + + +void basc_enable_rsp_send(struct basc_env_tag *basc_env, uint8_t conidx, uint8_t status) +{ + // Counter + uint8_t svc_inst; + + // Send APP the details of the discovered attributes on BASC + struct basc_enable_rsp * rsp = KE_MSG_ALLOC(BASC_ENABLE_RSP, + prf_dst_task_get(&(basc_env->prf_env) ,conidx), + prf_src_task_get(&(basc_env->prf_env) ,conidx), + basc_enable_rsp); + rsp->status = status; + rsp->bas_nb = 0; + if (status == GAP_ERR_NO_ERROR) + { + rsp->bas_nb = basc_env->env[conidx]->bas_nb; + + for (svc_inst = 0; svc_inst < co_min(basc_env->env[conidx]->bas_nb, BASC_NB_BAS_INSTANCES_MAX) ; svc_inst++) + { + rsp->bas[svc_inst] = basc_env->env[conidx]->bas[svc_inst]; + + // Register BASC task in gatt for indication/notifications + prf_register_atthdl2gatt(&(basc_env->prf_env), conidx, &basc_env->env[conidx]->bas[svc_inst].svc); + } + } + + ke_msg_send(rsp); +} + +#endif /* (BLE_BATT_CLIENT) */ + +/// @} BASC diff --git a/services/ble_profiles/bas/basc/src/basc.h b/services/ble_profiles/bas/basc/src/basc.h new file mode 100644 index 0000000..11e21cb --- /dev/null +++ b/services/ble_profiles/bas/basc/src/basc.h @@ -0,0 +1,130 @@ +#ifndef _BASC_H_ +#define _BASC_H_ + +/** + **************************************************************************************** + * @addtogroup BASC Battery Service Client + * @ingroup BAS + * @brief Battery Service Client + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_BATT_CLIENT) + +#include +#include +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "basc_task.h" + +/* + * DEFINES + **************************************************************************************** + */ + +///Maximum number of Battery Client task instances +#define BASC_IDX_MAX (BLE_CONNECTION_MAX) + +/// Possible states of the BAPC task +enum basc_state +{ + /// Disconnected state + BASC_FREE, + /// IDLE state + BASC_IDLE, + /// Busy State + BASC_BUSY, + + /// Number of defined states. + BASC_STATE_MAX +}; + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Environment variable for each Connections +struct basc_cnx_env +{ + /// on-going operation + struct ke_msg * operation; + ///BAS characteristics + struct bas_content bas[BASC_NB_BAS_INSTANCES_MAX]; + + ///Number of BAS instances found + uint8_t bas_nb; +}; + +/// Battery 'Profile' Client environment variable +struct basc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct basc_cnx_env* env[BASC_IDX_MAX]; + /// State of different task instances + ke_state_t state[BASC_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Retrieve BAS client profile interface + * + * @return BAS client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* basc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send BAS ATT DB discovery results to BASC host. + **************************************************************************************** + */ +void basc_enable_rsp_send(struct basc_env_tag *basc_env, uint8_t conidx, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void basc_task_init(struct ke_task_desc *task_desc); + +#endif /* (BLE_BATT_CLIENT) */ + +/// @} BASC + +#endif /* _BASC_H_ */ diff --git a/services/ble_profiles/bas/basc/src/basc_task.c b/services/ble_profiles/bas/basc/src/basc_task.c new file mode 100644 index 0000000..1e59722 --- /dev/null +++ b/services/ble_profiles/bas/basc/src/basc_task.c @@ -0,0 +1,623 @@ +/** + **************************************************************************************** + * @addtogroup BASCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_BATT_CLIENT) + +#include "gap.h" +#include "basc.h" +#include "basc_task.h" +#include "gattc_task.h" +#include "co_math.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// State machine used to retrieve Battery Service characteristics information +const struct prf_char_def basc_bas_char[BAS_CHAR_MAX] = +{ + /// Battery Level + [BAS_CHAR_BATT_LEVEL] = {ATT_CHAR_BATTERY_LEVEL, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, +}; + +/// State machine used to retrieve Battery Service characteristic description information +const struct prf_char_desc_def basc_bas_char_desc[BAS_DESC_MAX] = +{ + /// Battery Level Characteristic Presentation Format + [BAS_DESC_BATT_LEVEL_PRES_FORMAT] = {ATT_DESC_CHAR_PRES_FORMAT, ATT_OPTIONAL, BAS_CHAR_BATT_LEVEL}, + /// Battery Level Client Config + [BAS_DESC_BATT_LEVEL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_OPTIONAL, BAS_CHAR_BATT_LEVEL}, + +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref BASC_ENABLE_REQ message. + * The handler enables the Battery Service Client Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int basc_enable_req_handler(ke_msg_id_t const msgid, + struct basc_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + int msg_status = KE_MSG_CONSUMED; + + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Battery service Client Role Task Environment + struct basc_env_tag *basc_env = PRF_ENV_GET(BASC, basc); + + ASSERT_INFO(basc_env != NULL, dest_id, src_id); + if((state == BASC_IDLE) && (basc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + basc_env->env[conidx] = (struct basc_cnx_env*) ke_malloc(sizeof(struct basc_cnx_env),KE_MEM_ATT_DB); + memset(basc_env->env[conidx], 0, sizeof(struct basc_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering BAS on peer + prf_disc_svc_send(&(basc_env->prf_env), conidx, ATT_SVC_BATTERY_SERVICE); + + // Go to DISCOVERING state + ke_state_set(dest_id, BASC_BUSY); + basc_env->env[conidx]->operation = ke_param2msg(param); + msg_status = KE_MSG_NO_FREE; + } + //normal connection, get saved att details + else + { + basc_env->env[conidx]->bas_nb = param->bas_nb; + memcpy(&(basc_env->env[conidx]->bas[0]), &(param->bas[0]), sizeof(struct bas_content) * BASC_NB_BAS_INSTANCES_MAX); + + //send APP confirmation that can start normal connection to TH + basc_enable_rsp_send(basc_env, conidx, GAP_ERR_NO_ERROR); + } + } + else if(state != BASC_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + basc_enable_rsp_send(basc_env, conidx, status); + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == BASC_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct basc_env_tag *basc_env = PRF_ENV_GET(BASC, basc); + + ASSERT_INFO(basc_env != NULL, dest_id, src_id); + ASSERT_INFO(basc_env->env[conidx] != NULL, dest_id, src_id); + + if(basc_env->env[conidx]->bas_nb < BASC_NB_BAS_INSTANCES_MAX) + { + // Retrieve DIS characteristics + prf_extract_svc_info(ind, BAS_CHAR_MAX, &basc_bas_char[0], + &(basc_env->env[conidx]->bas[basc_env->env[conidx]->bas_nb].chars[0]), + BAS_DESC_MAX, &basc_bas_char_desc[0], + &(basc_env->env[conidx]->bas[basc_env->env[conidx]->bas_nb].descs[0])); + + //Even if we get multiple responses we only store 1 range + basc_env->env[conidx]->bas[basc_env->env[conidx]->bas_nb].svc.shdl = ind->start_hdl; + basc_env->env[conidx]->bas[basc_env->env[conidx]->bas_nb].svc.ehdl = ind->end_hdl; + } + + basc_env->env[conidx]->bas_nb++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref BASC_READ_INFO_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int basc_read_info_req_handler(ke_msg_id_t const msgid, struct basc_read_info_req const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(state == BASC_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct basc_env_tag *basc_env = PRF_ENV_GET(BASC, basc); + ASSERT_INFO(basc_env != NULL, dest_id, src_id); + // environment variable not ready + if(basc_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + // check parameter range + else if(param->bas_nb > basc_env->env[conidx]->bas_nb) + { + status = PRF_ERR_INVALID_PARAM; + } + else + { + uint16_t handle = ATT_INVALID_HANDLE; + status = PRF_ERR_INEXISTENT_HDL; + + // check requested info + switch(param->info) + { + /// Battery Level value + case BASC_BATT_LVL_VAL: + { + handle = basc_env->env[conidx]->bas[param->bas_nb].chars[BAS_CHAR_BATT_LEVEL].val_hdl; + }break; + /// Battery Level Client Characteristic Configuration + case BASC_NTF_CFG: + { + handle = basc_env->env[conidx]->bas[param->bas_nb].descs[BAS_DESC_BATT_LEVEL_CFG].desc_hdl; + }break; + /// Battery Level Characteristic Presentation Format + case BASC_BATT_LVL_PRES_FORMAT: + { + handle = basc_env->env[conidx]->bas[param->bas_nb].descs[BAS_DESC_BATT_LEVEL_PRES_FORMAT].desc_hdl; + }break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + }break; + } + + if(handle != ATT_INVALID_HANDLE) + { + status = GAP_ERR_NO_ERROR; + // read information + prf_read_char_send(&(basc_env->prf_env), conidx, + basc_env->env[conidx]->bas[param->bas_nb].svc.shdl, + basc_env->env[conidx]->bas[param->bas_nb].svc.ehdl, handle); + + // store context of request and go into busy state + basc_env->env[conidx]->operation = ke_param2msg(param); + ke_state_set(dest_id, BASC_BUSY); + msg_status = KE_MSG_NO_FREE; + } + } + } + // process message later + else if (state == BASC_BUSY) + { + status = GAP_ERR_NO_ERROR; + msg_status = KE_MSG_SAVED; + } + + + // request cannot be performed + if(status != GAP_ERR_NO_ERROR) + { + struct basc_read_info_rsp * rsp = KE_MSG_ALLOC(BASC_READ_INFO_RSP, + src_id, dest_id, basc_read_info_rsp); + // set error status + rsp->status = status; + rsp->info = param->info; + rsp->bas_nb = param->bas_nb; + + ke_msg_send(rsp); + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref BASC_BATT_LEVEL_NTF_CFG_REQ message. + * It allows configuration of the peer ntf/stop characteristic for Battery Level Characteristic. + * Will return an error code if that cfg char does not exist. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int basc_batt_level_ntf_cfg_req_handler(ke_msg_id_t const msgid, + struct basc_batt_level_ntf_cfg_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + int msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(state == BASC_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct basc_env_tag *basc_env = PRF_ENV_GET(BASC, basc); + ASSERT_INFO(basc_env != NULL, dest_id, src_id); + // environment variable not ready + if(basc_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + // check parameter range + else if((param->bas_nb > basc_env->env[conidx]->bas_nb) + || (param->ntf_cfg > PRF_CLI_START_NTF)) + { + status = PRF_ERR_INVALID_PARAM; + } + else + { + uint16_t handle = basc_env->env[conidx]->bas[param->bas_nb].descs[BAS_DESC_BATT_LEVEL_CFG].desc_hdl; + status = PRF_ERR_INEXISTENT_HDL; + + if(handle == ATT_INVALID_HDL) + { + status = PRF_ERR_INEXISTENT_HDL; + } + else + { + status = GAP_ERR_NO_ERROR; + // Send GATT Write Request + prf_gatt_write_ntf_ind(&basc_env->prf_env, conidx, handle, param->ntf_cfg); + // store context of request and go into busy state + basc_env->env[conidx]->operation = ke_param2msg(param); + ke_state_set(dest_id, BASC_BUSY); + msg_status = KE_MSG_NO_FREE; + } + } + } + // process message later + else if (state == BASC_BUSY) + { + status = GAP_ERR_NO_ERROR; + msg_status = KE_MSG_SAVED; + } + + + // request cannot be performed + if(status != GAP_ERR_NO_ERROR) + { + struct basc_batt_level_ntf_cfg_rsp * rsp = KE_MSG_ALLOC(BASC_BATT_LEVEL_NTF_CFG_RSP, + src_id, dest_id, basc_batt_level_ntf_cfg_rsp); + // set error status + rsp->status = status; + rsp->bas_nb = param->bas_nb; + + ke_msg_send(rsp); + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct basc_env_tag *basc_env = PRF_ENV_GET(BASC, basc); + + // sanity check + if((state == BASC_BUSY) && (basc_env->env[conidx] != NULL) + && (basc_env->env[conidx]->operation != NULL)) + { + switch(basc_env->env[conidx]->operation->id) + { + case BASC_ENABLE_REQ: + { + uint8_t status = param->status; + + if (param->status == ATT_ERR_NO_ERROR) + { + // check characteristic validity + if(basc_env->env[conidx]->bas_nb > 0) + { + uint8_t i; + for (i = 0 ; (i < co_min(basc_env->env[conidx]->bas_nb, BASC_NB_BAS_INSTANCES_MAX)) + && (status == GAP_ERR_NO_ERROR) ; i++) + { + status = prf_check_svc_char_validity(BAS_CHAR_MAX, basc_env->env[conidx]->bas[i].chars, + basc_bas_char); + + // check descriptor validity + if(status == GAP_ERR_NO_ERROR) + { + struct prf_char_desc_def bas_desc[BAS_DESC_MAX]; + memcpy(bas_desc, basc_bas_char_desc, sizeof(basc_bas_char_desc)); + + if (basc_env->env[conidx]->bas_nb > 1) + { + bas_desc[BAS_DESC_BATT_LEVEL_PRES_FORMAT].req_flag = ATT_MANDATORY; + } + if ((basc_env->env[conidx]->bas[i].chars[BAS_CHAR_BATT_LEVEL].prop & ATT_CHAR_PROP_NTF) == ATT_CHAR_PROP_NTF) + { + bas_desc[BAS_DESC_BATT_LEVEL_CFG].req_flag = ATT_MANDATORY; + } + + status = prf_check_svc_char_desc_validity(BAS_DESC_MAX, + basc_env->env[conidx]->bas[i].descs, bas_desc, + basc_env->env[conidx]->bas[i].chars); + } + } + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + } + basc_enable_rsp_send(basc_env, conidx, status); + }break; + case BASC_READ_INFO_REQ: + { + struct basc_read_info_req* req = (struct basc_read_info_req*) ke_msg2param(basc_env->env[conidx]->operation); + + struct basc_read_info_rsp * rsp = KE_MSG_ALLOC(BASC_READ_INFO_RSP, + prf_dst_task_get(&(basc_env->prf_env), conidx), dest_id, basc_read_info_rsp); + // set error status + rsp->status = param->status; + rsp->bas_nb = req->bas_nb; + rsp->info = req->info; + + ke_msg_send(rsp); + + }break; + case BASC_BATT_LEVEL_NTF_CFG_REQ: + { + struct basc_batt_level_ntf_cfg_req* req = (struct basc_batt_level_ntf_cfg_req*) ke_msg2param(basc_env->env[conidx]->operation); + + struct basc_batt_level_ntf_cfg_rsp * rsp = KE_MSG_ALLOC(BASC_BATT_LEVEL_NTF_CFG_RSP, + prf_dst_task_get(&(basc_env->prf_env), conidx), dest_id, basc_batt_level_ntf_cfg_rsp); + // set error status + rsp->status =param->status; + rsp->bas_nb = req->bas_nb; + + ke_msg_send(rsp); + }break; + default: + { + // Not Expected at all + ASSERT_ERR(0); + }break; + } + + // operation is over - go back to idle state + ke_free(basc_env->env[conidx]->operation); + basc_env->env[conidx]->operation = NULL; + ke_state_set(dest_id, BASC_IDLE); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == BASC_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct basc_env_tag *basc_env = PRF_ENV_GET(BASC, basc); + struct basc_read_info_req* req = (struct basc_read_info_req*) ke_msg2param(basc_env->env[conidx]->operation); + + ASSERT_INFO(basc_env != NULL, dest_id, src_id); + ASSERT_INFO(basc_env->env[conidx] != NULL, dest_id, src_id); + + + struct basc_read_info_rsp * rsp = KE_MSG_ALLOC(BASC_READ_INFO_RSP, + prf_dst_task_get(&(basc_env->prf_env),conidx), dest_id, basc_read_info_rsp); + // set error status + rsp->status = GAP_ERR_NO_ERROR; + rsp->bas_nb = req->bas_nb; + rsp->info = req->info; + + switch(req->info) + { + /// Battery Level value + case BASC_BATT_LVL_VAL: + { + rsp->data.batt_level = param->value[0]; + }break; + /// Battery Level Client Characteristic Configuration + case BASC_NTF_CFG: + { + rsp->data.ntf_cfg = co_read16p(¶m->value[0]); + + }break; + /// Battery Level Characteristic Presentation Format + case BASC_BATT_LVL_PRES_FORMAT: + { + prf_unpack_char_pres_fmt(¶m->value[0], &rsp->data.char_pres_format); + }break; + + default: + { + ASSERT_ERR(0); + }break; + } + + // send response + ke_msg_send(rsp); + + // operation is over - go back to idle state + ke_free(basc_env->env[conidx]->operation); + basc_env->env[conidx]->operation = NULL; + ke_state_set(dest_id, BASC_IDLE); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state != BASC_FREE) + { + + // BAS Instance + uint8_t bas_nb; + uint8_t conidx = KE_IDX_GET(src_id); + // Get the address of the environment + struct basc_env_tag *basc_env = PRF_ENV_GET(BASC, basc); + + //Battery Level - BAS instance is unknown. + for (bas_nb = 0; (bas_nb < basc_env->env[conidx]->bas_nb); bas_nb++) + { + if (param->handle == basc_env->env[conidx]->bas[bas_nb].chars[BAS_CHAR_BATT_LEVEL].val_hdl) + { + struct basc_batt_level_ind * ind = KE_MSG_ALLOC(BASC_BATT_LEVEL_IND, + prf_dst_task_get(&(basc_env->prf_env), conidx), dest_id, + basc_batt_level_ind); + + ind->batt_level = param->value[0]; + ind->bas_nb = bas_nb; + + //Send Battery Level value to APP + ke_msg_send(ind); + break; + } + } + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(basc) +{ + {BASC_ENABLE_REQ, (ke_msg_func_t)basc_enable_req_handler}, + {BASC_READ_INFO_REQ, (ke_msg_func_t)basc_read_info_req_handler}, + {BASC_BATT_LEVEL_NTF_CFG_REQ, (ke_msg_func_t)basc_batt_level_ntf_cfg_req_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void basc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct basc_env_tag *basc_env = PRF_ENV_GET(BASC, basc); + + task_desc->msg_handler_tab = basc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(basc_msg_handler_tab); + task_desc->state = basc_env->state; + task_desc->idx_max = BASC_IDX_MAX; +} + + + +#endif /* (BLE_BATT_CLIENT) */ + +/// @} BASCTASK diff --git a/services/ble_profiles/bas/bass/api/bass_task.h b/services/ble_profiles/bas/bass/api/bass_task.h new file mode 100644 index 0000000..96ae4f8 --- /dev/null +++ b/services/ble_profiles/bas/bass/api/bass_task.h @@ -0,0 +1,130 @@ +#ifndef _BASS_TASK_H_ +#define _BASS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup BAPSTASK Task + * @ingroup BAPS + * @brief Battery 'Profile' Task. + * + * The BAPS_TASK is responsible for handling the messages coming in and out of the + * @ref BAPS block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "prf_types.h" +#include "rwip_task.h" // Task definitions + +/* + * DEFINES + **************************************************************************************** + */ + +#define BAS_BATTERY_LVL_MAX (100) + + +///Maximal number of BAS that can be added in the DB +#define BASS_NB_BAS_INSTANCES_MAX (2) + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Messages for Battery Server +enum bass_msg_id +{ + /// Start the Battery Server - at connection used to restore bond data + BASS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_BASS), + /// Confirmation of the Battery Server start + BASS_ENABLE_RSP, + /// Battery Level Value Update Request + BASS_BATT_LEVEL_UPD_REQ, + /// Inform APP if Battery Level value has been notified or not + BASS_BATT_LEVEL_UPD_RSP, + /// Inform APP that Battery Level Notification Configuration has been changed - use to update bond data + BASS_BATT_LEVEL_NTF_CFG_IND, +}; + +/// Features Flag Masks +enum bass_features +{ + /// Battery Level Characteristic doesn't support notifications + BAS_BATT_LVL_NTF_NOT_SUP, + /// Battery Level Characteristic support notifications + BAS_BATT_LVL_NTF_SUP, +}; + + +/* + * APIs Structures + **************************************************************************************** + */ + +/// Parameters for the database creation +struct bass_db_cfg +{ + /// Number of BAS to add + uint8_t bas_nb; + /// Features of each BAS instance + uint8_t features[BASS_NB_BAS_INSTANCES_MAX]; + /// Battery Level Characteristic Presentation Format - Should not change during connection + struct prf_char_pres_fmt batt_level_pres_format[BASS_NB_BAS_INSTANCES_MAX]; +}; + +/// Parameters of the @ref BASS_ENABLE_REQ message +struct bass_enable_req +{ + /// connection index + uint8_t conidx; + /// Notification Configuration + uint8_t ntf_cfg; + /// Old Battery Level used to decide if notification should be triggered + uint8_t old_batt_lvl[BASS_NB_BAS_INSTANCES_MAX]; +}; + +/// Parameters of the @ref BASS_ENABLE_RSP message +struct bass_enable_rsp +{ + /// connection index + uint8_t conidx; + ///status + uint8_t status; +}; + +///Parameters of the @ref BASS_BATT_LEVEL_UPD_REQ message +struct bass_batt_level_upd_req +{ + /// BAS instance + uint8_t bas_instance; + /// Battery Level + uint8_t batt_level; +}; + +///Parameters of the @ref BAPS_BATT_LEVEL_UPD_RSP message +struct bass_batt_level_upd_rsp +{ + ///status + uint8_t status; +}; + +///Parameters of the @ref BASS_BATT_LEVEL_NTF_CFG_IND message +struct bass_batt_level_ntf_cfg_ind +{ + /// connection index + uint8_t conidx; + ///Notification Configuration + uint8_t ntf_cfg; +}; + +/// @} BASSTASK + +#endif /* _BASS_TASK_H_ */ diff --git a/services/ble_profiles/bas/bass/src/bass.c b/services/ble_profiles/bas/bass/src/bass.c new file mode 100644 index 0000000..50b89ab --- /dev/null +++ b/services/ble_profiles/bas/bass/src/bass.c @@ -0,0 +1,461 @@ +/** + **************************************************************************************** + * @addtogroup BASS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_BATT_SERVER) +#include "bass.h" +#include "bass_task.h" +#include "prf_utils.h" +#include "prf.h" + +#include "ke_mem.h" + +/* + * BAS ATTRIBUTES DEFINITION + **************************************************************************************** + */ + +/// Full BAS Database Description - Used to add attributes into the database +const struct attm_desc bas_att_db[BAS_IDX_NB] = +{ + // Battery Service Declaration + [BAS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // Battery Level Characteristic Declaration + [BAS_IDX_BATT_LVL_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Battery Level Characteristic Value + [BAS_IDX_BATT_LVL_VAL] = {ATT_CHAR_BATTERY_LEVEL, PERM(RD, ENABLE), PERM(RI, ENABLE), 0}, + // Battery Level Characteristic - Client Characteristic Configuration Descriptor + [BAS_IDX_BATT_LVL_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, 0}, + // Battery Level Characteristic - Characteristic Presentation Format Descriptor + [BAS_IDX_BATT_LVL_PRES_FMT] = {ATT_DESC_CHAR_PRES_FORMAT, PERM(RD, ENABLE), PERM(RI, ENABLE), 0}, +}; + + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the BASS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t bass_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct bass_db_cfg* params) +{ + uint16_t shdl[BASS_NB_BAS_INSTANCES_MAX]; + struct bass_env_tag* bass_env = NULL; + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Counter + uint8_t i; + + // Check number of BAS instances + if ((params->bas_nb > 0) && (params->bas_nb <= BASS_NB_BAS_INSTANCES_MAX)) + { + //-------------------- allocate memory required for the profile --------------------- + bass_env = (struct bass_env_tag* ) ke_malloc(sizeof(struct bass_env_tag), KE_MEM_ATT_DB); + memset(bass_env, 0 , sizeof(struct bass_env_tag)); + + // Save number of BAS + bass_env->svc_nb = params->bas_nb; + + for (i = 0; ((i < params->bas_nb) && (status == GAP_ERR_NO_ERROR)); i++) + { + // Service content flag + uint8_t cfg_flag = BAS_CFG_FLAG_MANDATORY_MASK; + + // Save database configuration + bass_env->features |= (params->features[i]) << i; + bass_env->batt_level_pres_format[i] = params->batt_level_pres_format[i]; + + // Check if notifications are supported + if (params->features[i] == BAS_BATT_LVL_NTF_SUP) + { + cfg_flag |= BAS_CFG_FLAG_NTF_SUP_MASK; + } + + // Check if multiple instances + if (bass_env->svc_nb > 1) + { + cfg_flag |= BAS_CFG_FLAG_MTP_BAS_MASK; + } + + shdl[i] = *start_hdl; + + //Create BAS in the DB + //------------------ create the attribute database for the profile ------------------- + status = attm_svc_create_db(&(shdl[i]), ATT_SVC_BATTERY_SERVICE, (uint8_t *)&cfg_flag, + BAS_IDX_NB, NULL, env->task, bas_att_db, + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS))); + + //Set optional permissions + if (status == GAP_ERR_NO_ERROR) + { + // update start handle for next service - only useful if multiple service, else not used. + // 4 characteristics + optional notification characteristic. + *start_hdl = shdl[i] + BAS_IDX_NB - ((params->features[i] == BAS_BATT_LVL_NTF_SUP) ? 0 : 1); + + //Set optional permissions + if(params->features[i] == BAS_BATT_LVL_NTF_SUP) + { + // Battery Level characteristic value permissions + uint16_t perm = PERM(RD, ENABLE) | PERM(NTF, ENABLE); + + attm_att_set_permission(shdl[i] + BAS_IDX_BATT_LVL_VAL, perm, 0); + } + } + + // Reset configuration flag + cfg_flag = BAS_CFG_FLAG_MANDATORY_MASK; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + + //-------------------- Update profile task information --------------------- + if (status == ATT_ERR_NO_ERROR) + { + + // allocate BASS required environment variable + env->env = (prf_env_t*) bass_env; + *start_hdl = shdl[0]; + bass_env->start_hdl = *start_hdl; + bass_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + bass_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + // initialize environment variable + env->id = TASK_ID_BASS; + bass_task_init(&(env->desc)); + + // service is ready, go into an Idle state + ke_state_set(env->task, BASS_IDLE); + } + else if(bass_env != NULL) + { + ke_free(bass_env); + } + + return (status); +} +/** + **************************************************************************************** + * @brief Destruction of the BASS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void bass_destroy(struct prf_task_env* env) +{ + struct bass_env_tag* bass_env = (struct bass_env_tag*) env->env; + + // clear on-going operation + if(bass_env->operation != NULL) + { + ke_free(bass_env->operation); + } + + // free profile environment variables + env->env = NULL; + ke_free(bass_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void bass_create(struct prf_task_env* env, uint8_t conidx) +{ + struct bass_env_tag* bass_env = (struct bass_env_tag*) env->env; + ASSERT_ERR(conidx < BLE_CONNECTION_MAX); + + // force notification config to zero when peer device is connected + bass_env->ntf_cfg[conidx] = 0; +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void bass_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct bass_env_tag* bass_env = (struct bass_env_tag*) env->env; + + ASSERT_ERR(conidx < BLE_CONNECTION_MAX); + // force notification config to zero when peer device is disconnected + bass_env->ntf_cfg[conidx] = 0; +} + + +/** + **************************************************************************************** + * @brief Trigger battery level notification + * + * @param bass_env profile environment + * @param conidx peer destination connection index + * @param svc_idx Service index + **************************************************************************************** + */ +static void bass_notify_batt_lvl(struct bass_env_tag* bass_env, uint8_t conidx, uint8_t svc_idx) +{ + // Allocate the GATT notification message + struct gattc_send_evt_cmd *batt_lvl = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&(bass_env->prf_env),0), + gattc_send_evt_cmd, sizeof(uint8_t)); + + // Fill in the parameter structure + batt_lvl->operation = GATTC_NOTIFY; + batt_lvl->handle = bass_get_att_handle(svc_idx, BAS_IDX_BATT_LVL_VAL); + // pack measured value in database + batt_lvl->length = sizeof(uint8_t); + batt_lvl->value[0] = bass_env->batt_lvl[svc_idx]; + + // send notification to peer device + ke_msg_send(batt_lvl); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// BASS Task interface required by profile manager +const struct prf_task_cbs bass_itf = +{ + (prf_init_fnct) bass_init, + bass_destroy, + bass_create, + bass_cleanup, +}; + + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* bass_prf_itf_get(void) +{ + return &bass_itf; +} + +uint16_t bass_get_att_handle(uint8_t svc_idx, uint8_t att_idx) +{ + struct bass_env_tag* bass_env = PRF_ENV_GET(BASS, bass); + uint16_t handle = ATT_INVALID_HDL; + uint8_t i = 0; + + + if(svc_idx < bass_env ->svc_nb) + { + handle = bass_env->start_hdl; + + for(i = 0 ; i < svc_idx ; i++) + { + // update start handle for next service - only useful if multiple service, else not used. + // 4 characteristics + optional notification characteristic. + handle += BAS_IDX_NB - ((((bass_env->features >> i) & 0x01) == BAS_BATT_LVL_NTF_SUP) ? 0 : 1); + } + + // increment index according to expected index + if(att_idx < BAS_IDX_BATT_LVL_NTF_CFG) + { + handle += att_idx; + } + // Battery notification + else if((att_idx == BAS_IDX_BATT_LVL_NTF_CFG) && (((bass_env->features >> i) & 0x01) == BAS_BATT_LVL_NTF_SUP)) + { + handle += BAS_IDX_BATT_LVL_NTF_CFG; + } + // Battery Level format + else if((att_idx == BAS_IDX_BATT_LVL_PRES_FMT) && (bass_env->svc_nb > 1)) + { + handle += BAS_IDX_BATT_LVL_PRES_FMT - ((((bass_env->features >> i) & 0x01) == BAS_BATT_LVL_NTF_SUP) ? 0 : 1); + } + else + { + handle = ATT_INVALID_HDL; + } + } + + return handle; +} + +uint8_t bass_get_att_idx(uint16_t handle, uint8_t *svc_idx, uint8_t *att_idx) +{ + struct bass_env_tag* bass_env = PRF_ENV_GET(BASS, bass); + uint16_t hdl_cursor = bass_env->start_hdl; + uint8_t status = PRF_APP_ERROR; + + // Browse list of services + // handle must be greater than current index + for(*svc_idx = 0 ; (*svc_idx < bass_env->svc_nb) && (handle >= hdl_cursor) ; (*svc_idx)++) + { + // check if it's a mandatory index + if(handle <= (hdl_cursor + BAS_IDX_BATT_LVL_VAL)) + { + *att_idx = handle -hdl_cursor; + status = GAP_ERR_NO_ERROR; + break; + } + + hdl_cursor += BAS_IDX_BATT_LVL_VAL; + + // check if it's a notify index + if(((bass_env->features >> *svc_idx) & 0x01) == BAS_BATT_LVL_NTF_SUP) + { + hdl_cursor++; + if(handle == hdl_cursor) + { + *att_idx = BAS_IDX_BATT_LVL_NTF_CFG; + status = GAP_ERR_NO_ERROR; + break; + } + } + + // check if it's battery level format + if(bass_env->svc_nb > 1) + { + hdl_cursor++; + if(handle == hdl_cursor) + { + *att_idx = BAS_IDX_BATT_LVL_PRES_FMT; + status = GAP_ERR_NO_ERROR; + break; + } + } + + hdl_cursor++; + } + + return (status); +} + +void bass_exe_operation(void) +{ + struct bass_env_tag* bass_env = PRF_ENV_GET(BASS, bass); + ASSERT_ERR(bass_env->operation != NULL); + bool finished = true; + uint8_t conidx = GAP_INVALID_CONIDX; + + // Restoring connection information requested + if(bass_env->operation->id == BASS_ENABLE_REQ) + { + struct bass_enable_req * enable = (struct bass_enable_req *) ke_msg2param(bass_env->operation); + conidx = enable->conidx; + // loop on all services to check if notification should be triggered + while(bass_env->cursor < BASS_NB_BAS_INSTANCES_MAX) + { + if(((bass_env->ntf_cfg[enable->conidx] & (1 << bass_env->cursor)) != 0) + && (enable->old_batt_lvl[bass_env->cursor] != bass_env->batt_lvl[bass_env->cursor])) + { + // trigger notification + bass_notify_batt_lvl(bass_env, enable->conidx, bass_env->cursor); + + finished = false; + bass_env->cursor++; + break; + } + bass_env->cursor++; + } + } + // Battery level updated + else if(bass_env->operation->id == BASS_BATT_LEVEL_UPD_REQ) + { + struct bass_batt_level_upd_req * update = (struct bass_batt_level_upd_req *) ke_msg2param(bass_env->operation); + + // loop on all connection + while(bass_env->cursor < BLE_CONNECTION_MAX) + { + if((bass_env->ntf_cfg[bass_env->cursor] & (1 << update->bas_instance)) != 0) + { + // trigger notification + bass_notify_batt_lvl(bass_env, bass_env->cursor, update->bas_instance); + finished = false; + bass_env->cursor++; + break; + } + bass_env->cursor++; + } + + } + // default, should not happen + else + { + ASSERT_ERR(0); + } + + // check if operation is finished + if(finished) + { + // trigger response message + if(bass_env->operation->id == BASS_ENABLE_REQ) + { + struct bass_enable_rsp * rsp = KE_MSG_ALLOC(BASS_ENABLE_RSP, bass_env->operation->src_id, + bass_env->operation->dest_id, bass_enable_rsp); + + rsp->conidx = conidx; + rsp->status = GAP_ERR_NO_ERROR; + ke_msg_send(rsp); + } + else if(bass_env->operation->id == BASS_BATT_LEVEL_UPD_REQ) + { + struct bass_batt_level_upd_rsp * rsp = KE_MSG_ALLOC(BASS_BATT_LEVEL_UPD_RSP, bass_env->operation->src_id, + bass_env->operation->dest_id, bass_batt_level_upd_rsp); + + rsp->status = GAP_ERR_NO_ERROR; + ke_msg_send(rsp); + } + + // free operation + ke_free(bass_env->operation); + bass_env->operation = NULL; + // go back to idle state + ke_state_set(prf_src_task_get(&(bass_env->prf_env), 0), BASS_IDLE); + } +} + + +#endif // (BLE_BATT_SERVER) + +/// @} BASS diff --git a/services/ble_profiles/bas/bass/src/bass.h b/services/ble_profiles/bas/bass/src/bass.h new file mode 100644 index 0000000..78035d3 --- /dev/null +++ b/services/ble_profiles/bas/bass/src/bass.h @@ -0,0 +1,172 @@ +#ifndef _BASS_H_ +#define _BASS_H_ + +/** + **************************************************************************************** + * @addtogroup BAPS Battery 'Profile' Server + * @ingroup BAP + * @brief Battery 'Profile' Server + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_BATT_SERVER) + +#include "bass_task.h" +#include "prf_types.h" +#include "prf.h" + +/* + * DEFINES + **************************************************************************************** + */ + +///Maximum number of Battery Server task instances +#define BASS_IDX_MAX 0x01 + +#define BAS_CFG_FLAG_MANDATORY_MASK (0x07) +#define BAS_CFG_FLAG_NTF_SUP_MASK (0x08) +#define BAS_CFG_FLAG_MTP_BAS_MASK (0x10) + +#define BASS_FLAG_NTF_CFG_BIT (0x02) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the BASS task +enum bass_state +{ + /// Idle state + BASS_IDLE, + /// busy state + BASS_BUSY, + /// Number of defined states. + BASS_STATE_MAX +}; + +/// Battery Service Attributes Indexes +enum +{ + BAS_IDX_SVC, + + BAS_IDX_BATT_LVL_CHAR, + BAS_IDX_BATT_LVL_VAL, + BAS_IDX_BATT_LVL_NTF_CFG, + BAS_IDX_BATT_LVL_PRES_FMT, + + BAS_IDX_NB, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Battery 'Profile' Server environment variable +struct bass_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Battery Level Characteristic Presentation Format - Should not change during connection + struct prf_char_pres_fmt batt_level_pres_format[BASS_NB_BAS_INSTANCES_MAX]; + /// On-going operation + struct ke_msg * operation; + /// BAS Services Start Handle + uint16_t start_hdl; + /// Level of the battery + uint8_t batt_lvl[BASS_NB_BAS_INSTANCES_MAX]; + /// BASS task state + ke_state_t state[BASS_IDX_MAX]; + /// Notification configuration of peer devices. + uint8_t ntf_cfg[BLE_CONNECTION_MAX]; + /// Database features + uint8_t features; + /// Number of BAS + uint8_t svc_nb; + /// Cursor on connection used to notify peer devices when battery level changes + uint8_t cursor; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve BAS service profile interface + * + * @return BAS service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* bass_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Retrieve Attribute handle from service and attribute index + * + * @param[in] svc_idx BAS Service index + * @param[in] att_idx Attribute index + * + * @return BAS attribute handle or INVALID HANDLE if nothing found + **************************************************************************************** + */ +uint16_t bass_get_att_handle(uint8_t svc_idx, uint8_t att_idx); + +/** + **************************************************************************************** + * @brief Retrieve Service and attribute index form attribute handle + * + * @param[out] handle Attribute handle + * @param[out] svc_idx BAS Service index + * @param[out] att_idx Attribute index + * + * @return Success if attribute and service index found, else Application error + **************************************************************************************** + */ +uint8_t bass_get_att_idx(uint16_t handle, uint8_t *svc_idx, uint8_t *att_idx); + +/** + **************************************************************************************** + * @brief This function fully manage notification of battery level to peer(s) device(s) + * according to on-going operation requested by application: + * - Modification of Battery Level + * - Indicate to a known device that battery level has change + **************************************************************************************** + */ +void bass_exe_operation(void); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void bass_task_init(struct ke_task_desc *task_desc); + + +#endif /* #if (BLE_BATT_SERVER) */ + +/// @} BASS + +#endif /* _BASS_H_ */ diff --git a/services/ble_profiles/bas/bass/src/bass_task.c b/services/ble_profiles/bas/bass/src/bass_task.c new file mode 100644 index 0000000..e881e3c --- /dev/null +++ b/services/ble_profiles/bas/bass/src/bass_task.c @@ -0,0 +1,390 @@ +/** + **************************************************************************************** + * @addtogroup BASSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_BATT_SERVER) + +#include "gap.h" +#include "gattc_task.h" + +#include "bass.h" +#include "bass_task.h" + +#include "prf_utils.h" + +#include "co_utils.h" + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref BAPS_ENABLE_REQ message. + * The handler enables the Battery 'Profile' Server Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int bass_enable_req_handler(ke_msg_id_t const msgid, + struct bass_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_SAVED; + uint8_t state = ke_state_get(dest_id); + + // check state of the task + if(state == BASS_IDLE) + { + struct bass_env_tag* bass_env = PRF_ENV_GET(BASS, bass); + + // Check provided values + if((param->conidx > BLE_CONNECTION_MAX) + || (gapc_get_conhdl(param->conidx) == GAP_INVALID_CONHDL)) + { + // an error occurs, trigg it. + struct bass_enable_rsp* rsp = KE_MSG_ALLOC(BASS_ENABLE_RSP, src_id, + dest_id, bass_enable_rsp); + rsp->conidx = param->conidx; + rsp->status = (param->conidx > BLE_CONNECTION_MAX) ? GAP_ERR_INVALID_PARAM : PRF_ERR_REQ_DISALLOWED; + ke_msg_send(rsp); + + msg_status = KE_MSG_CONSUMED; + } + else + { + // put task in a busy state + msg_status = KE_MSG_NO_FREE; + ke_state_set(dest_id, BASS_BUSY); + bass_env->ntf_cfg[param->conidx] = param->ntf_cfg; + bass_env->operation = ke_param2msg(param); + bass_env->cursor = 0; + + // trigger notification + bass_exe_operation(); + } + } + + return msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref BAPS_BATT_LEVEL_SEND_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int bass_batt_level_upd_req_handler(ke_msg_id_t const msgid, + struct bass_batt_level_upd_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_SAVED; + uint8_t state = ke_state_get(dest_id); + + // check state of the task + if(state == BASS_IDLE) + { + struct bass_env_tag* bass_env = PRF_ENV_GET(BASS, bass); + + // Check provided values + if((param->bas_instance < bass_env->svc_nb) && (param->batt_level <= BAS_BATTERY_LVL_MAX)) + { + // update the battery level value + bass_env->batt_lvl[param->bas_instance] = param->batt_level; + + // put task in a busy state + msg_status = KE_MSG_NO_FREE; + ke_state_set(dest_id, BASS_BUSY); + bass_env->operation = ke_param2msg(param); + bass_env->cursor = 0; + + // trigger notification + bass_exe_operation(); + } + else + { + // an error occurs, trigg it. + struct bass_batt_level_upd_rsp * rsp = KE_MSG_ALLOC(BASS_BATT_LEVEL_UPD_RSP, src_id, + dest_id, bass_batt_level_upd_rsp); + + rsp->status = PRF_ERR_INVALID_PARAM; + ke_msg_send(rsp); + msg_status = KE_MSG_CONSUMED; + } + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + struct gattc_att_info_cfm * cfm; + uint8_t svc_idx = 0, att_idx = 0; + // retrieve handle information + uint8_t status = bass_get_att_idx(param->handle, &svc_idx, &att_idx); + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + if(status == GAP_ERR_NO_ERROR) + { + // check if it's a client configuration char + if(att_idx == BAS_IDX_BATT_LVL_NTF_CFG) + { + // CCC attribute length = 2 + cfm->length = 2; + } + // not expected request + else + { + cfm->length = 0; + status = ATT_ERR_WRITE_NOT_PERMITTED; + } + } + + cfm->status = status; + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_WRITE_REQ_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + struct gattc_write_cfm * cfm; + uint8_t svc_idx = 0, att_idx = 0; + uint8_t conidx = KE_IDX_GET(src_id); + // retrieve handle information + uint8_t status = bass_get_att_idx(param->handle, &svc_idx, &att_idx); + + // If the attribute has been found, status is GAP_ERR_NO_ERROR + if (status == GAP_ERR_NO_ERROR) + { + struct bass_env_tag* bass_env = PRF_ENV_GET(BASS, bass); + // Extract value before check + uint16_t ntf_cfg = co_read16p(¶m->value[0]); + + // Only update configuration if value for stop or notification enable + if ((att_idx == BAS_IDX_BATT_LVL_NTF_CFG) + && ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF))) + { + + // Conserve information in environment + if (ntf_cfg == PRF_CLI_START_NTF) + { + // Ntf cfg bit set to 1 + bass_env->ntf_cfg[conidx] |= (BAS_BATT_LVL_NTF_SUP << svc_idx); + } + else + { + // Ntf cfg bit set to 0 + bass_env->ntf_cfg[conidx] &= ~(BAS_BATT_LVL_NTF_SUP << svc_idx); + } + + // Inform APP of configuration change + struct bass_batt_level_ntf_cfg_ind * ind = KE_MSG_ALLOC(BASS_BATT_LEVEL_NTF_CFG_IND, + prf_dst_task_get(&(bass_env->prf_env), conidx), dest_id, + bass_batt_level_ntf_cfg_ind); + ind->conidx = conidx; + ind->ntf_cfg = bass_env->ntf_cfg[conidx]; + + ke_msg_send(ind); + } + else + { + status = PRF_APP_ERROR; + } + + } + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_REQ_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + struct gattc_read_cfm * cfm; + uint8_t svc_idx = 0, att_idx = 0; + uint8_t conidx = KE_IDX_GET(src_id); + // retrieve handle information + uint8_t status = bass_get_att_idx(param->handle, &svc_idx, &att_idx); + uint16_t length = 0; + struct bass_env_tag* bass_env = PRF_ENV_GET(BASS, bass); + + // If the attribute has been found, status is GAP_ERR_NO_ERROR + if (status == GAP_ERR_NO_ERROR) + { + // read notification information + if (att_idx == BAS_IDX_BATT_LVL_VAL) + { + length = sizeof(uint8_t); + } + // read notification information + else if (att_idx == BAS_IDX_BATT_LVL_NTF_CFG) + { + length = sizeof(uint16_t); + } + else if(att_idx == BAS_IDX_BATT_LVL_PRES_FMT) + { + length = PRF_CHAR_PRES_FMT_SIZE; + } + else + { + status = PRF_APP_ERROR; + } + } + + //Send write response + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, length); + cfm->handle = param->handle; + cfm->status = status; + cfm->length = length; + + if (status == GAP_ERR_NO_ERROR) + { + // read notification information + if (att_idx == BAS_IDX_BATT_LVL_VAL) + { + cfm->value[0] = bass_env->batt_lvl[svc_idx]; + } + // retrieve notification config + else if (att_idx == BAS_IDX_BATT_LVL_NTF_CFG) + { + uint16_t ntf_cfg = (bass_env->ntf_cfg[conidx] >> svc_idx & BAS_BATT_LVL_NTF_SUP) ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; + co_write16p(cfm->value, ntf_cfg); + } + // retrieve battery level format + else if(att_idx == BAS_IDX_BATT_LVL_PRES_FMT) + { + prf_pack_char_pres_fmt(cfm->value, &(bass_env->batt_level_pres_format[svc_idx])); + } + else + { + /* Not Possible */ + } + } + + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY message meaning that Measurement + * notification has been correctly sent to peer device (but not confirmed by peer device). + * * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + if(param->operation == GATTC_NOTIFY) + { + // continue operation execution + bass_exe_operation(); + } + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(bass) +{ + {BASS_ENABLE_REQ, (ke_msg_func_t) bass_enable_req_handler}, + {BASS_BATT_LEVEL_UPD_REQ, (ke_msg_func_t) bass_batt_level_upd_req_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, +}; + +void bass_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct bass_env_tag *bass_env = PRF_ENV_GET(BASS, bass); + + task_desc->msg_handler_tab = bass_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(bass_msg_handler_tab); + task_desc->state = bass_env->state; + task_desc->idx_max = BASS_IDX_MAX; +} + + + +#endif /* #if (BLE_BATT_SERVER) */ + +/// @} BASSTASK diff --git a/services/ble_profiles/blp/blp_common.h b/services/ble_profiles/blp/blp_common.h new file mode 100644 index 0000000..7f735c9 --- /dev/null +++ b/services/ble_profiles/blp/blp_common.h @@ -0,0 +1,162 @@ +#ifndef _BLP_COMMON_H_ +#define _BLP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup BLP Blood Pressure Profile + * @ingroup PROFILE + * @brief Blood Pressure Profile + * + * The BLP module is the responsible block for implementing the Blood Pressure Profile + * functionalities in the BLE Host. + * + * The Blood Pressure Profile defines the functionality required in a device that allows + * the user (Collector device) to configure and recover blood pressure measurements from + * a blood pressure device. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "prf_types.h" +#include + +/* + * DEFINES + **************************************************************************************** + */ + +///BLPC codes for the 2 possible client configuration characteristic descriptors determination in BPS +enum +{ + ///Blood Pressure Measurement + BPS_BP_MEAS_CODE = 0x01, + ///Intermediate Cuff Pressure Measurement + BPS_INTERM_CP_CODE, +}; + +/// Blood Pressure Measurement Flags field bit values +enum +{ + /// pressure in millimetre of mercury + BPS_FLAG_MMHG = 0x00, + /// Pressure in pascal + BPS_FLAG_KPA = 0x01, + /// Time Stamp present + BPS_FLAG_TIME_STAMP_PRESENT = 0x02, + /// Pulse Rate present + BPS_FLAG_PULSE_RATE_PRESENT = 0x04, + /// User ID present + BPS_FLAG_USER_ID_PRESENT = 0x08, + /// Measurement Status present + BPS_FLAG_MEAS_STATUS_PRESENT = 0x10, +}; + +/// Blood Pressure Measurement Status Flags field bit values +enum +{ + /// Body Movement Detection Flag + /// No body movement + BPS_STATE_NO_BODY_MVMT_DETECTED = 0x0000, + /// Body movement during measurement + BPS_STATE_BODY_MVMT_DETECTED = 0x0001, + + /// Cuff Fit Detection Flag + /// Cuff fits properly + BPS_STATE_CUFF_FITS_PROPERLY = 0x0000, + /// Cuff too loose + BPS_STATE_CUFF_TOO_LOOSE = 0x0002, + + /// Irregular Pulse Detection Flag + /// No irregular pulse detected + BPS_STATE_NO_IRREGULAR_PULSE_DETECTED = 0x0000, + /// Irregular pulse detected + BPS_STATE_IRREGULAR_PULSE_DETECTED = 0x0004, + + /// Pulse Rate Range Detection Flags + /// Pulse rate is within the range + BPS_STATE_PR_IN_RANGE = 0x0000, + /// Pulse rate exceeds upper limit + BPS_STATE_PR_IN_TOO_HIGH = 0x0008, + /// Pulse rate is less than lower limit + BPS_STATE_PR_IN_TOO_LOW = 0x0010, + + /// Measurement Position Detection Flag + /// Proper measurement position + BPS_STATE_MEAS_POS_OK = 0x0000, + /// Improper measurement position + BPS_STATE_MEAS_POS_KO = 0x0020, +}; + +/// Blood Pressure Feature Flags field bit values +enum +{ + ///Body Movement Detection Support bit + ///Body Movement Detection feature not supported + BPS_F_BODY_MVMT_DETECT_NOT_SUPPORTED = 0x0000, + ///Body Movement Detection feature supported + BPS_F_BODY_MVMT_DETECT_SUPPORTED = 0x0001, + + ///Cuff Fit Detection Support bit + ///Cuff Fit Detection feature not supported + BPS_F_CUFF_FIT_DETECT_NOT_SUPPORTED = 0x0000, + ///Cuff Fit Detection feature supported + BPS_F_CUFF_FIT_DETECT_SUPPORTED = 0x0002, + + ///Irregular Pulse Detection Support bit + ///Irregular Pulse Detection feature not supported + BPS_F_IRREGULAR_PULSE_DETECT_NOT_SUPPORTED = 0x0000, + ///Irregular Pulse Detection feature supported + BPS_F_IRREGULAR_PULSE_DETECT_SUPPORTED = 0x0004, + + ///Pulse Rate Range Detection Support bit + ///Pulse Rate Range Detection feature not supported + BPS_F_PULSE_RATE_RANGE_DETECT_NOT_SUPPORTED = 0x0000, + ///Pulse Rate Range Detection feature supported + BPS_F_PULSE_RATE_RANGE_DETECT_SUPPORTED = 0x0008, + + ///Measurement Position Detection Support bit + ///Measurement Position Detection feature not supported + BPS_F_MEAS_POS_DETECT_NOT_SUPPORTED = 0x0000, + ///Measurement Position Detection feature supported + BPS_F_MEAS_POS_DETECT_SUPPORTED = 0x0010, + + ///Multiple Bond Support bit + ///Multiple Bonds not supported + BPS_F_MULTIPLE_BONDS_NOT_SUPPORTED = 0x0000, + ///Multiple Bonds supported + BPS_F_MULTIPLE_BONDS_SUPPORTED = 0x0020, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Blood Pressure measurement structure +struct bps_bp_meas +{ + /// Flag + uint8_t flags; + /// User ID + uint8_t user_id; + /// Systolic (mmHg/kPa) + prf_sfloat systolic; + /// Diastolic (mmHg/kPa) + prf_sfloat diastolic; + /// Mean Arterial Pressure (mmHg/kPa) + prf_sfloat mean_arterial_pressure; + /// Pulse Rate + prf_sfloat pulse_rate; + /// Measurement Status + uint16_t meas_status; + /// Time stamp + struct prf_date_time time_stamp; +}; + +/// @} blp_common + +#endif /* _BLP_COMMON_H_ */ diff --git a/services/ble_profiles/blp/blpc/api/blpc_task.h b/services/ble_profiles/blp/blpc/api/blpc_task.h new file mode 100644 index 0000000..83ff89a --- /dev/null +++ b/services/ble_profiles/blp/blpc/api/blpc_task.h @@ -0,0 +1,157 @@ +#ifndef _BLPC_TASK_H_ +#define _BLPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup BLPCTASK Blood Pressure Profile Collector Task + * @ingroup BLPC + * @brief Blood Pressure Profile Collector Task + * + * The BLPCTASK is responsible for handling the messages coming in and out of the + * @ref BLPC monitor block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" +#include "blp_common.h" + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +enum +{ + /// Start the blood pressure profile - at connection + BLPC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_BLPC), + ///Confirm that cfg connection has finished with discovery results, or that normal cnx started + BLPC_ENABLE_RSP, + + /// Generic message to read a BPS or DIS characteristic value + BLPC_RD_CHAR_REQ, + ///Generic message for read responses for APP + BLPC_RD_CHAR_RSP, + + ///Generic message for configuring the 2 characteristics that can be handled + BLPC_CFG_INDNTF_REQ, + ///Generic message for write characteristic response status to APP + BLPC_CFG_INDNTF_RSP, + + /// Blood pressure value send to APP + BLPC_BP_MEAS_IND, +}; + +/// Characteristics +enum +{ + /// Blood Pressure Measurement + BLPC_CHAR_BP_MEAS, + /// Intermediate Cuff pressure + BLPC_CHAR_CP_MEAS, + /// Blood Pressure Feature + BLPC_CHAR_BP_FEATURE, + + BLPC_CHAR_MAX, +}; + +/// Characteristic descriptors +enum +{ + /// Blood Pressure Measurement client config + BLPC_DESC_BP_MEAS_CLI_CFG, + /// Intermediate Cuff pressure client config + BLPC_DESC_IC_MEAS_CLI_CFG, + BLPC_DESC_MAX, + BLPC_DESC_MASK = 0x10, +}; + +///Structure containing the characteristics handles, value handles and descriptors +struct bps_content +{ + /// service info + struct prf_svc svc; + + /// characteristic info: + /// - Blood Pressure Measurement + /// - Intermediate Cuff pressure + /// - Blood Pressure Feature + struct prf_char_inf chars[BLPC_CHAR_MAX]; + + /// Descriptor handles: + /// - Blood Pressure Measurement client cfg + /// - Intermediate Cuff pressure client cfg + struct prf_char_desc_inf descs[BLPC_DESC_MAX]; +}; + + +/// Parameters of the @ref BLPC_ENABLE_REQ message +struct blpc_enable_req +{ + ///Connection type + uint8_t con_type; + ///Existing handle values bps + struct bps_content bps; +}; + +/// Parameters of the @ref BLPC_ENABLE_RSP message +struct blpc_enable_rsp +{ + ///status + uint8_t status; + ///Existing handle values bps + struct bps_content bps; +}; + + +///Parameters of the @ref BLPC_RD_CHAR_REQ message +struct blpc_rd_char_req +{ + ///Characteristic value code + uint8_t char_code; +}; + +///Parameters of the @ref BLPC_RD_CHAR_RSP message +struct blpc_rd_char_rsp +{ + /// Attribute data information + struct prf_att_info info; +}; + +///Parameters of the @ref BLPC_CFG_INDNTF_REQ message +struct blpc_cfg_indntf_req +{ + ///Own code for differentiating between blood pressure and + ///intermediate cuff pressure measurements + uint8_t char_code; + ///Stop/notify/indicate value to configure into the peer characteristic + uint16_t cfg_val; +}; + +///Parameters of the @ref BLPC_CFG_INDNTF_RSP message +struct blpc_cfg_indntf_rsp +{ + ///Status + uint8_t status; +}; + +///Parameters of the @ref BLPC_BP_MEAS_IND message +struct blpc_bp_meas_ind +{ + /// Flag indicating if it is a intermediary cuff pressure measurement (0) or + /// stable blood pressure measurement (1). + uint16_t flag_interm_cp; + ///Blood Pressure measurement + struct bps_bp_meas meas_val; +}; + +/// @} BLPCTASK + +#endif /* _BLPC_TASK_H_ */ diff --git a/services/ble_profiles/blp/blpc/src/blpc.c b/services/ble_profiles/blp/blpc/src/blpc.c new file mode 100644 index 0000000..8500eb1 --- /dev/null +++ b/services/ble_profiles/blp/blpc/src/blpc.c @@ -0,0 +1,235 @@ +/** + **************************************************************************************** + * @addtogroup BLPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_BP_COLLECTOR) +#include "blpc.h" +#include "blpc_task.h" +#include "gap.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the BLPC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t blpc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct blpc_env_tag* blpc_env = + (struct blpc_env_tag* ) ke_malloc(sizeof(struct blpc_env_tag), KE_MEM_ATT_DB); + + // allocate BLPC required environment variable + env->env = (prf_env_t*) blpc_env; + + blpc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + blpc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_BLPC; + blpc_task_init(&(env->desc)); + + for(idx = 0; idx < BLPC_IDX_MAX ; idx++) + { + blpc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), BLPC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void blpc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct blpc_env_tag* blpc_env = (struct blpc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(blpc_env->env[conidx] != NULL) + { + ke_free(blpc_env->env[conidx]); + blpc_env->env[conidx] = NULL; + } + + /* Put BLP Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), BLPC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the BLPC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void blpc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct blpc_env_tag* blpc_env = (struct blpc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < BLPC_IDX_MAX ; idx++) + { + blpc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(blpc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void blpc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put BLP Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), BLPC_IDLE); +} + +/// BLPC Task interface required by profile manager +const struct prf_task_cbs blpc_itf = +{ + blpc_init, + blpc_destroy, + blpc_create, + blpc_cleanup, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* blpc_prf_itf_get(void) +{ + return &blpc_itf; +} + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +void blpc_enable_rsp_send(struct blpc_env_tag *blpc_env, uint8_t conidx, uint8_t status) +{ + // Send to APP the details of the discovered attributes on BLPS + struct blpc_enable_rsp * rsp = KE_MSG_ALLOC( + BLPC_ENABLE_RSP, + prf_dst_task_get(&(blpc_env->prf_env), conidx), + prf_src_task_get(&(blpc_env->prf_env), conidx), + blpc_enable_rsp); + + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->bps = blpc_env->env[conidx]->bps; + + prf_register_atthdl2gatt(&(blpc_env->prf_env), conidx, &(blpc_env->env[conidx]->bps.svc)); + + // Go to connected state + ke_state_set(prf_src_task_get(&(blpc_env->prf_env), conidx), BLPC_IDLE); + } + + ke_msg_send(rsp); +} + +void blpc_unpack_meas_value(struct bps_bp_meas* pmeas_val, uint8_t* packed_bp) +{ + uint8_t cursor; + + // blood pressure measurement flags + pmeas_val->flags = packed_bp[0]; + + // Blood Pressure Measurement Compound Value - Systolic + pmeas_val->systolic = co_read16p(&(packed_bp[1])); + + // Blood Pressure Measurement Compound Value - Diastolic (mmHg) + pmeas_val->diastolic = co_read16p(&(packed_bp[3])); + + // Blood Pressure Measurement Compound Value - Mean Arterial Pressure (mmHg) + pmeas_val->mean_arterial_pressure = co_read16p(&(packed_bp[5])); + + cursor = 7; + + // time flag set + if ((pmeas_val->flags & BPS_FLAG_TIME_STAMP_PRESENT) == BPS_FLAG_TIME_STAMP_PRESENT) + { + cursor += prf_unpack_date_time(packed_bp + cursor, &(pmeas_val->time_stamp)); + } + + // pulse rate flag set + if ((pmeas_val->flags & BPS_FLAG_PULSE_RATE_PRESENT) == BPS_FLAG_PULSE_RATE_PRESENT) + { + pmeas_val->pulse_rate = co_read16p(&(packed_bp[cursor + 0])); + cursor += 2; + } + + // User ID flag set + if ((pmeas_val->flags & BPS_FLAG_USER_ID_PRESENT) == BPS_FLAG_USER_ID_PRESENT) + { + pmeas_val->user_id = packed_bp[cursor + 0]; + cursor += 1; + } + + // measurement status flag set + if ((pmeas_val->flags & BPS_FLAG_MEAS_STATUS_PRESENT) == BPS_FLAG_MEAS_STATUS_PRESENT) + { + pmeas_val->meas_status = co_read16p(&(packed_bp[cursor + 0])); + cursor += 2; + } +} + +#endif /* (BLE_BP_COLLECTOR) */ + +/// @} BLPC diff --git a/services/ble_profiles/blp/blpc/src/blpc.h b/services/ble_profiles/blp/blpc/src/blpc.h new file mode 100644 index 0000000..daffd36 --- /dev/null +++ b/services/ble_profiles/blp/blpc/src/blpc.h @@ -0,0 +1,155 @@ +#ifndef _BLPC_H_ +#define _BLPC_H_ + + +/** + **************************************************************************************** + * @addtogroup BLPC Blood Pressure Profile Collector + * @ingroup BLP + * @brief Blood Pressure Profile Collector + * + * The BLPC is responsible for providing Blood Pressure Profile Collector functionalities + * to upper layer module or application. The device using this profile takes the role + * of Blood Pressure Profile Collector. + * + * Blood Pressure Profile Collector. (BLPC): A BLPC (e.g. PC, phone, etc) + * is the term used by this profile to describe a device that can interpret blood pressure + * measurement in a way suitable to the user application. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_BP_COLLECTOR) + +#include "blpc_task.h" +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" + +/* + * DEFINES + **************************************************************************************** + */ + +///Maximum number of Blood Pressure Collector task instances +#define BLPC_IDX_MAX (BLE_CONNECTION_MAX) + +/// Possible states of the BLPC task +enum +{ + /// Free state + BLPC_FREE, + /// IDLE state + BLPC_IDLE, + /// Discovering Blood Pressure SVC and CHars + BLPC_DISCOVERING, + /// Busy state + BLPC_BUSY, + + /// Number of defined states. + BLPC_STATE_MAX +}; + +/// Internal codes for reading a BPS or DIS characteristic with one single request +enum +{ + ///Read BPS Blood pressure Measurement + BLPC_RD_BPS_BP_MEAS = BLPC_CHAR_BP_MEAS, + ///Read BPS Intermdiate Cuff Pressure + BLPC_RD_BPS_CP_MEAS = BLPC_CHAR_CP_MEAS, + ///Read BPS Blood pressure Features + BLPC_RD_BPS_FEATURE = BLPC_CHAR_BP_FEATURE, + + ///Read BPS Blood pressure Measurement Client Cfg. Desc + BLPC_RD_BPS_BP_MEAS_CFG = (BLPC_DESC_MASK | BLPC_DESC_BP_MEAS_CLI_CFG), + ///Read BPS Intermdiate Cuff Pressure Client Cfg. Desc + BLPC_RD_BPS_CP_MEAS_CFG = (BLPC_DESC_MASK | BLPC_DESC_IC_MEAS_CLI_CFG), +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ +struct blpc_cnx_env +{ + /// Last requested UUID(to keep track of the two services and char) + uint16_t last_uuid_req; + /// Last characteristic code used in a read or a write request + uint16_t last_char_code; + /// Counter used to check service uniqueness + uint8_t nb_svc; + /// Current operation code + uint8_t operation; + ///HTS characteristics + struct bps_content bps; +}; + +/// Blood Pressure Profile Collector environment variable +struct blpc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct blpc_cnx_env* env[BLPC_IDX_MAX]; + /// State of different task instances + ke_state_t state[BLPC_IDX_MAX]; +}; + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve BLP client profile interface + * @return BLP client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* blpc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Blood Pressure ATT DB discovery results to BLPC host. + **************************************************************************************** + */ +void blpc_enable_rsp_send(struct blpc_env_tag *blpc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Unpack Blood pressure measurement data into a comprehensive structure. + * + * @param[out] pmeas_val Pointer to Blood pressure measurement structure destination + * @param[in] packed_bp Pointer of the packed data of Blood Pressure Measurement + * information + **************************************************************************************** + */ +void blpc_unpack_meas_value(struct bps_bp_meas* pmeas_val, uint8_t* packed_bp); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void blpc_task_init(struct ke_task_desc *task_desc); + + +#endif /* (BLE_BP_COLLECTOR) */ + +/// @} BLPC + +#endif /* _BLPC_H_ */ diff --git a/services/ble_profiles/blp/blpc/src/blpc_task.c b/services/ble_profiles/blp/blpc/src/blpc_task.c new file mode 100644 index 0000000..707c530 --- /dev/null +++ b/services/ble_profiles/blp/blpc/src/blpc_task.c @@ -0,0 +1,543 @@ +/** + **************************************************************************************** + * @addtogroup BLPCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_BP_COLLECTOR) +#include "co_utils.h" +#include "blpc_task.h" +#include "blpc.h" +#include "gap.h" +#include "att.h" +#include "gattc_task.h" +#include "gapc_task.h" +#include "ke_mem.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// State machine used to retrieve blood pressure service characteristics information +const struct prf_char_def blpc_bps_char[BLPC_CHAR_MAX] = +{ + /// Blood Pressure Measurement + [BLPC_CHAR_BP_MEAS] = {ATT_CHAR_BLOOD_PRESSURE_MEAS, + ATT_MANDATORY, + ATT_CHAR_PROP_IND}, + /// Intermediate Cuff pressure + [BLPC_CHAR_CP_MEAS] = {ATT_CHAR_INTERMEDIATE_CUFF_PRESSURE, + ATT_OPTIONAL, + ATT_CHAR_PROP_NTF}, + /// Blood Pressure Feature + [BLPC_CHAR_BP_FEATURE] = {ATT_CHAR_BLOOD_PRESSURE_FEATURE, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, +}; + +/// State machine used to retrieve blood pressure service characteristic description information +const struct prf_char_desc_def blpc_bps_char_desc[BLPC_DESC_MAX] = +{ + /// Blood Pressure Measurement client config + [BLPC_DESC_BP_MEAS_CLI_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_MANDATORY, BLPC_CHAR_BP_MEAS}, + /// Intermediate Cuff pressure client config + [BLPC_DESC_IC_MEAS_CLI_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_MANDATORY, BLPC_CHAR_CP_MEAS}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == BLPC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct blpc_env_tag *blpc_env = PRF_ENV_GET(BLPC, blpc); + + ASSERT_INFO(blpc_env != NULL, dest_id, src_id); + ASSERT_INFO(blpc_env->env[conidx] != NULL, dest_id, src_id); + + if(blpc_env->env[conidx]->nb_svc == 0) + { + // Retrieve BLS characteristics and descriptors + prf_extract_svc_info(ind, BLPC_CHAR_MAX, &blpc_bps_char[0], &blpc_env->env[conidx]->bps.chars[0], + BLPC_DESC_MAX, &blpc_bps_char_desc[0], &blpc_env->env[conidx]->bps.descs[0]); + + //Even if we get multiple responses we only store 1 range + blpc_env->env[conidx]->bps.svc.shdl = ind->start_hdl; + blpc_env->env[conidx]->bps.svc.ehdl = ind->end_hdl; + } + + blpc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref BLPC_ENABLE_REQ message. + * The handler enables the Blood Pressure Profile Collector Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int blpc_enable_req_handler(ke_msg_id_t const msgid, + struct blpc_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + // Get state + uint8_t state = ke_state_get(dest_id); + + // Blood pressure Client Role Task Environment + struct blpc_env_tag *blpc_env = PRF_ENV_GET(BLPC, blpc); + + ASSERT_INFO(blpc_env != NULL, dest_id, src_id); + if((state == BLPC_IDLE) && (blpc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + blpc_env->env[conidx] = (struct blpc_cnx_env*) ke_malloc(sizeof(struct blpc_cnx_env),KE_MEM_ATT_DB); + memset(blpc_env->env[conidx], 0, sizeof(struct blpc_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering BPS on peer + prf_disc_svc_send(&(blpc_env->prf_env), conidx, ATT_SVC_BLOOD_PRESSURE); + + blpc_env->env[conidx]->last_uuid_req = ATT_SVC_BLOOD_PRESSURE; + + // Go to DISCOVERING state + ke_state_set(dest_id, BLPC_DISCOVERING); + } + //normal connection, get saved att details + else + { + blpc_env->env[conidx]->bps = param->bps; + + //send APP confirmation that can start normal connection to TH + blpc_enable_rsp_send(blpc_env, conidx, GAP_ERR_NO_ERROR); + } + } + + else if(state != BLPC_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + blpc_enable_rsp_send(blpc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + // Get the address of the environment + struct blpc_env_tag *blpc_env = PRF_ENV_GET(BLPC, blpc); + // Status + uint8_t status; + + if (blpc_env != NULL) + { + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if(state == BLPC_DISCOVERING) + { + status = param->status; + + if ((status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| + (status == ATT_ERR_NO_ERROR)) + { + // Discovery + // check characteristic validity + if(blpc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(BLPC_CHAR_MAX, + blpc_env->env[conidx]->bps.chars, + blpc_bps_char); + } + // too much services + else if (blpc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if (status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(BLPC_DESC_MAX, + blpc_env->env[conidx]->bps.descs, + blpc_bps_char_desc, + blpc_env->env[conidx]->bps.chars); + } + } + + blpc_enable_rsp_send(blpc_env, conidx, status); + } + + else if(BLPC_BUSY) + { + switch(param->operation) + { + + case GATTC_WRITE: + case GATTC_WRITE_NO_RESPONSE: + { + struct blpc_cfg_indntf_rsp *wr_cfm = KE_MSG_ALLOC( + BLPC_CFG_INDNTF_RSP, + prf_dst_task_get(&(blpc_env->prf_env), conidx), + prf_src_task_get(&(blpc_env->prf_env), conidx), + blpc_cfg_indntf_rsp); + //it will be a GATT status code + wr_cfm->status = param->status; + // send the message + ke_msg_send(wr_cfm); + } + break; + + case GATTC_READ: + { + if(param->status != GAP_ERR_NO_ERROR) + { + prf_client_att_info_rsp( + (prf_env_t*) blpc_env->env[conidx], + conidx, BLPC_RD_CHAR_RSP, + param->status, NULL); + } + } + break; + + default: break; + } + + ke_state_set(prf_src_task_get(&blpc_env->prf_env, conidx), BLPC_IDLE); + } + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref BLPC_RD_CHAR_REQ message. + * Check if the handle exists in profile(already discovered) and send request, otherwise + * error to APP. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int blpc_rd_char_req_handler(ke_msg_id_t const msgid, + struct blpc_rd_char_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + // Get the address of the environment + struct blpc_env_tag *blpc_env = PRF_ENV_GET(BLPC, blpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if((state == BLPC_IDLE) && (blpc_env->env[conidx] != NULL)) + { + uint16_t search_hdl = ATT_INVALID_SEARCH_HANDLE; + + if((param->char_code & BLPC_DESC_MASK) == BLPC_DESC_MASK) + { + search_hdl = blpc_env->env[conidx]->bps.descs[param->char_code & ~BLPC_DESC_MASK].desc_hdl; + } + else + { + search_hdl = blpc_env->env[conidx]->bps.chars[param->char_code].val_hdl; + } + + //check if handle is viable + if (search_hdl != ATT_INVALID_SEARCH_HANDLE) + { + prf_read_char_send( + &(blpc_env->prf_env), conidx, + blpc_env->env[conidx]->bps.svc.shdl, + blpc_env->env[conidx]->bps.svc.ehdl, + search_hdl); + + status = GAP_ERR_NO_ERROR; + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + + if (status != GAP_ERR_NO_ERROR) + { + prf_client_att_info_rsp( + (prf_env_t*) blpc_env->env[conidx], + conidx, BLPC_RD_CHAR_RSP, + status, NULL); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct blpc_env_tag *blpc_env = PRF_ENV_GET(BLPC, blpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + prf_client_att_info_rsp(&blpc_env->prf_env, conidx, BLPC_RD_CHAR_RSP, + GAP_ERR_NO_ERROR, param); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref BLPC_CFG_INDNTF_REQ message. + * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic. + * Will return an error code if that cfg char does not exist. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int blpc_cfg_indntf_req_handler(ke_msg_id_t const msgid, + struct blpc_cfg_indntf_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint16_t cfg_hdl = ATT_INVALID_SEARCH_HANDLE; + // Get the address of the environment + struct blpc_env_tag *blpc_env = PRF_ENV_GET(BLPC, blpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if((blpc_env->env[conidx] != NULL) && (ke_state_get(dest_id) == BLPC_IDLE)) + { + status = PRF_ERR_INVALID_PARAM; + //get handle of the configuration characteristic to set and check if value matches property + switch(param->char_code) + { + case BLPC_CHAR_BP_MEAS://can only IND + { + if((param->cfg_val == PRF_CLI_STOP_NTFIND)|| + (param->cfg_val == PRF_CLI_START_IND)) + { + cfg_hdl = blpc_env->env[conidx]->bps.descs[BLPC_DESC_BP_MEAS_CLI_CFG].desc_hdl; + } + }break; + + case BLPC_CHAR_CP_MEAS://can only NTF + { + if((param->cfg_val == PRF_CLI_STOP_NTFIND)|| + (param->cfg_val == PRF_CLI_START_NTF)) + { + cfg_hdl = blpc_env->env[conidx]->bps.descs[BLPC_DESC_IC_MEAS_CLI_CFG].desc_hdl; + } + + }break; + + default: + { + status = PRF_ERR_INEXISTENT_HDL; + }break; + } + + //check if the handle value exists + if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE) + { + // Send GATT Write Request + prf_gatt_write_ntf_ind(&blpc_env->prf_env, conidx, cfg_hdl, param->cfg_val); + // Set status + status = GAP_ERR_NO_ERROR; + } + } + + if (status != GAP_ERR_NO_ERROR) + { + struct blpc_cfg_indntf_rsp *rsp = KE_MSG_ALLOC(BLPC_CFG_INDNTF_RSP, src_id, dest_id, blpc_cfg_indntf_rsp); + + // It will be an PRF status code + rsp->status = status; + + // Send the message + ke_msg_send(rsp); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct blpc_env_tag *blpc_env = PRF_ENV_GET(BLPC, blpc); + + if(blpc_env->env[conidx] != NULL) + { + switch(param->type) + { + case GATTC_INDICATE: + { + // confirm that indication has been correctly received + struct gattc_event_cfm * cfm = KE_MSG_ALLOC(GATTC_EVENT_CFM, src_id, dest_id, gattc_event_cfm); + cfm->handle = param->handle; + ke_msg_send(cfm); + } + /* no break */ + + case GATTC_NOTIFY: + { + if((param->handle == blpc_env->env[conidx]->bps.chars[BLPC_CHAR_CP_MEAS].val_hdl) + || ((param->handle == blpc_env->env[conidx]->bps.chars[BLPC_CHAR_BP_MEAS].val_hdl))) + { + //build a BLPC_BP_MEAD_IND message with stable blood pressure value code. + struct blpc_bp_meas_ind * ind = KE_MSG_ALLOC( + BLPC_BP_MEAS_IND, + prf_dst_task_get(&(blpc_env->prf_env), conidx), + prf_src_task_get(&(blpc_env->prf_env), conidx), + blpc_bp_meas_ind); + + // Intermediate cuff pressure value + ind->flag_interm_cp = ((param->type == GATTC_NOTIFY) ? 0x01 : 0x00); + + // unpack blood pressure measurement. + blpc_unpack_meas_value(&(ind->meas_val), (uint8_t*) param->value); + + ke_msg_send(ind); + } + } break; + + default: break; + } + } + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(blpc) +{ + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {BLPC_ENABLE_REQ, (ke_msg_func_t)blpc_enable_req_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, + {BLPC_RD_CHAR_REQ, (ke_msg_func_t)blpc_rd_char_req_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_EVENT_REQ_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {BLPC_CFG_INDNTF_REQ, (ke_msg_func_t)blpc_cfg_indntf_req_handler}, +}; + +void blpc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct blpc_env_tag *blpc_env = PRF_ENV_GET(BLPC, blpc); + + task_desc->msg_handler_tab = blpc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(blpc_msg_handler_tab); + task_desc->state = blpc_env->state; + task_desc->idx_max = BLPC_IDX_MAX; +} + +#endif /* (BLE_BP_COLLECTOR) */ +/// @} BLPCTASK diff --git a/services/ble_profiles/blp/blps/api/blps_task.h b/services/ble_profiles/blp/blps/api/blps_task.h new file mode 100644 index 0000000..f9e2a05 --- /dev/null +++ b/services/ble_profiles/blp/blps/api/blps_task.h @@ -0,0 +1,127 @@ +#ifndef _BLPS_TASK_H_ +#define _BLPS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup BLPSTASK Task + * @ingroup BLPS + * @brief Blood Pressure Profile Task. + * + * The BLPSTASK is responsible for handling the messages coming in and out of the + * @ref BLPS collector block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include "rwip_task.h" // Task definitions +#include "blp_common.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +enum +{ + /// measurement sent by profile + BLPS_BP_MEAS_SEND, + /// peer device confirm reception + BLPS_CENTRAL_IND_CFM, +}; + +/// Messages for Blood Pressure Profile Sensor +enum +{ + ///Start the Blood Pressure Profile Sensor - at connection + BLPS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_BLPS), + /// Start the Blood Pressure Profile Sensor - at connection + BLPS_ENABLE_RSP, + + ///Send blood pressure measurement value from APP + BLPS_MEAS_SEND_REQ, + ///Send blood pressure measurement value confirm to APP so stable values can be erased + BLPS_MEAS_SEND_RSP, + + ///Inform APP of new configuration value + BLPS_CFG_INDNTF_IND, +}; + +/// Parameters of the @ref BLPS_ENABLE_REQ message +struct blps_enable_req +{ + ///Connection index + uint8_t conidx; + + /// Blood Pressure indication configuration + uint16_t bp_meas_ind_en; + /// Intermediate Cuff Pressure Notification configuration + uint16_t interm_cp_ntf_en; +}; + +/// Parameters of the @ref BLPS_ENABLE_RSP message +struct blps_enable_rsp +{ + ///Connection index + uint8_t conidx; + ///Status + uint8_t status; +}; + +///Parameters of the @ref BLPS_CFG_INDNTF_IND message +struct blps_cfg_indntf_ind +{ + ///Connection index + uint8_t conidx; + ///Own code for differentiating between Blood Pressure Measurement, and Intermediate + /// Cuff Pressure Measurement characteristics + uint8_t char_code; + ///Stop/notify/indicate value to configure into the peer characteristic + uint16_t cfg_val; +}; + +/////Parameters of the @ref BLPS_MEAS_SEND_REQ message +struct blps_meas_send_req +{ + ///Connection index + uint8_t conidx; + /// Flag indicating if it is a intermediary cuff pressure measurement (0) or + /// stable blood pressure measurement (1). + uint8_t flag_interm_cp; + ///Blood Pressure measurement + struct bps_bp_meas meas_val; +}; + +///Parameters of the @ref BLPS_MEAS_SEND_RSP message +struct blps_meas_send_rsp +{ + ///Connection index + uint8_t conidx; + ///Status + uint8_t status; +}; + +///Parameters of the @ref BLPS_CREATE_DB_REQ message +struct blps_db_cfg +{ + /// Supported features + uint16_t features; + /// Profile Configuration + uint8_t prfl_cfg; +}; + +/// @} BLPSTASK + +#endif /* _BLPS_TASK_H_ */ diff --git a/services/ble_profiles/blp/blps/src/blps.c b/services/ble_profiles/blp/blps/src/blps.c new file mode 100644 index 0000000..0fd5563 --- /dev/null +++ b/services/ble_profiles/blp/blps/src/blps.c @@ -0,0 +1,278 @@ +/** + **************************************************************************************** + * @addtogroup BLPS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_BP_SENSOR) +#include "gap.h" +#include "gattc_task.h" +#include "blps.h" +#include "blps_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * BLPS PROFILE ATTRIBUTES + **************************************************************************************** + */ + +/// Full BLPS Database Description - Used to add attributes into the database +const struct attm_desc blps_att_db[BPS_IDX_NB] = +{ + // Blood Pressure Service Declaration + [BPS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // Blood Pressure Measurement Characteristic Declaration + [BPS_IDX_BP_MEAS_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Blood Pressure Measurement Characteristic Value + [BPS_IDX_BP_MEAS_VAL] = {ATT_CHAR_BLOOD_PRESSURE_MEAS, PERM(IND, ENABLE), PERM(RI, ENABLE), BLPS_BP_MEAS_MAX_LEN}, + // Blood Pressure Measurement Characteristic - Client Characteristic Configuration Descriptor + [BPS_IDX_BP_MEAS_IND_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Blood Pressure Feature Characteristic Declaration + [BPS_IDX_BP_FEATURE_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Blood Pressure Feature Characteristic Value + [BPS_IDX_BP_FEATURE_VAL] = {ATT_CHAR_BLOOD_PRESSURE_FEATURE, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(uint16_t)}, + + // Intermediate Cuff Pressure Characteristic Declaration + [BPS_IDX_INTM_CUFF_PRESS_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Intermediate Cuff Pressure Characteristic Value + [BPS_IDX_INTM_CUFF_PRESS_VAL] = {ATT_CHAR_INTERMEDIATE_CUFF_PRESSURE, PERM(NTF, ENABLE), PERM(RI, ENABLE), BLPS_BP_MEAS_MAX_LEN}, + // Intermediate Cuff Pressure Characteristic - Client Characteristic Configuration Descriptor + [BPS_IDX_INTM_CUFF_PRESS_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the BLPS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t blps_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct blps_db_cfg* params) +{ + //------------------ create the attribute database for the profile ------------------- + // Service content flag + uint32_t cfg_flag= BLPS_MANDATORY_MASK; + // DB Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + //Set Configuration Flag Value + if (params->prfl_cfg & BLPS_INTM_CUFF_PRESS_SUP) + { + cfg_flag |= BLPS_INTM_CUFF_PRESS_MASK; + } + + // Add service in the database + status = attm_svc_create_db(start_hdl, ATT_SVC_BLOOD_PRESSURE, (uint8_t *)&cfg_flag, + BPS_IDX_NB, NULL, env->task, &blps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, DISABLE)); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // Allocate BLPS required environment variable + struct blps_env_tag* blps_env = + (struct blps_env_tag* ) ke_malloc(sizeof(struct blps_env_tag), KE_MEM_ATT_DB); + + // Initialize BLPS environment + env->env = (prf_env_t*) blps_env; + blps_env->shdl = *start_hdl; + blps_env->features = params->features; + blps_env->prfl_cfg = params->prfl_cfg; + + blps_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Multi Instantiated task + blps_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_BLPS; + blps_task_init(&(env->desc)); + + memset(blps_env->prfl_ntf_ind_cfg, 0, BLE_CONNECTION_MAX); + + /* Put BLS in disabled state */ + ke_state_set(env->task, BLPS_IDLE); + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the BLPS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void blps_destroy(struct prf_task_env* env) +{ + struct blps_env_tag* blps_env = (struct blps_env_tag*) env->env; + + // free profile environment variables + env->env = NULL; + ke_free(blps_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void blps_create(struct prf_task_env* env, uint8_t conidx) +{ + struct blps_env_tag* blps_env = (struct blps_env_tag*) env->env; + blps_env->prfl_ntf_ind_cfg[conidx] = 0; + + /* Put BLS in idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), BLPS_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void blps_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct blps_env_tag* blps_env = (struct blps_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + blps_env->prfl_ntf_ind_cfg[conidx] = 0; +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// BLPS Task interface required by profile manager +const struct prf_task_cbs blps_itf = +{ + (prf_init_fnct) blps_init, + blps_destroy, + blps_create, + blps_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* blps_prf_itf_get(void) +{ + return &blps_itf; +} + +uint8_t blps_pack_meas_value(uint8_t *packed_bp, const struct bps_bp_meas* pmeas_val) +{ + uint8_t cursor; + + *(packed_bp) = pmeas_val->flags; + + // Blood Pressure Measurement Compound Value - Systolic + co_write16p(packed_bp + 1, pmeas_val->systolic); + + // Blood Pressure Measurement Compound Value - Diastolic (mmHg) + co_write16p(packed_bp + 3, pmeas_val->diastolic); + + // Blood Pressure Measurement Compound Value - Mean Arterial Pressure (mmHg) + co_write16p(packed_bp + 5, pmeas_val->mean_arterial_pressure); + + cursor = 7; + + // time flag set + if ((pmeas_val->flags & BPS_FLAG_TIME_STAMP_PRESENT) == BPS_FLAG_TIME_STAMP_PRESENT) + { + cursor += prf_pack_date_time(packed_bp + cursor, &(pmeas_val->time_stamp)); + } + + // Pulse rate flag set + if ((pmeas_val->flags & BPS_FLAG_PULSE_RATE_PRESENT) == BPS_FLAG_PULSE_RATE_PRESENT) + { + co_write16p(packed_bp + cursor, pmeas_val->pulse_rate); + cursor += 2; + } + + // User ID flag set + if ((pmeas_val->flags & BPS_FLAG_USER_ID_PRESENT) == BPS_FLAG_USER_ID_PRESENT) + { + *(packed_bp + cursor) = pmeas_val->user_id; + cursor += 1; + } + + // Measurement status flag set + if ((pmeas_val->flags & BPS_FLAG_MEAS_STATUS_PRESENT) == BPS_FLAG_MEAS_STATUS_PRESENT) + { + co_write16p(packed_bp + cursor, pmeas_val->meas_status); + cursor += 2; + } + + // clear unused packet data + if(cursor < BLPS_BP_MEAS_MAX_LEN) + { + memset(packed_bp + cursor, 0, BLPS_BP_MEAS_MAX_LEN - cursor); + } + + return cursor; +} + +void blps_meas_send_rsp_send(uint8_t conidx, uint8_t status) +{ + // Get the address of the environment + struct blps_env_tag *blps_env = PRF_ENV_GET(BLPS, blps); + + struct blps_meas_send_rsp * rsp = KE_MSG_ALLOC(BLPS_MEAS_SEND_RSP, + prf_dst_task_get(&blps_env->prf_env, conidx), + prf_src_task_get(&blps_env->prf_env, conidx), + blps_meas_send_rsp); + + rsp->conidx = conidx; + rsp->status = status; + + ke_msg_send(rsp); +} + +#endif /* BLE_BP_SENSOR */ + +/// @} BLPS diff --git a/services/ble_profiles/blp/blps/src/blps.h b/services/ble_profiles/blp/blps/src/blps.h new file mode 100644 index 0000000..0498261 --- /dev/null +++ b/services/ble_profiles/blp/blps/src/blps.h @@ -0,0 +1,215 @@ +#ifndef _BLPS_H_ +#define _BLPS_H_ + +/** + **************************************************************************************** + * @addtogroup BLPS Blood Pressure Profile Sensor + * @ingroup BLP + * @brief Blood Pressure Profile Sensor + * + * Blood pressure sensor (BPS) profile provides functionalities to upper layer module + * application. The device using this profile takes the role of Blood pressure sensor. + * + * The interface of this role to the Application is: + * - Enable the profile role (from APP) + * - Disable the profile role (from APP) + * - Notify peer device during Blood Pressure measurement (from APP) + * - Indicate measurements performed to peer device (from APP) + * + * Profile didn't manages multiple users configuration and storage of offline measurements. + * This must be handled by application. + * + * Blood Pressure Profile Sensor. (BLPS): A BLPS (e.g. PC, phone, etc) + * is the term used by this profile to describe a device that can perform blood pressure + * measurement and notify about on-going measurement and indicate final result to a peer + * BLE device. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "blp_common.h" + +#if (BLE_BP_SENSOR) + +#include "prf_types.h" +#include "prf.h" +#include "blps_task.h" +#include "attm.h" + +/* + * DEFINES + **************************************************************************************** + */ +///Maximum number of Blood Pressure task instances +#define BLPS_IDX_MAX 0x01 + +/// Maximum notification length +#define BLPS_BP_MEAS_MAX_LEN (19) + +///BPS Configuration Flag Masks +#define BLPS_MANDATORY_MASK (0x003F) +#define BLPS_INTM_CUFF_PRESS_MASK (0x01C0) + +/* + * MACROS + **************************************************************************************** + */ + +/// Possible states of the BLPS task +enum +{ + /// Idle state + BLPS_IDLE, + /// Busy state + BLPS_BUSY, + + /// Number of defined states. + BLPS_STATE_MAX +}; + + +#define BLPS_IS_SUPPORTED(mask) \ + (((blps_env->prfl_cfg & mask) == mask)) + +#define BLPS_IS_ENABLED(mask, conidx) \ + (((blps_env->prfl_ntf_ind_cfg[conidx] & mask) == mask)) + +///Attributes State Machine +enum +{ + BPS_IDX_SVC, + + BPS_IDX_BP_MEAS_CHAR, + BPS_IDX_BP_MEAS_VAL, + BPS_IDX_BP_MEAS_IND_CFG, + + BPS_IDX_BP_FEATURE_CHAR, + BPS_IDX_BP_FEATURE_VAL, + + BPS_IDX_INTM_CUFF_PRESS_CHAR, + BPS_IDX_INTM_CUFF_PRESS_VAL, + BPS_IDX_INTM_CUFF_PRESS_NTF_CFG, + + BPS_IDX_NB, +}; + +///Characteristic Codes +enum +{ + BPS_BP_MEAS_CHAR, + BPS_INTM_CUFF_MEAS_CHAR, + BPS_BP_FEATURE_CHAR, +}; + +///Database Configuration Bit Field Flags +enum +{ + /// support of Intermediate Cuff Pressure + BLPS_INTM_CUFF_PRESS_SUP = 0x01, +}; + +/// Indication/notification configuration (put in feature flag to optimize memory usage) +enum +{ + /// Bit used to know if blood pressure measurement indication is enabled + BLPS_BP_MEAS_IND_CFG = 0x02, + /// Bit used to know if cuff pressure measurement notification is enabled + BLPS_INTM_CUFF_PRESS_NTF_CFG = 0x04, + /// indication/notification config mask + BLPS_NTFIND_MASK = 0x06, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Blood Pressure Profile Sensor environment variable per connection +struct blps_cnx_env +{ + /// Profile Notify/Indication Flags + uint8_t prfl_ntf_ind_cfg; +}; + +/// Blood Pressure Profile Sensor environment variable +struct blps_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Blood Pressure Service Start Handle + uint16_t shdl; + /// Feature Configuration Flags + uint16_t features; + /// Profile configuration flags + uint8_t prfl_cfg; + /// Event (notification/indication) config + uint8_t evt_cfg; + /// Environment variable pointer for each connections + uint8_t prfl_ntf_ind_cfg[BLE_CONNECTION_MAX]; + /// State of different task instances + ke_state_t state[BLPS_IDX_MAX]; +}; + + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve BLP service profile interface + * + * @return BLP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* blps_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Pack Blood Pressure measurement value + * + * @param p_meas_val Blood Pressure measurement value + * + * @return size of packed value + **************************************************************************************** + */ +uint8_t blps_pack_meas_value(uint8_t *packed_bp, const struct bps_bp_meas* pmeas_val); + +/** + **************************************************************************************** + * @brief Send a BLPS_MEAS_SEND_RSP to the application + **************************************************************************************** + */ +void blps_meas_send_rsp_send(uint8_t conidx, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void blps_task_init(struct ke_task_desc *task_desc); + + +#endif /* #if (BLE_BP_SENSOR) */ + +/// @} BLPS + +#endif /* _BLPS_H_ */ diff --git a/services/ble_profiles/blp/blps/src/blps_task.c b/services/ble_profiles/blp/blps/src/blps_task.c new file mode 100644 index 0000000..fb839d6 --- /dev/null +++ b/services/ble_profiles/blp/blps/src/blps_task.c @@ -0,0 +1,412 @@ +/** + **************************************************************************************** + * @addtogroup BLPSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_BP_SENSOR) +#include "co_utils.h" + +#include "gap.h" +#include "gattc_task.h" +#include "blps.h" +#include "blps_task.h" +#include "prf_utils.h" + + + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref BLPS_ENABLE_REQ message. + * The handler enables the Blood Pressure Sensor Profile and initialize readable values. + * @param[in] msgid Id of the message received (probably unused).off + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int blps_enable_req_handler(ke_msg_id_t const msgid, + struct blps_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct blps_env_tag *blps_env = PRF_ENV_GET(BLPS, blps); + + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(gapc_get_conhdl(param->conidx) == GAP_INVALID_CONHDL) + { + status = PRF_ERR_DISCONNECTED; + } + else if(ke_state_get(dest_id) == BLPS_IDLE) + { + if (param->interm_cp_ntf_en == PRF_CLI_START_NTF) + { + // Enable Bonded Data + blps_env->prfl_ntf_ind_cfg[param->conidx] |= BLPS_INTM_CUFF_PRESS_NTF_CFG; + } + + if (param->bp_meas_ind_en == PRF_CLI_START_IND) + { + // Enable Bonded Data + blps_env->prfl_ntf_ind_cfg[param->conidx] |= BLPS_BP_MEAS_IND_CFG; + } + + status = GAP_ERR_NO_ERROR; + } + + // send completed information to APP task that contains error status + struct blps_enable_rsp *cmp_evt = KE_MSG_ALLOC(BLPS_ENABLE_RSP, src_id, dest_id, blps_enable_rsp); + cmp_evt->status = status; + cmp_evt->conidx = param->conidx; + ke_msg_send(cmp_evt); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == BLPS_IDLE) + { + // Get the address of the environment + struct blps_env_tag *blps_env = PRF_ENV_GET(BLPS, blps); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t att_idx = param->handle - blps_env->shdl; + + uint16_t value = 0; + uint8_t status = ATT_ERR_NO_ERROR; + + switch(att_idx) + { + case BPS_IDX_BP_FEATURE_VAL: + { + value = blps_env->features; + } break; + + case BPS_IDX_BP_MEAS_IND_CFG: + { + value = (blps_env->prfl_ntf_ind_cfg[conidx] & BLPS_BP_MEAS_IND_CFG) + ? PRF_CLI_START_IND : PRF_CLI_STOP_NTFIND; + } break; + case BPS_IDX_INTM_CUFF_PRESS_NTF_CFG: + { + // Characteristic is profile specific + if (BLPS_IS_SUPPORTED(BLPS_INTM_CUFF_PRESS_SUP)) + { + // Fill data + value = (blps_env->prfl_ntf_ind_cfg[conidx] & BLPS_INTM_CUFF_PRESS_NTF_CFG) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; + } + else + { + status = ATT_ERR_ATTRIBUTE_NOT_FOUND; + } + } break; + + default: + { + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } break; + } + + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->length = sizeof(uint16_t); + memcpy(cfm->value, &value, sizeof(uint16_t)); + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref BLPS_MEAS_SEND_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int blps_meas_send_req_handler(ke_msg_id_t const msgid, + struct blps_meas_send_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + if(gapc_get_conhdl(param->conidx) == GAP_INVALID_CONHDL) + { + status = PRF_ERR_DISCONNECTED; + } + else if(ke_state_get(dest_id) == BLPS_IDLE) + { + // Get the address of the environment + struct blps_env_tag *blps_env = PRF_ENV_GET(BLPS, blps); + + //Intermediary blood pressure, must be notified if enabled + if (param->flag_interm_cp) + { + // Check if supported + if (BLPS_IS_SUPPORTED(BLPS_INTM_CUFF_PRESS_SUP)) + { + if (!BLPS_IS_ENABLED(BLPS_INTM_CUFF_PRESS_NTF_CFG, param->conidx)) + { + status = PRF_ERR_NTF_DISABLED; + } + } + else + { + status = PRF_ERR_FEATURE_NOT_SUPPORTED; + } + } + + //Stable Blood Pressure Measurement, must be indicated if enabled + else if(! BLPS_IS_ENABLED(BLPS_BP_MEAS_IND_CFG, param->conidx)) + { + status = PRF_ERR_IND_DISABLED; + } + + // Check if message can be sent + if (status == GAP_ERR_NO_ERROR) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, param->conidx), dest_id, + gattc_send_evt_cmd, BLPS_BP_MEAS_MAX_LEN); + + // Fill event type and handle which trigger event + if (param->flag_interm_cp) + { + meas_val->operation = GATTC_NOTIFY; + meas_val->handle = blps_env->shdl + BPS_IDX_INTM_CUFF_PRESS_VAL; + } + else + { + // Fill in the parameter structure + meas_val->operation = GATTC_INDICATE; + meas_val->handle = blps_env->shdl + BPS_IDX_BP_MEAS_VAL; + } + + //Pack the BP Measurement value + meas_val->length = blps_pack_meas_value(meas_val->value, ¶m->meas_val); + + // Send the event + ke_msg_send(meas_val); + // Go to busy state + ke_state_set(dest_id, BLPS_BUSY); + } + } + else + { + // Save it for later + msg_status = KE_MSG_SAVED; + } + + if(status != GAP_ERR_NO_ERROR) + { + // Send error message to application + blps_meas_send_rsp_send(param->conidx, status); + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. + * The handler compares the new values with current ones and notifies them if they changed. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct blps_env_tag *blps_env = PRF_ENV_GET(BLPS, blps); + uint8_t conidx = KE_IDX_GET(src_id); + + uint16_t value = 0x0000; + uint8_t status = GAP_ERR_NO_ERROR; + uint8_t char_code = 0; + + //Extract value before check + memcpy(&value, &(param->value), sizeof(uint16_t)); + + //BP Measurement Char. - Client Char. Configuration + if (param->handle == (blps_env->shdl + BPS_IDX_BP_MEAS_IND_CFG)) + { + if ((value == PRF_CLI_STOP_NTFIND) || (value == PRF_CLI_START_IND)) + { + char_code = BPS_BP_MEAS_CHAR; + + if (value == PRF_CLI_STOP_NTFIND) + { + blps_env->prfl_ntf_ind_cfg[conidx] &= ~BLPS_BP_MEAS_IND_CFG; + } + else //PRF_CLI_START_IND + { + blps_env->prfl_ntf_ind_cfg[conidx] |= BLPS_BP_MEAS_IND_CFG; + } + } + else + { + status = PRF_APP_ERROR; + } + } + else if (param->handle == (blps_env->shdl + BPS_IDX_INTM_CUFF_PRESS_NTF_CFG)) + { + if ((value == PRF_CLI_STOP_NTFIND) || (value == PRF_CLI_START_NTF)) + { + char_code = BPS_INTM_CUFF_MEAS_CHAR; + + if (value == PRF_CLI_STOP_NTFIND) + { + blps_env->prfl_ntf_ind_cfg[conidx] &= ~BLPS_INTM_CUFF_PRESS_NTF_CFG; + } + else //PRF_CLI_START_NTF + { + blps_env->prfl_ntf_ind_cfg[conidx] |= BLPS_INTM_CUFF_PRESS_NTF_CFG; + } + } + else + { + status = PRF_APP_ERROR; + } + } + + if (status == GAP_ERR_NO_ERROR) + { + //Inform APP of configuration change + struct blps_cfg_indntf_ind * ind = KE_MSG_ALLOC( + BLPS_CFG_INDNTF_IND, + prf_dst_task_get(&blps_env->prf_env, conidx), + prf_src_task_get(&blps_env->prf_env, conidx), + blps_cfg_indntf_ind); + + ind->conidx = conidx; + ind->char_code = char_code; + memcpy(&ind->cfg_val, &value, sizeof(uint16_t)); + + ke_msg_send(ind); + } + + + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY and GATT_INDICATE message meaning + * that Measurement notification/indication has been correctly sent to peer device + * + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(src_id); + + switch(param->operation) + { + case GATTC_NOTIFY: + case GATTC_INDICATE: + { + // Send confirmation + blps_meas_send_rsp_send(conidx, param->status); + // Go to idle state + ke_state_set(dest_id, BLPS_IDLE); + } + break; + + default: break; + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(blps) +{ + {BLPS_ENABLE_REQ, (ke_msg_func_t) blps_enable_req_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {BLPS_MEAS_SEND_REQ, (ke_msg_func_t) blps_meas_send_req_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, +}; + +void blps_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct blps_env_tag *blps_env = PRF_ENV_GET(BLPS, blps); + + task_desc->msg_handler_tab = blps_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(blps_msg_handler_tab); + task_desc->state = blps_env->state; + task_desc->idx_max = BLPS_IDX_MAX; +} + +#endif /* #if (BLE_BP_SENSOR) */ + +/// @} BLPSTASK diff --git a/services/ble_profiles/cpp/cpp_common.h b/services/ble_profiles/cpp/cpp_common.h new file mode 100644 index 0000000..4e4e81d --- /dev/null +++ b/services/ble_profiles/cpp/cpp_common.h @@ -0,0 +1,441 @@ +#ifndef _CPP_COMMON_H_ +#define _CPP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup CPP Cycling Power Profile + * @ingroup PROFILE + * @brief Cycling Power Profile + * + * The Cycling Power Profile is used to enable a collector device in order to obtain + * data from a Cycling Power Sensor (CP Sensor) that exposes the Cycling Power Service + * in sports and fitness applications. + * + * This file contains all definitions that are common for the server and the client parts + * of the profile. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "prf_types.h" +#include + +/* + * DEFINES + **************************************************************************************** + */ +/// Procedure Already in Progress Error Code +#define CPP_ERROR_PROC_IN_PROGRESS (0x80) + +/// CP Measurement Notification Value Max Length +#define CPP_CP_MEAS_NTF_MAX_LEN (35) +/// CP Measurement Value Min Length +#define CPP_CP_MEAS_NTF_MIN_LEN (4) + +/// ADV Header size +#define CPP_CP_ADV_HEADER_LEN (3) +/// ADV Length size +#define CPP_CP_ADV_LENGTH_LEN (1) + +/// CP Measurement Advertisement Value Max Length +#define CPP_CP_MEAS_ADV_MAX_LEN (CPP_CP_MEAS_NTF_MAX_LEN + CPP_CP_ADV_HEADER_LEN) +/// CP Measurement Value Min Length +#define CPP_CP_MEAS_ADV_MIN_LEN (CPP_CP_MEAS_NTF_MIN_LEN + CPP_CP_ADV_HEADER_LEN) + +/// CP Vector Value Max Length +#define CPP_CP_VECTOR_MAX_LEN (19) +/// CP Vector Value Min Length +#define CPP_CP_VECTOR_MIN_LEN (1) + +/// CP Control Point Value Max Length +#define CPP_CP_CNTL_PT_REQ_MAX_LEN (9) +/// CP Control Point Value Min Length +#define CPP_CP_CNTL_PT_REQ_MIN_LEN (1) + +/// CP Control Point Value Max Length +#define CPP_CP_CNTL_PT_RSP_MAX_LEN (20) +/// CP Control Point Value Min Length +#define CPP_CP_CNTL_PT_RSP_MIN_LEN (3) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// CPP Service Characteristics +enum cpp_cpps_char +{ + /// CPP Measurement + CPP_CPS_MEAS_CHAR, + /// CPP Feature + CPP_CPS_FEAT_CHAR, + /// Sensor Location + CPP_CPS_SENSOR_LOC_CHAR, + ///Cycling Power Vector + CPP_CPS_VECTOR_CHAR, + /// CP Control Point + CPP_CPS_CTNL_PT_CHAR, + + CPP_CPS_CHAR_MAX, +}; + +/// CPP Measurement Flags +enum cpp_meas_flags +{ + /// Pedal Power Balance Present + CPP_MEAS_PEDAL_POWER_BALANCE_PRESENT = 0x0001, + /// Pedal Power Balance Reference + CPP_MEAS_PEDAL_POWER_BALANCE_REFERENCE = 0x0002, + /// Accumulated Torque Present + CPP_MEAS_ACCUM_TORQUE_PRESENT = 0x0004, + /// Accumulated Torque Source + CPP_MEAS_ACCUM_TORQUE_SOURCE = 0x0008, + /// Wheel Revolution Data Present + CPP_MEAS_WHEEL_REV_DATA_PRESENT = 0x0010, + /// Crank Revolution Data Present + CPP_MEAS_CRANK_REV_DATA_PRESENT = 0x0020, + /// Extreme Force Magnitudes Present + CPP_MEAS_EXTREME_FORCE_MAGNITUDES_PRESENT = 0x0040, + /// Extreme Torque Magnitudes Present + CPP_MEAS_EXTREME_TORQUE_MAGNITUDES_PRESENT = 0x0080, + /// Extreme Angles Present + CPP_MEAS_EXTREME_ANGLES_PRESENT = 0x0100, + /// Top Dead Spot Angle Present + CPP_MEAS_TOP_DEAD_SPOT_ANGLE_PRESENT = 0x0200, + /// Bottom Dead Spot Angle Present + CPP_MEAS_BOTTOM_DEAD_SPOT_ANGLE_PRESENT = 0x0400, + /// Accumulated Energy Present + CPP_MEAS_ACCUM_ENERGY_PRESENT = 0x0800, + /// Offset Compensation Indicator + CPP_MEAS_OFFSET_COMPENSATION_INDICATOR = 0x1000, + + /// All Supported + CPP_MEAS_ALL_SUPP = 0x1FFF, +}; + +/// CPP Feature Flags +enum cpp_feat_flags +{ + /// Pedal Power Balance Supported + CPP_FEAT_PEDAL_POWER_BALANCE_SUPP = 0x00000001, + /// Accumulated Torque Supported + CPP_FEAT_ACCUM_TORQUE_SUPP = 0x00000002, + /// Wheel Revolution Data Supported + CPP_FEAT_WHEEL_REV_DATA_SUPP = 0x00000004, + /// Crank Revolution Data Supported + CPP_FEAT_CRANK_REV_DATA_SUPP = 0x00000008, + /// Extreme Magnitudes Supported + CPP_FEAT_EXTREME_MAGNITUDES_SUPP = 0x00000010, + /// Extreme Angles Supported + CPP_FEAT_EXTREME_ANGLES_SUPP = 0x00000020, + /// Top and Bottom Dead Spot Angles Supported + CPP_FEAT_TOPBOT_DEAD_SPOT_ANGLES_SUPP = 0x00000040, + /// Accumulated Energy Supported + CPP_FEAT_ACCUM_ENERGY_SUPP = 0x00000080, + /// Offset Compensation Indicator Supported + CPP_FEAT_OFFSET_COMP_IND_SUPP = 0x00000100, + /// Offset Compensation Supported + CPP_FEAT_OFFSET_COMP_SUPP = 0x00000200, + /// CP Measurement CH Content Masking Supported + CPP_FEAT_CP_MEAS_CH_CONTENT_MASKING_SUPP = 0x00000400, + /// Multiple Sensor Locations Supported + CPP_FEAT_MULT_SENSOR_LOC_SUPP = 0x00000800, + /// Crank Length Adjustment Supported + CPP_FEAT_CRANK_LENGTH_ADJ_SUPP = 0x00001000, + /// Chain Length Adjustment Supported + CPP_FEAT_CHAIN_LENGTH_ADJ_SUPP = 0x00002000, + /// Chain Weight Adjustment Supported + CPP_FEAT_CHAIN_WEIGHT_ADJ_SUPP = 0x00004000, + /// Span Length Adjustment Supported + CPP_FEAT_SPAN_LENGTH_ADJ_SUPP = 0x00008000, + /// Sensor Measurement Context + CPP_FEAT_SENSOR_MEAS_CONTEXT = 0x00010000, + /// Instantaneous Measurement Direction Supported + CPP_FEAT_INSTANT_MEAS_DIRECTION_SUPP = 0x00020000, + /// Factory Calibration Date Supported + CPP_FEAT_FACTORY_CALIBRATION_DATE_SUPP = 0x00040000, + + /// All supported + CPP_FEAT_ALL_SUPP = 0x0007FFFF, +}; + +/// CPP Sensor Locations Keys +enum cpp_sensor_loc +{ + /// Other (0) + CPP_LOC_OTHER = 0, + /// Top of shoe (1) + CPP_LOC_TOP_SHOE, + /// In shoe (2) + CPP_LOC_IN_SHOE, + /// Hip (3) + CPP_LOC_HIP, + /// Front Wheel (4) + CPP_LOC_FRONT_WHEEL, + /// Left Crank (5) + CPP_LOC_LEFT_CRANK, + /// Right Crank (6) + CPP_LOC_RIGHT_CRANK, + /// Left Pedal (7) + CPP_LOC_LEFT_PEDAL, + /// Right Pedal (8) + CPP_LOC_RIGHT_PEDAL, + /// Front Hub (9) + CPP_LOC_FRONT_HUB, + /// Rear Dropout (10) + CPP_LOC_REAR_DROPOUT, + /// Chainstay (11) + CPP_LOC_CHAINSTAY, + /// Rear Wheel (12) + CPP_LOC_REAR_WHEEL, + /// Rear Hub (13) + CPP_LOC_REAR_HUB, + /// Chest (14) + CPP_LOC_CHEST, + + CPP_LOC_MAX, +}; + +/// CPP Vector Flags +enum cpp_vector_flags +{ + /// Crank Revolution Data Present + CPP_VECTOR_CRANK_REV_DATA_PRESENT = 0x01, + /// First Crank Measurement Angle Present + CPP_VECTOR_FIRST_CRANK_MEAS_ANGLE_PRESENT = 0x02, + /// Instantaneous Force Magnitude Array Present + CPP_VECTOR_INST_FORCE_MAGNITUDE_ARRAY_PRESENT = 0x04, + /// Instantaneous Torque Magnitude Array Present + CPP_VECTOR_INST_TORQUE_MAGNITUDE_ARRAY_PRESENT = 0x08, + /// Instantaneous Measurement Direction LSB + CPP_VECTOR_INST_MEAS_DIRECTION_LSB = 0x10, + /// Instantaneous Measurement Direction MSB + CPP_VECTOR_INST_MEAS_DIRECTION_MSB = 0x20, + + ///All suported + CPP_VECTOR_ALL_SUPP = 0x3F, +}; + +/// CPP Control Point Code Keys +enum cpp_ctnl_pt_code +{ + /// Reserved value + CPP_CTNL_PT_RESERVED = 0, + + /// Set Cumulative Value + CPP_CTNL_PT_SET_CUMUL_VAL, + /// Update Sensor Location + CPP_CTNL_PT_UPD_SENSOR_LOC, + /// Request Supported Sensor Locations + CPP_CTNL_PT_REQ_SUPP_SENSOR_LOC, + /// Set Crank Length + CPP_CTNL_PT_SET_CRANK_LENGTH, + /// Request Crank Length + CPP_CTNL_PT_REQ_CRANK_LENGTH, + /// Set Chain Length + CPP_CTNL_PT_SET_CHAIN_LENGTH, + /// Request Chain Length + CPP_CTNL_PT_REQ_CHAIN_LENGTH, + /// Set Chain Weight + CPP_CTNL_PT_SET_CHAIN_WEIGHT, + /// Request Chain Weight + CPP_CTNL_PT_REQ_CHAIN_WEIGHT, + /// Set Span Length + CPP_CTNL_PT_SET_SPAN_LENGTH, + /// Request Span Length + CPP_CTNL_PT_REQ_SPAN_LENGTH, + /// Start Offset Compensation + CPP_CTNL_PT_START_OFFSET_COMP, + /// Mask CP Measurement Characteristic Content + CPP_CTNL_MASK_CP_MEAS_CH_CONTENT, + /// Request Sampling Rate + CPP_CTNL_REQ_SAMPLING_RATE, + /// Request Factory Calibration Date + CPP_CTNL_REQ_FACTORY_CALIBRATION_DATE, + + /// Response Code + CPP_CTNL_PT_RSP_CODE = 32, +}; + +/// CPP Control Point Response Value +enum cpp_ctnl_pt_resp_val +{ + /// Reserved value + CPP_CTNL_PT_RESP_RESERVED = 0, + + /// Success + CPP_CTNL_PT_RESP_SUCCESS, + /// Operation Code Not Supported + CPP_CTNL_PT_RESP_NOT_SUPP, + /// Invalid Parameter + CPP_CTNL_PT_RESP_INV_PARAM, + /// Operation Failed + CPP_CTNL_PT_RESP_FAILED, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// CP Measurement +struct cpp_cp_meas +{ + /// Flags + uint16_t flags; + /// Instantaneous Power + int16_t inst_power; + /// Pedal Power Balance + uint8_t pedal_power_balance; + /// Accumulated torque + uint16_t accum_torque; + /// Cumulative Wheel Revolutions + int16_t cumul_wheel_rev; + /// Last Wheel Event Time + uint16_t last_wheel_evt_time; + /// Cumulative Crank Revolution + uint16_t cumul_crank_rev; + /// Last Crank Event Time + uint16_t last_crank_evt_time; + /// Maximum Force Magnitude + int16_t max_force_magnitude; + /// Minimum Force Magnitude + int16_t min_force_magnitude; + /// Maximum Torque Magnitude + int16_t max_torque_magnitude; + /// Minimum Torque Magnitude + int16_t min_torque_magnitude; + /// Maximum Angle (12 bits) + uint16_t max_angle; + /// Minimum Angle (12bits) + uint16_t min_angle; + /// Top Dead Spot Angle + uint16_t top_dead_spot_angle; + /// Bottom Dead Spot Angle + uint16_t bot_dead_spot_angle; + ///Accumulated energy + uint16_t accum_energy; + +}; + +/// CP Measurement +struct cpp_cp_meas_ind +{ + /// Flags + uint16_t flags; + /// Instantaneous Power + int16_t inst_power; + /// Pedal Power Balance + uint8_t pedal_power_balance; + /// Accumulated torque + uint16_t accum_torque; + /// Cumulative Wheel Revolutions + uint32_t cumul_wheel_rev; + /// Last Wheel Event Time + uint16_t last_wheel_evt_time; + /// Cumulative Crank Revolution + uint16_t cumul_crank_rev; + /// Last Crank Event Time + uint16_t last_crank_evt_time; + /// Maximum Force Magnitude + int16_t max_force_magnitude; + /// Minimum Force Magnitude + int16_t min_force_magnitude; + /// Maximum Torque Magnitude + int16_t max_torque_magnitude; + /// Minimum Torque Magnitude + int16_t min_torque_magnitude; + /// Maximum Angle (12 bits) + uint16_t max_angle; + /// Minimum Angle (12bits) + uint16_t min_angle; + /// Top Dead Spot Angle + uint16_t top_dead_spot_angle; + /// Bottom Dead Spot Angle + uint16_t bot_dead_spot_angle; + ///Accumulated energy + uint16_t accum_energy; + +}; + + +///CP Vector +struct cpp_cp_vector +{ + /// Flags + uint8_t flags; + /// Force-Torque Magnitude Array Length + uint8_t nb; + /// Cumulative Crank Revolutions + uint16_t cumul_crank_rev; + /// Last Crank Event Time + uint16_t last_crank_evt_time; + /// First Crank Measurement Angle + uint16_t first_crank_meas_angle; + ///Mutually excluded Force and Torque Magnitude Arrays + int16_t force_torque_magnitude[__ARRAY_EMPTY]; +}; + +/// CP Control Point Request +struct cpp_ctnl_pt_req +{ + /// Operation Code + uint8_t op_code; + /// Value + union cpp_ctnl_pt_req_val + { + /// Cumulative Value + uint32_t cumul_val; + /// Sensor Location + uint8_t sensor_loc; + /// Crank Length + uint16_t crank_length; + /// Chain Length + uint16_t chain_length; + /// Chain Weight + uint16_t chain_weight; + /// Span Length + uint16_t span_length; + /// Mask Content + uint16_t mask_content; + } value; +}; + +/// CP Control Point Response +struct cpp_ctnl_pt_rsp +{ + /// Requested Operation Code + uint8_t req_op_code; + /// Response Value + uint8_t resp_value; + + ///Value + union cpp_ctnl_pt_rsp_val + { + /// List of supported locations + uint32_t supp_loc; + /// Crank Length + uint16_t crank_length; + /// Chain Length + uint16_t chain_length; + /// Chain Weight + uint16_t chain_weight; + /// Span Length + uint16_t span_length; + /// Start Offset Compensation + int16_t offset_comp; + /// Sampling Rate Procedure + uint8_t sampling_rate; + /// Calibration date + struct prf_date_time factory_calibration; + } value; +}; + +/// @} cpp_common + +#endif //(_CPP_COMMON_H_) diff --git a/services/ble_profiles/cpp/cppc/api/cppc_task.h b/services/ble_profiles/cpp/cppc/api/cppc_task.h new file mode 100644 index 0000000..27d9487 --- /dev/null +++ b/services/ble_profiles/cpp/cppc/api/cppc_task.h @@ -0,0 +1,237 @@ +#ifndef _CPPC_TASK_H_ +#define _CPPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup CPPCTASK Cycling Power Profile Collector Task + * @ingroup CPPC + * @brief Cycling Power Profile Collector Task + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "cpp_common.h" + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" + + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Cycling Power Service Characteristic Descriptors +enum cppc_cps_descs +{ + /// CP Measurement Char. - Client Characteristic Configuration + CPPC_DESC_CP_MEAS_CL_CFG, + /// CP Measurement Char. - Server Characteristic Configuration + CPPC_DESC_CP_MEAS_SV_CFG, + /// CP Vector Char. - Client Characteristic Configuration + CPPC_DESC_VECTOR_CL_CFG, + /// Control Point Char. - Client Characteristic Configuration + CPPC_DESC_CTNL_PT_CL_CFG, + + CPPC_DESC_MAX, + + CPPC_DESC_MASK = 0x10, +}; + +/// Message IDs +enum cppc_msg_ids +{ + /// Enable the Cycling Power Profile Collector task - at connection + CPPC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_CPPC), + /// Confirm that cfg connection has finished with discovery results, or that normal cnx started + CPPC_ENABLE_RSP, + + /// Read the value of an attribute in the peer device database + CPPC_READ_CMD, + + /// Configure sending of notification or indication + CPPC_CFG_NTFIND_CMD, + + /// Configure the SC Control Point value + CPPC_CTNL_PT_CFG_REQ, + /// Indicate that an control point response has been triggered by peer device + CPPC_CTNL_PT_RSP, + + /// Indicate that an attribute value has been received either upon notification or read response + CPPC_VALUE_IND, + + /// Complete Event Information + CPPC_CMP_EVT, + + /// Procedure Timeout Timer + CPPC_TIMEOUT_TIMER_IND, +}; + +/// Operation Codes +enum cppc_op_code +{ + /// Reserved operation code + CPPC_RESERVED_OP_CODE = 0x00, + + /// Discovery Procedure + CPPC_ENABLE_OP_CODE, + /// Read attribute value Procedure + CPPC_READ_OP_CODE, + + /// Wait for the Write Response after having written a Client Char. Cfg. Descriptor. + CPPC_CFG_NTF_IND_OP_CODE, + + /// Wait for the Write Response after having written the Control Point Char. + CPPC_CTNL_PT_CFG_WR_OP_CODE, + /// Wait for the Indication Response after having written the Control Point Char. + CPPC_CTNL_PT_CFG_IND_OP_CODE, +}; + +/* + * API MESSAGE STRUCTURES + **************************************************************************************** + */ + +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Cycling Power Service + */ +struct cppc_cps_content +{ + /// Service info + struct prf_svc svc; + + /// Characteristic info: + /// - CP Measurement + /// - CP Feature + /// - Sensor Location + /// - Vector + /// - SC Control Point + struct prf_char_inf chars[CPP_CPS_CHAR_MAX]; + + /// Descriptor handles: + /// - CP Measurement Client Cfg + /// - Vector Client Cfg + /// - Control Point Client Cfg + struct prf_char_desc_inf descs[CPPC_DESC_MAX]; +}; + +/// Parameters of the @ref CPPC_ENABLE_REQ message +struct cppc_enable_req +{ + /// Connection type + uint8_t con_type; + /// Existing handle values CPS + struct cppc_cps_content cps; +}; + +/// Parameters of the @ref CPPC_ENABLE_RSP message +struct cppc_enable_rsp +{ + /// status + uint8_t status; + /// Existing handle values CPS + struct cppc_cps_content cps; +}; + +/// Parameters of the @ref CPPC_READ_CMD message +struct cpps_read_cmd +{ + /// Operation Code + uint8_t operation; + /// Read code + uint8_t read_code; +}; + +/// Parameters of the @ref CPPC_CFG_NTFIND_CMD message +struct cppc_cfg_ntfind_cmd +{ + /// Operation Code + uint8_t operation; + /// Descriptor code + uint8_t desc_code; + /// Ntf/Ind Configuration + uint16_t ntfind_cfg; +}; + +/// Parameters of the @ref CPPC_CTNL_PT_CFG_REQ message +struct cppc_ctnl_pt_cfg_req +{ + /// Operation Code + uint8_t operation; + /// SC Control Point Request + struct cpp_ctnl_pt_req ctnl_pt; +}; + +/// Parameters of the @ref CPPC_VALUE_IND message +struct cppc_value_ind +{ + /// Attribute Code + uint8_t att_code; + /// Value + union cppc_value_tag + { + /// CP Feature + uint32_t sensor_feat; + /// CP Measurement + struct cpp_cp_meas cp_meas; + /// Sensor Vector + struct cpp_cp_vector cp_vector; + /// Client Characteristic Configuration Descriptor Value + uint16_t ntf_cfg; + /// Sensor Location + uint8_t sensor_loc; + } value; +}; + + +/// Parameters of the @ref CPPC_VALUE_IND message +struct cppc_value_meas_ind +{ + /// Attribute Code + uint8_t att_code; + /// Value + union cppc_value_tag2 + { + /// CP Feature + uint32_t sensor_feat; + /// CP Measurement + struct cpp_cp_meas_ind cp_meas; + /// Sensor Vector + struct cpp_cp_vector cp_vector; + /// Client Characteristic Configuration Descriptor Value + uint16_t ntf_cfg; + /// Sensor Location + uint8_t sensor_loc; + } value; +}; + + + + +/// Parameters of the @ref CPPC_CTNL_PT_RSP message +struct cppc_ctnl_pt_rsp +{ + /// SC Control Point Response + struct cpp_ctnl_pt_rsp rsp; +}; + +/// Parameters of the @ref CPPC_CMP_EVT message +struct cppc_cmp_evt +{ + /// Operation code + uint8_t operation; + /// Status + uint8_t status; +}; + +/// @} CPPCTASK + +#endif //(_CPPC_TASK_H_) diff --git a/services/ble_profiles/cpp/cppc/src/cppc.c b/services/ble_profiles/cpp/cppc/src/cppc.c new file mode 100644 index 0000000..dd7f3f9 --- /dev/null +++ b/services/ble_profiles/cpp/cppc/src/cppc.c @@ -0,0 +1,751 @@ +/** + **************************************************************************************** + * @addtogroup CPPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_CP_COLLECTOR) + +#include "cpp_common.h" +#include "cppc.h" +#include "cppc_task.h" +#include "ke_timer.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * GLOBAL VARIABLES DECLARATION + **************************************************************************************** + */ + + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the CPPC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t cppc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct cppc_env_tag* cppc_env = + (struct cppc_env_tag* ) ke_malloc(sizeof(struct cppc_env_tag), KE_MEM_ATT_DB); + + // allocate CPPC required environment variable + env->env = (prf_env_t*) cppc_env; + + cppc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + cppc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_CPPC; + cppc_task_init(&(env->desc)); + + for(idx = 0; idx < CPPC_IDX_MAX ; idx++) + { + cppc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), CPPC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void cppc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct cppc_env_tag* cppc_env = (struct cppc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(cppc_env->env[conidx] != NULL) + { + if (cppc_env->env[conidx]->operation != NULL) + { + ke_free(ke_param2msg(cppc_env->env[conidx]->operation)); + } + ke_timer_clear(CPPC_TIMEOUT_TIMER_IND, prf_src_task_get(&cppc_env->prf_env, conidx)); + ke_free(cppc_env->env[conidx]); + cppc_env->env[conidx] = NULL; + } + + /* Put CPP Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), CPPC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the CPPC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void cppc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct cppc_env_tag* cppc_env = (struct cppc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < CPPC_IDX_MAX ; idx++) + { + cppc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(cppc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void cppc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put CPP Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), CPPC_IDLE); +} + +/// CPPC Task interface required by profile manager +const struct prf_task_cbs cppc_itf = +{ + cppc_init, + cppc_destroy, + cppc_create, + cppc_cleanup, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* cppc_prf_itf_get(void) +{ + return &cppc_itf; +} + + +void cppc_enable_rsp_send(struct cppc_env_tag *cppc_env, uint8_t conidx, uint8_t status) +{ + // Send to APP the details of the discovered attributes on CPPS + struct cppc_enable_rsp * rsp = KE_MSG_ALLOC( + CPPC_ENABLE_RSP, + prf_dst_task_get(&(cppc_env->prf_env), conidx), + prf_src_task_get(&(cppc_env->prf_env), conidx), + cppc_enable_rsp); + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->cps = cppc_env->env[conidx]->cps; + // Register CPPC task in gatt for indication/notifications + prf_register_atthdl2gatt(&(cppc_env->prf_env), conidx, &(cppc_env->env[conidx]->cps.svc)); + // Go to connected state + ke_state_set(prf_src_task_get(&(cppc_env->prf_env), conidx), CPPC_IDLE); + } + + ke_msg_send(rsp); +} + + +void cppc_send_no_conn_cmp_evt(uint8_t src_id, uint8_t dest_id, uint8_t operation) +{ + // Send the message + struct cppc_cmp_evt *evt = KE_MSG_ALLOC(CPPC_CMP_EVT, + dest_id, src_id, + cppc_cmp_evt); + + evt->operation = operation; + evt->status = PRF_ERR_REQ_DISALLOWED; + + ke_msg_send(evt); +} + +void cppc_send_cmp_evt(struct cppc_env_tag *cppc_env, uint8_t conidx, uint8_t operation, uint8_t status) +{ + // Free the stored operation if needed + if (cppc_env->env[conidx]->operation != NULL) + { + ke_msg_free(ke_param2msg(cppc_env->env[conidx]->operation)); + cppc_env->env[conidx]->operation = NULL; + } + + // Go back to the IDLE state if the state is busy + if (ke_state_get(prf_src_task_get(&(cppc_env->prf_env), conidx)) == CPPC_BUSY) + { + ke_state_set(prf_src_task_get(&cppc_env->prf_env, conidx), CPPC_IDLE); + } + + // Send the message + struct cppc_cmp_evt *evt = KE_MSG_ALLOC(CPPC_CMP_EVT, + prf_dst_task_get(&(cppc_env->prf_env), conidx), + prf_src_task_get(&(cppc_env->prf_env), conidx), + cppc_cmp_evt); + + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +uint16_t cppc_get_read_handle_req (struct cppc_env_tag *cppc_env, uint8_t conidx, struct cpps_read_cmd *param) +{ + // Attribute Handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + + switch (param->read_code) + { + // Read CP Feature + case (CPPC_RD_CP_FEAT): + { + handle = cppc_env->env[conidx]->cps.chars[CPP_CPS_FEAT_CHAR].val_hdl; + } break; + + // Read Sensor Location + case (CPPC_RD_SENSOR_LOC): + { + handle = cppc_env->env[conidx]->cps.chars[CPP_CPS_SENSOR_LOC_CHAR].val_hdl; + } break; + + // Read CP Measurement Characteristic Client Char. Cfg. Descriptor Value + case (CPPC_RD_WR_CP_MEAS_CL_CFG): + { + handle = cppc_env->env[conidx]->cps.descs[CPPC_DESC_CP_MEAS_CL_CFG].desc_hdl; + } break; + + // Read CP Measurement Characteristic Server Char. Cfg. Descriptor Value + case (CPPC_RD_WR_CP_MEAS_SV_CFG): + { + handle = cppc_env->env[conidx]->cps.descs[CPPC_DESC_CP_MEAS_SV_CFG].desc_hdl; + } break; + + // Read CP Vector Characteristic Server Char. Cfg. Descriptor Value + case (CPPC_RD_WR_VECTOR_CFG): + { + handle = cppc_env->env[conidx]->cps.descs[CPPC_DESC_VECTOR_CL_CFG].desc_hdl; + } break; + + // Read Unread Alert Characteristic Client Char. Cfg. Descriptor Value + case (CPPC_RD_WR_CTNL_PT_CFG): + { + handle = cppc_env->env[conidx]->cps.descs[CPPC_DESC_CTNL_PT_CL_CFG].desc_hdl; + } break; + + default: + { + handle = ATT_INVALID_SEARCH_HANDLE; + } break; + } + + return handle; +} + +uint8_t cppc_get_write_desc_handle_req (uint8_t conidx, struct cppc_cfg_ntfind_cmd *param, struct cppc_env_tag *cppc_env, uint16_t *handle) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + switch(param->desc_code) + { + // Write CP Measurement Characteristic Client Char. Cfg. Descriptor Value + case (CPPC_RD_WR_CP_MEAS_CL_CFG): + { + if (param->ntfind_cfg <= PRF_CLI_START_NTF) + { + *handle = cppc_env->env[conidx]->cps.descs[CPPC_DESC_CP_MEAS_CL_CFG].desc_hdl; + + // The descriptor is mandatory + ASSERT_ERR(*handle != ATT_INVALID_SEARCH_HANDLE); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + // Write CP Measurement Characteristic Server Char. Cfg. Descriptor Value + case (CPPC_RD_WR_CP_MEAS_SV_CFG): + { + if (param->ntfind_cfg <= PRF_SRV_START_BCST) + { + *handle = cppc_env->env[conidx]->cps.descs[CPPC_DESC_CP_MEAS_SV_CFG].desc_hdl; + + if (*handle == ATT_INVALID_SEARCH_HANDLE) + { + // The descriptor has not been found. + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + break; + + // Write CP Vector Characteristic Client Char. Cfg. Descriptor Value + case (CPPC_RD_WR_VECTOR_CFG): + { + if (param->ntfind_cfg <= PRF_CLI_START_NTF) + { + *handle = cppc_env->env[conidx]->cps.descs[CPPC_DESC_VECTOR_CL_CFG].desc_hdl; + + if (*handle == ATT_INVALID_SEARCH_HANDLE) + { + // The descriptor has not been found. + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + break; + + // Write SC Control Point Characteristic Client Char. Cfg. Descriptor Value + case (CPPC_RD_WR_CTNL_PT_CFG): + { + if ((param->ntfind_cfg == PRF_CLI_STOP_NTFIND) || + (param->ntfind_cfg == PRF_CLI_START_IND)) + { + *handle = cppc_env->env[conidx]->cps.descs[CPPC_DESC_CTNL_PT_CL_CFG].desc_hdl; + + if (*handle == ATT_INVALID_SEARCH_HANDLE) + { + // The descriptor has not been found. + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + + return (status); +} + +uint8_t cppc_unpack_meas_ind (uint8_t conidx, struct gattc_event_ind const *param, struct cppc_env_tag *cppc_env) +{ + // CP Measurement value has been received + struct cppc_value_meas_ind *ind = KE_MSG_ALLOC( + CPPC_VALUE_IND, + prf_dst_task_get(&(cppc_env->prf_env), conidx), + prf_src_task_get(&(cppc_env->prf_env), conidx), + cppc_value_meas_ind); + + // Offset + uint8_t offset = CPP_CP_MEAS_NTF_MIN_LEN; + + // Attribute code + ind->att_code = CPPC_NTF_CP_MEAS; + + // Flags + ind->value.cp_meas.flags = co_read16p(¶m->value[0]); + // Instant power + ind->value.cp_meas.inst_power = co_read16p(¶m->value[2]); + + if (ind->value.cp_meas.flags & CPP_MEAS_PEDAL_POWER_BALANCE_PRESENT) + { + //Unpack Pedal Power Balance info + ind->value.cp_meas.pedal_power_balance = param->value[offset]; + offset++; + } + + if (ind->value.cp_meas.flags & CPP_MEAS_ACCUM_TORQUE_PRESENT) + { + //Unpack Accumulated Torque info + ind->value.cp_meas.accum_torque = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (ind->value.cp_meas.flags & CPP_MEAS_WHEEL_REV_DATA_PRESENT) + { + //Unpack Wheel Revolution Data (Cumulative Wheel & Last Wheel Event Time) + ind->value.cp_meas.cumul_wheel_rev = co_read32p(¶m->value[offset]); + offset += 4; + ind->value.cp_meas.last_wheel_evt_time = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (ind->value.cp_meas.flags & CPP_MEAS_CRANK_REV_DATA_PRESENT) + { + //Unpack Crank Revolution Data (Cumulative Crank & Last Crank Event Time) + ind->value.cp_meas.cumul_crank_rev = co_read16p(¶m->value[offset]); + offset += 2; + ind->value.cp_meas.last_crank_evt_time = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (ind->value.cp_meas.flags & CPP_MEAS_EXTREME_FORCE_MAGNITUDES_PRESENT) + { + //Unpack Extreme Force Magnitudes (Maximum Force Magnitude & Minimum Force Magnitude) + ind->value.cp_meas.max_force_magnitude = co_read16p(¶m->value[offset]); + offset += 2; + ind->value.cp_meas.min_force_magnitude = co_read16p(¶m->value[offset]); + offset += 2; + } + + else if (ind->value.cp_meas.flags & CPP_MEAS_EXTREME_TORQUE_MAGNITUDES_PRESENT) + { + //Unpack Extreme Force Magnitudes (Maximum Force Magnitude & Minimum Force Magnitude) + ind->value.cp_meas.max_torque_magnitude = co_read16p(¶m->value[offset]); + offset += 2; + ind->value.cp_meas.min_torque_magnitude = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (ind->value.cp_meas.flags & CPP_MEAS_EXTREME_ANGLES_PRESENT) + { + //Unpack Extreme Angles (Maximum Angle & Minimum Angle) + uint32_t angle = co_read24p(¶m->value[offset]); + offset += 3; + + //Force to 12 bits + ind->value.cp_meas.max_angle = (angle & (0x0FFF)); + ind->value.cp_meas.min_angle = ((angle>>12) & 0x0FFF); + } + + if (ind->value.cp_meas.flags & CPP_MEAS_TOP_DEAD_SPOT_ANGLE_PRESENT) + { + //Unpack Top Dead Spot Angle + ind->value.cp_meas.top_dead_spot_angle = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (ind->value.cp_meas.flags & CPP_MEAS_BOTTOM_DEAD_SPOT_ANGLE_PRESENT) + { + //Unpack Bottom Dead Spot Angle + ind->value.cp_meas.bot_dead_spot_angle = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (ind->value.cp_meas.flags & CPP_MEAS_ACCUM_ENERGY_PRESENT) + { + //Unpack Accumulated Energy + ind->value.cp_meas.accum_energy = co_read16p(¶m->value[offset]); + offset += 2; + } + + // Send the message + ke_msg_send(ind); + + return offset; +} + +uint8_t cppc_unpack_vector_ind (uint8_t conidx, struct gattc_event_ind const *param, struct cppc_env_tag *cppc_env) +{ + // CP Measurement value has been received + struct cppc_value_ind *ind = KE_MSG_ALLOC_DYN( + CPPC_VALUE_IND, + prf_dst_task_get(&cppc_env->prf_env, conidx), + prf_src_task_get(&cppc_env->prf_env, conidx), + cppc_value_ind, + param->length); + + // Offset + uint8_t offset = CPP_CP_VECTOR_MIN_LEN; + + // Attribute code + ind->att_code = CPPC_NTF_CP_VECTOR; + + // Flags + ind->value.cp_vector.flags = param->value[0]; + + if (ind->value.cp_vector.flags & CPP_VECTOR_CRANK_REV_DATA_PRESENT) + { + // Unpack Crank Revolution Data + ind->value.cp_vector.cumul_crank_rev = co_read16p(¶m->value[offset]); + offset += 2; + // Unpack Last Crank Evt time + ind->value.cp_vector.last_crank_evt_time = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (ind->value.cp_vector.flags & CPP_VECTOR_FIRST_CRANK_MEAS_ANGLE_PRESENT) + { + // Unpack First Crank Measurement Angle + ind->value.cp_vector.first_crank_meas_angle = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (!(ind->value.cp_vector.flags & CPP_VECTOR_INST_FORCE_MAGNITUDE_ARRAY_PRESENT) != + !(ind->value.cp_vector.flags & CPP_VECTOR_INST_TORQUE_MAGNITUDE_ARRAY_PRESENT)) + { + // Unpack Force or Torque magnitude (mutually excluded) + ind->value.cp_vector.nb = (param->length - offset)/2; + if (ind->value.cp_vector.nb) + { + for (int i = 0; i < ind->value.cp_vector.nb; i++) + { + // Handle the array buffer to extract parameters + ind->value.cp_vector.force_torque_magnitude[i] = co_read16p(¶m->value[offset]); + offset += 2; + } + } + } + +// if ((ind->value.cp_vector.flags & CPP_VECTOR_INST_MEAS_DIRECTION_LSB) || +// (ind->value.cp_vector.flags & CPP_VECTOR_INST_MEAS_DIRECTION_MSB)) +// { +// +// } + + // Send the message + ke_msg_send(ind); + + return offset; + +} + +uint8_t cppc_pack_ctnl_pt_req (struct cppc_ctnl_pt_cfg_req *param, uint8_t *req, uint8_t *status) +{ + // Request Length + uint8_t req_len = CPP_CP_CNTL_PT_REQ_MIN_LEN; + + // Set the operation code + req[0] = param->ctnl_pt.op_code; + + // Fulfill the message according to the operation code + switch (param->ctnl_pt.op_code) + { + case (CPP_CTNL_PT_SET_CUMUL_VAL): + { + // Set the cumulative value + co_write32p(&req[req_len], param->ctnl_pt.value.cumul_val); + // Update length + req_len += 4; + } break; + + case (CPP_CTNL_PT_UPD_SENSOR_LOC): + { + // Set the sensor location + req[req_len] = param->ctnl_pt.value.sensor_loc; + // Update length + req_len++; + } break; + + case (CPP_CTNL_PT_SET_CRANK_LENGTH): + { + // Set the crank length + co_write16p(&req[req_len], param->ctnl_pt.value.crank_length); + // Update length + req_len += 2; + } break; + + case (CPP_CTNL_PT_SET_CHAIN_LENGTH): + { + // Set the chain length + co_write16p(&req[req_len], param->ctnl_pt.value.chain_length); + // Update length + req_len += 2; + } break; + + case (CPP_CTNL_PT_SET_CHAIN_WEIGHT): + { + // Set the chain weight + co_write16p(&req[req_len], param->ctnl_pt.value.chain_weight); + // Update length + req_len += 2; + } break; + + case (CPP_CTNL_PT_SET_SPAN_LENGTH): + { + // Set the span length + co_write16p(&req[req_len], param->ctnl_pt.value.span_length); + // Update length + req_len += 2; + } break; + + case (CPP_CTNL_MASK_CP_MEAS_CH_CONTENT): + { + // Set the Content Mask + co_write16p(&req[req_len], param->ctnl_pt.value.mask_content); + // Update length + req_len += 2; + } break; + + case (CPP_CTNL_PT_REQ_SUPP_SENSOR_LOC): + case (CPP_CTNL_PT_REQ_CRANK_LENGTH): + case (CPP_CTNL_PT_REQ_CHAIN_LENGTH): + case (CPP_CTNL_PT_REQ_CHAIN_WEIGHT): + case (CPP_CTNL_PT_REQ_SPAN_LENGTH): + case (CPP_CTNL_PT_START_OFFSET_COMP): + case (CPP_CTNL_REQ_SAMPLING_RATE): + case (CPP_CTNL_REQ_FACTORY_CALIBRATION_DATE): + { + // Nothing more to do + } break; + + default: + { + *status = PRF_ERR_INVALID_PARAM; + } break; + } + + return req_len; +} + +uint8_t cppc_unpack_ctln_pt_ind (uint8_t conidx, struct gattc_event_ind const *param, struct cppc_env_tag *cppc_env) +{ + // Offset + uint8_t offset = CPP_CP_CNTL_PT_RSP_MIN_LEN; + + // Control Point value has been received + struct cppc_ctnl_pt_rsp *ind = KE_MSG_ALLOC( + CPPC_CTNL_PT_RSP, + prf_dst_task_get(&cppc_env->prf_env, conidx), + prf_src_task_get(&cppc_env->prf_env, conidx), + cppc_ctnl_pt_rsp); + + // Requested operation code + ind->rsp.req_op_code = param->value[1]; + // Response value + ind->rsp.resp_value = param->value[2]; + + if ((ind->rsp.resp_value == CPP_CTNL_PT_RESP_SUCCESS) && (param->length >= 3)) + { + switch (ind->rsp.req_op_code) + { + case (CPP_CTNL_PT_REQ_SUPP_SENSOR_LOC): + { + // Get the number of supported locations that have been received + uint8_t nb_supp_loc = (param->length - 3); + // Location + uint8_t loc; + + for (uint8_t counter = 0; counter < nb_supp_loc; counter++) + { + loc = param->value[counter + CPP_CP_CNTL_PT_RSP_MIN_LEN]; + // Check if valid + if (loc < CPP_LOC_MAX) + { + ind->rsp.value.supp_loc |= (1 << loc); + } + offset++; + } + } break; + + case (CPP_CTNL_PT_REQ_CRANK_LENGTH): + { + ind->rsp.value.crank_length = co_read16p(¶m->value[offset]); + offset += 2; + } break; + + case (CPP_CTNL_PT_REQ_CHAIN_LENGTH): + { + ind->rsp.value.chain_length = co_read16p(¶m->value[offset]); + offset += 2; + } break; + + case (CPP_CTNL_PT_REQ_CHAIN_WEIGHT): + { + ind->rsp.value.chain_weight = co_read16p(¶m->value[offset]); + offset += 2; + } break; + + case (CPP_CTNL_PT_REQ_SPAN_LENGTH): + { + ind->rsp.value.span_length = co_read16p(¶m->value[offset]); + offset += 2; + } break; + + case (CPP_CTNL_PT_START_OFFSET_COMP): + { + ind->rsp.value.offset_comp = co_read16p(¶m->value[offset]); + offset += 2; + } break; + + case (CPP_CTNL_REQ_SAMPLING_RATE): + { + ind->rsp.value.sampling_rate = param->value[offset]; + offset++; + } break; + + case (CPP_CTNL_REQ_FACTORY_CALIBRATION_DATE): + { + offset += prf_unpack_date_time( + (uint8_t *) &(param->value[offset]), &(ind->rsp.value.factory_calibration)); + } break; + + case (CPP_CTNL_PT_SET_CUMUL_VAL): + case (CPP_CTNL_PT_UPD_SENSOR_LOC): + case (CPP_CTNL_PT_SET_CRANK_LENGTH): + case (CPP_CTNL_PT_SET_CHAIN_LENGTH): + case (CPP_CTNL_PT_SET_CHAIN_WEIGHT): + case (CPP_CTNL_PT_SET_SPAN_LENGTH): + case (CPP_CTNL_MASK_CP_MEAS_CH_CONTENT): + { + // No parameters + } break; + + default: + { + + } break; + } + } + + // Send the message + ke_msg_send(ind); + + return offset; +} +#endif //(BLE_CP_COLLECTOR) + +/// @} CPP diff --git a/services/ble_profiles/cpp/cppc/src/cppc.h b/services/ble_profiles/cpp/cppc/src/cppc.h new file mode 100644 index 0000000..52e7ae3 --- /dev/null +++ b/services/ble_profiles/cpp/cppc/src/cppc.h @@ -0,0 +1,255 @@ +#ifndef _CPPC_H_ +#define _CPPC_H_ + +/** + **************************************************************************************** + * @addtogroup CPPC Cycling Power Profile Collector + * @ingroup CPP + * @brief Cycling Power Profile Collector + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "cpp_common.h" + +#if (BLE_CP_COLLECTOR) + +#include "cppc_task.h" +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" + + + +/* + * DEFINES + **************************************************************************************** + */ +/// Maximum number of Cycling Power Collector task instances +#define CPPC_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the CPPC task +enum cppc_states +{ + /// Idle state + CPPC_FREE, + /// Connected state + CPPC_IDLE, + /// Busy state + CPPC_DISCOVERING, + /// Busy state + CPPC_BUSY, + + /// Number of defined states. + CPPC_STATE_MAX +}; + +/// Internal codes for reading/writing a CPS characteristic with one single request +enum cppc_code +{ + /// Notified CP Measurement + CPPC_NTF_CP_MEAS = CPP_CPS_MEAS_CHAR, + /// Read CP Feature + CPPC_RD_CP_FEAT = CPP_CPS_FEAT_CHAR, + /// Read Sensor Location + CPPC_RD_SENSOR_LOC = CPP_CPS_SENSOR_LOC_CHAR, + /// Notified Vector + CPPC_NTF_CP_VECTOR = CPP_CPS_VECTOR_CHAR, + /// Indicated SC Control Point + CPPC_IND_CTNL_PT = CPP_CPS_CTNL_PT_CHAR, + + /// Read/Write CP Measurement Client Char. Configuration Descriptor + CPPC_RD_WR_CP_MEAS_CL_CFG = (CPPC_DESC_CP_MEAS_CL_CFG | CPPC_DESC_MASK), + /// Read/Write CP Measurement Server Char. Configuration Descriptor + CPPC_RD_WR_CP_MEAS_SV_CFG = (CPPC_DESC_CP_MEAS_SV_CFG | CPPC_DESC_MASK), + + /// Read/Write Vector Client Char. Configuration Descriptor + CPPC_RD_WR_VECTOR_CFG = (CPPC_DESC_VECTOR_CL_CFG | CPPC_DESC_MASK), + /// Read SC Control Point Client Char. Configuration Descriptor + CPPC_RD_WR_CTNL_PT_CFG = (CPPC_DESC_CTNL_PT_CL_CFG | CPPC_DESC_MASK), +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +struct cppc_cnx_env +{ + /// Current Operation + void *operation; + ///Last requested UUID(to keep track of the two services and char) + uint16_t last_uuid_req; + /// Counter used to check service uniqueness + uint8_t nb_svc; + /// Cycling Power Service Characteristics + struct cppc_cps_content cps; +}; + +/// Cycling Power Profile Collector environment variable +struct cppc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct cppc_cnx_env* env[CPPC_IDX_MAX]; + /// State of different task instances + ke_state_t state[CPPC_IDX_MAX]; +}; + +/// Command Message Basic Structure +struct cppc_cmd +{ + /// Operation Code + uint8_t operation; + + /// MORE DATA +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/* + * GLOBAL FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve CPP client profile interface + * @return CPP client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* cppc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Cycling Power ATT DB discovery results to CPPC host. + * @param[in] cppc_env environment variable + * @param[in] conidx Connection index + * @param[in] status Satus + **************************************************************************************** + */ +void cppc_enable_rsp_send(struct cppc_env_tag *cppc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Send a CPPC_CMP_EVT message when no connection exists (no environment) + * @param[in] src_id Source task + * @param[in] dest_id Destination task + * @param[in] operation Operation + **************************************************************************************** + */ +void cppc_send_no_conn_cmp_evt(uint8_t src_id, uint8_t dest_id, uint8_t operation); + +/** + **************************************************************************************** + * @brief Send a CPPC_CMP_EVT message to the task which enabled the profile + * @param[in] cppc_env environment variable + * @param[in] conidx Connection index + * @param[in] operation Operation + * @param[in] status Satus + **************************************************************************************** + */ +void cppc_send_cmp_evt(struct cppc_env_tag *cppc_env, uint8_t conidx, uint8_t operation, uint8_t status); + +/** + **************************************************************************************** + * @brief Gets correct read handle according to the request + * @param[in] cppc_env environment variable + * @param[in] conidx Connection index + * @param[in] param Pointer to the parameters of the message. + * @return handle + **************************************************************************************** + */ +uint16_t cppc_get_read_handle_req (struct cppc_env_tag *cppc_env, uint8_t conidx, struct cpps_read_cmd *param); + +/** + **************************************************************************************** + * @brief Gets correct write handle according to the request + * @param[in] conidx Connection index + * @param[in] param Pointer to the parameters of the message. + * @param[in] cppc_env environment variable + * @param[out] handle handle + * @return status of the operation + **************************************************************************************** + */ +uint8_t cppc_get_write_desc_handle_req (uint8_t conidx, struct cppc_cfg_ntfind_cmd *param, struct cppc_env_tag *cppc_env, uint16_t *handle); + +/** + **************************************************************************************** + * @brief Unpacks measurement data and sends the indication + * @param[in] conidx Connection index + * @param[in] param Pointer to the parameters of the message. + * @param[in] cppc_env environment variable + * @return length + **************************************************************************************** + */ +uint8_t cppc_unpack_meas_ind (uint8_t conidx, struct gattc_event_ind const *param, struct cppc_env_tag *cppc_env); + +/** + **************************************************************************************** + * @brief Unpacks Vector data and sends the indication + * @param[in] conidx Connection index + * @param[in] param Pointer to the parameters of the message. + * @param[in] cppc_env environment variable + * @return length + **************************************************************************************** + */ +uint8_t cppc_unpack_vector_ind (uint8_t conidx, struct gattc_event_ind const *param, struct cppc_env_tag *cppc_env); + +/** + **************************************************************************************** + * @brief Packs Control Point data + * @param[in] param Pointer to the parameters of the message. + * @param[out] req packed message + * @param[out] status status of the operation + * @return length + **************************************************************************************** + */ +uint8_t cppc_pack_ctnl_pt_req (struct cppc_ctnl_pt_cfg_req *param, uint8_t *req, uint8_t *status); + +/** + **************************************************************************************** + * @brief Unpacks Control Point data and sends the indication + * @param[in] conidx Connection index + * @param[in] param Pointer to the parameters of the message. + * @param[in] cppc_env environment variable + * @return length + **************************************************************************************** + */ +uint8_t cppc_unpack_ctln_pt_ind (uint8_t conidx, struct gattc_event_ind const *param,struct cppc_env_tag *cppc_env); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void cppc_task_init(struct ke_task_desc *task_desc); + + +#endif //(BLE_CP_COLLECTOR) + +/// @} CPPC + +#endif //(_CPPC_H_) diff --git a/services/ble_profiles/cpp/cppc/src/cppc_task.c b/services/ble_profiles/cpp/cppc/src/cppc_task.c new file mode 100644 index 0000000..5cde3f2 --- /dev/null +++ b/services/ble_profiles/cpp/cppc/src/cppc_task.c @@ -0,0 +1,790 @@ +/** + **************************************************************************************** + * @addtogroup CPPCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_CP_COLLECTOR) +#include "cpp_common.h" +#include "cppc_task.h" +#include "cppc.h" + +#include "gap.h" +#include "gattc_task.h" + +#include "ke_timer.h" +#include "ke_mem.h" + +#include "co_utils.h" + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// State machine used to retrieve Cycling Power service characteristics information +const struct prf_char_def cppc_cps_char[CPP_CPS_CHAR_MAX] = +{ + /// CP Measurement + [CPP_CPS_MEAS_CHAR] = {ATT_CHAR_CP_MEAS, + ATT_MANDATORY, + ATT_CHAR_PROP_NTF}, + /// CP Feature + [CPP_CPS_FEAT_CHAR] = {ATT_CHAR_CP_FEAT, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, + /// Sensor Location + [CPP_CPS_SENSOR_LOC_CHAR] = {ATT_CHAR_SENSOR_LOC, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, + ///Vector + [CPP_CPS_VECTOR_CHAR] = {ATT_CHAR_CP_VECTOR, + ATT_OPTIONAL, + ATT_CHAR_PROP_NTF}, + /// SC Control Point + [CPP_CPS_CTNL_PT_CHAR] = {ATT_CHAR_CP_CNTL_PT, + ATT_OPTIONAL, + ATT_CHAR_PROP_WR | ATT_CHAR_PROP_IND}, +}; + +/// State machine used to retrieve Cycling Power service characteristic descriptor information +const struct prf_char_desc_def cppc_cps_char_desc[CPPC_DESC_MAX] = +{ + /// CP Measurement Char. - Client Characteristic Configuration + [CPPC_DESC_CP_MEAS_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_MANDATORY, + CPP_CPS_MEAS_CHAR}, + + /// CP Measurement Char. - Server Characteristic Configuration + [CPPC_DESC_CP_MEAS_SV_CFG] = {ATT_DESC_SERVER_CHAR_CFG, + ATT_OPTIONAL, + CPP_CPS_MEAS_CHAR}, + + /// CP Vector Char. - Client Characteristic Configuration + [CPPC_DESC_VECTOR_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_OPTIONAL, + CPP_CPS_VECTOR_CHAR}, + + /// Control Point Char. - Client Characteristic Configuration + [CPPC_DESC_CTNL_PT_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_OPTIONAL, + CPP_CPS_CTNL_PT_CHAR}, +}; + +/* + * HANDLER FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPC_ENABLE_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cppc_enable_req_handler(ke_msg_id_t const msgid, + struct cppc_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + uint8_t state = ke_state_get(dest_id); + // Cycling Power Profile Collector Role Task Environment + struct cppc_env_tag *cppc_env = PRF_ENV_GET(CPPC, cppc); + + ASSERT_INFO(cppc_env != NULL, dest_id, src_id); + if((state == CPPC_IDLE) && (cppc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + cppc_env->env[conidx] = (struct cppc_cnx_env*) ke_malloc(sizeof(struct cppc_cnx_env),KE_MEM_ATT_DB); + memset(cppc_env->env[conidx], 0, sizeof(struct cppc_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering CPS on peer + prf_disc_svc_send(&(cppc_env->prf_env), conidx, ATT_SVC_CYCLING_POWER); + + // Go to DISCOVERING state + ke_state_set(dest_id, CPPC_DISCOVERING); + } + //normal connection, get saved att details + else + { + cppc_env->env[conidx]->cps = param->cps; + + //send APP confirmation that can start normal connection to TH + cppc_enable_rsp_send(cppc_env, conidx, GAP_ERR_NO_ERROR); + } + } + + else if(state != CPPC_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + cppc_enable_rsp_send(cppc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPC_READ_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cppc_read_req_handler(ke_msg_id_t const msgid, + struct cpps_read_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get the address of the environment + struct cppc_env_tag *cppc_env = PRF_ENV_GET(CPPC, cppc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if(state == CPPC_IDLE) + { + ASSERT_INFO(cppc_env != NULL, dest_id, src_id); + // environment variable not ready + if(cppc_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + else + { + // Get the handler + uint16_t hdl = cppc_get_read_handle_req (cppc_env, conidx, param); + + // Check if handle is viable + if (hdl != ATT_INVALID_SEARCH_HANDLE) + { + // Force the operation value + param->operation = CPPC_READ_OP_CODE; + + // Store the command structure + cppc_env->env[conidx]->operation = param; + msg_status = KE_MSG_NO_FREE; + + // Send the read request + prf_read_char_send( &(cppc_env->prf_env), conidx, + cppc_env->env[conidx]->cps.svc.shdl, + cppc_env->env[conidx]->cps.svc.ehdl, + hdl); + + // Go to the Busy state + ke_state_set(dest_id, CPPC_BUSY); + + status = ATT_ERR_NO_ERROR; + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + } + else if(state == CPPC_FREE) + { + status = GAP_ERR_DISCONNECTED; + } + else + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + status = GAP_ERR_NO_ERROR; + } + + if (status != GAP_ERR_NO_ERROR) + { + // Send the complete event message to the task id stored in the environment + cppc_send_cmp_evt(cppc_env, conidx, CPPC_READ_OP_CODE, status); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPC_CFG_NTFIND_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cppc_cfg_ntfind_cmd_handler(ke_msg_id_t const msgid, + struct cppc_cfg_ntfind_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cppc_env_tag *cppc_env = PRF_ENV_GET(CPPC, cppc); + + uint8_t state = ke_state_get(dest_id); + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + if (cppc_env != NULL) + { + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + // Handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + do + { + if (state != CPPC_IDLE) + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + break; + } + + ASSERT_ERR(cppc_env->env[conidx] != NULL); + + // Get handle + status = cppc_get_write_desc_handle_req (conidx, param, cppc_env, &handle); + } while (0); + + if ((status == GAP_ERR_NO_ERROR) && (handle != ATT_INVALID_SEARCH_HANDLE)) + { + // Set the operation code + param->operation = CPPC_CFG_NTF_IND_OP_CODE; + + // Store the command structure + cppc_env->env[conidx]->operation = param; + msg_status = KE_MSG_NO_FREE; + + // Go to the Busy state + ke_state_set(dest_id, CPPC_BUSY); + + // Send GATT Write Request + prf_gatt_write_ntf_ind(&cppc_env->prf_env, conidx, handle, param->ntfind_cfg); + } + } + else + { + cppc_send_no_conn_cmp_evt(dest_id, src_id, CPPC_CFG_NTF_IND_OP_CODE); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPC_CTNL_PT_CFG_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cppc_ctnl_pt_cfg_req_handler(ke_msg_id_t const msgid, + struct cppc_ctnl_pt_cfg_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get the address of the environment + struct cppc_env_tag *cppc_env = PRF_ENV_GET(CPPC, cppc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (cppc_env != NULL) + { + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + do + { + // State is Connected or Busy + ASSERT_ERR(ke_state_get(dest_id) > CPPC_FREE); + // Check the provided connection handle + if (cppc_env->env[conidx] == NULL) + { + status = PRF_ERR_INVALID_PARAM; + break; + } + + if (ke_state_get(dest_id) != CPPC_IDLE) + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + // Status is GAP_ERR_NO_ERROR, no message will be sent to the application + break; + } + + // Check if the characteristic has been found + if (cppc_env->env[conidx]->cps.descs[CPPC_DESC_CTNL_PT_CL_CFG].desc_hdl != ATT_INVALID_SEARCH_HANDLE) + { + // Request array declaration + uint8_t req[CPP_CP_CNTL_PT_REQ_MAX_LEN]; + // Pack request + uint8_t nb = cppc_pack_ctnl_pt_req (param, req, &status); + + if (status == GAP_ERR_NO_ERROR) + { + // Set the operation code + param->operation = CPPC_CTNL_PT_CFG_WR_OP_CODE; + + // Store the command structure + cppc_env->env[conidx]->operation = param; + // Store the command information + msg_status = KE_MSG_NO_FREE; + + // Go to the Busy state + ke_state_set(dest_id, CPPC_BUSY); + + // Send the write request + prf_gatt_write(&(cppc_env->prf_env), conidx, cppc_env->env[conidx]->cps.chars[CPP_CPS_CTNL_PT_CHAR].val_hdl, + (uint8_t *)&req[0], nb, GATTC_WRITE); + } + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } while (0); + + if (status != GAP_ERR_NO_ERROR) + { + // Send a complete event status to the application + cppc_send_cmp_evt(cppc_env, conidx, CPPC_CTNL_PT_CFG_WR_OP_CODE, status); + } + } + else + { + // No connection + cppc_send_no_conn_cmp_evt(dest_id, src_id, CPPC_CTNL_PT_CFG_WR_OP_CODE); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPC_TIMEOUT_TIMER_IND message. This message is + * received when the peer device doesn't send a SC Control Point indication within 30s + * after reception of the write response. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cppc_timeout_timer_ind_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cppc_env_tag *cppc_env = PRF_ENV_GET(CPPC, cppc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (cppc_env != NULL) + { + ASSERT_ERR(cppc_env->env[conidx]->operation != NULL); + ASSERT_ERR(((struct cppc_cmd *)cppc_env->env[conidx]->operation)->operation == CPPC_CTNL_PT_CFG_IND_OP_CODE); + + // Send the complete event message + cppc_send_cmp_evt(cppc_env, conidx, CPPC_CTNL_PT_CFG_WR_OP_CODE, PRF_ERR_PROC_TIMEOUT); + } + // else drop the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == CPPC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct cppc_env_tag *cppc_env = PRF_ENV_GET(CPPC, cppc); + + ASSERT_INFO(cppc_env != NULL, dest_id, src_id); + ASSERT_INFO(cppc_env->env[conidx] != NULL, dest_id, src_id); + + if(cppc_env->env[conidx]->nb_svc == 0) + { + // Retrieve CPS characteristics and descriptors + prf_extract_svc_info(ind, CPP_CPS_CHAR_MAX, &cppc_cps_char[0], &cppc_env->env[conidx]->cps.chars[0], + CPPC_DESC_MAX, &cppc_cps_char_desc[0], &cppc_env->env[conidx]->cps.descs[0]); + + //Even if we get multiple responses we only store 1 range + cppc_env->env[conidx]->cps.svc.shdl = ind->start_hdl; + cppc_env->env[conidx]->cps.svc.ehdl = ind->end_hdl; + } + + cppc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cppc_env_tag *cppc_env = PRF_ENV_GET(CPPC, cppc); + // Status + uint8_t status; + + + if (cppc_env != NULL) + { + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if (state == CPPC_DISCOVERING) + { + status = param->status; + + if ((status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || + (status == ATT_ERR_NO_ERROR)) + { + // Discovery + // check characteristic validity + if(cppc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(CPP_CPS_CHAR_MAX, + cppc_env->env[conidx]->cps.chars, + cppc_cps_char); + } + // too much services + else if (cppc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if (status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(CPPC_DESC_MAX, + cppc_env->env[conidx]->cps.descs, + cppc_cps_char_desc, + cppc_env->env[conidx]->cps.chars); + } + } + + cppc_enable_rsp_send(cppc_env, conidx, status); + } + + else if (state == CPPC_BUSY) + { + switch (param->operation) + { + case GATTC_READ: + { + // Send the complete event status + cppc_send_cmp_evt(cppc_env, conidx, CPPC_READ_OP_CODE, param->status); + } break; + + case GATTC_WRITE: + case GATTC_WRITE_NO_RESPONSE: + { + uint8_t operation = ((struct cppc_cmd *)cppc_env->env[conidx]->operation)->operation; + + if (operation == CPPC_CFG_NTF_IND_OP_CODE) + { + // Send the complete event status + cppc_send_cmp_evt(cppc_env, conidx, operation, param->status); + } + + else if (operation == CPPC_CTNL_PT_CFG_WR_OP_CODE) + { + if (param->status == GAP_ERR_NO_ERROR) + { + // Start Timeout Procedure + ke_timer_set(CPPC_TIMEOUT_TIMER_IND, dest_id, ATT_TRANS_RTX); + + // Wait for the response indication + ((struct cppc_cmd *)cppc_env->env[conidx]->operation)->operation = CPPC_CTNL_PT_CFG_IND_OP_CODE; + } + else + { + // Send the complete event status + cppc_send_cmp_evt(cppc_env, conidx, operation, param->status); + } + } + } break; + + case GATTC_REGISTER: + case GATTC_UNREGISTER: + { + // Do nothing + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + // Get the address of the environment + struct cppc_env_tag *cppc_env = PRF_ENV_GET(CPPC, cppc); + + if (state == CPPC_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + ASSERT_INFO(cppc_env != NULL, dest_id, src_id); + ASSERT_INFO(cppc_env->env[conidx] != NULL, dest_id, src_id); + + // Send the read value to the HL + struct cppc_value_ind *ind = KE_MSG_ALLOC( + CPPC_VALUE_IND, + prf_dst_task_get(&(cppc_env->prf_env), conidx), + dest_id, + cppc_value_ind); + + switch (((struct cpps_read_cmd *)cppc_env->env[conidx]->operation)->read_code) + { + // Read CP Feature Characteristic value + case (CPPC_RD_CP_FEAT): + { + ind->value.sensor_feat = co_read32p(¶m->value[0]); + + // Mask the reserved bits +// ind->value.sensor_feat &= CPP_FEAT_ALL_SUPP; + } break; + + // Read Sensor Location Characteristic value + case (CPPC_RD_SENSOR_LOC): + { + ind->value.sensor_loc = param->value[0]; + } break; + + // Read Client Characteristic Configuration Descriptor value + case (CPPC_RD_WR_CP_MEAS_CL_CFG): + case (CPPC_RD_WR_CP_MEAS_SV_CFG): + case (CPPC_RD_WR_VECTOR_CFG): + case (CPPC_RD_WR_CTNL_PT_CFG): + { + co_write16p(&ind->value.ntf_cfg, param->value[0]); + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + + ind->att_code = ((struct cpps_read_cmd *)cppc_env->env[conidx]->operation)->read_code; + + // Send the message to the application + ke_msg_send(ind); + } + // else drop the message + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct cppc_env_tag *cppc_env = PRF_ENV_GET(CPPC, cppc); + + if (cppc_env != NULL) + { + switch (param->type) + { + case (GATTC_NOTIFY): + { + + if (param->handle == cppc_env->env[conidx]->cps.chars[CPP_CPS_MEAS_CHAR].val_hdl) + { + //Unpack measurement + cppc_unpack_meas_ind (conidx, param, cppc_env); + } + else if (param->handle == cppc_env->env[conidx]->cps.chars[CPP_CPS_VECTOR_CHAR].val_hdl) + { + //Unpack vector + cppc_unpack_vector_ind (conidx, param, cppc_env); + } + else + { + ASSERT_ERR(0); + } + } break; + + case (GATTC_INDICATE): + { + // confirm that indication has been correctly received + struct gattc_event_cfm * cfm = KE_MSG_ALLOC(GATTC_EVENT_CFM, src_id, dest_id, gattc_event_cfm); + cfm->handle = param->handle; + ke_msg_send(cfm); + + // Check if we were waiting for the indication + if (cppc_env->env[conidx]->operation != NULL) + { + if (((struct cppc_cmd *)cppc_env->env[conidx]->operation)->operation == CPPC_CTNL_PT_CFG_IND_OP_CODE) + { + // Stop the procedure timeout timer + ke_timer_clear(CPPC_TIMEOUT_TIMER_IND, dest_id); + + //Unpack control point + cppc_unpack_ctln_pt_ind (conidx, param, cppc_env); + + // Send the complete event message + cppc_send_cmp_evt(cppc_env, conidx, CPPC_CTNL_PT_CFG_WR_OP_CODE, GAP_ERR_NO_ERROR); + } + // else drop the message + } + // else drop the message + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(cppc) +{ + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {CPPC_READ_CMD, (ke_msg_func_t)cppc_read_req_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {CPPC_CFG_NTFIND_CMD, (ke_msg_func_t)cppc_cfg_ntfind_cmd_handler}, + {CPPC_CTNL_PT_CFG_REQ, (ke_msg_func_t)cppc_ctnl_pt_cfg_req_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_EVENT_REQ_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {CPPC_TIMEOUT_TIMER_IND, (ke_msg_func_t)cppc_timeout_timer_ind_handler}, + {CPPC_ENABLE_REQ, (ke_msg_func_t)cppc_enable_req_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void cppc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct cppc_env_tag *cppc_env = PRF_ENV_GET(CPPC, cppc); + + task_desc->msg_handler_tab = cppc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(cppc_msg_handler_tab); + task_desc->state = cppc_env->state; + task_desc->idx_max = CPPC_IDX_MAX; +} + +#endif //(BLE_CP_COLLECTOR) + +/// @} CPPCTASK diff --git a/services/ble_profiles/cpp/cpps/api/cpps_task.h b/services/ble_profiles/cpp/cpps/api/cpps_task.h new file mode 100644 index 0000000..7a71387 --- /dev/null +++ b/services/ble_profiles/cpp/cpps/api/cpps_task.h @@ -0,0 +1,344 @@ +#ifndef _CPPS_TASK_H_ +#define _CPPS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup CPPSTASK Task + * @ingroup CPPS + * @brief Cycling Power Profile Task. + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "cpp_common.h" + + +#include +#include "rwip_task.h" // Task definitions + +/* + * DEFINES + **************************************************************************************** + */ + + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Messages for Cycling Power Profile Sensor +enum cpps_msg_id +{ + /// Start the Cycling Power Profile Server profile + CPPS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_CPPS), + /// Confirm profile + CPPS_ENABLE_RSP, + + /// Gets packed data for advertising + CPPS_GET_ADV_DATA_REQ, + /// Response with packed data for advertising + CPPS_GET_ADV_DATA_RSP, + + /// Send a CP Measurement to the peer device (Notification) + CPPS_NTF_CP_MEAS_REQ, + /// CP Measurement response + CPPS_NTF_CP_MEAS_RSP, + + /// Send a CP Vector to the peer device (Notification) + CPPS_NTF_CP_VECTOR_REQ, + /// CP Vector response + CPPS_NTF_CP_VECTOR_RSP, + + /// Send a complete event status to the application + CPPS_CMP_EVT, + + /// Indicate that an attribute value has been written + CPPS_CFG_NTFIND_IND, + + /// Request to change vector client configuration + CPPS_VECTOR_CFG_REQ_IND, + /// Confirmation to change vector client configuration + CPPS_VECTOR_CFG_CFM, + + /// Indicate that Control Point characteristic value has been written + CPPS_CTNL_PT_REQ_IND, + /// Application response after receiving a CPPS_CTNL_PT_REQ_IND message + CPPS_CTNL_PT_CFM, +}; + +/// Operation Code used in the profile state machine +enum cpps_op_code +{ + /// Reserved Operation Code + CPPS_RESERVED_OP_CODE = 0x00, + + /// Enable Profile Operation Code + CPPS_ENABLE_REQ_OP_CODE, + + /// Send CP Measurement Operation Code + CPPS_NTF_MEAS_OP_CODE, + + /// Send Vector Operation Code + CPPS_NTF_VECTOR_OP_CODE, + + /** + * Control Point Operation + */ + /// Set Cumulative Value + CPPS_CTNL_PT_SET_CUMUL_VAL_OP_CODE, + /// Update Sensor Location + CPPS_CTNL_PT_UPD_SENSOR_LOC_OP_CODE, + /// Request Supported Sensor Locations + CPPS_CTNL_PT_REQ_SUPP_SENSOR_LOC_OP_CODE, + /// Set Crank Length + CPPS_CTNL_PT_SET_CRANK_LENGTH_OP_CODE, + /// Request Crank Length + CPPS_CTNL_PT_REQ_CRANK_LENGTH_OP_CODE, + /// Set Chain Length + CPPS_CTNL_PT_SET_CHAIN_LENGTH_OP_CODE, + /// Request Chain Length + CPPS_CTNL_PT_REQ_CHAIN_LENGTH_OP_CODE, + /// Set Chain Weight + CPPS_CTNL_PT_SET_CHAIN_WEIGHT_OP_CODE, + /// Request Chain Weight + CPPS_CTNL_PT_REQ_CHAIN_WEIGHT_OP_CODE, + /// Set Span Length + CPPS_CTNL_PT_SET_SPAN_LENGTH_OP_CODE, + /// Request Span Length + CPPS_CTNL_PT_REQ_SPAN_LENGTH_OP_CODE, + /// Start Offset Compensation + CPPS_CTNL_PT_START_OFFSET_COMP_OP_CODE, + /// Mask CP Measurement Characteristic Content + CPPS_CTNL_MASK_CP_MEAS_CH_CONTENT_OP_CODE, + /// Request Sampling Rate + CPPS_CTNL_REQ_SAMPLING_RATE_OP_CODE, + /// Request Factory Calibration Date + CPPS_CTNL_REQ_FACTORY_CALIBRATION_DATE_OP_CODE, + + /// Error Indication Sent Operation Code + CPPS_CTNL_ERR_IND_OP_CODE, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Parameters of the @ref CPPS_CREATE_DB_REQ message +struct cpps_db_cfg +{ + /** + * CP Feature Value - Not supposed to be modified during the lifetime of the device + * This bit field is set in order to decide which features are supported: + * Supported features (specification) ---------------- Bits 0 to 18 + */ + uint32_t cp_feature; + /// Initial count for wheel revolutions + uint32_t wheel_rev; + /** + * Profile characteristic configuration: + * Enable broadcaster mode in Measurement Characteristic --- Bit 0 + * Enable Control Point Characteristic (*) ----------------- Bit 1 + * + * (*) Note this characteristic is mandatory if server supports: + * - Wheel Revolution Data + * - Multiple Sensor Locations + * - Configurable Settings + * - Offset Compensation + * - Server allows to be requested for parameters (CPP_CTNL_PT_REQ... codes) + */ + uint8_t prfl_config; + /** + * Indicate the sensor location. + */ + uint8_t sensor_loc; +}; + +/// Parameters of the @ref CPPS_ENABLE_REQ message +struct cpps_enable_req +{ + /// Connection index + uint8_t conidx; + /** + * Profile characteristic configuration: + * Measurement Characteristic notification config --- Bit 0 + * Measurement Characteristic broadcast config ------ Bit 1 + * Vector Characteristic notification config -------- Bit 2 + * Control Point Characteristic indication config --- Bit 3 + */ + uint16_t prfl_ntf_ind_cfg; +}; + +/// Parameters of the @ref CPPS_ENABLE_RSP message +struct cpps_enable_rsp +{ + /// Connection index + uint8_t conidx; + /// status + uint8_t status; +}; + +/// Parameters of the @ref CPPS_GET_ADV_DATA_REQ message +struct cpps_get_adv_data_req +{ + ///Parameters + struct cpp_cp_meas parameters; +}; + +/// Parameters of the @ref CPPS_GET_ADV_DATA_RSP message +struct cpps_get_adv_data_rsp +{ + uint8_t status; + /// Data length + uint8_t data_len; + /// Data to advertise + uint8_t adv_data[__ARRAY_EMPTY]; +}; + +/// Parameters of the @ref CPPS_NTF_CP_MEAS_REQ message +struct cpps_ntf_cp_meas_req +{ + ///Parameters + struct cpp_cp_meas parameters; +}; + +/// Parameters of the @ref CPPS_NTF_CP_MEAS_RSP message +struct cpps_ntf_cp_meas_rsp +{ + /// Status + uint8_t status; +}; + +/// Parameters of the @ref CPPS_NTF_CP_VECTOR_REQ message +struct cpps_ntf_cp_vector_req +{ + ///Parameters + struct cpp_cp_vector parameters; +}; + +/// Parameters of the @ref CPPS_NTF_CP_VECTOR_RSP message +struct cpps_ntf_cp_vector_rsp +{ + /// Status + uint8_t status; +}; + +/// Parameters of the @ref CPPS_CTNL_PT_REQ_IND message +struct cpps_ctnl_pt_req_ind +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t op_code; + /// Value + union cpps_ctnl_pt_req_ind_value + { + /// Cumulative Value + uint32_t cumul_val; + /// Sensor Location + uint8_t sensor_loc; + /// Crank Length + uint16_t crank_length; + /// Chain Length + uint16_t chain_length; + /// Chain Weight + uint16_t chain_weight; + /// Span Length + uint16_t span_length; + /// Mask Content + uint16_t mask_content; + } value; +}; + +/// Parameters of the @ref CPPS_CTNL_PT_CFM message +struct cpps_ctnl_pt_cfm +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t op_code; + /// Status + uint8_t status; + /// Value + union cpps_sc_ctnl_pt_cfm_value + { + /// Supported sensor locations (up to 17) + uint32_t supp_sensor_loc; + /// New Cumulative Wheel revolution Value + uint32_t cumul_wheel_rev; + /// Crank Length + uint16_t crank_length; + /// Chain Length + uint16_t chain_length; + /// Chain Weight + uint16_t chain_weight; + /// Span Length + uint16_t span_length; + /// Offset compensation + int16_t offset_comp; + /// Mask Measurement content + uint16_t mask_meas_content; + ///Sampling rate + uint8_t sampling_rate; + /// New Sensor Location + uint8_t sensor_loc; + /// Calibration date + struct prf_date_time factory_calibration; + + } value; +}; + +/// Parameters of the @ref CPPS_CFG_NTFIND_IND message +struct cpps_cfg_ntfind_ind +{ + /// Connection index + uint8_t conidx; + /// Characteristic Code (CP Measurement or Control Point) + uint8_t char_code; + /// Char. Client Characteristic Configuration + uint16_t ntf_cfg; +}; + +/// Parameters of the @ref CPPS_VECTOR_CFG_REQ_IND message +struct cpps_vector_cfg_req_ind +{ + /// Connection index + uint8_t conidx; + /// Characteristic Code + uint8_t char_code; + /// Char. Client Characteristic Configuration + uint16_t ntf_cfg; +}; + +/// Parameters of the @ref CPPS_VECTOR_CFG_CFM message +struct cpps_vector_cfg_cfm +{ + /// Connection index + uint8_t conidx; + /// Status + uint8_t status; + /// Char. Client Characteristic Configuration + uint16_t ntf_cfg; +}; + +/// Parameters of the @ref CPPS_CMP_EVT message +struct cpps_cmp_evt +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t operation; + /// Operation Status + uint8_t status; +}; + +/// @} CPPSTASK + +#endif //(_CPPS_TASK_H_) diff --git a/services/ble_profiles/cpp/cpps/src/cpps.c b/services/ble_profiles/cpp/cpps/src/cpps.c new file mode 100644 index 0000000..95fce70 --- /dev/null +++ b/services/ble_profiles/cpp/cpps/src/cpps.c @@ -0,0 +1,1452 @@ +/** + **************************************************************************************** + * @addtogroup CPPS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "rwip_config.h" +#if (BLE_CP_SENSOR) +#include "cpp_common.h" +#include "gap.h" +#include "gattc_task.h" +#include "gattc.h" +#include "cpps.h" +#include "cpps_task.h" +#include "prf_utils.h" +#include "co_math.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Full CPPS Database Description - Used to add attributes into the database +static const struct attm_desc cpps_att_db[CPS_IDX_NB] = +{ + // Cycling Power Service Declaration + [CPS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // CP Measurement Characteristic Declaration + [CPS_IDX_CP_MEAS_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // CP Measurement Characteristic Value + [CPS_IDX_CP_MEAS_VAL] = {ATT_CHAR_CP_MEAS, PERM(NTF, ENABLE), PERM(RI, ENABLE), CPP_CP_MEAS_NTF_MAX_LEN}, + // CP Measurement Characteristic - Client Characteristic Configuration Descriptor + [CPS_IDX_CP_MEAS_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + // CP Measurement Characteristic - Server Characteristic Configuration Descriptor + [CPS_IDX_CP_MEAS_BCST_CFG] = {ATT_DESC_SERVER_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // CP Feature Characteristic Declaration + [CPS_IDX_CP_FEAT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // CP Feature Characteristic Value + [CPS_IDX_CP_FEAT_VAL] = {ATT_CHAR_CP_FEAT, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(uint32_t)}, + + // Sensor Location Characteristic Declaration + [CPS_IDX_SENSOR_LOC_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Sensor Location Characteristic Value + [CPS_IDX_SENSOR_LOC_VAL] = {ATT_CHAR_SENSOR_LOC, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, + + // CP Vector Characteristic Declaration + [CPS_IDX_VECTOR_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // CP Vector Characteristic Value + [CPS_IDX_VECTOR_VAL] = {ATT_CHAR_CP_VECTOR, PERM(NTF, ENABLE), PERM(RI, ENABLE), CPP_CP_VECTOR_MAX_LEN}, + // CP Vector Characteristic - Client Characteristic Configuration Descriptor + [CPS_IDX_VECTOR_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // CP Control Point Characteristic Declaration + [CPS_IDX_CTNL_PT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // CP Control Point Characteristic Value - The response has the maximal length + [CPS_IDX_CTNL_PT_VAL] = {ATT_CHAR_CP_CNTL_PT, PERM(IND, ENABLE) | PERM(WRITE_REQ, ENABLE), + PERM(RI, ENABLE), CPP_CP_CNTL_PT_RSP_MAX_LEN}, + // CP Control Point Characteristic - Client Characteristic Configuration Descriptor + [CPS_IDX_CTNL_PT_IND_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, +}; + + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the CPPS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t cpps_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct cpps_db_cfg* params) +{ + //------------------ create the attribute database for the profile ------------------- + // Service content flag + uint32_t cfg_flag= CPPS_MANDATORY_MASK; + // DB Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + /* + * Check if Broadcaster role shall be added. + */ + if(CPPS_IS_FEATURE_SUPPORTED(params->prfl_config, CPPS_BROADCASTER_SUPP_FLAG)) + { + //Add configuration to the database + cfg_flag |= CPPS_MEAS_BCST_MASK; + } + /* + * Check if the CP Vector characteristic shall be added. + * Mandatory if at least one Vector procedure is supported, otherwise excluded. + */ + if ((CPPS_IS_FEATURE_SUPPORTED(params->cp_feature, CPP_FEAT_CRANK_REV_DATA_SUPP)) || + (CPPS_IS_FEATURE_SUPPORTED(params->cp_feature, CPP_FEAT_EXTREME_ANGLES_SUPP)) || + (CPPS_IS_FEATURE_SUPPORTED(params->cp_feature, CPP_FEAT_INSTANT_MEAS_DIRECTION_SUPP))) + { + cfg_flag |= CPPS_VECTOR_MASK; + } + /* + * Check if the Control Point characteristic shall be added + * Mandatory if server supports: + * - Wheel Revolution Data + * - Multiple Sensor Locations + * - Configurable Settings (CPP_CTNL_PT_SET codes) + * - Offset Compensation + * - Server allows to be requested for parameters (CPP_CTNL_PT_REQ codes) + */ + if ((CPPS_IS_FEATURE_SUPPORTED(params->prfl_config, CPPS_CTNL_PT_CHAR_SUPP_FLAG)) || + (CPPS_IS_FEATURE_SUPPORTED(params->cp_feature, CPP_FEAT_WHEEL_REV_DATA_SUPP)) || + (CPPS_IS_FEATURE_SUPPORTED(params->cp_feature, CPP_FEAT_MULT_SENSOR_LOC_SUPP)) || + (CPPS_IS_FEATURE_SUPPORTED(params->cp_feature, CPP_FEAT_CRANK_LENGTH_ADJ_SUPP)) || + (CPPS_IS_FEATURE_SUPPORTED(params->cp_feature, CPP_FEAT_CHAIN_LENGTH_ADJ_SUPP)) || + (CPPS_IS_FEATURE_SUPPORTED(params->cp_feature, CPP_FEAT_CHAIN_WEIGHT_ADJ_SUPP)) || + (CPPS_IS_FEATURE_SUPPORTED(params->cp_feature, CPP_FEAT_SPAN_LENGTH_ADJ_SUPP)) || + (CPPS_IS_FEATURE_SUPPORTED(params->cp_feature, CPP_FEAT_OFFSET_COMP_SUPP))) + { + cfg_flag |= CPPS_CTNL_PT_MASK; + } + + // Add service in the database + status = attm_svc_create_db(start_hdl, ATT_SVC_CYCLING_POWER, (uint8_t *)&cfg_flag, + CPS_IDX_NB, NULL, env->task, &cpps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, DISABLE)); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // Allocate CPPS required environment variable + struct cpps_env_tag* cpps_env = + (struct cpps_env_tag* ) ke_malloc(sizeof(struct cpps_env_tag), KE_MEM_ATT_DB); + + // Initialize CPPS environment + env->env = (prf_env_t*) cpps_env; + cpps_env->shdl = *start_hdl; + cpps_env->prfl_cfg = cfg_flag; + cpps_env->features = params->cp_feature; + cpps_env->sensor_loc = params->sensor_loc; + cpps_env->cumul_wheel_rev = params->wheel_rev; + cpps_env->operation = CPPS_RESERVED_OP_CODE; + + cpps_env->op_data = NULL; + memset(cpps_env->env, 0, sizeof(cpps_env->env)); + + cpps_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Mono Instantiated task + cpps_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + // initialize environment variable + env->id = TASK_ID_CPPS; + cpps_task_init(&(env->desc)); + + /* + * Check if the Broadcaster role shall be added. + */ + if(CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_MEAS_BCST_MASK)) + { + // Optional Permissions + uint16_t perm = PERM(NTF, ENABLE) | PERM(BROADCAST,ENABLE); + //Add configuration to the database + attm_att_set_permission(CPPS_HANDLE(CPS_IDX_CP_MEAS_VAL), perm, 0); + } + + /* Put CPS in Idle state */ + ke_state_set(env->task, CPPS_IDLE); + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the CPPS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void cpps_destroy(struct prf_task_env* env) +{ + struct cpps_env_tag* cpps_env = (struct cpps_env_tag*) env->env; + + if (cpps_env->op_data != NULL) + { + ke_free(cpps_env->op_data->cmd); + if(cpps_env->op_data->ntf_pending) + { + ke_free(cpps_env->op_data->ntf_pending); + } + ke_free(cpps_env->op_data); + } + + // free profile environment variables + env->env = NULL; + ke_free(cpps_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void cpps_create(struct prf_task_env* env, uint8_t conidx) +{ + struct cpps_env_tag* cpps_env = (struct cpps_env_tag*) env->env; + + memset(&(cpps_env->env[conidx]), 0, sizeof(struct cpps_cnx_env)); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void cpps_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct cpps_env_tag* cpps_env = (struct cpps_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + memset(&(cpps_env->env[conidx]), 0, sizeof(struct cpps_cnx_env)); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// CPPS Task interface required by profile manager +const struct prf_task_cbs cpps_itf = +{ + (prf_init_fnct) cpps_init, + cpps_destroy, + cpps_create, + cpps_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* cpps_prf_itf_get(void) +{ + return &cpps_itf; +} + +uint8_t cpps_pack_meas_ntf(struct cpp_cp_meas *param, uint8_t *pckd_meas) +{ + // Packed Measurement length + uint8_t pckd_meas_len = CPP_CP_MEAS_NTF_MIN_LEN; + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + + // Check provided flags + if (CPPS_IS_PRESENT(param->flags, CPP_MEAS_PEDAL_POWER_BALANCE_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_PEDAL_POWER_BALANCE_SUPP)) + { + //Pack Pedal Power Balance info + pckd_meas[pckd_meas_len] = param->pedal_power_balance; + pckd_meas_len++; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_MEAS_PEDAL_POWER_BALANCE_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_MEAS_ACCUM_TORQUE_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_ACCUM_TORQUE_SUPP)) + { + //Pack Accumulated Torque info + co_write16p(&pckd_meas[pckd_meas_len], param->accum_torque); + pckd_meas_len += 2; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_MEAS_ACCUM_TORQUE_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_MEAS_WHEEL_REV_DATA_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_WHEEL_REV_DATA_SUPP)) + { + //Pack Wheel Revolution Data (Cumulative Wheel & Last Wheel Event Time) + co_write32p(&pckd_meas[pckd_meas_len], cpps_env->cumul_wheel_rev); + pckd_meas_len += 4; + co_write16p(&pckd_meas[pckd_meas_len], param->last_wheel_evt_time); + pckd_meas_len += 2; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_MEAS_WHEEL_REV_DATA_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_MEAS_CRANK_REV_DATA_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_CRANK_REV_DATA_SUPP)) + { + //Pack Crank Revolution Data (Cumulative Crank & Last Crank Event Time) + co_write16p(&pckd_meas[pckd_meas_len], param->cumul_crank_rev); + pckd_meas_len += 2; + co_write16p(&pckd_meas[pckd_meas_len], param->last_crank_evt_time); + pckd_meas_len += 2; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_MEAS_CRANK_REV_DATA_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_MEAS_EXTREME_FORCE_MAGNITUDES_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_EXTREME_MAGNITUDES_SUPP) + && CPPS_IS_CLEAR(cpps_env->features, CPP_FEAT_SENSOR_MEAS_CONTEXT)) + { + //Pack Extreme Force Magnitudes (Maximum Force Magnitude & Minimum Force Magnitude) + co_write16p(&pckd_meas[pckd_meas_len], param->max_force_magnitude); + pckd_meas_len += 2; + co_write16p(&pckd_meas[pckd_meas_len], param->min_force_magnitude); + pckd_meas_len += 2; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_MEAS_EXTREME_FORCE_MAGNITUDES_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_MEAS_EXTREME_TORQUE_MAGNITUDES_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_EXTREME_MAGNITUDES_SUPP) + && CPPS_IS_SET(cpps_env->features, CPP_FEAT_SENSOR_MEAS_CONTEXT)) + { + //Pack Extreme Force Magnitudes (Maximum Force Magnitude & Minimum Force Magnitude) + co_write16p(&pckd_meas[pckd_meas_len], param->max_torque_magnitude); + pckd_meas_len += 2; + co_write16p(&pckd_meas[pckd_meas_len], param->min_torque_magnitude); + pckd_meas_len += 2; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_MEAS_EXTREME_TORQUE_MAGNITUDES_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_MEAS_EXTREME_ANGLES_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_EXTREME_ANGLES_SUPP)) + { + //Pack Extreme Angles (Maximum Angle & Minimum Angle) + //Force to 12 bits + param->max_angle &= 0x0FFF; + param->min_angle &= 0x0FFF; + uint32_t angle = (uint32_t) (param->max_angle | (param->min_angle<<12)); + co_write24p(&pckd_meas[pckd_meas_len], angle); + pckd_meas_len += 3; + + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_MEAS_EXTREME_ANGLES_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_MEAS_TOP_DEAD_SPOT_ANGLE_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_TOPBOT_DEAD_SPOT_ANGLES_SUPP)) + { + //Pack Top Dead Spot Angle + co_write16p(&pckd_meas[pckd_meas_len], param->top_dead_spot_angle); + pckd_meas_len += 2; + } + else + { + //Force to not supported + param->flags &= ~CPP_MEAS_TOP_DEAD_SPOT_ANGLE_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_MEAS_BOTTOM_DEAD_SPOT_ANGLE_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_TOPBOT_DEAD_SPOT_ANGLES_SUPP)) + { + //Pack Bottom Dead Spot Angle + co_write16p(&pckd_meas[pckd_meas_len], param->bot_dead_spot_angle); + pckd_meas_len += 2; + } + else + { + //Force to not supported + param->flags &= ~CPP_MEAS_BOTTOM_DEAD_SPOT_ANGLE_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_MEAS_ACCUM_ENERGY_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_ACCUM_ENERGY_SUPP)) + { + //Pack Accumulated Energy + co_write16p(&pckd_meas[pckd_meas_len], param->accum_energy); + pckd_meas_len += 2; + } + else + { + //Force to not supported + param->flags &= ~CPP_MEAS_ACCUM_ENERGY_PRESENT; + } + } + + // Allow to use reserved flags according to PTS Test + //param->flags &= CPP_MEAS_ALL_SUPP; + // Flags value + co_write16p(&pckd_meas[0], param->flags); + //Instant Power (Mandatory) + co_write16p(&pckd_meas[2], param->inst_power); + + return pckd_meas_len; +} + +uint8_t cpps_split_meas_ntf(uint8_t conidx, struct gattc_send_evt_cmd *meas_ntf1) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + // Extract flags info + uint16_t flags = co_read16p(&meas_ntf1->value[0]); + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_ntf2 = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&cpps_env->prf_env, conidx), + gattc_send_evt_cmd, CPP_CP_MEAS_NTF_MAX_LEN); + + // Fill in the parameter structure + meas_ntf2->operation = GATTC_NOTIFY; + meas_ntf2->handle = CPPS_HANDLE(CPS_IDX_CP_MEAS_VAL); + meas_ntf2->length = CPP_CP_MEAS_NTF_MIN_LEN; + + // Copy status flags + co_write16p(&meas_ntf2->value[0], (flags & (CPP_MEAS_PEDAL_POWER_BALANCE_REFERENCE | + CPP_MEAS_ACCUM_TORQUE_SOURCE | + CPP_MEAS_OFFSET_COMPENSATION_INDICATOR))); + // Copy Instantaneous power + memcpy(&meas_ntf2->value[2], &meas_ntf1->value[2], 2); + + // Current position + uint8_t len = 0; + + for (uint16_t feat = CPP_MEAS_PEDAL_POWER_BALANCE_PRESENT; + feat <= CPP_MEAS_OFFSET_COMPENSATION_INDICATOR; + feat <<= 1) + { + // First message fits within the MTU + if (meas_ntf1->length <= gattc_get_mtu(conidx) - 3) + { + // Stop splitting + break; + } + + if (CPPS_IS_PRESENT(flags, feat)) + { + switch (feat) + { + case CPP_MEAS_PEDAL_POWER_BALANCE_PRESENT: + // Copy uint8 + meas_ntf2->value[meas_ntf2->length] = meas_ntf1->value[CPP_CP_MEAS_NTF_MIN_LEN]; + len = 1; + break; + + case CPP_MEAS_ACCUM_TORQUE_PRESENT: + case CPP_MEAS_TOP_DEAD_SPOT_ANGLE_PRESENT: + case CPP_MEAS_ACCUM_ENERGY_PRESENT: + case CPP_MEAS_BOTTOM_DEAD_SPOT_ANGLE_PRESENT: + // Copy uint16 + memcpy(&meas_ntf2->value[meas_ntf2->length], &meas_ntf1->value[CPP_CP_MEAS_NTF_MIN_LEN], 2); + len = 2; + break; + + case CPP_MEAS_EXTREME_ANGLES_PRESENT: + // Copy uint24 + memcpy(&meas_ntf2->value[meas_ntf2->length], &meas_ntf1->value[CPP_CP_MEAS_NTF_MIN_LEN], 3); + len = 3; + break; + + case CPP_MEAS_CRANK_REV_DATA_PRESENT: + case CPP_MEAS_EXTREME_FORCE_MAGNITUDES_PRESENT: + case CPP_MEAS_EXTREME_TORQUE_MAGNITUDES_PRESENT: + // Copy uint16 + uint16 + memcpy(&meas_ntf2->value[meas_ntf2->length], &meas_ntf1->value[CPP_CP_MEAS_NTF_MIN_LEN], 4); + len = 4; + break; + + case CPP_MEAS_WHEEL_REV_DATA_PRESENT: + // Copy uint32 + uint16 + memcpy(&meas_ntf2->value[meas_ntf2->length], &meas_ntf1->value[CPP_CP_MEAS_NTF_MIN_LEN], 6); + len = 6; + break; + + default: + len = 0; + break; + } + + if (len) + { + // Update values + meas_ntf2->length += len; + // Remove field and flags from the first ntf + meas_ntf1->length -= len; + memcpy(&meas_ntf1->value[CPP_CP_MEAS_NTF_MIN_LEN], + &meas_ntf1->value[CPP_CP_MEAS_NTF_MIN_LEN + len], + meas_ntf1->length); + // Update flags + meas_ntf1->value[0] &= ~feat; + meas_ntf2->value[0] |= feat; + } + } + } + + // store the pending notification to send + cpps_env->op_data->ntf_pending = meas_ntf2; + + return meas_ntf2->length; +} + +uint8_t cpps_update_characteristic_config(uint8_t conidx, uint8_t prfl_config, struct gattc_write_req_ind const *param) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get the value + uint16_t ntf_cfg = co_read16p(¶m->value[0]); + + switch (prfl_config) + { + case CPP_PRF_CFG_FLAG_CTNL_PT_IND: + // Check CCC configuration + if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_IND)) + { + // Save the new configuration in the environment + (ntf_cfg == PRF_CLI_STOP_NTFIND) ? + CPPS_DISABLE_NTF_IND_BCST(conidx, prfl_config) : CPPS_ENABLE_NTF_IND_BCST(conidx, prfl_config); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + break; + + case CPP_PRF_CFG_FLAG_VECTOR_NTF: + // Do not save until confirmation + break; + + case CPP_PRF_CFG_FLAG_SP_MEAS_NTF: + // Check CCC configuration + if ((ntf_cfg == PRF_SRV_STOP_BCST) || (ntf_cfg == PRF_SRV_START_BCST)) + { + // Save the new configuration in the environment + cpps_env->broadcast_enabled = (ntf_cfg == PRF_SRV_STOP_BCST) ? + false : true; + + // Update value for every connection (useful for bond data) + for (uint8_t i=0; iprf_env, conidx), prf_src_task_get(&cpps_env->prf_env, conidx), + cpps_vector_cfg_req_ind); + //Inform APP of configuration change + ind->char_code = prfl_config; + ind->ntf_cfg = ntf_cfg; + ind->conidx = conidx; + ke_msg_send(ind); + } + else + { + // Allocate message to inform application + struct cpps_cfg_ntfind_ind *ind = KE_MSG_ALLOC(CPPS_CFG_NTFIND_IND, + prf_dst_task_get(&cpps_env->prf_env, conidx), prf_src_task_get(&cpps_env->prf_env, conidx), + cpps_cfg_ntfind_ind); + //Inform APP of configuration change + ind->char_code = prfl_config; + ind->ntf_cfg = ntf_cfg; + ind->conidx = conidx; + ke_msg_send(ind); + } + // Enable Bonded Data + CPPS_ENABLE_NTF_IND_BCST(conidx, CPP_PRF_CFG_PERFORMED_OK); + } + return (status); +} + +uint8_t cpps_pack_vector_ntf(struct cpp_cp_vector *param, uint8_t *pckd_vector) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + // Packed Measurement length + uint8_t pckd_vector_len = CPP_CP_VECTOR_MIN_LEN; + + // Check provided flags + if (CPPS_IS_PRESENT(param->flags, CPP_VECTOR_CRANK_REV_DATA_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_CRANK_REV_DATA_SUPP)) + { + //Pack Crank Revolution Data (Cumulative Crank & Last Crank Event Time) + co_write16p(&pckd_vector[pckd_vector_len], param->cumul_crank_rev); + pckd_vector_len += 2; + co_write16p(&pckd_vector[pckd_vector_len], param->last_crank_evt_time); + pckd_vector_len += 2; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_VECTOR_CRANK_REV_DATA_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_VECTOR_FIRST_CRANK_MEAS_ANGLE_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_EXTREME_ANGLES_SUPP)) + { + //Pack First Crank Measurement Angle + co_write16p(&pckd_vector[pckd_vector_len], param->first_crank_meas_angle); + pckd_vector_len += 2; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_VECTOR_FIRST_CRANK_MEAS_ANGLE_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_VECTOR_INST_FORCE_MAGNITUDE_ARRAY_PRESENT)) + { + if (CPPS_IS_CLEAR(cpps_env->features, CPP_FEAT_SENSOR_MEAS_CONTEXT)) + { + //Pack Instantaneous Force Magnitude Array + if ((param->nb > CPP_CP_VECTOR_MIN_LEN) && + (param->nb <= CPP_CP_VECTOR_MAX_LEN - pckd_vector_len)) + { + for(int j=0; jnb; j++) + { + co_write16p(&pckd_vector[pckd_vector_len], param->force_torque_magnitude[j]); + pckd_vector_len += 2; + } + } + else + { + return 0; + } + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_VECTOR_INST_FORCE_MAGNITUDE_ARRAY_PRESENT; + } + } + + if (CPPS_IS_PRESENT(param->flags, CPP_VECTOR_INST_TORQUE_MAGNITUDE_ARRAY_PRESENT)) + { + if (CPPS_IS_SET(cpps_env->features, CPP_FEAT_SENSOR_MEAS_CONTEXT)) + { + //Pack Instantaneous Torque Magnitude Array + if ((param->nb > CPP_CP_VECTOR_MIN_LEN) && + (param->nb <= CPP_CP_VECTOR_MAX_LEN - pckd_vector_len)) + { + for(int j=0; jnb; j++) + { + co_write16p(&pckd_vector[pckd_vector_len], param->force_torque_magnitude[j]); + pckd_vector_len += 2; + } + } + else + { + return 0; + } + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~CPP_VECTOR_INST_TORQUE_MAGNITUDE_ARRAY_PRESENT; + } + } + + // Allow to use reserved flags + //param->flags &= CPP_VECTOR_ALL_SUPP; + // Flags value + pckd_vector[0] = param->flags; + + return pckd_vector_len; +} + +void cpps_send_rsp_ind(uint8_t conidx, uint8_t req_op_code, uint8_t status) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ctl_pt_rsp = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), + prf_src_task_get(&cpps_env->prf_env, conidx), + gattc_send_evt_cmd, CPP_CP_CNTL_PT_RSP_MIN_LEN); + + // Fill in the parameter structure + ctl_pt_rsp->operation = GATTC_INDICATE; + ctl_pt_rsp->handle = CPPS_HANDLE(CPS_IDX_CTNL_PT_VAL); + // Pack Control Point confirmation + ctl_pt_rsp->length = CPP_CP_CNTL_PT_RSP_MIN_LEN; + // Response Code + ctl_pt_rsp->value[0] = CPP_CTNL_PT_RSP_CODE; + // Request Operation Code + ctl_pt_rsp->value[1] = req_op_code; + // Response value + ctl_pt_rsp->value[2] = status; + + // Send the event + ke_msg_send(ctl_pt_rsp); +} + +uint8_t cpps_unpack_ctnl_point_ind (uint8_t conidx, struct gattc_write_req_ind const *param) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + + // Indication Status + uint8_t ind_status = CPP_CTNL_PT_RESP_NOT_SUPP; + + // Allocate a request indication message for the application + struct cpps_ctnl_pt_req_ind *req_ind = KE_MSG_ALLOC(CPPS_CTNL_PT_REQ_IND, + prf_dst_task_get(&cpps_env->prf_env, conidx), prf_src_task_get(&cpps_env->prf_env, conidx), cpps_ctnl_pt_req_ind); + // Operation Code + req_ind->op_code = param->value[0]; + req_ind->conidx = conidx; + + // Operation Code + switch(req_ind->op_code) + { + case (CPP_CTNL_PT_SET_CUMUL_VAL): + { + // Check if the Wheel Revolution Data feature is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_WHEEL_REV_DATA_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = CPP_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 5) + { + // The request can be handled + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_SET_CUMUL_VAL_OP_CODE; + // Cumulative value + req_ind->value.cumul_val = co_read32p(¶m->value[1]); + } + } + } break; + + case (CPP_CTNL_PT_UPD_SENSOR_LOC): + { + // Check if the Multiple Sensor Location feature is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_MULT_SENSOR_LOC_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = CPP_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 2) + { + // Check the sensor location value + if (param->value[1] < CPP_LOC_MAX) + { + // The request can be handled + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_UPD_SENSOR_LOC_OP_CODE; + // Sensor Location + req_ind->value.sensor_loc = param->value[1]; + } + } + } + } break; + + case (CPP_CTNL_PT_REQ_SUPP_SENSOR_LOC): + { + // Check if the Multiple Sensor Location feature is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_MULT_SENSOR_LOC_SUPP)) + { + // The request can be handled + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_REQ_SUPP_SENSOR_LOC_OP_CODE; + } + } break; + + case (CPP_CTNL_PT_SET_CRANK_LENGTH): + { + // Check if the Crank Length Adjustment feature is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_CRANK_LENGTH_ADJ_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = CPP_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 3) + { + // The request can be handled + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_SET_CRANK_LENGTH_OP_CODE; + // Crank Length + req_ind->value.crank_length = co_read16p(¶m->value[1]); + } + } + + } break; + + case (CPP_CTNL_PT_REQ_CRANK_LENGTH): + { + // Optional even if feature not supported + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_REQ_CRANK_LENGTH_OP_CODE; + } break; + + case (CPP_CTNL_PT_SET_CHAIN_LENGTH): + { + // Check if the Chain Length Adjustment feature is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_CHAIN_LENGTH_ADJ_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = CPP_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 3) + { + // The request can be handled + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_SET_CHAIN_LENGTH_OP_CODE; + // Chain Length + req_ind->value.crank_length = co_read16p(¶m->value[1]); + } + } + + } break; + + case (CPP_CTNL_PT_REQ_CHAIN_LENGTH): + { + // Optional even if feature not supported + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_REQ_CHAIN_LENGTH_OP_CODE; + } break; + + case (CPP_CTNL_PT_SET_CHAIN_WEIGHT): + { + // Check if the Chain Weight Adjustment feature is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_CHAIN_WEIGHT_ADJ_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = CPP_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 3) + { + // The request can be handled + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_SET_CHAIN_WEIGHT_OP_CODE; + // Chain Weight + req_ind->value.chain_weight = co_read16p(¶m->value[1]); + } + } + + } break; + + case (CPP_CTNL_PT_REQ_CHAIN_WEIGHT): + { + // Optional even if feature not supported + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_REQ_CHAIN_WEIGHT_OP_CODE; + } break; + + case (CPP_CTNL_PT_SET_SPAN_LENGTH): + { + // Check if the Span Length Adjustment feature is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_SPAN_LENGTH_ADJ_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = CPP_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 3) + { + // The request can be handled + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_SET_SPAN_LENGTH_OP_CODE; + // Span Length + req_ind->value.span_length = co_read16p(¶m->value[1]); + } + } + + } break; + + case (CPP_CTNL_PT_REQ_SPAN_LENGTH): + { + // Optional even if feature not supported + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_REQ_SPAN_LENGTH_OP_CODE; + } break; + + case (CPP_CTNL_PT_START_OFFSET_COMP): + { + // Check if the Offset Compensation feature is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_OFFSET_COMP_SUPP)) + { + // The request can be handled + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_PT_START_OFFSET_COMP_OP_CODE; + } + } break; + + case (CPP_CTNL_MASK_CP_MEAS_CH_CONTENT): + { + // Check if the CP Masking feature is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_CP_MEAS_CH_CONTENT_MASKING_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = CPP_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 3) + { + // The request can be handled + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_MASK_CP_MEAS_CH_CONTENT_OP_CODE; + // Mask content + req_ind->value.mask_content = co_read16p(¶m->value[1]); + } + } + } break; + + case (CPP_CTNL_REQ_SAMPLING_RATE): + { + // Optional even if feature not supported + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_REQ_SAMPLING_RATE_OP_CODE; + } break; + + case (CPP_CTNL_REQ_FACTORY_CALIBRATION_DATE): + { + // Optional even if feature not supported + ind_status = CPP_CTNL_PT_RESP_SUCCESS; + // Update the environment + cpps_env->operation = CPPS_CTNL_REQ_FACTORY_CALIBRATION_DATE_OP_CODE; + } break; + + default: + { + // Operation Code is invalid, status is already CPP_CTNL_PT_RESP_NOT_SUPP + } break; + } + + // If no error raised, inform the application about the request + if (ind_status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Send the request indication to the application + ke_msg_send(req_ind); + // Go to the Busy status + ke_state_set(prf_src_task_get(&cpps_env->prf_env, conidx), CPPS_BUSY); + } + else + { + // Free the allocated message + ke_msg_free(ke_param2msg(req_ind)); + } + + return ind_status; +} + +uint8_t cpps_pack_ctnl_point_cfm (uint8_t conidx, struct cpps_ctnl_pt_cfm *param, uint8_t *rsp) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + // Response Length (At least 3) + uint8_t rsp_len = CPP_CP_CNTL_PT_RSP_MIN_LEN; + + // Set the Response Code + rsp[0] = CPP_CTNL_PT_RSP_CODE; + // Set the Response Value + rsp[2] = (param->status > CPP_CTNL_PT_RESP_FAILED) ? CPP_CTNL_PT_RESP_FAILED : param->status; + + switch (cpps_env->operation) + { + case (CPPS_CTNL_PT_SET_CUMUL_VAL_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_SET_CUMUL_VAL; + + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Save in the environment + cpps_env->cumul_wheel_rev = param->value.cumul_wheel_rev; + } + } break; + + case (CPPS_CTNL_PT_UPD_SENSOR_LOC_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_UPD_SENSOR_LOC; + + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Store the new value in the environment + cpps_env->sensor_loc = param->value.sensor_loc; + } + } break; + + case (CPPS_CTNL_PT_REQ_SUPP_SENSOR_LOC_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_REQ_SUPP_SENSOR_LOC; + + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Set the list of supported location + for (uint8_t counter = 0; counter < CPP_LOC_MAX; counter++) + { + if ((param->value.supp_sensor_loc >> counter) & 0x0001) + { + rsp[rsp_len] = counter; + rsp_len++; + } + } + } + } break; + + case (CPPS_CTNL_PT_SET_CRANK_LENGTH_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_SET_CRANK_LENGTH; + } break; + + case (CPPS_CTNL_PT_REQ_CRANK_LENGTH_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_REQ_CRANK_LENGTH; + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Set the response parameter + co_write16p(&rsp[rsp_len], param->value.crank_length); + rsp_len += 2; + } + } break; + + case (CPPS_CTNL_PT_SET_CHAIN_LENGTH_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_SET_CHAIN_LENGTH; + } break; + + case (CPPS_CTNL_PT_REQ_CHAIN_LENGTH_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_REQ_CHAIN_LENGTH; + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Set the response parameter + co_write16p(&rsp[rsp_len], param->value.chain_length); + rsp_len += 2; + } + } break; + + case (CPPS_CTNL_PT_SET_CHAIN_WEIGHT_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_SET_CHAIN_WEIGHT; + } break; + + + case (CPPS_CTNL_PT_REQ_CHAIN_WEIGHT_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_REQ_CHAIN_WEIGHT; + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Set the response parameter + co_write16p(&rsp[rsp_len], param->value.chain_weight); + rsp_len += 2; + } + } break; + + case (CPPS_CTNL_PT_SET_SPAN_LENGTH_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_SET_SPAN_LENGTH; + } break; + + case (CPPS_CTNL_PT_REQ_SPAN_LENGTH_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_REQ_SPAN_LENGTH; + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Set the response parameter + co_write16p(&rsp[rsp_len], param->value.span_length); + rsp_len += 2; + } + } break; + + case (CPPS_CTNL_PT_START_OFFSET_COMP_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_PT_START_OFFSET_COMP; + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Set the response parameter + co_write16p(&rsp[rsp_len], param->value.offset_comp); + rsp_len += 2; + } + } break; + + case (CPPS_CTNL_MASK_CP_MEAS_CH_CONTENT_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_MASK_CP_MEAS_CH_CONTENT; + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + uint16_t cpp_mask_cp_meas_flags [] = + { + CPP_MEAS_PEDAL_POWER_BALANCE_PRESENT, + CPP_MEAS_ACCUM_TORQUE_PRESENT, + CPP_MEAS_WHEEL_REV_DATA_PRESENT, + CPP_MEAS_CRANK_REV_DATA_PRESENT, + CPP_MEAS_EXTREME_FORCE_MAGNITUDES_PRESENT | + CPP_MEAS_EXTREME_TORQUE_MAGNITUDES_PRESENT, + CPP_MEAS_EXTREME_ANGLES_PRESENT, + CPP_MEAS_TOP_DEAD_SPOT_ANGLE_PRESENT, + CPP_MEAS_BOTTOM_DEAD_SPOT_ANGLE_PRESENT, + CPP_MEAS_ACCUM_ENERGY_PRESENT, + }; + + uint16_t mask = 0; + for (uint8_t count = 0; count < 9; count++) + { + if ((param->value.mask_meas_content >> count) & 0x0001) + { + mask |= cpp_mask_cp_meas_flags[count]; + } + } + cpps_env->env[conidx].mask_meas_content = mask; + } + } break; + + case (CPPS_CTNL_REQ_SAMPLING_RATE_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_REQ_SAMPLING_RATE; + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Set the response parameter + rsp[rsp_len] = param->value.sampling_rate; + rsp_len ++; + } + } break; + + case (CPPS_CTNL_REQ_FACTORY_CALIBRATION_DATE_OP_CODE): + { + // Set the request operation code + rsp[1] = CPP_CTNL_REQ_FACTORY_CALIBRATION_DATE; + if (param->status == CPP_CTNL_PT_RESP_SUCCESS) + { + // Set the response parameter + rsp_len += prf_pack_date_time(&rsp[rsp_len], &(param->value.factory_calibration)); + } + } break; + + default: + { + rsp[2] = CPP_CTNL_PT_RESP_NOT_SUPP; + } break; + } + + return rsp_len; +} + + +int cpps_update_cfg_char_value (uint8_t conidx, uint8_t con_type, uint8_t handle, uint16_t ntf_cfg, uint16_t cfg_flag) +{ + uint8_t status = ATT_ERR_NO_ERROR; + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + + if (con_type != PRF_CON_DISCOVERY) + { + // Save the new configuration in the environment + ((ntf_cfg & cfg_flag) == 0) ? + CPPS_DISABLE_NTF_IND_BCST(conidx, cfg_flag) : + CPPS_ENABLE_NTF_IND_BCST(conidx, cfg_flag); + } + + return (status); +} + +void cpps_send_cmp_evt(uint8_t conidx, uint8_t src_id, uint8_t dest_id, uint8_t operation, uint8_t status) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + // Go back to the IDLE if the state is busy + if (ke_state_get(src_id) == CPPS_BUSY) + { + ke_state_set(src_id, CPPS_IDLE); + } + + // Set the operation code + cpps_env->operation = CPPS_RESERVED_OP_CODE; + + // Send the message + struct cpps_cmp_evt *evt = KE_MSG_ALLOC(CPPS_CMP_EVT, + dest_id, src_id, + cpps_cmp_evt); + + evt->conidx = conidx; + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + +void cpps_exe_operation(void) +{ + struct cpps_env_tag* cpps_env = PRF_ENV_GET(CPPS, cpps); + + ASSERT_ERR(cpps_env->op_data != NULL); + + bool finished = true; + + while((cpps_env->op_data->cursor < BLE_CONNECTION_MAX) && finished) + { + uint8_t conidx = cpps_env->op_data->cursor; + + switch(cpps_env->operation) + { + case CPPS_NTF_MEAS_OP_CODE: + { + // notification is pending, send it first + if(cpps_env->op_data->ntf_pending != NULL) + { + ke_msg_send(cpps_env->op_data->ntf_pending); + cpps_env->op_data->ntf_pending = NULL; + finished = false; + } + // Check if sending of notifications has been enabled + else if (CPPS_IS_NTF_IND_BCST_ENABLED(conidx, CPP_PRF_CFG_FLAG_CP_MEAS_NTF)) + { + struct cpps_ntf_cp_meas_req *meas_cmd = + (struct cpps_ntf_cp_meas_req *) ke_msg2param(cpps_env->op_data->cmd); + // Save flags value + uint16_t flags = meas_cmd->parameters.flags; + + // Mask unwanted fields if supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_CP_MEAS_CH_CONTENT_MASKING_SUPP)) + { + meas_cmd->parameters.flags &= ~cpps_env->env[conidx].mask_meas_content; + } + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&(cpps_env->prf_env),conidx), + gattc_send_evt_cmd, CPP_CP_MEAS_NTF_MAX_LEN); + + // Fill in the parameter structure + meas_val->operation = GATTC_NOTIFY; + meas_val->handle = CPPS_HANDLE(CPS_IDX_CP_MEAS_VAL); + // pack measured value in database + meas_val->length = cpps_pack_meas_ntf(&meas_cmd->parameters, meas_val->value); + + if (meas_val->length > gattc_get_mtu(conidx) - 3) + { + // Split (if necessary) + cpps_split_meas_ntf(conidx, meas_val); + } + + // Restore flags value + meas_cmd->parameters.flags = flags; + + // Send the event + ke_msg_send(meas_val); + + finished = false; + } + // update cursor only if all notification has been sent + if(cpps_env->op_data->ntf_pending == NULL) + { + cpps_env->op_data->cursor++; + } + } break; + + case CPPS_NTF_VECTOR_OP_CODE: + { + struct cpps_ntf_cp_vector_req *vector_cmd = + (struct cpps_ntf_cp_vector_req *) ke_msg2param(cpps_env->op_data->cmd); + + // Check if sending of notifications has been enabled + if (CPPS_IS_NTF_IND_BCST_ENABLED(conidx, CPP_PRF_CFG_FLAG_VECTOR_NTF)) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *vector_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&(cpps_env->prf_env),conidx), + gattc_send_evt_cmd, CPP_CP_VECTOR_MAX_LEN); + + // Fill in the parameter structure + vector_val->operation = GATTC_NOTIFY; + vector_val->handle = CPPS_HANDLE(CPS_IDX_VECTOR_VAL); + // pack measured value in database + vector_val->length = cpps_pack_vector_ntf(&vector_cmd->parameters, vector_val->value); + + // Send the event + ke_msg_send(vector_val); + + finished = false; + } + + cpps_env->op_data->cursor++; + } break; + + default: ASSERT_ERR(0); break; + } + } + + // check if operation is finished + if(finished) + { + if (cpps_env->operation == CPPS_NTF_MEAS_OP_CODE) + { + // send response to requester + struct cpps_ntf_cp_meas_rsp * rsp = KE_MSG_ALLOC( + CPPS_NTF_CP_MEAS_RSP, + cpps_env->op_data->cmd->src_id, + cpps_env->op_data->cmd->dest_id, + cpps_ntf_cp_meas_rsp); + + rsp->status = GAP_ERR_NO_ERROR; + ke_msg_send(rsp); + } + else if (cpps_env->operation == CPPS_NTF_VECTOR_OP_CODE) + { + // send response to requester + struct cpps_ntf_cp_vector_rsp * rsp = KE_MSG_ALLOC( + CPPS_NTF_CP_VECTOR_RSP, + cpps_env->op_data->cmd->src_id, + cpps_env->op_data->cmd->dest_id, + cpps_ntf_cp_vector_rsp); + + rsp->status = GAP_ERR_NO_ERROR; + ke_msg_send(rsp); + } + + // free operation data + ke_msg_free(cpps_env->op_data->cmd); + ke_free(cpps_env->op_data); + cpps_env->op_data = NULL; + // Set the operation code + cpps_env->operation = CPPS_RESERVED_OP_CODE; + // go back to idle state + ke_state_set(prf_src_task_get(&(cpps_env->prf_env), 0), CPPS_IDLE); + } +} + +#endif //(BLE_CP_SENSOR) + +/// @} CPPS diff --git a/services/ble_profiles/cpp/cpps/src/cpps.h b/services/ble_profiles/cpp/cpps/src/cpps.h new file mode 100644 index 0000000..66ceacc --- /dev/null +++ b/services/ble_profiles/cpp/cpps/src/cpps.h @@ -0,0 +1,366 @@ +#ifndef _CPPS_H_ +#define _CPPS_H_ + +/** + **************************************************************************************** + * @addtogroup CPPS Cycling Power Profile Sensor + * @ingroup CPP + * @brief Cycling Power Profile Sensor + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "cpp_common.h" + +#if (BLE_CP_SENSOR) + +#include "prf_types.h" +#include "prf.h" +#include "cpps_task.h" +#include "attm.h" +#include "co_math.h" + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/* + * DEFINES + **************************************************************************************** + */ +/// Maximum number of Cycling Power Profile Sensor role task instances +#define CPPS_IDX_MAX 1 + +/******************************************** + ******* CPPS Configuration Flag Masks ****** + ********************************************/ + +/// Mandatory Attributes (CP Measurement + CP Feature + CP Sensor Location) +#define CPPS_MANDATORY_MASK (0x01EF) +/// Broadcast Attribute +#define CPPS_MEAS_BCST_MASK (0x0010) +/// Vector Attributes +#define CPPS_VECTOR_MASK (0x0E00) +/// Control Point Attributes +#define CPPS_CTNL_PT_MASK (0x7000) + +/// Broadcast supported flag +#define CPPS_BROADCASTER_SUPP_FLAG (0x01) +/// Control Point supported flag +#define CPPS_CTNL_PT_CHAR_SUPP_FLAG (0x02) + + +/* + * MACROS + **************************************************************************************** + */ + +#define CPPS_IS_FEATURE_SUPPORTED(features, flag) ((features & flag) == flag) + +#define CPPS_IS_PRESENT(features, flag) ((features & flag) == flag) + +#define CPPS_IS_SET(features, flag) (features & flag) + +#define CPPS_IS_CLEAR(features, flag) ((features & flag) == 0) + +#define CPPS_ENABLE_NTF_IND_BCST(idx, ccc_flag) (cpps_env->env[idx].prfl_ntf_ind_cfg |= ccc_flag) + +#define CPPS_DISABLE_NTF_IND_BCST(idx, ccc_flag) (cpps_env->env[idx].prfl_ntf_ind_cfg &= ~ccc_flag) + +#define CPPS_IS_NTF_IND_BCST_ENABLED(idx, ccc_flag) ((cpps_env->env[idx].prfl_ntf_ind_cfg & ccc_flag) == ccc_flag) + +// MACRO TO CALCULATE HANDLE shdl + idx - BCST - VECTOR +// BCST is 1 if the broadcast mode is supported otherwise 0 +// VECTOR is 3 if the Vector characteristic is supported otherwise 0 +#define CPPS_HANDLE(idx) \ + (cpps_env->shdl + (idx) - \ + ((!(CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_MEAS_BCST_MASK)) && \ + ((idx) > CPS_IDX_CP_MEAS_BCST_CFG))? (1) : (0)) - \ + ((!(CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_VECTOR_MASK)) && \ + ((idx) > CPS_IDX_VECTOR_CHAR))? (3) : (0))) + +// Get database attribute index + #define CPPS_IDX(hdl) \ + ((hdl - cpps_env->shdl) + \ + ((!(CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_MEAS_BCST_MASK)) && \ + ((hdl - cpps_env->shdl) > CPS_IDX_CP_MEAS_BCST_CFG)) ? (1) : (0)) + \ + ((!(CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_VECTOR_MASK)) && \ + ((hdl - cpps_env->shdl) > CPS_IDX_VECTOR_CHAR)) ? (3) : (0))) + + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the CPPS task +enum cpps_state +{ + /// Idle state + CPPS_IDLE, + /// Busy state + CPPS_BUSY, + + /// Number of defined states. + CPPS_STATE_MAX +}; +/// Cycling Power Service - Attribute List +enum cpps_cps_att_list +{ + /// Cycling Power Service + CPS_IDX_SVC, + /// CP Measurement + CPS_IDX_CP_MEAS_CHAR, + CPS_IDX_CP_MEAS_VAL, + CPS_IDX_CP_MEAS_NTF_CFG, + CPS_IDX_CP_MEAS_BCST_CFG, + /// CP Feature + CPS_IDX_CP_FEAT_CHAR, + CPS_IDX_CP_FEAT_VAL, + /// Sensor Location + CPS_IDX_SENSOR_LOC_CHAR, + CPS_IDX_SENSOR_LOC_VAL, + /// CP Vector + CPS_IDX_VECTOR_CHAR, + CPS_IDX_VECTOR_VAL, + CPS_IDX_VECTOR_NTF_CFG, + /// CP Control Point + CPS_IDX_CTNL_PT_CHAR, + CPS_IDX_CTNL_PT_VAL, + CPS_IDX_CTNL_PT_IND_CFG, + + /// Number of attributes + CPS_IDX_NB, +}; + + +/// Profile Configuration Additional Flags () +enum cpps_prf_cfg_flag +{ + /// CP Measurement - Client Char. Cfg + CPP_PRF_CFG_FLAG_CP_MEAS_NTF = 0x01, + + /// CP Measurement - Server Char. Cfg + CPP_PRF_CFG_FLAG_SP_MEAS_NTF = 0x02, + + /// CP Vector - Client Characteristic configuration + CPP_PRF_CFG_FLAG_VECTOR_NTF = 0x04, + + /// Control Point - Client Characteristic configuration + CPP_PRF_CFG_FLAG_CTNL_PT_IND = 0x08, + + /// Bonded data used + CPP_PRF_CFG_PERFORMED_OK = 0x80, +}; + + + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// ongoing operation information +struct cpps_op +{ + /// On-going operation command + struct ke_msg * cmd; + /// notification pending + struct gattc_send_evt_cmd* ntf_pending; + + /// Cursor on connection + uint8_t cursor; +}; + +/// Cycling Power Profile Sensor environment variable per connection +struct cpps_cnx_env +{ + /// Measurement content mask + uint16_t mask_meas_content; + /// Profile Notify/Indication Flags + uint8_t prfl_ntf_ind_cfg; +}; + +/// Cycling Power Profile Sensor environment variable +struct cpps_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct cpps_cnx_env env[BLE_CONNECTION_MAX]; + /// On-going operation + struct cpps_op * op_data; + + /// Feature Configuration Flags + uint32_t features; + + /// Instantaneous Power + uint32_t inst_power; + /// Cumulative Value + uint32_t cumul_wheel_rev; + + /// Cycling Speed and Cadence Service Start Handle + uint16_t shdl; + /// Profile Configuration Flags + uint16_t prfl_cfg; + /// Operation + uint8_t operation; + + /// Sensor Location + uint8_t sensor_loc; + + /// State of different task instances + ke_state_t state[CPPS_IDX_MAX]; + + /// Broadcast advertisements are active + bool broadcast_enabled; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Retrieve CPP service profile interface + * + * @return CPP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* cpps_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Packs measurement notifications + * @param[in] param Pointer to the parameters of the message. + * @param[out] pckd_meas pointer to packed message + * @return status of the operation + **************************************************************************************** + */ +uint8_t cpps_pack_meas_ntf(struct cpp_cp_meas *param, uint8_t *pckd_meas); + +/** + **************************************************************************************** + * @brief Splits notifications in order to be sent with default MTU + * @param[in] conidx connection index + * @param[out] meas_val message to split + * @return length of the second notification + **************************************************************************************** + */ +uint8_t cpps_split_meas_ntf(uint8_t conidx, struct gattc_send_evt_cmd *meas_val); + +/** + **************************************************************************************** + * @brief updates the environment with the descriptor configuration and sends indication + * @param[in] conidx connection index + * @param[in] prfl_config profile descriptor code + * @param[in] param pointer to the message parameters + * @return status of the operation + **************************************************************************************** + */ +uint8_t cpps_update_characteristic_config(uint8_t conidx, uint8_t prfl_config, struct gattc_write_req_ind const *param); + +/** + **************************************************************************************** + * @brief Packs vector notifications + * @param[in] param Pointer to the parameters of the message. + * @param[out] pckd_vector pointer to packed message + * @return length + **************************************************************************************** + */ +uint8_t cpps_pack_vector_ntf(struct cpp_cp_vector *param, uint8_t *pckd_vector); + +/** + **************************************************************************************** + * @brief Unpack control point and sends indication + * @param[in] conidx connection index + * @param[in] param pointer to message + * @return status of the operation + **************************************************************************************** + */ +uint8_t cpps_unpack_ctnl_point_ind (uint8_t conidx, struct gattc_write_req_ind const *param); + +/** + **************************************************************************************** + * @brief Packs control point + * @param[in] conidx connection index + * @param[in] param Pointer to the parameters of the message. + * @param[out] rsp pointer to message + * @return status of the operation + **************************************************************************************** + */ +uint8_t cpps_pack_ctnl_point_cfm (uint8_t conidx, struct cpps_ctnl_pt_cfm *param, uint8_t *rsp); + +/** + **************************************************************************************** + * @brief Update database in non discovery modes + * @param[in] conidx connection index + * @param[in] con_type Connection type + * @param[in] handle handle + * @param[in] ntf_cfg provided flag + * @param[in] cfg_flag requested flag + * @return status of the operation + **************************************************************************************** + */ +int cpps_update_cfg_char_value (uint8_t conidx, uint8_t con_type, uint8_t handle, uint16_t ntf_cfg, uint16_t cfg_flag); + +/** + **************************************************************************************** + * @brief Send a CPPS_CMP_EVT message to the application. + * @param[in] conidx connection index + * @param[in] src_id Source task + * @param[in] dest_id Destination task + * @param[in] operation Operation completed + * @param[in] status status of the operation + **************************************************************************************** + */ +void cpps_send_cmp_evt(uint8_t conidx, uint8_t src_id, uint8_t dest_id, uint8_t operation, uint8_t status); + +/** + **************************************************************************************** + * @brief Send a control point response to the peer + * @param[in] conidx connection index + * @param[in] req_op_code operation code + * @param[in] status status of the operation + **************************************************************************************** + */ +void cpps_send_rsp_ind(uint8_t conidx, uint8_t req_op_code, uint8_t status); + +/** + **************************************************************************************** + * @brief This function fully manages notification of measurement and vector + **************************************************************************************** + */ +void cpps_exe_operation(void); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void cpps_task_init(struct ke_task_desc *task_desc); + +#endif //(BLE_CP_SENSOR) + +/// @} CPPS + +#endif //(_CPPS_H_) diff --git a/services/ble_profiles/cpp/cpps/src/cpps_task.c b/services/ble_profiles/cpp/cpps/src/cpps_task.c new file mode 100644 index 0000000..3869934 --- /dev/null +++ b/services/ble_profiles/cpp/cpps/src/cpps_task.c @@ -0,0 +1,779 @@ +/** + **************************************************************************************** + * @addtogroup CPPSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "rwip_config.h" +#if (BLE_CP_SENSOR) +#include "cpp_common.h" + +#include "gapc.h" +#include "gattc.h" +#include "gattc_task.h" +#include "cpps.h" +#include "cpps_task.h" +#include "prf_utils.h" +#include "co_math.h" + +#include "ke_mem.h" +#include "co_utils.h" + + +/* + * CYCLING POWER SERVICE ATTRIBUTES + **************************************************************************************** + */ + + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPS_ENABLE_REQ message. + * @param[in] msgid Id of the message received + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ + +static int cpps_enable_req_handler(ke_msg_id_t const msgid, + struct cpps_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(ke_state_get(dest_id) == CPPS_IDLE) + { + // Bonded data was not used before + if (!CPPS_IS_PRESENT(cpps_env->env[param->conidx].prfl_ntf_ind_cfg, CPP_PRF_CFG_PERFORMED_OK)) + { + status = GAP_ERR_NO_ERROR; + // Save configuration and set flag + cpps_env->env[param->conidx].prfl_ntf_ind_cfg = param->prfl_ntf_ind_cfg; + // Enable Bonded Data + CPPS_ENABLE_NTF_IND_BCST(param->conidx, CPP_PRF_CFG_PERFORMED_OK); + } + } + + // send completed information to APP task that contains error status + struct cpps_enable_rsp *cmp_evt = KE_MSG_ALLOC(CPPS_ENABLE_RSP, src_id, dest_id, cpps_enable_rsp); + cmp_evt->status = status; + cmp_evt->conidx = param->conidx; + ke_msg_send(cmp_evt); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPS_GET_ADV_DATA_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int cpps_get_adv_data_req_handler(ke_msg_id_t const msgid, + struct cpps_get_adv_data_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + // State shall not be Connected or Busy + if (ke_state_get(dest_id) == CPPS_IDLE) + { + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + + // Allocate the message + struct cpps_get_adv_data_rsp *rsp = KE_MSG_ALLOC_DYN(CPPS_GET_ADV_DATA_RSP, + src_id, dest_id, + cpps_get_adv_data_rsp, CPP_CP_MEAS_ADV_MAX_LEN); + // Set status + rsp->status = GAP_ERR_COMMAND_DISALLOWED; + // Set length + rsp->data_len = 0; + + // Check Broadcast is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_MEAS_BCST_MASK)) + { + // Check if broadcast has been enabled + if (cpps_env->broadcast_enabled) + { + // Pack Cp Measurement + rsp->adv_data[0] = cpps_pack_meas_ntf(¶m->parameters, &rsp->adv_data[4]) + CPP_CP_ADV_HEADER_LEN; + // Pack Service Data AD type + rsp->adv_data[1] = GAP_AD_TYPE_SERVICE_16_BIT_DATA; + // Pack UUID of CPS + co_write16p(&rsp->adv_data[2], ATT_SVC_CYCLING_POWER); + + // Set data length + rsp->data_len = rsp->adv_data[0] + CPP_CP_ADV_LENGTH_LEN; + // Set status + rsp->status = GAP_ERR_NO_ERROR; + } + } + + // Send message + ke_msg_send(rsp); + } + else + { + msg_status = KE_MSG_SAVED; + } + + return (msg_status); +} +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPS_NTF_CP_MEAS_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int cpps_ntf_cp_meas_req_handler(ke_msg_id_t const msgid, + struct cpps_ntf_cp_meas_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_NO_FREE; + + // State shall not be Connected or Busy + if (ke_state_get(dest_id) == CPPS_IDLE) + { + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + + // Configure the environment + cpps_env->operation = CPPS_NTF_MEAS_OP_CODE; + // allocate operation data + cpps_env->op_data = (struct cpps_op*) ke_malloc(sizeof(struct cpps_op), KE_MEM_KE_MSG); + cpps_env->op_data->cmd = ke_param2msg(param); + cpps_env->op_data->cursor = 0; + cpps_env->op_data->ntf_pending = NULL; + + // Go to busy state + ke_state_set(dest_id, CPPS_BUSY); + + // Should be updated just once + if (CPPS_IS_PRESENT(param->parameters.flags, CPP_MEAS_WHEEL_REV_DATA_PRESENT)) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->features, CPP_FEAT_WHEEL_REV_DATA_SUPP)) + { + // Update the cumulative wheel revolutions value stored in the environment + // The value shall not decrement below zero + if (param->parameters.cumul_wheel_rev < 0) + { + cpps_env->cumul_wheel_rev = (co_abs(param->parameters.cumul_wheel_rev) > cpps_env->cumul_wheel_rev) ? + 0 : cpps_env->cumul_wheel_rev + param->parameters.cumul_wheel_rev; + } + else + { + cpps_env->cumul_wheel_rev += param->parameters.cumul_wheel_rev; + } + } + } + + // start operation execution + cpps_exe_operation(); + } + else + { + // Save it for later + msg_status = KE_MSG_SAVED; + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPS_NTF_CP_VECTOR_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int cpps_ntf_cp_vector_req_handler(ke_msg_id_t const msgid, + struct cpps_ntf_cp_vector_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + // State shall be Connected or Busy + if (ke_state_get(dest_id) == CPPS_IDLE) + { + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + // Check Vector characteristic is supported + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_VECTOR_MASK)) + { + // Configure the environment + cpps_env->operation = CPPS_NTF_VECTOR_OP_CODE; + // allocate operation data + cpps_env->op_data = (struct cpps_op*) ke_malloc(sizeof(struct cpps_op), KE_MEM_KE_MSG); + cpps_env->op_data->cmd = ke_param2msg(param); + cpps_env->op_data->cursor = 0; + cpps_env->op_data->ntf_pending = NULL; + // Go to busy state + ke_state_set(dest_id, CPPS_BUSY); + // start operation execution + cpps_exe_operation(); + + msg_status = KE_MSG_NO_FREE; + } + else + { + // send response to requester + struct cpps_ntf_cp_vector_rsp * rsp = KE_MSG_ALLOC( + CPPS_NTF_CP_VECTOR_RSP, + src_id, + dest_id, + cpps_ntf_cp_vector_rsp); + + rsp->status = PRF_ERR_FEATURE_NOT_SUPPORTED; + ke_msg_send(rsp); + } + } + else + { + // Keep the message for later + msg_status = KE_MSG_SAVED; + } + + return (int)msg_status; +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_WRITE_REQ_IND message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + uint8_t conidx = KE_IDX_GET(src_id); + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Control Point Status + uint8_t ctl_pt_status = CPP_CTNL_PT_RESP_SUCCESS; + + if (cpps_env != NULL) + { + // CP Measurement Characteristic, Client Characteristic Configuration Descriptor + if (param->handle == (CPPS_HANDLE(CPS_IDX_CP_MEAS_NTF_CFG))) + { + // Update value + status = cpps_update_characteristic_config(conidx, CPP_PRF_CFG_FLAG_CP_MEAS_NTF, param); + } + // CP Measurement Characteristic, Server Characteristic Configuration Descriptor + else if (param->handle == (CPPS_HANDLE(CPS_IDX_CP_MEAS_BCST_CFG))) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_MEAS_BCST_MASK)) + { + // Save value + status = cpps_update_characteristic_config(conidx, CPP_PRF_CFG_FLAG_SP_MEAS_NTF, param); + } + else + { + status = ATT_ERR_ATTRIBUTE_NOT_FOUND; + } + } + // CP Vector Characteristic, Client Characteristic Configuration Descriptor + else if (param->handle == (CPPS_HANDLE(CPS_IDX_VECTOR_NTF_CFG))) + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_VECTOR_MASK)) + { + // Update value + status = cpps_update_characteristic_config(conidx, CPP_PRF_CFG_FLAG_VECTOR_NTF, param); + } + else + { + status = ATT_ERR_ATTRIBUTE_NOT_FOUND; + } + } + // CP Control Point Characteristic + else + { + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_CTNL_PT_MASK)) + { + // CP Control Point, Client Characteristic Configuration Descriptor + if (param->handle == (CPPS_HANDLE(CPS_IDX_CTNL_PT_IND_CFG))) + { + // Update value + status = cpps_update_characteristic_config(conidx, CPP_PRF_CFG_FLAG_CTNL_PT_IND, param); + } + // CP Control Point Characteristic + else if (param->handle == (CPPS_HANDLE(CPS_IDX_CTNL_PT_VAL))) + { + do + { + // Check if sending of indications has been enabled + if (!CPPS_IS_NTF_IND_BCST_ENABLED(conidx, CPP_PRF_CFG_FLAG_CTNL_PT_IND)) + { + // CPP improperly configured + status = PRF_CCCD_IMPR_CONFIGURED; + break; + } + + if (cpps_env->operation >= CPPS_CTNL_PT_SET_CUMUL_VAL_OP_CODE) + { + // A procedure is already in progress + status = CPP_ERROR_PROC_IN_PROGRESS; + break; + } + + if (cpps_env->operation == CPPS_NTF_MEAS_OP_CODE) + { + // Keep the message until the end of the current procedure + msg_status = KE_MSG_NO_FREE; + break; + } + // Unpack Control Point parameters + ctl_pt_status = cpps_unpack_ctnl_point_ind (conidx, param); + + } while (0); + } + else + { + ASSERT_ERR(0); + } + } + else + { + status = ATT_ERR_ATTRIBUTE_NOT_FOUND; + } + } + + // Vector confirmation is sent by calling cpps_vector_cfg_cfm_handler + if (param->handle != (CPPS_HANDLE(CPS_IDX_VECTOR_NTF_CFG))) + { + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + + // Check if control point failed + if ((param->handle == (CPPS_HANDLE(CPS_IDX_CTNL_PT_VAL))) && + (ctl_pt_status != CPP_CTNL_PT_RESP_SUCCESS)) + { + // Send response to peer + cpps_send_rsp_ind(conidx, param->value[0], ctl_pt_status); + } + } + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == CPPS_IDLE) + { + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + uint8_t att_idx = CPPS_IDX(param->handle); + struct gattc_att_info_cfm * cfm; + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + // check if it's a client configuration char + if((att_idx == CPS_IDX_CP_MEAS_NTF_CFG) + || (att_idx == CPS_IDX_CP_MEAS_BCST_CFG) + || (att_idx == CPS_IDX_VECTOR_NTF_CFG) + || (att_idx == CPS_IDX_CTNL_PT_IND_CFG)) + { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } + + else if (att_idx == CPS_IDX_CTNL_PT_VAL) + { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } + // not expected request + else + { + cfm->length = 0; + cfm->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == CPPS_IDLE) + { + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t att_idx = CPPS_IDX(param->handle); + + uint8_t value[4]; + uint8_t value_size = 0; + uint8_t status = ATT_ERR_NO_ERROR; + + switch(att_idx) + { + case CPS_IDX_CP_MEAS_NTF_CFG: + { + value_size = sizeof(uint16_t); + co_write16p(value, (cpps_env->env[conidx].prfl_ntf_ind_cfg & CPP_PRF_CFG_FLAG_CP_MEAS_NTF) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + } break; + + case CPS_IDX_CP_MEAS_BCST_CFG: + { + // Broadcast feature is profile specific + if (CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_MEAS_BCST_MASK)) + { + // Fill data + value_size = sizeof(uint16_t); + // Broadcast status is also masked per connection (useful for bonding data) + co_write16p(value, (cpps_env->env[conidx].prfl_ntf_ind_cfg & CPP_PRF_CFG_FLAG_SP_MEAS_NTF) + ? PRF_SRV_START_BCST : PRF_SRV_STOP_BCST); + } + else + { + status = ATT_ERR_ATTRIBUTE_NOT_FOUND; + } + } break; + + case CPS_IDX_VECTOR_NTF_CFG: + { + // Fill data + value_size = sizeof(uint16_t); + co_write16p(value, (cpps_env->env[conidx].prfl_ntf_ind_cfg & CPP_PRF_CFG_FLAG_VECTOR_NTF) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + } break; + + case CPS_IDX_CTNL_PT_IND_CFG: + { + // Fill data + value_size = sizeof(uint16_t); + co_write16p(value, (cpps_env->env[conidx].prfl_ntf_ind_cfg & CPP_PRF_CFG_FLAG_CTNL_PT_IND) + ? PRF_CLI_START_IND : PRF_CLI_STOP_NTFIND); + } break; + + case CPS_IDX_CP_FEAT_VAL: + { + // Fill data + value_size = sizeof(uint32_t); + co_write32p(value, cpps_env->features); + } break; + + case CPS_IDX_SENSOR_LOC_VAL: + { + // Fill data + value_size = sizeof(uint8_t); + value[0] = cpps_env->sensor_loc; + } break; + + default: + { + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } break; + } + + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, value_size); + cfm->length = value_size; + memcpy(cfm->value, value, value_size); + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPS_VECTOR_CFG_CFM message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int cpps_vector_cfg_cfm_handler(ke_msg_id_t const msgid, + struct cpps_vector_cfg_cfm *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + // Status + uint8_t status = PRF_APP_ERROR; + + if (ke_state_get(dest_id) == CPPS_IDLE) + { + if (param->status == GAP_ERR_NO_ERROR) + { + if ((param->ntf_cfg == PRF_CLI_STOP_NTFIND) || (param->ntf_cfg == PRF_CLI_START_NTF)) + { + // Save the new configuration in the environment + (param->ntf_cfg == PRF_CLI_STOP_NTFIND) ? + CPPS_DISABLE_NTF_IND_BCST(param->conidx, CPP_PRF_CFG_FLAG_VECTOR_NTF) : + CPPS_ENABLE_NTF_IND_BCST(param->conidx, CPP_PRF_CFG_FLAG_VECTOR_NTF); + + status = GAP_ERR_NO_ERROR; + } + } + + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, KE_BUILD_ID(TASK_GATTC, param->conidx), dest_id, gattc_write_cfm); + cfm->handle = CPPS_HANDLE(CPS_IDX_VECTOR_NTF_CFG); + cfm->status = status; + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CPPS_CTNL_PT_CFM message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int cpps_ctnl_pt_cfm_handler(ke_msg_id_t const msgid, + struct cpps_ctnl_pt_cfm *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + uint8_t status = GAP_ERR_NO_ERROR; + + if (ke_state_get(dest_id) == CPPS_BUSY) + { + do + { + // Check the current operation + if (cpps_env->operation < CPPS_CTNL_PT_SET_CUMUL_VAL_OP_CODE) + { + // The confirmation has been sent without request indication, ignore + break; + } + + // The CP Control Point Characteristic must be supported if we are here + if (!CPPS_IS_FEATURE_SUPPORTED(cpps_env->prfl_cfg, CPPS_CTNL_PT_MASK)) + { + status = PRF_ERR_REQ_DISALLOWED; + break; + } + + // Check if sending of indications has been enabled + if (!CPPS_IS_NTF_IND_BCST_ENABLED(param->conidx, CPP_PRF_CFG_FLAG_CTNL_PT_IND)) + { + // CPP improperly configured + status = PRF_CCCD_IMPR_CONFIGURED; + break; + } + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ctl_pt_rsp = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, param->conidx), dest_id, + gattc_send_evt_cmd, CPP_CP_CNTL_PT_RSP_MAX_LEN); + + // Fill in the parameter structure + ctl_pt_rsp->operation = GATTC_INDICATE; + ctl_pt_rsp->handle = CPPS_HANDLE(CPS_IDX_CTNL_PT_VAL); + // Pack Control Point confirmation + ctl_pt_rsp->length = cpps_pack_ctnl_point_cfm (param->conidx, param, ctl_pt_rsp->value); + + // Send the event + ke_msg_send(ctl_pt_rsp); + + } while (0); + + if (status != GAP_ERR_NO_ERROR) + { + // Inform the application that a procedure has been completed + cpps_send_cmp_evt(param->conidx, + prf_src_task_get(&cpps_env->prf_env, param->conidx), + prf_dst_task_get(&cpps_env->prf_env, param->conidx), + cpps_env->operation, status); + } + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles @ref GATT_NOTIFY_CMP_EVT message meaning that a notification or an indication + * has been correctly sent to peer device (but not confirmed by peer device). + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(src_id); + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + + // Check if a connection exists + if (ke_state_get(dest_id) == CPPS_BUSY) + { + switch (param->operation) + { + case (GATTC_NOTIFY): + { + // On-going operation execution + cpps_exe_operation(); + } break; + + case (GATTC_INDICATE): + { + ASSERT_INFO(cpps_env->operation >= CPPS_CTNL_PT_SET_CUMUL_VAL_OP_CODE, 0, 0); + + // Inform the application that a procedure has been completed + cpps_send_cmp_evt(conidx, + prf_src_task_get(&cpps_env->prf_env, conidx), + prf_dst_task_get(&cpps_env->prf_env, conidx), + cpps_env->operation, param->status); + // else ignore the message + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(cpps) +{ + {CPPS_ENABLE_REQ, (ke_msg_func_t) cpps_enable_req_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {CPPS_GET_ADV_DATA_REQ, (ke_msg_func_t) cpps_get_adv_data_req_handler}, + {CPPS_NTF_CP_MEAS_REQ, (ke_msg_func_t) cpps_ntf_cp_meas_req_handler}, + {CPPS_NTF_CP_VECTOR_REQ, (ke_msg_func_t) cpps_ntf_cp_vector_req_handler}, + {CPPS_CTNL_PT_CFM, (ke_msg_func_t) cpps_ctnl_pt_cfm_handler}, + {CPPS_VECTOR_CFG_CFM, (ke_msg_func_t) cpps_vector_cfg_cfm_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, +}; + +void cpps_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct cpps_env_tag *cpps_env = PRF_ENV_GET(CPPS, cpps); + + task_desc->msg_handler_tab = cpps_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(cpps_msg_handler_tab); + task_desc->state = cpps_env->state; + task_desc->idx_max = CPPS_IDX_MAX; +} + +#endif //(BLE_CSC_SENSOR) + +/// @} CPPSTASK diff --git a/services/ble_profiles/cscp/cscp_common.h b/services/ble_profiles/cscp/cscp_common.h new file mode 100644 index 0000000..336a9e5 --- /dev/null +++ b/services/ble_profiles/cscp/cscp_common.h @@ -0,0 +1,208 @@ +#ifndef _CSCP_COMMON_H_ +#define _CSCP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup CSCP Cycling Speed and Cadence Profile + * @ingroup PROFILE + * @brief Cycling Speed and Cadence Profile + * + * The Cycling Speed and Cadence profile enables a Collector device to connect and + * interact with a Cycling Speed and Cadence Sensor for use in sports and fitness + * applications. + * + * This file contains all definitions that are common for the server and the client parts + * of the profile. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include + +/* + * DEFINES + **************************************************************************************** + */ +/// Procedure Already in Progress Error Code +#define CSCP_ERROR_PROC_IN_PROGRESS (0x80) +/// Client Characteristic Configuration descriptor improperly configured Error Code +#define CSCP_ERROR_CCC_INVALID_PARAM (0x81) + +/// CSC Measurement Value Min Length +#define CSCP_CSC_MEAS_MIN_LEN (1) +/// CSC Measurement Value Max Length +#define CSCP_CSC_MEAS_MAX_LEN (11) +/// SC Control Point Request Value Min Length +#define CSCP_SC_CNTL_PT_REQ_MIN_LEN (1) +/// SC Control Point Request Value Max Length +#define CSCP_SC_CNTL_PT_REQ_MAX_LEN (5) +/// SC Control Point Response Value Min Length +#define CSCP_SC_CNTL_PT_RSP_MIN_LEN (3) +/// SC Control Point Response Value Max Length +#define CSCP_SC_CNTL_PT_RSP_MAX_LEN (CSCP_SC_CNTL_PT_RSP_MIN_LEN + CSCP_LOC_MAX) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Cycling Speed and Cadence Service Characteristics +enum cscp_cscs_char +{ + /// CSC Measurement + CSCP_CSCS_CSC_MEAS_CHAR, + /// CSC Feature + CSCP_CSCS_CSC_FEAT_CHAR, + /// Sensor Location + CSCP_CSCS_SENSOR_LOC_CHAR, + /// SC Control Point + CSCP_CSCS_SC_CTNL_PT_CHAR, + + CSCP_CSCS_CHAR_MAX, +}; + +/// CSC Measurement Flags +enum cscp_meas_flags +{ + /// Wheel Revolution Data Present + CSCP_MEAS_WHEEL_REV_DATA_PRESENT = 0x01, + /// Crank Revolution Data Present + CSCP_MEAS_CRANK_REV_DATA_PRESENT = 0x02, + + /// All present + CSCP_MEAS_ALL_PRESENT = 0x03, +}; + +/// CSC Feature Flags +enum cscp_feat_flags +{ + /// Wheel Revolution Data Supported + CSCP_FEAT_WHEEL_REV_DATA_SUPP = 0x0001, + /// Crank Revolution Data Supported + CSCP_FEAT_CRANK_REV_DATA_SUPP = 0x0002, + /// Multiple Sensor Location Supported + CSCP_FEAT_MULT_SENSOR_LOC_SUPP = 0x0004, + + /// All supported + CSCP_FEAT_ALL_SUPP = 0x0007, +}; + +/// Sensor Locations Keys +enum cscp_sensor_loc +{ + /// Other (0) + CSCP_LOC_OTHER = 0, + /// Front Wheel (4) + CSCP_LOC_FRONT_WHEEL = 4, + /// Left Crank (5) + CSCP_LOC_LEFT_CRANK, + /// Right Crank (6) + CSCP_LOC_RIGHT_CRANK, + /// Left Pedal (7) + CSCP_LOC_LEFT_PEDAL, + /// Right Pedal (8) + CSCP_LOC_RIGHT_PEDAL, + /// Rear Dropout (9) + CSCP_LOC_REAR_DROPOUT, + /// Chainstay (10) + CSCP_LOC_CHAINSTAY, + /// Front Hub (11) + CSCP_LOC_FRONT_HUB, + /// Rear Wheel (12) + CSCP_LOC_REAR_WHEEL, + /// Rear Hub (13) + CSCP_LOC_REAR_HUB, + + CSCP_LOC_MAX, +}; + +/// Control Point Operation Code Keys +enum cscp_sc_ctnl_pt_op_code +{ + /// Reserved value + CSCP_CTNL_PT_OP_RESERVED = 0, + + /// Set Cumulative Value + CSCP_CTNL_PT_OP_SET_CUMUL_VAL, + /// Start Sensor Calibration + CSCP_CTNL_PT_OP_START_CALIB, + /// Update Sensor Location + CSCP_CTNL_PT_OP_UPD_LOC, + /// Request Supported Sensor Locations + CSCP_CTNL_PT_OP_REQ_SUPP_LOC, + + /// Response Code + CSCP_CTNL_PT_RSP_CODE = 16, +}; + +/// Control Point Response Value +enum cscp_ctnl_pt_resp_val +{ + /// Reserved value + CSCP_CTNL_PT_RESP_RESERVED = 0, + + /// Success + CSCP_CTNL_PT_RESP_SUCCESS, + /// Operation Code Not Supported + CSCP_CTNL_PT_RESP_NOT_SUPP, + /// Invalid Parameter + CSCP_CTNL_PT_RESP_INV_PARAM, + /// Operation Failed + CSCP_CTNL_PT_RESP_FAILED, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// CSC Measurement +struct cscp_csc_meas +{ + /// Flags + uint8_t flags; + /// Cumulative Crank Revolution + uint16_t cumul_crank_rev; + /// Last Crank Event Time + uint16_t last_crank_evt_time; + /// Last Wheel Event Time + uint16_t last_wheel_evt_time; + /// Cumulative Wheel Revolution + uint32_t cumul_wheel_rev; +}; + +/// SC Control Point Request +struct cscp_sc_ctnl_pt_req +{ + /// Operation Code + uint8_t op_code; + /// Value + union cscp_sc_ctnl_pt_req_val + { + /// Sensor Location + uint8_t sensor_loc; + /// Cumulative value + uint32_t cumul_val; + } value; +}; + +/// SC Control Point Response +struct cscp_sc_ctnl_pt_rsp +{ + /// Requested Operation Code + uint8_t req_op_code; + /// Response Value + uint8_t resp_value; + /// List of supported locations + uint16_t supp_loc; +}; + + +/// @} cscp_common + +#endif //(_CSCP_COMMON_H_) diff --git a/services/ble_profiles/cscp/cscpc/api/cscpc_task.h b/services/ble_profiles/cscp/cscpc/api/cscpc_task.h new file mode 100644 index 0000000..cffed8d --- /dev/null +++ b/services/ble_profiles/cscp/cscpc/api/cscpc_task.h @@ -0,0 +1,199 @@ +#ifndef _CSCPC_TASK_H_ +#define _CSCPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup CSCPCTASK Cycling Speed and Cadence Profile Collector Task + * @ingroup CSCPC + * @brief Cycling Speed and Cadence Profile Collector Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "cscp_common.h" + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Message IDs +enum cscpc_msg_ids +{ + /// Enable the Cycling Speed and Cadence Profile Collector task - at connection + CSCPC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_CSCPC), + /// Enable the Cycling Speed and Cadence Profile Collector task - at connection + CSCPC_ENABLE_RSP, + + /// Read the value of an attribute in the peer device database + CSCPC_READ_CMD, + + /// Configure sending of notification or indication + CSCPC_CFG_NTFIND_CMD, + + /// Configure the SC Control Point value + CSCPC_CTNL_PT_CFG_REQ, + /// SC Control Point value response + CSCPC_CTNL_PT_RSP, + + /// Indicate that an attribute value has been received either upon notification or read response + CSCPC_VALUE_IND, + + /// Complete Event Information + CSCPC_CMP_EVT, + + /// Procedure Timeout Timer + CSCPC_TIMEOUT_TIMER_IND, +}; + +/// Operation Codes +enum cscpc_op_codes +{ + /// Reserved operation code + CSCPC_RESERVED_OP_CODE = 0x00, + + /// Read attribute value Procedure + CSCPC_READ_OP_CODE, + + /// Wait for the Write Response after having written a Client Char. Cfg. Descriptor. + CSCPC_CFG_NTF_IND_OP_CODE, + /// Wait for the Write Response after having written the SC Control Point Char. + CSCPC_CTNL_PT_CFG_WR_OP_CODE, + /// Wait for the Indication Response after having written the SC Control Point Char. + CSCPC_CTNL_PT_CFG_IND_OP_CODE, +}; + +/* + * API MESSAGE STRUCTURES + **************************************************************************************** + */ + +/// Cycling Speed and Cadence Service Characteristic Descriptors +enum cscpc_cscs_descs +{ + /// CSC Measurement Char. - Client Characteristic Configuration + CSCPC_DESC_CSC_MEAS_CL_CFG, + /// SC Control Point Char. - Client Characteristic Configuration + CSCPC_DESC_SC_CTNL_PT_CL_CFG, + + CSCPC_DESC_MAX, + + CSCPC_DESC_MASK = 0x10, +}; + +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Cycling Speed and Cadence Service + */ +struct cscpc_cscs_content +{ + /// Service info + struct prf_svc svc; + + /// Characteristic info: + /// - CSC Measurement + /// - CSC Feature + /// - Sensor Location + /// - SC Control Point + struct prf_char_inf chars[CSCP_CSCS_CHAR_MAX]; + + /// Descriptor handles: + /// - CSC Measurement Client Cfg + /// - SC Control Point Client Cfg + struct prf_char_desc_inf descs[CSCPC_DESC_MAX]; +}; + +/// Parameters of the @ref CSCPC_ENABLE_REQ message +struct cscpc_enable_req +{ + /// Connection type + uint8_t con_type; + /// Existing handle values CSCS + struct cscpc_cscs_content cscs; +}; + +/// Parameters of the @ref CSCPC_ENABLE_RSP message +struct cscpc_enable_rsp +{ + /// status + uint8_t status; + /// Existing handle values CPS + struct cscpc_cscs_content cscs; +}; + +/// Parameters of the @ref CSCPC_READ_CMD message +struct cscpc_read_cmd +{ + /// Operation Code + uint8_t operation; + /// Read code + uint8_t read_code; +}; + +/// Parameters of the @ref CSCPC_CFG_NTFIND_CMD message +struct cscpc_cfg_ntfind_cmd +{ + /// Operation Code + uint8_t operation; + /// Descriptor code + uint8_t desc_code; + /// Ntf/Ind Configuration + uint16_t ntfind_cfg; +}; + +/// Parameters of the @ref CSCPC_CTNL_PT_CFG_REQ message +struct cscpc_ctnl_pt_cfg_req +{ + /// Operation Code + uint8_t operation; + /// SC Control Point Request + struct cscp_sc_ctnl_pt_req sc_ctnl_pt; +}; + +/// Parameters of the @ref CSCPC_CTNL_PT_RSP message +struct cscpc_ctnl_pt_rsp +{ + /// SC Control Point Response + struct cscp_sc_ctnl_pt_rsp ctnl_pt_rsp; +}; + + +/// Parameters of the @ref CSCPC_VALUE_IND message +struct cscpc_value_ind +{ + /// Attribute Code + uint8_t att_code; + /// Value + union cscpc_value_tag + { + /// CSC Measurement + struct cscp_csc_meas csc_meas; + /// CSC Feature + uint16_t sensor_feat; + /// Sensor Location + uint8_t sensor_loc; + /// Client Characteristic Configuration Descriptor Value + uint16_t ntf_cfg; + } value; +}; + +/// Parameters of the @ref CSCPC_CMP_EVT message +struct cscpc_cmp_evt +{ + /// Operation code + uint8_t operation; + /// Status + uint8_t status; +}; + +/// @} CSCPCTASK + +#endif //(_CSCPC_TASK_H_) diff --git a/services/ble_profiles/cscp/cscpc/src/cscpc.c b/services/ble_profiles/cscp/cscpc/src/cscpc.c new file mode 100644 index 0000000..b603cbc --- /dev/null +++ b/services/ble_profiles/cscp/cscpc/src/cscpc.c @@ -0,0 +1,237 @@ +/** + **************************************************************************************** + * @addtogroup CSCPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_CSC_COLLECTOR) +#include "cscp_common.h" + +#include "cscpc.h" +#include "cscpc_task.h" +#include "ke_timer.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * GLOBAL VARIABLES DECLARATION + **************************************************************************************** + */ + + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the CSCPC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t cscpc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct cscpc_env_tag* cscpc_env = + (struct cscpc_env_tag* ) ke_malloc(sizeof(struct cscpc_env_tag), KE_MEM_ATT_DB); + + // allocate CSCPC required environment variable + env->env = (prf_env_t*) cscpc_env; + + cscpc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + cscpc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_CSCPC; + cscpc_task_init(&(env->desc)); + + for(idx = 0; idx < CSCPC_IDX_MAX ; idx++) + { + cscpc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), CSCPC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void cscpc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct cscpc_env_tag* cscpc_env = (struct cscpc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(cscpc_env->env[conidx] != NULL) + { + if (cscpc_env->env[conidx]->operation != NULL) + { + ke_free(ke_param2msg(cscpc_env->env[conidx]->operation)); + } + ke_timer_clear(CSCPC_TIMEOUT_TIMER_IND, prf_src_task_get(&cscpc_env->prf_env, conidx)); + + ke_free(cscpc_env->env[conidx]); + cscpc_env->env[conidx] = NULL; + } + + /* Put CSCP Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), CSCPC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the CSCPC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void cscpc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct cscpc_env_tag* cscpc_env = (struct cscpc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < CSCPC_IDX_MAX ; idx++) + { + cscpc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(cscpc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void cscpc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put CSCP Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), CSCPC_IDLE); +} + +/// CSCPC Task interface required by profile manager +const struct prf_task_cbs cscpc_itf = +{ + cscpc_init, + cscpc_destroy, + cscpc_create, + cscpc_cleanup, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* cscpc_prf_itf_get(void) +{ + return &cscpc_itf; +} + + +void cscpc_enable_rsp_send(struct cscpc_env_tag *cscpc_env, uint8_t conidx, uint8_t status) +{ + // Send to APP the details of the discovered attributes on CSCPS + struct cscpc_enable_rsp * rsp = KE_MSG_ALLOC( + CSCPC_ENABLE_RSP, + prf_dst_task_get(&(cscpc_env->prf_env), conidx), + prf_src_task_get(&(cscpc_env->prf_env), conidx), + cscpc_enable_rsp); + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->cscs = cscpc_env->env[conidx]->cscs; + // Register CSCPC task in gatt for indication/notifications + prf_register_atthdl2gatt(&(cscpc_env->prf_env), conidx, &(cscpc_env->env[conidx]->cscs.svc)); + // Go to connected state + ke_state_set(prf_src_task_get(&(cscpc_env->prf_env), conidx), CSCPC_IDLE); + } + + ke_msg_send(rsp); +} + +void cscpc_send_no_conn_cmp_evt(uint8_t src_id, uint8_t dest_id, uint8_t operation) +{ + // Send the message + struct cscpc_cmp_evt *evt = KE_MSG_ALLOC(CSCPC_CMP_EVT, + dest_id, src_id, + cscpc_cmp_evt); + + evt->operation = operation; + evt->status = PRF_ERR_REQ_DISALLOWED; + + ke_msg_send(evt); +} + +void cscpc_send_cmp_evt(struct cscpc_env_tag *cscpc_env, uint8_t conidx, uint8_t operation, uint8_t status) +{ + // Free the stored operation if needed + if (cscpc_env->env[conidx]->operation != NULL) + { + ke_msg_free(ke_param2msg(cscpc_env->env[conidx]->operation)); + cscpc_env->env[conidx]->operation = NULL; + } + + // Go back to the CONNECTED state if the state is busy + if (ke_state_get(prf_src_task_get(&(cscpc_env->prf_env), conidx)) == CSCPC_BUSY) + { + ke_state_set(prf_src_task_get(&(cscpc_env->prf_env), conidx), CSCPC_IDLE); + } + + // Send the message + struct cscpc_cmp_evt *evt = KE_MSG_ALLOC(CSCPC_CMP_EVT, + prf_dst_task_get(&(cscpc_env->prf_env), conidx), + prf_src_task_get(&(cscpc_env->prf_env), conidx), + cscpc_cmp_evt); + + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + +#endif //(BLE_CSC_COLLECTOR) + +/// @} CSCP diff --git a/services/ble_profiles/cscp/cscpc/src/cscpc.h b/services/ble_profiles/cscp/cscpc/src/cscpc.h new file mode 100644 index 0000000..3b8067e --- /dev/null +++ b/services/ble_profiles/cscp/cscpc/src/cscpc.h @@ -0,0 +1,173 @@ +#ifndef _CSCPC_H_ +#define _CSCPC_H_ + +/** + **************************************************************************************** + * @addtogroup CSCPC Cycling Speed and Cadence Profile Collector + * @ingroup CSCP + * @brief Cycling Speed and Cadence Profile Collector + * @{ + **************************************************************************************** + */ + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of Cycling Speed and Cadence Collector task instances +#define CSCPC_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_CSC_COLLECTOR) + +#include "cscpc_task.h" +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the CSCPC task +enum cscpc_states +{ + /// Idle state + CSCPC_FREE, + /// Connected state + CSCPC_IDLE, + /// Discovery + CSCPC_DISCOVERING, + /// Busy state + CSCPC_BUSY, + + /// Number of defined states. + CSCPC_STATE_MAX +}; + + +/// Internal codes for reading/writing a CSCS characteristic with one single request +enum cscpc_codes +{ + /// Notified CSC Measurement + CSCPC_NTF_CSC_MEAS = CSCP_CSCS_CSC_MEAS_CHAR, + /// Read CSC Feature + CSCPC_RD_CSC_FEAT = CSCP_CSCS_CSC_FEAT_CHAR, + /// Read Sensor Location + CSCPC_RD_SENSOR_LOC = CSCP_CSCS_SENSOR_LOC_CHAR, + /// Indicated SC Control Point + CSCPC_IND_SC_CTNL_PT = CSCP_CSCS_SC_CTNL_PT_CHAR, + + /// Read/Write CSC Measurement Client Char. Configuration Descriptor + CSCPC_RD_WR_CSC_MEAS_CFG = (CSCPC_DESC_CSC_MEAS_CL_CFG | CSCPC_DESC_MASK), + /// Read SC Control Point Client Char. Configuration Descriptor + CSCPC_RD_WR_SC_CTNL_PT_CFG = (CSCPC_DESC_SC_CTNL_PT_CL_CFG | CSCPC_DESC_MASK), +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + + +struct cscpc_cnx_env +{ + /// Current Operation + void *operation; + ///Last requested UUID(to keep track of the two services and char) + uint16_t last_uuid_req; + /// Counter used to check service uniqueness + uint8_t nb_svc; + /// Cycling Speed and Cadence Service Characteristics + struct cscpc_cscs_content cscs; +}; + + +/// Cycling Speed and Cadence Profile Collector environment variable +struct cscpc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct cscpc_cnx_env* env[CSCPC_IDX_MAX]; + /// State of different task instances + ke_state_t state[CSCPC_IDX_MAX]; +}; + +/// Command Message Basic Structure +struct cscpc_cmd +{ + /// Operation Code + uint8_t operation; + + /// MORE DATA +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/* + * GLOBAL FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve CSCP client profile interface + * + * @return CSCP client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* cscpc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Cycling Power ATT DB discovery results to CSCPC host. + **************************************************************************************** + */ +void cscpc_enable_rsp_send(struct cscpc_env_tag *cscpc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Send a CSCPC_CMP_EVT message when no connection exists (no environment) + **************************************************************************************** + */ +void cscpc_send_no_conn_cmp_evt(uint8_t src_id, uint8_t dest_id, uint8_t operation); + +/** + **************************************************************************************** + * @brief Send a CSCPC_CMP_EVT message to the task which enabled the profile + **************************************************************************************** + */ +void cscpc_send_cmp_evt(struct cscpc_env_tag *cscpc_env, uint8_t conidx, uint8_t operation, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void cscpc_task_init(struct ke_task_desc *task_desc); + +#endif //(BLE_CSC_COLLECTOR) + +/// @} CSCPC + +#endif //(_CSCPC_H_) diff --git a/services/ble_profiles/cscp/cscpc/src/cscpc_task.c b/services/ble_profiles/cscp/cscpc/src/cscpc_task.c new file mode 100644 index 0000000..702e5fd --- /dev/null +++ b/services/ble_profiles/cscp/cscpc/src/cscpc_task.c @@ -0,0 +1,945 @@ +/** + **************************************************************************************** + * @addtogroup CSCPCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_CSC_COLLECTOR) +#include "cscp_common.h" +#include "cscpc_task.h" +#include "cscpc.h" + +#include "gap.h" +#include "gattc_task.h" + +#include "ke_timer.h" +#include "ke_mem.h" +#include "co_utils.h" + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// State machine used to retrieve Cycling Speed and Cadence service characteristics information +const struct prf_char_def cscpc_cscs_char[CSCP_CSCS_CHAR_MAX] = +{ + /// CSC Measurement + [CSCP_CSCS_CSC_MEAS_CHAR] = {ATT_CHAR_CSC_MEAS, + ATT_MANDATORY, + ATT_CHAR_PROP_NTF}, + /// CSC Feature + [CSCP_CSCS_CSC_FEAT_CHAR] = {ATT_CHAR_CSC_FEAT, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, + /// Sensor Location + [CSCP_CSCS_SENSOR_LOC_CHAR] = {ATT_CHAR_SENSOR_LOC, + ATT_OPTIONAL, + ATT_CHAR_PROP_RD}, + /// SC Control Point + [CSCP_CSCS_SC_CTNL_PT_CHAR] = {ATT_CHAR_SC_CNTL_PT, + ATT_OPTIONAL, + ATT_CHAR_PROP_WR | ATT_CHAR_PROP_IND}, +}; + +/// State machine used to retrieve Cycling Speed and Cadence service characteristic descriptor information +const struct prf_char_desc_def cscpc_cscs_char_desc[CSCPC_DESC_MAX] = +{ + /// CSC Measurement Char. - Client Characteristic Configuration + [CSCPC_DESC_CSC_MEAS_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_MANDATORY, + CSCP_CSCS_CSC_MEAS_CHAR}, + + /// SC Control Point Char. - Client Characteristic Configuration + [CSCPC_DESC_SC_CTNL_PT_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_OPTIONAL, + CSCP_CSCS_SC_CTNL_PT_CHAR}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == CSCPC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct cscpc_env_tag *cscpc_env = PRF_ENV_GET(CSCPC, cscpc); + + ASSERT_INFO(cscpc_env != NULL, dest_id, src_id); + ASSERT_INFO(cscpc_env->env[conidx] != NULL, dest_id, src_id); + + if(cscpc_env->env[conidx]->nb_svc == 0) + { + // Retrieve CSCS characteristics and descriptors + prf_extract_svc_info(ind, CSCP_CSCS_CHAR_MAX, &cscpc_cscs_char[0], &cscpc_env->env[conidx]->cscs.chars[0], + CSCPC_DESC_MAX, &cscpc_cscs_char_desc[0], &cscpc_env->env[conidx]->cscs.descs[0]); + + //Even if we get multiple responses we only store 1 range + cscpc_env->env[conidx]->cscs.svc.shdl = ind->start_hdl; + cscpc_env->env[conidx]->cscs.svc.ehdl = ind->end_hdl; + } + + cscpc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CSCPC_ENABLE_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cscpc_enable_req_handler(ke_msg_id_t const msgid, + struct cscpc_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + uint8_t state = ke_state_get(dest_id); + // Cycling Speed and Cadence Profile Collector Role Task Environment + struct cscpc_env_tag *cscpc_env = PRF_ENV_GET(CSCPC, cscpc); + + ASSERT_INFO(cscpc_env != NULL, dest_id, src_id); + if ((state == CSCPC_IDLE) && (cscpc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + cscpc_env->env[conidx] = (struct cscpc_cnx_env*) ke_malloc(sizeof(struct cscpc_cnx_env),KE_MEM_ATT_DB); + memset(cscpc_env->env[conidx], 0, sizeof(struct cscpc_cnx_env)); + + // Start discovering + if (param->con_type == PRF_CON_DISCOVERY) + { + prf_disc_svc_send(&(cscpc_env->prf_env), conidx, ATT_SVC_CYCLING_SPEED_CADENCE); + + // Go to DISCOVERING state + ke_state_set(dest_id, CSCPC_DISCOVERING); + } + // Bond information are provided + else + { + cscpc_env->env[conidx]->cscs = param->cscs; + + //send APP confirmation that can start normal connection to TH + cscpc_enable_rsp_send(cscpc_env, conidx, GAP_ERR_NO_ERROR); + } + } + else if (state != CSCPC_FREE) + { + // The message will be forwarded towards the good task instance + status = PRF_ERR_REQ_DISALLOWED; + } + + if(status != GAP_ERR_NO_ERROR) + { + // The request is disallowed (profile already enabled for this connection, or not enough memory, ...) + cscpc_enable_rsp_send(cscpc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CSCPC_READ_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cscpc_read_cmd_handler(ke_msg_id_t const msgid, + struct cscpc_read_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get the address of the environment + struct cscpc_env_tag *cscpc_env = PRF_ENV_GET(CSCPC, cscpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (state == CSCPC_IDLE) + { + ASSERT_INFO(cscpc_env != NULL, dest_id, src_id); + // environment variable not ready + if(cscpc_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + else + { + // Attribute Handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + + switch (param->read_code) + { + // Read CSC Feature + case (CSCPC_RD_CSC_FEAT): + { + handle = cscpc_env->env[conidx]->cscs.chars[CSCP_CSCS_CSC_FEAT_CHAR].val_hdl; + } break; + + // Read Sensor Location + case (CSCPC_RD_SENSOR_LOC): + { + handle = cscpc_env->env[conidx]->cscs.chars[CSCP_CSCS_SENSOR_LOC_CHAR].val_hdl; + } break; + + // Read CSC Measurement Characteristic Client Char. Cfg. Descriptor Value + case (CSCPC_RD_WR_CSC_MEAS_CFG): + { + handle = cscpc_env->env[conidx]->cscs.descs[CSCPC_DESC_CSC_MEAS_CL_CFG].desc_hdl; + } break; + + // Read Unread Alert Characteristic Client Char. Cfg. Descriptor Value + case (CSCPC_RD_WR_SC_CTNL_PT_CFG): + { + handle = cscpc_env->env[conidx]->cscs.descs[CSCPC_DESC_SC_CTNL_PT_CL_CFG].desc_hdl; + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + + // Check if handle is viable + if (handle != ATT_INVALID_SEARCH_HANDLE) + { + // Force the operation value + param->operation = CSCPC_READ_OP_CODE; + + // Store the command structure + cscpc_env->env[conidx]->operation = param; + msg_status = KE_MSG_NO_FREE; + + // Send the read request + prf_read_char_send(&(cscpc_env->prf_env), conidx, + cscpc_env->env[conidx]->cscs.svc.shdl, + cscpc_env->env[conidx]->cscs.svc.ehdl, + handle); + + // Go to the Busy state + ke_state_set(dest_id, CSCPC_BUSY); + + status = ATT_ERR_NO_ERROR; + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + } + + else if (state == CSCPC_FREE) + { + status = GAP_ERR_DISCONNECTED; + } + else + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + status = GAP_ERR_NO_ERROR; + } + + if (status != GAP_ERR_NO_ERROR) + { + // Send the complete event message to the task id stored in the environment + cscpc_send_cmp_evt(cscpc_env, conidx, CSCPC_READ_OP_CODE, status); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CSCPC_CFG_NTFIND_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cscpc_cfg_ntfind_cmd_handler(ke_msg_id_t const msgid, + struct cscpc_cfg_ntfind_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cscpc_env_tag *cscpc_env = PRF_ENV_GET(CSCPC, cscpc); + + uint8_t state = ke_state_get(dest_id); + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + if (cscpc_env != NULL) + { + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + // Handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + do + { + if (state != CSCPC_IDLE) + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + // Status is GAP_ERR_NO_ERROR, no message will be sent to the application + break; + } + + // state = CSCPC_CONNECTED + ASSERT_ERR(cscpc_env->env[conidx] != NULL); + + switch(param->desc_code) + { + // Write CSC Measurement Characteristic Client Char. Cfg. Descriptor Value + case (CSCPC_RD_WR_CSC_MEAS_CFG): + { + if (param->ntfind_cfg <= PRF_CLI_START_NTF) + { + handle = cscpc_env->env[conidx]->cscs.descs[CSCPC_DESC_CSC_MEAS_CL_CFG].desc_hdl; + // The descriptor is mandatory + ASSERT_ERR(handle != ATT_INVALID_SEARCH_HANDLE); + status = GAP_ERR_NO_ERROR; + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + // Write SC Control Point Characteristic Client Char. Cfg. Descriptor Value + case (CSCPC_RD_WR_SC_CTNL_PT_CFG): + { + if ((param->ntfind_cfg == PRF_CLI_STOP_NTFIND) || + (param->ntfind_cfg == PRF_CLI_START_IND)) + { + handle = cscpc_env->env[conidx]->cscs.descs[CSCPC_DESC_SC_CTNL_PT_CL_CFG].desc_hdl; + + status = GAP_ERR_NO_ERROR; + if (handle == ATT_INVALID_SEARCH_HANDLE) + { + // The descriptor has not been found. + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + } while (0); + + if ((status == GAP_ERR_NO_ERROR) && (handle != ATT_INVALID_SEARCH_HANDLE)) + { + // Set the operation code + param->operation = CSCPC_CFG_NTF_IND_OP_CODE; + + // Store the command structure + cscpc_env->env[conidx]->operation = param; + msg_status = KE_MSG_NO_FREE; + + // Go to the Busy state + ke_state_set(dest_id, CSCPC_BUSY); + + // Send GATT Write Request + prf_gatt_write_ntf_ind(&cscpc_env->prf_env, conidx, handle, param->ntfind_cfg); + } + } + else + { + cscpc_send_no_conn_cmp_evt(dest_id, src_id, CSCPC_CFG_NTF_IND_OP_CODE); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CSCPC_CFG_NTFIND_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cscpc_ctnl_pt_cfg_req_handler(ke_msg_id_t const msgid, + struct cscpc_ctnl_pt_cfg_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get the address of the environment + struct cscpc_env_tag *cscpc_env = PRF_ENV_GET(CSCPC, cscpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (cscpc_env != NULL) + { + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + do + { + // State is Connected or Busy + ASSERT_ERR(ke_state_get(dest_id) > CSCPC_FREE); + + // Check the provided connection handle + if (cscpc_env->env[conidx] == NULL) + { + status = PRF_ERR_INVALID_PARAM; + break; + } + + if (ke_state_get(dest_id) != CSCPC_IDLE) + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_NO_FREE; + // Status is GAP_ERR_NO_ERROR, no message will be sent to the application + break; + } + + // Check if the characteristic has been found + if (cscpc_env->env[conidx]->cscs.descs[CSCPC_DESC_SC_CTNL_PT_CL_CFG].desc_hdl != ATT_INVALID_SEARCH_HANDLE) + { + // Packed request + uint8_t req[CSCP_SC_CNTL_PT_REQ_MAX_LEN]; + // Request Length + uint8_t req_len = CSCP_SC_CNTL_PT_REQ_MIN_LEN; + + // Set the operation code + req[0] = param->sc_ctnl_pt.op_code; + + // Fulfill the message according to the operation code + switch (param->sc_ctnl_pt.op_code) + { + case (CSCP_CTNL_PT_OP_SET_CUMUL_VAL): + { + // Set the cumulative value + co_write32p(&req[req_len], param->sc_ctnl_pt.value.cumul_val); + // Update length + req_len += 4; + } break; + + case (CSCP_CTNL_PT_OP_UPD_LOC): + { + // Set the sensor location + req[req_len] = param->sc_ctnl_pt.value.sensor_loc; + // Update length + req_len++; + } break; + + case (CSCP_CTNL_PT_OP_RESERVED): + case (CSCP_CTNL_PT_OP_START_CALIB): + case (CSCP_CTNL_PT_OP_REQ_SUPP_LOC): + { + // Nothing more to do + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + + if (status == GAP_ERR_NO_ERROR) + { + // Set the operation code + param->operation = CSCPC_CTNL_PT_CFG_WR_OP_CODE; + + // Store the command structure + cscpc_env->env[conidx]->operation = param; + // Store the command information + msg_status = KE_MSG_NO_FREE; + + // Go to the Busy state + ke_state_set(dest_id, CSCPC_BUSY); + + // Send the write request + prf_gatt_write(&(cscpc_env->prf_env), conidx, cscpc_env->env[conidx]->cscs.chars[CSCP_CSCS_SC_CTNL_PT_CHAR].val_hdl, + (uint8_t *)&req[0], req_len, GATTC_WRITE); + } + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } while (0); + + if (status != GAP_ERR_NO_ERROR) + { + // Send a complete event status to the application + cscpc_send_cmp_evt(cscpc_env, conidx, CSCPC_CTNL_PT_CFG_WR_OP_CODE, status); + } + } + else + { + // No connection + cscpc_send_no_conn_cmp_evt(dest_id, src_id, CSCPC_CTNL_PT_CFG_WR_OP_CODE); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CSCPC_TIMEOUT_TIMER_IND message. This message is + * received when the peer device doesn't send a SC Control Point indication within 30s + * after reception of the write response. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cscpc_timeout_timer_ind_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cscpc_env_tag *cscpc_env = PRF_ENV_GET(CSCPC, cscpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (cscpc_env != NULL) + { + ASSERT_ERR(cscpc_env->env[conidx]->operation != NULL); + ASSERT_ERR(((struct cscpc_cmd *)cscpc_env->env[conidx]->operation)->operation == CSCPC_CTNL_PT_CFG_IND_OP_CODE); + + // Send the complete event message + cscpc_send_cmp_evt(cscpc_env, conidx, CSCPC_CTNL_PT_CFG_WR_OP_CODE, PRF_ERR_PROC_TIMEOUT); + } + // else drop the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cscpc_env_tag *cscpc_env = PRF_ENV_GET(CSCPC, cscpc); + // Status + uint8_t status; + + if (cscpc_env != NULL) + { + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if (state == CSCPC_DISCOVERING) + { + status = param->status; + + if ((status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || + (status == ATT_ERR_NO_ERROR)) + { + // Discovery + // check characteristic validity + if(cscpc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(CSCP_CSCS_CHAR_MAX, + cscpc_env->env[conidx]->cscs.chars, + cscpc_cscs_char); + } + // too much services + else if (cscpc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if (status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(CSCPC_DESC_MAX, + cscpc_env->env[conidx]->cscs.descs, + cscpc_cscs_char_desc, + cscpc_env->env[conidx]->cscs.chars); + } + } + + cscpc_enable_rsp_send(cscpc_env, conidx, status); + } + + else if (state == CSCPC_BUSY) + { + switch (param->operation) + { + case GATTC_READ: + { + // Send the complete event status + cscpc_send_cmp_evt(cscpc_env, conidx, CSCPC_READ_OP_CODE, param->status); + } break; + + case GATTC_WRITE: + case GATTC_WRITE_NO_RESPONSE: + { + uint8_t operation = ((struct cscpc_cmd *)cscpc_env->env[conidx]->operation)->operation; + + if (operation == CSCPC_CFG_NTF_IND_OP_CODE) + { + // Send the complete event status + cscpc_send_cmp_evt(cscpc_env, conidx, operation, param->status); + } + + else if (operation == CSCPC_CTNL_PT_CFG_WR_OP_CODE) + { + if (param->status == GAP_ERR_NO_ERROR) + { + // Start Timeout Procedure + ke_timer_set(CSCPC_TIMEOUT_TIMER_IND, dest_id, ATT_TRANS_RTX); + + // Wait for the response indication + ((struct cscpc_cmd *)cscpc_env->env[conidx]->operation)->operation = CSCPC_CTNL_PT_CFG_IND_OP_CODE; + } + else + { + // Send the complete event status + cscpc_send_cmp_evt(cscpc_env, conidx, operation, param->status); + } + } + } break; + + case GATTC_REGISTER: + case GATTC_UNREGISTER: + { + // Do nothing + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cscpc_env_tag *cscpc_env = PRF_ENV_GET(CSCPC, cscpc); + + if (ke_state_get(dest_id) == CSCPC_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + ASSERT_INFO(cscpc_env != NULL, dest_id, src_id); + ASSERT_INFO(cscpc_env->env[conidx] != NULL, dest_id, src_id); + + // Send the read value to the HL + struct cscpc_value_ind *ind = KE_MSG_ALLOC(CSCPC_VALUE_IND, + prf_dst_task_get(&(cscpc_env->prf_env), conidx), + dest_id, + cscpc_value_ind); + + + switch (((struct cscpc_read_cmd *)cscpc_env->env[conidx]->operation)->read_code) + { + // Read CSC Feature Characteristic value + case (CSCPC_RD_CSC_FEAT): + { + ind->value.sensor_feat = co_read16p(param->value); + + // Mask the reserved bits +// ind->value.sensor_feat &= CSCP_FEAT_ALL_SUPP; + } break; + + // Read Sensor Location Characteristic value + case (CSCPC_RD_SENSOR_LOC): + { + ind->value.sensor_loc = param->value[0]; + } break; + + // Read Client Characteristic Configuration Descriptor value + case (CSCPC_RD_WR_CSC_MEAS_CFG): + case (CSCPC_RD_WR_SC_CTNL_PT_CFG): + { + co_write16p(&ind->value.ntf_cfg, param->value[0]); + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + + ind->att_code = ((struct cscpc_read_cmd *)cscpc_env->env[conidx]->operation)->read_code; + + // Send the message to the application + ke_msg_send(ind); + } + // else drop the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct cscpc_env_tag *cscpc_env = PRF_ENV_GET(CSCPC, cscpc); + + if (cscpc_env != NULL) + { + switch (param->type) + { + case (GATTC_NOTIFY): + { + // Offset + uint8_t offset = CSCP_CSC_MEAS_MIN_LEN; + + // CSC Measurement value has been received + struct cscpc_value_ind *ind = KE_MSG_ALLOC(CSCPC_VALUE_IND, + prf_dst_task_get(&(cscpc_env->prf_env), conidx), + prf_src_task_get(&(cscpc_env->prf_env), conidx), + cscpc_value_ind); + // Attribute code + ind->att_code = CSCPC_NTF_CSC_MEAS; + + /*---------------------------------------------------- + * Unpack Measurement -------------------------------- + *----------------------------------------------------*/ + + // Flags + ind->value.csc_meas.flags = param->value[0]; + + // Cumulative Wheel Revolutions + // Last Wheel Event Time + if (param->value[0] & CSCP_MEAS_WHEEL_REV_DATA_PRESENT) + { + // Cumulative Wheel Revolutions + ind->value.csc_meas.cumul_wheel_rev = co_read32p(¶m->value[offset]); + offset += 4; + + // Last Wheel Event Time + ind->value.csc_meas.last_wheel_evt_time = co_read16p(¶m->value[offset]); + offset += 2; + } + + // Cumulative Crank Revolutions + // Last Crank Event Time + if (param->value[0] & CSCP_MEAS_CRANK_REV_DATA_PRESENT) + { + // Cumulative Crank Revolutions + ind->value.csc_meas.cumul_crank_rev = co_read16p(¶m->value[offset]); + offset += 2; + + // Last Crank Event Time + ind->value.csc_meas.last_crank_evt_time = co_read16p(¶m->value[offset]); + } + + ke_msg_send(ind); + } break; + + case (GATTC_INDICATE): + { + // confirm that indication has been correctly received + struct gattc_event_cfm * cfm = KE_MSG_ALLOC(GATTC_EVENT_CFM, src_id, dest_id, gattc_event_cfm); + cfm->handle = param->handle; + ke_msg_send(cfm); + + // Check if we were waiting for the indication + if (cscpc_env->env[conidx]->operation != NULL) + { + if (((struct cscpc_cmd *)cscpc_env->env[conidx]->operation)->operation == CSCPC_CTNL_PT_CFG_IND_OP_CODE) + { + // Stop the procedure timeout timer + ke_timer_clear(CSCPC_TIMEOUT_TIMER_IND, dest_id); + + // CSC Measurement value has been received + struct cscpc_ctnl_pt_rsp *ind = KE_MSG_ALLOC(CSCPC_CTNL_PT_RSP, + prf_dst_task_get(&(cscpc_env->prf_env), conidx), + prf_src_task_get(&(cscpc_env->prf_env), conidx), + cscpc_ctnl_pt_rsp); + + // Requested operation code + ind->ctnl_pt_rsp.req_op_code = param->value[1]; + // Response value + ind->ctnl_pt_rsp.resp_value = param->value[2]; + + // Get the list of supported sensor locations if needed + if ((ind->ctnl_pt_rsp.req_op_code == CSCP_CTNL_PT_OP_REQ_SUPP_LOC) && + (ind->ctnl_pt_rsp.resp_value == CSCP_CTNL_PT_RESP_SUCCESS) && + (param->length > 3)) + { + // Get the number of supported locations that have been received + uint8_t nb_supp_loc = (param->length - 3); + // Counter + uint8_t counter; + // Location + uint8_t loc; + + for (counter = 0; counter < nb_supp_loc; counter++) + { + loc = param->value[counter + 3]; + + // Check if valid + if (loc < CSCP_LOC_MAX) + { + ind->ctnl_pt_rsp.supp_loc |= (1 << loc); + } + } + } + + // Send the message + ke_msg_send(ind); + + // Send the complete event message + cscpc_send_cmp_evt(cscpc_env, conidx, CSCPC_CTNL_PT_CFG_WR_OP_CODE, GAP_ERR_NO_ERROR); + } + // else drop the message + } + // else drop the message + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(cscpc) +{ + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {CSCPC_ENABLE_REQ, (ke_msg_func_t)cscpc_enable_req_handler}, + {CSCPC_READ_CMD, (ke_msg_func_t)cscpc_read_cmd_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {CSCPC_CFG_NTFIND_CMD, (ke_msg_func_t)cscpc_cfg_ntfind_cmd_handler}, + {CSCPC_CTNL_PT_CFG_REQ, (ke_msg_func_t)cscpc_ctnl_pt_cfg_req_handler}, + {CSCPC_TIMEOUT_TIMER_IND, (ke_msg_func_t)cscpc_timeout_timer_ind_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_EVENT_REQ_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void cscpc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct cscpc_env_tag *cscpc_env = PRF_ENV_GET(CSCPC, cscpc); + + task_desc->msg_handler_tab = cscpc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(cscpc_msg_handler_tab); + task_desc->state = cscpc_env->state; + task_desc->idx_max = CSCPC_IDX_MAX; +} + +#endif //(BLE_CSC_COLLECTOR) + +/// @} CSCPCTASK diff --git a/services/ble_profiles/cscp/cscps/api/cscps_task.h b/services/ble_profiles/cscp/cscps/api/cscps_task.h new file mode 100644 index 0000000..0b37abd --- /dev/null +++ b/services/ble_profiles/cscp/cscps/api/cscps_task.h @@ -0,0 +1,209 @@ +#ifndef _CSCPS_TASK_H_ +#define _CSCPS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup CSCPSTASK Task + * @ingroup CSCPS + * @brief Cycling Speed and Cadence Profile Task. + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "cscp_common.h" +#include +#include "rwip_task.h" // Task definitions + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Messages for Cycling Speed and Cadence Profile Sensor +enum cscps_msg_id +{ + /// Enable the CSCP Sensor task for a connection + CSCPS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_CSCPS), + /// Enable the CSCP Sensor task for a connection + CSCPS_ENABLE_RSP, + + /// Send a CSC Measurement to the peer device (Notification) + CSCPS_NTF_CSC_MEAS_REQ, + /// Inform that CSC Measurement sent to peer devices. + CSCPS_NTF_CSC_MEAS_RSP, + + /// Indicate that the SC Control Point characteristic value has been written + CSCPS_SC_CTNL_PT_REQ_IND, + /// Application response after receiving a CSCPS_SC_CTNL_PT_REQ_IND message + CSCPS_SC_CTNL_PT_CFM, + + /// Indicate a new NTF/IND configuration to the application + CSCPS_CFG_NTFIND_IND, + + /// Send a complete event status to the application + CSCPS_CMP_EVT, +}; + +/// Operation Code used in the profile state machine +enum cscps_op_code +{ + /// Reserved Operation Code + CSCPS_RESERVED_OP_CODE = 0x00, + + /// Send CSC Measurement Operation Code + CSCPS_SEND_CSC_MEAS_OP_CODE, + + /** + * SC Control Point Operation + */ + + /// Set Cumulative Value Operation Code + CSCPS_CTNL_PT_CUMUL_VAL_OP_CODE, + /// Update Sensor Location Operation Code + CSCPS_CTNL_PT_UPD_LOC_OP_CODE, + /// Request Supported Sensor Locations Operation Code + CSCPS_CTNL_PT_SUPP_LOC_OP_CODE, + /// Error Indication Sent Operation Code + CSCPS_CTNL_ERR_IND_OP_CODE, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Parameters of the initialization function +struct cscps_db_cfg +{ + /** + * CSC Feature Value - Not supposed to be modified during the lifetime of the device + * This value is used to decide if the SC Control Point Characteristic is part of the + * Cycling Speed and Cadence service. + */ + uint16_t csc_feature; + /** + * Indicate if the Sensor Location characteristic is supported. Note that if the Multiple + * Sensor Location feature is set has supported in the csc_feature parameter, the + * characteristic will be added (mandatory). + */ + uint8_t sensor_loc_supp; + /// Sensor location + uint8_t sensor_loc; + /// Wheel revolution + uint32_t wheel_rev; +}; + +/// Parameters of the @ref CSCPS_ENABLE_REQ message +struct cscps_enable_req +{ + /// Connection index + uint8_t conidx; + /// Stored CSC Measurement Char. Client Characteristic Configuration + uint16_t csc_meas_ntf_cfg; + /// Stored SC Control Point Char. Client Characteristic Configuration + uint16_t sc_ctnl_pt_ntf_cfg; +}; + +/// Parameters of the @ref CSCPS_ENABLE_RSP message +struct cscps_enable_rsp +{ + /// Connection index + uint8_t conidx; + /// Status + uint8_t status; +}; + +/// Parameters of the @ref CSCPS_NTF_CSC_MEAS_REQ message +struct cscps_ntf_csc_meas_req +{ + /// Flags + uint8_t flags; + /// Cumulative Crank Revolution + uint16_t cumul_crank_rev; + /// Last Crank Event Time + uint16_t last_crank_evt_time; + /// Last Wheel Event Time + uint16_t last_wheel_evt_time; + /// Wheel Revolution since the last wheel event time + int16_t wheel_rev; +}; + +/// Parameters of the @ref CSCPS_NTF_CSC_MEAS_RSP message +struct cscps_ntf_csc_meas_rsp +{ + /// Operation Status + uint8_t status; + /// Cummul Wheel revolution value + uint32_t tot_wheel_rev; +}; + + +/// Parameters of the @ref CSCPS_SC_CTNL_PT_REQ_IND message +struct cscps_sc_ctnl_pt_req_ind +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t op_code; + /// Value + union cscps_sc_ctnl_pt_req_ind_value + { + /// Cumulative value + uint32_t cumul_value; + /// Sensor Location + uint8_t sensor_loc; + } value; +}; + +/// Parameters of the @ref CSCPS_SC_CTNL_PT_CFM message +struct cscps_sc_ctnl_pt_cfm +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t op_code; + /// Status + uint8_t status; + /// Value + union cscps_sc_ctnl_pt_cfm_value + { + /// Sensor Location + uint8_t sensor_loc; + /// Supported sensor locations + uint16_t supp_sensor_loc; + /// New Cumulative Wheel revolution Value + uint32_t cumul_wheel_rev; + } value; +}; + +/// Parameters of the @ref CSCPS_CFG_NTFIND_IND message +struct cscps_cfg_ntfind_ind +{ + /// Connection handle + uint8_t conidx; + /// Characteristic Code (CSC Measurement or SC Control Point) + uint8_t char_code; + /// Char. Client Characteristic Configuration + uint16_t ntf_cfg; +}; + +/// Parameters of the @ref CSCPS_CMP_EVT message +struct cscps_cmp_evt +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t operation; + /// Operation Status + uint8_t status; +}; + +/// @} CSCPSTASK + +#endif //(_CSCPS_TASK_H_) diff --git a/services/ble_profiles/cscp/cscps/src/cscps.c b/services/ble_profiles/cscp/cscps/src/cscps.c new file mode 100644 index 0000000..20e2721 --- /dev/null +++ b/services/ble_profiles/cscp/cscps/src/cscps.c @@ -0,0 +1,357 @@ +/** + **************************************************************************************** + * @addtogroup CSCPS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_CSC_SENSOR) +#include "cscp_common.h" + +#include "gap.h" +#include "gattc_task.h" +#include "cscps.h" +#include "cscps_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Full CSCPS Database Description - Used to add attributes into the database +static const struct attm_desc cscps_att_db[CSCS_IDX_NB] = +{ + // Cycling Speed and Cadence Service Declaration + [CSCS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // CSC Measurement Characteristic Declaration + [CSCS_IDX_CSC_MEAS_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // CSC Measurement Characteristic Value + [CSCS_IDX_CSC_MEAS_VAL] = {ATT_CHAR_CSC_MEAS, PERM(NTF, ENABLE), PERM(RI, ENABLE), CSCP_CSC_MEAS_MAX_LEN}, + // CSC Measurement Characteristic - Client Characteristic Configuration Descriptor + [CSCS_IDX_CSC_MEAS_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // CSC Feature Characteristic Declaration + [CSCS_IDX_CSC_FEAT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // CSC Feature Characteristic Value + [CSCS_IDX_CSC_FEAT_VAL] = {ATT_CHAR_CSC_FEAT, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(uint16_t)}, + + // Sensor Location Characteristic Declaration + [CSCS_IDX_SENSOR_LOC_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Sensor Location Characteristic Value + [CSCS_IDX_SENSOR_LOC_VAL] = {ATT_CHAR_SENSOR_LOC, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, + + // SC Control Point Characteristic Declaration + [CSCS_IDX_SC_CTNL_PT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), CSCS_IDX_SC_CTNL_PT_VAL, 0}, + // SC Control Point Characteristic Value - The response has the maximal length + [CSCS_IDX_SC_CTNL_PT_VAL] = {ATT_CHAR_SC_CNTL_PT, PERM(IND, ENABLE) | PERM(WRITE_REQ, ENABLE), + PERM(RI, ENABLE), CSCP_SC_CNTL_PT_RSP_MAX_LEN}, + // SC Control Point Characteristic - Client Characteristic Configuration Descriptor + [CSCS_IDX_SC_CTNL_PT_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the CSCPS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t cscps_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct cscps_db_cfg* param) +{ + //------------------ create the attribute database for the profile ------------------- + // Service content flag + uint32_t cfg_flag= CSCPS_MANDATORY_MASK; + // DB Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + /* + * Check if the Sensor Location characteristic shall be added. + * Mandatory if the Multiple Sensor Location feature is supported, otherwise optional. + */ + if ((param->sensor_loc_supp == CSCPS_SENSOR_LOC_SUPP) || + (CSCPS_IS_FEATURE_SUPPORTED(param->csc_feature, CSCP_FEAT_MULT_SENSOR_LOC_SUPP))) + { + cfg_flag |= CSCPS_SENSOR_LOC_MASK; + } + + /* + * Check if the SC Control Point characteristic shall be added + * Mandatory if at least one SC Control Point procedure is supported, otherwise excluded. + */ + if (CSCPS_IS_FEATURE_SUPPORTED(param->csc_feature, CSCP_FEAT_WHEEL_REV_DATA_SUPP) || + CSCPS_IS_FEATURE_SUPPORTED(param->csc_feature, CSCP_FEAT_MULT_SENSOR_LOC_SUPP)) + { + cfg_flag |= CSCPS_SC_CTNL_PT_MASK; + } + + // Add service in the database + status = attm_svc_create_db(start_hdl, ATT_SVC_CYCLING_SPEED_CADENCE, (uint8_t *)&cfg_flag, + CSCS_IDX_NB, NULL, env->task, &cscps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, DISABLE)); + + // Check if an error has occured + if (status == ATT_ERR_NO_ERROR) + { + // Allocate CSCPS required environment variable + struct cscps_env_tag* cscps_env = + (struct cscps_env_tag* ) ke_malloc(sizeof(struct cscps_env_tag), KE_MEM_ATT_DB); + + // Initialize CSCPS environment + + env->env = (prf_env_t*) cscps_env; + cscps_env->shdl = *start_hdl; + cscps_env->prfl_cfg = cfg_flag; + cscps_env->features = param->csc_feature; + cscps_env->operation = CSCPS_RESERVED_OP_CODE; + + if (CSCPS_IS_FEATURE_SUPPORTED(cscps_env->prfl_cfg, CSCPS_SENSOR_LOC_MASK)) + { + cscps_env->sensor_loc = (param->sensor_loc >= CSCP_LOC_MAX) ? + CSCP_LOC_OTHER : param->sensor_loc; + } + + cscps_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Mono Instantiated task + cscps_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + // initialize environment variable + env->id = TASK_ID_CSCPS; + cscps_task_init(&(env->desc)); + + // Store the provided cumulative wheel revolution value + cscps_env->tot_wheel_rev = param->wheel_rev; + cscps_env->ntf = NULL; + + memset(cscps_env->prfl_ntf_ind_cfg, 0, BLE_CONNECTION_MAX); + + // If we are here, database has been fulfilled with success, go to idle state + ke_state_set(env->task, CSCPS_IDLE); + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the CSCPS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void cscps_destroy(struct prf_task_env* env) +{ + struct cscps_env_tag* cscps_env = (struct cscps_env_tag*) env->env; + + // cleanup environment variable for each task instances + if(cscps_env->ntf != NULL) + { + ke_free(cscps_env->ntf); + } + + // free profile environment variables + env->env = NULL; + ke_free(cscps_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void cscps_create(struct prf_task_env* env, uint8_t conidx) +{ + struct cscps_env_tag* cscps_env = (struct cscps_env_tag*) env->env; + cscps_env->prfl_ntf_ind_cfg[conidx] = 0; +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void cscps_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct cscps_env_tag* cscps_env = (struct cscps_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + cscps_env->prfl_ntf_ind_cfg[conidx] = 0; +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// CSCPS Task interface required by profile manager +const struct prf_task_cbs cscps_itf = +{ + (prf_init_fnct) cscps_init, + cscps_destroy, + cscps_create, + cscps_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* cscps_prf_itf_get(void) +{ + return &cscps_itf; +} + +void cscps_send_cmp_evt(uint8_t conidx, uint8_t src_id, uint8_t dest_id, uint8_t operation, uint8_t status) +{ + // Get the address of the environment + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + + // Go back to the Connected state if the state is busy + if (ke_state_get(src_id) == CSCPS_BUSY) + { + ke_state_set(src_id, CSCPS_IDLE); + } + + // Set the operation code + cscps_env->operation = CSCPS_RESERVED_OP_CODE; + + // Send the message + struct cscps_cmp_evt *evt = KE_MSG_ALLOC(CSCPS_CMP_EVT, + dest_id, src_id, + cscps_cmp_evt); + + evt->conidx = conidx; + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + + +void cscps_exe_operation(void) +{ + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + + ASSERT_ERR(cscps_env->ntf != NULL); + + bool finished = true; + + while(cscps_env->ntf->cursor < BLE_CONNECTION_MAX) + { + // Check if notifications are enabled + if(CSCPS_IS_NTFIND_ENABLED(cscps_env->ntf->cursor, CSCP_PRF_CFG_FLAG_CSC_MEAS_NTF)) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, cscps_env->ntf->cursor), + prf_src_task_get(&(cscps_env->prf_env), 0), + gattc_send_evt_cmd, cscps_env->ntf->length); + + // Fill in the parameter structure + meas_val->operation = GATTC_NOTIFY; + meas_val->handle = CSCPS_HANDLE(CSCS_IDX_CSC_MEAS_VAL); + meas_val->length = cscps_env->ntf->length; + memcpy(meas_val->value, cscps_env->ntf->value, cscps_env->ntf->length); + + // Send the event + ke_msg_send(meas_val); + + finished = false; + cscps_env->ntf->cursor++; + break; + } + + cscps_env->ntf->cursor++; + } + + // check if operation is finished + if(finished) + { + // Inform the application that a procedure has been completed + struct cscps_ntf_csc_meas_rsp *rsp = KE_MSG_ALLOC(CSCPS_NTF_CSC_MEAS_RSP, + prf_dst_task_get(&(cscps_env->prf_env), 0), + prf_src_task_get(&(cscps_env->prf_env), 0), + cscps_ntf_csc_meas_rsp); + + rsp->status = GAP_ERR_NO_ERROR; + rsp->tot_wheel_rev = cscps_env->tot_wheel_rev; + ke_msg_send(rsp); + + // free operation + ke_free(cscps_env->ntf); + cscps_env->ntf = NULL; + cscps_env->operation = CSCPS_RESERVED_OP_CODE; + + ke_state_set(prf_src_task_get(&(cscps_env->prf_env), 0), CSCPS_IDLE); + } +} + +void cscps_send_rsp_ind(uint8_t conidx, uint8_t req_op_code, uint8_t status) +{ + // Get the address of the environment + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ctl_pt_rsp = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), + prf_src_task_get(&cscps_env->prf_env, conidx), + gattc_send_evt_cmd, CSCP_SC_CNTL_PT_RSP_MIN_LEN); + + // Fill in the parameter structure + ctl_pt_rsp->operation = GATTC_INDICATE; + ctl_pt_rsp->handle = CSCPS_HANDLE(CSCS_IDX_SC_CTNL_PT_VAL); + // Pack Control Point confirmation + ctl_pt_rsp->length = CSCP_SC_CNTL_PT_RSP_MIN_LEN; + // Response Code + ctl_pt_rsp->value[0] = CSCP_CTNL_PT_RSP_CODE; + // Request Operation Code + ctl_pt_rsp->value[1] = req_op_code; + // Response value + ctl_pt_rsp->value[2] = status; + + // Send the event + ke_msg_send(ctl_pt_rsp); +} + +#endif //(BLE_CSC_SENSOR) + +/// @} CSCPS diff --git a/services/ble_profiles/cscp/cscps/src/cscps.h b/services/ble_profiles/cscp/cscps/src/cscps.h new file mode 100644 index 0000000..fe6c19d --- /dev/null +++ b/services/ble_profiles/cscp/cscps/src/cscps.h @@ -0,0 +1,237 @@ +#ifndef _CSCPS_H_ +#define _CSCPS_H_ + +/** + **************************************************************************************** + * @addtogroup CSCPS Cycling Speed and Cadence Profile Sensor + * @ingroup CSCP + * @brief Cycling Speed and Cadence Profile Sensor + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_CSC_SENSOR) +#include "cscp_common.h" + +#include "prf_types.h" +#include "prf.h" +#include "cscps_task.h" +#include "attm.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of Cycling Speed and Cadence Profile Sensor role task instances +#define CSCPS_IDX_MAX (1) + +/******************************************** + ******* CSCPS Configuration Flag Masks ****** + ********************************************/ + +/// Mandatory Attributes (CSC Measurement + CSC Feature) +#define CSCPS_MANDATORY_MASK (0x003F) +/// Sensor Location Attributes +#define CSCPS_SENSOR_LOC_MASK (0x00C0) +/// SC Control Point Attributes +#define CSCPS_SC_CTNL_PT_MASK (0x0700) + +/* + * MACROS + **************************************************************************************** + */ + +#define CSCPS_IS_FEATURE_SUPPORTED(features, flag) ((features & flag) == flag) + +#define CSCPS_IS_PRESENT(features, flag) ((features & flag) == flag) + +#define CSCPS_ENABLE_NTFIND(conidx, ccc_flag) (cscps_env->prfl_ntf_ind_cfg[conidx] |= ccc_flag) + +#define CSCPS_DISABLE_NTFIND(conidx, ccc_flag) (cscps_env->prfl_ntf_ind_cfg[conidx] &= ~ccc_flag) + +#define CSCPS_IS_NTFIND_ENABLED(conidx, ccc_flag) ((cscps_env->prfl_ntf_ind_cfg[conidx] & ccc_flag) == ccc_flag) + +#define CSCPS_HANDLE(idx) \ + (cscps_env->shdl + (idx) - \ + ((!(CSCPS_IS_FEATURE_SUPPORTED(cscps_env->prfl_cfg, CSCPS_SENSOR_LOC_MASK)) && \ + ((idx) > CSCS_IDX_SENSOR_LOC_CHAR))? (1) : (0))) + +// Get database attribute index + #define CSCPS_IDX(hdl) \ + ((hdl - cscps_env->shdl) + \ + ((!(CSCPS_IS_FEATURE_SUPPORTED(cscps_env->prfl_cfg, CSCPS_SENSOR_LOC_MASK)) && \ + ((hdl - cscps_env->shdl) > CSCS_IDX_SENSOR_LOC_CHAR)) ? (1) : (0))) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the CSCPS task +enum cscps_state +{ + /// Idle state + CSCPS_IDLE, + /// Busy state + CSCPS_BUSY, + + /// Number of defined states. + CSCPS_STATE_MAX +}; + +/// Cycling Speed and Cadence Service - Attribute List +enum cscps_cscs_att_list +{ + /// Cycling Speed and Cadence Service + CSCS_IDX_SVC, + /// CSC Measurement + CSCS_IDX_CSC_MEAS_CHAR, + CSCS_IDX_CSC_MEAS_VAL, + CSCS_IDX_CSC_MEAS_NTF_CFG, + /// CSC Feature + CSCS_IDX_CSC_FEAT_CHAR, + CSCS_IDX_CSC_FEAT_VAL, + /// Sensor Location + CSCS_IDX_SENSOR_LOC_CHAR, + CSCS_IDX_SENSOR_LOC_VAL, + /// SC Control Point + CSCS_IDX_SC_CTNL_PT_CHAR, + CSCS_IDX_SC_CTNL_PT_VAL, + CSCS_IDX_SC_CTNL_PT_NTF_CFG, + + /// Number of attributes + CSCS_IDX_NB, +}; + +/// Profile Configuration Additional Flags () +enum cscps_prf_cfg_flag +{ + /// CSC Measurement - Client Char. Cfg + CSCP_PRF_CFG_FLAG_CSC_MEAS_NTF = (CSCP_FEAT_MULT_SENSOR_LOC_SUPP << 1), + /// SC Control Point - Client Char. Cfg + CSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND = (CSCP_PRF_CFG_FLAG_CSC_MEAS_NTF << 1), + + /// Bonded data used + CSCP_PRF_CFG_PERFORMED_OK = 0x80 +}; + +/// Sensor Location Supported Flag +enum cscps_sensor_loc_supp +{ + /// Sensor Location Char. is not supported + CSCPS_SENSOR_LOC_NOT_SUPP, + /// Sensor Location Char. is supported + CSCPS_SENSOR_LOC_SUPP, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// ongoing notification information +struct cscps_ntf +{ + /// Cursor on connection + uint8_t cursor; + /// Packed notification/indication data size + uint8_t length; + /// Packed notification/indication data + uint8_t value[CSCP_CSC_MEAS_MAX_LEN]; +}; + +/// Cycling Speed and Cadence Profile Sensor environment variable +struct cscps_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Notification data + struct cscps_ntf* ntf; + /// Wheel revolution + uint32_t tot_wheel_rev; + + /// Cycling Speed and Cadence Service Start Handle + uint16_t shdl; + /// Features configuration + uint16_t features; + /// profile configuration + uint16_t prfl_cfg; + + /// Operation + uint8_t operation; + /// Sensor location + uint8_t sensor_loc; + + /// Environment variable pointer for each connections + uint8_t prfl_ntf_ind_cfg[BLE_CONNECTION_MAX]; + + /// State of different task instances + ke_state_t state[CSCPS_IDX_MAX]; +}; + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve CSCP service profile interface + * + * @return CSCP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* cscps_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send a CSCPS_CMP_EVT message to the application. + **************************************************************************************** + */ +void cscps_send_cmp_evt(uint8_t conidx, uint8_t src_id, uint8_t dest_id, + uint8_t operation, uint8_t status); + + +/** + **************************************************************************************** + * @brief This function fully manage event to trigg to peer(s) device(s) according + * to on-going operation requested by application + **************************************************************************************** + */ +void cscps_exe_operation(void); + +/** + **************************************************************************************** + * @brief This function sends control point indication error + **************************************************************************************** + */ +void cscps_send_rsp_ind(uint8_t conidx, uint8_t req_op_code, uint8_t status); + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void cscps_task_init(struct ke_task_desc *task_desc); + +#endif //(BLE_CSC_SENSOR) + +/// @} CSCPS + +#endif //(_CSCPS_H_) diff --git a/services/ble_profiles/cscp/cscps/src/cscps_task.c b/services/ble_profiles/cscp/cscps/src/cscps_task.c new file mode 100644 index 0000000..6ec34e8 --- /dev/null +++ b/services/ble_profiles/cscp/cscps/src/cscps_task.c @@ -0,0 +1,831 @@ +/** + **************************************************************************************** + * @addtogroup CSCPSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_CSC_SENSOR) + +#include "gapc.h" +#include "gattc_task.h" +#include "cscps.h" +#include "cscps_task.h" +#include "prf_utils.h" +#include "co_math.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CSCPS_ENABLE_REQ message. + * @param[in] msgid Id of the message received + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cscps_enable_req_handler(ke_msg_id_t const msgid, + struct cscps_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(ke_state_get(dest_id) == CSCPS_IDLE) + { + status = GAP_ERR_NO_ERROR; + + if (!CSCPS_IS_PRESENT(cscps_env->prfl_ntf_ind_cfg[param->conidx], CSCP_PRF_CFG_PERFORMED_OK)) + { + // Check the provided value + if (param->csc_meas_ntf_cfg == PRF_CLI_START_NTF) + { + // Store the status + CSCPS_ENABLE_NTFIND(param->conidx, CSCP_PRF_CFG_FLAG_CSC_MEAS_NTF); + } + + if (CSCPS_IS_FEATURE_SUPPORTED(cscps_env->prfl_cfg, CSCPS_SC_CTNL_PT_MASK)) + { + // Check the provided value + if (param->sc_ctnl_pt_ntf_cfg == PRF_CLI_START_IND) + { + // Store the status + CSCPS_ENABLE_NTFIND(param->conidx, CSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND); + } + } + // Enable Bonded Data + CSCPS_ENABLE_NTFIND(param->conidx, CSCP_PRF_CFG_PERFORMED_OK); + } + } + + // send completed information to APP task that contains error status + struct cscps_enable_rsp *cmp_evt = KE_MSG_ALLOC(CSCPS_ENABLE_RSP, src_id, dest_id, cscps_enable_rsp); + cmp_evt->status = status; + cmp_evt->conidx = param->conidx; + ke_msg_send(cmp_evt); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == CSCPS_IDLE) + { + // Get the address of the environment + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t att_idx = CSCPS_IDX(param->handle); + + // Send data to peer device + struct gattc_read_cfm* cfm = NULL; + + uint8_t status = ATT_ERR_NO_ERROR; + + switch(att_idx) + { + case CSCS_IDX_CSC_MEAS_NTF_CFG: + { + // Fill data + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->length = sizeof(uint16_t); + co_write16p(cfm->value, (cscps_env->prfl_ntf_ind_cfg[conidx] & CSCP_PRF_CFG_FLAG_CSC_MEAS_NTF) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + } break; + + case CSCS_IDX_CSC_FEAT_VAL: + { + // Fill data + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->length = sizeof(uint16_t); + co_write16p(cfm->value, cscps_env->features); + } break; + + case CSCS_IDX_SENSOR_LOC_VAL: + { + // Fill data + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint8_t)); + cfm->length = sizeof(uint8_t); + cfm->value[0] = cscps_env->sensor_loc; + } break; + + case CSCS_IDX_SC_CTNL_PT_NTF_CFG: + { + // Fill data + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->length = sizeof(uint16_t); + co_write16p(cfm->value, (cscps_env->prfl_ntf_ind_cfg[conidx] & CSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND) + ? PRF_CLI_START_IND : PRF_CLI_STOP_NTFIND); + } break; + + default: + { + cfm = KE_MSG_ALLOC(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm); + cfm->length = 0; + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } break; + } + + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == CSCPS_IDLE) + { + // Get the address of the environment + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + uint8_t att_idx = CSCPS_IDX(param->handle); + struct gattc_att_info_cfm * cfm; + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + // check if it's a client configuration char + if((att_idx == CSCS_IDX_CSC_MEAS_NTF_CFG) + || (att_idx == CSCS_IDX_SC_CTNL_PT_NTF_CFG)) + { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } + else if (att_idx == CSCS_IDX_SC_CTNL_PT_VAL) + { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } + // not expected request + else + { + cfm->length = 0; + cfm->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CSCPS_NTF_CSC_MEAS_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cscps_ntf_csc_meas_req_handler(ke_msg_id_t const msgid, + struct cscps_ntf_csc_meas_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + // State shall be Connected or Busy + if (ke_state_get(dest_id) == CSCPS_IDLE) + { + // Get the address of the environment + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + + // allocate and prepare data to notify + cscps_env->ntf = (struct cscps_ntf*) ke_malloc(sizeof(struct cscps_ntf), KE_MEM_KE_MSG); + + // pack measured value in database + cscps_env->ntf->length = CSCP_CSC_MEAS_MIN_LEN; + + // Check the provided flags value + if (!CSCPS_IS_FEATURE_SUPPORTED(cscps_env->prfl_cfg, CSCP_FEAT_WHEEL_REV_DATA_SUPP) && + CSCPS_IS_PRESENT(param->flags, CSCP_MEAS_WHEEL_REV_DATA_PRESENT)) + { + // Force Wheel Revolution Data to No (Not supported) + param->flags &= ~CSCP_MEAS_WHEEL_REV_DATA_PRESENT; + } + + if (!CSCPS_IS_FEATURE_SUPPORTED(cscps_env->prfl_cfg, CSCP_FEAT_CRANK_REV_DATA_SUPP) && + CSCPS_IS_PRESENT(param->flags, CSCP_MEAS_CRANK_REV_DATA_PRESENT)) + { + // Force Crank Revolution Data Present to No (Not supported) + param->flags &= ~CSCP_MEAS_CRANK_REV_DATA_PRESENT; + } + + // Force the unused bits of the flag value to 0 + cscps_env->ntf->value[0] = param->flags & CSCP_MEAS_ALL_PRESENT; + + // Cumulative Wheel Resolutions + // Last Wheel Event Time + if (CSCPS_IS_PRESENT(param->flags, CSCP_MEAS_WHEEL_REV_DATA_PRESENT)) + { + // Update the cumulative wheel revolutions value stored in the environment + if (param->wheel_rev < 0) + { + // The value shall not decrement below zero + if (co_abs(param->wheel_rev) > cscps_env->tot_wheel_rev) + { + cscps_env->tot_wheel_rev = 0; + } + else + { + cscps_env->tot_wheel_rev += param->wheel_rev; + } + } + else + { + cscps_env->tot_wheel_rev += param->wheel_rev; + } + + // Cumulative Wheel Resolutions + co_write32p(&cscps_env->ntf->value[cscps_env->ntf->length], cscps_env->tot_wheel_rev); + cscps_env->ntf->length += 4; + + // Last Wheel Event Time + co_write16p(&cscps_env->ntf->value[cscps_env->ntf->length], param->last_wheel_evt_time); + cscps_env->ntf->length += 2; + } + + // Cumulative Crank Revolutions + // Last Crank Event Time + if (CSCPS_IS_PRESENT(param->flags, CSCP_MEAS_CRANK_REV_DATA_PRESENT)) + { + // Cumulative Crank Revolutions + co_write32p(&cscps_env->ntf->value[cscps_env->ntf->length], param->cumul_crank_rev); + cscps_env->ntf->length += 2; + + // Last Crank Event Time + co_write16p(&cscps_env->ntf->value[cscps_env->ntf->length], param->last_crank_evt_time); + cscps_env->ntf->length += 2; + } + + // Configure the environment + cscps_env->operation = CSCPS_SEND_CSC_MEAS_OP_CODE; + cscps_env->ntf->cursor = 0; + + // Go to busy state + ke_state_set(dest_id, CSCPS_BUSY); + + // start operation execution + cscps_exe_operation(); + } + else + { + // Save it for later + msg_status = KE_MSG_SAVED; + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref CSCPS_SC_CTNL_PT_CFM message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int cscps_sc_ctnl_pt_cfm_handler(ke_msg_id_t const msgid, + struct cscps_sc_ctnl_pt_cfm *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + uint8_t conidx = KE_IDX_GET(src_id); + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if (ke_state_get(dest_id) == CSCPS_BUSY) + { + do + { // check if op code valid + if((param->op_code < CSCPS_CTNL_PT_CUMUL_VAL_OP_CODE) + || (param->op_code > CSCPS_CTNL_ERR_IND_OP_CODE)) + { + //Wrong op code + status = PRF_ERR_INVALID_PARAM; + break; + } + + // Check the current operation + if ((cscps_env->operation < CSCPS_CTNL_PT_CUMUL_VAL_OP_CODE) || + (param->op_code != cscps_env->operation)) + { + // The confirmation has been sent without request indication, ignore + status = PRF_ERR_REQ_DISALLOWED; + break; + } + + // The CP Control Point Characteristic must be supported if we are here + if (CSCPS_IS_FEATURE_SUPPORTED(cscps_env->prfl_cfg, CSCPS_SC_CTNL_PT_MASK)) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ctl_pt_rsp = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, param->conidx), dest_id, + gattc_send_evt_cmd, CSCP_SC_CNTL_PT_RSP_MAX_LEN); + + // Fill in the parameter structure + ctl_pt_rsp->operation = GATTC_INDICATE; + ctl_pt_rsp->handle = CSCPS_HANDLE(CSCS_IDX_SC_CTNL_PT_VAL); + // Pack Control Point confirmation + ctl_pt_rsp->length = CSCP_SC_CNTL_PT_RSP_MIN_LEN; + + // Set the operation code (Response Code) + ctl_pt_rsp->value[0] = CSCP_CTNL_PT_RSP_CODE; + // Set the response value + ctl_pt_rsp->value[2] = (param->status > CSCP_CTNL_PT_RESP_FAILED) ? CSCP_CTNL_PT_RESP_FAILED : param->status; + + switch (cscps_env->operation) + { + // Set cumulative value + case (CSCPS_CTNL_PT_CUMUL_VAL_OP_CODE): + { + // Set the request operation code + ctl_pt_rsp->value[1] = CSCP_CTNL_PT_OP_SET_CUMUL_VAL; + + // Store the new value in the environment + cscps_env->tot_wheel_rev = param->value.cumul_wheel_rev; + status = GAP_ERR_NO_ERROR; + } break; + + // Update Sensor Location + case (CSCPS_CTNL_PT_UPD_LOC_OP_CODE): + { + // Set the request operation code + ctl_pt_rsp->value[1] = CSCP_CTNL_PT_OP_UPD_LOC; + + if (param->status == CSCP_CTNL_PT_RESP_SUCCESS) + { + // The CP Control Point Characteristic must be supported if we are here + if (CSCPS_IS_FEATURE_SUPPORTED(cscps_env->prfl_cfg, CSCPS_SENSOR_LOC_MASK)) + { + cscps_env->sensor_loc = param->value.sensor_loc; + status = GAP_ERR_NO_ERROR; + } + } + } break; + + case (CSCPS_CTNL_PT_SUPP_LOC_OP_CODE): + { + // Set the request operation code + ctl_pt_rsp->value[1] = CSCP_CTNL_PT_OP_REQ_SUPP_LOC; + + if (param->status == CSCP_CTNL_PT_RESP_SUCCESS) + { + // Counter + uint8_t counter; + + // Set the list of supported location + for (counter = 0; counter < CSCP_LOC_MAX; counter++) + { + if (((param->value.supp_sensor_loc >> counter) & 0x0001) == 0x0001) + { + ctl_pt_rsp->value[ctl_pt_rsp->length] = counter; + ctl_pt_rsp->length++; + } + } + status = GAP_ERR_NO_ERROR; + } + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + + // Send the event + ke_msg_send(ctl_pt_rsp); + } + } while (0); + + if (status != GAP_ERR_NO_ERROR) + { + // Inform the application that a procedure has been completed + cscps_send_cmp_evt(conidx, + prf_src_task_get(&cscps_env->prf_env, conidx), + prf_dst_task_get(&cscps_env->prf_env, conidx), + cscps_env->operation, param->status); + } + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_WRITE_REQ_IND message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + uint8_t conidx = KE_IDX_GET(src_id); + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + // Check the connection handle + if (cscps_env != NULL) + { + // CSC Measurement Characteristic, Client Characteristic Configuration Descriptor + if (param->handle == (CSCPS_HANDLE(CSCS_IDX_CSC_MEAS_NTF_CFG))) + { + uint16_t ntf_cfg; + // Status + uint8_t status = PRF_ERR_INVALID_PARAM; + + // Get the value + co_write16p(&ntf_cfg, param->value[0]); + + // Check if the value is correct + if (ntf_cfg <= PRF_CLI_START_NTF) + { + status = GAP_ERR_NO_ERROR; + + // Save the new configuration in the environment + if (ntf_cfg == PRF_CLI_STOP_NTFIND) + { + CSCPS_DISABLE_NTFIND(conidx, CSCP_PRF_CFG_FLAG_CSC_MEAS_NTF); + } + else // ntf_cfg == PRF_CLI_START_NTF + { + CSCPS_ENABLE_NTFIND(conidx, CSCP_PRF_CFG_FLAG_CSC_MEAS_NTF); + } + + // Inform the HL about the new configuration + struct cscps_cfg_ntfind_ind *ind = KE_MSG_ALLOC(CSCPS_CFG_NTFIND_IND, + prf_dst_task_get(&cscps_env->prf_env, conidx), + prf_src_task_get(&cscps_env->prf_env, conidx), + cscps_cfg_ntfind_ind); + + ind->char_code = CSCP_CSCS_CSC_MEAS_CHAR; + ind->ntf_cfg = ntf_cfg; + + ke_msg_send(ind); + + // Enable Bonded Data + CSCPS_ENABLE_NTFIND(conidx, CSCP_PRF_CFG_PERFORMED_OK); + } + // else status is PRF_ERR_INVALID_PARAM + + // Send the write response to the peer device + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + } + else // Should be the SC Control Point Characteristic + { + if (CSCPS_IS_FEATURE_SUPPORTED(cscps_env->prfl_cfg, CSCPS_SC_CTNL_PT_MASK)) + { + // SC Control Point, Client Characteristic Configuration Descriptor + if (param->handle == (CSCPS_HANDLE(CSCS_IDX_SC_CTNL_PT_NTF_CFG))) + { + uint16_t ntf_cfg; + // Status + uint8_t status = PRF_ERR_INVALID_PARAM; + + // Get the value + co_write16p(&ntf_cfg, param->value[0]); + + // Check if the value is correct + if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_IND)) + { + status = GAP_ERR_NO_ERROR; + + // Save the new configuration in the environment + if (ntf_cfg == PRF_CLI_STOP_NTFIND) + { + CSCPS_DISABLE_NTFIND(conidx, CSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND); + } + else // ntf_cfg == PRF_CLI_START_IND + { + CSCPS_ENABLE_NTFIND(conidx, CSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND); + } + + // Inform the HL about the new configuration + struct cscps_cfg_ntfind_ind *ind = KE_MSG_ALLOC(CSCPS_CFG_NTFIND_IND, + prf_dst_task_get(&cscps_env->prf_env, conidx), + prf_src_task_get(&cscps_env->prf_env, conidx), + cscps_cfg_ntfind_ind); + + ind->char_code = CSCP_CSCS_SC_CTNL_PT_CHAR; + ind->ntf_cfg = ntf_cfg; + + ke_msg_send(ind); + + // Enable Bonded Data + CSCPS_ENABLE_NTFIND(conidx, CSCP_PRF_CFG_PERFORMED_OK); + } + // else status is PRF_ERR_INVALID_PARAM + + // Send the write response to the peer device + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + } + // SC Control Point Characteristic + else if (param->handle == (CSCPS_HANDLE(CSCS_IDX_SC_CTNL_PT_VAL))) + { + // Write Response Status + uint8_t wr_status = ATT_ERR_NO_ERROR; + // Indication Status + uint8_t ind_status = CSCP_CTNL_PT_RESP_NOT_SUPP; + + do + { + // Check if sending of indications has been enabled + if (!CSCPS_IS_NTFIND_ENABLED(conidx, CSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND)) + { + // CCC improperly configured + wr_status = CSCP_ERROR_CCC_INVALID_PARAM; + ind_status = CSCP_CTNL_PT_RESP_FAILED; + break; + } + + if (cscps_env->operation >= CSCPS_CTNL_PT_CUMUL_VAL_OP_CODE) + { + // A procedure is already in progress + wr_status = CSCP_ERROR_PROC_IN_PROGRESS; + ind_status = CSCP_CTNL_PT_RESP_FAILED; + break; + } + + if (cscps_env->operation == CSCPS_SEND_CSC_MEAS_OP_CODE) + { + // Keep the message until the end of the current procedure + msg_status = KE_MSG_NO_FREE; + break; + } + + // Allocate a request indication message for the application + struct cscps_sc_ctnl_pt_req_ind *req_ind = KE_MSG_ALLOC(CSCPS_SC_CTNL_PT_REQ_IND, + prf_dst_task_get(&cscps_env->prf_env, conidx), + prf_src_task_get(&cscps_env->prf_env, conidx), + cscps_sc_ctnl_pt_req_ind); + + // Operation Code + req_ind->op_code = param->value[0]; + // Connection index + req_ind->conidx = conidx; + + // Operation Code + switch(param->value[0]) + { + // Set Cumulative value + case (CSCP_CTNL_PT_OP_SET_CUMUL_VAL): + { + // Check if the Wheel Revolution Data feature is supported + if (CSCPS_IS_FEATURE_SUPPORTED(cscps_env->features, CSCP_FEAT_WHEEL_REV_DATA_SUPP)) + { + // The request can be handled + ind_status = CSCP_CTNL_PT_RESP_SUCCESS; + cscps_env->operation = CSCPS_CTNL_PT_CUMUL_VAL_OP_CODE; + + // Cumulative value + req_ind->value.cumul_value = co_read32p(¶m->value[1]); + } + } break; + + // Update sensor location + case (CSCP_CTNL_PT_OP_UPD_LOC): + { + // Check if the Multiple Sensor Location feature is supported + if (CSCPS_IS_FEATURE_SUPPORTED(cscps_env->features, CSCP_FEAT_MULT_SENSOR_LOC_SUPP)) + { + // Check the sensor location value + if (param->value[1] < CSCP_LOC_MAX) + { + // The request can be handled + ind_status = CSCP_CTNL_PT_RESP_SUCCESS; + + cscps_env->operation = CSCPS_CTNL_PT_UPD_LOC_OP_CODE; + + // Sensor Location + req_ind->value.sensor_loc = param->value[1]; + } + else + { + // The request can be handled + ind_status = CSCP_CTNL_PT_RESP_INV_PARAM; + } + } + } break; + + // Request supported sensor locations + case (CSCP_CTNL_PT_OP_REQ_SUPP_LOC): + { + // Check if the Multiple Sensor Location feature is supported + if (CSCPS_IS_FEATURE_SUPPORTED(cscps_env->features, CSCP_FEAT_MULT_SENSOR_LOC_SUPP)) + { + // The request can be handled + ind_status = CSCP_CTNL_PT_RESP_SUCCESS; + + cscps_env->operation = CSCPS_CTNL_PT_SUPP_LOC_OP_CODE; + } + + } break; + + default: + { + // Operation Code is invalid, status is already CSCP_CTNL_PT_RESP_NOT_SUPP + } break; + } + + // If no error raised, inform the application about the request + if (ind_status == CSCP_CTNL_PT_RESP_SUCCESS) + { + // Send the request indication to the application + ke_msg_send(req_ind); + // Go to the Busy status + ke_state_set(dest_id, CSCPS_BUSY); + // Align error code + wr_status = GAP_ERR_NO_ERROR; + } + else + { + // Free the allocated message + ke_msg_free(ke_param2msg(req_ind)); + } + } while (0); + + + // Send the write response to the peer device + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = wr_status; + ke_msg_send(cfm); + + // If error raised in control point, inform the peer + if ((ind_status != CSCP_CTNL_PT_RESP_SUCCESS) && + (param->handle == (CSCPS_HANDLE(CSCS_IDX_SC_CTNL_PT_VAL)))) + { + cscps_send_rsp_ind(conidx, param->value[0], ind_status); + } + } + } + else + { + ASSERT_ERR(0); + } + } + } + // else drop the message + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles @ref GATT_NOTIFY_CMP_EVT message meaning that a notification or an indication + * has been correctly sent to peer device (but not confirmed by peer device). + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(src_id); + // Get the address of the environment + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + + // Check if a connection exists + if (ke_state_get(dest_id) == CSCPS_BUSY) + { + switch (param->operation) + { + case (GATTC_NOTIFY): + { + ASSERT_ERR(cscps_env->operation == CSCPS_SEND_CSC_MEAS_OP_CODE); + // continuer operation execution + cscps_exe_operation(); + } break; + + case (GATTC_INDICATE): + { + ASSERT_ERR(cscps_env->operation >= CSCPS_CTNL_PT_CUMUL_VAL_OP_CODE); + + // Inform the application that a procedure has been completed + cscps_send_cmp_evt(conidx, + prf_src_task_get(&cscps_env->prf_env, conidx), + prf_dst_task_get(&cscps_env->prf_env, conidx), + cscps_env->operation, param->status); + // else ignore the message + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(cscps) +{ + {CSCPS_ENABLE_REQ, (ke_msg_func_t) cscps_enable_req_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler}, + {CSCPS_NTF_CSC_MEAS_REQ, (ke_msg_func_t) cscps_ntf_csc_meas_req_handler}, + {CSCPS_SC_CTNL_PT_CFM, (ke_msg_func_t) cscps_sc_ctnl_pt_cfm_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, +}; + +void cscps_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct cscps_env_tag *cscps_env = PRF_ENV_GET(CSCPS, cscps); + + task_desc->msg_handler_tab = cscps_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(cscps_msg_handler_tab); + task_desc->state = cscps_env->state; + task_desc->idx_max = CSCPS_IDX_MAX; +} + +#endif //(BLE_CSC_SENSOR) + +/// @} CSCPSTASK diff --git a/services/ble_profiles/datapath/datapathps/api/datapathps_task.h b/services/ble_profiles/datapath/datapathps/api/datapathps_task.h new file mode 100644 index 0000000..02b5dfc --- /dev/null +++ b/services/ble_profiles/datapath/datapathps/api/datapathps_task.h @@ -0,0 +1,88 @@ +#ifndef _DATAPATHPS_TASK_H_ +#define _DATAPATHPS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup DATAPATHPSTASK Task + * @ingroup DATAPATHPS + * @brief Heart Rate Profile Task. + * + * The DATAPATHPSTASK is responsible for handling the messages coming in and out of the + * @ref DATAPATHPS collector block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include "rwip_task.h" // Task definitions + +/* + * DEFINES + **************************************************************************************** + */ +/// Messages for Data Path Server Profile +enum datapathps_msg_id +{ + DATAPATHPS_TX_CCC_CHANGED = TASK_FIRST_MSG(TASK_ID_DATAPATHPS), + + DATAPATHPS_TX_DATA_SENT, + + DATAPATHPS_RX_DATA_RECEIVED, + + DATAPATHPS_NOTIFICATION_RECEIVED, + + DATAPATHPS_SEND_DATA_VIA_NOTIFICATION, + + DATAPATHPS_SEND_DATA_VIA_INDICATION, + + DATAPATHPS_SEND_DATA_VIA_WRITE_COMMAND, + + DATAPATHPS_SEND_DATA_VIA_WRITE_REQUEST, + + DATAPATHPS_CONTROL_NOTIFICATION, + +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +struct ble_datapath_tx_notif_config_t +{ + bool isNotificationEnabled; +}; + +struct ble_datapath_rx_data_ind_t +{ + uint16_t length; + uint8_t data[0]; +}; + +struct ble_datapath_tx_sent_ind_t +{ + uint8_t status; +}; + +struct ble_datapath_send_data_req_t +{ + uint8_t connecionIndex; + uint32_t length; + uint8_t value[__ARRAY_EMPTY]; +}; + +struct ble_datapath_control_notification_t +{ + bool isEnable; + uint8_t connecionIndex; +}; + +/// @} DATAPATHPSTASK + +#endif /* _DATAPATHPS_TASK_H_ */ diff --git a/services/ble_profiles/datapath/datapathps/src/datapathps.c b/services/ble_profiles/datapath/datapathps/src/datapathps.c new file mode 100644 index 0000000..f1a6e40 --- /dev/null +++ b/services/ble_profiles/datapath/datapathps/src/datapathps.c @@ -0,0 +1,240 @@ +/** + **************************************************************************************** + * @addtogroup DPPS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_DATAPATH_SERVER) +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "gapc_task.h" +#include "datapathps.h" +#include "datapathps_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * DATAPATH SRVER PROFILE ATTRIBUTES + **************************************************************************************** + */ + +#define USE_128BIT_UUID 1 + +#if USE_128BIT_UUID + +#define datapath_service_uuid_128_content {0x12, 0x34, 0x56, 0x78, 0x90, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01 } +#define datapath_tx_char_val_uuid_128_content {0x12, 0x34, 0x56, 0x78, 0x91, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02 } +#define datapath_rx_char_val_uuid_128_content {0x12, 0x34, 0x56, 0x78, 0x92, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03 } + +#define ATT_DECL_PRIMARY_SERVICE_UUID { 0x00, 0x28 } +#define ATT_DECL_CHARACTERISTIC_UUID { 0x03, 0x28 } +#define ATT_DESC_CLIENT_CHAR_CFG_UUID { 0x02, 0x29 } +#define ATT_DESC_CHAR_USER_DESCRIPTION_UUID { 0x01, 0x29 } + + +static const uint8_t DATAPATH_SERVICE_UUID_128[ATT_UUID_128_LEN] = datapath_service_uuid_128_content; + +/// Full DATAPATH SERVER Database Description - Used to add attributes into the database +const struct attm_desc_128 datapathps_att_db[DATAPATHPS_IDX_NB] = +{ + // Service Declaration + [DATAPATHPS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE_UUID, PERM(RD, ENABLE), 0, 0}, + + // TX Characteristic Declaration + [DATAPATHPS_IDX_TX_CHAR] = {ATT_DECL_CHARACTERISTIC_UUID, PERM(RD, ENABLE), 0, 0}, + // TX Characteristic Value + [DATAPATHPS_IDX_TX_VAL] = {datapath_tx_char_val_uuid_128_content, PERM(NTF, ENABLE) | PERM(RD, ENABLE), PERM(RI, ENABLE) | PERM_VAL(UUID_LEN, PERM_UUID_128), DATAPATHPS_MAX_LEN}, + // TX Characteristic - Client Characteristic Configuration Descriptor + [DATAPATHPS_IDX_TX_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG_UUID, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + // TX Characteristic - Characteristic User Description Descriptor + [DATAPATHPS_IDX_TX_DESC] = {ATT_DESC_CHAR_USER_DESCRIPTION_UUID, PERM(RD, ENABLE), PERM(RI, ENABLE), 32}, + + // RX Characteristic Declaration + [DATAPATHPS_IDX_RX_CHAR] = {ATT_DECL_CHARACTERISTIC_UUID, PERM(RD, ENABLE), 0, 0}, + // RX Characteristic Value + [DATAPATHPS_IDX_RX_VAL] = {datapath_rx_char_val_uuid_128_content, PERM(WRITE_REQ, ENABLE) | PERM(WRITE_COMMAND, ENABLE), PERM(RI, ENABLE) | PERM_VAL(UUID_LEN, PERM_UUID_128), DATAPATHPS_MAX_LEN}, + // RX Characteristic - Characteristic User Description Descriptor + [DATAPATHPS_IDX_RX_DESC] = {ATT_DESC_CHAR_USER_DESCRIPTION_UUID, PERM(RD, ENABLE), PERM(RI, ENABLE), 32}, +}; +#else + +#define DATAPATHPS_SERVICE_UUID_16BIT 0xFEF8 +#define DATAPATHPS_TX_CHAR_VAL_UUID_16BIT 0xFEF9 +#define DATAPATHPS_RX_CHAR_VAL_UUID_16BIT 0xFEFA + +const struct attm_desc datapathps_att_db[DATAPATHPS_IDX_NB] = +{ + // Service Declaration + [DATAPATHPS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // TX Characteristic Declaration + [DATAPATHPS_IDX_TX_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // TX Characteristic Value + [DATAPATHPS_IDX_TX_VAL] = {DATAPATHPS_TX_CHAR_VAL_UUID_16BIT, PERM(NTF, ENABLE), PERM(RI, ENABLE), DATAPATHPS_MAX_LEN}, + // TX Characteristic - Client Characteristic Configuration Descriptor + [DATAPATHPS_IDX_TX_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + // TX Characteristic - Characteristic User Description Descriptor + [DATAPATHPS_IDX_TX_DESC] = {ATT_DESC_CHAR_USER_DESCRIPTION, PERM(RD, ENABLE), PERM(RI, ENABLE), 32}, + + // RX Characteristic Declaration + [DATAPATHPS_IDX_RX_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // RX Characteristic Value + [DATAPATHPS_IDX_RX_VAL] = {DATAPATHPS_RX_CHAR_VAL_UUID_16BIT, PERM(WRITE_REQ, ENABLE) | PERM(WRITE_COMMAND, ENABLE), PERM(RI, ENABLE), DATAPATHPS_MAX_LEN}, + // RX Characteristic - Characteristic User Description Descriptor + [DATAPATHPS_IDX_RX_DESC] = {ATT_DESC_CHAR_USER_DESCRIPTION, PERM(RD, ENABLE), PERM(RI, ENABLE), 32}, +}; + +#endif +/** + **************************************************************************************** + * @brief Initialization of the DATAPATHPS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t datapathps_init(struct prf_task_env* env, uint16_t* start_hdl, + uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t status; + + //Add Service Into Database +#if USE_128BIT_UUID + + status = attm_svc_create_db_128(start_hdl, DATAPATH_SERVICE_UUID_128, NULL, + DATAPATHPS_IDX_NB, NULL, env->task, &datapathps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS))| PERM(SVC_MI, DISABLE) + | PERM_VAL(SVC_UUID_LEN, PERM_UUID_128)); +#else + status = attm_svc_create_db(start_hdl, DATAPATHPS_SERVICE_UUID_16BIT, NULL, + DATAPATHPS_IDX_NB, NULL, env->task, &datapathps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, DISABLE) ); +#endif + + BLE_GATT_DBG("attm_svc_create_db_128 returns %d start handle is %d", status, *start_hdl); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // Allocate DATAPATHPS required environment variable + struct datapathps_env_tag* datapathps_env = + (struct datapathps_env_tag* ) ke_malloc(sizeof(struct datapathps_env_tag), KE_MEM_ATT_DB); + + memset((uint8_t *)datapathps_env, 0, sizeof(struct datapathps_env_tag)); + // Initialize DATAPATHPS environment + env->env = (prf_env_t*) datapathps_env; + datapathps_env->shdl = *start_hdl; + + datapathps_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Mono Instantiated task + datapathps_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + // initialize environment variable + env->id = TASK_ID_DATAPATHPS; + datapathps_task_init(&(env->desc)); + + /* Put HRS in Idle state */ + ke_state_set(env->task, DATAPATHPS_IDLE); + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the DATAPATHPS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void datapathps_destroy(struct prf_task_env* env) +{ + struct datapathps_env_tag* datapathps_env = (struct datapathps_env_tag*) env->env; + + // free profile environment variables + env->env = NULL; + ke_free(datapathps_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void datapathps_create(struct prf_task_env* env, uint8_t conidx) +{ + struct datapathps_env_tag* datapathps_env = (struct datapathps_env_tag*) env->env; + struct prf_svc datapathps_svc = {datapathps_env->shdl, datapathps_env->shdl + DATAPATHPS_IDX_NB}; + prf_register_atthdl2gatt(env->env, conidx, &datapathps_svc); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void datapathps_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + /* Nothing to do */ +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// DATAPATHPS Task interface required by profile manager +const struct prf_task_cbs datapathps_itf = +{ + (prf_init_fnct) datapathps_init, + datapathps_destroy, + datapathps_create, + datapathps_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* datapathps_prf_itf_get(void) +{ + return &datapathps_itf; +} + + +#endif /* BLE_DATAPATH_SERVER */ + +/// @} DATAPATHPS diff --git a/services/ble_profiles/datapath/datapathps/src/datapathps.h b/services/ble_profiles/datapath/datapathps/src/datapathps.h new file mode 100644 index 0000000..168e3c3 --- /dev/null +++ b/services/ble_profiles/datapath/datapathps/src/datapathps.h @@ -0,0 +1,163 @@ +#ifndef _DATAPATHPS_H_ +#define _DATAPATHPS_H_ + +/** + **************************************************************************************** + * @addtogroup DATAPATHPS Datapath Profile Server + * @ingroup DATAPATHP + * @brief Datapath Profile Server + * + * Datapath Profile Server provides functionalities to upper layer module + * application. The device using this profile takes the role of Datapath Server. + * + * The interface of this role to the Application is: + * - Enable the profile role (from APP) + * - Disable the profile role (from APP) + * - Send data to peer device via notifications (from APP) + * - Receive data from peer device via write no response (from APP) + * + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_DATAPATH_SERVER) +#include "prf_types.h" +#include "prf.h" +#include "datapathps_task.h" +#include "attm.h" +#include "prf_utils.h" + + +#define BLE_MAXIMUM_CHARACTERISTIC_DESCRIPTION 32 + +static const char custom_tx_desc[] = "Data Path TX Data"; +static const char custom_rx_desc[] = "Data Path RX Data"; + + + +/* + * DEFINES + **************************************************************************************** + */ + +#define DATAPATHPS_MAX_LEN (509) // consider the extended data length + +#define DATAPATHPS_MANDATORY_MASK (0x0F) +#define DATAPATHPS_BODY_SENSOR_LOC_MASK (0x30) +#define DATAPATHPS_HR_CTNL_PT_MASK (0xC0) + +#define HRP_PRF_CFG_PERFORMED_OK (0x80) + +/* + * MACROS + **************************************************************************************** + */ + +#define DATAPATHPS_IS_SUPPORTED(features, mask) ((features & mask) == mask) + + +/* + * DEFINES + **************************************************************************************** + */ +/// Possible states of the DATAPATHPS task +enum +{ + /// Idle state + DATAPATHPS_IDLE, + /// Connected state + DATAPATHPS_BUSY, + + /// Number of defined states. + DATAPATHPS_STATE_MAX, +}; + +///Attributes State Machine +enum +{ + DATAPATHPS_IDX_SVC, + + DATAPATHPS_IDX_TX_CHAR, + DATAPATHPS_IDX_TX_VAL, + DATAPATHPS_IDX_TX_NTF_CFG, + DATAPATHPS_IDX_TX_DESC, + + DATAPATHPS_IDX_RX_CHAR, + DATAPATHPS_IDX_RX_VAL, + + DATAPATHPS_IDX_RX_DESC, + + DATAPATHPS_IDX_NB, +}; + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Datapath Profile Server environment variable +struct datapathps_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Service Start Handle + uint16_t shdl; + /// flag to mark whether notification is enabled + uint8_t isNotificationEnabled[BLE_CONNECTION_MAX]; + /// State of different task instances + ke_state_t state; +}; + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve HRP service profile interface + * + * @return HRP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* datapathps_prf_itf_get(void); + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void datapathps_task_init(struct ke_task_desc *task_desc); + + + +#endif /* #if (BLE_DATAPATH_SERVER) */ + +/// @} DATAPATHPS + +#endif /* _DATAPATHPS_H_ */ + diff --git a/services/ble_profiles/datapath/datapathps/src/datapathps_task.c b/services/ble_profiles/datapath/datapathps/src/datapathps_task.c new file mode 100644 index 0000000..608d5d7 --- /dev/null +++ b/services/ble_profiles/datapath/datapathps/src/datapathps_task.c @@ -0,0 +1,466 @@ +/** + **************************************************************************************** + * @addtogroup DATAPATHPSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_DATAPATH_SERVER) +#include "gap.h" +#include "gattc_task.h" +#include "gapc_task.h" +#include "attm.h" +#include "datapathps.h" +#include "datapathps_task.h" + +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ +static int gapc_disconnect_ind_handler(ke_msg_id_t const msgid, + struct gapc_disconnect_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + uint8_t conidx = KE_IDX_GET(src_id); + datapathps_env->isNotificationEnabled[conidx] = false; + return KE_MSG_CONSUMED; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. + * The handler compares the new values with current ones and notifies them if they changed. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + uint8_t conidx = KE_IDX_GET(src_id); + + uint8_t status = GAP_ERR_NO_ERROR; + + BLE_GATT_DBG("gattc_write_req_ind_handler datapathps_env 0x%x write handle %d shdl %d", + datapathps_env, param->handle, datapathps_env->shdl); + + + if (datapathps_env != NULL) + { + // TX ccc + if (param->handle == (datapathps_env->shdl + DATAPATHPS_IDX_TX_NTF_CFG)) + { + uint16_t value = 0x0000; + + //Extract value before check + memcpy(&value, &(param->value), sizeof(uint16_t)); + + if (value == PRF_CLI_STOP_NTFIND) { + datapathps_env->isNotificationEnabled[conidx] = false; + } else if (value == PRF_CLI_START_NTF) { + datapathps_env->isNotificationEnabled[conidx] = true; + } else { + status = PRF_APP_ERROR; + } + + if (status == GAP_ERR_NO_ERROR) { + //Inform APP of TX ccc change + struct ble_datapath_tx_notif_config_t * ind = KE_MSG_ALLOC(DATAPATHPS_TX_CCC_CHANGED, + prf_dst_task_get(&datapathps_env->prf_env, conidx), + prf_src_task_get(&datapathps_env->prf_env, conidx), + ble_datapath_tx_notif_config_t); + + ind->isNotificationEnabled = datapathps_env->isNotificationEnabled[conidx]; + + ke_msg_send(ind); + } + } + // RX data + else if (param->handle == (datapathps_env->shdl + DATAPATHPS_IDX_RX_VAL)) + { + //inform APP of data + struct ble_datapath_rx_data_ind_t * ind = KE_MSG_ALLOC_DYN(DATAPATHPS_RX_DATA_RECEIVED, + prf_dst_task_get(&datapathps_env->prf_env, conidx), + prf_src_task_get(&datapathps_env->prf_env, conidx), + ble_datapath_rx_data_ind_t, + param->length); + + ind->length = param->length; + memcpy((uint8_t *)(ind->data), &(param->value), param->length); + + ke_msg_send(ind); + } + else + { + status = PRF_APP_ERROR; + } + } + + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY message meaning that Measurement + * notification has been correctly sent to peer device (but not confirmed by peer device). + * * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + // Get the address of the environment + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + + uint8_t conidx = KE_IDX_GET(dest_id); + + // notification has been sent out + if ((GATTC_NOTIFY == param->operation) || (GATTC_WRITE_NO_RESPONSE == param->operation)) + { + + struct ble_datapath_tx_sent_ind_t * ind = KE_MSG_ALLOC(DATAPATHPS_TX_DATA_SENT, + prf_dst_task_get(&datapathps_env->prf_env, conidx), + prf_src_task_get(&datapathps_env->prf_env, conidx), + ble_datapath_tx_sent_ind_t); + + ind->status = param->status; + + ke_msg_send(ind); + + } + + ke_state_set(dest_id, DATAPATHPS_IDLE); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, + gattc_read_cfm, BLE_MAXIMUM_CHARACTERISTIC_DESCRIPTION); + + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t status = GAP_ERR_NO_ERROR; + + BLE_GATT_DBG("gattc_read_req_ind_handler read handle %d shdl %d", param->handle, datapathps_env->shdl); + + if (param->handle == (datapathps_env->shdl + DATAPATHPS_IDX_TX_DESC)) { + cfm->length = sizeof(custom_tx_desc); + memcpy(cfm->value, custom_tx_desc, cfm->length); + } else if (param->handle == (datapathps_env->shdl + DATAPATHPS_IDX_RX_DESC)) { + cfm->length = sizeof(custom_rx_desc); + memcpy(cfm->value, custom_rx_desc, cfm->length); + } else if (param->handle == (datapathps_env->shdl + DATAPATHPS_IDX_TX_NTF_CFG)) { + uint16_t notify_ccc; + if (datapathps_env->isNotificationEnabled[conidx]) { + notify_ccc = 1; + } else { + notify_ccc = 0; + } + cfm->length = sizeof(notify_ccc); + memcpy(cfm->value, (uint8_t *)¬ify_ccc, cfm->length); + } + + else { + cfm->length = 0; + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } + + cfm->handle = param->handle; + + cfm->status = status; + + ke_msg_send(cfm); + + ke_state_set(dest_id, DATAPATHPS_IDLE); + + return (KE_MSG_CONSUMED); +} + +static void send_notifiction(uint8_t conidx, const uint8_t* ptrData, uint32_t length) +{ + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + + if (datapathps_env->isNotificationEnabled[conidx]) { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *report_ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&datapathps_env->prf_env, conidx), + gattc_send_evt_cmd, length); + + // Fill in the parameter structure + report_ntf->operation = GATTC_NOTIFY; + report_ntf->handle = datapathps_env->shdl + DATAPATHPS_IDX_TX_VAL; + // pack measured value in database + report_ntf->length = length; + memcpy(report_ntf->value, ptrData, length); + // send notification to peer device + ke_msg_send(report_ntf); + } +} + +__STATIC int send_data_via_notification_handler(ke_msg_id_t const msgid, + struct ble_datapath_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + send_notifiction(param->connecionIndex, param->value, param->length); + return (KE_MSG_CONSUMED); +} + +static void send_indication(uint8_t conidx, const uint8_t* ptrData, uint32_t length) +{ + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + + if (datapathps_env->isNotificationEnabled[conidx]) { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *report_ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&datapathps_env->prf_env, conidx), + gattc_send_evt_cmd, length); + + // Fill in the parameter structure + report_ntf->operation = GATTC_INDICATE; + report_ntf->handle = datapathps_env->shdl + DATAPATHPS_IDX_TX_VAL; + // pack measured value in database + report_ntf->length = length; + memcpy(report_ntf->value, ptrData, length); + // send notification to peer device + ke_msg_send(report_ntf); + } +} + +__STATIC int send_data_via_indication_handler(ke_msg_id_t const msgid, + struct ble_datapath_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + send_indication(param->connecionIndex, param->value, param->length); + return (KE_MSG_CONSUMED); +} + +__STATIC int send_data_via_write_command_handler(ke_msg_id_t const msgid, + struct ble_datapath_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + + prf_gatt_write(&(datapathps_env->prf_env), KE_IDX_GET(dest_id), datapathps_env->shdl + DATAPATHPS_IDX_RX_VAL, + (uint8_t *)¶m->value, param->length, GATTC_WRITE_NO_RESPONSE); + + ke_state_set(dest_id, DATAPATHPS_BUSY); + return (KE_MSG_CONSUMED); +} + +__STATIC int send_data_via_write_request_handler(ke_msg_id_t const msgid, + struct ble_datapath_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + + prf_gatt_write(&(datapathps_env->prf_env), KE_IDX_GET(dest_id), datapathps_env->shdl + DATAPATHPS_IDX_RX_VAL, + (uint8_t *)¶m->value, param->length, GATTC_WRITE); + + ke_state_set(dest_id, DATAPATHPS_BUSY); + return (KE_MSG_CONSUMED); +} + +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + + switch(param->type) + { + case GATTC_INDICATE: + { + // confirm that indication has been correctly received + struct gattc_event_cfm * cfm = KE_MSG_ALLOC(GATTC_EVENT_CFM, src_id, dest_id, gattc_event_cfm); + cfm->handle = param->handle; + ke_msg_send(cfm); + } + /* no break */ + + case GATTC_NOTIFY: + { + if (param->handle == datapathps_env->shdl + DATAPATHPS_IDX_TX_VAL) + { + //inform APP of data + struct ble_datapath_rx_data_ind_t * ind = KE_MSG_ALLOC_DYN(DATAPATHPS_NOTIFICATION_RECEIVED, + prf_dst_task_get(&datapathps_env->prf_env, conidx), + prf_src_task_get(&datapathps_env->prf_env, conidx), + ble_datapath_rx_data_ind_t, + param->length); + + ind->length = param->length; + memcpy((uint8_t *)(ind->data), &(param->value), param->length); + + ke_msg_send(ind); + + } + } break; + + default: + break; + } + + return (KE_MSG_CONSUMED); +} + +__STATIC int control_notification_handler(ke_msg_id_t const msgid, + struct ble_datapath_control_notification_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + uint16_t ccc_write_val = 0; + if (param->isEnable) + { + ccc_write_val = 1; + } + + prf_gatt_write(&(datapathps_env->prf_env), param->connecionIndex, datapathps_env->shdl + DATAPATHPS_IDX_TX_NTF_CFG, + (uint8_t *)&ccc_write_val, sizeof(ccc_write_val), GATTC_WRITE); + + ke_state_set(dest_id, DATAPATHPS_BUSY); + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct gattc_att_info_cfm * cfm; + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + // check if it's a client configuration char + if (param->handle == datapathps_env->shdl + DATAPATHPS_IDX_TX_NTF_CFG) + { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } + else if (param->handle == datapathps_env->shdl + DATAPATHPS_IDX_RX_VAL) + { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } + // not expected request + else + { + cfm->length = 0; + cfm->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/* Default State handlers definition. */ +KE_MSG_HANDLER_TAB(datapathps) +{ + {GAPC_DISCONNECT_IND, (ke_msg_func_t) gapc_disconnect_ind_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {DATAPATHPS_SEND_DATA_VIA_NOTIFICATION, (ke_msg_func_t) send_data_via_notification_handler}, + {DATAPATHPS_SEND_DATA_VIA_INDICATION, (ke_msg_func_t) send_data_via_indication_handler}, + {DATAPATHPS_SEND_DATA_VIA_WRITE_COMMAND, (ke_msg_func_t) send_data_via_write_command_handler}, + {DATAPATHPS_SEND_DATA_VIA_WRITE_REQUEST, (ke_msg_func_t) send_data_via_write_request_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t) gattc_event_ind_handler}, + {DATAPATHPS_CONTROL_NOTIFICATION, (ke_msg_func_t) control_notification_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler }, + +}; + +void datapathps_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct datapathps_env_tag *datapathps_env = PRF_ENV_GET(DATAPATHPS, datapathps); + + task_desc->msg_handler_tab = datapathps_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(datapathps_msg_handler_tab); + task_desc->state = &(datapathps_env->state); + task_desc->idx_max = BLE_CONNECTION_MAX; +} + +#endif /* #if (BLE_DATAPATH_SERVER) */ + +/// @} DATAPATHPSTASK diff --git a/services/ble_profiles/dis/disc/api/disc_task.h b/services/ble_profiles/dis/disc/api/disc_task.h new file mode 100644 index 0000000..84003a2 --- /dev/null +++ b/services/ble_profiles/dis/disc/api/disc_task.h @@ -0,0 +1,105 @@ +#ifndef DISC_TASK_H_ +#define DISC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup DISCTASK Device Information Service Client Task + * @ingroup DISC + * @brief Device Information Service Client Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +enum +{ + /// Start the find me locator profile - at connection + DISC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_DISC), + /// Confirm that cfg connection has finished with discovery results, or that normal cnx started + DISC_ENABLE_RSP, + + /// Generic message to read a DIS characteristic value + DISC_RD_CHAR_REQ, + /// Generic message for read responses for APP + DISC_RD_CHAR_RSP, +}; + +enum +{ + DISC_MANUFACTURER_NAME_CHAR, + DISC_MODEL_NB_STR_CHAR, + DISC_SERIAL_NB_STR_CHAR, + DISC_HARD_REV_STR_CHAR, + DISC_FIRM_REV_STR_CHAR, + DISC_SW_REV_STR_CHAR, + DISC_SYSTEM_ID_CHAR, + DISC_IEEE_CHAR, + DISC_PNP_ID_CHAR, + + DISC_CHAR_MAX, +}; +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Device Information Service + */ +struct disc_dis_content +{ + /// service info + struct prf_svc svc; + + /// Characteristic info: + struct prf_char_inf chars[DISC_CHAR_MAX]; +}; + +/// Parameters of the @ref DISC_ENABLE_REQ message +struct disc_enable_req +{ + ///Connection type + uint8_t con_type; + + /// Existing handle values dis + struct disc_dis_content dis; +}; + +/// Parameters of the @ref DISC_ENABLE_RSP message +struct disc_enable_rsp +{ + ///status + uint8_t status; + + /// DIS handle values and characteristic properties + struct disc_dis_content dis; +}; + +///Parameters of the @ref DISC_RD_CHAR_REQ message +struct disc_rd_char_req +{ + ///Characteristic value code + uint8_t char_code; +}; + +///Parameters of the @ref DISC_RD_CHAR_RSP message +struct disc_rd_char_rsp +{ + /// Attribute data information + struct prf_att_info info; +}; + + + +/// @} DISCTASK + +#endif // DISC_TASK_H_ diff --git a/services/ble_profiles/dis/disc/src/disc.c b/services/ble_profiles/dis/disc/src/disc.c new file mode 100644 index 0000000..21ac429 --- /dev/null +++ b/services/ble_profiles/dis/disc/src/disc.c @@ -0,0 +1,198 @@ +/** + **************************************************************************************** + * @addtogroup DISC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_DIS_CLIENT) +#include "disc.h" +#include "disc_task.h" +#include "gap.h" + +#include "ke_mem.h" + + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialization of the DISC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t disc_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct disc_env_tag* disc_env = + (struct disc_env_tag* ) ke_malloc(sizeof(struct disc_env_tag), KE_MEM_ATT_DB); + + // allocate DISC required environment variable + env->env = (prf_env_t*) disc_env; + + disc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + disc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_DISC; + disc_task_init(&(env->desc)); + + for(idx = 0; idx < DISC_IDX_MAX ; idx++) + { + disc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), DISC_FREE); + } + + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Destruction of the DISC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void disc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct disc_env_tag* disc_env = (struct disc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < DISC_IDX_MAX ; idx++) + { + if(disc_env->env[idx] != NULL) + { + ke_free(disc_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(disc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void disc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put DIS Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), DISC_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void disc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct disc_env_tag* disc_env = (struct disc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(disc_env->env[conidx] != NULL) + { + ke_free(disc_env->env[conidx]); + disc_env->env[conidx] = NULL; + } + + /* Put DIS Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), DISC_FREE); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// DISC Task interface required by profile manager +const struct prf_task_cbs disc_itf = +{ + disc_init, + disc_destroy, + disc_create, + disc_cleanup, +}; + + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* disc_prf_itf_get(void) +{ + return &disc_itf; +} + + +void disc_enable_rsp_send(struct disc_env_tag *disc_env, uint8_t conidx, uint8_t status) +{ + // Send APP the details of the discovered attributes on DISC + struct disc_enable_rsp * rsp = KE_MSG_ALLOC(DISC_ENABLE_RSP, + prf_dst_task_get(&(disc_env->prf_env), conidx), + prf_src_task_get(&(disc_env->prf_env), conidx), + disc_enable_rsp); + + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->dis = disc_env->env[conidx]->dis; + + // Go to connected state + ke_state_set(prf_src_task_get(&(disc_env->prf_env), conidx), DISC_IDLE); + } + else + { + // clean-up environment variable allocated for task instance + ke_free(disc_env->env[conidx]); + disc_env->env[conidx] = NULL; + } + + ke_msg_send(rsp); +} + +#endif //BLE_DIS_CLIENT + +/// @} DISC diff --git a/services/ble_profiles/dis/disc/src/disc.h b/services/ble_profiles/dis/disc/src/disc.h new file mode 100644 index 0000000..d4a27a1 --- /dev/null +++ b/services/ble_profiles/dis/disc/src/disc.h @@ -0,0 +1,131 @@ +#ifndef DISC_H_ +#define DISC_H_ + +/** + **************************************************************************************** + * @addtogroup DIS Device Information Service + * @ingroup PROFILE + * @brief Device Information Service + ***************************************************************************************** + */ + +/** + **************************************************************************************** + * @addtogroup DISC Device Information Service Client + * @ingroup DIS + * @brief Device Information Service Client + * @{ + **************************************************************************************** + */ +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" +#if (BLE_DIS_CLIENT) +#include +#include +#include "ke_task.h" +#include "prf_utils.h" +#include "disc_task.h" + +/* + * DEFINES + **************************************************************************************** + */ + +///Maximum number of Device Information Service Client task instances +#define DISC_IDX_MAX (BLE_CONNECTION_MAX) + +/// Possible states of the DISC task +enum +{ + /// Not Connected State + DISC_FREE, + /// Idle state + DISC_IDLE, + /// Discovering State + DISC_DISCOVERING, + /// Busy State + DISC_BUSY, + + ///Number of defined states. + DISC_STATE_MAX +}; + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Environment variable for each Connections +struct disc_cnx_env +{ + ///Current Time Service Characteristics + struct disc_dis_content dis; + /// Last char. code requested to read. + uint8_t last_char_code; + /// counter used to check service uniqueness + uint8_t nb_svc; +}; + +/// Device Information Service Client environment variable +struct disc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct disc_cnx_env* env[DISC_IDX_MAX]; + /// State of different task instances + ke_state_t state[DISC_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Retrieve DIS client profile interface + * + * @return DIS client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* disc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Thermometer ATT DB discovery results to HTPC host. + **************************************************************************************** + */ +void disc_enable_rsp_send(struct disc_env_tag *disc_env, uint8_t conidx, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void disc_task_init(struct ke_task_desc *task_desc); + +#endif //BLE_DIS_CLIENT + +/// @} DISC + +#endif // DISC_H_ diff --git a/services/ble_profiles/dis/disc/src/disc_task.c b/services/ble_profiles/dis/disc/src/disc_task.c new file mode 100644 index 0000000..585a1b3 --- /dev/null +++ b/services/ble_profiles/dis/disc/src/disc_task.c @@ -0,0 +1,345 @@ +/** + **************************************************************************************** + * @addtogroup DISCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_DIS_CLIENT) +#include "co_utils.h" +#include "gap.h" +#include "disc_task.h" +#include "disc.h" +#include "gattc_task.h" + +#include "ke_mem.h" + + +/// State machine used to retrieve Device Information Service characteristics information +const struct prf_char_def disc_dis_char[DISC_CHAR_MAX] = +{ + /// Manufacturer Name + [DISC_MANUFACTURER_NAME_CHAR] = {ATT_CHAR_MANUF_NAME, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, + /// Model Number String + [DISC_MODEL_NB_STR_CHAR] = {ATT_CHAR_MODEL_NB, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, + /// Serial Number String + [DISC_SERIAL_NB_STR_CHAR] = {ATT_CHAR_SERIAL_NB, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, + /// Hardware Revision String + [DISC_HARD_REV_STR_CHAR] = {ATT_CHAR_HW_REV, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, + /// Firmware Revision String + [DISC_FIRM_REV_STR_CHAR] = {ATT_CHAR_FW_REV, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, + /// TSoftware Revision String + [DISC_SW_REV_STR_CHAR] = {ATT_CHAR_SW_REV, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, + /// System ID + [DISC_SYSTEM_ID_CHAR] = {ATT_CHAR_SYS_ID, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, + /// IEEE + [DISC_IEEE_CHAR] = {ATT_CHAR_IEEE_CERTIF, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, + /// PnP ID + [DISC_PNP_ID_CHAR] = {ATT_CHAR_PNP_ID, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, +}; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref DISC_ENABLE_REQ message. + * The handler enables the Device Information Service Client Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int disc_enable_req_handler(ke_msg_id_t const msgid, + struct disc_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Device Information Service Client Role Task Environment + struct disc_env_tag *disc_env = PRF_ENV_GET(DISC, disc); + + + ASSERT_INFO(disc_env != NULL, dest_id, src_id); + if((state == DISC_IDLE) && (disc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + disc_env->env[conidx] = (struct disc_cnx_env*) ke_malloc(sizeof(struct disc_cnx_env),KE_MEM_ATT_DB); + memset(disc_env->env[conidx], 0, sizeof(struct disc_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering HTS on peer + prf_disc_svc_send(&(disc_env->prf_env), conidx, ATT_SVC_DEVICE_INFO); + + // Go to DISCOVERING state + ke_state_set(dest_id, DISC_DISCOVERING); + } + //normal connection, get saved att details + else + { + disc_env->env[conidx]->dis = param->dis; + + //send APP confirmation that can start normal connection to TH + disc_enable_rsp_send(disc_env, conidx, GAP_ERR_NO_ERROR); + } + } + else if(state != DISC_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + disc_enable_rsp_send(disc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == DISC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct disc_env_tag *disc_env = PRF_ENV_GET(DISC, disc); + + ASSERT_INFO(disc_env != NULL, dest_id, src_id); + ASSERT_INFO(disc_env->env[conidx] != NULL, dest_id, src_id); + + if(disc_env->env[conidx]->nb_svc == 0) + { + // Retrieve DIS characteristics + prf_extract_svc_info(ind, DISC_CHAR_MAX, &disc_dis_char[0], &(disc_env->env[conidx]->dis.chars[0]), + 0, NULL, NULL); + + //Even if we get multiple responses we only store 1 range + disc_env->env[conidx]->dis.svc.shdl = ind->start_hdl; + disc_env->env[conidx]->dis.svc.ehdl = ind->end_hdl; + } + + disc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + // Get the address of the environment + struct disc_env_tag *disc_env = PRF_ENV_GET(DISC, disc); + uint8_t conidx = KE_IDX_GET(dest_id); + + + if(state == DISC_DISCOVERING) + { + uint8_t status = param->status; + + if (param->status == ATT_ERR_NO_ERROR) + { + if(disc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(DISC_CHAR_MAX, disc_env->env[conidx]->dis.chars, + disc_dis_char); + } + // too much services + else if (disc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + } + + disc_enable_rsp_send(disc_env, conidx, status); + } + else if (state == DISC_BUSY) + { + // an error occurs while performing read request + if((param->operation == GATTC_READ) && (param->status != GAP_ERR_NO_ERROR)) + { + prf_client_att_info_rsp(&(disc_env->prf_env), conidx, DISC_RD_CHAR_RSP, + param->status, NULL); + } + + ke_state_set(dest_id, DISC_IDLE); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HTPC_RD_DATETIME_REQ message. + * Check if the handle exists in profile(already discovered) and send request, otherwise + * error to APP. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int disc_rd_char_req_handler(ke_msg_id_t const msgid, + struct disc_rd_char_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Device Information Service Client Role Task Environment + struct disc_env_tag *disc_env = PRF_ENV_GET(DISC, disc); + + ASSERT_INFO(disc_env != NULL, dest_id, src_id); + if((state == DISC_IDLE) && (disc_env->env[conidx] != NULL)) + { + uint16_t search_hdl = ATT_INVALID_HDL; + + // retrieve search handle + if (param->char_code < DISC_CHAR_MAX) + { + search_hdl = disc_env->env[conidx]->dis.chars[param->char_code].val_hdl; + } + + //Check if handle is viable + if (search_hdl != ATT_INVALID_HDL) + { + // perform read request + disc_env->env[conidx]->last_char_code = param->char_code; + prf_read_char_send(&(disc_env->prf_env), conidx, disc_env->env[conidx]->dis.svc.shdl, + disc_env->env[conidx]->dis.svc.ehdl, search_hdl); + + // enter in a busy state + ke_state_set(dest_id, DISC_BUSY); + } + else + { + // invalid handle requested + status = PRF_ERR_INEXISTENT_HDL; + } + } + else if(state != DISC_FREE) + { + // request cannot be performed + status = PRF_ERR_REQ_DISALLOWED; + } + + // send error response if request fails + if(status != GAP_ERR_NO_ERROR) + { + prf_client_att_info_rsp(&(disc_env->prf_env), conidx, DISC_RD_CHAR_RSP, + status, NULL); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == DISC_BUSY) + { + // Get the address of the environment + struct disc_env_tag *disc_env = PRF_ENV_GET(DISC, disc); + + ASSERT_INFO(disc_env != NULL, dest_id, src_id); + ASSERT_INFO(disc_env->env[KE_IDX_GET(dest_id)] != NULL, dest_id, src_id); + prf_client_att_info_rsp(&(disc_env->prf_env), KE_IDX_GET(dest_id), DISC_RD_CHAR_RSP, + GAP_ERR_NO_ERROR, param); + } + + return (KE_MSG_CONSUMED); +} + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(disc) +{ + {DISC_RD_CHAR_REQ, (ke_msg_func_t)disc_rd_char_req_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {DISC_ENABLE_REQ, (ke_msg_func_t)disc_enable_req_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void disc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct disc_env_tag *disc_env = PRF_ENV_GET(DISC, disc); + + task_desc->msg_handler_tab = disc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(disc_msg_handler_tab); + task_desc->state = disc_env->state; + task_desc->idx_max = DISC_IDX_MAX; +} + +#endif //BLE_DIS_CLIENT + +/// @} DISCTASK diff --git a/services/ble_profiles/dis/diss/api/diss_task.h b/services/ble_profiles/dis/diss/api/diss_task.h new file mode 100644 index 0000000..41d1fb3 --- /dev/null +++ b/services/ble_profiles/dis/diss/api/diss_task.h @@ -0,0 +1,144 @@ +#ifndef DISS_TASK_H_ +#define DISS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup DISSTASK Task + * @ingroup DISS + * @brief Device Information Service Server Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include "rwip_task.h" // Task definitions +#include "prf_types.h" + +/* + * DEFINES + **************************************************************************************** + */ + + + +/// Messages for Device Information Service Server +enum +{ + ///Set the value of an attribute - Request + DISS_SET_VALUE_REQ = TASK_FIRST_MSG(TASK_ID_DISS), + ///Set the value of an attribute - Response + DISS_SET_VALUE_RSP, + + /// Peer device request to get profile attribute value + DISS_VALUE_REQ_IND, + /// Peer device confirm value of requested attribute + DISS_VALUE_CFM, +}; + +///Attribute Table Indexes +enum diss_info +{ + /// Manufacturer Name + DIS_MANUFACTURER_NAME_CHAR, + /// Model Number + DIS_MODEL_NB_STR_CHAR, + /// Serial Number + DIS_SERIAL_NB_STR_CHAR, + /// HW Revision Number + DIS_HARD_REV_STR_CHAR, + /// FW Revision Number + DIS_FIRM_REV_STR_CHAR, + /// SW Revision Number + DIS_SW_REV_STR_CHAR, + /// System Identifier Name + DIS_SYSTEM_ID_CHAR, + /// IEEE Certificate + DIS_IEEE_CHAR, + /// Plug and Play Identifier + DIS_PNP_ID_CHAR, + + DIS_CHAR_MAX, +}; + +///Database Configuration Flags +enum diss_features +{ + ///Indicate if Manufacturer Name String Char. is supported + DIS_MANUFACTURER_NAME_CHAR_SUP = 0x0001, + ///Indicate if Model Number String Char. is supported + DIS_MODEL_NB_STR_CHAR_SUP = 0x0002, + ///Indicate if Serial Number String Char. is supported + DIS_SERIAL_NB_STR_CHAR_SUP = 0x0004, + ///Indicate if Hardware Revision String Char. supports indications + DIS_HARD_REV_STR_CHAR_SUP = 0x0008, + ///Indicate if Firmware Revision String Char. is writable + DIS_FIRM_REV_STR_CHAR_SUP = 0x0010, + ///Indicate if Software Revision String Char. is writable + DIS_SW_REV_STR_CHAR_SUP = 0x0020, + ///Indicate if System ID Char. is writable + DIS_SYSTEM_ID_CHAR_SUP = 0x0040, + ///Indicate if IEEE Char. is writable + DIS_IEEE_CHAR_SUP = 0x0080, + ///Indicate if PnP ID Char. is writable + DIS_PNP_ID_CHAR_SUP = 0x0100, + + ///All features are supported + DIS_ALL_FEAT_SUP = 0x01FF, +}; +/* + * API MESSAGES STRUCTURES + **************************************************************************************** + */ + +/// Parameters for the database creation +struct diss_db_cfg +{ + /// Database configuration @see enum diss_features + uint16_t features; +}; + + +///Set the value of an attribute - Request +struct diss_set_value_req +{ + /// Value to Set + uint8_t value; + /// Value length + uint8_t length; + /// Value data + uint8_t data[__ARRAY_EMPTY]; +}; + +///Set the value of an attribute - Response +struct diss_set_value_rsp +{ + /// Value Set + uint8_t value; + /// status of the request + uint8_t status; +}; + +/// Peer device request to get profile attribute value +struct diss_value_req_ind +{ + /// Requested value + uint8_t value; +}; + +/// Peer device value of requested attribute +struct diss_value_cfm +{ + /// Requested value + uint8_t value; + /// Value length + uint8_t length; + /// Value data + uint8_t data[__ARRAY_EMPTY]; +}; + +/// @} DISSTASK +#endif // DISS_TASK_H_ diff --git a/services/ble_profiles/dis/diss/src/diss.c b/services/ble_profiles/dis/diss/src/diss.c new file mode 100644 index 0000000..c16808b --- /dev/null +++ b/services/ble_profiles/dis/diss/src/diss.c @@ -0,0 +1,347 @@ +/** + **************************************************************************************** + * @addtogroup DISS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_DIS_SERVER) +#include "attm.h" +#include "diss.h" +#include "diss_task.h" +#include "prf_utils.h" +#include "prf.h" + +#include "ke_mem.h" + +/* + * MACROS + **************************************************************************************** + */ + +/// Maximal length for Characteristic values - 128 bytes +#define DIS_VAL_MAX_LEN (128) +///System ID string length +#define DIS_SYS_ID_LEN (0x08) +///IEEE Certif length (min 6 bytes) +#define DIS_IEEE_CERTIF_MIN_LEN (0x06) +///PnP ID length +#define DIS_PNP_ID_LEN (0x07) + + +/* + * DIS ATTRIBUTES + **************************************************************************************** + */ + +/// Full DIS Database Description - Used to add attributes into the database +const struct attm_desc diss_att_db[DIS_IDX_NB] = +{ + // Device Information Service Declaration + [DIS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // Manufacturer Name Characteristic Declaration + [DIS_IDX_MANUFACTURER_NAME_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Manufacturer Name Characteristic Value + [DIS_IDX_MANUFACTURER_NAME_VAL] = {ATT_CHAR_MANUF_NAME, PERM(RD, ENABLE), PERM(RI, ENABLE), DIS_VAL_MAX_LEN}, + + // Model Number String Characteristic Declaration + [DIS_IDX_MODEL_NB_STR_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Model Number String Characteristic Value + [DIS_IDX_MODEL_NB_STR_VAL] = {ATT_CHAR_MODEL_NB, PERM(RD, ENABLE), PERM(RI, ENABLE), DIS_VAL_MAX_LEN}, + + // Serial Number String Characteristic Declaration + [DIS_IDX_SERIAL_NB_STR_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Serial Number String Characteristic Value + [DIS_IDX_SERIAL_NB_STR_VAL] = {ATT_CHAR_SERIAL_NB, PERM(RD, ENABLE), PERM(RI, ENABLE), DIS_VAL_MAX_LEN}, + + // Hardware Revision String Characteristic Declaration + [DIS_IDX_HARD_REV_STR_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Hardware Revision String Characteristic Value + [DIS_IDX_HARD_REV_STR_VAL] = {ATT_CHAR_HW_REV, PERM(RD, ENABLE), PERM(RI, ENABLE), DIS_VAL_MAX_LEN}, + + // Firmware Revision String Characteristic Declaration + [DIS_IDX_FIRM_REV_STR_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Firmware Revision String Characteristic Value + [DIS_IDX_FIRM_REV_STR_VAL] = {ATT_CHAR_FW_REV, PERM(RD, ENABLE), PERM(RI, ENABLE), DIS_VAL_MAX_LEN}, + + // Software Revision String Characteristic Declaration + [DIS_IDX_SW_REV_STR_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Software Revision String Characteristic Value + [DIS_IDX_SW_REV_STR_VAL] = {ATT_CHAR_SW_REV, PERM(RD, ENABLE), PERM(RI, ENABLE), DIS_VAL_MAX_LEN}, + + // System ID Characteristic Declaration + [DIS_IDX_SYSTEM_ID_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // System ID Characteristic Value + [DIS_IDX_SYSTEM_ID_VAL] = {ATT_CHAR_SYS_ID, PERM(RD, ENABLE), PERM(RI, ENABLE), DIS_SYS_ID_LEN}, + + // IEEE 11073-20601 Regulatory Certification Data List Characteristic Declaration + [DIS_IDX_IEEE_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // IEEE 11073-20601 Regulatory Certification Data List Characteristic Value + [DIS_IDX_IEEE_VAL] = {ATT_CHAR_IEEE_CERTIF, PERM(RD, ENABLE), PERM(RI, ENABLE), DIS_SYS_ID_LEN}, + + // PnP ID Characteristic Declaration + [DIS_IDX_PNP_ID_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // PnP ID Characteristic Value + [DIS_IDX_PNP_ID_VAL] = {ATT_CHAR_PNP_ID, PERM(RD, ENABLE), PERM(RI, ENABLE), DIS_PNP_ID_LEN}, +}; + + + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the DISS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t diss_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct diss_db_cfg* params) +{ + //------------------ create the attribute database for the profile ------------------- + + // Service content flag + uint32_t cfg_flag; + // DB Creation Statis + uint8_t status = ATT_ERR_NO_ERROR; + + // Compute Attribute Table and save it in environment + cfg_flag = diss_compute_cfg_flag(params->features); + + status = attm_svc_create_db(start_hdl, ATT_SVC_DEVICE_INFO, (uint8_t *)&cfg_flag, + DIS_IDX_NB, NULL, env->task, &diss_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS))); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + struct diss_env_tag* diss_env = + (struct diss_env_tag* ) ke_malloc(sizeof(struct diss_env_tag), KE_MEM_ATT_DB); + + // allocate DISS required environment variable + env->env = (prf_env_t*) diss_env; + diss_env->start_hdl = *start_hdl; + diss_env->features = params->features; + diss_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + diss_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + // initialize environment variable + env->id = TASK_ID_DISS; + diss_task_init(&(env->desc)); + co_list_init(&(diss_env->values)); + + // service is ready, go into an Idle state + ke_state_set(env->task, DISS_IDLE); + } + + return (status); +} +/** + **************************************************************************************** + * @brief Destruction of the DISS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void diss_destroy(struct prf_task_env* env) +{ + struct diss_env_tag* diss_env = (struct diss_env_tag*) env->env; + + // remove all values present in list + while(!co_list_is_empty(&(diss_env->values))) + { + struct co_list_hdr* hdr = co_list_pop_front(&(diss_env->values)); + ke_free(hdr); + } + + // free profile environment variables + env->env = NULL; + ke_free(diss_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void diss_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Nothing to do */ +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void diss_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + /* Nothing to do */ +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// DISS Task interface required by profile manager +const struct prf_task_cbs diss_itf = +{ + (prf_init_fnct) diss_init, + diss_destroy, + diss_create, + diss_cleanup, +}; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* diss_prf_itf_get(void) +{ + return &diss_itf; +} + +uint32_t diss_compute_cfg_flag(uint16_t features) +{ + //Service Declaration + uint32_t cfg_flag = 1; + + for (uint8_t i = 0; i> i) & 1) == 1) + { + cfg_flag |= (3 << (i*2 + 1)); + } + } + + return cfg_flag; +} + + +uint8_t diss_handle_to_value(struct diss_env_tag* env, uint16_t handle) +{ + uint8_t value = DIS_CHAR_MAX; + + // handle cursor, start from first characteristic of service handle + uint16_t cur_hdl = env->start_hdl + 1; + + for (uint8_t i = 0; ifeatures >> i) & 1) == 1) + { + // check if value handle correspond to requested handle + if((cur_hdl +1) == handle) + { + value = i; + break; + } + cur_hdl += 2; + } + } + + return value; +} + +uint16_t diss_value_to_handle(struct diss_env_tag* env, uint8_t value) +{ + uint16_t handle = env->start_hdl + 1; + int8_t i; + + for (i = 0; ifeatures >> i) & 1) == 1) + { + // requested value + if(value == i) + { + handle += 1; + break; + } + handle += 2; + } + } + + // check if handle found + return ((i == DIS_CHAR_MAX) ? ATT_INVALID_HDL : handle); +} + +uint8_t diss_check_val_len(uint8_t char_code, uint8_t val_len) +{ + uint8_t status = GAP_ERR_NO_ERROR; + + // Check if length is upper than the general maximal length + if (val_len > DIS_VAL_MAX_LEN) + { + status = PRF_ERR_UNEXPECTED_LEN; + } + else + { + // Check if length matches particular requirements + switch (char_code) + { + case DIS_SYSTEM_ID_CHAR: + if (val_len != DIS_SYS_ID_LEN) + { + status = PRF_ERR_UNEXPECTED_LEN; + } + break; + case DIS_IEEE_CHAR: + if (val_len < DIS_IEEE_CERTIF_MIN_LEN) + { + status = PRF_ERR_UNEXPECTED_LEN; + } + break; + case DIS_PNP_ID_CHAR: + if (val_len != DIS_PNP_ID_LEN) + { + status = PRF_ERR_UNEXPECTED_LEN; + } + break; + default: + break; + } + } + + return (status); +} + + + +#endif //BLE_DIS_SERVER + +/// @} DISS diff --git a/services/ble_profiles/dis/diss/src/diss.h b/services/ble_profiles/dis/diss/src/diss.h new file mode 100644 index 0000000..1d88492 --- /dev/null +++ b/services/ble_profiles/dis/diss/src/diss.h @@ -0,0 +1,197 @@ +#ifndef DISS_H_ +#define DISS_H_ + +/** + **************************************************************************************** + * @addtogroup DISS Device Information Service Server + * @ingroup DIS + * @brief Device Information Service Server + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_DIS_SERVER) +#include "prf_types.h" +#include "prf.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +#define DISS_IDX_MAX (1) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the DISS task +enum +{ + /// Idle state + DISS_IDLE, + /// Busy state + DISS_BUSY, + /// Number of defined states. + DISS_STATE_MAX +}; + +/// DISS Attributes database handle list +enum diss_att_db_handles +{ + DIS_IDX_SVC, + + DIS_IDX_MANUFACTURER_NAME_CHAR, + DIS_IDX_MANUFACTURER_NAME_VAL, + + DIS_IDX_MODEL_NB_STR_CHAR, + DIS_IDX_MODEL_NB_STR_VAL, + + DIS_IDX_SERIAL_NB_STR_CHAR, + DIS_IDX_SERIAL_NB_STR_VAL, + + DIS_IDX_HARD_REV_STR_CHAR, + DIS_IDX_HARD_REV_STR_VAL, + + DIS_IDX_FIRM_REV_STR_CHAR, + DIS_IDX_FIRM_REV_STR_VAL, + + DIS_IDX_SW_REV_STR_CHAR, + DIS_IDX_SW_REV_STR_VAL, + + DIS_IDX_SYSTEM_ID_CHAR, + DIS_IDX_SYSTEM_ID_VAL, + + DIS_IDX_IEEE_CHAR, + DIS_IDX_IEEE_VAL, + + DIS_IDX_PNP_ID_CHAR, + DIS_IDX_PNP_ID_VAL, + + DIS_IDX_NB, +}; + +/// Value element +struct diss_val_elmt +{ + /// list element header + struct co_list_hdr hdr; + /// value identifier + uint8_t value; + /// value length + uint8_t length; + /// value data + uint8_t data[__ARRAY_EMPTY]; +}; + +///Device Information Service Server Environment Variable +struct diss_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// List of values set by application + struct co_list values; + /// Service Attribute Start Handle + uint16_t start_hdl; + /// Services features + uint16_t features; + /// Last requested value + uint8_t req_val; + /// Last connection index which request value + uint8_t req_conidx; + + /// DISS task state + ke_state_t state[DISS_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve DIS service profile interface + * + * @return DIS service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* diss_prf_itf_get(void); + + +/** + **************************************************************************************** + * @brief Check if an attribute shall be added or not in the database + * + * @param features DIS features + * + * @return Feature config flag + **************************************************************************************** + */ +uint32_t diss_compute_cfg_flag(uint16_t features); + +/** + **************************************************************************************** + * @brief Check if the provided value length matches characteristic requirements + * @param char_code Characteristic Code + * @param val_len Length of the Characteristic value + * + * @return status if value length is ok or not + **************************************************************************************** + */ +uint8_t diss_check_val_len(uint8_t char_code, uint8_t val_len); + +/** + **************************************************************************************** + * @brief Retrieve handle attribute from value + * + * @param[in] env Service environment variable + * @param[in] value Value to search + * + * @return Handle attribute from value + **************************************************************************************** + */ +uint16_t diss_value_to_handle(struct diss_env_tag* env, uint8_t value); + +/** + **************************************************************************************** + * @brief Retrieve value from attribute handle + * + * @param[in] env Service environment variable + * @param[in] handle Attribute handle to search + * + * @return Value from attribute handle + **************************************************************************************** + */ +uint8_t diss_handle_to_value(struct diss_env_tag* env, uint16_t handle); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void diss_task_init(struct ke_task_desc *task_desc); + +#endif //BLE_DIS_SERVER + +/// @} DISS + +#endif // DISS_H_ diff --git a/services/ble_profiles/dis/diss/src/diss_task.c b/services/ble_profiles/dis/diss/src/diss_task.c new file mode 100644 index 0000000..3a741fd --- /dev/null +++ b/services/ble_profiles/dis/diss/src/diss_task.c @@ -0,0 +1,277 @@ +/** + **************************************************************************************** + * @addtogroup DISSTASK + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_DIS_SERVER) +#include "co_utils.h" +#include "gap.h" +#include "gattc_task.h" +#include "diss.h" +#include "diss_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref DISS_SET_VALUE_REQ message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int diss_set_value_req_handler(ke_msg_id_t const msgid, + struct diss_set_value_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Request status + uint8_t status; + // Characteristic Declaration attribute handle + uint16_t handle; + + struct diss_env_tag* diss_env = PRF_ENV_GET(DISS, diss); + struct diss_set_value_rsp* rsp; + // Check Characteristic Code + if (param->value < DIS_CHAR_MAX) + { + // Get Characteristic Declaration attribute handle + handle = diss_value_to_handle(diss_env, param->value); + + // Check if the Characteristic exists in the database + if (handle != ATT_INVALID_HDL) + { + // Check the value length + status = diss_check_val_len(param->value, param->length); + + if (status == GAP_ERR_NO_ERROR) + { + // Check value in already present in service + struct diss_val_elmt *val = (struct diss_val_elmt *) co_list_pick(&(diss_env->values)); + // loop until value found + while(val != NULL) + { + // if value already present, remove old one + if(val->value == param->value) + { + co_list_extract(&(diss_env->values), &(val->hdr)); + ke_free(val); + break; + } + val = (struct diss_val_elmt *)val->hdr.next; + } + + // allocate value data + val = (struct diss_val_elmt *) ke_malloc(sizeof(struct diss_val_elmt) + param->length, KE_MEM_ATT_DB); + val->value = param->value; + val->length = param->length; + memcpy(val->data, param->data, param->length); + // insert value into the list + co_list_push_back(&(diss_env->values), &(val->hdr)); + } + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + + // send response to application + rsp = KE_MSG_ALLOC(DISS_SET_VALUE_RSP, src_id, dest_id, diss_set_value_rsp); + rsp->value = param->value; + rsp->status = status; + ke_msg_send(rsp); + + + return (KE_MSG_CONSUMED); +} + + + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + ke_state_t state = ke_state_get(dest_id); + + if(state == DISS_IDLE) + { + struct diss_env_tag* diss_env = PRF_ENV_GET(DISS, diss); + // retrieve value attribute + uint8_t value = diss_handle_to_value(diss_env, param->handle); + + // Check Characteristic Code + if (value < DIS_CHAR_MAX) + { + // Check value in already present in service + struct diss_val_elmt *val = (struct diss_val_elmt *) co_list_pick(&(diss_env->values)); + // loop until value found + while(val != NULL) + { + // value is present in service + if(val->value == value) + { + break; + } + val = (struct diss_val_elmt *)val->hdr.next; + } + + if(val != NULL) + { + // Send value to peer device. + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, val->length); + cfm->handle = param->handle; + cfm->status = ATT_ERR_NO_ERROR; + cfm->length = val->length; + memcpy(cfm->value, val->data, val->length); + ke_msg_send(cfm); + } + else + { + // request value to application + diss_env->req_val = value; + diss_env->req_conidx = KE_IDX_GET(src_id); + + struct diss_value_req_ind* req_ind = KE_MSG_ALLOC(DISS_VALUE_REQ_IND, + prf_dst_task_get(&(diss_env->prf_env), KE_IDX_GET(src_id)), + dest_id, diss_value_req_ind); + req_ind->value = value; + ke_msg_send(req_ind); + + // Put Service in a busy state + ke_state_set(dest_id, DISS_BUSY); + } + } + else + { + // application error, value cannot be retrieved + struct gattc_read_cfm* cfm = KE_MSG_ALLOC(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm); + cfm->handle = param->handle; + cfm->status = ATT_ERR_APP_ERROR; + ke_msg_send(cfm); + } + } + // postpone request if profile is in a busy state - required for multipoint + else if(state == DISS_BUSY) + { + msg_status = KE_MSG_SAVED; + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the value confirmation from application + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int diss_value_cfm_handler(ke_msg_id_t const msgid, + struct diss_value_cfm const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + ke_state_t state = ke_state_get(dest_id); + + if(state == DISS_BUSY) + { + struct diss_env_tag* diss_env = PRF_ENV_GET(DISS, diss); + // retrieve value attribute + uint16_t handle = diss_value_to_handle(diss_env, diss_env->req_val); + + // chack if application provide correct value + if (diss_env->req_val == param->value) + { + // Send value to peer device. + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, KE_BUILD_ID(TASK_GATTC, diss_env->req_conidx), dest_id, gattc_read_cfm, param->length); + cfm->handle = handle; + cfm->status = ATT_ERR_NO_ERROR; + cfm->length = param->length; + memcpy(cfm->value, param->data, param->length); + ke_msg_send(cfm); + } + else + { + // application error, value provided by application is not the expected one + struct gattc_read_cfm* cfm = KE_MSG_ALLOC(GATTC_READ_CFM, KE_BUILD_ID(TASK_GATTC, diss_env->req_conidx), dest_id, gattc_read_cfm); + cfm->handle = handle; + cfm->status = ATT_ERR_APP_ERROR; + ke_msg_send(cfm); + } + + // return to idle state + ke_state_set(dest_id, DISS_IDLE); + } + // else ignore request if not in busy state + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(diss) +{ + {DISS_SET_VALUE_REQ, (ke_msg_func_t)diss_set_value_req_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t)gattc_read_req_ind_handler}, + {DISS_VALUE_CFM, (ke_msg_func_t)diss_value_cfm_handler}, +}; + +void diss_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct diss_env_tag *diss_env = PRF_ENV_GET(DISS, diss); + + task_desc->msg_handler_tab = diss_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(diss_msg_handler_tab); + task_desc->state = diss_env->state; + task_desc->idx_max = DISS_IDX_MAX; +} + +#endif //BLE_DIS_SERVER + +/// @} DISSTASK diff --git a/services/ble_profiles/find/find_common.h b/services/ble_profiles/find/find_common.h new file mode 100644 index 0000000..1405b3a --- /dev/null +++ b/services/ble_profiles/find/find_common.h @@ -0,0 +1,102 @@ +#ifndef _FIND_COMMON_H_ +#define _FIND_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup FIND Find Profile + * @ingroup PROFILE + * @brief Find Profile + * + * The FIND module is the responsible block for implementing the Find Profile + * functionalities in the BLE Host. + * + * The Find Profile defines the functionality required in a device that allows + * the user (Collector device) to configure and recover Find measurements from + * a Find device. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "prf_types.h" +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/// Find measurement packet max length +#define FIND_MEAS_MAX_LEN (17) +/// Find measurement context packet max length +#define FIND_MEAS_CTX_MAX_LEN (17) +/// Record Access Control Point packet max length +#define FIND_REC_ACCESS_CTRL_MAX_LEN (21) + + +/// Find Service Error Code +enum find_error_code +{ + /// RACP Procedure already in progress + FIND_ERR_PROC_ALREADY_IN_PROGRESS = (0x80), + /// Client Characteristic Configuration Descriptor Improperly Configured + FIND_ERR_IMPROPER_CLI_CHAR_CFG = (0x81), +}; + +/// Record access control point operation filter +struct find_filter +{ + /// function operator + uint8_t operator; + + /// filter type + uint8_t filter_type; + + /// filter union + union + { + /// Sequence number filtering (filter_type = FIND_FILTER_SEQ_NUMBER) + struct + { + /// Min sequence number + uint16_t min; + /// Max sequence number + uint16_t max; + }seq_num; + + /// User facing time filtering (filter_type = FIND_FILTER_USER_FACING_TIME) + struct + { + /// Min base time + struct prf_date_time facetime_min; + + /// Max base time + struct prf_date_time facetime_max; + } time; + } val; +}; + +/// Record access control point request +struct find_racp_req +{ + /// operation code + uint8_t op_code; + + /// operation filter + struct find_filter filter; +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + + +/// @} find_common + +#endif /* _FIND_COMMON_H_ */ diff --git a/services/ble_profiles/find/findl/api/findl_task.h b/services/ble_profiles/find/findl/api/findl_task.h new file mode 100644 index 0000000..ade6884 --- /dev/null +++ b/services/ble_profiles/find/findl/api/findl_task.h @@ -0,0 +1,103 @@ +#ifndef FINDL_TASK_H_ +#define FINDL_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup FINDLTASK Find Me Locator Task + * @ingroup FINDL + * @brief Find Me Locator Task + * + * The FINDLTASK is responsible for handling the API messages coming from the application + * or internal tasks. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" +#include "find_common.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +///Find Me Locator API messages +enum findl_msg_id +{ + /// Start the find me locator profile - at connection + FINDL_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_FINDL), + /// Enable confirm message, containing IAS attribute details if discovery connection type + FINDL_ENABLE_RSP, + + /// Alert level set request + FINDL_SET_ALERT_REQ, + /// Alert level set response + FINDL_SET_ALERT_RSP, +}; + +/// Alert levels +enum +{ + /// No alert + FINDL_ALERT_NONE = 0x00, + /// Mild alert + FINDL_ALERT_MILD, + /// High alert + FINDL_ALERT_HIGH +}; + + +/// Immediate Alert service details container +struct ias_content +{ + /// Service info + struct prf_svc svc; + + /// Characteristic info: + /// - Alert Level + struct prf_char_inf alert_lvl_char; +}; + +/// Parameters of the @ref FINDL_ENABLE_REQ message +struct findl_enable_req +{ + ///Connection type + uint8_t con_type; + ///Discovered IAS details if any + struct ias_content ias; +}; + +/// Parameters of the @ref FINDL_ENABLE_RSP message +struct findl_enable_rsp +{ + ///Status + uint8_t status; + ///Discovered IAS details if any + struct ias_content ias; +}; + +/// Parameters of the @ref FINDL_SET_ALERT_REQ message +struct findl_set_alert_req +{ + /// Alert level + uint8_t alert_lvl; +}; + +///Parameters of the @ref FINDL_SET_ALERT_RSP message +struct findl_set_alert_rsp +{ + /// Status + uint8_t status; +}; + +/// @} FINDLTASK + +#endif // FINDL_TASK_H_ diff --git a/services/ble_profiles/find/findl/src/findl.c b/services/ble_profiles/find/findl/src/findl.c new file mode 100644 index 0000000..6ed43fa --- /dev/null +++ b/services/ble_profiles/find/findl/src/findl.c @@ -0,0 +1,196 @@ +/** + **************************************************************************************** + * @addtogroup FINDL + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_FINDME_LOCATOR) +#include "findl.h" +#include "findl_task.h" +#include "prf_utils.h" +#include "gap.h" + +#include "ke_mem.h" + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialization of the FINDL module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t findl_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, + uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct findl_env_tag* findl_env = + (struct findl_env_tag* ) ke_malloc(sizeof(struct findl_env_tag), KE_MEM_ATT_DB); + + // allocate FINDL required environment variable + env->env = (prf_env_t*) findl_env; + + findl_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + findl_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_FINDL; + findl_task_init(&(env->desc)); + + for(idx = 0; idx < FINDL_IDX_MAX ; idx++) + { + findl_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), FINDL_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Destruction of the FINDL module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void findl_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct findl_env_tag* findl_env = (struct findl_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < FINDL_IDX_MAX ; idx++) + { + if(findl_env->env[idx] != NULL) + { + ke_free(findl_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(findl_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void findl_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put FINDL in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), FINDL_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void findl_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct findl_env_tag* findl_env = (struct findl_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(findl_env->env[conidx] != NULL) + { + ke_free(findl_env->env[conidx]); + findl_env->env[conidx] = NULL; + } + + /* Put FINDL in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), FINDL_FREE); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/// FINDL Task interface required by profile manager +const struct prf_task_cbs findl_itf = +{ + (prf_init_fnct) findl_init, + findl_destroy, + findl_create, + findl_cleanup, +}; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* findl_prf_itf_get(void) +{ + return &findl_itf; +} + +void findl_enable_rsp_send(struct findl_env_tag *findl_env, uint8_t conidx, uint8_t status) +{ + //send response to app + struct findl_enable_rsp * cfm = KE_MSG_ALLOC(FINDL_ENABLE_RSP, + prf_dst_task_get(&(findl_env->prf_env), conidx), + prf_src_task_get(&(findl_env->prf_env), conidx), + findl_enable_rsp); + + cfm->ias = findl_env->env[conidx]->ias; + cfm->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + // Go to idle state + ke_state_set(prf_src_task_get(&(findl_env->prf_env), conidx), FINDL_IDLE); + } + else + { + // clean-up environment variable allocated for task instance + ke_free(findl_env->env[conidx]); + findl_env->env[conidx] = NULL; + } + + ke_msg_send(cfm); +} + +#endif //BLE_FINDME_LOCATOR + +/// @} FINDL diff --git a/services/ble_profiles/find/findl/src/findl.h b/services/ble_profiles/find/findl/src/findl.h new file mode 100644 index 0000000..82a26fa --- /dev/null +++ b/services/ble_profiles/find/findl/src/findl.h @@ -0,0 +1,172 @@ +#ifndef FINDL_H_ +#define FINDL_H_ + +/** + **************************************************************************************** + * @addtogroup FIND Find Me Profile + * @ingroup PROFILE + * @brief Find Me Profile + * + * The FIND module is the responsible block for implementing the Find Me profile + * functionalities in the BLE Host. + * + * The Find Me Profile defines the functionality required in a device that allows the user + * to find a peer device by setting its alarm level. + ***************************************************************************************** + */ + +/** + **************************************************************************************** + * @addtogroup FINDL Find Me Locator + * @ingroup FIND + * @brief Find Me Profile Locator + * + * The FINDL is responsible for providing Find Me profile Locator functionalities to + * upper layer module or application. The device using this profile takes the role + * of find me locator. + * + * Find Me Locator (LOC): A LOC (e.g. PC, phone, etc) + * is the term used by this profile to describe a device that can set an alarm level value + * in the peer Find Me target Device (TG), causing the TG to start a sound or flashing light + * or other type of signal allowing it to be located. + * + * The interface of this role to the Application is: + * - Enable the profile role (from APP) + * - Disable the profile role (from APP) + * - Discover Immediate Alert Service range(from APP) and Send result (to APP) + * - Discover Alert Level Characteristic in the IAS range(from APP) and Send Result (to APP) + * - Set alert level in Target (from APP) + * - Error indications (to APP) + * + * The application should remember the discovered IAS range and Alert Level Char. handles + * for the next connection to a known peer (that may also advertise it supports Find Me Profile.) + * This allows the setting of the alert level to be faster. + * + * The enable/disable of the profile and devices disconnection is handled in the application, + * depending on its User Input. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_FINDME_LOCATOR) +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "findl_task.h" + +/* + * DEFINES + **************************************************************************************** + */ + +///Maximum number of Find me Locator task instances +#define FINDL_IDX_MAX (BLE_CONNECTION_MAX) + + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Possible states of the FINDL task +enum findl_state +{ + /// Not Connected State + FINDL_FREE, + /// Idle state + FINDL_IDLE, + /// Discovering state + FINDL_DISCOVERING, + /// Busy State + FINDL_BUSY, + + /// Number of defined states. + FINDL_STATE_MAX +}; +enum +{ + FINDL_ALERT_LVL_CHAR, + + FINDL_IAS_CHAR_MAX, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Environment variable for each Connections +struct findl_cnx_env +{ + /// Found IAS details + struct ias_content ias; + /// Last char. code requested to read. + uint8_t last_char_code; + /// counter used to check service uniqueness + uint8_t nb_svc; +}; + +/// Find me Locator environment variable +struct findl_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct findl_cnx_env* env[FINDL_IDX_MAX]; + /// State of different task instances + ke_state_t state[FINDL_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve IAS service profile interface + * + * @return IAS service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* findl_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Enable Confirm message to the application. + * @param status Status to send. + **************************************************************************************** + */ +void findl_enable_rsp_send(struct findl_env_tag *findl_env, uint8_t conidx, uint8_t status); + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void findl_task_init(struct ke_task_desc *task_desc); + + +#endif //BLE_FINDME_LOCATOR + +/// @} FINDL +#endif // FINDL_H_ diff --git a/services/ble_profiles/find/findl/src/findl_task.c b/services/ble_profiles/find/findl/src/findl_task.c new file mode 100644 index 0000000..b1e2019 --- /dev/null +++ b/services/ble_profiles/find/findl/src/findl_task.c @@ -0,0 +1,305 @@ +/** + **************************************************************************************** + * @addtogroup FINDLTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_FINDME_LOCATOR) +#include "co_utils.h" +#include "findl_task.h" +#include "findl.h" +#include "gattc_task.h" +#include "prf_utils.h" +#include "gap.h" +#include "gapc.h" +#include "gapc_task.h" +#include + +#include "ke_mem.h" + +/// table used to retrieve immediate alert service characteristics information +const struct prf_char_def findl_ias_char[FINDL_IAS_CHAR_MAX] = +{ + [FINDL_ALERT_LVL_CHAR] = {ATT_CHAR_ALERT_LEVEL, + ATT_MANDATORY, + ATT_CHAR_PROP_WR_NO_RESP}, +}; + + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref FINDL_ENABLE_REQ message. + * The handler enables the Find Me profile - Locator Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int findl_enable_req_handler(ke_msg_id_t const msgid, + struct findl_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Find me Locator Role Task Environment + struct findl_env_tag *findl_env = PRF_ENV_GET(FINDL, findl); + + ASSERT_INFO(findl_env != NULL, dest_id, src_id); + if((state == FINDL_IDLE) && (findl_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + findl_env->env[conidx] = (struct findl_cnx_env*) ke_malloc(sizeof(struct findl_cnx_env),KE_MEM_ATT_DB); + memset(findl_env->env[conidx], 0, sizeof(struct findl_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering IAS on peer + prf_disc_svc_send(&(findl_env->prf_env), conidx, ATT_SVC_IMMEDIATE_ALERT); + + // Go to DISCOVERING state + ke_state_set(dest_id, FINDL_DISCOVERING); + } + //normal connection, get saved att details + else + { + findl_env->env[conidx]->ias = param->ias; + + //send APP confirmation that can start normal connection to TH + findl_enable_rsp_send(findl_env, conidx, GAP_ERR_NO_ERROR); + } + } + else if(state != FINDL_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + findl_enable_rsp_send(findl_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == FINDL_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct findl_env_tag *findl_env = PRF_ENV_GET(FINDL, findl); + + ASSERT_INFO(findl_env != NULL, dest_id, src_id); + ASSERT_INFO(findl_env->env[conidx] != NULL, dest_id, src_id); + + if(findl_env->env[conidx]->nb_svc == 0) + { + // Retrieve IAS characteristic + prf_extract_svc_info(ind, FINDL_IAS_CHAR_MAX, &findl_ias_char[0], + &(findl_env->env[conidx]->ias.alert_lvl_char), 0, NULL, NULL); + + //Even if we get multiple responses we only store 1 range + findl_env->env[conidx]->ias.svc.shdl = ind->start_hdl; + findl_env->env[conidx]->ias.svc.ehdl = ind->end_hdl; + } + + findl_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref FINDL_SET_ALERT_REQ message. + * The handler disables the Find Me profile - Target Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int findl_set_alert_req_handler(ke_msg_id_t const msgid, + struct findl_set_alert_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get the address of the environment + struct findl_env_tag *findl_env = PRF_ENV_GET(FINDL, findl); + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + int msg_status = KE_MSG_CONSUMED; + + if(state == FINDL_IDLE) + { + // check if discovery performed + if(findl_env->env[conidx] == NULL) + { + status = PRF_ERR_REQ_DISALLOWED; + } + //Check we're sending a correct value + else if ((param->alert_lvl == FINDL_ALERT_NONE) || + (param->alert_lvl == FINDL_ALERT_MILD) || + (param->alert_lvl == FINDL_ALERT_HIGH)) + { + if(findl_env->env[conidx]->ias.alert_lvl_char.char_hdl != 0x0000) + { + // Send GATT Write Request + prf_gatt_write(&findl_env->prf_env, conidx, + findl_env->env[conidx]->ias.alert_lvl_char.val_hdl, + (uint8_t *)¶m->alert_lvl, sizeof(uint8_t), GATTC_WRITE_NO_RESPONSE); + // wait for end of write request + ke_state_set(dest_id, FINDL_BUSY); + } + else + { + //cannot set alert level because have no char handle for it + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + //wrong level - not one of the possible 3 + status = PRF_ERR_INVALID_PARAM; + } + + struct findl_set_alert_rsp *rsp = KE_MSG_ALLOC(FINDL_SET_ALERT_RSP, + src_id, dest_id, findl_set_alert_rsp); + // set error status + rsp->status = status; + + ke_msg_send(rsp); + } + else if(state != FINDL_FREE) + { + msg_status = KE_MSG_SAVED;; + } + // else nothing to do - ignore message + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + // Get the address of the environment + struct findl_env_tag *findl_env = PRF_ENV_GET(FINDL, findl); + uint8_t conidx = KE_IDX_GET(dest_id); + + + if(state == FINDL_DISCOVERING) + { + uint8_t status = param->status; + + if (param->status == ATT_ERR_NO_ERROR) + { + if(findl_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(FINDL_IAS_CHAR_MAX, + &(findl_env->env[conidx]->ias.alert_lvl_char), findl_ias_char); + } + // too much services + else if (findl_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + + findl_enable_rsp_send(findl_env, conidx, status); + } + else if (state == FINDL_BUSY) + { + ke_state_set(dest_id, FINDL_IDLE); + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(findl) +{ + {FINDL_ENABLE_REQ, (ke_msg_func_t)findl_enable_req_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {FINDL_SET_ALERT_REQ, (ke_msg_func_t)findl_set_alert_req_handler}, +}; + +void findl_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct findl_env_tag *findl_env = PRF_ENV_GET(FINDL, findl); + + task_desc->msg_handler_tab = findl_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(findl_msg_handler_tab); + task_desc->state = findl_env->state; + task_desc->idx_max = FINDL_IDX_MAX; +} + +#endif //BLE_FINDME_LOCATOR + +/// @} FINDLTASK diff --git a/services/ble_profiles/find/findt/api/findt_task.h b/services/ble_profiles/find/findt/api/findt_task.h new file mode 100644 index 0000000..dccb533 --- /dev/null +++ b/services/ble_profiles/find/findt/api/findt_task.h @@ -0,0 +1,62 @@ +#ifndef FINDT_TASK_H_ +#define FINDT_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup FINDTTASK Find Me Target Task + * @ingroup FINDT + * @brief Find Me Target Task + * + * The FINDTTASK is responsible for handling the APi messages from the application or + * internal tasks. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include "rwip_task.h" // Task definitions +#include "find_common.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +/// Messages for Find Me Target +enum findt_msg_id +{ + /// Alert indication + FINDT_ALERT_IND = TASK_FIRST_MSG(TASK_ID_FINDT), +}; + + +/// Parameters of the @ref FINDT_ALERT_IND message +struct findt_alert_ind +{ + /// Alert level + uint8_t alert_lvl; + /// Connection index + uint8_t conidx; +}; + + +/* + * API MESSAGES STRUCTURES + **************************************************************************************** + */ +/// Parameters for the database creation +struct findt_db_cfg +{ + /// Database configuration + uint8_t dummy; +}; + + +/// @} FINDTTASK +#endif // FINDT_TASK_H_ diff --git a/services/ble_profiles/find/findt/src/findt.c b/services/ble_profiles/find/findt/src/findt.c new file mode 100644 index 0000000..25ab80f --- /dev/null +++ b/services/ble_profiles/find/findt/src/findt.c @@ -0,0 +1,171 @@ +/** + **************************************************************************************** + * @addtogroup FINDT + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_FINDME_TARGET) +#include "findt.h" +#include "findt_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" + +/* + * FINDT PROFILE ATTRIBUTES + **************************************************************************************** + */ +/// Full IAS Database Description - Used to add attributes into the database +const struct attm_desc findt_att_db[FINDT_IAS_IDX_NB] = +{ + // Immediate Alert Service Declaration + [FINDT_IAS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + // Alert Level Characteristic Declaration + [FINDT_IAS_IDX_ALERT_LVL_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Alert Level Characteristic Value + [FINDT_IAS_IDX_ALERT_LVL_VAL] = {ATT_CHAR_ALERT_LEVEL, PERM(WRITE_COMMAND, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, +}; + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the FINDT module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t findt_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, + uint8_t sec_lvl, struct findt_db_cfg* params) +{ + //------------------ create the attribute database for the profile ------------------- + + // Service content flag + uint32_t cfg_flag = FINDT_MANDATORY_MASK; + // DB Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + status = attm_svc_create_db(start_hdl, ATT_SVC_IMMEDIATE_ALERT, (uint8_t *)&cfg_flag, + FINDT_IAS_IDX_NB, NULL, env->task, &findt_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, DISABLE) ); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + struct findt_env_tag* findt_env = + (struct findt_env_tag* ) ke_malloc(sizeof(struct findt_env_tag), KE_MEM_ATT_DB); + + // allocate FINDT required environment variable + env->env = (prf_env_t*) findt_env; + findt_env->shdl = *start_hdl; + findt_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + findt_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + + // initialize environment variable + env->id = TASK_ID_FINDT; + findt_task_init(&(env->desc)); + + // service is ready, go into an Idle state + ke_state_set(env->task, FINDT_IDLE); + } + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the FINDT module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void findt_destroy(struct prf_task_env* env) +{ + struct findt_env_tag* findt_env = (struct findt_env_tag*) env->env; + + // free profile environment variables + env->env = NULL; + ke_free(findt_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void findt_create(struct prf_task_env* env, uint8_t conidx) +{ + /* nothing to do */ +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void findt_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + /* nothing to do */ +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// FINDT Task interface required by profile manager +const struct prf_task_cbs findt_itf = +{ + (prf_init_fnct) findt_init, + findt_destroy, + findt_create, + findt_cleanup, +}; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* findt_prf_itf_get(void) +{ + return &findt_itf; +} + + +#endif //BLE_FINDME_TARGET + +/// @} FINDT diff --git a/services/ble_profiles/find/findt/src/findt.h b/services/ble_profiles/find/findt/src/findt.h new file mode 100644 index 0000000..82849de --- /dev/null +++ b/services/ble_profiles/find/findt/src/findt.h @@ -0,0 +1,154 @@ +#ifndef FINDT_H_ +#define FINDT_H_ + +/** + **************************************************************************************** + * @addtogroup FINDT Find Me Target + * @ingroup FIND + * @brief Find Me Profile Target. + * + * In the Find Me BLE Profile, the device that is in Target role will act as GATT server. + * + * The Target will react to alert levels written by the Locator in the Alert Level + * Characteristic of the Immediate Alert Service(IAS) present in the ATT DB of the device. + * + * The interface of this role to the Application is: + * - Enable the profile role (from APP) + * - Disable the profile role (from APP) + * - Indicate that the alert level has been written by the Locator. (to APP) + * + * There shall be only one IAS instance on the device. There shall be only one + * Alert Level Characteristic in the IAS. The characteristic properties shall be + * Write No Response only. + * + * The enable/disable of the profile and devices disconnection is handled in the application, + * depending on its User Input. + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#include "find_common.h" +#if (BLE_FINDME_TARGET) +#include +#include +#include "gap.h" +#include "prf_types.h" +#include "prf_utils.h" + +/* + * DEFINES + **************************************************************************************** + */ + +///Maximum number of instances of the Find Me Target task +#define FINDT_IDX_MAX 0x01 + +#define FINDT_MANDATORY_MASK (0x07) + +/// Possible states of the FINDT task +enum findt_state +{ + /// Idle state + FINDT_IDLE, + + /// Number of defined states. + FINDT_STATE_MAX +}; + +/// Find Me Target environment variable +struct findt_env_tag +{ + /// profile environment + prf_env_t prf_env; + ///IAS Start Handle + uint16_t shdl; + /// State of different task instances + ke_state_t state[FINDT_IDX_MAX]; +}; + +/* + * MACROS + **************************************************************************************** + */ + +/// Get database attribute handle +#define FINDT_HANDLE(idx) \ + (findt_env->start_hdl + (idx) ) + +/// Get database attribute index +#define FINDT_IDX(hdl) \ + ( (hdl) - findt_env->shdl ) + + +/* + * ENUMS + **************************************************************************************** + */ + +///FINDT Attributes database handle list +enum findt_att_db_handles +{ + FINDT_IAS_IDX_SVC, + + FINDT_IAS_IDX_ALERT_LVL_CHAR, + FINDT_IAS_IDX_ALERT_LVL_VAL, + + FINDT_IAS_IDX_NB, +}; + +/// Alert levels +enum +{ + /// No alert + FINDT_ALERT_NONE = 0x00, + /// Mild alert + FINDT_ALERT_MILD, + /// High alert + FINDT_ALERT_HIGH +}; + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve IAS service profile interface + * + * @return IAS service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* findt_prf_itf_get(void); + + +/* + * GLOBAL VARIABLES DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void findt_task_init(struct ke_task_desc *task_desc); +#endif //BLE_FINDME_TARGET + +/// @} FINDT + +#endif // FINDT_H_ diff --git a/services/ble_profiles/find/findt/src/findt_task.c b/services/ble_profiles/find/findt/src/findt_task.c new file mode 100644 index 0000000..ccb9303 --- /dev/null +++ b/services/ble_profiles/find/findt/src/findt_task.c @@ -0,0 +1,109 @@ +/** + **************************************************************************************** + * @addtogroup FINDTTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_FINDME_TARGET) +#include "co_utils.h" +#include "gattc_task.h" +#include "findt_task.h" +#include "findt.h" +#include "attm.h" +#include "prf_utils.h" + + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_WRITE_REQ_IND message. + * The message is redirected from TASK_SVC because at profile enable, the ATT handle is + * register for TASK_FINDT. In the handler, an ATT Write Response/Error Response should + * be sent for ATT protocol, but Alert Level Characteristic only supports WNR so no + * response PDU is needed. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t alert_lvl = 0x0000; + uint8_t conidx = KE_IDX_GET(src_id); + // Allocate write confirmation message. + struct gattc_write_cfm *cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, + src_id, dest_id, gattc_write_cfm); + + // Get the address of the environment + struct findt_env_tag *findt_env = PRF_ENV_GET(FINDT, findt); + uint8_t att_idx = FINDT_IDX(param->handle); + + // Fill in the parameter structure + cfm->handle = param->handle; + cfm->status = PRF_APP_ERROR; + + //Check if Alert Level is valid + if((att_idx == FINDT_IAS_IDX_ALERT_LVL_VAL) && (param->value[0] <= FINDT_ALERT_HIGH)) + { + alert_lvl = param->value[0]; + cfm->status = GAP_ERR_NO_ERROR; + + // Allocate the alert value change indication + struct findt_alert_ind *ind = KE_MSG_ALLOC(FINDT_ALERT_IND, + prf_dst_task_get(&(findt_env->prf_env), conidx), + dest_id, findt_alert_ind); + // Fill in the parameter structure + ind->alert_lvl = alert_lvl; + ind->conidx = conidx; + + // Send the message + ke_msg_send(ind); + } + + // Send the message + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(findt) +{ + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, +}; + +void findt_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct findt_env_tag *findt_env = PRF_ENV_GET(FINDT, findt); + + task_desc->msg_handler_tab = findt_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(findt_msg_handler_tab); + task_desc->state = findt_env->state; + task_desc->idx_max = FINDT_IDX_MAX; +} + +#endif //BLE_FINDME_TARGET + +/// @} FINDTTASK diff --git a/services/ble_profiles/gfps/Makefile b/services/ble_profiles/gfps/Makefile new file mode 100644 index 0000000..cb689b3 --- /dev/null +++ b/services/ble_profiles/gfps/Makefile @@ -0,0 +1,16 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)gfps_crypto/*.c)) + +#CRYPTO_LIB_NAME := libgfps_crypto +#$(CRYPTO_LIB_NAME)-y := $(obj_c:.c=.o) + +libgfps_crypto-y := $(obj_c:.c=.o) +obj-y := libgfps_crypto.a +subdir-ccflags-y += \ + -Igfps_crypto/ \ + -Iutils/encrypt \ + -Iapi/ + + + diff --git a/services/ble_profiles/gfps/api/gfps_crypto.h b/services/ble_profiles/gfps/api/gfps_crypto.h new file mode 100644 index 0000000..b6be235 --- /dev/null +++ b/services/ble_profiles/gfps/api/gfps_crypto.h @@ -0,0 +1,21 @@ +#ifndef _GFPS_PROVIDER_CRYPTO_H_ +#define _GFPS_PROVIDER_CRYPTO_H_ +#include "prf_utils.h" + +void gfps_crypto_init(void); + +uint32_t gfps_crypto_get_secret_decrypt(const uint8_t* in_encryptdata ,const uint8_t *in_public_key,uint8_t * out_key,uint8_t *out_decryptdata ); +uint32_t gfps_crypto_encrypt(const uint8_t *in_data,uint8_t len,const uint8_t *AESkey,uint8_t *out_encrypt); +uint32_t gfps_crypto_decrypt(const uint8_t *in_data,uint8_t len,const uint8_t *AESkey,uint8_t *out_encrypt); +uint32_t gfps_crypto_gen_DHKey(const uint8_t *in_PubKey,const uint8_t *in_PrivateKey,uint8_t *out_DHKey); + +uint32_t gfps_crypto_make_P256_key(uint8_t * out_public_key,uint8_t * out_private_key); +uint32_t gfps_crypto_set_p256_key(const uint8_t* in_public_key,const uint8_t* in_private_key); +uint32_t gfps_SHA256_hash(const void* in_data, int len, void* out_data); +void gfps_encrypt_name(uint8_t* aesKey, uint8_t* inputRawName, uint32_t inputLen, + uint8_t* outputEncryptedName, uint8_t* hmacFirst8Bytes, uint8_t* nonce); +bool gfps_decrypt_name(uint8_t* aesKey, uint8_t* hmacFirst8Bytes, + uint8_t* nonce, uint8_t* encryptedName, uint8_t* rawName, uint32_t nameLen); + +#endif + diff --git a/services/ble_profiles/gfps/gfps_provider/api/gfps_provider.h b/services/ble_profiles/gfps/gfps_provider/api/gfps_provider.h new file mode 100644 index 0000000..ded9410 --- /dev/null +++ b/services/ble_profiles/gfps/gfps_provider/api/gfps_provider.h @@ -0,0 +1,278 @@ +#ifndef GFPSP_H_ +#define GFPSP_H_ + +/** + **************************************************************************************** + * @addtogroup GFPSP google fast pair s + * @ingroup DIS + * @brief Device Information Service Server + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_GFPS_PROVIDER) +#include "prf_types.h" +#include "prf.h" + + +/* + * DEFINES + **************************************************************************************** + */ +#define RAW_REQ_FLAGS_DISCOVERABILITY_BIT0_EN (1) +#define RAW_REQ_FLAGS_DISCOVERABILITY_BIT0_DIS (0) +#define RAW_REQ_FLAGS_INTBONDING_SEEKERADDR_BIT1_EN (1) +#define RAW_REQ_FLAGS_INTBONDING_SEEKERADDR_BIT1_DIS (0) + +#define GFPSP_KEY_BASED_PAIRING_REQ_LEN_WITH_PUBLIC_KEY (80) +#define GFPSP_KEY_BASED_PAIRING_REQ_LEN_WITHOUT_PUBLIC_KEY (16) + +#define GFPSP_IDX_MAX (BLE_CONNECTION_MAX) + +#define GFPSP_ENCRYPTED_RSP_LEN 16 + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the GFPSP task +enum +{ + /// Idle state + GFPSP_IDLE, + /// Busy state + GFPSP_BUSY, + /// Number of defined states. + GFPSP_STATE_MAX +}; + +/// GFPSP Attributes database handle list +enum gfpsp_att_db_handles +{ + GFPSP_IDX_SVC, + + GFPSP_IDX_KEY_BASED_PAIRING_CHAR, + GFPSP_IDX_KEY_BASED_PAIRING_VAL, + GFPSP_IDX_KEY_BASED_PAIRING_NTF_CFG, + + GFPSP_IDX_PASSKEY_CHAR, + GFPSP_IDX_PASSKEY_VAL, + GFPSP_IDX_PASSKEY_NTF_CFG, + + GFPSP_IDX_ACCOUNT_KEY_CHAR, + GFPSP_IDX_ACCOUNT_KEY_VAL, + GFPSP_IDX_ACCOUNT_KEY_CFG, + + GFPSP_IDX_NAME_CHAR, + GFPSP_IDX_NAME_VAL, + GFPSP_IDX_NAME_CFG, + + GFPSP_IDX_NB, +}; + +/// Value element +struct gfpsp_val_elmt +{ + /// list element header + struct co_list_hdr hdr; + /// value identifier + uint8_t value; + /// value length + uint8_t length; + /// value data + uint8_t data[__ARRAY_EMPTY]; +}; + +///Device Information Service Server Environment Variable +struct gfpsp_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// List of values set by application + struct co_list values; + /// Service Attribute Start Handle + uint16_t start_hdl; + /// Services features + uint16_t features; + /// Last requested value + uint8_t req_val; + /// Last connection index which request value + uint8_t req_conidx; + + /// GFPSP task state + ke_state_t state[GFPSP_IDX_MAX]; +}; + +typedef struct _gfpsp_encrypted_req_uint128{ + uint8_t uint128_array[16]; +}gfpsp_encrypted_req_uint128; + +typedef struct _gfpsp_64B_public_key_{ + uint8_t public_key_64B[64]; +}gfpsp_64B_public_key; + +typedef enum +{ + KEY_BASED_PAIRING_REQ = 0x00, + KEY_BASED_PAIRING_RSP = 0x01, + ACTION_REQUEST = 0x10, +} GFPS_MESSAGE_TYPE_E; + +typedef struct { + uint8_t message_type; + uint8_t reserved[15]; +} gfpsp_raw_req_t; + +typedef struct { + uint8_t message_type; // KEY_BASED_PAIRING_REQ + uint8_t flags_reserved : 4; + uint8_t flags_retroactively_write_account_key : 1; + uint8_t flags_get_existing_name : 1; + uint8_t flags_bonding_addr : 1; + uint8_t flags_discoverability : 1; + + uint8_t provider_addr[6]; + uint8_t seeker_addr[6]; + uint8_t reserved[2]; +} gfpsp_key_based_pairing_req_t; + +typedef struct { + uint8_t message_type; // ACTION_REQUEST + uint8_t flags_reserved : 6; + uint8_t isFollowedByAdditionalDataCh : 1; + uint8_t isDeviceAction : 1; + + uint8_t provider_addr[6]; + uint8_t messageGroup; // Mandatory if Flags Bit 1 is set. + uint8_t messageCode; // Mandatory if Flags Bit 1 is set. + uint8_t additionalDataLen; // Mandatory if Flags Bit 1 is set. Less than 6 + uint8_t additionalData[6]; // Mandatory if Flags Bit 1 is set. +} gfpsp_action_req_t; + +typedef struct { + uint8_t message_type; // KEY_BASED_PAIRING_RSP + uint8_t provider_addr[6]; + uint8_t salt[9]; +}gfpsp_raw_resp; + +typedef struct _gfpsp_raw_passkey_resp{ + uint8_t message_type; + uint8_t passkey[3]; + uint8_t reserved[12]; +}gfpsp_raw_pass_key_resp; + +typedef struct _gfpsp_encrypted_resp{ + uint8_t uint128_array[GFPSP_ENCRYPTED_RSP_LEN]; +}gfpsp_encrypted_resp; + +typedef struct _gfpsp_req_resp{ + union{ + gfpsp_raw_req_t raw_req; + gfpsp_encrypted_req_uint128 en_req; + gfpsp_key_based_pairing_req_t key_based_pairing_req; + gfpsp_action_req_t action_req; + gfpsp_raw_resp key_based_pairing_rsp; + gfpsp_encrypted_resp en_rsp; + }rx_tx; +}gfpsp_req_resp; + + +typedef struct _gfpsp_Key_based_Pairing_req{ + gfpsp_encrypted_req_uint128 * en_req; + gfpsp_64B_public_key * pub_key; +}gfpsp_Key_based_Pairing_req; + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve DIS service profile interface + * + * @return DIS service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* gfpsp_prf_itf_get(void); + + +/** + **************************************************************************************** + * @brief Check if an attribute shall be added or not in the database + * + * @param features DIS features + * + * @return Feature config flag + **************************************************************************************** + */ +uint32_t gfpsp_compute_cfg_flag(uint16_t features); + +/** + **************************************************************************************** + * @brief Check if the provided value length matches characteristic requirements + * @param char_code Characteristic Code + * @param val_len Length of the Characteristic value + * + * @return status if value length is ok or not + **************************************************************************************** + */ +uint8_t gfpsp_check_val_len(uint8_t char_code, uint8_t val_len); + +/** + **************************************************************************************** + * @brief Retrieve handle attribute from value + * + * @param[in] env Service environment variable + * @param[in] value Value to search + * + * @return Handle attribute from value + **************************************************************************************** + */ +uint16_t gfpsp_value_to_handle(struct gfpsp_env_tag* env, uint8_t value); + +/** + **************************************************************************************** + * @brief Retrieve value from attribute handle + * + * @param[in] env Service environment variable + * @param[in] handle Attribute handle to search + * + * @return Value from attribute handle + **************************************************************************************** + */ +uint8_t gfpsp_handle_to_value(struct gfpsp_env_tag* env, uint16_t handle); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void gfpsp_task_init(struct ke_task_desc *task_desc); + +uint32_t gfpsp_crypto_gen_DHKey(const uint8_t *in_PubKey,const uint8_t *in_PrivateKey,uint8_t *out_DHKey); +uint32_t gfpsp_crypto_make_P256_key(uint8_t * out_public_key,uint8_t * out_private_key); + +#endif //BLE_GFPSP_SERVER + +/// @} GFPSP + +#endif // GFPSP_H_ diff --git a/services/ble_profiles/gfps/gfps_provider/api/gfps_provider_errors.h b/services/ble_profiles/gfps/gfps_provider/api/gfps_provider_errors.h new file mode 100644 index 0000000..29c51ac --- /dev/null +++ b/services/ble_profiles/gfps/gfps_provider/api/gfps_provider_errors.h @@ -0,0 +1,13 @@ +#ifndef _GFPS_PROVIDER_ERRORS_H_ +#define _GFPS_PROVIDER_ERRORS_H_ + +enum{ +GFPS_SUCCESS, +GFPS_ERROR_EXEC_FAIL, +GFPS_ERROR_NULL, +GFPS_ERROR_INVALID_PARAM, +GFPS_ERROR_DATA_SIZE +}; +#define Gfps_CheckParm(code, exp) if (!(exp)) return (code) + +#endif diff --git a/services/ble_profiles/gfps/gfps_provider/api/gfps_provider_task.h b/services/ble_profiles/gfps/gfps_provider/api/gfps_provider_task.h new file mode 100644 index 0000000..0f4c9f5 --- /dev/null +++ b/services/ble_profiles/gfps/gfps_provider/api/gfps_provider_task.h @@ -0,0 +1,190 @@ +#ifndef GFPSP_TASK_H_ +#define GFPSP_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup GFPSPTASK Task + * @ingroup GFPSP + * @brief Device Information Service Server Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include "rwip_task.h" // Task definitions +#include "prf_types.h" + +/* + * DEFINES + **************************************************************************************** + */ + + + +/// Messages for Device Information Service Server +enum +{ + //port msg use to reference .. + ///Set the value of an attribute - Request + GFPSP_SET_VALUE_REQ = TASK_FIRST_MSG(TASK_ID_GFPSP), + ///Set the value of an attribute - Response + GFPSP_SET_VALUE_RSP, + /// Peer device request to get profile attribute value + GFPSP_VALUE_REQ_IND, + /// Peer device confirm value of requested attribute + GFPSP_VALUE_CFM, + + GFPSP_KEY_BASED_PAIRING_NTF_CFG, + GFPSP_KEY_BASED_PAIRING_WRITE_IND, + GFPSP_KEY_BASED_PAIRING_WRITE_NOTIFY, + + GFPSP_KEY_PASS_KEY_NTF_CFG, + GFPSP_KEY_PASS_KEY_WRITE_IND, + GFPSP_KEY_PASS_KEY_WRITE_NOTIFY, + + GFPSP_KEY_ACCOUNT_KEY_WRITE_IND, + GFPSP_NAME_WRITE_IND, + GFPSP_NAME_NOTIFY, + + GFPSP_SEND_WRITE_RESPONSE, + +}; + +///Attribute Table Indexes +enum gfpsp_info +{ + /// Manufacturer Name + GFPSP_MANUFACTURER_NAME_CHAR, + /// Model Number + GFPSP_MODEL_NB_STR_CHAR, + /// Serial Number + GFPSP_SERIAL_NB_STR_CHAR, + /// HW Revision Number + GFPSP_HARD_REV_STR_CHAR, + /// FW Revision Number + GFPSP_FIRM_REV_STR_CHAR, + /// SW Revision Number + GFPSP_SW_REV_STR_CHAR, + /// System Identifier Name + GFPSP_SYSTEM_ID_CHAR, + /// IEEE Certificate + GFPSP_IEEE_CHAR, + /// Plug and Play Identifier + GFPSP_PNP_ID_CHAR, + + GFPSP_CHAR_MAX, +}; + +///Database Configuration Flags +enum gfpsp_features +{ + ///Indicate if Manufacturer Name String Char. is supported + GFPSP_MANUFACTURER_NAME_CHAR_SUP = 0x0001, + ///Indicate if Model Number String Char. is supported + GFPSP_MODEL_NB_STR_CHAR_SUP = 0x0002, + ///Indicate if Serial Number String Char. is supported + GFPSP_SERIAL_NB_STR_CHAR_SUP = 0x0004, + ///Indicate if Hardware Revision String Char. supports indications + GFPSP_HARD_REV_STR_CHAR_SUP = 0x0008, + ///Indicate if Firmware Revision String Char. is writable + GFPSP_FIRM_REV_STR_CHAR_SUP = 0x0010, + ///Indicate if Software Revision String Char. is writable + GFPSP_SW_REV_STR_CHAR_SUP = 0x0020, + ///Indicate if System ID Char. is writable + GFPSP_SYSTEM_ID_CHAR_SUP = 0x0040, + ///Indicate if IEEE Char. is writable + GFPSP_IEEE_CHAR_SUP = 0x0080, + ///Indicate if PnP ID Char. is writable + GFPSP_PNP_ID_CHAR_SUP = 0x0100, + + ///All features are supported + GFPSP_ALL_FEAT_SUP = 0x01FF, +}; +/* + * API MESSAGES STRUCTURES + **************************************************************************************** + */ + +/// Parameters for the database creation +struct gfpsp_db_cfg +{ + /// Database configuration @see enum gfpsp_features + uint16_t features; +}; + + +///Set the value of an attribute - Request +struct gfpsp_set_value_req +{ + /// Value to Set + uint8_t value; + /// Value length + uint8_t length; + /// Value data + uint8_t data[__ARRAY_EMPTY]; +}; + +///Set the value of an attribute - Response +struct gfpsp_set_value_rsp +{ + /// Value Set + uint8_t value; + /// status of the request + uint8_t status; +}; + +/// Peer device request to get profile attribute value +struct gfpsp_value_req_ind +{ + /// Requested value + uint8_t value; +}; + +/// Peer device value of requested attribute +struct gfpsp_value_cfm +{ + /// Requested value + uint8_t value; + /// Value length + uint8_t length; + /// Value data + uint8_t data[__ARRAY_EMPTY]; +}; + +struct gfpsp_send_write_rsp_t +{ + uint16_t src_task_id; + uint16_t dst_task_id; + uint16_t handle; + uint16_t status; +}; + +struct gfpsp_write_ind_t +{ + struct gfpsp_send_write_rsp_t pendingWriteRsp; + uint16_t length; + uint8_t data[0]; +}; +struct gfpsp_send_data_req_t +{ + uint8_t connecionIndex; + uint32_t length; + uint8_t value[__ARRAY_EMPTY]; +}; + +struct app_gfps_key_based_notif_config_t +{ + bool isNotificationEnabled; +}; + +struct app_gfps_pass_key_notif_config_t +{ + bool isNotificationEnabled; +}; + +/// @} GFPSPTASK +#endif // GFPSP_TASK_H_ diff --git a/services/ble_profiles/gfps/gfps_provider/src/gfps_provider.c b/services/ble_profiles/gfps/gfps_provider/src/gfps_provider.c new file mode 100644 index 0000000..05994ec --- /dev/null +++ b/services/ble_profiles/gfps/gfps_provider/src/gfps_provider.c @@ -0,0 +1,413 @@ +/** + **************************************************************************************** + * @addtogroup GFPSP + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_GFPS_PROVIDER) +#include "attm.h" +#include "gfps_provider.h" +#include "gfps_provider_task.h" +#include "gfps_crypto.h" +#include "prf_utils.h" +#include "prf.h" + +#include "ke_mem.h" + +#include "nvrecord_fp_account_key.h" + +/* + * MACROS + **************************************************************************************** + */ + +/// Maximal length for Characteristic values - 128 bytes +#define GFPSP_VAL_MAX_LEN (128) +///System ID string length +#define GFPSP_SYS_ID_LEN (0x08) +///IEEE Certif length (min 6 bytes) +#define GFPSP_IEEE_CERTIF_MIN_LEN (0x06) +///PnP ID length +#define GFPSP_PNP_ID_LEN (0x07) + +#define GFPS_USE_128BIT_UUIDx + +#ifdef GFPS_USE_128BIT_UUID + +static const uint8_t ATT_SVC_GOOGLE_FAST_PAIR_PROVIDER[ATT_UUID_16_LEN] = {0x2C, 0xFE}; + +/*------------------- UNITS ---------------------*/ + +/*---------------- DECLARATIONS -----------------*/ +#define ATT_DECL_PRIMARY_SERVICE_UUID { 0x00, 0x28 } +#define ATT_DECL_CHARACTERISTIC_UUID { 0x03, 0x28 } +#define ATT_DESC_CLIENT_CHAR_CFG_UUID { 0x02, 0x29 } + +/*----------------- DESCRIPTORS -----------------*/ +/*--------------- CHARACTERISTICS ---------------*/ +#define ATT_CHAR_KEY_BASED_PAIRING {0xEA, 0x0B, 0x10, 0x32, 0xDE, 0x01, 0xB0, 0x8E, 0x14, 0x48, 0x66, 0x83, 0x34, 0x12, 0x2C, 0xFE} +#define ATT_CHAR_PASSKEY {0xEA, 0x0B, 0x10, 0x32, 0xDE, 0x01, 0xB0, 0x8E, 0x14, 0x48, 0x66, 0x83, 0x35, 0x12, 0x2C, 0xFE} +#define ATT_CHAR_ACCOUNTKEY {0xEA, 0x0B, 0x10, 0x32, 0xDE, 0x01, 0xB0, 0x8E, 0x14, 0x48, 0x66, 0x83, 0x36, 0x12, 0x2C, 0xFE} +#define ATT_CHAR_NAME {0xEA, 0x0B, 0x10, 0x32, 0xDE, 0x01, 0xB0, 0x8E, 0x14, 0x48, 0x66, 0x83, 0x37, 0x12, 0x2C, 0xFE} + +/* + * DIS ATTRIBUTES + **************************************************************************************** + */ + +const struct attm_desc_128 gfpsp_att_db[GFPSP_IDX_NB] = +{ + // Google fast pair service provider Declaration + [GFPSP_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE_UUID, PERM(RD, ENABLE), 0, 0}, + + [GFPSP_IDX_KEY_BASED_PAIRING_CHAR] = {ATT_DECL_CHARACTERISTIC_UUID, PERM(RD, ENABLE), 0, 0}, + [GFPSP_IDX_KEY_BASED_PAIRING_VAL] = {ATT_CHAR_KEY_BASED_PAIRING, PERM(NTF, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE) | PERM_VAL(UUID_LEN, PERM_UUID_128), GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_KEY_BASED_PAIRING_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG_UUID, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), sizeof(uint16_t)}, + + + [GFPSP_IDX_PASSKEY_CHAR] = {ATT_DECL_CHARACTERISTIC_UUID, PERM(RD, ENABLE), 0, 0}, + [GFPSP_IDX_PASSKEY_VAL] = {ATT_CHAR_PASSKEY, PERM(NTF, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE) | PERM_VAL(UUID_LEN, PERM_UUID_128), GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_PASSKEY_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG_UUID, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), sizeof(uint16_t)}, + + [GFPSP_IDX_ACCOUNT_KEY_CHAR] = {ATT_DECL_CHARACTERISTIC_UUID, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_ACCOUNT_KEY_VAL] = {ATT_CHAR_ACCOUNTKEY, PERM(NTF, ENABLE) |PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE) | PERM_VAL(UUID_LEN, PERM_UUID_128), GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_ACCOUNT_KEY_CFG] = {ATT_DESC_CLIENT_CHAR_CFG_UUID, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), GFPSP_VAL_MAX_LEN}, + + [GFPSP_IDX_NAME_CHAR] = {ATT_DECL_CHARACTERISTIC_UUID, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_NAME_VAL] = {ATT_CHAR_NAME, PERM(NTF, ENABLE) |PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE) | PERM_VAL(UUID_LEN, PERM_UUID_128), GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_NAME_CFG] = {ATT_DESC_CLIENT_CHAR_CFG_UUID, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), GFPSP_VAL_MAX_LEN}, + +}; +#else +enum { + +/*----------------- SERVICES ---------------------*/ +/// +ATT_SVC_GOOGLE_FAST_PAIR_PROVIDER = ATT_UUID_16(0xFE2C), +/*------------------- UNITS ---------------------*/ + +/*---------------- DECLARATIONS -----------------*/ +/*----------------- DESCRIPTORS -----------------*/ +/*--------------- CHARACTERISTICS ---------------*/ +ATT_CHAR_KEY_BASED_PAIRING = ATT_UUID_16(0x1234), +ATT_CHAR_PASSKEY = ATT_UUID_16(0x1235), +ATT_CHAR_ACCOUNTKEY = ATT_UUID_16(0x1236), +ATT_CHAR_NAME = ATT_UUID_16(0x1237), +}; +/* + * DIS ATTRIBUTES + **************************************************************************************** + */ + +const struct attm_desc gfpsp_att_db[GFPSP_IDX_NB] = +{ + // Google fast pair service provider Declaration + [GFPSP_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + [GFPSP_IDX_KEY_BASED_PAIRING_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + [GFPSP_IDX_KEY_BASED_PAIRING_VAL] = {ATT_CHAR_KEY_BASED_PAIRING, PERM(NTF, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_KEY_BASED_PAIRING_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), sizeof(uint16_t)}, + + + [GFPSP_IDX_PASSKEY_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + [GFPSP_IDX_PASSKEY_VAL] = {ATT_CHAR_PASSKEY, PERM(NTF, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_PASSKEY_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), sizeof(uint16_t)}, + + [GFPSP_IDX_ACCOUNT_KEY_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_ACCOUNT_KEY_VAL] = {ATT_CHAR_ACCOUNTKEY, PERM(NTF, ENABLE) |PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_ACCOUNT_KEY_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), GFPSP_VAL_MAX_LEN}, + + [GFPSP_IDX_NAME_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_NAME_VAL] = {ATT_CHAR_NAME, PERM(NTF, ENABLE) |PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), GFPSP_VAL_MAX_LEN}, + [GFPSP_IDX_NAME_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), GFPSP_VAL_MAX_LEN}, + +}; +#endif + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the GFPSP module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t gfpsp_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct gfpsp_db_cfg* params) +{ + //------------------ create the attribute database for the profile ------------------- + + // Service content flag + uint32_t cfg_flag; + // DB Creation Statis + uint8_t status = ATT_ERR_NO_ERROR; + + + // Compute Attribute Table and save it in environment + cfg_flag = gfpsp_compute_cfg_flag(params->features); + +#ifdef GFPS_USE_128BIT_UUID + status = attm_svc_create_db_128(start_hdl, ATT_SVC_GOOGLE_FAST_PAIR_PROVIDER, (uint8_t *)&cfg_flag, + GFPSP_IDX_NB, NULL, env->task, &gfpsp_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS))); +#else + status = attm_svc_create_db(start_hdl, ATT_SVC_GOOGLE_FAST_PAIR_PROVIDER, (uint8_t *)&cfg_flag, + GFPSP_IDX_NB, NULL, env->task, &gfpsp_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS))); +#endif + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + struct gfpsp_env_tag* gfpsp_env = + (struct gfpsp_env_tag* ) ke_malloc(sizeof(struct gfpsp_env_tag), KE_MEM_ATT_DB); + + // allocate GFPSP required environment variable + env->env = (prf_env_t*) gfpsp_env; + gfpsp_env->start_hdl = *start_hdl; + gfpsp_env->features = params->features; + gfpsp_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + gfpsp_env->prf_env.prf_task = env->task | + (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + + // initialize environment variable + env->id = TASK_ID_GFPSP; + gfpsp_task_init(&(env->desc)); + co_list_init(&(gfpsp_env->values)); + + // service is ready, go into an Idle state + ke_state_set(env->task, GFPSP_IDLE); + } + + return (status); +} +/** + **************************************************************************************** + * @brief Destruction of the GFPSP module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void gfpsp_destroy(struct prf_task_env* env) +{ + struct gfpsp_env_tag* gfpsp_env = (struct gfpsp_env_tag*) env->env; + + // remove all values present in list + while(!co_list_is_empty(&(gfpsp_env->values))) + { + struct co_list_hdr* hdr = co_list_pop_front(&(gfpsp_env->values)); + ke_free(hdr); + } + + // free profile environment variables + env->env = NULL; + ke_free(gfpsp_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void gfpsp_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Nothing to do */ +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void gfpsp_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + /* Nothing to do */ +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// GFPSP Task interface required by profile manager +const struct prf_task_cbs gfpsp_itf = +{ + (prf_init_fnct) gfpsp_init, + gfpsp_destroy, + gfpsp_create, + gfpsp_cleanup, +}; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* gfpsp_prf_itf_get(void) +{ + return &gfpsp_itf; +} + +uint32_t gfpsp_compute_cfg_flag(uint16_t features) +{ + //Service Declaration + uint32_t cfg_flag = 1; + + for (uint8_t i = 0; i> i) & 1) == 1) + { + cfg_flag |= (3 << (i*2 + 1)); + } + } + + return cfg_flag; +} + + +uint8_t gfpsp_handle_to_value(struct gfpsp_env_tag* env, uint16_t handle) +{ + uint8_t value = GFPSP_CHAR_MAX; + + // handle cursor, start from first characteristic of service handle + uint16_t cur_hdl = env->start_hdl + 1; + + for (uint8_t i = 0; ifeatures >> i) & 1) == 1) + { + // check if value handle correspond to requested handle + if((cur_hdl +1) == handle) + { + value = i; + break; + } + cur_hdl += 2; + } + } + + return value; +} + +uint16_t gfpsp_value_to_handle(struct gfpsp_env_tag* env, uint8_t value) +{ + uint16_t handle = env->start_hdl + 1; + int8_t i; + + for (i = 0; ifeatures >> i) & 1) == 1) + { + // requested value + if(value == i) + { + handle += 1; + break; + } + handle += 2; + } + } + + // check if handle found + return ((i == GFPSP_CHAR_MAX) ? ATT_INVALID_HDL : handle); +} + +uint8_t gfpsp_check_val_len(uint8_t char_code, uint8_t val_len) +{ + uint8_t status = GAP_ERR_NO_ERROR; + + // Check if length is upper than the general maximal length + if (val_len > GFPSP_VAL_MAX_LEN) + { + status = PRF_ERR_UNEXPECTED_LEN; + } + else + { + // Check if length matches particular requirements + switch (char_code) + { + case GFPSP_SYSTEM_ID_CHAR: + if (val_len != GFPSP_SYS_ID_LEN) + { + status = PRF_ERR_UNEXPECTED_LEN; + } + break; + case GFPSP_IEEE_CHAR: + if (val_len < GFPSP_IEEE_CERTIF_MIN_LEN) + { + status = PRF_ERR_UNEXPECTED_LEN; + } + break; + case GFPSP_PNP_ID_CHAR: + if (val_len != GFPSP_PNP_ID_LEN) + { + status = PRF_ERR_UNEXPECTED_LEN; + } + break; + default: + break; + } + } + + return (status); +} + + +uint32_t gfpsp_crypto_gen_DHKey(const uint8_t *in_PubKey,const uint8_t *in_PrivateKey,uint8_t *out_DHKey) +{ + return gfps_crypto_gen_DHKey(in_PubKey,in_PrivateKey,out_DHKey); +} + +uint32_t gfpsp_crypto_make_P256_key(uint8_t * out_public_key,uint8_t * out_private_key) +{ + return gfps_crypto_make_P256_key(out_public_key,out_private_key); +} + +#else + +uint32_t gfpsp_crypto_gen_DHKey(const uint8_t *in_PubKey,const uint8_t *in_PrivateKey,uint8_t *out_DHKey) +{ + return 1; +} + +uint32_t gfpsp_crypto_make_P256_key(uint8_t * out_public_key,uint8_t * out_private_key) +{ + return 1; +} + +#endif //BLE_GFPSP_SERVER + +/// @} GFPSP diff --git a/services/ble_profiles/gfps/gfps_provider/src/gfps_provider_task.c b/services/ble_profiles/gfps/gfps_provider/src/gfps_provider_task.c new file mode 100644 index 0000000..739994f --- /dev/null +++ b/services/ble_profiles/gfps/gfps_provider/src/gfps_provider_task.c @@ -0,0 +1,338 @@ +/** + **************************************************************************************** + * @addtogroup GFPS STASK + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_GFPS_PROVIDER) +#include + +#include "co_utils.h" +#include "gap.h" +#include "gattc_task.h" +#include "gfps_provider.h" +//#include "crypto.h" +#include "gfps_provider_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ +static void send_notifiction(uint8_t conidx, uint8_t contentType, const uint8_t* ptrData, uint32_t length) +{ + struct gfpsp_env_tag* gfpsp_env = PRF_ENV_GET(GFPSP, gfpsp); + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *report_ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&gfpsp_env->prf_env, conidx), + gattc_send_evt_cmd, length); + + // Fill in the parameter structure + report_ntf->operation = GATTC_NOTIFY; + report_ntf->handle = gfpsp_env->start_hdl + contentType;//GFPSP_IDX_KEY_BASED_PAIRING_VAL;//handle_offset; + // pack measured value in database + report_ntf->length = length; + memcpy(report_ntf->value, ptrData, length); + // send notification to peer device + ke_msg_send(report_ntf); +} + +__STATIC int send_data_via_notification_handler(ke_msg_id_t const msgid, + struct gfpsp_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + send_notifiction(param->connecionIndex, GFPSP_IDX_KEY_BASED_PAIRING_VAL, param->value, param->length); + return (KE_MSG_CONSUMED); +} + +__STATIC int send_passkey_data_via_notification_handler(ke_msg_id_t const msgid, + struct gfpsp_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + send_notifiction(param->connecionIndex, GFPSP_IDX_PASSKEY_VAL, param->value, param->length); + return (KE_MSG_CONSUMED); +} + +__STATIC int send_name_via_notification_handler(ke_msg_id_t const msgid, + struct gfpsp_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + send_notifiction(param->connecionIndex, GFPSP_IDX_NAME_VAL, param->value, param->length); + return (KE_MSG_CONSUMED); +} + + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of write request message. + * The handler will analyse what has been set and decide alert level + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +uint8_t Encrypted_req[80]={ + 0xb9,0x7b,0x2c,0x4b,0x84,0x59,0x3e,0x69,0xf9,0xc5, + 0x1c,0x6f,0xf9,0xba,0x7e,0xc0,0x27,0xa6,0x13,0x55, + 0x26,0x84,0xbc,0xa2,0xd8,0x95,0xd6,0xf8,0xdd,0x5e, + 0xb5,0x91,0xfe,0xf7,0x31,0x1c,0x19,0x3e,0x38,0x8e, + 0x5f,0x3a,0xe6,0x6b,0x68,0x46,0xc4,0x14,0x1c,0x03, + 0xcb,0xc3,0x18,0x06,0x6b,0x52,0xd9,0x5c,0xa0,0xa2, + 0xb5,0x80,0xd9,0x90,0x4b,0xed,0x46,0x23,0x22,0x9b, + 0x42,0xe7,0xc2,0xde,0x2e,0x2a,0xba,0x7c,0xac,0x2b +}; + +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct gfpsp_env_tag* gfpsp_env = PRF_ENV_GET(GFPSP, gfpsp); + uint8_t conidx = KE_IDX_GET(src_id); + + uint8_t status = GAP_ERR_NO_ERROR; + + if (GFPSP_IDX_KEY_BASED_PAIRING_VAL != (param->handle-gfpsp_env->start_hdl) && + (GFPSP_IDX_NAME_VAL != (param->handle-gfpsp_env->start_hdl))) + { + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + } + + if (gfpsp_env != NULL) + { + switch (param->handle-gfpsp_env->start_hdl) + { + case GFPSP_IDX_KEY_BASED_PAIRING_VAL: + { + //inform APP of data + struct gfpsp_write_ind_t * ind = KE_MSG_ALLOC_DYN(GFPSP_KEY_BASED_PAIRING_WRITE_IND, + prf_dst_task_get(&gfpsp_env->prf_env, conidx), + prf_src_task_get(&gfpsp_env->prf_env, conidx), + gfpsp_write_ind_t, + param->length); + ind->length = param->length; + ind->pendingWriteRsp.dst_task_id = src_id; + ind->pendingWriteRsp.src_task_id = dest_id; + ind->pendingWriteRsp.handle = param->handle; + memcpy((uint8_t *)(ind->data),&(param->value), param->length); + + ke_msg_send(ind); + break; + } + case GFPSP_IDX_KEY_BASED_PAIRING_NTF_CFG: + { + uint16_t value = 0x0000; + memcpy(&value, &(param->value), sizeof(uint16_t)); + struct app_gfps_key_based_notif_config_t * ind = KE_MSG_ALLOC(GFPSP_KEY_BASED_PAIRING_NTF_CFG, + prf_dst_task_get(&gfpsp_env->prf_env, conidx), + prf_src_task_get(&gfpsp_env->prf_env, conidx), + app_gfps_key_based_notif_config_t); + + ind->isNotificationEnabled = value; + ke_msg_send(ind); + break; + } + case GFPSP_IDX_PASSKEY_NTF_CFG: + { + uint16_t value = 0x0000; + memcpy(&value, &(param->value), sizeof(uint16_t)); + struct app_gfps_pass_key_notif_config_t * ind = KE_MSG_ALLOC(GFPSP_KEY_PASS_KEY_NTF_CFG, + prf_dst_task_get(&gfpsp_env->prf_env, conidx), + prf_src_task_get(&gfpsp_env->prf_env, conidx), + app_gfps_pass_key_notif_config_t); + + ind->isNotificationEnabled = value; + ke_msg_send(ind); + break; + } + case GFPSP_IDX_PASSKEY_VAL: + { + //inform APP of data + struct gfpsp_write_ind_t * ind = KE_MSG_ALLOC_DYN(GFPSP_KEY_PASS_KEY_WRITE_IND, + prf_dst_task_get(&gfpsp_env->prf_env, conidx), + prf_src_task_get(&gfpsp_env->prf_env, conidx), + gfpsp_write_ind_t, + param->length); + ind->length = param->length; + memcpy((uint8_t *)(ind->data),&(param->value), param->length); + + ke_msg_send(ind); + break; + } + case GFPSP_IDX_ACCOUNT_KEY_VAL: + { + TRACE(0,"Get account key:"); + DUMP8("%02x ", param->value, param->length); + struct gfpsp_write_ind_t * ind = KE_MSG_ALLOC_DYN(GFPSP_KEY_ACCOUNT_KEY_WRITE_IND, + prf_dst_task_get(&gfpsp_env->prf_env, conidx), + prf_src_task_get(&gfpsp_env->prf_env, conidx), + gfpsp_write_ind_t, + param->length); + ind->length = param->length; + memcpy((uint8_t *)(ind->data),&(param->value), param->length); + + ke_msg_send(ind); + break; + } + case GFPSP_IDX_NAME_VAL: + { + TRACE(0,"Get updated name:"); + DUMP8("%02x ", param->value, param->length); + + struct gfpsp_write_ind_t * ind = KE_MSG_ALLOC_DYN(GFPSP_NAME_WRITE_IND, + prf_dst_task_get(&gfpsp_env->prf_env, conidx), + prf_src_task_get(&gfpsp_env->prf_env, conidx), + gfpsp_write_ind_t, + param->length); + ind->length = param->length; + ind->pendingWriteRsp.dst_task_id = src_id; + ind->pendingWriteRsp.src_task_id = dest_id; + ind->pendingWriteRsp.handle = param->handle; + memcpy((uint8_t *)(ind->data),&(param->value), param->length); + + ke_msg_send(ind); + break; + } + default: + { + break; + } + } + } + + return (KE_MSG_CONSUMED); +} + +__STATIC int gfpsp_send_write_rsp_handler(ke_msg_id_t const msgid, + struct gfpsp_send_write_rsp_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, param->dst_task_id, param->src_task_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = param->status; + ke_msg_send(cfm); + + return KE_MSG_CONSUMED; +} + +static int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct gattc_att_info_cfm * cfm; + + + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + struct gfpsp_env_tag* gfpsp_env = PRF_ENV_GET(GFPSP, gfpsp); + + TRACE(1,"gattc_att_info_req_ind_handler, is %d",param->handle-gfpsp_env->start_hdl); + + if (param->handle == (gfpsp_env->start_hdl + GFPSP_KEY_BASED_PAIRING_NTF_CFG)) { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } else if (param->handle == (gfpsp_env->start_hdl + GFPSP_KEY_PASS_KEY_NTF_CFG)) { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } else if (param->handle == (gfpsp_env->start_hdl + GFPSP_IDX_ACCOUNT_KEY_CFG)) { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } else if (param->handle == (gfpsp_env->start_hdl + GFPSP_IDX_NAME_CFG)) { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } else if (param->handle == (gfpsp_env->start_hdl + GFPSP_IDX_KEY_BASED_PAIRING_VAL)) { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } else if (param->handle == (gfpsp_env->start_hdl + GFPSP_IDX_PASSKEY_VAL)) { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } else if (param->handle == (gfpsp_env->start_hdl + GFPSP_IDX_ACCOUNT_KEY_VAL)) { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } else if (param->handle == (gfpsp_env->start_hdl + GFPSP_IDX_NAME_VAL)) { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } + else { + cfm->length = 0; + cfm->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ +// +/// Default State handlers definition +KE_MSG_HANDLER_TAB(gfpsp) +{ + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GFPSP_KEY_BASED_PAIRING_WRITE_NOTIFY, (ke_msg_func_t)send_data_via_notification_handler}, + {GFPSP_KEY_PASS_KEY_WRITE_NOTIFY, (ke_msg_func_t)send_passkey_data_via_notification_handler}, + {GFPSP_NAME_NOTIFY, (ke_msg_func_t)send_name_via_notification_handler}, + {GFPSP_SEND_WRITE_RESPONSE, (ke_msg_func_t)gfpsp_send_write_rsp_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t)gattc_att_info_req_ind_handler }, +}; + +void gfpsp_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct gfpsp_env_tag *gfpsp_env = PRF_ENV_GET(GFPSP, gfpsp); + + task_desc->msg_handler_tab = gfpsp_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(gfpsp_msg_handler_tab); + task_desc->state = gfpsp_env->state; + task_desc->idx_max = GFPSP_IDX_MAX; +} + +#endif //BLE_GFPS_SERVER + +/// @} DISSTASK diff --git a/services/ble_profiles/glp/glp_common.h b/services/ble_profiles/glp/glp_common.h new file mode 100644 index 0000000..ab1eb85 --- /dev/null +++ b/services/ble_profiles/glp/glp_common.h @@ -0,0 +1,623 @@ +#ifndef _GLP_COMMON_H_ +#define _GLP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup GLP Glucose Profile + * @ingroup PROFILE + * @brief Glucose Profile + * + * The GLP module is the responsible block for implementing the Glucose Profile + * functionalities in the BLE Host. + * + * The Glucose Profile defines the functionality required in a device that allows + * the user (Collector device) to configure and recover Glucose measurements from + * a Glucose device. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "prf_types.h" +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/// Glucose measurement packet max length +#define GLP_MEAS_MAX_LEN (17) +/// Glucose measurement context packet max length +#define GLP_MEAS_CTX_MAX_LEN (17) +/// Record Access Control Point packet max length +#define GLP_REC_ACCESS_CTRL_MAX_LEN (21) + + +/// Glucose Service Error Code +enum glp_error_code +{ + /// RACP Procedure already in progress + GLP_ERR_PROC_ALREADY_IN_PROGRESS = (0x80), + /// Client Characteristic Configuration Descriptor Improperly Configured + GLP_ERR_IMPROPER_CLI_CHAR_CFG = (0x81), +}; + +/// Glucose Measurement Flags field bit values +enum glp_meas_flag +{ + /// Time Offset Present Bit + /// Time Offset Present + GLP_MEAS_TIME_OFF_PRES = (1 << 0), + /// Time Offset Not Present + GLP_MEAS_TIME_OFF_NOT_PRES = (0 << 0), + + /// Glucose Concentration, Type and Sample Location Present Bit + /// Glucose Concentration, Type and Sample Location Present + GLP_MEAS_GL_CTR_TYPE_AND_SPL_LOC_PRES = (1 << 1), + /// Glucose Concentration, Type and Sample Location Not Present + GLP_MEAS_GL_CTR_TYPE_AND_SPL_LOC_NOT_PRES = (0 << 1), + + /// Glucose Concentration Units (kg/L, mol/L) + GLP_MEAS_GL_CTR_UNITS_KG_L = (0 << 2), + GLP_MEAS_GL_CTR_UNITS_MOL_L = (1 << 2), + + /// Sensor Status Annunciation Present Bit + /// Sensor Status Annunciation Present + GLP_MEAS_SENS_STAT_ANNUN_PRES = (1 << 3), + /// Sensor Status Annunciation Not Present + GLP_MEAS_SENS_STAT_ANNUN_NOT_PRES = (0 << 3), + + /// Context Information Follow Bit + /// Context Information Follows + GLP_MEAS_CTX_INF_FOLW = (1 << 4), + /// Context Information Not Follows + GLP_MEAS_CTX_INF_NOT_FOLW = (0 << 4), +}; + +/// Glucose Measurement Context Flags field bit values +enum glp_meas_ctx_flag +{ + /// Carbohydrate ID And Carbohydrate Present Bit + /// Carbohydrate ID And Carbohydrate Present + GLP_CTX_CRBH_ID_AND_CRBH_PRES = (1 << 0), + /// Carbohydrate ID And Carbohydrate Not Present + GLP_CTX_CRBH_ID_AND_CRBH_NOT_PRES = (0 << 0), + + /// Meal Present Bit + /// Meal Present + GLP_CTX_MEAL_PRES = (1 << 1), + /// Meal Not Present + GLP_CTX_MEAL_NOT_PRES = (0 << 1), + + /// Tester-Health Present Bit + /// Tester-Health Present + GLP_CTX_TESTER_HEALTH_PRES = (1 << 2), + /// Tester-Health Not Present + GLP_CTX_TESTER_HEALTH_NOT_PRES = (0 << 2), + + /// Exercise Duration And Exercise Intensity Present Bit + /// Exercise Duration And Exercise Intensity Present + GLP_CTX_EXE_DUR_AND_EXE_INTENS_PRES = (1 << 3), + /// Exercise Duration And Exercise Intensity Not Present + GLP_CTX_EXE_DUR_AND_EXE_INTENS_NOT_PRES = (0 << 3), + + /// Medication ID And Medication Present Bit + /// Medication ID And Medication Present + GLP_CTX_MEDIC_ID_AND_MEDIC_PRES = (1 << 4), + /// Medication ID And Medication Not Present + GLP_CTX_MEDIC_ID_AND_MEDIC_NOT_PRES = (0 << 4), + + /// Medication Value Units (kilograms, liters) + GLP_CTX_MEDIC_VAL_UNITS_KG = (0 << 5), + GLP_CTX_MEDIC_VAL_UNITS_L = (1 << 5), + + /// HbA1c Present Bit + /// HbA1c Present + GLP_CTX_HBA1C_PRES = (1 << 6), + /// HbA1c Not Present + GLP_CTX_HBA1C_NOT_PRES = (0 << 6), + + /// Extended Flags Present Bit + /// Extended Flags Present + GLP_CTX_EXTD_F_PRES = (1 << 7), + /// Extended Flags Not Present + GLP_CTX_EXTD_F_NOT_PRES = (0 << 7), +}; + +/// Glucose Service Feature Flags field bit values +enum glp_srv_feature_flag +{ + /// Low Battery Detection During Measurement Support Bit + /// Low Battery Detection During Measurement Supported + GLP_FET_LOW_BAT_DET_DUR_MEAS_SUPP = (1 << 0), + /// Low Battery Detection During Measurement Not Supported + GLP_FET_LOW_BAT_DET_DUR_MEAS_NOT_SUPP = (0 << 0), + + /// Sensor Malfunction Detection Support Bit + /// Sensor Malfunction Detection Supported + GLP_FET_SENS_MFNC_DET_SUPP = (1 << 1), + /// Sensor Malfunction Detection Not Supported + GLP_FET_SENS_MFNC_DET_NOT_SUPP = (0 << 1), + + /// Sensor Sample Size Support Bit + /// Sensor Sample Size Supported + GLP_FET_SENS_SPL_SIZE_SUPP = (1 << 2), + /// Sensor Sample Size Not Supported + GLP_FET_SENS_SPL_SIZE_NOT_SUPP = (0 << 2), + + /// Sensor Strip Insertion Error Detection Support Bit + /// Sensor Strip Insertion Error Detection Supported + GLP_FET_SENS_STRIP_INSERT_ERR_DET_SUPP = (1 << 3), + /// Sensor Strip Insertion Error Detection Not Supported + GLP_FET_SENS_STRIP_INSERT_ERR_DET_NOT_SUPP = (0 << 3), + + /// Sensor Strip Type Error Detection Support Bit + /// Sensor Strip Type Error Detection Supported + GLP_FET_SENS_STRIP_TYPE_ERR_DET_SUPP = (1 << 4), + /// Sensor Strip Type Error Detection Not Supported + GLP_FET_SENS_STRIP_TYPE_ERR_DET_NOT_SUPP = (0 << 4), + + /// Sensor Result High-Low Detection Support Bit + /// Sensor Result High-Low Detection Supported + GLP_FET_SENS_RES_HIGH_LOW_DET_SUPP = (1 << 5), + /// Sensor Result High-Low Detection Not Supported + GLP_FET_SENS_RES_HIGH_LOW_DET_NOT_SUPP = (0 << 5), + + /// Sensor Temperature High-Low Detection Support Bit + /// Sensor Temperature High-Low Detection Supported + GLP_FET_SENS_TEMP_HIGH_LOW_DET_SUPP = (1 << 6), + /// Sensor Temperature High-Low Detection Not Supported + GLP_FET_SENS_TEMP_HIGH_LOW_DET_NOT_SUPP = (0 << 6), + + /// Sensor Read Interrupt Detection Support Bit + /// Sensor Read Interrupt Detection Supported + GLP_FET_SENS_RD_INT_DET_SUPP = (1 << 7), + /// Sensor Read Interrupt Detection Not Supported + GLP_FET_SENS_RD_INT_DET_NOT_SUPP = (0 << 7), + + /// General Device Fault Support Bit + /// General Device Fault Supported + GLP_FET_GEN_DEV_FLT_SUPP = (1 << 8), + /// General Device Fault Not Supported + GLP_FET_GEN_DEV_FLT_NOT_SUPP = (0 << 8), + + /// Time Fault Support Bit + /// Time Fault Supported + GLP_FET_TIME_FLT_SUPP = (1 << 9), + /// Time Fault Not Supported + GLP_FET_TIME_FLT_NOT_SUPP = (0 << 9), + + /// Multiple Bond Support Bit + /// Multiple Bond Supported + GLP_FET_MUL_BOND_SUPP = (1 << 10), + /// Multiple Bond Not Supported + GLP_FET_MUL_BOND_NOT_SUPP = (0 << 10), +}; + + +/// Glucose measurement type +enum glp_meas_type +{ + /// Capillary Whole blood + GLP_TYPE_CAPILLARY_WHOLE_BLOOD = (1), + + /// Capillary Plasma + GLP_TYPE_CAPILLARY_PLASMA = (2), + + /// Venous Whole blood + GLP_TYPE_VENOUS_WHOLE_BLOOD = (3), + + /// Venous Plasma + GLP_TYPE_VENOUS_PLASMA = (4), + + /// Arterial Whole blood + GLP_TYPE_ARTERIAL_WHOLE_BLOOD = (5), + + /// Arterial Plasma + GLP_TYPE_ARTERIAL_PLASMA = (6), + + /// Undetermined Whole blood + GLP_TYPE_UNDETERMINED_WHOLE_BLOOD = (7), + + /// Undetermined Plasma + GLP_TYPE_UNDETERMINED_PLASMA = (8), + + /// Interstitial Fluid (ISF) + GLP_TYPE_INTERSTITIAL_FLUID = (9), + + /// Control Solution + GLP_TYPE_CTRL_SOLUTION = (10), +}; + + +/// Glucose measurement Sample Location +enum glp_meas_loc +{ + /// Finger + GLP_LOC_FINGER = (1), + + /// Alternate Site Test (AST) + GLP_LOC_ALT_SITE_TEST = (2), + + /// Earlobe + GLP_LOC_EARLOBE = (3), + + /// Control solution + GLP_LOC_CTRL_SOLUTION = (4), + + /// Sample Location value not available + GLP_LOC_SPL_LOC_VAL_NOT_AVA = (15), +}; + +/// Glucose measurement Sensor Status Annunciation +enum glp_meas_state +{ + /// Device battery low at time of measurement + GLP_MEAS_STATE_DEV_BAT_LOW = (1 << 0), + + /// Sensor malfunction or faulting at time of measurement + GLP_MEAS_STATE_SENS_MFNC_OR_FLTING = (1 << 1), + + /// Sample size for blood or control solution insufficient at time of measurement + GLP_MEAS_STATE_SPL_SIZE_INSUFF = (1 << 2), + + /// Strip insertion error + GLP_MEAS_STATE_STRIP_INSERT_ERR = (1 << 3), + + /// Strip type incorrect for device + GLP_MEAS_STATE_STRIP_TYPE_INCOR_FOR_DEV = (1 << 4), + + /// Sensor result higher than the device can process + GLP_MEAS_STATE_SENS_RES_HIGHER = (1 << 5), + + /// Sensor result lower than the device can process + GLP_MEAS_STATE_SENS_RES_LOWER = (1 << 6), + + /// Sensor temperature too high for valid test/result at time of measurement + GLP_MEAS_STATE_SENS_TEMP_TOO_HIGH = (1 << 7), + + /// Sensor temperature too low for valid test/result at time of measurement + GLP_MEAS_STATE_SENS_TEMP_TOO_LOW = (1 << 8), + + /// Sensor read interrupted because strip was pulled too soon at time of measurement + GLP_MEAS_STATE_SENS_RD_INTED = (1 << 9), + + /// General device fault has occurred in the sensor + GLP_MEAS_STATE_GEN_DEV_FLT = (1 << 10), + + /// Time fault has occurred in the sensor and time may be inaccurate + GLP_MEAS_STATE_TIME_FLT = (1 << 11), +}; + + +/// Glucose measurement context Carbohydrate ID +enum glp_meas_ctx_carbo +{ + /// Breakfast + GLP_CID_BREAKFAST = (1), + + /// Lunch + GLP_CID_LUNCH = (2), + + /// Dinner + GLP_CID_DINNER = (3), + + /// Snack + GLP_CID_SNACK = (4), + + /// Drink + GLP_CID_DRINK = (5), + + /// Supper + GLP_CID_SUPPER = (6), + + /// Brunch + GLP_CID_BRUNCH = (7), +}; + +/// Glucose measurement context Meal +enum glp_meas_ctx_meal +{ + /// Preprandial (before meal) + GLP_MEAL_PREPRANDIAL = (1), + + /// Postprandial (after meal) + GLP_MEAL_POSTPRANDIAL = (2), + + /// Fasting + GLP_MEAL_FASTING = (3), + + /// Casual (snacks, drinks, etc.) + GLP_MEAL_CASUAL = (4), + + /// Bedtime + GLP_MEAL_BEDTIME = (5), +}; + +/// Glucose measurement context tester type +enum glp_meas_ctx_tester_type +{ + /// Self + GLP_TESTER_SELF = (1), + + /// Health Care Professional + GLP_TESTER_HEALTH_CARE_PROFESSIONAL = (2), + + /// Lab test + GLP_TESTER_LAB_TEST = (3), + + /// Tester value not available + GLP_TESTER_TESTER_VAL_NOT_AVA = (15), +}; + +/// Glucose measurement context personal health feeling +enum glp_meas_ctx_feeling +{ + /// Minor health issues + GLP_HEALTH_MINOR_HEALTH_ISSUES = (1), + + /// Major health issues + GLP_HEALTH_MAJOR_HEALTH_ISSUES = (2), + + /// During menses + GLP_HEALTH_DUR_MENSES = (3), + + /// Under stress + GLP_HEALTH_UNDER_STRESS = (4), + + /// No health issues + GLP_HEALTH_NO_HEALTH_ISSUES = (5), + + /// Health value not available + GLP_HEALTH_HEALTH_VAL_NOT_AVA = (15), +}; + +/// Glucose measurement context medication identification +enum glp_meas_ctx_med_id +{ + /// Rapid acting insulin + GLP_MEDID_RAPID_ACTING_INSULIN = (1), + + /// Short acting insulin + GLP_MEDID_SHORT_ACTING_INSULIN = (2), + + /// Intermediate acting insulin + GLP_MEDID_INTER_ACTING_INSULIN = (3), + + /// Long acting insulin + GLP_MEDID_LONG_ACTING_INSULIN = (4), + + /// Pre-mixed insulin + GLP_MEDID_PRE_MIXED_INSULIN = (5), +}; + + +/// Glucose access control OP Code +enum glp_racp_op_code +{ + /// Report stored records (Operator: Value from Operator Table) + GLP_REQ_REP_STRD_RECS = (1), + + /// Delete stored records (Operator: Value from Operator Table) + GLP_REQ_DEL_STRD_RECS = (2), + + /// Abort operation (Operator: Null 'value of 0x00 from Operator Table') + GLP_REQ_ABORT_OP = (3), + + /// Report number of stored records (Operator: Value from Operator Table) + GLP_REQ_REP_NUM_OF_STRD_RECS = (4), + + /// Number of stored records response (Operator: Null 'value of 0x00 from Operator Table') + GLP_REQ_NUM_OF_STRD_RECS_RSP = (5), + + /// Response Code (Operator: Null 'value of 0x00 from Operator Table') + GLP_REQ_RSP_CODE = (6), +}; + +/// Glucose access control Operator +enum glp_racp_operator +{ + /// All records + GLP_OP_ALL_RECS = (1), + + /// Less than or equal to + GLP_OP_LT_OR_EQ = (2), + + /// Greater than or equal to + GLP_OP_GT_OR_EQ = (3), + + /// Within range of (inclusive) + GLP_OP_WITHIN_RANGE_OF = (4), + + /// First record(i.e. oldest record) + GLP_OP_FIRST_REC = (5), + + /// Last record (i.e. most recent record) + GLP_OP_LAST_REC = (6), +}; + +/// Glucose access control response code +enum glp_racp_status +{ + /// Success + GLP_RSP_SUCCESS = (1), + + /// Op Code not supported + GLP_RSP_OP_CODE_NOT_SUP = (2), + + /// Invalid Operator + GLP_RSP_INVALID_OPERATOR = (3), + + /// Operator not supported + GLP_RSP_OPERATOR_NOT_SUP = (4), + + /// Invalid Operand + GLP_RSP_INVALID_OPERAND = (5), + + /// No records found + GLP_RSP_NO_RECS_FOUND = (6), + + /// Abort unsuccessful + GLP_RSP_ABORT_UNSUCCESSFUL = (7), + + /// Procedure not completed + GLP_RSP_PROCEDURE_NOT_COMPLETED = (8), + + /// Operand not supported + GLP_RSP_OPERAND_NOT_SUP = (9), +}; + + +/// record access control filter type +enum glp_racp_filter +{ + /// Filter using Sequence number + GLP_FILTER_SEQ_NUMBER = (1), + /// Filter using Facing time + GLP_FILTER_USER_FACING_TIME = (2), +}; + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + + + + +/// Glucose measurement +struct glp_meas +{ + /// Base Time + struct prf_date_time base_time; + /// Time Offset + int16_t time_offset; + /// Glucose Concentration - units of kg/L or mol/L + prf_sfloat concentration; + ///Sensor Status Annunciation + uint16_t status; + /// Type + uint8_t type; + /// Sample Location + uint8_t location; + /// Flags + uint8_t flags; +}; + +/// Glucose measurement context +struct glp_meas_ctx +{ + /// Carbohydrate - units of kilograms + prf_sfloat carbo_val; + /// Exercise Duration + uint16_t exercise_dur; + /// Medication value (units of kilograms or liters) + prf_sfloat med_val; + /// HbA1c value + prf_sfloat hba1c_val; + + /// Carbohydrate ID + uint8_t carbo_id; + /// Meal + uint8_t meal; + /// Tester + uint8_t tester; + /// Health + uint8_t health; + /// Exercise Intensity + uint8_t exercise_intens; + /// Medication ID + uint8_t med_id; + + /// Flag + uint8_t flags; + /// Extended Flags + uint8_t ext_flags; +}; + + +/// Record access control point operation filter +struct glp_filter +{ + /// function operator + uint8_t operator; + + /// filter type + uint8_t filter_type; + + /// filter union + union + { + /// Sequence number filtering (filter_type = GLP_FILTER_SEQ_NUMBER) + struct + { + /// Min sequence number + uint16_t min; + /// Max sequence number + uint16_t max; + }seq_num; + + /// User facing time filtering (filter_type = GLP_FILTER_USER_FACING_TIME) + struct + { + /// Min base time + struct prf_date_time facetime_min; + + /// Max base time + struct prf_date_time facetime_max; + } time; + } val; +}; + + + +/// Record access control point request +struct glp_racp_req +{ + /// operation code + uint8_t op_code; + + /// operation filter + struct glp_filter filter; +}; + + + +/// Record access control point response +struct glp_racp_rsp +{ + /// operation code + uint8_t op_code; + + /// operator (ignored, always set to null) + uint8_t operator; + + /// response operand + union + { + /// Number of record (if op_code = GLP_REQ_NUM_OF_STRD_RECS_RSP) + uint16_t num_of_record; + + /// Command Status (if op_code = GLP_REQ_RSP_CODE) + struct + { + /// Request Op Code + uint8_t op_code_req; + /// Response Code status + uint8_t status; + } rsp; + } operand; +}; + + + +/// @} glp_common + +#endif /* _GLP_COMMON_H_ */ diff --git a/services/ble_profiles/glp/glpc/api/glpc_task.h b/services/ble_profiles/glp/glpc/api/glpc_task.h new file mode 100644 index 0000000..ff9fd15 --- /dev/null +++ b/services/ble_profiles/glp/glpc/api/glpc_task.h @@ -0,0 +1,196 @@ +#ifndef _GLPC_TASK_H_ +#define _GLPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup GLPCTASK Glucose Profile Collector Task + * @ingroup GLPC + * @brief Glucose Profile Collector Task + * + * The GLPCTASK is responsible for handling the messages coming in and out of the + * @ref GLPC monitor block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" +#include "glp_common.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +enum glpc_msg_id +{ + /// Start the Glucose Profile - at connection + GLPC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_GLPC), + /// Confirm that cfg connection has finished with discovery results, or that normal cnx started + GLPC_ENABLE_RSP, + + /// Register to Glucose sensor notifications - request + GLPC_REGISTER_REQ, + /// Register to Glucose sensor notifications - confirmation + GLPC_REGISTER_RSP, + + /// Read Glucose sensor features - request + GLPC_READ_FEATURES_REQ, + /// Read Glucose sensor features - response + GLPC_READ_FEATURES_RSP, + + /// Record Access Control Point - Request + GLPC_RACP_REQ, + /// Record Access Control Point - Resp + GLPC_RACP_RSP, + + /// Glucose measurement value received + GLPC_MEAS_IND, + + /// Glucose measurement context received + GLPC_MEAS_CTX_IND, + + + /// Glucose Record Access Control Point Request Timeout + GLPC_RACP_REQ_TIMEOUT, +}; + +/// Characteristics +enum +{ + /// Glucose Measurement + GLPC_CHAR_MEAS, + /// Glucose Measurement Context + GLPC_CHAR_MEAS_CTX, + /// Glucose Sensor Feature + GLPC_CHAR_FEATURE, + /// Record Access control point + GLPC_CHAR_RACP, + + GLPC_CHAR_MAX, +}; + + +/// Characteristic descriptors +enum +{ + /// Glucose Measurement client config + GLPC_DESC_MEAS_CLI_CFG, + /// Glucose Measurement context client config + GLPC_DESC_MEAS_CTX_CLI_CFG, + /// Record Access control point client config + GLPC_DESC_RACP_CLI_CFG, + + GLPC_DESC_MAX, +}; + +///Structure containing the characteristics handles, value handles and descriptors +struct gls_content +{ + /// service info + struct prf_svc svc; + + /// characteristic info: + /// - Glucose Measurement + /// - Glucose Measurement Context + /// - Glucose Feature + /// - Record Access Control Point + struct prf_char_inf chars[GLPC_CHAR_MAX]; + + /// Descriptor handles:info: + /// - Glucose Measurement client cfg + /// - Glucose Measurement Context client cfg + /// - Record Access Control Point client cfg + struct prf_char_desc_inf descs[GLPC_DESC_MAX]; +}; + + +/// Parameters of the @ref GLPC_ENABLE_REQ message +struct glpc_enable_req +{ + /// Connection type + uint8_t con_type; + /// Existing handle values gls + struct gls_content gls; +}; + +/// Parameters of the @ref GLPC_ENABLE_RSP message +struct glpc_enable_rsp +{ + /// status + uint8_t status; + /// Existing handle values gls + struct gls_content gls; +}; + +/// Parameters of the @ref GLPC_REGISTER_REQ message +struct glpc_register_req +{ + /// Register or not Glucose measurement context notifications + bool meas_ctx_en; +}; +/// Parameters of the @ref GLPC_REGISTER_RSP message +struct glpc_register_rsp +{ + /// Status + uint8_t status; +}; + +/// Parameters of the @ref GLPC_READ_FEATURES_RSP message +struct glpc_read_features_rsp +{ + /// Glucose sensor features + uint16_t features; + /// Status + uint8_t status; +}; + +/// Parameters of the @ref GLPC_RACP_REQ message +struct glpc_racp_req +{ + /// Record Access Control Point Request + struct glp_racp_req racp_req; +}; +/// Parameters of the @ref GLPC_RACP_RSP message +struct glpc_racp_rsp +{ + ///record access control response + struct glp_racp_rsp racp_rsp; + /// Status + uint8_t status; +}; + +/// Parameters of the @ref GLPC_MEAS_IND message +struct glpc_meas_ind +{ + /// Sequence Number + uint16_t seq_num; + /// Glucose measurement + struct glp_meas meas_val; +}; + +/// Parameters of the @ref GLPC_MEAS_CTX_IND message +struct glpc_meas_ctx_ind +{ + /// Sequence Number + uint16_t seq_num; + /// Glucose measurement + struct glp_meas_ctx ctx; +}; + +/// @} GLPCTASK + +#endif /* _GLPC_TASK_H_ */ diff --git a/services/ble_profiles/glp/glpc/src/glpc.c b/services/ble_profiles/glp/glpc/src/glpc.c new file mode 100644 index 0000000..87827b9 --- /dev/null +++ b/services/ble_profiles/glp/glpc/src/glpc.c @@ -0,0 +1,442 @@ +/** + **************************************************************************************** + * @addtogroup GLPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_GL_COLLECTOR) +#include "glpc.h" +#include "glpc_task.h" +#include "gap.h" + +#include "ke_mem.h" +#include "co_utils.h" + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialization of the GLPC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t glpc_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct glpc_env_tag* glpc_env = + (struct glpc_env_tag* ) ke_malloc(sizeof(struct glpc_env_tag), KE_MEM_ATT_DB); + + // allocate GLPC required environment variable + env->env = (prf_env_t*) glpc_env; + + glpc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + glpc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_GLPC; + glpc_task_init(&(env->desc)); + + for(idx = 0; idx < GLPC_IDX_MAX ; idx++) + { + glpc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), GLPC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Destruction of the GLPC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void glpc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct glpc_env_tag* glpc_env = (struct glpc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < GLPC_IDX_MAX ; idx++) + { + if(glpc_env->env[idx] != NULL) + { + ke_free(glpc_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(glpc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void glpc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put GLP Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), GLPC_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void glpc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct glpc_env_tag* glpc_env = (struct glpc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(glpc_env->env[conidx] != NULL) + { + ke_free(glpc_env->env[conidx]); + glpc_env->env[conidx] = NULL; + } + + /* Put GLP Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), GLPC_FREE); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// GLPC Task interface required by profile manager +const struct prf_task_cbs glpc_itf = +{ + glpc_init, + glpc_destroy, + glpc_create, + glpc_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* glpc_prf_itf_get(void) +{ + return &glpc_itf; +} + + +void glpc_enable_rsp_send(struct glpc_env_tag *glpc_env, uint8_t conidx, uint8_t status) +{ + // Send to APP the details of the discovered attributes on GLPS + struct glpc_enable_rsp * rsp = KE_MSG_ALLOC(GLPC_ENABLE_RSP, + prf_dst_task_get(&(glpc_env->prf_env), conidx), + prf_src_task_get(&(glpc_env->prf_env), conidx), + glpc_enable_rsp); + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->gls = glpc_env->env[conidx]->gls; + // Register GLPC task in gatt for indication/notifications + prf_register_atthdl2gatt(&(glpc_env->prf_env), conidx, &(glpc_env->env[conidx]->gls.svc)); + // Go to IDLE state + ke_state_set(prf_src_task_get(&(glpc_env->prf_env), conidx), GLPC_IDLE); + } + + ke_msg_send(rsp); +} + +uint8_t glpc_unpack_meas_value(uint8_t *packed_meas, struct glp_meas* meas_val, + uint16_t *seq_num) +{ + uint8_t cursor = 0; + + // Flags + meas_val->flags = packed_meas[cursor]; + cursor += 1; + + // Sequence Number + *seq_num = co_read16p(packed_meas + cursor); + cursor += 2; + + // Base Time + cursor += prf_unpack_date_time(packed_meas + cursor, &(meas_val->base_time)); + + //Time Offset + if((meas_val->flags & GLP_MEAS_TIME_OFF_PRES) != 0) + { + meas_val->time_offset = co_read16p(packed_meas + cursor); + cursor += 2; + } + + // Glucose Concentration, type and location + if((meas_val->flags & GLP_MEAS_GL_CTR_TYPE_AND_SPL_LOC_PRES) != 0) + { + meas_val->concentration = co_read16p(packed_meas + cursor); + cursor += 2; + + /* type and location are 2 nibble values */ + meas_val->location = packed_meas[cursor] >> 4; + meas_val->type = packed_meas[cursor] & 0xF; + + cursor += 1; + } + + // Sensor Status Annunciation + if((meas_val->flags & GLP_MEAS_SENS_STAT_ANNUN_PRES) != 0) + { + meas_val->status = co_read16p(packed_meas + cursor); + cursor += 2; + } + + return cursor;} + + +uint8_t glpc_unpack_meas_ctx_value(uint8_t *packed_meas_ctx, + struct glp_meas_ctx* meas_ctx_val, + uint16_t* seq_num) +{ + uint8_t cursor = 0; + // Flags + meas_ctx_val->flags = packed_meas_ctx[cursor]; + cursor += 1; + + // Sequence Number + *seq_num = co_read16p(packed_meas_ctx + cursor); + cursor += 2; + + // Extended Flags + if((meas_ctx_val->flags & GLP_CTX_EXTD_F_PRES) != 0) + { + meas_ctx_val->ext_flags = packed_meas_ctx[cursor]; + cursor += 1; + } + + // Carbohydrate ID And Carbohydrate Present + if((meas_ctx_val->flags & GLP_CTX_CRBH_ID_AND_CRBH_PRES) != 0) + { + // Carbohydrate ID + meas_ctx_val->carbo_id = packed_meas_ctx[cursor]; + cursor += 1; + // Carbohydrate Present + meas_ctx_val->carbo_val = co_read16p(packed_meas_ctx + cursor); + cursor += 2; + } + + // Meal Present + if((meas_ctx_val->flags & GLP_CTX_MEAL_PRES) != 0) + { + meas_ctx_val->meal = packed_meas_ctx[cursor]; + cursor += 1; + } + + // Tester-Health Present + if((meas_ctx_val->flags & GLP_CTX_TESTER_HEALTH_PRES) != 0) + { + // Tester and Health are 2 nibble values + meas_ctx_val->health = packed_meas_ctx[cursor] >> 4; + meas_ctx_val->tester = packed_meas_ctx[cursor] & 0xF; + cursor += 1; + } + + // Exercise Duration & Exercise Intensity Present + if((meas_ctx_val->flags & GLP_CTX_EXE_DUR_AND_EXE_INTENS_PRES) != 0) + { + // Exercise Duration + meas_ctx_val->exercise_dur = co_read16p(packed_meas_ctx + cursor); + cursor += 2; + + // Exercise Intensity + meas_ctx_val->exercise_intens = packed_meas_ctx[cursor]; + cursor += 1; + } + + // Medication ID And Medication Present + if((meas_ctx_val->flags & GLP_CTX_MEDIC_ID_AND_MEDIC_PRES) != 0) + { + // Medication ID + meas_ctx_val->med_id = packed_meas_ctx[cursor]; + cursor += 1; + + // Medication Present + meas_ctx_val->med_val = co_read16p(packed_meas_ctx + cursor); + cursor += 2; + } + + // HbA1c Present + if((meas_ctx_val->flags & GLP_CTX_HBA1C_PRES) != 0) + { + // HbA1c + meas_ctx_val->hba1c_val = co_read16p(packed_meas_ctx + cursor); + cursor += 2; + } + + return cursor; +} + +uint8_t glpc_pack_racp_req(uint8_t *packed_val, + const struct glp_racp_req* racp_req) +{ + uint8_t cursor = 0; + + // command op code + packed_val[cursor] = racp_req->op_code; + cursor++; + + // operator of the function + packed_val[cursor] = racp_req->filter.operator; + cursor++; + + // Abort operation don't require any other parameter + if(racp_req->op_code == GLP_REQ_ABORT_OP) + { + return cursor; + } + + // check if request requires operand (filter) + if((racp_req->filter.operator >= GLP_OP_LT_OR_EQ) + && (racp_req->filter.operator <= GLP_OP_WITHIN_RANGE_OF)) + { + + // command filter type + packed_val[cursor] = racp_req->filter.filter_type; + cursor++; + + // filter uses sequence number + if(racp_req->filter.filter_type == GLP_FILTER_SEQ_NUMBER) + { + // minimum value + if((racp_req->filter.operator == GLP_OP_GT_OR_EQ) + || (racp_req->filter.operator == GLP_OP_WITHIN_RANGE_OF)) + { + // minimum value + co_write16p(packed_val + cursor,racp_req->filter.val.seq_num.min); + cursor +=2; + } + + // maximum value + if((racp_req->filter.operator == GLP_OP_LT_OR_EQ) + || (racp_req->filter.operator == GLP_OP_WITHIN_RANGE_OF)) + { + // maximum value + co_write16p(packed_val + cursor,racp_req->filter.val.seq_num.max); + cursor +=2; + } + } + // filter uses user facing time + else + { + // retrieve minimum value + if((racp_req->filter.operator == GLP_OP_GT_OR_EQ) + || (racp_req->filter.operator == GLP_OP_WITHIN_RANGE_OF)) + { + // retrieve minimum facing time + cursor += prf_pack_date_time((packed_val + cursor), + &(racp_req->filter.val.time.facetime_min)); + } + + // retrieve maximum value + if((racp_req->filter.operator == GLP_OP_LT_OR_EQ) + || (racp_req->filter.operator == GLP_OP_WITHIN_RANGE_OF)) + { + // retrieve maximum facing time + cursor += prf_pack_date_time((packed_val + cursor), + &(racp_req->filter.val.time.facetime_max)); + } + } + } + + return cursor; +} + +uint8_t glpc_unpack_racp_rsp(uint8_t *packed_val, + struct glp_racp_rsp* racp_rsp) +{ + uint8_t cursor = 0; + + // response op code + racp_rsp->op_code = packed_val[cursor]; + cursor++; + + // operator (null) + cursor++; + + // number of records + if(racp_rsp->op_code == GLP_REQ_NUM_OF_STRD_RECS_RSP) + { + racp_rsp->operand.num_of_record = co_read16p(packed_val + cursor); + cursor += 2; + } + else + { + // requested opcode + racp_rsp->operand.rsp.op_code_req = packed_val[cursor]; + cursor++; + // command status + racp_rsp->operand.rsp.status = packed_val[cursor]; + cursor++; + } + + return cursor; +} + +uint8_t glpc_validate_request(struct glpc_env_tag *glpc_env, uint8_t conidx, uint8_t char_code) +{ + uint8_t status = GAP_ERR_NO_ERROR; + // check if feature val characteristic exists + if(glpc_env->env[conidx]->gls.chars[char_code].val_hdl == ATT_INVALID_HANDLE) + { + status = PRF_ERR_INEXISTENT_HDL; + } + + return (status); +} + +#endif /* (BLE_GL_COLLECTOR) */ + +/// @} GLPC diff --git a/services/ble_profiles/glp/glpc/src/glpc.h b/services/ble_profiles/glp/glpc/src/glpc.h new file mode 100644 index 0000000..ed9896e --- /dev/null +++ b/services/ble_profiles/glp/glpc/src/glpc.h @@ -0,0 +1,209 @@ +#ifndef _GLPC_H_ +#define _GLPC_H_ + +/** + **************************************************************************************** + * @addtogroup GLPC Glucose Profile Collector + * @ingroup GLP + * @brief Glucose Profile Collector + * + * The GLPC is responsible for providing Glucose Profile Collector functionalities + * to upper layer module or application. The device using this profile takes the role + * of Glucose Profile Collector. + * + * Glucose Profile Collector. (GLPC): A GLPC (e.g. PC, phone, etc) + * is the term used by this profile to describe a device that can interpret Glucose + * measurement in a way suitable to the user application. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_GL_COLLECTOR) +#include "glp_common.h" +#include "ke_task.h" +#include "prf.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "glpc_task.h" +/* + * DEFINES + **************************************************************************************** + */ +/// Maximum number of Glucose Collector task instances +#define GLPC_IDX_MAX (BLE_CONNECTION_MAX) + + +/// 30 seconds record access control point timer +#define GLPC_RACP_TIMEOUT 0x0BB8 + +/// Possible states of the GLPC task +enum glpc_state +{ + /// Not Connected state + GLPC_FREE, + /// IDLE state + GLPC_IDLE, + /// Discovering Glucose SVC and Chars + GLPC_DISCOVERING, + + /// Number of defined states. + GLPC_STATE_MAX +}; + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Glucose Profile Collector environment variable per connection +struct glpc_cnx_env +{ + ///Last requested UUID(to keep track of the two services and char) + uint16_t last_uuid_req; + /// counter used to check service uniqueness + uint8_t nb_svc; + /// used to store if measurement context + uint8_t meas_ctx_en; + ///HTS characteristics + struct gls_content gls; +}; + +/// Glucose Profile Collector environment variable +struct glpc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct glpc_cnx_env* env[GLPC_IDX_MAX]; + /// State of different task instances + ke_state_t state[GLPC_IDX_MAX]; +}; + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve GLP client profile interface + * + * @return GLP client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* glpc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Glucose ATT DB discovery results to GLPC host. + **************************************************************************************** + */ +void glpc_enable_rsp_send(struct glpc_env_tag *glpc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Unpack Glucose measurement value + * + * @param[in] packed_meas Glucose measurement value packed + * @param[out] meas_val Glucose measurement value + * @param[out] seq_num Glucose measurement sequence number + * + * @return size of packed value + **************************************************************************************** + */ +uint8_t glpc_unpack_meas_value(uint8_t *packed_meas, struct glp_meas* meas_val, + uint16_t* seq_num); + + +/** + **************************************************************************************** + * @brief Unpack Glucose measurement context value + * + * @param[in] packed_meas Glucose measurement context value packed + * @param[out] meas_val Glucose measurement context value + * @param[out] seq_num Glucose measurement sequence number + * + * @return size of packed value + **************************************************************************************** + */ +uint8_t glpc_unpack_meas_ctx_value(uint8_t *packed_meas_ctx, + struct glp_meas_ctx* meas_ctx_val, + uint16_t* seq_num); + + + +/** + **************************************************************************************** + * @brief Pack Record Access Control request + * + * @param[out] packed_val Record Access Control Point value packed + * @param[in] racp_req Record Access Control Request value + * + * @return size of packed data + **************************************************************************************** + */ +uint8_t glpc_pack_racp_req(uint8_t *packed_val, + const struct glp_racp_req* racp_req); + + +/** + **************************************************************************************** + * @brief Unpack Record Access Control response + * + * @param[in] packed_val Record Access Control Point value packed + * @param[out] racp_rsp Record Access Control Response value + * + * @return size of packed data + **************************************************************************************** + */ +uint8_t glpc_unpack_racp_rsp(uint8_t *packed_val, + struct glp_racp_rsp* racp_rsp); + + +/** + **************************************************************************************** + * @brief Check if collector request is possible or not + * + * @param[in] conidx Connection Index. + * @param[in] atthdl Attribute handle. + * + * @return GAP_ERR_NO_ERROR if request can be performed, error code else. + **************************************************************************************** + */ +uint8_t glpc_validate_request(struct glpc_env_tag *glpc_env, uint8_t conidx, uint8_t char_code); + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void glpc_task_init(struct ke_task_desc *task_desc); + +#endif /* (BLE_GL_COLLECTOR) */ + +/// @} GLPC + +#endif /* _GLPC_H_ */ diff --git a/services/ble_profiles/glp/glpc/src/glpc_task.c b/services/ble_profiles/glp/glpc/src/glpc_task.c new file mode 100644 index 0000000..5c4628b --- /dev/null +++ b/services/ble_profiles/glp/glpc/src/glpc_task.c @@ -0,0 +1,773 @@ +/** + **************************************************************************************** + * @addtogroup GLPCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_GL_COLLECTOR) +#include "gap.h" +#include "attm.h" +#include "glpc_task.h" +#include "glpc.h" +#include "gattc_task.h" +#include "gapc_task.h" +#include "ke_timer.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/* + * DEFINES + **************************************************************************************** + */ + +/// State machine used to retrieve Glucose service characteristics information +const struct prf_char_def glpc_gls_char[GLPC_CHAR_MAX] = +{ + + /// Glucose Measurement + [GLPC_CHAR_MEAS] = {ATT_CHAR_GLUCOSE_MEAS, + ATT_MANDATORY, + ATT_CHAR_PROP_NTF}, + /// Glucose Measurement Context + [GLPC_CHAR_MEAS_CTX] = {ATT_CHAR_GLUCOSE_MEAS_CTX, + ATT_OPTIONAL, + ATT_CHAR_PROP_NTF}, + /// Glucose Feature + [GLPC_CHAR_FEATURE] = {ATT_CHAR_GLUCOSE_FEATURE, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, + /// Record Access control point + [GLPC_CHAR_RACP] = {ATT_CHAR_REC_ACCESS_CTRL_PT, + ATT_MANDATORY, + ATT_CHAR_PROP_WR|ATT_CHAR_PROP_IND}, +}; + +/// State machine used to retrieve Glucose service characteristic description information +const struct prf_char_desc_def glpc_gls_char_desc[GLPC_DESC_MAX] = +{ + /// Glucose Measurement client config + [GLPC_DESC_MEAS_CLI_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_MANDATORY, GLPC_CHAR_MEAS}, + + /// Glucose Measurement context client config + [GLPC_DESC_MEAS_CTX_CLI_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_MANDATORY, GLPC_CHAR_MEAS_CTX}, + + /// Record Access control point client config + [GLPC_DESC_RACP_CLI_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_MANDATORY, GLPC_CHAR_RACP}, +}; + + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GLPC_ENABLE_REQ message. + * The handler enables the Glucose Profile Collector Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int glpc_enable_req_handler(ke_msg_id_t const msgid, + struct glpc_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Glucose Profile Client Role Task Environment + struct glpc_env_tag *glpc_env = PRF_ENV_GET(GLPC, glpc); + + ASSERT_INFO(glpc_env != NULL, dest_id, src_id); + if((state == GLPC_IDLE) && (glpc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + glpc_env->env[conidx] = (struct glpc_cnx_env*) ke_malloc(sizeof(struct glpc_cnx_env),KE_MEM_ATT_DB); + memset(glpc_env->env[conidx], 0, sizeof(struct glpc_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering GLS on peer + prf_disc_svc_send(&(glpc_env->prf_env), conidx, ATT_SVC_GLUCOSE); + + // Go to DISCOVERING state + ke_state_set(dest_id, GLPC_DISCOVERING); + } + //normal connection, get saved att details + else + { + glpc_env->env[conidx]->gls = param->gls; + + //send APP confirmation that can start normal connection to TH + glpc_enable_rsp_send(glpc_env, conidx, GAP_ERR_NO_ERROR); + } + } + + else if(state != GLPC_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + glpc_enable_rsp_send(glpc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == GLPC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct glpc_env_tag *glpc_env = PRF_ENV_GET(GLPC, glpc); + + ASSERT_INFO(glpc_env != NULL, dest_id, src_id); + ASSERT_INFO(glpc_env->env[conidx] != NULL, dest_id, src_id); + + if(glpc_env->env[conidx]->nb_svc == 0) + { + // Retrieve GLS characteristics and descriptors + prf_extract_svc_info(ind, GLPC_CHAR_MAX, &glpc_gls_char[0], &glpc_env->env[conidx]->gls.chars[0], + GLPC_DESC_MAX, &glpc_gls_char_desc[0], &glpc_env->env[conidx]->gls.descs[0]); + + //Even if we get multiple responses we only store 1 range + glpc_env->env[conidx]->gls.svc.shdl = ind->start_hdl; + glpc_env->env[conidx]->gls.svc.ehdl = ind->end_hdl; + } + + glpc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status; + // Get the address of the environment + struct glpc_env_tag *glpc_env = PRF_ENV_GET(GLPC, glpc); + uint8_t conidx = KE_IDX_GET(dest_id); + + if(state == GLPC_DISCOVERING) + { + status = param->status; + + if (param->status == ATT_ERR_NO_ERROR) + { + // check characteristic validity + if(glpc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(GLPC_CHAR_MAX, glpc_env->env[conidx]->gls.chars, + glpc_gls_char); + } + // too much services + else if (glpc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if(status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(GLPC_DESC_MAX, + glpc_env->env[conidx]->gls.descs, + glpc_gls_char_desc, + glpc_env->env[conidx]->gls.chars); + } + } + + glpc_enable_rsp_send(glpc_env, conidx, status); + + + } + else if (state == GLPC_IDLE) + { + switch(param->operation) + { + case GATTC_WRITE: + case GATTC_WRITE_NO_RESPONSE: + { + // RACP write done. + if(glpc_env->env[conidx]->last_uuid_req == ATT_CHAR_REC_ACCESS_CTRL_PT) + { + // an error occurs while writing RACP command + if(param->status != GAP_ERR_NO_ERROR) + { + struct glpc_racp_rsp * rsp = KE_MSG_ALLOC(GLPC_RACP_RSP, + prf_dst_task_get(&(glpc_env->prf_env), conidx), dest_id, + glpc_racp_rsp); + + // set error status + rsp->status = param->status; + + // stop timer. + ke_timer_clear(GLPC_RACP_REQ_TIMEOUT, dest_id); + + ke_msg_send(rsp); + glpc_env->env[conidx]->last_uuid_req = 0; + } + } + else + { + bool finished = false; + + // Restore if measurement context notification should be register in from + // unused variable + bool meas_ctx_en = glpc_env->env[conidx]->meas_ctx_en; + + // Registration succeed + if(param->status == GAP_ERR_NO_ERROR) + { + // Glucose measurement notification registration done + if(glpc_env->env[conidx]->last_uuid_req == GLPC_DESC_MEAS_CLI_CFG) + { + // register to RACP indications + prf_gatt_write_ntf_ind(&(glpc_env->prf_env), conidx, + glpc_env->env[conidx]->gls.descs[GLPC_DESC_RACP_CLI_CFG].desc_hdl, + PRF_CLI_START_IND); + glpc_env->env[conidx]->last_uuid_req = GLPC_DESC_RACP_CLI_CFG; + } + // Record access control point indication registration done + // Register to Glucose Measurement Context notifications if requested. + else if((glpc_env->env[conidx]->last_uuid_req == GLPC_DESC_RACP_CLI_CFG) + && meas_ctx_en) + { + // register to Glucose Measurement Context notifications + prf_gatt_write_ntf_ind(&(glpc_env->prf_env), conidx, + glpc_env->env[conidx]->gls.descs[GLPC_DESC_MEAS_CTX_CLI_CFG].desc_hdl, + PRF_CLI_START_NTF); + glpc_env->env[conidx]->last_uuid_req = GLPC_DESC_MEAS_CTX_CLI_CFG; + } + // All registration done + else + { + // indication/notification registration finished + finished = true; + } + } + + // send status if registration done or if an error occurs. + if((param->status != GAP_ERR_NO_ERROR) || (finished)) + { + struct glpc_register_rsp * cfm = KE_MSG_ALLOC(GLPC_REGISTER_RSP, + prf_dst_task_get(&(glpc_env->prf_env), conidx), dest_id, + glpc_register_rsp); + // set error status + cfm->status = param->status; + + ke_msg_send(cfm); + } + } + } + break; + + case GATTC_READ: + { + if(param->status != GAP_ERR_NO_ERROR) + { + struct glpc_read_features_rsp * rsp = KE_MSG_ALLOC(GLPC_READ_FEATURES_RSP, + prf_dst_task_get(&(glpc_env->prf_env), conidx), dest_id, + glpc_read_features_rsp); + + // set error status + rsp->status = param->status; + + ke_msg_send(rsp); + } + } + break; + default: break; + } + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GLPC_READ_FEATURES_REQ message. + * Send by application task, it's used to retrieve Glucose Sensor features. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int glpc_read_features_req_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(state == GLPC_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct glpc_env_tag *glpc_env = PRF_ENV_GET(GLPC, glpc); + + ASSERT_INFO(glpc_env != NULL, dest_id, src_id); + + // environment variable not ready + if(glpc_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + else + { + status = glpc_validate_request(glpc_env, conidx, GLPC_CHAR_FEATURE); + + // request can be performed + if(status == GAP_ERR_NO_ERROR) + { + // read glucose sensor featur + prf_read_char_send(&(glpc_env->prf_env), conidx, glpc_env->env[conidx]->gls.svc.shdl, + glpc_env->env[conidx]->gls.svc.ehdl, glpc_env->env[conidx]->gls.chars[GLPC_CHAR_FEATURE].val_hdl); + } + } + } + + // request cannot be performed + if(status != GAP_ERR_NO_ERROR) + { + struct glpc_read_features_rsp * rsp = KE_MSG_ALLOC(GLPC_READ_FEATURES_RSP, + src_id, dest_id, glpc_read_features_rsp); + // set error status + rsp->status = status; + + ke_msg_send(rsp); + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == GLPC_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct glpc_env_tag *glpc_env = PRF_ENV_GET(GLPC, glpc); + + ASSERT_INFO(glpc_env != NULL, dest_id, src_id); + ASSERT_INFO(glpc_env->env[conidx] != NULL, dest_id, src_id); + + struct glpc_read_features_rsp * rsp = KE_MSG_ALLOC(GLPC_READ_FEATURES_RSP, + prf_dst_task_get(&(glpc_env->prf_env), conidx), dest_id, + glpc_read_features_rsp); + // set error status + rsp->status = ATT_ERR_NO_ERROR; + // unpack feature information + rsp->features = co_read16p(param->value); + + ke_msg_send(rsp); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GLPC_REGISTER_REQ message. + * When receiving this request, Glucose collector register to measurement notifications + * and RACP indications. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int glpc_register_req_handler(ke_msg_id_t const msgid, + struct glpc_register_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(state == GLPC_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct glpc_env_tag *glpc_env = PRF_ENV_GET(GLPC, glpc); + + ASSERT_INFO(glpc_env != NULL, dest_id, src_id); + + // environment variable not ready + if(glpc_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + // check if client characteristics are present + else if ((glpc_env->env[conidx]->gls.descs[GLPC_DESC_MEAS_CLI_CFG].desc_hdl == ATT_INVALID_HANDLE) + || (glpc_env->env[conidx]->gls.descs[GLPC_DESC_RACP_CLI_CFG].desc_hdl == ATT_INVALID_HANDLE) + || ((param->meas_ctx_en) + && (glpc_env->env[conidx]->gls.descs[GLPC_DESC_MEAS_CTX_CLI_CFG].desc_hdl == ATT_INVALID_HANDLE))) + { + status = PRF_ERR_INEXISTENT_HDL; + } + // request can be performed + else + { + // register to notification + prf_gatt_write_ntf_ind(&(glpc_env->prf_env), conidx, + glpc_env->env[conidx]->gls.descs[GLPC_DESC_MEAS_CLI_CFG].desc_hdl, + PRF_CLI_START_NTF); + glpc_env->env[conidx]->last_uuid_req = GLPC_DESC_MEAS_CLI_CFG; + + // save if measurement context notification should be register in an unused variable + glpc_env->env[conidx]->meas_ctx_en = param->meas_ctx_en; + + status = GAP_ERR_NO_ERROR; + } + } + + // request cannot be performed + if(status != GAP_ERR_NO_ERROR) + { + struct glpc_register_rsp * cfm = KE_MSG_ALLOC(GLPC_REGISTER_RSP, src_id, dest_id, glpc_register_rsp); + // set error status + cfm->status = status; + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GLPC_RACP_REQ message. + * When receiving this request, Glucose collector send a RACP command to Glucose sensor. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int glpc_racp_req_handler(ke_msg_id_t const msgid, + struct glpc_racp_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(state == GLPC_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct glpc_env_tag *glpc_env = PRF_ENV_GET(GLPC, glpc); + + ASSERT_INFO(glpc_env != NULL, dest_id, src_id); + + // environment variable not ready + if(glpc_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + else + { + status = glpc_validate_request(glpc_env, conidx, GLPC_CHAR_RACP); + + // request can be performed + if(status == GAP_ERR_NO_ERROR) + { + // send command request + uint8_t value[GLP_REC_ACCESS_CTRL_MAX_LEN]; + uint16_t length; + + // pack Record Access Control Point request + length = glpc_pack_racp_req((uint8_t*)&(value[0]), &(param->racp_req)); + + // write Record Access Control Point request + prf_gatt_write(&(glpc_env->prf_env), conidx, + glpc_env->env[conidx]->gls.chars[GLPC_CHAR_RACP].val_hdl, + &(value[0]),length, GATTC_WRITE); + + glpc_env->env[conidx]->last_uuid_req = ATT_CHAR_REC_ACCESS_CTRL_PT; + + // start the timer; will destroy the link if it expires + ke_timer_set(GLPC_RACP_REQ_TIMEOUT, dest_id, GLPC_RACP_TIMEOUT); + } + } + } + + // request cannot be performed + if(status != GAP_ERR_NO_ERROR) + { + struct glpc_racp_rsp * rsp = KE_MSG_ALLOC(GLPC_RACP_RSP, src_id, dest_id, glpc_racp_rsp); + // set error status + rsp->status = status; + ke_msg_send(rsp); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state != GLPC_FREE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct glpc_env_tag *glpc_env = PRF_ENV_GET(GLPC, glpc); + + ASSERT_INFO(glpc_env != NULL, dest_id, src_id); + ASSERT_INFO(glpc_env->env[conidx] != NULL, dest_id, src_id); + + switch(param->type) + { + case GATTC_INDICATE: + { + // confirm that indication has been correctly received + struct gattc_event_cfm * cfm = KE_MSG_ALLOC(GATTC_EVENT_CFM, src_id, dest_id, gattc_event_cfm); + cfm->handle = param->handle; + ke_msg_send(cfm); + + // check if it's a RACP indication + if (glpc_env->env[conidx]->gls.chars[GLPC_CHAR_RACP].val_hdl == param->handle) + { + struct glpc_racp_rsp * rsp = KE_MSG_ALLOC(GLPC_RACP_RSP, + prf_dst_task_get(&(glpc_env->prf_env), conidx), dest_id, + glpc_racp_rsp); + + // set error status + rsp->status = GAP_ERR_NO_ERROR; + + // stop timer. + ke_timer_clear(GLPC_RACP_REQ_TIMEOUT, dest_id); + + // unpack RACP response indication. + glpc_unpack_racp_rsp((uint8_t*)param->value, &(rsp->racp_rsp)); + ke_msg_send(rsp); + } + } + break; + case GATTC_NOTIFY: + { + // check if it's a Glucose measurement notification + if (glpc_env->env[conidx]->gls.chars[GLPC_CHAR_MEAS].val_hdl == param->handle) + { + + // build a GLPC_MEAS_IND message with glucose measurement value + struct glpc_meas_ind * ind = KE_MSG_ALLOC(GLPC_MEAS_IND, + prf_dst_task_get(&(glpc_env->prf_env), conidx), dest_id, + glpc_meas_ind); + + // unpack Glucose measurement. + glpc_unpack_meas_value((uint8_t*) param->value, &(ind->meas_val), &(ind->seq_num)); + + if(glpc_env->env[conidx]->last_uuid_req == ATT_CHAR_REC_ACCESS_CTRL_PT) + { + // restart the timer; will destroy the link if it expires + ke_timer_set(GLPC_RACP_REQ_TIMEOUT, dest_id, GLPC_RACP_TIMEOUT); + } + + ke_msg_send(ind); + } + // check if it's a Glucose measurement context notification + else if(glpc_env->env[conidx]->gls.chars[GLPC_CHAR_MEAS_CTX].val_hdl == param->handle) + { + // build a GLPC_MEAS_CTX_IND message with glucose measurement context value + struct glpc_meas_ctx_ind * ind = KE_MSG_ALLOC(GLPC_MEAS_CTX_IND, + prf_dst_task_get(&(glpc_env->prf_env), conidx), dest_id, + glpc_meas_ctx_ind); + + // unpack Glucose measurement context. + glpc_unpack_meas_ctx_value((uint8_t*) param->value, &(ind->ctx), &(ind->seq_num)); + + if(glpc_env->env[conidx]->last_uuid_req == ATT_CHAR_REC_ACCESS_CTRL_PT) + { + // restart the timer; will destroy the link if it expires + ke_timer_set(GLPC_RACP_REQ_TIMEOUT, dest_id, GLPC_RACP_TIMEOUT); + } + + ke_msg_send(ind); + } + } + break; + default: break; + } + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief RACP request not executed by peer device or is freezed. + * It can be a connection problem, disconnect the link. + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (TASK_GATTC). + * @param[in] src_id ID of the sending task instance. + * + * @return If the message was consumed or not. + * + **************************************************************************************** + */ +__STATIC int glpc_racp_req_timeout_handler(ke_msg_id_t const msgid, void const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state != GLPC_FREE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + struct glpc_env_tag *glpc_env = PRF_ENV_GET(GLPC, glpc); + + ASSERT_INFO(glpc_env != NULL, dest_id, src_id); + ASSERT_INFO(glpc_env->env[conidx] != NULL, dest_id, src_id); + + // inform that racp execution is into a timeout state + struct glpc_racp_rsp * rsp = KE_MSG_ALLOC(GLPC_RACP_RSP, + prf_dst_task_get(&(glpc_env->prf_env), conidx), dest_id, glpc_racp_rsp); + // set error status + rsp->status = PRF_ERR_PROC_TIMEOUT; + + ke_msg_send(rsp); + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(glpc) +{ + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {GLPC_READ_FEATURES_REQ, (ke_msg_func_t)glpc_read_features_req_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GLPC_REGISTER_REQ, (ke_msg_func_t)glpc_register_req_handler}, + {GLPC_RACP_REQ, (ke_msg_func_t)glpc_racp_req_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_EVENT_REQ_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GLPC_RACP_REQ_TIMEOUT, (ke_msg_func_t)glpc_racp_req_timeout_handler}, + {GLPC_ENABLE_REQ, (ke_msg_func_t)glpc_enable_req_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void glpc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct glpc_env_tag *glpc_env = PRF_ENV_GET(GLPC, glpc); + + task_desc->msg_handler_tab = glpc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(glpc_msg_handler_tab); + task_desc->state = glpc_env->state; + task_desc->idx_max = GLPC_IDX_MAX; +} + +#endif /* (BLE_GL_COLLECTOR) */ +/// @} GLPCTASK diff --git a/services/ble_profiles/glp/glps/api/glps.h b/services/ble_profiles/glp/glps/api/glps.h new file mode 100644 index 0000000..699d692 --- /dev/null +++ b/services/ble_profiles/glp/glps/api/glps.h @@ -0,0 +1,324 @@ +#ifndef _GLPS_H_ +#define _GLPS_H_ + +/** + **************************************************************************************** + * @addtogroup GLPS Glucose Profile Sensor + * @ingroup GLP + * @brief Glucose Profile Sensor + * + * Glucose sensor (GLS) profile provides functionalities to upper layer module + * application. The device using this profile takes the role of Glucose sensor. + * + * The interface of this role to the Application is: + * - Enable the profile role (from APP) + * - Disable the profile role (from APP) + * - Notify peer device during Glucose measurement (from APP) + * - Indicate measurements performed to peer device (from APP) + * + * Profile didn't manages multiple users configuration and storage of offline measurements. + * This must be handled by application. + * + * Glucose Profile Sensor. (GLPS): A GLPS (e.g. PC, phone, etc) + * is the term used by this profile to describe a device that can perform Glucose + * measurement and notify about on-going measurement and indicate final result to a peer + * BLE device. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_GL_SENSOR) + +#include "glp_common.h" +#include "prf_types.h" +#include "prf.h" +#include "attm.h" + +/* + * DEFINES + **************************************************************************************** + */ +///Maximum number of Glucose task instances +#define GLPS_IDX_MAX BLE_CONNECTION_MAX + + +///GLS Configuration Flag Masks +#define GLPS_MANDATORY_MASK (0x1F8F) +#define GLPS_MEAS_CTX_PRES_MASK (0x0070) + +/* + * MACROS + **************************************************************************************** + */ + +/// check if flag enable +#define GLPS_IS(IDX, FLAG) ((glps_env->env[IDX]->flags & (1<< (GLPS_##FLAG))) == (1<< (GLPS_##FLAG))) + +/// Set flag enable +#define GLPS_SET(IDX, FLAG) (glps_env->env[IDX]->flags |= (1<< (GLPS_##FLAG))) + +/// Set flag disable +#define GLPS_CLEAR(IDX, FLAG) (glps_env->env[IDX]->flags &= ~(1<< (GLPS_##FLAG))) + + +/// Get database attribute handle +#define GLPS_HANDLE(idx) \ + (glps_env->start_hdl + (idx) - \ + ((!(glps_env->meas_ctx_supported) && ((idx) > GLS_IDX_MEAS_CTX_NTF_CFG))? (3) : (0))) + +/// Get database attribute index +#define GLPS_IDX(hdl) \ + (((((hdl) - glps_env->start_hdl) > GLS_IDX_MEAS_CTX_NTF_CFG) && !(glps_env->meas_ctx_supported)) ?\ + ((hdl) - glps_env->start_hdl + 3) : ((hdl) - glps_env->start_hdl)) + +/// Get event Indication/notification configuration bit +#define GLPS_IND_NTF_EVT(idx) (1 << ((idx - 1) / 3)) +/* + * ENUMS + **************************************************************************************** + */ + +/// Possible states of the GLPS task +enum glps_state +{ + /// Not Connected state + GLPS_FREE, + /// Idle state + GLPS_IDLE, + + /// Number of defined states. + GLPS_STATE_MAX +}; + +///Attributes State Machine +enum +{ + /// Glucose Service + GLS_IDX_SVC, + /// Glucose Measurement + GLS_IDX_MEAS_CHAR, + GLS_IDX_MEAS_VAL, + GLS_IDX_MEAS_NTF_CFG, + /// Glucose Measurement Context + GLS_IDX_MEAS_CTX_CHAR, + GLS_IDX_MEAS_CTX_VAL, + GLS_IDX_MEAS_CTX_NTF_CFG, + ///Glucose Feature + GLS_IDX_FEATURE_CHAR, + GLS_IDX_FEATURE_VAL, + ///Record Access Control Point + GLS_IDX_REC_ACCESS_CTRL_CHAR, + GLS_IDX_REC_ACCESS_CTRL_VAL, + GLS_IDX_REC_ACCESS_CTRL_IND_CFG, + + GLS_IDX_NB, +}; + +///Characteristic Codes +enum +{ + /// Glucose Measurement + GLS_MEAS_CHAR, + /// Glucose Measurement Context + GLS_MEAS_CTX_CHAR, + /// Glucose Feature + GLS_FEATURE_CHAR, + /// Record Access Control Point + GLS_REC_ACCESS_CTRL_CHAR, +}; + +///Database Configuration Bit Field Flags +enum +{ + /// support of Glucose Measurement Context + GLPS_MEAS_CTX_SUP = 0x01, +}; + +/// Indication/notification configuration (put in feature flag to optimize memory usage) +enum +{ + /// Bit used to know if Glucose measurement notification is enabled + GLPS_MEAS_NTF_CFG = GLPS_IND_NTF_EVT(GLS_IDX_MEAS_NTF_CFG), + /// Bit used to know if Glucose measurement context notification is enabled + GLPS_MEAS_CTX_NTF_CFG = GLPS_IND_NTF_EVT(GLS_IDX_MEAS_CTX_NTF_CFG), + /// Bit used to know if Glucose measurement context indication is enabled + GLPS_RACP_IND_CFG = GLPS_IND_NTF_EVT(GLS_IDX_REC_ACCESS_CTRL_IND_CFG), +}; + +/// Type of request completed +enum +{ + /// Glucose measurement notification sent completed + GLPS_SEND_MEAS_REQ_NTF_CMP, + /// Record Access Control Point Response Indication + GLPS_SEND_RACP_RSP_IND_CMP +}; + +/// Glucose service processing flags +enum +{ + /// Use To know if bond data are present + GLPS_BOND_DATA_PRESENT, + /// Flag used to know if there is an on-going record access control point request + GLPS_RACP_ON_GOING, + /// Service id sending a measurement + GLPS_SENDING_MEAS, + /// Measurement sent + GLPS_MEAS_SENT, + /// Measurement context sent + GLPS_MEAS_CTX_SENT, + /// RACP Response sent by application + GLPS_RACP_RSP_SENT_BY_APP, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Glucose Profile Sensor environment variable per connection +struct glps_cnx_env +{ + /// Glucose service processing flags + uint8_t flags; + /// Event (notification/indication) configuration + uint8_t evt_cfg; +}; + +/// Glucose Profile Sensor environment variable +struct glps_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct glps_cnx_env* env[GLPS_IDX_MAX]; + /// Glucose Service Start Handle + uint16_t start_hdl; + /// Glucose Feature + uint16_t features; + /// Measurement context supported + uint8_t meas_ctx_supported; + /// State of different task instances + ke_state_t state[GLPS_IDX_MAX]; +}; + + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve GLP service profile interface + * + * @return GLP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* glps_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Pack Glucose measurement value + * + * @param[out] packed_meas Glucose measurement value packed + * @param[in] meas_val Glucose measurement value + * @param[in] seq_num Glucose measurement sequence number + * + * @return size of packed value + **************************************************************************************** + */ +uint8_t glps_pack_meas_value(uint8_t *packed_meas, const struct glp_meas* meas_val, + uint16_t seq_num); + + +/** + **************************************************************************************** + * @brief Pack Glucose measurement context value + * + * @param[out] packed_meas Glucose measurement context value packed + * @param[in] meas_val Glucose measurement context value + * @param[in] seq_num Glucose measurement sequence number + * + * @return size of packed value + **************************************************************************************** + */ +uint8_t glps_pack_meas_ctx_value(uint8_t *packed_meas_ctx, + const struct glp_meas_ctx* meas_ctx_val, + uint16_t seq_num); + + + +/** + **************************************************************************************** + * @brief Unpack Record Access Control request + * + * @param[in] packed_val Record Access Control Point value packed + * @param[out] racp_req Record Access Control Request value + * + * @return status of unpacking + **************************************************************************************** + */ +uint8_t glps_unpack_racp_req(uint8_t *packed_val, uint16_t length, + struct glp_racp_req* racp_req); + + +/** + **************************************************************************************** + * @brief Pack Record Access Control response + * + * @param[out] packed_val Record Access Control Point value packed + * @param[in] racp_rsp Record Access Control Response value + * + * @return size of packed data + **************************************************************************************** + */ +uint8_t glps_pack_racp_rsp(uint8_t *packed_val, + struct glp_racp_rsp* racp_rsp); + +/** + **************************************************************************************** + * @brief Send Record Access Control Response Indication + * + * @param[in] racp_rsp Record Access Control Response value + * @param[in] racp_ind_src Application that requests to send RACP response indication. + * + * @return PRF_ERR_IND_DISABLED if indication disabled by peer device, GAP_ERR_NO_ERROR else. + **************************************************************************************** + */ +uint8_t glps_send_racp_rsp(struct glp_racp_rsp * racp_rsp, + ke_task_id_t racp_ind_src); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void glps_task_init(struct ke_task_desc *task_desc); + +#endif /* #if (BLE_GL_SENSOR) */ + +/// @} GLPS + +#endif /* _GLPS_H_ */ diff --git a/services/ble_profiles/glp/glps/api/glps_task.h b/services/ble_profiles/glp/glps/api/glps_task.h new file mode 100644 index 0000000..4e5b10b --- /dev/null +++ b/services/ble_profiles/glp/glps/api/glps_task.h @@ -0,0 +1,147 @@ +#ifndef _GLPS_TASK_H_ +#define _GLPS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup GLPSTASK Task + * @ingroup GLPS + * @brief Glucose Profile Task. + * + * The GLPSTASK is responsible for handling the messages coming in and out of the + * @ref GLPS collector block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include "rwip_task.h" // Task definitions +#include "glp_common.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Messages for Glucose Profile Sensor +enum glps_msg_id +{ + /// Start the Glucose Profile Sensor - at connection + GLPS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_GLPS), + /// Confirm that Glucose Profile Sensor is started. + GLPS_ENABLE_RSP, + + ///Inform APP of new configuration value + GLPS_CFG_INDNTF_IND, + + /// Record Access Control Point Request + GLPS_RACP_REQ_RCV_IND, + + /// Record Access Control Point Resp + GLPS_SEND_RACP_RSP_CMD, + + /// Send Glucose measurement with context information + GLPS_SEND_MEAS_WITH_CTX_CMD, + /// Send Glucose measurement without context information + GLPS_SEND_MEAS_WITHOUT_CTX_CMD, + + ///Inform that requested action has been performed + GLPS_CMP_EVT, +}; + +///Parameters of the Glucose service database +struct glps_db_cfg +{ + /// Glucose Feature + uint16_t features; + /// Measurement context supported + uint8_t meas_ctx_supported; +}; + + +/// Parameters of the @ref GLPS_ENABLE_REQ message +struct glps_enable_req +{ + /// Glucose indication/notification configuration + uint16_t evt_cfg; +}; + +///Parameters of the @ref GLPS_ENABLE_RSP message +struct glps_enable_rsp +{ + ///Status + uint8_t status; +}; + +///Parameters of the @ref GLPS_CFG_INDNTF_IND message +struct glps_cfg_indntf_ind +{ + /// Glucose indication/notification configuration + uint8_t evt_cfg; +}; + +///Parameters of the @ref GLPS_SEND_MEAS_WITH_CTX_CMD message +struct glps_send_meas_with_ctx_cmd +{ + /// Sequence Number + uint16_t seq_num; + /// Glucose measurement + struct glp_meas meas; + /// Glucose measurement context + struct glp_meas_ctx ctx; +}; + + +///Parameters of the @ref GLPS_SEND_MEAS_WITHOUT_CTX_CMD message +struct glps_send_meas_without_ctx_cmd +{ + /// Sequence Number + uint16_t seq_num; + /// Glucose measurement + struct glp_meas meas; +}; + + +///Parameters of the @ref GLPS_RACP_REQ_RCV_IND message +struct glps_racp_req_rcv_ind +{ + ///RACP Request + struct glp_racp_req racp_req; +}; + +///Parameters of the @ref GLPS_SEND_RACP_RSP_CMD message +struct glps_send_racp_rsp_cmd +{ + ///Number of records. + uint16_t num_of_record; + /// operation code + uint8_t op_code; + ///Command status + uint8_t status; +}; + +///Parameters of the @ref GLPS_CMP_EVT message +struct glps_cmp_evt +{ + /// completed request + uint8_t request; + ///Command status + uint8_t status; +}; + + +/// @} GLPSTASK + +#endif /* _GLPS_TASK_H_ */ diff --git a/services/ble_profiles/glp/glps/src/glps.c b/services/ble_profiles/glp/glps/src/glps.c new file mode 100644 index 0000000..16adb7e --- /dev/null +++ b/services/ble_profiles/glp/glps/src/glps.c @@ -0,0 +1,551 @@ +/** + **************************************************************************************** + * @addtogroup GLPS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_GL_SENSOR) +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "glps.h" +#include "glps_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Full GLPS Database Description - Used to add attributes into the database +static const struct attm_desc glps_att_db[GLS_IDX_NB] = +{ + // Glucose Service Declaration + [GLS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // Glucose Measurement Characteristic Declaration + [GLS_IDX_MEAS_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Glucose Measurement Characteristic Value + [GLS_IDX_MEAS_VAL] = {ATT_CHAR_GLUCOSE_MEAS, PERM(NTF, ENABLE), PERM(RI, ENABLE), 0}, + // Glucose Measurement Characteristic - Client Characteristic Configuration Descriptor + [GLS_IDX_MEAS_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Glucose Measurement Context Characteristic Declaration + [GLS_IDX_MEAS_CTX_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Glucose Measurement Context Characteristic Value + [GLS_IDX_MEAS_CTX_VAL] = {ATT_CHAR_GLUCOSE_MEAS_CTX, PERM(NTF, ENABLE), PERM(RI, ENABLE), 0}, + // Glucose Measurement Context Characteristic - Client Characteristic Configuration Descriptor + [GLS_IDX_MEAS_CTX_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Glucose Features Characteristic Declaration + [GLS_IDX_FEATURE_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Glucose Features Characteristic Value + [GLS_IDX_FEATURE_VAL] = {ATT_CHAR_GLUCOSE_FEATURE, PERM(RD, ENABLE), PERM(RI, ENABLE) | sizeof(uint16_t), 0}, + + // Record Access Control Point characteristic Declaration + [GLS_IDX_REC_ACCESS_CTRL_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Record Access Control Point characteristic Value + [GLS_IDX_REC_ACCESS_CTRL_VAL] = {ATT_CHAR_REC_ACCESS_CTRL_PT, PERM(IND, ENABLE)|PERM(WP, UNAUTH)|PERM(WRITE_REQ, ENABLE), + PERM(RI, ENABLE), GLP_REC_ACCESS_CTRL_MAX_LEN}, + // Record Access Control Point characteristic - Client Characteristic Configuration Descriptor + [GLS_IDX_REC_ACCESS_CTRL_IND_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, 0}, +}; + + +/* + * DEFINES + **************************************************************************************** + */ + +#define GLPS_FILTER_USER_FACING_TIME_SIZE (7) + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialization of the GLPS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t glps_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct glps_db_cfg* params) +{ + //------------------ create the attribute database for the profile ------------------- + uint8_t idx; + // Service content flag + uint32_t cfg_flag= GLPS_MANDATORY_MASK; + // DB Creation Statis + uint8_t status = ATT_ERR_NO_ERROR; + + //Set Configuration Flag Value + if (params->meas_ctx_supported) + { + cfg_flag |= GLPS_MEAS_CTX_PRES_MASK; + } + + // Create Glucose Database + status = attm_svc_create_db(start_hdl, ATT_SVC_GLUCOSE, (uint8_t *)&cfg_flag, + GLS_IDX_NB, NULL, env->task, &glps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, ENABLE)); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // Allocate GLPS required environment variable + struct glps_env_tag* glps_env = + (struct glps_env_tag* ) ke_malloc(sizeof(struct glps_env_tag), KE_MEM_ATT_DB); + + // Initialize GLPS environment + env->env = (prf_env_t*) glps_env; + glps_env->start_hdl = *start_hdl; + glps_env->meas_ctx_supported = params->meas_ctx_supported; + glps_env->features = params->features; + glps_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + glps_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_GLPS; + glps_task_init(&(env->desc)); + + for(idx = 0; idx < GLPS_IDX_MAX ; idx++) + { + glps_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), GLPS_FREE); + } + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the GLPS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void glps_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct glps_env_tag* glps_env = (struct glps_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < GLPS_IDX_MAX ; idx++) + { + if(glps_env->env[idx] != NULL) + { + ke_free(glps_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(glps_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void glps_create(struct prf_task_env* env, uint8_t conidx) +{ + struct glps_env_tag* glps_env = (struct glps_env_tag*) env->env; + glps_env->env[conidx] = (struct glps_cnx_env*) + ke_malloc(sizeof(struct glps_cnx_env), KE_MEM_ATT_DB); + + memset(glps_env->env[conidx], 0, sizeof(struct glps_cnx_env)); + + /* Put GLS in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), GLPS_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void glps_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct glps_env_tag* glps_env = (struct glps_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(glps_env->env[conidx] != NULL) + { + ke_free(glps_env->env[conidx]); + glps_env->env[conidx] = NULL; + } + + /* Put GLS in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), GLPS_FREE); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// GLPS Task interface required by profile manager +const struct prf_task_cbs glps_itf = +{ + (prf_init_fnct) glps_init, + glps_destroy, + glps_create, + glps_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* glps_prf_itf_get(void) +{ + return &glps_itf; +} + +uint8_t glps_pack_meas_value(uint8_t *packed_meas, const struct glp_meas* meas_val, + uint16_t seq_num) +{ + uint8_t cursor = 0; + + // Flags + packed_meas[cursor] = meas_val->flags; + cursor += 1; + + // Sequence Number + co_write16p(packed_meas + cursor, seq_num); + cursor += 2; + + // Base Time + cursor += prf_pack_date_time(packed_meas + cursor, &(meas_val->base_time)); + + //Time Offset + if((meas_val->flags & GLP_MEAS_TIME_OFF_PRES) != 0) + { + co_write16p(packed_meas + cursor, meas_val->time_offset); + cursor += 2; + } + + // Glucose Concentration, type and location + if((meas_val->flags & GLP_MEAS_GL_CTR_TYPE_AND_SPL_LOC_PRES) != 0) + { + co_write16p(packed_meas + cursor, meas_val->concentration); + cursor += 2; + + /* type and location are 2 nibble values */ + packed_meas[cursor] = (meas_val->location << 4) | (meas_val->type); + cursor += 1; + } + + // Sensor Status Annunciation + if((meas_val->flags & GLP_MEAS_SENS_STAT_ANNUN_PRES) != 0) + { + co_write16p(packed_meas + cursor, meas_val->status); + cursor += 2; + } + + return cursor; +} + + +uint8_t glps_pack_meas_ctx_value(uint8_t *packed_meas_ctx, + const struct glp_meas_ctx* meas_ctx_val, + uint16_t seq_num) +{ + uint8_t cursor = 0; + // Flags + packed_meas_ctx[cursor] = meas_ctx_val->flags; + cursor += 1; + + // Sequence Number + co_write16p(packed_meas_ctx + cursor, seq_num); + cursor += 2; + + // Extended Flags + if((meas_ctx_val->flags & GLP_CTX_EXTD_F_PRES) != 0) + { + packed_meas_ctx[cursor] = meas_ctx_val->ext_flags; + cursor += 1; + } + + // Carbohydrate ID And Carbohydrate Present + if((meas_ctx_val->flags & GLP_CTX_CRBH_ID_AND_CRBH_PRES) != 0) + { + // Carbohydrate ID + packed_meas_ctx[cursor] = meas_ctx_val->carbo_id; + cursor += 1; + // Carbohydrate Present + co_write16p(packed_meas_ctx + cursor, meas_ctx_val->carbo_val); + cursor += 2; + } + + // Meal Present + if((meas_ctx_val->flags & GLP_CTX_MEAL_PRES) != 0) + { + packed_meas_ctx[cursor] = meas_ctx_val->meal; + cursor += 1; + } + + // Tester-Health Present + if((meas_ctx_val->flags & GLP_CTX_TESTER_HEALTH_PRES) != 0) + { + // Tester and Health are 2 nibble values + packed_meas_ctx[cursor] = (meas_ctx_val->health << 4) | (meas_ctx_val->tester); + cursor += 1; + } + + // Exercise Duration & Exercise Intensity Present + if((meas_ctx_val->flags & GLP_CTX_EXE_DUR_AND_EXE_INTENS_PRES) != 0) + { + // Exercise Duration + co_write16p(packed_meas_ctx + cursor, meas_ctx_val->exercise_dur); + cursor += 2; + + // Exercise Intensity + packed_meas_ctx[cursor] = meas_ctx_val->exercise_intens; + cursor += 1; + } + + // Medication ID And Medication Present + if((meas_ctx_val->flags & GLP_CTX_MEDIC_ID_AND_MEDIC_PRES) != 0) + { + // Medication ID + packed_meas_ctx[cursor] = meas_ctx_val->med_id; + cursor += 1; + + // Medication Present + co_write16p(packed_meas_ctx + cursor, meas_ctx_val->med_val); + cursor += 2; + } + + // HbA1c Present + if((meas_ctx_val->flags & GLP_CTX_HBA1C_PRES) != 0) + { + // HbA1c + co_write16p(packed_meas_ctx + cursor, meas_ctx_val->hba1c_val); + cursor += 2; + } + + return cursor; +} + +uint8_t glps_unpack_racp_req(uint8_t *packed_val, uint16_t length, + struct glp_racp_req* racp_req) +{ + uint8_t cursor = 0; + + // verify that enough data present to load operation filter + if(length < 2) + { + return PRF_APP_ERROR; + } + + // retrieve command op code + racp_req->op_code = packed_val[cursor]; + cursor++; + + // clear filter structure + memset(&(racp_req->filter), 0, sizeof(struct glp_filter)); + + + // retrieve operator of the function + racp_req->filter.operator = packed_val[cursor]; + cursor++; + + // check if opcode is supported + if((racp_req->op_code < GLP_REQ_REP_STRD_RECS) + || (racp_req->op_code > GLP_REQ_REP_NUM_OF_STRD_RECS)) + { + return GLP_RSP_OP_CODE_NOT_SUP; + } + + // Abort operation don't require any other parameter + if(racp_req->op_code == GLP_REQ_ABORT_OP) + { + return GAP_ERR_NO_ERROR; + } + + // check if operator is valid + if(racp_req->filter.operator < GLP_OP_ALL_RECS) + { + return GLP_RSP_INVALID_OPERATOR; + } + // check if operator is supported + else if(racp_req->filter.operator > GLP_OP_LAST_REC) + { + return GLP_RSP_OPERATOR_NOT_SUP; + } + + // check if request requires operand (filter) + if((racp_req->filter.operator >= GLP_OP_LT_OR_EQ) + && (racp_req->filter.operator <= GLP_OP_WITHIN_RANGE_OF)) + { + // verify that enough data present to load operand filter + if(length < cursor) + { + return GLP_RSP_INVALID_OPERAND; + } + + // retrieve command filter type + racp_req->filter.filter_type = packed_val[cursor]; + cursor++; + + // filter uses sequence number + if(racp_req->filter.filter_type == GLP_FILTER_SEQ_NUMBER) + { + // retrieve minimum value + if((racp_req->filter.operator == GLP_OP_GT_OR_EQ) + || (racp_req->filter.operator == GLP_OP_WITHIN_RANGE_OF)) + { + // check sufficient data available + if((length - cursor) < 2) + { + return GLP_RSP_INVALID_OPERAND; + } + + // retrieve minimum value + racp_req->filter.val.seq_num.min = co_read16p(packed_val + cursor); + cursor +=2; + } + + // retrieve maximum value + if((racp_req->filter.operator == GLP_OP_LT_OR_EQ) + || (racp_req->filter.operator == GLP_OP_WITHIN_RANGE_OF)) + { + if((length - cursor) < 2) + { + return GLP_RSP_INVALID_OPERAND; + } + + // retrieve maximum value + racp_req->filter.val.seq_num.max = co_read16p(packed_val + cursor); + cursor +=2; + } + + + // check that range value is valid + if((racp_req->filter.operator == GLP_OP_WITHIN_RANGE_OF) + && (racp_req->filter.val.seq_num.min > racp_req->filter.val.seq_num.max)) + { + return GLP_RSP_INVALID_OPERAND; + } + } + // filter uses user facing time + else if (racp_req->filter.filter_type == GLP_FILTER_USER_FACING_TIME) + { + // retrieve minimum value + if((racp_req->filter.operator == GLP_OP_GT_OR_EQ) + || (racp_req->filter.operator == GLP_OP_WITHIN_RANGE_OF)) + { + // check sufficient data available + if((length - cursor) < GLPS_FILTER_USER_FACING_TIME_SIZE) + { + return GLP_RSP_INVALID_OPERAND; + } + + // retrieve minimum facing time + cursor += prf_unpack_date_time((packed_val + cursor), + &(racp_req->filter.val.time.facetime_min)); + cursor +=2; + } + + // retrieve maximum value + if((racp_req->filter.operator == GLP_OP_LT_OR_EQ) + || (racp_req->filter.operator == GLP_OP_WITHIN_RANGE_OF)) + { + if((length - cursor) < GLPS_FILTER_USER_FACING_TIME_SIZE) + { + return GLP_RSP_INVALID_OPERAND; + } + + // retrieve maximum facing time + cursor += prf_unpack_date_time((packed_val + cursor), + &(racp_req->filter.val.time.facetime_max)); + } + } + else + { + return GLP_RSP_OPERAND_NOT_SUP; + } + } + else if ((length - cursor) != 0) + { + return GLP_RSP_INVALID_OPERAND; + } + + // Check that operand is valid + return GAP_ERR_NO_ERROR; +} + +uint8_t glps_pack_racp_rsp(uint8_t *packed_val, + struct glp_racp_rsp* racp_rsp) +{ + uint8_t cursor = 0; + + // set response op code + packed_val[cursor] = racp_rsp->op_code; + cursor++; + + // set operator (null) + packed_val[cursor] = 0; + cursor++; + + // number of record + if(racp_rsp->op_code == GLP_REQ_NUM_OF_STRD_RECS_RSP) + { + co_write16(packed_val+cursor, racp_rsp->operand.num_of_record); + cursor += 2; + } + else + { + // requested opcode + packed_val[cursor] = racp_rsp->operand.rsp.op_code_req;; + cursor++; + // command status + packed_val[cursor] = racp_rsp->operand.rsp.status; + cursor++; + } + + return cursor; +} + +#endif /* BLE_GL_SENSOR */ + +/// @} GLPS diff --git a/services/ble_profiles/glp/glps/src/glps_task.c b/services/ble_profiles/glp/glps/src/glps_task.c new file mode 100644 index 0000000..2a67cfc --- /dev/null +++ b/services/ble_profiles/glp/glps/src/glps_task.c @@ -0,0 +1,724 @@ +/** + **************************************************************************************** + * @addtogroup GLPSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_GL_SENSOR) + +#include "gap.h" +#include "gattc_task.h" +#include "glps.h" +#include "glps_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * GLUCOSE PROFILE ATTRIBUTES + **************************************************************************************** + */ + + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GLPS_ENABLE_REQ message. + * The handler enables the Glucose Sensor Profile and initialize readable values. + * @param[in] msgid Id of the message received (probably unused).off + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int glps_enable_req_handler(ke_msg_id_t const msgid, + struct glps_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + struct glps_enable_rsp * cmp_evt; + + if(state == GLPS_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps); + if(!GLPS_IS(conidx, BOND_DATA_PRESENT)) + { + GLPS_SET(conidx, BOND_DATA_PRESENT); + status = GAP_ERR_NO_ERROR; + glps_env->env[conidx]->evt_cfg = param->evt_cfg; + } + } + + // send completed information to APP task that contains error status + cmp_evt = KE_MSG_ALLOC(GLPS_ENABLE_RSP, src_id, dest_id, glps_enable_rsp); + cmp_evt->status = status; + ke_msg_send(cmp_evt); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GLPS_MEAS_SEND_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int glps_meas_send_req_handler(ke_msg_id_t const msgid, + struct glps_send_meas_with_ctx_cmd const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(state == GLPS_IDLE) + { + // Get the address of the environment + struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps); + + //Cannot send another measurement in parallel + if(!GLPS_IS(conidx, SENDING_MEAS)) + { + // inform that device is sending a measurement + GLPS_SET(conidx, SENDING_MEAS); + + // check if context is supported + if((msgid == GLPS_SEND_MEAS_WITH_CTX_CMD) && !(glps_env->meas_ctx_supported)) + { + // Context not supported + status = (PRF_ERR_FEATURE_NOT_SUPPORTED); + } + // check if notifications enabled + else if(((glps_env->env[conidx]->evt_cfg & GLPS_MEAS_NTF_CFG) == 0) + || (((glps_env->env[conidx]->evt_cfg & GLPS_MEAS_CTX_NTF_CFG) == 0) + && (msgid == GLPS_SEND_MEAS_WITH_CTX_CMD))) + { + // Not allowed to send measurement if Notifications not enabled. + status = (PRF_ERR_NTF_DISABLED); + } + else + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), dest_id, + gattc_send_evt_cmd, GLP_MEAS_MAX_LEN); + + // Fill in the parameter structure + meas_val->operation = GATTC_NOTIFY; + meas_val->handle = GLPS_HANDLE(GLS_IDX_MEAS_VAL); + // pack measured value in database + meas_val->length = glps_pack_meas_value(meas_val->value, &(param->meas), param->seq_num); + + // Measurement value notification not yet sent + GLPS_CLEAR(conidx, MEAS_SENT); + + // Send the event + ke_msg_send(meas_val); + + if(msgid == GLPS_SEND_MEAS_WITH_CTX_CMD) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_ctx_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), dest_id, + gattc_send_evt_cmd, GLP_MEAS_CTX_MAX_LEN); + + // Fill in the parameter structure + meas_ctx_val->operation = GATTC_NOTIFY; + meas_ctx_val->handle = GLPS_HANDLE(GLS_IDX_MEAS_CTX_VAL); + // pack measured value in database + meas_ctx_val->length = glps_pack_meas_ctx_value(meas_ctx_val->value, &(param->ctx), param->seq_num); + + // 2 notification complete messages expected + GLPS_SET(conidx, MEAS_CTX_SENT); + + // Send the event + ke_msg_send(meas_ctx_val); + } + else + { + // 1 notification complete messages expected + GLPS_CLEAR(conidx, MEAS_CTX_SENT); + } + + status = (GAP_ERR_NO_ERROR); + } + } + } + + // send command complete if an error occurs + if(status != GAP_ERR_NO_ERROR) + { + // send completed information to APP task that contains error status + struct glps_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_CMP_EVT, src_id, + dest_id, glps_cmp_evt); + + cmp_evt->request = GLPS_SEND_MEAS_REQ_NTF_CMP; + cmp_evt->status = status; + + ke_msg_send(cmp_evt); + } + + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GLPS_SEND_RACP_RSP_CMD message. + * Send when a RACP requests is finished + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int glps_send_racp_rsp_cmd_handler(ke_msg_id_t const msgid, + struct glps_send_racp_rsp_cmd const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if(state == GLPS_IDLE) + { + // Get the address of the environment + struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps); + + // check if op code valid + if((param->op_code < GLP_REQ_REP_STRD_RECS) + || (param->op_code > GLP_REQ_REP_NUM_OF_STRD_RECS)) + { + //Wrong op code + status = PRF_ERR_INVALID_PARAM; + } + // check if RACP on going + else if((param->op_code != GLP_REQ_ABORT_OP) && !(GLPS_IS(conidx, RACP_ON_GOING))) + { + //Cannot send response since no RACP on going + status = PRF_ERR_REQ_DISALLOWED; + } + // Indication not enabled on peer device + else if((glps_env->env[conidx]->evt_cfg & GLPS_RACP_IND_CFG) == 0) + { + status = PRF_ERR_IND_DISABLED; + // There is no more RACP on going + GLPS_CLEAR(conidx, RACP_ON_GOING); + } + else + { + struct glp_racp_rsp racp_rsp; + // Allocate the GATT indication message + struct gattc_send_evt_cmd *racp_rsp_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), dest_id, + gattc_send_evt_cmd, GLP_REC_ACCESS_CTRL_MAX_LEN); + + // Fill in the parameter structure + racp_rsp_val->operation = GATTC_INDICATE; + racp_rsp_val->handle = GLPS_HANDLE(GLS_IDX_REC_ACCESS_CTRL_VAL); + + // Number of stored record calculation succeed. + if((param->op_code == GLP_REQ_REP_NUM_OF_STRD_RECS) + && ( param->status == GLP_RSP_SUCCESS)) + { + racp_rsp.op_code = GLP_REQ_NUM_OF_STRD_RECS_RSP; + racp_rsp.operand.num_of_record = param->num_of_record; + } + // Send back status information + else + { + racp_rsp.op_code = GLP_REQ_RSP_CODE; + racp_rsp.operand.rsp.op_code_req = param->op_code; + racp_rsp.operand.rsp.status = param->status; + } + + // pack measured value in database + racp_rsp_val->length = glps_pack_racp_rsp(racp_rsp_val->value, &racp_rsp); + + // There is no more RACP on going + GLPS_CLEAR(conidx, RACP_ON_GOING); + status = GAP_ERR_NO_ERROR; + + // Store that response sent by application + GLPS_SET(conidx, RACP_RSP_SENT_BY_APP); + + // send RACP Response indication + ke_msg_send(racp_rsp_val); + } + } + + if (status != GAP_ERR_NO_ERROR) + { + // send completed information about request failed + struct glps_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_CMP_EVT, src_id, dest_id, glps_cmp_evt); + cmp_evt->request = GLPS_SEND_RACP_RSP_IND_CMP; + cmp_evt->status = status; + ke_msg_send(cmp_evt); + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == GLPS_IDLE) + { + struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps); + uint8_t att_idx = GLPS_IDX(param->handle); + struct gattc_att_info_cfm * cfm; + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + // check if it's a client configuration char + if((att_idx == GLS_IDX_MEAS_NTF_CFG) + || (att_idx == GLS_IDX_MEAS_CTX_NTF_CFG) + || (att_idx == GLS_IDX_REC_ACCESS_CTRL_IND_CFG)) + { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } + else if (att_idx == GLS_IDX_REC_ACCESS_CTRL_VAL) + { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } + // not expected request + else + { + cfm->length = 0; + cfm->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + ke_msg_send(cfm); + } + + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATT_CODE_ATT_WR_CMD_IND message. + * The handler compares the new values with current ones and notifies them if they changed. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + struct glp_racp_rsp racp_rsp; + racp_rsp.op_code = 0; + + if(state == GLPS_IDLE) + { + uint8_t status = GAP_ERR_NO_ERROR; + struct gattc_write_cfm * cfm; + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps); + uint8_t att_idx = GLPS_IDX(param->handle); + + if(param->offset != 0) + { + status = ATT_ERR_UNLIKELY_ERR; + } + // check if it's a client configuration char + else if((att_idx == GLS_IDX_MEAS_NTF_CFG) + || (att_idx == GLS_IDX_MEAS_CTX_NTF_CFG) + || (att_idx == GLS_IDX_REC_ACCESS_CTRL_IND_CFG)) + { + uint16_t cli_cfg; + uint8_t evt_mask = GLPS_IND_NTF_EVT(att_idx); + + // get client configuration + cli_cfg = co_read16(&(param->value)); + + // stop indication/notification + if(cli_cfg == PRF_CLI_STOP_NTFIND) + { + glps_env->env[conidx]->evt_cfg &= ~evt_mask; + } + // start indication/notification (check that char value accept it) + else if(((att_idx == GLS_IDX_REC_ACCESS_CTRL_IND_CFG) && (cli_cfg == PRF_CLI_START_IND)) + ||((att_idx != GLS_IDX_REC_ACCESS_CTRL_IND_CFG) && (cli_cfg == PRF_CLI_START_NTF))) + { + glps_env->env[conidx]->evt_cfg |= evt_mask; + } + // improper value + else + { + status = GLP_ERR_IMPROPER_CLI_CHAR_CFG; + } + + if (status == GAP_ERR_NO_ERROR) + { + //Inform APP of configuration change + struct glps_cfg_indntf_ind * ind = KE_MSG_ALLOC(GLPS_CFG_INDNTF_IND, + prf_dst_task_get(&(glps_env->prf_env), conidx), dest_id, glps_cfg_indntf_ind); + ind->evt_cfg = glps_env->env[conidx]->evt_cfg; + ke_msg_send(ind); + } + } + + else if (att_idx == GLS_IDX_REC_ACCESS_CTRL_VAL) + { + if((glps_env->env[conidx]->evt_cfg & GLPS_RACP_IND_CFG) == 0) + { + // do nothing since indication not enabled for this characteristic + status = GLP_ERR_IMPROPER_CLI_CHAR_CFG; + } + // If a request is on going + else if(GLPS_IS(conidx, RACP_ON_GOING)) + { + // if it's an abort command, execute it. + if((param->offset == 0) && (param->value[0] == GLP_REQ_ABORT_OP)) + { + //forward abort operation to application + struct glps_racp_req_rcv_ind * req = KE_MSG_ALLOC(GLPS_RACP_REQ_RCV_IND, + prf_dst_task_get(&(glps_env->prf_env), conidx), dest_id, glps_racp_req_rcv_ind); + req->racp_req.op_code = GLP_REQ_ABORT_OP; + req->racp_req.filter.operator = 0; + ke_msg_send(req); + } + else + { + // do nothing since a procedure already in progress + status = GLP_ERR_PROC_ALREADY_IN_PROGRESS; + } + } + else + { + struct glp_racp_req racp_req; + // unpack record access control point value + uint8_t reqstatus = glps_unpack_racp_req(param->value, param->length, &racp_req); + + // check unpacked status + switch(reqstatus) + { + case PRF_APP_ERROR: + { + /* Request failed */ + status = ATT_ERR_UNLIKELY_ERR; + } + break; + case GAP_ERR_NO_ERROR: + { + // check wich request shall be send to api task + switch(racp_req.op_code) + { + case GLP_REQ_REP_STRD_RECS: + case GLP_REQ_DEL_STRD_RECS: + case GLP_REQ_REP_NUM_OF_STRD_RECS: + { + //forward request operation to application + struct glps_racp_req_rcv_ind * req = KE_MSG_ALLOC(GLPS_RACP_REQ_RCV_IND, + prf_dst_task_get(&(glps_env->prf_env), conidx), dest_id, + glps_racp_req_rcv_ind); + req->racp_req = racp_req; + // RACP on going. + GLPS_SET(conidx, RACP_ON_GOING); + ke_msg_send(req); + } + break; + case GLP_REQ_ABORT_OP: + { + // nothing to abort, send an error message. + racp_rsp.op_code = GLP_REQ_RSP_CODE; + racp_rsp.operand.rsp.op_code_req = + racp_req.op_code; + racp_rsp.operand.rsp.status = GLP_RSP_ABORT_UNSUCCESSFUL; + } + break; + default: + { + // nothing to do since it's handled during unpack + } + break; + } + } + break; + default: + { + /* There is an error in record access control request, inform peer + * device that request is incorrect. */ + racp_rsp.op_code = GLP_REQ_RSP_CODE; + racp_rsp.operand.rsp.op_code_req = racp_req.op_code; + racp_rsp.operand.rsp.status = reqstatus; + } + break; + } + } + } + // not expected request + else + { + status = ATT_ERR_WRITE_NOT_PERMITTED; + } + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + + /* The racp response has to be sent - after write confirm */ + if(racp_rsp.op_code != 0) + { + // Allocate the GATT indication message + struct gattc_send_evt_cmd *racp_rsp_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), dest_id, + gattc_send_evt_cmd, GLP_REC_ACCESS_CTRL_MAX_LEN); + + racp_rsp_val->operation = GATTC_INDICATE; + racp_rsp_val->handle = param->handle; + // pack measured value in database + racp_rsp_val->length = glps_pack_racp_rsp(racp_rsp_val->value, &racp_rsp); + + // Store that response internally sent by profile + GLPS_CLEAR(conidx, RACP_RSP_SENT_BY_APP); + + // send RACP Response indication + ke_msg_send(racp_rsp_val); + } + } + + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + ke_state_t state = ke_state_get(dest_id); + + if(state == GLPS_IDLE) + { + // Send value to peer device. + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->handle = param->handle; + cfm->status = ATT_ERR_NO_ERROR; + cfm->length = sizeof(uint16_t); + + + // Get the address of the environment + struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps); + uint8_t att_idx = GLPS_IDX(param->handle); + uint8_t conidx = KE_IDX_GET(dest_id); + + switch(att_idx) + { + case GLS_IDX_MEAS_NTF_CFG: + { + co_write16p(cfm->value, (glps_env->env[conidx]->evt_cfg & GLPS_MEAS_NTF_CFG) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + } + break; + case GLS_IDX_MEAS_CTX_NTF_CFG: + { + co_write16p(cfm->value, (glps_env->env[conidx]->evt_cfg & GLPS_MEAS_CTX_NTF_CFG) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + } + break; + case GLS_IDX_REC_ACCESS_CTRL_IND_CFG: + { + co_write16p(cfm->value, (glps_env->env[conidx]->evt_cfg & GLPS_RACP_IND_CFG) + ? PRF_CLI_START_IND : PRF_CLI_STOP_NTFIND); + } + break; + case GLS_IDX_FEATURE_VAL: + { + co_write16p(cfm->value, glps_env->features); + } + break; + default: + { + cfm->status = ATT_ERR_INSUFF_AUTHOR; + } + break; + } + + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY and GATT_INDICATE message meaning + * that Measurement notification/indication has been correctly sent to peer device + * + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if(state == GLPS_IDLE) + { + // Get the address of the environment + struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps); + + switch(param->operation) + { + case GATTC_NOTIFY: + { + /* send message indication if an error occurs, + * or if all notification complete event has been received + */ + if((param->status != GAP_ERR_NO_ERROR) + || (!(GLPS_IS(conidx, MEAS_CTX_SENT))) + || (GLPS_IS(conidx, MEAS_CTX_SENT) && (GLPS_IS(conidx, MEAS_SENT)))) + { + GLPS_CLEAR(conidx, SENDING_MEAS); + + // send completed information to APP task + struct glps_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_CMP_EVT, prf_dst_task_get(&(glps_env->prf_env), conidx), + dest_id, glps_cmp_evt); + + cmp_evt->request = GLPS_SEND_MEAS_REQ_NTF_CMP; + cmp_evt->status = param->status; + + ke_msg_send(cmp_evt); + } + else + { + // Measurement value notification sent + GLPS_SET(conidx, MEAS_SENT); + } + } + break; + case GATTC_INDICATE: + { + // verify if indication should be conveyed to application task + if(GLPS_IS(conidx, RACP_RSP_SENT_BY_APP)) + { + // send completed information to APP task + struct glps_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_CMP_EVT, prf_dst_task_get(&(glps_env->prf_env), conidx), + dest_id, glps_cmp_evt); + + cmp_evt->request = GLPS_SEND_RACP_RSP_IND_CMP; + cmp_evt->status = param->status; + + ke_msg_send(cmp_evt); + } + + GLPS_CLEAR(conidx, RACP_RSP_SENT_BY_APP); + } + break; + + default: break; + } + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(glps) +{ + {GLPS_ENABLE_REQ, (ke_msg_func_t) glps_enable_req_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {GLPS_SEND_MEAS_WITH_CTX_CMD, (ke_msg_func_t) glps_meas_send_req_handler}, + {GLPS_SEND_MEAS_WITHOUT_CTX_CMD, (ke_msg_func_t) glps_meas_send_req_handler}, + {GLPS_SEND_RACP_RSP_CMD, (ke_msg_func_t) glps_send_racp_rsp_cmd_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, +}; + +void glps_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct glps_env_tag *glps_env = PRF_ENV_GET(GLPS, glps); + + task_desc->msg_handler_tab = glps_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(glps_msg_handler_tab); + task_desc->state = glps_env->state; + task_desc->idx_max = GLPS_IDX_MAX; +} + +#endif /* #if (BLE_GL_SENSOR) */ + +/// @} GLPSTASK diff --git a/services/ble_profiles/hogp/hogp_common.h b/services/ble_profiles/hogp/hogp_common.h new file mode 100644 index 0000000..6b26353 --- /dev/null +++ b/services/ble_profiles/hogp/hogp_common.h @@ -0,0 +1,92 @@ +#ifndef _HOGP_COMMON_H_ +#define _HOGP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup HOGP HID Over GATT Profile + * @ingroup PROFILE + * @brief HID Over GATT Profile + * + * The HOGP module is the responsible block for implementing the HID Over GATT Profile + * functionalities in the BLE Host. + * + * The HID Over GATT Profile defines the functionality required to allow HID reports and + * HID data to be exchanged between a HID Device and a HID Host + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "prf_types.h" +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// HID Information bit values +enum hogp_info_bit +{ + /// Device capable of providing wake-up signal to a HID host + HIDS_REMOTE_WAKE_CAPABLE = 0x01, + /// Normally connectable support bit + HIDS_NORM_CONNECTABLE = 0x02, +}; + +/// HID Control Point Characteristic value keys +enum hogp_ctnl_pt +{ + /// Suspend + HOGP_CTNL_PT_SUSPEND = 0x00, + /// Exit suspend + HOGP_CTNL_PT_EXIT_SUSPEND, +}; + +/// Protocol Mode Char. value Keys +enum hogp_boot_prot_mode +{ + /// Boot Protocol Mode + HOGP_BOOT_PROTOCOL_MODE = 0x00, + /// Report Protocol Mode + HOGP_REPORT_PROTOCOL_MODE, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Report Reference structure +struct hids_report_ref +{ + ///Report ID + uint8_t report_id; + ///Report Type + uint8_t report_type; +}; + +/// HID Information structure +struct hids_hid_info +{ + /// bcdHID + uint16_t bcdHID; + /// bCountryCode + uint8_t bCountryCode; + /// Flags + uint8_t flags; +}; + + + +/// @} hogp_common + +#endif /* _HOGP_COMMON_H_ */ diff --git a/services/ble_profiles/hogp/hogpbh/api/hogpbh_task.h b/services/ble_profiles/hogp/hogpbh/api/hogpbh_task.h new file mode 100644 index 0000000..94866dc --- /dev/null +++ b/services/ble_profiles/hogp/hogpbh/api/hogpbh_task.h @@ -0,0 +1,252 @@ +#ifndef _HOGPBH_TASK_H_ +#define _HOGPBH_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup HOGPBHTASK HID Over GATT Profile Boot Host Task + * @ingroup HOGPBH + * @brief HID Over GATT Profile Boot Host Task + * + * The HOGPBHTASK is responsible for handling the messages coming in and out of the + * @ref HOGPBH monitor block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" +#include "hogp_common.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximal number of hids instances that can be handled +#define HOGPBH_NB_HIDS_INST_MAX (2) + +/// Maximal Length of Boot Report Char. Value +#define HOGPBH_BOOT_REPORT_MAX_LEN (8) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +enum hogpbh_msg_id +{ + /// Start the HID Over GATT profile - at connection + HOGPBH_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_HOGPBH), + ///Confirm that cfg connection has finished with discovery results, or that normal cnx started + HOGPBH_ENABLE_RSP, + + /// Read Characteristic Value Request + HOGPBH_READ_INFO_REQ, + /// Read Characteristic Value Request + HOGPBH_READ_INFO_RSP, + + /// Write/Configure peer device attribute Request + HOGPBH_WRITE_REQ, + /// Write/Configure peer device attribute Response + HOGPBH_WRITE_RSP, + + /// Boot Report value send to APP (after Read Request or Notification) + HOGPBH_BOOT_REPORT_IND, +}; + + +/// Characteristics +enum hogpbh_chars +{ + /// Protocol Mode + HOGPBH_CHAR_PROTO_MODE, + /// Boot Keyboard Input Report + HOGPBH_CHAR_BOOT_KB_IN_REPORT, + /// Boot Keyboard Output Report + HOGPBH_CHAR_BOOT_KB_OUT_REPORT, + /// Boot Mouse Input Report + HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT, + + HOGPBH_CHAR_MAX, +}; + + +/// Characteristic descriptors +enum hogpbh_descs +{ + /// Boot Keyboard Input Report Client Config + HOGPBH_DESC_BOOT_KB_IN_REPORT_CFG, + /// Boot Mouse Input Report Client Config + HOGPBH_DESC_BOOT_MOUSE_IN_REPORT_CFG, + + HOGPBH_DESC_MAX, +}; + + +/// Peer HID service info that can be read/write +enum hogpbh_info +{ + /// Protocol Mode + HOGPBH_PROTO_MODE, + /// Boot Keyboard Input Report + HOGPBH_BOOT_KB_IN_REPORT, + /// Boot Keyboard Output Report + HOGPBH_BOOT_KB_OUT_REPORT, + /// Boot Mouse Input Report + HOGPBH_BOOT_MOUSE_IN_REPORT, + + /// Boot Keyboard Input Report Client Config + HOGPBH_BOOT_KB_IN_NTF_CFG, + /// Boot Mouse Input Report Client Config + HOGPBH_BOOT_MOUSE_IN_NTF_CFG, + + HOGPBH_INFO_MAX, +}; + +/* + * APIs Structure + **************************************************************************************** + */ + +///Structure containing the characteristics handles, value handles and descriptors +struct hogpbh_content +{ + /// service info + struct prf_svc svc; + + /// characteristic info: + /// - Protocol Mode + /// - Boot Keyboard Input Report + /// - Boot Keyboard Output Report + /// - Boot Mouse Input Report + struct prf_char_inf chars[HOGPBH_CHAR_MAX]; + + /// Descriptor handles: + /// - Boot Keyboard Input Client Cfg + /// - Boot Mouse Input Client Cfg + struct prf_char_desc_inf descs[HOGPBH_DESC_MAX]; +}; + +/// Parameters of the @ref HOGPBH_ENABLE_REQ message +struct hogpbh_enable_req +{ + /// Connection type + uint8_t con_type; + /// Number of HIDS instances + uint8_t hids_nb; + /// Existing handle values hids + struct hogpbh_content hids[HOGPBH_NB_HIDS_INST_MAX]; +}; + +/// Parameters of the @ref HOGPBH_ENABLE_RSP message +struct hogpbh_enable_rsp +{ + ///status + uint8_t status; + /// Number of HIDS instances + uint8_t hids_nb; + /// Existing handle values hids + struct hogpbh_content hids[HOGPBH_NB_HIDS_INST_MAX]; +}; + +/// HID boot report info +struct hogpbh_boot_report +{ + /// Report Length + uint8_t length; + /// Boot Report value + uint8_t value[__ARRAY_EMPTY]; +}; + + +/// Information data +union hogpbh_data +{ + /// Protocol Mode + /// - info = HOGPBH_PROTO_MODE + uint8_t proto_mode; + ///Notification Configuration Value + /// - info = HOGPBH_BOOT_KB_IN_NTF_CFG + /// - info = HOGPBH_BOOT_MOUSE_IN_NTF_CFG + uint16_t ntf_cfg; + + /// Boot report information + /// - info = HOGPBH_BOOT_KB_IN_REPORT + /// - info = HOGPBH_BOOT_KB_OUT_REPORT + /// - info = HOGPBH_BOOT_MOUSE_IN_REPORT + struct hogpbh_boot_report report; +}; + + + +///Parameters of the @ref HOGPBH_READ_INFO_REQ message +struct hogpbh_read_info_req +{ + ///Characteristic info @see enum hogpbh_info + uint8_t info; + /// HID Service Instance - From 0 to HOGPBH_NB_HIDS_INST_MAX-1 + uint8_t hid_idx; +}; + +///Parameters of the @ref HOGPBH_READ_INFO_RSP message +struct hogpbh_read_info_rsp +{ + /// status of the request + uint8_t status; + ///Characteristic info @see enum hogpbh_info + uint8_t info; + /// HID Service Instance - From 0 to HOGPBH_NB_HIDS_INST_MAX-1 + uint8_t hid_idx; + /// Information data + union hogpbh_data data; +}; + + +///Parameters of the @ref HOGPBH_WRITE_REQ message +struct hogpbh_write_req +{ + ///Characteristic info @see enum hogpbh_info + uint8_t info; + /// HID Service Instance - From 0 to HOGPBH_NB_HIDS_INST_MAX-1 + uint8_t hid_idx; + /// Write type ( Write without Response True or Write Request) + /// - only valid for HOGPBH_BOOT_KB_OUT_REPORT + bool wr_cmd; + /// Information data + union hogpbh_data data; +}; + + +///Parameters of the @ref HOGPBH_WRITE_RSP message +struct hogpbh_write_rsp +{ + /// status of the request + uint8_t status; + ///Characteristic info @see enum hogpbh_info + uint8_t info; + /// HID Service Instance - From 0 to HOGPBH_NB_HIDS_INST_MAX-1 + uint8_t hid_idx; +}; + + +///Parameters of the @ref HOGPBH_BOOT_REPORT_IND message +struct hogpbh_boot_report_ind +{ + ///Characteristic info @see enum hogpbh_info + uint8_t info; + /// HIDS Instance + uint8_t hid_idx; + /// Report data + struct hogpbh_boot_report report; +}; + +/// @} HOGPBHTASK + +#endif /* _HOGPBH_TASK_H_ */ diff --git a/services/ble_profiles/hogp/hogpbh/src/hogpbh.c b/services/ble_profiles/hogp/hogpbh/src/hogpbh.c new file mode 100644 index 0000000..df59171 --- /dev/null +++ b/services/ble_profiles/hogp/hogpbh/src/hogpbh.c @@ -0,0 +1,207 @@ +/** + **************************************************************************************** + * @addtogroup HOGPBH + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" +#if (BLE_HID_BOOT_HOST) + +#include "hogpbh.h" +#include "hogpbh_task.h" +#include "co_math.h" +#include "gap.h" + +#include "ke_mem.h" + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the HOGPBH module. + * This function performs all the initializations of the Profile module. + * - Creation of datahide (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t hogpbh_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct hogpbh_env_tag* hogpbh_env = + (struct hogpbh_env_tag* ) ke_malloc(sizeof(struct hogpbh_env_tag), KE_MEM_ATT_DB); + + // allocate HOGPBH required environment variable + env->env = (prf_env_t*) hogpbh_env; + + hogpbh_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + hogpbh_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_HOGPBH; + hogpbh_task_init(&(env->desc)); + + for(idx = 0; idx < HOGPBH_IDX_MAX ; idx++) + { + hogpbh_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), HOGPBH_FREE); + } + + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Destruction of the HOGPBH module - due to a reset for instance. + * This function clean-up allocated memory (attribute datahide is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void hogpbh_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct hogpbh_env_tag* hogpbh_env = (struct hogpbh_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < HOGPBH_IDX_MAX ; idx++) + { + if(hogpbh_env->env[idx] != NULL) + { + if(hogpbh_env->env[idx]->operation != NULL) + { + ke_free(hogpbh_env->env[idx]->operation); + } + ke_free(hogpbh_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(hogpbh_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void hogpbh_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put HID Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), HOGPBH_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void hogpbh_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct hogpbh_env_tag* hogpbh_env = (struct hogpbh_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(hogpbh_env->env[conidx] != NULL) + { + if(hogpbh_env->env[conidx]->operation != NULL) + { + ke_free(hogpbh_env->env[conidx]->operation); + } + ke_free(hogpbh_env->env[conidx]); + hogpbh_env->env[conidx] = NULL; + } + + /* Put HID Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), HOGPBH_FREE); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// HOGPBH Task interface required by profile manager +const struct prf_task_cbs hogpbh_itf = +{ + hogpbh_init, + hogpbh_destroy, + hogpbh_create, + hogpbh_cleanup, +}; + + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* hogpbh_prf_itf_get(void) +{ + return &hogpbh_itf; +} + +void hogpbh_enable_rsp_send(struct hogpbh_env_tag *hogpbh_env, uint8_t conidx, uint8_t status) +{ + // Counter + uint8_t svc_inst; + + // Send APP the details of the discovered attributes on HOGPBH + struct hogpbh_enable_rsp * rsp = KE_MSG_ALLOC(HOGPBH_ENABLE_RSP, + prf_dst_task_get(&(hogpbh_env->prf_env) ,conidx), + prf_src_task_get(&(hogpbh_env->prf_env) ,conidx), + hogpbh_enable_rsp); + rsp->status = status; + rsp->hids_nb = 0; + if (status == GAP_ERR_NO_ERROR) + { + rsp->hids_nb = hogpbh_env->env[conidx]->hids_nb; + + for (svc_inst = 0; svc_inst < co_min(hogpbh_env->env[conidx]->hids_nb, HOGPBH_NB_HIDS_INST_MAX) ; svc_inst++) + { + rsp->hids[svc_inst] = hogpbh_env->env[conidx]->hids[svc_inst]; + + // Register HOGPBH task in gatt for indication/notifications + prf_register_atthdl2gatt(&(hogpbh_env->prf_env), conidx, &hogpbh_env->env[conidx]->hids[svc_inst].svc); + } + } + + ke_msg_send(rsp); +} + +#endif /* (BLE_HID_BOOT_HOST) */ + +/// @} HOGPBH diff --git a/services/ble_profiles/hogp/hogpbh/src/hogpbh.h b/services/ble_profiles/hogp/hogpbh/src/hogpbh.h new file mode 100644 index 0000000..e9580c7 --- /dev/null +++ b/services/ble_profiles/hogp/hogpbh/src/hogpbh.h @@ -0,0 +1,136 @@ +#ifndef _HOGPBH_H_ +#define _HOGPBH_H_ + + +/** + **************************************************************************************** + * @addtogroup HOGPBH HID Over GATT Profile Client + * @ingroup HOGP + * @brief HID Over GATT Profile Client + * @{ + **************************************************************************************** + */ +#include "rwip_config.h" +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#if (BLE_HID_BOOT_HOST) + +#include "hogp_common.h" +#include "ke_task.h" +#include "hogpbh_task.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "prf.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +///Maximum number of HID Over GATT Boot Device task instances +#define HOGPBH_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * MACROS + **************************************************************************************** +*/ + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Possible states of the HOGPBH task +enum hogpbh_state +{ + /// Disconnected state + HOGPBH_FREE, + /// IDLE state + HOGPBH_IDLE, + /// Busy State + HOGPBH_BUSY, + /// Number of defined states. + HOGPBH_STATE_MAX +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Environment variable for each Connections +struct hogpbh_cnx_env +{ + /// on-going operation + struct ke_msg * operation; + ///HIDS characteristics + struct hogpbh_content hids[HOGPBH_NB_HIDS_INST_MAX]; + ///Number of HIDS instances found + uint8_t hids_nb; +}; + +/// HID Over Gatt Profile Boot Host environment variable +struct hogpbh_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct hogpbh_cnx_env* env[HOGPBH_IDX_MAX]; + /// State of different task instances + ke_state_t state[HOGPBH_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * GLOBAL FUNCTIONS DECLARATIONS + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Retrieve HID boot host profile interface + * + * @return HID boot host profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* hogpbh_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send HID ATT DB discovery results to HOGPBH host. + **************************************************************************************** + */ +void hogpbh_enable_rsp_send(struct hogpbh_env_tag *hogpbh_env, uint8_t conidx, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void hogpbh_task_init(struct ke_task_desc *task_desc); + + + +#endif /* (BLE_HID_BOOT_HOST) */ + +/// @} HOGPBH + +#endif /* _HOGPBH_H_ */ diff --git a/services/ble_profiles/hogp/hogpbh/src/hogpbh_task.c b/services/ble_profiles/hogp/hogpbh/src/hogpbh_task.c new file mode 100644 index 0000000..42145c6 --- /dev/null +++ b/services/ble_profiles/hogp/hogpbh/src/hogpbh_task.c @@ -0,0 +1,699 @@ +/** + **************************************************************************************** + * @addtogroup HOGPBHTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_HID_BOOT_HOST) + +#include "gap.h" +#include "attm.h" +#include "hogpbh_task.h" +#include "hogpbh.h" +#include "gattc_task.h" +#include "hogp_common.h" + +#include "ke_mem.h" +#include "co_utils.h" +#include "co_math.h" + +/* + * LOCAL VARIABLES DEFINITION + **************************************************************************************** + */ + +/// State machine used to retrieve HID Service characteristics information +const struct prf_char_def hogpbh_hids_char[HOGPBH_CHAR_MAX] = +{ + /// Protocol Mode + [HOGPBH_CHAR_PROTO_MODE] = {ATT_CHAR_PROTOCOL_MODE, + ATT_MANDATORY, + ATT_CHAR_PROP_RD | ATT_CHAR_PROP_WR_NO_RESP}, + /// Boot Keyboard Input Report + [HOGPBH_CHAR_BOOT_KB_IN_REPORT] = {ATT_CHAR_BOOT_KB_IN_REPORT, + ATT_OPTIONAL, + ATT_CHAR_PROP_RD | ATT_CHAR_PROP_NTF}, + /// Boot Keyboard Output Report + [HOGPBH_CHAR_BOOT_KB_OUT_REPORT] = {ATT_CHAR_BOOT_KB_OUT_REPORT, + ATT_OPTIONAL, + ATT_CHAR_PROP_RD | ATT_CHAR_PROP_WR}, + /// Boot Keyboard Output Report + [HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT] = {ATT_CHAR_BOOT_MOUSE_IN_REPORT, + ATT_OPTIONAL, + ATT_CHAR_PROP_RD | ATT_CHAR_PROP_NTF}, +}; + +/// State machine used to retrieve HID Service characteristic description information +const struct prf_char_desc_def hogpbh_hids_char_desc[HOGPBH_DESC_MAX] = +{ + /// Boot Keyboard Input Report Client Config + [HOGPBH_DESC_BOOT_KB_IN_REPORT_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_OPTIONAL, HOGPBH_CHAR_BOOT_KB_IN_REPORT}, + /// Boot Mouse Input Report Client Config + [HOGPBH_DESC_BOOT_MOUSE_IN_REPORT_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_OPTIONAL, HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT}, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HOGPBH_ENABLE_REQ message. + * The handler enables the HID Over GATT Profile Boot Host Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hogpbh_enable_req_handler(ke_msg_id_t const msgid, + struct hogpbh_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + int msg_status = KE_MSG_CONSUMED; + + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Battery service Client Role Task Environment + struct hogpbh_env_tag *hogpbh_env = PRF_ENV_GET(HOGPBH, hogpbh); + + ASSERT_INFO(hogpbh_env != NULL, dest_id, src_id); + if((state == HOGPBH_IDLE) && (hogpbh_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + hogpbh_env->env[conidx] = (struct hogpbh_cnx_env*) ke_malloc(sizeof(struct hogpbh_cnx_env),KE_MEM_ATT_DB); + memset(hogpbh_env->env[conidx], 0, sizeof(struct hogpbh_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering HID on peer + prf_disc_svc_send(&(hogpbh_env->prf_env), conidx, ATT_SVC_HID); + + // Go to DISCOVERING state + ke_state_set(dest_id, HOGPBH_BUSY); + hogpbh_env->env[conidx]->operation = ke_param2msg(param); + msg_status = KE_MSG_NO_FREE; + } + //normal connection, get saved att details + else + { + hogpbh_env->env[conidx]->hids_nb = param->hids_nb; + memcpy(&(hogpbh_env->env[conidx]->hids[0]), &(param->hids[0]), sizeof(struct hogpbh_content) * HOGPBH_NB_HIDS_INST_MAX); + + //send APP confirmation that can start normal connection to TH + hogpbh_enable_rsp_send(hogpbh_env, conidx, GAP_ERR_NO_ERROR); + } + } + else if(state != HOGPBH_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + hogpbh_enable_rsp_send(hogpbh_env, conidx, status); + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == HOGPBH_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct hogpbh_env_tag *hogpbh_env = PRF_ENV_GET(HOGPBH, hogpbh); + + ASSERT_INFO(hogpbh_env != NULL, dest_id, src_id); + ASSERT_INFO(hogpbh_env->env[conidx] != NULL, dest_id, src_id); + + if(hogpbh_env->env[conidx]->hids_nb < HOGPBH_NB_HIDS_INST_MAX) + { + // Retrieve HID characteristics + prf_extract_svc_info(ind, HOGPBH_CHAR_MAX, &hogpbh_hids_char[0], + &(hogpbh_env->env[conidx]->hids[hogpbh_env->env[conidx]->hids_nb].chars[0]), + HOGPBH_DESC_MAX, &hogpbh_hids_char_desc[0], + &(hogpbh_env->env[conidx]->hids[hogpbh_env->env[conidx]->hids_nb].descs[0])); + + // Store service range + hogpbh_env->env[conidx]->hids[hogpbh_env->env[conidx]->hids_nb].svc.shdl = ind->start_hdl; + hogpbh_env->env[conidx]->hids[hogpbh_env->env[conidx]->hids_nb].svc.ehdl = ind->end_hdl; + } + + hogpbh_env->env[conidx]->hids_nb++; + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HOGPBH_READ_INFO_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hogpbh_read_info_req_handler(ke_msg_id_t const msgid, struct hogpbh_read_info_req const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(state == HOGPBH_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct hogpbh_env_tag *hogpbh_env = PRF_ENV_GET(HOGPBH, hogpbh); + ASSERT_INFO(hogpbh_env != NULL, dest_id, src_id); + // environment variable not ready + if(hogpbh_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + // check parameter range + else if(param->hid_idx > hogpbh_env->env[conidx]->hids_nb) + { + status = PRF_ERR_INVALID_PARAM; + } + else + { + uint16_t handle = ATT_INVALID_HANDLE; + status = PRF_ERR_INEXISTENT_HDL; + + // check requested info + switch(param->info) + { + /// Protocol Mode + case HOGPBH_PROTO_MODE: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].chars[HOGPBH_CHAR_PROTO_MODE].val_hdl; + }break; + /// Boot Keyboard Input Report + case HOGPBH_BOOT_KB_IN_REPORT: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].chars[HOGPBH_CHAR_BOOT_KB_IN_REPORT].val_hdl; + }break; + /// Boot Keyboard Output Report + case HOGPBH_BOOT_KB_OUT_REPORT: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].chars[HOGPBH_CHAR_BOOT_KB_OUT_REPORT].val_hdl; + }break; + /// Boot Mouse Input Report + case HOGPBH_BOOT_MOUSE_IN_REPORT: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].chars[HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT].val_hdl; + }break; + /// Boot Keyboard Input Report Client Config + case HOGPBH_BOOT_KB_IN_NTF_CFG: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].descs[HOGPBH_DESC_BOOT_KB_IN_REPORT_CFG].desc_hdl; + }break; + /// Boot Mouse Input Report Client Config + case HOGPBH_BOOT_MOUSE_IN_NTF_CFG: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].descs[HOGPBH_DESC_BOOT_MOUSE_IN_REPORT_CFG].desc_hdl; + }break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + }break; + } + + if(handle != ATT_INVALID_HANDLE) + { + status = GAP_ERR_NO_ERROR; + // read information + prf_read_char_send(&(hogpbh_env->prf_env), conidx, + hogpbh_env->env[conidx]->hids[param->hid_idx].svc.shdl, + hogpbh_env->env[conidx]->hids[param->hid_idx].svc.ehdl, handle); + + // store context of request and go into busy state + hogpbh_env->env[conidx]->operation = ke_param2msg(param); + ke_state_set(dest_id, HOGPBH_BUSY); + msg_status = KE_MSG_NO_FREE; + } + } + } + // process message later + else if (state == HOGPBH_BUSY) + { + status = GAP_ERR_NO_ERROR; + msg_status = KE_MSG_SAVED; + } + + + // request cannot be performed + if(status != GAP_ERR_NO_ERROR) + { + struct hogpbh_read_info_rsp * rsp = KE_MSG_ALLOC(HOGPBH_READ_INFO_RSP, + src_id, dest_id, hogpbh_read_info_rsp); + // set error status + rsp->status = status; + rsp->info = param->info; + rsp->hid_idx = param->hid_idx; + + ke_msg_send(rsp); + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HOGPBH_WRITE_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hogpbh_write_req_handler(ke_msg_id_t const msgid, struct hogpbh_write_req const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(state == HOGPBH_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct hogpbh_env_tag *hogpbh_env = PRF_ENV_GET(HOGPBH, hogpbh); + ASSERT_INFO(hogpbh_env != NULL, dest_id, src_id); + // environment variable not ready + if(hogpbh_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + // check parameter range + else if((param->hid_idx > hogpbh_env->env[conidx]->hids_nb) + || (param->info > HOGPBH_INFO_MAX) + || ((param->info >= HOGPBH_BOOT_KB_IN_NTF_CFG) && (param->data.ntf_cfg > PRF_CLI_START_NTF))) + { + status = PRF_ERR_INVALID_PARAM; + } + else + { + uint16_t handle = ATT_INVALID_HANDLE; + status = PRF_ERR_INEXISTENT_HDL; + + // check requested info + switch(param->info) + { + // Protocol Mode + case HOGPBH_PROTO_MODE: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].chars[HOGPBH_CHAR_PROTO_MODE].val_hdl; + prf_gatt_write(&hogpbh_env->prf_env, conidx, handle, (uint8_t*)¶m->data.proto_mode, 1, GATTC_WRITE_NO_RESPONSE); + }break; + // Boot Keyboard Input Report + case HOGPBH_BOOT_KB_IN_REPORT: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].chars[HOGPBH_CHAR_BOOT_KB_IN_REPORT].val_hdl; + prf_gatt_write(&hogpbh_env->prf_env, conidx, handle, (uint8_t*)param->data.report.value, param->data.report.length, GATTC_WRITE); + }break; + // Boot Keyboard Output Report + case HOGPBH_BOOT_KB_OUT_REPORT: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].chars[HOGPBH_CHAR_BOOT_KB_OUT_REPORT].val_hdl; + prf_gatt_write(&hogpbh_env->prf_env, conidx, handle, (uint8_t*)param->data.report.value, param->data.report.length, param->wr_cmd ? GATTC_WRITE_NO_RESPONSE : GATTC_WRITE); + }break; + // Boot Mouse Input Report + case HOGPBH_BOOT_MOUSE_IN_REPORT: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].chars[HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT].val_hdl; + prf_gatt_write(&hogpbh_env->prf_env, conidx, handle, (uint8_t*)param->data.report.value, param->data.report.length, GATTC_WRITE); + }break; + // Boot Keyboard Input Report Client Config + case HOGPBH_BOOT_KB_IN_NTF_CFG: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].descs[HOGPBH_DESC_BOOT_KB_IN_REPORT_CFG].desc_hdl; + prf_gatt_write_ntf_ind(&hogpbh_env->prf_env, conidx, handle, param->data.ntf_cfg); + }break; + // Boot Mouse Input Report Client Config + case HOGPBH_BOOT_MOUSE_IN_NTF_CFG: + { + handle = hogpbh_env->env[conidx]->hids[param->hid_idx].descs[HOGPBH_DESC_BOOT_MOUSE_IN_REPORT_CFG].desc_hdl; + prf_gatt_write_ntf_ind(&hogpbh_env->prf_env, conidx, handle, param->data.ntf_cfg); + }break; + default: + { + status = PRF_ERR_INVALID_PARAM; + }break; + } + + if(handle != ATT_INVALID_HANDLE) + { + status = GAP_ERR_NO_ERROR; + + // store context of request and go into busy state + hogpbh_env->env[conidx]->operation = ke_param2msg(param); + ke_state_set(dest_id, HOGPBH_BUSY); + msg_status = KE_MSG_NO_FREE; + } + } + } + // process message later + else if (state == HOGPBH_BUSY) + { + status = GAP_ERR_NO_ERROR; + msg_status = KE_MSG_SAVED; + } + + + // request cannot be performed + if(status != GAP_ERR_NO_ERROR) + { + struct hogpbh_write_rsp * rsp = KE_MSG_ALLOC(HOGPBH_WRITE_RSP, + src_id, dest_id, hogpbh_write_rsp); + // set error status + rsp->status = status; + rsp->info = param->info; + rsp->hid_idx = param->hid_idx; + + ke_msg_send(rsp); + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct hogpbh_env_tag *hogpbh_env = PRF_ENV_GET(HOGPBH, hogpbh); + + // sanity check + if((state == HOGPBH_BUSY) && (hogpbh_env->env[conidx] != NULL) + && (hogpbh_env->env[conidx]->operation != NULL)) + { + switch(hogpbh_env->env[conidx]->operation->id) + { + case HOGPBH_ENABLE_REQ: + { + uint8_t status = param->status; + + if (param->status == ATT_ERR_NO_ERROR) + { + // check characteristic validity + if(hogpbh_env->env[conidx]->hids_nb > 0) + { + uint8_t i; + for (i = 0 ; (i < co_min(hogpbh_env->env[conidx]->hids_nb, HOGPBH_NB_HIDS_INST_MAX)) + && (status == GAP_ERR_NO_ERROR) ; i++) + { + status = prf_check_svc_char_validity(HOGPBH_CHAR_MAX, hogpbh_env->env[conidx]->hids[i].chars, + hogpbh_hids_char); + + // check descriptor validity + if(status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(HOGPBH_DESC_MAX, + hogpbh_env->env[conidx]->hids[i].descs, hogpbh_hids_char_desc, + hogpbh_env->env[conidx]->hids[i].chars); + } + } + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + } + hogpbh_enable_rsp_send(hogpbh_env, conidx, status); + }break; + case HOGPBH_READ_INFO_REQ: + { + struct hogpbh_read_info_req* req = (struct hogpbh_read_info_req*) ke_msg2param(hogpbh_env->env[conidx]->operation); + + struct hogpbh_read_info_rsp * rsp = KE_MSG_ALLOC(HOGPBH_READ_INFO_RSP, + prf_dst_task_get(&(hogpbh_env->prf_env), conidx), dest_id, hogpbh_read_info_rsp); + // set error status + rsp->status = param->status; + rsp->hid_idx = req->hid_idx; + rsp->info = req->info; + + ke_msg_send(rsp); + + }break; + case HOGPBH_WRITE_REQ: + { + struct hogpbh_write_req* req = (struct hogpbh_write_req*) ke_msg2param(hogpbh_env->env[conidx]->operation); + + struct hogpbh_write_rsp * rsp = KE_MSG_ALLOC(HOGPBH_WRITE_RSP, + prf_dst_task_get(&(hogpbh_env->prf_env), conidx), dest_id, hogpbh_write_rsp); + // set error status + rsp->status =param->status; + rsp->hid_idx = req->hid_idx; + rsp->info = req->info; + + ke_msg_send(rsp); + }break; + default: + { + // Not Expected at all + ASSERT_ERR(0); + }break; + } + + // operation is over - go back to idle state + ke_free(hogpbh_env->env[conidx]->operation); + hogpbh_env->env[conidx]->operation = NULL; + ke_state_set(dest_id, HOGPBH_IDLE); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == HOGPBH_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct hogpbh_env_tag *hogpbh_env = PRF_ENV_GET(HOGPBH, hogpbh); + struct hogpbh_read_info_req* req = (struct hogpbh_read_info_req*) ke_msg2param(hogpbh_env->env[conidx]->operation); + + ASSERT_INFO(hogpbh_env != NULL, dest_id, src_id); + ASSERT_INFO(hogpbh_env->env[conidx] != NULL, dest_id, src_id); + + + struct hogpbh_read_info_rsp * rsp = KE_MSG_ALLOC_DYN(HOGPBH_READ_INFO_RSP, + prf_dst_task_get(&(hogpbh_env->prf_env),conidx), dest_id, hogpbh_read_info_rsp, param->length); + + // set error status + rsp->status = GAP_ERR_NO_ERROR; + rsp->hid_idx = req->hid_idx; + rsp->info = req->info; + + switch(req->info) + { + /// Protocol Mode + case HOGPBH_PROTO_MODE: + { + rsp->data.proto_mode = param->value[0]; + }break; + /// Boot Keyboard Input Report + case HOGPBH_BOOT_KB_IN_REPORT: + /// Boot Keyboard Output Report + case HOGPBH_BOOT_KB_OUT_REPORT: + /// Boot Mouse Input Report + case HOGPBH_BOOT_MOUSE_IN_REPORT: + { + rsp->data.report.length = param->length; + memcpy(rsp->data.report.value, param->value, param->length); + }break; + /// Boot Keyboard Input Report Client Config + case HOGPBH_BOOT_KB_IN_NTF_CFG: + /// Boot Mouse Input Report Client Config + case HOGPBH_BOOT_MOUSE_IN_NTF_CFG: + { + rsp->data.ntf_cfg = co_read16p(param->value); + }break; + default: + { + ASSERT_ERR(0); + }break; + } + + // send response + ke_msg_send(rsp); + + // operation is over - go back to idle state + ke_free(hogpbh_env->env[conidx]->operation); + hogpbh_env->env[conidx]->operation = NULL; + ke_state_set(dest_id, HOGPBH_IDLE); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state != HOGPBH_FREE) + { + // HID Instance + uint8_t hid_nb; + uint8_t att_info = HOGPBH_INFO_MAX; + uint8_t conidx = KE_IDX_GET(src_id); + // Get the address of the environment + struct hogpbh_env_tag *hogpbh_env = PRF_ENV_GET(HOGPBH, hogpbh); + + // BOOT Report - HID instance is unknown. + for (hid_nb = 0; (hid_nb < hogpbh_env->env[conidx]->hids_nb); hid_nb++) + { + if (param->handle == hogpbh_env->env[conidx]->hids[hid_nb].chars[HOGPBH_CHAR_BOOT_KB_IN_REPORT].val_hdl) + { + att_info = HOGPBH_BOOT_KB_IN_REPORT; + break; + } + else if (param->handle == hogpbh_env->env[conidx]->hids[hid_nb].chars[HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT].val_hdl) + { + att_info = HOGPBH_BOOT_MOUSE_IN_REPORT; + break; + } + } + + // check if indication can be handled + if(att_info != HOGPBH_INFO_MAX) + { + // send boot report indication + struct hogpbh_boot_report_ind* ind = KE_MSG_ALLOC_DYN(HOGPBH_BOOT_REPORT_IND, + prf_dst_task_get(&(hogpbh_env->prf_env), conidx), dest_id, + hogpbh_boot_report_ind, param->length); + + ind->hid_idx = hid_nb; + ind->info = att_info; + ind->report.length = param->length; + memcpy(ind->report.value, param->value, param->length); + + ke_msg_send(ind); + } + } + + return (KE_MSG_CONSUMED); +} + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(hogpbh) +{ + {HOGPBH_ENABLE_REQ, (ke_msg_func_t)hogpbh_enable_req_handler}, + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + + {HOGPBH_READ_INFO_REQ, (ke_msg_func_t)hogpbh_read_info_req_handler}, + {HOGPBH_WRITE_REQ, (ke_msg_func_t)hogpbh_write_req_handler}, + + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void hogpbh_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct hogpbh_env_tag *hogpbh_env = PRF_ENV_GET(HOGPBH, hogpbh); + + task_desc->msg_handler_tab = hogpbh_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(hogpbh_msg_handler_tab); + task_desc->state = hogpbh_env->state; + task_desc->idx_max = HOGPBH_IDX_MAX; +} + +#endif /* (BLE_HOG_BOOT_HOST) */ +/// @} HOGPBHTASK diff --git a/services/ble_profiles/hogp/hogpd/api/hogpd_task.h b/services/ble_profiles/hogp/hogpd/api/hogpd_task.h new file mode 100644 index 0000000..19ac9d4 --- /dev/null +++ b/services/ble_profiles/hogp/hogpd/api/hogpd_task.h @@ -0,0 +1,305 @@ +#ifndef _HOGPD_TASK_H_ +#define _HOGPD_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup HOGPDTASK Task + * @ingroup HOGPD + * @brief HID Over GATT Profile Task. + * + * The HOGPD_TASK is responsible for handling the messages coming in and out of the + * @ref HOGPD block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include +#include "rwip_task.h" // Task definitions +#include "hogp_common.h" +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximal number of HIDS that can be added in the DB +#define HOGPD_NB_HIDS_INST_MAX (2) +/// Maximal number of Report Char. that can be added in the DB for one HIDS - Up to 11 +#define HOGPD_NB_REPORT_INST_MAX (5) + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Messages for HID Over GATT Profile Device Role +enum hogpd_msg_id +{ + /// Restore bond data the HID Over GATT Profile Device Role Task + HOGPD_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_HOGPD), + /// Response of enabled request + HOGPD_ENABLE_RSP, + + /// Request sending of a report to the host - notification + HOGPD_REPORT_UPD_REQ, + /// Response sending of a report to the host + HOGPD_REPORT_UPD_RSP, + + + /// Request from peer device to Read or update a report value + HOGPD_REPORT_REQ_IND, + /// Confirmation for peer device for Reading or Updating a report value + HOGPD_REPORT_CFM, + + /// Inform Device APP that Protocol Mode Characteristic Value has been written on Device + HOGPD_PROTO_MODE_REQ_IND, + /// Confirm if the new protocol mode value + HOGPD_PROTO_MODE_CFM, + + /// Inform Device APP that a Client Characteristic Configuration has been modified + HOGPD_NTF_CFG_IND, + /// Inform APP that HID Control Point Characteristic Value has been written on Device + HOGPD_CTNL_PT_IND, +}; + +/// Report Char. Configuration Flag Values +enum hogpd_report_cfg +{ + /// Input Report + HOGPD_CFG_REPORT_IN = 0x01, + /// Output Report + HOGPD_CFG_REPORT_OUT = 0x02, + //HOGPD_CFG_REPORT_FEAT can be used as a mask to check Report type + /// Feature Report + HOGPD_CFG_REPORT_FEAT = 0x03, + /// Input report with Write capabilities + HOGPD_CFG_REPORT_WR = 0x10, +}; + +/// Features Flag Values +enum hogpd_cfg +{ + /// Keyboard Device + HOGPD_CFG_KEYBOARD = 0x01, + /// Mouse Device + HOGPD_CFG_MOUSE = 0x02, + /// Protocol Mode present + HOGPD_CFG_PROTO_MODE = 0x04, + /// Extended Reference Present + HOGPD_CFG_MAP_EXT_REF = 0x08, + /// Boot Keyboard Report write capability + HOGPD_CFG_BOOT_KB_WR = 0x10, + /// Boot Mouse Report write capability + HOGPD_CFG_BOOT_MOUSE_WR = 0x20, + + /// Valid Feature mask + HOGPD_CFG_MASK = 0x3F, + + /// Report Notification Enabled (to be shift for each report index) + HOGPD_CFG_REPORT_NTF_EN = 0x40, +}; + +/// Type of reports +enum hogpd_report_type +{ + /// The Report characteristic is used to exchange data between a HID Device and a HID Host. + HOGPD_REPORT, + /// The Report Map characteristic + HOGPD_REPORT_MAP, + /// Boot Keyboard Input Report + HOGPD_BOOT_KEYBOARD_INPUT_REPORT, + /// Boot Keyboard Output Report + HOGPD_BOOT_KEYBOARD_OUTPUT_REPORT, + /// Boot Mouse Input Report + HOGPD_BOOT_MOUSE_INPUT_REPORT, +}; + +/// type of operation requested by peer device +enum hogpd_op +{ + /// No operation + HOGPD_OP_NO, + /// Read report value + HOGPD_OP_REPORT_READ, + /// Modify/Set report value + HOGPD_OP_REPORT_WRITE, + /// Modify Protocol mode + HOGPD_OP_PROT_UPDATE, +}; + +/* + * APIs Structures + **************************************************************************************** + */ +/// External Report Reference +struct hogpd_ext_ref +{ + /// External Report Reference - Included Service + uint16_t inc_svc_hdl; + /// External Report Reference - Characteristic UUID + uint16_t rep_ref_uuid; +}; + +/// Database Creation Service Instance Configuration structure +struct hogpd_hids_cfg +{ + /// Service Features (@see enum hogpd_cfg) + uint8_t svc_features; + /// Number of Report Char. instances to add in the database + uint8_t report_nb; + /// Report Char. Configuration (@see enum hogpd_report_cfg) + uint8_t report_char_cfg[HOGPD_NB_REPORT_INST_MAX]; + /// Report id number + uint8_t report_id[HOGPD_NB_REPORT_INST_MAX]; + /// HID Information Char. Values + struct hids_hid_info hid_info; + /// External Report Reference + struct hogpd_ext_ref ext_ref; + +}; + +/// Parameters of the @ref HOGPD_CREATE_DB_REQ message +struct hogpd_db_cfg +{ + /// Number of HIDS to add + uint8_t hids_nb; + /// Initial configuration for each HIDS instance + struct hogpd_hids_cfg cfg[HOGPD_NB_HIDS_INST_MAX]; +}; + +/// Parameters of the @ref HOGPD_ENABLE_REQ message +struct hogpd_enable_req +{ + ///Connection index + uint8_t conidx; + /// Notification Configurations + uint16_t ntf_cfg[HOGPD_NB_HIDS_INST_MAX]; +}; + +/// Parameters of the @ref HOGPD_ENABLE_RSP message +struct hogpd_enable_rsp +{ + ///Connection index + uint8_t conidx; + /// status of the request + uint8_t status; +}; + +///Parameters of the @ref HOGPD_NTF_CFG_IND message +struct hogpd_ntf_cfg_ind +{ + /// Connection Index + uint8_t conidx; + /// Notification Configurations + uint16_t ntf_cfg[HOGPD_NB_HIDS_INST_MAX]; +}; + + +/// Inform Device APP that Protocol Mode Characteristic Value has been written on Device +struct hogpd_proto_mode_req_ind +{ + /// Connection Index + uint8_t conidx; + /// Operation requested (update protocol mode @see hogpd_op) + uint8_t operation; + /// HIDS Instance + uint8_t hid_idx; + /// New Protocol Mode Characteristic Value + uint8_t proto_mode; +}; + +/// Confirm if the new protocol mode value +struct hogpd_proto_mode_cfm +{ + /// Connection Index + uint8_t conidx; + /// Status of the request + uint8_t status; + /// HIDS Instance + uint8_t hid_idx; + /// New Protocol Mode Characteristic Value + uint8_t proto_mode; +}; + +/// HID Report Info +struct hogpd_report_info +{ + /// HIDS Instance + uint8_t hid_idx; + /// type of report (@see enum hogpd_report_type) + uint8_t type; + /// Report Length (uint8_t) + uint16_t length; + /// Report Instance - 0 for boot reports and report map + uint8_t idx; + /// Report data + uint8_t value[__ARRAY_EMPTY]; +}; + + +/// Request sending of a report to the host - notification +struct hogpd_report_upd_req +{ + /// Connection Index + uint8_t conidx; + /// Report Info + struct hogpd_report_info report; +}; + +/// Response sending of a report to the host +struct hogpd_report_upd_rsp +{ + /// Connection Index + uint8_t conidx; + /// Status of the request + uint8_t status; +}; + +/// Request from peer device to Read or update a report value +struct hogpd_report_req_ind +{ + /// Connection Index + uint8_t conidx; + /// Operation requested (read/write @see hogpd_op) + uint8_t operation; + /// Report Info + struct hogpd_report_info report; +}; + +/// Confirmation for peer device for Reading or Updating a report value +struct hogpd_report_cfm +{ + /// Connection Index + uint8_t conidx; + /// Operation requested (read/write @see enum hogpd_op) + uint8_t operation; + /// Status of the request + uint8_t status; + /// Report Info + struct hogpd_report_info report; +}; + + +///Parameters of the @ref HOGPD_CTNL_PT_IND message +struct hogpd_ctnl_pt_ind +{ + /// Connection Index + uint8_t conidx; + /// HIDS Instance + uint8_t hid_idx; + /// New HID Control Point Characteristic Value + uint8_t hid_ctnl_pt; +}; + + + +/// @} HOGPDTASK + +#endif /* _HOGPD_TASK_H_ */ diff --git a/services/ble_profiles/hogp/hogpd/src/hogpd.c b/services/ble_profiles/hogp/hogpd/src/hogpd.c new file mode 100644 index 0000000..9dd5217 --- /dev/null +++ b/services/ble_profiles/hogp/hogpd/src/hogpd.c @@ -0,0 +1,903 @@ +/** + **************************************************************************************** + * @addtogroup HOGPD + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_HID_DEVICE) + +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "hogpd.h" +#include "hogpd_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" + +/* + * DEFINES + **************************************************************************************** + */ +#define HIDS_CFG_FLAG_MANDATORY_MASK ((uint32_t)0x000FD) +#define HIDS_MANDATORY_ATT_NB (7) +#define HIDS_CFG_FLAG_MAP_EXT_MASK ((uint32_t)0x00102) +#define HIDS_MAP_EXT_ATT_NB (2) +#define HIDS_CFG_FLAG_PROTO_MODE_MASK ((uint32_t)0x00600) +#define HIDS_PROTO_MODE_ATT_NB (2) +#define HIDS_CFG_FLAG_KEYBOARD_MASK ((uint32_t)0x0F800) +#define HIDS_KEYBOARD_ATT_NB (5) +#define HIDS_CFG_FLAG_MOUSE_MASK ((uint32_t)0x70000) +#define HIDS_MOUSE_ATT_NB (3) + +#define HIDS_CFG_REPORT_MANDATORY_MASK ((uint32_t)0x7) +#define HIDS_REPORT_MANDATORY_ATT_NB (3) +#define HIDS_CFG_REPORT_IN_MASK ((uint32_t)0x8) +#define HIDS_REPORT_IN_ATT_NB (1) +// number of attribute index for a report +#define HIDS_REPORT_NB_IDX (4) + +/* + * HIDS ATTRIBUTES DEFINITION + **************************************************************************************** + */ + +/// Full HIDS Database Description - Used to add attributes into the database +const struct attm_desc hids_att_db[HOGPD_IDX_NB] = +{ + // HID Service Declaration + [HOGPD_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // HID Service Declaration + [HOGPD_IDX_INCL_SVC] = {ATT_DECL_INCLUDE, PERM(RD, ENABLE), 0, 0}, + + // HID Information Characteristic Declaration + [HOGPD_IDX_HID_INFO_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE),0, 0}, + // HID Information Characteristic Value + [HOGPD_IDX_HID_INFO_VAL] = {ATT_CHAR_HID_INFO, PERM(RD, ENABLE), 0, sizeof(struct hids_hid_info)}, + + // HID Control Point Characteristic Declaration + [HOGPD_IDX_HID_CTNL_PT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // HID Control Point Characteristic Value + [HOGPD_IDX_HID_CTNL_PT_VAL] = {ATT_CHAR_HID_CTNL_PT, PERM(WRITE_COMMAND, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, + + // Report Map Characteristic Declaration + [HOGPD_IDX_REPORT_MAP_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Report Map Characteristic Value + [HOGPD_IDX_REPORT_MAP_VAL] = {ATT_CHAR_REPORT_MAP, PERM(RD, ENABLE), PERM(RI, ENABLE), HOGPD_REPORT_MAP_MAX_LEN}, + // Report Map Characteristic - External Report Reference Descriptor + [HOGPD_IDX_REPORT_MAP_EXT_REP_REF] = {ATT_DESC_EXT_REPORT_REF, PERM(RD, ENABLE), 0, sizeof(uint16_t)}, + + // Protocol Mode Characteristic Declaration + [HOGPD_IDX_PROTO_MODE_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Protocol Mode Characteristic Value + [HOGPD_IDX_PROTO_MODE_VAL] = {ATT_CHAR_PROTOCOL_MODE, (PERM(RD, ENABLE) | PERM(WRITE_COMMAND, ENABLE)), PERM(RI, ENABLE), sizeof(uint8_t)}, + + // Boot Keyboard Input Report Characteristic Declaration + [HOGPD_IDX_BOOT_KB_IN_REPORT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Boot Keyboard Input Report Characteristic Value + [HOGPD_IDX_BOOT_KB_IN_REPORT_VAL] = {ATT_CHAR_BOOT_KB_IN_REPORT, (PERM(RD, ENABLE) | PERM(NTF, ENABLE)), PERM(RI, ENABLE), HOGPD_BOOT_REPORT_MAX_LEN}, + // Boot Keyboard Input Report Characteristic - Client Characteristic Configuration Descriptor + [HOGPD_IDX_BOOT_KB_IN_REPORT_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Boot Keyboard Output Report Characteristic Declaration + [HOGPD_IDX_BOOT_KB_OUT_REPORT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Boot Keyboard Output Report Characteristic Value + [HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL] = {ATT_CHAR_BOOT_KB_OUT_REPORT, (PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE) | PERM(WRITE_COMMAND, ENABLE)), PERM(RI, ENABLE), HOGPD_BOOT_REPORT_MAX_LEN}, + + // Boot Mouse Input Report Characteristic Declaration + [HOGPD_IDX_BOOT_MOUSE_IN_REPORT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Boot Mouse Input Report Characteristic Value + [HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL] = {ATT_CHAR_BOOT_MOUSE_IN_REPORT, (PERM(RD, ENABLE) | PERM(NTF, ENABLE)), PERM(RI, ENABLE), HOGPD_BOOT_REPORT_MAX_LEN,}, + // Boot Mouse Input Report Characteristic - Client Characteristic Configuration Descriptor + [HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE) | PERM(WRITE_COMMAND, ENABLE), 0, 0}, + + // Report Characteristic Declaration + [HOGPD_IDX_REPORT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Report Characteristic Value + [HOGPD_IDX_REPORT_VAL] = {ATT_CHAR_REPORT, PERM(RD, ENABLE), PERM(RI, ENABLE), HOGPD_REPORT_MAX_LEN}, + // Report Characteristic - Report Reference Descriptor + [HOGPD_IDX_REPORT_REP_REF] = {ATT_DESC_REPORT_REF, PERM(RD, ENABLE), 0, sizeof(struct hids_report_ref)}, + // Report Characteristic - Client Characteristic Configuration Descriptor + [HOGPD_IDX_REPORT_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE) | PERM(WRITE_COMMAND, ENABLE), 0, 0}, +}; + + +/** + **************************************************************************************** + * @brief Initialization of the HOGPD module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t hogpd_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct hogpd_db_cfg* params) +{ + struct hogpd_env_tag* hogpd_env = NULL; + // Service content flag - Without Report Characteristics + uint32_t cfg_flag[HOGPD_NB_HIDS_INST_MAX][(HOGPD_ATT_MAX/32) +1]; + // Start handle used to allocate service. + uint16_t shdl; + + // Total number of attributes + uint8_t tot_nb_att = 0; + + // array of service description used to allocate the service + struct attm_desc * hids_db[HOGPD_NB_HIDS_INST_MAX]; + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Service Instance Counter, Counter + uint8_t svc_idx, report_idx; + // Report Char. Report Ref value + struct hids_report_ref report_ref; + + //-------------------- allocate memory required for the profile --------------------- + hogpd_env = (struct hogpd_env_tag* ) ke_malloc(sizeof(struct hogpd_env_tag), KE_MEM_ATT_DB); + + // ensure that everything is initialized + memset(hids_db, 0, sizeof(hids_db)); + memset(cfg_flag, 0, sizeof(cfg_flag)); + memset(hogpd_env, 0, sizeof(struct hogpd_env_tag)); + + + // Check number of HID instances + if ((params->hids_nb == 0) || (params->hids_nb > HOGPD_NB_HIDS_INST_MAX)) + { + // Invalid number of service instances + status = PRF_ERR_INVALID_PARAM; + } + + // For each required HIDS instance + for (svc_idx = 0; ((svc_idx < params->hids_nb) && (status == GAP_ERR_NO_ERROR)); svc_idx++) + { + // Check number of Report Char. instances + if (params->cfg[svc_idx].report_nb > HOGPD_NB_REPORT_INST_MAX) + { + // Too many Report Char. Instances + status = PRF_ERR_INVALID_PARAM; + break; + } + + // retrieve features + hogpd_env->svcs[svc_idx].features = params->cfg[svc_idx].svc_features & HOGPD_CFG_MASK; + hogpd_env->svcs[svc_idx].nb_report = params->cfg[svc_idx].report_nb; + + hids_db[svc_idx] = (struct attm_desc *) ke_malloc(HOGPD_ATT_MAX * sizeof(struct attm_desc), KE_MEM_NON_RETENTION); + + cfg_flag[svc_idx][0] = HIDS_CFG_FLAG_MANDATORY_MASK; + hogpd_env->svcs[svc_idx].nb_att += HIDS_MANDATORY_ATT_NB; + + // copy default definition of the HID attribute database + memcpy(hids_db[svc_idx], hids_att_db, sizeof(struct attm_desc) * HOGPD_ATT_UNIQ_NB); + + //-------------------------------------------------------------------- + // Compute cfg_flag[i] without Report Characteristics + //-------------------------------------------------------------------- + if ((params->cfg[svc_idx].svc_features & HOGPD_CFG_MAP_EXT_REF) == HOGPD_CFG_MAP_EXT_REF) + { + cfg_flag[svc_idx][0] |= HIDS_CFG_FLAG_MAP_EXT_MASK; + hogpd_env->svcs[svc_idx].nb_att += HIDS_MAP_EXT_ATT_NB; + // store reference handle in database + hids_db[svc_idx][HOGPD_IDX_INCL_SVC].max_size = params->cfg[svc_idx].ext_ref.inc_svc_hdl; + } + + if ((params->cfg[svc_idx].svc_features & HOGPD_CFG_PROTO_MODE) == HOGPD_CFG_PROTO_MODE) + { + cfg_flag[svc_idx][0] |= HIDS_CFG_FLAG_PROTO_MODE_MASK; + hogpd_env->svcs[svc_idx].nb_att += HIDS_PROTO_MODE_ATT_NB; + } + + if ((params->cfg[svc_idx].svc_features & HOGPD_CFG_KEYBOARD) == HOGPD_CFG_KEYBOARD) + { + cfg_flag[svc_idx][0] |= HIDS_CFG_FLAG_KEYBOARD_MASK; + hogpd_env->svcs[svc_idx].nb_att += HIDS_KEYBOARD_ATT_NB; + + if ((params->cfg[svc_idx].svc_features & HOGPD_CFG_BOOT_KB_WR) == HOGPD_CFG_BOOT_KB_WR) + { + // Adds write permissions on report + hids_db[svc_idx][HOGPD_IDX_BOOT_KB_IN_REPORT_VAL].perm |= (PERM(WRITE_REQ, ENABLE)); + } + } + + if ((params->cfg[svc_idx].svc_features & HOGPD_CFG_MOUSE) == HOGPD_CFG_MOUSE) + { + cfg_flag[svc_idx][0] |= HIDS_CFG_FLAG_MOUSE_MASK; + hogpd_env->svcs[svc_idx].nb_att += HIDS_MOUSE_ATT_NB; + + if ((params->cfg[svc_idx].svc_features & HOGPD_CFG_BOOT_MOUSE_WR) == HOGPD_CFG_BOOT_MOUSE_WR) + { + // Adds write permissions on report + hids_db[svc_idx][HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL].perm |= (PERM(WRITE_REQ, ENABLE)); + } + } + + // set report handle offset + hogpd_env->svcs[svc_idx].report_hdl_offset = hogpd_env->svcs[svc_idx].nb_att; + + //-------------------------------------------------------------------- + // Update cfg_flag_rep[i] with Report Characteristics + //-------------------------------------------------------------------- + for (report_idx = 0; report_idx < params->cfg[svc_idx].report_nb; report_idx++) + { + uint16_t perm = 0; + uint16_t report_offset = HIDS_REPORT_NB_IDX*report_idx; + + // update config for current report + cfg_flag[svc_idx][(HOGPD_IDX_REPORT_CHAR + report_offset) / 32] |= (1 << ((HOGPD_IDX_REPORT_CHAR + report_offset) % 32)); + cfg_flag[svc_idx][(HOGPD_IDX_REPORT_VAL + report_offset) / 32] |= (1 << ((HOGPD_IDX_REPORT_VAL + report_offset) % 32)); + cfg_flag[svc_idx][(HOGPD_IDX_REPORT_REP_REF + report_offset) / 32] |= (1 << ((HOGPD_IDX_REPORT_REP_REF + report_offset) % 32)); + hogpd_env->svcs[svc_idx].nb_att += HIDS_REPORT_MANDATORY_ATT_NB; + + // copy default definition of the HID report database + memcpy(&(hids_db[svc_idx][HOGPD_IDX_REPORT_CHAR + report_offset]), &(hids_att_db[HOGPD_IDX_REPORT_CHAR]), sizeof(struct attm_desc) * HIDS_REPORT_NB_IDX); + + // according to the report type, update value property + switch (params->cfg[svc_idx].report_char_cfg[report_idx] & HOGPD_CFG_REPORT_FEAT) + { + // Input Report + case HOGPD_CFG_REPORT_IN: + { + // add notification permission on report + perm = PERM(RD, ENABLE) | PERM(NTF, ENABLE); + // Report Char. supports NTF => Client Characteristic Configuration Descriptor + cfg_flag[svc_idx][(HOGPD_IDX_REPORT_NTF_CFG + report_offset) / 32] |= (1 << ((HOGPD_IDX_REPORT_NTF_CFG + report_offset) % 32)); + hogpd_env->svcs[svc_idx].nb_att += HIDS_REPORT_IN_ATT_NB; + + // update feature flag + hogpd_env->svcs[svc_idx].features |= (HOGPD_CFG_REPORT_NTF_EN << report_idx); + + // check if attribute value could be written + if ((params->cfg[svc_idx].report_char_cfg[report_idx] & HOGPD_CFG_REPORT_WR) == HOGPD_CFG_REPORT_WR) + { + perm |= PERM(WRITE_REQ, ENABLE); + } + } break; + + // Output Report + case HOGPD_CFG_REPORT_OUT: + { + perm = PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE) | PERM(WRITE_COMMAND, ENABLE); + } break; + + // Feature Report + case HOGPD_CFG_REPORT_FEAT: + { + perm = PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE); + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + + hids_db[svc_idx][HOGPD_IDX_REPORT_VAL + (HIDS_REPORT_NB_IDX*report_idx)].perm = perm; + } + + // increment total number of attributes to allocate. + tot_nb_att += hogpd_env->svcs[svc_idx].nb_att; + } + + // Check that attribute list can be allocated. + if(status == ATT_ERR_NO_ERROR) + { + status = attm_reserve_handle_range(start_hdl, tot_nb_att); + } + + // used start handle calculated when handle range reservation has been performed + shdl = *start_hdl; + hogpd_env->start_hdl = *start_hdl; + hogpd_env->hids_nb = params->hids_nb; + // Initialize the Report ID + report_ref.report_id = 0; + + // allocate services + for (svc_idx = 0; ((svc_idx < params->hids_nb) && (status == GAP_ERR_NO_ERROR)); svc_idx++) + { + uint16_t handle; + status = attm_svc_create_db(&shdl, ATT_SVC_HID, (uint8_t *)&(cfg_flag[svc_idx][0]), + HOGPD_ATT_MAX, NULL, env->task, hids_db[svc_idx], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS))); + // update start handle for next service + shdl += hogpd_env->svcs[svc_idx].nb_att; + + // Set HID Information Char. Value + if(status == GAP_ERR_NO_ERROR) + { + handle = hogpd_get_att_handle(hogpd_env, svc_idx, HOGPD_IDX_HID_INFO_VAL, 0); + ASSERT_ERR(handle != ATT_INVALID_HDL); + status = attm_att_set_value(handle, sizeof(struct hids_hid_info), 0, (uint8_t *)¶ms->cfg[svc_idx].hid_info); + } + + // Set Report Map Char. External Report Ref value + if((status == GAP_ERR_NO_ERROR) + && ((params->cfg[svc_idx].svc_features & HOGPD_CFG_MAP_EXT_REF) == HOGPD_CFG_MAP_EXT_REF)) + { + handle = hogpd_get_att_handle(hogpd_env, svc_idx, HOGPD_IDX_REPORT_MAP_EXT_REP_REF, 0); + ASSERT_ERR(handle != ATT_INVALID_HDL); + status = attm_att_set_value(handle, sizeof(uint16_t), 0, (uint8_t *)¶ms->cfg[svc_idx].ext_ref.rep_ref_uuid); + } + + // Set Report External Ref value + for(report_idx = 0 ; (status == GAP_ERR_NO_ERROR) + && (report_idx < params->cfg[svc_idx].report_nb) ; report_idx++) + { + // Save the Report ID + report_ref.report_id = params->cfg[svc_idx].report_id[report_idx]; + // Set Report Type + report_ref.report_type = (params->cfg[svc_idx].report_char_cfg[report_idx] & HOGPD_CFG_REPORT_FEAT); + + handle = hogpd_get_att_handle(hogpd_env, svc_idx, HOGPD_IDX_REPORT_REP_REF, report_idx); + ASSERT_ERR(handle != ATT_INVALID_HDL); + // Set value in the database + status = attm_att_set_value(handle, sizeof(struct hids_report_ref), 0, (uint8_t *)&report_ref); + } + + + // by default in Report protocol mode. + hogpd_env->svcs[svc_idx].proto_mode = HOGP_REPORT_PROTOCOL_MODE; + + } + + //-------------------- Update profile task information --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // allocate HOGPD required environment variable + env->env = (prf_env_t*) hogpd_env; + hogpd_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + hogpd_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + // initialize environment variable + env->id = TASK_ID_HOGPD; + hogpd_task_init(&(env->desc)); + + // service is ready, go into an Idle state + ke_state_set(env->task, HOGPD_IDLE); + } + else if(hogpd_env != NULL) + { + ke_free(hogpd_env); + } + + // ensure that temporary allocated databases description is correctly free + for (svc_idx = 0; svc_idx < HOGPD_NB_HIDS_INST_MAX; svc_idx++) + { + if(hids_db[svc_idx] != NULL) + { + ke_free(hids_db[svc_idx]); + } + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the HOGPD module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void hogpd_destroy(struct prf_task_env* env) +{ + struct hogpd_env_tag* hogpd_env = (struct hogpd_env_tag*) env->env; + + // free profile environment variables + env->env = NULL; + ke_free(hogpd_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void hogpd_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Nothing to do */ +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void hogpd_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct hogpd_env_tag* hogpd_env = (struct hogpd_env_tag*) env->env; + uint8_t svc_idx; + ASSERT_ERR(conidx < BLE_CONNECTION_MAX); + + // Reset the notification configuration to ensure that no notification will be sent on + // a disconnected link + for (svc_idx = 0; svc_idx < hogpd_env->hids_nb; svc_idx++) + { + hogpd_env->svcs[svc_idx].ntf_cfg[conidx] = 0; + } +} + + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// HOGPD Task interface required by profile manager +const struct prf_task_cbs hogpd_itf = +{ + (prf_init_fnct) hogpd_init, + hogpd_destroy, + hogpd_create, + hogpd_cleanup, +}; + + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* hogpd_prf_itf_get(void) +{ + return &hogpd_itf; +} + + +uint16_t hogpd_get_att_handle(struct hogpd_env_tag* hogpd_env, uint8_t svc_idx, uint8_t att_idx, uint8_t report_idx) +{ + uint16_t handle = ATT_INVALID_HDL; + uint8_t i = 0; + + // Sanity check + if((svc_idx < hogpd_env ->hids_nb) && (att_idx < HOGPD_IDX_NB) + && ((att_idx < HOGPD_ATT_UNIQ_NB) || (report_idx < hogpd_env->svcs[svc_idx].nb_report))) + { + handle = hogpd_env->start_hdl; + + for(i = 0 ; i < svc_idx ; i++) + { + // update start handle for next service - only useful if multiple service, else not used. + handle += hogpd_env->svcs[i].nb_att; + } + + // increment index according to expected index + if(att_idx < HOGPD_ATT_UNIQ_NB) + { + handle += att_idx; + + // check if Keyboard feature active + if((hogpd_env->svcs[svc_idx].features & HOGPD_CFG_KEYBOARD) == 0) + { + if(att_idx > HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL) + { + handle -= HIDS_KEYBOARD_ATT_NB; + } + // Error Case + else if ((att_idx >= HOGPD_IDX_BOOT_KB_IN_REPORT_CHAR) + && (att_idx <= HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL)) + { + handle = ATT_INVALID_HANDLE; + } + } + + // check if Mouse feature active + if((hogpd_env->svcs[svc_idx].features & HOGPD_CFG_MOUSE) == 0) + { + if(att_idx > HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG) + { + handle -= HIDS_MOUSE_ATT_NB; + } + // Error Case + else if ((att_idx >= HOGPD_IDX_BOOT_MOUSE_IN_REPORT_CHAR) + && (att_idx <= HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG)) + { + handle = ATT_INVALID_HANDLE; + } + } + + // check if Protocol Mode feature active + if((hogpd_env->svcs[svc_idx].features & HOGPD_CFG_PROTO_MODE) == 0) + { + if(att_idx > HOGPD_IDX_PROTO_MODE_VAL) + { + handle -= HIDS_PROTO_MODE_ATT_NB; + } + // Error Case + else if ((att_idx >= HOGPD_IDX_PROTO_MODE_CHAR) + && (att_idx <= HOGPD_IDX_PROTO_MODE_VAL)) + { + handle = ATT_INVALID_HANDLE; + } + } + + // check if Ext Ref feature active + if((hogpd_env->svcs[svc_idx].features & HOGPD_CFG_MAP_EXT_REF) == 0) + { + if(att_idx > HOGPD_IDX_REPORT_MAP_EXT_REP_REF) + { + handle -= HIDS_MAP_EXT_ATT_NB; + } + else if(att_idx > HOGPD_IDX_INCL_SVC) + { + handle -= 1; + } + // Error Case + else if ((att_idx == HOGPD_IDX_INCL_SVC) + || (att_idx == HOGPD_IDX_REPORT_MAP_EXT_REP_REF)) + { + handle = ATT_INVALID_HANDLE; + } + } + } + else + { + handle += hogpd_env->svcs[svc_idx].report_hdl_offset; + + // increment attribute handle with other reports + for(i = 0 ; i < report_idx; i++) + { + handle += HIDS_REPORT_MANDATORY_ATT_NB; + // check if it's a Report input + if((hogpd_env->svcs[svc_idx].features & (HOGPD_CFG_REPORT_NTF_EN << i)) != 0) + { + handle += HIDS_REPORT_IN_ATT_NB; + } + } + + // Error check + if((att_idx == HOGPD_IDX_REPORT_NTF_CFG) + && ((hogpd_env->svcs[svc_idx].features & (HOGPD_CFG_REPORT_NTF_EN << report_idx)) != 0)) + { + handle = ATT_INVALID_HANDLE; + } + else + { + // update handle cursor + handle += att_idx - HOGPD_ATT_UNIQ_NB; + } + } + } + + return handle; +} + +uint8_t hogpd_get_att_idx(struct hogpd_env_tag* hogpd_env, uint16_t handle, uint8_t *svc_idx, uint8_t *att_idx, uint8_t *report_idx) +{ + uint16_t hdl_cursor = hogpd_env->start_hdl; + uint8_t status = PRF_APP_ERROR; + + // invalid index + *att_idx = HOGPD_IDX_NB; + + // Browse list of services + // handle must be greater than current index + for(*svc_idx = 0 ; (*svc_idx < hogpd_env->hids_nb) && (handle >= hdl_cursor) ; (*svc_idx)++) + { + // check if handle is on current service + if(handle >= (hdl_cursor + hogpd_env->svcs[*svc_idx].nb_att)) + { + hdl_cursor += hogpd_env->svcs[*svc_idx].nb_att; + continue; + } + + // if we are here, we are sure that handle is valid + status = GAP_ERR_NO_ERROR; + *report_idx = 0; + + // check if handle is in reports or not + if(handle < (hdl_cursor + hogpd_env->svcs[*svc_idx].report_hdl_offset)) + { + if(handle == hdl_cursor) + { + *att_idx = HOGPD_IDX_SVC; + break; + } + + // check if Ext Ref feature active + if((hogpd_env->svcs[*svc_idx].features & HOGPD_CFG_MAP_EXT_REF) != 0) + { + hdl_cursor += 1; + if(handle == hdl_cursor) + { + *att_idx = HOGPD_IDX_INCL_SVC; + break; + } + } + + // check if handle is in mandatory range + hdl_cursor += HIDS_MANDATORY_ATT_NB; + if(handle <= hdl_cursor) + { + *att_idx = HOGPD_IDX_REPORT_MAP_VAL - (hdl_cursor - handle - 1); + break; + } + + // check if Ext Ref feature active + if((hogpd_env->svcs[*svc_idx].features & HOGPD_CFG_MAP_EXT_REF) != 0) + { + hdl_cursor += 1; + if(handle == hdl_cursor) + { + *att_idx = HOGPD_IDX_REPORT_MAP_EXT_REP_REF; + break; + } + } + + // check if Protocol Mode feature active + if((hogpd_env->svcs[*svc_idx].features & HOGPD_CFG_PROTO_MODE) != 0) + { + hdl_cursor += HIDS_PROTO_MODE_ATT_NB; + if(handle <= hdl_cursor) + { + *att_idx = HOGPD_IDX_PROTO_MODE_VAL - (hdl_cursor - handle - 1); + break; + } + } + + // check if Keyboard feature active + if((hogpd_env->svcs[*svc_idx].features & HOGPD_CFG_KEYBOARD) != 0) + { + hdl_cursor += HIDS_KEYBOARD_ATT_NB; + if(handle <= hdl_cursor) + { + *att_idx = HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL - (hdl_cursor - handle - 1); + break; + } + } + + // check if Mouse feature active + if((hogpd_env->svcs[*svc_idx].features & HOGPD_CFG_MOUSE) != 0) + { + hdl_cursor += HIDS_MOUSE_ATT_NB; + if(handle <= hdl_cursor) + { + *att_idx = HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG - (hdl_cursor - handle - 1); + break; + } + } + + // not expected + ASSERT_ERR(0); + } + else + { + // add handle offset + hdl_cursor += hogpd_env->svcs[*svc_idx].report_hdl_offset; + + for(*report_idx = 0 ; (*report_idx < hogpd_env->svcs[*svc_idx].nb_report) ; (*report_idx)++) + { + hdl_cursor += HIDS_REPORT_MANDATORY_ATT_NB; + if(handle <= hdl_cursor) + { + *att_idx = HOGPD_IDX_REPORT_REP_REF - (hdl_cursor - handle - 1); + break; + } + + if((hogpd_env->svcs[*svc_idx].features & (HOGPD_CFG_REPORT_NTF_EN << *report_idx)) != 0) + { + hdl_cursor += HIDS_REPORT_IN_ATT_NB; + if(handle == hdl_cursor) + { + *att_idx = HOGPD_IDX_REPORT_NTF_CFG; + break; + } + } + } + + // not expected + ASSERT_ERR(*att_idx != HOGPD_IDX_NB); + } + // loop not expected here + break; + } + + return (status); +} + + +uint8_t hogpd_ntf_send(uint8_t conidx, const struct hogpd_report_info* report) +{ + struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd); + uint8_t status = GAP_ERR_NO_ERROR; + uint16_t handle = ATT_INVALID_HANDLE; + uint8_t att_idx = HOGPD_IDX_NB; + uint16_t max_report_len= 0; + uint16_t feature_mask = 0; + uint8_t exp_prot_mode = 0; + + // According to the report type retrieve: + // - Attribute index + // - Attribute max length + // - Feature to use + // - Expected protocol mode + switch(report->type) + { + // An Input Report + case HOGPD_REPORT: + { + att_idx = HOGPD_IDX_REPORT_VAL; + max_report_len = HOGPD_REPORT_MAX_LEN; + feature_mask = HOGPD_CFG_REPORT_NTF_EN << report->idx; + exp_prot_mode = HOGP_REPORT_PROTOCOL_MODE; + }break; + // Boot Keyboard input report + case HOGPD_BOOT_KEYBOARD_INPUT_REPORT: + { + att_idx = HOGPD_IDX_BOOT_KB_IN_REPORT_VAL; + max_report_len = HOGPD_BOOT_REPORT_MAX_LEN; + feature_mask = HOGPD_CFG_KEYBOARD; + exp_prot_mode = HOGP_BOOT_PROTOCOL_MODE; + }break; + // Boot Mouse input report + case HOGPD_BOOT_MOUSE_INPUT_REPORT: + { + att_idx = HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL; + max_report_len = HOGPD_BOOT_REPORT_MAX_LEN; + feature_mask = HOGPD_CFG_MOUSE; + exp_prot_mode = HOGP_BOOT_PROTOCOL_MODE; + }break; + + default: /* Nothing to do */ break; + } + + handle = hogpd_get_att_handle(hogpd_env, report->hid_idx, att_idx, report->idx); + + // check if attribute is found + if(handle == ATT_INVALID_HANDLE) + { + // check if it's an unsupported feature + if((feature_mask != 0) && (report->hid_idx < hogpd_env->hids_nb) + && (report->idx < hogpd_env->svcs[report->hid_idx].nb_report) + && ((hogpd_env->svcs[report->hid_idx].features & feature_mask) == 0)) + { + status = PRF_ERR_FEATURE_NOT_SUPPORTED; + } + // or an invalid param + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + // check if length is valid + else if(report->length > max_report_len) + { + status = PRF_ERR_UNEXPECTED_LEN; + } + // check if notification is enabled + else if ((hogpd_env->svcs[report->hid_idx].ntf_cfg[conidx] & feature_mask) == 0) + { + status = PRF_ERR_NTF_DISABLED; + } + // check if protocol mode is valid + else if((hogpd_env->svcs[report->hid_idx].proto_mode != exp_prot_mode) + && ((hogpd_env->svcs[report->hid_idx].features & HOGPD_CFG_PROTO_MODE) != 0)) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + if(status == GAP_ERR_NO_ERROR) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *report_ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&(hogpd_env->prf_env), conidx), + gattc_send_evt_cmd, report->length); + + // Fill in the parameter structure + report_ntf->operation = GATTC_NOTIFY; + report_ntf->handle = handle; + // pack measured value in database + report_ntf->length = report->length; + memcpy(report_ntf->value, report->value, report->length); + // send notification to peer device + ke_msg_send(report_ntf); + } + + return (status); +} + +uint8_t hogpd_ntf_cfg_ind_send(uint8_t conidx, uint8_t svc_idx, uint8_t att_idx, uint8_t report_idx, uint16_t ntf_cfg) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + uint16_t mask = 0; + + struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd); + + // set notification config update mask + switch(att_idx) + { + // An Input Report + case HOGPD_IDX_REPORT_NTF_CFG: + { + mask = HOGPD_CFG_REPORT_NTF_EN << report_idx; + }break; + // Boot Keyboard input report + case HOGPD_IDX_BOOT_KB_IN_REPORT_NTF_CFG: + { + mask = HOGPD_CFG_KEYBOARD; + }break; + // Boot Mouse input report + case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG: + { + mask = HOGPD_CFG_MOUSE; + }break; + + default: + { + ASSERT_ERR(0); + }break; + } + + // Stop notification + if (ntf_cfg == PRF_CLI_STOP_NTFIND) + { + hogpd_env->svcs[svc_idx].ntf_cfg[conidx] &= ~mask; + } + // Start notification + else if(ntf_cfg == PRF_CLI_START_NTF) + { + hogpd_env->svcs[svc_idx].ntf_cfg[conidx] |= mask; + } + // Provided value is incorrect + else + { + status = PRF_APP_ERROR; + } + + + // inform application about updated notification configuration + if(status == GAP_ERR_NO_ERROR) + { + // Allocate the GATT notification message + struct hogpd_ntf_cfg_ind *ntf_cfg_ind = KE_MSG_ALLOC(HOGPD_NTF_CFG_IND, + prf_dst_task_get(&(hogpd_env->prf_env), conidx), + prf_src_task_get(&(hogpd_env->prf_env), conidx), + hogpd_ntf_cfg_ind); + + // Fill in the parameter structure + ntf_cfg_ind->conidx = conidx; + + for(svc_idx = 0 ; svc_idx < HOGPD_NB_HIDS_INST_MAX; svc_idx++) + { + ntf_cfg_ind->ntf_cfg[svc_idx] = hogpd_env->svcs[svc_idx].ntf_cfg[conidx]; + } + + // send indication to application + ke_msg_send(ntf_cfg_ind); + } + + return (status); +} + +#endif /* BLE_HID_DEVICE */ + +/// @} HOGPD diff --git a/services/ble_profiles/hogp/hogpd/src/hogpd.h b/services/ble_profiles/hogp/hogpd/src/hogpd.h new file mode 100644 index 0000000..44206eb --- /dev/null +++ b/services/ble_profiles/hogp/hogpd/src/hogpd.h @@ -0,0 +1,271 @@ +#ifndef _HOGPD_H_ +#define _HOGPD_H_ + +/** + **************************************************************************************** + * @addtogroup HOGPD HID Over GATT Profile Device Role + * @ingroup HOGP + * @brief HID Over GATT Profile Device Role + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_HID_DEVICE) +#include "hogp_common.h" +#include "hogpd_task.h" + +#include "prf.h" +#include "prf_types.h" + + +/* + * DEFINES + **************************************************************************************** + */ + + +///Maximum number of HID Over GATT Device task instances +#define HOGPD_IDX_MAX (0x01) + +/// Maximal length of Report Char. Value +#define HOGPD_REPORT_MAX_LEN (45) +/// Maximal length of Report Map Char. Value +#define HOGPD_REPORT_MAP_MAX_LEN (512) + +/// Length of Boot Report Char. Value Maximal Length +#define HOGPD_BOOT_REPORT_MAX_LEN (8) + +/// Boot KB Input Report Notification Configuration Bit Mask +#define HOGPD_BOOT_KB_IN_NTF_CFG_MASK (0x40) +/// Boot KB Input Report Notification Configuration Bit Mask +#define HOGPD_BOOT_MOUSE_IN_NTF_CFG_MASK (0x80) +/// Boot Report Notification Configuration Bit Mask +#define HOGPD_REPORT_NTF_CFG_MASK (0x20) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the HOGPD task +enum hogpd_state +{ + /// Idle state + HOGPD_IDLE, + /// Request from application on-going + HOGPD_REQ_BUSY = (1 << 0), + /// OPeration requested by peer device on-going + HOGPD_OP_BUSY = (1 << 1), + /// Number of defined states. + HOGPD_STATE_MAX +}; + +/// HID Service Attributes Indexes +enum +{ + HOGPD_IDX_SVC, + + // Included Service + HOGPD_IDX_INCL_SVC, + + // HID Information + HOGPD_IDX_HID_INFO_CHAR, + HOGPD_IDX_HID_INFO_VAL, + + // HID Control Point + HOGPD_IDX_HID_CTNL_PT_CHAR, + HOGPD_IDX_HID_CTNL_PT_VAL, + + // Report Map + HOGPD_IDX_REPORT_MAP_CHAR, + HOGPD_IDX_REPORT_MAP_VAL, + HOGPD_IDX_REPORT_MAP_EXT_REP_REF, + + // Protocol Mode + HOGPD_IDX_PROTO_MODE_CHAR, + HOGPD_IDX_PROTO_MODE_VAL, + + // Boot Keyboard Input Report + HOGPD_IDX_BOOT_KB_IN_REPORT_CHAR, + HOGPD_IDX_BOOT_KB_IN_REPORT_VAL, + HOGPD_IDX_BOOT_KB_IN_REPORT_NTF_CFG, + + // Boot Keyboard Output Report + HOGPD_IDX_BOOT_KB_OUT_REPORT_CHAR, + HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL, + + // Boot Mouse Input Report + HOGPD_IDX_BOOT_MOUSE_IN_REPORT_CHAR, + HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL, + HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG, + + /// number of attributes that are uniq in the service + HOGPD_ATT_UNIQ_NB, + + // Report + HOGPD_IDX_REPORT_CHAR = HOGPD_ATT_UNIQ_NB, + HOGPD_IDX_REPORT_VAL, + HOGPD_IDX_REPORT_REP_REF, + HOGPD_IDX_REPORT_NTF_CFG, + + HOGPD_IDX_NB, + + // maximum number of attribute that can be present in the HID service + HOGPD_ATT_MAX = HOGPD_ATT_UNIQ_NB + (4* (HOGPD_NB_REPORT_INST_MAX)), +}; + + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// HIDS service cfg +struct hogpd_svc_cfg +{ + /// Service Features (@see enum hogpd_cfg) + uint16_t features; + /// Notification configuration + uint16_t ntf_cfg[BLE_CONNECTION_MAX]; + /// Number of attribute present in service + uint8_t nb_att; + /// Number of Report Char. instances to add in the database + uint8_t nb_report; + /// Handle offset where report are available - to enhance handle search + uint8_t report_hdl_offset; + /// Current Protocol Mode + uint8_t proto_mode; +}; + +/// HIDS on-going operation +struct hogpd_operation +{ + /// Connection index impacted + uint8_t conidx; + /// Operation type (@see enum hogpd_op) + uint8_t operation; + /// Handle impacted by operation + uint16_t handle; +}; + +/// HID Over GATT Profile HID Device Role Environment variable +struct hogpd_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Supported Features + struct hogpd_svc_cfg svcs[HOGPD_NB_HIDS_INST_MAX]; + /// HIDS Start Handles + uint16_t start_hdl; + /// On-going operation (requested by peer device) + struct hogpd_operation op; + /// HID Over GATT task state + ke_state_t state[HOGPD_IDX_MAX]; + /// Number of HIDS added in the database + uint8_t hids_nb; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve HID service profile interface + * + * @return HID service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* hogpd_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Retrieve Attribute handle from service and attribute index + * + * @param[in] hogpd_env HID Service environment + * @param[in] svc_idx HID Service index + * @param[in] att_idx Attribute index + * @param[in] report_idx Report index + * + * @return HID attribute handle or INVALID HANDLE if nothing found + **************************************************************************************** + */ +uint16_t hogpd_get_att_handle(struct hogpd_env_tag* hogpd_env, uint8_t svc_idx, uint8_t att_idx, uint8_t report_idx); + + +/** + **************************************************************************************** + * @brief Retrieve Service and attribute index form attribute handle + * + * @param[out] handle Attribute handle + * @param[out] svc_idx HID Service index + * @param[out] att_idx Attribute index + * @param[out] report_idx Report Index + * + * @return Success if attribute and service index found, else Application error + **************************************************************************************** + */ +uint8_t hogpd_get_att_idx(struct hogpd_env_tag* hogpd_env, uint16_t handle, uint8_t *svc_idx, uint8_t *att_idx, uint8_t *report_idx); + + +/** + **************************************************************************************** + * @brief Check if a report value can be notified to the peer central. + * + * @param[in] conidx Connection Index + * @param[in] report Report information to notify + * + * @return Status Code to know if request succeed or not. + **************************************************************************************** + */ +uint8_t hogpd_ntf_send(uint8_t conidx, const struct hogpd_report_info* report); + +/** + **************************************************************************************** + * @brief Send a HOGPD_NTF_CFG_IND message to the application + * + * @param[in] conidx Connection Index + * @param[in] svc_idx HID Service index + * @param[in] att_idx Attribute index + * @param[in] report_idx Report Index + * @param[in] ntf_cfg Client Characteristic Configuration Descriptor value + * + * @return Status Code to know if notification update succeed or not + **************************************************************************************** + */ +uint8_t hogpd_ntf_cfg_ind_send(uint8_t conidx, uint8_t svc_idx, uint8_t att_idx, uint8_t report_idx, uint16_t ntf_cfg); + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void hogpd_task_init(struct ke_task_desc *task_desc); + +#endif /* #if (BLE_HID_DEVICE) */ + +/// @} HOGPD + +#endif /* _HOGPD_H_ */ diff --git a/services/ble_profiles/hogp/hogpd/src/hogpd_task.c b/services/ble_profiles/hogp/hogpd/src/hogpd_task.c new file mode 100644 index 0000000..7d96bf7 --- /dev/null +++ b/services/ble_profiles/hogp/hogpd/src/hogpd_task.c @@ -0,0 +1,784 @@ +/** + **************************************************************************************** + * @addtogroup HOGPDTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_HID_DEVICE) +#include "gap.h" +#include "gattc_task.h" + +//HID Over GATT Profile Device Role Functions +#include "hogpd.h" +#include "hogpd_task.h" + +#include "prf_utils.h" + +#include "co_utils.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HOGPD_ENABLE_REQ message. + * The handler enables the HID Over GATT Profile Device Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hogpd_enable_req_handler(ke_msg_id_t const msgid, + struct hogpd_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Counter for HIDS instance + uint8_t svc_idx; + uint8_t status = GAP_ERR_NO_ERROR; + + struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd); + + ASSERT_ERR(hogpd_env!=NULL); + + // Check provided values and check if connection exists + if((param->conidx > BLE_CONNECTION_MAX) + || (gapc_get_conhdl(param->conidx) == GAP_INVALID_CONHDL)) + { + // an error occurs, trigg it. + status = (param->conidx > BLE_CONNECTION_MAX) ? GAP_ERR_INVALID_PARAM : PRF_ERR_REQ_DISALLOWED; + } + else + { + for (svc_idx = 0; svc_idx < hogpd_env->hids_nb; svc_idx++) + { + // Retrieve notification configuration + hogpd_env->svcs[svc_idx].ntf_cfg[param->conidx] = param->ntf_cfg[svc_idx]; + } + } + + // Send back response + struct hogpd_enable_rsp* rsp = KE_MSG_ALLOC(HOGPD_ENABLE_RSP, src_id, dest_id, hogpd_enable_rsp); + rsp->conidx = param->conidx; + rsp->status = status; + ke_msg_send(rsp); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HOGPD_REPORT_UPD_REQ message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hogpd_report_upd_req_handler(ke_msg_id_t const msgid, + struct hogpd_report_upd_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + + // check that task is in idle state + if((state & HOGPD_REQ_BUSY) == HOGPD_IDLE) + { + // Status + uint8_t status = PRF_ERR_INVALID_PARAM; + // Check provided values and check if connection exists + if((param->conidx > BLE_CONNECTION_MAX) + || (gapc_get_conhdl(param->conidx) == GAP_INVALID_CONHDL)) + { + status = (param->conidx > BLE_CONNECTION_MAX) ? GAP_ERR_INVALID_PARAM : PRF_ERR_REQ_DISALLOWED; + } + else + { + status = hogpd_ntf_send(param->conidx, &(param->report)); + } + + // an error occurs inform application + if (status != GAP_ERR_NO_ERROR) + { + // send report update response + struct hogpd_report_upd_rsp *rsp = KE_MSG_ALLOC(HOGPD_REPORT_UPD_RSP, + src_id, dest_id, hogpd_report_upd_rsp); + rsp->conidx = param->conidx; + rsp->status = status; + ke_msg_send(rsp); + } + // go in a busy state + else + { + ke_state_set(dest_id, state | HOGPD_REQ_BUSY); + } + } + // else process it later + else + { + msg_status = KE_MSG_SAVED; + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HOGPD_REPORT_CFM message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hogpd_report_cfm_handler(ke_msg_id_t const msgid, + struct hogpd_report_cfm const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + uint8_t state = ke_state_get(dest_id); + + // check that an operation is ongoing + if((state & HOGPD_OP_BUSY) == HOGPD_OP_BUSY) + { + uint16_t handle = ATT_INVALID_HANDLE; + uint8_t status = PRF_APP_ERROR; + struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd); + + // check received status + if(param->status != GAP_ERR_NO_ERROR) + { + status = param->status; + } + // perform operation sanity check + else if((param->operation == hogpd_env->op.operation) && (param->conidx == hogpd_env->op.conidx)) + { + // retrieve attribute index. + uint8_t att_idx = 0; + switch(param->report.type) + { + case HOGPD_REPORT: + { + att_idx = HOGPD_IDX_REPORT_VAL; + }break; + case HOGPD_REPORT_MAP: + { + att_idx = HOGPD_IDX_REPORT_MAP_VAL; + }break; + case HOGPD_BOOT_KEYBOARD_INPUT_REPORT: + { + att_idx = HOGPD_IDX_BOOT_KB_IN_REPORT_VAL; + }break; + case HOGPD_BOOT_KEYBOARD_OUTPUT_REPORT: + { + att_idx = HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL; + }break; + case HOGPD_BOOT_MOUSE_INPUT_REPORT: + { + att_idx = HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL; + }break; + default: /* Nothing to do */ break; + } + + // retrieve handle + handle = hogpd_get_att_handle(hogpd_env, param->report.hid_idx, att_idx, param->report.idx); + + // check if answer correspond to expected one + if(handle == hogpd_env->op.handle) + { + status = GAP_ERR_NO_ERROR; + } + } + + // read operation + if(hogpd_env->op.operation == HOGPD_OP_REPORT_READ) + { + uint16_t length = (status == GAP_ERR_NO_ERROR) ? param->report.length : 0; + //Send read response + struct gattc_read_cfm * rd_cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, + KE_BUILD_ID(TASK_GATTC, hogpd_env->op.conidx), dest_id, gattc_read_cfm, length); + rd_cfm->handle = hogpd_env->op.handle; + rd_cfm->status = status; + rd_cfm->length = length; + + if(status == GAP_ERR_NO_ERROR) + { + memcpy(rd_cfm->value, param->report.value, length); + } + + ke_msg_send(rd_cfm); + } + // write operation + else + { + //Send write response + struct gattc_write_cfm * wr_cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, + KE_BUILD_ID(TASK_GATTC, hogpd_env->op.conidx), dest_id, gattc_write_cfm); + wr_cfm->handle = hogpd_env->op.handle; + wr_cfm->status = status; + ke_msg_send(wr_cfm); + } + + // cleanup environment + hogpd_env->op.operation = HOGPD_OP_NO; + hogpd_env->op.handle = ATT_INVALID_HDL; + hogpd_env->op.conidx = 0xFF; + + // go back in idle state + ke_state_set(dest_id, state & ~HOGPD_OP_BUSY); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HOGPD_PROTO_MODE_CFM message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hogpd_proto_mode_cfm_handler(ke_msg_id_t const msgid, + struct hogpd_proto_mode_cfm const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + uint8_t state = ke_state_get(dest_id); + + // check that an operation is ongoing + if((state & HOGPD_OP_BUSY) == HOGPD_OP_BUSY) + { + uint16_t handle = ATT_INVALID_HANDLE; + uint8_t status = PRF_APP_ERROR; + struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd); + + // check received status + if(param->status != GAP_ERR_NO_ERROR) + { + status = param->status; + } + // perform operation sanity check + else if((hogpd_env->op.operation == HOGPD_OP_PROT_UPDATE) && (param->conidx == hogpd_env->op.conidx)) + { + // retrieve handle + handle = hogpd_get_att_handle(hogpd_env, param->hid_idx, HOGPD_IDX_PROTO_MODE_VAL, 0); + + // check if answer correspond to expected one + if(handle == hogpd_env->op.handle) + { + status = GAP_ERR_NO_ERROR; + hogpd_env->svcs[param->hid_idx].proto_mode = param->proto_mode; + } + } + + // read operation/something failed + if(hogpd_env->op.operation == HOGPD_OP_REPORT_READ) + { + //Send read response + struct gattc_read_cfm * rd_cfm = KE_MSG_ALLOC(GATTC_READ_CFM, + KE_BUILD_ID(TASK_GATTC, hogpd_env->op.conidx), dest_id, gattc_read_cfm); + rd_cfm->handle = hogpd_env->op.handle; + rd_cfm->status = status; + ke_msg_send(rd_cfm); + } + // write operation + else + { + //Send write response + struct gattc_write_cfm * wr_cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, + KE_BUILD_ID(TASK_GATTC, hogpd_env->op.conidx), dest_id, gattc_write_cfm); + wr_cfm->handle = hogpd_env->op.handle; + wr_cfm->status = status; + ke_msg_send(wr_cfm); + } + + // cleanup environment + hogpd_env->op.operation = HOGPD_OP_NO; + hogpd_env->op.handle = ATT_INVALID_HDL; + hogpd_env->op.conidx = 0xFF; + + // go back in idle state + ke_state_set(dest_id, state & ~HOGPD_OP_BUSY); + } + + return (KE_MSG_CONSUMED); +} + + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_ATT_INFO_REQ_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t hid_idx, att_idx, report_idx; + struct gattc_att_info_cfm * cfm; + struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd); + // retrieve attribute requested + uint8_t status = hogpd_get_att_idx(hogpd_env, param->handle, &hid_idx, &att_idx, &report_idx); + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + if(status == GAP_ERR_NO_ERROR) + { + // check which attribute is requested by peer device + switch(att_idx) + { + case HOGPD_IDX_BOOT_KB_IN_REPORT_VAL: + case HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL: + case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL: + case HOGPD_IDX_REPORT_VAL: + { + cfm->length = 0; + }break; + + // Notification configuration + case HOGPD_IDX_BOOT_KB_IN_REPORT_NTF_CFG: + case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG: + case HOGPD_IDX_REPORT_NTF_CFG: + { + cfm->length = 2; + }break; + + default: + { + cfm->length = 0; + status = ATT_ERR_WRITE_NOT_PERMITTED; + } break; + } + } + + cfm->status = status; + + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_WRITE_REQ_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + + // check that task is in idle state + if((state & HOGPD_OP_BUSY) == HOGPD_IDLE) + { + uint8_t hid_idx, att_idx, report_idx; + + // used to know if gatt_write confirmation should be sent immediately + uint8_t conidx = KE_IDX_GET(src_id); + + struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd); + // retrieve attribute requested + uint8_t status = hogpd_get_att_idx(hogpd_env, param->handle, &hid_idx, &att_idx, &report_idx); + + + // prepare operation info + hogpd_env->op.conidx = conidx; + hogpd_env->op.operation = HOGPD_OP_NO; + hogpd_env->op.handle = param->handle; + + if(status == GAP_ERR_NO_ERROR) + { + + // check which attribute is requested by peer device + switch(att_idx) + { + // Control point value updated + case HOGPD_IDX_HID_CTNL_PT_VAL: + { + // send control point indication + struct hogpd_ctnl_pt_ind *cp_ind = KE_MSG_ALLOC(HOGPD_CTNL_PT_IND, + prf_dst_task_get(&(hogpd_env->prf_env), conidx), dest_id, + hogpd_ctnl_pt_ind); + cp_ind->conidx = conidx; + cp_ind->hid_idx = hid_idx; + cp_ind->hid_ctnl_pt = param->value[0]; + ke_msg_send(cp_ind); + }break; + + // Modification of protocol mode requested + case HOGPD_IDX_PROTO_MODE_VAL: + { + // send control point indication + struct hogpd_proto_mode_req_ind *prot_ind = KE_MSG_ALLOC(HOGPD_PROTO_MODE_REQ_IND, + prf_dst_task_get(&(hogpd_env->prf_env), conidx), dest_id, + hogpd_proto_mode_req_ind); + prot_ind->conidx = conidx; + prot_ind->operation = HOGPD_OP_PROT_UPDATE; + prot_ind->hid_idx = hid_idx; + prot_ind->proto_mode = param->value[0]; + ke_msg_send(prot_ind); + + hogpd_env->op.operation = HOGPD_OP_PROT_UPDATE; + }break; + + // Modification of report value requested + case HOGPD_IDX_BOOT_KB_IN_REPORT_VAL: + case HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL: + case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL: + case HOGPD_IDX_REPORT_VAL: + { + // send report indication + struct hogpd_report_req_ind *report_ind = KE_MSG_ALLOC_DYN(HOGPD_REPORT_REQ_IND, + prf_dst_task_get(&(hogpd_env->prf_env), conidx), dest_id, + hogpd_report_req_ind, param->length); + + report_ind->conidx = conidx; + report_ind->operation = HOGPD_OP_REPORT_WRITE; + report_ind->report.length = param->length; + report_ind->report.hid_idx = hid_idx; + report_ind->report.idx = report_idx; + + memcpy(report_ind->report.value, param->value, param->length); + + // retrieve report type + switch(att_idx) + { + // An Input Report + case HOGPD_IDX_BOOT_KB_IN_REPORT_VAL: + { + report_ind->report.type = HOGPD_BOOT_KEYBOARD_INPUT_REPORT; + }break; + // Boot Keyboard input report + case HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL: + { + report_ind->report.type = HOGPD_BOOT_KEYBOARD_OUTPUT_REPORT; + }break; + // Boot Mouse input report + case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL: + { + report_ind->report.type = HOGPD_BOOT_MOUSE_INPUT_REPORT; + }break; + // Normal report + case HOGPD_IDX_REPORT_VAL: + { + report_ind->report.type = HOGPD_REPORT; + }break; + + default: + { + ASSERT_ERR(0); + }break; + } + + ke_msg_send(report_ind); + + hogpd_env->op.operation = HOGPD_OP_REPORT_WRITE; + }break; + + // Notification configuration update + case HOGPD_IDX_BOOT_KB_IN_REPORT_NTF_CFG: + case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG: + case HOGPD_IDX_REPORT_NTF_CFG: + { + uint16_t ntf_cfg = co_read16p(param->value); + status = hogpd_ntf_cfg_ind_send(conidx, hid_idx, att_idx, report_idx, ntf_cfg); + }break; + + default: + { + status = PRF_APP_ERROR; + } break; + } + } + + // check if peer operation is over + if(hogpd_env->op.operation == HOGPD_OP_NO) + { + //Send write response + struct gattc_write_cfm * cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + } + else + { + // go into operation busy state + ke_state_set(dest_id, state | HOGPD_OP_BUSY); + } + } + // else process it later + else + { + msg_status = KE_MSG_SAVED; + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_REQ_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + + // check that task is in idle state + if((state & HOGPD_OP_BUSY) == HOGPD_IDLE) + { + uint8_t hid_idx, att_idx, report_idx; + bool finished = true; + uint8_t report_type = 0; + uint16_t value = 0; + uint16_t length = 0; + + struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd); + + // used to know if gatt_write confirmation should be sent immediately + uint8_t conidx = KE_IDX_GET(src_id); + + // retrieve attribute requested + uint8_t status = hogpd_get_att_idx(hogpd_env, param->handle, &hid_idx, &att_idx, &report_idx); + + if(status == GAP_ERR_NO_ERROR) + { + // check which attribute is requested by peer device + switch(att_idx) + { + // ------------ READ report value requested + case HOGPD_IDX_BOOT_KB_IN_REPORT_VAL: + { + report_type = HOGPD_BOOT_KEYBOARD_INPUT_REPORT; + finished = false; + }break; + case HOGPD_IDX_BOOT_KB_OUT_REPORT_VAL: + { + report_type = HOGPD_BOOT_KEYBOARD_OUTPUT_REPORT; + finished = false; + }break; + case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_VAL: + { + report_type = HOGPD_BOOT_MOUSE_INPUT_REPORT; + finished = false; + }break; + case HOGPD_IDX_REPORT_VAL: + { + report_type = HOGPD_REPORT; + finished = false; + }break; + case HOGPD_IDX_REPORT_MAP_VAL: + { + report_type = HOGPD_REPORT_MAP; + finished = false; + }break; + + // ------------ READ active protocol mode + case HOGPD_IDX_PROTO_MODE_VAL: + { + value = hogpd_env->svcs[hid_idx].proto_mode; + length = sizeof(uint8_t); + }break; + + // ------------ READ Notification configuration + case HOGPD_IDX_BOOT_KB_IN_REPORT_NTF_CFG: + { + value = ((hogpd_env->svcs[hid_idx].ntf_cfg[conidx] & HOGPD_CFG_KEYBOARD) != 0) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; + + length = sizeof(uint16_t); + }break; + case HOGPD_IDX_BOOT_MOUSE_IN_REPORT_NTF_CFG: + { + value = ((hogpd_env->svcs[hid_idx].ntf_cfg[conidx] & HOGPD_CFG_MOUSE) != 0) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; + length = sizeof(uint16_t); + }break; + case HOGPD_IDX_REPORT_NTF_CFG: + { + value = ((hogpd_env->svcs[hid_idx].ntf_cfg[conidx] & (HOGPD_CFG_REPORT_NTF_EN << report_idx)) != 0) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; + length = sizeof(uint16_t); + }break; + + default: + { + status = PRF_APP_ERROR; + } break; + } + } + + // check if peer operation is over + if(finished) + { + //Send write response + struct gattc_read_cfm * cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, length); + cfm->handle = param->handle; + cfm->status = status; + cfm->length = length; + memcpy(cfm->value, &value, length); + ke_msg_send(cfm); + } + else + { + // send report indication + struct hogpd_report_req_ind *report_ind = KE_MSG_ALLOC(HOGPD_REPORT_REQ_IND, + prf_dst_task_get(&(hogpd_env->prf_env), conidx), dest_id, + hogpd_report_req_ind); + + report_ind->conidx = conidx; + report_ind->operation = HOGPD_OP_REPORT_READ; + report_ind->report.length = 0; + report_ind->report.hid_idx = hid_idx; + report_ind->report.type = report_type; + report_ind->report.idx = report_idx; + + ke_msg_send(report_ind); + + hogpd_env->op.conidx = conidx; + hogpd_env->op.operation = HOGPD_OP_REPORT_READ; + hogpd_env->op.handle = param->handle; + + // go into operation busy state + ke_state_set(dest_id, state | HOGPD_OP_BUSY); + } + } + // else process it later + else + { + msg_status = KE_MSG_SAVED; + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles @ref GATT_NOTIFY_CMP_EVT message meaning that Report notification + * has been correctly sent to peer device (but not confirmed by peer device). + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + if(param->operation == GATTC_NOTIFY) + { + uint8_t conidx = KE_IDX_GET(src_id); + struct hogpd_env_tag* hogpd_env = PRF_ENV_GET(HOGPD, hogpd); + + // send report update response + struct hogpd_report_upd_rsp *rsp = KE_MSG_ALLOC(HOGPD_REPORT_UPD_RSP, + prf_dst_task_get(&(hogpd_env->prf_env), conidx), + dest_id, hogpd_report_upd_rsp); + rsp->conidx = conidx; + rsp->status = param->status; + ke_msg_send(rsp); + + // go back in to idle mode + ke_state_set(dest_id, ke_state_get(dest_id) & ~HOGPD_REQ_BUSY); + } // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(hogpd) +{ + { HOGPD_ENABLE_REQ, (ke_msg_func_t) hogpd_enable_req_handler }, + { HOGPD_REPORT_UPD_REQ, (ke_msg_func_t) hogpd_report_upd_req_handler }, + { HOGPD_REPORT_CFM, (ke_msg_func_t) hogpd_report_cfm_handler }, + { HOGPD_PROTO_MODE_CFM, (ke_msg_func_t) hogpd_proto_mode_cfm_handler }, + + { GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler }, + { GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler }, + { GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler }, + { GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler }, +}; + +void hogpd_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct hogpd_env_tag *hogpd_env = PRF_ENV_GET(HOGPD, hogpd); + + task_desc->msg_handler_tab = hogpd_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(hogpd_msg_handler_tab); + task_desc->state = hogpd_env->state; + task_desc->idx_max = HOGPD_IDX_MAX; +} + +#endif /* #if (BLE_HID_DEVICE) */ + +/// @} HOGPDTASK diff --git a/services/ble_profiles/hogp/hogprh/api/hogprh_task.h b/services/ble_profiles/hogp/hogprh/api/hogprh_task.h new file mode 100644 index 0000000..2d7c593 --- /dev/null +++ b/services/ble_profiles/hogp/hogprh/api/hogprh_task.h @@ -0,0 +1,331 @@ +#ifndef _HOGPRH_TASK_H_ +#define _HOGPRH_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup HOGPRHTASK HID Over GATT Profile Report Host Task + * @ingroup HOGPRH + * @brief HID Over GATT Profile Report Host Task + * + * The HOGPRHTASK is responsible for handling the messages coming in and out of the + * @ref HOGPRH monitor block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" +#include "hogp_common.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +/// Maximal number of hids instances that can be handled +#define HOGPRH_NB_HIDS_INST_MAX (2) +/// Maximal number of Report Char. that can be added in the DB for one HIDS - Up to 11 +#define HOGPRH_NB_REPORT_INST_MAX (5) + +/// Maximal length of Report Map Char. Value +#define HOGPRH_REPORT_MAP_MAX_LEN (512) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +enum hogprh_msg_id +{ + /// Start the HID Over GATT profile - at connection + HOGPRH_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_HOGPRH), + ///Confirm that cfg connection has finished with discovery results, or that normal cnx started + HOGPRH_ENABLE_RSP, + + /// Read Characteristic Value Request + HOGPRH_READ_INFO_REQ, + /// Read Characteristic Value Request + HOGPRH_READ_INFO_RSP, + + /// Write/Configure peer device attribute Request + HOGPRH_WRITE_REQ, + /// Write/Configure peer device attribute Response + HOGPRH_WRITE_RSP, + + /// Report value send to APP (after Notification) + HOGPRH_REPORT_IND, +}; + + +/// Characteristics +enum hogprh_chars +{ + /// Report Map + HOGPRH_CHAR_REPORT_MAP, + /// HID Information + HOGPRH_CHAR_HID_INFO, + /// HID Control Point + HOGPRH_CHAR_HID_CTNL_PT, + /// Protocol Mode + HOGPRH_CHAR_PROTOCOL_MODE, + /// Report + HOGPRH_CHAR_REPORT, + + HOGPRH_CHAR_MAX = HOGPRH_CHAR_REPORT + HOGPRH_NB_REPORT_INST_MAX, +}; + + +/// Characteristic descriptors +enum hogprh_descs +{ + /// Report Map Char. External Report Reference Descriptor + HOGPRH_DESC_REPORT_MAP_EXT_REP_REF, + /// Report Char. Report Reference + HOGPRH_DESC_REPORT_REF, + /// Report Client Config + HOGPRH_DESC_REPORT_CFG = HOGPRH_DESC_REPORT_REF + HOGPRH_NB_REPORT_INST_MAX, + + HOGPRH_DESC_MAX = HOGPRH_DESC_REPORT_CFG + HOGPRH_NB_REPORT_INST_MAX, +}; + +/// Peer HID service info that can be read/write +enum hogprh_info +{ + /// Protocol Mode + HOGPRH_PROTO_MODE, + /// Report Map + HOGPRH_REPORT_MAP, + /// Report Map Char. External Report Reference Descriptor + HOGPRH_REPORT_MAP_EXT_REP_REF, + + /// HID Information + HOGPRH_HID_INFO, + /// HID Control Point + HOGPRH_HID_CTNL_PT, + /// Report + HOGPRH_REPORT, + /// Report Char. Report Reference + HOGPRH_REPORT_REF, + /// Report Notification config + HOGPRH_REPORT_NTF_CFG, + + HOGPRH_INFO_MAX, +}; + +/* + * APIs Structure + **************************************************************************************** + */ + + +///Structure containing the characteristics handles, value handles and descriptors +struct hogprh_content +{ + /// Service info + struct prf_svc svc; + + /// Included service info + struct prf_incl_svc incl_svc; + + /// Characteristic info: + struct prf_char_inf chars[HOGPRH_CHAR_MAX]; + + /// Descriptor handles: + struct prf_char_desc_inf descs[HOGPRH_DESC_MAX]; + + /// Number of Report Char. that have been found + uint8_t report_nb; +}; + + +/// Parameters of the @ref HOGPRH_ENABLE_REQ message +struct hogprh_enable_req +{ + /// Connection type + uint8_t con_type; + + /// Number of HIDS instances + uint8_t hids_nb; + /// Existing handle values hids + struct hogprh_content hids[HOGPRH_NB_HIDS_INST_MAX]; +}; + +/// Parameters of the @ref HOGPRH_ENABLE_RSP message +struct hogprh_enable_rsp +{ + ///status + uint8_t status; + + /// Number of HIDS instances + uint8_t hids_nb; + /// Existing handle values hids + struct hogprh_content hids[HOGPRH_NB_HIDS_INST_MAX]; +}; + + +/// HID report info +struct hogprh_report +{ + /// Report Length + uint8_t length; + /// Report value + uint8_t value[__ARRAY_EMPTY]; +}; + +/// HID report Reference +struct hogprh_report_ref +{ + /// Report ID + uint8_t id; + /// Report Type + uint8_t type; +}; + +/// HID report MAP info +struct hogprh_report_map +{ + /// Report MAP Length + uint16_t length; + /// Report MAP value + uint8_t value[__ARRAY_EMPTY]; +}; + +/// HID report MAP reference +struct hogprh_report_map_ref +{ + /// Reference UUID length + uint8_t uuid_len; + /// Reference UUID Value + uint8_t uuid[__ARRAY_EMPTY]; +}; + +/// Information data +union hogprh_data +{ + /// Protocol Mode + /// - info = HOGPRH_PROTO_MODE + uint8_t proto_mode; + + /// HID Information value + /// - info = HOGPRH_HID_INFO + struct hids_hid_info hid_info; + + /// HID Control Point value to write + /// - info = HOGPRH_HID_CTNL_PT + uint8_t hid_ctnl_pt; + + /// Report information + /// - info = HOGPRH_REPORT + struct hogprh_report report; + + ///Notification Configuration Value + /// - info = HOGPRH_REPORT_NTF_CFG + uint16_t report_cfg; + + /// HID report Reference + /// - info = HOGPRH_REPORT_REF + struct hogprh_report_ref report_ref; + + /// HID report MAP info + /// - info = HOGPRH_REPORT_MAP + struct hogprh_report_map report_map; + + /// HID report MAP reference + /// - info = HOGPRH_REPORT_MAP_EXT_REP_REF + struct hogprh_report_map_ref report_map_ref; +}; + + + +///Parameters of the @ref HOGPRH_READ_INFO_REQ message +struct hogprh_read_info_req +{ + ///Characteristic info @see enum hogprh_info + uint8_t info; + /// HID Service Instance - From 0 to HOGPRH_NB_HIDS_INST_MAX-1 + uint8_t hid_idx; + /// HID Report Index: only relevant for: + /// - info = HOGPRH_REPORT + /// - info = HOGPRH_REPORT_REF + /// - info = HOGPRH_REPORT_NTF_CFG + uint8_t report_idx; +}; + +///Parameters of the @ref HOGPRH_READ_INFO_RSP message +struct hogprh_read_info_rsp +{ + /// status of the request + uint8_t status; + ///Characteristic info @see enum hogprh_info + uint8_t info; + /// HID Service Instance - From 0 to HOGPRH_NB_HIDS_INST_MAX-1 + uint8_t hid_idx; + /// HID Report Index: only relevant for: + /// - info = HOGPRH_REPORT + /// - info = HOGPRH_REPORT_REF + /// - info = HOGPRH_REPORT_NTF_CFG + uint8_t report_idx; + /// Information data + union hogprh_data data; +}; + + +///Parameters of the @ref HOGPRH_WRITE_REQ message +struct hogprh_write_req +{ + ///Characteristic info @see enum hogprh_info + uint8_t info; + /// HID Service Instance - From 0 to HOGPRH_NB_HIDS_INST_MAX-1 + uint8_t hid_idx; + /// HID Report Index: only relevant for: + /// - info = HOGPRH_REPORT + /// - info = HOGPRH_REPORT_NTF_CFG + uint8_t report_idx; + /// Write type ( Write without Response True or Write Request) + /// - only valid for HOGPRH_REPORT + bool wr_cmd; + /// Information data + union hogprh_data data; +}; + + +///Parameters of the @ref HOGPRH_WRITE_RSP message +struct hogprh_write_rsp +{ + /// status of the request + uint8_t status; + ///Characteristic info @see enum hogprh_info + uint8_t info; + /// HID Service Instance - From 0 to HOGPRH_NB_HIDS_INST_MAX-1 + uint8_t hid_idx; + /// HID Report Index: only relevant for: + /// - info = HOGPRH_REPORT + /// - info = HOGPRH_REPORT_REF + /// - info = HOGPRH_REPORT_NTF_CFG + uint8_t report_idx; +}; + + +///Parameters of the @ref HOGPRH_BOOT_REPORT_IND message +struct hogprh_report_ind +{ + /// HIDS Instance + uint8_t hid_idx; + /// HID Report Index + uint8_t report_idx; + /// Report data + struct hogprh_report report; +}; + +/// @} HOGPRHTASK + +#endif /* _HOGPRH_TASK_H_ */ diff --git a/services/ble_profiles/hogp/hogprh/src/hogprh.c b/services/ble_profiles/hogp/hogprh/src/hogprh.c new file mode 100644 index 0000000..1b8cafe --- /dev/null +++ b/services/ble_profiles/hogp/hogprh/src/hogprh.c @@ -0,0 +1,203 @@ +/** + **************************************************************************************** + * @addtogroup HOGPRH + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_HID_REPORT_HOST) + +#include "hogprh.h" +#include "hogprh_task.h" +#include "co_math.h" +#include "gap.h" + +#include "ke_mem.h" + +/** + **************************************************************************************** + * @brief Initialization of the HOGPRH module. + * This function performs all the initializations of the Profile module. + * - Creation of datahide (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t hogprh_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct hogprh_env_tag* hogprh_env = + (struct hogprh_env_tag* ) ke_malloc(sizeof(struct hogprh_env_tag), KE_MEM_ATT_DB); + + // allocate HOGPRH required environment variable + env->env = (prf_env_t*) hogprh_env; + + hogprh_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + hogprh_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_HOGPRH; + hogprh_task_init(&(env->desc)); + + for(idx = 0; idx < HOGPRH_IDX_MAX ; idx++) + { + hogprh_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), HOGPRH_FREE); + } + + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Destruction of the HOGPRH module - due to a reset for instance. + * This function clean-up allocated memory (attribute datahide is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void hogprh_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct hogprh_env_tag* hogprh_env = (struct hogprh_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < HOGPRH_IDX_MAX ; idx++) + { + if(hogprh_env->env[idx] != NULL) + { + if(hogprh_env->env[idx]->operation != NULL) + { + ke_free(hogprh_env->env[idx]->operation); + } + ke_free(hogprh_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(hogprh_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void hogprh_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put HID Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), HOGPRH_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void hogprh_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct hogprh_env_tag* hogprh_env = (struct hogprh_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(hogprh_env->env[conidx] != NULL) + { + if(hogprh_env->env[conidx]->operation != NULL) + { + ke_free(hogprh_env->env[conidx]->operation); + } + ke_free(hogprh_env->env[conidx]); + hogprh_env->env[conidx] = NULL; + } + + /* Put HID Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), HOGPRH_FREE); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// HOGPRH Task interface required by profile manager +const struct prf_task_cbs hogprh_itf = +{ + hogprh_init, + hogprh_destroy, + hogprh_create, + hogprh_cleanup, +}; + + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* hogprh_prf_itf_get(void) +{ + return &hogprh_itf; +} + +void hogprh_enable_rsp_send(struct hogprh_env_tag *hogprh_env, uint8_t conidx, uint8_t status) +{ + // Counter + uint8_t svc_inst; + + // Send APP the details of the discovered attributes on HOGPRH + struct hogprh_enable_rsp * rsp = KE_MSG_ALLOC(HOGPRH_ENABLE_RSP, + prf_dst_task_get(&(hogprh_env->prf_env) ,conidx), + prf_src_task_get(&(hogprh_env->prf_env) ,conidx), + hogprh_enable_rsp); + rsp->status = status; + rsp->hids_nb = 0; + if (status == GAP_ERR_NO_ERROR) + { + rsp->hids_nb = hogprh_env->env[conidx]->hids_nb; + + for (svc_inst = 0; svc_inst < co_min(hogprh_env->env[conidx]->hids_nb, HOGPRH_NB_HIDS_INST_MAX) ; svc_inst++) + { + rsp->hids[svc_inst] = hogprh_env->env[conidx]->hids[svc_inst]; + + // Register HOGPRH task in gatt for indication/notifications + prf_register_atthdl2gatt(&(hogprh_env->prf_env), conidx, &hogprh_env->env[conidx]->hids[svc_inst].svc); + } + } + + ke_msg_send(rsp); +} + +#endif /* (BLE_HID_REPORT_HOST) */ + +/// @} HOGPRH diff --git a/services/ble_profiles/hogp/hogprh/src/hogprh.h b/services/ble_profiles/hogp/hogprh/src/hogprh.h new file mode 100644 index 0000000..29381d4 --- /dev/null +++ b/services/ble_profiles/hogp/hogprh/src/hogprh.h @@ -0,0 +1,130 @@ +#ifndef _HOGPRH_H_ +#define _HOGPRH_H_ + + +/** + **************************************************************************************** + * @addtogroup HOGPRH HID Over GATT Profile Report Host + * @ingroup HOGP + * @brief HID Over GATT Profile Report Host + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_HID_REPORT_HOST) + +#include "hogp_common.h" +#include "ke_task.h" +#include "hogprh_task.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "prf.h" + +/* + * DEFINES + **************************************************************************************** + */ + +///Maximum number of HID Over GATT Report Host task instances +#define HOGPRH_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the HOGPRH task +enum hogprh_state +{ + /// Disconnected state + HOGPRH_FREE, + /// IDLE state + HOGPRH_IDLE, + /// Busy State + HOGPRH_BUSY, + /// Number of defined states. + HOGPRH_STATE_MAX +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Environment variable for each Connections +struct hogprh_cnx_env +{ + /// on-going operation + struct ke_msg * operation; + ///HIDS characteristics + struct hogprh_content hids[HOGPRH_NB_HIDS_INST_MAX]; + ///Number of HIDS instances found + uint8_t hids_nb; +}; + +/// HID Over Gatt Profile Boot Host environment variable +struct hogprh_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct hogprh_cnx_env* env[HOGPRH_IDX_MAX]; + /// State of different task instances + ke_state_t state[HOGPRH_IDX_MAX]; +}; + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * GLOBAL FUNCTIONS DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve HID report host profile interface + * + * @return HID report host profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* hogprh_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send HID ATT DB discovery results to HOGPRH host. + **************************************************************************************** + */ +void hogprh_enable_rsp_send(struct hogprh_env_tag *hogprh_env, uint8_t conidx, uint8_t status); + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void hogprh_task_init(struct ke_task_desc *task_desc); + + + +#endif /* (BLE_HID_REPORT_HOST) */ + +/// @} HOGPRH + +#endif /* _HOGPRH_H_ */ diff --git a/services/ble_profiles/hogp/hogprh/src/hogprh_task.c b/services/ble_profiles/hogp/hogprh/src/hogprh_task.c new file mode 100644 index 0000000..a4f67e7 --- /dev/null +++ b/services/ble_profiles/hogp/hogprh/src/hogprh_task.c @@ -0,0 +1,825 @@ +/** + **************************************************************************************** + * @addtogroup HOGPRHTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_HID_REPORT_HOST) + +#include "gap.h" +#include "attm.h" +#include "hogprh_task.h" +#include "hogprh.h" +#include "gattc_task.h" +#include "gattc.h" +#include "hogp_common.h" + +#include "ke_mem.h" +#include "co_utils.h" +#include "co_math.h" + +/* + * LOCAL VARIABLES DEFINITION + **************************************************************************************** + */ + +/// State machine used to retrieve HID Service characteristics information +const struct prf_char_def hogprh_hids_char[HOGPRH_CHAR_REPORT + 1] = +{ + /// Report Map + [HOGPRH_CHAR_REPORT_MAP] = {ATT_CHAR_REPORT_MAP, ATT_MANDATORY, ATT_CHAR_PROP_RD}, + /// HID Information + [HOGPRH_CHAR_HID_INFO] = {ATT_CHAR_HID_INFO, ATT_MANDATORY, ATT_CHAR_PROP_RD}, + /// HID Control Point + [HOGPRH_CHAR_HID_CTNL_PT] = {ATT_CHAR_HID_CTNL_PT, ATT_MANDATORY, ATT_CHAR_PROP_WR_NO_RESP}, + /// Protocol Mode + [HOGPRH_CHAR_PROTOCOL_MODE] = {ATT_CHAR_PROTOCOL_MODE, ATT_OPTIONAL, (ATT_CHAR_PROP_RD | ATT_CHAR_PROP_WR_NO_RESP)}, + /// Report + [HOGPRH_CHAR_REPORT] = {ATT_CHAR_REPORT, ATT_MANDATORY, ATT_CHAR_PROP_RD}, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HOGPRH_ENABLE_REQ message. + * The handler enables the HID Over GATT Profile Boot Host Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hogprh_enable_req_handler(ke_msg_id_t const msgid, + struct hogprh_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + int msg_status = KE_MSG_CONSUMED; + + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Battery service Client Role Task Environment + struct hogprh_env_tag *hogprh_env = PRF_ENV_GET(HOGPRH, hogprh); + + ASSERT_INFO(hogprh_env != NULL, dest_id, src_id); + if((state == HOGPRH_IDLE) && (hogprh_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + hogprh_env->env[conidx] = (struct hogprh_cnx_env*) ke_malloc(sizeof(struct hogprh_cnx_env),KE_MEM_ATT_DB); + memset(hogprh_env->env[conidx], 0, sizeof(struct hogprh_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering HID on peer + prf_disc_svc_send(&(hogprh_env->prf_env), conidx, ATT_SVC_HID); + + // Go to DISCOVERING state + ke_state_set(dest_id, HOGPRH_BUSY); + hogprh_env->env[conidx]->operation = ke_param2msg(param); + msg_status = KE_MSG_NO_FREE; + } + //normal connection, get saved att details + else + { + hogprh_env->env[conidx]->hids_nb = param->hids_nb; + memcpy(&(hogprh_env->env[conidx]->hids[0]), &(param->hids[0]), sizeof(struct hogprh_content) * HOGPRH_NB_HIDS_INST_MAX); + + //send APP confirmation that can start normal connection to TH + hogprh_enable_rsp_send(hogprh_env, conidx, GAP_ERR_NO_ERROR); + } + } + else if(state != HOGPRH_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + hogprh_enable_rsp_send(hogprh_env, conidx, status); + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == HOGPRH_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct hogprh_env_tag *hogprh_env = PRF_ENV_GET(HOGPRH, hogprh); + + ASSERT_INFO(hogprh_env != NULL, dest_id, src_id); + ASSERT_INFO(hogprh_env->env[conidx] != NULL, dest_id, src_id); + + if(hogprh_env->env[conidx]->hids_nb < HOGPRH_NB_HIDS_INST_MAX) + { + uint8_t i; + struct prf_char_def hids_char[HOGPRH_CHAR_MAX]; + struct prf_char_desc_def hids_char_desc[HOGPRH_DESC_MAX]; + uint8_t hid_idx = hogprh_env->env[conidx]->hids_nb; + uint8_t fnd_att; + + + + // 1. Create characteristic reference + memcpy(hids_char, hogprh_hids_char, sizeof(struct prf_char_def) * HOGPRH_CHAR_REPORT); + for(i = HOGPRH_CHAR_REPORT ; i < HOGPRH_CHAR_MAX ; i++) + { + hids_char[i] = hogprh_hids_char[HOGPRH_CHAR_REPORT]; + } + + // 2. create descriptor reference + // Report Map Char. External Report Reference Descriptor + hids_char_desc[HOGPRH_DESC_REPORT_MAP_EXT_REP_REF].char_code = HOGPRH_CHAR_REPORT_MAP; + hids_char_desc[HOGPRH_DESC_REPORT_MAP_EXT_REP_REF].req_flag = ATT_OPTIONAL; + hids_char_desc[HOGPRH_DESC_REPORT_MAP_EXT_REP_REF].uuid = ATT_DESC_EXT_REPORT_REF; + + for(i = 0 ; i < HOGPRH_NB_REPORT_INST_MAX ; i++) + { + // Report Char. Report Reference + hids_char_desc[HOGPRH_DESC_REPORT_REF + i].char_code = HOGPRH_CHAR_REPORT + i; + hids_char_desc[HOGPRH_DESC_REPORT_REF + i].req_flag = ATT_OPTIONAL; + hids_char_desc[HOGPRH_DESC_REPORT_REF + i].uuid = ATT_DESC_REPORT_REF; + // Report Client Config + hids_char_desc[HOGPRH_DESC_REPORT_CFG + i].char_code = HOGPRH_CHAR_REPORT + i; + hids_char_desc[HOGPRH_DESC_REPORT_CFG + i].req_flag = ATT_OPTIONAL; + hids_char_desc[HOGPRH_DESC_REPORT_CFG + i].uuid = ATT_DESC_CLIENT_CHAR_CFG; + } + + // 3. Retrieve HID characteristics + prf_extract_svc_info(ind, HOGPRH_CHAR_MAX, &hids_char[0], + &(hogprh_env->env[conidx]->hids[hid_idx].chars[0]), + HOGPRH_DESC_MAX, &hids_char_desc[0], + &(hogprh_env->env[conidx]->hids[hid_idx].descs[0])); + + // 4. Store service range + hogprh_env->env[conidx]->hids[hid_idx].svc.shdl = ind->start_hdl; + hogprh_env->env[conidx]->hids[hid_idx].svc.ehdl = ind->end_hdl; + + // 5. Search for an included service + for (fnd_att=0; fnd_att< (ind->end_hdl - ind->start_hdl); fnd_att++) + { + if(ind->info[fnd_att].att_type == GATTC_SDP_INC_SVC) + { + hogprh_env->env[conidx]->hids[hid_idx].incl_svc.handle = ind->start_hdl + fnd_att + 1; + hogprh_env->env[conidx]->hids[hid_idx].incl_svc.start_hdl = ind->info[fnd_att].inc_svc.start_hdl; + hogprh_env->env[conidx]->hids[hid_idx].incl_svc.end_hdl = ind->info[fnd_att].inc_svc.end_hdl; + hogprh_env->env[conidx]->hids[hid_idx].incl_svc.uuid_len = ind->info[fnd_att].inc_svc.uuid_len; + memcpy(hogprh_env->env[conidx]->hids[hid_idx].incl_svc.uuid, ind->info[fnd_att].inc_svc.uuid, + ind->info[fnd_att].inc_svc.uuid_len); + } + if((ind->info[fnd_att].att_type == GATTC_SDP_ATT_VAL) + && (attm_uuid16_comp((uint8_t*)ind->info[fnd_att].att.uuid, ind->info[fnd_att].att.uuid_len, ATT_CHAR_REPORT))) + { + hogprh_env->env[conidx]->hids[hid_idx].report_nb++; + } + } + + hogprh_env->env[conidx]->hids_nb++; + } + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HOGPRH_READ_INFO_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hogprh_read_info_req_handler(ke_msg_id_t const msgid, struct hogprh_read_info_req const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(state == HOGPRH_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct hogprh_env_tag *hogprh_env = PRF_ENV_GET(HOGPRH, hogprh); + ASSERT_INFO(hogprh_env != NULL, dest_id, src_id); + // environment variable not ready + if(hogprh_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + // check parameter range + else if((param->hid_idx > hogprh_env->env[conidx]->hids_nb) || (param->report_idx >= HOGPRH_NB_REPORT_INST_MAX)) + { + status = PRF_ERR_INVALID_PARAM; + } + else + { + uint16_t handle = ATT_INVALID_HANDLE; + status = PRF_ERR_INEXISTENT_HDL; + + // check requested info + switch(param->info) + { + /// Protocol Mode + case HOGPRH_PROTO_MODE: + { + handle = hogprh_env->env[conidx]->hids[param->hid_idx].chars[HOGPRH_CHAR_PROTOCOL_MODE].val_hdl; + }break; + /// Report Map + case HOGPRH_REPORT_MAP: + { + handle = hogprh_env->env[conidx]->hids[param->hid_idx].chars[HOGPRH_CHAR_REPORT_MAP].val_hdl; + }break; + /// Report Map Char. External Report Reference Descriptor + case HOGPRH_REPORT_MAP_EXT_REP_REF: + { + handle = hogprh_env->env[conidx]->hids[param->hid_idx].descs[HOGPRH_DESC_REPORT_MAP_EXT_REP_REF].desc_hdl; + }break; + /// HID Information + case HOGPRH_HID_INFO: + { + handle = hogprh_env->env[conidx]->hids[param->hid_idx].chars[HOGPRH_CHAR_HID_INFO].val_hdl; + }break; + /// Report + case HOGPRH_REPORT: + { + handle = hogprh_env->env[conidx]->hids[param->hid_idx].chars[HOGPRH_CHAR_REPORT + param->report_idx].val_hdl; + }break; + /// Report Char. Report Reference + case HOGPRH_REPORT_REF: + { + handle = hogprh_env->env[conidx]->hids[param->hid_idx].descs[HOGPRH_DESC_REPORT_REF + param->report_idx].desc_hdl; + }break; + /// Report Notification config + case HOGPRH_REPORT_NTF_CFG: + { + handle = hogprh_env->env[conidx]->hids[param->hid_idx].descs[HOGPRH_DESC_REPORT_CFG + param->report_idx].desc_hdl; + }break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + }break; + } + + if(handle != ATT_INVALID_HANDLE) + { + status = GAP_ERR_NO_ERROR; + // read information + prf_read_char_send(&(hogprh_env->prf_env), conidx, + hogprh_env->env[conidx]->hids[param->hid_idx].svc.shdl, + hogprh_env->env[conidx]->hids[param->hid_idx].svc.ehdl, handle); + + // store context of request and go into busy state + hogprh_env->env[conidx]->operation = ke_param2msg(param); + ke_state_set(dest_id, HOGPRH_BUSY); + msg_status = KE_MSG_NO_FREE; + } + } + } + // process message later + else if (state == HOGPRH_BUSY) + { + status = GAP_ERR_NO_ERROR; + msg_status = KE_MSG_SAVED; + } + + + // request cannot be performed + if(status != GAP_ERR_NO_ERROR) + { + struct hogprh_read_info_rsp * rsp = KE_MSG_ALLOC(HOGPRH_READ_INFO_RSP, + src_id, dest_id, hogprh_read_info_rsp); + // set error status + rsp->status = status; + rsp->info = param->info; + rsp->hid_idx = param->hid_idx; + + ke_msg_send(rsp); + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HOGPRH_WRITE_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hogprh_write_req_handler(ke_msg_id_t const msgid, struct hogprh_write_req *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(state == HOGPRH_IDLE) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct hogprh_env_tag *hogprh_env = PRF_ENV_GET(HOGPRH, hogprh); + ASSERT_INFO(hogprh_env != NULL, dest_id, src_id); + // environment variable not ready + if(hogprh_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + // check parameter range + else if((param->hid_idx > hogprh_env->env[conidx]->hids_nb) || (param->report_idx >= HOGPRH_NB_REPORT_INST_MAX) + || (param->info > HOGPRH_INFO_MAX) + || ((param->info == HOGPRH_REPORT_NTF_CFG) && (param->data.report_cfg > PRF_CLI_START_NTF))) + { + status = PRF_ERR_INVALID_PARAM; + } + else + { + uint16_t handle = ATT_INVALID_HANDLE; + status = PRF_ERR_INEXISTENT_HDL; + + // check requested info + switch(param->info) + { + // Protocol Mode + case HOGPRH_PROTO_MODE: + { + handle = hogprh_env->env[conidx]->hids[param->hid_idx].chars[HOGPRH_CHAR_PROTOCOL_MODE].val_hdl; + prf_gatt_write(&hogprh_env->prf_env, conidx, handle, (uint8_t*)¶m->data.proto_mode, 1, GATTC_WRITE_NO_RESPONSE); + }break; + // HID Control Point + case HOGPRH_HID_CTNL_PT: + { + handle = hogprh_env->env[conidx]->hids[param->hid_idx].chars[HOGPRH_CHAR_HID_CTNL_PT].val_hdl; + prf_gatt_write(&hogprh_env->prf_env, conidx, handle, (uint8_t*)¶m->data.hid_ctnl_pt, 1, GATTC_WRITE_NO_RESPONSE); + }break; + // Report Char. Report Reference + case HOGPRH_REPORT: + { + // Get MTU to select between GATT_WRITE_LONG_CHAR and GATT_WRITE_CHAR + if (param->data.report.length > (gattc_get_mtu(conidx) - 3)) + { + param->wr_cmd = false; + } + + handle = hogprh_env->env[conidx]->hids[param->hid_idx].chars[HOGPRH_CHAR_REPORT + param->report_idx].val_hdl; + prf_gatt_write(&hogprh_env->prf_env, conidx, handle, (uint8_t*)param->data.report.value , + param->data.report.length, (param->wr_cmd ? GATTC_WRITE_NO_RESPONSE : GATTC_WRITE)); + }break; + // Report Notification config + case HOGPRH_REPORT_NTF_CFG: + { + handle = hogprh_env->env[conidx]->hids[param->hid_idx].descs[HOGPRH_DESC_REPORT_CFG + param->report_idx].desc_hdl; + prf_gatt_write_ntf_ind(&hogprh_env->prf_env, conidx, handle, param->data.report_cfg); + }break; + default: + { + status = PRF_ERR_INVALID_PARAM; + }break; + } + + if(handle != ATT_INVALID_HANDLE) + { + status = GAP_ERR_NO_ERROR; + + // store context of request and go into busy state + hogprh_env->env[conidx]->operation = ke_param2msg(param); + ke_state_set(dest_id, HOGPRH_BUSY); + msg_status = KE_MSG_NO_FREE; + } + } + } + // process message later + else if (state == HOGPRH_BUSY) + { + status = GAP_ERR_NO_ERROR; + msg_status = KE_MSG_SAVED; + } + + + // request cannot be performed + if(status != GAP_ERR_NO_ERROR) + { + struct hogprh_write_rsp * rsp = KE_MSG_ALLOC(HOGPRH_WRITE_RSP, + src_id, dest_id, hogprh_write_rsp); + // set error status + rsp->status = status; + rsp->info = param->info; + rsp->hid_idx = param->hid_idx; + + ke_msg_send(rsp); + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct hogprh_env_tag *hogprh_env = PRF_ENV_GET(HOGPRH, hogprh); + + // sanity check + if((state == HOGPRH_BUSY) && (hogprh_env->env[conidx] != NULL) + && (hogprh_env->env[conidx]->operation != NULL)) + { + switch(hogprh_env->env[conidx]->operation->id) + { + case HOGPRH_ENABLE_REQ: + { + uint8_t status = param->status; + + if (param->status == ATT_ERR_NO_ERROR) + { + // check characteristic validity + if(hogprh_env->env[conidx]->hids_nb > 0) + { + uint8_t report_idx; + uint8_t hid_idx; + for (hid_idx = 0 ; (hid_idx < co_min(hogprh_env->env[conidx]->hids_nb, HOGPRH_NB_HIDS_INST_MAX)) + && (status == GAP_ERR_NO_ERROR) ; hid_idx++) + { + + struct prf_char_def hids_char[HOGPRH_CHAR_MAX]; + struct prf_char_desc_def hids_char_desc[HOGPRH_DESC_MAX]; + + // 1. Create characteristic reference + memcpy(hids_char, hogprh_hids_char, sizeof(struct prf_char_def) * HOGPRH_CHAR_REPORT); + for(report_idx = HOGPRH_CHAR_REPORT ; report_idx < HOGPRH_CHAR_MAX ; report_idx++) + { + hids_char[report_idx] = hogprh_hids_char[HOGPRH_CHAR_REPORT]; + hids_char[report_idx].req_flag = ATT_OPTIONAL; + } + + // 2. create descriptor reference + // Report Map Char. External Report Reference Descriptor + hids_char_desc[HOGPRH_DESC_REPORT_MAP_EXT_REP_REF].char_code = HOGPRH_CHAR_REPORT_MAP; + hids_char_desc[HOGPRH_DESC_REPORT_MAP_EXT_REP_REF].req_flag = ATT_OPTIONAL; + hids_char_desc[HOGPRH_DESC_REPORT_MAP_EXT_REP_REF].uuid = ATT_DESC_EXT_REPORT_REF; + + for(report_idx = 0 ; report_idx < HOGPRH_NB_REPORT_INST_MAX ; report_idx++) + { + // Report Char. Report Reference + hids_char_desc[HOGPRH_DESC_REPORT_REF + report_idx].char_code = HOGPRH_CHAR_REPORT + report_idx; + hids_char_desc[HOGPRH_DESC_REPORT_REF + report_idx].req_flag = ATT_OPTIONAL; + hids_char_desc[HOGPRH_DESC_REPORT_REF + report_idx].uuid = ATT_DESC_REPORT_REF; + // Report Client Config + hids_char_desc[HOGPRH_DESC_REPORT_CFG + report_idx].char_code = HOGPRH_CHAR_REPORT + report_idx; + hids_char_desc[HOGPRH_DESC_REPORT_CFG + report_idx].req_flag = ATT_OPTIONAL; + hids_char_desc[HOGPRH_DESC_REPORT_CFG + report_idx].uuid = ATT_DESC_CLIENT_CHAR_CFG; + } + + // 3. Check Characteristic validity + status = prf_check_svc_char_validity(HOGPRH_CHAR_MAX, hogprh_env->env[conidx]->hids[hid_idx].chars, + hids_char); + + // 4. check descriptor validity + if(status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(HOGPRH_DESC_MAX, + hogprh_env->env[conidx]->hids[hid_idx].descs, hids_char_desc, + hogprh_env->env[conidx]->hids[hid_idx].chars); + } + } + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + } + hogprh_enable_rsp_send(hogprh_env, conidx, status); + }break; + case HOGPRH_READ_INFO_REQ: + { + // do not send anything if it's a local request + if(hogprh_env->env[conidx]->operation->src_id != dest_id) + { + struct hogprh_read_info_req* req = (struct hogprh_read_info_req*) ke_msg2param(hogprh_env->env[conidx]->operation); + struct hogprh_read_info_rsp * rsp = KE_MSG_ALLOC(HOGPRH_READ_INFO_RSP, + prf_dst_task_get(&(hogprh_env->prf_env), conidx), dest_id, hogprh_read_info_rsp); + // set error status + rsp->status = param->status; + rsp->hid_idx = req->hid_idx; + rsp->info = req->info; + rsp->report_idx = req->report_idx; + + ke_msg_send(rsp); + } + + }break; + case HOGPRH_WRITE_REQ: + { + struct hogprh_write_req* req = (struct hogprh_write_req*) ke_msg2param(hogprh_env->env[conidx]->operation); + + struct hogprh_write_rsp * rsp = KE_MSG_ALLOC(HOGPRH_WRITE_RSP, + prf_dst_task_get(&(hogprh_env->prf_env), conidx), dest_id, hogprh_write_rsp); + // set error status + rsp->status = param->status; + rsp->hid_idx = req->hid_idx; + rsp->info = req->info; + rsp->report_idx = req->report_idx; + + ke_msg_send(rsp); + }break; + default: + { + // Not Expected at all + ASSERT_ERR(0); + }break; + } + + // operation is over - go back to idle state + ke_free(hogprh_env->env[conidx]->operation); + hogprh_env->env[conidx]->operation = NULL; + ke_state_set(dest_id, HOGPRH_IDLE); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == HOGPRH_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct hogprh_env_tag *hogprh_env = PRF_ENV_GET(HOGPRH, hogprh); + struct hogprh_read_info_req* req = (struct hogprh_read_info_req*) ke_msg2param(hogprh_env->env[conidx]->operation); + + ASSERT_INFO(hogprh_env != NULL, dest_id, src_id); + ASSERT_INFO(hogprh_env->env[conidx] != NULL, dest_id, src_id); + + // check if read is requested locally due to a received notification or b + if(hogprh_env->env[conidx]->operation->src_id == dest_id) + { + // send report indication + struct hogprh_report_ind* ind = KE_MSG_ALLOC_DYN(HOGPRH_REPORT_IND, + prf_dst_task_get(&(hogprh_env->prf_env), conidx), dest_id, + hogprh_report_ind, param->length); + + ind->hid_idx = req->hid_idx; + ind->report_idx = req->report_idx; + ind->report.length = param->length; + memcpy(ind->report.value, param->value, param->length); + + ke_msg_send(ind); + } + // or by the HID Client application + else + { + struct hogprh_read_info_rsp * rsp = KE_MSG_ALLOC_DYN(HOGPRH_READ_INFO_RSP, + prf_dst_task_get(&(hogprh_env->prf_env),conidx), dest_id, hogprh_read_info_rsp, param->length); + + // set error status + rsp->status = GAP_ERR_NO_ERROR; + rsp->hid_idx = req->hid_idx; + rsp->info = req->info; + rsp->report_idx = req->report_idx; + + switch(req->info) + { + /// Protocol Mode + case HOGPRH_PROTO_MODE: + { + rsp->data.proto_mode = param->value[0]; + }break; + /// Report Map + case HOGPRH_REPORT_MAP: + { + rsp->data.report_map.length = param->length; + memcpy(rsp->data.report_map.value, param->value, param->length); + }break; + /// Report Map Char. External Report Reference Descriptor + case HOGPRH_REPORT_MAP_EXT_REP_REF: + { + rsp->data.report_map_ref.uuid_len = param->length; + memcpy(rsp->data.report_map_ref.uuid, param->value, co_min(param->length, ATT_UUID_128_LEN)); + }break; + /// HID Information + case HOGPRH_HID_INFO: + { + rsp->data.hid_info.bcdHID = co_read16p(param->value); + rsp->data.hid_info.bCountryCode = param->value[2]; + rsp->data.hid_info.flags = param->value[3]; + }break; + /// Report + case HOGPRH_REPORT: + { + rsp->data.report.length = param->length; + memcpy(rsp->data.report.value, param->value, param->length); + }break; + /// Report Char. Report Reference + case HOGPRH_REPORT_REF: + { + rsp->data.report_ref.id = param->value[0]; + rsp->data.report_ref.type = param->value[1]; + }break; + /// Report Notification config + case HOGPRH_REPORT_NTF_CFG: + { + rsp->data.report_cfg = co_read16p(param->value); + }break; + default: + { + ASSERT_ERR(0); + }break; + } + + // send response + ke_msg_send(rsp); + } + + // operation is over - go back to idle state + ke_free(hogprh_env->env[conidx]->operation); + hogprh_env->env[conidx]->operation = NULL; + ke_state_set(dest_id, HOGPRH_IDLE); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state != HOGPRH_FREE) + { + // HID Instance + uint8_t hid_nb; + uint8_t report_idx; + uint8_t conidx = KE_IDX_GET(src_id); + bool finished = false; + // Get the address of the environment + struct hogprh_env_tag *hogprh_env = PRF_ENV_GET(HOGPRH, hogprh); + + // BOOT Report - HID instance is unknown. + for (hid_nb = 0; (hid_nb < hogprh_env->env[conidx]->hids_nb) && !finished; hid_nb++) + { + for (report_idx = 0; (report_idx < HOGPRH_NB_REPORT_INST_MAX) && !finished; report_idx++) + { + if (param->handle == hogprh_env->env[conidx]->hids[hid_nb].chars[HOGPRH_CHAR_REPORT + report_idx].val_hdl) + { + + // Check if size of the data is lower than [ATT_MTU-3] + if (param->length < (gattc_get_mtu(conidx) - 3)) + { + // send report indication + struct hogprh_report_ind* ind = KE_MSG_ALLOC_DYN(HOGPRH_REPORT_IND, + prf_dst_task_get(&(hogprh_env->prf_env), conidx), dest_id, + hogprh_report_ind, param->length); + + ind->hid_idx = hid_nb; + ind->report_idx = report_idx; + ind->report.length = param->length; + memcpy(ind->report.value, param->value, param->length); + + ke_msg_send(ind); + } + else + { + // data is maybe incomplete so perform an attribute read + struct hogprh_read_info_req* req = KE_MSG_ALLOC(HOGPRH_READ_INFO_REQ, + dest_id, dest_id, hogprh_read_info_req); + + req->info = HOGPRH_REPORT; + req->hid_idx = hid_nb; + req->report_idx = report_idx; + + ke_msg_send(req); + } + + finished = true; + } + } + } + } + + return (KE_MSG_CONSUMED); +} + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(hogprh) +{ + {HOGPRH_ENABLE_REQ, (ke_msg_func_t)hogprh_enable_req_handler}, + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + + {HOGPRH_READ_INFO_REQ, (ke_msg_func_t)hogprh_read_info_req_handler}, + {HOGPRH_WRITE_REQ, (ke_msg_func_t)hogprh_write_req_handler}, + + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void hogprh_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct hogprh_env_tag *hogprh_env = PRF_ENV_GET(HOGPRH, hogprh); + + task_desc->msg_handler_tab = hogprh_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(hogprh_msg_handler_tab); + task_desc->state = hogprh_env->state; + task_desc->idx_max = HOGPRH_IDX_MAX; +} + +#endif /* (BLE_HID_REPORT_HOST) */ + +/// @} HOGPRHTASK diff --git a/services/ble_profiles/hrp/hrp_common.h b/services/ble_profiles/hrp/hrp_common.h new file mode 100644 index 0000000..4db3a93 --- /dev/null +++ b/services/ble_profiles/hrp/hrp_common.h @@ -0,0 +1,134 @@ +#ifndef _HRP_COMMON_H_ +#define _HRP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup HRP Heart Rate Profile + * @ingroup PROFILE + * @brief Heart Rate Profile + * + * The HRP module is the responsible block for implementing the Heart Rate Profile + * functionalities in the BLE Host. + * + * The Heart Rate Profile defines the functionality required in a device that allows + * the user (Collector device) to configure and recover Heart Rate measurements from + * a Heart Rate device. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "prf_types.h" +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/// maximum number of RR-Interval supported +#define HRS_MAX_RR_INTERVAL (4) + +/// Heart Rate Control Point Not Supported error code +#define HRS_ERR_HR_CNTL_POINT_NOT_SUPPORTED (0x80) + +///HRS codes for the 2 possible client configuration characteristic descriptors determination +enum +{ + /// Heart Rate Measurement + HRS_HR_MEAS_CODE = 0x01, + /// Energy Expended - Heart Rate Control Point + HRS_HR_CNTL_POINT_CODE, +}; + + +/// Heart Rate Measurement Flags field bit values +enum +{ + /// Heart Rate Value Format bit + /// Heart Rate Value Format is set to UINT8. Units: beats per minute (bpm) + HRS_FLAG_HR_8BITS_VALUE = 0x00, + /// Heart Rate Value Format is set to UINT16. Units: beats per minute (bpm) + HRS_FLAG_HR_16BITS_VALUE = 0x01, + + /// Sensor Contact Status bits + /// Sensor Contact feature is not supported in the current connection + HRS_FLAG_SENSOR_CCT_FET_NOT_SUPPORTED = 0x00, + /// Sensor Contact feature supported in the current connection + HRS_FLAG_SENSOR_CCT_FET_SUPPORTED = 0x04, + /// Contact is not detected + HRS_FLAG_SENSOR_CCT_NOT_DETECTED = 0x00, + /// Contact is detected + HRS_FLAG_SENSOR_CCT_DETECTED = 0x02, + + /// Energy Expended Status bit + /// Energy Expended field is not present + HRS_FLAG_ENERGY_EXPENDED_NOT_PRESENT = 0x00, + /// Energy Expended field is present. Units: kilo Joules + HRS_FLAG_ENERGY_EXPENDED_PRESENT = 0x08, + + /// RR-Interval bit + /// RR-Interval values are not present. + HRS_FLAG_RR_INTERVAL_NOT_PRESENT = 0x00, + /// One or more RR-Interval values are present. Units: 1/1024 seconds + HRS_FLAG_RR_INTERVAL_PRESENT = 0x10, +}; + +/// Heart Rate Feature Flags field bit values +enum +{ + /// Body Sensor Location support bit + /// Body Sensor Location feature Not Supported + HRS_F_BODY_SENSOR_LOCATION_NOT_SUPPORTED = 0x00, + /// Body Sensor Location feature Supported + HRS_F_BODY_SENSOR_LOCATION_SUPPORTED = 0x01, + + /// Energy Expended support bit + /// Energy Expended feature Not Supported + HRS_F_ENERGY_EXPENDED_NOT_SUPPORTED = 0x00, + /// Energy Expended feature Supported + HRS_F_ENERGY_EXPENDED_SUPPORTED = 0x02, +}; + +/// Body Sensor Location +enum +{ + HRS_LOC_OTHER, + HRS_LOC_CHEST, + HRS_LOC_WRIST, + HRS_LOC_FINGER, + HRS_LOC_HAND, + HRS_LOC_EAR_LOBE, + HRS_LOC_FOOT, + HRS_LOC_MAX, +}; + + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Heart Rate measurement structure +struct hrs_hr_meas +{ + /// Flag + uint8_t flags; + /// Heart Rate Measurement Value + uint16_t heart_rate; + /// Energy Expended + uint16_t energy_expended; + /// RR-Interval numbers (max 4) + uint8_t nb_rr_interval; + /// RR-Intervals + uint16_t rr_intervals[HRS_MAX_RR_INTERVAL]; +}; + + +/// @} hrp_common + +#endif /* _HRP_COMMON_H_ */ diff --git a/services/ble_profiles/hrp/hrpc/api/hrpc_task.h b/services/ble_profiles/hrp/hrpc/api/hrpc_task.h new file mode 100644 index 0000000..9f5fa62 --- /dev/null +++ b/services/ble_profiles/hrp/hrpc/api/hrpc_task.h @@ -0,0 +1,171 @@ +#ifndef _HRPC_TASK_H_ +#define _HRPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup HRPCTASK Heart Rate Profile Collector Task + * @ingroup HRPC + * @brief Heart Rate Profile Collector Task + * + * The HRPCTASK is responsible for handling the messages coming in and out of the + * @ref HRPC monitor block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "hrp_common.h" +#include "rwip_task.h" // Task definitions + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Characteristics +enum +{ + /// Heart Rate Measurement + HRPC_CHAR_HR_MEAS, + /// Body Sensor Location + HRPC_CHAR_BODY_SENSOR_LOCATION, + /// Heart Rate Control Point + HRPC_CHAR_HR_CNTL_POINT, + + HRPC_CHAR_MAX, +}; + + +/// Characteristic descriptors +enum +{ + /// Heart Rate Measurement client config + HRPC_DESC_HR_MEAS_CLI_CFG, + HRPC_DESC_MAX, + HRPC_DESC_MASK = 0x10, +}; + +enum +{ + /// Start the Heart Rate profile - at connection + HRPC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_HRPC), + ///Confirm that cfg connection has finished with discovery results, or that normal cnx started + HRPC_ENABLE_RSP, + + /// Generic message to read a HRS or DIS characteristic value + HRPC_RD_CHAR_REQ, + ///Generic message for read responses for APP + HRPC_RD_CHAR_RSP, + + ///Generic message for configuring the 2 characteristics that can be handled + HRPC_CFG_INDNTF_REQ, + ///Update IND/NTF config response + HRPC_CFG_INDNTF_RSP, + + ///APP request for control point write (to reset Energy Expanded) + HRPC_WR_CNTL_POINT_REQ, + ///Write Control Point response + HRPC_WR_CNTL_POINT_RSP, + + /// Heart Rate value send to APP + HRPC_HR_MEAS_IND, +}; + +///Structure containing the characteristics handles, value handles and descriptors +struct hrs_content +{ + /// service info + struct prf_svc svc; + + /// characteristic info: + /// - Heart Rate Measurement + /// - Body Sensor Location + /// - Heart Rate Control Point + struct prf_char_inf chars[HRPC_CHAR_MAX]; + + /// Descriptor handles: + /// - Heart Rate Measurement client cfg + struct prf_char_desc_inf descs[HRPC_DESC_MAX]; +}; + +/// Parameters of the @ref HRPC_ENABLE_REQ message +struct hrpc_enable_req +{ + ///Connection type + uint8_t con_type; + ///Existing handle values hrs + struct hrs_content hrs; +}; + +/// Parameters of the @ref HRPC_ENABLE_RSP message +struct hrpc_enable_rsp +{ + ///status + uint8_t status; + ///Existing handle values hrs + struct hrs_content hrs; +}; + +///Parameters of the @ref HRPC_CFG_INDNTF_REQ message +struct hrpc_cfg_indntf_req +{ + ///Stop/notify/indicate value to configure into the peer characteristic + uint16_t cfg_val; +}; + + +///Parameters of the @ref HRPC_CFG_INDNTF_RSP message +struct hrpc_cfg_indntf_rsp +{ + ///Status + uint8_t status; +}; + +///Parameters of the @ref HRPC_RD_CHAR_REQ message +struct hrpc_rd_char_req +{ + ///Characteristic value code + uint8_t char_code; +}; + +///Parameters of the @ref HRPC_RD_CHAR_RSP message +struct hrpc_rd_char_rsp +{ + /// Attribute data information + struct prf_att_info info; +}; + +///Parameters of the @ref HRPC_WR_CNTL_POINT_REQ message +struct hrpc_wr_cntl_point_req +{ + ///value + uint8_t val; +}; + +///Parameters of the @ref HRPC_WR_CNTL_POINT_RSP message +struct hrpc_wr_cntl_point_rsp +{ + ///Status + uint8_t status; +}; + +///Parameters of the @ref HRPC_HR_MEAS_IND message +struct hrpc_hr_meas_ind +{ + ///Heart Rate measurement + struct hrs_hr_meas meas_val; +}; + +/// @} HRPCTASK + +#endif /* _HRPC_TASK_H_ */ diff --git a/services/ble_profiles/hrp/hrpc/src/hrpc.c b/services/ble_profiles/hrp/hrpc/src/hrpc.c new file mode 100644 index 0000000..c5fe7e6 --- /dev/null +++ b/services/ble_profiles/hrp/hrpc/src/hrpc.c @@ -0,0 +1,238 @@ +/** + **************************************************************************************** + * @addtogroup HRPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_HR_COLLECTOR) + +#include "hrp_common.h" +#include "hrpc.h" +#include "hrpc_task.h" + +#include "ke_mem.h" +#include "co_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the HRPC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t hrpc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct hrpc_env_tag* hrpc_env = + (struct hrpc_env_tag* ) ke_malloc(sizeof(struct hrpc_env_tag), KE_MEM_ATT_DB); + + // allocate HRPC required environment variable + env->env = (prf_env_t*) hrpc_env; + + hrpc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + hrpc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_HRPC; + hrpc_task_init(&(env->desc)); + + for(idx = 0; idx < HRPC_IDX_MAX ; idx++) + { + hrpc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), HRPC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void hrpc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct hrpc_env_tag* hrpc_env = (struct hrpc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(hrpc_env->env[conidx] != NULL) + { + ke_free(hrpc_env->env[conidx]); + hrpc_env->env[conidx] = NULL; + } + + /* Put HRP Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), HRPC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the HRPC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void hrpc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct hrpc_env_tag* hrpc_env = (struct hrpc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < HRPC_IDX_MAX ; idx++) + { + hrpc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(hrpc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void hrpc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put HRP Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), HRPC_IDLE); +} + +/// HRPC Task interface required by profile manager +const struct prf_task_cbs hrpc_itf = +{ + hrpc_init, + hrpc_destroy, + hrpc_create, + hrpc_cleanup, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* hrpc_prf_itf_get(void) +{ + return &hrpc_itf; +} + + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +void hrpc_enable_rsp_send(struct hrpc_env_tag *hrpc_env, uint8_t conidx, uint8_t status) +{ + //send APP the details of the discovered attributes on HTPT + struct hrpc_enable_rsp * rsp = KE_MSG_ALLOC( + HRPC_ENABLE_RSP, + prf_dst_task_get(&(hrpc_env->prf_env), conidx), + prf_src_task_get(&(hrpc_env->prf_env), conidx), + hrpc_enable_rsp); + + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->hrs = hrpc_env->env[conidx]->hrs; + //register HRPC task in gatt for indication/notifications + prf_register_atthdl2gatt(&hrpc_env->prf_env, conidx, &hrpc_env->env[conidx]->hrs.svc); + // Go to connected state + ke_state_set(prf_src_task_get(&(hrpc_env->prf_env), conidx), HRPC_IDLE); + } + + ke_msg_send(rsp); +} + +void hrpc_unpack_meas_value(struct hrs_hr_meas* pmeas_val, uint8_t* packed_hr, uint8_t size) +{ + int8_t cursor = 0; + int8_t i = 0; + + // Heart Rate measurement flags + pmeas_val->flags = packed_hr[0]; + cursor += 1; + + if ((pmeas_val->flags & HRS_FLAG_HR_16BITS_VALUE) == HRS_FLAG_HR_16BITS_VALUE) + { + // Heart Rate Measurement Value 16 bits + pmeas_val->heart_rate = co_read16p(&packed_hr[cursor]); + cursor += 2; + } + else + { + // Heart Rate Measurement Value 8 bits + pmeas_val->heart_rate = (uint16_t) packed_hr[cursor]; + cursor += 1; + } + + if ((pmeas_val->flags & HRS_FLAG_ENERGY_EXPENDED_PRESENT) == HRS_FLAG_ENERGY_EXPENDED_PRESENT) + { + // Energy Expended present + pmeas_val->energy_expended = co_read16p(&packed_hr[cursor]); + cursor += 2; + } + + // retrieve number of rr intervals + pmeas_val->nb_rr_interval = ((size - cursor) > 0 ? ((size - cursor)/ 2) : (0)); + + for(i = 0 ; (i < (pmeas_val->nb_rr_interval)) && (i < (HRS_MAX_RR_INTERVAL)) ; i++) + { + // RR-Intervals + pmeas_val->rr_intervals[i] = co_read16p(&packed_hr[cursor]); + cursor += 2; + } +} + +void hrpc_error_ind_send(struct hrpc_env_tag *hrpc_env, uint8_t conidx, uint8_t status) +{ + +} + +#endif /* (BLE_HR_COLLECTOR) */ + +/// @} HRPC diff --git a/services/ble_profiles/hrp/hrpc/src/hrpc.h b/services/ble_profiles/hrp/hrpc/src/hrpc.h new file mode 100644 index 0000000..85a399b --- /dev/null +++ b/services/ble_profiles/hrp/hrpc/src/hrpc.h @@ -0,0 +1,162 @@ +#ifndef _HRPC_H_ +#define _HRPC_H_ + +/** + **************************************************************************************** + * @addtogroup HRPC Heart Rate Profile Collector + * @ingroup HRP + * @brief Heart Rate Profile Collector + * + * The HRPC is responsible for providing Heart Rate Profile Collector functionalities + * to upper layer module or application. The device using this profile takes the role + * of Heart Rate Profile Collector. + * + * Heart Rate Profile Collector. (HRPC): A HRPC (e.g. PC, phone, etc) + * is the term used by this profile to describe a device that can interpret Heart Rate + * measurement in a way suitable to the user application. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" +#if (BLE_HR_COLLECTOR) + +#include "hrp_common.h" +#include "hrpc_task.h" +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" + +/* + * DEFINES + **************************************************************************************** + */ + +///Maximum number of Heart Rate Collector task instances +#define HRPC_IDX_MAX (BLE_CONNECTION_MAX) + +/// Possible states of the HRPC task +enum +{ + /// Free state + HRPC_FREE, + /// Idle state + HRPC_IDLE, + /// Discovering Heart Rate SVC and Chars + HRPC_DISCOVERING, + /// Busy state + HRPC_BUSY, + + /// Number of defined states. + HRPC_STATE_MAX +}; + +/// Internal codes for reading a HRS or DIS characteristic with one single request +enum +{ + ///Read HRS Heart Rate Measurement + HRPC_RD_HRS_HR_MEAS = HRPC_CHAR_HR_MEAS, + ///Body Sensor Location + HRPC_RD_HRS_BODY_SENSOR_LOC = HRPC_CHAR_BODY_SENSOR_LOCATION, + ///Heart Rate Control Point + HRPC_RD_HRS_CNTL_POINT = HRPC_CHAR_HR_CNTL_POINT, + + ///Read HRS Heart Rate Measurement Client Cfg. Desc + HRPC_RD_HRS_HR_MEAS_CFG = (HRPC_DESC_MASK | HRPC_DESC_HR_MEAS_CLI_CFG), +}; + + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +struct hrpc_cnx_env +{ + /// Current operation code + void *operation; + /// Last requested UUID(to keep track of the two services and char) + uint16_t last_uuid_req; + /// Last characteristic code used in a read or a write request + uint16_t last_char_code; + /// Counter used to check service uniqueness + uint8_t nb_svc; + ///HTS characteristics + struct hrs_content hrs; +}; + +/// Heart Rate Profile Collector environment variable +struct hrpc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connection + struct hrpc_cnx_env* env[HRPC_IDX_MAX]; + /// State of different task instances + ke_state_t state[HRPC_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve HRP client profile interface + * @return HRP client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* hrpc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Heart Rate ATT DB discovery results to HRPC host. + **************************************************************************************** + */ +void hrpc_enable_rsp_send(struct hrpc_env_tag *hrpc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Unpack Heart Rate measurement data into a comprehensive structure. + * + * @param[out] pmeas_val Pointer to Heart Rate measurement structure destination + * @param[in] packed_hr Pointer of the packed data of Heart Rate Measurement + * information + * @param[in] size Packet data size + **************************************************************************************** + */ +void hrpc_unpack_meas_value(struct hrs_hr_meas* pmeas_val, uint8_t* packed_hr, uint8_t size); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void hrpc_task_init(struct ke_task_desc *task_desc); + + +#endif /* (BLE_HR_COLLECTOR) */ + +/// @} HRPC + +#endif /* _HRPC_H_ */ diff --git a/services/ble_profiles/hrp/hrpc/src/hrpc_task.c b/services/ble_profiles/hrp/hrpc/src/hrpc_task.c new file mode 100644 index 0000000..b61bf70 --- /dev/null +++ b/services/ble_profiles/hrp/hrpc/src/hrpc_task.c @@ -0,0 +1,633 @@ +/** + **************************************************************************************** + * @addtogroup HRPCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" +#include "hrp_common.h" + +#if (BLE_HR_COLLECTOR) +#include "co_utils.h" +#include "gap.h" +#include "attm.h" +#include "hrpc_task.h" +#include "hrpc.h" +#include "gattc_task.h" + +#include "ke_mem.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// State machine used to retrieve heart rate service characteristics information +const struct prf_char_def hrpc_hrs_char[HRPC_CHAR_MAX] = +{ + /// Heart Rate Measurement + [HRPC_CHAR_HR_MEAS] = {ATT_CHAR_HEART_RATE_MEAS, + ATT_MANDATORY, + ATT_CHAR_PROP_NTF}, + /// Body Sensor Location + [HRPC_CHAR_BODY_SENSOR_LOCATION] = {ATT_CHAR_BODY_SENSOR_LOCATION, + ATT_OPTIONAL, + ATT_CHAR_PROP_RD}, + /// Heart Rate Control Point + [HRPC_CHAR_HR_CNTL_POINT] = {ATT_CHAR_HEART_RATE_CNTL_POINT, + ATT_OPTIONAL, + ATT_CHAR_PROP_WR}, +}; + +/// State machine used to retrieve heart rate service characteristic description information +const struct prf_char_desc_def hrpc_hrs_char_desc[HRPC_DESC_MAX] = +{ + /// Heart Rate Measurement client config + [HRPC_DESC_HR_MEAS_CLI_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_MANDATORY, HRPC_CHAR_HR_MEAS}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == HRPC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct hrpc_env_tag *hrpc_env = PRF_ENV_GET(HRPC, hrpc); + + ASSERT_INFO(hrpc_env != NULL, dest_id, src_id); + ASSERT_INFO(hrpc_env->env[conidx] != NULL, dest_id, src_id); + + if(hrpc_env->env[conidx]->nb_svc == 0) + { + // Retrieve HRS characteristics and descriptors + prf_extract_svc_info(ind, HRPC_CHAR_MAX, &hrpc_hrs_char[0], &hrpc_env->env[conidx]->hrs.chars[0], + HRPC_DESC_MAX, &hrpc_hrs_char_desc[0], &hrpc_env->env[conidx]->hrs.descs[0]); + + //Even if we get multiple responses we only store 1 range + hrpc_env->env[conidx]->hrs.svc.shdl = ind->start_hdl; + hrpc_env->env[conidx]->hrs.svc.ehdl = ind->end_hdl; + } + + hrpc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HRPC_ENABLE_REQ message. + * The handler enables the Heart Rate Profile Collector Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hrpc_enable_req_handler(ke_msg_id_t const msgid, + struct hrpc_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + uint8_t state = ke_state_get(dest_id); + // Heart Rate Profile Client Role Task Environment + struct hrpc_env_tag *hrpc_env = PRF_ENV_GET(HRPC, hrpc);; + + ASSERT_INFO(hrpc_env != NULL, dest_id, src_id); + // Config connection, start discovering + if((state == HRPC_IDLE) && (hrpc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + hrpc_env->env[conidx] = (struct hrpc_cnx_env*) ke_malloc(sizeof(struct hrpc_cnx_env),KE_MEM_ATT_DB); + memset(hrpc_env->env[conidx], 0, sizeof(struct hrpc_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering HRS on peer + prf_disc_svc_send(&(hrpc_env->prf_env), conidx, ATT_SVC_HEART_RATE); + + hrpc_env->env[conidx]->last_uuid_req = ATT_SVC_HEART_RATE; + + // Go to DISCOVERING state + ke_state_set(dest_id, HRPC_DISCOVERING); + } + //normal connection, get saved att details + else + { + hrpc_env->env[conidx]->hrs = param->hrs; + //send APP confirmation that can start normal connection to TH + hrpc_enable_rsp_send(hrpc_env, conidx, GAP_ERR_NO_ERROR); + } + + status = GAP_ERR_NO_ERROR; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + hrpc_enable_rsp_send(hrpc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct hrpc_env_tag *hrpc_env = PRF_ENV_GET(HRPC, hrpc); + // Status + uint8_t status; + + if (hrpc_env != NULL) + { + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if(state == HRPC_DISCOVERING) + { + status = param->status; + + if ((status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| + (status == ATT_ERR_NO_ERROR)) + { + // Discovery + // check characteristic validity + if(hrpc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(HRPC_CHAR_MAX, + hrpc_env->env[conidx]->hrs.chars, + hrpc_hrs_char); + } + // too much services + else if (hrpc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if (status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(HRPC_DESC_MAX, + hrpc_env->env[conidx]->hrs.descs, + hrpc_hrs_char_desc, + hrpc_env->env[conidx]->hrs.chars); + } + } + + hrpc_enable_rsp_send(hrpc_env, conidx, status); + } + + else if(state == HRPC_BUSY) + { + switch(param->operation) + { + case GATTC_WRITE: + case GATTC_WRITE_NO_RESPONSE: + { + uint16_t rsp_msg_id = HRPC_CFG_INDNTF_RSP; + if(hrpc_env->env[conidx]->last_char_code != HRPC_DESC_HR_MEAS_CLI_CFG) + { + rsp_msg_id = HRPC_WR_CNTL_POINT_RSP; + } + + struct hrpc_cfg_indntf_rsp *rsp = KE_MSG_ALLOC(rsp_msg_id, + prf_dst_task_get(&(hrpc_env->prf_env), conidx), dest_id, + hrpc_cfg_indntf_rsp); + rsp->status = param->status; + // Send the message + ke_msg_send(rsp); + } + break; + + case GATTC_READ: + { + if(param->status != GAP_ERR_NO_ERROR) + { + // an error occurs while reading peer device attribute + prf_client_att_info_rsp( + (prf_env_t*) hrpc_env->env[conidx], + conidx, + HRPC_RD_CHAR_RSP, + param->status, + NULL); + } + } + break; + + default: break; + } + + ke_state_set(prf_src_task_get(&hrpc_env->prf_env, conidx), HRPC_IDLE); + } + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HRPC_RD_DATETIME_REQ message. + * Check if the handle exists in profile(already discovered) and send request, otherwise + * error to APP. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hrpc_rd_char_req_handler(ke_msg_id_t const msgid, + struct hrpc_rd_char_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get the address of the environment + struct hrpc_env_tag *hrpc_env = PRF_ENV_GET(HRPC, hrpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if(state == HRPC_IDLE) + { + ASSERT_INFO(hrpc_env != NULL, dest_id, src_id); + // environment variable not ready + if(hrpc_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + else + { + uint16_t search_hdl = ATT_INVALID_SEARCH_HANDLE; + + if(((param->char_code & HRPC_DESC_MASK) == HRPC_DESC_MASK) && + ((param->char_code & ~HRPC_DESC_MASK) < HRPC_DESC_MAX)) + { + search_hdl = hrpc_env->env[conidx]->hrs.descs[param->char_code & ~HRPC_DESC_MASK].desc_hdl; + } + else if (param->char_code < HRPC_CHAR_MAX) + { + search_hdl = hrpc_env->env[conidx]->hrs.chars[param->char_code].val_hdl; + } + + //check if handle is viable + if (search_hdl != ATT_INVALID_SEARCH_HANDLE) + { + // Store the command + hrpc_env->env[conidx]->last_char_code = param->char_code; + // Send the read request + prf_read_char_send(&(hrpc_env->prf_env), conidx, + hrpc_env->env[conidx]->hrs.svc.shdl, + hrpc_env->env[conidx]->hrs.svc.ehdl, + search_hdl); + + // Go to the Busy state + ke_state_set(dest_id, HRPC_BUSY); + + status = ATT_ERR_NO_ERROR; + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + } + else if (state == HRPC_FREE) + { + status = GAP_ERR_DISCONNECTED; + } + else + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + status = GAP_ERR_NO_ERROR; + } + + if (status != GAP_ERR_NO_ERROR) + { + prf_client_att_info_rsp(&hrpc_env->prf_env, conidx, HRPC_RD_CHAR_RSP, + status, NULL); + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct hrpc_env_tag *hrpc_env = PRF_ENV_GET(HRPC, hrpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + prf_client_att_info_rsp(&hrpc_env->prf_env, conidx, HRPC_RD_CHAR_RSP, + GAP_ERR_NO_ERROR, param); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HRPC_CFG_INDNTF_REQ message. + * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic. + * Will return an error code if that cfg char does not exist. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hrpc_cfg_indntf_req_handler(ke_msg_id_t const msgid, + struct hrpc_cfg_indntf_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct hrpc_env_tag *hrpc_env = PRF_ENV_GET(HRPC, hrpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + + if(state == HRPC_IDLE) + { + if(hrpc_env->env[conidx] != NULL) + { + + // Status + status = PRF_ERR_INVALID_PARAM; + // Check if parameter is OK + if((param->cfg_val == PRF_CLI_STOP_NTFIND) || + (param->cfg_val == PRF_CLI_START_NTF)) + { + // Status + status = PRF_ERR_INEXISTENT_HDL; + // Get handle of the client configuration + uint16_t cfg_hdl = + hrpc_env->env[conidx]->hrs.descs[HRPC_DESC_HR_MEAS_CLI_CFG].desc_hdl; + //check if the handle value exists + if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE) + { + hrpc_env->env[conidx]->last_char_code = HRPC_DESC_HR_MEAS_CLI_CFG; + + status = GAP_ERR_NO_ERROR; + // Go to the Busy state + ke_state_set(dest_id, HRPC_BUSY); + // Send GATT Write Request + prf_gatt_write_ntf_ind(&hrpc_env->prf_env, conidx, cfg_hdl, param->cfg_val); + } + } + } + else + { + status = PRF_APP_ERROR; + } + } + else if (state == HRPC_FREE) + { + status = GAP_ERR_DISCONNECTED; + } + else + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + status = GAP_ERR_NO_ERROR; + } + + if (status != GAP_ERR_NO_ERROR) + { + struct hrpc_cfg_indntf_rsp *rsp = KE_MSG_ALLOC(HRPC_CFG_INDNTF_RSP, src_id, dest_id, hrpc_cfg_indntf_rsp); + rsp->status = status; + // Send the message + ke_msg_send(rsp); + } + + return (msg_status); +} + +/** +**************************************************************************************** +* @brief Handles reception of the @ref HRPC_WR_CNTL_POINT_REQ message. +* Check if the handle exists in profile(already discovered) and send request, otherwise +* error to APP. +* @param[in] msgid Id of the message received (probably unused). +* @param[in] param Pointer to the parameters of the message. +* @param[in] dest_id ID of the receiving task instance (probably unused). +* @param[in] src_id ID of the sending task instance. +* @return If the message was consumed or not. +**************************************************************************************** +*/ +__STATIC int hrpc_wr_cntl_point_req_handler(ke_msg_id_t const msgid, + struct hrpc_wr_cntl_point_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct hrpc_env_tag *hrpc_env = PRF_ENV_GET(HRPC, hrpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t status = GAP_ERR_NO_ERROR; + + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + uint8_t state = ke_state_get(dest_id); + + if(state == HRPC_IDLE) + { + //this is mandatory readable if it is included in the peer's DB + if(hrpc_env->env[conidx] != NULL) + { + //this is mandatory readable if it is included in the peer's DB + if (hrpc_env->env[conidx]->hrs.chars[HRPC_CHAR_HR_CNTL_POINT].char_hdl != ATT_INVALID_SEARCH_HANDLE) + { + if ((hrpc_env->env[conidx]->hrs.chars[HRPC_CHAR_HR_CNTL_POINT].prop & ATT_CHAR_PROP_WR) == ATT_CHAR_PROP_WR) + { + hrpc_env->env[conidx]->last_char_code = HRPC_CHAR_HR_CNTL_POINT; + + // Send GATT Write Request + prf_gatt_write(&hrpc_env->prf_env, conidx, hrpc_env->env[conidx]->hrs.chars[HRPC_CHAR_HR_CNTL_POINT].val_hdl, + (uint8_t *)¶m->val, sizeof(uint8_t), GATTC_WRITE); + // Go to the Busy state + ke_state_set(dest_id, HRPC_BUSY); + } + //write not allowed, so no point in continuing + else + { + status = PRF_ERR_NOT_WRITABLE; + } + } + //send app error indication for inexistent handle for this characteristic + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_APP_ERROR; + } + } + else if (state == HRPC_FREE) + { + status = GAP_ERR_DISCONNECTED; + } + else + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + status = GAP_ERR_NO_ERROR; + } + + if(status != GAP_ERR_NO_ERROR) + { + struct hrpc_wr_cntl_point_rsp *rsp = KE_MSG_ALLOC(HRPC_WR_CNTL_POINT_RSP, src_id, dest_id, hrpc_wr_cntl_point_rsp); + rsp->status = status; + // Send the message + ke_msg_send(rsp); + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct hrpc_env_tag *hrpc_env = PRF_ENV_GET(HRPC, hrpc); + + if(hrpc_env != NULL) + { + if((param->handle == hrpc_env->env[conidx]->hrs.chars[HRPC_CHAR_HR_MEAS].val_hdl) && + (param->type == GATTC_NOTIFY)) + { + //build a HRPC_HR_MEAS_IND message with stable heart rate value code. + struct hrpc_hr_meas_ind * ind = KE_MSG_ALLOC( + HRPC_HR_MEAS_IND, + prf_dst_task_get(&(hrpc_env->prf_env), conidx), + prf_src_task_get(&(hrpc_env->prf_env), conidx), + hrpc_hr_meas_ind); + + // unpack heart rate measurement. + hrpc_unpack_meas_value(&(ind->meas_val), (uint8_t*) param->value, param->length); + + ke_msg_send(ind); + } + } + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(hrpc) +{ + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {HRPC_ENABLE_REQ, (ke_msg_func_t)hrpc_enable_req_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, + {HRPC_CFG_INDNTF_REQ, (ke_msg_func_t)hrpc_cfg_indntf_req_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {HRPC_RD_CHAR_REQ, (ke_msg_func_t)hrpc_rd_char_req_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {HRPC_WR_CNTL_POINT_REQ, (ke_msg_func_t)hrpc_wr_cntl_point_req_handler}, +}; + +void hrpc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct hrpc_env_tag *hrpc_env = PRF_ENV_GET(HRPC, hrpc); + + task_desc->msg_handler_tab = hrpc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(hrpc_msg_handler_tab); + task_desc->state = hrpc_env->state; + task_desc->idx_max = HRPC_IDX_MAX; +} + +#endif /* (BLE_HR_COLLECTOR) */ +/// @} HRPCTASK diff --git a/services/ble_profiles/hrp/hrps/api/hrps_task.h b/services/ble_profiles/hrp/hrps/api/hrps_task.h new file mode 100644 index 0000000..1827a96 --- /dev/null +++ b/services/ble_profiles/hrp/hrps/api/hrps_task.h @@ -0,0 +1,117 @@ +#ifndef _HRPS_TASK_H_ +#define _HRPS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup HRPSTASK Task + * @ingroup HRPS + * @brief Heart Rate Profile Task. + * + * The HRPSTASK is responsible for handling the messages coming in and out of the + * @ref HRPS collector block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include "rwip_task.h" // Task definitions + +/* + * DEFINES + **************************************************************************************** + */ + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Messages for Heart Rate Profile Sensor +enum +{ + ///Start the Heart Rate Profile Sensor - at connection + HRPS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_HRPS), + + /// Disable confirmation with configuration to save after profile disabled + HRPS_ENABLE_RSP, + + ///Send Heart Rate measurement value from APP + HRPS_MEAS_SEND_REQ, + ///Send Heart Rate measurement value confirm to APP so stable values can be erased + ///if correctly sent. + HRPS_MEAS_SEND_RSP, + + ///Inform APP of new configuration value + HRPS_CFG_INDNTF_IND, + ///Inform APP that Energy Expanded must be reset value + HRPS_ENERGY_EXP_RESET_IND, +}; + +///Parameters of the @ref HRPS_CREATE_DB_REQ message +struct hrps_db_cfg +{ + ///Database configuration + uint8_t features; + ///Body Sensor Location + uint8_t body_sensor_loc; +}; + +/// Parameters of the @ref HRPS_ENABLE_REQ message +struct hrps_enable_req +{ + ///Connection index + uint8_t conidx; + /// Heart Rate Notification configuration + uint16_t hr_meas_ntf; +}; + +/// Parameters of the @ref HRPS_ENABLE_RSP message +struct hrps_enable_rsp +{ + /// Connection index + uint8_t conidx; + /// status + uint8_t status; +}; + +///Parameters of the @ref HRPS_CFG_INDNTF_IND message +struct hrps_cfg_indntf_ind +{ + ///Connection idx + uint8_t conidx; + ///Stop/notify/indicate value to configure into the peer characteristic + uint16_t cfg_val; +}; + +/////Parameters of the @ref HRPS_MEAS_SEND_REQ message +struct hrps_meas_send_req +{ + ///Heart Rate measurement + struct hrs_hr_meas meas_val; +}; + +///Parameters of the @ref HRPS_MEAS_SEND_RSP message +struct hrps_meas_send_rsp +{ + ///Status + uint8_t status; +}; + +///Parameters of the @ref HRPS_ENERGY_EXP_RESET_IND message +struct hrps_energy_exp_reset_ind +{ + ///Connection handle + uint8_t conidx; +}; + + +/// @} HRPSTASK + +#endif /* _HRPS_TASK_H_ */ diff --git a/services/ble_profiles/hrp/hrps/src/hrps.c b/services/ble_profiles/hrp/hrps/src/hrps.c new file mode 100644 index 0000000..f56bbe7 --- /dev/null +++ b/services/ble_profiles/hrp/hrps/src/hrps.c @@ -0,0 +1,324 @@ +/** + **************************************************************************************** + * @addtogroup HRPS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_HR_SENSOR) +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "gapc_task.h" +#include "hrps.h" +#include "hrps_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * HTPT PROFILE ATTRIBUTES + **************************************************************************************** + */ + +/// Full HRS Database Description - Used to add attributes into the database +const struct attm_desc hrps_att_db[HRS_IDX_NB] = +{ + // Heart Rate Service Declaration + [HRS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // Heart Rate Measurement Characteristic Declaration + [HRS_IDX_HR_MEAS_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Heart Rate Measurement Characteristic Value + [HRS_IDX_HR_MEAS_VAL] = {ATT_CHAR_HEART_RATE_MEAS, PERM(NTF, ENABLE), PERM(RI, ENABLE), HRPS_HT_MEAS_MAX_LEN}, + // Heart Rate Measurement Characteristic - Client Characteristic Configuration Descriptor + [HRS_IDX_HR_MEAS_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Body Sensor Location Characteristic Declaration + [HRS_IDX_BODY_SENSOR_LOC_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Body Sensor Location Characteristic Value + [HRS_IDX_BODY_SENSOR_LOC_VAL] = {ATT_CHAR_BODY_SENSOR_LOCATION, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, + + // Heart Rate Control Point Characteristic Declaration + [HRS_IDX_HR_CTNL_PT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Heart Rate Control Point Characteristic Value + [HRS_IDX_HR_CTNL_PT_VAL] = {ATT_CHAR_HEART_RATE_CNTL_POINT, PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, +}; + +/** + **************************************************************************************** + * @brief Initialization of the HRPS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t hrps_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct hrps_db_cfg* params) +{ + //------------------ create the attribute database for the profile ------------------- + //Service Configuration Flag + uint8_t cfg_flag = HRPS_MANDATORY_MASK; + //Database Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + //Set Configuration Flag Value + if (HRPS_IS_SUPPORTED(params->features, HRPS_BODY_SENSOR_LOC_CHAR_SUP)) + { + cfg_flag |= HRPS_BODY_SENSOR_LOC_MASK; + } + if (HRPS_IS_SUPPORTED(params->features, HRPS_ENGY_EXP_FEAT_SUP)) + { + cfg_flag |= HRPS_HR_CTNL_PT_MASK; + } + + //Add Service Into Database + status = attm_svc_create_db(start_hdl, ATT_SVC_HEART_RATE, (uint8_t *)&cfg_flag, + HRS_IDX_NB, NULL, env->task, &hrps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS))| PERM(SVC_MI, DISABLE)); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // Allocate HRPS required environment variable + struct hrps_env_tag* hrps_env = + (struct hrps_env_tag* ) ke_malloc(sizeof(struct hrps_env_tag), KE_MEM_ATT_DB); + + // Initialize HRPS environment + env->env = (prf_env_t*) hrps_env; + hrps_env->shdl = *start_hdl; + hrps_env->features = params->features; + hrps_env->sensor_location = params->body_sensor_loc; + hrps_env->operation = NULL; + + hrps_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Mono Instantiated task + hrps_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + // initialize environment variable + env->id = TASK_ID_HRPS; + hrps_task_init(&(env->desc)); + + /* Put HRS in Idle state */ + ke_state_set(env->task, HRPS_IDLE); + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the HRPS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void hrps_destroy(struct prf_task_env* env) +{ + struct hrps_env_tag* hrps_env = (struct hrps_env_tag*) env->env; + + // free profile environment variables + if(hrps_env->operation != NULL) + { + ke_free(hrps_env->operation); + } + env->env = NULL; + ke_free(hrps_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void hrps_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Nothing to do */ +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void hrps_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + /* Nothing to do */ +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// HRPS Task interface required by profile manager +const struct prf_task_cbs hrps_itf = +{ + (prf_init_fnct) hrps_init, + hrps_destroy, + hrps_create, + hrps_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* hrps_prf_itf_get(void) +{ + return &hrps_itf; +} + + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +void hrps_meas_send_rsp_send(uint8_t status) +{ + // Get the address of the environment + struct hrps_env_tag *hrps_env = PRF_ENV_GET(HRPS, hrps); + + // Send CFM to APP that value has been sent or not + struct hrps_meas_send_rsp * cfm = KE_MSG_ALLOC( + HRPS_MEAS_SEND_RSP, + prf_dst_task_get(&hrps_env->prf_env, 0), + prf_src_task_get(&hrps_env->prf_env, 0), + hrps_meas_send_rsp); + + cfm->status = status; + + ke_msg_send(cfm); +} + +uint8_t hrps_pack_meas_value(uint8_t *packed_hr, const struct hrs_hr_meas* pmeas_val) +{ + uint8_t cursor = 0; + uint8_t i = 0; + + // Heart Rate measurement flags + *(packed_hr) = pmeas_val->flags; + + if ((pmeas_val->flags & HRS_FLAG_HR_16BITS_VALUE) == HRS_FLAG_HR_16BITS_VALUE) + { + // Heart Rate Measurement Value 16 bits + co_write16p(packed_hr + 1, pmeas_val->heart_rate); + cursor += 3; + } + else + { + // Heart Rate Measurement Value 8 bits + *(packed_hr + 1) = pmeas_val->heart_rate; + cursor += 2; + } + + if ((pmeas_val->flags & HRS_FLAG_ENERGY_EXPENDED_PRESENT) == HRS_FLAG_ENERGY_EXPENDED_PRESENT) + { + // Energy Expended present + co_write16p(packed_hr + cursor, pmeas_val->energy_expended); + cursor += 2; + } + + if ((pmeas_val->flags & HRS_FLAG_RR_INTERVAL_PRESENT) == HRS_FLAG_RR_INTERVAL_PRESENT) + { + for(i = 0 ; (i < (pmeas_val->nb_rr_interval)) && (i < (HRS_MAX_RR_INTERVAL)) ; i++) + { + // RR-Intervals + co_write16p(packed_hr + cursor, pmeas_val->rr_intervals[i]); + cursor += 2; + } + } + + // Clear unused packet data + if(cursor < HRPS_HT_MEAS_MAX_LEN) + { + memset(packed_hr + cursor, 0, HRPS_HT_MEAS_MAX_LEN - cursor); + } + + return cursor; +} + + +void hrps_exe_operation(void) +{ + struct hrps_env_tag *hrps_env = PRF_ENV_GET(HRPS, hrps); + + ASSERT_ERR(hrps_env->operation != NULL); + + bool finished = true; + + while(hrps_env->operation->cursor < BLE_CONNECTION_MAX) + { + // Check if notifications are enabled + if((hrps_env->hr_meas_ntf[hrps_env->operation->cursor] & ~HRP_PRF_CFG_PERFORMED_OK) == PRF_CLI_START_NTF) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, hrps_env->operation->cursor), + prf_src_task_get(&(hrps_env->prf_env), 0), + gattc_send_evt_cmd, hrps_env->operation->length); + + // Fill in the parameter structure + meas_val->operation = GATTC_NOTIFY; + meas_val->handle = hrps_env->shdl + HRS_IDX_HR_MEAS_VAL; + meas_val->length = hrps_env->operation->length; + memcpy(meas_val->value, hrps_env->operation->data, hrps_env->operation->length); + + // Send the event + ke_msg_send(meas_val); + + finished = false; + hrps_env->operation->cursor++; + break; + } + + hrps_env->operation->cursor++; + } + + // check if operation is finished + if(finished) + { + // Send confirmation + hrps_meas_send_rsp_send(GAP_ERR_NO_ERROR); + + // free operation + ke_free(hrps_env->operation); + hrps_env->operation = NULL; + // go back to idle state + ke_state_set(prf_src_task_get(&(hrps_env->prf_env), 0), HRPS_IDLE); + } +} + +#endif /* BLE_HR_SENSOR */ + +/// @} HRPS diff --git a/services/ble_profiles/hrp/hrps/src/hrps.h b/services/ble_profiles/hrp/hrps/src/hrps.h new file mode 100644 index 0000000..eb45c00 --- /dev/null +++ b/services/ble_profiles/hrp/hrps/src/hrps.h @@ -0,0 +1,228 @@ +#ifndef _HRPS_H_ +#define _HRPS_H_ + +/** + **************************************************************************************** + * @addtogroup HRPS Heart Rate Profile Sensor + * @ingroup HRP + * @brief Heart Rate Profile Sensor + * + * Heart Rate sensor (HRS) profile provides functionalities to upper layer module + * application. The device using this profile takes the role of Heart Rate sensor. + * + * The interface of this role to the Application is: + * - Enable the profile role (from APP) + * - Disable the profile role (from APP) + * - Notify peer device during Heart Rate measurement (from APP) + * - Indicate measurements performed to peer device (from APP) + * + * Profile didn't manages multiple users configuration and storage of offline measurements. + * This must be handled by application. + * + * Heart Rate Profile Sensor. (HRPS): A HRPS (e.g. PC, phone, etc) + * is the term used by this profile to describe a device that can perform Heart Rate + * measurement and notify about on-going measurement and indicate final result to a peer + * BLE device. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_HR_SENSOR) +#include "hrp_common.h" +#include "prf_types.h" +#include "prf.h" +#include "hrps_task.h" +#include "attm.h" + +/* + * DEFINES + **************************************************************************************** + */ +///Maximum number of Heart Rate task instances +#define HRPS_IDX_MAX 0x01 + +#define HRPS_HT_MEAS_MAX_LEN (5 + (2 * HRS_MAX_RR_INTERVAL)) + +#define HRPS_MANDATORY_MASK (0x0F) +#define HRPS_BODY_SENSOR_LOC_MASK (0x30) +#define HRPS_HR_CTNL_PT_MASK (0xC0) + +#define HRP_PRF_CFG_PERFORMED_OK (0x80) + +/* + * MACROS + **************************************************************************************** + */ + +#define HRPS_IS_SUPPORTED(features, mask) ((features & mask) == mask) + + +/* + * DEFINES + **************************************************************************************** + */ +/// Possible states of the HRPS task +enum +{ + /// Idle state + HRPS_IDLE, + /// Connected state + HRPS_BUSY, + + /// Number of defined states. + HRPS_STATE_MAX, +}; + +///Attributes State Machine +enum +{ + 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, +}; + +enum +{ + HRPS_HR_MEAS_CHAR, + HRPS_BODY_SENSOR_LOC_CHAR, + HRPS_HR_CTNL_PT_CHAR, + + HRPS_CHAR_MAX, +}; + +enum +{ + /// Body Sensor Location Feature Supported + HRPS_BODY_SENSOR_LOC_CHAR_SUP = 0x01, + /// Energy Expanded Feature Supported + HRPS_ENGY_EXP_FEAT_SUP = 0x02, + + HRPS_HR_MEAS_NTF_CFG = 0x04, +}; + + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + + +/// ongoing operation information +struct hrps_op +{ + /// Cursor on connection + uint8_t cursor; + /// Packed notification/indication data size + uint8_t length; + /// Packed notification/indication data + uint8_t data[HRPS_HT_MEAS_MAX_LEN]; +}; + +/// Heart Rate Profile Sensor environment variable +struct hrps_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Operation pointer used to generate notifications + struct hrps_op* operation; + ///Service Start Handle + uint16_t shdl; + ///Database configuration + uint8_t features; + /// Sensor location + uint8_t sensor_location; + /// Measurement notification config + uint16_t hr_meas_ntf[BLE_CONNECTION_MAX]; + + /// State of different task instances + ke_state_t state[HRPS_IDX_MAX]; +}; + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve HRP service profile interface + * + * @return HRP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* hrps_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send a HRPS_MEAS_SEND_RSP message to the application. + * + * @param[in] status Confirmation Status + **************************************************************************************** + */ +void hrps_meas_send_rsp_send(uint8_t status); + +/** + **************************************************************************************** + * @brief Pack Heart Rate measurement value + * + * @param[in] p_meas_val Heart Rate measurement value + **************************************************************************************** + */ +uint8_t hrps_pack_meas_value(uint8_t *packed_hr, const struct hrs_hr_meas* pmeas_val); + + + +/** + **************************************************************************************** + * @brief This function fully manage notification of Heart Rate Measurement + * to peer(s) device(s) according to on-going operation requested by application + **************************************************************************************** + */ +void hrps_exe_operation(void); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void hrps_task_init(struct ke_task_desc *task_desc); + +#endif /* #if (BLE_HR_SENSOR) */ + +/// @} HRPS + +#endif /* _HRPS_H_ */ diff --git a/services/ble_profiles/hrp/hrps/src/hrps_task.c b/services/ble_profiles/hrp/hrps/src/hrps_task.c new file mode 100644 index 0000000..fab0781 --- /dev/null +++ b/services/ble_profiles/hrp/hrps/src/hrps_task.c @@ -0,0 +1,353 @@ +/** + **************************************************************************************** + * @addtogroup HRPSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_HR_SENSOR) +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "hrps.h" +#include "hrps_task.h" + +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HRPS_ENABLE_REQ message. + * The handler enables the Heart Rate Sensor Profile. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hrps_enable_req_handler(ke_msg_id_t const msgid, + struct hrps_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct hrps_env_tag *hrps_env = PRF_ENV_GET(HRPS, hrps); + + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(ke_state_get(dest_id) == HRPS_IDLE) + { + if ((param->conidx < BLE_CONNECTION_MAX) && + (param->hr_meas_ntf <= PRF_CLI_START_NTF)) + { + // Bonded data was not used before + if (!HRPS_IS_SUPPORTED(hrps_env->hr_meas_ntf[param->conidx], HRP_PRF_CFG_PERFORMED_OK)) + { + // Save notification config + hrps_env->hr_meas_ntf[param->conidx] = param->hr_meas_ntf; + // Enable Bonded Data + hrps_env->hr_meas_ntf[param->conidx] |= HRP_PRF_CFG_PERFORMED_OK; + status = GAP_ERR_NO_ERROR; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + + // send completed information to APP task that contains error status + struct hrps_enable_rsp *cmp_evt = KE_MSG_ALLOC(HRPS_ENABLE_RSP, src_id, dest_id, hrps_enable_rsp); + cmp_evt->status = status; + cmp_evt->conidx = param->conidx; + ke_msg_send(cmp_evt); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HRPS_MEAS_SEND_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int hrps_meas_send_req_handler(ke_msg_id_t const msgid, + struct hrps_meas_send_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + // State shall not be Connected or Busy + if (ke_state_get(dest_id) == HRPS_IDLE) + { + if(param->meas_val.nb_rr_interval <= HRS_MAX_RR_INTERVAL) + { + + // Get the address of the environment + struct hrps_env_tag *hrps_env = PRF_ENV_GET(HRPS, hrps); + + // allocate and prepare data to notify + hrps_env->operation = (struct hrps_op*) ke_malloc(sizeof(struct hrps_op), KE_MEM_KE_MSG); + hrps_env->operation->length = hrps_pack_meas_value(hrps_env->operation->data, ¶m->meas_val); + hrps_env->operation->cursor = 0; + + // start operation execution + hrps_exe_operation(); + + // Go to busy state + ke_state_set(dest_id, HRPS_BUSY); + } + else + { + // Send confirmation + hrps_meas_send_rsp_send(PRF_ERR_INVALID_PARAM); + } + } + else + { + // Save it for later + msg_status = KE_MSG_SAVED; + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. + * The handler compares the new values with current ones and notifies them if they changed. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct hrps_env_tag *hrps_env = PRF_ENV_GET(HRPS, hrps); + uint8_t conidx = KE_IDX_GET(src_id); + + uint16_t value = 0x0000; + uint8_t status = GAP_ERR_NO_ERROR; + + if (hrps_env != NULL) + { + //BP Measurement Char. - Client Char. Configuration + if (param->handle == (hrps_env->shdl + HRS_IDX_HR_MEAS_NTF_CFG)) + { + //Extract value before check + memcpy(&value, &(param->value), sizeof(uint16_t)); + + if ((value == PRF_CLI_STOP_NTFIND) || (value == PRF_CLI_START_NTF)) + { + hrps_env->hr_meas_ntf[conidx] = value | HRP_PRF_CFG_PERFORMED_OK; + } + else + { + status = PRF_APP_ERROR; + } + + if (status == GAP_ERR_NO_ERROR) + { + //Inform APP of configuration change + struct hrps_cfg_indntf_ind * ind = KE_MSG_ALLOC(HRPS_CFG_INDNTF_IND, + prf_dst_task_get(&hrps_env->prf_env, conidx), + prf_src_task_get(&hrps_env->prf_env, conidx), + hrps_cfg_indntf_ind); + + ind->conidx = conidx; + ind->cfg_val = value; + + ke_msg_send(ind); + } + } + //HR Control Point Char. Value + else + { + if (HRPS_IS_SUPPORTED(hrps_env->features, HRPS_ENGY_EXP_FEAT_SUP)) + { + //Extract value + memcpy(&value, &(param->value), sizeof(uint8_t)); + + if (value == 0x1) + { + //inform APP of configuration change + struct hrps_energy_exp_reset_ind * ind = KE_MSG_ALLOC(HRPS_ENERGY_EXP_RESET_IND, + prf_dst_task_get(&hrps_env->prf_env, conidx), + prf_src_task_get(&hrps_env->prf_env, conidx), + hrps_energy_exp_reset_ind); + + ind->conidx = conidx; + ke_msg_send(ind); + } + else + { + status = HRS_ERR_HR_CNTL_POINT_NOT_SUPPORTED; + } + } + else + { + //Allowed to send Application Error if value inconvenient + status = HRS_ERR_HR_CNTL_POINT_NOT_SUPPORTED; + } + } + } + + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY message meaning that Measurement + * notification has been correctly sent to peer device (but not confirmed by peer device). + * * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + if((ke_state_get(dest_id) == HRPS_BUSY) && (param->operation == GATTC_NOTIFY)) + { + // continue operation execution + hrps_exe_operation(); + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == HRPS_IDLE) + { + // Get the address of the environment + struct hrps_env_tag *hrps_env = PRF_ENV_GET(HRPS, hrps); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t att_idx = param->handle - hrps_env->shdl; + + uint8_t value[4]; + uint8_t value_size = 0; + uint8_t status = ATT_ERR_NO_ERROR; + + switch(att_idx) + { + case HRS_IDX_HR_MEAS_NTF_CFG: + { + value_size = sizeof(uint16_t); + co_write16p(value, hrps_env->hr_meas_ntf[conidx] & ~HRP_PRF_CFG_PERFORMED_OK); + } break; + + case HRS_IDX_BODY_SENSOR_LOC_VAL: + { + // Broadcast feature is profile specific + if (HRPS_IS_SUPPORTED(hrps_env->features, HRPS_BODY_SENSOR_LOC_CHAR_SUP)) + { + // Fill data + value_size = sizeof(uint8_t); + value[0] = hrps_env->sensor_location; + } + else + { + status = ATT_ERR_ATTRIBUTE_NOT_FOUND; + } + } break; + + default: + { + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } break; + } + + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, value_size); + cfm->length = value_size; + memcpy(cfm->value, value, value_size); + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/* Default State handlers definition. */ +KE_MSG_HANDLER_TAB(hrps) +{ + {HRPS_ENABLE_REQ, (ke_msg_func_t) hrps_enable_req_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {HRPS_MEAS_SEND_REQ, (ke_msg_func_t) hrps_meas_send_req_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, +}; + +void hrps_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct hrps_env_tag *hrps_env = PRF_ENV_GET(HRPS, hrps); + + task_desc->msg_handler_tab = hrps_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(hrps_msg_handler_tab); + task_desc->state = hrps_env->state; + task_desc->idx_max = HRPS_IDX_MAX; +} + +#endif /* #if (BLE_HR_SENSOR) */ + +/// @} HRPSTASK diff --git a/services/ble_profiles/htp/htp_common.h b/services/ble_profiles/htp/htp_common.h new file mode 100644 index 0000000..fb81837 --- /dev/null +++ b/services/ble_profiles/htp/htp_common.h @@ -0,0 +1,92 @@ +#ifndef _HTP_COMMON_H_ +#define _HTP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup HTP Health Thermometer Profile + * @ingroup PROFILE + * @brief Health Thermometer Profile + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "prf_types.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Out of range error code. +#define HTP_OUT_OF_RANGE_ERR_CODE (0x80) + +///Temperature Measurement Flags field bit values +enum htp_temp_flag +{ + /// Temperature Units Flag - Celsius + HTP_FLAG_CELSIUS = 0x00, + /// Temperature Units Flag - Fahrenheit + HTP_FLAG_FAHRENHEIT, + /// Time Stamp Flag + HTP_FLAG_TIME, + /// Temperature Type Flag + HTP_FLAG_TYPE = 0x04, +}; + +/// Temperature Type Description +enum htp_temp_type +{ + /// Armpit + HTP_TYPE_ARMPIT = 0x01, + /// Body (general) + HTP_TYPE_BODY = 0x02, + /// Ear (usually ear lobe) + HTP_TYPE_EAR = 0x03, + /// Finger + HTP_TYPE_FINGER = 0x04, + /// Gastro-intestinal Tract + HTP_TYPE_GASTRO_INTESTINAL_TRACT = 0x05, + /// Mouth + HTP_TYPE_MOUTH = 0x06, + /// Rectum + HTP_TYPE_RECTUM = 0x07, + /// Toe + HTP_TYPE_TOE = 0x08, + /// Tympanum (ear drum) + HTP_TYPE_TYMPANUM = 0x09, +}; + +/// Temprature type: intermdiary/stable +enum htp_temp_info +{ + /// intermediate temperature measurement + HTP_TEMP_INTERM = (0x00), + /// stable temperature measurement + HTP_TEMP_STABLE = (0x01), +}; + /* + * STRUCTURES + **************************************************************************************** + */ + +///Temperature Measurement Value Structure +struct htp_temp_meas +{ + /// Temperature value + uint32_t temp; + /// Time stamp + struct prf_date_time time_stamp; + /// Flag (@see enum htp_temp_flag) + uint8_t flags; + /// Type (@see enum htp_temp_type) + uint8_t type; +}; + + +/// @} htp_common + +#endif /* _HTP_COMMON_H_ */ diff --git a/services/ble_profiles/htp/htpc/api/htpc_task.h b/services/ble_profiles/htp/htpc/api/htpc_task.h new file mode 100644 index 0000000..54ff2d1 --- /dev/null +++ b/services/ble_profiles/htp/htpc/api/htpc_task.h @@ -0,0 +1,216 @@ +#ifndef HTPC_TASK_H_ +#define HTPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup HTPCTASK Health Thermometer Profile Collector Task + * @ingroup HTPC + * @brief Health Thermometer Profile Collector Task + * + * The HTPCTASK is responsible for handling the messages coming in and out of the + * @ref HTPC monitor block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_task.h" // Task definitions +#include "htp_common.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +/// Message id +enum htpc_msg_id +{ + /// Start the Health Thermometer Collector profile - at connection + HTPC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_HTPC), + /// Confirm that cfg connection has finished with discovery results, or that normal cnx started + HTPC_ENABLE_RSP, + + + /// Write Health Thermometer Notification Configuration Value request + HTPC_HEALTH_TEMP_NTF_CFG_REQ, + /// Write Health Thermometer Notification Configuration Value response + HTPC_HEALTH_TEMP_NTF_CFG_RSP, + + ///APP request for measurement interval write + HTPC_WR_MEAS_INTV_REQ, + ///APP request for measurement interval write + HTPC_WR_MEAS_INTV_RSP, + + /// Temperature value received from peer sensor + HTPC_TEMP_IND, + /// Measurement interval update indication received from peer sensor + HTPC_MEAS_INTV_IND, + + /// Generic message to read a HTP characteristic value + HTPC_RD_CHAR_REQ, + /// Read HTP characteristic value response + HTPC_RD_CHAR_RSP, +}; + + + +/// Health Thermometer Service Characteristics - Char. Code +enum htpc_chars +{ + /// Temperature Measurement + HTPC_CHAR_HTS_TEMP_MEAS = 0x0, + /// Temperature Type + HTPC_CHAR_HTS_TEMP_TYPE, + /// Intermediate Temperature + HTPC_CHAR_HTS_INTM_TEMP, + /// Measurement Interval + HTPC_CHAR_HTS_MEAS_INTV, + + HTPC_CHAR_HTS_MAX, +}; + +/// Health Thermometer Service Characteristic Descriptors +enum htpc_descs +{ + /// Temp. Meas. Client Config + HTPC_DESC_HTS_TEMP_MEAS_CLI_CFG, + /// Intm. Meas. Client Config + HTPC_DESC_HTS_INTM_MEAS_CLI_CFG, + /// Meas. Intv. Client Config + HTPC_DESC_HTS_MEAS_INTV_CLI_CFG, + /// Meas. Intv. Valid Range, + HTPC_DESC_HTS_MEAS_INTV_VAL_RGE, + + HTPC_DESC_HTS_MAX, +}; + +/// Internal codes for reading a HTS characteristic with one single request +enum htpc_rd_char +{ + ///Read HTS Temp. Type + HTPC_RD_TEMP_TYPE = 0, + ///Read HTS Measurement Interval + HTPC_RD_MEAS_INTV, + + ///Read HTS Temperature Measurement Client Cfg. Desc + HTPC_RD_TEMP_MEAS_CLI_CFG, + ///Read HTS Intermediate Temperature Client Cfg. Desc + HTPC_RD_INTM_TEMP_CLI_CFG, + ///Read HTS Measurement Interval Client Cfg. Desc + HTPC_RD_MEAS_INTV_CLI_CFG, + ///Read HTS Measurement Interval Client Cfg. Desc + HTPC_RD_MEAS_INTV_VAL_RGE, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Health Thermometer Service + */ +struct htpc_hts_content +{ + /// service info + struct prf_svc svc; + + /// Characteristic info: + struct prf_char_inf chars[HTPC_CHAR_HTS_MAX]; + + /// Descriptor handles: + struct prf_char_desc_inf descs[HTPC_DESC_HTS_MAX]; +}; + +/// Parameters of the @ref HTPC_ENABLE_REQ message +struct htpc_enable_req +{ + ///Connection type + uint8_t con_type; + + ///Existing handle values hts + struct htpc_hts_content hts; +}; + +/// Parameters of the @ref HTPC_ENABLE_RSP message +struct htpc_enable_rsp +{ + ///status + uint8_t status; + /// HTS handle values and characteristic properties + struct htpc_hts_content hts; +}; + +///Parameters of the @ref HTPC_HEALTH_TEMP_NTF_CFG_REQ message +struct htpc_health_temp_ntf_cfg_req +{ + ///Stop/notify/indicate value to configure into the peer characteristic + uint16_t cfg_val; + ///Own code for differentiating between Temperature Measurement, Intermediate Temperature and Measurement Interval chars + uint8_t char_code; +}; + +///Parameters of the @ref HTPC_HEALTH_TEMP_NTF_CFG_RSP message +struct htpc_health_temp_ntf_cfg_rsp +{ + ///status + uint8_t status; +}; + +///Parameters of the @ref HTPC_WR_MEAS_INTV_REQ message +struct htpc_wr_meas_intv_req +{ + ///Interval value + uint16_t intv; +}; + +///Parameters of the @ref HTPC_WR_MEAS_INTV_RSP message +struct htpc_wr_meas_intv_rsp +{ + ///status + uint8_t status; +}; + +///Parameters of the @ref HTPC_TEMP_IND message +struct htpc_temp_ind +{ + /// Temperature Measurement Structure + struct htp_temp_meas temp_meas; + /// Stable or intermediary type of temperature + bool stable_meas; +}; + +///Parameters of @ref HTPC_MEAS_INTV_IND message +struct htpc_meas_intv_ind +{ + ///Interval + uint16_t intv; +}; + +///Parameters of the @ref HTPC_RD_CHAR_REQ message +struct htpc_rd_char_req +{ + ///Characteristic value code (@see enum htpc_rd_char) + uint8_t char_code; +}; + +///Parameters of the @ref HTPC_RD_CHAR_RSP message +struct htpc_rd_char_rsp +{ + /// Attribute data information + struct prf_att_info info; +}; + + + +/// @} HTPCTASK + +#endif // HTPC_TASK_H_ diff --git a/services/ble_profiles/htp/htpc/src/htpc.c b/services/ble_profiles/htp/htpc/src/htpc.c new file mode 100644 index 0000000..5d54251 --- /dev/null +++ b/services/ble_profiles/htp/htpc/src/htpc.c @@ -0,0 +1,287 @@ +/** + **************************************************************************************** + * @addtogroup HTPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_HT_COLLECTOR) +#include "htpc.h" +#include "htpc_task.h" +#include "gap.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the HTPC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t htpc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, + uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct htpc_env_tag* htpc_env = + (struct htpc_env_tag* ) ke_malloc(sizeof(struct htpc_env_tag), KE_MEM_ATT_DB); + + // allocate HTPC required environment variable + env->env = (prf_env_t*) htpc_env; + + htpc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + htpc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_HTPC; + htpc_task_init(&(env->desc)); + + for(idx = 0; idx < HTPC_IDX_MAX ; idx++) + { + htpc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), HTPC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Destruction of the HTPC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void htpc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct htpc_env_tag* htpc_env = (struct htpc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < HTPC_IDX_MAX ; idx++) + { + if(htpc_env->env[idx] != NULL) + { + if(htpc_env->env[idx]->operation != NULL) + { + ke_msg_free(htpc_env->env[idx]->operation); + } + + ke_free(htpc_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(htpc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void htpc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put HTP Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), HTPC_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void htpc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct htpc_env_tag* htpc_env = (struct htpc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(htpc_env->env[conidx] != NULL) + { + if(htpc_env->env[conidx]->operation != NULL) + { + ke_msg_free(htpc_env->env[conidx]->operation); + } + + ke_free(htpc_env->env[conidx]); + htpc_env->env[conidx] = NULL; + } + + /* Put HTP Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), HTPC_FREE); +} + + +void htpc_unpack_temp(struct htpc_env_tag *htpc_env, uint8_t *packed_temp, + uint8_t length, uint8_t flag_stable_meas, uint8_t conidx) +{ + // Cursor used to read parameter in the packed temperature value + uint8_t cursor = 0; + + + // Checked the length of the received value + if (length >= HTPC_PACKED_TEMP_MIN_LEN) + { + // Prepare the message to send to the application + struct htpc_temp_ind *ind = KE_MSG_ALLOC(HTPC_TEMP_IND, + prf_dst_task_get(&htpc_env->prf_env, conidx), + prf_src_task_get(&htpc_env->prf_env, conidx), + htpc_temp_ind); + + // Unpack Temp Measurement + ind->temp_meas.flags = *(packed_temp + cursor); + cursor += 1; + + ind->temp_meas.temp = co_read32p(packed_temp + cursor); + cursor += 4; + + // Time Flag Set + if ((ind->temp_meas.flags & HTP_FLAG_TIME) == HTP_FLAG_TIME) + { + cursor += prf_unpack_date_time(packed_temp+cursor, &(ind->temp_meas.time_stamp)); + } + + // Type Flag set + if ((ind->temp_meas.flags & HTP_FLAG_TYPE) == HTP_FLAG_TYPE) + { + ind->temp_meas.type = *(packed_temp + cursor); + } + + // Stable or intermediary type of temperature + ind->stable_meas = flag_stable_meas; + + //Send request to ATT + ke_msg_send(ind); + } +} +#if 0 +uint8_t htpc_get_next_desc_char_code(struct htpc_env_tag *htpc_env, + const struct prf_char_desc_def *desc_def) +{ + // Counter + uint8_t i; + uint8_t next_char_code; + + for (i=0; i htpc_env->last_char_code) + { + //If Char. has been found and number of attributes is upper than 2 + if ((htpc_env->hts.chars[next_char_code].char_hdl != 0) + & (htpc_env->hts.chars[next_char_code].char_ehdl_off > 2)) + { + return next_char_code; + } + } + } + + return i; +} +#endif + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// HTPC Task interface required by profile manager +const struct prf_task_cbs htpc_itf = +{ + (prf_init_fnct) htpc_init, + htpc_destroy, + htpc_create, + htpc_cleanup, +}; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* htpc_prf_itf_get(void) +{ + return &htpc_itf; +} + + +void htpc_enable_rsp_send(struct htpc_env_tag *htpc_env, uint8_t conidx, uint8_t status) +{ + // Inform the APP about the status of the enabling of the Health Thermometer Profile Collector role 5awk + struct htpc_enable_rsp *cfm = KE_MSG_ALLOC(HTPC_ENABLE_RSP, + prf_dst_task_get(&(htpc_env->prf_env), conidx), + prf_src_task_get(&(htpc_env->prf_env), conidx), + htpc_enable_rsp); + + // Status + cfm->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + cfm->hts = htpc_env->env[conidx]->hts; + // Go to IDLE state + ke_state_set(prf_src_task_get(&(htpc_env->prf_env), conidx), HTPC_IDLE); + + // Register profile handle to catch gatt indications + prf_register_atthdl2gatt(&(htpc_env->prf_env), conidx, &htpc_env->env[conidx]->hts.svc ); + } + else + { + if(htpc_env->env[conidx] != NULL) + { + // clean-up environment variable allocated for task instance + if(htpc_env->env[conidx]->operation != NULL) + { + ke_free(htpc_env->env[conidx]->operation); + } + ke_free(htpc_env->env[conidx]); + htpc_env->env[conidx] = NULL; + } + } + + // Send the confirmation to the application + ke_msg_send(cfm); +} + +#endif //BLE_HT_COLLECTOR +/// @} HTPC diff --git a/services/ble_profiles/htp/htpc/src/htpc.h b/services/ble_profiles/htp/htpc/src/htpc.h new file mode 100644 index 0000000..21f5e02 --- /dev/null +++ b/services/ble_profiles/htp/htpc/src/htpc.h @@ -0,0 +1,178 @@ +#ifndef HTPC_H_ +#define HTPC_H_ + +/** + **************************************************************************************** + * @addtogroup HTP Health Thermometer Profile + * @ingroup PROFILE + * @brief Health Thermometer Profile + * + * The HTP module is the responsible block for implementing the Health Thermometer Profile + * functionalities in the BLE Host. + * + * The Health Thermometer Profile defines the functionality required in a device that allows + * the user (Collector device) to configure and recover temperature measurements from a Thermometer device. + ***************************************************************************************** + */ + +/** + **************************************************************************************** + * @addtogroup HTPC Health Thermometer Profile Collector + * @ingroup HTP + * @brief Health Thermometer Profile Collector + * + * The HTPC is responsible for providing Health Thermometer Profile Collector functionalities to + * upper layer module or application. The device using this profile takes the role + * of Health Thermometer Profile Collector. + * + * Health Thermometer Profile Collector (HTPC): A HTPC (e.g. PC, phone, etc) + * is the term used by this profile to describe a device that can set temperature + * indication/notification intervals in a HTP Thermometer, interpreting them in a way + * suitable to the user application. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_HT_COLLECTOR || BLE_HT_THERMOM) +#include "ke_task.h" +#include "prf_utils.h" +#include "htpc_task.h" +#include "htp_common.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +#define HTPC_PACKED_TEMP_MIN_LEN (5) +#define HTPC_PACKED_TEMP_MAX_LEN (13) + +/// Maximum number of task instances +#define HTPC_IDX_MAX (BLE_CONNECTION_MAX) + + +/// Possible states of the HTPC task +enum htpc_state +{ + ///Free state + HTPC_FREE, + ///Idle state + HTPC_IDLE, + ///Busy state + HTPC_BUSY, + + ///Number of defined states. + HTPC_STATE_MAX +}; +/* + * MACROS + **************************************************************************************** + */ + + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Health Temperature Collector environment variable per connection +struct htpc_cnx_env +{ + /// Last service for which something was discovered + uint8_t last_svc_req; + /// counter used to check service uniqueness + uint8_t nb_svc; + /// used to store if measurement context + uint8_t meas_ctx_en; + + struct ke_msg * operation; + + struct htpc_hts_content hts; +}; + +/// Health Thermometer Profile Client environment variable +struct htpc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct htpc_cnx_env* env[HTPC_IDX_MAX]; + /// State of different task instances + ke_state_t state[HTPC_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve HTS service profile interface + * + * @return HTS service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* htpc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Thermometer ATT DB discovery results to HTPC host. + **************************************************************************************** + */ +void htpc_enable_rsp_send(struct htpc_env_tag *htpc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Unpack the received temperature measurement value + **************************************************************************************** + */ +void htpc_unpack_temp(struct htpc_env_tag *htpc_env, uint8_t *packed_temp, + uint8_t length, uint8_t flag_stable_meas, uint8_t conidx); + +/** + **************************************************************************************** + * @brief Look for the next characteristic for which descriptors have to be discovered. + * @return Char code of this characteristic + **************************************************************************************** + */ +uint8_t htpc_get_next_desc_char_code(struct htpc_env_tag *htpc_env, + const struct prf_char_desc_def *desc_def); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void htpc_task_init(struct ke_task_desc *task_desc); + + +#endif //BLE_HT_COLLECTOR +/// @} HTPC +#endif // HTPC_H_ diff --git a/services/ble_profiles/htp/htpc/src/htpc_task.c b/services/ble_profiles/htp/htpc/src/htpc_task.c new file mode 100644 index 0000000..dd1b434 --- /dev/null +++ b/services/ble_profiles/htp/htpc/src/htpc_task.c @@ -0,0 +1,651 @@ +/** + **************************************************************************************** + * @addtogroup HTPCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_HT_COLLECTOR) +#include "co_utils.h" +#include "gap.h" +#include "attm.h" +#include "htpc_task.h" +#include "htpc.h" +#include "gapc.h" +#include "gapc_task.h" + +#include "ke_mem.h" + +/// State machine used to retrieve Health Thermometer service characteristics information +const struct prf_char_def htpc_hts_char[HTPC_CHAR_HTS_MAX] = +{ + /// Temperature Measurement + [HTPC_CHAR_HTS_TEMP_MEAS] = {ATT_CHAR_TEMPERATURE_MEAS, ATT_MANDATORY, ATT_CHAR_PROP_IND}, + /// Temperature Type + [HTPC_CHAR_HTS_TEMP_TYPE] = {ATT_CHAR_TEMPERATURE_TYPE, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, + /// Intermediate Temperature + [HTPC_CHAR_HTS_INTM_TEMP] = {ATT_CHAR_INTERMED_TEMPERATURE, ATT_OPTIONAL, ATT_CHAR_PROP_NTF}, + /// Measurement Interval + [HTPC_CHAR_HTS_MEAS_INTV] = {ATT_CHAR_MEAS_INTERVAL, ATT_OPTIONAL, ATT_CHAR_PROP_RD}, +}; + +/// State machine used to retrieve Health Thermometer service characteristics description information +const struct prf_char_desc_def htpc_hts_char_desc[HTPC_DESC_HTS_MAX] = +{ + /// Temperature Measurement Client Config + [HTPC_DESC_HTS_TEMP_MEAS_CLI_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_MANDATORY, HTPC_CHAR_HTS_TEMP_MEAS}, + /// Intermediate Temperature Client Config + [HTPC_DESC_HTS_INTM_MEAS_CLI_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_OPTIONAL, HTPC_CHAR_HTS_INTM_TEMP}, + /// Measurement Interval Client Config + [HTPC_DESC_HTS_MEAS_INTV_CLI_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, ATT_OPTIONAL, HTPC_CHAR_HTS_MEAS_INTV}, + /// Measurement Interval valid range + [HTPC_DESC_HTS_MEAS_INTV_VAL_RGE] = {ATT_DESC_VALID_RANGE, ATT_OPTIONAL, HTPC_CHAR_HTS_MEAS_INTV}, +}; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HTPC_ENABLE_REQ message. + * The handler enables the Health Thermometer Profile Collector Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int htpc_enable_req_handler(ke_msg_id_t const msgid, + struct htpc_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + uint8_t status = GAP_ERR_NO_ERROR; + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Health Thermometer Profile Collector Role Task Environment + struct htpc_env_tag *htpc_env = PRF_ENV_GET(HTPC, htpc); + + if((state == HTPC_IDLE) && (htpc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + htpc_env->env[conidx] = (struct htpc_cnx_env*) ke_malloc(sizeof(struct htpc_cnx_env),KE_MEM_ATT_DB); + memset(htpc_env->env[conidx], 0, sizeof(struct htpc_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering HTS on peer + prf_disc_svc_send(&(htpc_env->prf_env), conidx, ATT_SVC_HEALTH_THERMOM); + + // store context of request and go into busy state + htpc_env->env[conidx]->operation = ke_param2msg(param); + msg_status = KE_MSG_NO_FREE; + ke_state_set(dest_id, HTPC_BUSY); + } + //normal connection, get saved att details + else + { + htpc_env->env[conidx]->hts = param->hts; + + //send APP confirmation that can start normal connection to TH + htpc_enable_rsp_send(htpc_env, conidx, GAP_ERR_NO_ERROR); + } + } + else + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + htpc_enable_rsp_send(htpc_env, conidx, status); + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == HTPC_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct htpc_env_tag *htpc_env = PRF_ENV_GET(HTPC, htpc); + + ASSERT_INFO(htpc_env != NULL, dest_id, src_id); + ASSERT_INFO(htpc_env->env[conidx] != NULL, dest_id, src_id); + + if(htpc_env->env[conidx]->nb_svc == 0) + { + // Retrieve IAS characteristic + prf_extract_svc_info(ind, HTPC_CHAR_HTS_MAX, &htpc_hts_char[0], + htpc_env->env[conidx]->hts.chars, + HTPC_DESC_HTS_MAX, + &htpc_hts_char_desc[0], + &(htpc_env->env[conidx]->hts.descs[0]) ); + + //Even if we get multiple responses we only store 1 range + htpc_env->env[conidx]->hts.svc.shdl = ind->start_hdl; + htpc_env->env[conidx]->hts.svc.ehdl = ind->end_hdl; + } + htpc_env->env[conidx]->nb_svc++; + } + return (KE_MSG_CONSUMED); +} + + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HTPC_WR_MEAS_INTV_REQ message. + * Check if the handle exists in profile(already discovered) and send request, otherwise + * error to APP. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int htpc_wr_meas_intv_req_handler(ke_msg_id_t const msgid, + struct htpc_wr_meas_intv_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + + // Device Information Service Client Role Task Environment + struct htpc_env_tag *htpc_env = PRF_ENV_GET(HTPC, htpc); + + ASSERT_INFO(htpc_env != NULL, dest_id, src_id); + if((state == HTPC_IDLE) && (htpc_env->env[conidx] != NULL)) + { + uint16_t val_hdl = ATT_INVALID_HANDLE; + + if ((htpc_env->env[conidx]->hts.chars[HTPC_CHAR_HTS_MEAS_INTV].prop & ATT_CHAR_PROP_WR) != ATT_CHAR_PROP_WR) + { + status = PRF_ERR_NOT_WRITABLE; + } + else + { + val_hdl = htpc_env->env[conidx]->hts.chars[HTPC_CHAR_HTS_MEAS_INTV].val_hdl; + + if (val_hdl != ATT_INVALID_HANDLE) + { + // Send GATT Write Request + prf_gatt_write(&(htpc_env->prf_env), conidx, val_hdl, + (uint8_t *)¶m->intv, sizeof(uint16_t), GATTC_WRITE); + + // store context of request and go into busy state + htpc_env->env[conidx]->operation = ke_param2msg(param); + msg_status = KE_MSG_NO_FREE; + ke_state_set(dest_id, HTPC_BUSY); + } + else + { + // invalid handle requested + status = PRF_ERR_INEXISTENT_HDL; + } + } + } + else if(state != HTPC_FREE) + { + // request cannot be performed + status = PRF_ERR_REQ_DISALLOWED; + } + + // send error response if request fails + if(status != GAP_ERR_NO_ERROR) + { + struct htpc_wr_meas_intv_rsp *rsp = KE_MSG_ALLOC(HTPC_WR_MEAS_INTV_RSP, src_id, dest_id, htpc_wr_meas_intv_rsp); + rsp->status = status; + ke_msg_send(rsp); + } + + return (msg_status); +} + + + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HTPC_HEALTH_TEMP_NTF_CFG_REQ message. + * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic. + * Will return an error code if that cfg char does not exist. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int htpc_health_temp_ntf_cfg_req_handler(ke_msg_id_t const msgid, + struct htpc_health_temp_ntf_cfg_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Client Characteristic Configuration Descriptor Handle + uint16_t cfg_hdl = 0x0000; + // Status + uint8_t status = GAP_ERR_NO_ERROR; + int msg_status = KE_MSG_CONSUMED; + // Get the address of the environment + struct htpc_env_tag *htpc_env = PRF_ENV_GET(HTPC, htpc); + uint8_t conidx = KE_IDX_GET(dest_id); + + switch(param->char_code) + { + case HTPC_CHAR_HTS_TEMP_MEAS://can only IND + cfg_hdl = htpc_env->env[conidx]->hts.descs[HTPC_DESC_HTS_TEMP_MEAS_CLI_CFG].desc_hdl; + if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)|| + (param->cfg_val == PRF_CLI_START_IND))) + { + status = PRF_ERR_INVALID_PARAM; + } + break; + + case HTPC_CHAR_HTS_MEAS_INTV://can only IND + cfg_hdl = htpc_env->env[conidx]->hts.descs[HTPC_DESC_HTS_MEAS_INTV_CLI_CFG].desc_hdl; + if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)|| + (param->cfg_val == PRF_CLI_START_IND))) + { + status = PRF_ERR_INVALID_PARAM; + } + break; + + case HTPC_CHAR_HTS_INTM_TEMP://can only NTF + cfg_hdl = htpc_env->env[conidx]->hts.descs[HTPC_DESC_HTS_INTM_MEAS_CLI_CFG].desc_hdl; + if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)|| + (param->cfg_val == PRF_CLI_START_NTF))) + { + status = PRF_ERR_INVALID_PARAM; + } + break; + + default: + //Let app know that one of the request params is incorrect + status = PRF_ERR_INVALID_PARAM; + break; + } + + //Check if the handle value exists + if ((cfg_hdl == ATT_INVALID_HANDLE)) + { + status = PRF_ERR_INEXISTENT_HDL; + } + + // no error detected + if (status == GAP_ERR_NO_ERROR) + { + // Send GATT Write Request + prf_gatt_write_ntf_ind(&htpc_env->prf_env, conidx, cfg_hdl, param->cfg_val); + // store context of request and go into busy state + htpc_env->env[conidx]->operation = ke_param2msg(param); + ke_state_set(dest_id, HTPC_BUSY); + msg_status = KE_MSG_NO_FREE; + } + // an error occurs send back response message + else + { + struct htpc_health_temp_ntf_cfg_rsp* rsp = KE_MSG_ALLOC(HTPC_HEALTH_TEMP_NTF_CFG_RSP, + src_id, dest_id, + htpc_health_temp_ntf_cfg_rsp); + rsp->status = status; + ke_msg_send(rsp); + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HTPC_RD_REQ message. + * Check if the handle exists in profile(already discovered) and send request, otherwise + * error to APP. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int htpc_rd_char_req_handler(ke_msg_id_t const msgid, + struct htpc_rd_char_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Device Information Service Client Role Task Environment + struct htpc_env_tag *htpc_env = PRF_ENV_GET(HTPC, htpc); + + ASSERT_INFO(htpc_env != NULL, dest_id, src_id); + if((state == HTPC_IDLE) && (htpc_env->env[conidx] != NULL)) + { + uint16_t search_hdl = ATT_INVALID_HDL; + + switch (param->char_code) + { + ///Read HTS Temp. Type + case HTPC_RD_TEMP_TYPE: + { + search_hdl = htpc_env->env[conidx]->hts.chars[HTPC_CHAR_HTS_TEMP_TYPE].val_hdl; + }break; + ///Read HTS Measurement Interval + case HTPC_RD_MEAS_INTV: + { + search_hdl = htpc_env->env[conidx]->hts.chars[HTPC_CHAR_HTS_MEAS_INTV].val_hdl; + }break; + + ///Read HTS Temperature Measurement Client Cfg. Desc + case HTPC_RD_TEMP_MEAS_CLI_CFG: + { + search_hdl = htpc_env->env[conidx]->hts.descs[HTPC_DESC_HTS_TEMP_MEAS_CLI_CFG].desc_hdl; + }break; + ///Read HTS Intermediate Temperature Client Cfg. Desc + case HTPC_RD_INTM_TEMP_CLI_CFG: + { + search_hdl = htpc_env->env[conidx]->hts.descs[HTPC_DESC_HTS_INTM_MEAS_CLI_CFG].desc_hdl; + }break; + ///Read HTS Measurement Interval Client Cfg. Desc + case HTPC_RD_MEAS_INTV_CLI_CFG: + { + search_hdl = htpc_env->env[conidx]->hts.descs[HTPC_DESC_HTS_MEAS_INTV_CLI_CFG].desc_hdl; + }break; + ///Read HTS Measurement Interval Client Cfg. Desc + case HTPC_RD_MEAS_INTV_VAL_RGE: + { + search_hdl = htpc_env->env[conidx]->hts.descs[HTPC_DESC_HTS_MEAS_INTV_VAL_RGE].desc_hdl; + }break; + default: + { + status = GAP_ERR_INVALID_PARAM; + }break; + } + + //Check if handle is viable + if (search_hdl != ATT_INVALID_HDL) + { + // perform read request + //htpc_env->env[conidx]->last_char_code = param->char_code; + prf_read_char_send(&(htpc_env->prf_env), conidx, htpc_env->env[conidx]->hts.svc.shdl, + htpc_env->env[conidx]->hts.svc.ehdl, search_hdl); + + // store context of request and go into busy state + htpc_env->env[conidx]->operation = ke_param2msg(param); + msg_status = KE_MSG_NO_FREE; + ke_state_set(dest_id, HTPC_BUSY); + } + else if(status == GAP_ERR_NO_ERROR) + { + // invalid handle requested + status = PRF_ERR_INEXISTENT_HDL; + } + } + else if(state != HTPC_FREE) + { + // request cannot be performed + status = PRF_ERR_REQ_DISALLOWED; + } + + // send error response if request fails + if(status != GAP_ERR_NO_ERROR) + { + prf_client_att_info_rsp(&(htpc_env->prf_env), conidx, HTPC_RD_CHAR_RSP, + status, NULL); + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct htpc_env_tag *htpc_env = PRF_ENV_GET(HTPC, htpc); + uint8_t conidx = KE_IDX_GET(dest_id); + + // send attribute information + prf_client_att_info_rsp(&(htpc_env->prf_env), conidx, HTPC_RD_CHAR_RSP, GAP_ERR_NO_ERROR, param); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + + // Get the address of the environment + struct htpc_env_tag *htpc_env = PRF_ENV_GET(HTPC, htpc); + + if(state == HTPC_BUSY) + { + switch(htpc_env->env[conidx]->operation->id) + { + case HTPC_ENABLE_REQ: + { + uint8_t status; + if(htpc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(HTPC_CHAR_HTS_MAX, + htpc_env->env[conidx]->hts.chars, htpc_hts_char); + + htpc_env->env[conidx]->nb_svc =0; + } + // Too many services found only one such service should exist + else if(htpc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + htpc_enable_rsp_send(htpc_env, conidx, status); + }break; + + + case HTPC_HEALTH_TEMP_NTF_CFG_REQ: + { + // send response of the notification configuration request + struct htpc_health_temp_ntf_cfg_rsp * rsp = KE_MSG_ALLOC(HTPC_HEALTH_TEMP_NTF_CFG_RSP, + prf_dst_task_get(&(htpc_env->prf_env), conidx), dest_id, htpc_health_temp_ntf_cfg_rsp); + // set error status + rsp->status =param->status; + ke_msg_send(rsp); + }break; + + case HTPC_RD_CHAR_REQ: + { + if(param->status != GAP_ERR_NO_ERROR) + { + // send attribute information + prf_client_att_info_rsp(&(htpc_env->prf_env), conidx, HTPC_RD_CHAR_RSP, param->status, NULL); + } + }break; + + case HTPC_WR_MEAS_INTV_REQ: + { + struct htpc_wr_meas_intv_rsp *rsp = KE_MSG_ALLOC(HTPC_WR_MEAS_INTV_RSP, + prf_dst_task_get(&(htpc_env->prf_env), conidx), dest_id, htpc_wr_meas_intv_rsp); + rsp->status = param->status; + ke_msg_send(rsp); + }break; + + default: break; + } + + + //free operation + if((htpc_env->env[conidx] != NULL) && (htpc_env->env[conidx]->operation != NULL)) + { + ke_free(htpc_env->env[conidx]->operation); + htpc_env->env[conidx]->operation = NULL; + } + // set state to IDLE + ke_state_set(dest_id, HTPC_IDLE); + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct htpc_env_tag *htpc_env = PRF_ENV_GET(HTPC, htpc); + uint8_t conidx = KE_IDX_GET(dest_id); + + // Temperature Measurement Char. + if(param->handle == htpc_env->env[conidx]->hts.chars[HTPC_CHAR_HTS_TEMP_MEAS].val_hdl) + { + // confirm that indication has been correctly received + struct gattc_event_cfm * cfm = KE_MSG_ALLOC(GATTC_EVENT_CFM, src_id, dest_id, gattc_event_cfm); + cfm->handle = param->handle; + ke_msg_send(cfm); + + htpc_unpack_temp(htpc_env, (uint8_t *)&(param->value), param->length, + ((param->type == GATTC_NOTIFY) ? HTP_TEMP_INTERM : HTP_TEMP_STABLE), conidx); + } + // Intermediate Temperature Measurement Char. + else if(param->handle == htpc_env->env[conidx]->hts.chars[HTPC_CHAR_HTS_INTM_TEMP].val_hdl) + { + htpc_unpack_temp(htpc_env, (uint8_t *)&(param->value), param->length, + ((param->type == GATTC_NOTIFY) ? HTP_TEMP_INTERM : HTP_TEMP_STABLE), conidx); + } + // Measurement Interval Char. + else if (param->handle == htpc_env->env[conidx]->hts.chars[HTPC_CHAR_HTS_MEAS_INTV].val_hdl) + { + // confirm that indication has been correctly received + struct gattc_event_cfm * cfm = KE_MSG_ALLOC(GATTC_EVENT_CFM, src_id, dest_id, gattc_event_cfm); + cfm->handle = param->handle; + ke_msg_send(cfm); + + struct htpc_meas_intv_ind * ind = KE_MSG_ALLOC(HTPC_MEAS_INTV_IND, + prf_dst_task_get(&htpc_env->prf_env, conidx), + prf_src_task_get(&htpc_env->prf_env, conidx), + htpc_meas_intv_ind); + + memcpy(&ind->intv, ¶m->value[0], sizeof(uint16_t)); + + ke_msg_send(ind); + } + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/* Default State handlers definition. */ +KE_MSG_HANDLER_TAB(htpc) +{ + {HTPC_ENABLE_REQ, (ke_msg_func_t) htpc_enable_req_handler}, + {GATTC_SDP_SVC_IND, (ke_msg_func_t) gattc_sdp_svc_ind_handler}, + {HTPC_HEALTH_TEMP_NTF_CFG_REQ, (ke_msg_func_t) htpc_health_temp_ntf_cfg_req_handler}, + {HTPC_WR_MEAS_INTV_REQ, (ke_msg_func_t) htpc_wr_meas_intv_req_handler}, + {HTPC_RD_CHAR_REQ, (ke_msg_func_t) htpc_rd_char_req_handler}, + {GATTC_READ_IND, (ke_msg_func_t) gattc_read_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t) gattc_event_ind_handler}, + {GATTC_EVENT_REQ_IND, (ke_msg_func_t) gattc_event_ind_handler}, +}; + +void htpc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct htpc_env_tag *htpc_env = PRF_ENV_GET(HTPC, htpc); + + task_desc->msg_handler_tab = htpc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(htpc_msg_handler_tab); + task_desc->state = htpc_env->state; + task_desc->idx_max = HTPC_IDX_MAX; +} + +#endif //BLE_HT_COLLECTOR + +/// @} HTPCTASK diff --git a/services/ble_profiles/htp/htpt/api/htpt_task.h b/services/ble_profiles/htp/htpt/api/htpt_task.h new file mode 100644 index 0000000..5f7c516 --- /dev/null +++ b/services/ble_profiles/htp/htpt/api/htpt_task.h @@ -0,0 +1,187 @@ +#ifndef HTPT_TASK_H_ +#define HTPT_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup HTPTTASK Task + * @ingroup HTPT + * @brief Health Thermometer Profile Thermometer Task + * + * The HTPTTASK is responsible for handling the messages coming in and out of the + * @ref HTPT reporter block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_task.h" // Task definitions +#include "htp_common.h" +/* + * DEFINES + **************************************************************************************** + */ + +/// Messages for Health Thermometer Profile Thermometer +enum htpt_msg_id +{ + /// Start the Health Thermometer Profile Thermometer profile - at connection + HTPT_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_HTPT), + /// Enable confirmation + HTPT_ENABLE_RSP, + + /// Send temperature value from APP + HTPT_TEMP_SEND_REQ, + /// Send temperature response + HTPT_TEMP_SEND_RSP, + + /// Indicate Measurement Interval + HTPT_MEAS_INTV_UPD_REQ, + /// Send Measurement Interval response + HTPT_MEAS_INTV_UPD_RSP, + + /// Inform APP of new measurement interval value requested by a peer device + HTPT_MEAS_INTV_CHG_REQ_IND, + /// APP Confirm message of new measurement interval value requested by a peer device + /// If accepted, it triggers indication on measurement interval attribute + HTPT_MEAS_INTV_CHG_CFM, + + /// Inform APP that Indication Configuration has been changed - use to update bond data + HTPT_CFG_INDNTF_IND, +}; + + +/// Database Feature Configuration Flags +enum htpt_features +{ + /// Indicate if Temperature Type Char. is supported + HTPT_TEMP_TYPE_CHAR_SUP = 0x01, + /// Indicate if Intermediate Temperature Char. is supported + HTPT_INTERM_TEMP_CHAR_SUP = 0x02, + /// Indicate if Measurement Interval Char. is supported + HTPT_MEAS_INTV_CHAR_SUP = 0x04, + /// Indicate if Measurement Interval Char. supports indications + HTPT_MEAS_INTV_IND_SUP = 0x08, + /// Indicate if Measurement Interval Char. is writable + HTPT_MEAS_INTV_WR_SUP = 0x10, + + /// All Features supported + HTPT_ALL_FEAT_SUP = 0x1F, +}; + + +/// Notification and indication configuration +enum htpt_ntf_ind_cfg +{ + /// Stable measurement interval indication enabled + HTPT_CFG_STABLE_MEAS_IND = (1 << 0), + /// Intermediate measurement notification enabled + HTPT_CFG_INTERM_MEAS_NTF = (1 << 1), + /// Measurement interval indication + HTPT_CFG_MEAS_INTV_IND = (1 << 2), +}; + + +/* + * API MESSAGES STRUCTURES + **************************************************************************************** + */ +/// Parameters of the Health thermometer service database +struct htpt_db_cfg +{ + /// Health thermometer Feature (@see enum htpt_features) + uint8_t features; + /// Temperature Type Value + uint8_t temp_type; + + /// Measurement Interval Valid Range - Minimal Value + uint16_t valid_range_min; + /// Measurement Interval Valid Range - Maximal Value + uint16_t valid_range_max; + /// Measurement interval (latest known interval range) + uint16_t meas_intv; +}; + +/// Parameters of the @ref HTPT_ENABLE_REQ message +struct htpt_enable_req +{ + /// Connection index + uint8_t conidx; + /// Notification configuration (Bond Data to restore: @see enum htpt_ntf_ind_cfg) + uint8_t ntf_ind_cfg; +}; + +/// Parameters of the @ref HTPT_ENABLE_RSP message +struct htpt_enable_rsp +{ + /// Connection index + uint8_t conidx; + /// Status of enable request + uint8_t status; +}; + +/// Parameters of the @ref HTPT_TEMP_SEND_REQ message +struct htpt_temp_send_req +{ + /// Temperature Measurement + struct htp_temp_meas temp_meas; + /// Stable or intermediary type of temperature (True stable meas, else false) + bool stable_meas; +}; + +/// Parameters of the @ref HTPT_TEMP_SEND_RSP message +struct htpt_temp_send_rsp +{ + /// Status + uint8_t status; +}; + +/// Parameters of the @ref HTPT_MEAS_INTV_UPD_REQ message +struct htpt_meas_intv_upd_req +{ + /// Measurement Interval value + uint16_t meas_intv; +}; + +/// Parameters of the @ref HTPT_MEAS_INTV_UPD_RSP message +struct htpt_meas_intv_upd_rsp +{ + /// status + uint8_t status; +}; + + +/// Parameters of the @ref HTPT_MEAS_INTV_CHG_REQ_IND message +struct htpt_meas_intv_chg_req_ind +{ + /// Connection index + uint8_t conidx; + /// new measurement interval + uint16_t intv; +}; + +/// Parameters of the @ref HTPT_MEAS_INTV_CHG_CFM message +struct htpt_meas_intv_chg_cfm +{ + /// Connection index + uint8_t conidx; + /// status of the request + uint8_t status; +}; + +/// Parameters of the @ref HTPT_CFG_INDNTF_IND message +struct htpt_cfg_indntf_ind +{ + /// connection index + uint8_t conidx; + /// Notification Configuration (@see enum htpt_ntf_ind_cfg) + uint8_t ntf_ind_cfg; +}; + + +/// @} HTPTTASK +#endif // HTPT_TASK_H_ diff --git a/services/ble_profiles/htp/htpt/src/htpt.c b/services/ble_profiles/htp/htpt/src/htpt.c new file mode 100644 index 0000000..0861152 --- /dev/null +++ b/services/ble_profiles/htp/htpt/src/htpt.c @@ -0,0 +1,586 @@ +/** + **************************************************************************************** + * @addtogroup HTPT + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_HT_THERMOM) +#include "attm.h" +#include "htpt.h" +#include "htpt_task.h" +#include "co_utils.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * HTPT PROFILE ATTRIBUTES + **************************************************************************************** + */ +/// Full HTS Database Description - Used to add attributes into the database +const struct attm_desc htpt_att_db[HTS_IDX_NB] = +{ + // Health Thermometer Service Declaration + [HTS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // Temperature Measurement Characteristic Declaration + [HTS_IDX_TEMP_MEAS_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Temperature Measurement Characteristic Value + [HTS_IDX_TEMP_MEAS_VAL] = {ATT_CHAR_TEMPERATURE_MEAS, PERM(IND, ENABLE), PERM(RI, ENABLE), 0}, + // Temperature Measurement Characteristic - Client Characteristic Configuration Descriptor + [HTS_IDX_TEMP_MEAS_IND_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Temperature Type Characteristic Declaration + [HTS_IDX_TEMP_TYPE_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Temperature Type Characteristic Value + [HTS_IDX_TEMP_TYPE_VAL] = {ATT_CHAR_TEMPERATURE_TYPE, PERM(RD, ENABLE), PERM(RI, ENABLE), 0}, + + // Intermediate Measurement Characteristic Declaration + [HTS_IDX_INTERM_TEMP_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Intermediate Measurement Characteristic Value + [HTS_IDX_INTERM_TEMP_VAL] = {ATT_CHAR_INTERMED_TEMPERATURE, PERM(NTF, ENABLE), PERM(RI, ENABLE), 0}, + // Intermediate Measurement Characteristic - Client Characteristic Configuration Descriptor + [HTS_IDX_INTERM_TEMP_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Measurement Interval Characteristic Declaration + [HTS_IDX_MEAS_INTV_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Measurement Interval Characteristic Value + [HTS_IDX_MEAS_INTV_VAL] = {ATT_CHAR_MEAS_INTERVAL, PERM(RD, ENABLE), PERM(RI, ENABLE), HTPT_MEAS_INTV_MAX_LEN}, + // Measurement Interval Characteristic - Client Characteristic Configuration Descriptor + [HTS_IDX_MEAS_INTV_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, 0}, + // Measurement Interval Characteristic - Valid Range Descriptor + [HTS_IDX_MEAS_INTV_VAL_RANGE] = {ATT_DESC_VALID_RANGE, PERM(RD, ENABLE), PERM(RI, ENABLE), 0}, +}; + +static uint16_t htpt_compute_att_table(uint16_t features); + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +static uint8_t htpt_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, + uint8_t sec_lvl, struct htpt_db_cfg* params) +{ + // Service content flag + uint16_t cfg_flag; + // DB Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + BLE_PRF_HP_FUNC_ENTER(); + + cfg_flag = htpt_compute_att_table(params->features); + + status = attm_svc_create_db(start_hdl, ATT_SVC_HEALTH_THERMOM, (uint8_t *)&cfg_flag, + HTS_IDX_NB, NULL, env->task, &htpt_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, DISABLE) ); + + if( status == ATT_ERR_NO_ERROR ) + { + //-------------------- allocate memory required for the profile --------------------- + struct htpt_env_tag* htpt_env = + (struct htpt_env_tag* ) ke_malloc(sizeof(struct htpt_env_tag), KE_MEM_ATT_DB); + + // allocate PROXR required environment variable + env->env = (prf_env_t*) htpt_env; + + htpt_env->shdl = *start_hdl; + htpt_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + htpt_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + // initialize environment variable + env->id = TASK_ID_HTPT; + htpt_task_init(&(env->desc)); + + //Save features on the environment + htpt_env->features = params->features; + htpt_env->meas_intv = params->meas_intv; + htpt_env->meas_intv_min = params->valid_range_min; + htpt_env->meas_intv_max = params->valid_range_max; + htpt_env->temp_type = params->temp_type; + htpt_env->operation = NULL; + memset(htpt_env->ntf_ind_cfg, 0 , sizeof(htpt_env->ntf_ind_cfg)); + + // Update measurement interval permissions + if (HTPT_IS_FEATURE_SUPPORTED(params->features, HTPT_MEAS_INTV_CHAR_SUP)) + { + uint16_t perm = PERM(RD, ENABLE); + + //Check if Measurement Interval Char. supports indications + if (HTPT_IS_FEATURE_SUPPORTED(params->features, HTPT_MEAS_INTV_IND_SUP)) + { + perm |= PERM(IND, ENABLE); + } + + //Check if Measurement Interval Char. is writable + if (HTPT_IS_FEATURE_SUPPORTED(params->features, HTPT_MEAS_INTV_WR_SUP)) + { + perm |= PERM(WP, UNAUTH)|PERM(WRITE_REQ, ENABLE); + } + + attm_att_set_permission(HTPT_HANDLE(HTS_IDX_MEAS_INTV_VAL), perm, 0); + } + + // service is ready, go into an Idle state + ke_state_set(env->task, HTPT_IDLE); + } + + BLE_PRF_HP_FUNC_LEAVE(); + + return (status); +} + +static void htpt_destroy(struct prf_task_env* env) +{ + struct htpt_env_tag* htpt_env = (struct htpt_env_tag*) env->env; + + BLE_PRF_HP_FUNC_ENTER(); + + // free profile environment variables + if(htpt_env->operation != NULL) + { + ke_free(htpt_env->operation); + } + + env->env = NULL; + ke_free(htpt_env); + + BLE_PRF_HP_FUNC_LEAVE(); +} + +static void htpt_create(struct prf_task_env* env, uint8_t conidx) +{ + BLE_PRF_HP_FUNC_ENTER(); + + /* Clear configuration for this connection */ + struct htpt_env_tag* htpt_env = (struct htpt_env_tag*) env->env; + htpt_env->ntf_ind_cfg[conidx] = 0; + + BLE_PRF_HP_FUNC_LEAVE(); +} + +static void htpt_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + BLE_PRF_HP_FUNC_ENTER(); + + /* Clear configuration for this connection */ + struct htpt_env_tag* htpt_env = (struct htpt_env_tag*) env->env; + htpt_env->ntf_ind_cfg[conidx] = 0; + + BLE_PRF_HP_FUNC_LEAVE(); +} + +/** + **************************************************************************************** + * @brief Compute a flag allowing to know attributes to add into the database + * + * @return a 16-bit flag whose each bit matches an attribute. If the bit is set to 1, the + * attribute will be added into the database. + **************************************************************************************** + */ +static uint16_t htpt_compute_att_table(uint16_t features) +{ + BLE_PRF_HP_FUNC_ENTER(); + + //Temperature Measurement Characteristic is mandatory + uint16_t att_table = HTPT_TEMP_MEAS_MASK; + + //Check if Temperature Type Char. is supported + if (HTPT_IS_FEATURE_SUPPORTED(features, HTPT_TEMP_TYPE_CHAR_SUP)) + { + att_table |= HTPT_TEMP_TYPE_MASK; + } + + //Check if Intermediate Temperature Char. is supported + if (HTPT_IS_FEATURE_SUPPORTED(features, HTPT_INTERM_TEMP_CHAR_SUP)) + { + att_table |= HTPT_INTM_TEMP_MASK; + } + + //Check if Measurement Interval Char. is supported + if (HTPT_IS_FEATURE_SUPPORTED(features, HTPT_MEAS_INTV_CHAR_SUP)) + { + att_table |= HTPT_MEAS_INTV_MASK; + + //Check if Measurement Interval Char. supports indications + if (HTPT_IS_FEATURE_SUPPORTED(features, HTPT_MEAS_INTV_IND_SUP)) + { + att_table |= HTPT_MEAS_INTV_CCC_MASK; + } + + //Check if Measurement Interval Char. is writable + if (HTPT_IS_FEATURE_SUPPORTED(features, HTPT_MEAS_INTV_WR_SUP)) + { + att_table |= HTPT_MEAS_INTV_VALID_RGE_MASK; + } + } + + BLE_PRF_HP_FUNC_LEAVE(); + + return att_table; +} + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// HTPT Task interface required by profile manager +const struct prf_task_cbs htpt_itf = +{ + (prf_init_fnct) htpt_init, + htpt_destroy, + htpt_create, + htpt_cleanup, +}; + + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +uint8_t htpt_get_valid_rge_offset(uint16_t features) +{ + uint8_t offset = 0; + + if (HTPT_IS_FEATURE_SUPPORTED(features, HTPT_MEAS_INTV_WR_SUP)) + { + offset += 1; + + if (HTPT_IS_FEATURE_SUPPORTED(features, HTPT_MEAS_INTV_IND_SUP)) + { + offset += 1; + } + } + + return offset; +} + +uint8_t htpt_pack_temp_value(uint8_t *packed_temp, struct htp_temp_meas temp_meas) +{ + uint8_t cursor = 0; + + *(packed_temp + cursor) = temp_meas.flags; + cursor += 1; + + co_write32p(packed_temp + cursor, temp_meas.temp); + cursor += 4; + + //Time Flag Set + if ((temp_meas.flags & HTP_FLAG_TIME) == HTP_FLAG_TIME) + { + cursor += prf_pack_date_time(packed_temp + cursor, &(temp_meas.time_stamp)); + } + + //Type flag set + if ((temp_meas.flags & HTP_FLAG_TYPE) == HTP_FLAG_TYPE) + { + *(packed_temp + cursor) = temp_meas.type; + cursor += 1; + } + + //Clear unused packet data + if(cursor < HTPT_TEMP_MEAS_MAX_LEN) + { + memset(packed_temp + cursor, 0, (HTPT_TEMP_MEAS_MAX_LEN - cursor)); + } + + return cursor; +} + +void htpt_exe_operation(void) +{ + BLE_PRF_HP_FUNC_ENTER(); + + struct htpt_env_tag* htpt_env = PRF_ENV_GET(HTPT, htpt); + + ASSERT_ERR(htpt_env->operation != NULL); + + bool finished = true; + + while(htpt_env->operation->cursor < BLE_CONNECTION_MAX) + { + // check if this type of event is enabled + if(((htpt_env->ntf_ind_cfg[htpt_env->operation->cursor] & htpt_env->operation->op) != 0) + // and event not filtered on current connection + && (htpt_env->operation->conidx != htpt_env->operation->cursor)) + { + // trigger the event + struct gattc_send_evt_cmd * evt = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC , htpt_env->operation->cursor), prf_src_task_get(&htpt_env->prf_env, 0), + gattc_send_evt_cmd, htpt_env->operation->length); + + evt->operation = (htpt_env->operation->op != HTPT_CFG_INTERM_MEAS_NTF) ? GATTC_INDICATE : GATTC_NOTIFY; + evt->length = htpt_env->operation->length; + evt->handle = htpt_env->operation->handle; + memcpy(evt->value, htpt_env->operation->data, evt->length); + + ke_msg_send(evt); + + finished = false; + htpt_env->operation->cursor++; + break; + } + htpt_env->operation->cursor++; + } + + + // check if operation is finished + if(finished) + { + // do not send response if operation has been locally requested + if(htpt_env->operation->dest_id != prf_src_task_get(&htpt_env->prf_env, 0)) + { + // send response to requester + struct htpt_meas_intv_upd_rsp * rsp = + KE_MSG_ALLOC(((htpt_env->operation->op == HTPT_CFG_MEAS_INTV_IND) ? HTPT_MEAS_INTV_UPD_RSP : HTPT_TEMP_SEND_RSP), + htpt_env->operation->dest_id, prf_src_task_get(&htpt_env->prf_env, 0), + htpt_meas_intv_upd_rsp); + rsp->status = GAP_ERR_NO_ERROR; + ke_msg_send(rsp); + } + + // free operation + ke_free(htpt_env->operation); + htpt_env->operation = NULL; + // go back to idle state + ke_state_set(prf_src_task_get(&(htpt_env->prf_env), 0), HTPT_IDLE); + } + + BLE_PRF_HP_FUNC_LEAVE(); +} + + +uint8_t htpt_update_ntf_ind_cfg(uint8_t conidx, uint8_t cfg, uint16_t valid_val, uint16_t value) +{ + struct htpt_env_tag* htpt_env = PRF_ENV_GET(HTPT, htpt); + uint8_t status = GAP_ERR_NO_ERROR; + + BLE_PRF_HP_FUNC_ENTER(); + + if((value != valid_val) && (value != PRF_CLI_STOP_NTFIND)) + { + status = PRF_APP_ERROR; + + } + else if (value == valid_val) + { + htpt_env->ntf_ind_cfg[conidx] |= cfg; + } + else + { + htpt_env->ntf_ind_cfg[conidx] &= ~cfg; + } + + if(status == GAP_ERR_NO_ERROR) + { + // inform application that notification/indication configuration has changed + struct htpt_cfg_indntf_ind * ind = KE_MSG_ALLOC(HTPT_CFG_INDNTF_IND, + prf_dst_task_get(&htpt_env->prf_env, conidx), prf_src_task_get(&htpt_env->prf_env, conidx), + htpt_cfg_indntf_ind); + ind->conidx = conidx; + ind->ntf_ind_cfg = htpt_env->ntf_ind_cfg[conidx]; + ke_msg_send(ind); + } + + BLE_PRF_HP_FUNC_LEAVE(); + + return (status); +} + + +const struct prf_task_cbs* htpt_prf_itf_get(void) +{ + return &htpt_itf; +} + + +uint16_t htpt_att_hdl_get(struct htpt_env_tag* htpt_env, uint8_t att_idx) +{ + uint16_t handle = htpt_env->shdl; + + do + { + // Mandatory attribute handle + if(att_idx > HTS_IDX_TEMP_MEAS_IND_CFG) + { + handle += HTPT_TEMP_MEAS_ATT_NB; + } + else + { + handle += att_idx; + break; + } + + // Temperature Type + if((HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_TEMP_TYPE_CHAR_SUP)) && (att_idx > HTS_IDX_TEMP_TYPE_VAL)) + { + handle += HTPT_TEMP_TYPE_ATT_NB; + } + else if(!HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_TEMP_TYPE_CHAR_SUP)) + { + handle = ATT_INVALID_HANDLE; + break; + } + else + { + handle += att_idx - HTS_IDX_TEMP_TYPE_CHAR; + break; + } + + // Intermediate Temperature Measurement + if((HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_INTERM_TEMP_CHAR_SUP)) && (att_idx > HTS_IDX_INTERM_TEMP_CFG)) + { + handle += HTPT_INTERM_MEAS_ATT_NB; + } + else if(!HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_INTERM_TEMP_CHAR_SUP)) + { + handle = ATT_INVALID_HANDLE; + break; + } + else + { + handle += att_idx - HTS_IDX_INTERM_TEMP_CHAR; + break; + } + + // Measurement Interval + if(!HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_MEAS_INTV_CHAR_SUP) || (att_idx >= HTS_IDX_NB)) + { + handle = ATT_INVALID_HANDLE; + break; + } + + if(att_idx <= HTS_IDX_MEAS_INTV_VAL) + { + handle += att_idx - HTS_IDX_MEAS_INTV_CHAR; + break; + } + else + { + handle += HTPT_MEAS_INTV_ATT_NB; + } + + // Measurement Interval Indication + if(att_idx == HTS_IDX_MEAS_INTV_CFG) + { + if(!HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_MEAS_INTV_IND_SUP)) + { + handle = ATT_INVALID_HANDLE; + break; + } + } + // Measurement Interval Write permission + else if(HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_MEAS_INTV_WR_SUP)) + { + handle += HTPT_MEAS_INTV_CCC_ATT_NB; + + if(!HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_MEAS_INTV_WR_SUP)) + { + handle = ATT_INVALID_HANDLE; + break; + } + } + } while (0); + + return handle; +} + +uint8_t htpt_att_idx_get(struct htpt_env_tag* htpt_env, uint16_t handle) +{ + uint16_t handle_ref = htpt_env->shdl; + uint8_t att_idx = ATT_INVALID_IDX; + + do + { + // not valid hande + if(handle < handle_ref) + { + break; + } + + // Mandatory attribute handle + handle_ref += HTPT_TEMP_MEAS_ATT_NB; + + if(handle < handle_ref) + { + att_idx = HTS_IDX_TEMP_TYPE_CHAR - (handle_ref - handle); + break; + } + + // Temperature Type + if(HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_TEMP_TYPE_CHAR_SUP)) + { + handle_ref += HTPT_TEMP_TYPE_ATT_NB; + + if(handle < handle_ref) + { + att_idx = HTS_IDX_INTERM_TEMP_CHAR - (handle_ref - handle); + break; + } + } + + // Intermediate Temperature Measurement + if(HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_INTERM_TEMP_CHAR_SUP)) + { + handle_ref += HTPT_INTERM_MEAS_ATT_NB; + + if(handle < handle_ref) + { + att_idx = HTS_IDX_MEAS_INTV_CHAR - (handle_ref - handle); + break; + } + } + + // Measurement Interval + if(HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_MEAS_INTV_CHAR_SUP)) + { + handle_ref += HTPT_MEAS_INTV_ATT_NB; + + if(handle < handle_ref) + { + att_idx = HTS_IDX_MEAS_INTV_CFG - (handle_ref - handle); + break; + } + + if(HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_MEAS_INTV_IND_SUP)) + { + if(handle == handle_ref) + { + att_idx = HTS_IDX_MEAS_INTV_CFG; + break; + } + + handle_ref += HTPT_MEAS_INTV_CCC_ATT_NB; + } + + if(HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_MEAS_INTV_WR_SUP)) + { + if(handle == handle_ref) + { + att_idx = HTS_IDX_MEAS_INTV_VAL_RANGE; + break; + } + } + } + } while (0); + + return att_idx; +} + + + +#endif //BLE_HT_THERMOM + +/// @} HTPT diff --git a/services/ble_profiles/htp/htpt/src/htpt.h b/services/ble_profiles/htp/htpt/src/htpt.h new file mode 100644 index 0000000..22c58f8 --- /dev/null +++ b/services/ble_profiles/htp/htpt/src/htpt.h @@ -0,0 +1,290 @@ +#ifndef HTPT_H_ +#define HTPT_H_ + +/** + **************************************************************************************** + * @addtogroup HTPT Health Thermometer Profile Thermometer + * @ingroup HTP + * @brief Health Thermometer Profile Thermometer + * + * An actual thermometer device does not exist on current platform, so measurement values + * that would come from a driver are replaced by simple counters sent at certain intervals + * following by the profile attributes configuration. + * When a measurement interval + * has been set to a non-zero value in a configuration connection, once reconnected, + * TH will send regular measurement INDs if Temp Meas Char Cfg is set to indicate and + * using the Meas Intv Value. The INDs will continue until meas interval is set to 0 + * or connection gets disconnected by C. Measurements should be stored even so, until + * profile is disabled.(?) + * + * If the measurement interval has been set to 0, then if Intermediate Temp is set to be + * notified and Temp Meas to be indicated, then a timer of fixed length simulates + * sending several NTF before and indication of a "stable" value. This fake behavior + * should be replaced once a real driver exists. If Intermediary Temp cannot be notified, + * just send the indication, if neither can be sent (the configuration connection should + * never leave this like this) then disconnect. + * + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_HT_THERMOM) +#include +#include +#include "htp_common.h" +#include "prf_types.h" +#include "prf_utils.h" + +#include "gap.h" + +/* + * MACROS + **************************************************************************************** + */ +#define HTPT_IS_FEATURE_SUPPORTED(feat, bit_mask) (((feat & bit_mask) == bit_mask)) + +#define HTPT_HANDLE(idx) (htpt_att_hdl_get(htpt_env, (idx))) + +#define HTPT_IDX(hdl) (htpt_att_idx_get(htpt_env, (hdl))) + + +/* + * DEFINES + **************************************************************************************** + */ +///Maximum number of Health thermometer task instances +#define HTPT_IDX_MAX (1) + + +///Valid range for measurement interval values (s) +#define HTPT_MEAS_INTV_DFLT_MIN (0x0001) +#define HTPT_MEAS_INTV_DFLT_MAX (0x000A) + +#define HTPT_TEMP_MEAS_MAX_LEN (13) +#define HTPT_TEMP_TYPE_MAX_LEN (1) +#define HTPT_MEAS_INTV_MAX_LEN (2) +#define HTPT_MEAS_INTV_RANGE_MAX_LEN (4) +#define HTPT_IND_NTF_CFG_MAX_LEN (2) + +#define HTPT_TEMP_MEAS_MASK (0x000F) +#define HTPT_TEMP_TYPE_MASK (0x0030) +#define HTPT_INTM_TEMP_MASK (0x01C0) +#define HTPT_MEAS_INTV_MASK (0x0600) +#define HTPT_MEAS_INTV_CCC_MASK (0x0800) +#define HTPT_MEAS_INTV_VALID_RGE_MASK (0x1000) + +#define HTPT_TEMP_MEAS_ATT_NB (4) +#define HTPT_TEMP_TYPE_ATT_NB (2) +#define HTPT_INTERM_MEAS_ATT_NB (3) +#define HTPT_MEAS_INTV_ATT_NB (2) +#define HTPT_MEAS_INTV_CCC_ATT_NB (1) +#define HTPT_MEAS_INTV_RNG_ATT_NB (1) + + +/// Possible states of the HTPT task +enum htpt_state +{ + /// Idle state + HTPT_IDLE, + /// Busy state + HTPT_BUSY, + + /// Number of defined states. + HTPT_STATE_MAX +}; + +///Attributes database elements +enum hts_att_db_list +{ + HTS_IDX_SVC, + + HTS_IDX_TEMP_MEAS_CHAR, + HTS_IDX_TEMP_MEAS_VAL, + HTS_IDX_TEMP_MEAS_IND_CFG, + + HTS_IDX_TEMP_TYPE_CHAR, + HTS_IDX_TEMP_TYPE_VAL, + + HTS_IDX_INTERM_TEMP_CHAR, + HTS_IDX_INTERM_TEMP_VAL, + HTS_IDX_INTERM_TEMP_CFG, + + HTS_IDX_MEAS_INTV_CHAR, + HTS_IDX_MEAS_INTV_VAL, + HTS_IDX_MEAS_INTV_CFG, + HTS_IDX_MEAS_INTV_VAL_RANGE, + + HTS_IDX_NB, +}; + + +/// ongoing operation information +struct htpt_op +{ + /// Operation + uint8_t op; + /// Cursor on connection + uint8_t cursor; + /// Handle of the attribute to indicate/notify + uint16_t handle; + /// Task that request the operation that should receive completed message response + uint16_t dest_id; + /// Packed notification/indication data size + uint8_t length; + /// used to know on which device interval update has been requested, and to prevent + /// indication to be triggered on this connection index + uint8_t conidx; + /// Packed notification/indication data + uint8_t data[__ARRAY_EMPTY]; +}; + + +///Health Thermometer Profile Thermometer Environment Variable +struct htpt_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// On-going operation + struct htpt_op * operation; + /// Service Start Handle + uint16_t shdl; + /// Database configuration + uint16_t features; + + /// Current Measure interval + uint16_t meas_intv; + /// measurement interval range min + uint16_t meas_intv_min; + /// measurement interval range max + uint16_t meas_intv_max; + /// Temperature Type Value + uint8_t temp_type; + + /// Notification and indication configuration of peer devices. + uint8_t ntf_ind_cfg[BLE_CONNECTION_MAX]; + /// State of different task instances + ke_state_t state[HTPT_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Compute the offset of the valid range descriptor. + * The Measurement Interval characteristic has two optional descriptors. In the database, + * the Client Characteristic Configuration descriptor will always be placed just after the + * characteristic value. Thus, this function checks if the CCC descriptor has been added. + * @return 0 if Measurement Interval Char. is not writable (no Valid Range descriptor) + * 1 if Measurement Interval Char. doesn't support indications (no CCC descriptor) + * 2 otherwise + **************************************************************************************** + */ +uint8_t htpt_get_valid_rge_offset(uint16_t features); + +/** + **************************************************************************************** + * @brief Retrieve HTS service profile interface + * + * @return HTS service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* htpt_prf_itf_get(void); + + +/** + **************************************************************************************** + * @brief Pack temperature value from several components + * + * @return size of packed value + **************************************************************************************** + */ +uint8_t htpt_pack_temp_value(uint8_t *packed_temp, struct htp_temp_meas temp_meas); + + +/** + **************************************************************************************** + * @brief This function fully manage notification and indication of health thermometer + * to peer(s) device(s) according to on-going operation requested by application: + * - Modification of Intermediate Temperature + * - Indicate to a known device that Temperature Measured has change + * - Indicate to a known device that Measure Interval has change + **************************************************************************************** + */ +void htpt_exe_operation(void); + + + +/** + **************************************************************************************** + * @brief Update Notification, Indication configuration + * + * @param[in] conidx Connection index + * @param[in] cfg Indication configuration flag + * @param[in] valid_val Valid value if NTF/IND enable + * @param[in] value Value set by peer device. + * + * @return status of configuration update + **************************************************************************************** + */ +uint8_t htpt_update_ntf_ind_cfg(uint8_t conidx, uint8_t cfg, uint16_t valid_val, uint16_t value); + + +/** + **************************************************************************************** + * @brief Retrieve attribute handle from attribute index + * + * @param[in] htpt_env Environment variable + * @param[in] att_idx Attribute Index + * + * @return attribute Handle + **************************************************************************************** + */ +uint16_t htpt_att_hdl_get(struct htpt_env_tag* htpt_env, uint8_t att_idx); + +/** + **************************************************************************************** + * @brief Retrieve attribute index from attribute handle + * + * @param[in] htpt_env Environment variable + * @param[in] handle Attribute Handle + * + * @return attribute Index + **************************************************************************************** + */ +uint8_t htpt_att_idx_get(struct htpt_env_tag* htpt_env, uint16_t handle); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void htpt_task_init(struct ke_task_desc *task_desc); + + + +#endif //BLE_HT_THERMOM + +/// @} HTPT + +#endif // HTPT_H_ diff --git a/services/ble_profiles/htp/htpt/src/htpt_task.c b/services/ble_profiles/htp/htpt/src/htpt_task.c new file mode 100644 index 0000000..8c7f5a9 --- /dev/null +++ b/services/ble_profiles/htp/htpt/src/htpt_task.c @@ -0,0 +1,589 @@ +/** + **************************************************************************************** + * @addtogroup HTPTTASK + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_HT_THERMOM) + +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "htpt.h" +#include "htpt_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HTPT_ENABLE_REQ message. + * The handler enables the Health Thermometer Profile Thermometer Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int htpt_enable_req_handler(ke_msg_id_t const msgid, + struct htpt_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + // check state of the task + if(gapc_get_conhdl(param->conidx) != GAP_INVALID_CONHDL) + { + // restore Bond Data + struct htpt_env_tag* htpt_env = PRF_ENV_GET(HTPT, htpt); + htpt_env->ntf_ind_cfg[param->conidx] = param->ntf_ind_cfg; + status = GAP_ERR_NO_ERROR; + + } + + // send response + struct htpt_enable_rsp *rsp = KE_MSG_ALLOC(HTPT_ENABLE_RSP, src_id, dest_id, htpt_enable_rsp); + rsp->conidx = param->conidx; + rsp->status = status; + ke_msg_send(rsp); + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HTPT_TEMP_SEND_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int htpt_temp_send_req_handler(ke_msg_id_t const msgid, + struct htpt_temp_send_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + int msg_status = KE_MSG_SAVED; + uint8_t state = ke_state_get(dest_id); + + // check state of the task + if(state == HTPT_IDLE) + { + // Get the address of the environment + struct htpt_env_tag *htpt_env = PRF_ENV_GET(HTPT, htpt); + + // for intermediate measurement, feature must be enabled + if(!(param->stable_meas) && (!HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_INTERM_TEMP_CHAR_SUP))) + { + struct htpt_temp_send_rsp *rsp = KE_MSG_ALLOC(HTPT_TEMP_SEND_RSP, src_id, dest_id, htpt_temp_send_rsp); + rsp->status = PRF_ERR_FEATURE_NOT_SUPPORTED; + ke_msg_send(rsp); + } + else + { + // allocate operation to execute + htpt_env->operation = (struct htpt_op *) ke_malloc(sizeof(struct htpt_op) + HTPT_TEMP_MEAS_MAX_LEN, KE_MEM_ATT_DB); + + // Initialize operation parameters + htpt_env->operation->cursor = 0; + htpt_env->operation->dest_id = src_id; + htpt_env->operation->conidx = GAP_INVALID_CONIDX; + + // Stable measurement indication or intermediate measurement notification + if(param->stable_meas) + { + htpt_env->operation->op = HTPT_CFG_STABLE_MEAS_IND; + htpt_env->operation->handle = HTPT_HANDLE(HTS_IDX_TEMP_MEAS_VAL); + } + else + { + htpt_env->operation->op = HTPT_CFG_INTERM_MEAS_NTF; + htpt_env->operation->handle = HTPT_HANDLE(HTS_IDX_INTERM_TEMP_VAL); + } + + //Pack the temperature measurement value + htpt_env->operation->length = htpt_pack_temp_value(&(htpt_env->operation->data[0]), param->temp_meas); + + // put task in a busy state + ke_state_set(dest_id, HTPT_BUSY); + + // execute operation + htpt_exe_operation(); + } + + msg_status = KE_MSG_CONSUMED; + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Request to update Measurement Interval Value + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int htpt_meas_intv_upd_req_handler(ke_msg_id_t const msgid, + struct htpt_meas_intv_upd_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_SAVED; + uint8_t state = ke_state_get(dest_id); + + // check state of the task + if(state == HTPT_IDLE) + { + // Get the address of the environment + struct htpt_env_tag *htpt_env = PRF_ENV_GET(HTPT, htpt); + + // update measurement interval + htpt_env->meas_intv = param->meas_intv; + + //Check if Measurement Interval indication is supported + if(!HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_MEAS_INTV_CHAR_SUP)) + { + struct htpt_meas_intv_upd_rsp *rsp = KE_MSG_ALLOC(HTPT_MEAS_INTV_UPD_RSP, src_id, dest_id, htpt_meas_intv_upd_rsp); + rsp->status = PRF_ERR_FEATURE_NOT_SUPPORTED; + ke_msg_send(rsp); + } + else + { + // update internal measurement interval value + htpt_env->meas_intv = param->meas_intv; + + // no indication to trigger + if(!HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_MEAS_INTV_IND_SUP)) + { + struct htpt_meas_intv_upd_rsp *rsp = KE_MSG_ALLOC(HTPT_MEAS_INTV_UPD_RSP, src_id, dest_id, htpt_meas_intv_upd_rsp); + rsp->status = GAP_ERR_NO_ERROR; + ke_msg_send(rsp); + } + // trigger measurement update indication + else + { + // allocate operation to execute + htpt_env->operation = (struct htpt_op *) ke_malloc(sizeof(struct htpt_op) + HTPT_MEAS_INTV_MAX_LEN, KE_MEM_ATT_DB); + + // Initialize operation parameters + htpt_env->operation->op = HTPT_CFG_MEAS_INTV_IND; + htpt_env->operation->handle = HTPT_HANDLE(HTS_IDX_MEAS_INTV_VAL); + htpt_env->operation->dest_id = src_id; + htpt_env->operation->cursor = 0; + htpt_env->operation->conidx = GAP_INVALID_CONIDX; + + // Pack the interval value + htpt_env->operation->length = HTPT_MEAS_INTV_MAX_LEN; + co_write16p(htpt_env->operation->data, param->meas_intv); + + // put task in a busy state + ke_state_set(dest_id, HTPT_BUSY); + + // execute operation + htpt_exe_operation(); + } + } + + msg_status = KE_MSG_CONSUMED; + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + struct htpt_env_tag* htpt_env = PRF_ENV_GET(HTPT, htpt); + uint8_t att_idx = HTPT_IDX(param->handle); + struct gattc_att_info_cfm * cfm; + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + switch(att_idx) + { + case HTS_IDX_MEAS_INTV_VAL: + { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + }break; + + case HTS_IDX_TEMP_MEAS_IND_CFG: + case HTS_IDX_INTERM_TEMP_CFG: + case HTS_IDX_MEAS_INTV_CFG: + { + cfm->length = HTPT_IND_NTF_CFG_MAX_LEN; + cfm->status = GAP_ERR_NO_ERROR; + }break; + + default: + { + cfm->status = ATT_ERR_REQUEST_NOT_SUPPORTED; + }break; + } + + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. + * The handler compares the new values with current ones and notifies them if they changed. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + struct htpt_env_tag* htpt_env = PRF_ENV_GET(HTPT, htpt); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t status = ATT_ERR_NO_ERROR; + int msg_status = KE_MSG_CONSUMED; + + // to check if confirmation message should be send + bool send_cfm = true; + + // retrieve handle information + uint8_t att_idx = HTPT_IDX(param->handle); + + if(param->length != HTPT_MEAS_INTV_MAX_LEN) + { + status = PRF_ERR_UNEXPECTED_LEN; + } + else + { + switch(att_idx) + { + case HTS_IDX_MEAS_INTV_VAL: + { + uint16_t meas_intv = co_read16p(param->value); + + // check measurement length validity + if(((meas_intv >= htpt_env->meas_intv_min) && (meas_intv <= htpt_env->meas_intv_max)) + // notification can be disabled anyway + || (meas_intv == 0)) + { + uint8_t state = ke_state_get(dest_id); + send_cfm = false; + + // check state of the task to know if it can be proceed immediately + if(state == HTPT_IDLE) + { + // inform application that update of measurement interval is requested by peer device. + struct htpt_meas_intv_chg_req_ind * req_ind = KE_MSG_ALLOC(HTPT_MEAS_INTV_CHG_REQ_IND, + prf_dst_task_get(&htpt_env->prf_env, conidx), dest_id, htpt_meas_intv_chg_req_ind); + req_ind->conidx = conidx; + req_ind->intv = meas_intv; + ke_msg_send(req_ind); + + // allocate operation to execute + htpt_env->operation = (struct htpt_op *) ke_malloc(sizeof(struct htpt_op) + HTPT_MEAS_INTV_MAX_LEN, KE_MEM_ATT_DB); + + // Initialize operation parameters + htpt_env->operation->op = HTPT_CFG_MEAS_INTV_IND; + htpt_env->operation->handle = HTPT_HANDLE(HTS_IDX_MEAS_INTV_VAL); + htpt_env->operation->dest_id = dest_id; + htpt_env->operation->conidx = conidx; + // to be sure that no notification will be triggered + htpt_env->operation->cursor = 0xFF; + + // Pack the interval value + htpt_env->operation->length = HTPT_MEAS_INTV_MAX_LEN; + co_write16p(htpt_env->operation->data, meas_intv); + + // put task in a busy state + ke_state_set(dest_id, HTPT_BUSY); + } + else + { + msg_status = KE_MSG_SAVED; + } + } + else + { + // value not in expected range + status = HTP_OUT_OF_RANGE_ERR_CODE; + } + }break; + + case HTS_IDX_TEMP_MEAS_IND_CFG: + { + status = htpt_update_ntf_ind_cfg(conidx, HTPT_CFG_STABLE_MEAS_IND, PRF_CLI_START_IND, co_read16p(param->value)); + }break; + + case HTS_IDX_INTERM_TEMP_CFG: + { + status = htpt_update_ntf_ind_cfg(conidx, HTPT_CFG_INTERM_MEAS_NTF, PRF_CLI_START_NTF, co_read16p(param->value)); + }break; + + case HTS_IDX_MEAS_INTV_CFG: + { + status = htpt_update_ntf_ind_cfg(conidx, HTPT_CFG_MEAS_INTV_IND, PRF_CLI_START_IND, co_read16p(param->value)); + }break; + + default: + { + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + }break; + } + } + + if(send_cfm) + { + //Send write response + struct gattc_write_cfm * cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + } + + return (msg_status); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_REQ_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + struct htpt_env_tag* htpt_env = PRF_ENV_GET(HTPT, htpt); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t value[HTPT_MEAS_INTV_RANGE_MAX_LEN]; + uint8_t value_size = 0; + uint8_t status = ATT_ERR_NO_ERROR; + + // retrieve handle information + uint8_t att_idx = HTPT_IDX(param->handle); + + switch(att_idx) + { + case HTS_IDX_MEAS_INTV_VAL: + { + value_size = HTPT_MEAS_INTV_MAX_LEN; + co_write16p(&(value[0]), htpt_env->meas_intv); + }break; + + case HTS_IDX_MEAS_INTV_VAL_RANGE: + { + value_size = HTPT_MEAS_INTV_RANGE_MAX_LEN; + co_write16p(&(value[0]), htpt_env->meas_intv_min); + co_write16p(&(value[2]), htpt_env->meas_intv_max); + }break; + + case HTS_IDX_TEMP_MEAS_IND_CFG: + { + value_size = HTPT_IND_NTF_CFG_MAX_LEN; + co_write16p(value, ((htpt_env->ntf_ind_cfg[conidx] & HTPT_CFG_STABLE_MEAS_IND) != 0) ? PRF_CLI_START_IND : PRF_CLI_STOP_NTFIND); + }break; + + case HTS_IDX_INTERM_TEMP_CFG: + { + value_size = HTPT_IND_NTF_CFG_MAX_LEN; + co_write16p(value, ((htpt_env->ntf_ind_cfg[conidx] & HTPT_CFG_INTERM_MEAS_NTF) != 0) ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + }break; + + case HTS_IDX_MEAS_INTV_CFG: + { + value_size = HTPT_IND_NTF_CFG_MAX_LEN; + co_write16p(value, ((htpt_env->ntf_ind_cfg[conidx] & HTPT_CFG_MEAS_INTV_IND) != 0) ? PRF_CLI_START_IND : PRF_CLI_STOP_NTFIND); + }break; + + case HTS_IDX_TEMP_TYPE_VAL: + { + value_size = HTPT_TEMP_TYPE_MAX_LEN; + value[0] = htpt_env->temp_type; + }break; + + default: + { + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + }break; + } + + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, value_size); + cfm->length = value_size; + memcpy(cfm->value, value, value_size); + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref HTPT_MEAS_INTV_UPD_CFM message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int htpt_meas_intv_chg_cfm_handler(ke_msg_id_t const msgid, struct htpt_meas_intv_chg_cfm const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + struct htpt_env_tag* htpt_env = PRF_ENV_GET(HTPT, htpt); + + uint8_t state = ke_state_get(dest_id); + + // check state of the task + if(state == HTPT_BUSY) + { + // retrieve connection index from operation + uint8_t conidx = htpt_env->operation->conidx; + + //Send write response + struct gattc_write_cfm * cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, + KE_BUILD_ID(TASK_GATTC, conidx), dest_id, gattc_write_cfm); + cfm->handle = HTPT_HANDLE(HTS_IDX_MEAS_INTV_VAL); + cfm->status = (param->conidx == conidx) ? param->status : PRF_APP_ERROR; + ke_msg_send(cfm); + + + // check if no error occurs + if(cfm->status == GAP_ERR_NO_ERROR) + { + // update the current measurement interval + htpt_env->meas_intv = co_read16p(htpt_env->operation->data); + + // check if an indication of new measurement interval should be triggered + if(HTPT_IS_FEATURE_SUPPORTED(htpt_env->features, HTPT_MEAS_INTV_IND_SUP)) + { + // set back cursor to zero in order to send indication + htpt_env->operation->cursor = 0; + } + } + + // send indication or terminate operation + htpt_exe_operation(); + } + + return (KE_MSG_CONSUMED); +} + + + + +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY and GATT_INDICATE message meaning + * that Measurement notification/indication has been correctly sent to peer device + * + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + // continue operation execution + htpt_exe_operation(); + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(htpt) +{ + {HTPT_ENABLE_REQ, (ke_msg_func_t) htpt_enable_req_handler}, + + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, + + {HTPT_TEMP_SEND_REQ, (ke_msg_func_t) htpt_temp_send_req_handler}, + {HTPT_MEAS_INTV_UPD_REQ, (ke_msg_func_t) htpt_meas_intv_upd_req_handler}, + {HTPT_MEAS_INTV_CHG_CFM, (ke_msg_func_t) htpt_meas_intv_chg_cfm_handler}, +}; + +void htpt_task_init(struct ke_task_desc *task_desc) +{ + BLE_PRF_HP_FUNC_ENTER(); + + // Get the address of the environment + struct htpt_env_tag *htpt_env = PRF_ENV_GET(HTPT, htpt); + + task_desc->msg_handler_tab = htpt_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(htpt_msg_handler_tab); + task_desc->state = htpt_env->state; + task_desc->idx_max = HTPT_IDX_MAX; + + BLE_PRF_HP_FUNC_LEAVE(); +} + +#endif //BLE_HT_THERMOM + +/// @} HTPTTASK diff --git a/services/ble_profiles/lan/lan_common.h b/services/ble_profiles/lan/lan_common.h new file mode 100644 index 0000000..2d44c9d --- /dev/null +++ b/services/ble_profiles/lan/lan_common.h @@ -0,0 +1,399 @@ +#ifndef _LANP_COMMON_H_ +#define _LANP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup LANP Location and Navigation Profile + * @ingroup PROFILE + * @brief Location and Navigation Profile + * + * The Location and Navigation Profile is used to enable a collector device in order to obtain + * data from a Location and Navigation Sensor (LAN Sensor) that exposes the Location and Navigation Service. + * + * This file contains all definitions that are common for the server and the client parts + * of the profile. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "prf_types.h" +#include + +/* + * DEFINES + **************************************************************************************** + */ +/// Inappropriate Connection Parameters Error Code +#define LAN_ERROR_INAPP_CONNECT_PARAMS (0x80) +/// Procedure Already in Progress Error Code +#define LAN_ERROR_PROC_IN_PROGRESS (0x80) + + +#define LANP_LAN_LSPEED_MAX_PAIR_SIZE (8) + +/// LAN Location and Speed Value Max Length +#define LANP_LAN_LOC_SPEED_MAX_LEN (28) +/// LAN Location and Speed Value Min Length +#define LANP_LAN_LOC_SPEED_MIN_LEN (2) + +/// LAN Position Quality Value Max Length +#define LANP_LAN_POSQ_MAX_LEN (16) +/// LAN Position Quality Value Min Length +#define LANP_LAN_POSQ_MIN_LEN (2) + +/// LAN Control Point Value Request Max Length +#define LANP_LAN_LN_CNTL_PT_REQ_MAX_LEN (5) +/// LAN Control Point Value Request Min Length +#define LANP_LAN_LN_CNTL_PT_REQ_MIN_LEN (1) + +/// LAN Control Point data Max Length (from 2 to max route name) +#define LANP_LAN_LN_CNTL_DATA_MAX_LEN (128) +/// LAN Control Point Value Response Max Length +#define LANP_LAN_LN_CNTL_PT_RSP_MAX_LEN (3 + LANP_LAN_LN_CNTL_DATA_MAX_LEN) +/// LAN Control Point Value Response Min Length +#define LANP_LAN_LN_CNTL_PT_RSP_MIN_LEN (3) + +/// LAN Navigation Value Max Length +#define LANP_LAN_NAVIGATION_MAX_LEN (21) +/// LAN Navigation Value Min Length +#define LANP_LAN_NAVIGATION_MIN_LEN (6) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// LANP Service Characteristics +enum lanp_lans_char +{ + /// LN Feature + LANP_LANS_LN_FEAT_CHAR, + /// Location and speed + LANP_LANS_LOC_SPEED_CHAR, + /// Position quality + LANP_LANS_POS_Q_CHAR, + /// LN Control Point + LANP_LANS_LN_CTNL_PT_CHAR, + /// Navigation + LANP_LANS_NAVIG_CHAR, + + LANP_LANS_CHAR_MAX +}; + +/// LANP Feature Flags +enum lanp_feat_flags +{ + /// Instantaneous Speed Supported + LANP_FEAT_INSTANTANEOUS_SPEED_SUPP = 0x00000001, + /// Total Distance Supported + LANP_FEAT_TOTAL_DISTANCE_SUPP = 0x00000002, + /// Location Supported + LANP_FEAT_LOCATION_SUPP = 0x00000004, + /// Elevation Supported + LANP_FEAT_ELEVATION_SUPP = 0x00000008, + /// Heading Supported + LANP_FEAT_HEADING_SUPP = 0x00000010, + /// Rolling Time Supported + LANP_FEAT_ROLLING_TIME_SUPP = 0x00000020, + /// UTC Time Supported + LANP_FEAT_UTC_TIME_SUPP = 0x00000040, + /// Remaining Distance Supported + LANP_FEAT_REMAINING_DISTANCE_SUPP = 0x00000080, + /// Remaining Vertical Distance Supported + LANP_FEAT_REMAINING_VERTICAL_DISTANCE_SUPP = 0x00000100, + /// Estimated Time of Arrival Supported + LANP_FEAT_ESTIMATED_TIME_OF_ARRIVAL_SUPP = 0x00000200, + /// Number of Beacons in Solution Supported + LANP_FEAT_NUMBER_OF_BEACONS_IN_SOLUTION_SUPP = 0x00000400, + /// Number of Beacons in View Supported + LANP_FEAT_NUMBER_OF_BEACONS_IN_VIEW_SUPP = 0x00000800, + /// Time to First Fix Supported + LANP_FEAT_TIME_TO_FIRST_FIX_SUPP = 0x00001000, + /// Estimated Horizontal Position Error Supported + LANP_FEAT_ESTIMATED_HOR_POSITION_ERROR_SUPP = 0x00002000, + /// Estimated Vertical Position Error Supported + LANP_FEAT_ESTIMATED_VER_POSITION_ERROR_SUPP = 0x00004000, + /// Horizontal Dilution of Precision Supported + LANP_FEAT_HOR_DILUTION_OF_PRECISION_SUPP = 0x00008000, + /// Vertical Dilution of Precision Supported + LANP_FEAT_VER_DILUTION_OF_PRECISION_SUPP = 0x00010000, + /// Location and Speed Characteristic Content Masking Supported + LANP_FEAT_LSPEED_CHAR_CT_MASKING_SUPP = 0x00020000, + /// Fix Rate Setting Supported + LANP_FEAT_FIX_RATE_SETTING_SUPP = 0x00040000, + /// Elevation Setting Supported + LANP_FEAT_ELEVATION_SETTING_SUPP = 0x00080000, + /// Position Status Supported + LANP_FEAT_POSITION_STATUS_SUPP = 0x00100000, + + /// All Supported + LANP_FEAT_ALL_SUPP = 0x001FFFFF +}; + +/// LANP Location and speed Flags +enum lanp_lspeed_flags +{ + /// Instantaneous Speed Present + LANP_LSPEED_INST_SPEED_PRESENT = 0x0001, + /// Total Distance Present + LANP_LSPEED_TOTAL_DISTANCE_PRESENT = 0x0002, + /// Location Present + LANP_LSPEED_LOCATION_PRESENT = 0x0004, + /// Elevation Present + LANP_LSPEED_ELEVATION_PRESENT = 0x0008, + /// Heading Present + LANP_LSPEED_HEADING_PRESENT = 0x0010, + /// Rolling Time Present + LANP_LSPEED_ROLLING_TIME_PRESENT = 0x0020, + /// UTC Time Present + LANP_LSPEED_UTC_TIME_PRESENT = 0x0040, + /// Position Status LSB + LANP_LSPEED_POSITION_STATUS_LSB = 0x0080, + /// Position Status MSB + LANP_LSPEED_POSITION_STATUS_MSB = 0x0100, + /// Speed and Distance format + LANP_LSPEED_SPEED_AND_DISTANCE_FORMAT = 0x0200, + /// Elevation Source LSB + LANP_LSPEED_ELEVATION_SOURCE_LSB = 0x0400, + /// Elevation Source MSB + LANP_LSPEED_ELEVATION_SOURCE_MSB = 0x0800, + /// Heading Source + LANP_LSPEED_HEADING_SOURCE = 0x1000, + + /// All Present + LANP_LSPEED_ALL_PRESENT = 0x1FFF +}; + +/// LANP Position quality Flags +enum lanp_posq_flags +{ + /// Number of Beacons in Solution Present + LANP_POSQ_NUMBER_OF_BEACONS_IN_SOLUTION_PRESENT = 0x0001, + /// Number of Beacons in View Present + LANP_POSQ_NUMBER_OF_BEACONS_IN_VIEW_PRESENT = 0x0002, + /// Time to First Fix Present + LANP_POSQ_TIME_TO_FIRST_FIX_PRESENT = 0x0004, + /// EHPE Present + LANP_POSQ_EHPE_PRESENT = 0x0008, + /// EVPE Present + LANP_POSQ_EVPE_PRESENT = 0x0010, + /// HDOP Present + LANP_POSQ_HDOP_PRESENT = 0x0020, + /// VDOP Present + LANP_POSQ_VDOP_PRESENT = 0x0040, + /// Position Status LSB + LANP_POSQ_POSITION_STATUS_LSB = 0x0080, + /// Position Status MSB + LANP_POSQ_POSITION_STATUS_MSB = 0x0100, + + /// All Present + LANP_POSQ_ALL_PRESENT = 0x01FF +}; + +/// LANP Control Point Keys +enum lanp_ln_ctnl_pt_code +{ + /// Reserved value + LANP_LN_CTNL_PT_RESERVED = 0, + + /// Set Cumulative Value + LANP_LN_CTNL_PT_SET_CUMUL_VALUE, + /// Mask Location and Speed Characteristic Content + LANP_LN_CTNL_PT_MASK_LSPEED_CHAR_CT, + /// Navigation Control + LANP_LN_CTNL_PT_NAVIGATION_CONTROL, + /// Request Number of Routes + LANP_LN_CTNL_PT_REQ_NUMBER_OF_ROUTES, + /// Request Name of Route + LANP_LN_CTNL_PT_REQ_NAME_OF_ROUTE, + /// Select Route + LANP_LN_CTNL_PT_SELECT_ROUTE, + /// Set Fix Rate + LANP_LN_CTNL_PT_SET_FIX_RATE, + /// Set Elevation + LANP_LN_CTNL_PT_SET_ELEVATION, + /// Response Code + LANP_LN_CTNL_PT_RESPONSE_CODE = 32 +}; + +/// LANP Control Point Response Value +enum lanp_ctnl_pt_resp_val +{ + /// Reserved value + LANP_LN_CTNL_PT_RESP_RESERVED = 0, + + /// Success + LANP_LN_CTNL_PT_RESP_SUCCESS, + /// Operation Code Not Supported + LANP_LN_CTNL_PT_RESP_NOT_SUPP, + /// Invalid Parameter + LANP_LN_CTNL_PT_RESP_INV_PARAM, + /// Operation Failed + LANP_LN_CTNL_PT_RESP_FAILED, +}; + +/// LANP Navigation Control parameter +enum lanp_navi_control +{ + /// Stop Navigation + LANP_LN_CTNL_STOP_NAVI = 0x00, + /// Start Navigation + LANP_LN_CTNL_START_NAVI = 0x01, + /// Pause Navigation + LANP_LN_CTNL_PAUSE_NAVI = 0x02, + /// Resume Navigation + LANP_LN_CTNL_RESUME_NAVI = 0x03, + /// Skip waypoint on route + LANP_LN_CTNL_SKIP_WPT = 0x04, + /// Start Navigation from the nearest waypoint + LANP_LN_CTNL_START_NST_WPT = 0x05, +}; + +/// LANP Navigation flags +enum lanp_navi_flags +{ + /// Remaining Distance Present + LANP_NAVI_REMAINING_DIS_PRESENT = 0x0001, + /// Remaining Vertical Distance Present + LANP_NAVI_REMAINING_VER_DIS_PRESENT = 0x0002, + /// Estimated Time of Arrival Present + LANP_NAVI_ESTIMATED_TIME_OF_ARRIVAL_PRESENT = 0x0004, + /// Position Status lsb + LANP_NAVI_POSITION_STATUS_LSB = 0x0008, + /// Position Status msb + LANP_NAVI_POSITION_STATUS_MSB = 0x0010, + /// Heading Source + LANP_NAVI_HEADING_SOURCE = 0x0020, + /// Navigation Indicator Type + LANP_NAVI_NAVIGATION_INDICATOR_TYPE = 0x0040, + /// Waypoint Reached + LANP_NAVI_WAYPOINT_REACHED = 0x0080, + /// Destination Reached + LANP_NAVI_DESTINATION_REACHED = 0x0100, + /// ALl present + LANP_NAVI_ALL_PRESENT = 0x01FF + +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Location and Speed +struct lanp_loc_speed +{ + /// Flags + uint16_t flags; + /// Instantaneous Speed + uint16_t inst_speed; + /// Total distance + uint32_t total_dist; + /// Location - Latitude + int32_t latitude; + /// Location - Longitude + int32_t longitude; + /// Elevation + int32_t elevation; + /// Heading + uint16_t heading; + /// Rolling time + uint8_t rolling_time; + /// UTC Time + struct prf_date_time date_time; +}; + +/// LAN Position quality +struct lanp_posq +{ + /// Flags + uint16_t flags; + /// Time to First Fix + uint16_t time_first_fix; + /// EHPE + uint32_t ehpe; + /// EVPE + uint32_t evpe; + /// Number of Beacons in Solution + uint8_t n_beacons_solution; + /// Number of Beacons in view + uint8_t n_beacons_view; + /// HDOP + uint8_t hdop; + /// VDOP + uint8_t vdop; +}; + +/// LN Control Point Request +struct lan_ln_ctnl_pt_req +{ + /// Operation code + uint8_t op_code; + + /// Value + union lanp_ln_ctnl_pt_req_val + { + /// Cumulative Value (24 bits) + uint32_t cumul_val; + /// Mask Content + uint16_t mask_content; + /// Navigation Control + uint8_t control_value; + /// Route number + uint16_t route_number; + /// Fix rate + uint8_t fix_rate; + /// Elevation + int32_t elevation; + } value; +}; + +/// LAN Control Point Response +struct lanp_ln_ctnl_pt_rsp +{ + /// Operation code + uint8_t req_op_code; + /// Response Value + uint8_t resp_value; + + /// Value + union lanp_ctnl_pt_rsp_val + { + /// Number of routes + uint16_t number_of_routes; + + struct lanp_route_name + { + uint8_t length; + /// Name of Route UTF-8 + uint8_t name[__ARRAY_EMPTY]; + } route; + } value; +}; + +/// LAN Navigation +struct lanp_navigation +{ + /// Flags + uint16_t flags; + /// Bearing + uint16_t bearing; + /// Heading + uint16_t heading; + /// Remaining Distance (24 bits) + uint32_t remaining_distance; + /// Remaining Vertical Distance (24 bits) + uint32_t remaining_ver_distance; + /// Estimated Time of Arrival + struct prf_date_time estimated_arrival_time; +}; + + +/// @} lanp_common + +#endif //(_LANP_COMMON_H_) diff --git a/services/ble_profiles/lan/lanc/api/lanc_task.h b/services/ble_profiles/lan/lanc/api/lanc_task.h new file mode 100644 index 0000000..3b25448 --- /dev/null +++ b/services/ble_profiles/lan/lanc/api/lanc_task.h @@ -0,0 +1,211 @@ +#ifndef _LANC_TASK_H_ +#define _LANC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup LANCTASK Location and Navigation Profile Collector Task + * @ingroup LANC + * @brief Location and Navigation Profile Collector Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "lan_common.h" +#include "rwip_task.h" // Task definitions + + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Location and Navigation Service Characteristic Descriptors +enum lanc_lns_descs +{ + /// Location and Speed Char. - Client Characteristic Configuration + LANC_DESC_LOC_SPEED_CL_CFG, + /// LN Control Point Char. - Client Characteristic Configuration + LANC_DESC_LN_CTNL_PT_CL_CFG, + /// Navigation Char. - Client Characteristic Configuration + LANC_DESC_NAVIGATION_CL_CFG, + + LANC_DESC_MAX, + + LANC_DESC_MASK = 0x10, +}; + +/// Message IDs +enum lanc_msg_ids +{ + /// Enable the Location and Navigation Profile Collector task - at connection + LANC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_LANC), + /// Confirm that cfg connection has finished with discovery results, or that normal cnx started + LANC_ENABLE_RSP, + + /// Read the value of an attribute in the peer device database + LANC_READ_CMD, + /// Configure sending of notification or indication + LANC_CFG_NTFIND_CMD, + + /// Configure the SC Control Point value + LANC_LN_CTNL_PT_CFG_REQ, + /// Indicate that an control point response has been triggered by peer device + LANC_LN_CTNL_PT_RSP, + + /// Indicate that an attribute value has been received either upon notification or read response + LANC_VALUE_IND, + + /// Complete Event Information + LANC_CMP_EVT, + + /// Procedure Timeout Timer + LANC_TIMEOUT_TIMER_IND, +}; + +/// Operation Codes +enum lanc_op_code +{ + /// Reserved operation code + LANC_RESERVED_OP_CODE = 0x00, + + /// Discovery Procedure + LANC_ENABLE_OP_CODE, + /// Read attribute value Procedure + LANC_READ_OP_CODE, + + /// Wait for the Write Response after having written a Client Char. Cfg. Descriptor. + LANC_CFG_NTF_IND_OP_CODE, + + /// Wait for the Write Response after having written the Control Point Char. + LANC_LN_CTNL_PT_CFG_WR_OP_CODE, + /// Wait for the Indication Response after having written the Control Point Char. + LANC_LN_CTNL_PT_CFG_IND_OP_CODE, +}; + +/* + * API MESSAGE STRUCTURES + **************************************************************************************** + */ +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Location and Navigation Service + */ +struct lanc_lns_content +{ + /// Service info + struct prf_svc svc; + + /// Characteristic info: + /// - LN Feature + /// - Location and Speed + /// - Position quality + /// - LN Control Point + /// - Navigation + struct prf_char_inf chars[LANP_LANS_CHAR_MAX]; + + /// Descriptor handles: + /// - Location and Speed Client Cfg + /// - Control Point Client Cfg + /// - Navigation Client Cfg + struct prf_char_desc_inf descs[LANC_DESC_MAX]; +}; + +/// Parameters of the @ref LANC_ENABLE_REQ message +struct lanc_enable_req +{ + /// Connection type + uint8_t con_type; + /// Existing handle values LNS + struct lanc_lns_content lans; +}; + +/// Parameters of the @ref LANC_ENABLE_RSP message +struct lanc_enable_rsp +{ + /// status + uint8_t status; + /// Existing handle values LNS + struct lanc_lns_content lns; +}; + +/// Parameters of the @ref LANC_READ_CMD message +struct lanc_read_cmd +{ + /// Operation Code + uint8_t operation; + /// Read code + uint8_t read_code; +}; + +/// Parameters of the @ref LANC_VALUE_IND message +struct lanc_value_ind +{ + /// Attribute Code + uint8_t att_code; + /// Value + union lanc_value_tag + { + /// LN Feature + uint32_t LN_feat; + /// Location and Speed + struct lanp_loc_speed loc_speed; + /// LAN Position quality + struct lanp_posq pos_q; + /// Navigation + struct lanp_navigation navigation; + /// Client Characteristic Configuration Descriptor Value + uint16_t ntf_cfg; + } value; +}; + +/// Parameters of the @ref LANC_CFG_NTFIND_CMD message +struct lanc_cfg_ntfind_cmd +{ + /// Operation Code + uint8_t operation; + /// Descriptor code + uint8_t desc_code; + /// Ntf/Ind Configuration + uint16_t ntfind_cfg; +}; + +/// Parameters of the @ref LANC_LN_CTNL_PT_CFG_REQ message +struct lanc_ln_ctnl_pt_cfg_req +{ + /// Operation Code + uint8_t operation; + /// SC Control Point Request + struct lan_ln_ctnl_pt_req ln_ctnl_pt; +}; + +/// Parameters of the @ref LANC_LN_CTNL_PT_RSP message +struct lanc_ln_ctnl_pt_rsp +{ + /// SC Control Point Response + struct lanp_ln_ctnl_pt_rsp rsp; +}; + +/// Parameters of the @ref LANC_CMP_EVT message +struct lanc_cmp_evt +{ + /// Operation code + uint8_t operation; + /// Status + uint8_t status; +}; + + + +/// @} LANCTASK + +#endif //(_LANC_TASK_H_) diff --git a/services/ble_profiles/lan/lanc/src/lanc.c b/services/ble_profiles/lan/lanc/src/lanc.c new file mode 100644 index 0000000..ccbb4b4 --- /dev/null +++ b/services/ble_profiles/lan/lanc/src/lanc.c @@ -0,0 +1,686 @@ +/** + **************************************************************************************** + * @addtogroup LANC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_LN_COLLECTOR) +#include "lan_common.h" + +#include "lanc.h" +#include "lanc_task.h" + +#include "ke_timer.h" +#include "ke_mem.h" +#include "co_utils.h" + +/* + * GLOBAL VARIABLES DECLARATION + **************************************************************************************** + */ + + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the LANC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ + +static uint8_t lanc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct lanc_env_tag* lanc_env = + (struct lanc_env_tag* ) ke_malloc(sizeof(struct lanc_env_tag), KE_MEM_ATT_DB); + + // allocate LANC required environment variable + env->env = (prf_env_t*) lanc_env; + + lanc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + lanc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_LANC; + lanc_task_init(&(env->desc)); + + for(idx = 0; idx < LANC_IDX_MAX ; idx++) + { + lanc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), LANC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void lanc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct lanc_env_tag* lanc_env = (struct lanc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(lanc_env->env[conidx] != NULL) + { + if (lanc_env->env[conidx]->operation != NULL) + { + ke_free(ke_param2msg(lanc_env->env[conidx]->operation)); + } + ke_timer_clear(LANC_TIMEOUT_TIMER_IND, prf_src_task_get(&lanc_env->prf_env, conidx)); + + ke_free(lanc_env->env[conidx]); + lanc_env->env[conidx] = NULL; + } + + /* Put LAN Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), LANC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the LANC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void lanc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct lanc_env_tag* lanc_env = (struct lanc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < LANC_IDX_MAX ; idx++) + { + lanc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(lanc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void lanc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put LAN Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), LANC_IDLE); +} + + +/// LANC Task interface required by profile manager +const struct prf_task_cbs lanc_itf = +{ + lanc_init, + lanc_destroy, + lanc_create, + lanc_cleanup, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* lanc_prf_itf_get(void) +{ + return &lanc_itf; +} + +void lanc_enable_rsp_send(struct lanc_env_tag *lanc_env, uint8_t conidx, uint8_t status) +{ + // Send to APP the details of the discovered attributes on LANS + struct lanc_enable_rsp * rsp = KE_MSG_ALLOC( + LANC_ENABLE_RSP, + prf_dst_task_get(&(lanc_env->prf_env), conidx), + prf_src_task_get(&(lanc_env->prf_env), conidx), + lanc_enable_rsp); + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->lns = lanc_env->env[conidx]->lans; + // Register LANC task in gatt for indication/notifications + prf_register_atthdl2gatt(&(lanc_env->prf_env), conidx, &(lanc_env->env[conidx]->lans.svc)); + // Go to connected state + ke_state_set(prf_src_task_get(&(lanc_env->prf_env), conidx), LANC_IDLE); + } + + ke_msg_send(rsp); +} + +void lanc_send_no_conn_cmp_evt(uint8_t src_id, uint8_t dest_id, uint8_t operation) +{ + // Send the message + struct lanc_cmp_evt *evt = KE_MSG_ALLOC(LANC_CMP_EVT, + dest_id, src_id, + lanc_cmp_evt); + + evt->operation = operation; + evt->status = PRF_ERR_REQ_DISALLOWED; + + ke_msg_send(evt); +} + +void lanc_send_cmp_evt(struct lanc_env_tag *lanc_env, uint8_t conidx, uint8_t operation, uint8_t status) +{ + // Free the stored operation if needed + if (lanc_env->env[conidx]->operation != NULL) + { + ke_msg_free(ke_param2msg(lanc_env->env[conidx]->operation)); + lanc_env->env[conidx]->operation = NULL; + } + + // Go back to the CONNECTED state if the state is busy + if (ke_state_get(prf_src_task_get(&(lanc_env->prf_env), conidx)) == LANC_BUSY) + { + ke_state_set(prf_src_task_get(&(lanc_env->prf_env), conidx), LANC_IDLE); + } + + // Send the message + struct lanc_cmp_evt *evt = KE_MSG_ALLOC(LANC_CMP_EVT, + prf_dst_task_get(&(lanc_env->prf_env), conidx), + prf_src_task_get(&(lanc_env->prf_env), conidx), + lanc_cmp_evt); + + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + +uint16_t lanc_get_read_handle_req (struct lanc_env_tag *lanc_env, uint8_t conidx, struct lanc_read_cmd *param) +{ + // Attribute Handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + + switch (param->read_code) + { + // Read LN Feature + case (LANC_RD_LN_FEAT): + { + handle = lanc_env->env[conidx]->lans.chars[LANP_LANS_LN_FEAT_CHAR].val_hdl; + } break; + + // Read Position Quality + case (LANC_RD_POS_Q): + { + handle = lanc_env->env[conidx]->lans.chars[LANP_LANS_POS_Q_CHAR].val_hdl; + } break; + + // Read Location and Speed Characteristic Client Char. Cfg. Descriptor Value + case (LANC_RD_WR_LOC_SPEED_CL_CFG): + { + handle = lanc_env->env[conidx]->lans.descs[LANC_DESC_LOC_SPEED_CL_CFG].desc_hdl; + } break; + + // Read Unread Alert Characteristic Client Char. Cfg. Descriptor Value + case (LANC_RD_WR_LN_CTNL_PT_CFG): + { + handle = lanc_env->env[conidx]->lans.descs[LANC_DESC_LN_CTNL_PT_CL_CFG].desc_hdl; + } break; + + // Read Navigation Characteristic Server Char. Cfg. Descriptor Value + case (LANC_RD_WR_NAVIGATION_CFG): + { + handle = lanc_env->env[conidx]->lans.descs[LANC_DESC_NAVIGATION_CL_CFG].desc_hdl; + } break; + + + default: + { + handle = ATT_INVALID_SEARCH_HANDLE; + } break; + } + + return handle; +} + +uint8_t lanc_get_write_desc_handle_req (uint8_t conidx, struct lanc_cfg_ntfind_cmd *param, struct lanc_env_tag *lanc_env, uint16_t *handle) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + switch(param->desc_code) + { + // Write Location and speed Characteristic Client Char. Cfg. Descriptor Value + case (LANC_RD_WR_LOC_SPEED_CL_CFG): + { + if (param->ntfind_cfg <= PRF_CLI_START_NTF) + { + *handle = lanc_env->env[conidx]->lans.descs[LANC_DESC_LOC_SPEED_CL_CFG].desc_hdl; + + // The descriptor is mandatory + ASSERT_ERR(*handle != ATT_INVALID_SEARCH_HANDLE); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + // Write LN Control Point Characteristic Client Char. Cfg. Descriptor Value + case (LANC_RD_WR_LN_CTNL_PT_CFG): + { + if ((param->ntfind_cfg == PRF_CLI_STOP_NTFIND) || + (param->ntfind_cfg == PRF_CLI_START_IND)) + { + *handle = lanc_env->env[conidx]->lans.descs[LANC_DESC_LN_CTNL_PT_CL_CFG].desc_hdl; + + if (*handle == ATT_INVALID_SEARCH_HANDLE) + { + // The descriptor has not been found. + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + // Write Navigation Characteristic Client Char. Cfg. Descriptor Value + case (LANC_RD_WR_NAVIGATION_CFG): + { + if (param->ntfind_cfg <= PRF_CLI_START_NTF) + { + *handle = lanc_env->env[conidx]->lans.descs[LANC_DESC_NAVIGATION_CL_CFG].desc_hdl; + + if (*handle == ATT_INVALID_SEARCH_HANDLE) + { + // The descriptor has not been found. + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + + return (status); +} + +uint8_t lanc_unpack_loc_speed_ind (uint8_t conidx, struct gattc_event_ind const *param, struct lanc_env_tag *lanc_env) +{ + // Offset + uint8_t offset = LANP_LAN_LOC_SPEED_MIN_LEN; + + // LN Measurement value has been received + struct lanc_value_ind *ind = KE_MSG_ALLOC(LANC_VALUE_IND, + prf_dst_task_get(&(lanc_env->prf_env), conidx), + prf_src_task_get(&(lanc_env->prf_env), conidx), + lanc_value_ind); + + // Attribute code + ind->att_code = LANC_NTF_LOC_SPEED; + + if ((param->length >= LANP_LAN_LOC_SPEED_MIN_LEN) && + (param->length <= LANP_LAN_LOC_SPEED_MAX_LEN)) + { + // Flags + ind->value.loc_speed.flags = co_read16p(¶m->value[0]); + + if (ind->value.loc_speed.flags & LANP_LSPEED_INST_SPEED_PRESENT) + { + //Unpack instantaneous speed + ind->value.loc_speed.inst_speed = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (ind->value.loc_speed.flags & LANP_LSPEED_TOTAL_DISTANCE_PRESENT) + { + //Unpack Total distance (24 bits) + ind->value.loc_speed.total_dist = co_read24p(¶m->value[offset]); + offset += 3; + } + + if (ind->value.loc_speed.flags & LANP_LSPEED_LOCATION_PRESENT) + { + //Unpack Location + ind->value.loc_speed.latitude = co_read32p(¶m->value[offset]); + offset += 4; + ind->value.loc_speed.longitude = co_read32p(¶m->value[offset]); + offset += 4; + } + + if (ind->value.loc_speed.flags & LANP_LSPEED_ELEVATION_PRESENT) + { + // Unpack Elevation (24 bits) + ind->value.loc_speed.elevation = co_read24p(¶m->value[offset]); + offset += 3; + } + + if (ind->value.loc_speed.flags & LANP_LSPEED_HEADING_PRESENT) + { + // Unpack heading + ind->value.loc_speed.heading = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (ind->value.loc_speed.flags & LANP_LSPEED_ROLLING_TIME_PRESENT) + { + // Unpack rolling time + ind->value.loc_speed.rolling_time = param->value[offset]; + offset++; + } + + if (ind->value.loc_speed.flags & LANP_LSPEED_UTC_TIME_PRESENT) + { + //Unpack UTC time + offset += prf_unpack_date_time( + (uint8_t *) &(param->value[offset]), &(ind->value.loc_speed.date_time)); + } + } + + // Send the message + ke_msg_send(ind); + + return offset; +} + +uint8_t lanc_unpack_navigation_ind (uint8_t conidx, struct gattc_event_ind const *param, struct lanc_env_tag *lanc_env) +{ + // Offset + uint8_t offset = LANP_LAN_NAVIGATION_MIN_LEN; + + // LN Measurement value has been received + struct lanc_value_ind *ind = KE_MSG_ALLOC(LANC_VALUE_IND, + prf_dst_task_get(&(lanc_env->prf_env), conidx), + prf_src_task_get(&(lanc_env->prf_env), conidx), + lanc_value_ind); + + // Attribute code + ind->att_code = LANC_NTF_NAVIGATION; + + if ((param->length >= LANP_LAN_NAVIGATION_MIN_LEN) && + (param->length <= LANP_LAN_NAVIGATION_MAX_LEN)) + { + // Flags + ind->value.navigation.flags = co_read16p(¶m->value[0]); + // Bearing + ind->value.navigation.bearing = co_read16p(¶m->value[2]); + // Heading + ind->value.navigation.heading = co_read16p(¶m->value[4]); + + if (ind->value.navigation.flags & LANP_NAVI_REMAINING_DIS_PRESENT) + { + //Unpack remaining distance (24 bits) + ind->value.navigation.remaining_distance = co_read24p(¶m->value[offset]); + offset += 3; + } + + if (ind->value.navigation.flags & LANP_NAVI_REMAINING_VER_DIS_PRESENT) + { + //Unpack remaining vertical distance (24 bits) + ind->value.navigation.remaining_ver_distance = co_read24p(¶m->value[offset]); + offset += 3; + } + + if (ind->value.navigation.flags & LANP_NAVI_ESTIMATED_TIME_OF_ARRIVAL_PRESENT) + { + //Unpack time + offset += prf_unpack_date_time( + (uint8_t *) &(param->value[offset]), &(ind->value.navigation.estimated_arrival_time)); + } + } + + // Send the message + ke_msg_send(ind); + + return offset; +} + + +uint8_t lanc_unpack_pos_q_ind (struct gattc_read_ind const *param, struct lanc_value_ind *ind) +{ + /*---------------------------------------------------- + * Unpack Position Quality --------------------------- + *----------------------------------------------------*/ + // Offset + uint8_t offset = LANP_LAN_POSQ_MIN_LEN; + + // Flags + ind->value.pos_q.flags = co_read16p(¶m->value[0]); + + if (ind->value.pos_q.flags & LANP_POSQ_NUMBER_OF_BEACONS_IN_SOLUTION_PRESENT) + { + //Unpack beacons in solution + ind->value.pos_q.n_beacons_solution = param->value[offset]; + offset++; + } + + if (ind->value.pos_q.flags & LANP_POSQ_NUMBER_OF_BEACONS_IN_VIEW_PRESENT) + { + //Unpack beacons in view + ind->value.pos_q.n_beacons_view = param->value[offset]; + offset++; + } + + if (ind->value.pos_q.flags & LANP_POSQ_TIME_TO_FIRST_FIX_PRESENT) + { + //Unpack time first fix + ind->value.pos_q.time_first_fix = co_read16p(¶m->value[offset]); + offset += 2; + } + + if (ind->value.pos_q.flags & LANP_POSQ_EHPE_PRESENT) + { + //Unpack ehpe + ind->value.pos_q.ehpe = co_read32p(¶m->value[offset]); + offset += 4; + } + + if (ind->value.pos_q.flags & LANP_POSQ_EVPE_PRESENT) + { + //Unpack evpe + ind->value.pos_q.evpe = co_read32p(¶m->value[offset]); + offset += 4; + } + + if (ind->value.pos_q.flags & LANP_POSQ_HDOP_PRESENT) + { + //Unpack hdop + ind->value.pos_q.hdop = param->value[offset]; + offset++; + } + + if (ind->value.pos_q.flags & LANP_POSQ_VDOP_PRESENT) + { + //Unpack vdop + ind->value.pos_q.vdop = param->value[offset]; + offset++; + } + + return offset; +} + +uint8_t lanc_pack_ln_ctnl_pt_req (struct lanc_ln_ctnl_pt_cfg_req *param, uint8_t *req, uint8_t *status) +{ + // Request Length + uint8_t req_len = LANP_LAN_LN_CNTL_PT_REQ_MIN_LEN; + + // Set the operation code + req[0] = param->ln_ctnl_pt.op_code; + + // Fulfill the message according to the operation code + switch (param->ln_ctnl_pt.op_code) + { + case (LANP_LN_CTNL_PT_SET_CUMUL_VALUE): + { + // Set the cumulative value (24 bits) + co_write24p(&req[req_len], param->ln_ctnl_pt.value.cumul_val); + // Update length + req_len += 3; + } break; + + case (LANP_LN_CTNL_PT_MASK_LSPEED_CHAR_CT): + { + // Set mask content + co_write16p(&req[req_len], param->ln_ctnl_pt.value.mask_content); + // Update length + req_len += 2; + } break; + + case (LANP_LN_CTNL_PT_NAVIGATION_CONTROL): + { + // Set control value + req[req_len] = param->ln_ctnl_pt.value.control_value; + // Update length + req_len++; + } break; + + case (LANP_LN_CTNL_PT_REQ_NAME_OF_ROUTE): + case (LANP_LN_CTNL_PT_SELECT_ROUTE): + { + // Set route number + co_write16p(&req[req_len], param->ln_ctnl_pt.value.route_number); + // Update length + req_len += 2; + } break; + + case (LANP_LN_CTNL_PT_SET_FIX_RATE): + { + // Set the fix rate + req[req_len] = param->ln_ctnl_pt.value.fix_rate; + // Update length + req_len++; + } break; + + case (LANP_LN_CTNL_PT_SET_ELEVATION): + { + // Set elevation (24 bits) + co_write24p(&req[req_len], param->ln_ctnl_pt.value.elevation); + // Update length + req_len += 3; + } break; + + case (LANP_LN_CTNL_PT_REQ_NUMBER_OF_ROUTES): + { + // Nothing more to do + } break; + + default: + { + *status = PRF_ERR_INVALID_PARAM; + } break; + } + + return req_len; +} + +uint8_t lanc_unpack_ln_ctln_pt_ind (struct gattc_event_ind const *param, ke_task_id_t src, ke_task_id_t dest) +{ + // Offset + uint8_t offset = LANP_LAN_LN_CNTL_PT_RSP_MIN_LEN; + + // Control Point value has been received + struct lanc_ln_ctnl_pt_rsp *ind = KE_MSG_ALLOC_DYN(LANC_LN_CTNL_PT_RSP, + dest, + src, + lanc_ln_ctnl_pt_rsp, + param->length); + // Requested operation code + ind->rsp.req_op_code = param->value[1]; + // Response value + ind->rsp.resp_value = param->value[2]; + + + if ((ind->rsp.resp_value == LANP_LN_CTNL_PT_RESP_SUCCESS) && (param->length >= 3)) + { + switch (ind->rsp.req_op_code) + { + case (LANP_LN_CTNL_PT_REQ_NUMBER_OF_ROUTES): + { + ind->rsp.value.number_of_routes = co_read16p(¶m->value[offset]); + offset += 2; + + } break; + + case (LANP_LN_CTNL_PT_REQ_NAME_OF_ROUTE): + { + // Get the length of the route + ind->rsp.value.route.length = (param->length - 3); + for (int i = 0; irsp.value.route.length; i++) + { + ind->rsp.value.route.name[i] = param->value[i + 3]; + offset++; + } + } break; + + case (LANP_LN_CTNL_PT_SET_CUMUL_VALUE): + case (LANP_LN_CTNL_PT_MASK_LSPEED_CHAR_CT): + case (LANP_LN_CTNL_PT_NAVIGATION_CONTROL): + case (LANP_LN_CTNL_PT_SELECT_ROUTE): + case (LANP_LN_CTNL_PT_SET_FIX_RATE): + case (LANP_LN_CTNL_PT_SET_ELEVATION): + { + // No parameters + } break; + + default: + { + + } break; + } + } + + // Send the message + ke_msg_send(ind); + + return offset; +} +#endif //(BLE_LN_COLLECTOR) + +/// @} LAN diff --git a/services/ble_profiles/lan/lanc/src/lanc.h b/services/ble_profiles/lan/lanc/src/lanc.h new file mode 100644 index 0000000..f4fffaf --- /dev/null +++ b/services/ble_profiles/lan/lanc/src/lanc.h @@ -0,0 +1,267 @@ +#ifndef _LANC_H_ +#define _LANC_H_ + +/** + **************************************************************************************** + * @addtogroup LANC Location and Navigation Profile Collector + * @ingroup LAN + * @brief Location and Navigation Profile Collector + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" +#if (BLE_LN_COLLECTOR) + +#include "lan_common.h" +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" +#include "lanc_task.h" + + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of Location and Navigation Collector task instances +#define LANC_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * ENUMERATIONS + **************************************************************************************** + */ +/// Possible states of the LANC task +enum lanc_states +{ + /// Idle state + LANC_FREE, + /// Connected state + LANC_IDLE, + /// SDP state + LANC_DISCOVERING, + /// Busy state + LANC_BUSY, + + /// Number of defined states. + LANC_STATE_MAX +}; + + +/// Internal codes for reading/writing a LNS characteristic with one single request +enum lanc_code +{ + /// Read LN Feature + LANC_RD_LN_FEAT = LANP_LANS_LN_FEAT_CHAR, + /// Notified Location and Speed + LANC_NTF_LOC_SPEED = LANP_LANS_LOC_SPEED_CHAR, + /// Read Position quality + LANC_RD_POS_Q = LANP_LANS_POS_Q_CHAR, + /// Indicated LN Control Point + LANC_IND_LN_CTNL_PT = LANP_LANS_LN_CTNL_PT_CHAR, + /// Notified Navigation + LANC_NTF_NAVIGATION = LANP_LANS_NAVIG_CHAR, + + /// Read/Write Location and Speed Client Char. Configuration Descriptor + LANC_RD_WR_LOC_SPEED_CL_CFG = (LANC_DESC_LOC_SPEED_CL_CFG | LANC_DESC_MASK), + + /// Read LN Control Point Client Char. Configuration Descriptor + LANC_RD_WR_LN_CTNL_PT_CFG = (LANC_DESC_LN_CTNL_PT_CL_CFG | LANC_DESC_MASK), + + /// Read/Write Vector Client Char. Configuration Descriptor + LANC_RD_WR_NAVIGATION_CFG = (LANC_DESC_NAVIGATION_CL_CFG | LANC_DESC_MASK), + +}; + + +/* + * STRUCTURES + **************************************************************************************** + */ + +struct lanc_cnx_env +{ + ///Last requested UUID(to keep track of the two services and char) + uint16_t last_uuid_req; + /// Counter used to check service uniqueness + uint8_t nb_svc; + /// Location and Navigation Service Characteristics + struct lanc_lns_content lans; + /// Current Operation + void *operation; +}; + +/// Location and Navigation Profile Collector environment variable +struct lanc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct lanc_cnx_env* env[LANC_IDX_MAX]; + /// State of different task instances + ke_state_t state[LANC_IDX_MAX]; +}; + +/// Command Message Basic Structure +struct lanc_cmd +{ + /// Operation Code + uint8_t operation; + + /// MORE DATA +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/* + * GLOBAL FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve LAN client profile interface + * + * @return LAN client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* lanc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Location and Navigation ATT DB discovery results to LANC host. + * @param[in] lanc_env environment variable + * @param[in] conidx Connection index + * @param[in] status Status + * @return handle + **************************************************************************************** + */ +void lanc_enable_rsp_send(struct lanc_env_tag *lanc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Send a LANC_CMP_EVT message when no connection exists (no environment) + * @param[in] src_id Source task + * @param[in] dest_id Destination task + * @param[in] operation Operation + **************************************************************************************** + */ +void lanc_send_no_conn_cmp_evt(uint8_t src_id, uint8_t dest_id, uint8_t operation); + +/** + **************************************************************************************** + * @brief Send a LANC_CMP_EVT message to the task which enabled the profile + * @param[in] lanc_env environment variable + * @param[in] conidx Connection index + * @param[in] operation Operation + * @param[in] status Status + * @return handle + **************************************************************************************** + */ +void lanc_send_cmp_evt(struct lanc_env_tag *lanc_env, uint8_t conidx, uint8_t operation, uint8_t status); + +/** + **************************************************************************************** + * @brief Gets correct read handle according to the request + * @param[in] lanc_env environment variable + * @param[in] conidx Connection index + * @param[in] param Pointer to the parameters of the message. + * @return handle + **************************************************************************************** + */ +uint16_t lanc_get_read_handle_req (struct lanc_env_tag *lanc_env, uint8_t conidx, struct lanc_read_cmd *param); + +/** + **************************************************************************************** + * @brief Gets correct write handle according to the request + * @param[in] conidx Connection index + * @param[in] param Pointer to the parameters of the message. + * @param[in] lanc_env environment variable + * @param[out] handle handle + * @return handle + **************************************************************************************** + */ +uint8_t lanc_get_write_desc_handle_req (uint8_t conidx, struct lanc_cfg_ntfind_cmd *param, struct lanc_env_tag *lanc_env, uint16_t *handle); + +/** + **************************************************************************************** + * @brief Unpacks location and speed data and sends the indication + * @param[in] conidx Connection index + * @param[in] param Pointer to the parameters of the message. + * @param[in] lanc_env environment variable + * @return length + **************************************************************************************** + */ +uint8_t lanc_unpack_loc_speed_ind (uint8_t conidx, struct gattc_event_ind const *param, struct lanc_env_tag *lanc_env); + +/** + **************************************************************************************** + * @brief Unpacks Navigation and sends the indication + * @param[in] conidx Connection index + * @param[in] param Pointer to the parameters of the message. + * @param[in] lanc_env environment variable + * @return length + **************************************************************************************** + */ +uint8_t lanc_unpack_navigation_ind (uint8_t conidx, struct gattc_event_ind const *param, struct lanc_env_tag *lanc_env); + +/** + **************************************************************************************** + * @brief Unpacks position quality + * @param[in] param Pointer to the parameters of the message + * @param[out] ind Pointer to the value indication + * @return length + **************************************************************************************** + */ +uint8_t lanc_unpack_pos_q_ind (struct gattc_read_ind const *param, struct lanc_value_ind *ind); + +/** + **************************************************************************************** + * @brief Packs Control Point data + * @param[in] param Pointer to the parameters of the message. + * @param[out] req packed message + * @param[out] status status of the operation + * @return length + **************************************************************************************** + */ +uint8_t lanc_pack_ln_ctnl_pt_req (struct lanc_ln_ctnl_pt_cfg_req *param, uint8_t *req, uint8_t *status); + +/** + **************************************************************************************** + * @brief Unpacks Control Point data and sends the indication + * @param[in] param Pointer to the parameters of the message. + * @param[in] src Source task + * @param[in] dest Destination task + * @return length + **************************************************************************************** + */ +uint8_t lanc_unpack_ln_ctln_pt_ind (struct gattc_event_ind const *param, ke_task_id_t src, ke_task_id_t dest); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void lanc_task_init(struct ke_task_desc *task_desc); +#endif //(BLE_LN_COLLECTOR) + +/// @} LANC + +#endif //(_LANC_H_) diff --git a/services/ble_profiles/lan/lanc/src/lanc_task.c b/services/ble_profiles/lan/lanc/src/lanc_task.c new file mode 100644 index 0000000..9888515 --- /dev/null +++ b/services/ble_profiles/lan/lanc/src/lanc_task.c @@ -0,0 +1,784 @@ +/** + **************************************************************************************** + * @addtogroup LANCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_LN_COLLECTOR) +#include "lan_common.h" + +#include "gap.h" +#include "attm.h" +#include "lanc_task.h" +#include "lanc.h" +#include "gattc_task.h" +#include "ke_timer.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// State machine used to retrieve Location and Navigation service characteristics information +const struct prf_char_def lanc_lns_char[LANP_LANS_CHAR_MAX] = +{ + /// LN Feature + [LANP_LANS_LN_FEAT_CHAR] = {ATT_CHAR_LN_FEAT, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, + /// LN Measurement + [LANP_LANS_LOC_SPEED_CHAR] = {ATT_CHAR_LOC_SPEED, + ATT_MANDATORY, + ATT_CHAR_PROP_NTF}, + /// Position Quality + [LANP_LANS_POS_Q_CHAR] = {ATT_CHAR_POS_QUALITY, + ATT_OPTIONAL, + ATT_CHAR_PROP_RD}, + /// SC Control Point + [LANP_LANS_LN_CTNL_PT_CHAR] = {ATT_CHAR_LN_CNTL_PT, + ATT_OPTIONAL, + ATT_CHAR_PROP_WR | ATT_CHAR_PROP_IND}, + /// Navigation + [LANP_LANS_NAVIG_CHAR] = {ATT_CHAR_NAVIGATION, + ATT_OPTIONAL, + ATT_CHAR_PROP_NTF}, +}; + +/// State machine used to retrieve Location and Navigation service characteristic descriptor information +const struct prf_char_desc_def lanc_lns_char_desc[LANC_DESC_MAX] = +{ + /// Location and Speed Char. - Client Characteristic Configuration + [LANC_DESC_LOC_SPEED_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_MANDATORY, + LANP_LANS_LOC_SPEED_CHAR}, + + /// Control Point Char. - Client Characteristic Configuration + [LANC_DESC_LN_CTNL_PT_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_OPTIONAL, + LANP_LANS_LN_CTNL_PT_CHAR}, + + /// Navigation Char. - Client Characteristic Configuration + [LANC_DESC_NAVIGATION_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_OPTIONAL, + LANP_LANS_NAVIG_CHAR}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == LANC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct lanc_env_tag *lanc_env = PRF_ENV_GET(LANC, lanc); + + ASSERT_INFO(lanc_env != NULL, dest_id, src_id); + ASSERT_INFO(lanc_env->env[conidx] != NULL, dest_id, src_id); + + if(lanc_env->env[conidx]->nb_svc == 0) + { + // Retrieve CPS characteristics and descriptors + prf_extract_svc_info(ind, LANP_LANS_CHAR_MAX, &lanc_lns_char[0], &lanc_env->env[conidx]->lans.chars[0], + LANC_DESC_MAX, &lanc_lns_char_desc[0], &lanc_env->env[conidx]->lans.descs[0]); + + //Even if we get multiple responses we only store 1 range + lanc_env->env[conidx]->lans.svc.shdl = ind->start_hdl; + lanc_env->env[conidx]->lans.svc.ehdl = ind->end_hdl; + } + + lanc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref LANC_ENABLE_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int lanc_enable_req_handler(ke_msg_id_t const msgid, + struct lanc_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + uint8_t state = ke_state_get(dest_id); + // Location and Navigation Profile Collector Role Task Environment + struct lanc_env_tag *lanc_env = PRF_ENV_GET(LANC, lanc); + + ASSERT_INFO(lanc_env != NULL, dest_id, src_id); + if((state == LANC_IDLE) && (lanc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + lanc_env->env[conidx] = (struct lanc_cnx_env*) ke_malloc(sizeof(struct lanc_cnx_env),KE_MEM_ATT_DB); + memset(lanc_env->env[conidx], 0, sizeof(struct lanc_cnx_env)); + + //Config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering CPS on peer + prf_disc_svc_send(&(lanc_env->prf_env), conidx, ATT_SVC_LOCATION_AND_NAVIGATION); + + // Go to DISCOVERING state + ke_state_set(dest_id, LANC_DISCOVERING); + } + //normal connection, get saved att details + else + { + lanc_env->env[conidx]->lans = param->lans; + + //send APP confirmation that can start normal connection to TH + lanc_enable_rsp_send(lanc_env, conidx, GAP_ERR_NO_ERROR); + } + } + + else if(state != LANC_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + lanc_enable_rsp_send(lanc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref LANC_READ_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int lanc_read_cmd_handler(ke_msg_id_t const msgid, + struct lanc_read_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get the address of the environment + struct lanc_env_tag *lanc_env = PRF_ENV_GET(LANC, lanc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (state == LANC_IDLE) + { + ASSERT_INFO(lanc_env != NULL, dest_id, src_id); + // environment variable not ready + if(lanc_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + else + { + // Get the handler + uint16_t hdl = lanc_get_read_handle_req (lanc_env, conidx, param); + + // Check if handle is viable + if (hdl != ATT_INVALID_SEARCH_HANDLE) + { + // Force the operation value + param->operation = LANC_READ_OP_CODE; + + // Store the command structure + lanc_env->env[conidx]->operation = param; + msg_status = KE_MSG_NO_FREE; + + // Send the read request + prf_read_char_send(&(lanc_env->prf_env), conidx, + lanc_env->env[conidx]->lans.svc.shdl, + lanc_env->env[conidx]->lans.svc.ehdl, + hdl); + + // Go to the Busy state + ke_state_set(dest_id, LANC_BUSY); + + status = ATT_ERR_NO_ERROR; + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + } + else if(state == LANC_FREE) + { + status = GAP_ERR_DISCONNECTED; + } + else + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + status = GAP_ERR_NO_ERROR; + } + + if (status != GAP_ERR_NO_ERROR) + { + // Send the complete event message to the task id stored in the environment + lanc_send_cmp_evt(lanc_env, conidx, LANC_READ_OP_CODE, status); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref LANC_CFG_NTFIND_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int lanc_cfg_ntfind_cmd_handler(ke_msg_id_t const msgid, + struct lanc_cfg_ntfind_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct lanc_env_tag *lanc_env = PRF_ENV_GET(LANC, lanc); + + uint8_t state = ke_state_get(dest_id); + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + if (lanc_env != NULL) + { + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + // Handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + do + { + if (state != LANC_IDLE) + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + break; + } + + ASSERT_ERR(lanc_env->env[conidx] != NULL); + + // Get handle + status = lanc_get_write_desc_handle_req (conidx, param, lanc_env, &handle); + } while (0); + + if ((status == GAP_ERR_NO_ERROR) && (handle != ATT_INVALID_SEARCH_HANDLE)) + { + // Set the operation code + param->operation = LANC_CFG_NTF_IND_OP_CODE; + + // Store the command structure + lanc_env->env[conidx]->operation = param; + msg_status = KE_MSG_NO_FREE; + + // Go to the Busy state + ke_state_set(dest_id, LANC_BUSY); + + // Send GATT Write Request + prf_gatt_write_ntf_ind(&lanc_env->prf_env, conidx, handle, param->ntfind_cfg); + } + } + else + { + lanc_send_no_conn_cmp_evt(dest_id, src_id, LANC_CFG_NTF_IND_OP_CODE); + } + + return (int)msg_status; +} + + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref LANC_LN_CTNL_PT_CFG_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int lanc_ln_ctnl_pt_cfg_req_handler(ke_msg_id_t const msgid, + struct lanc_ln_ctnl_pt_cfg_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get the address of the environment + struct lanc_env_tag *lanc_env = PRF_ENV_GET(LANC, lanc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (lanc_env != NULL) + { + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + do + { + // State is Connected or Busy + ASSERT_ERR(ke_state_get(dest_id) > LANC_FREE); + + // Check the provided connection handle + if (lanc_env->env[conidx] == NULL) + { + status = PRF_ERR_INVALID_PARAM; + break; + } + + if (ke_state_get(dest_id) != LANC_IDLE) + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + // Status is PRF_ERR_OK, no message will be sent to the application + break; + } + + // Check if the characteristic has been found + if (lanc_env->env[conidx]->lans.descs[LANC_DESC_LN_CTNL_PT_CL_CFG].desc_hdl != ATT_INVALID_SEARCH_HANDLE) + { + // Request array declaration + uint8_t req[LANP_LAN_LN_CNTL_PT_REQ_MAX_LEN]; + // Pack request + uint8_t nb = lanc_pack_ln_ctnl_pt_req (param, req, &status); + + if (status == GAP_ERR_NO_ERROR) + { + // Set the operation code + param->operation = LANC_LN_CTNL_PT_CFG_WR_OP_CODE; + + // Store the command structure + lanc_env->env[conidx]->operation = param; + // Store the command information + msg_status = KE_MSG_NO_FREE; + + // Go to the Busy state + ke_state_set(dest_id, LANC_BUSY); + + // Send the write request + prf_gatt_write(&(lanc_env->prf_env), conidx, lanc_env->env[conidx]->lans.chars[LANP_LANS_LN_CTNL_PT_CHAR].val_hdl, + (uint8_t *)&req[0], nb, GATTC_WRITE); + } + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } while (0); + + if (status != GAP_ERR_NO_ERROR) + { + // Send a complete event status to the application + lanc_send_cmp_evt(lanc_env, conidx, LANC_LN_CTNL_PT_CFG_WR_OP_CODE, status); + } + } + else + { + // No connection + lanc_send_no_conn_cmp_evt(dest_id, src_id, LANC_LN_CTNL_PT_CFG_WR_OP_CODE); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref LANC_TIMEOUT_TIMER_IND message. This message is + * received when the peer device doesn't send a SC Control Point indication within 30s + * after reception of the write response. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int lanc_timeout_timer_ind_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct lanc_env_tag *lanc_env = PRF_ENV_GET(LANC, lanc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (lanc_env != NULL) + { + ASSERT_ERR(lanc_env->env[conidx]->operation != NULL); + ASSERT_ERR(((struct lanc_cmd *)lanc_env->env[conidx]->operation)->operation == LANC_LN_CTNL_PT_CFG_IND_OP_CODE); + + // Send the complete event message + lanc_send_cmp_evt(lanc_env, conidx, LANC_LN_CTNL_PT_CFG_WR_OP_CODE, PRF_ERR_PROC_TIMEOUT); + } + // else drop the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct lanc_env_tag *lanc_env = PRF_ENV_GET(LANC, lanc); + // Status + uint8_t status; + + if (lanc_env != NULL) + { + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if (state == LANC_DISCOVERING) + { + status = param->status; + + if ((status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || + (status == ATT_ERR_NO_ERROR)) + { + // Discovery + // check characteristic validity + if(lanc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(LANP_LANS_CHAR_MAX, + lanc_env->env[conidx]->lans.chars, + lanc_lns_char); + } + // too much services + else if (lanc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if (status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(LANC_DESC_MAX, + lanc_env->env[conidx]->lans.descs, + lanc_lns_char_desc, + lanc_env->env[conidx]->lans.chars); + } + } + + lanc_enable_rsp_send(lanc_env, conidx, status); + } + + else if (state == LANC_BUSY) + { + switch (param->operation) + { + case GATTC_READ: + { + // Send the complete event status + lanc_send_cmp_evt(lanc_env, conidx, LANC_READ_OP_CODE, param->status); + } break; + + case GATTC_WRITE: + case GATTC_WRITE_NO_RESPONSE: + { + uint8_t operation = ((struct lanc_cmd *)lanc_env->env[conidx]->operation)->operation; + + if (operation == LANC_CFG_NTF_IND_OP_CODE) + { + // Send the complete event status + lanc_send_cmp_evt(lanc_env, conidx, operation, param->status); + } + + else if (operation == LANC_LN_CTNL_PT_CFG_WR_OP_CODE) + { + if (param->status == GAP_ERR_NO_ERROR) + { + // Start Timeout Procedure + ke_timer_set(LANC_TIMEOUT_TIMER_IND, dest_id, ATT_TRANS_RTX); + + // Wait for the response indication + ((struct lanc_cmd *)lanc_env->env[conidx]->operation)->operation = LANC_LN_CTNL_PT_CFG_IND_OP_CODE; + } + else + { + // Send the complete event status + lanc_send_cmp_evt(lanc_env, conidx, operation, param->status); + } + } + } break; + + case GATTC_REGISTER: + case GATTC_UNREGISTER: + { + // Do nothing + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + // Get the address of the environment + struct lanc_env_tag *lanc_env = PRF_ENV_GET(LANC, lanc); + + if (state == LANC_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + ASSERT_INFO(lanc_env != NULL, dest_id, src_id); + ASSERT_INFO(lanc_env->env[conidx] != NULL, dest_id, src_id); + + // Send the read value to the HL + struct lanc_value_ind *ind = KE_MSG_ALLOC(LANC_VALUE_IND, + prf_dst_task_get(&(lanc_env->prf_env), conidx), + dest_id, + lanc_value_ind); + + switch (((struct lanc_read_cmd *)lanc_env->env[conidx]->operation)->read_code) + { + // Read LN Feature Characteristic value + case (LANC_RD_LN_FEAT): + { + ind->value.LN_feat = co_read32p(¶m->value[0]); + + // Mask the reserved bits +// ind->value.LN_feat &= LANP_FEAT_ALL_SUPP; + } break; + + // Read Position Quality + case (LANC_RD_POS_Q): + { + // Read position quality + lanc_unpack_pos_q_ind (param, ind); + + } break; + + // Read Client Characteristic Configuration Descriptor value + case (LANC_RD_WR_LOC_SPEED_CL_CFG): + case (LANC_RD_WR_LN_CTNL_PT_CFG): + case (LANC_RD_WR_NAVIGATION_CFG): + { + ind->value.ntf_cfg = co_read16p(¶m->value[0]); + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + + ind->att_code = ((struct lanc_read_cmd *)lanc_env->env[conidx]->operation)->read_code; + + // Send the message to the application + ke_msg_send(ind); + } + // else drop the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct lanc_env_tag *lanc_env = PRF_ENV_GET(LANC, lanc); + + if (lanc_env != NULL) + { + switch (param->type) + { + case (GATTC_NOTIFY): + { + if (param->handle == lanc_env->env[conidx]->lans.chars[LANP_LANS_LOC_SPEED_CHAR].val_hdl) + { + //Unpack location and speed + lanc_unpack_loc_speed_ind(conidx, param, lanc_env); + } + else if (param->handle == lanc_env->env[conidx]->lans.chars[LANP_LANS_NAVIG_CHAR].val_hdl) + { + // Unpack navigation + lanc_unpack_navigation_ind(conidx, param, lanc_env); + } + else + { + ASSERT_ERR(0); + } + } break; + + case (GATTC_INDICATE): + { + // confirm that indication has been correctly received + struct gattc_event_cfm * cfm = KE_MSG_ALLOC(GATTC_EVENT_CFM, src_id, dest_id, gattc_event_cfm); + cfm->handle = param->handle; + ke_msg_send(cfm); + + // Check if we were waiting for the indication + if (lanc_env->env[conidx]->operation != NULL) + { + if (((struct lanc_cmd *)lanc_env->env[conidx]->operation)->operation == LANC_LN_CTNL_PT_CFG_IND_OP_CODE) + { + // Stop the procedure timeout timer + ke_timer_clear(LANC_TIMEOUT_TIMER_IND, dest_id); + + //Unpack control point + lanc_unpack_ln_ctln_pt_ind(param, prf_src_task_get(&(lanc_env->prf_env), conidx), prf_dst_task_get(&(lanc_env->prf_env), conidx)); + + // Send the complete event message + lanc_send_cmp_evt(lanc_env, conidx, LANC_LN_CTNL_PT_CFG_WR_OP_CODE, GAP_ERR_NO_ERROR); + } + // else drop the message + } + // else drop the message + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(lanc) +{ + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {LANC_ENABLE_REQ, (ke_msg_func_t)lanc_enable_req_handler}, + {LANC_READ_CMD, (ke_msg_func_t)lanc_read_cmd_handler}, + {LANC_CFG_NTFIND_CMD, (ke_msg_func_t)lanc_cfg_ntfind_cmd_handler}, + {LANC_LN_CTNL_PT_CFG_REQ, (ke_msg_func_t)lanc_ln_ctnl_pt_cfg_req_handler}, + {LANC_TIMEOUT_TIMER_IND, (ke_msg_func_t)lanc_timeout_timer_ind_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_EVENT_REQ_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void lanc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct lanc_env_tag *lanc_env = PRF_ENV_GET(LANC, lanc); + + task_desc->msg_handler_tab = lanc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(lanc_msg_handler_tab); + task_desc->state = lanc_env->state; + task_desc->idx_max = LANC_IDX_MAX; +} + +#endif //(BLE_LN_COLLECTOR) + +/// @} LANCTASK diff --git a/services/ble_profiles/lan/lans/api/lans_task.h b/services/ble_profiles/lan/lans/api/lans_task.h new file mode 100644 index 0000000..72c5068 --- /dev/null +++ b/services/ble_profiles/lan/lans/api/lans_task.h @@ -0,0 +1,270 @@ +#ifndef _LANS_TASK_H_ +#define _LANS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup LANSTASK Task + * @ingroup LANS + * @brief Location and Navigation Profile Task. + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "lan_common.h" +#include "rwip_task.h" // Task definitions + +/* + * DEFINES + **************************************************************************************** + */ + + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Messages for Location and Navigation Profile Sensor +enum lans_msg_id +{ + /// Start the Location and Navigation Profile Server profile + LANS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_LANS), + /// Confirm profile + LANS_ENABLE_RSP, + + /// Update Position Quality + LANS_UPD_POS_Q_REQ, + /// Update Position Quality + LANS_UPD_POS_Q_RSP, + + /// Send a Location and Speed to the peer device (Notification) + LANS_NTF_LOC_SPEED_REQ, + /// Response of Send a Location and Speed request + LANS_NTF_LOC_SPEED_RSP, + + /// Send a LN Vector to the peer device (Notification) + LANS_NTF_NAVIGATION_REQ, + /// Response of Send LN Vector request + LANS_NTF_NAVIGATION_RSP, + + /// Send a complete event status to the application + LANS_CMP_EVT, + + /// Indicate that an attribute value has been written + LANS_CFG_NTFIND_IND, + + /// Indicate that Control Point characteristic value has been written + LANS_LN_CTNL_PT_REQ_IND, + /// Application response after receiving a LANS_CTNL_PT_REQ_IND message + LANS_LN_CTNL_PT_CFM, +}; + +/// Operation Code used in the profile state machine +enum lans_op_code +{ + /// Reserved Operation Code + LANS_RESERVED_OP_CODE = 0x00, + + /// Enable Profile Operation Code + LANS_ENABLE_REQ_OP_CODE, + + /// Send Location and Speed Operation Code + LANS_NTF_LOC_SPEED_OP_CODE, + + /// Update Position quality + LANS_UPD_POS_Q_OP_CODE, + + /// Send Navigation Operation Code + LANS_NTF_NAVIGATION_OP_CODE, + + /** + * Control Point Operation + */ + /// Set Cumulative Value + LANS_SET_CUMUL_VALUE_OP_CODE, + /// Mask Location and Speed Characteristic Content + LANS_MASK_LSPEED_CHAR_CT_OP_CODE, + /// Navigation Control + LANS_NAVIGATION_CONTROL_OP_CODE, + /// Request Number of Routes + LANS_REQ_NUMBER_OF_ROUTES_OP_CODE, + /// Request Name of Route + LANS_REQ_NAME_OF_ROUTE_OP_CODE, + /// Select Route + LANS_SELECT_ROUTE_OP_CODE, + /// Set Fix Rate + LANS_SET_FIX_RATE_OP_CODE, + /// Set Elevation + LANS_SET_ELEVATION_OP_CODE, + + /// Error Indication Sent Operation Code + LANS_LN_CTNL_ERR_IND_OP_CODE, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Parameters of the @ref LANS_CREATE_DB_REQ message +struct lans_db_cfg +{ + /** + * LN Feature Value - Not supposed to be modified during the lifetime of the device + * This bit field is set in order to decide which features are supported: + */ + uint32_t ln_feature; + + /** + * Bit 0 - Enable LN Control Point + * Bit 1 - Enable Navigation Feature + */ + uint8_t prfl_config; +}; + +/// Parameters of the @ref LANS_ENABLE_REQ message +struct lans_enable_req +{ + /// Connection index + uint8_t conidx; + /** + * Profile characteristic configuration: + * Location and speed Characteristic NTF config -- Bit 0 + * LN Control Point Characteristic IND config ---- Bit 1 + * Navigation Characteristic NTF config ---------- Bit 2 + */ + uint16_t prfl_ntf_ind_cfg; +}; + +/// Parameters of the @ref LANS_ENABLE_RSP message +struct lans_enable_rsp +{ + /// Connection index + uint8_t conidx; + /// status + uint8_t status; +}; + +/// Parameters of the @ref LANS_CMP_EVT message +struct lans_cmp_evt +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t operation; + /// Operation Status + uint8_t status; +}; + +/// Parameters of the @ref LANS_CFG_NTFIND_IND message +struct lans_cfg_ntfind_ind +{ + /// Connection index + uint8_t conidx; + /// Characteristic Code (Location and speed, Control Point or navigation) + uint8_t char_code; + /// Char. Client Characteristic Configuration + uint16_t ntf_cfg; +}; + +/// Parameters of the @ref LANS_NTF_LOC_SPEED_REQ message +struct lans_ntf_loc_speed_req +{ + ///Parameters + struct lanp_loc_speed parameters; +}; + +/// Parameters of the @ref LANS_NTF_LOC_SPEED_RSP message +struct lans_ntf_loc_speed_rsp +{ + /// Operation Status + uint8_t status; +}; + +/// Parameters of the @ref LANS_NTF_NAVIGATION_REQ message +struct lans_ntf_navigation_req +{ + ///Parameters + struct lanp_navigation parameters; +}; + +/// Parameters of the @ref LANS_NTF_NAVIGATION_RSP message +struct lans_ntf_navigation_rsp +{ + /// Operation Status + uint8_t status; +}; + +/// Parameters of the @ref LANS_UPD_POS_Q_REQ message +struct lans_upd_pos_q_req +{ + ///Parameters + struct lanp_posq parameters; +}; + +/// Parameters of the @ref LANS_UPD_POS_Q_RSP message +struct lans_upd_pos_q_rsp +{ + /// Operation Status + uint8_t status; +}; + +/// Parameters of the @ref LANS_LN_CTNL_PT_REQ_IND message +struct lans_ln_ctnl_pt_req_ind +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t op_code; + /// Value + union lans_ln_ctnl_pt_req_ind_value + { + /// Cumulative Value (24 bits) + uint32_t cumul_val; + /// Mask Content + uint16_t mask_content; + /// Navigation Control + uint8_t control_value; + /// Route number + uint16_t route_number; + /// Fix rate + uint8_t fix_rate; + /// Elevation + int32_t elevation; + } value; +}; + +/// Parameters of the @ref LANS_CTNL_PT_CFM message +struct lans_ln_ctnl_pt_cfm +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t op_code; + /// Status + uint8_t status; + /// Value + union lans_ln_ctnl_pt_cfm_value + { + /// Number of routes + uint16_t number_of_routes; + /// Mask content + uint16_t mask_lspeed_content; + struct lan_route_name + { + uint8_t length; + /// Name of Route UTF-8 + uint8_t name[__ARRAY_EMPTY]; + } route; + } value; +}; + +/// @} LANSTASK + +#endif //(_LANS_TASK_H_) diff --git a/services/ble_profiles/lan/lans/src/lans.c b/services/ble_profiles/lan/lans/src/lans.c new file mode 100644 index 0000000..0da319c --- /dev/null +++ b/services/ble_profiles/lan/lans/src/lans.c @@ -0,0 +1,1362 @@ +/** + **************************************************************************************** + * @addtogroup LANS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_LN_SENSOR) +#include "lan_common.h" + +#include "gap.h" +#include "gattc_task.h" +#include "gattc.h" +#include "attm.h" +#include "lans.h" +#include "lans_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * CYCLING POWER SERVICE ATTRIBUTES + **************************************************************************************** + */ + +/// Full LANS Database Description - Used to add attributes into the database +static const struct attm_desc lans_att_db[LNS_IDX_NB] = +{ + // Location and Navigation Service Declaration + [LNS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // LN Feature Characteristic Declaration + [LNS_IDX_LN_FEAT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // LN Feature Characteristic Value + [LNS_IDX_LN_FEAT_VAL] = {ATT_CHAR_LN_FEAT, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(uint32_t)}, + + // Location and Speed Characteristic Declaration + [LNS_IDX_LOC_SPEED_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Location and Speed Characteristic Value + [LNS_IDX_LOC_SPEED_VAL] = {ATT_CHAR_LOC_SPEED, PERM(NTF, ENABLE), PERM(RI, ENABLE), LANP_LAN_LOC_SPEED_MAX_LEN}, + // Location and Speed Characteristic - Client Characteristic Configuration Descriptor + [LNS_IDX_LOC_SPEED_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Position Quality Characteristic Declaration + [LNS_IDX_POS_Q_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Position Quality Characteristic Value + [LNS_IDX_POS_Q_VAL] = {ATT_CHAR_POS_QUALITY, PERM(RD, ENABLE), PERM(RI, ENABLE), LANP_LAN_POSQ_MAX_LEN}, + + // LN Control Point Characteristic Declaration + [LNS_IDX_LN_CTNL_PT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // LN Control Point Characteristic Value - The response has the maximal length + [LNS_IDX_LN_CTNL_PT_VAL] = {ATT_CHAR_LN_CNTL_PT, PERM(IND, ENABLE) | PERM(WRITE_REQ, ENABLE), + PERM(RI, ENABLE), LANP_LAN_LN_CNTL_PT_RSP_MAX_LEN}, + // LN Control Point Characteristic - Client Characteristic Configuration Descriptor + [LNS_IDX_LN_CTNL_PT_IND_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Navigation Characteristic Declaration + [LNS_IDX_NAVIGATION_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Navigation Characteristic Value + [LNS_IDX_NAVIGATION_VAL] = {ATT_CHAR_NAVIGATION, PERM(NTF, ENABLE), PERM(RI, ENABLE), LANP_LAN_NAVIGATION_MAX_LEN}, + // Navigation Characteristic - Client Characteristic Configuration Descriptor + [LNS_IDX_NAVIGATION_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the LANS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t lans_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct lans_db_cfg* params) +{ + //------------------ create the attribute database for the profile ------------------- + // Service Configuration Flag + uint16_t cfg_flag = LANS_MANDATORY_MASK; + // Database Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + /* + * Check if Position Quality shall be added. + */ + if((LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_NUMBER_OF_BEACONS_IN_SOLUTION_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_NUMBER_OF_BEACONS_IN_VIEW_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_TIME_TO_FIRST_FIX_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_ESTIMATED_HOR_POSITION_ERROR_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_ESTIMATED_VER_POSITION_ERROR_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_HOR_DILUTION_OF_PRECISION_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_VER_DILUTION_OF_PRECISION_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_POSITION_STATUS_SUPP))) + { + //Add configuration to the database + cfg_flag |= LANS_POS_Q_MASK; + } + + /* + * Check if the Navigation characteristic shall be added. + */ + if ((LANS_IS_FEATURE_SUPPORTED(params->prfl_config, LANS_NAVIGATION_SUPP_FLAG)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_NUMBER_OF_BEACONS_IN_SOLUTION_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_REMAINING_DISTANCE_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_REMAINING_VERTICAL_DISTANCE_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_ESTIMATED_TIME_OF_ARRIVAL_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_POSITION_STATUS_SUPP))) + { + cfg_flag |= LANS_NAVI_MASK; + } + /* + * Check if the LN Control Point characteristic shall be added + */ + if ((LANS_IS_FEATURE_SUPPORTED(cfg_flag, LANS_NAVI_MASK)) || + (LANS_IS_FEATURE_SUPPORTED(params->prfl_config, LANS_CTNL_PT_CHAR_SUPP_FLAG)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_TOTAL_DISTANCE_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_LSPEED_CHAR_CT_MASKING_SUPP)) || + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_FIX_RATE_SETTING_SUPP)) || + ((LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_ELEVATION_SUPP)) && + (LANS_IS_FEATURE_SUPPORTED(params->ln_feature, LANP_FEAT_ELEVATION_SETTING_SUPP)))) + { + cfg_flag |= LANS_LN_CTNL_PT_MASK; + } + + // Add service in the database + status = attm_svc_create_db(start_hdl, ATT_SVC_LOCATION_AND_NAVIGATION, (uint8_t *)&cfg_flag, + LNS_IDX_NB, NULL, env->task, &lans_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, DISABLE)); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // Allocate LANS required environment variable + struct lans_env_tag* lans_env = + (struct lans_env_tag* ) ke_malloc(sizeof(struct lans_env_tag), KE_MEM_ATT_DB); + + // Initialize LANS environment + env->env = (prf_env_t*) lans_env; + lans_env->shdl = *start_hdl; + lans_env->prfl_cfg = cfg_flag; + lans_env->features = params->ln_feature; + lans_env->operation = LANS_RESERVED_OP_CODE; + lans_env->posq = (LANS_IS_FEATURE_SUPPORTED(cfg_flag, LANS_POS_Q_MASK)) ? + (struct lanp_posq* ) ke_malloc(sizeof(struct lanp_posq), KE_MEM_ATT_DB) : NULL; + + lans_env->op_data = NULL; + memset(lans_env->env, 0, sizeof(lans_env->env)); + + lans_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Mono Instantiated task + lans_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + // initialize environment variable + env->id = TASK_ID_LANS; + lans_task_init(&(env->desc)); + + /* Put CPS in Idle state */ + ke_state_set(env->task, LANS_IDLE); + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the LANS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void lans_destroy(struct prf_task_env* env) +{ + struct lans_env_tag* lans_env = (struct lans_env_tag*) env->env; + + // free profile environment variables + env->env = NULL; + + if (lans_env->posq != NULL) + { + ke_free(lans_env->posq); + } + + if (lans_env->op_data != NULL) + { + ke_free(lans_env->op_data->cmd); + if(lans_env->op_data->ntf_pending) + { + ke_free(lans_env->op_data->ntf_pending); + } + ke_free(lans_env->op_data); + } + + ke_free(lans_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void lans_create(struct prf_task_env* env, uint8_t conidx) +{ + struct lans_env_tag* lans_env = (struct lans_env_tag*) env->env; + + memset(&(lans_env->env[conidx]), 0, sizeof(struct lans_cnx_env)); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void lans_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct lans_env_tag* lans_env = (struct lans_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + memset(&(lans_env->env[conidx]), 0, sizeof(struct lans_cnx_env)); +} + +/// LANS Task interface required by profile manager +const struct prf_task_cbs lans_itf = +{ + (prf_init_fnct) lans_init, + lans_destroy, + lans_create, + lans_cleanup, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* lans_prf_itf_get(void) +{ + return &lans_itf; +} + +void lans_send_cmp_evt(uint8_t conidx, uint8_t src_id, uint8_t dest_id, uint8_t operation, uint8_t status) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + + // Go back to the Connected state if the state is busy + if (ke_state_get(src_id) == LANS_BUSY) + { + ke_state_set(src_id, LANS_IDLE); + } + + // Set the operation code + lans_env->operation = LANS_RESERVED_OP_CODE; + + // Send the message + struct lans_cmp_evt *evt = KE_MSG_ALLOC(LANS_CMP_EVT, + dest_id, src_id, + lans_cmp_evt); + + evt->conidx = conidx; + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + +uint8_t lans_pack_loc_speed_ntf(struct lanp_loc_speed *param, uint8_t *pckd_loc_speed) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + // Packed Measurement length + uint8_t pckd_loc_speed_len = LANP_LAN_LOC_SPEED_MIN_LEN; + + // Check provided flags + if (LANS_IS_PRESENT(param->flags, LANP_LSPEED_INST_SPEED_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_INSTANTANEOUS_SPEED_SUPP)) + { + //Pack instantaneous speed + co_write16p(&pckd_loc_speed[pckd_loc_speed_len], param->inst_speed); + pckd_loc_speed_len += 2; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~LANP_LSPEED_INST_SPEED_PRESENT; + } + } + + if (LANS_IS_PRESENT(param->flags, LANP_LSPEED_TOTAL_DISTANCE_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_TOTAL_DISTANCE_SUPP)) + { + //Pack total distance (24bits) + co_write24p(&pckd_loc_speed[pckd_loc_speed_len], param->total_dist); + pckd_loc_speed_len += 3; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~LANP_LSPEED_TOTAL_DISTANCE_PRESENT; + } + } + + if (LANS_IS_PRESENT(param->flags, LANP_LSPEED_LOCATION_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_LOCATION_SUPP)) + { + //Pack Location + co_write32p(&pckd_loc_speed[pckd_loc_speed_len], param->latitude); + pckd_loc_speed_len += 4; + co_write32p(&pckd_loc_speed[pckd_loc_speed_len], param->longitude); + pckd_loc_speed_len += 4; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~LANP_LSPEED_LOCATION_PRESENT; + } + } + + if (LANS_IS_PRESENT(param->flags, LANP_LSPEED_ELEVATION_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_ELEVATION_SUPP)) + { + //Pack elevation (24 bits) + co_write24p(&pckd_loc_speed[pckd_loc_speed_len], param->elevation); + pckd_loc_speed_len += 3; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~LANP_LSPEED_ELEVATION_PRESENT; + } + } + + if (LANS_IS_PRESENT(param->flags, LANP_LSPEED_HEADING_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_HEADING_SUPP)) + { + //Pack Extreme Force Magnitudes (Maximum Force Magnitude & Minimum Force Magnitude) + co_write16p(&pckd_loc_speed[pckd_loc_speed_len], param->heading); + pckd_loc_speed_len += 2; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~LANP_LSPEED_HEADING_PRESENT; + } + } + + if (LANS_IS_PRESENT(param->flags, LANP_LSPEED_ROLLING_TIME_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_ROLLING_TIME_SUPP)) + { + //Pack rolling time + pckd_loc_speed[pckd_loc_speed_len] = param->rolling_time; + pckd_loc_speed_len++; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~LANP_LSPEED_ROLLING_TIME_PRESENT; + } + } + + if (LANS_IS_PRESENT(param->flags, LANP_LSPEED_UTC_TIME_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_UTC_TIME_SUPP)) + { + // Pack UTC time + pckd_loc_speed_len += prf_pack_date_time(&pckd_loc_speed[pckd_loc_speed_len], &(param->date_time)); + + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~LANP_LSPEED_UTC_TIME_PRESENT; + } + } + + // Force the unused bits of the flag value to 0 +// param->flags &= LANP_LSPEED_ALL_PRESENT; + // Flags value + co_write16p(&pckd_loc_speed[0], param->flags); + + return pckd_loc_speed_len; +} + +uint8_t lans_split_loc_speed_ntf(uint8_t conidx, struct gattc_send_evt_cmd *loc_speed_ntf1) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + // Extract flags info + uint16_t flags = co_read16p(&loc_speed_ntf1->value[0]); + // Allocate the GATT notification message + struct gattc_send_evt_cmd *loc_speed_ntf2 = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&(lans_env->prf_env), conidx), + gattc_send_evt_cmd, LANP_LAN_LOC_SPEED_MAX_LEN); + + // Fill in the parameter structure + loc_speed_ntf2->operation = GATTC_NOTIFY; + loc_speed_ntf2->handle = LANS_HANDLE(LNS_IDX_LOC_SPEED_VAL); + loc_speed_ntf2->length = LANP_LAN_LOC_SPEED_MIN_LEN; + + // Copy status flags + co_write16p(&loc_speed_ntf2->value[0], (flags & (LANP_LSPEED_POSITION_STATUS_LSB | + LANP_LSPEED_POSITION_STATUS_MSB | + LANP_LSPEED_SPEED_AND_DISTANCE_FORMAT | + LANP_LSPEED_ELEVATION_SOURCE_LSB | + LANP_LSPEED_ELEVATION_SOURCE_MSB | + LANP_LSPEED_HEADING_SOURCE))); + // Current position + uint8_t len = 0; + + for (uint16_t feat = LANP_LSPEED_INST_SPEED_PRESENT; + feat <= LANP_LSPEED_POSITION_STATUS_LSB; + feat <<= 1) + { + // First message fits within the MTU + if (loc_speed_ntf1->length <= gattc_get_mtu(conidx) - 3) + { + // Stop splitting + break; + } + + if (LANS_IS_PRESENT(flags, feat)) + { + switch (feat) + { + case LANP_LSPEED_ROLLING_TIME_PRESENT: + // Copy uint8 + loc_speed_ntf2->value[loc_speed_ntf2->length] = + loc_speed_ntf1->value[LANP_LAN_LOC_SPEED_MIN_LEN]; + len = 1; + break; + + case LANP_LSPEED_INST_SPEED_PRESENT: + case LANP_LSPEED_HEADING_PRESENT: + // Copy uint16 + memcpy(&loc_speed_ntf2->value[loc_speed_ntf2->length], + &loc_speed_ntf1->value[LANP_LAN_LOC_SPEED_MIN_LEN], + 2); + len = 2; + break; + + case LANP_LSPEED_TOTAL_DISTANCE_PRESENT: + case LANP_LSPEED_ELEVATION_PRESENT: + // Copy uint24 + memcpy(&loc_speed_ntf2->value[loc_speed_ntf2->length], + &loc_speed_ntf1->value[LANP_LAN_LOC_SPEED_MIN_LEN], + 3); + len = 3; + break; + + case LANP_LSPEED_LOCATION_PRESENT: + // Copy latitude and longitude + memcpy(&loc_speed_ntf2->value[loc_speed_ntf2->length], + &loc_speed_ntf1->value[LANP_LAN_LOC_SPEED_MIN_LEN], + 8); + len = 8; + break; + + case LANP_LSPEED_UTC_TIME_PRESENT: + // Copy time + memcpy(&loc_speed_ntf2->value[loc_speed_ntf2->length], + &loc_speed_ntf1->value[LANP_LAN_LOC_SPEED_MIN_LEN], + 7); + len = 7; + break; + + default: + len = 0; + break; + } + + if (len) + { + // Update values + loc_speed_ntf2->length += len; + // Remove field and flags from the first ntf + loc_speed_ntf1->length -= len; + memcpy(&loc_speed_ntf1->value[LANP_LAN_LOC_SPEED_MIN_LEN], + &loc_speed_ntf1->value[LANP_LAN_LOC_SPEED_MIN_LEN + len], + loc_speed_ntf1->length); + // Update flags + loc_speed_ntf1->value[0] &= ~feat; + loc_speed_ntf2->value[0] |= feat; + } + } + } + + // store the pending notification to send + lans_env->op_data->ntf_pending = loc_speed_ntf2; + + return loc_speed_ntf2->length; +} + +uint8_t lans_update_characteristic_config(uint8_t conidx, uint8_t prfl_config, struct gattc_write_req_ind const *param) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get the value + uint16_t ntf_cfg = co_read16p(¶m->value[0]); + + // Check if the value is correct + if (prfl_config == LANS_PRF_CFG_FLAG_LN_CTNL_PT_IND) + { + if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_IND)) + { + // Save the new configuration in the environment + (ntf_cfg == PRF_CLI_STOP_NTFIND) ? + LANS_DISABLE_NTF_IND(conidx, prfl_config) : LANS_ENABLE_NTF_IND(conidx, prfl_config); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + else + { + if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF)) + { + // Save the new configuration in the environment + (ntf_cfg == PRF_CLI_STOP_NTFIND) ? + LANS_DISABLE_NTF_IND(conidx, prfl_config) : LANS_ENABLE_NTF_IND(conidx, prfl_config); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + + if (status == GAP_ERR_NO_ERROR) + { + // Allocate message to inform application + struct lans_cfg_ntfind_ind *ind = KE_MSG_ALLOC(LANS_CFG_NTFIND_IND, + prf_dst_task_get(&(lans_env->prf_env), conidx), prf_src_task_get(&(lans_env->prf_env), conidx), + lans_cfg_ntfind_ind); + // Inform APP of configuration change + ind->char_code = prfl_config; + ind->ntf_cfg = ntf_cfg; + ind->conidx = conidx; + ke_msg_send(ind); + + // Enable Bonded Data + LANS_ENABLE_NTF_IND(conidx, LANS_PRF_CFG_PERFORMED_OK); + } + + return (status); +} + +uint8_t lans_pack_navigation_ntf(struct lanp_navigation *param, uint8_t *pckd_navigation) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + // Packed Measurement length + uint8_t pckd_navigation_len = LANP_LAN_NAVIGATION_MIN_LEN; + + // Check provided flags + if (LANS_IS_PRESENT(param->flags, LANP_NAVI_REMAINING_DIS_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_REMAINING_DISTANCE_SUPP)) + { + //Pack distance (24bits) + co_write24p(&pckd_navigation[pckd_navigation_len], param->remaining_distance); + pckd_navigation_len += 3; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~LANP_NAVI_REMAINING_DIS_PRESENT; + } + } + + if (LANS_IS_PRESENT(param->flags, LANP_NAVI_REMAINING_VER_DIS_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_REMAINING_VERTICAL_DISTANCE_SUPP)) + { + //Pack vertical distance (24bits) + co_write24p(&pckd_navigation[pckd_navigation_len], param->remaining_ver_distance); + pckd_navigation_len += 3; + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~LANP_NAVI_REMAINING_VER_DIS_PRESENT; + } + } + + if (LANS_IS_PRESENT(param->flags, LANP_NAVI_ESTIMATED_TIME_OF_ARRIVAL_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_ESTIMATED_TIME_OF_ARRIVAL_SUPP)) + { + //Pack time + pckd_navigation_len += prf_pack_date_time( + &pckd_navigation[pckd_navigation_len], &(param->estimated_arrival_time)); + + } + else //Not supported by the profile + { + //Force to not supported + param->flags &= ~LANP_NAVI_ESTIMATED_TIME_OF_ARRIVAL_PRESENT; + } + } + + // Force the unused bits of the flag value to 0 +// param->flags &= LANP_NAVI_ALL_PRESENT; + // Flags value + co_write16p(&pckd_navigation[0], param->flags); + // Bearing value + co_write16p(&pckd_navigation[2], param->bearing); + // heading value + co_write16p(&pckd_navigation[4], param->heading); + + return pckd_navigation_len; +} + +void lans_upd_posq(struct lanp_posq param) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + + // Check provided flags + if (LANS_IS_PRESENT(param.flags, LANP_POSQ_NUMBER_OF_BEACONS_IN_SOLUTION_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_NUMBER_OF_BEACONS_IN_SOLUTION_SUPP)) + { + //Pack beacons in solution + lans_env->posq->n_beacons_solution = param.n_beacons_solution; + } + else //Not supported by the profile + { + //Force to not supported + param.flags &= ~LANP_POSQ_NUMBER_OF_BEACONS_IN_SOLUTION_PRESENT; + } + } + + if (LANS_IS_PRESENT(param.flags, LANP_POSQ_NUMBER_OF_BEACONS_IN_VIEW_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_NUMBER_OF_BEACONS_IN_VIEW_SUPP)) + { + //Pack beacons in view + lans_env->posq->n_beacons_view = param.n_beacons_view; + } + else //Not supported by the profile + { + //Force to not supported + param.flags &= ~LANP_POSQ_NUMBER_OF_BEACONS_IN_VIEW_PRESENT; + } + } + + if (LANS_IS_PRESENT(param.flags, LANP_POSQ_TIME_TO_FIRST_FIX_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_TIME_TO_FIRST_FIX_SUPP)) + { + //Pack time to fix + lans_env->posq->time_first_fix = param.time_first_fix; + } + else //Not supported by the profile + { + //Force to not supported + param.flags &= ~LANP_POSQ_TIME_TO_FIRST_FIX_PRESENT; + } + } + + if (LANS_IS_PRESENT(param.flags, LANP_POSQ_EHPE_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_ESTIMATED_HOR_POSITION_ERROR_SUPP)) + { + //Pack ehpe + lans_env->posq->ehpe = param.ehpe; + } + else //Not supported by the profile + { + //Force to not supported + param.flags &= ~LANP_POSQ_EHPE_PRESENT; + } + } + + if (LANS_IS_PRESENT(param.flags, LANP_POSQ_EVPE_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_ESTIMATED_VER_POSITION_ERROR_SUPP)) + { + //Pack evpe + lans_env->posq->evpe = param.evpe; + } + else //Not supported by the profile + { + //Force to not supported + param.flags &= ~LANP_POSQ_EVPE_PRESENT; + } + } + + if (LANS_IS_PRESENT(param.flags, LANP_POSQ_HDOP_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_HOR_DILUTION_OF_PRECISION_SUPP)) + { + //Pack hdop + lans_env->posq->hdop = param.hdop; + } + else //Not supported by the profile + { + //Force to not supported + param.flags &= ~LANP_POSQ_HDOP_PRESENT; + } + } + + if (LANS_IS_PRESENT(param.flags, LANP_POSQ_VDOP_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_VER_DILUTION_OF_PRECISION_SUPP)) + { + //Pack vdop + lans_env->posq->vdop = param.vdop; + } + else //Not supported by the profile + { + //Force to not supported + param.flags &= ~LANP_POSQ_VDOP_PRESENT; + } + } + + // Force the unused bits of the flag value to 0 +// param.flags &= LANP_POSQ_ALL_PRESENT; + // Flags value + lans_env->posq->flags = param.flags; +} + +uint8_t lans_pack_posq(uint8_t *pckd_posq) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + + // Packed length + uint8_t pckd_posq_len = LANP_LAN_POSQ_MIN_LEN; + + // Check provided flags + if (LANS_IS_PRESENT(lans_env->posq->flags, LANP_POSQ_NUMBER_OF_BEACONS_IN_SOLUTION_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_NUMBER_OF_BEACONS_IN_SOLUTION_SUPP)) + { + //Pack beacons in solution + pckd_posq[pckd_posq_len] = lans_env->posq->n_beacons_solution; + pckd_posq_len++; + } + else //Not supported by the profile + { + //Force to not supported + lans_env->posq->flags &= ~LANP_POSQ_NUMBER_OF_BEACONS_IN_SOLUTION_PRESENT; + } + } + + if (LANS_IS_PRESENT(lans_env->posq->flags, LANP_POSQ_NUMBER_OF_BEACONS_IN_VIEW_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_NUMBER_OF_BEACONS_IN_VIEW_SUPP)) + { + //Pack beacons in view + pckd_posq[pckd_posq_len] = lans_env->posq->n_beacons_view; + pckd_posq_len++; + } + else //Not supported by the profile + { + //Force to not supported + lans_env->posq->flags &= ~LANP_POSQ_NUMBER_OF_BEACONS_IN_VIEW_PRESENT; + } + } + + if (LANS_IS_PRESENT(lans_env->posq->flags, LANP_POSQ_TIME_TO_FIRST_FIX_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_TIME_TO_FIRST_FIX_SUPP)) + { + //Pack time to fix + co_write16p(&pckd_posq[pckd_posq_len], lans_env->posq->time_first_fix); + pckd_posq_len += 2; + } + else //Not supported by the profile + { + //Force to not supported + lans_env->posq->flags &= ~LANP_POSQ_TIME_TO_FIRST_FIX_PRESENT; + } + } + + if (LANS_IS_PRESENT(lans_env->posq->flags, LANP_POSQ_EHPE_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_ESTIMATED_HOR_POSITION_ERROR_SUPP)) + { + //Pack ehpe + co_write32p(&pckd_posq[pckd_posq_len], lans_env->posq->ehpe); + pckd_posq_len += 4; + } + else //Not supported by the profile + { + //Force to not supported + lans_env->posq->flags &= ~LANP_POSQ_EHPE_PRESENT; + } + } + + if (LANS_IS_PRESENT(lans_env->posq->flags, LANP_POSQ_EVPE_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_ESTIMATED_VER_POSITION_ERROR_SUPP)) + { + //Pack ehpe + co_write32p(&pckd_posq[pckd_posq_len], lans_env->posq->evpe); + pckd_posq_len += 4; + } + else //Not supported by the profile + { + //Force to not supported + lans_env->posq->flags &= ~LANP_POSQ_EVPE_PRESENT; + } + } + + if (LANS_IS_PRESENT(lans_env->posq->flags, LANP_POSQ_HDOP_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_HOR_DILUTION_OF_PRECISION_SUPP)) + { + //Pack ehpe + pckd_posq[pckd_posq_len] = lans_env->posq->hdop; + pckd_posq_len++; + } + else //Not supported by the profile + { + //Force to not supported + lans_env->posq->flags &= ~LANP_POSQ_HDOP_PRESENT; + } + } + + if (LANS_IS_PRESENT(lans_env->posq->flags, LANP_POSQ_VDOP_PRESENT)) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_VER_DILUTION_OF_PRECISION_SUPP)) + { + //Pack ehpe + pckd_posq[pckd_posq_len] = lans_env->posq->vdop; + pckd_posq_len++; + } + else //Not supported by the profile + { + //Force to not supported + lans_env->posq->flags &= ~LANP_POSQ_VDOP_PRESENT; + } + } + + // Force the unused bits of the flag value to 0 +// lans_env->posq->flags &= LANP_POSQ_ALL_PRESENT; + // Flags value + co_write16p(&pckd_posq[0], lans_env->posq->flags); + + return pckd_posq_len; +} + +uint8_t lans_pack_ln_ctnl_point_cfm (uint8_t conidx, struct lans_ln_ctnl_pt_cfm *param, uint8_t *rsp) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + // Response Length (At least 3) + uint8_t rsp_len = LANP_LAN_LN_CNTL_PT_RSP_MIN_LEN; + + // Set the Response Code + rsp[0] = LANP_LN_CTNL_PT_RESPONSE_CODE; + // Set the Response Value + rsp[2] = (param->status > LANP_LN_CTNL_PT_RESP_FAILED) ? LANP_LN_CTNL_PT_RESP_FAILED : param->status; + + switch (lans_env->operation) + { + case (LANS_SET_CUMUL_VALUE_OP_CODE): + { + // Set the request operation code + rsp[1] = LANP_LN_CTNL_PT_SET_CUMUL_VALUE; + } break; + + case (LANS_MASK_LSPEED_CHAR_CT_OP_CODE): + { + // Set the request operation code + rsp[1] = LANP_LN_CTNL_PT_MASK_LSPEED_CHAR_CT; + if (param->status == LANP_LN_CTNL_PT_RESP_SUCCESS) + { + lans_env->env[conidx].mask_lspeed_content = + param->value.mask_lspeed_content & 0x007F; + } + } break; + + case (LANS_NAVIGATION_CONTROL_OP_CODE): + { + // Set the request operation code + rsp[1] = LANP_LN_CTNL_PT_NAVIGATION_CONTROL; + if (param->status == LANP_LN_CTNL_PT_RESP_SUCCESS) + { + switch(LANS_GET_NAV_MODE(conidx)) + { + // Disable notifications + case LANP_LN_CTNL_STOP_NAVI: + case LANP_LN_CTNL_PAUSE_NAVI: + LANS_SET_NAV_EN(conidx, false); + break; + + // Enable notifications + case LANP_LN_CTNL_START_NAVI: + case LANP_LN_CTNL_RESUME_NAVI: + case LANP_LN_CTNL_START_NST_WPT: + LANS_SET_NAV_EN(conidx, true); + break; + + // Do nothing + case LANP_LN_CTNL_SKIP_WPT: + default: + break; + } + } + } break; + + case (LANS_REQ_NUMBER_OF_ROUTES_OP_CODE): + { + // Set the request operation code + rsp[1] = LANP_LN_CTNL_PT_REQ_NUMBER_OF_ROUTES; + if (param->status == LANP_LN_CTNL_PT_RESP_SUCCESS) + { + co_write16p(&rsp[rsp_len], param->value.number_of_routes); + rsp_len += 2; + } + } break; + + case (LANS_REQ_NAME_OF_ROUTE_OP_CODE): + { + // Set the request operation code + rsp[1] = LANP_LN_CTNL_PT_REQ_NAME_OF_ROUTE; + if (param->status == LANP_LN_CTNL_PT_RESP_SUCCESS) + { + // pack name of route + for (int i=0; ivalue.route.length; i++) + { + rsp[i + 3] = param->value.route.name[i]; + rsp_len++; + } + } + } break; + + case (LANS_SELECT_ROUTE_OP_CODE): + { + // Set the request operation code + rsp[1] = LANP_LN_CTNL_PT_SELECT_ROUTE; + } break; + + case (LANS_SET_FIX_RATE_OP_CODE): + { + // Set the request operation code + rsp[1] = LANP_LN_CTNL_PT_SET_FIX_RATE; + } break; + + case (LANS_SET_ELEVATION_OP_CODE): + { + // Set the request operation code + rsp[1] = LANP_LN_CTNL_PT_SET_ELEVATION; + } break; + + default: + { + param->status = LANP_LN_CTNL_PT_RESP_NOT_SUPP; + } break; + } + + return rsp_len; +} + +uint8_t lans_unpack_ln_ctnl_point_ind (uint8_t conidx, struct gattc_write_req_ind const *param) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + + // Indication Status + uint8_t ind_status = LANP_LN_CTNL_PT_RESP_NOT_SUPP; + + // Allocate a request indication message for the application + struct lans_ln_ctnl_pt_req_ind *req_ind = KE_MSG_ALLOC(LANS_LN_CTNL_PT_REQ_IND, + prf_dst_task_get(&(lans_env->prf_env), conidx), prf_src_task_get(&(lans_env->prf_env), conidx), + lans_ln_ctnl_pt_req_ind); + // Operation Code + req_ind->op_code = param->value[0]; + req_ind->conidx = conidx; + + // Operation Code + switch(req_ind->op_code) + { + case (LANP_LN_CTNL_PT_SET_CUMUL_VALUE): + { + // Check if total distance feature is supported + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_TOTAL_DISTANCE_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = LANP_LN_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 4) + { + // The request can be handled + ind_status = LANP_LN_CTNL_PT_RESP_SUCCESS; + // Update the environment + lans_env->operation = LANS_SET_CUMUL_VALUE_OP_CODE; + // Cumulative value + req_ind->value.cumul_val = co_read24p(¶m->value[1]); + } + } + } break; + + case (LANP_LN_CTNL_PT_MASK_LSPEED_CHAR_CT): + { + // Check if the LN Masking feature is supported + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_LSPEED_CHAR_CT_MASKING_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = LANP_LN_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 3) + { + // The request can be handled + ind_status = LANP_LN_CTNL_PT_RESP_SUCCESS; + // Update the environment + lans_env->operation = LANS_MASK_LSPEED_CHAR_CT_OP_CODE; + // Mask content + req_ind->value.mask_content = co_read16p(¶m->value[1]); + } + } + } break; + + case (LANP_LN_CTNL_PT_NAVIGATION_CONTROL): + { + // Check if navigation feature is supported + if ((LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_NAVI_MASK)) && + (LANS_IS_NTF_IND_ENABLED(conidx, LANS_PRF_CFG_FLAG_NAVIGATION_NTF))) + { + // Provided parameter in not within the defined range + ind_status = LANP_LN_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 2) + { + if (param->value[1] <= 0x05) + { + // The request can be handled + ind_status = LANP_LN_CTNL_PT_RESP_SUCCESS; + // Update the environment + lans_env->operation = LANS_NAVIGATION_CONTROL_OP_CODE; + // Control value + req_ind->value.control_value = param->value[1]; + // Store value in the environment + LANS_SET_NAV_MODE(conidx, req_ind->value.control_value); + } + } + } + } break; + + case (LANP_LN_CTNL_PT_REQ_NUMBER_OF_ROUTES): + { + // Check if navigation feature is supported + if (LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_NAVI_MASK)) + { + // The request can be handled + ind_status = LANP_LN_CTNL_PT_RESP_SUCCESS; + // Update the environment + lans_env->operation = LANS_REQ_NUMBER_OF_ROUTES_OP_CODE; + } + } break; + + case (LANP_LN_CTNL_PT_REQ_NAME_OF_ROUTE): + { + // Check if navigation feature is supported + if (LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_NAVI_MASK)) + { + // Provided parameter in not within the defined range + ind_status = LANP_LN_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 3) + { + // The request can be handled + ind_status = LANP_LN_CTNL_PT_RESP_SUCCESS; + // Update the environment + lans_env->operation = LANS_REQ_NAME_OF_ROUTE_OP_CODE; + // Route number + req_ind->value.route_number = co_read16p(¶m->value[1]); + } + } + } break; + + case (LANP_LN_CTNL_PT_SELECT_ROUTE): + { + // Check if navigation feature is supported + if (LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_NAVI_MASK)) + { + // Provided parameter in not within the defined range + ind_status = LANP_LN_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 3) + { + // The request can be handled + ind_status = LANP_LN_CTNL_PT_RESP_SUCCESS; + // Update the environment + lans_env->operation = LANS_SELECT_ROUTE_OP_CODE; + // route number + req_ind->value.route_number = co_read16p(¶m->value[1]); + } + } + } break; + + case (LANP_LN_CTNL_PT_SET_FIX_RATE): + { + // Check if the LN Masking feature is supported + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_FIX_RATE_SETTING_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = LANP_LN_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 2) + { + // The request can be handled + ind_status = LANP_LN_CTNL_PT_RESP_SUCCESS; + // Update the environment + lans_env->operation = LANS_SET_FIX_RATE_OP_CODE; + // fix rate + req_ind->value.fix_rate = param->value[1]; + } + } + } break; + + case (LANP_LN_CTNL_PT_SET_ELEVATION): + { + // Check if the Chain Weight Adjustment feature is supported + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_ELEVATION_SETTING_SUPP)) + { + // Provided parameter in not within the defined range + ind_status = LANP_LN_CTNL_PT_RESP_INV_PARAM; + + if (param->length == 4) + { + // The request can be handled + ind_status = LANP_LN_CTNL_PT_RESP_SUCCESS; + // Update the environment + lans_env->operation = LANS_SET_ELEVATION_OP_CODE; + // elevation + req_ind->value.elevation = co_read24p(¶m->value[1]); + } + } + } break; + + default: + { + // Operation Code is invalid, status is already LAN_CTNL_PT_RESP_NOT_SUPP + } break; + } + + // If no error raised, inform the application about the request + if (ind_status == LANP_LN_CTNL_PT_RESP_SUCCESS) + { + // Send the request indication to the application + ke_msg_send(req_ind); + // Go to the Busy status + ke_state_set(prf_src_task_get(&(lans_env->prf_env), conidx), LANS_BUSY); + } + else + { + // Free the allocated message + ke_msg_free(ke_param2msg(req_ind)); + } + + return ind_status; +} + + + + +void lans_exe_operation(void) +{ + struct lans_env_tag* lans_env = PRF_ENV_GET(LANS, lans); + + ASSERT_ERR(lans_env->op_data != NULL); + + bool finished = true; + + while((lans_env->op_data->cursor < BLE_CONNECTION_MAX) && finished) + { + uint8_t conidx = lans_env->op_data->cursor; + + switch(lans_env->operation) + { + case LANS_NTF_LOC_SPEED_OP_CODE: + { + // notification is pending, send it first + if(lans_env->op_data->ntf_pending != NULL) + { + ke_msg_send(lans_env->op_data->ntf_pending); + lans_env->op_data->ntf_pending = NULL; + finished = false; + } + // Check if sending of notifications has been enabled + else if (LANS_IS_NTF_IND_ENABLED(conidx, LANS_PRF_CFG_FLAG_LOC_SPEED_NTF)) + { + struct lans_ntf_loc_speed_req *speed_cmd = + (struct lans_ntf_loc_speed_req *) ke_msg2param(lans_env->op_data->cmd); + + // Save flags value + uint16_t flags = speed_cmd->parameters.flags; + + // Mask unwanted fields if supported + if (LANS_IS_FEATURE_SUPPORTED(lans_env->features, LANP_FEAT_LSPEED_CHAR_CT_MASKING_SUPP)) + { + speed_cmd->parameters.flags &= ~lans_env->env[conidx].mask_lspeed_content; + } + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&(lans_env->prf_env),conidx), + gattc_send_evt_cmd, LANP_LAN_LOC_SPEED_MAX_LEN); + + // Fill in the parameter structure + meas_val->operation = GATTC_NOTIFY; + meas_val->handle = LANS_HANDLE(LNS_IDX_LOC_SPEED_VAL); + // pack measured value in database + meas_val->length = lans_pack_loc_speed_ntf(&speed_cmd->parameters, meas_val->value); + + if (meas_val->length > gattc_get_mtu(conidx) - 3) + { + // Split (if necessary) + lans_split_loc_speed_ntf(conidx, meas_val); + } + + // Restore flags value + speed_cmd->parameters.flags = flags; + + // Send the event + ke_msg_send(meas_val); + + finished = false; + } + + // update cursor only if all notification has been sent + if(lans_env->op_data->ntf_pending == NULL) + { + lans_env->op_data->cursor++; + } + } + break; + + case LANS_NTF_NAVIGATION_OP_CODE: + { + struct lans_ntf_navigation_req *nav_cmd = + (struct lans_ntf_navigation_req *) ke_msg2param(lans_env->op_data->cmd); + + // Check if sending of notifications has been enabled + if (LANS_IS_NTF_IND_ENABLED(conidx, LANS_PRF_CFG_FLAG_NAVIGATION_NTF) + // and if navigation is enabled + && LANS_IS_NAV_EN(conidx)) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&(lans_env->prf_env),conidx), + gattc_send_evt_cmd, LANP_LAN_NAVIGATION_MAX_LEN); + + // Fill in the parameter structure + meas_val->operation = GATTC_NOTIFY; + meas_val->handle = LANS_HANDLE(LNS_IDX_NAVIGATION_VAL); + // pack measured value in database + meas_val->length = lans_pack_navigation_ntf(&nav_cmd->parameters, meas_val->value); + + // Send the event + ke_msg_send(meas_val); + + finished = false; + } + + lans_env->op_data->cursor++; + } + break; + default: ASSERT_ERR(0); break; + } + } + + + // check if operation is finished + if(finished) + { + // send response to requester + struct lans_ntf_navigation_rsp * rsp = + KE_MSG_ALLOC(((lans_env->operation == LANS_NTF_NAVIGATION_OP_CODE) ? + LANS_NTF_NAVIGATION_RSP : LANS_NTF_LOC_SPEED_RSP), + lans_env->op_data->cmd->src_id, + lans_env->op_data->cmd->dest_id, + lans_ntf_navigation_rsp); + rsp->status = GAP_ERR_NO_ERROR; + ke_msg_send(rsp); + + // free operation data + ke_msg_free(lans_env->op_data->cmd); + ke_free(lans_env->op_data); + lans_env->op_data = NULL; + // Set the operation code + lans_env->operation = LANS_RESERVED_OP_CODE; + // go back to idle state + ke_state_set(prf_src_task_get(&(lans_env->prf_env), 0), LANS_IDLE); + } +} + +void lans_send_rsp_ind(uint8_t conidx, uint8_t req_op_code, uint8_t status) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ctl_pt_rsp = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), + prf_src_task_get(&lans_env->prf_env, conidx), + gattc_send_evt_cmd, LANP_LAN_LN_CNTL_PT_RSP_MIN_LEN); + + // Fill in the parameter structure + ctl_pt_rsp->operation = GATTC_INDICATE; + ctl_pt_rsp->handle = LANS_HANDLE(LNS_IDX_LN_CTNL_PT_VAL); + // Pack Control Point confirmation + ctl_pt_rsp->length = LANP_LAN_LN_CNTL_PT_RSP_MIN_LEN; + // Response Code + ctl_pt_rsp->value[0] = LANP_LN_CTNL_PT_RESPONSE_CODE; + // Request Operation Code + ctl_pt_rsp->value[1] = req_op_code; + // Response value + ctl_pt_rsp->value[2] = status; + + // Send the event + ke_msg_send(ctl_pt_rsp); +} + + +#endif //(BLE_LN_SENSOR) + +/// @} LANS diff --git a/services/ble_profiles/lan/lans/src/lans.h b/services/ble_profiles/lan/lans/src/lans.h new file mode 100644 index 0000000..70e0a07 --- /dev/null +++ b/services/ble_profiles/lan/lans/src/lans.h @@ -0,0 +1,372 @@ +#ifndef _LANS_H_ +#define _LANS_H_ + +/** + **************************************************************************************** + * @addtogroup LANS Location and Navigation Profile Sensor + * @ingroup LAN + * @brief Location and Navigation Profile Sensor + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_LN_SENSOR) +#include "lan_common.h" +#include "lans_task.h" +#include "prf_types.h" +#include "prf.h" +#include "attm.h" +#include "co_math.h" + +/* + * DEFINES + **************************************************************************************** + */ +/// Maximum number of Location and Navigation Profile Sensor role task instances +#define LANS_IDX_MAX (1) + +/******************************************** + ******* LANS Configuration Flag Masks ****** + ********************************************/ + +/// Mandatory Attributes (LN Feature + Location and Speed) +#define LANS_MANDATORY_MASK (0x003F) +/// Position quality Attribute +#define LANS_POS_Q_MASK (0x00C0) +/// Control Point Attributes +#define LANS_LN_CTNL_PT_MASK (0x0700) +/// Navigation Attributes +#define LANS_NAVI_MASK (0x3800) + + +/* + * MACROS + **************************************************************************************** + */ + +#define LANS_IS_FEATURE_SUPPORTED(features, flag) ((features & flag) == flag) + +#define LANS_IS_PRESENT(features, flag) ((features & flag) == flag) + +#define LANS_IS_SET(features, flag) (features & flag) + +#define LANS_IS_CLEAR(features, flag) ((features & flag) == 0) + +#define LANS_ENABLE_NTF_IND(idx, ccc_flag) (lans_env->env[idx].prfl_ntf_ind_cfg |= ccc_flag) + +#define LANS_DISABLE_NTF_IND(idx, ccc_flag) (lans_env->env[idx].prfl_ntf_ind_cfg &= ~ccc_flag) + +#define LANS_IS_NTF_IND_ENABLED(idx, ccc_flag) ((lans_env->env[idx].prfl_ntf_ind_cfg & ccc_flag) == ccc_flag) + +// Management of Navigation status +#define LANS_IS_NAV_EN(idx) ((lans_env->env[idx].nav_ctrl & 0x80) != 0) +#define LANS_SET_NAV_EN(idx, enable) \ + (lans_env->env[idx].nav_ctrl = ((lans_env->env[idx].nav_ctrl & 0x7F) | (enable << 7))) + +// Management of Navigation mode +#define LANS_GET_NAV_MODE(idx) (lans_env->env[idx].nav_ctrl & 0x7F) +#define LANS_SET_NAV_MODE(idx, mode) \ + (lans_env->env[idx].nav_ctrl = ((lans_env->env[idx].nav_ctrl & 0x8F) | (mode & 0x7F))) + + +// MACRO TO CALCULATE HANDLE shdl + idx - POSQ - CNTL PT +// POSQ is 2 if the Position quality is supported otherwise 0 +// CNTL PT is 3 if the CP characteristic is supported otherwise 0 +#define LANS_HANDLE(idx) \ + (lans_env->shdl + (idx) - \ + ((!(LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_POS_Q_MASK)) && \ + ((idx) > LNS_IDX_POS_Q_CHAR))? (2) : (0)) - \ + ((!(LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_LN_CTNL_PT_MASK)) && \ + ((idx) > LNS_IDX_LN_CTNL_PT_CHAR))? (3) : (0))) + +// Get database attribute index + #define LANS_IDX(hdl) \ + ((hdl - lans_env->shdl) + \ + ((!(LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_POS_Q_MASK)) && \ + ((hdl - lans_env->shdl) > LNS_IDX_POS_Q_CHAR)) ? (2) : (0)) + \ + ((!(LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_LN_CTNL_PT_MASK)) && \ + ((hdl - lans_env->shdl) > LNS_IDX_LN_CTNL_PT_CHAR)) ? (3) : (0))) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the LANS task +enum lans_state +{ + /// Idle state + LANS_IDLE, + /// Busy state + LANS_BUSY, + + /// Number of defined states. + LANS_STATE_MAX +}; + +/// Location and Navigation Service - Attribute List +enum lans_cps_att_list +{ + /// Location and Navigation Service + LNS_IDX_SVC, + /// LN Feature + LNS_IDX_LN_FEAT_CHAR, + LNS_IDX_LN_FEAT_VAL, + /// Location and Speed + LNS_IDX_LOC_SPEED_CHAR, + LNS_IDX_LOC_SPEED_VAL, + LNS_IDX_LOC_SPEED_NTF_CFG, + /// Position Quality + LNS_IDX_POS_Q_CHAR, + LNS_IDX_POS_Q_VAL, + /// LN Control Point + LNS_IDX_LN_CTNL_PT_CHAR, + LNS_IDX_LN_CTNL_PT_VAL, + LNS_IDX_LN_CTNL_PT_IND_CFG, + /// Navigation + LNS_IDX_NAVIGATION_CHAR, + LNS_IDX_NAVIGATION_VAL, + LNS_IDX_NAVIGATION_NTF_CFG, + + /// Number of attributes + LNS_IDX_NB, +}; + +/// Profile Configuration +enum lans_prf_cfg_flag +{ + /// Nothing supported + LANS_NOTHING_SUPP_FLAG = (0x00), + /// Control Point supported flag + LANS_CTNL_PT_CHAR_SUPP_FLAG = (0x01), + /// Broadcast supported flag + LANS_NAVIGATION_SUPP_FLAG = (0x02), +}; + + +/// Profile Configuration NTF/IND Flags () +enum lans_prf_cfg_ntfind_flag +{ + /// Location and Speed - Client Char. Cfg + LANS_PRF_CFG_FLAG_LOC_SPEED_NTF = 0x01, + + /// Control Point - Client Characteristic configuration + LANS_PRF_CFG_FLAG_LN_CTNL_PT_IND = 0x02, + + /// Navigation - Client Characteristic configuration + LANS_PRF_CFG_FLAG_NAVIGATION_NTF = 0x04, + + /// Bonded Data configured + LANS_PRF_CFG_PERFORMED_OK = 0x80 +}; + + + + +/* + * STRUCTURES + **************************************************************************************** + */ +/// ongoing operation information +struct lans_op +{ + /// On-going operation command + struct ke_msg * cmd; + /// notification pending + struct gattc_send_evt_cmd* ntf_pending; + + /// Cursor on connection + uint8_t cursor; +}; + +/// Location and Navigation environment variable per connection +struct lans_cnx_env +{ + /// Location an speed content mask + uint16_t mask_lspeed_content; + /// Profile Notify/Indication Flags + uint8_t prfl_ntf_ind_cfg; + /// LN Navigation Control parameter + uint8_t nav_ctrl; +}; + + +/// Location and Navigation Profile Sensor environment variable +struct lans_env_tag +{ + /// profile environment + prf_env_t prf_env; + + /// Environment variable pointer for each connections + struct lans_cnx_env env[BLE_CONNECTION_MAX]; + /// Position quality + struct lanp_posq *posq; + /// On-going operation + struct lans_op * op_data; + + /// Feature Configuration Flags + uint32_t features; + + /// Location and Navigation Service Start Handle + uint16_t shdl; + /// Profile Configuration Flags + uint16_t prfl_cfg; + /// Operation + uint8_t operation; + + /// State of different task instances + ke_state_t state[LANS_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Retrieve LAN service profile interface + * + * @return LAN service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* lans_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send a LANS_CMP_EVT message to the application. + * @param[in] conidx connection index + * @param[in] src_id Source task + * @param[in] dest_id Destination task + * @param[in] operation Operation completed + * @param[in] status status of the operation + **************************************************************************************** + */ +void lans_send_cmp_evt(uint8_t conidx, uint8_t src_id, uint8_t dest_id, uint8_t operation, uint8_t status); + +/** + **************************************************************************************** + * @brief Packs location and speed notifications + * @param[in] param Pointer to the parameters of the message. + * @param[out] pckd_loc_speed pointer to packed message + * @return status of the operation + **************************************************************************************** + */ +uint8_t lans_pack_loc_speed_ntf(struct lanp_loc_speed *param, uint8_t *pckd_loc_speed); + +/** + **************************************************************************************** + * @brief Packs navigation notifications + * @param[in] param Pointer to the parameters of the message. + * @param[out] pckd_navigation pointer to packed message + * @return length + **************************************************************************************** + */ +uint8_t lans_pack_navigation_ntf(struct lanp_navigation *param, uint8_t *pckd_navigation); + +/** + **************************************************************************************** + * @brief Splits notifications in order to be sent with default MTU + * @param[in] conidx connection index + * @param[in/out] loc_speed_ntf1 first notification + * @return length + **************************************************************************************** + */ +uint8_t lans_split_loc_speed_ntf(uint8_t conidx, struct gattc_send_evt_cmd *loc_speed_ntf1); + +/** + **************************************************************************************** + * @brief updates the environment with the descriptor configuration and sends indication + * @param[in] conidx connection index + * @param[in] prfl_config requested value + * @param[in] param pointer to the message parameters + * @return status of the operation + **************************************************************************************** + */ +uint8_t lans_update_characteristic_config(uint8_t conidx, uint8_t prfl_config, struct gattc_write_req_ind const *param); + +/** + **************************************************************************************** + * @brief Packs position quality + * @param[in] param Pointer to the parameters of the message. + **************************************************************************************** + */ +void lans_upd_posq(struct lanp_posq param); + +/** + **************************************************************************************** + * @brief Packs position quality + * @param[out] pckd_posq pointer to packed message + * @return length + **************************************************************************************** + */ +uint8_t lans_pack_posq(uint8_t *pckd_posq); + +/** + **************************************************************************************** + * @brief Packs control point + * @param[in] conidx connection index + * @param[in] param Pointer to the parameters of the message. + * @param[out] rsp pointer to message + * @return status of the operation + **************************************************************************************** + */ +uint8_t lans_pack_ln_ctnl_point_cfm (uint8_t conidx, struct lans_ln_ctnl_pt_cfm *param, uint8_t *rsp); + +/** + **************************************************************************************** + * @brief Unpack control point and sends indication + * @param[in] conidx connection index + * @param[in] param pointer to message + * @return status of the operation + **************************************************************************************** + */ +uint8_t lans_unpack_ln_ctnl_point_ind (uint8_t conidx, struct gattc_write_req_ind const *param); + +/** + **************************************************************************************** + * @brief This function fully manage notification of navigation and speed information + **************************************************************************************** + */ +void lans_exe_operation(void); + +/** + **************************************************************************************** + * @brief Send a control point response to the peer + * @param[in] conidx connection index + * @param[in] req_op_code operation code + * @param[in] status status of the operation + **************************************************************************************** + */ +void lans_send_rsp_ind(uint8_t conidx, uint8_t req_op_code, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void lans_task_init(struct ke_task_desc *task_desc); + +#endif //(BLE_LN_SENSOR) + +/// @} LANS + +#endif //(_LANS_H_) diff --git a/services/ble_profiles/lan/lans/src/lans_task.c b/services/ble_profiles/lan/lans/src/lans_task.c new file mode 100644 index 0000000..492f63d --- /dev/null +++ b/services/ble_profiles/lan/lans/src/lans_task.c @@ -0,0 +1,670 @@ +/** + **************************************************************************************** + * @addtogroup LANSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_LN_SENSOR) +#include "lan_common.h" + +#include "gapc.h" +#include "gattc.h" +#include "gattc_task.h" +#include "attm.h" +#include "lans.h" +#include "lans_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" +#include "co_math.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref LANS_ENABLE_REQ message. + * @param[in] msgid Id of the message received + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ + +__STATIC int lans_enable_req_handler(ke_msg_id_t const msgid, + struct lans_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(ke_state_get(dest_id) == LANS_IDLE) + { + // Bonded data was not used before + if (!LANS_IS_PRESENT(lans_env->env[param->conidx].prfl_ntf_ind_cfg, LANS_PRF_CFG_PERFORMED_OK)) + { + status = GAP_ERR_NO_ERROR; + lans_env->env[param->conidx].prfl_ntf_ind_cfg = param->prfl_ntf_ind_cfg; + } + // Enable Bonded Data + LANS_ENABLE_NTF_IND(param->conidx, LANS_PRF_CFG_PERFORMED_OK); + } + + // send completed information to APP task that contains error status + struct lans_enable_rsp *cmp_evt = KE_MSG_ALLOC(LANS_ENABLE_RSP, src_id, dest_id, lans_enable_rsp); + cmp_evt->status = status; + cmp_evt->conidx = param->conidx; + ke_msg_send(cmp_evt); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == LANS_IDLE) + { + // Pointer to the response message + struct gattc_read_cfm* cfm = NULL; + + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t att_idx = LANS_IDX(param->handle); + + uint8_t status = ATT_ERR_NO_ERROR; + + switch(att_idx) + { + case LNS_IDX_LN_FEAT_VAL: + { + // Allocate structure + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint32_t)); + cfm->length = sizeof(uint32_t); + // Fill data + co_write32p(cfm->value, lans_env->features); + } break; + + case LNS_IDX_POS_Q_VAL: + { + // Check if Position Quality Char. has been added in the database + if (LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_POS_Q_MASK)) + { + // Allocate structure + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(struct lanp_posq)); + // Fill data + cfm->length = lans_pack_posq(cfm->value); + } + else + { + status = PRF_ERR_FEATURE_NOT_SUPPORTED; + } + + } break; + + case LNS_IDX_LOC_SPEED_NTF_CFG: + { + // allocate structure + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->length = sizeof(uint16_t); + // Fill data + co_write16p(cfm->value, (lans_env->env[conidx].prfl_ntf_ind_cfg & LANS_PRF_CFG_FLAG_LOC_SPEED_NTF) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + } break; + + case LNS_IDX_NAVIGATION_NTF_CFG: + { + // Check if Navigation Char. has been added in the database + if (LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_NAVI_MASK)) + { + // allocate structure + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->length = sizeof(uint16_t); + co_write16p(cfm->value, (lans_env->env[conidx].prfl_ntf_ind_cfg & LANS_PRF_CFG_FLAG_NAVIGATION_NTF) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + } + else + { + status = PRF_ERR_FEATURE_NOT_SUPPORTED; + } + } break; + + case LNS_IDX_LN_CTNL_PT_IND_CFG: + { + // Check if LN control point has been added in the database + if (LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_LN_CTNL_PT_MASK)) + { + // allocate structure + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->length = sizeof(uint16_t); + // Fill data + co_write16p(cfm->value, (lans_env->env[conidx].prfl_ntf_ind_cfg & LANS_PRF_CFG_FLAG_LN_CTNL_PT_IND) + ? PRF_CLI_START_IND : PRF_CLI_STOP_NTFIND); + } + else + { + status = PRF_ERR_FEATURE_NOT_SUPPORTED; + } + } break; + + default: + { + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } break; + } + + if (status != ATT_ERR_NO_ERROR) + { + cfm = KE_MSG_ALLOC(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm); + cfm->length = 0; + } + + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == LANS_IDLE) + { + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + uint8_t att_idx = LANS_IDX(param->handle); + struct gattc_att_info_cfm * cfm; + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + // check if it's a client configuration char + if((att_idx == LNS_IDX_LOC_SPEED_NTF_CFG) + || (att_idx == LNS_IDX_NAVIGATION_NTF_CFG) + || (att_idx == LNS_IDX_LN_CTNL_PT_IND_CFG)) + { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } + else if (att_idx == LNS_IDX_LN_CTNL_PT_VAL) + { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } + // not expected request + else + { + cfm->length = 0; + cfm->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref LANS_NTF_LN_MEAS_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int lans_ntf_loc_speed_req_handler(ke_msg_id_t const msgid, + struct lans_ntf_loc_speed_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_NO_FREE; + + // State shall be Connected or Busy + if (ke_state_get(dest_id) == LANS_IDLE) + { + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + + // Configure the environment + lans_env->operation = LANS_NTF_LOC_SPEED_OP_CODE; + // allocate operation data + lans_env->op_data = (struct lans_op*) ke_malloc(sizeof(struct lans_op), KE_MEM_KE_MSG); + lans_env->op_data->cmd = ke_param2msg(param); + lans_env->op_data->cursor = 0; + lans_env->op_data->ntf_pending = NULL; + + // Go to busy state + ke_state_set(dest_id, LANS_BUSY); + + // start operation execution + lans_exe_operation(); + } + else + { + // Save it for later + msg_status = KE_MSG_SAVED; + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref LANS_UPD_POS_Q_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int lans_upd_pos_q_req_handler(ke_msg_id_t const msgid, + struct lans_upd_pos_q_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + // Allocate response message + struct lans_upd_pos_q_rsp *rsp = KE_MSG_ALLOC(LANS_UPD_POS_Q_RSP, + src_id, dest_id, lans_upd_pos_q_rsp); + rsp->status = PRF_ERR_FEATURE_NOT_SUPPORTED; + + // Check if Position Quality Char. has been added in the database + if (LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_POS_Q_MASK)) + { + if (lans_env->posq != NULL) + { + // Update position quality + lans_upd_posq(param->parameters); + // Set status value + rsp->status = GAP_ERR_NO_ERROR; + } + else + { + // Set status value + rsp->status = PRF_APP_ERROR; + } + } + + // Send response to the application + ke_msg_send(rsp); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref LANS_NTF_NAVIGATION_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int lans_ntf_navigation_req_handler(ke_msg_id_t const msgid, + struct lans_ntf_navigation_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_NO_FREE; + + // State shall be Connected or Busy + if (ke_state_get(dest_id) == LANS_IDLE) + { + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + + + // Configure the environment + lans_env->operation = LANS_NTF_NAVIGATION_OP_CODE; + // allocate operation data + lans_env->op_data = (struct lans_op*) ke_malloc(sizeof(struct lans_op), KE_MEM_KE_MSG); + lans_env->op_data->cmd = ke_param2msg(param); + lans_env->op_data->cursor = 0; + lans_env->op_data->ntf_pending = NULL; + + // Go to busy state + ke_state_set(dest_id, LANS_BUSY); + + // start operation execution + lans_exe_operation(); + } + else + { + // Save it for later + msg_status = KE_MSG_SAVED; + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref LANS_LN_CTNL_PT_CFM message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int lans_ln_ctnl_pt_cfm_handler(ke_msg_id_t const msgid, + struct lans_ln_ctnl_pt_cfm *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + uint8_t status = GAP_ERR_NO_ERROR; + + if (ke_state_get(dest_id) == LANS_BUSY) + { + do + { + // Check the current operation + if (lans_env->operation < LANS_SET_CUMUL_VALUE_OP_CODE) + { + // The confirmation has been sent without request indication, ignore + break; + } + + // The LN Control Point Characteristic must be supported if we are here + if (!LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_LN_CTNL_PT_MASK)) + { + status = PRF_ERR_REQ_DISALLOWED; + break; + } + + // Check if sending of indications has been enabled + if (!LANS_IS_NTF_IND_ENABLED(param->conidx, LANS_PRF_CFG_FLAG_LN_CTNL_PT_IND)) + { + // CCC improperly configured + status = PRF_CCCD_IMPR_CONFIGURED; + break; + } + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ctl_pt_rsp = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, param->conidx), dest_id, + gattc_send_evt_cmd, LANP_LAN_LN_CNTL_PT_RSP_MAX_LEN); + + // Fill in the parameter structure + ctl_pt_rsp->operation = GATTC_INDICATE; + ctl_pt_rsp->handle = LANS_HANDLE(LNS_IDX_LN_CTNL_PT_VAL); + // Pack Control Point confirmation + ctl_pt_rsp->length = lans_pack_ln_ctnl_point_cfm (param->conidx, param, ctl_pt_rsp->value); + + // Send the event + ke_msg_send(ctl_pt_rsp); + + } while (0); + + if (status != GAP_ERR_NO_ERROR) + { + // Inform the application that a procedure has been completed + lans_send_cmp_evt(param->conidx, + prf_src_task_get(&lans_env->prf_env, param->conidx), + prf_dst_task_get(&lans_env->prf_env, param->conidx), + lans_env->operation, status); + } + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_WRITE_REQ_IND message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + uint8_t conidx = KE_IDX_GET(src_id); + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Control Point Status + uint8_t ctl_pt_status = LANP_LN_CTNL_PT_RESP_SUCCESS; + + if (lans_env != NULL) + { + // Location and speed Characteristic, Client Characteristic Configuration Descriptor + if (param->handle == (LANS_HANDLE(LNS_IDX_LOC_SPEED_NTF_CFG))) + { + // Update value + status = lans_update_characteristic_config(conidx, LANS_PRF_CFG_FLAG_LOC_SPEED_NTF, param); + } + + // Navigation Characteristic, Client Characteristic Configuration Descriptor + else if (param->handle == (LANS_HANDLE(LNS_IDX_NAVIGATION_NTF_CFG))) + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_NAVI_MASK)) + { + // Update value + status = lans_update_characteristic_config(conidx, LANS_PRF_CFG_FLAG_NAVIGATION_NTF, param); + } + else + { + status = ATT_ERR_ATTRIBUTE_NOT_FOUND; + } + } + // LN Control Point Characteristic + else + { + if (LANS_IS_FEATURE_SUPPORTED(lans_env->prfl_cfg, LANS_LN_CTNL_PT_MASK)) + { + // LN Control Point, Client Characteristic Configuration Descriptor + if (param->handle == (LANS_HANDLE(LNS_IDX_LN_CTNL_PT_IND_CFG))) + { + // Update value + status = lans_update_characteristic_config(conidx, LANS_PRF_CFG_FLAG_LN_CTNL_PT_IND, param); + } + // LN Control Point Characteristic + else if (param->handle == (LANS_HANDLE(LNS_IDX_LN_CTNL_PT_VAL))) + { + do + { + // Check if sending of indications has been enabled + if (!LANS_IS_NTF_IND_ENABLED(conidx, LANS_PRF_CFG_FLAG_LN_CTNL_PT_IND)) + { + // CCC improperly configured + status = PRF_CCCD_IMPR_CONFIGURED; + break; + } + + if (lans_env->operation >= LANS_SET_CUMUL_VALUE_OP_CODE) + { + // A procedure is already in progress + status = LAN_ERROR_PROC_IN_PROGRESS; + break; + } + + if (lans_env->operation == LANS_NTF_LOC_SPEED_OP_CODE) + { + // Keep the message until the end of the current procedure + msg_status = KE_MSG_SAVED; + break; + } + + // Unpack Control Point parameters + ctl_pt_status = lans_unpack_ln_ctnl_point_ind (conidx, param); + + } while (0); + } + else + { + ASSERT_ERR(0); + } + } + else + { + status = ATT_ERR_ATTRIBUTE_NOT_FOUND; + } + } + } + + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + + // Check if control point failed + if ((param->handle == (LANS_HANDLE(LNS_IDX_LN_CTNL_PT_VAL))) && + (ctl_pt_status != LANP_LN_CTNL_PT_RESP_SUCCESS)) + { + // Send response to peer + lans_send_rsp_ind(conidx, param->value[0], ctl_pt_status); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles @ref GATT_NOTIFY_CMP_EVT message meaning that a notification or an indication + * has been correctly sent to peer device (but not confirmed by peer device). + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(src_id); + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + // Check if a connection exists + if (ke_state_get(dest_id) == LANS_BUSY) + { + switch (param->operation) + { + case (GATTC_NOTIFY): + { + lans_exe_operation(); + // else ignore the message + } break; + + case (GATTC_INDICATE): + { + ASSERT_ERR(lans_env->operation >= LANS_SET_CUMUL_VALUE_OP_CODE); + + // Inform the application that a procedure has been completed + lans_send_cmp_evt(conidx, prf_src_task_get(&(lans_env->prf_env), conidx), prf_dst_task_get(&(lans_env->prf_env), conidx), + lans_env->operation, param->status); + // else ignore the message + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(lans) +{ + {LANS_ENABLE_REQ, (ke_msg_func_t)lans_enable_req_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t)gattc_read_req_ind_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler}, + {LANS_NTF_LOC_SPEED_REQ, (ke_msg_func_t)lans_ntf_loc_speed_req_handler}, + {LANS_UPD_POS_Q_REQ, (ke_msg_func_t)lans_upd_pos_q_req_handler}, + {LANS_NTF_NAVIGATION_REQ, (ke_msg_func_t)lans_ntf_navigation_req_handler}, + {LANS_LN_CTNL_PT_CFM, (ke_msg_func_t)lans_ln_ctnl_pt_cfm_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t)gattc_write_req_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void lans_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct lans_env_tag *lans_env = PRF_ENV_GET(LANS, lans); + + task_desc->msg_handler_tab = lans_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(lans_msg_handler_tab); + task_desc->state = lans_env->state; + task_desc->idx_max = LANS_IDX_MAX; +} + +#endif //(BLE_LN_SENSOR) + +/// @} LANSTASK diff --git a/services/ble_profiles/ota/ota.c b/services/ble_profiles/ota/ota.c new file mode 100644 index 0000000..68a6e86 --- /dev/null +++ b/services/ble_profiles/ota/ota.c @@ -0,0 +1,207 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_OTA) +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "gapc_task.h" +#include "ota.h" +#include "ota_task.h" +#include "prf_utils.h" +#include "ke_mem.h" +#include "co_utils.h" +#include "ota_bes.h" +#ifdef __GATT_OVER_BR_EDR__ +#include "app_btgatt.h" +#endif + +/* + * OTA CMD PROFILE ATTRIBUTES + **************************************************************************************** + */ + +static const uint8_t OTA_SERVICE_UUID_128[ATT_UUID_128_LEN] = BES_OTA_UUID_128; + +#define RD_PERM PERM(RD, ENABLE) +#define VAL_PERM PERM(WRITE_REQ, ENABLE) | PERM(NTF, ENABLE) +#define NTF_CFG_PERM PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE) + +/// Full OTA SERVER Database Description - Used to add attributes into the database +const struct attm_desc_128 ota_att_db[OTA_IDX_NB] = +{ + // OTA Service Declaration + [OTA_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE_UUID, RD_PERM, 0, 0}, + // OTA Characteristic Declaration + [OTA_IDX_CHAR] = {ATT_DECL_CHARACTERISTIC_UUID, RD_PERM, 0, 0}, + // OTA service + [OTA_IDX_VAL] = {ota_val_char_val_uuid_128_content, VAL_PERM, PERM(RI, ENABLE) | PERM_VAL(UUID_LEN, PERM_UUID_128), OTA_MAX_LEN}, + // OTA Characteristic + [OTA_IDX_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG_UUID, NTF_CFG_PERM, 0, 0}, + +}; + + +/** + **************************************************************************************** + * @brief Initialization of the OTA module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t ota_init(struct prf_task_env* env, uint16_t* start_hdl, + uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t status; + + //Add Service Into Database + status = attm_svc_create_db_128(start_hdl, OTA_SERVICE_UUID_128, NULL, + OTA_IDX_NB, NULL, env->task, &ota_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS))| PERM(SVC_MI, DISABLE) + | PERM_VAL(SVC_UUID_LEN, PERM_UUID_128)); + + + BLE_GATT_DBG("attm_svc_create_db_128 returns %d start handle is %d", status, *start_hdl); + +#ifdef __GATT_OVER_BR_EDR__ + app_btgatt_addsdp(ATT_SERVICE_UUID, *start_hdl, *start_hdl+OTA_IDX_NB-1); +#endif + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // Allocate OTA required environment variable + struct ota_env_tag* ota_env = + (struct ota_env_tag* ) ke_malloc(sizeof(struct ota_env_tag), KE_MEM_ATT_DB); + + // Initialize OTA environment + env->env = (prf_env_t*) ota_env; + ota_env->shdl = *start_hdl; + + ota_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Mono Instantiated task + ota_env->prf_env.prf_task = env->task | + (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + + // initialize environment variable + env->id = TASK_ID_OTA; + ota_task_init(&(env->desc)); + + /* Put HRS in Idle state */ + ke_state_set(env->task, OTA_IDLE); + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the OTA module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void ota_destroy(struct prf_task_env* env) +{ + struct ota_env_tag* ota_env = (struct ota_env_tag*) env->env; + + // free profile environment variables + env->env = NULL; + ke_free(ota_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void ota_create(struct prf_task_env* env, uint8_t conidx) +{ + struct ota_env_tag* ota_env = (struct ota_env_tag*) env->env; + struct prf_svc ota_ota_svc = {ota_env->shdl, ota_env->shdl + OTA_IDX_NB}; + prf_register_atthdl2gatt(env->env, conidx, &ota_ota_svc); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void ota_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + /* Nothing to do */ +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// OTA Task interface required by profile manager +const struct prf_task_cbs ota_itf = +{ + (prf_init_fnct) ota_init, + ota_destroy, + ota_create, + ota_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* ota_prf_itf_get(void) +{ + return &ota_itf; +} + + +#endif /* BLE_OTA */ + +/// @} OTA + diff --git a/services/ble_profiles/ota/ota.h b/services/ble_profiles/ota/ota.h new file mode 100644 index 0000000..68d7cd8 --- /dev/null +++ b/services/ble_profiles/ota/ota.h @@ -0,0 +1,151 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef _OTA_H_ +#define _OTA_H_ + +/** + **************************************************************************************** + * @addtogroup OTA Datapath Profile Server + * @ingroup OTAP + * @brief Datapath Profile Server + * + * Datapath Profile Server provides functionalities to upper layer module + * application. The device using this profile takes the role of Datapath Server. + * + * The interface of this role to the Application is: + * - Enable the profile role (from APP) + * - Disable the profile role (from APP) + * - Send data to peer device via notifications (from APP) + * - Receive data from peer device via write no response (from APP) + * + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_OTA) +#include "prf_types.h" +#include "prf.h" +#include "ota_task.h" +#include "attm.h" +#include "prf_utils.h" + + +/* + * DEFINES + **************************************************************************************** + */ +#define OTA_MAX_LEN (509) + +/* + * DEFINES + **************************************************************************************** + */ +/// Possible states of the OTA task +enum +{ + /// Idle state + OTA_IDLE, + /// Connected state + OTA_BUSY, + + /// Number of defined states. + OTA_STATE_MAX, +}; + +///Attributes State Machine +enum +{ + OTA_IDX_SVC, + + OTA_IDX_CHAR, + OTA_IDX_VAL, + OTA_IDX_NTF_CFG, + + OTA_IDX_NB, +}; + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Datapath Profile Server environment variable +struct ota_env_tag +{ + /// profile environment + prf_env_t prf_env; + uint8_t isNotificationEnabled[BLE_CONNECTION_MAX]; + /// Service Start Handle + uint16_t shdl; + /// State of different task instances + ke_state_t state; +}; + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve HRP service profile interface + * + * @return HRP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* ota_prf_itf_get(void); + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void ota_task_init(struct ke_task_desc *task_desc); + + + +#endif /* #if (BLE_OTA) */ + +/// @} OTA + +#endif /* _OTA_H_ */ + diff --git a/services/ble_profiles/ota/ota_task.c b/services/ble_profiles/ota/ota_task.c new file mode 100644 index 0000000..c4b2167 --- /dev/null +++ b/services/ble_profiles/ota/ota_task.c @@ -0,0 +1,429 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +/** + **************************************************************************************** + * @addtogroup OTATASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_OTA) +#include "gap.h" +#include "gattc_task.h" +#include "gapc_task.h" +#include "attm.h" +#include "ota.h" +#include "ota_task.h" + +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ +static int gapc_disconnect_ind_handler(ke_msg_id_t const msgid, + struct gapc_disconnect_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(src_id); + struct ota_env_tag *ota_env = PRF_ENV_GET(OTA, ota); + ota_env->isNotificationEnabled[conidx] = false; + return KE_MSG_CONSUMED; +} + +void app_ota_send_rx_cfm(uint8_t conidx) +{ + struct ota_env_tag *ota_env = PRF_ENV_GET(OTA, ota); + + struct gattc_write_cfm *cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, + KE_BUILD_ID(TASK_GATTC, conidx), + prf_src_task_get(&ota_env->prf_env, conidx), + gattc_write_cfm); + cfm->handle = ota_env->shdl + OTA_IDX_VAL; + cfm->status = GAP_ERR_NO_ERROR; + ke_msg_send(cfm); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. + * The handler compares the new values with current ones and notifies them if they changed. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct ota_env_tag *ota_env = PRF_ENV_GET(OTA, ota); + uint8_t conidx = KE_IDX_GET(src_id); + + uint8_t status = GAP_ERR_NO_ERROR; + + BLE_GATT_DBG("gattc_write_req_ind_handler ota_env 0x%x write handle %d shdl %d", + ota_env, param->handle, ota_env->shdl); + +#if 0 //reply write-response so fast which results in rx queue oveflow + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); +#endif + + if (ota_env != NULL) + { + if (param->handle == (ota_env->shdl + OTA_IDX_NTF_CFG)) + { + uint16_t value = 0x0000; + struct gattc_write_cfm *cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + + //Extract value before check + memcpy(&value, &(param->value), sizeof(uint16_t)); + + if (value == PRF_CLI_STOP_NTFIND) + { + ota_env->isNotificationEnabled[conidx] = false; + } + else if (value == PRF_CLI_START_NTF) + { + ota_env->isNotificationEnabled[conidx] = true; + } + else + { + status = PRF_APP_ERROR; + } + + if (status == GAP_ERR_NO_ERROR) + { + //Inform APP of TX ccc change + struct ble_ota_tx_notif_config_t * ind = KE_MSG_ALLOC(OTA_CCC_CHANGED, + prf_dst_task_get(&ota_env->prf_env, conidx), + prf_src_task_get(&ota_env->prf_env, conidx), + ble_ota_tx_notif_config_t); + + ind->isNotificationEnabled = ota_env->isNotificationEnabled[conidx]; + + ke_msg_send(ind); + } + } + else if (param->handle == (ota_env->shdl + OTA_IDX_VAL)) + { + TRACE(1,"[OTA] ble cmd %x",param->value[0]); + //inform APP of data + struct ble_ota_rx_data_ind_t * ind = KE_MSG_ALLOC_DYN(OTA_DATA_RECEIVED, + prf_dst_task_get(&ota_env->prf_env, conidx), + prf_src_task_get(&ota_env->prf_env, conidx), + ble_ota_rx_data_ind_t, + sizeof(struct ble_ota_rx_data_ind_t) + param->length); + + ind->length = param->length; + memcpy((uint8_t *)(ind->data), &(param->value), param->length); + + ke_msg_send(ind); + + return KE_MSG_CONSUMED; + } + else + { + status = PRF_APP_ERROR; + } + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY message meaning that Measurement + * notification has been correctly sent to peer device (but not confirmed by peer device). + * * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + // Get the address of the environment + struct ota_env_tag *ota_env = PRF_ENV_GET(OTA, ota); + + uint8_t conidx = KE_IDX_GET(dest_id); + + // notification or write request has been sent out + if ((GATTC_NOTIFY == param->operation) || (GATTC_INDICATE == param->operation)) + { + + struct ble_ota_tx_sent_ind_t * ind = KE_MSG_ALLOC(OTA_TX_DATA_SENT, + prf_dst_task_get(&ota_env->prf_env, conidx), + prf_src_task_get(&ota_env->prf_env, conidx), + ble_ota_tx_sent_ind_t); + + ind->status = param->status; + + ke_msg_send(ind); + + } + + ke_state_set(dest_id, OTA_IDLE); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct ota_env_tag *ota_env = PRF_ENV_GET(OTA, ota); + + struct gattc_read_cfm* cfm; + + uint8_t status = GAP_ERR_NO_ERROR; + uint8_t conidx = KE_IDX_GET(src_id); + + BLE_GATT_DBG("gattc_read_req_ind_handler read handle %d shdl %d", param->handle, ota_env->shdl); + + if (param->handle == (ota_env->shdl + OTA_IDX_NTF_CFG)) + { + uint16_t notify_ccc; + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(notify_ccc)); + + if (ota_env->isNotificationEnabled[conidx]) + { + notify_ccc = 1; + } + else + { + notify_ccc = 0; + } + cfm->length = sizeof(notify_ccc); + memcpy(cfm->value, (uint8_t *)¬ify_ccc, cfm->length); + } + else + { + cfm = KE_MSG_ALLOC(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm); + cfm->length = 0; + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } + + cfm->handle = param->handle; + + cfm->status = status; + + ke_msg_send(cfm); + + ke_state_set(dest_id, OTA_IDLE); + + return (KE_MSG_CONSUMED); +} + +static void send_notifiction(uint8_t conidx, const uint8_t* ptrData, uint32_t length) +{ + uint16_t handle_offset = 0xFFFF; + struct ota_env_tag *ota_env = PRF_ENV_GET(OTA, ota); + + if (ota_env->isNotificationEnabled[conidx]) + { + handle_offset = OTA_IDX_VAL; + } + + TRACE(1,"Send ota notificationto handle offset %d:", handle_offset); + DUMP8("%02x ", ptrData, length); + + + if (0xFFFF != handle_offset) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *report_ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&ota_env->prf_env, conidx), + gattc_send_evt_cmd, length); + + // Fill in the parameter structure + report_ntf->operation = GATTC_NOTIFY; + report_ntf->handle = ota_env->shdl + handle_offset; + // pack measured value in database + report_ntf->length = length; + memcpy(report_ntf->value, ptrData, length); + // send notification to peer device + ke_msg_send(report_ntf); + } +} + +static void send_indication(uint8_t conidx, const uint8_t* ptrData, uint32_t length) +{ + uint16_t handle_offset = 0xFFFF; + struct ota_env_tag *ota_env = PRF_ENV_GET(OTA, ota); + + if (ota_env->isNotificationEnabled[conidx]) + { + handle_offset = OTA_IDX_VAL; + } + + if (0xFFFF != handle_offset) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *report_ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&ota_env->prf_env, conidx), + gattc_send_evt_cmd, length); + + // Fill in the parameter structure + report_ntf->operation = GATTC_INDICATE; + report_ntf->handle = ota_env->shdl + handle_offset; + // pack measured value in database + report_ntf->length = length; + memcpy(report_ntf->value, ptrData, length); + // send notification to peer device + ke_msg_send(report_ntf); + } +} + +__STATIC int send_notification_handler(ke_msg_id_t const msgid, + struct ble_ota_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + send_notifiction(param->connecionIndex, param->value, param->length); + return (KE_MSG_CONSUMED); +} + +__STATIC int send_indication_handler(ke_msg_id_t const msgid, + struct ble_ota_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + send_indication(param->connecionIndex, param->value, param->length); + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct gattc_att_info_cfm * cfm; + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + struct ota_env_tag *ota_env = PRF_ENV_GET(OTA, ota); + + if (param->handle == (ota_env->shdl + OTA_IDX_NTF_CFG)) + { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } + else if (param->handle == (ota_env->shdl + OTA_IDX_VAL)) + { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } + else + { + cfm->length = 0; + cfm->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/* Default State handlers definition. */ +KE_MSG_HANDLER_TAB(ota) +{ + {GAPC_DISCONNECT_IND, (ke_msg_func_t) gapc_disconnect_ind_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {OTA_SEND_NOTIFICATION, (ke_msg_func_t) send_notification_handler}, + {OTA_SEND_INDICATION, (ke_msg_func_t) send_indication_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler }, +}; + +void ota_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct ota_env_tag *ota_env = PRF_ENV_GET(OTA, ota); + + task_desc->msg_handler_tab = ota_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(ota_msg_handler_tab); + task_desc->state = &(ota_env->state); + task_desc->idx_max = BLE_CONNECTION_MAX; +} + +#endif /* #if (BLE_OTA) */ + +/// @} OTATASK diff --git a/services/ble_profiles/ota/ota_task.h b/services/ble_profiles/ota/ota_task.h new file mode 100644 index 0000000..b799510 --- /dev/null +++ b/services/ble_profiles/ota/ota_task.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +#ifndef _OTA_TASK_H_ +#define _OTA_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup OTATASK Task + * @ingroup OTA + * @brief OTA Profile Task. + * + * The OTATASK is responsible for handling the messages coming in and out of the + * @ref OTA collector block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include "rwip_task.h" // Task definitions + +/* + * DEFINES + **************************************************************************************** + */ +#define OTA_CONTENT_TYPE_COMMAND 0 +#define OTA_CONTENT_TYPE_DATA 1 + +/// Messages for OTA Profile +enum ota_msg_id +{ + OTA_CCC_CHANGED = TASK_FIRST_MSG(TASK_ID_OTA), + + OTA_TX_DATA_SENT, + + OTA_DATA_RECEIVED, + + OTA_SEND_NOTIFICATION, + + OTA_SEND_INDICATION, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +struct ble_ota_tx_notif_config_t +{ + bool isNotificationEnabled; +}; + +struct ble_ota_rx_data_ind_t +{ + uint16_t length; + uint8_t data[0]; +}; + +struct ble_ota_tx_sent_ind_t +{ + uint8_t status; +}; + +struct ble_ota_send_data_req_t +{ + uint8_t connecionIndex; + uint32_t length; + uint8_t value[__ARRAY_EMPTY]; +}; + + +/// @} OTATASK + +#endif /* _OTA_TASK_H_ */ + diff --git a/services/ble_profiles/pasp/pasp_common.h b/services/ble_profiles/pasp/pasp_common.h new file mode 100644 index 0000000..70a3fc5 --- /dev/null +++ b/services/ble_profiles/pasp/pasp_common.h @@ -0,0 +1,41 @@ +#ifndef _PASP_COMMON_H_ +#define _PASP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup PASP Phone Alert Status Profile + * @ingroup PROFILE + * @brief Phone Alert Status Profile + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +/* + * DEFINES + **************************************************************************************** + */ + +/// Alert Status Flags +#define PASP_RINGER_ACTIVE (0x01) +#define PASP_VIBRATE_ACTIVE (0x02) +#define PASP_DISP_ALERT_STATUS_ACTIVE (0x04) +#define PASP_ALERT_STATUS_VAL_MAX (0x07) + +/// Ringer Settings Keys +#define PASP_RINGER_SILENT (0) +#define PASP_RINGER_NORMAL (1) + +/// Ringer Control Point Keys +#define PASP_SILENT_MODE (1) +#define PASP_MUTE_ONCE (2) +#define PASP_CANCEL_SILENT_MODE (3) + + +/// @} pasp_common + +#endif //(_HTP_COMMON_H_) diff --git a/services/ble_profiles/pasp/paspc/api/paspc_task.h b/services/ble_profiles/pasp/paspc/api/paspc_task.h new file mode 100644 index 0000000..19e48e6 --- /dev/null +++ b/services/ble_profiles/pasp/paspc/api/paspc_task.h @@ -0,0 +1,188 @@ +#ifndef _PASPC_TASK_H_ +#define _PASPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup PASPCTASK Phone Alert Status Profile Client Task + * @ingroup PASPC + * @brief Phone Alert Status Profile Client Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "pasp_common.h" +#include "rwip_task.h" // Task definitions +#include "prf_types.h" + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Message IDs +enum paspc_msg_ids +{ + /// Enable the Phone Alert Status Profile Client task - at connection + PASPC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_PASPC), + /// Enable the Phone Alert Status Profile Client task - at connection + PASPC_ENABLE_RSP, + + /// Read the value of an attribute in the peer device database + PASPC_READ_CMD, + /// Write the value of an attribute in the peer device database + PASPC_WRITE_CMD, + + /// Indicate that an attribute value has been received either upon notification or read response + PASPC_VALUE_IND, + + /// Complete Event Information + PASPC_CMP_EVT, +}; + +/// Operation Codes +enum paspc_op_codes +{ + /// Reserved operation code + PASPC_RESERVED_OP_CODE = 0x00, + + /// Discovery Procedure + PASPC_ENABLE_OP_CODE, + /// Read attribute value Procedure + PASPC_READ_OP_CODE, + /// Write attribute value Procedure + PASPC_WRITE_OP_CODE, +}; + +/* + * API MESSAGE STRUCTURES + **************************************************************************************** + */ + +/// Phone Alert Status Service Characteristics +enum +{ + /// Alert Status + PASPC_CHAR_ALERT_STATUS, + /// Ringer Setting + PASPC_CHAR_RINGER_SETTING, + /// Ringer Control Point + PASPC_CHAR_RINGER_CTNL_PT, + + PASPC_CHAR_MAX, +}; + +/// Phone Alert Status Service Characteristic Descriptors +enum +{ + /// Alert Status Char. - Client Characteristic Configuration + PASPC_DESC_ALERT_STATUS_CL_CFG, + /// Ringer Setting Char. - Client Characteristic Configuration + PASPC_DESC_RINGER_SETTING_CL_CFG, + + PASPC_DESC_MAX, + + PASPC_DESC_MASK = 0x10, +}; + +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Phone Alert Status Service + */ +struct paspc_pass_content +{ + /// Service info + struct prf_svc svc; + + /// Characteristic info: + /// - Alert Status + /// - Ringer Setting + /// - Ringer Control Point + struct prf_char_inf chars[PASPC_CHAR_MAX]; + + /// Descriptor handles: + /// - Alert Status Client Cfg + /// - Ringer Setting Client Cfg + struct prf_char_desc_inf descs[PASPC_DESC_MAX]; +}; + + +/// Parameters of the @ref PASPC_ENABLE_REQ message +struct paspc_enable_req +{ + /// Connection type + uint8_t con_type; + /// Existing handle values PASS + struct paspc_pass_content pass; +}; + +/// Parameters of the @ref PASPC_ENABLE_RSP message +struct paspc_enable_rsp +{ + /// status + uint8_t status; + /// Existing handle values PASS + struct paspc_pass_content pass; +}; + +/// Parameters of the @ref PASPC_READ_CMD message +struct paspc_read_cmd +{ + /// Read code + uint8_t read_code; +}; + +/// Parameters of the @ref PASPC_WRITE_CMD message +struct paspc_write_cmd +{ + /// Write code + uint8_t write_code; + /// Value + union write_value_tag + { + /// Ringer Control Point characteristic value + uint8_t ringer_ctnl_pt; + /// Alert Status characteristic client characteristic configuration value + uint16_t alert_status_ntf_cfg; + /// Ringer Setting characteristic client characteristic configuration value + uint16_t ringer_setting_ntf_cfg; + } value; +}; + +/// Parameters of the @ref PASPC_VALUE_IND message +struct paspc_value_ind +{ + /// Attribute Code + uint8_t att_code; + /// Value + union value_tag + { + /// Alert Status characteristic value + uint8_t alert_status; + /// Ringer Setting characteristic value + uint8_t ringer_setting; + /// Alert Status characteristic client characteristic configuration value + uint16_t alert_status_ntf_cfg; + /// Ringer Setting characteristic client characteristic configuration value + uint16_t ringer_setting_ntf_cfg; + } value; +}; + +/// Parameters of the @ref PASPC_CMP_EVT message +struct paspc_cmp_evt +{ + /// Operation code + uint8_t operation; + /// Status + uint8_t status; +}; + + +/// @} PASPCTASK + +#endif //(_PASPC_TASK_H_) diff --git a/services/ble_profiles/pasp/paspc/src/paspc.c b/services/ble_profiles/pasp/paspc/src/paspc.c new file mode 100644 index 0000000..ad7cf96 --- /dev/null +++ b/services/ble_profiles/pasp/paspc/src/paspc.c @@ -0,0 +1,204 @@ +/** + **************************************************************************************** + * @addtogroup PASPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_PAS_CLIENT) +#include "pasp_common.h" + +#include "paspc.h" +#include "paspc_task.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the PASPC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t paspc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct paspc_env_tag* paspc_env = + (struct paspc_env_tag* ) ke_malloc(sizeof(struct paspc_env_tag), KE_MEM_ATT_DB); + + // allocate PASPC required environment variable + env->env = (prf_env_t*) paspc_env; + + paspc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + paspc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_PASPC; + paspc_task_init(&(env->desc)); + + for(idx = 0; idx < PASPC_IDX_MAX ; idx++) + { + paspc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), PASPC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void paspc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct paspc_env_tag* paspc_env = (struct paspc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(paspc_env->env[conidx] != NULL) + { + ke_free(paspc_env->env[conidx]); + paspc_env->env[conidx] = NULL; + } + + /* Put PASP Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), PASPC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the PASPC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void paspc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct paspc_env_tag* paspc_env = (struct paspc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < PASPC_IDX_MAX ; idx++) + { + paspc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(paspc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void paspc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put PASP Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), PASPC_IDLE); +} + +/// PASPC Task interface required by profile manager +const struct prf_task_cbs paspc_itf = +{ + paspc_init, + paspc_destroy, + paspc_create, + paspc_cleanup, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* paspc_prf_itf_get(void) +{ + return &paspc_itf; +} + +void paspc_enable_rsp_send(struct paspc_env_tag *paspc_env, uint8_t conidx, uint8_t status) +{ + // Send to APP the details of the discovered attributes on PASPS + struct paspc_enable_rsp * rsp = KE_MSG_ALLOC( + PASPC_ENABLE_RSP, + prf_dst_task_get(&(paspc_env->prf_env), conidx), + prf_src_task_get(&(paspc_env->prf_env), conidx), + paspc_enable_rsp); + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->pass = paspc_env->env[conidx]->pass; + // Register PASPC task in gatt for indication/notifications + prf_register_atthdl2gatt(&(paspc_env->prf_env), conidx, &(paspc_env->env[conidx]->pass.svc)); + // Go to connected state + ke_state_set(prf_src_task_get(&(paspc_env->prf_env), conidx), PASPC_IDLE); + } + + ke_msg_send(rsp); +} + +void paspc_send_cmp_evt(struct paspc_env_tag *paspc_env, uint8_t conidx, + uint8_t operation, uint8_t status) +{ + // Go back to the CONNECTED state if the state is busy + if (ke_state_get(prf_src_task_get(&(paspc_env->prf_env), conidx)) == PASPC_BUSY) + { + ke_state_set(prf_src_task_get(&paspc_env->prf_env, conidx), PASPC_IDLE); + } + + // Send the message + struct paspc_cmp_evt *evt = KE_MSG_ALLOC(PASPC_CMP_EVT, + prf_dst_task_get(&(paspc_env->prf_env), conidx), + prf_src_task_get(&(paspc_env->prf_env), conidx), + paspc_cmp_evt); + + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + +#endif //(BLE_PAS_CLIENT) + +/// @} PASPC diff --git a/services/ble_profiles/pasp/paspc/src/paspc.h b/services/ble_profiles/pasp/paspc/src/paspc.h new file mode 100644 index 0000000..9418e2a --- /dev/null +++ b/services/ble_profiles/pasp/paspc/src/paspc.h @@ -0,0 +1,155 @@ +#ifndef _PASPC_H_ +#define _PASPC_H_ + +/** + **************************************************************************************** + * @addtogroup PASPC Phone Alert Status Profile Client + * @ingroup PASP + * @brief Phone Alert Status Profile Client + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_PAS_CLIENT) +#include "pasp_common.h" +#include "paspc_task.h" +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of Phone Alert Status Client task instances +#define PASPC_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the PASPC task +enum paspc_states +{ + /// Idle state + PASPC_FREE, + /// Connected state + PASPC_IDLE, + /// Busy state + PASPC_DISCOVERING, + /// Busy state + PASPC_BUSY, + + /// Number of defined states. + PASPC_STATE_MAX +}; + + +/// Internal codes for reading/writing a PAS characteristic with one single request +enum +{ + /// Read PAS Alert Status + PASPC_RD_ALERT_STATUS = PASPC_CHAR_ALERT_STATUS, + /// Read PAS Ringer Setting + PASPC_RD_RINGER_SETTING = PASPC_CHAR_RINGER_SETTING, + /// Write PAS Ringer Control Point + PASPC_WR_RINGER_CTNL_PT = PASPC_CHAR_RINGER_CTNL_PT, + + /// Read/Write PAS Alert Status Client Characteristic Configuration Descriptor + PASPC_RD_WR_ALERT_STATUS_CFG = (PASPC_DESC_ALERT_STATUS_CL_CFG | PASPC_DESC_MASK), + /// Read PAS Ringer Setting Client Characteristic Configuration Descriptor + PASPC_RD_WR_RINGER_SETTING_CFG = (PASPC_DESC_RINGER_SETTING_CL_CFG | PASPC_DESC_MASK), +}; + + + +/* + * STRUCTURES + **************************************************************************************** + */ + + +struct paspc_cnx_env +{ + /// Last requested UUID(to keep track of the two services and char) + uint16_t last_uuid_req; + /// Last characteristic code used in a read or a write request + uint16_t last_char_code; + /// Counter used to check service uniqueness + uint8_t nb_svc; + /// Current operation code + uint8_t operation; + /// Phone Alert Status Service Characteristics + struct paspc_pass_content pass; +}; + +/// Phone Alert Status Profile Client environment variable +struct paspc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct paspc_cnx_env* env[PASPC_IDX_MAX]; + /// State of different task instances + ke_state_t state[PASPC_IDX_MAX]; +}; + +/* + * GLOBAL FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve PASP client profile interface + * @return PASP client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* paspc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Phone Alert Status ATT DB discovery results to PASPC host. + * @param[in] paspc_env environment variable + * @param[in] conidx Connection index + * @param[in] status Satus + **************************************************************************************** + */ +void paspc_enable_rsp_send(struct paspc_env_tag *paspc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Send a PASPC_CMP_EVT message to the task which enabled the profile + **************************************************************************************** + */ +void paspc_send_cmp_evt(struct paspc_env_tag *paspc_env, uint8_t conidx, + uint8_t operation, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void paspc_task_init(struct ke_task_desc *task_desc); + +#endif //(BLE_PAS_CLIENT) + +/// @} PASPC + +#endif //(_PASPC_H_) diff --git a/services/ble_profiles/pasp/paspc/src/paspc_task.c b/services/ble_profiles/pasp/paspc/src/paspc_task.c new file mode 100644 index 0000000..4e470d6 --- /dev/null +++ b/services/ble_profiles/pasp/paspc/src/paspc_task.c @@ -0,0 +1,696 @@ +/** + **************************************************************************************** + * @addtogroup PASPCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_PAS_CLIENT) +#include "pasp_common.h" +#include "paspc_task.h" +#include "paspc.h" + +#include "gap.h" +#include "attm.h" +#include "gattc_task.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// State machine used to retrieve Phone Alert Status service characteristics information +const struct prf_char_def paspc_pass_char[PASPC_CHAR_MAX] = +{ + /// Alert Status + [PASPC_CHAR_ALERT_STATUS] = {ATT_CHAR_ALERT_STATUS, + ATT_MANDATORY, + ATT_CHAR_PROP_RD | ATT_CHAR_PROP_NTF}, + /// Ringer Setting + [PASPC_CHAR_RINGER_SETTING] = {ATT_CHAR_RINGER_SETTING, + ATT_MANDATORY, + ATT_CHAR_PROP_RD | ATT_CHAR_PROP_NTF}, + /// Ringer Control Point + [PASPC_CHAR_RINGER_CTNL_PT] = {ATT_CHAR_RINGER_CNTL_POINT, + ATT_MANDATORY, + ATT_CHAR_PROP_WR_NO_RESP}, +}; + +/// State machine used to retrieve Phone Alert Status service characteristic descriptor information +const struct prf_char_desc_def paspc_pass_char_desc[PASPC_DESC_MAX] = +{ + /// Alert Status Client Characteristic Configuration + [PASPC_DESC_ALERT_STATUS_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_MANDATORY, + PASPC_CHAR_ALERT_STATUS}, + /// Ringer Setting Client Characteristic Configuration + [PASPC_DESC_RINGER_SETTING_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_MANDATORY, + PASPC_CHAR_RINGER_SETTING}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref PASPC_ENABLE_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int paspc_enable_req_handler(ke_msg_id_t const msgid, + struct paspc_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Phone Alert Status Profile Client Role Task Environment + struct paspc_env_tag *paspc_env = PRF_ENV_GET(PASPC, paspc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if ((state == PASPC_IDLE) && (paspc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + paspc_env->env[conidx] = (struct paspc_cnx_env*) ke_malloc(sizeof(struct paspc_cnx_env),KE_MEM_ATT_DB); + memset(paspc_env->env[conidx], 0, sizeof(struct paspc_cnx_env)); + + paspc_env->env[conidx]->operation = PASPC_ENABLE_OP_CODE; + + // Start discovering + if (param->con_type == PRF_CON_DISCOVERY) + { + prf_disc_svc_send(&(paspc_env->prf_env), conidx, ATT_SVC_PHONE_ALERT_STATUS); + + // Go to DISCOVERING state + ke_state_set(dest_id, PASPC_DISCOVERING); + + // Configure the environment for a discovery procedure + paspc_env->env[conidx]->last_uuid_req = ATT_SVC_PHONE_ALERT_STATUS; + } + // Bond information is provided + else + { + // Keep the provided database content + memcpy(&paspc_env->env[conidx]->pass, ¶m->pass, sizeof(struct paspc_pass_content)); + + //send APP confirmation that can start normal connection to TH + paspc_enable_rsp_send(paspc_env, conidx, GAP_ERR_NO_ERROR); + + /* -------------------------------------------------------------------------------- + * After connection establishment, once the discovery procedure is successful, + * the client shall read the Alert Status + * -------------------------------------------------------------------------------- */ + // Configure the environment for a read procedure + paspc_env->env[conidx]->last_char_code = PASPC_RD_ALERT_STATUS; + + // Send the read request + prf_read_char_send(&(paspc_env->prf_env), + conidx, paspc_env->env[conidx]->pass.svc.shdl, + paspc_env->env[conidx]->pass.svc.ehdl, + paspc_env->env[conidx]->pass.chars[PASPC_CHAR_ALERT_STATUS].val_hdl); + + // Go to BUSY state + ke_state_set(dest_id, PASPC_BUSY); + } + } + else if (state != PASPC_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + paspc_enable_rsp_send(paspc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref PASPC_READ_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int paspc_read_cmd_handler(ke_msg_id_t const msgid, + struct paspc_read_cmd const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct paspc_env_tag *paspc_idx_env = PRF_ENV_GET(PASPC, paspc); + + if (paspc_idx_env != NULL) + { + // Attribute Handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + // Check the provided connection handle + do + { + // Check the current state + if (ke_state_get(dest_id) == PASPC_BUSY) + { + // Keep the request for later, state is GAP_ERR_NO_ERROR + msg_status = KE_MSG_SAVED; + break; + } + + switch (param->read_code) + { + // Read Alert Status Characteristic Value + case (PASPC_RD_ALERT_STATUS): + { + handle = paspc_idx_env->env[conidx]->pass.chars[PASPC_CHAR_ALERT_STATUS].val_hdl; + } break; + + // Read Ringer Setting Characteristic Value + case (PASPC_RD_RINGER_SETTING): + { + handle = paspc_idx_env->env[conidx]->pass.chars[PASPC_CHAR_RINGER_SETTING].val_hdl; + } break; + + // Read Alert Status Characteristic Client Char. Cfg. Descriptor Value + case (PASPC_RD_WR_ALERT_STATUS_CFG): + { + handle = paspc_idx_env->env[conidx]->pass.descs[PASPC_DESC_ALERT_STATUS_CL_CFG].desc_hdl; + } break; + + // Read Ringer Setting Characteristic Client Char. Cfg. Descriptor Value + case (PASPC_RD_WR_RINGER_SETTING_CFG): + { + handle = paspc_idx_env->env[conidx]->pass.descs[PASPC_DESC_RINGER_SETTING_CL_CFG].desc_hdl; + } break; + + default: + { + // Handle is ATT_INVALID_SEARCH_HANDLE + status = PRF_ERR_INVALID_PARAM; + } break; + } + + if (status == GAP_ERR_NO_ERROR) + { + // Check if handle is viable + if (handle != ATT_INVALID_SEARCH_HANDLE) + { + // Configure the environment for a read operation + paspc_idx_env->env[conidx]->operation = PASPC_READ_OP_CODE; + paspc_idx_env->env[conidx]->last_char_code = param->read_code; + + // Send the read request + prf_read_char_send(&(paspc_idx_env->prf_env), conidx, + paspc_idx_env->env[conidx]->pass.svc.shdl, + paspc_idx_env->env[conidx]->pass.svc.ehdl, + handle); + + // Go to the Busy state + ke_state_set(dest_id, PASPC_BUSY); + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + } while(0); + + if (status != GAP_ERR_NO_ERROR) + { + paspc_send_cmp_evt(paspc_idx_env, conidx, PASPC_READ_OP_CODE, status); + } + } + else + { + // No connection exists + paspc_send_cmp_evt(paspc_idx_env, conidx, PASPC_READ_OP_CODE, PRF_ERR_REQ_DISALLOWED); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref PASPC_WRITE_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int paspc_write_cmd_handler(ke_msg_id_t const msgid, + struct paspc_write_cmd const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + // Get the address of the environment + struct paspc_env_tag *paspc_idx_env = PRF_ENV_GET(PASPC, paspc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (paspc_idx_env != NULL) + { + do + { + // Check the current state + if (ke_state_get(dest_id) != PASPC_IDLE) + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + break; + } + + // Attribute handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + // Write type + uint8_t wr_type; + // Length + uint8_t length; + + switch (param->write_code) + { + // Write Ringer Control Point Characteristic Value + case (PASPC_WR_RINGER_CTNL_PT): + { + if ((param->value.ringer_ctnl_pt >= PASP_SILENT_MODE) && + (param->value.ringer_ctnl_pt <= PASP_CANCEL_SILENT_MODE)) + { + handle = paspc_idx_env->env[conidx]->pass.chars[PASPC_CHAR_RINGER_CTNL_PT].val_hdl; + length = sizeof(uint8_t); + wr_type = GATTC_WRITE_NO_RESPONSE; + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + // Write Alert Status Characteristic Client Char. Cfg. Descriptor Value + case (PASPC_RD_WR_ALERT_STATUS_CFG): + { + if (param->value.alert_status_ntf_cfg <= PRF_CLI_START_NTF) + { + handle = paspc_idx_env->env[conidx]->pass.descs[PASPC_DESC_ALERT_STATUS_CL_CFG].desc_hdl; + length = sizeof(uint16_t); + wr_type = GATTC_WRITE; + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + // Write Ringer Setting Characteristic Client Char. Cfg. Descriptor Value + case (PASPC_RD_WR_RINGER_SETTING_CFG): + { + if (param->value.ringer_setting_ntf_cfg <= PRF_CLI_START_NTF) + { + handle = paspc_idx_env->env[conidx]->pass.descs[PASPC_DESC_RINGER_SETTING_CL_CFG].desc_hdl; + length = sizeof(uint16_t); + wr_type = GATTC_WRITE; + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + + if (status == GAP_ERR_NO_ERROR) + { + // Check if handle is viable + if (handle != ATT_INVALID_SEARCH_HANDLE) + { + // Send the write request + prf_gatt_write(&(paspc_idx_env->prf_env), conidx, handle, (uint8_t *)¶m->value, length, wr_type); + + // Configure the environment for a write operation + paspc_idx_env->env[conidx]->operation = PASPC_WRITE_OP_CODE; + paspc_idx_env->env[conidx]->last_char_code = param->write_code; + + // Go to the Busy state + ke_state_set(dest_id, PASPC_BUSY); + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + } while (0); + } + else + { + status = PRF_ERR_REQ_DISALLOWED; + } + + if (status != GAP_ERR_NO_ERROR) + { + paspc_send_cmp_evt(paspc_idx_env, conidx, PASPC_WRITE_OP_CODE, status); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == PASPC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct paspc_env_tag *paspc_env = PRF_ENV_GET(PASPC, paspc); + + ASSERT_INFO(paspc_env != NULL, dest_id, src_id); + ASSERT_INFO(paspc_env->env[conidx] != NULL, dest_id, src_id); + + if(paspc_env->env[conidx]->nb_svc == 0) + { + // Retrieve PASS characteristics and descriptors + prf_extract_svc_info(ind, PASPC_CHAR_MAX, &paspc_pass_char[0], &paspc_env->env[conidx]->pass.chars[0], + PASPC_DESC_MAX, &paspc_pass_char_desc[0], &paspc_env->env[conidx]->pass.descs[0]); + + //Even if we get multiple responses we only store 1 range + paspc_env->env[conidx]->pass.svc.shdl = ind->start_hdl; + paspc_env->env[conidx]->pass.svc.ehdl = ind->end_hdl; + } + + paspc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct paspc_env_tag *paspc_env = PRF_ENV_GET(PASPC, paspc); + // Status + uint8_t status; + + + if (paspc_env != NULL) + { + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if (state == PASPC_DISCOVERING) + { + status = param->status; + + if ((status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || + (status == ATT_ERR_NO_ERROR)) + { + // Discovery + // check characteristic validity + if(paspc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(PASPC_CHAR_MAX, + paspc_env->env[conidx]->pass.chars, + paspc_pass_char); + } + // too much services + else if (paspc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if (status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(PASPC_DESC_MAX, + paspc_env->env[conidx]->pass.descs, + paspc_pass_char_desc, + paspc_env->env[conidx]->pass.chars); + } + } + + paspc_enable_rsp_send(paspc_env, conidx, status); + } + + else if (state == PASPC_BUSY) + { + switch (param->operation) + { + case GATTC_READ: + { + // Send the complete event status + paspc_send_cmp_evt(paspc_env, conidx, PASPC_READ_OP_CODE, param->status); + } break; + + case GATTC_WRITE: + case GATTC_WRITE_NO_RESPONSE: + { + if (paspc_env->env[conidx]->operation == PASPC_WRITE_OP_CODE) + { + // Send the complete event status + paspc_send_cmp_evt(paspc_env, conidx, PASPC_WRITE_OP_CODE, param->status); + } + } break; + + case GATTC_REGISTER: + case GATTC_UNREGISTER: + { + // Do nothing + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + } + // else ignore the message + + + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct paspc_env_tag *paspc_env = PRF_ENV_GET(PASPC, paspc); + uint8_t conidx = KE_IDX_GET(dest_id); + + if (paspc_env != NULL) + { + ASSERT_ERR(ke_state_get(dest_id) == PASPC_BUSY); + + // Prepare the indication message for the HL + struct paspc_value_ind *ind = KE_MSG_ALLOC(PASPC_VALUE_IND, + prf_dst_task_get(&(paspc_env->prf_env), conidx), + dest_id, + paspc_value_ind); + + switch (paspc_env->env[conidx]->last_char_code) + { + // Read Alert Status Characteristic Value + case (PASPC_RD_ALERT_STATUS): + { + ind->value.alert_status = param->value[0]; + } break; + + // Read Ringer Setting Characteristic Value + case (PASPC_RD_RINGER_SETTING): + { + ind->value.ringer_setting = param->value[0]; + } break; + + // Read Alert Status Characteristic Client Char. Cfg. Descriptor Value + case (PASPC_RD_WR_ALERT_STATUS_CFG): + { + ind->value.alert_status_ntf_cfg = co_read16p(¶m->value[0]); + } break; + + // Read Ringer Setting Characteristic Client Char. Cfg. Descriptor Value + case (PASPC_RD_WR_RINGER_SETTING_CFG): + { + ind->value.ringer_setting_ntf_cfg = co_read16p(¶m->value[0]); + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + + ind->att_code = paspc_env->env[conidx]->last_char_code; + + // Send the message + ke_msg_send(ind); + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct paspc_env_tag *paspc_env = PRF_ENV_GET(PASPC, paspc); + uint8_t conidx = KE_IDX_GET(dest_id); + + if (paspc_env != NULL) + { + ASSERT_ERR((param->handle == paspc_env->env[conidx]->pass.chars[PASPC_CHAR_ALERT_STATUS].val_hdl) || + (param->handle == paspc_env->env[conidx]->pass.chars[PASPC_CHAR_RINGER_SETTING].val_hdl)); + + // Prepare the indication message for the HL + struct paspc_value_ind *ind = KE_MSG_ALLOC(PASPC_VALUE_IND, + prf_dst_task_get(&paspc_env->prf_env, conidx), + prf_src_task_get(&paspc_env->prf_env, conidx), + paspc_value_ind); + + // Alert Status Characteristic Value + if (param->handle == paspc_env->env[conidx]->pass.chars[PASPC_CHAR_ALERT_STATUS].val_hdl) + { + ind->value.alert_status = param->value[0]; + ind->att_code = PASPC_RD_ALERT_STATUS; + } + // Ringer Setting Characteristic Value + else + { + ind->value.ringer_setting = param->value[0]; + ind->att_code = PASPC_RD_RINGER_SETTING; + } + + // Send the message + ke_msg_send(ind); + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(paspc) +{ + {PASPC_ENABLE_REQ, (ke_msg_func_t)paspc_enable_req_handler}, + {PASPC_READ_CMD, (ke_msg_func_t)paspc_read_cmd_handler}, + {PASPC_WRITE_CMD, (ke_msg_func_t)paspc_write_cmd_handler}, + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void paspc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct paspc_env_tag *paspc_env = PRF_ENV_GET(PASPC, paspc); + + task_desc->msg_handler_tab = paspc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(paspc_msg_handler_tab); + task_desc->state = paspc_env->state; + task_desc->idx_max = PASPC_IDX_MAX; +} + +#endif //(BLE_PAS_CLIENT) + +/// @} PASPCTASK diff --git a/services/ble_profiles/pasp/pasps/api/pasps_task.h b/services/ble_profiles/pasp/pasps/api/pasps_task.h new file mode 100644 index 0000000..1c511b1 --- /dev/null +++ b/services/ble_profiles/pasp/pasps/api/pasps_task.h @@ -0,0 +1,124 @@ +#ifndef PASPS_TASK_H_ +#define PASPS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup PASPSTASK Task + * @ingroup PASPS + * @brief Phone Alert Status Profile Server Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "pasp_common.h" +#include "rwip_task.h" // Task definitions + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Messages for Phone Alert Status Profile Server +enum pasps_msg_ids +{ + /// Set Bonded Data + PASPS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_PASPS), + /// Bonded data confirmation + PASPS_ENABLE_RSP, + + /// Update the value of a characteristic + PASPS_UPDATE_CHAR_VAL_CMD, + /// Indicate that an attribute value has been written + PASPS_WRITTEN_CHAR_VAL_IND, + + /// Complete Event Information + PASPS_CMP_EVT, +}; + +/// Operation Codes +enum pasps_op_codes +{ + PASPS_RESERVED_OP_CODE = 0x00, + + /// Enable Procedure + PASPS_ENABLE_OP_CODE, + /// Update Alert Status Char. value + PASPS_UPD_ALERT_STATUS_OP_CODE, + /// Update Ringer Setting Char. value + PASPS_UPD_RINGER_SETTING_OP_CODE, +}; + +/* + * API MESSAGES STRUCTURES + **************************************************************************************** + */ + +/// Parameters of the @ref PASPS_CREATE_DB_REQ message +struct pasps_db_cfg +{ + /// Alert Status Char. Value + uint8_t alert_status; + /// Ringer Settings Char. Value + uint8_t ringer_setting; +}; + +/// Parameters of the @ref PASPS_ENABLE_REQ message +struct pasps_enable_req +{ + /// Alert Status Characteristic Notification Configuration + uint16_t alert_status_ntf_cfg; + /// Ringer Setting Characteristic Notification Configuration + uint16_t ringer_setting_ntf_cfg; +}; + +/// Parameters of the @ref PASPS_ENABLE_RSP message +struct pasps_enable_rsp +{ + /// status + uint8_t status; +}; + +///Parameters of the @ref PASPS_UPDATE_CHAR_VAL_CMD message +struct pasps_update_char_val_cmd +{ + /// Operation Code (PASPS_UPD_ALERT_STATUS_OP_CODE or PASPS_UPD_RINGER_SETTING_OP_CODE) + uint8_t operation; + /// Alert Status Characteristic Value or Ringer Setting Characteristic Value + uint8_t value; +}; + +///Parameters of the @ref PASPS_WRITTEN_CHAR_VAL_IND message +struct pasps_written_char_val_ind +{ + /// Attribute Code + uint8_t att_code; + /// Written value + union written_value_tag + { + /// Ringer Control Point Char. Value + uint8_t ringer_ctnl_pt; + /// Alert Status Notification Configuration + uint16_t alert_status_ntf_cfg; + /// Ringer Setting Notification Configuration + uint16_t ringer_setting_ntf_cfg; + } value; +}; + +///Parameters of the @ref PASPS_CMP_EVT message +struct pasps_cmp_evt +{ + /// Operation + uint8_t operation; + /// Status + uint8_t status; +}; + +/// @} PASPSTASK + +#endif // PASPS_TASK_H_ diff --git a/services/ble_profiles/pasp/pasps/src/pasps.c b/services/ble_profiles/pasp/pasps/src/pasps.c new file mode 100644 index 0000000..7767d27 --- /dev/null +++ b/services/ble_profiles/pasp/pasps/src/pasps.c @@ -0,0 +1,253 @@ +/** + **************************************************************************************** + * @addtogroup PASPS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" +#if (BLE_PAS_SERVER) +#include "pasp_common.h" + +#include "pasps_task.h" +#include "pasps.h" +#include "prf_utils.h" + +#include "ke_mem.h" + +/* + * PHONE ALERT STATUS SERVICE ATTRIBUTES + **************************************************************************************** + */ + +/// Full PAS Database Description - Used to add attributes into the database +const struct attm_desc pasps_att_db[PASS_IDX_NB] = +{ + // Phone Alert Status Service Declaration + [PASS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // Alert Status Characteristic Declaration + [PASS_IDX_ALERT_STATUS_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Alert Status Characteristic Value + [PASS_IDX_ALERT_STATUS_VAL] = {ATT_CHAR_ALERT_STATUS, PERM(RD, ENABLE) | PERM(NTF, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, + // Alert Status Characteristic - Client Characteristic Configuration Descriptor + [PASS_IDX_ALERT_STATUS_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Ringer Setting Characteristic Declaration + [PASS_IDX_RINGER_SETTING_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Ringer Settings Characteristic Value + [PASS_IDX_RINGER_SETTING_VAL] = {ATT_CHAR_RINGER_SETTING, PERM(RD, ENABLE) | PERM(NTF, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, + // Ringer Settings Characteristic - Client Characteristic Configuration Descriptor + [PASS_IDX_RINGER_SETTING_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Ringer Control Point Characteristic Declaration + [PASS_IDX_RINGER_CTNL_PT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Ringer Control Point Characteristic Value + [PASS_IDX_RINGER_CTNL_PT_VAL] = {ATT_CHAR_RINGER_CNTL_POINT, PERM(WRITE_COMMAND, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the PASPS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t pasps_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct pasps_db_cfg* params) +{ + //------------------ create the attribute database for the profile ------------------- + // Service content flag + uint32_t cfg_flag= PASPS_DB_CFG_FLAG; + // DB Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + // Add service in the database + status = attm_svc_create_db(start_hdl, ATT_SVC_PHONE_ALERT_STATUS, (uint8_t *)&cfg_flag, + PASS_IDX_NB, NULL, env->task, &pasps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, ENABLE)); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // Allocate PASPS required environment variable + struct pasps_env_tag* pasps_env = + (struct pasps_env_tag* ) ke_malloc(sizeof(struct pasps_env_tag), KE_MEM_ATT_DB); + + // Initialize PASPS environment + env->env = (prf_env_t*) pasps_env; + pasps_env->shdl = *start_hdl; + + pasps_env->alert_status = params->alert_status; + pasps_env->ringer_setting = params->ringer_setting; + + pasps_env->operation = PASPS_RESERVED_OP_CODE; + + pasps_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Multi Instantiated task + pasps_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_PASPS; + pasps_task_init(&(env->desc)); + + for(uint8_t idx = 0; idx < BLE_CONNECTION_MAX ; idx++) + { + pasps_env->env[idx] = NULL; + /* Put PASS in disabled state */ + ke_state_set(KE_BUILD_ID(env->task, idx), PASPS_FREE); + } + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the PASPS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void pasps_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct pasps_env_tag* pasps_env = (struct pasps_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < BLE_CONNECTION_MAX ; idx++) + { + if(pasps_env->env[idx] != NULL) + { + ke_free(pasps_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(pasps_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void pasps_create(struct prf_task_env* env, uint8_t conidx) +{ + struct pasps_env_tag* pasps_env = (struct pasps_env_tag*) env->env; + pasps_env->env[conidx] = (struct pasps_cnx_env*) + ke_malloc(sizeof(struct pasps_cnx_env), KE_MEM_ATT_DB); + + memset(pasps_env->env[conidx], 0, sizeof(struct pasps_cnx_env)); + + pasps_env->env[conidx]->ringer_state = pasps_env->ringer_setting; + /* Put PASS in idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), PASPS_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void pasps_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct pasps_env_tag* pasps_env = (struct pasps_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(pasps_env->env[conidx] != NULL) + { + ke_free(pasps_env->env[conidx]); + pasps_env->env[conidx] = NULL; + } + + /* Put PASS in disabled state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), PASPS_FREE); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// PASPS Task interface required by profile manager +const struct prf_task_cbs pasps_itf = +{ + (prf_init_fnct) pasps_init, + pasps_destroy, + pasps_create, + pasps_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* pasps_prf_itf_get(void) +{ + return &pasps_itf; +} + + +///* +// * FUNCTION DEFINITIONS +// **************************************************************************************** +// */ + +void pasps_send_cmp_evt(ke_task_id_t src_id, ke_task_id_t dest_id, + uint8_t operation, uint8_t status) +{ + // Come back to the Connected state if the state was busy. + if (ke_state_get(src_id) == PASPS_BUSY) + { + ke_state_set(src_id, PASPS_IDLE); + } + + // Send the message to the application + struct pasps_cmp_evt *evt = KE_MSG_ALLOC(PASPS_CMP_EVT, + dest_id, src_id, + pasps_cmp_evt); + + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + +#endif //(BLE_PASP_SERVER) + +/// @} PASPS diff --git a/services/ble_profiles/pasp/pasps/src/pasps.h b/services/ble_profiles/pasp/pasps/src/pasps.h new file mode 100644 index 0000000..a931f46 --- /dev/null +++ b/services/ble_profiles/pasp/pasps/src/pasps.h @@ -0,0 +1,199 @@ +#ifndef PASPS_H_ +#define PASPS_H_ + +/** + **************************************************************************************** + * @addtogroup PASPS Phone Alert Status Profile Server + * @ingroup PASP + * @brief Phone Alert Status Profile Server + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" +#if (BLE_PAS_SERVER) +#include "pasp_common.h" + +#include +#include +#include "prf_types.h" +#include "prf.h" +#include "attm.h" + + +/* + * DEFINES + **************************************************************************************** + */ + +/// Number of parallel instances of the task +#define PASPS_IDX_MAX (BLE_CONNECTION_MAX) +/// Database Configuration Flag +#define PASPS_DB_CFG_FLAG (0x01FF) + +/// Notification States Flags +#define PASPS_FLAG_ALERT_STATUS_CFG (0x01) +#define PASPS_FLAG_RINGER_SETTING_CFG (0x02) +/// CP Discovery or Bonded data used +#define PASPS_FLAG_CFG_PERFORMED_OK (0x80) + + +/* + * MACROS + **************************************************************************************** + */ + +#define PASPS_IS_NTF_ENABLED(conidx, idx_env, flag) ((idx_env->env[conidx]->ntf_state & flag) == flag) + +#define PASPS_ENABLE_NTF(conidx, idx_env, flag) (idx_env->env[conidx]->ntf_state |= flag) + +#define PASPS_DISABLE_NTF(conidx, idx_env, flag) (idx_env->env[conidx]->ntf_state &= ~flag) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the PASPS task +enum pasps_states +{ + /// Not connected state + PASPS_FREE, + /// Idle state + PASPS_IDLE, + /// Busy state + PASPS_BUSY, + + /// Number of defined states. + PASPS_STATE_MAX +}; + +/// Attributes State Machine +enum pasps_pass_att_list +{ + PASS_IDX_SVC, + + PASS_IDX_ALERT_STATUS_CHAR, + PASS_IDX_ALERT_STATUS_VAL, + PASS_IDX_ALERT_STATUS_CFG, + + PASS_IDX_RINGER_SETTING_CHAR, + PASS_IDX_RINGER_SETTING_VAL, + PASS_IDX_RINGER_SETTING_CFG, + + PASS_IDX_RINGER_CTNL_PT_CHAR, + PASS_IDX_RINGER_CTNL_PT_VAL, + + PASS_IDX_NB, +}; + +/// Attribute Codes +enum pasps_att_code +{ + /// Alert Status Characteristic + PASPS_ALERT_STATUS_CHAR_VAL, + /// Ringer Setting Characteristic + PASPS_RINGER_SETTING_CHAR_VAL, + /// Ringer Control Point Characteristic + PASPS_RINGER_CTNL_PT_CHAR_VAL, + + /// Alert Status Characteristic - Notification Configuration + PASPS_ALERT_STATUS_NTF_CFG, + /// Ringer Setting Characteristic - Notification Configuration + PASPS_RINGER_SETTING_NTF_CFG, +}; + + + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Phone Alert Status Profile Server Connection Dependent Environment Variable +struct pasps_cnx_env +{ + /// Ringer State + uint8_t ringer_state; + + /** + * Ringer State + Notification State + * Bit 0: Alert Status notification configuration + * Bit 1: Ringer setting notification configuration + */ + uint8_t ntf_state; +}; + +/// Phone Alert Status Profile Server Environment Variable +struct pasps_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Phone Alert Status Service Start Handle + uint16_t shdl; + /// Environment variable pointer for each connections + struct pasps_cnx_env* env[BLE_CONNECTION_MAX]; + + /// Current Operation Code + uint8_t operation; + /// Alert Status Char. Value + uint8_t alert_status; + /// Ringer Settings Char. Value + uint8_t ringer_setting; + + /// State of different task instances + ke_state_t state[PASPS_IDX_MAX]; +}; + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve PASP service profile interface + * + * @return PASP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* pasps_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send a PASPS_CMP_EVT message to a requester. + * + * @param[in] src_id Source ID of the message (instance of TASK_PASPS) + * @param[in] dest_id Destination ID of the message + * @param[in] operation Code of the completed operation + * @param[in] status Status of the request + **************************************************************************************** + */ +void pasps_send_cmp_evt(ke_task_id_t src_id, ke_task_id_t dest_id, + uint8_t operation, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void pasps_task_init(struct ke_task_desc *task_desc); + + +#endif //(BLE_PAS_SERVER) + +/// @} PASPS + +#endif // PASPS_H_ diff --git a/services/ble_profiles/pasp/pasps/src/pasps_task.c b/services/ble_profiles/pasp/pasps/src/pasps_task.c new file mode 100644 index 0000000..a58692e --- /dev/null +++ b/services/ble_profiles/pasp/pasps/src/pasps_task.c @@ -0,0 +1,566 @@ +/** + **************************************************************************************** + * @addtogroup PASPSTASK + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_PAS_SERVER) +#include "pasp_common.h" + +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "pasps.h" +#include "pasps_task.h" +#include "prf_utils.h" + +#include "co_utils.h" + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref PASPS_ENABLE_REQ message. + * @param[in] msgid Id of the message received + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int pasps_enable_req_handler(ke_msg_id_t const msgid, + struct pasps_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct pasps_env_tag *pasps_env = PRF_ENV_GET(PASPS, pasps); + uint8_t conidx = KE_IDX_GET(src_id); + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(ke_state_get(dest_id) == PASPS_IDLE) + { + // Bonded data was not used before + if (!(pasps_env->env[conidx]->ntf_state & PASPS_FLAG_CFG_PERFORMED_OK)) + { + status = GAP_ERR_NO_ERROR; + if (param->alert_status_ntf_cfg != PRF_CLI_STOP_NTFIND) + { + // Force to PRF_CLI_START_NTF + param->alert_status_ntf_cfg = PRF_CLI_START_NTF; + + PASPS_ENABLE_NTF(conidx, pasps_env, PASPS_FLAG_ALERT_STATUS_CFG); + } + + if (param->ringer_setting_ntf_cfg != PRF_CLI_STOP_NTFIND) + { + // Force to PRF_CLI_START_NTF + param->ringer_setting_ntf_cfg = PRF_CLI_START_NTF; + + PASPS_ENABLE_NTF(conidx, pasps_env, PASPS_FLAG_RINGER_SETTING_CFG); + } + } + // Enable Bonded Data + PASPS_ENABLE_NTF(conidx, pasps_env, PASPS_FLAG_CFG_PERFORMED_OK); + } + + // send completed information to APP task that contains error status + struct pasps_enable_rsp *cmp_evt = KE_MSG_ALLOC(PASPS_ENABLE_RSP, src_id, dest_id, pasps_enable_rsp); + cmp_evt->status = status; + + ke_msg_send(cmp_evt); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref PASPS_UPDATE_CHAR_VAL_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int pasps_update_char_val_cmd_handler(ke_msg_id_t const msgid, + struct pasps_update_char_val_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = PRF_ERR_INVALID_PARAM; + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if (state == PASPS_IDLE) + { + // Get the address of the environment + struct pasps_env_tag *pasps_env = PRF_ENV_GET(PASPS, pasps); + // Handle + uint16_t handle = ATT_ERR_INVALID_HANDLE; + // Notification status flag + uint8_t flag = 0; + + ASSERT_ERR(pasps_env != NULL); + ASSERT_ERR(pasps_env->env[conidx] != NULL); + + // Check the connection handle + switch (param->operation) + { + // Alert Status Characteristic + case (PASPS_UPD_ALERT_STATUS_OP_CODE): + { + // Check the provided value + if (param->value <= PASP_ALERT_STATUS_VAL_MAX) + { + // Set the handle value + handle = pasps_env->shdl + PASS_IDX_ALERT_STATUS_VAL; + // Set the flag + flag = PASPS_FLAG_ALERT_STATUS_CFG; + // Update the ringer state value + pasps_env->alert_status = param->value; + + status = GAP_ERR_NO_ERROR; + } + // else status is PRF_ERR_INVALID_PARAM + } break; + + // Ringer Setting Characteristic + case (PASPS_UPD_RINGER_SETTING_OP_CODE): + { + // Check the provided value + if (param->value <= PASP_RINGER_NORMAL) + { + // Set the handle value + handle = pasps_env->shdl + PASS_IDX_RINGER_SETTING_VAL; + // Set the flag + flag = PASPS_FLAG_RINGER_SETTING_CFG; + // Update the ringer state value + pasps_env->ringer_setting = param->value; + + status = GAP_ERR_NO_ERROR; + } + // else status is PRF_ERR_INVALID_PARAM + } break; + + default: + { + // Nothing more to do, status is PRF_ERR_INVALID_PARAM + } break; + } + + if (status == GAP_ERR_NO_ERROR) + { + // Check if sending of notifications is enabled for this connection + if (PASPS_IS_NTF_ENABLED(conidx, pasps_env, flag)) + { + // Configure the environment for the operation + pasps_env->operation = param->operation; + // Go to the Busy state + ke_state_set(dest_id, PASPS_BUSY); + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), dest_id, + gattc_send_evt_cmd, sizeof(uint8_t)); + + // Fill in the parameter structure + ntf->operation = GATTC_NOTIFY; + ntf->handle = handle; + // pack measured value in database + ntf->length = sizeof(uint8_t); + // Fill data + ntf->value[0] = param->value; + + // The notification can be sent, send the notification + ke_msg_send(ntf); + } + else + { + status = PRF_ERR_NTF_DISABLED; + } + } + } + else if (state == PASPS_BUSY) + { + // Save it for later + msg_status = KE_MSG_SAVED; + status = GAP_ERR_NO_ERROR; + } + // no connection + else + { + status = GAP_ERR_DISCONNECTED; + } + + if(status != GAP_ERR_NO_ERROR) + { + // Send the message to the application + struct pasps_cmp_evt *evt = KE_MSG_ALLOC(PASPS_CMP_EVT, src_id, dest_id, pasps_cmp_evt); + + evt->operation = param->operation; + evt->status = status; + + ke_msg_send(evt); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == PASPS_IDLE) + { + // Get the address of the environment + struct pasps_env_tag *pasps_env = PRF_ENV_GET(PASPS, pasps); + uint8_t att_idx = param->handle - pasps_env->shdl; + struct gattc_att_info_cfm * cfm; + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + // check if it's a client configuration char + if((att_idx == PASS_IDX_ALERT_STATUS_CFG) + || (att_idx == PASS_IDX_RINGER_SETTING_CFG)) + { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } + else if (att_idx == PASS_IDX_RINGER_CTNL_PT_VAL) + { + // attribute length = 1 + cfm->length = 1; + cfm->status = GAP_ERR_NO_ERROR; + } + // not expected request + else + { + cfm->length = 0; + cfm->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == PASPS_IDLE) + { + // Get the address of the environment + struct pasps_env_tag *pasps_env = PRF_ENV_GET(PASPS, pasps); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t att_idx = param->handle - pasps_env->shdl; + + uint8_t value[2]; + uint8_t value_size = 0; + uint8_t status = ATT_ERR_NO_ERROR; + + switch(att_idx) + { + case PASS_IDX_ALERT_STATUS_VAL: + { + // Fill data + value_size = sizeof(uint8_t); + value[0] = pasps_env->alert_status; + } break; + + case PASS_IDX_RINGER_SETTING_VAL: + { + // Fill data + value_size = sizeof(uint8_t); + value[0] = pasps_env->ringer_setting; + } break; + + case PASS_IDX_ALERT_STATUS_CFG: + { + // Fill data + value_size = sizeof(uint16_t); + co_write16p(value, (pasps_env->env[conidx]->ntf_state & PASPS_FLAG_ALERT_STATUS_CFG) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + } break; + + case PASS_IDX_RINGER_SETTING_CFG: + { + // Fill data + value_size = sizeof(uint16_t); + co_write16p(value, (pasps_env->env[conidx]->ntf_state & PASPS_FLAG_RINGER_SETTING_CFG) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + } break; + + default: + { + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } break; + } + + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, value_size); + cfm->length = value_size; + memcpy(cfm->value, value, value_size); + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_WRITE_REQ_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get the conidx + uint8_t conidx = KE_IDX_GET(src_id); + // Get the address of the environment + struct pasps_env_tag *pasps_env = PRF_ENV_GET(PASPS, pasps); + + // Check if the connection exists + if (pasps_env->env[conidx] != NULL) + { + /* + * --------------------------------------------------------------------------------------------- + * Alert Status Client Characteristic Configuration Descriptor Value - Write + * --------------------------------------------------------------------------------------------- + * Ringer Setting Client Characteristic Configuration Descriptor Value - Write + * --------------------------------------------------------------------------------------------- + */ + if ((param->handle == (pasps_env->shdl + PASS_IDX_ALERT_STATUS_CFG)) || + (param->handle == (pasps_env->shdl + PASS_IDX_RINGER_SETTING_CFG))) + { + // Received configuration value + uint16_t ntf_cfg = co_read16p(¶m->value[0]); + + if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF)) + { + struct pasps_written_char_val_ind *ind = KE_MSG_ALLOC(PASPS_WRITTEN_CHAR_VAL_IND, + prf_dst_task_get(&pasps_env->prf_env, conidx), + prf_src_task_get(&pasps_env->prf_env, conidx), + pasps_written_char_val_ind); + + if (param->handle == pasps_env->shdl + PASS_IDX_ALERT_STATUS_CFG) + { + ind->value.alert_status_ntf_cfg = ntf_cfg; + ind->att_code = PASPS_ALERT_STATUS_NTF_CFG; + + if (ntf_cfg == PRF_CLI_STOP_NTFIND) + { + PASPS_DISABLE_NTF(conidx, pasps_env, PASPS_FLAG_ALERT_STATUS_CFG); + } + else + { + PASPS_ENABLE_NTF(conidx, pasps_env, PASPS_FLAG_ALERT_STATUS_CFG); + } + } + else + { + ind->value.ringer_setting_ntf_cfg = ntf_cfg; + ind->att_code = PASPS_RINGER_SETTING_NTF_CFG; + + if (ntf_cfg == PRF_CLI_STOP_NTFIND) + { + PASPS_DISABLE_NTF(conidx, pasps_env, PASPS_FLAG_RINGER_SETTING_CFG); + } + else + { + PASPS_ENABLE_NTF(conidx, pasps_env, PASPS_FLAG_RINGER_SETTING_CFG); + } + } + + ke_msg_send(ind); + + // Enable Bonded Data + PASPS_ENABLE_NTF(conidx, pasps_env, PASPS_FLAG_CFG_PERFORMED_OK); + } + else + { + status = PRF_APP_ERROR; + } + } + /* + * --------------------------------------------------------------------------------------------- + * Ringer Control Point Characteristic Value - Write Without Response + * --------------------------------------------------------------------------------------------- + */ + else if (param->handle == (pasps_env->shdl + PASS_IDX_RINGER_CTNL_PT_VAL)) + { + // Inform the HL ? + bool inform_hl = false; + + // Check the received value + switch (param->value[0]) + { + case (PASP_SILENT_MODE): + { + // Ignore if ringer is already silent + if (pasps_env->env[conidx]->ringer_state == PASP_RINGER_NORMAL) + { + inform_hl = true; + } + } break; + + case (PASP_CANCEL_SILENT_MODE): + { + // Ignore if ringer is not silent + if (pasps_env->env[conidx]->ringer_state == PASP_RINGER_SILENT) + { + inform_hl = true; + } + } break; + + case (PASP_MUTE_ONCE): + { + inform_hl = true; + } break; + + // No need to respond with an error (Write Without Response) + default: break; + } + + if (inform_hl) + { + struct pasps_written_char_val_ind *ind = KE_MSG_ALLOC(PASPS_WRITTEN_CHAR_VAL_IND, + prf_dst_task_get(&pasps_env->prf_env, conidx), + prf_src_task_get(&pasps_env->prf_env, conidx), + pasps_written_char_val_ind); + + ind->att_code = PASPS_RINGER_CTNL_PT_CHAR_VAL; + ind->value.ringer_ctnl_pt = param->value[0]; + + ke_msg_send(ind); + } + } + // Send the write response to the peer device + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT message meaning that a notification or an indication + * has been correctly sent to peer device (but not confirmed by peer device). + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + // Get the address of the environment + struct pasps_env_tag *pasps_env = PRF_ENV_GET(PASPS, pasps); + uint8_t conidx = KE_IDX_GET(src_id); + + if (pasps_env != NULL) + { + // Send a complete event status to the application + pasps_send_cmp_evt(prf_src_task_get(&pasps_env->prf_env, conidx), + prf_dst_task_get(&pasps_env->prf_env, conidx), + pasps_env->operation, param->status); + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(pasps) +{ + {PASPS_ENABLE_REQ, (ke_msg_func_t) pasps_enable_req_handler}, + {PASPS_UPDATE_CHAR_VAL_CMD, (ke_msg_func_t) pasps_update_char_val_cmd_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, +}; + +void pasps_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct pasps_env_tag *pasps_env = PRF_ENV_GET(PASPS, pasps); + + task_desc->msg_handler_tab = pasps_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(pasps_msg_handler_tab); + task_desc->state = pasps_env->state; + task_desc->idx_max = PASPS_IDX_MAX; +} + +#endif //(BLE_PASS_SERVER) + +/// @} PASPSTASK diff --git a/services/ble_profiles/prf/prf.c b/services/ble_profiles/prf/prf.c new file mode 100644 index 0000000..b259bdc --- /dev/null +++ b/services/ble_profiles/prf/prf.c @@ -0,0 +1,894 @@ +/** + **************************************************************************************** + * @addtogroup PRF + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_PROFILES) +#include "prf.h" +#include "att.h" + + +#if (BLE_HT_THERMOM) +extern const struct prf_task_cbs* htpt_prf_itf_get(void); +#endif // (BLE_HT_THERMOM) + +#if (BLE_HT_COLLECTOR) +extern const struct prf_task_cbs* htpc_prf_itf_get(void); +#endif // (BLE_HT_COLLECTOR) + +#if (BLE_DIS_SERVER) +extern const struct prf_task_cbs* diss_prf_itf_get(void); +#endif // (BLE_HT_THERMOM) + +#if (BLE_DIS_CLIENT) +extern const struct prf_task_cbs* disc_prf_itf_get(void); +#endif // (BLE_DIS_CLIENT) + +#if (BLE_BP_SENSOR) +extern const struct prf_task_cbs* blps_prf_itf_get(void); +#endif // (BLE_BP_SENSOR) + +#if (BLE_BP_COLLECTOR) +extern const struct prf_task_cbs* blpc_prf_itf_get(void); +#endif // (BLE_BP_COLLECTOR) + +#if (BLE_TIP_SERVER) +extern const struct prf_task_cbs* tips_prf_itf_get(void); +#endif // (BLE_TIP_SERVER) + +#if (BLE_TIP_CLIENT) +extern const struct prf_task_cbs* tipc_prf_itf_get(void); +#endif // (BLE_TIP_CLIENT) + +#if (BLE_HR_SENSOR) +extern const struct prf_task_cbs* hrps_prf_itf_get(void); +#endif // (BLE_HR_SENSOR) + +#if (BLE_HR_COLLECTOR) +extern const struct prf_task_cbs* hrpc_prf_itf_get(void); +#endif // (BLE_HR_COLLECTOR) + +#if (BLE_FINDME_LOCATOR) +extern const struct prf_task_cbs* findl_prf_itf_get(void); +#endif // (BLE_FINDME_LOCATOR) + +#if (BLE_FINDME_TARGET) +extern const struct prf_task_cbs* findt_prf_itf_get(void); +#endif // (BLE_FINDME_TARGET) + +#if (BLE_PROX_MONITOR) +extern const struct prf_task_cbs* proxm_prf_itf_get(void); +#endif // (BLE_PROX_MONITOR) + +#if (BLE_PROX_REPORTER) +extern const struct prf_task_cbs* proxr_prf_itf_get(void); +#endif // (BLE_PROX_REPORTER) + +#if (BLE_SP_CLIENT) +extern const struct prf_task_cbs* scppc_prf_itf_get(void); +#endif // (BLE_SP_CLENT) + +#if (BLE_SP_SERVER) +extern const struct prf_task_cbs* scpps_prf_itf_get(void); +#endif // (BLE_SP_SERVER) + +#if (BLE_BATT_CLIENT) +extern const struct prf_task_cbs* basc_prf_itf_get(void); +#endif // (BLE_BATT_CLIENT) + +#if (BLE_BATT_SERVER) +extern const struct prf_task_cbs* bass_prf_itf_get(void); +#endif // (BLE_BATT_SERVER) + +#if (BLE_HID_DEVICE) +extern const struct prf_task_cbs* hogpd_prf_itf_get(void); +#endif // (BLE_HID_DEVICE) + +#if (BLE_HID_BOOT_HOST) +extern const struct prf_task_cbs* hogpbh_prf_itf_get(void); +#endif // (BLE_HID_BOOT_HOST) + +#if (BLE_HID_REPORT_HOST) +extern const struct prf_task_cbs* hogprh_prf_itf_get(void); +#endif // (BLE_HID_REPORT_HOST) + +#if (BLE_GL_COLLECTOR) +extern const struct prf_task_cbs* glpc_prf_itf_get(void); +#endif // (BLE_GL_COLLECTOR) + +#if (BLE_GL_SENSOR) +extern const struct prf_task_cbs* glps_prf_itf_get(void); +#endif // (BLE_GL_SENSOR) + +#if (BLE_RSC_COLLECTOR) +extern const struct prf_task_cbs* rscpc_prf_itf_get(void); +#endif // (BLE_RSC_COLLECTOR) + +#if (BLE_RSC_SENSOR) +extern const struct prf_task_cbs* rscps_prf_itf_get(void); +#endif // (BLE_RSC_COLLECTOR) + +#if (BLE_CSC_COLLECTOR) +extern const struct prf_task_cbs* cscpc_prf_itf_get(void); +#endif // (BLE_CSC_COLLECTOR) + +#if (BLE_CSC_SENSOR) +extern const struct prf_task_cbs* cscps_prf_itf_get(void); +#endif // (BLE_CSC_COLLECTOR) + +#if (BLE_AN_CLIENT) +extern const struct prf_task_cbs* anpc_prf_itf_get(void); +#endif // (BLE_AN_CLIENT) + +#if (BLE_AN_SERVER) +extern const struct prf_task_cbs* anps_prf_itf_get(void); +#endif // (BLE_AN_SERVER) + +#if (BLE_PAS_CLIENT) +extern const struct prf_task_cbs* paspc_prf_itf_get(void); +#endif // (BLE_PAS_CLIENT) + +#if (BLE_PAS_SERVER) +extern const struct prf_task_cbs* pasps_prf_itf_get(void); +#endif // (BLE_PAS_SERVER) + +#if (BLE_CP_COLLECTOR) +extern const struct prf_task_cbs* cppc_prf_itf_get(void); +#endif //(BLE_CP_COLLECTOR) + +#if (BLE_CP_SENSOR) +extern const struct prf_task_cbs* cpps_prf_itf_get(void); +#endif //(BLE_CP_SENSOR) + +#if (BLE_LN_COLLECTOR) +extern const struct prf_task_cbs* lanc_prf_itf_get(void); +#endif //(BLE_CP_COLLECTOR) + +#if (BLE_LN_SENSOR) +extern const struct prf_task_cbs* lans_prf_itf_get(void); +#endif //(BLE_CP_SENSOR) + +#if (BLE_IPS_SERVER) +extern const struct prf_task_cbs* ipss_prf_itf_get(void); +#endif //(BLE_IPS_SERVER) + +#if (BLE_IPS_CLIENT) +extern const struct prf_task_cbs* ipsc_prf_itf_get(void); +#endif //(BLE_IPS_CLIENT) + +#if (BLE_ENV_SERVER) +extern const struct prf_task_cbs* envs_prf_itf_get(void); +#endif //(BLE_ENV_SERVER) + +#if (BLE_ENV_CLIENT) +extern const struct prf_task_cbs* envc_prf_itf_get(void); +#endif //(BLE_ENV_CLIENT + +#if (BLE_WSC_SERVER) +extern const struct prf_task_cbs* wscs_prf_itf_get(void); +#endif //(BLE_WSC_SERVER) + +#if (BLE_WSC_CLIENT) +extern const struct prf_task_cbs* wscc_prf_itf_get(void); +#endif //(BLE_WSC_CLIENT + +#if (BLE_BCS_SERVER) +extern const struct prf_task_cbs* bcss_prf_itf_get(void); +#endif //(BLE_BCS_SERVER) + +#if (BLE_BCS_CLIENT) +extern const struct prf_task_cbs* bcsc_prf_itf_get(void); +#endif //(BLE_BCS_CLIENT) + +#ifdef BLE_AM0_HEARING_AID_SERV +extern const struct prf_task_cbs* am0_has_prf_itf_get(void); +#endif // BLE_AM0_HEARING_AID_SERV + +#if (BLE_UDS_SERVER) +extern const struct prf_task_cbs* udss_prf_itf_get(void); +#endif //(BLE_UDS_SERVER) + +#if (BLE_UDS_CLIENT) +extern const struct prf_task_cbs* udsc_prf_itf_get(void); +#endif //(BLE_UDS_CLIENT) + +#if (BLE_VOICEPATH) +extern const struct prf_task_cbs* voicepath_prf_itf_get(void); +#endif //(BLE_VOICEPATH) + +#if (BLE_DATAPATH_SERVER) +extern const struct prf_task_cbs* datapathps_prf_itf_get(void); +#endif //(BLE_DATAPATH_SERVER) + +#if (BLE_OTA) +extern const struct prf_task_cbs* ota_prf_itf_get(void); +#endif //(BLE_OTA) + +#if (BLE_TOTA) +extern const struct prf_task_cbs* tota_prf_itf_get(void); +#endif //(BLE_TOTA) + +#if (BLE_BMS) +extern const struct prf_task_cbs* bms_prf_itf_get(void); +#endif //(BLE_BMS) + + +#if (BLE_ANC_CLIENT) +extern const struct prf_task_cbs* ancc_prf_itf_get(void); +#endif //(BLE_ANC_CLIENT) + +#if (BLE_AMS_CLIENT) +extern const struct prf_task_cbs* amsc_prf_itf_get(void); +#endif //(BLE_AMS_CLIENT) + +#if (BLE_GFPS_PROVIDER) +extern const struct prf_task_cbs* gfpsp_prf_itf_get(void); +#endif //(BLE_GFPS_PROVIDER) + +#ifdef BLE_AI_VOICE +extern const struct prf_task_cbs* ai_prf_itf_get(void); +#endif + +#if (ANCS_PROXY_ENABLE) +extern const struct prf_task_cbs* ancs_proxy_prf_itf_get(void); +extern const struct prf_task_cbs* ams_proxy_prf_itf_get(void); +#endif + +#if (BLE_TILE) +extern const struct prf_task_cbs* tile_prf_itf_get(void); +#endif //(BLE_TILE) + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * MACROS + **************************************************************************************** + */ + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ +struct prf_env_tag prf_env; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve profile interface + **************************************************************************************** + */ +static const struct prf_task_cbs * prf_itf_get(uint16_t task_id) +{ + const struct prf_task_cbs* prf_cbs = NULL; + + BLE_DBG(">>>>>> prf_itf_get task_id: %d task_id %d<<<<<<\n", KE_TYPE_GET(task_id), task_id); + switch(KE_TYPE_GET(task_id)) + { + #if (BLE_HT_THERMOM) + case TASK_ID_HTPT: + prf_cbs = htpt_prf_itf_get(); + break; + #endif // (BLE_HT_THERMOM) + + #if (BLE_HT_COLLECTOR) + case TASK_ID_HTPC: + prf_cbs = htpc_prf_itf_get(); + break; + #endif // (BLE_HT_COLLECTOR) + + #if (BLE_DIS_SERVER) + case TASK_ID_DISS: + prf_cbs = diss_prf_itf_get(); + break; + #endif // (BLE_DIS_SERVER) + + #if (BLE_DIS_CLIENT) + case TASK_ID_DISC: + prf_cbs = disc_prf_itf_get(); + break; + #endif // (BLE_DIS_CLIENT) + + #if (BLE_BP_SENSOR) + case TASK_ID_BLPS: + prf_cbs = blps_prf_itf_get(); + break; + #endif // (BLE_BP_SENSOR) + + #if (BLE_BP_COLLECTOR) + case TASK_ID_BLPC: + prf_cbs = blpc_prf_itf_get(); + break; + #endif // (BLE_BP_COLLECTOR) + + #if (BLE_TIP_SERVER) + case TASK_ID_TIPS: + prf_cbs = tips_prf_itf_get(); + break; + #endif // (BLE_TIP_SERVER) + + #if (BLE_TIP_CLIENT) + case TASK_ID_TIPC: + prf_cbs = tipc_prf_itf_get(); + break; + #endif // (BLE_TIP_CLIENT) + + #if (BLE_HR_SENSOR) + case TASK_ID_HRPS: + prf_cbs = hrps_prf_itf_get(); + break; + #endif // (BLE_HR_SENSOR) + + #if (BLE_HR_COLLECTOR) + case TASK_ID_HRPC: + prf_cbs = hrpc_prf_itf_get(); + break; + #endif // (BLE_HR_COLLECTOR) + + #if (BLE_FINDME_LOCATOR) + case TASK_ID_FINDL: + prf_cbs = findl_prf_itf_get(); + break; + #endif // (BLE_FINDME_LOCATOR) + + #if (BLE_FINDME_TARGET) + case TASK_ID_FINDT: + prf_cbs = findt_prf_itf_get(); + break; + #endif // (BLE_FINDME_TARGET) + + #if (BLE_PROX_MONITOR) + case TASK_ID_PROXM: + prf_cbs = proxm_prf_itf_get(); + break; + #endif // (BLE_PROX_MONITOR) + + #if (BLE_PROX_REPORTER) + case TASK_ID_PROXR: + prf_cbs = proxr_prf_itf_get(); + break; + #endif // (BLE_PROX_REPORTER) + + #if (BLE_SP_SERVER) + case TASK_ID_SCPPS: + prf_cbs = scpps_prf_itf_get(); + break; + #endif // (BLE_SP_SERVER) + + #if (BLE_SP_CLIENT) + case TASK_ID_SCPPC: + prf_cbs = scppc_prf_itf_get(); + break; + #endif // (BLE_SP_CLIENT) + + #if (BLE_BATT_SERVER) + case TASK_ID_BASS: + prf_cbs = bass_prf_itf_get(); + break; + #endif // (BLE_BATT_SERVER) + + #if (BLE_BATT_CLIENT) + case TASK_ID_BASC: + prf_cbs = basc_prf_itf_get(); + break; + #endif // (BLE_BATT_CLIENT) + + #if (BLE_HID_DEVICE) + case TASK_ID_HOGPD: + prf_cbs = hogpd_prf_itf_get(); + break; + #endif // (BLE_HID_DEVICE) + + #if (BLE_HID_BOOT_HOST) + case TASK_ID_HOGPBH: + prf_cbs = hogpbh_prf_itf_get(); + break; + #endif // (BLE_HID_BOOT_HOST) + + #if (BLE_HID_REPORT_HOST) + case TASK_ID_HOGPRH: + prf_cbs = hogprh_prf_itf_get(); + break; + #endif // (BLE_HID_REPORT_HOST) + + #if (BLE_GL_COLLECTOR) + case TASK_ID_GLPC: + prf_cbs = glpc_prf_itf_get(); + break; + #endif // (BLE_GL_COLLECTOR) + + #if (BLE_GL_SENSOR) + case TASK_ID_GLPS: + prf_cbs = glps_prf_itf_get(); + break; + #endif // (BLE_GL_SENSOR) + + #if (BLE_RSC_COLLECTOR) + case TASK_ID_RSCPC: + prf_cbs = rscpc_prf_itf_get(); + break; + #endif // (BLE_RSC_COLLECTOR) + + #if (BLE_RSC_SENSOR) + case TASK_ID_RSCPS: + prf_cbs = rscps_prf_itf_get(); + break; + #endif // (BLE_RSC_SENSOR) + + #if (BLE_CSC_COLLECTOR) + case TASK_ID_CSCPC: + prf_cbs = cscpc_prf_itf_get(); + break; + #endif // (BLE_CSC_COLLECTOR) + + #if (BLE_CSC_SENSOR) + case TASK_ID_CSCPS: + prf_cbs = cscps_prf_itf_get(); + break; + #endif // (BLE_CSC_SENSOR) + + #if (BLE_CP_COLLECTOR) + case TASK_ID_CPPC: + prf_cbs = cppc_prf_itf_get(); + break; + #endif // (BLE_CP_COLLECTOR) + + #if (BLE_CP_SENSOR) + case TASK_ID_CPPS: + prf_cbs = cpps_prf_itf_get(); + break; + #endif // (BLE_CP_SENSOR) + + #if (BLE_LN_COLLECTOR) + case TASK_ID_LANC: + prf_cbs = lanc_prf_itf_get(); + break; + #endif // (BLE_LN_COLLECTOR) + + #if (BLE_LN_SENSOR) + case TASK_ID_LANS: + prf_cbs = lans_prf_itf_get(); + break; + #endif // (BLE_LN_SENSOR) + + #if (BLE_AN_CLIENT) + case TASK_ID_ANPC: + prf_cbs = anpc_prf_itf_get(); + break; + #endif // (BLE_AN_CLIENT) + + #if (BLE_AN_SERVER) + case TASK_ID_ANPS: + prf_cbs = anps_prf_itf_get(); + break; + #endif // (BLE_AN_SERVER) + + #if (BLE_PAS_CLIENT) + case TASK_ID_PASPC: + prf_cbs = paspc_prf_itf_get(); + break; + #endif // (BLE_PAS_CLIENT) + + #if (BLE_PAS_SERVER) + case TASK_ID_PASPS: + prf_cbs = pasps_prf_itf_get(); + break; + #endif // (BLE_PAS_SERVER) + + #ifdef BLE_AM0_HEARING_AID_SERV + case TASK_ID_AM0_HAS: + prf_cbs = am0_has_prf_itf_get(); + break; + #endif // defined(BLE_AM0_HEARING_AID_SERV) + + #if (BLE_IPS_SERVER) + case TASK_ID_IPSS: + prf_cbs = ipss_prf_itf_get(); + break; + #endif //(BLE_IPS_SERVER) + + #if (BLE_IPS_CLIENT) + case TASK_ID_IPSC: + prf_cbs = ipsc_prf_itf_get(); + break; + #endif //(BLE_IPS_CLIENT) + + #if (BLE_ENV_SERVER) + case TASK_ID_ENVS: + prf_cbs = envs_prf_itf_get(); + break; + #endif //(BLE_ENV_SERVER) + + #if (BLE_ENV_CLIENT) + case TASK_ID_ENVC: + prf_cbs = envc_prf_itf_get(); + break; + #endif //(BLE_ENV_CLIENT + + #if (BLE_WSC_SERVER) + case TASK_ID_WSCS: + prf_cbs = wscs_prf_itf_get(); + break; + #endif //(BLE_WSC_SERVER) + + #if (BLE_WSC_CLIENT) + case TASK_ID_WSCC: + prf_cbs = wscc_prf_itf_get(); + break; + #endif //(BLE_WSC_CLIENT + + #if (BLE_BCS_SERVER) + case TASK_ID_BCSS: + prf_cbs = bcss_prf_itf_get(); + break; + #endif //(BLE_BCS_SERVER) + + #if (BLE_BCS_CLIENT) + case TASK_ID_BCSC: + prf_cbs = bcsc_prf_itf_get(); + break; + #endif //(BLE_BCS_CLIENT) + + #if (BLE_UDS_SERVER) + case TASK_ID_UDSS: + prf_cbs = udss_prf_itf_get(); + break; + #endif //(BLE_UDS_SERVER) + + #if (BLE_UDS_CLIENT) + case TASK_ID_UDSC: + prf_cbs = udsc_prf_itf_get(); + break; + #endif //(BLE_UDS_CLIENT) + + #if (BLE_VOICEPATH) + case TASK_ID_VOICEPATH: + prf_cbs = voicepath_prf_itf_get(); + break; + #endif //(TASK_ID_VOICEPATH) + + #if (BLE_OTA) + case TASK_ID_OTA: + prf_cbs = ota_prf_itf_get(); + break; + #endif //(BLE_OTA) + + #if (BLE_TOTA) + case TASK_ID_TOTA: + prf_cbs = tota_prf_itf_get(); + break; + #endif //(BLE_TOTA) + + #if (BLE_BMS) + case TASK_ID_BMS: + prf_cbs = bms_prf_itf_get(); + break; + #endif //(BLE_BMS) + + #if (BLE_ANC_CLIENT) + case TASK_ID_ANCC: + prf_cbs = ancc_prf_itf_get(); + break; + #endif //(BLE_ANC_CLIENT) + + #if (BLE_AMS_CLIENT) + case TASK_ID_AMSC: + prf_cbs = amsc_prf_itf_get(); + break; + #endif //(BLE_AMS_CLIENT) + + #if (BLE_TILE) + case TASK_ID_TILE: + prf_cbs = tile_prf_itf_get(); + break; + #endif //(TASK_ID_TILE) + + #if (ANCS_PROXY_ENABLE) + case TASK_ID_ANCSP: + prf_cbs = ancs_proxy_prf_itf_get(); + break; + case TASK_ID_AMSP: + prf_cbs = ams_proxy_prf_itf_get(); + break; + #endif //(ANCS_PROXY_ENABLE) + + #if (BLE_GFPS_PROVIDER) + case TASK_ID_GFPSP: + prf_cbs = gfpsp_prf_itf_get(); + break; + #endif //(BLE_GFPS_PROVIDER) + + #if (BLE_AI_VOICE) + case TASK_ID_AI: + prf_cbs = ai_prf_itf_get(); + break; + #endif //(BLE_AMA) + + #if (BLE_DATAPATH_SERVER) + case TASK_ID_DATAPATHPS: + prf_cbs = datapathps_prf_itf_get(); + break; + #endif //(BLE_DATAPATH_SERVER) + + default: /* Nothing to do */ + break; + } + + return prf_cbs; +} + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ +void prf_init(bool reset) +{ + uint8_t i; + + BLE_FUNC_ENTER(); + + BLE_DBG(">>>>>> prf_create reset %d<<<<<<\n", reset); + if (!reset) + { + // FW boot profile initialization + for(i = 0; i < BLE_NB_PROFILES ; i++) + { + prf_env.prf[i].env = NULL; + prf_env.prf[i].task = TASK_GAPC + i +1; + prf_env.prf[i].id = TASK_ID_INVALID; + + // Initialize Task Descriptor + prf_env.prf[i].desc.msg_handler_tab = NULL; + prf_env.prf[i].desc.state = NULL; + prf_env.prf[i].desc.idx_max = 0; + prf_env.prf[i].desc.msg_cnt = 0; + + ke_task_create(prf_env.prf[i].task, &(prf_env.prf[i].desc)); + BLE_DBG("prf_init prf_env.prf[%d].task: %d\n", i, prf_env.prf[i].task); + } + } + else + { + // FW boot profile destruction + for(i = 0; i < BLE_NB_PROFILES ; i++) + { + // Get Profile API + const struct prf_task_cbs * cbs = prf_itf_get(prf_env.prf[i].id); + if(cbs != NULL) + { + // request to destroy profile + cbs->destroy(&(prf_env.prf[i])); + } + // unregister profile + prf_env.prf[i].id = TASK_ID_INVALID; + prf_env.prf[i].desc.msg_handler_tab = NULL; + prf_env.prf[i].desc.state = NULL; + prf_env.prf[i].desc.idx_max = 0; + prf_env.prf[i].desc.msg_cnt = 0; + + // Request kernel to flush task messages + ke_task_msg_flush(KE_TYPE_GET(prf_env.prf[i].task)); + } + } + + BLE_FUNC_LEAVE(); +} + + +uint8_t prf_add_profile(struct gapm_profile_task_add_cmd * params, ke_task_id_t* prf_task) +{ + uint8_t i; + uint8_t status = GAP_ERR_NO_ERROR; + + BLE_DBG(">>>>>> prf_add_profile <<<<<<\n"); + + // retrieve profile callback + const struct prf_task_cbs * cbs = prf_itf_get(params->prf_task_id); + if(cbs == NULL) + { + // profile API not available + status = GAP_ERR_INVALID_PARAM; + } + + // check if profile not already present in task list + if(status == GAP_ERR_NO_ERROR) + { + for(i = 0; i < BLE_NB_PROFILES ; i++) + { + if(prf_env.prf[i].id == params->prf_task_id) + { + status = GAP_ERR_NOT_SUPPORTED; + break; + } + } + } + + if(status == GAP_ERR_NO_ERROR) + { + // find first available task + for(i = 0; i < BLE_NB_PROFILES ; i++) + { + // available task found + if(prf_env.prf[i].id == TASK_ID_INVALID) + { + // initialize profile + status = cbs->init(&(prf_env.prf[i]), &(params->start_hdl), params->app_task, params->sec_lvl, params->param); + + // initialization succeed + if(status == GAP_ERR_NO_ERROR) + { + // register profile + prf_env.prf[i].id = params->prf_task_id; + *prf_task = prf_env.prf[i].task; + } + break; + } + } + + if(i == BLE_NB_PROFILES) + { + status = GAP_ERR_INSUFF_RESOURCES; + } + } + + return (status); +} + + + +void prf_create(uint8_t conidx) +{ + uint8_t i; + /* simple connection creation handler, nothing to do. */ + + BLE_DBG(">>>>>> prf_create <<<<<<\n"); + // execute create function of each profiles + for(i = 0; i < BLE_NB_PROFILES ; i++) + { + // Get Profile API + const struct prf_task_cbs * cbs = prf_itf_get(prf_env.prf[i].id); + if(cbs != NULL) + { + // call create callback + cbs->create(&(prf_env.prf[i]), conidx); + } + } +} + + +void prf_cleanup(uint8_t conidx, uint8_t reason) +{ + uint8_t i; + /* simple connection creation handler, nothing to do. */ + + BLE_DBG(">>>>>> prf_cleanup <<<<<<\n"); + // execute create function of each profiles + for(i = 0; i < BLE_NB_PROFILES ; i++) + { + // Get Profile API + const struct prf_task_cbs * cbs = prf_itf_get(prf_env.prf[i].id); + if(cbs != NULL) + { + // call cleanup callback + cbs->cleanup(&(prf_env.prf[i]), conidx, reason); + } + } +} + + +prf_env_t* prf_env_get(uint16_t prf_id) +{ + prf_env_t* env = NULL; + uint8_t i; + // find if profile present in profile tasks + BLE_DBG("%s prf_id %d", __func__, prf_id); + for(i = 0; i < BLE_NB_PROFILES ; i++) + { + // check if profile identifier is known + if(prf_env.prf[i].id == prf_id) + { + env = prf_env.prf[i].env; + break; + } + } + + return env; +} + +ke_task_id_t prf_src_task_get(prf_env_t* env, uint8_t conidx) +{ + ke_task_id_t task = PERM_GET(env->prf_task, PRF_TASK); + + BLE_DBG("%s conidx %d", __func__, conidx); + if(PERM_GET(env->prf_task, PRF_MI)) + { + task = KE_BUILD_ID(task, conidx); + } + + return task; +} + +ke_task_id_t prf_dst_task_get(prf_env_t* env, uint8_t conidx) +{ + ke_task_id_t task = PERM_GET(env->app_task, PRF_TASK); + + BLE_DBG("%s app_task %d conidx %d", __func__, env->app_task, conidx); + if(PERM_GET(env->app_task, PRF_MI)) + { + task = KE_BUILD_ID(task, conidx); + } + + return task; +} + + +ke_task_id_t prf_get_id_from_task(ke_msg_id_t task) +{ + ke_task_id_t id = TASK_ID_INVALID; + uint8_t idx = KE_IDX_GET(task); + uint8_t i; + task = KE_TYPE_GET(task); + + BLE_DBG("%s task %d", __func__, task); + // find if profile present in profile tasks + for(i = 0; i < BLE_NB_PROFILES ; i++) + { + // check if profile identifier is known + if(prf_env.prf[i].task == task) + { + id = prf_env.prf[i].id; + break; + } + } + + return KE_BUILD_ID(id, idx); +} + +ke_task_id_t prf_get_task_from_id(ke_msg_id_t id) +{ + ke_task_id_t task = TASK_NONE; + uint8_t idx = KE_IDX_GET(id); + uint8_t i; + id = KE_TYPE_GET(id); + + BLE_DBG("%s id %d", __func__, id); + // find if profile present in profile tasks + for(i = 0; i < BLE_NB_PROFILES ; i++) + { + // check if profile identifier is known + if(prf_env.prf[i].id == id) + { + task = prf_env.prf[i].task; + break; + } + } + + return KE_BUILD_ID(task, idx); +} + + +#endif // (BLE_PROFILES) + +/// @} PRF diff --git a/services/ble_profiles/prf/prf_utils.c b/services/ble_profiles/prf/prf_utils.c new file mode 100644 index 0000000..cfe2a4c --- /dev/null +++ b/services/ble_profiles/prf/prf_utils.c @@ -0,0 +1,384 @@ +/** + **************************************************************************************** + * @addtogroup PRF_UTILS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_PROFILES) +#if (BLE_SERVER_PRF || BLE_CLIENT_PRF) + +#include +#include +#include "ke_task.h" +#include "attm.h" +#include "gattc_task.h" +#include "prf_utils.h" +#include "gap.h" +#include "gapc.h" + +#include "ke_mem.h" +#include "co_utils.h" +#include "co_error.h" + +#endif /* (BLE_SERVER_PRF || BLE_CLIENT_PRF) */ + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +#if (BLE_BATT_SERVER) +void prf_pack_char_pres_fmt(uint8_t *packed_val, const struct prf_char_pres_fmt* char_pres_fmt) +{ + *packed_val = char_pres_fmt->format; + *(packed_val + 1) = char_pres_fmt->exponent; + co_write16p(packed_val + 2, char_pres_fmt->unit); + *(packed_val + 4) = char_pres_fmt->name_space; + co_write16p(packed_val + 5, char_pres_fmt->description); +} +#endif // (BLE_BATT_SERVER) + +#if (BLE_BATT_CLIENT) +void prf_unpack_char_pres_fmt(const uint8_t *packed_val, struct prf_char_pres_fmt* char_pres_fmt) +{ + + char_pres_fmt->format = *packed_val; + char_pres_fmt->exponent = *(packed_val + 1); + char_pres_fmt->unit = co_read16p(packed_val + 2); + char_pres_fmt->name_space = *(packed_val + 4); + char_pres_fmt->description = co_read16p(packed_val + 5); +} +#endif // (BLE_BATT_CLIENT) + + +#if (BLE_CLIENT_PRF) +void prf_read_char_send(prf_env_t *prf_env, uint8_t conidx, + uint16_t shdl, uint16_t ehdl, uint16_t valhdl) +{ + struct gattc_read_cmd * req = KE_MSG_ALLOC(GATTC_READ_CMD, KE_BUILD_ID(TASK_GATTC, conidx), + prf_src_task_get(prf_env, conidx), gattc_read_cmd); + //request type + req->operation = GATTC_READ; + req->nb = 1; + req->req.simple.offset = 0; + req->req.simple.length = 0; + req->req.simple.handle = valhdl; + + //send request to GATT + ke_msg_send(req); +} + +void prf_register_atthdl2gatt(prf_env_t *prf_env, uint8_t conidx, struct prf_svc *svc) +{ + if(svc->shdl != ATT_INVALID_HANDLE) + { + //register profile task in gatt for indication/notifications + struct gattc_reg_to_peer_evt_cmd * reg = KE_MSG_ALLOC(GATTC_REG_TO_PEER_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(prf_env, conidx), + gattc_reg_to_peer_evt_cmd); + + reg->operation = GATTC_REGISTER; + reg->start_hdl = svc->shdl; + reg->end_hdl = svc->ehdl; + + ke_msg_send(reg); + } +} + +void prf_unregister_atthdl2gatt(prf_env_t *prf_env, uint8_t conidx, struct prf_svc *svc) +{ + if(svc->shdl != ATT_INVALID_HANDLE) + { + //un register profile task in gatt for indication/notifications + struct gattc_reg_to_peer_evt_cmd * reg = KE_MSG_ALLOC(GATTC_REG_TO_PEER_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(prf_env, conidx), + gattc_reg_to_peer_evt_cmd); + + reg->operation = GATTC_UNREGISTER; + reg->start_hdl = svc->shdl; + reg->end_hdl = svc->ehdl; + + ke_msg_send(reg); + } +} + + +void prf_disc_svc_send(prf_env_t *prf_env, uint8_t conidx, uint16_t uuid) +{ + //send GATT discover primary services by UUID request + struct gattc_sdp_svc_disc_cmd * svc_req = KE_MSG_ALLOC_DYN(GATTC_SDP_SVC_DISC_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(prf_env, conidx), + gattc_sdp_svc_disc_cmd, ATT_UUID_16_LEN); + + //gatt request type: by UUID + svc_req->operation = GATTC_SDP_DISC_SVC; + //start handle; + svc_req->start_hdl = ATT_1ST_REQ_START_HDL; + //end handle + svc_req->end_hdl = ATT_1ST_REQ_END_HDL; + + // UUID search + svc_req->uuid_len = ATT_UUID_16_LEN; + + //set the first two bytes to the value array, LSB to MSB:Health Thermometer Service UUID first + co_write16p(&(svc_req->uuid[0]), uuid); + + //send the message to GATT, which will send back the response when it gets it + ke_msg_send(svc_req); +} + + + +void prf_gatt_write(prf_env_t *prf_env, uint8_t conidx, + uint16_t handle, uint8_t* value, uint16_t length, uint8_t operation) +{ + if(handle != ATT_INVALID_HANDLE) + { + struct gattc_write_cmd *wr_char = KE_MSG_ALLOC_DYN(GATTC_WRITE_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(prf_env, conidx), + gattc_write_cmd, length); + + // Offset + wr_char->offset = 0x0000; + // cursor always 0 + wr_char->cursor = 0x0000; + // Write Type + wr_char->operation = operation; + // Characteristic Value attribute handle + wr_char->handle = handle; + // Value Length + wr_char->length = length; + // Auto Execute + wr_char->auto_execute = true; + // Value + memcpy(&wr_char->value[0], value, length); + + // Send the message + ke_msg_send(wr_char); + } +} + +void prf_gatt_write_ntf_ind(prf_env_t *prf_env, uint8_t conidx, uint16_t handle, uint16_t ntf_ind_cfg) +{ + uint8_t value[2]; + + // put value in air format + co_write16p((&value[0]), ntf_ind_cfg); + // write value over GATT + prf_gatt_write(prf_env, conidx, handle, value, 2, GATTC_WRITE); +} + +uint8_t prf_check_svc_char_validity(uint8_t nb_chars, + const struct prf_char_inf* chars, + const struct prf_char_def* chars_req) +{ + uint8_t status = GAP_ERR_NO_ERROR; + uint8_t i; + + for(i = 0; ((i < nb_chars) && (status == GAP_ERR_NO_ERROR)); i++) + { + if (chars[i].char_hdl == ATT_INVALID_HANDLE) + { + //If Characteristic is not present, check requirements + if (chars_req[i].req_flag == ATT_MANDATORY) + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + } + else + { + //If Characteristic is present, check properties + if((chars[i].prop & chars_req[i].prop_mand) != chars_req[i].prop_mand) + { + status = PRF_ERR_STOP_DISC_WRONG_CHAR_PROP; + } + } + } + + return (status); +} + + +uint8_t prf_check_svc_char_desc_validity(uint8_t descs_size, + const struct prf_char_desc_inf* descs, + const struct prf_char_desc_def* descs_req, + const struct prf_char_inf* chars) +{ + uint8_t status = GAP_ERR_NO_ERROR; + uint8_t i; + + for(i = 0; ((i < descs_size) && (status == GAP_ERR_NO_ERROR)) ; i++) + { + if (descs[i].desc_hdl == ATT_INVALID_HANDLE) + { + //If Descriptor is missing, check if it is mandatory + if (descs_req[i].req_flag == ATT_MANDATORY) + { + //Check if Char is present + if (chars[descs_req[i].char_code].char_hdl != ATT_INVALID_HANDLE) + { + //Char. is present and descriptor not, error + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + } + } + } + + return (status); +} + +void prf_extract_svc_info(const struct gattc_sdp_svc_ind* param, + uint8_t nb_chars, const struct prf_char_def* chars_req, struct prf_char_inf* chars, + uint8_t nb_descs, const struct prf_char_desc_def* descs_req, struct prf_char_desc_inf* descs) +{ + //Counters + uint8_t svc_char; + uint8_t svc_desc; + uint8_t fnd_att; + + for (fnd_att=0; fnd_att< (param->end_hdl - param->start_hdl); fnd_att++) + { + if(param->info[fnd_att].att_type == GATTC_SDP_ATT_CHAR) + { + uint16_t char_hdl = param->start_hdl+ 1 + fnd_att; + uint16_t val_hdl = param->info[fnd_att].att_char.handle; + uint8_t val_prop = param->info[fnd_att].att_char.prop; + uint8_t char_idx = fnd_att; + + // check that value handle is in a valid range + if((val_hdl <= param->end_hdl) && (val_hdl > (param->start_hdl + fnd_att))) + { + // retrieve value index + uint8_t val_idx = (val_hdl - param->start_hdl - 1); + + //Look over requested characteristics + for (svc_char=0; svc_charinfo[val_idx].att.uuid, + param->info[val_idx].att.uuid_len, chars_req[svc_char].uuid)) + { + //Save properties and handles + chars[svc_char].char_hdl = char_hdl; + chars[svc_char].val_hdl = val_hdl; + chars[svc_char].prop = val_prop; + + // find end of characteristic handle and discover descriptors + do + { + fnd_att++; + + // found a descriptor + if(param->info[fnd_att].att_type == GATTC_SDP_ATT_DESC) + { + //Retrieve characteristic descriptor handle using UUID + for(svc_desc = 0; svc_descinfo[fnd_att].att.uuid, + param->info[fnd_att].att.uuid_len, descs_req[svc_desc].uuid))) + { + descs[svc_desc].desc_hdl = param->start_hdl + 1 + fnd_att; + // search for next descriptor + break; + } + } + } + } while(((param->start_hdl+ 1 + fnd_att) <= param->end_hdl) + && (param->info[fnd_att].att_type != GATTC_SDP_ATT_CHAR) + && (param->info[fnd_att].att_type != GATTC_SDP_INC_SVC)); + + // return to previous valid value + fnd_att--; + // previous handle was end of the characteristic + chars[svc_char].char_ehdl_off = fnd_att - char_idx; + + // search next characteristic + break; + } + } + } + } + } +} + + +#endif //(BLE_CLIENT_PRF) + +#if (BLE_CLIENT_PRF || BLE_TIP_SERVER || BLE_AN_SERVER || BLE_PAS_SERVER) + +void prf_client_att_info_rsp(prf_env_t *prf_env, uint8_t conidx, uint16_t msg_id, + uint8_t status, struct gattc_read_ind const* read_ind) +{ + // retrieve value length + uint16_t length = 0; + if(status == GAP_ERR_NO_ERROR) + { + length = read_ind->length; + } + + // prepare response + struct prf_att_info *rsp = KE_MSG_ALLOC_DYN(msg_id, + prf_dst_task_get(prf_env, conidx), prf_src_task_get(prf_env, conidx), + prf_att_info, length); + + rsp->status = status; + rsp->handle = ATT_INVALID_HDL; + rsp->length = length; + + // set value array + if (read_ind != NULL) + { + rsp->handle = read_ind->handle; + memcpy(&(rsp->value[0]), &(read_ind->value[0]), length); + } + + ke_msg_send(rsp); +} +#endif //(BLE_CLIENT_PRF || BLE_TIP_SERVER || BLE_AN_SERVER || BLE_PAS_SERVER) + + +#if ((BLE_SERVER_PRF || BLE_CLIENT_PRF)) + +uint8_t prf_pack_date_time(uint8_t *packed_date, const struct prf_date_time* date_time) +{ + co_write16p(packed_date, date_time->year); + *(packed_date + 2) = date_time->month; + *(packed_date + 3) = date_time->day; + *(packed_date + 4) = date_time->hour; + *(packed_date + 5) = date_time->min; + *(packed_date + 6) = date_time->sec; + + return 7; +} +uint8_t prf_unpack_date_time(uint8_t *packed_date, struct prf_date_time* date_time) +{ + date_time->year = co_read16p(&(packed_date[0])); + date_time->month = packed_date[2]; + date_time->day = packed_date[3]; + date_time->hour = packed_date[4]; + date_time->min = packed_date[5]; + date_time->sec = packed_date[6]; + + return 7; +} + + +#endif /* ((BLE_SERVER_PRF || BLE_CLIENT_PRF)) */ +#endif // (BLE_PROFILES) +/// @} PRF_UTILS + diff --git a/services/ble_profiles/prf/prf_utils_128.c b/services/ble_profiles/prf/prf_utils_128.c new file mode 100644 index 0000000..49efa70 --- /dev/null +++ b/services/ble_profiles/prf/prf_utils_128.c @@ -0,0 +1,164 @@ +/** + **************************************************************************************** + * @addtogroup PRF_UTILS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_CLIENT_PRF) +#include +#include +#include "ke_task.h" +#include "co_error.h" +#include "attm.h" +#include "gattc_task.h" +#include "prf_utils_128.h" +#include "ke_mem.h" +#include "gap.h" +#include "gapc.h" +#endif //(BLE_CLIENT_PRF) + +#if (BLE_CLIENT_PRF) + +void prf_disc_svc_send_128(prf_env_t *prf_env, uint8_t conidx, uint8_t *uuid_128) +{ + //send GATT discover primary services by UUID request: find by type request + struct gattc_disc_cmd * svc_req = KE_MSG_ALLOC_DYN(GATTC_SDP_SVC_DISC_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(prf_env, conidx), + gattc_disc_cmd, ATT_UUID_128_LEN); + + //gatt request type: by UUID + svc_req->operation = GATTC_SDP_DISC_SVC; + //start handle; + svc_req->start_hdl = ATT_1ST_REQ_START_HDL; + //end handle + svc_req->end_hdl = ATT_1ST_REQ_END_HDL; + + // UUID search + svc_req->uuid_len = ATT_UUID_128_LEN; + + // set 128 bit UUID for searching + memcpy(&svc_req->uuid[0], uuid_128, (sizeof(uint8_t) * ATT_UUID_128_LEN)); + + //send the message to GATT, which will send back the response when it gets it + ke_msg_send(svc_req); +} + +uint8_t prf_check_svc_char_validity_128(uint8_t nb_chars, + const struct prf_char_inf* chars, + const struct prf_char_def_128* chars_req) +{ + uint8_t status = GAP_ERR_NO_ERROR; + uint8_t i; + + for(i = 0; ((i < nb_chars) && (status == GAP_ERR_NO_ERROR)); i++) + { + if (chars[i].char_hdl == ATT_INVALID_HANDLE) + { + //If Characteristic is not present, check requirements + if (chars_req[i].req_flag == ATT_MANDATORY) + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + } + else + { + //If Characteristic is present, check properties + if((chars[i].prop & chars_req[i].prop_mand) != chars_req[i].prop_mand) + { + status = PRF_ERR_STOP_DISC_WRONG_CHAR_PROP; + } + } + } + + return status; +} + +void prf_extract_svc_info_128(const struct gattc_sdp_svc_ind* param, + uint8_t nb_chars, const struct prf_char_def_128* chars_req, struct prf_char_inf* chars, + uint8_t nb_descs, const struct prf_char_desc_def* descs_req, struct prf_char_desc_inf* descs) +{ + //Counters + uint8_t svc_char; + uint8_t svc_desc; + uint8_t fnd_att; + + for (fnd_att=0; fnd_att< (param->end_hdl - param->start_hdl); fnd_att++) + { + if(param->info[fnd_att].att_type == GATTC_SDP_ATT_CHAR) + { + uint16_t char_hdl = param->start_hdl+ 1 + fnd_att; + uint16_t val_hdl = param->info[fnd_att].att_char.handle; + uint8_t val_prop = param->info[fnd_att].att_char.prop; + uint8_t char_idx = fnd_att; + + // check that value handle is in a valid range + if((val_hdl <= param->end_hdl) && (val_hdl > (param->start_hdl + fnd_att))) + { + // retrieve value index + uint8_t val_idx = (val_hdl - param->start_hdl - 1); + + //Look over requested characteristics + for (svc_char=0; svc_charinfo[val_idx].att.uuid, ATT_UUID_128_LEN, + (uint8_t*)chars_req[svc_char].uuid, ATT_UUID_128_LEN)) + { + //Save properties and handles + chars[svc_char].char_hdl = char_hdl; + chars[svc_char].val_hdl = val_hdl; + chars[svc_char].prop = val_prop; + + // find end of characteristic handle and discover descriptors + do + { + fnd_att++; + + // found a descriptor + if(param->info[fnd_att].att_type == GATTC_SDP_ATT_DESC) + { + //Retrieve characteristic descriptor handle using UUID + for(svc_desc = 0; svc_descinfo[fnd_att].att.uuid, + param->info[fnd_att].att.uuid_len, descs_req[svc_desc].uuid))) + { + descs[svc_desc].desc_hdl = param->start_hdl + 1 + fnd_att; + // search for next descriptor + break; + } + } + } + } while(((param->start_hdl+ 1 + fnd_att) <= param->end_hdl) + && (param->info[fnd_att].att_type != GATTC_SDP_ATT_CHAR) + && (param->info[fnd_att].att_type != GATTC_SDP_INC_SVC)); + + // return to previous valid value + fnd_att--; + // previous handle was end of the characteristic + chars[svc_char].char_ehdl_off = fnd_att - char_idx; + + // search next characteristic + break; + } + } + } + } + } +} + +#endif /*(BLE_SAMPLE128_CLIENT) */ + +/// @} PRF_UTILS + diff --git a/services/ble_profiles/prox/proxm/api/proxm_task.h b/services/ble_profiles/prox/proxm/api/proxm_task.h new file mode 100644 index 0000000..b13b86e --- /dev/null +++ b/services/ble_profiles/prox/proxm/api/proxm_task.h @@ -0,0 +1,151 @@ +#ifndef PROXM_TASK_H_ +#define PROXM_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup PROXMTASK Proximity Monitor Task + * @ingroup PROXM + * @brief Proximity Monitor Task + * + * The Proximity Monitor Task is responsible for handling the API messages received from + * either the Application or internal tasks. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_task.h" // Task definitions +#include "prf_types.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Max number of characteristics for all services +#define PROXM_CHAR_NB_MAX 1 + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +///Proximity Monitor API messages +enum +{ + ///Proximity Monitor role enable request from application. + PROXM_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_PROXM), + /// Proximity Monitor role enable confirmation to application. + PROXM_ENABLE_RSP, + + /// Read LLS Alert or TX Power Level - request + PROXM_RD_REQ, + /// Read LLS Alert or TX Power Level - response + PROXM_RD_RSP, + + ///Set Alert level + PROXM_WR_ALERT_LVL_REQ, + ///Set Alert level response + PROXM_WR_ALERT_LVL_RSP, +}; + +enum +{ + PROXM_LK_LOSS_SVC, + PROXM_IAS_SVC, + PROXM_TX_POWER_SVC, + + PROXM_SVC_NB +}; + +/* + * API Messages Structures + **************************************************************************************** + */ + +/// Service information +struct svc_content +{ + /// Service info + struct prf_svc svc; + + /// Characteristic info: + /// - Alert Level for IAS and LLS + /// - TX Power Level for TXPS + struct prf_char_inf characts[PROXM_CHAR_NB_MAX]; +}; + +/// Proximity monitor enable command structure +struct proxm_enable_req +{ + /// Connection type + uint8_t con_type; + + /// Reporter LLS details kept in APP + struct svc_content lls; + /// Reporter IAS details kept in APP + struct svc_content ias; + /// Reporter TPS details kept in APP + struct svc_content txps; +}; + +/// Proximity monitor enable confirm structure +struct proxm_enable_rsp +{ + /// Status + uint8_t status; + + /// Reporter LLS details to keep in APP + struct svc_content lls; + /// Reporter IAS details to keep in APP + struct svc_content ias; + /// Reporter TPS details to keep in APP + struct svc_content txps; +}; + + +///Parameters of the @ref PROXM_WR_ALERT_LVL_REQ message +struct proxm_wr_alert_lvl_req +{ + /// 0=LLS or 1=IAS, code for the service in which the alert level should be written + uint8_t svc_code; + /// Alert level + uint8_t lvl; +}; + +///Parameters of the @ref PROXM_WR_ALERT_LVL_RSP message +struct proxm_wr_alert_lvl_rsp +{ + /// Write characteristic response status code, may be GATT code or ATT error code. + uint8_t status; +}; + +///Parameters of the @ref PROXM_RD_REQ message +struct proxm_rd_req +{ + /// 0=LLS or 1=TXPS, code for the service in which the alert level should be read + uint8_t svc_code; +}; + +/// Parameters of the @ref PROXM_RD_RSP message +struct proxm_rd_rsp +{ + /// 0=LLS or 1=TXPS, code for the service in which the alert level should be read + uint8_t svc_code; + /// Status + uint8_t status; + /// Value + uint8_t value; +}; + + + +/// @} PROXMTASK + +#endif // PROXM_TASK_H_ diff --git a/services/ble_profiles/prox/proxm/src/proxm.c b/services/ble_profiles/prox/proxm/src/proxm.c new file mode 100644 index 0000000..f55e98f --- /dev/null +++ b/services/ble_profiles/prox/proxm/src/proxm.c @@ -0,0 +1,215 @@ +/** + **************************************************************************************** + * @addtogroup PROXM + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_PROX_MONITOR) + +#include "proxm.h" +#include "proxm_task.h" +#include "prf_utils.h" +#include "gap.h" + +#include "ke_mem.h" + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + + +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialization of the PROXM module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t proxm_init (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct proxm_env_tag* proxm_env = + (struct proxm_env_tag* ) ke_malloc(sizeof(struct proxm_env_tag), KE_MEM_ATT_DB); + + // allocate PROXM required environment variable + env->env = (prf_env_t*) proxm_env; + + proxm_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + proxm_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_PROXM; + proxm_task_init(&(env->desc)); + + for(idx = 0; idx < PROXM_IDX_MAX ; idx++) + { + proxm_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), PROXM_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Destruction of the PROXM module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void proxm_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct proxm_env_tag* proxm_env = (struct proxm_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < PROXM_IDX_MAX ; idx++) + { + if(proxm_env->env[idx] != NULL) + { + ke_free(proxm_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(proxm_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void proxm_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put PROX Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), PROXM_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void proxm_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct proxm_env_tag* proxm_env = (struct proxm_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(proxm_env->env[conidx] != NULL) + { + ke_free(proxm_env->env[conidx]); + proxm_env->env[conidx] = NULL; + } + + /* Put PROX Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), PROXM_FREE); +} +/* +* GLOBAL VARIABLE DEFINITIONS +**************************************************************************************** +*/ + +/// PROXM Task interface required by profile manager +const struct prf_task_cbs proxm_itf = +{ + (prf_init_fnct) proxm_init, + proxm_destroy, + proxm_create, + proxm_cleanup, +}; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* proxm_prf_itf_get(void) +{ + return &proxm_itf; +} + +void proxm_enable_rsp_send(struct proxm_env_tag *proxm_env, uint8_t conidx, uint8_t status) +{ + //format response to app + struct proxm_enable_rsp * cfm = KE_MSG_ALLOC(PROXM_ENABLE_RSP, + prf_dst_task_get(&(proxm_env->prf_env), conidx), + prf_src_task_get(&(proxm_env->prf_env), conidx), + proxm_enable_rsp); + + cfm->lls = proxm_env->env[conidx]->prox[PROXM_LK_LOSS_SVC]; + cfm->ias = proxm_env->env[conidx]->prox[PROXM_IAS_SVC]; + cfm->txps = proxm_env->env[conidx]->prox[PROXM_TX_POWER_SVC]; + cfm->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + // Go to IDLE state + ke_state_set(prf_src_task_get(&(proxm_env->prf_env), conidx), PROXM_IDLE); + } + else + { + // clean-up environment variable allocated for task instance + ke_free(proxm_env->env[conidx]); + proxm_env->env[conidx] = NULL; + } + + ke_msg_send(cfm); +} + +uint8_t proxm_validate_request(struct proxm_env_tag *proxm_env, uint8_t conidx, uint8_t char_code) +{ + uint8_t status = GAP_ERR_NO_ERROR; + // check if feature val characteristic exists + if(proxm_env->env[conidx]->prox[char_code].characts[0].val_hdl == ATT_INVALID_HANDLE) + { + status = PRF_ERR_INEXISTENT_HDL; + } + + return (status); +} + +#endif //BLE_PROX_MONITOR + +/// @} PROXM diff --git a/services/ble_profiles/prox/proxm/src/proxm.h b/services/ble_profiles/prox/proxm/src/proxm.h new file mode 100644 index 0000000..0115ddd --- /dev/null +++ b/services/ble_profiles/prox/proxm/src/proxm.h @@ -0,0 +1,228 @@ +#ifndef PROXM_H_ +#define PROXM_H_ + +/** + **************************************************************************************** + * @addtogroup PROX Proximity Profile + * @ingroup PROFILE + * @brief Proximity Profile + * + * The PROX module is the responsible block for implementing the proximity profile + * functionalities in the BLE Host. + * + * The Proximity Profile defines the functionality required in a device that can + * alert the user when the user's personal device moves further away or closer together + * to another communicating device. + ***************************************************************************************** + */ + +/** + **************************************************************************************** + * @addtogroup PROXM Proximity Monitor + * @ingroup PROX + * @brief Proximity Profile Monitor + * + * The PROXM is responsible for providing proximity profile monitor functionalities to + * upper layer module or application. The device using this profile takes the role + * of a proximity monitor role. + * + * Proximity Monitor (PM): A PM (e.g. PC, phone, electronic door entry system, etc) + * is the term used by this profile to describe a device that monitors the distance + * between itself and the connected PR device. The profile on the PM device constantly + * monitors the path loss between itself and the communicating Proximity Reporter + * device. The profile provides indications to an application which can cause an alert + * to the user. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_PROX_MONITOR) + +#include "proxm_task.h" +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of Proximity Monitor task instances +#define PROXM_IDX_MAX (BLE_CONNECTION_MAX) + + +/* + * ENUMERATIONS + **************************************************************************************** + */ +/// Possible states of the PROXM task +enum proxm_state +{ + /// FREE state + PROXM_FREE, + /// IDLE state + PROXM_IDLE, + /// Busy state + PROXM_BUSY, + ///Discovering + PROXM_DISCOVERING, + + /// Number of defined states. + PROXM_STATE_MAX +}; + + +/// Characteristics Link loss +enum +{ + PROXM_LK_LOSS_CHAR, + + PROXM_LK_LOSS_CHAR_MAX, +}; + +/// Characteristics IAS +enum +{ + PROXM_IAS_CHAR, + + PROXM_IAS_CHAR_MAX, +}; + +/// Characteristics Tx power +enum +{ + PROXM_TX_POWER_CHAR, + + PROXM_TX_POWER_CHAR_MAX, +}; + +/// Max characteristic number on services +enum +{ + PROXM_SVCS_CHAR_NB = 1 +}; + +///Link Loss or Immediate Alert code for setting alert through one message +enum +{ + ///Code for LLS Alert Level Char. + PROXM_SET_LK_LOSS_ALERT = 0x00, + ///Code for IAS Alert Level Char. + PROXM_SET_IMMDT_ALERT, +}; + +/// Read Characteristic Code +enum +{ + /// Read Link Loss Service Alert Level Characteristic Value + PROXM_RD_LL_ALERT_LVL = 0x00, + /// Read TX Power Service TX Power Level Characteristic Value + PROXM_RD_TX_POWER_LVL, +}; + +///Alert Level Values +enum +{ + PROXM_ALERT_NONE = 0x00, + PROXM_ALERT_MILD, + PROXM_ALERT_HIGH, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + + +/// Proximity Monitor environment variable per connection +struct proxm_cnx_env +{ + /// Last service for which something was discovered + uint8_t last_svc_req; + /// counter used to check service uniqueness + uint8_t nb_svc; + /// used to store if measurement context + uint8_t meas_ctx_en; + + struct svc_content prox[PROXM_SVC_NB]; +}; + +/// Proximity monitor environment variable +struct proxm_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct proxm_cnx_env* env[PROXM_IDX_MAX]; + /// State of different task instances + ke_state_t state[PROXM_IDX_MAX]; +}; + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve Proximity service profile interface + * + * @return Proximity service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* proxm_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send enable confirmation to application. + * @param status Status of the enable: either OK or error encountered while discovery. + **************************************************************************************** + */ +void proxm_enable_rsp_send(struct proxm_env_tag *proxm_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Check if collector request is possible or not + * + * @param[in] proxm_env Client environment. + * @param[in] conidx Connection Index. + * @param[in] char_code Characteristic number. + * + * @return GAP_ERR_NO_ERROR if request can be performed, error code else. + **************************************************************************************** + */ +uint8_t proxm_validate_request(struct proxm_env_tag *proxm_env, uint8_t conidx, uint8_t char_code); + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void proxm_task_init(struct ke_task_desc *task_desc); + +#endif //BLE_PROX_MONITOR + +/// @} PROXM + +#endif // PROXM_H_ diff --git a/services/ble_profiles/prox/proxm/src/proxm_task.c b/services/ble_profiles/prox/proxm/src/proxm_task.c new file mode 100644 index 0000000..04ed96b --- /dev/null +++ b/services/ble_profiles/prox/proxm/src/proxm_task.c @@ -0,0 +1,510 @@ +/** + **************************************************************************************** + * @addtogroup PROXMTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_PROX_MONITOR) +#include "co_utils.h" + +#include "gap.h" +#include "gapc.h" +#include "proxm_task.h" +#include "proxm.h" +#include "gattc_task.h" +#include "prf_types.h" +#include "prf_utils.h" + +#include "ke_mem.h" + +///// State machine used to retrieve services characteristics information + +const struct prf_char_def proxm_svc_char[PROXM_SVC_NB][PROXM_SVCS_CHAR_NB] = { + [PROXM_LK_LOSS_SVC] = {{ ATT_CHAR_ALERT_LEVEL, + ATT_MANDATORY, + ATT_CHAR_PROP_RD | ATT_CHAR_PROP_WR}}, + + [PROXM_IAS_SVC] = {{ ATT_CHAR_ALERT_LEVEL, + ATT_MANDATORY, + ATT_CHAR_PROP_WR_NO_RESP}}, + + [PROXM_TX_POWER_SVC] = {{ATT_CHAR_TX_POWER_LEVEL, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}} +}; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Enable the Proximity Monitor role, used after connection. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int proxm_enable_req_handler(ke_msg_id_t const msgid, + struct proxm_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + // Proximity Monitor Environment + struct proxm_env_tag *proxm_env = PRF_ENV_GET(PROXM, proxm); + + ASSERT_INFO(proxm_env != NULL, dest_id, src_id); + if((state == PROXM_IDLE) && (proxm_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + proxm_env->env[conidx] = (struct proxm_cnx_env*) ke_malloc(sizeof(struct proxm_cnx_env),KE_MEM_ATT_DB); + memset(proxm_env->env[conidx], 0, sizeof(struct proxm_cnx_env)); + + if(param->con_type == PRF_CON_DISCOVERY) + { + proxm_env->env[conidx]->last_svc_req = PROXM_LK_LOSS_SVC; + prf_disc_svc_send(&(proxm_env->prf_env), conidx, ATT_SVC_LINK_LOSS); + + // Go to DISCOVERING state + ke_state_set(dest_id, PROXM_DISCOVERING); + } + else + { + proxm_env->env[conidx]->prox[PROXM_LK_LOSS_SVC] = param->lls; + proxm_env->env[conidx]->prox[PROXM_IAS_SVC] = param->ias; + proxm_env->env[conidx]->prox[PROXM_TX_POWER_SVC] = param->txps; + + //send APP confirmation that can start normal connection to TH + proxm_enable_rsp_send(proxm_env, conidx, GAP_ERR_NO_ERROR); + } + + } + else if(state != PROXM_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + proxm_enable_rsp_send(proxm_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref PROXM_RD_REQ message. + * Request to read the LLS alert level. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int proxm_rd_req_handler(ke_msg_id_t const msgid, + struct proxm_rd_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = GAP_ERR_NO_ERROR; + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t current_svc = PROXM_SVC_NB; + + if(state == PROXM_IDLE) + { + struct proxm_env_tag *proxm_env = PRF_ENV_GET(PROXM, proxm); + + ASSERT_INFO(proxm_env != NULL, dest_id, src_id); + + // environment variable not ready + if(proxm_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + else + { + // Get the request type and handle value for this type of write + switch(param->svc_code) + { + case PROXM_RD_LL_ALERT_LVL: + current_svc = PROXM_LK_LOSS_SVC; + status = proxm_validate_request(proxm_env, conidx, PROXM_LK_LOSS_SVC); + break; + case PROXM_RD_TX_POWER_LVL: + current_svc = PROXM_TX_POWER_SVC; + status = proxm_validate_request(proxm_env, conidx, PROXM_TX_POWER_SVC); + break; + default: + current_svc = PROXM_SVC_NB; + status = PRF_ERR_INVALID_PARAM; + break; + } + + if(status == GAP_ERR_NO_ERROR) + { + prf_read_char_send(&(proxm_env->prf_env), conidx, + proxm_env->env[conidx]->prox[current_svc].characts[0].char_hdl, + proxm_env->env[conidx]->prox[current_svc].characts[0].char_ehdl_off, + proxm_env->env[conidx]->prox[current_svc].characts[0].val_hdl); + // wait for end of read request + proxm_env->env[conidx]->last_svc_req = param->svc_code; + + ke_state_set(dest_id, PROXM_BUSY); + } + } + + // request cannot be performed + if(status != GAP_ERR_NO_ERROR) + { + struct proxm_rd_rsp * rsp = KE_MSG_ALLOC(PROXM_RD_RSP, + src_id, dest_id, proxm_rd_rsp); + rsp->svc_code = param->svc_code; + // set error status + rsp->status = status; + ke_msg_send(rsp); + } + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref PROXM_WR_ALERT_LVL_REQ message. + * Request to write either the LLS or IAS alert levels. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int proxm_wr_alert_lvl_req_handler(ke_msg_id_t const msgid, + struct proxm_wr_alert_lvl_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = GAP_ERR_NO_ERROR; + uint8_t operation = 0x00; + uint16_t val_hdl = 0x0000; + uint8_t conidx = KE_IDX_GET(dest_id); + struct proxm_env_tag *proxm_env = PRF_ENV_GET(PROXM, proxm); + + if(state == PROXM_IDLE) + { + ASSERT_INFO(proxm_env != NULL, dest_id, src_id); + + // environment variable not ready + if(proxm_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + else + { + // Alert level only has 3 values, other not useful + if(param->lvl <= PROXM_ALERT_HIGH) + { + // Get the request type and handle value for this type of write + switch(param->svc_code) + { + case PROXM_SET_LK_LOSS_ALERT: + operation = GATTC_WRITE; + val_hdl = proxm_env->env[conidx]->prox[PROXM_LK_LOSS_SVC].characts[0].val_hdl; + break; + case PROXM_SET_IMMDT_ALERT: + operation = GATTC_WRITE_NO_RESPONSE; + val_hdl = proxm_env->env[conidx]->prox[PROXM_IAS_SVC].characts[0].val_hdl; + break; + default: + status = PRF_ERR_INVALID_PARAM; + break; + } + + if(status == GAP_ERR_NO_ERROR) + { + // Send GATT Write Request + prf_gatt_write(&(proxm_env->prf_env), conidx, val_hdl, (uint8_t *)¶m->lvl, + sizeof(uint8_t), operation); + // wait for end of write request + ke_state_set(dest_id, PROXM_BUSY); + } + } + else + { + //wrong level - not one of the possible 3 + status = PRF_ERR_INVALID_PARAM; + } + } + // An error occurs, send the response with error status + if(status != GAP_ERR_NO_ERROR) + { + struct proxm_wr_alert_lvl_rsp * rsp = KE_MSG_ALLOC(PROXM_WR_ALERT_LVL_RSP, + src_id, dest_id, proxm_wr_alert_lvl_rsp); + // set error status + rsp->status = status; + + ke_msg_send(rsp); + } + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == PROXM_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + uint16_t current_svc = PROXM_SVC_NB; + const struct prf_char_def* current_char_def; + + struct proxm_env_tag *proxm_env = PRF_ENV_GET(PROXM, proxm); + + ASSERT_INFO(proxm_env != NULL, dest_id, src_id); + ASSERT_INFO(proxm_env->env[conidx] != NULL, dest_id, src_id); + + // check if a valid service is found + if (attm_uuid16_comp((unsigned char *)ind->uuid, ind->uuid_len, ATT_SVC_LINK_LOSS)) + { + current_svc = PROXM_LK_LOSS_SVC; + current_char_def = &proxm_svc_char[PROXM_LK_LOSS_SVC][PROXM_LK_LOSS_CHAR]; + } + else if(attm_uuid16_comp((unsigned char *)ind->uuid, ind->uuid_len, ATT_SVC_IMMEDIATE_ALERT)) + { + current_svc = PROXM_IAS_SVC; + current_char_def = &proxm_svc_char[PROXM_IAS_SVC][PROXM_IAS_CHAR]; + } + else if(attm_uuid16_comp((unsigned char *)ind->uuid, ind->uuid_len, ATT_SVC_TX_POWER)) + { + current_svc = PROXM_TX_POWER_SVC; + current_char_def = &proxm_svc_char[PROXM_TX_POWER_SVC][PROXM_TX_POWER_CHAR]; + } + + // if a valid service found, put it into environment variable + if(current_svc != PROXM_SVC_NB) + { + prf_extract_svc_info(ind, PROXM_CHAR_NB_MAX, current_char_def, + proxm_env->env[conidx]->prox[current_svc].characts, 0, NULL, NULL); + + proxm_env->env[conidx]->prox[current_svc].svc.shdl = ind->start_hdl; + proxm_env->env[conidx]->prox[current_svc].svc.ehdl = ind->end_hdl; + + proxm_env->env[conidx]->nb_svc++; + } + } + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + // Get the address of the environment + struct proxm_env_tag *proxm_env = PRF_ENV_GET(PROXM, proxm); + uint8_t conidx = KE_IDX_GET(dest_id); + uint16_t current_att_svc = ATT_INVALID_UUID; + uint8_t status = GAP_ERR_NO_ERROR; + + if(state == PROXM_DISCOVERING) + { + status = prf_check_svc_char_validity(PROXM_SVCS_CHAR_NB, + proxm_env->env[conidx]->prox[proxm_env->env[conidx]->last_svc_req].characts, + proxm_svc_char[proxm_env->env[conidx]->last_svc_req]); + + // Too many services found only one such service should exist + if(proxm_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // if an error append, send confirmation with error status and stop discovering + if(status != GAP_ERR_NO_ERROR) + { + proxm_enable_rsp_send(proxm_env, conidx, status); + } + // if a valid service found, discover and then send confirmation message + else + { + proxm_env->env[conidx]->nb_svc =0; + proxm_env->env[conidx]->last_svc_req += 1; + + if((proxm_env->env[conidx]->last_svc_req) < PROXM_SVC_NB) + { + switch(proxm_env->env[conidx]->last_svc_req) + { + case PROXM_LK_LOSS_SVC: + current_att_svc = ATT_SVC_LINK_LOSS; + break; + case PROXM_IAS_SVC: + current_att_svc = ATT_SVC_IMMEDIATE_ALERT; + break; + case PROXM_TX_POWER_SVC: + current_att_svc = ATT_SVC_TX_POWER; + break; + default : break; + } + + prf_disc_svc_send(&(proxm_env->prf_env), conidx, current_att_svc); + } + else + { + proxm_enable_rsp_send(proxm_env, conidx, GAP_ERR_NO_ERROR); + } + } + } + else if (state == PROXM_BUSY) + { + switch(param->operation) + { + case GATTC_WRITE: + case GATTC_WRITE_NO_RESPONSE: + { + struct proxm_wr_alert_lvl_rsp * rsp = KE_MSG_ALLOC(PROXM_WR_ALERT_LVL_RSP, + prf_dst_task_get(&(proxm_env->prf_env), conidx), + prf_src_task_get(&(proxm_env->prf_env), conidx), + proxm_wr_alert_lvl_rsp); + // set error status + rsp->status = param->status; + ke_msg_send(rsp); + + ke_state_set(dest_id, PROXM_IDLE); + } + break; + + case GATTC_READ: + { + if(param->status != GAP_ERR_NO_ERROR) + { + struct proxm_rd_rsp * rsp = KE_MSG_ALLOC(PROXM_RD_RSP, + prf_dst_task_get(&(proxm_env->prf_env), conidx), + prf_src_task_get(&(proxm_env->prf_env), conidx), + proxm_rd_rsp); + // set error status + rsp->status = param->status; + rsp->svc_code = proxm_env->env[conidx]->last_svc_req; + ke_msg_send(rsp); + } + ke_state_set(dest_id, PROXM_IDLE); + } + break; + default: break; + } + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == PROXM_BUSY) + { + struct proxm_env_tag *proxm_env = PRF_ENV_GET(PROXM, proxm); + uint8_t conidx = KE_IDX_GET(dest_id); + + ASSERT_INFO(proxm_env != NULL, dest_id, src_id); + ASSERT_INFO(proxm_env->env[conidx] != NULL, dest_id, src_id); + + struct proxm_rd_rsp * rsp = KE_MSG_ALLOC(PROXM_RD_RSP, + prf_dst_task_get(&(proxm_env->prf_env), conidx), + dest_id, + proxm_rd_rsp); + rsp->status = GAP_ERR_NO_ERROR; + rsp->svc_code = proxm_env->env[conidx]->last_svc_req; + rsp->value = param->value[0]; + ke_msg_send(rsp); + } + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(proxm) +{ + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {PROXM_ENABLE_REQ, (ke_msg_func_t)proxm_enable_req_handler}, + {PROXM_WR_ALERT_LVL_REQ, (ke_msg_func_t)proxm_wr_alert_lvl_req_handler}, + {PROXM_RD_REQ, (ke_msg_func_t)proxm_rd_req_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void proxm_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct proxm_env_tag *proxm_env = PRF_ENV_GET(PROXM, proxm); + + task_desc->msg_handler_tab = proxm_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(proxm_msg_handler_tab); + task_desc->state = proxm_env->state; + task_desc->idx_max = PROXM_IDX_MAX; +} + +#endif //BLE_PROX_MONITOR + +/// @} PROXMTASK diff --git a/services/ble_profiles/prox/proxr/api/proxr_task.h b/services/ble_profiles/prox/proxr/api/proxr_task.h new file mode 100644 index 0000000..1332074 --- /dev/null +++ b/services/ble_profiles/prox/proxr/api/proxr_task.h @@ -0,0 +1,86 @@ +#ifndef PROXR_TASK_H_ +#define PROXR_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup PROXRTASK Proximity Reporter Task + * @ingroup PROXR + * @brief Proximity Reporter Task + * + * The PROXRTASK is responsible for handling the APi messages from the Application or internal + * tasks. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_task.h" // Task definitions + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Proximity reporter feature bit field +enum proxr_feature +{ + /// immediate alert and TX Power services are not present + PROXR_IAS_TXPS_NOT_SUP = 0, + /// immediate alert and TX Power services are present + PROXR_IAS_TXPS_SUP, +}; + +/// Messages for Proximity Reporter +enum proxr_msg_id +{ + /// LLS/IAS Alert Level Indication + PROXR_ALERT_IND = TASK_FIRST_MSG(TASK_ID_PROXR), +}; + +///Characteristics Code for Write Indications +enum +{ + PROXR_ERR_CHAR, + PROXR_LLS_CHAR, + PROXR_IAS_CHAR, +}; + + +/* + * API MESSAGES STRUCTURES + **************************************************************************************** + */ +///Parameters of the Proximity service database +struct proxr_db_cfg +{ + /// Proximity Feature (@see enum proxm_feature) + uint16_t features; +}; + + +/// Parameters of the @ref PROXR_ALERT_IND message +struct proxr_alert_ind +{ + /// Connection index + uint8_t conidx; + /// Alert level + uint8_t alert_lvl; + /// Char Code - Indicate if LLS or IAS + uint8_t char_code; +}; + + +/// @} PROXRTASK + +#endif // PROXR_TASK_H_ diff --git a/services/ble_profiles/prox/proxr/src/proxr.c b/services/ble_profiles/prox/proxr/src/proxr.c new file mode 100644 index 0000000..9f39793 --- /dev/null +++ b/services/ble_profiles/prox/proxr/src/proxr.c @@ -0,0 +1,220 @@ +/** + **************************************************************************************** + * @addtogroup PROXR + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_PROX_REPORTER) + +#include "proxr.h" +#include "proxr_task.h" +#include "attm.h" +#include "gap.h" + +#include "ke_mem.h" + +/* + * PROXIMITY PROFILE ATTRIBUTES DEFINITION + **************************************************************************************** + */ + +/// Full LLS Database Description - Used to add attributes into the database +const struct attm_desc proxr_lls_att_db[LLS_IDX_NB] = +{ + // Link Loss Service Declaration + [LLS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + // Alert Level Characteristic Declaration + [LLS_IDX_ALERT_LVL_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Alert Level Characteristic Value + [LLS_IDX_ALERT_LVL_VAL] = {ATT_CHAR_ALERT_LEVEL, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, +}; + +/// Full IAS Database Description - Used to add attributes into the database +const struct attm_desc proxr_ias_att_db[IAS_IDX_NB] = +{ + // Immediate Alert Service Declaration + [IAS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE),0, 0}, + // Alert Level Characteristic Declaration + [IAS_IDX_ALERT_LVL_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Alert Level Characteristic Value + [IAS_IDX_ALERT_LVL_VAL] = {ATT_CHAR_ALERT_LEVEL, PERM(WRITE_COMMAND, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, +}; + +/// Full TXPS Database Description - Used to add attributes into the database +const struct attm_desc proxr_txps_att_db[TXPS_IDX_NB] = +{ + // TX Power Service Declaration + [TXPS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + // TX Power Level Characteristic Declaration + [TXPS_IDX_TX_POWER_LVL_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // TX Power Level Characteristic Value + [TXPS_IDX_TX_POWER_LVL_VAL] = {ATT_CHAR_TX_POWER_LEVEL, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, +}; +/* + * LOCAL FUNCTION DEFINITIONS + **************************************************************************************** + */ + +static uint8_t proxr_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, + uint8_t sec_lvl, struct proxr_db_cfg* params) +{ + // Service content flag + uint32_t cfg_flag = PROXR_LLS_MANDATORY_MASK; + // DB Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + //-------------------- allocate memory required for the profile --------------------- + struct proxr_env_tag* proxr_env = + (struct proxr_env_tag* ) ke_malloc(sizeof(struct proxr_env_tag), KE_MEM_ATT_DB); + + // allocate PROXR required environment variable + env->env = (prf_env_t*) proxr_env; + + status = attm_svc_create_db(start_hdl, ATT_SVC_LINK_LOSS, (uint8_t *)&cfg_flag, + LLS_IDX_NB, NULL, env->task, &proxr_lls_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) + | PERM(SVC_MI, DISABLE) ); + + proxr_env->lls_start_hdl = *start_hdl; + *start_hdl += LLS_IDX_NB; + + if( (status == ATT_ERR_NO_ERROR) && (params->features == PROXR_IAS_TXPS_SUP) ) + { + cfg_flag = PROXR_IAS_MANDATORY_MASK; + status = attm_svc_create_db(start_hdl, ATT_SVC_IMMEDIATE_ALERT, (uint8_t *)&cfg_flag, + IAS_IDX_NB, NULL, env->task, &proxr_ias_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) + | PERM(SVC_MI, DISABLE) ); + + proxr_env->ias_start_hdl = *start_hdl; + *start_hdl += IAS_IDX_NB; + + if( status == ATT_ERR_NO_ERROR ) + { + cfg_flag = PROXR_TXP_MANDATORY_MASK; + status = attm_svc_create_db(start_hdl, ATT_SVC_TX_POWER, (uint8_t *)&cfg_flag, + TXPS_IDX_NB, NULL, env->task, &proxr_txps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) + | PERM(SVC_MI, DISABLE) ); + + proxr_env->txp_start_hdl = *start_hdl; + + if (status == ATT_ERR_NO_ERROR) + { + // set start handle to first allocated service value + *start_hdl = proxr_env->ias_start_hdl; + + proxr_env->features = params->features; + proxr_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + proxr_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + // initialize environment variable + env->id = TASK_ID_PROXR; + proxr_task_init(&(env->desc)); + + // service is ready, go into an Idle state + ke_state_set(env->task, PROXR_IDLE); + } + } + } + return (status); +} + +static void proxr_destroy(struct prf_task_env* env) +{ + struct proxr_env_tag* proxr_env = (struct proxr_env_tag*) env->env; + + // free profile environment variables + env->env = NULL; + ke_free(proxr_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void proxr_create(struct prf_task_env* env, uint8_t conidx) +{ + struct proxr_env_tag* proxr_env = (struct proxr_env_tag*) env->env; + + proxr_env->lls_alert_lvl[conidx] = PROXR_ALERT_NONE; +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void proxr_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct proxr_env_tag* proxr_env = (struct proxr_env_tag*) env->env; + + if((proxr_env->features == PROXR_IAS_TXPS_SUP) && (reason != LL_ERR_REMOTE_USER_TERM_CON)) + { + if(proxr_env->lls_alert_lvl[conidx] > PROXR_ALERT_NONE) + { + + // Allocate the alert value change indication + struct proxr_alert_ind *ind = KE_MSG_ALLOC(PROXR_ALERT_IND, + prf_dst_task_get(&(proxr_env->prf_env), conidx), + prf_src_task_get(&(proxr_env->prf_env), conidx), proxr_alert_ind); + + // Fill in the parameter structure + ind->alert_lvl = proxr_env->lls_alert_lvl[conidx]; + ind->char_code = PROXR_LLS_CHAR; + ind->conidx = conidx; + + // Send the message + ke_msg_send(ind); + } + } + +} + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/// PROXR Task interface required by profile manager +const struct prf_task_cbs proxr_itf = +{ + (prf_init_fnct) proxr_init, + proxr_destroy, + proxr_create, + proxr_cleanup, +}; + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* proxr_prf_itf_get(void) +{ + return &proxr_itf; +} + + +#endif //BLE_PROX_REPORTER + +/// @} PROXR diff --git a/services/ble_profiles/prox/proxr/src/proxr.h b/services/ble_profiles/prox/proxr/src/proxr.h new file mode 100644 index 0000000..b4f3e4a --- /dev/null +++ b/services/ble_profiles/prox/proxr/src/proxr.h @@ -0,0 +1,210 @@ +#ifndef PROXR_H_ +#define PROXR_H_ + +/** + **************************************************************************************** + * @addtogroup PROXR Proximity Reporter + * @ingroup PROX + * @brief Proximity Profile Reporter. + * + * The PROXR is responsible for providing proximity reporter functionalities to + * upper layer module or application. The device using this profile takes the role + * of a proximity reporter role. + * + * Proximity Reporter (PR): A PR (e.g. a watch, key fob, etc) is the term used by + * this profile to describe a personal device that a user carries with them and that + * has low power requirement (i.e. it is operating with a button cell), allowing another + * device to monitor their connection. The device may have a simple user alert + * functionality, for example a blinking LED or audible output. + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_PROX_REPORTER) + +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" + +/* + * DEFINES + **************************************************************************************** + */ + +///Maximum number of Proximity task instances +#define PROXR_IDX_MAX (1) + +#define PROXR_IAS_MANDATORY_MASK (0x07) +#define PROXR_LLS_MANDATORY_MASK (0x07) +#define PROXR_TXP_MANDATORY_MASK (0x07) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the PROXR task +enum +{ + /// Idle state + PROXR_IDLE, + /// Proximity reporter in a busy state + PROXR_BUSY, + + /// Number of defined states. + PROXR_STATE_MAX +}; + +/// LLS Handles offsets +enum +{ + LLS_IDX_SVC, + + LLS_IDX_ALERT_LVL_CHAR, + LLS_IDX_ALERT_LVL_VAL, + + LLS_IDX_NB, +}; + +/// IAS Handles offsets +enum +{ + IAS_IDX_SVC, + + IAS_IDX_ALERT_LVL_CHAR, + IAS_IDX_ALERT_LVL_VAL, + + IAS_IDX_NB, +}; + +/// TXPS Handles offsets +enum +{ + TXPS_IDX_SVC, + + TXPS_IDX_TX_POWER_LVL_CHAR, + TXPS_IDX_TX_POWER_LVL_VAL, + + TXPS_IDX_NB, +}; + + +///Alert Level Values +enum +{ + PROXR_ALERT_NONE, + PROXR_ALERT_MILD, + PROXR_ALERT_HIGH, +}; + + +/// Proximity service processing flags +enum +{ + /// Use To know if bond data are present + PROXR_BOND_DATA_PRESENT, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Proximity reporter environment variable +struct proxr_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// IAS Start Handle + uint16_t ias_start_hdl; + /// LLS Start Handle + uint16_t lls_start_hdl; + /// TXP Start Handle + uint16_t txp_start_hdl; + /// Proximity Feature + uint16_t features; + /// Connection index backup, needed due to GAP request for TX power read + uint8_t conidx_saved; + /// State of different task instances + ke_state_t state[PROXR_IDX_MAX]; + /// LLS alert level + uint8_t lls_alert_lvl[PROXR_IDX_MAX]; +}; + +/* + * PROXIMITY PROFILE ATTRIBUTES DECLARATION + **************************************************************************************** + */ + +/* + * PROXIMITY PROFILE ATTRIBUTES VALUES DECLARATION + **************************************************************************************** + */ + +/// Link Loss Service +extern const att_svc_desc_t proxr_lls_svc; +/// Link Loss Service - Alert Level Characteristic +extern const struct att_char_desc proxr_lls_alert_lvl_char; + +/// Immediate Alert Service +extern const att_svc_desc_t proxr_ias_svc; +/// Immediate Alert Service - Alert Level Characteristic +extern const struct att_char_desc proxr_ias_alert_lvl_char; + +/// TX Power Service +extern const att_svc_desc_t proxr_txps_svc; +/// TX Power Service -TX Power Level Characteristic +extern const struct att_char_desc proxr_txps_tx_power_lvl_char; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve Proximity service profile interface + * + * @return Proximity service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* proxr_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Disable role. + **************************************************************************************** + */ +void proxr_disable(uint16_t conhdl); + +/* + * GLOBAL VARIABLES DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void proxr_task_init(struct ke_task_desc *task_desc); + + +#endif //BLE_PROX_REPORTER + +/// @} PROXR + +#endif // PROXR_H_ diff --git a/services/ble_profiles/prox/proxr/src/proxr_task.c b/services/ble_profiles/prox/proxr/src/proxr_task.c new file mode 100644 index 0000000..7a3a63c --- /dev/null +++ b/services/ble_profiles/prox/proxr/src/proxr_task.c @@ -0,0 +1,282 @@ +/** + **************************************************************************************** + * @addtogroup PROXRTASK + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_PROX_REPORTER) +#include "co_utils.h" + +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "proxr_task.h" +#include "proxr.h" +#include "prf_utils.h" + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of write request message. + * The handler will analyse what has been set and decide alert level + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + int msg_status = KE_MSG_CONSUMED; + + if(ke_state_get(dest_id) == PROXR_IDLE) + { + uint8_t alert_lvl = 0x0000; + uint8_t conidx = KE_IDX_GET(src_id); + // Allocate write confirmation message. + struct gattc_write_cfm *cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, + src_id, dest_id, gattc_write_cfm); + + // Get the address of the environment + struct proxr_env_tag *proxr_env = PRF_ENV_GET(PROXR, proxr); + + // Fill in the parameter structure + cfm->handle = param->handle; + cfm->status = PRF_APP_ERROR; + + if(param->value[0] <= PROXR_ALERT_HIGH) + { + alert_lvl = param->value[0]; + // Store alert level on the environment + if(param->handle == (proxr_env->lls_start_hdl + LLS_IDX_ALERT_LVL_VAL)) + { + proxr_env->lls_alert_lvl[conidx] = alert_lvl; + cfm->status = GAP_ERR_NO_ERROR; + } + else if(param->handle == (proxr_env->ias_start_hdl + IAS_IDX_ALERT_LVL_VAL)) + { + // Allocate the alert value change indication + struct proxr_alert_ind *ind = KE_MSG_ALLOC(PROXR_ALERT_IND, + prf_dst_task_get(&(proxr_env->prf_env), conidx), + dest_id, proxr_alert_ind); + // Fill in the parameter structure + ind->alert_lvl = alert_lvl; + ind->char_code = PROXR_IAS_CHAR; + ind->conidx = conidx; + + // Send the message + ke_msg_send(ind); + + cfm->status = GAP_ERR_NO_ERROR; + } + else + { + cfm->status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } + } + + // Send the message + ke_msg_send(cfm); + } + else if(ke_state_get(dest_id) == PROXR_BUSY) + { + msg_status = KE_MSG_SAVED; + } + + return (msg_status); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + int msg_status = KE_MSG_CONSUMED; + + if(ke_state_get(dest_id) == PROXR_IDLE) + { + // Get the address of the environment + struct proxr_env_tag *proxr_env = PRF_ENV_GET(PROXR, proxr); + uint8_t conidx = KE_IDX_GET(src_id); + + uint8_t value = PROXR_ALERT_NONE; + uint8_t status = ATT_ERR_NO_ERROR; + + if(param->handle == (proxr_env->lls_start_hdl + LLS_IDX_ALERT_LVL_VAL)) + { + value = proxr_env->lls_alert_lvl[conidx]; + } + else if(param->handle == (proxr_env->txp_start_hdl + TXPS_IDX_TX_POWER_LVL_VAL)) + { + // send a request to read TX power level on GAPM + struct gapm_get_dev_info_cmd* cmd = KE_MSG_ALLOC(GAPM_GET_DEV_INFO_CMD, TASK_GAPM, dest_id, + gapm_get_dev_info_cmd); + cmd->operation = GAPM_GET_DEV_ADV_TX_POWER; + ke_msg_send(cmd); + + // save the connection index + proxr_env->conidx_saved = conidx; + + // need to wait for GAPM response, go into busy state + ke_state_set(dest_id, PROXR_BUSY); + + status = PRF_APP_ERROR; + } + else + { + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } + + // Don't send the confirmation if gap read request has been initiated. + if(status != PRF_APP_ERROR) + { + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, + gattc_read_cfm, sizeof(uint8_t)); + cfm->length = sizeof(uint8_t); + cfm->value[0] = value; + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + } + } + else if(ke_state_get(dest_id) == PROXR_BUSY) + { + msg_status = KE_MSG_SAVED; + } + + return msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GAPM_DEV_ADV_TX_POWER_IND message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gapm_dev_adv_tx_power_ind_handler(ke_msg_id_t const msgid, + struct gapm_dev_adv_tx_power_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct proxr_env_tag *proxr_env = PRF_ENV_GET(PROXR, proxr); + + if( ke_state_get(dest_id) == PROXR_BUSY ) + { + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, KE_BUILD_ID(TASK_GATTC, proxr_env->conidx_saved), dest_id, + gattc_read_cfm, sizeof(uint8_t)); + cfm->length = sizeof(uint8_t); + cfm->value[0] = param->power_lvl; + cfm->handle = proxr_env->txp_start_hdl + TXPS_IDX_TX_POWER_LVL_VAL; + cfm->status = GAP_ERR_NO_ERROR; + + // Send value to peer device. + ke_msg_send(cfm); + + ke_state_set(dest_id, PROXR_IDLE); + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GAPM_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gapm_cmp_evt_handler(ke_msg_id_t const msgid, + struct gapm_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct proxr_env_tag *proxr_env = PRF_ENV_GET(PROXR, proxr); + + if( (ke_state_get(dest_id) == PROXR_BUSY) && (param->status != GAP_ERR_NO_ERROR)) + { + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC(GATTC_READ_CFM, KE_BUILD_ID(TASK_GATTC, + proxr_env->conidx_saved), dest_id, gattc_read_cfm); + cfm->length = sizeof(uint8_t); + cfm->handle = proxr_env->txp_start_hdl + TXPS_IDX_TX_POWER_LVL_VAL; + cfm->status = PRF_APP_ERROR; + + // Send value to peer device. + ke_msg_send(cfm); + + ke_state_set(dest_id, PROXR_IDLE); + } + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(proxr) +{ + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {GAPM_DEV_ADV_TX_POWER_IND, (ke_msg_func_t) gapm_dev_adv_tx_power_ind_handler}, + {GAPM_CMP_EVT, (ke_msg_func_t) gapm_cmp_evt_handler}, +}; + +void proxr_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct proxr_env_tag *proxr_env = PRF_ENV_GET(PROXR, proxr); + + task_desc->msg_handler_tab = proxr_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(proxr_msg_handler_tab); + task_desc->state = proxr_env->state; + task_desc->idx_max = PROXR_IDX_MAX; +} + +#endif //BLE_PROX_REPORTER + +/// @} PROXRTASK diff --git a/services/ble_profiles/rscp/rscp_common.h b/services/ble_profiles/rscp/rscp_common.h new file mode 100644 index 0000000..9953ea3 --- /dev/null +++ b/services/ble_profiles/rscp/rscp_common.h @@ -0,0 +1,204 @@ +#ifndef _RSCP_COMMON_H_ +#define _RSCP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup RSCP Running Speed and Cadence Profile + * @ingroup PROFILE + * @brief Running Speed and Cadence Profile + * + * The Running Speed and Cadence profile enables a Collector device to connect and + * interact with a Running Speed and Cadence Sensor for use in sports and fitness + * applications. + * + * This file contains all definitions that are common for the server and the client parts + * of the profile. + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "prf_types.h" +#include + +/* + * DEFINES + **************************************************************************************** + */ +/// Procedure Already in Progress Error Code +#define RSCP_ERROR_PROC_IN_PROGRESS (0x80) +/// Client Characteristic Configuration descriptor improperly configured Error Code +#define RSCP_ERROR_CCC_INVALID_PARAM (0x81) + +/// RSC Measurement Value Min Length +#define RSCP_RSC_MEAS_MIN_LEN (4) +/// RSC Measurement Value Max Length +#define RSCP_RSC_MEAS_MAX_LEN (10) +/// SC Control Point Request Value Min Length +#define RSCP_SC_CNTL_PT_REQ_MIN_LEN (1) +/// SC Control Point Request Value Max Length +#define RSCP_SC_CNTL_PT_REQ_MAX_LEN (5) +/// SC Control Point Response Value Min Length +#define RSCP_SC_CNTL_PT_RSP_MIN_LEN (3) +/// SC Control Point Response Value Max Length +#define RSCP_SC_CNTL_PT_RSP_MAX_LEN (RSCP_SC_CNTL_PT_RSP_MIN_LEN + RSCP_LOC_MAX) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Running Speed and Cadence Service Characteristics +enum rscp_rscs_char +{ + /// RSC Measurement + RSCP_RSCS_RSC_MEAS_CHAR, + /// RSC Feature + RSCP_RSCS_RSC_FEAT_CHAR, + /// Sensor Location + RSCP_RSCS_SENSOR_LOC_CHAR, + /// SC Control Point + RSCP_RSCS_SC_CTNL_PT_CHAR, + + /// Maximum Characteristic + RSCP_RSCS_CHAR_MAX, +}; + +/// RSC Measurement Flags +enum rscp_meas_flags +{ + /// Instantaneous Stride Length Present + RSCP_MEAS_INST_STRIDE_LEN_PRESENT = 0x01, + /// Total Distance Present + RSCP_MEAS_TOTAL_DST_MEAS_PRESENT = 0x02, + /// Walking or Running + RSCP_MEAS_WALK_RUN_STATUS = 0x04, + + /// All present + RSCP_MEAS_ALL_PRESENT = 0x07, +}; + +/// RSC Feature Flags +enum rscp_feat_flags +{ + /// Instantaneous Stride Length Measurement Supported + RSCP_FEAT_INST_STRIDE_LEN_SUPP = 0x0001, + /// Total Distance Measurement Supported + RSCP_FEAT_TOTAL_DST_MEAS_SUPP = 0x0002, + /// Walking or Running Status Supported + RSCP_FEAT_WALK_RUN_STATUS_SUPP = 0x0004, + /// Calibration Procedure Supported + RSCP_FEAT_CALIB_PROC_SUPP = 0x0008, + /// Multiple Sensor Locations Supported + RSCP_FEAT_MULT_SENSOR_LOC_SUPP = 0x0010, + + /// All supported + RSCP_FEAT_ALL_SUPP = 0x001F, +}; + +/// Sensor Locations Keys +enum rscp_sensor_loc +{ + /// Other (0) + RSCP_LOC_OTHER = 0, + /// Top of shoe (1) + RSCP_LOC_TOP_SHOE, + /// In shoe (2) + RSCP_LOC_IN_SHOE, + /// Hip (3) + RSCP_LOC_HIP, + /// Chest (14) + RSCP_LOC_CHEST = 14, + + /// Maximum Sensor Location + RSCP_LOC_MAX, +}; + +/// Control Point Operation Code Keys +enum rscp_sc_ctnl_pt_op_code +{ + /// Reserved value + RSCP_CTNL_PT_OP_RESERVED = 0, + + /// Set Cumulative Value + RSCP_CTNL_PT_OP_SET_CUMUL_VAL, + /// Start Sensor Calibration + RSCP_CTNL_PT_OP_START_CALIB, + /// Update Sensor Location + RSCP_CTNL_PT_OP_UPD_LOC, + /// Request Supported Sensor Locations + RSCP_CTNL_PT_OP_REQ_SUPP_LOC, + + /// Response Code + RSCP_CTNL_PT_RSP_CODE = 16, +}; + +/// Control Point Response Value +enum rscp_sc_ctnl_pt_resp_val +{ + /// Reserved value + RSCP_CTNL_PT_RESP_RESERVED = 0, + + /// Success + RSCP_CTNL_PT_RESP_SUCCESS, + /// Operation Code Not Supported + RSCP_CTNL_PT_RESP_NOT_SUPP, + /// Invalid Parameter + RSCP_CTNL_PT_RESP_INV_PARAM, + /// Operation Failed + RSCP_CTNL_PT_RESP_FAILED, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// RSC Measurement +struct rscp_rsc_meas +{ + /// Flags + uint8_t flags; + /// Instantaneous Cadence + uint8_t inst_cad; + /// Instantaneous Speed + uint16_t inst_speed; + /// Instantaneous Stride Length + uint16_t inst_stride_len; + /// Total Distance + uint32_t total_dist; +}; + +/// SC Control Point Request +struct rscp_sc_ctnl_pt_req +{ + /// Operation Code + uint8_t op_code; + /// Value + union rscp_sc_ctnl_pt_req_val + { + /// Sensor Location + uint8_t sensor_loc; + /// Cumulative value + uint32_t cumul_val; + } value; +}; + +/// SC Control Point Response +struct rscp_sc_ctnl_pt_rsp +{ + /// Requested Operation Code + uint8_t req_op_code; + /// Response Value + uint8_t resp_value; + /// List of supported locations + uint16_t supp_loc; +}; + + +/// @} rscp_common + +#endif //(_RSCP_COMMON_H_) diff --git a/services/ble_profiles/rscp/rscpc/api/rscpc_task.h b/services/ble_profiles/rscp/rscpc/api/rscpc_task.h new file mode 100644 index 0000000..3a3d15a --- /dev/null +++ b/services/ble_profiles/rscp/rscpc/api/rscpc_task.h @@ -0,0 +1,198 @@ +#ifndef _RSCPC_TASK_H_ +#define _RSCPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup RSCPCTASK Running Speed and Cadence Profile Collector Task + * @ingroup RSCPC + * @brief Running Speed and Cadence Profile Collector Task + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rscp_common.h" +#include "rwip_task.h" // Task definitions + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Message IDs +enum rscpc_msg_ids +{ + /// Enable the Running Speed and Cadence Profile Collector task - at connection + RSCPC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_RSCPC), + /// Enable the Running Speed and Cadence Profile Collector task - at connection + RSCPC_ENABLE_RSP, + + /// Read the value of an attribute in the peer device database + RSCPC_READ_CMD, + /// Configure sending of notification or indication + RSCPC_CFG_NTFIND_CMD, + + /// Configure the SC Control Point value + RSCPC_CTNL_PT_CFG_REQ, + /// SC Control Point value response + RSCPC_CTNL_PT_CFG_RSP, + + /// Indicate that an attribute value has been received either upon notification or read response + RSCPC_VALUE_IND, + + /// Complete Event Information + RSCPC_CMP_EVT, + + /// Procedure Timeout Timer + RSCPC_TIMEOUT_TIMER_IND, +}; + +/// Operation Codes +enum rscpc_op_codes +{ + /// Reserved operation code + RSCPC_RESERVED_OP_CODE = 0x00, + + /// Discovery Procedure + RSCPC_ENABLE_OP_CODE, + /// Read attribute value Procedure + RSCPC_READ_OP_CODE, + + /// Wait for the Write Response after having written a Client Char. Cfg. Descriptor. + RSCPC_CFG_NTF_IND_OP_CODE, + /// Wait for the Write Response after having written the SC Control Point Char. + RSCPC_CTNL_PT_CFG_WR_OP_CODE, + /// Wait for the Indication Response after having written the SC Control Point Char. + RSCPC_CTNL_PT_CFG_IND_OP_CODE, +}; + +/* + * API MESSAGE STRUCTURES + **************************************************************************************** + */ + +/// Running Speed and Cadence Service Characteristic Descriptors +enum rscpc_rscs_descs +{ + /// RSC Measurement Char. - Client Characteristic Configuration + RSCPC_DESC_RSC_MEAS_CL_CFG, + /// SC Control Point Char. - Client Characteristic Configuration + RSCPC_DESC_SC_CTNL_PT_CL_CFG, + + RSCPC_DESC_MAX, + + RSCPC_DESC_MASK = 0x10, +}; + +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Running Speed and Cadence Service + */ +struct rscpc_rscs_content +{ + /// Service info + struct prf_svc svc; + + /// Characteristic info: + /// - RSC Measurement + /// - RSC Feature + /// - Sensor Location + /// - SC Control Point + struct prf_char_inf chars[RSCP_RSCS_CHAR_MAX]; + + /// Descriptor handles: + /// - RSC Measurement Client Cfg + /// - SC Control Point Client Cfg + struct prf_char_desc_inf descs[RSCPC_DESC_MAX]; +}; + +/// Parameters of the @ref RSCPC_ENABLE_REQ message +struct rscpc_enable_req +{ + /// Connection type + uint8_t con_type; + /// Existing handle values RSCS + struct rscpc_rscs_content rscs; +}; + +/// Parameters of the @ref RSCPC_ENABLE_RSP message +struct rscpc_enable_rsp +{ + /// status + uint8_t status; + /// Existing handle values RSCS + struct rscpc_rscs_content rscs; +}; + +/// Parameters of the @ref RSCPC_READ_CMD message +struct rscpc_read_cmd +{ + /// Operation Code + uint8_t operation; + /// Read code + uint8_t read_code; +}; + +/// Parameters of the @ref RSCPC_VALUE_IND message +struct rscpc_value_ind +{ + /// Attribute Code + uint8_t att_code; + /// Value + union rscpc_value_tag + { + /// RSC Measurement + struct rscp_rsc_meas rsc_meas; + /// RSC Feature + uint16_t sensor_feat; + /// Sensor Location + uint8_t sensor_loc; + /// Client Characteristic Configuration Descriptor Value + uint16_t ntf_cfg; + } value; +}; + +/// Parameters of the @ref RSCPC_CFG_NTFIND_CMD message +struct rscpc_cfg_ntfind_cmd +{ + /// Operation Code + uint8_t operation; + /// Descriptor code + uint8_t desc_code; + /// Ntf/Ind Configuration + uint16_t ntfind_cfg; +}; + +/// Parameters of the @ref RSCPC_CTNL_PT_CFG_REQ message +struct rscpc_ctnl_pt_cfg_req +{ + /// Operation Code + uint8_t operation; + /// SC Control Point Request + struct rscp_sc_ctnl_pt_req sc_ctnl_pt; +}; + +/// Parameters of the @ref RSCPC_CTNL_PT_CFG_RSP message +struct rscpc_ctnl_pt_cfg_rsp +{ + /// SC Control Point Response + struct rscp_sc_ctnl_pt_rsp ctnl_pt_rsp; +}; + +/// Parameters of the @ref RSCPC_CMP_EVT message +struct rscpc_cmp_evt +{ + /// Operation code + uint8_t operation; + /// Status + uint8_t status; +}; + +/// @} RSCPCTASK + +#endif //(_RSCPC_TASK_H_) diff --git a/services/ble_profiles/rscp/rscpc/src/rscpc.c b/services/ble_profiles/rscp/rscpc/src/rscpc.c new file mode 100644 index 0000000..dc80922 --- /dev/null +++ b/services/ble_profiles/rscp/rscpc/src/rscpc.c @@ -0,0 +1,235 @@ +/** + **************************************************************************************** + * @addtogroup RSCPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_RSC_COLLECTOR) +#include "rscp_common.h" + + +#include "rscpc.h" +#include "rscpc_task.h" +#include "ke_timer.h" +#include "ke_mem.h" + +/* + * GLOBAL VARIABLES DECLARATION + **************************************************************************************** + */ + + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the RSCPC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t rscpc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct rscpc_env_tag* rscpc_env = + (struct rscpc_env_tag* ) ke_malloc(sizeof(struct rscpc_env_tag), KE_MEM_ATT_DB); + + // allocate RSCPC required environment variable + env->env = (prf_env_t*) rscpc_env; + + rscpc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + rscpc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_RSCPC; + rscpc_task_init(&(env->desc)); + + for(idx = 0; idx < RSCPC_IDX_MAX ; idx++) + { + rscpc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), RSCPC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void rscpc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct rscpc_env_tag* rscpc_env = (struct rscpc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(rscpc_env->env[conidx] != NULL) + { + if (rscpc_env->env[conidx]->operation != NULL) + { + ke_free(ke_param2msg(rscpc_env->env[conidx]->operation)); + } + ke_timer_clear(RSCPC_TIMEOUT_TIMER_IND, prf_src_task_get(&rscpc_env->prf_env, conidx)); + ke_free(rscpc_env->env[conidx]); + rscpc_env->env[conidx] = NULL; + } + + /* Put RSCP Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), RSCPC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the RSCPC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void rscpc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct rscpc_env_tag* rscpc_env = (struct rscpc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < RSCPC_IDX_MAX ; idx++) + { + rscpc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(rscpc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void rscpc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put RSCP Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), RSCPC_IDLE); +} + +/// RSCPC Task interface required by profile manager +const struct prf_task_cbs rscpc_itf = +{ + rscpc_init, + rscpc_destroy, + rscpc_create, + rscpc_cleanup, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* rscpc_prf_itf_get(void) +{ + return &rscpc_itf; +} + +void rscpc_enable_rsp_send(struct rscpc_env_tag *rscpc_env, uint8_t conidx, uint8_t status) +{ + // Send to APP the details of the discovered attributes on RSCPS + struct rscpc_enable_rsp * rsp = KE_MSG_ALLOC( + RSCPC_ENABLE_RSP, + prf_dst_task_get(&(rscpc_env->prf_env), conidx), + prf_src_task_get(&(rscpc_env->prf_env), conidx), + rscpc_enable_rsp); + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->rscs = rscpc_env->env[conidx]->rscs; + // Register RSCPC task in gatt for indication/notifications + prf_register_atthdl2gatt(&(rscpc_env->prf_env), conidx, &(rscpc_env->env[conidx]->rscs.svc)); + // Go to connected state + ke_state_set(prf_src_task_get(&(rscpc_env->prf_env), conidx), RSCPC_IDLE); + } + + ke_msg_send(rsp); +} + +void rscps_send_no_conn_cmp_evt(uint8_t src_id, uint8_t dest_id, uint8_t operation) +{ + // Send the message + struct rscpc_cmp_evt *evt = KE_MSG_ALLOC(RSCPC_CMP_EVT, + dest_id, src_id, + rscpc_cmp_evt); + + evt->operation = operation; + evt->status = PRF_ERR_REQ_DISALLOWED; + + ke_msg_send(evt); +} + +void rscpc_send_cmp_evt(struct rscpc_env_tag *rscpc_env, uint8_t conidx, uint8_t operation, uint8_t status) +{ + // Free the stored operation if needed + if (rscpc_env->env[conidx]->operation != NULL) + { + ke_msg_free(ke_param2msg(rscpc_env->env[conidx]->operation)); + rscpc_env->env[conidx]->operation = NULL; + } + + // Go back to the CONNECTED state if the state is busy + if (ke_state_get(prf_src_task_get(&(rscpc_env->prf_env), conidx)) == RSCPC_BUSY) + { + ke_state_set(prf_src_task_get(&(rscpc_env->prf_env), conidx), RSCPC_IDLE); + } + + // Send the message + struct rscpc_cmp_evt *evt = KE_MSG_ALLOC(RSCPC_CMP_EVT, + prf_dst_task_get(&(rscpc_env->prf_env), conidx), + prf_src_task_get(&(rscpc_env->prf_env), conidx), + rscpc_cmp_evt); + + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + +#endif //(BLE_RSC_COLLECTOR) + +/// @} RSCP diff --git a/services/ble_profiles/rscp/rscpc/src/rscpc.h b/services/ble_profiles/rscp/rscpc/src/rscpc.h new file mode 100644 index 0000000..f61b514 --- /dev/null +++ b/services/ble_profiles/rscp/rscpc/src/rscpc.h @@ -0,0 +1,174 @@ +#ifndef _RSCPC_H_ +#define _RSCPC_H_ + +/** + **************************************************************************************** + * @addtogroup RSCPC Running Speed and Cadence Profile Collector + * @ingroup RSCP + * @brief Running Speed and Cadence Profile Collector + * @{ + **************************************************************************************** + */ + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of Running Speed and Cadence Collector task instances +#define RSCPC_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_RSC_COLLECTOR) +#include "rscpc_task.h" + +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the RSCPC task +enum rscpc_states +{ + /// Idle state + RSCPC_FREE, + /// Connected state + RSCPC_IDLE, + /// Discovery + RSCPC_DISCOVERING, + /// Busy state + RSCPC_BUSY, + + /// Number of defined states. + RSCPC_STATE_MAX +}; + + +/// Internal codes for reading/writing a RSCS characteristic with one single request +enum rscpc_codes +{ + /// Notified RSC Measurement + RSCPC_NTF_RSC_MEAS = RSCP_RSCS_RSC_MEAS_CHAR, + /// Read RSC Feature + RSCPC_RD_RSC_FEAT = RSCP_RSCS_RSC_FEAT_CHAR, + /// Read Sensor Location + RSCPC_RD_SENSOR_LOC = RSCP_RSCS_SENSOR_LOC_CHAR, + /// Indicated SC Control Point + RSCPC_IND_SC_CTNL_PT = RSCP_RSCS_SC_CTNL_PT_CHAR, + + /// Read/Write RSC Measurement Client Char. Configuration Descriptor + RSCPC_RD_WR_RSC_MEAS_CFG = (RSCPC_DESC_RSC_MEAS_CL_CFG | RSCPC_DESC_MASK), + /// Read SC Control Point Client Char. Configuration Descriptor + RSCPC_RD_WR_SC_CTNL_PT_CFG = (RSCPC_DESC_SC_CTNL_PT_CL_CFG | RSCPC_DESC_MASK), +}; + + + +/* + * STRUCTURES + **************************************************************************************** + */ + +struct rscpc_cnx_env +{ + /// Current Operation + void *operation; + ///Last requested UUID(to keep track of the two services and char) + uint16_t last_uuid_req; + /// Counter used to check service uniqueness + uint8_t nb_svc; + /// Running Speed and Cadence Service Characteristics + struct rscpc_rscs_content rscs; +}; + +/// Running Speed and Cadence Profile Collector environment variable +struct rscpc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct rscpc_cnx_env* env[RSCPC_IDX_MAX]; + /// State of different task instances + ke_state_t state[RSCPC_IDX_MAX]; +}; + +/// Command Message Basic Structure +struct rscpc_cmd +{ + /// Operation Code + uint8_t operation; + + /// MORE DATA +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + + +/* + * GLOBAL FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve CSCP client profile interface + * + * @return CSCP client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* rscpc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Running Speed and Cadence ATT DB discovery results to RSCPC host. + **************************************************************************************** + */ +void rscpc_enable_rsp_send(struct rscpc_env_tag *cscpc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Send a RSCPC_CMP_EVT message when no connection exists (no environment) + **************************************************************************************** + */ +void rscps_send_no_conn_cmp_evt(uint8_t src_id, uint8_t dest_id, uint8_t operation); + +/** + **************************************************************************************** + * @brief Send a RSCPC_CMP_EVT message to the task which enabled the profile + **************************************************************************************** + */ +void rscpc_send_cmp_evt(struct rscpc_env_tag *rscpc_env, uint8_t conidx, uint8_t operation, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void rscpc_task_init(struct ke_task_desc *task_desc); + + +#endif //(BLE_RSC_COLLECTOR) + +/// @} RSCPC + +#endif //(_RSCPC_H_) diff --git a/services/ble_profiles/rscp/rscpc/src/rscpc_task.c b/services/ble_profiles/rscp/rscpc/src/rscpc_task.c new file mode 100644 index 0000000..44734c1 --- /dev/null +++ b/services/ble_profiles/rscp/rscpc/src/rscpc_task.c @@ -0,0 +1,943 @@ +/** + **************************************************************************************** + * @addtogroup RSCPCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_RSC_COLLECTOR) +#include "rscp_common.h" +#include "rscpc_task.h" +#include "rscpc.h" + +#include "gap.h" +#include "attm.h" +#include "gattc_task.h" +#include "prf_utils.h" +#include "compiler.h" +#include "ke_timer.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// State machine used to retrieve Running Speed and Cadence service characteristics information +const struct prf_char_def rscpc_rscs_char[RSCP_RSCS_CHAR_MAX] = +{ + /// RSC Measurement + [RSCP_RSCS_RSC_MEAS_CHAR] = {ATT_CHAR_RSC_MEAS, + ATT_MANDATORY, + ATT_CHAR_PROP_NTF}, + /// RSC Feature + [RSCP_RSCS_RSC_FEAT_CHAR] = {ATT_CHAR_RSC_FEAT, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, + /// Sensor Location + [RSCP_RSCS_SENSOR_LOC_CHAR] = {ATT_CHAR_SENSOR_LOC, + ATT_OPTIONAL, + ATT_CHAR_PROP_RD}, + /// SC Control Point + [RSCP_RSCS_SC_CTNL_PT_CHAR] = {ATT_CHAR_SC_CNTL_PT, + ATT_OPTIONAL, + ATT_CHAR_PROP_WR | ATT_CHAR_PROP_IND}, +}; + +/// State machine used to retrieve Running Speed and Cadence service characteristic descriptor information +const struct prf_char_desc_def rscpc_rscs_char_desc[RSCPC_DESC_MAX] = +{ + /// RSC Measurement Char. - Client Characteristic Configuration + [RSCPC_DESC_RSC_MEAS_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_MANDATORY, + RSCP_RSCS_RSC_MEAS_CHAR}, + /// SC Control Point Char. - Client Characteristic Configuration + [RSCPC_DESC_SC_CTNL_PT_CL_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_OPTIONAL, + RSCP_RSCS_SC_CTNL_PT_CHAR}, +}; + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == RSCPC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct rscpc_env_tag *rscpc_env = PRF_ENV_GET(RSCPC, rscpc); + + ASSERT_INFO(rscpc_env != NULL, dest_id, src_id); + ASSERT_INFO(rscpc_env->env[conidx] != NULL, dest_id, src_id); + + if(rscpc_env->env[conidx]->nb_svc == 0) + { + // Retrieve RSCS characteristics and descriptors + prf_extract_svc_info(ind, RSCP_RSCS_CHAR_MAX, &rscpc_rscs_char[0], &rscpc_env->env[conidx]->rscs.chars[0], + RSCPC_DESC_MAX, &rscpc_rscs_char_desc[0], &rscpc_env->env[conidx]->rscs.descs[0]); + + //Even if we get multiple responses we only store 1 range + rscpc_env->env[conidx]->rscs.svc.shdl = ind->start_hdl; + rscpc_env->env[conidx]->rscs.svc.ehdl = ind->end_hdl; + } + + rscpc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref RSCPC_ENABLE_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int rscpc_enable_req_handler(ke_msg_id_t const msgid, + struct rscpc_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + uint8_t state = ke_state_get(dest_id); + // Running Speed and Cadence Profile Collector Role Task Environment + struct rscpc_env_tag *rscpc_env = PRF_ENV_GET(RSCPC, rscpc); + + ASSERT_INFO(rscpc_env != NULL, dest_id, src_id); + if ((state == RSCPC_IDLE) && (rscpc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + rscpc_env->env[conidx] = (struct rscpc_cnx_env*) ke_malloc(sizeof(struct rscpc_cnx_env), KE_MEM_ATT_DB); + memset(rscpc_env->env[conidx], 0, sizeof(struct rscpc_cnx_env)); + + // Start discovering + if (param->con_type == PRF_CON_DISCOVERY) + { + prf_disc_svc_send(&(rscpc_env->prf_env), conidx, ATT_SVC_RUNNING_SPEED_CADENCE); + + // Go to DISCOVERING state + ke_state_set(dest_id, RSCPC_DISCOVERING); + } + // Bond information is provided + else + { + rscpc_env->env[conidx]->rscs = param->rscs; + + //send APP confirmation that can start normal connection to TH + rscpc_enable_rsp_send(rscpc_env, conidx, GAP_ERR_NO_ERROR); + } + } + else if (state != RSCPC_FREE) + { + // The message will be forwarded towards the good task instance + status = PRF_ERR_REQ_DISALLOWED; + } + + if(status != GAP_ERR_NO_ERROR) + { + // The request is disallowed (profile already enabled for this connection, or not enough memory, ...) + rscpc_enable_rsp_send(rscpc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref RSCPC_READ_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int rscpc_read_cmd_handler(ke_msg_id_t const msgid, + struct rscpc_read_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get the address of the environment + struct rscpc_env_tag *rscpc_env = PRF_ENV_GET(RSCPC, rscpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (state == RSCPC_IDLE) + { + // State is Connected or Busy + ASSERT_INFO(rscpc_env != NULL, dest_id, src_id); + + // Check the current state + if (rscpc_env->env[conidx] == NULL) + { + status = PRF_APP_ERROR; + } + else // State is RSCPC_CONNECTED + { + // Attribute Handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + + switch (param->read_code) + { + // Read RSC Feature + case (RSCPC_RD_RSC_FEAT): + { + handle = rscpc_env->env[conidx]->rscs.chars[RSCP_RSCS_RSC_FEAT_CHAR].val_hdl; + } break; + + // Read Sensor Location + case (RSCPC_RD_SENSOR_LOC): + { + handle = rscpc_env->env[conidx]->rscs.chars[RSCP_RSCS_SENSOR_LOC_CHAR].val_hdl; + } break; + + // Read RSC Measurement Characteristic Client Char. Cfg. Descriptor Value + case (RSCPC_RD_WR_RSC_MEAS_CFG): + { + handle = rscpc_env->env[conidx]->rscs.descs[RSCPC_DESC_RSC_MEAS_CL_CFG].desc_hdl; + } break; + + // Read Unread Alert Characteristic Client Char. Cfg. Descriptor Value + case (RSCPC_RD_WR_SC_CTNL_PT_CFG): + { + handle = rscpc_env->env[conidx]->rscs.descs[RSCPC_DESC_SC_CTNL_PT_CL_CFG].desc_hdl; + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + + // Check if handle is viable + if (handle != ATT_INVALID_SEARCH_HANDLE) + { + // Force the operation value + param->operation = RSCPC_READ_OP_CODE; + + // Store the command structure + rscpc_env->env[conidx]->operation = (void *)param; + msg_status = KE_MSG_NO_FREE; + + // Send the read request + prf_read_char_send(&(rscpc_env->prf_env), conidx, + rscpc_env->env[conidx]->rscs.svc.shdl, + rscpc_env->env[conidx]->rscs.svc.ehdl, + handle); + + // Go to the Busy state + ke_state_set(dest_id, RSCPC_BUSY); + + status = ATT_ERR_NO_ERROR; + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + } + else if (state == RSCPC_FREE) + { + status = GAP_ERR_DISCONNECTED; + } + else + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + status = GAP_ERR_NO_ERROR; + } + + if (status != GAP_ERR_NO_ERROR) + { + // Send the complete event message to the task id stored in the environment + rscpc_send_cmp_evt(rscpc_env, conidx, RSCPC_READ_OP_CODE, status); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref RSCPC_CFG_NTFIND_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int rscpc_cfg_ntfind_cmd_handler(ke_msg_id_t const msgid, + struct rscpc_cfg_ntfind_cmd *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct rscpc_env_tag *rscpc_env = PRF_ENV_GET(RSCPC, rscpc); + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + if (rscpc_env != NULL) + { + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + // Handle + uint16_t handle = ATT_INVALID_SEARCH_HANDLE; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + do + { + if (ke_state_get(dest_id) != RSCPC_IDLE) + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + // Status is GAP_ERR_NO_ERROR, no message will be sent to the application + break; + } + + ASSERT_ERR(rscpc_env->env[conidx] != NULL); + + switch(param->desc_code) + { + // Write RSC Measurement Characteristic Client Char. Cfg. Descriptor Value + case (RSCPC_RD_WR_RSC_MEAS_CFG): + { + if (param->ntfind_cfg <= PRF_CLI_START_NTF) + { + handle = rscpc_env->env[conidx]->rscs.descs[RSCPC_DESC_RSC_MEAS_CL_CFG].desc_hdl; + + status = GAP_ERR_NO_ERROR; + // The characteristic is mandatory and the descriptor is mandatory + ASSERT_ERR(handle != ATT_INVALID_SEARCH_HANDLE); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + // Write SC Control Point Characteristic Client Char. Cfg. Descriptor Value + case (RSCPC_RD_WR_SC_CTNL_PT_CFG): + { + if ((param->ntfind_cfg == PRF_CLI_STOP_NTFIND) || + (param->ntfind_cfg == PRF_CLI_START_IND)) + { + handle = rscpc_env->env[conidx]->rscs.descs[RSCPC_DESC_SC_CTNL_PT_CL_CFG].desc_hdl; + + status = GAP_ERR_NO_ERROR; + if (handle == ATT_INVALID_SEARCH_HANDLE) + { + // The descriptor has not been found. + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + } while (0); + + + if ((status == GAP_ERR_NO_ERROR) && (handle != ATT_INVALID_SEARCH_HANDLE)) + { + // Set the operation code + param->operation = RSCPC_CFG_NTF_IND_OP_CODE; + + // Store the command structure + rscpc_env->env[conidx]->operation = param; + msg_status = KE_MSG_NO_FREE; + + // Go to the Busy state + ke_state_set(dest_id, RSCPC_BUSY); + + // Send GATT Write Request + prf_gatt_write_ntf_ind(&rscpc_env->prf_env, conidx, handle, param->ntfind_cfg); + } + } + else + { + // No connection + rscps_send_no_conn_cmp_evt(dest_id, src_id, RSCPC_CFG_NTF_IND_OP_CODE); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref RSCPC_CFG_NTFIND_CMD message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int rscpc_ctnl_pt_cfg_req_handler(ke_msg_id_t const msgid, + struct rscpc_ctnl_pt_cfg_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + // Get the address of the environment + struct rscpc_env_tag *rscpc_env = PRF_ENV_GET(RSCPC, rscpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if (rscpc_env != NULL) + { + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + do + { + // State is Connected or Busy + ASSERT_ERR(ke_state_get(dest_id) > RSCPC_FREE); + + // Check the provided connection handle + if (rscpc_env->env[conidx] == NULL) + { + status = PRF_ERR_INVALID_PARAM; + break; + } + + if (ke_state_get(dest_id) != RSCPC_IDLE) + { + // Another procedure is pending, keep the command for later + msg_status = KE_MSG_SAVED; + // Status is GAP_ERR_NO_ERROR, no message will be sent to the application + break; + } + + // Check if the characteristic has been found + if (rscpc_env->env[conidx]->rscs.descs[RSCPC_DESC_SC_CTNL_PT_CL_CFG].desc_hdl != ATT_INVALID_SEARCH_HANDLE) + { + // Packed request + uint8_t req[RSCP_SC_CNTL_PT_REQ_MAX_LEN]; + // Request Length + uint8_t req_len = RSCP_SC_CNTL_PT_REQ_MIN_LEN; + + // Set the operation code + req[0] = param->sc_ctnl_pt.op_code; + + // Fulfill the message according to the operation code + switch (param->sc_ctnl_pt.op_code) + { + case (RSCP_CTNL_PT_OP_RESERVED): + { + // Do nothing, used to generate an "Operation Code not supported" error. + } break; + + case (RSCP_CTNL_PT_OP_SET_CUMUL_VAL): + { + // Set the cumulative value + co_write32p(&req[req_len], param->sc_ctnl_pt.value.cumul_val); + // Update length + req_len += 4; + } break; + + case (RSCP_CTNL_PT_OP_UPD_LOC): + { + // Set the sensor location + req[req_len] = param->sc_ctnl_pt.value.sensor_loc; + // Update length + req_len++; + } break; + + case (RSCP_CTNL_PT_OP_START_CALIB): + case (RSCP_CTNL_PT_OP_REQ_SUPP_LOC): + { + // Nothing more to do + } break; + + default: + { + status = PRF_ERR_INVALID_PARAM; + } break; + } + + if (status == GAP_ERR_NO_ERROR) + { + // Set the operation code + param->operation = RSCPC_CTNL_PT_CFG_WR_OP_CODE; + + // Store the command structure + rscpc_env->env[conidx]->operation = param; + // Store the command information + msg_status = KE_MSG_NO_FREE; + + // Go to the Busy state + ke_state_set(dest_id, RSCPC_BUSY); + + // Send the write request + prf_gatt_write(&(rscpc_env->prf_env), conidx, rscpc_env->env[conidx]->rscs.chars[RSCP_RSCS_SC_CTNL_PT_CHAR].val_hdl, + (uint8_t *)&req[0], req_len, GATTC_WRITE); + } + } + else + { + // The SC Control Point Characteristic has not been found + status = PRF_ERR_INEXISTENT_HDL; + } + } while (0); + + if (status != GAP_ERR_NO_ERROR) + { + // Send a complete event status to the application + rscpc_send_cmp_evt(rscpc_env, conidx, RSCPC_CTNL_PT_CFG_WR_OP_CODE, status); + } + } + else + { + // No connection + rscps_send_no_conn_cmp_evt(dest_id, src_id, RSCPC_CTNL_PT_CFG_WR_OP_CODE); + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref RSCPC_TIMEOUT_TIMER_IND message. This message is + * received when the peer device doesn't send a SC Control Point indication within 30s + * after reception of the write response. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int rscpc_timeout_timer_ind_handler(ke_msg_id_t const msgid, + void const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct rscpc_env_tag *rscpc_env = PRF_ENV_GET(RSCPC, rscpc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if ((rscpc_env != NULL) && (rscpc_env->env[conidx] != NULL)) + { + ASSERT_ERR(rscpc_env->env[conidx]->operation != NULL); + ASSERT_ERR(((struct rscpc_cmd *)rscpc_env->env[conidx]->operation)->operation == RSCPC_CTNL_PT_CFG_IND_OP_CODE); + + // Send the complete event message + rscpc_send_cmp_evt(rscpc_env, conidx, RSCPC_CTNL_PT_CFG_WR_OP_CODE, PRF_ERR_PROC_TIMEOUT); + } + // else drop the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct rscpc_env_tag *rscpc_env = PRF_ENV_GET(RSCPC, rscpc); + // Status + uint8_t status; + + if (rscpc_env != NULL) + { + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t state = ke_state_get(dest_id); + + if (state == RSCPC_DISCOVERING) + { + status = param->status; + + if ((status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || + (status == ATT_ERR_NO_ERROR)) + { + // Discovery + // check characteristic validity + if(rscpc_env->env[conidx]->nb_svc == 1) + { + status = prf_check_svc_char_validity(RSCP_RSCS_CHAR_MAX, + rscpc_env->env[conidx]->rscs.chars, + rscpc_rscs_char); + } + // too much services + else if (rscpc_env->env[conidx]->nb_svc > 1) + { + status = PRF_ERR_MULTIPLE_SVC; + } + // no services found + else + { + status = PRF_ERR_STOP_DISC_CHAR_MISSING; + } + + // check descriptor validity + if (status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(RSCPC_DESC_MAX, + rscpc_env->env[conidx]->rscs.descs, + rscpc_rscs_char_desc, + rscpc_env->env[conidx]->rscs.chars); + } + } + + rscpc_enable_rsp_send(rscpc_env, conidx, status); + } + + else if (state == RSCPC_BUSY) + { + switch (param->operation) + { + case GATTC_READ: + { + // Send the complete event status + rscpc_send_cmp_evt(rscpc_env, conidx, RSCPC_READ_OP_CODE, param->status); + } break; + + case GATTC_WRITE: + case GATTC_WRITE_NO_RESPONSE: + { + uint8_t operation = ((struct rscpc_cmd *)rscpc_env->env[conidx]->operation)->operation; + + if (operation == RSCPC_CFG_NTF_IND_OP_CODE) + { + // Send the complete event status + rscpc_send_cmp_evt(rscpc_env, conidx, operation, param->status); + } + + else if (operation == RSCPC_CTNL_PT_CFG_WR_OP_CODE) + { + if (param->status == GAP_ERR_NO_ERROR) + { + // Start Timeout Procedure + ke_timer_set(RSCPC_TIMEOUT_TIMER_IND, dest_id, ATT_TRANS_RTX); + + // Wait for the response indication + ((struct rscpc_cmd *)rscpc_env->env[conidx]->operation)->operation = RSCPC_CTNL_PT_CFG_IND_OP_CODE; + } + else + { + // Send the complete event status + rscpc_send_cmp_evt(rscpc_env, conidx, operation, param->status); + } + } + } break; + + case GATTC_REGISTER: + case GATTC_UNREGISTER: + { + // Do nothing + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + } + // else ignore the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct rscpc_env_tag *rscpc_env = PRF_ENV_GET(RSCPC, rscpc); + + if (ke_state_get(dest_id) == RSCPC_BUSY) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + ASSERT_INFO(rscpc_env != NULL, dest_id, src_id); + ASSERT_INFO(rscpc_env->env[conidx] != NULL, dest_id, src_id); + + // Send the read value to the HL + struct rscpc_value_ind *ind = KE_MSG_ALLOC(RSCPC_VALUE_IND, + prf_dst_task_get(&(rscpc_env->prf_env), conidx), + dest_id, + rscpc_value_ind); + + switch (((struct rscpc_read_cmd *)rscpc_env->env[conidx]->operation)->read_code) + { + // Read RSC Feature Characteristic value + case (RSCPC_RD_RSC_FEAT): + { + ind->value.sensor_feat = co_read16p(param->value); + + // Mask the unused bits +// ind->value.sensor_feat &= RSCP_FEAT_ALL_SUPP; + } break; + + // Read Sensor Location Characteristic value + case (RSCPC_RD_SENSOR_LOC): + { + ind->value.sensor_loc = param->value[0]; + } break; + + // Read Client Characteristic Configuration Descriptor value + case (RSCPC_RD_WR_RSC_MEAS_CFG): + case (RSCPC_RD_WR_SC_CTNL_PT_CFG): + { + co_write16p(&ind->value.ntf_cfg, param->value[0]); + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + + ind->att_code = ((struct rscpc_read_cmd *)rscpc_env->env[conidx]->operation)->read_code; + + // Send the message to the application + ke_msg_send(ind); + } + // else drop the message + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(dest_id); + // Get the address of the environment + struct rscpc_env_tag *rscpc_env = PRF_ENV_GET(RSCPC, rscpc); + + if (rscpc_env != NULL) + { + switch (param->type) + { + case (GATTC_NOTIFY): + { + // Offset + uint8_t offset = RSCP_RSC_MEAS_MIN_LEN; + + // RSC Measurement value has been received + struct rscpc_value_ind *ind = KE_MSG_ALLOC(RSCPC_VALUE_IND, + prf_dst_task_get(&(rscpc_env->prf_env), conidx), + prf_src_task_get(&(rscpc_env->prf_env), conidx), + rscpc_value_ind); + + // Attribute code + ind->att_code = RSCPC_NTF_RSC_MEAS; + + /*---------------------------------------------------- + * Unpack Measurement -------------------------------- + *----------------------------------------------------*/ + + // Flags + ind->value.rsc_meas.flags = param->value[0]; + // Instantaneous Speed + ind->value.rsc_meas.inst_speed = co_read16p((uint16_t *)¶m->value[1]); + // Instantaneous Cadence + ind->value.rsc_meas.inst_cad = param->value[3]; + + // Instantaneous Stride Length + if (param->value[0] & RSCP_MEAS_INST_STRIDE_LEN_PRESENT) + { + ind->value.rsc_meas.inst_stride_len = co_read16p(¶m->value[offset]); + offset += 2; + } + + // Total Distance + if (param->value[0] & RSCP_MEAS_TOTAL_DST_MEAS_PRESENT) + { + ind->value.rsc_meas.total_dist = co_read32p(¶m->value[offset]); + } + + ke_msg_send(ind); + } break; + + case (GATTC_INDICATE): + { + // confirm that indication has been correctly received + struct gattc_event_cfm * cfm = KE_MSG_ALLOC(GATTC_EVENT_CFM, src_id, dest_id, gattc_event_cfm); + cfm->handle = param->handle; + ke_msg_send(cfm); + + // Check if we were waiting for the indication + if (rscpc_env->env[conidx]->operation != NULL) + { + if (((struct rscpc_cmd *)rscpc_env->env[conidx]->operation)->operation == RSCPC_CTNL_PT_CFG_IND_OP_CODE) + { + // Stop the procedure timeout timer + ke_timer_clear(RSCPC_TIMEOUT_TIMER_IND, dest_id); + + // RSC Measurement value has been received + struct rscpc_ctnl_pt_cfg_rsp *ind = KE_MSG_ALLOC(RSCPC_CTNL_PT_CFG_RSP, + prf_dst_task_get(&(rscpc_env->prf_env), conidx), + prf_src_task_get(&(rscpc_env->prf_env), conidx), + rscpc_ctnl_pt_cfg_rsp); + + // Requested operation code + ind->ctnl_pt_rsp.req_op_code = param->value[1]; + // Response value + ind->ctnl_pt_rsp.resp_value = param->value[2]; + + // Get the list of supported sensor locations if needed + if ((ind->ctnl_pt_rsp.req_op_code == RSCP_CTNL_PT_OP_REQ_SUPP_LOC) && + (ind->ctnl_pt_rsp.resp_value == RSCP_CTNL_PT_RESP_SUCCESS) && + (param->length > 3)) + { + // Get the number of supported locations that have been received + uint8_t nb_supp_loc = (param->length - 3); + // Counter + uint8_t counter; + // Location + uint8_t loc; + + for (counter = 0; counter < nb_supp_loc; counter++) + { + loc = param->value[counter + 3]; + + // Check if valid + if (loc < RSCP_LOC_MAX) + { + ind->ctnl_pt_rsp.supp_loc |= (1 << loc); + } + } + } + + // Send the message + ke_msg_send(ind); + + // Send the complete event message + rscpc_send_cmp_evt(rscpc_env, conidx, RSCPC_CTNL_PT_CFG_WR_OP_CODE, GAP_ERR_NO_ERROR); + } + // else drop the message + } + // else drop the message + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(rscpc) +{ + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {RSCPC_ENABLE_REQ, (ke_msg_func_t)rscpc_enable_req_handler}, + {RSCPC_READ_CMD, (ke_msg_func_t)rscpc_read_cmd_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {RSCPC_CFG_NTFIND_CMD, (ke_msg_func_t)rscpc_cfg_ntfind_cmd_handler}, + {RSCPC_CTNL_PT_CFG_REQ, (ke_msg_func_t)rscpc_ctnl_pt_cfg_req_handler}, + {RSCPC_TIMEOUT_TIMER_IND, (ke_msg_func_t)rscpc_timeout_timer_ind_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_EVENT_REQ_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void rscpc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct rscpc_env_tag *rscpc_env = PRF_ENV_GET(RSCPC, rscpc); + + task_desc->msg_handler_tab = rscpc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(rscpc_msg_handler_tab); + task_desc->state = rscpc_env->state; + task_desc->idx_max = RSCPC_IDX_MAX; +} + +#endif //(BLE_RSC_COLLECTOR) + +/// @} RSCPCTASK diff --git a/services/ble_profiles/rscp/rscps/api/rscps_task.h b/services/ble_profiles/rscp/rscps/api/rscps_task.h new file mode 100644 index 0000000..1fc2a9b --- /dev/null +++ b/services/ble_profiles/rscp/rscps/api/rscps_task.h @@ -0,0 +1,205 @@ +#ifndef _RSCPS_TASK_H_ +#define _RSCPS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup RSCPSTASK Task + * @ingroup RSCPS + * @brief Running Speed and Cadence Profile Task. + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rscp_common.h" +#include "rwip_task.h" // Task definitions + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Messages for Running Speed and Cadence Profile Sensor +enum rscps_msg_id +{ + /// Enable the RSCP Sensor task for a connection + RSCPS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_RSCPS), + /// Enable the RSCP Sensor task for a connection + RSCPS_ENABLE_RSP, + + /// Send a RSC Measurement to the peer device (Notification) + RSCPS_NTF_RSC_MEAS_REQ, + /// Response of RSC Measurement send request + RSCPS_NTF_RSC_MEAS_RSP, + + /// Indicate that the SC Control Point characteristic value has been written + RSCPS_SC_CTNL_PT_REQ_IND, + /// Application response after receiving a RSCPS_SC_CTNL_PT_REQ_IND message + RSCPS_SC_CTNL_PT_CFM, + + /// Indicate a new NTF/IND configuration to the application + RSCPS_CFG_NTFIND_IND, + + /// Send a complete event status to the application + RSCPS_CMP_EVT, +}; + +/// Operation Code used in the profile state machine +enum rscps_op_code +{ + /// Reserved Operation Code + RSCPS_RESERVED_OP_CODE = 0x00, + + /// Enable Profile Operation Code + RSCPS_ENABLE_OP_CODE, + /// Send RSC Measurement Operation Code + RSCPS_SEND_RSC_MEAS_OP_CODE, + + /** + * SC Control Point Operation + */ + + /// Set Cumulative Value Operation Code + RSCPS_CTNL_PT_CUMUL_VAL_OP_CODE, + /// Start Sensor Calibration Operation Code + RSCPS_CTNL_PT_START_CAL_OP_CODE, + /// Update Sensor Location Operation Code + RSCPS_CTNL_PT_UPD_LOC_OP_CODE, + /// Request Supported Sensor Locations Operation Code + RSCPS_CTNL_PT_SUPP_LOC_OP_CODE, + /// Error Indication Sent Operation Code + RSCPS_CTNL_ERR_IND_OP_CODE, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Parameters of the initialization function +struct rscps_db_cfg +{ + /** + * RSC Feature Value - Not supposed to be modified during the lifetime of the device + * This value is used to decide if the SC Control Point Characteristic is part of the + * Running Speed and Cadence service. + */ + uint16_t rsc_feature; + /** + * Indicate if the Sensor Location characteristic is supported. Note that if the Multiple + * Sensor Location feature is set has supported in the rsc_feature parameter, the + * characteristic will be added (mandatory). + */ + uint8_t sensor_loc_supp; + /// Sensor location + uint8_t sensor_loc; +}; + +/// Parameters of the @ref RSCPS_ENABLE_REQ message +struct rscps_enable_req +{ + /// Connection handle + uint16_t conidx; + /// Stored RSC Measurement Char. Client Characteristic Configuration + uint16_t rsc_meas_ntf_cfg; + /// Stored SC Control Point Char. Client Characteristic Configuration + uint16_t sc_ctnl_pt_ntf_cfg; +}; + +/// Parameters of the @ref RSCPS_ENABLE_RSP message +struct rscps_enable_rsp +{ + /// Connection index + uint8_t conidx; + /// Status + uint8_t status; +}; + +/// Parameters of the @ref RSCPS_NTF_RSC_MEAS_REQ message +struct rscps_ntf_rsc_meas_req +{ + /// Flags + uint8_t flags; + /// Instantaneous Cadence + uint8_t inst_cad; + /// Instantaneous Speed + uint16_t inst_speed; + /// Instantaneous Stride Length + uint16_t inst_stride_len; + /// Total Distance + uint32_t total_dist; +}; + +/// Parameters of the @ref RSCPS_NTF_RSC_MEAS_RSP message +struct rscps_ntf_rsc_meas_rsp +{ + /// status of the request + uint8_t status; +}; + +/// Parameters of the @ref RSCPS_SC_CTNL_PT_REQ_IND message +struct rscps_sc_ctnl_pt_req_ind +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t op_code; + /// Value + union rscps_sc_ctnl_pt_req_ind_value + { + /// Cumulative value + uint32_t cumul_value; + /// Sensor Location + uint8_t sensor_loc; + } value; +}; + +/// Parameters of the @ref RSCPS_SC_CTNL_PT_CFM message +struct rscps_sc_ctnl_pt_cfm +{ + /// Connection handle + uint8_t conidx; + /// Operation Code + uint8_t op_code; + /// Status + uint8_t status; + /// Value + union rscps_sc_ctnl_pt_cfm_value + { + /// Sensor Location + uint8_t sensor_loc; + /// Supported sensor locations + uint16_t supp_sensor_loc; + } value; +}; + +/// Parameters of the @ref RSCPS_CFG_NTFIND_IND message +struct rscps_cfg_ntfind_ind +{ + /// Connection index + uint8_t conidx; + /// Characteristic Code (RSC Measurement or SC Control Point) + uint8_t char_code; + /// Char. Client Characteristic Configuration + uint16_t ntf_cfg; +}; + +/// Parameters of the @ref RSCPS_CMP_EVT message +struct rscps_cmp_evt +{ + /// Connection index + uint8_t conidx; + /// Operation Code + uint8_t operation; + /// Operation Status + uint8_t status; +}; + +/// @} RSCPSTASK + +#endif //(_RSCPS_TASK_H_) diff --git a/services/ble_profiles/rscp/rscps/src/rscps.c b/services/ble_profiles/rscp/rscps/src/rscps.c new file mode 100644 index 0000000..d8ee461 --- /dev/null +++ b/services/ble_profiles/rscp/rscps/src/rscps.c @@ -0,0 +1,356 @@ +/** + **************************************************************************************** + * @addtogroup RSCPS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_RSC_SENSOR) +#include "rscp_common.h" + +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "rscps.h" +#include "rscps_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Full RSCPS Database Description - Used to add attributes into the database +static const struct attm_desc rscps_att_db[RSCS_IDX_NB] = +{ + // Running Speed and Cadence Service Declaration + [RSCS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // RSC Measurement Characteristic Declaration + [RSCS_IDX_RSC_MEAS_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // RSC Measurement Characteristic Value + [RSCS_IDX_RSC_MEAS_VAL] = {ATT_CHAR_RSC_MEAS, PERM(NTF, ENABLE), PERM(RI, ENABLE), RSCP_RSC_MEAS_MAX_LEN}, + // RSC Measurement Characteristic - Client Characteristic Configuration Descriptor + [RSCS_IDX_RSC_MEAS_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // RSC Feature Characteristic Declaration + [RSCS_IDX_RSC_FEAT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // RSC Feature Characteristic Value + [RSCS_IDX_RSC_FEAT_VAL] = {ATT_CHAR_RSC_FEAT, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(uint16_t)}, + + // Sensor Location Characteristic Declaration + [RSCS_IDX_SENSOR_LOC_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Sensor Location Characteristic Value + [RSCS_IDX_SENSOR_LOC_VAL] = {ATT_CHAR_SENSOR_LOC, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(uint8_t)}, + + // SC Control Point Characteristic Declaration + [RSCS_IDX_SC_CTNL_PT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // SC Control Point Characteristic Value - The response has the maximal length + [RSCS_IDX_SC_CTNL_PT_VAL] = {ATT_CHAR_SC_CNTL_PT, PERM(IND, ENABLE) | PERM(WRITE_REQ, ENABLE), + PERM(RI, ENABLE), RSCP_SC_CNTL_PT_RSP_MAX_LEN}, + // SC Control Point Characteristic - Client Characteristic Configuration Descriptor + [RSCS_IDX_SC_CTNL_PT_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the RSCPS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t rscps_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct rscps_db_cfg* param) +{ + //------------------ create the attribute database for the profile ------------------- + // Service content flag + uint32_t cfg_flag= RSCPS_MANDATORY_MASK; + // DB Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + + /* + * Check if the Sensor Location characteristic shall be added. + * Mandatory if the Multiple Sensor Location feature is supported, otherwise optional. + */ + if ((param->sensor_loc_supp == RSCPS_SENSOR_LOC_SUPP) || + (RSCPS_IS_FEATURE_SUPPORTED(param->rsc_feature, RSCP_FEAT_MULT_SENSOR_LOC_SUPP))) + { + cfg_flag |= RSCPS_SENSOR_LOC_MASK; + } + + /* + * Check if the SC Control Point characteristic shall be added + * Mandatory if at least one SC Control Point procedure is supported, otherwise excluded. + */ + if (RSCPS_IS_FEATURE_SUPPORTED(param->rsc_feature, RSCP_FEAT_CALIB_PROC_SUPP) || + RSCPS_IS_FEATURE_SUPPORTED(param->rsc_feature, RSCP_FEAT_MULT_SENSOR_LOC_SUPP) || + RSCPS_IS_FEATURE_SUPPORTED(param->rsc_feature, RSCP_FEAT_TOTAL_DST_MEAS_SUPP)) + { + cfg_flag |= RSCPS_SC_CTNL_PT_MASK; + } + + // Add service in the database + status = attm_svc_create_db(start_hdl, ATT_SVC_RUNNING_SPEED_CADENCE, (uint8_t *)&cfg_flag, + RSCS_IDX_NB, NULL, env->task, &rscps_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, DISABLE)); + + // Check if an error has occured + if (status == ATT_ERR_NO_ERROR) + { + // Allocate RSCPS required environment variable + struct rscps_env_tag* rscps_env = + (struct rscps_env_tag* ) ke_malloc(sizeof(struct rscps_env_tag), KE_MEM_ATT_DB); + + // Initialize RSCPS environment + + env->env = (prf_env_t*) rscps_env; + rscps_env->shdl = *start_hdl; + rscps_env->prf_cfg = cfg_flag; + rscps_env->features = param->rsc_feature; + rscps_env->operation = RSCPS_RESERVED_OP_CODE; + + if (RSCPS_IS_FEATURE_SUPPORTED(rscps_env->prf_cfg, RSCPS_SENSOR_LOC_MASK)) + { + rscps_env->sensor_loc = (param->sensor_loc >= RSCP_LOC_MAX) ? + RSCP_LOC_OTHER : param->sensor_loc; + } + + rscps_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Mono Instantiated task + rscps_env->prf_env.prf_task = env->task | PERM(PRF_MI, DISABLE); + + // initialize environment variable + env->id = TASK_ID_RSCPS; + rscps_task_init(&(env->desc)); + + rscps_env->ntf = NULL; + memset(rscps_env->prfl_ntf_ind_cfg, 0, BLE_CONNECTION_MAX); + + // If we are here, database has been fulfilled with success, go to idle state + ke_state_set(env->task, RSCPS_IDLE); + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the RSCPS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void rscps_destroy(struct prf_task_env* env) +{ + struct rscps_env_tag* rscps_env = (struct rscps_env_tag*) env->env; + + // cleanup environment variable for each task instances + if(rscps_env->ntf != NULL) + { + ke_free(rscps_env->ntf); + } + + // free profile environment variables + env->env = NULL; + ke_free(rscps_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void rscps_create(struct prf_task_env* env, uint8_t conidx) +{ + struct rscps_env_tag* rscps_env = (struct rscps_env_tag*) env->env; + rscps_env->prfl_ntf_ind_cfg[conidx] = 0; + +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void rscps_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct rscps_env_tag* rscps_env = (struct rscps_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + rscps_env->prfl_ntf_ind_cfg[conidx] = 0; +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// RSCPS Task interface required by profile manager +const struct prf_task_cbs rscps_itf = +{ + (prf_init_fnct) rscps_init, + rscps_destroy, + rscps_create, + rscps_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* rscps_prf_itf_get(void) +{ + return &rscps_itf; +} + +void rscps_send_cmp_evt(uint8_t conidx, uint8_t src_id, uint8_t dest_id, uint8_t operation, uint8_t status) +{ + // Get the address of the environment + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + + // Go back to the Connected state if the state is busy + if (ke_state_get(src_id) == RSCPS_BUSY) + { + ke_state_set(src_id, RSCPS_IDLE); + } + + // Set the operation code + rscps_env->operation = RSCPS_RESERVED_OP_CODE; + + // Send the message + struct rscps_cmp_evt *evt = KE_MSG_ALLOC(RSCPS_CMP_EVT, + dest_id, src_id, + rscps_cmp_evt); + + evt->operation = operation; + evt->status = status; + + ke_msg_send(evt); +} + + +void rscps_exe_operation(void) +{ + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + + ASSERT_ERR(rscps_env->ntf != NULL); + + bool finished = true; + + while(rscps_env->ntf->cursor < BLE_CONNECTION_MAX) + { + // Check if notifications are enabled + if(RSCPS_IS_NTFIND_ENABLED(rscps_env->ntf->cursor, RSCP_PRF_CFG_FLAG_RSC_MEAS_NTF)) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, rscps_env->ntf->cursor), + prf_src_task_get(&(rscps_env->prf_env), 0), + gattc_send_evt_cmd, rscps_env->ntf->length); + + // Fill in the parameter structure + meas_val->operation = GATTC_NOTIFY; + meas_val->handle = RSCPS_HANDLE(RSCS_IDX_RSC_MEAS_VAL); + meas_val->length = rscps_env->ntf->length; + memcpy(meas_val->value, rscps_env->ntf->value, rscps_env->ntf->length); + + // Send the event + ke_msg_send(meas_val); + + finished = false; + rscps_env->ntf->cursor++; + break; + } + + rscps_env->ntf->cursor++; + } + + // check if operation is finished + if(finished) + { + // Inform the application that a procedure has been completed + struct rscps_ntf_rsc_meas_rsp *rsp = KE_MSG_ALLOC(RSCPS_NTF_RSC_MEAS_RSP, + prf_dst_task_get(&(rscps_env->prf_env), 0), + prf_src_task_get(&(rscps_env->prf_env), 0), + rscps_ntf_rsc_meas_rsp); + + rsp->status = GAP_ERR_NO_ERROR; + ke_msg_send(rsp); + + // free operation + ke_free(rscps_env->ntf); + rscps_env->ntf = NULL; + rscps_env->operation = RSCPS_RESERVED_OP_CODE; + + ke_state_set(prf_src_task_get(&(rscps_env->prf_env), 0), RSCPS_IDLE); + } +} + +void rscps_send_rsp_ind(uint8_t conidx, uint8_t req_op_code, uint8_t status) +{ + // Get the address of the environment + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ctl_pt_rsp = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), + prf_src_task_get(&rscps_env->prf_env, conidx), + gattc_send_evt_cmd, RSCP_SC_CNTL_PT_RSP_MIN_LEN); + + // Fill in the parameter structure + ctl_pt_rsp->operation = GATTC_INDICATE; + ctl_pt_rsp->handle = RSCPS_HANDLE(RSCS_IDX_SC_CTNL_PT_VAL); + // Pack Control Point confirmation + ctl_pt_rsp->length = RSCP_SC_CNTL_PT_RSP_MIN_LEN; + // Response Code + ctl_pt_rsp->value[0] = RSCP_CTNL_PT_RSP_CODE; + // Request Operation Code + ctl_pt_rsp->value[1] = req_op_code; + // Response value + ctl_pt_rsp->value[2] = status; + + // Send the event + ke_msg_send(ctl_pt_rsp); +} + +#endif //(BLE_RSC_SENSOR) + +/// @} RSCPS diff --git a/services/ble_profiles/rscp/rscps/src/rscps.h b/services/ble_profiles/rscp/rscps/src/rscps.h new file mode 100644 index 0000000..c3fc857 --- /dev/null +++ b/services/ble_profiles/rscp/rscps/src/rscps.h @@ -0,0 +1,247 @@ +#ifndef _RSCPS_H_ +#define _RSCPS_H_ + +/** + **************************************************************************************** + * @addtogroup RSCPS Running Speed and Cadence Profile Sensor + * @ingroup RSCP + * @brief Running Speed and Cadence Profile Sensor + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_RSC_SENSOR) +#include "rscp_common.h" + +#include "prf_types.h" +#include "prf.h" +#include "rscps_task.h" +#include "attm.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of Running Speed and Cadence Profile Sensor role task instances +#define RSCPS_IDX_MAX (1) + +/******************************************** + ******* RSCS Configuration Flag Masks ****** + ********************************************/ + +/// Mandatory Attributes (RSC Measurement + RSC Feature) +#define RSCPS_MANDATORY_MASK (0x003F) +/// Sensor Location Attributes +#define RSCPS_SENSOR_LOC_MASK (0x00C0) +/// SC Control Point Attributes +#define RSCPS_SC_CTNL_PT_MASK (0x0700) + +/* + * MACROS + **************************************************************************************** + */ + +#define RSCPS_IS_FEATURE_SUPPORTED(features, flag) ((features & flag) == flag) + +#define RSCPS_IS_PRESENT(features, flag) ((features & flag) == flag) + +#define RSCPS_ENABLE_NTFIND(conidx, ccc_flag) (rscps_env->prfl_ntf_ind_cfg[conidx] |= ccc_flag) + +#define RSCPS_DISABLE_NTFIND(conidx, ccc_flag) (rscps_env->prfl_ntf_ind_cfg[conidx] &= ~ccc_flag) + +#define RSCPS_IS_NTFIND_ENABLED(conidx, ccc_flag) ((rscps_env->prfl_ntf_ind_cfg[conidx] & ccc_flag) == ccc_flag) + +#define RSCPS_HANDLE(idx) \ + (rscps_env->shdl + (idx) - \ + ((!(RSCPS_IS_FEATURE_SUPPORTED(rscps_env->prf_cfg, RSCPS_SENSOR_LOC_MASK)) && \ + ((idx) > RSCS_IDX_SENSOR_LOC_CHAR))? (1) : (0))) + +// Get database attribute index + #define RSCPS_IDX(hdl) \ + ((hdl - rscps_env->shdl) + \ + ((!(RSCPS_IS_FEATURE_SUPPORTED(rscps_env->prf_cfg, RSCPS_SENSOR_LOC_MASK)) && \ + ((hdl - rscps_env->shdl) > RSCS_IDX_SENSOR_LOC_CHAR)) ? (1) : (0))) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// Possible states of the RSCPS task +enum rscps_state +{ + /// Idle state + RSCPS_IDLE, + /// Busy state + RSCPS_BUSY, + + /// Number of defined states. + RSCPS_STATE_MAX +}; + +/// Running Speed and Cadence Service - Attribute List +enum rscps_rscs_att_list +{ + /// Running Speed and Cadence Service + RSCS_IDX_SVC, + /// RSC Measurement + RSCS_IDX_RSC_MEAS_CHAR, + RSCS_IDX_RSC_MEAS_VAL, + RSCS_IDX_RSC_MEAS_NTF_CFG, + /// RSC Feature + RSCS_IDX_RSC_FEAT_CHAR, + RSCS_IDX_RSC_FEAT_VAL, + /// Sensor Location + RSCS_IDX_SENSOR_LOC_CHAR, + RSCS_IDX_SENSOR_LOC_VAL, + /// SC Control Point + RSCS_IDX_SC_CTNL_PT_CHAR, + RSCS_IDX_SC_CTNL_PT_VAL, + RSCS_IDX_SC_CTNL_PT_NTF_CFG, + + /// Number of attributes + RSCS_IDX_NB, +}; + +/// Profile Configuration Additional Flags () +enum rscps_prf_cfg_flag +{ + /// RSC Measurement - Client Char. Cfg + RSCP_PRF_CFG_FLAG_RSC_MEAS_NTF = (RSCP_FEAT_MULT_SENSOR_LOC_SUPP << 1), + /// SC Control Point - Client Char. Cfg + RSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND = (RSCP_PRF_CFG_FLAG_RSC_MEAS_NTF << 1), + + /// Bonded data configured + RSCP_PRF_CFG_PERFORMED_OK = 0x80 +}; + +/// Sensor Location Supported Flag +enum rscps_sensor_loc_supp +{ + /// Sensor Location Char. is not supported + RSCPS_SENSOR_LOC_NOT_SUPP, + /// Sensor Location Char. is supported + RSCPS_SENSOR_LOC_SUPP, +}; + + + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// ongoing notification information +struct rscps_ntf +{ + /// Cursor on connection + uint8_t cursor; + /// Packed notification/indication data size + uint8_t length; + /// Packed notification/indication data + uint8_t value[RSCP_RSC_MEAS_MAX_LEN]; +}; + +/// Running Power Profile Sensor environment variable per connection +struct rscps_cnx_env +{ + /// Profile Notify/Indication Flags + uint8_t prfl_ntf_ind_cfg; +}; + +/// Running Speed and Cadence Profile Sensor environment variable +struct rscps_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Notification data + struct rscps_ntf* ntf; + /// Cycling Speed and Cadence Service Start Handle + uint16_t shdl; + + /// Features configuration + uint16_t features; + /// profile configuration + uint16_t prf_cfg; + + /// Operation + uint8_t operation; + /// Sensor location + uint8_t sensor_loc; + + /// State of different task instances + ke_state_t state[RSCPS_IDX_MAX]; + /// Profile Notify/Indication Flags + uint8_t prfl_ntf_ind_cfg[BLE_CONNECTION_MAX]; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve RSCP service profile interface + * + * @return RSCP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* rscps_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send a RSCPS_CMP_EVT message to the application. + **************************************************************************************** + */ +void rscps_send_cmp_evt(uint8_t conidx, uint8_t src_id, uint8_t dest_id, uint8_t operation, uint8_t status); + +/** + **************************************************************************************** + * @brief This function fully manage event to trigg to peer(s) device(s) according + * to on-going operation requested by application + **************************************************************************************** + */ +void rscps_exe_operation(void); + +/** + **************************************************************************************** + * @brief This function sends control point indication error + **************************************************************************************** + */ +void rscps_send_rsp_ind(uint8_t conidx, uint8_t req_op_code, uint8_t status); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void rscps_task_init(struct ke_task_desc *task_desc); + + +#endif //(BLE_RSC_SENSOR) + +/// @} RSCPS + +#endif //(_RSCPS_H_) diff --git a/services/ble_profiles/rscp/rscps/src/rscps_task.c b/services/ble_profiles/rscp/rscps/src/rscps_task.c new file mode 100644 index 0000000..9e21dfc --- /dev/null +++ b/services/ble_profiles/rscp/rscps/src/rscps_task.c @@ -0,0 +1,825 @@ +/** + **************************************************************************************** + * @addtogroup RSCPSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_RSC_SENSOR) +#include "rscp_common.h" + +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "rscps.h" +#include "rscps_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref RSCPS_ENABLE_REQ message. + * @param[in] msgid Id of the message received + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int rscps_enable_req_handler(ke_msg_id_t const msgid, + struct rscps_enable_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if(ke_state_get(dest_id) == RSCPS_IDLE) + { + status = GAP_ERR_NO_ERROR; + + if (!RSCPS_IS_PRESENT(rscps_env->prfl_ntf_ind_cfg[param->conidx], RSCP_PRF_CFG_PERFORMED_OK)) + { + // Check the provided value + if (param->rsc_meas_ntf_cfg == PRF_CLI_START_NTF) + { + // Store the status + RSCPS_ENABLE_NTFIND(param->conidx, RSCP_PRF_CFG_FLAG_RSC_MEAS_NTF); + } + + if (RSCPS_IS_FEATURE_SUPPORTED(rscps_env->prf_cfg, RSCPS_SC_CTNL_PT_MASK)) + { + // Check the provided value + if (param->sc_ctnl_pt_ntf_cfg == PRF_CLI_START_IND) + { + // Store the status + RSCPS_ENABLE_NTFIND(param->conidx, RSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND); + } + } + // Enable Bonded Data + RSCPS_ENABLE_NTFIND(param->conidx, RSCP_PRF_CFG_PERFORMED_OK); + } + } + + // send completed information to APP task that contains error status + struct rscps_enable_rsp *cmp_evt = KE_MSG_ALLOC(RSCPS_ENABLE_RSP, src_id, dest_id, rscps_enable_rsp); + cmp_evt->status = status; + cmp_evt->conidx = param->conidx; + ke_msg_send(cmp_evt); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == RSCPS_IDLE) + { + // Get the address of the environment + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t att_idx = RSCPS_IDX(param->handle); + + // Send data to peer device + struct gattc_read_cfm* cfm = NULL; + + uint8_t status = ATT_ERR_NO_ERROR; + + switch(att_idx) + { + case RSCS_IDX_RSC_MEAS_NTF_CFG: + { + // Fill data + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->length = sizeof(uint16_t); + co_write16p(cfm->value, (rscps_env->prfl_ntf_ind_cfg[conidx] & RSCP_PRF_CFG_FLAG_RSC_MEAS_NTF) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND); + } break; + + case RSCS_IDX_RSC_FEAT_VAL: + { + // Fill data + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->length = sizeof(uint16_t); + co_write16p(cfm->value, rscps_env->features); + } break; + + case RSCS_IDX_SENSOR_LOC_VAL: + { + // Fill data + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint8_t)); + cfm->length = sizeof(uint8_t); + cfm->value[0] = rscps_env->sensor_loc; + } break; + + case RSCS_IDX_SC_CTNL_PT_NTF_CFG: + { + // Fill data + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(uint16_t)); + cfm->length = sizeof(uint16_t); + co_write16p(cfm->value, (rscps_env->prfl_ntf_ind_cfg[conidx] & RSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND) + ? PRF_CLI_START_IND : PRF_CLI_STOP_NTFIND); + } break; + + default: + { + cfm = KE_MSG_ALLOC(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm); + cfm->length = 0; + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } break; + } + + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + if(ke_state_get(dest_id) == RSCPS_IDLE) + { + // Get the address of the environment + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + uint8_t att_idx = RSCPS_IDX(param->handle); + struct gattc_att_info_cfm * cfm; + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + // check if it's a client configuration char + if((att_idx == RSCS_IDX_RSC_MEAS_NTF_CFG) + || (att_idx == RSCS_IDX_SC_CTNL_PT_NTF_CFG)) + { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } + else if (att_idx == RSCS_IDX_SC_CTNL_PT_VAL) + { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } + // not expected request + else + { + cfm->length = 0; + cfm->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + ke_msg_send(cfm); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref RSCPS_NTF_RSC_MEAS_REQ message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int rscps_ntf_rsc_meas_req_handler(ke_msg_id_t const msgid, + struct rscps_ntf_rsc_meas_req *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + // State shall be Connected or Busy + if (ke_state_get(dest_id) == RSCPS_IDLE) + { + // Get the address of the environment + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + // allocate and prepare data to notify + rscps_env->ntf = (struct rscps_ntf*) ke_malloc(sizeof(struct rscps_ntf), KE_MEM_KE_MSG); + + // Fill in the parameter structure + rscps_env->ntf->length = RSCP_RSC_MEAS_MIN_LEN; + + // Check the provided flags value + if (!RSCPS_IS_FEATURE_SUPPORTED(rscps_env->prf_cfg, RSCP_FEAT_INST_STRIDE_LEN_SUPP) && + RSCPS_IS_PRESENT(param->flags, RSCP_MEAS_INST_STRIDE_LEN_PRESENT)) + { + // Force Measurement Instantaneous Stride Length Present to No (Not supported) + param->flags &= ~RSCP_MEAS_INST_STRIDE_LEN_PRESENT; + } + + if (!RSCPS_IS_FEATURE_SUPPORTED(rscps_env->prf_cfg, RSCP_FEAT_TOTAL_DST_MEAS_SUPP) && + RSCPS_IS_PRESENT(param->flags, RSCP_MEAS_TOTAL_DST_MEAS_PRESENT)) + { + // Force Total Distance Measurement Present to No (Not supported) + param->flags &= ~RSCP_MEAS_TOTAL_DST_MEAS_PRESENT; + } + + // Force the unused bits of the flag value to 0 + rscps_env->ntf->value[0] = param->flags & RSCP_MEAS_ALL_PRESENT; + + // Instantaneous Speed + co_write16p(&rscps_env->ntf->value[1], param->inst_speed); + // Instantaneous Cadence + rscps_env->ntf->value[3] = param->inst_cad; + + // Instantaneous Stride Length + if (RSCPS_IS_PRESENT(param->flags, RSCP_MEAS_INST_STRIDE_LEN_PRESENT)) + { + co_write16p(&rscps_env->ntf->value[rscps_env->ntf->length], param->inst_stride_len); + rscps_env->ntf->length += 2; + } + + // Total Distance + if (RSCPS_IS_PRESENT(param->flags, RSCP_MEAS_TOTAL_DST_MEAS_PRESENT)) + { + co_write32p(&rscps_env->ntf->value[rscps_env->ntf->length], param->total_dist); + rscps_env->ntf->length += 4; + } + + // Configure the environment + rscps_env->operation = RSCPS_SEND_RSC_MEAS_OP_CODE; + rscps_env->ntf->cursor = 0; + + // Go to busy state + ke_state_set(dest_id, RSCPS_BUSY); + + // start operation execution + rscps_exe_operation(); + } + else + { + // Save it for later + msg_status = KE_MSG_SAVED; + } + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref RSCPS_SC_CTNL_PT_CFM message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int rscps_sc_ctnl_pt_cfm_handler(ke_msg_id_t const msgid, + struct rscps_sc_ctnl_pt_cfm *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + uint8_t conidx = KE_IDX_GET(src_id); + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if (ke_state_get(dest_id) == RSCPS_BUSY) + { + do + { + // check if op code valid + if((param->op_code < RSCPS_CTNL_PT_CUMUL_VAL_OP_CODE) + || (param->op_code > RSCPS_CTNL_ERR_IND_OP_CODE)) + { + //Wrong op code + status = PRF_ERR_INVALID_PARAM; + break; + } + + // Check the current operation + if ((rscps_env->operation < RSCPS_CTNL_PT_CUMUL_VAL_OP_CODE) || + (param->op_code != rscps_env->operation)) + { + // The confirmation has been sent without request indication, ignore + status = PRF_ERR_REQ_DISALLOWED; + break; + } + + // The SC Control Point Characteristic must be supported if we are here + if (RSCPS_IS_FEATURE_SUPPORTED(rscps_env->prf_cfg, RSCPS_SC_CTNL_PT_MASK)) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *ctl_pt_rsp = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, param->conidx), dest_id, + gattc_send_evt_cmd, RSCP_SC_CNTL_PT_RSP_MAX_LEN); + + // Fill in the parameter structure + ctl_pt_rsp->operation = GATTC_INDICATE; + ctl_pt_rsp->handle = RSCPS_HANDLE(RSCS_IDX_SC_CTNL_PT_VAL); + // Pack Control Point confirmation + ctl_pt_rsp->length = RSCP_SC_CNTL_PT_RSP_MIN_LEN; + + // Set the operation code (Response Code) + ctl_pt_rsp->value[0] = RSCP_CTNL_PT_RSP_CODE; + // Set the response value + ctl_pt_rsp->value[2] = (param->status > RSCP_CTNL_PT_RESP_FAILED) ? RSCP_CTNL_PT_RESP_FAILED : param->status; + + switch (rscps_env->operation) + { + // Set cumulative value + case (RSCPS_CTNL_PT_CUMUL_VAL_OP_CODE): + { + // Set the request operation code + ctl_pt_rsp->value[1] = RSCP_CTNL_PT_OP_SET_CUMUL_VAL; + status = GAP_ERR_NO_ERROR; + } break; + + // Start Sensor Calibration + case (RSCPS_CTNL_PT_START_CAL_OP_CODE): + { + // Set the request operation code + ctl_pt_rsp->value[1] = RSCP_CTNL_PT_OP_START_CALIB; + status = GAP_ERR_NO_ERROR; + } break; + + // Update Sensor Location + case (RSCPS_CTNL_PT_UPD_LOC_OP_CODE): + { + // Set the request operation code + ctl_pt_rsp->value[1] = RSCP_CTNL_PT_OP_UPD_LOC; + + if (param->status == RSCP_CTNL_PT_RESP_SUCCESS) + { + // The Sensor Location Characteristic is supported if we are here + if (RSCPS_IS_FEATURE_SUPPORTED(rscps_env->prf_cfg, RSCPS_SENSOR_LOC_MASK)) + { + // If operation is successful, update the value in the database + rscps_env->sensor_loc = param->value.sensor_loc; + status = GAP_ERR_NO_ERROR; + } + } + } break; + + case (RSCPS_CTNL_PT_SUPP_LOC_OP_CODE): + { + // Set the request operation code + ctl_pt_rsp->value[1] = RSCP_CTNL_PT_OP_REQ_SUPP_LOC; + + if (param->status == RSCP_CTNL_PT_RESP_SUCCESS) + { + // Counter + uint8_t counter; + + // Set the list of supported location + for (counter = 0; counter < RSCP_LOC_MAX; counter++) + { + if (((param->value.supp_sensor_loc >> counter) & 0x0001) == 0x0001) + { + ctl_pt_rsp->value[ctl_pt_rsp->length] = counter; + ctl_pt_rsp->length++; + } + } + status = GAP_ERR_NO_ERROR; + } + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + + // Send the event + ke_msg_send(ctl_pt_rsp); + } + } while (0); + + if (status != GAP_ERR_NO_ERROR) + { + // Inform the application that a procedure has been completed + rscps_send_cmp_evt(conidx, + prf_src_task_get(&rscps_env->prf_env, conidx), + prf_dst_task_get(&rscps_env->prf_env, conidx), + rscps_env->operation, param->status); + } + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_WRITE_REQ_IND message. + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance. + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + uint8_t conidx = KE_IDX_GET(src_id); + // Message status + uint8_t msg_status = KE_MSG_CONSUMED; + + // Check if a connection exists + if (rscps_env != NULL) + { + // RSC Measurement Characteristic, Client Characteristic Configuration Descriptor + if (param->handle == (RSCPS_HANDLE(RSCS_IDX_RSC_MEAS_NTF_CFG))) + { + uint16_t ntf_cfg; + // Status + uint8_t status = PRF_ERR_INVALID_PARAM; + + // Get the value + co_write16p(&ntf_cfg, param->value[0]); + + // Check if the value is correct + if (ntf_cfg <= PRF_CLI_START_NTF) + { + status = GAP_ERR_NO_ERROR; + + // Save the new configuration in the environment + if (ntf_cfg == PRF_CLI_STOP_NTFIND) + { + RSCPS_DISABLE_NTFIND(conidx, RSCP_PRF_CFG_FLAG_RSC_MEAS_NTF); + } + else // ntf_cfg == PRF_CLI_START_NTF + { + RSCPS_ENABLE_NTFIND(conidx, RSCP_PRF_CFG_FLAG_RSC_MEAS_NTF); + } + + // Inform the HL about the new configuration + struct rscps_cfg_ntfind_ind *ind = KE_MSG_ALLOC(RSCPS_CFG_NTFIND_IND, + prf_dst_task_get(&rscps_env->prf_env, conidx), + prf_src_task_get(&rscps_env->prf_env, conidx), + rscps_cfg_ntfind_ind); + + ind->char_code = RSCP_RSCS_RSC_MEAS_CHAR; + ind->ntf_cfg = ntf_cfg; + + ke_msg_send(ind); + + // Enable Bonded Data + RSCPS_ENABLE_NTFIND(conidx, RSCP_PRF_CFG_PERFORMED_OK); + } + // else status is RSCP_ERROR_CCC_INVALID_PARAM + + // Send the write response to the peer device + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + } + else // Should be the SC Control Point Characteristic + { + if (RSCPS_IS_FEATURE_SUPPORTED(rscps_env->prf_cfg, RSCPS_SC_CTNL_PT_MASK)) + { + // SC Control Point, Client Characteristic Configuration Descriptor + if (param->handle == (RSCPS_HANDLE(RSCS_IDX_SC_CTNL_PT_NTF_CFG))) + { + uint16_t ntf_cfg; + // Status + uint8_t status = PRF_ERR_INVALID_PARAM; + + // Get the value + co_write16p(&ntf_cfg, param->value[0]); + + // Check if the value is correct + if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_IND)) + { + status = GAP_ERR_NO_ERROR; + + // Save the new configuration in the environment + if (ntf_cfg == PRF_CLI_STOP_NTFIND) + { + RSCPS_DISABLE_NTFIND(conidx, RSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND); + } + else // ntf_cfg == PRF_CLI_START_IND + { + RSCPS_ENABLE_NTFIND(conidx, RSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND); + } + + // Inform the HL about the new configuration + struct rscps_cfg_ntfind_ind *ind = KE_MSG_ALLOC(RSCPS_CFG_NTFIND_IND, + prf_dst_task_get(&rscps_env->prf_env, conidx), + prf_src_task_get(&rscps_env->prf_env, conidx), + rscps_cfg_ntfind_ind); + + ind->char_code = RSCP_RSCS_SC_CTNL_PT_CHAR; + ind->ntf_cfg = ntf_cfg; + + ke_msg_send(ind); + + // Enable Bonded Data + RSCPS_ENABLE_NTFIND(conidx, RSCP_PRF_CFG_PERFORMED_OK); + } + // else status is RSCP_ERROR_CCC_INVALID_PARAM + + // Send the write response to the peer device + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + } + // SC Control Point Characteristic + else if (param->handle == (RSCPS_HANDLE(RSCS_IDX_SC_CTNL_PT_VAL))) + { + // Write Response Status + uint8_t wr_status = ATT_ERR_NO_ERROR; + // Indication Status + uint8_t ind_status = RSCP_CTNL_PT_RESP_NOT_SUPP; + + do + { + // Check if sending of indications has been enabled + if (!RSCPS_IS_NTFIND_ENABLED(conidx, RSCP_PRF_CFG_FLAG_SC_CTNL_PT_IND)) + { + // CCC improperly configured + wr_status = RSCP_ERROR_CCC_INVALID_PARAM; + ind_status = RSCP_CTNL_PT_RESP_FAILED; + break; + } + + if ((rscps_env->operation >= RSCPS_CTNL_PT_CUMUL_VAL_OP_CODE) && + (rscps_env->operation <= RSCPS_CTNL_ERR_IND_OP_CODE)) + { + // A procedure is already in progress + wr_status = RSCP_ERROR_PROC_IN_PROGRESS; + ind_status = RSCP_CTNL_PT_RESP_FAILED; + break; + } + + if (rscps_env->operation == RSCPS_SEND_RSC_MEAS_OP_CODE) + { + // Keep the message until the end of the current procedure + msg_status = KE_MSG_SAVED; + break; + } + + // Allocate a request indication message for the application + struct rscps_sc_ctnl_pt_req_ind *req_ind = KE_MSG_ALLOC(RSCPS_SC_CTNL_PT_REQ_IND, + prf_dst_task_get(&rscps_env->prf_env, conidx), + prf_src_task_get(&rscps_env->prf_env, conidx), + rscps_sc_ctnl_pt_req_ind); + + // Operation Code + req_ind->op_code = param->value[0]; + // Connection index + req_ind->conidx = conidx; + + // Operation Code + switch(param->value[0]) + { + // Set Cumulative value + case (RSCP_CTNL_PT_OP_SET_CUMUL_VAL): + { + // Check if the Total Distance Measurement feature is supported + if (RSCPS_IS_FEATURE_SUPPORTED(rscps_env->features, RSCP_FEAT_TOTAL_DST_MEAS_SUPP)) + { + // The request can be handled + ind_status = RSCP_CTNL_PT_RESP_SUCCESS; + rscps_env->operation = RSCPS_CTNL_PT_CUMUL_VAL_OP_CODE; + + // Cumulative value + req_ind->value.cumul_value = co_read32p(¶m->value[1]); + } + } break; + + // Start Sensor calibration + case (RSCP_CTNL_PT_OP_START_CALIB): + { + // Check if the Calibration Procedure feature is supported + if (RSCPS_IS_FEATURE_SUPPORTED(rscps_env->features, RSCP_FEAT_CALIB_PROC_SUPP)) + { + // The request can be handled + ind_status = RSCP_CTNL_PT_RESP_SUCCESS; + + rscps_env->operation = RSCPS_CTNL_PT_START_CAL_OP_CODE; + } + } break; + + // Update sensor location + case (RSCP_CTNL_PT_OP_UPD_LOC): + { + // Check if the Multiple Sensor Location feature is supported + if (RSCPS_IS_FEATURE_SUPPORTED(rscps_env->features, RSCP_FEAT_MULT_SENSOR_LOC_SUPP)) + { + // Check the sensor location value + if (param->value[1] < RSCP_LOC_MAX) + { + // The request can be handled + ind_status = RSCP_CTNL_PT_RESP_SUCCESS; + + rscps_env->operation = RSCPS_CTNL_PT_UPD_LOC_OP_CODE; + + // Sensor Location + req_ind->value.sensor_loc = param->value[1]; + } + else + { + // Provided parameter in not within the defined range + ind_status = RSCP_CTNL_PT_RESP_INV_PARAM; + } + } + } break; + + // Request supported sensor locations + case (RSCP_CTNL_PT_OP_REQ_SUPP_LOC): + { + // Check if the Multiple Sensor Location feature is supported + if (RSCPS_IS_FEATURE_SUPPORTED(rscps_env->features, RSCP_FEAT_MULT_SENSOR_LOC_SUPP)) + { + // The request can be handled + ind_status = RSCP_CTNL_PT_RESP_SUCCESS; + + rscps_env->operation = RSCPS_CTNL_PT_SUPP_LOC_OP_CODE; + } + } break; + + default: + { + // Operation Code is invalid, status is already RSCP_CTNL_PT_RESP_NOT_SUPP + } break; + } + + // If no error raised, inform the application about the request + if (ind_status == RSCP_CTNL_PT_RESP_SUCCESS) + { + // Send the request indication to the application + ke_msg_send(req_ind); + // Go to the Busy status + ke_state_set(dest_id, RSCPS_BUSY); + // Align error code + wr_status = GAP_ERR_NO_ERROR; + } + else + { + // Free the allocated message + ke_msg_free(ke_param2msg(req_ind)); + } + } while (0); + + // Send the write response to the peer device + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = wr_status; + ke_msg_send(cfm); + + // If error raised in control point, inform the peer + if ((ind_status != RSCP_CTNL_PT_RESP_SUCCESS) && + (param->handle == (RSCPS_HANDLE(RSCS_IDX_SC_CTNL_PT_VAL)))) + { + rscps_send_rsp_ind(conidx, param->value[0], ind_status); + } + } + else + { + ASSERT_ERR(0); + } + } + } + } + // else drop the message + + return (int)msg_status; +} + +/** + **************************************************************************************** + * @brief Handles @ref GATT_NOTIFY_CMP_EVT message meaning that a notification or an indication + * has been correctly sent to peer device (but not confirmed by peer device). + * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + uint8_t conidx = KE_IDX_GET(src_id); + // Get the address of the environment + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + + // Check if a connection exists + if (ke_state_get(dest_id) == RSCPS_BUSY) + { + switch (param->operation) + { + case (GATTC_NOTIFY): + { + ASSERT_ERR(rscps_env->operation == RSCPS_SEND_RSC_MEAS_OP_CODE); + // continuer operation execution + rscps_exe_operation(); + } break; + + case (GATTC_INDICATE): + { + ASSERT_ERR((rscps_env->operation >= RSCPS_CTNL_PT_CUMUL_VAL_OP_CODE) || + (rscps_env->operation != RSCPS_CTNL_ERR_IND_OP_CODE)); + + // Inform the application that a procedure has been completed + rscps_send_cmp_evt(conidx, + prf_src_task_get(&rscps_env->prf_env, conidx), + prf_dst_task_get(&rscps_env->prf_env, conidx), + rscps_env->operation, param->status); + } break; + + default: + { + ASSERT_ERR(0); + } break; + } + } + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Specifies the default message handlers +KE_MSG_HANDLER_TAB(rscps) +{ + {RSCPS_ENABLE_REQ, (ke_msg_func_t) rscps_enable_req_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler}, + {RSCPS_NTF_RSC_MEAS_REQ, (ke_msg_func_t) rscps_ntf_rsc_meas_req_handler}, + {RSCPS_SC_CTNL_PT_CFM, (ke_msg_func_t) rscps_sc_ctnl_pt_cfm_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, +}; + +void rscps_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct rscps_env_tag *rscps_env = PRF_ENV_GET(RSCPS, rscps); + + task_desc->msg_handler_tab = rscps_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(rscps_msg_handler_tab); + task_desc->state = rscps_env->state; + task_desc->idx_max = RSCPS_IDX_MAX; +} + +#endif //(BLE_RSC_SENSOR) + +/// @} RSCPSTASK diff --git a/services/ble_profiles/tip/tip_common.h b/services/ble_profiles/tip/tip_common.h new file mode 100644 index 0000000..f28a8c0 --- /dev/null +++ b/services/ble_profiles/tip/tip_common.h @@ -0,0 +1,231 @@ +#ifndef _TIP_COMMON_H_ +#define _TIP_COMMON_H_ + +/** + **************************************************************************************** + * @addtogroup TIP Time Profile + * @ingroup PROFILE + * @brief Time Profile + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "prf_types.h" +#include + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +///Adjust Reason Flags field bit values +enum +{ + TIPS_FLAG_MAN_TIME_UPDATE = 0x01, + TIPS_FLAG_EXT_TIME_UPDATE = 0x02, + TIPS_FLAG_CHG_TIME_ZONE = 0x04, + TIPS_FLAG_DST_CHANGE = 0x08, +}; + +///Time Update Control Point Key values +enum +{ + TIPS_TIME_UPD_CTNL_PT_GET = 0x01, + TIPS_TIME_UPD_CTNL_PT_CANCEL, +}; + +///Time Update State Current State Key Values +enum +{ + TIPS_TIME_UPD_STATE_IDLE = 0x00, + TIPS_TIME_UPD_STATE_PENDING, +}; + +///Time Update State Result Key Values +enum +{ + TIPS_TIME_UPD_RESULT_SUCCESS = 0x00, + TIPS_TIME_UPD_RESULT_CANCELED, + TIPS_TIME_UPD_RESULT_NO_CONN, + TIPS_TIME_UPD_RESULT_ERROR_RSP, + TIPS_TIME_UPD_RESULT_TIMEOUT, + TIPS_TIME_UPD_NOT_ATTEMPTED, +}; + +///Time Profile Supported Features bit flags +enum +{ + ///NDCS bit + ///NDCS supported + TIPS_NDCS_SUPPORTED = 0x01, + + ///RTUS bit + ///RTUS supported + TIPS_RTUS_SUPPORTED = 0x02, +}; + +enum +{ + TIP_RD_RSP = 0x00, + TIP_NTF = 0x01, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/* + * STRUCTURES + **************************************************************************************** + */ + +/** + * Each of the following structure is related to a characteristic. + */ + +/* + * Current Time Service + */ + +///Current Time Characteristic Structure +struct tip_curr_time +{ + /// Date time + struct prf_date_time date_time; + /// Day of the week + uint8_t day_of_week; + /// 1/256th of a second + uint8_t fraction_256; + /// Adjust reason + uint8_t adjust_reason; +}; + +/** + * + * Time Zone Characteristic - UUID:0x2A0E + * Min value : -48 (UTC-12:00), Max value : 56 (UTC+14:00) + * -128 : Time zone offset is not known + */ +typedef int8_t tip_time_zone; + +/** + * DST Offset Characteristic - UUID:0x2A2D + * Min value : 0, Max value : 8 + * 255 = DST is not known + */ +typedef uint8_t tip_dst_offset; + +///Local Time Info Characteristic Structure - UUID:0x2A0F +struct tip_loc_time_info +{ + tip_time_zone time_zone; + tip_dst_offset dst_offset; +}; + +/** + * Time Source Characteristic - UUID:0x2A13 + * Min value : 0, Max value : 6 + * 0 = Unknown + * 1 = Network Time Protocol + * 2 = GPS + * 3 = Radio Time Signal + * 4 = Manual + * 5 = Atomic Clock + * 6 = Cellular Network + */ +typedef uint8_t tip_time_source; + +/** + * Time Accuracy Characteristic - UUID:0x2A12 + * Accuracy (drift) of time information in steps of 1/8 of a second (125ms) compared + * to a reference time source. Valid range from 0 to 253 (0s to 31.5s). A value of + * 254 means Accuracy is out of range (> 31.5s). A value of 255 means Accuracy is + * unknown. + */ +typedef uint8_t tip_time_accuracy; + +///Reference Time Info Characteristic Structure - UUID:0x2A14 +struct tip_ref_time_info +{ + tip_time_source time_source; + tip_time_accuracy time_accuracy; + /** + * Days since last update about Reference Source + * Min value : 0, Max value : 254 + * 255 = 255 or more days + */ + uint8_t days_update; + /** + * Hours since update about Reference Source + * Min value : 0, Mac value : 23 + * 255 = 255 or more days (If Days Since Update = 255, then Hours Since Update shall + * also be set to 255) + */ + uint8_t hours_update; +}; + +/* + * Next DST Change Service + */ +///Time With DST Characteristic Structure - UUID:0x2A11 +struct tip_time_with_dst +{ + ///Date and Time of the Next DST Change + struct prf_date_time date_time; + ///DST Offset that will be in effect after this change + tip_dst_offset dst_offset; +}; + +/* + * Reference Time Update Service + */ +/** + * Time Update Control Point Characteristic - UUID:0x2A16 + * The Time Update Control Point Characteristic enables a client to issue a command + * request to update the time in the time server. + * 0x01 = Get Reference Update = Forces the state machine to Update Pending and + * starts the time update procedure + * 0x02 = Cancel Reference Update = Forces the state machine to idle and stops the + * attempt to receive a time update. + */ +typedef uint8_t tip_time_upd_contr_pt; + +///Time Update State Characteristic Structure - UUID:0x2A17 +struct tip_time_upd_state +{ + /** + * The Time Update Status Characteristic exposes the status of the time update + * process and the result of the last update in the server. + */ + + /** + * Current State + * Min value : 0, Max value = 1 + * 0 = Idle + * 1 = Update Pending + */ + uint8_t current_state; + /** + * Result + * Min value : 0, Max Value : 5 + * 0 = Successful + * 1 = Canceled + * 2 = No Connection To Reference + * 3 = Reference responded with an error + * 4 = Timeout + * 5 = Update not attempted after reset + */ + uint8_t result; +}; + + +/// @} tip_common + +#endif /* _TIP_COMMON_H_ */ diff --git a/services/ble_profiles/tip/tipc/api/tipc_task.h b/services/ble_profiles/tip/tipc/api/tipc_task.h new file mode 100644 index 0000000..e964fe0 --- /dev/null +++ b/services/ble_profiles/tip/tipc/api/tipc_task.h @@ -0,0 +1,257 @@ +#ifndef _TIPC_TASK_H_ +#define _TIPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup TIPCTASK Time Profile Client Task + * @ingroup TIPC + * @brief Time Profile Client Task + * + * The TIPCTASK is responsible for handling the messages coming in and out of the + * @ref TIPC monitor block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "tip_common.h" +#include "rwip_task.h" // Task definitions + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +enum +{ + /// Start the time profile - at connection + TIPC_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_TIPC), + ///Confirm that cfg connection has finished with discovery results, or that normal cnx started + TIPC_ENABLE_RSP, + + /// Generic message to read a CTS, NDCS or RTUS characteristic value + TIPC_RD_CHAR_REQ, + /// Received read value + TIPC_RD_CHAR_RSP, + + ///Generic message for configuring the Current Time Characteristic on the Server + TIPC_CT_NTF_CFG_REQ, + ///Current Time Characteristic configuration response + TIPC_CT_NTF_CFG_RSP, + + /// Generic message for writing the Time Update Control Point Characteristic Value on a peer device + TIPC_WR_TIME_UPD_CTNL_PT_REQ, + ///Generic message for writing characteristic response status to APP + TIPC_WR_TIME_UPD_CTNL_PT_RSP, + + /// Received Current Time value (Notification) + TIPC_CT_IND, +}; + + + +/// Current Time Service Characteristics +enum +{ + /// Current Time + TIPC_CHAR_CTS_CURR_TIME, + /// Local Time Info + TIPC_CHAR_CTS_LOCAL_TIME_INFO, + /// Reference Time Info + TIPC_CHAR_CTS_REF_TIME_INFO, + + TIPC_CHAR_CTS_MAX, +}; + +/// Next DST Change Service Characteristics +enum +{ + /// Time With DST + TIPC_CHAR_NDCS_TIME_WITH_DST, + + TIPC_CHAR_NDCS_MAX, + TIPC_CHAR_NDCS_MASK = 0x10, +}; + +/// Reference Time Update Service Characteristics +enum +{ + /// Time Update Control Point + TIPC_CHAR_RTUS_TIME_UPD_CTNL_PT, + /// Time Update State + TIPC_CHAR_RTUS_TIME_UPD_STATE, + + TIPC_CHAR_RTUS_MAX, + TIPC_CHAR_RTUS_MASK = 0x20, +}; + +/// Current Time Service Characteristic Descriptors +enum +{ + /// Current Time client config + TIPC_DESC_CTS_CURR_TIME_CLI_CFG, + + TIPC_DESC_CTS_MAX, + TIPC_DESC_CTS_MASK = 0x30, +}; + +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Current Time Service + */ +struct tipc_cts_content +{ + /// service info + struct prf_svc svc; + + /// Characteristic info: + /// - Current Time + /// - Local Time Info + /// - Reference Time Info + struct prf_char_inf chars[TIPC_CHAR_CTS_MAX]; + + /// Descriptor handles: + /// - Current Time client cfg + struct prf_char_desc_inf descs[TIPC_DESC_CTS_MAX]; +}; + +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Next DST Change Service + */ +struct tipc_ndcs_content +{ + /// service info + struct prf_svc svc; + + /// characteristic info: + /// - Time With DST + struct prf_char_inf chars[TIPC_CHAR_NDCS_MAX]; +}; + +/** + * Structure containing the characteristics handles, value handles and descriptors for + * the Reference Time Update Service + */ +struct tipc_rtus_content +{ + /// service info + struct prf_svc svc; + + /// characteristic info: + /// - Time Update Control Point + /// - Time Update State + struct prf_char_inf chars[TIPC_CHAR_RTUS_MAX]; +}; + + +/// Parameters of the @ref TIPC_ENABLE_REQ message +struct tipc_enable_req +{ + ///Connection type + uint8_t con_type; + + ///Existing handle values cts + struct tipc_cts_content cts; + ///Existing handle values ndcs + struct tipc_ndcs_content ndcs; + ///Existing handle values rtus + struct tipc_rtus_content rtus; +}; + +/// Parameters of the @ref TIPC_ENABLE_RSP message +struct tipc_enable_rsp +{ + ///status + uint8_t status; + + ///Existing handle values cts + struct tipc_cts_content cts; + ///Existing handle values ndcs + struct tipc_ndcs_content ndcs; + ///Existing handle values rtus + struct tipc_rtus_content rtus; +}; + +///Parameters of the @ref TIPC_CT_NTF_CFG_REQ message +struct tipc_ct_ntf_cfg_req +{ + ///Stop/notify/indicate value to configure into the peer characteristic + uint16_t cfg_val; +}; + +///Parameters of the @ref TIPC_CT_NTF_CFG_RSP message +struct tipc_ct_ntf_cfg_rsp +{ + ///Status + uint8_t status; +}; + +///Parameters of the @ref TIPC_RD_CHAR_REQ message +struct tipc_rd_char_req +{ + ///Characteristic value code + uint8_t char_code; +}; + +///Parameters of the @ref TIPC_RD_CHAR_RSP message +struct tipc_rd_char_rsp +{ + /// Operation code + uint8_t op_code; + /// Status + uint8_t status; + + union tipc_rd_value_tag + { + ///Notification Configuration + uint16_t ntf_cfg; + ///Current Time + struct tip_curr_time curr_time; + ///Local Time Information + struct tip_loc_time_info loc_time_info; + ///Reference Time Information + struct tip_ref_time_info ref_time_info; + ///Time With DST + struct tip_time_with_dst time_with_dst; + ///Time Update State + struct tip_time_upd_state time_upd_state; + } value; +}; + +///Parameters of the @ref TIPC_WR_TIME_UPD_CTNL_PT_REQ message +struct tipc_wr_time_udp_ctnl_pt_req +{ + ///Value + uint8_t value; +}; + +///Parameters of the @ref TIPC_WR_TIME_UPD_CTNL_PT_RSP message +struct tipc_wr_time_upd_ctnl_pt_rsp +{ + ///Status + uint8_t status; +}; + +///Parameters of the @ref TIPC_CT_IND message +struct tipc_ct_ind +{ + ///Current Time Value + struct tip_curr_time ct_val; +}; + + +/// @} TIPCTASK + +#endif /* _TIPC_TASK_H_ */ diff --git a/services/ble_profiles/tip/tipc/src/tipc.c b/services/ble_profiles/tip/tipc/src/tipc.c new file mode 100644 index 0000000..ed8e61f --- /dev/null +++ b/services/ble_profiles/tip/tipc/src/tipc.c @@ -0,0 +1,210 @@ +/** + **************************************************************************************** + * @addtogroup TIPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_TIP_CLIENT) +#include "prf.h" +#include "tipc.h" +#include "tipc_task.h" +#include "gap.h" + +#include "ke_mem.h" + +/** + **************************************************************************************** + * @brief Initialization of the TIPC module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t tipc_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t idx; + //-------------------- allocate memory required for the profile --------------------- + + struct tipc_env_tag* tipc_env = + (struct tipc_env_tag* ) ke_malloc(sizeof(struct tipc_env_tag), KE_MEM_ATT_DB); + + // allocate TIPC required environment variable + env->env = (prf_env_t*) tipc_env; + + tipc_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + tipc_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_TIPC; + tipc_task_init(&(env->desc)); + + for(idx = 0; idx < TIPC_IDX_MAX ; idx++) + { + tipc_env->env[idx] = NULL; + // service is ready, go into an Idle state + ke_state_set(KE_BUILD_ID(env->task, idx), TIPC_FREE); + } + + return GAP_ERR_NO_ERROR; +} + +/** + **************************************************************************************** + * @brief Clean-up connection dedicated environment parameters + * This function performs cleanup of ongoing operations + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void tipc_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct tipc_env_tag* tipc_env = (struct tipc_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(tipc_env->env[conidx] != NULL) + { + ke_free(tipc_env->env[conidx]); + tipc_env->env[conidx] = NULL; + } + + /* Put TIP Client in Free state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), TIPC_FREE); +} + +/** + **************************************************************************************** + * @brief Destruction of the TIPC module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void tipc_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct tipc_env_tag* tipc_env = (struct tipc_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < TIPC_IDX_MAX ; idx++) + { + tipc_cleanup(env, idx, 0); + } + + // free profile environment variables + env->env = NULL; + ke_free(tipc_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void tipc_create(struct prf_task_env* env, uint8_t conidx) +{ + /* Put TIP Client in Idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), TIPC_IDLE); +} + +/// TIPC Task interface required by profile manager +const struct prf_task_cbs tipc_itf = +{ + tipc_init, + tipc_destroy, + tipc_create, + tipc_cleanup, +}; + +/* + * GLOBAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* tipc_prf_itf_get(void) +{ + return &tipc_itf; +} + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +void tipc_enable_rsp_send(struct tipc_env_tag *tipc_env, uint8_t conidx, uint8_t status) +{ + // Send to APP the details of the discovered attributes on TIPS + struct tipc_enable_rsp * rsp = KE_MSG_ALLOC(TIPC_ENABLE_RSP, + prf_dst_task_get(&(tipc_env->prf_env), conidx), + prf_src_task_get(&(tipc_env->prf_env), conidx), + tipc_enable_rsp); + + rsp->status = status; + + if (status == GAP_ERR_NO_ERROR) + { + rsp->cts = tipc_env->env[conidx]->cts; + rsp->ndcs = tipc_env->env[conidx]->ndcs; + rsp->rtus = tipc_env->env[conidx]->rtus; + + //register TIPC task in gatt for indication/notifications + prf_register_atthdl2gatt(&tipc_env->prf_env, conidx, &tipc_env->env[conidx]->cts.svc); + + // Go to connected state + ke_state_set(prf_src_task_get(&tipc_env->prf_env, conidx), TIPC_IDLE); + } + + ke_msg_send(rsp); +} + +void tipc_unpack_curr_time_value(struct tip_curr_time* p_curr_time_val, uint8_t* packed_ct) +{ + //Date-Time + prf_unpack_date_time(packed_ct, &(p_curr_time_val->date_time)); + + //Day of Week + p_curr_time_val->day_of_week = packed_ct[7]; + + //Fraction 256 + p_curr_time_val->fraction_256 = packed_ct[8]; + + //Adjust Reason + p_curr_time_val->adjust_reason = packed_ct[9]; +} + +void tipc_unpack_time_dst_value(struct tip_time_with_dst* p_time_dst_val, uint8_t* packed_tdst) +{ + //Date-Time + prf_unpack_date_time(packed_tdst, &(p_time_dst_val->date_time)); + + //DST Offset + p_time_dst_val->dst_offset = packed_tdst[7]; +} + +#endif /* (BLE_TIP_CLIENT) */ + +/// @} TIPC diff --git a/services/ble_profiles/tip/tipc/src/tipc.h b/services/ble_profiles/tip/tipc/src/tipc.h new file mode 100644 index 0000000..0d04856 --- /dev/null +++ b/services/ble_profiles/tip/tipc/src/tipc.h @@ -0,0 +1,157 @@ +#ifndef _TIPC_H_ +#define _TIPC_H_ + +/** + **************************************************************************************** + * @addtogroup TIPC Time Profile Client + * @ingroup TIP + * @brief Time Profile Client + * + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_TIP_CLIENT) +#include "tipc_task.h" +#include "ke_task.h" +#include "prf_types.h" +#include "prf_utils.h" + +/* + * DEFINES + **************************************************************************************** + */ + +///Maximum number of Time Client task instances +#define TIPC_IDX_MAX (BLE_CONNECTION_MAX) + +/// Possible states of the TIPC task +enum +{ + /// Free state + TIPC_FREE, + /// IDLE state + TIPC_IDLE, + /// Discovering Blood Pressure SVC and CHars + TIPC_DISCOVERING, + /// Busy state + TIPC_BUSY, + + /// Number of defined states. + TIPC_STATE_MAX +}; + +/// Internal codes for reading a CTS or NDCS or RTUS characteristic with one single request +enum +{ + ///Read CTS Current Time + TIPC_RD_CTS_CURR_TIME = TIPC_CHAR_CTS_CURR_TIME, + ///Read CTS Local Time Info + TIPC_RD_CTS_LOCAL_TIME_INFO = TIPC_CHAR_CTS_LOCAL_TIME_INFO, + ///Read CTS Reference Time Info + TIPC_RD_CTS_REF_TIME_INFO = TIPC_CHAR_CTS_REF_TIME_INFO, + + ///Read CTS Current Time Client Cfg. Desc + TIPC_RD_CTS_CURR_TIME_CLI_CFG = (TIPC_DESC_CTS_MASK | TIPC_DESC_CTS_CURR_TIME_CLI_CFG), + + ///Read NDCS Time With DST + TIPC_RD_NDCS_TIME_WITH_DST = (TIPC_CHAR_NDCS_MASK | TIPC_CHAR_NDCS_TIME_WITH_DST), + + ///Read RTUS Time Update State + TIPC_RD_RTUS_TIME_UPD_STATE = (TIPC_CHAR_RTUS_MASK | TIPC_CHAR_RTUS_TIME_UPD_STATE), +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +struct tipc_cnx_env +{ + /// Last requested UUID(to keep track of the two services and char) + uint16_t last_uuid_req; + ///Last service for which something was discovered + uint16_t last_svc_req; + /// Last characteristic code used in a read or a write request + uint16_t last_char_code; + /// Counter used to check service uniqueness + uint8_t nb_svc; + + ///Current Time Service Characteristics + struct tipc_cts_content cts; + ///Next DST Change Characteristics + struct tipc_ndcs_content ndcs; + ///Reference Time Update Characteristics + struct tipc_rtus_content rtus; +}; + + +/// Time Profile Client environment variable +struct tipc_env_tag +{ + /// profile environment + prf_env_t prf_env; + /// Environment variable pointer for each connections + struct tipc_cnx_env* env[TIPC_IDX_MAX]; + /// State of different task instances + ke_state_t state[TIPC_IDX_MAX]; +}; + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve TIP client profile interface + * @return TIP client profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* tipc_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Send Time ATT DB discovery results to TIPC host. + **************************************************************************************** + */ +void tipc_enable_rsp_send(struct tipc_env_tag *tipc_env, uint8_t conidx, uint8_t status); + +/** + **************************************************************************************** + * @brief Send error indication from profile to Host, with proprietary status codes. + * @param status Status code of error. + **************************************************************************************** + */ + +void tipc_unpack_curr_time_value(struct tip_curr_time* p_curr_time_val, uint8_t* packed_ct); +// +void tipc_unpack_time_dst_value(struct tip_time_with_dst* p_time_dst_val, uint8_t* packed_tdst); + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void tipc_task_init(struct ke_task_desc *task_desc); + +#endif /* (BLE_TIP_CLIENT) */ + +/// @} TIPC + +#endif /* _TIPC_H_ */ diff --git a/services/ble_profiles/tip/tipc/src/tipc_task.c b/services/ble_profiles/tip/tipc/src/tipc_task.c new file mode 100644 index 0000000..fc44e84 --- /dev/null +++ b/services/ble_profiles/tip/tipc/src/tipc_task.c @@ -0,0 +1,799 @@ +/** + **************************************************************************************** + * @addtogroup TIPCTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_TIP_CLIENT) +#include "co_utils.h" +#include "tipc_task.h" +#include "tipc.h" +#include "gap.h" +#include "attm.h" +#include "gattc_task.h" + +#include "ke_mem.h" +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + + +/* + * DEFINES + **************************************************************************************** + */ + +/// State machine used to retrieve Current Time service characteristics information +const struct prf_char_def tipc_cts_char[TIPC_CHAR_CTS_MAX] = +{ + /// Current Time + [TIPC_CHAR_CTS_CURR_TIME] = {ATT_CHAR_CT_TIME, + ATT_MANDATORY, + ATT_CHAR_PROP_RD|ATT_CHAR_PROP_NTF}, + /// Local Time Info + [TIPC_CHAR_CTS_LOCAL_TIME_INFO] = {ATT_CHAR_LOCAL_TIME_INFO, + ATT_OPTIONAL, + ATT_CHAR_PROP_RD}, + /// Reference Time Info + [TIPC_CHAR_CTS_REF_TIME_INFO] = {ATT_CHAR_REFERENCE_TIME_INFO, + ATT_OPTIONAL, + ATT_CHAR_PROP_RD}, +}; + +/// State machine used to retrieve Current Time service characteristic description information +const struct prf_char_desc_def tipc_cts_char_desc[TIPC_DESC_CTS_MAX] = +{ + /// Current Time client config + [TIPC_DESC_CTS_CURR_TIME_CLI_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, + ATT_MANDATORY, + TIPC_CHAR_CTS_CURR_TIME}, +}; + +/// State machine used to retrieve Next DST Change service characteristics information +const struct prf_char_def tipc_ndcs_char[TIPC_CHAR_NDCS_MAX] = +{ + /// Current Time + [TIPC_CHAR_NDCS_TIME_WITH_DST] = {ATT_CHAR_TIME_WITH_DST, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, +}; + +/// State machine used to retrieve Reference Time Update service characteristics information +const struct prf_char_def tipc_rtus_char[TIPC_CHAR_RTUS_MAX] = +{ + /// Time Update Control Point + [TIPC_CHAR_RTUS_TIME_UPD_CTNL_PT] = {ATT_CHAR_TIME_UPDATE_CNTL_POINT, + ATT_MANDATORY, + ATT_CHAR_PROP_WR_NO_RESP}, + /// Time Update State + [TIPC_CHAR_RTUS_TIME_UPD_STATE] = {ATT_CHAR_TIME_UPDATE_STATE, + ATT_MANDATORY, + ATT_CHAR_PROP_RD}, +}; + + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_SDP_SVC_IND_HANDLER message. + * The handler stores the found service details for service discovery. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_sdp_svc_ind_handler(ke_msg_id_t const msgid, + struct gattc_sdp_svc_ind const *ind, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + + if(state == TIPC_DISCOVERING) + { + uint8_t conidx = KE_IDX_GET(dest_id); + + struct tipc_env_tag *tipc_env = PRF_ENV_GET(TIPC, tipc); + + ASSERT_INFO(tipc_env != NULL, dest_id, src_id); + ASSERT_INFO(tipc_env->env[conidx] != NULL, dest_id, src_id); + + if(attm_uuid16_comp((unsigned char *)ind->uuid, ind->uuid_len, ATT_SVC_CURRENT_TIME)) + { + // Retrieve TIS characteristics and descriptors + prf_extract_svc_info(ind, TIPC_CHAR_CTS_MAX, &tipc_cts_char[0], &tipc_env->env[conidx]->cts.chars[0], + TIPC_DESC_CTS_MAX, &tipc_cts_char_desc[0], &tipc_env->env[conidx]->cts.descs[0]); + + //Even if we get multiple responses we only store 1 range + tipc_env->env[conidx]->cts.svc.shdl = ind->start_hdl; + tipc_env->env[conidx]->cts.svc.ehdl = ind->end_hdl; + } + + if(attm_uuid16_comp((unsigned char *)ind->uuid, ind->uuid_len, ATT_SVC_NEXT_DST_CHANGE)) + { + // Retrieve NDCS characteristics and descriptors + prf_extract_svc_info(ind, TIPC_CHAR_NDCS_MAX, &tipc_ndcs_char[0], &tipc_env->env[conidx]->ndcs.chars[0], + 0, NULL, NULL); + + //Even if we get multiple responses we only store 1 range + tipc_env->env[conidx]->ndcs.svc.shdl = ind->start_hdl; + tipc_env->env[conidx]->ndcs.svc.ehdl = ind->end_hdl; + } + + if(attm_uuid16_comp((unsigned char *)ind->uuid, ind->uuid_len, ATT_SVC_REF_TIME_UPDATE)) + { + // Retrieve RTUS characteristics and descriptors + prf_extract_svc_info(ind, TIPC_CHAR_RTUS_MAX, &tipc_rtus_char[0], &tipc_env->env[conidx]->rtus.chars[0], + 0, NULL, NULL); + + //Even if we get multiple responses we only store 1 range + tipc_env->env[conidx]->rtus.svc.shdl = ind->start_hdl; + tipc_env->env[conidx]->rtus.svc.ehdl = ind->end_hdl; + } + + // Increment number of services + tipc_env->env[conidx]->nb_svc++; + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref TIPC_ENABLE_REQ message. + * The handler enables the Time Profile Client Role. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int tipc_enable_req_handler(ke_msg_id_t const msgid, + struct tipc_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + // Get state + uint8_t state = ke_state_get(dest_id); + + // Time Service Client Role Task Environment + struct tipc_env_tag *tipc_env = PRF_ENV_GET(TIPC, tipc); + + ASSERT_INFO(tipc_env != NULL, dest_id, src_id); + if ((state == TIPC_IDLE) && (tipc_env->env[conidx] == NULL)) + { + // allocate environment variable for task instance + tipc_env->env[conidx] = (struct tipc_cnx_env*) ke_malloc(sizeof(struct tipc_cnx_env),KE_MEM_ATT_DB); + memset(tipc_env->env[conidx], 0, sizeof(struct tipc_cnx_env)); + + //config connection, start discovering + if(param->con_type == PRF_CON_DISCOVERY) + { + //start discovering CTS on peer + prf_disc_svc_send(&(tipc_env->prf_env), conidx, ATT_SVC_CURRENT_TIME); + + tipc_env->env[conidx]->last_uuid_req = ATT_SVC_CURRENT_TIME; + tipc_env->env[conidx]->last_svc_req = ATT_SVC_CURRENT_TIME; + + // Go to DISCOVERING state + ke_state_set(dest_id, TIPC_DISCOVERING); + } + //normal connection, get saved att details + else + { + tipc_env->env[conidx]->cts = param->cts; + tipc_env->env[conidx]->ndcs = param->ndcs; + tipc_env->env[conidx]->rtus = param->rtus; + + //send APP confirmation that can start normal connection + tipc_enable_rsp_send(tipc_env, conidx, GAP_ERR_NO_ERROR); + } + } + + else if(state != TIPC_FREE) + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // send an error if request fails + if(status != GAP_ERR_NO_ERROR) + { + tipc_enable_rsp_send(tipc_env, conidx, status); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref TIPC_RD_CHAR_REQ message. + * Check if the handle exists in profile(already discovered) and send request, otherwise + * error to APP. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int tipc_rd_char_req_handler(ke_msg_id_t const msgid, + struct tipc_rd_char_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + uint8_t state = ke_state_get(dest_id); + uint8_t status = GAP_ERR_NO_ERROR; + + // Get the address of the environment + struct tipc_env_tag *tipc_env = PRF_ENV_GET(TIPC, tipc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + + if((state == TIPC_IDLE) && (tipc_env->env[conidx] != NULL)) + { + // Service + struct prf_svc *svc = NULL; + // Attribute Handle + uint16_t search_hdl = ATT_INVALID_SEARCH_HANDLE; + + //Next DST Change Service Characteristic + if (((param->char_code & TIPC_CHAR_NDCS_MASK) == TIPC_CHAR_NDCS_MASK) && + ((param->char_code & ~TIPC_CHAR_NDCS_MASK) < TIPC_CHAR_NDCS_MAX)) + { + svc = &tipc_env->env[conidx]->ndcs.svc; + search_hdl = tipc_env->env[conidx]->ndcs. + chars[param->char_code & ~TIPC_CHAR_NDCS_MASK].val_hdl; + } + //Reference Time Update Service Characteristic + else if (((param->char_code & TIPC_CHAR_RTUS_MASK) == TIPC_CHAR_RTUS_MASK) && + ((param->char_code & ~TIPC_CHAR_RTUS_MASK) < TIPC_CHAR_RTUS_MAX)) + { + svc = &tipc_env->env[conidx]->rtus.svc; + search_hdl = tipc_env->env[conidx]->rtus. + chars[param->char_code & ~TIPC_CHAR_RTUS_MASK].val_hdl; + } + else + { + svc = &tipc_env->env[conidx]->cts.svc; + + //Current Time Characteristic Descriptor + if (((param->char_code & TIPC_DESC_CTS_MASK) == TIPC_DESC_CTS_MASK) && + ((param->char_code & ~TIPC_DESC_CTS_MASK) < TIPC_DESC_CTS_MAX)) + { + search_hdl = tipc_env->env[conidx]->cts. + descs[param->char_code & ~TIPC_DESC_CTS_MASK].desc_hdl; + } + //Current Time Service Characteristic + else if (param->char_code < TIPC_CHAR_CTS_MAX) + { + search_hdl = tipc_env->env[conidx]->cts. + chars[param->char_code].val_hdl; + } + } + + // Check if handle is viable + if ((search_hdl != ATT_INVALID_SEARCH_HANDLE) && (svc != NULL)) + { + // Save char code + tipc_env->env[conidx]->last_char_code = param->char_code; + // Send read request + prf_read_char_send(&(tipc_env->prf_env), conidx, svc->shdl, svc->ehdl, search_hdl); + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_REQ_DISALLOWED; + } + + if (status != GAP_ERR_NO_ERROR) + { + //send app error indication + struct tipc_rd_char_rsp *ind = KE_MSG_ALLOC( + TIPC_RD_CHAR_RSP, + prf_dst_task_get(&(tipc_env->prf_env), conidx), + prf_src_task_get(&(tipc_env->prf_env), conidx), + tipc_rd_char_rsp); + + // It will be an TIPC status code + ind->status = status; + ind->op_code = param->char_code; + + // send the message + ke_msg_send(ind); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref TIPC_CT_NTF_CFG_REQ message. + * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic. + * Will return an error code if that cfg char does not exist. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int tipc_ct_ntf_cfg_req_handler(ke_msg_id_t const msgid, + struct tipc_ct_ntf_cfg_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint16_t cfg_hdl = ATT_INVALID_SEARCH_HANDLE; + // Get the address of the environment + struct tipc_env_tag *tipc_env = PRF_ENV_GET(TIPC, tipc); + // Get connection index + uint8_t conidx = KE_IDX_GET(dest_id); + // Status + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if((tipc_env->env[conidx] != NULL) && (ke_state_get(dest_id) == TIPC_IDLE)) + { + //Only NTF + if((param->cfg_val == PRF_CLI_STOP_NTFIND)||(param->cfg_val == PRF_CLI_START_NTF)) + { + cfg_hdl = tipc_env->env[conidx]->cts.descs[TIPC_DESC_CTS_CURR_TIME_CLI_CFG].desc_hdl; + + //check if the handle value exists + if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE) + { + // Send GATT Write Request + prf_gatt_write_ntf_ind(&tipc_env->prf_env, conidx, cfg_hdl, param->cfg_val); + status = GAP_ERR_NO_ERROR; + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + + if (status != GAP_ERR_NO_ERROR) + { + struct tipc_ct_ntf_cfg_rsp *ind = KE_MSG_ALLOC( + TIPC_CT_NTF_CFG_RSP, + prf_dst_task_get(&(tipc_env->prf_env), conidx), + prf_src_task_get(&(tipc_env->prf_env), conidx), + tipc_ct_ntf_cfg_rsp); + + // It will be an TIPC status code + ind->status = status; + // send the message + ke_msg_send(ind); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref TIPC_WR_TIME_UPD_CTNL_PT_REQ message. + * Check if the handle exists in profile(already discovered) and send request, otherwise + * error to APP. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int tipc_wr_time_upd_ctnl_pt_req_handler(ke_msg_id_t const msgid, + struct tipc_wr_time_udp_ctnl_pt_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct tipc_env_tag *tipc_env = PRF_ENV_GET(TIPC, tipc); + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if((ke_state_get(dest_id) == TIPC_IDLE) && (tipc_env->env[conidx] != NULL)) + { + // Check provided parameters + if ((param->value == TIPS_TIME_UPD_CTNL_PT_GET) || + (param->value == TIPS_TIME_UPD_CTNL_PT_CANCEL)) + { + if (tipc_env->env[conidx]->cts.chars[TIPC_CHAR_RTUS_TIME_UPD_CTNL_PT].char_hdl != ATT_INVALID_SEARCH_HANDLE) + { + // Send GATT Write Request + prf_gatt_write(&tipc_env->prf_env, conidx, + tipc_env->env[conidx]->rtus.chars[TIPC_CHAR_RTUS_TIME_UPD_CTNL_PT].val_hdl, + (uint8_t *)¶m->value, sizeof(uint8_t), GATTC_WRITE_NO_RESPONSE); + + status = GAP_ERR_NO_ERROR; + } + else + { + status = PRF_ERR_INEXISTENT_HDL; + } + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + + if (status != GAP_ERR_NO_ERROR) + { + //send app error indication + struct tipc_wr_time_upd_ctnl_pt_rsp *ind = KE_MSG_ALLOC( + TIPC_WR_TIME_UPD_CTNL_PT_RSP, + prf_dst_task_get(&(tipc_env->prf_env), conidx), + prf_src_task_get(&(tipc_env->prf_env), conidx), + tipc_wr_time_upd_ctnl_pt_rsp); + + // It will be an TIPC status code + ind->status = status; + + // send the message + ke_msg_send(ind); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_CMP_EVT message. + * This generic event is received for different requests, so need to keep track. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, + struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint8_t state = ke_state_get(dest_id); + uint8_t conidx = KE_IDX_GET(dest_id); + uint8_t status = PRF_ERR_STOP_DISC_CHAR_MISSING; + bool finished = false; + + // Get the address of the environment + struct tipc_env_tag *tipc_env = PRF_ENV_GET(TIPC, tipc); + + if((state == TIPC_DISCOVERING) && (tipc_env->env[conidx] != NULL)) + { + if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| + (param->status == ATT_ERR_NO_ERROR)) + { + // check characteristic validity + if(tipc_env->env[conidx]->nb_svc <= 1) + { + switch(tipc_env->env[conidx]->last_svc_req) + { + case ATT_SVC_CURRENT_TIME: + { + // Check service (mandatory) + status = prf_check_svc_char_validity(TIPC_CHAR_CTS_MAX, + tipc_env->env[conidx]->cts.chars, + tipc_cts_char); + + // Check Descriptors (mandatory) + if(status == GAP_ERR_NO_ERROR) + { + status = prf_check_svc_char_desc_validity(TIPC_DESC_CTS_MAX, + tipc_env->env[conidx]->cts.descs, + tipc_cts_char_desc, + tipc_env->env[conidx]->cts.chars); + // Prepare to discovery next service + tipc_env->env[conidx]->last_svc_req = ATT_SVC_NEXT_DST_CHANGE; + } + }break; + + case ATT_SVC_NEXT_DST_CHANGE: + { + // Check service (if found) + if(tipc_env->env[conidx]->nb_svc) + { + status = prf_check_svc_char_validity(TIPC_CHAR_NDCS_MAX, + tipc_env->env[conidx]->ndcs.chars, + tipc_ndcs_char); + } + else + { + status = GAP_ERR_NO_ERROR; + } + // Prepare to discovery next service + tipc_env->env[conidx]->last_svc_req = ATT_SVC_REF_TIME_UPDATE; + }break; + + case ATT_SVC_REF_TIME_UPDATE: + { + // Check service (if found) + if(tipc_env->env[conidx]->nb_svc) + { + status = prf_check_svc_char_validity(TIPC_CHAR_RTUS_MAX, + tipc_env->env[conidx]->rtus.chars, + tipc_rtus_char); + } + else + { + status = GAP_ERR_NO_ERROR; + } + + if(status == GAP_ERR_NO_ERROR) + { + // send app the details about the discovered TIPS DB to save + tipc_enable_rsp_send(tipc_env, conidx, GAP_ERR_NO_ERROR); + // Discovery is finished + finished = true; + } + }break; + + default: + break; + } + } + // too many services + else + { + status = PRF_ERR_MULTIPLE_SVC; + } + + if(status == GAP_ERR_NO_ERROR) + { + // reset number of services + tipc_env->env[conidx]->nb_svc = 0; + + if (!finished) + { + //start discovering following service on peer + prf_disc_svc_send(&(tipc_env->prf_env), conidx, tipc_env->env[conidx]->last_svc_req); + } + } + else + { + // stop discovery procedure + tipc_enable_rsp_send(tipc_env, conidx, status); + } + } + } + else if(state == TIPC_IDLE) + { + switch(param->operation) + { + case GATTC_WRITE: + { + struct tipc_ct_ntf_cfg_rsp *wr_cfm = KE_MSG_ALLOC( + TIPC_CT_NTF_CFG_RSP, + prf_dst_task_get(&(tipc_env->prf_env), conidx), + prf_src_task_get(&(tipc_env->prf_env), conidx), + tipc_ct_ntf_cfg_rsp); + + //it will be a GATT status code + wr_cfm->status = param->status; + // send the message + ke_msg_send(wr_cfm); + } break; + + case GATTC_WRITE_NO_RESPONSE: + { + struct tipc_wr_time_upd_ctnl_pt_rsp *wr_cfm = KE_MSG_ALLOC( + TIPC_WR_TIME_UPD_CTNL_PT_RSP, + prf_dst_task_get(&(tipc_env->prf_env), conidx), + prf_src_task_get(&(tipc_env->prf_env), conidx), + tipc_wr_time_upd_ctnl_pt_rsp); + + //it will be a GATT status code + wr_cfm->status = param->status; + // send the message + ke_msg_send(wr_cfm); + } + break; + + case GATTC_READ: + { + // an error occurs while reading peer attribute, inform app + if(param->status != GAP_ERR_NO_ERROR) + { + struct tipc_rd_char_rsp *rd_cfm = KE_MSG_ALLOC( + TIPC_RD_CHAR_RSP, + prf_dst_task_get(&(tipc_env->prf_env), conidx), + prf_src_task_get(&(tipc_env->prf_env), conidx), + tipc_rd_char_rsp); + + //it will be a GATT status code + rd_cfm->status = param->status; + rd_cfm->op_code = tipc_env->env[conidx]->last_char_code; + // send the message + ke_msg_send(rd_cfm); + } + } + break; + + default: + break; + } + } + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_READ_IND message. + * Generic event received after every simple read command sent to peer server. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct tipc_env_tag *tipc_env = PRF_ENV_GET(TIPC, tipc); + uint8_t conidx = KE_IDX_GET(dest_id); + + //Build the message + struct tipc_rd_char_rsp * ind = KE_MSG_ALLOC( + TIPC_RD_CHAR_RSP, + prf_dst_task_get(&(tipc_env->prf_env), conidx), + dest_id, + tipc_rd_char_rsp); + + //Current Time Characteristic + if (tipc_env->env[conidx]->last_char_code == TIPC_RD_CTS_CURR_TIME) + { + ind->op_code = TIPC_RD_CTS_CURR_TIME; + // Unpack Current Time Value. + tipc_unpack_curr_time_value(&(ind->value.curr_time), (uint8_t *) param->value); + } + //Local Time Information Characteristic + else if (tipc_env->env[conidx]->last_char_code == TIPC_RD_CTS_LOCAL_TIME_INFO) + { + ind->op_code = TIPC_RD_CTS_LOCAL_TIME_INFO; + // Local Time Information Value + ind->value.loc_time_info.time_zone = param->value[0]; + ind->value.loc_time_info.dst_offset = param->value[1]; + } + //Reference Time Information Characteristic + else if (tipc_env->env[conidx]->last_char_code == TIPC_RD_CTS_REF_TIME_INFO) + { + ind->op_code = TIPC_RD_CTS_REF_TIME_INFO; + // Reference Time Information Value + ind->value.ref_time_info.time_source = param->value[0]; + ind->value.ref_time_info.time_accuracy = param->value[1]; + ind->value.ref_time_info.days_update = param->value[2]; + ind->value.ref_time_info.hours_update = param->value[3]; + } + //Time with DST Characteristic + else if (tipc_env->env[conidx]->last_char_code == TIPC_RD_NDCS_TIME_WITH_DST) + { + ind->op_code = TIPC_RD_NDCS_TIME_WITH_DST; + // Time with DST Value + tipc_unpack_time_dst_value(&ind->value.time_with_dst, (uint8_t *) param->value); + } + //Time Update State Characteristic + else if (tipc_env->env[conidx]->last_char_code == TIPC_RD_RTUS_TIME_UPD_STATE) + { + ind->op_code = TIPC_RD_RTUS_TIME_UPD_STATE; + // Reference Time Information Value + ind->value.time_upd_state.current_state = param->value[0]; + ind->value.time_upd_state.result = param->value[1]; + } + //Current Time Characteristic - Client Characteristic Configuration Descriptor + else if (tipc_env->env[conidx]->last_char_code == TIPC_RD_CTS_CURR_TIME_CLI_CFG) + { + ind->op_code = TIPC_RD_CTS_CURR_TIME_CLI_CFG; + // Notification Configuration + memcpy(&ind->value.ntf_cfg, ¶m->value[0], sizeof(uint16_t)); + } + + ke_msg_send(ind); + + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GATTC_EVENT_IND message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_event_ind_handler(ke_msg_id_t const msgid, + struct gattc_event_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct tipc_env_tag *tipc_env = PRF_ENV_GET(TIPC, tipc); + uint8_t conidx = KE_IDX_GET(dest_id); + + if(tipc_env->env[conidx] != NULL) + { + if(param->handle == tipc_env->env[conidx]->cts.chars[TIPC_CHAR_CTS_CURR_TIME].val_hdl) + { + //Build a TIPC_CT_IND message + struct tipc_ct_ind * ind = KE_MSG_ALLOC( + TIPC_CT_IND, + prf_dst_task_get(&(tipc_env->prf_env), conidx), + prf_src_task_get(&(tipc_env->prf_env), conidx), + tipc_ct_ind); + + // Unpack Current Time Value. + tipc_unpack_curr_time_value(&(ind->ct_val), (uint8_t*) param->value); + + ke_msg_send(ind); + } + } + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(tipc) +{ + {TIPC_ENABLE_REQ, (ke_msg_func_t)tipc_enable_req_handler}, + {GATTC_SDP_SVC_IND, (ke_msg_func_t)gattc_sdp_svc_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, + {TIPC_CT_NTF_CFG_REQ, (ke_msg_func_t)tipc_ct_ntf_cfg_req_handler}, + {GATTC_EVENT_IND, (ke_msg_func_t)gattc_event_ind_handler}, + {TIPC_RD_CHAR_REQ, (ke_msg_func_t)tipc_rd_char_req_handler}, + {GATTC_READ_IND, (ke_msg_func_t)gattc_read_ind_handler}, + {TIPC_WR_TIME_UPD_CTNL_PT_REQ, (ke_msg_func_t)tipc_wr_time_upd_ctnl_pt_req_handler}, +}; + +void tipc_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct tipc_env_tag *tipc_env = PRF_ENV_GET(TIPC, tipc); + + task_desc->msg_handler_tab = tipc_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(tipc_msg_handler_tab); + task_desc->state = tipc_env->state; + task_desc->idx_max = TIPC_IDX_MAX; +} + +#endif /* (BLE_TIP_CLIENT) */ +/// @} TIPCTASK diff --git a/services/ble_profiles/tip/tips/api/tips_task.h b/services/ble_profiles/tip/tips/api/tips_task.h new file mode 100644 index 0000000..2dfdd7c --- /dev/null +++ b/services/ble_profiles/tip/tips/api/tips_task.h @@ -0,0 +1,149 @@ +#ifndef TIPS_TASK_H_ +#define TIPS_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup TIPSTASK Task + * @ingroup TIPS + * @brief Time Profile Server Task + * + * The TIPSTASK is responsible for handling the messages coming in and out of the + * @ref TIPS reporter block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "tip_common.h" +#include "rwip_task.h" // Task definitions + +/* + * DEFINES + **************************************************************************************** + */ + + +/// Messages for Time Profile Server +enum +{ + ///Start the Time Profile Server Role - at connection + TIPS_ENABLE_REQ = TASK_FIRST_MSG(TASK_ID_TIPS), + ///Inform the application about the task creation result + TIPS_ENABLE_RSP, + + ///Update Current Time Request from APP + TIPS_UPD_CURR_TIME_REQ, + ///Update Current Time Response to APP + TIPS_UPD_CURR_TIME_RSP, + + ///Inform APP about a requested read + TIPS_RD_REQ_IND, + ///Read request Response + TIPS_RD_CFM, + + ///Inform APP about modification of Current Time Characteristic Client. Charact. Cfg + TIPS_CURRENT_TIME_CCC_IND, + ///Inform APP about modification of Time Update Control Point Characteristic Value + TIPS_TIME_UPD_CTNL_PT_IND, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Parameters of the @ref TIPS_ENABLE_REQ message +struct tips_enable_req +{ + ///Current Time notification configuration + uint16_t current_time_ntf_en; +}; + +/// Parameters of the @ref TIPS_ENABLE_RSP message +struct tips_enable_rsp +{ + ///Status + uint8_t status; +}; + +///Parameters of the @ref TIPS_UPD_CURR_TIME_REQ message +struct tips_upd_curr_time_req +{ + ///Current Time + struct tip_curr_time current_time; + /** + * Indicate if the new Current Time value can be sent if the current_time_ntf_en parameter is + * set to 1. + * (0 - Disable; 1- Enable) + * + * If the time of the Current Time Server is changed because of reference time update (adjust reason) + * then no notifications shall be sent to the Current Time Service Client within the 15 minutes from + * the last notification, unless one of both of the two statements below are true : + * - The new time information differs by more than 1min from the Current Time Server + * time previous to the update + * - The update was caused by the client (interacting with another service) + */ + uint8_t enable_ntf_send; +}; + +///Parameters of the @ref TIPS_UPD_CURR_TIME_RSP message +struct tips_upd_curr_time_rsp +{ + /// Status of the operation + uint8_t status; +}; + +///Parameters of the @ref TIPS_RD_REQ_IND message +struct tips_rd_req_ind +{ + /// Characteristic code + uint8_t char_code; +}; + +///Parameters of the @ref TIPS_RD_CFM message +struct tips_rd_cfm +{ + uint8_t op_code; + + union tips_rd_value_tag + { + ///Current Time + struct tip_curr_time curr_time; + ///Local Time Information + struct tip_loc_time_info loc_time_info; + ///Reference Time Information + struct tip_ref_time_info ref_time_info; + ///Time With DST + struct tip_time_with_dst time_with_dst; + ///Time Update State + struct tip_time_upd_state time_upd_state; + } value; +}; + +///Parameters of the @ref TIPS_CURRENT_TIME_CCC_IND message +struct tips_current_time_ccc_ind +{ + ///Configuration Value + uint16_t cfg_val; +}; + +///Parameters of the @ref TIPS_TIME_UPD_CTNL_PT_IND message +struct tips_time_upd_ctnl_pt_ind +{ + ///Time Update Control Point Value + tip_time_upd_contr_pt value; +}; + +///Parameters of the @ref TIPS_CREATE_DB_REQ message +struct tips_db_cfg +{ + ///Database configuration + uint8_t features; +}; + +/// @} TIPSTASK +#endif // TIPS_TASK_H_ diff --git a/services/ble_profiles/tip/tips/src/tips.c b/services/ble_profiles/tip/tips/src/tips.c new file mode 100644 index 0000000..97ccf2b --- /dev/null +++ b/services/ble_profiles/tip/tips/src/tips.c @@ -0,0 +1,333 @@ +/** + **************************************************************************************** + * @addtogroup TIPS + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_TIP_SERVER) +#include "attm.h" +#include "tips.h" +#include "tips_task.h" +#include "prf_utils.h" + +#include "ke_mem.h" + +/* + * CTS, NDCS, RTUS ATTRIBUTES + **************************************************************************************** + */ +/// Full CTS Database Description - Used to add attributes into the database +const struct attm_desc cts_att_db[CTS_IDX_NB] = +{ + // Current Time Service Declaration + [CTS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // Current Time Characteristic Declaration + [CTS_IDX_CURRENT_TIME_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Current Time Characteristic Value + [CTS_IDX_CURRENT_TIME_VAL] = {ATT_CHAR_CT_TIME, PERM(RD, ENABLE) | PERM(NTF, ENABLE), PERM(RI, ENABLE), CTS_CURRENT_TIME_VAL_LEN}, + // Current Time Characteristic - Client Char. Configuration Descriptor + [CTS_IDX_CURRENT_TIME_CFG] = {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + + // Local Time Information Characteristic Declaration + [CTS_IDX_LOCAL_TIME_INFO_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Local Time Information Characteristic Value + [CTS_IDX_LOCAL_TIME_INFO_VAL] = {ATT_CHAR_LOCAL_TIME_INFO, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(struct tip_loc_time_info)}, + + // Reference Time Information Characteristic Declaration + [CTS_IDX_REF_TIME_INFO_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Reference Time Info Characteristic Value + [CTS_IDX_REF_TIME_INFO_VAL] = {ATT_CHAR_REFERENCE_TIME_INFO, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(struct tip_ref_time_info)}, +}; + +/// Full NDCS Database Description - Used to add attributes into the database +const struct attm_desc ndcs_att_db[NDCS_IDX_NB] = +{ + // Next DST Change Service Declaration + [NDCS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // Time with DST Characteristic Declaration + [NDCS_IDX_TIME_DST_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Time With DST Characteristic Value + [NDCS_IDX_TIME_DST_VAL] = {ATT_CHAR_TIME_WITH_DST, PERM(RD, ENABLE), PERM(RI, ENABLE), NDCS_TIME_DST_VAL_LEN}, +}; + +/// Full RTUS Database Description - Used to add attributes into the database +const struct attm_desc rtus_att_db[RTUS_IDX_NB] = +{ + // Reference Time Information Service Declaration + [RTUS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0, 0}, + + // Time Update Control Point Characteristic Declaration + [RTUS_IDX_TIME_UPD_CTNL_PT_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Time Update Control Point Characteristic Value + [RTUS_IDX_TIME_UPD_CTNL_PT_VAL] = {ATT_CHAR_TIME_UPDATE_CNTL_POINT, PERM(WRITE_COMMAND, ENABLE), PERM(RI, ENABLE), sizeof(tip_time_upd_contr_pt)}, + + // Time Update State Characteristic Declaration + [RTUS_IDX_TIME_UPD_STATE_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), 0, 0}, + // Time Update State Characteristic Value + [RTUS_IDX_TIME_UPD_STATE_VAL] = {ATT_CHAR_TIME_UPDATE_STATE, PERM(RD, ENABLE), PERM(RI, ENABLE), sizeof(struct tip_time_upd_state)}, +}; + + +/** + **************************************************************************************** + * @brief Initialization of the TIPS module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t tips_init(struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, struct tips_db_cfg* params) +{ + // Service content flag + uint32_t cfg_flag= TIPS_CTS_CURRENT_TIME_MASK; + // DB Creation Status + uint8_t status = ATT_ERR_NO_ERROR; + // Total number of attributes + uint8_t tot_nb_att = CTS_IDX_NB; + + // Allocate TIPS required environment variable + struct tips_env_tag* tips_env = + (struct tips_env_tag* ) ke_malloc(sizeof(struct tips_env_tag), KE_MEM_ATT_DB); + + env->env = (prf_env_t*) tips_env; + + //------------------ create the attribute database for the profile ------------------- + + // Check supported attributes + if (params->features & TIPS_NDCS_SUP) + { + tot_nb_att += NDCS_IDX_NB; + } + + if (params->features & TIPS_NDCS_SUP) + { + tot_nb_att += RTUS_IDX_NB; + } + + // Check that attribute list can be allocated. + status = attm_reserve_handle_range(start_hdl, tot_nb_att); + + if (status == ATT_ERR_NO_ERROR) + { + //Set Configuration Flag Value + if (params->features & TIPS_CTS_LOC_TIME_INFO_SUP) + { + cfg_flag |= TIPS_CTS_LOC_TIME_INFO_MASK; + } + + if (params->features & TIPS_CTS_REF_TIME_INFO_SUP) + { + cfg_flag |= TIPS_CTS_REF_TIME_INFO_MASK; + } + + /*---------------------------------------------------* + * Current Time Service Creation + *---------------------------------------------------*/ + status = attm_svc_create_db(start_hdl, ATT_SVC_CURRENT_TIME, (uint8_t *)&cfg_flag, + CTS_IDX_NB, &tips_env->cts_att_tbl[0], env->task, &cts_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, ENABLE)); + + // Update index + tips_env->cts_shdl = *start_hdl; + *start_hdl += CTS_IDX_NB; + + //All attributes are mandatory for NDCS and RTUS + cfg_flag = 0xFF; + + if ((status == ATT_ERR_NO_ERROR) && ((params->features & TIPS_NDCS_SUP))) + { + /*---------------------------------------------------* + * Next DST Change Service Creation + *---------------------------------------------------*/ + status = attm_svc_create_db(start_hdl, ATT_SVC_NEXT_DST_CHANGE, (uint8_t *)&cfg_flag, + NDCS_IDX_NB, &tips_env->ndcs_att_tbl[0], env->task, &ndcs_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, ENABLE)); + + // Update index + tips_env->ndcs_shdl = *start_hdl; + *start_hdl += NDCS_IDX_NB; + } + + /*---------------------------------------------------* + * Reference Time Update Service Creation + *---------------------------------------------------*/ + if ((status == ATT_ERR_NO_ERROR) && ((params->features & TIPS_RTUS_SUP))) + { + status = attm_svc_create_db(start_hdl, ATT_SVC_REF_TIME_UPDATE, (uint8_t *)&cfg_flag, + RTUS_IDX_NB, &tips_env->rtus_att_tbl[0], env->task, &rtus_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS)) | PERM(SVC_MI, ENABLE)); + + // Update index + tips_env->rtus_shdl = *start_hdl; + *start_hdl += RTUS_IDX_NB; + } + + // Initialize TIPS environment + tips_env->features = params->features; + + tips_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Multi Instantiated task + tips_env->prf_env.prf_task = env->task | PERM(PRF_MI, ENABLE); + + // initialize environment variable + env->id = TASK_ID_TIPS; + tips_task_init(&(env->desc)); + + for(uint8_t idx = 0; idx < BLE_CONNECTION_MAX ; idx++) + { + tips_env->env[idx] = NULL; + } + + /* Put TIS in disabled state */ + ke_state_set(env->task, TIPS_IDLE); + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the TIPS module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void tips_destroy(struct prf_task_env* env) +{ + uint8_t idx; + struct tips_env_tag* tips_env = (struct tips_env_tag*) env->env; + + // cleanup environment variable for each task instances + for(idx = 0; idx < BLE_CONNECTION_MAX ; idx++) + { + if(tips_env->env[idx] != NULL) + { + ke_free(tips_env->env[idx]); + } + } + + // free profile environment variables + env->env = NULL; + ke_free(tips_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void tips_create(struct prf_task_env* env, uint8_t conidx) +{ + struct tips_env_tag* tips_env = (struct tips_env_tag*) env->env; + tips_env->env[conidx] = (struct tips_cnx_env*) + ke_malloc(sizeof(struct tips_cnx_env), KE_MEM_ATT_DB); + + memset(tips_env->env[conidx], 0, sizeof(struct tips_cnx_env)); + + /* Put TIS in idle state */ + ke_state_set(KE_BUILD_ID(env->task, conidx), TIPS_IDLE); +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void tips_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + struct tips_env_tag* tips_env = (struct tips_env_tag*) env->env; + + // clean-up environment variable allocated for task instance + if(tips_env->env[conidx] != NULL) + { + ke_free(tips_env->env[conidx]); + tips_env->env[conidx] = NULL; + } +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// TIPS Task interface required by profile manager +const struct prf_task_cbs tips_itf = +{ + (prf_init_fnct) tips_init, + tips_destroy, + tips_create, + tips_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* tips_prf_itf_get(void) +{ + return &tips_itf; +} + +uint8_t tips_pack_curr_time_value(uint8_t *p_pckd_time, const struct tip_curr_time* p_curr_time_val) +{ + // Date-Time + prf_pack_date_time(p_pckd_time, &(p_curr_time_val->date_time)); + + //Day of Week + *(p_pckd_time + 7) = p_curr_time_val->day_of_week; + + //Fraction 256 + *(p_pckd_time + 8) = p_curr_time_val->fraction_256; + + //Adjust Reason + *(p_pckd_time + 9) = p_curr_time_val->adjust_reason; + + return 10; +} + +uint8_t tips_pack_time_dst_value(uint8_t *p_pckd_time_dst, const struct tip_time_with_dst* p_time_dst_val) +{ + // Date-Time + prf_pack_date_time(p_pckd_time_dst, &(p_time_dst_val->date_time)); + + // DST Offset + *(p_pckd_time_dst + 7) = p_time_dst_val->dst_offset; + + return 8; +} + +#endif //BLE_TIP_SERVER + +/// @} TIPS diff --git a/services/ble_profiles/tip/tips/src/tips.h b/services/ble_profiles/tip/tips/src/tips.h new file mode 100644 index 0000000..941cae2 --- /dev/null +++ b/services/ble_profiles/tip/tips/src/tips.h @@ -0,0 +1,257 @@ +#ifndef TIPS_H_ +#define TIPS_H_ + +/** + **************************************************************************************** + * @addtogroup TIPS Time Profile Server + * @ingroup TIP + * @brief Time Profile Server + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_TIP_SERVER) +#include +#include + +#include "tip_common.h" +#include "prf_types.h" +#include "gap.h" +#include "prf.h" + +/* + * DEFINES + **************************************************************************************** + */ +//Maximum number of Time Server task instances +#define TIPS_IDX_MAX (BLE_CONNECTION_MAX) + +//CTS Configuration Flag Masks +#define TIPS_CTS_CURRENT_TIME_MASK (0x0F) +#define TIPS_CTS_LOC_TIME_INFO_MASK (0x30) +#define TIPS_CTS_REF_TIME_INFO_MASK (0xC0) + +//Packed Values Length +#define CTS_CURRENT_TIME_VAL_LEN (10) +#define NDCS_TIME_DST_VAL_LEN (8) + +/* + * MACROS + **************************************************************************************** + */ + +#define TIPS_IS_SUPPORTED(mask) (((tips_env->features & mask) == mask)) + +/* + * ENUMERATIONS + **************************************************************************************** + */ +/// Possible states of the TIPS task +enum +{ + /// idle state + TIPS_IDLE, + /// connected state + TIPS_BUSY, + + /// Number of defined states. + TIPS_STATE_MAX +}; + +///Database Configuration - Bit Field Flags +enum +{ + TIPS_CTS_CURR_TIME_SUP = 0x00, + TIPS_CTS_LOC_TIME_INFO_SUP = 0x01, + TIPS_CTS_REF_TIME_INFO_SUP = 0x02, + TIPS_NDCS_SUP = 0x04, + TIPS_RTUS_SUP = 0x08, + + TIPS_CTS_CURRENT_TIME_CFG = 0x10, +}; + +enum +{ + CTS_IDX_SVC, + + CTS_IDX_CURRENT_TIME_CHAR, + CTS_IDX_CURRENT_TIME_VAL, + CTS_IDX_CURRENT_TIME_CFG, + + CTS_IDX_LOCAL_TIME_INFO_CHAR, + CTS_IDX_LOCAL_TIME_INFO_VAL, + + CTS_IDX_REF_TIME_INFO_CHAR, + CTS_IDX_REF_TIME_INFO_VAL, + + CTS_IDX_NB, +}; + +enum +{ + NDCS_IDX_SVC, + NDCS_IDX_TIME_DST_CHAR, + NDCS_IDX_TIME_DST_VAL, + + NDCS_IDX_NB, +}; + +enum +{ + RTUS_IDX_SVC, + RTUS_IDX_TIME_UPD_CTNL_PT_CHAR, + RTUS_IDX_TIME_UPD_CTNL_PT_VAL, + RTUS_IDX_TIME_UPD_STATE_CHAR, + RTUS_IDX_TIME_UPD_STATE_VAL, + + RTUS_IDX_NB, +}; + +enum +{ + CTS_CURRENT_TIME_CHAR, + CTS_LOCAL_TIME_INFO_CHAR, + CTS_REF_TIME_INFO_CHAR, + + CTS_CHAR_MAX, +}; + +enum +{ + NDCS_TIME_DST_CHAR, + + NDCS_CHAR_MAX, +}; + +enum +{ + RTUS_TIME_UPD_CTNL_PT_CHAR, + RTUS_TIME_UPD_STATE_CHAR, + + RTUS_CHAR_MAX, +}; + +enum +{ + TIPS_CTS_CURRENT_TIME, + TIPS_CTS_LOCAL_TIME_INFO, + TIPS_CTS_REF_TIME_INFO, + TIPS_NDCS_TIME_DST, + TIPS_RTUS_TIME_UPD_STATE_VAL, + TIPS_CTS_CURRENT_TIME_CLI +}; + + +/* + * STRUCTURES + **************************************************************************************** + */ + +/// Time Profile Server Instance Environment variable +struct tips_cnx_env +{ + /// NTF State + uint8_t ntf_state; + /// Saved read handle + uint16_t handle; +}; + + +/// Time Profile Server. Environment variable +struct tips_env_tag +{ + /// profile environment + prf_env_t prf_env; + + /// CTS Start Handle + uint16_t cts_shdl; + /// NDCS Start Handle + uint16_t ndcs_shdl; + /// RTUS Start Handle + uint16_t rtus_shdl; + + /// CTS Attribute Table + uint8_t cts_att_tbl[CTS_CHAR_MAX]; + /// NDCS Attribute Table + uint8_t ndcs_att_tbl[NDCS_CHAR_MAX]; + /// NDCS Attribute Table + uint8_t rtus_att_tbl[RTUS_CHAR_MAX]; + + /// Environment variable pointer for each connections + struct tips_cnx_env* env[BLE_CONNECTION_MAX]; + + /// Database configuration + uint8_t features; + /// Time update state for the Ctl Pt + uint8_t time_upd_state; + + /// State of different task instances + ke_state_t state[TIPS_IDX_MAX]; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve TIP service profile interface + * + * @return BLP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* tips_prf_itf_get(void); + +/** + **************************************************************************************** + * @brief Pack Current Time value + * + * @param p_curr_time_val Current Time value + **************************************************************************************** + */ +uint8_t tips_pack_curr_time_value(uint8_t *p_pckd_time, + const struct tip_curr_time* p_curr_time_val); + +/** + **************************************************************************************** + * @brief Pack Time With DST value + * + * @param p_time_dst_val Time With DST value + **************************************************************************************** + */ +uint8_t tips_pack_time_dst_value(uint8_t *p_pckd_time_dst, + const struct tip_time_with_dst* p_time_dst_val); + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void tips_task_init(struct ke_task_desc *task_desc); + + +#endif //BLE_TIP_SERVER + +/// @} TIPS + +#endif // TIPS_H_ diff --git a/services/ble_profiles/tip/tips/src/tips_task.c b/services/ble_profiles/tip/tips/src/tips_task.c new file mode 100644 index 0000000..7ca6fbe --- /dev/null +++ b/services/ble_profiles/tip/tips/src/tips_task.c @@ -0,0 +1,556 @@ +/** + **************************************************************************************** + * @addtogroup TIPSTASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_TIP_SERVER) +#include "co_utils.h" +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "tips.h" +#include "tips_task.h" + +#include "prf_utils.h" + + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Handles reception of the @ref TIPS_ENABLE_REQ message. + * The handler enables the Time Server Profile. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int tips_enable_req_handler(ke_msg_id_t const msgid, + struct tips_enable_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct tips_env_tag *tips_env = PRF_ENV_GET(TIPS, tips); + uint8_t conidx = KE_IDX_GET(src_id); + + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + if(gapc_get_conhdl(conidx) == GAP_INVALID_CONHDL) + { + status = PRF_ERR_DISCONNECTED; + } + else if(ke_state_get(dest_id) == TIPS_IDLE) + { + if (param->current_time_ntf_en == PRF_CLI_START_NTF) + { + // Enable Bonded Data + tips_env->env[conidx]->ntf_state |= TIPS_CTS_CURRENT_TIME_CFG; + } + } + else + { + status = PRF_ERR_REQ_DISALLOWED; + } + + // Send to APP the details of the discovered attributes on TIPS + struct tips_enable_rsp * rsp = KE_MSG_ALLOC( + TIPS_ENABLE_RSP, + src_id, + dest_id, + tips_enable_rsp); + + rsp->status = status; + ke_msg_send(rsp); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref TIPS_UPD_CURR_TIME_REQ message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int tips_upd_curr_time_req_handler(ke_msg_id_t const msgid, + struct tips_upd_curr_time_req const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Status + uint8_t status = GAP_ERR_NO_ERROR; + + // Get the address of the environment + struct tips_env_tag *tips_env = PRF_ENV_GET(TIPS, tips); + uint8_t conidx = KE_IDX_GET(src_id); + + if ((tips_env->env[conidx] != NULL) && (ke_state_get(dest_id) == TIPS_IDLE)) + { + + //Check if Notifications are enabled + if ((tips_env->env[conidx]->ntf_state & TIPS_CTS_CURRENT_TIME_CFG) == TIPS_CTS_CURRENT_TIME_CFG) + { + //Check if notification can be sent + if ((param->current_time.adjust_reason & TIPS_FLAG_EXT_TIME_UPDATE) == TIPS_FLAG_EXT_TIME_UPDATE) + { + if(param->enable_ntf_send == 0) + { + status = PRF_ERR_REQ_DISALLOWED; + } + } + + if (status == GAP_ERR_NO_ERROR) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *meas_val = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), dest_id, + gattc_send_evt_cmd, CTS_CURRENT_TIME_VAL_LEN); + + // Fill in the parameter structure + meas_val->operation = GATTC_NOTIFY; + meas_val->handle = tips_env->cts_shdl + CTS_IDX_CURRENT_TIME_VAL; + // Pack the Current Time value + meas_val->length = tips_pack_curr_time_value(meas_val->value, ¶m->current_time); + + // Go to idle state + ke_state_set(dest_id, TIPS_BUSY); + // Send the event + ke_msg_send(meas_val); + } + } + else + { + status = PRF_ERR_NTF_DISABLED; + } + } + else + { + status = GAP_ERR_INVALID_PARAM; + } + + if (status != GAP_ERR_NO_ERROR) + { + // Inform APP + struct tips_upd_curr_time_rsp *ind = KE_MSG_ALLOC( + TIPS_UPD_CURR_TIME_RSP, + prf_dst_task_get(&(tips_env->prf_env), conidx), + prf_src_task_get(&(tips_env->prf_env), conidx), + tips_upd_curr_time_rsp); + + ind->status = status; + + // send the message + ke_msg_send(ind); + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct tips_env_tag *tips_env = PRF_ENV_GET(TIPS, tips); + uint8_t conidx = KE_IDX_GET(src_id); + + uint8_t status = PRF_ERR_REQ_DISALLOWED; + + if((ke_state_get(dest_id) == TIPS_IDLE) && (tips_env->env[conidx] != NULL)) + { + //CTS : Current Time client configuration + if (param->handle == tips_env->cts_shdl + CTS_IDX_CURRENT_TIME_CFG) + { + uint16_t value = (tips_env->env[conidx]->ntf_state & TIPS_CTS_CURRENT_TIME_CFG) + ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND; + status = ATT_ERR_NO_ERROR; + + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN( + GATTC_READ_CFM, + src_id, dest_id, + gattc_read_cfm, + sizeof(uint16_t)); + + cfm->length = sizeof(uint16_t); + memcpy(cfm->value, &value, sizeof(uint16_t)); + cfm->handle = param->handle; + cfm->status = status; + + // Send value to peer device. + ke_msg_send(cfm); + } + else + { + // Inform APP about read request + struct tips_rd_req_ind* ind = KE_MSG_ALLOC( + TIPS_RD_REQ_IND, + prf_dst_task_get(&(tips_env->prf_env), conidx), + prf_src_task_get(&(tips_env->prf_env), conidx), + tips_rd_req_ind); + + // Current Time Service + if (param->handle < tips_env->cts_shdl + CTS_IDX_NB) + { + // Current Time Char value + if(param->handle == tips_env->cts_shdl + CTS_IDX_CURRENT_TIME_VAL) + { + ind->char_code = TIPS_CTS_CURRENT_TIME; + status = ATT_ERR_NO_ERROR; + } + // Local Time Info Char value + else if ((param->handle == tips_env->cts_shdl + CTS_IDX_LOCAL_TIME_INFO_VAL) + && (TIPS_IS_SUPPORTED(TIPS_CTS_LOC_TIME_INFO_SUP))) + { + ind->char_code = TIPS_CTS_LOCAL_TIME_INFO; + status = ATT_ERR_NO_ERROR; + } + // Reference Time Info Char value + else if ((param->handle == tips_env->cts_shdl + CTS_IDX_REF_TIME_INFO_VAL) + && (TIPS_IS_SUPPORTED(TIPS_CTS_REF_TIME_INFO_SUP))) + { + ind->char_code = TIPS_CTS_REF_TIME_INFO; + status = ATT_ERR_NO_ERROR; + } + } + // Time with DST Char value + else if ((param->handle == tips_env->ndcs_shdl + NDCS_IDX_TIME_DST_VAL) + && (TIPS_IS_SUPPORTED(TIPS_NDCS_SUP))) + { + ind->char_code = TIPS_NDCS_TIME_DST; + status = ATT_ERR_NO_ERROR; + } + // Time Update State + else if ((param->handle == tips_env->rtus_shdl + RTUS_IDX_TIME_UPD_STATE_VAL) + && (TIPS_IS_SUPPORTED(TIPS_RTUS_SUP))) + { + ind->char_code = TIPS_RTUS_TIME_UPD_STATE_VAL; + status = ATT_ERR_NO_ERROR; + } + else + { + // Set error code + status = PRF_ERR_INEXISTENT_HDL; + } + + if (status == ATT_ERR_NO_ERROR) + { + // Save handle + tips_env->env[conidx]->handle = param->handle; + // Send message to the APP + ke_msg_send(ind); + // Go to busy state + ke_state_set(dest_id, TIPS_BUSY); + } + else + { + // Free message + ke_msg_free(ke_param2msg(ind)); + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC( + GATTC_READ_CFM, + src_id, dest_id, + gattc_read_cfm); + + cfm->handle = param->handle; + cfm->status = status; + + // Send to peer device. + ke_msg_send(cfm); + } + } + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref TIPS_RD_CFM message. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int tips_rd_cfm_handler(ke_msg_id_t const msgid, + struct tips_rd_cfm const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct tips_env_tag *tips_env = PRF_ENV_GET(TIPS, tips); + uint8_t conidx = KE_IDX_GET(src_id); + uint8_t status = GAP_ERR_NO_ERROR; + + if ((ke_state_get(dest_id) == TIPS_BUSY) && (tips_env->env[conidx] != NULL)) + { + if (tips_env->env[conidx]->handle != ATT_INVALID_HANDLE) + { + // Send data to peer device + struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN( + GATTC_READ_CFM, + KE_BUILD_ID(TASK_GATTC, conidx), dest_id, + gattc_read_cfm, + sizeof(struct tips_rd_cfm)); + + switch (param->op_code) + { + case TIPS_CTS_CURRENT_TIME: + { + // Pack Current Time + cfm->length = tips_pack_curr_time_value(cfm->value, ¶m->value.curr_time); + } break; + + case TIPS_CTS_LOCAL_TIME_INFO: + { + // Pack Local Time + cfm->length = sizeof(struct tip_loc_time_info); + memcpy(cfm->value, ¶m->value, cfm->length); + } break; + + case TIPS_CTS_REF_TIME_INFO: + { + // Pack Reference Time + cfm->length = sizeof(struct tip_ref_time_info); + memcpy(cfm->value, ¶m->value, cfm->length); + } break; + + case TIPS_NDCS_TIME_DST: + { + // Pack Time with DST + cfm->length = tips_pack_time_dst_value(cfm->value, ¶m->value.time_with_dst); + } break; + + case TIPS_RTUS_TIME_UPD_STATE_VAL: + { + // Pack Time Update State + cfm->length = sizeof(struct tip_time_upd_state); + memcpy(cfm->value, ¶m->value, cfm->length); + } break; + default: + { + // Return Application error to peer + cfm->length = 0; + status = PRF_APP_ERROR; + } break; + } + + // Set parameters + cfm->handle = tips_env->env[conidx]->handle; + cfm->status = status; + // Send value to peer device. + ke_msg_send(cfm); + // Go to idle state + ke_state_set(dest_id, TIPS_IDLE); + // Reset environment variable + tips_env->env[conidx]->handle = ATT_INVALID_HANDLE; + } + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY message meaning that Measurement + * notification has been correctly sent to peer device (but not confirmed by peer device). + * * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + // Get the address of the environment + struct tips_env_tag *tips_env = PRF_ENV_GET(TIPS, tips); + uint8_t conidx = KE_IDX_GET(src_id); + + if (tips_env->env[conidx] != NULL) + { + if (param->operation == GATTC_NOTIFY) + { + // Inform APP + struct tips_upd_curr_time_rsp *ind = KE_MSG_ALLOC( + TIPS_UPD_CURR_TIME_RSP, + prf_dst_task_get(&(tips_env->prf_env), conidx), + prf_src_task_get(&(tips_env->prf_env), conidx), + tips_upd_curr_time_rsp); + + ind->status = param->status; + + // send the message + ke_msg_send(ind); + // Go to idle state + ke_state_set(dest_id, TIPS_IDLE); + } + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. + * The handler compares the new values with current ones and notifies them if they changed. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + uint16_t cfg_value = 0x0000; +// uint8_t time_upd_ctnl_pt = 0x00; + uint8_t status = GAP_ERR_NO_ERROR; + + // Get the address of the environment + struct tips_env_tag *tips_env = PRF_ENV_GET(TIPS, tips); + uint8_t conidx = KE_IDX_GET(src_id); + + //CTS : Current Time Char. - Notification Configuration + if (param->handle == tips_env->cts_shdl + CTS_IDX_CURRENT_TIME_CFG) + { + //Extract value before check + memcpy(&cfg_value, ¶m->value[0], sizeof(uint16_t)); + + //only update configuration if value for stop or notification enable + if ((cfg_value == PRF_CLI_STOP_NTFIND) || (cfg_value == PRF_CLI_START_NTF)) + { + if (cfg_value == PRF_CLI_STOP_NTFIND) + { + tips_env->env[conidx]->ntf_state &= ~TIPS_CTS_CURRENT_TIME_CFG; + } + else //PRF_CLI_START_NTF + { + tips_env->env[conidx]->ntf_state |= TIPS_CTS_CURRENT_TIME_CFG; + } + + //Inform APP of configuration change + struct tips_current_time_ccc_ind * msg = KE_MSG_ALLOC( + TIPS_CURRENT_TIME_CCC_IND, + prf_dst_task_get(&tips_env->prf_env, conidx), + prf_src_task_get(&tips_env->prf_env, conidx), + tips_current_time_ccc_ind); + + msg->cfg_val = cfg_value; + + ke_msg_send(msg); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + //RTUS : Time Update Control Point Char. - Val + else if (param->handle == tips_env->rtus_shdl + RTUS_IDX_TIME_UPD_CTNL_PT_VAL) + { + //Check if value to write is in allowed range + if ((param->value[0] == TIPS_TIME_UPD_CTNL_PT_GET) || + (param->value[0] == TIPS_TIME_UPD_CTNL_PT_CANCEL)) + { + //Update value + tips_env->time_upd_state = param->value[0]; + + //Send APP the indication with the new value + struct tips_time_upd_ctnl_pt_ind * msg = KE_MSG_ALLOC( + TIPS_TIME_UPD_CTNL_PT_IND, + prf_dst_task_get(&tips_env->prf_env, conidx), + prf_src_task_get(&tips_env->prf_env, conidx), + tips_time_upd_ctnl_pt_ind); + + // Time Update Control Point Characteristic Value + msg->value = tips_env->time_upd_state; + // Send message + ke_msg_send(msg); + } + else + { + status = PRF_ERR_INVALID_PARAM; + } + } + else + { + status = PRF_ERR_NOT_WRITABLE; + } + + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// Default State handlers definition +KE_MSG_HANDLER_TAB(tips) +{ + {TIPS_ENABLE_REQ, (ke_msg_func_t)tips_enable_req_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t)gattc_write_req_ind_handler}, + {TIPS_UPD_CURR_TIME_REQ, (ke_msg_func_t)tips_upd_curr_time_req_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t)gattc_read_req_ind_handler}, + {TIPS_RD_CFM, (ke_msg_func_t)tips_rd_cfm_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t)gattc_cmp_evt_handler}, +}; + +void tips_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct tips_env_tag *tips_env = PRF_ENV_GET(TIPS, tips); + + task_desc->msg_handler_tab = tips_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(tips_msg_handler_tab); + task_desc->state = tips_env->state; + task_desc->idx_max = TIPS_IDX_MAX; +} + +#endif //BLE_TIP_SERVER + +/// @} TIPSTASK diff --git a/services/ble_profiles/tota/tota_ble.c b/services/ble_profiles/tota/tota_ble.c new file mode 100644 index 0000000..ef8b5ab --- /dev/null +++ b/services/ble_profiles/tota/tota_ble.c @@ -0,0 +1,199 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_TOTA) +#include "gap.h" +#include "gattc_task.h" +#include "attm.h" +#include "gapc_task.h" +#include "tota_ble.h" +#include "tota_task.h" +#include "prf_utils.h" +#include "ke_mem.h" +#include "co_utils.h" + + +/* + * TOTA CMD PROFILE ATTRIBUTES + **************************************************************************************** + */ +#define tota_service_uuid_128_content {0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86 } +#define tota_val_char_val_uuid_128_content {0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97 } + +#define ATT_DECL_PRIMARY_SERVICE_UUID { 0x00, 0x28 } +#define ATT_DECL_CHARACTERISTIC_UUID { 0x03, 0x28 } +#define ATT_DESC_CLIENT_CHAR_CFG_UUID { 0x02, 0x29 } + +static const uint8_t TOTA_SERVICE_UUID_128[ATT_UUID_128_LEN] = tota_service_uuid_128_content; + +/// Full OTA SERVER Database Description - Used to add attributes into the database +const struct attm_desc_128 tota_att_db[TOTA_IDX_NB] = +{ + // TOTA Service Declaration + [TOTA_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE_UUID, PERM(RD, ENABLE), 0, 0}, + // TOTA Characteristic Declaration + [TOTA_IDX_CHAR] = {ATT_DECL_CHARACTERISTIC_UUID, PERM(RD, ENABLE), 0, 0}, + // TOTA service + [TOTA_IDX_VAL] = {tota_val_char_val_uuid_128_content, PERM(WRITE_REQ, ENABLE) | PERM(NTF, ENABLE), PERM(RI, ENABLE) | PERM_VAL(UUID_LEN, PERM_UUID_128), TOTA_MAX_LEN}, + // TOTA Characteristic + [TOTA_IDX_NTF_CFG] = {ATT_DESC_CLIENT_CHAR_CFG_UUID, PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), 0, 0}, + +}; + + +/** + **************************************************************************************** + * @brief Initialization of the TOTA module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +static uint8_t tota_init(struct prf_task_env* env, uint16_t* start_hdl, + uint16_t app_task, uint8_t sec_lvl, void* params) +{ + uint8_t status; + //Add Service Into Database + status = attm_svc_create_db_128(start_hdl, TOTA_SERVICE_UUID_128, NULL, + TOTA_IDX_NB, NULL, env->task, &tota_att_db[0], + (sec_lvl & (PERM_MASK_SVC_DIS | PERM_MASK_SVC_AUTH | PERM_MASK_SVC_EKS))| PERM(SVC_MI, DISABLE) + | PERM_VAL(SVC_UUID_LEN, PERM_UUID_128)); + + + BLE_GATT_DBG("attm_svc_create_db_128 returns %d start handle is %d", status, *start_hdl); + + //-------------------- allocate memory required for the profile --------------------- + if (status == ATT_ERR_NO_ERROR) + { + // Allocate TOTA required environment variable + struct tota_env_tag* tota_env = + (struct tota_env_tag* ) ke_malloc(sizeof(struct tota_env_tag), KE_MEM_ATT_DB); + + // Initialize TOTA environment + env->env = (prf_env_t*) tota_env; + tota_env->shdl = *start_hdl; + + tota_env->prf_env.app_task = app_task + | (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + // Mono Instantiated task + tota_env->prf_env.prf_task = env->task | + (PERM_GET(sec_lvl, SVC_MI) ? PERM(PRF_MI, ENABLE) : PERM(PRF_MI, DISABLE)); + + // initialize environment variable + env->id = TASK_ID_TOTA; + tota_task_init(&(env->desc)); + + /* Put HRS in Idle state */ + ke_state_set(env->task, TOTA_IDLE); + } + + return (status); +} + +/** + **************************************************************************************** + * @brief Destruction of the TOTA module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +static void tota_destroy(struct prf_task_env* env) +{ + struct tota_env_tag* tota_env = (struct tota_env_tag*) env->env; + + // free profile environment variables + env->env = NULL; + ke_free(tota_env); +} + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +static void tota_create(struct prf_task_env* env, uint8_t conidx) +{ + struct tota_env_tag* tota_env = (struct tota_env_tag*) env->env; + struct prf_svc tota_tota_svc = {tota_env->shdl, tota_env->shdl + TOTA_IDX_NB}; + prf_register_atthdl2gatt(env->env, conidx, &tota_tota_svc); + +} + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +static void tota_cleanup(struct prf_task_env* env, uint8_t conidx, uint8_t reason) +{ + /* Nothing to do */ +} + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/// TOTA Task interface required by profile manager +const struct prf_task_cbs tota_itf = +{ + (prf_init_fnct) tota_init, + tota_destroy, + tota_create, + tota_cleanup, +}; + +/* + * EXPORTED FUNCTIONS DEFINITIONS + **************************************************************************************** + */ + +const struct prf_task_cbs* tota_prf_itf_get(void) +{ + return &tota_itf; +} + + +#endif /* BLE_TOTA */ diff --git a/services/ble_profiles/tota/tota_ble.h b/services/ble_profiles/tota/tota_ble.h new file mode 100644 index 0000000..f24485c --- /dev/null +++ b/services/ble_profiles/tota/tota_ble.h @@ -0,0 +1,150 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef _TOTA_H_ +#define _TOTA_H_ + +/** + **************************************************************************************** + * @addtogroup TOTA Datapath Profile Server + * @ingroup TOTAP + * @brief Datapath Profile Server + * + * Datapath Profile Server provides functionalities to upper layer module + * application. The device using this profile takes the role of Datapath Server. + * + * The interface of this role to the Application is: + * - Enable the profile role (from APP) + * - Disable the profile role (from APP) + * - Send data to peer device via notifications (from APP) + * - Receive data from peer device via write no response (from APP) + * + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_TOTA) +#include "prf_types.h" +#include "prf.h" +// #include "tota_task.h" +#include "attm.h" +#include "prf_utils.h" + + +/* + * DEFINES + **************************************************************************************** + */ +#define TOTA_MAX_LEN (509) + +/* + * DEFINES + **************************************************************************************** + */ +/// Possible states of the TOTA task +enum +{ + /// Idle state + TOTA_IDLE, + /// Connected state + TOTA_BUSY, + + /// Number of defined states. + TOTA_STATE_MAX, +}; + +///Attributes State Machine +enum +{ + TOTA_IDX_SVC, + + TOTA_IDX_CHAR, + TOTA_IDX_VAL, + TOTA_IDX_NTF_CFG, + + TOTA_IDX_NB, +}; + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Datapath Profile Server environment variable +struct tota_env_tag +{ + /// profile environment + prf_env_t prf_env; + uint8_t isNotificationEnabled[BLE_CONNECTION_MAX]; + /// Service Start Handle + uint16_t shdl; + /// State of different task instances + ke_state_t state; +}; + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve HRP service profile interface + * + * @return HRP service profile interface + **************************************************************************************** + */ +const struct prf_task_cbs* tota_prf_itf_get(void); + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * Initialize task handler + * + * @param task_desc Task descriptor to fill + **************************************************************************************** + */ +void tota_task_init(struct ke_task_desc *task_desc); + + + +#endif /* #if (BLE_TOTA) */ + +/// @} TOTA + +#endif /* _TOTA_H_ */ \ No newline at end of file diff --git a/services/ble_profiles/tota/tota_task.c b/services/ble_profiles/tota/tota_task.c new file mode 100644 index 0000000..cb1b013 --- /dev/null +++ b/services/ble_profiles/tota/tota_task.c @@ -0,0 +1,428 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +/** + **************************************************************************************** + * @addtogroup TOTATASK + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_TOTA) +#include "gap.h" +#include "gattc_task.h" +#include "gapc_task.h" +#include "attm.h" +#include "tota_ble.h" +#include "tota_task.h" + +#include "prf_utils.h" + +#include "ke_mem.h" +#include "co_utils.h" + +/* + * LOCAL FUNCTIONS DEFINITIONS + **************************************************************************************** + */ +static int gapc_disconnect_ind_handler(ke_msg_id_t const msgid, + struct gapc_disconnect_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + TOTA_LOG_DBG(1,"[%s]TOTA",__func__); + uint8_t conidx = KE_IDX_GET(src_id); + struct tota_env_tag *tota_env = PRF_ENV_GET(TOTA, tota); + tota_env->isNotificationEnabled[conidx] = false; + return KE_MSG_CONSUMED; +} + +void app_tota_send_rx_cfm(uint8_t conidx) +{ + TOTA_LOG_DBG(1,"[%s]TOTA",__func__); + struct tota_env_tag *tota_env = PRF_ENV_GET(TOTA, tota); + + struct gattc_write_cfm *cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, + KE_BUILD_ID(TASK_GATTC, conidx), + prf_src_task_get(&tota_env->prf_env, conidx), + gattc_write_cfm); + cfm->handle = tota_env->shdl + TOTA_IDX_VAL; + cfm->status = ATT_ERR_NO_ERROR; + ke_msg_send(cfm); +} + +/** + **************************************************************************************** + * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. + * The handler compares the new values with current ones and notifies them if they changed. + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_write_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + // Get the address of the environment + struct tota_env_tag *tota_env = PRF_ENV_GET(TOTA, tota); + uint8_t conidx = KE_IDX_GET(src_id); + + uint8_t status = GAP_ERR_NO_ERROR; + + BLE_GATT_DBG("gattc_write_req_ind_handler tota_env 0x%x write handle %d shdl %d", + tota_env, param->handle, tota_env->shdl); + + //Send write response + struct gattc_write_cfm *cfm = KE_MSG_ALLOC( + GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm); + cfm->handle = param->handle; + cfm->status = status; + ke_msg_send(cfm); + + if (tota_env != NULL) + { + if (param->handle == (tota_env->shdl + TOTA_IDX_NTF_CFG)) + { + uint16_t value = 0x0000; + + //Extract value before check + memcpy(&value, &(param->value), sizeof(uint16_t)); + + if (value == PRF_CLI_STOP_NTFIND) + { + tota_env->isNotificationEnabled[conidx] = false; + } + else if (value == PRF_CLI_START_NTF) + { + tota_env->isNotificationEnabled[conidx] = true; + } + else + { + status = PRF_APP_ERROR; + } + + if (status == GAP_ERR_NO_ERROR) + { + //Inform APP of TX ccc change + struct ble_tota_tx_notif_config_t * ind = KE_MSG_ALLOC(TOTA_CCC_CHANGED, + prf_dst_task_get(&tota_env->prf_env, conidx), + prf_src_task_get(&tota_env->prf_env, conidx), + ble_tota_tx_notif_config_t); + + ind->isNotificationEnabled = tota_env->isNotificationEnabled[conidx]; + + ke_msg_send(ind); + } + } + else if (param->handle == (tota_env->shdl + TOTA_IDX_VAL)) + { + //inform APP of data + struct ble_tota_rx_data_ind_t * ind = KE_MSG_ALLOC_DYN(TOTA_DATA_RECEIVED, + prf_dst_task_get(&tota_env->prf_env, conidx), + prf_src_task_get(&tota_env->prf_env, conidx), + ble_tota_rx_data_ind_t, + sizeof(struct ble_tota_rx_data_ind_t) + param->length); + + ind->length = param->length; + memcpy((uint8_t *)(ind->data), &(param->value), param->length); + + ke_msg_send(ind); + + return KE_MSG_CONSUMED; + } + else + { + status = PRF_APP_ERROR; + } + } + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY message meaning that Measurement + * notification has been correctly sent to peer device (but not confirmed by peer device). + * * + * @param[in] msgid Id of the message received. + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) +{ + TOTA_LOG_DBG(1,"[%s]TOTA",__func__); + // Get the address of the environment + struct tota_env_tag *tota_env = PRF_ENV_GET(TOTA, tota); + + uint8_t conidx = KE_IDX_GET(dest_id); + + // notification or write request has been sent out + if ((GATTC_NOTIFY == param->operation) || (GATTC_INDICATE == param->operation)) + { + + struct ble_tota_tx_sent_ind_t * ind = KE_MSG_ALLOC(TOTA_TX_DATA_SENT, + prf_dst_task_get(&tota_env->prf_env, conidx), + prf_src_task_get(&tota_env->prf_env, conidx), + ble_tota_tx_sent_ind_t); + + ind->status = param->status; + + ke_msg_send(ind); + + } + + ke_state_set(dest_id, TOTA_IDLE); + + return (KE_MSG_CONSUMED); +} + +/** + **************************************************************************************** + * @brief Handles reception of the read request from peer device + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +__STATIC int gattc_read_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_read_req_ind const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + + TOTA_LOG_DBG(1,"[%s]TOTA",__func__); + // Get the address of the environment + struct tota_env_tag *tota_env = PRF_ENV_GET(TOTA, tota); + + struct gattc_read_cfm* cfm; + + uint8_t status = GAP_ERR_NO_ERROR; + uint8_t conidx = KE_IDX_GET(src_id); + + BLE_GATT_DBG("gattc_read_req_ind_handler read handle %d shdl %d", param->handle, tota_env->shdl); + + if (param->handle == (tota_env->shdl + TOTA_IDX_NTF_CFG)) + { + uint16_t notify_ccc; + cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, sizeof(notify_ccc)); + + if (tota_env->isNotificationEnabled[conidx]) + { + notify_ccc = 1; + } + else + { + notify_ccc = 0; + } + cfm->length = sizeof(notify_ccc); + memcpy(cfm->value, (uint8_t *)¬ify_ccc, cfm->length); + } + else + { + cfm = KE_MSG_ALLOC(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm); + cfm->length = 0; + status = ATT_ERR_REQUEST_NOT_SUPPORTED; + } + + cfm->handle = param->handle; + + cfm->status = status; + + ke_msg_send(cfm); + + ke_state_set(dest_id, TOTA_IDLE); + + return (KE_MSG_CONSUMED); +} + +static void send_notifiction(uint8_t conidx, const uint8_t* ptrData, uint32_t length) +{ + uint16_t handle_offset = 0xFFFF; + struct tota_env_tag *tota_env = PRF_ENV_GET(TOTA, tota); + + if (tota_env->isNotificationEnabled[conidx]) + { + handle_offset = TOTA_IDX_VAL; + } + + TRACE(1,"Send tota notificationto handle offset %d:", handle_offset); + + if (0xFFFF != handle_offset) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *report_ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&tota_env->prf_env, conidx), + gattc_send_evt_cmd, length); + + // Fill in the parameter structure + report_ntf->operation = GATTC_NOTIFY; + report_ntf->handle = tota_env->shdl + handle_offset; + // pack measured value in database + report_ntf->length = length; + memcpy(report_ntf->value, ptrData, length); + // send notification to peer device + ke_msg_send(report_ntf); + } +} + +static void send_indication(uint8_t conidx, const uint8_t* ptrData, uint32_t length) +{ + uint16_t handle_offset = 0xFFFF; + struct tota_env_tag *tota_env = PRF_ENV_GET(TOTA, tota); + if (tota_env->isNotificationEnabled[conidx]) + { + handle_offset = TOTA_IDX_VAL; + } + + TRACE(1,"Send tota indicationto handle offset %d:", handle_offset); + + if (0xFFFF != handle_offset) + { + // Allocate the GATT notification message + struct gattc_send_evt_cmd *report_ntf = KE_MSG_ALLOC_DYN(GATTC_SEND_EVT_CMD, + KE_BUILD_ID(TASK_GATTC, conidx), prf_src_task_get(&tota_env->prf_env, conidx), + gattc_send_evt_cmd, length); + + // Fill in the parameter structure + report_ntf->operation = GATTC_INDICATE; + report_ntf->handle = tota_env->shdl + handle_offset; + // pack measured value in database + report_ntf->length = length; + memcpy(report_ntf->value, ptrData, length); + // send notification to peer device + ke_msg_send(report_ntf); + } +} + +__STATIC int send_notification_handler(ke_msg_id_t const msgid, + struct ble_tota_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + send_notifiction(param->connecionIndex, param->value, param->length); + return (KE_MSG_CONSUMED); +} + +__STATIC int send_indication_handler(ke_msg_id_t const msgid, + struct ble_tota_send_data_req_t const *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + send_indication(param->connecionIndex, param->value, param->length); + return (KE_MSG_CONSUMED); +} + + +/** + **************************************************************************************** + * @brief Handles reception of the attribute info request message. + * + * @param[in] msgid Id of the message received (probably unused). + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id ID of the receiving task instance (probably unused). + * @param[in] src_id ID of the sending task instance. + * @return If the message was consumed or not. + **************************************************************************************** + */ +static int gattc_att_info_req_ind_handler(ke_msg_id_t const msgid, + struct gattc_att_info_req_ind *param, + ke_task_id_t const dest_id, + ke_task_id_t const src_id) +{ + TOTA_LOG_DBG(1,"[%s]TOTA",__func__); + // Get the address of the environment + struct gattc_att_info_cfm * cfm; + + //Send write response + cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm); + cfm->handle = param->handle; + + struct tota_env_tag *tota_env = PRF_ENV_GET(TOTA, tota); + + if (param->handle == (tota_env->shdl + TOTA_IDX_NTF_CFG)) + { + // CCC attribute length = 2 + cfm->length = 2; + cfm->status = GAP_ERR_NO_ERROR; + } + else if (param->handle == (tota_env->shdl + TOTA_IDX_VAL)) + { + // force length to zero to reject any write starting from something != 0 + cfm->length = 0; + cfm->status = GAP_ERR_NO_ERROR; + } + else + { + cfm->length = 0; + cfm->status = ATT_ERR_WRITE_NOT_PERMITTED; + } + + ke_msg_send(cfm); + + return (KE_MSG_CONSUMED); +} + + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ + +/* Default State handlers definition. */ +KE_MSG_HANDLER_TAB(tota) +{ + {GAPC_DISCONNECT_IND, (ke_msg_func_t) gapc_disconnect_ind_handler}, + {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler}, + {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler}, + {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler}, + {TOTA_SEND_NOTIFICATION, (ke_msg_func_t) send_notification_handler}, + {TOTA_SEND_INDICATION, (ke_msg_func_t) send_indication_handler}, + {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler }, +}; + +void tota_task_init(struct ke_task_desc *task_desc) +{ + // Get the address of the environment + struct tota_env_tag *tota_env = PRF_ENV_GET(TOTA, tota); + + task_desc->msg_handler_tab = tota_msg_handler_tab; + task_desc->msg_cnt = ARRAY_LEN(tota_msg_handler_tab); + task_desc->state = &(tota_env->state); + task_desc->idx_max = BLE_CONNECTION_MAX; +} + +#endif /* #if (BLE_TOTA) */ + +/// @} TOTATASK diff --git a/services/ble_profiles/tota/tota_task.h b/services/ble_profiles/tota/tota_task.h new file mode 100644 index 0000000..5c92ea0 --- /dev/null +++ b/services/ble_profiles/tota/tota_task.h @@ -0,0 +1,97 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +#ifndef _TOTA_TASK_H_ +#define _TOTA_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup TOTATASK Task + * @ingroup TOTA + * @brief TOTA Profile Task. + * + * The TOTATASK is responsible for handling the messages coming in and out of the + * @ref TOTA collector block of the BLE Host. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include "rwip_task.h" // Task definitions +#include "app_tota_cmd_code.h" + +/* + * DEFINES + **************************************************************************************** + */ +#define TOTA_CONTENT_TYPE_COMMAND 0 +#define TOTA_CONTENT_TYPE_DATA 1 + +/// Messages for TOTA Profile +enum tota_msg_id +{ + TOTA_CCC_CHANGED = TASK_FIRST_MSG(TASK_ID_TOTA), + + TOTA_TX_DATA_SENT, + + TOTA_DATA_RECEIVED, + + TOTA_SEND_NOTIFICATION, + + TOTA_SEND_INDICATION, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +struct ble_tota_tx_notif_config_t +{ + bool isNotificationEnabled; +}; + +struct ble_tota_rx_data_ind_t +{ + uint16_t length; + uint8_t data[0]; +}; + +struct ble_tota_tx_sent_ind_t +{ + uint8_t status; +}; + +struct ble_tota_send_data_req_t +{ + uint8_t connecionIndex; + uint32_t length; + uint8_t value[__ARRAY_EMPTY]; +}; + + +/// @} TOTATASK + +#endif /* _TOTA_TASK_H_ */ + diff --git a/services/ble_stack/Makefile b/services/ble_stack/Makefile new file mode 100644 index 0000000..2bccf70 --- /dev/null +++ b/services/ble_stack/Makefile @@ -0,0 +1,61 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)common/src/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/gap/gapc/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/gap/gapm/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/gap/smpc/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/gatt/attc/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/gatt/attm/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/gatt/atts/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/gatt/gattc/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/gatt/gattm/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/l2c/l2cc/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/l2c/l2cm/*.c)) +#obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/prf/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hl/src/rwble_hl/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hci/src/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)ke/src/*.c)) +#obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)dbg/src/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)ble_ip/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)util/*.c)) + +BTBLE_LIB_NAME := $(CHIP)_libble_stack + +ifeq ($(HFP_1_6_ENABLE), 1) +BTBLE_LIB_NAME := $(BTBLE_LIB_NAME)_sbc_enc +endif + +$(BTBLE_LIB_NAME)-y := $(obj_c:.c=.o) +obj-y := $(BTBLE_LIB_NAME).a + +subdir-ccflags-y += \ + -Iservices/bridge/ \ + $(BT_IF_INCLUDES) \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/hl/api/ \ + -Iservices/ble_stack/hl/src/gap/ \ + -Iservices/ble_stack/hl/src/gap/gapc/ \ + -Iservices/ble_stack/hl/src/gap/gapm/ \ + -Iservices/ble_stack/hl/src/gap/smpc/ \ + -Iservices/ble_stack/ke/api/ \ + -Iservices/ble_stack/ke/src/ \ + -Iservices/ble_stack/hl/src/gatt/attc/ \ + -Iservices/ble_stack/hl/src/gatt/attm/ \ + -Iservices/ble_stack/hl/src/gatt/atts/ \ + -Iservices/ble_stack/hl/src/gatt/gattc/ \ + -Iservices/ble_stack/hl/src/gatt/gattm/ \ + -Iservices/ble_stack/hl/src/gatt/ \ + -Iservices/ble_stack/hl/src/l2c/l2cc/ \ + -Iservices/ble_stack/hl/src/l2c/l2cm/ \ + -Iservices/ble_stack/hci/api/ \ + -Iservices/ble_stack/hci/src/ \ + -Iservices/ble_app/app_main/ \ + -Iservices/ble_stack/ble_ip/ \ + -Iservices/ble_app/app_datapath/ \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/app/src/ +ifeq ($(GATT_OVER_BR_EDR),1) +ccflags-y += -Iservices/bt_app +endif \ No newline at end of file diff --git a/services/ble_stack/ble_ip/arch.h b/services/ble_stack/ble_ip/arch.h new file mode 100644 index 0000000..b2f2cdc --- /dev/null +++ b/services/ble_stack/ble_ip/arch.h @@ -0,0 +1,217 @@ +#ifndef _ARCH_H_ +#define _ARCH_H_ + +/** + **************************************************************************************** + * @defgroup REFIP + * @brief Reference IP Platform + * + * This module contains reference platform components - REFIP. + * + * + * @{ + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @defgroup DRIVERS + * @ingroup REFIP + * @brief Reference IP Platform Drivers + * + * This module contains the necessary drivers to run the platform with the + * RW BT SW protocol stack. + * + * This has the declaration of the platform architecture API. + * + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include // standard integer definition +//#include "compiler.h" // inline functions +#include "hal_trace.h" + +/* + * CPU WORD SIZE + **************************************************************************************** + */ +/// ARM is a 32-bit CPU +#define CPU_WORD_SIZE 4 + +/* + * CPU Endianness + **************************************************************************************** + */ +/// ARM is little endian +#define CPU_LE 1 + +/* + * DEBUG configuration + **************************************************************************************** + */ +#if defined(CFG_DBG) +#define PLF_DEBUG 1 +#else //CFG_DBG +#define PLF_DEBUG 0 +#endif //CFG_DBG + + +/* + * NVDS + **************************************************************************************** + */ + +/// NVDS +#ifdef CFG_NVDS +#define PLF_NVDS 1 +#else // CFG_NVDS +#define PLF_NVDS 0 +#endif // CFG_NVDS + + +/* + * UART + **************************************************************************************** + */ + +/// UART +#define PLF_UART 1 + +/* + * DEFINES + **************************************************************************************** + */ + +/// Possible errors detected by FW +#define RESET_NO_ERROR 0x00000000 +#define RESET_MEM_ALLOC_FAIL 0xF2F2F2F2 + +/// Reset platform and stay in ROM +#define RESET_TO_ROM 0xA5A5A5A5 +/// Reset platform and reload FW +#define RESET_AND_LOAD_FW 0xC3C3C3C3 + +/// Exchange memory size limit +#define EM_SIZE_LIMIT 0x8000 +/* + * EXPORTED FUNCTION DECLARATION + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Compute size of SW stack used. + * + * This function is compute the maximum size stack used by SW. + * + * @return Size of stack used (in bytes) + **************************************************************************************** + */ +uint16_t get_stack_usage(void); + +/** + **************************************************************************************** + * @brief Re-boot FW. + * + * This function is used to re-boot the FW when error has been detected, it is the end of + * the current FW execution. + * After waiting transfers on UART to be finished, and storing the information that + * FW has re-booted by itself in a non-loaded area, the FW restart by branching at FW + * entry point. + * + * Note: when calling this function, the code after it will not be executed. + * + * @param[in] error Error detected by FW + **************************************************************************************** + */ +void platform_reset(uint32_t error); + +#if PLF_DEBUG +/** + **************************************************************************************** + * @brief Print the assertion error reason and loop forever. + * + * @param condition C string containing the condition. + * @param file C string containing file where the assertion is located. + * @param line Line number in the file where the assertion is located. + **************************************************************************************** + */ +void assert_err(const char *condition, const char * file, int line); + +/** + **************************************************************************************** + * @brief Print the assertion error reason and loop forever. + * The parameter value that is causing the assertion will also be disclosed. + * + * @param param0 parameter value 0. + * @param param1 parameter value 1. + * @param file C string containing file where the assertion is located. + * @param line Line number in the file where the assertion is located. + **************************************************************************************** + */ +void assert_param(int param0, int param1, const char * file, int line); + +/** + **************************************************************************************** + * @brief Print the assertion warning reason. + * + * @param param0 parameter value 0. + * @param param1 parameter value 1. + * @param file C string containing file where the assertion is located. + * @param line Line number in the file where the assertion is located. + **************************************************************************************** + */ +void assert_warn(int param0, int param1, const char * file, int line); + + +/** + **************************************************************************************** + * @brief Dump data value into FW. + * + * @param data start pointer of the data. + * @param length data size to dump + **************************************************************************************** + */ +void dump_data(uint8_t* data, uint16_t length); +#endif //PLF_DEBUG + + +/* + * ASSERTION CHECK + **************************************************************************************** + */ +#if 1 +/// Assertions showing a critical error that could require a full system reset +#define ASSERT_ERR(cond) { if (!(cond)) { TRACE(2,"line is %d file is %s", __LINE__, __FILE__); } } + +/// Assertions showing a critical error that could require a full system reset +#define ASSERT_INFO(cond, param0, param1) { if (!(cond)) { TRACE(2,"line is %d file is %s", __LINE__, __FILE__); } } + +/// Assertions showing a non-critical problem that has to be fixed by the SW +#define ASSERT_WARN(cond, param0, param1) { if (!(cond)) { TRACE(2,"line is %d file is %s", __LINE__, __FILE__); } } + +#define DUMP_DATA(data, length) \ + // dump_data((uint8_t*)data, length) + +#else +/// Assertions showing a critical error that could require a full system reset +#define ASSERT_ERR(cond) + +/// Assertions showing a critical error that could require a full system reset +#define ASSERT_INFO(cond, param0, param1) + +/// Assertions showing a non-critical problem that has to be fixed by the SW +#define ASSERT_WARN(cond, param0, param1) + +/// DUMP data array present in the SW. +#define DUMP_DATA(data, length) +#endif //PLF_DEBUG + +/// @} DRIVERS +#endif // _ARCH_H_ diff --git a/services/ble_stack/ble_ip/besble.h b/services/ble_stack/ble_ip/besble.h new file mode 100644 index 0000000..f3943c0 --- /dev/null +++ b/services/ble_stack/ble_ip/besble.h @@ -0,0 +1,8 @@ +#ifndef _BESBLE_H_ +#define _BESBLE_H_ + +void bes_ble_init(void); +void bes_ble_reset(void); +void bes_ble_schedule(void); + +#endif diff --git a/services/ble_stack/ble_ip/compiler.h b/services/ble_stack/ble_ip/compiler.h new file mode 100644 index 0000000..ad77b74 --- /dev/null +++ b/services/ble_stack/ble_ip/compiler.h @@ -0,0 +1,43 @@ +#ifndef _COMPILER_H_ +#define _COMPILER_H_ + +#ifndef __INLINE +#define __INLINE inline +#endif + +/// define the static keyword for this compiler +#define __STATIC static + +/// define the BLE IRQ handler attribute for this compiler +#define __BTIRQ + +/// define the BLE IRQ handler attribute for this compiler +#define __BLEIRQ + +/// define size of an empty array (used to declare structure with an array size not defined) +#define __ARRAY_EMPTY 1 + +/// Function returns struct in registers (4 in rvds, var with gnuarm). +/// With Gnuarm, feature depends on command line options and +/// impacts ALL functions returning 2-words max structs +/// (check -freg-struct-return and -mabi=xxx) +#define __VIR + +/// function has no side effect and return depends only on arguments +#define __PURE __attribute__((const)) + +/// Align instantiated lvalue or struct member on 4 bytes +#define __ALIGN4 __attribute__((aligned(4))) + +/// __MODULE__ comes from the RVDS compiler that supports it +#define __MODULE__ __BASE_FILE__ + +/// Pack a structure field +#ifndef __PACKED +#define __PACKED __attribute__ ((__packed__)) +#endif + +/// Put a variable in a memory maintained during deep sleep +#define __LOWPOWER_SAVED + +#endif // _COMPILER_H_ diff --git a/services/ble_stack/ble_ip/rwapp_config.h b/services/ble_stack/ble_ip/rwapp_config.h new file mode 100644 index 0000000..3e68845 --- /dev/null +++ b/services/ble_stack/ble_ip/rwapp_config.h @@ -0,0 +1,207 @@ +#ifndef _RWAPP_CONFIG_H_ +#define _RWAPP_CONFIG_H_ + +/** + **************************************************************************************** + * @addtogroup app + * @brief Application configuration definition + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +/* + * DEFINES + **************************************************************************************** + */ + +/******************************************************************************************/ +/* ------------------------- BLE APPLICATION SETTINGS -----------------------------*/ +/******************************************************************************************/ +#define CFG_APP_DATAPATH_SERVER + +#define FAST_PAIR_REV_1_0 0 +#define FAST_PAIR_REV_2_0 1 +#define BLE_APP_GFPS_VER FAST_PAIR_REV_2_0 + +#ifdef GFPS_ENABLED +#if BLE_APP_GFPS_VER==FAST_PAIR_REV_2_0 + #define CFG_APP_GFPS + #ifndef CFG_APP_SEC + #define CFG_APP_SEC + #endif +#else + #undef CFG_APP_GFPS +#endif +#endif + +#if defined(BISTO_ENABLED) +#ifndef CFG_APP_SEC +#define CFG_APP_SEC +#endif +#endif + +#ifdef VOICE_DATAPATH +#define CFG_APP_VOICEPATH +#ifndef CFG_APP_SEC +#define CFG_APP_SEC +#endif +#endif + +#ifdef TILE_DATAPATH +#define CFG_APP_TILE +#endif + +#ifdef BES_OTA_BASIC +#define CFG_APP_OTA +#endif + +#ifdef BLE_TOTA_ENABLED +#define CFG_APP_TOTA +#endif + +#ifdef __AI_VOICE__ +#ifndef CFG_APP_SEC +#define CFG_APP_SEC +#endif +#ifndef CFG_SEC_CON +#define CFG_SEC_CON +#endif + +#define CFG_APP_AI_VOICE +#endif + +#if defined(VOICE_DATAPATH) && defined(BISTO_ENABLED) +#define ANCS_PROXY_ENABLE 1 +#else +#define ANCS_PROXY_ENABLE 0 +#endif + +#if ANCS_PROXY_ENABLE +#define CFG_APP_AMS +#define CFG_APP_ANCC +#endif + +#ifdef CHIP_FPGA1000 +#ifndef CFG_APP_SEC +#define CFG_APP_SEC +#endif +#endif +/// Health Thermometer Application +#if defined(CFG_APP_HT) +#define BLE_APP_HT 1 +#else // defined(CFG_APP_HT) +#define BLE_APP_HT 0 +#endif // defined(CFG_APP_HT) + +#if defined(CFG_APP_HR) +#define BLE_APP_HR 1 +#else +#define BLE_APP_HR 0 +#endif + +/// Data Path Server Application +#if defined(CFG_APP_DATAPATH_SERVER) +#define BLE_APP_DATAPATH_SERVER 1 +#else // defined(CFG_APP_DATAPATH_SERVER) +#define BLE_APP_DATAPATH_SERVER 0 +#endif // defined(CFG_APP_DATAPATH_SERVER) + +/// HID Application +#if defined(CFG_APP_HID) +#define BLE_APP_HID 1 +#else // defined(CFG_APP_HID) +#define BLE_APP_HID 0 +#endif // defined(CFG_APP_HID) + +/// DIS Application +#if defined(CFG_APP_DIS) +#define BLE_APP_DIS 1 +#else // defined(CFG_APP_DIS) +#define BLE_APP_DIS 0 +#endif // defined(CFG_APP_DIS) + +/// Time Application +#if defined(CFG_APP_TIME) +#define BLE_APP_TIME 1 +#else // defined(CFG_APP_TIME) +#define BLE_APP_TIME 0 +#endif // defined(CFG_APP_TIME) + +/// Battery Service Application +#if (BLE_APP_HID) +#define BLE_APP_BATT 1 +#else +#define BLE_APP_BATT 0 +#endif // (BLE_APP_HID) + +/// Security Application +#if (defined(CFG_APP_SEC) || BLE_APP_HID || defined(BLE_APP_AM0)) +#define BLE_APP_SEC 1 +#else // defined(CFG_APP_SEC) +#define BLE_APP_SEC 0 +#endif // defined(CFG_APP_SEC) + +/// Voice Path Application +#if defined(CFG_APP_VOICEPATH) +#define BLE_APP_VOICEPATH 1 +#else // defined(CFG_APP_VOICEPATH) +#define BLE_APP_VOICEPATH 0 +#endif // defined(CFG_APP_VOICEPATH) + +#if defined(CFG_APP_TILE) +#define BLE_APP_TILE 1 +#else // defined(CFG_APP_TILE) +#define BLE_APP_TILE 0 +#endif // defined(CFG_APP_TILE) + +/// OTA Application +#if defined(CFG_APP_OTA) +#define BLE_APP_OTA 1 +#else // defined(CFG_APP_OTA) +#define BLE_APP_OTA 0 +#endif // defined(CFG_APP_OTA) + +#if defined(CFG_APP_TOTA) +#define BLE_APP_TOTA 1 +#else // defined(CFG_APP_TOTA) +#define BLE_APP_TOTA 0 +#endif // defined(CFG_APP_TOTA) + +/// ANCC Application +#if defined(CFG_APP_ANCC) +#define BLE_APP_ANCC 1 +#else // defined(CFG_APP_ANCC) +#define BLE_APP_ANCC 0 +#endif // defined(CFG_APP_ANCC) + +/// AMS Application +#if defined(CFG_APP_AMS) +#define BLE_APP_AMS 1 +#else // defined(CFG_APP_AMS) +#define BLE_APP_AMS 0 +#endif // defined(CFG_APP_AMS) +/// GFPS Application +#if defined(CFG_APP_GFPS) +#define BLE_APP_GFPS 1 +#else // defined(CFG_APP_GFPS) +#define BLE_APP_GFPS 0 +#endif // defined(CFG_APP_GFPS) + + +/// AMA Voice Application +#if defined(CFG_APP_AI_VOICE) +#define BLE_APP_AI_VOICE 1 +#else // defined(CFG_APP_AMA) +#define BLE_APP_AI_VOICE 0 +#endif // defined(CFG_APP_AMA) + +/// @} rwapp_config + +#endif /* _RWAPP_CONFIG_H_ */ diff --git a/services/ble_stack/ble_ip/rwble_hl.h b/services/ble_stack/ble_ip/rwble_hl.h new file mode 100644 index 0000000..1c346b4 --- /dev/null +++ b/services/ble_stack/ble_ip/rwble_hl.h @@ -0,0 +1,47 @@ +#ifndef RWBLE_HL_H_ +#define RWBLE_HL_H_ + +#include + +/** + **************************************************************************************** + * @addtogroup ROOT + * @brief Entry points of the BLE Host stack + * + * This module contains the primitives that allow an application accessing and running the + * BLE protocol stack + * + * @{ + **************************************************************************************** + */ + + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Initialize the BLE Host stack. + **************************************************************************************** + */ +void rwble_hl_init(void); + +/** + **************************************************************************************** + * @brief Initialize the host (reset requested) + * + **************************************************************************************** + */ +void rwble_hl_reset(void); + +/// @} RWBLE_HL + +#endif // RWBLE_HL_H_ diff --git a/services/ble_stack/ble_ip/rwble_hl_config.h b/services/ble_stack/ble_ip/rwble_hl_config.h new file mode 100644 index 0000000..3d5a6c4 --- /dev/null +++ b/services/ble_stack/ble_ip/rwble_hl_config.h @@ -0,0 +1,253 @@ +#ifndef RWBLE_HL_CONFIG_H_ +#define RWBLE_HL_CONFIG_H_ + +#include "rwprf_config.h" +#include "rwapp_config.h" + +#define CFG_PRF +#define CFG_NB_PRF (BLE_APP_OTA + BLE_APP_GFPS + BLE_VOICEPATH + BLE_BMS + \ + BLE_ANC_CLIENT + BLE_AMS_CLIENT + (ANCS_PROXY_ENABLE ? 2 : 0) + \ + BLE_APP_DATAPATH_SERVER + BLE_AI_VOICE + BLE_APP_TOTA + BLE_APP_TILE) + +/** + **************************************************************************************** + * @addtogroup ROOT + * @{ + * @name BLE stack configuration + * @{ + **************************************************************************************** + */ + +#include "rwble_hl_error.h" + +/******************************************************************************************/ +/* ------------------------- BLE PARTITIONING -------------------------------------*/ +/******************************************************************************************/ + + +/******************************************************************************************/ +/* -------------------------- INTERFACES ----------------------------------------*/ +/******************************************************************************************/ + + +#if BLE_APP_PRESENT +#define APP_MAIN_TASK TASK_APP +#else // BLE_APP_PRESENT +#define APP_MAIN_TASK TASK_AHI +#endif // BLE_APP_PRESENT + +// Host Controller Interface (Host side) +#define BLEHL_HCIH_ITF HCIH_ITF + +/******************************************************************************************/ +/* -------------------------- COEX SETUP ----------------------------------------*/ +/******************************************************************************************/ + +///WLAN coex +#define BLEHL_WLAN_COEX RW_WLAN_COEX +///WLAN test mode +#define BLEHL_WLAN_COEX_TEST RW_WLAN_COEX_TEST + +/******************************************************************************************/ +/* -------------------------- HOST MODULES ----------------------------------------*/ +/******************************************************************************************/ + +#define BLE_GAPM 1 +#if (BLE_CENTRAL || BLE_PERIPHERAL) +#define BLE_GAPC 1 +#define BLE_GAPC_HEAP_ENV_SIZE (sizeof(struct gapc_env_tag) + KE_HEAP_MEM_RESERVED) +#else //(BLE_CENTRAL || BLE_PERIPHERAL) +#define BLE_GAPC 0 +#define BLE_GAPC_HEAP_ENV_SIZE 0 +#endif //(BLE_CENTRAL || BLE_PERIPHERAL) + +#if (BLE_CENTRAL || BLE_PERIPHERAL) +#define BLE_L2CM 1 +#define BLE_L2CC 1 +#define BLE_ATTM 1 +#define BLE_GATTM 1 +#define BLE_GATTC 1 +#define BLE_GATTC_HEAP_ENV_SIZE (sizeof(struct gattc_env_tag) + KE_HEAP_MEM_RESERVED) +#define BLE_L2CC_HEAP_ENV_SIZE (sizeof(struct l2cc_env_tag) + KE_HEAP_MEM_RESERVED) +#else //(BLE_CENTRAL || BLE_PERIPHERAL) +#define BLE_L2CM 0 +#define BLE_L2CC 0 +#define BLE_ATTC 0 +#define BLE_ATTS 0 +#define BLE_ATTM 0 +#define BLE_GATTM 0 +#define BLE_GATTC 0 +#define BLE_GATTC_HEAP_ENV_SIZE 0 +#define BLE_L2CC_HEAP_ENV_SIZE 0 +#endif //(BLE_CENTRAL || BLE_PERIPHERAL) + +#define BLE_SMPM 1 +#if (BLE_CENTRAL || BLE_PERIPHERAL) +#define BLE_SMPC 1 +#else //(BLE_CENTRAL || BLE_PERIPHERAL) +#define BLE_SMPC 0 +#endif //(BLE_CENTRAL || BLE_PERIPHERAL) + + +/******************************************************************************************/ +/* -------------------------- ATT DB ----------------------------------------*/ +/******************************************************************************************/ + +//ATT DB,Testing and Qualification related flags +#if (BLE_CENTRAL || BLE_PERIPHERAL) + /// Support of External DB Management + #if defined(CFG_EXT_DB) + #define BLE_EXT_ATT_DB 1 + #else + #define BLE_EXT_ATT_DB 0 + #endif // defined(CFG_EXT_DB) +#else + #define BLE_EXT_ATT_DB 0 +#endif // (BLE_CENTRAL || BLE_PERIPHERAL) +/******************************************************************************************/ +/* -------------------------- PROFILES ----------------------------------------*/ +/******************************************************************************************/ +#ifdef CFG_PRF +#define BLE_PROFILES (1) +/// Number of Profile tasks managed by GAP manager. +#define BLE_NB_PROFILES (CFG_NB_PRF) + +#include "rwprf_config.h" +#else +#define BLE_PROFILES (0) +#define BLE_NB_PROFILES (0) +#endif // CFG_PRF + + +#ifndef BLE_ATTS +#if (BLE_CENTRAL || BLE_PERIPHERAL || defined(CFG_ATTS)) +#define BLE_ATTS 1 +#else +#define BLE_ATTS 0 +#endif // (BLE_CENTRAL || BLE_PERIPHERAL || defined(CFG_ATTS)) +#endif // BLE_ATTS + + +#ifndef BLE_ATTC +#if (BLE_CENTRAL || defined(CFG_ATTC)) +#define BLE_ATTC 1 +#else +#define BLE_ATTC 0 +#endif // (BLE_CENTRAL || defined(CFG_ATTC)) +#endif // BLE_ATTC + +#ifndef BLE_LECB +#if (BLE_CENTRAL || BLE_PERIPHERAL) +#define BLE_LECB 1 +#else +#define BLE_LECB 0 +#endif // (BLE_CENTRAL || defined(CFG_ATTC)) +#endif // BLE_ATTC + + +/// Attribute Server +#if (BLE_ATTS) +#define BLE_ATTS 1 +#else +#define BLE_ATTS 0 +#endif //(BLE_ATTS) + + +/// Size of the heap +#if (BLE_CENTRAL || BLE_PERIPHERAL) + /// some heap must be reserved for attribute database + #if (BLE_ATTS || BLE_ATTC) + #define BLEHL_HEAP_DB_SIZE (1024) + #else + #define BLEHL_HEAP_DB_SIZE (0) + #endif /* (BLE_ATTS || BLE_ATTC) */ + +#define BLEHL_HEAP_MSG_SIZE (2048 + 256 * BLE_CONNECTION_MAX) +#else + #define BLEHL_HEAP_MSG_SIZE (256) + #define BLEHL_HEAP_DB_SIZE (0) +#endif /* #if (BLE_CENTRAL || BLE_PERIPHERAL) */ + + + + +/// Number of BLE HL tasks +#define BLEHL_TASK_SIZE BLE_HOST_TASK_SIZE + BLE_PRF_TASK_SIZE + +/// Size of environment variable needed on BLE Host Stack for one link +#define BLEHL_HEAP_ENV_SIZE ( BLE_GAPC_HEAP_ENV_SIZE + \ + BLE_GATTC_HEAP_ENV_SIZE + \ + BLE_L2CC_HEAP_ENV_SIZE) + + + + + + + +/* + * DEFINES - Mandatory for BLE Host Layers + **************************************************************************************** + */ +/// Maximum time to remain advertising when in the Limited +/// Discover able mode: TGAP(lim_adv_timeout) +/// required value: 180s: (18000 for ke timer) +#define GAP_TMR_LIM_ADV_TIMEOUT 0x4650 + +/// Minimum time to perform scanning when performing +/// the General Discovery procedure: TGAP(gen_disc_scan_min) +/// recommended value: 10.24s: (1024 for ke timer) +#define GAP_TMR_GEN_DISC_SCAN 0x0300 + +/// Minimum time to perform scanning when performing the +/// Limited Discovery procedure: TGAP(lim_disc_scan_min) +/// recommended value: 10.24s: (1024 for ke timer) +#define GAP_TMR_LIM_DISC_SCAN 0x0300 + +/// Minimum time interval between private address change +/// TGAP(private_addr_int) +/// recommended value: 15 minutes; 0x01F4 for PTS +/// 0x3A98 is 150 seconds; 0xEA60 is 10 minutes +#define GAP_TMR_PRIV_ADDR_INT 0x3A98 + + +/// Timer used in connection parameter update procedure +/// TGAP(conn_param_timeout) +/// recommended value: 30 s: (3000 for ke timer) +#define GAP_TMR_CONN_PARAM_TIMEOUT 0x0BB8 + +/// Timer used in LE credit based connection procedure +/// TGAP(lecb_conn_timeout) +/// recommended value: 30 s: (3000 for ke timer) +#define GAP_TMR_LECB_CONN_TIMEOUT 0x0BB8 + +/// Timer used in LE credit based disconnection procedure +/// TGAP(lecb_disconn_timeout) +/// recommended value: 30 s: (3000 for ke timer) +#define GAP_TMR_LECB_DISCONN_TIMEOUT 0x0BB8 + +/// Maximal authorized MTU value +#define GAP_MAX_LE_MTU (2048) + +/// Maximum GAP device name size +#define GAP_MAX_NAME_SIZE (0x20) + + + + +/// Maximum Transmission Unit +#define ATT_DEFAULT_MTU (23) +/// 30 seconds transaction timer +#define ATT_TRANS_RTX (0x0BB8) +/// Acceptable encryption key size - strict access +#define ATT_SEC_ENC_KEY_SIZE (0x10) + + +/// Maximum attribute value length +#define ATT_MAX_VALUE (GAP_MAX_LE_MTU) + + +/// @} BLE stack configuration +/// @} ROOT + +#endif // RWBLE_HL_CONFIG_H_ diff --git a/services/ble_stack/ble_ip/rwip.h b/services/ble_stack/ble_ip/rwip.h new file mode 100644 index 0000000..f21caa2 --- /dev/null +++ b/services/ble_stack/ble_ip/rwip.h @@ -0,0 +1,523 @@ +#ifndef _RWIP_H_ +#define _RWIP_H_ + +/** + **************************************************************************************** + * @addtogroup ROOT + * @brief Entry points of the RW IP stacks/modules + * + * This module contains the primitives that allow an application accessing and running the + * RW IP protocol stacks / modules. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" // stack configuration + +#include // standard integer definitions +#include // standard boolean definitions + + +/* + * DEFINES + **************************************************************************************** + */ +/// Maximum value of a Bluetooth clock (in 312.5us half slots) +#define RWIP_MAX_CLOCK_TIME ((1L<<32) - 1) +/// Maximum value of a 10ms Bluetooth clock +#define RWIP_MAX_10MS_TIME ((1L<<25) - 1) +/// retrieve 10ms time according to clock time +#define RWIP_CLOCK_TO_10MS_TIME(clock) ((clock) >> 5) +/// retrieve clock time according to 10ms time +#define RWIP_10MS_TIME_TO_CLOCK(time) ((time) << 5) +/// Invalid target time +#define RWIP_INVALID_TARGET_TIME (0xFFFFFFFFL) + + +/// result of sleep state. +enum rwip_sleep_state +{ + /// Some activity pending, can not enter in sleep state + RWIP_ACTIVE = 0, + /// CPU can be put in sleep state + RWIP_CPU_SLEEP, + /// IP could enter in deep sleep + RWIP_DEEP_SLEEP, +}; + + +/// Definition of the bits preventing the system from sleeping +enum prevent_sleep +{ + /// Flag indicating that the wake up process is ongoing + RW_WAKE_UP_ONGOING = 0x0001, + /// Flag indicating that an TX transfer is ongoing on Transport Layer + RW_TL_TX_ONGOING = 0x0002, + /// Flag indicating that an RX transfer is ongoing on Transport Layer + RW_TL_RX_ONGOING = 0x0004, + /// Flag indicating HCI timeout is ongoing + RW_AHI_TIMEOUT = 0x0008, + /// Flag indicating that an encryption is ongoing + RW_CRYPT_ONGOING = 0x0010, + /// Flag indicating that controller shall not sleep due to not CSB LPO_Allowed + RW_CSB_NOT_LPO_ALLOWED = 0x0040, + /// Flag indicating the MWS/WLAN Event Generator is in operation + RW_MWS_WLAN_EVENT_GENERATOR_ACTIVE = 0x0080, + /// Flag to indicate that platform does not support deep sleep + RW_PLF_DEEP_SLEEP_DISABLED = 0x0100, +}; + +/// Parameters - Possible Returned Status +enum PARAM_STATUS +{ + /// PARAM status OK + PARAM_OK, + /// generic PARAM status KO + PARAM_FAIL, + /// PARAM ID unrecognized + PARAM_ID_NOT_DEFINED, + /// No space for PARAM + PARAM_NO_SPACE_AVAILABLE, + /// Length violation + PARAM_LENGTH_OUT_OF_RANGE, + /// PARAM parameter locked + PARAM_PARAM_LOCKED, + /// PARAM corrupted + PARAM_CORRUPT +}; + +/** + * External interface type types. + */ +enum rwip_eif_types +{ + /// Host Controller Interface - Controller part + RWIP_EIF_HCIC, + + /// Host Controller Interface - Host part + RWIP_EIF_HCIH, + + /// Application Host interface + RWIP_EIF_AHI, +}; + + +/// Enumeration of External Interface status codes +enum rwip_eif_status +{ + /// EIF status OK + RWIP_EIF_STATUS_OK, + /// EIF status KO + RWIP_EIF_STATUS_ERROR, + +#if (BLE_EMB_PRESENT == 0) + /// External interface detached + RWIP_EIF_STATUS_DETACHED, + /// External interface attached + RWIP_EIF_STATUS_ATTACHED, +#endif // (BLE_EMB_PRESENT == 0) +}; + +/// Enumeration of RF modulations +enum rwip_rf_mod +{ + MOD_GFSK = 0x01, + MOD_DQPSK = 0x02, + MOD_8DPSK = 0x03, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Time information +typedef struct +{ + /// Time in 312.5 us step. + uint32_t time; + /// number of half us before getting next tick + uint32_t next_tick; +} rwip_time_t; + + + +/// 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 + uint8_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)(uint16_t); + /// Function used to write a RF register + void (*reg_wr)(uint16_t, uint32_t); + /// Function called to put the RF in deep sleep mode + void (*sleep)(void); + /// 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; +}; + +/// API functions of the parameters that are used by the BLE or BT software +struct rwip_param_api +{ + /** + * Get a parameter value + * @param[in] param_id Parameter identifier + * @param[in/out] lengthPtr Pointer to the length of the parameter (input: contain max length, output contain the effective param length) + * @param[out] buf Pointer to the buffer be filled with the parameter value + * @return status 0: success | >0 : error + */ + uint8_t (*get) (uint8_t param_id, uint8_t * lengthPtr, uint8_t *buf); + + /** + * Set a parameter value + * @param[in] param_id Parameter identifier + * @param[in/out] length Length of the parameter + * @param[out] buf Pointer to the buffer containing the parameter value + * @return status 0: success | >0 : error + */ + uint8_t (*set) (uint8_t param_id, uint8_t length, uint8_t *buf); + + /** + * Delete a parameter + * @param[in] param_id Parameter identifier + * @return status 0: success | >0 : error + */ + uint8_t (*del) (uint8_t param_id); +}; + +/// Internal API for priority +struct rwip_prio +{ + ///value + uint8_t value; + ///Increment + uint8_t increment; +}; +/** + **************************************************************************************** + * @brief Function called when packet transmission/reception is finished. + + * @param[in] dummy Dummy data pointer returned to callback when operation is over. + * @param[in] status Ok if action correctly performed, else reason status code. + ***************************************************************************************** + */ +typedef void (*rwip_eif_callback) (void*, uint8_t); + +/** + * Transport layer communication interface. + */ +struct rwip_eif_api +{ + /** + ************************************************************************************* + * @brief Starts a data reception. + * + * @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 (*read) (uint8_t *bufptr, uint32_t size, rwip_eif_callback callback, void* dummy); + + /** + ************************************************************************************* + * @brief Starts a data transmission. + * + * @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 (*write)(uint8_t *bufptr, uint32_t size, rwip_eif_callback callback, void* dummy); + + /** + ************************************************************************************* + * @brief Enable Interface flow. + ************************************************************************************* + */ + void (*flow_on)(void); + + /** + ************************************************************************************* + * @brief Disable Interface flow. + * + * @return True if flow has been disabled, False else. + ************************************************************************************* + */ + bool (*flow_off)(void); +}; + +/* + * VARIABLE DECLARATION +***************************************************************************************** + */ + +/// API for RF driver +extern struct rwip_rf_api rwip_rf; +/// API for parameters +extern struct rwip_param_api rwip_param; +#if (BLE_EMB_PRESENT || BT_EMB_PRESENT) +/// API for dual mode priority +extern const struct rwip_prio rwip_priority[RWIP_PRIO_IDX_MAX]; +#endif //#if (BLE_EMB_PRESENT || BT_EMB_PRESENT) + +#if (BT_EMB_PRESENT || BLE_EMB_PRESENT) +#if (RW_WLAN_COEX) +/// API for COEX configuration +extern const uint8_t rwip_coex_cfg[RWIP_COEX_CFG_MAX]; +#endif //(RW_WLAN_COEX) +#endif //(BT_EMB_PRESENT || BLE_EMB_PRESENT) + +/* + * MACROS + **************************************************************************************** + */ + +/// Get Event status flag +#if (BT_EMB_PRESENT || BLE_EMB_PRESENT) +#if (RW_WLAN_COEX) +#define RWIP_COEX_GET(coex_cfg_idx, bit_field) \ + (uint8_t)(((rwip_coex_cfg[RWIP_COEX_ ## coex_cfg_idx ##_IDX]) >> RWIP_ ## bit_field ## _POS ) & RWIP_COEX_BIT_MASK) +#else //(RW_WLAN_COEX) +#define RWIP_COEX_GET(coex_cfg_idx, bit_field) 0 +#endif //(RW_WLAN_COEX) +#endif //(BT_EMB_PRESENT || BLE_EMB_PRESENT) + +/* + * FUNCTION DECLARATION +***************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initializes the RW BT SW. + * + **************************************************************************************** + */ +void rwip_init(uint32_t error); + +/** + **************************************************************************************** + * @brief Reset the RW BT SW. + * + **************************************************************************************** + */ +void rwip_reset(void); + + + +#if (BT_EMB_PRESENT) + +#if PCA_SUPPORT +/** + **************************************************************************************** + * @brief Check if clock dragging limitation + * + * @return true if clock dragging must be used + **************************************************************************************** + */ +bool rwip_pca_clock_dragging_only(void); +#endif //PCA_SUPPORT +#endif // (BT_EMB_PRESENT) + +#if (BT_EMB_PRESENT || BLE_EMB_PRESENT) +#if (RW_MWS_COEX) +/** + **************************************************************************************** + * @brief Enable/Disable the MWS coexistence interface. + * + * @param[in] CoexSetting Coexistence value + * + **************************************************************************************** + */ +//void rwip_mwscoex_set(bool state); +#endif //RW_MWS_COEX + +#if (RW_WLAN_COEX) +/** + **************************************************************************************** + * @brief Enable/Disable the Wireless LAN coexistence interface. + * + * @param[in] CoexSetting Coexistence value + * + **************************************************************************************** + */ +//void rwip_wlcoex_set(bool state); +#endif //RW_WLAN_COEX +#endif //(BT_EMB_PRESENT || BLE_EMB_PRESENT) + +/** + **************************************************************************************** + * @brief Function to implement in platform in order to retrieve expected external + * interface such as UART for Host Control Interface. + * + * @param[in] type external interface type (@see rwip_eif_types) + * + * @return External interface api structure + **************************************************************************************** + */ +extern const struct rwip_eif_api* rwip_eif_get(uint8_t type); + +#if RW_DEBUG +/** + **************************************************************************************** + * @brief Raises an assertion message to the control interface (if present) + * + * @param[in] file File name + * @param[in] line Line number + * @param[in] param0 Parameter 0 (custom value given by the assert instruction) + * @param[in] param1 Parameter 1 (custom value given by the assert instruction) + **************************************************************************************** + */ +void rwip_assert_err(const char * file, int line, int param0, int param1); +#endif //RW_DEBUG + + +/* ************************************************************************************** + * Driver functions + * ************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieved sampled current time in half slot and next tick time in half us. + * + * @note Shall be called within a critical section + * + * @return current time sampled (@see rwip_time_t) + **************************************************************************************** + */ +rwip_time_t rwip_time_get(void); + + +/** + **************************************************************************************** + * @brief Set the a 10 ms target timer + * + * @note if target is RWIP_INVALID_TARGET_TIME, not timer are programmed + * + * @param[in] target 10ms Timer target value + **************************************************************************************** + */ +void rwip_timer_10ms_set(uint32_t target); + +/** + **************************************************************************************** + * @brief Set the a half slot target timer + * + * @note if target is RWIP_INVALID_TARGET_TIME, not timer are programmed + * + * @param[in] target Half Slot Timer target value + **************************************************************************************** + */ +void rwip_timer_hs_set(uint32_t target); + +/** + **************************************************************************************** + * @brief Gives FW/HW versions of RW-BT stack. + * + **************************************************************************************** + */ +//void rwip_version(uint8_t* fw_version, uint8_t* hw_version); + +/** + **************************************************************************************** + * @brief Start AES encryption + * + * The exchange memory must be filled before calling this function. + * This function expect to be called from a BLE Module + * + * @param[in] key AES Encryption key must be 16 bytes + * @param[in] data_em_ptr Exchange memory data pointer of data to encrypt + **************************************************************************************** + */ +//void rwip_aes_encrypt(uint8_t *key, uint16_t data_em_ptr); + +/** + **************************************************************************************** + * @brief Request a Software interrupt to be triggered + **************************************************************************************** + */ +//void rwip_sw_int_req(void); + +/** + **************************************************************************************** + * @brief Schedule all pending events. + * + **************************************************************************************** + */ +//void rwip_schedule(void); + +/** + **************************************************************************************** + * @brief Invoke the sleep function. + * + * @return sleep status (@see enum rwip_sleep_state) + **************************************************************************************** + */ +//uint8_t rwip_sleep(void); + +/** + **************************************************************************************** + * @brief Handle the common core interrupts. + * + * @param[in] current IRQ status + **************************************************************************************** + */ +//void rwip_isr(uint32_t irq_stat); + +/** + **************************************************************************************** + * @brief Set a bit in the prevent sleep bit field, in order to prevent the system from + * going to sleep + * + * @param[in] prv_slp_bit Bit to be set in the prevent sleep bit field + **************************************************************************************** + */ +//void rwip_prevent_sleep_set(uint16_t prv_slp_bit); + +/** + **************************************************************************************** + * @brief Clears a bit in the prevent sleep bit field, in order to allow the system + * going to sleep + * + * @param[in] prv_slp_bit Bit to be cleared in the prevent sleep bit field + **************************************************************************************** + */ +//void rwip_prevent_sleep_clear(uint16_t prv_slp_bit); + +///@} ROOT + +#endif // _RWIP_H_ diff --git a/services/ble_stack/ble_ip/rwip_config.h b/services/ble_stack/ble_ip/rwip_config.h new file mode 100644 index 0000000..14eec4f --- /dev/null +++ b/services/ble_stack/ble_ip/rwip_config.h @@ -0,0 +1,1035 @@ +#ifndef RWIP_CONFIG_H_ +#define RWIP_CONFIG_H_ + +/** + **************************************************************************************** + * @addtogroup ROOT + * @{ + * + * Information about RW SW IP options and flags + * + * BT_DUAL_MODE BT/BLE Dual Mode + * BT_STD_MODE BT Only + * BLE_STD_MODE BLE Only + * + * BT_EMB_PRESENT BT controller exists + * BLE_EMB_PRESENT BLE controller exists + * BLE_HOST_PRESENT BLE host exists + * + * @name RW Stack Configuration + * @{ + **************************************************************************************** + */ + +/* + * DEFINES + **************************************************************************************** + */ +#include "rwapp_config.h" // Audio Mode 0 configuration +#include "os_api.h" +#include "cmsis.h" +#include "besble_debug.h" + +//#if (__IAG_BLE_INCLUDE__ == XA_ENABLED) + +#ifdef __IAG_BLE_INCLUDE__ +#ifndef FPGA +#define _BLE_NVDS_ +#endif +#define CFG_BLE +#define CFG_HOST +#define CFG_APP + +#if defined(BISTO_ENABLED) +#ifndef CFG_APP_SEC +#define CFG_APP_SEC +#endif + +#define CFG_SEC_CON +#endif +#endif + +#define GLOBAL_INT_DISABLE() do { uint32_t lock = int_lock(); +#define GLOBAL_INT_RESTORE() int_unlock(lock); } while(0); + +/******************************************************************************************/ +/* -------------------------- GENERAL SETUP --------------------------------------*/ +/******************************************************************************************/ + +/// Flag indicating if stack is compiled in dual or single mode +#if defined(CFG_BT) + #define BLE_STD_MODE 0 + #if defined(CFG_BLE) + #define BT_DUAL_MODE 1 + #define BT_STD_MODE 0 + #else // CFG_BLE + #define BT_DUAL_MODE 0 + #define BT_STD_MODE 1 + #endif // CFG_BLE +#elif defined(CFG_BLE) + #define BT_DUAL_MODE 0 + #define BT_STD_MODE 0 + #define BLE_STD_MODE 1 +#endif // CFG_BT + +/******************************************************************************************/ +/* ------------------------- STACK PARTITIONING -----------------------------------*/ +/******************************************************************************************/ + +#if (BT_DUAL_MODE) + #define BT_EMB_PRESENT 1 + #define BLE_EMB_PRESENT 1 + #define HCI_PRESENT 1 + #define BLE_HOST_PRESENT 0 + #define BLE_APP_PRESENT 0 +#elif (BT_STD_MODE) + #define BT_EMB_PRESENT 1 + #define BLE_EMB_PRESENT 0 + #define HCI_PRESENT 1 + #define BLE_HOST_PRESENT 0 + #define BLE_APP_PRESENT 0 +#elif (BLE_STD_MODE) + #define BT_EMB_PRESENT 0 + #define HCI_PRESENT 1 + #if defined(CFG_EMB) + #define BLE_EMB_PRESENT 1 + #else + #define BLE_EMB_PRESENT 0 + #endif //CFG_EMB + #if defined(CFG_HOST) + #define BLE_HOST_PRESENT 1 + #else + #define BLE_HOST_PRESENT 0 + #endif //CFG_HOST + #if defined(CFG_APP) + #define BLE_APP_PRESENT 1 + #else + #define BLE_APP_PRESENT 0 + #endif //CFG_APP +#endif // BT_DUAL_MODE / BT_STD_MODE / BLE_STD_MODE + +#define EA_PRESENT (BT_EMB_PRESENT || BLE_EMB_PRESENT) + +/******************************************************************************************/ +/* ------------------------- INTERFACES DEFINITIONS -------------------------------*/ +/******************************************************************************************/ +#define CFG_AHITL +#define CFG_HCITL + +/// Application Host Interface +#if defined(CFG_AHITL) +#define AHI_TL_SUPPORT 1 +#else // defined(CFG_AHITL) +#define AHI_TL_SUPPORT 0 +#endif // defined(CFG_AHITL) + + +/// Host Controller Interface Support (defines if HCI parser is present or not) +#if defined(CFG_HCITL) +#define HCI_TL_SUPPORT 1 +#else //defined(CFG_HCITL) +#define HCI_TL_SUPPORT 0 +#endif //defined(CFG_HCITL) + + +#if BLE_HOST_PRESENT +#if BLE_EMB_PRESENT +#define H4TL_SUPPORT (AHI_TL_SUPPORT) +#else // !BLE_EMB_PRESENT +#define H4TL_SUPPORT 0//((AHI_TL_SUPPORT) + (HCI_TL_SUPPORT)) +#endif // BLE_EMB_PRESENT +#else // !BLE_HOST_PRESENT +#define H4TL_SUPPORT (HCI_TL_SUPPORT) +#endif // BLE_HOST_PRESENT + +/// TCI LMP trace support +#define TCI_LMP_ENABLED 0 + +/******************************************************************************************/ +/* -------------------------- BLE COMMON DEFINITIONS ------------------------------*/ +/******************************************************************************************/ +/// Kernel Heap memory sized reserved for allocate dynamically connection environment +#define KE_HEAP_MEM_RESERVED (4) + +#define CFG_ALLROLES + +#if defined(CFG_BLE) +/// Application role definitions +#define BLE_BROADCASTER (defined(CFG_BROADCASTER) || defined(CFG_PERIPHERAL) || defined(CFG_ALLROLES)) +#define BLE_OBSERVER (defined(CFG_OBSERVER) || defined(CFG_CENTRAL) || defined(CFG_ALLROLES)) +#define BLE_PERIPHERAL (defined(CFG_PERIPHERAL) || defined(CFG_ALLROLES)) +#define BLE_CENTRAL (defined(CFG_CENTRAL) || defined(CFG_ALLROLES)) + +#if (!BLE_BROADCASTER) && (!BLE_OBSERVER) && (!BLE_PERIPHERAL) && (!BLE_CENTRAL) + #error "No application role defined" +#endif /* #if (!BLE_BROADCASTER) && (!BLE_OBSERVER) && (!BLE_PERIPHERAL) && (!BLE_CENTRAL) */ + +/// Maximum number of simultaneous BLE activities (scan, connection, advertising, initiating) +#define BLE_ACTIVITY_MAX (BLE_CONNECTION_MAX) + +/// Maximum number of audio connections +#if defined(CFG_AUDIO) +#if (BLE_CENTRAL || BLE_PERIPHERAL) +#define BLE_AUDIO (1) +#define BLE_AUDIO_CONNECT_MAX (CFG_AUDIO_CON) +#else +#define BLE_AUDIO (0) +#endif /*(BLE_CENTRAL || BLE_PERIPHERAL)*/ +#else +#define BLE_AUDIO (0) +#endif /*defined(CFG_AUDIO)*/ + +/// Max advertising reports before sending the info to the host +#define BLE_ADV_REPORTS_MAX 1 + +/// Define Number of AUDIO TX/RX buffers per voice channel +#if (BLE_AUDIO) + #if defined(CFG_AUDIO_AOAHI) + // 3 buffers per connection using audio over AHI TL + #define BLE_NB_INPUT_BUFF_PER_VC (3) + #define BLE_NB_OUTPUT_BUFF_PER_VC (3) + #else // defined(CFG_AUDIO_AOAHI) + // 2 buffers if a codec is available + #define BLE_NB_INPUT_BUFF_PER_VC (2) + #define BLE_NB_OUTPUT_BUFF_PER_VC (2) + #endif // defined(CFG_AUDIO_AOAHI) + // add one more buffer for fake reception and fake transmit + #define BLE_TX_AUDIO_BUFFER_CNT ((BLE_AUDIO_CONNECT_MAX * BLE_NB_INPUT_BUFF_PER_VC) + 1) + #define BLE_RX_AUDIO_BUFFER_CNT ((BLE_AUDIO_CONNECT_MAX * BLE_NB_OUTPUT_BUFF_PER_VC) + 1) +#endif // (BLE_AUDIO) + +#define CFG_DEPRECATED_API +/// Support of Legacy Air Operations +#if defined(CFG_DEPRECATED_API) +#define BLE_DEPRECATED_API (1) +#else //defined(CFG_DEPRECATED_API) +#define BLE_DEPRECATED_API (0) +#endif //defined(CFG_DEPRECATED_API) +#endif //defined(CFG_BLE) + + +/******************************************************************************************/ +/* -------------------------- DISPLAY SETUP -------------------------------------*/ +/******************************************************************************************/ + +/// Display controller enable/disable +#if defined(CFG_DISPLAY) +#define DISPLAY_SUPPORT 1 +#else +#define DISPLAY_SUPPORT 0 +#endif //CFG_DISPLAY + + +/******************************************************************************************/ +/* -------------------------- RTC SETUP -------------------------------------*/ +/******************************************************************************************/ + +/// RTC enable/disable +#if defined(CFG_RTC) +#define RTC_SUPPORT 1 +#else +#define RTC_SUPPORT 0 +#endif //CFG_DISPLAY + +/******************************************************************************************/ +/* -------------------------- PS2 SETUP -------------------------------------*/ +/******************************************************************************************/ + +/// PS2 enable/disable +#if defined(CFG_PS2) +#define PS2_SUPPORT 1 +#else +#define PS2_SUPPORT 0 +#endif //CFG_PS2 + +/******************************************************************************************/ +/* -------------------------- TRACER SETUP -------------------------------------*/ +/******************************************************************************************/ + +/// tracer enable/disable +#if defined(CFG_TRC_EN) + #define TRACER_PRESENT 1 + #include "dbg_trc_config.h" +#else + #define TRACER_PRESENT 0 +#endif // CFG_TRC_EN + +/******************************************************************************************/ +/* ------------------------- DEEP SLEEP SETUP -------------------------------------*/ +/******************************************************************************************/ + +/// Use 32K Hz Clock if set to 1 else 32,768k is used +#define HZ32000 0 + +/// Time to wake-up Radio Module (in us) +#define SLEEP_RM_WAKEUP_DELAY 625 +/// Time for stabilization of the high frequency oscillator following a sleep-timer expiry (in us) +#define SLEEP_OSC_NORMAL_WAKEUP_DELAY 5000 +/// Time for stabilization of the high frequency oscillator following an external wake-up request (in us) +#define SLEEP_OSC_EXT_WAKEUP_DELAY 5000 + +/******************************************************************************************/ +/* -------------------------- RADIO SETUP ----------------------------------------*/ +/******************************************************************************************/ + +/// Power control features +#define RF_TXPWR 1 +/// Class of device +#define RF_CLASS1 0 + +/******************************************************************************************/ +/* ------------------------- SUPPORTED RADIO PHY ------------------------------------*/ +/******************************************************************************************/ + +#if defined(CFG_RF_ATLAS) +#define BLE_PHY_1MBPS_SUPPORT 1 +#define BLE_PHY_2MBPS_SUPPORT 1 +#define BLE_PHY_CODED_SUPPORT 0 +#else +#define BLE_PHY_1MBPS_SUPPORT 1 +#define BLE_PHY_2MBPS_SUPPORT 1 +#define BLE_PHY_CODED_SUPPORT 1 +#endif + +/******************************************************************************************/ +/* ------------------------- COEXISTENCE SETUP ------------------------------------*/ +/******************************************************************************************/ + +/// WLAN Coexistence +#if defined(CFG_WLAN_COEX) + #define RW_WLAN_COEX 1 + #define RW_WLAN_COEX_TEST (defined(CFG_WLAN_COEX_TEST)) +#else + #define RW_WLAN_COEX 0 + #define RW_WLAN_COEX_TEST 0 +#endif // defined(CFG_WLAN_COEX) + +/// MWS Coexistence +#if defined(CFG_MWS_COEX) + #define RW_MWS_COEX 1 + #define RW_MWS_COEX_TEST (defined(CFG_MWS_COEX_TEST)) +#else + #define RW_MWS_COEX 0 + #define RW_MWS_COEX_TEST 0 +#endif // defined(CFG_MWS_COEX) + +/******************************************************************************************/ +/* ------------------------- DM ARBITRATION SETUP ---------------------------------*/ +/******************************************************************************************/ + +#if BT_DUAL_MODE +/** + * Dual mode arbitration margin (in us) + * + * BREDRMARGIN/BLEMARGIN corresponding to a timing value that allows the RF to power-down properly before any other + * activity. This is radio dependent. + */ +#define DM_ARB_MARGIN 40 +#endif //BT_DUAL_MODE + +/******************************************************************************************/ +/* -------------------- SECURE CONNECTIONS SETUP --------------------------------------*/ +/******************************************************************************************/ +#define SECURE_CONNECTIONS (1) +#if defined(CFG_ECC_16_BITS_ALGO) +#define ECC_MULT_ALGO_TYPE (16) +#else // !defined(CFG_ECC_16_BITS_ALGO) +#define ECC_MULT_ALGO_TYPE (32) +#endif // defined(CFG_ECC_16_BITS_ALGO) +#if defined(CFG_CRYPTO_UT) +#define CRYPTO_UT (1) +#else //defined(CFG_CRYPTO_UT) +#define CRYPTO_UT (0) +#endif //defined(CFG_CRYPTO_UT) + +/******************************************************************************************/ +/* -------------------------- DEBUG SETUP ----------------------------------------*/ +/******************************************************************************************/ + +/// Flag indicating if debug mode is activated or not +#if defined(CFG_DBG) + #define RW_DEBUG ((BLE_EMB_PRESENT) || (BT_EMB_PRESENT) || (BLE_HOST_PRESENT)) +#if (BLE_EMB_PRESENT || BT_EMB_PRESENT) + #define RW_SWDIAG 1 +#else + #define RW_SWDIAG 0 +#endif + #define KE_PROFILING 1 +#else + #define RW_DEBUG 0 + #define RW_SWDIAG 0 + #define KE_PROFILING 0 +#endif /* CFG_DBG */ + +/// Flag indicating if Read/Write memory commands are supported or not +#if defined(CFG_DBG_MEM) + #define RW_DEBUG_MEM 1 +#else //CFG_DBG_MEM + #define RW_DEBUG_MEM 0 +#endif //CFG_DBG_MEM + +/// Flag indicating if Flash debug commands are supported or not +#if defined(CFG_DBG_FLASH) + #define RW_DEBUG_FLASH 1 +#else //CFG_DBG_FLASH + #define RW_DEBUG_FLASH 0 +#endif //CFG_DBG_FLASH + +/// Flag indicating if CPU stack profiling commands are supported or not +#if defined(CFG_DBG_STACK_PROF) + #define RW_DEBUG_STACK_PROF 1 +#else + #define RW_DEBUG_STACK_PROF 0 +#endif // defined (CFG_DBG_STACK_PROF) + +/// Modem back to back setup +#define MODEM2MODEM 0 +/// Special clock testing +#define CLK_WRAPPING 0 + +/******************************************************************************************/ +/* -------------------------- NVDS SETUP --------------------------------------*/ +/******************************************************************************************/ + +/// Flag indicating if NVDS feature is supported or not +#if defined(CFG_NVDS) + #define NVDS_SUPPORT 1 +#else //CFG_DBG_NVDS + #define NVDS_SUPPORT 0 +#endif //CFG_DBG_NVDS + +/******************************************************************************************/ +/* -------------------------- MISC SETUP --------------------------------------*/ +/******************************************************************************************/ +/// Manufacturer: RivieraWaves SAS +#define RW_COMP_ID 0x0060 + +/// Bluetooth technologies version +#define RW_BT40_VERSION (6) +#define RW_BT41_VERSION (7) +#define RW_BT42_VERSION (8) +#define RW_BT50_VERSION (9) + +/******************************************************************************************/ +/* ------------------------- BT / BLE / BLE HL CONFIG -------------------------------*/ +/******************************************************************************************/ + +#if 0 +#if (BT_EMB_PRESENT) +#include "rwbt_config.h" // bt stack configuration +#endif //BT_EMB_PRESENT + +#if (BLE_EMB_PRESENT) +#include "rwble_config.h" // ble stack configuration +#endif //BLE_EMB_PRESENT +#endif + +#if (BLE_HOST_PRESENT) +#include "rwble_hl_config.h" // ble Host stack configuration +#endif //BLE_HOST_PRESENT + +#if defined(CFG_AUDIO_AM0) +#include "rwam0_config.h" // Audio Mode 0 configuration +#endif // defined(CFG_AUDIO_AM0) + +#if defined(CFG_APP) +//#include "rwapp_config.h" // Audio Mode 0 configuration +#endif // defined(CFG_APP) + +#define BLE_INVALID_CONNECTION_INDEX 0xFF + + + +#define SV_HIGH_SPEED_BLE_CONNECTION_INTERVAL_MIN_IN_MS 80 +#define SV_HIGH_SPEED_BLE_CONNECTION_INTERVAL_MAX_IN_MS 400 +#define SV_HIGH_SPEED_BLE_CONNECTION_SUPERVISOR_TIMEOUT_IN_MS 20000 + +#define SV_LOW_SPEED_BLE_CONNECTION_INTERVAL_MIN_IN_MS 400 +#define SV_LOW_SPEED_BLE_CONNECTION_INTERVAL_MAX_IN_MS 1000 +#define SV_LOW_SPEED_BLE_CONNECTION_SUPERVISOR_TIMEOUT_IN_MS 20000 + + +/******************************************************************************************/ +/* ------------------------- KERNEL SETUP -------------------------------------*/ +/******************************************************************************************/ + +/// Event types definition +enum KE_EVENT_TYPE +{ + KE_EVENT_KE_MESSAGE , + KE_EVENT_KE_TIMER , + #if (TRACER_PRESENT) + KE_EVENT_TRC , + #endif /*(TRACER_PRESENT)*/ + + #if (AHI_TL_SUPPORT) + KE_EVENT_AHI_TX_DONE , + #endif //(AHI_TL_SUPPORT) + + #if (BLE_HOST_PRESENT) + #if (BLE_L2CC) + KE_EVENT_L2CAP_TX , + #endif //(BLE_L2CC) + #endif// (BLE_HOST_PRESENT) + + KE_EVENT_MAX , +}; + +/// Tasks types definition +enum KE_TASK_TYPE +{ +#if (BLE_APP_PRESENT) + TASK_APP, +#endif // (BLE_APP_PRESENT) + +#if (BLE_HOST_PRESENT) + TASK_L2CC, // L2CAP Controller Task + TASK_GATTM, // Generic Attribute Profile Manager Task + TASK_GATTC, // Generic Attribute Profile Controller Task + TASK_GAPM, // Generic Access Profile Manager, 4 + TASK_GAPC, // Generic Access Profile Controller + + // allocate a certain number of profiles task + TASK_PRF_MAX = (TASK_GAPC + BLE_NB_PROFILES), + + #ifdef BLE_AUDIO_AM0_TASK + TASK_AM0, // BLE Audio Mode 0 Task + #endif // BLE_AUDIO_AM0_TASK +#endif // (BLE_HOST_PRESENT) + +#if (AHI_TL_SUPPORT) + TASK_AHI, +#endif // (AHI_TL_SUPPORT) + + /// Maximum number of tasks + TASK_MAX = 0xFE, + + TASK_NONE = 0xFF, +}; + +/// Kernel memory heaps types. +enum +{ + /// Memory allocated for environment variables + KE_MEM_ENV, + #if (BLE_HOST_PRESENT) + /// Memory allocated for Attribute database + KE_MEM_ATT_DB, + #endif // (BLE_HOST_PRESENT) + /// Memory allocated for kernel messages + KE_MEM_KE_MSG, + /// Non Retention memory block + KE_MEM_NON_RETENTION, + KE_MEM_BLOCK_MAX, +}; + + + +#if (BT_EMB_PRESENT) +#define BT_HEAP_MSG_SIZE_ BT_HEAP_MSG_SIZE +#define BT_HEAP_ENV_SIZE_ BT_HEAP_ENV_SIZE +#else +#define BT_HEAP_MSG_SIZE_ 0 +#define BT_HEAP_ENV_SIZE_ 0 +#endif //BT_EMB_PRESENT + +#if (BLE_EMB_PRESENT) +#define BLE_HEAP_MSG_SIZE_ BLE_HEAP_MSG_SIZE +#define BLE_HEAP_ENV_SIZE_ BLE_HEAP_ENV_SIZE +#else +#define BLE_HEAP_MSG_SIZE_ 0 +#define BLE_HEAP_ENV_SIZE_ 0 +#endif //BLE_EMB_PRESENT + +#if (BLE_HOST_PRESENT) +#define BLEHL_HEAP_MSG_SIZE_ BLEHL_HEAP_MSG_SIZE +#define BLEHL_HEAP_ENV_SIZE_ BLEHL_HEAP_ENV_SIZE +#define BLEHL_HEAP_DB_SIZE_ BLEHL_HEAP_DB_SIZE +#else +#define BLEHL_HEAP_MSG_SIZE_ 0 +#define BLEHL_HEAP_ENV_SIZE_ 0 +#define BLEHL_HEAP_DB_SIZE_ 0 +#endif //BLE_HOST_PRESENT + + +/// Kernel Message Heap +#define RWIP_HEAP_MSG_SIZE ( BT_HEAP_MSG_SIZE_ + \ + BLE_HEAP_MSG_SIZE_ + \ + BLEHL_HEAP_MSG_SIZE_ ) + +/// Number of link in kernel environment +#define KE_NB_LINK_IN_HEAP_ENV 4 + +/// Size of Environment heap +#define RWIP_HEAP_ENV_SIZE ( BT_HEAP_ENV_SIZE_ + \ + ( BLE_HEAP_ENV_SIZE_ + \ + BLEHL_HEAP_ENV_SIZE_ ) \ + * KE_NB_LINK_IN_HEAP_ENV ) + +/// Size of Attribute database heap +#define RWIP_HEAP_DB_SIZE ( BLEHL_HEAP_DB_SIZE ) + +/// Size of non retention heap - 512 bytes per ble link plus 4096 bytes for data throughput should be sufficient and should be tuned +#if (BLE_EMB_PRESENT || BLE_HOST_PRESENT) +#define RWIP_HEAP_NON_RET_SIZE (( 512 * BLE_CONNECTION_MAX ) + 4096) +#else +#define RWIP_HEAP_NON_RET_SIZE ( 1024 ) +#endif + +/// Minimum sleep time to enter in deep sleep (in half slot). +#define RWIP_MINIMUM_SLEEP_TIME (1) + +/******************************************************************************************/ +/* ------------------------- CONFIGURABLE PARAMETERS -----------------------------*/ +/******************************************************************************************/ + +/// List of parameters identifiers +enum PARAM_ID +{ + /// Definition of the tag associated to each parameters + /// Local Bd Address + PARAM_ID_BD_ADDRESS = 0x01, + /// Device Name + PARAM_ID_DEVICE_NAME = 0x02, + /// Radio Drift + PARAM_ID_LPCLK_DRIFT = 0x07, + /// Radio Jitter + PARAM_ID_LPCLK_JITTER = 0x08, + /// Radio Class + PARAM_ID_RADIO_CLASS = 0x09, + /// Bluejay specific Settings + PARAM_ID_BJ_TXCNTL1 = 0x0A, + /// External wake-up time + PARAM_ID_EXT_WAKEUP_TIME = 0x0D, + /// Oscillator wake-up time + PARAM_ID_OSC_WAKEUP_TIME = 0x0E, + /// Radio wake-up time + PARAM_ID_RM_WAKEUP_TIME = 0x0F, + /// UART baudrate + PARAM_ID_UART_BAUDRATE = 0x10, + /// Enable sleep mode + PARAM_ID_SLEEP_ENABLE = 0x11, + /// Enable External Wakeup + PARAM_ID_EXT_WAKEUP_ENABLE = 0x12, + /// SP Private Key 192 + PARAM_ID_SP_PRIVATE_KEY_P192 = 0x13, + /// SP Public Key 192 + PARAM_ID_SP_PUBLIC_KEY_P192 = 0x14, + /// Errata adopted check + PARAM_ID_ERRATA_ADOPTED = 0x15, + /// CQDDR Tags + PARAM_ID_BASIC_THRESHOLD = 0x16, + PARAM_ID_EDR_THRESHOLD = 0x17, + PARAM_ID_BASIC_ALGORITHM = 0x18, + PARAM_ID_EDR_ALGORITHM = 0x19, + PARAM_ID_BASIC_PACKET_LUT = 0x2A, + PARAM_ID_EDR_PACKET_LUT = 0x2B, + /// Synchronous links configuration + PARAM_ID_SYNC_CONFIG = 0x2C, + /// PCM Settings + PARAM_ID_PCM_SETTINGS = 0x2D, + /// Sleep algorithm duration + PARAM_ID_SLEEP_ALGO_DUR = 0x2E, + + /// Diagport configuration + PARAM_ID_DIAG_BT_HW = 0x30, + PARAM_ID_DIAG_BLE_HW = 0x31, + PARAM_ID_DIAG_SW = 0x32, + PARAM_ID_DIAG_PLF = 0x34, + + /// RSSI threshold tags + PARAM_ID_RSSI_HIGH_THR = 0x3A, + PARAM_ID_RSSI_LOW_THR = 0x3B, + PARAM_ID_RSSI_INTERF_THR = 0x3C, + + /// BLE Channel Assessment tags + PARAM_ID_BLE_CA_TIMER_DUR = 0x40, + PARAM_ID_BLE_CRA_TIMER_CNT = 0x41, + PARAM_ID_BLE_CA_MIN_THR = 0x42, + PARAM_ID_BLE_CA_MAX_THR = 0x43, + PARAM_ID_BLE_CA_NOISE_THR = 0x44, + + /// AFH algorithm tags + PARAM_ID_AFH_REASS_NBCH = 0x51, + PARAM_ID_AFH_WINLGTH = 0x52, + PARAM_ID_AFH_RSSIMIN = 0x53, + PARAM_ID_AFH_PERTHRESBAD = 0x54, + PARAM_ID_AFH_REASS_INT = 0x55, + PARAM_ID_AFH_NMIN = 0x56, + PARAM_ID_AFH_MAXADAPT = 0x57, + PARAM_ID_AFH_THSMIN = 0x58, + + + PARAM_ID_BT_LINK_KEY_FIRST = 0x60, + PARAM_ID_BT_LINK_KEY_LAST = 0x67, + + PARAM_ID_BLE_LINK_KEY_FIRST = 0x70, + PARAM_ID_BLE_LINK_KEY_LAST = 0x7F, + /// SC Private Key (Low Energy) + PARAM_ID_LE_PRIVATE_KEY_P256 = 0x80, + /// SC Public Key (Low Energy) + PARAM_ID_LE_PUBLIC_KEY_P256 = 0x81, + /// SC Debug: Used Fixed Private Key from NVDS (Low Energy) + PARAM_ID_LE_DBG_FIXED_P256_KEY = 0x82, + /// SP Private Key (classic BT) + PARAM_ID_SP_PRIVATE_KEY_P256 = 0x83, + /// SP Public Key (classic BT) + PARAM_ID_SP_PUBLIC_KEY_P256 = 0x84, + + /// Application specific + PARAM_ID_APP_SPECIFIC_FIRST = 0x90, + PARAM_ID_APP_SPECIFIC_LAST = 0xAF, +}; + +/// List of parameters lengths +enum PARAM_LEN +{ + // Definition of length associated to each parameters + /// Local Bd Address + PARAM_LEN_BD_ADDRESS = 6, + /// Device Name + PARAM_LEN_DEVICE_NAME = 248, + /// Low power clock drift + PARAM_LEN_LPCLK_DRIFT = 2, + /// Low power clock jitter + PARAM_LEN_LPCLK_JITTER = 1, + /// Radio Class + PARAM_LEN_RADIO_CLASS = 1, + /// Bluejay specific Settings + PARAM_LEN_BJ_TXCNTL1 = 4, + + + /// External wake-up time + PARAM_LEN_EXT_WAKEUP_TIME = 2, + /// Oscillator wake-up time + PARAM_LEN_OSC_WAKEUP_TIME = 2, + /// Radio wake-up time + PARAM_LEN_RM_WAKEUP_TIME = 2, + /// UART baudrate + PARAM_LEN_UART_BAUDRATE = 4, + /// Enable sleep mode + PARAM_LEN_SLEEP_ENABLE = 1, + /// Enable External Wakeup + PARAM_LEN_EXT_WAKEUP_ENABLE = 1, + /// SP Private Key 192 + PARAM_LEN_SP_PRIVATE_KEY_P192 = 24, + /// SP Public Key 192 + PARAM_LEN_SP_PUBLIC_KEY_P192 = 48, + /// Errata adopted check + PARAM_LEN_ERRATA_ADOPTED = 1, + /// CQDDR Tags + PARAM_LEN_BASIC_THRESHOLD = 70, + PARAM_LEN_EDR_THRESHOLD = 70, + PARAM_LEN_BASIC_ALGORITHM = 21, + PARAM_LEN_EDR_ALGORITHM = 21, + PARAM_LEN_BASIC_PACKET_LUT = 16, + PARAM_LEN_EDR_PACKET_LUT = 16, + /// Synchronous links configuration + PARAM_LEN_SYNC_CONFIG = 2, + /// PCM Settings + PARAM_LEN_PCM_SETTINGS = 8, + /// Diagport configuration + PARAM_LEN_DIAG_BT_HW = 4, + PARAM_LEN_DIAG_BLE_HW = 4, + PARAM_LEN_DIAG_SW = 4, + PARAM_LEN_DIAG_PLF = 4, + /// RSSI thresholds + PARAM_LEN_RSSI_THR = 1, + + + PARAM_LEN_BLE_CA_TIMER_DUR = 2, + PARAM_LEN_BLE_CRA_TIMER_CNT = 1, + PARAM_LEN_BLE_CA_MIN_THR = 1, + PARAM_LEN_BLE_CA_MAX_THR = 1, + PARAM_LEN_BLE_CA_NOISE_THR = 1, + + /// AFH algorithm tags + PARAM_LEN_AFH_REASS_NBCH = 1, + PARAM_LEN_AFH_WINLGTH = 1, + PARAM_LEN_AFH_RSSIMIN = 1, + PARAM_LEN_AFH_PERTHRESBAD = 1, + PARAM_LEN_AFH_REASS_INT = 1, + PARAM_LEN_AFH_NMIN = 1, + PARAM_LEN_AFH_MAXADAPT = 1, + PARAM_LEN_AFH_THSMIN = 1, + /// Link keys + PARAM_LEN_BT_LINK_KEY = 22, + PARAM_LEN_BLE_LINK_KEY = 48, + + /// P256 + PARAM_LEN_PRIVATE_KEY_P256 = 32, + PARAM_LEN_PUBLIC_KEY_P256 = 64, + PARAM_LEN_DBG_FIXED_P256_KEY = 1, +}; + +/******************************************************************************************/ +/* ------------------------- BT-BLE COEX -----------------------------------*/ +/******************************************************************************************/ + +///To let the HW using the default values set in the registers +#define RW_BLE_PTI_PRIO_AUTO 15 + +#if (BLE_EMB_PRESENT || BT_EMB_PRESENT) +/// Enable and diable definition for the PTI +///Enable TX busy signal +#define RWIP_PTI_TXEN 1 +///Disable TX busy signal +#define RWIP_PTI_TXDIS 0 +/// Tx busy position +#define RWIP_TXBSY_POS 0 + +///Enable RX busy signal +#define RWIP_PTI_RXEN 1 +///Disable RX busy signal +#define RWIP_PTI_RXDIS 0 +/// Rx busy position +#define RWIP_RXBSY_POS 1 + +///Enable do not abort TX +#define RWIP_PTI_DNABORTEN 1 +///Disable do not abort TX +#define RWIP_PTI_DNABORTDIS 0 +/// Do not abort busy position +#define RWIP_DNABORT_POS 2 + +///Allows Tx operation in the current frame. +#define RWIP_MWS_TXEN 0 +///Prevent from any Tx operation in the current frame. +#define RWIP_MWS_TXDIS 1 +/// MWS transmit disable position +#define RWIP_MWSTXDSB_POS 3 + +///Allows Rx operation in the current frame. +#define RWIP_MWS_RXEN 0 +///Prevent from any Rx operation in the current frame. +#define RWIP_MWS_RXDIS 1 +/// MWS transmit disable position +#define RWIP_MWSRXDSB_POS 4 + +/// Bit masking +#define RWIP_COEX_BIT_MASK 1 + +/// Coex configuration index +enum rwip_coex_config_idx +{ + #if (BT_EMB_PRESENT) + RWIP_COEX_MSSWITCH_IDX , + RWIP_COEX_SNIFFATT_IDX , + RWIP_COEX_PAGE_IDX, + RWIP_COEX_PSCAN_IDX, + RWIP_COEX_INQ_IDX, + RWIP_COEX_INQRES_IDX, + RWIP_COEX_SCORSVD_IDX, + RWIP_COEX_BCAST_IDX, + RWIP_COEX_CONNECT_IDX, + #endif //#if (BT_EMB_PRESENT) + #if (BLE_EMB_PRESENT) + RWIP_COEX_CON_IDX, + RWIP_COEX_CON_DATA_IDX, + RWIP_COEX_ADV_IDX, + RWIP_COEX_SCAN_IDX, + RWIP_COEX_INIT_IDX, + #endif // #if (BLE_EMB_PRESENT) + /// Max configuration index + RWIP_COEX_CFG_MAX, +}; +#endif //(BLE_EMB_PRESENT || BT_EMB_PRESENT) + +/******************************************************************************************/ +/* ------------------------- BT-BLE PRIORITIES -----------------------------------*/ +/******************************************************************************************/ +#if (BLE_EMB_PRESENT || BT_EMB_PRESENT) +/// Priority index definition +enum rwip_prio_idx +{ + #if (BT_EMB_PRESENT) + /// ACL event default priority + RWIP_PRIO_ACL_DFT_IDX, + /// ACL event priority with activity + RWIP_PRIO_ACL_ACT_IDX, + /// ACL Role Switch event default priority + RWIP_PRIO_ACL_RSW_IDX, + /// ACL sniff event default priority + RWIP_PRIO_ACL_SNIFF_DFT_IDX, + /// ACL sniff transition event default priority + RWIP_PRIO_ACL_SNIFF_TRANS_IDX, + #if MAX_NB_SYNC + /// SCO event default priority + RWIP_PRIO_SCO_DFT_IDX, + #endif //MAX_NB_SYNC + /// Broadcast ACL event default priority + RWIP_PRIO_BCST_DFT_IDX, + /// Broadcast ACL event with LMP activity priority + RWIP_PRIO_BCST_ACT_IDX, + /// CSB RX event default priority + RWIP_PRIO_CSB_RX_DFT_IDX, + /// CSB TX event default priority + RWIP_PRIO_CSB_TX_DFT_IDX, + /// Inquiry event default priority + RWIP_PRIO_INQ_DFT_IDX, + /// Inquiry Scan event default priority + RWIP_PRIO_ISCAN_DFT_IDX, + /// Page event default priority + RWIP_PRIO_PAGE_DFT_IDX, + /// Page event default priority + RWIP_PRIO_PAGE_1ST_PKT_IDX, + /// Page first packet event default priority + RWIP_PRIO_PCA_DFT_IDX, + /// Page scan event default priority + RWIP_PRIO_PSCAN_DFT_IDX, + /// Page scan event priority increment when canceled + RWIP_PRIO_PSCAN_1ST_PKT_IDX, + /// Synchronization Scan event default priority + RWIP_PRIO_SSCAN_DFT_IDX, + /// Synchronization Train event default priority + RWIP_PRIO_STRAIN_DFT_IDX, + #endif //#if (BT_EMB_PRESENT) + #if (BLE_EMB_PRESENT) + /// Default priority for scanning events + RWIP_PRIO_SCAN_IDX, + /// Default priority for initiating events + RWIP_PRIO_INIT_IDX, + /// Default priority for master connect events + RWIP_PRIO_MCONNECT_IDX, + /// Default priority for slave connect events + RWIP_PRIO_SCONNECT_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 resolvable private addresses renewal event + RWIP_PRIO_RPA_RENEW_IDX, + #endif // #if (BLE_EMB_PRESENT) + RWIP_PRIO_IDX_MAX +}; +/// Default priority value definition +enum rwip_prio_dft +{ + #if (BT_EMB_PRESENT) + /// ACL event default priority + RWIP_PRIO_ACL_DFT = 5, + /// ACL event priority with activity + RWIP_PRIO_ACL_ACT = 10, + /// ACL Role Switch event default priority + RWIP_PRIO_ACL_RSW = 20, + /// ACL sniff event default priority + RWIP_PRIO_ACL_SNIFF_DFT = 15, + /// ACL sniff transition event default priority + RWIP_PRIO_ACL_SNIFF_TRANS = 10, + #if MAX_NB_SYNC + /// SCO event default priority + RWIP_PRIO_SCO_DFT = 18, + #endif //MAX_NB_SYNC + /// Broadcast ACL event default priority + RWIP_PRIO_BCST_DFT = 5, + /// Broadcast ACL event with LMP activity priority + RWIP_PRIO_BCST_ACT = 10, + /// CSB RX event default priority + RWIP_PRIO_CSB_RX_DFT = 10, + /// CSB TX event default priority + RWIP_PRIO_CSB_TX_DFT = 10, + /// Inquiry event default priority + RWIP_PRIO_INQ_DFT = 5, + /// Inquiry Scan event default priority + RWIP_PRIO_ISCAN_DFT = 5, + /// Page event default priority + RWIP_PRIO_PAGE_DFT = 8, + /// Page first packet event default priority + RWIP_PRIO_PAGE_1ST_PKT = 20, + /// PCA event default priority + RWIP_PRIO_PCA_DFT = 20, + /// Page scan event default priority + RWIP_PRIO_PSCAN_DFT = 8, + /// Page scan event priority increment when canceled + RWIP_PRIO_PSCAN_1ST_PKT = 20, + /// Synchronization Scan event default priority + RWIP_PRIO_SSCAN_DFT = 10, + /// Synchronization Train event default priority + RWIP_PRIO_STRAIN_DFT = 10, + #endif //#if (BT_EMB_PRESENT) + #if (BLE_EMB_PRESENT) + /// Default priority for scanning events + RWIP_PRIO_SCAN_DFT = 5, + /// Default priority for initiating events + RWIP_PRIO_INIT_DFT = 10, + /// Default priority for master connect events + RWIP_PRIO_MCONNECT_DFT = 15, + /// Default priority for slave connect events + RWIP_PRIO_SCONNECT_DFT = 15, + /// Default priority for advertising events + RWIP_PRIO_ADV_DFT = 5, + /// Default priority for advertising high duty cycle events + RWIP_PRIO_ADV_HDC_DFT = 10, + /// Default priority for resolvable private addresses renewal event + RWIP_PRIO_RPA_RENEW_DFT = 10, + #endif // #if (BLE_EMB_PRESENT) + /// Max priority + RWIP_PRIO_MAX = 31, +}; +/// Default increment value definition +enum rwip_incr_dft +{ + #if (BT_EMB_PRESENT) + /// ACL event default increment + RWIP_INCR_ACL_DFT = 1, + /// ACL event increment with activity + RWIP_INCR_ACL_ACT = 1, + /// ACL Role Switch event default increment + RWIP_INCR_ACL_RSW = 1, + /// ACL sniff event default increment + RWIP_INCR_ACL_SNIFF_DFT = 1, + /// ACL sniff transition event default increment + RWIP_INCR_ACL_SNIFF_TRANS = 1, + #if MAX_NB_SYNC + /// SCO event default increment + RWIP_INCR_SCO_DFT = 1, + #endif //MAX_NB_SYNC + /// Broadcast ACL event default increment + RWIP_INCR_BCST_DFT = 1, + /// Broadcast ACL event with LMP activity increment + RWIP_INCR_BCST_ACT = 1, + /// CSB RX event default increment + RWIP_INCR_CSB_RX_DFT = 1, + /// CSB TX event default increment + RWIP_INCR_CSB_TX_DFT = 1, + /// Inquiry event default increment + RWIP_INCR_INQ_DFT = 1, + /// Inquiry Scan event default increment + RWIP_INCR_ISCAN_DFT = 1, + /// Page event default increment + RWIP_INCR_PAGE_DFT = 1, + /// Page event default increment + RWIP_INCR_PAGE_1ST_PKT = 2, + /// Page first packet event default increment + RWIP_INCR_PCA_DFT = 1, + /// Page scan event default increment + RWIP_INCR_PSCAN_DFT = 1, + /// Page scan event increment increment when canceled + RWIP_INCR_PSCAN_1ST_PKT = 1, + /// Synchronization Scan event default increment + RWIP_INCR_SSCAN_DFT = 1, + /// Synchronization Train event default increment + RWIP_INCR_STRAIN_DFT = 1, + #endif //#if (BT_EMB_PRESENT) + #if (BLE_EMB_PRESENT) + /// Default increment for scanning events + RWIP_INCR_SCAN_DFT = 1, + /// Default increment for initiating events + RWIP_INCR_INIT_DFT = 1, + /// Default increment for master connect events + RWIP_INCR_MCONNECT_DFT = 1, + /// Default increment for slave connect events + RWIP_INCR_SCONNECT_DFT = 1, + /// Default increment for advertising events + RWIP_INCR_ADV_DFT = 1, + /// Default increment for advertising high duty cycle events + RWIP_INCR_ADV_HDC_PRIO_DFT = 1, + /// Default increment for resolvable private addresses renewal event + RWIP_INCR_RPA_RENEW_DFT = 1, + #endif // #if (BLE_EMB_PRESENT) +}; +#endif //#if (BLE_EMB_PRESENT || BT_EMB_PRESENT) +/// @} BT Stack Configuration +/// @} ROOT + +#endif //RWIP_CONFIG_H_ diff --git a/services/ble_stack/ble_ip/rwip_task.h b/services/ble_stack/ble_ip/rwip_task.h new file mode 100644 index 0000000..c4830b5 --- /dev/null +++ b/services/ble_stack/ble_ip/rwip_task.h @@ -0,0 +1,173 @@ +#ifndef RWIP_TASK_H_ +#define RWIP_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup ROOT + * @{ + * + * Information about RW SW TASK + * + * @name RW TASK Configuration + * @{ + **************************************************************************************** + */ + +#include + +/* + * DEFINES + **************************************************************************************** + */ + + +/// Build the first message ID of a task. (in fact a ke_msg_id_t) +#define TASK_FIRST_MSG(task) ((uint16_t)((task) << 8)) + +/// Builds the task identifier from the type and the index of that task. +#define TASK_BUILD(type, index) ((uint16_t)(((index) << 8)|(type)) ) + +/// Retrieves task type from task id. +#define TASK_TYPE_GET(ke_task_id) ((uint16_t) & 0xFF) + +/// Retrieves task index number from task id. +#define TASK_IDX_GET(ke_task_id) (((uint16_t) >> 8) & 0xFF) + + +/// Tasks types definition, this value shall be in [0-254] range +enum TASK_API_ID +{ + // Link Layer Tasks + TASK_ID_LLM = 0, + TASK_ID_LLC = 1, + TASK_ID_LLD = 2, + TASK_ID_DBG = 3, + + // BT Controller Tasks + TASK_ID_LM = 4, + TASK_ID_LC = 5, + TASK_ID_LB = 6, + TASK_ID_LD = 7, + + TASK_ID_HCI = 8, + TASK_ID_DISPLAY = 9, + + // ----------------------------------------------------------------------------------- + // --------------------- BLE HL TASK API Identifiers --------------------------------- + // ----------------------------------------------------------------------------------- + + TASK_ID_L2CC = 10, // L2CAP Controller Task + TASK_ID_GATTM = 11, // Generic Attribute Profile Manager Task + TASK_ID_GATTC = 12, // Generic Attribute Profile Controller Task + TASK_ID_GAPM = 13, // Generic Access Profile Manager + TASK_ID_GAPC = 14, // Generic Access Profile Controller + + TASK_ID_APP = 15, // Application API + TASK_ID_AHI = 16, // Application Host Interface + + // ----------------------------------------------------------------------------------- + // --------------------- BLE Profile TASK API Identifiers ---------------------------- + // ----------------------------------------------------------------------------------- + TASK_ID_DISS = 20, // Device Information Service Server Task + TASK_ID_DISC = 21, // Device Information Service Client Task + + TASK_ID_PROXM = 22, // Proximity Monitor Task + TASK_ID_PROXR = 23, // Proximity Reporter Task + + TASK_ID_FINDL = 24, // Find Me Locator Task + TASK_ID_FINDT = 25, // Find Me Target Task + + TASK_ID_HTPC = 26, // Health Thermometer Collector Task + TASK_ID_HTPT = 27, // Health Thermometer Sensor Task + + TASK_ID_BLPS = 28, // Blood Pressure Sensor Task + TASK_ID_BLPC = 29, // Blood Pressure Collector Task + + TASK_ID_HRPS = 30, // Heart Rate Sensor Task + TASK_ID_HRPC = 31, // Heart Rate Collector Task + + TASK_ID_TIPS = 32, // Time Server Task + TASK_ID_TIPC = 33, // Time Client Task + + TASK_ID_SCPPS = 34, // Scan Parameter Profile Server Task + TASK_ID_SCPPC = 35, // Scan Parameter Profile Client Task + + TASK_ID_BASS = 36, // Battery Service Server Task + TASK_ID_BASC = 37, // Battery Service Client Task + + TASK_ID_HOGPD = 38, // HID Device Task + TASK_ID_HOGPBH = 39, // HID Boot Host Task + TASK_ID_HOGPRH = 40, // HID Report Host Task + + TASK_ID_GLPS = 41, // Glucose Profile Sensor Task + TASK_ID_GLPC = 42, // Glucose Profile Collector Task + + TASK_ID_RSCPS = 43, // Running Speed and Cadence Profile Server Task + TASK_ID_RSCPC = 44, // Running Speed and Cadence Profile Collector Task + + TASK_ID_CSCPS = 45, // Cycling Speed and Cadence Profile Server Task + TASK_ID_CSCPC = 46, // Cycling Speed and Cadence Profile Client Task + + TASK_ID_ANPS = 47, // Alert Notification Profile Server Task + TASK_ID_ANPC = 48, // Alert Notification Profile Client Task + + TASK_ID_PASPS = 49, // Phone Alert Status Profile Server Task + TASK_ID_PASPC = 50, // Phone Alert Status Profile Client Task + + TASK_ID_CPPS = 51, // Cycling Power Profile Server Task + TASK_ID_CPPC = 52, // Cycling Power Profile Client Task + + TASK_ID_LANS = 53, // Location and Navigation Profile Server Task + TASK_ID_LANC = 54, // Location and Navigation Profile Client Task + + TASK_ID_IPSS = 55, // Internet Protocol Support Profile Server Task + TASK_ID_IPSC = 56, // Internet Protocol Support Profile Client Task + + TASK_ID_ENVS = 57, // Environmental Sensing Profile Server Task + TASK_ID_ENVC = 58, // Environmental Sensing Profile Client Task + + TASK_ID_WSCS = 59, // Weight Scale Profile Server Task + TASK_ID_WSCC = 60, // Weight Scale Profile Client Task + + TASK_ID_UDSS = 61, // User Data Service Server Task + TASK_ID_UDSC = 62, // User Data Service Client Task + + TASK_ID_BCSS = 63, // Body Composition Server Task + TASK_ID_BCSC = 64, // Body Composition Client Task + + TASK_ID_GFPSP = 65, //google fast pair service provider + TASK_ID_GFPSS = 66, // seeker + + TASK_ID_VOICEPATH = 67, // Voice Path Task + + TASK_ID_OTA = 68, // OTA Task + + TASK_ID_ANCC = 69, // ANCS Client Task + + TASK_ID_AMSC = 70, // AMS Client Task + + TASK_ID_BMS = 71, // BMS Task + + TASK_ID_ANCSP = 72, // ANCS Proxy Task + + TASK_ID_AMSP = 73, // AMS Proxy Task + + TASK_ID_DATAPATHPS = 74, // Datapath Server Task + + TASK_ID_AI = 75, // ai Task + + TASK_ID_TOTA = 76, // TOTA Task + + TASK_ID_TILE = 77, // skull tile task + + /* 240 -> 241 reserved for Audio Mode 0 */ + TASK_ID_AM0 = 240, // BLE Audio Mode 0 Task + TASK_ID_AM0_HAS = 241, // BLE Audio Mode 0 Hearing Aid Service Task + + TASK_ID_INVALID = 0xFF, // Invalid Task Identifier +}; + +/// @} BT Stack Configuration +/// @} ROOT + +#endif //RWIP_CONFIG_H_ diff --git a/services/ble_stack/ble_ip/rwprf_config.h b/services/ble_stack/ble_ip/rwprf_config.h new file mode 100644 index 0000000..1f39e08 --- /dev/null +++ b/services/ble_stack/ble_ip/rwprf_config.h @@ -0,0 +1,572 @@ +#ifndef _RWPRF_CONFIG_H_ +#define _RWPRF_CONFIG_H_ + +#include "rwapp_config.h" + +#ifdef GFPS_ENABLED +#if BLE_APP_GFPS_VER==FAST_PAIR_REV_2_0 +#define CFG_PRF_GFPS_PROVIDER +#endif +#endif + +#ifdef VOICE_DATAPATH +#define CFG_VOICEPATH +#else +#define CFG_PRF_DATAPATH_SERVER +#endif + +#ifdef __AI_VOICE__ +#define CFG_AI_VOICE +#endif + +#ifdef BES_OTA_BASIC +#define CFG_OTA +#endif + +#ifdef BLE_TOTA_ENABLED +#define CFG_TOTA +#endif + +#ifdef TILE_DATAPATH +#define CFG_TILE +#endif + +#if defined(VOICE_DATAPATH) && defined(BISTO_ENABLED) +#define CFG_BMS +#if ANCS_PROXY_ENABLE +#define CFG_PRF_AMS +#define CFG_PRF_ANCC +#endif + +#endif + +/** + **************************************************************************************** + * @addtogroup PRF_CONFIG + * @ingroup PROFILE + * @brief Profile configuration + * + * @{ + **************************************************************************************** + */ + +//ATT DB,Testing and Qualification related flags +#if (BLE_CENTRAL || BLE_PERIPHERAL) +/// Proximity Profile Monitor Role +#if defined(CFG_PRF_PXPM) +#define BLE_PROX_MONITOR 1 +#else +#define BLE_PROX_MONITOR 0 +#endif // defined(CFG_PRF_PXPM) + +/// Proximity Profile Reporter Role +#if defined(CFG_PRF_PXPR) +#define BLE_PROX_REPORTER 1 +#else +#define BLE_PROX_REPORTER 0 +#endif // defined(CFG_PRF_PXPR) + +///Find Me Profile Locator role +#if defined(CFG_PRF_FMPL) +#define BLE_FINDME_LOCATOR 1 +#else +#define BLE_FINDME_LOCATOR 0 +#endif // defined(CFG_PRF_FMPL) + +///Find Me Profile Target role +#if defined(CFG_PRF_FMPT) +#define BLE_FINDME_TARGET 1 +#else +#define BLE_FINDME_TARGET 0 +#endif // defined(CFG_PRF_FMPT) + +///Health Thermometer Profile Collector Role +#if defined(CFG_PRF_HTPC) +#define BLE_HT_COLLECTOR 1 +#else +#define BLE_HT_COLLECTOR 0 +#endif // defined(CFG_PRF_HTPC) + +///Health Thermometer Profile Thermometer Role +#if defined(CFG_PRF_HTPT) +#define BLE_HT_THERMOM 1 +#else +#define BLE_HT_THERMOM 0 +#endif // defined(CFG_PRF_HTPT) + +///Device Information Service Client Role +#if defined(CFG_PRF_DISC) +#define BLE_DIS_CLIENT 1 +#else +#define BLE_DIS_CLIENT 0 +#endif // defined(CFG_PRF_DISC) + +///Device Information Service Server Role +#if defined(CFG_PRF_DISS) +#define BLE_DIS_SERVER 1 +#else +#define BLE_DIS_SERVER 0 +#endif // defined(CFG_PRF_DISS) + +///Blood Pressure Profile Collector Role +#if defined(CFG_PRF_BLPC) +#define BLE_BP_COLLECTOR 1 +#else +#define BLE_BP_COLLECTOR 0 +#endif // defined(CFG_PRF_BLPC) + +///Blood Pressure Profile Sensor Role +#if defined(CFG_PRF_BLPS) +#define BLE_BP_SENSOR 1 +#else +#define BLE_BP_SENSOR 0 +#endif // defined(CFG_PRF_BLPS) + +///Time Profile Client Role +#if defined(CFG_PRF_TIPC) +#define BLE_TIP_CLIENT 1 +#else +#define BLE_TIP_CLIENT 0 +#endif // defined(CFG_PRF_TIPC) + +///Time Profile Server Role +#if defined(CFG_PRF_TIPS) +#define BLE_TIP_SERVER 1 +#else +#define BLE_TIP_SERVER 0 +#endif // defined(CFG_PRF_TIPS) + +///Heart Rate Profile Collector Role +#if defined(CFG_PRF_HRPC) +#define BLE_HR_COLLECTOR 1 +#else +#define BLE_HR_COLLECTOR 0 +#endif // defined(CFG_PRF_HRPC) + +///Heart Rate Profile Sensor Role +#if defined(CFG_PRF_HRPS) +#define BLE_HR_SENSOR 1 +#else +#define BLE_HR_SENSOR 0 +#endif // defined(CFG_PRF_HRPS) + +///Scan Parameter Profile Client Role +#if defined(CFG_PRF_SCPPC) +#define BLE_SP_CLIENT 1 +#else +#define BLE_SP_CLIENT 0 +#endif // defined(CFG_PRF_SCPPC) + +///Scan Parameter Profile Server Role +#if defined(CFG_PRF_SCPPS) +#define BLE_SP_SERVER 1 +#else +#define BLE_SP_SERVER 0 +#endif // defined(CFG_PRF_SCPPS) + +///Battery Service Client Role +#if defined(CFG_PRF_BASC) +#define BLE_BATT_CLIENT 1 +#else +#define BLE_BATT_CLIENT 0 +#endif // defined(CFG_PRF_BASC) + +///Battery Service Server Role +#if defined(CFG_PRF_BASS) +#define BLE_BATT_SERVER 1 +#else +#define BLE_BATT_SERVER 0 +#endif // defined(CFG_PRF_BASS) + +///HID Device Role +#if defined(CFG_PRF_HOGPD) +#define BLE_HID_DEVICE 1 +#else +#define BLE_HID_DEVICE 0 +#endif // defined(CFG_PRF_HOGPD) + +///HID Boot Host Role +#if defined(CFG_PRF_HOGPBH) +#define BLE_HID_BOOT_HOST 1 +#else +#define BLE_HID_BOOT_HOST 0 +#endif // defined(CFG_PRF_HOGPBH) + +///HID Report Host Role +#if defined(CFG_PRF_HOGPRH) +#define BLE_HID_REPORT_HOST 1 +#else +#define BLE_HID_REPORT_HOST 0 +#endif // defined(CFG_PRF_HOGPRH) + +/// Glucose Profile Collector Role +#if defined(CFG_PRF_GLPC) +#define BLE_GL_COLLECTOR 1 +#else +#define BLE_GL_COLLECTOR 0 +#endif // defined(CFG_PRF_GLPC) + +/// Glucose Profile Sensor Role +#if defined(CFG_PRF_GLPS) +#define BLE_GL_SENSOR 1 +#else +#define BLE_GL_SENSOR 0 +#endif // defined(CFG_PRF_GLPS) + +/// Running Speed and Cadence Profile Collector Role +#if defined(CFG_PRF_RSCPC) +#define BLE_RSC_COLLECTOR 1 +#else +#define BLE_RSC_COLLECTOR 0 +#endif // defined(CFG_PRF_RSCPC) + +/// Running Speed and Cadence Profile Server Role +#if defined(CFG_PRF_RSCPS) +#define BLE_RSC_SENSOR 1 +#else +#define BLE_RSC_SENSOR 0 +#endif // defined(CFG_PRF_RSCPS) + +/// Cycling Speed and Cadence Profile Collector Role +#if defined(CFG_PRF_CSCPC) +#define BLE_CSC_COLLECTOR 1 +#else +#define BLE_CSC_COLLECTOR 0 +#endif // defined(CFG_PRF_CSCPC) + +/// Cycling Speed and Cadence Profile Server Role +#if defined(CFG_PRF_CSCPS) +#define BLE_CSC_SENSOR 1 +#else +#define BLE_CSC_SENSOR 0 +#endif // defined(CFG_PRF_CSCPS) + +/// Cycling Power Profile Collector Role +#if defined(CFG_PRF_CPPC) +#define BLE_CP_COLLECTOR 1 +#else +#define BLE_CP_COLLECTOR 0 +#endif // defined (CFG_PRF_CPPC) + +/// Cycling Power Profile Server Role +#if defined(CFG_PRF_CPPS) +#define BLE_CP_SENSOR 1 +#else +#define BLE_CP_SENSOR 0 +#endif // defined (CFG_PRF_CPPS) + +/// Location and Navigation Profile Collector Role +#if defined(CFG_PRF_LANC) +#define BLE_LN_COLLECTOR 1 +#else +#define BLE_LN_COLLECTOR 0 +#endif // defined (CFG_PRF_LANC) + +/// Location and Navigation Profile Server Role +#if defined(CFG_PRF_LANS) +#define BLE_LN_SENSOR 1 +#else +#define BLE_LN_SENSOR 0 +#endif // defined (CFG_PRF_LANS) + +/// Alert Notification Profile Client Role +#if defined(CFG_PRF_ANPC) +#define BLE_AN_CLIENT 1 +#else +#define BLE_AN_CLIENT 0 +#endif // defined(CFG_PRF_ANPC) + +/// Alert Notification Profile Server Role +#if defined(CFG_PRF_ANPS) +#define BLE_AN_SERVER 1 +#else +#define BLE_AN_SERVER 0 +#endif // defined(CFG_PRF_ANPS) + +/// Phone Alert Status Profile Client Role +#if defined(CFG_PRF_PASPC) +#define BLE_PAS_CLIENT 1 +#else +#define BLE_PAS_CLIENT 0 +#endif // defined(CFG_PRF_PASPC) + +/// Phone Alert Status Profile Server Role +#if defined(CFG_PRF_PASPS) +#define BLE_PAS_SERVER 1 +#else +#define BLE_PAS_SERVER 0 +#endif // defined(CFG_PRF_PASPS) + +/// Internet Protocol Support Profile Server Role +#if defined(CFG_PRF_IPSS) +#define BLE_IPS_SERVER 1 +#else +#define BLE_IPS_SERVER 0 +#endif // defined(CFG_PRF_IPSS) + +/// Internet Protocol Support Profile Client Role +#if defined(CFG_PRF_IPSC) +#define BLE_IPS_CLIENT 1 +#else +#define BLE_IPS_CLIENT 0 +#endif // defined(CFG_PRF_IPSC) + +/// Environmental Sensing Profile Server Role +#if defined(CFG_PRF_ENVS) +#define BLE_ENV_SERVER 1 +#else +#define BLE_ENV_SERVER 0 +#endif // defined(CFG_PRF_ENVS) + +/// Environmental Sensing Profile Client Role +#if defined(CFG_PRF_ENVC) +#define BLE_ENV_CLIENT 1 +#else +#define BLE_ENV_CLIENT 0 +#endif // defined(CFG_PRF_ENVC) + +/// Weight Scale Profile Server Role +#if defined(CFG_PRF_WSCS) +#define BLE_WSC_SERVER 1 +#else +#define BLE_WSC_SERVER 0 +#endif // defined(CFG_PRF_WSCS) + +/// Weight Scale Profile Client Role +#if defined(CFG_PRF_WSCC) +#define BLE_WSC_CLIENT 1 +#else +#define BLE_WSC_CLIENT 0 +#endif // defined(CFG_PRF_WSCC) + +/// Body Composition Server Role +#if defined(CFG_PRF_BCSS) +#define BLE_BCS_SERVER 1 +#else +#define BLE_BCS_SERVER 0 +#endif // defined(CFG_PRF_BCSS) + +/// Body Composition Client Role +#if defined(CFG_PRF_BCSC) +#define BLE_BCS_CLIENT 1 +#else +#define BLE_BCS_CLIENT 0 +#endif // defined(CFG_PRF_BCSC) + +/// User Data Service Server Role +#if defined(CFG_PRF_UDSS) +#define BLE_UDS_SERVER 1 +#else +#define BLE_UDS_SERVER 0 +#endif // defined(CFG_PRF_UDSS) + +/// User Data Service Client Role +#if defined(CFG_PRF_UDSC) +#define BLE_UDS_CLIENT 1 +#else +#define BLE_UDS_CLIENT 0 +#endif // defined(CFG_PRF_UDSC) + +#if defined(CFG_VOICEPATH) +#define BLE_VOICEPATH 1 +#else +#define BLE_VOICEPATH 0 +#endif // defined(CFG_VOICEPATH) + +#if defined(CFG_TILE) +#define BLE_TILE 1 +#else +#define BLE_TILE 0 +#endif // + +#if defined(CFG_AI_VOICE) +#define BLE_AI_VOICE 1 +#else +#define BLE_AI_VOICE 0 +#endif + +/// Data Path Service Server Role +#if defined(CFG_PRF_DATAPATH_SERVER) +#define BLE_DATAPATH_SERVER 1 +#else +#define BLE_DATAPATH_SERVER 0 +#endif // defined(CFG_PRF_DATAPATH_SERVER) + +#if defined(CFG_OTA) +#define BLE_OTA 1 +#else +#define BLE_OTA 0 +#endif // defined(CFG_OTA) + +#if defined(CFG_TOTA) +#define BLE_TOTA 1 +#else +#define BLE_TOTA 0 +#endif // defined(CFG_TOTA) + +#if defined(CFG_BMS) +#define BLE_BMS 1 +#else +#define BLE_BMS 0 +#endif // defined(BLE_BMS) + +/// ANCS Profile Client Role +#if defined(CFG_PRF_ANCC) +#define BLE_ANC_CLIENT 1 +#else +#define BLE_ANC_CLIENT 0 +#endif // defined(CFG_PRF_ANCC) + +/// AMS Profile Client Role +#if defined(CFG_PRF_AMS) +#define BLE_AMS_CLIENT 1 +#else +#define BLE_AMS_CLIENT 0 +#endif // defined(CFG_PRF_AMS) +#if defined(CFG_PRF_GFPS_PROVIDER) +#define BLE_GFPS_PROVIDER 1 +#else +#define BLE_GFPS_PROVIDER 0 +#endif + +/// BLE_CLIENT_PRF indicates if at least one client profile is present +#if (BLE_PROX_MONITOR || BLE_FINDME_LOCATOR || BLE_HT_COLLECTOR || BLE_BP_COLLECTOR \ + || BLE_HR_COLLECTOR || BLE_DIS_CLIENT || BLE_TIP_CLIENT || BLE_SP_CLIENT \ + || BLE_BATT_CLIENT || BLE_GL_COLLECTOR || BLE_HID_BOOT_HOST || BLE_HID_REPORT_HOST \ + || BLE_RSC_COLLECTOR || BLE_CSC_COLLECTOR || BLE_CP_COLLECTOR || BLE_LN_COLLECTOR || BLE_AN_CLIENT \ + || BLE_PAS_CLIENT || BLE_IPS_CLIENT || BLE_ENV_CLIENT || BLE_WSC_CLIENT \ + || BLE_UDS_CLIENT || BLE_BCS_CLIENT || BLE_VOICEPATH || BLE_DATAPATH_SERVER || BLE_ANC_CLIENT || BLE_BMS || BLE_OTA||BLE_AI_VOICE || BLE_TOTA || BLE_TILE) +#define BLE_CLIENT_PRF 1 +#else +#define BLE_CLIENT_PRF 0 +#endif //(BLE_PROX_MONITOR || BLE_FINDME_LOCATOR ...) + +/// BLE_SERVER_PRF indicates if at least one server profile is present +#if (BLE_PROX_REPORTER || BLE_FINDME_TARGET || BLE_HT_THERMOM || BLE_BP_SENSOR \ + || BLE_TIP_SERVER || BLE_HR_SENSOR || BLE_DIS_SERVER || BLE_SP_SERVER \ + || BLE_BATT_SERVER || BLE_HID_DEVICE || BLE_GL_SENSOR || BLE_RSC_SENSOR \ + || BLE_CSC_SENSOR || BLE_CP_SENSOR || BLE_LN_SENSOR || BLE_AN_SERVER \ + || BLE_PAS_SERVER || BLE_IPS_SERVER || BLE_ENV_SERVER || BLE_WSC_SERVER \ + || BLE_UDS_SERVER || BLE_BCS_SERVER|| BLE_TOTA) +#define BLE_SERVER_PRF 1 +#else +#define BLE_SERVER_PRF 0 +#endif //(BLE_PROX_REPORTER || BLE_FINDME_TARGET ...) + +//Force ATT parts depending on profile roles or compile options +/// Attribute Client +#if (BLE_CLIENT_PRF) +#define BLE_ATTC 1 +#endif //(BLE_CLIENT_PRF) + +/// Attribute Server +#if (BLE_SERVER_PRF) +#define BLE_ATTS 1 +#endif //(BLE_SERVER_PRF) + + +#elif (BLE_OBSERVER || BLE_BROADCASTER) +/// Proximity Profile Monitor Role +#define BLE_PROX_MONITOR 0 +/// Proximity Profile Reporter Role +#define BLE_PROX_REPORTER 0 +///Find Me Profile Locator role +#define BLE_FINDME_LOCATOR 0 +///Find Me Profile Target role +#define BLE_FINDME_TARGET 0 +///Health Thermometer Profile Collector Role +#define BLE_HT_COLLECTOR 0 +///Health Thermometer Profile Thermometer Role +#define BLE_HT_THERMOM 0 +///Blood Pressure Profile Collector Role +#define BLE_BP_COLLECTOR 0 +///Blood Pressure Profile Sensor Role +#define BLE_BP_SENSOR 0 +///Heart Rate Profile Collector Role +#define BLE_HR_COLLECTOR 0 +///Heart Rate Profile Sensor Role +#define BLE_HR_SENSOR 0 +///Time Profile Client Role +#define BLE_TIP_CLIENT 0 +///Time Profile Server Role +#define BLE_TIP_SERVER 0 +/// Device Information Service Client Role +#define BLE_DIS_CLIENT 0 +/// Device Information Service Server Role +#define BLE_DIS_SERVER 0 +/// Scan Parameter Profile Client Role +#define BLE_SP_CLIENT 0 +/// Scan Parameter Profile Server Role +#define BLE_SP_SERVER 0 +/// Battery Service Client Role +#define BLE_BATT_CLIENT 0 +/// Battery Service Server Role +#define BLE_BATT_SERVER 0 +/// HID Device Role +#define BLE_HID_DEVICE 0 +/// HID Boot Host Role +#define BLE_HID_BOOT_HOST 0 +/// HID Report Host Role +#define BLE_HID_REPORT_HOST 0 +/// Glucose Profile Collector Role +#define BLE_GL_COLLECTOR 0 +/// Glucose Profile Sensor Role +#define BLE_GL_SENSOR 0 +/// Running Speed and Cadence Collector Role +#define BLE_RSC_COLLECTOR 0 +/// Running Speed and Cadence Server Role +#define BLE_RSC_SENSOR 0 +/// Cycling Speed and Cadence Collector Role +#define BLE_CSC_COLLECTOR 0 +/// Cycling Speed and Cadence Server Role +#define BLE_CSC_SENSOR 0 +/// Cycling Power Collector Role +#define BLE_CP_COLLECTOR 0 +/// Cycling Power Server Role +#define BLE_CP_SENSOR 0 +/// Location and Navigation Collector Role +#define BLE_LN_COLLECTOR 0 +/// Location and Navigation Server Role +#define BLE_LN_SENSOR 0 +/// Alert Notification Client Role +#define BLE_AN_CLIENT 0 +/// Alert Notification Server Role +#define BLE_AN_SERVER 0 +/// Phone Alert Status Client Role +#define BLE_PAS_CLIENT 0 +/// Phone Alert Status Server Role +#define BLE_PAS_SERVER 0 +/// Internet Protocol Support Profile Server Role +#define BLE_IPS_SERVER 0 +/// Internet Protocol Support Profile Client Role +#define BLE_IPS_CLIENT 0 +/// Environmental Sensing Profile Server Role +#define BLE_ENV_SERVER 0 +/// Environmental Sensing Profile Client Role +#define BLE_ENV_CLIENT 0 +/// Weight Scale Profile Server Role +#define BLE_WSC_SERVER 0 +/// Weight Scale Profile Client Role +#define BLE_WSC_CLIENT 0 +/// Body Composition Profile Client Role +#define BLE_BCS_CLIENT 0 +/// Body Composition Profile Server Role +#define BLE_BCS_SERVER 0 +/// User Data Service Server Role +#define BLE_UDS_SERVER 0 +/// User Data Service Client Role +#define BLE_UDS_CLIENT 0 + +//Force ATT parts to 0 +/// External database management +#define BLE_EXT_ATTS_DB 0 +/// Profile Server +#define BLE_SERVER_PRF 0 +/// Profile Client +#define BLE_CLIENT_PRF 0 +#endif //(BLE_OBSERVER || BLE_BROADCASTER) + + +/// @} PRF_CONFIG + +#endif /* _RWPRF_CONFIG_H_ */ diff --git a/services/ble_stack/common/api/co_bt.h b/services/ble_stack/common/api/co_bt.h new file mode 100644 index 0000000..4b348a7 --- /dev/null +++ b/services/ble_stack/common/api/co_bt.h @@ -0,0 +1,48 @@ +#ifndef CO_BT_H_ +#define CO_BT_H_ + +/** + **************************************************************************************** + * @addtogroup COMMON Common SW Block + * @ingroup ROOT + * @brief The Common RW SW Block. + * + * The COMMON is the block with Bluetooth definitions and structures shared + * to all the protocol stack blocks. This also contain software wide error code + * definitions, mathematical functions, help functions, list and buffer definitions. + * + * @{ + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @addtogroup CO_BT Common Bluetooth defines + * @ingroup COMMON + * @brief Common Bluetooth definitions and structures. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include // standard boolean definitions +#include // standard definitions +#include // standard integer definitions + +/* + * DEFINES + **************************************************************************************** + */ + +#include "co_bt_defines.h" // Bluetooth defines +#include "co_lmp.h" // Bluetooth LMP definitions +#include "co_hci.h" // Bluetooth HCI definitions +#include "co_error.h" // Bluetooth error codes definitions + +/// @} CO_BT +#endif // CO_BT_H_ diff --git a/services/ble_stack/common/api/co_bt_defines.h b/services/ble_stack/common/api/co_bt_defines.h new file mode 100644 index 0000000..64021ec --- /dev/null +++ b/services/ble_stack/common/api/co_bt_defines.h @@ -0,0 +1,2614 @@ +#ifndef CO_BT_DEFINES_H_ +#define CO_BT_DEFINES_H_ + + +/** + **************************************************************************************** + * @addtogroup CO_BT_DEFINES Common Bluetooth defines + * @ingroup CO_BT + * @brief Common Bluetooth definitions and structures. + * + * @{ + **************************************************************************************** + */ + + +/* + * DEFINES + **************************************************************************************** + */ + +/** + * BD Address format (values in bytes) + * | 3B | 1B | 2B | + * | LAP | UAP | NAP | + */ +#define BD_ADDR_LEN 6 +#define BD_ADDR_LAP_POS 0 +#define BD_ADDR_LAP_LEN 3 +#define BD_ADDR_UAP_POS BD_ADDR_LAP_LEN +#define BD_ADDR_UAP_LEN 1 +#define BD_ADDR_NAP_POS BD_ADDR_UAP_LEN +#define BD_ADDR_NAP_LEN 2 + +///Length of fields in Bluetooth messages, in number of bytes +#define EVT_MASK_LEN 8 +#define DEV_CLASS_LEN 3 +#define ACO_LEN 12 +#define SRES_LEN 0x04 +#define ACCESS_ADDR_LEN 0x04 +#define LE_PASSKEY_LEN 0x04 +#define BD_NAME_SIZE 0xF8 // Was 0x20 for BLE HL +#define ADV_DATA_LEN 0x1F +#define EXT_ADV_DATA_MAX_LEN 229 // HCI:7.7.65.13 +#define PER_ADV_DATA_MAX_LEN 248 // HCI:7.7.65.16 +#define BLE_DATA_LEN 0x1F +#define BLE_ADV_FLAG_PART_LEN 0x03 +#define BLE_ADV_DATA_WITHOUT_FLAG_LEN (BLE_DATA_LEN) +#define BLE_ADV_DATA_WITH_FLAG_LEN (BLE_DATA_LEN - BLE_ADV_FLAG_PART_LEN) +#define SCAN_RSP_DATA_LEN (BLE_DATA_LEN) +#define CONNECT_REQ_DATA_LEN 0x16 +#define LE_CHNL_MAP_LEN 0x05 +#define CHNL_MAP_LEN 0x0A +#define KEY_LEN 0x10 +#define PIN_CODE_MIN_LEN 0x01 +#define PIN_CODE_MAX_LEN 0x10 +#define PRIV_KEY_192_LEN 24 +#define PUB_KEY_192_LEN 48 +#define PRIV_KEY_256_LEN 32 +#define PUB_KEY_256_LEN 64 +#define CFM_LEN 0x10 +#define ENC_DATA_LEN 0x10 +#define RAND_VAL_LEN 0x10 +#define RAND_NB_LEN 0x08 +#define LE_FEATS_LEN 0x08 +#define SUPP_CMDS_LEN 0x40 +#define FEATS_LEN 0x08 +#define NAME_VECT_SIZE 14 +#define LMP_FEATS_LEN 0x08 +#define LE_STATES_LEN 0x08 +#define WHITE_LIST_LEN 0x0A +#define LE_FREQ_LEN 0x28 +#define LE_DATA_FREQ_LEN 0x25 +#define CRC_INIT_LEN 0x03 +#define SESS_KEY_DIV_LEN 0x08 +#define INIT_VECT_LEN 0x04 +#define MIC_LEN 0x04 +#define IV_LEN 0x08 +#define SK_DIV_LEN 0x10 + +// Session Key Diversifier Master or slave +#define SKD_M_OFFSET 0x00 +#define SKD_S_OFFSET 0x08 +// Initialization Vector Master or slave +#define IV_M_OFFSET 0x00 +#define IV_S_OFFSET 0x04 + + +// BT 4.2 - Secure Connections +#define PUBLIC_KEY_P256_LEN 0x20 +#define DHKEY_CHECK_LEN 0x10 + +#define DH_KEY_LEN 0x20 + +/// Maximum maskable event code +#define EVT_MASK_CODE_MAX EVT_MASK_LEN * 8 + +/// Advertising and Data Channel Indices (chapter 6.B.1.4.1) +#define DATA_CHANNEL_MIN 0 +#define DATA_CHANNEL_MAX 36 +#define DATA_CHANNEL_NB 37 +#define ADV_CHANNEL_37 37 +#define ADV_CHANNEL_38 38 +#define ADV_CHANNEL_39 39 + +/// Minimum number of used channel in the map (chapter 6.B.4.5.8.1) +#define DATA_CHANNEL_USED_NB_MIN 2 + +/// Advertising interval (in 625us slot) (chapter 2.E.7.8.5) +#define ADV_INTERVAL_MIN 0x0020 //(20 ms) +#define ADV_INTERVAL_MAX 0x4000 //(10.24 sec) +#define ADV_INTERVAL_DFT 0x0800 //(1.28 sec) + +/// Scanning interval (in 625us slot) (chapter 2.E.7.8.10) +#define SCAN_INTERVAL_MIN 0x0004 //(2.5 ms) +#define SCAN_INTERVAL_MAX 0x4000 //(10.24 sec) +#define SCAN_INTERVAL_DFT 0x0010 //(10 ms) + +/// Scanning window (in 625us slot) (chapter 2.E.7.8.10) +#define SCAN_WINDOW_MIN 0x0004 //(2.5 ms) +#define SCAN_WINDOW_MAX 0x4000 //(10.24 sec) +#define SCAN_WINDOW_DFT 0x0010 //(10 ms) + +/// Connection interval (N*1.250ms) (chapter 2.E.7.8.12) +#define CON_INTERVAL_MIN 0x0006 //(7.5 msec) +#define CON_INTERVAL_MAX 0x0C80 //(4 sec) +/// Connection latency (N*cnx evt) (chapter 2.E.7.8.12) +#define CON_LATENCY_MIN 0x0000 +#define CON_LATENCY_MAX 0x01F3 // (499) +/// Supervision TO (N*10ms) (chapter 2.E.7.8.12) +#define CON_SUP_TO_MIN 0x000A //(100 msec) +#define CON_SUP_TO_MAX 0x0C80 //(32 sec) + +/// Format of the Advertising packets +#define ADV_ADDR_OFFSET 0 +#define ADV_ADDR_LEN BD_ADDR_LEN +#define ADV_DATA_OFFSET (ADV_ADDR_OFFSET + ADV_ADDR_LEN) + +/// BLE supported features +//byte 0 +#define BLE_ENC_FEAT 0x01 +#define BLE_CON_PARAM_REQ_PROC_FEAT 0x02 +#define BLE_REJ_IND_EXT_FEAT 0x04 +#define BLE_SLAVE_INIT_EXCHG_FEAT 0x08 +#define BLE_PING_FEAT 0x10 +#define BLE_LENGTH_EXT_FEAT 0x20 +#define BLE_LL_PRIVACY_FEAT 0x40 +#define BLE_EXT_SCAN_POLICY_FEAT 0x80 + +//byte 1 +#define BLE_2M_PHY_FEAT 0x01 +#define BLE_STABLE_MOD_IDX_TX_FEAT 0x02 +#define BLE_STABLE_MOD_IDX_RX_FEAT 0x04 +#define BLE_CODED_PHY_FEAT 0x08 +#define BLE_EXT_ADV_FEAT 0x10 +#define BLE_PER_ADV_FEAT 0x20 +#define BLE_CHAN_SEL_ALGO_2_FEAT 0x40 +#define BLEPWR_CLASS_1_FEAT 0x80 + +//byte 2 +#define BLE_MIN_NUM_USED_CHAN_PROC 0x01 + +// List of supported BLE Features +enum ble_feature +{ + BLE_FEAT_ENC = (0), + BLE_FEAT_CON_PARAM_REQ_PROC = (1), + BLE_FEAT_REJ_IND_EXT = (2), + BLE_FEAT_SLAVE_INIT_EXCHG = (3), + BLE_FEAT_PING = (4), + BLE_FEAT_LENGTH_EXT = (5), + BLE_FEAT_LL_PRIVACY = (6), + BLE_FEAT_EXT_SCAN_POLICY = (7), + BLE_FEAT_2MBPS = (8), + BLE_FEAT_STABLE_MOD = (9), +}; + +/// BLE supported states +//byte 0 +#define BLE_NON_CON_ADV_STATE 0x01 +#define BLE_DISC_ADV_STATE 0x02 +#define BLE_CON_ADV_STATE 0x04 +#define BLE_HDC_DIRECT_ADV_STATE 0x08 +#define BLE_PASS_SCAN_STATE 0x10 +#define BLE_ACTIV_SCAN_STATE 0x20 +#define BLE_INIT_MASTER_STATE 0x40 +#define BLE_CON_SLAVE_STATE 0x80 + +//byte 1 +#define BLE_NON_CON_ADV_PASS_SCAN_STATE 0x01 +#define BLE_DISC_ADV_PASS_SCAN_STATE 0x02 +#define BLE_CON_ADV_PASS_SCAN_STATE 0x04 +#define BLE_HDC_DIRECT_ADV_PASS_SCAN_STATE 0x08 +#define BLE_NON_CON_ADV_ACTIV_SCAN_STATE 0x10 +#define BLE_DISC_ADV_ACTIV_SCAN_STATE 0x20 +#define BLE_CON_ADV_ACTIV_SCAN_STATE 0x40 +#define BLE_HDC_DIRECT_ADV_ACTIV_SCAN_STATE 0x80 + +//byte 2 +#define BLE_NON_CON_ADV_INIT_STATE 0x01 +#define BLE_DISC_ADV_INIT_STATE 0x02 +#define BLE_NON_CON_ADV_MASTER_STATE 0x04 +#define BLE_DISC_ADV_MASTER_STATE 0x08 +#define BLE_NON_CON_ADV_SLAVE_STATE 0x10 +#define BLE_DISC_ADV_SLAVE_STATE 0x20 +#define BLE_PASS_SCAN_INIT_STATE 0x40 +#define BLE_ACTIV_SCAN_INIT_STATE 0x80 + +//byte 3 +#define BLE_PASS_SCAN_MASTER_STATE 0x01 +#define BLE_ACTIV_SCAN_MASTER_STATE 0x02 +#define BLE_PASS_SCAN_SLAVE_STATE 0x04 +#define BLE_ACTIV_SCAN_SLAVE_STATE 0x08 +#define BLE_INIT_MASTER_MASTER_STATE 0x10 +#define BLE_LDC_DIRECT_ADV_STATE 0x20 +#define BLE_LDC_DIRECT_ADV_PASS_SCAN_STATE 0x40 +#define BLE_LDC_DIRECT_ADV_ACTIV_SCAN_STATE 0x80 + +//byte 4 +#define BLE_CON_ADV_INIT_MASTER_SLAVE_STATE 0x01 +#define BLE_HDC_DIRECT_ADV_INIT_MASTER_SLAVE_STATE 0x02 +#define BLE_LDC_DIRECT_ADV_INIT_MASTER_SLAVE_STATE 0x04 +#define BLE_CON_ADV_MASTER_SLAVE_STATE 0x08 +#define BLE_HDC_DIRECT_ADV_MASTER_SLAVE_STATE 0x10 +#define BLE_LDC_DIRECT_ADV_MASTER_SLAVE_STATE 0x20 +#define BLE_CON_ADV_SLAVE_SLAVE_STATE 0x40 +#define BLE_HDC_DIRECT_ADV_SLAVE_SLAVE_STATE 0x80 + +//byte 5 +#define BLE_LDC_DIRECT_ADV_SLAVE_SLAVE_STATE 0x01 +#define BLE_INIT_MASTER_SLAVE_STATE 0x02 + +/// BLE supported commands +//byte0 +#define BLE_DISC_CMD 0x20 +//byte2 +#define BLE_RD_REM_VERS_CMD 0x80 +//byte5 +#define BLE_SET_EVT_MSK_CMD 0x40 +#define BLE_RESET_CMD 0x80 +//byte10 +#define BLE_RD_TX_PWR_CMD 0x04 +#define BLE_SET_CTRL_TO_HL_FCTRL_CMD 0x20 +#define BLE_HL_BUF_SIZE_CMD 0x40 +#define BLE_HL_NB_CMP_PKT_CMD 0x80 +//byte14 +#define BLE_RD_LOC_VERS_CMD 0x08 +#define BLE_RD_LOC_SUP_FEAT_CMD 0x20 +#define BLE_RD_BUF_SIZE_CMD 0x80 +//byte15 +#define BLE_RD_BD_ADDR_CMD 0x02 +#define BLE_RD_RSSI_CMD 0x20 +//byte22 +#define BLE_SET_EVT_MSK_PG2_CMD 0x04 +//byte25 +#define BLE_LE_SET_EVT_MSK_CMD 0x01 +#define BLE_LE_RD_BUF_SIZE_CMD 0x02 +#define BLE_LE_RD_LOC_SUP_FEAT_CMD 0x04 +#define BLE_LE_SET_RAND_ADDR_CMD 0x10 +#define BLE_LE_SET_ADV_PARAM_CMD 0x20 +#define BLE_LE_RD_ADV_TX_PWR_CMD 0x40 +#define BLE_LE_SET_ADV_DATA_CMD 0x80 +//byte26 +#define BLE_LE_SET_SC_RSP_DATA_CMD 0x01 +#define BLE_LE_SET_ADV_EN_CMD 0x02 +#define BLE_LE_SET_SC_PARAM_CMD 0x04 +#define BLE_LE_SET_SC_EN_CMD 0x08 +#define BLE_LE_CREAT_CNX_CMD 0x10 +#define BLE_LE_CREAT_CNX_CNL_CMD 0x20 +#define BLE_LE_RD_WL_SIZE_CMD 0x40 +#define BLE_LE_CLEAR_WL_CMD 0x80 +//byte27 +#define BLE_LE_ADD_DEV_WL_CMD 0x01 +#define BLE_LE_REM_DEV_WL_CMD 0x02 +#define BLE_LE_CNX_UPDATE_CMD 0x04 +#define BLE_LE_SET_HL_CH_CLASS_CMD 0x08 +#define BLE_LE_RD_CH_MAP_CMD 0x10 +#define BLE_LE_RD_REM_FEAT_CMD 0x20 +#define BLE_LE_ENCRYPT_CMD 0x40 +#define BLE_LE_RAND_CMD 0x80 +//byte28 +#define BLE_LE_START_ENC_CMD 0x01 +#define BLE_LE_LTK_REQ_RPLY_CMD 0x02 +#define BLE_LE_LTK_REQ_NEG_RPLY_CMD 0x04 +#define BLE_LE_RD_SUPP_STATES_CMD 0x08 +#define BLE_LE_RX_TEST_CMD 0x10 +#define BLE_LE_TX_TEST_CMD 0x20 +#define BLE_LE_STOP_TEST_CMD 0x40 + +//byte32 +#define BLE_RD_AUTH_PAYL_TO_CMD 0x10 +#define BLE_WR_AUTH_PAYL_TO_CMD 0x20 + + +//byte33 +#define BLE_LE_REM_CON_PARA_REQ_RPLY_CMD 0x10 +#define BLE_LE_REM_CON_PARA_REQ_NEG_RPLY_CMD 0x20 +#define BLE_LE_SET_DATA_LEN_CMD 0x40 +#define BLE_LE_RD_SUGGTED_DFT_DATA_LEN_CMD 0x80 + +//byte34 +#define BLE_LE_WR_SUGGTED_DFT_DATA_LEN_CMD 0x01 +#define BLE_LE_RD_LOC_P256_PUB_KEY_CMD 0x02 +#define BLE_LE_GEN_DH_KEY_CMD 0x04 +#define BLE_LE_ADD_DEV_TO_RESOLV_LIST_CMD 0x08 +#define BLE_LE_REM_DEV_FROM_RESOLV_LIST_CMD 0x10 +#define BLE_LE_CLEAR_RESOLV_LIST_CMD 0x20 +#define BLE_LE_RD_RESOLV_LIST_SIZE_CMD 0x40 +#define BLE_LE_RD_PEER_RESOLV_ADDR_CMD 0x80 + +//byte35 +#define BLE_LE_RD_LOCAL_RESOLV_ADDR_CMD 0x01 +#define BLE_LE_SET_ADDR_RESOL_CMD 0x02 +#define BLE_LE_SET_RESOLV_PRIV_ADDR_TO_CMD 0x04 +#define BLE_LE_RD_MAX_DATA_LEN_CMD 0x08 + +// Inquiry Length HCI:7.1.1 +#define INQ_LEN_MIN 0x01 +#define INQ_LEN_MAX 0x30 + +// Inquiry Length HCI:7.1.3 +#define INQ_MIN_PER_LEN_MIN 0x0002 +#define INQ_MIN_PER_LEN_MAX 0xFFFE +#define INQ_MAX_PER_LEN_MIN 0x0003 +#define INQ_MAX_PER_LEN_MAX 0xFFFF + +// IAC support +#define NB_IAC_MIN 0x01 +#define NB_IAC_MAX 0x40 + + +/// Logical Transport Adresses BB:4.2 +#define LT_ADDR_BCST 0x00 +#define LT_ADDR_MIN 0x01 +#define LT_ADDR_MAX 0x07 + +/// Link type HCI:7.7.3 +#define SCO_TYPE 0 +#define ACL_TYPE 1 +#define ESCO_TYPE 2 +#define UNKNOWN_TYPE 3 // Used in LM +#define LE_TYPE 4 + + +/// Allow Role Switch HCI:4.6.8 +#define MASTER_ROLE 0 +#define SLAVE_ROLE 1 +#define UNKNOWN_ROLE 0xFF //Used in LC to init the links role + +/// Link policy HCI:4.6.9 and HCI:4.6.10 +#define POLICY_SWITCH 0x0001 +#define POLICY_HOLD 0x0002 +#define POLICY_SNIFF 0x0004 +#define POLICY_PARK 0x0008 + +/// Allow Role Switch HCI:4.5.5 +#define ROLE_SWITCH_NOT_ALLOWED 0 +#define ROLE_SWITCH_ALLOWED 1 + +/// AcceptConnection Role HCI:4.5.8 +#define ACCEPT_SWITCH_TO_MASTER 0 +#define ACCEPT_REMAIN_SLAVE 1 + +/// Packet Type Flags HCI:7.1.14 +#define PACKET_TYPE_EDR_MSK 0x330E +#define PACKET_TYPE_GFSK_MSK 0xCCF8 +#define PACKET_TYPE_NO_2_DH1_FLAG 0x0002 +#define PACKET_TYPE_NO_3_DH1_FLAG 0x0004 +#define PACKET_TYPE_DM1_FLAG 0x0008 +#define PACKET_TYPE_DH1_FLAG 0x0010 +#define PACKET_TYPE_HV1_FLAG 0x0020 +#define PACKET_TYPE_HV2_FLAG 0x0040 +#define PACKET_TYPE_HV3_FLAG 0x0080 +#define PACKET_TYPE_NO_2_DH3_FLAG 0x0100 +#define PACKET_TYPE_NO_3_DH3_FLAG 0x0200 +#define PACKET_TYPE_DM3_FLAG 0x0400 +#define PACKET_TYPE_DH3_FLAG 0x0800 +#define PACKET_TYPE_NO_2_DH5_FLAG 0x1000 +#define PACKET_TYPE_NO_3_DH5_FLAG 0x2000 +#define PACKET_TYPE_DM5_FLAG 0x4000 +#define PACKET_TYPE_DH5_FLAG 0x8000 + +/// Synchronous Packet Types HCI:7.1.14 +#define SYNC_PACKET_TYPE_HV1_FLAG 0x0001 +#define SYNC_PACKET_TYPE_HV2_FLAG 0x0002 +#define SYNC_PACKET_TYPE_HV3_FLAG 0x0004 +#define SYNC_PACKET_TYPE_EV3_FLAG 0x0008 +#define SYNC_PACKET_TYPE_EV4_FLAG 0x0010 +#define SYNC_PACKET_TYPE_EV5_FLAG 0x0020 + +#define SYNC_PACKET_TYPE_NO_EV3_2_FLAG 0x0040 +#define SYNC_PACKET_TYPE_NO_EV3_3_FLAG 0x0080 +#define SYNC_PACKET_TYPE_NO_EV5_2_FLAG 0x0100 +#define SYNC_PACKET_TYPE_NO_EV5_3_FLAG 0x0200 + +#define SYNC_PACKET_TYPE_EV3_2_FLAG 0x0040 +#define SYNC_PACKET_TYPE_EV3_3_FLAG 0x0080 +#define SYNC_PACKET_TYPE_EV5_2_FLAG 0x0100 +#define SYNC_PACKET_TYPE_EV5_3_FLAG 0x0200 + +/// RWBT 1.2 +#define SYNC_EV3_PACKET_SIZE 30 +#define SYNC_EV4_PACKET_SIZE 120 +#define SYNC_EV5_PACKET_SIZE 180 + +/// Packet Boundary Flag HCI:5.4.2 +#define PBF_1ST_NF_HL_FRAG 0x00 // Non-flushable packets +#define PBF_CONT_HL_FRAG 0x01 +#define PBF_1ST_HL_FRAG 0x02 +#define PBF_CMP_PDU 0x03 +//#define PBF_MASK 0x03 + +/// Broadcast Flag HCI:5.4.2 +#define BCF_P2P 0x00 +#define BCF_ACTIVE_SLV_BCST 0x01 +#define BCF_PARK_SLV_BCST 0x02 +#define BCF_MASK 0x03 + +/// Synchronous Packet Status Flag HCI:5.4.3 +#define CORRECTLY_RX_FLAG 0x00 +#define POSSIBLY_INVALID_FLAG 0x01 +#define NO_RX_DATA_FLAG 0x02 +#define PARTIALLY_LOST_FLAG 0x03 + +/// Park mode defines LMP:3.17 +#define MACCESS_MSK 0x0F +#define ACCSCHEM_MSK 0xF0 + +/// Support 3 feature pages +#define FEATURE_PAGE_MAX 3 + +#define FEATURE_PAGE_0 0 +#define FEATURE_PAGE_1 1 +#define FEATURE_PAGE_2 2 + +/// Feature mask definition LMP:3.3 +#define B0_3_SLOT_POS 0 +#define B0_3_SLOT_MSK 0x01 +#define B0_5_SLOT_POS 1 +#define B0_5_SLOT_MSK 0x02 +#define B0_ENC_POS 2 +#define B0_ENC_MSK 0x04 +#define B0_SLOT_OFF_POS 3 +#define B0_SLOT_OFF_MSK 0x08 +#define B0_TIMING_ACCU_POS 4 +#define B0_TIMING_ACCU_MSK 0x10 +#define B0_ROLE_SWITCH_POS 5 +#define B0_ROLE_SWITCH_MSK 0x20 +#define B0_HOLD_MODE_POS 6 +#define B0_HOLD_MODE_MSK 0x40 +#define B0_SNIFF_MODE_POS 7 +#define B0_SNIFF_MODE_MSK 0x80 + +#define B1_PARK_POS 0 +#define B1_PARK_MSK 0x01 +#define B1_RSSI_POS 1 +#define B1_RSSI_MSK 0x02 +#define B1_CQDDR_POS 2 +#define B1_CQDDR_MSK 0x04 +#define B1_SCO_POS 3 +#define B1_SCO_MSK 0x08 +#define B1_HV2_POS 4 +#define B1_HV2_MSK 0x10 +#define B1_HV3_POS 5 +#define B1_HV3_MSK 0x20 +#define B1_MULAW_POS 6 +#define B1_MULAW_MSK 0x40 +#define B1_ALAW_POS 7 +#define B1_ALAW_MSK 0x80 + +#define B2_CVSD_POS 0 +#define B2_CVSD_MSK 0x01 +#define B2_PAGING_PAR_NEGO_POS 1 +#define B2_PAGING_PAR_NEGO_MSK 0x02 +#define B2_PWR_CTRL_POS 2 +#define B2_PWR_CTRL_MSK 0x04 +#define B2_TRANSPARENT_SCO_POS 3 +#define B2_TRANSPARENT_SCO_MSK 0x08 +#define B2_FLOW_CTRL_LAG_POS 4 +#define B2_FLOW_CTRL_LAG_MSK 0x70 +#define B2_BCAST_ENC_POS 7 +#define B2_BCAST_ENC_MSK 0x80 + +#define B3_EDR_2MBPS_ACL_POS 1 +#define B3_EDR_2MBPS_ACL_MSK 0x02 +#define B3_EDR_3MBPS_ACL_POS 2 +#define B3_EDR_3MBPS_ACL_MSK 0x04 +#define B3_ENH_INQSCAN_POS 3 +#define B3_ENH_INQSCAN_MSK 0x08 +#define B3_INT_INQSCAN_POS 4 +#define B3_INT_INQSCAN_MSK 0x10 +#define B3_INT_PAGESCAN_POS 5 +#define B3_INT_PAGESCAN_MSK 0x20 +#define B3_RSSI_INQ_RES_POS 6 +#define B3_RSSI_INQ_RES_MSK 0x40 +#define B3_ESCO_EV3_POS 7 +#define B3_ESCO_EV3_MSK 0x80 + +#define B4_EV4_PKT_POS 0 +#define B4_EV4_PKT_MSK 0x01 +#define B4_EV5_PKT_POS 1 +#define B4_EV5_PKT_MSK 0x02 +#define B4_AFH_CAP_SLV_POS 3 +#define B4_AFH_CAP_SLV_MSK 0x08 +#define B4_AFH_CLASS_SLV_POS 4 +#define B4_AFH_CLASS_SLV_MSK 0x10 +#define B4_BR_EDR_NOT_SUPP_POS 5 +#define B4_BR_EDR_NOT_SUPP_MSK 0x20 +#define B4_LE_SUPP_POS 6 +#define B4_LE_SUPP_MSK 0x40 +#define B4_3_SLOT_EDR_ACL_POS 7 +#define B4_3_SLOT_EDR_ACL_MSK 0x80 + +#define B5_5_SLOT_EDR_ACL_POS 0 +#define B5_5_SLOT_EDR_ACL_MSK 0x01 +#define B5_SSR_POS 1 +#define B5_SSR_MSK 0x02 +#define B5_PAUSE_ENC_POS 2 +#define B5_PAUSE_ENC_MSK 0x04 +#define B5_AFH_CAP_MST_POS 3 +#define B5_AFH_CAP_MST_MSK 0x08 +#define B5_AFH_CLASS_MST_POS 4 +#define B5_AFH_CLASS_MST_MSK 0x10 +#define B5_EDR_ESCO_2MBPS_POS 5 +#define B5_EDR_ESCO_2MBPS_MSK 0x20 +#define B5_EDR_ESCO_3MBPS_POS 6 +#define B5_EDR_ESCO_3MBPS_MSK 0x40 +#define B5_3_SLOT_EDR_ESCO_POS 7 +#define B5_3_SLOT_EDR_ESCO_MSK 0x80 + +#define B6_EIR_POS 0 +#define B6_EIR_MSK 0x01 +#define B6_SIM_LE_BREDR_DEV_CAP_POS 1 +#define B6_SIM_LE_BREDR_DEV_CAP_MSK 0x02 +#define B6_SSP_POS 3 +#define B6_SSP_MSK 0x08 +#define B6_ENCAPS_PDU_POS 4 +#define B6_ENCAPS_PDU_MSK 0x10 +#define B6_ERR_DATA_REP_POS 5 +#define B6_ERR_DATA_REP_MSK 0x20 +#define B6_NONFLUSH_PBF_POS 6 +#define B6_NONFLUSH_PBF_MSK 0x40 + +#define B7_LST_CHANGE_EVT_POS 0 +#define B7_LST_CHANGE_EVT_MSK 0x01 +#define B7_INQRES_TXPOW_POS 1 +#define B7_INQRES_TXPOW_MSK 0x02 +#define B7_ENH_PWR_CTRL_POS 2 +#define B7_ENH_PWR_CTRL_MSK 0x04 +#define B7_EXT_FEATS_POS 7 +#define B7_EXT_FEATS_MSK 0x80 + +/// Extended feature mask definition page 1 LMP:3.3 +#define B0_HOST_SSP_POS 0 +#define B0_HOST_SSP_MSK 0x01 +#define B0_HOST_LE_POS 1 +#define B0_HOST_LE_MSK 0x02 +#define B0_HOST_LE_BR_EDR_POS 2 +#define B0_HOST_LE_BR_EDR_MSK 0x04 +#define B0_HOST_SECURE_CON_POS 3 +#define B0_HOST_SECURE_CON_MSK 0x08 + +/// Extended feature mask definition page 2 LMP:3.3 +#define B0_CSB_MASTER_POS 0 +#define B0_CSB_MASTER_MSK 0x01 +#define B0_CSB_SLAVE_POS 1 +#define B0_CSB_SLAVE_MSK 0x02 +#define B0_SYNC_TRAIN_POS 2 +#define B0_SYNC_TRAIN_MSK 0x04 +#define B0_SYNC_SCAN_POS 3 +#define B0_SYNC_SCAN_MSK 0x08 +#define B0_INQ_RES_NOTIF_EVT_POS 4 +#define B0_INQ_RES_NOTIF_EVT_MSK 0x10 +#define B0_GEN_INTERL_SCAN_POS 5 +#define B0_GEN_INTERL_SCAN_MSK 0x20 +#define B0_COARSE_CLK_ADJ_POS 6 +#define B0_COARSE_CLK_ADJ_MSK 0x40 + +#define B1_SEC_CON_CTRL_POS 0 +#define B1_SEC_CON_CTRL_MSK 0x01 +#define B1_PING_POS 1 +#define B1_PING_MSK 0x02 +#define B1_TRAIN_NUDGING_POS 3 +#define B1_TRAIN_NUDGING_MSK 0x08 + +/// Features definitions +#define FEAT_3_SLOT_BIT_POS 0 +#define FEAT_5_SLOT_BIT_POS 1 +#define FEAT_ENC_BIT_POS 2 +#define FEAT_SLOT_OFFSET_BIT_POS 3 +#define FEAT_TIMING_ACC_BIT_POS 4 +#define FEAT_SWITCH_BIT_POS 5 +#define FEAT_HOLD_BIT_POS 6 +#define FEAT_SNIFF_BIT_POS 7 + +#define FEAT_PARK_BIT_POS 8 +#define FEAT_RSSI_BIT_POS 9 +#define FEAT_QUALITY_BIT_POS 10 +#define FEAT_SCO_BIT_POS 11 +#define FEAT_HV2_BIT_POS 12 +#define FEAT_HV3_BIT_POS 13 +#define FEAT_ULAW_BIT_POS 14 +#define FEAT_ALAW_BIT_POS 15 + +#define FEAT_CVSD_BIT_POS 16 +#define FEAT_PAGING_BIT_POS 17 +#define FEAT_POWER_BIT_POS 18 +#define FEAT_TRANSP_SCO_BIT_POS 19 +#define FEAT_BCAST_ENCRYPT_BIT_POS 23 + +#define FEAT_EDR_2MB_BIT_POS 25 +#define FEAT_EDR_3MB_BIT_POS 26 +#define FEAT_ENH_INQSCAN_BIT_POS 27 +#define FEAT_INT_INQSCAN_BIT_POS 28 +#define FEAT_INT_PAGESCAN_BIT_POS 29 +#define FEAT_RSSI_INQRES_BIT_POS 30 +#define FEAT_EV3_BIT_POS 31 + +#define FEAT_EV4_BIT_POS 32 +#define FEAT_EV5_BIT_POS 33 +#define FEAT_AFH_CAPABLE_S_BIT_POS 35 +#define FEAT_AFH_CLASS_S_BIT_POS 36 +#define FEAT_BR_EDR_NO_SUPP_BIT_POS 37 +#define FEAT_LE_BIT_POS 38 +#define FEAT_3_SLOT_EDR_BIT_POS 39 +#define FEAT_5_SLOT_EDR_BIT_POS 40 +#define FEAT_SNIFF_SUBRAT_BIT_POS 41 +#define FEAT_PAUSE_ENCRYPT_BIT_POS 42 +#define FEAT_AFH_CAPABLE_M_BIT_POS 43 +#define FEAT_AFH_CLASS_M_BIT_POS 44 +#define FEAT_EDR_ESCO_2MB_BIT_POS 45 +#define FEAT_EDR_ESCO_3MB_BIT_POS 46 +#define FEAT_3_SLOT_EDR_ESCO_BIT_POS 47 +#define FEAT_EIR_BIT_POS 48 +#define FEAT_LE_BR_EDR_BIT_POS 49 +#define FEAT_SSP_BIT_POS 51 +#define FEAT_ENCAP_PDU_BIT_POS 52 +#define FEAT_ERRO_DATA_REP_BIT_POS 53 +#define FEAT_NFLUSH_PBF_BIT_POS 54 +#define FEAT_LSTO_CHG_EVT_BIT_POS 56 +#define FEAT_INQ_TXPWR_BIT_POS 57 +#define FEAT_EPC_BIT_POS 58 +#define FEAT_EXT_FEATS_BIT_POS 63 +#define FEAT_SSP_HOST_BIT_POS 64 +#define FEAT_LE_HOST_BIT_POS 65 +#define FEAT_LE_BR_EDR_HOST_BIT_POS 66 +#define FEAT_SEC_CON_HOST_BIT_POS 67 + +#define FEAT_CSB_MASTER_BIT_POS 128 +#define FEAT_CSB_SLAVE_BIT_POS 129 +#define FEAT_SYNC_TRAIN_BIT_POS 130 +#define FEAT_SYNC_SCAN_BIT_POS 131 +#define FEAT_INQ_RES_NOTIF_EVT_BIT_POS 132 +#define FEAT_GEN_INTERL_SCAN_BIT_POS 133 +#define FEAT_COARSE_CLK_ADJ_BIT_POS 134 +#define FEAT_SEC_CON_CTRL_BIT_POS 136 +#define FEAT_PING_BIT_POS 137 +#define FEAT_TRAIN_NUDGING_BIT_POS 139 + +/// Maximum number of feature bits per page (8 bytes x 8 bits) +#define MAX_FEAT_BITS_PER_PAGE 64 + +/// Poll interval defines LMP:5.2 +#define POLL_INTERVAL_MIN 0x0006 +#define POLL_INTERVAL_DFT 0x0028 +#define POLL_INTERVAL_MAX 0x1000 + +/// Power Adjustment Request LMP:5.2 +#define PWR_ADJ_REQ_DEC_1_STEP 0x00 +#define PWR_ADJ_REQ_INC_1_STEP 0x01 +#define PWR_ADJ_REQ_INC_MAX 0x02 + +/// Power Adjustment Response LMP:5.2 +#define PWR_ADJ_RES_GFSK_POS 0 +#define PWR_ADJ_RES_GFSK_MASK 0x03 +#define PWR_ADJ_RES_DQPSK_POS 2 +#define PWR_ADJ_RES_DQPSK_MASK 0x0C +#define PWR_ADJ_RES_8DPSK_POS 4 +#define PWR_ADJ_RES_8DPSK_MASK 0x30 + +#define PWR_ADJ_RES_NOT_SUPP 0x00 +#define PWR_ADJ_RES_CHG_1_STEP 0x01 +#define PWR_ADJ_RES_MAX 0x02 +#define PWR_ADJ_RES_MIN 0x03 + +/// Nb of Broadcast retransmissions defines +#define NB_BROADCAST_DFT 0x01 + +/// Nb of Broadcast CLK_ADJ PDU Baseband:4.1.14.1 +#define NB_BROADCAST_CLK_ADJ 0x06 + +/// Min PCA clk_adj_instant (in slots) LMP:4.1.14.1 +#define PCA_INSTANT_MIN 12 + +/// Piconet Clock Adjustment clk_adj_mode LMP:4.1.14.1 +#define CLK_ADJ_BEFORE_INSTANT 0 +#define CLK_ADJ_AFTER_INSTANT 1 + + +/// Different packet types BaseBand:6.7 +/* Packet and buffer sizes. These sizes do not include payload header (except for FHS + * packet where there is no payload header) since payload header is written or read by + * the RWBT in a different control structure part (TX/RXPHDR) */ +#define FHS_PACKET_SIZE 18 +#define DM1_PACKET_SIZE 17 +#define DH1_PACKET_SIZE 27 +#define DH1_2_PACKET_SIZE 54 +#define DH1_3_PACKET_SIZE 83 +#define DV_ACL_PACKET_SIZE 9 +#define DM3_PACKET_SIZE 121 +#define DH3_PACKET_SIZE 183 +#define DH3_2_PACKET_SIZE 367 +#define DH3_3_PACKET_SIZE 552 +#define DM5_PACKET_SIZE 224 +#define DH5_PACKET_SIZE 339 +#define DH5_2_PACKET_SIZE 679 +#define DH5_3_PACKET_SIZE 1021 +#define AUX1_PACKET_SIZE 29 + +#define HV1_PACKET_SIZE 10 +#define HV2_PACKET_SIZE 20 +#define HV3_PACKET_SIZE 30 +#define EV3_PACKET_SIZE 30 +#define EV3_2_PACKET_SIZE 60 +#define EV3_3_PACKET_SIZE 90 +#define EV4_PACKET_SIZE 120 +#define EV5_PACKET_SIZE 180 +#define EV5_2_PACKET_SIZE 360 +#define EV5_3_PACKET_SIZE 540 + +/// SCO Packet coding LMP:5.2 +#define SCO_PACKET_HV1 0x00 +#define SCO_PACKET_HV2 0x01 +#define SCO_PACKET_HV3 0x02 + +/// eSCO Packet coding LMP:5.2 +#define ESCO_PACKET_NULL 0x00 +#define ESCO_PACKET_EV3 0x07 +#define ESCO_PACKET_EV4 0x0C +#define ESCO_PACKET_EV5 0x0D +#define ESCO_PACKET_EV3_2 0x26 +#define ESCO_PACKET_EV3_3 0x37 +#define ESCO_PACKET_EV5_2 0x2C +#define ESCO_PACKET_EV5_3 0x3D + +/// Max number of HV packet BaseBand:4.4.2.1 +#define MAX_NB_HV1 1 +#define MAX_NB_HV2 2 +#define MAX_NB_HV3 3 + +/// Tsco (ScoInterval) BaseBand:4.4.2.1 +#define TSCO_HV1 2 +#define TSCO_HV2 4 +#define TSCO_HV3 6 + +/* Inquiry train repetition length , Baseband :Table 10.4 + * - 256 repetitions if no SCO + * - 512 repetitions if 1 SCO + * - 768 repetitions if 2 SCO */ +#define INQ_TRAIN_LENGTH_NO_SCO 256 +#define INQ_TRAIN_LENGTH_1_SCO 512 +#define INQ_TRAIN_LENGTH_2_SCO 768 + +/* Counter for train length, Npage (N*16 slots) depends on the slave page scan mode and + * the number of active SCO: + * | SR mode | no SCO | one SCO | two SCO | + * | R0 | >=1 | >=2 | >=3 | + * | R1 | >=128 | >=256 | >=384 | + * | R2 | >=256 | >=512 | >=768 | */ +#define PAGE_TRAIN_LENGTH_R0 1 +#define PAGE_TRAIN_LENGTH_R1 128 +#define PAGE_TRAIN_LENGTH_R2 256 + +/// Synchronisation defines +#define NORMAL_SYNC_POS (64 + 4) // End of Synchro word at bit 68 (64 + 4) +#define SLOT_SIZE 625 // A slot is 625 us +#define HALF_SLOT_SIZE 625 // A half slot is 312.5 us (in half us) + +/// Baseband timeout default value, Baseband timers: 1.1 +#define PAGE_RESP_TO_DEF 8 +#define INQ_RESP_TO_DEF 128 +#define NEW_CONNECTION_TO 32 + +/// LMP Response Timeout (in sec) +#define LMP_RSP_TO 30 +/// LLCP Response Timeout (in units of 10 ms) +#define LLCP_RSP_TO 3000 // 30 secs + +/// Athenticated Payload Timeout (in units of 10 ms) +#define AUTH_PAYL_TO_DFT 0x0BB8 // 30 secs +#define AUTH_PAYL_TO_MIN 0x0001 + +/// Voice mute pattern defines +#define MU_LAW_MUTE 0xFF +#define ALAW_CVSD_MUTE 0x55 +#define TRANSP_MUTE 0x00 + +/// Air Mode LMP:5.2 +#define MU_LAW_MODE 0 +#define A_LAW_MODE 1 +#define CVSD_MODE 2 +#define TRANS_MODE 3 + +/// eSCO negotiation State LMP:5.2 +#define ESCO_NEGO_INIT 0 +#define ESCO_NEGO_LATEST_POSSIBLE 1 +#define ESCO_NEGO_SLOT_VIOLATION 2 +#define ESCO_NEGO_LAT_VIOLATION 3 +#define ESCO_NEGO_UNSUPPORTED 4 + +#define SCO_BANDWIDTH 8000 +#define SYNC_BANDWIDTH_DONT_CARE 0xFFFFFFFF + +#define SYNC_MIN_LATENCY 0x0004 +#define SYNC_MAX_LATENCY_ESCO_S1 0x0007 +#define SYNC_MAX_LATENCY_ESCO_S2 0x0007 +#define SYNC_MAX_LATENCY_ESCO_S3 0x000A +#define SYNC_DONT_CARE_LATENCY 0xFFFF + +#define SYNC_NO_RE_TX 0x00 +#define SYNC_RE_TX_POWER 0x01 +#define SYNC_RE_TX_QUALITY 0x02 +#define SYNC_RE_TX_DONT_CARE 0xFF + +/// Timing Control Flags LMP:5.2 +#define TIM_CHANGE_FLAG 0x01 +#define INIT2_FLAG 0x02 +#define ACCESS_WIN_FLAG 0x04 + +/// Packet Type Table defines LMP:4.1.11 +#define PACKET_TABLE_1MBPS 0x00 +#define PACKET_TABLE_2_3MBPS 0x01 + +/// Data Rate defines LMP:5.2 +#define FEC_RATE_MSK 0x01 +#define USE_FEC_RATE 0x00 +#define NO_FEC_RATE 0x01 +#define PREF_PACK_MSK 0x06 +#define NO_PREF_PACK_SIZE 0x00 +#define USE_1_SLOT_PACKET 0x02 +#define USE_3_SLOT_PACKET 0x04 +#define USE_5_SLOT_PACKET 0x06 +#define PREF_EDR_MSK 0x18 +#define USE_DM1_ONLY 0x00 +#define USE_2_MBPS_RATE 0x08 +#define USE_3_MBPS_RATE 0x10 +#define PREF_PACK_EDR_MSK 0x60 +#define USE_1_SLOT_EDR_PKT 0x20 +#define USE_3_SLOT_EDR_PKT 0x40 +#define USE_5_SLOT_EDR_PKT 0x60 + +/// EIR Data Size HCI:6.24 +#define EIR_DATA_SIZE 240 + +/// Voice setting HCI:4.7.29 & 4.7.30 +#define INPUT_COD_LIN 0x0000 +#define INPUT_COD_MULAW 0x0100 +#define INPUT_COD_ALAW 0x0200 +#define INPUT_COD_MSK 0x0300 +#define INPUT_COD_OFF 8 +#define INPUT_DATA_1COMP 0x0000 +#define INPUT_DATA_2COMP 0x0040 +#define INPUT_DATA_SMAG 0x0080 +#define INPUT_DATA_UNSIGNED 0x00C0 +#define INPUT_DATAFORM_MSK 0x00C0 +#define INPUT_DATAFORM_OFF 6 +#define INPUT_SAMP_8BIT 0x0000 +#define INPUT_SAMP_16BIT 0x0020 +#define INPUT_SAMPSIZE_MSK 0x0020 +#define INPUT_SAMPSIZE_OFF 5 +#define LIN_PCM_BIT_POS_MSK 0x001C +#define LIN_PCM_BIT_POS_OFF 2 +#define AIR_COD_CVSD 0x0000 +#define AIR_COD_MULAW 0x0001 +#define AIR_COD_ALAW 0x0002 +#define AIR_COD_TRANS 0x0003 +#define AIR_COD_MSK 0x0003 +#define AIR_COD_OFF 0 + +/// ScanEnable HCI:6.1 +#define BOTH_SCAN_DISABLE 0 +#define INQUIRY_SCAN_ENABLE 1 +#define PAGE_SCAN_ENABLE 2 +#define BOTH_SCAN_ENABLE 3 + +/// PageScanInterval HCI:6.8 +#define PAGE_SCAN_INTV_MIN 0x0012 +#define PAGE_SCAN_INTV_MAX 0x1000 +#define PAGE_SCAN_INTV_DFT 0x0800 + +/// PageScanWindow HCI:6.9 +#define PAGE_SCAN_WIN_MIN 0x0011 +#define PAGE_SCAN_WIN_MAX 0x1000 +#define PAGE_SCAN_WIN_DFT 0x0012 + +/// InquiryScanInterval HCI:6.2 +#define INQ_SCAN_INTV_MIN 0x0012 +#define INQ_SCAN_INTV_MAX 0x1000 +#define INQ_SCAN_INTV_DFT 0x1000 + +/// InquiryScanWindow HCI:6.3 +#define INQ_SCAN_WIN_MIN 0x0011 +#define INQ_SCAN_WIN_MAX 0x1000 +#define INQ_SCAN_WIN_DFT 0x0012 + +/// General/Unlimited Inquiry Access Code (GIAC) +#define GIAC_LAP_0 0x33 +#define GIAC_LAP_1 0x8B +#define GIAC_LAP_2 0x9E + +/// Limited Dedicated Inquiry Access Code (LIAC) +#define LIAC_LAP_0 0x00 +#define LIAC_LAP_1 0x8B +#define LIAC_LAP_2 0x9E + +/// Maximum Dedicated Inquiry Access Code (DIAC MAX) +#define DIAC_MAX_LAP_0 0x3F +#define DIAC_MAX_LAP_1 0x8B +#define DIAC_MAX_LAP_2 0x9E + +/// PIN Type HCI:6.13 +#define VARIABLE_PIN 0 +#define FIXED_PIN 1 + +/// ConnectionAcceptTimeout HCI:6.7 +#define CON_ACCEPT_TO_MIN 0x00A0 +#define CON_ACCEPT_TO_MAX 0xB540 +#define CON_ACCEPT_TO_DFT 0x1FA0 + +/// PageTimeout HCI:6.6 +#define PAGE_TO_MIN 0x0016 +#define PAGE_TO_MAX 0xFFFF +#define PAGE_TO_DFT 0x2000 + +/// Clock offset valid flag in clock offset field HCI:7.1.5/7.1.19 +#define CLK_OFFSET_VALID_FLAG_POS 15 +#define CLK_OFFSET_VALID_FLAG_MSK 0x8000 + +/// AuthenticationEnable HCI:4.7.24 +#define AUTH_DISABLED 0x00 // Default +#define AUTH_ENABLED 0x01 + +/// EncryptionMode HCI:4.7.26 +#define ENC_DISABLED 0x00 // Default +#define ENC_PP_ENABLED 0x01 +#define ENC_PP_BC_ENABLED 0x02 + +/// AutomaticFlushTimeout HCI:4.7.32 +#define AUTO_FLUSH_TIMEOUT_MAX 0x07FF +#define AUTO_FLUSH_TIMEOUT_OFF 0x0000 +#define AUTO_FLUSH_TIMEOUT_DFT AUTO_FLUSH_TIMEOUT_OFF // Default (no automatic flush timeout) + +/// Link Supervision Time Out (in slots) HCI:6.21 +#define LSTO_OFF 0x0000 +#define LSTO_MIN 0x0001 +#define LSTO_DFT 0x7D00 // Default is 20 s +#define LSTO_MAX 0xFFFF + +/// PageScanRepetitionMode HCI:4.5.5 +#define R0 0x00 +#define R1 0x01 +#define R2 0x02 +#define PAGESCAN_REP_DEF R1 // Default + +/// PageScanPeriodMode HCI:4.7.49 +#define P0 0x00 // Default +#define P1 0x01 +#define P2 0x02 + +/// PageScanMode HCI:4.7.51 +#define MANDATORY_PAGE_SCAN_MODE 0x00 // Default + +#define OPT_PAGE_SCAN_MODE_1 0x01 +#define OPT_PAGE_SCAN_MODE_2 0x02 +#define OPT_PAGE_SCAN_MODE_3 0x03 + +/// Encryption Enable HCI:4.5.17 +#define ENCRYPTION_OFF 0x00 +#define ENCRYPTION_ON 0x01 + +/// Country Code HCI:4.8.4 +#define NORTH_AMERICA_EUROPE 0x00 +#define FRANCE 0x01 +#define SPAIN 0x02 +#define JAPAN 0x03 + +/// Loopback mode HCI:7.6.2 +#define NO_LOOPBACK 0x00 // Default +#define LOCAL_LOOPBACK 0x01 +#define REMOTE_LOOPBACK 0x02 + +/// Erroneous Data Reporting HCI:7.3.65 +#define ERR_DATA_REP_DIS 0x00 // Default +#define ERR_DATA_REP_EN 0x01 + +/// LM modes HCI:5.2.20 +#define LM_ACTIVE_MODE 0x00 +#define LM_HOLD_MODE 0x01 +#define LM_SNIFF_MODE 0x02 +#define LM_PARK_MODE 0x03 + +/// Key Type HCI:5.2.24 +#define COMB_KEY 0 +//#define LOCAL_UNIT_KEY 1 +//#define REMOTE_UNIT_KEY 2 +#define DEBUG_COMB_KEY 3 +#define UNAUTH_COMB_KEY_192 4 +#define AUTH_COMB_KEY_192 5 +#define CHANGED_COMB_KEY 6 +#define UNAUTH_COMB_KEY_256 7 +#define AUTH_COMB_KEY_256 8 + +/// Key Flag HCI:5.4.18 +#define SEMI_PERMANENT_KEY 0x00 +#define TEMPORARY_KEY 0x01 + +/// QOS Service Type HCI:4.6.6 +#define QOS_NO_TRAFFIC 0x00 +#define QOS_BEST_EFFORT 0x01 +#define QOS_GUARANTEED 0x02 +#define QOS_NOTSPECIFIED 0xFF + +#define QOS_WILD_CARD 0xFFFFFFFF + +/// RSSI golden range +#define RSSI_GOLDEN_RG 0x00 + +/// Inquiry TX power level (in dBm) HCI:7.3.62 +#define INQ_TX_PWR_DBM_MIN -70 +#define INQ_TX_PWR_DBM_DFT 0 +#define INQ_TX_PWR_DBM_MAX +20 + +/// Bluetooth Test Mode defines Bluetooth Test Mode: Table 3.2 + +#define PAUSE_MODE 0x00 +#define TXTEST0_MODE 0x01 +#define TXTEST1_MODE 0x02 +#define TXTEST10_MODE 0x03 +#define PRAND_MODE 0x04 +#define ACLLOOP_MODE 0x05 +#define SCOLOOP_MODE 0x06 +#define ACLNOWHIT_MODE 0x07 +#define SCONOWHIT_MODE 0x08 +#define TXTEST1100_MODE 0x09 +#define EXITTEST_MODE 0xFF + +#define HOPSINGLE 0x00 +#define HOPUSA 0x01 + +#define FIXTXPOW 0x00 +#define ADAPTTXPOW 0x01 + +/// Packet type parameter bit field of LMP_test_control +#define LMP_TEST_CTRL_PKT_TYPE_CODE_POS 0 +#define LMP_TEST_CTRL_PKT_TYPE_CODE_MSK 0x0F +#define LMP_TEST_CTRL_PKT_TYPE_LINK_POS 4 +#define LMP_TEST_CTRL_PKT_TYPE_LINK_MSK 0xF0 +#define TEST_ACLSCO 0 +#define TEST_ESCO 1 +#define TEST_EDRACL 2 +#define TEST_EDRESCO 3 + +/// LMP_encapsulated_header parameters LMP:5.3 +#define LMP_ENCAPS_P192_MAJ_TYPE 1 +#define LMP_ENCAPS_P192_MIN_TYPE 1 +#define LMP_ENCAPS_P192_PAYL_LEN 48 +#define LMP_ENCAPS_P192_PAYL_NB 3 +#define LMP_ENCAPS_P256_MAJ_TYPE 1 +#define LMP_ENCAPS_P256_MIN_TYPE 2 +#define LMP_ENCAPS_P256_PAYL_LEN 64 +#define LMP_ENCAPS_P256_PAYL_NB 4 + +/// Number of bits in the passkey code used during Secure Simple Pairing +#define SSP_PASSKEY_NB_BITS 20 + +// Event Filter HCI 4.7.3 + +/// Filter type +#define CLEAR_ALL_FILTER_TYPE 0x00 +#define INQUIRY_FILTER_TYPE 0x01 +#define CONNECTION_FILTER_TYPE 0x02 + +/// Filter size +#define CLEAR_ALL_FILTER_SIZE 0 + +/// Inquiry & Connection Setup Filter Condition Type +#define ALL_FILTER_CONDITION_TYPE 0x00 +#define CLASS_FILTER_CONDITION_TYPE 0x01 +#define BD_ADDR_FILTER_CONDITION_TYPE 0x02 + +/// Auto Accept Flag +#define DO_NOT_AUTO_ACCEPT_CONNECTION 0x01 +#define ACCEPT_CONNECTION_SLAVE 0x02 +#define ACCEPT_CONNECTION_MASTER 0x03 + +/// Event Mask HCI 4.7.1 +#define NO_EVENTS_SPECIFIED_FILTER 0x00000000 +#define INQUIRY_COMPLETE_EVENT_FILTER 0x00000001 +#define INQUIRY_RESULT_EVENT_FILTER 0x00000002 +#define CONNECTION_COMPLETE_EVENT_FILTER 0x00000004 +#define CONNECTION_REQUEST_EVENT_FILTER 0x00000008 +#define DISCONNECTION_COMPLETE_EVENT_FILTER 0x00000010 +#define AUTHENTICATION_COMPLETE_EVENT_FILTER 0x00000020 +#define REMOTE_NAME_REQUEST_COMPLETE_EVENT_FILTER 0x00000040 +#define ENCRYPTION_CHANGE_EVENT_FILTER 0x00000080 +#define CHANGE_CONNECTION_LINK_KEY_COMPLETE_EVENT_FILTER 0x00000100 +#define MASTER_LINK_KEY_COMPLETE_EVENT_FILTER 0x00000200 +#define READ_REMOTE_SUPPORTED_FEATURES_COMPLETE_EVENT_FILTER 0x00000400 +#define READ_REMOTE_VERSION_INFORMATION_COMPLETE_EVENT_FILTER 0x00000800 +#define QOS_SETUP_COMPLETE_EVENT_FILTER 0x00001000 +#define COMMAND_COMPLETE_EVENT_FILTER 0x00002000 // Unchecked */ +#define COMMAND_STATUS_EVENT_FILTER 0x00004000 // Unchecked */ +#define HARDWARE_ERROR_EVENT_FILTER 0x00008000 +#define FLUSH_OCCURRED_EVENT_FILTER 0x00010000 +#define ROLE_CHANGE_EVENT_FILTER 0x00020000 +#define NUMBER_OF_COMPLETED_PACKETS_EVENT_FILTER 0x00040000 // Unchecked */ +#define MODE_CHANGE_EVENT_FILTER 0x00080000 +#define RETURN_LINK_KEYS_EVENT_FILTER 0x00100000 +#define PIN_CODE_REQUEST_EVENT_FILTER 0x00200000 +#define LINK_KEY_REQUEST_EVENT_FILTER 0x00400000 +#define LINK_KEY_NOTIFICATION_EVENT_FILTER 0x00800000 +#define LOOPBACK_COMMAND_EVENT_FILTER 0x01000000 // Not implemented */ +#define DATA_BUFFER_OVERFLOW_EVENT_FILTER 0x02000000 +#define MAX_SLOTS_CHANGE_EVENT_FILTER 0x04000000 +#define READ_CLOCK_OFFSET_COMPLETE_EVENT_FILTER 0x08000000 +#define CONNECTION_PACKET_TYPE_CHANGED_EVENT_FILTER 0x10000000 +#define QOS_VIOLATION_EVENT_FILTER 0x20000000 +#define PAGE_SCAN_MODE_CHANGE_EVENT_FILTER 0x40000000 // Deprecated */ +#define PAGE_SCAN_REPETITION_MODE_CHANGE_EVENT_FILTER 0x80000000 + +#define FLOW_SPECIFICATION_COMPLETE_EVENT_FILTER 0x00000001 +#define INQUIRY_RESULT_WITH_RSSI_EVENT_FILTER 0x00000002 +#define READ_REMOTE_EXTENDED_FEATURES_COMPLETE_EVENT_FILTER 0x00000004 +#define SYNCHRONOUS_CONNECTION_COMPLETE_EVENT_FILTER 0x00000800 +#define SYNCHRONOUS_CONNECTION_CHANGE_EVENT_FILTER 0x00001000 +#define SNIFF_SUBRATING_EVENT_FILTER 0x00002000 +#define EXTENDED_INQUIRY_RESULT_EVENT_FILTER 0x00004000 +#define ENCRYPTION_KEY_REFRESH_COMPLETE_EVENT_FILTER 0x00008000 +#define IO_CAPABILITY_REQUEST_EVENT_FILTER 0x00010000 +#define IO_CAPABILITY_REQUEST_REPLY_EVENT_FILTER 0x00020000 +#define USER_CONFIRMATION_REQUEST_EVENT_FILTER 0x00040000 +#define USER_PASSKEY_REQUEST_EVENT_FILTER 0x00080000 +#define REMOTE_OOB_DATA_REQUEST_EVENT_FILTER 0x00100000 +#define SIMPLE_PAIRING_COMPLETE_EVENT_FILTER 0x00200000 +#define LINK_SUPERVISION_TIMEOUT_CHANGE_EVENT_FILTER 0x00800000 +#define ENHANCED_FLUSH_COMPLETE_EVENT_FILTER 0x01000000 +#define USER_PASSKEY_NOTIFICATION_EVENT_FILTER 0x04000000 +#define KEYPRESS_NOTIFICATION_EVENT_FILTER 0x08000000 +#define REM_HOST_SUPPORTED_FEATURES_NOTIFICATION_EVENT_FILTER 0x10000000 + +/// HostControllerToHostFlowControl (ACL) HCI 7.3.40 +#define FLOW_CONTROL_OFF 0x00 +#define FLOW_CONTROL_ACL 0x01 +#define FLOW_CONTROL_SCO 0x02 +#define FLOW_CONTROL_ACL_SCO 0x03 + +/// SynchroinousFlowControlEnable (SCO) HCI 7.3.39 +#define SYNC_FLOW_CONTROL_OFF 0x00 +#define SYNC_FLOW_CONTROL_ON 0x01 + +/// Tx Power HCI:4.7.37 +#define CURRENT_TX_POWER 0x00 +#define MAX_TX_POWER 0x01 + +/// Flow_direction HCI:7.2.13 +#define FLOW_DIR_OUT 0x00 +#define FLOW_DIR_IN 0x01 + +/// Drift and Jitter default value LMP 5.2 +#define DRIFT_BLE_DFT 500 +#define DRIFT_BT_DFT 250 +#define JITTER_DFT 10 +#define DRIFT_BT_ACTIVE_MAX 20 // BB:2.2.5 + +/// Read Stored Link Key HCI:4.7.8 +#define LINK_KEY_BD_ADDR 0x00 +#define LINK_KEY_ALL 0x01 + +/// Read/Write Hold Mode Activity HCI:4.7.35 and 4.7.36 +#define HOLD_MODE_ACTIV_DEFAULT 0x00 +#define HOLD_MODE_ACTIV_SUSP_PAGE_SCAN 0x01 +#define HOLD_MODE_ACTIV_SUSP_INQUIRY_SCAN 0x02 +#define HOLD_MODE_ACTIV_SUSP_PERIODIC_INQ 0x04 +#define HOLD_MODE_ACTIV_NOT_MASK 0xF8 + +/// AFH Mode +#define AFH_DISABLED 0x00 +#define AFH_ENABLED 0x01 + +/// AFH Reporting Mode +#define AFH_REPORTING_DISABLED 0x00 +#define AFH_REPORTING_ENABLED 0x01 + +/// AFH channel assessment Mode +#define AFH_CH_ASS_DISABLED 0x00 +#define AFH_CH_ASS_ENABLED 0x01 + +/// AFH MIn/Max interval, in BT slots (1s - 30s) +#define AFH_REPORT_INTERVAL_MIN 0x0640 +#define AFH_REPORT_INTERVAL_MAX 0xBB80 + +/// Channel classification values for frequency pairs +#define AFH_CH_CLASS_UNKNOWN 0x0 +#define AFH_CH_CLASS_GOOD 0x1 +#define AFH_CH_CLASS_RESERVED 0x2 +#define AFH_CH_CLASS_BAD 0x3 + +/// Maximum number of frequencies used in adapted channel hopping sequence +#define AFH_NB_CHANNEL_MIN 20 +#define AFH_NB_CHANNEL_MAX 79 + +/// Maximum number of frequencies used in synchronization train BB:2.6.4.8 +#define SYNC_TRAIN_CHANNEL_NB 3 +/// Indices of frequencies used in synchronization train +#define SYNC_TRAIN_CHANNEL_0 0 +#define SYNC_TRAIN_CHANNEL_1 24 +#define SYNC_TRAIN_CHANNEL_2 78 + +/// Maximum delay in synchronization train (in slots) BB:2.7.2 +#define SYNC_TRAIN_DELAY_MAX_DFT 16 +/// Maximum delay in synchronization train for Coarse clock adjustment (in slots) BB:2.7.2 +#define SYNC_TRAIN_DELAY_MAX_CLK_ADJ 4 +/// Synchronization train interval for Coarse clock adjustment (in slots) BB:2.7.2 +#define SYNC_TRAIN_INTV_CLK_ADJ 32 + +/// Future CSB instant value offset for Coarse clock adjustment (in slots) BB: 8.11.2 +#define SYNC_TRAIN_CSB_INSTANT_OFFSET_CLK_ADJ 1600 + +/// Minimum value for synchronization train interval (in slots) HCI:7.3.90 +#define SYNC_TRAIN_INTV_MIN 0x20 +/// Minimum value for synchronization train timeout (in slots) HCI:7.3.90 +#define SYNC_TRAIN_TO_MIN 0x00000002 +/// Maximum value for synchronization train timeout (in slots) HCI:7.3.90 +#define SYNC_TRAIN_TO_MAX 0x07FFFFFE + +/// Default value for synchronization train interval (in slots) HCI:6.36 +#define SYNC_TRAIN_INTV_DEFAULT 0x80 +/// Default value for synchronization train timeout (in slots) HCI:6.37 +#define SYNC_TRAIN_TO_DEFAULT 0x0002EE00 +/// Default value for synchronization train service data HCI:6.39 +#define SYNC_TRAIN_SVC_DATA_DEFAULT 0x00 + +/// Minimum value for synchronization scan timeout (in slots) HCI:7.1.52 +#define SYNC_SCAN_TO_MIN 0x22 +/// Minimum value for synchronization scan window (in slots) HCI:7.1.52 +#define SYNC_SCAN_WIN_MIN 0x22 +/// Minimum value for synchronization scan interval (in slots) HCI:7.1.52 +#define SYNC_SCAN_INTV_MIN 0x02 + +/// Default value for synchronization scan timeout (in slots) BB: Apppendix B +#define SYNC_SCAN_TO_DEFAULT 0x2000 +/// Recommended value for synchronization scan window (91.25ms) GAP: Appendix A +#define SYNC_SCAN_WIN_DEFAULT 0x0092 +/// Recommended value for synchronization scan interval (320 ms) GAP: Appendix A +#define SYNC_SCAN_INTV_DEFAULT 0x0200 + +/// CSB receive enable HCI:7.1.50 +#define CSB_RX_MODE_DIS 0x00 +#define CSB_RX_MODE_EN 0x01 + +/// CSB fragment HCI:7.2.88 +#define CSB_CONTINUATION_FRAGMENT 0 +#define CSB_STARTING_FRAGMENT 1 +#define CSB_ENDING_FRAGMENT 2 +#define CSB_NO_FRAGMENTATION 3 + +/// CSB max fragment size HCI:7.2.88 +#define CSB_FRAGMENT_SIZE_MAX 0xFF + +/// MWS Channel_Enable +#define MWS_CHANNEL_DISABLED 0x00 +#define MWS_CHANNEL_ENABLED 0x01 + +/// MWS Channel_Type +#define MWS_TDD_CHANNEL_TYPE 0x00 +#define MWS_FDD_CHANNEL_TYPE 0x01 + +/// MWS Transport_Layer +#define MWS_SIGNALING_ONLY 0x00 +#define MWS_WCI_1 0x01 +#define MWS_WCI_2 0x02 +#define MWS_TRANSPORT_TYPE_MAX 0x02 + +/// MWS PATTERN Index +#define MWS_PATTERN_INDEX_MAX 2 + +/// MWS PATTERN IntervalType +#define MWS_PATTERN_NO_TXRX 0 +#define MWS_PATTERN_TX_ALLOWED 1 +#define MWS_PATTERN_RX_ALLOWED 2 +#define MWS_PATTERN_TXRX_ALLOWED 3 +#define MWS_PATTERN_EXT_FRAME 4 +#define MWS_PATTERN_TYPE_MAX 4 + + +/// MWS Ext_Num_Periods +#define MWS_EXT_NUM_PERIODS_MIN 0x01 +#define MWS_EXT_NUM_PERIODS_MAX 0x32 + +/// MWS Period_Type +#define MWS_PERIOD_TYPE_DOWNLINK 0x00 +#define MWS_PERIOD_TYPE_UPLINK 0x01 +#define MWS_PERIOD_TYPE_BIDIRECTIONAL 0x02 +#define MWS_PERIOD_TYPE_GUARD_PERIOD 0x03 +#define MWS_PERIOD_TYPE_RESERVED 0x04 + +/// Simple pairing mode HCI:7.3.58/HCI:7.3.59 +#define SP_MODE_DIS 0x00 +#define SP_MODE_EN 0x01 + +/// Inquiry Scan Type and Page Scan Type HCI:6.4/HCI:6.11 +#define STANDARD_SCAN 0x00 +#define INTERLACED_SCAN 0x01 + +/// Default interlace offset used for frequency selection during interlaced inquiry/page scan BB:8.3.1/8.4.1 +#define INTERLACE_OFFSET_DFT 16 + +/// Inquiry Mode +#define STANDARD_INQUIRY 0x00 +#define RSSI_INQUIRY 0x01 +#define EXTENDED_INQUIRY 0x02 + +/// Maximum number of link keys Host can write via HCI Write Stored Link Key Command +#define NB_LINK_KEY 0x0B + +/// LMP Version +#define BT_LMP_V1_0 0 +#define BT_LMP_V1_1 1 +#define BT_LMP_V1_2 2 +#define BT_LMP_V2_0 3 +#define BT_LMP_V2_1 4 +#define BT_LMP_V3_0 5 +#define BT_LMP_V4_0 6 +#define BT_LMP_V4_1 7 + +/// WhichClock parameter +#define LOCAL_CLOCK 0 +#define PICONET_CLOCK 1 + +/// Clock Accuracy parameter +#define CLOCK_ACCURACY_UNKNOWN 0xFFFF + +#define SP_PASSKEY_STARTED 0x00 +#define SP_PASSKEY_DIGIT_ENTERED 0x01 +#define SP_PASSKEY_DIGIT_ERASED 0x02 +#define SP_PASSKEY_CLEARED 0x03 +#define SP_PASSKEY_COMPLETED 0x04 + +/// Low Power Mode +#define PARK_BEACON_MIN 0x000E + +/// RWBT Device can be slave of 2 master at max +#define MAX_SLAVES_FOR_DIFFERENT_MASTERS 2 +// Flags for ld_util_get_nb_acl function +/// Flag for master link +#define MASTER_FLAG 0x01 +/// Flag for slave link +#define SLAVE_FLAG 0x02 + + +/// BLE packet info in bytes +#define BLE_PKT_HDR_LEN (2) +#define BLE_PKT_CRC_LEN (3) +#define BLE_PKT_ACCESS_LEN (4) + +/// IFS duration in us +#define BLE_IFS_DUR (150) + + +/// BLE event mask +enum le_evt_mask +{ + LE_EVT_MASK_CON_CMP_EVT_BIT = 0, //!< LE_EVT_MASK_CON_CMP_EVT_BIT + LE_EVT_MASK_CON_CMP_EVT_MSK = 0x0001,//!< LE_EVT_MASK_CON_CMP_EVT_MSK + LE_EVT_MASK_ADV_REP_EVT_BIT = 1, //!< LE_EVT_MASK_ADV_REP_EVT_BIT + LE_EVT_MASK_ADV_REP_EVT_MSK = 0x0002,//!< LE_EVT_MASK_ADV_REP_EVT_MSK + LE_EVT_MASK_CON_UPD_EVT_BIT = 2, //!< LE_EVT_MASK_CON_UPD_EVT_BIT + LE_EVT_MASK_CON_UPD_EVT_MSK = 0x0004,//!< LE_EVT_MASK_CON_UPD_EVT_MSK + LE_EVT_MASK_CON_RD_REM_FEAT_EVT_BIT = 3, //!< LE_EVT_MASK_CON_RD_REM_FEAT_EVT_BIT + LE_EVT_MASK_CON_RD_REM_FEAT_EVT_MSK = 0x0008,//!< LE_EVT_MASK_CON_RD_REM_FEAT_EVT_MSK + LE_EVT_MASK_LG_TR_KEY_REQ_EVT_BIT = 4, //!< LE_EVT_MASK_LG_TR_KEY_REQ_EVT_BIT + LE_EVT_MASK_LG_TR_KEY_REQ_EVT_MSK = 0x0010,//!< LE_EVT_MASK_LG_TR_KEY_REQ_EVT_MSK + LE_EVT_MASK_REM_CON_PARA_REQ_EVT_BIT = 5, //!< LE_EVT_MASK_REM_CON_PARA_REQ_EVT_BIT + LE_EVT_MASK_REM_CON_PARA_REQ_EVT_MSK = 0x0020,//!< LE_EVT_MASK_REM_CON_PARA_REQ_EVT_MSK + LE_EVT_MASK_DATA_LEN_CHG_EVT_BIT = 6, //!< LE_EVT_MASK_DATA_LEN_CHG_EVT_BIT + LE_EVT_MASK_DATA_LEN_CHG_EVT_MSK = 0x0040,//!< LE_EVT_MASK_DATA_LEN_CHG_EVT_MSK + LE_EVT_MASK_RD_LOC_P256_PUB_KEY_CMP_EVT_BIT = 7, //!< LE_EVT_MASK_RD_LOC_P256_PUB_KEY_CMP_EVT_BIT + LE_EVT_MASK_RD_LOC_P256_PUB_KEY_CMP_EVT_MSK = 0x0080,//!< LE_EVT_MASK_RD_LOC_P256_PUB_KEY_CMP_EVT_MSK + LE_EVT_MASK_GEN_DHKEY_CMP_EVT_BIT = 8, //!< LE_EVT_MASK_GEN_DHKEY_CMP_EVT_BIT + LE_EVT_MASK_GEN_DHKEY_CMP_EVT_MSK = 0x0100,//!< LE_EVT_MASK_GEN_DHKEY_CMP_EVT_MSK + LE_EVT_MASK_ENH_CON_CMP_EVT_BIT = 9, //!< LE_EVT_MASK_ENH_CON_CMP_EVT_BIT + LE_EVT_MASK_ENH_CON_CMP_EVT_MSK = 0x0200,//!< LE_EVT_MASK_ENH_CON_CMP_EVT_MSK + LE_EVT_MASK_DIR_ADV_REP_EVT_BIT = 10, //!< LE_EVT_MASK_DIR_ADV_REP_EVT_BIT + LE_EVT_MASK_DIR_ADV_REP_EVT_MSK = 0x0400,//!< LE_EVT_MASK_DIR_ADV_REP_EVT_MSK + LE_EVT_MASK_PHY_UPD_CMP_EVT_BIT = 11, //!< LE_EVT_MASK_PHY_UPD_CMP_EVT_BIT + LE_EVT_MASK_PHY_UPD_CMP_EVT_MSK = 0x0800,//!< LE_EVT_MASK_PHY_UPD_CMP_EVT_MSK + + LE_EVT_MASK_DFT = 0x001F,//!< LE_EVT_MASK_DFT +}; + +/// Enhanced Synchronous Connection HCI:7.1.41 & 7.1.42 +#define CODING_FORMAT_ULAW 0x00 +#define CODING_FORMAT_ALAW 0x01 +#define CODING_FORMAT_CVSD 0x02 +#define CODING_FORMAT_TRANSP 0x03 +#define CODING_FORMAT_LINPCM 0x04 +#define CODING_FORMAT_MSBC 0x05 +#define CODING_FORMAT_VENDSPEC 0xFF + +#define PCM_FORMAT_NA 0x00 +#define PCM_FORMAT_1SCOMP 0x01 +#define PCM_FORMAT_2SCOMP 0x02 +#define PCM_FORMAT_SIGNMAG 0x03 +#define PCM_FORMAT_UNSIGNED 0x04 + +#define PCM_SAMPLE_SIZE_8BITS 8 +#define PCM_SAMPLE_SIZE_16BITS 16 + +#define AUDIO_DATA_PATH_HCI 0 +#define AUDIO_DATA_PATH_PCM 1 + +/// Default maximum number of slots per packet +#define MAX_SLOT_DFT 1 + +/// Packet type code interpretation possibilities BB:6.5 +#define ID_NUL_TYPE 0x0 +#define POLL_TYPE 0x1 +#define FHS_TYPE 0x2 +#define DM1_TYPE 0x3 +#define DH1_TYPE 0x4 +#define DH1_2_TYPE 0x4 +#define DH1_3_TYPE 0x8 +#define HV1_TYPE 0x5 +#define HV2_TYPE 0x6 +#define EV3_2_TYPE 0x6 +#define HV3_TYPE 0x7 +#define EV3_TYPE 0x7 +#define EV3_3_TYPE 0x7 +#define DV_TYPE 0x8 +#define AUX1_TYPE 0x9 +#define DM3_TYPE 0xA +#define DH3_TYPE 0xB +#define DH3_2_TYPE 0xA +#define DH3_3_TYPE 0xB +#define EV4_TYPE 0xC +#define EV5_2_TYPE 0xC +#define EV5_TYPE 0xD +#define EV5_3_TYPE 0xD +#define DM5_TYPE 0xE +#define DH5_TYPE 0xF +#define DH5_2_TYPE 0xE +#define DH5_3_TYPE 0xF + +/// Format of the FHS payload BB:6.5.1.4 +#define FHS_PAR_BITS_POS 0 +#define FHS_PAR_BITS_LEN 34 +#define FHS_PAR_BITS_END (FHS_PAR_BITS_POS + FHS_PAR_BITS_LEN) +#define FHS_LAP_POS FHS_PAR_BITS_END +#define FHS_LAP_LEN 24 +#define FHS_LAP_END (FHS_LAP_POS + FHS_LAP_LEN) +#define FHS_EIR_POS FHS_LAP_END +#define FHS_EIR_LEN 1 +#define FHS_EIR_END (FHS_EIR_POS + FHS_EIR_LEN) +#define FHS_UNDEF_POS FHS_EIR_END +#define FHS_UNDEF_LEN 1 +#define FHS_UNDEF_END (FHS_UNDEF_POS + FHS_UNDEF_LEN) +#define FHS_SR_POS FHS_UNDEF_END +#define FHS_SR_LEN 2 +#define FHS_SR_END (FHS_SR_POS + FHS_SR_LEN) +#define FHS_RSVD_POS FHS_SR_END +#define FHS_RSVD_LEN 2 +#define FHS_RSVD_END (FHS_RSVD_POS + FHS_RSVD_LEN) +#define FHS_UAP_POS FHS_RSVD_END +#define FHS_UAP_LEN 8 +#define FHS_UAP_END (FHS_UAP_POS + FHS_UAP_LEN) +#define FHS_NAP_POS FHS_UAP_END +#define FHS_NAP_LEN 16 +#define FHS_NAP_END (FHS_NAP_POS + FHS_NAP_LEN) +#define FHS_CLASS_OF_DEV_POS FHS_NAP_END +#define FHS_CLASS_OF_DEV_LEN 24 +#define FHS_CLASS_OF_DEV_END (FHS_CLASS_OF_DEV_POS + FHS_CLASS_OF_DEV_LEN) +#define FHS_LT_ADDR_POS FHS_CLASS_OF_DEV_END +#define FHS_LT_ADDR_LEN 3 +#define FHS_LT_ADDR_END (FHS_LT_ADDR_POS + FHS_LT_ADDR_LEN) +#define FHS_CLK_POS FHS_LT_ADDR_END +#define FHS_CLK_LEN 26 +#define FHS_CLK_END (FHS_CLK_POS + FHS_CLK_LEN) +#define FHS_PAGE_SCAN_MODE_POS FHS_CLK_END +#define FHS_PAGE_SCAN_MODE_LEN 3 +#define FHS_PAGE_SCAN_MODE_END (FHS_PAGE_SCAN_MODE_POS + FHS_PAGE_SCAN_MODE_LEN) + +/// Format of the STP payload BB:8.11.2 +#define STP_CLK_POS 0 +#define STP_CLK_LEN 4 +#define STP_FUT_CSB_INST_POS 4 +#define STP_FUT_CSB_INST_LEN 4 +#define STP_AFH_CH_MAP_POS 8 +#define STP_AFH_CH_MAP_LEN 10 +#define STP_MST_BD_ADDR_POS 18 +#define STP_MST_BD_ADDR_LEN 6 +#define STP_CSB_INTV_POS 24 +#define STP_CSB_INTV_LEN 2 +#define STP_CSB_LT_ADDR_POS 26 +#define STP_CSB_LT_ADDR_LEN 1 +#define STP_SVC_DATA_POS 27 +#define STP_SVC_DATA_LEN 1 +#define STP_PACKET_SIZE 28 + +/// CSB Receive status HCI:7.7.69 +#define CSB_RX_OK 0x00 +#define CSB_RX_KO 0x01 + + +/// HCI 7.8.18 LE Connection Update Command +/// Connection interval min (N*1.250ms) +#define LE_CNX_INTERVAL_MIN 6 //(0x06) +/// Connection interval Max (N*1.250ms) +#define LE_CNX_INTERVAL_MAX 3200 //(0xC80) +/// Connection latency min (N*cnx evt) +#define LE_CNX_LATENCY_MIN 0 //(0x00) +/// Connection latency Max (N*cnx evt +#define LE_CNX_LATENCY_MAX 500 //(0x1F4) +/// Supervision TO min (N*10ms) +#define LE_CNX_SUP_TO_MIN 10 //(0x0A) +/// Supervision TO Max (N*10ms) +#define LE_CNX_SUP_TO_MAX 3200 //(0xC80) +/// Connection event length min (N*0.625ms) +#define LE_CNX_CE_LGTH_MIN 0 //(0x00) +/// Connection event length Max (N*0.625ms) +#define LE_CNX_CE_LGTH_MAX 65535 //(0xFFFF)' + + +/// HCI 7.8.33 LE Set Data Length Command +/// Preferred minimum number of payload octets +#define LE_MIN_OCTETS (27) +/// Preferred minimum number of microseconds +#define LE_MIN_TIME (328) +/// Preferred maximum number of payload octets +#define LE_MAX_OCTETS (251) +/// Preferred maximum number of microseconds +#define LE_MAX_TIME (2120) + +/// LE LL 2.1.2 Access Address +#define LE_ADV_CH_ACC_ADDR_H 0x8E89 +#define LE_ADV_CH_ACC_ADDR_L 0xBED6 + +/// Resolvable private address timeout (in seconds) HCI:7.8.45 +#define RPA_TO_MAX 0xA1B8 // approximately 11.5 hours +#define RPA_TO_DFT 0x0384 // 900 seconds or 15 minutes +#define RPA_TO_MIN 0x0001 // 1 second + +/// Scan/Init PHYs (bit fields, as defined in HCI:7.8.64, HCI:7.8.66). +#define LE_1M_PHY_BIT_POS 0 +#define LE_1M_PHY_BIT_MSK 0x01 +#define LE_CODED_PHY_BIT_POS 2 +#define LE_CODED_PHY_BIT_MSK 0x04 + +/// Max scanning PHYs which can be set HCI:7.8.64 +#define MAX_SCAN_PHYS 2 + +/// Max initiatng PHYs which can be set HCI:7.8.66 +#define MAX_INIT_PHYS 2 + +/// Ext Scanning interval (in 625us slot) (chapter 2.E.7.8.64) +#define EXT_SCAN_INTERVAL_MIN 0x0004 //(2.5 ms) +#define EXT_SCAN_INTERVAL_MAX 0xFFFF //(40.96 sec) + +/// Ext Scanning window (in 625us slot) (chapter 2.E.7.8.64) +#define EXT_SCAN_WINDOW_MIN 0x0004 //(2.5 ms) +#define EXT_SCAN_WINDOW_MAX 0xFFFF //(40.96 sec) + +/// Advertiser PHY definitions for Ext Adv report Evts HCI:7.7.65.13 +#define HCI_ADV_PHY_1M 1 +#define HCI_ADV_PHY_2M 2 +#define HCI_ADV_PHY_CODED 3 + +/// Duration of 1MBPS PDU of specified payload length in microseconds (chapter 6.B.2.1) +#define PDU_1MBPS_LEN_US(n_bytes) ((8 + (2 + n_bytes))*8) // (1 + 4 + (2 + payload_len) + 3)*8 + +/// Duration of 2MBPS PDU of specified payload length in microseconds (chapter 6.B.2.1) +#define PDU_2MBPS_LEN_US(n_bytes) ((9 + (2 + n_bytes))*4) // (2 + 4 + (2 + payload_len) + 3)*4 + +/// Duration of 500KBPS PDU of specified payload length in microseconds (chapter 6.B.2.2) +#define PDU_500KBPS_LEN_US(n_bytes) (430 + (2 + n_bytes)*16) // 80 + 256 + 16 + 24 + (2 + payload_len)*8*2 + 24*2 + 3*2 + +/// Duration of 125KBPS PDU of specified payload length in microseconds (chapter 6.B.2.2) +#define PDU_125KBPS_LEN_US(n_bytes) (592 + (2 + n_bytes)*64) // 80 + 256 + 16 + 24 + (2 + payload_len)*8*8 + 24*8 + 3*8 + +/// Maximum length of BLE advertising channel PDU payloads ((chapter 6.B.2.3)) +#define PDU_ADV_PAYLOAD_LEN_MAX 255 + +/// Ext Adv Report - ADV SID - Define for no ADI filed in the PDU HCI:7.7.65.13 +#define REP_ADV_NO_ADI 0xFF + +/// Ext Adv Report - Tx Power & RSSI dBm - Define for information not available HCI:7.7.65.13 +#define REP_ADV_DBM_UNKNOWN 127 + +/// Periodic Advertising Report - Unused parameter - mandatory value HCI:7.7.65.15 +#define PER_ADV_REPORT_TRAIL_BYTE 0xFF + +/// Maximum advertising handle HCI:7.8.53 +#define ADV_HDL_MAX 0xEF + +/// Advertising_Tx_Power, Host has no preference HCI:7.8.53 +#define ADV_TX_PWR_NO_PREF 127 + + +/* + * ENUMERATIONS + **************************************************************************************** + */ +/// BLE 2MBPS HCI:7.8.x +enum le_phys_preference +{ + /// The Host has no preference among the transmitter PHYs supported by the Controller + ALL_PHYS_TX_NO_PREF = (1 << 0), + /// The Host has no preference among the receiver PHYs supported by the Controller + ALL_PHYS_RX_NO_PREF = (1 << 1), +}; + +enum le_phy_value +{ + /// The Host prefers to use the LE 1M transmitter/receiver PHY (possibly among others) + PHY_1MBPS = (1<<0), + /// The Host prefers to use the LE 2M transmitter/receiver PHY (possibly among others) + PHY_2MBPS = (1<<1), + /// The Host prefers to use the LE Coded transmitter/receiver PHY (possibly among others) + PHY_LE_CODED = (1<<2), + /// The Host prefers to use the LE Coded transmitter/receiver PHY (possibly among others) + PHY_ALL = (PHY_1MBPS | PHY_2MBPS | PHY_LE_CODED), +}; + +enum le_phy_opt +{ + /// The Host has no preferred coding when transmitting on the LE Coded PHY + PHY_OPT_NO_LE_CODED_TX_PREF, + /// The Host prefers that S=2 coding be used when transmitting on the LE Coded PHY + PHY_OPT_S2_LE_CODED_TX_PREF, + /// The Host prefers that S=8 coding be used when transmitting on the LE Coded PHY + PHY_OPT_S8_LE_CODED_TX_PREF, +}; + + +enum le_phy_mode +{ + PHYS_MOD_STANDARD , + PHYS_MOD_STABLE , + PHYS_MOD_MAX, +}; + +///Transmit Power level types +enum +{ + ///Current Power Level + TX_PW_LVL_CURRENT = 0x00, + ///Maximum power level + TX_PW_LVL_MAX, +}; + +///Controller to Host flow control +enum +{ + /// C-> H flow control off + FLOW_CTRL_OFF = 0x00, + ///C->H ACL flow control on only + FLOW_CTRL_ON_ACL_OFF_SYNC, + ///C->H Sync flow control on only + FLOW_CTRL_OFF_ACL_ON_SYNC, + ///C->H ACL and Sync flow control on + FLOW_CTRL_ON_ACL_ON_SYNC, +}; + +///LE Supported Host enable +enum +{ + ///Disable LE supported Host + LE_SUPP_HOST_DIS = 0x00, + ///Enable LE Supported Host + LE_SUPP_HOST_EN, +}; + +///Simultaneous LE Host enable +enum +{ + ///Disable LE simultaneous Host disable + SIMULT_LE_HOST_DIS = 0x00, + ///Enable LE simultaneous Host disable + SIMULT_LE_HOST_EN, +}; + +///Advertising HCI Type +enum +{ + ///Connectable Undirected advertising + ADV_CONN_UNDIR = 0x00, + ///Connectable high duty cycle directed advertising + ADV_CONN_DIR, + ///Discoverable undirected advertising + ADV_DISC_UNDIR, + ///Non-connectable undirected advertising + ADV_NONCONN_UNDIR, + ///Connectable low duty cycle directed advertising + ADV_CONN_DIR_LDC, +}; + +///Advertising event properties values for legacy PDUs +enum +{ + ///Connectable and scannable undirected + ADV_IND = 0x13, + ///Connectable directed (low duty cycle) + ADV_DIRECT_LO_IND = 0x15, + ///Connectable directed (high duty cycle) + ADV_DIRECT_HI_IND = 0x1D, + ///Connectable directed (received) + ADV_DIRECT_IND = 0x15, + ///Scannable undirected + ADV_SCAN_IND = 0x12, + ///Non-connectable and non-scannable undirected + ADV_NONCONN_IND = 0x10, + ///Scan response to an ADV_IND + SCAN_RSP_TO_ADV_IND = 0x1B, + ///Scan response to an ADV_SCAN_IND + SCAN_RSP_TO_ADV_SCAN_IND = 0x1A, +}; + +///Advertising event properties masks +enum +{ + ///Connectable advertising + ADV_CON = 0x01, + ///Scannable advertising + ADV_SCAN = 0x02, + ///Directed advertising + ADV_DIRECT = 0x04, + ///High duty cycle directed connectable advertising + ADV_DIRECT_HI = 0x08, + ///Use legacy advertising PDUs + ADV_LEGACY = 0x10, + ///Omit advertiser's address from all PDUs ("anonymous advertising") + ADV_ANONYMOUS = 0x20, + ///Include TxPower in the extended header of the advertising PDU + ADV_TX_PWR = 0x40, +}; + +///Scanning HCI Type +enum +{ + ///Scan request + SCAN_REQ, + ///Scan response + SCAN_RSP, +}; + +///BD address type +enum +{ + ///Public BD address + ADDR_PUBLIC = 0x00, + ///Random BD Address + ADDR_RAND, + /// Controller generates Resolvable Private Address based on the + /// local IRK from resolving list. If resolving list contains no matching + /// entry, use public address. + ADDR_RPA_OR_PUBLIC, + /// Controller generates Resolvable Private Address based on the + /// local IRK from resolving list. If resolving list contains no matching + /// entry, use random address. + ADDR_RPA_OR_RAND, + /// mask used to determine Address type in the air + ADDR_MASK = 0x01, + /// mask used to determine if an address is an RPA + ADDR_RPA_MASK = 0x02, + /// Random device address (controller unable to resolve) + ADDR_RAND_UNRESOLVED = 0xFE, + /// No address provided (anonymous advertisement) + ADDR_NONE = 0xFF, +}; + +///Privacy mode type +enum +{ + ///Network privacy mode + PRIV_TYPE_NETWORK = 0x00, + ///Device privacy mode + PRIV_TYPE_DEVICE = 0x01, +}; + +/// Random Address type (2 MSB of the LE BD Address) +enum rnd_addr_type +{ + /// Static random address - 11 (MSB->LSB) + RND_STATIC_ADDR = 0xC0, + /// Private non resolvable address - 00 (MSB->LSB) + RND_NON_RSLV_ADDR = 0x00, + /// Private resolvable address - 01 (MSB->LSB) + RND_RSLV_ADDR = 0x40, +}; + +///Advertising channels enables +enum adv_channel_map +{ + ///Byte value for advertising channel map for channel 37 enable + ADV_CHNL_37_EN = 0x01, + ///Byte value for advertising channel map for channel 38 enable + ADV_CHNL_38_EN = 0x02, + ///Byte value for advertising channel map for channel 39 enable + ADV_CHNL_39_EN = 0x04, + ///Byte value for advertising channel map for channel 37, 38 and 39 enable + ADV_ALL_CHNLS_EN = 0x07, +}; + +///Advertising filter policy +enum adv_filter_policy +{ + ///Allow both scan and connection requests from anyone + ADV_ALLOW_SCAN_ANY_CON_ANY = 0x00, + ///Allow both scan req from White List devices only and connection req from anyone + ADV_ALLOW_SCAN_WLST_CON_ANY, + ///Allow both scan req from anyone and connection req from White List devices only + ADV_ALLOW_SCAN_ANY_CON_WLST, + ///Allow scan and connection requests from White List devices only + ADV_ALLOW_SCAN_WLST_CON_WLST, +}; + +///Advertising enables +enum +{ + ///Disable advertising + ADV_DIS = 0x00, + ///Enable advertising + ADV_EN, +}; + +///LE Scan type +enum +{ + ///Passive scan + SCAN_PASSIVE = 0x00, + ///Active scan + SCAN_ACTIVE, +}; + +///Scan filter policy +enum scan_filter_policy +{ + ///Allow advertising packets from anyone + SCAN_ALLOW_ADV_ALL = 0x00, + ///Allow advertising packets from White List devices only + SCAN_ALLOW_ADV_WLST, + ///Allow advertising packets from anyone and Direct adv using RPA in InitA + SCAN_ALLOW_ADV_ALL_AND_INIT_RPA, + ///Allow advertising packets from White List devices only and Direct adv using RPA in InitA + SCAN_ALLOW_ADV_WLST_AND_INIT_RPA, +}; + +///Le Scan enables +enum +{ + ///Disable scan + SCAN_DIS = 0x00, + ///Enable scan + SCAN_EN, +}; + +///Filter duplicates +enum scan_dup_filter_policy +{ + ///Disable filtering of duplicate packets + SCAN_FILT_DUPLIC_DIS = 0x00, + ///Enable filtering of duplicate packets + SCAN_FILT_DUPLIC_EN, + ///Enable filtering of duplicate packets per scan period + SCAN_FILT_DUPLIC_EN_PER_PERIOD, +}; + +///Initiator Filter policy +enum +{ + ///Initiator will ignore White List + INIT_FILT_IGNORE_WLST = 0x00, + ///Initiator will use White List + INIT_FILT_USE_WLST, +}; + +///Transmitter test Packet Payload Type +enum +{ + ///Pseudo-random 9 TX test payload type + PAYL_PSEUDO_RAND_9 = 0x00, + ///11110000 TX test payload type + PAYL_11110000, + ///10101010 TX test payload type + PAYL_10101010, + ///Pseudo-random 15 TX test payload type + PAYL_PSEUDO_RAND_15, + ///All 1s TX test payload type + PAYL_ALL_1, + ///All 0s TX test payload type + PAYL_ALL_0, + ///00001111 TX test payload type + PAYL_00001111, + ///01010101 TX test payload type + PAYL_01010101, +}; + +/// Constant defining the role +enum +{ + ///Master role + ROLE_MASTER, + ///Slave role + ROLE_SLAVE, +}; + +/// Constant clock accuracy +enum +{ + ///Clock accuracy at 500PPM + SCA_500PPM, + ///Clock accuracy at 250PPM + SCA_250PPM, + ///Clock accuracy at 150PPM + SCA_150PPM, + ///Clock accuracy at 100PPM + SCA_100PPM, + ///Clock accuracy at 75PPM + SCA_75PPM, + ///Clock accuracy at 50PPM + SCA_50PPM, + ///Clock accuracy at 30PPM + SCA_30PPM, + ///Clock accuracy at 20PPM + SCA_20PPM +}; + +///Advertising pdu Type +enum ble_adv_type +{ + /// Undirected advertising + BLE_ADV_IND = 0x00, + /// Directed advertising + BLE_ADV_DIRECT_IND = 0x01, + /// Non Connectable advertising + BLE_ADV_NONCONN_IND = 0x02, + /// Scan Request on primary channel + BLE_SCAN_REQ = 0x03, + /// Scan Response on secondary channel + BLE_AUX_SCAN_REQ = 0x03, + + /// Scan Response + BLE_SCAN_RSP = 0x04, + /// Connect Request on primary channel + BLE_CONNECT_IND = 0x05, + /// Connect Request on secondary channel + BLE_AUX_CONNECT_REQ = 0x05, + + /// Discoverable advertising + BLE_ADV_SCAN_IND = 0x06, + + /// Extended Advertising indication on primary channel + BLE_ADV_EXT_IND = 0x07, + + /// ADV data indication on secondary channel + BLE_AUX_ADV_IND = 0x07, + /// Scan response data on secondary channel + BLE_AUX_SCAN_RSP = 0x07, + /// Periodic Advertising packet on secondary channel + BLE_AUX_SYNC_IND = 0x07, + /// Continuation of advertising data on secondary channel + BLE_AUX_CHAIN_IND = 0x07, + /// Response of the AUX_CONNECT_REQ on secondary channel to confirm that connection is accepted + BLE_AUX_CONNECT_RSP = 0x08, + + /// Reserved + BLE_RESERVED_PDU_TYPES, +}; + + +/// LE Advertising Report Event Type HCI:7.7.65.2 +enum +{ + /// Connectable undirected advertising + ADV_IND_EVT = 0x00, + /// Connectable directed advertising + ADV_DIRECT_IND_EVT, + /// Scannable undirected advertising + ADV_SCAN_IND_EVT, + /// Non connectable undirected advertising + ADV_NONCONN_IND_EVT, + /// Scan Response + SCAN_RSP_EVT, + /// Reserved + RESERVED_ADV_EVT_TYPES, +}; + +/// LE Extended Advertising Report Event Type Bit Mask HCI:7.765.13 + +/// Connectable advertising event +#define CON_ADV_EVT_MSK 0x01 +/// Scannable advertising event +#define SCAN_ADV_EVT_MSK 0x02 +/// Directed advertising event +#define DIR_ADV_EVT_MSK 0x04 +/// Scan Response +#define SCAN_RSP_EVT_MSK 0x08 +/// Legacy advertising PDUs +#define LGCY_ADV_EVT_MSK 0x10 + +/// Connectable undirected advertising +#define LGCY_ADV_IND_EVT 0x13 //LGCY_ADV_EVT_MSK|SCAN_ADV_EVT_MSK|CON_ADV_EVT_MSK +/// Connectable directed advertising +#define LGCY_ADV_DIRECT_IND_EVT 0x15 //LGCY_ADV_EVT_MSK|DIR_ADV_EVT_MSK|CON_ADV_EVT_MSK +/// Scannable undirected advertising +#define LGCY_ADV_SCAN_IND_EVT 0x12 //LGCY_ADV_EVT_MSK|SCAN_ADV_EVT_MSK +/// Non connectable undirected advertising +#define LGCY_ADV_NONCONN_IND_EVT 0x10 //LGCY_ADV_EVT_MSK +/// Scan Response to ADV_IND +#define LGCY_SCAN_RSP_TO_ADV_IND_EVT 0x1B //LGCY_ADV_EVT_MSK|SCAN_RSP_EVT_MSK|SCAN_ADV_EVT_MSK|CON_ADV_EVT_MSK +/// Scan Response to ADV_SCAN_IND +#define LGCY_SCAN_RSP_TO_ADV_SCAN_IND_EVT 0x1A //LGCY_ADV_EVT_MSK|SCAN_RSP_EVT_MSK|SCAN_ADV_EVT_MSK + +/// Offset of data status field in event type value +#define ADV_EVT_DATA_STATUS_OFFSET 5 +/// Mask for data status field in event type value +#define ADV_EVT_DATA_STATUS_MASK 0x0003 +/// Data status of extended advertising event - Complete +#define ADV_EVT_DATA_STATUS_COMPLETE 0 +/// Data status of extended advertising event - Incomplete, more data to come +#define ADV_EVT_DATA_STATUS_INCOMPLETE 1 +/// Data status of extended advertising event - Incomplete, data truncated, no more to come +#define ADV_EVT_DATA_STATUS_TRUNCATED 2 +/// Data status of extended advertising event - Reserved for future use +#define ADV_EVT_DATA_STATUS_RESERVED 3 + +/// LLID packet +enum +{ + /// Reserved for future use + LLID_RFU, + /// Continue + LLID_CONTINUE, + /// Start + LLID_START, + /// Control + LLID_CNTL +}; + +/// Remote OOB Data present parameter value HCI:7.1.29 +enum +{ + REM_OOB_DATA_NO = 0x00, + REM_OOB_DATA_P192 = 0x01, + REM_OOB_DATA_P256 = 0x02, + REM_OOB_DATA_P192_P256 = 0x03, +}; + +/// Encryption enabled parameter in HCI_Enc_Chg_Evt HCI:7.7.8 +enum +{ + ENC_OFF = 0x00, + ENC_BRDER_E0_LE_AESCCM = 0x01, + ENC_BREDR_AESCC = 0x02, +}; + +/// Combined duration of Preamble and Access Address depending on the PHY used (in us) +#define BLE_PREAMBLE_ACCESS_ADDR_DUR_1MBPS (5*8) +#define BLE_PREAMBLE_ACCESS_ADDR_DUR_2MBPS (6*4) +#define BLE_PREAMBLE_ACCESS_ADDR_DUR_125KBPS (80+256) +#define BLE_PREAMBLE_ACCESS_ADDR_DUR_500KBPS (80+256) + +/// size of the LEN & MODE info preceeding the extended header +#define BLE_EXT_ADV_PRE_HEADER_LEN (1) +/// size of the FLAGS info at start of the extended header +#define BLE_EXT_ADV_HEADER_FLAGS_LEN (1) +/// size of the extended header in bytes (pre-header + flags) +#define BLE_EXT_ADV_HEADER_LEN (2) +/// Size of supplemental info in extended header +#define BLE_EXT_SUP_INFO_LEN (1) +/// Size of ADV Data Info in extended header +#define BLE_EXT_ADI_LEN (2) +/// Size of Aux Pointer info in extended header +#define BLE_EXT_AUX_PTR_LEN (3) +/// Size of Sync PTR info in extended header +#define BLE_EXT_SYNC_LEN (18) +/// Size of TX Power info in extended header +#define BLE_EXT_TX_PWR_LEN (1) + +/// Extended Header Flags +enum ble_ext_header_flags +{ + // AdvA + ADVA_BIT = 0x01, + ADVA_POS = 0, + // TargetA + TARGETA_BIT = 0x02, + TARGETA_POS = 1, + // SuppInfo + SUPPINFO_BIT = 0x04, + SUPPINFO_POS = 2, + // AdvDataInfo (ADI) + ADI_BIT = 0x08, + ADI_POS = 3, + // AuxPtr + AUXPTR_BIT = 0x10, + AUXPTR_POS = 4, + // SyncInfo + SYNCINFO_BIT = 0x20, + SYNCINFO_POS = 5, + // TxPower + TXPOWER_BIT = 0x40, + TXPOWER_POS = 6, +}; + +/// AUX pointer description +enum ble_aux_ptr +{ + // Aux LL Channel + BLE_AUX_LL_CHANNEL_MASK = 0x0000003F, + BLE_AUX_LL_CHANNEL_LSB = 0, + // Aux Clock Accuracy + BLE_AUX_CA_BIT = 0x00000040, + BLE_AUX_CA_POS = 6, + // Aux Offset Unit + BLE_AUX_OFFSET_UNIT_BIT = 0x00000080, + BLE_AUX_OFFSET_UNIT_POS = 7, + // Aux ADV offset + BLE_AUX_OFFSET_MASK = 0x001FFF00, + BLE_AUX_OFFSET_LSB = 8, + // Aux PHY + BLE_AUX_PHY_MASK = 0x00E00000, + BLE_AUX_PHY_LSB = 21, +}; + +/// AdvDataInfo (ADI) field description +enum ble_adi +{ + // Advertising Data ID (DID) + BLE_ADI_DID_MASK = 0x0FFF, + BLE_ADI_DID_LSB = 0, + // Advertising Set ID (SID) + BLE_ADI_SID_MASK = 0xF000, + BLE_ADI_SID_LSB = 12, +}; + +/// Advertising mode +enum ble_adv_mode +{ + /// Non connectable and non scannable mode + BLE_MODE_NON_CON_SCAN = 0, + /// Connectable Mode (accept connection request) + BLE_MODE_CONNECTABLE = 1, + /// Scannable Mode (accept scan request) + BLE_MODE_SCANNABLE = 2, + /// Reserved Advertising mode + BLE_MODE_RESERVED = 3, +}; + +/// Advertising data operation +enum adv_data_op +{ + /// Intermediate fragment of fragmented extended advertising data + ADV_DATA_OP_INTERMEDIATE_FRAG = 0, + /// First fragment of fragmented extended advertising data + ADV_DATA_OP_FIRST_FRAG = 1, + /// Last fragment of fragmented extended advertising data + ADV_DATA_OP_LAST_FRAG = 2, + /// Complete extended advertising data + ADV_DATA_OP_COMPLETE = 3, + /// Unchanged data (just update the Advertising DID) + ADV_DATA_OP_UNCHANGED_DATA = 4, +}; + +/// Advertising data fragment preference +enum adv_data_frag_pref +{ + /// The Controller may fragment all Host advertising data + ADV_DATA_MAY_FRAG = 0, + /// The Controller should not fragment nor minimize fragmentation of Host advertising data + ADV_DATA_SHOULD_NOT_FRAG = 1, +}; + +/* + * STRUCTURE DEFINITONS + **************************************************************************************** + */ + +///BD name structure +struct bd_name +{ + ///length for name + uint8_t namelen; + ///array of bytes for name + uint8_t name[BD_NAME_SIZE]; +}; + +///Structure device name +struct device_name +{ + ///array of bytes for name + uint8_t name[BD_NAME_SIZE]; +}; + +///Structure name vector +struct name_vect +{ + uint8_t vect[NAME_VECT_SIZE]; +}; + +/// lap structure +struct lap +{ + /// LAP + uint8_t A[BD_ADDR_LAP_LEN]; +}; + +/// class structure +struct devclass +{ + /// class + uint8_t A[DEV_CLASS_LEN]; +}; + +///Extended inquiry response structure +struct eir +{ + /// eir data + uint8_t data[EIR_DATA_SIZE]; +}; + +///Event mask structure +struct evt_mask +{ + ///8-byte array for mask value + uint8_t mask[EVT_MASK_LEN]; +}; + +///Host number of completed packets structure, for 1 connection handle +struct host_cmpl_pkts +{ + ///Connection handle + uint16_t con_hdl; + ///Number of completed packets + uint16_t nb_cmpl_pkts; +}; + +///BD Address structure +struct bd_addr +{ + ///6-byte array address value + uint8_t addr[BD_ADDR_LEN]; +}; + +///Access Address structure +struct access_addr +{ + ///4-byte array access address + uint8_t addr[ACCESS_ADDR_LEN]; +}; + +///Advertising data structure +struct adv_data +{ + ///Maximum length data bytes array + uint8_t data[ADV_DATA_LEN]; +}; + +///Scan response data structure +struct scan_rsp_data +{ + ///Maximum length data bytes array + uint8_t data[SCAN_RSP_DATA_LEN]; +}; + +///Channel map structure +struct chnl_map +{ + ///10-bytes channel map array + uint8_t map[CHNL_MAP_LEN]; +}; + +///Channel map structure +struct le_chnl_map +{ + ///5-byte channel map array + uint8_t map[LE_CHNL_MAP_LEN]; +}; + +///Long Term Key structure +struct ltk +{ + ///16-byte array for LTK value + uint8_t ltk[KEY_LEN]; +}; + +///Identity Resolving Key structure +struct irk +{ + ///16-byte array for IRK value + uint8_t key[KEY_LEN]; +}; + +/// Initialization vector (for AES-CCM encryption) +struct initialization_vector +{ + ///8-byte array + uint8_t vect[IV_LEN]; +}; + +/// Bluetooth address with link key +struct bd_addr_plus_key +{ + /// BD Address + struct bd_addr bd_addr; + /// Link Key + struct ltk link_key; +}; + +///Random number structure +struct rand_nb +{ + ///8-byte array for random number + uint8_t nb[RAND_NB_LEN]; +}; + +///Advertising report structure +struct adv_report +{ + ///Event type: + /// - ADV_CONN_UNDIR: Connectable Undirected advertising + /// - ADV_CONN_DIR: Connectable directed advertising + /// - ADV_DISC_UNDIR: Discoverable undirected advertising + /// - ADV_NONCONN_UNDIR: Non-connectable undirected advertising + uint8_t evt_type; + ///Advertising address type: public/random + uint8_t adv_addr_type; + ///Advertising address value + struct bd_addr adv_addr; + ///Data length in advertising packet + uint8_t data_len; + ///Data of advertising packet + uint8_t data[ADV_DATA_LEN]; + ///RSSI value for advertising packet + uint8_t rssi; +}; + +///Direct Advertising report structure +struct dir_adv_report +{ + ///Event type: + /// - ADV_CONN_DIR: Connectable directed advertising + uint8_t evt_type; + ///Address type: public/random + uint8_t addr_type; + ///Address value + struct bd_addr addr; + ///Direct address type: public/random + uint8_t dir_addr_type; + ///Direct address value + struct bd_addr dir_addr; + ///RSSI value for advertising packet + uint8_t rssi; +}; + +///Exteneded Advertising report structure +struct ext_adv_report +{ + ///Event type + uint16_t evt_type; + ///Advertising address type: public/random + uint8_t adv_addr_type; + ///Advertising address value + struct bd_addr adv_addr; + ///Primary PHY + uint8_t phy; + ///Secondary PHY + uint8_t phy2; + ///Advertising SID + uint8_t adv_sid; + ///Tx Power + uint8_t tx_power; + ///RSSI value for advertising packet + uint8_t rssi; + ///Periodic Advertising interval (Time=N*1.25ms) + uint16_t interval; + ///Direct address type + uint8_t dir_addr_type; + ///Direct address value + struct bd_addr dir_addr; + ///Data length in advertising packet + uint8_t data_len; + ///Data of advertising packet + uint8_t data[EXT_ADV_DATA_MAX_LEN]; +}; + +///Supported LE Features structure +struct le_features +{ + ///8-byte array for LE features + uint8_t feats[LE_FEATS_LEN]; +}; + +///Simple pairing hash structure +struct hash +{ + ///16-byte array for LTK value + uint8_t C[KEY_LEN]; +}; + +///Simple pairing randomizer structure +struct randomizer +{ + ///16-byte array for LTK value + uint8_t R[KEY_LEN]; +}; + +///Pin code structure +struct pin_code +{ + ///16-byte array for PIN value + uint8_t pin[PIN_CODE_MAX_LEN]; +}; + +///Sres structure +struct sres_nb +{ + ///8-byte array for random number + uint8_t nb[SRES_LEN]; +}; + +///aco structure +struct aco +{ + ///8-byte array for random number + uint8_t a[ACO_LEN]; +}; + +///struct byte 16 to stay align with the sdl version +struct byte16 +{ + uint8_t A[16]; +}; + +///Controller number of completed packets structure +struct nb_cmpl_pk +{ + ///Connection handle + uint16_t con_hdl; + ///Controller number of data packets that have been completed since last time + uint16_t nb_hc_cmpl_pkts; +}; + +///Supported Features structure +struct features +{ + ///8-byte array for features + uint8_t feats[FEATS_LEN]; +}; + +///Supported commands structure +struct supp_cmds +{ + ///64-byte array for supported commands + uint8_t cmds[SUPP_CMDS_LEN]; +}; + +///Supported LMP features structure +struct lmp_features +{ + ///8-byte array for LMp features + uint8_t feats[FEATS_LEN]; +}; + +///Simple pairing IO capabilities +struct io_capability +{ + ///IO capability + uint8_t io_cap; + /// Out Of Band Data present + bool oob_data_present; + ///Authentication Requirement + uint8_t aut_req; +}; + +///Public key +struct pub_key_192 +{ + uint8_t p_key[PUB_KEY_192_LEN/2]; +}; + +///Public key +struct pub_key_256 +{ + uint8_t p_key[PUB_KEY_256_LEN/2]; +}; + +///Simple pairing public keys 192 +struct sp_pub_key_192 +{ + ///Public key X + struct pub_key_192 X; + ///Public key Y + struct pub_key_192 Y; +}; + +///Simple pairing public keys 256 +struct sp_pub_key_256 +{ + ///Public key X + struct pub_key_256 X; + ///Public key Y + struct pub_key_256 Y; +}; + +///Supported LE states structure +struct le_states +{ + ///8-byte array for LE states + uint8_t supp_states[LE_STATES_LEN]; +}; + +///White List element structure +struct white_list +{ + ///BD address of device entry + struct bd_addr wl_bdaddr; + ///BD address type of device entry + uint8_t wl_bdaddr_type; +}; + +///CRC initial value structure +struct crc_init +{ + ///3-byte array CRC initial value + uint8_t crc[CRC_INIT_LEN]; +}; + +///Session key diversifier master or slave structure +struct sess_k_div_x +{ + ///8-byte array for diversifier value + uint8_t skdiv[SESS_KEY_DIV_LEN]; +}; + +///Session key diversifier structure +struct sess_k_div +{ + ///16-byte array for session key diversifier. + uint8_t skd[2*SESS_KEY_DIV_LEN]; +}; + +///Initiator vector +struct init_vect +{ + ///4-byte array for vector + uint8_t iv[INIT_VECT_LEN]; +}; + +typedef struct t_public_key +{ + uint8_t x[PUBLIC_KEY_P256_LEN]; + uint8_t y[PUBLIC_KEY_P256_LEN]; + +} t_public_key; + +/// structure connection request +struct pdu_con_req +{ + /// access address + struct access_addr aa; + + /// CRC init + struct crc_init crcinit; + + /// window size + uint8_t winsize; + + /// window offset + uint16_t winoffset; + + /// interval + uint16_t interval; + + /// latency + uint16_t latency; + + /// timeout + uint16_t timeout; + + /// channel mapping + struct le_chnl_map chm; + + /// hopping + uint8_t hop_sca; +}; + +/// Device specific link preferences +typedef struct +{ + // **** Data Length Management **** + /// Suggested value for the Controller's maximum transmitted number of payload octets + uint16_t suggested_max_tx_octets; + /// Suggested value for the Controller's maximum packet transmission time (in us) + uint16_t suggested_max_tx_time; + + // **** PHY Management **** + /// Default TX preferred PHY to use (@see enum le_phy_value) + uint8_t tx_phys; + /// Default RX preferred PHY to use (@see enum le_phy_value) + uint8_t rx_phys; +} link_pref_t; + + +/// @} CO_BT_DEFINES +#endif // CO_BT_DEFINES_H_ diff --git a/services/ble_stack/common/api/co_endian.h b/services/ble_stack/common/api/co_endian.h new file mode 100644 index 0000000..2cdab20 --- /dev/null +++ b/services/ble_stack/common/api/co_endian.h @@ -0,0 +1,235 @@ +#ifndef _CO_ENDIAN_H_ +#define _CO_ENDIAN_H_ + +#include // standard integer definitions +#include "rwip_config.h" // stack configuration +#include "arch.h" // architectural platform definition + +/** + **************************************************************************************** + * @defgroup CO_ENDIAN Endianness + * @ingroup COMMON + * @brief Endianness conversion functions. + * + * This set of functions converts values between the local system + * and a external one. It is inspired from the htonl-like functions + * from the standard C library. + * + * Example: + * @code + * struct eth_header *header = get_header(); // get pointer on Eth II packet header + * uint16_t eth_id; // will contain the type of the packet + * eth_id = co_ntohs(header->eth_id); // retrieve the type with correct endianness + * @endcode + * + * @{ + * **************************************************************************************** + * */ + + +/** + **************************************************************************************** + * @brief Swap bytes of a 32 bits value. + * The swap is done in every case. Should not be called directly. + * @param[in] val32 The 32 bits value to swap. + * @return The 32 bit swapped value. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_bswap32(uint32_t val32) +{ + return (val32<<24) | ((val32<<8)&0xFF0000) | ((val32>>8)&0xFF00) | ((val32>>24)&0xFF); +} + +/** + **************************************************************************************** + * @brief Swap bytes of a 16 bits value. + * The swap is done in every case. Should not be called directly. + * @param[in] val16 The 16 bit value to swap. + * @return The 16 bit swapped value. + **************************************************************************************** + */ +__STATIC __INLINE uint16_t co_bswap16(uint16_t val16) +{ + return ((val16<<8)&0xFF00) | ((val16>>8)&0xFF); +} +/// @} CO_ENDIAN + + + + +/** + * **************************************************************************************** + * @defgroup CO_ENDIAN_NET Endianness (Network) + * @ingroup CO_ENDIAN + * @brief Endianness conversion functions for Network data + * + * Converts values between the local system and big-endian network data + * (e.g. IP, Ethernet, but NOT WLAN). + * + * The \b host term in the descriptions of these functions refers + * to the local system, i.e. \b application or \b embedded system. + * Therefore, these functions will behave differently depending on which + * side they are used. The reason of this terminology is to keep the + * same name than the standard C function. + * + * Behavior will depends on the endianness of the host: + * - little endian: swap bytes; + * - big endian: identity function. + * + * @{ + * **************************************************************************************** + * */ + +/** + **************************************************************************************** + * @brief Convert host to network long word. + * + * @param[in] hostlong Long word value to convert. + * + * @return The converted long word. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_htonl(uint32_t hostlong) +{ + #if (!CPU_LE) + return hostlong; + #else + return co_bswap32(hostlong); + #endif // CPU_LE +} + +/** + **************************************************************************************** + * @brief Convert host to network short word. + * + * @param[in] hostshort Short word value to convert. + * + * @return The converted short word. + **************************************************************************************** + */ +__STATIC __INLINE uint16_t co_htons(uint16_t hostshort) +{ + #if (!CPU_LE) + return hostshort; + #else + return co_bswap16(hostshort); + #endif // CPU_LE +} + +/** + **************************************************************************************** + * @brief Convert network to host long word. + * + * @param[in] netlong Long word value to convert. + * + * @return The converted long word. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_ntohl(uint32_t netlong) +{ + return co_htonl(netlong); +} + +/** + **************************************************************************************** + * @brief Convert network to host short word. + * + * @param[in] netshort Short word value to convert. + * + * @return The converted short word. + **************************************************************************************** + */ +__STATIC __INLINE uint16_t co_ntohs(uint16_t netshort) +{ + return co_htons(netshort); +} +/// @} CO_ENDIAN_NET + +/** + * **************************************************************************************** + * @defgroup CO_ENDIAN_BT Endianness (BT) + * @ingroup CO_ENDIAN + * @brief Endianness conversion functions for Bluetooth data (HCI and protocol) + * + * Converts values between the local system and little-endian Bluetooth data. + * + * The \b host term in the descriptions of these functions refers + * to the local system (check \ref CO_ENDIAN_NET "this comment"). + * + * Behavior will depends on the endianness of the host: + * - little endian: identity function; + * - big endian: swap bytes. + * + * @addtogroup CO_ENDIAN_BT + * @{ + * **************************************************************************************** + * */ + +/** + **************************************************************************************** + * @brief Convert host to Bluetooth long word. + * + * @param[in] hostlong Long word value to convert. + * + * @return The converted long word. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_htobl(uint32_t hostlong) +{ + #if (CPU_LE) + return hostlong; + #else + return co_bswap32(hostlong); + #endif // CPU_LE +} + +/** + **************************************************************************************** + * @brief Convert host to Bluetooth short word. + * + * @param[in] hostshort Short word value to convert. + * + * @return The converted short word. + **************************************************************************************** + */ +__STATIC __INLINE uint16_t co_htobs(uint16_t hostshort) +{ + #if (CPU_LE) + return hostshort; + #else + return co_bswap16(hostshort); + #endif // CPU_LE +} + + +/** + **************************************************************************************** + * @brief Convert Bluetooth to host long word. + * + * @param[in] btlong Long word value to convert. + * + * @return The converted long word. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_btohl(uint32_t btlong) +{ + return co_htobl(btlong); +} + + +/** + **************************************************************************************** + * @brief Convert Bluetooth to host short word. + * + * @param[in] btshort Short word value to convert. + * + * @return The converted short word. + **************************************************************************************** + */ +__STATIC __INLINE uint16_t co_btohs(uint16_t btshort) +{ + return co_htobs(btshort); +} +/// @} CO_ENDIAN + +#endif // _CO_ENDIAN_H_ diff --git a/services/ble_stack/common/api/co_error.h b/services/ble_stack/common/api/co_error.h new file mode 100644 index 0000000..a02c9e7 --- /dev/null +++ b/services/ble_stack/common/api/co_error.h @@ -0,0 +1,101 @@ +#ifndef CO_ERROR_H_ +#define CO_ERROR_H_ + +/** + **************************************************************************************** + * @addtogroup CO_ERROR Error Codes + * @ingroup COMMON + * @brief Defines error codes in messages. + * + * @{ + **************************************************************************************** + */ + +/* + * DEFINES + **************************************************************************************** + */ +enum co_error +{ +/***************************************************** + *** ERROR CODES *** + *****************************************************/ + + CO_ERROR_NO_ERROR = 0x00, + CO_ERROR_UNKNOWN_HCI_COMMAND = 0x01, + CO_ERROR_UNKNOWN_CONNECTION_ID = 0x02, + CO_ERROR_HARDWARE_FAILURE = 0x03, + CO_ERROR_PAGE_TIMEOUT = 0x04, + CO_ERROR_AUTH_FAILURE = 0x05, + CO_ERROR_PIN_MISSING = 0x06, + CO_ERROR_MEMORY_CAPA_EXCEED = 0x07, + CO_ERROR_CON_TIMEOUT = 0x08, + CO_ERROR_CON_LIMIT_EXCEED = 0x09, + CO_ERROR_SYNC_CON_LIMIT_DEV_EXCEED = 0x0A, + CO_ERROR_ACL_CON_EXISTS = 0x0B, + CO_ERROR_COMMAND_DISALLOWED = 0x0C, + CO_ERROR_CONN_REJ_LIMITED_RESOURCES = 0x0D, + CO_ERROR_CONN_REJ_SECURITY_REASONS = 0x0E, + CO_ERROR_CONN_REJ_UNACCEPTABLE_BDADDR = 0x0F, + CO_ERROR_CONN_ACCEPT_TIMEOUT_EXCEED = 0x10, + CO_ERROR_UNSUPPORTED = 0x11, + CO_ERROR_INVALID_HCI_PARAM = 0x12, + CO_ERROR_REMOTE_USER_TERM_CON = 0x13, + CO_ERROR_REMOTE_DEV_TERM_LOW_RESOURCES = 0x14, + CO_ERROR_REMOTE_DEV_POWER_OFF = 0x15, + CO_ERROR_CON_TERM_BY_LOCAL_HOST = 0x16, + CO_ERROR_REPEATED_ATTEMPTS = 0x17, + CO_ERROR_PAIRING_NOT_ALLOWED = 0x18, + CO_ERROR_UNKNOWN_LMP_PDU = 0x19, + CO_ERROR_UNSUPPORTED_REMOTE_FEATURE = 0x1A, + CO_ERROR_SCO_OFFSET_REJECTED = 0x1B, + CO_ERROR_SCO_INTERVAL_REJECTED = 0x1C, + CO_ERROR_SCO_AIR_MODE_REJECTED = 0x1D, + CO_ERROR_INVALID_LMP_PARAM = 0x1E, + CO_ERROR_UNSPECIFIED_ERROR = 0x1F, + CO_ERROR_UNSUPPORTED_LMP_PARAM_VALUE = 0x20, + CO_ERROR_ROLE_CHANGE_NOT_ALLOWED = 0x21, + CO_ERROR_LMP_RSP_TIMEOUT = 0x22, + CO_ERROR_LMP_COLLISION = 0x23, + CO_ERROR_LMP_PDU_NOT_ALLOWED = 0x24, + CO_ERROR_ENC_MODE_NOT_ACCEPT = 0x25, + CO_ERROR_LINK_KEY_CANT_CHANGE = 0x26, + CO_ERROR_QOS_NOT_SUPPORTED = 0x27, + CO_ERROR_INSTANT_PASSED = 0x28, + CO_ERROR_PAIRING_WITH_UNIT_KEY_NOT_SUP = 0x29, + CO_ERROR_DIFF_TRANSACTION_COLLISION = 0x2A, + CO_ERROR_QOS_UNACCEPTABLE_PARAM = 0x2C, + CO_ERROR_QOS_REJECTED = 0x2D, + CO_ERROR_CHANNEL_CLASS_NOT_SUP = 0x2E, + CO_ERROR_INSUFFICIENT_SECURITY = 0x2F, + CO_ERROR_PARAM_OUT_OF_MAND_RANGE = 0x30, + CO_ERROR_ROLE_SWITCH_PEND = 0x32, /* LM_ROLE_SWITCH_PENDING */ + CO_ERROR_RESERVED_SLOT_VIOLATION = 0x34, /* LM_RESERVED_SLOT_VIOLATION */ + CO_ERROR_ROLE_SWITCH_FAIL = 0x35, /* LM_ROLE_SWITCH_FAILED */ + CO_ERROR_EIR_TOO_LARGE = 0x36, /* LM_EXTENDED_INQUIRY_RESPONSE_TOO_LARGE */ + CO_ERROR_SP_NOT_SUPPORTED_HOST = 0x37, + CO_ERROR_HOST_BUSY_PAIRING = 0x38, + CO_ERROR_CONTROLLER_BUSY = 0x3A, + CO_ERROR_UNACCEPTABLE_CONN_PARAM = 0x3B, + CO_ERROR_DIRECT_ADV_TO = 0x3C, + CO_ERROR_TERMINATED_MIC_FAILURE = 0x3D, + CO_ERROR_CONN_FAILED_TO_BE_EST = 0x3E, + CO_ERROR_CCA_REJ_USE_CLOCK_DRAG = 0x40, + CO_ERROR_TYPE0_SUBMAP_NOT_DEFINED = 0x41, + CO_ERROR_UNKNOWN_ADVERTISING_ID = 0x42, + CO_ERROR_LIMIT_REACHED = 0x43, + CO_ERROR_OPERATION_CANCELED_BY_HOST = 0x44, + CO_ERROR_UNDEFINED = 0xFF, + + +/***************************************************** + *** HW ERROR CODES *** + *****************************************************/ + + CO_ERROR_HW_UART_OUT_OF_SYNC = 0x00, + CO_ERROR_HW_MEM_ALLOC_FAIL = 0x01, +}; + +/// @} CO_ERROR + +#endif // CO_ERROR_H_ diff --git a/services/ble_stack/common/api/co_hci.h b/services/ble_stack/common/api/co_hci.h new file mode 100644 index 0000000..b06457f --- /dev/null +++ b/services/ble_stack/common/api/co_hci.h @@ -0,0 +1,4986 @@ +#ifndef CO_HCI_H_ +#define CO_HCI_H_ + +/** + **************************************************************************************** + * @addtogroup COMMON Common SW Block + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include // standard boolean definitions +#include // standard definitions +#include // standard integer definitions + +#include "rwip_config.h" // IP configuration + +#include "compiler.h" // compiler definitions +#include "hci_api.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +/******************************************************************************************/ +/* ------------------------- H4TL DEFINITIONS Part IV.A -----------------------------*/ +/******************************************************************************************/ + +///HCI Transport Header length - change if different transport +#define HCI_TRANSPORT_HDR_LEN 0x01 + +///UART header: command message type +#define HCI_CMD_MSG_TYPE 0x01 + +///UART header: ACL data message type +#define HCI_ACL_MSG_TYPE 0x02 + +///UART header: Synchronous data message type +#define HCI_SYNC_MSG_TYPE 0x03 + +///UART header: event message type +#define HCI_EVT_MSG_TYPE 0x04 + +///UART header: event message type +#define HCI_TCI_MSG_TYPE 0xFF + +/******************************************************************************************/ +/* ------------------------- HCI DEFINITIONS Part II.E -----------------------------*/ +/******************************************************************************************/ + +///HCI Command Opcode byte length +#define HCI_CMD_OPCODE_LEN (0x02) + +///HCI Event code byte length +#define HCI_EVT_CODE_LEN (0x01) + +///HCI Command/Event parameter length field byte length +#define HCI_CMDEVT_PARLEN_LEN (0x01) + +///HCI Command header length +#define HCI_CMD_HDR_LEN (HCI_CMD_OPCODE_LEN + HCI_CMDEVT_PARLEN_LEN) + +///HCI Event header length +#define HCI_EVT_HDR_LEN (HCI_EVT_CODE_LEN + HCI_CMDEVT_PARLEN_LEN) + +/// HCI ACL header: handle and flags decoding +enum hci_acl_hdr_fields +{ + + /// bits[00:11]: Connection handle + HCI_ACL_HDR_HDL_LSB = (0), + HCI_ACL_HDR_HDL_MASK = (0x0FFF), + /// bits[12:13]: Packet boundary flag + HCI_ACL_HDR_PB_FLAG_LSB = (12), + HCI_ACL_HDR_PB_FLAG_MASK = (0x3000), + /// bits[14:15]: Broadcast flag + HCI_ACL_HDR_BC_FLAG_LSB = (14), + HCI_ACL_HDR_BC_FLAG_MASK = (0xC000), + + /// Packet boundary and Broadcast flags + HCI_ACL_HDR_DATA_FLAG_LSB = (12), + HCI_ACL_HDR_DATA_FLAG_MASK = (0xF000), +}; + +#define HCI_ACL_HDR_HDL_FLAGS_POS (0) +#define HCI_ACL_HDR_HDL_FLAGS_LEN (2) +/// HCI ACL header: data length field length +#define HCI_ACL_HDR_DATA_LEN_POS (HCI_ACL_HDR_HDL_FLAGS_LEN) +#define HCI_ACL_HDR_DATA_LEN_LEN (2) + +///HCI ACL data packet header length +#define HCI_ACL_HDR_LEN (HCI_ACL_HDR_HDL_FLAGS_LEN + HCI_ACL_HDR_DATA_LEN_LEN) + +/// HCI Synchronous header: handle and flags decoding +#define HCI_SYNC_HDR_HDL_FLAGS_POS (0) +#define HCI_SYNC_HDR_HDL_FLAGS_LEN (2) +#define HCI_SYNC_HDR_HDL_POS (0) +#define HCI_SYNC_HDR_HDL_MASK (0x0FFF) +#define HCI_SYNC_HDR_PSF_FLAG_POS (12) +#define HCI_SYNC_HDR_PSF_FLAG_MASK (0x3000) +#define HCI_SYNC_HDR_RES_FLAG_POS (14) +#define HCI_SYNC_HDR_RES_FLAG_MASK (0xC000) +#define HCI_SYNC_HDR_DATA_FLAG_POS (12) +#define HCI_SYNC_HDR_DATA_FLAG_MASK (0xF000) + +/// HCI Synchronous header: data length field length +#define HCI_SYNC_HDR_DATA_LEN_POS (HCI_SYNC_HDR_HDL_FLAGS_LEN) +#define HCI_SYNC_HDR_DATA_LEN_LEN (1) +#define HCI_SYNC_MAX_DATA_SIZE (255) + +///HCI sync data packet header length +#define HCI_SYNC_HDR_LEN (HCI_SYNC_HDR_HDL_FLAGS_LEN + HCI_SYNC_HDR_DATA_LEN_LEN) + +///HCI Command Complete Event minimum parameter length: 1(nb_pk)+2(opcode) +#define HCI_CCEVT_HDR_PARLEN (0x03) + +///HCI Command Complete Event header length:1(code)+1(len)+1(pk)+2(opcode) +#define HCI_CCEVT_HDR_LEN (HCI_EVT_HDR_LEN + HCI_CCEVT_HDR_PARLEN) + +///HCI Basic Command Complete Event packet length +#define HCI_CCEVT_BASIC_LEN (HCI_CCEVT_HDR_LEN + 1) + +///HCI Command Status Event parameter length - constant +#define HCI_CSEVT_PARLEN (0x04) + +///HCI Command Status Event length:1(code)+1(len)+1(st)+1(pk)+2(opcode) +#define HCI_CSEVT_LEN (HCI_EVT_HDR_LEN + HCI_CSEVT_PARLEN) + +///HCI Reset Command parameter length +#define HCI_RESET_CMD_PARLEN 0 + +/// Default return parameter length for HCI Command Complete Event +#define HCI_CCEVT_BASIC_RETPAR_LEN 1 + +/// Max HCI commands param size +#define HCI_MAX_CMD_PARAM_SIZE 255 + +/// Macro to extract OCF from OPCODE +#define HCI_OP2OCF(opcode) ((opcode) & 0x03FF) + +/// Macro to extract OGF from OPCODE +#define HCI_OP2OGF(opcode) ((opcode) >> 10 & 0x003F) + +/// Macro to create OPCODE from OGF and OCF +#define HCI_OPCODE(ocf, ogf) (((ogf) << 10) | ocf) + +/// Maximum length of HCI advertising data fragments +#define HCI_ADV_DATA_FRAG_MAX_LEN 252 + + +/************************************************************************************** + ************** HCI COMMANDS **************** + **************************************************************************************/ + +///HCI enumeration of possible Command OGF values. +enum +{ + ///HCI Link Control Commands Group OGF code + LK_CNTL_OGF = 0x01, + ///HCI Link Policy Commands Group OGF code + LK_POL_OGF, + ///HCI Controller and Baseband Commands Group OGF code + CNTLR_BB_OGF, + ///HCI Information Parameters Commands Group OGF code + INFO_PAR_OGF, + ///HCI Status Commands Group OGF code + STAT_PAR_OGF, + ///HCI Test Commands Group OGF code + TEST_OGF, + ///HCI Low Energy Commands Group OGF code + LE_CNTLR_OGF=0x08, + ///HCI Vendor Specific Group OGF code + VS_OGF = 0x3F, + MAX_OGF +}; + + +///Commands Opcodes: OGF(6b) | OCF(10b) +/* Some Abbreviation used in names: + * - LK = Link Key + * - RD = Read + * - WR = Write + * - REM = Remote + * - STG = Settings + * - CON = Connection + * - CHG = Change + * - DFT = Default + * - PER = Periodic + */ + +///HCI enumeration of possible Command OP Codes. +enum hci_opcode +{ + HCI_NO_OPERATION_CMD_OPCODE = 0x0000, + + //Link Control Commands + HCI_INQ_CMD_OPCODE = 0x0401, + HCI_INQ_CANCEL_CMD_OPCODE = 0x0402, + HCI_PER_INQ_MODE_CMD_OPCODE = 0x0403, + HCI_EXIT_PER_INQ_MODE_CMD_OPCODE = 0x0404, + HCI_CREATE_CON_CMD_OPCODE = 0x0405, + HCI_DISCONNECT_CMD_OPCODE = 0x0406, + HCI_CREATE_CON_CANCEL_CMD_OPCODE = 0x0408, + HCI_ACCEPT_CON_REQ_CMD_OPCODE = 0x0409, + HCI_REJECT_CON_REQ_CMD_OPCODE = 0x040A, + HCI_LK_REQ_REPLY_CMD_OPCODE = 0x040B, + HCI_LK_REQ_NEG_REPLY_CMD_OPCODE = 0x040C, + HCI_PIN_CODE_REQ_REPLY_CMD_OPCODE = 0x040D, + HCI_PIN_CODE_REQ_NEG_REPLY_CMD_OPCODE = 0x040E, + HCI_CHG_CON_PKT_TYPE_CMD_OPCODE = 0x040F, + HCI_AUTH_REQ_CMD_OPCODE = 0x0411, + HCI_SET_CON_ENC_CMD_OPCODE = 0x0413, + HCI_CHG_CON_LK_CMD_OPCODE = 0x0415, + HCI_MASTER_LK_CMD_OPCODE = 0x0417, + HCI_REM_NAME_REQ_CMD_OPCODE = 0x0419, + HCI_REM_NAME_REQ_CANCEL_CMD_OPCODE = 0x041A, + HCI_RD_REM_SUPP_FEATS_CMD_OPCODE = 0x041B, + HCI_RD_REM_EXT_FEATS_CMD_OPCODE = 0x041C, + HCI_RD_REM_VER_INFO_CMD_OPCODE = 0x041D, + HCI_RD_CLK_OFF_CMD_OPCODE = 0x041F, + HCI_RD_LMP_HDL_CMD_OPCODE = 0x0420, + HCI_SETUP_SYNC_CON_CMD_OPCODE = 0x0428, + HCI_ACCEPT_SYNC_CON_REQ_CMD_OPCODE = 0x0429, + HCI_REJECT_SYNC_CON_REQ_CMD_OPCODE = 0x042A, + HCI_IO_CAP_REQ_REPLY_CMD_OPCODE = 0x042B, + HCI_USER_CFM_REQ_REPLY_CMD_OPCODE = 0x042C, + HCI_USER_CFM_REQ_NEG_REPLY_CMD_OPCODE = 0x042D, + HCI_USER_PASSKEY_REQ_REPLY_CMD_OPCODE = 0x042E, + HCI_USER_PASSKEY_REQ_NEG_REPLY_CMD_OPCODE = 0x042F, + HCI_REM_OOB_DATA_REQ_REPLY_CMD_OPCODE = 0x0430, + HCI_REM_OOB_DATA_REQ_NEG_REPLY_CMD_OPCODE = 0x0433, + HCI_IO_CAP_REQ_NEG_REPLY_CMD_OPCODE = 0x0434, + HCI_ENH_SETUP_SYNC_CON_CMD_OPCODE = 0x043D, + HCI_ENH_ACCEPT_SYNC_CON_CMD_OPCODE = 0x043E, + HCI_TRUNC_PAGE_CMD_OPCODE = 0x043F, + HCI_TRUNC_PAGE_CAN_CMD_OPCODE = 0x0440, + HCI_SET_CON_SLV_BCST_CMD_OPCODE = 0x0441, + HCI_SET_CON_SLV_BCST_REC_CMD_OPCODE = 0x0442, + HCI_START_SYNC_TRAIN_CMD_OPCODE = 0x0443, + HCI_REC_SYNC_TRAIN_CMD_OPCODE = 0x0444, + HCI_REM_OOB_EXT_DATA_REQ_REPLY_CMD_OPCODE = 0x0445, + + //Link Policy Commands + HCI_HOLD_MODE_CMD_OPCODE = 0x0801, + HCI_SNIFF_MODE_CMD_OPCODE = 0x0803, + HCI_EXIT_SNIFF_MODE_CMD_OPCODE = 0x0804, + HCI_PARK_STATE_CMD_OPCODE = 0x0805, + HCI_EXIT_PARK_STATE_CMD_OPCODE = 0x0806, + HCI_QOS_SETUP_CMD_OPCODE = 0x0807, + HCI_ROLE_DISCOVERY_CMD_OPCODE = 0x0809, + HCI_SWITCH_ROLE_CMD_OPCODE = 0x080B, + HCI_RD_LINK_POL_STG_CMD_OPCODE = 0x080C, + HCI_WR_LINK_POL_STG_CMD_OPCODE = 0x080D, + HCI_RD_DFT_LINK_POL_STG_CMD_OPCODE = 0x080E, + HCI_WR_DFT_LINK_POL_STG_CMD_OPCODE = 0x080F, + HCI_FLOW_SPEC_CMD_OPCODE = 0x0810, + HCI_SNIFF_SUB_CMD_OPCODE = 0x0811, + + //Controller and Baseband Commands + HCI_SET_EVT_MASK_CMD_OPCODE = 0x0C01, + HCI_RESET_CMD_OPCODE = 0x0C03, + HCI_SET_EVT_FILTER_CMD_OPCODE = 0x0C05, + HCI_FLUSH_CMD_OPCODE = 0x0C08, + HCI_RD_PIN_TYPE_CMD_OPCODE = 0x0C09, + HCI_WR_PIN_TYPE_CMD_OPCODE = 0x0C0A, + HCI_CREATE_NEW_UNIT_KEY_CMD_OPCODE = 0x0C0B, + HCI_RD_STORED_LK_CMD_OPCODE = 0x0C0D, + HCI_WR_STORED_LK_CMD_OPCODE = 0x0C11, + HCI_DEL_STORED_LK_CMD_OPCODE = 0x0C12, + HCI_WR_LOCAL_NAME_CMD_OPCODE = 0x0C13, + HCI_RD_LOCAL_NAME_CMD_OPCODE = 0x0C14, + HCI_RD_CON_ACCEPT_TO_CMD_OPCODE = 0x0C15, + HCI_WR_CON_ACCEPT_TO_CMD_OPCODE = 0x0C16, + HCI_RD_PAGE_TO_CMD_OPCODE = 0x0C17, + HCI_WR_PAGE_TO_CMD_OPCODE = 0x0C18, + HCI_RD_SCAN_EN_CMD_OPCODE = 0x0C19, + HCI_WR_SCAN_EN_CMD_OPCODE = 0x0C1A, + HCI_RD_PAGE_SCAN_ACT_CMD_OPCODE = 0x0C1B, + HCI_WR_PAGE_SCAN_ACT_CMD_OPCODE = 0x0C1C, + HCI_RD_INQ_SCAN_ACT_CMD_OPCODE = 0x0C1D, + HCI_WR_INQ_SCAN_ACT_CMD_OPCODE = 0x0C1E, + HCI_RD_AUTH_EN_CMD_OPCODE = 0x0C1F, + HCI_WR_AUTH_EN_CMD_OPCODE = 0x0C20, + HCI_RD_CLASS_OF_DEV_CMD_OPCODE = 0x0C23, + HCI_WR_CLASS_OF_DEV_CMD_OPCODE = 0x0C24, + HCI_RD_VOICE_STG_CMD_OPCODE = 0x0C25, + HCI_WR_VOICE_STG_CMD_OPCODE = 0x0C26, + HCI_RD_AUTO_FLUSH_TO_CMD_OPCODE = 0x0C27, + HCI_WR_AUTO_FLUSH_TO_CMD_OPCODE = 0x0C28, + HCI_RD_NB_BDCST_RETX_CMD_OPCODE = 0x0C29, + HCI_WR_NB_BDCST_RETX_CMD_OPCODE = 0x0C2A, + HCI_RD_HOLD_MODE_ACTIVITY_CMD_OPCODE = 0x0C2B, + HCI_WR_HOLD_MODE_ACTIVITY_CMD_OPCODE = 0x0C2C, + HCI_RD_TX_PWR_LVL_CMD_OPCODE = 0x0C2D, + HCI_RD_SYNC_FLOW_CTRL_EN_CMD_OPCODE = 0x0C2E, + HCI_WR_SYNC_FLOW_CTRL_EN_CMD_OPCODE = 0x0C2F, + HCI_SET_CTRL_TO_HOST_FLOW_CTRL_CMD_OPCODE = 0x0C31, + HCI_HOST_BUF_SIZE_CMD_OPCODE = 0x0C33, + HCI_HOST_NB_CMP_PKTS_CMD_OPCODE = 0x0C35, + HCI_RD_LINK_SUPV_TO_CMD_OPCODE = 0x0C36, + HCI_WR_LINK_SUPV_TO_CMD_OPCODE = 0x0C37, + HCI_RD_NB_SUPP_IAC_CMD_OPCODE = 0x0C38, + HCI_RD_CURR_IAC_LAP_CMD_OPCODE = 0x0C39, + HCI_WR_CURR_IAC_LAP_CMD_OPCODE = 0x0C3A, + HCI_SET_AFH_HOST_CH_CLASS_CMD_OPCODE = 0x0C3F, + HCI_RD_INQ_SCAN_TYPE_CMD_OPCODE = 0x0C42, + HCI_WR_INQ_SCAN_TYPE_CMD_OPCODE = 0x0C43, + HCI_RD_INQ_MODE_CMD_OPCODE = 0x0C44, + HCI_WR_INQ_MODE_CMD_OPCODE = 0x0C45, + HCI_RD_PAGE_SCAN_TYPE_CMD_OPCODE = 0x0C46, + HCI_WR_PAGE_SCAN_TYPE_CMD_OPCODE = 0x0C47, + HCI_RD_AFH_CH_ASSESS_MODE_CMD_OPCODE = 0x0C48, + HCI_WR_AFH_CH_ASSESS_MODE_CMD_OPCODE = 0x0C49, + HCI_RD_EXT_INQ_RSP_CMD_OPCODE = 0x0C51, + HCI_WR_EXT_INQ_RSP_CMD_OPCODE = 0x0C52, + HCI_REFRESH_ENC_KEY_CMD_OPCODE = 0x0C53, + HCI_RD_SP_MODE_CMD_OPCODE = 0x0C55, + HCI_WR_SP_MODE_CMD_OPCODE = 0x0C56, + HCI_RD_LOC_OOB_DATA_CMD_OPCODE = 0x0C57, + HCI_RD_INQ_RSP_TX_PWR_LVL_CMD_OPCODE = 0x0C58, + HCI_WR_INQ_TX_PWR_LVL_CMD_OPCODE = 0x0C59, + HCI_RD_DFT_ERR_DATA_REP_CMD_OPCODE = 0x0C5A, + HCI_WR_DFT_ERR_DATA_REP_CMD_OPCODE = 0x0C5B, + HCI_ENH_FLUSH_CMD_OPCODE = 0x0C5F, + HCI_SEND_KEYPRESS_NOTIF_CMD_OPCODE = 0x0C60, + HCI_SET_EVT_MASK_PAGE_2_CMD_OPCODE = 0x0C63, + HCI_RD_FLOW_CNTL_MODE_CMD_OPCODE = 0x0C66, + HCI_WR_FLOW_CNTL_MODE_CMD_OPCODE = 0x0C67, + HCI_RD_ENH_TX_PWR_LVL_CMD_OPCODE = 0x0C68, + HCI_RD_LE_HOST_SUPP_CMD_OPCODE = 0x0C6C, + HCI_WR_LE_HOST_SUPP_CMD_OPCODE = 0x0C6D, + HCI_SET_MWS_CHANNEL_PARAMS_CMD_OPCODE = 0x0C6E, + HCI_SET_EXTERNAL_FRAME_CONFIG_CMD_OPCODE = 0x0C6F, + HCI_SET_MWS_SIGNALING_CMD_OPCODE = 0x0C70, + HCI_SET_MWS_TRANSPORT_LAYER_CMD_OPCODE = 0x0C71, + HCI_SET_MWS_SCAN_FREQ_TABLE_CMD_OPCODE = 0x0C72, + HCI_SET_MWS_PATTERN_CONFIG_CMD_OPCODE = 0x0C73, + HCI_SET_RES_LT_ADDR_CMD_OPCODE = 0x0C74, + HCI_DEL_RES_LT_ADDR_CMD_OPCODE = 0x0C75, + HCI_SET_CON_SLV_BCST_DATA_CMD_OPCODE = 0x0C76, + HCI_RD_SYNC_TRAIN_PARAM_CMD_OPCODE = 0x0C77, + HCI_WR_SYNC_TRAIN_PARAM_CMD_OPCODE = 0x0C78, + HCI_RD_SEC_CON_HOST_SUPP_CMD_OPCODE = 0x0C79, + HCI_WR_SEC_CON_HOST_SUPP_CMD_OPCODE = 0x0C7A, + HCI_RD_AUTH_PAYL_TO_CMD_OPCODE = 0x0C7B, + HCI_WR_AUTH_PAYL_TO_CMD_OPCODE = 0x0C7C, + HCI_RD_LOC_OOB_EXT_DATA_CMD_OPCODE = 0x0C7D, + HCI_RD_EXT_PAGE_TO_CMD_OPCODE = 0x0C7E, + HCI_WR_EXT_PAGE_TO_CMD_OPCODE = 0x0C7F, + HCI_RD_EXT_INQ_LEN_CMD_OPCODE = 0x0C80, + HCI_WR_EXT_INQ_LEN_CMD_OPCODE = 0x0C81, + + //Info Params + HCI_RD_LOCAL_VER_INFO_CMD_OPCODE = 0x1001, + HCI_RD_LOCAL_SUPP_CMDS_CMD_OPCODE = 0x1002, + HCI_RD_LOCAL_SUPP_FEATS_CMD_OPCODE = 0x1003, + HCI_RD_LOCAL_EXT_FEATS_CMD_OPCODE = 0x1004, + HCI_RD_BUFF_SIZE_CMD_OPCODE = 0x1005, + HCI_RD_BD_ADDR_CMD_OPCODE = 0x1009, + HCI_RD_LOCAL_SUPP_CODECS_CMD_OPCODE = 0x100B, + + //Status Params + HCI_RD_FAIL_CONTACT_CNT_CMD_OPCODE = 0x1401, + HCI_RST_FAIL_CONTACT_CNT_CMD_OPCODE = 0x1402, + HCI_RD_LINK_QUAL_CMD_OPCODE = 0x1403, + HCI_RD_RSSI_CMD_OPCODE = 0x1405, + HCI_RD_AFH_CH_MAP_CMD_OPCODE = 0x1406, + HCI_RD_CLK_CMD_OPCODE = 0x1407, + HCI_RD_ENC_KEY_SIZE_CMD_OPCODE = 0x1408, + HCI_GET_MWS_TRANSPORT_LAYER_CONFIG_CMD_OPCODE = 0x140C, + + //Testing Commands + HCI_RD_LOOPBACK_MODE_CMD_OPCODE = 0x1801, + HCI_WR_LOOPBACK_MODE_CMD_OPCODE = 0x1802, + HCI_EN_DUT_MODE_CMD_OPCODE = 0x1803, + HCI_WR_SP_DBG_MODE_CMD_OPCODE = 0x1804, + + /// LE Commands Opcodes + HCI_LE_SET_EVT_MASK_CMD_OPCODE = 0x2001, + HCI_LE_RD_BUFF_SIZE_CMD_OPCODE = 0x2002, + HCI_LE_RD_LOCAL_SUPP_FEATS_CMD_OPCODE = 0x2003, + HCI_LE_SET_RAND_ADDR_CMD_OPCODE = 0x2005, + HCI_LE_SET_ADV_PARAM_CMD_OPCODE = 0x2006, + HCI_LE_RD_ADV_CHNL_TX_PW_CMD_OPCODE = 0x2007, + HCI_LE_SET_ADV_DATA_CMD_OPCODE = 0x2008, + HCI_LE_SET_SCAN_RSP_DATA_CMD_OPCODE = 0x2009, + HCI_LE_SET_ADV_EN_CMD_OPCODE = 0x200A, + HCI_LE_SET_SCAN_PARAM_CMD_OPCODE = 0x200B, + HCI_LE_SET_SCAN_EN_CMD_OPCODE = 0x200C, + HCI_LE_CREATE_CON_CMD_OPCODE = 0x200D, + HCI_LE_CREATE_CON_CANCEL_CMD_OPCODE = 0x200E, + HCI_LE_RD_WLST_SIZE_CMD_OPCODE = 0x200F, + HCI_LE_CLEAR_WLST_CMD_OPCODE = 0x2010, + HCI_LE_ADD_DEV_TO_WLST_CMD_OPCODE = 0x2011, + HCI_LE_RMV_DEV_FROM_WLST_CMD_OPCODE = 0x2012, + HCI_LE_CON_UPDATE_CMD_OPCODE = 0x2013, + HCI_LE_SET_HOST_CH_CLASS_CMD_OPCODE = 0x2014, + HCI_LE_RD_CHNL_MAP_CMD_OPCODE = 0x2015, + HCI_LE_RD_REM_FEATS_CMD_OPCODE = 0x2016, + HCI_LE_ENC_CMD_OPCODE = 0x2017, + HCI_LE_RAND_CMD_OPCODE = 0x2018, + HCI_LE_START_ENC_CMD_OPCODE = 0x2019, + HCI_LE_LTK_REQ_REPLY_CMD_OPCODE = 0x201A, + HCI_LE_LTK_REQ_NEG_REPLY_CMD_OPCODE = 0x201B, + HCI_LE_RD_SUPP_STATES_CMD_OPCODE = 0x201C, + HCI_LE_RX_TEST_CMD_OPCODE = 0x201D, + HCI_LE_TX_TEST_CMD_OPCODE = 0x201E, + HCI_LE_TEST_END_CMD_OPCODE = 0x201F, + HCI_LE_REM_CON_PARAM_REQ_REPLY_CMD_OPCODE = 0x2020, + HCI_LE_REM_CON_PARAM_REQ_NEG_REPLY_CMD_OPCODE = 0x2021, + HCI_LE_SET_DATA_LEN_CMD_OPCODE = 0x2022, + HCI_LE_RD_SUGGTED_DFT_DATA_LEN_CMD_OPCODE = 0x2023, + HCI_LE_WR_SUGGTED_DFT_DATA_LEN_CMD_OPCODE = 0x2024, + HCI_LE_RD_LOC_P256_PUB_KEY_CMD_OPCODE = 0x2025, + HCI_LE_GEN_DHKEY_CMD_OPCODE = 0x2026, + HCI_LE_ADD_DEV_TO_RSLV_LIST_CMD_OPCODE = 0x2027, + HCI_LE_RMV_DEV_FROM_RSLV_LIST_CMD_OPCODE = 0x2028, + HCI_LE_CLEAR_RSLV_LIST_CMD_OPCODE = 0x2029, + HCI_LE_RD_RSLV_LIST_SIZE_CMD_OPCODE = 0x202A, + HCI_LE_RD_PEER_RSLV_ADDR_CMD_OPCODE = 0x202B, + HCI_LE_RD_LOC_RSLV_ADDR_CMD_OPCODE = 0x202C, + HCI_LE_SET_ADDR_RESOL_EN_CMD_OPCODE = 0x202D, + HCI_LE_SET_RSLV_PRIV_ADDR_TO_CMD_OPCODE = 0x202E, + HCI_LE_RD_MAX_DATA_LEN_CMD_OPCODE = 0x202F, + HCI_LE_RD_PHY_CMD_OPCODE = 0x2030, + HCI_LE_SET_DFT_PHY_CMD_OPCODE = 0x2031, + HCI_LE_SET_PHY_CMD_OPCODE = 0x2032, + HCI_LE_ENH_RX_TEST_CMD_OPCODE = 0x2033, + HCI_LE_ENH_TX_TEST_CMD_OPCODE = 0x2034, + HCI_LE_SET_ADV_SET_RAND_ADDR_CMD_OPCODE = 0x2035, + HCI_LE_SET_EXT_ADV_PARAM_CMD_OPCODE = 0x2036, + HCI_LE_SET_EXT_ADV_DATA_CMD_OPCODE = 0x2037, + HCI_LE_SET_EXT_SCAN_RSP_DATA_CMD_OPCODE = 0x2038, + HCI_LE_SET_EXT_ADV_EN_CMD_OPCODE = 0x2039, + HCI_LE_RD_MAX_ADV_DATA_LEN_CMD_OPCODE = 0x203A, + HCI_LE_RD_NB_SUPP_ADV_SETS_CMD_OPCODE = 0x203B, + HCI_LE_RMV_ADV_SET_CMD_OPCODE = 0x203C, + HCI_LE_CLEAR_ADV_SETS_CMD_OPCODE = 0x203D, + HCI_LE_SET_PER_ADV_PARAM_CMD_OPCODE = 0x203E, + HCI_LE_SET_PER_ADV_DATA_CMD_OPCODE = 0x203F, + HCI_LE_SET_PER_ADV_EN_CMD_OPCODE = 0x2040, + HCI_LE_SET_EXT_SCAN_PARAM_CMD_OPCODE = 0x2041, + HCI_LE_SET_EXT_SCAN_EN_CMD_OPCODE = 0x2042, + HCI_LE_EXT_CREATE_CON_CMD_OPCODE = 0x2043, + HCI_LE_PER_ADV_CREATE_SYNC_CMD_OPCODE = 0x2044, + HCI_LE_PER_ADV_CREATE_SYNC_CANCEL_CMD_OPCODE = 0x2045, + HCI_LE_PER_ADV_TERM_SYNC_CMD_OPCODE = 0x2046, + HCI_LE_ADD_DEV_TO_PER_ADV_LIST_CMD_OPCODE = 0x2047, + HCI_LE_RMV_DEV_FROM_PER_ADV_LIST_CMD_OPCODE = 0x2048, + HCI_LE_CLEAR_PER_ADV_LIST_CMD_OPCODE = 0x2049, + HCI_LE_RD_PER_ADV_LIST_SIZE_CMD_OPCODE = 0x204A, + HCI_LE_RD_TX_PWR_CMD_OPCODE = 0x204B, + HCI_LE_RD_RF_PATH_COMP_CMD_OPCODE = 0x204C, + HCI_LE_WR_RF_PATH_COMP_CMD_OPCODE = 0x204D, + HCI_LE_SET_PRIV_MODE_CMD_OPCODE = 0x204E, + HCI_LE_SET_MIN_NUM_USED_CHAN_CMD_OPCODE = 0x204F, + + ///Debug commands - OGF = 0x3F (spec) + HCI_DBG_RD_MEM_CMD_OPCODE = 0xFC01, + HCI_DBG_WR_MEM_CMD_OPCODE = 0xFC02, + HCI_DBG_DEL_PAR_CMD_OPCODE = 0xFC03, + HCI_DBG_ID_FLASH_CMD_OPCODE = 0xFC05, + HCI_DBG_ER_FLASH_CMD_OPCODE = 0xFC06, + HCI_DBG_WR_FLASH_CMD_OPCODE = 0xFC07, + HCI_DBG_RD_FLASH_CMD_OPCODE = 0xFC08, + HCI_DBG_RD_PAR_CMD_OPCODE = 0xFC09, + HCI_DBG_WR_PAR_CMD_OPCODE = 0xFC0A, + HCI_DBG_WLAN_COEX_CMD_OPCODE = 0xFC0B, + HCI_DBG_WLAN_COEXTST_SCEN_CMD_OPCODE = 0xFC0D, + HCI_DBG_BT_SEND_LMP_CMD_OPCODE = 0xFC0E, + HCI_DBG_RD_KE_STATS_CMD_OPCODE = 0xFC10, + HCI_DBG_PLF_RESET_CMD_OPCODE = 0xFC11, + HCI_DBG_RD_MEM_INFO_CMD_OPCODE = 0xFC12, + HCI_DBG_HW_REG_RD_CMD_OPCODE = 0xFC30, + HCI_DBG_HW_REG_WR_CMD_OPCODE = 0xFC31, + HCI_DBG_SET_BD_ADDR_CMD_OPCODE = 0xFC32, + HCI_DBG_SET_TYPE_PUB_CMD_OPCODE = 0xFC33, + HCI_DBG_SET_TYPE_RAND_CMD_OPCODE = 0xFC34, + HCI_DBG_SET_CRC_CMD_OPCODE = 0xFC35, + HCI_DBG_LLCP_DISCARD_CMD_OPCODE = 0xFC36, + HCI_DBG_RESET_RX_CNT_CMD_OPCODE = 0xFC37, + HCI_DBG_RESET_TX_CNT_CMD_OPCODE = 0xFC38, + HCI_DBG_RF_REG_RD_CMD_OPCODE = 0xFC39, + HCI_DBG_RF_REG_WR_CMD_OPCODE = 0xFC3A, + HCI_DBG_SET_TX_PW_CMD_OPCODE = 0xFC3B, + HCI_DBG_RF_SWITCH_CLK_CMD_OPCODE = 0xFC3C, + HCI_DBG_RF_WR_DATA_TX_CMD_OPCODE = 0xFC3D, + HCI_DBG_RF_RD_DATA_RX_CMD_OPCODE = 0xFC3E, + HCI_DBG_RF_CNTL_TX_CMD_OPCODE = 0xFC3F, + HCI_DBG_RF_SYNC_P_CNTL_CMD_OPCODE = 0xFC40, + HCI_TESTER_SET_LE_PARAMS_CMD_OPCODE = 0xFC40, + HCI_DBG_WR_DLE_DFT_VALUE_CMD_OPCODE = 0xFC41, +#if (BLE_EMB_PRESENT) +#if (BLE_TESTER) + HCI_DBG_BLE_TST_LLCP_PT_EN_CMD_OPCODE = 0xFC42, + HCI_DBG_BLE_TST_SEND_LLCP_CMD_OPCODE = 0xFC43, +#endif // (BLE_TESTER) +#if (BLE_AUDIO) + HCI_DBG_AUDIO_CONFIGURE_CMD_OPCODE = 0xFC50, + HCI_DBG_AUDIO_SET_MODE_CMD_OPCODE = 0xFC51, + HCI_DBG_AUDIO_RESET_CMD_OPCODE = 0xFC52, + HCI_DBG_AUDIO_SET_POINTER_CMD_OPCODE = 0xFC53, + HCI_DBG_AUDIO_ALLOCATE_CMD_OPCODE = 0xFC54, + HCI_DBG_AUDIO_GET_VX_CH_CMD_OPCODE = 0xFC55, +#endif +#endif // (BLE_EMB_PRESENT) + + #if (RW_DEBUG && BT_EMB_PRESENT) + HCI_DBG_BT_DISCARD_LMP_EN_CMD_OPCODE = 0xFC44, + #endif //RW_DEBUG && BT_EMB_PRESENT + + HCI_DBG_MWS_COEX_CMD_OPCODE = 0xFC45, + HCI_DBG_MWS_COEXTST_SCEN_CMD_OPCODE = 0xFC46, + + #if CRYPTO_UT + HCI_DBG_TEST_CRYPTO_FUNC_CMD_OPCODE = 0xFC60, + #endif //CRYPTO_UT +}; + +/************************************************************************************** + ************** HCI EVENTS **************** + **************************************************************************************/ + +///Event Codes +enum hci_evt_code +{ + HCI_INQ_CMP_EVT_CODE = 0x01, + HCI_INQ_RES_EVT_CODE = 0x02, + HCI_CON_CMP_EVT_CODE = 0x03, + HCI_CON_REQ_EVT_CODE = 0x04, + HCI_DISC_CMP_EVT_CODE = 0x05, + HCI_AUTH_CMP_EVT_CODE = 0x06, + HCI_REM_NAME_REQ_CMP_EVT_CODE = 0x07, + HCI_ENC_CHG_EVT_CODE = 0x08, + HCI_CHG_CON_LK_CMP_EVT_CODE = 0x09, + HCI_MASTER_LK_CMP_EVT_CODE = 0x0A, + HCI_RD_REM_SUPP_FEATS_CMP_EVT_CODE = 0x0B, + HCI_RD_REM_VER_INFO_CMP_EVT_CODE = 0x0C, + HCI_QOS_SETUP_CMP_EVT_CODE = 0x0D, + HCI_CMD_CMP_EVT_CODE = 0x0E, + HCI_CMD_STATUS_EVT_CODE = 0x0F, + HCI_HW_ERR_EVT_CODE = 0x10, + HCI_FLUSH_OCCURRED_EVT_CODE = 0x11, + HCI_ROLE_CHG_EVT_CODE = 0x12, + HCI_NB_CMP_PKTS_EVT_CODE = 0x13, + HCI_MODE_CHG_EVT_CODE = 0x14, + HCI_RETURN_LINK_KEYS_EVT_CODE = 0x15, + HCI_PIN_CODE_REQ_EVT_CODE = 0x16, + HCI_LK_REQ_EVT_CODE = 0x17, + HCI_LK_NOTIF_EVT_CODE = 0x18, + HCI_DATA_BUF_OVFLW_EVT_CODE = 0x1A, + HCI_MAX_SLOT_CHG_EVT_CODE = 0x1B, + HCI_RD_CLK_OFF_CMP_EVT_CODE = 0x1C, + HCI_CON_PKT_TYPE_CHG_EVT_CODE = 0x1D, + HCI_QOS_VIOL_EVT_CODE = 0x1E, + HCI_PAGE_SCAN_REPET_MODE_CHG_EVT_CODE = 0x20, + HCI_FLOW_SPEC_CMP_EVT_CODE = 0x21, + HCI_INQ_RES_WITH_RSSI_EVT_CODE = 0x22, + HCI_RD_REM_EXT_FEATS_CMP_EVT_CODE = 0x23, + HCI_SYNC_CON_CMP_EVT_CODE = 0x2C, + HCI_SYNC_CON_CHG_EVT_CODE = 0x2D, + HCI_SNIFF_SUB_EVT_CODE = 0x2E, + HCI_EXT_INQ_RES_EVT_CODE = 0x2F, + HCI_ENC_KEY_REFRESH_CMP_EVT_CODE = 0x30, + HCI_IO_CAP_REQ_EVT_CODE = 0x31, + HCI_IO_CAP_RSP_EVT_CODE = 0x32, + HCI_USER_CFM_REQ_EVT_CODE = 0x33, + HCI_USER_PASSKEY_REQ_EVT_CODE = 0x34, + HCI_REM_OOB_DATA_REQ_EVT_CODE = 0x35, + HCI_SP_CMP_EVT_CODE = 0x36, + HCI_LINK_SUPV_TO_CHG_EVT_CODE = 0x38, + HCI_ENH_FLUSH_CMP_EVT_CODE = 0x39, + HCI_USER_PASSKEY_NOTIF_EVT_CODE = 0x3B, + HCI_KEYPRESS_NOTIF_EVT_CODE = 0x3C, + HCI_REM_HOST_SUPP_FEATS_NOTIF_EVT_CODE = 0x3D, + HCI_LE_META_EVT_CODE = 0x3E, + HCI_MAX_EVT_MSK_PAGE_1_CODE = 0x40, + HCI_SYNC_TRAIN_CMP_EVT_CODE = 0x4F, + HCI_SYNC_TRAIN_REC_EVT_CODE = 0x50, + HCI_CON_SLV_BCST_REC_EVT_CODE = 0x51, + HCI_CON_SLV_BCST_TO_EVT_CODE = 0x52, + HCI_TRUNC_PAGE_CMP_EVT_CODE = 0x53, + HCI_SLV_PAGE_RSP_TO_EVT_CODE = 0x54, + HCI_CON_SLV_BCST_CH_MAP_CHG_EVT_CODE = 0x55, + HCI_AUTH_PAYL_TO_EXP_EVT_CODE = 0x57, + HCI_MAX_EVT_MSK_PAGE_2_CODE = 0x58, + HCI_DBG_META_EVT_CODE = 0xFF, + + /// LE Events Subcodes + HCI_LE_CON_CMP_EVT_SUBCODE = 0x01, + HCI_LE_ADV_REPORT_EVT_SUBCODE = 0x02, + HCI_LE_CON_UPDATE_CMP_EVT_SUBCODE = 0x03, + HCI_LE_RD_REM_FEATS_CMP_EVT_SUBCODE = 0x04, + HCI_LE_LTK_REQUEST_EVT_SUBCODE = 0x05, + HCI_LE_REM_CON_PARAM_REQ_EVT_SUBCODE = 0x06, + HCI_LE_DATA_LEN_CHG_EVT_SUBCODE = 0x07, + HCI_LE_RD_LOC_P256_PUB_KEY_CMP_EVT_SUBCODE = 0x08, + HCI_LE_GEN_DHKEY_CMP_EVT_SUBCODE = 0x09, + HCI_LE_ENH_CON_CMP_EVT_SUBCODE = 0x0A, + HCI_LE_DIR_ADV_REP_EVT_SUBCODE = 0x0B, + HCI_LE_PHY_UPD_CMP_EVT_SUBCODE = 0x0C, + HCI_LE_EXT_ADV_REPORT_EVT_SUBCODE = 0x0D, + HCI_LE_PERIODIC_ADV_SYNC_EST_EVT_SUBCODE = 0x0E, + HCI_LE_PERIODIC_ADV_REPORT_EVT_SUBCODE = 0x0F, + HCI_LE_PERIODIC_ADV_SYNC_LOST_EVT_SUBCODE = 0x10, + HCI_LE_SCAN_TIMEOUT_EVT_SUBCODE = 0x11, + HCI_LE_ADV_SET_TERMINATED_EVT_SUBCODE = 0x12, + HCI_LE_SCAN_REQ_RCVD_EVT_SUBCODE = 0x13, + HCI_LE_CH_SEL_ALGO_EVT_SUBCODE = 0x14, + + /// DBG Events Subcodes + #if (BLE_EMB_PRESENT && BLE_TESTER) + HCI_DBG_BLE_TST_LLCP_RECV_EVT_SUBCODE = 0x01, + #endif // (BLE_EMB_PRESENT && BLE_TESTER) + #if (RW_DEBUG) + HCI_DBG_ASSERT_ERR_EVT_SUBCODE = 0x02, + #endif //(RW_DEBUG) +}; + +/// Event mask page enum +enum hci_evt_mask_page +{ + /// page 0 + HCI_PAGE_0, + /// page 1 + HCI_PAGE_1, + /// page 2 + HCI_PAGE_2, + /// Default + HCI_PAGE_DFT, + /// LE event + HCI_PAGE_LE, +}; + +/// HCI ACL data RX packet structure +struct hci_ble_acl_data_rx +{ + /// bits[00:11]: Connection handle + /// bits[12:13]: Packet boundary flag + /// bits[14:15]: Broadcast flag + uint16_t conhdl_pb_bc_flag; + /// length of the data + uint16_t length; + /// Memory Pointer address + uint32_t buf_ptr; + /// Private buffer + void *hcibuffer; +}; + +/// HCI ACL data TX packet structure +struct hci_ble_acl_data_tx +{ + /// bits[00:11]: Connection handle + /// bits[12:13]: Packet boundary flag + /// bits[14:15]: Broadcast flag + uint16_t conhdl_pb_bc_flag; + /// length of the data + uint16_t length; + /// Memory Pointer address + uint32_t buf_ptr; +}; + +#if (BT_EMB_PRESENT) +/// HCI ACL data packet structure +struct hci_bt_acl_data_tx +{ + /// Buffer element + struct bt_em_acl_buf_elt* buf_elt; +}; + +/// HCI ACL data Rx packet structure +struct hci_bt_acl_data_rx +{ + /// EM buffer pointer + uint16_t buf_ptr; + /// Data length + Data Flags (PBF + BF) + uint16_t data_len_flags; +}; + +/// HCI Synchronous data packet structure +struct hci_bt_sync_data_tx +{ + /// Buffer element + struct bt_em_sync_buf_elt* buf_elt; +}; + +/// HCI Synchronous data Rx packet structure +struct hci_bt_sync_data_rx +{ + /// EM buffer pointer + uint16_t buf_ptr; + /// Data length + uint8_t data_len; + /// Packet status flag + uint8_t packet_status_flag; + /// Synchronous link identifier + uint8_t sync_link_id; +}; +#endif // (BT_EMB_PRESENT) + + +/* + * HCI COMMANDS PARAMETERS (to classify) + **************************************************************************************** + */ + +/// HCI basic command structure with connection handle +struct hci_basic_conhdl_cmd +{ + /// connection handle + uint16_t conhdl; +}; + +/// HCI basic command structure with BD address +struct hci_basic_bd_addr_cmd +{ + ///BdAddr + struct bd_addr bd_addr; +}; + +/// HCI Accept connection request command structure +struct hci_accept_con_req_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Page Scan Repetition Mode + uint8_t role; +}; + +/// HCI Accept synchronous connection request command structure +struct hci_accept_sync_con_req_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Transmit bandwidth + uint32_t tx_bw; + ///Receive bandwidth + uint32_t rx_bw; + ///Max latency + uint16_t max_lat; + ///Voice settings + uint16_t vx_set; + ///Retransmission effort + uint8_t retx_eff; + ///Packet type + uint16_t pkt_type ; +}; + +/// HCI Enhanced Accept synchronous connection request command structure +struct hci_enh_accept_sync_con_cmd +{ + + struct bd_addr bd_addr; // BD address + uint32_t tx_bw; // Transmit Bandwidth (in B/sec) + uint32_t rx_bw; // Receive Bandwidth (in B/sec) + uint8_t tx_cod_fmt[5]; // Transmit Coding Format + uint8_t rx_cod_fmt[5]; // Receive Coding Format + uint16_t tx_cod_fr_sz; // Transmit Codec Frame Size (in B) + uint16_t rx_cod_fr_sz; // Receive Codec Frame Size (in B) + uint32_t in_bw; // Input Bandwidth (in B/sec) + uint32_t out_bw; // Output Bandwidth (in B/sec) + uint8_t in_cod_fmt[5]; // Input Coding Format + uint8_t out_cod_fmt[5]; // Output Coding Format + uint16_t in_cod_data_sz; // Input Coded Data Size (in bits) + uint16_t out_cod_data_sz; // Output Coded Data Size (in bits) + uint8_t in_data_fmt; // Input PCM Data Format + uint8_t out_data_fmt; // Output PCM Data Format + uint8_t in_msb_pos; // Input PCM Sample Payload MSB Position (in bits) + uint8_t out_msb_pos; // Output PCM Sample Payload MSB Position (in bits) + uint8_t in_data_path; // Input Data Path + uint8_t out_data_path; // Output Data Path + uint8_t in_tr_unit_sz; // Input Transport Unit Size (in bits) + uint8_t out_tr_unit_sz; // Output Transport Unit Size (in bits) + uint16_t max_lat; // Max Latency (in ms) + uint16_t packet_type; // Packet Type + uint8_t retx_eff; // Retransmission Effort + + +}; + +/// HCI reject connection request command structure +struct hci_reject_con_req_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Reason + uint8_t reason; +}; + +/// HCI reject synchronous connection request command structure +struct hci_reject_sync_con_req_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Reason + uint8_t reason; +}; + +/// HCI link key request reply command structure +struct hci_lk_req_reply_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Key + struct ltk key; +}; + +/// HCI link key request reply command structure +struct hci_pin_code_req_reply_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Pin code length + uint8_t pin_len; + ///Key + struct pin_code pin; +}; + +/// HCI switch role command structure +struct hci_switch_role_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Read all flag + uint8_t role; +}; + +/// HCI flow specification command parameters structure +struct hci_flow_spec_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Flags + uint8_t flags; + ///Flow direction + uint8_t flow_dir; + ///Service type + uint8_t serv_type; + ///Token rate + uint32_t tk_rate; + ///Token buffer size + uint32_t tk_buf_sz; + ///Peak bandwidth + uint32_t pk_bw; + ///Access latency + uint32_t acc_lat; +}; + +/// HCI enhanced flush command parameters structure +struct hci_enh_flush_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Packet Type + uint8_t pkt_type; +}; + +/// HCI command complete event structure for the read auto flush TO command +struct hci_rd_auto_flush_to_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Flush timeout + uint16_t flush_to; +}; + +/// HCI write flush timeout command parameters structure +struct hci_wr_auto_flush_to_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Flush timeout + uint16_t flush_to; +}; + +/// HCI change connection packet type command parameters structure +struct hci_chg_con_pkt_type_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Packet type + uint16_t pkt_type; +}; + +/// HCI read link policy settings command parameters structure +struct hci_rd_link_pol_stg_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Link policy + uint16_t lnk_policy; +}; + +/// HCI read link policy settings command parameters structure +struct hci_wr_link_pol_stg_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Link policy + uint16_t lnk_policy; +}; + +/// HCI sniff mode request command parameters structure +struct hci_sniff_mode_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Sniff max interval + uint16_t max_int; + ///Sniff min interval + uint16_t min_int; + ///Sniff attempt + uint16_t attempt; + ///Sniff timeout + uint16_t timeout; +}; + +/// HCI sniff subrating mode request command parameters structure +struct hci_sniff_sub_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Sniff max latency + uint16_t max_lat; + ///Minimun remote TO + uint16_t min_rem_to; + ///Minimun local TO + uint16_t min_loc_to; +}; + +/// HCI role discovery complete event parameters structure +struct hci_role_discovery_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Role + uint8_t role; + +}; + +/// HCI read failed contact counter command parameters structure +struct hci_rd_fail_contact_cnt_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Fail contact counter + uint16_t fail_cnt; +}; + +/// HCI read link quality complete event parameters structure +struct hci_rd_link_qual_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Quality type + uint8_t quality; +}; + +/// HCI read afh channel map complete event parameters structure +struct hci_rd_afh_ch_map_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + /// AFH mode + uint8_t afh_mode; + /// AFH channel map + struct chnl_map afh_map; +}; + +/// HCI read lmp handle complete event parameters structure +struct hci_rd_lmp_hdl_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///lmp handle + uint8_t lmp_hdl; + ///rsvd + uint32_t rsvd; +}; + +/// HCI read remote extended features command parameters structure +struct hci_rd_rem_ext_feats_cmd +{ + ///Connection handle + uint16_t conhdl; + ///page number + uint8_t pg_nb; +}; + +/// HCI read encryption key size complete event parameters structure +struct hci_rd_enc_key_size_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Key size + uint8_t key_sz; +}; + +/// HCI read enhanced transmit power command parameters structure +struct hci_rd_enh_tx_pwr_lvl_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Type + uint8_t type; +}; + +/// HCI read enhanced transmit power complete event parameters structure +struct hci_rd_enh_tx_pwr_lvl_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Transmit power GFSK + uint8_t pw_gfsk; + ///Transmit power DQPSK + uint8_t pw_dqpsk; + ///Transmit power 8DPSK + uint8_t pw_8dpsk; +}; + + +/* + * HCI LINK CONTROL COMMANDS PARAMETERS + **************************************************************************************** + */ + +/// Format of the message of the Group: LINK_CONTROL_COMMANDS +/// HCI Inquiry command parameters structure +struct hci_inq_cmd +{ + ///Lap + struct lap lap; + ///Inquiry Length + uint8_t inq_len; + ///Number of response + uint8_t nb_rsp; +}; +struct hci_per_inq_mode_cmd +{ + ///Maximum period length + uint16_t max_per_len; + ///Minimum period length + uint16_t min_per_len; + ///lap + struct lap lap; + ///Inquiry length + uint8_t inq_len; + ///Number of response + uint8_t nb_rsp; +}; +struct hci_create_con_cmd +{ + /// BdAddr + struct bd_addr bd_addr; + /// Packet Type + uint16_t pkt_type; + /// Page Scan Repetition Mode + uint8_t page_scan_rep_mode; + /// Reserved + uint8_t rsvd; + /** + * Clock Offset + * + * Bits 14-0 : Bits 16-2 of CLKNslave-CLK + * Bit 15 : Clock_Offset_Valid_Flag + * Invalid Clock Offset = 0 + * Valid Clock Offset = 1 + */ + uint16_t clk_off; + /// Allow Switch + uint8_t switch_en; +}; + +/// HCI disconnect command structure +struct hci_disconnect_cmd +{ + /// connection handle + uint16_t conhdl; + /// reason + uint8_t reason; +}; + +/// HCI master link key command structure +struct hci_master_lk_cmd +{ + ///Key flag + uint8_t key_flag; +}; + +/// HCI authentication request command parameters structure +struct hci_set_con_enc_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Encryption mode + uint8_t enc_en; +}; + +struct hci_rem_name_req_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Page Scan Repetition Mode + uint8_t page_scan_rep_mode; + ///Reserved + uint8_t rsvd; + /** + * Clock Offset + * + * Bits 14-0 : Bits 16-2 of CLKNslave-CLK + * Bit 15 : Clock_Offset_Valid_Flag + * Invalid Clock Offset = 0 + * Valid Clock Offset = 1 + */ + uint16_t clk_off; +}; + +/// HCI remote name request complete event structure +struct hci_rem_name_req_cmp_evt +{ + /// Status + uint8_t status; + /// BD Addr + struct bd_addr bd_addr; + /// Name + struct device_name name; +}; + +/// HCI setup synchronous connection command structure +struct hci_setup_sync_con_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Transmit bandwidth + uint32_t tx_bw; + ///Receive bandwidth + uint32_t rx_bw; + ///Max latency + uint16_t max_lat; + ///Voice setting + uint16_t vx_set; + ///Retransmission effort + uint8_t retx_eff; + ///Packet type + uint16_t pkt_type; +}; + +/// HCI setup synchronous connection command structure +struct hci_enh_setup_sync_con_cmd +{ + uint16_t conhdl; // Connection Handle + uint32_t tx_bw; // Transmit Bandwidth (in B/sec) + uint32_t rx_bw; // Receive Bandwidth (in B/sec) + uint8_t tx_cod_fmt[5]; // Transmit Coding Format + uint8_t rx_cod_fmt[5]; // Receive Coding Format + uint16_t tx_cod_fr_sz; // Transmit Codec Frame Size (in B) + uint16_t rx_cod_fr_sz; // Receive Codec Frame Size (in B) + uint32_t in_bw; // Input Bandwidth (in B/sec) + uint32_t out_bw; // Output Bandwidth (in B/sec) + uint8_t in_cod_fmt[5]; // Input Coding Format + uint8_t out_cod_fmt[5]; // Output Coding Format + uint16_t in_cod_data_sz; // Input Coded Data Size (in bits) + uint16_t out_cod_data_sz; // Output Coded Data Size (in bits) + uint8_t in_data_fmt; // Input PCM Data Format + uint8_t out_data_fmt; // Output PCM Data Format + uint8_t in_msb_pos; // Input PCM Sample Payload MSB Position (in bits) + uint8_t out_msb_pos; // Output PCM Sample Payload MSB Position (in bits) + uint8_t in_data_path; // Input Data Path + uint8_t out_data_path; // Output Data Path + uint8_t in_tr_unit_sz; // Input Transport Unit Size (in bits) + uint8_t out_tr_unit_sz; // Output Transport Unit Size (in bits) + uint16_t max_lat; // Max Latency (in ms) + uint16_t packet_type; // Packet Type + uint8_t retx_eff; // Retransmission Effort +}; + +/// HCI io capability request reply command structure +struct hci_io_cap_req_reply_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///IO capability + uint8_t io_capa; + ///OOB data present + uint8_t oob_data_pres; + ///Authentication requirements + uint8_t auth_req; + +}; + +/// HCI io capability request negative reply command structure +struct hci_io_cap_req_neg_reply_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Reason + uint8_t reason; +}; + +/// HCI user pass key request reply command structure +struct hci_user_passkey_req_reply_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Numeric value + uint32_t num_val; +}; + +/// HCI remote oob data request reply command structure +struct hci_rem_oob_data_req_reply_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///hash part + struct hash oob_c; + ///random part + struct randomizer oob_r; +}; + +/// HCI send key press notification command structure +struct hci_send_keypress_notif_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Notification type + uint8_t notif_type; +}; + +/// HCI truncated page command structure +struct hci_trunc_page_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + /// Page Scan Repetition Mode + uint8_t page_scan_rep_mode; + /** + * Clock Offset + * + * Bits 14-0 : Bits 16-2 of CLKNslave-CLK + * Bit 15 : Clock_Offset_Valid_Flag + * Invalid Clock Offset = 0 + * Valid Clock Offset = 1 + */ + uint16_t clk_off; +}; + +/// HCI truncated page cancel command structure +struct hci_trunc_page_can_cmd +{ + ///BdAddr + struct bd_addr bd_addr; +}; + +/// HCI set connectionless slave broadcast command structure +struct hci_set_con_slv_bcst_cmd +{ + /// Enable + uint8_t enable; + /// LT_ADDR + uint8_t lt_addr; + /// LPO_Allowed + uint8_t lpo_allowed; + /// Packet_Type + uint16_t packet_type; + /// Interval_Min (in slots) + uint16_t interval_min; + /// Interval_Max (in slots) + uint16_t interval_max; + /// CSB_supervisionTO (in slots) + uint16_t csb_supv_to; +}; + +/// HCI set connectionless slave broadcast command complete event structure +struct hci_set_con_slv_bcst_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// LT_ADDR + uint8_t lt_addr; + /// Interval (in slots) + uint16_t interval; +}; + +/// HCI set connectionless slave broadcast receive command structure +struct hci_set_con_slv_bcst_rec_cmd +{ + /// Enable + uint8_t enable; + /// BD_ADDR + struct bd_addr bd_addr; + /// LT_ADDR + uint8_t lt_addr; + /// Interval (in slots) + uint16_t interval; + /// Clock_Offset (28 bits) - (CLKNslave � CLK) modulo 2^28 + uint32_t clock_offset; + /// Next_Connectionless_Slave_Broadcast_Clock (28 bits) + uint32_t next_csb_clock; + /// CSB_supervisionTO (in slots) + uint16_t csb_supv_to; + /// Remote_Timing_Accuracy (in ppm) + uint8_t remote_timing_accuracy; + /// Skip + uint8_t skip; + /// Packet_Type + uint16_t packet_type; + /// AFH_Channel_Map + struct chnl_map afh_ch_map; +}; + +/// HCI set connectionless slave broadcast receive command complete event structure +struct hci_set_con_slv_bcst_rec_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// BD_ADDR + struct bd_addr bd_addr; + /// LT_ADDR + uint8_t lt_addr; +}; + +/// HCI Receive Synchronization Train command structure +struct hci_rec_sync_train_cmd +{ + /// BD_ADDR + struct bd_addr bd_addr; + /// Synchronization_scanTO (in slots) + uint16_t sync_scan_to; + /// Sync_Scan_Window (in slots) + uint16_t sync_scan_win; + /// Sync_Scan_Interval (in slots) + uint16_t sync_scan_int; +}; + +/// HCI remote oob extended data request reply command structure +struct hci_rem_oob_ext_data_req_reply_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///hash part + struct hash oob_c_192; + ///random part + struct randomizer oob_r_192; + ///hash part + struct hash oob_c_256; + ///random part + struct randomizer oob_r_256; +}; + + +struct hci_le_generate_dh_key_cmd +{ + uint8_t public_key[64]; +}; +/* + * HCI LINK POLICY COMMANDS PARAMETERS + **************************************************************************************** + */ + +/// HCI setup quality of service command structure +struct hci_qos_setup_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Flags + uint8_t flags; + ///Service type + uint8_t serv_type; + ///Token rate + uint32_t tok_rate; + ///Peak bandwidth + uint32_t pk_bw; + ///Latency + uint32_t lat; + ///Delay variation + uint32_t del_var; +}; + +/// HCI command complete event structure for read default link policy command structure +struct hci_rd_dft_link_pol_stg_cmd_cmp_evt +{ + ///Status of the command reception + uint8_t status; + ///Link policy + uint16_t link_pol_stg; +}; + +struct hci_wr_dft_link_pol_stg_cmd +{ + ///Link policy + uint16_t link_pol_stg; +}; + +/* + * HCI CONTROL & BASEBAND COMMANDS PARAMETERS + **************************************************************************************** + */ + +/// HCI set event mask command structure +struct hci_set_evt_mask_cmd +{ + ///Event Mask + struct evt_mask event_mask; +}; + +/// HCI set event filter command structure +struct hci_set_evt_filter_cmd +{ + /// Filter type + uint8_t filter_type; + + /// Filters + union hci_filter + { + uint8_t clear_all_filter_reserved; + + /// Inquiry Result Filter + struct inq_res_filter + { + /// Filter Condition type + uint8_t cond_type; + + /// Filter conditions + union hci_inq_filter_cond + { + /// Reserved value (Inquiry Result Filter - condition type 0x00 has no condition) + uint8_t cond_0_reserved; + + /// Inquiry Result Filter Condition - condition type 0x01 + struct inq_res_filter_cond_1 + { + /// Class_of_Device + struct devclass class_of_dev; + /// Class_of_Device_Mask + struct devclass class_of_dev_msk; + } cond_1; + + /// Inquiry Result Filter Condition - condition type 0x02 + struct inq_res_filter_cond_2 + { + /// BD Address + struct bd_addr bd_addr; + } cond_2; + } cond; + } inq_res; + + /// Connection Setup Filter + struct con_set_filter + { + /// Filter Condition type + uint8_t cond_type; + + /// Filter conditions + union hci_con_filter_cond + { + /// Connection Setup Filter Condition - condition type 0x00 + struct con_set_filter_cond_0 + { + /// Auto_Accept_Flag + uint8_t auto_accept; + } cond_0; + + /// Connection Setup Filter Condition - condition type 0x01 + struct con_set_filter_cond_1 + { + /// Class_of_Device + struct devclass class_of_dev; + /// Class_of_Device_Mask + struct devclass class_of_dev_msk; + /// Auto_Accept_Flag + uint8_t auto_accept; + } cond_1; + + /// Connection Setup Filter Condition - condition type 0x02 + struct con_set_filter_cond_2 + { + /// BD Address + struct bd_addr bd_addr; + /// Auto_Accept_Flag + uint8_t auto_accept; + } cond_2; + } cond; + + } con_set; + + } filter; +}; + +/// HCI command completed event structure for the flush command +struct hci_flush_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; +}; + +/// HCI command complete event structure for the Read pin type command +struct hci_rd_pin_type_cmd_cmp_evt +{ + ///Status of the command + uint8_t status; + ///PIN type + uint8_t pin_type; +}; + +struct hci_wr_pin_type_cmd +{ + ///PIN type + uint8_t pin_type; +}; + +struct hci_rd_stored_lk_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Read all flag + uint8_t rd_all_flag; +}; + +/// HCI command complete event structure for read stored link key command +struct hci_rd_stored_lk_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Maximum number of key + uint16_t num_key_max; + ///Read number of key + uint16_t num_key_rd; +}; + +#if BT_EMB_PRESENT +struct hci_wr_stored_lk_cmd +{ + /// Number of key to write + uint8_t num_key_wr; + + /// BD Address + Key table + struct bd_addr_plus_key link_keys[HCI_MAX_CMD_PARAM_SIZE / sizeof(struct bd_addr_plus_key)]; +}; +#endif //BT_EMB_PRESENT + +/// HCI command complete event structure for write stored link key command +struct hci_wr_stored_lk_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///number of key written + uint8_t num_key_wr; +}; + +struct hci_del_stored_lk_cmd +{ + ///BdAddr + struct bd_addr bd_addr; + ///Delete all flag + uint8_t del_all_flag; +}; + +/// HCI command complete event structure for delete stored link key command +struct hci_del_stored_lk_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Read number of key + uint16_t num_key_del; +}; + +struct hci_wr_local_name_cmd +{ + ///Name + struct device_name name; +}; + +/// HCI command complete event structure for the read local name command +struct hci_rd_local_name_cmd_cmp_evt +{ + ///Status of the command + uint8_t status; + ///Name + uint8_t name[BD_NAME_SIZE]; +}; + +/// HCI command complete event structure for the Read connection accept to command +struct hci_rd_con_accept_to_cmd_cmp_evt +{ + ///Status of the command + uint8_t status; + /// Connection accept timeout (in slots) + uint16_t con_acc_to; +}; + +struct hci_wr_con_accept_to_cmd +{ + /// Connection accept timeout (in slots) + uint16_t con_acc_to; +}; + +/// HCI command complete event structure for the Read page to command +struct hci_rd_page_to_cmd_cmp_evt +{ + ///Status of the command + uint8_t status; + /// Page timeout (in slots) + uint16_t page_to; +}; + +struct hci_wr_page_to_cmd +{ + /// Page timeout (in slots) + uint16_t page_to; +}; + +/// HCI command complete event structure for the Read scan enable command +struct hci_rd_scan_en_cmd_cmp_evt +{ + ///Status of the command + uint8_t status; + ///Status of the scan enable + uint8_t scan_en; +}; + +struct hci_wr_scan_en_cmd +{ + ///Status of the scan enable + uint8_t scan_en; +}; + +/// HCI command complete event structure for the Read scan activity command +struct hci_rd_page_scan_act_cmd_cmp_evt +{ + ///Status of the command + uint8_t status; + /// Page scan interval (in slots) + uint16_t page_scan_intv; + /// Page scan window (in slots) + uint16_t page_scan_win; +}; + +struct hci_wr_page_scan_act_cmd +{ + /// Page scan interval (in slots) + uint16_t page_scan_intv; + /// Page scan window (in slots) + uint16_t page_scan_win; +}; + +/// HCI command complete event structure for the Read inquiry scan activity command +struct hci_rd_inq_scan_act_cmd_cmp_evt +{ + /// Status of the command + uint8_t status; + /// Inquiry scan interval (in slots) + uint16_t inq_scan_intv; + /// Inquiry scan window (in slots) + uint16_t inq_scan_win; +}; + +struct hci_wr_inq_scan_act_cmd +{ + /// Inquiry scan interval (in slots) + uint16_t inq_scan_intv; + /// Inquiry scan window (in slots) + uint16_t inq_scan_win; +}; + +/// HCI command complete event structure for the Read authentication command +struct hci_rd_auth_en_cmd_cmp_evt +{ + ///Status of the command + uint8_t status; + ///Value of the authentication + uint8_t auth_en; +}; + +struct hci_wr_auth_en_cmd +{ + ///Value of the authentication + uint8_t auth_en; +}; + +/// HCI command complete event structure for the read class of device command +struct hci_rd_class_of_dev_cmd_cmp_evt +{ + ///Status of the command + uint8_t status; + ///Class of device + struct devclass class_of_dev; +}; + +struct hci_wr_class_of_dev_cmd +{ + ///Class of device + struct devclass class_of_dev; +}; + +/// HCI read voice settings complete event +struct hci_rd_voice_stg_cmd_cmp_evt +{ + ///Status of the command reception + uint8_t status; + /// Voice setting + uint16_t voice_stg; +}; + +struct hci_wr_voice_stg_cmd +{ + /// voice setting + uint16_t voice_stg; +}; + +/// HCI command complete event structure for read number of broadcast retrans command +struct hci_rd_nb_bdcst_retx_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Read number of broadcast retransmission + uint8_t num_bcst_ret; +}; + +struct hci_wr_nb_bdcst_retx_cmd +{ + ///Read number of broadcast retransmission + uint8_t num_bcst_ret; +}; + +/// HCI command complete event structure for the Read Synchronous Flow Control command +struct hci_rd_sync_flow_ctrl_en_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Synchronous flow control enable + uint8_t sync_flow_ctrl_en; +}; + +struct hci_wr_sync_flow_ctrl_en_cmd +{ + /// Synchronous Flow Control enable + uint8_t sync_flow_ctrl_en; +}; + +///HCI set controller to host flow control command +struct hci_set_ctrl_to_host_flow_ctrl_cmd +{ + ///Flow control enable for controller + uint8_t flow_cntl; +}; + +///HCI host buffer size command +struct hci_host_buf_size_cmd +{ + ///Host ACL packet length + uint16_t acl_pkt_len; + ///Host synchronous packet length + uint8_t sync_pkt_len; + ///Host Total number of ACL packets allowed + uint16_t nb_acl_pkts; + ///Host total number of synchronous packets allowed + uint16_t nb_sync_pkts; +}; + +#if BT_EMB_PRESENT +///HCI host number of completed packets command +struct hci_host_nb_cmp_pkts_cmd +{ + ///Number of handles for which the completed packets number is given + uint8_t nb_of_hdl; + ///Array of connection handles + uint16_t con_hdl[MAX_NB_ACTIVE_ACL]; + ///Array of number of completed packets values for connection handles. + uint16_t nb_comp_pkt[MAX_NB_ACTIVE_ACL]; +}; +#elif BLE_EMB_PRESENT || BLE_HOST_PRESENT +///HCI host number of completed packets command +struct hci_host_nb_cmp_pkts_cmd +{ + ///Number of handles for which the completed packets number is given + uint8_t nb_of_hdl; + ///Array of connection handles + uint16_t con_hdl[BLE_CONNECTION_MAX+1]; // ensure that at least 1 element is present + ///Array of number of completed packets values for connection handles. + uint16_t nb_comp_pkt[BLE_CONNECTION_MAX+1]; // ensure that at least 1 element is present +}; +#endif //BLE_EMB_PRESENT || BLE_HOST_PRESENT + +/// HCI read link supervision timeout command parameters structure +struct hci_rd_link_supv_to_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Link supervision timeout + uint16_t lsto_val; +}; + +/// HCI write link supervision timeout command parameters structure +struct hci_wr_link_supv_to_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Link supervision timeout + uint16_t lsto_val; +}; + +/// HCI command complete event structure for the nb of supported IAC command +struct hci_rd_nb_supp_iac_cmd_cmp_evt +{ + ///Status of the command + uint8_t status; + ///nb_of iac + uint8_t nb_iac; +}; + +/// HCI command complete event structure for read current IAC LAP command +struct hci_rd_curr_iac_lap_cmd_cmp_evt +{ + ///Status of the command + uint8_t status; + ///nb of current iac + uint8_t nb_curr_iac; + ///lap + struct lap iac_lap; +}; + +/// HCI write current IAC LAP command structure +struct hci_wr_curr_iac_lap_cmd +{ + /// Number of current iac laps + uint8_t nb_curr_iac; + ///lap + struct lap iac_lap[(HCI_MAX_CMD_PARAM_SIZE / BD_ADDR_LAP_LEN) - 1]; +}; + +struct hci_set_afh_host_ch_class_cmd +{ + ///AFH channel map + struct chnl_map afh_ch; +}; + +/// HCI command complete event structure for write inquiry scan type command structure +struct hci_rd_inq_scan_type_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + /// Inquiry scan type + uint8_t inq_scan_type; +}; + +struct hci_wr_inq_scan_type_cmd +{ + /// Inquiry scan type + uint8_t inq_scan_type; +}; + +/// HCI command complete event structure for read inquiry mode command structure +struct hci_rd_inq_mode_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + /// Inquiry mode + uint8_t inq_mode; +}; + +struct hci_wr_inq_mode_cmd +{ + /// Inquiry mode + uint8_t inq_mode; +}; + +/// HCI command complete event structure for write page scan type command structure +struct hci_rd_page_scan_type_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + /// Page scan type + uint8_t page_scan_type; +}; + +struct hci_wr_page_scan_type_cmd +{ + /// Page scan type + uint8_t page_scan_type; +}; + +/// HCI command complete event structure for read assessment mode command structure +struct hci_rd_afh_ch_assess_mode_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///AFH channel assessment mode + uint8_t afh_ch_ass_mode; +}; + +struct hci_wr_afh_ch_assess_mode_cmd +{ + ///AFH channel assessment mode + uint8_t afh_ch_ass_mode; +}; + +/// HCI command complete event structure for remote name request cancel command +struct hci_rd_ext_inq_rsp_cmd_cmp_evt +{ + ///status + uint8_t status; + ///FEC required + uint8_t fec_req; + ///Extended inquiry response + struct eir eir; +}; + +struct hci_wr_ext_inq_rsp_cmd +{ + ///FEC required + uint8_t fec_req; + ///Extended inquiry response + struct eir eir; +}; + +/// HCI command complete event structure for remote name request cancel command +struct hci_rd_sp_mode_cmd_cmp_evt +{ + ///status + uint8_t status; + ///Simple pairing mode + uint8_t sp_mode; +}; + +struct hci_wr_sp_mode_cmd +{ + ///Simple pairing mode + uint8_t sp_mode; +}; + +/// HCI command complete event structure for read oob data command +struct hci_rd_loc_oob_data_cmd_cmp_evt +{ + ///status + uint8_t status; + ///hash part + struct hash oob_c; + ///random part + struct randomizer oob_r; +}; + +/// HCI command complete event structure for read inquiry response transmit power command +struct hci_rd_inq_rsp_tx_pwr_lvl_cmd_cmp_evt +{ + ///status + uint8_t status; + ///TX power + uint8_t tx_pwr; +}; + +struct hci_wr_inq_tx_pwr_lvl_cmd +{ + ///TX power + int8_t tx_pwr; +}; + +/// HCI command complete event structure for read erroneous data reporting command +struct hci_rd_dft_err_data_rep_cmd_cmp_evt +{ + ///status + uint8_t status; + ///Erroneous data reporting + uint8_t err_data_rep; +}; + +struct hci_wr_dft_err_data_rep_cmd +{ + ///Erroneous data reporting + uint8_t err_data_rep; +}; + +/// HCI read LE Host Supported complete event +struct hci_rd_le_host_supp_cmd_cmp_evt +{ + ///Status + uint8_t status; + ///LE_Supported_Host + uint8_t le_supported_host; + ///Simultaneous_LE_Host + uint8_t simultaneous_le_host; +}; + +/// HCI write LE Host Supported command +struct hci_wr_le_host_supp_cmd +{ + ///LE_Supported_Host + uint8_t le_supported_host; + ///Simultaneous_LE_Host + uint8_t simultaneous_le_host; +}; + +/// HCI Set MWS Channel Parameters command +struct hci_set_mws_channel_params_cmd +{ + ///MWS_Channel_Enable + uint8_t mws_channel_enable; + ///MWS_RX_Center_Frequency + uint16_t mws_rx_center_frequency; + ///MWS_TX_Center_Frequency + uint16_t mws_tx_center_frequency; + ///MWS_RX_Channel_Bandwidth + uint16_t mws_rx_channel_bandwidth; + ///MWS_TX_Channel_Bandwidth + uint16_t mws_tx_channel_bandwidth; + ///MWS_Channel_Type + uint8_t mws_channel_type; +}; + +/// HCI Set External Frame Configuration command +struct hci_set_external_frame_config_cmd +{ + /// Ext_Frame_Duration + uint16_t ext_fr_duration; + /// Ext_Frame_Sync_Assert_Offset + int16_t ext_fr_sync_assert_offset; + /// Ext_Frame_Sync_Assert_Jitter + uint16_t ext_fr_sync_assert_jitter; + /// Ext_Frame_Num_Periods + uint8_t ext_fr_num_periods; + /// Period_Duration[i] + uint16_t period_duration[__ARRAY_EMPTY]; + /// Period_Type[i] + //uint8_t period_type[__ARRAY_EMPTY]; +}; + +/// HCI Set MWS Signaling command +struct hci_set_mws_signaling_cmd +{ + ///MWS_RX_Assert_Offset + int16_t mws_rx_assert_offset; + ///MWS_RX_Assert_Jitter + uint16_t mws_rx_assert_jitter; + ///MWS_RX_Deassert_Offset + int16_t mws_rx_deassert_offset; + ///MWS_RX_Deassert_Jitter + uint16_t mws_rx_deassert_jitter; + ///MWS_TX_Assert_Offset + int16_t mws_tx_assert_offset; + ///MWS_TX_Assert_Jitter + uint16_t mws_tx_assert_jitter; + ///MWS_TX_Deassert_Offset + int16_t mws_tx_deassert_offset; + ///MWS_TX_Deassert_Jitter + uint16_t mws_tx_deassert_jitter; + ///MWS_Pattern_Assert_Offset + int16_t mws_pattern_assert_offset; + ///MWS_Pattern_Assert_Jitter + uint16_t mws_pattern_assert_jitter; + ///MWS_Inactivity_Duration_Assert_Offset + int16_t mws_inactivity_duration_assert_offset; + ///MWS_Inactivity_Duration_Assert_Jitter + uint16_t mws_inactivity_duration_assert_jitter; + ///MWS_Scan_Frequency_Assert_Offset + int16_t mws_scan_frequency_assert_offset; + ///MWS_Scan_Frequency_Assert_Jitter + uint16_t mws_scan_frequency_assert_jitter; + ///MWS_Priority_Assert_Offset_Request + uint16_t mws_priority_assert_offset_request; +}; + +/// HCI Set MWS Signaling command complete event +struct hci_set_mws_signaling_cmd_cmp_evt +{ + ///Status + uint8_t status; + ///Bluetooth_Rx_Priority_Assert_Offset + int16_t bt_rx_prio_assert_offset; + ///Bluetooth_Rx_Priority_Assert_Jitter + uint16_t bt_rx_prio_assert_jitter; + ///Bluetooth_Rx_Priority_Deassert_Offset + int16_t bt_rx_prio_deassert_offset; + ///Bluetooth_Rx_Priority_Deassert_Jitter + uint16_t bt_rx_prio_deassert_jitter; + ///802_Rx_Priority_Assert_Offset + int16_t _802_rx_prio_assert_offset; + ///802_Rx_Priority_Assert_Jitter + uint16_t _802_rx_prio_assert_jitter; + ///802_Rx_Priority_Deassert_Offset + int16_t _802_rx_prio_deasssert_offset; + ///802_Rx_Priority_Deassert_Jitter + uint16_t _802_rx_prio_deassert_jitter; + ///Bluetooth_Tx_On_Assert_Offset + int16_t bt_tx_on_assert_offset; + ///Bluetooth_Tx_On_Assert_Jitter + uint16_t bt_tx_on_assert_jitter; + ///Bluetooth_Tx_On_Deassert_Offset + int16_t bt_tx_on_deassert_offset; + ///Bluetooth_Tx_On_Deassert_Jitter + uint16_t bt_tx_on_deassert_jitter; + ///802_Tx_On_Assert_Offset + int16_t _802_tx_on_assert_offset; + ///802_Tx_On_Assert_Jitter + uint16_t _802_tx_on_assert_jitter; + ///802_Tx_On_Deassert_Offset + int16_t _802_tx_on_deassert_offset; + ///802_Tx_On_Deassert_Jitter + uint16_t _802_tx_on_deassert_jitter; +}; + +/// HCI Set MWS Transport Layer command +struct hci_set_mws_transport_layer_cmd +{ + ///Transport_Layer + uint8_t transport_layer; + ///To_MWS_Baud_Rate + uint32_t to_mws_baud_rate; + ///From_MWS_Baud_Rate + uint32_t from_mws_baud_rate; +}; + +/// HCI Set MWS Scan Frequency Table command +struct hci_set_mws_scan_freq_table_cmd +{ + ///Num_Scan_Frequencies + uint8_t num_scan_frequencies; + ///Scan_Frequency_Low[i] + uint16_t scan_frequency_low[1/*__ARRAY_EMPTY*/]; + ///Scan_Frequency_High[i] + uint16_t scan_frequency_high[1/*__ARRAY_EMPTY*/]; +}; + +/// HCI Set MWS Pattern Configuration command +struct hci_set_mws_pattern_config_cmd +{ + ///MWS_PATTERN_Index + uint8_t mws_pattern_index; + ///MWS_PATTERN_NumIntervals + uint8_t mws_pattern_num_intervals; + ///MWS_PATTERN_IntervalDuration[i] + uint16_t mws_pattern_interval_duration[1/*__ARRAY_EMPTY*/]; + ///MWS_PATTERN_IntervalType[i] + uint8_t mws_pattern_interval_type[1/*__ARRAY_EMPTY*/]; +}; + +/// Hci Get MWS Transport Layer Configuration command complete event +struct hci_get_mws_transport_layer_config_cmd_cmp_evt +{ + ///Status + uint8_t status; + ///Num_Transports + uint8_t num_transports; + ///Transport_Layer[i] + uint8_t transport_layer[1/*__ARRAY_EMPTY*/]; + ///Num_Baud_Rates[i] + uint8_t num_baud_rates[1/*__ARRAY_EMPTY*/]; + ///To_MWS_Baud_Rate[k] + uint32_t to_mws_baud_rate[1/*__ARRAY_EMPTY*/]; + ///From_MWS_Baud_Rate[k] + uint32_t from_mws_baud_rate[1/*__ARRAY_EMPTY*/]; +}; + +/// HCI read Secure Connections Host Support complete event +struct hci_rd_sec_con_host_supp_cmd_cmp_evt +{ + ///Status + uint8_t status; + /// Secure Connections Host Support + uint8_t sec_con_host_supp; +}; + +/// HCI write Secure Connections Host Support command +struct hci_wr_sec_con_host_supp_cmd +{ + /// Secure Connections Host Support + uint8_t sec_con_host_supp; +}; + +/// HCI Set Reserved LT_ADDR command +struct hci_set_res_lt_addr_cmd +{ + /// LT_ADDR + uint8_t lt_addr; +}; + +/// HCI Set Reserved LT_ADDR command complete event +struct hci_set_res_lt_addr_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// LT_ADDR + uint8_t lt_addr; +}; + +/// HCI Delete Reserved LT_ADDR command +struct hci_del_res_lt_addr_cmd +{ + /// LT_ADDR + uint8_t lt_addr; +}; + +/// HCI Delete Reserved LT_ADDR command complete event +struct hci_del_res_lt_addr_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// LT_ADDR + uint8_t lt_addr; +}; + +/// HCI Set Connectionless Slave Broadcast Data command +struct hci_set_con_slv_bcst_data_cmd +{ + /// LT_ADDR + uint8_t lt_addr; + /// Fragment + uint8_t fragment; + /// Data_Length (in bytes) + uint8_t data_length; + /// Data + uint8_t data[__ARRAY_EMPTY]; +}; + +/// HCI Set Connectionless Slave Broadcast Data command complete event +struct hci_set_con_slv_bcst_data_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// LT_ADDR + uint8_t lt_addr; +}; + +/// HCI Read Synchronization Train Parameters command complete event +struct hci_rd_sync_train_param_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// Sync_Train_Interval (in slots) + uint16_t sync_train_int; + /// synchronization_trainTO (in slots) + uint32_t sync_train_to; + /// Service_Data + uint8_t service_data; +}; + +/// HCI Write Synchronization Train Parameters command +struct hci_wr_sync_train_param_cmd +{ + /// Interval_Min (in slots) + uint16_t int_min; + /// Interval_Max (in slots) + uint16_t int_max; + /// synchronization_trainTO (in slots) + uint32_t sync_train_to; + /// Service_Data + uint8_t service_data; +}; + +/// HCI Write Synchronization Train Parameters command complete event +struct hci_wr_sync_train_param_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// Sync_Train_Interval (in slots) + uint16_t sync_train_int; +}; + +// HCI Synchronization Train Complete event +struct hci_sync_train_cmp_evt +{ + /// Status + uint8_t status; +}; + +/// HCI read authenticated payload timeout command +struct hci_rd_auth_payl_to_cmd +{ + ///Connection handle + uint16_t conhdl; +}; + +/// HCI command complete event structure for the Read Authenticated Payload Timeout Command +struct hci_rd_auth_payl_to_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Authenticated payload timeout + uint16_t auth_payl_to; +}; + +/// HCI command complete event structure for read oob extended data command +struct hci_rd_loc_oob_ext_data_cmd_cmp_evt +{ + ///status + uint8_t status; + ///hash part + struct hash oob_c_192; + ///random part + struct randomizer oob_r_192; + ///hash part + struct hash oob_c_256; + ///random part + struct randomizer oob_r_256; +}; + +/// HCI read Extended Page Timeout CC event +struct hci_rd_ext_page_to_cmd_cmp_evt +{ + /// Status + uint8_t status; + /** + * Extended Page Timeout measured in Number of Baseband slots. Interval Length = N * 0.625 msec (1 Baseband slot) + * Range for N: 0x0000 (default) - 0xFFFF + * Time Range: 0 - 40.9 Seconds + */ + uint16_t ext_page_to; +}; + +/// HCI write Extended Page Timeout +struct hci_wr_ext_page_to_cmd +{ + /** + * Extended Page Timeout measured in Number of Baseband slots. Interval Length = N * 0.625 msec (1 Baseband slot) + * Range for N: 0x0000 (default) - 0xFFFF + * Time Range: 0 - 40.9 Seconds + */ + uint16_t ext_page_to; +}; + +/// HCI read Extended Inquiry Length CC event +struct hci_rd_ext_inq_len_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// Extended Inquiry Length + uint16_t ext_inq_len; +}; + +/// HCI write Extended Inquiry Length +struct hci_wr_ext_inq_len_cmd +{ + /// Extended Inquiry Length + uint16_t ext_inq_len; +}; + +/* + * HCI INFORMATIONAL PARAMETERS COMMANDS PARAMETERS + **************************************************************************************** + */ + +///HCI command complete event structure for read local version information +struct hci_rd_local_ver_info_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///HCI version number + uint8_t hci_ver; + ///HCI revision number + uint16_t hci_rev; + ///LMP version + uint8_t lmp_ver; + ///manufacturer name + uint16_t manuf_name; + ///LMP Subversion + uint16_t lmp_subver; +}; + +///HCI command complete event structure for read local supported commands +struct hci_rd_local_supp_cmds_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Supported Commands structure + struct supp_cmds local_cmds; +}; + +/// HCI command complete event structure for read local supported features command +struct hci_rd_local_supp_feats_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Local supported features + struct features feats; +}; + +struct hci_rd_local_ext_feats_cmd +{ + ///Page number + uint8_t page_nb; +}; + +/// HCI command complete event structure for read local extended features command +struct hci_rd_local_ext_feats_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Page number + uint8_t page_nb; + ///Maximum page number + uint8_t page_nb_max; + ///Extended LMP features + struct features ext_feats; +}; + +///HCI command complete event structure for the Read Buffer Size Command +struct hci_rd_buff_size_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///ACL data packet length controller can receive from host + uint16_t hc_data_pk_len; + ///Synchronous data packet length controller can receive from host + uint8_t hc_sync_pk_len; + ///Total number of ACL data packets controller can receive from host + uint16_t hc_tot_nb_data_pkts; + ///Total number of synchronous data packets controller can receive from host + uint16_t hc_tot_nb_sync_pkts; +}; + +///HCI command complete event structure for read bd address +struct hci_rd_bd_addr_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///BD address + struct bd_addr local_addr; +}; + +/// HCI command complete event structure for read local supported codecs +struct hci_rd_local_supp_codecs_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + uint8_t nb_supp_codecs; + uint8_t nb_supp_vendor_specific_codecs; + +// ///Supported Codecs structure +// struct supp_codecs local_codecs; +}; + +/* + * HCI STATUS PARAMETERS COMMANDS PARAMETERS + **************************************************************************************** + */ + +/// HCI command complete event structure for read rssi +struct hci_rd_rssi_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///RSSI value + uint8_t rssi; +}; + +struct hci_rd_clk_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Which clock + uint8_t clk_type; +}; + +/// HCI read clock command structure +struct hci_rd_clk_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///clock + uint32_t clk; + ///Accuracy + uint16_t clk_acc; +}; + + +/* + * HCI TESTING COMMANDS PARAMETERS + **************************************************************************************** + */ + +/// HCI command complete event structure for read loop back mode command +struct hci_rd_loopback_mode_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Local supported features + uint8_t lb_mode; +}; + +struct hci_wr_loopback_mode_cmd +{ + ///Local supported features + uint8_t lb_mode; +}; +struct hci_wr_sp_dbg_mode_cmd +{ + ///Simple pairing mode + uint8_t sp_mode; +}; + + +/// * TCI Event subcodes +enum tci_evt_subcode +{ + TCI_LMP_TX_EVENT = 0x22, + TCI_LMP_RX_EVENT = 0x23, + TCI_LC_TX_EVENT = 0x24, + TCI_LC_RX_EVENT = 0x25, + TCI_BB_TX_EVENT = 0x26, + TCI_BB_RX_EVENT = 0x27, + TCI_HW_ERROR_EVENT = 0x28, + TCI_RADIO_EVENT = 0x30, + TCI_INTERRUPT_EVENT = 0x40, +}; + +/// LMP direction +#define TCI_LMP_DIR_TX 0 +#define TCI_LMP_DIR_RX 1 + +/// HCI tci lmp exchange event structure +struct hci_tci_lmp_evt +{ + ///code + uint8_t tci_code; + ///length + uint8_t evt_len; + ///subcode + uint8_t subcode; + ///evt direction + uint8_t direction; + ///lmp evt body + uint8_t body[17]; +}; + +/* + * HCI LE CONTROLLER COMMANDS PARAMETERS + **************************************************************************************** + */ + +///HCI LE Set Event Mask Command parameters structure +struct hci_le_set_evt_mask_cmd +{ + ///LE Event Mask + struct evt_mask le_mask; +}; + +///HCI LE Set Random Address Command parameters structure +struct hci_le_set_rand_addr_cmd +{ + ///Random address to set + struct bd_addr rand_addr; +}; + +///HCI LE Set Advertising Parameters Command parameters structure +struct hci_le_set_adv_param_cmd +{ + ///Minimum interval for advertising + uint16_t adv_intv_min; + ///Maximum interval for advertising + uint16_t adv_intv_max; + ///Advertising type + uint8_t adv_type; + ///Own address type: public=0 / random=1 / rpa_or_pub=2 / rpa_or_rnd=3 + uint8_t own_addr_type; + ///Peer address type: public=0 / random=1 + uint8_t peer_addr_type; + ///Peer Bluetooth device address + struct bd_addr peer_addr; + ///Advertising channel map + uint8_t adv_chnl_map; + ///Advertising filter policy + uint8_t adv_filt_policy; +}; + +///HCI LE Set Advertising Data Command parameters structure +struct hci_le_set_adv_data_cmd +{ + ///Advertising data length + uint8_t adv_data_len; + ///Advertising data - maximum 31 bytes + struct adv_data data; +}; + +///HCI LE Set Scan Response Data Command parameters structure +struct hci_le_set_scan_rsp_data_cmd +{ + ///Scan response data length + uint8_t scan_rsp_data_len; + ///Scan response data - maximum 31 bytes + struct scan_rsp_data data; +}; + +///HCI LE Set Advertise Enable Command parameters structure +struct hci_le_set_adv_en_cmd +{ + ///Advertising enable - 0=disabled, 1=enabled + uint8_t adv_en; +}; + +///HCI LE Set Scan Parameters Command parameters structure +struct hci_le_set_scan_param_cmd +{ + ///Scan type - 0=passive / 1=active + uint8_t scan_type; + ///Scan interval + uint16_t scan_intv; + ///Scan window size + uint16_t scan_window; + ///Own address type - public=0 / random=1 / rpa_or_pub=2 / rpa_or_rnd=3 + uint8_t own_addr_type; + ///Scan filter policy + uint8_t scan_filt_policy; +}; + +///HCI LE Set Scan Enable Command parameters structure +struct hci_le_set_scan_en_cmd +{ + ///Scan enable - 0=disabled, 1=enabled + uint8_t scan_en; + ///Enable for duplicates filtering - 0 =disabled/ 1=enabled + uint8_t filter_duplic_en; +}; + +///HCI LE Create Connection Command parameters structure +struct hci_le_create_con_cmd +{ + ///Scan interval (N * 0.625 ms) + uint16_t scan_intv; + ///Scan window size (N * 0.625 ms) + uint16_t scan_window; + ///Initiator filter policy + uint8_t init_filt_policy; + ///Peer address type - public=0 / random=1 / rpa_or_pub=2 / rpa_or_rnd=3 + uint8_t peer_addr_type; + ///Peer BD address + struct bd_addr peer_addr; + ///Own address type - public=0 / random=1 / rpa_or_pub=2 / rpa_or_rnd=3 + uint8_t own_addr_type; + ///Minimum of connection interval (N * 1.25 ms) + uint16_t con_intv_min; + ///Maximum of connection interval (N * 1.25 ms) + uint16_t con_intv_max; + ///Connection latency + uint16_t con_latency; + ///Link supervision timeout + uint16_t superv_to; + ///Minimum CE length (N * 0.625 ms) + uint16_t ce_len_min; + ///Maximum CE length (N * 0.625 ms) + uint16_t ce_len_max; +}; + +///HCI LE Add Device to White List Command parameters structure +struct hci_le_add_dev_to_wlst_cmd +{ + ///Type of address of the device to be added to the White List - 0=public/1=random + uint8_t dev_addr_type; + ///Address of device to be added to White List + struct bd_addr dev_addr; +}; + +///HCI LE Remove Device from White List Command parameters structure +struct hci_le_rmv_dev_from_wlst_cmd +{ + ///Type of address of the device to be removed from the White List - 0=public/1=random + uint8_t dev_addr_type; + ///Address of device to be removed from White List + struct bd_addr dev_addr; +}; + +///HCI LE Set Extended Scan Paramaters Command parameters structure +struct hci_le_set_ext_scan_param_cmd +{ + ///Own address type public/random/rpa + uint8_t own_addr_type; + ///Scanning filter policy + uint8_t scan_filt_policy; + ///Indicates the PHY(s) on which the advertising packets should be received + uint8_t scan_phys; + ///Paramaters for PHY(s) + struct scan_phy_param + { + ///Scaning Type: passive/active + uint8_t scan_type; + ///Scan interval (slots) + uint16_t scan_intv; + ///Scan window size (slots) + uint16_t scan_window; + } phy[MAX_SCAN_PHYS]; +}; + +///HCI LE Set Extended Scan Enable Command parameters structure +struct hci_le_set_ext_scan_en_cmd +{ + ///Scan enable - 0=disabled, 1=enabled + uint8_t scan_en; + ///Filter duplicates - 0=disabled, 1=enabled, 2=enabled & reset each scan period + uint8_t filter_duplic_en; + ///Scan duration (Time=N*10ms) + uint16_t duration; + ///Scan period (Time=N*1.28sec) + uint16_t period; +}; + +///HCI LE Extended Create Connection Command parameters strucuture +struct hci_le_ext_create_con_cmd +{ + ///Initiator filter policy + uint8_t init_filter_policy; + ///Own address type public/random/rpa + uint8_t own_addr_type; + ///Peer address type public/random/rpa + uint8_t peer_addr_type; + ///Peer address + struct bd_addr peer_addr; + ///Indicates the PHY(s) on which the advertising packets should be received + uint8_t init_phys; + ///Paramaters for PHY(s) + struct init_phy_param + { + ///Scan interval (N * 0.625 ms) + uint16_t scan_interval; + ///Scan window size (N * 0.625 ms) + uint16_t scan_window; + ///Minimum of connection interval (N * 1.25 ms) + uint16_t con_intv_min; + ///Maximum of connection interval (N * 1.25 ms) + uint16_t con_intv_max; + ///Connection latency + uint16_t con_latency; + ///Link supervision timeout + uint16_t superv_to; + ///Minimum CE length (N * 0.625 ms) + uint16_t ce_len_min; + ///Maximum CE length (N * 0.625 ms) + uint16_t ce_len_max; + } phy[MAX_INIT_PHYS]; +}; + +///HCI LE Periodic Advertising Create Sync Command parameters strucutre +struct hci_le_per_adv_create_sync_cmd +{ + ///Filter policy + uint8_t filter_policy; + ///Advertising SID + uint8_t adv_sid; + ///Advertising address type + uint8_t adv_addr_type; + ///Advertiser address + struct bd_addr adv_addr; + ///max Skip after receive + uint16_t skip; + ///Sync timeout (Time=N*10ms) + uint16_t sync_to; +}; + +///HCI LE Periodic Advertising Terminate Sync Command parameters structure +struct hci_le_per_adv_term_sync_cmd +{ + ///Sync handle + uint16_t sync_handle; +}; + +///HCI LE Add Device to Periodic Advertiser List Command parameters structure +struct hci_le_add_dev_to_per_adv_list_cmd +{ + ///Advertiser address type + uint8_t adv_addr_type; + ///Advertiser address + struct bd_addr adv_addr; + ///Advertising SID + uint8_t adv_sid; +}; + +///HCI LE Remove Device from Periodic Advertiser List Command parameters structure +struct hci_le_rmv_dev_from_per_adv_list_cmd +{ + ///Advertiser address type + uint8_t adv_addr_type; + ///Advertiser address + struct bd_addr adv_addr; + ///Advertising SID + uint8_t adv_sid; +}; + +///HCI LE Set Privacy Mode Command parameters structure +struct hci_le_set_priv_mode_cmd +{ + ///Peer identity address type + uint8_t peer_addr_type; + ///Peer identity address + struct bd_addr peer_addr; + ///Privacy mode + uint8_t priv_mode; +}; + +///HCI LE Set Host Channel Classification Command parameters structure +struct hci_le_set_host_ch_class_cmd +{ + ///Channel map + struct le_chnl_map chmap; +}; + + +///HCI LE Receiver Test Command parameters structure +struct hci_le_rx_test_cmd +{ + ///RX frequency for Rx test + uint8_t rx_freq; +}; + +///HCI LE Transmitter Test Command parameters structure +struct hci_le_tx_test_cmd +{ + ///TX frequency for Tx test + uint8_t tx_freq; + ///TX test data length + uint8_t test_data_len; + ///TX test payload type - see enum + uint8_t pk_payload_type; +}; + +///HCI LE Encrypt Command parameters structure +struct hci_le_enc_cmd +{ + ///Long term key structure + struct ltk key; + ///Pointer to buffer with plain data to encrypt - 16 bytes + uint8_t plain_data[16]; +}; + +/// HCI LE Connection Update Command parameters structure +struct hci_le_con_update_cmd +{ + ///Connection Handle + uint16_t conhdl; + ///Minimum of connection interval (units of 1.25 ms) + uint16_t con_intv_min; + ///Maximum of connection interval (units of 1.25 ms) + uint16_t con_intv_max; + ///Connection latency (units of connection event) + uint16_t con_latency; + ///Link supervision timeout (units of 10 ms) + uint16_t superv_to; + ///Minimum of CE length (units of 0.625 ms) + uint16_t ce_len_min; + ///Maximum of CE length (units of 0.625 ms) + uint16_t ce_len_max; +}; + +/// HCI LE Start Encryption Command parameters structure +struct hci_le_start_enc_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Random number - 8B + struct rand_nb nb; + ///Encryption Diversifier + uint16_t enc_div; + ///Long term key + struct ltk ltk; +}; + +/// HCI long term key request reply command parameters structure +struct hci_le_ltk_req_reply_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Long term key + struct ltk ltk; +}; + +/// HCI long term key request negative reply command parameters structure +struct hci_le_ltk_req_neg_reply_cmd +{ + ///Connection handle + uint16_t conhdl; +}; + +/// HCI LE remote connection parameter request reply command parameters structure +struct hci_le_rem_con_param_req_reply_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Interval_Min + uint16_t interval_min; + ///Interval_Max + uint16_t interval_max; + ///Latency + uint16_t latency; + ///Timeout + uint16_t timeout; + ///Minimum_CE_Length + uint16_t min_ce_len; + ///Maximum_CE_Length + uint16_t max_ce_len; +}; + +/// HCI LE remote connection parameter request negative reply command parameters structure +struct hci_le_rem_con_param_req_neg_reply_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Reason + uint8_t reason; +}; + + +/// HCI LE Set Data Length Command parameters structure +struct hci_le_set_data_len_cmd +{ + ///Connection Handle + uint16_t conhdl; + ///Preferred maximum number of payload octets that the local Controller should include + ///in a single Link Layer Data Channel PDU. + uint16_t tx_octets; + ///Preferred maximum number of microseconds that the local Controller should use to transmit + ///a single Link Layer Data Channel PDU + uint16_t tx_time; +}; + +/// HCI LE Read Suggested Default Data Length Command +struct hci_le_wr_suggted_dft_data_len_cmd +{ + ///Suggested value for the Controller's maximum transmitted number of payload octets to be used + uint16_t suggted_max_tx_octets; + ///Suggested value for the Controller's maximum packet transmission time to be used + uint16_t suggted_max_tx_time; +}; + +/// HCI LE Add Device to Resolving List Command +struct hci_le_add_dev_to_rslv_list_cmd +{ + /// Peer Identity Address Type + uint8_t peer_id_addr_type; + /// Peer Identity Address + struct bd_addr peer_id_addr; + /// Peer IRK + struct irk peer_irk; + /// Local IRK + struct irk local_irk; +}; + +/// HCI LE Remove Device From Resolving List Command +struct hci_le_rmv_dev_from_rslv_list_cmd +{ + /// Peer Identity Address Type + uint8_t peer_id_addr_type; + /// Peer Identity Address + struct bd_addr peer_id_addr; +}; + +/// HCI LE Read Peer Resolvable Address Command +struct hci_le_rd_peer_rslv_addr_cmd +{ + /// Peer Identity Address Type + uint8_t peer_id_addr_type; + /// Peer Identity Address + struct bd_addr peer_id_addr; +}; + +/// HCI LE Read Local Resolvable Address Command +struct hci_le_rd_loc_rslv_addr_cmd +{ + /// Peer Identity Address Type + uint8_t peer_id_addr_type; + /// Peer Identity Address + struct bd_addr peer_id_addr; +}; + +/// HCI LE Set Address Resolution Enable Command +struct hci_le_set_addr_resol_en_cmd +{ + /// Address Resolution Enable + uint8_t enable; +}; + +/// HCI LE Set Resolvable Private Address Timeout Command +struct hci_le_set_rslv_priv_addr_to_cmd +{ + /// RPA Timeout + uint16_t rpa_timeout; +}; + +/* + * HCI EVENTS PARAMETERS + **************************************************************************************** + */ + +/// HCI inquiry complete event structure +struct hci_inq_cmp_evt +{ + ///Status of the procedure + uint8_t status; +}; + + +/// HCI Inquiry result event structure (with only 1 result) +struct hci_inq_res_evt +{ + + ///Number of response + uint8_t nb_rsp; + ///BdAddr + struct bd_addr bd_addr; + ///Page Scan Repetition Mode + uint8_t page_scan_rep_mode; + ///Reserved + uint8_t reserved1; + ///Reserved + uint8_t reserved2; + ///class of device + struct devclass class_of_dev; + ///Clock Offset + uint16_t clk_off; + +}; + +/// HCI Inquiry result with rssi event structure (with only 1 result) +struct hci_inq_res_with_rssi_evt +{ + ///Number of response + uint8_t nb_rsp; + ///BdAddr + struct bd_addr bd_addr; + ///Page Scan Repetition Mode + uint8_t page_scan_rep_mode; + ///Reserved + uint8_t reserved1; + ///class of device + struct devclass class_of_dev; + ///Clock Offset + uint16_t clk_off; + ///Rssi + uint8_t rssi; + +}; + +/// HCI Extended inquiry result indication structure (with only 1 result) +struct hci_ext_inq_res_evt +{ + ///Number of response + uint8_t nb_rsp; + ///BdAddr + struct bd_addr bd_addr; + ///Page Scan Repetition Mode + uint8_t page_scan_rep_mode; + ///Reserved + uint8_t reserved1; + ///class of device + struct devclass class_of_dev; + ///Clock Offset + uint16_t clk_off; + ///RSSi + uint8_t rssi; + ///Extended inquiry response data + struct eir eir; +}; + +/// HCI disconnect complete event structure +struct hci_disc_cmp_evt +{ + ///Status of received command + uint8_t status; + ///Connection Handle + uint16_t conhdl; + ///Reason for disconnection + uint8_t reason; +}; + +/// HCI basic command complete event structure +struct hci_basic_cmd_cmp_evt +{ + ///Status of the command reception + uint8_t status; +}; + +/// HCI basic command complete event structure with connection handle +struct hci_basic_conhdl_cmd_cmp_evt +{ + /// status + uint8_t status; + /// connection handle + uint16_t conhdl; +}; + +/// HCI basic command complete event structure with BD address +struct hci_basic_bd_addr_cmd_cmp_evt +{ + ///status + uint8_t status; + ///BdAddr + struct bd_addr bd_addr; +}; + +/// HCI basic event structure with status and BD address +struct hci_basic_stat_bd_addr_evt +{ + ///status + uint8_t status; + ///BdAddr + struct bd_addr bd_addr; +}; + +/// HCI basic event including a connection handle as parameter +struct hci_basic_conhdl_evt +{ + ///Connection handle + uint16_t conhdl; +}; + +/// HCI complete event with status only. +struct hci_cmd_stat_event +{ + /// Status of the command reception + uint8_t status; +}; + +/// HCI number of packet complete event structure +struct hci_nb_cmp_pkts_evt +{ + /// number of handles + uint8_t nb_of_hdl; + /// connection handle + uint16_t conhdl[1]; + /// number of completed packets + uint16_t nb_comp_pkt[1]; +}; + +/// HCI data buffer overflow event structure +struct hci_data_buf_ovflw_evt +{ + ///Link type + uint8_t link_type; +}; + +/// HCI Hardware Error Event parameters structure +struct hci_hw_err_evt +{ + /// HW error code + uint8_t hw_code; +}; + +/// HCI encryption change event structure +struct hci_enc_change_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Encryption enabled information + uint8_t enc_stat; +}; + +/// HCI encryption key refresh complete event structure +struct hci_enc_key_ref_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; +}; + +/// HCI Authenticated Payload Timeout Expired Event structure +struct hci_auth_payl_to_exp_evt +{ + ///Connection handle + uint16_t conhdl; +}; + +/// HCI command complete event structure for create connection +struct hci_con_cmp_evt +{ + /// Status + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Bluetooth Device address + struct bd_addr bd_addr; + ///Link type + uint8_t link_type; + ///Encryption state + uint8_t enc_en; +}; + +/// HCI command complete event structure for qos setup +struct hci_qos_setup_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Flags + uint8_t flags; + ///Service type + uint8_t serv_type; + ///Token rate + uint32_t tok_rate; + ///Peak bandwidth + uint32_t pk_bw; + ///Latency + uint32_t lat; + ///Delay variation + uint32_t del_var; +}; + +/// HCI flow specification complete event parameters structure +struct hci_flow_spec_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Flags + uint8_t flags; + ///Flow direction + uint8_t flow_dir; + ///Service type + uint8_t serv_type; + ///Token rate + uint32_t tk_rate; + ///Token buffer size + uint32_t tk_buf_sz; + ///Peak bandwidth + uint32_t pk_bw; + ///Access latency + uint32_t acc_lat; +}; + +/// HCI role change event parameters structure +struct hci_role_chg_evt +{ + ///Status + uint8_t status; + ///BD address + struct bd_addr bd_addr; + ///New role + uint8_t new_role; +}; + +/// HCI complete event structure for the read clock offset command +struct hci_rd_clk_off_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Clock offset + uint16_t clk_off_val; +}; + +/// HCI event structure for the flush occurred event +struct hci_flush_occurred_evt +{ + ///Connection handle + uint16_t conhdl; +}; + +/// HCI max slot change event structure +struct hci_max_slot_chg_evt +{ + ///Connection handle + uint16_t conhdl; + ///Max slot + uint8_t max_slot; +}; + +/// HCI sniff subrating event parameters structure +struct hci_sniff_sub_evt +{ + ///Status. + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Maximum transmit latency + uint16_t max_lat_tx; + ///Maximum receive latency + uint16_t max_lat_rx; + ///Minimum remote TO + uint16_t min_rem_to; + ///Minimum local TO + uint16_t min_loc_to; +}; + +/// HCI read remote extended features complete event parameters structure +struct hci_rd_rem_ext_feats_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///page number + uint8_t pg_nb; + ///page number max + uint8_t pg_nb_max; + ///ext LMP features + struct features ext_feats; +}; + +/// HCI read remote extended features complete event parameters structure +struct hci_rem_host_supp_feats_notif_evt +{ + ///BD address + struct bd_addr bd_addr; + ///ext lmp features + struct features ext_feats; +}; + +/// HCI command complete event structure for the read remote supported features command +struct hci_rd_rem_supp_feats_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Remote features + struct features rem_feats; +}; + +/// HCI command complete event structure for the read remote information version command +struct hci_rd_rem_ver_info_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///LMP version + uint8_t vers; + ///Manufacturer name + uint16_t compid; + ///LMP subversion + uint16_t subvers; +}; + +/// HCI encryption change event structure +struct hci_enc_chg_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Encryption enabled information + uint8_t enc_stat; +}; + +/// HCI mode change event structure +struct hci_mode_chg_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Current mode + uint8_t cur_mode; + /// Interval + uint16_t interv; +}; + +/// HCI simple pairing complete event structure +struct hci_sp_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Bluetooth Device address + struct bd_addr bd_addr; +}; + +/// HCI Authentication complete event structure +struct hci_auth_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; +}; + +/// HCI change connection link key complete event structure +struct hci_chg_con_lk_cmp_evt +{ + ///Status + uint8_t status; + ///Connection handle + uint16_t conhdl; +}; + +/// HCI encryption key refresh complete event structure +struct hci_enc_key_refresh_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; +}; + +/// HCI master link key complete event structure +struct hci_master_lk_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Key flag + uint8_t key_flag; +}; +/// HCI synchronous link connection complete event structure +struct hci_sync_con_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///BD address + struct bd_addr bd_addr; + ///Link type + uint8_t lk_type; + ///Transmit interval + uint8_t tx_int; + ///Retransmission window + uint8_t ret_win; + ///rx packet length + uint16_t rx_pkt_len; + ///tx packet length + uint16_t tx_pkt_len; + ///Air mode + uint8_t air_mode; + +}; + +/// HCI synchronous connection change event structure +struct hci_sync_con_chg_evt +{ + ///Status for command reception + uint8_t status; + ///Synchronous Connection handle + uint16_t sync_conhdl; + ///Transmit interval + uint8_t tx_int; + ///Retransmission window + uint8_t ret_win; + ///rx packet length + uint16_t rx_pkt_len; + ///tx packet length + uint16_t tx_pkt_len; +}; + +/// HCI connection packet type change event structure +struct hci_con_pkt_type_chg_evt +{ + ///Status for command reception + uint8_t status; + ///Synchronous Connection handle + uint16_t sync_conhdl; + ///Synchronous packet type + uint16_t pkt_type; +}; + +/// HCI link supervision timeout change event structure +struct hci_link_supv_to_chg_evt +{ + ///Connection handle + uint16_t conhdl; + ///Link supervision timeout + uint16_t lsto_val; +}; + +/// HCI link key request event structure +struct hci_lk_req_evt +{ + ///BD address + struct bd_addr bd_addr; +}; + +/// HCI encryption key refresh event structure +struct hci_enc_key_refresh_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; +}; + +/// HCI connection request event structure +struct hci_con_req_evt +{ + ///BD address + struct bd_addr bd_addr; + ///Class of device + struct devclass classofdev; + ///link type + uint8_t lk_type; +}; + +/// HCI quality of service violation event structure +struct hci_qos_viol_evt +{ + ///Connection handle + uint16_t conhdl; +}; + +/// HCI io capability response event structure +struct hci_io_cap_rsp_evt +{ + ///BdAddr + struct bd_addr bd_addr; + ///IO capability + uint8_t io_capa; + ///OOB data present + uint8_t oob_data_pres; + ///Authentication requirements + uint8_t auth_req; + +}; + +/// HCI IO capability response event structure +struct hci_io_cap_req_evt +{ + ///BdAddr + struct bd_addr bd_addr; +}; + +/// HCI Return link keys event structure +struct hci_return_link_keys_evt +{ + ///Number of Keys + uint8_t num_keys; + ///BdAddr + struct bd_addr bd_addr; + ///Key + struct ltk key; +}; + +/// HCI pin code request event structure +struct hci_pin_code_req_evt +{ + ///BdAddr + struct bd_addr bd_addr; +}; + +/// HCI user passkey request event structure +struct hci_user_passkey_req_evt +{ + ///BdAddr + struct bd_addr bd_addr; +}; + +/// HCI user passkey notification event structure +struct hci_user_passkey_notif_evt +{ + ///BdAddr + struct bd_addr bd_addr; + ///Passkey + uint32_t passkey; +}; + +/// HCI remote OOB data request event structure +struct hci_rem_oob_data_req_evt +{ + ///BdAddr + struct bd_addr bd_addr; +}; + +/// HCI user confirmation request event structure +struct hci_user_cfm_req_evt +{ + ///BdAddr + struct bd_addr bd_addr; + ///Passkey + uint32_t passkey; +}; + +/// HCI keypress notification event structure +struct hci_keypress_notif_evt +{ + ///BdAddr + struct bd_addr bd_addr; + ///type + uint8_t type; +}; + +/// HCI link key notification event structure +struct hci_lk_notif_evt +{ + ///BdAddr + struct bd_addr bd_addr; + ///Key + struct ltk key; + ///type + uint8_t key_type; +}; + + +/* + * HCI LE META EVENTS PARAMETERS + **************************************************************************************** + */ + + +// LE event structures + +/// HCI command complete event structure for the Read Local Supported Features +struct hci_le_rd_local_supp_feats_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Local LE supported features + struct le_features feats; +}; + +/// HCI command complete event structure for the Read Advertising Channel Tx Power Command +struct hci_rd_adv_chnl_tx_pw_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Advertising channel Tx power level + int8_t adv_tx_pw_lvl; +}; + +///HCI command complete event structure for the Read White List Size Command +struct hci_le_rd_wlst_size_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///White List size + uint8_t wlst_size; +}; + +///HCI command complete event structure for the Read Buffer Size Command +struct hci_le_rd_buff_size_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///ACL data packet length that can be sent from host to controller + uint16_t hc_data_pk_len; + ///Total number of ACL data packets that can be sent from host to controller. + uint8_t hc_tot_nb_data_pkts; +}; + +///HCI command complete event structure for LE Rand Command +struct hci_le_rand_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Random number + struct rand_nb nb; +}; + +///HCI command complete event structure for Read Supported States Command +struct hci_rd_supp_states_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///LE supported states response + struct le_states states; +}; + +///HCI command complete event structure for Read Transmit Power Command +struct hci_rd_tx_pwr_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + /// Minimum transmit power + uint8_t min_tx_pwr; + /// Maximum transmit power + uint8_t max_tx_pwr; +}; + +///HCI command complete event structure for Test End +struct hci_test_end_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Number of RX packets - null if TX test was the ended one + uint16_t nb_packet_received; +}; + +///HCI LE Encrypt complete event structure +struct hci_le_enc_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Encrypted data to return to command source. + uint8_t encrypted_data[ENC_DATA_LEN]; +}; + +#if BLE_EMB_PRESENT || BLE_HOST_PRESENT +///HCI LE advertising report event structure +struct hci_le_adv_report_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Number of advertising reports in this event + uint8_t nb_reports; + ///Advertising reports structures array + struct adv_report adv_rep[BLE_ADV_REPORTS_MAX]; +}; + +///HCI LE extended advertising report event structure +struct hci_le_ext_adv_report_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Number of advertising reports in this event + uint8_t nb_reports; + ///Paramaters for each report + struct ext_adv_report adv_rep[BLE_ADV_REPORTS_MAX]; +}; + +///HCI LE periodic advertising sync established event structure +struct hci_le_per_adv_sync_est_evt +{ + ///LE Subevent code + uint8_t subcode; + /// Status of the advertising sync + uint8_t status; + /// Sync Handle to be used + uint16_t sync_handle; + /// Advertising SID + uint8_t adv_sid; + ///Advertising address type: public/random + uint8_t adv_addr_type; + ///Advertising address value + struct bd_addr adv_addr; + /// Advertiser PHY + uint8_t phy; + /// Advertising interval (Time=N*1.25ms) + uint16_t interval; + /// Advertiser clock accuracy + uint8_t adv_ca; +}; + +///HCI LE periodic advertising report event structure +struct hci_le_per_adv_report_evt +{ + ///LE Subevent code + uint8_t subcode; + /// Sync Handle to be used + uint16_t sync_handle; + /// Tx Power + uint8_t tx_power; + /// RSSI + uint8_t rssi; + /// Data Status + uint8_t status; + ///Data length in advertising packet + uint8_t data_len; + ///Data of advertising packet + uint8_t data[PER_ADV_DATA_MAX_LEN]; + ///Unused + uint8_t unused; +}; + +///HCI LE periodic advertising sync lost event structure +struct hci_le_per_adv_sync_lost_evt +{ + ///LE Subevent code + uint8_t subcode; + /// Sync Handle to be used + uint16_t sync_handle; +}; + +///HCI LE scan timeout event structure +struct hci_le_scan_timeout_evt +{ + ///LE Subevent code + uint8_t subcode; +}; + +#endif //BLE_EMB_PRESENT || BLE_HOST_PRESENT + +/// HCI command complete event structure for Read Channel Map Command +struct hci_le_rd_chnl_map_cmd_cmp_evt +{ + ///Status of command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Channel map + struct le_chnl_map ch_map; +}; + +/// HCI command complete event structure for Long Term Key Request Reply Command +struct hci_le_ltk_req_reply_cmd_cmp_evt +{ + ///Status of command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; +}; + +/// HCI command complete event structure for Long Term Key Request Negative Reply Command +struct hci_le_ltk_req_neg_reply_cmd_cmp_evt +{ + ///Status of command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; +}; + +/// HCI command complete event structure for LE Read Suggested Default Data Length Command +struct hci_le_rd_suggted_dft_data_len_cmd_cmp_evt +{ + ///Status of command reception + uint8_t status; + ///Host's suggested value for the Controller's maximum transmitted number of payload octets + uint16_t suggted_max_tx_octets; + ///Host's suggested value for the Controller's maximum packet transmission time + uint16_t suggted_max_tx_time; +}; +/// HCI command complete event structure for LE Read Maximum Data Length Command +struct hci_le_rd_max_data_len_cmd_cmp_evt +{ + ///Status of command reception + uint8_t status; + ///Maximum number of payload octets that the local Controller supports for transmission + uint16_t suppted_max_tx_octets; + ///Maximum time, in microseconds, that the local Controller supports for transmission + uint16_t suppted_max_tx_time; + ///Maximum number of payload octets that the local Controller supports for reception + uint16_t suppted_max_rx_octets; + ///Maximum time, in microseconds, that the local Controller supports for reception + uint16_t suppted_max_rx_time; +}; + +/// HCI LE Read Peer Resolvable Address Command Complete Event +struct hci_le_rd_peer_rslv_addr_cmd_cmp_evt +{ + ///Status + uint8_t status; + /// Peer Resolvable Address + struct bd_addr peer_rslv_addr; +}; + +/// HCI LE Read Local Resolvable Address Command Complete Event +struct hci_le_rd_loc_rslv_addr_cmd_cmp_evt +{ + ///Status + uint8_t status; + /// Local Resolvable Address + struct bd_addr loc_rslv_addr; +}; + +/// HCI LE Read Resolving List Size Command Complete Event +struct hci_le_rd_rslv_list_size_cmd_cmp_evt +{ + ///Status + uint8_t status; + /// Resolving List Size + uint8_t size; +}; + + +/// HCI write authenticated payload timeout command +struct hci_wr_auth_payl_to_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Authenticated payload timeout (N*10ms) + uint16_t auth_payl_to; +}; + +/// HCI command complete event structure for the Write Authenticated Payload Timeout Command +struct hci_wr_auth_payl_to_cmd_cmp_evt +{ + /// Status of the command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; +}; + +/// HCI command complete event structure for HCI LE Connection Update Command +struct hci_le_con_update_cmp_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Status of received command + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Connection interval value + uint16_t con_interval; + ///Connection latency value + uint16_t con_latency; + ///Supervision timeout + uint16_t sup_to; +}; + +/// HCI command complete event structure for create connection +struct hci_le_con_cmp_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Status of received command + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Device role - 0=Master/ 1=Slave + uint8_t role; + ///Peer address type - 0=public/1=random + uint8_t peer_addr_type; + ///Peer address + struct bd_addr peer_addr; + ///Connection interval + uint16_t con_interval; + ///Connection latency + uint16_t con_latency; + ///Link supervision timeout + uint16_t sup_to; + ///Master clock accuracy + uint8_t clk_accuracy; +}; + +/// HCI LE read remote used feature command parameters structure +struct hci_le_rd_rem_feats_cmd +{ + ///Connection handle + uint16_t conhdl; +}; + +/// HCI command complete event structure for HCI LE read remote feature Command +struct hci_le_rd_rem_feats_cmd_cmp_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Status of received command + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Le Features + struct le_features le_feats; +}; + +/// HCI command structure for the read transmit power level command +struct hci_rd_tx_pwr_lvl_cmd +{ + ///Connection handle + uint16_t conhdl; + ///Power Level type: current or maximum + uint8_t type; +}; + +/// HCI command complete event structure for the read transmit power level command +struct hci_rd_tx_pwr_lvl_cmd_cmp_evt +{ + ///Status for command reception + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Value of TX power level + uint8_t tx_pow_lvl; +}; + +/// HCI read remote information version command parameters structure +struct hci_rd_rem_ver_info_cmd +{ + ///Connection handle + uint16_t conhdl; +}; + +/// HCI LE remote connection parameter request event +struct hci_le_rem_con_param_req_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Connection handle + uint16_t conhdl; + ///Interval_Min + uint16_t interval_min; + ///Interval_Max + uint16_t interval_max; + ///Latency + uint16_t latency; + ///Timeout + uint16_t timeout; +}; + + +/// HCI command complete event structure for enhance create connection +struct hci_le_enh_con_cmp_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Status of received command + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///Device role - 0=Master/ 1=Slave + uint8_t role; + ///Peer address type - 0=public/1=random + uint8_t peer_addr_type; + ///Peer address + struct bd_addr peer_addr; + ///Local Resolvable Private Address + struct bd_addr loc_rslv_priv_addr; + ///Peer Resolvable Private Address + struct bd_addr peer_rslv_priv_addr; + ///Connection interval + uint16_t con_interval; + ///Connection latency + uint16_t con_latency; + ///Link supervision timeout + uint16_t sup_to; + ///Master clock accuracy + uint8_t clk_accuracy; +}; + + +struct hci_generate_dhkey_cmp_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Status of received command + uint8_t status; + /// The 32 byte Diffie Helman Key + uint8_t dh_key[32]; +}; + + +struct hci_rd_local_p256_public_key_cmp_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Status of received command + uint8_t status; + /// The 32 byte Diffie Helman Key + uint8_t public_key[64]; + +}; + +#if BLE_EMB_PRESENT || BLE_HOST_PRESENT +/// HCI LE Direct Advertising Report Event +struct hci_le_dir_adv_rep_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Number of reports + uint8_t nb_reports; + ///Direct Advertising reports structures array + struct dir_adv_report adv_rep[BLE_ADV_REPORTS_MAX]; +}; +#endif //BLE_EMB_PRESENT || BLE_HOST_PRESENT + +/// HCI command complete event structure for HCI LE read remote used feature Command +struct hci_le_ltk_request_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Connection handle + uint16_t conhdl; + ///Random number + struct rand_nb rand; + ///Encryption diversifier + uint16_t ediv; +}; + +/// HCI LE META event LE Data Length Change Event +struct hci_le_data_len_chg_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Connection handle + uint16_t conhdl; + ///The maximum number of payload octets in TX + uint16_t max_tx_octets; + ///The maximum time that the local Controller will take to TX + uint16_t max_tx_time; + ///The maximum number of payload octets in RX + uint16_t max_rx_octets; + ///The maximum time that the local Controller will take to RX + uint16_t max_rx_time; +}; + + +/// HCI Synchronization Train Received Event +struct hci_sync_train_rec_evt +{ + /// Status + uint8_t status; + /// BD_ADDR + struct bd_addr bd_addr; + /// Clock_Offset (28 bits) - (CLKNslave - CLK) modulo 2^28 + uint32_t clock_offset; + /// AFH_Channel_Map + struct chnl_map afh_ch_map; + /// LT_ADDR + uint8_t lt_addr; + /// Next_Broadcast_Instant (28 bits) + uint32_t next_bcst_instant; + /// Connectionless_Slave_Broadcast_Interval (in slots) + uint16_t csb_int; + /// Service_Data + uint8_t service_data; +}; + +/// HCI Connectionless Slave Broadcast Receive Event +struct hci_con_slv_bcst_rec_evt +{ + /// BD_ADDR + struct bd_addr bd_addr; + /// LT_ADDR + uint8_t lt_addr; + /// CLK (28 bits) + uint32_t clk; + /// Offset (28 bits) - (CLKNslave - CLK) modulo 2^28 + uint32_t offset; + /// Receive Status + uint8_t receive_status; + /// Fragment + uint8_t fragment; + /// Data_Length (in bytes) + uint8_t data_length; + /// Data + uint8_t data[__ARRAY_EMPTY]; +}; + +/// HCI Connectionless Slave Broadcast Timeout Event +struct hci_con_slv_bcst_to_evt +{ + /// BD_ADDR + struct bd_addr bd_addr; + /// LT_ADDR + uint8_t lt_addr; +}; + +/// HCI Connectionless Slave Broadcast Channel Map Change Event +struct hci_con_slv_bcst_ch_map_chg_evt +{ + /// Channel_Map + struct chnl_map ch_map; +}; + + +struct hci_le_generate_dhkey_cmp_evt +{ + ///LE Subevent code + uint8_t subcode; + uint8_t status; + uint8_t dh_key[32]; +}; + +struct hci_le_generate_p256_public_key_cmp_evt +{ + ///LE Subevent code + uint8_t subcode; + uint8_t status; + t_public_key public_key; +}; + +/* + * HCI VENDOR SPECIFIC COMMANDS PARAMETERS + **************************************************************************************** + */ + +/// Buffer structure +struct buffer_tag +{ + /// length of buffer + uint8_t length; + /// data of 128 bytes length + uint8_t data[128]; +}; + +/// Common structure for Command Complete Event of HCI Debug Read Memory/Flash/Param complete event parameters - vendor specific +struct hci_dbg_basic_rd_data_cmd_cmp_evt +{ + ///Status + uint8_t status; + ///buffer structure to return + struct buffer_tag buf; +}; + +///HCI Debug read memory variable command parameters - vendor specific +struct hci_dbg_rd_mem_cmd +{ + ///Start address to read + uint32_t start_addr; + ///Access size + uint8_t type; + ///Length to read + uint8_t length; +}; + +///HCI Debug write memory variable command parameters - vendor specific +struct hci_dbg_wr_mem_cmd +{ + ///Start address to read + uint32_t start_addr; + ///Access size + uint8_t type; + ///buffer structure to return + struct buffer_tag buf; +}; + +///HCI Debug delete parameter command parameters - vendor specific +struct hci_dbg_del_param_cmd +{ + ///Parameter tag + uint16_t param_tag; +}; + +///HCI Debug erase flash command parameters - vendor specific +struct hci_dbg_er_flash_cmd +{ + ///Flash type + uint8_t flashtype; + ///Start offset address + uint32_t startoffset; + ///Size to erase + uint32_t size; +}; + +///HCI Debug write flash command parameters - vendor specific +struct hci_dbg_wr_flash_cmd +{ + ///Flash type + uint8_t flashtype; + ///Start offset address + uint32_t startoffset; + ///buffer structure + struct buffer_tag buf; +}; + +///HCI Debug read flash command parameters - vendor specific +struct hci_dbg_rd_flash_cmd +{ + ///Flash type + uint8_t flashtype; + ///Start offset address + uint32_t startoffset; + ///Size to read + uint8_t size; +}; + +///HCI Debug read parameter command parameters - vendor specific +struct hci_dbg_rd_par_cmd +{ + ///Parameter tag + uint16_t param_tag; +}; + +///HCI Debug read parameters command parameters - vendor specific +struct hci_dbg_wr_par_cmd +{ + ///Parameter tag + uint16_t param_tag; + ///Structure buffer + struct buffer_tag buf; +}; + +#if CRYPTO_UT +struct hci_dbg_test_crypto_func_cmd +{ + /// Id of Function to be tested + uint8_t function; + /// Structure buffer + struct buffer_tag buf; +}; +#endif //CRYPTO_UT + +///HCI Debug Read Kernel Statistics complete event parameters - vendor specific +struct hci_dbg_rd_ke_stats_cmd_cmp_evt +{ + ///Status + uint8_t status; + ///Max message sent + uint8_t max_msg_sent; + ///Max message saved + uint8_t max_msg_saved; + ///Max timer used + uint8_t max_timer_used; + ///Max heap used + uint16_t max_heap_used; + ///Max stack used + uint16_t max_stack_used; +}; + + +/// HCI Debug Read information about memory usage. - vendor specific +struct hci_dbg_rd_mem_info_cmd_cmp_evt +{ + ///Status + uint8_t status; + /// memory size currently used into each heaps. + uint16_t mem_used[KE_MEM_BLOCK_MAX]; + /// peak of memory usage measured + uint32_t max_mem_used; +}; + +///HCI Debug identify Flash command complete event parameters - vendor specific +struct hci_dbg_id_flash_cmd_cmp_evt +{ + ///Status + uint8_t status; + ///Flash identity + uint8_t flash_id; +}; + +///HCI Debug RF Register read command +struct hci_dbg_rf_reg_rd_cmd +{ + /// register address + uint16_t addr; +}; + +///HCI Debug RF Register read command complete event +struct hci_dbg_rf_reg_rd_cmd_cmp_evt +{ + /// status + uint8_t status; + /// register address + uint16_t addr; + /// register value + uint32_t value; +}; + +///HCI Debug RF Register write command +struct hci_dbg_rf_reg_wr_cmd +{ + /// register address + uint16_t addr; + /// register value + uint32_t value; +}; + +///HCI Debug RF Register write command complete event +struct hci_dbg_rf_reg_wr_cmd_cmp_evt +{ + /// status + uint8_t status; + /// address + uint16_t addr; +}; + +///HCI Debug platform reset command parameters - vendor specific +struct hci_dbg_plf_reset_cmd +{ + /// reason + uint8_t reason; +}; + +#if (RW_DEBUG && BT_EMB_PRESENT) +/// Discard LMP Packets +struct hci_dbg_bt_send_lmp_cmd +{ + /// Connection handle + uint16_t conhdl; + ///buffer structure to return + struct buffer_tag buf; +}; + +/// Discard LMP Packets +struct hci_dbg_bt_discard_lmp_en_cmd +{ + /// Connection handle + uint16_t conhdl; + /// Enable/Disable LMP discard (0: disable / 1: enable) + uint8_t enable; +}; +#endif //(RW_DEBUG && BT_EMB_PRESENT) + +#if (RW_WLAN_COEX) +///HCI Debug wlan coexistence command parameters - vendor specific +struct hci_dbg_wlan_coex_cmd +{ + /// State + uint8_t state; +}; +#if (RW_WLAN_COEX_TEST) +///HCI Debug wlan coexistence test scenario command parameters - vendor specific +struct hci_dbg_wlan_coextst_scen_cmd +{ + /// Scenario + uint32_t scenario; +}; +#endif //RW_WLAN_COEX_TEST +#endif //RW_WLAN_COEX + +#if (RW_MWS_COEX) +///HCI Debug mws coexistence command parameters - vendor specific +struct hci_dbg_mws_coex_cmd +{ + /// State + uint8_t state; +}; +#if (RW_MWS_COEX_TEST) +///HCI Debug mws coexistence test scenario command parameters - vendor specific +struct hci_dbg_mws_coextst_scen_cmd +{ + /// Scenario + uint32_t scenario; +}; +#endif //RW_MWS_COEX_TEST +#endif //RW_MWS_COEX + +///HCI Debug HW Register Read command parameters - vendor specific +struct hci_dbg_hw_reg_rd_cmd +{ + /// register address + uint16_t reg_addr; +}; + +///HCI Debug HW Register write command parameters - vendor specific +struct hci_dbg_hw_reg_wr_cmd +{ + /// register address + uint16_t reg_addr; + /// extra parameter + uint16_t reserved; + /// register value + uint32_t reg_value; +}; + +///HCI Debug HW Register Read Complete event parameters - vendor specific +struct hci_dbg_hw_reg_rd_cmd_cmp_evt +{ + /// status + uint8_t status; + /// register address + uint16_t reg_addr; + /// register value + uint32_t reg_value; +}; + +///HCI Debug HW Register Write Complete event parameters - vendor specific +struct hci_dbg_hw_reg_wr_cmd_cmp_evt +{ + /// status + uint8_t status; + /// register address + uint16_t reg_addr; +}; + +///HCI Debug write DLE default value command parameters - vendor specific +struct hci_dbg_wr_dle_dft_value_cmd +{ + /// Max transmit packet size supported + uint16_t suppted_max_tx_octets; + /// Max transmit packet time supported + uint16_t suppted_max_tx_time; + /// Max receive packet size supported + uint16_t suppted_max_rx_octets; + /// Max receive packet time supported + uint16_t suppted_max_rx_time; + +}; + +#if (BLE_EMB_PRESENT || BLE_HOST_PRESENT) +///HCI Debug bd address write command parameters - vendor specific +struct hci_dbg_set_bd_addr_cmd +{ + ///bd address to set + struct bd_addr addr; +}; + +///HCI Debug crc write command parameters - vendor specific +struct hci_dbg_set_crc_cmd +{ + /// Handle pointing to the connection for which CRC has to be modified + uint16_t conhdl; + /// CRC to set + struct crc_init crc; +}; + +///HCI Debug LLC discard command parameters - vendor specific +struct hci_dbg_llcp_discard_cmd +{ + /// Handle pointing to the connection for which LLCP commands have to be discarded + uint16_t conhdl; + /// Flag indicating if the discarding has to be enabled or disabled + uint8_t enable; +}; + +///HCI Debug reset RX counter command parameters - vendor specific +struct hci_dbg_reset_rx_cnt_cmd +{ + /// Handle pointing to the connection for which the counter have to be reseted + uint16_t conhdl; +}; + +///HCI Debug reset TX counter command parameters - vendor specific +struct hci_dbg_reset_tx_cnt_cmd +{ + /// Handle pointing to the connection for which the counter have to be reseted + uint16_t conhdl; +}; + +///HCI Debug Set TX Power Level Command parameters +struct hci_dbg_set_tx_pw_cmd +{ + /// Connection handle + uint16_t conhdl; + /// Power level + uint8_t pw_lvl; +}; + +///HCI Debug configure audio command parameters - vendor specific + +struct hci_dbg_audio_configure_audio_cmd +{ + /// Voice channel to be updated + uint8_t voice_channel; + /// Configure transmitter size in bytes + uint8_t tx_size; + /// Configure receiver size in bytes + uint8_t rx_size; + /// Configure transmitter rate + uint8_t tx_rate; + /// Configure receiver rate + uint8_t rx_rate; + /// Configure number of retransmission + uint8_t nb_retx; + /// Audio link priority + uint8_t priority; + /// Encryption mode + uint8_t mode; + /// Channel and mute configuration (@see enum audio_cfg) + uint8_t chan_mute_cfg; + /// Mute Pattern + uint8_t mute_pattern; +}; + +struct hci_dbg_audio_set_pointer_cmd +{ + /// Voice channel to be updated + uint8_t voice_channel; + /// Rx or Tx selection + uint8_t rx_tx_select; + /// Tog to be updated + uint8_t tog; + /// Exchange memory pointer + uint16_t em_ptr; +}; +///HCI Debug set audio mode command parameters - vendor specific +struct hci_audio_set_mode_cmd +{ + /// Voice channel to be updated + uint8_t voice_channel; + /// Mode + uint8_t mode; +}; + +///HCI Debug set audio mode command parameters - vendor specific +struct hci_dbg_audio_reset_cmd +{ + /// Voice channel to be updated + uint8_t voice_channel; +}; + +///HCI Debug set audio mode command parameters - vendor specific +struct hci_dbg_audio_allocate_cmd +{ + /// Connection handle + uint16_t conhdl; + /// Audio mode + uint8_t mode; +}; + +///HCI Debug set audio mode command parameters - vendor specific +struct hci_dbg_audio_get_vx_ch_cmd +{ + /// Connection handle + uint16_t conhdl; +}; +///HCI Tester set LE parameters +struct hci_tester_set_le_params_cmd +{ + /// Connection handle + uint16_t conhdl; + /// Tester features + uint8_t tester_feats; + /// Preferred periodicity + uint8_t pref_period; + /// Offset0 + uint16_t offset0; + /// Offset1 + uint16_t offset1; + /// Offset2 + uint16_t offset2; + /// Offset3 + uint16_t offset3; + /// Offset4 + uint16_t offset4; + /// Offset5 + uint16_t offset5; +}; + +/// HCI BLE Tester: enable LLCP pass through mechanism +struct hci_dbg_ble_tst_llcp_pt_en_cmd +{ + /// Connection handle + uint16_t conhdl; + /// Enable or not LLCP pass through mechanism + uint8_t enable; +}; + +/// HCI BLE Tester: send an LLCP PDU +struct hci_dbg_ble_tst_send_llcp_cmd +{ + /// Connection handle + uint16_t conhdl; + /// length of LLCP PDU + uint8_t length; + /// LLCP PDU data + uint8_t data[26]; +}; + + +/// HCI DBG Meta Event trigg when LLCP message received with LLCP pass through mechanism +struct hci_dbg_ble_tst_llcp_recv_evt +{ + ///DBG Subevent code + uint8_t subcode; + ///Connection handle + uint16_t conhdl; + /// length of LLCP message + uint8_t length; + /// LLCP data + uint8_t data[26]; +}; + +#endif //BLE_EMB_PRESENT || BLE_HOST_PRESENT + +#if (RW_DEBUG) +/// HCI DBG Meta Event indicating a SW assertion error +struct hci_dbg_assert_err_evt +{ + ///DBG Subevent code + uint8_t subcode; + /// Line number + uint32_t line; + /// Param0 + uint32_t param0; + /// Param1 + uint32_t param1; + /// File name + uint8_t file[__ARRAY_EMPTY]; +}; +#endif //(RW_DEBUG) + +/// HCI LE Read PHY command +struct hci_le_rd_phy_cmd +{ + /// Connection Handle + uint16_t conhdl; +}; + +/// HCI LE Set Default PHY Command +struct hci_le_set_dft_phy_cmd +{ + /// Preferred PHYS selection + uint8_t all_phys; + /// Preferred PHYS for TX + uint8_t tx_phys; + /// Preferred PHYS for RX + uint8_t rx_phys; +}; + +/// HCI LE Set PHY Command +struct hci_le_set_phy_cmd +{ + /// Connection Handle + uint16_t conhdl; + /// Preferred PHYS selection + uint8_t all_phys; + /// Preferred PHYS for TX + uint8_t tx_phys; + /// Preferred PHYS for RX + uint8_t rx_phys; + /// PHY options + uint16_t phy_opt; +}; + +/// HCI LE Set Extended Advertising Parameters Command Complete Event +struct hci_le_set_ext_adv_param_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// Selected Tx power + uint8_t sel_tx_pwr; +}; + +/// HCI LE Enhanced Receiver Test Command +struct hci_le_enh_rx_test_cmd +{ + /// Reception channel value + uint8_t channel; + /// Reception PHY rate + uint8_t phys; + /// Modulation index + uint8_t modulation_idx; +}; + +/// HCI LE Enhanced Transmitter Test Command +struct hci_le_enh_tx_test_cmd +{ + /// Transmit channel value + uint8_t channel; + /// Length of the data to be transmitted in a packet + uint8_t payload_length; + /// Type of the data contained in a packet + uint8_t payload_type; + /// Transmit PHY rate + uint8_t phys; +}; + +///HCI LE Set Advertising Set Random Address Command parameters structure +struct hci_le_set_adv_set_rand_addr_cmd +{ + /// Advertising handle + uint8_t adv_hdl; + /// Advertising random address + struct bd_addr rand_addr; +}; + +///HCI LE Set Extended Advertising Parameters Command parameters structure +struct hci_le_set_ext_adv_param_cmd +{ + /// Advertising handle + uint8_t adv_hdl; + /// Advertising event properties + uint16_t adv_evt_properties; + /// Primary advertising minimum interval + uint8_t prim_adv_intv_min[3]; + /// Primary advertising maximum interval + uint8_t prim_adv_intv_max[3]; + /// Primary advertising channel map + uint8_t prim_adv_chnl_map; + /// Own address type: public=0 / random=1 / rpa_or_pub=2 / rpa_or_rnd=3 + uint8_t own_addr_type; + /// Peer address type: public=0 / random=1 + uint8_t peer_addr_type; + /// Peer Bluetooth device address + struct bd_addr peer_addr; + /// Advertising filter policy + uint8_t adv_filt_policy; + /// Advertising Tx power + int8_t adv_tx_pwr; + /// Primary advertising PHY + uint8_t prim_adv_phy; + /// Secondary advertising max skip + uint8_t sec_adv_max_skip; + /// Secondary advertising PHY + uint8_t sec_adv_phy; + /// Advertising SID + uint8_t adv_sid; + /// Scan request notification enable + uint8_t scan_req_notif_en; +}; + +///HCI LE Set Extended Advertising Data Command parameters structure +struct hci_le_set_ext_adv_data_cmd +{ + /// Advertising handle + uint8_t adv_hdl; + /** + * Operation + * 0x00 Intermediate fragment of fragmented extended advertising data + * 0x01 First fragment of fragmented extended advertising data + * 0x02 Last fragment of fragmented extended advertising data + * 0x03 Complete extended advertising data + * 0x04 [ID7300_r06] Unchanged data (just update the Advertising DID) + * All other values Reserved for future use + */ + uint8_t operation; + /** + * Fragment preference + * 0x00 The Controller may fragment all Host advertising data + * 0x01 The Controller should not fragment nor minimize fragmentation of Host advertising data + * All other values Reserved for future use + */ + uint8_t frag_pref; + /// Advertising Data Length (0-252 bytes) + uint8_t data_len; + /// Advertising data + uint8_t data[__ARRAY_EMPTY]; +}; + +///HCI LE Set Extended Scan Response Data Command parameters structure +struct hci_le_set_ext_scan_rsp_data_cmd +{ + /// Advertising handle + uint8_t adv_hdl; + /** + * Operation + * 0x00 Intermediate fragment of fragmented extended advertising data + * 0x01 First fragment of fragmented extended advertising data + * 0x02 Last fragment of fragmented extended advertising data + * 0x03 Complete extended advertising data + * 0x04 [ID7300_r06] Unchanged data (just update the Advertising DID) + * All other values Reserved for future use + */ + uint8_t operation; + /** + * Fragment preference + * 0x00 The Controller may fragment all Host advertising data + * 0x01 The Controller should not fragment nor minimize fragmentation of Host advertising data + * All other values Reserved for future use + */ + uint8_t frag_pref; + /// Scan Response Data Length (0-252 bytes) + uint8_t data_len; + /// Advertising data + uint8_t data[__ARRAY_EMPTY]; +}; + +///HCI LE Set Extended Advertising Enbale Command parameters structure +struct hci_le_set_ext_adv_en_cmd +{ + /// Enable + uint8_t enable; + /// Number of sets (1 - 0x3F) + uint8_t nb_sets; + /// Advertising handle + uint8_t adv_hdl[BLE_ACTIVITY_MAX]; + /// Duration (N * 10 ms), 0x0000 No advertising duration. Advertising to continue until the Host disables it. + uint16_t duration[BLE_ACTIVITY_MAX]; + /// Maximum number of extended advertising events + uint8_t max_ext_adv_evt[BLE_ACTIVITY_MAX]; +}; + +///HCI LE Read Maximum Advertising Data Length Command complete event +struct hci_le_rd_max_adv_data_len_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// Maximum advertising data length + uint16_t max_adv_data_len; +}; + +///HCI LE Remove Advertising Set Command parameters structure +struct hci_le_rem_adv_set_cmd +{ + /// Advertising handle + uint8_t adv_hdl; +}; + +///HCI LE Read Number of Supported Advertising Sets Command complete event +struct hci_le_rd_nb_supp_adv_sets_cmd_cmp_evt +{ + /// Status + uint8_t status; + /// Number of supported advertising sets + uint8_t nb_supp_adv_sets; +}; + +///HCI LE Set Periodic Advertising Parameters Command parameters structure +struct hci_le_set_per_adv_param_cmd +{ + /// Advertising handle + uint8_t adv_hdl; + /// Minimum advertising interval for periodic advertising + uint16_t adv_intv_min; + /// Maximum advertising interval for periodic advertising + uint16_t adv_intv_max; + /// Advertising properties + uint16_t adv_prop; +}; + +///HCI LE Set Periodic Advertising Data Command parameters structure +struct hci_le_set_per_adv_data_cmd +{ + /// Advertising handle + uint8_t adv_hdl; + /** + * Operation + * 0x00 Intermediate fragment of fragmented periodic advertising data + * 0x01 First fragment of fragmented periodic advertising data + * 0x02 Last fragment of fragmented periodic advertising data + * 0x03 Complete periodic advertising data + * All other values Reserved for future use + */ + uint8_t operation; + /// Advertising Data Length (0-252 bytes) + uint8_t data_len; + /// Advertising data + uint8_t data[__ARRAY_EMPTY]; +}; + +///HCI LE Set Periodic Advertising Enable Command parameters structure +struct hci_le_set_per_adv_en_cmd +{ + /// Enable + uint8_t enable; + /// Advertising handle + uint8_t adv_hdl; +}; + +///HCI LE Advertising Set Terminated event +struct hci_le_adv_set_term_evt +{ + /// LE Subevent code + uint8_t subcode; + /// Status + uint8_t status; + /// Advertising handle + uint8_t adv_hdl; + /// Connection handle + uint16_t conhdl; + /// Num_Completed_Extended_Advertising_Events + uint8_t nb_cmp_ext_adv_evt; +}; + +///HCI LE Scan Request Received event +struct hci_le_scan_req_rcvd_evt +{ + /// LE Subevent code + uint8_t subcode; + /// Advertising handle + uint8_t adv_hdl; + /// Scanner address type: public=0 / random=1 / rpa_or_pub=2 / rpa_or_rnd=3 + uint8_t scan_addr_type; + /// Scanner address + struct bd_addr scan_addr; +}; + +///HCI LE Read Periodic Advertiser List Size Command complete event +struct hci_le_rd_per_adv_list_size_cmd_cmp_evt +{ + ///Status + uint8_t status; + /// Periodic Advertiser List Size + uint8_t size; +}; + +///HCI LE Channel Selection Algorithm event +struct hci_le_ch_sel_algo_evt +{ + /// LE Subevent code + uint8_t subcode; + /// Connection handle + uint16_t conhdl; + /// Channel selection algorithm + uint8_t ch_sel_algo; +}; + +/// HCI LE read PHY Command complete event +struct hci_le_rd_phy_cmd_cmp_evt +{ + ///Status of received command + uint8_t status; + /// Connection Handle + uint16_t conhdl; + /// Current configured PHY for TX + uint8_t tx_phy; + /// Current configured PHY for RX + uint8_t rx_phy; +}; + +/// HCI command complete event structure for HCI LE PHY Update Command +struct hci_le_phy_update_cmp_evt +{ + ///LE Subevent code + uint8_t subcode; + ///Status of received command + uint8_t status; + ///Connection handle + uint16_t conhdl; + ///TX phy chosen + uint8_t tx_phy; + ///RX phy chosen + uint8_t rx_phy; +}; + +/// @} CO_BT +#endif // CO_HCI_H_ diff --git a/services/ble_stack/common/api/co_list.h b/services/ble_stack/common/api/co_list.h new file mode 100644 index 0000000..8ae9968 --- /dev/null +++ b/services/ble_stack/common/api/co_list.h @@ -0,0 +1,288 @@ +#ifndef _CO_LIST_H_ +#define _CO_LIST_H_ + +/** + ***************************************************************************************** + * @defgroup CO_LIST List management + * @ingroup COMMON + * + * @brief List management. + * + * This module contains the list structures and handling functions. + * @{ + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include // standard definition +#include // boolean definition +#include // for NULL and size_t +#include "rwip_config.h" // stack configuration +#include "compiler.h" // for __INLINE + + +/* + * DEFINES + **************************************************************************************** + */ +///list type +enum +{ + POOL_LINKED_LIST = 0x00, + RING_LINKED_LIST, + LINK_TYPE_END +}; + +/// structure of a list element header +struct co_list_hdr +{ + /// Pointer to next co_list_hdr + struct co_list_hdr *next; +}; + +/// structure of a list +struct co_list +{ + /// pointer to first element of the list + struct co_list_hdr *first; + /// pointer to the last element + struct co_list_hdr *last; + + #if (KE_PROFILING) + /// number of element in the list + uint32_t cnt; + /// max number of element in the list + uint32_t maxcnt; + /// min number of element in the list + uint32_t mincnt; + #endif //KE_PROFILING +}; + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialize a list to defaults values. + * + * @param list Pointer to the list structure. + **************************************************************************************** + */ +void co_list_init(struct co_list *list); + +/** + **************************************************************************************** + * @brief Initialize a pool to default values, and initialize the relative free list. + * + * @param list Pointer to the list structure + * @param pool Pointer to the pool to be initialized + * @param elmt_size Size of one element of the pool + * @param elmt_cnt Nb of elements available in the pool + * @param default_value Pointer to the default value of each element (may be NULL) + * @param list_type Determine if the it is a ring list or not + * + **************************************************************************************** + */ +void co_list_pool_init(struct co_list *list, + void *pool, + size_t elmt_size, + uint32_t elmt_cnt, + void *default_value, + uint8_t list_type); + +/** + **************************************************************************************** + * @brief Add an element as last on the list. + * + * @param list Pointer to the list structure + * @param list_hdr Pointer to the header to add at the end of the list + * + **************************************************************************************** + */ +void co_list_push_back(struct co_list *list, struct co_list_hdr *list_hdr); + +/** + **************************************************************************************** + * @brief Append a sequence of elements at the end of a list. + * + * Note: the elements to append shall be linked together + * + * @param list Pointer to the list structure + * @param first_hdr Pointer to the first element to append + * @param last_hdr Pointer to the last element to append + **************************************************************************************** + */ +void co_list_push_back_sublist(struct co_list *list, struct co_list_hdr *first_hdr, struct co_list_hdr *last_hdr); + +/** + **************************************************************************************** + * @brief Add an element as first on the list. + * + * @param list Pointer to the list structure + * @param list_hdr Pointer to the header to add at the beginning of the list + **************************************************************************************** + */ +void co_list_push_front(struct co_list *list, struct co_list_hdr *list_hdr); + +/** + **************************************************************************************** + * @brief Extract the first element of the list. + * @param list Pointer to the list structure + * @return The pointer to the element extracted, and NULL if the list is empty. + **************************************************************************************** + */ +struct co_list_hdr *co_list_pop_front(struct co_list *list); + +/** + **************************************************************************************** + * @brief Search for a given element in the list, and extract it if found. + * + * @param list Pointer to the list structure + * @param list_hdr Element to extract + * + * @return true if the element is found in the list, false otherwise + **************************************************************************************** + */ +bool co_list_extract(struct co_list *list, struct co_list_hdr *list_hdr); + +/** + **************************************************************************************** + * @brief Extract an element when the previous element is known + * + * Note: the element to remove shall follow immediately the reference within the list + * + * @param list Pointer to the list structure + * @param elt_ref_hdr Pointer to the referenced element (NULL if element to extract is the first in the list) + * @param elt_to_rem_hdr Pointer to the element to be extracted + **************************************************************************************** + */ +void co_list_extract_after(struct co_list *list, struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_rem_hdr); + +/** + **************************************************************************************** + * @brief Extract a sub-list when the previous element is known + * + * Note: the elements to remove shall be linked together and follow immediately the reference element + * + * @param[in] list Pointer to the list structure + * @param[in] ref_hdr Pointer to the referenced element (NULL if first element to extract is first in the list) + * @param[in] last_hdr Pointer to the last element to extract () + **************************************************************************************** + */ +void co_list_extract_sublist(struct co_list *list, struct co_list_hdr *ref_hdr, struct co_list_hdr *last_hdr); + +/** + **************************************************************************************** + * @brief Searched a given element in the list. + * + * @param list Pointer to the list structure + * @param list_hdr Pointer to the searched element + * + * @return true if the element is found in the list, false otherwise + **************************************************************************************** + */ +bool co_list_find(struct co_list *list, struct co_list_hdr *list_hdr); + +/** + **************************************************************************************** + * @brief Merge two lists in a single one. + * + * This function appends the list pointed by list2 to the list pointed by list1. Once the + * merge is done, it empties list2. + * + * @param list1 Pointer to the destination list + * @param list2 Pointer to the list to append to list1 + **************************************************************************************** + */ +void co_list_merge(struct co_list *list1, struct co_list *list2); + +/** + **************************************************************************************** + * @brief Insert a given element in the list before the referenced element. + * + * @param list Pointer to the list structure + * @param elt_ref_hdr Pointer to the referenced element + * @param elt_to_add_hdr Pointer to the element to be inserted + * + * @return true if the element is found in the list, false otherwise + **************************************************************************************** + */ +void co_list_insert_before(struct co_list *list, + struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_add_hdr); + +/** + **************************************************************************************** + * @brief Insert a given element in the list after the referenced element. + * + * @param list Pointer to the list structure + * @param elt_ref_hdr Pointer to the referenced element + * @param elt_to_add_hdr Pointer to the element to be inserted + * + * @return true if the element is found in the list, false otherwise + **************************************************************************************** + */ +void co_list_insert_after(struct co_list *list, + struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_add_hdr); + + +/** + **************************************************************************************** + * @brief Count number of elements present in the list + * + * @param list Pointer to the list structure + * + * @return Number of elements present in the list + **************************************************************************************** + */ +uint16_t co_list_size(struct co_list *list); + +/** + **************************************************************************************** + * @brief Test if the list is empty. + * @param list Pointer to the list structure. + * @return true if the list is empty, false else otherwise. + **************************************************************************************** + */ +__STATIC __INLINE bool co_list_is_empty(const struct co_list *const list) +{ + bool listempty; + listempty = (list->first == NULL); + return (listempty); +} + +/** + **************************************************************************************** + * @brief Pick the first element from the list without removing it. + * + * @param list Pointer to the list structure. + * + * @return First element address. Returns NULL pointer if the list is empty. + **************************************************************************************** + */ +__STATIC __INLINE struct co_list_hdr *co_list_pick(const struct co_list *const list) +{ + return(list->first); +} + + +/** + **************************************************************************************** + * @brief Return following element of a list element. + * + * @param list_hdr Pointer to the list element. + * + * @return The pointer to the next element. + **************************************************************************************** + */ +__STATIC __INLINE struct co_list_hdr *co_list_next(const struct co_list_hdr *const list_hdr) +{ + return(list_hdr->next); +} + +/// @} CO_LIST +#endif // _CO_LIST_H_ diff --git a/services/ble_stack/common/api/co_llcp.h b/services/ble_stack/common/api/co_llcp.h new file mode 100644 index 0000000..236e5c8 --- /dev/null +++ b/services/ble_stack/common/api/co_llcp.h @@ -0,0 +1,483 @@ +#ifndef CO_LLCP_H_ +#define CO_LLCP_H_ + +/** + **************************************************************************************** + * @addtogroup CO_BT + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "co_bt.h" +/* + * DEFINES + **************************************************************************************** + */ +#define LLCP_OPCODE_MASK (0xFF) +#define LLCP_OPCODE_POS (0) +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ +/// Control packet op_code +enum co_llcp_op_code +{ + /// Connection update request + LLCP_CONNECTION_UPDATE_IND_OPCODE, + /// Channel map request + LLCP_CHANNEL_MAP_IND_OPCODE, + /// Termination indication + LLCP_TERMINATE_IND_OPCODE, + /// Encryption request + LLCP_ENC_REQ_OPCODE, + /// Encryption response + LLCP_ENC_RSP_OPCODE, + /// Start encryption request + LLCP_START_ENC_REQ_OPCODE, + /// Start encryption response + LLCP_START_ENC_RSP_OPCODE, + /// Unknown response + LLCP_UNKNOWN_RSP_OPCODE, + /// Feature request + LLCP_FEATURE_REQ_OPCODE, + /// Feature response + LLCP_FEATURE_RSP_OPCODE, + /// Pause encryption request + LLCP_PAUSE_ENC_REQ_OPCODE, + /// Pause encryption response + LLCP_PAUSE_ENC_RSP_OPCODE, + /// Version indication + LLCP_VERSION_IND_OPCODE, + /// Reject indication + LLCP_REJECT_IND_OPCODE, + /// Slave feature request + LLCP_SLAVE_FEATURE_REQ_OPCODE, + /// Connection parameters request + LLCP_CONNECTION_PARAM_REQ_OPCODE, + /// Connection parameters response + LLCP_CONNECTION_PARAM_RSP_OPCODE, + /// Reject indication extended + LLCP_REJECT_IND_EXT_OPCODE, + /// Ping request + LLCP_PING_REQ_OPCODE, + /// Ping response + LLCP_PING_RSP_OPCODE, + /// Ping request + LLCP_LENGTH_REQ_OPCODE, + /// Ping response + LLCP_LENGTH_RSP_OPCODE, + /// Phy request + LLCP_PHY_REQ_OPCODE, + /// Phy response + LLCP_PHY_RSP_OPCODE, + /// Phy update indication + LLCP_PHY_UPD_IND_OPCODE, + /// Min used channels indication + LLCP_MIN_USED_CHANNELS_IND_OPCODE, + /// Opcode length + LLCP_OPCODE_MAX_OPCODE, + + #if (BLE_TESTER) + LLCP_OPCODE_DEBUG = 0xFF, + #endif // (BLE_TESTER) +}; + +/// LLCP PDU lengths (including op_code) +enum co_llcp_length +{ + LLCP_CON_UPDATE_IND_LEN = 12, + LLCP_CHANNEL_MAP_IND_LEN = 8, + LLCP_TERM_IND_LEN = 2, + LLCP_ENC_REQ_LEN = 23, + LLCP_ENC_RSP_LEN = 13, + LLCP_ST_ENC_REQ_LEN = 1, + LLCP_ST_ENC_RSP_LEN = 1, + LLCP_UNKN_RSP_LEN = 2, + LLCP_FEAT_REQ_LEN = 9, + LLCP_FEAT_RSP_LEN = 9, + LLCP_PA_ENC_REQ_LEN = 1, + LLCP_PA_ENC_RSP_LEN = 1, + LLCP_VERS_IND_LEN = 6, + LLCP_REJ_IND_LEN = 2, + LLCP_SLAVE_FEATURE_REQ_LEN = 9, + LLCP_REJECT_IND_EXT_LEN = 3, + LLCP_CON_PARAM_REQ_LEN = 24, + LLCP_CON_PARAM_RSP_LEN = 24, + LLCP_PING_REQ_LEN = 1, + LLCP_PING_RSP_LEN = 1, + LLCP_LENGTH_REQ_LEN = 9, + LLCP_LENGTH_RSP_LEN = 9, + LLCP_PHY_REQ_LEN = 3, + LLCP_PHY_RSP_LEN = 3, + LLCP_PHY_UPD_IND_LEN = 5, + LLCP_MIN_USED_CH_IND_LEN = 3, + LLCP_PDU_LENGTH_MAX = 34 +}; + +/// PDU lengths +enum co_pdu_length +{ + PDU_SCAN_REQ_LEN = 12, + PDU_CON_REQ_LEN = 34, + PDU_CON_RSP_LEN = 14, +}; + +/* + * MESSAGES + **************************************************************************************** + */ + +/// LLCP_CONNECTION_UPDATE_IND structure. +struct llcp_con_update_ind +{ + /// op_code + uint8_t op_code; + /// window size (units of 1.25 ms) + uint8_t win_size; + /// window offset (units of 1.25 ms) + uint16_t win_off; + /// interval (units of 1.25 ms) + uint16_t interv; + /// connection latency (unit of connection event) + uint16_t latency; + /// link supervision timeout (unit of 10 ms) + uint16_t timeout; + /// instant (unit of connection event) + uint16_t instant; +}; + +/// LLCP_CHANNEL_MAP_IND structure. +struct llcp_channel_map_ind +{ + /// op_code + uint8_t op_code; + /// channel mapping + struct le_chnl_map ch_map; + /// instant + uint16_t instant; +}; + +/// LLCP_TERMINATE_IND structure. +struct llcp_terminate_ind +{ + /// op_code + uint8_t op_code; + /// termination code + uint8_t err_code; +}; + +/// LLCP_ENC_REQ structure. +struct llcp_enc_req +{ + /// op_code + uint8_t op_code; + /// random value + struct rand_nb rand; + /// ediv + uint16_t ediv; + /// skdm + struct sess_k_div_x skdm; + /// ivm + struct init_vect ivm; +}; + +/// LLCP_ENC_RSP structure. +struct llcp_enc_rsp +{ + /// op_code + uint8_t op_code; + /// skds + struct sess_k_div_x skds; + /// ivs + struct init_vect ivs; +}; + +/// LLCP_START_ENC_REQ structure. +struct llcp_start_enc_req +{ + /// op_code + uint8_t op_code; +}; + +/// LLCP_START_ENC_RSP structure. +struct llcp_start_enc_rsp +{ + /// op_code + uint8_t op_code; +}; + +/// LLCP_UNKNOWN_RSP structure. +struct llcp_unknown_rsp +{ + /// op_code + uint8_t op_code; + /// unknown type + uint8_t unk_type; +}; + +/// LLCP_FEATURE_REQ structure. +struct llcp_feats_req +{ + /// op_code + uint8_t op_code; + /// le features + struct le_features feats; +}; + + +/// LLCP_FEATURE_RSP structure. +struct llcp_feats_rsp +{ + /// op_code + uint8_t op_code; + /// le features + struct le_features feats; +}; + +/// LLCP_PAUSE_ENC_REQ structure. +struct llcp_pause_enc_req +{ + /// op_code + uint8_t op_code; +}; + +/// LLCP_PAUSE_ENC_RSP structure. +struct llcp_pause_enc_rsp +{ + /// op_code + uint8_t op_code; +}; + +/// LLCP_VERS_IND structure +struct llcp_vers_ind +{ + /// op_code + uint8_t op_code; + /// version + uint8_t vers; + /// company id + uint16_t compid; + /// sub version + uint16_t subvers; +}; + +/// LLCP_REJECT_IND structure. +struct llcp_reject_ind +{ + /// op_code + uint8_t op_code; + /// reject reason + uint8_t err_code; +}; + +/// LLCP_SLAVE_FEATURE_REQ structure. +struct llcp_slave_feature_req +{ + /// op_code + uint8_t op_code; + /// le features + struct le_features feats; +}; + +/// LLCP_CONNECTION_PARAM_REQ structure. +struct llcp_con_param_req +{ + /// op_code + uint8_t op_code; + /// minimum value of connInterval (units of 1.25 ms) + uint16_t interval_min; + /// maximum value of connInterval (units of 1.25 ms) + uint16_t interval_max; + /// connSlaveLatency value (unit of connection event) + uint16_t latency; + /// connSupervisionTimeout value (unit of 10 ms) + uint16_t timeout; + /// preferred periodicity (units of 1.25 ms) + uint8_t pref_period; + /// ReferenceConnEventCount (unit of connection event) + uint16_t ref_con_event_count; + /// Offset0 (units of 1.25 ms) + uint16_t offset0; + /// Offset1 (units of 1.25 ms) + uint16_t offset1; + /// Offset2 (units of 1.25 ms) + uint16_t offset2; + /// Offset3 (units of 1.25 ms) + uint16_t offset3; + /// Offset4 (units of 1.25 ms) + uint16_t offset4; + /// Offset5 (units of 1.25 ms) + uint16_t offset5; +}; + +/// LLCP_CONNECTION_PARAM_RSP structure. +struct llcp_con_param_rsp +{ + /// op_code + uint8_t op_code; + /// minimum value of connInterval (units of 1.25 ms) + uint16_t interval_min; + /// maximum value of connInterval (units of 1.25 ms) + uint16_t interval_max; + /// connSlaveLatency value (unit of connection event) + uint16_t latency; + /// connSupervisionTimeout value (unit of 10 ms) + uint16_t timeout; + /// preferred periodicity (units of 1.25 ms) + uint8_t pref_period; + /// ReferenceConnEventCount (unit of connection event) + uint16_t ref_con_event_count; + /// Offset0 (units of 1.25 ms) + uint16_t offset0; + /// Offset1 (units of 1.25 ms) + uint16_t offset1; + /// Offset2 (units of 1.25 ms) + uint16_t offset2; + /// Offset3 (units of 1.25 ms) + uint16_t offset3; + /// Offset4 (units of 1.25 ms) + uint16_t offset4; + /// Offset5 (units of 1.25 ms) + uint16_t offset5; +}; + +/// LLCP_REJECT_IND structure. +struct llcp_reject_ind_ext +{ + /// op_code + uint8_t op_code; + /// rejected op_code + uint8_t rej_op_code; + /// reject reason + uint8_t err_code; +}; + +/// LLCP_PING_REQ structure. +struct llcp_ping_req +{ + /// op_code + uint8_t op_code; +}; + +/// LLCP_PING_RSP structure. +struct llcp_ping_rsp +{ + /// op_code + uint8_t op_code; +}; + +/// LLCP_LENGTH_REQ structure. +struct llcp_length_req +{ + /// op_code + uint8_t op_code; + /// The max size in reception (unit of byte) + uint16_t max_rx_octets; + /// The max time in reception (unit of microsecond) + uint16_t max_rx_time; + /// The max size in transmission (unit of byte) + uint16_t max_tx_octets; + /// The max time in transmission (unit of microsecond) + uint16_t max_tx_time; +}; + +/// LLCP_LENGTH_RSP structure. +struct llcp_length_rsp +{ + /// op_code + uint8_t op_code; + /// The max size in reception (unit of byte) + uint16_t max_rx_octets; + /// The max time in reception (unit of microsecond) + uint16_t max_rx_time; + /// The max size in transmission (unit of byte) + uint16_t max_tx_octets; + /// The max time in transmission (unit of microsecond) + uint16_t max_tx_time; +}; +/// LLCP_PHY_REQ structure. +struct llcp_phy_req +{ + /// op_code + uint8_t op_code; + /// Tx phy selection + uint8_t tx_phys; + /// Rx phy selection + uint8_t rx_phys; +}; + +/// LLCP_PHY_RSP structure. +struct llcp_phy_rsp +{ + /// op_code + uint8_t op_code; + /// Tx phy selection + uint8_t tx_phys; + /// Rx phy selection + uint8_t rx_phys; +}; + +/// LLCP_PHY_UPD_IND structure. +struct llcp_phy_upd_ind +{ + /// op_code + uint8_t op_code; + /// master to slave phy selected + uint8_t m_to_s_phy; + /// slave to master phy selected + uint8_t s_to_m_phy; + /// Instant + uint16_t instant; +}; + +/// LLCP_MIN_USED_CHANNELS_IND structure. +struct llcp_min_used_ch_ind +{ + /// op_code + uint8_t op_code; + /// PHY(s) for which the slave has a minimum number of used channels requirement + uint8_t phys; + /// minimum number of channels to be used on the specified PHY + uint8_t min_used_ch; +}; + +/// LLCP pdu format +union llcp_pdu +{ + /// op_code + uint8_t op_code; + + struct llcp_con_update_ind con_update_ind; + struct llcp_channel_map_ind channel_map_ind; + struct llcp_terminate_ind terminate_ind; + struct llcp_enc_req enc_req; + struct llcp_enc_rsp enc_rsp; + struct llcp_start_enc_req start_enc_req; + struct llcp_start_enc_rsp start_enc_rsp; + struct llcp_unknown_rsp unknown_rsp; + struct llcp_feats_req feats_req; + struct llcp_feats_rsp feats_rsp; + struct llcp_pause_enc_req pause_enc_req; + struct llcp_pause_enc_rsp pause_enc_rsp; + struct llcp_vers_ind vers_ind; + struct llcp_reject_ind reject_ind; + struct llcp_slave_feature_req slave_feature_req; + struct llcp_con_param_req con_param_req; + struct llcp_con_param_rsp con_param_rsp; + struct llcp_reject_ind_ext reject_ind_ext; + struct llcp_ping_req ping_req; + struct llcp_ping_rsp ping_rsp; + struct llcp_length_req length_req; + struct llcp_length_rsp length_rsp; + struct llcp_phy_req phy_req; + struct llcp_phy_rsp phy_rsp; + struct llcp_phy_upd_ind phy_upd_ind; +}; + +/// @} CO_BT +#endif // CO_LLCP_H_ diff --git a/services/ble_stack/common/api/co_lmp.h b/services/ble_stack/common/api/co_lmp.h new file mode 100644 index 0000000..84c9148 --- /dev/null +++ b/services/ble_stack/common/api/co_lmp.h @@ -0,0 +1,1225 @@ +#ifndef CO_LMP_H_ +#define CO_LMP_H_ + +/** + **************************************************************************************** + * @addtogroup CO_BT + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "co_bt.h" +/* + * DEFINES + **************************************************************************************** + */ + +//LMP Opcodes +#define LMP_NAME_REQ_OPCODE 1 +#define LMP_NAME_RES_OPCODE 2 +#define LMP_ACCEPTED_OPCODE 3 +#define LMP_NOT_ACCEPTED_OPCODE 4 +#define LMP_CLK_OFF_REQ_OPCODE 5 +#define LMP_CLK_OFF_RES_OPCODE 6 +#define LMP_DETACH_OPCODE 7 +#define LMP_INRAND_OPCODE 8 +#define LMP_COMBKEY_OPCODE 9 +#define LMP_UNITKEY_OPCODE 10 +#define LMP_AURAND_OPCODE 11 +#define LMP_SRES_OPCODE 12 +#define LMP_TEMPRAND_OPCODE 13 +#define LMP_TEMPKEY_OPCODE 14 +#define LMP_ENC_MODE_REQ_OPCODE 15 +#define LMP_ENC_KEY_SIZE_REQ_OPCODE 16 +#define LMP_START_ENC_REQ_OPCODE 17 +#define LMP_STOP_ENC_REQ_OPCODE 18 +#define LMP_SWITCH_REQ_OPCODE 19 +#define LMP_HOLD_OPCODE 20 +#define LMP_HOLD_REQ_OPCODE 21 +#define LMP_SNIFF_REQ_OPCODE 23 +#define LMP_UNSNIFF_REQ_OPCODE 24 +#define LMP_PARK_REQ_OPCODE 25 +#define LMP_SET_BSWIN_OPCODE 27 +#define LMP_MODIF_BEACON_OPCODE 28 +#define LMP_UNPARK_BD_REQ_OPCODE 29 +#define LMP_UNPARK_PM_REQ_OPCODE 30 +#define LMP_INCR_PWR_REQ_OPCODE 31 +#define LMP_DECR_PWR_REQ_OPCODE 32 +#define LMP_MAX_PWR_OPCODE 33 +#define LMP_MIN_PWR_OPCODE 34 +#define LMP_AUTO_RATE_OPCODE 35 +#define LMP_PREF_RATE_OPCODE 36 +#define LMP_VER_REQ_OPCODE 37 +#define LMP_VER_RES_OPCODE 38 +#define LMP_FEATS_REQ_OPCODE 39 +#define LMP_FEATS_RES_OPCODE 40 +#define LMP_QOS_OPCODE 41 +#define LMP_QOS_REQ_OPCODE 42 +#define LMP_SCO_LINK_REQ_OPCODE 43 +#define LMP_RMV_SCO_LINK_REQ_OPCODE 44 +#define LMP_MAX_SLOT_OPCODE 45 +#define LMP_MAX_SLOT_REQ_OPCODE 46 +#define LMP_TIMING_ACCU_REQ_OPCODE 47 +#define LMP_TIMING_ACCU_RES_OPCODE 48 +#define LMP_SETUP_CMP_OPCODE 49 +#define LMP_USE_SEMI_PERM_KEY_OPCODE 50 +#define LMP_HOST_CON_REQ_OPCODE 51 +#define LMP_SLOT_OFF_OPCODE 52 +#define LMP_PAGE_MODE_REQ_OPCODE 53 +#define LMP_PAGE_SCAN_MODE_REQ_OPCODE 54 +#define LMP_SUPV_TO_OPCODE 55 +#define LMP_TEST_ACTIVATE_OPCODE 56 +#define LMP_TEST_CTRL_OPCODE 57 +#define LMP_ENC_KEY_SIZE_MASK_REQ_OPCODE 58 +#define LMP_ENC_KEY_SIZE_MASK_RES_OPCODE 59 +#define LMP_SET_AFH_OPCODE 60 +#define LMP_ENCAPS_HDR_OPCODE 61 +#define LMP_ENCAPS_PAYL_OPCODE 62 +#define LMP_SP_CFM_OPCODE 63 +#define LMP_SP_NB_OPCODE 64 +#define LMP_DHKEY_CHK_OPCODE 65 +#define LMP_PAUSE_ENC_AES_REQ_OPCODE 66 + +#define LMP_ESC1_OPCODE 124 +#define LMP_ESC2_OPCODE 125 +#define LMP_ESC3_OPCODE 126 +#define LMP_ESC4_OPCODE 127 + +///LMP Escape 4 Extended Opcodes +#define LMP_ACCEPTED_EXT_EXTOPCODE 1 +#define LMP_NOT_ACCEPTED_EXT_EXTOPCODE 2 +#define LMP_FEATS_REQ_EXT_EXTOPCODE 3 +#define LMP_FEATS_RES_EXT_EXTOPCODE 4 +#define LMP_CLK_ADJ_EXTOPCODE 5 +#define LMP_CLK_ADJ_ACK_EXTOPCODE 6 +#define LMP_CLK_ADJ_REQ_EXTOPCODE 7 +#define LMP_PKT_TYPE_TBL_REQ_EXTOPCODE 11 +#define LMP_ESCO_LINK_REQ_EXTOPCODE 12 +#define LMP_RMV_ESCO_LINK_REQ_EXTOPCODE 13 +#define LMP_CH_CLASS_REQ_EXTOPCODE 16 +#define LMP_CH_CLASS_EXTOPCODE 17 +#define LMP_SSR_REQ_EXTOPCODE 21 +#define LMP_SSR_RES_EXTOPCODE 22 +#define LMP_PAUSE_ENC_REQ_EXTOPCODE 23 +#define LMP_RESUME_ENC_REQ_EXTOPCODE 24 +#define LMP_IO_CAP_REQ_EXTOPCODE 25 +#define LMP_IO_CAP_RES_EXTOPCODE 26 +#define LMP_NUM_COMPARISON_FAIL_EXTOPCODE 27 +#define LMP_PASSKEY_FAIL_EXTOPCODE 28 +#define LMP_OOB_FAIL_EXTOPCODE 29 +#define LMP_KEYPRESS_NOTIF_EXTOPCODE 30 +#define LMP_PWR_CTRL_REQ_EXTOPCODE 31 +#define LMP_PWR_CTRL_RES_EXTOPCODE 32 +#define LMP_PING_REQ_EXTOPCODE 33 +#define LMP_PING_RES_EXTOPCODE 34 + +/// PDU lengths (including opcode) +#define LMP_NAME_REQ_LEN 2 +#define LMP_NAME_RES_LEN 17 +#define LMP_ACCEPTED_LEN 2 +#define LMP_NOT_ACCEPTED_LEN 3 +#define LMP_CLK_OFF_REQ_LEN 1 +#define LMP_CLK_OFF_RES_LEN 3 +#define LMP_DETACH_LEN 2 +#define LMP_INRAND_LEN 17 +#define LMP_COMBKEY_LEN 17 +#define LMP_UNITKEY_LEN 17 +#define LMP_AURAND_LEN 17 +#define LMP_SRES_LEN 5 +#define LMP_TEMPRAND_LEN 17 +#define LMP_TEMPKEY_LEN 17 +#define LMP_ENC_MODE_REQ_LEN 2 +#define LMP_ENC_KEY_SIZE_REQ_LEN 2 +#define LMP_START_ENC_REQ_LEN 17 +#define LMP_STOP_ENC_REQ_LEN 1 +#define LMP_SWITCH_REQ_LEN 5 +#define LMP_HOLD_LEN 7 +#define LMP_HOLD_REQ_LEN 7 +#define LMP_SNIFF_REQ_LEN 10 +#define LMP_UNSNIFF_REQ_LEN 1 +#define LMP_PARK_REQ_LEN 17 +#define LMP_INCR_PWR_REQ_LEN 2 +#define LMP_DECR_PWR_REQ_LEN 2 +#define LMP_MAX_PWR_LEN 1 +#define LMP_MIN_PWR_LEN 1 +#define LMP_AUTO_RATE_LEN 1 +#define LMP_PREF_RATE_LEN 2 +#define LMP_VER_REQ_LEN 6 +#define LMP_VER_RES_LEN 6 +#define LMP_FEATS_REQ_LEN 9 +#define LMP_FEATS_RES_LEN 9 +#define LMP_QOS_LEN 4 +#define LMP_QOS_REQ_LEN 4 +#define LMP_SCO_LINK_REQ_LEN 7 +#define LMP_RMV_SCO_LINK_REQ_LEN 3 +#define LMP_MAX_SLOT_LEN 2 +#define LMP_MAX_SLOT_REQ_LEN 2 +#define LMP_TIMING_ACCU_REQ_LEN 1 +#define LMP_TIMING_ACCU_RES_LEN 3 +#define LMP_SETUP_CMP_LEN 1 +#define LMP_USE_SEMI_PERM_KEY_LEN 1 +#define LMP_HOST_CON_REQ_LEN 1 +#define LMP_SLOT_OFF_LEN 9 +#define LMP_PAGE_MODE_REQ_LEN 3 +#define LMP_PAGE_SCAN_MODE_REQ_LEN 3 +#define LMP_SUPV_TO_LEN 3 +#define LMP_TEST_ACTIVATE_LEN 1 +#define LMP_TEST_CTRL_LEN 10 +#define LMP_ENC_KEY_SIZE_MASK_REQ_LEN 1 +#define LMP_ENC_KEY_SIZE_MASK_RES_LEN 3 +#define LMP_SET_AFH_LEN 16 +#define LMP_ENCAPS_HDR_LEN 4 +#define LMP_ENCAPS_PAYL_LEN 17 +#define LMP_SP_CFM_LEN 17 +#define LMP_SP_NB_LEN 17 +#define LMP_DHKEY_CHK_LEN 17 +#define LMP_PAUSE_ENC_AES_REQ_LEN 17 + +/// LMP Escape 4 Extended PDU length (including opcode and ext opcode) +#define LMP_ACCEPTED_EXT_LEN 4 +#define LMP_NOT_ACCEPTED_EXT_LEN 5 +#define LMP_FEATS_REQ_EXT_LEN 12 +#define LMP_FEATS_RES_EXT_LEN 12 +#define LMP_CLK_ADJ_LEN 15 +#define LMP_CLK_ADJ_ACK_LEN 3 +#define LMP_CLK_ADJ_REQ_LEN 6 +#define LMP_PKT_TYPE_TBL_REQ_LEN 3 +#define LMP_ESCO_LINK_REQ_LEN 16 +#define LMP_RMV_ESCO_LINK_REQ_LEN 4 +#define LMP_CH_CLASS_REQ_LEN 7 +#define LMP_CH_CLASS_LEN 12 +#define LMP_SSR_REQ_LEN 9 +#define LMP_SSR_RES_LEN 9 +#define LMP_PAUSE_ENC_REQ_LEN 2 +#define LMP_RESUME_ENC_REQ_LEN 2 +#define LMP_IO_CAP_REQ_LEN 5 +#define LMP_IO_CAP_RES_LEN 5 +#define LMP_NUM_COMPARISON_FAIL_LEN 2 +#define LMP_PASSKEY_FAIL_LEN 2 +#define LMP_OOB_FAIL_LEN 2 +#define LMP_KEYPRESS_NOTIF_LEN 3 +#define LMP_PWR_CTRL_REQ_LEN 3 +#define LMP_PWR_CTRL_RES_LEN 3 +#define LMP_PING_REQ_LEN 2 +#define LMP_PING_RES_LEN 2 + +/// Maximum LMP PDU size (including opcode and ext opcode) +#define LMP_MAX_PDU_SIZE DM1_PACKET_SIZE + +/// Position of transaction ID in 1st byte +#define LMP_TR_ID_POS 0 +#define LMP_TR_ID_MASK 0x01 +/// Position of opcode in 1st byte +#define LMP_OPCODE_POS 1 +#define LMP_OPCODE_MASK 0xFE + +#define LMP_OPCODE(opcode, tr_id) (((opcode << LMP_OPCODE_POS) & LMP_OPCODE_MASK) | ((tr_id << LMP_TR_ID_POS) & LMP_TR_ID_MASK)) +/* + * MESSAGES + **************************************************************************************** + */ + +///LMP_name_req PDU structure +struct lmp_name_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Offset + uint8_t offset; +}; + +///LMP_name_res PDU structure +struct lmp_name_res +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Offset + uint8_t offset; + ///Name Length + uint8_t length; + ///Name Fragment + struct name_vect name_frag; +}; + +///LMP_accepted PDU structure +struct lmp_accepted +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Opcode of the original LMP + uint8_t orig_opcode; +}; + +///LMP_not_accepted PDU structure +struct lmp_not_accepted +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Opcode of the original LMP + uint8_t orig_opcode; + ///Reason for not accepting the PDU (error code) + uint8_t reason; +}; + +///LMP_clkoffset_req PDU structure +struct lmp_clk_off_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_clkoffset_res PDU structure +struct lmp_clk_off_res +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Clock Offset value + uint16_t clk_offset ; +}; + +///LMP_detach PDU structure +struct lmp_detach +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Reason to detach + uint8_t reason; +}; + +///LMP_in_rand PDU structure +struct lmp_inrand +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Random number + struct ltk random; +}; + +///LMP_comb_key PDU structure +struct lmp_combkey +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Random number + struct ltk random; +}; + +///LMP_unit_key PDU structure +struct lmp_unitkey +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Key + struct ltk key; +}; + +///LMP_au_rand PDU structure +struct lmp_aurand +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Random number + struct ltk random; +}; + +///LMP_sres PDU structure +struct lmp_sres +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Authentication Response + struct sres_nb Sres; +}; + +///LMP_temp_rand PDU structure +struct lmp_temprand +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Random number + struct ltk random; +}; + +///LMP_temp_key PDU structure +struct lmp_tempkey +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Key + struct ltk key; +}; + +///LMP_encryption_mode_req PDU structure +struct lmp_enc_mode_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Encryption Mode + uint8_t enc_mode; +}; + +///LMP_encryption_key_size_req PDU structure +struct lmp_enc_key_size_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Key Size + uint8_t key_size; +}; + +///LMP_start_encryption_req PDU structure +struct lmp_start_enc_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Random number + struct ltk random; +}; + +///LMP_stop_encryption_req PDU structure +struct lmp_stop_enc_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_switch_req PDU structure +struct lmp_switch_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Switch Instant + uint32_t switch_inst; +}; + +///LMP_sniff_req PDU structure +struct lmp_sniff_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Timing Control Flags + uint8_t flags; + ///Dsniff + uint16_t d_sniff; + ///Tsniff + uint16_t t_sniff; + ///Sniff attempt + uint16_t sniff_attempt; + ///Sniff Timeout + uint16_t sniff_to; +}; + +///LMP_unsniff_req PDU structure +struct lmp_unsniff_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_incr_power_req PDU structure +struct lmp_incr_pwr_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///For future use + uint8_t reserved; +}; + +///LMP_decr_power_req PDU structure +struct lmp_decr_pwr_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///For future use + uint8_t reserved; +}; + +///LMP_max_power PDU structure +struct lmp_max_pwr +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_min_power PDU structure +struct lmp_min_pwr +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_auto_rate PDU structure +struct lmp_auto_rate +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_preferred_rate PDU structure +struct lmp_pref_rate +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Data Rate + uint8_t rate; +}; + +///LMP_version_req PDU structure +struct lmp_ver_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Version number + uint8_t ver; + ///Company ID + uint16_t co_id; + ///Subversion number + uint16_t subver; +}; + +///LMP_version_res PDU structure +struct lmp_ver_res +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Version number + uint8_t ver; + ///Company ID + uint16_t co_id; + ///Subversion number + uint16_t subver; +}; + +///LMP_features_req PDU structure +struct lmp_feats_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Features + struct features feats; +}; + +///LMP_features_res PDU structure +struct lmp_feats_res +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Features + struct features feats; +}; + +///LMP_quality_of_service PDU structure +struct lmp_qos +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Poll interval + uint16_t poll_intv; + ///Nbc + uint8_t nbc; +}; + + +///LMP_quality_of_service_req PDU structure +struct lmp_qos_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Poll interval + uint16_t poll_intv; + ///Nbc + uint8_t nbc; +}; + +///LMP_SCO_link_req PDU structure +struct lmp_sco_link_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///SCO handle + uint8_t sco_hdl; + ///timing control flags + uint8_t flags; + ///Dsco + uint8_t d_sco; + ///Tsco + uint8_t t_sco; + ///SCO packet + uint8_t sco_pkt; + ///Air mode + uint8_t air_mode; +}; + +///LMP_remove_SCO_link_req PDU structure +struct lmp_rmv_sco_link_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///SCO handle + uint8_t sco_hdl; + ///Reason for its removal(error code) + uint8_t reason; +}; + +///LMP_max_slot PDU structure +struct lmp_max_slot +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Max slots + uint8_t max_slots; +}; + + +///LMP_max_slot_req PDU structure +struct lmp_max_slot_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Max slots + uint8_t max_slots; +}; + +///LMP_timing_accuracy_req PDU structure +struct lmp_timing_accu_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_timing_accuracy_res PDU structure +struct lmp_timing_accu_res +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Drift + uint8_t drift; + ///Jitter + uint8_t jitter; +}; + +///LMP_setup_complete PDU structure +struct lmp_setup_cmp +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_use_semi_permanent_key PDU structure +struct lmp_use_semi_perm_key +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_host_connection_req PDU structure +struct lmp_host_con_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_slot_offset PDU structure +struct lmp_slot_off +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Slot Offset + uint16_t slot_off; + ///BD Address + struct bd_addr addr; +}; + +///LMP_page_mode_req PDU structure +struct lmp_page_mode_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Paging scheme + uint8_t page_scheme; + ///Paging scheme settings + uint8_t page_stg; +}; + +///LMP_page_scan_mode_req PDU structure +struct lmp_page_scan_mode_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Paging scheme + uint8_t page_scheme; + ///Paging scheme settings + uint8_t page_stg; +}; + +///LMP_supervision_timeout PDU structure +struct lmp_supv_to +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Supervision Timeout + uint16_t supv_to; +}; + +///LMP_test_activate PDU structure +struct lmp_test_activate +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_test_control PDU structure +struct lmp_test_ctrl +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Test Scenario + uint8_t scenario; + ///Hopping Mode + uint8_t hop; + ///Tx frequency + uint8_t tx_freq; + ///Rx Frequency + uint8_t rx_freq; + ///Power Control Mode + uint8_t pwr_ctrl; + ///Poll period + uint8_t poll_period; + ///Packet type + uint8_t pkt_type; + ///length of test data + uint16_t data_len; +}; + +///LMP_encryption_key_size_mask_req PDU structure +struct lmp_enc_key_size_mask_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; +}; + +///LMP_encryption_key_size_mask_res PDU structure +struct lmp_enc_key_size_mask_res +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Encryption Key Size Mask + uint16_t mask; +}; + +///LMP_set_AFH PDU structure +struct lmp_set_afh +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///AFH Instant + uint32_t instant; + ///AFH Mode + uint8_t mode; + ///AFH channel map + struct chnl_map map; +}; + +///LMP_encapsulated_header PDU structure +struct lmp_encaps_hdr +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Encapsulated major type + uint8_t maj_type; + ///Encapsulated minor type + uint8_t min_type; + ///Encapsulated Payload Length + uint8_t payl_len; +}; + +///LMP_encapsulated_payload PDU structure +struct lmp_encaps_payl +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Encapsulated data + struct byte16 data; +}; + +///LMP_Simple_Pairing_Confirm PDU structure +struct lmp_sp_cfm +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Commitment Value + struct byte16 commitment_val ; +}; + +///LMP_Simple_Pairing_Number PDU structure +struct lmp_sp_nb +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///nonce Value + struct byte16 nonce; +}; + +///LMP_DHkey_check PDU structure +struct lmp_dhkey_chk +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Confirmation Value + struct ltk cfm_val; +}; + +///LMP_pause_encryption_aes_req PDU structure +struct lmp_pause_enc_aes_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + /// Random Number + struct ltk rand; +}; + +/* + * Extended PDUs parameter structures - Escape 4 + ****************************************************************************************/ + +///LMP_accepted_ext PDU structure +struct lmp_accepted_ext +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Escape opcode of the original LMP + uint8_t orig_esc_opcode; + ///Extended opcode of the original LMP + uint8_t orig_ext_opcode; +}; + +///LMP_not_accepted_ext PDU structure +struct lmp_not_accepted_ext +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Escape opcode of the original LMP + uint8_t orig_esc_opcode; + ///Extended opcode of the original LMP + uint8_t orig_ext_opcode; + ///Reason + uint8_t reason; +}; + +///LMP_features_req_ext PDU structure +struct lmp_feats_req_ext +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Features page + uint8_t page; + ///Max supported page + uint8_t max_page; + ///Extended features + struct features ext_feats; +}; + +///LMP_features_res_ext PDU structure +struct lmp_feats_res_ext +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Features page + uint8_t page; + ///Max supported page + uint8_t max_page; + ///Extended features + struct features ext_feats; +}; + +///LMP_clk_adj PDU structure +struct lmp_clk_adj +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Coarse clock adjustment Event ID + uint8_t clk_adj_id; + ///Coarse clock adjustment instant + uint32_t clk_adj_instant; + ///Coarse clock adjustment intraslot alignment offset + int16_t clk_adj_us; + ///Coarse clock adjustment slot offset + uint8_t clk_adj_slots; + ///Coarse clock adjustment mode (before/after instant) + uint8_t clk_adj_mode; + ///Coarse clock adjustment PDU CLK instant + uint32_t clk_adj_clk; +}; + +///LMP_clk_adj_ack PDU structure +struct lmp_clk_adj_ack +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Coarse clock adjustment Event ID + uint8_t clk_adj_id; +}; + +///LMP_clk_adj_req PDU structure +struct lmp_clk_adj_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Coarse clock adjustment intraslot alignment offset + int16_t clk_adj_us; + ///Coarse clock adjustment slot offset + uint8_t clk_adj_slots; + ///Corase clock adjustment period + uint8_t clk_adj_period; +}; + +///LMP_packet_type_table_req PDU structure +struct lmp_pkt_type_tbl_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Packet Type table + uint8_t pkt_type_tbl; +}; + +///LMP_eSCO_link_req PDU structure +struct lmp_esco_link_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///eSCO handle + uint8_t esco_hdl; + ///eSCo LT Address + uint8_t esco_lt_addr; + ///timing control flags + uint8_t flags; + ///Desco + uint8_t d_esco; + ///t_esco + uint8_t t_esco; + ///Wesco + uint8_t w_esco; + ///eSCO packet type M2S + uint8_t m2s_pkt_type; + ///eSCO packet type S2M + uint8_t s2m_pkt_type; + ///Packet Length M2S + uint16_t m2s_pkt_len; + ///Packet Length S2m + uint16_t s2m_pkt_len; + ///Air Mode + uint8_t air_mode; + ///Negotiation state + uint8_t negt_st; +}; + +///LMP_remove_eSCO_link_req PDU structure +struct lmp_rmv_esco_link_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///eSCO handle + uint8_t esco_hdl; + ///Reason + uint8_t reason; +}; + +///LMP_channel_classification_req PDU structure +struct lmp_ch_class_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///AFH reporting mode + uint8_t rep_mode; + ///AFH min interval + uint16_t min_intv; + ///AFH max interval + uint16_t max_intv; +}; + +///LMP_channel_classification PDU structure +struct lmp_ch_class +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///AFh channel classification + struct chnl_map ch_class; +}; + +///LMP_sniff_subrating_req PDU structure +struct lmp_ssr_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Maximum sniff sub-rate + uint8_t max_subrate; + ///Minimum sniff mode timeout + uint16_t min_to; + ///Sniff sub-rating instant + uint32_t inst; +}; + +///LMP_sniff_subrating_res PDU structure +struct lmp_ssr_res +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Maximum sniff sub-rate + uint8_t max_subrate; + ///Minimum sniff mode timeout + uint16_t min_to; + ///Sniff sub-rating instant + uint32_t inst; +}; + +///LMP_pause_encryption_req PDU structure +struct lmp_pause_enc_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; +}; + +///LMP_resume_encryption_req PDU structure +struct lmp_resume_enc_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; +}; + +///LMP_IO_capability_req PDU structure +struct lmp_io_cap_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///IO Capabilities + uint8_t io_cap; + /// OOB Authentication data + uint8_t oob_auth_data; + ///Authentication requirements + uint8_t auth_req; +}; + + +///LMP_IO_capability_res PDU structure +struct lmp_io_cap_res +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///IO Capabilities + uint8_t io_cap; + /// OOB Authentication data + uint8_t oob_auth_data; + ///Authentication requirements + uint8_t auth_req; +}; + +///LMP_numeric_comparison_failed PDU structure +struct lmp_num_comparison_fail +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; +}; + +///LMP_passkey_failed PDU structure +struct lmp_passkey_fail +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; +}; + +///LMP_oob_failed PDU structure +struct lmp_oob_fail +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; +}; + +///LMP_keypress_notification PDU structure +struct lmp_keypress_notif +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Notification Type + uint8_t type; +}; + +///LMP_power_control_req PDU structure +struct lmp_pwr_ctrl_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Power adjustment request + uint8_t pwr_adj; + +}; + +///LMP_power_control_res PDU structure +struct lmp_pwr_ctrl_res +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; + ///Power adjustment response + uint8_t pwr_adj; +}; + +/// LMP_ping_req PDU structure +struct lmp_ping_req +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; +}; + +/// LMP_ping_res PDU structure +struct lmp_ping_res +{ + ///Opcode (including transaction ID) + uint8_t opcode; + ///Extended opcode + uint8_t ext_opcode; +}; + +/// Union of all the LMP message structures +union lmp_pdu_data +{ + struct lmp_name_req name_req ; + struct lmp_name_res name_res ; + struct lmp_accepted accepted ; + struct lmp_not_accepted not_accepted ; + struct lmp_clk_off_req clk_off_req ; + struct lmp_clk_off_res clk_off_res ; + struct lmp_detach detach ; + struct lmp_inrand inrand ; + struct lmp_combkey combkey ; + struct lmp_unitkey unitkey ; + struct lmp_aurand aurand ; + struct lmp_sres sres ; + struct lmp_temprand temprand ; + struct lmp_tempkey tempkey ; + struct lmp_enc_mode_req enc_mode_req ; + struct lmp_enc_key_size_req enc_key_size_req ; + struct lmp_start_enc_req start_enc_req ; + struct lmp_stop_enc_req stop_enc_req ; + struct lmp_switch_req switch_req ; + struct lmp_sniff_req sniff_req ; + struct lmp_unsniff_req unsniff_req ; + struct lmp_incr_pwr_req incr_pwr_req ; + struct lmp_decr_pwr_req decr_pwr_req ; + struct lmp_max_pwr max_pwr ; + struct lmp_min_pwr min_pwr ; + struct lmp_auto_rate auto_rate ; + struct lmp_pref_rate pref_rate ; + struct lmp_ver_req ver_req ; + struct lmp_ver_res ver_res ; + struct lmp_feats_req feats_req ; + struct lmp_feats_res feats_res ; + struct lmp_clk_adj clk_adj ; + struct lmp_clk_adj_ack clk_adj_ack ; + struct lmp_clk_adj_req clk_adj_req ; + struct lmp_qos qos ; + struct lmp_qos_req qos_req ; + struct lmp_sco_link_req sco_link_req ; + struct lmp_rmv_sco_link_req rmv_sco_link_req ; + struct lmp_max_slot max_slot ; + struct lmp_max_slot_req max_slot_req ; + struct lmp_timing_accu_req timing_accu_req ; + struct lmp_timing_accu_res timing_accu_res ; + struct lmp_setup_cmp setup_cmp ; + struct lmp_use_semi_perm_key use_semi_perm_key ; + struct lmp_host_con_req host_con_req ; + struct lmp_slot_off slot_off ; + struct lmp_page_mode_req page_mode_req ; + struct lmp_page_scan_mode_req page_scan_mode_req ; + struct lmp_supv_to supv_to ; + struct lmp_test_activate test_activate ; + struct lmp_test_ctrl test_ctrl ; + struct lmp_enc_key_size_mask_req enc_key_size_mask_req ; + struct lmp_enc_key_size_mask_res enc_key_size_mask_res ; + struct lmp_set_afh set_afh ; + struct lmp_encaps_hdr encaps_hdr ; + struct lmp_encaps_payl encaps_payl ; + struct lmp_sp_cfm sp_cfm ; + struct lmp_sp_nb sp_nb ; + struct lmp_dhkey_chk dhkey_chk ; + struct lmp_accepted_ext accepted_ext ; + struct lmp_not_accepted_ext not_accepted_ext ; + struct lmp_feats_req_ext feats_req_ext ; + struct lmp_feats_res_ext feats_res_ext ; + struct lmp_pkt_type_tbl_req pkt_type_tbl_req ; + struct lmp_esco_link_req esco_link_req ; + struct lmp_rmv_esco_link_req rmv_esco_link_req ; + struct lmp_ch_class_req ch_class_req ; + struct lmp_ch_class ch_class ; + struct lmp_ssr_req ssr_req ; + struct lmp_ssr_res ssr_res ; + struct lmp_pause_enc_req pause_enc_req ; + struct lmp_resume_enc_req resume_enc_req ; + struct lmp_io_cap_req io_cap_req ; + struct lmp_io_cap_res io_cap_res ; + struct lmp_num_comparison_fail num_comparison_fail ; + struct lmp_passkey_fail passkey_fail ; + struct lmp_oob_fail oob_fail ; + struct lmp_keypress_notif keypress_notif ; + struct lmp_pwr_ctrl_req pwr_ctrl_req ; + struct lmp_pwr_ctrl_res pwr_ctrl_res ; + struct lmp_ping_req ping_req ; + struct lmp_ping_res ping_res ; +}; + + +/// @} CO_BT +#endif // CO_LMP_H_ diff --git a/services/ble_stack/common/api/co_math.h b/services/ble_stack/common/api/co_math.h new file mode 100644 index 0000000..18e2903 --- /dev/null +++ b/services/ble_stack/common/api/co_math.h @@ -0,0 +1,193 @@ +#ifndef _CO_MATH_H_ +#define _CO_MATH_H_ + +/** + ***************************************************************************************** + * @defgroup CO_MATH Math functions + * @ingroup COMMON + * @brief Optimized math functions and other computations. + * + * @{ + ***************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include // standard integer definitions +#include // boolean definitions +#include // standard library +#include "compiler.h" // for __INLINE + +extern void srand (unsigned int seed); +extern int rand (void); + +/* + * MACROS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Return value with one bit set. + * + * @param[in] pos Position of the bit to set. + * + * @return Value with one bit set. There is no return type since this is a macro and this + * will be resolved by the compiler upon assignment to an l-value. + **************************************************************************************** + */ +#define CO_BIT(pos) (1UL<<(pos)) + +/** + **************************************************************************************** + * @brief Align val on the multiple of 4 equal or nearest higher. + * @param[in] val Value to align. + * @return Value aligned. + **************************************************************************************** + */ +#define CO_ALIGN4_HI(val) (((val)+3)&~3) + + +/** + **************************************************************************************** + * @brief Align val on the multiple of 4 equal or nearest lower. + * @param[in] val Value to align. + * @return Value aligned. + **************************************************************************************** + */ +#define CO_ALIGN4_LO(val) ((val)&~3) + +/** + **************************************************************************************** + * @brief Align val on the multiple of 2 equal or nearest higher. + * @param[in] val Value to align. + * @return Value aligned. + **************************************************************************************** + */ +#define CO_ALIGN2_HI(val) (((val)+1)&~1) + + +/** + **************************************************************************************** + * @brief Align val on the multiple of 2 equal or nearest lower. + * @param[in] val Value to align. + * @return Value aligned. + **************************************************************************************** + */ +#define CO_ALIGN2_LO(val) ((val)&~1) + + +/* + * FUNCTION DEFINTIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Count leading zeros. + * @param[in] val Value to count the number of leading zeros on. + * @return Number of leading zeros when value is written as 32 bits. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_clz(uint32_t val) +{ + #if defined(__arm__) + return __builtin_clz(val); + #elif defined(__GNUC__) + if (val == 0) + { + return 32; + } + return __builtin_clz(val); + #else + uint32_t i; + for (i = 0; i < 32; i++) + { + if (val & CO_BIT(31 - i)) + break; + } + return i; + #endif // defined(__arm__) +} + +/** + **************************************************************************************** + * @brief Function to initialize the random seed. + * @param[in] seed The seed number to use to generate the random sequence. + **************************************************************************************** + */ +__STATIC __INLINE void co_random_init(uint32_t seed) +{ + srand(seed); +} + +/** + **************************************************************************************** + * @brief Function to get an 8 bit random number. + * @return Random byte value. + **************************************************************************************** + */ +__STATIC __INLINE uint8_t co_rand_byte(void) +{ + return (uint8_t)(rand() & 0xFF); +} + +/** + **************************************************************************************** + * @brief Function to get an 16 bit random number. + * @return Random half word value. + **************************************************************************************** + */ +__STATIC __INLINE uint16_t co_rand_hword(void) +{ + return (uint16_t)(rand() & 0xFFFF); +} + +/** + **************************************************************************************** + * @brief Function to get an 32 bit random number. + * @return Random word value. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_rand_word(void) +{ + return (uint32_t)rand(); +} + +/** + **************************************************************************************** + * @brief Function to return the smallest of 2 unsigned 32 bits words. + * @return The smallest value. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_min(uint32_t a, uint32_t b) +{ + return a < b ? a : b; +} + +/** + **************************************************************************************** + * @brief Function to return the greatest of 2 unsigned 32 bits words. + * @return The greatest value. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_max(uint32_t a, uint32_t b) +{ + return a > b ? a : b; +} + +/** + **************************************************************************************** + * @brief Function to return the absolute value of a signed integer. + * @return The absolute value. + **************************************************************************************** + */ +__STATIC __INLINE int co_abs(int val) +{ + return val < 0 ? val*(-1) : val; +} + +/// @} CO_MATH + + +#endif // _CO_MATH_H_ diff --git a/services/ble_stack/common/api/co_utils.h b/services/ble_stack/common/api/co_utils.h new file mode 100644 index 0000000..9c70162 --- /dev/null +++ b/services/ble_stack/common/api/co_utils.h @@ -0,0 +1,501 @@ +#ifndef _CO_UTILS_H_ +#define _CO_UTILS_H_ + +/** + **************************************************************************************** + * @defgroup CO_UTILS Utilities + * @ingroup COMMON + * @brief Common utilities + * + * This module contains the common utilities functions and macros. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include // standard definitions +#include // standard definitions +#include "co_bt.h" // common bt definitions +#include "rwip_config.h" // SW configuration +#include "compiler.h" // for inline functions + + +/* + * MACRO DEFINITIONS + **************************************************************************************** + */ + +/// Number of '1' bits in a byte +#define NB_ONE_BITS(byte) (one_bits[byte & 0x0F] + one_bits[byte >> 4]) + +/// Get the number of elements within an array, give also number of rows in a 2-D array +#define ARRAY_LEN(array) (sizeof((array))/sizeof((array)[0])) + +/// Get the number of columns within a 2-D array +#define ARRAY_NB_COLUMNS(array) (sizeof((array[0]))/sizeof((array)[0][0])) + + +/// Macro for LMP message handler function declaration or definition +#define LMP_MSG_HANDLER(msg_name) __STATIC int lmp_##msg_name##_handler(struct lmp_##msg_name const *param, \ + ke_task_id_t const dest_id) +/// Macro for LMP message handler function declaration or definition +#define LLCP_MSG_HANDLER(msg_name) __STATIC int llcp_##msg_name##_handler(struct llcp_##msg_name const *param, \ + ke_task_id_t const dest_id) + +/// Macro for HCI message handler function declaration or definition (for multi-instantiated tasks) +#define HCI_CMD_HANDLER_C(cmd_name, param_struct) __STATIC int hci_##cmd_name##_cmd_handler(param_struct const *param, \ + ke_task_id_t const dest_id, \ + uint16_t opcode) + +/// Macro for HCI message handler function declaration or definition (with parameters) +#define HCI_CMD_HANDLER(cmd_name, param_struct) __STATIC int hci_##cmd_name##_cmd_handler(param_struct const *param, \ + uint16_t opcode) + +/// Macro for HCI message handler function declaration or definition (with parameters) +#define HCI_CMD_HANDLER_TAB(task) __STATIC const struct task##_hci_cmd_handler task##_hci_command_handler_tab[] = + + +/// MACRO to build a subversion field from the Minor and Release fields +#define CO_SUBVERSION_BUILD(minor, release) (((minor) << 8) | (release)) + + +/// Macro to get a structure from one of its structure field +//#define CONTAINER_OF(ptr, type, member) ((type *)( (char *)ptr - offsetof(type,member) )) + + +/* + * ENUMERATIONS DEFINITIONS + **************************************************************************************** + */ + +/// Status returned by generic packer-unpacker +enum CO_UTIL_PACK_STATUS +{ + CO_UTIL_PACK_OK, + CO_UTIL_PACK_IN_BUF_OVFLW, + CO_UTIL_PACK_OUT_BUF_OVFLW, + CO_UTIL_PACK_WRONG_FORMAT, + CO_UTIL_PACK_ERROR, +}; + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/* + * CONSTANT DECLARATIONS + **************************************************************************************** + */ + +/// Number of '1' bits in values from 0 to 15, used to fasten bit counting +extern const unsigned char one_bits[16]; + +/// Conversion table Sleep Clock Accuracy to PPM +extern const uint16_t co_sca2ppm[]; + +/// NULL BD address +extern const struct bd_addr co_null_bdaddr; + +/// Default BD address +extern const struct bd_addr co_default_bdaddr; + + +/* + * OPERATIONS ON BT CLOCK + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Clocks addition with 2 operands + * + * @param[in] clock_a 1st operand value (in BT slots) + * @param[in] clock_b 2nd operand value (in BT slots) + * @return result operation result (in BT slots) + **************************************************************************************** + */ +#define CLK_ADD_2(clock_a, clock_b) ((uint32_t)(((clock_a) + (clock_b)) & RWIP_MAX_CLOCK_TIME)) + +/** + **************************************************************************************** + * @brief Clocks addition with 3 operands + * + * @param[in] clock_a 1st operand value (in BT slots) + * @param[in] clock_b 2nd operand value (in BT slots) + * @param[in] clock_c 3rd operand value (in BT slots) + * @return result operation result (in BT slots) + **************************************************************************************** + */ +#define CLK_ADD_3(clock_a, clock_b, clock_c) ((uint32_t)(((clock_a) + (clock_b) + (clock_c)) & RWIP_MAX_CLOCK_TIME)) + +/** + **************************************************************************************** + * @brief Clocks subtraction + * + * @param[in] clock_a 1st operand value (in BT slots) + * @param[in] clock_b 2nd operand value (in BT slots) + * @return result operation result (in BT slots) + **************************************************************************************** + */ +#define CLK_SUB(clock_a, clock_b) ((uint32_t)(((clock_a) - (clock_b)) & RWIP_MAX_CLOCK_TIME)) + +/** + **************************************************************************************** + * @brief Clocks time difference + * + * @param[in] clock_a 1st operand value (in BT half-slots) + * @param[in] clock_b 2nd operand value (in BT half-slots) + * @return result return the time difference from clock A to clock B + * - result < 0 => clock_b is in the past + * - result == 0 => clock_a is equal to clock_b + * - result > 0 => clock_b is in the future + **************************************************************************************** + */ +#define CLK_DIFF(clock_a, clock_b) ( (CLK_SUB((clock_b), (clock_a)) > ((RWIP_MAX_CLOCK_TIME+1) >> 1)) ? \ + ((int32_t)((-CLK_SUB((clock_a), (clock_b))))) : ((int32_t)((CLK_SUB((clock_b), (clock_a))))) ) + + + +/// macro to extract a field from a value containing several fields +/// @param[in] __r bit field value +/// @param[in] __f field name +/// @return the value of the register masked and shifted +#define GETF(__r, __f) \ + (( (__r) & (__f##_MASK) ) >> (__f##_LSB)) + +/// macro to set a field value into a value containing several fields. +/// @param[in] __r bit field value +/// @param[in] __f field name +/// @param[in] __v value to put in field +#define SETF(__r, __f, __v) \ + do { \ + ASSERT_INFO( ( ( ( (__v) << (__f##_LSB) ) & ( ~(__f##_MASK) ) ) ) == 0 ,(__f##_MASK), (__v)); \ + __r = (((__r) & ~(__f##_MASK)) | (__v) << (__f##_LSB)); \ + } while (0) + + + +/// macro to extract a bit field from a value containing several fields +/// @param[in] __r bit field value +/// @param[in] __b bit field name +/// @return the value of the register masked and shifted +#define GETB(__r, __b) \ + (( (__r) & (__b##_BIT) ) >> (__b##_POS)) + +/// macro to set a bit field value into a value containing several fields. +/// @param[in] __r bit field value +/// @param[in] __b bit field name +/// @param[in] __v value to put in field +#define SETB(__r, __b, __v) \ + do { \ + ASSERT_ERR( ( ( ( (__v) << (__b##_POS) ) & ( ~(__b##_BIT) ) ) ) == 0 ); \ + __r = (((__r) & ~(__b##_BIT)) | (__v) << (__b##_POS)); \ + } while (0) + +#if (BLE_EMB_PRESENT) +/** + ****************************************************************************** + * @brief Compare 2 BLE instants (connection event counter) + * @param[in] instant_a 1st operand value (connection event counter) + * @param[in] instant_b 2nd operand value (connection event counter) + * @return result True: B is greater or equal to A | False: B is smaller than A + ****************************************************************************** + */ +#define CO_BLE_INSTANT_PASSED(instant_a, instant_b) ((uint16_t)(instant_b - instant_a) < 32767) +#endif //BLE_EMB_PRESENT + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Read an aligned 32 bit word. + * @param[in] ptr32 The address of the first byte of the 32 bit word. + * @return The 32 bit value. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_read32(void const *ptr32) +{ + return *((uint32_t*)ptr32); +} + +/** + **************************************************************************************** + * @brief Read an aligned 16 bits word. + * @param[in] ptr16 The address of the first byte of the 16 bits word. + * @return The 16 bits value. + **************************************************************************************** + */ +__STATIC __INLINE uint16_t co_read16(void const *ptr16) +{ + return *((uint16_t*)ptr16); +} + +/** + **************************************************************************************** + * @brief Write an aligned 32 bits word. + * @param[in] ptr32 The address of the first byte of the 32 bits word. + * @param[in] value The value to write. + **************************************************************************************** + */ +__STATIC __INLINE void co_write32(void const *ptr32, uint32_t value) +{ + *(uint32_t*)ptr32 = value; +} + +/** + **************************************************************************************** + * @brief Write an aligned 16 bits word. + * @param[in] ptr16 The address of the first byte of the 16 bits word. + * @param[in] value The value to write. + **************************************************************************************** + */ +__STATIC __INLINE void co_write16(void const *ptr16, uint32_t value) +{ + *(uint16_t*)ptr16 = value; +} + +/** + **************************************************************************************** + * @brief Write a 8 bits word. + * @param[in] ptr8 The address of the first byte of the 8 bits word. + * @param[in] value The value to write. + **************************************************************************************** + */ +__STATIC __INLINE void co_write8(void const *ptr8, uint32_t value) +{ + *(uint8_t*)ptr8 = value; +} + +/** + **************************************************************************************** + * @brief Read a packed 16 bits word. + * @param[in] ptr16 The address of the first byte of the 16 bits word. + * @return The 16 bits value. + **************************************************************************************** + */ +__STATIC __INLINE uint16_t co_read16p(void const *ptr16) +{ + uint16_t value = ((uint8_t *)ptr16)[0] | ((uint8_t *)ptr16)[1] << 8; + return value; +} + +/** + **************************************************************************************** + * @brief Read a packed 24 bits word. + * @param[in] ptr24 The address of the first byte of the 24 bits word. + * @return The 24 bits value. + **************************************************************************************** + */ + +__STATIC __INLINE uint32_t co_read24p(void const *ptr24) +{ + uint16_t addr_l, addr_h; + addr_l = co_read16p(ptr24); + addr_h = *((uint8_t *)ptr24 + 2) & 0x00FF; + return ((uint32_t)addr_l | (uint32_t)addr_h << 16); +} + +/** + **************************************************************************************** + * @brief Write a packed 24 bits word. + * @param[in] ptr24 The address of the first byte of the 24 bits word. + * @param[in] value The value to write. + **************************************************************************************** + */ + +__STATIC __INLINE void co_write24p(void const *ptr24, uint32_t value) +{ + uint8_t *ptr=(uint8_t*)ptr24; + + *ptr++ = (uint8_t)(value&0xff); + *ptr++ = (uint8_t)((value&0xff00)>>8); + *ptr++ = (uint8_t)((value&0xff0000)>>16); +} + +/** + **************************************************************************************** + * @brief Read a packed 32 bits word. + * @param[in] ptr32 The address of the first byte of the 32 bits word. + * @return The 32 bits value. + **************************************************************************************** + */ +__STATIC __INLINE uint32_t co_read32p(void const *ptr32) +{ + uint16_t addr_l, addr_h; + addr_l = co_read16p(ptr32); + addr_h = co_read16p((uint8_t *)ptr32 + 2); + return ((uint32_t)addr_l | (uint32_t)addr_h << 16); +} +/** + **************************************************************************************** + * @brief Write a packed 32 bits word. + * @param[in] ptr32 The address of the first byte of the 32 bits word. + * @param[in] value The value to write. + **************************************************************************************** + */ +__STATIC __INLINE void co_write32p(void const *ptr32, uint32_t value) +{ + uint8_t *ptr=(uint8_t*)ptr32; + + *ptr++ = (uint8_t)(value&0xff); + *ptr++ = (uint8_t)((value&0xff00)>>8); + *ptr++ = (uint8_t)((value&0xff0000)>>16); + *ptr = (uint8_t)((value&0xff000000)>>24); +} + +/** + **************************************************************************************** + * @brief Write a packed 16 bits word. + * @param[in] ptr16 The address of the first byte of the 16 bits word. + * @param[in] value The value to write. + **************************************************************************************** + */ +__STATIC __INLINE void co_write16p(void const *ptr16, uint16_t value) +{ + uint8_t *ptr=(uint8_t*)ptr16; + + *ptr++ = value&0xff; + *ptr = (value&0xff00)>>8; +} + +#if RW_DEBUG +/** + **************************************************************************************** + * @brief Convert bytes to hexadecimal string + * + * @param[out] dest Pointer to the destination string (must be 2x longer than input table) + * @param[in] src Pointer to the bytes table + * @param[in] nb_bytes Number of bytes to display in the string + **************************************************************************************** + */ +void co_bytes_to_string(char* dest, uint8_t* src, uint8_t nb_bytes); +#endif //RW_DEBUG + +/** + **************************************************************************************** + * @brief Compares two Bluetooth device addresses + * + * This function checks if the two bd address are equal. + * + * @param[in] bd_address1 Pointer on the first bd address to be compared. + * @param[in] bd_address2 Pointer on the second bd address to be compared. + * + * @return result of the comparison (true: equal | false: different). + **************************************************************************************** + */ +bool co_bdaddr_compare(struct bd_addr const *bd_address1, struct bd_addr const *bd_address2); + +#if (BLE_EMB_PRESENT) +/** + ****************************************************************************** + * @brief Count the number of good channels in a LE map + * @param[in] map Channel Map (bit fields for the 40 BT RF channels) + * @return Number of good channels + ****************************************************************************** + */ +uint8_t co_nb_good_le_channels(const struct le_chnl_map* map); +#endif //BLE_EMB_PRESENT + +#if (BT_EMB_PRESENT) + +/** + ****************************************************************************** + * @brief Convert an duration in baseband slot to a duration in number of ticks. + * @param[in] slot_cnt Duration in number of baseband slot + * @return Duration (in number of ticks). + ****************************************************************************** + */ +uint32_t co_slot_to_duration(uint16_t slot_cnt); + +/** + ****************************************************************************** + * @brief Count the number of good channels in a map + * @param[in] map Channel Map (bit fields for the 79 BT RF channels) + * @return Number of good channels + ****************************************************************************** + */ +uint8_t co_nb_good_channels(const struct chnl_map* map); + +#endif //BT_EMB_PRESENT + +/** + **************************************************************************************** + * @brief Pack parameters from a C structure to a packed buffer + * + * This function packs parameters according to a specific format. It takes care of the + * endianess, padding, required by the compiler. + * + * Format strings are the mechanism used to specify the expected layout when packing and unpacking data. They are built + * up from Format Characters, which specify the type of data being packed/unpacked. + * - B : byte - 8bits value + * - H : word - 16bits value + * - L : long - 32-bits value + * - XXB: table of several bytes, where XX is the byte number, in decimal + * + * Example: "BBLH12BL" => 1 byte | 1 byte | 1 long | 1 short | 12-bytes table | 1 long + * + * Note: the function works in the same buffer + * + * @param[out] out Output Data Buffer + * @param[in] in Input Data Buffer + * @param[out] out_len Output size of packed data (in bytes) + * @param[in] in_len Input buffer size (in bytes) + * @param[in] format Parameters format + * + * @return Status of the packing operation + ***************************************************************************************** + */ +enum CO_UTIL_PACK_STATUS co_util_pack(uint8_t* out, uint8_t* in, uint16_t* out_len, uint16_t in_len, const char* format); + +/** + **************************************************************************************** + * @brief Unpack parameters from an unpacked buffer to a C structure + * + * This function unpacks parameters according to a specific format. It takes care of the + * endianess, padding, required by the compiler. + * + * Format strings are the mechanism used to specify the expected layout when packing and unpacking data. They are built + * up from Format Characters, which specify the type of data being packed/unpacked. + * - B : byte - 8bits value + * - H : word - 16bits value + * - L : long - 32-bits value + * - XXB: table of several bytes, where XX is the byte number, in decimal + * + * Example: "BBLH12BL" => 1 byte | 1 byte | 1 long | 1 short | 12-bytes table | 1 long + * + * Note: the output buffer provided must be large enough to contain the unpacked data. + * Note2: if a NULL output buffer is provided, the function does not copy the unpacked parameters. It still parses the + * format string and input buffer to return the number of unpacked bytes. Can be used to compute the expected unpacked + * buffer size. + * + * @param[out] out Unpacked parameters buffer + * @param[in] in Packed parameters buffer + * @param[inout] out_len Input: buffer size / Output: size of unpacked data (in bytes) + * @param[in] in_len Size of the packed data (in bytes) + * @param[in] format Parameters format + * + * @return Status of the unpacking operation + ***************************************************************************************** + */ +enum CO_UTIL_PACK_STATUS co_util_unpack(uint8_t* out, uint8_t* in, uint16_t* out_len, uint16_t in_len, const char* format); + +/// @} CO_UTILS + +#endif // _CO_UTILS_H_ diff --git a/services/ble_stack/common/api/co_version.h b/services/ble_stack/common/api/co_version.h new file mode 100644 index 0000000..4ab7994 --- /dev/null +++ b/services/ble_stack/common/api/co_version.h @@ -0,0 +1,33 @@ +#ifndef _CO_VERSION_H_ +#define _CO_VERSION_H_ +/** + **************************************************************************************** + * @defgroup CO_VERSION Version Defines + * @ingroup COMMON + * + * @brief Bluetooth Controller Version definitions. + * + * @{ + **************************************************************************************** + */ +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" // SW configuration options + +/// RWBT SW Major Version +#define RWBT_SW_VERSION_MAJOR (RW_BT50_VERSION) +/// RWBT SW Minor Version +#define RWBT_SW_VERSION_MINOR 0 +/// RWBT SW Build Version +#define RWBT_SW_VERSION_BUILD 3 + +/// RWBT SW Major Version +#define RWBT_SW_VERSION_SUB_BUILD 0 + + +/// @} CO_VERSION + + +#endif // _CO_VERSION_H_ diff --git a/services/ble_stack/common/api/lePhone_rw_ble_error.txt b/services/ble_stack/common/api/lePhone_rw_ble_error.txt new file mode 100644 index 0000000..a6d5d54 --- /dev/null +++ b/services/ble_stack/common/api/lePhone_rw_ble_error.txt @@ -0,0 +1,370 @@ +[RX]: +04 3e 13 01 00 00 00 01 01 7e dd 73 45 f9 4c 20 00 00 00 d0 07 01 +[BLE_HCI]: Func: HciProcessEvent, Line: 82 event: 62 +[BLE]: Func: MeHandleEvents, Line: 2458 + +[BLE]: bridge_hci_ble_event line: 294 ++++ + +3e 13 01 00 00 00 01 01 7e dd 73 45 f9 4c 20 00 00 00 d0 07 01 +[BLE]: Func: bridge_hci_ble_event, Line: 313 len: 15 +[BLE]: Func: bridge_hci_ble_event, Line: 317 len: 13, code: 3e +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 19 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: bridge_hci_ble_event line: 341 ---- + +[BLE_GAPM]: Func: gapm_hci_handler, Line: 400 msgid: 2052 +[BLE]: gapm_setup_conn line: 2120 ++++ + +[BLE]: gapm_con_create line: 575 ++++ + +[BLE]: gapm_get_requester line: 497 ++++ + +[BLE_GAPM]: Func: gapm_get_requester, Line: 505 msg->src_id: 0 +[BLE]: gapm_get_requester line: 508 ---- + +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 16 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: l2cc_create line: 106 ++++ + +[BLE]: l2cc_create line: 140 ---- + +[BLE]: htpt_create line: 176 ++++ + +[BLE]: htpt_create line: 182 ---- + +[BLE]: gapm_con_create line: 624 ---- + +[BLE]: gapm_update_air_op_state line: 1968 ++++ + +[BLE]: gapm_update_adv_op_state line: 631 ++++ + +[BLE_GAPM]: Func: gapm_update_adv_op_state, Line: 633 state: 13 +[BLE]: gapm_update_adv_op_state line: 783 ---- + +[BLE]: gapm_send_complete_evt line: 518 ++++ + +[BLE_GAPM]: Func: gapm_send_complete_evt, Line: 519 cmp_evt->operation: 13, op_type: 1 +[BLE]: gapm_get_requester line: 497 ++++ + +[BLE_GAPM]: Func: gapm_get_requester, Line: 505 msg->src_id: 0 +[BLE]: gapm_get_requester line: 508 ---- + +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 2 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: gapm_operation_cleanup line: 132 ++++ + +[BLE]: gapm_update_state line: 831 ++++ + +[BLE_GAPM]: Func: gapm_update_state, Line: 833 old_state 0, operation: 1, busy: 0 + +[BLE]: gapm_update_state line: 849 ---- + +[BLE]: gapm_operation_cleanup line: 173 ---- + +[BLE]: gapm_send_complete_evt line: 544 ---- + +[BLE]: gapm_setup_conn line: 2162 ---- + +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 44 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: gapm_cmp_evt_handler line: 222 ++++ + +[BLE_APP]: Func: gapm_cmp_evt_handler, Line: 224 param->operation: 13 +[BLE]: gapm_cmp_evt_handler line: 331 ---- + +[BLE]: gapm_con_enable line: 632 ++++ + +[BLE]: gapm_con_enable line: 641 ---- + +[RX]: +02 00 20 0b 00 07 00 04 00 10 01 00 ff ff 00 28 +[BLE]: bridge_hcif_recv_acl line: 376 ++++ + +[BLE_HCI]: Func: hci_acl_rx_data_received, Line: 1783 conhdl: 0, idx: 0 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 8 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: bridge_hcif_recv_acl line: 382 ---- + +[BLE]: hci_ble_acl_data_rx_handler line: 507 ++++ + +[BLE_L2C]: Func: hci_ble_acl_data_rx_handler, Line: 542 pb_flag: 2 +[BLE]: l2cc_pdu_header_check line: 1069 ++++ + +00 20 0b 00 07 +[BLE_L2C]: Func: l2cc_pdu_header_check, Line: 1103 cid: 11 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 74 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: hci_ble_acl_data_rx_handler line: 671 ---- + +[BLE]: l2cc_pdu_recv_ind_handler line: 1168 ++++ + +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 74 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: l2cc_pdu_recv_ind_handler line: 1236 ++++ + +[BLE]: l2cc_pdu_send_cmd_handler line: 221 ++++ + +[BLE]: l2cm_tx_status line: 132 ++++ + +[BLE]: l2cm_tx_status line: 154 ---- + +[BLE]: l2cc_pdu_send_cmd_handler line: 249 ---- + +[BLE]: l2cm_l2cap_tx_handler line: 50 ++++ + +[BLE]: l2cc_data_send line: 353 ++++ + +[BLE_L2C]: Func: l2cc_data_send, Line: 354 conidx: 0, nb_buffer: 6 +[BLE_L2C]: Func: l2cc_data_send, Line: 390 L2CC_PDU_SEND_CMD: 2577, pkt->id: 2577 +[BLE_L2C]: Func: l2cc_pdu_pack, Line: 440 p_pdu->chan_id: 0005, code: 1 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 6 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 8 +[BLE]: hci_send_2_controller line: 938 ++++ + +[BLE]: hci_tl_send line: 1201 ++++ + +[BLE]: hci_tx_trigger line: 1181 ++++ + +[BLE]: hci_tx_start line: 835 ++++ + +[TX2]: +02 00 00 0e 00 0a 00 05 00 01 00 06 00 02 00 0b 00 00 00 +[BLE_HCI]: Func: bridge_hcif_send_acl, Line: 409 ****** bytes_sent: 0 , bytes_to_send: 18****** +[BLE]: hci_tx_trigger line: 1190 ---- + +[BLE]: l2cm_tx_status line: 132 ++++ + +[BLE]: l2cm_tx_status line: 154 ---- + +[BLE]: l2cc_data_send line: 612 ---- + +[BLE]: l2cm_l2cap_tx_handler line: 74 ---- + +[RX]: +04 13 05 01 00 00 01 00 +[BLE_HCI]: Func: HciProcessEvent, Line: 82 event: 19 +[BLE]: Func: HciProcessEvent, Line: 92 + +[BLE]: bridge_hci_ble_event line: 294 ++++ + +13 05 01 00 00 01 00 +[BLE]: Func: bridge_hci_ble_event, Line: 313 len: 07 +[BLE]: Func: bridge_hci_ble_event, Line: 317 len: 05, code: 13 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 6 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: bridge_hci_ble_event line: 341 ---- + +[BLE]: hci_nb_cmp_pkts_evt_handler line: 454 ++++ + +[BLE]: hci_nb_cmp_pkts_evt_handler line: 478 ---- + +[TX]: +01 35 0c 05 01 00 00 01 00 +[RX]: +04 3e 0a 03 00 00 00 06 00 00 00 d0 07 +[BLE_HCI]: Func: HciProcessEvent, Line: 82 event: 62 +[BLE]: Func: MeHandleEvents, Line: 2458 + +[BLE]: bridge_hci_ble_event line: 294 ++++ + +3e 0a 03 00 00 00 06 00 00 00 d0 07 +[BLE]: Func: bridge_hci_ble_event, Line: 313 len: 0c +[BLE]: Func: bridge_hci_ble_event, Line: 317 len: 0a, code: 3e +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 10 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: bridge_hci_ble_event line: 341 ---- + +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 6 +[BLE]: ke_msg_send line: 72 ++++ + +[RX]: +02 00 20 0b 00 07 00 04 00 10 01 00 ff ff 00 28 +[BLE]: bridge_hcif_recv_acl line: 376 ++++ + +[BLE_HCI]: Func: hci_acl_rx_data_received, Line: 1783 conhdl: 0, idx: 0 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 8 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: bridge_hcif_recv_acl line: 382 ---- + +[BLE]: hci_ble_acl_data_rx_handler line: 507 ++++ + +[BLE_L2C]: Func: hci_ble_acl_data_rx_handler, Line: 542 pb_flag: 2 +[BLE]: l2cc_pdu_header_check line: 1069 ++++ + +00 20 0b 00 07 +[BLE_L2C]: Func: l2cc_pdu_header_check, Line: 1103 cid: 11 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 74 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: hci_ble_acl_data_rx_handler line: 671 ---- + +[BLE]: l2cc_pdu_recv_ind_handler line: 1168 ++++ + +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 74 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: l2cc_pdu_recv_ind_handler line: 1236 ++++ + +[BLE]: l2cc_pdu_send_cmd_handler line: 221 ++++ + +[BLE]: l2cm_tx_status line: 132 ++++ + +[BLE]: l2cm_tx_status line: 154 ---- + +[BLE]: l2cc_pdu_send_cmd_handler line: 249 ---- + +[BLE]: l2cm_l2cap_tx_handler line: 50 ++++ + +[BLE]: l2cc_data_send line: 353 ++++ + +[BLE_L2C]: Func: l2cc_data_send, Line: 354 conidx: 0, nb_buffer: 6 +[BLE_L2C]: Func: l2cc_data_send, Line: 390 L2CC_PDU_SEND_CMD: 2577, pkt->id: 2577 +[BLE_L2C]: Func: l2cc_pdu_pack, Line: 440 p_pdu->chan_id: 0005, code: 1 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 6 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 8 +[BLE]: hci_send_2_controller line: 938 ++++ + +[BLE]: hci_tl_send line: 1201 ++++ + +[BLE]: hci_tx_trigger line: 1181 ++++ + +[BLE]: hci_tx_start line: 835 ++++ + +[TX2]: +02 00 00 0e 00 0a 00 05 00 01 00 06 00 02 00 0b 00 00 00 +[BLE_HCI]: Func: bridge_hcif_send_acl, Line: 409 ****** bytes_sent: 0 , bytes_to_send: 18****** +[BLE]: hci_tx_trigger line: 1190 ---- + +[BLE]: l2cm_tx_status line: 132 ++++ + +[BLE]: l2cm_tx_status line: 154 ---- + +[BLE]: l2cc_data_send line: 612 ---- + +[BLE]: l2cm_l2cap_tx_handler line: 74 ---- + +[RX]: +04 13 05 01 00 00 01 00 +[BLE_HCI]: Func: HciProcessEvent, Line: 82 event: 19 +[BLE]: Func: HciProcessEvent, Line: 92 + +[BLE]: bridge_hci_ble_event line: 294 ++++ + +13 05 01 00 00 01 00 +[BLE]: Func: bridge_hci_ble_event, Line: 313 len: 07 +[BLE]: Func: bridge_hci_ble_event, Line: 317 len: 05, code: 13 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 6 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: bridge_hci_ble_event line: 341 ---- + +[BLE]: hci_nb_cmp_pkts_evt_handler line: 454 ++++ + +[BLE]: hci_nb_cmp_pkts_evt_handler line: 478 ---- + +[TX]: +01 35 0c 05 01 00 00 01 00 +[RX]: +02 00 20 0b 00 07 00 04 00 10 01 00 ff ff 00 28 +[BLE]: bridge_hcif_recv_acl line: 376 ++++ + +[BLE_HCI]: Func: hci_acl_rx_data_received, Line: 1783 conhdl: 0, idx: 0 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 8 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: bridge_hcif_recv_acl line: 382 ---- + +[BLE]: hci_ble_acl_data_rx_handler line: 507 ++++ + +[BLE_L2C]: Func: hci_ble_acl_data_rx_handler, Line: 542 pb_flag: 2 +[BLE]: l2cc_pdu_header_check line: 1069 ++++ + +00 20 0b 00 07 +[BLE_L2C]: Func: l2cc_pdu_header_check, Line: 1103 cid: 11 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 74 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: hci_ble_acl_data_rx_handler line: 671 ---- + +[BLE]: l2cc_pdu_recv_ind_handler line: 1168 ++++ + +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 74 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: l2cc_pdu_recv_ind_handler line: 1236 ++++ + +[BLE]: l2cc_pdu_send_cmd_handler line: 221 ++++ + +[BLE]: l2cm_tx_status line: 132 ++++ + +[BLE]: l2cm_tx_status line: 154 ---- + +[BLE]: l2cc_pdu_send_cmd_handler line: 249 ---- + +[BLE]: l2cm_l2cap_tx_handler line: 50 ++++ + +[BLE]: l2cc_data_send line: 353 ++++ + +[BLE_L2C]: Func: l2cc_data_send, Line: 354 conidx: 0, nb_buffer: 6 +[BLE_L2C]: Func: l2cc_data_send, Line: 390 L2CC_PDU_SEND_CMD: 2577, pkt->id: 2577 +[BLE_L2C]: Func: l2cc_pdu_pack, Line: 440 p_pdu->chan_id: 0005, code: 1 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 6 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 8 +[BLE]: hci_send_2_controller line: 938 ++++ + +[BLE]: hci_tl_send line: 1201 ++++ + +[BLE]: hci_tx_trigger line: 1181 ++++ + +[BLE]: hci_tx_start line: 835 ++++ + +[TX2]: +02 00 00 0e 00 0a 00 05 00 01 00 06 00 02 00 0b 00 00 00 +[BLE_HCI]: Func: bridge_hcif_send_acl, Line: 409 ****** bytes_sent: 0 , bytes_to_send: 18****** +[BLE]: hci_tx_trigger line: 1190 ---- + +[BLE]: l2cm_tx_status line: 132 ++++ + +[BLE]: l2cm_tx_status line: 154 ---- + +[BLE]: l2cc_data_send line: 612 ---- + +[BLE]: l2cm_l2cap_tx_handler line: 74 ---- + +[RX]: +04 13 05 01 00 00 01 00 +[BLE_HCI]: Func: HciProcessEvent, Line: 82 event: 19 +[BLE]: Func: HciProcessEvent, Line: 92 + +[BLE]: bridge_hci_ble_event line: 294 ++++ + +13 05 01 00 00 01 00 +[BLE]: Func: bridge_hci_ble_event, Line: 313 len: 07 +[BLE]: Func: bridge_hci_ble_event, Line: 317 len: 05, code: 13 +[BLE]: Func: ke_msg_alloc, Line: 61 param_len: 6 +[BLE]: ke_msg_send line: 72 ++++ + +[BLE]: bridge_hci_ble_event line: 341 ---- + +[BLE]: hci_nb_cmp_pkts_evt_handler line: 454 ++++ + +[BLE]: hci_nb_cmp_pkts_evt_handler line: 478 ---- + +[TX]: +01 35 0c 05 01 00 00 01 00 diff --git a/services/ble_stack/dbg/api/dbg.h b/services/ble_stack/dbg/api/dbg.h new file mode 100644 index 0000000..c0c5612 --- /dev/null +++ b/services/ble_stack/dbg/api/dbg.h @@ -0,0 +1,53 @@ +#ifndef DBG_H_ +#define DBG_H_ + +/** +**************************************************************************************** +* @addtogroup DBG +* @ingroup CONTROLLER +* @brief Debug +* +* @{ +**************************************************************************************** +*/ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // stack configuration + +#include "dbg_swdiag.h" // sw profiling definitions + +#include "dbg_trc.h" // debug tracer definition + +/* + * FUNCTION DECLARATION + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the BT Debug task + * + * This function initializes the the DBG task + * + **************************************************************************************** + */ +void dbg_init(bool reset); + +/** + **************************************************************************************** + * @brief Send back to host status of platform reset request. + * + * @param status Reset error code + * + **************************************************************************************** + */ +void dbg_platform_reset_complete(uint32_t error); + +///@} DBG + +#endif // DBG_H_ diff --git a/services/ble_stack/dbg/api/dbg_mwsgen.h b/services/ble_stack/dbg/api/dbg_mwsgen.h new file mode 100644 index 0000000..4ab4110 --- /dev/null +++ b/services/ble_stack/dbg/api/dbg_mwsgen.h @@ -0,0 +1,199 @@ +#ifndef DBG_MWSGEN_H_ +#define DBG_MWSGEN_H_ + +/** + **************************************************************************************** + * @addtogroup DBGMWSGEN + * @ingroup DBG + * @brief Debug SW - MWS/WLAN Generator. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (RW_WLAN_COEX_TEST) || (RW_MWS_COEX_TEST) + +#include "reg_mwsgen.h" // MWS Event Generator register functions + +/* + * CONSTANT DEFINITIONS + **************************************************************************************** + */ + +#if (RW_WLAN_COEX) +/// WLAN coexistence disabled +#define DBG_COEX_WLAN_DISABLED 0 +/// WLAN coexistence enabled +#define DBG_COEX_WLAN_ENABLED 1 +#endif + +#if (RW_MWS_COEX) +/// MWS coexistence disabled +#define DBG_COEX_MWS_DISABLED 0 +/// MWS coexistence enabled +#define DBG_COEX_MWS_ENABLED 1 +#endif + +/* + * VARIABLE DECLARATION + **************************************************************************************** + */ +#if (RW_WLAN_COEX_TEST) +extern uint32_t dbg_coex_scenario; +#endif // RW_WLAN_COEX_TEST + +#if (RW_MWS_COEX_TEST) +extern uint32_t dbg_coex_scenario; +#endif // RW_MWS_COEX_TEST + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +#if (RW_MWS_COEX_TEST) +/** + **************************************************************************************** + * @brief Set the scenario for the unitary testing. + * + * @param[in] scenario Scenario type + * + * @return none + * + **************************************************************************************** + */ +uint8_t dbg_mwscoex_scen_set(uint32_t scenario); + +/** + **************************************************************************************** + * @brief Initialize and configure MWS event generator registers to be in MWS mode. + **************************************************************************************** + */ +void dbg_mwsgen_init(void); + +/** + **************************************************************************************** + * @brief Configure MWS generator + * + * @param[in] period Period of the mws signal (us) + * @param[in] duty_cycle Duration of the high level (us) + * @param[in] tx_act Duration of the tx activity (us) + * @param[in] rx_act Duration of the rx activity (us) + * + **************************************************************************************** + */ +void dbg_mwsgen_config(uint32_t period, uint32_t duty_cycle, uint32_t tx_act, uint32_t rx_act); + +/** + **************************************************************************************** + * @brief Configure the WLAN COEX mode for BT. + * + * @param[in] txmode + * @param[in] rxmode + * @param[in] txmsk + * @param[in] rxmsk + * @param[in] txfmsk + * @param[in] rxfmsk + * @param[in] scanfmsk + * @param[in] knudge + * + **************************************************************************************** + */ +void dbg_mws_config(uint8_t txmode, uint8_t rxmode, uint8_t txmsk, uint8_t rxmsk, uint8_t txfms, uint8_t rxfmsk, uint8_t scanfmsk, uint8_t knudge); + +/** + **************************************************************************************** + * @brief Start the MWS signal generator. + * + **************************************************************************************** + */ +void dbg_mwsgen_start(void); + +/** + **************************************************************************************** + * @brief Stop the MWS signal generator. + * + **************************************************************************************** + */ +void dbg_mwsgen_stop(void); +#endif // RW_MWS_COEX_TEST + +#if (RW_WLAN_COEX_TEST) +/** + **************************************************************************************** + * @brief Set the scenario for the unitary testing. + * + * @param[in] scenario Scenario type + * + * @return none + * + **************************************************************************************** + */ + +uint8_t dbg_wlcoex_scen_set(uint32_t scenario); + +/** + **************************************************************************************** + * @brief Initialize and configure MWS event generator registers to be in WLAN mode. + **************************************************************************************** + */ +void dbg_wlangen_init(void); + +/** + **************************************************************************************** + * @brief Set the period and duty cycle for the wlrxbsy signal. + * + * @param[in] period Period of the wlrxbsy signal (us) + * @param[in] duty_cycle Duration of the high level (us) + * @param[in] tx_act Duration of the tx activity (us) + * @param[in] rx_act Duration of the rx activity (us) + * + **************************************************************************************** + */ +void dbg_wlangen_config(uint32_t period, uint32_t duty_cycle, uint32_t tx_act, uint32_t rx_act); + +/** + **************************************************************************************** + * @brief Configure the WLAN COEX mode for BT. + * + * @param[in] txmode + * @param[in] rxmode + * @param[in] txmsk + * @param[in] rxmsk + * @param[in] txthr + * @param[in] rxthr + * @param[in] pduration + * @param[in] pdelay + * + **************************************************************************************** + */ +void dbg_wlan_config(uint8_t txmode, uint8_t rxmode, uint8_t txmsk, uint8_t rxmsk, uint8_t txthr, uint8_t rxthr, uint8_t pduration, uint8_t pdelay); + +/** + **************************************************************************************** + * @brief Start the wlrxbs signal generator. + * + **************************************************************************************** + */ +void dbg_wlangen_start(void); + +/** + **************************************************************************************** + * @brief Stop the wlrxbs signal generator. + * + **************************************************************************************** + */ +void dbg_wlangen_stop(void); +#endif // RW_WLAN_COEX_TEST + +#endif // (RW_WLAN_COEX_TEST) || (RW_MWS_COEX_TEST) + +/// @} DBGMWSGEN + +#endif // DBG_MWSGEN_H_ diff --git a/services/ble_stack/dbg/api/dbg_swdiag.h b/services/ble_stack/dbg/api/dbg_swdiag.h new file mode 100644 index 0000000..14fb0b1 --- /dev/null +++ b/services/ble_stack/dbg/api/dbg_swdiag.h @@ -0,0 +1,960 @@ +#ifndef DBG_SWDIAG_H_ +#define DBG_SWDIAG_H_ + +/** + **************************************************************************************** + * @addtogroup DBGSWDIAG Diag + * @ingroup DBG + * @brief Debug SW profiling module + * + * SW profiling is a debug feature that provides user a configurable way to analyze SW execution performance or + * behavior, such as timings, state machines, bit field values and so on. + * It manages the SW state representation over HW digital diagnostic signals (diagports), from the signals selection to + * the toggling of real HW signals. + * HW signals representing the SW execution could then be watched on a logic analyzer in parallel with HW internal + * signals, that could be very useful for low level debugging. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" // stack configuration + +#if (!RW_SWDIAG) + +/// Macro used to set a SW diag to specific value +#define DBG_SWDIAG(bank , field , value) + +#else //RW_SWDIAG + +#if (BT_EMB_PRESENT) // TODO not fully agree with this +#include "reg_btcore.h" // bt core registers +#elif (BLE_EMB_PRESENT) +#include "reg_blecore.h" // ble core registers +#endif //BT_EMB_PRESENT / BLE_EMB_PRESENT + + +/* + * DEFINES + **************************************************************************************** + */ + +/// Number of HW diagport banks +#define DBG_SWDIAG_NB_HW_BANKS 4 + +/// Undefined configuration +#define DBG_SWDIAG_UNDEFINED 0xFF + + +/* + * MACROS + **************************************************************************************** + */ +#if (BT_EMB_PRESENT) +#define SW_DIAG_SET bt_swprofiling_set +#define SW_DIAG_GET bt_swprofiling_get +#elif (BLE_EMB_PRESENT) +#define SW_DIAG_SET ble_swprofiling_set +#define SW_DIAG_GET ble_swprofiling_get +#endif //BT_EMB_PRESENT / BLE_EMB_PRESENT + +/// Macro used to set a SW diag to specific value +#define DBG_SWDIAG(bank , field , value) \ + if(sw_to_hw[DBG_SWDIAG_##bank] != DBG_SWDIAG_UNDEFINED) \ + { \ + SW_DIAG_SET( ((SW_DIAG_GET()) & (~(DBG_SWDIAG_##bank##_##field##_MASK << (8 * sw_to_hw[DBG_SWDIAG_##bank])))) | ((((value << DBG_SWDIAG_##bank##_##field##_OFFSET) & DBG_SWDIAG_##bank##_##field##_MASK) << (8*sw_to_hw[DBG_SWDIAG_##bank]))) ); \ + } + + +/* + * SW DIAGS MAP + **************************************************************************************** + */ + +enum dbg_swdiag +{ +/** +****************************************************************************************** +* @brief BANK 0 : BT_ISR +****************************************************************************************** +*/ + DBG_SWDIAG_BT_ISR = 0, + + DBG_SWDIAG_BT_ISR_RX_OFFSET = 0, + DBG_SWDIAG_BT_ISR_RX_MASK = 0x01, + + DBG_SWDIAG_BT_ISR_FRAME_OFFSET = 1, + DBG_SWDIAG_BT_ISR_FRAME_MASK = 0x02, + + DBG_SWDIAG_BT_ISR_SKET_OFFSET = 3, + DBG_SWDIAG_BT_ISR_SKET_MASK = 0x04, + + +/** +****************************************************************************************** +* @brief BANK 1 : SLEEP +****************************************************************************************** +*/ + DBG_SWDIAG_SLEEP = 1, + + DBG_SWDIAG_SLEEP_SLEEP_OFFSET = 0, + DBG_SWDIAG_SLEEP_SLEEP_MASK = 0x01, + + DBG_SWDIAG_SLEEP_FUNC_OFFSET = 1, + DBG_SWDIAG_SLEEP_FUNC_MASK = 0x02, + + DBG_SWDIAG_SLEEP_ALGO_OFFSET = 4, + DBG_SWDIAG_SLEEP_ALGO_MASK = 0xF0, + +// DBG_SWDIAG_SLEEP_PREVENT_OFFSET = 4, +// DBG_SWDIAG_SLEEP_PREVENT_MASK = 0xF0, + + +/** +****************************************************************************************** +* @brief BANK 2 : ISR +****************************************************************************************** +*/ + DBG_SWDIAG_ISR = 2, + + DBG_SWDIAG_ISR_UART_OFFSET = 0, + DBG_SWDIAG_ISR_UART_MASK = 0x01, + + DBG_SWDIAG_ISR_BT_OFFSET = 1, + DBG_SWDIAG_ISR_BT_MASK = 0x02, + + DBG_SWDIAG_ISR_PS2_OFFSET = 1, + DBG_SWDIAG_ISR_PS2_MASK = 0x02, + + DBG_SWDIAG_ISR_BLE_OFFSET = 2, + DBG_SWDIAG_ISR_BLE_MASK = 0x04, + + DBG_SWDIAG_ISR_RESERVED_OFFSET = 3, + DBG_SWDIAG_ISR_RESERVED_MASK = 0x08, + + DBG_SWDIAG_ISR_GPIO_OFFSET = 4, + DBG_SWDIAG_ISR_GPIO_MASK = 0x10, + + DBG_SWDIAG_ISR_RTC0_OFFSET = 5, + DBG_SWDIAG_ISR_RTC0_MASK = 0x20, + + DBG_SWDIAG_ISR_SPI_OFFSET = 6, + DBG_SWDIAG_ISR_SPI_MASK = 0x40, + + DBG_SWDIAG_ISR_WFI_OFFSET = 7, + DBG_SWDIAG_ISR_WFI_MASK = 0x80, + + +/** +****************************************************************************************** +* @brief BANK 3 : BLEISR +****************************************************************************************** +*/ + DBG_SWDIAG_BLE_ISR = 3, + + DBG_SWDIAG_BLE_ISR_RXINT_OFFSET = 0, + DBG_SWDIAG_BLE_ISR_RXINT_MASK = 0x01, + + DBG_SWDIAG_BLE_ISR_TXINT_OFFSET = 1, + DBG_SWDIAG_BLE_ISR_TXINT_MASK = 0x02, + + DBG_SWDIAG_BLE_ISR_EVENTINT_OFFSET = 2, + DBG_SWDIAG_BLE_ISR_EVENTINT_MASK = 0x04, + + DBG_SWDIAG_BLE_ISR_EVENTAPFMINT_OFFSET = 3, + DBG_SWDIAG_BLE_ISR_EVENTAPFMINT_MASK = 0x08, + + DBG_SWDIAG_BLE_ISR_ERRORINT_OFFSET = 4, + DBG_SWDIAG_BLE_ISR_ERRORINT_MASK = 0x10, + + DBG_SWDIAG_BLE_ISR_AUDIO0INT_OFFSET = 5, + DBG_SWDIAG_BLE_ISR_AUDIO0INT_MASK = 0x20, + + DBG_SWDIAG_BLE_ISR_AUDIO1INT_OFFSET = 6, + DBG_SWDIAG_BLE_ISR_AUDIO1INT_MASK = 0x40, + + DBG_SWDIAG_BLE_ISR_AUDIO2INT_OFFSET = 7, + DBG_SWDIAG_BLE_ISR_AUDIO2INT_MASK = 0x80, + + + +/** +****************************************************************************************** +* @brief BANK 4 : FLASH +****************************************************************************************** +*/ + DBG_SWDIAG_FLASH = 4, + + DBG_SWDIAG_FLASH_STATE_OFFSET = 0, + DBG_SWDIAG_FLASH_STATE_MASK = 0x07, + + DBG_SWDIAG_FLASH_SUBSTATE_OFFSET = 3, + DBG_SWDIAG_FLASH_SUBSTATE_MASK = 0x38, + + DBG_SWDIAG_FLASH_MANAGE_OFFSET = 6, + DBG_SWDIAG_FLASH_MANAGE_MASK = 0x40, + + DBG_SWDIAG_FLASH_CALLBACK_OFFSET = 7, + DBG_SWDIAG_FLASH_CALLBACK_MASK = 0x80, + +/** +****************************************************************************************** +* @brief BANK 5 : Reserved +****************************************************************************************** +*/ + + + +/** +****************************************************************************************** +* @brief BANK 6 : Event execution overview. +****************************************************************************************** +*/ + DBG_SWDIAG_EVT = 6, + + DBG_SWDIAG_EVT_BLE_SCHEDULE_OFFSET = 0, + DBG_SWDIAG_EVT_BLE_SCHEDULE_MASK = 0x01, + + DBG_SWDIAG_EVT_BLE_RX_OFFSET = 1, + DBG_SWDIAG_EVT_BLE_RX_MASK = 0x02, + + DBG_SWDIAG_EVT_BLE_END_OFFSET = 2, + DBG_SWDIAG_EVT_BLE_END_MASK = 0x04, + + DBG_SWDIAG_EVT_BLE_RESTART_OFFSET = 3, + DBG_SWDIAG_EVT_BLE_RESTART_MASK = 0x08, + + DBG_SWDIAG_EVT_BLE_PROG_OFFSET = 4, + DBG_SWDIAG_EVT_BLE_PROG_MASK = 0x10, + + DBG_SWDIAG_EVT_BLE_CRYPT_OFFSET = 5, + DBG_SWDIAG_EVT_BLE_CRYPT_MASK = 0x20, + + DBG_SWDIAG_EVT_TIMER_OFFSET = 6, + DBG_SWDIAG_EVT_TIMER_MASK = 0x40, + + DBG_SWDIAG_EVT_MESSAGE_OFFSET = 7, + DBG_SWDIAG_EVT_MESSAGE_MASK = 0x80, + + +/** +****************************************************************************************** +* @brief BANK 8 : AFH +****************************************************************************************** +*/ + DBG_SWDIAG_AFH = 8, + + DBG_SWDIAG_AFH_TO_OFFSET = 0, + DBG_SWDIAG_AFH_TO_MASK = 0x01, + + DBG_SWDIAG_AFH_LMP_TX_OFFSET = 1, + DBG_SWDIAG_AFH_LMP_TX_MASK = 0x02, + + DBG_SWDIAG_AFH_CLASS_RX_OFFSET = 2, + DBG_SWDIAG_AFH_CLASS_RX_MASK = 0x04, + + DBG_SWDIAG_AFH_HOST_OFFSET = 3, + DBG_SWDIAG_AFH_HOST_MASK = 0x08, + + DBG_SWDIAG_AFH_REPORT_TO_OFFSET = 4, + DBG_SWDIAG_AFH_REPORT_TO_MASK = 0x10, + + DBG_SWDIAG_AFH_HSSI_OFFSET = 5, + DBG_SWDIAG_AFH_HSSI_MASK = 0x20, + + DBG_SWDIAG_AFH_CFM_OFFSET = 6, + DBG_SWDIAG_AFH_CFM_MASK = 0x40, + + DBG_SWDIAG_AFH_LMP_RX_OFFSET = 7, + DBG_SWDIAG_AFH_LMP_RX_MASK = 0x80, + + +/** +****************************************************************************************** +* @brief BANK 9 : SWITCH +****************************************************************************************** +*/ + DBG_SWDIAG_SWITCH = 9, + + DBG_SWDIAG_SWITCH_LOOP_OFFSET = 0, + DBG_SWDIAG_SWITCH_LOOP_MASK = 0x01, + + DBG_SWDIAG_SWITCH_SM_OFFSET = 1, + DBG_SWDIAG_SWITCH_SM_MASK = 0x06, + + DBG_SWDIAG_SWITCH_RSW_FAIL_OFFSET = 3, + DBG_SWDIAG_SWITCH_RSW_FAIL_MASK = 0x08, + + +/** +****************************************************************************************** +* @brief BANK 11 : VALUE8 +****************************************************************************************** +*/ + DBG_SWDIAG_VALUE8 = 11, + + DBG_SWDIAG_VALUE8_VALUE_OFFSET = 0, + DBG_SWDIAG_VALUE8_VALUE_MASK = 0xFF, + +/** +****************************************************************************************** +* @brief BANK 12 : VALUE16 +****************************************************************************************** +*/ + DBG_SWDIAG_VALUE16 = 12, + + DBG_SWDIAG_VALUE16_VALUE_OFFSET = 0, + DBG_SWDIAG_VALUE16_VALUE_MASK = 0xFF, + + +/** +****************************************************************************************** +* @brief BANK 13 : SNIFF +****************************************************************************************** +*/ + DBG_SWDIAG_SNIFF = 13, + + DBG_SWDIAG_SNIFF_EVT_START_OFFSET = 0, + DBG_SWDIAG_SNIFF_EVT_START_MASK = 0x01, + + DBG_SWDIAG_SNIFF_EVT_CANCELED_OFFSET = 1, + DBG_SWDIAG_SNIFF_EVT_CANCELED_MASK = 0x02, + + DBG_SWDIAG_SNIFF_FRM_ISR_OFFSET = 2, + DBG_SWDIAG_SNIFF_FRM_ISR_MASK = 0x04, + + DBG_SWDIAG_SNIFF_RX_ISR_OFFSET = 3, + DBG_SWDIAG_SNIFF_RX_ISR_MASK = 0x08, + + DBG_SWDIAG_SNIFF_SCHED_OFFSET = 4, + DBG_SWDIAG_SNIFF_SCHED_MASK = 0x10, + + +/** +****************************************************************************************** +* @brief BANK 14 : SCO +****************************************************************************************** +*/ + DBG_SWDIAG_SCO = 14, + + DBG_SWDIAG_SCO_EVT_START_OFFSET = 0, + DBG_SWDIAG_SCO_EVT_START_MASK = 0x01, + + DBG_SWDIAG_SCO_EVT_STOP_OFFSET = 1, + DBG_SWDIAG_SCO_EVT_STOP_MASK = 0x02, + + DBG_SWDIAG_SCO_EVT_CANCELED_OFFSET = 2, + DBG_SWDIAG_SCO_EVT_CANCELED_MASK = 0x04, + + DBG_SWDIAG_SCO_FRM_ISR_OFFSET = 3, + DBG_SWDIAG_SCO_FRM_ISR_MASK = 0x08, + + DBG_SWDIAG_SCO_RESCHED_OFFSET = 4, + DBG_SWDIAG_SCO_RESCHED_MASK = 0x10, + + DBG_SWDIAG_SCO_UPDATE_OFFSET = 5, + DBG_SWDIAG_SCO_UPDATE_MASK = 0x60, + + DBG_SWDIAG_SCO_AUDIO_ISR_OFFSET = 7, + DBG_SWDIAG_SCO_AUDIO_ISR_MASK = 0x80, + + +/** +****************************************************************************************** +* @brief BANK 15 : CHNL_ASSESS (NB_CHNL) +****************************************************************************************** +*/ + DBG_SWDIAG_CHNL_ASSESS = 15, + + DBG_SWDIAG_CHNL_ASSESS_NB_CHNL_OFFSET = 0, + DBG_SWDIAG_CHNL_ASSESS_NB_CHNL_MASK = 0x3F, + + DBG_SWDIAG_CHNL_ASSESS_REM_CHNL_OFFSET = 6, + DBG_SWDIAG_CHNL_ASSESS_REM_CHNL_MASK = 0x40, + + DBG_SWDIAG_CHNL_ASSESS_ADD_CHNL_OFFSET = 7, + DBG_SWDIAG_CHNL_ASSESS_ADD_CHNL_MASK = 0x80, + +/** +****************************************************************************************** +* @brief BANK 16 : ASSESS_MECH +****************************************************************************************** +*/ + DBG_SWDIAG_ASSESS_MECH = 16, + + DBG_SWDIAG_ASSESS_MECH_ATIMER_OFFSET = 0, + DBG_SWDIAG_ASSESS_MECH_ATIMER_MASK = 0x01, + + DBG_SWDIAG_ASSESS_MECH_RTIMER_OFFSET = 1, + DBG_SWDIAG_ASSESS_MECH_RTIMER_MASK = 0x02, + + DBG_SWDIAG_ASSESS_MECH_BAD_PKT_OFFSET = 2, + DBG_SWDIAG_ASSESS_MECH_BAD_PKT_MASK = 0x04, + + DBG_SWDIAG_ASSESS_MECH_SYNC_ERR_OFFSET = 3, + DBG_SWDIAG_ASSESS_MECH_SYNC_ERR_MASK = 0x08, + +/** +****************************************************************************************** +* @brief BANK 17 : PAGE +****************************************************************************************** +*/ + DBG_SWDIAG_PAGE = 17, + + DBG_SWDIAG_PAGE_PSCAN_EVT_START_OFFSET = 0, + DBG_SWDIAG_PAGE_PSCAN_EVT_START_MASK = 0x01, + + DBG_SWDIAG_PAGE_PSCAN_EVT_CANCELED_OFFSET = 1, + DBG_SWDIAG_PAGE_PSCAN_EVT_CANCELED_MASK = 0x02, + + DBG_SWDIAG_PAGE_PSCAN_FRM_ISR_OFFSET = 2, + DBG_SWDIAG_PAGE_PSCAN_FRM_ISR_MASK = 0x04, + + DBG_SWDIAG_PAGE_PSCAN_KE_EVT_OFFSET = 3, + DBG_SWDIAG_PAGE_PSCAN_KE_EVT_MASK = 0x08, + + DBG_SWDIAG_PAGE_PAGE_EVT_START_OFFSET = 4, + DBG_SWDIAG_PAGE_PAGE_EVT_START_MASK = 0x10, + + DBG_SWDIAG_PAGE_PAGE_EVT_CANCELED_OFFSET = 5, + DBG_SWDIAG_PAGE_PAGE_EVT_CANCELED_MASK = 0x20, + + DBG_SWDIAG_PAGE_PAGE_FRM_ISR_OFFSET = 6, + DBG_SWDIAG_PAGE_PAGE_FRM_ISR_MASK = 0x40, + + DBG_SWDIAG_PAGE_PAGE_STEP_OFFSET = 7, + DBG_SWDIAG_PAGE_PAGE_STEP_MASK = 0x80, + +/** +****************************************************************************************** +* @brief BANK 18 : INQ +****************************************************************************************** +*/ + DBG_SWDIAG_INQ = 18, + + DBG_SWDIAG_INQ_ISCAN_EVT_START_OFFSET = 0, + DBG_SWDIAG_INQ_ISCAN_EVT_START_MASK = 0x01, + + DBG_SWDIAG_INQ_ISCAN_EVT_CANCELED_OFFSET = 1, + DBG_SWDIAG_INQ_ISCAN_EVT_CANCELED_MASK = 0x02, + + DBG_SWDIAG_INQ_ISCAN_FRM_ISR_OFFSET = 2, + DBG_SWDIAG_INQ_ISCAN_FRM_ISR_MASK = 0x04, + + DBG_SWDIAG_INQ_INQ_EVT_START_OFFSET = 3, + DBG_SWDIAG_INQ_INQ_EVT_START_MASK = 0x08, + + DBG_SWDIAG_INQ_INQ_EVT_CANCELED_OFFSET = 4, + DBG_SWDIAG_INQ_INQ_EVT_CANCELED_MASK = 0x10, + + DBG_SWDIAG_INQ_INQ_FRM_ISR_OFFSET = 5, + DBG_SWDIAG_INQ_INQ_FRM_ISR_MASK = 0x20, + +/** +****************************************************************************************** +* @brief BANK 19 : ACL +****************************************************************************************** +*/ + DBG_SWDIAG_ACL = 19, + + DBG_SWDIAG_ACL_EVT_START_OFFSET = 0, + DBG_SWDIAG_ACL_EVT_START_MASK = 0x01, + + DBG_SWDIAG_ACL_EVT_STOP_OFFSET = 1, + DBG_SWDIAG_ACL_EVT_STOP_MASK = 0x02, + + DBG_SWDIAG_ACL_EVT_CANCELED_OFFSET = 2, + DBG_SWDIAG_ACL_EVT_CANCELED_MASK = 0x04, + + DBG_SWDIAG_ACL_FRM_ISR_OFFSET = 3, + DBG_SWDIAG_ACL_FRM_ISR_MASK = 0x08, + + DBG_SWDIAG_ACL_CLK_ISR_OFFSET = 4, + DBG_SWDIAG_ACL_CLK_ISR_MASK = 0x10, + + DBG_SWDIAG_ACL_PROG_EN_OFFSET = 5, + DBG_SWDIAG_ACL_PROG_EN_MASK = 0x20, + + DBG_SWDIAG_ACL_SKET_ISR_OFFSET = 6, + DBG_SWDIAG_ACL_SKET_ISR_MASK = 0x40, + + DBG_SWDIAG_ACL_PARITY_OFFSET = 7, + DBG_SWDIAG_ACL_PARITY_MASK = 0x80, + +/** +****************************************************************************************** +* @brief BANK 20 : RSW +****************************************************************************************** +*/ + DBG_SWDIAG_RSW = 20, + + DBG_SWDIAG_RSW_EVT_START_OFFSET = 0, + DBG_SWDIAG_RSW_EVT_START_MASK = 0x01, + + DBG_SWDIAG_RSW_EVT_CANCELED_OFFSET = 1, + DBG_SWDIAG_RSW_EVT_CANCELED_MASK = 0x02, + + DBG_SWDIAG_RSW_FRM_ISR_OFFSET = 2, + DBG_SWDIAG_RSW_FRM_ISR_MASK = 0x04, + + DBG_SWDIAG_RSW_STEP_OFFSET = 3, + DBG_SWDIAG_RSW_STEP_MASK = 0x08, + + DBG_SWDIAG_RSW_TX_SLOTOFF_OFFSET = 4, + DBG_SWDIAG_RSW_TX_SLOTOFF_MASK = 0x10, + + DBG_SWDIAG_RSW_TX_PARITY_OFFSET = 5, + DBG_SWDIAG_RSW_TX_PARITY_MASK = 0x20, + + DBG_SWDIAG_RSW_TDD_PARITY_OFFSET = 6, + DBG_SWDIAG_RSW_TDD_PARITY_MASK = 0x40, + +/** +****************************************************************************************** +* @brief BANK 21 : TX +****************************************************************************************** +*/ + DBG_SWDIAG_TX = 21, + + DBG_SWDIAG_TX_LMP_TX_OFFSET = 0, + DBG_SWDIAG_TX_LMP_TX_MASK = 0x01, + + DBG_SWDIAG_TX_ACL_TX_OFFSET = 1, + DBG_SWDIAG_TX_ACL_TX_MASK = 0x02, + + DBG_SWDIAG_TX_SW_IDX_OFFSET = 2, + DBG_SWDIAG_TX_SW_IDX_MASK = 0x04, + + DBG_SWDIAG_TX_HW_IDX_OFFSET = 3, + DBG_SWDIAG_TX_HW_IDX_MASK = 0x08, + + DBG_SWDIAG_TX_TX_CNT_OFFSET = 4, + DBG_SWDIAG_TX_TX_CNT_MASK = 0x30, + +/** +****************************************************************************************** +* @brief BANK 22 : DATA +****************************************************************************************** +*/ + DBG_SWDIAG_DATA = 22, + + DBG_SWDIAG_DATA_LMP_TX_OFFSET = 0, + DBG_SWDIAG_DATA_LMP_TX_MASK = 0x01, + + DBG_SWDIAG_DATA_ACL_TX_OFFSET = 1, + DBG_SWDIAG_DATA_ACL_TX_MASK = 0x02, + + DBG_SWDIAG_DATA_LMP_RX_OFFSET = 2, + DBG_SWDIAG_DATA_LMP_RX_MASK = 0x04, + + DBG_SWDIAG_DATA_ACL_RX_OFFSET = 3, + DBG_SWDIAG_DATA_ACL_RX_MASK = 0x08, + + DBG_SWDIAG_DATA_LMP_ACK_OFFSET = 4, + DBG_SWDIAG_DATA_LMP_ACK_MASK = 0x10, + + DBG_SWDIAG_DATA_ACL_ACK_OFFSET = 5, + DBG_SWDIAG_DATA_ACL_ACK_MASK = 0x20, + + /** + ****************************************************************************************** + * @brief BANK 23 : ECDH + ****************************************************************************************** + */ + DBG_SWDIAG_ECDH = 23, + + DBG_SWDIAG_ECDH_BUSY_OFFSET = 0, + DBG_SWDIAG_ECDH_BUSY_MASK = 0x01, + + DBG_SWDIAG_ECDH_COMPUTE_OFFSET = 1, + DBG_SWDIAG_ECDH_COMPUTE_MASK = 0x02, + + DBG_SWDIAG_ECDH_MULT_OFFSET = 2, + DBG_SWDIAG_ECDH_MULT_MASK = 0x04, + + DBG_SWDIAG_ECDH_END_OFFSET = 3, + DBG_SWDIAG_ECDH_END_MASK = 0x08, + + DBG_SWDIAG_ECDH_INV_OFFSET = 4, + DBG_SWDIAG_ECDH_INV_MASK = 0x10, + + /** + ****************************************************************************************** + * @brief BANK 24 : PCA + ****************************************************************************************** + */ + DBG_SWDIAG_PCA = 24, + + DBG_SWDIAG_PCA_FRAME_SYNC_INT_OFFSET = 0, + DBG_SWDIAG_PCA_FRAME_SYNC_INT_MASK = 0x01, + + DBG_SWDIAG_PCA_MTOFF_LT_INT_OFFSET = 1, + DBG_SWDIAG_PCA_MTOFF_LT_INT_MASK = 0x02, + + DBG_SWDIAG_PCA_SLOT_INT_OFFSET = 2, + DBG_SWDIAG_PCA_SLOT_INT_MASK = 0x04, + + DBG_SWDIAG_PCA_COARSE_CLK_ADJ_OFFSET = 3, + DBG_SWDIAG_PCA_COARSE_CLK_ADJ_MASK = 0x08, + + DBG_SWDIAG_PCA_EVT_START_OFFSET = 4, + DBG_SWDIAG_PCA_EVT_START_MASK = 0x10, + + DBG_SWDIAG_PCA_EVT_CANCELED_OFFSET = 5, + DBG_SWDIAG_PCA_EVT_CANCELED_MASK = 0x20, + + DBG_SWDIAG_PCA_ALARM_INSTANT_OFFSET = 6, + DBG_SWDIAG_PCA_ALARM_INSTANT_MASK = 0x40, + + DBG_SWDIAG_PCA_CLK_DRAG_OFFSET = 7, + DBG_SWDIAG_PCA_CLK_DRAG_MASK = 0x80, + + /** + ****************************************************************************************** + * @brief BANK 25 : BCST + ****************************************************************************************** + */ + DBG_SWDIAG_BCST = 25, + + DBG_SWDIAG_BCST_FRM_ISR_OFFSET = 0, + DBG_SWDIAG_BCST_FRM_ISR_MASK = 0x01, + + DBG_SWDIAG_BCST_EVT_START_OFFSET = 1, + DBG_SWDIAG_BCST_EVT_START_MASK = 0x02, + + DBG_SWDIAG_BCST_SKET_ISR_OFFSET = 2, + DBG_SWDIAG_BCST_SKET_ISR_MASK = 0x04, + + DBG_SWDIAG_BCST_EVT_CANCELED_OFFSET = 3, + DBG_SWDIAG_BCST_EVT_CANCELED_MASK = 0x08, + + DBG_SWDIAG_BCST_ACL_TX_OFFSET = 4, + DBG_SWDIAG_BCST_ACL_TX_MASK = 0x10, + + DBG_SWDIAG_BCST_ACL_ACK_OFFSET = 5, + DBG_SWDIAG_BCST_ACL_ACK_MASK = 0x20, + + DBG_SWDIAG_BCST_LMP_TX_OFFSET = 6, + DBG_SWDIAG_BCST_LMP_TX_MASK = 0x40, + + DBG_SWDIAG_BCST_LMP_ACK_OFFSET = 7, + DBG_SWDIAG_BCST_LMP_ACK_MASK = 0x80, + + + + /** + ****************************************************************************************** + * @brief IPISR - 2 + ****************************************************************************************** + */ + DBG_SWDIAG_IP_ISR = 26, + + DBG_SWDIAG_IP_ISR_CLKNINT_OFFSET = 0, + DBG_SWDIAG_IP_ISR_CLKNINT_MASK = 0x01, + + DBG_SWDIAG_IP_ISR_FINETGTIMINT_OFFSET = 1, + DBG_SWDIAG_IP_ISR_FINETGTIMINT_MASK = 0x02, + + DBG_SWDIAG_IP_ISR_GROSSTGTIMINT_OFFSET = 2, + DBG_SWDIAG_IP_ISR_GROSSTGTIMINT_MASK = 0x04, + + DBG_SWDIAG_IP_ISR_SLPINT_OFFSET = 3, + DBG_SWDIAG_IP_ISR_SLPINT_MASK = 0x08, + + DBG_SWDIAG_IP_ISR_CRYPTINT_OFFSET = 4, + DBG_SWDIAG_IP_ISR_CRYPTINT_MASK = 0x10, + + DBG_SWDIAG_IP_ISR_SWINT_OFFSET = 5, + DBG_SWDIAG_IP_ISR_SWINT_MASK = 0x20, + + /** + ****************************************************************************************** + * @brief RSA Algorithm + ****************************************************************************************** + */ + + DBG_SWDIAG_RSA = 27, + + DBG_SWDIAG_RSA_BUSY_OFFSET = 0, + DBG_SWDIAG_RSA_BUSY_MASK = 0x01, + + DBG_SWDIAG_RSA_COMPUTE_OFFSET = 1, + DBG_SWDIAG_RSA_COMPUTE_MASK = 0x02, + + /** + ****************************************************************************************** + * @brief BANK 28 : SYNC SCAN + ****************************************************************************************** + */ + DBG_SWDIAG_SSCAN = 28, + + DBG_SWDIAG_SSCAN_FRM_ISR_OFFSET = 0, + DBG_SWDIAG_SSCAN_FRM_ISR_MASK = 0x01, + + DBG_SWDIAG_SSCAN_EVT_START_OFFSET = 1, + DBG_SWDIAG_SSCAN_EVT_START_MASK = 0x02, + + DBG_SWDIAG_SSCAN_START_OFFSET = 2, + DBG_SWDIAG_SSCAN_START_MASK = 0x04, + + DBG_SWDIAG_SSCAN_EVT_CANCELED_OFFSET = 3, + DBG_SWDIAG_SSCAN_EVT_CANCELED_MASK = 0x08, + + DBG_SWDIAG_SSCAN_FRM_CBK_OFFSET = 4, + DBG_SWDIAG_SSCAN_FRM_CBK_MASK = 0x10, + + DBG_SWDIAG_SSCAN_STP_RX_OFFSET = 5, + DBG_SWDIAG_SSCAN_STP_RX_MASK = 0x20, + + DBG_SWDIAG_SSCAN_STP_RX_OK_OFFSET = 6, + DBG_SWDIAG_SSCAN_STP_RX_OK_MASK = 0x40, + + DBG_SWDIAG_SSCAN_TIMEOUT_OFFSET = 7, + DBG_SWDIAG_SSCAN_TIMEOUT_MASK = 0x80, + + /** + ****************************************************************************************** + * @brief BANK 29 : LE SCAN + ****************************************************************************************** + */ + DBG_SWDIAG_LESCAN = 29, + + DBG_SWDIAG_LESCAN_START_OFFSET = 0, + DBG_SWDIAG_LESCAN_START_MASK = 0x01, + + DBG_SWDIAG_LESCAN_STOP_OFFSET = 1, + DBG_SWDIAG_LESCAN_STOP_MASK = 0x02, + + DBG_SWDIAG_LESCAN_EVT_START_OFFSET = 2, + DBG_SWDIAG_LESCAN_EVT_START_MASK = 0x04, + + DBG_SWDIAG_LESCAN_EVT_CANCELED_OFFSET = 3, + DBG_SWDIAG_LESCAN_EVT_CANCELED_MASK = 0x08, + + DBG_SWDIAG_LESCAN_FRM_ISR_RX_OFFSET = 4, + DBG_SWDIAG_LESCAN_FRM_ISR_RX_MASK = 0x10, + + DBG_SWDIAG_LESCAN_FRM_ISR_EOF_OFFSET = 5, + DBG_SWDIAG_LESCAN_FRM_ISR_EOF_MASK = 0x20, + + DBG_SWDIAG_LESCAN_SCHED_OFFSET = 6, + DBG_SWDIAG_LESCAN_SCHED_MASK = 0x40, + + DBG_SWDIAG_LESCAN_PKT_RX_OFFSET = 7, + DBG_SWDIAG_LESCAN_PKT_RX_MASK = 0x80, + + /** + ****************************************************************************************** + * @brief BANK 30 : LLD FM + ****************************************************************************************** + */ + DBG_SWDIAG_LLDFM = 30, + + DBG_SWDIAG_LLDFM_RX_ISR_OFFSET = 0, + DBG_SWDIAG_LLDFM_RX_ISR_MASK = 0x01, + + DBG_SWDIAG_LLDFM_END_ISR_OFFSET = 1, + DBG_SWDIAG_LLDFM_END_ISR_MASK = 0x02, + + DBG_SWDIAG_LLDFM_PROG_PUSH_OFFSET = 2, + DBG_SWDIAG_LLDFM_PROG_PUSH_MASK = 0x04, + + DBG_SWDIAG_LLDFM_INIT_OFFSET = 3, + DBG_SWDIAG_LLDFM_INIT_MASK = 0x08, + + DBG_SWDIAG_LLDFM_TX_ISR_OFFSET = 4, + DBG_SWDIAG_LLDFM_TX_ISR_MASK = 0x10, + + /** + ****************************************************************************************** + * @brief BANK 31 : LE INITIATING + ****************************************************************************************** + */ + DBG_SWDIAG_LEINIT = 31, + + DBG_SWDIAG_LEINIT_START_OFFSET = 0, + DBG_SWDIAG_LEINIT_START_MASK = 0x01, + + DBG_SWDIAG_LEINIT_STOP_OFFSET = 1, + DBG_SWDIAG_LEINIT_STOP_MASK = 0x02, + + DBG_SWDIAG_LEINIT_EVT_START_OFFSET = 2, + DBG_SWDIAG_LEINIT_EVT_START_MASK = 0x04, + + DBG_SWDIAG_LEINIT_EVT_CANCELED_OFFSET = 3, + DBG_SWDIAG_LEINIT_EVT_CANCELED_MASK = 0x08, + + DBG_SWDIAG_LEINIT_FRM_CBK_OFFSET = 4, + DBG_SWDIAG_LEINIT_FRM_CBK_MASK = 0x10, + + DBG_SWDIAG_LEINIT_FRM_ISR_EOF_OFFSET = 5, + DBG_SWDIAG_LEINIT_FRM_ISR_EOF_MASK = 0x20, + + DBG_SWDIAG_LEINIT_SCHED_OFFSET = 6, + DBG_SWDIAG_LEINIT_SCHED_MASK = 0x40, + + DBG_SWDIAG_LEINIT_PKT_RX_OFFSET = 7, + DBG_SWDIAG_LEINIT_PKT_RX_MASK = 0x80, + + /** + ****************************************************************************************** + * @brief BANK 32 : LE ADVERTISING + ****************************************************************************************** + */ + DBG_SWDIAG_LEADV = 32, + + DBG_SWDIAG_LEADV_START_OFFSET = 0, + DBG_SWDIAG_LEADV_START_MASK = 0x01, + + DBG_SWDIAG_LEADV_STOP_OFFSET = 1, + DBG_SWDIAG_LEADV_STOP_MASK = 0x02, + + DBG_SWDIAG_LEADV_EVT_START_OFFSET = 2, + DBG_SWDIAG_LEADV_EVT_START_MASK = 0x04, + + DBG_SWDIAG_LEADV_EVT_CANCELED_OFFSET = 3, + DBG_SWDIAG_LEADV_EVT_CANCELED_MASK = 0x08, + + DBG_SWDIAG_LEADV_RX_ISR_OFFSET = 4, + DBG_SWDIAG_LEADV_RX_ISR_MASK = 0x10, + + DBG_SWDIAG_LEADV_FRM_ISR_OFFSET = 5, + DBG_SWDIAG_LEADV_FRM_ISR_MASK = 0x20, + + DBG_SWDIAG_LEADV_SCHED_OFFSET = 6, + DBG_SWDIAG_LEADV_SCHED_MASK = 0x40, + + DBG_SWDIAG_LEADV_PKT_RX_OFFSET = 7, + DBG_SWDIAG_LEADV_PKT_RX_MASK = 0x80, + + /** + ****************************************************************************************** + * @brief BANK 33 : LE CONNECTION + ****************************************************************************************** + */ + DBG_SWDIAG_LECON = 33, + + DBG_SWDIAG_LECON_START_OFFSET = 0, + DBG_SWDIAG_LECON_START_MASK = 0x01, + + DBG_SWDIAG_LECON_STOP_OFFSET = 1, + DBG_SWDIAG_LECON_STOP_MASK = 0x02, + + DBG_SWDIAG_LECON_EVT_START_OFFSET = 2, + DBG_SWDIAG_LECON_EVT_START_MASK = 0x04, + + DBG_SWDIAG_LECON_EVT_CANCELED_OFFSET = 3, + DBG_SWDIAG_LECON_EVT_CANCELED_MASK = 0x08, + + DBG_SWDIAG_LECON_RX_ISR_OFFSET = 4, + DBG_SWDIAG_LECON_RX_ISR_MASK = 0x10, + + DBG_SWDIAG_LECON_FRM_ISR_OFFSET = 5, + DBG_SWDIAG_LECON_FRM_ISR_MASK = 0x20, + + DBG_SWDIAG_LECON_SCHED_OFFSET = 6, + DBG_SWDIAG_LECON_SCHED_MASK = 0x40, + + DBG_SWDIAG_LECON_TX_ISR_OFFSET = 7, + DBG_SWDIAG_LECON_TX_ISR_MASK = 0x80, + + /** + ****************************************************************************************** + * @brief BANK 34 : LE DATA + ****************************************************************************************** + */ + DBG_SWDIAG_LEDATA = 34, + + DBG_SWDIAG_LEDATA_LLCP_TX_OFFSET = 0, + DBG_SWDIAG_LEDATA_LLCP_TX_MASK = 0x01, + + DBG_SWDIAG_LEDATA_ACL_TX_OFFSET = 1, + DBG_SWDIAG_LEDATA_ACL_TX_MASK = 0x02, + + DBG_SWDIAG_LEDATA_LLCP_RX_OFFSET = 2, + DBG_SWDIAG_LEDATA_LLCP_RX_MASK = 0x04, + + DBG_SWDIAG_LEDATA_ACL_RX_OFFSET = 3, + DBG_SWDIAG_LEDATA_ACL_RX_MASK = 0x08, + + DBG_SWDIAG_LEDATA_LLCP_ACK_OFFSET = 4, + DBG_SWDIAG_LEDATA_LLCP_ACK_MASK = 0x10, + + DBG_SWDIAG_LEDATA_ACL_ACK_OFFSET = 5, + DBG_SWDIAG_LEDATA_ACL_ACK_MASK = 0x20, + + /** + ****************************************************************************************** + * @brief BANK 35 : LETX + ****************************************************************************************** + */ + DBG_SWDIAG_LETX = 35, + + DBG_SWDIAG_LETX_LLCP_TX_OFFSET = 0, + DBG_SWDIAG_LETX_LLCP_TX_MASK = 0x01, + + DBG_SWDIAG_LETX_ACL_TX_OFFSET = 1, + DBG_SWDIAG_LETX_ACL_TX_MASK = 0x02, + + DBG_SWDIAG_LETX_SW_IDX_OFFSET = 2, + DBG_SWDIAG_LETX_SW_IDX_MASK = 0x04, + + DBG_SWDIAG_LETX_HW_IDX_OFFSET = 3, + DBG_SWDIAG_LETX_HW_IDX_MASK = 0x08, + + DBG_SWDIAG_LETX_TX_CNT_OFFSET = 4, + DBG_SWDIAG_LETX_TX_CNT_MASK = 0x30, + + /// Number of SW profiles - to increase when new bank are added + DBG_SWDIAG_NB_PROFILES = 36, +}; + + +/* + * GLOBAL VARIABLE DECLARATION + **************************************************************************************** + */ + +/// Allocate HW banks to SW profiles +extern uint8_t sw_to_hw[DBG_SWDIAG_NB_PROFILES]; + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** +****************************************************************************************** +* @brief Initialize SW profiling module +****************************************************************************************** +*/ +void dbg_swdiag_init(void); + +/** +****************************************************************************************** +* @brief Read the SW profiling configuration. +* +* @return SW profile configuration +****************************************************************************************** +*/ +uint32_t dbg_swdiag_read(void); + +/** +****************************************************************************************** +* @brief Write the SW profiling configuration. +* +* @param[in] profile SW profiling configuration to apply +****************************************************************************************** +*/ +void dbg_swdiag_write(uint32_t profile); + +#endif //RW_SWDIAG + +/// @} DBGSWDIAG + +#endif // DBG_SWDIAG_H_ diff --git a/services/ble_stack/dbg/api/dbg_trc.h b/services/ble_stack/dbg/api/dbg_trc.h new file mode 100644 index 0000000..ef1a5b3 --- /dev/null +++ b/services/ble_stack/dbg/api/dbg_trc.h @@ -0,0 +1,886 @@ +#ifndef DBG_TRC_H_ +#define DBG_TRC_H_ + +/** +**************************************************************************************** +* @addtogroup TRACER +* @ingroup TRACER +* @brief Tracer module sends traces to the PC through UART +* @{ +**************************************************************************************** +*/ + +#include "rwip_config.h" +#if (TRACER_PRESENT) + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include + +#if (TRC_KE_MSG || TRC_KE_TMR) +#include "ke_msg.h" +#endif /*(TRC_KE_MSG || TRC_KE_TMR)*/ + +#if (TRC_EA) +#include "ea.h" +#endif /*(TRC_EA) */ + +/* + * DEFINES + **************************************************************************************** + */ +#define TRC_GRP_B(__t) (__t##_BIT) +#define TRC_GRP_P(__t) (__t##_POS) + +#define TRC_MSG_TYPE 0x06 + +#define TRC_OPCODE_LEN (1) +#define TRC_PDULEN_LEN (2) +#define TRC_MSG_HDR_LEN (TRC_OPCODE_LEN + TRC_PDULEN_LEN) + +#define TRC_CFG_WORD_LEN (4) + +/* + * ENUMERATION DEFINITION + **************************************************************************************** + */ +/// Possible types of trace +enum trace_types +{ + KE_MSG_SEND_QUEUE = 0x00, + KE_MSG_HANDLED = 0x01, + KE_TMR_SET = 0x02, + KE_TMR_CLR = 0x03, + KE_TMR_EXP = 0x04, + KE_EVT_SET = 0x05, + KE_EVT_HANDLED = 0x06, + MEM_ALLOC = 0x07, + MEM_FREE = 0x08, + SLEEP_ENTER = 0x09, + SLEEP_WAKEUP = 0x0A, + ASSERT_WARNING = 0x0B, + ASSERT_ERROR = 0x0C, + ET_PROG = 0x0D, + CONN_EVT_CNT = 0x0E, + FRM_CMP_BT = 0x0F, + FRM_CMP_BLE = 0x10, + CS_BLE = 0x11, + CS_BT = 0x12, + RX_DESC = 0x13, + LLCP_TX = 0x14, + LLCP_RX = 0x15, + LLCP_ACK = 0x16, + LMP_TX = 0x17, + LMP_RX = 0x18, + LMP_ACK = 0x19, + L2CAP_TX = 0x1A, + L2CAP_RX = 0x1B, + L2CAP_ACK = 0x1C, + EA_REQ = 0x1D, + EA_CANC = 0x1E, + EA_REM = 0x1F, + EA_START = 0x20, + EA_SHIFT = 0x21, + LC_ST = 0x22, + LLC_ST = 0x23, + HCI_CMD = 0x24, + HCI_EVT = 0x25, + CUSTOM = 0x26, +}; + +/// Configuration word bit field +/// +/// 7 6 5 4 3 2 1 0 +/// +-------+-------+-------+-------+-------+-------+-------+-------+ +/// |CS_BLE | PROG |SW_ASS | SLEEP | MEM |KE_EVT |KE_TMR |KE_MSG | +/// +-------+-------+-------+-------+-------+-------+-------+-------+ +/// +/// 15 14 13 12 11 10 9 8 +/// +-------+-------+-------+-------+-------+-------+-------+-------+ +/// | LC_ST |LLC_ST | EA | L2CAP | LMP | LLCP |RX_DESC| CS_BT | +/// +-------+-------+-------+-------+-------+-------+-------+-------+ +/// +/// 23 22 21 20 19 18 17 16 +/// +-------+-------+-------+-------+-------+-------+-------+-------+ +/// | | | | | | |CUSTOM | HCI | +/// +-------+-------+-------+-------+-------+-------+-------+-------+ +/// +/// 31 30 29 28 27 26 25 24 +/// +-------+-------+-------+-------+-------+-------+-------+-------+ +/// | | | | | | | | | +/// +-------+-------+-------+-------+-------+-------+-------+-------+ +/// +enum dbg_trc_cfg_fields +{ + /// Kernel message + TRC_KE_MSG_POS = 0, + TRC_KE_MSG_BIT = 0x00000001, + + /// Kernel timer + TRC_KE_TMR_POS = 1, + TRC_KE_TMR_BIT = 0x00000002, + + /// Kernel event + TRC_KE_EVT_POS = 2, + TRC_KE_EVT_BIT = 0x00000004, + + /// Memory allocation and deallocation + TRC_MEM_POS = 3, + TRC_MEM_BIT = 0x00000008, + + /// Sleep mode + TRC_SLEEP_POS = 4, + TRC_SLEEP_BIT = 0x00000010, + + /// Software Assert + TRC_SW_ASS_POS = 5, + TRC_SW_ASS_BIT = 0x00000020, + + /// Programming of the exchange table, updating of the event counter and handling of "End of Event" interrupt + TRC_PROG_POS = 6, + TRC_PROG_BIT = 0x00000040, + + /// BLE Control structure + TRC_CS_BLE_POS = 7, + TRC_CS_BLE_BIT = 0x00000080, + + /// BT Control structure + TRC_CS_BT_POS = 8, + TRC_CS_BT_BIT = 0x00000100, + + /// Processing of RX descriptors at each LLD driver + TRC_RX_DESC_POS = 9, + TRC_RX_DESC_BIT = 0x00000200, + + /// LLCP transmission, reception and acknowledgment + TRC_LLCP_POS = 10, + TRC_LLCP_BIT = 0x00000400, + + /// LMP transmission, reception and acknowledgment + TRC_LMP_POS = 11, + TRC_LMP_BIT = 0x00000800, + + /// L2CAP transmission, reception and acknowledgment + TRC_L2CAP_POS = 12, + TRC_L2CAP_BIT = 0x00001000, + + /// Scheduling request, cancellation, shift and remove + TRC_EA_POS = 13, + TRC_EA_BIT = 0x00002000, + + /// LLC state transition + TRC_LLC_STATE_TRANS_POS = 14, + TRC_LLC_STATE_TRANS_BIT = 0x00004000, + + /// LC state transition + TRC_LC_STATE_TRANS_POS = 15, + TRC_LC_STATE_TRANS_BIT = 0x00008000, + + /// HCI messages (in Full embedded mode) + TRC_HCI_POS = 16, + TRC_HCI_BIT = 0x00010000, + + /// Custom trace + TRC_CUSTOM_POS = 17, + TRC_CUSTOM_BIT = 0x00020000, +}; + +/// Tracer packet types +enum dbg_trc_pkt_types +{ + /// Trace message + TRACE = 0x01, + /// Configuration message + TRACER_CFG = 0x02, + /// Acknowledgment message + TRACER_ACK = 0x03 +}; + +#if (TRC_RX_DESC) +/// LLD driver types +enum driver_types +{ + LLD_SCAN = 0x01, + LLD_INIT = 0x02, + LLD_ADV = 0x03, + LLD_CON = 0x04 +}; +#endif /*(TRC_RX_DESC)*/ + +#if (TRC_CUSTOM) +/// Custom trace types +enum custom_trace_types +{ + UINT8_T = 0x01, + UINT16_T = 0x02, + UINT32_T = 0x03, + VOID = 0x04 +}; +#endif /*(TRC_CUSTOM)*/ +#endif /*(TRACER_PRESENT)*/ + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATION + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Request a new trace + * + * This function checks the current configuration of the tracer + * + **************************************************************************************** + */ +#if (TRACER_PRESENT && TRC_KE_MSG) +/** + **************************************************************************************** + * @brief Trace request API for kernel message pushed in the send queue + * + * This function is called when a kernel message is pushed in the send queue. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "kernel message" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] msg Kernel message + **************************************************************************************** + */ +void dbg_trc_req_ke_msg_send(struct ke_msg const *msg); + +/// Macro used to send trace request API for kernel message send +#define TRC_REQ_KE_MSG_SEND(msg) \ + dbg_trc_req_ke_msg_send(msg); + +/** + **************************************************************************************** + * @brief Trace request API for kernel message handled + * + * This function is called when a task handles a message + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "kernel message" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] id Kernel message id + * @param[in] dest_id Destination kernel identifier + * @param[in] src_id Source kernel identifier + * @param[in] msg_status Status returned by the kernel message handler + **************************************************************************************** + */ +void dbg_trc_req_ke_msg_handled(ke_msg_id_t const id, ke_task_id_t const dest_id, ke_task_id_t const src_id, uint8_t const msg_status); + +/// Macro used to send trace request API for kernel message handled +#define TRC_REQ_KE_MSG_HANDLED(id, dest_id, src_id, msg_status) \ + dbg_trc_req_ke_msg_handled(id, dest_id, src_id, msg_status); +#else /*TRACER_PRESENT && TRC_KE_MSG*/ +#define TRC_REQ_KE_MSG_SEND(msg) +#define TRC_REQ_KE_MSG_HANDLED(id, dest_id, src_id, msg_status) +#endif /*TRACER_PRESENT && TRC_KE_MSG*/ + +#if (TRACER_PRESENT && TRC_KE_TMR) +/** + **************************************************************************************** + * @brief Trace request API for kernel timer + * + * This function is called when a kernel timer is set, cleared or expired. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "kernel timer" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] tmr_trc_type Trace type for kernel timer (timer set, cleared and expired of @see enum trace_types) + * @param[in] target_time Timer time value + * @param[in] task_id Timer task identifier + * @param[in] msg_id Timer message identifier + **************************************************************************************** + */ +void dbg_trc_req_ke_tmr(uint8_t const tmr_trc_type, uint32_t const target_time, ke_task_id_t const task_id, ke_msg_id_t const msg_id); + +/// Macro used to send trace request API for kernel timer set +#define TRC_REQ_KE_TMR_SET(target_time, task_id, msg_id) \ + dbg_trc_req_ke_tmr(KE_TMR_SET, target_time, task_id, msg_id); + +/// Macro used to send trace request API for kernel timer cleared +#define TRC_REQ_KE_TMR_CLR(target_time, task_id, msg_id) \ + dbg_trc_req_ke_tmr(KE_TMR_CLR,target_time, task_id, msg_id); + +/// Macro used to send trace request API for kernel timer expired +#define TRC_REQ_KE_TMR_EXP(target_time, task_id, msg_id) \ + dbg_trc_req_ke_tmr(KE_TMR_EXP,target_time, task_id, msg_id); +#else /*(TRACER_PRESENT && TRC_KE_TMR)*/ +#define TRC_REQ_KE_TMR_SET(target_time, task_id, msg_id) +#define TRC_REQ_KE_TMR_CLR(target_time, task_id, msg_id) +#define TRC_REQ_KE_TMR_EXP(target_time, task_id, msg_id) +#endif /*(TRACER_PRESENT && TRC_KE_TMR)*/ + +#if (TRACER_PRESENT && TRC_KE_EVT) +/** + **************************************************************************************** + * @brief Trace request API for kernel event + * + * This function is called when a kernel event is set or handled. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "kernel event" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] evt_req_type Trace type for kernel event (event set and handled of @see enum trace_types) + * @param[in] event_type Type of event + **************************************************************************************** + */ +void dbg_trc_req_ke_evt(uint8_t const evt_trc_type, uint8_t const event_type); + +/// Macro used to send trace request API for kernel event set +#define TRC_REQ_KE_EVT_SET(evt_type) \ + dbg_trc_req_ke_evt(KE_EVT_SET, evt_type); + +/// Macro used to send trace request API for kernel event handled +#define TRC_REQ_KE_EVT_HANDLED(evt_type) \ + dbg_trc_req_ke_evt(KE_EVT_HANDLED, evt_type); +#else /*(TRACER_PRESENT && TRC_KE_EVT)*/ +#define TRC_REQ_KE_EVT_SET(evt_type) +#define TRC_REQ_KE_EVT_HANDLED(evt_type) +#endif /*(TRACER_PRESENT && TRC_KE_EVT)*/ + +#if (TRACER_PRESENT && TRC_MEM) +/** + **************************************************************************************** + * @brief Trace request API for memory management + * + * This function is called when the memory is allocated or freed. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "memory" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] mem_trc_type Trace type for memory management (memory alloc and free of @see enum trace_types) + * @param[in] heap_id Heap identifier + * @param[in] blk_address Address of the used memory block + * @param[in] size Size of the memory area that has been allocated or freed. + **************************************************************************************** + */ +void dbg_trc_req_mem(uint8_t const mem_trc_type, uint8_t const heap_id, void const *blk_address, uint32_t const size); + +/// Macro used to send trace request API for memory allocation +#define TRC_REQ_MEM_ALLOC(heap_id, blk_address, size) \ + dbg_trc_req_mem(MEM_ALLOC, heap_id, blk_address, size); + +/// Macro used to send trace request API for memory deallocation +#define TRC_REQ_MEM_FREE(heap_id, blk_address, size) \ + dbg_trc_req_mem(MEM_FREE, heap_id, blk_address, size); + +#else /*(TRACER_PRESENT && TRC_MEM)*/ +#define TRC_REQ_MEM_ALLOC(heap_id, blk_address, size) +#define TRC_REQ_MEM_FREE(heap_id, blk_address, size) +#endif/*(TRACER_PRESENT && TRC_MEM)*/ + +#if (TRACER_PRESENT && TRC_SLEEP) +/** + **************************************************************************************** + * @brief Trace request API for sleep mode + * + * This function is called when the IP enter in deep sleep and when it wakes up. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "sleep" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] sleep_trc_type Trace type for sleep mode (sleep enter and wakeup of @see enum trace_types) + **************************************************************************************** + */ +void dbg_trc_req_deep_sleep(uint8_t const sleep_trc_type); + +/// Macro used to send trace request API when the IP enters in deep sleep +#define TRC_REQ_SLEEP() \ + dbg_trc_req_deep_sleep(SLEEP_ENTER); + +/// Macro used to send trace request API when the IP wakes up from deep sleep +#define TRC_REQ_WAKEUP() \ + dbg_trc_req_deep_sleep(SLEEP_WAKEUP); + +#else /*(TRACER_PRESENT && TRC_SLEEP)*/ +#define TRC_REQ_SLEEP() +#define TRC_REQ_WAKEUP() +#endif /*(TRACER_PRESENT && TRC_SLEEP)*/ + +#if (TRACER_PRESENT && TRC_SW_ASS) +/** + **************************************************************************************** + * @brief Trace request API for software asserts + * + * This function is called when an assertion statement is evaluated as true. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "sw assertions" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] ass_trc_type Trace type for assertions (assert warning and assert error of @see enum trace_types) + * @param[in] filename Name of the file that triggered the assertion + * @param[in] code_line Line of code where the assertion was triggered + * @param[in] param0 Parameter value 0 + * @param[in] param1 Parameter value 1 + **************************************************************************************** + */ +void dbg_trc_req_sw_ass(uint8_t const ass_trc_type, char const *filename, uint16_t const code_line, uint32_t const param0, uint32_t const param1); + +/// Macro used to send trace request API when an assert warning is evaluated as true +#define TRC_REQ_SW_ASS_WARN(filename, code_line, param0, param1) \ + dbg_trc_req_sw_ass(ASSERT_WARNING, filename, code_line, param0, param1); + +/// Macro used to send trace request API when an assert warning is evaluated as true +#define TRC_REQ_SW_ASS_ERR(filename, code_line, param0, param1) \ + dbg_trc_req_sw_ass(ASSERT_ERROR, filename, code_line, param0, param1); + +#else /*(TRACER_PRESENT && TRC_SW_ASS)*/ +#define TRC_REQ_SW_ASS_WARN(filename, code_line, param0, param1) +#define TRC_REQ_SW_ASS_ERR(filename, code_line, param0, param1) +#endif /*(TRACER_PRESENT && TRC_SW_ASS)*/ + +#if (TRACER_PRESENT && TRC_PROG) +/** + **************************************************************************************** + * @brief Trace request API for exchange table programming + * + * This function is called when the exchange table is programmed. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "programming" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] elt_idx Index of the programmed entry in the ET + **************************************************************************************** + */ +void dbg_trc_req_et_prog(uint8_t const elt_idx); + +#define TRC_REQ_ET_PROG(elt_idx) \ + dbg_trc_req_et_prog(elt_idx); + +/** + **************************************************************************************** + * @brief Trace request API for connection event counter programming + * + * This function is called when the connection event counter is set. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "programming" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] conhdl Connection handle + * @param[in] value Value of connection event counter + **************************************************************************************** + */ +void dbg_trc_req_evt_cnt(uint16_t const conhdl, uint16_t const value); +#define TRC_REQ_EVT_CNT(conhdl, value) \ + dbg_trc_req_evt_cnt(conhdl, value); +/** + **************************************************************************************** + * @brief Trace request API for frame completion + * + * This function is called when a frame is completed. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "programming" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] timestamp Timestamp of the programmed frame (in BLE slots, based on local clock) + * @param[in] frm_id Frame identifier + * @param[in] frm_cbk Callback for handling interrupts related to the frame + **************************************************************************************** + */ +void dbg_trc_req_frm_cmp(uint32_t const timestamp, uint8_t const frm_id, uint32_t const frm_cbk); + +#define TRC_REQ_FRM_CMP(timestamp, frm_id, frm_cbk) \ + dbg_trc_req_frm_cmp(timestamp, frm_id, frm_cbk); + +#else /*(TRACER_PRESENT && TRC_PROG)*/ +#define TRC_REQ_ET_PROG(elt_idx) +#define TRC_REQ_EVT_CNT(conhdl, value) +#define TRC_REQ_FRM_CMP(timestamp, frm_id, frm_cbk) +#endif /*(TRACER_PRESENT && TRC_PROG)*/ + +#if (TRACER_PRESENT && TRC_CS_BLE) +/** + **************************************************************************************** + * @brief Trace request API for control structure programming in BLE + * + * This function is called when a control structure is modified. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "BLE control structure" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] cs_addr Address of the control structure in the exchange memory + **************************************************************************************** + */ +void dbg_trc_req_cs_ble(uint16_t const cs_addr); + +#define TRC_REQ_CS_BLE(cs_addr) \ + dbg_trc_req_cs_ble(cs_addr); + +#else /*(TRACER_PRESENT && TRC_CS_BLE)*/ +#define TRC_REQ_CS_BLE(cs_addr) +#endif /*(TRACER_PRESENT && TRC_CS_BLE)*/ + +#if (TRACER_PRESENT && TRC_CS_BT) +/** + **************************************************************************************** + * @brief Trace request API for control structure programming in BT + * + * This function is called when a control structure is modified. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "BT control structure" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] cs_addr Address of the control structure in the exchange memory + **************************************************************************************** + */ +void dbg_trc_req_cs_bt(uint16_t const cs_addr); + +#define TRC_REQ_CS_BT(cs_addr) \ + dbg_trc_req_cs_bt(cs_addr); +#else /*(TRACER_PRESENT && TRC_CS_BT)*/ +#define TRC_REQ_CS_BT(cs_addr) +#endif /*(TRACER_PRESENT && TRC_CS_BT)*/ + +#if (TRACER_PRESENT && TRC_RX_DESC) +/** + **************************************************************************************** + * @brief Trace request API for processing of rx descriptors + * + * This function is called when a packet is received and a driver processes a rx descriptor. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "Rx descriptor" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] drv_type LLD driver (@see enum driver_type) + * @param[in] act_id Activity identifier + * @param[in] rx_desc_add Address of the rx descriptor in the exchange memory + **************************************************************************************** + */ +void dbg_trc_req_rx_desc(uint8_t const drv_type, uint8_t const act_id, uint16_t const rx_desc_add); + +#define TRC_REQ_RX_DESC(drv_type, act_id, rx_desc_add) \ + dbg_trc_req_rx_desc(drv_type, act_id, rx_desc_add); + +#else /*(TRACER_PRESENT && TRC_RX_DESC)*/ +#define TRC_REQ_RX_DESC(drv_type, act_id, rx_desc_add) +#endif /*(TRACER_PRESENT && TRC_RX_DESC) */ + +#if (TRACER_PRESENT && TRC_LLCP) +/** + **************************************************************************************** + * @brief Trace request API for llcp packets transmission, reception and acknowledgment + * + * This function is called when a llcp packet is transmitted, received or acknowledged. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "LLCP" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] llcp_trc_type Trace type for llcp (llcp tx, llcp rx and llcp ack of @see enum trace_types) + * @param[in] conhdl Connection handle + * @param[in] data_len Data length (in bytes) + * @param[in] pdu_data PDU Data + **************************************************************************************** + */ +void dbg_trc_req_llcp(uint8_t const llcp_trc_type, uint16_t const conhdl, uint8_t const data_len, uint8_t const *pdu_data); + +/// Macro used to send trace request API when an llcp packet is transmitted +#define TRC_REQ_LLCP_TX(conhdl, data_len, pdu_data) \ + dbg_trc_req_llcp(LLCP_TX, conhdl, data_len, pdu_data); + +/// Macro used to send trace request API when an llcp packet is received +#define TRC_REQ_LLCP_RX(conhdl, data_len, pdu_data) \ + dbg_trc_req_llcp(LLCP_RX, conhdl, data_len, pdu_data); + +/// Macro used to send trace request API when an llcp packet is acknowledged +#define TRC_REQ_LLCP_ACK(conhdl, data_len, pdu_data) \ + dbg_trc_req_llcp(LLCP_ACK, conhdl, data_len, pdu_data); +#else /*(TRACER_PRESENT && TRC_LLCP)*/ +#define TRC_REQ_LLCP_TX(conhdl, data_len, pdu_data) +#define TRC_REQ_LLCP_RX(conhdl, data_len, pdu_data) +#define TRC_REQ_LLCP_ACK(conhdl, data_len, pdu_data) +#endif /*(TRACER_PRESENT && TRC_LLCP) */ + +#if (TRACER_PRESENT && TRC_LMP) +/** + **************************************************************************************** + * @brief Trace request API for lmp packets transmission, reception and acknowledgment + * + * This function is called when a lmp packet is transmitted, received or acknowledged. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "LMP" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] llcp_trc_type Trace type for lmp (lmp tx, lmp rx and lmp ack of @see enum trace_types) + * @param[in] conhdl Connection handle + * @param[in] data_len Data length (in bytes) + * @param[in] pdu_data PDU Data + **************************************************************************************** + */ +void dbg_trc_req_lmp(uint8_t const lmp_trc_type, uint16_t const conhdl, uint8_t const data_len, uint8_t const *pdu_data); + +/// Macro used to send trace request API when an lmp packet is transmitted +#define TRC_REQ_LMP_TX(conhdl, data_len, pdu_data) \ + dbg_trc_req_lmp(LMP_TX, conhdl, data_len, pdu_data); + +/// Macro used to send trace request API when an lmp packet is received +#define TRC_REQ_LMP_RX(conhdl, data_len, pdu_data) \ + dbg_trc_req_lmp(LMP_RX, conhdl, data_len, pdu_data); + +/// Macro used to send trace request API when an lmp packet is acknowledged +#define TRC_REQ_LMP_ACK(conhdl, data_len, pdu_data) \ + dbg_trc_req_lmp(LMP_ACK, conhdl, data_len, pdu_data); + +#else /*(TRACER_PRESENT && TRC_LMP)*/ +#define TRC_REQ_LMP_TX(conhdl, data_len, pdu_data) +#define TRC_REQ_LMP_RX(conhdl, data_len, pdu_data) +#define TRC_REQ_LMP_ACK(conhdl, data_len, pdu_data) +#endif /*(TRACER_PRESENT && TRC_LMP)*/ + +#if (TRACER_PRESENT && TRC_L2CAP) +/** + **************************************************************************************** + * @brief Trace request API for l2cap packets transmission and reception + * + * This function is called when a l2cap packet is transmitted or received. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "L2CAP" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] l2cap_trc_type Trace type for l2cap (l2cap tx and l2cap rx of @see enum trace_types) + * @param[in] conhdl Connection handle + * @param[in] data_len Data length (in bytes) + * @param[in] buf_ptr Memory pointer address + **************************************************************************************** + */ +void dbg_trc_req_l2cap(uint8_t const l2cap_trc_type, uint16_t const conhdl, uint16_t const data_len, uint32_t const buf_ptr); + +/// Macro used to send trace request API when an l2cap packet is transmitted +#define TRC_REQ_L2CAP_TX(conhdl, tx_len, buf_ptr) \ + dbg_trc_req_l2cap(L2CAP_TX, conhdl, tx_len, buf_ptr); + +/// Macro used to send trace request API when an l2cap packet is received +#define TRC_REQ_L2CAP_RX(conhdl, tx_len, buf_ptr) \ + dbg_trc_req_l2cap(L2CAP_RX, conhdl, tx_len, buf_ptr); + +/** + **************************************************************************************** + * @brief Trace request API for l2cap packet acknowledgment + * + * This function is called when l2cap packets are acknowledged. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "L2CAP" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] conhdl Connection handle + * @param[in] num_ack_pkts Number of acknowledged l2cap packets + **************************************************************************************** + */ +void dbg_trc_req_l2cap_ack(uint16_t const conhdl, uint16_t const num_ack_pkts); + +#define TRC_REQ_L2CAP_ACK(conhdl, num_ack_pkts) \ + dbg_trc_req_l2cap_ack(conhdl, num_ack_pkts); + +#else /*(TRACER_PRESENT && TRC_L2CAP)*/ +#define TRC_REQ_L2CAP_TX(conhdl, tx_len, buf_ptr) +#define TRC_REQ_L2CAP_RX(conhdl, tx_len, buf_ptr) +#define TRC_REQ_L2CAP_ACK(conhdl, num_ack_pkts) +#endif/*(TRACER_PRESENT && TRC_L2CAP) */ + +#if (TRACER_PRESENT && TRC_EA) +/** + **************************************************************************************** + * @brief Trace request API for cancellation, removal and starting of events + * + * This function is called when an event starts, is removed or is cancelled. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "EA" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] ea_trc_type Trace type for event arbiter (cancel, remove and start of @see enum trace_types) + * @param[in] ea_elt Pointer to the event arbiter element + **************************************************************************************** + */ +void dbg_trc_req_ea(uint8_t const ea_trc_type,const struct ea_elt_tag *ea_elt); + +/// Macro used to send trace request API when an event is cancelled +#define TRC_REQ_EA_CANC(ea_elt) \ + dbg_trc_req_ea(EA_CANC, ea_elt); + +/// Macro used to send trace request API when an event is removed +#define TRC_REQ_EA_REM(ea_elt) \ + dbg_trc_req_ea(EA_REM, ea_elt); + +/// Macro used to send trace request API when an event starts +#define TRC_REQ_EA_START(ea_elt) \ + dbg_trc_req_ea(EA_START, ea_elt); + +/** + **************************************************************************************** + * @brief Trace request API for shifting of events + * + * This function is called when an event is shifted. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "EA" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] ea_elt Pointer to the event arbiter element + **************************************************************************************** + */ +void dbg_trc_req_ea_shift(const struct ea_elt_tag *ea_elt); + +#define TRC_REQ_EA_SHIFT(ea_elt) \ + dbg_trc_req_ea_shift(ea_elt); +/** + **************************************************************************************** + * @brief Trace request API for pushing of event in the waiting queue + * + * This function is called when an event is pushed in the waiting queue. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "EA" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] ea_elt Pointer to the event arbiter element + **************************************************************************************** + */ +void dbg_trc_req_ea_insert(uint32_t const target_time, uint8_t const status, const struct ea_elt_tag *ea_elt); + +#define TRC_REQ_EA_INSERT(target_time, status, ea_elt) \ + dbg_trc_req_ea_insert(target_time, status, ea_elt); + +#else /*(TRACER_PRESENT && TRC_EA)*/ +#define TRC_REQ_EA_CANC(ea_elt) +#define TRC_REQ_EA_REM(ea_elt) +#define TRC_REQ_EA_START(ea_elt) +#define TRC_REQ_EA_SHIFT(ea_elt) +#define TRC_REQ_EA_INSERT(target_time, status, ea_elt) +#endif /*(TRACER_PRESENT && TRC_EA)*/ + +#if (TRACER_PRESENT && TRC_LC_STATE_TRANS) +/** + **************************************************************************************** + * @brief Trace request API for lc procedure state transition + * + * This function is called when an lc procedure changes its state. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "LC state transition" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] conhdl Connection handle + * @param[in] proc_type LC procedure + * @param[in] prev_state Previous procedure state + * @param[in] curr_state Current procedure state + **************************************************************************************** + */ +void dbg_trc_req_lc_state_trans(uint16_t const conhdl, uint8_t const proc_type, uint8_t const prev_state, uint8_t const curr_state); + +#define TRC_REQ_LC_STATE_TRANS(conhdl, proc_type, prev_state, curr_state) \ + dbg_trc_req_lc_state_trans(conhdl, proc_type, prev_state, curr_state); + +#else /*(TRACER_PRESENT && TRC_LC_STATE_TRANS)*/ +#define TRC_REQ_LC_STATE_TRANS(conhdl, proc_type, prev_state, curr_state) +#endif /*(TRACER_PRESENT && TRC_LC_STATE_TRANS)*/ + +#if (TRACER_PRESENT && TRC_LLC_STATE_TRANS) +/** + **************************************************************************************** + * @brief Trace request API for llc procedure state transition + * + * This function is called when an llcp procedure changes its state. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "LLC state transition" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] conhdl Connection handle + * @param[in] proc_type LLC procedure + * @param[in] prev_state Previous procedure state + * @param[in] curr_state Current procedure state + **************************************************************************************** + */ +void dbg_trc_req_llc_state_trans(uint16_t const conhdl, uint8_t const proc_type, uint8_t const prev_state, uint8_t const curr_state); + +#define TRC_REQ_LLC_STATE_TRANS(conhdl, proc_type, prev_state, curr_state) \ + dbg_trc_req_llc_state_trans(conhdl, proc_type, prev_state, curr_state); + +#else /*(TRACER_PRESENT && TRC_LLC_STATE_TRANS)*/ +#define TRC_REQ_LLC_STATE_TRANS(conhdl, proc_type, prev_state, curr_state) +#endif /*(TRACER_PRESENT && TRC_LLC_STATE_TRANS)*/ + +#if (TRACER_PRESENT && TRC_HCI) +/** + **************************************************************************************** + * @brief Trace request API for HCI messages (in FE mode) + * + * This function is called when a HCI command is received or a HCI event is sent. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "HCI" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] hci_msg_type Type of hci message (HCI command and event of @see enum trace_types) + * @param[in] opcode HCI opcode + * @param[in] par_len HCI parameter length + * @param[in] params unpacked HCI parameters + **************************************************************************************** + */ +void dbg_trc_req_hci(uint8_t const hci_msg_type, uint16_t const opcode, uint16_t const par_len, uint32_t const *params); + +/// Macro used to send trace request API when an HCI command is received +#define TRC_REQ_HCI_CMD(opcode, par_len, params) \ + dbg_trc_req_hci(HCI_CMD, opcode, par_len, params); + +/// Macro used to send trace request API when an HCI event is sent +#define TRC_REQ_HCI_EVT(opcode, par_len, params) \ + dbg_trc_req_hci(HCI_EVT, opcode, par_len, params); + +#else /*(TRACER_PRESENT && TRC_HCI)*/ +#define TRC_REQ_HCI_CMD(opcode, par_len, params) +#define TRC_REQ_HCI_EVT(opcode, par_len, params) +#endif /*(TRACER_PRESENT && TRC_HCI)*/ + +#if (TRACER_PRESENT && TRC_CUSTOM) +/** + **************************************************************************************** + * @brief Trace request API for custom traces + * + * This function is called to send a custom trace. + * + * It checks the current tracer configuration and writes the trace in memory if the trace + * group "custom" (@see enum tracer_cfg_fields) is enabled. + * + * @param[in] trc_id Trace request identifier (progressive number that identifies the caller) + * @param[in] data_type Type of data (@see enum custom_trace_type) + * @param[in] data Pointer to the data to send + **************************************************************************************** + */ +void dbg_trc_req_custom(const uint8_t trc_id, const uint8_t data_type, void const *data); +#define TRC_REQ_CUSTOM(trc_id, data_type, data) \ + dbg_trc_req_custom(trc_id, data_type, data); +#else /*(TRACER_PRESENT && TRC_CUSTOM)*/ +#define TRC_REQ_CUSTOM(trc_id, data_type, data) +#endif /*(TRACER_PRESENT && TRC_CUSTOM)*/ + +#if (TRACER_PRESENT) +/** + **************************************************************************************** + * @brief Configuration received + * + * This function checks if the received configuration can be adopted and acknowledges it + * + **************************************************************************************** + */ +void dbg_trc_cfg_received(); + +/** + **************************************************************************************** + * @brief Get the reception buffer for configuration word + * + * @return Buffer for payload reception of tracer configuration packets + **************************************************************************************** + */ +uint8_t* dbg_trc_pay_buff_get(); +#endif /*(TRACER_PRESENT)*/ +///@} TRACER +#endif // DBG_TRC_H_ diff --git a/services/ble_stack/dbg/api/dbg_trc_config.h b/services/ble_stack/dbg/api/dbg_trc_config.h new file mode 100644 index 0000000..dbef865 --- /dev/null +++ b/services/ble_stack/dbg/api/dbg_trc_config.h @@ -0,0 +1,198 @@ +#ifndef DBG_TRC_CONFIG_H_ +#define DBG_TRC_CONFIG_H_ + +/** + **************************************************************************************** + * @addtogroup TRACER + * @{ + * @name Tracer module configuration + * @{ + **************************************************************************************** + */ + +#if defined CFG_TRC_ALL +#define TRC_KE_MSG 1 +#define TRC_KE_TMR 1 +#define TRC_KE_EVT 1 +#define TRC_MEM 1 +#define TRC_SLEEP 1 +#define TRC_SW_ASS 1 +#define TRC_PROG 1 +#define TRC_RX_DESC 1 +#define TRC_CUSTOM 1 +#define TRC_EA 1 + +#if (BLE_EMB_PRESENT) +#define TRC_CS_BLE 1 +#define TRC_LLCP 1 +#define TRC_LLC_STATE_TRANS 1 + +#if (BLE_HOST_PRESENT) +#define TRC_HCI 1 +#define TRC_L2CAP 1 +#else +#define TRC_HCI 0 +#define TRC_L2CAP 0 +#endif /*(BLE_HOST_PRESENT)*/ + +#else +#define TRC_CS_BLE 0 +#define TRC_LLCP 0 +#define TRC_LLC_STATE_TRANS 0 +#define TRC_HCI 0 +#define TRC_L2CAP 0 +#endif /*(BLE_EMB_PRESENT)*/ + +#if (BT_EMB_PRESENT) +#define TRC_CS_BT 1 +#define TRC_LMP 1 +#define TRC_LC_STATE_TRANS 1 +#else +#define TRC_CS_BT 0 +#define TRC_LMP 0 +#define TRC_LC_STATE_TRANS 0 +#endif /*(BT_EMB_PRESENT)*/ + +#else /*(CFG_TRC_ALL)*/ + +#if defined CFG_TRC_KE_MSG +#define TRC_KE_MSG 1 +#else +#define TRC_KE_MSG 0 +#endif /*(CFG_TRC_KE_MSG)*/ + +#if defined CFG_TRC_KE_TMR +#define TRC_KE_TMR 1 +#else +#define TRC_KE_TMR 0 +#endif /*CFG_TRC_KE_TMR*/ + +#if defined CFG_TRC_KE_EVT +#define TRC_KE_EVT 1 +#else +#define TRC_KE_EVT 0 +#endif /*CFG_TRC_KE_EVT*/ + +#if defined CFG_TRC_MEM +#define TRC_MEM 1 +#else +#define TRC_MEM 0 +#endif /*CFG_TRC_MEM*/ + +#if defined CFG_TRC_SLEEP +#define TRC_SLEEP 1 +#else +#define TRC_SLEEP 0 +#endif /*CFG_TRC_SLEEP*/ + +#if defined CFG_TRC_SW_ASS +#define TRC_SW_ASS 1 +#else +#define TRC_SW_ASS 0 +#endif /*CFG_TRC_SW_ASS*/ + +#if defined CFG_TRC_PROG +#define TRC_PROG 1 +#else +#define TRC_PROG 0 +#endif /*CFG_TRC_PROG*/ + +#if defined CFG_TRC_RX_DESC +#define TRC_RX_DESC 1 +#else +#define TRC_RX_DESC 0 +#endif /*CFG_TRC_RX_DESC*/ + +#if defined CFG_TRC_CUSTOM +#define TRC_CUSTOM 1 +#else +#define TRC_CUSTOM 0 +#endif /*CFG_TRC_CUSTOM*/ + +#if defined CFG_TRC_EA +#define TRC_EA 1 +#else +#define TRC_EA 0 +#endif /*CFG_TRC_EA*/ + +#if (BLE_EMB_PRESENT) +#if defined CFG_TRC_CS_BLE +#define TRC_CS_BLE 1 +#else +#define TRC_CS_BLE 0 +#endif /*(CFG_TRC_CS_BLE)*/ + +#if defined CFG_TRC_LLCP +#define TRC_LLCP 1 +#else +#define TRC_LLCP 0 +#endif /*(CFG_TRC_LLCP)*/ + +#if defined CFG_TRC_LLC_STATE_TRANS + +#define TRC_LLC_STATE_TRANS 1 +#else +#define TRC_LLC_STATE_TRANS 0 +#endif /*(CFG_TRC_LLC_STATE_TRANS)*/ + +#if (BLE_HOST_PRESENT) + +#if defined CFG_TRC_L2CAP +#define TRC_L2CAP 1 +#else +#define TRC_L2CAP 0 +#endif /*CFG_TRC_L2CAP*/ + +#if defined CFG_TRC_HCI +#define TRC_HCI 1 +#else +#define TRC_HCI 0 +#endif /*CFG_TRC_HCI*/ + +#else /*BLE_HOST_PRESENT*/ + +#define TRC_L2CAP 0 +#define TRC_HCI 0 +#endif /*BLE_HOST_PRESENT*/ + +#else /*BLE_EMB_PRESENT*/ + +#define TRC_CS_BLE 0 +#define TRC_LLCP 0 +#define TRC_LLC_STATE_TRANS 0 +#define TRC_L2CAP 0 +#define TRC_HCI 0 + +#endif /*BLE_EMB_PRESENT*/ + +#if (BT_EMB_PRESENT) + +#if defined CFG_TRC_CS_BT +#define TRC_CS_BT 1 +#else +#define TRC_CS_BT 0 +#endif /*CFG_TRC_CS_BT*/ + +#if defined CFG_TRC_LMP +#define TRC_LMP 1 +#else +#define TRC_LMP 0 +#endif /*CFG_TRC_LMP*/ + +#if defined CFG_TRC_LC_STATE_TRANS +#define TRC_LC_STATE_TRANS 1 +#else +#define TRC_LC_STATE_TRANS 0 +#endif /*CFG_TRC_LC_STATE_TRANS*/ + +#else /*BT_EMB_PRESENT*/ + +#define TRC_CS_BT 0 +#define TRC_LMP 0 +#define TRC_LC_STATE_TRANS 0 + +#endif /*BT_EMB_PRESENT*/ + +#endif /* CFG_TRC_ALL */ +/// @} TRACER +#endif /* DBG_TRC_CONFIG_H_ */ diff --git a/services/ble_stack/dbg/src/dbg_trc_int.h b/services/ble_stack/dbg/src/dbg_trc_int.h new file mode 100644 index 0000000..68fc132 --- /dev/null +++ b/services/ble_stack/dbg/src/dbg_trc_int.h @@ -0,0 +1,146 @@ +#ifndef DBG_TRC_INT_H_ +#define DBG_TRC_INT_H_ + +/** + **************************************************************************************** + * @addtogroup TRACER + * @{ + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (TRACER_PRESENT) +#include // standard definitions +#include // boolean + +/* + * DEFINES + **************************************************************************************** + */ + +///Channel index length +#define CHANNEL_ID_LEN 1 + +///lengths of trace packet fields +#define SEQ_NUM_LEN 2 +#define TIMESTAMP_LEN 4 +#define TRC_CODE_LEN 1 + +#define TRC_FIX_LEN \ + CHANNEL_ID_LEN +\ + TRC_MSG_HDR_LEN +\ + SEQ_NUM_LEN +\ + TIMESTAMP_LEN +\ + TRC_CODE_LEN + +/** + **************************************************************************************** + * @brief Convenient wrapper to trc_mem_alloc() + * + * This macro calls trc_mem_alloc() passing as parameter the length of the trace packet + * + * @param[in] trace_pay Trace payload length + * + * @return Pointer to trace code field(or NULL if the trace cannot be written) + **************************************************************************************** + */ +#define TRC_MEM_ALLOC(trace_pay) \ + dbg_trc_mem_alloc(TRC_FIX_LEN + trace_pay) + +typedef uint8_t trc_id_t; +typedef uint8_t trc_opcode_t; + +/* + * STRUCTURES DEFINITIONS + **************************************************************************************** + */ +///Tracer Environment context structure +struct dbg_trc_env_tag +{ + /// Current tracer configuration word + uint32_t curr_cw; + + /// Compiled tracer configuration word + uint32_t compiled_cw; +}; + +/* + * GLOBAL VARIABLE DEFINITIONS + **************************************************************************************** + */ +///Tracer environment context +extern struct dbg_trc_env_tag dbg_trc_env; + +/* + * TRANSPORT LAYER FUNCTION DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief initialize tracer TL + **************************************************************************************** + */ +void dbg_trc_tl_init(); + +/** + **************************************************************************************** + * @brief trigger the transmission of tracer packets + **************************************************************************************** + */ +void dbg_trc_tx_trigger(void); + +/* + * MEMORY FUNCTION DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialize tracer memory + **************************************************************************************** + */ +void dbg_trc_mem_init(); + +/** + **************************************************************************************** + * @brief Try to write a trace in memory. + * @param[in] trace_len Trace packet length (expressed in bytes) + * + * @return Pointer to trace code field(or NULL if the trace cannot be written) + **************************************************************************************** + */ +uint8_t *dbg_trc_mem_alloc(uint16_t const trace_len); + +/** + **************************************************************************************** + * @brief Try to read a trace from the memory. + * + * @return Pointer to the total size of the trace (or NULL if the trace cannot be read) + **************************************************************************************** + */ +uint8_t *dbg_trc_mem_read(); + +/** + **************************************************************************************** + * @brief Deallocate a trace from the memory. + * + * This function marks the trace block pointed by the reading pointer as invalid and moves + * it to the next trace block + * + **************************************************************************************** + */ +void dbg_trc_mem_dealloc(); + +/** + **************************************************************************************** + * @brief Initialization of the tracer + * + * This function initializes the tracer + * + **************************************************************************************** + */ +void dbg_trc_init(bool reset); + +#endif /* TRACER_PRESENT */ +/// @} TRACER +#endif /* DBG_TRC_INT_H_ */ diff --git a/services/ble_stack/hci/api/hci_ble.h b/services/ble_stack/hci/api/hci_ble.h new file mode 100644 index 0000000..208b35f --- /dev/null +++ b/services/ble_stack/hci/api/hci_ble.h @@ -0,0 +1,525 @@ +#ifndef HCI_H_ +#define HCI_H_ + +/** + **************************************************************************************** + * @addtogroup HCI Host Controller Interface + * @ingroup ROOT + * @brief HCI module handling communication between lower and higher layers in split + * architecture. + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (HCI_PRESENT) + +#include // standard definition +#include // standard integer +#include "co_bt.h" // BT standard definitions + +#include "rwip_task.h" // Task definitions + +#include "bridge.h" + +/* + * DEFINES + **************************************************************************************** + */ + +#if (BLE_EMB_PRESENT || BLE_HOST_PRESENT) +#if (BLE_CENTRAL || BLE_PERIPHERAL) +#define HCI_BLE_CON_SUPPORT 1 +#else // (BLE_CENTRAL || BLE_PERIPHERAL) +#define HCI_BLE_CON_SUPPORT 0 +#endif // (BLE_CENTRAL || BLE_PERIPHERAL) +#else //(BLE_EMB_PRESENT || BLE_HOST_PRESENT) +#define HCI_BLE_CON_SUPPORT 0 +#endif //(BLE_EMB_PRESENT || BLE_HOST_PRESENT) + +/// Length of HCI Reset Message +#define HCI_RESET_MSG_LEN 4 + +/// HCI Reset Message use to resync. +#define HCI_RESET_MSG_BUF {HCI_CMD_MSG_TYPE, (HCI_RESET_CMD_OPCODE & 0xFF), ((HCI_RESET_CMD_OPCODE >> 8) & 0xFF), 0} + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Message API of the HCI task +enum HCI_MSG +{ + HCI_MSG_ID_FIRST = TASK_FIRST_MSG(TASK_ID_HCI), + + HCI_CMD_CMP_EVENT, + HCI_CMD_STAT_EVENT, + HCI_EVENT, + HCI_LE_EVENT, + + HCI_COMMAND, + + #if (HCI_BLE_CON_SUPPORT) + HCI_BLE_ACL_DATA_RX, + HCI_BLE_ACL_DATA_TX, + #endif // (HCI_BLE_CON_SUPPORT) + + #if BT_EMB_PRESENT + HCI_BT_ACL_DATA_TX, + HCI_BT_ACL_DATA_RX, + #if VOICE_OVER_HCI + HCI_BT_SYNC_DATA_TX, + HCI_BT_SYNC_DATA_RX, + #endif //VOICE_OVER_HCI + #endif //BT_EMB_PRESENT + + HCI_TCI_LMP, + + HCI_DBG_EVT, + + HCI_MSG_ID_LAST +}; + +/// Status of HCI command header processing +enum HCI_CMD_HDR +{ + /// Header is correct + HCI_CMD_HDR_STATUS_OK, + /// Opcode is unknown + HCI_CMD_HDR_STATUS_UNKNOWN, + /// Header is not correct + HCI_CMD_HDR_STATUS_FAIL +}; + + + +///HCI Command header components structure +struct hci_cmd_hdr +{ + /// Opcode field + uint16_t opcode; + ///Parameter length - the number of bytes of the command parameters + uint8_t parlen; +}; + +///HCI ACL data packets header structure +struct hci_acl_hdr +{ + ///Connection handle & Data Flags + uint16_t hdl_flags; + ///Data length in number of bytes + uint16_t datalen; +}; + +#if (BT_EMB_PRESENT) +#if (VOICE_OVER_HCI) +///HCI synchronous data packets header structure +struct hci_sync_hdr +{ + /// Connection handle & Data Flags + uint16_t conhdl_flags; + /// Data total length in number of bytes + uint8_t data_total_len; +}; +#endif // (VOICE_OVER_HCI) +#endif // (BT_EMB_PRESENT) + +///HCI Event header components structure - contains all details possible in an event +struct hci_evt_hdr +{ + ///Event code + uint8_t code; + ///Event parameters length + uint8_t parlen; +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** +**************************************************************************************** +* @brief Initialize HCI (including transport) +***************************************************************************************** +*/ +void hci_init(bool reset); + +#if (BLE_EMB_PRESENT || BT_EMB_PRESENT) +/** + **************************************************************************************** + * @brief Function called when an internal task needs to send a HCI message to Host + * + * This function decides whether the message is sent externally onto HCI Transport Layer + * or redirected into an internal task of the other side of the HCI. + * + * The input message ID, length and parameters must be filled. + * In case the message is an HCI command or event, the source ID must be filled with the + * command opcode or event code. + * In case the message concerns a particular BT or BLE link, the destination ID must be + * filled with the associated link ID. + * + * @param[in] param Pointer to the parameters of the Kernel message carrying the HCI message + ***************************************************************************************** + */ +void hci_send_2_host(void *param); +#endif // (BLE_EMB_PRESENT || BT_EMB_PRESENT) + +#if BLE_HOST_PRESENT +/** + **************************************************************************************** + * @brief Function called when an internal task needs to send a HCI message to Controller + * + * This function decides whether the message is sent externally onto HCI Transport Layer + * or redirected into an internal task of the other side of the HCI. + * + * The input message ID, length and parameters must be filled. + * In case the message is an HCI command or event, the source ID must be filled with the + * command opcode or event code. + * In case the message concerns a particular BT or BLE link, the destination ID must be + * filled with the associated link ID. + * + * @param[in] param Pointer to the parameters of the Kernel message carrying the HCI message + ***************************************************************************************** + */ +void hci_send_2_controller(void *param); + +/** + **************************************************************************************** + * @brief function used to send a basic command, without parameters to the controller. + * + * @param[in] opcode Operation code of the command + ***************************************************************************************** + */ +void hci_basic_cmd_send_2_controller(uint16_t opcode); +#endif //BLE_HOST_PRESENT + +#if (BLE_EMB_PRESENT && HCI_BLE_CON_SUPPORT) +/** + **************************************************************************************** + * @brief Register connection handle for a BLE connection + * + * @param[in] link_id BLE connection link ID + ***************************************************************************************** + */ +void hci_ble_conhdl_register(uint8_t link_id); + +/** + **************************************************************************************** + * @brief Unregister a BLE connection + * + * @param[in] link_id BLE connection link ID + ***************************************************************************************** + */ +void hci_ble_conhdl_unregister(uint8_t link_id); +#endif //(BLE_EMB_PRESENT && !BLE_HOST_PRESENT && HCI_BLE_CON_SUPPORT) + +#if (BT_EMB_PRESENT) +/** + **************************************************************************************** + * @brief Register BD address for a BT ACL connection + * + * @param[in] link_id BT ACL connection link ID + * @param[in] bd_addr Pointer to the device BD address associated to the connection + ***************************************************************************************** + */ +void hci_bt_acl_bdaddr_register(uint8_t link_id, struct bd_addr* bd_addr); +/** + **************************************************************************************** + * @brief Register connection handle for a BT ACL connection + * + * @param[in] link_id BT ACL connection link ID + ***************************************************************************************** + */ +void hci_bt_acl_conhdl_register(uint8_t link_id); + +/** + **************************************************************************************** + * @brief Unregister a BT ACL connection + * + * @param[in] link_id BT ACL connection link ID + ***************************************************************************************** + */ +void hci_bt_acl_bdaddr_unregister(uint8_t link_id); + +#endif //(BT_EMB_PRESENT) + +/** + **************************************************************************************** + * @brief Set the event mask + * + * @param[in] evt_msk Pointer to the new event mask + * @param[in] page indicate which event page should be changed + * + * @return The status of the event mask saving + ***************************************************************************************** + */ +uint8_t hci_evt_mask_set(struct evt_mask const *evt_msk, uint8_t page); + +#if (BT_EMB_PRESENT) +/** + **************************************************************************************** + * @brief Add an event filter according to the parameters of the HCI command + * + * Note: the consistency of the parameters according to the input has already been checked by HCI during the special + * unpacking. + * + * @param[in] param Pointer to the HCI parameter + * + * @return The status of the filter addition + ***************************************************************************************** + */ +uint8_t hci_evt_filter_add(struct hci_set_evt_filter_cmd const *param); + +#if (MAX_NB_SYNC > 0) +/** + **************************************************************************************** + * @brief Get voice setting (for SCO auto-accept via event filter) + * + * @return Voice settings + ***************************************************************************************** + */ +uint16_t hci_voice_settings_get(void); + +/** + **************************************************************************************** + * @brief Set voice setting (for SCO auto-accept via event filter) + * + * @param[in] voice_settings Voice settings + * + * @return Status (0: Success | Others: failure) + ***************************************************************************************** + */ +uint8_t hci_voice_settings_set(uint16_t voice_settings); +#endif // (MAX_NB_SYNC > 0) +#endif //(BT_EMB_PRESENT) + +#if (HCI_TL_SUPPORT) +#if (BLE_EMB_PRESENT || BT_EMB_PRESENT) +/** + **************************************************************************************** + * @brief Get the maximum parameter size for a specific command + * + * This function is used by TL to know the theoretical maximum parameters size for a + * specific HCI command. + * Note: if the command is not supported by HCI (unknown), the maximum possible value of + * 255 bytes is returned. + * + * @param[in] opcode Opcode received + * + * @return The command maximum parameters size / 255 if command is unknown + ***************************************************************************************** + */ +uint8_t hci_cmd_get_max_param_size(uint16_t opcode); + +/** + **************************************************************************************** + * @brief Indicates that a HCI command has been received + * + * This function is used by TL to indicate the reception of a HCI command. + * + * @param[in] opcode Command Opcode + * @param[in] length Parameters length + * @param[in] payload Pointer to payload + ***************************************************************************************** + */ +void hci_cmd_received(uint16_t opcode, uint8_t length, uint8_t *payload); + +/** + **************************************************************************************** + * @brief Allocates the reception buffer for ACL TX data + * + * @param[in] hdl_flags Connection handle and data flags from HCI ACL packet header + * @param[in] len Length to receive (from HCI ACL packet header) + * + * @return Buffer for data reception (NULL if not possible to allocate one) + ***************************************************************************************** + */ +uint8_t* hci_acl_tx_data_alloc(uint16_t hdl_flags, uint16_t len); + +/** + **************************************************************************************** + * @brief Indicates that a HCI ACL TX data packet has been received + * + * This function is used by TL to indicate the reception of a HCI ACL TX data. + * + * @param[in] hdl_flags Connection handle and data flags from HCI ACL packet header + * @param[out] datalen Data length + * @param[in] payload Pointer to payload + ***************************************************************************************** + */ +void hci_acl_tx_data_received(uint16_t hdl_flags, uint16_t datalen, uint8_t * payload); + +#if (BT_EMB_PRESENT) +#if (VOICE_OVER_HCI) +/** + **************************************************************************************** + * @brief Allocates the reception buffer for Sync TX data + * + * @param[in] conhdl_flags Connection handle and data flags from HCI Sync packet header + * @param[in] len Length to receive (from HCI Sync packet header) + * + * @return Buffer for data reception (NULL if not possible to allocate one) + ***************************************************************************************** + */ +uint8_t* hci_sync_tx_data_alloc(uint16_t conhdl_flags, uint8_t len); + +/** + **************************************************************************************** + * @brief Indicates that a HCI Sync TX data packet has been received + * + * This function is used by TL to indicate the reception of a HCI Sync TX data. + * + * @param[in] conhdl_flags Connection handle and data flags from HCI Sync packet header + * @param[in] len Length to receive (from HCI Sync packet header) + * @param[in] payload Pointer to payload + ***************************************************************************************** + */ +void hci_sync_tx_data_received(uint16_t conhdl_flags, uint8_t len, uint8_t * payload); +#endif // (VOICE_OVER_HCI) +#endif // (BT_EMB_PRESENT) +#endif // (BLE_EMB_PRESENT || BT_EMB_PRESENT) + +#if ((BLE_HOST_PRESENT) && (!BLE_EMB_PRESENT)) +/** + **************************************************************************************** + * @brief Allocates the reception buffer for ACL RX data + * + * @param[in] hdl_flags Connection handle and data flags from HCI ACL RX packet header + * @param[in] len Length to receive (from HCI ACL packet header) + * + * @return Buffer for data reception (NULL if not possible to allocate one) + ***************************************************************************************** + */ +uint8_t* hci_acl_rx_data_alloc(uint16_t hdl_flags, uint16_t len); + +/** + **************************************************************************************** + * @brief Indicates that a HCI ACL RX data packet has been received + * + * This function is used by TL to indicate the reception of a HCI ACL RX data. + * + * @param[in] hdl_flags Connection handle and data flags from HCI ACL packet header + * @param[out] datalen Data length + * @param[in] payload Pointer to payload + ***************************************************************************************** + */ +//void hci_acl_rx_data_received(uint16_t hdl_flags, uint16_t datalen, uint8_t * payload); +void hci_acl_rx_data_received_payload(uint16_t hdl_flags, uint16_t datalen, uint8_t *payload, uint8_t *priv); +void hci_acl_rx_data_received(uint16_t hdl_flags, uint16_t datalen, BridgeBuffer *briBuffer); + +/** + **************************************************************************************** + * @brief Indicates that a HCI event has been received + * + * This function is used by TL to indicate the reception of a HCI event. + * + * @param[in] code Event code + * @param[in] length Parameters length + * @param[in] payload Pointer to payload + * + * @return status of receive operation + ***************************************************************************************** + */ +//uint8_t hci_evt_received(uint8_t code, uint8_t length, uint8_t *payload); +uint8_t hci_evt_received_payload(uint8_t code, uint8_t length, uint8_t *payload); +uint8_t hci_evt_received(uint8_t code, uint8_t length, BridgeBuffer *briBuffer); + +/** + **************************************************************************************** + * @brief Check if passing command opcode is supported by ble stack + * + * This function is used to check if passing command opcode is supported by ble stack + * + * @param[in] opcode Command Opcode + * + * @return 1 if supported or 0 + ***************************************************************************************** + */ +uint8_t hci_is_cmd_opcode_supported(uint16_t opcode); + +#endif // ((BLE_HOST_PRESENT) && (!BLE_EMB_PRESENT)) + +#endif // HCI_TL_SUPPORT + +//common for both BLE & BT +/** + **************************************************************************************** + * @brief process HostBufferSize + * + * @param[in] acl_pkt_len ACL packet length + * @param[in] nb_acl_pkts Number of ACL packets + * + * @return status + ***************************************************************************************** + */ +uint8_t hci_fc_acl_buf_size_set(uint16_t acl_pkt_len, uint16_t nb_acl_pkts); +/** + **************************************************************************************** + * @brief process HostBufferSize + * + * @param[in] sync_pkt_len SYNC packet length + * @param[in] nb_sync_pkts Number of SYNC packets + * + * @return status + ***************************************************************************************** + */ +uint8_t hci_fc_sync_buf_size_set(uint8_t sync_pkt_len, uint16_t nb_sync_pkts); + +/** + **************************************************************************************** + * @brief set the state of the ACL flow control + * + * @param[in] flow_enable boolean state of control + * + * @return status + ***************************************************************************************** + */ +uint8_t hci_fc_acl_en(bool flow_enable); + +/** + **************************************************************************************** + * @brief set the state of the SYNC flow control + * + * @param[in] flow_enable boolean state of control + ***************************************************************************************** + */ +void hci_fc_sync_en(bool flow_enable); + +/** + **************************************************************************************** + * @brief update data packet counters according to HostNumberOfCompletePackets + * + * @param[in] acl_pkt_nb accumulated number for ACL handles + ***************************************************************************************a** + */ +void hci_fc_host_nb_acl_pkts_complete(uint16_t acl_pkt_nb); + +/** + **************************************************************************************** + * @brief update data packet counters according to HostNumberOfCompletePackets + * + * @param[in] sync_pkt_nb accumulated number for SCO handles + ***************************************************************************************a** + */ +void hci_fc_host_nb_sync_pkts_complete(uint16_t sync_pkt_nb); + +#endif //HCI_PRESENT + +/// @} HCI + +#endif // HCI_H_ diff --git a/services/ble_stack/hci/src/hci_int.h b/services/ble_stack/hci/src/hci_int.h new file mode 100644 index 0000000..1d323b0 --- /dev/null +++ b/services/ble_stack/hci/src/hci_int.h @@ -0,0 +1,454 @@ +#ifndef HCI_INT_H_ +#define HCI_INT_H_ + +/** + **************************************************************************************** + * @addtogroup HCI Host Controller Interface + *@{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // SW configuration + +#if (HCI_PRESENT) + +#include // standard definition +#include // standard integer +#include "co_bt.h" // BT standard definitions + +#include "hci_ble.h" +#include "ke_msg.h" // Kernel message definitions + +/* + * DEFINES + **************************************************************************************** + */ + +/// Macro to get OCF of a known command +#define OCF(cmd) (HCI_OP2OCF(HCI_##cmd##_CMD_OPCODE)) + +/// Unknown opcode identifier +#define HCI_OPCODE_UNKNOWN 0xFFFF + +/** + * Destination field decoding + * + * bit | 7 6 | 5 4 | 3..0 | + * def | Rsvd (pkupk) | HL | LL | + */ +#define HCI_CMD_DEST_LL_POS 0 +#define HCI_CMD_DEST_LL_MASK 0x0F +#define HCI_CMD_DEST_HL_POS 4 +#define HCI_CMD_DEST_HL_MASK 0x30 + +/** + * Destination field decoding + * + * bit | 7..2 | 1 0 | + * def | Rsvd | HL | + */ +#define HCI_EVT_DEST_HL_POS 0 +#define HCI_EVT_DEST_HL_MASK 0x03 + +#if (HCI_TL_SUPPORT) + +/// Special Pack-Unpack settings for HCI commands (parameters and return parameters) +/** + * Special Pack-Unpack settings for HCI commands (parameters and return parameters) + * + * bit | 7 | 6 | 5..0 | + * def | RET PAR | PAR | Rsvd | + */ +#define HCI_CMD_DEST_SPEC_PAR_PK_POS 6 +#define HCI_CMD_DEST_SPEC_PAR_PK_MSK 0x40 +#define HCI_CMD_DEST_SPEC_RET_PAR_PK_POS 7 +#define HCI_CMD_DEST_SPEC_RET_PAR_PK_MSK 0x80 +#define PK_GEN_GEN (0x00) +#define PK_GEN_SPE (HCI_CMD_DEST_SPEC_RET_PAR_PK_MSK) +#define PK_SPE_GEN (HCI_CMD_DEST_SPEC_PAR_PK_MSK) +#define PK_SPE_SPE (HCI_CMD_DEST_SPEC_RET_PAR_PK_MSK | HCI_CMD_DEST_SPEC_PAR_PK_MSK) + +/// Special Pack settings for HCI events +#define PK_GEN 0x00 +#define PK_SPE 0x01 + +/// Macro for building a command descriptor in split mode (with parameters packing/unpacking) +#define CMD(opcode, dest_ll, dest_hl, pkupk, par_size_max, par_fmt, ret_fmt) {HCI_##opcode##_CMD_OPCODE, (dest_ll< 0) + /** + * Voice settings used when SCO connection is auto-accepted + */ + uint16_t voice_settings; + #endif //(MAX_NB_SYNC > 0) + + /** + * Auto-reject flag, used to filter the complete event when a request has been auto-rejected + */ + bool auto_reject; + + #elif (BLE_HOST_PRESENT && !BLE_EMB_PRESENT && (BLE_CENTRAL || BLE_PERIPHERAL)) + /// Link association table for BLE link-oriented messages routing + struct hci_ble_acl_con_tag ble_acl_con_tab[BLE_CONNECTION_MAX]; + + #endif //(BT_EMB_PRESENT) +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +#if BLE_HOST_PRESENT +extern const uint8_t hl_task_type[]; +#endif //BLE_HOST_PRESENT + +///HCI environment context +extern struct hci_env_tag hci_env; + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** +**************************************************************************************** +* @brief Look for a command descriptor that could match with the specified opcode +* +* @param[in] opcode Command opcode +* +* @return Pointer the command descriptor (NULL if not found) +***************************************************************************************** +*/ +const struct hci_cmd_desc_tag* hci_look_for_cmd_desc(uint16_t opcode); + +/** +**************************************************************************************** +* @brief Look for an event descriptor that could match with the specified event code +* +* @param[in] code event code +* +* @return Pointer the event descriptor (NULL if not found) +***************************************************************************************** +*/ +const struct hci_evt_desc_tag* hci_look_for_evt_desc(uint8_t code); + + +/** +**************************************************************************************** +* @brief Look for an event descriptor that could match with the specified DBG subcode +* +* @param[in] subcode DBG event subcode +* +* @return Pointer the event descriptor (NULL if not found) +***************************************************************************************** +*/ +const struct hci_evt_desc_tag* hci_look_for_dbg_evt_desc(uint8_t subcode); + +#if (BLE_EMB_PRESENT || BLE_HOST_PRESENT) +/** +**************************************************************************************** +* @brief Look for an event descriptor that could match with the specified LE subcode +* +* @param[in] subcode LE event subcode +* +* @return Pointer the event descriptor (NULL if not found) +***************************************************************************************** +*/ +const struct hci_evt_desc_tag* hci_look_for_le_evt_desc(uint8_t subcode); + +#endif //(BLE_EMB_PRESENT || BLE_HOST_PRESENT) + +#if (HCI_TL_SUPPORT) +/** + **************************************************************************************** + * @brief Initialize HIC TL part + ***************************************************************************************** + */ +void hci_tl_init(bool reset); + +/** + **************************************************************************************** + * @brief Send an HCI message over TL + * + * @param[in] msg Kernel message carrying the HCI message + ***************************************************************************************** + */ +void hci_tl_send(struct ke_msg *msg); +#endif //(HCI_TL_SUPPORT) + +/** + **************************************************************************************** + * @brief Initialize Flow Control Structure + * + ***************************************************************************************** + */ +void hci_fc_init(void); + +/** + **************************************************************************************** + * @brief count ACL packets sent to Host + * + ***************************************************************************************** + */ +void hci_fc_acl_packet_sent(void); + +/** + **************************************************************************************** + * @brief count SCO packets sent to Host + * + ***************************************************************************************** + */ +void hci_fc_sync_packet_sent(void); + +/** + **************************************************************************************** + * @brief Calculate number of ACL packets slots available on Host side + * + * @return number of packets available + ***************************************************************************************** + */ +uint16_t hci_fc_check_host_available_nb_acl_packets(void); + +/** + **************************************************************************************** + * @brief Calculate number of SCO packets slots available on Host side + * + * @return number of packets available + ***************************************************************************************** + */ +uint16_t hci_fc_check_host_available_nb_sync_packets(void); + + +#endif //HCI_PRESENT + +/// @} HCI + +#endif // HCI_INT_H_ diff --git a/services/ble_stack/hl/api/att.h b/services/ble_stack/hl/api/att.h new file mode 100644 index 0000000..ca6411a --- /dev/null +++ b/services/ble_stack/hl/api/att.h @@ -0,0 +1,1109 @@ +#ifndef ATT_H_ +#define ATT_H_ + +/** + **************************************************************************************** + * @addtogroup ATT Attribute Protocol + * @ingroup HOST + * @brief Attribute Protocol. + * + * The ATT block contains the procedures for discovering, reading, writing + * and indicating attributes to peer device . It also defines a number of items + * that caters to the security aspect of the block as access to some information + * may require both authorization and an authenticated and encrypted physical + * link before an attribute can be read or written + * + * @{ + * + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/// Macro used to convert CPU integer define to LSB first 16-bits UUID +#define ATT_UUID_16(uuid) (uuid) + +/// Invalid attribute handle +#define ATT_INVALID_HDL (0x0000) +/// Invalid attribute idx (used for profiles) +#define ATT_INVALID_IDX (0xff) + +#define ATT_1ST_REQ_START_HDL 0x0001 +#define ATT_1ST_REQ_END_HDL 0xFFFF + +/// Maximum possible attribute handle +#define ATT_MAX_ATTR_HDL ATT_1ST_REQ_END_HDL + +/// Offset of value in signed PDU +#define ATT_SIGNED_PDU_VAL_OFFSET 0x03 + +/// Attribute Features +#define ATT_SERVER_CONFIG 0x0001 +#define ATT_SERVICE_DISC 0x0002 +#define ATT_RELATIONSHIP_DISC 0x0004 +#define ATT_CHAR_DISC 0x0008 +#define ATT_CHAR_DESC_DISC 0x0010 +#define ATT_RD_CHAR_VALUE 0x0020 +#define ATT_WR_CHAR_VALUE 0x0040 +#define ATT_NOTIF_CHAR_VALUE 0x0080 +#define ATT_IND_CHAR_VALUE 0x0100 +#define ATT_RD_CHAR_DESC 0x0200 +#define ATT_WR_CHAR_DESC 0x0400 + +/// Length, number, offset defines +#define ATT_SVC_VALUE_MAX_LEN 0x0030 +#define ATT_CHAR_NAME_MAX_LEN 0x0030 +#define ATT_UUID_16_LEN 0x0002 +#define ATT_UUID_32_LEN 0x0004 +#define ATT_UUID_128_LEN 0x0010 + +/// offset - l2cap header and ATT code +#define ATT_PDU_DATA_OFFSET 0x05 + +/// Characteristic Properties Bit +#define ATT_CHAR_PROP_BCAST 0x01 +#define ATT_CHAR_PROP_RD 0x02 +#define ATT_CHAR_PROP_WR_NO_RESP 0x04 +#define ATT_CHAR_PROP_WR 0x08 +#define ATT_CHAR_PROP_NTF 0x10 +#define ATT_CHAR_PROP_IND 0x20 +#define ATT_CHAR_PROP_AUTH 0x40 +#define ATT_CHAR_PROP_EXT_PROP 0x80 +/// Invalid Attribute Handle +#define ATT_INVALID_SEARCH_HANDLE 0x0000 +#define ATT_INVALID_HANDLE 0x0000 +/// Read Information Request +#define ATT_UUID_FILTER_0 0x00 +#define ATT_UUID_FILTER_2 0x02 +#define ATT_UUID_FILTER_16 0x10 +/// Read Information Response +#define ATT_FORMAT_LEN 0x0001 +#define ATT_FORMAT_16BIT_UUID 0x01 +#define ATT_FORMAT_128BIT_UUID 0x02 +/// For No fix length PDU +#define ATT_HANDLE_LEN 0x0002 +#define ATT_EACHLEN_LEN 0x0001 +#define ATT_PROP_LEN 0x0001 +#define ATT_CODE_LEN 0x0001 +#define ATT_CODE_AND_DATA_LEN 0x0002 +#define ATT_CODE_AND_HANDLE_LEN 0x0003 +#define ATT_CODE_AND_HANDLE_LEN_AND_OFFSET 0x0005 +#define ATT_SIGNATURE_LEN 0x0C + +/// extended characteristics +#define ATT_EXT_RELIABLE_WRITE 0x0001 +#define ATT_EXT_WRITABLE_AUX 0x0002 +#define ATT_EXT_RFU 0xFFFC + +/// PDU size for error response +#define ATT_ERROR_RESP_LEN 0x05 + +/// Offset of value in signed PDU +#define ATT_SIGNED_PDU_VAL_OFFSET 0x03 + + + +#define ATT_BT_UUID_128 {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, \ + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + + + +/* Attribute Specification Defines */ + +/// Common 16-bit Universal Unique Identifier +enum { + ATT_INVALID_UUID = ATT_UUID_16(0x0000), + /*----------------- SERVICES ---------------------*/ + /// Generic Access Profile + ATT_SVC_GENERIC_ACCESS = ATT_UUID_16(0x1800), + /// Attribute Profile + ATT_SVC_GENERIC_ATTRIBUTE = ATT_UUID_16(0x1801), + /// Immediate alert Service + ATT_SVC_IMMEDIATE_ALERT = ATT_UUID_16(0x1802), + /// Link Loss Service + ATT_SVC_LINK_LOSS = ATT_UUID_16(0x1803), + /// Tx Power Service + ATT_SVC_TX_POWER = ATT_UUID_16(0x1804), + /// Current Time Service Service + ATT_SVC_CURRENT_TIME = ATT_UUID_16(0x1805), + /// Reference Time Update Service + ATT_SVC_REF_TIME_UPDATE = ATT_UUID_16(0x1806), + /// Next DST Change Service + ATT_SVC_NEXT_DST_CHANGE = ATT_UUID_16(0x1807), + /// Glucose Service + ATT_SVC_GLUCOSE = ATT_UUID_16(0x1808), + /// Health Thermometer Service + ATT_SVC_HEALTH_THERMOM = ATT_UUID_16(0x1809), + /// Device Information Service + ATT_SVC_DEVICE_INFO = ATT_UUID_16(0x180A), + /// Heart Rate Service + ATT_SVC_HEART_RATE = ATT_UUID_16(0x180D), + /// Phone Alert Status Service + ATT_SVC_PHONE_ALERT_STATUS = ATT_UUID_16(0x180E), + /// Battery Service + ATT_SVC_BATTERY_SERVICE = ATT_UUID_16(0x180F), + /// Blood Pressure Service + ATT_SVC_BLOOD_PRESSURE = ATT_UUID_16(0x1810), + /// Alert Notification Service + ATT_SVC_ALERT_NTF = ATT_UUID_16(0x1811), + /// HID Service + ATT_SVC_HID = ATT_UUID_16(0x1812), + /// Scan Parameters Service + ATT_SVC_SCAN_PARAMETERS = ATT_UUID_16(0x1813), + /// Running Speed and Cadence Service + ATT_SVC_RUNNING_SPEED_CADENCE = ATT_UUID_16(0x1814), + /// Cycling Speed and Cadence Service + ATT_SVC_CYCLING_SPEED_CADENCE = ATT_UUID_16(0x1816), + /// Cycling Power Service + ATT_SVC_CYCLING_POWER = ATT_UUID_16(0x1818), + /// Location and Navigation Service + ATT_SVC_LOCATION_AND_NAVIGATION = ATT_UUID_16(0x1819), + /// Environmental Sensing Service + ATT_SVC_ENVIRONMENTAL_SENSING = ATT_UUID_16(0x181A), + /// Body Composition Service + ATT_SVC_BODY_COMPOSITION = ATT_UUID_16(0x181B), + /// User Data Service + ATT_SVC_USER_DATA = ATT_UUID_16(0x181C), + /// Weight Scale Service + ATT_SVC_WEIGHT_SCALE = ATT_UUID_16(0x181D), + /// Bond Management Service + ATT_SVC_BOND_MANAGEMENT = ATT_UUID_16(0x181E), + /// Continuous Glucose Monitoring Service + ATT_SVC_CONTINUOUS_GLUCOSE_MONITORING = ATT_UUID_16(0x181F), + /// Internet Protocol Support Service + ATT_SVC_IP_SUPPORT = ATT_UUID_16(0x1820), + /// Indoor Positioning Service + ATT_SVC_INDOOR_POSITIONING = ATT_UUID_16(0x1821), + /// Pulse Oximeter Service + ATT_SVC_PULSE_OXIMETER = ATT_UUID_16(0x1822), + /// HTTP Proxy Service + ATT_SVC_HTTP_PROXY = ATT_UUID_16(0x1823), + /// Transport Discovery Service + ATT_SVC_TRANSPORT_DISCOVERY = ATT_UUID_16(0x1824), + /// Object Transfer Service + ATT_SVC_OBJECT_TRANSFER = ATT_UUID_16(0x1825), + + /*------------------- UNITS ---------------------*/ + /// No defined unit + ATT_UNIT_UNITLESS = ATT_UUID_16(0x2700), + /// Length Unit - Metre + ATT_UNIT_METRE = ATT_UUID_16(0x2701), + ///Mass unit - Kilogram + ATT_UNIT_KG = ATT_UUID_16(0x2702), + ///Time unit - second + ATT_UNIT_SECOND = ATT_UUID_16(0x2703), + ///Electric current unit - Ampere + ATT_UNIT_AMPERE = ATT_UUID_16(0x2704), + ///Thermodynamic Temperature unit - Kelvin + ATT_UNIT_KELVIN = ATT_UUID_16(0x2705), + /// Amount of substance unit - mole + ATT_UNIT_MOLE = ATT_UUID_16(0x2706), + ///Luminous intensity unit - candela + ATT_UNIT_CANDELA = ATT_UUID_16(0x2707), + ///Area unit - square metres + ATT_UNIT_SQ_METRE = ATT_UUID_16(0x2710), + ///Colume unit - cubic metres + ATT_UNIT_CUBIC_METRE = ATT_UUID_16(0x2710), + ///Velocity unit - metres per second + ATT_UNIT_METRE_PER_SECOND = ATT_UUID_16(0x2711), + ///Acceleration unit - metres per second squared + ATT_UNIT_METRES_PER_SEC_SQ = ATT_UUID_16(0x2712), + ///Wavenumber unit - reciprocal metre + ATT_UNIT_RECIPROCAL_METRE = ATT_UUID_16(0x2713), + ///Density unit - kilogram per cubic metre + ATT_UNIT_DENS_KG_PER_CUBIC_METRE = ATT_UUID_16(0x2714), + ///Surface density unit - kilogram per square metre + ATT_UNIT_KG_PER_SQ_METRE = ATT_UUID_16(0x2715), + ///Specific volume unit - cubic metre per kilogram + ATT_UNIT_CUBIC_METRE_PER_KG = ATT_UUID_16(0x2716), + ///Current density unit - ampere per square metre + ATT_UNIT_AMPERE_PER_SQ_METRE = ATT_UUID_16(0x2717), + ///Magnetic field strength unit - Ampere per metre + ATT_UNIT_AMPERE_PER_METRE = ATT_UUID_16(0x2718), + ///Amount concentration unit - mole per cubic metre + ATT_UNIT_MOLE_PER_CUBIC_METRE = ATT_UUID_16(0x2719), + ///Mass Concentration unit - kilogram per cubic metre + ATT_UNIT_MASS_KG_PER_CUBIC_METRE = ATT_UUID_16(0x271A), + ///Luminance unit - candela per square metre + ATT_UNIT_CANDELA_PER_SQ_METRE = ATT_UUID_16(0x271B), + ///Refractive index unit + ATT_UNIT_REFRACTIVE_INDEX = ATT_UUID_16(0x271C), + ///Relative permeability unit + ATT_UNIT_RELATIVE_PERMEABILITY = ATT_UUID_16(0x271D), + ///Plane angle unit - radian + ATT_UNIT_RADIAN = ATT_UUID_16(0x2720), + ///Solid angle unit - steradian + ATT_UNIT_STERADIAN = ATT_UUID_16(0x2721), + ///Frequency unit - Hertz + ATT_UNIT_HERTZ = ATT_UUID_16(0x2722), + ///Force unit - Newton + ATT_UNIT_NEWTON = ATT_UUID_16(0x2723), + ///Pressure unit - Pascal + ATT_UNIT_PASCAL = ATT_UUID_16(0x2724), + ///Energy unit - Joule + ATT_UNIT_JOULE = ATT_UUID_16(0x2725), + ///Power unit - Watt + ATT_UNIT_WATT = ATT_UUID_16(0x2726), + ///electric Charge unit - Coulomb + ATT_UNIT_COULOMB = ATT_UUID_16(0x2727), + ///Electric potential difference - Volt + ATT_UNIT_VOLT = ATT_UUID_16(0x2728), + ///Capacitance unit - Farad + ATT_UNIT_FARAD = ATT_UUID_16(0x2729), + ///electric resistance unit - Ohm + ATT_UNIT_OHM = ATT_UUID_16(0x272A), + ///Electric conductance - Siemens + ATT_UNIT_SIEMENS = ATT_UUID_16(0x272B), + ///Magnetic flux unit - Weber + ATT_UNIT_WEBER = ATT_UUID_16(0x272C), + ///Magnetic flux density unit - Tesla + ATT_UNIT_TESLA = ATT_UUID_16(0x272D), + ///Inductance unit - Henry + ATT_UNIT_HENRY = ATT_UUID_16(0x272E), + ///Temperature unit - degree Celsius + ATT_UNIT_CELSIUS = ATT_UUID_16(0x272F), + ///Luminous flux unit - lumen + ATT_UNIT_LUMEN = ATT_UUID_16(0x2730), + ///Illuminance unit - lux + ATT_UNIT_LUX = ATT_UUID_16(0x2731), + ///Activity referred to a radionuclide unit - becquerel + ATT_UNIT_BECQUEREL = ATT_UUID_16(0x2732), + ///Absorbed dose unit - Gray + ATT_UNIT_GRAY = ATT_UUID_16(0x2733), + ///Dose equivalent unit - Sievert + ATT_UNIT_SIEVERT = ATT_UUID_16(0x2734), + ///Catalytic activity unit - Katal + ATT_UNIT_KATAL = ATT_UUID_16(0x2735), + ///Synamic viscosity unit - Pascal second + ATT_UNIT_PASCAL_SECOND = ATT_UUID_16(0x2740), + ///Moment of force unit - Newton metre + ATT_UNIT_NEWTON_METRE = ATT_UUID_16(0x2741), + ///surface tension unit - Newton per metre + ATT_UNIT_NEWTON_PER_METRE = ATT_UUID_16(0x2742), + ///Angular velocity unit - radian per second + ATT_UNIT_RADIAN_PER_SECOND = ATT_UUID_16(0x2743), + ///Angular acceleration unit - radian per second squared + ATT_UNIT_RADIAN_PER_SECOND_SQ = ATT_UUID_16(0x2744), + ///Heat flux density unit - Watt per square metre + ATT_UNIT_WATT_PER_SQ_METRE = ATT_UUID_16(0x2745), + ///HEat capacity unit - Joule per Kelvin + ATT_UNIT_JOULE_PER_KELVIN = ATT_UUID_16(0x2746), + ///Specific heat capacity unit - Joule per kilogram kelvin + ATT_UNIT_JOULE_PER_KG_KELVIN = ATT_UUID_16(0x2747), + ///Specific Energy unit - Joule per kilogram + ATT_UNIT_JOULE_PER_KG = ATT_UUID_16(0x2748), + ///Thermal conductivity - Watt per metre Kelvin + ATT_UNIT_WATT_PER_METRE_KELVIN = ATT_UUID_16(0x2749), + ///Energy Density unit - joule per cubic metre + ATT_UNIT_JOULE_PER_CUBIC_METRE = ATT_UUID_16(0x274A), + ///Electric field strength unit - volt per metre + ATT_UNIT_VOLT_PER_METRE = ATT_UUID_16(0x274B), + ///Electric charge density unit - coulomb per cubic metre + ATT_UNIT_COULOMB_PER_CUBIC_METRE = ATT_UUID_16(0x274C), + ///Surface charge density unit - coulomb per square metre + ATT_UNIT_SURF_COULOMB_PER_SQ_METRE = ATT_UUID_16(0x274D), + ///Electric flux density unit - coulomb per square metre + ATT_UNIT_FLUX_COULOMB_PER_SQ_METRE = ATT_UUID_16(0x274E), + ///Permittivity unit - farad per metre + ATT_UNIT_FARAD_PER_METRE = ATT_UUID_16(0x274F), + ///Permeability unit - henry per metre + ATT_UNIT_HENRY_PER_METRE = ATT_UUID_16(0x2750), + ///Molar energy unit - joule per mole + ATT_UNIT_JOULE_PER_MOLE = ATT_UUID_16(0x2751), + ///Molar entropy unit - joule per mole kelvin + ATT_UNIT_JOULE_PER_MOLE_KELVIN = ATT_UUID_16(0x2752), + ///Exposure unit - coulomb per kilogram + ATT_UNIT_COULOMB_PER_KG = ATT_UUID_16(0x2753), + ///Absorbed dose rate unit - gray per second + ATT_UNIT_GRAY_PER_SECOND = ATT_UUID_16(0x2754), + ///Radiant intensity unit - watt per steradian + ATT_UNIT_WATT_PER_STERADIAN = ATT_UUID_16(0x2755), + ///Radiance unit - watt per square meter steradian + ATT_UNIT_WATT_PER_SQ_METRE_STERADIAN = ATT_UUID_16(0x2756), + ///Catalytic activity concentration unit - katal per cubic metre + ATT_UNIT_KATAL_PER_CUBIC_METRE = ATT_UUID_16(0x2757), + ///Time unit - minute + ATT_UNIT_MINUTE = ATT_UUID_16(0x2760), + ///Time unit - hour + ATT_UNIT_HOUR = ATT_UUID_16(0x2761), + ///Time unit - day + ATT_UNIT_DAY = ATT_UUID_16(0x2762), + ///Plane angle unit - degree + ATT_UNIT_ANGLE_DEGREE = ATT_UUID_16(0x2763), + ///Plane angle unit - minute + ATT_UNIT_ANGLE_MINUTE = ATT_UUID_16(0x2764), + ///Plane angle unit - second + ATT_UNIT_ANGLE_SECOND = ATT_UUID_16(0x2765), + ///Area unit - hectare + ATT_UNIT_HECTARE = ATT_UUID_16(0x2766), + ///Volume unit - litre + ATT_UNIT_LITRE = ATT_UUID_16(0x2767), + ///Mass unit - tonne + ATT_UNIT_TONNE = ATT_UUID_16(0x2768), + ///Pressure unit - bar + ATT_UNIT_BAR = ATT_UUID_16(0x2780), + ///Pressure unit - millimetre of mercury + ATT_UNIT_MM_MERCURY = ATT_UUID_16(0x2781), + ///Length unit - angstrom + ATT_UNIT_ANGSTROM = ATT_UUID_16(0x2782), + ///Length unit - nautical mile + ATT_UNIT_NAUTICAL_MILE = ATT_UUID_16(0x2783), + ///Area unit - barn + ATT_UNIT_BARN = ATT_UUID_16(0x2784), + ///Velocity unit - knot + ATT_UNIT_KNOT = ATT_UUID_16(0x2785), + ///Logarithmic radio quantity unit - neper + ATT_UNIT_NEPER = ATT_UUID_16(0x2786), + ///Logarithmic radio quantity unit - bel + ATT_UNIT_BEL = ATT_UUID_16(0x2787), + ///Length unit - yard + ATT_UNIT_YARD = ATT_UUID_16(0x27A0), + ///Length unit - parsec + ATT_UNIT_PARSEC = ATT_UUID_16(0x27A1), + ///length unit - inch + ATT_UNIT_INCH = ATT_UUID_16(0x27A2), + ///length unit - foot + ATT_UNIT_FOOT = ATT_UUID_16(0x27A3), + ///length unit - mile + ATT_UNIT_MILE = ATT_UUID_16(0x27A4), + ///pressure unit - pound-force per square inch + ATT_UNIT_POUND_FORCE_PER_SQ_INCH = ATT_UUID_16(0x27A5), + ///velocity unit - kilometre per hour + ATT_UNIT_KM_PER_HOUR = ATT_UUID_16(0x27A6), + ///velocity unit - mile per hour + ATT_UNIT_MILE_PER_HOUR = ATT_UUID_16(0x27A7), + ///angular velocity unit - revolution per minute + ATT_UNIT_REVOLUTION_PER_MINUTE = ATT_UUID_16(0x27A8), + ///energy unit - gram calorie + ATT_UNIT_GRAM_CALORIE = ATT_UUID_16(0x27A9), + ///energy unit - kilogram calorie + ATT_UNIT_KG_CALORIE = ATT_UUID_16(0x27AA), + /// energy unit - kilowatt hour + ATT_UNIT_KILOWATT_HOUR = ATT_UUID_16(0x27AB), + ///thermodynamic temperature unit - degree Fahrenheit + ATT_UNIT_FAHRENHEIT = ATT_UUID_16(0x27AC), + ///percentage + ATT_UNIT_PERCENTAGE = ATT_UUID_16(0x27AD), + ///per mille + ATT_UNIT_PER_MILLE = ATT_UUID_16(0x27AE), + ///period unit - beats per minute) + ATT_UNIT_BEATS_PER_MINUTE = ATT_UUID_16(0x27AF), + ///electric charge unit - ampere hours + ATT_UNIT_AMPERE_HOURS = ATT_UUID_16(0x27B0), + ///mass density unit - milligram per decilitre + ATT_UNIT_MILLIGRAM_PER_DECILITRE = ATT_UUID_16(0x27B1), + ///mass density unit - millimole per litre + ATT_UNIT_MILLIMOLE_PER_LITRE = ATT_UUID_16(0x27B2), + ///time unit - year + ATT_UNIT_YEAR = ATT_UUID_16(0x27B3), + ////time unit - month + ATT_UNIT_MONTH = ATT_UUID_16(0x27B4), + + + /*---------------- DECLARATIONS -----------------*/ + /// Primary service Declaration + ATT_DECL_PRIMARY_SERVICE = ATT_UUID_16(0x2800), + /// Secondary service Declaration + ATT_DECL_SECONDARY_SERVICE = ATT_UUID_16(0x2801), + /// Include Declaration + ATT_DECL_INCLUDE = ATT_UUID_16(0x2802), + /// Characteristic Declaration + ATT_DECL_CHARACTERISTIC = ATT_UUID_16(0x2803), + + + /*----------------- DESCRIPTORS -----------------*/ + /// Characteristic extended properties + ATT_DESC_CHAR_EXT_PROPERTIES = ATT_UUID_16(0x2900), + /// Characteristic user description + ATT_DESC_CHAR_USER_DESCRIPTION = ATT_UUID_16(0x2901), + /// Client characteristic configuration + ATT_DESC_CLIENT_CHAR_CFG = ATT_UUID_16(0x2902), + /// Server characteristic configuration + ATT_DESC_SERVER_CHAR_CFG = ATT_UUID_16(0x2903), + /// Characteristic Presentation Format + ATT_DESC_CHAR_PRES_FORMAT = ATT_UUID_16(0x2904), + /// Characteristic Aggregate Format + ATT_DESC_CHAR_AGGREGATE_FORMAT = ATT_UUID_16(0x2905), + /// Valid Range + ATT_DESC_VALID_RANGE = ATT_UUID_16(0x2906), + /// External Report Reference + ATT_DESC_EXT_REPORT_REF = ATT_UUID_16(0x2907), + /// Report Reference + ATT_DESC_REPORT_REF = ATT_UUID_16(0x2908), + /// Environmental Sensing Configuration + ATT_DESC_ES_CONFIGURATION = ATT_UUID_16(0x290B), + /// Environmental Sensing Measurement + ATT_DESC_ES_MEASUREMENT = ATT_UUID_16(0x290C), + /// Environmental Sensing Trigger Setting + ATT_DESC_ES_TRIGGER_SETTING = ATT_UUID_16(0x290D), + + + /*--------------- CHARACTERISTICS ---------------*/ + /// Device name + ATT_CHAR_DEVICE_NAME = ATT_UUID_16(0x2A00), + /// Appearance + ATT_CHAR_APPEARANCE = ATT_UUID_16(0x2A01), + /// Privacy flag + ATT_CHAR_PRIVACY_FLAG = ATT_UUID_16(0x2A02), + /// Reconnection address + ATT_CHAR_RECONNECTION_ADDR = ATT_UUID_16(0x2A03), + /// Peripheral preferred connection parameters + ATT_CHAR_PERIPH_PREF_CON_PARAM = ATT_UUID_16(0x2A04), + /// Service handles changed + ATT_CHAR_SERVICE_CHANGED = ATT_UUID_16(0x2A05), + /// Alert Level characteristic + ATT_CHAR_ALERT_LEVEL = ATT_UUID_16(0x2A06), + /// Tx Power Level + ATT_CHAR_TX_POWER_LEVEL = ATT_UUID_16(0x2A07), + /// Date Time + ATT_CHAR_DATE_TIME = ATT_UUID_16(0x2A08), + /// Day of Week + ATT_CHAR_DAY_WEEK = ATT_UUID_16(0x2A09), + /// Day Date Time + ATT_CHAR_DAY_DATE_TIME = ATT_UUID_16(0x2A0A), + /// Exact time 256 + ATT_CHAR_EXACT_TIME_256 = ATT_UUID_16(0x2A0C), + /// DST Offset + ATT_CHAR_DST_OFFSET = ATT_UUID_16(0x2A0D), + /// Time zone + ATT_CHAR_TIME_ZONE = ATT_UUID_16(0x2A0E), + /// Local time Information + ATT_CHAR_LOCAL_TIME_INFO = ATT_UUID_16(0x2A0F), + /// Time with DST + ATT_CHAR_TIME_WITH_DST = ATT_UUID_16(0x2A11), + /// Time Accuracy + ATT_CHAR_TIME_ACCURACY = ATT_UUID_16(0x2A12), + ///Time Source + ATT_CHAR_TIME_SOURCE = ATT_UUID_16(0x2A13), + /// Reference Time Information + ATT_CHAR_REFERENCE_TIME_INFO = ATT_UUID_16(0x2A14), + /// Time Update Control Point + ATT_CHAR_TIME_UPDATE_CNTL_POINT = ATT_UUID_16(0x2A16), + /// Time Update State + ATT_CHAR_TIME_UPDATE_STATE = ATT_UUID_16(0x2A17), + /// Glucose Measurement + ATT_CHAR_GLUCOSE_MEAS = ATT_UUID_16(0x2A18), + /// Battery Level + ATT_CHAR_BATTERY_LEVEL = ATT_UUID_16(0x2A19), + /// Temperature Measurement + ATT_CHAR_TEMPERATURE_MEAS = ATT_UUID_16(0x2A1C), + /// Temperature Type + ATT_CHAR_TEMPERATURE_TYPE = ATT_UUID_16(0x2A1D), + /// Intermediate Temperature + ATT_CHAR_INTERMED_TEMPERATURE = ATT_UUID_16(0x2A1E), + /// Measurement Interval + ATT_CHAR_MEAS_INTERVAL = ATT_UUID_16(0x2A21), + /// Boot Keyboard Input Report + ATT_CHAR_BOOT_KB_IN_REPORT = ATT_UUID_16(0x2A22), + /// System ID + ATT_CHAR_SYS_ID = ATT_UUID_16(0x2A23), + /// Model Number String + ATT_CHAR_MODEL_NB = ATT_UUID_16(0x2A24), + /// Serial Number String + ATT_CHAR_SERIAL_NB = ATT_UUID_16(0x2A25), + /// Firmware Revision String + ATT_CHAR_FW_REV = ATT_UUID_16(0x2A26), + /// Hardware revision String + ATT_CHAR_HW_REV = ATT_UUID_16(0x2A27), + /// Software Revision String + ATT_CHAR_SW_REV = ATT_UUID_16(0x2A28), + /// Manufacturer Name String + ATT_CHAR_MANUF_NAME = ATT_UUID_16(0x2A29), + /// IEEE Regulatory Certification Data List + ATT_CHAR_IEEE_CERTIF = ATT_UUID_16(0x2A2A), + /// CT Time + ATT_CHAR_CT_TIME = ATT_UUID_16(0x2A2B), + /// Magnetic Declination + ATT_CHAR_MAGN_DECLINE = ATT_UUID_16(0x2A2C), + /// Scan Refresh + ATT_CHAR_SCAN_REFRESH = ATT_UUID_16(0x2A31), + /// Boot Keyboard Output Report + ATT_CHAR_BOOT_KB_OUT_REPORT = ATT_UUID_16(0x2A32), + /// Boot Mouse Input Report + ATT_CHAR_BOOT_MOUSE_IN_REPORT = ATT_UUID_16(0x2A33), + /// Glucose Measurement Context + ATT_CHAR_GLUCOSE_MEAS_CTX = ATT_UUID_16(0x2A34), + /// Blood Pressure Measurement + ATT_CHAR_BLOOD_PRESSURE_MEAS = ATT_UUID_16(0x2A35), + /// Intermediate Cuff Pressure + ATT_CHAR_INTERMEDIATE_CUFF_PRESSURE = ATT_UUID_16(0x2A36), + /// Heart Rate Measurement + ATT_CHAR_HEART_RATE_MEAS = ATT_UUID_16(0x2A37), + /// Body Sensor Location + ATT_CHAR_BODY_SENSOR_LOCATION = ATT_UUID_16(0x2A38), + /// Heart Rate Control Point + ATT_CHAR_HEART_RATE_CNTL_POINT = ATT_UUID_16(0x2A39), + /// Alert Status + ATT_CHAR_ALERT_STATUS = ATT_UUID_16(0x2A3F), + /// Ringer Control Point + ATT_CHAR_RINGER_CNTL_POINT = ATT_UUID_16(0x2A40), + /// Ringer Setting + ATT_CHAR_RINGER_SETTING = ATT_UUID_16(0x2A41), + /// Alert Category ID Bit Mask + ATT_CHAR_ALERT_CAT_ID_BIT_MASK = ATT_UUID_16(0x2A42), + /// Alert Category ID + ATT_CHAR_ALERT_CAT_ID = ATT_UUID_16(0x2A43), + /// Alert Notification Control Point + ATT_CHAR_ALERT_NTF_CTNL_PT = ATT_UUID_16(0x2A44), + /// Unread Alert Status + ATT_CHAR_UNREAD_ALERT_STATUS = ATT_UUID_16(0x2A45), + /// New Alert + ATT_CHAR_NEW_ALERT = ATT_UUID_16(0x2A46), + /// Supported New Alert Category + ATT_CHAR_SUP_NEW_ALERT_CAT = ATT_UUID_16(0x2A47), + /// Supported Unread Alert Category + ATT_CHAR_SUP_UNREAD_ALERT_CAT = ATT_UUID_16(0x2A48), + /// Blood Pressure Feature + ATT_CHAR_BLOOD_PRESSURE_FEATURE = ATT_UUID_16(0x2A49), + /// HID Information + ATT_CHAR_HID_INFO = ATT_UUID_16(0x2A4A), + /// Report Map + ATT_CHAR_REPORT_MAP = ATT_UUID_16(0x2A4B), + /// HID Control Point + ATT_CHAR_HID_CTNL_PT = ATT_UUID_16(0x2A4C), + /// Report + ATT_CHAR_REPORT = ATT_UUID_16(0x2A4D), + /// Protocol Mode + ATT_CHAR_PROTOCOL_MODE = ATT_UUID_16(0x2A4E), + /// Scan Interval Window + ATT_CHAR_SCAN_INTV_WD = ATT_UUID_16(0x2A4F), + /// PnP ID + ATT_CHAR_PNP_ID = ATT_UUID_16(0x2A50), + /// Glucose Feature + ATT_CHAR_GLUCOSE_FEATURE = ATT_UUID_16(0x2A51), + /// Record access control point + ATT_CHAR_REC_ACCESS_CTRL_PT = ATT_UUID_16(0x2A52), + /// RSC Measurement + ATT_CHAR_RSC_MEAS = ATT_UUID_16(0x2A53), + /// RSC Feature + ATT_CHAR_RSC_FEAT = ATT_UUID_16(0x2A54), + /// SC Control Point + ATT_CHAR_SC_CNTL_PT = ATT_UUID_16(0x2A55), + /// CSC Measurement + ATT_CHAR_CSC_MEAS = ATT_UUID_16(0x2A5B), + /// CSC Feature + ATT_CHAR_CSC_FEAT = ATT_UUID_16(0x2A5C), + /// Sensor Location + ATT_CHAR_SENSOR_LOC = ATT_UUID_16(0x2A5D), + /// CP Measurement + ATT_CHAR_CP_MEAS = ATT_UUID_16(0x2A63), + /// CP Vector + ATT_CHAR_CP_VECTOR = ATT_UUID_16(0x2A64), + /// CP Feature + ATT_CHAR_CP_FEAT = ATT_UUID_16(0x2A65), + /// CP Control Point + ATT_CHAR_CP_CNTL_PT = ATT_UUID_16(0x2A66), + /// Location and Speed + ATT_CHAR_LOC_SPEED = ATT_UUID_16(0x2A67), + /// Navigation + ATT_CHAR_NAVIGATION = ATT_UUID_16(0x2A68), + /// Position Quality + ATT_CHAR_POS_QUALITY = ATT_UUID_16(0x2A69), + /// LN Feature + ATT_CHAR_LN_FEAT = ATT_UUID_16(0x2A6A), + /// LN Control Point + ATT_CHAR_LN_CNTL_PT = ATT_UUID_16(0x2A6B), + /// Elevation + ATT_CHAR_ELEVATION = ATT_UUID_16(0x2A6C), + /// Pressure + ATT_CHAR_PRESSURE = ATT_UUID_16(0x2A6D), + /// Temperature + ATT_CHAR_TEMPERATURE = ATT_UUID_16(0x2A6E), + /// Humidity + ATT_CHAR_HUMIDITY = ATT_UUID_16(0x2A6F), + /// True Wind Speed + ATT_CHAR_TRUE_WIND_SPEED = ATT_UUID_16(0x2A70), + /// True Wind Direction + ATT_CHAR_TRUE_WIND_DIR = ATT_UUID_16(0x2A71), + /// Apparent Wind Speed + ATT_CHAR_APRNT_WIND_SPEED = ATT_UUID_16(0x2A72), + /// Apparent Wind Direction + ATT_CHAR_APRNT_WIND_DIRECTION = ATT_UUID_16(0x2A73), + /// Gust Factor + ATT_CHAR_GUST_FACTOR = ATT_UUID_16(0x2A74), + /// Pollen Concentration + ATT_CHAR_POLLEN_CONC = ATT_UUID_16(0x2A75), + /// UV Index + ATT_CHAR_UV_INDEX = ATT_UUID_16(0x2A76), + /// Irradiance + ATT_CHAR_IRRADIANCE = ATT_UUID_16(0x2A77), + /// Rainfall + ATT_CHAR_RAINFALL = ATT_UUID_16(0x2A78), + /// Wind Chill + ATT_CHAR_WIND_CHILL = ATT_UUID_16(0x2A79), + /// Heat Index + ATT_CHAR_HEAT_INDEX = ATT_UUID_16(0x2A7A), + /// Dew Point + ATT_CHAR_DEW_POINT = ATT_UUID_16(0x2A7B), + /// Descriptor Value Changed + ATT_CHAR_DESCRIPTOR_VALUE_CHANGED = ATT_UUID_16(0x2A7D), + /// Aerobic Heart Rate Lower Limit + ATT_CHAR_AEROBIC_HEART_RATE_LOWER_LIMIT = ATT_UUID_16(0x2A7E), + /// Aerobic Threshhold + ATT_CHAR_AEROBIC_THRESHHOLD = ATT_UUID_16(0x2A7F), + /// Age + ATT_CHAR_AGE = ATT_UUID_16(0x2A80), + /// Anaerobic Heart Rate Lower Limit + ATT_CHAR_ANAEROBIC_HEART_RATE_LOWER_LIMIT = ATT_UUID_16(0x2A81), + /// Anaerobic Heart Rate Upper Limit + ATT_CHAR_ANAEROBIC_HEART_RATE_UPPER_LIMIT = ATT_UUID_16(0x2A82), + /// Anaerobic Threshhold + ATT_CHAR_ANAEROBIC_THRESHHOLD = ATT_UUID_16(0x2A83), + /// Aerobic Heart Rate Upper Limit + ATT_CHAR_AEROBIC_HEART_RATE_UPPER_LIMIT = ATT_UUID_16(0x2A84), + /// Date Of Birth + ATT_CHAR_DATE_OF_BIRTH = ATT_UUID_16(0x2A85), + /// Date Of Threshold Assessment + ATT_CHAR_DATE_OF_THRESHOLD_ASSESSMENT = ATT_UUID_16(0x2A86), + /// Email Address + ATT_CHAR_EMAIL_ADDRESS = ATT_UUID_16(0x2A87), + /// Fat Burn Heart Rate Lower Limit + ATT_CHAR_FAT_BURN_HEART_RATE_LOWER_LIMIT = ATT_UUID_16(0x2A88), + /// Fat Burn Heart Rate Upper Limit + ATT_CHAR_FAT_BURN_HEART_RATE_UPPER_LIMIT = ATT_UUID_16(0x2A89), + /// First Name + ATT_CHAR_FIRST_NAME = ATT_UUID_16(0x2A8A), + /// Five Zone Heart Rate Limits + ATT_CHAR_FIVE_ZONE_HEART_RATE_LIMITS = ATT_UUID_16(0x2A8B), + /// Gender + ATT_CHAR_GENDER = ATT_UUID_16(0x2A8C), + /// Max Heart Rate + ATT_CHAR_MAX_HEART_RATE = ATT_UUID_16(0x2A8D), + /// Height + ATT_CHAR_HEIGHT = ATT_UUID_16(0x2A8E), + /// Hip Circumference + ATT_CHAR_HIP_CIRCUMFERENCE = ATT_UUID_16(0x2A8F), + /// Last Name + ATT_CHAR_LAST_NAME = ATT_UUID_16(0x2A90), + /// Maximum Recommended Heart Rate + ATT_CHAR_MAXIMUM_RECOMMENDED_HEART_RATE = ATT_UUID_16(0x2A91), + /// Resting Heart Rate + ATT_CHAR_RESTING_HEART_RATE = ATT_UUID_16(0x2A92), + /// Sport Type For Aerobic And Anaerobic Thresholds + ATT_CHAR_SPORT_TYPE_FOR_AEROBIC_AND_ANAEROBIC_THRESHOLDS = ATT_UUID_16(0x2A93), + /// Three Zone Heart Rate Limits + ATT_CHAR_THREE_ZONE_HEART_RATE_LIMITS = ATT_UUID_16(0x2A94), + /// Two Zone Heart Rate Limit + ATT_CHAR_TWO_ZONE_HEART_RATE_LIMIT = ATT_UUID_16(0x2A95), + /// Vo2 Max + ATT_CHAR_VO2_MAX = ATT_UUID_16(0x2A96), + /// Waist Circumference + ATT_CHAR_WAIST_CIRCUMFERENCE = ATT_UUID_16(0x2A97), + /// Weight + ATT_CHAR_WEIGHT = ATT_UUID_16(0x2A98), + /// Database Change Increment + ATT_CHAR_DATABASE_CHANGE_INCREMENT = ATT_UUID_16(0x2A99), + /// User Index + ATT_CHAR_USER_INDEX = ATT_UUID_16(0x2A9A), + /// Body Composition Feature + ATT_CHAR_BODY_COMPOSITION_FEATURE = ATT_UUID_16(0x2A9B), + /// Body Composition Measurement + ATT_CHAR_BODY_COMPOSITION_MEASUREMENT = ATT_UUID_16(0x2A9C), + /// Weight Measurement + ATT_CHAR_WEIGHT_MEASUREMENT = ATT_UUID_16(0x2A9D), + /// Weight Scale Feature + ATT_CHAR_WEIGHT_SCALE_FEATURE = ATT_UUID_16(0x2A9E), + /// User Control Point + ATT_CHAR_USER_CONTROL_POINT = ATT_UUID_16(0x2A9F), + /// Flux Density - 2D + ATT_CHAR_MAGN_FLUX_2D = ATT_UUID_16(0x2AA0), + /// Magnetic Flux Density - 3D + ATT_CHAR_MAGN_FLUX_3D = ATT_UUID_16(0x2AA1), + /// Language string + ATT_CHAR_LANGUAGE = ATT_UUID_16(0x2AA2), + /// Barometric Pressure Trend + ATT_CHAR_BAR_PRES_TREND = ATT_UUID_16(0x2AA3), + /// Central Address Resolution Support + ATT_CHAR_CTL_ADDR_RESOL_SUPP = ATT_UUID_16(0x2AA6), +}; + +/// Format for Characteristic Presentation +enum { + /// unsigned 1-bit: true or false + ATT_FORMAT_BOOL = 0x01, + /// unsigned 2-bit integer + ATT_FORMAT_2BIT, + /// unsigned 4-bit integer + ATT_FORMAT_NIBBLE, + /// unsigned 8-bit integer + ATT_FORMAT_UINT8, + /// unsigned 12-bit integer + ATT_FORMAT_UINT12, + /// unsigned 16-bit integer + ATT_FORMAT_UINT16, + /// unsigned 24-bit integer + ATT_FORMAT_UINT24, + /// unsigned 32-bit integer + ATT_FORMAT_UINT32, + /// unsigned 48-bit integer + ATT_FORMAT_UINT48, + /// unsigned 64-bit integer + ATT_FORMAT_UINT64, + /// unsigned 128-bit integer + ATT_FORMAT_UINT128, + /// signed 8-bit integer + ATT_FORMAT_SINT8, + /// signed 12-bit integer + ATT_FORMAT_SINT12, + /// signed 16-bit integer + ATT_FORMAT_SINT16, + /// signed 24-bit integer + ATT_FORMAT_SINT24, + /// signed 32-bit integer + ATT_FORMAT_SINT32, + /// signed 48-bit integer + ATT_FORMAT_SINT48, + /// signed 64-bit integer + ATT_FORMAT_SINT64, + /// signed 128-bit integer + ATT_FORMAT_SINT128, + /// IEEE-754 32-bit floating point + ATT_FORMAT_FLOAT32, + /// IEEE-754 64-bit floating point + ATT_FORMAT_FLOAT64, + /// IEEE-11073 16-bit SFLOAT + ATT_FORMAT_SFLOAT, + /// IEEE-11073 32-bit FLOAT + ATT_FORMAT_FLOAT, + /// IEEE-20601 format + ATT_FORMAT_DUINT16, + /// UTF-8 string + ATT_FORMAT_UTF8S, + /// UTF-16 string + ATT_FORMAT_UTF16S, + /// Opaque structure + ATT_FORMAT_STRUCT, + /// Last format + ATT_FORMAT_LAST +}; + + +/// Client Characteristic Configuration Codes +enum att_ccc_val +{ + /// Stop notification/indication + ATT_CCC_STOP_NTFIND = 0x0000, + /// Start notification + ATT_CCC_START_NTF, + /// Start indication + ATT_CCC_START_IND +}; + +/* + * Type Definition + **************************************************************************************** + */ + +/// Attribute length type +typedef uint16_t att_size_t; + + +/// UUID - 128-bit type +struct att_uuid_128 +{ + /// 128-bit UUID + uint8_t uuid[ATT_UUID_128_LEN]; +}; + +/// UUID - 32-bit type +struct att_uuid_32 +{ + /// 32-bit UUID + uint8_t uuid[ATT_UUID_32_LEN]; +}; + + + +/// Characteristic Value Descriptor +struct att_char_desc +{ + /// properties + uint8_t prop; + /// attribute handle + uint8_t attr_hdl[ATT_HANDLE_LEN]; + /// attribute type + uint8_t attr_type[ATT_UUID_16_LEN]; +}; + +/// Characteristic Value Descriptor +struct att_char128_desc +{ + /// properties + uint8_t prop; + /// attribute handle + uint8_t attr_hdl[ATT_HANDLE_LEN]; + /// attribute type + uint8_t attr_type[ATT_UUID_128_LEN]; +}; + +/// Service Value Descriptor - 16-bit +typedef uint16_t att_svc_desc_t; + +/// include service entry element +struct att_incl_desc +{ + /// start handle value of included service + uint16_t start_hdl; + /// end handle value of included service + uint16_t end_hdl; + /// attribute value UUID + uint16_t uuid; +}; + +/// include service entry element +struct att_incl128_desc +{ + /// start handle value of included service + uint16_t start_hdl; + /// end handle value of included service + uint16_t end_hdl; +}; + + +// -------------------------- PDU HANDLER Definition -------------------------- + +/// used to know if PDU handler has been found +#define ATT_PDU_HANDLER_NOT_FOUND (0xff) + +/// Format of a pdu handler function +typedef int (*att_func_t)(uint8_t conidx, void *pdu); + +/// Element of a pdu handler table. +struct att_pdu_handler +{ + /// PDU identifier of the message + uint8_t pdu_id; + /// Pointer to the handler function for the pdu above. + att_func_t handler; +}; + + +// --------------------------- Database permissions ----------------------------- + +/// Macro used to retrieve access permission rights +#define PERM_GET(perm, access)\ + (((perm) & (PERM_MASK_ ## access)) >> (PERM_POS_ ## access)) + +/// Macro used to retrieve permission value from access and rights on attribute. +#define PERM(access, right) \ + (((PERM_RIGHT_ ## right) << (PERM_POS_ ## access)) & (PERM_MASK_ ## access)) + +/// Macro used know if permission is set or not. +#define PERM_IS_SET(perm, access, right) \ + (((perm) & (((PERM_RIGHT_ ## right) << (PERM_POS_ ## access))) \ + & (PERM_MASK_ ## access)) == PERM(access, right)) + +/// Macro used to create permission value +#define PERM_VAL(access, perm) \ + ((((perm) << (PERM_POS_ ## access))) & (PERM_MASK_ ## access)) + + + +/// Retrieve attribute security level from attribute right and service right +#define ATT_GET_SEC_LVL(att_right, svc_right) \ + co_max(((att_right) & PERM_RIGHT_AUTH), ((svc_right) & PERM_RIGHT_AUTH)); + +/// Retrieve UUID LEN from UUID Length Permission +#define ATT_UUID_LEN(uuid_len_perm) ((uuid_len_perm == 0) ? ATT_UUID_16_LEN : \ + ((uuid_len_perm == 1) ? ATT_UUID_32_LEN : \ + ((uuid_len_perm == 2) ? ATT_UUID_128_LEN : 0))) + +/// Initialization of attribute element +#define ATT_ELEMT_INIT {{NULL}, false} + +/** + * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + * +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + * |EXT | WS | I | N | WR | WC | RD | B | NP | IP | WP | RP | + * +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + * + * Bit [0-1] : Read Permission (0 = NO_AUTH, 1 = UNAUTH, 2 = AUTH, 3 = SEC_CON) + * Bit [2-3] : Write Permission (0 = NO_AUTH, 1 = UNAUTH, 2 = AUTH, 3 = SEC_CON) + * Bit [4-5] : Indication Permission (0 = NO_AUTH, 1 = UNAUTH, 2 = AUTH, 3 = SEC_CON) + * Bit [6-7] : Notification Permission (0 = NO_AUTH, 1 = UNAUTH, 2 = AUTH, 3 = SEC_CON) + * + * Bit [8] : Broadcast permission (only relevant for a characteristic value) + * Bit [9] : Read accepted + * Bit [10] : Write Command accepted + * Bit [11] : Write Request accepted + * Bit [12] : Notification accepted + * Bit [13] : Indication accepted + * Bit [14] : Write Signed accepted + * Bit [15] : Extended properties present (only relevant for a characteristic value) + */ +enum attm_perm_mask +{ + /// retrieve all permission info + PERM_MASK_ALL = 0x0000, + /// Read Permission Mask + PERM_MASK_RP = 0x0003, + PERM_POS_RP = 0, + /// Write Permission Mask + PERM_MASK_WP = 0x000C, + PERM_POS_WP = 2, + /// Indication Access Mask + PERM_MASK_IP = 0x0030, + PERM_POS_IP = 4, + /// Notification Access Mask + PERM_MASK_NP = 0x00C0, + PERM_POS_NP = 6, + /// Broadcast descriptor present + PERM_MASK_BROADCAST = 0x0100, + PERM_POS_BROADCAST = 8, + /// Read Access Mask + PERM_MASK_RD = 0x0200, + PERM_POS_RD = 9, + /// Write Command Enabled attribute Mask + PERM_MASK_WRITE_COMMAND = 0x0400, + PERM_POS_WRITE_COMMAND = 10, + /// Write Request Enabled attribute Mask + PERM_MASK_WRITE_REQ = 0x0800, + PERM_POS_WRITE_REQ = 11, + /// Notification Access Mask + PERM_MASK_NTF = 0x1000, + PERM_POS_NTF = 12, + /// Indication Access Mask + PERM_MASK_IND = 0x2000, + PERM_POS_IND = 13, + /// Write Signed Enabled attribute Mask + PERM_MASK_WRITE_SIGNED = 0x4000, + PERM_POS_WRITE_SIGNED = 14, + /// Extended properties descriptor present + PERM_MASK_EXT = 0x8000, + PERM_POS_EXT = 15, + + /// Properties + PERM_MASK_PROP = 0xFF00, + PERM_POS_PROP = 8, +}; + +/** + * Value permission bit field + * + * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + * +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + * | RI |UUID_LEN |EKS | MAX_LEN (RI = 1) / Value Offset (RI = 0) | + * +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + * + * Bit [0-11] : Maximum Attribute Length or Value Offset pointer + * Bit [12] : Encryption key Size must be 16 bytes + * Bit [14-13]: UUID Length (0 = 16 bits, 1 = 32 bits, 2 = 128 bits, 3 = RFU) + * Bit [15] : Trigger Read Indication (0 = Value present in Database, 1 = Value not present in Database) + */ +enum attm_value_perm_mask +{ + /// Maximum Attribute Length + PERM_MASK_MAX_LEN = 0x0FFF, + PERM_POS_MAX_LEN = 0, + /// Attribute value Offset + PERM_MASK_VAL_OFFSET = 0x0FFF, + PERM_POS_VAL_OFFSET = 0, + /// Check Encryption key size Mask + PERM_MASK_EKS = 0x1000, + PERM_POS_EKS = 12, + /// UUID Length + PERM_MASK_UUID_LEN = 0x6000, + PERM_POS_UUID_LEN = 13, + /// Read trigger Indication + PERM_MASK_RI = 0x8000, + PERM_POS_RI = 15, +}; + + +/** + * Service permissions + * + * 7 6 5 4 3 2 1 0 + * +----+----+----+----+----+----+----+----+ + * |SEC |UUID_LEN |DIS | AUTH |EKS | MI | + * +----+----+----+----+----+----+----+----+ + * + * Bit [0] : Task that manage service is multi-instantiated (Connection index is conveyed) + * Bit [1] : Encryption key Size must be 16 bytes + * Bit [2-3]: Service Permission (0 = NO_AUTH, 1 = UNAUTH, 2 = AUTH, 3 = Secure Connect) + * Bit [4] : Disable the service + * Bit [5-6]: UUID Length (0 = 16 bits, 1 = 32 bits, 2 = 128 bits, 3 = RFU) + * Bit [7] : Secondary Service (0 = Primary Service, 1 = Secondary Service) + */ +enum attm_svc_perm_mask +{ + /// Task that manage service is multi-instantiated + PERM_MASK_SVC_MI = 0x01, + PERM_POS_SVC_MI = 0, + /// Check Encryption key size for service Access + PERM_MASK_SVC_EKS = 0x02, + PERM_POS_SVC_EKS = 1, + /// Service Permission authentication + PERM_MASK_SVC_AUTH = 0x0C, + PERM_POS_SVC_AUTH = 2, + /// Disable the service + PERM_MASK_SVC_DIS = 0x10, + PERM_POS_SVC_DIS = 4, + /// Service UUID Length + PERM_MASK_SVC_UUID_LEN = 0x60, + PERM_POS_SVC_UUID_LEN = 5, + /// Service type Secondary + PERM_MASK_SVC_SECONDARY = 0x80, + PERM_POS_SVC_SECONDARY = 7, +}; + +/// Attribute & Service access mode +enum +{ + /// Disable access + PERM_RIGHT_DISABLE = 0, + /// Enable access + PERM_RIGHT_ENABLE = 1, +}; + +/// Attribute & Service access rights +enum +{ + /// No Authentication + PERM_RIGHT_NO_AUTH = 0, + /// Access Requires Unauthenticated link + PERM_RIGHT_UNAUTH = 1, + /// Access Requires Authenticated link + PERM_RIGHT_AUTH = 2, + /// Access Requires Secure Connection link + PERM_RIGHT_SEC_CON = 3, +}; + +/// Attribute & Service UUID Length +enum +{ + /// 16 bits UUID + PERM_UUID_16 = 0, + PERM_RIGHT_UUID_16 = 0, + /// 32 bits UUID + PERM_UUID_32 = 1, + PERM_RIGHT_UUID_32 = 1, + /// 128 bits UUID + PERM_UUID_128 = 2, + PERM_RIGHT_UUID_128 = 2, + /// Invalid + PERM_UUID_RFU = 3, +}; + +/// execute flags +enum +{ + /// Cancel All the Reliable Writes + ATT_CANCEL_ALL_PREPARED_WRITES = 0x00, + /// Write All the Reliable Writes + ATT_EXECUTE_ALL_PREPARED_WRITES +}; + + + +/// @} ATT +#endif // ATT_H_ diff --git a/services/ble_stack/hl/api/gap.h b/services/ble_stack/hl/api/gap.h new file mode 100644 index 0000000..9a3c416 --- /dev/null +++ b/services/ble_stack/hl/api/gap.h @@ -0,0 +1,1047 @@ +#ifndef GAP_H_ +#define GAP_H_ +/** + **************************************************************************************** + * @addtogroup HOST + * @ingroup ROOT + * @brief Bluetooth Low Energy Host + * + * The HOST layer of the stack contains the higher layer protocols (@ref ATT "ATT", + * @ref SMP "SMP") and transport module (@ref L2C "L2C"). It also includes the Generic + * Access Profile (@ref GAP "GAP"), used for scanning/connection operations. + **************************************************************************************** + */ +/** + **************************************************************************************** + * @addtogroup GAP Generic Access Profile + * @ingroup HOST + * @brief Generic Access Profile. + * + * The GAP module is responsible for providing an API to the application in order to + * configure the device in the desired mode (discoverable, connectable, etc.) and perform + * required actions (scanning, connection, pairing, etc.). To achieve this, the GAP + * interfaces with both the @ref SMP "SMP", @ref L2C "L2C" and the @ref CONTROLLER "CONTROLLER" + * + * @{ + **************************************************************************************** + */ + +#include +#include "compiler.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// BD address length +#define GAP_BD_ADDR_LEN (6) +/// LE Channel map length +#define GAP_LE_CHNL_MAP_LEN (0x05) +/// LE Feature Flags Length +#define GAP_LE_FEATS_LEN (0x08) +/// ADV Data and Scan Response length +#define GAP_ADV_DATA_LEN (0x1F) +#define GAP_SCAN_RSP_DATA_LEN (0x1F) +/// Random number length +#define GAP_RAND_NB_LEN (0x08) +/// Key length +#define GAP_KEY_LEN (16) +/// P256 Key Len +#define GAP_P256_KEY_LEN (0x20) + + +///***** AD Type Flag - Bit set *******/ +/// Limited discovery flag - AD Flag +#define GAP_LE_LIM_DISCOVERABLE_FLG 0x01 +/// General discovery flag - AD Flag +#define GAP_LE_GEN_DISCOVERABLE_FLG 0x02 +/// Legacy BT not supported - AD Flag +#define GAP_BR_EDR_NOT_SUPPORTED 0x04 +/// Dual mode for controller supported (BR/EDR/LE) - AD Flag +#define GAP_SIMUL_BR_EDR_LE_CONTROLLER 0x08 +/// Dual mode for host supported (BR/EDR/LE) - AD Flag +#define GAP_SIMUL_BR_EDR_LE_HOST 0x10 + +/*********** GAP Miscellaneous Defines *************/ +/// Invalid connection index +#define GAP_INVALID_CONIDX 0xFF + +/// Invalid connection handle +#define GAP_INVALID_CONHDL 0xFFFF + +/// Connection interval min (N*1.250ms) +#define GAP_CNX_INTERVAL_MIN 6 //(0x06) +/// Connection interval Max (N*1.250ms) +#define GAP_CNX_INTERVAL_MAX 3200 //(0xC80) +/// Connection latency min (N*cnx evt) +#define GAP_CNX_LATENCY_MIN 0 //(0x00) +/// Connection latency Max (N*cnx evt +#define GAP_CNX_LATENCY_MAX 499 //(0x1F3) +/// Supervision TO min (N*10ms) +#define GAP_CNX_SUP_TO_MIN 10 //(0x0A) +/// Supervision TO Max (N*10ms) +#define GAP_CNX_SUP_TO_MAX 3200 //(0xC80) + + + +/// Length of resolvable random address prand part +#define GAP_ADDR_PRAND_LEN (3) +/// Length of resolvable random address hash part +#define GAP_ADDR_HASH_LEN (3) + +/* + * DEFINES - Optional for BLE application usage + **************************************************************************************** + */ + +/// Central idle timer +/// TGAP(conn_pause_central) +/// recommended value: 1 s: (100 for ke timer) +#define GAP_TMR_CONN_PAUSE_CT 0x0064 + +/// Minimum time upon connection establishment before the peripheral +/// starts a connection update procedure: TGAP(conn_pause_peripheral) +/// recommended value: 5 s: (500 for ke timer) +#define GAP_TMR_CONN_PAUSE_PH 0x01F4 + +/// Minimum time to perform scanning when user initiated +/// TGAP(scan_fast_period) +/// recommended value: 30.72 s: (3072 for ke timer) +#define GAP_TMR_SCAN_FAST_PERIOD 0x0C00 + +/// Minimum time to perform advertising when user initiated +/// TGAP(adv_fast_period) +/// recommended value: 30 s: (3000 for ke timer) +#define GAP_TMR_ADV_FAST_PERIOD 0x0BB8 + +/// Scan interval used during Link Layer Scanning State when +/// performing the Limited Discovery procedure +/// TGAP(lim_disc_scan_int) +/// recommended value: 11.25ms; (18 decimal) +#define GAP_LIM_DISC_SCAN_INT 0x0012 + +/// Scan interval in any discovery or connection establishment +/// procedure when user initiated: TGAP(scan_fast_interval) +/// recommended value: 30 to 60 ms; N * 0.625 +#define GAP_SCAN_FAST_INTV 0x0030 + +/// Scan window in any discovery or connection establishment +/// procedure when user initiated: TGAP(scan_fast_window) +/// recommended value: 30 ms; N * 0.625 +#define GAP_SCAN_FAST_WIND 0x0030 + +/// Scan interval in any discovery or connection establishment +/// procedure when background scanning: TGAP(scan_slow_interval1) +/// recommended value: 1.28 s : 0x00CD (205); N * 0.625 +#define GAP_SCAN_SLOW_INTV1 0x00CD + +/// Scan interval in any discovery or connection establishment +/// procedure when background scanning: TGAP(scan_slow_interval2) +/// recommended value: 2.56 s : 0x019A (410); N * 0.625 +#define GAP_SCAN_SLOW_INTV2 0x019A + +/// Scan window in any discovery or connection establishment +/// procedure when background scanning: TGAP(scan_slow_window1) +/// recommended value: 11.25 ms : 0x0012 (18); N * 0.625 +#define GAP_SCAN_SLOW_WIND1 0x0012 + +/// Scan window in any discovery or connection establishment +/// procedure when background scanning: TGAP(scan_slow_window2) +/// recommended value: 22.5 ms : 0x0024 (36); N * 0.625 +#define GAP_SCAN_SLOW_WIND2 0x0024 + +/// Minimum to maximum advertisement interval in any discoverable +/// or connectable mode when user initiated: TGAP(adv_fast_interval1) +/// recommended value: 30 to 60 ms; N * 0.625 +#define GAP_ADV_FAST_INTV1 0x0030 + +/// Minimum to maximum advertisement interval in any discoverable +/// or connectable mode when user initiated: TGAP(adv_fast_interval2) +/// recommended value: 100 to 150 ms; N * 0.625 +#define GAP_ADV_FAST_INTV2 0x0064 + +/// Minimum to maximum advertisement interval in any discoverable or +/// connectable mode when background advertising: TGAP(adv_slow_interval) +/// recommended value: 1 to 1.2 s : 0x00B0 (176); N * 0.625 +#define GAP_ADV_SLOW_INTV 0x00B0 + +/// Minimum to maximum connection interval upon any connection +/// establishment: TGAP(initial_conn_interval) +/// recommended value: 30 to 50 ms ; N * 1.25 ms +#define GAP_INIT_CONN_MIN_INTV 0x0018 +#define GAP_INIT_CONN_MAX_INTV 0x0028 + +/// RW Defines +#define GAP_INQ_SCAN_INTV 0x0012 +#define GAP_INQ_SCAN_WIND 0x0012 + +/// Connection supervision timeout +/// recommended value: 20s +#define GAP_CONN_SUPERV_TIMEOUT 0x07D0 + +/// Minimum connection event +/// default value: 0x0000 +#define GAP_CONN_MIN_CE 0x0000 + +/// Maximum connection event +/// default value: 0xFFFF +#define GAP_CONN_MAX_CE 0xFFFF + +/// Connection latency +/// default value: 0x0000 +#define GAP_CONN_LATENCY 0x0000 + +/// GAP Device name Characteristic +/// Default device name +#define GAP_DEV_NAME "RIVIERAWAVES-BLE" + +/// GAP Appearance or Icon Characteristic - 2 octets +/// Current appearance value is 0x0000 (unknown appearance) +/// Description: +/// http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml +#define GAP_APPEARANCE 0x0000 + +///GAP Peripheral Preferred Connection Parameter - 8 octets +#define GAP_PPCP_CONN_INTV_MAX 0x0064 +#define GAP_PPCP_CONN_INTV_MIN 0x00C8 +#define GAP_PPCP_SLAVE_LATENCY 0x0000 +#define GAP_PPCP_STO_MULT 0x07D0 + +/* + * Enumerations + **************************************************************************************** + */ +/// GAP Advertising Flags +enum gap_ad_type +{ + /// Flag + GAP_AD_TYPE_FLAGS = 0x01, + /// Use of more than 16 bits UUID + GAP_AD_TYPE_MORE_16_BIT_UUID = 0x02, + /// Complete list of 16 bit UUID + GAP_AD_TYPE_COMPLETE_LIST_16_BIT_UUID = 0x03, + /// Use of more than 32 bit UUD + GAP_AD_TYPE_MORE_32_BIT_UUID = 0x04, + /// Complete list of 32 bit UUID + GAP_AD_TYPE_COMPLETE_LIST_32_BIT_UUID = 0x05, + /// Use of more than 128 bit UUID + GAP_AD_TYPE_MORE_128_BIT_UUID = 0x06, + /// Complete list of 128 bit UUID + GAP_AD_TYPE_COMPLETE_LIST_128_BIT_UUID = 0x07, + /// Shortened device name + GAP_AD_TYPE_SHORTENED_NAME = 0x08, + /// Complete device name + GAP_AD_TYPE_COMPLETE_NAME = 0x09, + /// Transmit power + GAP_AD_TYPE_TRANSMIT_POWER = 0x0A, + /// Class of device + GAP_AD_TYPE_CLASS_OF_DEVICE = 0x0D, + /// Simple Pairing Hash C + GAP_AD_TYPE_SP_HASH_C = 0x0E, + /// Simple Pairing Randomizer + GAP_AD_TYPE_SP_RANDOMIZER_R = 0x0F, + /// Temporary key value + GAP_AD_TYPE_TK_VALUE = 0x10, + /// Out of Band Flag + GAP_AD_TYPE_OOB_FLAGS = 0x11, + /// Slave connection interval range + GAP_AD_TYPE_SLAVE_CONN_INT_RANGE = 0x12, + /// Require 16 bit service UUID + GAP_AD_TYPE_RQRD_16_BIT_SVC_UUID = 0x14, + /// Require 32 bit service UUID + GAP_AD_TYPE_RQRD_32_BIT_SVC_UUID = 0x1F, + /// Require 128 bit service UUID + GAP_AD_TYPE_RQRD_128_BIT_SVC_UUID = 0x15, + /// Service data 16-bit UUID + GAP_AD_TYPE_SERVICE_16_BIT_DATA = 0x16, + /// Service data 32-bit UUID + GAP_AD_TYPE_SERVICE_32_BIT_DATA = 0x20, + /// Service data 128-bit UUID + GAP_AD_TYPE_SERVICE_128_BIT_DATA = 0x21, + /// Public Target Address + GAP_AD_TYPE_PUB_TGT_ADDR = 0x17, + /// Random Target Address + GAP_AD_TYPE_RAND_TGT_ADDR = 0x18, + /// Appearance + GAP_AD_TYPE_APPEARANCE = 0x19, + /// Advertising Interval + GAP_AD_TYPE_ADV_INTV = 0x1A, + /// LE Bluetooth Device Address + GAP_AD_TYPE_LE_BT_ADDR = 0x1B, + /// LE Role + GAP_AD_TYPE_LE_ROLE = 0x1C, + /// Simple Pairing Hash C-256 + GAP_AD_TYPE_SPAIR_HASH = 0x1D, + /// Simple Pairing Randomizer R-256 + GAP_AD_TYPE_SPAIR_RAND = 0x1E, + /// 3D Information Data + GAP_AD_TYPE_3D_INFO = 0x3D, + + /// Manufacturer specific data + GAP_AD_TYPE_MANU_SPECIFIC_DATA = 0xFF, +}; + + +/// Random Address type +enum gap_rnd_addr_type +{ + /// Static random address - 11 (MSB->LSB) + GAP_STATIC_ADDR = 0xC0, + /// Private non resolvable address - 01 (MSB->LSB) + GAP_NON_RSLV_ADDR = 0x00, + /// Private resolvable address - 01 (MSB->LSB) + GAP_RSLV_ADDR = 0x40, +}; + +/// Boolean value set +enum +{ + /// Disable + GAP_DISABLE = 0x00, + /// Enable + GAP_ENABLE +}; + + +/// GAP Attribute database handles +/// Generic Access Profile Service +enum +{ + GAP_IDX_PRIM_SVC, + GAP_IDX_CHAR_DEVNAME, + GAP_IDX_DEVNAME, + GAP_IDX_CHAR_ICON, + GAP_IDX_ICON, + GAP_IDX_CHAR_SLAVE_PREF_PARAM, + GAP_IDX_SLAVE_PREF_PARAM, + GAP_IDX_CHAR_CNT_ADDR_RESOL, + GAP_IDX_CNT_ADDR_RESOL, + GAP_IDX_NUMBER +}; + + + +/****************** GAP Role **********************/ +enum gap_role +{ + /// No role set yet + GAP_ROLE_NONE = 0x00, + + /// Observer role + GAP_ROLE_OBSERVER = 0x01, + + /// Broadcaster role + GAP_ROLE_BROADCASTER = 0x02, + + /// Master/Central role + GAP_ROLE_CENTRAL = (0x04 | GAP_ROLE_OBSERVER), + + /// Peripheral/Slave role + GAP_ROLE_PERIPHERAL = (0x08 | GAP_ROLE_BROADCASTER), + + /// Device has all role, both peripheral and central + GAP_ROLE_ALL = (GAP_ROLE_CENTRAL | GAP_ROLE_PERIPHERAL), + + /// Debug mode used to force LL configuration on BLE 4.0 + GAP_ROLE_DBG_LE_4_0 = 0x80, +}; + +/// Advertising mode +enum gap_adv_mode +{ + /// Mode in non-discoverable + GAP_NON_DISCOVERABLE, + /// Mode in general discoverable + GAP_GEN_DISCOVERABLE, + /// Mode in limited discoverable + GAP_LIM_DISCOVERABLE, + /// Broadcaster mode which is a non discoverable and non connectable mode. + GAP_BROADCASTER_MODE +}; + +/// Scan mode +enum gap_scan_mode +{ + /// Mode in general discovery + GAP_GEN_DISCOVERY, + /// Mode in limited discovery + GAP_LIM_DISCOVERY, + /// Observer mode + GAP_OBSERVER_MODE, + /// Invalid mode + GAP_INVALID_MODE +}; + + + +/// IO Capability Values +enum gap_io_cap +{ + /// Display Only + GAP_IO_CAP_DISPLAY_ONLY = 0x00, + /// Display Yes No + GAP_IO_CAP_DISPLAY_YES_NO, + /// Keyboard Only + GAP_IO_CAP_KB_ONLY, + /// No Input No Output + GAP_IO_CAP_NO_INPUT_NO_OUTPUT, + /// Keyboard Display + GAP_IO_CAP_KB_DISPLAY, + GAP_IO_CAP_LAST +}; + +/// TK Type +enum gap_tk_type +{ + /// TK get from out of band method + GAP_TK_OOB = 0x00, + /// TK generated and shall be displayed by local device + GAP_TK_DISPLAY, + /// TK shall be entered by user using device keyboard + GAP_TK_KEY_ENTRY +}; + +/// OOB Data Present Flag Values +enum gap_oob +{ + /// OOB Data not present + GAP_OOB_AUTH_DATA_NOT_PRESENT = 0x00, + /// OOB data present + GAP_OOB_AUTH_DATA_PRESENT, + GAP_OOB_AUTH_DATA_LAST +}; + +/// Authentication mask +enum gap_auth_mask +{ + /// No Flag set + GAP_AUTH_NONE = 0, + /// Bond authentication + GAP_AUTH_BOND = (1 << 0), + /// Man In the middle protection + GAP_AUTH_MITM = (1 << 2), + /// Secure Connection + GAP_AUTH_SEC_CON = (1 << 3), + /// Key Notification + GAP_AUTH_KEY_NOTIF = (1 << 4) +}; + +/// Security Link Level +enum gap_lk_sec_lvl +{ + /// No authentication + GAP_LK_NO_AUTH = 0, + /// Unauthenticated link + GAP_LK_UNAUTH, + /// Authenticated link + GAP_LK_AUTH, + /// Secure Connection link + GAP_LK_SEC_CON, +}; + +/// Authentication Requirements +enum gap_auth +{ + /// No MITM No Bonding + GAP_AUTH_REQ_NO_MITM_NO_BOND = (GAP_AUTH_NONE), + /// No MITM Bonding + GAP_AUTH_REQ_NO_MITM_BOND = (GAP_AUTH_BOND), + /// MITM No Bonding + GAP_AUTH_REQ_MITM_NO_BOND = (GAP_AUTH_MITM), + /// MITM and Bonding + GAP_AUTH_REQ_MITM_BOND = (GAP_AUTH_MITM | GAP_AUTH_BOND), + /// SEC_CON and No Bonding + GAP_AUTH_REQ_SEC_CON_NO_BOND = (GAP_AUTH_SEC_CON), + /// SEC_CON and Bonding + GAP_AUTH_REQ_SEC_CON_BOND = (GAP_AUTH_SEC_CON | GAP_AUTH_BOND), + + GAP_AUTH_REQ_LAST, + + /// Mask of authentication features without reserved flag + GAP_AUTH_REQ_MASK = 0x1F, +}; + +/// Key Distribution Flags +enum gap_kdist +{ + /// No Keys to distribute + GAP_KDIST_NONE = 0x00, + /// Encryption key in distribution + GAP_KDIST_ENCKEY = (1 << 0), + /// IRK (ID key)in distribution + GAP_KDIST_IDKEY = (1 << 1), + /// CSRK(Signature key) in distribution + GAP_KDIST_SIGNKEY= (1 << 2), + /// LTK in distribution + GAP_KDIST_LINKKEY= (1 << 3), + + GAP_KDIST_LAST = (1 << 4) +}; + +/// Security Defines +enum gap_sec_req +{ + /// No security (no authentication and encryption) + GAP_NO_SEC = 0x00, + /// Unauthenticated pairing with encryption + GAP_SEC1_NOAUTH_PAIR_ENC, + /// Authenticated pairing with encryption + GAP_SEC1_AUTH_PAIR_ENC, + /// Unauthenticated pairing with data signing + GAP_SEC2_NOAUTH_DATA_SGN, + /// Authentication pairing with data signing + GAP_SEC2_AUTH_DATA_SGN, + /// Secure Connection pairing with encryption + GAP_SEC1_SEC_CON_PAIR_ENC, +}; + +/// Bit field use to select the preferred TX or RX LE PHY Rate. 0 means no preferences +enum gap_rate +{ + /// No preferred rate + GAP_RATE_ANY = 0x00, + /// LE PHY 1mb/s preferred rate for an active link + GAP_RATE_LE_1MBPS = (1 << 0), + /// LE PHY 2mb/s preferred rate for an active link + GAP_RATE_LE_2MBPS = (1 << 1), +}; + +/// API settings bit field values +enum gap_api_settings +{ + /// Use deprecated API and do not use extended air operations + GAP_ADD_INFO_USE_DEPRECATED_API_BIT = (1 << 0), +}; + +/// Privacy configuration +enum gap_priv_cfg +{ + /// Indicate if public or static private random address must be used by default + GAP_PRIV_CFG_PRIV_ADDR_BIT = (1 << 0), + /// Bit 1 is reserved + GAP_PRIV_CFG_RSVD = (1 << 1), + /// Indicate if controller privacy is enabled + GAP_PRIV_CFG_CTNL_PRIV_BIT = (1 << 2), +}; + +/// Type of own address +enum gap_own_addr_type +{ + /// Use address configured using GAPM_SET_DEV_CONFIG_CMD. + /// Can be either a public address or a random static address + GAP_OWN_ADDR_TYPE_DEFAULT = 0, + /// Use a non-resolvable private address + GAP_OWN_ADDR_TYPE_NRPA, + /// Use a resolvable private address + GAP_OWN_ADDR_TYPE_RPA, +}; + +/// Type of activities that can be created +enum gap_actv_type +{ + /// Advertising activity + GAP_ACTV_TYPE_ADV = 0, + /// Scanning activity + GAP_ACTV_TYPE_SCAN, + /// Initiating activity + GAP_ACTV_TYPE_INIT, + /// Periodic synchronization activity + GAP_ACTV_TYPE_PERIOD_SYNC, +}; + +/// Type of advertising that can be created +enum gap_adv_type +{ + /// Legacy advertising + GAP_ADV_TYPE_LEGACY = 0, + /// Extended advertising + GAP_ADV_TYPE_EXTENDED, + /// Periodic advertising + GAP_ADV_TYPE_PERIODIC, +}; + +/// Advertising report type +enum gap_adv_report_type +{ + /// Extended advertising report + GAP_REPORT_TYPE_ADV_EXT = 0, + /// Legacy advertising report + GAP_REPORT_TYPE_ADV_LEG, + /// Extended scan response report + GAP_REPORT_TYPE_SCAN_RSP_EXT, + /// Legacy scan response report + GAP_REPORT_TYPE_SCAN_RSP_LEG, + /// Periodic advertising report + GAP_REPORT_TYPE_PER_ADV, +}; + +/// Advertising properties bit field bit value +enum gap_adv_prop +{ + /// Indicate that advertising is connectable, reception of CONNECT_REQ or AUX_CONNECT_REQ + /// PDUs is accepted. Not applicable for periodic advertising. + GAP_ADV_PROP_CONNECTABLE_BIT = (1 << 0), + /// Indicate that advertising is scannable, reception of SCAN_REQ or AUX_SCAN_REQ PDUs is + /// accepted + GAP_ADV_PROP_SCANNABLE_BIT = (1 << 1), + /// Indicate that advertising targets a specific device. Only apply in following cases: + /// - Legacy advertising: if connectable + /// - Extended advertising: connectable or (non connectable and non discoverable) + GAP_ADV_PROP_DIRECTED_BIT = (1 << 2), + /// Indicate that High Duty Cycle has to be used for advertising on primary channel + /// Apply only if created advertising is not an extended advertising + GAP_ADV_PROP_HDC_BIT = (1 << 3), + /// Bit 4 is reserved + GAP_ADV_PROP_RESERVED_4_BIT = (1 << 4), + /// Enable anonymous mode. Device address won't appear in send PDUs + /// Valid only if created advertising is an extended advertising + GAP_ADV_PROP_ANONYMOUS_BIT = (1 << 5), + /// Include TX Power in the extended header of the advertising PDU. + /// Valid only if created advertising is not a legacy advertising + GAP_ADV_PROP_TX_PWR_BIT = (1 << 6), + /// Include TX Power in the periodic advertising PDU. + /// Valid only if created advertising is a periodic advertising + GAP_ADV_PROP_PER_TX_PWR_BIT = (1 << 7), + /// Indicate if application must be informed about received scan requests PDUs + GAP_ADV_PROP_SCAN_REQ_NTF_EN_BIT = (1 << 8), +}; + +/// PHY Type +enum gap_phy_type +{ + /// LE 1M + GAP_PHY_TYPE_LE_1M = 0, + /// LE 2M + GAP_PHY_TYPE_LE_2M, + /// LE Coded + GAP_PHY_TYPE_LE_CODED, +}; + +/// Advertising discovery mode +enum gap_adv_disc_mode +{ + /// Mode in non-discoverable + GAP_ADV_MODE_NON_DISC = 0, + /// Mode in general discoverable + GAP_ADV_MODE_GEN_DISC, + /// Mode in limited discoverable + GAP_ADV_MODE_LIM_DISC, +}; + +/// Scanning Types +enum gap_scan_type +{ + /// General discovery + GAP_SCAN_TYPE_GEN_DISC = 0, + /// Limited discovery + GAP_SCAN_TYPE_LIM_DISC, + /// Observer + GAP_SCAN_TYPE_OBSERVER, + /// Selective observer + GAP_SCAN_TYPE_SEL_OBSERVER, + /// Connectable discovery + GAP_SCAN_TYPE_CONN_DISC, + /// Selective connectable discovery + GAP_SCAN_TYPE_SEL_CONN_DISC, +}; + +/// Scanning properties bit field bit value +enum gap_scan_prop +{ + /// Scan advertisement on the LE 1M PHY + GAP_SCAN_PROP_PHY_1M_BIT = (1 << 0), + /// Scan advertisement on the LE Coded PHY + GAP_SCAN_PROP_PHY_CODED_BIT = (1 << 1), + /// Active scan on LE 1M PHY (Scan Request PDUs may be sent) + GAP_SCAN_PROP_ACTIVE_1M_BIT = (1 << 2), + /// Active scan on LE Coded PHY (Scan Request PDUs may be sent) + GAP_SCAN_PROP_ACTIVE_CODED_BIT = (1 << 3), + /// Accept directed advertising packets if we use a RPA and target address cannot be solved by the + /// controller + GAP_SCAN_PROP_ACCEPT_RPA_BIT = (1 << 4), + /// Filter truncated advertising or scan response reports + GAP_SCAN_PROP_FILT_TRUNC_BIT = (1 << 5), +}; + +/// Initiating Types +enum gap_init_type +{ + /// Direct connection establishment, establish a connection with an indicated device + GAPM_INIT_TYPE_DIRECT_CONN_EST = 0, + /// Automatic connection establishment, establish a connection with all devices whose address is + /// present in the white list + GAPM_INIT_TYPE_AUTO_CONN_EST, + /// 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. + GAPM_INIT_TYPE_NAME_DISC, +}; + +/// Initiating Properties +enum gap_init_prop +{ + /// Scan connectable advertisements on the LE 1M PHY. Connection parameters for the LE 1M PHY are provided + GAPM_INIT_PROP_1M_BIT = (1 << 0), + /// Connection parameters for the LE 2M PHY are provided + GAPM_INIT_PROP_2M_BIT = (1 << 1), + /// Scan connectable advertisements on the LE Coded PHY. Connection parameters for the LE Coded PHY are provided + GAPM_INIT_PROP_CODED_BIT = (1 << 2), +}; + +/// Advertising report information +enum gap_adv_report_info +{ + /// Report Type + GAP_REPORT_INFO_REPORT_TYPE = 0x07, + /// Report is complete + GAP_REPORT_INFO_COMPLETE = (1 << 3), + /// Connectable advertising + GAP_REPORT_INFO_CONN_ADV = (1 << 4), + /// Scannable advertising + GAP_REPORT_INFO_SCAN_ADV = (1 << 5), + /// Directed advertising + GAP_REPORT_INFO_DIR_ADV = (1 << 6), +}; + +/// Filtering policy for duplicated packets +enum gap_dup_filter_pol +{ + /// Disable filtering of duplicated packets + GAP_DUP_FILT_DIS = 0, + /// Enable filtering of duplicated packets + GAP_DUP_FILT_EN, + /// Enable filtering of duplicated packets, reset for each scan period + GAP_DUP_FILT_EN_PERIOD, +}; + +/* + * Masks for advertising properties + **************************************************************************************** + */ + +/// Advertising properties configurations for legacy advertising +enum gap_leg_adv_prop +{ + /// Non connectable non scannable advertising + GAP_ADV_PROP_NON_CONN_NON_SCAN_MASK = 0x0000, + /// Broadcast non scannable advertising - Discovery mode must be Non Discoverable + GAP_ADV_PROP_BROADCAST_NON_SCAN_MASK = GAP_ADV_PROP_NON_CONN_NON_SCAN_MASK, + /// Non connectable scannable advertising + GAP_ADV_PROP_NON_CONN_SCAN_MASK = GAP_ADV_PROP_SCANNABLE_BIT, + /// Broadcast non scannable advertising - Discovery mode must be Non Discoverable + GAP_ADV_PROP_BROADCAST_SCAN_MASK = GAP_ADV_PROP_NON_CONN_SCAN_MASK, + /// Undirected connectable advertising + GAP_ADV_PROP_UNDIR_CONN_MASK = GAP_ADV_PROP_CONNECTABLE_BIT | GAP_ADV_PROP_SCANNABLE_BIT, + /// Directed connectable advertising + GAP_ADV_PROP_DIR_CONN_MASK = GAP_ADV_PROP_DIRECTED_BIT | GAP_ADV_PROP_CONNECTABLE_BIT, + /// Directed connectable with Low Duty Cycle + GAP_ADV_PROP_DIR_CONN_LDC_MASK = GAP_ADV_PROP_DIR_CONN_MASK, + /// Directed connectable with High Duty Cycle + GAP_ADV_PROP_DIR_CONN_HDC_MASK = GAP_ADV_PROP_DIR_CONN_MASK | GAP_ADV_PROP_HDC_BIT, +}; + +/// Advertising properties configurations for extended advertising +enum gap_ext_adv_prop +{ + /// Non connectable non scannable extended advertising + GAP_EXT_ADV_PROP_NON_CONN_NON_SCAN_MASK = 0x0000, + /// Non connectable scannable extended advertising + GAP_EXT_ADV_PROP_NON_CONN_SCAN_MASK = GAP_ADV_PROP_SCANNABLE_BIT, + /// Undirected connectable extended advertising + GAP_EXT_ADV_PROP_UNDIR_CONN_MASK = GAP_ADV_PROP_CONNECTABLE_BIT, + /// Directed connectable extended advertising + GAP_EXT_ADV_PROP_DIR_CONN_MASK = GAP_ADV_PROP_CONNECTABLE_BIT | GAP_ADV_PROP_DIRECTED_BIT, +}; + +/*************** GAP Structures ********************/ + +/// Device name +struct gap_dev_name +{ + /// name length + uint16_t length; + /// name value + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Slave preferred connection parameters +struct gap_slv_pref +{ + /// Connection interval minimum + uint16_t con_intv_min; + /// Connection interval maximum + uint16_t con_intv_max; + /// Slave latency + uint16_t slave_latency; + /// Connection supervision timeout multiplier + uint16_t conn_timeout; +}; + +///BD Address structure +#define BLE_BD_ADDR_T +typedef struct +{ + ///6-byte array address value + uint8_t addr[GAP_BD_ADDR_LEN]; +} bd_addr_t; + +///Channel map structure +typedef struct +{ + ///5-byte channel map array + uint8_t map[GAP_LE_CHNL_MAP_LEN]; +} le_chnl_map_t; + + +///Random number structure +typedef struct +{ + ///8-byte array for random number + uint8_t nb[GAP_RAND_NB_LEN]; +} rand_nb_t; + +///Advertising report structure +typedef struct +{ + ///Event type: + /// - ADV_CONN_UNDIR: Connectable Undirected advertising + /// - ADV_CONN_DIR: Connectable directed advertising + /// - ADV_DISC_UNDIR: Discoverable undirected advertising + /// - ADV_NONCONN_UNDIR: Non-connectable undirected advertising + uint8_t evt_type; + ///Advertising address type: public/random + uint8_t adv_addr_type; + ///Advertising address value + bd_addr_t adv_addr; + ///Data length in advertising packet + uint8_t data_len; + ///Data of advertising packet + uint8_t data[GAP_ADV_DATA_LEN]; + ///RSSI value for advertising packet + uint8_t rssi; +} adv_report_t; + + +/// P256 Public key data format +typedef struct +{ + /// X Coordinate of the key + uint8_t x[GAP_P256_KEY_LEN]; + /// X Coordinate of the key + uint8_t y[GAP_P256_KEY_LEN]; +} public_key_t; +/// P256 private key data format +typedef struct +{ + ///MSB->LSB + uint8_t Secrt_key[GAP_P256_KEY_LEN]; +} private_key_t; + + + +/// Address information about a device address +struct gap_bdaddr +{ + /// BD Address of device + bd_addr_t addr; + /// Address type of the device 0=public/1=private random + uint8_t addr_type; +}; + +/// Resolving list device information +struct gap_ral_dev_info +{ + /// Address type of the device 0=public/1=private random + uint8_t addr_type; + /// BD Address of device + bd_addr_t addr; + /// Peer IRK + uint8_t peer_irk[GAP_KEY_LEN]; + /// Local IRK + uint8_t local_irk[GAP_KEY_LEN]; +}; + +/// Generic Security key structure +struct gap_sec_key +{ + /// Key value MSB -> LSB + uint8_t key[GAP_KEY_LEN]; +}; + +/// Configuration for advertising on primary channel +struct gap_adv_prim_cfg +{ + /// Minimum advertising interval (in unit of 625us). Must be greater than 20ms + uint32_t adv_intv_min; + /// Maximum advertising interval (in unit of 625us). Must be greater than 20ms + uint32_t adv_intv_max; + /// Bit field indicating the channel mapping + uint8_t chnl_map; + /// Indicate on which PHY primary advertising has to be performed (@see enum gap_phy_type) + /// Note that LE 2M PHY is not allowed and that legacy advertising only support LE 1M PHY + uint8_t phy; +}; + +/// Configuration for advertising on secondary channel +struct gap_adv_second_cfg +{ + /// Maximum number of advertising events the controller can skip before sending the + /// AUX_ADV_IND packets. 0 means that AUX_ADV_IND PDUs shall be sent prior each + /// advertising events + uint8_t max_skip; + /// Indicate on which PHY secondary advertising has to be performed (@see enum gap_phy_type) + uint8_t phy; + /// Advertising SID + uint8_t adv_sid; +}; + +/// Configuration for periodic advertising +struct gap_adv_period_cfg +{ + /// Minimum advertising interval (in unit of 1.25ms). Must be greater than 20ms + uint16_t adv_intv_min; + /// Maximum advertising interval (in unit of 1.25ms). Must be greater than 20ms + uint16_t adv_intv_max; +}; + +/// Advertising parameters +struct gap_adv_param +{ + /// Advertising type (@see enum gap_adv_type) + uint8_t type; + /// Discovery mode (@see enum gap_adv_mode) + uint8_t disc_mode; + /// Bit field value provided advertising properties (@see enum gap_adv_prop for bit signification) + uint16_t prop; + /// Maximum power level at which the advertising packets have to be transmitted + /// (between -127 and 126 dBm) + int8_t max_tx_pwr; + /// Advertising filtering policy + uint8_t filter_pol; + /// Peer address configuration (only used in case of directed advertising) + struct gap_bdaddr peer_addr; + /// Configuration for primary advertising + struct gap_adv_prim_cfg prim_cfg; + /// Configuration for secondary advertising (valid only if advertising type is + /// GAPM_ADV_TYPE_EXTENDED or GAPM_ADV_TYPE_PERIODIC) + struct gap_adv_second_cfg second_cfg; + /// Configuration for periodic advertising (valid only if advertising type os + /// GAPM_ADV_TYPE_PERIODIC) + struct gap_adv_period_cfg period_cfg; +}; + +/// Additional advertising parameters +struct gap_adv_add_param +{ + /// Advertising duration (in unit of 10ms). 0 means that advertising continues + /// until the host disable it + uint16_t duration; + /// Maximum number of extended advertising events the controller shall attempt to send prior to + /// terminating the extending advertising + /// Valid only if extended advertising + uint8_t max_adv_evt; +}; + +/// Scan Window operation parameters +struct gap_scan_wd_op_param +{ + /// Scan interval + uint16_t scan_intv; + /// Scan window + uint16_t scan_wd; +}; + +/// Scanning parameters +struct gap_scan_param +{ + /// Type of scanning to be started (@see enum gap_scan_type) + uint8_t type; + /// Properties for the scan procedure (@see enum gap_scan_prop for bit signification) + uint8_t prop; + /// Duplicate packet filtering policy + uint8_t dup_filt_pol; + /// Reserved for future use + uint8_t rsvd; + /// Scan window opening parameters for LE 1M PHY + struct gap_scan_wd_op_param scan_param_1m; + /// Scan window opening parameters for LE Coded PHY + struct gap_scan_wd_op_param scan_param_coded; + /// Scan duration (in unit of 10ms). 0 means that the controller will scan continuously until + /// reception of a stop command from the application + uint16_t duration; + /// Scan period (in unit of 1.28s). Time interval betweem two consequent starts of a scan duration + /// by the controller. 0 means that the scan procedure is not periodic + uint16_t period; +}; + +/// Connection parameters +struct gap_conn_param +{ + /// 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.5ms to 4s. + uint16_t conn_intv_min; + /// 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.5ms to 4s. + uint16_t conn_intv_max; + /// Slave latency. Number of events that can be missed by a connected slave device + uint16_t conn_latency; + /// Link supervision timeout (in unit of 10ms). Allowed range is 100ms to 32s + uint16_t supervision_to; + /// Recommended minimum duration of connection events (in unit of 625us) + uint16_t ce_len_min; + /// Recommended maximum duration of connection events (in unit of 625us) + uint16_t ce_len_max; +}; + +/// Initiating parameters +struct gap_init_param +{ + /// Initiating type (@see enum gap_init_type) + uint8_t type; + /// Properties for the initiating procedure (@see enum gap_init_prop for bit signification) + uint8_t prop; + /// Timeout for automatic connection establishment (in unit of 10ms). Cancel the procedure if not all + /// indicated devices have been connected when the timeout occurs. 0 means there is no timeout + uint16_t conn_to; + /// Scan window opening parameters for LE 1M PHY + struct gap_scan_wd_op_param scan_param_1m; + /// Scan window opening parameters for LE Coded PHY + struct gap_scan_wd_op_param scan_param_coded; + /// Connection parameters for LE 1M PHY + struct gap_conn_param conn_param_1m; + /// Connection parameters for LE 2M PHY + struct gap_conn_param conn_param_2m; + /// Connection parameters for LE Coded PHY + struct gap_conn_param conn_param_coded; + /// Address of peer device in case white list is not used for connection + struct gap_bdaddr peer_addr; +}; + +/// Periodic advertising information +struct gap_period_adv_addr_cfg +{ + /// Advertiser address information + struct gap_bdaddr addr; + /// Advertising SID + uint8_t adv_sid; +}; + +/// Periodic synchronization parameters +struct gap_period_sync_param +{ + /// Number of periodic advertising that can be skipped after a successful receive. Maximum authorized + /// value is 499 + uint16_t skip; + /// Synchronization timeout for the periodic advertising (in unit of 10ms between 100ms and 163.84s) + uint16_t sync_to; + /// Indicate if Periodic Advertiser List has to be used to determine which advertiser to listen to, else + /// provided advertiser information are used + uint8_t use_pal; + /// Reserved for future used + uint8_t rsvd; + /// Address of advertiser with which synchronization has to be established (used only if use_pal is false) + struct gap_period_adv_addr_cfg adv_addr; +}; + +/// @} GAP +#endif // GAP_H_ diff --git a/services/ble_stack/hl/api/gapc_task.h b/services/ble_stack/hl/api/gapc_task.h new file mode 100644 index 0000000..55d02ee --- /dev/null +++ b/services/ble_stack/hl/api/gapc_task.h @@ -0,0 +1,959 @@ +#ifndef _GAPC_TASK_H_ +#define _GAPC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup GAPC_TASK Generic Access Profile Controller Task + * @ingroup GAPC + * @brief Handles ALL messages to/from GAP Controller block. + * + * It handles messages from lower and higher layers related to an ongoing connection. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_task.h" // Task definitions +#include "gap.h" +#include + + +/* + * MACROS + **************************************************************************************** + */ + +/* + * DEFINES + **************************************************************************************** + */ + + +/// GAP Controller Task messages +enum gapc_msg_id +{ + /* Default event */ + /// Command Complete event + GAPC_CMP_EVT = TASK_FIRST_MSG(TASK_ID_GAPC), + + /* Connection state information */ + /// Indicate that a connection has been established + GAPC_CONNECTION_REQ_IND, + /// Set specific link data configuration. + GAPC_CONNECTION_CFM, + + /// Indicate that a link has been disconnected + GAPC_DISCONNECT_IND, + + /* Link management command */ + /// Request disconnection of current link command. + GAPC_DISCONNECT_CMD, + + /* Peer device info */ + /// Retrieve information command + GAPC_GET_INFO_CMD, + /// Peer device attribute DB info such as Device Name, Appearance or Slave Preferred Parameters + GAPC_PEER_ATT_INFO_IND, + /// Indication of peer version info + GAPC_PEER_VERSION_IND, + /// Indication of peer features info + GAPC_PEER_FEATURES_IND, + /// Indication of ongoing connection RSSI + GAPC_CON_RSSI_IND, + + /* Device Name Management */ + /// Peer device request local device info such as name, appearance or slave preferred parameters + GAPC_GET_DEV_INFO_REQ_IND, + /// Send requested info to peer device + GAPC_GET_DEV_INFO_CFM, + /// Peer device request to modify local device info such as name or appearance + GAPC_SET_DEV_INFO_REQ_IND, + /// Local device accept or reject device info modification + GAPC_SET_DEV_INFO_CFM, + + /* Connection parameters update */ + /// Perform update of connection parameters command + GAPC_PARAM_UPDATE_CMD, + /// Request of updating connection parameters indication + GAPC_PARAM_UPDATE_REQ_IND, + /// Master confirm or not that parameters proposed by slave are accepted or not + GAPC_PARAM_UPDATE_CFM, + /// Connection parameters updated indication + GAPC_PARAM_UPDATED_IND, + + /* Bonding procedure */ + /// Start Bonding command procedure + GAPC_BOND_CMD, + /// Bonding requested by peer device indication message. + GAPC_BOND_REQ_IND, + /// Confirm requested bond information. + GAPC_BOND_CFM, + /// Bonding information indication message + GAPC_BOND_IND, + + /* Encryption procedure */ + /// Start Encryption command procedure + GAPC_ENCRYPT_CMD, + /// Encryption requested by peer device indication message. + GAPC_ENCRYPT_REQ_IND, + /// Confirm requested Encryption information. + GAPC_ENCRYPT_CFM, + /// Encryption information indication message + GAPC_ENCRYPT_IND, + + /* Security request procedure */ + /// Start Security Request command procedure + GAPC_SECURITY_CMD, + /// Security requested by peer device indication message + GAPC_SECURITY_IND, + + /* Signature procedure */ + /// Indicate the current sign counters to the application + GAPC_SIGN_COUNTER_IND, + + /* Device information */ + /// Indication of ongoing connection Channel Map + GAPC_CON_CHANNEL_MAP_IND, + + + /* Deprecated */ + /// Deprecated messages + GAPC_DEPRECATED_0, + GAPC_DEPRECATED_1, + GAPC_DEPRECATED_2, + GAPC_DEPRECATED_3, + GAPC_DEPRECATED_4, + GAPC_DEPRECATED_5, + GAPC_DEPRECATED_6, + GAPC_DEPRECATED_7, + GAPC_DEPRECATED_8, + GAPC_DEPRECATED_9, + + /* LE Ping */ + /// Update LE Ping timeout value + GAPC_SET_LE_PING_TO_CMD, + /// LE Ping timeout indication + GAPC_LE_PING_TO_VAL_IND, + /// LE Ping timeout expires indication + GAPC_LE_PING_TO_IND, + + /* LE Data Length extension*/ + /// LE Set Data Length Command + GAPC_SET_LE_PKT_SIZE_CMD, + /// LE Set Data Length Indication + GAPC_LE_PKT_SIZE_IND, + + /* Secure Connections */ + /// Request to inform the remote device when keys have been entered or erased + GAPC_KEY_PRESS_NOTIFICATION_CMD, + /// Indication that a KeyPress has been performed on the peer device. + GAPC_KEY_PRESS_NOTIFICATION_IND, + + /* LE PHY update */ + /// Set the PHY configuration for current active link + GAPC_SET_PHY_CMD, + /// Active link PHY configuration. Triggered when configuration is read or during an update. + GAPC_LE_PHY_IND, + + // ---------------------- INTERNAL API ------------------------ + /* Internal messages for timer events, not part of API*/ + /// Signature procedure + GAPC_SIGN_CMD, + /// Signature result + GAPC_SIGN_IND, + + /// Parameter update procedure timeout indication + GAPC_PARAM_UPDATE_TO_IND, + /// Pairing procedure timeout indication + GAPC_SMP_TIMEOUT_TIMER_IND, + /// Pairing repeated attempts procedure timeout indication + GAPC_SMP_REP_ATTEMPTS_TIMER_IND, +}; + + + + +/// request operation type - application interface +enum gapc_operation +{ + /* Operation Flags */ + /* No Operation (if nothing has been requested) */ + /* ************************************************ */ + /// No operation + GAPC_NO_OP = 0x00, + + /* Connection management */ + /// Disconnect link + GAPC_DISCONNECT, + + /* Connection information */ + /// Retrieve name of peer device. + GAPC_GET_PEER_NAME, + /// Retrieve peer device version info. + GAPC_GET_PEER_VERSION, + /// Retrieve peer device features. + GAPC_GET_PEER_FEATURES, + /// Get Peer device appearance + GAPC_GET_PEER_APPEARANCE, + /// Get Peer device Slaved Preferred Parameters + GAPC_GET_PEER_SLV_PREF_PARAMS, + /// Retrieve connection RSSI. + GAPC_GET_CON_RSSI, + /// Retrieve Connection Channel MAP. + GAPC_GET_CON_CHANNEL_MAP, + + /* Connection parameters update */ + /// Perform update of connection parameters. + GAPC_UPDATE_PARAMS, + + /* Security procedures */ + /// Start bonding procedure. + GAPC_BOND, + /// Start encryption procedure. + GAPC_ENCRYPT, + /// Start security request procedure + GAPC_SECURITY_REQ, + + /* Deprecated */ + /// Deprecated operation + GAPC_OP_DEPRECATED_0, + GAPC_OP_DEPRECATED_1, + GAPC_OP_DEPRECATED_2, + GAPC_OP_DEPRECATED_3, + GAPC_OP_DEPRECATED_4, + + /* LE Ping*/ + /// get timer timeout value + GAPC_GET_LE_PING_TO, + /// set timer timeout value + GAPC_SET_LE_PING_TO, + + /* LE Data Length extension*/ + /// LE Set Data Length + GAPC_SET_LE_PKT_SIZE, + + /* Central Address resolution supported*/ + GAPC_GET_ADDR_RESOL_SUPP, + + /* Secure Connections */ + /// Request to inform the remote device when keys have been entered or erased + GAPC_KEY_PRESS_NOTIFICATION, + + /* LE PHY update */ + /// Set the PHY configuration for current active link + GAPC_SET_PHY, + /// Retrieve PHY configuration of active link + GAPC_GET_PHY, + + // ---------------------- INTERNAL API ------------------------ + /* Packet signature */ + /// sign an attribute packet + GAPC_SIGN_PACKET, + /// Verify signature or an attribute packet + GAPC_SIGN_CHECK, +}; + +/// Bond event type. +enum gapc_bond +{ + /// Bond Pairing request + GAPC_PAIRING_REQ, + /// Respond to Pairing request + GAPC_PAIRING_RSP, + + /// Pairing Finished information + GAPC_PAIRING_SUCCEED, + /// Pairing Failed information + GAPC_PAIRING_FAILED, + + /// Used to retrieve pairing Temporary Key + GAPC_TK_EXCH, + /// Used for Identity Resolving Key exchange + GAPC_IRK_EXCH, + /// Used for Connection Signature Resolving Key exchange + GAPC_CSRK_EXCH, + /// Used for Long Term Key exchange + GAPC_LTK_EXCH, + + /// Bond Pairing request issue, Repeated attempt + GAPC_REPEATED_ATTEMPT, + + /// Out of Band - exchange of confirm and rand. + GAPC_OOB_EXCH, + + /// Numeric Comparison - Exchange of Numeric Value - + GAPC_NC_EXCH +}; + +/// List of device info that should be provided by application +enum gapc_dev_info +{ + /// Device Name + GAPC_DEV_NAME, + /// Device Appearance Icon + GAPC_DEV_APPEARANCE, + /// Device Slave preferred parameters + GAPC_DEV_SLV_PREF_PARAMS, + /// Device Central address resolution + GAPC_DEV_CTL_ADDR_RESOL, + /// maximum device info parameter + GAPC_DEV_INFO_MAX, +}; + +/// List of features available on a device +enum gapc_features_list +{ + /// LE encryption + GAPC_ENCRYPT_FEAT_MASK = (1 << 0), + /// Connection Parameters Request Procedure + GAPC_CONN_PARAM_REQ_FEAT_MASK = (1 << 1), + /// Extended Reject Indication + GAPC_EXT_REJECT_IND_FEAT_MASK = (1 << 2), + /// Slave-initiated Features Exchange + GAPC_SLAVE_FEAT_EXCH_FEAT_MASK = (1 << 3), + /// LE ping + GAPC_LE_PING_FEAT_MASK = (1 << 4), + /// data packet length extension + GAPC_EXT_DATA_LEN_MASK = (1 << 5), + /// LL privacy + GAPC_LL_PRIVACY_MASK = (1 << 6), + /// Extended Scanner Filter Policies + GAPC_EXT_SCANNER_FILTER_POLICIES_MASK = (1 << 7), + +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Operation command structure in order to keep requested operation. +struct gapc_operation_cmd +{ + /// GAP request type + uint8_t operation; +}; + + +/// Command complete event data structure +struct gapc_cmp_evt +{ + /// GAP request type + uint8_t operation; + /// Status of the request + uint8_t status; +}; + +/// Indicate that a connection has been established +struct gapc_connection_req_ind +{ + /// Connection handle + uint16_t conhdl; + /// Connection interval + uint16_t con_interval; + /// Connection latency + uint16_t con_latency; + /// Link supervision timeout + uint16_t sup_to; + /// Clock accuracy + uint8_t clk_accuracy; + /// Peer address type + uint8_t peer_addr_type; + /// Peer BT address + bd_addr_t peer_addr; +}; + + +/// Set specific link data configuration. +struct gapc_connection_cfm +{ + /// Local CSRK value + struct gap_sec_key lcsrk; + /// Local signature counter value + uint32_t lsign_counter; + + /// Remote CSRK value + struct gap_sec_key rcsrk; + /// Remote signature counter value + uint32_t rsign_counter; + + /// Authentication (@see gap_auth) + uint8_t auth; + /// Service Changed Indication enabled + uint8_t svc_changed_ind_enable; + /// LTK exchanged during pairing. + bool ltk_present; +}; + + +/// Request disconnection of current link command. +struct gapc_disconnect_cmd +{ + /// GAP request type: + /// - GAPC_DISCONNECT: Disconnect link. + uint8_t operation; + + /// Reason of disconnection + uint8_t reason; +}; + + +/// Indicate that a link has been disconnected +struct gapc_disconnect_ind +{ + /// Connection handle + uint16_t conhdl; + /// Reason of disconnection + uint8_t reason; +}; + + +/// Retrieve information command +struct gapc_get_info_cmd +{ + /// GAP request type: + /// - GAPC_GET_PEER_NAME: Retrieve name of peer device. + /// - GAPC_GET_PEER_VERSION: Retrieve peer device version info. + /// - GAPC_GET_PEER_FEATURES: Retrieve peer device features. + /// - GAPC_GET_CON_RSSI: Retrieve connection RSSI. + /// - GAPC_GET_CON_CHANNEL_MAP: Retrieve Connection Channel MAP. + /// - GAPC_GET_PEER_APPEARANCE: Get Peer device appearance + /// - GAPC_GET_PEER_SLV_PREF_PARAMS: Get Peer device Slaved Preferred Parameters + /// - GAPC_GET_ADDR_RESOL_SUPP: Address Resolution Supported + /// - GAPC_GET_LE_PING_TIMEOUT: Retrieve LE Ping Timeout Value + uint8_t operation; +}; + +/// device information data +union gapc_dev_info_val +{ + /// Device name + struct gap_dev_name name; + /// Appearance Icon + uint16_t appearance; + /// Slave preferred parameters + struct gap_slv_pref slv_params; + /// Central address resolution + uint8_t cnt_addr_resol; +}; + +/// Peer device attribute DB info such as Device Name, Appearance or Slave Preferred Parameters +struct gapc_peer_att_info_ind +{ + /// Requested information + /// - GAPC_DEV_NAME: Device Name + /// - GAPC_DEV_APPEARANCE: Device Appearance Icon + /// - GAPC_DEV_SLV_PREF_PARAMS: Device Slave preferred parameters + /// - GAPC_GET_ADDR_RESOL_SUPP: Address resolution supported + uint8_t req; + /// Attribute handle + uint16_t handle; + + /// device information data + union gapc_dev_info_val info; +}; + +/// Indication of peer version info +struct gapc_peer_version_ind +{ + /// Manufacturer name + uint16_t compid; + /// LMP subversion + uint16_t lmp_subvers; + /// LMP version + uint8_t lmp_vers; +}; + +/// Indication of peer features info +struct gapc_peer_features_ind +{ + /// 8-byte array for LE features + uint8_t features[GAP_LE_FEATS_LEN]; +}; + +/// Indication of ongoing connection RSSI +struct gapc_con_rssi_ind +{ + /// RSSI value + uint8_t rssi; +}; +/// Indication of ongoing connection Channel Map +struct gapc_con_channel_map_ind +{ + /// channel map value + le_chnl_map_t ch_map; +}; + +/// Sign counter value changed due to packet signing or signature verification. +struct gapc_sign_counter_updated_ind +{ + /// New Local signature counter value + uint32_t lsign_counter; + /// New Remote signature counter value + uint32_t rsign_counter; +}; + +/// Indication of LE Ping +struct gapc_le_ping_to_val_ind +{ + ///Authenticated payload timeout + uint16_t timeout; +}; + + +/// Peer device request local device info such as name, appearance or slave preferred parameters +struct gapc_get_dev_info_req_ind +{ + /// Requested information + /// - GAPC_DEV_NAME: Device Name + /// - GAPC_DEV_APPEARANCE: Device Appearance Icon + /// - GAPC_DEV_SLV_PREF_PARAMS: Device Slave preferred parameters + uint8_t req; +}; + + + +/// Send requested info to peer device +struct gapc_get_dev_info_cfm +{ + /// Requested information + /// - GAPC_DEV_NAME: Device Name + /// - GAPC_DEV_APPEARANCE: Device Appearance Icon + /// - GAPC_DEV_SLV_PREF_PARAMS: Device Slave preferred parameters + uint8_t req; + + /// Peer device information data + union gapc_dev_info_val info; +}; + +/// Peer device request to modify local device info such as name or appearance +struct gapc_set_dev_info_req_ind +{ + /// Requested information + /// - GAPC_DEV_NAME: Device Name + /// - GAPC_DEV_APPEARANCE: Device Appearance Icon + uint8_t req; + + /// device information data + union gapc_set_dev_info + { + /// Device name + struct gap_dev_name name; + /// Appearance Icon + uint16_t appearance; + } info; +}; + +/// Local device accept or reject device info modification +struct gapc_set_dev_info_cfm +{ + /// Requested information + /// - GAPC_DEV_NAME: Device Name + /// - GAPC_DEV_APPEARANCE: Device Appearance Icon + uint8_t req; + + /// Status code used to know if requested has been accepted or not + uint8_t status; +}; + +/// Connection Parameter used to update connection parameters +struct gapc_conn_param +{ + /// Connection interval minimum + uint16_t intv_min; + /// Connection interval maximum + uint16_t intv_max; + /// Latency + uint16_t latency; + /// Supervision timeout + uint16_t time_out; +}; + +/// Perform update of connection parameters command +struct gapc_param_update_cmd +{ + /// GAP request type: + /// - GAPC_UPDATE_PARAMS: Perform update of connection parameters. + uint8_t operation; + /// Internal parameter used to manage internally l2cap packet identifier for signaling + uint8_t pkt_id; + /// Connection interval minimum + uint16_t intv_min; + /// Connection interval maximum + uint16_t intv_max; + /// Latency + uint16_t latency; + /// Supervision timeout + uint16_t time_out; + /// Minimum Connection Event Duration + uint16_t ce_len_min; + /// Maximum Connection Event Duration + uint16_t ce_len_max; +}; + +/// Request of updating connection parameters indication +struct gapc_param_update_req_ind +{ + /// Connection interval minimum + uint16_t intv_min; + /// Connection interval maximum + uint16_t intv_max; + /// Latency + uint16_t latency; + /// Supervision timeout + uint16_t time_out; +}; + +/// Connection parameters updated indication +struct gapc_param_updated_ind +{ + ///Connection interval value + uint16_t con_interval; + ///Connection latency value + uint16_t con_latency; + ///Supervision timeout + uint16_t sup_to; +}; + +/// Master confirm or not that parameters proposed by slave are accepted or not +struct gapc_param_update_cfm +{ + /// True to accept slave connection parameters, False else. + bool accept; + /// Minimum Connection Event Duration + uint16_t ce_len_min; + /// Maximum Connection Event Duration + uint16_t ce_len_max; +}; + +/// Pairing parameters +struct gapc_pairing +{ + /// IO capabilities (@see gap_io_cap) + uint8_t iocap; + /// OOB information (@see gap_oob) + uint8_t oob; + /// Authentication (@see gap_auth) + /// Note in BT 4.1 the Auth Field is extended to include 'Key Notification' and + /// and 'Secure Connections'. + uint8_t auth; + /// Encryption key size (7 to 16) + uint8_t key_size; + ///Initiator key distribution (@see gap_kdist) + uint8_t ikey_dist; + ///Responder key distribution (@see gap_kdist) + uint8_t rkey_dist; + + /// Device security requirements (minimum security level). (@see gap_sec_req) + uint8_t sec_req; +}; + +/// Long Term Key information +struct gapc_ltk +{ + /// Long Term Key + struct gap_sec_key ltk; + /// Encryption Diversifier + uint16_t ediv; + /// Random Number + rand_nb_t randnb; + /// Encryption key size (7 to 16) + uint8_t key_size; + + uint8_t isLocal; +}; +/// Out of Band Information +struct gapc_oob +{ + /// Confirm Value + uint8_t conf[GAP_KEY_LEN]; + /// Random Number + uint8_t rand[GAP_KEY_LEN]; +}; + +struct gapc_nc +{ + uint8_t value[4]; +}; + +/// Identity Resolving Key information +struct gapc_irk +{ + /// Identity Resolving Key + struct gap_sec_key irk; + /// Device BD Identity Address + struct gap_bdaddr addr; +}; + + +/// Start Bonding command procedure +struct gapc_bond_cmd +{ + /// GAP request type: + /// - GAPC_BOND: Start bonding procedure. + uint8_t operation; + /// Pairing information + struct gapc_pairing pairing; +}; + +/// Bonding requested by peer device indication message. +struct gapc_bond_req_ind +{ + /// Bond request type (@see gapc_bond) + uint8_t request; + + /// Bond procedure requested information data + union gapc_bond_req_data + { + /// Authentication level (@see gap_auth) (if request = GAPC_PAIRING_REQ) + uint8_t auth_req; + /// LTK Key Size (if request = GAPC_LTK_EXCH) + uint8_t key_size; + /// Device IO used to get TK: (if request = GAPC_TK_EXCH) + /// - GAP_TK_OOB: TK get from out of band method + /// - GAP_TK_DISPLAY: TK generated and shall be displayed by local device + /// - GAP_TK_KEY_ENTRY: TK shall be entered by user using device keyboard + uint8_t tk_type; + + /// Addition OOB Data for the OOB Conf and Rand values + struct gapc_oob oob_data; + /// Numeric Comparison Data + struct gapc_nc nc_data; + } data; +}; + +/// Confirm requested bond information. +struct gapc_bond_cfm +{ + /// Bond request type (@see gapc_bond) + uint8_t request; + /// Request accepted + uint8_t accept; + + /// Bond procedure information data + union gapc_bond_cfm_data + { + /// Pairing Features (request = GAPC_PAIRING_RSP) + struct gapc_pairing pairing_feat; + /// LTK (request = GAPC_LTK_EXCH) + struct gapc_ltk ltk; + /// CSRK (request = GAPC_CSRK_EXCH) + struct gap_sec_key csrk; + /// TK (request = GAPC_TK_EXCH) + struct gap_sec_key tk; + /// IRK (request = GAPC_IRK_EXCH) + struct gapc_irk irk; + /// OOB Confirm and Random from the peer (request = GAPC_OOB_EXCH) + struct gapc_oob oob; + } data; +}; + +/** + * Authentication information + */ +struct gapc_bond_auth +{ + /// Authentication information (@see gap_auth) + uint8_t info; + + /// LTK exchanged during pairing. + bool ltk_present; +}; + + + +/// Bonding information indication message +struct gapc_bond_ind +{ + /// Bond information type (@see gapc_bond) + uint8_t info; + + /// Bond procedure information data + union gapc_bond_data + { + /// Authentication information (@see gap_auth) + /// (if info = GAPC_PAIRING_SUCCEED) + struct gapc_bond_auth auth; + /// Pairing failed reason (if info = GAPC_PAIRING_FAILED) + uint8_t reason; + /// Long Term Key information (if info = GAPC_LTK_EXCH) + struct gapc_ltk ltk; + /// Identity Resolving Key information (if info = GAPC_IRK_EXCH) + struct gapc_irk irk; + /// Connection Signature Resolving Key information (if info = GAPC_CSRK_EXCH) + struct gap_sec_key csrk; + } data; +}; + +/// Start Encryption command procedure +struct gapc_encrypt_cmd +{ + /// GAP request type: + /// - GAPC_ENCRYPT: Start encryption procedure. + uint8_t operation; + /// Long Term Key information + struct gapc_ltk ltk; +}; + +/// Encryption requested by peer device indication message. +struct gapc_encrypt_req_ind +{ + /// Encryption Diversifier + uint16_t ediv; + /// Random Number + rand_nb_t rand_nb; +}; + +/// Confirm requested Encryption information. +struct gapc_encrypt_cfm +{ + /// Indicate if a LTK has been found for the peer device + uint8_t found; + /// Long Term Key + struct gap_sec_key ltk; + /// LTK Key Size + uint8_t key_size; +}; + +/// Encryption information indication message +struct gapc_encrypt_ind +{ + /// Authentication level (@see gap_auth) + uint8_t auth; +}; + +/// Start Security Request command procedure +struct gapc_security_cmd +{ + /// GAP request type: + /// - GAPC_SECURITY_REQ: Start security request procedure + uint8_t operation; + /// Authentication level (@see gap_auth) + uint8_t auth; +}; +/// Security requested by peer device indication message +struct gapc_security_ind +{ + /// Authentication level (@see gap_auth) + uint8_t auth; +}; + +/// Parameters of the @ref GAPC_SIGN_COUNTER_IND message +struct gapc_sign_counter_ind +{ + /// Local SignCounter value + uint32_t local_sign_counter; + /// Peer SignCounter value + uint32_t peer_sign_counter; +}; + + +/// Parameters of the @ref GAPC_SET_LE_PING_TO_CMD message +struct gapc_set_le_ping_to_cmd +{ + /// GAP request type: + /// - GAPC_SET_LE_PING_TO : Set the LE Ping timeout value + uint8_t operation; + /// Authenticated payload timeout + uint16_t timeout; +}; + +/// Parameters of the @ref GAPC_SET_LE_PKT_SIZE_CMD message +struct gapc_set_le_pkt_size_cmd +{ + /// GAP request type: + /// - GAPC_SET_LE_PKT_SIZE : Set the LE Data length value + uint8_t operation; + ///Preferred maximum number of payload octets that the local Controller should include + ///in a single Link Layer Data Channel PDU. + uint16_t tx_octets; + ///Preferred maximum number of microseconds that the local Controller should use to transmit + ///a single Link Layer Data Channel PDU + uint16_t tx_time; +}; + +/// Parameters of the @ref GAPC_LE_PKT_SIZE_IND message +struct gapc_le_pkt_size_ind +{ + ///The maximum number of payload octets in TX + uint16_t max_tx_octets; + ///The maximum time that the local Controller will take to TX + uint16_t max_tx_time; + ///The maximum number of payload octets in RX + uint16_t max_rx_octets; + ///The maximum time that the local Controller will take to RX + uint16_t max_rx_time; +}; + +/// Parameters of the @ref GAPC_KEY_PRESS_NOTIFICATION_CMD message +struct gapc_key_press_notif_cmd +{ + /// GAP request type: + /// - GAPC_KEY_PRESS_NOTIFICATION_CMD : Inform the remote device when keys have been entered or erased + uint8_t operation; + /// notification type + uint8_t notification_type; +}; + +/// Parameters of the @ref GAPC_KEY_PRESS_NOTIFICATION_IND message +struct gapc_key_press_notif_ind +{ + /// notification type + uint8_t notification_type; +}; + +/// Set the PHY configuration for current active link +struct gapc_set_phy_cmd +{ + /// GAP request type: + /// - GAPC_SET_PHY : Set the PHY configuration for current active link + uint8_t operation; + /// Supported LE PHY rates for data transmission (@see enum gap_rate) + uint8_t tx_rates; + /// Supported LE PHY rates for data reception (@see enum gap_rate) + uint8_t rx_rates; +}; + +/// Active link PHY configuration. Triggered when configuration is read or during an update. +struct gapc_le_phy_ind +{ + /// LE PHY rate for data transmission (@see enum gap_rate) + uint8_t tx_rate; + /// LE PHY rate for data reception (@see enum gap_rate) + uint8_t rx_rate; +}; + +/// Parameters of the @ref GAPC_SIGN_CMD message +struct gapc_sign_cmd +{ + /// GAP request type: + /// - GAPC_SIGN_PACKET: Sign an attribute packet + /// - GAPC_SIGN_CHECK: Verify signature or an attribute packet + uint8_t operation; + /// Data PDU length (Bytes) + uint16_t byte_len; + /// Data PDU + SignCounter if generation, Data PDU + SignCounter + MAC if verification + uint8_t msg[__ARRAY_EMPTY]; +}; + +/// Parameters of the @ref GAPC_SIGN_IND message +struct gapc_sign_ind +{ + /// GAP request type: + /// - GAPC_SIGN_PACKET: Sign an attribute packet + /// - GAPC_SIGN_CHECK: Verify signature or an attribute packet + uint8_t operation; + /// Data PDU length (Bytes) + uint16_t byte_len; + /// Data PDU + SignCounter + MAC + uint8_t signed_msg[__ARRAY_EMPTY]; +}; + + +/// @} GAPC_TASK + +#endif /* _GAPC_TASK_H_ */ diff --git a/services/ble_stack/hl/api/gapm_task.h b/services/ble_stack/hl/api/gapm_task.h new file mode 100644 index 0000000..d083faf --- /dev/null +++ b/services/ble_stack/hl/api/gapm_task.h @@ -0,0 +1,1441 @@ +#ifndef _GAPM_TASK_H_ +#define _GAPM_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup GAPM_TASK Generic Access Profile Manager Task + * @ingroup GAPM + * @brief Handles ALL messages to/from GAP Manager block. + * + * It handles messages from lower and higher layers not related to an ongoing connection. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_task.h" // Task definitions +#include "gap.h" + + +/* + * DEFINES + **************************************************************************************** + */ + +/// Offset for List Management Operation Codes +#define GAPM_OP_OFFSET_LIST_MGMT (0x90) +/// Offset for Extended Air Operation Codes +#define GAPM_OP_OFFSET_EXT_AIR (0xA0) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/// GAP Manager Message Interface +enum gapm_msg_id +{ + /* Default event */ + /// Command Complete event + GAPM_CMP_EVT = TASK_FIRST_MSG(TASK_ID_GAPM), + /// Event triggered to inform that lower layers are ready + GAPM_DEVICE_READY_IND, + + /* Default commands */ + /// Reset link layer and the host command + GAPM_RESET_CMD, + /// Cancel ongoing operation - DEPRECATED + GAPM_CANCEL_CMD, + + /* Device Configuration */ + /// Set device configuration command + GAPM_SET_DEV_CONFIG_CMD, + /// Set device channel map + GAPM_SET_CHANNEL_MAP_CMD, + + /* Local device information */ + /// Get local device info command + GAPM_GET_DEV_INFO_CMD, + /// Local device version indication event + GAPM_DEV_VERSION_IND, + /// Local device BD Address indication event + GAPM_DEV_BDADDR_IND, + /// Advertising channel Tx power level + GAPM_DEV_ADV_TX_POWER_IND, + /// Indication containing information about memory usage. + GAPM_DBG_MEM_INFO_IND, + + /* White List */ + /// White List Management Command - DEPRECATED + GAPM_WHITE_LIST_MGT_CMD, + /// White List Size indication event - DEPRECATED + GAPM_WHITE_LIST_SIZE_IND, + + /* Air Operations */ + /// Set advertising mode Command - DEPRECATED + GAPM_START_ADVERTISE_CMD, + /// Update Advertising Data Command - On fly update when device is advertising - DEPRECATED, 41 + GAPM_UPDATE_ADVERTISE_DATA_CMD, + + /// Set Scan mode Command - DEPRECATED + GAPM_START_SCAN_CMD, + /// Advertising or scanning report information event - DEPRECATED + GAPM_ADV_REPORT_IND, + + /// Set connection initialization Command - DEPRECATED + GAPM_START_CONNECTION_CMD, + /// Name of peer device indication + GAPM_PEER_NAME_IND, + /// Confirm connection to a specific device (Connection Operation in Selective mode) - DEPRECATED + GAPM_CONNECTION_CFM, + + /* Security / Encryption Toolbox */ + /// Resolve address command + GAPM_RESOLV_ADDR_CMD, + /// Indicate that resolvable random address has been solved + GAPM_ADDR_SOLVED_IND, + /// Generate a random address. + GAPM_GEN_RAND_ADDR_CMD, + /// Use the AES-128 block in the controller + GAPM_USE_ENC_BLOCK_CMD, + /// AES-128 block result indication + GAPM_USE_ENC_BLOCK_IND, + /// Generate a 8-byte random number + GAPM_GEN_RAND_NB_CMD, + /// Random Number Indication + GAPM_GEN_RAND_NB_IND, + + /* Profile Management */ + /// Create new task for specific profile, 3355 + GAPM_PROFILE_TASK_ADD_CMD, + /// Inform that profile task has been added. + GAPM_PROFILE_ADDED_IND, + + /// Indicate that a message has been received on an unknown task + GAPM_UNKNOWN_TASK_IND, + + /* Data Length Extension */ + /// Suggested Default Data Length indication + GAPM_SUGG_DFLT_DATA_LEN_IND, + /// Maximum Data Length indication + GAPM_MAX_DATA_LEN_IND, + + /* Resolving list for controller-based privacy*/ + /// Resolving address list management - DEPRECATED + GAPM_RAL_MGT_CMD, + /// Resolving address list size indication - DEPRECATED + GAPM_RAL_SIZE_IND, + /// Resolving address list address indication + GAPM_RAL_ADDR_IND, + + /* Set new IRK */ + /// Modify current IRK + GAPM_SET_IRK_CMD, + + /* LE Protocol/Service Multiplexer Management */ + /// Register a LE Protocol/Service Multiplexer command + GAPM_LEPSM_REGISTER_CMD, + /// Unregister a LE Protocol/Service Multiplexer command + GAPM_LEPSM_UNREGISTER_CMD, + + /* ************************************************ */ + /* ------------ NEW COMMANDS FOR BLE 5 ------------ */ + /* ************************************************ */ + + /* List Management Operations */ + /// Get local or peer address + /// @see struct gapm_get_ral_addr_cmd + GAPM_GET_RAL_ADDR_CMD = TASK_FIRST_MSG(TASK_ID_GAPM) + GAPM_OP_OFFSET_LIST_MGMT, + /// Set content of either white list or resolving list or periodic advertiser list + /// @see struct gapm_list_set_wl_cmd + /// @see struct gapm_list_set_ral_cmd + /// @see struct gapm_list_set_pal_cmd + GAPM_LIST_SET_CMD, + /// Indicate size of list indicated in GAPM_GET_DEV_CONFIG_CMD message + /// @see struct gapm_list_size_ind + GAPM_LIST_SIZE_IND, + + /* Extended Air Operations */ + /// Create an advertising, a scanning, an initiating or a periodic synchronization activity + /// @see struct gapm_activity_create_cmd + /// @see struct gapm_activity_create_adv_cmd + GAPM_ACTIVITY_CREATE_CMD = TASK_FIRST_MSG(TASK_ID_GAPM) + GAPM_OP_OFFSET_EXT_AIR, + /// Start a previously created activity + /// @see struct gapm_activity_start_cmd + GAPM_ACTIVITY_START_CMD, + /// Stop either a given activity or all existing activities + /// @see struct gapm_activity_stop_cmd + GAPM_ACTIVITY_STOP_CMD, + /// Delete either a given activity or all existing activities + /// @see struct gapm_activity_delete_cmd + GAPM_ACTIVITY_DELETE_CMD, + /// Indicate that an activity has well been created + /// @see struct gapm_activity_create_ind + GAPM_ACTIVITY_CREATED_IND, + /// Indicate that an activity has been stopped and can be restarted + /// @see struct gapm_activity_stopped_ind + GAPM_ACTIVITY_STOPPED_IND, + /// Set either advertising data or scan response data or periodic advertising data + /// @see struct gapm_set_adv_data_cmd + GAPM_SET_ADV_DATA_CMD, + /// Indicate reception of an advertising report (periodic or not), a scan response report + /// @see struct gapm_ext_adv_report_ind + GAPM_EXT_ADV_REPORT_IND, + /// Indicate reception of a scan request + /// @see struct gapm_scan_request_ind + GAPM_SCAN_REQUEST_IND, + /// Indicate that synchronization has been successfully established with a periodic advertiser + /// @see struct gapm_sync_established_ind + GAPM_SYNC_ESTABLISHED_IND, + /// Indicate maximum advertising data length supported by controller + /// @see struct gapm_max_adv_data_len_ind + GAPM_MAX_ADV_DATA_LEN_IND, + /// Indicate number of available advertising sets + /// @see struct gapm_nb_adv_sets_ind + GAPM_NB_ADV_SETS_IND, + + /* ************************************************ */ + /* -------------- Internal usage only ------------- */ + /* ************************************************ */ + /// Message received to unknown task received + GAPM_UNKNOWN_TASK_MSG, + + /* Secure Connections */ + /// Request to provide DH Key + GAPM_GEN_DH_KEY_CMD, + /// if the controller do not supp DHK GEN we make it on host.. + GAPM_GEN_DH_KEY_ON_HOST_CMD, + /// Indicates the DH Key computation is complete and available + GAPM_GEN_DH_KEY_IND, + + /* Internal messages for timer events, not part of API*/ + /// Limited discoverable timeout indication - DEPRECATED + GAPM_LIM_DISC_TO_IND, + /// Scan timeout indication - DEPRECATED + GAPM_SCAN_TO_IND, + /// Address renewal timeout indication + GAPM_ADDR_RENEW_TO_IND, + /// Automatic connection establishment timeout indication + GAPM_AUTO_CONN_TO_IND, + /// Renew random private addresses + /// @see struct gapm_actv_addr_renew_cmd + GAPM_ACTV_ADDR_RENEW_CMD, +}; + + +/// GAP Manager operation type - application interface +enum gapm_operation +{ + /* No Operation (if nothing has been requested) */ + /* ************************************************ */ + /// No operation. + GAPM_NO_OP = 0x00, + + /* Default operations */ + /* ************************************************ */ + /// Reset BLE subsystem: LL and HL. + GAPM_RESET, + /// Cancel currently executed operation. - DEPRECATED + GAPM_CANCEL, + + /* Configuration operations */ + /* ************************************************ */ + /// Set device configuration + GAPM_SET_DEV_CONFIG, + /// Set device channel map + GAPM_SET_CHANNEL_MAP, + + /* Retrieve device information */ + /* ************************************************ */ + /// Get Local device version + GAPM_GET_DEV_VERSION, + /// Get Local device BD Address + GAPM_GET_DEV_BDADDR, + /// Get device advertising power level, 7 + GAPM_GET_DEV_ADV_TX_POWER, + + /* Operation on White list */ + /* ************************************************ */ + /// Get White List Size. + GAPM_GET_WLIST_SIZE, + /// Add devices in white list. - DEPRECATED + GAPM_ADD_DEV_IN_WLIST, + /// Remove devices form white list. - DEPRECATED + GAPM_RMV_DEV_FRM_WLIST, + /// Clear all devices from white list. - DEPRECATED + GAPM_CLEAR_WLIST, + + /* Advertise mode operations */ + /* ************************************************ */ + /// Start non connectable advertising - DEPRECATED + GAPM_ADV_NON_CONN, + /// Start undirected connectable advertising - DEPRECATED 13 + GAPM_ADV_UNDIRECT, + /// Start directed connectable advertising - DEPRECATED + GAPM_ADV_DIRECT, + /// Start directed connectable advertising using Low Duty Cycle - DEPRECATED + GAPM_ADV_DIRECT_LDC, + /// Update on the fly advertising data - DEPRECATED + GAPM_UPDATE_ADVERTISE_DATA, + + /* Scan mode operations */ + /* ************************************************ */ + /// Start active scan operation - DEPRECATED + GAPM_SCAN_ACTIVE, + /// Start passive scan operation - DEPRECATED + GAPM_SCAN_PASSIVE, + + /* Connection mode operations */ + /* ************************************************ */ + /// Direct connection operation - DEPRECATED + GAPM_CONNECTION_DIRECT, + /// Automatic connection operation - DEPRECATED + GAPM_CONNECTION_AUTO, + /// Selective connection operation - DEPRECATED + GAPM_CONNECTION_SELECTIVE, + /// Name Request operation (requires to start a direct connection) - DEPRECATED + GAPM_CONNECTION_NAME_REQUEST, + + /* Security / Encryption Toolbox */ + /* ************************************************ */ + /// Resolve device address + GAPM_RESOLV_ADDR, + /// Generate a random address + GAPM_GEN_RAND_ADDR, + /// Use the controller's AES-128 block + GAPM_USE_ENC_BLOCK, + /// Generate a 8-byte random number + GAPM_GEN_RAND_NB, + + /* Profile Management */ + /* ************************************************ */ + /// Create new task for specific profile , 27 + GAPM_PROFILE_TASK_ADD, + + /* DEBUG */ + /* ************************************************ */ + /// Get memory usage + GAPM_DBG_GET_MEM_INFO, + /// Perform a platform reset + GAPM_PLF_RESET, + + /* Data Length Extension */ + /* ************************************************ */ + /// Set Suggested Default LE Data Length + GAPM_SET_SUGGESTED_DFLT_LE_DATA_LEN, + /// Get Suggested Default LE Data Length + GAPM_GET_SUGGESTED_DFLT_LE_DATA_LEN, + /// Get Maximum LE Data Length + GAPM_GET_MAX_LE_DATA_LEN, + + /* Operation on Resolving List */ + /* ************************************************ */ + /// Get resolving address list size + GAPM_GET_RAL_SIZE, + /// Get resolving local address + GAPM_GET_RAL_LOC_ADDR, + /// Get resolving peer address + GAPM_GET_RAL_PEER_ADDR, + /// Add device in resolving address list - DEPRECATED + GAPM_ADD_DEV_IN_RAL, + /// Remove device from resolving address list - DEPRECATED + GAPM_RMV_DEV_FRM_RAL, + /// Clear resolving address list - DEPRECATED + GAPM_CLEAR_RAL, + + /* Connection mode operations - cont */ + /* ************************************************ */ + /// General connection operation - DEPRECATED + GAPM_CONNECTION_GENERAL, + + /* Change current IRK */ + /* ************************************************ */ + /// Set IRK + GAPM_SET_IRK, + + /* LE Protocol/Service Multiplexer management */ + /* ************************************************ */ + /// Register a LE Protocol/Service Multiplexer + GAPM_LEPSM_REG, + /// Unregister a LE Protocol/Service Multiplexer + GAPM_LEPSM_UNREG, + + /* Secure Connection - Internal API */ + /* ************************************************ */ + /// Generate DH_Key + GAPM_GEN_DH_KEY, + + /* List Management */ + /* ************************************************ */ + /// Set content of white list + GAPM_SET_WLIST = GAPM_NO_OP + GAPM_OP_OFFSET_LIST_MGMT, + /// Set content of resolving list + GAPM_SET_RAL, + /// Set content of periodic advertiser list + GAPM_SET_PAL, + /// Get white list size + //GAPM_GET_WHITE_LIST_SIZE, + /// Get resolving list size + //GAPM_GET_RAL_SIZE, + /// Get periodic advertiser list size + GAPM_GET_PAL_SIZE = GAPM_SET_PAL + 3, + + /* Extended Air Operations */ + /* ************************************************ */ + /// Create advertising activity + GAPM_CREATE_ADV_ACTIVITY = GAPM_NO_OP + GAPM_OP_OFFSET_EXT_AIR, + /// Create scanning activity + GAPM_CREATE_SCAN_ACTIVITY, + /// Create initiating activity + GAPM_CREATE_INIT_ACTIVITY, + /// Create periodic synchronization activity + GAPM_CREATE_PERIOD_SYNC_ACTIVITY, + /// Start an activity + GAPM_START_ACTIVITY, + /// Stop an activity + GAPM_STOP_ACTIVITY, + /// Stop all activities + GAPM_STOP_ALL_ACTIVITIES, + /// Delete an activity + GAPM_DELETE_ACTIVITY, + /// Delete all activities + GAPM_DELETE_ALL_ACTIVITIES, + /// Set advertising data + GAPM_SET_ADV_DATA, + /// Set scan response data + GAPM_SET_SCAN_RSP_DATA, + /// Set periodic advertising data + GAPM_SET_PERIOD_ADV_DATA, + /// Get number of available advertising sets + GAPM_GET_NB_ADV_SETS, + /// Get maximum advertising data length supported by the controller + GAPM_GET_MAX_LE_ADV_DATA_LEN, + /// INTERNAL OPERATION - Renew random addresses + GAPM_RENEW_ADDR, +}; + +/// Device Address type Configuration +enum gapm_addr_type +{ + /// Device Address is a Public Static address + GAPM_CFG_ADDR_PUBLIC = 0, + /// Device Address is a Private Static address + GAPM_CFG_ADDR_PRIVATE = 1, + /// Device Address generated using host-based Privacy feature - DEPRECATED + GAPM_CFG_ADDR_HOST_PRIVACY = 2, + /// Device Address generated using controller-based Privacy feature + GAPM_CFG_ADDR_CTNL_PRIVACY = 4, +}; + +/// Own BD address source of the device +enum gapm_own_addr +{ + /// Public or Private Static Address according to device address configuration + GAPM_STATIC_ADDR, + /// Generated resolvable private random address + GAPM_GEN_RSLV_ADDR, + /// Generated non-resolvable private random address + GAPM_GEN_NON_RSLV_ADDR, +}; + +/// Device Attribute write permission requirement +enum gapm_write_att_perm +{ + /// Disable write access + GAPM_WRITE_DISABLE = 0, + /// Enable write access - no authentication required + GAPM_WRITE_NO_AUTH = 1, + /// Write access requires unauthenticated link + GAPM_WRITE_UNAUTH = 2, + /// Write access requires authenticated link + GAPM_WRITE_AUTH = 3, + /// Write access requires secure connected link + GAPM_WRITE_SEC_CON = 4 +}; + +/// Attribute database configuration +/// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +/// +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ +/// | DBG | RFU | SC |PCP | APP_PERM | NAME_PERM | +/// +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ +/// - Bit [0-2] : Device Name write permission requirements for peer device (@see gapm_write_att_perm) +/// - Bit [3-5] : Device Appearance write permission requirements for peer device (@see gapm_write_att_perm) +/// - Bit [6] : Slave Preferred Connection Parameters present +/// - Bit [7] : Service change feature present in GATT attribute database. +/// - Bit [8-14]: Reserved +/// - Bit [15] : Enable Debug Mode +enum gapm_att_cfg_flag +{ + /// Device Name write permission requirements for peer device (@see gapm_write_att_perm) + GAPM_MASK_ATT_NAME_PERM = 0x0007, + GAPM_POS_ATT_NAME_PERM = 0x00, + /// Device Appearance write permission requirements for peer device (@see gapm_write_att_perm) + GAPM_MASK_ATT_APPEARENCE_PERM = 0x0038, + GAPM_POS_ATT_APPEARENCE_PERM = 0x03, + /// Slave Preferred Connection Parameters present in GAP attribute database. + GAPM_MASK_ATT_SLV_PREF_CON_PAR_EN = 0x0040, + GAPM_POS_ATT_SLV_PREF_CON_PAR_EN = 0x06, + /// Service change feature present in GATT attribute database. + GAPM_MASK_ATT_SVC_CHG_EN = 0x0080, + GAPM_POS_ATT_SVC_CHG_EN = 0x07, + /// Service change feature present in GATT attribute database. + GAPM_MASK_ATT_DBG_MODE_EN = 0x8000, + GAPM_POS_ATT_DBG_MODE_EN = 0x0F, +}; + +/// Pairing mode authorized on the device +/// 7 6 5 4 3 2 1 0 +/// +----+----+----+----+----+----+----+----+ +/// |KGEN| RFU | SCP| LP | +/// +----+----+----+----+----+----+----+----+ +enum gapm_pairing_mode +{ + /// No pairing authorized + GAPM_PAIRING_DISABLE = 0, + /// Legacy pairing Authorized + GAPM_PAIRING_LEGACY = (1 << 0), + /// Secure Connection pairing Authorized + GAPM_PAIRING_SEC_CON = (1 << 1), + + + /// Force re-generation of P256 private and public keys + GAPM_PAIRING_FORCE_P256_KEY_GEN = (1<<7), +}; + +/// LE Audio Mode Configuration +/// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +/// +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ +/// | RFU | AM0| +/// +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ +enum gapm_audio_cfg_flag +{ + /// LE Audio Mode 0 Supported + GAPM_MASK_AUDIO_AM0_SUP = 0x0001, + GAPM_POS_AUDIO_AM0_SUP = 0x00, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Operation command structure in order to keep requested operation. +struct gapm_operation_cmd +{ + /// GAP request type + uint8_t operation; +}; + +/// Command complete event data structure +struct gapm_cmp_evt +{ + /// GAP requested operation + uint8_t operation; + /// Status of the request + uint8_t status; +}; + +/// Reset link layer and the host command +struct gapm_reset_cmd +{ + /// GAPM requested operation: + /// - GAPM_RESET: Reset BLE subsystem: LL and HL. + uint8_t operation; +}; + +/// Set device configuration command +struct gapm_set_dev_config_cmd +{ + /// GAPM requested operation: + /// - GAPM_SET_DEV_CONFIG: Set device configuration + uint8_t operation; + /// Device Role: Central, Peripheral, Observer, Broadcaster or All roles. + uint8_t role; + + /// -------------- Privacy Config ----------------------- + /// Duration before regenerate device address when privacy is enabled. + uint16_t renew_dur; + /// Provided own static private random address + bd_addr_t addr; + /// Device IRK used for resolvable random BD address generation (LSB first) + struct gap_sec_key irk; + /// Privacy configuration bit field (@see enum gap_priv_cfg for bit signification) + uint8_t privacy_cfg; + + /// -------------- Security Config ----------------------- + + /// Pairing mode authorized (@see enum gapm_pairing_mode) + uint8_t pairing_mode; + + /// -------------- ATT Database Config ----------------------- + + /// GAP service start handle + uint16_t gap_start_hdl; + /// GATT service start handle + uint16_t gatt_start_hdl; + + /// Attribute database configuration + /// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + /// +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + /// | DBG | RFU | SC |PCP | APP_PERM | NAME_PERM | + /// +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + /// - Bit [0-2] : Device Name write permission requirements for peer device (@see gapm_write_att_perm) + /// - Bit [3-5] : Device Appearance write permission requirements for peer device (@see gapm_write_att_perm) + /// - Bit [6] : Slave Preferred Connection Parameters present + /// - Bit [7] : Service change feature present in GATT attribute database. + /// - Bit [8-14]: Reserved + /// - Bit [15] : Enable Debug Mode + uint16_t att_cfg; + + /// -------------- LE Data Length Extension ----------------------- + ///Suggested value for the Controller's maximum transmitted number of payload octets to be used + uint16_t sugg_max_tx_octets; + ///Suggested value for the Controller's maximum packet transmission time to be used + uint16_t sugg_max_tx_time; + + /// --------------- L2CAP Configuration --------------------------- + /// Maximal MTU acceptable for device + uint16_t max_mtu; + /// Maximal MPS Packet size acceptable for device + uint16_t max_mps; + /// Maximum number of LE Credit based connection that can be established + uint8_t max_nb_lecb; + + /// --------------------- Miscellaneous --------------------------- + /// API settings bit field (@see enum gap_api_settings for each bit meaning) + uint8_t api_settings; + + /// --------------- LE Audio Mode Supported ----------------------- + /// + /// LE Audio Mode Configuration (@see gapm_audio_cfg_flag) + uint16_t audio_cfg; + + /// ------------------ LE PHY Management ------------------------- + /// Preferred LE PHY rate for data transmission (@see enum gap_rate) + uint8_t tx_pref_rates; + /// Preferred LE PHY rate for data reception (@see enum gap_rate) + uint8_t rx_pref_rates; +}; + +/// Set new IRK +struct gapm_set_irk_cmd +{ + /// GAPM requested operation: + /// - GAPM_SET_IRK: Set device configuration + uint8_t operation; + /// Device IRK used for resolvable random BD address generation (LSB first) + struct gap_sec_key irk; +}; + +/// Set device channel map +struct gapm_set_channel_map_cmd +{ + /// GAPM requested operation: + /// - GAPM_SET_CHANNEL_MAP: Set device channel map. + uint8_t operation; + /// Channel map + le_chnl_map_t chmap; +}; + +/// Get local device info command +struct gapm_get_dev_info_cmd +{ + /// GAPM requested operation: + /// - GAPM_GET_DEV_VERSION: Get Local device version + /// - GAPM_GET_DEV_BDADDR: Get Local device BD Address + /// - GAPM_GET_DEV_ADV_TX_POWER: Get device advertising power level + /// - GAPM_DBG_GET_MEM_INFO: Get memory usage (debug only) + uint8_t operation; +}; + +/// Local device version indication event +struct gapm_dev_version_ind +{ + /// HCI version + uint8_t hci_ver; + /// LMP version + uint8_t lmp_ver; + /// Host version + uint8_t host_ver; + /// HCI revision + uint16_t hci_subver; + /// LMP subversion + uint16_t lmp_subver; + /// Host revision + uint16_t host_subver; + /// Manufacturer name + uint16_t manuf_name; +}; + +/// Local device BD Address indication event +struct gapm_dev_bdaddr_ind +{ + /// Local device address information + struct gap_bdaddr addr; +}; + +/// Advertising channel Tx power level indication event +struct gapm_dev_adv_tx_power_ind +{ + /// Advertising channel Tx power level + int8_t power_lvl; +}; + +/// Cancel ongoing operation - DEPRECATED +struct gapm_cancel_cmd +{ + /// GAPM requested operation + /// - GAPM_CANCEL: Cancel running operation + uint8_t operation; +}; + +/// White List Management Command - DEPRECATED +struct gapm_white_list_mgt_cmd +{ + /// GAPM requested operation: + /// - GAPM_GET_WLIST_SIZE: Get White List Size. + /// - GAPM_ADD_DEV_IN_WLIST: Add devices in white list. + /// - GAPM_RMV_DEV_FRM_WLIST: Remove devices form white list. + /// - GAPM_CLEAR_WLIST: Clear all devices from white list. + uint8_t operation; + /// Number of device information present in command + uint8_t nb; + /// Device address information that can be used to add or remove element in device list. + struct gap_bdaddr devices[__ARRAY_EMPTY]; +}; + +/// Resolving List Management Command - DEPRECATED +struct gapm_ral_mgt_cmd +{ + /// GAPM requested operation: + /// - GAPM_GET_RAL_SIZE: Get Resolving List Size. + /// - GAPM_GET_RAL_LOC_ADDR: Get Resolving Local Address. + /// - GAPM_GET_RAL_PEER_ADDR: Get Resolving Peer Address. + /// - GAPM_ADD_DEV_IN_RAL: Add devices in resolving list. + /// - GAPM_RMV_DEV_FRM_RAL: Remove devices form resolving list. + /// - GAPM_CLEAR_RAL: Clear all devices from resolving list. + uint8_t operation; + /// Number of device information present in command + uint8_t nb; + /// Device address information that can be used to add or remove element in device list. + struct gap_ral_dev_info devices[__ARRAY_EMPTY]; +}; + +/// Resolving Address indication event +struct gapm_ral_addr_ind +{ + /// Peer or local read operation + uint8_t operation; + /// Resolving List address + struct gap_bdaddr addr; +}; + +/// Resolve Address command +struct gapm_resolv_addr_cmd +{ + /// GAPM requested operation: + /// - GAPM_RESOLV_ADDR: Resolve device address + uint8_t operation; + /// Number of provided IRK (sahlle be > 0) + uint8_t nb_key; + /// Resolvable random address to solve + bd_addr_t addr; + /// Array of IRK used for address resolution (MSB -> LSB) + struct gap_sec_key irk[__ARRAY_EMPTY]; +}; + +/// Indicate that resolvable random address has been solved +struct gapm_addr_solved_ind +{ + /// Resolvable random address solved + bd_addr_t addr; + /// IRK that correctly solved the random address + struct gap_sec_key irk; +}; + +/// Advertising data that contains information set by host. - DEPRECATED +struct gapm_adv_host +{ + /// Advertising mode : + /// - GAP_NON_DISCOVERABLE: Non discoverable mode + /// - GAP_GEN_DISCOVERABLE: General discoverable mode + /// - GAP_LIM_DISCOVERABLE: Limited discoverable mode + /// - GAP_BROADCASTER_MODE: Broadcaster mode + uint8_t mode; + + /// Advertising filter policy: + /// - ADV_ALLOW_SCAN_ANY_CON_ANY: Allow both scan and connection requests from anyone + /// - ADV_ALLOW_SCAN_WLST_CON_ANY: Allow both scan req from White List devices only and + /// connection req from anyone + /// - ADV_ALLOW_SCAN_ANY_CON_WLST: Allow both scan req from anyone and connection req + /// from White List devices only + /// - ADV_ALLOW_SCAN_WLST_CON_WLST: Allow scan and connection requests from White List + /// devices only + uint8_t adv_filt_policy; + + /// Advertising data length - maximum 28 bytes, 3 bytes are reserved to set + /// Advertising AD type flags, shall not be set in advertising data + uint8_t adv_data_len; + /// Advertising data + uint8_t adv_data[GAP_ADV_DATA_LEN]; + /// Scan response data length- maximum 31 bytes + uint8_t scan_rsp_data_len; + /// Scan response data + uint8_t scan_rsp_data[GAP_SCAN_RSP_DATA_LEN]; + /// Peer address + struct gap_bdaddr peer_addr; + + uint8_t flags; +}; + +/// Air operation default parameters - DEPRECATED +struct gapm_air_operation +{ + /// Operation code. + uint8_t code; + + /** + * Own BD address source of the device: + * - GAPM_STATIC_ADDR: Public or Private Static Address according to device address configuration + * - GAPM_GEN_RSLV_ADDR: Generated resolvable private random address + * - GAPM_GEN_NON_RSLV_ADDR: Generated non-resolvable private random address + */ + uint8_t addr_src; + + /// Dummy data use to retrieve internal operation state (should be set to 0). + uint16_t state; + + uint16_t randomAddrRenewIntervalInSecond; +}; + +/// Set advertising mode Command - DEPRECATED +struct gapm_start_advertise_cmd +{ + /// GAPM requested operation: + /// - GAPM_ADV_NON_CONN: Start non connectable advertising + /// - GAPM_ADV_UNDIRECT: Start undirected connectable advertising + /// - GAPM_ADV_DIRECT: Start directed connectable advertising + /// - GAPM_ADV_DIRECT_LDC: Start directed connectable advertising using Low Duty Cycle + struct gapm_air_operation op; + + /// Minimum interval for advertising + uint16_t intv_min; + /// Maximum interval for advertising + uint16_t intv_max; + + ///Advertising channel map + uint8_t channel_map; + //true:force reserve 3 byte for ourself;false:all 31 byte can use by customer,default open this flag,reserve 3byte + uint8_t isIncludedFlags; + + /// Advertising information + union gapm_adv_info + { + /// Host information advertising data (GAPM_ADV_NON_CONN and GAPM_ADV_UNDIRECT) + struct gapm_adv_host host; + /// Direct address information (GAPM_ADV_DIRECT) + /// (used only if reconnection address isn't set or privacy disabled) + struct gap_bdaddr direct; + } info; +}; + +/// Update Advertising Data Command - On fly update when device is advertising - DEPRECATED +struct gapm_update_advertise_data_cmd +{ + /// GAPM requested operation: + /// - GAPM_UPDATE_ADVERTISE_DATA: Update on the fly advertising data + uint8_t operation; + /// Advertising data length - maximum 28 bytes, 3 bytes are reserved to set + /// Advertising AD type flags, shall not be set in advertising data + uint8_t adv_data_len; + /// Advertising data + uint8_t adv_data[GAP_ADV_DATA_LEN]; + /// Scan response data length- maximum 31 bytes + uint8_t scan_rsp_data_len; + /// Scan response data + uint8_t scan_rsp_data[GAP_SCAN_RSP_DATA_LEN]; +}; + +/// Set scan mode Command - DEPRECATED +struct gapm_start_scan_cmd +{ + /// GAPM requested operation: + /// - GAPM_SCAN_ACTIVE: Start active scan operation + /// - GAPM_SCAN_PASSIVE: Start passive scan operation + struct gapm_air_operation op; + + /// Scan interval + uint16_t interval; + /// Scan window size + uint16_t window; + + /// Scanning mode : + /// - GAP_GEN_DISCOVERY: General discovery mode + /// - GAP_LIM_DISCOVERY: Limited discovery mode + /// - GAP_OBSERVER_MODE: Observer mode + uint8_t mode; + + /// Scan filter policy: + /// - SCAN_ALLOW_ADV_ALL: Allow advertising packets from anyone + /// - SCAN_ALLOW_ADV_WLST: Allow advertising packets from White List devices only + uint8_t filt_policy; + /// Scan duplicate filtering policy: + /// - SCAN_FILT_DUPLIC_DIS: Disable filtering of duplicate packets + /// - SCAN_FILT_DUPLIC_EN: Enable filtering of duplicate packets + uint8_t filter_duplic; +}; + +/// Advertising or scanning report information event - DEPRECATED +struct gapm_adv_report_ind +{ + /// Advertising report structure + adv_report_t report; +}; + +/// Set connection initialization Command - DEPRECATED +struct gapm_start_connection_cmd +{ + /// GAPM requested operation: + /// - GAPM_CONNECTION_DIRECT: Direct connection operation + /// - GAPM_CONNECTION_AUTO: Automatic connection operation + /// - GAPM_CONNECTION_SELECTIVE: Selective connection operation + /// - GAPM_CONNECTION_NAME_REQUEST: Name Request operation (requires to start a direct + /// connection) + /// - GAPM_CONNECTION_GENERAL: General connection operation + struct gapm_air_operation op; + + /// Scan interval + uint16_t scan_interval; + /// Scan window size + uint16_t scan_window; + + /// Minimum of connection interval + uint16_t con_intv_min; + /// Maximum of connection interval + uint16_t con_intv_max; + /// Connection latency + uint16_t con_latency; + /// Link supervision timeout + uint16_t superv_to; + /// Minimum CE length + uint16_t ce_len_min; + /// Maximum CE length + uint16_t ce_len_max; + + /// Number of peer device information present in message. + /// Shall be 1 for GAPM_CONNECTION_DIRECT or GAPM_CONNECTION_NAME_REQUEST operations + /// Shall be greater than 0 for other operations + uint8_t nb_peers; + + /// Peer device information + struct gap_bdaddr peers[__ARRAY_EMPTY]; +}; + +/// Confirm connection to a specific device (Connection Operation in Selective mode) - DEPRECATED +struct gapm_connection_cfm +{ + /// peer device bd address + bd_addr_t addr; + /// peer device address type + uint8_t addr_type; + + /// Minimum of connection interval + uint16_t con_intv_min; + /// Maximum of connection interval + uint16_t con_intv_max; + /// Connection latency + uint16_t con_latency; + /// Link supervision timeout + uint16_t superv_to; + /// Minimum CE length + uint16_t ce_len_min; + /// Maximum CE length + uint16_t ce_len_max; +}; + +/// Name of peer device indication +struct gapm_peer_name_ind +{ + /// peer device bd address + bd_addr_t addr; + /// peer device address type + uint8_t addr_type; + /// peer device name length + uint8_t name_len; + /// peer device name + uint8_t name[__ARRAY_EMPTY]; +}; + +/// Generate a random address. +struct gapm_gen_rand_addr_cmd +{ + /// GAPM requested operation: + /// - GAPM_GEN_RAND_ADDR: Generate a random address + uint8_t operation; + /// Dummy parameter used to store the prand part of the address + uint8_t prand[GAP_ADDR_PRAND_LEN]; + /// Random address type @see gap_rnd_addr_type + /// - GAP_STATIC_ADDR: Static random address + /// - GAP_NON_RSLV_ADDR: Private non resolvable address + /// - GAP_RSLV_ADDR: Private resolvable address + uint8_t rnd_type; +}; + +/// Parameters of the @ref GAPM_USE_ENC_BLOCK_CMD message +struct gapm_use_enc_block_cmd +{ + /// Command Operation Code (shall be GAPM_USE_ENC_BLOCK) + uint8_t operation; + /// Operand 1 + uint8_t operand_1[GAP_KEY_LEN]; + /// Operand 2 + uint8_t operand_2[GAP_KEY_LEN]; +}; + +/// Parameters of the @ref GAPM_USE_ENC_BLOCK_IND message +struct gapm_use_enc_block_ind +{ + /// Result (16 bytes) + uint8_t result[GAP_KEY_LEN]; +}; + +/// Parameters of the @ref GAPM_GEN_DH_KEY_CMD message +struct gapm_gen_dh_key_cmd +{ + /// Command Operation Code (shall be GAPM_GEN_DH_KEY) + uint8_t operation; + /// X coordinate + uint8_t operand_1[GAP_P256_KEY_LEN]; + /// Y coordinate + uint8_t operand_2[GAP_P256_KEY_LEN]; +}; + +/// Parameters of the @ref GAPM_GEN_DH_KEY_IND message +struct gapm_gen_dh_key_ind +{ + /// Result (32 bytes) + uint8_t result[GAP_P256_KEY_LEN]; +}; + +/// Parameters of the @ref GAPM_GEN_RAND_NB_CMD message +struct gapm_gen_rand_nb_cmd +{ + /// Command Operation Code (shall be GAPM_GEN_RAND_NB) + uint8_t operation; +}; + +/// Parameters of the @ref GAPM_GEN_RAND_NB_IND message +struct gapm_gen_rand_nb_ind +{ + /// Generation Random Number (8 bytes) + rand_nb_t randnb; +}; + +/// Create new task for specific profile +struct gapm_profile_task_add_cmd +{ + /// GAPM requested operation: + /// - GAPM_PROFILE_TASK_ADD: Add new profile task + uint8_t operation; + /// Security Level : + /// 7 6 5 4 3 2 1 0 + /// +----+----+----+----+----+----+----+----+ + /// | Reserved |DIS | AUTH |EKS | MI | + /// +----+----+----+----+----+----+----+----+ + /// + /// - MI: 1 - Application task is a Multi-Instantiated task, 0 - Mono-Instantiated + /// Only applies for service - Ignored by collectors: + /// - EKS: Service needs a 16 bytes encryption key + /// - AUTH: 0 - Disable, 1 - Enable, 2 - Unauth, 3 - Auth + /// - DIS: Disable the service + uint8_t sec_lvl; + /// Profile task identifier + uint16_t prf_task_id; + /// Application task number + uint16_t app_task; + /// Service start handle + /// Only applies for services - Ignored by collectors + /// 0: dynamically allocated in Attribute database + uint16_t start_hdl; + /// 32 bits value that contains value to initialize profile (database parameters, etc...) + uint32_t param[__ARRAY_EMPTY]; +}; + +/// Inform that profile task has been added. +struct gapm_profile_added_ind +{ + /// Profile task identifier + uint16_t prf_task_id; + /// Profile task number allocated + uint16_t prf_task_nb; + /// Service start handle + /// Only applies for services - Ignored by collectors + uint16_t start_hdl; +}; + +/// Indicate that a message has been received on an unknown task +struct gapm_unknown_task_ind +{ + /// Message identifier + uint16_t msg_id; + /// Task identifier + uint16_t task_id; +}; + +/// Indicates suggested default data length +struct gapm_sugg_dflt_data_len_ind +{ + ///Host's suggested value for the Controller's maximum transmitted number of payload octets + uint16_t suggted_max_tx_octets; + ///Host's suggested value for the Controller's maximum packet transmission time + uint16_t suggted_max_tx_time; +}; + +/// Indicates maximum data length +struct gapm_max_data_len_ind +{ + ///Maximum number of payload octets that the local Controller supports for transmission + uint16_t suppted_max_tx_octets; + ///Maximum time, in microseconds, that the local Controller supports for transmission + uint16_t suppted_max_tx_time; + ///Maximum number of payload octets that the local Controller supports for reception + uint16_t suppted_max_rx_octets; + ///Maximum time, in microseconds, that the local Controller supports for reception + uint16_t suppted_max_rx_time; +}; + +/// Register a LE Protocol/Service Multiplexer command +struct gapm_lepsm_register_cmd +{ + /// GAPM requested operation: + /// - GAPM_LEPSM_REG: Register a LE Protocol/Service Multiplexer + uint8_t operation; + /// LE Protocol/Service Multiplexer + uint16_t le_psm; + /// Application task number + uint16_t app_task; + /// Security level + /// 7 6 5 4 3 2 1 0 + /// +---+---+---+---+---+---+---+---+ + /// |MI | RFU |EKS|SEC_LVL| + /// +---+---+---+---+---+---+---+---+ + /// bit[0-1]: Security level requirement (0=NO_AUTH, 1=UNAUTH, 2=AUTH, 3=SEC_CON) + /// bit[2] : Encryption Key Size length must have 16 bytes + /// bit[7] : Does the application task is multi-instantiated or not + uint8_t sec_lvl; +}; + +/// Unregister a LE Protocol/Service Multiplexer command +struct gapm_lepsm_unregister_cmd +{ + /// GAPM requested operation: + /// - GAPM_LEPSM_UNREG: Unregister a LE Protocol/Service Multiplexer + uint8_t operation; + /// LE Protocol/Service Multiplexer + uint16_t le_psm; +}; + +/// Create an advertising, a scanning, an initiating, a periodic synchonization activity command (common) +struct gapm_activity_create_cmd +{ + /// GAPM request operation: + /// - GAPM_CREATE_ADV_ACTIVITY: Create advertising activity + /// - GAPM_CREATE_SCAN_ACTIVITY: Create scanning activity + /// - GAPM_CREATE_INIT_ACTIVITY: Create initiating activity + /// - GAPM_CREATE_PERIOD_SYNC_ACTIVITY: Create periodic synchronization activity + uint8_t operation; + /// Own address type + uint8_t own_addr_type; +}; + +/// Create an advertising activity command +struct gapm_activity_create_adv_cmd +{ + /// GAPM request operation: + /// - GAPM_CREATE_ADV_ACTIVITY: Create advertising activity + uint8_t operation; + /// Own address type (@see gap_own_addr_type) + uint8_t own_addr_type; + /// Advertising parameters (optional, shall be present only if operation is GAPM_CREATE_ADV_ACTIVITY) + struct gap_adv_param adv_param; +}; + +/// Start a given activity command +struct gapm_activity_start_cmd +{ + /// GAPM request operation: + /// - GAPM_START_ACTIVITY: Start a given activity + uint8_t operation; + /// Activity identifier + uint8_t actv_idx; + /// Activity parameters + union + { + /// Additional advertising parameters (for advertising activity) + struct gap_adv_add_param adv_add_param; + /// Scan parameters (for scanning activity) + struct gap_scan_param scan_param; + /// Initiating parameters (for initiating activity) + struct gap_init_param init_param; + /// Periodic synchronization parameters (for periodic synchronization activity) + struct gap_period_sync_param period_sync_param; + } u_param; +}; + +/// Stop one or all activity(ies) command +struct gapm_activity_stop_cmd +{ + /// GAPM request operation: + /// - GAPM_STOP_ACTIVITY: Stop a given activity + /// - GAPM_STOP_ALL_ACTIVITIES: Stop all existing activities + uint8_t operation; + /// Activity identifier - used only if operation is GAPM_STOP_ACTIVITY + uint8_t actv_idx; +}; + +/// Delete one or all activity(ies) command +struct gapm_activity_delete_cmd +{ + /// GAPM request operation: + /// - GAPM_DELETE_ACTIVITY: Delete a given activity + /// - GAPM_DELETE_ALL_ACTIVITIES: Delete all existing activities + uint8_t operation; + /// Activity identifier - used only if operation is GAPM_STOP_ACTIVITY + uint8_t actv_idx; +}; + +/// Indicate creation of an activity +struct gapm_activity_created_ind +{ + /// Activity identifier + uint8_t actv_idx; + /// Activity type (@see enum gap_actv_type) + uint8_t actv_type; + /// Selected TX power for advertising activity + int8_t tx_pwr; +}; + +/// Indicate that an activity has been stopped +struct gapm_activity_stopped_ind +{ + /// Activity identifier + uint8_t actv_idx; + /// Activity type (@see enum gap_actv_type) + uint8_t actv_type; + /// Activity stop reason + uint8_t reason; + /// In case of periodic advertising, indicate if periodic advertising has been stoppped + uint8_t per_adv_stop; +}; + +/// Set advertising, scan response or periodic advertising data command +struct gapm_set_adv_data_cmd +{ + /// GAPM request operation: + /// - GAPM_SET_ADV_DATA: Set advertising data + /// - GAPM_SET_SCAN_RSP_DATA: Set scan response data + /// - GAPM_SET_PERIOD_ADV_DATA: Set periodic advertising data + uint8_t operation; + /// Activity identifier + uint8_t actv_idx; + /// Data length + uint16_t length; + /// Data + uint8_t data[__ARRAY_EMPTY]; +}; + +/// Indicate reception of scan request +struct gapm_scan_request_ind +{ + /// Activity identifier + uint8_t actv_idx; + /// Transmitter device address + struct gap_bdaddr trans_addr; +}; + +/// Indicate reception of advertising, scan response or periodic advertising data +struct gapm_ext_adv_report_ind +{ + /// Activity identifier + uint8_t actv_idx; + /// Bit field providing information about the received report (@see enum gap_adv_report_info) + /// - Bit 0-2: Report type (@see enum gap_adv_report_type) + /// - Bit 3: Report is complete + /// - Bit 4: Connectable advertising + /// - Bit 5: Scannable advertising + /// - Bit 6: Directed advertising + /// - Bit 7: Reserved for future use + uint8_t info; + /// Transmitter device address + struct gap_bdaddr trans_addr; + /// Target address (in case of a directed advertising report) + struct gap_bdaddr target_addr; + /// TX power (in dBm) + int8_t tx_pwr; + /// RSSI (between -127 and +20 dBm) + int8_t rssi; + /// Primary PHY on which advertising report has been received + uint8_t phy_prim; + /// Secondary PHY on which advertising report has been received + uint8_t phy_second; + /// Advertising SID + /// Valid only for periodic advertising report + uint8_t adv_sid; + /// Periodic advertising interval (in unit of 1.25ms, min is 7.5ms) + /// Valid only for periodic advertising report + uint16_t period_adv_intv; + /// Report length + uint16_t length; + /// Report + uint8_t data[__ARRAY_EMPTY]; +}; + +/// Indicate that synchronization has been established with a periodic advertiser +struct gapm_sync_established_ind +{ + /// Activity identifier + uint8_t actv_idx; + /// PHY on which synchronization has been established (@see gap_phy_type) + uint8_t phy; + /// Periodic advertising interval (in unit of 1.25ms, min is 7.5ms) + uint16_t intv; + /// Advertising SID + uint8_t adv_sid; + /// Advertiser clock accuracy (@see enum gap_clock_accuracy) + uint8_t clk_acc; + /// Advertiser address + struct gap_bdaddr addr; +}; + +/// Read local or peer address +struct gapm_get_ral_addr_cmd +{ + /// GAPM request operation: + /// - GAPM_GET_RAL_LOC_ADDR: Set white list content + /// - GAPM_GET_RAL_PEER_ADDR: Set resolving list content + uint8_t operation; + /// Peer device identity + struct gap_bdaddr peer_identity; +}; + +/// Set content of either white list or resolving list or periodic advertiser list command (common part) +struct gapm_list_set_cmd +{ + /// GAPM request operation: + /// - GAPM_SET_WHITE_LIST: Set white list content + /// - GAPM_SET_RAL: Set resolving list content + /// - GAPM_SET_PAL: Set periodic advertiser list content + uint8_t operation; + /// Number of entries to be added in the list. 0 means that list content has to be cleared + uint8_t size; +}; + +/// Set content of white list +struct gapm_list_set_wl_cmd +{ + /// GAPM request operation: + /// - GAPM_SET_WHITE_LIST: Set white list content + uint8_t operation; + /// Number of entries to be added in the list. 0 means that list content has to be cleared + uint8_t size; + /// List of entries to be added in the list + struct gap_bdaddr wl_info[__ARRAY_EMPTY]; +}; + +/// Set content of resolving list command +struct gapm_list_set_ral_cmd +{ + /// GAPM request operation: + /// - GAPM_SET_RAL: Set resolving list content + uint8_t operation; + /// Number of entries to be added in the list. 0 means that list content has to be cleared + uint8_t size; + /// List of entries to be added in the list + struct gap_ral_dev_info ral_info[__ARRAY_EMPTY]; +}; + +/// Set content of periodic advertiser list command +struct gapm_list_set_pal_cmd +{ + /// GAPM request operation: + /// - GAPM_SET_PAL: Set periodic advertiser list content + uint8_t operation; + /// Number of entries to be added in the list. 0 means that list content has to be cleared + uint8_t size; + /// List of entries to be added in the list + struct gap_period_adv_addr_cfg pal_info[__ARRAY_EMPTY]; +}; + +/// White List Size indication event - DEPRECATED +struct gapm_white_list_size_ind +{ + /// White list size + uint8_t size; +}; + +/// Resolving List Size indication event - DEPRECATED +struct gapm_ral_size_ind +{ + /// Resolving list size + uint8_t size; +}; + +/// List Size indication event +struct gapm_list_size_ind +{ + /// Operation code, indicate list for which size has been read + uint8_t operation; + /// List size + uint8_t size; +}; + +/// Maximum advertising data length indication event +struct gapm_max_adv_data_len_ind +{ + /// Maximum advertising data length supported by controller + uint16_t length; +}; + +/// Number of available advertising sets indication event +struct gapm_nb_adv_sets_ind +{ + /// Number of available advertising sets + uint8_t nb_adv_sets; +}; + +/// Request to renew all currently used random private addresses (non-resolvable or resolvable) +/// For internal use only +struct gapm_actv_addr_renew_cmd +{ + /// GAPM request operation: + /// - GAPM_RENEW_ADDR: Renew random private addresses + uint8_t operation; + /// Activity index, sued by GAPM state machine in order to remind for which activity + /// a new address has been generated + uint8_t actv_idx; +}; + +/* + * MACROS + **************************************************************************************** + */ + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +int hci_no_operation_cmd_cmp_evt_handler(uint16_t opcode, void const *param); + +/// @} GAPM_TASK + +#endif /* _GAPM_TASK_H_ */ diff --git a/services/ble_stack/hl/api/gattc_task.h b/services/ble_stack/hl/api/gattc_task.h new file mode 100644 index 0000000..9a58a59 --- /dev/null +++ b/services/ble_stack/hl/api/gattc_task.h @@ -0,0 +1,711 @@ +#ifndef GATTC_TASK_H_ +#define GATTC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup GATTCTASK Task + * @ingroup GATTC + * @brief Handles ALL messages to/from GATT Controller block. + * + * The GATTCTASK is responsible for managing the messages coming from + * the attribute layer and host-level layers for dedicated connection. + * The task includes services and characteristic discovery, configuration exchanges + * and attribute value access operations (reading, writing, notification and indication). + * + * Messages may originate from @ref ATTC "ATTC", @ref ATTS "ATTS", @ref GAP "GAP" + * and Application. + * + * @{ + **************************************************************************************** + */ +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "att.h" +#include "rwip_task.h" // Task definitions +#include "compiler.h" +#include +/* + * DEFINES + **************************************************************************************** + */ + #ifndef TILE_ID_LEN + #define TILE_ID_LEN 8 + #endif + +/// GATT Task messages +enum gattc_msg_id +{ + /* Default event */ + /// Command Complete event + GATTC_CMP_EVT = TASK_FIRST_MSG(TASK_ID_GATTC), + + /* ATTRIBUTE CLIENT */ + /// Server configuration request + GATTC_EXC_MTU_CMD, + /// Indicate that the ATT MTU has been updated (negotiated) + GATTC_MTU_CHANGED_IND, + + /*Discover All Services */ + /*Discover Services by Service UUID*/ + /*Find Included Services*/ + /*Discover Characteristics by UUID*/ + /*Discover All Characteristics of a Service*/ + /*Discover All Characteristic Descriptors*/ + /// Discovery command + GATTC_DISC_CMD, + /* GATT -> HL: Events to Upper layer */ + /*Discover All Services*/ + /// Discovery services indication + GATTC_DISC_SVC_IND, + /*Find Included Services*/ + /// Discover included services indication + GATTC_DISC_SVC_INCL_IND, + /*Discover All Characteristics of a Service*/ + /// Discover characteristic indication + GATTC_DISC_CHAR_IND, + /*Discover All Characteristic Descriptors*/ + /// Discovery characteristic descriptor indication + GATTC_DISC_CHAR_DESC_IND, + + /*Read Value*/ + /*Read Using UUID*/ + /*Read Long Value*/ + /*Read Multiple Values*/ + /// Read command + GATTC_READ_CMD, + /// Read response + GATTC_READ_IND, + + /*Write without response*/ + /*Write without response with Authentication*/ + /*Write Characteristic Value*/ + /*Signed Write Characteristic Value*/ + /*Write Long Characteristic Value*/ + /*Characteristic Value Reliable Write*/ + /*Write Characteristic Descriptors*/ + /*Write Long Characteristic Descriptors*/ + /*Characteristic Value Reliable Write*/ + /// Write command request + GATTC_WRITE_CMD, + + /* Cancel / Execute pending write operations */ + /// Execute write characteristic request + GATTC_EXECUTE_WRITE_CMD, + + /* Reception of an indication or notification from peer device. */ + /// peer device triggers an event (notification) + GATTC_EVENT_IND, + /// peer device triggers an event that requires a confirmation (indication) + GATTC_EVENT_REQ_IND, + /// Confirm reception of event (trigger a confirmation message) + GATTC_EVENT_CFM, + + /// Registration to peer device events (Indication/Notification). + GATTC_REG_TO_PEER_EVT_CMD, + + /* -------------------------- ATTRIBUTE SERVER ------------------------------- */ + /*Notify Characteristic*/ + /*Indicate Characteristic*/ + /// send an event to peer device + GATTC_SEND_EVT_CMD, + + /* Service Changed Characteristic Indication */ + /** + * Send a Service Changed indication to a device + * (message structure is struct gattm_svc_changed_ind_req) + */ + GATTC_SEND_SVC_CHANGED_CMD, + /** + * Inform the application when sending of Service Changed indications has been + * enabled or disabled + */ + GATTC_SVC_CHANGED_CFG_IND, + + /* Indicate that read operation is requested. */ + /// Read command indicated to upper layers. + GATTC_READ_REQ_IND, + /// REad command confirmation from upper layers. + GATTC_READ_CFM, + + /* Indicate that write operation is requested. */ + /// Write command indicated to upper layers. + GATTC_WRITE_REQ_IND, + /// Write command confirmation from upper layers. + GATTC_WRITE_CFM, + + /* Indicate that write operation is requested. */ + /// Request Attribute info to upper layer - could be trigger during prepare write + GATTC_ATT_INFO_REQ_IND, + /// Attribute info from upper layer confirmation + GATTC_ATT_INFO_CFM, + + /* ----------------------- SERVICE DISCOVERY PROCEDURE --------------------------- */ + /// Service Discovery command + GATTC_SDP_SVC_DISC_CMD, + /// Service Discovery indicate that a service has been found. + GATTC_SDP_SVC_IND, + + /* -------------------------- TRANSACTION ERROR EVENT ----------------------------- */ + /// Transaction Timeout Error Event no more transaction will be accepted + GATTC_TRANSACTION_TO_ERROR_IND, + + /* ------------------------------- Internal API ----------------------------------- */ + /// Client Response timeout indication + GATTC_CLIENT_RTX_IND, + /// Server indication confirmation timeout indication + GATTC_SERVER_RTX_IND, +}; + + +/// request operation type - application interface +enum gattc_operation +{ + /* Attribute Client Flags */ + /* No Operation (if nothing has been requested) */ + /* ************************************************ */ + /// No operation + GATTC_NO_OP = 0x00, + + /* Operation flags for MTU Exchange */ + /* ************************************************ */ + /// Perform MTU exchange + GATTC_MTU_EXCH, + + /* Operation flags for discovery operation */ + /* ************************************************ */ + /// Discover all services + GATTC_DISC_ALL_SVC, + /// Discover services by UUID + GATTC_DISC_BY_UUID_SVC, + /// Discover included services + GATTC_DISC_INCLUDED_SVC, + /// Discover all characteristics + GATTC_DISC_ALL_CHAR, + /// Discover characteristic by UUID + GATTC_DISC_BY_UUID_CHAR, + /// Discover characteristic descriptor + GATTC_DISC_DESC_CHAR, + + /* Operation flags for reading attributes */ + /* ************************************************ */ + /// Read attribute + GATTC_READ, + /// Read long attribute + GATTC_READ_LONG, + /// Read attribute by UUID + GATTC_READ_BY_UUID, + /// Read multiple attribute + GATTC_READ_MULTIPLE, + + /* Operation flags for writing/modifying attributes */ + /* ************************************************ */ + /// Write attribute + GATTC_WRITE, + /// Write no response + GATTC_WRITE_NO_RESPONSE, + /// Write signed + GATTC_WRITE_SIGNED, + /// Execute write + GATTC_EXEC_WRITE, + + /* Operation flags for registering to peer device */ + /* events */ + /* ************************************************ */ + /// Register to peer device events + GATTC_REGISTER, + /// Unregister from peer device events + GATTC_UNREGISTER, + + /* Operation flags for sending events to peer device*/ + /* ************************************************ */ + /// Send an attribute notification + GATTC_NOTIFY, + /// Send an attribute indication + GATTC_INDICATE, + /// Send a service changed indication + GATTC_SVC_CHANGED, + + /* Service Discovery Procedure */ + /* ************************************************ */ + /// Search specific service + GATTC_SDP_DISC_SVC, + /// Search for all services + GATTC_SDP_DISC_SVC_ALL, + /// Cancel Service Discovery Procedure + GATTC_SDP_DISC_CANCEL, +}; + +/// Service Discovery Attribute type +enum gattc_sdp_att_type +{ + /// No Attribute Information + GATTC_SDP_NONE, + /// Included Service Information + GATTC_SDP_INC_SVC, + /// Characteristic Declaration + GATTC_SDP_ATT_CHAR, + /// Attribute Value + GATTC_SDP_ATT_VAL, + /// Attribute Descriptor + GATTC_SDP_ATT_DESC, +}; + +/// Command complete event data structure +struct gattc_op_cmd +{ + /// GATT request type + uint8_t operation; + /// operation sequence number + uint16_t seq_num; +}; + +/// Command complete event data structure +struct gattc_cmp_evt +{ + /// GATT request type + uint8_t operation; + /// Status of the request + uint8_t status; + /// operation sequence number - provided when operation is started + uint16_t seq_num; +}; + + +/// Service Discovery Command Structure +struct gattc_exc_mtu_cmd +{ + /// GATT request type + uint8_t operation; + /// operation sequence number + uint16_t seq_num; +}; + +/// Indicate that the ATT MTU has been updated (negotiated) +struct gattc_mtu_changed_ind +{ + /// Exchanged MTU value + uint16_t mtu; + /// operation sequence number + uint16_t seq_num; +}; + +/// Service Discovery Command Structure +struct gattc_disc_cmd +{ + /// GATT request type + uint8_t operation; + /// UUID length + uint8_t uuid_len; + /// operation sequence number + uint16_t seq_num; + /// start handle range + uint16_t start_hdl; + /// start handle range + uint16_t end_hdl; + /// UUID + uint8_t uuid[__ARRAY_EMPTY]; +}; + + +/// Discover Service indication Structure +struct gattc_disc_svc_ind +{ + /// start handle + uint16_t start_hdl; + /// end handle + uint16_t end_hdl; + /// UUID length + uint8_t uuid_len; + /// service UUID + uint8_t uuid[__ARRAY_EMPTY]; +}; + +/// Discover Service indication Structure +struct gattc_disc_svc_incl_ind +{ + /// element handle + uint16_t attr_hdl; + /// start handle + uint16_t start_hdl; + /// end handle + uint16_t end_hdl; + /// UUID length + uint8_t uuid_len; + /// included service UUID + uint8_t uuid[__ARRAY_EMPTY]; +}; + +/// Discovery All Characteristic indication Structure +struct gattc_disc_char_ind +{ + /// database element handle + uint16_t attr_hdl; + /// pointer attribute handle to UUID + uint16_t pointer_hdl; + /// properties + uint8_t prop; + /// UUID length + uint8_t uuid_len; + /// characteristic UUID + uint8_t uuid[__ARRAY_EMPTY]; +}; + +/// Discovery Characteristic Descriptor indication Structure +struct gattc_disc_char_desc_ind +{ + /// database element handle + uint16_t attr_hdl; + /// UUID length + uint8_t uuid_len; + /// Descriptor UUID + uint8_t uuid[__ARRAY_EMPTY]; +}; + + +/// Simple Read (GATTC_READ or GATTC_READ_LONG) +struct gattc_read_simple +{ + /// attribute handle + uint16_t handle; + /// start offset in data payload + uint16_t offset; + /// Length of data to read (0 = read all) + uint16_t length; +}; + +/// Read by UUID: search UUID and read it's characteristic value (GATTC_READ_BY_UUID) +/// Note: it doesn't perform an automatic read long. +struct gattc_read_by_uuid +{ + /// Start handle + uint16_t start_hdl; + /// End handle + uint16_t end_hdl; + /// Size of UUID + uint8_t uuid_len; + /// UUID value + uint8_t uuid[__ARRAY_EMPTY]; +}; + +/// Read Multiple short characteristic (GATTC_READ_MULTIPLE) +struct gattc_read_multiple +{ + /// attribute handle + uint16_t handle; + /// Known Handle length (shall be != 0) + uint16_t len; +}; + +/// Read command (Simple, Long, Multiple, or by UUID) +struct gattc_read_cmd +{ + /// request type + uint8_t operation; + /// number of read (only used for multiple read) + uint8_t nb; + /// operation sequence number + uint16_t seq_num; + + /// request union according to read type + union gattc_read_req + { + /// Simple Read (GATTC_READ or GATTC_READ_LONG) + struct gattc_read_simple simple; + /// Read by UUID (GATTC_READ_BY_UUID) + struct gattc_read_by_uuid by_uuid; + /// Read Multiple short characteristic (GATTC_READ_MULTIPLE) + struct gattc_read_multiple multiple[1]; + } req; +}; + +/// Attribute value read indication +struct gattc_read_ind +{ + /// Attribute handle + uint16_t handle; + /// Read offset + uint16_t offset; + /// Read length + uint16_t length; + /// Handle value + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Write peer attribute value command +struct gattc_write_cmd +{ + /// Request type + uint8_t operation; + /// Perform automatic execution + /// (if false, an ATT Prepare Write will be used this shall be use for reliable write) + bool auto_execute; + /// operation sequence number + uint16_t seq_num; + /// Attribute handle + uint16_t handle; + /// Write offset + uint16_t offset; + /// Write length + uint16_t length; + /// Internal write cursor shall be initialized to 0 + uint16_t cursor; + /// Value to write + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Write peer attribute value command +struct gattc_execute_write_cmd +{ + /// Request type + uint8_t operation; + + /// [True = perform/False cancel] pending write operations + bool execute; + /// operation sequence number + uint16_t seq_num; +}; +/// peer device triggers an event (notification) +struct gattc_event_ind +{ + /// Event Type + uint8_t type; + /// Data length + uint16_t length; + /// Attribute handle + uint16_t handle; + /// Event Value + uint8_t value[__ARRAY_EMPTY]; +}; + +/// peer device triggers an event that requires a confirmation (indication) +struct gattc_event_req_ind +{ + /// Event Type + uint8_t type; + /// Data length + uint16_t length; + /// Attribute handle + uint16_t handle; + /// Event Value + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Confirm reception of event (trigger a confirmation message) +struct gattc_event_cfm +{ + /// Attribute handle + uint16_t handle; +}; + +/// Register to peer device events command +struct gattc_reg_to_peer_evt_cmd +{ + /// Request type + uint8_t operation; + /// operation sequence number + uint16_t seq_num; + /// attribute start handle + uint16_t start_hdl; + /// attribute end handle + uint16_t end_hdl; +}; + +/// Send an event to peer device +struct gattc_send_evt_cmd +{ + /// Request type (notification / indication) + uint8_t operation; + /// operation sequence number + uint16_t seq_num; + /// characteristic handle + uint16_t handle; + /// length of packet to send + uint16_t length; + /// data value + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Inform that attribute value is requested by lower layers. +struct gattc_read_req_ind +{ + /// Handle of the attribute that has to be read + uint16_t handle; +}; + +/// Confirm Read Request requested by GATT to profile +struct gattc_read_cfm +{ + /// Handle of the attribute read + uint16_t handle; + /// Data length read + uint16_t length; + /// Status of read command execution by upper layers + uint8_t status; + /// attribute data value + uint8_t value[TILE_ID_LEN]; +}; + +/// Inform that a modification of database has been requested by peer device. +struct gattc_write_req_ind +{ + /// Handle of the attribute that has to be written + uint16_t handle; + /// offset at which the data has to be written + uint16_t offset; + /// Data length to be written + uint16_t length; + /// Data to be written in attribute database + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Confirm modification of database from upper layer when requested by peer device. +struct gattc_write_cfm +{ + /// Handle of the attribute written + uint16_t handle; + /// Status of write command execution by upper layers + uint8_t status; +}; + +/// Parameters for @ref GATTC_SEND_SVC_CHANGED_CMD message +struct gattc_send_svc_changed_cmd +{ + /// Request Type + uint8_t operation; + /// operation sequence number + uint16_t seq_num; + /// Start of Affected Attribute Handle Range + uint16_t svc_shdl; + /// End of Affected Attribute Handle Range + uint16_t svc_ehdl; +}; + +/// Parameters for @ref GATTC_SVC_CHANGED_CFG_IND and @ref GATTC_SVC_CHANGED_SET_CFG_REQ message +struct gattc_svc_changed_cfg +{ + /** + * Current value of the Client Characteristic Configuration descriptor for the Service + * Changed characteristic + */ + uint16_t ind_cfg; +}; + + +/// Request Attribute info to upper layer - could be trigger during prepare write +struct gattc_att_info_req_ind +{ + /// Handle of the attribute for which info are requested + uint16_t handle; +}; + +/// Attribute info from upper layer confirmation +struct gattc_att_info_cfm +{ + /// Handle of the attribute + uint16_t handle; + /// Current length of the attribute + uint16_t length; + /// use to know if it's possible to modify the attribute + /// can contains authorization or application error code. + uint8_t status; +}; + + +/// Service Discovery command +struct gattc_sdp_svc_disc_cmd +{ + /// GATT Request Type + /// - GATTC_SDP_DISC_SVC Search specific service + /// - GATTC_SDP_DISC_SVC_ALL Search for all services + /// - GATTC_SDP_DISC_CANCEL Cancel Service Discovery Procedure + uint8_t operation; + /// Service UUID Length + uint8_t uuid_len; + /// operation sequence number + uint16_t seq_num; + /// Search start handle + uint16_t start_hdl; + /// Search end handle + uint16_t end_hdl; + /// Service UUID + uint8_t uuid[ATT_UUID_128_LEN]; +}; + + +/// Information about included service +struct gattc_sdp_include_svc +{ + /// Attribute Type + /// - GATTC_SDP_INC_SVC: Included Service Information + uint8_t att_type; + /// Included service UUID Length + uint8_t uuid_len; + /// Included Service UUID + uint8_t uuid[ATT_UUID_128_LEN]; + /// Included service Start Handle + uint16_t start_hdl; + /// Included service End Handle + uint16_t end_hdl; +}; + +/// Information about attribute characteristic +struct gattc_sdp_att_char +{ + /// Attribute Type + /// - GATTC_SDP_ATT_CHAR: Characteristic Declaration + uint8_t att_type; + /// Value property + uint8_t prop; + /// Value Handle + uint16_t handle; +}; + +/// Information about attribute +struct gattc_sdp_att +{ + /// Attribute Type + /// - GATTC_SDP_ATT_VAL: Attribute Value + /// - GATTC_SDP_ATT_DESC: Attribute Descriptor + uint8_t att_type; + /// Attribute UUID Length + uint8_t uuid_len; + /// Attribute UUID + uint8_t uuid[ATT_UUID_128_LEN]; +}; + +/// Attribute information +union gattc_sdp_att_info +{ + /// Attribute Type + uint8_t att_type; + /// Information about attribute characteristic + struct gattc_sdp_att_char att_char; + /// Information about included service + struct gattc_sdp_include_svc inc_svc; + /// Information about attribute + struct gattc_sdp_att att; +}; + + +/// Service Discovery indicate that a service has been found. +struct gattc_sdp_svc_ind +{ + /// Service UUID Length + uint8_t uuid_len; + /// Service UUID + uint8_t uuid[ATT_UUID_128_LEN]; + /// Service start handle + uint16_t start_hdl; + /// Service end handle + uint16_t end_hdl; + /// attribute information present in the service + /// (length = end_hdl - start_hdl) + union gattc_sdp_att_info info[__ARRAY_EMPTY]; +}; + + + +/// @} GATTCTASK +#endif // GATTC_TASK_H_ diff --git a/services/ble_stack/hl/api/gattm_task.h b/services/ble_stack/hl/api/gattm_task.h new file mode 100644 index 0000000..1ba4eb8 --- /dev/null +++ b/services/ble_stack/hl/api/gattm_task.h @@ -0,0 +1,375 @@ +#ifndef GATTM_TASK_H_ +#define GATTM_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup GATTMTASK Task + * @ingroup GATTM + * @brief Handles ALL GATT block operations not related to a connection. + * + * The GATTMTASK is responsible for managing internal attribute database and state of + * GATT controller which manage GATT block operations related to a connection. + * + * Messages may originate from @ref ATTM "ATTM", @ref GAP "GAP" and Application. + * + * @{ + **************************************************************************************** + */ +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_task.h" // Task definitions +#include "att.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +/// GATT Task messages +enum gattm_msg_id +{ + /* Database Management */ + /// Add service in database request + GATTM_ADD_SVC_REQ = TASK_FIRST_MSG(TASK_ID_GATTM), + /// Add service in database response + GATTM_ADD_SVC_RSP, + + /* Service management */ + /// Get permission settings of service request + GATTM_SVC_GET_PERMISSION_REQ, + /// Get permission settings of service response + GATTM_SVC_GET_PERMISSION_RSP, + /// Set permission settings of service request + GATTM_SVC_SET_PERMISSION_REQ, + /// Set permission settings of service response + GATTM_SVC_SET_PERMISSION_RSP, + + /* Attribute Manipulation */ + /// Get permission settings of attribute request + GATTM_ATT_GET_PERMISSION_REQ, + /// Get permission settings of attribute response + GATTM_ATT_GET_PERMISSION_RSP, + /// Set permission settings of attribute request + GATTM_ATT_SET_PERMISSION_REQ, + /// Set permission settings of attribute response + GATTM_ATT_SET_PERMISSION_RSP, + + /// Get attribute value request + GATTM_ATT_GET_VALUE_REQ, + /// Get attribute value response + GATTM_ATT_GET_VALUE_RSP, + /// Set attribute value request + GATTM_ATT_SET_VALUE_REQ, + /// Set attribute value response + GATTM_ATT_SET_VALUE_RSP, + + /* Debug messages */ + /// DEBUG ONLY: Destroy Attribute database request + GATTM_DESTROY_DB_REQ, + /// DEBUG ONLY: Destroy Attribute database response + GATTM_DESTROY_DB_RSP, + /// DEBUG ONLY: Retrieve list of services request + GATTM_SVC_GET_LIST_REQ, + /// DEBUG ONLY: Retrieve list of services response + GATTM_SVC_GET_LIST_RSP, + /// DEBUG ONLY: Retrieve information of attribute request + GATTM_ATT_GET_INFO_REQ, + /// DEBUG ONLY: Retrieve information of attribute response + GATTM_ATT_GET_INFO_RSP, +}; + + +/** + * Attribute Description + */ +struct gattm_att_desc +{ + /** Attribute UUID (LSB First) */ + uint8_t uuid[ATT_UUID_128_LEN]; + + /** + * Attribute Permission (@see attm_perm_mask) + */ + uint16_t perm; + + + /** + * Maximum length of the attribute + * + * Note: + * For Included Services and Characteristic Declarations, this field contains targeted + * handle. + * + * For Characteristic Extended Properties, this field contains 2 byte value + * + * Not used Client Characteristic Configuration and Server Characteristic Configuration, + * this field is not used. + */ + uint16_t max_len; + + /** + * Attribute Extended permissions + * + * Extended Value permission bit field + * + * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + * +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + * | RI |UUID_LEN |EKS | Reserved | + * +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + * + * Bit [0-11] : Reserved + * Bit [12] : Encryption key Size must be 16 bytes + * Bit [13-14]: UUID Length (0 = 16 bits, 1 = 32 bits, 2 = 128 bits, 3 = RFU) + * Bit [15] : Trigger Read Indication (0 = Value present in Database, 1 = Value not present in Database) + */ + uint16_t ext_perm; +}; + +/** + * Service description + */ +struct gattm_svc_desc +{ + /// Attribute Start Handle (0 = dynamically allocated) + uint16_t start_hdl; + /// Task identifier that manages service + uint16_t task_id; + + /** + * 7 6 5 4 3 2 1 0 + * +----+----+----+----+----+----+----+----+ + * |SEC |UUID_LEN |DIS | AUTH |EKS | MI | + * +----+----+----+----+----+----+----+----+ + * + * Bit [0] : Task that manage service is multi-instantiated (Connection index is conveyed) + * Bit [1] : Encryption key Size must be 16 bytes + * Bit [2-3]: Service Permission (0 = NO_AUTH, 1 = UNAUTH, 2 = AUTH, 3 = Secure Connect) + * Bit [4] : Disable the service + * Bit [5-6]: UUID Length (0 = 16 bits, 1 = 32 bits, 2 = 128 bits, 3 = RFU) + * Bit [7] : Secondary Service (0 = Primary Service, 1 = Secondary Service) + */ + uint8_t perm; + + /// Number of attributes + uint8_t nb_att; + + /** Service UUID */ + uint8_t uuid[ATT_UUID_128_LEN]; + /** + * List of attribute description present in service. + */ + struct gattm_att_desc atts[__ARRAY_EMPTY]; +}; + + +/// Add service in database request +struct gattm_add_svc_req +{ + /// service description + struct gattm_svc_desc svc_desc; +}; + +/// Add service in database response +struct gattm_add_svc_rsp +{ + /// Start handle of allocated service in attribute database + uint16_t start_hdl; + /// Return status of service allocation in attribute database. + uint8_t status; +}; + +/* Service management */ +/// Get permission settings of service request +struct gattm_svc_get_permission_req +{ + /// Service start attribute handle + uint16_t start_hdl; +}; + +/// Get permission settings of service response +struct gattm_svc_get_permission_rsp +{ + /// Service start attribute handle + uint16_t start_hdl; + /// service permission + uint8_t perm; + /// Return status + uint8_t status; +}; + +/// Set permission settings of service request +struct gattm_svc_set_permission_req +{ + /// Service start attribute handle + uint16_t start_hdl; + /// service permission + uint8_t perm; +}; + +/// Set permission settings of service response +struct gattm_svc_set_permission_rsp +{ + /// Service start attribute handle + uint16_t start_hdl; + /// Return status + uint8_t status; +}; + + +/* Attribute management */ +/// Get permission settings of attribute request +struct gattm_att_get_permission_req +{ + /// Handle of the attribute + uint16_t handle; +}; + +/// Get permission settings of attribute response +struct gattm_att_get_permission_rsp +{ + /// Handle of the attribute + uint16_t handle; + /// Attribute permission + uint16_t perm; + /// Extended Attribute permission + uint16_t ext_perm; + /// Return status + uint8_t status; +}; + +/// Set permission settings of attribute request +struct gattm_att_set_permission_req +{ + /// Handle of the attribute + uint16_t handle; + /// Attribute permission + uint16_t perm; + /// Extended Attribute permission + uint16_t ext_perm; +}; + +/// Set permission settings of attribute response +struct gattm_att_set_permission_rsp +{ + /// Handle of the attribute + uint16_t handle; + /// Return status + uint8_t status; +}; + + +/// Get attribute value request +struct gattm_att_get_value_req +{ + /// Handle of the attribute + uint16_t handle; +}; + +/// Get attribute value response +struct gattm_att_get_value_rsp +{ + /// Handle of the attribute + uint16_t handle; + /// Attribute value length + uint16_t length; + /// Return status + uint8_t status; + /// Attribute value + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Set attribute value request +struct gattm_att_set_value_req +{ + /// Handle of the attribute + uint16_t handle; + /// Attribute value length + uint16_t length; + /// Attribute value + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Set attribute value response +struct gattm_att_set_value_rsp +{ + /// Handle of the attribute + uint16_t handle; + /// Return status + uint8_t status; +}; + +/// DEBUG ONLY: Destroy Attribute database request +struct gattm_destroy_db_req +{ + /// New Gap Start Handle + uint16_t gap_hdl; + /// New Gatt Start Handle + uint16_t gatt_hdl; +}; + +/// DEBUG ONLY: Destroy Attribute database Response +struct gattm_destroy_db_rsp +{ + /// Return status + uint8_t status; +}; + + +/// Service information +struct gattm_svc_info +{ + /// Service start handle + uint16_t start_hdl; + /// Service end handle + uint16_t end_hdl; + /// Service task_id + uint16_t task_id; + /// Service permission + uint8_t perm; +}; + +/// DEBUG ONLY: Retrieve list of services response +struct gattm_svc_get_list_rsp +{ + /// Return status + uint8_t status; + /// Number of services + uint8_t nb_svc; + /// Array of information about services + struct gattm_svc_info svc[__ARRAY_EMPTY]; +}; + +/// DEBUG ONLY: Retrieve information of attribute request +struct gattm_att_get_info_req +{ + /// Attribute Handle + uint16_t handle; +}; + +/// DEBUG ONLY: Retrieve information of attribute response +struct gattm_att_get_info_rsp +{ + /// Return status + uint8_t status; + /// UUID Length + uint8_t uuid_len; + /// Attribute Handle + uint16_t handle; + /// Attribute Permissions + uint16_t perm; + /// Extended Attribute permission + uint16_t ext_perm; + /// UUID value + uint8_t uuid[ATT_UUID_128_LEN]; +}; + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/// @} GATTMTASK +#endif // GATTM_TASK_H_ diff --git a/services/ble_stack/hl/api/l2cc_task.h b/services/ble_stack/hl/api/l2cc_task.h new file mode 100644 index 0000000..8eaaa9d --- /dev/null +++ b/services/ble_stack/hl/api/l2cc_task.h @@ -0,0 +1,298 @@ +#ifndef L2CC_TASK_H_ +#define L2CC_TASK_H_ + +/** + **************************************************************************************** + * @addtogroup L2CCTASK Task + * @ingroup L2CC + * @brief Handles ALL messages to/from L2CC block. + * + * The L2CC task is responsible for L2CAP attribute and security block handling. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_task.h" // Task definitions +#include "compiler.h" +#include + +/* + * MACRO DEFINITIONS + **************************************************************************************** + */ + +/// Number of L2CC Deprecated messages +#define L2CC_NB_DEPRECATED_MSG (4) + +/* + * STATES + **************************************************************************************** + */ + +/* + * MESSAGES + **************************************************************************************** + */ + +/// Message API of the L2CC task +enum l2cc_msg_id +{ + /// L2CAP Operation completed event + L2CC_CMP_EVT = TASK_FIRST_MSG(TASK_ID_L2CC) + L2CC_NB_DEPRECATED_MSG, + + /* ************* LE Credit Based API ************* */ + /// LE credit based connection request + L2CC_LECB_CONNECT_CMD, + /// LE credit based connection request indication + L2CC_LECB_CONNECT_REQ_IND, + /// LE credit based connection request confirmation + L2CC_LECB_CONNECT_CFM, + /// LE credit based connection indication + L2CC_LECB_CONNECT_IND, + /// LE credit based disconnect request + L2CC_LECB_DISCONNECT_CMD, + /// LE credit based disconnect indication + L2CC_LECB_DISCONNECT_IND, + /// LE credit based credit addition + L2CC_LECB_ADD_CMD, + /// LE credit based credit addition indication + L2CC_LECB_ADD_IND, + + /// Send data over an LE Credit Based Connection + L2CC_LECB_SDU_SEND_CMD, + /// Inform that a data packet has been received from a LE Credit Based connection. + L2CC_LECB_SDU_RECV_IND, + + + /* ******************* Debug API ******************* */ + /// Send Debug PDU data + L2CC_DBG_PDU_SEND_CMD, + /// Debug PDU data received + L2CC_DBG_PDU_RECV_IND, + + + /* **************** PDU Internal API ****************** */ + /// Send Legacy PDU data + L2CC_PDU_SEND_CMD, + /// Legacy PDU data received + L2CC_PDU_RECV_IND, + + /// Timeout indication for a transaction on signaling channel + L2CC_SIGNALING_TRANS_TO_IND, +}; + + +/// request operation type - application interface +enum l2cc_operation +{ + /* Operation Flags */ + /* No Operation (if nothing has been requested) */ + /* ************************************************ */ + /// No operation + L2CC_NO_OP = 0x00, + + /* LE Credit Based */ + /* ************************************************ */ + /// LE credit based connection request + L2CC_LECB_CONNECT, + /// LE credit based disconnection request + L2CC_LECB_DISCONNECT, + /// LE credit addition request + L2CC_LECB_CREDIT_ADD, + /// Send SDU + L2CC_LECB_SDU_SEND, + + /* Debug PDU Transmission (internal) */ + /* ************************************************ */ + /// Send a Debug PDU + L2CC_DBG_PDU_SEND, + + /* PDU Transmission (internal) */ + /* ************************************************ */ + /// Send internal LE Legacy PDU + L2CC_PDU_SEND, +}; + + +/// Default L2Cap SDU definition +struct l2cc_sdu +{ + /// Channel Identifier + uint16_t cid; + /// Number of credit used + uint16_t credit; + /// SDU Data length + uint16_t length; + /// data + uint8_t data[__ARRAY_EMPTY]; +}; + + +/// Operation completed event +struct l2cc_cmp_evt +{ + /// L2CC request type (@see enum l2cc_operation) + uint8_t operation; + /// Status of request. + uint8_t status; + /// Channel ID + uint16_t cid; + /// Number of peer credit used - only relevant for LECB + uint16_t credit; +}; + +/// LE credit based connection request +struct l2cc_lecb_connect_cmd +{ + /// L2CC request type: + /// - L2CC_LECB_CONNECT: LE credit connection + uint8_t operation; + /// parameter used for internal usage + uint8_t pkt_id; + /// LE Protocol/Service Multiplexer + uint16_t le_psm; + /// Local Channel identifier (0: automatically allocate a free channel) + uint16_t local_cid; + /// Credit allocated for the LE Credit Based Connection + /// Shall be at least: floor(((SDU + 2) + (MPS - 1)) / MPS) + 1 + /// To be sure that 1 SDU can be fully received without requesting credits to application + uint16_t local_credit; + /// Maximum SDU size - Shall not exceed device MTU + uint16_t local_mtu; + /// Maximum Packet size - Shall not exceed device MPS + uint16_t local_mps; +}; + +/// LE credit based connection request indication +struct l2cc_lecb_connect_req_ind +{ + /// LE Protocol/Service Multiplexer + uint16_t le_psm; + /// Peer Channel identifier + uint16_t peer_cid; + /// Maximum SDU size + uint16_t peer_mtu; + /// Maximum Packet size + uint16_t peer_mps; +}; + +/// LE credit based connection request confirmation +struct l2cc_lecb_connect_cfm +{ + /// LE Protocol/Service Multiplexer + uint16_t le_psm; + /// Peer Channel identifier + uint16_t peer_cid; + /// True to accept the incoming connection, False else + bool accept; + /// Local Channel identifier (0: automatically allocate a free channel) + uint16_t local_cid; + /// Credit allocated for the LE Credit Based Connection + /// Shall be at least: floor(((SDU + 2) + (MPS - 1)) / MPS) + 1 + /// To be sure that 1 SDU can be fully received without requesting credits to application + uint16_t local_credit; + /// Maximum SDU size - Shall not exceed device MTU + uint16_t local_mtu; + /// Maximum Packet size - Shall not exceed device MPS + uint16_t local_mps; +}; + +/// LE credit based connection indication +struct l2cc_lecb_connect_ind +{ + /// Status + uint8_t status; + /// LE Protocol/Service Multiplexer + uint16_t le_psm; + /// Local Channel identifier + uint16_t local_cid; + /// Peer Channel identifier + uint16_t peer_cid; + /// Destination Credit for the LE Credit Based Connection + uint16_t peer_credit; + /// Maximum SDU size + uint16_t peer_mtu; + /// Maximum Packet size + uint16_t peer_mps; +}; + +/// LE credit based disconnect request +struct l2cc_lecb_disconnect_cmd +{ + /// L2CC request type: + /// - L2CC_LECB_DISCONNECT: LE credit disconnection + uint8_t operation; + /// parameter used for internal usage + uint8_t pkt_id; + /// Peer Channel identifier + uint16_t peer_cid; +}; + +/// LE credit based disconnect indication +struct l2cc_lecb_disconnect_ind +{ + /// LE Protocol/Service Multiplexer + uint16_t le_psm; + /// Local Channel identifier + uint16_t local_cid; + /// Peer Channel identifier + uint16_t peer_cid; + /// Reason + uint8_t reason; +}; + +/// LE credit based credit addition +struct l2cc_lecb_add_cmd +{ + /// L2CC request type: + /// - L2CC_LECB_CREDIT_ADD: LE credit addition + uint8_t operation; + /// parameter used for internal usage + uint8_t pkt_id; + /// Local Channel identifier + uint16_t local_cid; + /// Credit added locally for channel identifier + uint16_t credit; +}; + +///LE credit based credit addition indication +struct l2cc_lecb_add_ind +{ + /// Peer Channel identifier + uint16_t peer_cid; + /// Destination added credit (relative value) + uint16_t peer_added_credit; +}; + +/// Send data over an LE Credit Based Connection +struct l2cc_lecb_sdu_send_cmd +{ + /// L2CC request type (@see enum l2cc_operation): + /// - L2CC_LECB_SDU_SEND: Send a SDU + uint8_t operation; + /// offset value information - for internal use only + uint16_t offset; + /// SDU information + struct l2cc_sdu sdu; +}; + +/// Inform that a data packet has been received from a LE Credit Based connection. +struct l2cc_lecb_sdu_recv_ind +{ + /// Status information + uint8_t status; + /// offset value information + uint16_t offset; + /// SDU information + struct l2cc_sdu sdu; +}; + + +/// @} L2CCTASK + +#endif // L2CC_TASK_H_ diff --git a/services/ble_stack/hl/api/prf_types.h b/services/ble_stack/hl/api/prf_types.h new file mode 100644 index 0000000..cbdb0f6 --- /dev/null +++ b/services/ble_stack/hl/api/prf_types.h @@ -0,0 +1,232 @@ +#ifndef _PRF_TYPES_H_ +#define _PRF_TYPES_H_ + +/** + **************************************************************************************** + * @addtogroup PRF_TYPES + * @ingroup PROFILE + * @brief Definitions of shared profiles types + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "att.h" +#include "compiler.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Attribute is mandatory +#define ATT_MANDATORY (0xFF) +/// Attribute is optional +#define ATT_OPTIONAL (0x00) + +/// Characteristic Presentation Format Descriptor Size +#define PRF_CHAR_PRES_FMT_SIZE (7) + + +/// Possible values for setting client configuration characteristics +enum prf_cli_conf +{ + /// Stop notification/indication + PRF_CLI_STOP_NTFIND = 0x0000, + /// Start notification + PRF_CLI_START_NTF, + /// Start indication + PRF_CLI_START_IND, +}; + +/// Possible values for setting server configuration characteristics +enum prf_srv_conf +{ + /// Stop Broadcast + PRF_SRV_STOP_BCST = 0x0000, + /// Start Broadcast + PRF_SRV_START_BCST, +}; + +/// Connection type +enum prf_con_type +{ + ///Discovery type connection + PRF_CON_DISCOVERY = 0x00, + /// Normal type connection + PRF_CON_NORMAL = 0x01, +}; + +enum prf_svc_type +{ + PRF_PRIMARY_SERVICE = 0x00, + PRF_SECONDARY_SERVICE = 0x01 +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/** + * Characteristic Presentation Format Descriptor structure + * Packed size is PRF_CHAR_PRES_FMT_SIZE + */ +/// characteristic presentation information +struct prf_char_pres_fmt +{ + /// Unit (The Unit is a UUID) + uint16_t unit; + /// Description + uint16_t description; + /// Format + uint8_t format; + /// Exponent + uint8_t exponent; + /// Name space + uint8_t name_space; +}; + +/** + * date and time structure + * size = 7 bytes + */ +/// Time profile information +struct prf_date_time +{ + /// year time element + uint16_t year; + /// month time element + uint8_t month; + /// day time element + uint8_t day; + /// hour time element + uint8_t hour; + /// minute time element + uint8_t min; + /// second time element + uint8_t sec; +}; + +/** + * SFLOAT: Short Floating Point Type + * + * +----------+----------+---------+ + * | Exponent | Mantissa | Total | + * +------+----------+----------+---------+ + * | size | 4 bits | 12 bits | 16 bits | + * +------+----------+----------+---------+ + */ +typedef uint16_t prf_sfloat; + + + +/// Attribute information +struct prf_att_info +{ + /// Attribute Handle + uint16_t handle; + /// Attribute length + uint16_t length; + /// Status of request + uint8_t status; + /// Attribute value + uint8_t value[__ARRAY_EMPTY]; +}; + + + + +/// service handles +struct prf_svc +{ + /// start handle + uint16_t shdl; + /// end handle + uint16_t ehdl; +}; + +/// service handles +struct prf_incl_svc +{ + /// attribute handle + uint16_t handle; + /// included service start handle + uint16_t start_hdl; + /// included service end handle + uint16_t end_hdl; + /// UUID length + uint8_t uuid_len; + /// UUID + uint8_t uuid[ATT_UUID_128_LEN]; +}; + +/// characteristic info +struct prf_char_inf +{ + /// Characteristic handle + uint16_t char_hdl; + /// Value handle + uint16_t val_hdl; + /// Characteristic properties + uint8_t prop; + /// End of characteristic offset + uint8_t char_ehdl_off; +}; + +/// characteristic description +struct prf_char_desc_inf +{ + /// Descriptor handle + uint16_t desc_hdl; +}; + + +/// Characteristic definition +struct prf_char_def +{ + /// Characteristic UUID + uint16_t uuid; + /// Requirement Attribute Flag + uint8_t req_flag; + /// Mandatory Properties + uint8_t prop_mand; +}; + +/// Characteristic Descriptor definition +struct prf_char_desc_def +{ + /// Characteristic Descriptor uuid + uint16_t uuid; + /// requirement attribute flag + uint8_t req_flag; + /// Corresponding characteristic code + uint8_t char_code; +}; + +/// Message structure used to inform APP that a profile client role has been disabled +struct prf_client_disable_ind +{ + /// Status + uint8_t status; +}; + + + +/// Message structure used to inform APP that an error has occured in the profile server role task +struct prf_server_error_ind +{ + /// Message ID + uint16_t msg_id; + /// Status + uint8_t status; +}; + + +/// @} PRF_TYPES + +#endif /* _PRF_TYPES_H_ */ diff --git a/services/ble_stack/hl/api/rwble_hl_error.h b/services/ble_stack/hl/api/rwble_hl_error.h new file mode 100644 index 0000000..d177533 --- /dev/null +++ b/services/ble_stack/hl/api/rwble_hl_error.h @@ -0,0 +1,415 @@ +#ifndef RWBLE_HL_ERROR_H_ +#define RWBLE_HL_ERROR_H_ + + +/** + **************************************************************************************** + * @addtogroup ROOT + * @brief High layer error codes + * + * This module contains the primitives that allow an application accessing and running the + * BLE protocol stack + * + * @{ + **************************************************************************************** + */ + + + +/// Error code from HCI TO HL Range - from 0x90 to 0xD0 +#define RW_ERR_HCI_TO_HL(err) (((err) != 0) ? ((err) + 0x90) : (0)) + + +/// Error code from HL TO HCI Range - from 0x90 to 0xD0 +#define RW_ERR_HL_TO_HCI(err) (((err) > 0x90) ? ((err) - 0x90) : (0)) + +/** + * List all HL error codes + */ +enum hl_err +{ + /// No error + GAP_ERR_NO_ERROR = 0x00, + + // ---------------------------------------------------------------------------------- + // ------------------------- ATT Specific Error ------------------------------------ + // ---------------------------------------------------------------------------------- + /// No error + ATT_ERR_NO_ERROR = 0x00, + /// 0x01: Handle is invalid + ATT_ERR_INVALID_HANDLE = 0x01, + /// 0x02: Read permission disabled + ATT_ERR_READ_NOT_PERMITTED = 0x02, + /// 0x03: Write permission disabled + ATT_ERR_WRITE_NOT_PERMITTED = 0x03, + /// 0x04: Incorrect PDU + ATT_ERR_INVALID_PDU = 0x04, + /// 0x05: Authentication privilege not enough + ATT_ERR_INSUFF_AUTHEN = 0x05, + /// 0x06: Request not supported or not understood + ATT_ERR_REQUEST_NOT_SUPPORTED = 0x06, + /// 0x07: Incorrect offset value + ATT_ERR_INVALID_OFFSET = 0x07, + /// 0x08: Authorization privilege not enough + ATT_ERR_INSUFF_AUTHOR = 0x08, + /// 0x09: Capacity queue for reliable write reached + ATT_ERR_PREPARE_QUEUE_FULL = 0x09, + /// 0x0A: Attribute requested not existing + ATT_ERR_ATTRIBUTE_NOT_FOUND = 0x0A, + /// 0x0B: Attribute requested not long + ATT_ERR_ATTRIBUTE_NOT_LONG = 0x0B, + /// 0x0C: Encryption size not sufficient + ATT_ERR_INSUFF_ENC_KEY_SIZE = 0x0C, + /// 0x0D: Invalid length of the attribute value + ATT_ERR_INVALID_ATTRIBUTE_VAL_LEN = 0x0D, + /// 0x0E: Operation not fit to condition + ATT_ERR_UNLIKELY_ERR = 0x0E, + /// 0x0F: Attribute requires encryption before operation + ATT_ERR_INSUFF_ENC = 0x0F, + /// 0x10: Attribute grouping not supported + ATT_ERR_UNSUPP_GRP_TYPE = 0x10, + /// 0x11: Resources not sufficient to complete the request + ATT_ERR_INSUFF_RESOURCE = 0x11, + /// 0x80: Application error (also used in PRF Errors) + ATT_ERR_APP_ERROR = 0x80, + + // ---------------------------------------------------------------------------------- + // -------------------------- L2C Specific Error ------------------------------------ + // ---------------------------------------------------------------------------------- + /// Message cannot be sent because connection lost. (disconnected) + L2C_ERR_CONNECTION_LOST = 0x30, + /// Invalid PDU length exceed MTU + L2C_ERR_INVALID_MTU_EXCEED = 0x31, + /// Invalid PDU length exceed MPS + L2C_ERR_INVALID_MPS_EXCEED = 0x32, + /// Invalid Channel ID + L2C_ERR_INVALID_CID = 0x33, + /// Invalid PDU + L2C_ERR_INVALID_PDU = 0x34, + /// Connection refused - no resources available + L2C_ERR_NO_RES_AVAIL = 0x35, + /// Connection refused - insufficient authentication + L2C_ERR_INSUFF_AUTHEN = 0x36, + /// Connection refused - insufficient authorization + L2C_ERR_INSUFF_AUTHOR = 0x37, + /// Connection refused - insufficient encryption key size + L2C_ERR_INSUFF_ENC_KEY_SIZE = 0x38, + /// Connection Refused - insufficient encryption + L2C_ERR_INSUFF_ENC = 0x39, + /// Connection refused - LE_PSM not supported + L2C_ERR_LEPSM_NOT_SUPP = 0x3A, + /// No more credit + L2C_ERR_INSUFF_CREDIT = 0x3B, + /// Command not understood by peer device + L2C_ERR_NOT_UNDERSTOOD = 0x3C, + /// Credit error, invalid number of credit received + L2C_ERR_CREDIT_ERROR = 0x3D, + /// Channel identifier already allocated + L2C_ERR_CID_ALREADY_ALLOC = 0x3E, + + + // ---------------------------------------------------------------------------------- + // -------------------------- GAP Specific Error ------------------------------------ + // ---------------------------------------------------------------------------------- + /// Invalid parameters set + GAP_ERR_INVALID_PARAM = 0x40, + /// Problem with protocol exchange, get unexpected response + GAP_ERR_PROTOCOL_PROBLEM = 0x41, + /// Request not supported by software configuration + GAP_ERR_NOT_SUPPORTED = 0x42, + /// Request not allowed in current state. + GAP_ERR_COMMAND_DISALLOWED = 0x43, + /// Requested operation canceled. + GAP_ERR_CANCELED = 0x44, + /// Requested operation timeout. + GAP_ERR_TIMEOUT = 0x45, + /// Link connection lost during operation. + GAP_ERR_DISCONNECTED = 0x46, + /// Search algorithm finished, but no result found + GAP_ERR_NOT_FOUND = 0x47, + /// Request rejected by peer device + GAP_ERR_REJECTED = 0x48, + /// Problem with privacy configuration + GAP_ERR_PRIVACY_CFG_PB = 0x49, + /// Duplicate or invalid advertising data + GAP_ERR_ADV_DATA_INVALID = 0x4A, + /// Insufficient resources + GAP_ERR_INSUFF_RESOURCES = 0x4B, + /// Unexpected Error + GAP_ERR_UNEXPECTED = 0x4C, + /// Feature mismatch + GAP_ERR_MISMATCH = 0x4D, + /// Limit Reached + GAP_ERR_LIMIT_REACHED = 0x4E, + + // ---------------------------------------------------------------------------------- + // ------------------------- GATT Specific Error ------------------------------------ + // ---------------------------------------------------------------------------------- + /// Problem with ATTC protocol response + GATT_ERR_INVALID_ATT_LEN = 0x50, + /// Error in service search + GATT_ERR_INVALID_TYPE_IN_SVC_SEARCH = 0x51, + /// Invalid write data + GATT_ERR_WRITE = 0x52, + /// Signed write error + GATT_ERR_SIGNED_WRITE = 0x53, + /// No attribute client defined + GATT_ERR_ATTRIBUTE_CLIENT_MISSING = 0x54, + /// No attribute server defined + GATT_ERR_ATTRIBUTE_SERVER_MISSING = 0x55, + /// Permission set in service/attribute are invalid + GATT_ERR_INVALID_PERM = 0x56, + + // ---------------------------------------------------------------------------------- + // ------------------------- SMP Specific Error ------------------------------------- + // ---------------------------------------------------------------------------------- + // SMP Protocol Errors detected on local device + /// The user input of pass key failed, for example, the user canceled the operation. + SMP_ERROR_LOC_PASSKEY_ENTRY_FAILED = 0x61, + /// The OOB Data is not available. + SMP_ERROR_LOC_OOB_NOT_AVAILABLE = 0x62, + /// The pairing procedure cannot be performed as authentication requirements cannot be met + /// due to IO capabilities of one or both devices. + SMP_ERROR_LOC_AUTH_REQ = 0x63, + /// The confirm value does not match the calculated confirm value. + SMP_ERROR_LOC_CONF_VAL_FAILED = 0x64, + /// Pairing is not supported by the device. + SMP_ERROR_LOC_PAIRING_NOT_SUPP = 0x65, + /// The resultant encryption key size is insufficient for the security requirements of + /// this device. + SMP_ERROR_LOC_ENC_KEY_SIZE = 0x66, + /// The SMP command received is not supported on this device. + SMP_ERROR_LOC_CMD_NOT_SUPPORTED = 0x67, + /// Pairing failed due to an unspecified reason. + SMP_ERROR_LOC_UNSPECIFIED_REASON = 0x68, + /// Pairing or Authentication procedure is disallowed because too little time has elapsed + /// since last pairing request or security request. + SMP_ERROR_LOC_REPEATED_ATTEMPTS = 0x69, + /// The command length is invalid or a parameter is outside of the specified range. + SMP_ERROR_LOC_INVALID_PARAM = 0x6A, + /// Indicates to the remote device that the DHKey Check value received doesn't + /// match the one calculated by the local device. + SMP_ERROR_LOC_DHKEY_CHECK_FAILED = 0x6B, + /// Indicates that the confirm values in the numeric comparison protocol do not match. + SMP_ERROR_LOC_NUMERIC_COMPARISON_FAILED = 0x6C, + /// Indicates that the pairing over the LE transport failed due to a Pairing Request sent + /// over the BR/EDR transport in process. + SMP_ERROR_LOC_BREDR_PAIRING_IN_PROGRESS = 0x6D, + /// Indicates that the BR/EDR Link Key generated on the BR/EDR transport cannot be + /// used to derive and distribute keys for the LE transport. + SMP_ERROR_LOC_CROSS_TRANSPORT_KEY_GENERATION_NOT_ALLOWED = 0x6E, + // SMP Protocol Errors detected by remote device + /// The user input of passkey failed, for example, the user canceled the operation. + SMP_ERROR_REM_PASSKEY_ENTRY_FAILED = 0x71, + /// The OOB Data is not available. + SMP_ERROR_REM_OOB_NOT_AVAILABLE = 0x72, + /// The pairing procedure cannot be performed as authentication requirements cannot be + /// met due to IO capabilities of one or both devices. + SMP_ERROR_REM_AUTH_REQ = 0x73, + /// The confirm value does not match the calculated confirm value. + SMP_ERROR_REM_CONF_VAL_FAILED = 0x74, + /// Pairing is not supported by the device. + SMP_ERROR_REM_PAIRING_NOT_SUPP = 0x75, + /// The resultant encryption key size is insufficient for the security requirements of + /// this device. + SMP_ERROR_REM_ENC_KEY_SIZE = 0x76, + /// The SMP command received is not supported on this device. + SMP_ERROR_REM_CMD_NOT_SUPPORTED = 0x77, + /// Pairing failed due to an unspecified reason. + SMP_ERROR_REM_UNSPECIFIED_REASON = 0x78, + /// Pairing or Authentication procedure is disallowed because too little time has elapsed + /// since last pairing request or security request. + SMP_ERROR_REM_REPEATED_ATTEMPTS = 0x79, + /// The command length is invalid or a parameter is outside of the specified range. + SMP_ERROR_REM_INVALID_PARAM = 0x7A, + /// Indicates to the remote device that the DHKey Check value received doesn't + /// match the one calculated by the local device. + SMP_ERROR_REM_DHKEY_CHECK_FAILED = 0x7B, + /// Indicates that the confirm values in the numeric comparison protocol do not match. + SMP_ERROR_REM_NUMERIC_COMPARISON_FAILED = 0x7C, + /// Indicates that the pairing over the LE transport failed due to a Pairing Request sent + /// over the BR/EDR transport in process. + SMP_ERROR_REM_BREDR_PAIRING_IN_PROGRESS = 0x7D, + /// Indicates that the BR/EDR Link Key generated on the BR/EDR transport cannot be + /// used to derive and distribute keys for the LE transport. + SMP_ERROR_REM_CROSS_TRANSPORT_KEY_GENERATION_NOT_ALLOWED = 0x7E, + // SMP Errors triggered by local device + /// The provided resolvable address has not been resolved. + SMP_ERROR_ADDR_RESOLV_FAIL = 0xD0, + /// The Signature Verification Failed + SMP_ERROR_SIGN_VERIF_FAIL = 0xD1, + /// The encryption procedure failed because the slave device didn't find the LTK + /// needed to start an encryption session. + SMP_ERROR_ENC_KEY_MISSING = 0xD2, + /// The encryption procedure failed because the slave device doesn't support the + /// encryption feature. + SMP_ERROR_ENC_NOT_SUPPORTED = 0xD3, + /// A timeout has occurred during the start encryption session. + SMP_ERROR_ENC_TIMEOUT = 0xD4, + + // ---------------------------------------------------------------------------------- + //------------------------ Profiles specific error codes ---------------------------- + // ---------------------------------------------------------------------------------- + /// Application Error + PRF_APP_ERROR = 0x80, + /// Invalid parameter in request + PRF_ERR_INVALID_PARAM = 0x81, + /// Inexistent handle for sending a read/write characteristic request + PRF_ERR_INEXISTENT_HDL = 0x82, + /// Discovery stopped due to missing attribute according to specification + PRF_ERR_STOP_DISC_CHAR_MISSING = 0x83, + /// Too many SVC instances found -> protocol violation + PRF_ERR_MULTIPLE_SVC = 0x84, + /// Discovery stopped due to found attribute with incorrect properties + PRF_ERR_STOP_DISC_WRONG_CHAR_PROP = 0x85, + /// Too many Char. instances found-> protocol violation + PRF_ERR_MULTIPLE_CHAR = 0x86, + /// Attribute write not allowed + PRF_ERR_NOT_WRITABLE = 0x87, + /// Attribute read not allowed + PRF_ERR_NOT_READABLE = 0x88, + /// Request not allowed + PRF_ERR_REQ_DISALLOWED = 0x89, + /// Notification Not Enabled + PRF_ERR_NTF_DISABLED = 0x8A, + /// Indication Not Enabled + PRF_ERR_IND_DISABLED = 0x8B, + /// Feature not supported by profile + PRF_ERR_FEATURE_NOT_SUPPORTED = 0x8C, + /// Read value has an unexpected length + PRF_ERR_UNEXPECTED_LEN = 0x8D, + /// Disconnection occurs + PRF_ERR_DISCONNECTED = 0x8E, + /// Procedure Timeout + PRF_ERR_PROC_TIMEOUT = 0x8F, + /// Client characteristic configuration improperly configured + PRF_CCCD_IMPR_CONFIGURED = 0xFD, + /// Procedure already in progress + PRF_PROC_IN_PROGRESS = 0xFE, + /// Out of Range + PRF_OUT_OF_RANGE = 0xFF, + + // ---------------------------------------------------------------------------------- + //-------------------- LL Error codes conveyed to upper layer ----------------------- + // ---------------------------------------------------------------------------------- + /// Unknown HCI Command + LL_ERR_UNKNOWN_HCI_COMMAND = 0x91, + /// Unknown Connection Identifier + LL_ERR_UNKNOWN_CONNECTION_ID = 0x92, + /// Hardware Failure + LL_ERR_HARDWARE_FAILURE = 0x93, + /// BT Page Timeout + LL_ERR_PAGE_TIMEOUT = 0x94, + /// Authentication failure + LL_ERR_AUTH_FAILURE = 0x95, + /// Pin code missing + LL_ERR_PIN_MISSING = 0x96, + /// Memory capacity exceed + LL_ERR_MEMORY_CAPA_EXCEED = 0x97, + /// Connection Timeout + LL_ERR_CON_TIMEOUT = 0x98, + /// Connection limit Exceed + LL_ERR_CON_LIMIT_EXCEED = 0x99, + /// Synchronous Connection limit exceed + LL_ERR_SYNC_CON_LIMIT_DEV_EXCEED = 0x9A, + /// ACL Connection exits + LL_ERR_ACL_CON_EXISTS = 0x9B, + /// Command Disallowed + LL_ERR_COMMAND_DISALLOWED = 0x9C, + /// Connection rejected due to limited resources + LL_ERR_CONN_REJ_LIMITED_RESOURCES = 0x9D, + /// Connection rejected due to security reason + LL_ERR_CONN_REJ_SECURITY_REASONS = 0x9E, + /// Connection rejected due to unacceptable BD Addr + LL_ERR_CONN_REJ_UNACCEPTABLE_BDADDR = 0x9F, + /// Connection rejected due to Accept connection timeout + LL_ERR_CONN_ACCEPT_TIMEOUT_EXCEED = 0xA0, + /// Not Supported + LL_ERR_UNSUPPORTED = 0xA1, + /// invalid parameters + LL_ERR_INVALID_HCI_PARAM = 0xA2, + /// Remote user terminate connection + LL_ERR_REMOTE_USER_TERM_CON = 0xA3, + /// Remote device terminate connection due to low resources + LL_ERR_REMOTE_DEV_TERM_LOW_RESOURCES = 0xA4, + /// Remote device terminate connection due to power off + LL_ERR_REMOTE_DEV_POWER_OFF = 0xA5, + /// Connection terminated by local host + LL_ERR_CON_TERM_BY_LOCAL_HOST = 0xA6, + /// Repeated attempts + LL_ERR_REPEATED_ATTEMPTS = 0xA7, + /// Pairing not Allowed + LL_ERR_PAIRING_NOT_ALLOWED = 0xA8, + /// Unknown PDU Error + LL_ERR_UNKNOWN_LMP_PDU = 0xA9, + /// Unsupported remote feature + LL_ERR_UNSUPPORTED_REMOTE_FEATURE = 0xAA, + /// Sco Offset rejected + LL_ERR_SCO_OFFSET_REJECTED = 0xAB, + /// SCO Interval Rejected + LL_ERR_SCO_INTERVAL_REJECTED = 0xAC, + /// SCO air mode Rejected + LL_ERR_SCO_AIR_MODE_REJECTED = 0xAD, + /// Invalid LMP parameters + LL_ERR_INVALID_LMP_PARAM = 0xAE, + /// Unspecified error + LL_ERR_UNSPECIFIED_ERROR = 0xAF, + /// Unsupported LMP Parameter value + LL_ERR_UNSUPPORTED_LMP_PARAM_VALUE = 0xB0, + /// Role Change Not allowed + LL_ERR_ROLE_CHANGE_NOT_ALLOWED = 0xB1, + /// LMP Response timeout + LL_ERR_LMP_RSP_TIMEOUT = 0xB2, + /// LMP Collision + LL_ERR_LMP_COLLISION = 0xB3, + /// LMP Pdu not allowed + LL_ERR_LMP_PDU_NOT_ALLOWED = 0xB4, + /// Encryption mode not accepted + LL_ERR_ENC_MODE_NOT_ACCEPT = 0xB5, + /// Link Key Cannot be changed + LL_ERR_LINK_KEY_CANT_CHANGE = 0xB6, + /// Quality of Service not supported + LL_ERR_QOS_NOT_SUPPORTED = 0xB7, + /// Error, instant passed + LL_ERR_INSTANT_PASSED = 0xB8, + /// Pairing with unit key not supported + LL_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUP = 0xB9, + /// Transaction collision + LL_ERR_DIFF_TRANSACTION_COLLISION = 0xBA, + /// Unacceptable parameters + LL_ERR_QOS_UNACCEPTABLE_PARAM = 0xBC, + /// Quality of Service rejected + LL_ERR_QOS_REJECTED = 0xBD, + /// Channel class not supported + LL_ERR_CHANNEL_CLASS_NOT_SUP = 0xBE, + /// Insufficient security + LL_ERR_INSUFFICIENT_SECURITY = 0xBF, + /// Parameters out of mandatory range + LL_ERR_PARAM_OUT_OF_MAND_RANGE = 0xC0, + /// Role switch pending + LL_ERR_ROLE_SWITCH_PEND = 0xC2, + /// Reserved slot violation + LL_ERR_RESERVED_SLOT_VIOLATION = 0xC4, + /// Role Switch fail + LL_ERR_ROLE_SWITCH_FAIL = 0xC5, + /// Error, EIR too large + LL_ERR_EIR_TOO_LARGE = 0xC6, + /// Simple pairing not supported by host + LL_ERR_SP_NOT_SUPPORTED_HOST = 0xC7, + /// Host pairing is busy + LL_ERR_HOST_BUSY_PAIRING = 0xC8, + /// Controller is busy + LL_ERR_CONTROLLER_BUSY = 0xCA, + /// Unacceptable connection initialization + LL_ERR_UNACCEPTABLE_CONN_INT = 0xCB, + /// Direct Advertising Timeout + LL_ERR_DIRECT_ADV_TO = 0xCC, + /// Connection Terminated due to a MIC failure + LL_ERR_TERMINATED_MIC_FAILURE = 0xCD, + /// Connection failed to be established + LL_ERR_CONN_FAILED_TO_BE_EST = 0xCE, +}; + +/// @} RWBLE_HL_ERROR_H + +#endif // RWBLE_HL_ERROR_H_ diff --git a/services/ble_stack/hl/inc/attm.h b/services/ble_stack/hl/inc/attm.h new file mode 100644 index 0000000..262483c --- /dev/null +++ b/services/ble_stack/hl/inc/attm.h @@ -0,0 +1,401 @@ +#ifndef ATTM_H_ +#define ATTM_H_ + +/** + **************************************************************************************** + * @addtogroup ATTM Attribute Manager + * @ingroup ATT + * @brief Attribute Manager + * + * The ATTM is the attribute manager of the Attribute Profile block and + * is responsible for managing messages and providing generic attribute + * functionalities to @ref ATTC "ATTC" and @ref ATTS "ATTS". + * + * + * @{ + * + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#include +#include + +#include "co_error.h" +#include "att.h" +#include "ke_task.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// update attribute permission on specific handle +#define ATTMDB_UPDATE_PERM(handle, access, right)\ + attm_att_update_perm(handle, (PERM_MASK_ ## access), PERM(access, right)) + +#define ATTMDB_UPDATE_PERM_VAL(handle, access, val)\ + attm_att_update_perm(handle, (PERM_MASK_ ## access), ((val) << (PERM_POS_ ## access))) + + + +/* + * DATA STRUCTURES + **************************************************************************************** + */ + +/// Internal 16bits UUID service description +struct attm_desc +{ + /// 16 bits UUID LSB First + uint16_t uuid; + /// Attribute Permissions (@see enum attm_perm_mask) + uint16_t perm; + /// Attribute Extended Permissions (@see enum attm_value_perm_mask) + uint16_t ext_perm; + /// Attribute Max Size + /// note: for characteristic declaration contains handle offset + /// note: for included service, contains target service handle + uint16_t max_size; +}; + + +/// Internal 128bits UUID service description +struct attm_desc_128 +{ + /// 128 bits UUID LSB First + uint8_t uuid[ATT_UUID_128_LEN]; + /// Attribute Permissions (@see enum attm_perm_mask) + uint16_t perm; + /// Attribute Extended Permissions (@see enum attm_value_perm_mask) + uint16_t ext_perm; + /// Attribute Max Size + /// note: for characteristic declaration contains handle offset + /// note: for included service, contains target service handle + uint16_t max_size; +}; + + + +#if (BLE_CENTRAL || BLE_PERIPHERAL) +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Compare if two UUIDs matches + * + * @param[in] uuid_a UUID A value + * @param[in] uuid_a_len UUID A length + * @param[in] uuid_b UUID B value + * @param[in] uuid_b_len UUID B length + * + * @return true if UUIDs matches, false otherwise + **************************************************************************************** + */ +bool attm_uuid_comp(uint8_t *uuid_a, uint8_t uuid_a_len, + uint8_t *uuid_b, uint8_t uuid_b_len); + + +/** + **************************************************************************************** + * @brief Check if two UUIDs matches (2nd UUID is a 16 bits UUID with LSB First) + * + * @param[in] uuid_a UUID A value + * @param[in] uuid_a_len UUID A length + * @param[in] uuid_b UUID B 16 bit value + * + * @return true if UUIDs matches, false otherwise + **************************************************************************************** + */ +bool attm_uuid16_comp(uint8_t *uuid_a, uint8_t uuid_a_len, uint16_t uuid_b); + + +/** + **************************************************************************************** + * @brief Convert UUID value to 128 bit UUID + * + * @param[out] uuid128 converted 32-bit Bluetooth UUID to 128-bit UUID + * @param[in] uuid UUID to convert to 128-bit UUID + * @param[in] uuid_len UUID length + * + **************************************************************************************** + */ +void attm_convert_to128(uint8_t *uuid128, uint8_t *uuid, uint8_t uuid_len); + +/** + **************************************************************************************** + * @brief Check if it's a Bluetooth 16-bits UUID for 128-bit input + * + * @param[in] uuid 128-bit UUID + * + * @return true if uuid is a Bluetooth 16-bit UUID, false else. + **************************************************************************************** + */ +bool attm_is_bt16_uuid(uint8_t *uuid); + +/** + **************************************************************************************** + * @brief Check if it's a Bluetooth 32 bits UUID for 128-bit input + * + * @param[in] uuid 128-bit UUID + * + * @return true if uuid is a Bluetooth 32-bits UUID, false else. + **************************************************************************************** + */ +bool attm_is_bt32_uuid(uint8_t *uuid); + + +#if (BLE_ATTS) +/** + **************************************************************************************** + * @brief Function use to ease service database creation. + * Use @see attmdb_add_service function of attmdb module to create service database, + * then use @see attmdb_add_attribute function of attmdb module to create attributes + * according to database description array given in parameter. + * + * @note: database description array shall be const to reduce memory consumption (only ROM) + * @note: It supports only 16 bits UUIDs + * + * @note: If shdl = 0, it return handle using first available handle (shdl is + * modified); else it verifies if start handle given can be used to allocates handle range. + * + * @param[in|out] shdl Service start handle. + * @param[in] uuid Service UUID + * @param[in|out] cfg_flag Configuration Flag, each bit matches with an attribute of + * att_db (Max: 32 attributes); if the bit is set to 1, the + * attribute will be added in the service. + * @param[in] max_nb_att Number of attributes in the service + * @param[in|out] att_tbl Array which will be fulfilled with the difference between + * each characteristic handle and the service start handle. + * This array is useful if several characteristics are optional + * within the service, can be set to NULL if not needed. + * @param[in] dest_id Task ID linked to the service. This task will be notified + * each time the service content is modified by a peer device. + * @param[in|out] att_db Table containing all attributes information + * @param[in] svc_perm Service permission (@see enum attm_svc_perm_mask) + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If database creation succeeds. + * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter + nb of attribute override + * some existing services handles. + * - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer. + * or of new attribute cannot be added because all expected + * attributes already added or buffer overflow detected during + * allocation + **************************************************************************************** + */ +uint8_t attm_svc_create_db(uint16_t *shdl, uint16_t uuid, uint8_t *cfg_flag, uint8_t max_nb_att, + uint8_t *att_tbl, ke_task_id_t const dest_id, + const struct attm_desc *att_db, uint8_t svc_perm); + + + +/** + **************************************************************************************** + * @brief Function use to ease service database creation. + * Use @see attmdb_add_service function of attmdb module to create service database, + * then use @see attmdb_add_attribute function of attmdb module to create attributes + * according to database description array given in parameter. + * + * @note: database description array shall be const to reduce memory consumption (only ROM) + * @note: It supports 128, 32 and 16 bits UUIDs + * + * @note: If shdl = 0, it return handle using first available handle (shdl is + * modified); else it verifies if start handle given can be used to allocates handle range. + * + * @param[in|out] shdl Service start handle. + * @param[in] uuid Service UUID + * @param[in|out] cfg_flag Configuration Flag, each bit matches with an attribute of + * att_db (Max: 32 attributes); if the bit is set to 1, the + * attribute will be added in the service. + * @param[in] max_nb_att Number of attributes in the service + * @param[in|out] att_tbl Array which will be fulfilled with the difference between + * each characteristic handle and the service start handle. + * This array is useful if several characteristics are optional + * within the service, can be set to NULL if not needed. + * @param[in] dest_id Task ID linked to the service. This task will be notified + * each time the service content is modified by a peer device. + * @param[in|out] att_db Table containing all attributes information + * @param[in] svc_perm Service permission (@see enum attm_svc_perm_mask) + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If database creation succeeds. + * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter + nb of attribute override + * some existing services handles. + * - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer. + * or of new attribute cannot be added because all expected + * attributes already added or buffer overflow detected during + * allocation + **************************************************************************************** + */ +uint8_t attm_svc_create_db_128(uint16_t *shdl, const uint8_t* uuid, uint8_t *cfg_flag, uint8_t max_nb_att, + uint8_t *att_tbl, ke_task_id_t const dest_id, + const struct attm_desc_128 *att_db, uint8_t svc_perm); + +/** + **************************************************************************************** + * @brief Function use to verify if several services can be allocated on a contiguous + * handle range. If this command succeed, it means that service allocation will succeed. + * + * If start_hdl = 0, it return handle using first available handle (start_hdl is + * modified); else it verifies if start handle given can be used to allocates handle range. + * + * @param[in|out] start_hdl Service start handle. + * @param[in] nb_att Number of handle to allocate (containing service handles) + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If service allocation succeeds. + * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter or UUIDs value invalid + **************************************************************************************** + */ +uint8_t attm_reserve_handle_range(uint16_t* start_hdl, uint8_t nb_att); + + + +/** + **************************************************************************************** + * @brief Update attribute value + * + * Updating attribute value do not trigger any notification or indication, this shall be + * handled by GATT task. + * + * @param[in] handle Attribute handle. + * @param[in] length Size of new attribute value + * @param[in] offset Data offset of in the payload to set + * @param[in] value Attribute value payload + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If attribute value update succeeds + * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database + * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database or + * cannot be modified + * - @ref ATT_ERR_INVALID_ATTRIBUTE_VAL_LEN: If new value length exceeds maximum attribute + * value length. + * + **************************************************************************************** + */ +uint8_t attm_att_set_value(uint16_t handle, att_size_t length, att_size_t offset, uint8_t* value); + +/** + **************************************************************************************** + * @brief Retrieve attribute value + + * + * @param[in] handle Attribute handle. + * @param[out] length Size of attribute value + * @param[out] value Pointer to attribute value payload + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If request succeeds + * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database + * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database + **************************************************************************************** + */ +uint8_t attm_get_value(uint16_t handle, att_size_t* length, uint8_t** value); + + +/** + **************************************************************************************** + * @brief Update attribute permission + * + * @param[in] handle Attribute handle. + * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database + * @param[in] perm New attribute permission + * @param[in] ext_perm New attribute extended permission + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If request succeeds + * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database + * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute permission is fixed + **************************************************************************************** + */ +uint8_t attm_att_set_permission(uint16_t handle, uint16_t perm, uint16_t ext_perm); + + +/** + **************************************************************************************** + * @brief Reset some permissions bit in the Handle passed as parameter. + * + * @param[in] handle Attribute handle. + * @param[in] access_mask Access mask of permission to update + * @param[in] perm New value of the permission to update + * + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If request succeeds + * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database + * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute permission is fixed + **************************************************************************************** + */ +uint8_t attm_att_update_perm(uint16_t handle, uint16_t access_mask, uint16_t perm); + +/** + **************************************************************************************** + * @brief Update attribute service permission + * + * @param[in] handle Attribute handle. + * @param[in] perm New attribute permission + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If request succeeds + * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database + **************************************************************************************** + */ +uint8_t attm_svc_set_permission(uint16_t handle, uint8_t perm); + + +/** + **************************************************************************************** + * @brief Retrieve attribute service permission + * + * @param[in] handle Attribute handle. + * @param[out] perm Permission value to return + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If request succeeds + * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database + **************************************************************************************** + */ +uint8_t attm_svc_get_permission(uint16_t handle, uint8_t* perm); + + +/** + **************************************************************************************** + * @brief Clear database + * + * For debug purpose only, this function clear the database and unalloc all services + * within database. + * + * This function shall be used only for qualification and tests in order to manually + * change database without modifying software. + **************************************************************************************** + */ +void attmdb_destroy(void); + +/** + **************************************************************************************** + * @brief Initialize Attribute Database (clear it) + * + * @param[in] reset true if it's requested by a reset; false if it's boot initialization + **************************************************************************************** + */ +void attm_init(bool reset); +#endif // (BLE_ATTS) + +#endif // #if (BLE_CENTRAL || BLE_PERIPHERAL) +/// @} ATTM +#endif // ATTM_H_ diff --git a/services/ble_stack/hl/inc/gapc.h b/services/ble_stack/hl/inc/gapc.h new file mode 100644 index 0000000..920acd4 --- /dev/null +++ b/services/ble_stack/hl/inc/gapc.h @@ -0,0 +1,236 @@ +#ifndef _GAPC_H_ +#define _GAPC_H_ + +/** + **************************************************************************************** + * @addtogroup GAPC Generic Access Profile Controller + * @ingroup GAP + * @brief Generic Access Profile Controller. + * + * The GAP Controller module is responsible for providing an API to the application in + * to perform GAP action related to a BLE connection (pairing, update parameters, + * disconnect ...). GAP controller is multi-instantiated, one task instance per BLE + * connection. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_GAPC) + +#include "ke_task.h" +#include "gap.h" +#include "smpc.h" + + + +/* + * DEFINES + **************************************************************************************** + */ + + +/// Operation type +enum gapc_op_type +{ + /// Operation used to manage Link (update params, get peer info) + GAPC_OP_LINK_INFO = 0x00, + + /// Operation used to manage SMP + GAPC_OP_SMP = 0x01, + + /// Operation used to manage connection update + GAPC_OP_LINK_UPD = 0x02, + + /// Max number of operations + GAPC_OP_MAX +}; + +/// Link security status. This status represents the authentication/authorization/bonding levels of the connection +enum gapc_lk_sec_req +{ + /// Link is bonded + GAPC_LK_BONDED, + /// Link is Encrypted + GAPC_LK_ENCRYPTED, + /// Link LTK Exchanged during pairing + GAPC_LK_LTK_PRESENT, +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// GAP controller environment variable structure. +struct gapc_env_tag +{ + /// Request operation Kernel message + void* operation[GAPC_OP_MAX]; + /// Task id requested disconnection + ke_task_id_t disc_requester; + + + /* Connection parameters to keep */ + + /// Security Management Protocol environment variables + struct smpc_env smpc; + + /// connection handle + uint16_t conhdl; + + /// Configuration fields (@see enum gapc_fields) + uint8_t fields; + + // BD Address used for the link that should be kept + struct gap_bdaddr src[SMPC_INFO_MAX]; + + /// Relevant information of peer LE features 8-byte array + uint8_t features; +}; + + + +/* + * MACROS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Retrieve connection index from connection handle. + * + * @param[in] conhdl Connection handle + * + * @return Return found connection index, GAP_INVALID_CONIDX if not found. + **************************************************************************************** + */ +uint8_t gapc_get_conidx(uint16_t conhdl); + +/** + **************************************************************************************** + * @brief Retrieve connection handle from connection index. + * + * @param[in] conidx Connection index + * + * @return Return found connection handle, GAP_INVALID_CONHDL if not found. + **************************************************************************************** + */ +uint16_t gapc_get_conhdl(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Retrieve connection role from connection index. + * + * @param[in] conidx Connection index + * + * @return Return found connection role + **************************************************************************************** + */ +uint8_t gapc_get_role(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Retrieve connection address information on current link. + * + * @param[in] conidx Connection index + * @param[in] src Connection information source + * + * @return Return found connection address + **************************************************************************************** + */ +struct gap_bdaddr* gapc_get_bdaddr(uint8_t conidx, uint8_t src); + + +/** + **************************************************************************************** + * @brief Check if current link support security requirements. + * + * @param[in] conidx Connection index + * @param[in] sec_req Link security requirement to test + * + * @return True if link requirement is supported, False else. + **************************************************************************************** + */ +bool gapc_is_sec_set(uint8_t conidx, uint8_t sec_req); + +/** + **************************************************************************************** + * @brief Retrieve Link Security level + * + * @param[in] conidx Connection index + * + * @return Link Security level. + **************************************************************************************** + */ +uint8_t gapc_lk_sec_lvl_get(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Retrieve the encryption key size of the connection + * + * @param[in] conidx Connection index + * + * @return encryption key size (size is 7 - 16 byte range) + * + **************************************************************************************** + */ +uint8_t gapc_enc_keysize_get(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Get Service Change Client Configuration + * + * @param[in] conidx Connection index + * + * @return Service Change Client Configuration + **************************************************************************************** + */ +bool gapc_svc_chg_ccc_get(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Set Service Change Client Configuration + * + * @param[in] conidx Connection index + * @param[in] enable True if CCC is enabled, False else + * + **************************************************************************************** + */ +void gapc_svc_chg_ccc_set(uint8_t conidx, bool enable); + +/** + **************************************************************************************** + * Retrieve if current connection index is used for a discovery purpose such as + * Name discovery + * + * @param conidx Index of the specific connection + * + * @return true if connection has a discovery purpose, False else + **************************************************************************************** + */ +bool gapc_is_disc_connection(uint8_t conidx); + +bool gapc_get_remote_dev_feature(uint8_t conidx, uint8_t* ptrFeature); + +#ifdef __GATT_OVER_BR_EDR__ +uint8_t gapc_create_btgatt(uint16_t conhdl); +void gapc_clean_btgatt(uint8_t conidx); +#endif + +#endif // (BLE_GAPC) +/// @} GAPC + +#endif /* _GAPC_H_ */ diff --git a/services/ble_stack/hl/inc/gapm.h b/services/ble_stack/hl/inc/gapm.h new file mode 100644 index 0000000..22b1417 --- /dev/null +++ b/services/ble_stack/hl/inc/gapm.h @@ -0,0 +1,346 @@ +#ifndef _GAPM_H_ +#define _GAPM_H_ + +/** + **************************************************************************************** + * @addtogroup GAPM Generic Access Profile Manager + * @ingroup GAP + * @brief Generic Access Profile Manager. + * + * The GAP Manager module is responsible for providing an API to the application in order + * to manage all non connected stuff such as configuring device to go in desired mode + * (discoverable, connectable, etc.) and perform required actions (scanning, connection, + * etc.). GAP Manager is also responsible of managing GAP Controller state according to + * corresponding BLE connection states. + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#include "ke_task.h" +#include "gap.h" + +/* + * DEFINES + **************************************************************************************** + */ +/// Bit checking +#define GAPM_ISBITSET(flag, mask) (((flag)&(mask)) == mask) + + + + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialize Generic Access Profile Manager Module. + * + * @param[in] reset true if it's requested by a reset; false if it's boot initialization + * + **************************************************************************************** + */ +void gapm_init(bool reset); + + +/** + **************************************************************************************** + * @brief Retrieve Task Identifier from Task number + * (automatically update index of task in returned task id) + * + * @param task Task number + * @return Task Identifier + **************************************************************************************** + */ +ke_task_id_t gapm_get_id_from_task(ke_msg_id_t task); + +/** + **************************************************************************************** + * @brief Retrieve Task Number from Task Identifier + * (automatically update index of task in returned task id) + * + * @param id Task Identifier + * @return Task Number + **************************************************************************************** + */ +ke_task_id_t gapm_get_task_from_id(ke_msg_id_t id); + + + +#if (BLE_GAPC) +/** + **************************************************************************************** + * @brief Created link connection parameters (from bond data) has been set, connection + * ready to be used. + * + * @param[in] conidx Connection Index + * + **************************************************************************************** + */ +void gapm_con_enable(uint8_t conidx); + + +/** + **************************************************************************************** + * @brief A link has been disconnected, clean-up host stack for this connection. + * + * @param[in] conidx Connection Index + * @param[in] conhdl Connection Handle + * @param[in] reason Reason of the disconnection + * + **************************************************************************************** + */ +void gapm_con_cleanup(uint8_t conidx, uint16_t conhdl, uint8_t reason); + +#endif // (BLE_GAPC) + + +/** + **************************************************************************************** + * @brief Retrieve device identity key. + * + * @return Device Identity Key + **************************************************************************************** + */ +struct gap_sec_key* gapm_get_irk(void); + + +/** + **************************************************************************************** + * @brief update the device identity key saved in @gapm_env. + * + * @return Device Identity Key to update + **************************************************************************************** + */ +void gapm_update_irk(uint8_t *irk); + + +/** + **************************************************************************************** + * @brief Retrieve local public address. + * + * @return Return local public address + **************************************************************************************** + */ +bd_addr_t* gapm_get_bdaddr(void); + +bd_addr_t* gapm_get_connected_bdaddr(uint8_t conidx); + +#ifdef BLE_AUDIO_AM0_TASK +/** + **************************************************************************************** + * @brief Return if LE Audio Mode 0 is supported or not + * + * @return True if supported, False else + **************************************************************************************** + */ +bool gapm_is_audio_am0_sup(void); +#endif // BLE_AUDIO_AM0_TASK + + +#if(BLE_EMB_PRESENT && HCI_TL_SUPPORT) +/** + **************************************************************************************** + * @brief Retrieve if host is embedded or not + * + * @return True if embedded host is enabled, false else. + **************************************************************************************** + */ +bool gapm_is_embedded_host(void); + +/** + **************************************************************************************** + * @brief Set if host is embedded or not + * + * @param[in] enable True to enable embedded host, false else. + **************************************************************************************** + */ +void gapm_set_embedded_host(bool enable); +#endif // (BLE_EMB_PRESENT && HCI_TL_SUPPORT) + + + +/** + **************************************************************************************** + * @brief Retrieve the device address type (@see enum gapm_addr_type) + * + * @return address type + **************************************************************************************** + */ +uint8_t gapm_get_address_type(void); + + +#if (BLE_ATTS) + +/** + **************************************************************************************** + * @brief Get if preferred connection parameters present in GAP ATT database + * + * @return True if referred connection parameters present in GAP ATT database, False else + **************************************************************************************** + */ +bool gapm_is_pref_con_param_pres(void); + +/** + **************************************************************************************** + * @brief retrieve gap attribute handle from attribute index. + * + * @param[in] att_idx Attribute index + * + * @return Attribute handle + **************************************************************************************** + */ +uint16_t gapm_get_att_handle(uint8_t att_idx); + +#endif // (BLE_ATTS) + +#if (SECURE_CONNECTIONS) +/** + **************************************************************************************** + * @brief Returns the local Public Key + * + * @return pointer to the local Public Key + **************************************************************************************** + */ +public_key_t* gapm_get_local_public_key(void); +private_key_t * gapm_get_local_private_key(void); +#endif // (SECURE_CONNECTIONS) + +/** + **************************************************************************************** + * @brief Retrieve if Legacy pairing is supported on local device + * + * @return True if legacy pairing is supported + **************************************************************************************** + */ +bool gapm_is_legacy_pairing_supp(void); + + +/** + **************************************************************************************** + * @brief Retrieve if Secure Connection pairing is supported on local device + * + * @return True if Secure Connection pairing is supported + **************************************************************************************** + */ +bool gapm_is_sec_con_pairing_supp(void); + + +#if (BLE_LECB) +/** + **************************************************************************************** + * @brief Check if LECB connection can be registered (established) + * + * @param[in] le_psm LE Protocol/Service Multiplexer + * @param[in] conidx Connection index for app_task computation + * @param[out] app_task Destination application/profile task + * @param[out] sec_lvl Security level requirements + * + * + * @return GAP_ERR_NOT_FOUND if LE_PSM not register, GAP_ERR_NO_ERROR else + **************************************************************************************** + */ +uint8_t gapm_le_psm_get_info(uint16_t le_psm, uint8_t conidx, ke_task_id_t *app_task, uint8_t *sec_lvl); + + +/** + **************************************************************************************** + * @brief Check if LECB connection can be registered (established) + * + * @param[in] le_psm LE Protocol/Service Multiplexer + * @param[in] peer_con_init Info to know if connection is initiated by peer device + * + * @return L2C_ERR_NO_RES_AVAIL if all LECB link are established, GAP_ERR_NO_ERROR else + **************************************************************************************** + */ +uint8_t gapm_lecb_register(uint16_t le_psm, bool peer_con_init); + + +/** + **************************************************************************************** + * @brief Unregister an existing LECB connection + * + * @param[in] le_psm LE Protocol/Service Multiplexer + * @param[in] peer_con_init Info to know if connection is initiated by peer device + * + * @return GAP_ERR_NO_ERROR + **************************************************************************************** + */ +uint8_t gapm_lecb_unregister(uint16_t le_psm, bool peer_con_init); + +#endif // (BLE_LECB) + +/** + **************************************************************************************** + * @brief Return the maximal MTU value + * + * @param[out] Maximal MTU value + **************************************************************************************** + */ +uint16_t gapm_get_max_mtu(void); + +/** + **************************************************************************************** + * @brief Return the maximal MPS value + * + * @param[out] Maximal MPS value + **************************************************************************************** + */ +uint16_t gapm_get_max_mps(void); + + + +/** + **************************************************************************************** + * @brief Check If Service changed feature is enabled or not + * + * @return true if enabled, false else. + * + **************************************************************************************** + */ +bool gapm_svc_chg_en(void); + +#if (RW_DEBUG) +/** + **************************************************************************************** + * @brief Check If Debug mode feature is enabled or not + * + * @return true if enabled, false else. + * + **************************************************************************************** + */ +bool gapm_dbg_mode_en(void); + +/** + **************************************************************************************** + * @brief Force the GAP service start handle + **************************************************************************************** + */ +void gapm_set_svc_start_hdl(uint16_t start_hdl); +#endif // (RW_DEBUG) + +/** + **************************************************************************************** + * Retrieve if current connection index is used for a discovery purpose such as + * Name discovery + * + * @param conidx Index of the specific connection + * + * @return true if connection has a discovery purpose, False else + **************************************************************************************** + */ +bool gapm_is_disc_connection(uint8_t conidx); + +/// @} GAPM + +#endif /* _GAPM_H_ */ diff --git a/services/ble_stack/hl/inc/gattc.h b/services/ble_stack/hl/inc/gattc.h new file mode 100644 index 0000000..df2972d --- /dev/null +++ b/services/ble_stack/hl/inc/gattc.h @@ -0,0 +1,163 @@ +#ifndef GATTC_H_ +#define GATTC_H_ + +/** + **************************************************************************************** + * @addtogroup GATTC Generic Attribute Profile Controller + * @ingroup GATT + * @brief Generic Attribute Profile Controller. + * + * This GATT module is responsible for providing an API for all attribute related operations + * related to a BLE connection. + * It is responsible for all the service framework activities using the Attribute protocol + * for discovering services and for reading and writing characteristic values on a peer device. + * To achieve this, the GATT interfaces with @ref ATTC "ATTC" and the @ref ATTS "ATTS". + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +/* kernel task */ +#include "rwip_config.h" +#if (BLE_GATTC) + +#include "co_list.h" + + +/* + * DEFINES + **************************************************************************************** + */ + +/// Operation type +enum gattc_op_type +{ + #if (BLE_ATTS) + /// Operation used to Server Request operations + GATTC_OP_SERVER, + #endif // (BLE_ATTS) + + #if (BLE_ATTC) + /// Operation used to Client Request operations + GATTC_OP_CLIENT, + /// Service Discovery Procedure operation + GATTC_OP_SDP, + #endif // (BLE_ATTC) + + /// Max number of operations + GATTC_OP_MAX +}; + +/* + * TYPES DEFINITIONS + **************************************************************************************** + */ + +#if (BLE_ATTC) +/// Attribute Client environment variable requirements +struct attc_env +{ + /// List of ATT message used to aggregate long value in a single buffer. + struct co_list rsp_list; + /// List that contains peer device event registration + struct co_list reg_evt; + /// List that contains data for service discovery + struct co_list sdp_data; +}; +#endif // (BLE_ATTC) + +#if (BLE_ATTS) +/// Attribute server environment variables +struct atts_env +{ + /// This is used to merge save all the prepare write request received , + /// before receiving the execute or cancel or disconnection. + struct co_list prep_wr_req_list; + /// This list is used to put any data in order to send a response to peer device + struct co_list rsp; + /// This structure is used to store in cache latest attribute read value + struct gattc_read_cfm* read_cache; + /// pointer to the PDU which is currently handled by ATTS + struct l2cc_pdu_recv_ind* pdu; +}; +#endif // (BLE_ATTS) + +/// GATT controller environment variable structure. +struct gattc_env_tag +{ + /// Request operation Kernel message + void* operation[GATTC_OP_MAX]; + + #if (BLE_ATTC) + struct attc_env client; + #endif // (BLE_ATTC) + + #if (BLE_ATTS) + struct atts_env server; + #endif // (BLE_ATTS) + + /// Current MTU Size + uint16_t mtu_size; + + /// A transaction timeout occurs, reject next attribute commands + bool trans_timeout; +}; +/* + * MACRO DEFINITIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Created link connection parameters (from bond data) has been set, connection + * ready to be used. + * + * @param[in] conidx Connection Index + * + **************************************************************************************** + */ +void gattc_con_enable(uint8_t conidx); + + +/** + **************************************************************************************** + * @brief Gets the negotiated MTU. This function gets the negotiated MTU. + * + * @param[in] idx connection record index + * + * @return MTU negotiated + * + **************************************************************************************** + */ +uint16_t gattc_get_mtu(uint8_t idx); + +/** + **************************************************************************************** + * @brief Sets the negotiated MTU This function stores the negotiated MTU. + * + * @param[in] idx connection record index + * @param[in] mtu negotiated MTU + * + * @return status indicates if the MTU setting operation is successful + * + **************************************************************************************** + */ +void gattc_set_mtu(uint8_t idx, uint16_t mtu); + + + +#endif /* (BLE_GATTC) */ + +/// @} GATTC +#endif // GATTC_H_ diff --git a/services/ble_stack/hl/inc/gattm.h b/services/ble_stack/hl/inc/gattm.h new file mode 100644 index 0000000..b6270e0 --- /dev/null +++ b/services/ble_stack/hl/inc/gattm.h @@ -0,0 +1,108 @@ +#ifndef GATTM_H_ +#define GATTM_H_ + + + +/** + **************************************************************************************** + * @addtogroup GATTM Generic Attribute Profile Manager + * @ingroup GATT + * @brief Generic Attribute Profile. + * + * The GATT manager module is responsible for providing an API for all action operations + * not related to a connection. It's responsible to managing internal database. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +/* kernel task */ +#include "rwip_config.h" + +#if (BLE_CENTRAL || BLE_PERIPHERAL) +#include +#include + +/* + * DEFINES + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialization of the GATT manager module. + * This function performs all the initialization steps of the GATT module. + * + * @param[in] reset true if it's requested by a reset; false if it's boot initialization + * + **************************************************************************************** + */ +void gattm_init(bool reset); + + +/** + **************************************************************************************** + * @brief Initialize GATT attribute database + * + * @param[in] start_hdl Service Start Handle + * @param[in] svc_chg_en Service Change feature enabled + * + * @return status code of attribute database initialization + * Command status code: + * - @ref ATT_ERR_NO_ERROR: If database creation succeeds. + * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter + nb of attribute override + * some existing services handles. + * - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer. + * or of new attribute cannot be added because all expected + * attributes already add + **************************************************************************************** + */ +uint8_t gattm_init_attr(uint16_t start_hdl, bool svc_chg_en); + +/** + **************************************************************************************** + * @brief Initialize GATT resources for connection. + * + * @param[in] conidx connection record index + * @param[in] role device role after connection establishment + * + **************************************************************************************** + */ +void gattm_create(uint8_t conidx); +/** + **************************************************************************************** + * @brief Cleanup GATT resources for connection + * + * @param[in] conidx connection record index + * + **************************************************************************************** + */ +void gattm_cleanup(uint8_t conidx); + +#ifdef __GATT_OVER_BR_EDR__ +void gattm_enable(uint8_t conidx); +void gattm_set_mtu(uint8_t idx, uint16_t mtu); +#endif + +#if (BLE_ATTS) +/** + **************************************************************************************** + * @brief Return the start handle of the GATT service in the database * + **************************************************************************************** + */ +uint16_t gattm_svc_get_start_hdl(void); +#endif //(BLE_ATTS) +#endif /* (BLE_CENTRAL || BLE_PERIPHERAL) */ + +/// @} GATTM +#endif // GATTM_H_ diff --git a/services/ble_stack/hl/inc/l2cc.h b/services/ble_stack/hl/inc/l2cc.h new file mode 100644 index 0000000..95f2d34 --- /dev/null +++ b/services/ble_stack/hl/inc/l2cc.h @@ -0,0 +1,244 @@ +#ifndef L2CC_H_ +#define L2CC_H_ + +/** + **************************************************************************************** + * @addtogroup L2CC L2CAP Controller + * @ingroup L2C + * @brief L2CAP block for data processing and per device connection + * + * The L2CC is responsible for all the data processing related + * functions of the L2CAP block per device connection. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_L2CC) + +#include "l2cc_task.h" +#include "l2cc_pdu.h" + +#include +#include +#include "co_list.h" +#include "ke_task.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Generic way to creates and allocate a Signaling PDU message that can be then + * sent to peer device + * + * @param[in] conidx Connection Index + * @param[in] code PDU code + * @param[in] src_id Source task ID + * + * @return Pointer to the PDU payload + **************************************************************************************** + */ +#define L2CC_SIG_PDU_ALLOC(conidx, code, src_id, type) \ + ((struct type*) l2cc_pdu_alloc(conidx, L2C_CID_LE_SIGNALING, code, src_id, 0)) + +/// from PDU, retrieve the send command +#define L2CC_PDU_TO_CMD(_pdu) \ + ((struct l2cc_pdu_send_cmd*) (((uint8_t*)_pdu) - offsetof(struct l2cc_pdu_send_cmd, pdu.data.code))) + +/// from PDU, retrieve the receive indication +#define L2CC_PDU_TO_IND(_pdu) \ + ((struct l2cc_pdu_recv_ind*) (((uint8_t*)_pdu) - offsetof(struct l2cc_pdu_recv_ind, pdu.data.code))) + + +/** + **************************************************************************************** + * @brief Generic way to creates and allocate a SMP PDU message that can be then sent to + * peer device + * + * @param[in] conidx Connection Index + * @param[in] code PDU code + * @param[in] src_id Source task ID + * + * @return Pointer to the PDU payload + **************************************************************************************** + */ +#define L2CC_SMP_PDU_ALLOC(conidx, code, src_id, type) \ + ((struct type*) l2cc_pdu_alloc(conidx, L2C_CID_SECURITY, code, src_id, 0)) + + +/** + **************************************************************************************** + * @brief Generic way to creates and allocate an ATT PDU message that can be then sent to + * peer device + * + * @param[in] conidx Connection Index + * @param[in] code PDU code + * @param[in] src_id Source task ID + * + * @return Pointer to the PDU payload + **************************************************************************************** + */ +#define L2CC_ATT_PDU_ALLOC(conidx, code, src_id, type)\ + ((struct type*) l2cc_pdu_alloc(conidx, L2C_CID_ATTRIBUTE, code, src_id, 0)) + + +/** + **************************************************************************************** + * @brief Generic way to creates and allocate an ATT PDU message that can be then sent to + * peer device + * + * @param[in] conidx Connection Index + * @param[in] code PDU code + * @param[in] src_id Source task ID + * @param[in] length Dynamic payload length to allocate + * + * @return Pointer to the PDU payload + **************************************************************************************** + */ +#define L2CC_ATT_PDU_ALLOC_DYN(conidx, code, src_id, type, length)\ + ((struct type*) l2cc_pdu_alloc(conidx, L2C_CID_ATTRIBUTE, code, src_id, length)) + +/* + * INTERNAL MESSAGES API TYPES + **************************************************************************************** + */ + + + +/// Send Debug PDU data +struct l2cc_dbg_pdu_send_cmd +{ + /// L2CC request type (@see enum l2cc_operation): + /// - L2CC_DBG_PDU_SEND: Send a PDU + uint8_t operation; + /// offset value information + uint16_t offset; + /// PDU Data + struct l2cc_dbg_pdu pdu; +}; + +/// Debug PDU data received +struct l2cc_dbg_pdu_recv_ind +{ + /// Status information + uint8_t status; + /// offset value information + uint16_t offset; + /// PDU Data + struct l2cc_dbg_pdu pdu; +}; + +/// Send Legacy PDU data +struct l2cc_pdu_send_cmd +{ + /// L2CC request type (@see enum l2cc_operation): + /// - L2CC_PDU_SEND: Send internal LE Legacy PDU + uint8_t operation; + /// offset value information + uint16_t offset; + /// PDU Data + struct l2cc_pdu pdu; +}; + + +/// Legacy PDU data received +struct l2cc_pdu_recv_ind +{ + /// Status information + uint8_t status; + /// offset value information + uint16_t offset; + /// PDU Data + struct l2cc_pdu pdu; +}; + +/// Operation type +enum l2cc_op_type +{ + /// Operation used for signaling protocol message exchange + L2CC_OP_SIG = 0x00, + /// Max number of operations + L2CC_OP_MAX, +}; + +/* + * STRUCTURES + **************************************************************************************** + */ + + + +/// L2CAP environment structure +struct l2cc_env_tag +{ + /// Ongoing operation + void* operation[L2CC_OP_MAX]; + + /// Buffer in TX queue + struct co_list tx_queue; + /// Buffer currently receiving data + struct ke_msg* rx_buffer; + #if (BLE_LECB) + /// List of LE credit based connections + struct co_list lecb_list; + #endif // (BLE_LECB) + + /// Length of PDU still expected + uint16_t rx_pdu_rem_len; + +}; + + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Generic way to creates and allocate a PDU message that can be then sent to peer + * device + * + * @note use L2CC_SIG_PDU_ALLOC, L2CC_SMP_PDU_ALLOC, L2CC_ATT_PDU_ALLOC + * or L2CC_ATT_PDU_ALLOC_DYN instead of direct function call + * + * @param[in] conidx Connection Index + * @param[in] cid Channel Identifier + * @param[in] code PDU code + * @param[in] src_id Source task ID + * @param[in] length Dynamic payload length to allocate + * + * @return Generic pointer to the PDU payload + **************************************************************************************** + */ +void* l2cc_pdu_alloc(uint8_t conidx, uint16_t cid, uint8_t code, ke_task_id_t src_id, uint16_t length); + +/** + **************************************************************************************** + * @brief Generic way to send the PDU message + * + * @param[in] pdu PDU message to send to peer device + **************************************************************************************** + */ +void l2cc_pdu_send(void* pdu); + +#ifdef __GATT_OVER_BR_EDR__ +void l2cc_data_rec_over_bt(uint8_t* ptrData, uint16_t dataLen); +#endif + +#endif //(BLE_L2CC) + +/// @} L2CC + +#endif // L2CC_H_ diff --git a/services/ble_stack/hl/inc/l2cc_pdu.h b/services/ble_stack/hl/inc/l2cc_pdu.h new file mode 100644 index 0000000..edf987c --- /dev/null +++ b/services/ble_stack/hl/inc/l2cc_pdu.h @@ -0,0 +1,1092 @@ +#ifndef _L2CC_PDU_H_ +#define _L2CC_PDU_H_ + +/** + **************************************************************************************** + * @addtogroup L2CC_PDU L2Cap Controller PDU generator/extractor + * @ingroup L2CC + * @brief This module is in charge to pack or unpack L2CAP packets + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "co_bt.h" +#include "gap.h" +#include "att.h" +#include "compiler.h" + +/* + * MACROS + **************************************************************************************** + */ + + +/* + * DEFINES + **************************************************************************************** + */ + +/// Minimal authorized MTU value (defined by Bluetooth SIG) +#define L2C_MIN_LE_MTUSIG (23) + +/// L2CAP mode supported for BLE - only mode accepted +#define L2C_MODE_BASIC_L2CAP (0x00) + +/// Packet partition +#define L2C_CID_LEN (2) +#define L2C_LENGTH_LEN (2) +#define L2C_CODE_LEN (1) +#define L2C_HEADER_LEN (L2C_CID_LEN + L2C_LENGTH_LEN) +#define L2C_SDU_LEN (2) +#define L2C_LECB_HEADER_LEN (L2C_HEADER_LEN + L2C_SDU_LEN) + +/// Maximum credit +#define L2C_LECB_MAX_CREDIT 0xFFFF + + +/* result for connection parameter update response */ +#define L2C_CONN_PARAM_ACCEPT 0x0000 +#define L2C_CONN_PARAM_REJECT 0x0001 + +/* command reject reasons */ +enum l2cc_pdu_err +{ + L2C_CMD_NOT_UNDERSTOOD = 0x0000, + L2C_MTU_SIG_EXCEEDED = 0x0001, + L2C_INVALID_CID = 0x0002, +}; + +/// Check if channel ID is within the correct range +#define L2C_IS_DYNAMIC_CID(cid) ((cid >= L2C_CID_DYN_MIN) && (cid <= L2C_CID_DYN_MAX)) + +/// Check if LE PSM is within the correct range +#define L2C_IS_VALID_LEPSM(lepsm) (lepsm != L2C_LEPSM_RESERVED) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/** L2CAP LE PSM limits */ +enum l2cc_lepsm_limits +{ + /// Reserved + L2C_LEPSM_RESERVED = 0x0000, + /// Fixed minimum range SIG assigned + L2C_LEPSM_FIXED_MIN = 0x0001, + /// Fixed maximum range SIG assigned + L2C_LEPSM_FIXED_MAX = 0x007F, + /// Dynamic minimum range SIG assigned + L2C_LEPSM_DYN_MIN = 0x0080, + /// Dynamic maximum range SIG assigned + L2C_LEPSM_DYN_MAX = 0x00FF, + /// Reserved minimum range SIG assigned + L2C_LEPSM_RSV_MIN = 0x0100, + /// Reserved maximum range SIG assigned + L2C_LEPSM_RSV_MAX = 0xFFFF, +}; + +/** L2CAP channels id */ +enum l2cc_cid +{ + /// Reserved channel id + L2C_CID_RESERVED = 0x0000, + /// Attribute channel id + L2C_CID_ATTRIBUTE = 0x0004, + /// Signaling channel id + L2C_CID_LE_SIGNALING = 0x0005, + /// Security channel id + L2C_CID_SECURITY = 0x0006, + /// Dynamically allocated minimum range + L2C_CID_DYN_MIN = 0x0040, + /// Dynamically allocated maximum range + L2C_CID_DYN_MAX = 0x007F, +}; + + +/// signaling codes +enum l2cc_signal_code +{ + /// Reserved code + L2C_CODE_RESERVED = 0x00, + /// Reject request + L2C_CODE_REJECT = 0x01, + /// Connection request + L2C_CODE_CONNECTION_REQ = 0x02, + /// Connection response + L2C_CODE_CONNECTION_RESP = 0x03, + /// Configuration request + L2C_CODE_CONFIGURATION_REQ = 0x04, + /// Configuration response + L2C_CODE_CONFIGURATION_RESP = 0x05, + /// Disconnection request + L2C_CODE_DISCONNECTION_REQ = 0x06, + /// Disconnection response + L2C_CODE_DISCONNECTION_RESP = 0x07, + /// Echo request + L2C_CODE_ECHO_REQ = 0x08, + /// Echo response + L2C_CODE_ECHO_RESP = 0x09, + /// Information request + L2C_CODE_INFORMATION_REQ = 0x0A, + /// Information response + L2C_CODE_INFORMATION_RESP = 0x0B, + /// Create channel request + L2C_CODE_CREATE_CHANNEL_REQ = 0x0C, + /// Create channel response + L2C_CODE_CREATE_CHANNEL_RESP = 0x0D, + /// Move channel request + L2C_CODE_MOVE_CHANNEL_REQ = 0x0E, + /// Move channel response + L2C_CODE_MOVE_CHANNEL_RESP = 0x0F, + /// Move channel confirmation + L2C_CODE_MOVE_CHANNEL_CFM = 0x10, + /// Move channel confirmation response + L2C_CODE_MOVE_CHANNEL_CFM_RESP = 0x11, + /// Connection Parameter Update Request + L2C_CODE_CONN_PARAM_UPD_REQ = 0x12, + /// Connection Parameter Update Response + L2C_CODE_CONN_PARAM_UPD_RESP = 0x13, + /// LE Credit Based Connection request + L2C_CODE_LE_CB_CONN_REQ = 0x14, + /// LE Credit Based Connection response + L2C_CODE_LE_CB_CONN_RESP = 0x15, + /// LE Flow Control Credit + L2C_CODE_LE_FLOW_CONTROL_CREDIT = 0x16, + + /// max number of signaling codes + L2C_CODE_SIGNALING_MAX +}; + + +/// security codes +enum l2cc_security_code +{ + /// Pairing Request + L2C_CODE_PAIRING_REQUEST = 0x01, + /// Pairing Response + L2C_CODE_PAIRING_RESPONSE = 0x02, + /// Pairing Confirm + L2C_CODE_PAIRING_CONFIRM = 0x03, + /// Pairing Random + L2C_CODE_PAIRING_RANDOM = 0x04, + /// Pairing Failed + L2C_CODE_PAIRING_FAILED = 0x05, + /// Encryption Information + L2C_CODE_ENCRYPTION_INFORMATION = 0x06, + /// Master Identification + L2C_CODE_MASTER_IDENTIFICATION = 0x07, + /// Identity Information + L2C_CODE_IDENTITY_INFORMATION = 0x08, + /// Identity Address Information + L2C_CODE_IDENTITY_ADDRESS_INFORMATION = 0x09, + /// Signing Information + L2C_CODE_SIGNING_INFORMATION = 0x0A, + /// Security Request + L2C_CODE_SECURITY_REQUEST = 0x0B, + // Pairing Public Keys + L2C_CODE_PUBLIC_KEY = 0x0C, + // Pairing DHKey Check + L2C_CODE_DHKEY_CHECK = 0x0D, + // Pairing Keypress Notification + L2C_CODE_KEYPRESS_NOTIFICATION = 0x0E, + /// max number of security codes + L2C_CODE_SECURITY_MAX +}; + + +/// attribute protocol PDU codes +enum l2cc_attribute_code +{ + /// Error response + L2C_CODE_ATT_ERR_RSP = 0x01, + /// Exchange MTU Request + L2C_CODE_ATT_MTU_REQ = 0x02, + /// Exchange MTU Response + L2C_CODE_ATT_MTU_RSP = 0x03, + /// Find Information Request + L2C_CODE_ATT_FIND_INFO_REQ = 0x04, + /// Find Information Response + L2C_CODE_ATT_FIND_INFO_RSP = 0x05, + /// Find By Type Value Request + L2C_CODE_ATT_FIND_BY_TYPE_REQ = 0x06, + /// Find By Type Value Response + L2C_CODE_ATT_FIND_BY_TYPE_RSP = 0x07, + /// Read By Type Request + L2C_CODE_ATT_RD_BY_TYPE_REQ = 0x08, + /// Read By Type Response + L2C_CODE_ATT_RD_BY_TYPE_RSP = 0x09, + /// Read Request + L2C_CODE_ATT_RD_REQ = 0x0A, + /// Read Response + L2C_CODE_ATT_RD_RSP = 0x0B, + /// Read Blob Request + L2C_CODE_ATT_RD_BLOB_REQ = 0x0C, + /// Read Blob Response + L2C_CODE_ATT_RD_BLOB_RSP = 0x0D, + /// Read Multiple Request + L2C_CODE_ATT_RD_MULT_REQ = 0x0E, + /// Read Multiple Response + L2C_CODE_ATT_RD_MULT_RSP = 0x0F, + /// Read by Group Type Request + L2C_CODE_ATT_RD_BY_GRP_TYPE_REQ = 0x10, + /// Read By Group Type Response + L2C_CODE_ATT_RD_BY_GRP_TYPE_RSP = 0x11, + /// Write Request + L2C_CODE_ATT_WR_REQ = 0x12, + /// Write Response + L2C_CODE_ATT_WR_RSP = 0x13, + /// Write Command + L2C_CODE_ATT_WR_CMD_INFO = 0x14, + L2C_CODE_ATT_WR_CMD = 0x52, + /// Signed Write Command + L2C_CODE_ATT_SIGN_WR_CMD_INFO = 0x15, + L2C_CODE_ATT_SIGN_WR_CMD = 0xD2, + /// Prepare Write Request + L2C_CODE_ATT_PREP_WR_REQ = 0x16, + /// Prepare Write Response + L2C_CODE_ATT_PREP_WR_RSP = 0x17, + /// Execute Write Request + L2C_CODE_ATT_EXE_WR_REQ = 0x18, + /// Execute Write Response + L2C_CODE_ATT_EXE_WR_RSP = 0x19, + /// Handle Value Notification + L2C_CODE_ATT_HDL_VAL_NTF = 0x1B, + /// Handle Value Indication + L2C_CODE_ATT_HDL_VAL_IND = 0x1D, + /// Handle Value Confirmation + L2C_CODE_ATT_HDL_VAL_CFM = 0x1E, + + /// max number of security codes + L2C_CODE_ATT_MAX +}; + +/// LE Connection oriented PDU codes +enum l2cc_le_connor_code +{ + /// Data frame + L2C_CODE_CON_DATA = 0x01, + + /// max number of connection oriented codes + L2C_CODE_CON_MAX +}; + +/// Result values for LE Credit Based Connection Response +enum l2cc_cb_resp_value +{ + /// connection successful + L2C_CB_CON_SUCCESS = 0x0000, + /// Reserved + L2C_CB_CON_RSV1, + /// Connection refused - LE_PSM not supported + L2C_CB_CON_LEPSM_NOT_SUPP, + /// Reserved + L2C_CB_CON_RSV2, + /// Connection refused - no resources available + L2C_CB_CON_NO_RES_AVAIL, + /// Connection refused - insufficient authentication + L2C_CB_CON_INS_AUTH, + /// Connection refused - insufficient authorization + L2C_CB_CON_INS_AUTHOR, + /// Connection refused - insufficient encryption key size + L2C_CB_CON_INS_EKS, + /// Connection Refused - insufficient encryption + L2C_CB_CON_INS_ENCRYPTION, + + /* ESR 09 error codes */ + /// Connection Refused - invalid Source CID + L2C_CB_CON_INVALID_SRC_CID, + /// Connection Refused - Source CID already allocated + L2C_CB_CON_SRC_CID_ALREADY_ALLOC, + /// Connection Refused - Unacceptable parameters + L2C_CB_CON_UNACCEPTABLE_PARAM +}; + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Disconnection Request +struct l2cc_disconnection_req +{ + /// Signaling code - 0x06 + uint8_t code; + /// Packet Identifier + uint8_t pkt_id; + /// data length + uint16_t length; + /// Destination CID + uint16_t dcid; + /// Source CID + uint16_t scid; +}; + +/// Disconnection Response +struct l2cc_disconnection_rsp +{ + /// Signaling code - 0x07 + uint8_t code; + /// Packet Identifier + uint8_t pkt_id; + /// data length + uint16_t length; + /// Destination CID + uint16_t dcid; + /// Source CID + uint16_t scid; +}; + +/// Connection Parameter Update Request +struct l2cc_update_param_req +{ + /// Signaling code - 0x12 + uint8_t code; + /// Packet Identifier + uint8_t pkt_id; + /// data length + uint16_t length; + /// minimum value for the connection event interval + uint16_t intv_min; + /// maximum value for the connection event interval + uint16_t intv_max; + /// slave latency parameter + uint16_t latency; + /// connection timeout parameter + uint16_t timeout; +}; + +/// Connection Parameter Update Response +struct l2cc_update_param_rsp +{ + /// Signaling code - 0x13 + uint8_t code; + /// Packet Identifier + uint8_t pkt_id; + /// data length + uint16_t length; + /// Result field indicates the response to the Connection Parameter Update Request + /// - 0x0000 Connection Parameters accepted + /// - 0x0001 Connection Parameters rejected + uint16_t response; +}; + +/// LE Credit based connection request +struct l2cc_lecb_req +{ + /// Signaling code - 0x14 + uint8_t code; + /// Packet Identifier + uint8_t pkt_id; + /// data length + uint16_t length; + /// LE Protocol/Service Multiplexer + uint16_t le_psm; + /// Source CID + uint16_t scid; + /// Maximum Transmission Unit + uint16_t mtu; + /// Maximum PDU Size + uint16_t mps; + /// Initial credits + uint16_t initial_credits; +}; + +/// LE Credit based connection response +struct l2cc_lecb_rsp +{ + /// Signaling code - 0x15 + uint8_t code; + /// Packet Identifier + uint8_t pkt_id; + /// data length + uint16_t length; + /// Destination CID + uint16_t dcid; + /// Maximum Transmission Unit + uint16_t mtu; + /// Maximum PDU Size + uint16_t mps; + /// Initial credits + uint16_t initial_credits; + /// Result + uint16_t result; +}; + +/// LE Flow Control Credit +struct l2cc_le_flow_ctl_credit +{ + /// Signaling code - 0x16 + uint8_t code; + /// Packet Identifier + uint8_t pkt_id; + /// data length + uint16_t length; + /// CID + uint16_t cid; + /// Credits + uint16_t credits; +}; + +/// Command Reject +struct l2cc_reject +{ + /// Signaling code - 0x01 + uint8_t code; + /// Packet Identifier + uint8_t pkt_id; + /// data length + uint16_t length; + /// The Reason field describes why the Request packet was rejected + /// - 0x0000 Command not understood + /// - 0x0001 Signaling MTU exceeded + /// - 0x0002 Invalid CID in request + uint16_t reason; + /// Optional parameters total length + uint16_t opt_len; + ///16-byte array for optional parameters + uint8_t opt[__ARRAY_EMPTY]; +}; + + +/// Pairing Request +struct l2cc_pairing_req +{ + /// security code - 0x01 + uint8_t code; + /// IO Capability + uint8_t iocap; + /// OOB data flag + uint8_t oob; + /// AuthReq + uint8_t auth; + /// Maximum Encryption Key Size + uint8_t key_size; + /// Initiator Key Distribution + uint8_t ikey_dist; + /// Responder Key Distribution + uint8_t rkey_dist; +}; +/// Pairing Response +struct l2cc_pairing_rsp +{ + /// security code - 0x02 + uint8_t code; + /// IO Capability + uint8_t iocap; + /// OOB data flag + uint8_t oob; + /// AuthReq + uint8_t auth; + /// Maximum Encryption Key Size + uint8_t key_size; + /// Initiator Key Distribution + uint8_t ikey_dist; + /// Responder Key Distribution + uint8_t rkey_dist; +}; +/// Pairing Confirm +struct l2cc_pairing_cfm +{ + /// security code - 0x03 + uint8_t code; + ///Confirm value + uint8_t cfm_val[CFM_LEN]; +}; +/// Pairing Random +struct l2cc_pairing_random +{ + /// security code - 0x04 + uint8_t code; + ///Random value + uint8_t random[RAND_VAL_LEN]; +}; +/// Pairing Failed +struct l2cc_pairing_failed +{ + /// security code - 0x05 + uint8_t code; + /// The Reason field indicates why the pairing failed + uint8_t reason; +}; +/// Encryption Information +struct l2cc_encryption_inf +{ + /// security code - 0x06 + uint8_t code; + ///16-byte array for LTK value + uint8_t ltk[GAP_KEY_LEN]; +}; +/// Master Identification +struct l2cc_master_id +{ + /// security code - 0x07 + uint8_t code; + /// key diversifier + uint16_t ediv; + ///8-byte array for random number + uint8_t nb[GAP_RAND_NB_LEN]; +}; +/// Identity Information +struct l2cc_identity_inf +{ + /// security code - 0x08 + uint8_t code; + ///16-byte array for IRK value + uint8_t irk[GAP_KEY_LEN]; +}; +/// Identity Address Information +struct l2cc_id_addr_inf +{ + /// security code - 0x09 + uint8_t code; + /// BD Address Type + uint8_t addr_type; + /// BD Address + bd_addr_t addr; +}; +/// Signing Information +struct l2cc_signing_inf +{ + /// security code - 0x0A + uint8_t code; + ///16-byte array for CSRK value + uint8_t csrk[GAP_KEY_LEN]; +}; +/// Security Request +struct l2cc_security_req +{ + /// security code - 0x0B + uint8_t code; + /// AuthReq + uint8_t auth; +}; + +/// Public Key (x,y) +struct l2cc_publc_key +{ + /// security code - 0x0C + uint8_t code; + /// X and Y co-ordinates of the Public Key + uint8_t x[GAP_P256_KEY_LEN]; + uint8_t y[GAP_P256_KEY_LEN]; +}; + +/// DH Key Check +struct l2cc_dhkey_check +{ + /// security code - 0x0D + uint8_t code; + uint8_t check[DHKEY_CHECK_LEN]; +}; +/// Keypress Notification - PassKey method only +struct l2cc_keypress_noticication +{ + /// security code - 0x0E + uint8_t code; + + uint8_t notification_type; +}; + + +/* Attribute protocol PDUs */ + +/// Error response +struct l2cc_att_err_rsp +{ + /// Error Response - 0x01 + uint8_t code; + /// The request that generated this error response + uint8_t op_code; + /// The attribute handle that generated this error response + uint16_t handle; + ///The reason why the request has generated an error response + uint8_t reason; +}; + +/// Exchange MTU Request +struct l2cc_att_mtu_req +{ + /// Exchange MTU Request - 0x02 + uint8_t code; + /// Client Rx MTU size + uint16_t mtu_size; +}; + +/// Exchange MTU Response +struct l2cc_att_mtu_rsp +{ + /// Exchange MTU Response - 0x03 + uint8_t code; + /// Server Rx MTU size + uint16_t mtu_size; +}; + +/// Find Information Request +struct l2cc_att_find_info_req +{ + /// Find Information Request - 0x04 + uint8_t code; + /// First requested handle number + uint16_t shdl; + /// Last requested handle number + uint16_t ehdl; +}; + +/// Find Information Response +struct l2cc_att_find_info_rsp +{ + /// Find Information Response - 0x05 + uint8_t code; + /// The format of the information data. + uint8_t format; + /// Data length + uint16_t data_len; + ///The information data whose format is determined by the Format field + uint8_t data[__ARRAY_EMPTY]; +}; + +/// Find By Type Value Request +struct l2cc_att_find_by_type_req +{ + /// Find By Type Value Request - 0x06 + uint8_t code; + /// First requested handle number + uint16_t shdl; + /// Last requested handle number + uint16_t ehdl; + /// 2 octet UUID to find + uint16_t type; + /// Attribute value length + uint16_t val_len; + /// Attribute value to find + uint8_t val[__ARRAY_EMPTY]; +}; + +/// Find By Type Value Response +struct l2cc_att_find_by_type_rsp +{ + /// Find By Type Value Response - 0x07 + uint8_t code; + /// data length + uint16_t data_len; + /// A list of 1 or more Handle Informations. + uint8_t data[__ARRAY_EMPTY]; +}; + +/// Read By Type Request +struct l2cc_att_rd_by_type_req +{ + /// Read By Type Request - 0x08 + uint8_t code; + /// Starting Handle + uint16_t shdl; + /// Ending Handle + uint16_t ehdl; + /// Attribute uuid length + uint16_t uuid_len; + /// Attribute type uuid + uint8_t uuid[__ARRAY_EMPTY]; +}; + +/// Read By Type Response +struct l2cc_att_rd_by_type_rsp +{ + /// Read By Type Response - 0x09 + uint8_t code; + /// size of each attribute handle listed + uint8_t each_len; + /// Attribute Data length + uint16_t data_len; + /// A list of Attribute Data. + uint8_t data[__ARRAY_EMPTY]; +}; + +/// Read Request +struct l2cc_att_rd_req +{ + /// Read Request - 0x0A + uint8_t code; + /// Attribute Handle + uint16_t handle; +}; + +/// Read Response +struct l2cc_att_rd_rsp +{ + /// Read Response - 0x0B + uint8_t code; + /// value length + uint16_t value_len; + /// The value of the attribute with the handle given + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Read Blob Request +struct l2cc_att_rd_blob_req +{ + /// Read Blob Request - 0x0C + uint8_t code; + /// Attribute Handle + uint16_t handle; + /// The offset of the first octet to be read + uint16_t offset; +}; + +/// Read Blob Response +struct l2cc_att_rd_blob_rsp +{ + /// Read Blob Response - 0x0D + uint8_t code; + /// value length + uint16_t value_len; + /// Part of the value of the attribute with the handle given + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Read Multiple Request +struct l2cc_att_rd_mult_req +{ + /// Read Multiple Request - 0x0E + uint8_t code; + /// Number of handles + uint16_t nb_handles; + /// A set of two or more attribute handles. + uint16_t handles[__ARRAY_EMPTY]; +}; + +/// Read Multiple Response +struct l2cc_att_rd_mult_rsp +{ + /// Read Multiple Response - 0x0F + uint8_t code; + /// value length + uint16_t value_len; + /// A set of two or more values. + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Read by Group Type Request +struct l2cc_att_rd_by_grp_type_req +{ + /// Read by Group Type Request - 0x10 + uint8_t code; + /// First requested handle number + uint16_t shdl; + /// Last requested handle number + uint16_t ehdl; + /// Attribute uuid length + uint16_t uuid_len; + /// Attribute type uuid (2 or 16 octet UUID) + uint8_t uuid[__ARRAY_EMPTY]; +}; + +/// Read By Group Type Response +struct l2cc_att_rd_by_grp_type_rsp +{ + /// Read By Group Type Response - 0x11 + uint8_t code; + /// size of each attribute handle listed + uint8_t each_len; + /// Attribute Data length + uint16_t data_len; + /// A list of Attribute Data. + uint8_t data[__ARRAY_EMPTY]; +}; + +/// Write Request +struct l2cc_att_wr_req +{ + /// Write Request - 0x12 + uint8_t code; + /// The handle of the attribute to be written + uint16_t handle; + /// Value length + uint16_t value_len; + /// The value to be written to the attribute + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Write Response +struct l2cc_att_wr_rsp +{ + /// Write Response - 0x13 + uint8_t code; +}; + +/// Write Command +struct l2cc_att_wr_cmd +{ + /// Write Command - 0x52 + uint8_t code; + /// The handle of the attribute to be written + uint16_t handle; + /// Value length + uint16_t value_len; + /// The value to be written to the attribute + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Signed Write Command +struct l2cc_att_sign_wr_cmd +{ + /// Write Command - 0xD2 + uint8_t code; + /// The handle of the attribute to be written + uint16_t handle; + /// Attribute Data length + uint16_t value_len; + /// The value to be written to the attribute + /// + 12 bytes of signatures: + /// Authentication signature for the Attribute Upload, Attribute Handle and Attribute + /// Value Parameters + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Prepare Write Request +struct l2cc_att_prep_wr_req +{ + /// Prepare Write Request - 0x16 + uint8_t code; + /// The handle of the attribute to be written + uint16_t handle; + /// The offset of the first octet to be written + uint16_t offset; + /// Value length + uint16_t value_len; + /// The value to be written to the attribute + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Prepare Write Response +struct l2cc_att_prep_wr_rsp +{ + /// Prepare Write Response - 0x17 + uint8_t code; + /// The handle of the attribute to be written + uint16_t handle; + /// The offset of the first octet to be written + uint16_t offset; + /// Value length + uint16_t value_len; + /// The value to be written to the attribute + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Execute Write Request +struct l2cc_att_exe_wr_req +{ + /// Execute Write Request - 0x18 + uint8_t code; + /// 0x00 - Cancel all prepared writes + /// 0x01 - Immediately write all pending prepared values + uint8_t flags; +}; + +/// Execute Write Response +struct l2cc_att_exe_wr_rsp +{ + /// Prepare Write Response - 0x19 + uint8_t code; +}; + +/// Handle Value Notification +struct l2cc_att_hdl_val_ntf +{ + /// Handle Value Notification - 0x1B + uint8_t code; + /// The handle of the attribute to be written + uint16_t handle; + /// Value length + uint16_t value_len; + /// The current value of the attribute + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Handle Value Indication +struct l2cc_att_hdl_val_ind +{ + /// Handle Value Indication - 0x1D + uint8_t code; + /// The handle of the attribute to be written + uint16_t handle; + /// Value length + uint16_t value_len; + /// The current value of the attribute + uint8_t value[__ARRAY_EMPTY]; +}; + +/// Handle Value Confirmation +struct l2cc_att_hdl_val_cfm +{ + /// Handle Value Confirmation - 0x1E + uint8_t code; +}; + +/* LE Credit Based PDUs */ + +/// LE Generic send data request (includes total SDU Length) +struct l2cc_lecb_send_data_req +{ + /// Code variable (RFU) + uint8_t code; + /// SDU data length + uint16_t sdu_data_len; + /// Data + uint8_t sdu_data[__ARRAY_EMPTY]; +}; + + +struct l2cc_pdu_data_t +{ + /// L2Cap packet code. + uint8_t code; +}; + +/// Default L2Cap PDU definition +struct l2cc_pdu +{ + /// L2Cap Payload Length + uint16_t payld_len; + /// L2Cap Channel ID + uint16_t chan_id; + + /// Data PDU definition + union l2cc_pdu_data + { + /// L2Cap packet code. + uint8_t code; + + /* LE Credit Based packets */ + /// LE send first frame + struct l2cc_lecb_send_data_req send_lecb_data_req; + + /* Connection Signaling Packets */ + /// Command Reject + struct l2cc_reject reject; + /// Connection Parameter Update Request + struct l2cc_update_param_req update_req; + /// Connection Parameter Update Response + struct l2cc_update_param_rsp update_rsp; + /// LE Credit based connection request + struct l2cc_lecb_req credit_con_req; + /// LE Credit based connection response + struct l2cc_lecb_rsp credit_con_rsp; + /// LE Flow Control Credit + struct l2cc_le_flow_ctl_credit flow_ctl_credit; + /// LE disconnection request + struct l2cc_disconnection_req disc_req; + /// LE disconnection response + struct l2cc_disconnection_rsp disc_rsp; + + /* Security manager PDUs */ + /// Pairing Request + struct l2cc_pairing_req pairing_req; + /// Pairing Response + struct l2cc_pairing_rsp pairing_rsp; + /// Pairing Confirm + struct l2cc_pairing_cfm pairing_cfm; + /// Pairing Random + struct l2cc_pairing_random pairing_random; + /// Pairing Failed + struct l2cc_pairing_failed pairing_failed; + /// Encryption Information + struct l2cc_encryption_inf encryption_inf; + /// Master Identification + struct l2cc_master_id master_id; + /// Identity Information + struct l2cc_identity_inf identity_inf; + /// Identity Address Information + struct l2cc_id_addr_inf id_addr_inf; + /// Signing Information + struct l2cc_signing_inf signing_inf; + /// Security Request + struct l2cc_security_req security_req; + /// Public Keys + struct l2cc_publc_key public_key; + /// Key Press Notification + struct l2cc_keypress_noticication keypress_noticication; + /// DH Key Check + struct l2cc_dhkey_check dhkey_check; + /* Attribute protocol PDUs */ + /// Error response + struct l2cc_att_err_rsp err_rsp; + /// Exchange MTU Request + struct l2cc_att_mtu_req mtu_req; + /// Exchange MTU Response + struct l2cc_att_mtu_rsp mtu_rsp; + /// Find Information Request + struct l2cc_att_find_info_req find_info_req; + /// Find Information Response + struct l2cc_att_find_info_rsp find_info_rsp; + /// Find By Type Value Request + struct l2cc_att_find_by_type_req find_by_type_req; + /// Find By Type Value Response + struct l2cc_att_find_by_type_rsp find_by_type_rsp; + /// Read By Type Request + struct l2cc_att_rd_by_type_req rd_by_type_req; + /// Read By Type Response + struct l2cc_att_rd_by_type_rsp rd_by_type_rsp; + /// Read Request + struct l2cc_att_rd_req rd_req; + /// Read Response + struct l2cc_att_rd_rsp rd_rsp; + /// Read Blob Request + struct l2cc_att_rd_blob_req rd_blob_req; + /// Read Blob Response + struct l2cc_att_rd_blob_rsp rd_blob_rsp; + /// Read Multiple Request + struct l2cc_att_rd_mult_req rd_mult_req; + /// Read Multiple Response + struct l2cc_att_rd_mult_rsp rd_mult_rsp; + /// Read by Group Type Request + struct l2cc_att_rd_by_grp_type_req rd_by_grp_type_req; + /// Read By Group Type Response + struct l2cc_att_rd_by_grp_type_rsp rd_by_grp_type_rsp; + /// Write Request + struct l2cc_att_wr_req wr_req; + /// Write Response + struct l2cc_att_wr_rsp wr_rsp; + /// Write Command + struct l2cc_att_wr_cmd wr_cmd; + /// Signed Write Command + struct l2cc_att_sign_wr_cmd sign_wr_cmd; + /// Prepare Write Request + struct l2cc_att_prep_wr_req prep_wr_req; + /// Prepare Write Response + struct l2cc_att_prep_wr_rsp prep_wr_rsp; + /// Execute Write Request + struct l2cc_att_exe_wr_req exe_wr_req; + /// Execute Write Response + struct l2cc_att_exe_wr_rsp exe_wr_rsp; + /// Handle Value Notification + struct l2cc_att_hdl_val_ntf hdl_val_ntf; + /// Handle Value Indication + struct l2cc_att_hdl_val_ind hdl_val_ind; + /// Handle Value Confirmation + struct l2cc_att_hdl_val_cfm hdl_val_cfm; + } data; +}; + +/// Default L2Cap DBG pdu definition +struct l2cc_dbg_pdu +{ + /// Data length + uint16_t length; + /// data + uint8_t data[__ARRAY_EMPTY]; +}; + +/// Default L2Cap SDU definition +struct l2cc_sdu; + + +/// @} L2CC_PDU + + +#endif /* _L2CC_PDU_H_ */ diff --git a/services/ble_stack/hl/inc/l2cm.h b/services/ble_stack/hl/inc/l2cm.h new file mode 100644 index 0000000..24029c5 --- /dev/null +++ b/services/ble_stack/hl/inc/l2cm.h @@ -0,0 +1,114 @@ +#ifndef L2CM_H_ +#define L2CM_H_ + +/** + **************************************************************************************** + * @addtogroup L2C Logical Link Control and Adaptation Protocol + * @ingroup HOST + * @brief Logical Link Control and Adaptation Protocol - BLE Host. + * + * The L2C module is responsible for L2CAP provides connection-oriented + * and connection-less data services to upper layer protocols with protocol + * multiplexing capability and segmentation and re-assembly operation. + * + * @{ + **************************************************************************************** + */ +/** + **************************************************************************************** + * @addtogroup L2CM L2CAP Manager + * @ingroup L2C + * @brief L2CAP block for signaling and resource management functions + * + * The L2CM is an internal L2CAP block responsible for managing + * the signaling messages and propagation of connection and disconnection + * related L2CAP messages within the Host. + * + * @{ + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_L2CM) +#include +#include + +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Create and Initialize the L2CAP manager task. + * + * @param[in] reset true if it's requested by a reset; false if it's boot initialization + * + **************************************************************************************** + */ +void l2cm_init(bool reset); + + + +/** + **************************************************************************************** + * @brief Allocates an L2CAP resource. + * + * @param[in] conidx connection index + * + **************************************************************************************** + */ +void l2cm_create(uint8_t conidx); + +/** + **************************************************************************************** + * @brief De-initializes the L2CAP resources for specified link. + * + * @param[in] conidx connection index + * + **************************************************************************************** + */ +void l2cm_cleanup(uint8_t conidx); + + +/** + **************************************************************************************** + * @brief Sets link layer buffer size capacity + * + * @param[in] pkt_len length of the packet + * @param[in] nb_acl number of acl + * + **************************************************************************************** + */ +void l2cm_set_link_layer_buff_size(uint16_t pkt_len, uint16_t nb_acl); + +/** + **************************************************************************************** + * @brief Retrieve number of low layer buffer available + * + * @return Number of low layer buffer available + **************************************************************************************** + */ +uint16_t l2cm_get_nb_buffer_available(void); + +/// @} L2CM + +#endif //(BLE_L2CM) + +#endif // L2CM_H_ diff --git a/services/ble_stack/hl/inc/prf.h b/services/ble_stack/hl/inc/prf.h new file mode 100644 index 0000000..dc3953a --- /dev/null +++ b/services/ble_stack/hl/inc/prf.h @@ -0,0 +1,293 @@ +#ifndef _PRF_H_ +#define _PRF_H_ + +/** + **************************************************************************************** + * @addtogroup PROFILE PROFILES + * @ingroup ROOT + * @brief Bluetooth Low Energy Host Profiles + * + * The PROFILE of the stack contains the profile layers (@ref PROX "PROXIMITY", + * @ref HTP "HTP",@ref FIND "FIND ME" @ref BPS "Blood Pressure"). + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @addtogroup PRF + * @ingroup PROFILE + * @brief Definitions of Profile management API + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_PROFILES) + +#include "ke_task.h" +#include "gapm_task.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/** + * Profile task fields + * + * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + * +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + * | MI | TASK Number | + * +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + * + * Bit [0-14] : Task number value + * Bit [15] : Task is multi-instantiated (Connection index is conveyed) + */ +enum prf_perm_mask +{ + /// Task number value + PERM_MASK_PRF_TASK = 0x7FFF, + PERM_POS_PRF_TASK = 0, + /// Task is multi-instantiated + PERM_MASK_PRF_MI = 0x8000, + PERM_POS_PRF_MI = 15, +}; +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + +/// Profile Environment Data +typedef struct prf_env +{ + /// Application Task Number - if MSB bit set, Multi-Instantiated task + ke_task_id_t app_task; + /// Profile Task Number - if MSB bit set, Multi-Instantiated task + ke_task_id_t prf_task; +} prf_env_t; + + + +/// Profile task environment variable definition to dynamically allocate a Task. +struct prf_task_env +{ + /// Profile Task description + struct ke_task_desc desc; + /// pointer to the allocated memory used by profile during runtime. + prf_env_t* env; + /// Profile Task Number + ke_task_id_t task; + /// Profile Task Identifier + ke_task_id_t id; +}; + +/** + **************************************************************************************** + * @brief Initialization of the Profile module. + * This function performs all the initializations of the Profile module. + * - Creation of database (if it's a service) + * - Allocation of profile required memory + * - Initialization of task descriptor to register application + * - Task State array + * - Number of tasks + * - Default task handler + * + * @param[out] env Collector or Service allocated environment data. + * @param[in|out] start_hdl Service start handle (0 - dynamically allocated), only applies for services. + * @param[in] app_task Application task number. + * @param[in] sec_lvl Security level (AUTH, EKS and MI field of @see enum attm_value_perm_mask) + * @param[in] param Configuration parameters of profile collector or service (32 bits aligned) + * + * @return status code to know if profile initialization succeed or not. + **************************************************************************************** + */ +typedef uint8_t (*prf_init_fnct) (struct prf_task_env* env, uint16_t* start_hdl, uint16_t app_task, uint8_t sec_lvl, void* params); + +/** + **************************************************************************************** + * @brief Destruction of the Profile module - due to a reset for instance. + * This function clean-up allocated memory (attribute database is destroyed by another + * procedure) + * + * @param[in|out] env Collector or Service allocated environment data. + **************************************************************************************** + */ +typedef void (*prf_destroy_fnct) (struct prf_task_env* env); + +/** + **************************************************************************************** + * @brief Handles Connection creation + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + **************************************************************************************** + */ +typedef void (*prf_create_fnct) (struct prf_task_env* env, uint8_t conidx); + +/** + **************************************************************************************** + * @brief Handles Disconnection + * + * @param[in|out] env Collector or Service allocated environment data. + * @param[in] conidx Connection index + * @param[in] reason Detach reason + **************************************************************************************** + */ +typedef void (*prf_cleanup_fnct) (struct prf_task_env* env, uint8_t conidx, uint8_t reason); + +/// Profile task callbacks. +struct prf_task_cbs +{ + /// Initialization callback + prf_init_fnct init; + /// Destroy profile callback + prf_destroy_fnct destroy; + /// Connection callback + prf_create_fnct create; + /// Disconnection callback + prf_cleanup_fnct cleanup; +}; + + +/// Profile Manager environment structure +struct prf_env_tag +{ + /// Array of profile tasks that can be managed by Profile manager. + struct prf_task_env prf[BLE_NB_PROFILES]; +}; + +/* + * MACROS + **************************************************************************************** + */ + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ +extern struct prf_env_tag prf_env; + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Perform Profile initialization + * + * @param[in] reset Reset requested or basic initialization + **************************************************************************************** + */ +void prf_init(bool reset); + + +/** + **************************************************************************************** + * @brief Create Profile (collector or service) task creation and initialize it. + * + * @param[in|out] params Collector or Service parameter used for profile task creation + * @param[out] prf_task Allocated Task number + * + * @return status of adding profile task + **************************************************************************************** + */ +uint8_t prf_add_profile(struct gapm_profile_task_add_cmd * params, ke_task_id_t *prf_task); + + +/** + **************************************************************************************** + * @brief Link creation event, update profiles states. + * + * @param[in] conidx connection index + * + **************************************************************************************** + */ +void prf_create(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Link disconnection event, clean-up profiles. + * + * @param[in] conidx connection index + * @param[in] reason detach reason + * + **************************************************************************************** + */ +void prf_cleanup(uint8_t conidx, uint8_t reason); + + + +/** + **************************************************************************************** + * @brief Retrieve environment variable allocated for a profile + * + * @param[in] prf_id Profile Task Identifier + * + * @return Environment variable allocated for a profile + **************************************************************************************** + */ +prf_env_t* prf_env_get(uint16_t prf_id); + + +/** + **************************************************************************************** + * @brief Retrieve source profile task number value + * + * @param[in] env Profile Environment + * @param[in] conidx Connection index + * + * @return Source profile task number value + **************************************************************************************** + */ +ke_task_id_t prf_src_task_get(prf_env_t* env, uint8_t conidx); + +/** + **************************************************************************************** + * @brief Retrieve destination application task number value + * + * @param[in] env Profile Environment + * @param[in] conidx Connection index + * + * @return Destination application task number value + **************************************************************************************** + */ +ke_task_id_t prf_dst_task_get(prf_env_t* env, uint8_t conidx); + + +/** + **************************************************************************************** + * @brief Retrieve Task Identifier from Task number + * (automatically update index of task in returned task id) + * + * @param task Task number + * @return Task Identifier + **************************************************************************************** + */ +ke_task_id_t prf_get_id_from_task(ke_msg_id_t task); + +/** + **************************************************************************************** + * @brief Retrieve Task Number from Task Identifier + * (automatically update index of task in returned task id) + * + * @param id Task Identifier + * @return Task Number + **************************************************************************************** + */ +ke_task_id_t prf_get_task_from_id(ke_msg_id_t id); + +#endif // (BLE_PROFILES) + +/// @} PRF + +#endif /* _PRF_H_ */ diff --git a/services/ble_stack/hl/inc/prf_utils.h b/services/ble_stack/hl/inc/prf_utils.h new file mode 100644 index 0000000..e729665 --- /dev/null +++ b/services/ble_stack/hl/inc/prf_utils.h @@ -0,0 +1,278 @@ +#ifndef _PRF_UTILS_H_ +#define _PRF_UTILS_H_ + +/** + **************************************************************************************** + * @addtogroup PRF_UTILS + * @ingroup PROFILE + * + * @brief Definitions of shared profiles functions that can be used by several profiles + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" +#if (BLE_SERVER_PRF || BLE_CLIENT_PRF) +#include "ke_msg.h" +#include "prf_types.h" +#include "gattc_task.h" +#include "gapc.h" +#include "gapc_task.h" +#include "attm.h" +#include "prf.h" +#endif /* (BLE_SERVER_PRF || BLE_CLIENT_PRF) */ + +/* + * MACROS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Macro used to called the prf_client_get_env function. + * + * @param prf_id Profile Task ID (In Upper case, ex: HTPC, DISC, ...) + * @param type Profile task type (In lower case, ex: htpc, disc, ...) + **************************************************************************************** + */ +#define PRF_ENV_GET(prf_id, type) \ + ((struct type ## _env_tag *)prf_env_get((TASK_ID_##prf_id))) + + + + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +#if (BLE_BATT_SERVER) +/** + **************************************************************************************** + * @brief Pack Characteristic Presentation Format descriptor value + **************************************************************************************** + */ +void prf_pack_char_pres_fmt(uint8_t *packed_val, const struct prf_char_pres_fmt* char_pres_fmt); +#endif // (BLE_BATT_SERVER) + +#if (BLE_BATT_CLIENT) +/** + **************************************************************************************** + * @brief Unpack Characteristic Presentation Format descriptor value + **************************************************************************************** + */ +void prf_unpack_char_pres_fmt(const uint8_t *packed_val, struct prf_char_pres_fmt* char_pres_fmt); +#endif // (BLE_BATT_CLIENT) + +#if (BLE_CLIENT_PRF) +/** + **************************************************************************************** + * @brief Request peer device to read an attribute + * + * @param[in] prf_env Pointer to profile information + * + * @param conidx Connection index + * @param shdl Search Start Handle + * @param ehdl Search End Handle + * + * @param valhdl Value Handle + * + * @note: if attribute is invalid, nothing is registered + **************************************************************************************** + */ +void prf_read_char_send(prf_env_t *prf_env, uint8_t conidx, + uint16_t shdl, uint16_t ehdl, uint16_t valhdl); + + +/** + **************************************************************************************** + * @brief register attribute handle in GATT + * + * @param[in] prf_env Pointer to profile information + * + * @param conidx Connection index + * @param svc Service to register + * + * @note: if attribute is invalid, nothing is registered + **************************************************************************************** + */ +void prf_register_atthdl2gatt(prf_env_t *prf_env, uint8_t conidx, struct prf_svc *svc); + +/** + **************************************************************************************** + * @brief Unregister attribute handle in GATT + * + * @param[in] prf_env Pointer to profile information + * + * @param conidx Connection index + * @param svc Service to register + * + * @note: if attribute is invalid, nothing is registered + **************************************************************************************** + */ +void prf_unregister_atthdl2gatt(prf_env_t *prf_env, uint8_t conidx, struct prf_svc *svc); + +/** + **************************************************************************************** + * @brief Request service discovery on peer device. + * + * This request will be used to retrieve start and end handles of the service. + * + * @param[in] prf_env Pointer to profile information + * + * @param conidx Connection index + * @param uuid Service UUID + **************************************************************************************** + */ +void prf_disc_svc_send(prf_env_t *prf_env,uint8_t conidx, uint16_t uuid); + + +/** + **************************************************************************************** + * @brief Write peer characteristic using GATT. + * + * It will request write modification of peer handle + * + * @param[in] prf_env Pointer to profile information + * @param[in] conidx Connection index + * @param[in] handle Peer handle to modify + * @param[in] value New Peer handle value + * @param[in] length Value length + **************************************************************************************** + */ +void prf_gatt_write(prf_env_t *prf_env, uint8_t conidx, + uint16_t handle, uint8_t* value, uint16_t length, uint8_t operation); + +/** + **************************************************************************************** + * @brief Modify peer client configuration descriptor using GATT + * + * It will request write modification of peer client configuration descriptor handle + * + * @param[in] prf_env Pointer to profile information + * + * @param[in] conidx Connection index + * @param[in] handle Peer client configuration descriptor handle to modify + * + * @param[in] ntf_ind_cfg Indication/Notification configuration + **************************************************************************************** + */ +void prf_gatt_write_ntf_ind(prf_env_t *prf_env, uint8_t conidx, uint16_t handle, + uint16_t ntf_ind_cfg); + +/** + **************************************************************************************** + * @brief Check service characteristic validity + * + * For each characteristic in service it verifies handles. + * + * If some handles are not present, it checks if they shall be present or they are optional. + * + * @param nb_chars Number of Characteristics in the service + * @param chars Characteristics values (char handles, val handles, properties) + * @param chars_req Characteristics requirements. + * + * @return 0x1 if service is valid, 0x00 else. + **************************************************************************************** + */ +uint8_t prf_check_svc_char_validity(uint8_t nb_chars, + const struct prf_char_inf* chars, + const struct prf_char_def* chars_req); + +/** + **************************************************************************************** + * @brief Check service characteristic descriptors validity + * + * For each characteristic descriptors in service it verifies handles. + * + * If some handles are not present, according to characteristic properties it verify if + * descriptor is optional or not. + * + * @param descs_size Number of Characteristic descriptors in the service + * @param descs Characteristic descriptors values (handles) + * @param descs_req Characteristics descriptors requirements. + * + * @return 0x1 if service is valid, 0x00 else. + **************************************************************************************** + */ +uint8_t prf_check_svc_char_desc_validity(uint8_t descs_size, + const struct prf_char_desc_inf* descs, + const struct prf_char_desc_def* descs_req, + const struct prf_char_inf* chars); + +/** + **************************************************************************************** + * @brief Extract information of the service according to the service description + * + * @param param Service information + * @param nb_chars Length of provided arrays (chars and chars_req) + * @param chars_req Characteristics requirements + * @param chars Characteristics + * @param nb_descs Length of provided arrays (descs and descs_req) + * @param descs_req Descriptors requirements + * @param descs Descriptors + **************************************************************************************** + */ +void prf_extract_svc_info(const struct gattc_sdp_svc_ind* param, + uint8_t nb_chars, const struct prf_char_def* chars_req, struct prf_char_inf* chars, + uint8_t nb_descs, const struct prf_char_desc_def* descs_req, struct prf_char_desc_inf* descs); + +#endif //(BLE_CLIENT_PRF) + + +#if (BLE_CLIENT_PRF || BLE_TIP_SERVER || BLE_AN_SERVER || BLE_PAS_SERVER) + +/** + **************************************************************************************** + * @brief The function is used to send information about peer attribute value + * + * @param[in] prf_env Pointer to the profile environment variable + * @param[in] conidx Connection index + * @param[in] msg_id Profile message ID to trigger + * @param[in] status Response status code + * @param[in] read_ind GATT read message indication + **************************************************************************************** + */ +void prf_client_att_info_rsp(prf_env_t *prf_env, uint8_t conidx, uint16_t msg_id, + uint8_t status, struct gattc_read_ind const* read_ind); + +#endif //(BLE_CLIENT_PRF || BLE_TIP_SERVER || BLE_AN_SERVER || BLE_PAS_SERVER) + +#if (BLE_SERVER_PRF || BLE_CLIENT_PRF) +/** + **************************************************************************************** + * @brief Pack date time value + * + * @param[out] packed_date packed date time + * @param[in] date_time structure date time + * + * @return size of packed value + **************************************************************************************** + */ +uint8_t prf_pack_date_time(uint8_t *packed_date, const struct prf_date_time* date_time); + +/** + **************************************************************************************** + * @brief Unpack date time value + * + * @param[in] packed_date packed date time + * @param[out] date_time structure date time + * + * @return size of packed value + **************************************************************************************** + */ +uint8_t prf_unpack_date_time(uint8_t *packed_date, struct prf_date_time* date_time); + +#endif /* (BLE_SERVER_PRF || BLE_CLIENT_PRF) */ + +/// @} prf_utils + +#endif /* _PRF_UTILS_H_ */ diff --git a/services/ble_stack/hl/inc/prf_utils_128.h b/services/ble_stack/hl/inc/prf_utils_128.h new file mode 100644 index 0000000..06237a9 --- /dev/null +++ b/services/ble_stack/hl/inc/prf_utils_128.h @@ -0,0 +1,115 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +#ifndef _PRF_UTILS_128_H_ +#define _PRF_UTILS_128_H_ + +/** + **************************************************************************************** + * @addtogroup PRF_UTILS + * @ingroup PROFILE + * + * @brief Definitions of shared profiles functions that can be used by several profiles + * + * @{ + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#if (BLE_CLIENT_PRF) +#include "ke_msg.h" +#include "prf.h" +#include "prf_types.h" +#include "gattc_task.h" +#include "gapc.h" +#include "gapc_task.h" +#include "attm_db.h" +#endif /* (BLE_CLIENT_PRF) */ + +/* + * MACROS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + + +#if (BLE_CLIENT_PRF) + +/// Characteristic definition +struct prf_char_def_128 +{ + /// Characteristic UUID + uint8_t uuid[ATT_UUID_128_LEN]; + /// Requirement Attribute Flag + uint8_t req_flag; + /// Mandatory Properties + uint8_t prop_mand; +}; + +/** + **************************************************************************************** + * @brief Request service discovery with 128-bit UUID on peer device. + * + * This request will be used to retrieve start and end handles of the service. + * + * @param con_info Pointer to connection information (connection handle, app task id, + * profile task id) + * + * @param uuid_128 128-bit service UUID + **************************************************************************************** + */ +void prf_disc_svc_send_128(prf_env_t *prf_env, uint8_t conidx, uint8_t *uuid_128); + +/** + **************************************************************************************** + * @brief Check validity for service characteristic with 128-bit UUID + * + * For each characteristic in service it verifies handles. + * + * If some handles are not present, it checks if they shall be present or they are optional. + * + * @param nb_chars Number of Characteristics in the service + * @param chars Characteristics values (char handles, val handles, properties) + * @param chars_req Characteristics requirements. + * + * @return 0x1 if service is valid, 0x00 else. + **************************************************************************************** + */ +uint8_t prf_check_svc_char_validity_128(uint8_t nb_chars, + const struct prf_char_inf* chars, + const struct prf_char_def_128* chars_req); + +void prf_extract_svc_info_128(const struct gattc_sdp_svc_ind* param, + uint8_t nb_chars, const struct prf_char_def_128* chars_req, struct prf_char_inf* chars, + uint8_t nb_descs, const struct prf_char_desc_def* descs_req, struct prf_char_desc_inf* descs); + +#endif //(BLE_CLIENT_PRF) + + +/// @} prf_utils + +#endif /* _PRF_UTILS_128_H_ */ diff --git a/services/ble_stack/hl/inc/smpc.h b/services/ble_stack/hl/inc/smpc.h new file mode 100644 index 0000000..101e331 --- /dev/null +++ b/services/ble_stack/hl/inc/smpc.h @@ -0,0 +1,314 @@ +#ifndef SMPC_H_ +#define SMPC_H_ + +/** + **************************************************************************************** + * @addtogroup SMP Security Manager Protocol + * @ingroup HOST + * @brief Security Manager Protocol. + * + * The SMP is responsible for the over-all security policies of BLE. + * It defines methods for pairing and key distribution, handles encryption, + * data signing and privacy features such as random addressing generation and resolution. + * + * Pairing is performed to exchange pairing features and generate a short term + * key for link encryption. + * A transport specific key distribution is performed to + * share the keys that can be used to encrypt the link in the future + * reconnection process, signed data verification and random address + * resolution. + * + * There exist 3 phases in the complete security procedure: + * 1. Feature exchange (IO capabilities, OOB flags, Authentication Requirements, Key distributions) + * 2. Short Term Key generation + * Generation method depends on exchanged features: + * - Just Works - use Temporary key = 0 + * - PassKey Entry - use Temporary Key = 6-digit provided by user + * - Out of Band (OOB) - use Temporary Key = 16-octet key, available form OOB source + * 3. Transport Specific Key Distribution (TKDP)(LTK+EDIV+RAND_NB, IRK+ADDR, CSRK) + *--------------------------------------------------------------------- + * @addtogroup SMPC Security Manager Protocol Controller + * @ingroup SMP + * @brief Security Manager Protocol Controller. + * + * This block handles control of SM procedures for several possible existing connections, + * for which the security procedure may be conducted simultaneously. + * + * It allows flow control for HCI access to encryption and random number generation, used + * at different moments in the procedure. + * + * It handles PDU creation and sending through L2CAP, also their reception from L2CAP + * and interpretation. + * + * Other small utilities such as maximum key size determination and TKDP organization are + * implemented in SMPC. + * @{ + * + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_SMPC) +#include "co_bt.h" +#include "gap.h" +#include "gapc_task.h" +#include "ke_task.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// MAC length +#define SMPC_SIGN_MAC_LEN (8) +/// SignCounter length +#define SMPC_SIGN_COUNTER_LEN (4) +/// Signature length +#define SMPC_SIGN_LEN (SMPC_SIGN_MAC_LEN + SMPC_SIGN_COUNTER_LEN) + +/** + * Repeated Attempts Timer Configuration + */ +/// Repeated Attempts Timer default value (x10ms) +#define SMPC_REP_ATTEMPTS_TIMER_DEF_VAL (200) //2s +/// Repeated Attempts Timer max value (x10ms) +#define SMPC_REP_ATTEMPTS_TIMER_MAX_VAL (3000) //30s +/// Repeated Attempts Timer multiplier +#define SMPC_REP_ATTEMPTS_TIMER_MULT (2) + +/** + * Timeout Timer Configuration + */ +#define SMPC_TIMEOUT_TIMER_DURATION (3000) //30s + +#define SMPC_PUBLIC_KEY_256_COORD_LEN 0x20 +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +/// Information source. +enum smpc_addr_src +{ + /// Local info. + SMPC_INFO_LOCAL, + /// Peer info. + SMPC_INFO_PEER, + /// Maximum info source. + SMPC_INFO_MAX +}; + +/* + * STRUCTURES DEFINITION + **************************************************************************************** + */ + +/// Master ID Information Structure +struct smpc_mst_id_info +{ + // Encryption Diversifier + uint16_t ediv; + + // Random Number + uint8_t randnb[GAP_RAND_NB_LEN]; +}; + +#if (SECURE_CONNECTIONS) +struct smp_aes_cmac +{ + uint8_t* M; // pointer to memory allocated by calling function + uint8_t M_len; + uint8_t M_last[16]; + uint8_t X[16]; + uint8_t Y[16]; + uint8_t* K; //[16]; + uint8_t K1[16]; + uint8_t K2[16]; + uint8_t next_block; + uint8_t num_blocks; + uint8_t state; // Only 3 States - Idle, SubKey Generation, Block AES +}; + +struct smp_f4 +{ + uint8_t M[65]; + uint8_t X[16]; // The Key +}; + +struct smp_f5 +{ + uint8_t M[53]; + uint8_t* W; + uint8_t T[16]; + uint8_t SALT[16]; +}; + + +struct smp_f6 +{ + uint8_t W[16]; + uint8_t M[65]; +}; + +struct smp_g2 +{ + uint8_t X[16]; + uint8_t M[80]; +}; + +struct gapc_public_key +{ + uint8_t x[GAP_P256_KEY_LEN]; + uint8_t y[GAP_P256_KEY_LEN]; +}; + +#endif // (SECURE_CONNECTIONS) +/// Pairing Information +struct smpc_pair_info +{ + /// TK during Phase 2, LTK or IRK during Phase 3 + struct gap_sec_key key; + /// Pairing request command + struct gapc_pairing pair_req_feat; + /// Pairing response feature + struct gapc_pairing pair_rsp_feat; + /// Random number value + uint8_t rand[RAND_VAL_LEN]; + /// Remote random number value + uint8_t rem_rand[RAND_VAL_LEN]; + /// Confirm value to check + uint8_t conf_value[GAP_KEY_LEN]; + /// Pairing Method + uint8_t pair_method; + /// Authentication level + uint8_t auth; + /// check that LTK exchanged during pairing + bool ltk_exchanged; + /// Key to be exchanged (transmitted or to be received) + uint8_t keys_dist; + + + #if (SECURE_CONNECTIONS) + // AES_CMAC Info + struct smp_aes_cmac* aes_cmac; + // Structure for Secure Connections Crypto functions + struct smp_f4* f4_info; + struct smp_f5* f5_info; + struct smp_f6* f6_info; + struct smp_g2* g2_info; + + bool dh_key_calculation_complete; + + uint8_t MacKey[GAP_KEY_LEN]; + uint8_t dh_key_check_peer[DHKEY_CHECK_LEN]; + uint8_t dh_key_local[DH_KEY_LEN]; + + uint8_t dh_key_check_local[DHKEY_CHECK_LEN]; + bool dh_key_check_received_from_peer; + + public_key_t peer_public_key; + + uint8_t passkey_bit_count; + uint32_t passkey; + + // Required for OOB + uint8_t peer_r[GAP_KEY_LEN]; + uint8_t local_r[GAP_KEY_LEN]; + bool peer_rand_received; + bool peer_confirm_received; + #endif // (SECURE_CONNECTIONS) +}; + +/// Signing Information +struct smpc_sign_info +{ + /// Operation requester task id + ke_task_id_t requester; + + /// Message offset + uint16_t msg_offset; + /// Number of block + uint8_t block_nb; + /// Cn-1 value -> Need to kept this value to retrieve it after L generation + uint8_t cn1[GAP_KEY_LEN]; +}; + +/// SMPC environment structure +struct smpc_env +{ + /// SMPC temporary information + union smpc_info + { + /** + * Pairing Information - This structure is allocated at the beginning of a pairing + * or procedure. It is freed when a disconnection occurs or at the end of + * the pairing procedure. If not enough memory can be found, the procedure will fail + * with an "Unspecified Reason" error + */ + struct smpc_pair_info *pair; + + /** + * Signature Procedure Information - This structure is allocated at the beginning of a + * signing procedure. It is freed when a disconnection occurs or at the end of + * the signing procedure. If not enough memory can be found, the procedure will fail + * with an "Unspecified Reason" error. + */ + struct smpc_sign_info *sign; + } info; + + /// CSRK values (Local and remote) + struct gap_sec_key csrk[SMPC_INFO_MAX]; + + /// signature counter values (Local and remote) + uint32_t sign_counter[SMPC_INFO_MAX]; + + /// Repeated Attempt Timer value + uint16_t rep_att_timer_val; + + /// Encryption key size + uint8_t key_size; + + /** + * Contains the current state of the two timers needed in the SMPC task + * Bit 0 - Is Timeout Timer running + * Bit 1 - Is Repeated Attempt Timer running + * Bit 2 - Has task reached a SMP Timeout + */ + uint8_t timer_state; + + /// State of the current procedure + uint8_t state; + + #if (SECURE_CONNECTIONS) + bool secure_connections_enabled; + #endif // (SECURE_CONNECTIONS) +}; + +/* + * GLOBAL VARIABLES DEFINITION + **************************************************************************************** + */ + + +/* + * MACROS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + + +#endif //(BLE_SMPC) +#endif //SMPC_H_ + +/// @} SMPC diff --git a/services/ble_stack/hl/src/gap/gapc/gapc_int.h b/services/ble_stack/hl/src/gap/gapc/gapc_int.h new file mode 100644 index 0000000..006d8a2 --- /dev/null +++ b/services/ble_stack/hl/src/gap/gapc/gapc_int.h @@ -0,0 +1,378 @@ +#ifndef _GAPC_INT_H_ +#define _GAPC_INT_H_ + +/** + **************************************************************************************** + * @addtogroup GAPC_INT Generic Access Profile Controller Internals + * @ingroup GAPC + * @brief Handles ALL Internal GAPC API + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "gapc.h" +#include "gapc_task.h" + +#if (BLE_GAPC) + +/* + * MACROS + **************************************************************************************** + */ + +/// Set link configuration field +#define GAPC_SET_FIELD(conidx, field, value)\ + (gapc_env[conidx]->fields) = ((gapc_env[conidx]->fields) & (~GAPC_##field##_MASK)) \ + | (((value) << GAPC_##field) & (GAPC_##field##_MASK)) + + +/// Get link configuration field +#define GAPC_GET_FIELD(conidx, field)\ + (((gapc_env[conidx]->fields) & (GAPC_##field##_MASK)) >> GAPC_##field) + + +/* + * DEFINES + **************************************************************************************** + */ + +/// number of GAP Controller Process +#define GAPC_IDX_MAX BLE_CONNECTION_MAX + + + + +/// states of GAP Controller task +enum gapc_state_id +{ + /// Connection ready state + GAPC_READY, + + /// Link Operation on-going + GAPC_LINK_INFO_BUSY = (1 << GAPC_OP_LINK_INFO), + /// SMP Operation on-going + GAPC_SMP_BUSY = (1 << GAPC_OP_SMP), + /// Update Operation on-going + GAPC_LINK_UPD_BUSY = (1 << GAPC_OP_LINK_UPD), + /// SMP start encryption on-going + GAPC_ENCRYPT_BUSY = (1 << GAPC_OP_MAX), + + /// Disconnection on-going + GAPC_DISC_BUSY = 0x1F, + /// Free state + GAPC_FREE = 0X3F, + + /// Number of defined states. + GAPC_STATE_MAX +}; + + + +/// fields definitions. +/// Configuration fields: +/// 7 6 5 4 3 2 1 0 +/// +----+----+----+----+----+----+----+----+ +/// |RFU |SVCH|ROLE|LTK |ENC |BOND| SEC_LVL | +/// +----+----+----+----+----+----+----+----+ +enum gapc_fields +{ + /// Link Security Level + GAPC_SEC_LVL = 0, + GAPC_SEC_LVL_MASK = 0x03, + /// Link Bonded or not + GAPC_BONDED = 2, + GAPC_BONDED_MASK = 0x04, + /// Encrypted connection or not + GAPC_ENCRYPTED = 3, + GAPC_ENCRYPTED_MASK = 0x08, + /// Ltk present and exchanged during pairing + GAPC_LTK_PRESENT = 4, + GAPC_LTK_PRESENT_MASK = 0x10, + /// Local connection role + GAPC_ROLE = 5, + GAPC_ROLE_MASK = 0x20, + /// Service Changed CCC configuration + GAPC_SVC_CHG_CCC = 6, + GAPC_SVC_CHG_CCC_MASK = 0x40, +}; + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ +extern struct gapc_env_tag* gapc_env[GAPC_IDX_MAX]; + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialize Generic Access Profile Controller Module. + * + * @param[in] reset true if it's requested by a reset; false if it's boot initialization + * + **************************************************************************************** + */ +void gapc_init(bool reset); + + +/** + **************************************************************************************** + * @brief A connection has been created, initialize Controller task. + * + * This function find first available task index available for new connection. + * It triggers also connection event to task that has requested the connection. + * + * @param[in] msgid Message id for normal or enhanced privacy + * @param[in] con_params Connection parameters from lower layers + * @param[in] requester Task that request the connection to send indication(s) + * @param[in] laddr Local BD Address + * @param[in] laddr_type Local BD Address Type (PUBLIC or RAND) + * + * @return Connection index allocated to the new connection. + **************************************************************************************** + */ +uint8_t gapc_con_create(ke_msg_id_t const msgid, struct hci_le_enh_con_cmp_evt const *con_params, + ke_task_id_t requester, bd_addr_t* laddr, uint8_t laddr_type); + +/** + **************************************************************************************** + * @brief A connection has been disconnected, uninitialized Controller task. + * + * unregister connection, and destroy environment variable allocated for current connection. + * + * @param[in] conidx Connection index + * + * @return Connection index of the connection. + **************************************************************************************** + */ +uint8_t gapc_con_cleanup(uint8_t conidx); + + +/** + **************************************************************************************** + * @brief Send Disconnection indication to specific task + * + * @param[in] conidx Connection index + * @param[in] reason Disconnection reason + * @param[in] conhdl Connection handle + * @param[in] dest_id Message destination ID + * + **************************************************************************************** + */ +void gapc_send_disconect_ind(uint8_t conidx, uint8_t reason, uint8_t conhdl, + ke_task_id_t dest_id); + + + +/** + **************************************************************************************** + * @brief Retrieve connection CSRK information on current link. + * + * @param[in] conidx Connection index + * @param[in] src Connection information source + * + * @return Return found connection CSRK + **************************************************************************************** + */ +struct gap_sec_key* gapc_get_csrk(uint8_t conidx, uint8_t src); + +/** + **************************************************************************************** + * @brief Return the sign counter value for the specified connection index. + * + * @param[in] conidx Connection index + * @param[in] src Connection information source + * + * @return the requested signCounter value + **************************************************************************************** + */ +uint32_t gapc_get_sign_counter(uint8_t conidx, uint8_t src); + +/** + * @brief Send a complete event of ongoing executed operation to requester. + * It also clean-up variable used for ongoing operation. + * + * @param[in] conidx Connection index + * @param[in] op_type Operation type. + * @param[in] status Status of completed operation + */ +void gapc_send_complete_evt(uint8_t conidx, uint8_t op_type, uint8_t status); + +/** + **************************************************************************************** + * @brief Send operation completed message with status error code not related to a + * running operation. + * + * @param[in] conidx Connection index + * @param[in] operation Operation code + * @param[in] requester requester of operation + * @param[in] status Error status code + **************************************************************************************** + */ +void gapc_send_error_evt(uint8_t conidx, uint8_t operation, const ke_task_id_t requester, uint8_t status); + + +/** + **************************************************************************************** + * @brief Get operation on going + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return operation code on going + **************************************************************************************** + */ +uint8_t gapc_get_operation(uint8_t conidx, uint8_t op_type); + +/** + **************************************************************************************** + * @brief Get operation pointer + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return operation pointer on going + **************************************************************************************** + */ +void* gapc_get_operation_ptr(uint8_t conidx, uint8_t op_type); + + +/** + **************************************************************************************** + * @brief Set operation pointer + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * @param[in] op Operation pointer. + * + **************************************************************************************** + */ +void gapc_set_operation_ptr(uint8_t conidx, uint8_t op_type, void* op); + +/** + **************************************************************************************** + * @brief Operation execution not finish, request kernel to reschedule it in order to + * continue its execution + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return if operation has been rescheduled (not done if operation pointer is null) + **************************************************************************************** + */ +bool gapc_reschedule_operation(uint8_t conidx, uint8_t op_type); + +/** + **************************************************************************************** + * @brief Get requester of on going operation + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return task that requests to execute the operation + **************************************************************************************** + */ +ke_task_id_t gapc_get_requester(uint8_t conidx, uint8_t op_type); + + + + +/** + **************************************************************************************** + * @brief Set the encryption key size of the connection + * + * @param[in] conidx Connection index + * @param[in] key_size encryption key size (size is 7 - 16 byte range) + * + **************************************************************************************** + */ +void gapc_enc_keysize_set(uint8_t conidx, uint8_t key_size); + + +/** + **************************************************************************************** + * @brief Update link status, current link is now encrypted + * + * @param[in] conidx Connection index + * + **************************************************************************************** + */ +void gapc_link_encrypted(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Update link authentication level + * + * @param[in] conidx Connection index + * @param[in] auth Link authentication level + * @param[in] ltk_present Link paired and an LTK has been exchanged + * + **************************************************************************************** + */ +void gapc_auth_set(uint8_t conidx, uint8_t auth, bool ltk_present); + +/** + **************************************************************************************** + * @brief Retrieve link authentication level + * + * @param[in] conidx Connection index + * @return Link authentication level + **************************************************************************************** + */ +uint8_t gapc_auth_get(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Update task state + * + * @param[in] conidx Connection index + * @param[in] state to update + * @param[in] set state to busy (true) or idle (false) + * + **************************************************************************************** + */ +void gapc_update_state(uint8_t conidx, ke_state_t state, bool busy); + + +/** + **************************************************************************************** + * @brief Checks connection parameters values + * + * @param[in] intv_max maximum interval + * @param[in] intv_min minimum interval + * @param[in] latency latency + * @param[in] timeout timeout value + * + * @return true if OK, false if not OK + **************************************************************************************** + */ +bool gapc_param_update_sanity(uint16_t intv_max, uint16_t intv_min, uint16_t latency, uint16_t timeout); + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ +int gapc_process_op(uint8_t conidx, uint8_t op_type, void* op_msg, enum gapc_operation* supp_ops); + + + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +#endif // (BLE_GAPC) +/// @} GAPC_INT + +#endif /* _GAPC_INT_H_ */ diff --git a/services/ble_stack/hl/src/gap/gapc/gapc_sig.h b/services/ble_stack/hl/src/gap/gapc/gapc_sig.h new file mode 100644 index 0000000..d29368b --- /dev/null +++ b/services/ble_stack/hl/src/gap/gapc/gapc_sig.h @@ -0,0 +1,52 @@ +#ifndef _GAPC_SIG_H_ +#define _GAPC_SIG_H_ + + +/** + **************************************************************************************** + * @addtogroup GAPC_SIG Generic Access Profile Controller Signaling PDU Handler. + * @ingroup GAPC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_GAPC) +#include "l2cc_pdu.h" + + +#if (BLE_CENTRAL) +/** + **************************************************************************************** + * @brief Sends parameter response + * + * @param[in] conidx connection index + * @param[in] result response result + * @param[in] pkt_id Packet identifier + **************************************************************************************** + */ +void gapc_sig_send_param_resp(uint8_t conidx, uint16_t result, uint8_t pkt_id); +#endif // (BLE_CENTRAL) + +/** + **************************************************************************************** + * @brief Handles reception of L2CAP signaling messages from peer device. + * + * @param[in] conidx Connection Index + * @param[in] pdu PDU Received + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +int gapc_sig_pdu_recv_handler(uint8_t conidx, struct l2cc_pdu *pdu); + +#endif // (BLE_GAPC) + +#endif // _GAPC_SIG_H_ + +/// @} GAPC_SIG diff --git a/services/ble_stack/hl/src/gap/gapm/gapm_int.h b/services/ble_stack/hl/src/gap/gapm/gapm_int.h new file mode 100644 index 0000000..43ff26c --- /dev/null +++ b/services/ble_stack/hl/src/gap/gapm/gapm_int.h @@ -0,0 +1,762 @@ +#ifndef _GAPM_INT_H_ +#define _GAPM_INT_H_ + +/** + **************************************************************************************** + * @addtogroup GAPM_INT Generic Access Profile Manager Internal + * @ingroup GAPM + * @brief defines for internal GAPM usage + * + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "gapm.h" +#include "gapm_task.h" +#if (BLE_DEPRECATED_API) +#include "gapc.h" +#endif //(BLE_DEPRECATED_API) +#include "co_bt.h" + + +/* + * DEFINES + **************************************************************************************** + */ + +/// Maximum number of GAP Manager process +#define GAPM_IDX_MAX BLE_CONNECTION_MAX + +/// Scan filter size +#define GAPM_SCAN_FILTER_SIZE 10 + +/// check if current role is supported by configuration +#define GAPM_IS_ROLE_SUPPORTED(role_type)\ + ((gapm_env.role & (role_type)) == (role_type)) + +/// Number of supported activities in host +#define GAPM_ACTV_NB (BLE_ACTIVITY_MAX) +/// Maximum number of advertising report that can be reassembled in parallel +#define GAPM_REPORT_NB_MAX (5) +/// Invalid activity identifier +#define GAPM_ACTV_INVALID_IDX (0xFF) + +/* + * INTERNAL API TYPES + **************************************************************************************** + */ + + +/// Retrieve information about memory usage +struct gapm_dbg_get_mem_info_cmd +{ + /// GAPM requested operation: + /// - GAPM_DBG_GET_MEM_INFO: Get memory usage + uint8_t operation; +}; + +/// Indication containing information about memory usage. +struct gapm_dbg_mem_info_ind +{ + /// peak of memory usage measured + uint32_t max_mem_used; + /// memory size currently used into each heaps. + uint16_t mem_used[KE_MEM_BLOCK_MAX]; +}; + + +/// Operation type +enum gapm_op_type +{ + /// Configuration operation + GAPM_OP_CFG = 0x00, + + /// Air mode operation (scanning, advertising, connection establishment) + /// Note: Restriction, only one air operation supported. + GAPM_OP_AIR = 0x01, + #if (SECURE_CONNECTIONS) + /// GAP State for DH Key Generation + GAPM_OP_DHKEY = 0x02, + #endif // (SECURE_CONNECTIONS) + /// Max number of operations + GAPM_OP_MAX +}; + +/// GAPM states +enum gapm_state_id +{ + /// Idle state - no on going operation + GAPM_IDLE, + + /// Busy state - Configuration operation on going + GAPM_CFG_BUSY = 1 << GAPM_OP_CFG, + /// Busy state - Air operation on going + GAPM_AIR_BUSY = 1 << GAPM_OP_AIR, + #if (SECURE_CONNECTIONS) + /// Busy state - DH Key Calculation operation on going + GAPM_DHKEY_BUSY = 1 << GAPM_OP_DHKEY, + #endif // (SECURE_CONNECTIONS) + + /// Reset state - Reset operation on going + GAPM_DEVICE_SETUP = 1 << GAPM_OP_MAX, + + GAPM_STATE_MAX +}; + +/// Device configuration flags +/// 7 6 5 4 3 2 1 0 +/// +-----+----+----+----+----+----+----+----+ +/// | DBG | SC | CP | GA | RE |CTLP|HSTP|ADDR| +/// +-----+----+----+----+----+----+----+----+ +/// - Bit [0-2]: Address Type @see enum gapm_cfg_flag +/// Bit 0: 0 = Public address, 1 = Private address +/// Bit 1: 0 = Host-based Privacy disabled, 1 = enabled - DEPRECATED +/// Bit 2: 0 = Controller-based Privacy disabled, 1 = enabled +/// +/// - Bit [3] : Address to renew (only if privacy is enabled, 1 address to renew else 0) +/// - Bit [4] : Generated Address type (1 = Resolvable, 0 = Non Resolvable) +/// - Bit [5] : Preferred Connection parameters present in GAP DB +/// - Bit [6] : Service Change feature present +/// - Bit [7] : Enable Debug mode +/// Configuration flag bit description +enum gapm_cfg_flag_def +{ + /// Address Type + GAPM_MASK_ADDR_TYPE = 0x07, + GAPM_POS_ADDR_TYPE = 0x00, + /// Address to renew + GAPM_MASK_ADDR_RENEW = 0x08, + GAPM_POS_ADDR_RENEW = 0x03, + /// Generated Address type + GAPM_MASK_RESOLV_ADDR = 0x10, + GAPM_POS_RESOLV_ADDR = 0x04, + /// Preferred Connection parameters present in GAP DB + GAPM_MASK_PREF_CON_PAR_PRES = 0x20, + GAPM_POS_PREF_CON_PAR_PRES = 0x05, + /// Service Change feature present + GAPM_MASK_SVC_CHG_EN = 0x40, + GAPM_POS_SVC_CHG_EN = 0x06, + +#if (RW_DEBUG) + /// L2CAP Debug Mode used to force LE-frames + GAPM_MASK_DBG_MODE_EN = 0x80, + GAPM_POS_DBG_MODE_EN = 0x07, +#endif // (RW_DEBUG) +}; + + +/// Security level +/// 7 6 5 4 3 2 1 0 +/// +---+---+---+---+---+---+---+---+ +/// |MI | RFU |EKS|SEC_LVL| +/// +---+---+---+---+---+---+---+---+ +/// bit[0-1]: Security level requirement (0=NO_AUTH, 1=UNAUTH, 2=AUTH, 3=SEC_CON) +/// bit[2] : Encryption Key Size length must have 16 bytes +/// bit[7] : Multi-instantiated task +enum gapm_le_psm_sec_mask +{ + /// bit[0-1]: Security level requirement (0=NO_AUTH, 1=UNAUTH, 2=AUTH, 3=SEC_CON) + /// bit[2] : Encryption Key Size length must have 16 bytes + GAPM_LE_PSM_SEC_LVL_MASK = 0x07, + /// bit[7] : Multi-instantiated task + GAPM_LE_PSM_MI_TASK_MASK = 0x80, +}; + +/// Activity states +enum gapm_actv_state +{ + /// Activity is being created - next state is CREATED + GAPM_ACTV_CREATING = 0, + /// Activity has been successfully created + GAPM_ACTV_CREATED, + /// Activity is being started - next state is STARTED + GAPM_ACTV_STARTING, + /// Activity has been successfully started + GAPM_ACTV_STARTED, + /// Activity is being stopped - next state is CREATED + GAPM_ACTV_STOPPING, + /// Activity is being deleted - no next state + GAPM_ACTV_DELETING, +}; + +/// Activity information bit field values +enum gapm_actv_info +{ + /// Scanning activity has been started + GAPM_ACTV_INFO_SCAN_STARTED_BIT = (1 << 0), + /// Initiating activity has been started + GAPM_ACTV_INFO_INIT_STARTED_BIT = (2 << 0), +}; + +/// Connection role +enum gapm_conn_role +{ + /// Master + GAPM_ROLE_MASTER = 0, + /// Slave + GAPM_ROLE_SLAVE, +}; + +/* + * MACROS + **************************************************************************************** + */ +/// Macro used to retrieve field +#define GAPM_F_GET(data, field)\ + (((data) & (GAPM_MASK_ ## field)) >> (GAPM_POS_ ## field)) + +/// Macro used to set field +#define GAPM_F_SET(data, field, val)\ + (data) = (((data) & ~(GAPM_MASK_ ## field)) \ + | ((val << (GAPM_POS_ ## field)) & (GAPM_MASK_ ## field))) + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Information about registered LE_PSM +struct gapm_le_psm_info +{ + /// List header structure to put information within a list + struct co_list_hdr hdr; + + /// LE Protocol/Service Multiplexer + uint16_t le_psm; + + /// Registered task identifier + ke_task_id_t task_id; + + /// Security level + /// 7 6 5 4 3 2 1 0 + /// +---+---+---+---+---+---+---+---+ + /// |MI | RFU |EKS|SEC_LVL| + /// +---+---+---+---+---+---+---+---+ + /// bit[0-1]: Security level requirement (0=NO_AUTH, 1=UNAUTH, 2=AUTH, 3=SEC_CON) + /// bit[2] : Encryption Key Size length must have 16 bytes + /// bit[7] : Multi-instantiated task + uint8_t sec_lvl; + + /// Number of established link + uint8_t nb_est_lk; +}; + +/// GAP Manager activity structure (common part for advertising, scanning, +/// initiating and periodic synchronization activities) +struct gapm_actv_tag +{ + /// Identifier + uint8_t idx; + /// Type (@see enum gap_actv_type) + uint8_t type; + /// Subtype - meaning depends on activity type + /// - Advertising activity: @see enum gap_adv_subtype + /// - Scanning activity: @see enum gap_scan_subtype + /// - Initiating activity: @see enum gap_init_subtype + /// - Periodic Synchronization activity: @see enum gap_period_sync_subtype + uint8_t subtype; + /// State (@see enum gapm_actv_state) + uint8_t state; + /// Information bit field, meaning depends on activity type + /// - Bit 0-6: meaning depends on activity type + /// - Bit 7: Random Address must be renewed + uint8_t info; + /// Own address type + uint8_t own_addr_type; + /// Next expected HCI event opcode + uint16_t next_exp_opcode; + /// ID for . This task will receive GAPM_ACTIVITY_STOPPED_IND message that might not + /// be trigger by application + ke_task_id_t requester; + /// BD Address used by the activity (can be different if controller privacy is used and + /// application chose to use a resolvable private address) + bd_addr_t addr; +}; + +struct gapm_report_elem +{ + /// List Header + struct co_list_hdr list_hdr; + /// Report fragment information + struct ext_adv_report report_frag; +}; + +struct gapm_report_list +{ + // List of received reports (@see struct gapm_report_elem) + struct co_list report_list; + // Advertiser address + struct gap_bdaddr adv_addr; + // Received length + uint16_t length; +}; + +/// GAP Manager activity structure for advertising activity +struct gapm_actv_adv_tag +{ + /// Common activity parameters + struct gapm_actv_tag common; + /// Data offset for the set advertising data procedure + uint16_t data_offset; + /// Advertising mode (@see enum gap_adv_disc_mode) + uint8_t mode; + /// Stored status + uint8_t kept_status; + /// Selected TX power + uint8_t tx_pwr; +}; + +/// GAP Manager activity structure for scanning activity +struct gapm_actv_scan_tag +{ + /// Common activity parameters + struct gapm_actv_tag common; + /// Lists used to reassemble report fragment + struct gapm_report_list report_lists[GAPM_REPORT_NB_MAX]; + /// Scan filtering Array + struct gap_bdaddr *p_scan_filter; +}; + +/// GAP Manager activity structure for initiating activity +struct gapm_actv_init_tag +{ + /// Common activity parameters + struct gapm_actv_tag common; + /// Initiating parameters + struct gap_init_param init_param; + /// Number of connection to be established for automatic connection + /// -> Number of devices in the white list when GAPM_ACTIVITY_START_CMD is received + uint8_t nb_auto_conn; + /// Stored status + uint8_t kept_status; +}; + +/// GAP Manager activity structure for periodic synchronization activity +struct gapm_actv_per_sync_tag +{ + /// Common activity parameters + struct gapm_actv_tag common; +}; + +/// GAP Manager environment structure +struct gapm_env_tag +{ + /// Request operation Kernel message + void* operation[GAPM_OP_MAX]; + + /// Array of pointers to the allocated activities + /// TODO [LT] IMPROVEMENT - Could be dynamically allocated based on read number of sets supported by controller + struct gapm_actv_tag *actvs[GAPM_ACTV_NB]; + + #if (BLE_DEPRECATED_API) + #if (BLE_OBSERVER) + /// Scan filtering Array + struct gap_bdaddr* scan_filter; + #endif // (BLE_OBSERVER) + #endif //(BLE_DEPRECATED_API) + + #if (BLE_LECB) + /// Registered list of LE Protocol/Service Multiplexer for LE Credit Based Connection + struct co_list reg_le_psm; + #endif // (BLE_LECB) + + #if (BLE_ATTS) + /// GAP service start handle + uint16_t svc_start_hdl; + #endif // (BLE_ATTS) + + #if (BLE_BROADCASTER) + uint16_t max_adv_data_len; + #endif //(BLE_BROADCASTER) + + /// Duration before regenerate device address when privacy is enabled. + uint16_t renew_dur; + /// Device IRK used for resolvable random BD address generation (MSB -> LSB) + struct gap_sec_key irk; + + /// Current device Address + bd_addr_t addr; + bd_addr_t connectedAddr[6]; + /// Device Role + uint8_t role; + /// Number of BLE connection + uint8_t connections; + /// Device configuration flags - (@see enum gapm_cfg_flag_def) + uint8_t cfg_flags; + /// Pairing mode authorized (see enum gapm_pairing_mode) + uint8_t pairing_mode; + /// Maximum device MTU size + uint16_t max_mtu; + /// Maximum device MPS size + uint16_t max_mps; + #if (SECURE_CONNECTIONS) + /// Local device Public Key + public_key_t public_key; + private_key_t private_key; + private_key_t host_DHKey; + + #endif // (SECURE_CONNECTIONS) + + #if(BLE_AUDIO) + /// Audio configuration flag (see gapm_audio_cfg_flag) + uint16_t audio_cfg; + #endif // (BLE_AUDIO) + + #if(BLE_EMB_PRESENT && HCI_TL_SUPPORT) + /// In Full mode, by default the AHI API is used, but if an HCI Reset is received, + /// TL is switched to HCI and embedded host is disabled + bool embedded_host; + #endif // (BLE_EMB_PRESENT && HCI_TL_SUPPORT) + + #if (BLE_LECB) + /// Maximum number of allowed LE Credit Based channels + uint8_t max_nb_lecb; + /// Current number of LE Credit Based channel connections established + uint8_t nb_lecb; + #endif // (BLE_LECB) + + #if (BLE_DEPRECATED_API) + /// Indicate if deprecated API must be used + bool use_deprecated_api; + #endif //(BLE_DEPRECATED_API) + + #if (BLE_BROADCASTER) + /// Number of advertising sets supported by controller + uint8_t max_adv_set; + /// Number of created advertising activities + uint8_t nb_adv_actv; + #endif //(BLE_BROADCASTER) + #if (BLE_OBSERVER) + /// Bit field making management of activity easier (@see enum gapm_actv_info) + uint8_t actv_info; + #endif //(BLE_OBSERVER) + /// Activity identifier currently used for air operation + uint8_t actv_idx; + /// Number of created activities + uint8_t created_actvs; + /// Number of started activities + uint8_t started_actvs; + #if (BLE_OBSERVER) + /// Number of devices in the white list + uint8_t nb_dev_wl; + #endif //(BLE_OBSERVER) +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ +/// GAP Manager environment variable. +extern struct gapm_env_tag gapm_env; + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Initialize GAP attribute database + * + * @param[in] start_hdl Service Start Handle + * @param[in] feat Attribute database features + * + * @return status code of attribute database initialization + * - @ref ATT_ERR_NO_ERROR: If database creation succeeds. + * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter + nb of attribute override + * some existing services handles. + * - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer. + * or of new attribute cannot be added because all expected + * attributes already add + **************************************************************************************** + */ +uint8_t gapm_init_attr(uint16_t start_hdl, uint32_t feat); + +void gapm_send_raw_complete_evt(uint8_t op_type, uint8_t status); + +/** + **************************************************************************************** + * @brief Send operation completed message according to operation type. + * Perform also am operation clean-up + * + * @param[in] op_type Operation type + * @param[in] status Command status + ***************************************************************************************** + */ +void gapm_send_complete_evt(uint8_t op_type, uint8_t status); + +/** + **************************************************************************************** + * @brief Send operation completed message with status error code not related to a + * running operation. + * + * @param[in] operation Operation code + * @param[in] requester requester of operation + * @param[in] status Error status code + **************************************************************************************** + */ +void gapm_send_error_evt(uint8_t operation, const ke_task_id_t requester, uint8_t status); + + +/** + **************************************************************************************** + * @brief Get operation pointer + * + * @param[in] op_type Operation type. + * + * @return operation pointer on going + **************************************************************************************** + */ +static __INLINE void* gapm_get_operation_ptr(uint8_t op_type) +{ + ASSERT_ERR(op_type < GAPM_OP_MAX); + // return operation pointer + return gapm_env.operation[op_type]; +} + + +/** + **************************************************************************************** + * @brief Set operation pointer + * + * @param[in] op_type Operation type. + * @param[in] op Operation pointer. + * + **************************************************************************************** + */ +static __INLINE void gapm_set_operation_ptr(uint8_t op_type, void* op) +{ + ASSERT_ERR(op_type < GAPM_OP_MAX); + // update operation pointer + gapm_env.operation[op_type] = op; +} + + +/** + **************************************************************************************** + * @brief Check if current operation can be processed or not. + * if it can be proceed, initialize an operation request. + * If a command complete event with error code can be triggered. + * + * Function returns how the message should be handled by message handler. + * + * @param[in] op_type Operation type. + * @param[in] op_msg Requested operation message (note op_msg cannot be null) + * @param[in] supp_ops Supported operations array. + * Latest array value shall be GAPM_NO_OP. + * + * @return operation can be executed if message status equals KE_MSG_NO_FREE, + * else nothing to do, just exit from the handler. + **************************************************************************************** + */ +int gapm_process_op(uint8_t op_type, void* op_msg, enum gapm_operation* supp_ops); + +/** + **************************************************************************************** + * @brief Get operation on going + * + * @param[in] op_type Operation type. + * + * @return operation code on going + **************************************************************************************** + */ +uint8_t gapm_get_operation(uint8_t op_type); + +/** + **************************************************************************************** + * @brief Get requester of on going operation + * + * @param[in] op_type Operation type. + * + * @return task that requests to execute the operation + **************************************************************************************** + */ +ke_task_id_t gapm_get_requester(uint8_t op_type); + + + + +#if (BLE_GAPC) +/** + **************************************************************************************** + * @brief A connection has been created, initialize host stack to be ready for connection. + * + * @param[in] msgid Message id + * @param[in] operation Air operation type + * @param[in] con_params Connection parameters from lower layers + * + * @return Connection index allocated to the new connection. + **************************************************************************************** + */ +uint8_t gapm_con_create(ke_msg_id_t const msgid, uint8_t operation, struct hci_le_enh_con_cmp_evt const *con_params); + +#endif // (BLE_GAPC) + + +/** + **************************************************************************************** + * @brief Set the maximal MTU value + * + * @param[in] mtu Max MTU value (Minimum is 23) + **************************************************************************************** + */ +void gapm_set_max_mtu(uint16_t mtu); + +/** + **************************************************************************************** + * @brief Set the maximal MPS value + * + * @param[in] mps Max MPS value (Minimum is 23) + **************************************************************************************** + */ +void gapm_set_max_mps(uint16_t mps); + +/** + **************************************************************************************** + * @brief Checks validity of the address type + * + * @param[in] addr_type Address type + **************************************************************************************** + */ +uint8_t gapm_addr_check( uint8_t addr_type); + +#if (BLE_DEPRECATED_API) +/** + **************************************************************************************** + * @brief + **************************************************************************************** + */ +uint8_t gapm_privacy_cfg_check(uint8_t privacy_cfg); +#endif //(BLE_DEPRECATED_API) + +/** + **************************************************************************************** + * @brief Checks validity of the Data Length Suggested values + * + * @param[in] sugg_oct Suggested octets + * @param[in] sugg_time Suggested time + **************************************************************************************** + */ +uint8_t gapm_dle_val_check(uint16_t sugg_oct, uint16_t sugg_time); + + + +/** + **************************************************************************************** + * @brief Update task state + * + * @param[in] operation that modify the state + * @param[in] set state to busy (true) or idle (false) + * + **************************************************************************************** + */ +void gapm_update_state(uint8_t operation, bool busy); + + + +#if (BLE_LECB) + + +/** + **************************************************************************************** + * @brief Find Information about LE_PSM registered in GAPM + * + * @param[in] le_psm LE Protocol/Service Multiplexer + * + * @return Null if not found or LE_PSM info structure + **************************************************************************************** + */ +struct gapm_le_psm_info* gapm_le_psm_find(uint16_t le_psm); + + +/** + **************************************************************************************** + * @brief Remove all registered LE_PSM + **************************************************************************************** + */ +void gapm_le_psm_cleanup(void); +#endif // (BLE_LECB) + +#if (BLE_DEPRECATED_API) +/** + **************************************************************************************** + * Continue address update for air operation + * + * @param[in] opcode HCI event operation code + * @param[in] status HCI command status + **************************************************************************************** + */ +void gapm_air_addr_update_cont(uint16_t opcode, uint8_t status); + +int gapm_cmp_evt_leg_air_handler(ke_msg_id_t const msgid, struct gapm_cmp_evt const *cmp_evt, + ke_task_id_t const dest_id, ke_task_id_t const src_id); +int gapm_addr_renew_to_ind_leg_air_handler(ke_msg_id_t const msgid, void const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id); +int hci_le_enh_con_cmp_evt_leg_air_handler(uint16_t opcode, struct hci_le_enh_con_cmp_evt const *event); +int gapc_cmp_evt_leg_air_handler(ke_msg_id_t const msgid, struct gapc_cmp_evt const *cmp_evt, + ke_task_id_t const dest_id, ke_task_id_t const src_id); +int gapc_peer_att_info_ind_leg_air_handler(ke_msg_id_t const msgid, struct gapc_peer_att_info_ind const *p_event, + ke_task_id_t const dest_id, ke_task_id_t const src_id); +#endif //(BLE_DEPRECATED_API) + +void gapm_actv_init(bool reset); +struct gapm_actv_tag *gapm_actv_alloc(uint8_t actv_idx, uint8_t size); +bool gapm_actv_retrieve_cmd_cmp_evt(struct gapm_actv_tag **pp_actv, uint16_t opcode); +uint8_t gapm_actv_get_hci_own_addr_type(uint8_t app_addr_type); +void gapm_actv_created(struct gapm_actv_tag *p_actv, uint8_t error); +void gapm_actv_started(struct gapm_actv_tag *p_actv, uint8_t error); +void gapm_actv_stopped(struct gapm_actv_tag *p_actv, uint8_t status); +void gapm_actv_deleted(struct gapm_actv_tag *p_actv); +void gapm_actv_send_gen_rand_addr(struct gapm_actv_tag *p_actv); +void gapm_actv_addr_gen_ind(uint8_t *p_prand, uint8_t *p_hash); +void gapm_actv_addr_set_ind(void); + +void gapm_adv_send_hci_le_set_adv_set_rand_addr_cmd(struct gapm_actv_tag *p_actv); +uint8_t gapm_adv_create(uint8_t actv_idx, struct gapm_activity_create_adv_cmd *p_param); +uint8_t gapm_adv_start(struct gapm_actv_tag *p_actv, struct gapm_activity_start_cmd *p_param); +void gapm_adv_stop(struct gapm_actv_tag *p_actv); +void gapm_adv_delete(struct gapm_actv_tag *p_actv); + +void gapm_scan_actv_clean(struct gapm_actv_tag *p_actv); +uint8_t gapm_scan_create(uint8_t actv_idx, struct gapm_activity_create_cmd *p_param); +uint8_t gapm_scan_start(struct gapm_actv_tag *p_actv, struct gapm_activity_start_cmd *p_param); +void gapm_scan_stop(struct gapm_actv_tag *p_actv); +void gapm_scan_delete(struct gapm_actv_tag *p_actv); +void gapm_scan_addr_set_ind(struct gapm_actv_tag *p_actv); + +uint8_t gapm_init_create(uint8_t actv_idx, struct gapm_activity_create_cmd *p_param); +uint8_t gapm_init_start(struct gapm_actv_tag *p_actv, struct gapm_activity_start_cmd *p_param); +void gapm_init_stop(struct gapm_actv_tag *p_actv); +void gapm_init_delete(struct gapm_actv_tag *p_actv); +bool gapm_init_connection_ind(uint8_t conidx); +void gapm_init_addr_set_ind(struct gapm_actv_tag *p_actv); + +uint8_t gapm_per_sync_create(uint8_t actv_idx, struct gapm_activity_create_cmd *p_param); +uint8_t gapm_per_sync_start(struct gapm_actv_tag *p_actv, struct gapm_activity_start_cmd *p_param); +void gapm_per_sync_stop(struct gapm_actv_tag *p_actv); +void gapm_per_sync_delete(struct gapm_actv_tag *p_actv); + +/** + **************************************************************************************** + * @brief Sends a basic HCI command (with no parameter) + * + * @param[in] opcode Command opcode + **************************************************************************************** + */ +void hci_basic_cmd_send_2_controller(uint16_t opcode); + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + +/// @} GAPM_INT + +#endif /* _GAPM_INT_H_ */ diff --git a/services/ble_stack/hl/src/gap/smp_common.h b/services/ble_stack/hl/src/gap/smp_common.h new file mode 100644 index 0000000..b32e1c5 --- /dev/null +++ b/services/ble_stack/hl/src/gap/smp_common.h @@ -0,0 +1,146 @@ +/** + **************************************************************************************** + * @addtogroup SMP_COMMON + * @ingroup SMP + * @{ + **************************************************************************************** + */ + +#ifndef SMP_COMMON_H_ +#define SMP_COMMON_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#include // Standard Boolean Definitions +#include // Standard Integer Definitions + +#include "co_utils.h" +#include "co_bt.h" // Common Bluetooth Definitions + +/* + * DEFINES + **************************************************************************************** + */ + +/// Mask applied to a Pairing Failed error triggered by us. +#define SMP_PAIR_FAIL_REASON_MASK (0x60) +/// Mask applied to a Pairing Failed error triggered by the peer device. +#define SMP_PAIR_FAIL_REASON_REM_MASK (0x70) + +/* + * MACROS + **************************************************************************************** + */ + +/// Mask a Pairing Failed reason value with the provided mask. +#define SMP_GEN_PAIR_FAIL_REASON(mask, reason) (mask | reason) +/// Extract the mask from a masked Pairing Failed reason value. +#define SMP_GET_PAIR_FAIL_MASK(reason) (0xF0 & reason) +/// Extract the Pairing Failed reason value from a masked Pairing Failed reason value. +#define SMP_GET_PAIR_FAIL_REASON(reason) (0x0F & reason) + +/* + * ENUMERATIONS + **************************************************************************************** + */ + +/** + * SMP Pairing Failed Reasons + */ +enum smp_pair_fail_reason +{ + + /** + * Passkey Entry Failed (0x01) + * The user input of passkey failed, for example, the user cancelled the operation. + */ + SMP_ERROR_PASSKEY_ENTRY_FAILED = 0x01, + /** + * OOB Not Available (0x02) + * The OOB Data is not available. + */ + SMP_ERROR_OOB_NOT_AVAILABLE, + /** + * Authentication Requirements (0x03) + * The pairing procedure cannot be performed as authentication requirements cannot be + * met due to IO capabilities of one or both devices. + */ + SMP_ERROR_AUTH_REQ, + /** + * Confirm Value Failed (0x04) + * The confirm value does not match the calculated confirm value. + */ + SMP_ERROR_CONF_VAL_FAILED, + /** + * Pairing Not Supported (0x05) + * Pairing is not supported by the device. + */ + SMP_ERROR_PAIRING_NOT_SUPP, + /** + * Encryption Key Size (0x06) + * The resultant encryption key size is insufficient for the security requirements of + * this device. + */ + SMP_ERROR_ENC_KEY_SIZE, + /** + * Command Not Supported (0x07) + * The SMP command received is not supported on this device. + */ + SMP_ERROR_CMD_NOT_SUPPORTED, + /** + * Unspecified Reason (0x08) + * Pairing failed due to an unspecified reason. + */ + SMP_ERROR_UNSPECIFIED_REASON, + /** + * Repeated Attempts (0x09) + * Pairing or Authentication procedure is disallowed because too little time has elapsed + * since last pairing request or security request. + */ + SMP_ERROR_REPEATED_ATTEMPTS, + /** + * Invalid Parameters (0x0A) + * The command length is invalid or a parameter is outside of the specified range. + */ + SMP_ERROR_INVALID_PARAM, + /** + * DHKey Check Failed (0x0B) + * Indicates to the remote device that the DHKey Check value received doesn't + * match the one calculated by the local device. + */ + SMP_ERROR_DHKEY_CHECK_FAILED, + /** + * Numeric Comparison Failed (0x0C) + * Indicates that the confirm values in the numeric comparison protocol do not match. + */ + SMP_ERROR_NUMERIC_COMPARISON_FAILED, + /** + * BR/EDR pairing in progress (0x0D) + * Indicates that the pairing over the LE transport failed due to a Pairing Request sent + * over the BR/EDR transport in process. + */ + SMP_ERROR_BREDR_PAIRING_IN_PROGRESS, + /** + * Cross-transport Key Derivation/Generation not allowed (0x0E) + * + * Indicates that the BR/EDR Link Key generated on the BR/EDR transport cannot be + * used to derive and distribute keys for the LE transport. + */ + SMP_ERROR_CROSS_TRANSPORT_KEY_GENERATION_NOT_ALLOWED, +}; + + +/* + * STRUCTURES + **************************************************************************************** + */ + + +#endif // (SMP_COMMON_H_) + +/// @} SMP_COMMON diff --git a/services/ble_stack/hl/src/gap/smpc/smpc_api.h b/services/ble_stack/hl/src/gap/smpc/smpc_api.h new file mode 100644 index 0000000..ceccad9 --- /dev/null +++ b/services/ble_stack/hl/src/gap/smpc/smpc_api.h @@ -0,0 +1,547 @@ +#ifndef SMPC_API_H_ +#define SMPC_API_H_ + +/** + **************************************************************************************** + * @addtogroup SMPC_API Task + * @ingroup SMPC + * @brief Provides a SMP API for controller tasks. + * + * The SMPC api is responsible for all security protocol and secure connections handling. + * + * @{ + **************************************************************************************** + */ +/* + * INCLUDE FILES + **************************************************************************************** + */ + + +#include "rwip_config.h" +#if (BLE_SMPC) +#include "../smp_common.h" +#include "gap.h" +#include "gapc_task.h" +#include "l2cc_pdu.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +/// check if flag is set +#define SMPC_IS_FLAG_SET(conidx, flag) ((gapc_env[conidx]->smpc.timer_state & flag) == flag) + +#define SMPC_TIMER_SET_FLAG(conidx, flag) (gapc_env[conidx]->smpc.timer_state |= flag) + +#define SMPC_TIMER_UNSET_FLAG(conidx, flag) (gapc_env[conidx]->smpc.timer_state &= ~flag) + + +/** + * Timer State Masks + */ +/// Timeout Timer +#define SMPC_TIMER_TIMEOUT_FLAG (0x01) +/// Repeated Attempts Timer +#define SMPC_TIMER_REP_ATT_FLAG (SMPC_TIMER_TIMEOUT_FLAG << 1) +/// Blocked because of SMP Timeout +#define SMPC_TIMER_TIMEOUT_BLOCKED_FLAG (SMPC_TIMER_REP_ATT_FLAG << 1) + + +/// SMPC Internal State Code +enum smpc_state +{ + SMPC_STATE_RESERVED = 0x00, + + /******************************************************** + * Pairing Procedure + ********************************************************/ + + /**------------------------------------** + * Pairing Features Exchange Phase * + **------------------------------------**/ + /// Is waiting for the pairing response + SMPC_PAIRING_RSP_WAIT, + /// Is waiting for the pairing features + SMPC_PAIRING_FEAT_WAIT, + + /**------------------------------------** + * Legacy (Pre BT 4.2 ) Authentication and Encryption Phase * + **------------------------------------**/ + + /// Is waiting for the TK + SMPC_PAIRING_TK_WAIT, + /// Is waiting for the TK, peer confirm value has been received + SMPC_PAIRING_TK_WAIT_CONF_RCV, + /// Calculate the Random Number, part 1 + SMPC_PAIRING_GEN_RAND_P1, + /// Calculate the Random Number, part 2 + SMPC_PAIRING_GEN_RAND_P2, + /// The first part of the device's confirm value is being generated + SMPC_PAIRING_CFM_P1, + /// The device's confirm value is being generated + SMPC_PAIRING_CFM_P2, + /// The first part of the peer device's confirm value is being generated + SMPC_PAIRING_REM_CFM_P1, + /// The peer device's confirm value is being generated + SMPC_PAIRING_REM_CFM_P2, + /// The device is waiting for the confirm value generated by the peer device + SMPC_PAIRING_WAIT_CONFIRM, + /// The device is waiting for the random value generated by the peer device + SMPC_PAIRING_WAIT_RAND, + /// The STK is being generated + SMPC_PAIRING_GEN_STK, + + #if (SECURE_CONNECTIONS) + /**------------------------------------** + * Secure Connections (BT 4.2 ) Authentication and Encryption Phase * + **------------------------------------**/ + SMPC_PAIRING_SC_W4_PEER_PUBLIC_KEY, + + // Just Works and Numeric Comparison + //--------------------------------- + + // In Just Works/Numeric Comparison - this state is used while + // we are waiting for the LL to generate a Rand. + SMPC_PAIRING_SC_W4_LOCAL_RAND_N_P1, + SMPC_PAIRING_SC_W4_LOCAL_RAND_N_P2, + // Used in Slave during F4 while waiting for AES_CMAC + SMPC_PAIRING_SC_W4_F4_COMMITMENT_DETERMINATION, + + // Used in Master to Wait for Peer Commitment Cb + SMPC_PAIRING_SC_W4_PEER_COMMITMENT, + + // Used in Master/Slave to Wait for Random Number From peer. + SMPC_PAIRING_SC_W4_PEER_RAND, + + // Used in Slave to wait for Random Number Na from Master + // SMPC_PAIRING_SC_W4_PAIRING_Na, + + // Used in Master during F4 calculation for Commitment Check + SMPC_PAIRING_SC_W4_F4_COMMITMENT_CHECK, + + // Numeric Comparison + // States specific to Secure Commenctions - numeric comparison + + // Used in both Master/Slave to wait for the AES-CMAC calculation does to calculated the + // PassCode for the user. + + SMPC_PAIRING_SC_W4_G2_AES_CMAC, + + // Wait for the user to enter Accept/Reject for the Numeric Value + SMPC_PAIRING_SC_W4_NC_ACCEPT, + // Used in both Master/Slave while waiting for the user Pass Code Confirmation. + + SMPC_PAIRING_SC_W4_USER_PASSCODE_CONFIRMATION, + + //----------------------------- + // Secure Connections - Passkey + //----------------------------- + + // Used in both Master/Slave while the user is entering the PassKey + SMPC_PAIRING_SC_PASSKEY_W4_PASSKEY_RAND, + + // Used in both Master/Slave while Random numbers Nai,Nbi are being generated. + SMPC_PAIRING_SC_PASSKEY_W4_LOCAL_RAND_N_P1, + + // Used in both Master/Slave while Random numbers Nai,Nbi are being generated. + SMPC_PAIRING_SC_PASSKEY_W4_LOCAL_RAND_N_P2, + + // Used in both Master/Slave while waiting for the commitment value Cai,Cbi from the peer + SMPC_PAIRING_SC_PASSKEY_W4_PEER_COMMITMENT, + + // Used in both Master/Slave while using AES_CMAC during F4 calculation of the commitment + SMPC_PAIRING_SC_PASSKEY_W4_F4_COMMITMENT_DETERMINATION, + + // Used in both Master/Slave while waiting for the random number Nai,Nbi from the peer + SMPC_PAIRING_SC_PASSKEY_W4_PEER_RAND, + + // Used in both Master/Slave while using AES_CMAC during F4 calculation for the commitment check + SMPC_PAIRING_SC_PASSKEY_W4_F4_COMMITMENT_CHECK, + + + // OOB + SMPC_PAIRING_SC_OOB_W4_LOCAL_RAND_N_P1, + + SMPC_PAIRING_SC_OOB_W4_LOCAL_RAND_N_P2, + + SMPC_PAIRING_SC_OOB_W4_LOCAL_RAND_R_P1, + + SMPC_PAIRING_SC_OOB_W4_LOCAL_RAND_R_P2, + + SMPC_PAIRING_SC_OOB_W4_F4_COMMITMENT_DETERMINATION, + + SMPC_PAIRING_SC_OOB_W4_F4_COMMITMENT_CHECK, + + SMPC_PAIRING_SC_OOB_W4_PEER_RAND, + + // Wait for OOB data (A,Ca,Ra OR B,Cb,Rb) to be recieved from Peer. + SMPC_PAIRING_SC_OOB_W4_OOB_DATA, + + // Secure Connections Authentication Phase 2 + + // Wait for the AES_CMACsalt to generate T + SMPC_PAIRING_SC_W4_F5_P1, + + // Wait for the AES_CMAC to generate MACKEY + SMPC_PAIRING_SC_W4_F5_P2, + + // Wait for the AES_CMAC to generate LTK + SMPC_PAIRING_SC_W4_F5_P3, + + // Wait for the AES_CMAC to complete the DHKEY check + SMPC_PAIRING_SC_W4_F6_DHKEY_CHECK, + + // Wait for DHkey_Check from the peer + SMPC_PAIRING_SC_W4_PEER_DHKEY_CHECK, + + SMPC_PAIRING_SC_W4_F6_DHKEY_VERIFICATION, + + SMPC_PAIRING_SC_W4_DHKEY_KEY_COMPLETE, + + SMPC_PAIRING_SC_W4_ENCRYPTION_START, + + SMPC_PAIRING_SC_W4_ENCRYPTION_CHANGE, + + #endif // (SECURE_CONNECTIONS) + /**------------------------------------** + * Transport Keys Distribution Phase * + **------------------------------------**/ + + /// Default pairing remote waiting state + SMPC_PAIRING_APP_WAIT, + /// Is waiting for the LTK from application + SMPC_PAIRING_APP_LTK_WAIT, + /// Is waiting for the Identity Resolving Key from application + SMPC_PAIRING_APP_IRK_WAIT, + /// Is waiting for the CSRK from application + SMPC_PAIRING_APP_CSRK_WAIT, + + + /// Default pairing remote waiting state + SMPC_PAIRING_REM_WAIT, + /// Is waiting for the remote LTK + SMPC_PAIRING_REM_LTK_WAIT, + /// Is waiting for the remote EDIV and Rand Value + SMPC_PAIRING_REM_MST_ID_WAIT, + /// Is waiting for the remote IRK + SMPC_PAIRING_REM_IRK_WAIT, + /// Is waiting for the remote BD Address + SMPC_PAIRING_REM_BD_ADDR_WAIT, + /// Is waiting for the remote CSRK + SMPC_PAIRING_REM_CSRK_WAIT, + + /******************************************************** + * Signing Procedure + ********************************************************/ + /// Generation of L + SMPC_SIGN_L_GEN, + /// Generation of Ci + SMPC_SIGN_Ci_GEN, + + /******************************************************** + * Encryption Procedure (STK or LTK) + ********************************************************/ + /// Is waiting the change encryption event with LTK + SMPC_START_ENC_LTK, + /// Is waiting the change encryption event with STK + SMPC_START_ENC_STK +}; + +/* + * FUNCTION DEFINITION + **************************************************************************************** + */ + +#if (BLE_CENTRAL) +/** + **************************************************************************************** + * @brief Handles pairing request from GAP, start the pairing procedure + * + * @param[in] idx Connection Index + * @param[in] pairing Pairing Information + * + * @return Status of Pairing start + **************************************************************************************** + */ +uint8_t smpc_pairing_start(uint8_t idx, struct gapc_pairing *pairing); +#endif // (BLE_CENTRAL) + + +/** + **************************************************************************************** + * @brief Handles TK exchange part of pairing + * + * @param[in] idx Connection Index + * @param[in] accept True if pairing is accepted, False else + * @param[in] tk The TK transmitted by application + * + * @return status of pairing + **************************************************************************************** + */ +uint8_t smpc_pairing_tk_exch(uint8_t idx, bool accept, struct gap_sec_key *tk); + +/** + **************************************************************************************** + * @brief Handles LTK exchange part of pairing + * + * @param[in] idx Connection Index + * @param[in] ltk The LTK transmitted by application + * + * @return status of pairing + **************************************************************************************** + */ +uint8_t smpc_pairing_ltk_exch(uint8_t idx, struct gapc_ltk* ltk); + + +/** + **************************************************************************************** + * @brief Handles IRK exchange part of pairing + * + * @param[in] idx Connection Index + * @param[in] irk The IRK transmitted by application + * @param[in] identity Device identity address + * + * @return status of pairing + **************************************************************************************** + */ +uint8_t smpc_pairing_irk_exch(uint8_t idx, struct gap_sec_key* irk, struct gap_bdaddr *identity); + +/** + **************************************************************************************** + * @brief Handles CSRK exchange part of pairing + * + * @param[in] idx Connection Index + * @param[in] csrk The CSRK transmitted by application + * + * @return status of pairing + **************************************************************************************** + */ +uint8_t smpc_pairing_csrk_exch(uint8_t idx, struct gap_sec_key *csrk); + +#if (SECURE_CONNECTIONS) +/** + **************************************************************************************** + * @brief Handles OOB exchange part of pairing + * + * @param[in] idx Connection Index + * @param[in] accept Accept or Reject the OOB (reject if OOB reception not available on the device) + * @param[in] csrk The OOB Confirm and OOB Rand from the peer + * + * @return status of pairing + **************************************************************************************** + */ + +uint8_t smpc_pairing_oob_exch(uint8_t idx, bool accept, struct gapc_oob *oob); + +/** + **************************************************************************************** + * @brief Handles Numeric Value Acceptance as part of pairing + * + * @param[in] idx Connection Index + * @param[in] accept Accept or Reject the numeric comparison + * + * @return status of pairing + **************************************************************************************** + */ + +uint8_t smpc_pairing_nc_exch(uint8_t idx,uint8_t accept ); + +#endif // (SECURE_CONNECTIONS) +/** + **************************************************************************************** + * @brief Handles reception of pairing response information + * + * @param[in] idx Connection Index + * @param[in] accept True if pairing is accepted, False else + * @param[in] feat Pairing response feature information + * + * @return status of pairing + **************************************************************************************** + */ +uint8_t smpc_pairing_rsp(uint8_t idx, bool accept, struct gapc_pairing *feat); + + +#if (BLE_PERIPHERAL) + +/** + **************************************************************************************** + * @brief Handles reception of pairing request information + * + * @param[in] idx Connection Index + * @param[in] feat Pairing request feature information + **************************************************************************************** + */ +void smpc_pairing_req_handler(uint8_t idx, struct gapc_pairing *feat); + +/** + **************************************************************************************** + * @brief Handles request to send a security request to peer device + * + * @param[in] idx Connection Index + * @param[in] auth Requested Authentication Level + * + * @return status of the request + **************************************************************************************** + */ +uint8_t smpc_security_req_send(uint8_t idx, uint8_t auth); +#endif // (BLE_PERIPHERAL) + + +#if (BLE_CENTRAL) +/** + **************************************************************************************** + * @brief Master requests to start encryption + * + * @param[in] idx Connection Index + * @param[in] ltk LTK information + * + * @return status of the request + **************************************************************************************** + */ +uint8_t smpc_encrypt_start(uint8_t idx, struct gapc_ltk *ltk); +#endif //(BLE_CENTRAL) + + +#if (BLE_PERIPHERAL) + +/** + **************************************************************************************** + * @brief Handles reception of encryption request + * + * @param[in] idx Connection Index + * @param[in] ltk LTK to search information + **************************************************************************************** + */ +void smpc_encrypt_start_handler(uint8_t idx, struct gapc_ltk *ltk); + +/** + **************************************************************************************** + * @brief Slave respond to peer device encryption request + * + * @param[in] idx Connection Index + * @param[in] accept Accept or not to start encryption + * @param[in] ltk LTK information + * @param[in] key_size Encryption key size + **************************************************************************************** + */ +void smpc_encrypt_cfm(uint8_t idx, bool accept, struct gap_sec_key *ltk, uint8_t key_size); +#endif //(BLE_PERIPHERAL) + + +/** + **************************************************************************************** + * @brief Request to sign an attribute packet or check signature + * + * @param[in] idx Connection Index + * @param[in] param ATT packet information + * + * @return status of signature request + **************************************************************************************** + */ +uint8_t smpc_sign_command(uint8_t idx, struct gapc_sign_cmd *param); + + +/** + **************************************************************************************** + * @brief Continue signature generation or check of an attribute packet after an AES. + * + * @param[in] idx Connection Index + * @param[in] aes_res Result of AES calculation + **************************************************************************************** + */ +void smpc_sign_cont(uint8_t idx, uint8_t* aes_res); + +/** + **************************************************************************************** + * @brief Continue generation of rand number for confirm value. + * + * @param[in] idx Connection Index + * @param[in] randnb Generated Random Number + **************************************************************************************** + */ +void smpc_confirm_gen_rand(uint8_t idx, rand_nb_t* randnb); + +/** + **************************************************************************************** + * @brief Continue Calculation of Confirm Value or STK after AES. + * + * @param[in] idx Connection Index + * @param[in] aes_res Result of AES calculation + **************************************************************************************** + */ +void smpc_calc_confirm_cont(uint8_t idx, uint8_t* aes_res); + +/** + **************************************************************************************** + * @brief Send an KeyPress Notification Event to the Host + * + * @param[in] idx Connection Index + * @param[in] keypress KeyPress Type + **************************************************************************************** + */ +void smpc_key_press_notification_ind(uint8_t idx, uint8_t keypress); + +/** + **************************************************************************************** + * @brief Stop the timer used to detect a SMP Timeout + * + * @param[in] conidx Connection Index + **************************************************************************************** + */ +void smpc_clear_timeout_timer(uint8_t conidx); + + +/** + **************************************************************************************** + * @brief Handle reception of a SMP PDU sent by the peer device. + * + * @param[in] conidx Connection Index + * @param[in] pdu Unpacked PDU + **************************************************************************************** + */ +void smpc_pdu_recv(uint8_t conidx, struct l2cc_pdu *pdu); + +/** + **************************************************************************************** + * @brief Send a SMP PDU to the peer device + * + * @param[in] conidx Connection Index + * @param[in] cmd_code Code of the PDU to send + * @param[in] value Unpacked value + **************************************************************************************** + */ +void smpc_pdu_send(uint8_t conidx, uint8_t cmd_code, void *value); + + +/** + **************************************************************************************** + * @brief Inform the HL that the pairing procedure currently in progress is over. + * + * @param[in] conidx Connection Index + * @param[in] role Current role of the device + * @param[in] status Status + * @param[in] start_ra_timer Indicate if the repeated attempts timer shall be started in + * the case of a pairing failed. + **************************************************************************************** + */ +void smpc_pairing_end(uint8_t conidx, uint8_t role, uint8_t status, bool start_ra_timer); + + +/** + **************************************************************************************** + * @brief Handle reception of a DH Key from HCI + * + * @param[in] conidx Connection Index + * @param[in] status Indicates if HCI request Succeeded or Failed + * @param[in] dh_key Diffie Helman Key - 32 Bytes + **************************************************************************************** + */ +void smpc_handle_dh_key_check_complete(uint8_t conidx,const uint8_t* dh_key); + +#endif // (BLE_SMPC) +#endif //(SMPC_API_H_) + +/// @} SMPC_API diff --git a/services/ble_stack/hl/src/gap/smpc/smpc_crypto.h b/services/ble_stack/hl/src/gap/smpc/smpc_crypto.h new file mode 100644 index 0000000..2547b00 --- /dev/null +++ b/services/ble_stack/hl/src/gap/smpc/smpc_crypto.h @@ -0,0 +1,164 @@ +#ifndef SMPC_CRYPTO_H_ +#define SMPC_CRYPTO_H_ + +#include "rwip_config.h" +#if (SECURE_CONNECTIONS) +#include "../smp_common.h" + +/** + **************************************************************************************** + * @brief Initiates the F4 crypto function + * + * @param[in] conidx connection identifier + * @param[in] U pointer to array of bytes (see spec) + * @param[in] V pointer to array of bytes (see spec) + * @param[in] X pointer to array of bytes (see spec) + * @param[in] Z single byte value (see spec) + * @return none. + **************************************************************************************** + */ +void smpc_f4_Init(uint8_t conidx,uint8_t* U,uint8_t* V,uint8_t* X,uint8_t Z); + + +/** + **************************************************************************************** + * @brief Cleans up after the F4 crypto function, freeing any memory which had been allocated + * + * @param[in] conidx connection identifier + * @return none. + **************************************************************************************** + */ +void smpc_f4_complete(uint8_t conidx); + + +/** + **************************************************************************************** + * @brief Initiates the G2 crypto function + * + * @param[in] conidx connection identifier + * @param[in] U pointer to array of bytes (see spec) + * @param[in] V pointer to array of bytes (see spec) + * @param[in] X pointer to array of bytes (see spec) + * @param[in] Y pointer to array of bytes (see spec) + * @return none. + **************************************************************************************** + */ +void smpc_g2_init(uint8_t conidx, uint8_t* U, uint8_t* V, uint8_t* X, uint8_t* Y); + +/** + **************************************************************************************** + * @brief Cleans up after the G2 crypto function, freeing any memory which had been allocated + * + * @param[in] conidx connection identifier + * @return none. + **************************************************************************************** + */ +void smpc_g2_complete(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Initiates the F5 crypto function + * + * @param[in] conidx connection identifier + * @param[in] W pointer to the DH Key + * @param[in] N1 pointer to 16 byte random number + * @param[in] N2 pointer to 16 byte random number + * @param[in] A1 pointer to array representing address of device + * @param[in] A2 pointer to array representing address of device + * @return none. + **************************************************************************************** + */ +void smpc_f5_init(uint8_t conidx, uint8_t* W,uint8_t* N1,uint8_t* N2,uint8_t* A1,uint8_t* A2); + +/** + **************************************************************************************** + * @brief Cleans up after the F5 crypto function, freeing any memory which had been allocated + * + * @param[in] conidx connection identifier + * @return none. + **************************************************************************************** + */ +void smpc_f5_complete(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Initiates the F6 crypto function + * + * @param[in] conidx connection identifier + * @param[in] W pointer to Mac Key + * @param[in] N1 pointer to 16 byte random number + * @param[in] N2 pointer to 16 byte random number + * @param[in] R pointer to array of bytes (see spec) + * @param[in] IoCap pointer to array representing IO capabilities of device + * @param[in] A1 pointer to array representing address of device + * @param[in] A2 pointer to array representing address of device + * @return none. + **************************************************************************************** + */ +void smpc_f6_init(uint8_t conidx,uint8_t* W, uint8_t* N1, uint8_t* N2, uint8_t* R, uint8_t* IOcap, uint8_t* A1, uint8_t* A2); + +/** + **************************************************************************************** + * @brief Cleans up after the F6 crypto function, freeing any memory which had been allocated + * + * @param[in] conidx connection identifier + * @return none. + **************************************************************************************** + */ +void smpc_f6_complete(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Initiates the AES CMAC crypto function. Allocate memory for the CMAC and + * begins the subkey generation + * + * @param[in] conidx connection identifier + * @param[in] K pointer to the Key to be used + * @param[in] M pointer to the block of data the data on which the CMAC is performed + * @param[in] M_len length (in bytes) of the block of data M + * @return none. + **************************************************************************************** + */ +void smpc_aes_cmac_init(uint8_t conidx,uint8_t* K,uint8_t* M,uint8_t M_len); + +/** + **************************************************************************************** + * @brief Continues subsequent stages of the AES CMAC crypto function + * + * @param[in] conidx connection identifier + * @param[in] aes_res point to the result of the previous stage of the AES CMAC + * + * @return none. + **************************************************************************************** + */ +void smpc_aes_cmac_continue(uint8_t conIdx,uint8_t* aes_res); + +/** + **************************************************************************************** + * @brief The final stage of the AES CMAC crypto function + * + * @param[in] conidx connection identifier + * @param[in] aes_res point to the result of the previous stage of the AES CMAC + * + * @return none. + **************************************************************************************** + */ +void smpc_aes_cmac_complete(uint8_t conIdx,uint8_t* aes_res); + +/** + **************************************************************************************** + * @brief Process the next stage of the AES CMAC (wrapping smpc_aes_cmac_continue(..) and + * smpc_aes_cmac_complete(..) + * + * @param[in] conidx connection identifier + * @param[in] aes_res point to the result of the previous stage of the AES CMAC + * + * @returns boolean Indicate if the AES CMAC is complete + **************************************************************************************** + */ + +bool smpc_process_aes_cmac(uint8_t idx,uint8_t* aes_res); +#endif // (SECURE_CONNECTIONS) + + +#endif /* SMPC_CRYPTO_H_ */ diff --git a/services/ble_stack/hl/src/gap/smpc/smpc_int.h b/services/ble_stack/hl/src/gap/smpc/smpc_int.h new file mode 100644 index 0000000..9a4d8ae --- /dev/null +++ b/services/ble_stack/hl/src/gap/smpc/smpc_int.h @@ -0,0 +1,498 @@ +#ifndef SMPC_INT_H_ +#define SMPC_INT_H_ + +/** + **************************************************************************************** + * @addtogroup SMP_INT Security Manager Protocol Internal + * @ingroup HOST + * @brief Security Manager Protocol Internals. + * @{ + * + **************************************************************************************** + */ + + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_SMPC) +#include "smpc.h" + +#include "../smp_common.h" + +#include +#include + +#include "co_bt.h" +#include "gap.h" + +#include "smpc_api.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// Minimum Encryption key size +#define SMPC_MIN_ENC_SIZE_LEN (7) +/// Maximum Encryption Key size +#define SMPC_MAX_ENC_SIZE_LEN (16) + + +/// Pairing Request and Pairing Response PDU Length +#define SMPC_CODE_PAIRING_REQ_RESP_LEN (7) + + +/* + * ENUMERATIONS + **************************************************************************************** + */ + + +///Security Properties for distributed keys(all have the issued STK's properties) +enum +{ + ///No security properties + SMP_KSEC_NONE = 0x00, + ///Unauthenticated no MITM + SMP_KSEC_UNAUTH_NO_MITM, + ///Authenticated with MITM + SMP_KSEC_AUTH_MITM, +}; + +/// Repeated Attempts Attack Detection status +enum smpc_attempts_status +{ + /// No attack has been detected + SMPC_REP_ATTEMPTS_NO_ERROR = GAP_ERR_NO_ERROR, // 0x00 + /// An attack has already been detected, drop the message + SMPC_REP_ATTEMPTS_ATTACK, + /// An attack has been detected, an indication has been sent to the HL + SMPC_REP_ATTEMPS_ATTACK_DETECTED, + /// Repeated Attempt detected, need to send a Pairing Failed PDU to the peer device + SMPC_REP_ATTEMPT = SMP_ERROR_REPEATED_ATTEMPTS // 0x09 +}; + + +/// STK generation methods +enum smpc_method +{ + ///Just Works Method + SMPC_METH_JW = 0x00, + ///PassKey Entry Method + SMPC_METH_PK, + ////OOB Method + SMPC_METH_OOB, + ////Numeric Comparison + SMPC_METH_NC +}; + +/// Signature Command Types +enum +{ + /// Generate Signature + SMPC_SIGN_GEN = 0x00, + /// Verify Signature + SMPC_SIGN_VERIF +}; + +enum +{ + /// Use of STK in start encryption command + SMPC_USE_STK = 0x00, + /// Use of LTK in start encryption command + SMPC_USE_LTK +}; + +#if (SECURE_CONNECTIONS) +enum +{ + SMP_AES_CMAC_KEY_GENERATION = 0x00, + + SMP_AES_CMAC_BLOCK +}; + +/// Keypress Notification types +enum smpc_notification_type +{ + /// Passkey entry started + SMP_PASSKEY_ENTRY_STARTED = 0x00, + /// Passkey digit entered + SMP_PASSKEY_DIGIT_ENTERED, + /// Passkey digit erased + SMP_PASSKEY_DIGIT_ERASED, + /// Passkey cleared + SMP_PASSKEY_CLEARED, + /// Passkey entry completed + SMP_PASSKEY_ENTRY_COMPLETED +}; +#endif // (SECURE_CONNECTIONS) +/* + * STRUCTURES DEFINITION + **************************************************************************************** + */ + +/* + * GLOBAL VARIABLES DEFINITION + **************************************************************************************** + */ + + +/* + * MACROS + **************************************************************************************** + */ +/// Authentication Request mask +#define SMPC_MASK_AUTH_REQ(req) (req & 0x07) + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Send a GAPM_USE_ENC_BLOCK_CMD message to the SMPM. Shall be use when the AES_128 + * encryption block need to be used. + * + * @param[in] conidx Connection Index + * @param[in] operand_1 First operand + * @param[in] operand_2 Second operand + **************************************************************************************** + */ +void smpc_send_use_enc_block_cmd(uint8_t conidx, + uint8_t *operand_1, uint8_t *operand_2); + + +/** + **************************************************************************************** + * @brief Send a GAPM_GEN_DH_KEY_CMD message to the SMPM. Shall be use when we need to + * generate a DH KEy + * + * @param[in] conidx Connection Index + * @param[in] operand_1 X co-ordinate + * @param[in] operand_2 Y co-ordinate + **************************************************************************************** + */ + +void smpc_send_gen_dh_key_cmd(uint8_t conidx, + uint8_t *operand_1, uint8_t *operand_2); + +/** + **************************************************************************************** + * @brief Send a request to the controller to start the encryption procedure. + * + * @param[in] conidx Connection Index + * @param[in] operand_1 First operand + * @param[in] operand_2 Second operand + **************************************************************************************** + */ +void smpc_send_start_enc_cmd(uint8_t idx, uint8_t key_type, uint8_t *key, + uint8_t *randnb, uint16_t ediv); + +/** + **************************************************************************************** + * @brief Send the LTK provided by the HL to the controller. + * + * @param[in] idx Connection Index + * @param[in] found Indicate if the requested LTK has been found by the application + * @param[in] key Found LTK, used only if found is set to true + **************************************************************************************** + */ +void smpc_send_ltk_req_rsp(uint8_t idx, bool found, uint8_t *key); + +/** + **************************************************************************************** + * @brief Send a SMPC_PAIRING_REQ_IND message to the HL + * + * @param[in] conidx Connection Index + * @param[in] req_type Kind of request + **************************************************************************************** + */ +void smpc_send_pairing_req_ind(uint8_t conidx, uint8_t req_type); + +/** + **************************************************************************************** + * @brief Send a SMPC_PAIRING_IND message to the HL + * + * @param[in] conidx Connection Index + * @param[in] ind_type Kind of indication + * @param[in] value Value to indicate (keys, ...) + **************************************************************************************** + */ +void smpc_send_pairing_ind(uint8_t conidx, uint8_t ind_type, void *value); + +/** + **************************************************************************************** + * @brief Check if the provided pairing features are within the specified range. + * + * @param[in] pair_feat Pairing Features values to check + * + * @param[out] true if features are valid, else false + **************************************************************************************** + */ +bool smpc_check_pairing_feat(struct gapc_pairing *pair_feat); + +/** + **************************************************************************************** + * @brief Check if an attack by repeated attempts has been triggered by the peer device + * + * @param[in] conidx Connection Index + **************************************************************************************** + */ +uint8_t smpc_check_repeated_attempts(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Compute and check the encryption key size to use during the connection. + * + * @param[in] conidx Connection Index + * + * @param[out] true if the resultant EKS is within the specified range [7-16 bytes], else false + **************************************************************************************** + */ +bool smpc_check_max_key_size(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Check if the keys distribution scheme is compliant with the required security + * level + * + * @param[in] conidx Connection Index + * @param[in] sec_level Security level required by the device. + **************************************************************************************** + */ +bool smpc_check_key_distrib(uint8_t conidx, uint8_t sec_level); + +/** + **************************************************************************************** + * @brief Apply the XOR operator to the two provided operands + * + * @param[in|out] result Buffer which will contain the result of the XOR operation + * @param[in] operand_1 First operand + * @param[in] operand_2 Second operand + **************************************************************************************** + */ +void smpc_xor(uint8_t *result, uint8_t *operand_1, uint8_t *operand_2); + +/** + **************************************************************************************** + * @brief Generate the L value during a signature verification/generation procedure. + * + * @param[in] conidx Connection Index + * @param[in] src Indicate the source of the CSRK which will be used (LOCAL or PEER) + **************************************************************************************** + */ +void smpc_generate_l(uint8_t conidx, uint8_t src); + +/** + **************************************************************************************** + * @brief Generate one of the Ci value during a signature verification/generation procedure. + * + * @param[in] conidx Connection Index + * @param[in] src Indicate the source of the CSRK which will be used (LOCAL or PEER) + * @param[in] ci1 Previous computed Ci value + * @param[in] mi 16-byte block used to generate the ci value + **************************************************************************************** + */ +void smpc_generate_ci(uint8_t conidx, uint8_t src, uint8_t *ci1, uint8_t *mi); + +/** + **************************************************************************************** + * @brief Generate the random value exchanged during the pairing procedure (phase 2) + * + * @param[in] conidx Connection Index + * @param[in] state New state of the SMPC task. + **************************************************************************************** + */ +void smpc_generate_rand(uint8_t conidx, uint8_t state); + +/** + **************************************************************************************** + * @brief Generate the first value needed in the confirm value generation + * + * @param[in] conidx Connection Index + * @param[in] role Current role of the device + * @param[in] local true if the confirm value to generate is the confirm value of the + * device, false if it is the remote device's one. + **************************************************************************************** + */ +void smpc_generate_e1(uint8_t conidx, uint8_t role, bool local); + +/** + **************************************************************************************** + * @brief Generate the confirm value + * + * @param[in] conidx Connection Index + * @param[in] role Current role of the device + * @param[in] e1 e1 value + **************************************************************************************** + */ +void smpc_generate_cfm(uint8_t conidx, uint8_t role, uint8_t *e1); + +/** + **************************************************************************************** + * @brief Generate the STK used to encrypt a link after the pairing procedure + * + * @param[in] conidx Connection Index + * @param[in] role Current role of the device + **************************************************************************************** + */ +void smpc_generate_stk(uint8_t conidx, uint8_t role); + +/** + **************************************************************************************** + * @brief Calculate one of the subkey used during the signature generation/verification + * procedure. + * + * @param[in] gen_k2 true if the returned subkeys is k2, false if k1 + * @param[in] l_value L value obtained from the CSRK. + * @param[in|out] subkey Buffer which will contain the generated subkey. + **************************************************************************************** + */ +void smpc_calc_subkeys(bool gen_k2, uint8_t *l_value, uint8_t *subkey); + +/** + **************************************************************************************** + * @brief Start to send the keys defined during the pairing features exchange procedure. + * + * @param[in] conidx Connection Index + * @param[in] role Current role of the device + **************************************************************************************** + */ +void smpc_tkdp_send_start(uint8_t conidx, uint8_t role); + +/** + **************************************************************************************** + * @brief Define the next step of TKDP procedure (sending side). + * + * @param[in] conidx Connection Index + * @param[in] role Current role of the device + **************************************************************************************** + */ +void smpc_tkdp_send_continue(uint8_t conidx, uint8_t role); + +/** + **************************************************************************************** + * @brief Put the task in a state allowing to receive the keys defined during the pairing + * features exchange procedure. + * + * @param[in] conidx Connection Index + * @param[in] role Current role of the device + **************************************************************************************** + */ +void smpc_tkdp_rcp_start(uint8_t conidx, uint8_t role); + +/** + **************************************************************************************** + * @brief Define the next step of TKDP procedure (reception side). + * + * @param[in] conidx Connection Index + * @param[in] role Current role of the device + **************************************************************************************** + */ +void smpc_tkdp_rcp_continue(uint8_t conidx, uint8_t role); + + +/** + **************************************************************************************** + * @brief Start the timer used to detect a Repeated Attempts attack + * + * @param[in] conidx Connection Index + **************************************************************************************** + */ +void smpc_launch_rep_att_timer(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Determine the method which will be used to generate the STK during a pairing + * procedure + * + * @param[in] conidx Connection Index + **************************************************************************************** + */ +void smpc_get_key_sec_prop(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Check if the security mode requested by the application or the peer device can + * be reached with the exchanged pairing features. + * + * @param[in] conidx Connection Index + * @param[in] role Current role of the device + **************************************************************************************** + */ +bool smpc_is_sec_mode_reached(uint8_t conidx, uint8_t role); + +/** + **************************************************************************************** + * @brief Define what to do once a start encryption procedure has been successfully finished. + * + * @param[in] conidx Connection Index + * @param[in] role Current role of the device + * @param[in] status Status + **************************************************************************************** + */ +void smpc_handle_enc_change_evt(uint8_t conidx, uint8_t role, uint8_t status); + + +#if (SECURE_CONNECTIONS) +/** + **************************************************************************************** + * @brief Initiate DHKey Check algorithm + * + * @param[in] conidx Connection Index + **************************************************************************************** + */ +void smpc_initiate_dhkey_check(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Initiates the f5 algorithm to calculate the MacKey and LTK for a link + * + * @param[in] conidx Connection Index + * + **************************************************************************************** + */ + +void smpc_init_mac_key_calculation(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Initiates the f6 algorithm to verify a DH Key Check. + * + * @param[in] conidx Connection Index + * + **************************************************************************************** + */ + +void smpc_initiate_dhkey_verification(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Determines the next bit of the passkey to be used + * + * @param[in] conidx Connection Index + * + **************************************************************************************** + */ +uint8_t smpc_get_next_passkey_bit(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Checks if secure connections are enabled on a link + * + * @param[in] conidx Connection Index + * + **************************************************************************************** + */ +bool smpc_secure_connections_enabled(uint8_t idx); + +#endif // (SECURE_CONNECTIONS) +#endif //(BLE_SMPC) +#endif //SMPC_INT_H_ + +/// @} SMPC diff --git a/services/ble_stack/hl/src/gap/smpc/smpc_util.h b/services/ble_stack/hl/src/gap/smpc/smpc_util.h new file mode 100644 index 0000000..4e618d8 --- /dev/null +++ b/services/ble_stack/hl/src/gap/smpc/smpc_util.h @@ -0,0 +1,69 @@ +#ifndef SMPC_UTIL_H_ +#define SMPC_UTIL_H_ + +/** + **************************************************************************************** + * @addtogroup SMPC_UTIL Utility + * @ingroup SMPC + * @brief Contains utility functions and macros for SMPC. + * + * The SMPC Utilities block contains key generating and security related functions + * that are useful in accomplishing the task of the security manager protocol + * layer of the Bluetooth Low Energy. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_SMPC) + +#include "../smp_common.h" +#include + +#include "l2cc_pdu.h" +#include "smpc_int.h" + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// SMPC command PDU construct function pointer type definition +typedef void (*smpc_construct_pdu_t)(struct l2cc_pdu *pdu, void *value); + +/// SMPC command PDU reception functions +typedef void (*smpc_recv_pdu_t)(uint8_t idx, struct l2cc_pdu *pdu); + +/* + * GLOBAL VARIABLES DECLARATION + **************************************************************************************** + */ + +extern const smpc_construct_pdu_t smpc_construct_pdu[L2C_CODE_SECURITY_MAX]; +extern const smpc_recv_pdu_t smpc_recv_pdu[L2C_CODE_SECURITY_MAX]; + +/* + * FUNCTIONS DECLARATION + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Parameter checking function of SMP PDU packets. + * + * @param[in] pdu Pointer to the data part of the SMP command PDU. + * + * @return Value of check parameter status, to be reported to host or back to peer. + **************************************************************************************** + */ +uint8_t smpc_check_param(struct l2cc_pdu *pdu); + +#endif //(BLE_SMPC) +#endif //(SMPC_UTIL_H_) + +/// @} SMPC_UTIL diff --git a/services/ble_stack/hl/src/gatt/attc/attc.h b/services/ble_stack/hl/src/gatt/attc/attc.h new file mode 100644 index 0000000..e4bea89 --- /dev/null +++ b/services/ble_stack/hl/src/gatt/attc/attc.h @@ -0,0 +1,114 @@ +#ifndef ATTC_H_ +#define ATTC_H_ + +/** + **************************************************************************************** + * @addtogroup ATTC Attribute Client + * @ingroup ATT + * @brief Attribute Protocol Client + * + * The ATTC module is responsible for handling messages intended for the attribute + * profile client. It has defined interfaces with @ref ATTM "ATTM". + * + * @{ + * + **************************************************************************************** + */ +#include "rwip_config.h" + +#include +#include "l2cc.h" +#include "ke_task.h" + +#if (BLE_ATTC) +/* + * INCLUDE FILES + **************************************************************************************** + */ +/* + * DEFINES + **************************************************************************************** + */ + +/// Allocate a Attribute PDU packet for a specific attribute request. +#define ATTC_ALLOCATE_ATT_REQ(conidx, opcode, pdu_type, value_len)\ + L2CC_ATT_PDU_ALLOC_DYN(conidx, opcode, KE_BUILD_ID(TASK_GATTC, conidx), pdu_type, value_len) + +/* + * DATA STRUCTURES + **************************************************************************************** + */ + +/// Peer device event registration +struct attc_register_evt +{ + /// list header + struct co_list_hdr hdr; + /// Attribute start handle + uint16_t start_hdl; + /// Attribute end handle + uint16_t end_hdl; + /// Task to be notified + ke_task_id_t task; +}; + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Sends Indication reception confirmation message + * + * @param[in] conidx connection index + * + **************************************************************************************** + */ +void attc_send_hdl_cfm(uint8_t conidx); + +/** + **************************************************************************************** + * @brief Sends write execute. + * + * @param[in] conidx connection index + * @param[in] flag write execute flag (write or discard) + * + **************************************************************************************** + */ +void attc_send_execute(uint8_t conidx, uint8_t flag); + + +/** + **************************************************************************************** + * @brief Send a PDU Attribute request packet + * + * @param[in] conidx Index of the connection with the peer device + * @param[in] pdu PDU Packet + **************************************************************************************** + */ +void attc_send_att_req(uint8_t conidx, void *pdu); + +#endif /* (BLE_ATTC) */ + +#if (BLE_CENTRAL || BLE_PERIPHERAL) +/** + **************************************************************************************** + * @brief Handles reception of PDU Packet + * + * @param[in] conidx Index of the connection with the peer device + * @param[in] param Received PDU Packet + * + * @return If message has been proceed or consumed + **************************************************************************************** + */ +int attc_l2cc_pdu_recv_handler(uint8_t conidx, struct l2cc_pdu_recv_ind *param); +#endif /* #if (BLE_CENTRAL || BLE_PERIPHERAL) */ + +/// @} ATTC +#endif // ATT_H_ diff --git a/services/ble_stack/hl/src/gatt/attm/attm_db.h b/services/ble_stack/hl/src/gatt/attm/attm_db.h new file mode 100644 index 0000000..500b6e2 --- /dev/null +++ b/services/ble_stack/hl/src/gatt/attm/attm_db.h @@ -0,0 +1,355 @@ +#ifndef ATTM_DB_H_ +#define ATTM_DB_H_ + +/** + **************************************************************************************** + * @addtogroup ATTDB Database + * @ingroup ATTM + * @brief Attribute Protocol Database + * + * The ATTDB module is responsible for providing different sets of attribute databases + * for Attribute Profile server. + * + * This module can be tailored by client, to match the requirement of the desired database. + * + * @{ + * + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_ATTS) +#include +#include "rwip_config.h" +#include "ke_task.h" +#include "attm.h" +#include "gattm_task.h" + +/* + * DEFINES + **************************************************************************************** + */ + + +/* + * TYPE DEFINITION + **************************************************************************************** + */ +#if(BLE_ATTS) + +/** + * Attribute Description + */ +struct attm_att_desc +{ + /** + * 16 bits UUID or data offset used to retrieve 32 or 128 bits UUID in service memory block + */ + uint16_t uuid; + + /** + * Attribute Permission (@see attm_perm_mask) + */ + uint16_t perm; + + /** + * value information (@see attm_value_perm_mask) + */ + union att_info + { + /// attribute max length (RI = 1) + uint16_t max_length; + + /// attribute value offset pointer (RI = 0) + uint16_t offset; + } info; +}; + +/// attribute value if present in database +struct attm_att_value +{ + /// Maximum attribute length + uint16_t max_length; + /// currrent attribute length that can be read. + uint16_t length; + ///value data pointer + uint8_t value[__ARRAY_EMPTY]; +}; + +/// service description +struct attm_svc_desc +{ + /// Service Start Handle + uint16_t start_hdl; + /// Service End Handle + uint16_t end_hdl; + /// Task identifier that manages service + uint16_t task_id; + + /** + * Service Permission (@see attm_svc_perm_mask) + */ + uint8_t perm; + + /// number of attributes present in service (end_hdl - start_hdl - 1) + uint8_t nb_att; + + /// Service 16 bits UUID (LSB First) or data offset used to retrieve 32 or 128 bits + /// UUID in service memory block + uint16_t uuid; +}; + +/** + * Service description present in attribute database + */ +struct attm_svc +{ + /// Next Service + struct attm_svc* next; + + /// service description + struct attm_svc_desc svc; + + /** + * List of attribute description present in service. + */ + struct attm_att_desc atts[__ARRAY_EMPTY]; +}; + +/// Attribute element information +struct attm_elmt +{ + /// element info + union elem_info + { + /// attribute info pointer + struct attm_att_desc* att; + + /// service info pointer + struct attm_svc_desc* svc; + } info; + + /// use to know if current element is a service or an attribute + bool service; +}; + +/// ATTM General Information Manager +struct attm_db +{ + /** + * ************************************************************************************** + * @brief Attribute database + * + * The Attribute database is a list of attribute services sorted by handle number. + * This database shall be initiate by GAP, GATT, profiles and application process at + * startup and must not change during runtime. + * + * Database initialization shall be deterministic in order to always have service handle + * at same position in database during all product life-cycle. This is required since + * database client can save position of services in database to not perform service + * discovery at each connection. + *************************************************************************************** + */ + struct attm_svc * svcs; + + /** + *************************************************************************************** + * Last attribute service searched. + * + * Used as a cached variable, it's used to reduce handle search duration. + *************************************************************************************** + */ + struct attm_svc * cache; + + /** + * Temporary value used for read operation on service and characteristics attributes + */ + uint8_t temp_val[ATT_UUID_128_LEN + ATT_HANDLE_LEN + ATT_HANDLE_LEN]; +}; + + + + + +#endif //(BLE_ATTS) + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + * Check if Service handle Range can be allocated in Database, and if handle should be + * dynamically allocated, calculate first available handle range. + * + * @param[in|out] svc_desc Service information to add in DB + * + * @return status of operation + */ +uint8_t attmdb_svc_check_hdl(struct gattm_svc_desc* svc_desc); + +/** + **************************************************************************************** + * @brief Add a service in database. + * + * According to service start handle and number of attribute, ATTM DB allocate a set of + * attribute handles, then using other parameters it allocate a buffer used to describe + * service, and allocate attributes + their values. + * + * If start_hdl = 0, it allocated service using first available handle (start_hdl is + * modified); else it will allocate service according to given start handle. + * + * + * @param[in|out] svc_desc Service description. + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If service allocation succeeds. + * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter or UUIDs value invalid + * - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer. + **************************************************************************************** + */ +uint8_t attmdb_add_service(struct gattm_svc_desc* svc_desc); + + + + +/** + **************************************************************************************** + * @brief Search in database from which service attribute handle comes from. + * + * @param[in] handle Attribute handle. + * + * @return Services that contains attribute handle; NULL if handle not available in + * database. + **************************************************************************************** + */ +struct attm_svc * attmdb_get_service(uint16_t handle); + +/** + **************************************************************************************** + * @brief Search in database Attribute pointer using attribute handle. + * + * @param[in] handle Attribute handle. + * @param[out] elmt Attribute element to fill + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If attribute found. + * - @ref ATT_ERR_INVALID_HANDLE: If No Attribute found + **************************************************************************************** + */ +uint8_t attmdb_get_attribute(uint16_t handle, struct attm_elmt*elmt); + +/** + **************************************************************************************** + * @brief Retrieve attribute at or after specified handle + * + * Retrieve first attribute with handle >= parameter handle. + * Parameter handle is updated according found attribute. + * + * @param[in|out] handle Attribute handle. + * @param[out] elmt Attribute element to fill + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If attribute found. + * - @ref ATT_ERR_INVALID_HANDLE: If No Attribute found + **************************************************************************************** + */ +uint8_t attmdb_get_next_att(uint16_t * handle, struct attm_elmt*elmt); + +/** + **************************************************************************************** + * Check if attribute element UUID is equals to uuid given in parameter. + * + * @param elmt Attribute element that can be a UUID 16 or 128 bits + * @param uuid16 UUID 16 bits to compare + * + * @return True if UUIDs matches, False else. + **************************************************************************************** + */ +bool attmdb_uuid16_comp(struct attm_elmt *elmt, uint16_t uuid16); + +/** + **************************************************************************************** + * @brief Retrieve attribute value Max Length + * + * @param[in] elmt Attribute element information + * @param[out] length Max length Size of attribute value + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If request succeeds + * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute is read only + **************************************************************************************** + */ +uint8_t attmdb_get_max_len(struct attm_elmt* elmt, att_size_t* length); + + +/** + **************************************************************************************** + * @brief Retrieve attribute UUID + * + * @param[in] elmt Attribute information. + * @param[out] uuid_len Size of attribute UUID + * @param[out] uuid UUID value to update + * @param[in] srv_uuid For a service, if set, return service UUID + * @param[in] air Prepare UUID for the air (For a 32 bit UUID, returns a 128 bit UUID) + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If request succeeds + * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database + **************************************************************************************** + */ +uint8_t attmdb_get_uuid(struct attm_elmt *elmt, uint8_t* uuid_len, uint8_t* uuid, bool srv_uuid, bool air); + +/** + **************************************************************************************** + * @brief Retrieve attribute permission + * If access mask is set, service authentication or encryption key size value can be loaded. + * + * @param[in] handle Attribute handle. + * @param[out] perm Permission value to return + * @param[in] mode_mask Mode Access mask to check type of access + * parameter (0 return full attribute permission) + * @param[in] perm_mask Permission Access mask to check only specific permission + * @param[in|out] elmt Attribute information + * + * @return Command status code: + * - @ref ATT_ERR_NO_ERROR: If request succeeds + * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database. + * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If mode is disabled. + * - @ref ATT_ERR_INSUFF_AUTHOR: when service is disabled. + * - @ref ATT_ERR_INSUFF_ENC_KEY_SIZE: + **************************************************************************************** + */ +uint8_t attmdb_att_get_permission(uint16_t handle, uint16_t* perm, uint16_t mode_mask, + uint16_t perm_mask, struct attm_elmt *elmt); + + +#if (RW_DEBUG) + +/** + **************************************************************************************** + * @brief Retrieve number of services. + * + * @return number of services + **************************************************************************************** + */ +uint8_t attmdb_get_nb_svc(void); + +/** + **************************************************************************************** + * @brief Retrieve services informations + * + * @param[in] svc_info Services information array to update + **************************************************************************************** + */ +void attmdb_get_svc_info(struct gattm_svc_info* svc_info); +#endif /* (RW_DEBUG) */ + +#endif // #if (BLE_ATTS) + +/// @} ATTDB +#endif // ATTM_DB_H_ diff --git a/services/ble_stack/hl/src/gatt/atts/atts.h b/services/ble_stack/hl/src/gatt/atts/atts.h new file mode 100644 index 0000000..c6929f2 --- /dev/null +++ b/services/ble_stack/hl/src/gatt/atts/atts.h @@ -0,0 +1,138 @@ +#ifndef ATTS_H_ +#define ATTS_H_ + +/** + **************************************************************************************** + * @addtogroup ATTS Attribute Server + * @ingroup ATT + * @brief Attribute Protocol Server + * + * The ATTS module is responsible for handling messages intended for the attribute + * profile server. It has defined interfaces with @ref ATTM "ATTM". + * + * + * @{ + * + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_ATTS) +#include "att.h" +#include "compiler.h" +#include +#include "co_list.h" +#include "gattc_task.h" +#include "l2cc.h" + +/* + * DEFINES + **************************************************************************************** + */ + + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + + +/** + * Confirmation of write signed (signature verified) + * + * @param[in] conidx Connection Index + * @param[in] length Signed Data Length + * @param[in] sign_data Signed Data + */ +void atts_write_signed_cfm(uint8_t conidx, uint16_t length, uint8_t* sign_data); + + +/** + **************************************************************************************** + * @brief Send an attribute error response to peer. + * + * @param[in] conidx Index of the connection with the peer device + * @param[in] opcode failing operation code + * @param[in] uuid attribute UUID + * @param[in] error error code + **************************************************************************************** + */ +void atts_send_error(uint8_t conidx, uint8_t opcode, uint16_t uuid, uint8_t error); + + +/** + **************************************************************************************** + * @brief Format the Write Response PDU and send it after receiving a Write Request PDU + * @param[in] conidx Index of the connection with the peer device + * @param[in] atthdl Attribute handle for which to send the response + * @param[in] status ATT error code + **************************************************************************************** + */ +void atts_write_rsp_send(uint8_t conidx, uint16_t atthdl, uint8_t status); + + +/** + **************************************************************************************** + * @brief Sends a value notification/indication command + * + * @param[in] conidx Connection Index + * @param[in] event Event parameters to send + * + * @return If notification can be sent or not + **************************************************************************************** + */ +uint8_t atts_send_event(uint8_t conidx, struct gattc_send_evt_cmd *event); + + +/** + * @brief Clear allocated prepare write temporary data. + * + * @param[in] conidx connection index + */ +void atts_clear_prep_data(uint8_t conidx); + + +/** + * @brief Clear allocated temporary data used for ATTS response. + * + * @param[in] conidx connection index + */ +void atts_clear_rsp_data(uint8_t conidx); + +/** + * @brief Clear temporary attribute read data present in cache. + * + * @param[in] conidx connection index + */ +void atts_clear_read_cache(uint8_t conidx); + + +/// @} ATTS +#endif /* (BLE_ATTS) */ + +#if (BLE_CENTRAL || BLE_PERIPHERAL) +/** + **************************************************************************************** + * @brief Handles reception of PDU Packet + * + * @param[in] conidx Index of the connection with the peer device + * @param[in] param Received PDU Packet + * + * @return If message has been proceed or consumed + **************************************************************************************** + */ +int atts_l2cc_pdu_recv_handler(uint8_t conidx, struct l2cc_pdu_recv_ind *param); +#endif /* #if (BLE_CENTRAL || BLE_PERIPHERAL) */ + +#endif // ATTS_H_ diff --git a/services/ble_stack/hl/src/gatt/gatt.h b/services/ble_stack/hl/src/gatt/gatt.h new file mode 100644 index 0000000..2675740 --- /dev/null +++ b/services/ble_stack/hl/src/gatt/gatt.h @@ -0,0 +1,70 @@ +#ifndef GATT_H_ +#define GATT_H_ + +/** + **************************************************************************************** + * @addtogroup GATT Generic Attribute Profile + * @ingroup HOST + * @brief Generic Attribute Profile. + * + * The GATT module is responsible for providing an API for all attribute related operations. + * It is responsible for all the service framework activities using the Attribute protocol + * for discovering services and for reading and writing characteristic values on a peer device. + * To achieve this, the GATT interfaces with @ref ATTM "ATTM", @ref ATTC "ATTC" and the + * @ref ATTS "ATTS". + * + * @{ + **************************************************************************************** + */ +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#include "att.h" + + +/* + * DEFINE DECLARATIONS + **************************************************************************************** + */ + +/// retrieve gatt attribute handle from attribute index. +#define GATT_GET_ATT_HANDLE(idx)\ + ((gattm_svc_get_start_hdl() == 0)? (0) :(gattm_svc_get_start_hdl() + (idx))) + + + + +#if (BLE_ATTS) +/// GATT Attribute database handles +/// Generic Attribute Profile Service +enum gatt_db_att +{ + GATT_IDX_PRIM_SVC, + GATT_IDX_CHAR_SVC_CHANGED, + GATT_IDX_SVC_CHANGED, + GATT_IDX_SVC_CHANGED_CFG, + + GATT_IDX_NUMBER +}; +#endif /* (BLE_ATTS)*/ + +/* + * Type Definition + **************************************************************************************** + */ + + +/// Service Changed type definition +struct gatt_svc_changed +{ + /// Service start handle which changed + uint16_t start_hdl; + /// Service end handle which changed + uint16_t end_hdl; +}; + + +/// @} GATT +#endif // GATT_H_ diff --git a/services/ble_stack/hl/src/gatt/gattc/gattc_int.h b/services/ble_stack/hl/src/gatt/gattc/gattc_int.h new file mode 100644 index 0000000..69459a0 --- /dev/null +++ b/services/ble_stack/hl/src/gatt/gattc/gattc_int.h @@ -0,0 +1,245 @@ +#ifndef GATTC_TASK_INT_H_ +#define GATTC_TASK_INT_H_ + +/** + **************************************************************************************** + * @addtogroup GATTC_INT Internals + * @ingroup GATTC + * @brief Internal features of the GATTC module + * + * @{ + **************************************************************************************** + */ +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_GATTC) +#include "gattc.h" +#include "gattc_task.h" +#include "ke_task.h" + +/* + * DEFINES + **************************************************************************************** + */ +/// retrieve on-going operation command +#define GATT_OPERATION_CMD(conidx, op_type, cmd) \ + ((struct cmd*) gattc_get_operation_ptr(conidx, op_type)) + +#define GATT_WRITE_ERROR_CODE (0xFFFF) + + +/// number of GATT Controller Process +#define GATTC_IDX_MAX BLE_CONNECTION_MAX + + + +/// states of GATT Controller task +enum gattc_state_id +{ + /// Connection ready state + GATTC_READY = 0, + #if (BLE_ATTC) + /// Client operation on-going + GATTC_CLIENT_BUSY = (1 << GATTC_OP_CLIENT), + /// Service Discovery Procedure operation on-going + GATTC_SDP_BUSY = (1 << GATTC_OP_SDP), + #endif // (BLE_ATTC) + #if (BLE_ATTS) + /// Server operation on-going + GATTC_SERVER_BUSY = (1 << GATTC_OP_SERVER), + GATTC_ATTS_BUSY = (1 << GATTC_OP_MAX), + #endif // (BLE_ATTS) + /// Connection started but ATTS not ready + GATTC_CONNECTED = (1 << (GATTC_OP_MAX + 1)), + + /// Free state + GATTC_FREE = (1 << (GATTC_OP_MAX + 2)), + /// Number of defined states. + GATTC_STATE_MAX +}; + + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ +extern struct gattc_env_tag* gattc_env[GATTC_IDX_MAX]; + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Initialization of the GATT controller module. + * This function performs all the initialization steps of the GATT module. + * + * @param[in] reset true if it's requested by a reset; false if it's boot initialization + * + **************************************************************************************** + */ +void gattc_init(bool reset); + + +/** + **************************************************************************************** + * @brief Initialize GATT controller for connection. + * + * @param[in] conidx connection record index + * @param[in] role device role after connection establishment + * + **************************************************************************************** + */ +void gattc_create(uint8_t conidx); + + + +/** + **************************************************************************************** + * @brief Cleanup GATT controller resources for connection + * + * @param[in] conidx connection record index + * + **************************************************************************************** + */ +void gattc_cleanup(uint8_t conidx); + +/** + * @brief Send a complete event of ongoing executed operation to requester. + * It also clean-up variable used for ongoing operation. + * + * @param[in] conidx Connection index + * @param[in] op_type Operation type. + * @param[in] status Status of completed operation + */ +void gattc_send_complete_evt(uint8_t conidx, uint8_t op_type, uint8_t status); + +/** + **************************************************************************************** + * @brief Send operation completed message with status error code not related to a + * running operation. + * + * @param[in] conidx Connection index + * @param[in] operation Operation code + * @param[in] seq_num Operation sequence number + * @param[in] requester requester of operation + * @param[in] status Error status code + **************************************************************************************** + */ +void gattc_send_error_evt(uint8_t conidx, uint8_t operation, uint16_t seq_num, const ke_task_id_t requester, uint8_t status); + + +/** + **************************************************************************************** + * @brief Get operation on going + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return operation code on going + **************************************************************************************** + */ +uint8_t gattc_get_operation(uint8_t conidx, uint8_t op_type); + +/** + **************************************************************************************** + * @brief Get operation pointer + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return operation pointer on going + **************************************************************************************** + */ +void* gattc_get_operation_ptr(uint8_t conidx, uint8_t op_type); + + +/** + **************************************************************************************** + * @brief Set operation pointer + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * @param[in] op Operation pointer. + * + **************************************************************************************** + */ +void gattc_set_operation_ptr(uint8_t conidx, uint8_t op_type, void* op); + +/** + **************************************************************************************** + * @brief Operation execution not finish, request kernel to reschedule it in order to + * continue its execution + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return if operation has been rescheduled (not done if operation pointer is null) + **************************************************************************************** + */ +bool gattc_reschedule_operation(uint8_t conidx, uint8_t op_type); + +/** + **************************************************************************************** + * @brief Get requester of on going operation + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return task that requests to execute the operation + **************************************************************************************** + */ +ke_task_id_t gattc_get_requester(uint8_t conidx, uint8_t op_type); + + + +/** + **************************************************************************************** + * @brief Get Operation Sequence Number + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return Sequence number provided for operation execution + **************************************************************************************** + */ +uint16_t gattc_get_op_seq_num(uint8_t conidx, uint8_t op_type); + + +/** + **************************************************************************************** + * @brief Update task state + * + * @param[in] conidx Connection index + * @param[in] state to update + * @param[in] set state to busy (true) or idle (false) + * + **************************************************************************************** + */ +void gattc_update_state(uint8_t conidx, ke_state_t state, bool busy); + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + + +#endif // (BLE_GATTC) + +/// @} GATTCTASK +#endif // GATTC_INT diff --git a/services/ble_stack/hl/src/gatt/gattm/gattm_int.h b/services/ble_stack/hl/src/gatt/gattm/gattm_int.h new file mode 100644 index 0000000..8d41ccb --- /dev/null +++ b/services/ble_stack/hl/src/gatt/gattm/gattm_int.h @@ -0,0 +1,83 @@ +#ifndef GATTM_INT_H_ +#define GATTM_INT_H_ + +/** + **************************************************************************************** + * @addtogroup GATTM_INT Task + * @ingroup GATTM + * @brief Internal function required for GATTM usage + * @{ + **************************************************************************************** + */ +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "ke_task.h" +#include "gattm_task.h" + +#include "../attm/attm_db.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/// number of GATT Process +#define GATTM_IDX_MAX BLE_CONNECTION_MAX + + +/// GATT database default features +#define GATT_DB_DEFAULT_FEAT 0x0001 +/// GATT database Service changed feature +#define GATT_DB_SVC_CHG_FEAT 0x000E + + + +/// states of GATT task +enum gattm_state_id +{ + /// idle state + GATTM_IDLE, + /// busy state + GATTM_BUSY, + /// Number of defined states. + GATTM_STATE_MAX +}; + + + +/// GATT General Information Manager +struct gattm_env_tag +{ + #if (BLE_ATTS) + /// Environment data needed by attribute database + struct attm_db db; + + /// GATT service start handle + uint16_t svc_start_hdl; + #endif // (BLE_ATTS) +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ +extern struct gattm_env_tag gattm_env; + + +/* + * FUNCTIONS DECLARATIONS + **************************************************************************************** + */ + + + +/* + * TASK DESCRIPTOR DECLARATIONS + **************************************************************************************** + */ + + +/// @} GATTM_INT +#endif // GATTM_INT_H_ diff --git a/services/ble_stack/hl/src/l2c/l2cc/l2cc_int.h b/services/ble_stack/hl/src/l2c/l2cc/l2cc_int.h new file mode 100644 index 0000000..886a6b2 --- /dev/null +++ b/services/ble_stack/hl/src/l2c/l2cc/l2cc_int.h @@ -0,0 +1,196 @@ +#ifndef L2CC_INT_H_ +#define L2CC_INT_H_ + +/** + **************************************************************************************** + * @addtogroup L2CCINT Internals + * @ingroup L2CC + * @brief Internal API for L2CC module + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" +#if (BLE_L2CC) + +#include "l2cc_task.h" +#include "l2cc.h" + +/* + * MACRO DEFINITIONS + **************************************************************************************** + */ + + +/// Maximum number of instances of the L2CC task +#define L2CC_IDX_MAX (BLE_CONNECTION_MAX) + +/* + * STATES + **************************************************************************************** + */ + + + +/// states of L2CAP Controller task +enum l2cc_state_id +{ + /// Connection ready state + L2CC_READY, + /// LE signaling protocol busy + L2CC_SIG_BUSY = (1 << L2CC_OP_SIG), + /// Free state + L2CC_FREE = 0X3F, + + /// Number of defined states. + L2CC_STATE_MAX +}; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/// L2CAP environment pool +extern struct l2cc_env_tag *l2cc_env[L2CC_IDX_MAX]; + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Create and Initialize the L2CAP controller task. + * + * @param[in] reset true if it's requested by a reset; false if it's boot initialization + * + **************************************************************************************** + */ +void l2cc_init(bool reset); + +/** +struct l2cc_pdu_recv_ind; + * + **************************************************************************************** + * @brief Initialize the link layer controller task. + * + * @param[in] conidx Connection index + * + **************************************************************************************** + */ +void l2cc_create(uint8_t conidx); + +/** + **************************************************************************************** + * @brief De-initialize the task. + * + * @param[in] conidx Connection index + * @param[in] reset true if it's requested by a reset; false if it's boot initialization + **************************************************************************************** + */ +void l2cc_cleanup(uint8_t conidx, bool reset); + +/** + **************************************************************************************** + * @brief Update task state + * + * @param[in] conidx Connection index + * @param[in] state to update + * @param[in] set state to busy (true) or idle (false) + * + **************************************************************************************** + */ +void l2cc_update_state(uint8_t conidx, ke_state_t state, bool busy); + + +/** + * @brief Send a complete event of ongoing executed operation to requester. + * It also clean-up variable used for ongoing operation. + * + * @param[in] conidx Connection index + * @param[in] op_type Operation type. + * @param[in] status Status of completed operation + */ +void l2cc_send_complete_evt(uint8_t conidx, uint8_t op_type, uint8_t status); + +/** + **************************************************************************************** + * @brief Send operation completed message with status error code not related to a + * running operation. + * + * @param[in] conidx Connection index + * @param[in] operation Operation code + * @param[in] requester requester of operation + * @param[in] status Error status code + * @param[in] cid Channel Identifier + **************************************************************************************** + */ +void l2cc_send_error_evt(uint8_t conidx, uint8_t operation, const ke_task_id_t requester, uint8_t status, uint16_t cid); + + +/** + **************************************************************************************** + * @brief Get operation on going + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return operation code on going + **************************************************************************************** + */ +uint8_t l2cc_get_operation(uint8_t conidx, uint8_t op_type); + +/** + **************************************************************************************** + * @brief Get operation pointer + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * + * @return operation pointer on going + **************************************************************************************** + */ +void* l2cc_get_operation_ptr(uint8_t conidx, uint8_t op_type); + + +/** + **************************************************************************************** + * @brief Set operation pointer + * + * @param[in] conidx Connection Index + * @param[in] op_type Operation type. + * @param[in] op Operation pointer. + * + **************************************************************************************** + */ +void l2cc_set_operation_ptr(uint8_t conidx, uint8_t op_type, void* op); + + + + +/** + **************************************************************************************** + * @brief Perform data packet TX over HCI (call of this function is handled by L2CM + * + * @param[in] conidx Connection Index + * @param[in] nb_buffer Number of available TX buffers + **************************************************************************************** + */ +bool l2cc_data_send(uint8_t conidx, uint8_t nb_buffer); + + + + + + +#endif //(BLE_L2CC) + +/// @} L2CCINT + +#endif // L2CC_INT_H_ diff --git a/services/ble_stack/hl/src/l2c/l2cc/l2cc_lecb.h b/services/ble_stack/hl/src/l2c/l2cc/l2cc_lecb.h new file mode 100644 index 0000000..a244a23 --- /dev/null +++ b/services/ble_stack/hl/src/l2c/l2cc/l2cc_lecb.h @@ -0,0 +1,249 @@ +#ifndef _L2CC_LECB_H_ +#define _L2CC_LECB_H_ + +/** + **************************************************************************************** + * @addtogroup L2CC_LECB L2Cap Controller LE Credit Based connection management + * @ingroup L2CC + * @brief This module is in charge of LECB connection management + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_LECB) + +/* + * DEFINES + **************************************************************************************** + */ +/// LE Credit Based fields. +enum l2cc_lecb_fields +{ + /// LE Protocol Service Multiplexer + L2CC_LECB_LEPSM, + /// Local channel ID + L2CC_LECB_LOCAL_CID, + /// Peer channel ID + L2CC_LECB_PEER_CID, +}; + + +/// Status of the LE Credit Based connection +/// +/// 7 6 5 4 3 2 1 0 +/// +----+----+----+----+----+----+----+----+ +/// | RFU |P_I |TX_W|CON | +/// +----+----+----+----+----+----+----+----+ +/// +/// bit [2] : Local(0)/Peer (1) initiated connection +/// bit [1] : TX in Wait state (segment transmission not finished) +/// bit [0] : LECB Connected +enum l2cc_lecb_state +{ + /// Peer initiated connection + L2CC_LECB_PEER_INIT_BIT = (1<<2), + L2CC_LECB_PEER_INIT_POS = (2), + + /// TX in Wait state (segment transmission not finished) + L2CC_LECB_TX_WAIT_BIT = (1<<1), + L2CC_LECB_TX_WAIT_POS = (1), + + /// Channel Connected + L2CC_LECB_CONNECTED_BIT = (1<<0), + L2CC_LECB_CONNECTED_POS = (0), +}; + + + + + +/* + * MACRO DEFINITIONS + **************************************************************************************** + */ + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + + +/// LE credit based information for a link started or on-going. +struct l2cc_lecb_info +{ + /// Pointer to the following list + struct co_list_hdr hdr; + /// SDU waiting to be transfered (required for segmentation algorithm) + struct l2cc_lecb_sdu_send_cmd* tx_sdu; + /// SDU waiting to be received (required for reassembly algorithm) + struct l2cc_lecb_sdu_recv_ind* rx_sdu; + + /// LE Protocol/Service Multiplexer + uint16_t le_psm; + + /// Local channel ID + uint16_t local_cid; + /// Local Maximum Transmission Unit + uint16_t local_mtu; + /// Local Maximum Packet Size + uint16_t local_mps; + /// Local credit + uint16_t local_credit; + + /// Peer channel ID + uint16_t peer_cid; + /// Peer Maximum Transmission Unit + uint16_t peer_mtu; + /// Peer Maximum Packet Size + uint16_t peer_mps; + /// Peer credit + uint16_t peer_credit; + + /// Task id requested connection + ke_task_id_t task_id; + + /// Status of the LE Credit Based connection (@see enum l2cc_lecb_state) + uint8_t state; + + /// disconnection reason + uint8_t disc_reason; + + /// Packet identifier - used for LECB negotiation + uint8_t pkt_id; +}; + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Search LE Credit Based channel depending on the parameter + * + * @param[in] conidx Connection Index + * @param[in] field Search field (@see enum l2cc_lecb_fields) + * @param[in] value Field value to search + * + * @return Returns NULL or pointer to the LE Credit Based channel info + **************************************************************************************** + */ +struct l2cc_lecb_info* l2cc_lecb_find(uint8_t conidx, uint8_t field, uint16_t value); + +/** + **************************************************************************************** + * @brief End of LECB Connection, free information, and send disconnect indication + * + * @param[in] conidx Connection Index + * @param[in] lecb LE Credit Based Connection information + * @param[in] disconnect_ind True, sends disconnect indication + **************************************************************************************** + */ +void l2cc_lecb_free(uint8_t conidx, struct l2cc_lecb_info* lecb, bool disconnect_ind); + + +/** + **************************************************************************************** + * @brief Sends LE credit based connection request + * + * @param[in] conidx connection index + * @param[in] pkt_id Packet identifier + * @param[in] scid Source channel ID + * @param[in] credits Credits + * @param[in] mps Maximum Packet Size + * @param[in] mtu Maximum Transfer Unit + **************************************************************************************** + */ +void l2cc_lecb_send_con_req(uint8_t conidx, uint8_t pkt_id, uint16_t le_psm, uint16_t scid, uint16_t credits, + uint16_t mps, uint16_t mtu); + +/** + **************************************************************************************** + * @brief Sends LE credit based connection response + * + * @param[in] conidx connection index + * @param[in] status status of the connection + * @param[in] pkt_id Packet identifier + * @param[in] dcid Destination channel ID + * @param[in] credits Credits + * @param[in] mps Maximum Packet Size + * @param[in] mtu Maximum Transfer Unit + **************************************************************************************** + */ +void l2cc_lecb_send_con_rsp(uint8_t conidx, uint16_t status, uint8_t pkt_id, + uint16_t dcid, uint16_t credits, uint16_t mps, uint16_t mtu); + +/** + **************************************************************************************** + * @brief Sends LE credit based disconnection request + * + * @param[in] conidx connection index + * @param[in] pkt_id Packet identifier + * @param[in] dcid Destination channel ID + * @param[in] scid Source channel ID + **************************************************************************************** + */ +void l2cc_lecb_send_disc_req(uint8_t conidx, uint8_t pkt_id, uint16_t scid, uint16_t dcid); + +/** + **************************************************************************************** + * @brief Sends LE credit based disconnection response + * + * @param[in] conidx connection index + * @param[in] pkt_id Packet identifier + * @param[in] dcid Destination channel ID + * @param[in] scid Source channel ID + **************************************************************************************** + */ +void l2cc_lecb_send_disc_rsp(uint8_t conidx, uint8_t pkt_id, uint16_t dcid, uint16_t scid); +/** + **************************************************************************************** + * @brief Sends LE credit based Flow Control credit add message + * + * @param[in] conidx connection index + * @param[in] pkt_id Packet identifier + * @param[in] cid Source Channel ID + * @param[in] credits Credits + **************************************************************************************** + */ +void l2cc_lecb_send_credit_add(uint8_t conidx, uint8_t pkt_id, uint16_t cid, uint16_t credits); + + +/** + **************************************************************************************** + * @brief Due to an error on LECB link, initiate a disconnection of the channel + * + * @param[in] conidx connection index + * @param[in] lecb Information of the channel + * @param[in] disc_reason Disconnection reason + * + **************************************************************************************** + */ +void l2cc_lecb_init_disconnect(uint8_t conidx, struct l2cc_lecb_info* lecb, uint8_t disc_reason); + +/** + **************************************************************************************** + * @brief Retrieve LECB error Code from Host error code + * + * @param[in] h_err Host Error code + * + * @return LECB Error code + **************************************************************************************** + */ +uint16_t l2cc_lecb_h2l_err(uint8_t h_err); + +#endif //(BLE_LECB) + +/// @} L2CC_LECB + +#endif /* _L2CC_LECB_H_ */ diff --git a/services/ble_stack/hl/src/l2c/l2cc/l2cc_pdu_int.h b/services/ble_stack/hl/src/l2c/l2cc/l2cc_pdu_int.h new file mode 100644 index 0000000..2279935 --- /dev/null +++ b/services/ble_stack/hl/src/l2c/l2cc/l2cc_pdu_int.h @@ -0,0 +1,176 @@ +#ifndef _L2CC_PDU_INT_H_ +#define _L2CC_PDU_INT_H_ + +/** + **************************************************************************************** + * @addtogroup L2CC_PDU_INT L2Cap Controller (internal) + * @ingroup L2CC + * @brief This module is in charge to pack or unpack L2CAP packets + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" + +#if (BLE_L2CC) + +#include "l2cc_pdu.h" + +/* + * MACROS + **************************************************************************************** + */ + + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Pack PDU from firmware readable data to a L2CAP packet using generic method. + * (no segmentation) + * + * @param[in] p_pdu Pointer to the unpacked PDU structure + * @param[in|out] p_offset Pointer to address where the next part of PDU will be read + * @param[in|out] p_length Pointer to the length of payload that has been packed + * @param[in|out] p_buffer Pointer to address where the next part of PDU will be written + * @param[in|out] pb_flag Packet Boundary flags + * + * @return GAP_ERR_NO_ERROR if packing succeed, else another error code. + **************************************************************************************** + */ +#ifdef __GATT_OVER_BR_EDR__ + uint8_t l2cc_pdu_pack(uint8_t conidx, struct l2cc_pdu *p_pdu, uint16_t *p_offset, uint16_t *p_length, uint8_t *p_buffer, uint8_t *pb_flag); +#else + uint8_t l2cc_pdu_pack(struct l2cc_pdu *p_pdu, uint16_t *p_offset, uint16_t *p_length, uint8_t *p_buffer, uint8_t *pb_flag); +#endif + +/** + **************************************************************************************** + * Unpack L2Cap PDU in a generic format that can be used by firmware using generic method. + * (no reassembly) + * + * @param[in] p_pdu Pointer to the unpacked PDU structure + * @param[in|out] p_offset Pointer to address where the next part of PDU will be written + * @param[in|out] p_rem_len Pointer to the remaining length value of PDU to receive + * @param[in|out] p_buffer Pointer to address where the next part of PDU will be read + * @param[in] pkt_length Length of the received packet + * @param[in] pb_flag Packet Boundary flags + * + * @return GAP_ERR_NO_ERROR if packing succeed, else another error code. + **************************************************************************************** + */ +uint8_t l2cc_pdu_unpack(struct l2cc_pdu *p_pdu, uint16_t *p_offset, uint16_t *p_rem_len, + const uint8_t *p_buffer, uint16_t pkt_length, uint8_t pb_flag); + + + +#if (RW_DEBUG) +/** + **************************************************************************************** + * Pack DBG PDU (any kind of PDU generated by Host) from firmware readable data to a L2CAP + * packet (no segmentation) + * + * @param[in] conidx Connection Index + * @param[in] pdu Pointer to the Debug PDU to send + * @param[in|out] p_length Pointer to the length of payload that has been packed + * @param[in|out] buffer Pointer to address where the next part of PDU will be written + * @param[in|out] offset Pointer to address where the next part of PDU will be read + * @param[in|out] pb_flag Packet Boundary flags + * + * @return GAP_ERR_NO_ERROR if packing succeed, else another error code. + **************************************************************************************** + */ +uint8_t l2cc_dbg_pdu_pack(struct l2cc_dbg_pdu *pdu, uint16_t *length, uint8_t *buffer, uint16_t* offset,uint8_t *pb_flag); + + +/** + **************************************************************************************** + * Unpack L2Cap PDU in a generic format that can be used by firmware for debugging + * (no reassembly) + * + * @param[in|out] sdu Pointer to the unpacked SDU structure + * @param[in] buffer Pointer to address where the next part of PDU will be read + * @param[in] length Length of the received packet + * @param[in|out] offset Pointer to address where the next part of PDU will be written + * @param[in] pb_flag Packet Boundary flags + * + * @return GAP_ERR_NO_ERROR if packing succeed, else another error code. + **************************************************************************************** + */ +uint8_t l2cc_dbg_pdu_unpack(struct l2cc_dbg_pdu *pdu, uint8_t *buffer, uint16_t length, uint16_t* offset, uint8_t pb_flag); +#endif // (RW_DEBUG) + +#if (BLE_LECB) +/** + **************************************************************************************** + * Pack LE Credit Based channel PDU from firmware readable data to a L2CAP packet + * + * @param[in] conidx Connection Index + * @param[in] pdu Pointer to the SDU to send + * @param[out] length Pointer to the length of payload that has been packed + * @param[in|out] buffer Pointer to address where the next part of PDU will be written + * @param[in|out] offset Pointer to address where the next part of PDU will be read + * @param[in|out] pdu_len PDU length to transmitt + * @param[in] pb_flag Packet Boundary flags + * + * @return GAP_ERR_NO_ERROR if packing succeed, else another error code. + **************************************************************************************** + */ +uint8_t l2cc_lecb_pdu_pack(uint8_t conidx, struct l2cc_sdu *sdu, uint16_t *length, uint8_t *buffer, uint16_t* offset, + uint16_t pdu_len, uint8_t pb_flag); + + +/** + **************************************************************************************** + * Unpack L2Cap LECB SDU in a generic format that can be used by firmware + * + * @param[in|out] sdu Pointer to the unpacked SDU structure + * @param[in] buffer Pointer to address where the next part of PDU will be read + * @param[in] length Length of the received packet + * @param[in|out] offset Pointer to address where the next part of PDU will be written + * @param[in|out] pdu_remain_len Pointer to the data length still expected on segment + * @param[in] pb_flag Packet Boundary flags + * + * @return GAP_ERR_NO_ERROR if packing succeed, else another error code. + **************************************************************************************** + */ +uint8_t l2cc_lecb_pdu_unpack(struct l2cc_sdu *sdu, uint8_t *buffer, uint16_t length, uint16_t* offset, + uint16_t* pdu_remain_len, uint8_t pb_flag); + +#endif //(BLE_LECB) + +/** + **************************************************************************************** + * @brief Check the PDU packet header channel ID, Length, in order to: + * - verify if no error detected + * - allocate or retrieve the RX messge for expected destination task + * + * @param[in] conidx Connection Index + * @param[in] buffer RX buffer that contains first PDU fragment + * + * @return GAP_ERR_NO_ERROR if header sanity check succeed, else an error code to ignore + * reception of PDU + **************************************************************************************** + */ +uint8_t l2cc_pdu_header_check(uint8_t conidx, uint8_t* buffer); + + +/// @} L2CC_PDU_INT + +#endif //(BLE_L2CC) + +#endif /* _L2CC_PDU_INT_H_ */ diff --git a/services/ble_stack/hl/src/l2c/l2cc/l2cc_sig.h b/services/ble_stack/hl/src/l2c/l2cc/l2cc_sig.h new file mode 100644 index 0000000..bb1a92e --- /dev/null +++ b/services/ble_stack/hl/src/l2c/l2cc/l2cc_sig.h @@ -0,0 +1,84 @@ +#ifndef _L2CC_SIG_H_ +#define _L2CC_SIG_H_ + + +/** + **************************************************************************************** + * @addtogroup L2CC_SIG L2CAP Controller Signaling PDU Handler. + * @ingroup L2CC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" + +#if (BLE_L2CC) + +#include "l2cc.h" +#include "l2cc_task.h" + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * MACRO DEFINITIONS + **************************************************************************************** + */ + + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Send an L2Cap command rejected signaling packet with command not understood + * error code. + * + * @param[in] conidx Connection Index + * @param[in] pkt_id Packet identifier + * + * @param[in] reason The Reason field describes why the Request packet was rejected + * @param[in] opt1 Optional param 1 + * @param[in] opt2 Optional param 2 + **************************************************************************************** + */ +void l2cc_sig_send_cmd_reject(uint8_t conidx, uint8_t pkt_id, uint16_t reason, uint16_t opt1, uint16_t opt2); + + +/** + **************************************************************************************** + * @brief Handles reception of L2CAP signaling messages from peer device. + * + * @param[in] conidx Connection Index + * @param[in] pdu PDU Received + * + * @return If the message was consumed or not. + **************************************************************************************** + */ +int l2cc_sig_pdu_recv_handler(uint8_t conidx, struct l2cc_pdu *pdu); + + + + +#endif // (BLE_L2CC) + +#endif // _L2CC_SIG_H_ + +/// @} L2CC_SIG diff --git a/services/ble_stack/hl/src/l2c/l2cm/l2cm_int.h b/services/ble_stack/hl/src/l2c/l2cm/l2cm_int.h new file mode 100644 index 0000000..14523f2 --- /dev/null +++ b/services/ble_stack/hl/src/l2c/l2cm/l2cm_int.h @@ -0,0 +1,153 @@ +#ifndef L2CM_INT_H_ +#define L2CM_INT_H_ + +/** + **************************************************************************************** + * @addtogroup L2C_INT Logical Link Control and Adaptation Protocol internals + * @ingroup HOST + * @brief Logical Link Control and Adaptation Protocol - Internal API. + * + * @{ + **************************************************************************************** + */ +#include "rwip_config.h" +#include "hal_trace.h" + +#if (BLE_L2CM) +#include +#include +#include "compiler.h" +#include "l2cm.h" + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#define TRACE_BLE_TX_BUFFER_USAGE 0 + +/* + * DEFINES + **************************************************************************************** + */ + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ + +/// L2CAP Manager environment structure to be saved +struct l2cm_env_tag +{ + #if (BLE_L2CC) + /// bit field used to know per connection if TX activity is on-going + uint32_t con_tx_state; + #endif // (BLE_L2CC) + /// Lower Layer buffers length + uint16_t le_acl_data_pkt_len; + /// Total number of available Lower Layer buffers + uint16_t le_acl_total_nb_acl_pkt; + /// Number of available Lower Layer buffers + uint16_t nb_buffer_avail; + + uint16_t usedBufferNumber[BLE_CONNECTION_MAX]; + + }; + +/* + * GLOBAL VARIABLE DECLARATIONS + **************************************************************************************** + */ +extern struct l2cm_env_tag l2cm_env; +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Acquire low layer LE ACL packet + **************************************************************************************** + */ +static __INLINE void l2cm_buffer_acquire(uint8_t conidx) +{ + l2cm_env.nb_buffer_avail--; + l2cm_env.usedBufferNumber[conidx]++; +#if TRACE_BLE_TX_BUFFER_USAGE + TRACE(3, "ble nb -- to %d coidx %d use buf ++ to %d", l2cm_env.nb_buffer_avail, + conidx, l2cm_env.usedBufferNumber[conidx]); +#endif +} + +/** + **************************************************************************************** + * @brief Release low layer LE ACL packet + * + * @parm[in] nb Number of buffer to release. + **************************************************************************************** + */ +static __INLINE void l2cm_buffer_release(uint8_t conidx, uint16_t nb) +{ + if (l2cm_env.usedBufferNumber[conidx] < nb) + { + l2cm_env.nb_buffer_avail += l2cm_env.usedBufferNumber[conidx]; + l2cm_env.usedBufferNumber[conidx] = 0; + } + else + { + l2cm_env.nb_buffer_avail += nb; + l2cm_env.usedBufferNumber[conidx] -= nb; + } +#if TRACE_BLE_TX_BUFFER_USAGE + TRACE(4, "post ble nb ++ %d to %d coidx %d use buf -- to %d", nb, l2cm_env.nb_buffer_avail, + conidx, l2cm_env.usedBufferNumber[conidx]); +#endif +} + +static __INLINE void l2cm_buffer_reset(uint8_t conidx) +{ +#if TRACE_BLE_TX_BUFFER_USAGE + TRACE(2, "pre ble nb %d use buf %d", l2cm_env.nb_buffer_avail, + l2cm_env.usedBufferNumber[conidx]); +#endif + + l2cm_env.nb_buffer_avail += l2cm_env.usedBufferNumber[conidx]; + l2cm_env.usedBufferNumber[conidx] = 0; + +#if TRACE_BLE_TX_BUFFER_USAGE + TRACE(3, "post ble reset to %d conidx %d use buf to %d", l2cm_env.nb_buffer_avail, + conidx, l2cm_env.usedBufferNumber[conidx]); +#endif +} + +/** + **************************************************************************************** + * @brief Retrieve low layer LE ACL Buffers size + * + * @return size of LE ACL Buffers + **************************************************************************************** + */ +static __INLINE uint16_t l2cm_get_buffer_size(void) + { + return l2cm_env.le_acl_data_pkt_len; + } + + +/** + **************************************************************************************** + * @brief Set if TX queue for specific connection is empty or not. + * + * If not empty, it will request L2CM to start transmission of buffers + * + * @param[in] conidx Connection index + * @param[in] busy False if TX buffer queue is empty, True else + * + **************************************************************************************** + */ +void l2cm_tx_status(uint8_t conidx, bool busy); + +/// @} L2CM_INT + +#endif //(BLE_L2CM) + +#endif // L2CM_INT_H_ diff --git a/services/ble_stack/ke/api/ke.h b/services/ble_stack/ke/api/ke.h new file mode 100644 index 0000000..98b997b --- /dev/null +++ b/services/ble_stack/ke/api/ke.h @@ -0,0 +1,90 @@ +#ifndef _KE_H_ +#define _KE_H_ + +/** + **************************************************************************************** + * @addtogroup ENV Environment + * @ingroup KERNEL + * @brief Kernel Environment + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // stack configuration + +#include // standard boolean definitions +#include // standard integer definitions + +/* + * ENUMERATION + **************************************************************************************** + */ + +/// Kernel Error Status +enum KE_STATUS +{ + KE_SUCCESS = 0, + KE_FAIL +}; + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief This function performs all the initializations of the kernel. + * + * It initializes first the heap, then the message queues and the events. Then if required + * it initializes the trace. + * + **************************************************************************************** + */ +void ke_init(void); + +/** + **************************************************************************************** + * @brief This function flushes all messages, timers and events currently pending in the + * kernel. + * + **************************************************************************************** + */ +void ke_flush(void); + +/** + **************************************************************************************** + * @brief This function checks if sleep is possible or kernel is processing + * + * @return True if sleep is allowed, false otherwise + **************************************************************************************** + */ +bool ke_sleep_check(void); + +#if (KE_PROFILING) +/** + **************************************************************************************** + * @brief This function gets the statistics of the kernel usage. + * + * @param[out] max_msg_sent Max message sent + * @param[out] max_msg_saved Max message saved + * @param[out] max_timer_used Max timer used + * @param[out] max_heap_used Max heap used + **************************************************************************************** + */ +enum KE_STATUS ke_stats_get(uint8_t* max_msg_sent, + uint8_t* max_msg_saved, + uint8_t* max_timer_used, + uint16_t* max_heap_used); +#endif //KE_PROFILING + +/// @} KE + +#endif // _KE_H_ diff --git a/services/ble_stack/ke/api/ke_event.h b/services/ble_stack/ke/api/ke_event.h new file mode 100644 index 0000000..937b3ee --- /dev/null +++ b/services/ble_stack/ke/api/ke_event.h @@ -0,0 +1,139 @@ +#ifndef _KE_EVENT_H_ +#define _KE_EVENT_H_ + +/** + **************************************************************************************** + * @addtogroup EVT Events and Schedule + * @ingroup KERNEL + * @brief Event scheduling module. + * + * The KE_EVT module implements event scheduling functions. It can be used to + * implement deferred actions. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ + +#include "rwip_config.h" // stack configuration + +#include // standard integer definition + + +/* + * CONSTANTS + **************************************************************************************** + */ + + +/// Status of ke_task API functions +enum KE_EVENT_STATUS +{ + KE_EVENT_OK = 0, + KE_EVENT_FAIL, + KE_EVENT_UNKNOWN, + KE_EVENT_CAPA_EXCEEDED, + KE_EVENT_ALREADY_EXISTS, +}; + + +/* + * TYPE DEFINITION + **************************************************************************************** + */ + + + + +/* + * FUNCTION PROTOTYPES + **************************************************************************************** + */ + + + +/** + **************************************************************************************** + * @brief Initialize Kernel event module. + **************************************************************************************** + */ +void ke_event_init(void); + +/** + **************************************************************************************** + * @brief Register an event callback. + * + * @param[in] event_type Event type. + * @param[in] p_callback Pointer to callback function. + * + * @return Status + **************************************************************************************** + */ +uint8_t ke_event_callback_set(uint8_t event_type, void (*p_callback)(void)); + +/** + **************************************************************************************** + * @brief Set an event + * + * This primitive sets one event. It will trigger the call to the corresponding event + * handler in the next scheduling call. + * + * @param[in] event_type Event to be set. + **************************************************************************************** + */ +void ke_event_set(uint8_t event_type); + +/** + **************************************************************************************** + * @brief Clear an event + * + * @param[in] event_type Event to be cleared. + **************************************************************************************** + */ +void ke_event_clear(uint8_t event_type); + +/** + **************************************************************************************** + * @brief Get the status of an event + * + * @param[in] event_type Event to get. + * + * @return Event status (0: not set / 1: set) + **************************************************************************************** + */ +uint8_t ke_event_get(uint8_t event_type); + +/** + **************************************************************************************** + * @brief Get all event status + * + * @return Events bit field + **************************************************************************************** + */ +uint32_t ke_event_get_all(void); + +/** + **************************************************************************************** + * @brief Flush all pending events. + **************************************************************************************** + */ +void ke_event_flush(void); + +/** + **************************************************************************************** + * @brief Event scheduler entry point. + * + * This primitive is the entry point of Kernel event scheduling. + **************************************************************************************** + */ +void ke_event_schedule(void); + + + +/// @} EVT + +#endif //_KE_EVENT_H_ diff --git a/services/ble_stack/ke/api/ke_mem.h b/services/ble_stack/ke/api/ke_mem.h new file mode 100644 index 0000000..1bdc62e --- /dev/null +++ b/services/ble_stack/ke/api/ke_mem.h @@ -0,0 +1,140 @@ +#ifndef _KE_MEM_H_ +#define _KE_MEM_H_ + +#include "rwip_config.h" // IP configuration +#include // standard integer +#include // standard includes + +/** + **************************************************************************************** + * @defgroup MEM Memory + * @ingroup KERNEL + * @brief Heap management module. + * + * This module implements heap management functions that allow initializing heap, + * allocating and freeing memory. + * + * @{ + **************************************************************************************** + */ + +// forward declarations +struct mblock_free; + +/** + **************************************************************************************** + * @brief Heap initialization. + * + * This function performs the following operations: + * - sanity checks + * - check memory allocated is at least large enough to hold two block descriptors to hold + * start and end + * - initialize the first and last descriptors + * - save heap into kernel environment variable. + * + * @param[in] type Memory type. + * @param[in|out] heap Heap pointer + * @param[in] heap_size Size of the heap + * + * + **************************************************************************************** + */ +void ke_mem_init(uint8_t type, uint8_t* heap, uint16_t heap_size); + +/** + **************************************************************************************** + * @brief Allocation of a block of memory. + * + * Allocates a memory block whose size is size; if no memory is available return NULL + * + * @param[in] size Size of the memory area that need to be allocated. + * @param[in] type Type of memory block + * + * @return A pointer to the allocated memory area. + * + **************************************************************************************** + */ +void *ke_malloc(uint32_t size, uint8_t type); + + +/** + **************************************************************************************** + * @brief Check if it's possible to allocate a block of memory with a specific size. + * + * @param[in] size Size of the memory area that need to be allocated. + * @param[in] type Type of memory block + * + * @return True if memory block can be allocated, False else. + * + **************************************************************************************** + */ +bool ke_check_malloc(uint32_t size, uint8_t type); + +/** + **************************************************************************************** + * @brief Freeing of a block of memory. + * + * Free the memory area pointed by mem_ptr : mark the block as free and insert it in + * the pool of free block. + * + * @param[in] mem_ptr Pointer to the memory area that need to be freed. + * + **************************************************************************************** + */ +void ke_free(void *mem_ptr); + + +/** + **************************************************************************************** + * @brief Check if current heap is empty or not (not used) + * + * @param[in] type Type of memory heap block + * + * @return true if heap not used, false else. + **************************************************************************************** + */ +bool ke_mem_is_empty(uint8_t type); + + + +/** + **************************************************************************************** + * @brief Check if current pointer is free or not + * + * @param[in] mem_ptr pointer to a memory block + * + * @return true if already free, false else. + **************************************************************************************** + */ +bool ke_is_free(void* mem_ptr); + +#if (KE_PROFILING) + +/** + **************************************************************************************** + * @brief Retrieve memory usage of selected heap. + * + * @param[in] type Type of memory heap block + * + * @return current memory usage of current heap. + **************************************************************************************** + */ +uint16_t ke_get_mem_usage(uint8_t type); + + +/** + **************************************************************************************** + * @brief Retrieve max memory usage of all heap. + * This command also resets max measured value. + * + * @return max memory usage of all heap. + **************************************************************************************** + */ +uint32_t ke_get_max_mem_usage(void); + +#endif // (KE_PROFILING) + +///@} MEM + +#endif // _KE_MEM_H_ + diff --git a/services/ble_stack/ke/api/ke_msg.h b/services/ble_stack/ke/api/ke_msg.h new file mode 100644 index 0000000..d46b6e1 --- /dev/null +++ b/services/ble_stack/ke/api/ke_msg.h @@ -0,0 +1,305 @@ +#ifndef _KE_MSG_H_ +#define _KE_MSG_H_ + +/** + **************************************************************************************** + * @defgroup MSG Message Exchange + * @ingroup KERNEL + * @brief Message scheduling module. + * + * The MSG module implements message scheduling functions. + + * A kernel message has an ID, a receiver task ID and a source task ID. + * In most cases, it also has parameters which are defined in + * a structure dynamically embedded in the message structure, + * so the whole message will be managed internally as one block. + * + * A message can also have one extra parameter which is referenced + * in the normal parameter structure. This extra block is assumed + * to be large by the kernel and will be moved by DMA if needed. + * This feature allows moving MMPDU from LMAC to UMAC. + * + * In order to send a message, a function first have to allocate + * the memory for this message. It can be done with the wrapper + * macro KE_MSG_ALLOC() (which will call ke_msg_alloc()). + + * The message can then be sent with ke_msg_send(). The kernel + * will take care of freeing the allocated memory. + + * If the message has no parameters, the ke_msg_send_basic() function + * can be used. + * + * @{ + **************************************************************************************** + */ + +#include // standard definition +#include // standard integer +#include // standard boolean +#include "arch.h" // architectural definition +#include "compiler.h" // compiler definition +#include "co_list.h" // list definition + +/// Task Identifier. Composed by the task type and the task index. +typedef uint16_t ke_task_id_t; + +/// Builds the task identifier from the type and the index of that task. +#define KE_BUILD_ID(type, index) ( (ke_task_id_t)(((index) << 8)|(type)) ) + +/// Retrieves task type from task id. +#define KE_TYPE_GET(ke_task_id) ((ke_task_id) & 0xFF) + +/// Retrieves task index number from task id. +#define KE_IDX_GET(ke_task_id) (((ke_task_id) >> 8) & 0xFF) + +/// Task State +typedef uint8_t ke_state_t; + +/// Message Identifier. The number of messages is limited to 0xFFFF. +/// The message ID is divided in two parts: +/// bits[15~8]: task index (no more than 255 tasks support) +/// bits[7~0]: message index(no more than 255 messages per task) +typedef uint16_t ke_msg_id_t; + +/// Message structure. +struct ke_msg +{ + struct co_list_hdr hdr; ///< List header for chaining + + ke_msg_id_t id; ///< Message id. + ke_task_id_t dest_id; ///< Destination kernel identifier. + ke_task_id_t src_id; ///< Source kernel identifier. + uint16_t param_len; ///< Parameter embedded struct length. + uint32_t param[__ARRAY_EMPTY]; ///< Parameter embedded struct. Must be word-aligned. +}; + + +/// Status returned by a task when handling a message +enum ke_msg_status_tag +{ + KE_MSG_CONSUMED = 0, ///< consumed, msg and ext are freed by the kernel + KE_MSG_NO_FREE, ///< consumed, nothing is freed by the kernel + KE_MSG_SAVED, ///< not consumed, will be pushed in the saved queue +}; + +/** + **************************************************************************************** + * @brief Convert a parameter pointer to a message pointer + * + * @param[in] param_ptr Pointer to the parameter member of a ke_msg + * Usually retrieved by a ke_msg_alloc() + * + * @return The pointer to the ke_msg + **************************************************************************************** + */ +__STATIC __INLINE struct ke_msg * ke_param2msg(void const *param_ptr) +{ + return (struct ke_msg*) (((uint8_t*)param_ptr) - offsetof(struct ke_msg, param)); +} + +/** + **************************************************************************************** + * @brief Convert a message pointer to a parameter pointer + * + * @param[in] msg Pointer to the ke_msg. + * + * @return The pointer to the param member + **************************************************************************************** + */ +__STATIC __INLINE void * ke_msg2param(struct ke_msg const *msg) +{ + return (void*) (((uint8_t*) msg) + offsetof(struct ke_msg, param)); +} + +/** + **************************************************************************************** + * @brief Convenient wrapper to ke_msg_alloc() + * + * This macro calls ke_msg_alloc() and cast the returned pointer to the + * appropriate structure. Can only be used if a parameter structure exists + * for this message (otherwise, use ke_msg_send_basic()). + * + * @param[in] id Message identifier + * @param[in] dest Destination Identifier + * @param[in] src Source Identifier + * @param[in] param_str parameter structure tag + * + * @return Pointer to the parameter member of the ke_msg. + **************************************************************************************** + */ +#define KE_MSG_ALLOC(id, dest, src, param_str) \ + (struct param_str*) ke_msg_alloc(id, dest, src, sizeof(struct param_str)) + +/** + **************************************************************************************** + * @brief Convenient wrapper to ke_msg_free() + * + * This macro calls ke_msg_free() with the appropriate msg pointer as parameter, according + * to the message parameter pointer passed. + * + * @param[in] param_ptr parameter structure pointer + **************************************************************************************** + */ +#define KE_MSG_FREE(param_ptr) ke_msg_free(ke_param2msg((param_ptr))) + +/** + **************************************************************************************** + * @brief Convenient wrapper to ke_msg_alloc() + * + * This macro calls ke_msg_alloc() and cast the returned pointer to the + * appropriate structure with a variable length. Can only be used if a parameter structure exists + * for this message (otherwise, use ke_msg_send_basic()).Can only be used if the data array is + * located at the end of the structure. + * + * @param[in] id Message identifier + * @param[in] dest Destination Identifier + * @param[in] src Source Identifier + * @param[in] param_str parameter structure tag + * @param[in] length length for the data + * + * @return Pointer to the parameter member of the ke_msg. + **************************************************************************************** + */ +#define KE_MSG_ALLOC_DYN(id, dest, src, param_str,length) (struct param_str*)ke_msg_alloc(id, dest, src, \ + (sizeof(struct param_str) + (length))); + +/** + **************************************************************************************** + * @brief Allocate memory for a message + * + * This primitive allocates memory for a message that has to be sent. The memory + * is allocated dynamically on the heap and the length of the variable parameter + * structure has to be provided in order to allocate the correct size. + * + * Several additional parameters are provided which will be preset in the message + * and which may be used internally to choose the kind of memory to allocate. + * + * The memory allocated will be automatically freed by the kernel, after the + * pointer has been sent to ke_msg_send(). If the message is not sent, it must + * be freed explicitly with ke_msg_free(). + * + * Allocation failure is considered critical and should not happen. + * + * @param[in] id Message identifier + * @param[in] dest_id Destination Task Identifier + * @param[in] src_id Source Task Identifier + * @param[in] param_len Size of the message parameters to be allocated + * + * @return Pointer to the parameter member of the ke_msg. If the parameter + * structure is empty, the pointer will point to the end of the message + * and should not be used (except to retrieve the message pointer or to + * send the message) + **************************************************************************************** + */ +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); + +/** + **************************************************************************************** + * @brief Message sending. + * + * Send a message previously allocated with any ke_msg_alloc()-like functions. + * + * The kernel will take care of freeing the message memory. + * + * Once the function have been called, it is not possible to access its data + * anymore as the kernel may have copied the message and freed the original + * memory. + * + * @param[in] param_ptr Pointer to the parameter member of the message that + * should be sent. + **************************************************************************************** + */ + +void ke_msg_send(void const *param_ptr); + +/** + **************************************************************************************** + * @brief Basic message sending. + * + * Send a message that has a zero length parameter member. No allocation is + * required as it will be done internally. + * + * @param[in] id Message identifier + * @param[in] dest_id Destination Identifier + * @param[in] src_id Source Identifier + **************************************************************************************** + */ +void ke_msg_send_basic(ke_msg_id_t const id, ke_task_id_t const dest_id, ke_task_id_t const src_id); + +/** + **************************************************************************************** + * @brief Message forwarding. + * + * Forward a message to another task by changing its destination and source tasks IDs. + * + * @param[in] param_ptr Pointer to the parameter member of the message that + * should be sent. + * @param[in] dest_id New destination task of the message. + * @param[in] src_id New source task of the message. + **************************************************************************************** + */ +void ke_msg_forward(void const *param_ptr, ke_task_id_t const dest_id, ke_task_id_t const src_id); + +/** + **************************************************************************************** + * @brief Message forwarding. + * + * Forward a message to another task by changing its message ID and its destination and source tasks IDs. + * + * @param[in] param_ptr Pointer to the parameter member of the message that + * should be sent. + * @param[in] msg_id New ID of the message. + * @param[in] dest_id New destination task of the message. + * @param[in] src_id New source task of the message. + **************************************************************************************** + */ +void ke_msg_forward_new_id(void const *param_ptr, + ke_msg_id_t const msg_id, ke_task_id_t const dest_id, ke_task_id_t const src_id); + +/** + **************************************************************************************** + * @brief Free allocated message + * + * @param[in] msg Pointer to the message to be freed (not the parameter member!) + **************************************************************************************** + */ +void ke_msg_free(struct ke_msg const *param); + + + +/** + **************************************************************************************** + * @brief Retrieve destination task identifier of a kernel message + * + * @param[in] param_ptr Pointer to the parameter member of the message. + * + * @return message destination task + **************************************************************************************** + */ +ke_msg_id_t ke_msg_dest_id_get(void const *param_ptr); + + + +/** + **************************************************************************************** + * @brief Retrieve source task identifier of a kernel message + * + * @param[in] param_ptr Pointer to the parameter member of the message. + * + * @return message source task + **************************************************************************************** + */ +ke_msg_id_t ke_msg_src_id_get(void const *param_ptr); + +/** + * Used to know if message is present in kernel queue or not. + * + * @param[in] param_ptr Pointer to the parameter member of the message. + * + * @return True if message is present in Kernel Queue, False else. + */ +bool ke_msg_in_queue(void const *param_ptr); +/// @} MSG + +#endif // _KE_MSG_H_ diff --git a/services/ble_stack/ke/api/ke_task.h b/services/ble_stack/ke/api/ke_task.h new file mode 100644 index 0000000..71b8758 --- /dev/null +++ b/services/ble_stack/ke/api/ke_task.h @@ -0,0 +1,219 @@ +#ifndef _KE_TASK_H_ +#define _KE_TASK_H_ + +/** + **************************************************************************************** + * @defgroup TASK Task and Process + * @ingroup KERNEL + * @brief Task management module. + * + * This module implements the functions used for managing tasks. + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include // standard integer +#include // standard boolean + +#include "rwip_config.h" // stack configuration +#include "compiler.h" // compiler defines, INLINE +#include "ke_msg.h" // kernel message defines + +/* Default Message handler code to handle several message type in same handler. */ +#define KE_MSG_DEFAULT_HANDLER (0xFFFF) +/* Invalid task */ +#define KE_TASK_INVALID (0xFFFF) +/* Used to know if a message is not present in kernel queue */ +#define KE_MSG_NOT_IN_QUEUE ((struct co_list_hdr *) 0xFFFFFFFF) + +/// Status of ke_task API functions +enum KE_TASK_STATUS +{ + KE_TASK_OK = 0, + KE_TASK_FAIL, + KE_TASK_UNKNOWN, + KE_TASK_CAPA_EXCEEDED, + KE_TASK_ALREADY_EXISTS, +}; + + +#define MSG_T(msg) ((ke_task_id_t)((msg) >> 8)) +#define MSG_I(msg) ((msg) & ((1<<8)-1)) + +/// Format of a task message handler function +typedef int (*ke_msg_func_t)(ke_msg_id_t const msgid, void const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id); + +/// Macro for message handler function declaration or definition +#define KE_MSG_HANDLER(msg_name, param_struct) __STATIC int msg_name##_handler(ke_msg_id_t const msgid, \ + param_struct const *param, \ + ke_task_id_t const dest_id, \ + ke_task_id_t const src_id) + +#define KE_MSG_HANDLER_NO_STATIC(msg_name, param_struct) int msg_name##_handler(ke_msg_id_t const msgid, \ + param_struct const *param, \ + ke_task_id_t const dest_id, \ + ke_task_id_t const src_id) + +/// Macro for message handlers table declaration or definition +#define KE_MSG_HANDLER_TAB(task) __STATIC const struct ke_msg_handler task##_msg_handler_tab[] = + +/// Element of a message handler table. +struct ke_msg_handler +{ + /// Id of the handled message. + ke_msg_id_t id; + /// Pointer to the handler function for the msgid above. + ke_msg_func_t func; +}; + +/// Element of a state handler table. +struct ke_state_handler +{ + /// Pointer to the message handler table of this state. + const struct ke_msg_handler *msg_table; + /// Number of messages handled in this state. + uint16_t msg_cnt; +}; + +/// Task descriptor grouping all information required by the kernel for the scheduling. +struct ke_task_desc +{ + /// Pointer to the message handler table + const struct ke_msg_handler* msg_handler_tab; + /// Pointer to the state table (one element for each instance). + ke_state_t* state; + /// Maximum index of supported instances of the task. + uint16_t idx_max; + /// Number of messages handled + uint16_t msg_cnt; +}; + +/* + * FUNCTION PROTOTYPES + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Initialize Kernel task module. + **************************************************************************************** + */ +void ke_task_init(void); + +/** + **************************************************************************************** + * @brief Create a task. + * + * @param[in] task_type Task type. + * @param[in] p_task_desc Pointer to task descriptor. + * + * @return Status + **************************************************************************************** + */ +uint8_t ke_task_create(uint8_t task_type, struct ke_task_desc const * p_task_desc); + +/** + **************************************************************************************** + * @brief Delete a task. + * + * @param[in] task_type Task type. + * + * @return Status + **************************************************************************************** + */ +uint8_t ke_task_delete(uint8_t task_type); + +/** + **************************************************************************************** + * @brief Retrieve the state of a task. + * + * @param[in] id Task id. + * + * @return Current state of the task + **************************************************************************************** + */ +ke_state_t ke_state_get(ke_task_id_t const id); + +/** + **************************************************************************************** + * @brief Set the state of the task identified by its Task Id. + * + * In this function we also handle the SAVE service: when a task state changes we + * try to activate all the messages currently saved in the save queue for the given + * task identifier. + * + * @param[in] id Identifier of the task instance whose state is going to be modified + * @param[in] state_id New State + * + **************************************************************************************** + */ +void ke_state_set(ke_task_id_t const id, ke_state_t const state_id); + +/** + **************************************************************************************** + * @brief Generic message handler to consume message without handling it in the task. + * + * @param[in] msgid Id of the message received (probably unused) + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id TaskId of the receiving task. + * @param[in] src_id TaskId of the sending task. + * + * @return KE_MSG_CONSUMED + **************************************************************************************** + */ +int ke_msg_discard(ke_msg_id_t const msgid, void const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id); + +/** + **************************************************************************************** + * @brief Generic message handler to consume message without handling it in the task. + * + * @param[in] msgid Id of the message received (probably unused) + * @param[in] param Pointer to the parameters of the message. + * @param[in] dest_id TaskId of the receiving task. + * @param[in] src_id TaskId of the sending task. + * + * @return KE_MSG_CONSUMED + **************************************************************************************** + */ +int ke_msg_save(ke_msg_id_t const msgid, void const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id); + + + +/** + **************************************************************************************** + * @brief This function flushes all messages, currently pending in the kernel for a + * specific task. + * + * @param[in] task The Task Identifier that shall be flushed. + **************************************************************************************** + */ +void ke_task_msg_flush(ke_task_id_t task); + + +/** + **************************************************************************************** + * @brief Check validity of a task. If task type or task instance does not exist, + * return invalid task + * + * @param[in] task Task Identifier to check. + * + * @return Task identifier if valid, invalid identifier else. + **************************************************************************************** + */ +ke_task_id_t ke_task_check(ke_task_id_t task); + +void ke_task_msg_retrieve(ke_task_id_t const id); + +/// @} TASK + +#endif // _KE_TASK_H_ + diff --git a/services/ble_stack/ke/api/ke_timer.h b/services/ble_stack/ke/api/ke_timer.h new file mode 100644 index 0000000..86cbb48 --- /dev/null +++ b/services/ble_stack/ke/api/ke_timer.h @@ -0,0 +1,140 @@ +#ifndef _KE_TIMER_H_ +#define _KE_TIMER_H_ + +/** + **************************************************************************************** + * @defgroup TIMER BT Time + * @ingroup KERNEL + * @brief Timer management module. + * + * This module implements the functions used for managing kernel timers. + * + **************************************************************************************** + */ + +#include "rwip_config.h" // stack configuration +#include "ke_msg.h" // messaging definition + + +/* + * DEFINITIONS + **************************************************************************************** + */ + +/// Convert timer from second to timer accuracy (10ms) +#define KE_TIME_IN_SEC(_time) (_time * 100) + + +/* + * TYPE DEFINITIONS + **************************************************************************************** + */ + +/// Timer Object +struct ke_timer +{ + /// next ke timer + struct ke_timer *next; + /// message identifier + ke_msg_id_t id; + /// task identifier + ke_task_id_t task; + /// time value + uint32_t time; +}; + + +/* + * FUNCTION PROTOTYPES + **************************************************************************************** + */ + + +/** + **************************************************************************************** + * @brief Initialize Kernel timer module. + **************************************************************************************** + */ +void ke_timer_init(void); + +/** + **************************************************************************************** + * @brief Set a timer. + * + * The function first cancel the timer if it is already existing, then + * it creates a new one. The timer can be one-shot or periodic, i.e. it + * will be automatically set again after each trigger. + * + * When the timer expires, a message is sent to the task provided as + * argument, with the timer id as message id. + * + * The timer is programmed in time units (TU is 10ms). + * + * @param[in] timer_id Timer identifier (message identifier type). + * @param[in] task_id Task identifier which will be notified + * @param[in] delay Delay in time units. + **************************************************************************************** + */ +void ke_timer_set(ke_msg_id_t const timer_id, ke_task_id_t const task, uint32_t delay); + +/** + **************************************************************************************** + * @brief Remove an registered timer. + * + * This function search for the timer identified by its id and its task id. + * If found it is stopped and freed, otherwise an error message is returned. + * + * @param[in] timer_id Timer identifier. + * @param[in] task Task identifier. + **************************************************************************************** + */ +void ke_timer_clear(ke_msg_id_t const timerid, ke_task_id_t const task); + +/** + **************************************************************************************** + * @brief Checks if a requested timer is active. + * + * This function pops the first timer from the timer queue and notifies the appropriate + * task by sending a kernel message. If the timer is periodic, it is set again; + * if it is one-shot, the timer is freed. The function checks also the next timers + * and process them if they have expired or are about to expire. + **************************************************************************************** + */ +bool ke_timer_active(ke_msg_id_t const timer_id, ke_task_id_t const task_id); + +/** + **************************************************************************************** + * @brief Adjust all kernel timers by specified adjustment delay. + * + * This function updates all timers to align to a new SCLK after a system clock adjust. + **************************************************************************************** + */ +void ke_timer_adjust_all(uint32_t delay); + +/** + **************************************************************************************** + * @brief Compute the authorized sleep time until next kernel timer event + * + * The function takes as argument the current time to compute the sleep time. + * + * if some timer are programmed it return the sleep time between current time and + * first timer expiration. + * + * If there is no timer programmed, function return false meaning that platform should not + * consider the kernel timer to decide the sleep time duration. + * + * @param[in] current_time Current system time + * @param[out] sleep_time Computed sleep duration + * + * @return true sleep time has been computed ; false if there is no programed timer, + meaning that sleep_time is not relevant and can be ignored. + **************************************************************************************** + */ +bool ke_sleep_time_get(uint32_t current_time, int32_t* sleep_time); + +bool ke_timer_is_active(void); + + +/// @} TIMER + +#endif // _KE_TIMER_H_ diff --git a/services/ble_stack/ke/src/ke_env.h b/services/ble_stack/ke/src/ke_env.h new file mode 100644 index 0000000..0afb6e7 --- /dev/null +++ b/services/ble_stack/ke/src/ke_env.h @@ -0,0 +1,53 @@ +#ifndef _KE_ENV_H_ +#define _KE_ENV_H_ + +/** + **************************************************************************************** + * @addtogroup ENV Environment + * @ingroup KERNEL + * @brief Kernel Environment + * + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "rwip_config.h" // stack configuration +#include "ke_event.h" // kernel event +#include "co_list.h" // kernel queue definition + +// forward declaration +struct mblock_free; + +/// Kernel environment definition +struct ke_env_tag +{ + /// Queue of sent messages but not yet delivered to receiver + struct co_list queue_sent; + /// Queue of messages delivered but not consumed by receiver + struct co_list queue_saved; + /// Queue of timers + struct co_list queue_timer; + + /// Root pointer = pointer to first element of heap linked lists + struct mblock_free * heap[KE_MEM_BLOCK_MAX]; + /// Size of heaps + uint16_t heap_size[KE_MEM_BLOCK_MAX]; + + #if (KE_PROFILING) + /// Size of heap used + uint16_t heap_used[KE_MEM_BLOCK_MAX]; + /// Maximum heap memory used + uint32_t max_heap_used; + #endif //KE_PROFILING +}; + +/// Kernel environment +extern struct ke_env_tag ke_env; + +/// @} ENV + +#endif // _KE_ENV_H_ diff --git a/services/ble_stack/ke/src/ke_queue.h b/services/ble_stack/ke/src/ke_queue.h new file mode 100644 index 0000000..e5953b5 --- /dev/null +++ b/services/ble_stack/ke/src/ke_queue.h @@ -0,0 +1,106 @@ +#ifndef _KE_QUEUE_H_ +#define _KE_QUEUE_H_ + +/** + **************************************************************************************** + * @addtogroup QUEUE Queues and Lists + * @ingroup KERNEL + * @brief Queue management module + * + * This module implements the functions used for managing message queues. + * These functions must not be called under IRQ! + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include // standard integer +#include // standard boolean +#include "compiler.h" // compiler definitions +#include "co_list.h" // list definition + +/* + * FUNCTION PROTOTYPES + **************************************************************************************** + */ + +/** + **************************************************************************************** + * @brief Pop entry to the queue + * + * @param[in] queue Pointer to the queue. + * @param[in] element Pointer to the element. + **************************************************************************************** + */ +__STATIC __INLINE void ke_queue_push(struct co_list *const queue, struct co_list_hdr *const element) +{ + co_list_push_back(queue, element); +} + +/** + **************************************************************************************** + * @brief push entry to the front of queue + * + * @param[in] queue Pointer to the queue. + * @param[in] element Pointer to the element. + **************************************************************************************** + */ +__STATIC __INLINE void ke_queue_push_front(struct co_list *const queue, struct co_list_hdr *const element) +{ + co_list_push_front(queue, element); +} + +/** + **************************************************************************************** + * @brief Pop entry from the queue + * + * @param[in] queue Pointer to the queue. + * + * @return Pointer to the element. + **************************************************************************************** + */ +__STATIC __INLINE struct co_list_hdr *ke_queue_pop(struct co_list *const queue) +{ + return co_list_pop_front(queue); +} + +/** + **************************************************************************************** + * @brief Extracts an element matching a given algorithm. + * + * @param[in] queue Pointer to the queue. + * @param[in] func Matching function. + * @param[in] arg Match argument. + * + * @return Pointer to the element found and removed (NULL otherwise). + **************************************************************************************** + */ +struct co_list_hdr *ke_queue_extract(struct co_list * const queue, + bool (*func)(struct co_list_hdr const * elmt, uint32_t arg), + uint32_t arg); + +/** + **************************************************************************************** + * @brief Insert an element in a sorted queue. + * + * This primitive use a comparison function from the parameter list to select where the + * element must be inserted. + * + * @param[in] queue Pointer to the queue. + * @param[in] element Pointer to the element to insert. + * @param[in] cmp Comparison function (return true if first element has to be inserted + * before the second one). + * + * @return Pointer to the element found and removed (NULL otherwise). + **************************************************************************************** + */ +void ke_queue_insert(struct co_list * const queue, struct co_list_hdr * const element, + bool (*cmp)(struct co_list_hdr const *elementA, + struct co_list_hdr const *elementB)); + +/// @} QUEUE + +#endif // _KE_QUEUE_H_ diff --git a/services/bridge/Makefile b/services/bridge/Makefile new file mode 100644 index 0000000..f9775ba --- /dev/null +++ b/services/bridge/Makefile @@ -0,0 +1,54 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +ifeq ($(ENHANCED_STACK),1) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)bridge_v2.c)) +else +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)bridge.c)) +endif + +BTBRIDGE_LIB_NAME := $(CHIP)_libbridge + +ifeq ($(HFP_1_6_ENABLE), 1) +BTBRIDGE_LIB_NAME := $(BTBRIDGE_LIB_NAME)_sbc_enc +endif + +$(BTBRIDGE_LIB_NAME)-y := $(obj_c:.c=.o) + +obj-y := $(BTBRIDGE_LIB_NAME).a + +PROF_INC := + + +subdir-ccflags-y += \ + -Iservices/bridge/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/hl/api/ \ + -Iservices/ble_stack/hl/src/gap/ \ + -Iservices/ble_stack/hl/src/gap/gapc/ \ + -Iservices/ble_stack/hl/src/gap/gapm/ \ + -Iservices/ble_stack/hl/src/gap/smpc/ \ + -Iservices/ble_stack/ke/api/ \ + -Iservices/ble_stack/ke/src/ \ + -Iservices/ble_stack/hl/src/gatt/attc/ \ + -Iservices/ble_stack/hl/src/gatt/attm/ \ + -Iservices/ble_stack/hl/src/gatt/atts/ \ + -Iservices/ble_stack/hl/src/gatt/gattc/ \ + -Iservices/ble_stack/hl/src/gatt/gattm/ \ + -Iservices/ble_stack/hl/src/gatt/ \ + -Iservices/ble_stack/hl/src/l2c/l2cc/ \ + -Iservices/ble_stack/hl/src/l2c/l2cm/ \ + -Iservices/ble_stack/hci/api/ \ + -Iservices/ble_stack/hci/src/ \ + -Iservices/ble_stack/dbg/api/ \ + -Iservices/ble_stack/dbg/src/ \ + -Iservices/ble_stack/ble_ip/ \ + -Iutils/intersyshci/ \ + -Iplatform/drivers/bt/ \ + -Iservices/bt_app/ \ + -Iservices/osif/ \ + $(BT_IF_INCLUDES) \ + $(BT_PROFILES_INCLUDES) + + diff --git a/services/bridge/bridge.h b/services/bridge/bridge.h new file mode 100644 index 0000000..6724024 --- /dev/null +++ b/services/bridge/bridge.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BRIDGE_H__ +#define __BRIDGE_H__ + +#if !defined(ENHANCED_STACK) +#include "hci.h" +#endif + +#include "ke_msg.h" + +#if defined(ENHANCED_STACK) + +typedef struct { + uint8_t *buffer; + uint16_t buffer_len; + uint8_t *priv; + uint16_t conn_handle_flags; +} BridgeBuffer; + +typedef struct { + U8 *param; + U8 param_len; + uint8_t event; + BridgeBuffer *rx_buff; +} BridgeEvent; + +#else + +typedef HciEvent BridgeEvent; +typedef HciBuffer BridgeBuffer; + +#endif /* ENHANCED_STACK */ + +void bridge_hcif_send_acl(struct ke_msg *msg); +void bridge_hcif_recv_acl(BridgeBuffer * pBuffer); +void bridge_free_rx_buffer(BridgeBuffer *pBuffer); +void bridge_free_tx_buffer(BridgeBuffer *pBuffer); +void bridge_hci_ble_event(const BridgeEvent* event); +uint8_t bridge_is_cmd_opcode_supported(uint16_t opcode); +void bridge_free_token(void * token); +U8 bridge_check_ble_handle_valid(U16 handle); +void bridge_hcif_send_cmd(struct ke_msg *msg); + +#endif diff --git a/services/bt_app/Makefile b/services/bt_app/Makefile new file mode 100644 index 0000000..48341b0 --- /dev/null +++ b/services/bt_app/Makefile @@ -0,0 +1,277 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) + +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) +ifeq ($(VOICE_DATAPATH_TYPE),gsound) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)/app_voice/app_$(VOICE_DATAPATH_TYPE)/*.cpp)) +endif + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +obj-y += a2dp_codecs/ + +ifeq ($(A2DP_AAC_ON),1) +AAC_INCLUDES = \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libAACdec/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libAACenc/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libFDK/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libPCMutils/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libSBRdec/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libSBRenc/include \ + -Iservices/multimedia/audio/codec/fdkaac_codec/libSYS/include +else +AAC_INCLUDES = +endif + +ccflags-y += \ + $(AAC_INCLUDES) \ + -Iservices/osif \ + -Iservices/audio_process \ + -Iservices/audio_dump/include \ + -Iservices/hw_dsp/inc \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + $(BT_IF_INCLUDES) \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/multimedia/speech/inc \ + -Iservices/bone_sensor/lis25ba \ + -Iservices/overlay \ + -Ithirdparty/tile/tile_common/tile_storage \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iservices/multimedia/rbcodec \ + -Iservices/multimedia/audio/process/resample/include \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/audio/process/drc/include \ + -Iservices/multimedia/audio/process/anc/include\ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/userdata_section \ + -Iservices/nv_section/include \ + -Iservices/voicepath/$(VOICE_DATAPATH_TYPE) \ + -Iservices/voicepath/gsound/gsound_target \ + -Iservices/voicepath/gsound/gsound_custom/inc \ + -Iservices/voicepath/gsound/gsound_target_api_read_only \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/cmsis \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iapps/anc/inc \ + -Iapps/key \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/audioplayers/a2dp_decoder \ + -Iapps/battery \ + -Iapps/common \ + -Iapps/factory \ + -Iservices/app_ibrt/inc \ + -Iservices/ble_app \ + -Iutils/hwtimer_list \ + -Iservices/ibrt_core/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/voicepath \ + -Ithirdparty/userapi \ + -Iservices/ble_app/app_gfps \ + -Iservices/ble_app/app_main \ + -Ithirdparty/audio_codec_lib/liblhdc-dec/inc \ + -Iservices/ai_voice/manager \ + -Iservices/ai_voice/audio \ + -Iservices/ai_voice/transport \ + -Iservices/app_ai/inc \ + -Iservices/interconnection/red \ + -Iservices/interconnection/green \ + -Iservices/interconnection/umm_malloc \ + -Iservices/bt_app \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/multimedia/audio/process/adj_mc/inc \ + -Iservices/bt_app/a2dp_codecs/include \ + -Ithirdparty/tile/tile_target \ + -Iservices/osif \ + -Iservices/app_tws/inc + +ifeq ($(GATT_OVER_BR_EDR),1) +ccflags-y += -Iservices/ble_stack/hl/src/l2c/l2cm +endif + +ifeq ($(ANC_NOISE_TRACKER),1) +ccflags-y += \ + -Ithirdparty/noise_tracker_lib \ + -Ithirdparty/userapi/noise_tracker_app +endif + +ifeq ($(BTUSB_AUDIO_MODE),1) +ccflags-y += -Iapps/btusbaudio +endif + +ifeq ($(BT_USB_AUDIO_DUAL_MODE),1) +ccflags-y += -Iapps/btusbaudio +ccflags-y += $(BT_PROFILES_INCLUDES) +endif + +ifeq ($(INTERCONNECTION),1) +ccflags-y += $(BT_PROFILES_INCLUDES) +endif + +ifeq ($(INTERACTION),1) +ccflags-y += $(BT_PROFILES_INCLUDES) +endif + +CFLAGS_app_bt_stream.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) + +ifeq ($(A2DP_LDAC_ON),1) +ccflags-y += -Ithirdparty/audio_codec_lib/ldac/inc +endif + +ifeq ($(RB_CODEC),1) +ccflags-y += -DRB_CODEC +endif + +ifeq ($(TEST_OVER_THE_AIR),1) +ccflags-y += -Iservices/tota +endif + +ifeq ($(IBRT),1) +ccflags-y += -Iservices/ibrt/inc +endif + + +ifeq ($(AUDIO_QUEUE_SUPPORT),1) +CFLAGS_app_bt_media_manager.o += -D__AUDIO_QUEUE_SUPPORT__ +endif + +CFLAGS_besmain.o += -DBUILD_HOSTNAME=$(BUILD_HOSTNAME) -DBUILD_USERNAME=$(BUILD_USERNAME) + +ifeq ($(SPEECH_TX_AEC),1) +CFLAGS_app_bt_stream.o += -DSPEECH_TX_AEC +CFLAGS_app_hfp.o += -DSPEECH_TX_AEC +endif + +ifeq ($(SPEECH_TX_NS),1) +CFLAGS_app_bt_stream.o += -DSPEECH_TX_NS +CFLAGS_app_hfp.o += -DSPEECH_TX_NS +endif + +ifeq ($(AUDIO_INPUT_MONO),1) +CFLAGS_app_bt_stream.o += -D__AUDIO_INPUT_MONO_MODE__ +endif + +ifeq ($(AUDIO_OUTPUT_MONO),1) +CFLAGS_app_bt_stream.o += -D__AUDIO_OUTPUT_MONO_MODE__ +endif + +ifeq ($(AUDIO_OUTPUT_SW_GAIN),1) +CFLAGS_app_bt_stream.o += -DAUDIO_OUTPUT_SW_GAIN +endif + +ifeq ($(AUDIO_RESAMPLE),1) +CFLAGS_app_bt_stream.o += -D__AUDIO_RESAMPLE__ +endif +ifeq ($(SW_PLAYBACK_RESAMPLE),1) +CFLAGS_app_bt_stream.o += -DSW_PLAYBACK_RESAMPLE +endif +ifeq ($(SW_CAPTURE_RESAMPLE),1) +CFLAGS_app_bt_stream.o += -DSW_CAPTURE_RESAMPLE +endif +ifeq ($(SW_SCO_RESAMPLE),1) +CFLAGS_app_bt_stream.o += -DSW_SCO_RESAMPLE +endif +ifeq ($(NO_SCO_RESAMPLE),1) +CFLAGS_app_bt_stream.o += -DNO_SCO_RESAMPLE +endif +ifeq ($(RESAMPLE_ANY_SAMPLE_RATE),1) +CFLAGS_app_bt_stream.o += -DRESAMPLE_ANY_SAMPLE_RATE +endif + +ifeq ($(BT_XTAL_SYNC),1) +CFLAGS_app_bt_stream.o += -DBT_XTAL_SYNC +endif + +ifeq ($(AUDIO_SPECTRUM),1) +CFLAGS_app_bt_stream.o += -D__AUDIO_SPECTRUM__ +endif + +ifeq ($(HW_FIR_EQ_PROCESS),1) +CFLAGS_app_bt_stream.o += -D__HW_FIR_EQ_PROCESS__ +endif + +ifeq ($(HW_IIR_EQ_PROCESS),1) +CFLAGS_app_bt_stream.o += -D__HW_IIR_EQ_PROCESS__ +endif + +ifeq ($(SW_IIR_EQ_PROCESS),1) +CFLAGS_app_bt_stream.o += -D__SW_IIR_EQ_PROCESS__ +endif + +ifeq ($(HW_DAC_IIR_EQ_PROCESS),1) +CFLAGS_app_bt_stream.o += -D__HW_DAC_IIR_EQ_PROCESS__ +endif + +ifeq ($(ANC_APP),1) +CFLAGS_app_bt_stream.o += -DANC_APP +CFLAGS_app_media_player.o += -DANC_APP +endif + +ifeq ($(ANC_WNR_ENABLED),1) +CFLAGS_app_bt_stream.o += -DANC_WNR_ENABLED +endif + +MUSIC_DELAY_CONTROL ?= 1 + +ifeq ($(MUSIC_DELAY_CONTROL),1) +CFLAGS_app_bt_stream.o += -DMUSIC_DELAY_CONTROL +endif + +ifeq ($(A2DP_EQ_24BIT),1) +CFLAGS_app_bt_stream.o += -DA2DP_EQ_24BIT +CFLAGS_app_ring_merge.o += -DA2DP_EQ_24BIT +endif + +ifeq ($(APP_MUSIC_26M),1) +CFLAGS_app_bt_stream.o += -DAPP_MUSIC_26M +endif + +ifeq ($(AUDIO_DRC),1) +ccflags-y += -D__AUDIO_DRC__ +endif + +ifeq ($(AUDIO_DRC2),1) +ccflags-y += -D__AUDIO_DRC2__ +endif + +ifeq ($(SPEECH_TX_AEC_CODEC_REF),1) +CFLAGS_app_bt_stream.o += -DSPEECH_TX_AEC_CODEC_REF +endif + +ifeq ($(SPEECH_RX_24BIT),1) +CFLAGS_app_bt_stream.o += -DSPEECH_RX_24BIT +endif + +ifeq ($(ANC_NOISE_TRACKER),1) +CFLAGS_app_bt_stream.o += -DANC_NOISE_TRACKER +endif + +ifeq ($(SNIFF_MODE_CHECK),1) +CFLAGS_app_a2dp.o += -D__SNIFF_MODE_CHECK__ +endif + +ifeq ($(MEDIA_PLAY_24BIT),1) +CFLAGS_app_media_player.o += -DMEDIA_PLAY_24BIT +endif diff --git a/services/bt_app/a2dp_codecs/Makefile b/services/bt_app/a2dp_codecs/Makefile new file mode 100644 index 0000000..8848241 --- /dev/null +++ b/services/bt_app/a2dp_codecs/Makefile @@ -0,0 +1,84 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_s += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*/*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*/*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*/*.cpp)) + +A2DPCODECS_LIB_NAME := lib_a2dpcodecs + +obj-y += $(A2DPCODECS_LIB_NAME).a + +$(A2DPCODECS_LIB_NAME)-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +CFLAGS_a2dp_codec_ldac.o += -Ithirdparty/audio_codec_lib/ldac/inc + +subdir-ccflags-y += \ + -Iservices/audio_process \ + -Iservices/hw_dsp/inc \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + $(BT_IF_INCLUDES) \ + -Iservices/multimedia/speech/inc \ + -Iservices/bone_sensor/lis25ba \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iservices/multimedia/rbcodec \ + -Iservices/multimedia/audio/process/resample/include \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/audio/process/drc/include \ + -Iservices/multimedia/audio/process/anc/include\ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/userdata_section \ + -Iservices/nv_section/include \ + -Iservices/voicepath/$(VOICE_DATAPATH_TYPE) \ + -Iservices/voicepath/gsound \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/cmsis \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iapps/anc/inc \ + -Iapps/key \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/audioplayers/a2dp_decoder \ + -Iapps/battery \ + -Iapps/common \ + -Iapps/factory \ + -Iservices/app_ibrt/inc \ + -Iservices/ble_app \ + -Iutils/hwtimer_list \ + -Iservices/ibrt_ui/inc \ + -Iservices/ibrt_core/inc \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/voicepath \ + -Ithirdparty/userapi \ + -Iservices/ble_app/app_gfps \ + -Iservices/ble_app/app_main \ + -Ithirdparty/audio_codec_lib/liblhdc-dec/inc \ + -Iservices/ai_voice/manager \ + -Iservices/ai_voice/audio \ + -Iservices/ai_voice/transport \ + -Iservices/app_ai/inc \ + -Iservices/interconnection/red \ + -Iservices/interconnection/green \ + -Iservices/interconnection/umm_malloc \ + -Iservices/bt_app \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/bt_app/a2dp_codecs/include diff --git a/services/bt_app/a2dp_codecs/aac/a2dp_codec_aac.cpp b/services/bt_app/a2dp_codecs/aac/a2dp_codec_aac.cpp new file mode 100644 index 0000000..b18ea18 --- /dev/null +++ b/services/bt_app/a2dp_codecs/aac/a2dp_codec_aac.cpp @@ -0,0 +1,108 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "app.h" +#include "bt_drv.h" +#include "app_audio.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "hal_location.h" +#include "a2dp_api.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif + +#include "a2dp_api.h" +#include "avrcp_api.h" +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "tgt_hardware.h" +#include "bt_drv_interface.h" +#include "hci_api.h" + +#include "a2dp_codec_aac.h" +#include "avdtp_api.h" + +extern struct BT_DEVICE_T app_bt_device; + +#if defined(A2DP_AAC_ON) + +#ifdef __A2DP_AVDTP_CP__ +btif_avdtp_content_prot_t a2dp_aac_avdtpCp[BT_DEVICE_NUM]; +U8 a2dp_avdtpCp_aac_securityData[BT_DEVICE_NUM][ BTIF_AVDTP_MAX_CP_VALUE_SIZE] = {}; +#endif + +btif_avdtp_codec_t a2dp_aac_avdtpcodec; + +const unsigned char a2dp_codec_aac_elements[A2DP_AAC_OCTET_NUMBER] = { + A2DP_AAC_OCTET0_MPEG2_AAC_LC, + A2DP_AAC_OCTET1_SAMPLING_FREQUENCY_44100, + A2DP_AAC_OCTET2_CHANNELS_1 | A2DP_AAC_OCTET2_CHANNELS_2 | A2DP_AAC_OCTET2_SAMPLING_FREQUENCY_48000, + A2DP_AAC_OCTET3_VBR_SUPPORTED | ((MAX_AAC_BITRATE >> 16) & 0x7f), + /* left bit rate 0 for unkown */ + (MAX_AAC_BITRATE >> 8) & 0xff, + (MAX_AAC_BITRATE) & 0xff +}; + + +btif_avdtp_codec_t *app_a2dp_codec_get_aac_avdtp_codec() +{ + return (btif_avdtp_codec_t *)&a2dp_aac_avdtpcodec; +} + +bt_status_t a2dp_codec_aac_init(int index) +{ + bt_status_t st; + struct BT_DEVICE_T *bt_dev = &app_bt_device; + +#ifdef __A2DP_AVDTP_CP__ + a2dp_aac_avdtpCp[index].cpType = BTIF_AVDTP_CP_TYPE_SCMS_T; + a2dp_aac_avdtpCp[index].data = (U8 *)&a2dp_avdtpCp_aac_securityData[index][0]; + a2dp_aac_avdtpCp[index].dataLen = 0; +#endif + + a2dp_aac_avdtpcodec.codecType = BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC; + a2dp_aac_avdtpcodec.discoverable = 1; + a2dp_aac_avdtpcodec.elements = (U8 *)&a2dp_codec_aac_elements; + a2dp_aac_avdtpcodec.elemLen = sizeof(a2dp_codec_aac_elements); + +#ifdef __A2DP_AVDTP_CP__ + st = btif_a2dp_register(bt_dev->a2dp_aac_stream[index]->a2dp_stream, BTIF_A2DP_STREAM_TYPE_SINK, &a2dp_aac_avdtpcodec,&a2dp_aac_avdtpCp[index], 1, index,a2dp_callback); + btif_a2dp_add_content_protection(bt_dev->a2dp_aac_stream[index]->a2dp_stream, &a2dp_aac_avdtpCp[index]); +#else + st = btif_a2dp_register(bt_dev->a2dp_aac_stream[index]->a2dp_stream, BTIF_A2DP_STREAM_TYPE_SINK, &a2dp_aac_avdtpcodec, NULL, 1,index, a2dp_callback); +#endif + + return st; +} + +#endif /* A2DP_AAC_ON */ diff --git a/services/bt_app/a2dp_codecs/app_a2dp_codecs.cpp b/services/bt_app/a2dp_codecs/app_a2dp_codecs.cpp new file mode 100644 index 0000000..1e3ee04 --- /dev/null +++ b/services/bt_app/a2dp_codecs/app_a2dp_codecs.cpp @@ -0,0 +1,241 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "app.h" +#include "bt_drv.h" +#include "app_audio.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "hal_location.h" +#include "a2dp_api.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif + +#include "a2dp_api.h" +#include "avrcp_api.h" +#include "besbt.h" + +#include "cqueue.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "tgt_hardware.h" +#include "bt_drv_interface.h" +#include "hci_api.h" + +#define _FILE_TAG_ "A2DP" +#include "color_log.h" +#include "app_bt_func.h" +#include "os_api.h" + +#if (A2DP_DECODER_VER >= 2) +#include "a2dp_decoder.h" +#endif + +#include "btapp.h" +#include "app_a2dp_codecs.h" +#include "app_a2dp.h" + +extern struct BT_DEVICE_T app_bt_device; + +int a2dp_codec_source_init(void) +{ + struct BT_DEVICE_T POSSIBLY_UNUSED *bt_dev = &app_bt_device; + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + if(bt_dev->src_or_snk == BT_DEVICE_SRC) + { + a2dp_avdtpcodec.codecType = BTIF_AVDTP_CODEC_TYPE_SBC; + a2dp_avdtpcodec.discoverable = 1; + a2dp_avdtpcodec.elements = (U8 *)&a2dp_codec_elements; + a2dp_avdtpcodec.elemLen = 4; + btif_a2dp_register(bt_dev->a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream, BTIF_A2DP_STREAM_TYPE_SOURCE, &a2dp_avdtpcodec, NULL, 0,0, a2dp_callback); + } +#endif + + return 0; +} + +int a2dp_codec_sink_init(void) +{ + int i; + struct BT_DEVICE_T POSSIBLY_UNUSED *bt_dev = &app_bt_device; + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + if(bt_dev->src_or_snk != BT_DEVICE_SRC) +#endif + { + for(i = 0; i < BT_DEVICE_NUM; i++) + { + a2dp_codec_sbc_init(i); +#if defined(A2DP_AAC_ON) + a2dp_codec_aac_init(i); +#endif +#if defined(A2DP_LDAC_ON) + a2dp_codec_ldac_init(i); +#endif +#if defined(A2DP_LHDC_ON) + a2dp_codec_lhdc_init(i); +#endif +#if defined(MASTER_USE_OPUS) || defined(ALL_USE_OPUS) + a2dp_codec_opus_init(i); +#endif +#if defined(A2DP_SCALABLE_ON) + a2dp_codec_scalable_init(i); +#endif + } + } + + return 0; +} + +uint8_t a2dp_codec_confirm_stream_state(uint8_t index, uint8_t old_state, uint8_t new_state) +{ + btif_a2dp_confirm_stream_state(app_bt_device.a2dp_stream[index]->a2dp_stream, old_state, new_state); +#if defined(A2DP_AAC_ON) + btif_a2dp_confirm_stream_state(app_bt_device.a2dp_aac_stream[index]->a2dp_stream, old_state, new_state); +#endif +#if defined(A2DP_LHDC_ON) + btif_a2dp_confirm_stream_state(app_bt_device.a2dp_lhdc_stream[index]->a2dp_stream, old_state, new_state); +#endif +#if defined(A2DP_SCALABLE_ON) + btif_a2dp_confirm_stream_state(app_bt_device.a2dp_scalable_stream[index]->a2dp_stream, old_state, new_state); +#endif +#if defined(A2DP_LDAC_ON) + btif_a2dp_confirm_stream_state(app_bt_device.a2dp_ldac_stream[index]->a2dp_stream, old_state, new_state); +#endif + + return 0; +} + +static void a2dp_set_codec_info(btif_dev_it_e dev_num, const uint8_t *codec) +{ + app_bt_device.codec_type[dev_num] = codec[0]; + app_bt_device.sample_bit[dev_num] = codec[1]; + app_bt_device.sample_rate[dev_num]= codec[2]; +#if defined(A2DP_LHDC_ON) + app_bt_device.a2dp_lhdc_llc[dev_num] = codec[3]; +#endif +#if defined(A2DP_LDAC_ON) + app_ibrt_restore_ldac_info(app_bt_device.sample_rate[dev_num]); +#endif + +} + +static void a2dp_get_codec_info(btif_dev_it_e dev_num, uint8_t *codec) +{ + codec[0] = app_bt_device.codec_type[dev_num]; + codec[1] = app_bt_device.sample_bit[dev_num]; + codec[2] = app_bt_device.sample_rate[dev_num]; +#if defined(A2DP_LHDC_ON) + codec[3] = app_bt_device.a2dp_lhdc_llc[dev_num]; +#endif +} + +int a2dp_codec_init(void) +{ + a2dp_codec_source_init(); + a2dp_codec_sink_init(); + btif_a2dp_get_codec_info_func(a2dp_get_codec_info); + btif_a2dp_set_codec_info_func(a2dp_set_codec_info); + return 0; +} + +btif_avdtp_codec_t * app_a2dp_codec_get_avdtp_codec() +{ + return (btif_avdtp_codec_t *)&a2dp_avdtpcodec; +} + +#if defined(IBRT) +enum AUD_SAMPRATE_T bt_parse_sbc_sample_rate(uint8_t sbc_samp_rate); +uint32_t app_a2dp_codec_parse_aac_sample_rate(const a2dp_callback_parms_t *info) +{ + uint32_t ret_sample_rate = AUD_SAMPRATE_44100; + btif_a2dp_callback_parms_t *p_info = (btif_a2dp_callback_parms_t *) info; + + if (p_info->p.configReq->codec.elements[1] & A2DP_AAC_OCTET1_SAMPLING_FREQUENCY_44100) + { + ret_sample_rate = AUD_SAMPRATE_44100; + } + else if (p_info->p.configReq->codec.elements[2] & A2DP_AAC_OCTET2_SAMPLING_FREQUENCY_48000) + { + ret_sample_rate = AUD_SAMPRATE_48000; + } + return ret_sample_rate; +} +uint32_t app_a2dp_codec_parse_aac_lhdc_sample_rate(const a2dp_callback_parms_t * info) +{ + btif_a2dp_callback_parms_t *p_info = (btif_a2dp_callback_parms_t *) info; + + switch (A2DP_LHDC_SR_DATA(p_info->p.configReq->codec.elements[6])) + { + case A2DP_LHDC_SR_96000: + return AUD_SAMPRATE_96000; + case A2DP_LHDC_SR_48000: + return AUD_SAMPRATE_48000; + case A2DP_LHDC_SR_44100: + return AUD_SAMPRATE_44100; + default: + return AUD_SAMPRATE_44100; + } +} +uint32_t app_a2dp_codec_get_sample_rate(const a2dp_callback_parms_t *info) +{ + btif_a2dp_callback_parms_t *p_info = (btif_a2dp_callback_parms_t *) info; + btif_avdtp_codec_type_t codetype = btif_a2dp_get_codec_type((const a2dp_callback_parms_t *)p_info); + + switch(codetype) + { + case BTIF_AVDTP_CODEC_TYPE_SBC: + return bt_parse_sbc_sample_rate(p_info->p.configReq->codec.elements[0]); + case BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC: + return app_a2dp_codec_parse_aac_sample_rate((const a2dp_callback_parms_t *)p_info); + case BTIF_AVDTP_CODEC_TYPE_LHDC: + return app_a2dp_codec_parse_aac_lhdc_sample_rate((const a2dp_callback_parms_t *)p_info); + default: + ASSERT(0,"btif_a2dp_get_sample_rate codetype error!!"); + return 0; + } +} +uint8_t app_a2dp_codec_get_sample_bit(const a2dp_callback_parms_t *info) +{ + btif_avdtp_codec_type_t codetype = btif_a2dp_get_codec_type(info); + btif_a2dp_callback_parms_t *p_info = (btif_a2dp_callback_parms_t *) info; + + if ((codetype == BTIF_AVDTP_CODEC_TYPE_LHDC) && + A2DP_LHDC_FMT_DATA(p_info->p.configReq->codec.elements[6])) + { + return 24; + } + else + { + //AAC and SBC sample bit eq 16 + return 16; + } +} +#endif diff --git a/services/bt_app/a2dp_codecs/include/a2dp_codec_aac.h b/services/bt_app/a2dp_codecs/include/a2dp_codec_aac.h new file mode 100644 index 0000000..5861e71 --- /dev/null +++ b/services/bt_app/a2dp_codecs/include/a2dp_codec_aac.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __A2DP_CODEC_AAC_H__ +#define __A2DP_CODEC_AAC_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "avdtp_api.h" +#include "tgt_hardware.h" + +#ifndef MAX_AAC_BITRATE +#if defined(CHIP_BEST1400) +#define MAX_AAC_BITRATE (96000) +#else +#define MAX_AAC_BITRATE (264630) +#endif +#endif + +#define A2DP_AAC_OCTET0_MPEG2_AAC_LC 0x80 +#define A2DP_AAC_OCTET0_MPEG4_AAC_LC 0x40 +#define A2DP_AAC_OCTET1_SAMPLING_FREQUENCY_44100 0x01 +#define A2DP_AAC_OCTET2_SAMPLING_FREQUENCY_48000 0x80 +#define A2DP_AAC_OCTET2_CHANNELS_1 0x08 +#define A2DP_AAC_OCTET2_CHANNELS_2 0x04 +#define A2DP_AAC_OCTET3_VBR_SUPPORTED 0x80 + +#define A2DP_AAC_OCTET_NUMBER (6) + +#if defined(A2DP_AAC_ON) +extern const unsigned char a2dp_codec_aac_elements[A2DP_AAC_OCTET_NUMBER]; +bt_status_t a2dp_codec_aac_init(int index); +#endif /* A2DP_AAC_ON */ + +#if defined(__cplusplus) +} +#endif + +#endif /* __A2DP_CODEC_AAC_H__ */ diff --git a/services/bt_app/a2dp_codecs/include/a2dp_codec_ldac.h b/services/bt_app/a2dp_codecs/include/a2dp_codec_ldac.h new file mode 100644 index 0000000..dfb4606 --- /dev/null +++ b/services/bt_app/a2dp_codecs/include/a2dp_codec_ldac.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __A2DP_CODEC_LDAC_H__ +#define __A2DP_CODEC_LDAC_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "avdtp_api.h" + +#define A2DP_LDAC_OCTET_NUMBER (8) +#define A2DP_LDAC_VENDOR_ID 0x0000012d +#define A2DP_LDAC_CODEC_ID 0x00aa +//To indicate Sampling Rate. +#define A2DP_LDAC_SR_96000 0x04 +#define A2DP_LDAC_SR_88200 0x08 +#define A2DP_LDAC_SR_48000 0x10 +#define A2DP_LDAC_SR_44100 0x20 +#define A2DP_LDAC_SR_DATA(X) (X & (A2DP_LDAC_SR_96000 | A2DP_LDAC_SR_88200 | A2DP_LDAC_SR_48000 | A2DP_LDAC_SR_44100)) +#define A2DP_LDAC_CM_DATA(X) (X & (A2DP_LDAC_CM_MONO | A2DP_LDAC_CM_DUAL | A2DP_LDAC_CM_STEREO)) +//To indicate channel mode(a2dp) +#define A2DP_LDAC_CM_MONO 0x04 +#define A2DP_LDAC_CM_DUAL 0x02 +#define A2DP_LDAC_CM_STEREO 0x01 + +#if defined(A2DP_LDAC_ON) +extern const unsigned char a2dp_codec_ldac_elements[A2DP_LDAC_OCTET_NUMBER]; +bt_status_t a2dp_codec_ldac_init(int index); +#endif /* A2DP_LDAC_ON */ + +#if defined(__cplusplus) +} +#endif + +#endif /* __A2DP_CODEC_LDAC_H__ */ \ No newline at end of file diff --git a/services/bt_app/a2dp_codecs/include/a2dp_codec_lhdc.h b/services/bt_app/a2dp_codecs/include/a2dp_codec_lhdc.h new file mode 100644 index 0000000..cb8559f --- /dev/null +++ b/services/bt_app/a2dp_codecs/include/a2dp_codec_lhdc.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __A2DP_CODEC_LHDC_H__ +#define __A2DP_CODEC_LHDC_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "avdtp_api.h" +#include "codec_lhdc.h" + +#if defined(A2DP_LHDC_ON) +extern const unsigned char a2dp_codec_lhdc_elements[A2DP_LHDC_OCTET_NUMBER]; +bt_status_t a2dp_codec_lhdc_init(int index); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* __A2DP_CODEC_LHDC_H__ */ \ No newline at end of file diff --git a/services/bt_app/a2dp_codecs/include/a2dp_codec_opus.h b/services/bt_app/a2dp_codecs/include/a2dp_codec_opus.h new file mode 100644 index 0000000..8c7ea2f --- /dev/null +++ b/services/bt_app/a2dp_codecs/include/a2dp_codec_opus.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __A2DP_CODEC_OPUS_H__ +#define __A2DP_CODEC_OPUS_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "avdtp_api.h" +#include "btapp.h" + +#if defined(MASTER_USE_OPUS) || defined(ALL_USE_OPUS) +bt_status_t a2dp_codec_opus_init(int index); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* __A2DP_CODEC_OPUS_H__ */ \ No newline at end of file diff --git a/services/bt_app/a2dp_codecs/include/a2dp_codec_sbc.h b/services/bt_app/a2dp_codecs/include/a2dp_codec_sbc.h new file mode 100644 index 0000000..049a0c8 --- /dev/null +++ b/services/bt_app/a2dp_codecs/include/a2dp_codec_sbc.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __A2DP_CODEC_SBC_H__ +#define __A2DP_CODEC_SBC_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "avdtp_api.h" + +extern btif_avdtp_codec_t a2dp_avdtpcodec; +extern const unsigned char a2dp_codec_elements[]; +bt_status_t a2dp_codec_sbc_init(int index); + +#if defined(__cplusplus) +} +#endif + +#endif /* __A2DP_CODEC_SBC_H__ */ \ No newline at end of file diff --git a/services/bt_app/a2dp_codecs/include/a2dp_codec_scalable.h b/services/bt_app/a2dp_codecs/include/a2dp_codec_scalable.h new file mode 100644 index 0000000..9195cd8 --- /dev/null +++ b/services/bt_app/a2dp_codecs/include/a2dp_codec_scalable.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __A2DP_CODEC_SCALABLE_H__ +#define __A2DP_CODEC_SCALABLE_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "avdtp_api.h" + +#define A2DP_SCALABLE_OCTET_NUMBER (7) +#define A2DP_SCALABLE_VENDOR_ID 0x00000075 +#define A2DP_SCALABLE_CODEC_ID 0x0103 + +//To indicate bits per sample. +#define A2DP_SCALABLE_HQ 0x08 +#define A2DP_SCALABLE_ADD_INFO1 0x00 +#define A2DP_SCALABLE_ADD_INFO2 0x00 +#define A2DP_SCALABLE_ADD_INFO3 0x00 +#define A2DP_SCALABLE_INFO(X) (X & (A2DP_SCALABLE_HQ | A2DP_SCALABLE_ADD_INFO1 | A2DP_SCALABLE_ADD_INFO2 | A2DP_SCALABLE_ADD_INFO3)) + +//To indicate Sampling Rate. +#define A2DP_SCALABLE_SR_96000 0x80 +#define A2DP_SCALABLE_SR_32000 0x40 +#define A2DP_SCALABLE_SR_44100 0x20 +#define A2DP_SCALABLE_SR_48000 0x10 +#define A2DP_SCALABLE_SR_DATA(X) (X & (A2DP_SCALABLE_SR_96000 | A2DP_SCALABLE_SR_32000 | A2DP_SCALABLE_SR_44100 | A2DP_SCALABLE_SR_48000)) + +//To indicate bits per sample. +#define A2DP_SCALABLE_FMT_24 0x08 +#define A2DP_SCALABLE_FMT_16 0x00 +#define A2DP_SCALABLE_FMT_DATA(X) (X & (A2DP_SCALABLE_FMT_24 | A2DP_SCALABLE_FMT_16)) + +extern btif_avdtp_codec_t a2dp_scalable_avdtpcodec; +extern const unsigned char a2dp_codec_scalable_elements[]; +bt_status_t a2dp_codec_scalable_init(int index); + +#if defined(__cplusplus) +} +#endif + +#endif /* __A2DP_CODEC_SCALABLE_H__ */ diff --git a/services/bt_app/a2dp_codecs/include/app_a2dp_codecs.h b/services/bt_app/a2dp_codecs/include/app_a2dp_codecs.h new file mode 100644 index 0000000..c3a8549 --- /dev/null +++ b/services/bt_app/a2dp_codecs/include/app_a2dp_codecs.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_A2DP_CODEC_H__ +#define __APP_A2DP_CODEC_H__ + +#include "a2dp_codec_sbc.h" +#include "a2dp_codec_aac.h" +#include "a2dp_codec_ldac.h" +#include "a2dp_codec_lhdc.h" +#include "a2dp_codec_opus.h" +#include "a2dp_codec_scalable.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +int a2dp_codec_init(void); +uint8_t a2dp_codec_confirm_stream_state(uint8_t index, uint8_t old_state, uint8_t new_state); + +#if defined(__cplusplus) +} +#endif + +#endif /* __APP_A2DP_CODEC_H__ */ \ No newline at end of file diff --git a/services/bt_app/a2dp_codecs/include/codec_lhdc.h b/services/bt_app/a2dp_codecs/include/codec_lhdc.h new file mode 100644 index 0000000..9fbf3d7 --- /dev/null +++ b/services/bt_app/a2dp_codecs/include/codec_lhdc.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __CODEC_LHDC_H__ +#define __CODEC_LHDC_H__ + +#define A2DP_LHDC_OCTET_NUMBER (9) +#define A2DP_LHDC_VENDOR_ID 0x0000053a +#if defined(A2DP_LHDC_V3) +#define A2DP_LHDC_CODEC_ID 0x4C33 +#else +#define A2DP_LHDC_CODEC_ID 0x4C32 +#endif +//To indicate Sampling Rate. +#define A2DP_LHDC_SR_96000 0x01 +#define A2DP_LHDC_SR_88200 0x02 +#define A2DP_LHDC_SR_48000 0x04 +#define A2DP_LHDC_SR_44100 0x08 +#define A2DP_LHDC_SR_DATA(X) (X & (A2DP_LHDC_SR_96000 | A2DP_LHDC_SR_88200 | A2DP_LHDC_SR_48000 | A2DP_LHDC_SR_44100)) + +//To indicate bits per sample. +#define A2DP_LHDC_FMT_24 0x10 +#define A2DP_LHDC_FMT_16 0x20 +#define A2DP_LHDC_FMT_DATA(X) (X & (A2DP_LHDC_FMT_24 | A2DP_LHDC_FMT_16)) + +#if defined(A2DP_LHDC_V3) +#define A2DP_LHDC_VERSION_NUM 0x01 +#else +#define A2DP_LHDC_VERSION_NUM 0x00 +#endif +#define A2DP_LHDC_MAX_SR_900 0x00 +#define A2DP_LHDC_MAX_SR_500 0x10 +#define A2DP_LHDC_MAX_SR_400 0x20 +#define A2DP_LHDC_MAX_SR_RESERVED 0x30 +#define A2DP_LHDC_LLC_ENABLE 0x40 + +#define A2DP_LHDC_COF_CSC_DISABLE 0x01 +#define A2DP_LHDC_COF_CSC 0x02 // +#define A2DP_LHDC_COF_CSC_PRE 0x04 +#define A2DP_LHDC_COF_CSC_RESERVED 0x08 +#define A2DP_LHDC_COF_DATA(X) (X & (A2DP_LHDC_COF_CSC_DISABLE | A2DP_LHDC_COF_CSC | A2DP_LHDC_COF_CSC_PRE)) + +typedef enum { + LHDC_CHANNEL_SPLIT_DISABLE = 0, + LHDC_CHANNEL_SPLIT, //For forwarding type TWS used + LHDC_CHANNEL_SPLIT_FROM_ENCODER, // Pre-split left/right frame at encode side. + LHDC_CHANNEL_SPLIT_INVALID, +} compressor_output_format_t; + +typedef struct { + uint32_t vendor_id; + uint16_t codec_id; + uint8_t bits; + uint8_t sample_rater; //uint:K + uint8_t version_num; + uint16_t max_sample_rate; //uint:K + bool llc_enable; //low latency control + compressor_output_format_t compress_output_format; +} lhdc_info_t; + +#ifdef __cplusplus +extern "C" { +#endif /* */ + + void lhdc_info_parse(uint8_t * elements, lhdc_info_t * info); + uint8_t a2dp_lhdc_get_sample_rate(uint8_t * elements); + +#ifdef __cplusplus +} +#endif + +#endif /* __CODEC_LHDC_H__ */ \ No newline at end of file diff --git a/services/bt_app/a2dp_codecs/ldac/a2dp_codec_ldac.cpp b/services/bt_app/a2dp_codecs/ldac/a2dp_codec_ldac.cpp new file mode 100644 index 0000000..3bdd5cc --- /dev/null +++ b/services/bt_app/a2dp_codecs/ldac/a2dp_codec_ldac.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "app.h" +#include "bt_drv.h" +#include "app_audio.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "hal_location.h" +#include "a2dp_api.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif + +#include "a2dp_api.h" +#include "avrcp_api.h" +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "tgt_hardware.h" +#include "bt_drv_interface.h" +#include "hci_api.h" + +#include "a2dp_codec_ldac.h" +#include "avdtp_api.h" + +extern struct BT_DEVICE_T app_bt_device; + +#if defined(A2DP_LDAC_ON) +static btif_avdtp_codec_t a2dp_ldac_avdtpcodec; + +const unsigned char a2dp_codec_ldac_elements[A2DP_LDAC_OCTET_NUMBER] = +{ + 0x2d, 0x01, 0x00, 0x00, //Vendor ID + 0xaa, 0x00, //Codec ID + (A2DP_LDAC_SR_96000|A2DP_LDAC_SR_88200|A2DP_LDAC_SR_48000 |A2DP_LDAC_SR_44100), +// (A2DP_LDAC_SR_48000 |A2DP_LDAC_SR_44100), + (A2DP_LDAC_CM_MONO|A2DP_LDAC_CM_DUAL|A2DP_LDAC_CM_STEREO), +}; + +bt_status_t a2dp_codec_ldac_init(int index) +{ + bt_status_t st; + + struct BT_DEVICE_T *bt_dev = &app_bt_device; + + a2dp_ldac_avdtpcodec.codecType = BTIF_AVDTP_CODEC_TYPE_NON_A2DP; + a2dp_ldac_avdtpcodec.discoverable = 1; + a2dp_ldac_avdtpcodec.elements = (U8 *)&a2dp_codec_ldac_elements; + a2dp_ldac_avdtpcodec.elemLen = sizeof(a2dp_codec_ldac_elements); + TRACE(1,"a2dp_ldac_avdtpcodec.elemLen = %d \n", a2dp_ldac_avdtpcodec.elemLen); + TRACE(7,"a2dp_ldac_avdtpcodec.elements->[0]=0x%02x,[1]=0x%02x,[2]=0x%02x,[3]=0x%02x,[4]=0x%02x,[5]=0x%02x,[6]=0x%02x,\n", \ + a2dp_ldac_avdtpcodec.elements[0], a2dp_ldac_avdtpcodec.elements[1], a2dp_ldac_avdtpcodec.elements[2], a2dp_ldac_avdtpcodec.elements[3], + a2dp_ldac_avdtpcodec.elements[4], a2dp_ldac_avdtpcodec.elements[5], a2dp_ldac_avdtpcodec.elements[6]); + TRACE(1,"a2dp_ldac_avdtpcodec.elements->[7]=0x%02x,\n", a2dp_ldac_avdtpcodec.elements[7]); + + st = btif_a2dp_register(bt_dev->a2dp_ldac_stream[index]->a2dp_stream, BTIF_A2DP_STREAM_TYPE_SINK, &a2dp_ldac_avdtpcodec, NULL, 3, index,a2dp_callback); + + return st; +} +#endif /* A2DP_LDAC_ON */ \ No newline at end of file diff --git a/services/bt_app/a2dp_codecs/lhdc/a2dp_codec_lhdc.cpp b/services/bt_app/a2dp_codecs/lhdc/a2dp_codec_lhdc.cpp new file mode 100644 index 0000000..6e5402b --- /dev/null +++ b/services/bt_app/a2dp_codecs/lhdc/a2dp_codec_lhdc.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "app.h" +#include "bt_drv.h" +#include "app_audio.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "hal_location.h" +#include "a2dp_api.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif + +#include "a2dp_api.h" +#include "avrcp_api.h" +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "tgt_hardware.h" +#include "bt_drv_interface.h" +#include "hci_api.h" + +#include "a2dp_codec_lhdc.h" +#include "avdtp_api.h" + +extern struct BT_DEVICE_T app_bt_device; + +#if defined(A2DP_LHDC_ON) +static btif_avdtp_codec_t a2dp_lhdc_avdtpcodec; + +#if 0 +const unsigned char a2dp_codec_lhdc_elements[A2DP_LHDC_OCTET_NUMBER] = { + 0x3A, 0x05, 0x00, 0x00, //Vendor ID + 0x4C, 0x48, //Codec ID + (A2DP_LHDC_SR_96000 | A2DP_LHDC_SR_48000 | A2DP_LHDC_SR_44100) | (A2DP_LHDC_FMT_16 | A2DP_LHDC_FMT_24), +}; +#else +//V2 + +const unsigned char a2dp_codec_lhdc_elements[A2DP_LHDC_OCTET_NUMBER] = { + 0x3A, 0x05, 0x00, 0x00, //Vendor ID +#if defined(A2DP_LHDC_V3) + 0x33, 0x4c, //Codec ID +#else + 0x32, 0x4c, //Codec ID +#endif + //A2DP_LHDC_SR_96000 | // 96K sample rate will audio drop, don't register + (A2DP_LHDC_SR_48000 | A2DP_LHDC_SR_44100) | (A2DP_LHDC_FMT_16 | A2DP_LHDC_FMT_24), + ( +#if defined(IBRT) + A2DP_LHDC_LLC_ENABLE | +#endif + A2DP_LHDC_MAX_SR_400 | A2DP_LHDC_VERSION_NUM), + (A2DP_LHDC_COF_CSC_DISABLE) +}; +#endif /* if 0 */ + +btif_avdtp_codec_t * app_a2dp_codec_get_lhdc_avdtp_codec() +{ + return (btif_avdtp_codec_t *)&a2dp_lhdc_avdtpcodec; +} + +bt_status_t a2dp_codec_lhdc_init(int index) +{ + bt_status_t st; + struct BT_DEVICE_T *bt_dev = &app_bt_device; + + a2dp_lhdc_avdtpcodec.codecType = BTIF_AVDTP_CODEC_TYPE_LHDC; + a2dp_lhdc_avdtpcodec.discoverable = 1; + a2dp_lhdc_avdtpcodec.elements = (U8 *)&a2dp_codec_lhdc_elements; + a2dp_lhdc_avdtpcodec.elemLen = sizeof(a2dp_codec_lhdc_elements); + { + btif_avdtp_codec_t *p = &a2dp_lhdc_avdtpcodec; + TRACE(1,"a2dp_lhdc_avdtpcodec.elemLen = %d \n", p->elemLen); + + TRACE(5,"a2dp_lhdc_avdtpcodec.elements->[0]=0x%02x,[1]=0x%02x,[2]=0x%02x,[3]=0x%02x,[4]=0x%02x\n", + p->elements[0], p->elements[1], p->elements[2], + p->elements[3], p->elements[4]); + + TRACE(4,"a2dp_lhdc_avdtpcodec.elements->[5]=0x%02x,[6]=0x%02x,[7]=0x%02x,[8]=0x%02x\n", + p->elements[5], p->elements[6], + p->elements[7], p->elements[8]); + } + + st = btif_a2dp_register(bt_dev->a2dp_lhdc_stream[index]->a2dp_stream, BTIF_A2DP_STREAM_TYPE_SINK, &a2dp_lhdc_avdtpcodec, NULL, 2, index, a2dp_callback); + + return st; +} +#endif /* A2DP_LHDC_ON */ diff --git a/services/bt_app/a2dp_codecs/lhdc/codec_lhdc.cpp b/services/bt_app/a2dp_codecs/lhdc/codec_lhdc.cpp new file mode 100644 index 0000000..f5588fe --- /dev/null +++ b/services/bt_app/a2dp_codecs/lhdc/codec_lhdc.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef A2DP_LHDC_ON + +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "bt_drv.h" +#include "app_audio.h" +#include "bt_drv_interface.h" +#include "app_bt_stream.h" +#include "nvrecord.h" +#include "nvrecord_env.h" + +#include "spp_api.h" +#include "hal_chipid.h" +#include "bt_drv_reg_op.h" +#include "besbt.h" +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "tgt_hardware.h" +#ifdef __TWS__ +#include "app_tws.h" +#include "app_bt.h" +#include "app_tws_if.h" +#endif + +#include "codec_lhdc.h" + +void lhdc_info_parse(uint8_t * elements, lhdc_info_t * info) +{ + info->vendor_id = (uint32_t) elements[0]; + info->vendor_id |= ((uint32_t) elements[1]) << 8; + info->vendor_id |= ((uint32_t) elements[2]) << 16; + info->vendor_id |= ((uint32_t) elements[3]) << 24; + + info->codec_id = (uint16_t) elements[4]; + info->codec_id |= ((uint16_t) elements[5]) << 8; + uint8_t config = elements[6]; + + if (info->vendor_id == A2DP_LHDC_VENDOR_ID && info->codec_id == A2DP_LHDC_CODEC_ID) { + + TRACE(2,"Vendor ID = 0x%08x, Codec ID = 0x%04x, LHDC Codec\n", info->vendor_id, info->codec_id); + switch (A2DP_LHDC_SR_DATA(config)) { + case A2DP_LHDC_SR_96000: + info->sample_rater = A2D_SBC_IE_SAMP_FREQ_96; + TRACE(1,"%s:CodecCfg sample_rate 96000\n", __func__); + break; + case A2DP_LHDC_SR_48000: + info->sample_rater = A2D_SBC_IE_SAMP_FREQ_48; + TRACE(1,"%s:CodecCfg sample_rate 48000\n", __func__); + break; + case A2DP_LHDC_SR_44100: + info->sample_rater = A2D_SBC_IE_SAMP_FREQ_44; + TRACE(1,"%s:CodecCfg sample_rate 44100\n", __func__); + break; + } + switch (A2DP_LHDC_FMT_DATA(config)) { + case A2DP_LHDC_FMT_16: + info->bits = 16; + TRACE(1,"%s:CodecCfg bits per sampe = 16", __func__); + break; + case A2DP_LHDC_FMT_24: + TRACE(1,"%s:CodecCfg bits per sampe = 24", __func__); + info->bits = 24; + break; + } + + config = elements[7]; + info->version_num = 0x0f & config; + TRACE(2,"%s:lhdc codec version num:%x\n", __func__, info->version_num); + info->max_sample_rate = 0x30 & config; + TRACE(2,"%s:lhdc codec max sample rate:%x\n", __func__, info->sample_rater); + + info->llc_enable = 0x40 & config; + TRACE(2,"%s:lhdc codec llc enable:%x \n", __func__, info->llc_enable); + + config = elements[8]; + switch (A2DP_LHDC_COF_DATA(config)) { + case A2DP_LHDC_COF_CSC_DISABLE: + info->compress_output_format = LHDC_CHANNEL_SPLIT_DISABLE; + TRACE(1,"%s:compress_output_format: LHDC_COF_CSC_DISABLE", __func__); + break; + case A2DP_LHDC_COF_CSC: + TRACE(1,"%s:compress_output_format: LHDC_COF_CSC", __func__); + info->compress_output_format = LHDC_CHANNEL_SPLIT; + break; + case A2DP_LHDC_COF_CSC_PRE: + TRACE(1,"%s:compress_output_format: LHDC_COF_CSC_PRE", __func__); + info->compress_output_format = LHDC_CHANNEL_SPLIT_FROM_ENCODER; + break; + + } + + } +} + +uint8_t a2dp_lhdc_get_sample_rate(uint8_t * elements) +{ + uint32_t vendor_id = (uint32_t) elements[0]; + vendor_id |= ((uint32_t) elements[1]) << 8; + vendor_id |= ((uint32_t) elements[2]) << 16; + vendor_id |= ((uint32_t) elements[3]) << 24; + uint16_t codec_id = (uint16_t) elements[4]; + codec_id |= ((uint16_t) elements[5]) << 8; + + uint8_t config = elements[6]; + if (vendor_id == A2DP_LHDC_VENDOR_ID && codec_id == A2DP_LHDC_CODEC_ID) { + switch (A2DP_LHDC_SR_DATA(config)) { + case A2DP_LHDC_SR_96000: + return A2D_SBC_IE_SAMP_FREQ_96; + case A2DP_LHDC_SR_48000: + return A2D_SBC_IE_SAMP_FREQ_48; + case A2DP_LHDC_SR_44100: + return A2D_SBC_IE_SAMP_FREQ_44; + } + } + return 0; +} + +#endif diff --git a/services/bt_app/a2dp_codecs/opus/a2dp_codec_opus.cpp b/services/bt_app/a2dp_codecs/opus/a2dp_codec_opus.cpp new file mode 100644 index 0000000..6f0572f --- /dev/null +++ b/services/bt_app/a2dp_codecs/opus/a2dp_codec_opus.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "app.h" +#include "bt_drv.h" +#include "app_audio.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "hal_location.h" +#include "a2dp_api.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif + +#include "a2dp_api.h" +#include "avrcp_api.h" +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "tgt_hardware.h" +#include "bt_drv_interface.h" +#include "hci_api.h" + +#include "a2dp_codec_opus.h" +#include "avdtp_api.h" + +extern struct BT_DEVICE_T app_bt_device; + +#if defined(MASTER_USE_OPUS) || defined(ALL_USE_OPUS) +static btif_avdtp_codec_t a2dp_opus_avdtpcodec; + +const unsigned char a2dp_codec_opus_elements[] = { + A2D_SBC_IE_SAMP_FREQ_48 | A2D_SBC_IE_SAMP_FREQ_44 | A2D_SBC_IE_CH_MD_STEREO | A2D_SBC_IE_CH_MD_JOINT, + A2D_SBC_IE_BLOCKS_16 | A2D_SBC_IE_BLOCKS_12 | A2D_SBC_IE_SUBBAND_8 | A2D_SBC_IE_ALLOC_MD_L, + A2D_SBC_IE_MIN_BITPOOL, + BTA_AV_CO_SBC_MAX_BITPOOL +}; + +bt_status_t a2dp_codec_opus_init(struct BT_DEVICE_T *bt_dev, int index) +{ + return BT_STS_SUCCESS; +} + +#endif /* MASTER_USE_OPUS || ALL_USE_OPUS */ \ No newline at end of file diff --git a/services/bt_app/a2dp_codecs/sbc/a2dp_codec_sbc.cpp b/services/bt_app/a2dp_codecs/sbc/a2dp_codec_sbc.cpp new file mode 100644 index 0000000..fe4a752 --- /dev/null +++ b/services/bt_app/a2dp_codecs/sbc/a2dp_codec_sbc.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "app.h" +#include "bt_drv.h" +#include "app_audio.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "hal_location.h" +#include "a2dp_api.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif + +#include "a2dp_api.h" +#include "avrcp_api.h" +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "tgt_hardware.h" +#include "bt_drv_interface.h" +#include "hci_api.h" + +#include "a2dp_codec_sbc.h" +#include "avdtp_api.h" + +extern struct BT_DEVICE_T app_bt_device; + +#ifdef __A2DP_AVDTP_CP__ +btif_avdtp_content_prot_t a2dp_avdtpCp[BT_DEVICE_NUM]; +U8 a2dp_avdtpCp_securityData[BT_DEVICE_NUM][BTIF_AVDTP_MAX_CP_VALUE_SIZE] = {}; +#endif /* __A2DP_AVDTP_CP__ */ + +btif_avdtp_codec_t a2dp_avdtpcodec; + +const unsigned char a2dp_codec_elements[] = { + A2D_SBC_IE_SAMP_FREQ_48 | A2D_SBC_IE_SAMP_FREQ_44 | A2D_SBC_IE_CH_MD_MONO | A2D_SBC_IE_CH_MD_STEREO | A2D_SBC_IE_CH_MD_JOINT | A2D_SBC_IE_CH_MD_DUAL, + A2D_SBC_IE_BLOCKS_16 | A2D_SBC_IE_BLOCKS_12 | A2D_SBC_IE_BLOCKS_8 |A2D_SBC_IE_BLOCKS_4 | A2D_SBC_IE_SUBBAND_8 | A2D_SBC_IE_ALLOC_MD_L | A2D_SBC_IE_ALLOC_MD_S, + A2D_SBC_IE_MIN_BITPOOL, + BTA_AV_CO_SBC_MAX_BITPOOL +}; + +bt_status_t a2dp_codec_sbc_init(int index) +{ + struct BT_DEVICE_T *bt_dev = &app_bt_device; + + bt_status_t st; +#ifdef __A2DP_AVDTP_CP__ + a2dp_avdtpCp[index].cpType = BTIF_AVDTP_CP_TYPE_SCMS_T; + a2dp_avdtpCp[index].data = (U8 *)&a2dp_avdtpCp_securityData[index][0]; + a2dp_avdtpCp[index].dataLen = 0; +#endif /* __A2DP_AVDTP_CP__ */ + + a2dp_avdtpcodec.codecType = BTIF_AVDTP_CODEC_TYPE_SBC; + a2dp_avdtpcodec.discoverable = 1; + a2dp_avdtpcodec.elements = (U8 *)&a2dp_codec_elements; + a2dp_avdtpcodec.elemLen = 4; + +#ifdef __A2DP_AVDTP_CP__ + st = btif_a2dp_register(bt_dev->a2dp_stream[index]->a2dp_stream, BTIF_A2DP_STREAM_TYPE_SINK, &a2dp_avdtpcodec, &a2dp_avdtpCp[index], 0,index,a2dp_callback); + btif_a2dp_add_content_protection(bt_dev->a2dp_stream[index]->a2dp_stream, &a2dp_avdtpCp[index]); +#else + st = btif_a2dp_register(bt_dev->a2dp_stream[index]->a2dp_stream, BTIF_A2DP_STREAM_TYPE_SINK, &a2dp_avdtpcodec, NULL, 0,index, a2dp_callback); +#endif /* __A2DP_AVDTP_CP__ */ + + return st; +} \ No newline at end of file diff --git a/services/bt_app/a2dp_codecs/scalable/a2dp_codec_scalable.cpp b/services/bt_app/a2dp_codecs/scalable/a2dp_codec_scalable.cpp new file mode 100644 index 0000000..eb1b528 --- /dev/null +++ b/services/bt_app/a2dp_codecs/scalable/a2dp_codec_scalable.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "app.h" +#include "bt_drv.h" +#include "app_audio.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "hal_location.h" +#include "a2dp_api.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif + +#include "a2dp_api.h" +#include "avrcp_api.h" +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "tgt_hardware.h" +#include "bt_drv_interface.h" +#include "hci_api.h" + +#include "a2dp_codec_scalable.h" +#include "avdtp_api.h" + +extern struct BT_DEVICE_T app_bt_device; + +#if defined(A2DP_SCALABLE_ON) +btif_avdtp_codec_t a2dp_scalable_avdtpcodec; + +//Vendor Specific value (8bit) : 0x78 (not support UHQ) 0xF8  (support UHQ) +// - bit 7 : 96kHz   sampling frequency supported +// - bit 6 : 32kHz   sampling frequency supported +// - bit 5 : 44.1kHz sampling frequency supported +// - bit 4 : 48kHz   sampling frequency supported +// - bit 3 : high quality supported  +// - bit 2 : additional information (current 0) +// - bit 1 : additional information (current 0) +// - bit 0 : additional information (current 0) +//<1byte Vendor Specific values for Scalable codec>  +const unsigned char a2dp_codec_scalable_elements[A2DP_SCALABLE_OCTET_NUMBER] = +{ + 0x75,0x0,0x0,0x0, // vendor id + 0x03,0x01, // vendor specific codec id +#if defined(A2DP_SCALABLE_UHQ_SUPPORT) + 0xf8, // vendor specific value +#else + 0x78, // vendor specific value +#endif +}; + +bt_status_t a2dp_codec_scalable_init(int index) +{ + bt_status_t st; + + struct BT_DEVICE_T *bt_dev = &app_bt_device; + + a2dp_scalable_avdtpcodec.codecType = BTIF_AVDTP_CODEC_TYPE_NON_A2DP; + a2dp_scalable_avdtpcodec.discoverable = 1; + a2dp_scalable_avdtpcodec.elements = (U8 *)&a2dp_codec_scalable_elements; + a2dp_scalable_avdtpcodec.elemLen = sizeof(a2dp_codec_scalable_elements); + + st = btif_a2dp_register(bt_dev->a2dp_scalable_stream[index]->a2dp_stream, BTIF_A2DP_STREAM_TYPE_SINK, &a2dp_scalable_avdtpcodec, NULL, 4,index,a2dp_callback); + + return st; +} +#endif /* A2DP_SCALABLE_ON */ diff --git a/services/bt_app/app_a2dp.cpp b/services/bt_app/app_a2dp.cpp new file mode 100644 index 0000000..5b53af8 --- /dev/null +++ b/services/bt_app/app_a2dp.cpp @@ -0,0 +1,4126 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "app.h" +#include "bt_drv.h" +#include "app_audio.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "hal_location.h" +#include "a2dp_api.h" +#include "app_a2dp.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif +#if defined(A2DP_LHDC_ON) +//#include "../liblhdc-dec/lhdcUtil.h" +#include "lhdcUtil.h" +#endif + +#if defined(A2DP_LDAC_ON) +#include"ldacBT.h" +#endif + +#include "a2dp_api.h" +#include "avrcp_api.h" +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "tgt_hardware.h" +#include "bt_drv_interface.h" +#include "hci_api.h" +#include "hal_bootmode.h" +#include "bt_drv_reg_op.h" + +#ifdef BT_USB_AUDIO_DUAL_MODE +#include "btusb_audio.h" +#endif + +#if defined(__BTMAP_ENABLE__) +#include "app_btmap_sms.h" +#endif + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +#include "app_a2dp_source.h" +extern enum AUD_SAMPRATE_T bt_parse_sbc_sample_rate(uint8_t sbc_samp_rate); +#endif + +#ifdef __THIRDPARTY +#include "app_thirdparty.h" +#endif + +#ifdef VOICE_DATAPATH +#include "app_voicepath.h" +#endif + +#ifdef __AI_VOICE__ +#include "ai_thread.h" +#endif + +#define _FILE_TAG_ "A2DP" +#include "color_log.h" +#include "app_bt_func.h" +#include "os_api.h" + +#if (A2DP_DECODER_VER >= 2) +#include "a2dp_decoder.h" +#endif + +#if defined(IBRT) +#include "app_ibrt_if.h" +#include "app_tws_ibrt_cmd_sync_a2dp_status.h" +#endif + +#ifdef BISTO_ENABLED +#include "gsound_custom_bt.h" +#endif + +#define APP_A2DP_STRM_FLAG_QUERY_CODEC 0x08 + +#define APP_A2DP__DEBUG + +#ifdef APP_A2DP__DEBUG +#define APP_A2DP_TRACE(str, ...) TRACE(str, ##__VA_ARGS__) +#else +#define APP_A2DP_TRACE(str, ...) +#endif + +uint8_t current_a2dp_non_type = 0; + +typedef uint8_t tx_done_flag; + +#define TX_DONE_FLAG_INIT ((uint8_t)0) +#define TX_DONE_FLAG_SUCCESS ((uint8_t)1) +#define TX_DONE_FLAG_FAIL ((uint8_t)2) +#define TX_DONE_FLAG_TXING ((uint8_t)3) +tx_done_flag vol_ctrl_done_flag[BT_DEVICE_NUM] = {TX_DONE_FLAG_INIT}; + +int a2dp_volume_get(enum BT_DEVICE_ID_T id); + +#ifdef GFPS_ENABLED +extern "C" void app_exit_fastpairing_mode(void); +#endif +extern int app_bt_stream_volumeset(int8_t vol); + +static void app_AVRCP_sendCustomCmdRsp(uint8_t device_id, btif_avrcp_channel_t *chnl, uint8_t isAccept, uint8_t transId); +static void app_AVRCP_CustomCmd_Received(uint8_t* ptrData, uint32_t len); + +void get_value1_pos(U8 mask,U8 *start_pos, U8 *end_pos) +{ + U8 num = 0; + + for(U8 i=0;i<8;i++){ + if((0x01<avrcp_channel_handle) == rem_dev) + break; + } + } + + if (i == BT_DEVICE_NUM) { + TRACE(2,"%s:no_proper_avrcp_channel_to_save,rem_dev=%p,error!", __func__, rem_dev); + return 0; + } + + buf[offset] = i; + ++offset; + + return offset; +} + +uint32_t app_avrcp_restore_ctxs(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len) +{ + return 0; +} +#endif /* ENHANCED_STACK */ +#endif + +bool is_bd_addr_valid(bt_bdaddr_t * addr) +{ + uint8_t addr_empty[6]; + memset(addr_empty, 0, sizeof(addr_empty)); + if (memcmp(addr,addr_empty,6)){ + return TRUE; + }else{ + return FALSE; + } + +} + +static void app_avrcp_connect_timeout_timer_handler(uint32_t deviceId) +{ + TRACE(2,"app_avrcp_connect_timeout_handler a2dp state=%d,avrcp state=%d", app_bt_device.a2dp_state[deviceId], + btif_get_avrcp_state(app_bt_device.avrcp_channel[deviceId])); + if((!app_is_disconnecting_all_bt_connections()) && + app_bt_device.a2dp_state[deviceId] && + (btif_get_avrcp_state(app_bt_device.avrcp_channel[deviceId]) != BTIF_AVRCP_STATE_CONNECTED)) + { + btif_remote_device_t * rdev = btif_a2dp_get_stream_conn_remDev(app_bt_device.a2dp_connected_stream[deviceId]); + if(rdev){ + bt_bdaddr_t * bd_addr = btif_me_get_remote_device_bdaddr(rdev); + if ( is_bd_addr_valid(bd_addr)){ + btif_avrcp_connect(app_bt_device.avrcp_channel[deviceId], bd_addr); + }else{ + TRACE(1,"%s bd_addr is empty ",__func__); + } + }else{ + TRACE(1,"%s rdev is NULL ", __func__); + } + } +} + +void app_avrcp_connect_timeout_timer_callback(void const *param) +{ + app_bt_start_custom_function_in_bt_thread((uint32_t)param ,0, + (uint32_t)app_avrcp_connect_timeout_timer_handler); +} + +#define MAX_AVRCP_CONNECT_TRY_TIME 3 +osTimerDef (APP_AVRCP_CONNECT0, app_avrcp_connect_timeout_timer_callback); +osTimerId POSSIBLY_UNUSED app_avrcp_connect_timer0 = NULL; +static uint8_t app_avrcp_connect_try_times[BT_DEVICE_NUM]; +#ifdef __BT_ONE_BRING_TWO__ +osTimerDef (APP_AVRCP_CONNECT1, app_avrcp_connect_timeout_timer_callback); +osTimerId POSSIBLY_UNUSED app_avrcp_connect_timer1 = NULL; +#endif + + +#define MAX_GET_CAPABILITIES_RETRY_TIME (3) +#define MAX_GET_CAPABILITIES_RETRY_INTERVAL (500) + +typedef struct { + btif_avrcp_chnl_handle_t chnl; + osTimerId delay_timer; + int8_t retry_cnt; +}app_avrcp_get_capabilities_ctx_t; + +void app_avrcp_get_capabilities_retry_callback(void const *param); +osTimerDef (APP_AVRCP_GET_CAPABILITIES0, app_avrcp_get_capabilities_retry_callback); +osTimerId POSSIBLY_UNUSED app_avrcp_get_capabilities_timer0 = NULL; +app_avrcp_get_capabilities_ctx_t app_avrcp_get_capabilities_ctx0; + +#ifdef __BT_ONE_BRING_TWO__ +osTimerDef (APP_AVRCP_GET_CAPABILITIES1, app_avrcp_get_capabilities_retry_callback); +osTimerId POSSIBLY_UNUSED app_avrcp_get_capabilities_timer1 = NULL; +app_avrcp_get_capabilities_ctx_t app_avrcp_get_capabilities_ctx1; +#endif + +void app_avrcp_get_capabilities_start(btif_avrcp_chnl_handle_t chnl) +{ +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T device_id = (chnl == app_bt_device.avrcp_channel[0]->avrcp_channel_handle) ? BT_DEVICE_ID_1 : BT_DEVICE_ID_2; +#else + enum BT_DEVICE_ID_T device_id = BT_DEVICE_ID_1; +#endif + btif_avrcp_channel_t *channel = btif_get_avrcp_channel(chnl); + + if (btif_get_avrcp_version(channel) == BTIF_AVRCP_VERSION_UNKNOWN) + { + APP_A2DP_TRACE(0,"::AVRCP_GET_CAPABILITY DELAY\n"); + switch (device_id) + { +#ifdef __BT_ONE_BRING_TWO__ + case BT_DEVICE_ID_2: + app_avrcp_get_capabilities_ctx1.chnl = chnl; + app_avrcp_get_capabilities_ctx1.retry_cnt = MAX_GET_CAPABILITIES_RETRY_TIME; + osTimerStart(app_avrcp_get_capabilities_ctx1.delay_timer, MAX_GET_CAPABILITIES_RETRY_INTERVAL); + break; +#endif + case BT_DEVICE_ID_1: + default: + app_avrcp_get_capabilities_ctx0.chnl = chnl; + app_avrcp_get_capabilities_ctx0.retry_cnt = MAX_GET_CAPABILITIES_RETRY_TIME; + osTimerStart(app_avrcp_get_capabilities_ctx0.delay_timer, MAX_GET_CAPABILITIES_RETRY_INTERVAL); + break; + } + } + else + { + if(btif_get_avrcp_version(channel) >= BTIF_AVRCP_VERSION_1_3) + { + APP_A2DP_TRACE(0,"::AVRCP_GET_CAPABILITY\n"); + if (app_bt_device.avrcp_cmd1[device_id] == NULL){ + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_cmd1[device_id]); + } + btif_avrcp_ct_get_capabilities(channel, app_bt_device.avrcp_cmd1[device_id],BTIF_AVRCP_CAPABILITY_EVENTS_SUPPORTED); + } + } + +} + +void app_avrcp_get_capabilities_retry_callback(void const *param) +{ + app_avrcp_get_capabilities_ctx_t *get_capabilities_ctx = (app_avrcp_get_capabilities_ctx_t *)param; + enum BT_DEVICE_ID_T device_id = BT_DEVICE_ID_1; + btif_avrcp_channel_t *channel = NULL; + +#ifdef __BT_ONE_BRING_TWO__ + device_id = (get_capabilities_ctx->chnl == app_bt_device.avrcp_channel[0]->avrcp_channel_handle) ? BT_DEVICE_ID_1 : BT_DEVICE_ID_2; +#else + device_id = BT_DEVICE_ID_1; +#endif + channel = btif_get_avrcp_channel(get_capabilities_ctx->chnl); + + get_capabilities_ctx->retry_cnt--; + + if (btif_get_avrcp_state(channel) != BTIF_AVRCP_STATE_CONNECTED) + { + APP_A2DP_TRACE(0,"::AVRCP_GET_CAPABILITY CONTINUE disconnect cancel"); + return; + } + + if (get_capabilities_ctx->retry_cnt <= 0) + { + APP_A2DP_TRACE(0,"::AVRCP_GET_CAPABILITY CONTINUE limit cancel"); + return; + } + + if (app_bt_device.avrcp_cmd1[device_id] == NULL) + { + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_cmd1[device_id]); + } + + if (btif_get_avrcp_version(channel) == BTIF_AVRCP_VERSION_UNKNOWN) + { + APP_A2DP_TRACE(1,"::AVRCP_GET_CAPABILITY CONTINUE cnt:%d\n", get_capabilities_ctx->retry_cnt); + switch (device_id) + { +#ifdef __BT_ONE_BRING_TWO__ + case BT_DEVICE_ID_2: + osTimerStart(app_avrcp_get_capabilities_ctx1.delay_timer, MAX_GET_CAPABILITIES_RETRY_INTERVAL); + break; +#endif + case BT_DEVICE_ID_1: + default: + osTimerStart(app_avrcp_get_capabilities_ctx0.delay_timer, MAX_GET_CAPABILITIES_RETRY_INTERVAL); + break; + } + } + else + { + if(btif_get_avrcp_version(channel) >= BTIF_AVRCP_VERSION_1_3) + { + APP_A2DP_TRACE(0,"::AVRCP_GET_CAPABILITY\n"); + if (app_bt_device.avrcp_cmd1[device_id] == NULL){ + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_cmd1[device_id]); + } + btif_avrcp_ct_get_capabilities(channel, app_bt_device.avrcp_cmd1[device_id],BTIF_AVRCP_CAPABILITY_EVENTS_SUPPORTED); + } + } +} + + +#ifdef BTIF_AVRCP_ADVANCED_CONTROLLER + +void a2dp_init(void) +{ + btif_a2dp_init(); + for(int i =0; i< BT_DEVICE_NUM; i++ ){ + app_bt_device.a2dp_stream[i] = btif_a2dp_alloc_stream(); +#if defined(A2DP_LHDC_ON) + app_bt_device.a2dp_lhdc_stream[i] = btif_a2dp_alloc_stream(); +#endif +#if defined(A2DP_SCALABLE_ON) + app_bt_device.a2dp_scalable_stream[i] = btif_a2dp_alloc_stream(); +#endif +#if defined(ALL_USE_OPUS) + app_bt_device.a2dp_aac_stream[i] = btif_a2dp_alloc_stream(); +#endif +#if defined(A2DP_AAC_ON) + app_bt_device.a2dp_aac_stream[i] = btif_a2dp_alloc_stream(); +#endif +#if defined(A2DP_LDAC_ON) + app_bt_device.a2dp_ldac_stream[i] = btif_a2dp_alloc_stream(); +#endif + } + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + struct nvrecord_env_t *nvrecord_env; + nv_record_env_get(&nvrecord_env); + app_bt_device.src_or_snk=nvrecord_env->src_snk_flag.src_snk_mode; + app_bt_device.src_or_snk=BT_DEVICE_SRC; +// app_bt_device.src_or_snk=BT_DEVICE_SNK; + TRACE(1,"src_or_snk:%d\n",app_bt_device.src_or_snk); + app_bt_device.input_onoff=0; +#endif + + for(uint8_t i=0; iaddress, + bd_addr_2->address, BTIF_BD_ADDR_SIZE) == 0); +} + +bool a2dp_id_from_bdaddr(bt_bdaddr_t *bd_addr, uint8_t *id) +{ + bt_bdaddr_t curr_addr = {0}; + uint8_t curr_id = BT_DEVICE_NUM; + + if (app_bt_is_device_connected(BT_DEVICE_ID_1)) + { + a2dp_bdaddr_from_id(BT_DEVICE_ID_1, &curr_addr); + if(a2dp_bdaddr_cmp(&curr_addr, bd_addr)) { + curr_id = BT_DEVICE_ID_1; + } + } + +#ifdef __BT_ONE_BRING_TWO__ + if (app_bt_is_device_connected(BT_DEVICE_ID_2)) + { + a2dp_bdaddr_from_id(BT_DEVICE_ID_2, &curr_addr); + if(a2dp_bdaddr_cmp(&curr_addr, bd_addr)) { + curr_id = BT_DEVICE_ID_2; + } + } +#endif + if(id) { + *id = curr_id; + } + return (curr_id < BT_DEVICE_NUM); +} + +#ifdef __BT_ONE_BRING_TWO__ +#define APP_BT_PAUSE_MEDIA_PLAYER_DELAY 300 +osTimerId app_bt_pause_media_player_delay_timer_id = NULL; +extern uint8_t avrcp_palyback_status[BT_DEVICE_NUM]; +static uint8_t deviceIdPendingForMediaPlayerPause = 0; +static uint8_t deviceIdInMediaPlayHoldState = BT_DEVICE_NUM; +static void app_bt_pause_media_player_delay_timer_handler(void const *n); +osTimerDef (APP_BT_PAUSE_MEDIA_PLAYER_DELAY_TIMER, app_bt_pause_media_player_delay_timer_handler); + +static void app_bt_pause_media_player_delay_timer_handler(void const *n) +{ + app_bt_start_custom_function_in_bt_thread(deviceIdPendingForMediaPlayerPause, 0, (uint32_t)app_bt_pause_music_player); +} + +void app_bt_pause_media_player_again(uint8_t deviceId) +{ + if (NULL == app_bt_pause_media_player_delay_timer_id) + { + app_bt_pause_media_player_delay_timer_id = osTimerCreate( + osTimer(APP_BT_PAUSE_MEDIA_PLAYER_DELAY_TIMER), osTimerOnce, NULL); + } + + TRACE(1,"The media player on device %d is resumed before it's allowed, so pause it again.", + deviceId); + + deviceIdPendingForMediaPlayerPause = deviceId; + osTimerStart(app_bt_pause_media_player_delay_timer_id, + APP_BT_PAUSE_MEDIA_PLAYER_DELAY); +} + +bool app_bt_is_to_resume_music_player(uint8_t deviceId) +{ + return (deviceIdInMediaPlayHoldState == deviceId); +} + +void app_bt_reset_music_player_resume_state(void) +{ + deviceIdInMediaPlayHoldState = BT_DEVICE_NUM; +} + +void app_bt_set_music_player_resume_device(uint8_t deviceId) +{ + deviceIdInMediaPlayHoldState = deviceId; +} + +bool app_bt_is_music_player_working(uint8_t deviceId) +{ + TRACE(3,"device %d a2dp streaming %d playback state %d", + deviceId, app_bt_is_a2dp_streaming(deviceId), + avrcp_palyback_status[deviceId]); + return (app_bt_is_a2dp_streaming(deviceId) && + avrcp_palyback_status[deviceId]); +} + +void app_bt_suspend_a2dp_streaming(uint8_t deviceId) +{ + if (!app_bt_is_a2dp_streaming(deviceId)) + { + return; + } + + TRACE(1,"Suspend a2dp streaming of device %d", deviceId); + btif_a2dp_suspend_stream(app_bt_device.a2dp_connected_stream[deviceId]); +} + + + +bool app_bt_pause_music_player(uint8_t deviceId) +{ + if (!app_bt_is_music_player_working(deviceId)) + { + return false; + } + + btif_avrcp_channel_t *avrcp_channel_tmp = + app_bt_device.avrcp_channel[deviceId]; + + TRACE(1,"Pause music player of device %d", deviceId); + app_bt_suspend_a2dp_streaming(deviceId); + + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_PAUSE,TRUE); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_PAUSE,FALSE); + + app_bt_device.a2dp_play_pause_flag = 0; + + return true; +} + +void app_bt_resume_music_player(uint8_t deviceId) +{ + app_bt_reset_music_player_resume_state(); + + if (app_bt_is_music_player_working(deviceId)) + { + return; + } + + btif_avrcp_channel_t *avrcp_channel_tmp = + app_bt_device.avrcp_channel[deviceId]; + + TRACE(1,"Resume music player of device %d", deviceId); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_PLAY,TRUE); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_PLAY,FALSE); + app_bt_device.a2dp_play_pause_flag = 1; +} +#endif + +bool app_bt_is_a2dp_streaming(uint8_t deviceId) +{ + return app_bt_device.a2dp_streamming[deviceId]; +} + +FRAM_TEXT_LOC uint8_t bt_sbc_player_get_codec_type(void) +{ + enum BT_DEVICE_ID_T st_id = app_bt_device.curr_a2dp_stream_id; + if(app_bt_device.a2dp_connected_stream[st_id]) + return btif_a2dp_get_stream_codec(app_bt_device.a2dp_connected_stream[st_id])->codecType; + else + return BTIF_AVDTP_CODEC_TYPE_SBC; +} + +FRAM_TEXT_LOC uint8_t bt_sbc_player_get_sample_bit(void) { + enum BT_DEVICE_ID_T st_id = app_bt_device.curr_a2dp_stream_id; + + return app_bt_device.sample_bit[st_id]; +} + + +#ifdef __BT_ONE_BRING_TWO__ + +uint8_t avrcp_palyback_status[BT_DEVICE_NUM] = {0}; +static struct BT_DEVICE_ID_DIFF avrcp_bond_a2dp_stream; +static uint8_t avrcp_bonding_a2dp_id[BT_DEVICE_NUM] = {BT_DEVICE_NUM,BT_DEVICE_NUM}; +static POSSIBLY_UNUSED uint8_t a2dp_get_cur_stream_id(void) +{ + return (uint8_t)app_bt_device.curr_a2dp_stream_id; +} +static uint8_t avrcp_find_a2dp_stream_id(btif_avrcp_chnl_handle_t chnl) +{ + btif_remote_device_t * p_avrcp_remDev = btif_avrcp_get_remote_device(chnl); + uint8_t i =0; + btif_remote_device_t * p_a2dp_remDev = 0; + TRACE(1,"avrcp_remDev = %p",p_avrcp_remDev); + for(i = 0; iavrcp_channel_handle) + == btif_a2dp_get_remote_device(ptrA2dpStream)) + { + avrcp_bond_a2dp_stream.id = (enum BT_DEVICE_ID_T)a2dpDevIndex; + avrcp_bonding_a2dp_id[avrcpIndex] = a2dpDevIndex; + break; + } + } +} + +#endif + +#ifdef __BT_ONE_BRING_TWO__ +void a2dp_update_music_link(void); +#endif + +static void a2dp_set_cur_stream(enum BT_DEVICE_ID_T id) +{ + TRACE(1,"Set current a2dp stream as %d", id); + app_bt_device.curr_a2dp_stream_id = id; + if(app_bt_device.a2dp_connected_stream[id]) + { + btif_remote_device_t* activeRem = + btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[id]); + if(activeRem) + app_bt_device.current_a2dp_conhdl= btif_me_get_remote_device_hci_handle(activeRem); + else + app_bt_device.current_a2dp_conhdl= 0xffff; + + } + else + { + app_bt_device.current_a2dp_conhdl= 0xffff; + } + +#ifdef __BT_ONE_BRING_TWO__ + a2dp_update_music_link(); +#endif +} + +static uint8_t a2dp_skip_frame_cnt = 0; +enum BT_DEVICE_ID_T a2dp_get_cur_stream(void) +{ + return app_bt_device.curr_a2dp_stream_id; +} + +uint16_t a2dp_Get_curr_a2dp_conhdl(void) +{ + return app_bt_device.current_a2dp_conhdl; +} + +void a2dp_get_curStream_remDev(btif_remote_device_t **p_remDev) +{ + enum BT_DEVICE_ID_T id = a2dp_get_cur_stream(); + uint8_t i =0; + if(id != BT_DEVICE_NUM) + i = id; + *p_remDev = btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[i]); + //TRACE(1,"temp_addr = %x",*p_remDev); +} +uint8_t app_a2dp_run_skip_frame(void) +{ + if(a2dp_skip_frame_cnt > 0){ + a2dp_skip_frame_cnt--; + return 1; + } + a2dp_skip_frame_cnt = 0; + return 0; +} +void app_a2dp_set_skip_frame(uint8_t frames) +{ + a2dp_skip_frame_cnt = frames; +} +#define SWITCH_MUTE_FRAMES_CNT 65 +void app_a2dp_hold_mute() +{ + TRACE(0,"mute a2dp streaming."); + a2dp_skip_frame_cnt = SWITCH_MUTE_FRAMES_CNT; +} +void app_a2dp_unhold_mute() +{ + a2dp_skip_frame_cnt = 0; +} + +avrcp_advanced_pdu_t * avrcp_get_play_status_cmd[BT_DEVICE_NUM] = {NULL}; + +void avrcp_get_current_media_status(enum BT_DEVICE_ID_T device_id) +{ + if(app_bt_device.avrcp_state[device_id] == 0) + return; + if (NULL == avrcp_get_play_status_cmd[device_id]) + { + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&avrcp_get_play_status_cmd[device_id]); + } + btif_avrcp_ct_get_play_status(app_bt_device.avrcp_channel[device_id], avrcp_get_play_status_cmd[device_id]); +} + +void btapp_a2dp_suspend_music(enum BT_DEVICE_ID_T stream_id); +uint8_t a2dp_get_streaming_id(void); +void avrcp_set_media_status(uint8_t status); + +#ifdef USER_REBOOT_PLAY_MUSIC_AUTO +extern bool a2dp_need_to_play; +#endif +extern "C" void avrcp_callback_CT(btif_avrcp_chnl_handle_t chnl, const avrcp_callback_parms_t* parms) +{ + btif_avrcp_channel_t * channel = btif_get_avrcp_channel( chnl); + btif_avctp_event_t event = btif_avrcp_get_callback_event( parms); + APP_A2DP_TRACE(3,"%s : chnl %p, Parms %p\n", __func__,chnl, parms); + APP_A2DP_TRACE(2,"::%s Parms->event %d\n", __func__, btif_avrcp_get_callback_event(parms)); +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T device_id = (chnl == app_bt_device.avrcp_channel[0]->avrcp_channel_handle) ? BT_DEVICE_ID_1 : BT_DEVICE_ID_2; + enum BT_DEVICE_ID_T device_id_other = (device_id==BT_DEVICE_ID_1)?(BT_DEVICE_ID_2):(BT_DEVICE_ID_1); + APP_A2DP_TRACE(1,"device_id = %d",device_id); +#else + enum BT_DEVICE_ID_T device_id = BT_DEVICE_ID_1; +#endif + switch(event) + { + case BTIF_AVRCP_EVENT_CONNECT_IND: +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("Connect ok."); +#endif + APP_A2DP_TRACE(1,"::avrcp_callback_CT AVRCP_EVENT_CONNECT_IND %d\n", btif_avrcp_get_callback_event(parms)); + btif_avrcp_connect_rsp (channel, 1); + + break; + case BTIF_AVRCP_EVENT_CONNECT: +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("Connect ok."); +#endif + app_bt_device.avrcp_state[device_id] = 1; + app_avrcp_get_capabilities_start(chnl); + +#ifdef AVRCP_TRACK_CHANGED + if (app_bt_device.avrcp_cmd2[device_id] == NULL) + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_cmd2[device_id]); + btif_avrcp_ct_register_notification(channel,app_bt_device.avrcp_cmd2[device_id],BTIF_AVRCP_ENABLE_TRACK_CHANGED,0); +#endif +#ifdef __AVRCP_TRACK_PLAY_STATUS__ + TRACE(0,"::REG AVRCP_EID_MEDIA_STATUS_CHANGED\n"); + if (app_bt_device.avrcp_cmd1[device_id] == NULL) + app_a2dp_avrcpadvancedpdu_mempool_calloc(app_bt_device.avrcp_cmd1[device_id]); + btif_avrcp_ct_register_notification(channel,app_bt_device.avrcp_cmd1[device_id],AVRCP_EID_MEDIA_STATUS_CHANGED,0); +#endif + avrcp_get_current_media_status(device_id); + APP_A2DP_TRACE(2,"::AVRCP_EVENT_CONNECT avrcp_version=0x%x,device_id=%d\n", btif_get_avrcp_version( channel),device_id); +#ifdef __BT_ONE_BRING_TWO__ + avrcp_palyback_status[device_id] = 0; + avrcp_bonding_a2dp_id[device_id] = BT_DEVICE_NUM; + avrcp_distinguish_bonding_a2dp_stream(chnl,device_id); +#endif +#ifdef USER_REBOOT_PLAY_MUSIC_AUTO + if(a2dp_need_to_play == true){ + TRACE(0,"a2dp_need_to_play is true,now play music"); + a2dp_handleKey(AVRCP_KEY_PLAY); + a2dp_need_to_play = false; + } +#endif + app_avrcp_connect_try_times[device_id] = 0; + break; + case BTIF_AVRCP_EVENT_DISCONNECT: + app_bt_device.avrcp_state[device_id] = 0; + TRACE(0,"::AVRCP_EVENT_DISCONNECT"); + #ifdef __BT_ONE_BRING_TWO__ + if (app_bt_is_to_resume_music_player(device_id)) + { + app_bt_reset_music_player_resume_state(); + } + #endif + if (app_bt_device.avrcp_get_capabilities_rsp[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_get_capabilities_rsp[device_id]); + app_bt_device.avrcp_get_capabilities_rsp[device_id] = NULL; + } + if (app_bt_device.avrcp_control_rsp[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_control_rsp[device_id]); + app_bt_device.avrcp_control_rsp[device_id] = NULL; + } + if (app_bt_device.avrcp_notify_rsp[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_notify_rsp[device_id]); + app_bt_device.avrcp_notify_rsp[device_id] = NULL; + } + + if (app_bt_device.avrcp_cmd1[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_cmd1[device_id]); + app_bt_device.avrcp_cmd1[device_id] = NULL; + } + if (app_bt_device.avrcp_cmd2[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_cmd2[device_id]); + app_bt_device.avrcp_cmd2[device_id] = NULL; + } + app_bt_device.volume_report[device_id] = 0; +#ifdef AVRCP_TRACK_CHANGED + app_bt_device.track_changed[device_id] = 0; +#endif +#ifdef __BT_ONE_BRING_TWO__ + avrcp_palyback_status[device_id ] = 0; + avrcp_bonding_a2dp_id[device_id] = BT_DEVICE_NUM; +#endif + + if (0 == device_id) + { + osTimerStop(app_avrcp_connect_timer0); + } +#ifdef __BT_ONE_BRING_TWO__ + else + { + osTimerStop(app_avrcp_connect_timer1); + } +#endif + +#ifndef IBRT + if(!app_is_disconnecting_all_bt_connections()) + { + app_avrcp_connect_try_times[device_id]++; + if (app_avrcp_connect_try_times[device_id] < MAX_AVRCP_CONNECT_TRY_TIME) + { + if (0 == device_id) + { + osTimerStart(app_avrcp_connect_timer0, 3000); + } + #ifdef __BT_ONE_BRING_TWO__ + else + { + osTimerStart(app_avrcp_connect_timer1, 3000); + } + #endif + } + } +#endif + break; + case BTIF_AVRCP_EVENT_RESPONSE: + APP_A2DP_TRACE(2,"::avrcp_callback_CT AVRCP_EVENT_RESPONSE op=%x,status=%x\n", btif_get_avrcp_cb_channel_advOp(parms), + btif_get_avrcp_cb_channel_state(parms)); + + + if( btif_get_avrcp_cb_channel_advOp(parms) == BTIF_AVRCP_OP_GET_PLAY_STATUS) + { + avrcp_set_media_status((uint8_t)btif_get_avrcp_cb_channel_state(parms)); + if( btif_get_avrcp_cb_channel_state(parms) == 0x1) + { + app_bt_device.a2dp_play_pause_flag = 1; + } + else if(btif_get_avrcp_adv_rsp_play_status(parms)->mediaStatus == 0x0||btif_get_avrcp_adv_rsp_play_status(parms)->mediaStatus == 0x2) + { + app_bt_device.a2dp_play_pause_flag = 0; + } + } + + break; +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +/*For Sony Compability Consideration*/ + case BTIF_AVRCP_EVENT_PANEL_PRESS: + TRACE(3,"::avrcp_callback_TG AVRCP_EVENT_PANEL_PRESS %x,%x,device_id=%d", + btif_get_avrcp_panel_cnf (parms)->operation, btif_get_avrcp_panel_ind( parms)->operation,device_id); + + switch( btif_get_avrcp_panel_ind( parms)->operation) + { + case BTIF_AVRCP_POP_VOLUME_UP: + TRACE(0,"avrcp_callback_TG avrcp_key = AVRCP_KEY_VOLUME_UP"); + app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_UP, 0); + break; + case BTIF_AVRCP_POP_VOLUME_DOWN: + TRACE(0,"avrcp_callback_TG avrcp_key = AVRCP_KEY_VOLUME_DOWN"); + app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_DOWN, 0); + break; + //SRC:for accept play/pause command from snk + case BTIF_AVRCP_POP_PLAY: + TRACE(0,"::avrcp start stream !"); + app_a2dp_start_stream(); + break; + case BTIF_AVRCP_POP_PAUSE: + TRACE(0,"::acrcp stop stream !"); + app_a2dp_suspend_stream(); + break; + default : + break; + } + break; +#else + /*For Sony Compability Consideration*/ + case BTIF_AVRCP_EVENT_PANEL_PRESS: + TRACE(3,"::avrcp_callback_TG AVRCP_EVENT_PANEL_PRESS %x,%x,device_id=%d", + btif_get_avrcp_panel_cnf (parms)->operation, btif_get_avrcp_panel_ind( parms)->operation,device_id); + switch(btif_get_avrcp_panel_cnf (parms)->operation) + { + case BTIF_AVRCP_POP_VOLUME_UP: + TRACE(0,"avrcp_callback_TG avrcp_key = AVRCP_KEY_VOLUME_UP"); + app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_UP, 0); + break; + case BTIF_AVRCP_POP_VOLUME_DOWN: + TRACE(0,"avrcp_callback_TG avrcp_key = AVRCP_KEY_VOLUME_DOWN"); + app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_DOWN, 0); + break; + default : + break; + } + break; + +#endif + case BTIF_AVRCP_EVENT_PANEL_HOLD: + TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_PANEL_HOLD %x,%x", + btif_get_avrcp_panel_cnf (parms)->operation, btif_get_avrcp_panel_ind( parms)->operation); + break; + case BTIF_AVRCP_EVENT_PANEL_RELEASE: + TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_PANEL_RELEASE %x,%x", + btif_get_avrcp_panel_cnf (parms)->operation,btif_get_avrcp_panel_ind( parms)->operation); + break; + /*For Sony Compability Consideration End*/ + case BTIF_AVRCP_EVENT_PANEL_CNF: + TRACE(3,"::AVRCP_EVENT_PANEL_CNF %x,%x,%x", + btif_get_avrcp_panel_cnf (parms)->operation, btif_get_avrcp_panel_cnf (parms)->press, btif_get_avrcp_panel_cnf (parms)->response); + break; + case BTIF_AVRCP_EVENT_ADV_TX_DONE://20 + TRACE(3,"::AVRCP_EVENT_ADV_TX_DONE op:%x err_code:%d state:%d\n", btif_get_avrcp_cb_txPdu_Op(parms), + btif_get_avrcp_cb_channel_error_code(parms), + btif_get_avrcp_cb_channel_state(parms)); + + if (btif_get_avrcp_cb_txPdu_Op(parms) == BTIF_AVRCP_OP_GET_CAPABILITIES){ + if (app_bt_device.avrcp_get_capabilities_rsp[device_id] == btif_get_avrcp_cb_txPdu( parms)){ + app_bt_device.avrcp_get_capabilities_rsp[device_id] = NULL; + btif_app_a2dp_avrcpadvancedpdu_mempool_free(btif_get_avrcp_cb_txPdu( parms)); + } + } + { + void *adv_pdu = app_bt_device.avrcp_notify_rsp[device_id]; + + if(adv_pdu && btif_get_avrcp_pdu_ctype(adv_pdu) == BTIF_AVCTP_RESPONSE_INTERIM) { + vol_ctrl_done_flag[device_id] = TX_DONE_FLAG_SUCCESS; + } + } + break; + case BTIF_AVRCP_EVENT_ADV_RESPONSE://18 + TRACE(2,"::avrcp_callback_CT AVRCP_EVENT_ADV_RESPONSE device_id=%d,role=%x\n",device_id,btif_get_avrcp_channel_role(channel)); + TRACE(2,"::avrcp_callback_CT AVRCP_EVENT_ADV_RESPONSE op=%x,status=%x\n", btif_get_avrcp_cb_channel_advOp(parms) + , btif_get_avrcp_cb_channel_state(parms)); + + if(btif_get_avrcp_cb_channel_advOp(parms) == BTIF_AVRCP_OP_GET_PLAY_STATUS && btif_get_avrcp_cb_channel_state(parms) == BT_STS_SUCCESS) + { + TRACE(3,"::AVRCP_OP_GET_PLAY_STATUS %d/%d Status:%d", + btif_get_avrcp_adv_rsp_play_status(parms)->position, + btif_get_avrcp_adv_rsp_play_status(parms)->length, + btif_get_avrcp_adv_rsp_play_status(parms)->mediaStatus); + avrcp_set_media_status(btif_get_avrcp_adv_rsp_play_status(parms)->mediaStatus); + } + + if(btif_get_avrcp_cb_channel_advOp(parms) == BTIF_AVRCP_OP_GET_CAPABILITIES && btif_get_avrcp_cb_channel_state(parms) == BT_STS_SUCCESS) + { + TRACE(1,"::avrcp_callback_CT AVRCP eventmask=%x\n", btif_get_avrcp_adv_rsp(parms)->capability.info.eventMask); + + btif_set_avrcp_adv_rem_event_mask(channel, btif_get_avrcp_adv_rsp(parms)->capability.info.eventMask); + if(btif_get_avrcp_adv_rem_event_mask(channel) & BTIF_AVRCP_ENABLE_PLAY_STATUS_CHANGED) + { + TRACE(0,"::avrcp_callback_CT AVRCP send notification PLAY_STATUS_CHANGED\n"); + if (app_bt_device.avrcp_cmd1[device_id] == NULL){ + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_cmd1[device_id]); + } + btif_avrcp_ct_register_notification( channel, app_bt_device.avrcp_cmd1[device_id], BTIF_AVRCP_EID_MEDIA_STATUS_CHANGED,0); + + } + if( btif_get_avrcp_adv_rem_event_mask( channel) & BTIF_AVRCP_ENABLE_PLAY_POS_CHANGED) + { +#if 0 + TRACE(0,"::avrcp_callback_CT AVRCP send notification PLAY_POS_CHANGED\n"); + if (app_bt_device.avrcp_cmd2[device_id] == NULL){ + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_cmd2[device_id]); + } + btif_avrcp_ct_register_notification(channel,app_bt_device.avrcp_cmd2[device_id],BTIF_AVRCP_EID_PLAY_POS_CHANGED,1); +#endif + } + } + else if(btif_get_avrcp_cb_channel_advOp(parms) == BTIF_AVRCP_OP_REGISTER_NOTIFY &&btif_get_avrcp_cb_channel_state(parms) == BT_STS_SUCCESS) + { + btif_avrcp_ct_register_notify_response_check(channel, btif_get_avrcp_adv_notify(parms)->event); + if(btif_get_avrcp_adv_notify(parms)->event == BTIF_AVRCP_EID_MEDIA_STATUS_CHANGED) + { + TRACE(1,"::avrcp_callback_CT ACRCP notify rsp playback states=%x",btif_get_avrcp_adv_notify(parms)->p.mediaStatus); +#if defined(__BT_ONE_BRING_TWO__) + if(btif_get_avrcp_adv_notify(parms)->p.mediaStatus == 0x1){ + avrcp_palyback_status[device_id] = 0x01; + if (app_bt_is_to_resume_music_player(device_id) || + (BTIF_HF_AUDIO_CON == app_bt_device.hf_audio_state[device_id_other])) + { + app_bt_pause_media_player_again(device_id); + } + }else if(btif_get_avrcp_adv_notify(parms)->p.mediaStatus == 0x0||btif_get_avrcp_adv_notify(parms)->p.mediaStatus == 0x2){ + avrcp_palyback_status[device_id] = 0x00; + app_bt_device.latestPausedDevId = device_id; + } +#endif +#if defined(__BT_ONE_BRING_TWO__) && defined(__MULTIPOINT_A2DP_PREEMPT__) + uint8_t is_a2dp_streaming = 0; + enum BT_DEVICE_ID_T avrcp_bonding_a2dp_another = BT_DEVICE_NUM; + is_a2dp_streaming = a2dp_get_streaming_id(); + TRACE(1,"is_a2dp_streaming = %d",is_a2dp_streaming); + TRACE(2,"device_id = %d other_id = %d",device_id,device_id_other); + if(avrcp_distinguish_bonding_a2dp_stream(chnl,device_id) == 0x02){ + return; + } + avrcp_bonding_a2dp_another = (avrcp_bond_a2dp_stream.id== BT_DEVICE_ID_1)?(BT_DEVICE_ID_2):(BT_DEVICE_ID_1); + TRACE(5,"avrcp_palyback_status_id[%d] = %d , avrcp_palyback_status_id_other[%d] = %d cur_a2dp_stream = %d",device_id, + avrcp_palyback_status[device_id],device_id_other,avrcp_palyback_status[device_id_other],app_bt_device.curr_a2dp_stream_id); + if((avrcp_palyback_status[BT_DEVICE_ID_1] == 0) && + (avrcp_palyback_status[BT_DEVICE_ID_2] == 0)){ + app_bt_device.a2dp_play_pause_flag = 0; + } + else{ + app_bt_device.a2dp_play_pause_flag = 1; + } + if(is_a2dp_streaming !=0){ + if(avrcp_palyback_status[device_id] == 1) /*&& + (avrcp_palyback_status[BT_DEVICE_ID_2] == 1))*/ { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,BT_STREAM_SBC,avrcp_bond_a2dp_stream.id,MAX_RECORD_NUM); + a2dp_set_cur_stream(avrcp_bond_a2dp_stream.id); +#if 1 + if(avrcp_palyback_status[device_id_other] == 1){ + btapp_a2dp_suspend_music(device_id_other); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC,avrcp_bonding_a2dp_another,MAX_RECORD_NUM); + /*if(bt_media_is_media_active_by_device(BT_STREAM_SBC,avrcp_bond_a2dp_stream.id_other) != 0)*/ + { + app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_SET, TGT_VOLUME_LEVEL_MUTE); + app_a2dp_hold_mute(); + } + } +#endif + } + if(is_a2dp_streaming >2){ + if((avrcp_palyback_status[device_id] == 1) && + (avrcp_palyback_status[device_id_other] == 0)){ + a2dp_set_cur_stream(avrcp_bond_a2dp_stream.id); + } + if(app_bt_device.a2dp_play_pause_flag == 0){ + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC,avrcp_bond_a2dp_stream.id,MAX_RECORD_NUM); + } + } + if(app_bt_device.a2dp_play_pause_flag == 1){ + if(avrcp_palyback_status[device_id] == 0){ + a2dp_set_cur_stream(avrcp_bonding_a2dp_another); + app_a2dp_unhold_mute(); + } + } + } + TRACE(1,">stream_id = %d",a2dp_get_cur_stream_id()); +#else + avrcp_set_media_status(btif_get_avrcp_adv_notify(parms)->p.mediaStatus); + if(btif_get_avrcp_adv_notify(parms)->p.mediaStatus == 0x1) { + app_bt_device.a2dp_play_pause_flag = 1; + } else if(btif_get_avrcp_adv_notify(parms)->p.mediaStatus == 0x0||btif_get_avrcp_adv_notify(parms)->p.mediaStatus == 0x2){ + app_bt_device.a2dp_play_pause_flag = 0; + } +#endif + } + else if(btif_get_avrcp_adv_notify(parms)->event == BTIF_AVRCP_EID_PLAY_POS_CHANGED) + { + TRACE(1,"::ACRCP notify rsp play pos =%x",btif_get_avrcp_adv_notify(parms)->p.position); + } + else if(btif_get_avrcp_adv_notify(parms)->event == BTIF_AVRCP_EID_VOLUME_CHANGED){ + TRACE(1,"::ACRCP notify rsp volume =%x",btif_get_avrcp_adv_notify(parms)->p.volume); + a2dp_volume_set(device_id, btif_get_avrcp_adv_notify(parms)->p.volume); + } +#ifdef AVRCP_TRACK_CHANGED + else if(btif_get_avrcp_adv_notify(parms)->event == BTIF_AVRCP_EID_TRACK_CHANGED){ + // TRACE(1,"::AVRCP_EID_TRACK_CHANGED transId:%d\n", Parms->p.cmdFrame->transId); + if (app_bt_device.avrcp_notify_rsp[device_id] == NULL) + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_notify_rsp[device_id]); + + btif_set_app_bt_device_avrcp_notify_rsp_ctype(app_bt_device.avrcp_notify_rsp[device_id], BTIF_AVCTP_RESPONSE_INTERIM); + + app_bt_device.track_changed[device_id] = BTIF_AVCTP_RESPONSE_INTERIM; + btif_avrcp_ct_get_media_Info(channel,app_bt_device.avrcp_notify_rsp[device_id],0x7f) ; + } +#endif + } + else if(btif_get_avrcp_cb_channel_advOp(parms) == BTIF_AVRCP_OP_GET_PLAY_STATUS && btif_get_avrcp_cb_channel_state(parms) == BT_STS_SUCCESS) + { + TRACE(1,"AVRCP get play status returns %d", btif_get_avrcp_adv_rsp_play_status(parms)->mediaStatus); + #if defined(__BT_ONE_BRING_TWO__) + if(btif_get_avrcp_adv_rsp_play_status(parms)->mediaStatus == 0x1){ + avrcp_palyback_status[device_id] = 0x01; + }else if(btif_get_avrcp_adv_rsp_play_status(parms)->mediaStatus == 0x0||btif_get_avrcp_adv_rsp_play_status(parms)->mediaStatus == 0x2){ + avrcp_palyback_status[device_id] = 0x00; + } + #endif + } +#ifdef AVRCP_TRACK_CHANGED + else if(btif_get_avrcp_cb_channel_advOp(parms) == BTIF_AVRCP_OP_GET_MEDIA_INFO && btif_get_avrcp_cb_channel_state(parms) == BT_STS_SUCCESS){ + TRACE(1,"AVRCP_TRACK_CHANGED numid=%d",btif_get_avrcp_adv_rsp(parms)->element.numIds); + for(uint8_t i=0;i<7;i++) + { + if(btif_get_avrcp_adv_rsp(parms)->element.txt[i].length>0) + { + TRACE(2,"Id=%d,%s\n",i,btif_get_avrcp_adv_rsp(parms)->element.txt[i].string); + } + } + + } +#endif + break; + case BTIF_AVRCP_EVENT_COMMAND: + TRACE(2,"::avrcp_callback_CT AVRCP_EVENT_COMMAND device_id=%d,role=%x\n",device_id,btif_get_avrcp_channel_role(channel)); + TRACE(2,"::avrcp_callback_CT AVRCP_EVENT_COMMAND ctype=%x,subunitype=%x\n", btif_get_avrcp_cmd_frame(parms)->ctype,btif_get_avrcp_cmd_frame(parms)->subunitType); + TRACE(2,"::avrcp_callback_CT AVRCP_EVENT_COMMAND subunitId=%x,opcode=%x\n", btif_get_avrcp_cmd_frame(parms)->subunitId,btif_get_avrcp_cmd_frame(parms)->opcode); + TRACE(2,"::avrcp_callback_CT AVRCP_EVENT_COMMAND operands=%p,operandLen=%x\n", btif_get_avrcp_cmd_frame(parms)->operands,btif_get_avrcp_cmd_frame(parms)->operandLen); + TRACE(1,"::avrcp_callback_CT AVRCP_EVENT_COMMAND more=%x\n", btif_get_avrcp_cmd_frame(parms)->more); + if( btif_get_avrcp_cmd_frame(parms)->ctype == BTIF_AVRCP_CTYPE_STATUS) + { + uint32_t company_id = *(btif_get_avrcp_cmd_frame(parms)->operands+2) + ((uint32_t)(*(btif_get_avrcp_cmd_frame(parms)->operands+1))<<8) + ((uint32_t)(*(btif_get_avrcp_cmd_frame(parms)->operands))<<16); + TRACE(1,"::avrcp_callback_CT AVRCP_EVENT_COMMAND company_id=%x\n", company_id); + if(company_id == 0x001958) //bt sig + { + avrcp_operation_t op = *(btif_get_avrcp_cmd_frame(parms)->operands+3); + uint8_t oplen = *(btif_get_avrcp_cmd_frame(parms)->operands+6)+ ((uint32_t)(*(btif_get_avrcp_cmd_frame(parms)->operands+5))<<8); + TRACE(2,"::avrcp_callback_CT AVRCP_EVENT_COMMAND op=%x,oplen=%x\n", op,oplen); + switch(op) + { + case BTIF_AVRCP_OP_GET_CAPABILITIES: + { + uint8_t event = *(btif_get_avrcp_cmd_frame(parms)->operands+7); + if(event==BTIF_AVRCP_CAPABILITY_COMPANY_ID) + { + TRACE(0,"::avrcp_callback_CT AVRCP_EVENT_COMMAND send support compay id"); + if (app_bt_device.avrcp_get_capabilities_rsp[device_id] == NULL) + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_get_capabilities_rsp[device_id]); + btif_avrcp_set_capabilities_rsp_cmd(app_bt_device.avrcp_get_capabilities_rsp[device_id], + btif_get_avrcp_cmd_frame(parms)->transId, BTIF_AVCTP_RESPONSE_IMPLEMENTED_STABLE); + btif_avrcp_ct_get_capabilities_company_id_rsp(channel, app_bt_device.avrcp_get_capabilities_rsp[device_id]); + } + else if(event == BTIF_AVRCP_CAPABILITY_EVENTS_SUPPORTED) + { + TRACE(1,"::avrcp_callback_CT AVRCP_EVENT_COMMAND send support event transId:%d", btif_get_avrcp_cmd_frame(parms)->transId); + if(app_bt_device.avrcpVolumeSync) + { + btif_set_avrcp_adv_rem_event_mask(channel, BTIF_AVRCP_ENABLE_VOLUME_CHANGED); + } + else + { + btif_set_avrcp_adv_rem_event_mask(channel, 0); + } + if (app_bt_device.avrcp_get_capabilities_rsp[device_id] == NULL) + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_get_capabilities_rsp[device_id]); + + uint8_t transid = btif_get_avrcp_cmd_frame(parms)->transId; + btif_avrcp_set_capabilities_rsp_cmd(app_bt_device.avrcp_get_capabilities_rsp[device_id], + transid, BTIF_AVCTP_RESPONSE_IMPLEMENTED_STABLE); + TRACE(1,"::avrcp_callback_CT AVRCP_EVENT_COMMAND send support event transId:%d", transid); + btif_avrcp_ct_get_capabilities_rsp(channel, app_bt_device.avrcp_get_capabilities_rsp[device_id], + BTIF_AVRCP_CAPABILITY_EVENTS_SUPPORTED, btif_get_avrcp_adv_rem_event_mask(channel)); + } + else + { + TRACE(0,"::avrcp_callback_CT AVRCP_EVENT_COMMAND send error event value"); + } + } + break; + } + + } + + }else if(btif_get_avrcp_cmd_frame(parms)->ctype == BTIF_AVCTP_CTYPE_CONTROL){ + TRACE(0,"::avrcp_callback_CT AVRCP_EVENT_COMMAND AVCTP_CTYPE_CONTROL\n"); + DUMP8("%02x ", btif_get_avrcp_cmd_frame(parms)->operands, btif_get_avrcp_cmd_frame(parms)->operandLen); + if (btif_get_avrcp_cmd_frame(parms)->operands[3] == BTIF_AVRCP_OP_SET_ABSOLUTE_VOLUME){ + TRACE(1,"::avrcp_callback_CT AVRCP_EID_VOLUME_CHANGED transId:%d\n", btif_get_avrcp_cmd_frame(parms)->transId); + if((btif_get_avrcp_cmd_frame(parms)->operands[7]<127)&&(btif_get_avrcp_cmd_frame(parms)->operands[7]>1)){ + a2dp_volume_set(device_id,btif_get_avrcp_cmd_frame(parms)->operands[7] + 1); + }else{ + a2dp_volume_set(device_id,btif_get_avrcp_cmd_frame(parms)->operands[7]); + } + //a2dp_volume_set(device_id, btif_get_avrcp_cmd_frame(parms)->operands[7]); + if (app_bt_device.avrcp_control_rsp[device_id] == NULL) + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_control_rsp[device_id]); +//#if defined(__BQB_PROFILE_TEST__) + if((btif_get_avrcp_cmd_frame(parms)->operandLen != 8))//it works for BQB + { + btif_avrcp_set_control_rsp_cmd_witherror(app_bt_device.avrcp_control_rsp[device_id],btif_get_avrcp_cmd_frame(parms)->transId, BTIF_AVCTP_RESPONSE_REJECTED, BTIF_AVRCP_ERR_INVALID_PARM); + TRACE(0,"reject invalid volume"); + } + else +//#endif + btif_avrcp_set_control_rsp_cmd(app_bt_device.avrcp_control_rsp[device_id],btif_get_avrcp_cmd_frame(parms)->transId, BTIF_AVCTP_RESPONSE_ACCEPTED); + + DUMP8("%02x ", btif_get_avrcp_cmd_frame(parms)->operands, btif_get_avrcp_cmd_frame(parms)->operandLen); + btif_avrcp_ct_accept_absolute_volume_rsp(channel, app_bt_device.avrcp_control_rsp[device_id], btif_get_avrcp_cmd_frame(parms)->operands[7]); + } else if (BTIF_AVRCP_OP_CUSTOM_CMD == btif_get_avrcp_cmd_frame(parms)->operands[3]) { + app_AVRCP_CustomCmd_Received(&btif_get_avrcp_cmd_frame(parms)->operands[7], btif_get_avrcp_cmd_frame(parms)->operandLen - 7); + app_AVRCP_sendCustomCmdRsp(device_id, channel, true,btif_get_avrcp_cmd_frame(parms)->transId); + } + }else if (btif_get_avrcp_cmd_frame(parms)->ctype == BTIF_AVCTP_CTYPE_NOTIFY){ + bt_status_t status; + TRACE(0,"::avrcp_callback_CT AVRCP_EVENT_COMMAND AVCTP_CTYPE_NOTIFY\n"); + DUMP8("%02x ", btif_get_avrcp_cmd_frame(parms)->operands, btif_get_avrcp_cmd_frame(parms)->operandLen); + if (btif_get_avrcp_cmd_frame(parms)->operands[7] == BTIF_AVRCP_EID_VOLUME_CHANGED){ + TRACE(1,"::avrcp_callback_CT AVRCP_EID_VOLUME_CHANGED transId:%d\n", btif_get_avrcp_cmd_frame(parms)->transId); + if (app_bt_device.avrcp_notify_rsp[device_id] == NULL){ + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_notify_rsp[device_id]); + } + btif_avrcp_set_notify_rsp_cmd(app_bt_device.avrcp_notify_rsp[device_id],btif_get_avrcp_cmd_frame(parms)->transId, BTIF_AVCTP_RESPONSE_INTERIM) ; + app_bt_device.volume_report[device_id] = BTIF_AVCTP_RESPONSE_INTERIM; + status = btif_avrcp_ct_get_absolute_volume_rsp(channel, + app_bt_device.avrcp_notify_rsp[device_id],a2dp_volume_get(device_id)); + TRACE(1,"::avrcp_callback_CT AVRCP_EVENT_COMMAND AVRCP_EID_VOLUME_CHANGED nRet:%x\n",status); + + } +//#if defined(__BQB_PROFILE_TEST__) + else if(btif_get_avrcp_cmd_frame(parms)->operands[7] == 0xff)//it works for BQB + { + TRACE(1,"trances id:%d",btif_get_avrcp_cmd_frame(parms)->transId); + if (app_bt_device.avrcp_notify_rsp[device_id] == NULL){ + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_notify_rsp[device_id]); + } + btif_avrcp_set_notify_rsp_cmd_witherror(app_bt_device.avrcp_notify_rsp[device_id],btif_get_avrcp_cmd_frame(parms)->transId, BTIF_AVCTP_RESPONSE_REJECTED, BTIF_AVRCP_ERR_INVALID_PARM); + + status = btif_avrcp_ct_invalid_volume_rsp(channel, app_bt_device.avrcp_notify_rsp[device_id]); + TRACE(1,"AVRCP_CtInvalidVolume_Rsp,status%d",status); + } +//#endif + } +//#endif + break; + case BTIF_AVRCP_EVENT_ADV_NOTIFY://17 + TRACE(3,"::avrcp_callback_CT AVRCP_EVENT_ADV_NOTIFY adv.notify.event=%x,device_id=%d,chnl->role=%x\n",btif_get_avrcp_adv_notify(parms)->event,device_id, btif_get_avrcp_cb_channel_role( channel)); + if(btif_get_avrcp_adv_notify(parms)->event == BTIF_AVRCP_EID_VOLUME_CHANGED) + { + TRACE(1,"::avrcp_callback_CT ACRCP notify vol =%x",btif_get_avrcp_adv_notify(parms)->p.volume); + // AVRCP_CtRegisterNotification(chnl,app_bt_device.avrcp_notify_rsp[device_id],BTIF_AVRCP_EID_VOLUME_CHANGED,0); + btif_avrcp_ct_register_notification(channel,app_bt_device.avrcp_notify_rsp[device_id],BTIF_AVRCP_EID_VOLUME_CHANGED,0); + } + else if(btif_get_avrcp_adv_notify(parms)->event == BTIF_AVRCP_EID_MEDIA_STATUS_CHANGED) + { + TRACE(1,"::avrcp_callback_CT ACRCP notify playback states=%x",btif_get_avrcp_adv_notify(parms)->p.mediaStatus); + avrcp_set_media_status(btif_get_avrcp_adv_notify(parms)->p.mediaStatus); + if (app_bt_device.avrcp_cmd1[device_id] == NULL){ + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_cmd1[device_id]); + } + btif_avrcp_ct_register_notification(channel,app_bt_device.avrcp_cmd1[device_id],BTIF_AVRCP_EID_MEDIA_STATUS_CHANGED,0); + } + else if(btif_get_avrcp_adv_notify(parms)->event == BTIF_AVRCP_EID_PLAY_POS_CHANGED) + { + TRACE(1,"::avrcp_callback_CT ACRCP notify play pos =%x",btif_get_avrcp_adv_notify(parms)->p.position); + if (app_bt_device.avrcp_cmd2[device_id] == NULL){ + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_cmd2[device_id]); + } + btif_avrcp_ct_register_notification(channel,app_bt_device.avrcp_cmd2[device_id],BTIF_AVRCP_EID_PLAY_POS_CHANGED,1); + } +#ifdef AVRCP_TRACK_CHANGED + else if(btif_get_avrcp_adv_notify(parms)->event == BTIF_AVRCP_EID_TRACK_CHANGED){ + TRACE(2,"::AVRCP notify track msU32=%x, lsU32=%x",btif_get_avrcp_adv_notify(parms)->p.track.msU32,btif_get_avrcp_adv_notify(parms)->p.track.lsU32); + if (app_bt_device.avrcp_cmd2[device_id] == NULL){ + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_cmd2[device_id]); + } + btif_avrcp_ct_register_notification(channel,app_bt_device.avrcp_cmd2[device_id],BTIF_AVRCP_EID_TRACK_CHANGED,0); + } +#endif + break; + case BTIF_AVRCP_EVENT_ADV_CMD_TIMEOUT: + TRACE(2,"::avrcp_callback_CT AVRCP_EVENT_ADV_CMD_TIMEOUT device_id=%d,role=%x\n",device_id,btif_get_avrcp_cb_channel_role(channel)); + break; + } + +#if defined(IBRT) + app_tws_ibrt_profile_callback(BTIF_APP_AVRCP_PROFILE_ID,(void *)chnl, (void *)parms); +#endif + +} + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +extern "C" void avrcp_callback_TG(btif_avrcp_chnl_handle_t chnl, const avrcp_callback_parms_t *parms) +{ + //do nothing +} +#endif +#ifdef __TWS__ +typedef uint8_t tx_done_flag; +#define TX_DONE_FLAG_INIT 0 +#define TX_DONE_FLAG_SUCCESS 1 +#define TX_DONE_FLAG_FAIL 2 +#define TX_DONE_FLAG_TXING 3 +tx_done_flag TG_tx_done_flag = TX_DONE_FLAG_INIT; + + +void avrcp_callback_TG(btif_avrcp_chnl_handle_t chnl, const avrcp_callback_parms_t *parms) +{ + APP_A2DP_TRACE(2,"avrcp_callback_TG : chnl %p, Parms %p\n", chnl, parms); + APP_A2DP_TRACE(1,"::avrcp_callback_TG Parms->event %d\n", btif_get_avrcp_cb_channel_state(parms)); + btif_avrcp_channel_t* channel = btif_get_avrcp_channel(chnl); + + +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T device_id = (chnl == app_bt_device.avrcp_channel[0]->avrcp_channel_handle)?BT_DEVICE_ID_1:BT_DEVICE_ID_2; +#else + enum BT_DEVICE_ID_T device_id = BT_DEVICE_ID_1; +#endif + switch(btif_avrcp_get_callback_event((avrcp_callback_parms_t *)parms)) + { + case BTIF_AVRCP_EVENT_CONNECT: + btif_set_avrcp_state(channel,BTIF_AVRCP_STATE_CONNECTED); + if (app_bt_device.avrcp_custom_cmd[device_id] == NULL) + { + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_custom_cmd[device_id]); + } + APP_A2DP_TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_CONNECT %x,device_id=%d\n", btif_get_avrcp_version( channel),device_id); + + break; + case BTIF_AVRCP_EVENT_DISCONNECT: + APP_A2DP_TRACE(0,"::avrcp_callback_TG AVRCP_EVENT_DISCONNECT"); + + + btif_set_avrcp_state(channel,BTIF_AVRCP_STATE_DISCONNECTED) ; + if (app_bt_device.avrcp_get_capabilities_rsp[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_get_capabilities_rsp[device_id]); + app_bt_device.avrcp_get_capabilities_rsp[device_id] = NULL; + } + if (app_bt_device.avrcp_control_rsp[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_control_rsp[device_id]); + app_bt_device.avrcp_control_rsp[device_id] = NULL; + } + if (app_bt_device.avrcp_notify_rsp[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_notify_rsp[device_id]); + app_bt_device.avrcp_notify_rsp[device_id] = NULL; + } + + if (app_bt_device.avrcp_cmd1[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_cmd1[device_id]); + app_bt_device.avrcp_cmd1[device_id] = NULL; + } + if (app_bt_device.avrcp_cmd2[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_cmd2[device_id]); + app_bt_device.avrcp_cmd2[device_id] = NULL; + } + + if (app_bt_device.avrcp_custom_cmd[device_id]){ + btif_app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_custom_cmd[device_id]); + app_bt_device.avrcp_custom_cmd[device_id] = NULL; + } + + app_bt_device.volume_report[device_id] = 0; + + + break; + case BTIF_AVRCP_EVENT_RESPONSE: + APP_A2DP_TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_RESPONSE op=%x,status=%x\n", btif_get_avrcp_cb_channel_advOp(parms), + btif_get_avrcp_cb_channel_state(parms)); + + break; + case BTIF_AVRCP_EVENT_PANEL_CNF: + APP_A2DP_TRACE(3,"::avrcp_callback_TG AVRCP_EVENT_PANEL_CNF %x,%x,%x", + btif_get_avrcp_panel_cnf(parms)->response, btif_get_avrcp_panel_cnf(parms)->operation, + btif_get_avrcp_panel_cnf(parms)->press); + break; + case BTIF_AVRCP_EVENT_ADV_TX_DONE: + APP_A2DP_TRACE(3,"::avrcp_callback_TG AVRCP_EVENT_ADV_TX_DONE device_id=%d,status=%x,errorcode=%x\n",device_id, + btif_get_avrcp_cb_channel_state(parms),btif_get_avrcp_cb_channel_error_code(parms)); + APP_A2DP_TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_ADV_TX_DONE op:%d, transid:%x\n", btif_get_avrcp_cb_txPdu_Op(parms), + btif_get_avrcp_cb_txPdu_transId(parms)); + if (btif_get_avrcp_cb_txPdu_Op(parms) == BTIF_AVRCP_OP_GET_CAPABILITIES){ + if (app_bt_device.avrcp_get_capabilities_rsp[device_id] == btif_get_avrcp_cb_txPdu(parms)){ + app_bt_device.avrcp_get_capabilities_rsp[device_id] = NULL; + btif_app_a2dp_avrcpadvancedpdu_mempool_free(btif_get_avrcp_cb_txPdu(parms)); + } + } + TG_tx_done_flag = TX_DONE_FLAG_SUCCESS; +#if 0 + if (Parms->p.adv.txPdu->op == AVRCP_OP_SET_ABSOLUTE_VOLUME){ + if (Parms->p.adv.txPdu->ctype != AVCTP_RESPONSE_INTERIM){ + if (app_bt_device.avrcp_control_rsp[device_id] == Parms->p.adv.txPdu){ + app_bt_device.avrcp_control_rsp[device_id] = NULL; + app_a2dp_avrcpadvancedpdu_mempool_free(Parms->p.adv.txPdu); + } + } + } + if (Parms->p.adv.txPdu->op == AVRCP_OP_REGISTER_NOTIFY){ + if (Parms->p.adv.txPdu->ctype != AVCTP_RESPONSE_INTERIM){ + if (Parms->p.adv.txPdu->parms[0] == AVRCP_EID_VOLUME_CHANGED){ + app_bt_device.avrcp_notify_rsp[device_id] = NULL; + app_a2dp_avrcpadvancedpdu_mempool_free(Parms->p.adv.txPdu); + } + } + } +#endif + + break; + case BTIF_AVRCP_EVENT_COMMAND: + APP_A2DP_TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_COMMAND device_id=%d,role=%x\n",device_id, btif_get_avrcp_channel_role(channel)); + APP_A2DP_TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_COMMAND ctype=%x,subunitype=%x\n", btif_get_avrcp_cmd_frame(parms)->ctype, + btif_get_avrcp_cmd_frame(parms)->subunitType); + APP_A2DP_TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_COMMAND subunitId=%x,opcode=%x\n", btif_get_avrcp_cmd_frame(parms)->subunitId, + btif_get_avrcp_cmd_frame(parms)->opcode); + APP_A2DP_TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_COMMAND operands=%x,operandLen=%x\n", + btif_get_avrcp_cmd_frame(parms)->operands,btif_get_avrcp_cmd_frame(parms)->operandLen); + APP_A2DP_TRACE(1,"::avrcp_callback_TG AVRCP_EVENT_COMMAND more=%x\n", btif_get_avrcp_cmd_frame(parms)->more); + if(btif_get_avrcp_cmd_frame(parms)->ctype == BTIF_AVRCP_CTYPE_STATUS) + { + uint32_t company_id = *(btif_get_avrcp_cmd_frame(parms)->operands+2) + ((uint32_t)(*(btif_get_avrcp_cmd_frame(parms)->operands+1))<<8) + + ((uint32_t)(*(btif_get_avrcp_cmd_frame(parms)->operands))<<16); + TRACE(1,"::avrcp_callback_TG AVRCP_EVENT_COMMAND company_id=%x\n", company_id); + if(company_id == 0x001958) //bt sig + { + avrcp_operation_t op = *(btif_get_avrcp_cmd_frame(parms)->operands+3); + uint8_t oplen = *(btif_get_avrcp_cmd_frame(parms)->operands+6)+ ((uint32_t)(*(btif_get_avrcp_cmd_frame(parms)->operands+5))<<8); + APP_A2DP_TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_COMMAND op=%x,oplen=%x\n", op,oplen); + switch(op) + { + case BTIF_AVRCP_OP_GET_CAPABILITIES: + { + uint8_t event = *(btif_get_avrcp_cmd_frame(parms)->operands+7); + if(event==BTIF_AVRCP_CAPABILITY_COMPANY_ID) + { + APP_A2DP_TRACE(0,"::avrcp_callback_TG AVRCP_EVENT_COMMAND send support compay id"); + } + else if(event == BTIF_AVRCP_CAPABILITY_EVENTS_SUPPORTED) + { + APP_A2DP_TRACE(1,"::avrcp_callback_TG AVRCP_EVENT_COMMAND send support event transId:%d",btif_get_avrcp_cmd_frame(parms)->transId); + if(app_bt_device.avrcpVolumeSync) + { + btif_set_avrcp_adv_rem_event_mask(channel, BTIF_AVRCP_ENABLE_VOLUME_CHANGED); + } + else + { + btif_set_avrcp_adv_rem_event_mask(channel, 0); + } + + if (app_bt_device.avrcp_get_capabilities_rsp[device_id] == NULL) + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_get_capabilities_rsp[device_id]); + + // app_bt_device.avrcp_get_capabilities_rsp[device_id]->transId = btif_get_avrcp_cmd_frame(parms)->transId; + //app_bt_device.avrcp_get_capabilities_rsp[device_id]->ctype = BTIF_AVCTP_RESPONSE_IMPLEMENTED_STABLE; + btif_avrcp_set_capabilities_rsp_cmd( app_bt_device.avrcp_get_capabilities_rsp[device_id],btif_get_avrcp_cmd_frame(parms)->transId, BTIF_AVCTP_RESPONSE_IMPLEMENTED_STABLE); + APP_A2DP_TRACE(1,"::avrcp_callback_TG AVRCP_EVENT_COMMAND send support event transId:%d", btif_get_app_bt_device_avrcp_notify_rsp_transid(app_bt_device.avrcp_get_capabilities_rsp[device_id])); + btif_avrcp_ct_get_capabilities_rsp(channel,app_bt_device.avrcp_get_capabilities_rsp[device_id],BTIF_AVRCP_CAPABILITY_EVENTS_SUPPORTED,btif_get_avrcp_adv_rem_event_mask(channel)); + // AVRCP_CtGetCapabilities_Rsp(chnl,app_bt_device.avrcp_get_capabilities_rsp[device_id],BTIF_AVRCP_CAPABILITY_EVENTS_SUPPORTED,chnl->adv.eventMask); + } + else + { + APP_A2DP_TRACE(0,"::avrcp_callback_TG AVRCP_EVENT_COMMAND send error event value"); + } + } + break; + } + + } + + }else if(btif_get_avrcp_cmd_frame(parms)->ctype == BTIF_AVCTP_CTYPE_CONTROL){ + APP_A2DP_TRACE(0,"::avrcp_callback_TG AVRCP_EVENT_COMMAND AVCTP_CTYPE_CONTROL\n"); + DUMP8("%02x ", btif_get_avrcp_cmd_frame(parms)->operands, btif_get_avrcp_cmd_frame(parms)->operandLen); + if (btif_get_avrcp_cmd_frame(parms)->operands[3] == BTIF_AVRCP_OP_SET_ABSOLUTE_VOLUME){ + APP_A2DP_TRACE(1,"::avrcp_callback_TG AVRCP_EID_VOLUME_CHANGED transId:%d\n", btif_get_avrcp_cmd_frame(parms)->transId); + a2dp_volume_set(device_id, (btif_get_avrcp_cmd_frame(parms)->operands[7])+1); + //a2dp_volume_set(btif_get_avrcp_cmd_frame(parms)->operands[7]); + log_event_2(EVENT_AVRCP_VOLUME_CHANGE_REQ_RECEIVED, (btif_avrcp_get_cmgrhandler_remDev_hciHandle(channel))&0x3, + btif_get_avrcp_cmd_frame(parms)->operands[7]); + + if (app_bt_device.avrcp_control_rsp[device_id] == NULL) + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_control_rsp[device_id]); + + //app_bt_device.avrcp_control_rsp[device_id]->transId = btif_get_avrcp_cmd_frame(parms)->transId; + //app_bt_device.avrcp_control_rsp[device_id]->ctype = BTIF_AVCTP_RESPONSE_ACCEPTED; + btif_avrcp_set_control_rsp_cmd(app_bt_device.avrcp_control_rsp[device_id], + btif_get_avrcp_cmd_frame(parms)->transId, BTIF_AVCTP_RESPONSE_ACCEPTED); + DUMP8("%02x ", btif_get_avrcp_cmd_frame(parms)->operands, btif_get_avrcp_cmd_frame(parms)->operandLen); + + //AVRCP_CtAcceptAbsoluteVolume_Rsp(chnl, app_bt_device.avrcp_control_rsp[device_id], btif_get_avrcp_cmd_frame(parms)->operands[7]); + btif_avrcp_ct_accept_absolute_volume_rsp(channel, app_bt_device.avrcp_control_rsp[device_id], btif_get_avrcp_cmd_frame(parms)->operands[7]); + } + else if (BTIF_AVRCP_OP_CUSTOM_CMD == btif_get_avrcp_cmd_frame(parms)->operands[3]) + { + app_AVRCP_CustomCmd_Received(& btif_get_avrcp_cmd_frame(parms)->operands[7], btif_get_avrcp_cmd_frame(parms)->operandLen - 7); + app_AVRCP_sendCustomCmdRsp(device_id, channel, true, btif_get_avrcp_cmd_frame(parms)->transId); + } + }else if ( btif_get_avrcp_cmd_frame(parms)->ctype == BTIF_AVCTP_CTYPE_NOTIFY){ + bt_status_t status; + APP_A2DP_TRACE(0,"::avrcp_callback_TG AVRCP_EVENT_COMMAND AVCTP_CTYPE_NOTIFY\n"); + DUMP8("%02x ", btif_get_avrcp_cmd_frame(parms)->operands, btif_get_avrcp_cmd_frame(parms)->operandLen); + if ( btif_get_avrcp_cmd_frame(parms)->operands[7] == BTIF_AVRCP_EID_VOLUME_CHANGED){ + APP_A2DP_TRACE(1,"::avrcp_callback_TG AVRCP_EID_VOLUME_CHANGED transId:%d\n", btif_get_avrcp_cmd_frame(parms)->transId); + if (app_bt_device.avrcp_notify_rsp[device_id] == NULL) + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_notify_rsp[device_id]); + + //app_bt_device.avrcp_notify_rsp[device_id]->transId = btif_get_avrcp_cmd_frame(parms)->transId; + //app_bt_device.avrcp_notify_rsp[device_id]->ctype = BTIF_AVCTP_RESPONSE_INTERIM; + btif_avrcp_set_notify_rsp_cmd(app_bt_device.avrcp_notify_rsp[device_id],btif_get_avrcp_cmd_frame(parms)->transId, BTIF_AVCTP_RESPONSE_INTERIM) ; + app_bt_device.volume_report[device_id] = BTIF_AVCTP_RESPONSE_INTERIM; + + //status = AVRCP_CtGetAbsoluteVolume_Rsp(chnl, app_bt_device.avrcp_notify_rsp[device_id], a2dp_volume_get()); + status = btif_avrcp_ct_get_absolute_volume_rsp(channel, app_bt_device.avrcp_notify_rsp[device_id], a2dp_volume_get(device_id)); + APP_A2DP_TRACE(1,"::avrcp_callback_TG AVRCP_EVENT_COMMAND AVRCP_EID_VOLUME_CHANGED nRet:%x\n",status); + } + } + break; + case BTIF_AVRCP_EVENT_ADV_CMD_TIMEOUT: + APP_A2DP_TRACE(2,"::avrcp_callback_TG AVRCP_EVENT_ADV_CMD_TIMEOUT device_id=%d,role=%x\n",device_id,btif_get_avrcp_channel_role(channel)); + break; + } +} + +#endif + + +avrcp_media_status_t media_status = 0xff; +uint8_t avrcp_get_media_status(void) +{ + APP_A2DP_TRACE(2,"%s %d",__func__, media_status); + return media_status; +} + uint8_t avrcp_ctrl_music_flag; +void avrcp_set_media_status(uint8_t status) +{ + APP_A2DP_TRACE(2,"%s %d",__func__, status); + if ((status == 1 && avrcp_ctrl_music_flag == 2) || (status == 2 && avrcp_ctrl_music_flag == 1)) + avrcp_ctrl_music_flag = 0; + + + media_status = status; +} + + + + + +#else +void a2dp_init(void) +{ + for(uint8_t i=0; ievent %d\n", Parms->event); + switch(Parms->event) + { + case AVRCP_EVENT_CONNECT_IND: + TRACE(1,"::AVRCP_EVENT_CONNECT_IND %d\n", Parms->event); + AVRCP_ConnectRsp(chnl, 1); + break; + case AVRCP_EVENT_CONNECT: + TRACE(1,"::AVRCP_EVENT_CONNECT %d\n", Parms->event); + break; + case AVRCP_EVENT_RESPONSE: + TRACE(1,"::AVRCP_EVENT_RESPONSE %d\n", Parms->event); + + break; + case AVRCP_EVENT_PANEL_CNF: + TRACE(3,"::AVRCP_EVENT_PANEL_CNF %x,%x,%x", + Parms->p.panelCnf.response,Parms->p.panelCnf.operation,Parms->p.panelCnf.press); +#if 0 + if((Parms->p.panelCnf.response == AVCTP_RESPONSE_ACCEPTED) && (Parms->p.panelCnf.press == TRUE)) + { + AVRCP_SetPanelKey(chnl,Parms->p.panelCnf.operation,FALSE); + } +#endif + break; + } +} +#endif +//void avrcp_init(void) +//{ +// hal_uart_open(HAL_UART_ID_0,NULL); +// TRACE(0,"avrcp_init...OK\n"); +//} + + + + +int store_sbc_buffer(unsigned char *buf, unsigned int len); +int a2dp_audio_sbc_set_frame_info(int rcv_len, int frame_num); + +void btapp_send_pause_key(enum BT_DEVICE_ID_T stream_id) +{ + TRACE(1,"btapp_send_pause_key id = %x",stream_id); + btif_avrcp_set_panel_key(app_bt_device.avrcp_channel[stream_id],BTIF_AVRCP_POP_PAUSE,TRUE); + btif_avrcp_set_panel_key(app_bt_device.avrcp_channel[stream_id],BTIF_AVRCP_POP_PAUSE,FALSE); + // app_bt_device.a2dp_play_pause_flag = 0; +} + + +void btapp_a2dp_suspend_music(enum BT_DEVICE_ID_T stream_id) +{ + TRACE(1,"btapp_a2dp_suspend_music id = %x",stream_id); + + btapp_send_pause_key(stream_id); +} + +extern enum AUD_SAMPRATE_T a2dp_sample_rate; + +#define A2DP_TIMESTAMP_TRACE(s,...) +//TRACE(s, ##__VA_ARGS__) + +#define A2DP_TIMESTAMP_DEBOUNCE_DURATION (1000) +#define A2DP_TIMESTAMP_MODE_SAMPLE_THRESHOLD (2000) + +#define A2DP_TIMESTAMP_SYNC_LIMIT_CNT (100) +#define A2DP_TIMESTAMP_SYNC_TIME_THRESHOLD (60) +#define A2DP_TIMESTAMP_SYNC_SAMPLE_THRESHOLD ((int64_t)a2dp_sample_rate*A2DP_TIMESTAMP_SYNC_TIME_THRESHOLD/1000) + +#define RICE_THRESHOLD +#define RICE_THRESHOLD + +struct A2DP_TIMESTAMP_INFO_T{ + uint16_t rtp_timestamp; + uint32_t loc_timestamp; + uint16_t frame_num; + int32_t rtp_timestamp_diff_sum; +}; + +enum A2DP_TIMESTAMP_MODE_T{ + A2DP_TIMESTAMP_MODE_NONE, + A2DP_TIMESTAMP_MODE_SAMPLE, + A2DP_TIMESTAMP_MODE_TIME, +}; + +enum A2DP_TIMESTAMP_MODE_T a2dp_timestamp_mode = A2DP_TIMESTAMP_MODE_NONE; + +struct A2DP_TIMESTAMP_INFO_T a2dp_timestamp_pre = {0,0,0}; +bool a2dp_timestamp_parser_need_sync = false; + +int a2dp_timestamp_parser_init(void) +{ + a2dp_timestamp_mode = A2DP_TIMESTAMP_MODE_NONE; + a2dp_timestamp_pre.rtp_timestamp = 0; + a2dp_timestamp_pre.loc_timestamp = 0; + a2dp_timestamp_pre.frame_num = 0; + a2dp_timestamp_pre.rtp_timestamp_diff_sum = 0; + a2dp_timestamp_parser_need_sync = false; + return 0; +} + +int a2dp_timestamp_parser_needsync(void) +{ + a2dp_timestamp_parser_need_sync = true; + return 0; +} + +int a2dp_timestamp_parser_run(uint16_t timestamp, uint16_t framenum) +{ + static int skip_cnt = 0; + struct A2DP_TIMESTAMP_INFO_T curr_timestamp; + int skipframe = 0; + uint16_t rtpdiff; + int32_t locdiff; + bool needsave_rtp_timestamp = true; + bool needsave_loc_timestamp = true; + + curr_timestamp.rtp_timestamp = timestamp; + curr_timestamp.loc_timestamp = hal_sys_timer_get(); + curr_timestamp.frame_num = framenum; + + switch(a2dp_timestamp_mode) { + case A2DP_TIMESTAMP_MODE_NONE: + +// TRACE(5,"parser rtp:%d loc:%d num:%d prertp:%d preloc:%d\n", curr_timestamp.rtp_timestamp, curr_timestamp.loc_timestamp, curr_timestamp.frame_num, +// a2dp_timestamp_pre.rtp_timestamp, a2dp_timestamp_pre.loc_timestamp); + if (a2dp_timestamp_pre.rtp_timestamp){ + locdiff = curr_timestamp.loc_timestamp - a2dp_timestamp_pre.loc_timestamp; + if (TICKS_TO_MS(locdiff) > A2DP_TIMESTAMP_DEBOUNCE_DURATION){ + rtpdiff = curr_timestamp.rtp_timestamp - a2dp_timestamp_pre.rtp_timestamp; + if (ABS((int16_t)TICKS_TO_MS(locdiff)-rtpdiff)>A2DP_TIMESTAMP_MODE_SAMPLE_THRESHOLD){ + a2dp_timestamp_mode = A2DP_TIMESTAMP_MODE_SAMPLE; + TRACE(0,"A2DP_TIMESTAMP_MODE_SAMPLE\n"); + }else{ + a2dp_timestamp_mode = A2DP_TIMESTAMP_MODE_TIME; + TRACE(0,"A2DP_TIMESTAMP_MODE_TIME\n"); + } + }else{ + needsave_rtp_timestamp = false; + needsave_loc_timestamp = false; + } + } + break; + case A2DP_TIMESTAMP_MODE_SAMPLE: + if (a2dp_timestamp_parser_need_sync){ + skip_cnt++; + rtpdiff = curr_timestamp.rtp_timestamp - a2dp_timestamp_pre.rtp_timestamp; + locdiff = curr_timestamp.loc_timestamp - a2dp_timestamp_pre.loc_timestamp; + a2dp_timestamp_pre.rtp_timestamp_diff_sum += rtpdiff; + + A2DP_TIMESTAMP_TRACE(3,"%d-%d=%d", curr_timestamp.rtp_timestamp, a2dp_timestamp_pre.rtp_timestamp, rtpdiff); + + A2DP_TIMESTAMP_TRACE(3,"%d-%d=%d", curr_timestamp.loc_timestamp , a2dp_timestamp_pre.loc_timestamp, locdiff); + + A2DP_TIMESTAMP_TRACE(3,"%d-%d=%d", (int32_t)((int64_t)(TICKS_TO_MS(locdiff))*(uint32_t)a2dp_sample_rate/1000), + a2dp_timestamp_pre.rtp_timestamp_diff_sum, + (int32_t)((TICKS_TO_MS(locdiff)*a2dp_sample_rate/1000) - a2dp_timestamp_pre.rtp_timestamp_diff_sum)); + + + A2DP_TIMESTAMP_TRACE(2,"A2DP_TIMESTAMP_MODE_SAMPLE SYNC diff:%d cnt:%d\n", (int32_t)((int64_t)(TICKS_TO_MS(locdiff)*a2dp_sample_rate/1000) - a2dp_timestamp_pre.rtp_timestamp_diff_sum), skip_cnt); + if (((int64_t)(TICKS_TO_MS(locdiff)*a2dp_sample_rate/1000) - a2dp_timestamp_pre.rtp_timestamp_diff_sum) < (int32_t)A2DP_TIMESTAMP_SYNC_SAMPLE_THRESHOLD){ + TRACE(1,"A2DP_TIMESTAMP_MODE_SAMPLE RESYNC OK cnt:%d\n", skip_cnt); + skip_cnt = 0; + a2dp_timestamp_parser_need_sync = false; + }else if (skip_cnt > A2DP_TIMESTAMP_SYNC_LIMIT_CNT){ + TRACE(0,"A2DP_TIMESTAMP_MODE_SAMPLE RESYNC FORCE END\n"); + skip_cnt = 0; + a2dp_timestamp_parser_need_sync = false; + }else{ + needsave_loc_timestamp = false; + skipframe = 1; + } + }else{ + a2dp_timestamp_pre.rtp_timestamp_diff_sum = 0; + } + break; + case A2DP_TIMESTAMP_MODE_TIME: + if (a2dp_timestamp_parser_need_sync){ + skip_cnt++; + rtpdiff = curr_timestamp.rtp_timestamp - a2dp_timestamp_pre.rtp_timestamp; + locdiff = curr_timestamp.loc_timestamp - a2dp_timestamp_pre.loc_timestamp; + a2dp_timestamp_pre.rtp_timestamp_diff_sum += rtpdiff; + + A2DP_TIMESTAMP_TRACE(5,"%d/%d/ %d/%d %d\n", rtpdiff,a2dp_timestamp_pre.rtp_timestamp_diff_sum, + a2dp_timestamp_pre.loc_timestamp, curr_timestamp.loc_timestamp, + TICKS_TO_MS(locdiff)); + A2DP_TIMESTAMP_TRACE(2,"A2DP_TIMESTAMP_MODE_TIME SYNC diff:%d cnt:%d\n", (int32_t)ABS(TICKS_TO_MS(locdiff) - a2dp_timestamp_pre.rtp_timestamp_diff_sum), skip_cnt); + if (((int64_t)TICKS_TO_MS(locdiff) - a2dp_timestamp_pre.rtp_timestamp_diff_sum) < A2DP_TIMESTAMP_SYNC_TIME_THRESHOLD){ + TRACE(1,"A2DP_TIMESTAMP_MODE_TIME RESYNC OK cnt:%d\n", skip_cnt); + skip_cnt = 0; + needsave_loc_timestamp = false; + a2dp_timestamp_parser_need_sync = false; + }else if (skip_cnt > A2DP_TIMESTAMP_SYNC_LIMIT_CNT){ + TRACE(0,"A2DP_TIMESTAMP_MODE_TIME RESYNC FORCE END\n"); + skip_cnt = 0; + a2dp_timestamp_parser_need_sync = false; + }else{ + needsave_loc_timestamp = false; + skipframe = 1; + } + }else{ + a2dp_timestamp_pre.rtp_timestamp_diff_sum = 0; + } + break; + } + + if (needsave_rtp_timestamp){ + a2dp_timestamp_pre.rtp_timestamp = curr_timestamp.rtp_timestamp; + } + + if (needsave_loc_timestamp){ + a2dp_timestamp_pre.loc_timestamp = curr_timestamp.loc_timestamp; + } + + return skipframe; +} + +static struct BT_DEVICE_ID_DIFF stream_id_flag; + +#if defined(A2DP_LHDC_ON) +uint8_t bits_depth; +uint8_t bt_sbc_player_get_bitsDepth(void){ + if (app_bt_device.sample_bit[stream_id_flag.id] != bits_depth) { + /* code */ + bits_depth = app_bt_device.sample_bit[stream_id_flag.id]; + } + return bits_depth; +} +#endif + + +#ifdef __BT_ONE_BRING_TWO__ + + +uint8_t a2dp_stream_id_distinguish(a2dp_stream_t *Stream , uint8_t event_type) +{ + uint8_t found_device_id = BT_DEVICE_NUM; + if(Stream == app_bt_device.a2dp_connected_stream[BT_DEVICE_ID_1]) + { + found_device_id = BT_DEVICE_ID_1; + stream_id_flag.id = BT_DEVICE_ID_1; + } + else if(Stream == app_bt_device.a2dp_connected_stream[BT_DEVICE_ID_2]) + { + found_device_id = BT_DEVICE_ID_2; + stream_id_flag.id = BT_DEVICE_ID_2; + }else/* if(event_type == A2DP_EVENT_STREAM_CLOSED)*/{ + btif_remote_device_t * remDev = 0; + btif_remote_device_t * connected_remDev[BT_DEVICE_NUM]; + remDev = btif_a2dp_get_remote_device(Stream); + connected_remDev[0] = btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[BT_DEVICE_ID_1]); + connected_remDev[1] = btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[BT_DEVICE_ID_2]); + if((connected_remDev[0] == remDev) && (remDev!= 0)){ + stream_id_flag.id = BT_DEVICE_ID_1; + found_device_id = BT_DEVICE_ID_1; + } + else if((connected_remDev[1] == remDev) && (remDev !=0)){ + stream_id_flag.id = BT_DEVICE_ID_2; + found_device_id = BT_DEVICE_ID_2; + } + } + return found_device_id; +} + +uint8_t POSSIBLY_UNUSED a2dp_get_streaming_id(void) +{ + uint8_t nRet = 0; + if( btif_a2dp_get_stream_state(app_bt_device.a2dp_connected_stream[BT_DEVICE_ID_1]) == BTIF_AVDTP_STRM_STATE_STREAMING) + nRet |= 1<<0; + if(btif_a2dp_get_stream_state(app_bt_device.a2dp_connected_stream[BT_DEVICE_ID_2]) == BTIF_AVDTP_STRM_STATE_STREAMING) + nRet |= 1<<1; + return nRet; +} + +/* profile pass to here 2 states, if no will to change it, call api to confirm it */ +uint8_t a2dp_stream_confirm_stream_state(uint8_t index, uint8_t old_state, uint8_t new_state) +{ + return a2dp_codec_confirm_stream_state(index, old_state, new_state); +} + +uint8_t a2dp_stream_locate_the_connected_dev_id(a2dp_stream_t *Stream) +{ + for (uint8_t index = 0;index < BT_DEVICE_NUM;index++) + { + if ((app_bt_device.a2dp_stream[index]->a2dp_stream) == Stream) + { + TRACE(1,"Get a2dp stream index %d", index); + return index; + } + + #if defined(A2DP_AAC_ON) + if ((app_bt_device.a2dp_aac_stream[index]->a2dp_stream) == Stream) + { + TRACE(1,"Get a2dp aac stream index %d", index); + return index; + } + #endif +#if defined(A2DP_LHDC_ON) + if ((app_bt_device.a2dp_lhdc_stream[index]->a2dp_stream) == Stream) + { + TRACE(1,"Get a2dp lhdc stream index %d", index); + return index; + } +#endif + +#if defined(A2DP_SCALABLE_ON) + if ((app_bt_device.a2dp_scalable_stream[index]->a2dp_stream) == Stream) + { + TRACE(1,"Get a2dp scalable stream index %d", index); + return index; + } +#endif + +#if defined(A2DP_LDAC_ON) + if ((app_bt_device.a2dp_ldac_stream[index]->a2dp_stream) == Stream) + { + TRACE(1,"Get a2dp ldac stream index %d", index); + return index; + } +#endif + + } + + ASSERT(false, "Connected to an non-existing a2dp stream instance."); + + return 0; +} + +void a2dp_stream_push_connected_stream(a2dp_stream_t *Stream) +{ + + uint8_t reserved_device = BT_DEVICE_NUM; + reserved_device = a2dp_stream_locate_the_connected_dev_id(Stream); + app_bt_device.a2dp_connected_stream[reserved_device] = Stream; +} + +void a2dp_stream_push_configed_stream(a2dp_stream_t *Stream,btif_remote_device_t *rem) +{ + uint8_t reserved_device = BT_DEVICE_NUM; + reserved_device = a2dp_stream_locate_the_connected_dev_id(Stream); + app_bt_device.a2dp_outconfiged_stream[reserved_device] = Stream; + app_bt_device.a2dp_outconfiged_rem[reserved_device] = rem; + +} + +#ifdef A2DP_AAC_ON +uint8_t is_aac_stream(a2dp_stream_t *Stream) +{ + if((Stream == app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream) + || (Stream == app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_2]->a2dp_stream)) + return TRUE; + else + return FALSE; +} +#endif +#endif + + +#if defined( __BTIF_EARPHONE__) && defined(__BTIF_BT_RECONNECT__) + +#ifdef __BT_ONE_BRING_TWO__ +extern btif_device_record_t record2_copy; +extern uint8_t record2_avalible; +#endif + +#endif + +#if defined(A2DP_LHDC_ON) +void a2dp_lhdc_config(uint8_t * elements){ + //uint8_t * elements = &(Info->p.configReq->codec.elements[0]); + uint32_t vendor_id = (uint32_t)elements[0]; + vendor_id |= ((uint32_t)elements[1]) << 8; + vendor_id |= ((uint32_t)elements[2]) << 16; + vendor_id |= ((uint32_t)elements[3]) << 24; + uint16_t codec_id = (uint16_t)elements[4]; + codec_id |= ((uint16_t)elements[5]) << 8; + uint8_t config = elements[6]; + TRACE(3,"##codecType: LHDC Codec, config value = 0x%02x, elements[6]=0x%02x elements[7]=0x%02x\n", A2DP_LHDC_SR_DATA(config), elements[6], elements[7]); + if (vendor_id == A2DP_LHDC_VENDOR_ID && codec_id == A2DP_LHDC_CODEC_ID) { + TRACE(2,"Vendor ID = 0x%08x, Codec ID = 0x%04x, LHDC Codec\n", vendor_id, codec_id); + switch (A2DP_LHDC_SR_DATA(config)) { + case A2DP_LHDC_SR_96000: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_96; + TRACE(1,"%s:CodecCfg sample_rate 96000\n", __func__); + break; + case A2DP_LHDC_SR_48000: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_48; + TRACE(1,"%s:CodecCfg sample_rate 48000\n", __func__); + break; + case A2DP_LHDC_SR_44100: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_44; + TRACE(1,"%s:CodecCfg sample_rate 44100\n", __func__); + break; + } + switch (A2DP_LHDC_FMT_DATA(config)) { + case A2DP_LHDC_FMT_16: + app_bt_device.sample_bit[stream_id_flag.id] = 16; + TRACE(1,"%s:CodecCfg bits per sampe = 16", __func__); + break; + case A2DP_LHDC_FMT_24: + TRACE(1,"%s:CodecCfg bits per sampe = 24", __func__); + app_bt_device.sample_bit[stream_id_flag.id] = 24; + break; + } + + if (elements[7]&A2DP_LHDC_LLC_ENABLE){ + app_bt_device.a2dp_lhdc_llc[stream_id_flag.id] = true;; + }else{ + app_bt_device.a2dp_lhdc_llc[stream_id_flag.id] = false;; + } + } +} + +uint8_t a2dp_lhdc_config_llc_get(void) +{ + return app_bt_device.a2dp_lhdc_llc[stream_id_flag.id]; +} + +#endif + +#if defined(A2DP_SCALABLE_ON) +void a2dp_scalable_config(uint8_t * elements){ + //uint8_t * elements = &(Info->p.configReq->codec.elements[0]); + uint32_t vendor_id = (uint32_t)elements[0]; + vendor_id |= ((uint32_t)elements[1]) << 8; + vendor_id |= ((uint32_t)elements[2]) << 16; + vendor_id |= ((uint32_t)elements[3]) << 24; + uint16_t codec_id = (uint16_t)elements[4]; + codec_id |= ((uint16_t)elements[5]) << 8; + uint8_t config = elements[6]; + TRACE(2,"##codecType: Scalable Codec, config value = 0x%02x, elements[6]=0x%02x\n", A2DP_SCALABLE_SR_DATA(config), elements[6]); + if (vendor_id == A2DP_SCALABLE_VENDOR_ID && codec_id == A2DP_SCALABLE_CODEC_ID) { + TRACE(2,"Vendor ID = 0x%08x, Codec ID = 0x%04x, Scalable Codec\n", vendor_id, codec_id); + switch (A2DP_SCALABLE_SR_DATA(config)) { + case A2DP_SCALABLE_SR_96000: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_96; + TRACE(1,"%s:CodecCfg sample_rate 96000\n", __func__); + break; + case A2DP_SCALABLE_SR_48000: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_48; + TRACE(1,"%s:CodecCfg sample_rate 48000\n", __func__); + break; + case A2DP_SCALABLE_SR_44100: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_44; + TRACE(1,"%s:CodecCfg sample_rate 44100\n", __func__); + break; + case A2DP_SCALABLE_SR_32000: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_32; + TRACE(1,"%s:CodecCfg sample_rate 32000\n", __func__); + break; + } + switch (A2DP_SCALABLE_FMT_DATA(config)) { + case A2DP_SCALABLE_FMT_16: + app_bt_device.sample_bit[stream_id_flag.id] = 16; + TRACE(1,"%s:CodecCfg bits per sampe = 16", __func__); + break; + case A2DP_SCALABLE_FMT_24: + app_bt_device.sample_bit[stream_id_flag.id] = 24; + TRACE(1,"%s:CodecCfg bits per sampe = 24", __func__); + if (app_bt_device.sample_rate[stream_id_flag.id] != A2D_SBC_IE_SAMP_FREQ_96) { + app_bt_device.sample_bit[stream_id_flag.id] = 16; + TRACE(1,"%s:CodeCfg reset bit per sample to 16 when samplerate is not 96k", __func__); + } + break; + } + } +} +#endif + +#if defined(A2DP_LDAC_ON) +int ldac_decoder_sf = 0; +int ldac_decoder_cm = 0; +void a2dp_ldac_config(uint8_t * elements){ + //uint8_t * elements = &(Info->p.configReq->codec.elements[0]); + uint32_t vendor_id = (uint32_t)elements[0]; + vendor_id |= ((uint32_t)elements[1]) << 8; + vendor_id |= ((uint32_t)elements[2]) << 16; + vendor_id |= ((uint32_t)elements[3]) << 24; + uint16_t codec_id = (uint16_t)elements[4]; + codec_id |= ((uint16_t)elements[5]) << 8; + uint8_t sf_config = elements[6]; + uint8_t cm_config = elements[7]; + TRACE(2,"##codecType: LDAC Codec, config value = 0x%02x, elements[6]=0x%02x\n", A2DP_LDAC_SR_DATA(sf_config), elements[6]); + TRACE(2,"##codecType: LDAC Codec, config value = 0x%02x, elements[7]=0x%02x\n", A2DP_LDAC_CM_DATA(cm_config), elements[7]); + TRACE(2,"Vendor ID = 0x%08x, Codec ID = 0x%04x, LDAC Codec\n", vendor_id, codec_id); + if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) { + switch (A2DP_LDAC_SR_DATA(sf_config)) { + case A2DP_LDAC_SR_96000: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_96; + ldac_decoder_sf = 96000; + TRACE(1,"%s:ldac CodecCfg sample_rate 96000\n", __func__); + break; + case A2DP_LDAC_SR_88200: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_88; + ldac_decoder_sf = 88200; + TRACE(1,"%s:ldac CodecCfg sample_rate 88200\n", __func__); + break; + case A2DP_LDAC_SR_48000: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_48; + ldac_decoder_sf = 48000; + TRACE(1,"%s:ldac CodecCfg sample_rate 48000\n", __func__); + break; + case A2DP_LDAC_SR_44100: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_44; + ldac_decoder_sf = 44100; + TRACE(1,"%sldac :CodecCfg sample_rate 44100\n", __func__); + break; + /*case A2DP_LDAC_SR_88200: + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_88; + ldac_decoder_sf = 88200; + TRACE(1,"%s:ldac CodecCfg sample_rate 88200\n", __func__); + break;*/ + } + switch (A2DP_LDAC_CM_DATA(cm_config)) { + case A2DP_LDAC_CM_MONO: + app_bt_device.channel_mode = LDACBT_CHANNEL_MODE_MONO; + TRACE(1,"%s:ldac CodecCfg A2DP_LDAC_CM_MONO", __func__); + break; + case A2DP_LDAC_CM_DUAL: + TRACE(1,"%s:ldac CodecCfg A2DP_LDAC_CM_DUAL", __func__); + app_bt_device.channel_mode = LDACBT_CHANNEL_MODE_DUAL_CHANNEL; + break; + case A2DP_LDAC_CM_STEREO: + TRACE(1,"%s:ldac ldac CodecCfg A2DP_LDAC_CM_STEREO", __func__); + app_bt_device.channel_mode = LDACBT_CHANNEL_MODE_STEREO; + break; + } + } +} + +void app_ibrt_restore_ldac_info(uint8_t sample_freq) +{ + app_bt_device.channel_mode=LDACBT_CHANNEL_MODE_STEREO; + switch (sample_freq) + { + case A2D_SBC_IE_SAMP_FREQ_96: + ldac_decoder_sf = 96000; + break; + case A2D_SBC_IE_SAMP_FREQ_88: + ldac_decoder_sf = 88200; + break; + case A2D_SBC_IE_SAMP_FREQ_48: + ldac_decoder_sf = 48000; + break; + case A2D_SBC_IE_SAMP_FREQ_44: + ldac_decoder_sf = 44100; + break; + } +} + + +int channel_mode; +int bt_ldac_player_get_channelmode(void){ + if (app_bt_device.channel_mode != channel_mode) { + /* code */ + channel_mode = app_bt_device.channel_mode; + } + return channel_mode; +} +int bt_get_ladc_sample_rate(void){ + + return ldac_decoder_sf; +} + +#endif + + + +extern void app_bt_profile_connect_manager_a2dp(enum BT_DEVICE_ID_T id, a2dp_stream_t *Stream, const a2dp_callback_parms_t *Info); + +#ifdef __BT_ONE_BRING_TWO__ + + +void a2dp_dual_slave_setup_during_sco(enum BT_DEVICE_ID_T currentId) +{ + if (app_bt_device.a2dp_state[BT_DEVICE_ID_1] || + app_bt_device.a2dp_state[BT_DEVICE_ID_2]) + { + uint8_t activeDevice = currentId; + uint8_t idleDevice = (BT_DEVICE_ID_1 == activeDevice)?BT_DEVICE_ID_2:BT_DEVICE_ID_1; + + btif_remote_device_t* activeRem = + btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[activeDevice]); + btif_remote_device_t* idleRem = + btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[idleDevice]); + + + TRACE(2,"activeRem %p idleRem %p", activeRem, idleRem); + if (idleRem && activeRem) + { + btdrv_enable_dual_slave_configurable_slot_mode(true, + btif_me_get_remote_device_hci_handle(activeRem), + btif_me_get_remote_device_role(activeRem), + btif_me_get_remote_device_hci_handle(idleRem), + btif_me_get_remote_device_role(idleRem)); + } + else + { + btdrv_enable_dual_slave_configurable_slot_mode(false, + 0x80, + BTIF_BCR_SLAVE, + 0x81, + BTIF_BCR_SLAVE); + } + } + else + { + btdrv_enable_dual_slave_configurable_slot_mode(false, + 0x80, + BTIF_BCR_SLAVE, + 0x81, + BTIF_BCR_SLAVE); + } +} + + +void a2dp_dual_slave_handling_refresh(void) +{ + if (app_bt_device.a2dp_state[BT_DEVICE_ID_1] || + app_bt_device.a2dp_state[BT_DEVICE_ID_2]) + { + TRACE(1,"current a2dp streaming id %d", app_bt_device.curr_a2dp_stream_id); + uint8_t activeDevice = app_bt_device.curr_a2dp_stream_id; + uint8_t idleDevice = (BT_DEVICE_ID_1 == activeDevice)?BT_DEVICE_ID_2:BT_DEVICE_ID_1; + + btif_remote_device_t* activeRem = + btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[activeDevice]); + btif_remote_device_t* idleRem = + btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[idleDevice]); + TRACE(2,"activeRem %p idleRem %p", activeRem, idleRem); + if (idleRem && activeRem) + { + btdrv_enable_dual_slave_configurable_slot_mode(true, + btif_me_get_remote_device_hci_handle(activeRem), + btif_me_get_remote_device_role(activeRem), + btif_me_get_remote_device_hci_handle(idleRem), + btif_me_get_remote_device_role(idleRem)); + } + else + { + btdrv_enable_dual_slave_configurable_slot_mode(false, + 0x80, + BTIF_BCR_SLAVE, + 0x81, + BTIF_BCR_SLAVE); + } + } + else + { + btdrv_enable_dual_slave_configurable_slot_mode(false, + 0x80, + BTIF_BCR_SLAVE, + 0x81, + BTIF_BCR_SLAVE); + } +} + +void a2dp_update_music_link(void) +{ + TRACE(1,"current a2dp streaming id %d", app_bt_device.curr_a2dp_stream_id); + uint8_t activeDevice = app_bt_device.curr_a2dp_stream_id; + uint8_t idleDevice = (BT_DEVICE_ID_1 == activeDevice)?BT_DEVICE_ID_2:BT_DEVICE_ID_1; + + btif_remote_device_t* activeRem = + btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[activeDevice]); + btif_remote_device_t* idleRem = + btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[idleDevice]); + TRACE(2,"activeRem %p idleRem %p", activeRem, idleRem); + if (idleRem && activeRem) + { + bt_drv_reg_op_music_link_config( + btif_me_get_remote_device_hci_handle(activeRem), + btif_me_get_remote_device_role(activeRem), + btif_me_get_remote_device_hci_handle(idleRem), + btif_me_get_remote_device_role(idleRem)); + } + else if(activeRem) + { + bt_drv_reg_op_music_link_config( + btif_me_get_remote_device_hci_handle(activeRem), + btif_me_get_remote_device_role(activeRem), + 0xff, + BTIF_BCR_SLAVE); + } + +} + +#endif + +uint8_t a2dp_get_latest_paused_device(void) +{ + return app_bt_device.latestPausedDevId; +} + +#ifdef __BT_ONE_BRING_TWO__ +#if !defined(__BT_SELECT_PROF_DEVICE_ID__) +static void a2dp_avdtp_stream_state_lock_management(a2dp_stream_t *Stream, const a2dp_callback_parms_t *info) +{ + btif_a2dp_callback_parms_t * Info = (btif_a2dp_callback_parms_t *)info; + + static uint8_t last_locked_configedid = 0xff; + if(Info->error!=BTIF_AVDTP_ERR_NO_ERROR) + return; + switch(Info->event) + { + + case BTIF_A2DP_AVDTP_EVENT_SET_CFG_CNF: //-->set config + LOG_D(0,"outgoing set cfg"); + //record the outgoing configed stream and rem + a2dp_stream_push_configed_stream(Stream,Info->remDev); + break; + + case BTIF_A2DP_EVENT_STREAM_RECONFIG_CNF: //reconfig--> + case BTIF_A2DP_EVENT_STREAM_RECONFIG_IND: //rsp reconfig <-- + + + case BTIF_A2DP_EVENT_STREAM_OPEN_IND: //set configed <-- + case BTIF_A2DP_EVENT_STREAM_OPEN: //after avdtp open rsp AVDTP medio connected + + LOG_E(2,"evt %d STREAM %p ",Info->event,Stream); + btif_a2dp_lock_same_deviceid_endpoint(Stream,Info->remDev); + break; + case BTIF_A2DP_EVENT_AVDTP_CLOSE_IND: + case BTIF_A2DP_EVENT_STREAM_CLOSED: //unlock the stream state before the connected stream been released + + LOG_E(2,"evt %d STREAM %p ",Info->event,Stream); + btif_a2dp_unlock_same_deviceid_endpoint(Stream,Info->remDev); + break; + case BTIF_A2DP_EVENT_AVDTP_DISCOVER_IND://<-- discover + + LOG_E(0,"DISCOVER_IND"); + btif_a2dp_unlock_the_connected_stream_byRemdev(Info->remDev); + + //lock the other id + last_locked_configedid =btif_a2dp_trylock_the_other_id_by_configedid(Info->remDev); + break; + case BTIF_A2DP_EVENT_AVDTP_DISCOVER_RSP: + LOG_D(0,"disc rsp"); + btif_a2dp_unlock_deviceid_endpoint(last_locked_configedid); + break; + default: + + break; + } +} +#endif +#endif + +#if defined(__BT_SELECT_PROF_DEVICE_ID__) +static void _a2dp_select_stream(a2dp_stream_t *Stream, a2dp_callback_parms_t *info) +{ + uint32_t i = 0, stream_is_on_device_id = 0; + a2dp_stream_t *dst_stream = NULL; + btif_remote_device_t *matching_remdev = NULL, *wanted_remdev = NULL; + // 1. find already connected profile, if any other one profile was conncected, select that device id + // 2. if no other profile connected, select min device id + btif_a2dp_set_dst_stream(info, Stream); + wanted_remdev = btif_a2dp_get_remote_device_from_cbparms(Stream, info); + for(i = 0 ; i < BT_DEVICE_NUM ; i++) { + // Other profile connected + stream_is_on_device_id = app_bt_a2dp_is_stream_on_device_id(Stream, i); + if (app_bt_is_any_profile_connected(i)) { + matching_remdev = app_bt_get_connected_profile_remdev(i); + LOG_D(3,"device_id=%d, a2dp_select_stream : remdev=0x%x:0x%x.", i, wanted_remdev, matching_remdev); + LOG_D(1,"device_id=%d, a2dp_select_stream : other_profile_connected.", i); + if (wanted_remdev == matching_remdev) { + LOG_D(1,"device_id=%d, a2dp_select_stream : same_remdev.", i); + // SWITCH COND 1 : same remdev but cross device id to select stream + if (!stream_is_on_device_id) { + app_bt_a2dp_find_same_unused_stream(Stream, &dst_stream, i); + btif_a2dp_set_dst_stream(info, dst_stream); + LOG_D(3,"device_id=%d, a2dp_select_stream : Switch_cond 1 : 0x%x:0x%x", i, Stream, dst_stream); + } + else { + LOG_D(1,"device_id=%d, a2dp_select_stream : same device id, no_need_to_switch.", i); + } + break; + } + else { + LOG_D(1,"device_id=%d, a2dp_select_stream : different_remdev.", i); + if (stream_is_on_device_id) { + LOG_D(1,"device_id=%d, a2dp_select_stream : error : different_remdev_but_same_device_id, see next device id.", i); + } + else { + LOG_D(1,"device_id=%d, a2dp_select_stream : good : different_remdev_different_device_id, see next device id.", i); + } + } + } + else { + LOG_D(1,"device_id=%d, a2dp_select_stream : other_profile_not_connected.", i); + // first found idle device id is min device id we want + // Assume : other profile will use device id ascending + // TODO to keep other profile use device id ascending + if (!stream_is_on_device_id) { + app_bt_a2dp_find_same_unused_stream(Stream, &dst_stream, i); + btif_a2dp_set_dst_stream(info, dst_stream); + LOG_D(3,"device_id=%d, a2dp_select_stream : Switch_cond 2 : 0x%x:0x%x", i, Stream, dst_stream); + } + else { + LOG_D(1,"device_id=%d, a2dp_select_stream : same device id, no_need_to_switch.", i); + } + break; + } + } +} +#endif + +#if defined(IBRT) +a2dp_stream_t * app_bt_get_mobile_a2dp_stream(uint32_t deviceId); +int app_bt_stream_ibrt_audio_mismatch_stopaudio(void); +void app_bt_stream_ibrt_audio_mismatch_resume(void); + +static uint8_t a2dp_session = 0; +int a2dp_ibrt_session_reset(void) +{ + a2dp_session = 0; + return 0; +} + +int a2dp_ibrt_session_new(void) +{ + a2dp_session++; + return 0; +} + +int a2dp_ibrt_session_set(uint8_t session) +{ + a2dp_session = session; + return 0; +} + +uint32_t a2dp_ibrt_session_get(void) +{ + return a2dp_session; +} + +static int a2dp_ibrt_autotrigger_flag = 0; +int a2dp_ibrt_stream_need_autotrigger_set_flag(void) +{ + a2dp_ibrt_autotrigger_flag = 1; + return 0; +} + +int a2dp_ibrt_stream_need_autotrigger_getandclean_flag(void) +{ + uint32_t flag; +#if defined(IBRT_A2DP_TRIGGER_BY_MYSELF) + flag = a2dp_ibrt_autotrigger_flag; + a2dp_ibrt_autotrigger_flag = 0; +#else + a2dp_ibrt_autotrigger_flag = 0; + flag = 1; +#endif + return flag; +} + +int a2dp_ibrt_sync_get_status(ibrt_a2dp_status_t *a2dp_status) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_ibrt_if_get_bt_ctrl_ctx(); + a2dp_status->codec = p_ibrt_ctrl->a2dp_codec; + a2dp_status->volume = a2dp_volume_get(BT_DEVICE_ID_1); + a2dp_status->state = btif_a2dp_get_stream_state(app_bt_device.a2dp_connected_stream[BT_DEVICE_ID_1]); + a2dp_status->latency_factor = a2dp_audio_latency_factor_get(); + a2dp_status->session = a2dp_ibrt_session_get(); + TRACE(4,"%s,sync a2dp stream ac = %p ; stream_status = %d ; codec_type = %d ",__func__,app_bt_device.a2dp_connected_stream[BT_DEVICE_ID_1],a2dp_status->state,a2dp_status->codec.codec_type); + return 0; +} + + + +int a2dp_ibrt_sync_set_status(ibrt_a2dp_status_t *a2dp_status) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_ibrt_if_get_bt_ctrl_ctx(); + a2dp_stream_t *Stream = app_bt_get_mobile_a2dp_stream(BTIF_DEVICE_ID_1); + btif_avdtp_stream_state_t old_avdtp_stream_state = btif_a2dp_get_stream_state(Stream); + + btif_a2dp_callback_parms_t info; + btif_avdtp_config_request_t avdtp_config_req; + + + TRACE(5,"%s,stream_state:[%d]->[%d], codec_type:%d volume:%d", __func__, old_avdtp_stream_state, a2dp_status->state, a2dp_status->codec.codec_type, a2dp_status->volume); + + if ((!(p_ibrt_ctrl->mobile_constate & BTIF_APP_A2DP_PROFILE_ID)) && (!(p_ibrt_ctrl->ibrt_constate & BTIF_APP_A2DP_PROFILE_ID))) + { + TRACE(1,"%s,a2dp profile not connected",__func__); + return 1; + } + + btif_a2dp_set_codec_info(BTIF_DEVICE_ID_1, (uint8_t*)&a2dp_status->codec); + info.event = BTIF_A2DP_EVENT_STREAM_OPEN; + app_tws_ibrt_set_a2dp_codec(&info); + app_bt_stream_volume_ptr_update((uint8_t *) btif_me_get_remote_device_bdaddr(btif_a2dp_get_stream_conn_remDev(Stream))); + a2dp_volume_set(BT_DEVICE_ID_1, a2dp_status->volume); + a2dp_audio_latency_factor_set(a2dp_status->latency_factor); + a2dp_ibrt_session_set(a2dp_status->session); + + if (a2dp_status->state != old_avdtp_stream_state){ + switch(a2dp_status->state) { + case BTIF_AVDTP_STRM_STATE_STREAMING: + app_bt_clear_connecting_profiles_state(BTIF_DEVICE_ID_1); + a2dp_timestamp_parser_init(); + btif_a2dp_set_stream_state(Stream, a2dp_status->state); + info.event = BTIF_A2DP_EVENT_STREAM_STARTED_MOCK; + TRACE(0,"::A2DP_EVENT_STREAM_STARTED mock"); + a2dp_ibrt_stream_need_autotrigger_set_flag(); +#if defined(IBRT_FORCE_AUDIO_RETRIGGER) + a2dp_callback(Stream, &info); + app_ibrt_if_force_audio_retrigger(); +#else +// app_bt_stream_ibrt_audio_mismatch_resume(); + a2dp_callback(Stream, &info); +#endif + break; + case BTIF_AVDTP_STRM_STATE_OPEN: + //Ignore START->OPEN transition since itslef can received SUSPEND CMD + if (old_avdtp_stream_state != BTIF_AVDTP_STRM_STATE_STREAMING) + { + TRACE(0,"::A2DP_EVENT_STREAM_OPEN mock"); + btif_a2dp_set_stream_state(Stream, a2dp_status->state); + info.event = BTIF_A2DP_EVENT_STREAM_OPEN; + info.p.configReq = &avdtp_config_req; + info.p.configReq->codec.codecType = a2dp_status->codec.codec_type; + info.p.configReq->codec.elements = (uint8_t*)btif_a2dp_get_stream_codecCfg((a2dp_stream_t *)p_ibrt_ctrl->p_mobile_a2dp_profile)+2; + a2dp_callback(Stream, &info); + } + break; + default: + if (btif_a2dp_get_stream_state(Stream) != BTIF_AVDTP_STRM_STATE_IDLE){ + TRACE(0,"::A2DP_EVENT_STREAM_SUSPENDED mock"); + btif_a2dp_set_stream_state(Stream, a2dp_status->state); + info.event = BTIF_A2DP_EVENT_STREAM_SUSPENDED; + a2dp_callback(Stream, &info); + } + break; + } + } + return 0; +} + +int a2dp_ibrt_stream_open_mock(void) +{ + a2dp_stream_t *Stream = app_bt_get_mobile_a2dp_stream(BTIF_DEVICE_ID_1); + btif_remote_device_t *remDev = btif_a2dp_get_stream_conn_remDev(Stream); + + TRACE(0,"::A2DP_EVENT_STREAM_OPEN mock"); + + app_bt_clear_connecting_profiles_state(BTIF_DEVICE_ID_1); + a2dp_timestamp_parser_init(); + a2dp_set_cur_stream(stream_id_flag.id); + + if (remDev){ + btdevice_profile *btdevice_plf_p = NULL; + btdevice_plf_p = (btdevice_profile *)app_bt_profile_active_store_ptr_get(btif_me_get_remote_device_bdaddr(remDev)->address); + nv_record_btdevicerecord_set_a2dp_profile_active_state(btdevice_plf_p, true); + nv_record_btdevicerecord_set_a2dp_profile_codec(btdevice_plf_p, bt_sbc_player_get_codec_type()); + a2dp_get_current_codec_type(btif_a2dp_get_stream_codec(app_bt_device.a2dp_connected_stream[app_bt_device.curr_a2dp_stream_id])->elements); + app_bt_stream_volume_ptr_update((uint8_t *) btif_me_get_remote_device_bdaddr(remDev)); + TRACE(2,"::A2DP_EVENT_STREAM_OPEN mock codec_type:%d vol:%d", bt_sbc_player_get_codec_type(), app_bt_stream_volume_get_ptr()->a2dp_vol); + }else{ + TRACE(0,"::A2DP_EVENT_STREAM_OPEN mock no find remDev"); + app_bt_stream_volume_ptr_update(NULL); + } + + return 0; +} + +#ifdef __SNIFF_MODE_CHECK__ +osTimerId sniff_check_timer = NULL; +static void sniff_check_timer_handler(void const *param); +osTimerDef (SNIFF_CHECK_TIMER, (void (*)(void const *))sniff_check_timer_handler); // define timers +uint8_t sniff_timer_state=0; + +static void sniff_check_timer_handler(void const *param) +{ + ASSERT(0,"sniff mode error"); +} +#endif + + +#define A2DP_IBRT_STREAM_SKIP_TWS_SNIFF_STATUS (1) + +int a2dp_ibrt_stream_event_stream_data_ind_needskip(a2dp_stream_t *Stream) +{ + int nRet = 0; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); +#ifdef __SNIFF_MODE_CHECK__ + if(!sniff_check_timer) + sniff_check_timer = osTimerCreate(osTimer(SNIFF_CHECK_TIMER), osTimerOnce, NULL); +#endif + if (app_tws_ibrt_mobile_link_connected()){ + if (p_ibrt_ctrl->mobile_mode == IBRT_SNIFF_MODE){ + TRACE(0,"::A2DP_EVENT_STREAM_DATA_IND ibrt_link skip (mobile) skip sniff\n"); + nRet = 1; +#ifdef __SNIFF_MODE_CHECK__ + if(sniff_timer_state ==0) + { + sniff_timer_state =1; + osTimerStart(sniff_check_timer,5000); + } +#endif + } +#ifdef __SNIFF_MODE_CHECK__ + else + { + sniff_timer_state= 0; + osTimerStop(sniff_check_timer); + } +#endif + if (app_tws_ibrt_tws_link_connected()){ + if (app_ibrt_ui_is_profile_exchanged() && + p_ibrt_ctrl->tws_mode == IBRT_SNIFF_MODE){ + TRACE(0,"::A2DP_EVENT_STREAM_DATA_IND mobile_link (tws) skip sniff\n"); +#ifndef A2DP_IBRT_STREAM_SKIP_TWS_SNIFF_STATUS + nRet = 1; +#endif +#ifdef __SNIFF_MODE_CHECK__ + if(sniff_timer_state ==0) + { + sniff_timer_state =1; + osTimerStart(sniff_check_timer,5000); + } +#endif + } +#ifdef __SNIFF_MODE_CHECK__ + else + { + sniff_timer_state = 0; + osTimerStop(sniff_check_timer); + } +#endif + } + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + if (p_ibrt_ctrl->mobile_mode == IBRT_SNIFF_MODE){ + TRACE(0,"::A2DP_EVENT_STREAM_DATA_IND ibrt_link skip (mobile) skip sniff\n"); + nRet = 1; +#ifdef __SNIFF_MODE_CHECK__ + if(sniff_timer_state ==0) + { + sniff_timer_state =1; + osTimerStart(sniff_check_timer,5000); + } +#endif + } +#ifdef __SNIFF_MODE_CHECK__ + else + { + sniff_timer_state = 0; + osTimerStop(sniff_check_timer); + } +#endif + if (p_ibrt_ctrl->tws_mode == IBRT_SNIFF_MODE){ + TRACE(0,"::A2DP_EVENT_STREAM_DATA_IND ibrt_link skip (tws) skip sniff\n"); +#ifndef A2DP_IBRT_STREAM_SKIP_TWS_SNIFF_STATUS + nRet = 1; +#endif +#ifdef __SNIFF_MODE_CHECK__ + if(sniff_timer_state ==0) + { + sniff_timer_state =1; + osTimerStart(sniff_check_timer,5000); + } +#endif + } +#ifdef __SNIFF_MODE_CHECK__ + else + { + sniff_timer_state = 0; + osTimerStop(sniff_check_timer); + } +#endif + } + +#ifdef __SNIFF_MODE_CHECK__ + if(nRet ==0) + { + sniff_timer_state= 0; + osTimerStop(sniff_check_timer); + } +#endif + return nRet; +} +#endif + +#ifdef __A2DP_AVDTP_CP__ +extern U8 a2dp_avdtpCp_securityData[BT_DEVICE_NUM][BTIF_AVDTP_MAX_CP_VALUE_SIZE]; +extern U8 a2dp_avdtpCp_aac_securityData[BT_DEVICE_NUM][BTIF_AVDTP_MAX_CP_VALUE_SIZE]; +#endif /* __A2DP_AVDTP_CP__ */ + +uint8_t a2dp_get_current_codec_type(uint8_t *elements) +{ + uint8_t current_codec_type = 0; + + TRACE(4,"INFO element[0]:0x%x, element[1]:0x%x, element[2]:0x%x, element[3]:0x%x", + elements[0], elements[1],elements[2], elements[3]); + +#if defined(A2DP_LHDC_ON) + TRACE(4,"LHDC element[0]:0x%x, element[1]:0x%x, element[2]:0x%x, element[3]:0x%x", + a2dp_codec_lhdc_elements[0], a2dp_codec_lhdc_elements[1], + a2dp_codec_lhdc_elements[2], a2dp_codec_lhdc_elements[3]); + + if (!(strncmp((char*)elements, (char*)&a2dp_codec_lhdc_elements, 4))) + { + TRACE(0,"USE codec type is LHDC"); + current_codec_type = A2DP_NON_CODEC_TYPE_LHDC; + } +#endif + +#if defined(A2DP_LDAC_ON) + TRACE(4,"LDAC element[0]:0x%x, element[1]:0x%x, element[2]:0x%x, element[3]:0x%x", + a2dp_codec_ldac_elements[0], a2dp_codec_ldac_elements[1], + a2dp_codec_ldac_elements[2], a2dp_codec_ldac_elements[3]); + + if (!(strncmp((char*)elements, (char*)&a2dp_codec_ldac_elements, 4))) + { + TRACE(0,"USE codec type is LDAC"); + current_codec_type = A2DP_NON_CODEC_TYPE_LDAC; + } +#endif + +#if defined(A2DP_SCALABLE_ON) + if (!(strncmp((char*)elements, (char*)&a2dp_codec_scalable_elements, 4))) + { + TRACE(0,"USE codec type is SCALABLE"); + current_codec_type = A2DP_NON_CODEC_TYPE_SCALABLE; + } +#endif + + current_a2dp_non_type = current_codec_type; + + return current_codec_type; +} + + +extern "C" void a2dp_callback(a2dp_stream_t *Stream, const a2dp_callback_parms_t *info) +{ + int header_len = 0; + btif_avdtp_media_header_t header; + uint8_t distinguish_found_id = BT_DEVICE_NUM; + btif_a2dp_callback_parms_t * Info = (btif_a2dp_callback_parms_t *)info; + btif_avdtp_codec_t *codec = NULL; + struct bt_cb_tag* bt_drv_func_cb = bt_drv_get_func_cb_ptr(); + + static uint8_t detect_first_packet[BT_DEVICE_NUM] = {0,}; + + uint8_t current_codec_type = 0; + +#if defined(__BTIF_BT_RECONNECT__) + static btif_avdtp_codec_t setconfig_codec; + static u8 tmp_element[10]; +#endif +#ifdef __A2DP_AVDTP_CP__ + static btif_avdtp_content_prot_t setconfig_cp[BT_DEVICE_NUM]; +#endif + +#ifdef __BT_ONE_BRING_TWO__ + + // !!! not used now + // if (Info->event == BTIF_A2DP_EVENT_STREAM_STATE_CFM) { + // _a2dp_confirm_stream_state(Stream, (a2dp_callback_parms_t *)info); + // return; + // } + + if (Info->event == BTIF_A2DP_EVENT_STREAM_SELECT) { +#if defined(__BT_SELECT_PROF_DEVICE_ID__) + _a2dp_select_stream(Stream, (a2dp_callback_parms_t *)info); +#endif + return; + } + + if(Info->event== BTIF_A2DP_EVENT_STREAM_OPEN){ + // BTIF_A2DP_EVENT_STREAM_OPEN means that the + // AVDTP opened the avdtp media has connected + a2dp_stream_push_connected_stream(Stream); + } +#if !defined(__BT_SELECT_PROF_DEVICE_ID__) + a2dp_avdtp_stream_state_lock_management(Stream,info); +#endif + if (Info->event == BTIF_A2DP_EVENT_STREAM_SELECT) { + return; + } + distinguish_found_id = a2dp_stream_id_distinguish(Stream,Info->event); +#else + stream_id_flag.id = BT_DEVICE_ID_1; + app_bt_device.a2dp_connected_stream[BT_DEVICE_ID_1] = Stream; + distinguish_found_id = BT_DEVICE_ID_1; +#endif + + codec = btif_a2dp_get_stream_codec( Stream); + if (BTIF_A2DP_EVENT_STREAM_DATA_IND != Info->event) + { + TRACE(1,"Get A2DP event %d", Info->event); + } +#ifdef __BT_ONE_BRING_TWO__ + + enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == stream_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1; +#endif + switch(Info->event) { + case BTIF_A2DP_EVENT_AVDTP_DISCONNECT: + TRACE(3,"::A2DP_EVENT_AVDTP_DISCONNECT %d st = %p,id %d\n", Info->event, Stream,stream_id_flag.id); + break; + case BTIF_A2DP_EVENT_AVDTP_CONNECT: + TRACE(3,"::A2DP_EVENT_AVDTP_CONNECT %d st = %p id = %d\n", Info->event, Stream,stream_id_flag.id); + +#ifdef BT_USB_AUDIO_DUAL_MODE + if(!btusb_is_bt_mode()) + { + btusb_btaudio_close(false); + } +#endif + break; + case BTIF_A2DP_EVENT_STREAM_OPEN: + TRACE(2,"::A2DP_EVENT_STREAM_OPEN dev_id %x, stream_id:%d, sample_rate codec.elements 0x%x\n", distinguish_found_id,stream_id_flag.id,Info->p.configReq->codec.elements[0]); + + //update bt_profile_manager[deviceId].stream + app_bt_set_mobile_a2dp_stream(distinguish_found_id,Stream); + + #ifdef __BT_ONE_BRING_TWO__ + app_bt_device.latestPausedDevId = anotherDevice; + #else + app_bt_device.latestPausedDevId = BT_DEVICE_ID_1; + #endif + + #ifdef GFPS_ENABLED + app_exit_fastpairing_mode(); + #endif + + app_bt_clear_connecting_profiles_state(stream_id_flag.id); + + #ifdef __BT_ONE_BRING_TWO__ + a2dp_to_bond_avrcp_with_stream(Stream, stream_id_flag.id); + #endif + +#if defined(__BTMAP_ENABLE__) +#ifdef BTIF_DIP_DEVICE + if ((btif_dip_get_process_status(btif_a2dp_get_stream_conn_remDev(Stream)))&& (app_btmap_check_is_idle(stream_id_flag.id))) +#endif + { + app_btmap_sms_open(stream_id_flag.id, btif_me_get_remote_device_bdaddr(btif_a2dp_get_stream_conn_remDev(Stream))); + } +#endif + +#ifdef __A2DP_AVDTP_CP__ + //btif_a2dp_security_control_req(Stream,(uint8_t *)&a2dp_avdtpCp_securityData[stream_id_flag.id][0],1); +#endif + a2dp_timestamp_parser_init(); + app_bt_stream_volume_ptr_update((uint8_t *) btif_me_get_remote_device_bdaddr(btif_a2dp_get_stream_conn_remDev(Stream))); +// app_bt_stream_a2dpvolume_reset(); + + current_codec_type = a2dp_get_current_codec_type(Info->p.configReq->codec.elements); + + TRACE(2, "codecType 0x%x, current_codec_type %d \n", Info->p.configReq->codec.codecType, current_codec_type); + +#if defined(A2DP_AAC_ON) + if (Info->p.configReq->codec.codecType == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) { + TRACE(2,"::A2DP_EVENT_STREAM_OPEN stream_id:%d, aac sample_rate codec.elements 0x%x\n", stream_id_flag.id,Info->p.configReq->codec.elements[1]); + app_bt_device.codec_type[stream_id_flag.id] = BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC; + app_bt_device.sample_bit[stream_id_flag.id] = 16; + // convert aac sample_rate to sbc sample_rate format + if (Info->p.configReq->codec.elements[1] & A2DP_AAC_OCTET1_SAMPLING_FREQUENCY_44100) { + TRACE(1,"::A2DP_EVENT_STREAM_OPEN stream_id:%d, aac sample_rate 44100\n", stream_id_flag.id); + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_44; + } + else if (Info->p.configReq->codec.elements[2] & A2DP_AAC_OCTET2_SAMPLING_FREQUENCY_48000) { + TRACE(1,"::A2DP_EVENT_STREAM_OPEN stream_id:%d, aac sample_rate 48000\n", stream_id_flag.id); + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_48; + } + else { + TRACE(1,"::A2DP_EVENT_STREAM_OPEN stream_id:%d, aac sample_rate not 48000 or 44100, set to 44100\n", stream_id_flag.id); + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_44; + } + + if (Info->p.configReq->codec.elements[2] & A2DP_AAC_OCTET2_CHANNELS_1){ + a2dp_channel_num[stream_id_flag.id] = 1; + }else{ + a2dp_channel_num[stream_id_flag.id] = 2; + } + }else +#endif + if (Info->p.configReq->codec.codecType == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { +#if defined(A2DP_LHDC_ON) + if (current_codec_type == A2DP_NON_CODEC_TYPE_LHDC) + { + TRACE(2,"##codecType: LHDC Codec, Element length = %d, AVDTP_MAX_CODEC_ELEM_SIZE = %d\n", Info->p.configReq->codec.elemLen, BTIF_AVDTP_MAX_CODEC_ELEM_SIZE); + app_bt_device.codec_type[stream_id_flag.id] = BTIF_AVDTP_CODEC_TYPE_NON_A2DP; + a2dp_lhdc_config(&(Info->p.configReq->codec.elements[0])); + } +#endif +#if defined(A2DP_SCALABLE_ON) + if (current_codec_type == A2DP_NON_CODEC_TYPE_SCALABLE) + { + TRACE(0,"##codecType scalable\n"); + a2dp_scalable_config(&(Info->p.configReq->codec.elements[0])); + app_bt_device.codec_type[stream_id_flag.id] = BTIF_AVDTP_CODEC_TYPE_NON_A2DP; + //0x75 0x00 0x00 0x00Vid + //0x03 0x01 Codec id + if(Info->p.codec->elements[0]==0x75&& + Info->p.codec->elements[4]==0x03&& + Info->p.codec->elements[5]==0x01 + ){ + setconfig_codec.elements = a2dp_scalable_avdtpcodec.elements; + } + else{ + if(Info->p.codec->pstreamflags!=NULL) + Info->p.codec->pstreamflags[0] &= ~APP_A2DP_STRM_FLAG_QUERY_CODEC; + else{ + ASSERT(false, "pstreamflags not init .."); + } + + a2dp_channel_num[stream_id_flag.id] = 2; + } + + } +#endif +#if defined(A2DP_LDAC_ON) + if (current_codec_type == A2DP_NON_CODEC_TYPE_LDAC) + { + TRACE(2,"##codecType: LDAC Codec, Element length = %d, AVDTP_MAX_CODEC_ELEM_SIZE = %d\n", Info->p.configReq->codec.elemLen, BTIF_AVDTP_MAX_CODEC_ELEM_SIZE); + app_bt_device.codec_type[stream_id_flag.id] = BTIF_AVDTP_CODEC_TYPE_NON_A2DP; + // + //Codec Info Element: 0x 2d 01 00 00 aa 00 34 07 + // + if(Info->p.codec->elements[0]==0x2d){ + app_bt_device.sample_bit[stream_id_flag.id] = 16; + a2dp_ldac_config(&(Info->p.configReq->codec.elements[0])); + + } + else{ + if(Info->p.codec->pstreamflags!=NULL) + Info->p.codec->pstreamflags[0] &= ~APP_A2DP_STRM_FLAG_QUERY_CODEC; + else{ + ASSERT(false, "pstreamflags not init .."); + } + + a2dp_channel_num[stream_id_flag.id] = 2; + } + + } +#endif + } + else + { + TRACE(5,"app_bt_device.sample_rate::elements[0] %d BITPOOL:%d/%d %02x/%02x\n", Info->p.codec->elements[0], + Info->p.codec->elements[2], + Info->p.codec->elements[3], + Info->p.codec->elements[2], + Info->p.codec->elements[3]); + + app_bt_device.codec_type[stream_id_flag.id] = BTIF_AVDTP_CODEC_TYPE_SBC; + app_bt_device.sample_bit[stream_id_flag.id] = 16; + app_bt_device.sample_rate[stream_id_flag.id] = (Info->p.configReq->codec.elements[0] & A2D_SBC_IE_SAMP_FREQ_MSK); + + if(Info->p.configReq->codec.elements[0] & A2D_SBC_IE_CH_MD_MONO) + a2dp_channel_num[stream_id_flag.id] = 1; + else + a2dp_channel_num[stream_id_flag.id] = 2; + + } + app_bt_device.a2dp_state[stream_id_flag.id] = 1; + + if (btif_a2dp_is_stream_device_has_delay_reporting(Stream)) + { + btif_a2dp_set_sink_delay(Stream, 150); + } +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + if(app_bt_device.src_or_snk==BT_DEVICE_SRC) + { + if((Info->p.configReq->codec.elements[1] & A2D_SBC_IE_SUBBAND_MSK) == A2D_SBC_IE_SUBBAND_4) + TRACE(0,"numSubBands is only support 8!"); + //a2dp_source.sample_rate = bt_parse_sbc_sample_rate(btif_a2dp_get_stream_codec_element(Stream,0)); + a2dp_source.sample_rate = bt_parse_sbc_sample_rate(A2D_SBC_IE_SAMP_FREQ_44); + //TRACE(0,"::AVRCP_Connect\n", __LINE__); + //AVRCP_Connect(&app_bt_device.avrcp_channel[stream_id_flag.id], &Stream->stream.conn.remDev->bdAddr); + } + else + { + // reset connect counter + app_avrcp_connect_try_times[stream_id_flag.id] = 0; + btif_avrcp_connect(app_bt_device.avrcp_channel[stream_id_flag.id], btif_me_get_remote_device_bdaddr(btif_a2dp_get_stream_conn_remDev(Stream))); + } +#else + // reset connect counter + app_avrcp_connect_try_times[stream_id_flag.id] = 0; + btif_avrcp_connect(app_bt_device.avrcp_channel[stream_id_flag.id], btif_me_get_remote_device_bdaddr(btif_a2dp_get_stream_conn_remDev(Stream))); +#endif + app_bt_profile_connect_manager_a2dp(stream_id_flag.id, Stream, (a2dp_callback_parms_t *)Info); +#ifdef __BT_ONE_BRING_TWO__ + + if(app_bt_device.a2dp_connected_stream[anotherDevice] && + (btif_a2dp_get_stream_state( app_bt_device.a2dp_connected_stream[anotherDevice]) != BTIF_AVDTP_STRM_STATE_STREAMING)) + { + a2dp_set_cur_stream(stream_id_flag.id); + }else if(!app_bt_device.a2dp_connected_stream[anotherDevice]){ + a2dp_set_cur_stream(stream_id_flag.id); + } +#else + a2dp_set_cur_stream(stream_id_flag.id); +#endif + +#ifdef __BT_ONE_BRING_TWO__ + a2dp_dual_slave_handling_refresh(); +#endif +#if defined(IBRT) + a2dp_ibrt_session_reset(); +#endif + break; + case BTIF_A2DP_EVENT_STREAM_OPEN_IND: + TRACE(1,"::A2DP_EVENT_STREAM_OPEN_IND %d\n", Info->event); + btif_a2dp_open_stream_rsp(Stream, BTIF_A2DP_ERR_NO_ERROR, BTIF_AVDTP_SRV_CAT_MEDIA_TRANSPORT); +#ifdef __A2DP_AVDTP_CP__ + if(Info->p.configReq->cp.cpType==BTIF_AVDTP_CP_TYPE_SCMS_T) + { + app_bt_device.avdtp_cp[stream_id_flag.id] = 1; + } +#endif + break; + case BTIF_A2DP_EVENT_STREAM_STARTED: +#if defined(IBRT) + a2dp_ibrt_session_new(); + case BTIF_A2DP_EVENT_STREAM_STARTED_MOCK: + app_ibrt_if_sniff_checker_start(APP_IBRT_IF_SNIFF_CHECKER_USER_A2DP); + { + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + bt_drv_reg_op_set_agc_thd(p_ibrt_ctrl->current_role == IBRT_MASTER,false); + } +#endif + + if(bt_drv_func_cb->bt_switch_agc != NULL) + { + bt_drv_func_cb->bt_switch_agc(BT_A2DP_WORK_MODE); + } + +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("Music on ok."); +#endif + if (btif_a2dp_is_stream_device_has_delay_reporting(Stream)) + { + btif_a2dp_set_sink_delay(Stream, 150); + } +#if !defined(IBRT) + app_bt_active_mode_set(ACTIVE_MODE_KEEPER_A2DP_STREAMING, stream_id_flag.id); +#endif + a2dp_timestamp_parser_init(); + app_bt_device.a2dp_streamming[stream_id_flag.id] = 1; + detect_first_packet[stream_id_flag.id] = 1; + +#ifdef __BT_ONE_BRING_TWO__ + if (app_bt_is_device_connected(anotherDevice)) + { + app_bt_active_mode_set(ACTIVE_MODE_KEEPER_A2DP_STREAMING, anotherDevice); + } + + TRACE(5,"::BTIF_A2DP_EVENT_STREAM_STARTED_MOCK %d stream_id:%d %d %d %d\n", + codec->codecType, + stream_id_flag.id, + app_bt_device.curr_a2dp_stream_id, + app_bt_device.a2dp_streamming[0], + app_bt_device.a2dp_streamming[1]); + + TRACE(1,"playback = %d",app_bt_device.a2dp_play_pause_flag); + if(app_bt_device.a2dp_connected_stream[anotherDevice] && + (btif_a2dp_get_stream_state (app_bt_device.a2dp_connected_stream[anotherDevice]) != BTIF_AVDTP_STRM_STATE_STREAMING)){ + a2dp_set_cur_stream(stream_id_flag.id); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,BT_STREAM_SBC,stream_id_flag.id,MAX_RECORD_NUM); + app_a2dp_unhold_mute(); + }else if(!app_bt_device.a2dp_connected_stream[anotherDevice]){ + a2dp_set_cur_stream(stream_id_flag.id); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,BT_STREAM_SBC,stream_id_flag.id,MAX_RECORD_NUM); + app_a2dp_unhold_mute(); + } +#else // #ifndef __BT_ONE_BRING_TWO__ + TRACE(4,"::A2DP_EVENT_STREAM_STARTED %d stream_id:%d %d %d\n", + codec->codecType, + stream_id_flag.id, + app_bt_device.curr_a2dp_stream_id, + app_bt_device.a2dp_streamming[0]); + + a2dp_set_cur_stream(BT_DEVICE_ID_1); + +#if (A2DP_DECODER_VER == 2) +#if defined(IBRT) + if (Info->event == BTIF_A2DP_EVENT_STREAM_STARTED) + { + a2dp_audio_latency_factor_setlow(); + } +#else + a2dp_audio_latency_factor_setlow(); +#endif +#endif + +#if defined(APP_LINEIN_A2DP_SOURCE) || defined(APP_I2S_A2DP_SOURCE) + if (app_bt_device.src_or_snk == BT_DEVICE_SNK) + { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START, BT_STREAM_SBC, stream_id_flag.id, MAX_RECORD_NUM); + } + else + { + TRACE(0,"::APP_A2DP_SOURCE START \n"); +#if defined(APP_LINEIN_A2DP_SOURCE) + app_audio_sendrequest(APP_A2DP_SOURCE_LINEIN_AUDIO, ( uint8_t )APP_BT_SETTING_OPEN, 0); +#else + app_audio_sendrequest(APP_A2DP_SOURCE_I2S_AUDIO, ( uint8_t )APP_BT_SETTING_OPEN, 0); +#endif + app_bt_device.input_onoff = 1; + } +#else // #if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START, BT_STREAM_SBC, stream_id_flag.id, MAX_RECORD_NUM); +#endif // #if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +#endif // #ifdef __BT_ONE_BRING_TWO__ + +#ifdef __BT_ONE_BRING_TWO__ + if (btapp_hfp_is_dev_sco_connected(anotherDevice)) + { + a2dp_dual_slave_setup_during_sco(anotherDevice); + } + else + { + a2dp_dual_slave_handling_refresh(); + } +#endif + +#ifdef __IAG_BLE_INCLUDE__ + app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_A2DP_ON, true); +#endif + break; + case BTIF_A2DP_EVENT_STREAM_START_IND: +#ifdef __BT_ONE_BRING_TWO__ + TRACE(5,"::A2DP_EVENT_STREAM_START_IND %d stream_id:%d %d %d %d\n", codec->codecType, stream_id_flag.id, app_bt_device.curr_a2dp_stream_id, + app_bt_device.a2dp_streamming[0], app_bt_device.a2dp_streamming[1]); +#else + TRACE(4,"::A2DP_EVENT_STREAM_START_IND %d stream_id:%d %d %d\n",codec->codecType, stream_id_flag.id, app_bt_device.curr_a2dp_stream_id, + app_bt_device.a2dp_streamming[0]); +#endif + { +#ifdef BT_USB_AUDIO_DUAL_MODE + if(!btusb_is_bt_mode()) + { + btif_a2dp_start_stream_rsp(Stream, BTIF_A2DP_ERR_INSUFFICIENT_RESOURCE); + } + else +#endif + { + btif_a2dp_start_stream_rsp(Stream, BTIF_A2DP_ERR_NO_ERROR); + app_bt_device.a2dp_play_pause_flag = 1; + } + } + break; + case BTIF_A2DP_EVENT_STREAM_IDLE: + TRACE(0,"BTIF_A2DP_EVENT_STREAM_IDLE"); + case BTIF_A2DP_EVENT_STREAM_SUSPENDED: +#if defined(IBRT) + app_ibrt_if_sniff_checker_stop(APP_IBRT_IF_SNIFF_CHECKER_USER_A2DP); +#endif + if(bt_drv_func_cb->bt_switch_agc != NULL) + { + bt_drv_func_cb->bt_switch_agc(BT_IDLE_MODE); + } + +#ifdef __BT_ONE_BRING_TWO__ + TRACE(5,"::A2DP_EVENT_STREAM_SUSPENDED %d stream_id:%d %d %d %d\n",codec->codecType, stream_id_flag.id, app_bt_device.curr_a2dp_stream_id, + app_bt_device.a2dp_streamming[0], app_bt_device.a2dp_streamming[1]); +#else + TRACE(4,"::A2DP_EVENT_STREAM_SUSPENDED %d stream_id:%d %d %d\n",codec->codecType, stream_id_flag.id, app_bt_device.curr_a2dp_stream_id, + app_bt_device.a2dp_streamming[0]); +#endif + a2dp_timestamp_parser_init(); + app_bt_device.a2dp_streamming[stream_id_flag.id] = 0; +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("Music suspend ok."); +#endif + app_bt_active_mode_clear(ACTIVE_MODE_KEEPER_A2DP_STREAMING, stream_id_flag.id); + +#ifdef __BT_ONE_BRING_TWO__ + if (app_bt_is_device_connected(anotherDevice) && + (!app_bt_device.a2dp_streamming[anotherDevice]) && + (BTIF_HF_CALL_ACTIVE != app_bt_device.hfchan_call[anotherDevice])) + { + app_bt_active_mode_clear(ACTIVE_MODE_KEEPER_A2DP_STREAMING, anotherDevice); + } + + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC,stream_id_flag.id,0); + if((app_bt_device.a2dp_connected_stream[anotherDevice]) && + (btif_a2dp_get_stream_state(app_bt_device.a2dp_connected_stream[anotherDevice]) == BTIF_AVDTP_STRM_STATE_STREAMING)){ + if(bt_media_is_media_active_by_device(BT_STREAM_SBC,anotherDevice) == 1){ + a2dp_set_cur_stream(anotherDevice); + app_bt_device.a2dp_play_pause_flag = 1; + }else{ + a2dp_set_cur_stream(anotherDevice); + app_bt_device.a2dp_play_pause_flag = 1; + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,BT_STREAM_SBC,anotherDevice,0); + } + }else{ + app_bt_device.a2dp_play_pause_flag = 0; + app_a2dp_hold_mute(); + } +#else + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + if(app_bt_device.src_or_snk==BT_DEVICE_SNK) + { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC,BT_DEVICE_ID_1,MAX_RECORD_NUM); + } + else + { + TRACE(0,"::APP_A2DP_SOURCE SUSPEND \n"); +#if defined(APP_LINEIN_A2DP_SOURCE) + app_audio_sendrequest(APP_A2DP_SOURCE_LINEIN_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE,0); +#else + app_audio_sendrequest(APP_A2DP_SOURCE_I2S_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE,0); +#endif + app_bt_device.input_onoff=0; + } +#else + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC,BT_DEVICE_ID_1,MAX_RECORD_NUM); +#endif + app_bt_device.a2dp_play_pause_flag = 0; +#endif + +#ifdef __BT_ONE_BRING_TWO__ + if (btapp_hfp_is_dev_sco_connected(anotherDevice)) + { + a2dp_dual_slave_setup_during_sco(anotherDevice); + } + else + { + a2dp_dual_slave_handling_refresh(); + } +#endif + +#ifdef __IAG_BLE_INCLUDE__ + app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_A2DP_ON, false); +#endif + + break; + case BTIF_A2DP_EVENT_STREAM_DATA_IND: +#ifdef __AI_VOICE__ + if(app_ai_is_to_mute_a2dp_during_ai_starting_speech()) { + //TRACE(0,"app_ai_is_to_mute_a2dp_during_ai_starting_speech"); + break; + } +#endif +#if defined(IBRT) + if (a2dp_ibrt_stream_event_stream_data_ind_needskip(Stream)){ + header_len = btif_avdtp_parse_mediaHeader(&header, (btif_a2dp_callback_parms_t *)Info,0); + TRACE(2,"::A2DP_EVENT_STREAM_DATA_IND skip seq:%d timestamp:%d\n", header.sequenceNumber, header.timestamp); + break; + } +#else + if (btif_me_get_current_mode(btif_a2dp_get_remote_device(Stream)) == BTIF_BLM_SNIFF_MODE){ + TRACE(0,"::A2DP_EVENT_STREAM_DATA_IND skip\n"); + break; + } +#endif + if (detect_first_packet[stream_id_flag.id]){ + detect_first_packet[stream_id_flag.id] = 0; + avrcp_get_current_media_status(stream_id_flag.id); + } + +#ifdef __BT_ONE_BRING_TWO__ + ////play music of curr_a2dp_stream_id + if(app_bt_device.curr_a2dp_stream_id == stream_id_flag.id && + app_bt_device.hf_audio_state[stream_id_flag.id]==BTIF_HF_AUDIO_DISCON && + app_bt_device.hf_audio_state[anotherDevice]==BTIF_HF_AUDIO_DISCON && + app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_NONE){ +#ifdef __A2DP_AVDTP_CP__ //zadd bug fixed sony Z5 no sound + header_len = btif_avdtp_parse_mediaHeader(&header, (btif_a2dp_callback_parms_t *)Info,app_bt_device.avdtp_cp[stream_id_flag.id]); +#else + header_len = btif_avdtp_parse_mediaHeader(&header,(btif_a2dp_callback_parms_t *) Info,0); +#endif + if (app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC) && (btif_a2dp_get_stream_state(Stream) == BTIF_AVDTP_STRM_STATE_STREAMING)){ +#ifdef __A2DP_TIMESTAMP_PARSER__ + if (a2dp_timestamp_parser_run(header.timestamp,(*(((unsigned char *)Info->p.data) + header_len)))){ + TRACE(0,"::A2DP_EVENT_STREAM_DATA_IND skip frame\n"); + }else +#endif + { +#if (A2DP_DECODER_VER >= 2) + a2dp_audio_store_packet(&header, ((unsigned char *)Info->p.data) + header_len , Info->len - header_len); +#else + a2dp_audio_sbc_set_frame_info(Info->len - header_len - 1, (*(((unsigned char *)Info->p.data) + header_len))); +#if defined(A2DP_LHDC_ON) + if (app_bt_device.codec_type[stream_id_flag.id] == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) { + store_sbc_buffer(((unsigned char *)Info->p.data) + header_len , Info->len - header_len); + } + else +#endif +#if defined(A2DP_AAC_ON) + if (app_bt_device.codec_type[stream_id_flag.id] == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) { +#ifdef BT_USB_AUDIO_DUAL_MODE + if(btusb_is_bt_mode()) +#endif + { + store_sbc_buffer(((unsigned char *)Info->p.data) + header_len , Info->len - header_len); + } + } + else +#endif +#if defined(A2DP_SCALABLE_ON) + if (app_bt_device.codec_type[stream_id_flag.id] == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) { + store_sbc_buffer(((unsigned char *)Info->p.data) + header_len , Info->len - header_len); + }else +#endif + { + store_sbc_buffer(((unsigned char *)Info->p.data) + header_len + 1 , Info->len - header_len - 1); + } +#endif + } + } + } +#else +#ifdef __A2DP_AVDTP_CP__ //zadd bug fixed sony Z5 no sound + header_len = btif_avdtp_parse_mediaHeader(&header, (btif_a2dp_callback_parms_t *)Info,app_bt_device.avdtp_cp[stream_id_flag.id]); +#else + header_len = btif_avdtp_parse_mediaHeader(&header, (btif_a2dp_callback_parms_t *)Info,0); +#endif + if ( +#if (A2DP_DECODER_VER < 2) + app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC) && +#endif + (btif_a2dp_get_stream_state(Stream) == BTIF_AVDTP_STRM_STATE_STREAMING)){ +#ifdef __A2DP_TIMESTAMP_PARSER__ + if (a2dp_timestamp_parser_run(header.timestamp,(*(((unsigned char *)Info->p.data) + header_len)))){ + TRACE(0,"::A2DP_EVENT_STREAM_DATA_IND skip frame\n"); + }else +#endif + { +#if (A2DP_DECODER_VER >= 2) + a2dp_audio_store_packet(&header, ((unsigned char *)Info->p.data) + header_len , Info->len - header_len); +#else + a2dp_audio_sbc_set_frame_info(Info->len - header_len - 1, (*(((unsigned char *)Info->p.data) + header_len))); + + current_codec_type = a2dp_get_current_codec_type((unsigned char *)Info->p.configReq->codec.elements); +#if defined(A2DP_AAC_ON) + //TRACE(4,"%s:%d pt 0x%x, app_bt_device.codec_type[stream_id_flag.id] %d\n", + // __func__, __LINE__, header.payloadType, app_bt_device.codec_type[stream_id_flag.id]); + if (app_bt_device.codec_type[stream_id_flag.id] == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) { + store_sbc_buffer(((unsigned char *)Info->p.data) + header_len , Info->len - header_len); + } + else +#endif +#if defined(A2DP_SCALABLE_ON) + if (app_bt_device.codec_type[stream_id_flag.id] == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) { + store_sbc_buffer(((unsigned char *)Info->p.data) + header_len , Info->len - header_len); + }else +#endif +#if defined(A2DP_LHDC_ON) + if (app_bt_device.codec_type[stream_id_flag.id] == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) { + store_sbc_buffer(((unsigned char *)Info->p.data) + header_len , Info->len - header_len); + }else +#endif +#if defined(A2DP_LDAC_ON) + if (app_bt_device.codec_type[stream_id_flag.id] == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) { + //if((((unsigned char *)Info->p.data) + header_len)) + store_sbc_buffer(((unsigned char *)Info->p.data) + header_len + 1, Info->len - header_len - 1); + } + else +#endif + + store_sbc_buffer(((unsigned char *)Info->p.data) + header_len + 1 , Info->len - header_len - 1); +#endif + } + } + else { + TRACE(2,"::A2DP_EVENT_STREAM_DATA_IND skip app_bt_stream_isrun=%d,stream_state=%d", app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC), btif_a2dp_get_stream_state(Stream)); + } +#endif + break; + case BTIF_A2DP_EVENT_STREAM_CLOSED: + if(bt_drv_func_cb->bt_switch_agc != NULL) + { + bt_drv_func_cb->bt_switch_agc(BT_IDLE_MODE); + } + TRACE(2,"::A2DP_EVENT_STREAM_CLOSED stream_id:%d, reason = %x\n", stream_id_flag.id,Info->discReason); + if (btif_a2dp_is_disconnected(app_bt_device.a2dp_connected_stream[stream_id_flag.id])) { + // disconnect avrcp also when a2dp closed + btif_avrcp_disconnect(app_bt_device.avrcp_channel[stream_id_flag.id]->avrcp_channel_handle); + } +#ifdef __A2DP_AVDTP_CP__ + app_bt_device.avdtp_cp[stream_id_flag.id]=0; +#endif + a2dp_timestamp_parser_init(); + app_bt_device.a2dp_streamming[stream_id_flag.id] = 0; + #ifdef __BT_ONE_BRING_TWO__ + if (app_bt_is_to_resume_music_player(stream_id_flag.id)) + { + app_bt_reset_music_player_resume_state(); + } + #endif + if(distinguish_found_id != BT_DEVICE_NUM){ +#ifdef __BT_ONE_BRING_TWO__ + TRACE(3,"found_id=%d state[0]/[1] = %d %d",distinguish_found_id, + app_bt_device.a2dp_state[BT_DEVICE_ID_1],app_bt_device.a2dp_state[BT_DEVICE_ID_2]); + // app_bt_device.curr_a2dp_stream_id = anotherDevice; + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC,stream_id_flag.id,0); + if((app_bt_device.a2dp_connected_stream[anotherDevice]) && + (btif_a2dp_get_stream_state(app_bt_device.a2dp_connected_stream[anotherDevice]) == BTIF_AVDTP_STRM_STATE_STREAMING)) + { + if(bt_media_is_media_active_by_device(BT_STREAM_SBC,anotherDevice) == 1) + { + a2dp_set_cur_stream(anotherDevice); + app_bt_device.a2dp_play_pause_flag = 1; + }else{ + a2dp_set_cur_stream(anotherDevice); + app_bt_device.a2dp_play_pause_flag = 1; + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,BT_STREAM_SBC,anotherDevice,0); + } + } + else + { + app_bt_device.a2dp_play_pause_flag = 0; + app_a2dp_hold_mute(); + } +#else + + + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + if(app_bt_device.src_or_snk==BT_DEVICE_SRC) + { + if(app_bt_device.input_onoff!=0) + { +#if defined(APP_LINEIN_A2DP_SOURCE) + app_audio_sendrequest(APP_A2DP_SOURCE_LINEIN_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE,0); +#else + app_audio_sendrequest(APP_A2DP_SOURCE_I2S_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE,0); +#endif + app_bt_device.input_onoff=0; + } + app_bt_device.a2dp_streamming[BT_DEVICE_ID_1] = 0; + a2dp_source_notify_send(); + } + else + { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC,stream_id_flag.id,0); + app_bt_profile_connect_manager_a2dp(stream_id_flag.id, Stream, (a2dp_callback_parms_t *)Info); + } +#else + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC,stream_id_flag.id,0); + app_bt_device.a2dp_play_pause_flag = 0; +#endif + +#endif + + app_bt_device.a2dp_state[stream_id_flag.id] = 0; + app_bt_device.a2dp_connected_stream[stream_id_flag.id] = NULL; +#ifdef __BT_ONE_BRING_TWO__ + ///a2dp disconnect so check the other stream is playing or not + if((app_bt_device.a2dp_connected_stream[anotherDevice]) && + (btif_a2dp_get_stream_state(app_bt_device.a2dp_connected_stream[anotherDevice]) != BTIF_AVDTP_STRM_STATE_STREAMING)) + { + app_bt_device.a2dp_play_pause_flag = 0; + app_a2dp_hold_mute(); + } +#endif + } + +#ifdef __BT_ONE_BRING_TWO__ + a2dp_dual_slave_handling_refresh(); +#endif + app_bt_profile_connect_manager_a2dp(stream_id_flag.id, Stream, info); +#if defined(IBRT) + a2dp_ibrt_session_reset(); +#endif + break; +#if defined(__BTIF_BT_RECONNECT__) + case BTIF_A2DP_EVENT_CODEC_INFO: + TRACE(1,"::A2DP_EVENT_CODEC_INFO %d\n", Info->event); + setconfig_codec.codecType = Info->p.codec->codecType; + setconfig_codec.discoverable = Info->p.codec->discoverable; + setconfig_codec.elemLen = Info->p.codec->elemLen; + setconfig_codec.elements = tmp_element; + memset(tmp_element, 0, sizeof(tmp_element)); + + DUMP8("%02x ", (setconfig_codec.elements), 8); + if(Info->p.codec->codecType == BTIF_AVDTP_CODEC_TYPE_SBC){ + setconfig_codec.elements[0] = (Info->p.codec->elements[0]) & (a2dp_codec_elements[0]); + setconfig_codec.elements[1] = (Info->p.codec->elements[1]) & (a2dp_codec_elements[1]); + + if(Info->p.codec->elements[2] <= a2dp_codec_elements[2]) + setconfig_codec.elements[2] = a2dp_codec_elements[2];////[2]:MIN_BITPOOL + else + setconfig_codec.elements[2] = Info->p.codec->elements[2]; + + if(Info->p.codec->elements[3] >= a2dp_codec_elements[3]) + setconfig_codec.elements[3] = a2dp_codec_elements[3];////[3]:MAX_BITPOOL + else + setconfig_codec.elements[3] = Info->p.codec->elements[3]; + + ///////null set situation: + if(setconfig_codec.elements[3] < a2dp_codec_elements[2]){ + setconfig_codec.elements[2] = a2dp_codec_elements[2]; + setconfig_codec.elements[3] = a2dp_codec_elements[3]; + } + else if(setconfig_codec.elements[2] > a2dp_codec_elements[3]){ + setconfig_codec.elements[2] = a2dp_codec_elements[3]; + setconfig_codec.elements[3] = a2dp_codec_elements[3]; + } + TRACE(2,"!!!setconfig_codec.elements[2]:%d,setconfig_codec.elements[3]:%d\n",setconfig_codec.elements[2],setconfig_codec.elements[3]); + + setconfig_codec.elements[0] = get_valid_bit(setconfig_codec.elements[0],A2D_SBC_IE_SAMP_FREQ_MSK); + setconfig_codec.elements[0] = get_valid_bit(setconfig_codec.elements[0],A2D_SBC_IE_CH_MD_MSK); + setconfig_codec.elements[1] = get_valid_bit(setconfig_codec.elements[1],A2D_SBC_IE_BLOCKS_MSK); + setconfig_codec.elements[1] = get_valid_bit(setconfig_codec.elements[1],A2D_SBC_IE_SUBBAND_MSK); + setconfig_codec.elements[1] = get_valid_bit(setconfig_codec.elements[1],A2D_SBC_IE_ALLOC_MD_MSK); + } +#if defined(A2DP_AAC_ON) + else if(Info->p.codec->codecType == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC){ + setconfig_codec.elements[0] = a2dp_codec_aac_elements[0]; + if(Info->p.codec->elements[1] & A2DP_AAC_OCTET1_SAMPLING_FREQUENCY_44100) + setconfig_codec.elements[1] |= A2DP_AAC_OCTET1_SAMPLING_FREQUENCY_44100; + else if(Info->p.codec->elements[2] & A2DP_AAC_OCTET2_SAMPLING_FREQUENCY_48000) + setconfig_codec.elements[2] |= A2DP_AAC_OCTET2_SAMPLING_FREQUENCY_48000; + + if(Info->p.codec->elements[2] & A2DP_AAC_OCTET2_CHANNELS_2) + setconfig_codec.elements[2] |= A2DP_AAC_OCTET2_CHANNELS_2; + else if(Info->p.codec->elements[2] & A2DP_AAC_OCTET2_CHANNELS_1) + setconfig_codec.elements[2] |= A2DP_AAC_OCTET2_CHANNELS_1; + + setconfig_codec.elements[3] = (Info->p.codec->elements[3]) & A2DP_AAC_OCTET3_VBR_SUPPORTED; + if ( ((Info->p.codec->elements[3]) & A2DP_AAC_OCTET3_VBR_SUPPORTED) && + (((a2dp_codec_aac_elements[3]) & A2DP_AAC_OCTET3_VBR_SUPPORTED) == 0)){ + Info->error = BTIF_A2DP_ERR_NOT_SUPPORTED_VBR; + TRACE(0,"setconfig: VBR UNSUPPORTED!!!!!!"); + } + + uint32_t bit_rate = 0; + bit_rate = ((Info->p.codec->elements[3]) & 0x7f) << 16; + bit_rate |= (Info->p.codec->elements[4]) << 8; + bit_rate |= (Info->p.codec->elements[5]); + TRACE(1,"bit_rate = %d", bit_rate); + if(bit_rate == 0){ + bit_rate = MAX_AAC_BITRATE; + }else if(bit_rate > MAX_AAC_BITRATE){ + bit_rate = MAX_AAC_BITRATE; + } + + setconfig_codec.elements[3] |= (bit_rate >> 16) &0x7f; + setconfig_codec.elements[4] = (bit_rate >> 8) & 0xff; + setconfig_codec.elements[5] = bit_rate & 0xff; + } +#endif + else if(Info->p.codec->codecType == BTIF_AVDTP_CODEC_TYPE_NON_A2DP){ +#if defined(A2DP_SCALABLE_ON) + //0x75 0x00 0x00 0x00Vid + //0x03 0x01 Codec id + if(Info->p.codec->elements[0]==0x75&& + Info->p.codec->elements[1]==0x00&& + Info->p.codec->elements[2]==0x00&& + Info->p.codec->elements[3]==0x00&& + Info->p.codec->elements[4]==0x03&& + Info->p.codec->elements[5]==0x01){ + memcpy(&setconfig_codec.elements[0], &a2dp_codec_scalable_elements[0], 6); + DUMP8("%02x ", (setconfig_codec.elements), 8); + DUMP8("%02x ", &(Info->p.codec->elements[0]), 8); + setconfig_codec.elements[6] = 0x00; + //Audio format setting +#if defined(A2DP_SCALABLE_UHQ_SUPPORT) + if (Info->p.codec->elements[6] & A2DP_SCALABLE_SR_96000) { + setconfig_codec.elements[6] |= A2DP_SCALABLE_SR_96000; + } +#endif + if (Info->p.codec->elements[6] & A2DP_SCALABLE_SR_32000) { + setconfig_codec.elements[6] |= A2DP_SCALABLE_SR_32000; + }else if (Info->p.codec->elements[6] & A2DP_SCALABLE_SR_44100) { + setconfig_codec.elements[6] |= A2DP_SCALABLE_SR_44100; + }else if (Info->p.codec->elements[6] & A2DP_SCALABLE_SR_48000) { + setconfig_codec.elements[6] |= A2DP_SCALABLE_SR_48000; + } + + if (Info->p.codec->elements[6] & A2DP_SCALABLE_HQ) { + setconfig_codec.elements[6] |= A2DP_SCALABLE_HQ; + } + DUMP8("0x%02x ", setconfig_codec.elements, setconfig_codec.elemLen); + } +#endif + +#if defined(A2DP_LHDC_ON) + //0x3A 0x05 0x00 0x00Vid + //0x33 0x4c Codec id V3 + //0x32 0x4c Codec id V2 + if(Info->p.codec->elements[0]==a2dp_codec_lhdc_elements[0]&& + Info->p.codec->elements[1]==a2dp_codec_lhdc_elements[1]&& + Info->p.codec->elements[2]==a2dp_codec_lhdc_elements[2]&& + Info->p.codec->elements[3]==a2dp_codec_lhdc_elements[3]&& + Info->p.codec->elements[4]==a2dp_codec_lhdc_elements[4]&& + Info->p.codec->elements[5]==a2dp_codec_lhdc_elements[5]){ + memcpy(&setconfig_codec.elements[0], &a2dp_codec_lhdc_elements[0], 6); + DUMP8("%02x ", (setconfig_codec.elements), 8); + DUMP8("%02x ", &(Info->p.codec->elements[0]), 8); + + //Audio format setting + //(A2DP_LHDC_SR_96000|A2DP_LHDC_SR_48000 |A2DP_LHDC_SR_44100) | (A2DP_LHDC_FMT_16), + if (Info->p.codec->elements[6] & A2DP_LHDC_SR_96000) { + setconfig_codec.elements[6] |= A2DP_LHDC_SR_96000; + }else if (Info->p.codec->elements[6] & A2DP_LHDC_SR_48000) { + setconfig_codec.elements[6] |= A2DP_LHDC_SR_48000; + }else if (Info->p.codec->elements[6] & A2DP_LHDC_SR_44100) { + setconfig_codec.elements[6] |= A2DP_LHDC_SR_44100; + } + + if (Info->p.codec->elements[6] & A2DP_LHDC_FMT_16) { + setconfig_codec.elements[6] |= A2DP_LHDC_FMT_16; + }else if (Info->p.codec->elements[6] & A2DP_LHDC_FMT_24) { + setconfig_codec.elements[6] |= A2DP_LHDC_FMT_24; + } + } +#endif + +#if defined(A2DP_LDAC_ON) +// 0x2d, 0x01, 0x00, 0x00, //Vendor ID +// 0xaa, 0x00, //Codec ID + if (Info->p.codec->elements[0]==a2dp_codec_ldac_elements[0]&& + Info->p.codec->elements[1]==a2dp_codec_ldac_elements[1]&& + Info->p.codec->elements[2]==a2dp_codec_ldac_elements[2]&& + Info->p.codec->elements[3]==a2dp_codec_ldac_elements[3]&& + Info->p.codec->elements[4]==a2dp_codec_ldac_elements[4]&& + Info->p.codec->elements[5]==a2dp_codec_ldac_elements[5]){ + memcpy(&setconfig_codec.elements[0], &a2dp_codec_ldac_elements[0], 6); + + DUMP8("%02x ", (setconfig_codec.elements), 8); + DUMP8("%02x ", &(Info->p.codec->elements[0]), 8); + //Audio format setting + //3c 03 + //34 07 + if (Info->p.codec->elements[6] & A2DP_LDAC_SR_96000) { + setconfig_codec.elements[6] |= A2DP_LDAC_SR_96000; + }else if (Info->p.codec->elements[6] & A2DP_LDAC_SR_88200) { + setconfig_codec.elements[6] |= A2DP_LDAC_SR_88200; + }else if (Info->p.codec->elements[6] & A2DP_LDAC_SR_48000) { + setconfig_codec.elements[6] |= A2DP_LDAC_SR_48000; + }else if (Info->p.codec->elements[6] & A2DP_LDAC_SR_44100) { + setconfig_codec.elements[6] |= A2DP_LDAC_SR_44100; + } + // }else if (Info->p.codec->elements[6] & A2DP_LDAC_SR_88200) { + // setconfig_codec.elements[6] |= A2DP_LDAC_SR_88200; + // } + + if (Info->p.codec->elements[7] & A2DP_LDAC_CM_MONO) { + setconfig_codec.elements[7] |= A2DP_LDAC_CM_MONO; + }else if (Info->p.codec->elements[7] & A2DP_LDAC_CM_DUAL) { + setconfig_codec.elements[7] |= A2DP_LDAC_CM_DUAL; + }else if (Info->p.codec->elements[7] & A2DP_LDAC_CM_STEREO) { + setconfig_codec.elements[7] |= A2DP_LDAC_CM_STEREO; + } + + TRACE(1,"setconfig_codec.elemLen = %d", setconfig_codec.elemLen); + TRACE(1,"setconfig_codec.elements[7] = 0x%02x", setconfig_codec.elements[7]); + + DUMP8("%02x ", (setconfig_codec.elements), 8); + } +#endif + } + break; + + case BTIF_A2DP_EVENT_GET_CONFIG_IND: + TRACE(1,"::A2DP_EVENT_GET_CONFIG_IND %d\n", Info->event); +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + //I2S or LineIn for 44.1K + setconfig_codec.elements[0] = (setconfig_codec.elements[0]&0xef) | A2D_SBC_IE_SAMP_FREQ_44; +#endif +#ifdef __A2DP_AVDTP_CP__ + if(Info->p.capability->type & BTIF_AVDTP_SRV_CAT_CONTENT_PROTECTION||Info->p.cp->cpType!=0){ + TRACE(0,"support CONTENT_PROTECTION\n"); + btif_a2dp_set_stream_config(Stream, &setconfig_codec, &setconfig_cp[stream_id_flag.id]); + }else{ + TRACE(0,"no CONTENT_PROTECTION\n"); + btif_a2dp_set_stream_config(Stream, &setconfig_codec, NULL); + } +#else + btif_a2dp_set_stream_config(Stream, &setconfig_codec, NULL); +#endif + break; + case BTIF_A2DP_EVENT_STREAM_RECONFIG_IND: + TRACE(1,"::A2DP_EVENT_STREAM_RECONFIG_IND %d\n", Info->event); +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + SOURCE_DBLOG("::BTIF_A2DP_EVENT_STREAM_RECONFIG_IND %d\n", Info->event); +#else + + if(Info->p.configReq->codec.codecType == BTIF_AVDTP_CODEC_TYPE_NON_A2DP){ + current_codec_type = a2dp_get_current_codec_type((unsigned char *)Info->p.configReq->codec.elements); +#if defined(A2DP_SCALABLE_ON) + if(current_codec_type == A2DP_NON_CODEC_TYPE_SCALABLE){ + TRACE(0,"::##SCALABLE A2DP_EVENT_STREAM_RECONFIG_IND\n"); + a2dp_scalable_config(&(Info->p.configReq->codec.elements[0])); + } +#endif +#if defined(A2DP_LHDC_ON) + if(current_codec_type == A2DP_NON_CODEC_TYPE_LHDC){ + TRACE(0,"::##LHDC A2DP_EVENT_STREAM_RECONFIG_IND\n"); + a2dp_lhdc_config(&(Info->p.configReq->codec.elements[0])); + } +#endif +#if defined(A2DP_LDAC_ON) + if(current_codec_type == A2DP_NON_CODEC_TYPE_LDAC){ + TRACE(0,"::##LDAC A2DP_EVENT_STREAM_RECONFIG_IND\n"); + a2dp_ldac_config(&(Info->p.configReq->codec.elements[0])); + } +#endif + } + +#if defined(A2DP_AAC_ON) + if(Info->p.configReq->codec.codecType == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC){ + TRACE(0,"::##AAC A2DP_EVENT_STREAM_RECONFIG_IND\n"); + if ( ((Info->p.codec->elements[3]) & A2DP_AAC_OCTET3_VBR_SUPPORTED) && + (((a2dp_codec_aac_elements[3]) & A2DP_AAC_OCTET3_VBR_SUPPORTED) == 0)){ + Info->error = BTIF_A2DP_ERR_NOT_SUPPORTED_VBR; + btif_a2dp_reconfig_stream_rsp(Stream,BTIF_A2DP_ERR_NOT_SUPPORTED_VBR,0); + TRACE(0,"stream reconfig: VBR UNSUPPORTED!!!!!!"); + break; + } + } +#endif + if(Info->p.configReq->codec.codecType == BTIF_AVDTP_CODEC_TYPE_SBC){ + TRACE(0,"::##SBC A2DP_EVENT_STREAM_RECONFIG_IND\n"); + TRACE(5,"app_bt_device.sample_rate::elements[0] %d BITPOOL:%d/%d %02x/%02x\n", Info->p.configReq->codec.elements[0], + Info->p.configReq->codec.elements[2], + Info->p.configReq->codec.elements[3], + Info->p.configReq->codec.elements[2], + Info->p.configReq->codec.elements[3]); + } +#endif + btif_a2dp_reconfig_stream_rsp(Stream,BTIF_A2DP_ERR_NO_ERROR,0); + break; + case BTIF_A2DP_EVENT_STREAM_RECONFIG_CNF: + TRACE(3,"::A2DP_EVENT_STREAM_RECONFIG_CNF %d,sample rate=%x,%x\n", + Info->event,btif_a2dp_get_stream_codecCfg( Stream)->elements[0], Info->p.codec->elements[0]); + +#if defined(A2DP_AAC_ON) + if (Info->p.configReq->codec.codecType == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) { +#ifdef __A2DP_AVDTP_CP__ + btif_a2dp_security_control_req(Stream,(U8 *)&a2dp_avdtpCp_aac_securityData[stream_id_flag.id][0],1); +#endif + TRACE(2,"::A2DP_EVENT_STREAM_OPEN stream_id:%d, aac sample_rate codec.elements 0x%x\n", stream_id_flag.id,Info->p.configReq->codec.elements[1]); + app_bt_device.codec_type[stream_id_flag.id] = BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC; + app_bt_device.sample_bit[stream_id_flag.id] = 16; + // convert aac sample_rate to sbc sample_rate format + if (Info->p.configReq->codec.elements[1] & A2DP_AAC_OCTET1_SAMPLING_FREQUENCY_44100) { + TRACE(1,"::A2DP_EVENT_STREAM_OPEN stream_id:%d, aac sample_rate 44100\n", stream_id_flag.id); + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_44; + } + else if (Info->p.configReq->codec.elements[2] & A2DP_AAC_OCTET2_SAMPLING_FREQUENCY_48000) { + TRACE(1,"::A2DP_EVENT_STREAM_OPEN stream_id:%d, aac sample_rate 48000\n", stream_id_flag.id); + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_48; + } + else { + TRACE(1,"::A2DP_EVENT_STREAM_OPEN stream_id:%d, aac sample_rate not 48000 or 44100, set to 44100\n", stream_id_flag.id); + app_bt_device.sample_rate[stream_id_flag.id] = A2D_SBC_IE_SAMP_FREQ_44; + } + + if (Info->p.configReq->codec.elements[2] & A2DP_AAC_OCTET2_CHANNELS_1){ + a2dp_channel_num[stream_id_flag.id] = 1; + }else{ + a2dp_channel_num[stream_id_flag.id] = 2; + } + } + else +#endif + if (Info->p.configReq->codec.codecType == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) { + current_codec_type = a2dp_get_current_codec_type((unsigned char *)Info->p.configReq->codec.elements); +#if defined(A2DP_SCALABLE_ON) + if (current_codec_type == A2DP_NON_CODEC_TYPE_SCALABLE) { + TRACE(0,"##codecType scalable\n"); + a2dp_scalable_config(&(Info->p.configReq->codec.elements[0])); + app_bt_device.codec_type[stream_id_flag.id] = BTIF_AVDTP_CODEC_TYPE_NON_A2DP; + //0x75 0x00 0x00 0x00Vid + //0x03 0x01 Codec id + if(Info->p.codec->elements[0]==0x75&& + Info->p.codec->elements[4]==0x03&& + Info->p.codec->elements[5]==0x01 + ){ + setconfig_codec.elements = a2dp_scalable_avdtpcodec.elements; + } + else{ + if(Info->p.codec->pstreamflags!=NULL) + Info->p.codec->pstreamflags[0] &= ~APP_A2DP_STRM_FLAG_QUERY_CODEC; + else{ + ASSERT(false, "pstreamflags not init .."); + } + } + + a2dp_channel_num[stream_id_flag.id] = 2; + } +#endif +#if defined(A2DP_LHDC_ON) + if (current_codec_type == A2DP_NON_CODEC_TYPE_LHDC) { + TRACE(2,"##codecType: LHDC Codec, Element length = %d, AVDTP_MAX_CODEC_ELEM_SIZE = %d\n", Info->p.configReq->codec.elemLen, BTIF_AVDTP_MAX_CODEC_ELEM_SIZE); + app_bt_device.codec_type[stream_id_flag.id] = BTIF_AVDTP_CODEC_TYPE_NON_A2DP; + a2dp_channel_num[stream_id_flag.id] = 2; + a2dp_lhdc_config(&(Info->p.configReq->codec.elements[0])); + } +#endif +#if defined(A2DP_LDAC_ON) + if (current_codec_type == A2DP_NON_CODEC_TYPE_LDAC) { + TRACE(2,"##codecType: LDAC Codec, Element length = %d, AVDTP_MAX_CODEC_ELEM_SIZE = %d\n", Info->p.configReq->codec.elemLen, BTIF_AVDTP_MAX_CODEC_ELEM_SIZE); + app_bt_device.codec_type[stream_id_flag.id] = BTIF_AVDTP_CODEC_TYPE_NON_A2DP; + a2dp_channel_num[stream_id_flag.id] = 2; + a2dp_ldac_config(&(Info->p.configReq->codec.elements[0])); + } +#endif + }else + + + { + TRACE(5,"app_bt_device.sample_rate::elements[0] %d BITPOOL:%d/%d %02x/%02x\n", Info->p.codec->elements[0], + Info->p.codec->elements[2], + Info->p.codec->elements[3], + Info->p.codec->elements[2], + Info->p.codec->elements[3]); + + app_bt_device.codec_type[stream_id_flag.id] = BTIF_AVDTP_CODEC_TYPE_SBC; + app_bt_device.sample_bit[stream_id_flag.id] = 16; + app_bt_device.sample_rate[stream_id_flag.id] = (Info->p.configReq->codec.elements[0] & A2D_SBC_IE_SAMP_FREQ_MSK); + + if(Info->p.configReq->codec.elements[0] & A2D_SBC_IE_CH_MD_MONO) + a2dp_channel_num[stream_id_flag.id] = 1; + else + a2dp_channel_num[stream_id_flag.id] = 2; + } +#ifdef __A2DP_AVDTP_CP__ + if(Info->p.configReq->cp.cpType==BTIF_AVDTP_CP_TYPE_SCMS_T) + { + app_bt_device.avdtp_cp[stream_id_flag.id] = 1; + } +#endif +#endif + if (btif_a2dp_is_stream_device_has_delay_reporting(Stream)) + { + btif_a2dp_set_sink_delay(Stream, 150); + } + break; +#ifdef __A2DP_AVDTP_CP__ + case BTIF_A2DP_EVENT_CP_INFO: + TRACE(2,"::A2DP_EVENT_CP_INFO %d cpType: %x\n", Info->event, Info->p.cp->cpType); + setconfig_cp[stream_id_flag.id].cpType = Info->p.cp->cpType; + setconfig_cp[stream_id_flag.id].data = Info->p.cp->data; + setconfig_cp[stream_id_flag.id].dataLen = Info->p.cp->dataLen; + if(Info->p.cp && Info->p.cp->cpType == BTIF_AVDTP_CP_TYPE_SCMS_T) + { + app_bt_device.avdtp_cp[stream_id_flag.id] = 1; + } + else + { + app_bt_device.avdtp_cp[stream_id_flag.id] = 0; + } + btif_a2dp_set_copy_protection_enable(Stream, app_bt_device.avdtp_cp[stream_id_flag.id]); + break; + case BTIF_A2DP_EVENT_STREAM_SECURITY_IND: + TRACE(1,"::A2DP_EVENT_STREAM_SECURITY_IND %d\n", Info->event); + DUMP8("%x ",Info->p.data,Info->len); + btif_a2dp_security_control_rsp(Stream,&Info->p.data[1],Info->len-1,Info->error); + break; + case BTIF_A2DP_EVENT_STREAM_SECURITY_CNF: + app_bt_device.avdtp_cp[stream_id_flag.id]=1; + TRACE(1,"::A2DP_EVENT_STREAM_SECURITY_CNF %d\n", Info->event); + break; +#endif + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + case BTIF_A2DP_EVENT_STREAM_SBC_PACKET_SENT: + //TRACE(0,"@sbc be send succ"); + if(app_bt_device.src_or_snk==BT_DEVICE_SRC) + { + a2dp_source_notify_send(); + } + break; +#endif + + } +#if defined(IBRT) + app_tws_ibrt_profile_callback(BTIF_APP_A2DP_PROFILE_ID,(void *)Stream, (void *)info); +#endif +} + +void a2dp_suspend_music_force(void) +{ + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC,BT_DEVICE_ID_1,0); +#ifdef __BT_ONE_BRING_TWO__ + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC,BT_DEVICE_ID_2,0); +#endif +} + +int a2dp_volume_get(enum BT_DEVICE_ID_T id) +{ + int vol = TGT_VOLUME_LEVEL_15; + + btif_remote_device_t *remDev = NULL; + nvrec_btdevicerecord *record = NULL; + + if (id >= BT_DEVICE_NUM) + { + TRACE(2,"%s error id %d", __func__, id); + } + + remDev = btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[id]); + if (remDev && !nv_record_btdevicerecord_find(btif_me_get_remote_device_bdaddr(remDev),&record)){ + vol = record->device_vol.a2dp_vol; + }else if (app_audio_manager_a2dp_is_active(id)){ + vol = app_bt_stream_a2dpvolume_get(); + }else{ + vol = TGT_VOLUME_LEVEL_15; + } + + if (vol == TGT_VOLUME_LEVEL_MUTE){ + vol = 0; + }else{ + if (vol >= TGT_VOLUME_LEVEL_15){ + vol = TGT_VOLUME_LEVEL_15; + }else if (vol <= TGT_VOLUME_LEVEL_0){ + vol = TGT_VOLUME_LEVEL_0; + } + vol = 8*(vol-1); + } + + if (vol > 0x7f) + vol = 0x7f; + + //TRACE(2,"get vol raw:%d %d/127", app_bt_stream_volume_get_ptr()->a2dp_vol, vol); + + return (vol); +} + +void a2dp_volume_local_set(enum BT_DEVICE_ID_T id, int8_t vol) +{ + btif_remote_device_t *remDev = NULL; + nvrec_btdevicerecord *record = NULL; + remDev = btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[id]); + if (remDev){ + if (!nv_record_btdevicerecord_find(btif_me_get_remote_device_bdaddr(remDev),&record)){ + nv_record_btdevicerecord_set_a2dp_vol(record, vol); + } + } + + if(app_bt_stream_volume_get_ptr()->a2dp_vol != vol){ +#if defined(NEW_NV_RECORD_ENABLED) + nv_record_btdevicevolume_set_a2dp_vol(app_bt_stream_volume_get_ptr(), vol); +#endif +#ifndef FPGA + nv_record_touch_cause_flush(); +#endif + } +} + +int a2dp_volume_set(enum BT_DEVICE_ID_T id, uint8_t vol) +{ + int dest_vol; + + if (!vol){ + dest_vol = TGT_VOLUME_LEVEL_MUTE; + }else{ + if (0x7f == vol) + { + dest_vol = TGT_VOLUME_LEVEL_15; + } + else + { + dest_vol = (((int)vol&0x7f)<<4)/128 + 1; + } + if (dest_vol > TGT_VOLUME_LEVEL_15){ + dest_vol = TGT_VOLUME_LEVEL_15; + }else if (dest_vol < TGT_VOLUME_LEVEL_0){ + dest_vol = TGT_VOLUME_LEVEL_0; + } + } + + a2dp_volume_local_set(id, dest_vol); + if (app_audio_manager_a2dp_is_active(id)){ + app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_SET, dest_vol); + } + + TRACE(2,"put vol raw:%d/127 %d", vol, dest_vol); + + return (vol); +} + +bool a2dp_is_music_ongoing(void) +{ +#ifdef __BT_ONE_BRING_TWO__ + return app_bt_device.a2dp_streamming[BT_DEVICE_ID_1] || + app_bt_device.a2dp_streamming[BT_DEVICE_ID_2]; +#else + return app_bt_device.a2dp_streamming[BT_DEVICE_ID_1]; +#endif + +} + +void btapp_a2dp_report_speak_gain(void) +{ +#ifdef BTIF_AVRCP_ADVANCED_CONTROLLER + uint8_t i; + int vol; + btif_remote_device_t *remDev = NULL; + btif_link_mode_t mode = BTIF_BLM_SNIFF_MODE; + + for(i=0; itransId, + app_bt_device.a2dp_state[i], + app_bt_device.a2dp_streamming[i], + app_bt_device.volume_report[i]); + */ + + osapi_lock_stack(); + if((vol_ctrl_done_flag[i]==TX_DONE_FLAG_INIT)||(vol_ctrl_done_flag[i]==TX_DONE_FLAG_SUCCESS)){ + remDev = btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[i]); + if (remDev){ + mode = btif_me_get_current_mode(remDev); + }else{ + mode = BTIF_BLM_SNIFF_MODE; + } + if ((app_bt_device.a2dp_state[i] == 1) && + (app_bt_device.a2dp_streamming[i] == 1) && + (app_bt_device.volume_report[i] == BTIF_AVCTP_RESPONSE_INTERIM) && + (mode == BTIF_BLM_ACTIVE_MODE)){ + app_bt_device.volume_report[i] = BTIF_AVCTP_RESPONSE_CHANGED; + // TRACE(1,"btapp_a2dp_report_speak_gain transId:%d\n", app_bt_device.avrcp_notify_rsp[i]->transId); + if (app_bt_device.avrcp_notify_rsp[i] != NULL){ + + btif_set_app_bt_device_avrcp_notify_rsp_ctype(app_bt_device.avrcp_notify_rsp[i], BTIF_AVCTP_RESPONSE_CHANGED); + vol = a2dp_volume_get((enum BT_DEVICE_ID_T)i); + btif_avrcp_ct_get_absolute_volume_rsp(app_bt_device.avrcp_channel[i], app_bt_device.avrcp_notify_rsp[i], vol); + vol_ctrl_done_flag[i] = TX_DONE_FLAG_TXING; + btif_avrcp_recheck_vol_ctrl_flag(vol_ctrl_done_flag+i); + } + } + } + osapi_unlock_stack(); + } +#endif +} + + + + + +extern "C" bool avdtp_Get_aacEnable_Flag( btif_remote_device_t* remDev, btif_avdtp_stream_t *strm) +{ + TRACE(2,"%s,version=%x", __func__, btif_me_get_remote_device_version(remDev)[1] ); +#if 0//defined(A2DP_AAC_ON) + if(((remDev->remoteVersion[1] == 0x0f) && (remDev->remoteVersion[2] == 0)) || strm->codec->codecType !=AVDTP_CODEC_TYPE_MPEG2_4_AAC){ + return TRUE; + }else + return FALSE; +#else + return TRUE; +#endif + + +} + + + +#ifdef __TWS__ +void app_AVRCP_SendCustomCmdToMobile(uint8_t* ptrData, uint32_t len) +{ + if (is_slave_tws_mode()) + { + return; + } + + btif_avrcp_send_custom_cmd_generic(app_bt_device.avrcp_channel[BT_DEVICE_ID_1], ptrData, len); +} + + +void app_AVRCP_SendCustomCmdToTws(uint8_t* ptrData, uint32_t len) +{ + if (is_slave_tws_mode()) + { + btif_avrcp_send_custom_cmd_generic(app_bt_device.avrcp_channel[BT_DEVICE_ID_1], ptrData, len); + } + else if (is_master_tws_mode()) + { + btif_avrcp_channel_t* chnl = btif_get_avrcp_channel(tws_get_avrcp_channel_hdl()); + btif_avrcp_send_custom_cmd_generic(chnl, ptrData, len); + } +} + +#endif + +static void app_AVRCP_sendCustomCmdRsp(uint8_t device_id, btif_avrcp_channel_t *chnl, uint8_t isAccept, uint8_t transId) +{ + if (app_bt_device.avrcp_control_rsp[device_id] == NULL) + { + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_control_rsp[device_id]); + } + + + btif_avrcp_set_control_rsp_cmd(app_bt_device.avrcp_control_rsp[device_id],transId, BTIF_AVCTP_RESPONSE_ACCEPTED); + + btif_avrcp_ct_accept_custom_cmd_rsp(chnl, app_bt_device.avrcp_control_rsp[device_id], isAccept); +} + +static void app_AVRCP_CustomCmd_Received(uint8_t* ptrData, uint32_t len) +{ + TRACE(1,"AVRCP Custom Command Received %d bytes data:", len); + DUMP8("0x%02x ", ptrData, len); +} + + + diff --git a/services/bt_app/app_a2dp.h b/services/bt_app/app_a2dp.h new file mode 100644 index 0000000..8cf540b --- /dev/null +++ b/services/bt_app/app_a2dp.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_A2DP_H__ +#define __APP_A2DP_H__ +#include "btapp.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#define A2DP_NON_CODEC_TYPE_NON 0 +#define A2DP_NON_CODEC_TYPE_LHDC 1 +#define A2DP_NON_CODEC_TYPE_LDAC 2 +#define A2DP_NON_CODEC_TYPE_SCALABLE 3 + +uint8_t a2dp_get_current_codec_type(uint8_t *elements); + +bool a2dp_is_music_ongoing(void); +int a2dp_volume_set(enum BT_DEVICE_ID_T id, uint8_t vol); +#if defined(A2DP_LDAC_ON) +void app_ibrt_restore_ldac_info(uint8_t sample_freq); +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/bt_app/app_a2dp_source.cpp b/services/bt_app/app_a2dp_source.cpp new file mode 100644 index 0000000..2e00c6c --- /dev/null +++ b/services/bt_app/app_a2dp_source.cpp @@ -0,0 +1,872 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + +#include "app_a2dp_source.h" +#include "app_overlay.h" +#include "a2dp_api.h" + + + +uint8_t *a2dp_linein_buff; +static char a2dp_transmit_buffer[A2DP_TRANS_SIZE]; + +sbcbank_t sbcbank; + +A2DP_SOURCE_STRUCT a2dp_source; + + +static sbcpack_t *get_sbcPacket(void) +{ + int index = sbcbank.free; + sbcbank.free +=1; + if(sbcbank.free == 1) { + sbcbank.free = 0; + } + return &(sbcbank.sbcpacks[index]); +} + + + +#if 0 +typedef struct { + AvrcpAdvancedPdu pdu; + uint8_t para_buf[10]; +}APP_A2DP_AVRCPADVANCEDPDU; + + + +extern osPoolId app_a2dp_avrcpadvancedpdu_mempool; + +#define app_a2dp_avrcpadvancedpdu_mempool_init() do{ \ + if (app_a2dp_avrcpadvancedpdu_mempool == NULL) \ + app_a2dp_avrcpadvancedpdu_mempool = osPoolCreate(osPool(app_a2dp_avrcpadvancedpdu_mempool)); \ + }while(0); + +#define app_a2dp_avrcpadvancedpdu_mempool_calloc(buf) do{ \ + APP_A2DP_AVRCPADVANCEDPDU * avrcpadvancedpdu; \ + avrcpadvancedpdu = (APP_A2DP_AVRCPADVANCEDPDU *)osPoolCAlloc(app_a2dp_avrcpadvancedpdu_mempool); \ + buf = &(avrcpadvancedpdu->pdu); \ + buf->parms = avrcpadvancedpdu->para_buf; \ + }while(0); + +#define app_a2dp_avrcpadvancedpdu_mempool_free(buf) do{ \ + osPoolFree(app_a2dp_avrcpadvancedpdu_mempool, buf); \ + }while(0); + + +void a2dp_source_volume_local_set(int8_t vol) +{ + app_bt_stream_volume_get_ptr()->a2dp_vol = vol; + nv_record_touch_cause_flush(); +} + +static int a2dp_volume_get(void) +{ + int vol = app_bt_stream_volume_get_ptr()->a2dp_vol; + + vol = 8*vol-1; + if (vol > (0x7f-1)) + vol = 0x7f; + + return (vol); +} + + +static int a2dp_volume_set(U8 vol) +{ + int dest_vol; + + dest_vol = (((int)vol&0x7f)<<4)/0x7f + 1; + + if (dest_vol > TGT_VOLUME_LEVEL_15) + dest_vol = TGT_VOLUME_LEVEL_15; + if (dest_vol < TGT_VOLUME_LEVEL_0) + dest_vol = TGT_VOLUME_LEVEL_0; + + a2dp_source_volume_local_set(dest_vol); + app_bt_stream_volumeset(dest_vol); + + return (vol); +} + + + +void avrcp_source_callback_TG(AvrcpChannel *chnl, const AvrcpCallbackParms *Parms) +{ + TRACE(3,"%s : chnl %p, Parms %p,Parms->event\n", __FUNCTION__,chnl, Parms,Parms->event); + + enum BT_DEVICE_ID_T device_id = BT_DEVICE_ID_1; + switch(Parms->event) + { + case AVRCP_EVENT_CONNECT: + if(0)//(chnl->avrcpVersion >=0x103) + { + TRACE(1,"::%s AVRCP_GET_CAPABILITY\n",__FUNCTION__); + if (app_bt_device.avrcp_cmd1[device_id] == NULL) + app_a2dp_avrcpadvancedpdu_mempool_calloc(app_bt_device.avrcp_cmd1[device_id]); + AVRCP_CtGetCapabilities(chnl,app_bt_device.avrcp_cmd1[device_id],AVRCP_CAPABILITY_EVENTS_SUPPORTED); + } + + app_bt_device.avrcp_channel[device_id].avrcpState = AVRCP_STATE_CONNECTED; + + TRACE(3,"::%s AVRCP_EVENT_CONNECT %x,device_id=%d\n",__FUNCTION__, chnl->avrcpVersion,device_id); + break; + case AVRCP_EVENT_DISCONNECT: + TRACE(1,"::%s AVRCP_EVENT_DISCONNECT",__FUNCTION__); + app_bt_device.avrcp_channel[device_id].avrcpState = AVRCP_STATE_DISCONNECTED; + if (app_bt_device.avrcp_get_capabilities_rsp[device_id]){ + app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_get_capabilities_rsp[device_id]); + app_bt_device.avrcp_get_capabilities_rsp[device_id] = NULL; + } + if (app_bt_device.avrcp_control_rsp[device_id]){ + app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_control_rsp[device_id]); + app_bt_device.avrcp_control_rsp[device_id] = NULL; + } + if (app_bt_device.avrcp_notify_rsp[device_id]){ + app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_notify_rsp[device_id]); + app_bt_device.avrcp_notify_rsp[device_id] = NULL; + } + + if (app_bt_device.avrcp_cmd1[device_id]){ + app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_cmd1[device_id]); + app_bt_device.avrcp_cmd1[device_id] = NULL; + } + if (app_bt_device.avrcp_cmd2[device_id]){ + app_a2dp_avrcpadvancedpdu_mempool_free(app_bt_device.avrcp_cmd2[device_id]); + app_bt_device.avrcp_cmd2[device_id] = NULL; + } + app_bt_device.volume_report[device_id] = 0; + break; + case AVRCP_EVENT_RESPONSE: + TRACE(3,"::%s AVRCP_EVENT_RESPONSE op=%x,status=%x\n",__FUNCTION__, Parms->advOp,Parms->status); + + break; + case AVRCP_EVENT_PANEL_CNF: + TRACE(4,"::%s AVRCP_EVENT_PANEL_CNF %x,%x,%x",__FUNCTION__, + Parms->p.panelCnf.response,Parms->p.panelCnf.operation,Parms->p.panelCnf.press); + break; + case AVRCP_EVENT_ADV_TX_DONE: + TRACE(4,"::%s AVRCP_EVENT_ADV_TX_DONE device_id=%d,status=%x,errorcode=%x\n",__FUNCTION__,device_id,Parms->status,Parms->errorCode); + TRACE(3,"::%s AVRCP_EVENT_ADV_TX_DONE op:%d, transid:%x\n", __FUNCTION__,Parms->p.adv.txPdu->op,Parms->p.adv.txPdu->transId); + if (Parms->p.adv.txPdu->op == AVRCP_OP_GET_CAPABILITIES){ + if (app_bt_device.avrcp_get_capabilities_rsp[device_id] == Parms->p.adv.txPdu){ + app_bt_device.avrcp_get_capabilities_rsp[device_id] = NULL; + app_a2dp_avrcpadvancedpdu_mempool_free(Parms->p.adv.txPdu); + } + } + + break; + case AVRCP_EVENT_COMMAND: +#ifndef __AVRCP_EVENT_COMMAND_VOLUME_SKIP__ + TRACE(3,"::%s AVRCP_EVENT_COMMAND device_id=%d,role=%x\n",__FUNCTION__,device_id,chnl->role); + TRACE(3,"::%s AVRCP_EVENT_COMMAND ctype=%x,subunitype=%x\n",__FUNCTION__, Parms->p.cmdFrame->ctype,Parms->p.cmdFrame->subunitType); + TRACE(3,"::%s AVRCP_EVENT_COMMAND subunitId=%x,opcode=%x\n",__FUNCTION__, Parms->p.cmdFrame->subunitId,Parms->p.cmdFrame->opcode); + TRACE(3,"::%s AVRCP_EVENT_COMMAND operands=%x,operandLen=%x\n",__FUNCTION__, Parms->p.cmdFrame->operands,Parms->p.cmdFrame->operandLen); + TRACE(2,"::%s AVRCP_EVENT_COMMAND more=%x\n", Parms->p.cmdFrame->more); + if(Parms->p.cmdFrame->ctype == AVRCP_CTYPE_STATUS) + { + uint32_t company_id = *(Parms->p.cmdFrame->operands+2) + ((uint32_t)(*(Parms->p.cmdFrame->operands+1))<<8) + ((uint32_t)(*(Parms->p.cmdFrame->operands))<<16); + TRACE(2,"::%s AVRCP_EVENT_COMMAND company_id=%x\n",__FUNCTION__, company_id); + if(company_id == 0x001958) //bt sig + { + AvrcpOperation op = *(Parms->p.cmdFrame->operands+3); + uint8_t oplen = *(Parms->p.cmdFrame->operands+6)+ ((uint32_t)(*(Parms->p.cmdFrame->operands+5))<<8); + TRACE(3,"::%s AVRCP_EVENT_COMMAND op=%x,oplen=%x\n",__FUNCTION__, op,oplen); + switch(op) + { + case AVRCP_OP_GET_CAPABILITIES: + { + uint8_t event = *(Parms->p.cmdFrame->operands+7); + if(event==AVRCP_CAPABILITY_COMPANY_ID) + { + TRACE(1,"::%s AVRCP_EVENT_COMMAND send support compay id",__FUNCTION__); + } + else if(event == AVRCP_CAPABILITY_EVENTS_SUPPORTED) + { + TRACE(2,"::%s AVRCP_EVENT_COMMAND send support event transId:%d", __FUNCTION__,Parms->p.cmdFrame->transId); + chnl->adv.eventMask = AVRCP_ENABLE_VOLUME_CHANGED; ///volume control + if (app_bt_device.avrcp_get_capabilities_rsp[device_id] == NULL) + app_a2dp_avrcpadvancedpdu_mempool_calloc(app_bt_device.avrcp_get_capabilities_rsp[device_id]); + app_bt_device.avrcp_get_capabilities_rsp[device_id]->transId = Parms->p.cmdFrame->transId; + app_bt_device.avrcp_get_capabilities_rsp[device_id]->ctype = AVCTP_RESPONSE_IMPLEMENTED_STABLE; + TRACE(2,"::%s AVRCP_EVENT_COMMAND send support event transId:%d", __FUNCTION__,app_bt_device.avrcp_get_capabilities_rsp[device_id]->transId); + AVRCP_CtGetCapabilities_Rsp(chnl,app_bt_device.avrcp_get_capabilities_rsp[device_id],AVRCP_CAPABILITY_EVENTS_SUPPORTED,chnl->adv.eventMask); + } + else + { + TRACE(1,"::%s AVRCP_EVENT_COMMAND send error event value",__FUNCTION__); + } + } + break; + } + + } + + }else if(Parms->p.cmdFrame->ctype == AVCTP_CTYPE_CONTROL){ + TRACE(1,"::%s AVRCP_EVENT_COMMAND AVCTP_CTYPE_CONTROL\n",__FUNCTION__); + DUMP8("%02x ", Parms->p.cmdFrame->operands, Parms->p.cmdFrame->operandLen); + if (Parms->p.cmdFrame->operands[3] == AVRCP_OP_SET_ABSOLUTE_VOLUME){ + TRACE(2,"::%s AVRCP_EID_VOLUME_CHANGED transId:%d\n", __FUNCTION__,Parms->p.cmdFrame->transId); + a2dp_volume_set(Parms->p.cmdFrame->operands[7]); + if (app_bt_device.avrcp_control_rsp[device_id] == NULL) + app_a2dp_avrcpadvancedpdu_mempool_calloc(app_bt_device.avrcp_control_rsp[device_id]); + app_bt_device.avrcp_control_rsp[device_id]->transId = Parms->p.cmdFrame->transId; + app_bt_device.avrcp_control_rsp[device_id]->ctype = AVCTP_RESPONSE_ACCEPTED; + DUMP8("%02x ", Parms->p.cmdFrame->operands, Parms->p.cmdFrame->operandLen); + AVRCP_CtAcceptAbsoluteVolume_Rsp(chnl, app_bt_device.avrcp_control_rsp[device_id], Parms->p.cmdFrame->operands[7]); + } + }else if (Parms->p.cmdFrame->ctype == AVCTP_CTYPE_NOTIFY){ + BtStatus status; + TRACE(1,"::%s AVRCP_EVENT_COMMAND AVCTP_CTYPE_NOTIFY\n",__FUNCTION__); + DUMP8("%02x ", Parms->p.cmdFrame->operands, Parms->p.cmdFrame->operandLen); + if (Parms->p.cmdFrame->operands[7] == AVRCP_EID_VOLUME_CHANGED){ + TRACE(2,"::%s AVRCP_EID_VOLUME_CHANGED transId:%d\n", __FUNCTION__,Parms->p.cmdFrame->transId); + if (app_bt_device.avrcp_notify_rsp[device_id] == NULL) + app_a2dp_avrcpadvancedpdu_mempool_calloc(app_bt_device.avrcp_notify_rsp[device_id]); + app_bt_device.avrcp_notify_rsp[device_id]->transId = Parms->p.cmdFrame->transId; + app_bt_device.avrcp_notify_rsp[device_id]->ctype = AVCTP_RESPONSE_INTERIM; + app_bt_device.volume_report[device_id] = AVCTP_RESPONSE_INTERIM; + status = AVRCP_CtGetAbsoluteVolume_Rsp(chnl, app_bt_device.avrcp_notify_rsp[device_id], a2dp_volume_get()); + TRACE(2,"::%s AVRCP_EVENT_COMMAND AVRCP_EID_VOLUME_CHANGED nRet:%x\n",__FUNCTION__,status); + } + } +#endif + break; + case AVRCP_EVENT_ADV_CMD_TIMEOUT: + TRACE(3,"::%s AVRCP_EVENT_ADV_CMD_TIMEOUT device_id=%d,role=%x\n",__FUNCTION__,device_id,chnl->role); + break; + } +} +#endif + +osMutexId a2dp_source_mutex_id = NULL; +osMutexDef(a2dp_source_mutex); + +static void a2dp_source_mutex_lock(void) +{ + osMutexWait(a2dp_source_mutex_id, osWaitForever); +} + +static void a2dp_source_mutex_unlock(void) +{ + osMutexRelease(a2dp_source_mutex_id); +} + +static void a2dp_source_sem_lock(a2dp_source_lock_t * lock) +{ + osSemaphoreWait(lock->_osSemaphoreId, osWaitForever); +} + +static void a2dp_source_sem_unlock(a2dp_source_lock_t * lock) +{ + + osSemaphoreRelease(lock->_osSemaphoreId); +} + + + +static void a2dp_source_reset_send_lock(void) +{ + PSCB p_scb =(PSCB)(a2dp_source.sbc_send_lock._osSemaphoreDef.semaphore); + uint32_t lock = int_lock(); + p_scb->tokens = 0; + int_unlock(lock); +} + + +static bool a2dp_source_is_send_wait(void) +{ + bool ret = false; + uint32_t lock = int_lock(); + PSCB p_scb =(PSCB)(a2dp_source.sbc_send_lock._osSemaphoreDef.semaphore); + if(p_scb->p_lnk){ + ret = true; + } + int_unlock(lock); + return ret; +} + + +static void a2dp_source_wait_pcm_data(void) +{ + + a2dp_source_lock_t *lock = &(a2dp_source.data_lock); + PSCB p_scb =(PSCB)(lock->_osSemaphoreDef.semaphore); + uint32_t iflag = int_lock(); + p_scb->tokens = 0; + int_unlock(iflag); + a2dp_source_sem_lock(lock); +} + +static void a2dp_source_put_data(void) +{ + a2dp_source_lock_t *lock = &(a2dp_source.data_lock); + a2dp_source_sem_unlock(lock); +} + +#if 0 +static void a2dp_source_lock_sbcsending(void * channel) +{ + tws_lock_t *lock = &(a2dp_source.sbc_send_lock); + sem_lock(lock); +} +static void a2dp_source_unlock_sbcsending(void * channel) +{ + tws_lock_t *lock = &(a2dp_source.sbc_send_lock); + sem_unlock(lock); +} +#endif + +static int32_t a2dp_source_wait_sent(uint32_t timeout) +{ + int32_t ret = 0; + a2dp_source_lock_t *lock = &(a2dp_source.sbc_send_lock); + a2dp_source_reset_send_lock(); + ret = osSemaphoreWait(lock->_osSemaphoreId, timeout); + return ret; + +} + +void a2dp_source_notify_send(void) +{ + if (a2dp_source_is_send_wait()){ //task wait lock + // TWS_DBLOG("\nNOTIFY SEND\n"); + a2dp_source_sem_unlock(&(a2dp_source.sbc_send_lock)); + } + +} + + +//loop write +static int A2dpSourceEnCQueue(CQueue *Q, CQItemType *e, unsigned int len) +{ + int status=CQ_OK; + if (AvailableOfCQueue(Q) < (int)len) { + Q->write=0; + Q->len=0; + Q->read=0; + status=CQ_ERR; + } + else + { + status=CQ_OK; + } + + Q->len += len; + + while(len > 0) { + Q->base[Q->write] = *e; + + ++Q->write; + ++e; + --len; + + if(Q->write >= Q->size) + Q->write = 0; + } + + //TRACE(1,"Q->len:%d ", Q->len); + + return status; +} + + + + +static int a2dp_source_pcm_buffer_write(uint8_t * pcm_buf, uint16_t len) +{ + int status; + //TWS_DBLOG("\nenter: %s %d\n",__FUNCTION__,__LINE__); + a2dp_source_mutex_lock(); + status = A2dpSourceEnCQueue(&(a2dp_source.pcm_queue), pcm_buf, len); + a2dp_source_mutex_unlock(); + //TWS_DBLOG("\nexit: %s %d\n",__FUNCTION__,__LINE__); + return status; +} + +static int a2dp_source_pcm_buffer_read(uint8_t *buff, uint16_t len) +{ + uint8_t *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + int status; + a2dp_source_mutex_lock(); + status = PeekCQueue(&(a2dp_source.pcm_queue), len, &e1, &len1, &e2, &len2); + if (len==(len1+len2)){ + memcpy(buff,e1,len1); + memcpy(buff+len1,e2,len2); + DeCQueue(&(a2dp_source.pcm_queue), 0, len); + }else{ + //SOURCE_DBLOG("memset buffer"); + memset(buff, 0x00, len); + status = -1; + } + a2dp_source_mutex_unlock(); + return status; +} + +uint32_t a2dp_source_linein_more_pcm_data(uint8_t * pcm_buf, uint32_t len) +{ +#if 1 + int status; + status = a2dp_source_pcm_buffer_write(pcm_buf,len); + //pcm data from adc + //DUMP8("%02x ",pcm_buf, 10); + if(status !=CQ_OK) + { + SOURCE_DBLOG("linin buff overflow!"); + } + a2dp_source_put_data(); + return len; +#else +int status; +status = a2dp_source_pcm_buffer_write(pcm_buf,len); +//pcm data from adc +//DUMP8("%02x ",pcm_buf, 10); +if(status !=CQ_OK) +{ + SOURCE_DBLOG("linin buff overflow!"); +} +if(((app_bt_device.input_onoff==1)&&(a2dp_source.pcm_queue.len >10*1024))||(app_bt_device.input_onoff==2)) +{ + a2dp_source_put_data(); + app_bt_device.input_onoff=2; +} + +return len; + +#endif +} + + +static btif_handler a2dp_source_handler; +static uint8_t app_a2dp_source_find_process=0; + + +void app_a2dp_source_stop_find(void) +{ + app_a2dp_source_find_process=0; + //ME_UnregisterGlobalHandler(&a2dp_source_handler); +} + +#if 0 +static void bt_a2dp_source_call_back(const BtEvent* event) +{ + switch (event->eType) { + case BTEVENT_HCI_COMMAND_SENT: + case BTEVENT_ACL_DATA_NOT_ACTIVE: + return; + case BTEVENT_ACL_DATA_ACTIVE: + CmgrHandler *cmgrHandler; + /* Start the sniff timer */ + cmgrHandler = CMGR_GetAclHandler(event->p.remDev); + if (cmgrHandler) + app_bt_CMGR_SetSniffTimer(cmgrHandler, NULL, CMGR_SNIFF_TIMER); + return; + } + + TRACE(1,"SRC app_bt_golbal_handle evt = %d",event->eType); + + switch(event->eType){ + case BTEVENT_NAME_RESULT: + SOURCE_DBLOG("\n%s %d BTEVENT_NAME_RESULT\n",__FUNCTION__,__LINE__); + break; + case BTEVENT_INQUIRY_RESULT: + SOURCE_DBLOG("\n%s %d BTEVENT_INQUIRY_RESULT\n",__FUNCTION__,__LINE__); + DUMP8("%02x ", event->p.inqResult.bdAddr.addr, 6); + SOURCE_DBLOG("inqmode = %x",event->p.inqResult.inqMode); + DUMP8("%02x ", event->p.inqResult.extInqResp, 20); + SOURCE_DBLOG("classdevice=%x",event->p.inqResult.classOfDevice); + ///check the class of device to find the handfree device + if(event->p.inqResult.classOfDevice & COD_MAJOR_AUDIO) + //if((event->p.inqResult.classOfDevice & COD_MAJOR_AUDIO)&&(!memcmp(event->p.inqResult.bdAddr.addr,"\x36\x35\x34",3))) + { + memcpy(app_bt_device.inquried_snk_bdAddr.addr,event->p.inqResult.bdAddr.addr,sizeof(event->p.inqResult.bdAddr.addr)); + DUMP8("%02x ",app_bt_device.inquried_snk_bdAddr.addr, 6); + ME_CancelInquiry(); + app_a2dp_source_stop_find(); + } + + break; + case BTEVENT_INQUIRY_COMPLETE: + SOURCE_DBLOG("\n%s %d BTEVENT_INQUIRY_COMPLETE\n",__FUNCTION__,__LINE__); + app_a2dp_source_stop_find(); + break; + /** The Inquiry process is canceled. */ + case BTEVENT_INQUIRY_CANCELED: + SOURCE_DBLOG("\n%s %d BTEVENT_INQUIRY_CANCELED\n",__FUNCTION__,__LINE__); + SOURCE_DBLOG("start to connect peer device"); + A2DP_OpenStream(&app_bt_device.a2dp_stream[BT_DEVICE_ID_1], (BT_BD_ADDR *)&app_bt_device.inquried_snk_bdAddr); + break; + case BTEVENT_LINK_CONNECT_CNF: + case BTEVENT_LINK_CONNECT_IND: + SOURCE_DBLOG("CONNECT_IND/CNF evt:%d errCode:0x%0x newRole:%d activeCons:%d",event->eType, event->errCode, event->p.remDev->role, MEC(activeCons)); +#if defined(__BTIF_EARPHONE__) && defined(__BTIF_AUTOPOWEROFF__) && !defined(FPGA) + if (MEC(activeCons) == 0){ + app_start_10_second_timer(APP_POWEROFF_TIMER_ID); + }else{ + app_stop_10_second_timer(APP_POWEROFF_TIMER_ID); + } +#endif + if (MEC(activeCons) > 1){ + app_bt_MeDisconnectLink(event->p.remDev); + } + default: + //SOURCE_DBLOG("\n%s %d etype:%d\n",__FUNCTION__,__LINE__,event->eType); + break; + + } + + app_bt_role_manager_process(event); + app_bt_accessible_manager_process(event); + app_bt_sniff_manager_process(event); + app_bt_golbal_handle_hook(event); + + //SOURCE_DBLOG("\nexit: %s %d\n",__FUNCTION__,__LINE__); + +} + +#else +uint8_t source_bt_addr[6]={0x88,0xaa,0x33,0x22,0x11,0x11}; +//uint8_t source_bt_addr[6]={0x85,0x7e,0xaa,0x3c,0xd0,0xe8}; + +static void bt_a2dp_source_call_back(const btif_event_t* Event) +{ + + uint8_t etype = btif_me_get_callback_event_type(Event); + btif_remote_device_t *remDev; + + + switch (etype) { + case BTIF_BTEVENT_HCI_COMMAND_SENT: + case BTIF_BTEVENT_ACL_DATA_NOT_ACTIVE: + return; + case BTIF_BTEVENT_ACL_DATA_ACTIVE: + + btif_cmgr_handler_t *cmgrHandler; + /* Start the sniff timer */ + cmgrHandler = btif_cmgr_get_acl_handler(btif_me_get_callback_event_rem_dev( Event)); + if (cmgrHandler) + app_bt_CMGR_SetSniffTimer(cmgrHandler, NULL, BTIF_CMGR_SNIFF_TIMER); + return; + } + + TRACE(1,"SRC app_bt_golbal_handle evt = %d",etype); + + switch(etype){ + case BTIF_BTEVENT_NAME_RESULT: + SOURCE_DBLOG("\n%s %d BTEVENT_NAME_RESULT\n",__FUNCTION__,__LINE__); + break; + case BTIF_BTEVENT_INQUIRY_RESULT: + remDev=btif_me_get_callback_event_rem_dev(Event); + SOURCE_DBLOG("\n%s %d BTEVENT_INQUIRY_RESULT\n",__FUNCTION__,__LINE__); + DUMP8("%02x ", btif_me_get_callback_event_inq_result_bd_addr_addr(Event), 6); + SOURCE_DBLOG("inqmode = %x",btif_me_get_callback_event_inq_result_inq_mode(Event)); + DUMP8("%02x ", btif_me_get_callback_event_inq_result_ext_inq_resp(Event), 20); + SOURCE_DBLOG("classdevice=%x",btif_me_get_callback_event_inq_result_classofdevice(Event)); + ///check the class of device to find the handfree device + //if(btif_me_get_callback_event_inq_result_classofdevice(Event) & BTIF_COD_MAJOR_AUDIO) + if((btif_me_get_callback_event_inq_result_classofdevice(Event) & BTIF_COD_MAJOR_AUDIO) && \ + (!memcmp(btif_me_get_callback_event_inq_result_bd_addr_addr(Event),source_bt_addr,6))) + { + memcpy(app_bt_device.inquried_snk_bdAddr.addr,btif_me_get_callback_event_inq_result_bd_addr_addr(Event),6); + DUMP8("%02x ",app_bt_device.inquried_snk_bdAddr.addr, 6); + btif_me_cancel_inquiry(); + app_a2dp_source_stop_find(); + } + + break; + case BTIF_BTEVENT_INQUIRY_COMPLETE: + SOURCE_DBLOG("\n%s %d BTEVENT_INQUIRY_COMPLETE\n",__FUNCTION__,__LINE__); + app_a2dp_source_stop_find(); + break; + /** The Inquiry process is canceled. */ + case BTIF_BTEVENT_INQUIRY_CANCELED: + SOURCE_DBLOG("\n%s %d BTEVENT_INQUIRY_CANCELED\n",__FUNCTION__,__LINE__); + SOURCE_DBLOG("start to connect peer device"); + btif_a2dp_open_stream(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream, (bt_bdaddr_t *)&app_bt_device.inquried_snk_bdAddr); + break; + case BTIF_BTEVENT_LINK_CONNECT_CNF: + case BTIF_BTEVENT_LINK_CONNECT_IND: + SOURCE_DBLOG("CONNECT_IND/CNF evt:%d errCode:0x%0x newRole:%d activeCons:%d",etype,btif_me_get_callback_event_err_code(Event),btif_me_get_remote_device_role(btif_me_get_callback_event_rem_dev(Event)),btif_me_get_activeCons()); +#if defined(__BTIF_EARPHONE__) && defined(__BTIF_AUTOPOWEROFF__) && !defined(FPGA) + if (btif_me_get_activeCons() == 0){ + app_start_10_second_timer(APP_POWEROFF_TIMER_ID); + }else{ + app_stop_10_second_timer(APP_POWEROFF_TIMER_ID); + } +#endif + if (btif_me_get_activeCons() > 1){ + remDev=btif_me_get_callback_event_rem_dev(Event); + app_bt_MeDisconnectLink(remDev); + } + default: + //SOURCE_DBLOG("\n%s %d etype:%d\n",__FUNCTION__,__LINE__,event->eType); + break; + + } + + app_bt_role_manager_process(Event); + app_bt_accessible_manager_process(Event); + app_bt_sniff_manager_process(Event); + + //SOURCE_DBLOG("\nexit: %s %d\n",__FUNCTION__,__LINE__); + +} + + +#endif + + + + +void app_a2dp_start_stream(void) +{ + btif_a2dp_start_stream(&app_bt_device.a2dp_stream[BT_DEVICE_ID_1]); + +} + + + +void app_a2dp_suspend_stream(void) +{ + btif_a2dp_suspend_stream(&app_bt_device.a2dp_stream[BT_DEVICE_ID_1]); +} + + +static void _find_a2dp_sink_peer_device_start(void) +{ + SOURCE_DBLOG("\nenter: %s %d\n",__FUNCTION__,__LINE__); + bt_status_t state; + if(app_a2dp_source_find_process ==0 && app_bt_device.a2dp_state[0]==0) + { + app_a2dp_source_find_process = 1; + + again: + state = btif_me_inquiry(BTIF_BT_IAC_GIAC, 30, 0); + SOURCE_DBLOG("\n%s %d\n",__FUNCTION__,__LINE__); + if (state != BT_STS_PENDING){ + osDelay(500); + goto again; + } + SOURCE_DBLOG("\n%s %d\n",__FUNCTION__,__LINE__); + } +} + +void app_a2dp_source_find_sink(void) +{ + _find_a2dp_sink_peer_device_start(); +} + + +static bool need_init_encoder = true; +//__PSRAMDATA static SbcStreamInfo StreamInfo = {0}; +static btif_sbc_stream_info_short_t StreamInfo = {0}; + +static btif_sbc_encoder_t sbc_encoder; + + +static uint8_t app_a2dp_source_samplerate_2_sbcenc_type(enum AUD_SAMPRATE_T sample_rate) +{ + uint8_t rate=BTIF_SBC_CHNL_SAMPLE_FREQ_16; + switch(sample_rate) + { + case AUD_SAMPRATE_16000: + rate = BTIF_SBC_CHNL_SAMPLE_FREQ_16; + break; + case AUD_SAMPRATE_32000: + rate = BTIF_SBC_CHNL_SAMPLE_FREQ_32; + break; + case AUD_SAMPRATE_44100: + rate = BTIF_SBC_CHNL_SAMPLE_FREQ_44_1; + break; + case AUD_SAMPRATE_48000: + rate = BTIF_SBC_CHNL_SAMPLE_FREQ_48; + break; + default: + TRACE(0,"error! sbc enc don't support other samplerate"); + break; + } + SOURCE_DBLOG("\n%s %d rate = %x\n",__FUNCTION__,__LINE__,rate); + return rate; + +} + +#if 1 +static void a2dp_source_send_sbc_packet(void) +{ + uint32_t frame_size = 512; + uint32_t frame_num = A2DP_TRANS_SIZE/frame_size; +// a2dp_source.lock_stream(&(tws.tws_source)); + uint16_t byte_encoded = 0; +// uint16_t pcm_frame_size = 512/2; + unsigned short enc_len = 0; + bt_status_t status = BT_STS_FAILED; + + int lock = int_lock(); + sbcpack_t *sbcpack = get_sbcPacket(); + btif_a2dp_sbc_packet_t *sbcPacket = &(sbcpack->sbcPacket); + sbcPacket->data = (U8 *)sbcpack->buffer; + memcpy(sbcpack->buffer,a2dp_transmit_buffer,A2DP_TRANS_SIZE); + +// sbcPacket->dataLen = len; +// sbcPacket->frameSize = len/frame_num; + + btif_sbc_pcm_data_t PcmEncData; + + if(need_init_encoder) { + btif_sbc_init_encoder(&sbc_encoder); + sbc_encoder.streamInfo.numChannels = 2; + sbc_encoder.streamInfo.channelMode = BTIF_SBC_CHNL_MODE_JOINT_STEREO; + sbc_encoder.streamInfo.bitPool = A2DP_SBC_BITPOOL; + sbc_encoder.streamInfo.sampleFreq = app_a2dp_source_samplerate_2_sbcenc_type(a2dp_source.sample_rate); + sbc_encoder.streamInfo.allocMethod = BTIF_SBC_ALLOC_METHOD_SNR; + sbc_encoder.streamInfo.numBlocks = 16; + sbc_encoder.streamInfo.numSubBands = 8; + sbc_encoder.streamInfo.mSbcFlag = 0; + need_init_encoder = 0; + } + PcmEncData.data = (uint8_t *)a2dp_transmit_buffer; + PcmEncData.dataLen = A2DP_TRANS_SIZE; + PcmEncData.numChannels = 2; + PcmEncData.sampleFreq = sbc_encoder.streamInfo.sampleFreq; + + btif_sbc_encode_frames(&sbc_encoder, &PcmEncData, &byte_encoded, + (unsigned char*)sbcpack->buffer, &enc_len, A2DP_TRANS_SIZE) ; + sbcPacket->dataLen = enc_len; + sbcPacket->frameSize = enc_len/frame_num; + + int_unlock(lock); + status = btif_a2dp_stream_send_sbc_packet(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream,sbcPacket,&StreamInfo); + if(status == BT_STS_PENDING) + a2dp_source_wait_sent(osWaitForever); +} +#endif + +//#define BT_A2DP_SOURCE_LINEIN_BUFF_SIZE (512*5*2*2) +#define BT_A2DP_SOURCE_LINEIN_BUFF_SIZE (A2DP_TRANS_SIZE*2) + + +#if defined(APP_LINEIN_A2DP_SOURCE) +//////////start the audio linein stream for capure the pcm data +int app_a2dp_source_linein_on(bool on) +{ + uint8_t *buff_play = NULL; + struct AF_STREAM_CONFIG_T stream_cfg; + static bool isRun = false; + SOURCE_DBLOG("app_a2dp_source_linein_on work:%d op:%d", isRun, on); + + if (isRun==on) + return 0; + + if (on){ +#if defined(SLAVE_USE_OPUS) || defined(MASTER_USE_OPUS) || defined(ALL_USE_OPUS) + app_audio_mempool_init(app_audio_get_basebuf_ptr(APP_MEM_LINEIN_AUDIO), app_audio_get_basebuf_size(APP_MEM_LINEIN_AUDIO)); +#else + app_audio_mempool_init(); +#endif + app_sysfreq_req(APP_SYSFREQ_USER_APP_0,APP_SYSFREQ_104M); + app_audio_mempool_get_buff(&buff_play, BT_A2DP_SOURCE_LINEIN_BUFF_SIZE); + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; + stream_cfg.sample_rate = a2dp_source.sample_rate; +#if FPGA==0 + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; +#else + stream_cfg.device = AUD_STREAM_USE_EXT_CODEC; +#endif + stream_cfg.vol = 10; + //stream_cfg.io_path = AUD_INPUT_PATH_HP_MIC; + //stream_cfg.io_path =AUD_INPUT_PATH_MAINMIC; + stream_cfg.io_path =AUD_INPUT_PATH_LINEIN; + stream_cfg.handler = a2dp_source_linein_more_pcm_data; + stream_cfg.data_ptr = buff_play; + stream_cfg.data_size = BT_A2DP_SOURCE_LINEIN_BUFF_SIZE; + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + SOURCE_DBLOG("app_source_linein_on on"); + } else { + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + SOURCE_DBLOG("app_source_linein_on off"); + //clear buffer data + a2dp_source.pcm_queue.write=0; + a2dp_source.pcm_queue.len=0; + a2dp_source.pcm_queue.read=0; + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_32K); + } + + isRun=on; + return 0; +} +#endif + + +////////////////////////////creat the thread for send sbc data to a2dp sink device /////////////////// +static void send_thread(const void *arg); + + +osThreadDef(send_thread, osPriorityHigh, 1, 1024*2, "a2dp_send"); + +#if 1 +static void send_thread(const void *arg) +{ + while(1){ + a2dp_source_wait_pcm_data(); + while(a2dp_source_pcm_buffer_read((uint8_t *)a2dp_transmit_buffer,A2DP_TRANS_SIZE)==0) + { + a2dp_source_send_sbc_packet(); + } + } +} +#endif +void app_source_init(void) +{ + //register the bt global handler + a2dp_source_handler.callback = bt_a2dp_source_call_back; + btif_me_register_global_handler(&a2dp_source_handler); + btif_me_set_event_mask(&a2dp_source_handler, BTIF_BEM_LINK_DISCONNECT|BTIF_BEM_ROLE_CHANGE|BTIF_BEM_INQUIRY_RESULT| + BTIF_BEM_INQUIRY_COMPLETE|BTIF_BEM_INQUIRY_CANCELED|BTIF_BEM_LINK_CONNECT_CNF|BTIF_BEM_LINK_CONNECT_IND); +} +///////init the a2dp source feature +void app_a2dp_source_init(void) +{ + a2dp_source_lock_t *lock; + //get heap from app_audio_buffer + app_audio_mempool_get_buff(&a2dp_linein_buff, A2DP_LINEIN_SIZE); + InitCQueue(&a2dp_source.pcm_queue, A2DP_LINEIN_SIZE, ( CQItemType *)a2dp_linein_buff); + if(a2dp_source_mutex_id == NULL) + { + a2dp_source_mutex_id = osMutexCreate((osMutex(a2dp_source_mutex))); + } + + lock = &(a2dp_source.data_lock); + memset(lock,0,sizeof(a2dp_source_lock_t)); + lock->_osSemaphoreDef.semaphore = lock->_semaphore_data; + lock->_osSemaphoreId = osSemaphoreCreate(&(lock->_osSemaphoreDef), 0); + + lock = &(a2dp_source.sbc_send_lock); + memset(lock,0,sizeof(a2dp_source_lock_t)); + lock->_osSemaphoreDef.semaphore = lock->_semaphore_data; + lock->_osSemaphoreId = osSemaphoreCreate(&(lock->_osSemaphoreDef), 0); + a2dp_source.sbc_send_id = osThreadCreate(osThread(send_thread), NULL); + a2dp_source.sample_rate = AUD_SAMPRATE_44100; +} + +#endif diff --git a/services/bt_app/app_a2dp_source.h b/services/bt_app/app_a2dp_source.h new file mode 100644 index 0000000..b5a80f2 --- /dev/null +++ b/services/bt_app/app_a2dp_source.h @@ -0,0 +1,124 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +#ifndef __APP_A2DP_SOURCE_H__ +#define __APP_A2DP_SOURCE_H__ + +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "bt_drv.h" +#include "app_audio.h" +#include "bt_drv_interface.h" +#include "app_bt_stream.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "a2dp_api.h" +#include "avrcp_api.h" + +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "tgt_hardware.h" +#include "app_utils.h" +#include "app_bt_func.h" +#include "a2dp_api.h" + +//#define APP_SOURCE_DEBUG +#ifdef APP_SOURCE_DEBUG +#define SOURCE_DBLOG TRACE +#else +#define SOURCE_DBLOG(...) +#endif + + +extern struct BT_DEVICE_T app_bt_device; + + +//#define A2DP_LINEIN_SIZE (48*2*1024) +//#define A2DP_TRANS_SIZE 2048 + +#define A2DP_LINEIN_SIZE (10*2*1024) +#if 0 +//2dh3 5frame 40 encode delay +#define A2DP_TRANS_SIZE (128*5*2*2) +#define A2DP_SBC_BITPOOL (51) +#elif +//2dh3 5frame 40 encode delay +#define A2DP_TRANS_SIZE (128*5*2*2) +#define A2DP_SBC_BITPOOL (27) +#else +//2dh3 5frame 40 encode delay +#define A2DP_TRANS_SIZE (128*4*2*2) +#define A2DP_SBC_BITPOOL (36) +#endif + +typedef struct _SCB { + U8 cb_type; /* Control Block Type */ + U8 mask; /* Semaphore token mask */ + U16 tokens; /* Semaphore tokens */ + struct OS_TCB *p_lnk; /* Chain of tasks waiting for tokens */ +} *PSCB; + +typedef struct { + osSemaphoreId _osSemaphoreId; + osSemaphoreDef_t _osSemaphoreDef; +#ifdef CMSIS_OS_RTX + uint32_t _semaphore_data[2]; +#endif + +} a2dp_source_lock_t; + + +typedef struct{ + CQueue pcm_queue; + osThreadId sbc_send_id; + a2dp_source_lock_t data_lock; + a2dp_source_lock_t sbc_send_lock; + enum AUD_SAMPRATE_T sample_rate; + uint8_t sbcen_samplerate; + + +}A2DP_SOURCE_STRUCT; + + +typedef struct sbcpack{ + btif_a2dp_sbc_packet_t sbcPacket; + char buffer[A2DP_TRANS_SIZE]; + int free; +}sbcpack_t; + +typedef struct sbcbank{ + sbcpack_t sbcpacks[1]; + int free; +}sbcbank_t; + +extern A2DP_SOURCE_STRUCT a2dp_source; +extern void a2dp_source_notify_send(void); +extern uint32_t a2dp_source_linein_more_pcm_data(uint8_t * pcm_buf, uint32_t len); +#endif +#endif diff --git a/services/bt_app/app_bqb.cpp b/services/bt_app/app_bqb.cpp new file mode 100644 index 0000000..d8a6334 --- /dev/null +++ b/services/bt_app/app_bqb.cpp @@ -0,0 +1,152 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#if defined(__BQB_PROFILE_TEST__) && !defined(ENHANCED_STACK) +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_cmu.h" +#include "analog.h" +#include "bt_drv.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" + + +#include "cqueue.h" +#include "apps.h" +#include "tgt_hardware.h" + +#include "stdio.h" +#include "cmsis_os.h" +#include "string.h" + +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_bootmode.h" + +#include "audioflinger.h" +#include "apps.h" +#include "app_thread.h" +#include "app_key.h" +#include "app_audio.h" +#include "app_overlay.h" +#include "app_utils.h" +#include "app_status_ind.h" +#ifdef __FACTORY_MODE_SUPPORT__ +#include "app_factory.h" +#include "app_factory_bt.h" +#endif +#include "bt_drv_interface.h" +#include "besbt.h" +#include "nvrecord.h" +#include "nvrecord_dev.h" +#include "nvrecord_env.h" + + +#include "me_api.h" +#include "a2dp_api.h" +#include "avdtp_api.h" +#include "avctp_api.h" +#include "avrcp_api.h" +#include "btapp.h" +#include "app_bt.h" + +#ifdef MEDIA_PLAYER_SUPPORT +#include "resources.h" +#include "app_media_player.h" +#endif +#include "app_bt_media_manager.h" +#include "hal_sleep.h" + + +extern struct BT_DEVICE_T app_bt_device; +void A2dp_pts_Set_Sink_Delay(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!A2dp_pts_Set_Sink_Delay\n"); + btif_a2dp_set_sink_delay(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream,10); +} + +void A2dp_pts_Create_Avdtp_Signal_Channel(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!A2dp_pts_Create_Avdtp_Signal_Channel\n"); + bt_bdaddr_t bdAddr; + + //PTS addr:13 71 da 7d 1a 0 + bdAddr.address[0] = 0x13; + bdAddr.address[1] = 0x71; + bdAddr.address[2] = 0xda; + bdAddr.address[3] = 0x7d; + bdAddr.address[4] = 0x1a; + bdAddr.address[5] = 0x00; + btif_a2dp_open_stream(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream, &bdAddr); +} + +void Hfp_pts_create_service_level_channel(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_create_service_level_channel\n"); + bt_bdaddr_t bdAddr; + + //PTS addr:13 71 da 7d 1a 0 + bdAddr.address[0] = 0x13; + bdAddr.address[1] = 0x71; + bdAddr.address[2] = 0xda; + bdAddr.address[3] = 0x7d; + bdAddr.address[4] = 0x1a; + bdAddr.address[5] = 0x00; + btif_hf_create_service_link(app_bt_device.hf_channel[BT_DEVICE_ID_1],&bdAddr); +} + +#if 0 +typedef struct { + AvrcpAdvancedPdu pdu; + uint8_t para_buf[10]; +}APP_A2DP_AVRCPADVANCEDPDU; +extern osPoolId app_a2dp_avrcpadvancedpdu_mempool; +#define app_a2dp_avrcpadvancedpdu_mempool_calloc(buf) do{ \ + APP_A2DP_AVRCPADVANCEDPDU * avrcpadvancedpdu; \ + avrcpadvancedpdu = (APP_A2DP_AVRCPADVANCEDPDU *)osPoolCAlloc(app_a2dp_avrcpadvancedpdu_mempool); \ + buf = &(avrcpadvancedpdu->pdu); \ + buf->parms = avrcpadvancedpdu->para_buf; \ + }while(0); + + +#endif + +void Avrcp_pts_volume_change_notify(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Avrcp_pts_volume_change_notify\n"); + if (app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1] == NULL) + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1]); + btif_avrcp_ct_register_notification(app_bt_device.avrcp_channel[BT_DEVICE_ID_1],app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1], BTIF_AVRCP_EID_VOLUME_CHANGED,0); +} + +//extern int a2dp_volume_get(void); +#if 0 +void Avrcp_pts_set_absolute_volume(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"app_avrcp_set_absolute_volume\n"); + if (app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1] == NULL) + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1]); + + int vol = app_bt_stream_volume_get_ptr()->a2dp_vol; + vol = 8*vol-1; + if (vol > (0x7f-1)) + vol = 0x7f; + + btif_avrcp_ct_set_absolute_volume(app_bt_device.avrcp_channel[BT_DEVICE_ID_1],(avrcp_advanced_pdu_t*)app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1],vol); +} +#endif +#endif diff --git a/services/bt_app/app_bqb_new_profile.cpp b/services/bt_app/app_bqb_new_profile.cpp new file mode 100644 index 0000000..75942bd --- /dev/null +++ b/services/bt_app/app_bqb_new_profile.cpp @@ -0,0 +1,277 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#if defined(__BQB_PROFILE_TEST__) && defined(ENHANCED_STACK) +#include "hal_trace.h" +#include "app_key.h" +#include "conmgr_api.h" +#include "bt_if.h" + +static bt_bdaddr_t pts_bt_addr = {{ +#if 1 + 0x14, 0x71, 0xda, 0x7d, 0x1a, 0x00 +#else + 0x13, 0x71, 0xda, 0x7d, 0x1a, 0x00 +#endif +}}; + +void A2dp_pts_Create_Avdtp_Signal_Channel(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!A2dp_pts_Create_Avdtp_Signal_Channel\n"); + btif_pts_av_create_channel(&pts_bt_addr); +} + +void A2dp_pts_set_sink_delay(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!A2dp_pts_set_sink_delay\n"); + btif_pts_av_set_sink_delay(); +} + +void Avctp_pts_avrcp_connect(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Avctp_pts_avrcp_connect\n"); + btif_pts_ar_connect(&pts_bt_addr); +} + +void Avrcp_pts_volume_change_notify(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Avrcp_pts_volume_change_notify\n"); + btif_pts_ar_volume_notify(); +} + +void Avrcp_pts_set_absolute_volume(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"app_avrcp_set_absolute_volume\n"); + btif_pts_ar_set_absolute_volume(); +} + +void Hfp_pts_create_service_level_channel(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_create_service_level_channel\n"); + btif_pts_hf_create_service_link(&pts_bt_addr); +} + +void Hfp_pts_disconnect_service_link(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_disconnect_service_link\n"); + btif_pts_hf_disc_service_link(); +} + +void Hfp_pts_create_audio_link(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_create_audio_link\n"); + btif_pts_hf_create_audio_link(); +} + +void Hfp_pts_enable_voice_recognition(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_enable_voice_recognition\n"); + btif_pts_hf_vr_enable(); +} + +void Hfp_pts_disable_voice_recognition(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_disable_voice_recognition\n"); + btif_pts_hf_vr_disable(); +} + +void Hfp_pts_list_current_calls(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_list_current_calls\n"); + btif_pts_hf_list_current_calls(); +} + +void Hfp_pts_release_active_call_index2(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_release_active_call_index2\n"); + btif_pts_hf_release_active_call_2(); +} + +void Hfp_pts_hold_active_call_index2(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_hold_active_call_index2\n"); + btif_pts_hf_hold_active_call_2(); +} + +void Hfp_pts_release_active_call(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_release_active_call\n"); + btif_pts_hf_release_active_call(); +} + +void Hfp_pts_hf_indicators_1(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_hf_indicators_1\n"); + btif_pts_hf_send_ind_1(); +} + +void Hfp_pts_hf_indicators_2(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_hf_indicators_2\n"); + btif_pts_hf_send_ind_2(); +} + +void Hfp_pts_hf_indicators_3(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_hf_indicators_3\n"); + btif_pts_hf_send_ind_3(); +} + +void Hfp_pts_update_indicators_value(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!Hfp_pts_update_indicators_value\n"); + btif_pts_hf_update_ind_value(); +} + +void rfcomm_pts_register_channel(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"rfcomm_pts_register_channel\n"); + btif_pts_rfc_register_channel(); +} + +void rfcomm_pts_rfcomm_close(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"rfcomm_pts_rfcomm_close\n"); + btif_pts_rfc_close(); +} + +void rfcomm_pts_rfcomm_close_dlci0(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"rfcomm_pts_rfcomm_close_dlci0\n"); + btif_pts_rfc_close_dlci_0(); +} + +void rfcomm_pts_rfcomm_send_data(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"rfcomm_pts_rfcomm_send_data\n"); + btif_pts_rfc_send_data(); +} + +void Avdtp_pts_send_discover_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_discover_cmd\n"); + btif_pts_av_send_discover(); +} + +void Avdtp_pts_send_get_capability_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_get_capability_cmd\n"); + btif_pts_av_send_getcap(); +} + +void Avdtp_pts_send_set_configuration_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_set_configuration_cmd\n"); + btif_pts_av_send_setconf(); +} + +void Avdtp_pts_send_get_configuration_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_get_configuration_cmd\n"); + btif_pts_av_send_getconf(); +} + +void Avdtp_pts_send_reconfigure_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_reconfigure_cmd\n"); + btif_pts_av_send_reconf(); +} + +void Avdtp_pts_send_open_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_open_cmd\n"); + btif_pts_av_send_open(); +} + +void Avdtp_pts_send_close_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_close_cmd\n"); + btif_pts_av_send_close(); +} + +void Avdtp_pts_send_abort_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_abort_cmd\n"); + btif_pts_av_send_abort(); +} + +void Avdtp_pts_send_get_all_capability_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_get_all_capability_cmd\n"); + btif_pts_av_send_getallcap(); +} + +void Avdtp_pts_send_suspend_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_suspend_cmd\n"); + btif_pts_av_send_suspend(); +} + +void Avdtp_pts_send_start_cmd(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_send_start_cmd\n"); + btif_pts_av_send_start(); +} + +void Avdtp_pts_create_media_channel(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"Avdtp_pts_create_media_channel\n"); + btif_pts_av_create_media_channel(); +} + +void l2cap_pts_disconnect_channel(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!l2cap_pts_disconnect_channel\n"); + btif_pts_l2c_disc_channel(); +} + +void l2cap_pts_send_data(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"!!!l2cap_pts_send_data\n"); + btif_pts_l2c_send_data(); +} + +void pts_spp_client_init(void); +btif_cmgr_handler_t* pts_cmgr_handler; +bt_status_t btif_cmgr_create_data_link(btif_cmgr_handler_t *cmgr_handler, + bt_bdaddr_t *bd_addr); +bt_status_t btif_cmgr_register_handler(btif_cmgr_handler_t *cmgr_handler, + btif_cmgr_callback callback); +void pts_cmgr_callback(btif_cmgr_handler_t *cHandler, + cmgr_event_t Event, + bt_status_t Status); +void spp_pts_client_open(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"spp_pts_client_open\n"); + + pts_cmgr_handler = btif_cmgr_handler_create(); + btif_cmgr_register_handler(pts_cmgr_handler,pts_cmgr_callback); + pts_spp_client_init(); + btif_cmgr_create_data_link(pts_cmgr_handler,&pts_bt_addr); + +} + +extern struct gap_bdaddr BLE_BdAddr; +extern "C" void pts_ble_addr_init(void); +extern "C" void appm_start_connecting(struct gap_bdaddr* ptBdAddr); +void ble_pts_appm_start_connecting(APP_KEY_STATUS *status, void *param) +{ + TRACE(0,"ble_pts_appm_start_connecting\n"); + pts_ble_addr_init(); + appm_start_connecting(&BLE_BdAddr); +} + +#endif diff --git a/services/bt_app/app_bt.cpp b/services/bt_app/app_bt.cpp new file mode 100644 index 0000000..2223d98 --- /dev/null +++ b/services/bt_app/app_bt.cpp @@ -0,0 +1,5277 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "hal_aud.h" +#include "hal_chipid.h" +#include "hal_trace.h" +#include "apps.h" +#include "app_thread.h" +#include "app_status_ind.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "besbt.h" +#include "besbt_cfg.h" +#include "me_api.h" +#include "mei_api.h" +#include "a2dp_api.h" +#include "hci_api.h" +#include "l2cap_api.h" +#include "hfp_api.h" +#include "dip_api.h" +#include "btapp.h" +#include "app_bt.h" +#include "app_hfp.h" +#include "app_bt_func.h" +#include "bt_drv_interface.h" +#include "os_api.h" +#include "bt_drv_reg_op.h" +#include "app_a2dp.h" +#include "app_dip.h" +#include "app_ai_manager_api.h" +#include "app_bt.h" + +#if defined(IBRT) +#include "app_tws_ibrt.h" +#include "app_ibrt_ui.h" +#include "app_ibrt_if.h" +#include "app_ibrt_a2dp.h" +#endif + +#ifdef __THIRDPARTY +#include "app_thirdparty.h" +#endif + +#include "app_ble_mode_switch.h" + +#ifdef GFPS_ENABLED +#include "app_gfps.h" +#endif + +#ifdef __AI_VOICE__ +#include "ai_spp.h" +#include "ai_thread.h" +#include "ai_manager.h" +#endif + +#ifdef __INTERCONNECTION__ +#include "app_interconnection.h" +#include "app_interconnection_ble.h" +#include "spp_api.h" +#include "app_interconnection_ccmp.h" +#include "app_spp.h" +#include "app_interconnection_spp.h" +#endif + +#ifdef __INTERACTION__ +#include "app_interaction.h" +#endif + +#ifdef BISTO_ENABLED +#include "gsound_custom_bt.h" +#endif + +#if defined(__EARPHONE_STAY_BCR_SLAVE__) && defined(__BT_ONE_BRING_TWO__) +#error can not defined at the same time. +#endif + +#ifdef GFPS_ENABLED +#include "app_gfps.h" +#endif + +#ifdef TILE_DATAPATH +#include "tile_target_ble.h" +#include "rwip_config.h" +#endif + +#if (A2DP_DECODER_VER >= 2) +#include "a2dp_decoder.h" +#endif +extern "C" +{ +#include "ddbif.h" +} +extern struct BT_DEVICE_T app_bt_device; +extern "C" bool app_anc_work_status(void); +extern uint8_t avrcp_get_media_status(void); +void avrcp_set_media_status(uint8_t status); + +#ifdef GFPS_ENABLED +extern "C" void app_gfps_handling_on_mobile_link_disconnection(btif_remote_device_t* pRemDev); +#endif + +static btif_remote_device_t *connectedMobile = NULL; +static btif_remote_device_t *sppOpenMobile = NULL; + +U16 bt_accessory_feature_feature = BTIF_HF_CUSTOM_FEATURE_SUPPORT; + +#ifdef __BT_ONE_BRING_TWO__ +btif_device_record_t record2_copy; +uint8_t record2_avalible; +#endif + +enum bt_profile_reconnect_mode +{ + bt_profile_reconnect_null, + bt_profile_reconnect_openreconnecting, + bt_profile_reconnect_reconnecting, + bt_profile_reconnect_reconnect_pending, +}; + +enum bt_profile_connect_status +{ + bt_profile_connect_status_unknow, + bt_profile_connect_status_success, + bt_profile_connect_status_failure, +}; + +struct app_bt_profile_manager +{ + bool has_connected; + enum bt_profile_connect_status hfp_connect; + enum bt_profile_connect_status hsp_connect; + enum bt_profile_connect_status a2dp_connect; + bt_bdaddr_t rmt_addr; + bt_profile_reconnect_mode reconnect_mode; + bt_profile_reconnect_mode saved_reconnect_mode; + a2dp_stream_t *stream; + //HfChannel *chan; + hf_chan_handle_t chan; +#if defined (__HSP_ENABLE__) + HsChannel * hs_chan; +#endif + uint16_t reconnect_cnt; + osTimerId connect_timer; + void (* connect_timer_cb)(void const *); + + APP_BT_CONNECTING_STATE_E connectingState; +}; + +//reconnect = (INTERVAL+PAGETO)*CNT = (3000ms+5000ms)*15 = 120s +#define APP_BT_PROFILE_RECONNECT_RETRY_INTERVAL_MS (3000) +#define APP_BT_PROFILE_OPENNING_RECONNECT_RETRY_LIMIT_CNT (2) +#define APP_BT_PROFILE_RECONNECT_RETRY_LIMIT_CNT (15) +#define APP_BT_PROFILE_CONNECT_RETRY_MS (10000) + +static struct app_bt_profile_manager bt_profile_manager[BT_DEVICE_NUM]; + +static int8_t app_bt_profile_reconnect_pending_process(void); +void app_bt_connectable_mode_stop_reconnecting(void); + +btif_accessible_mode_t g_bt_access_mode = BTIF_BAM_NOT_ACCESSIBLE; + +#define APP_BT_PROFILE_BOTH_SCAN_MS (11000) +#define APP_BT_PROFILE_PAGE_SCAN_MS (4000) + +osTimerId app_bt_accessmode_timer = NULL; +btif_accessible_mode_t app_bt_accessmode_timer_argument = BTIF_BAM_NOT_ACCESSIBLE; +static int app_bt_accessmode_timehandler(void const *param); +osTimerDef (APP_BT_ACCESSMODE_TIMER, (void (*)(void const *))app_bt_accessmode_timehandler); // define timers + +#define A2DP_CONN_CLOSED 10 + +#ifdef __IAG_BLE_INCLUDE__ +#define APP_FAST_BLE_ADV_TIMEOUT_IN_MS 30000 +osTimerId app_fast_ble_adv_timeout_timer = NULL; +static int app_fast_ble_adv_timeout_timehandler(void const *param); +osTimerDef(APP_FAST_BLE_ADV_TIMEOUT_TIMER, ( void (*)(void const *) )app_fast_ble_adv_timeout_timehandler); // define timers + +/*--------------------------------------------------------------------------- + * app_start_fast_connectable_ble_adv + *--------------------------------------------------------------------------- + * + *Synopsis: + * start fast connectable BLE adv + * + * Parameters: + * advInterval - adv interval + * + * Return: + * void + */ +static void app_start_fast_connectable_ble_adv(uint16_t advInterval); +#endif + + +#if defined(__INTERCONNECTION__) +btif_accessible_mode_t app_bt_get_current_access_mode(void) +{ + return g_bt_access_mode; +} + +bool app_bt_is_connected() +{ + uint8_t i=0; + bool connceted_value=false; + for(i=0; i= (int8_t)nameLen) + { + // Check if data can be added to the adv Data + adv_data[adv_data_len++] = nameLen + 1; + // Fill Device Name Flag + adv_data[adv_data_len++] = '\x09'; + // Copy device name + memcpy(&adv_data[adv_data_len], ble_name_in_nv, nameLen); + // Update adv Data Length + adv_data_len += nameLen; + btif_me_ble_set_adv_data(adv_data_len, adv_data); + + btif_adv_para_struct_t adv_para; + adv_para.interval_min = 32; + adv_para.interval_max = 32; + adv_para.adv_type = 0; + adv_para.own_addr_type = 0; + adv_para.peer_addr_type = 0; + adv_para.adv_chanmap = 0x07; + adv_para.adv_filter_policy = 0; + btif_me_ble_set_adv_parameters(&adv_para); + btif_me_set_ble_bd_address(ble_addr); + btif_me_ble_set_adv_en(1); + } + else + { + nameLen = avail_space - 2; + // Check if data can be added to the adv Data + adv_data[adv_data_len++] = nameLen + 1; + // Fill Device Name Flag + adv_data[adv_data_len++] = '\x08'; + // Copy device name + memcpy(&adv_data[adv_data_len], ble_name_in_nv, nameLen); + // Update adv Data Length + adv_data_len += nameLen; + btif_me_ble_set_adv_data(adv_data_len, adv_data); + + btif_adv_para_struct_t adv_para; + adv_para.interval_min = 256; + adv_para.interval_max = 256; + adv_para.adv_type = 0; + adv_para.own_addr_type = 0; + adv_para.peer_addr_type = 0; + adv_para.adv_chanmap = 0x07; + adv_para.adv_filter_policy = 0; + btif_me_ble_set_adv_parameters(&adv_para); + btif_me_set_ble_bd_address(ble_addr); + + avail_space = 31; + nameLen = strlen(ble_name_in_nv); + if(avail_space - 2 < (int8_t)nameLen) + nameLen = avail_space - 2; + + scan_rsp_data[scan_rsp_data_len++] = nameLen + 1; + // Fill Device Name Flag + scan_rsp_data[scan_rsp_data_len++] = '\x09'; + // Copy device name + memcpy(&scan_rsp_data[scan_rsp_data_len], ble_name_in_nv, nameLen); + // Update Scan response Data Length + scan_rsp_data_len += nameLen; + btif_me_ble_set_scan_rsp_data(scan_rsp_data_len, scan_rsp_data); + btif_me_ble_set_adv_en(1); + } +} + +void app_bt_write_controller_memory_for_test(uint32_t addr,uint32_t val,uint8_t type) +{ + TRACE(2,"%s addr=0x%x val=0x%x type=%d",__func__, addr,val,type); + app_bt_ME_Write_Controller_Memory_Fortest(addr,val,type); +} + +void app_bt_read_controller_memory_for_test(uint32_t addr,uint32_t len,uint8_t type) +{ + TRACE(2,"%s addr=0x%x len=%x type=%d",__func__, addr,len,type); + app_bt_ME_Read_Controller_Memory_Fortest(addr,len,type); +} +#endif + +extern "C" uint8_t app_bt_get_act_cons(void) +{ + int activeCons; + + osapi_lock_stack(); + activeCons = btif_me_get_activeCons(); + osapi_unlock_stack(); + TRACE(2,"%s %d",__func__,activeCons); + return activeCons; +} +enum +{ + INITIATE_PAIRING_NONE = 0, + INITIATE_PAIRING_RUN = 1, +}; +static uint8_t initiate_pairing = INITIATE_PAIRING_NONE; +void app_bt_connectable_state_set(uint8_t set) +{ + initiate_pairing = set; +} +bool is_app_bt_pairing_running(void) +{ + return (initiate_pairing == INITIATE_PAIRING_RUN)?(true):(false); +} +#define APP_DISABLE_PAGE_SCAN_AFTER_CONN +#ifdef APP_DISABLE_PAGE_SCAN_AFTER_CONN +osTimerId disable_page_scan_check_timer = NULL; +static void disable_page_scan_check_timer_handler(void const *param); +osTimerDef (DISABLE_PAGE_SCAN_CHECK_TIMER, (void (*)(void const *))disable_page_scan_check_timer_handler); // define timers +static void disable_page_scan_check_timer_handler(void const *param) +{ +#ifdef __BT_ONE_BRING_TWO__ + if((btif_me_get_activeCons() > 1) && (initiate_pairing == INITIATE_PAIRING_NONE)) + { +#else + if((btif_me_get_activeCons() > 0) && (initiate_pairing == INITIATE_PAIRING_NONE)) + { +#endif + app_bt_accessmode_set_req(BTIF_BAM_NOT_ACCESSIBLE); + } +} + +static void disable_page_scan_check_timer_start(void) +{ + if(disable_page_scan_check_timer == NULL) + { + disable_page_scan_check_timer = osTimerCreate(osTimer(DISABLE_PAGE_SCAN_CHECK_TIMER), osTimerOnce, NULL); + } + osTimerStart(disable_page_scan_check_timer, 4000); +} + +#endif +void PairingTransferToConnectable(void) +{ + int activeCons; + osapi_lock_stack(); + activeCons = btif_me_get_activeCons(); + osapi_unlock_stack(); + TRACE(1,"%s",__func__); + + app_bt_connectable_state_set(INITIATE_PAIRING_NONE); + if(activeCons == 0) + { + TRACE(0,"!!!PairingTransferToConnectable BAM_CONNECTABLE_ONLY\n"); + app_bt_accessmode_set_req(BTIF_BAM_CONNECTABLE_ONLY); + } +} +int app_bt_get_audio_up_id(void) +{ + uint8_t i; + btif_remote_device_t *remDev = NULL; + btif_cmgr_handler_t *cmgrHandler; + for (i=0; imaxInterval); + + TRACE(2,"checker: %s remDev:%p remote_dev_address:", str,remDev); + DUMP8("0x%02x ", btif_me_get_remote_device_bdaddr(remDev)->address, BTIF_BD_ADDR_SIZE); + } + else + { + TRACE(3,"checker: %s remDev:%p cmgrHandler:%p", str, remDev, cmgrHandler); + } + + if (a2dp_stream) + { + TRACE(1,"a2dp State:%d", btif_a2dp_get_stream_state(a2dp_stream)); + if (btif_a2dp_get_stream_state(a2dp_stream) > BTIF_AVDTP_STRM_STATE_IDLE) + { + TRACE(1,"a2dp cmgrHandler remDev:%p", btif_a2dp_get_stream_devic_cmgrHandler_remdev(a2dp_stream)); + } + } + else + { + TRACE(1,"%s a2dp stream NULL", str); + } + if (hf_channel) + { + TRACE(4,"hf_channel Connected:%d IsAudioUp:%d/%d remDev:%p", btif_hf_is_acl_connected(hf_channel), + app_bt_device.hf_audio_state[0], + btif_hf_check_AudioConnect_status(hf_channel), + btif_hf_cmgr_get_remote_device(hf_channel)); + } + else + { + TRACE(1,"%s hf_channel NULL", str); + } + return 0; +} +#endif + +int app_bt_state_checker(void) +{ + btif_remote_device_t *remDev = NULL; + btif_cmgr_handler_t *cmgrHandler; + + osapi_lock_stack(); + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (app_tws_ibrt_mobile_link_connected()) + { + TRACE(1,"checker: IBRT_MASTER activeCons:%d", btif_me_get_activeCons()); + remDev = p_ibrt_ctrl->p_tws_remote_dev; + if (remDev != NULL) + { + cmgrHandler = btif_cmgr_get_acl_handler(remDev); + if (cmgrHandler) + { + app_bt_ibrt_profile_checker("tws peers", remDev, cmgrHandler, NULL, NULL); + } + else + { + TRACE(0,"checker: cmgrhandler not handle p_tws_remote_dev!"); + } + } + else + { + TRACE(0,"checker: tws_remote_dev is NULL!"); + } + + remDev = p_ibrt_ctrl->p_mobile_remote_dev; + if (remDev != NULL) + { + cmgrHandler = btif_cmgr_get_acl_handler(remDev); + if (cmgrHandler) + { + app_bt_ibrt_profile_checker("master mobile", remDev, cmgrHandler, app_bt_device.a2dp_connected_stream[0], + app_bt_device.hf_conn_flag[0] ? app_bt_device.hf_channel[0] : NULL); + } + else + { + TRACE(0,"checker: cmgrhandler not handle mobile_remote_dev"); + } + } + else + { + TRACE(0,"checker: mobile_remote_dev is NULL!"); + } + } + else if (app_tws_ibrt_slave_ibrt_link_connected()) + { + TRACE(1,"checker: IBRT_SLAVE activeCons:%d", btif_me_get_activeCons()); + remDev = p_ibrt_ctrl->p_tws_remote_dev; + if (remDev != NULL) + { + cmgrHandler = btif_cmgr_get_acl_handler(remDev); + if (cmgrHandler) + { + app_bt_ibrt_profile_checker("tws peers", remDev, cmgrHandler, NULL, NULL); + } + else + { + TRACE(0,"checker: cmgrhandler not handle p_tws_remote_dev!"); + } + } + else + { + TRACE(0,"checker: tws_remote_dev is NULL!"); + } + if (app_ibrt_ui_is_profile_exchanged()) + { + app_bt_ibrt_profile_checker("ibrt mobile", NULL, NULL, app_bt_device.a2dp_connected_stream[0], + app_bt_device.hf_conn_flag[0] ? app_bt_device.hf_channel[0] : NULL); + } + } + else + { + TRACE(1,"checker: IBRT_UNKNOW activeCons:%d", btif_me_get_activeCons()); + } + app_ibrt_if_ctx_checker(); +#if defined(ENHANCED_STACK) + btif_me_cobuf_state_dump(); + btif_me_hcibuff_state_dump(); +#endif + //BT controller state checker + ASSERT(bt_drv_reg_op_check_bt_controller_state(), "BT controller dead!"); +#else + for (uint8_t i=0; imaxInterval, + app_bt_device.hf_audio_state[i]); + DUMP8("0x%02x ", btif_me_get_remote_device_bdaddr(remDev)->address, BTIF_BD_ADDR_SIZE); + TRACE(4,"remDev:%p a2dp State:%d hf_channel Connected:%d remDev:%p ", + remDev, + app_bt_device.a2dp_connected_stream[i] ? btif_a2dp_get_stream_state(app_bt_device.a2dp_connected_stream[i]):BTIF_A2DP_STREAM_STATE_CLOSED, + app_bt_device.hf_conn_flag[i], + app_bt_device.hf_conn_flag[i] ? (btif_remote_device_t *)btif_hf_cmgr_get_remote_device(app_bt_device.hf_channel[i]):NULL); + } + } + else + { + TRACE(1,"checker: id:%d remDev is NULL!", i); + } + +#ifdef __AI_VOICE__ + TRACE(1,"ai_setup_complete %d", app_ai_is_setup_complete()); +#endif +#ifdef IS_MULTI_AI_ENABLED + TRACE(1,"current_spec %d", app_ai_manager_get_current_spec()); +#endif +#if defined (__HSP_ENABLE__) + TRACE(2,"hs_channel Connected:%d remDev:%p ", + app_bt_device.hs_conn_flag[i], + app_bt_device.hs_channel[i].cmgrHandler.remDev); +#endif + TRACE(2,"%s btif_me_get_activeCons = %d",__func__,btif_me_get_activeCons()); +#ifdef HFP_DEBUG + hfp_call_state_checker(); +#endif + } +#if defined(ENHANCED_STACK) + btif_me_cobuf_state_dump(); + btif_me_hcibuff_state_dump(); +#endif +#endif + osapi_unlock_stack(); + + return 0; +} + +static uint8_t app_bt_get_devId_from_RemDev( btif_remote_device_t* remDev) +{ + uint8_t connectedDevId = 0; + for (uint8_t devId = 0; devId < BT_DEVICE_NUM; devId++) + { + if ( btif_me_enumerate_remote_devices(devId) == remDev) + { + TRACE(2, "%s %d", __func__, devId); + connectedDevId = devId; + break; + } + } + + return connectedDevId; +} +void app_bt_accessible_manager_process(const btif_event_t *Event) +{ +#if defined(IBRT) + //IBRT device's access mode will be controlled by UI + return; +#else + btif_event_type_t etype = btif_me_get_callback_event_type(Event); +#ifdef __BT_ONE_BRING_TWO__ + static uint8_t opening_reconnect_cnf_cnt = 0; + //uint8_t disconnectedDevId = app_bt_get_devId_from_RemDev(btif_me_get_callback_event_rem_dev( Event)); + + if (app_bt_profile_connect_openreconnecting(NULL)) + { + if (etype == BTIF_BTEVENT_LINK_CONNECT_CNF) + { + opening_reconnect_cnf_cnt++; + } + if (record2_avalible) + { + if (opening_reconnect_cnf_cnt<2) + { + return; + } + } + } +#endif + switch (etype) + { + case BTIF_BTEVENT_LINK_CONNECT_CNF: + case BTIF_BTEVENT_LINK_CONNECT_IND: + TRACE(1,"BTEVENT_LINK_CONNECT_IND/CNF activeCons:%d",btif_me_get_activeCons()); +#if defined(__BTIF_EARPHONE__) && !defined(FPGA) + app_stop_10_second_timer(APP_PAIR_TIMER_ID); +#endif +#ifdef __BT_ONE_BRING_TWO__ + if(btif_me_get_activeCons() == 0) + { +#ifdef __EARPHONE_STAY_BOTH_SCAN__ + app_bt_accessmode_set_req(BTIF_BT_DEFAULT_ACCESS_MODE_PAIR); +#else + app_bt_accessmode_set_req(BTIF_BAM_CONNECTABLE_ONLY); +#endif + } + else if(btif_me_get_activeCons() == 1) + { + app_bt_accessmode_set_req(BTIF_BAM_CONNECTABLE_ONLY); + } + else if(btif_me_get_activeCons() >= 2) + { + app_bt_accessmode_set_req(BTIF_BAM_NOT_ACCESSIBLE); + } +#else + if(btif_me_get_activeCons() == 0) + { +#ifdef __EARPHONE_STAY_BOTH_SCAN__ + app_bt_accessmode_set_req(BTIF_BT_DEFAULT_ACCESS_MODE_PAIR); +#else + app_bt_accessmode_set_req(BTIF_BAM_CONNECTABLE_ONLY); +#endif + } + else if(btif_me_get_activeCons() >= 1) + { + app_bt_accessmode_set_req(BTIF_BAM_NOT_ACCESSIBLE); + } +#endif + break; + case BTIF_BTEVENT_LINK_DISCONNECT: + TRACE(1,"DISCONNECT activeCons:%d",btif_me_get_activeCons()); +#ifdef __EARPHONE_STAY_BOTH_SCAN__ +#ifdef __BT_ONE_BRING_TWO__ + if(btif_me_get_activeCons() == 0) + { + app_bt_accessmode_set_req(BTIF_BT_DEFAULT_ACCESS_MODE_PAIR); + } + else if(btif_me_get_activeCons() == 1) + { + app_bt_accessmode_set_req(BTIF_BAM_CONNECTABLE_ONLY); + } + else if(btif_me_get_activeCons() >= 2) + { + app_bt_accessmode_set_req(BTIF_BAM_NOT_ACCESSIBLE); + } +#else + app_bt_accessmode_set_req(BTIF_BT_DEFAULT_ACCESS_MODE_PAIR); +#endif +#else + app_bt_accessmode_set_req(BTIF_BAM_CONNECTABLE_ONLY); +#endif + break; +#ifdef __BT_ONE_BRING_TWO__ + case BTIF_BTEVENT_SCO_CONNECT_IND: + case BTIF_BTEVENT_SCO_CONNECT_CNF: + if(btif_me_get_activeCons() == 1) + { + app_bt_accessmode_set_req(BTIF_BAM_NOT_ACCESSIBLE); + } + break; + case BTIF_BTEVENT_SCO_DISCONNECT: + if(btif_me_get_activeCons() == 1) + { + app_bt_accessmode_set_req(BTIF_BAM_CONNECTABLE_ONLY); + } + break; +#endif + default: + break; + } +#endif +} + +#define APP_BT_SWITCHROLE_LIMIT (2) +//#define __SET_OUR_AS_MASTER__ + +void app_bt_role_manager_process(const btif_event_t *Event) +{ +#if defined(IBRT) || defined(APP_LINEIN_A2DP_SOURCE) || defined(APP_I2S_A2DP_SOURCE) || defined(__APP_A2DP_SOURCE__) + return; +#else + static btif_remote_device_t *opRemDev = NULL; + static uint8_t switchrole_cnt = 0; + btif_remote_device_t *remDev = NULL; + btif_event_type_t etype = btif_me_get_callback_event_type(Event); + //on phone connecting + switch (etype) + { + case BTIF_BTEVENT_LINK_CONNECT_IND: + if( btif_me_get_callback_event_err_code(Event) == BTIF_BEC_NO_ERROR) + { + if (btif_me_get_activeCons() == 1) + { + switch ( btif_me_get_callback_event_rem_dev_role (Event)) + { +#if defined(__SET_OUR_AS_MASTER__) + case BTIF_BCR_SLAVE: + case BTIF_BCR_PSLAVE: +#else + case BTIF_BCR_MASTER: + case BTIF_BCR_PMASTER: +#endif + TRACE(1,"CONNECT_IND try to role %p\n", btif_me_get_callback_event_rem_dev( Event)); + //curr connectrot try to role + opRemDev =btif_me_get_callback_event_rem_dev( Event); + switchrole_cnt = 0; + app_bt_Me_SetLinkPolicy(btif_me_get_callback_event_rem_dev( Event), BTIF_BLP_MASTER_SLAVE_SWITCH|BTIF_BLP_SNIFF_MODE); + break; +#if defined(__SET_OUR_AS_MASTER__) + case BTIF_BCR_MASTER: + case BTIF_BCR_PMASTER: +#else + case BTIF_BCR_SLAVE: + case BTIF_BCR_PSLAVE: +#endif + case BTIF_BCR_ANY: + case BTIF_BCR_UNKNOWN: + default: + TRACE(1,"CONNECT_IND disable role %p\n",btif_me_get_callback_event_rem_dev( Event)); + //disable roleswitch when 1 connect + app_bt_Me_SetLinkPolicy ( btif_me_get_callback_event_rem_dev( Event), BTIF_BLP_SNIFF_MODE); + break; + } + //set next connector to master + app_bt_ME_SetConnectionRole(BTIF_BCR_MASTER); + } + else if (btif_me_get_activeCons() > 1) + { + switch (btif_me_get_callback_event_rem_dev_role (Event)) + { + case BTIF_BCR_MASTER: + case BTIF_BCR_PMASTER: + TRACE(1,"CONNECT_IND disable role %p\n",btif_me_get_callback_event_rem_dev( Event)); + //disable roleswitch + app_bt_Me_SetLinkPolicy(btif_me_get_callback_event_rem_dev( Event), BTIF_BLP_SNIFF_MODE); + break; + case BTIF_BCR_SLAVE: + case BTIF_BCR_PSLAVE: + case BTIF_BCR_ANY: + case BTIF_BCR_UNKNOWN: + default: + //disconnect slave + TRACE(1,"CONNECT_IND disconnect slave %p\n",btif_me_get_callback_event_rem_dev( Event)); + app_bt_MeDisconnectLink(btif_me_get_callback_event_rem_dev( Event)); + break; + } + //set next connector to master + app_bt_ME_SetConnectionRole(BTIF_BCR_MASTER); + } + } + break; + case BTIF_BTEVENT_LINK_CONNECT_CNF: + if (btif_me_get_activeCons() == 1) + { + switch (btif_me_get_callback_event_rem_dev_role (Event)) + { +#if defined(__SET_OUR_AS_MASTER__) + case BTIF_BCR_SLAVE: + case BTIF_BCR_PSLAVE: +#else + case BTIF_BCR_MASTER: + case BTIF_BCR_PMASTER: +#endif + TRACE(1,"CONNECT_CNF try to role %p\n",btif_me_get_callback_event_rem_dev( Event)); + //curr connectrot try to role + opRemDev =btif_me_get_callback_event_rem_dev( Event); + switchrole_cnt = 0; + app_bt_Me_SetLinkPolicy(btif_me_get_callback_event_rem_dev( Event), BTIF_BLP_MASTER_SLAVE_SWITCH|BTIF_BLP_SNIFF_MODE); + app_bt_ME_SwitchRole(btif_me_get_callback_event_rem_dev( Event)); + break; +#if defined(__SET_OUR_AS_MASTER__) + case BTIF_BCR_MASTER: + case BTIF_BCR_PMASTER: +#else + case BTIF_BCR_SLAVE: + case BTIF_BCR_PSLAVE: +#endif + case BTIF_BCR_ANY: + case BTIF_BCR_UNKNOWN: + default: + TRACE(1,"CONNECT_CNF disable role %p\n",btif_me_get_callback_event_rem_dev( Event)); + //disable roleswitch + app_bt_Me_SetLinkPolicy(btif_me_get_callback_event_rem_dev( Event), BTIF_BLP_SNIFF_MODE); + break; + } + //set next connector to master + app_bt_ME_SetConnectionRole(BTIF_BCR_MASTER); + } + else if (btif_me_get_activeCons() > 1) + { + switch (btif_me_get_callback_event_rem_dev_role (Event)) + { + case BTIF_BCR_MASTER: + case BTIF_BCR_PMASTER : + TRACE(1,"CONNECT_CNF disable role %p\n",btif_me_get_callback_event_rem_dev( Event)); + //disable roleswitch + app_bt_Me_SetLinkPolicy(btif_me_get_callback_event_rem_dev( Event), BTIF_BLP_SNIFF_MODE); + break; + case BTIF_BCR_SLAVE: + case BTIF_BCR_ANY: + case BTIF_BCR_UNKNOWN: + default: + //disconnect slave + TRACE(1,"CONNECT_CNF disconnect slave %p\n",btif_me_get_callback_event_rem_dev( Event)); + app_bt_MeDisconnectLink(btif_me_get_callback_event_rem_dev( Event)); + break; + } + //set next connector to master + app_bt_ME_SetConnectionRole(BTIF_BCR_MASTER); + } + break; + case BTIF_BTEVENT_LINK_DISCONNECT: + if (opRemDev ==btif_me_get_callback_event_rem_dev( Event)) + { + opRemDev = NULL; + switchrole_cnt = 0; + } + if (btif_me_get_activeCons() == 0) + { + for (uint8_t i=0; i 1) + { + uint8_t slave_cnt = 0; + for (uint8_t i=0; i1) + { + TRACE(1,"ROLE_CHANGE disconnect slave %p\n",btif_me_get_callback_event_rem_dev( Event)); + app_bt_MeDisconnectLink(btif_me_get_callback_event_rem_dev( Event)); + } + } + break; + default: + break; + } +#endif +} + +void app_bt_role_manager_process_dual_slave(const btif_event_t *Event) +{ +#if defined(IBRT) || defined(APP_LINEIN_A2DP_SOURCE) || defined(APP_I2S_A2DP_SOURCE) || defined(__APP_A2DP_SOURCE__) + return; +#else + static btif_remote_device_t *opRemDev = NULL; + static uint8_t switchrole_cnt = 0; + //btif_remote_device_t *remDev = NULL; + //on phone connecting + switch ( btif_me_get_callback_event_type(Event)) + { + case BTIF_BTEVENT_LINK_CONNECT_IND: + case BTIF_BTEVENT_LINK_CONNECT_CNF: + if(btif_me_get_callback_event_err_code(Event) == BTIF_BEC_NO_ERROR) + { + switch (btif_me_get_callback_event_rem_dev_role (Event)) + { +#if defined(__SET_OUR_AS_MASTER__) + case BTIF_BCR_SLAVE: + case BTIF_BCR_PSLAVE: +#else + case BTIF_BCR_MASTER: + case BTIF_BCR_PMASTER: +#endif + TRACE(1,"CONNECT_IND/CNF try to role %p\n",btif_me_get_callback_event_rem_dev( Event)); + opRemDev =btif_me_get_callback_event_rem_dev( Event); + switchrole_cnt = 0; + app_bt_Me_SetLinkPolicy(btif_me_get_callback_event_rem_dev( Event), BTIF_BLP_MASTER_SLAVE_SWITCH|BTIF_BLP_SNIFF_MODE); + app_bt_ME_SwitchRole(btif_me_get_callback_event_rem_dev( Event)); + break; +#if defined(__SET_OUR_AS_MASTER__) + case BTIF_BCR_MASTER: + case BTIF_BCR_PMASTER: +#else + case BTIF_BCR_SLAVE: + case BTIF_BCR_PSLAVE: +#endif + case BTIF_BCR_ANY: + case BTIF_BCR_UNKNOWN: + default: + TRACE(1,"CONNECT_IND disable role %p\n",btif_me_get_callback_event_rem_dev( Event)); + app_bt_Me_SetLinkPolicy(btif_me_get_callback_event_rem_dev( Event), BTIF_BLP_SNIFF_MODE); + break; + } + app_bt_ME_SetConnectionRole(BTIF_BCR_SLAVE); + } + break; + case BTIF_BTEVENT_LINK_DISCONNECT: + if (opRemDev ==btif_me_get_callback_event_rem_dev( Event)) + { + opRemDev = NULL; + switchrole_cnt = 0; + } + if ( btif_me_get_activeCons() == 0) + { + for (uint8_t i=0; i 1) + { + btif_remote_device_t* tmpRemDev = NULL; + btif_cmgr_handler_t *currbtif_cmgr_handler_t = NULL; + btif_cmgr_handler_t *otherbtif_cmgr_handler_t = NULL; + currbtif_cmgr_handler_t = btif_cmgr_get_conn_ind_handler(remDev); + for (uint8_t i=0; imaxInterval == btif_cmgr_get_cmgrhandler_sniff_info(currbtif_cmgr_handler_t)->maxInterval) + { + sniffInfo.maxInterval = btif_cmgr_get_cmgrhandler_sniff_info(otherbtif_cmgr_handler_t)->maxInterval -20; + sniffInfo.minInterval = btif_cmgr_get_cmgrhandler_sniff_info(otherbtif_cmgr_handler_t)->minInterval - 20; + sniffInfo.attempt = BTIF_CMGR_SNIFF_ATTEMPT; + sniffInfo.timeout = BTIF_CMGR_SNIFF_TIMEOUT; + app_bt_CMGR_SetSniffInfoToAllHandlerByRemDev(&sniffInfo, remDev); + } + } + break; + } + else + { + TRACE(3,"%s:enumerate i:%d remDev is NULL, param remDev:%p, this may cause error!", __func__, i, remDev); + } + } + } +#endif +} + +void app_bt_sniff_manager_process(const btif_event_t *Event) +{ + static btif_remote_device_t *opRemDev = NULL; + btif_remote_device_t *remDev = NULL; + btif_cmgr_handler_t *currbtif_cmgr_handler_t = NULL; + btif_cmgr_handler_t *otherbtif_cmgr_handler_t = NULL; + + btif_sniff_info_t sniffInfo; + + if (!besbt_cfg.sniff) + return; + + switch (btif_me_get_callback_event_type(Event)) + { + case BTIF_BTEVENT_LINK_CONNECT_IND: + break; + case BTIF_BTEVENT_LINK_CONNECT_CNF: + break; + case BTIF_BTEVENT_LINK_DISCONNECT: + if (opRemDev ==btif_me_get_callback_event_rem_dev( Event)) + { + opRemDev = NULL; + } + sniffInfo.maxInterval = BTIF_CMGR_SNIFF_MAX_INTERVAL; + sniffInfo.minInterval = BTIF_CMGR_SNIFF_MIN_INTERVAL; + sniffInfo.attempt = BTIF_CMGR_SNIFF_ATTEMPT; + sniffInfo.timeout = BTIF_CMGR_SNIFF_TIMEOUT; + app_bt_CMGR_SetSniffInfoToAllHandlerByRemDev(&sniffInfo,btif_me_get_callback_event_rem_dev( Event)); + break; + case BTIF_BTEVENT_MODE_CHANGE: + + /* + if(Event->p.modeChange.curMode == BLM_SNIFF_MODE){ + currbtif_cmgr_handler_t = btif_cmgr_get_acl_handler(btif_me_get_callback_event_rem_dev( Event)); + if (Event->p.modeChange.interval > CMGR_SNIFF_MAX_INTERVAL){ + if (!opRemDev){ + opRemDev = currbtif_cmgr_handler_t->remDev; + } + currbtif_cmgr_handler_t->sniffInfo.maxInterval = CMGR_SNIFF_MAX_INTERVAL; + currbtif_cmgr_handler_t->sniffInfo.minInterval = CMGR_SNIFF_MIN_INTERVAL; + currbtif_cmgr_handler_t->sniffInfo.attempt = CMGR_SNIFF_ATTEMPT; + currbtif_cmgr_handler_t->sniffInfo.timeout = CMGR_SNIFF_TIMEOUT; + app_bt_CMGR_SetSniffInfoToAllHandlerByRemDev(&currbtif_cmgr_handler_t->sniffInfo,btif_me_get_callback_event_rem_dev( Event)); + app_bt_ME_StopSniff(currbtif_cmgr_handler_t->remDev); + }else{ + if (currbtif_cmgr_handler_t){ + currbtif_cmgr_handler_t->sniffInfo.maxInterval = Event->p.modeChange.interval; + currbtif_cmgr_handler_t->sniffInfo.minInterval = Event->p.modeChange.interval; + currbtif_cmgr_handler_t->sniffInfo.attempt = CMGR_SNIFF_ATTEMPT; + currbtif_cmgr_handler_t->sniffInfo.timeout = CMGR_SNIFF_TIMEOUT; + app_bt_CMGR_SetSniffInfoToAllHandlerByRemDev(&currbtif_cmgr_handler_t->sniffInfo,btif_me_get_callback_event_rem_dev( Event)); + } + if (btif_me_get_activeCons() > 1){ + for (uint8_t i=0; isniffInfo.maxInterval == currbtif_cmgr_handler_t->sniffInfo.maxInterval){ + if (btif_me_get_current_mode(remDev) == BLM_ACTIVE_MODE){ + otherbtif_cmgr_handler_t->sniffInfo.maxInterval -= 20; + otherbtif_cmgr_handler_t->sniffInfo.minInterval -= 20; + otherbtif_cmgr_handler_t->sniffInfo.attempt = CMGR_SNIFF_ATTEMPT; + otherbtif_cmgr_handler_t->sniffInfo.timeout = CMGR_SNIFF_TIMEOUT; + app_bt_CMGR_SetSniffInfoToAllHandlerByRemDev(&otherbtif_cmgr_handler_t->sniffInfo, remDev); + TRACE(1,"reconfig sniff other RemDev:%x\n", remDev); + }else if (btif_me_get_current_mode(remDev) == BLM_SNIFF_MODE){ + need_reconfig = true; + } + } + } + break; + } + } + } + if (need_reconfig){ + opRemDev = remDev; + if (currbtif_cmgr_handler_t){ + currbtif_cmgr_handler_t->sniffInfo.maxInterval -= 20; + currbtif_cmgr_handler_t->sniffInfo.minInterval -= 20; + currbtif_cmgr_handler_t->sniffInfo.attempt = CMGR_SNIFF_ATTEMPT; + currbtif_cmgr_handler_t->sniffInfo.timeout = CMGR_SNIFF_TIMEOUT; + app_bt_CMGR_SetSniffInfoToAllHandlerByRemDev(&currbtif_cmgr_handler_t->sniffInfo, currbtif_cmgr_handler_t->remDev); + } + app_bt_ME_StopSniff(currbtif_cmgr_handler_t->remDev); + TRACE(1,"reconfig sniff setup op opRemDev:%x\n", opRemDev); + } + } + } + if (Event->p.modeChange.curMode == BLM_ACTIVE_MODE){ + if (opRemDev ==btif_me_get_callback_event_rem_dev( Event)){ + TRACE(1,"reconfig sniff op opRemDev:%x\n", opRemDev); + opRemDev = NULL; + currbtif_cmgr_handler_t = btif_cmgr_get_acl_handler(btif_me_get_callback_event_rem_dev( Event)); + if (currbtif_cmgr_handler_t){ + app_bt_CMGR_SetSniffTimer(currbtif_cmgr_handler_t, NULL, CMGR_SNIFF_TIMER); + } + } + } + */ + break; + case BTIF_BTEVENT_ACL_DATA_ACTIVE: + btif_cmgr_handler_t *cmgrHandler; + /* Start the sniff timer */ + cmgrHandler = btif_cmgr_get_acl_handler(btif_me_get_callback_event_rem_dev( Event)); + if (cmgrHandler) + app_bt_CMGR_SetSniffTimer(cmgrHandler, NULL, BTIF_CMGR_SNIFF_TIMER); + break; + case BTIF_BTEVENT_SCO_CONNECT_IND: + case BTIF_BTEVENT_SCO_CONNECT_CNF: + TRACE(1,"BTEVENT_SCO_CONNECT_IND/CNF cur_remDev = %p",btif_me_get_callback_event_rem_dev( Event)); + currbtif_cmgr_handler_t = btif_cmgr_get_conn_ind_handler(btif_me_get_callback_event_rem_dev( Event)); + app_bt_Me_SetLinkPolicy( btif_me_get_callback_event_sco_connect_rem_dev(Event), BTIF_BLP_DISABLE_ALL); + if (btif_me_get_activeCons() > 1) + { + for (uint8_t i=0; imobile_pair_canceled) +#endif + { + memset(&record, 0, sizeof(record)); + record.bdAddr = *bd_ddr; + ddbif_add_record(&record); + } + nv_record_flash_flush(); + } + } + break; + } + // trace filter + switch (btif_me_get_callback_event_type(Event)) + { + case BTIF_BTEVENT_HCI_COMMAND_SENT: + case BTIF_BTEVENT_ACL_DATA_NOT_ACTIVE: + case BTIF_BTEVENT_ACL_DATA_ACTIVE: + break; + default: + TRACE(1,"[BTEVENT] evt = %d", btif_me_get_callback_event_type(Event)); + break; + } + + switch (btif_me_get_callback_event_type(Event)) + { + case BTIF_BTEVENT_LINK_CONNECT_IND: + hfp_reconnecting_timer_stop_callback(Event); + case BTIF_BTEVENT_LINK_CONNECT_CNF: +#ifdef __BT_ONE_BRING_TWO__ + if(bt_drv_reg_op_get_reconnecting_flag()) + { + bt_drv_reg_op_clear_reconnecting_flag(); + if(a2dp_is_music_ongoing()) + a2dp_update_music_link(); + } +#endif + + if (BTIF_BEC_NO_ERROR == btif_me_get_callback_event_err_code(Event)) + { + connectedMobile = btif_me_get_callback_event_rem_dev( Event); + uint8_t connectedDevId = app_bt_get_devId_from_RemDev(connectedMobile); + app_bt_set_connecting_profiles_state(connectedDevId); + TRACE(1,"MEC(pendCons) is %d", btif_me_get_pendCons()); + + app_bt_stay_active_rem_dev(btif_me_get_callback_event_rem_dev( Event)); +#ifdef __BT_ONE_BRING_TWO__ + btif_remote_device_t *remote_dev = btif_me_get_callback_event_rem_dev(Event); + uint16_t conn_handle = btif_me_get_remote_device_hci_handle(remote_dev); + btif_me_qos_set_up(conn_handle); +#endif + +#if (defined(__AI_VOICE__) || defined(BISTO_ENABLED)) + app_ai_if_mobile_connect_handle(btif_me_get_callback_event_rem_dev_bd_addr(Event)); +#endif + } + + TRACE(4,"[BTEVENT] CONNECT_IND/CNF evt:%d errCode:0x%0x newRole:%d activeCons:%d",btif_me_get_callback_event_type(Event), + btif_me_get_callback_event_err_code(Event),btif_me_get_callback_event_rem_dev_role (Event), btif_me_get_activeCons()); + DUMP8("%02x ", btif_me_get_callback_event_rem_dev_bd_addr(Event), BTIF_BD_ADDR_SIZE); + +#if defined(__BTIF_EARPHONE__) && defined(__BTIF_AUTOPOWEROFF__) && !defined(FPGA) + if (btif_me_get_activeCons() == 0) + { + app_start_10_second_timer(APP_POWEROFF_TIMER_ID); + } + else + { + app_stop_10_second_timer(APP_POWEROFF_TIMER_ID); + } +#endif +#if defined(__BT_ONE_BRING_TWO__)||defined(IBRT) + if (btif_me_get_activeCons() > 2) + { + TRACE(1,"CONNECT_IND/CNF activeCons:%d so disconnect it", btif_me_get_activeCons()); + app_bt_MeDisconnectLink(btif_me_get_callback_event_rem_dev( Event)); + } +#else + if (btif_me_get_activeCons() > 1) + { + TRACE(1,"CONNECT_IND/CNF activeCons:%d so disconnect it", btif_me_get_activeCons()); + app_bt_MeDisconnectLink(btif_me_get_callback_event_rem_dev( Event)); + } +#endif + break; + case BTIF_BTEVENT_LINK_DISCONNECT: + { + connectedMobile = btif_me_get_callback_event_rem_dev( Event); + uint8_t disconnectedDevId = app_bt_get_devId_from_RemDev(connectedMobile); + connectedMobile = NULL; + app_bt_clear_connecting_profiles_state(disconnectedDevId); + + btif_remote_device_t *remote_dev = btif_me_get_callback_event_disconnect_rem_dev(Event); + if(remote_dev) + { + uint16_t conhdl = btif_me_get_remote_device_hci_handle(remote_dev); + bt_drv_reg_op_acl_tx_silence_clear(conhdl); + bt_drv_hwspi_select(conhdl-0x80, 0); + } + + TRACE(5,"[BTEVENT] DISCONNECT evt = %d encryptState:%d reason:0x%02x/0x%02x activeCons:%d", + btif_me_get_callback_event_type(Event), + btif_me_get_remote_sevice_encrypt_state(btif_me_get_callback_event_rem_dev( Event)), + btif_me_get_remote_device_disc_reason_saved(btif_me_get_callback_event_rem_dev( Event)), + btif_me_get_remote_device_disc_reason(btif_me_get_callback_event_rem_dev( Event)), + btif_me_get_activeCons()); + DUMP8("%02x ", btif_me_get_callback_event_rem_dev_bd_addr(Event), BTIF_BD_ADDR_SIZE); +#ifdef CHIP_BEST2000 + bt_drv_patch_force_disconnect_ack(); +#endif + //disconnect from reconnect connection, and the HF don't connect successful once + //(whitch will release the saved_reconnect_mode ). so we are reconnect fail with remote link key loss. + // goto pairing. + //reason 07 maybe from the controller's error . + //05 auth error + //16 io cap reject. + +#if defined(__BTIF_EARPHONE__) && defined(__BTIF_AUTOPOWEROFF__) && !defined(FPGA) + if (btif_me_get_activeCons() == 0) + { + app_start_10_second_timer(APP_POWEROFF_TIMER_ID); + } +#endif + +#if defined(BISTO_ENABLED) + gsound_custom_bt_link_disconnected_handler(btif_me_get_callback_event_rem_dev_bd_addr(Event)->address); +#endif +#if defined(__AI_VOICE__) + app_ai_mobile_disconnect_handle(btif_me_get_callback_event_rem_dev_bd_addr(Event)); +#endif +#ifdef __IAG_BLE_INCLUDE__ + // start BLE adv + app_ble_force_switch_adv(BLE_SWITCH_USER_BT_CONNECT, true); +#endif + +#ifdef BTIF_DIP_DEVICE + btif_dip_clear(remote_dev); +#endif + + app_bt_active_mode_reset(disconnectedDevId); + +#ifdef GFPS_ENABLED + app_gfps_handling_on_mobile_link_disconnection( + btif_me_get_callback_event_rem_dev(Event)); +#endif +#if !defined(IBRT) && defined( BT_XTAL_SYNC_NO_RESET) + bt_term_xtal_sync_default(); +#endif + + break; + } + case BTIF_BTEVENT_ROLE_CHANGE: + TRACE(3,"[BTEVENT] ROLE_CHANGE eType:0x%x errCode:0x%x newRole:%d activeCons:%d", btif_me_get_callback_event_type(Event), + btif_me_get_callback_event_err_code(Event), btif_me_get_callback_event_role_change_new_role(Event), btif_me_get_activeCons()); + break; + case BTIF_BTEVENT_MODE_CHANGE: + TRACE(4,"[BTEVENT] MODE_CHANGE evt:%d errCode:0x%0x curMode=0x%0x, interval=%d ",btif_me_get_callback_event_type(Event), + btif_me_get_callback_event_err_code(Event), btif_me_get_callback_event_mode_change_curMode(Event), + btif_me_get_callback_event_mode_change_interval(Event)); + DUMP8("%02x ", btif_me_get_callback_event_rem_dev_bd_addr(Event), BTIF_BD_ADDR_SIZE); + break; + case BTIF_BTEVENT_ACCESSIBLE_CHANGE: + TRACE(3,"[BTEVENT] ACCESSIBLE_CHANGE evt:%d errCode:0x%0x aMode=0x%0x", btif_me_get_callback_event_type(Event), + btif_me_get_callback_event_err_code(Event), + btif_me_get_callback_event_a_mode(Event)); +#if !defined(IBRT) + if (app_is_access_mode_set_pending()) + { + app_set_pending_access_mode(); + } + else + { + if (BTIF_BEC_NO_ERROR != btif_me_get_callback_event_err_code(Event)) + { + app_retry_setting_access_mode(); + } + } +#endif + break; + case BTIF_BTEVENT_LINK_POLICY_CHANGED: + { + BT_SET_LINKPOLICY_REQ_T* pReq = app_bt_pop_pending_set_linkpolicy(); + if (NULL != pReq) + { + app_bt_Me_SetLinkPolicy(pReq->remDev, pReq->policy); + } + break; + } + case BTIF_BTEVENT_DEFAULT_LINK_POLICY_CHANGED: + { + TRACE(0,"[BTEVENT] DEFAULT_LINK_POLICY_CHANGED-->BT_STACK_INITIALIZED"); + app_notify_stack_ready(STACK_READY_BT); + break; + } + case BTIF_BTEVENT_NAME_RESULT: + { + uint8_t* ptrName; + uint8_t nameLen; + nameLen = btif_me_get_callback_event_remote_dev_name(Event, &ptrName); + TRACE(1,"[BTEVENT] NAME_RESULT name len %d", nameLen); + if (nameLen > 0) + { + TRACE(1,"remote dev name: %s", ptrName); + } + //return; + } + default: + break; + } + +#ifdef MULTIPOINT_DUAL_SLAVE + app_bt_role_manager_process_dual_slave(Event); +#else + app_bt_role_manager_process(Event); +#endif + app_bt_accessible_manager_process(Event); +#if !defined(IBRT) + app_bt_sniff_manager_process(Event); +#endif + app_bt_global_handle_hook(Event); +#if defined(IBRT) + app_tws_ibrt_global_callback(Event); +#endif +} + +#include "app_bt_media_manager.h" +osTimerId bt_sco_recov_timer = NULL; +static void bt_sco_recov_timer_handler(void const *param); +osTimerDef (BT_SCO_RECOV_TIMER, (void (*)(void const *))bt_sco_recov_timer_handler); // define timers +void hfp_reconnect_sco(uint8_t flag); +static void bt_sco_recov_timer_handler(void const *param) +{ + TRACE(1,"%s",__func__); + hfp_reconnect_sco(0); +} +static void bt_sco_recov_timer_start() +{ + osTimerStop(bt_sco_recov_timer); + osTimerStart(bt_sco_recov_timer, 2500); +} + + +enum +{ + SCO_DISCONNECT_RECONN_START, + SCO_DISCONNECT_RECONN_RUN, + SCO_DISCONNECT_RECONN_NONE, +}; + +static uint8_t sco_reconnect_status = SCO_DISCONNECT_RECONN_NONE; + +void hfp_reconnect_sco(uint8_t set) +{ + TRACE(3,"%s cur_chl_id=%d reconnect_status =%d",__func__,app_bt_device.curr_hf_channel_id, + sco_reconnect_status); + if(set == 1) + { + sco_reconnect_status = SCO_DISCONNECT_RECONN_START; + } + if(sco_reconnect_status == SCO_DISCONNECT_RECONN_START) + { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_VOICE, app_bt_device.curr_hf_channel_id,MAX_RECORD_NUM); + app_bt_HF_DisconnectAudioLink(app_bt_device.hf_channel[app_bt_device.curr_hf_channel_id]); + sco_reconnect_status = SCO_DISCONNECT_RECONN_RUN; + bt_sco_recov_timer_start(); + } + else if(sco_reconnect_status == SCO_DISCONNECT_RECONN_RUN) + { + app_bt_HF_CreateAudioLink(app_bt_device.hf_channel[app_bt_device.curr_hf_channel_id]); + sco_reconnect_status = SCO_DISCONNECT_RECONN_NONE; + } +} + + +void app_bt_global_handle_init(void) +{ + btif_event_mask_t mask = BTIF_BEM_NO_EVENTS; + btif_me_init_handler(&app_bt_handler); + app_bt_handler.callback = app_bt_global_handle; + btif_me_register_global_handler(&app_bt_handler); +#if defined(IBRT) + btif_me_register_accept_handler(&app_bt_handler); +#endif +#ifdef IBRT_SEARCH_UI + app_bt_global_handle_hook_set(APP_BT_GOLBAL_HANDLE_HOOK_USER_0,app_bt_manager_ibrt_role_process); +#endif + + mask |= BTIF_BEM_ROLE_CHANGE | BTIF_BEM_SCO_CONNECT_CNF | BTIF_BEM_SCO_DISCONNECT | BTIF_BEM_SCO_CONNECT_IND; + mask |= BTIF_BEM_AUTHENTICATED; + mask |= BTIF_BEM_LINK_CONNECT_IND; + mask |= BTIF_BEM_LINK_DISCONNECT; + mask |= BTIF_BEM_LINK_CONNECT_CNF; + mask |= BTIF_BEM_ACCESSIBLE_CHANGE; + mask |= BTIF_BEM_ENCRYPTION_CHANGE; + mask |= BTIF_BEM_SIMPLE_PAIRING_COMPLETE; +#if (defined(__BT_ONE_BRING_TWO__)||defined(IBRT)) + mask |= BTIF_BEM_MODE_CHANGE; +#endif + mask |= BTIF_BEM_LINK_POLICY_CHANGED; + + app_bt_ME_SetConnectionRole(BTIF_BCR_ANY); + for (uint8_t i=0; ia2dp_stream, FALSE); +#if defined(A2DP_LHDC_ON) + app_bt_A2DP_SetMasterRole(app_bt_device.a2dp_lhdc_stream[i]->a2dp_stream, FALSE); +#endif +#if defined(A2DP_AAC_ON) + app_bt_A2DP_SetMasterRole(app_bt_device.a2dp_aac_stream[i]->a2dp_stream, FALSE); +#endif +#if defined(A2DP_SCALABLE_ON) + app_bt_A2DP_SetMasterRole(app_bt_device.a2dp_scalable_stream[i]->a2dp_stream, FALSE); +#endif +#if defined(A2DP_LDAC_ON) + app_bt_A2DP_SetMasterRole(app_bt_device.a2dp_ldac_stream[i]->a2dp_stream, FALSE); +#endif + + app_bt_HF_SetMasterRole(app_bt_device.hf_channel[i], FALSE); +#if defined (__HSP_ENABLE__) + HS_SetMasterRole(&app_bt_device.hs_channel[i], FALSE); +#endif + } + btif_me_set_event_mask(&app_bt_handler, mask); + app_bt_sniff_manager_init(); + app_bt_accessmode_timer = osTimerCreate (osTimer(APP_BT_ACCESSMODE_TIMER), osTimerOnce, &app_bt_accessmode_timer_argument); + bt_sco_recov_timer = osTimerCreate (osTimer(BT_SCO_RECOV_TIMER), osTimerOnce, NULL); +} + +void app_bt_send_request(uint32_t message_id, uint32_t param0, uint32_t param1, uint32_t ptr) +{ + APP_MESSAGE_BLOCK msg; + + msg.mod_id = APP_MODUAL_BT; + msg.msg_body.message_id = message_id; + msg.msg_body.message_Param0 = param0; + msg.msg_body.message_Param1 = param1; + msg.msg_body.message_ptr = ptr; + app_mailbox_put(&msg); +} + +extern void app_start_10_second_timer(uint8_t timer_id); + +static int app_bt_handle_process(APP_MESSAGE_BODY *msg_body) +{ + btif_accessible_mode_t old_access_mode; + + switch (msg_body->message_id) + { + case APP_BT_REQ_ACCESS_MODE_SET: + old_access_mode = g_bt_access_mode; + app_bt_accessmode_set(msg_body->message_Param0); + if (msg_body->message_Param0 == BTIF_BAM_GENERAL_ACCESSIBLE && + old_access_mode != BTIF_BAM_GENERAL_ACCESSIBLE) + { +#ifndef FPGA + //app_status_indication_set(APP_STATUS_INDICATION_BOTHSCAN); +#ifdef MEDIA_PLAYER_SUPPORT + app_voice_report(APP_STATUS_INDICATION_BOTHSCAN, 0); +#endif + app_start_10_second_timer(APP_PAIR_TIMER_ID); +#endif + } + else + { +#ifndef FPGA + //app_status_indication_set(APP_STATUS_INDICATION_PAGESCAN); +#endif + } + break; + default: + break; + } + + return 0; +} + +void *app_bt_profile_active_store_ptr_get(uint8_t *bdAddr) +{ + static btdevice_profile device_profile = {true, false, true,0}; + btdevice_profile *ptr; + +#ifndef FPGA + nvrec_btdevicerecord *record = NULL; + if (!nv_record_btdevicerecord_find((bt_bdaddr_t *)bdAddr,&record)) + { + uint32_t lock = nv_record_pre_write_operation(); + ptr = &(record->device_plf); + DUMP8("0x%02x ", bdAddr, BTIF_BD_ADDR_SIZE); + TRACE(5,"%s hfp_act:%d hsp_act:%d a2dp_act:0x%x codec_type=%x", __func__, ptr->hfp_act, ptr->hsp_act, ptr->a2dp_act,ptr->a2dp_codectype); + /* always need connect a2dp and hfp */ + ptr->hfp_act = true; + ptr->a2dp_act = true; + nv_record_post_write_operation(lock); + } + else +#endif + { + ptr = &device_profile; + TRACE(1,"%s default", __func__); + } + return (void *)ptr; +} + +static void app_bt_profile_reconnect_timehandler(void const *param); +extern void startonce_delay_event_Timer_(int ms); +osTimerDef (BT_PROFILE_CONNECT_TIMER0, app_bt_profile_reconnect_timehandler); // define timers +#ifdef __BT_ONE_BRING_TWO__ +osTimerDef (BT_PROFILE_CONNECT_TIMER1, app_bt_profile_reconnect_timehandler); +#endif + +#ifdef __AUTO_CONNECT_OTHER_PROFILE__ +static void app_bt_profile_connect_hf_retry_handler(void) +{ + struct app_bt_profile_manager *bt_profile_manager_p = (struct app_bt_profile_manager *)param; + if (MEC(pendCons) > 0) + { + TRACE(1,"Former link is not down yet, reset the timer %s.", __FUNCTION__); + osTimerStart(bt_profile_manager_p->connect_timer, APP_BT_PROFILE_RECONNECT_RETRY_INTERVAL_MS); + } + else + { + app_bt_precheck_before_starting_connecting(bt_profile_manager_p->has_connected); + if (bt_profile_manager_p->hfp_connect != bt_profile_connect_status_success) + { + app_bt_HF_CreateServiceLink(bt_profile_manager_p->chan, &bt_profile_manager_p->rmt_addr); + } + } +} + +static void app_bt_profile_connect_hf_retry_timehandler(void const *param) +{ + app_bt_start_custom_function_in_bt_thread(0, 0, + (uint32_t)app_bt_profile_connect_hf_retry_handler); +} + +#if defined (__HSP_ENABLE__) +static void app_bt_profile_connect_hs_retry_timehandler(void const *param) +{ + struct app_bt_profile_manager *bt_profile_manager_p = (struct app_bt_profile_manager *)param; + if (MEC(pendCons) > 0) + { + if (bt_profile_manager_p->reconnect_cnt < APP_BT_PROFILE_OPENNING_RECONNECT_RETRY_LIMIT_CNT) + { + bt_profile_manager_p->reconnect_cnt++; + } + TRACE(1,"Former link is not down yet, reset the timer %s.", __FUNCTION__); + osTimerStart(bt_profile_manager_p->connect_timer, + BTIF_BT_DEFAULT_PAGE_TIMEOUT_IN_MS+APP_BT_PROFILE_RECONNECT_RETRY_INTERVAL_MS); + } + else + { + if (bt_profile_manager_p->hsp_connect != bt_profile_connect_status_success) + { + app_bt_HS_CreateServiceLink(bt_profile_manager_p->hs_chan, &bt_profile_manager_p->rmt_addr); + } + } +} +#endif + +static bool app_bt_profile_manager_connect_a2dp_filter_connected_a2dp_stream(BT_BD_ADDR bd_addr) +{ + uint8_t i =0; + BtRemoteDevice *StrmRemDev; + A2dpStream * connected_stream; + + for(i =0; ibdAddr.addr,bd_addr.addr,BD_ADDR_SIZE) == 0) + { + return true; + } + } + } + return false; +} + +static void app_bt_profile_connect_a2dp_retry_handler(void) +{ + struct app_bt_profile_manager *bt_profile_manager_p = (struct app_bt_profile_manager *)param; + TRACE(1,"%s reconnect_cnt = %d",__func__,bt_profile_manager_p->reconnect_cnt); + + if (MEC(pendCons) > 0) + { + if (bt_profile_manager_p->reconnect_cnt < APP_BT_PROFILE_OPENNING_RECONNECT_RETRY_LIMIT_CNT) + { + bt_profile_manager_p->reconnect_cnt++; + } + TRACE(1,"Former link is not down yet, reset the timer %s.", __FUNCTION__); + osTimerStart(bt_profile_manager_p->connect_timer, + BTIF_BT_DEFAULT_PAGE_TIMEOUT_IN_MS+APP_BT_PROFILE_RECONNECT_RETRY_INTERVAL_MS); + } + else + { + if(app_bt_profile_manager_connect_a2dp_filter_connected_a2dp_stream(bt_profile_manager_p->rmt_addr) == true) + { + TRACE(0,"has been connected , no need to init connect again"); + return ; + } + app_bt_precheck_before_starting_connecting(bt_profile_manager_p->has_connected); + if (bt_profile_manager_p->a2dp_connect != bt_profile_connect_status_success) + { + app_bt_A2DP_OpenStream(bt_profile_manager_p->stream, &bt_profile_manager_p->rmt_addr); + } + } +} + +static void app_bt_profile_connect_a2dp_retry_timehandler(void const *param) +{ + app_bt_start_custom_function_in_bt_thread(0, 0, + (uint32_t)app_bt_profile_connect_a2dp_retry_handler); +} +#endif + +void app_bt_reset_reconnect_timer(bt_bdaddr_t *pBdAddr) +{ + uint8_t devId = 0; + for (uint8_t i = 0; i < BT_DEVICE_NUM; i++) + { + if (pBdAddr == &(bt_profile_manager[i].rmt_addr)) + { + devId = i; + break; + } + } + + TRACE(1,"Resart the reconnecting timer of dev %d", devId); + osTimerStart(bt_profile_manager[devId].connect_timer, + BTIF_BT_DEFAULT_PAGE_TIMEOUT_IN_MS+APP_BT_PROFILE_RECONNECT_RETRY_INTERVAL_MS); +} + +static void app_bt_profile_reconnect_handler(void const *param) +{ +#if !defined(IBRT) + struct app_bt_profile_manager *bt_profile_manager_p = (struct app_bt_profile_manager *)param; + TRACE(1,"%s reconnect_cnt = %d",__FUNCTION__,bt_profile_manager_p->reconnect_cnt); + + if ( btif_me_get_pendCons() > 0) + { + if (bt_profile_manager_p->reconnect_cnt < APP_BT_PROFILE_OPENNING_RECONNECT_RETRY_LIMIT_CNT) + { + bt_profile_manager_p->reconnect_cnt++; + } + TRACE(1,"Former link is not down yet, reset the timer %s.", __FUNCTION__); + osTimerStart(bt_profile_manager_p->connect_timer, + BTIF_BT_DEFAULT_PAGE_TIMEOUT_IN_MS+APP_BT_PROFILE_RECONNECT_RETRY_INTERVAL_MS); + } + else + { + btdevice_profile *btdevice_plf_p = (btdevice_profile *)app_bt_profile_active_store_ptr_get(bt_profile_manager_p->rmt_addr.address); +#ifdef __BT_ONE_BRING_TWO__ + if(a2dp_is_music_ongoing()&&(bt_profile_manager_p->has_connected == false)) + { + bt_drv_reg_op_set_reconnecting_flag(); + a2dp_update_music_link(); + } +#endif + + if (bt_profile_manager_p->connect_timer_cb) + { + bt_profile_manager_p->connect_timer_cb(param); + bt_profile_manager_p->connect_timer_cb = NULL; + } + else + { + if ((btdevice_plf_p->hfp_act) + &&(bt_profile_manager_p->hfp_connect != bt_profile_connect_status_success)) + { + TRACE(0,"try connect hf"); + app_bt_precheck_before_starting_connecting(bt_profile_manager_p->has_connected); + app_bt_HF_CreateServiceLink(bt_profile_manager_p->chan, (bt_bdaddr_t *)&bt_profile_manager_p->rmt_addr); + } +#if defined (__HSP_ENABLE__) + else if(btdevice_plf_p->hsp_act) + &&(bt_profile_manager_p->hsp_connect != bt_profile_connect_status_success)) + { + TRACE(0,"try connect hs"); + app_bt_precheck_before_starting_connecting(bt_profile_manager_p->has_connected); + app_bt_HS_CreateServiceLink(bt_profile_manager_p->hs_chan, &bt_profile_manager_p->rmt_addr); + } +#endif + else if((btdevice_plf_p->a2dp_act) + &&(bt_profile_manager_p->a2dp_connect != bt_profile_connect_status_success)) + { + TRACE(0,"try connect a2dp"); + app_bt_precheck_before_starting_connecting(bt_profile_manager_p->has_connected); + app_bt_A2DP_OpenStream(bt_profile_manager_p->stream, &bt_profile_manager_p->rmt_addr); + } + } + } +#else + TRACE(0,"ibrt_ui_log:app_bt_profile_reconnect_timehandler called"); +#endif +} + +static void app_bt_profile_reconnect_timehandler(void const *param) +{ + app_bt_start_custom_function_in_bt_thread((uint32_t)param, 0, + (uint32_t)app_bt_profile_reconnect_handler); +} + +bool app_bt_is_in_connecting_profiles_state(void) +{ + for (uint8_t devId = 0; devId < BT_DEVICE_NUM; devId++) + { + if (APP_BT_IN_CONNECTING_PROFILES_STATE == bt_profile_manager[devId].connectingState) + { + return true; + } + } + + return false; +} + +void app_bt_clear_connecting_profiles_state(uint8_t devId) +{ + TRACE(1,"Dev %d exists connecting profiles state", devId); + + bt_profile_manager[devId].connectingState = APP_BT_IDLE_STATE; + if (!app_bt_is_in_connecting_profiles_state()) + { +#ifdef __IAG_BLE_INCLUDE__ + app_start_fast_connectable_ble_adv(BLE_FAST_ADVERTISING_INTERVAL); +#endif + } +} + +void app_bt_set_connecting_profiles_state(uint8_t devId) +{ + TRACE(1,"Dev %d enters connecting profiles state", devId); + + bt_profile_manager[devId].connectingState = APP_BT_IN_CONNECTING_PROFILES_STATE; +} + +void app_bt_profile_connect_manager_open(void) +{ + uint8_t i=0; + for (i=0; ihfp_act)&&!(btdevice_plf_p->a2dp_act)) + { + nv_record_ddbrec_delete((bt_bdaddr_t *)&record1.bdAddr); + find_invalid_record_cnt++; + } + } + else if(ret == 2) + { + btdevice_plf_p = (btdevice_profile *)app_bt_profile_active_store_ptr_get(record1.bdAddr.address); + if (!(btdevice_plf_p->hfp_act)&&!(btdevice_plf_p->a2dp_act)) + { + nv_record_ddbrec_delete((bt_bdaddr_t *)&record1.bdAddr); + find_invalid_record_cnt++; + } + btdevice_plf_p = (btdevice_profile *)app_bt_profile_active_store_ptr_get(record2.bdAddr.address); + if (!(btdevice_plf_p->hfp_act)&&!(btdevice_plf_p->a2dp_act)) + { + nv_record_ddbrec_delete((bt_bdaddr_t *)&record2.bdAddr); + find_invalid_record_cnt++; + } + } + } + while(find_invalid_record_cnt); + + TRACE(0,"!!!app_bt_opening_reconnect:\n"); + DUMP8("%02x ", &record1.bdAddr, 6); + DUMP8("%02x ", &record2.bdAddr, 6); + + + if(ret > 0) + { + TRACE(0,"!!!start reconnect first device\n"); + + if( btif_me_get_pendCons() == 0) + { + bt_profile_manager[BT_DEVICE_ID_1].reconnect_mode = bt_profile_reconnect_openreconnecting; + bt_profile_manager[BT_DEVICE_ID_1].reconnect_cnt = 0; + memcpy(bt_profile_manager[BT_DEVICE_ID_1].rmt_addr.address, record1.bdAddr.address, BTIF_BD_ADDR_SIZE); + btdevice_plf_p = (btdevice_profile *)app_bt_profile_active_store_ptr_get(bt_profile_manager[BT_DEVICE_ID_1].rmt_addr.address); + +#if defined(A2DP_LHDC_ON) + if(btdevice_plf_p->a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_1]->a2dp_stream; + else +#endif +#if defined(A2DP_AAC_ON) + if(btdevice_plf_p->a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream; + else +#endif +#if defined(A2DP_LDAC_ON) //workaround for mate10 no a2dp issue when link back + if(btdevice_plf_p->a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + //bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream; + //btdevice_plf_p->a2dp_codectype = BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC; + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_ldac_stream[BT_DEVICE_ID_1]->a2dp_stream; + btdevice_plf_p->a2dp_codectype = BTIF_AVDTP_CODEC_TYPE_NON_A2DP; + } + else +#endif + +#if defined(A2DP_SCALABLE_ON) + if(btdevice_plf_p->a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_1]->a2dp_stream; + else +#endif + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + + btif_a2dp_reset_stream_state(bt_profile_manager[BT_DEVICE_ID_1].stream); + + bt_profile_manager[BT_DEVICE_ID_1].chan = app_bt_device.hf_channel[BT_DEVICE_ID_1]; +#if defined (__HSP_ENABLE__) + bt_profile_manager[BT_DEVICE_ID_1].hs_chan = &app_bt_device.hs_channel[BT_DEVICE_ID_1]; +#endif + if (btdevice_plf_p->hfp_act) + { + TRACE(0,"try connect hf"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[BT_DEVICE_ID_1].has_connected); + app_bt_HF_CreateServiceLink(bt_profile_manager[BT_DEVICE_ID_1].chan, (bt_bdaddr_t *)&bt_profile_manager[BT_DEVICE_ID_1].rmt_addr); + } + else if(btdevice_plf_p->a2dp_act) + { + TRACE(0,"try connect a2dp"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[BT_DEVICE_ID_1].has_connected); + app_bt_A2DP_OpenStream(bt_profile_manager[BT_DEVICE_ID_1].stream, &bt_profile_manager[BT_DEVICE_ID_1].rmt_addr); + } + +#if defined (__HSP_ENABLE__) + else if (btdevice_plf_p->hsp_act) + { + TRACE(0,"try connect hs"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[BT_DEVICE_ID_1].has_connected); + app_bt_HS_CreateServiceLink(bt_profile_manager[BT_DEVICE_ID_1].hs_chan, &bt_profile_manager[BT_DEVICE_ID_1].rmt_addr); + } +#endif + + } +#ifdef __BT_ONE_BRING_TWO__ + if(ret > 1) + { + TRACE(0,"!!!need reconnect second device\n"); + bt_profile_manager[BT_DEVICE_ID_2].reconnect_mode = bt_profile_reconnect_openreconnecting; + bt_profile_manager[BT_DEVICE_ID_2].reconnect_cnt = 0; + memcpy(bt_profile_manager[BT_DEVICE_ID_2].rmt_addr.address, record2.bdAddr.address, BTIF_BD_ADDR_SIZE); + btdevice_plf_p = (btdevice_profile *)app_bt_profile_active_store_ptr_get(bt_profile_manager[BT_DEVICE_ID_2].rmt_addr.address); + +#if defined(A2DP_LHDC_ON) + if(btdevice_plf_p->a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + bt_profile_manager[BT_DEVICE_ID_2].stream = app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_2]->a2dp_stream; + else +#endif +#if defined(A2DP_AAC_ON) + if(btdevice_plf_p->a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) + bt_profile_manager[BT_DEVICE_ID_2].stream = app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_2]->a2dp_stream; + else +#endif +#if defined(A2DP_SCALABLE_ON) + if(btdevice_plf_p->a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + bt_profile_manager[BT_DEVICE_ID_2].stream = app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_2]->a2dp_stream; + else +#endif + { + bt_profile_manager[BT_DEVICE_ID_2].stream = app_bt_device.a2dp_stream[BT_DEVICE_ID_2]->a2dp_stream; + } + + btif_a2dp_reset_stream_state(bt_profile_manager[BT_DEVICE_ID_2].stream); + + bt_profile_manager[BT_DEVICE_ID_2].chan = app_bt_device.hf_channel[BT_DEVICE_ID_2]; +#if defined (__HSP_ENABLE__) + bt_profile_manager[BT_DEVICE_ID_2].hs_chan = &app_bt_device.hs_channel[BT_DEVICE_ID_2]; +#endif + } +#endif + } + + else + { + TRACE(0,"!!!go to pairing\n"); +#ifdef __EARPHONE_STAY_BOTH_SCAN__ + app_bt_accessmode_set_req(BTIF_BT_DEFAULT_ACCESS_MODE_PAIR); +#else + app_bt_accessmode_set_req(BTIF_BAM_CONNECTABLE_ONLY); +#endif + + } + osapi_unlock_stack(); +} + + +void app_bt_resume_sniff_mode(uint8_t deviceId) +{ + if (bt_profile_connect_status_success == bt_profile_manager[deviceId].a2dp_connect|| + bt_profile_connect_status_success == bt_profile_manager[deviceId].hfp_connect|| + bt_profile_connect_status_success == bt_profile_manager[deviceId].hsp_connect) + { + app_bt_allow_sniff(deviceId); + btif_remote_device_t* currentRemDev = app_bt_get_remoteDev(deviceId); + app_bt_sniff_config(currentRemDev); + } +} +#if !defined(IBRT) +static int8_t app_bt_profile_reconnect_pending(enum BT_DEVICE_ID_T id) +{ + if(btapp_hfp_is_dev_call_active(id) == true) + { + bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_reconnect_pending; + return 0; + } + return -1; +} +#endif +static int8_t app_bt_profile_reconnect_pending_process(void) +{ + uint8_t i =BT_DEVICE_NUM; + + btif_remote_device_t *remDev = NULL; + btif_cmgr_handler_t *cmgrHandler; + + + for (i=0; ip.remDev->bdAddr.address); + + osTimerStop(bt_profile_manager[id].connect_timer); + bt_profile_manager[id].connect_timer_cb = NULL; + bool profile_reconnect_enable = false; + + if (Chan&&Info) + { + switch(Info->event) + { + case HF_EVENT_SERVICE_CONNECTED: + TRACE(1,"%s HS_EVENT_SERVICE_CONNECTED",__func__); + nv_record_btdevicerecord_set_hsp_profile_active_state(btdevice_plf_p, true); +#ifndef FPGA + nv_record_touch_cause_flush(); +#endif + bt_profile_manager[id].hsp_connect = bt_profile_connect_status_success; + bt_profile_manager[id].reconnect_cnt = 0; + bt_profile_manager[id].hs_chan = &app_bt_device.hs_channel[id]; + memcpy(bt_profile_manager[id].rmt_addr.address, Info->p.remDev->bdAddr.address, BTIF_BD_ADDR_SIZE); + if (false == bt_profile_manager[id].has_connected) + { + app_bt_resume_sniff_mode(id); + } + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_openreconnecting) + { + //do nothing + } + else if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_reconnecting) + { + if (btdevice_plf_p->a2dp_act && bt_profile_manager[id].a2dp_connect != bt_profile_connect_status_success) + { + TRACE(0,"!!!continue connect a2dp\n"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_A2DP_OpenStream(bt_profile_manager[id].stream, &bt_profile_manager[id].rmt_address); + } + } +#ifdef __AUTO_CONNECT_OTHER_PROFILE__ + else + { + if (btdevice_plf_p->a2dp_act && bt_profile_manager[id].a2dp_connect != bt_profile_connect_status_success) + { + bt_profile_manager[id].connect_timer_cb = app_bt_profile_connect_a2dp_retry_timehandler; + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + osTimerStart(bt_profile_manager[id].connect_timer, APP_BT_PROFILE_CONNECT_RETRY_MS); + } + } +#endif + break; + case HF_EVENT_SERVICE_DISCONNECTED: + TRACE(2,"%s HS_EVENT_SERVICE_DISCONNECTED discReason:%d",__func__, Info->p.remDev->discReason); + bt_profile_manager[id].hsp_connect = bt_profile_connect_status_failure; + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_openreconnecting) + { + if (++bt_profile_manager[id].reconnect_cnt < APP_BT_PROFILE_OPENNING_RECONNECT_RETRY_LIMIT_CNT) + { + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + profile_reconnect_enable = true; + bt_profile_manager[id].hfp_connect = bt_profile_connect_status_unknow; + } + } + else if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_reconnecting) + { + if (++bt_profile_manager[id].reconnect_cnt < APP_BT_PROFILE_RECONNECT_RETRY_LIMIT_CNT) + { + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + profile_reconnect_enable = true + } + else + { + app_bt_restore_reconnecting_idle_mode(id); + //bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_null; + } + TRACE(2,"%s try to reconnect cnt:%d",__func__, bt_profile_manager[id].reconnect_cnt); +#if !defined(IBRT) + } + else if(Info->p.remDev->discReason == 0x8) + { + bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_reconnecting; + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + TRACE(1,"%s try to reconnect",__func__); + if(app_bt_profile_reconnect_pending(id) != 0) + { + profile_reconnect_enable = true; + } +#endif + } + else + { + bt_profile_manager[id].hsp_connect = bt_profile_connect_status_unknow; + } + + if (profile_reconnect_enable) + { +#ifdef __IAG_BLE_INCLUDE__ + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); +#endif + osTimerStart(bt_profile_manager[id].connect_timer, APP_BT_PROFILE_RECONNECT_RETRY_INTERVAL_MS); + } + break; + default: + break; + } + } + + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_reconnecting) + { + bool reconnect_hsp_proc_final = true; + bool reconnect_a2dp_proc_final = true; + if (bt_profile_manager[id].hsp_connect == bt_profile_connect_status_failure) + { + reconnect_hsp_proc_final = false; + } + if (bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_failure) + { + reconnect_a2dp_proc_final = false; + } + if (reconnect_hsp_proc_final && reconnect_a2dp_proc_final) + { + TRACE(3,"!!!reconnect success %d/%d/%d\n", bt_profile_manager[id].hfp_connect, bt_profile_manager[id].hsp_connect, bt_profile_manager[id].a2dp_connect); + app_bt_restore_reconnecting_idle_mode(id); + // bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_null; + } + } + else if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_openreconnecting) + { + bool opening_hsp_proc_final = false; + bool opening_a2dp_proc_final = false; + + if (btdevice_plf_p->hsp_act && bt_profile_manager[id].hsp_connect == bt_profile_connect_status_unknow) + { + opening_hsp_proc_final = false; + } + else + { + opening_hsp_proc_final = true; + } + + if (btdevice_plf_p->a2dp_act && bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_unknow) + { + opening_a2dp_proc_final = false; + } + else + { + opening_a2dp_proc_final = true; + } + + if ((opening_hsp_proc_final && opening_a2dp_proc_final) || + (bt_profile_manager[id].hsp_connect == bt_profile_connect_status_failure)) + { + TRACE(3,"!!!reconnect success %d/%d/%d\n", bt_profile_manager[id].hfp_connect, bt_profile_manager[id].hsp_connect, bt_profile_manager[id].a2dp_connect); + app_bt_restore_reconnecting_idle_mode(id); + // bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_null; + } + + if (btdevice_plf_p->hsp_act && bt_profile_manager[id].hsp_connect == bt_profile_connect_status_success) + { + if (btdevice_plf_p->a2dp_act && !opening_a2dp_proc_final) + { + TRACE(0,"!!!continue connect a2dp\n"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_A2DP_OpenStream(bt_profile_manager[id].stream, &bt_profile_manager[id].rmt_addr); + } + } + + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_null) + { + for (uint8_t i=0; istart reconnect second device\n"); + if ((btdevice_plf_p->hfp_act)&&(!bt_profile_manager[i].hfp_connect)) + { + TRACE(0,"try connect hf"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[i].has_connected); + app_bt_HF_CreateServiceLink(bt_profile_manager[i].chan, &bt_profile_manager[i].rmt_addr); + } + else if ((btdevice_plf_p->hsp_act)&&(!bt_profile_manager[i].hsp_connect)) + { + TRACE(0,"try connect hs"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[i].has_connected); + app_bt_HS_CreateServiceLink(bt_profile_manager[i].hs_chan, &bt_profile_manager[i].rmt_addr); + + } + else if((btdevice_plf_p->a2dp_act)&&(!bt_profile_manager[i].a2dp_connect)) + { + TRACE(0,"try connect a2dp"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[i].has_connected); + app_bt_A2DP_OpenStream(bt_profile_manager[i].stream, &bt_profile_manager[i].rmt_addr); + } + break; + } + } + } + } + +#ifdef __IAG_BLE_INCLUDE__ + if (bt_profile_manager[id].hfp_connect == bt_profile_connect_status_success && + bt_profile_manager[id].hsp_connect == bt_profile_connect_status_success&& + bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_success) + { + app_ble_force_switch_adv(BLE_SWITCH_USER_BT_CONNECT, true); + } +#endif + + if (!bt_profile_manager[id].has_connected && + (bt_profile_manager[id].hfp_connect == bt_profile_connect_status_success || + bt_profile_manager[id].hsp_connect == bt_profile_connect_status_success|| + bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_success)) + { + + bt_profile_manager[id].has_connected = true; + TRACE(0,"BT connected!!!"); + +#ifndef IBRT + btif_me_get_remote_device_name(&(ctx->remote_dev_bdaddr), app_bt_global_handle); +#endif +#if defined(MEDIA_PLAYER_SUPPORT)&& !defined(IBRT) + app_voice_report(APP_STATUS_INDICATION_CONNECTED, id); +#endif +#ifdef __INTERCONNECTION__ + app_interconnection_start_disappear_adv(INTERCONNECTION_BLE_ADVERTISING_INTERVAL, + APP_INTERCONNECTION_DISAPPEAR_ADV_IN_MS); + + if (btif_me_get_activeCons() <= 2) + { + app_interconnection_spp_open(btif_me_enumerate_remote_devices(id)); + } +#endif +#ifdef __INTERACTION__ + // app_interaction_spp_open(); +#endif + } + + if (bt_profile_manager[id].has_connected && + (bt_profile_manager[id].hfp_connect != bt_profile_connect_status_success && + bt_profile_manager[id].hsp_connect != bt_profile_connect_status_success && + bt_profile_manager[id].a2dp_connect != bt_profile_connect_status_success)) + { + + bt_profile_manager[id].has_connected = false; + TRACE(0,"BT disconnected!!!"); + +#ifdef GFPS_ENABLED + if (app_gfps_is_last_response_pending()) + { + app_gfps_enter_connectable_mode_req_handler(app_gfps_get_last_response()); + } +#endif + +#if defined(MEDIA_PLAYER_SUPPORT)&& !defined(IBRT) + app_voice_report(APP_STATUS_INDICATION_DISCONNECTED, id); +#endif +#ifdef __INTERCONNECTION__ + app_interconnection_disconnected_callback(); +#endif + + app_set_disconnecting_all_bt_connections(false); + } + +#ifdef __BT_ONE_BRING_TWO__ + app_bt_update_connectable_mode_after_connection_management(); +#endif +} +#endif + +void hfp_reconnecting_timer_stop_callback(const btif_event_t *event) +{ + uint8_t i =0; + uint8_t id =BT_DEVICE_NUM; + bt_bdaddr_t *remote = NULL; + bt_bdaddr_t *hfp_remote = NULL; + remote = btif_me_get_callback_event_rem_dev_bd_addr(event); + if(remote != NULL){ + for(i = 0; ip.remDev->bdAddr.address); + btdevice_profile *btdevice_plf_p = (btdevice_profile *)app_bt_profile_active_store_ptr_get((uint8_t *)ctx->remote_dev_bdaddr.address); + bool profile_reconnect_enable = false; + + osTimerStop(bt_profile_manager[id].connect_timer); + bt_profile_manager[id].connect_timer_cb = NULL; + //if (Chan&&Info){ + if (Chan) + { + switch(ctx->event) + { + case BTIF_HF_EVENT_SERVICE_CONNECTED: + TRACE(1,"%s HF_EVENT_SERVICE_CONNECTED",__func__); + nv_record_btdevicerecord_set_hfp_profile_active_state(btdevice_plf_p, true); +#ifndef FPGA + nv_record_touch_cause_flush(); +#endif + bt_profile_manager[id].hfp_connect = bt_profile_connect_status_success; + bt_profile_manager[id].saved_reconnect_mode =bt_profile_reconnect_null; + bt_profile_manager[id].reconnect_cnt = 0; + bt_profile_manager[id].chan = app_bt_device.hf_channel[id]; + memcpy(bt_profile_manager[id].rmt_addr.address, ctx->remote_dev_bdaddr.address, BTIF_BD_ADDR_SIZE); + if (false == bt_profile_manager[id].has_connected) + { + app_bt_resume_sniff_mode(id); + } + +#ifdef BTIF_DIP_DEVICE + btif_dip_get_remote_info(app_bt_get_remoteDev(id)); +#endif + + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_openreconnecting) + { + //do nothing + } +#if defined(IBRT) + else if (app_bt_ibrt_reconnect_mobile_profile_flag_get()) + { + app_bt_ibrt_reconnect_mobile_profile_flag_clear(); +#else + else if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_reconnecting) + { +#endif + TRACE(2,"app_bt: a2dp_act in NV =%d,a2dp_connect=%d",btdevice_plf_p->a2dp_act,bt_profile_manager[id].a2dp_connect); + if (btdevice_plf_p->a2dp_act && bt_profile_manager[id].a2dp_connect != bt_profile_connect_status_success) + { + TRACE(0,"!!!continue connect a2dp\n"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_A2DP_OpenStream(bt_profile_manager[id].stream, &bt_profile_manager[id].rmt_addr); + } + } +#ifdef __AUTO_CONNECT_OTHER_PROFILE__ + else + { + //befor auto connect a2dp profile, check whether a2dp is supported + if (btdevice_plf_p->a2dp_act && bt_profile_manager[id].a2dp_connect != bt_profile_connect_status_success) + { + bt_profile_manager[id].connect_timer_cb = app_bt_profile_connect_a2dp_retry_timehandler; + app_bt_accessmode_set(BAM_CONNECTABLE_ONLY); + osTimerStart(bt_profile_manager[id].connect_timer, APP_BT_PROFILE_CONNECT_RETRY_MS); + } + } +#endif + break; + case BTIF_HF_EVENT_SERVICE_DISCONNECTED: + if(((ctx->disc_reason == 0)||(ctx->disc_reason == 19))&&(p_ibrt_ctrl->current_role != IBRT_SLAVE)) + { + once_event_case = 2; + startonce_delay_event_Timer_(1000); + } + //TRACE(3,"%s HF_EVENT_SERVICE_DISCONNECTED discReason:%d/%d",__func__, Info->p.remDev->discReason, Info->p.remDev->discReason_saved); + TRACE(3,"%s HF_EVENT_SERVICE_DISCONNECTED discReason:%d/%d",__func__, ctx->disc_reason, ctx->disc_reason_saved); + bt_profile_manager[id].hfp_connect = bt_profile_connect_status_failure; + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_openreconnecting) + { + if (++bt_profile_manager[id].reconnect_cnt < APP_BT_PROFILE_OPENNING_RECONNECT_RETRY_LIMIT_CNT) + { + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + profile_reconnect_enable = true; + bt_profile_manager[id].hfp_connect = bt_profile_connect_status_unknow; + } + } + else if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_reconnecting) + { + if (++bt_profile_manager[id].reconnect_cnt < APP_BT_PROFILE_RECONNECT_RETRY_LIMIT_CNT) + { + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + profile_reconnect_enable = true; + } + else + { + app_bt_restore_reconnecting_idle_mode(id); + // bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_null; + } + TRACE(2,"%s try to reconnect cnt:%d",__func__, bt_profile_manager[id].reconnect_cnt); + /* + }else if ((Info->p.remDev->discReason == 0x8)|| + (Info->p.remDev->discReason_saved == 0x8)){ + */ + } +#if !defined(IBRT) +#if defined(ENHANCED_STACK) + else if ((ctx->disc_reason == 0x8)|| + (ctx->disc_reason_saved == 0x8) || + (ctx->disc_reason == 0x4)|| + (ctx->disc_reason_saved == 0x4)) +#else + else if ((ctx->disc_reason == 0x8)|| + (ctx->disc_reason_saved == 0x8) || + (ctx->disc_reason == 0x0)|| + (ctx->disc_reason_saved == 0x0)) +#endif + { + bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_reconnecting; + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + TRACE(2,"%s try to reconnect reason =%d",__func__,ctx->disc_reason); + if(app_bt_profile_reconnect_pending(id) != 0) + { + profile_reconnect_enable = true; + } + } +#endif + else + { + bt_profile_manager[id].hfp_connect = bt_profile_connect_status_unknow; + } + + if (profile_reconnect_enable) + { +#ifdef __IAG_BLE_INCLUDE__ + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); +#endif + osTimerStart(bt_profile_manager[id].connect_timer, APP_BT_PROFILE_RECONNECT_RETRY_INTERVAL_MS); + } + break; + default: + break; + } + } + DUMP8("%02x ", &bt_profile_manager[id].rmt_addr.address, 6); + btdevice_profile *btdevice_plf_p1 = (btdevice_profile *)app_bt_profile_active_store_ptr_get((uint8_t *)&bt_profile_manager[id].rmt_addr.address); + + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_reconnecting) + { + bool reconnect_hfp_proc_final = false; + bool reconnect_a2dp_proc_final = false; + + if (bt_profile_manager[id].hfp_connect != bt_profile_connect_status_success) + { + reconnect_hfp_proc_final = false; + } + else + { + reconnect_hfp_proc_final = true; + } + if (bt_profile_manager[id].a2dp_connect != bt_profile_connect_status_success) + { + if(btdevice_plf_p1->hfp_act && btdevice_plf_p1->a2dp_act) + { + reconnect_a2dp_proc_final = false; + } + else + { + reconnect_a2dp_proc_final = true; + } + } + if (reconnect_hfp_proc_final && reconnect_a2dp_proc_final) + { + TRACE(3,"!!!reconnect success %d/%d/%d\n", bt_profile_manager[id].hfp_connect, bt_profile_manager[id].hsp_connect, bt_profile_manager[id].a2dp_connect); + app_bt_restore_reconnecting_idle_mode(id); + // bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_null; + } + } + else if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_openreconnecting) + { + bool opening_hfp_proc_final = false; + bool opening_a2dp_proc_final = false; + + if (btdevice_plf_p1->hfp_act && bt_profile_manager[id].hfp_connect == bt_profile_connect_status_unknow) + { + opening_hfp_proc_final = false; + } + else + { + opening_hfp_proc_final = true; + } + + if (btdevice_plf_p1->a2dp_act && bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_unknow) + { + opening_a2dp_proc_final = false; + } + else + { + opening_a2dp_proc_final = true; + } + + if(opening_hfp_proc_final && opening_a2dp_proc_final) + { + TRACE(3,"!!!reconnect success %d/%d/%d\n", bt_profile_manager[id].hfp_connect, bt_profile_manager[id].hsp_connect, bt_profile_manager[id].a2dp_connect); + bt_profile_manager[id].saved_reconnect_mode = bt_profile_reconnect_openreconnecting; + app_bt_restore_reconnecting_idle_mode(id); + } + else if(bt_profile_manager[id].hfp_connect == bt_profile_connect_status_failure) + { + TRACE(3,"reconnect_mode888:%d",bt_profile_manager[0].reconnect_mode); + TRACE(3,"!!!reconnect success %d/%d/%d\n", bt_profile_manager[id].hfp_connect, bt_profile_manager[id].hsp_connect, bt_profile_manager[id].a2dp_connect); + bt_profile_manager[id].saved_reconnect_mode = bt_profile_reconnect_openreconnecting; + if ((bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_openreconnecting) + &&(bt_profile_manager[id].reconnect_cnt >= APP_BT_PROFILE_OPENNING_RECONNECT_RETRY_LIMIT_CNT)) + { + app_bt_restore_reconnecting_idle_mode(id); + } + } + + if (btdevice_plf_p1->hfp_act && bt_profile_manager[id].hfp_connect == bt_profile_connect_status_success) + { + if (btdevice_plf_p1->a2dp_act && !opening_a2dp_proc_final) + { + TRACE(1,"!!!continue connect a2dp %p\n", bt_profile_manager[id].stream); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_A2DP_OpenStream(bt_profile_manager[id].stream, &bt_profile_manager[id].rmt_addr); + } + } + + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_null) + { + for (uint8_t i=0; istart reconnect second device\n"); + if ((btdevice_plf_p_temp->hfp_act)&&(!bt_profile_manager[i].hfp_connect)) + { + TRACE(0,"try connect hf"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_HF_CreateServiceLink(bt_profile_manager[i].chan, (bt_bdaddr_t *)&bt_profile_manager[i].rmt_addr); + } +#if defined (__HSP_ENABLE__) + else if((btdevice_plf_p_temp->hsp_act)&&(!bt_profile_manager[i].hsp_connect)) + { + TRACE(0,"try connect hs"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_HS_CreateServiceLink(bt_profile_manager[i].hs_chan, &bt_profile_manager[i].rmt_addr); + } +#endif + else if((btdevice_plf_p_temp->a2dp_act)&&(!bt_profile_manager[i].a2dp_connect)) + { + TRACE(0,"try connect a2dp"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_A2DP_OpenStream(bt_profile_manager[i].stream, &bt_profile_manager[i].rmt_addr); + } + break; + } + } + } + } +#ifdef __INTERCONNECTION__ + if (bt_profile_manager[id].hfp_connect == bt_profile_connect_status_success && + bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_success) + { + app_interconnection_start_disappear_adv(INTERCONNECTION_BLE_ADVERTISING_INTERVAL, + APP_INTERCONNECTION_DISAPPEAR_ADV_IN_MS); + + if (btif_me_get_activeCons() <= 2) + { + app_interconnection_spp_open(btif_me_enumerate_remote_devices(id)); + } + } +#endif + +#ifdef __IAG_BLE_INCLUDE__ + TRACE(3, "%s hfp %d a2dp %d", __func__, bt_profile_manager[id].hfp_connect, bt_profile_manager[id].a2dp_connect); + if (bt_profile_manager[id].hfp_connect == bt_profile_connect_status_success && +#ifdef __HSP_ENABLE__ + bt_profile_manager[id].hsp_connect == bt_profile_connect_status_success&& +#endif + bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_success) + { + app_ble_force_switch_adv(BLE_SWITCH_USER_BT_CONNECT, true); + } +#endif + + if (!bt_profile_manager[id].has_connected && + (bt_profile_manager[id].hfp_connect == bt_profile_connect_status_success || +#ifdef __HSP_ENABLE__ + bt_profile_manager[id].hsp_connect == bt_profile_connect_status_success|| +#endif + bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_success)) + { + + bt_profile_manager[id].has_connected = true; + TRACE(0,"BT connected!!!"); + once_event_case = 1; + /*if(IsMobileLinkLossing){ + startonce_delay_event_Timer_(3000); + } + else{ + startonce_delay_event_Timer_(1500); + }*/ + app_voice_report(APP_STATUS_INDICATION_CONNECTED,0); + IsMobileLinkLossing = FALSE; +#ifndef IBRT + btif_me_get_remote_device_name(&(ctx->remote_dev_bdaddr), app_bt_global_handle); +#endif +#if defined(MEDIA_PLAYER_SUPPORT)&& !defined(IBRT) + app_voice_report(APP_STATUS_INDICATION_CONNECTED, id); +#endif + +#if 0 // #ifdef __INTERCONNECTION__ + app_interconnection_start_disappear_adv(BLE_ADVERTISING_INTERVAL, APP_INTERCONNECTION_DISAPPEAR_ADV_IN_MS); + app_interconnection_spp_open(); +#endif + +#ifdef __INTERACTION__ + // app_interaction_spp_open(); +#endif + } + + if (bt_profile_manager[id].has_connected && + (bt_profile_manager[id].hfp_connect != bt_profile_connect_status_success && +#ifdef __HSP_ENABLE__ + bt_profile_manager[id].hsp_connect != bt_profile_connect_status_success && +#endif + bt_profile_manager[id].a2dp_connect != bt_profile_connect_status_success)) + { + + bt_profile_manager[id].has_connected = false; + TRACE(0,"BT disconnected!!!"); + +#ifdef GFPS_ENABLED + if (app_gfps_is_last_response_pending()) + { + app_gfps_enter_connectable_mode_req_handler(app_gfps_get_last_response()); + } +#endif + +#if defined(MEDIA_PLAYER_SUPPORT)&& !defined(IBRT) + app_voice_report(APP_STATUS_INDICATION_DISCONNECTED, id); +#endif +#ifdef __INTERCONNECTION__ + app_interconnection_disconnected_callback(); +#endif + + app_set_disconnecting_all_bt_connections(false); + } + +#ifdef __BT_ONE_BRING_TWO__ + app_bt_update_connectable_mode_after_connection_management(); +#endif +} + +void app_bt_profile_connect_manager_a2dp(enum BT_DEVICE_ID_T id, a2dp_stream_t *Stream, const a2dp_callback_parms_t *info) +{ + btdevice_profile *btdevice_plf_p = NULL; + btif_remote_device_t *remDev = NULL; + btif_a2dp_callback_parms_t* Info = (btif_a2dp_callback_parms_t*)info; + osTimerStop(bt_profile_manager[id].connect_timer); + bt_profile_manager[id].connect_timer_cb = NULL; + bool profile_reconnect_enable = false; + + remDev = btif_a2dp_get_stream_conn_remDev(Stream); + if (remDev) + { + btdevice_plf_p = (btdevice_profile *)app_bt_profile_active_store_ptr_get(btif_me_get_remote_device_bdaddr(remDev)->address); + } + else + { + btdevice_plf_p = (btdevice_profile *)app_bt_profile_active_store_ptr_get(NULL); + } + + if (Stream&&Info) + { + + switch(Info->event) + { + case BTIF_A2DP_EVENT_STREAM_OPEN: + TRACE(4,"%s A2DP_EVENT_STREAM_OPEN,codec type=%x a2dp:%d mode:%d", + __func__, Info->p.configReq->codec.codecType, + bt_profile_manager[id].a2dp_connect, + bt_profile_manager[id].reconnect_mode); + + nv_record_btdevicerecord_set_a2dp_profile_active_state(btdevice_plf_p, true); + nv_record_btdevicerecord_set_a2dp_profile_codec(btdevice_plf_p, Info->p.configReq->codec.codecType); +#ifndef FPGA + nv_record_touch_cause_flush(); +#endif + if(bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_success) + { + TRACE(0,"!!!a2dp has opened force return "); + return; + } + bt_profile_manager[id].a2dp_connect = bt_profile_connect_status_success; + bt_profile_manager[id].reconnect_cnt = 0; + bt_profile_manager[id].stream = app_bt_device.a2dp_connected_stream[id]; + memcpy(bt_profile_manager[id].rmt_addr.address, btif_me_get_remote_device_bdaddr(btif_a2dp_get_stream_conn_remDev(Stream))->address, BTIF_BD_ADDR_SIZE); + app_bt_record_latest_connected_service_device_id(id); + if (false == bt_profile_manager[id].has_connected) + { + app_bt_resume_sniff_mode(id); + } + +#ifdef BTIF_DIP_DEVICE + btif_dip_get_remote_info(remDev); +#endif + + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_openreconnecting) + { + //do nothing + } + +#if defined(IBRT) + else if (app_bt_ibrt_reconnect_mobile_profile_flag_get()) + { + app_bt_ibrt_reconnect_mobile_profile_flag_clear(); +#else + else if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_reconnecting) + { +#endif + TRACE(2,"app_bt: hfp_act in NV =%d,a2dp_connect=%d",btdevice_plf_p->hfp_act,bt_profile_manager[id].hfp_connect); + if (btdevice_plf_p->hfp_act&& bt_profile_manager[id].hfp_connect != bt_profile_connect_status_success) + { + if (btif_hf_check_rfcomm_l2cap_channel_is_creating(&bt_profile_manager[id].rmt_addr)) + { + TRACE(0,"!!!remote is creating hfp after a2dp connected\n"); + } + else + { + TRACE(0,"!!!continue connect hfp\n"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_HF_CreateServiceLink(bt_profile_manager[id].chan, (bt_bdaddr_t *)&bt_profile_manager[id].rmt_addr); + } + } +#if defined (__HSP_ENABLE__) + else if(btdevice_plf_p->hsp_act&& bt_profile_manager[id].hsp_connect != bt_profile_connect_status_success) + { + TRACE(0,"!!!continue connect hsp\n"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_HS_CreateServiceLink(bt_profile_manager[id].hs_chan, &bt_profile_manager[id].rmt_addr); + } +#endif + } +#ifdef __AUTO_CONNECT_OTHER_PROFILE__ + else + { + if(btdevice_plf_p->hfp_act && bt_profile_manager[id].hfp_connect != bt_profile_connect_status_success) + { + bt_profile_manager[id].connect_timer_cb = app_bt_profile_connect_hf_retry_timehandler; + app_bt_accessmode_set(BAM_CONNECTABLE_ONLY); + osTimerStart(bt_profile_manager[id].connect_timer, APP_BT_PROFILE_CONNECT_RETRY_MS); + } +#if defined (__HSP_ENABLE__) + else if(btdevice_plf_p->hsp_act && bt_profile_manager[id].hsp_connect != bt_profile_connect_status_success) + { + bt_profile_manager[id].connect_timer_cb = app_bt_profile_connect_hs_retry_timehandler; + app_bt_accessmode_set(BAM_CONNECTABLE_ONLY); + osTimerStart(bt_profile_manager[id].connect_timer, APP_BT_PROFILE_CONNECT_RETRY_MS); + } +#endif + } +#endif +#ifdef APP_DISABLE_PAGE_SCAN_AFTER_CONN + disable_page_scan_check_timer_start(); +#endif + break; + case BTIF_A2DP_EVENT_STREAM_CLOSED: + + TRACE(2,"%s A2DP_EVENT_STREAM_CLOSED discReason1:%d",__func__, Info->discReason); + + if(Info->subevt != A2DP_CONN_CLOSED) + { + TRACE(0,"do not need set access mode"); + return ; + } + + if(Stream!=NULL) + { + if(btif_a2dp_get_remote_device(Stream)!=NULL) + TRACE(2,"%s A2DP_EVENT_STREAM_CLOSED discReason2:%d",__func__,btif_me_get_remote_device_disc_reason_saved(btif_a2dp_get_remote_device(Stream))); + } + +#if defined(IBRT) + if (app_bt_ibrt_reconnect_mobile_profile_flag_get()) + { + app_bt_HF_CreateServiceLink(bt_profile_manager[id].chan, (bt_bdaddr_t *)&bt_profile_manager[id].rmt_addr); + } +#endif + + bt_profile_manager[id].a2dp_connect = bt_profile_connect_status_failure; + + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_openreconnecting) + { + if (++bt_profile_manager[id].reconnect_cnt < APP_BT_PROFILE_OPENNING_RECONNECT_RETRY_LIMIT_CNT) + { + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + profile_reconnect_enable = true; + bt_profile_manager[id].a2dp_connect = bt_profile_connect_status_unknow; + } + } + else if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_reconnecting) + { + if (++bt_profile_manager[id].reconnect_cnt < APP_BT_PROFILE_RECONNECT_RETRY_LIMIT_CNT) + { + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + profile_reconnect_enable = true; + } + else + { + app_bt_restore_reconnecting_idle_mode(id); + // bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_null; + } + TRACE(2,"%s try to reconnect cnt:%d",__func__, bt_profile_manager[id].reconnect_cnt); + } +#if !defined(IBRT) +#if defined(ENHANCED_STACK) + else if(((Info->discReason == 0x08)|| + (Info->discReason == 0x04)) && +#else + else if(((Info->discReason == 0x8)|| + (Info->discReason_saved == 0x8)|| + (Info->discReason_saved == 0x0)) && +#endif + (btdevice_plf_p->a2dp_act)&& + (!btdevice_plf_p->hfp_act) && + (!btdevice_plf_p->hsp_act)) + { + bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_reconnecting; + TRACE(2,"%s try to reconnect cnt:%d",__func__, bt_profile_manager[id].reconnect_cnt); + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + if(app_bt_profile_reconnect_pending(id) != 0) + { + profile_reconnect_enable = true; + } + } +#endif + else + { + bt_profile_manager[id].a2dp_connect = bt_profile_connect_status_unknow; + } + + if (profile_reconnect_enable) + { +#ifdef __IAG_BLE_INCLUDE__ + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); +#endif + osTimerStart(bt_profile_manager[id].connect_timer, APP_BT_PROFILE_RECONNECT_RETRY_INTERVAL_MS); + } + break; + default: + break; + } + } + + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_reconnecting) + { + bool reconnect_hfp_proc_final = true; + bool reconnect_a2dp_proc_final = true; + if (bt_profile_manager[id].hfp_connect == bt_profile_connect_status_failure) + { + reconnect_hfp_proc_final = false; + } +#if defined (__HSP_ENABLE__) + if(btdevice_plf_p->hsp_act !=0) //has HSP + { + reconnect_hfp_proc_final = true; + if (bt_profile_manager[id].hsp_connect == bt_profile_connect_status_failure) + { + reconnect_hfp_proc_final = false; + } + } +#endif + if (bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_failure) + { + reconnect_a2dp_proc_final = false; + } + if (reconnect_hfp_proc_final && reconnect_a2dp_proc_final) + { + TRACE(3,"!!!reconnect success %d/%d/%d\n", bt_profile_manager[id].hfp_connect, bt_profile_manager[id].hsp_connect, bt_profile_manager[id].a2dp_connect); + app_bt_restore_reconnecting_idle_mode(id); + // bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_null; + } + } + else if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_openreconnecting) + { + bool opening_hfp_proc_final = false; + bool opening_a2dp_proc_final = false; + + if (btdevice_plf_p->hfp_act && bt_profile_manager[id].hfp_connect == bt_profile_connect_status_unknow) + { + opening_hfp_proc_final = false; + } + else + { + opening_hfp_proc_final = true; + } + + if (btdevice_plf_p->a2dp_act && bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_unknow) + { + opening_a2dp_proc_final = false; + } + else + { + opening_a2dp_proc_final = true; + } + + if ((opening_hfp_proc_final && opening_a2dp_proc_final) || + (bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_failure)) + { + TRACE(3,"!!!reconnect success %d/%d/%d\n", bt_profile_manager[id].hfp_connect, bt_profile_manager[id].hsp_connect, bt_profile_manager[id].a2dp_connect); + app_bt_restore_reconnecting_idle_mode(id); + // bt_profile_manager[id].reconnect_mode = bt_profile_reconnect_null; + } + + if (btdevice_plf_p->a2dp_act && bt_profile_manager[id].a2dp_connect== bt_profile_connect_status_success) + { + if (btdevice_plf_p->hfp_act && !opening_hfp_proc_final) + { + if (btif_hf_check_rfcomm_l2cap_channel_is_creating(&bt_profile_manager[id].rmt_addr)) + { + TRACE(0,"!!!remote is creating hf after a2dp connected\n"); + } + else + { + TRACE(0,"!!!continue connect hf\n"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_HF_CreateServiceLink(bt_profile_manager[id].chan, (bt_bdaddr_t *)&bt_profile_manager[id].rmt_addr); + } + } +#if defined (__HSP_ENABLE) + else if(btdevice_plf_p->hsp_act && !opening_hfp_hsp_proc_final) + { + TRACE(0,"!!!continue connect hs\n"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[id].has_connected); + app_bt_HS_CreateServiceLink(bt_profile_manager[id].hs_chan, &bt_profile_manager[id].rmt_addr); + } +#endif + } + + if (bt_profile_manager[id].reconnect_mode == bt_profile_reconnect_null) + { + for (uint8_t i=0; istart reconnect device %d\n", i); + if ((btdevice_plf_p->hfp_act)&&(!bt_profile_manager[i].hfp_connect)) + { + TRACE(0,"try connect hf"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[i].has_connected); + app_bt_HF_CreateServiceLink(bt_profile_manager[i].chan, (bt_bdaddr_t *)&bt_profile_manager[i].rmt_addr); + } +#if defined (__HSP_ENABLE__) + else if((btdevice_plf_p->hsp_act)&&(!bt_profile_manager[i].hsp_connect)) + { + TRACE(0,"try connect hs"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[i].has_connected); + app_bt_HS_CreateServiceLink(bt_profile_manager[i].hs_chan, &bt_profile_manager[i].rmt_addr); + } +#endif + else if((btdevice_plf_p->a2dp_act)&&(!bt_profile_manager[i].a2dp_connect)) + { + TRACE(0,"try connect a2dp"); + app_bt_precheck_before_starting_connecting(bt_profile_manager[i].has_connected); + app_bt_A2DP_OpenStream(bt_profile_manager[i].stream, &bt_profile_manager[i].rmt_addr); + } + break; + } + } + } + } + +#ifdef __INTERCONNECTION__ + if (bt_profile_manager[id].hfp_connect == bt_profile_connect_status_success && + bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_success) + { + app_interconnection_start_disappear_adv(INTERCONNECTION_BLE_ADVERTISING_INTERVAL, + APP_INTERCONNECTION_DISAPPEAR_ADV_IN_MS); + + if (btif_me_get_activeCons() <= 2) + { + app_interconnection_spp_open(remDev); + } + } +#endif + +#ifdef __IAG_BLE_INCLUDE__ + TRACE(3, "%s hfp %d a2dp %d", __func__, bt_profile_manager[id].hfp_connect, bt_profile_manager[id].a2dp_connect); + if (bt_profile_manager[id].hfp_connect == bt_profile_connect_status_success && +#ifdef __HSP_ENABLE__ + bt_profile_manager[id].hsp_connect == bt_profile_connect_status_success && +#endif + bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_success) + { + app_ble_force_switch_adv(BLE_SWITCH_USER_BT_CONNECT, true); + } +#endif + + if (!bt_profile_manager[id].has_connected && + (bt_profile_manager[id].hfp_connect == bt_profile_connect_status_success || +#ifdef __HSP_ENABLE__ + bt_profile_manager[id].hsp_connect == bt_profile_connect_status_success|| +#endif + bt_profile_manager[id].a2dp_connect == bt_profile_connect_status_success)) + { + + bt_profile_manager[id].has_connected = true; + TRACE(0,"BT connected!!!"); + IsMobileLinkLossing = FALSE; +#ifndef IBRT + btif_me_get_remote_device_name(&(bt_profile_manager[id].rmt_addr), app_bt_global_handle); +#endif +#if defined(MEDIA_PLAYER_SUPPORT)//&& !defined(IBRT) + app_voice_report(APP_STATUS_INDICATION_CONNECTED, id); +#endif + +#if 0 // #ifdef __INTERCONNECTION__ + app_interconnection_start_disappear_adv(BLE_ADVERTISING_INTERVAL, APP_INTERCONNECTION_DISAPPEAR_ADV_IN_MS); + app_interconnection_spp_open(); +#endif + +#ifdef __INTERACTION__ + // app_interaction_spp_open(); +#endif + } + + if (bt_profile_manager[id].has_connected && + (bt_profile_manager[id].hfp_connect != bt_profile_connect_status_success && +#ifdef __HSP_ENABLE__ + bt_profile_manager[id].hsp_connect != bt_profile_connect_status_success && +#endif + bt_profile_manager[id].a2dp_connect != bt_profile_connect_status_success)) + { + + bt_profile_manager[id].has_connected = false; + TRACE(0,"BT disconnected!!!"); + +#ifdef GFPS_ENABLED + if (app_gfps_is_last_response_pending()) + { + app_gfps_enter_connectable_mode_req_handler(app_gfps_get_last_response()); + } +#endif + +#if defined(MEDIA_PLAYER_SUPPORT)&& !defined(IBRT) + app_voice_report(APP_STATUS_INDICATION_DISCONNECTED, id); +#endif +#ifdef __INTERCONNECTION__ + app_interconnection_disconnected_callback(); +#endif + + app_set_disconnecting_all_bt_connections(false); + } + +#ifdef __BT_ONE_BRING_TWO__ + app_bt_update_connectable_mode_after_connection_management(); +#endif +} + +#ifdef BTIF_HID_DEVICE +void hid_exit_shutter_mode(void); +#endif + +static bool isDisconnectAllBtConnections = false; + +bool app_is_disconnecting_all_bt_connections(void) +{ + return isDisconnectAllBtConnections; +} + +void app_set_disconnecting_all_bt_connections(bool isEnable) +{ + isDisconnectAllBtConnections = isEnable; +} + +bt_status_t LinkDisconnectDirectly(bool PowerOffFlag) +{ + app_set_disconnecting_all_bt_connections(true); + //TRACE(1,"osapi_lock_is_exist:%d",osapi_lock_is_exist()); + if(osapi_lock_is_exist()) + osapi_lock_stack(); +#ifdef __IAG_BLE_INCLUDE__ + TRACE(1,"ble_connected_state:%d", app_ble_is_any_connection_exist()); +#endif + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if(true==PowerOffFlag) + p_ibrt_ctrl->ibrt_in_poweroff= true; + + if (p_ibrt_ctrl->init_done) + { + if(IBRT_MASTER==p_ibrt_ctrl->current_role) + { + if(app_tws_ibrt_mobile_link_connected()) + { + //should check return status + app_tws_ibrt_disconnect_connection(btif_me_get_remote_device_by_handle(p_ibrt_ctrl->mobile_conhandle)); + } + } + if (app_tws_ibrt_tws_link_connected()) + { + app_tws_ibrt_disconnect_connection(btif_me_get_remote_device_by_handle(p_ibrt_ctrl->tws_conhandle)); + } + } + + if(osapi_lock_is_exist()) + osapi_unlock_stack(); + + osDelay(500); + + return BT_STS_SUCCESS; +#endif + + TRACE(1,"activeCons:%d", btif_me_get_activeCons()); + + uint8_t Tmp_activeCons = btif_me_get_activeCons(); + + if(Tmp_activeCons) + { + //TRACE(3,"%s id1 hf:%d a2dp:%d",__func__, app_bt_device.hf_channel[BT_DEVICE_ID_1].state, btif_a2dp_get_stream_state(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream)); + TRACE(3,"%s id1 hf:%d a2dp:%d",__func__, btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_1]), btif_a2dp_get_stream_state(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream)); +#ifdef BTIF_HID_DEVICE + hid_exit_shutter_mode(); +#endif + if (btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_1]) == BTIF_HF_STATE_OPEN) + { + app_bt_HF_DisconnectServiceLink(app_bt_device.hf_channel[BT_DEVICE_ID_1]); + } +#if defined (__HSP_ENABLE__) + if(app_bt_device.hs_channel[BT_DEVICE_ID_1].state == HS_STATE_OPEN) + { + app_bt_HS_DisconnectServiceLink(&app_bt_device.hs_channel[BT_DEVICE_ID_1]); + } +#endif //btif_a2dp_get_stream_state(app_bt_device.a2dp_stream[device_id]->a2dp_stream) + if(btif_a2dp_get_stream_state(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_STREAMING || + btif_a2dp_get_stream_state(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_OPEN) + { + app_bt_A2DP_CloseStream(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream); + } +#if defined(A2DP_LHDC_ON) + if(btif_a2dp_get_stream_state(app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_1]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_STREAMING || + btif_a2dp_get_stream_state(app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_1]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_OPEN) + { + app_bt_A2DP_CloseStream(app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_1]->a2dp_stream); + } +#endif +#if defined(A2DP_LDAC_ON) + if(btif_a2dp_get_stream_state(app_bt_device.a2dp_ldac_stream[BT_DEVICE_ID_1]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_STREAMING || + btif_a2dp_get_stream_state(app_bt_device.a2dp_ldac_stream[BT_DEVICE_ID_1]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_OPEN) + { + app_bt_A2DP_CloseStream(app_bt_device.a2dp_ldac_stream[BT_DEVICE_ID_1]->a2dp_stream); + } +#endif + +#if defined(A2DP_AAC_ON) + if(btif_a2dp_get_stream_state( app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_STREAMING || + btif_a2dp_get_stream_state( app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_OPEN) + { + app_bt_A2DP_CloseStream(app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream); + } +#endif +#if defined(A2DP_SCALABLE_ON) + if(btif_a2dp_get_stream_state( app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_1]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_STREAMING || + btif_a2dp_get_stream_state(app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_1]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_OPEN) + { + app_bt_A2DP_CloseStream(app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_1]->a2dp_stream); + } +#endif + if( btif_avrcp_get_remote_device(app_bt_device.avrcp_channel[BT_DEVICE_ID_1]->avrcp_channel_handle)) + { + btif_avrcp_disconnect(app_bt_device.avrcp_channel[BT_DEVICE_ID_1]->avrcp_channel_handle); + } +#ifdef __BT_ONE_BRING_TWO__ + TRACE(3,"%s id2 hf:%d a2dp:%d",__func__, btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_2]), btif_a2dp_get_stream_state(app_bt_device.a2dp_stream[BT_DEVICE_ID_2]->a2dp_stream)); + //if(app_bt_device.hf_channel[BT_DEVICE_ID_2].state == HF_STATE_OPEN){ + if(btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_2]) == BTIF_HF_STATE_OPEN) + { + app_bt_HF_DisconnectServiceLink(app_bt_device.hf_channel[BT_DEVICE_ID_2]); + } + +#if defined (__HSP_ENABLE__) + if(app_bt_device.hs_channel[BT_DEVICE_ID_2].state == HS_STATE_OPEN) + { + app_bt_HS_DisconnectServiceLink(&app_bt_device.hs_channel[BT_DEVICE_ID_2]); + } +#endif // __HSP_ENABLE__ + + if( btif_a2dp_get_stream_state(app_bt_device.a2dp_stream[BT_DEVICE_ID_2]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_STREAMING || + btif_a2dp_get_stream_state(app_bt_device.a2dp_stream[BT_DEVICE_ID_2]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_OPEN) + { + app_bt_A2DP_CloseStream(app_bt_device.a2dp_stream[BT_DEVICE_ID_2]->a2dp_stream); + } +#if defined(A2DP_LHDC_ON) + if(btif_a2dp_get_stream_state(app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_2]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_STREAMING || + btif_a2dp_get_stream_state(app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_2]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_OPEN) + { + app_bt_A2DP_CloseStream(app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_2]->a2dp_stream); + } +#endif // A2DP_LHDC_ON +#if defined(A2DP_AAC_ON) + if(btif_a2dp_get_stream_state(app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_2]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_STREAMING || + btif_a2dp_get_stream_state(app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_2]->a2dp_stream)== BTIF_AVDTP_STRM_STATE_OPEN) + { + app_bt_A2DP_CloseStream(app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_2]->a2dp_stream); + } +#endif // A2DP_AAC_ON +#if defined(A2DP_SCALABLE_ON) + if(btif_a2dp_get_stream_state(app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_2]->a2dp_stream)== BTIF_AVDTP_STRM_STATE_STREAMING || + btif_a2dp_get_stream_state(app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_2]->a2dp_stream) == BTIF_AVDTP_STRM_STATE_OPEN) + { + app_bt_A2DP_CloseStream(app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_2]->a2dp_stream); + } +#endif // A2DP_SCALABLE_ON + if( btif_avrcp_get_remote_device(app_bt_device.avrcp_channel[BT_DEVICE_ID_2]->avrcp_channel_handle)) + { + btif_avrcp_disconnect(app_bt_device.avrcp_channel[BT_DEVICE_ID_2]->avrcp_channel_handle); + } +#endif //__BT_ONE_BRING_TWO__ + +#ifdef BISTO_ENABLED + gsound_custom_bt_disconnect_all_channel(); +#endif + } + +#ifdef __IAG_BLE_INCLUDE__ + if(app_ble_is_any_connection_exist()) + { +#ifdef GFPS_ENABLED + if (!app_gfps_is_last_response_pending()) +#endif + app_ble_disconnect_all(); + } +#endif + + if(osapi_lock_is_exist()) + osapi_unlock_stack(); + + osDelay(500); + + if(Tmp_activeCons) + { + btif_remote_device_t* remDev = app_bt_get_remoteDev(BT_DEVICE_ID_1); + if (NULL != remDev) + { + app_bt_MeDisconnectLink(remDev); + } + +#ifdef __BT_ONE_BRING_TWO__ + remDev = app_bt_get_remoteDev(BT_DEVICE_ID_2); + if (NULL != remDev) + { + osDelay(200); + app_bt_MeDisconnectLink(remDev); + } +#endif + } + return BT_STS_SUCCESS; +} + +void app_disconnect_all_bt_connections(void) +{ + LinkDisconnectDirectly(false); +} + +static int app_custom_function_process(APP_MESSAGE_BODY *msg_body) +{ + APP_APPTHREAD_REQ_CUSTOMER_CALL_FN_T customer_call = (APP_APPTHREAD_REQ_CUSTOMER_CALL_FN_T)(msg_body->message_ptr); + TRACE(4, "func:0x%08x,param0:0x%08x, param1:0x%08x", + msg_body->message_ptr, + msg_body->message_Param0, + msg_body->message_Param1); + if (customer_call){ + customer_call((void *)msg_body->message_Param0, (void *)msg_body->message_Param1); + } + return 0; +} + +int app_bt_start_custom_function_in_app_thread( + uint32_t param0, uint32_t param1, uint32_t funcPtr) +{ + APP_MESSAGE_BLOCK msg; + + msg.mod_id = APP_MODUAL_CUSTOM_FUNCTION; + msg.msg_body.message_id = 0; + msg.msg_body.message_ptr = funcPtr; + msg.msg_body.message_Param0 = param0; + msg.msg_body.message_Param1 = param1; + + app_mailbox_put(&msg); + return 0; +} + +void app_bt_init(void) +{ + app_bt_mail_init(); + app_set_threadhandle(APP_MODUAL_BT, app_bt_handle_process); + btif_me_sec_set_io_cap_rsp_reject_ext(app_bt_profile_connect_openreconnecting); + app_bt_active_mode_manager_init(); + app_set_threadhandle(APP_MODUAL_CUSTOM_FUNCTION, app_custom_function_process); +} + +extern "C" bool app_bt_has_connectivitys(void) +{ + int activeCons; + osapi_lock_stack(); + activeCons = btif_me_get_activeCons(); + osapi_unlock_stack(); + + if(activeCons > 0) + return true; + + return false; +#if 0 + if(app_bt_device.hf_channel[BT_DEVICE_ID_1].cmgrHandler.remDev) + return true; + if(app_bt_device.a2dp_stream[BT_DEVICE_ID_1].device->cmgrHandler.remDev) + return true; +#ifdef __BT_ONE_BRING_TWO__ + if(app_bt_device.hf_channel[BT_DEVICE_ID_2].cmgrHandler.remDev) + return true; + if(app_bt_device.a2dp_stream[BT_DEVICE_ID_2].device->cmgrHandler.remDev) + return true; +#endif + return false; +#endif +} + + +#ifdef __TWS_CHARGER_BOX__ + +extern "C" { + bt_status_t ME_Ble_Clear_Whitelist(void); + bt_status_t ME_Ble_Set_Private_Address(BT_BD_ADDR *addr); + bt_status_t ME_Ble_Add_Dev_To_Whitelist(U8 addr_type,BT_BD_ADDR *addr); + bt_status_t ME_Ble_SetAdv_data(U8 len, U8 *data); + bt_status_t ME_Ble_SetScanRsp_data(U8 len, U8 *data); + bt_status_t ME_Ble_SetAdv_parameters(adv_para_struct *para); + bt_status_t ME_Ble_SetAdv_en(U8 en); + bt_status_t ME_Ble_Setscan_parameter(scan_para_struct *para); + bt_status_t ME_Ble_Setscan_en(U8 scan_en, U8 filter_duplicate); +} + + +int8_t power_level=0; +#define TWS_BOX_OPEN 1 +#define TWS_BOX_CLOSE 0 +void app_tws_box_set_slave_adv_data(uint8_t power_level,uint8_t box_status) +{ + uint8_t adv_data[] = + { + 0x02,0xfe, 0x00, + 0x02, 0xfd, 0x00 // manufacturer data + }; + + adv_data[2] = power_level; + + adv_data[5] = box_status; + ME_Ble_SetAdv_data(sizeof(adv_data), adv_data); + +} + + +void app_tws_box_set_slave_adv_para(void) +{ + uint8_t peer_addr[BTIF_BD_ADDR_SIZE] = {0}; + adv_para_struct para; + + + para.interval_min = 0x0040; // 20ms + para.interval_max = 0x0040; // 20ms + para.adv_type = 0x03; + para.own_addr_type = 0x01; + para.peer_addr_type = 0x01; + para.adv_chanmap = 0x07; + para.adv_filter_policy = 0x00; + memcpy(para.bd_addr.addr, peer_addr, BTIF_BD_ADDR_SIZE); + + ME_Ble_SetAdv_parameters(¶); + +} + + +extern uint8_t bt_addr[6]; +void app_tws_start_chargerbox_adv(void) +{ + app_tws_box_set_slave_adv_data(power_level,TWS_BOX_OPEN); + ME_Ble_Set_Private_Address((BT_BD_ADDR *)bt_addr); + app_tws_box_set_slave_adv_para(); + ME_Ble_SetAdv_en(1); + +} + + + +#endif + +bool app_is_hfp_service_connected(void) +{ + return (bt_profile_manager[BT_DEVICE_ID_1].hfp_connect == bt_profile_connect_status_success); +} + + +btif_remote_device_t* app_bt_get_remoteDev(uint8_t deviceId) +{ + btif_remote_device_t* currentRemDev = NULL; + + if(btif_a2dp_get_stream_state( app_bt_device.a2dp_stream[deviceId]->a2dp_stream) + == BTIF_AVDTP_STRM_STATE_STREAMING || + btif_a2dp_get_stream_state( app_bt_device.a2dp_stream[deviceId]->a2dp_stream) + == BTIF_AVDTP_STRM_STATE_OPEN) + { + currentRemDev = btif_a2dp_get_stream_conn_remDev(app_bt_device.a2dp_stream[deviceId]->a2dp_stream); + } + else if (btif_get_hf_chan_state(app_bt_device.hf_channel[deviceId]) == BTIF_HF_STATE_OPEN) + { + currentRemDev = (btif_remote_device_t *)btif_hf_cmgr_get_remote_device(app_bt_device.hf_channel[deviceId]); + } + + TRACE(2,"%s get current Remdev %p", __FUNCTION__, currentRemDev); + + return currentRemDev; +} + +void app_bt_stay_active_rem_dev(btif_remote_device_t* pRemDev) +{ + if (pRemDev) + { + btif_cmgr_handler_t *cmgrHandler; + /* Clear the sniff timer */ + cmgrHandler = btif_cmgr_get_acl_handler(pRemDev); + btif_cmgr_clear_sniff_timer(cmgrHandler); + btif_cmgr_disable_sniff_timer(cmgrHandler); + app_bt_Me_SetLinkPolicy(pRemDev, BTIF_BLP_MASTER_SLAVE_SWITCH); + } +} + +void app_bt_stay_active(uint8_t deviceId) +{ + btif_remote_device_t* currentRemDev = app_bt_get_remoteDev(deviceId); + app_bt_stay_active_rem_dev(currentRemDev); +} + +void app_bt_allow_sniff_rem_dev(btif_remote_device_t* pRemDev) +{ + if (pRemDev && (BTIF_BDS_CONNECTED == btif_me_get_remote_device_state(pRemDev))) + { + btif_cmgr_handler_t *cmgrHandler; + /* Enable the sniff timer */ + cmgrHandler = btif_cmgr_get_acl_handler(pRemDev); + + /* Start the sniff timer */ + btif_sniff_info_t sniffInfo; + sniffInfo.minInterval = BTIF_CMGR_SNIFF_MIN_INTERVAL; + sniffInfo.maxInterval = BTIF_CMGR_SNIFF_MAX_INTERVAL; + sniffInfo.attempt = BTIF_CMGR_SNIFF_ATTEMPT; + sniffInfo.timeout = BTIF_CMGR_SNIFF_TIMEOUT; + if (cmgrHandler) + { + btif_cmgr_set_sniff_timer(cmgrHandler, &sniffInfo, BTIF_CMGR_SNIFF_TIMER); + } + app_bt_Me_SetLinkPolicy(pRemDev, BTIF_BLP_MASTER_SLAVE_SWITCH | BTIF_BLP_SNIFF_MODE); + } +} + +extern "C" uint8_t is_sco_mode (void); +void app_bt_allow_sniff(uint8_t deviceId) +{ + if (a2dp_is_music_ongoing() || is_sco_mode()) + { + return; + } + btif_remote_device_t* currentRemDev = app_bt_get_remoteDev(deviceId); + app_bt_allow_sniff_rem_dev(currentRemDev); +} + +void app_bt_stop_sniff(uint8_t deviceId) +{ + btif_remote_device_t* currentRemDev = app_bt_get_remoteDev(deviceId); + + if (currentRemDev && (btif_me_get_remote_device_state(currentRemDev) == BTIF_BDS_CONNECTED)) + { + if (btif_me_get_current_mode(currentRemDev) == BTIF_BLM_SNIFF_MODE) + { + TRACE(1,"!!! stop sniff currmode:%d\n", btif_me_get_current_mode(currentRemDev)); + app_bt_ME_StopSniff(currentRemDev); + } + } +} + +bool app_bt_is_device_connected(uint8_t deviceId) +{ + if (deviceId < BT_DEVICE_NUM) + { + return bt_profile_manager[deviceId].has_connected; + } + else + { + // Indicate no connection is user passes invalid deviceId + return false; + } +} + +#if defined(__BT_SELECT_PROF_DEVICE_ID__) +int8_t app_bt_a2dp_is_same_stream(a2dp_stream_t *src_Stream, a2dp_stream_t *dst_Stream) +{ + return btif_a2dp_is_register_codec_same(src_Stream, dst_Stream); +} +void app_bt_a2dp_find_same_unused_stream(a2dp_stream_t *in_Stream, a2dp_stream_t **out_Stream, uint32_t device_id) +{ + *out_Stream = NULL; + if (app_bt_a2dp_is_same_stream(app_bt_device.a2dp_stream[device_id]->a2dp_stream, in_Stream)) + *out_Stream = app_bt_device.a2dp_stream[device_id]->a2dp_stream; +#if defined(A2DP_LHDC_ON) + else if (app_bt_a2dp_is_same_stream(app_bt_device.a2dp_lhdc_stream[device_id]->a2dp_stream, in_Stream)) + *out_Stream = app_bt_device.a2dp_lhdc_stream[device_id]->a2dp_stream; +#endif +#if defined(A2DP_LDAC_ON) + else if (app_bt_a2dp_is_same_stream(app_bt_device.a2dp_ldac_stream[device_id]->a2dp_stream, in_Stream)) + *out_Stream = app_bt_device.a2dp_ldac_stream[device_id]->a2dp_stream; +#endif +#if defined(A2DP_AAC_ON) + else if (app_bt_a2dp_is_same_stream(app_bt_device.a2dp_aac_stream[device_id]->a2dp_stream, in_Stream)) + *out_Stream = app_bt_device.a2dp_aac_stream[device_id]->a2dp_stream; +#endif +#if defined(A2DP_SCALABLE_ON) + else if (app_bt_a2dp_is_same_stream(app_bt_device.a2dp_scalable_stream[device_id]->a2dp_stream, in_Stream)) + *out_Stream = app_bt_device.a2dp_scalable_stream[device_id]->a2dp_stream; +#endif +} +int8_t app_bt_a2dp_is_stream_on_device_id(a2dp_stream_t *in_Stream, uint32_t device_id) +{ + if (app_bt_device.a2dp_stream[device_id]->a2dp_stream == in_Stream) + return 1; +#if defined(A2DP_LHDC_ON) + else if (app_bt_device.a2dp_lhdc_stream[device_id]->a2dp_stream == in_Stream) + return 1; +#endif +#if defined(A2DP_LDAC_ON) + else if (app_bt_device.a2dp_ldac_stream[device_id]->a2dp_stream == in_Stream) + return 1; +#endif +#if defined(A2DP_AAC_ON) + else if (app_bt_device.a2dp_aac_stream[device_id]->a2dp_stream == in_Stream) + return 1; +#endif +#if defined(A2DP_SCALABLE_ON) + else if (app_bt_device.a2dp_scalable_stream[device_id]->a2dp_stream == in_Stream) + return 1; +#endif + return 0; +} +int8_t app_bt_hfp_is_chan_on_device_id(hf_chan_handle_t chan, uint32_t device_id) +{ + if (app_bt_device.hf_channel[device_id] == chan) + return 1; + return 0; +} +int8_t app_bt_is_any_profile_connected(uint32_t device_id) +{ + // TODO avrcp?spp?hid?bisto?ama?dma?rfcomm? + if ((bt_profile_manager[device_id].hfp_connect == bt_profile_connect_status_success) + || (bt_profile_manager[device_id].hsp_connect == bt_profile_connect_status_success) + || (bt_profile_manager[device_id].a2dp_connect == bt_profile_connect_status_success)) + { + return 1; + } + + return 0; +} +int8_t app_bt_is_a2dp_connected(uint32_t device_id) +{ + if (bt_profile_manager[device_id].a2dp_connect == bt_profile_connect_status_success) + { + return 1; + } + + return 0; +} +btif_remote_device_t *app_bt_get_connected_profile_remdev(uint32_t device_id) +{ + if (bt_profile_manager[device_id].a2dp_connect == bt_profile_connect_status_success) + { + return (btif_remote_device_t *)btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[device_id]); + } + else if (bt_profile_manager[device_id].hfp_connect == bt_profile_connect_status_success) + { + return (btif_remote_device_t *)btif_hf_cmgr_get_remote_device(app_bt_device.hf_channel[device_id]); + } +#if defined (__HSP_ENABLE__) + else if (bt_profile_manager[device_id].hsp_connect == bt_profile_connect_status_success) + { + // TODO hsp support + //return (btif_remote_device_t *)btif_hs_cmgr_get_remote_device(app_bt_device.hs_channel[i]); + } +#endif + + return NULL; +} +#endif + +bool app_bt_get_device_bdaddr(uint8_t deviceId, uint8_t* btAddr) +{ + bool ret = false; + + if (app_bt_is_device_connected(deviceId)) + { + btif_remote_device_t* currentRemDev = app_bt_get_remoteDev(deviceId); + + if (currentRemDev) + { + memcpy(btAddr, btif_me_get_remote_device_bdaddr(currentRemDev)->address, BTIF_BD_ADDR_SIZE); + ret = true; + } + } + + return ret; +} + +void fast_pair_enter_pairing_mode_handler(void) +{ +#if defined(IBRT) + app_ibrt_ui_judge_scan_type(IBRT_FASTPAIR_TRIGGER, MOBILE_LINK, 0); +#else + app_bt_accessmode_set(BTIF_BAM_GENERAL_ACCESSIBLE); +#endif + +#ifdef __INTERCONNECTION__ + clear_discoverable_adv_timeout_flag(); + app_interceonnection_start_discoverable_adv(INTERCONNECTION_BLE_FAST_ADVERTISING_INTERVAL, + APP_INTERCONNECTION_FAST_ADV_TIMEOUT_IN_MS); +#endif +} + +bool app_bt_is_hfp_audio_on(void) +{ + bool hfp_audio_is_on = false; + for (uint8_t i=0; iaddress[0], addr->address[1], addr->address[2], addr->address[3], + addr->address[4], addr->address[5], name); + +#if defined(HFP_MOBILE_AG_ROLE) + bt_bdaddr_t test_device1 = {{0xd2, 0x53, 0x86, 0x42, 0x71, 0x31}}; + bt_bdaddr_t test_device2 = {{0xd3, 0x53, 0x86, 0x42, 0x71, 0x31}}; + return (memcmp(addr, test_device1.address, sizeof(bt_bdaddr_t)) == 0 || + memcmp(addr, test_device2.address, sizeof(bt_bdaddr_t)) == 0); +#else + return false; +#endif +} + +static struct app_bt_search_t g_bt_search; +static void app_bt_search_callback(const btif_event_t* event) +{ + TRACE(2,"%s event %d\n", __func__, btif_me_get_callback_event_type(event)); + + switch(btif_me_get_callback_event_type(event)) + { + case BTIF_BTEVENT_INQUIRY_RESULT: + { + bt_bdaddr_t *addr = btif_me_get_callback_event_inq_result_bd_addr(event); + uint8_t mode = btif_me_get_callback_event_inq_result_inq_mode(event); + const int NAME_MAX_LEN = 255; + char device_name[NAME_MAX_LEN+1] = {0}; + int device_name_len = 0; + uint8_t *eir = NULL; + + if ((mode == BTIF_INQ_MODE_EXTENDED) && + (eir = btif_me_get_callback_event_inq_result_ext_inq_resp(event))) + { + device_name_len = btif_me_get_ext_inq_data(eir, 0x09, (uint8_t *)device_name, NAME_MAX_LEN); + } + + if (app_bt_search_device_match(addr, device_name_len > 0 ? device_name : "")) + { + g_bt_search.address = *addr; + g_bt_search.device_searched = true; + btif_me_cancel_inquiry(); + } + } + break; + case BTIF_BTEVENT_INQUIRY_COMPLETE: + case BTIF_BTEVENT_INQUIRY_CANCELED: + btif_me_unregister_globa_handler((btif_handler *)btif_me_get_bt_handler()); + g_bt_search.search_start = false; + g_bt_search.inquiry_pending = false; + if (g_bt_search.device_searched) + { +#if defined(HFP_MOBILE_AG_ROLE) + bt_profile_manager[BT_DEVICE_ID_1].reconnect_mode = bt_profile_reconnect_null; + bt_profile_manager[BT_DEVICE_ID_1].rmt_addr = g_bt_search.address; + bt_profile_manager[BT_DEVICE_ID_1].chan = app_bt_device.hf_channel[BT_DEVICE_ID_1]; + app_bt_precheck_before_starting_connecting(bt_profile_manager[BT_DEVICE_ID_1].has_connected); + app_bt_HF_CreateServiceLink(bt_profile_manager[BT_DEVICE_ID_1].chan, &bt_profile_manager[BT_DEVICE_ID_1].rmt_addr); +#endif + } + else + { + TRACE(1,"%s no device matched\n", __func__); +#if 0 + /* continue to search ??? */ + app_bt_start_search(); +#endif + } + break; + default: + break; + } +} + +void app_bt_start_search(void) +{ + uint8_t max_search_time = 10; /* 12.8s */ + + if (g_bt_search.search_start) + { + TRACE(1,"%s already started\n", __func__); + return; + } + + btif_me_set_handler(btif_me_get_bt_handler(), app_bt_search_callback); + + btif_me_set_event_mask(btif_me_get_bt_handler(), + BTIF_BEM_INQUIRY_RESULT | BTIF_BEM_INQUIRY_COMPLETE | BTIF_BEM_INQUIRY_CANCELED | + BTIF_BEM_LINK_CONNECT_IND | BTIF_BEM_LINK_CONNECT_CNF | BTIF_BEM_LINK_DISCONNECT | + BTIF_BEM_ROLE_CHANGE | BTIF_BEM_MODE_CHANGE); + + btif_me_register_global_handler(btif_me_get_bt_handler()); + + g_bt_search.search_start = true; + g_bt_search.device_searched = false; + g_bt_search.inquiry_pending = false; + + if (BT_STS_PENDING != btif_me_inquiry(BTIF_BT_IAC_GIAC, max_search_time, 0)) + { + TRACE(1,"%s start inquiry failed\n", __func__); + g_bt_search.inquiry_pending = true; + } +} + +uint8_t app_bt_avrcp_get_notify_trans_id(void) +{ + return btif_a2dp_get_avrcpadvancedpdu_trans_id(app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1]); +} + +void app_bt_avrcp_set_notify_trans_id(uint8_t trans_id) +{ + TRACE(3,"%s %d %p\n", __func__, trans_id, app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1]); + btif_a2dp_set_avrcpadvancedpdu_trans_id(app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1], trans_id); +} + +uint8_t app_bt_avrcp_get_ctl_trans_id(void) +{ + return btif_avrcp_get_ctl_trans_id(app_bt_device.avrcp_channel[BT_DEVICE_ID_1]); +} + +void app_bt_avrcp_set_ctl_trans_id(uint8_t trans_id) +{ + TRACE(3,"%s %d %p\n", __func__, trans_id, app_bt_device.avrcp_channel[BT_DEVICE_ID_1]); + btif_avrcp_set_ctl_trans_id(app_bt_device.avrcp_channel[BT_DEVICE_ID_1], trans_id); +} + +void app_bt_set_mobile_a2dp_stream(uint32_t deviceId,a2dp_stream_t *stream) +{ + bt_profile_manager[deviceId].stream = stream; +} + +#if defined(IBRT) +#if defined(ENHANCED_STACK) +uint32_t app_bt_save_spp_app_ctx(uint32_t app_id,btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len) +{ + bt_bdaddr_t *remote = NULL; + uint32_t offset = 0; + struct spp_device *device = (struct spp_device *)btif_spp_get_device(app_id); + ASSERT(device, "%s NULL spp device app_id=0x%x",__func__, app_id); + + // save app_id + buf[offset++] = app_id & 0xFF; + buf[offset++] = (app_id >> 8) & 0xFF; + buf[offset++] = (app_id >> 16) & 0xFF; + buf[offset++] = (app_id >> 24) & 0xFF; + + // save port type + buf[offset++] = device->portType; + + //save remote address + remote = btif_me_get_remote_device_bdaddr(rem_dev); + memcpy(buf+offset, remote, sizeof(bt_bdaddr_t)); + offset += sizeof(bt_bdaddr_t); + + //TRACE(7,"%s:%02x:%02x:%02x:%02x:%02x:%02x\r\n", + // __func__, remote->addr[5], remote->addr[4], remote->addr[3], + // remote->addr[2], remote->addr[1], remote->addr[0]); + + //spp device + buf[offset++] = device->spp_connected_flag; + + return offset; +} + +uint32_t app_bt_restore_spp_app_ctx(uint8_t *buf, uint32_t buf_len, uint32_t app_id) +{ + bt_bdaddr_t remote; + uint32_t offset = 0; + struct spp_device *device = NULL; + uint8_t i = 0; + uint8_t port_type = 0; + uint32_t app_id_restore = 0; + + // restore app_id + for (i=0; i<4; i++) + { + app_id_restore += (buf[offset+i]<<(8*i)); + } + offset += 4; + + port_type = buf[offset++]; + + ASSERT(app_id_restore == app_id,"%s,spp app id mismatch=%x,%x",__func__,app_id_restore,app_id); + + // restore remote address + memcpy(&remote, buf+offset, sizeof(remote)); + offset += sizeof(remote); + + device = (struct spp_device *)btif_spp_get_device(app_id); + +#ifdef __INTERCONNECTION__ + TRACE(1,"%s,%x,%x,%x", __func__,app_id,BTIF_APP_SPP_CLIENT_CCMP_ID,BTIF_APP_SPP_CLIENT_RED_ID); +#endif + + if (device == NULL) + { + /* + * SPP client device may not be created in bt host initialized stage,so IBRT SLAVE will restore it + */ + if (port_type == BTIF_SPP_CLIENT_PORT) + { + TRACE(1,"%s,spp client device null", __func__); + switch (app_id) + { +#ifdef __INTERCONNECTION__ + case BTIF_APP_SPP_CLIENT_CCMP_ID: + app_ccmp_client_open((uint8_t *)SppServiceSearchReq, app_interconnection_get_length(), 0, 1); + device = (struct spp_device *)btif_spp_get_device(BTIF_APP_SPP_CLIENT_CCMP_ID); + device->spp_callback = ccmp_callback; + //device->_channel = chnl; //restore in btif_spp_profile_restore_ctx + device->sppUsedFlag = 1; + break; + + case BTIF_APP_SPP_CLIENT_RED_ID: + app_spp_client_open((uint8_t*)SppServiceSearchReq, app_interconnection_get_length(),1); + device = (struct spp_device *)btif_spp_get_device(BTIF_APP_SPP_CLIENT_RED_ID); + device->spp_callback = spp_client_callback; + //device->_channel = chnl; //restore in btif_spp_profile_restore_ctx + device->sppUsedFlag = 1; + break; +#endif + + default: + ASSERT(device, "%s NULL spp client device app_id=0x%x", __func__, app_id); + break; + } + } + else + { + ASSERT(device, "%s NULL spp server device app_id=0x%x", __func__, app_id); + } + } + +#ifdef __INTERCONNECTION__ + if (app_id == BTIF_APP_SPP_CLIENT_RED_ID) + { + //btm_conn will NULL if only SPP profile since btm_conn restore later + app_bt_set_spp_device_ptr((btif_remote_device_t *)btif_me_get_remote_device_by_bdaddr(&remote)); + } +#endif + + //restore spp device + device->portType = port_type; + device->spp_connected_flag = buf[offset++]; + + return offset; + +} + +uint32_t app_bt_save_hfp_app_ctx(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len) +{ + BTIF_CTX_INIT(buf); + + BTIF_CTX_STR_BUF(btif_me_get_remote_device_bdaddr(rem_dev), BTIF_BD_ADDR_SIZE); + + BTIF_CTX_STR_VAL8(app_bt_device.hfchan_call[BT_DEVICE_ID_1]); + BTIF_CTX_STR_VAL8(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1]); + BTIF_CTX_STR_VAL8(app_bt_device.hf_callheld[BT_DEVICE_ID_1]); + + BTIF_CTX_SAVE_UPDATE_DATA_LEN(); + return BTIF_CTX_GET_TOTAL_LEN(); +} + +uint32_t app_bt_restore_hfp_app_ctx(uint8_t *buf, uint32_t buf_len) +{ + bt_bdaddr_t remote; + uint8_t call, callsetup, callheld; + BTIF_CTX_INIT(buf); + + BTIF_CTX_LDR_BUF(&remote, BTIF_BD_ADDR_SIZE); + + BTIF_CTX_LDR_VAL8(call); + BTIF_CTX_LDR_VAL8(callsetup); + BTIF_CTX_LDR_VAL8(callheld); + + app_bt_device.hfchan_call[BT_DEVICE_ID_1] = call; + app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] = callsetup; + app_bt_device.hf_callheld[BT_DEVICE_ID_1] = callheld; + + TRACE(4,"%s call %d callsetup %d callheld %d", __func__, call, callsetup, callheld); + + return BTIF_CTX_GET_TOTAL_LEN(); +} +uint32_t app_bt_save_a2dp_app_ctx(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len) +{ + uint32_t offset = 0; + unsigned char stream_enc = 0; + uint32_t factor = 0; + + // TODO + // more codecs, BT_DEVICE_ID_2 + if (bt_profile_manager[BT_DEVICE_ID_1].stream == app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream) + { + stream_enc = 0; + } +#if defined(A2DP_AAC_ON) + else if (bt_profile_manager[BT_DEVICE_ID_1].stream == app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream) + { + stream_enc = 1; + } +#endif +#if defined(A2DP_LHDC_ON) + else if (bt_profile_manager[BT_DEVICE_ID_1].stream == app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_1]->a2dp_stream) + { + stream_enc = 2; + } +#endif +#if defined(A2DP_LDAC_ON) + else if (bt_profile_manager[BT_DEVICE_ID_1].stream == app_bt_device.a2dp_ldac_stream[BT_DEVICE_ID_1]->a2dp_stream) + { + stream_enc = 2; + } +#endif + + + buf[offset++] = stream_enc; + memcpy(buf+offset,btif_me_get_remote_device_bdaddr(rem_dev),BTIF_BD_ADDR_SIZE); + offset += BTIF_BD_ADDR_SIZE; + + buf[offset++] = app_bt_device.a2dp_state[BT_DEVICE_ID_1]; + buf[offset++] = app_bt_device.a2dp_play_pause_flag; + buf[offset++] = avrcp_get_media_status(); + + //codec + buf[offset++] = app_bt_device.codec_type[BT_DEVICE_ID_1]; + buf[offset++] = app_bt_device.sample_rate[BT_DEVICE_ID_1]; + buf[offset++] = app_bt_device.sample_bit[BT_DEVICE_ID_1]; +#if defined(A2DP_LHDC_ON) + buf[offset++] = app_bt_device.a2dp_lhdc_llc[BT_DEVICE_ID_1]; +#endif + +#if defined(__A2DP_AVDTP_CP__) + buf[offset++] = app_bt_device.avdtp_cp[BT_DEVICE_ID_1]; +#endif + + //volume + buf[offset++] = (uint8_t)a2dp_volume_get(BT_DEVICE_ID_1); + + //latency factor + factor = (uint32_t)a2dp_audio_latency_factor_get(); + buf[offset++] = factor & 0xFF; + buf[offset++] = (factor >> 8) & 0xFF; + buf[offset++] = (factor >> 16) & 0xFF; + buf[offset++] = (factor >> 24) & 0xFF; + + //a2dp session + buf[offset++] = a2dp_ibrt_session_get() & 0xFF; + buf[offset++] = (a2dp_ibrt_session_get() >> 8) & 0xFF; + buf[offset++] = (a2dp_ibrt_session_get() >> 16) & 0xFF; + buf[offset++] = (a2dp_ibrt_session_get() >> 24) & 0xFF; + + return offset; +} + +uint32_t app_bt_restore_a2dp_app_ctx(uint8_t *buf, uint32_t buf_len) +{ + uint32_t offset = 0; + bt_bdaddr_t remote; + unsigned char stream_enc = 0; + + stream_enc = buf[offset++]; + + memcpy(&remote,buf+offset,BTIF_BD_ADDR_SIZE); + offset += BTIF_BD_ADDR_SIZE; + + + app_bt_device.a2dp_state[BT_DEVICE_ID_1] = buf[offset++]; + app_bt_device.a2dp_play_pause_flag = buf[offset++]; + avrcp_set_media_status(buf[offset++]); + + //codec info + app_bt_device.codec_type[BT_DEVICE_ID_1] = buf[offset++]; + app_bt_device.sample_rate[BT_DEVICE_ID_1] = buf[offset++]; + app_bt_device.sample_bit[BT_DEVICE_ID_1] = buf[offset++]; +#if defined(A2DP_LHDC_ON) + app_bt_device.a2dp_lhdc_llc[BT_DEVICE_ID_1] = buf[offset++]; +#endif + +#if defined(__A2DP_AVDTP_CP__) + app_bt_device.avdtp_cp[BT_DEVICE_ID_1] = buf[offset++]; +#endif + + //volume + a2dp_volume_set(BT_DEVICE_ID_1, buf[offset++]); + + //latency factor + a2dp_audio_latency_factor_set((float)(buf[offset] + (buf[offset+1] << 8) + (buf[offset+2] << 16) + (buf[offset+3] << 24))); + offset += 4; + + //a2dp session + a2dp_ibrt_session_set((buf[offset] + (buf[offset+1] << 8) + (buf[offset+2] << 16) + (buf[offset+3] << 24))); + offset += 4; + + // TODO + // more codecs, BT_DEVICE_ID_2 + if (stream_enc == 0) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream; + } +#if defined(A2DP_AAC_ON) + else if (stream_enc == 1) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream; + } +#endif +#if defined(A2DP_LHDC_ON) + else if (stream_enc == 2) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_1]->a2dp_stream; + } +#endif +#if defined(A2DP_LDAC_ON) + else if (stream_enc == 2) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_ldac_stream[BT_DEVICE_ID_1]->a2dp_stream; + } +#endif + + memcpy(bt_profile_manager[BT_DEVICE_ID_1].rmt_addr.address, &remote, BTIF_BD_ADDR_SIZE); + bt_profile_manager[BT_DEVICE_ID_1].a2dp_connect = bt_profile_connect_status_success; + bt_profile_manager[BT_DEVICE_ID_1].hfp_connect = bt_profile_connect_status_success; + bt_profile_manager[BT_DEVICE_ID_1].has_connected = true; + + return offset; +} + +uint32_t app_bt_save_avrcp_app_ctx(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len) +{ + uint32_t offset = 0; + + buf[offset++] = app_bt_device.avrcp_state[BT_DEVICE_ID_1]; + buf[offset++] = app_bt_device.volume_report[BT_DEVICE_ID_1]; + + if (app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1]) + { + buf[offset++] = true; + buf[offset++] = app_bt_avrcp_get_notify_trans_id(); + } + else + { + buf[offset++] = false; + buf[offset++] = 0; + } + + return offset; +} + +uint32_t app_bt_restore_avrcp_app_ctx(uint8_t *buf, uint32_t buf_len) +{ + uint32_t offset = 0; + uint8_t notify_rsp_exist = 0; + uint8_t trans_id = 0; + + app_bt_device.avrcp_state[BT_DEVICE_ID_1] = buf[offset++]; + app_bt_device.volume_report[BT_DEVICE_ID_1] = buf[offset++]; + notify_rsp_exist = buf[offset++]; + trans_id = buf[offset++]; + + TRACE(4,"app_bt_restore_avrcp_app_ctx state %d report %d notify %d %d\n", + app_bt_device.avrcp_state[BT_DEVICE_ID_1], app_bt_device.volume_report[BT_DEVICE_ID_1], notify_rsp_exist, trans_id); + + if (notify_rsp_exist && app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1] == NULL) + { + btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(&app_bt_device.avrcp_notify_rsp[BT_DEVICE_ID_1]); + } + + app_bt_avrcp_set_notify_trans_id(trans_id); + + return offset; +} + +#ifdef __BTMAP_ENABLE__ +uint32_t app_bt_save_map_app_ctx(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len) +{ + //struct bdaddr_t *remote = NULL; + uint32_t offset = 0; + + memcpy((void *)buf, (void *)app_bt_device.map_session_handle, sizeof(app_bt_device.map_session_handle)); + offset += sizeof(app_bt_device.map_session_handle); + + return offset; +} + +uint32_t app_bt_restore_map_app_ctx(uint8_t *buf, uint32_t buf_len) +{ + uint32_t offset = 0; + + memcpy((void *)app_bt_device.map_session_handle, (void *)buf, sizeof(btif_map_session_handle_t)); + offset += sizeof(btif_map_session_handle_t); + + return offset; +} +#endif + +#if BTIF_HID_DEVICE +uint32_t app_bt_save_hid_app_ctx(uint8_t *buf) +{ + uint32_t offset = 0; + + if(app_bt_device.hid_channel == NULL) + { + TRACE(0, "app_bt_save_hid_app_ctx app_bt_device.hid_channel is NULL"); + return offset; + } + + memcpy((void *)buf, (void *)app_bt_device.hid_channel, sizeof(app_bt_device.hid_channel)); + offset += sizeof(app_bt_device.hid_channel); + + return offset; +} + +uint32_t app_bt_restore_hid_app_ctx(uint8_t *buf) +{ + uint32_t offset = 0; + + memcpy((void *)app_bt_device.hid_channel, (void *)buf, sizeof(hid_channel_t)); + offset += sizeof(hid_channel_t); + + return offset; +} +#endif +#endif /* ENHANCED_STACK */ + +a2dp_stream_t * app_bt_get_mobile_a2dp_stream(uint32_t deviceId) +{ + return bt_profile_manager[deviceId].stream; +} + +void app_bt_update_bt_profile_manager(void) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + memcpy(bt_profile_manager[BT_DEVICE_ID_1].rmt_addr.address, p_ibrt_ctrl->mobile_addr.address, BTIF_BD_ADDR_SIZE); + +#if defined(A2DP_AAC_ON) + if(p_ibrt_ctrl->a2dp_codec.codec_type == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream; + + } + else +#endif +#if defined(A2DP_SCALABLE_ON) + if (p_ibrt_ctrl->a2dp_codec.codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else +#endif +#if defined(A2DP_LHDC_ON) + if (p_ibrt_ctrl->a2dp_codec.codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else +#endif +#if defined(A2DP_LDAC_ON) + if (p_ibrt_ctrl->a2dp_codec.codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_ldac_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else +#endif + if (p_ibrt_ctrl->a2dp_codec.codec_type == BTIF_AVDTP_CODEC_TYPE_SBC) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else + { + ASSERT(0, "%s err codec_type:%d ", __func__, p_ibrt_ctrl->a2dp_codec.codec_type); + } + + bt_profile_manager[BT_DEVICE_ID_1].a2dp_connect = bt_profile_connect_status_success; + bt_profile_manager[BT_DEVICE_ID_1].hfp_connect = bt_profile_connect_status_success; + bt_profile_manager[BT_DEVICE_ID_1].has_connected = true; + + TRACE(3,"%s codec_type:%x if_a2dp_stream:%p", __func__, p_ibrt_ctrl->a2dp_codec.codec_type, bt_profile_manager[BT_DEVICE_ID_1].stream); + DUMP8("%02x ", bt_profile_manager[BT_DEVICE_ID_1].rmt_addr.address, BTIF_BD_ADDR_SIZE); +} + +void app_bt_update_bt_profile_manager_codec_type(uint8_t codec_type) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + p_ibrt_ctrl->a2dp_codec.codec_type = codec_type; + +#if defined(A2DP_AAC_ON) + if(p_ibrt_ctrl->a2dp_codec.codec_type == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream; + + } + else +#endif +#if defined(A2DP_SCALABLE_ON) + if (p_ibrt_ctrl->a2dp_codec.codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else +#endif +#if defined(A2DP_LHDC_ON) + if (p_ibrt_ctrl->a2dp_codec.codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else +#endif +#if defined(A2DP_LDAC_ON) + if (p_ibrt_ctrl->a2dp_codec.codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_ldac_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else +#endif + if (p_ibrt_ctrl->a2dp_codec.codec_type == BTIF_AVDTP_CODEC_TYPE_SBC) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else + { + ASSERT(0, "%s err codec_type:%d ", __func__, p_ibrt_ctrl->a2dp_codec.codec_type); + } + + bt_profile_manager[BT_DEVICE_ID_1].a2dp_connect = bt_profile_connect_status_success; + bt_profile_manager[BT_DEVICE_ID_1].hfp_connect = bt_profile_connect_status_success; + bt_profile_manager[BT_DEVICE_ID_1].has_connected = true; + + TRACE(3,"%s codec_type:%x if_a2dp_stream:%p", __func__, p_ibrt_ctrl->a2dp_codec.codec_type, bt_profile_manager[BT_DEVICE_ID_1].stream); +} + +static bool ibrt_reconnect_mobile_profile_flag = false; +void app_bt_ibrt_reconnect_mobile_profile_flag_set(void) +{ + ibrt_reconnect_mobile_profile_flag = true; +} + +void app_bt_ibrt_reconnect_mobile_profile_flag_clear(void) +{ + ibrt_reconnect_mobile_profile_flag = false; +} + +bool app_bt_ibrt_reconnect_mobile_profile_flag_get(void) +{ + return ibrt_reconnect_mobile_profile_flag; +} + +void app_bt_ibrt_reconnect_mobile_profile(bt_bdaddr_t mobile_addr) +{ + nvrec_btdevicerecord *mobile_record = NULL; + + bt_profile_manager[BT_DEVICE_ID_1].reconnect_mode = bt_profile_reconnect_null; + bt_profile_manager[BT_DEVICE_ID_1].rmt_addr = mobile_addr; + bt_profile_manager[BT_DEVICE_ID_1].chan = app_bt_device.hf_channel[BT_DEVICE_ID_1]; + + if (!nv_record_btdevicerecord_find(&mobile_addr, &mobile_record)) + { +#if defined(A2DP_AAC_ON) + if(mobile_record->device_plf.a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_aac_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else +#endif +#if defined(A2DP_SCALABLE_ON) + if(mobile_record->device_plf.a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_scalable_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else +#endif +#if defined(A2DP_LHDC_ON) + if(mobile_record->device_plf.a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_lhdc_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else +#endif +#if defined(A2DP_LDAC_ON) + if(mobile_record->device_plf.a2dp_codectype == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_ldac_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + else +#endif + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream; + } + } + else + { + bt_profile_manager[BT_DEVICE_ID_1].stream = app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream;//default using SBC + } + + btif_a2dp_reset_stream_state(bt_profile_manager[BT_DEVICE_ID_1].stream); + + TRACE(0,"ibrt_ui_log:start reconnect mobile, addr below:"); + DUMP8("0x%02x ",&(mobile_addr.address[0]),BTIF_BD_ADDR_SIZE); + app_bt_ibrt_reconnect_mobile_profile_flag_set(); + app_bt_precheck_before_starting_connecting(bt_profile_manager[BT_DEVICE_ID_1].has_connected); + + app_ibrt_ui_t *p_ibrt_ui = app_ibrt_ui_get_ctx(); + if (p_ibrt_ui->config.profile_concurrency_supported) + { + app_bt_A2DP_OpenStream(bt_profile_manager[BT_DEVICE_ID_1].stream, &(bt_profile_manager[BT_DEVICE_ID_1].rmt_addr)); + app_bt_HF_CreateServiceLink(bt_profile_manager[BT_DEVICE_ID_1].chan, &(bt_profile_manager[BT_DEVICE_ID_1].rmt_addr)); + } + else + { + app_bt_A2DP_OpenStream(bt_profile_manager[BT_DEVICE_ID_1].stream, &(bt_profile_manager[BT_DEVICE_ID_1].rmt_addr)); + //app_bt_HF_CreateServiceLink(bt_profile_manager[BT_DEVICE_ID_1].chan, &(bt_profile_manager[BT_DEVICE_ID_1].rmt_addr)); + } + //osTimerStart(bt_profile_manager[BT_DEVICE_ID_1].connect_timer, APP_IBRT_RECONNECT_TIMEOUT_MS); +} +#endif + +#ifdef __IAG_BLE_INCLUDE__ +static void app_start_fast_connectable_ble_adv(uint16_t advInterval) +{ + bool ret = FALSE; + + if (NULL == app_fast_ble_adv_timeout_timer) + { + app_fast_ble_adv_timeout_timer = + osTimerCreate(osTimer(APP_FAST_BLE_ADV_TIMEOUT_TIMER), + osTimerOnce, + NULL); + } + + osTimerStart(app_fast_ble_adv_timeout_timer, APP_FAST_BLE_ADV_TIMEOUT_IN_MS); + +#ifdef IBRT + ret = app_ibrt_ui_get_snoop_via_ble_enable(); +#endif + + if (FALSE == ret) + { + app_ble_start_connectable_adv(advInterval); + } +} + +static int app_fast_ble_adv_timeout_timehandler(void const *param) +{ + bool ret = FALSE; + +#ifdef IBRT + ret = app_ibrt_ui_get_snoop_via_ble_enable(); +#endif + + if (FALSE == ret) + { + app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL); + } + + return 0; +} + +void app_stop_fast_connectable_ble_adv_timer(void) +{ + if (NULL != app_fast_ble_adv_timeout_timer) + { + osTimerStop(app_fast_ble_adv_timeout_timer); + } +} +#endif + + +static uint32_t bt_link_active_mode_bits[MAX_ACTIVE_MODE_MANAGED_LINKS]; + +void app_bt_active_mode_manager_init(void) +{ + memset(bt_link_active_mode_bits, 0, sizeof(bt_link_active_mode_bits)); +} + +void app_bt_active_mode_reset(uint32_t linkIndex) +{ + bt_link_active_mode_bits[linkIndex] = 0; +} + +void app_bt_active_mode_set(BT_LINK_ACTIVE_MODE_KEEPER_USER_E user, uint32_t linkIndex) +{ +#if defined(IBRT) + return; +#endif + + bool isAlreadyInActiveMode = false; + if (linkIndex < MAX_ACTIVE_MODE_MANAGED_LINKS) + { + uint32_t lock = int_lock_global(); + if (bt_link_active_mode_bits[linkIndex] > 0) + { + isAlreadyInActiveMode = true; + } + else + { + isAlreadyInActiveMode = false; + } + bt_link_active_mode_bits[linkIndex] |= (1 << user); + int_unlock_global(lock); + + if (!isAlreadyInActiveMode) + { + app_bt_stop_sniff(linkIndex); + app_bt_stay_active(linkIndex); + } + + } + else if (MAX_ACTIVE_MODE_MANAGED_LINKS == linkIndex) + { + for (uint8_t devId = 0; devId < BT_DEVICE_NUM; devId++) + { + uint32_t lock = int_lock_global(); + if (bt_link_active_mode_bits[devId] > 0) + { + isAlreadyInActiveMode = true; + } + else + { + isAlreadyInActiveMode = false; + } + bt_link_active_mode_bits[devId] |= (1 << user); + int_unlock_global(lock); + + if (!isAlreadyInActiveMode) + { + app_bt_stop_sniff(devId); + app_bt_stay_active(devId); + } + } + } + + TRACE(2,"set active mode for user %d, link %d, now state:", user, linkIndex); + DUMP32("%08x", bt_link_active_mode_bits, MAX_ACTIVE_MODE_MANAGED_LINKS); +} + +void app_bt_active_mode_clear(BT_LINK_ACTIVE_MODE_KEEPER_USER_E user, uint32_t linkIndex) +{ +#if defined(IBRT) + return; +#endif + + bool isAlreadyAllowSniff = false; + if (linkIndex < MAX_ACTIVE_MODE_MANAGED_LINKS) + { + uint32_t lock = int_lock_global(); + + if (0 == bt_link_active_mode_bits[linkIndex]) + { + isAlreadyAllowSniff = true; + } + else + { + isAlreadyAllowSniff = false; + } + + bt_link_active_mode_bits[linkIndex] &= (~(1 << user)); + + int_unlock_global(lock); + + if (!isAlreadyAllowSniff) + { + app_bt_allow_sniff(linkIndex); + } + } + else if (MAX_ACTIVE_MODE_MANAGED_LINKS == linkIndex) + { + for (uint8_t devId = 0; devId < BT_DEVICE_NUM; devId++) + { + uint32_t lock = int_lock_global(); + if (0 == bt_link_active_mode_bits[devId]) + { + isAlreadyAllowSniff = true; + } + else + { + isAlreadyAllowSniff = false; + } + bt_link_active_mode_bits[devId] &= (~(1 << user)); + int_unlock_global(lock); + + if (!isAlreadyAllowSniff) + { + app_bt_allow_sniff(devId); + } + } + } + + TRACE(2,"clear active mode for user %d, link %d, now state:", user, linkIndex); + DUMP32("%08x ", bt_link_active_mode_bits, MAX_ACTIVE_MODE_MANAGED_LINKS); +} + +int8_t app_bt_get_rssi(void) +{ + int8_t rssi=127; + uint8_t i; + btif_remote_device_t *remDev = NULL; + rx_agc_t tws_agc = {0}; + + for (i=0; iconfig.disable_tws_switch = true;//disable role switch + + app_key_close(); + + if(IBRT_MASTER == app_tws_ibrt_role_get_callback(NULL)){ + btif_hf_disconnect_service_link(app_bt_device.hf_channel[BT_DEVICE_ID_1]); + btif_a2dp_suspend_stream(app_bt_device.a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream); + } + TRACE(0,"app_bt_prepare_for_ota"); +} +#endif diff --git a/services/bt_app/app_bt.h b/services/bt_app/app_bt.h new file mode 100644 index 0000000..8dfb7bf --- /dev/null +++ b/services/bt_app/app_bt.h @@ -0,0 +1,254 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BT_H__ +#define __APP_BT_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "me_api.h" +#include "a2dp_api.h" +#include "hfp_api.h" + +enum APP_BT_REQ_T { + APP_BT_REQ_ACCESS_MODE_SET, + APP_BT_REQ_AUTO_TEST, + APP_BT_REQ_NUM +}; + +enum APP_BT_GOLBAL_HANDLE_HOOK_USER_T { + APP_BT_GOLBAL_HANDLE_HOOK_USER_0 = 0, + APP_BT_GOLBAL_HANDLE_HOOK_USER_1, + APP_BT_GOLBAL_HANDLE_HOOK_USER_QTY +}; + +typedef void (*APP_BT_REQ_CONNECT_PROFILE_FN_T)(void *, void *); +typedef bt_status_t (*APP_BT_REQ_HF_OP_FN_T)(void *); +typedef void (*APP_BT_GOLBAL_HANDLE_HOOK_HANDLER)(const btif_event_t*Event); +typedef void (*APP_APPTHREAD_REQ_CUSTOMER_CALL_FN_T)(void *, void *); + +#define app_bt_accessmode_set_req(accmode) do{app_bt_send_request(APP_BT_REQ_ACCESS_MODE_SET, accmode, 0, 0);}while(0) +typedef enum +{ + APP_BT_IDLE_STATE = 0, + APP_BT_IN_CONNECTING_PROFILES_STATE // acl link is created and in the process of connecting profiles +} APP_BT_CONNECTING_STATE_E; + +typedef enum +{ + // always in active mode during a2dp streaming + ACTIVE_MODE_KEEPER_A2DP_STREAMING = 0, + // always in active mode during ai voice up-streaming + ACTIVE_MODE_KEEPER_AI_VOICE_STREAM, + // always in active mode during OTA + ACTIVE_MODE_KEEPER_OTA, + // stay in active mode for 15 seconds after role switch + ACTIVE_MODE_KEEPER_ROLE_SWITCH, + // stay in active mode during synchronous voice prompt playing + ACTIVE_MODE_KEEPER_SYNC_VOICE_PROMPT, + // always in active mode during phone call + ACTIVE_MODE_KEEPEER_SCO_STREAMING, + + +} BT_LINK_ACTIVE_MODE_KEEPER_USER_E; + +#define MAX_ACTIVE_MODE_MANAGED_LINKS 3 +#define UPDATE_ACTIVE_MODE_FOR_ALL_LINKS MAX_ACTIVE_MODE_MANAGED_LINKS + +void app_bt_active_mode_manager_init(void); + +void app_bt_active_mode_reset(uint32_t linkIndex); + +void app_bt_active_mode_set(BT_LINK_ACTIVE_MODE_KEEPER_USER_E user, uint32_t linkIndex); + +void app_bt_active_mode_clear(BT_LINK_ACTIVE_MODE_KEEPER_USER_E user, uint32_t linkIndex); + +void app_bt_global_handle(const btif_event_t *Event); +bool is_app_bt_pairing_running(void); + +void PairingTransferToConnectable(void); + +void app_bt_global_handle_init(void); + +void app_bt_opening_reconnect(void); + +void app_bt_accessmode_set( btif_accessible_mode_t mode); + +void app_bt_send_request(uint32_t message_id, uint32_t param0, uint32_t param1, uint32_t ptr); + +void app_bt_init(void); + +int app_bt_state_checker(void); + +void *app_bt_profile_active_store_ptr_get(uint8_t *bdAddr); + +void app_bt_profile_connect_manager_open(void); + +void app_bt_profile_connect_manager_opening_reconnect(void); + +BOOL app_bt_profile_connect_openreconnecting(void *ptr); + +int app_bt_global_handle_hook_set(enum APP_BT_GOLBAL_HANDLE_HOOK_USER_T user, APP_BT_GOLBAL_HANDLE_HOOK_HANDLER handler); + +APP_BT_GOLBAL_HANDLE_HOOK_HANDLER app_bt_global_handle_hook_get(enum APP_BT_GOLBAL_HANDLE_HOOK_USER_T user); + +bool app_is_hfp_service_connected(void); +#if defined(IBRT) +void app_bt_ibrt_reconnect_mobile_profile_flag_set(void); +void app_bt_ibrt_reconnect_mobile_profile_flag_clear(void); +bool app_bt_ibrt_reconnect_mobile_profile_flag_get(void); +#endif +#if defined(__BT_SELECT_PROF_DEVICE_ID__) +int8_t app_bt_a2dp_is_same_stream(a2dp_stream_t *src_Stream, a2dp_stream_t *dst_Stream); + +void app_bt_a2dp_find_same_unused_stream(a2dp_stream_t *in_Stream, a2dp_stream_t **out_Stream, uint32_t device_id); + +int8_t app_bt_a2dp_is_stream_on_device_id(a2dp_stream_t *in_Stream, uint32_t device_id); + +int8_t app_bt_hfp_is_chan_on_device_id(hf_chan_handle_t chan, uint32_t device_id); + +int8_t app_bt_is_any_profile_connected(uint32_t device_id); + +int8_t app_bt_is_a2dp_connected(uint32_t device_id); + +btif_remote_device_t *app_bt_get_connected_profile_remdev(uint32_t device_id); +#endif + +void app_bt_stay_active(uint8_t deviceId); + +void app_bt_allow_sniff(uint8_t deviceId); + +btif_remote_device_t* app_bt_get_remoteDev(uint8_t deviceId); + +void app_bt_stop_sniff(uint8_t deviceId); + +void app_bt_sniff_config(btif_remote_device_t *remDev); + +void app_bt_allow_sniff_rem_dev(btif_remote_device_t* pRemDev); + +void app_bt_stay_active_rem_dev(btif_remote_device_t* pRemDev); + +void app_check_pending_stop_sniff_op(void); + +void app_bt_reset_reconnect_timer(bt_bdaddr_t *pBdAddr); + +uint8_t app_bt_get_num_of_connected_dev(void); + +bool btapp_hfp_is_dev_call_active(uint8_t devId); + +void app_bt_pause_media_player_again(uint8_t deviceId); + +bool app_bt_is_music_player_working(uint8_t deviceId); + +bool app_bt_pause_music_player(uint8_t deviceId); + +void app_bt_resume_music_player(uint8_t deviceId); + +bool app_bt_is_to_resume_music_player(uint8_t deviceId); + +void app_bt_reset_music_player_resume_state(void); + +bool app_bt_is_device_connected(uint8_t deviceId); + +void app_bt_set_music_player_resume_device(uint8_t deviceId); + +bool app_bt_is_a2dp_streaming(uint8_t deviceId); + +void app_bt_suspend_a2dp_streaming(uint8_t deviceId); + +bool app_bt_get_device_bdaddr(uint8_t deviceId, uint8_t* btAddr); + +void fast_pair_enter_pairing_mode_handler(void); + +void app_hfp_start_voice_media(uint8_t devId); + +void app_hfp_resume_pending_voice_media(void); + +bool app_hfp_is_starting_media_pending(void); + +bool app_bt_is_in_reconnecting(void); + +bool btapp_hfp_is_dev_sco_connected(uint8_t devId); + +uint8_t a2dp_get_latest_paused_device(void); + +bool app_bt_is_in_connecting_profiles_state(void); + +void app_bt_clear_connecting_profiles_state(uint8_t devId); + +void app_bt_set_connecting_profiles_state(uint8_t devId); + +void app_a2dp_hold_mute(); + +void app_a2dp_unhold_mute(); + +void app_bt_set_mobile_a2dp_stream(uint32_t deviceId,a2dp_stream_t *stream); + +#if defined(__INTERCONNECTION__) +btif_accessible_mode_t app_bt_get_current_access_mode(void); + +bool app_bt_is_connected(); +#endif +bool app_device_bt_is_connected(); +bool app_bt_is_hfp_audio_on(void); + +btif_remote_device_t* app_bt_get_connected_mobile_device_ptr(void); +void app_bt_set_spp_device_ptr(btif_remote_device_t* device); +btif_remote_device_t* app_bt_get_spp_device_ptr(void); + +bool app_is_disconnecting_all_bt_connections(void); + +void app_set_disconnecting_all_bt_connections(bool isEnable); + +void app_bt_start_search(void); + +#if defined(IBRT) +#if defined(ENHANCED_STACK) +uint32_t app_bt_save_a2dp_app_ctx(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len); +uint32_t app_bt_restore_a2dp_app_ctx(uint8_t *buf, uint32_t buf_len); +uint32_t app_bt_save_avrcp_app_ctx(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len); +uint32_t app_bt_restore_avrcp_app_ctx(uint8_t *buf, uint32_t buf_len); +uint32_t app_bt_save_hfp_app_ctx(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len); +uint32_t app_bt_restore_hfp_app_ctx(uint8_t *buf, uint32_t buf_len); +uint32_t app_bt_save_spp_app_ctx(uint32_t app_id,btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len); +uint32_t app_bt_restore_spp_app_ctx(uint8_t *buf, uint32_t buf_len, uint32_t app_id); +#ifdef __BTMAP_ENABLE__ +uint32_t app_bt_save_map_app_ctx(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len); +uint32_t app_bt_restore_map_app_ctx(uint8_t *buf, uint32_t buf_len); +#endif +#ifdef BTIF_HID_DEVICE +uint32_t app_bt_save_hid_app_ctx(uint8_t *buf); +uint32_t app_bt_restore_hid_app_ctx(uint8_t *buf); +#endif +#endif /* ENHANCED_STACK */ +#endif + +void app_stop_fast_connectable_ble_adv_timer(void); +int8_t app_bt_get_rssi(void); + +#ifdef TILE_DATAPATH +int8_t app_tile_get_ble_rssi(void); +#endif +void app_bt_prepare_for_ota(void); +void hfp_reconnecting_timer_stop_callback(const btif_event_t *event); +int app_bt_start_custom_function_in_app_thread( + uint32_t param0, uint32_t param1, uint32_t funcPtr); +uint8_t app_bt_get_a2dp_state(); + +#ifdef __cplusplus +} +#endif +#endif /* BESBT_H */ diff --git a/services/bt_app/app_bt_func.cpp b/services/bt_app/app_bt_func.cpp new file mode 100644 index 0000000..c0f82b7 --- /dev/null +++ b/services/bt_app/app_bt_func.cpp @@ -0,0 +1,913 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "string.h" +#include "hal_trace.h" + +#include "bluetooth.h" +#include "besbt.h" +#include "app_bt_func.h" +#include "hfp_api.h" +#include "app_bt.h" +#include "os_api.h" +#include "app_ble_mode_switch.h" + +extern "C" void OS_NotifyEvm(void); +static const char * const app_bt_func_table_str[] = +{ + "Me_switch_sco", + "ME_SwitchRole", + "ME_SetConnectionRole", + "MeDisconnectLink", + "ME_StopSniff", + "ME_SetAccessibleMode", + "Me_SetLinkPolicy", + "CMGR_SetSniffTimer", + "CMGR_SetSniffInofToAllHandlerByRemDev", + "A2DP_OpenStream", + "A2DP_CloseStream", + "A2DP_SetMasterRole", + "HF_CreateServiceLink", + "HF_DisconnectServiceLink", + "HF_CreateAudioLink", + "HF_DisconnectAudioLink", + "HF_EnableSniffMode", + "HF_SetMasterRole", + "HS_CreateServiceLink", + "HS_CreateAudioLink", + "HS_DisconnectAudioLink", + "HS_EnableSniffMode", + "HS_DisconnectServiceLink", + "BT_Control_SleepMode", + "BT_Custom_Func", + "ME_StartSniff", + "DIP_QuryService", + "A2DP_Force_OpenStream", + "HF_Force_CreateServiceLink", + "app_set_access_mode_test", + "app_set_adv_mode_test", + "FPGA_write_mem_test", + "FPGA_read_mem_test", +}; + +#define APP_BT_MAILBOX_MAX (40) +osMailQDef (app_bt_mailbox, APP_BT_MAILBOX_MAX, APP_BT_MAIL); +static osMailQId app_bt_mailbox = NULL; + +static btif_accessible_mode_t gBT_DEFAULT_ACCESS_MODE = BTIF_BAM_NOT_ACCESSIBLE; +static uint8_t bt_access_mode_set_pending = 0; +void app_set_accessmode(btif_accessible_mode_t mode) +{ +#if !defined(IBRT) + const btif_access_mode_info_t info = { BTIF_BT_DEFAULT_INQ_SCAN_INTERVAL, + BTIF_BT_DEFAULT_INQ_SCAN_WINDOW, + BTIF_BT_DEFAULT_PAGE_SCAN_INTERVAL, + BTIF_BT_DEFAULT_PAGE_SCAN_WINDOW }; + bt_status_t status; + osapi_lock_stack(); + gBT_DEFAULT_ACCESS_MODE = mode; + + status = btif_me_set_accessible_mode(mode, &info); + TRACE(1,"app_set_accessmode status=0x%x",status); + + if(status == BT_STS_IN_PROGRESS) + bt_access_mode_set_pending = 1; + else + bt_access_mode_set_pending = 0; + osapi_unlock_stack(); +#endif +} + +bool app_is_access_mode_set_pending(void) +{ + return bt_access_mode_set_pending; +} + +extern "C" void app_bt_accessmode_set(btif_accessible_mode_t mode); +void app_set_pending_access_mode(void) +{ + if (bt_access_mode_set_pending) + { + TRACE(1,"Pending for change access mode to %d", gBT_DEFAULT_ACCESS_MODE); + bt_access_mode_set_pending = 0; + app_bt_accessmode_set(gBT_DEFAULT_ACCESS_MODE); + } +} + +void app_retry_setting_access_mode(void) +{ + TRACE(0,"Former setting access mode failed, retry it."); + app_bt_accessmode_set(gBT_DEFAULT_ACCESS_MODE); +} + +#define PENDING_SET_LINKPOLICY_REQ_BUF_CNT 5 +static BT_SET_LINKPOLICY_REQ_T pending_set_linkpolicy_req[PENDING_SET_LINKPOLICY_REQ_BUF_CNT]; + +static uint8_t pending_set_linkpolicy_in_cursor = 0; +static uint8_t pending_set_linkpolicy_out_cursor = 0; + +static void app_bt_print_pending_set_linkpolicy_req(void) +{ + TRACE(0,"Pending set link policy requests:"); + uint8_t index = pending_set_linkpolicy_out_cursor; + while (index != pending_set_linkpolicy_in_cursor) + { + TRACE(3,"index %d RemDev %p LinkPolicy %d", index, + pending_set_linkpolicy_req[index].remDev, + pending_set_linkpolicy_req[index].policy); + index++; + if (PENDING_SET_LINKPOLICY_REQ_BUF_CNT == index) + { + index = 0; + } + } +} + +static void app_bt_push_pending_set_linkpolicy(btif_remote_device_t *remDev, btif_link_policy_t policy) +{ + // go through the existing pending list to see if the remDev is already in + uint8_t index = pending_set_linkpolicy_out_cursor; + while (index != pending_set_linkpolicy_in_cursor) + { + if (remDev == pending_set_linkpolicy_req[index].remDev) + { + pending_set_linkpolicy_req[index].policy = policy; + return; + } + index++; + if (PENDING_SET_LINKPOLICY_REQ_BUF_CNT == index) + { + index = 0; + } + } + + pending_set_linkpolicy_req[pending_set_linkpolicy_in_cursor].remDev = remDev; + pending_set_linkpolicy_req[pending_set_linkpolicy_in_cursor].policy = policy; + pending_set_linkpolicy_in_cursor++; + if (PENDING_SET_LINKPOLICY_REQ_BUF_CNT == pending_set_linkpolicy_in_cursor) + { + pending_set_linkpolicy_in_cursor = 0; + } + + app_bt_print_pending_set_linkpolicy_req(); +} + +BT_SET_LINKPOLICY_REQ_T* app_bt_pop_pending_set_linkpolicy(void) +{ + if (pending_set_linkpolicy_out_cursor == pending_set_linkpolicy_in_cursor) + { + return NULL; + } + + BT_SET_LINKPOLICY_REQ_T* ptReq = &pending_set_linkpolicy_req[pending_set_linkpolicy_out_cursor]; + pending_set_linkpolicy_out_cursor++; + if (PENDING_SET_LINKPOLICY_REQ_BUF_CNT == pending_set_linkpolicy_out_cursor) + { + pending_set_linkpolicy_out_cursor = 0; + } + + app_bt_print_pending_set_linkpolicy_req(); + return ptReq; +} + +void app_bt_set_linkpolicy(btif_remote_device_t *remDev, btif_link_policy_t policy) +{ + if (btif_me_get_remote_device_state(remDev) == BTIF_BDS_CONNECTED) + { + bt_status_t ret = btif_me_set_link_policy(remDev, policy); + TRACE(3,"%s policy %d returns %d", __FUNCTION__, policy, ret); + + osapi_lock_stack(); + if (BT_STS_IN_PROGRESS == ret) + { + app_bt_push_pending_set_linkpolicy(remDev, policy); + } + osapi_unlock_stack(); + } +} + +#define COUNT_OF_PENDING_REMOTE_DEV_TO_EXIT_SNIFF_MODE 8 +static btif_remote_device_t* pendingRemoteDevToExitSniffMode[COUNT_OF_PENDING_REMOTE_DEV_TO_EXIT_SNIFF_MODE]; +static uint8_t maskOfRemoteDevPendingForExitingSniffMode = 0; +void app_check_pending_stop_sniff_op(void) +{ + if (maskOfRemoteDevPendingForExitingSniffMode > 0) + { + for (uint8_t index = 0;index < COUNT_OF_PENDING_REMOTE_DEV_TO_EXIT_SNIFF_MODE;index++) + { + if (maskOfRemoteDevPendingForExitingSniffMode & (1 << index)) + { + btif_remote_device_t* remDev = pendingRemoteDevToExitSniffMode[index]; + if (!btif_me_is_op_in_progress(remDev)) + { + if (btif_me_get_remote_device_state(remDev) == BTIF_BDS_CONNECTED){ + if (btif_me_get_current_mode(remDev) == BTIF_BLM_SNIFF_MODE){ + TRACE(1,"!!! stop sniff currmode:%d\n", btif_me_get_current_mode(remDev)); + bt_status_t ret = btif_me_stop_sniff(remDev); + TRACE(1,"Return status %d", ret); + if (BT_STS_IN_PROGRESS != ret) + { + maskOfRemoteDevPendingForExitingSniffMode &= (~(1< 0) + { + osapi_notify_evm(); + } + } +} + +static void app_add_pending_stop_sniff_op(btif_remote_device_t* remDev) +{ + for (uint8_t index = 0;index < COUNT_OF_PENDING_REMOTE_DEV_TO_EXIT_SNIFF_MODE;index++) + { + if (maskOfRemoteDevPendingForExitingSniffMode & (1 << index)) + { + if (pendingRemoteDevToExitSniffMode[index] == remDev) + { + return; + } + } + } + + for (uint8_t index = 0;index < COUNT_OF_PENDING_REMOTE_DEV_TO_EXIT_SNIFF_MODE;index++) + { + if (0 == (maskOfRemoteDevPendingForExitingSniffMode & (1 << index))) + { + pendingRemoteDevToExitSniffMode[index] = remDev; + maskOfRemoteDevPendingForExitingSniffMode |= (1 << index); + } + } +} + +#ifdef FPGA +extern "C" bt_status_t app_tws_ibrt_set_access_mode(btif_accessible_mode_t mode); +void app_start_ble_adv_for_test(void); +#endif + +static inline int app_bt_mail_process(APP_BT_MAIL* mail_p) +{ + bt_status_t status = BT_STS_LAST_CODE; + if (mail_p->request_id != CMGR_SetSniffTimer_req){ + TRACE(3,"[BT_FUNC] src_thread:0x%08x call request_id=%x->:%s", mail_p->src_thread, mail_p->request_id,app_bt_func_table_str[mail_p->request_id]); + } + switch (mail_p->request_id) { + case Me_switch_sco_req: + status = btif_me_switch_sco(mail_p->param.Me_switch_sco_param.scohandle); + break; + case ME_SwitchRole_req: + status = btif_me_switch_role(mail_p->param.ME_SwitchRole_param.remDev); + break; + case ME_SetConnectionRole_req: + status = btif_me_set_connection_role(mail_p->param.BtConnectionRole_param.role); + break; + case MeDisconnectLink_req: + status = btif_me_force_disconnect_link_with_reason(NULL, mail_p->param.MeDisconnectLink_param.remDev, BTIF_BEC_USER_TERMINATED, TRUE); + break; + case ME_StopSniff_req: + { + if (btif_me_get_remote_device_state(mail_p->param.ME_StopSniff_param.remDev) == BTIF_BDS_CONNECTED) + { + status = btif_me_stop_sniff(mail_p->param.ME_StopSniff_param.remDev); + if (BT_STS_IN_PROGRESS == status) + { + app_add_pending_stop_sniff_op(mail_p->param.ME_StopSniff_param.remDev); + } + } + break; + } + case ME_StartSniff_req: + { + if (btif_me_get_remote_device_state(mail_p->param.ME_StartSniff_param.remDev) == BTIF_BDS_CONNECTED) + { + status = btif_me_start_sniff (mail_p->param.ME_StartSniff_param.remDev, + &(mail_p->param.ME_StartSniff_param.sniffInfo)); + } + break; + } + case BT_Control_SleepMode_req: + { + btif_me_write_bt_sleep_enable(mail_p->param.ME_BtControlSleepMode_param.isEnable); + break; + } + case ME_SetAccessibleMode_req: + app_set_accessmode(mail_p->param.ME_SetAccessibleMode_param.mode); + break; + case Me_SetLinkPolicy_req: + app_bt_set_linkpolicy(mail_p->param.Me_SetLinkPolicy_param.remDev, + mail_p->param.Me_SetLinkPolicy_param.policy); + break; + case CMGR_SetSniffTimer_req: + if (mail_p->param.CMGR_SetSniffTimer_param.SniffInfo.maxInterval == 0){ + status = btif_cmgr_set_sniff_timer(mail_p->param.CMGR_SetSniffTimer_param.Handler, + NULL, + mail_p->param.CMGR_SetSniffTimer_param.Time); + }else{ + status = btif_cmgr_set_sniff_timer(mail_p->param.CMGR_SetSniffTimer_param.Handler, + &mail_p->param.CMGR_SetSniffTimer_param.SniffInfo, + mail_p->param.CMGR_SetSniffTimer_param.Time); + } + break; + case CMGR_SetSniffInofToAllHandlerByRemDev_req: + status = btif_cmgr_set_sniff_info_to_all_handler_by_remdev(&mail_p->param.CMGR_SetSniffInofToAllHandlerByRemDev_param.SniffInfo, + mail_p->param.CMGR_SetSniffInofToAllHandlerByRemDev_param.RemDev); + break; + case A2DP_OpenStream_req: + status = btif_a2dp_open_stream(mail_p->param.A2DP_OpenStream_param.Stream, + mail_p->param.A2DP_OpenStream_param.Addr); + if ((BT_STS_NO_RESOURCES == status) || (BT_STS_IN_PROGRESS == status)) + { + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + app_bt_reset_reconnect_timer(mail_p->param.A2DP_OpenStream_param.Addr); + } + else + { + app_bt_accessmode_set(BTIF_BAM_NOT_ACCESSIBLE); + } + break; + case A2DP_CloseStream_req: + status = btif_a2dp_close_stream(mail_p->param.A2DP_CloseStream_param.Stream); + break; + case A2DP_SetMasterRole_req: + status = btif_a2dp_set_master_role(mail_p->param.A2DP_SetMasterRole_param.Stream, + mail_p->param.A2DP_SetMasterRole_param.Flag); + break; + case HF_CreateServiceLink_req: + status = btif_hf_create_service_link(mail_p->param.HF_CreateServiceLink_param.Chan, + mail_p->param.HF_CreateServiceLink_param.Addr); + if ((BT_STS_NO_RESOURCES == status) || (BT_STS_IN_PROGRESS == status)) + { + app_bt_accessmode_set(BTIF_BAM_CONNECTABLE_ONLY); + app_bt_reset_reconnect_timer(mail_p->param.HF_CreateServiceLink_param.Addr); + } + else + { + app_bt_accessmode_set(BTIF_BAM_NOT_ACCESSIBLE); + } + break; + case HF_DisconnectServiceLink_req: + status = btif_hf_disconnect_service_link(mail_p->param.HF_DisconnectServiceLink_param.Chan); + break; + case HF_CreateAudioLink_req: + status = btif_hf_create_audio_link(mail_p->param.HF_CreateAudioLink_param.Chan); + break; + case HF_DisconnectAudioLink_req: + status = btif_hf_disc_audio_link(mail_p->param.HF_DisconnectAudioLink_param.Chan); + break; + case HF_EnableSniffMode_req: + status = btif_hf_enable_sniff_mode(mail_p->param.HF_EnableSniffMode_param.Chan, + mail_p->param.HF_EnableSniffMode_param.Enable); + break; + case HF_SetMasterRole_req: + status = btif_hf_set_master_role(mail_p->param.HF_SetMasterRole_param.Chan, + mail_p->param.HF_SetMasterRole_param.Flag); + break; +#ifdef BTIF_DIP_DEVICE + case DIP_QuryService_req: + status = btif_dip_query_for_service(mail_p->param.DIP_QuryService_param.dip_client, + mail_p->param.DIP_QuryService_param.remDev); + break; +#endif +#if defined (__HSP_ENABLE__) + case HS_CreateServiceLink_req: + app_bt_accessmode_set(BTIF_BAM_NOT_ACCESSIBLE); + status = HS_CreateServiceLink(mail_p->param.HS_CreateServiceLink_param.Chan, + mail_p->param.HS_CreateServiceLink_param.Addr); + break; + case HS_CreateAudioLink_req: + status = HS_CreateAudioLink(mail_p->param.HS_CreateAudioLink_param.Chan); + break; + case HS_DisconnectAudioLink_req: + status = HS_DisconnectAudioLink(mail_p->param.HS_DisconnectAudioLink_param.Chan); + break; + case HS_DisconnectServiceLink_req: + status = HS_DisconnectServiceLink(mail_p->param.HS_DisconnectServiceLink_param.Chan); + break; + case HS_EnableSniffMode_req: + status = HS_EnableSniffMode(mail_p->param.HS_EnableSniffMode_param.Chan, + mail_p->param.HS_EnableSniffMode_param.Enable); + break; +#endif +#ifdef FPGA + case BT_Set_Access_Mode_Test: +#if defined(IBRT) + app_tws_ibrt_set_access_mode(mail_p->param.ME_SetAccessibleMode_param.mode); +#else + app_set_accessmode(mail_p->param.ME_SetAccessibleMode_param.mode); +#endif + break; + case BT_Set_Adv_Mode_Test: +#if defined(IBRT) + app_start_ble_adv_for_test(); +#endif + break; + case Write_Controller_Memory_Test: + { + status = btif_me_write_controller_memory(mail_p->param.Me_writecontrollermem_param.addr, + mail_p->param.Me_writecontrollermem_param.memval, + mail_p->param.Me_writecontrollermem_param.type); + break; + } + case Read_Controller_Memory_Test: + { + status = btif_me_read_controller_memory(mail_p->param.Me_readcontrollermem_param.addr, + mail_p->param.Me_readcontrollermem_param.len, + mail_p->param.Me_readcontrollermem_param.type); + break; + } +#endif + case BT_Custom_Func_req: + if (mail_p->param.CustomFunc_param.func_ptr){ + TRACE(3,"func:0x%08x,param0:0x%08x, param1:0x%08x", + mail_p->param.CustomFunc_param.func_ptr, + mail_p->param.CustomFunc_param.param0, + mail_p->param.CustomFunc_param.param1); + ((APP_BTTHREAD_REQ_CUSTOMER_CALL_CB_T)(mail_p->param.CustomFunc_param.func_ptr))( + (void *)mail_p->param.CustomFunc_param.param0, + (void *)mail_p->param.CustomFunc_param.param1); + } + break; + } + + if (mail_p->request_id != CMGR_SetSniffTimer_req){ + TRACE(2,"[BT_FUNC] exit request_id:%d :status:%d", mail_p->request_id, status); + } + return 0; +} + +static inline int app_bt_mail_alloc(APP_BT_MAIL** mail) +{ + *mail = (APP_BT_MAIL*)osMailAlloc(app_bt_mailbox, 0); + ASSERT(*mail, "app_bt_mail_alloc error"); + return 0; +} + +static inline int app_bt_mail_send(APP_BT_MAIL* mail) +{ + osStatus status; + + ASSERT(mail, "osMailAlloc NULL"); + status = osMailPut(app_bt_mailbox, mail); + ASSERT(osOK == status, "osMailAlloc Put failed"); + + OS_NotifyEvm(); + + return (int)status; +} + +static inline int app_bt_mail_free(APP_BT_MAIL* mail_p) +{ + osStatus status; + + status = osMailFree(app_bt_mailbox, mail_p); + ASSERT(osOK == status, "osMailAlloc Put failed"); + + return (int)status; +} + +static inline int app_bt_mail_get(APP_BT_MAIL** mail_p) +{ + osEvent evt; + evt = osMailGet(app_bt_mailbox, 0); + if (evt.status == osEventMail) { + *mail_p = (APP_BT_MAIL *)evt.value.p; + return 0; + } + return -1; +} + +static void app_bt_mail_poll(void) +{ + APP_BT_MAIL *mail_p = NULL; + if (!app_bt_mail_get(&mail_p)){ + app_bt_mail_process(mail_p); + app_bt_mail_free(mail_p); + osapi_notify_evm(); + } +} + +int app_bt_mail_init(void) +{ + app_bt_mailbox = osMailCreate(osMailQ(app_bt_mailbox), NULL); + if (app_bt_mailbox == NULL) { + TRACE(0,"Failed to Create app_mailbox\n"); + return -1; + } + Besbt_hook_handler_set(BESBT_HOOK_USER_1, app_bt_mail_poll); + + return 0; +} + +int app_bt_Me_switch_sco(uint16_t scohandle) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = Me_switch_sco_req; + mail->param.Me_switch_sco_param.scohandle = scohandle; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_ME_SwitchRole(btif_remote_device_t* remDev) +{ +#if !defined(IBRT) + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = ME_SwitchRole_req; + mail->param.ME_SwitchRole_param.remDev = remDev; + app_bt_mail_send(mail); +#endif + return 0; +} + +int app_bt_ME_SetConnectionRole(btif_connection_role_t role) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = ME_SetConnectionRole_req; + mail->param.BtConnectionRole_param.role = role; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_MeDisconnectLink(btif_remote_device_t* remDev) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = MeDisconnectLink_req; + mail->param.MeDisconnectLink_param.remDev = remDev; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_ME_StopSniff(btif_remote_device_t *remDev) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = ME_StopSniff_req; + mail->param.ME_StopSniff_param.remDev = remDev; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_ME_StartSniff(btif_remote_device_t *remDev, btif_sniff_info_t* sniffInfo) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = ME_StartSniff_req; + mail->param.ME_StartSniff_param.remDev = remDev; + mail->param.ME_StartSniff_param.sniffInfo = *sniffInfo; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_ME_ControlSleepMode(bool isEnabled) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = BT_Control_SleepMode_req; + mail->param.ME_BtControlSleepMode_param.isEnable = isEnabled; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_ME_SetAccessibleMode(btif_accessible_mode_t mode, const btif_access_mode_info_t *info) +{ +#if defined(BLE_ONLY_ENABLED) + return 0; +#endif + + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = ME_SetAccessibleMode_req; + mail->param.ME_SetAccessibleMode_param.mode = mode; + memcpy(&mail->param.ME_SetAccessibleMode_param.info, info, sizeof(btif_access_mode_info_t)); + app_bt_mail_send(mail); + return 0; +} + +#ifdef FPGA +int app_bt_ME_SetAccessibleMode_Fortest(btif_accessible_mode_t mode, const btif_access_mode_info_t *info) +{ +#if defined(BLE_ONLY_ENABLED) + return 0; +#endif + + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = BT_Set_Access_Mode_Test; + mail->param.ME_SetAccessibleMode_param.mode = mode; + memcpy(&mail->param.ME_SetAccessibleMode_param.info, info, sizeof(btif_access_mode_info_t)); + app_bt_mail_send(mail); + return 0; +} + +int app_bt_ME_Set_Advmode_Fortest(uint8_t en) +{ + + + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = BT_Set_Adv_Mode_Test; + mail->param.ME_BtSetAdvMode_param.isEnable = en; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_ME_Write_Controller_Memory_Fortest(uint32_t addr,uint32_t val,uint8_t type) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = Write_Controller_Memory_Test; + mail->param.Me_writecontrollermem_param.addr = addr; + mail->param.Me_writecontrollermem_param.memval = val; + mail->param.Me_writecontrollermem_param.type = type; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_ME_Read_Controller_Memory_Fortest(uint32_t addr,uint32_t len,uint8_t type) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = Read_Controller_Memory_Test; + mail->param.Me_readcontrollermem_param.addr = addr; + mail->param.Me_readcontrollermem_param.len = len; + mail->param.Me_readcontrollermem_param.type = type; + app_bt_mail_send(mail); + return 0; +} + +#endif + +int app_bt_Me_SetLinkPolicy(btif_remote_device_t *remDev, btif_link_policy_t policy) +{ +#if !defined(IBRT) + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = Me_SetLinkPolicy_req; + mail->param.Me_SetLinkPolicy_param.remDev = remDev; + mail->param.Me_SetLinkPolicy_param.policy = policy; + app_bt_mail_send(mail); +#endif + return 0; +} + +int app_bt_CMGR_SetSniffTimer( btif_cmgr_handler_t *Handler, + btif_sniff_info_t* SniffInfo, + TimeT Time) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = CMGR_SetSniffTimer_req; + mail->param.CMGR_SetSniffTimer_param.Handler = Handler; + if (SniffInfo){ + memcpy(&mail->param.CMGR_SetSniffTimer_param.SniffInfo, SniffInfo, sizeof(btif_sniff_info_t)); + }else{ + memset(&mail->param.CMGR_SetSniffTimer_param.SniffInfo, 0, sizeof(btif_sniff_info_t)); + } + mail->param.CMGR_SetSniffTimer_param.Time = Time; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_CMGR_SetSniffInfoToAllHandlerByRemDev(btif_sniff_info_t* SniffInfo, + btif_remote_device_t *RemDev) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = CMGR_SetSniffInofToAllHandlerByRemDev_req; + memcpy(&mail->param.CMGR_SetSniffInofToAllHandlerByRemDev_param.SniffInfo, SniffInfo, sizeof(btif_sniff_info_t)); + mail->param.CMGR_SetSniffInofToAllHandlerByRemDev_param.RemDev = RemDev; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_A2DP_OpenStream(a2dp_stream_t *Stream, bt_bdaddr_t *Addr) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = A2DP_OpenStream_req; + mail->param.A2DP_OpenStream_param.Stream = Stream; + mail->param.A2DP_OpenStream_param.Addr = Addr; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_A2DP_CloseStream(a2dp_stream_t *Stream) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = A2DP_CloseStream_req; + mail->param.A2DP_CloseStream_param.Stream = Stream; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_A2DP_SetMasterRole(a2dp_stream_t *Stream, BOOL Flag) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = A2DP_SetMasterRole_req; + mail->param.A2DP_SetMasterRole_param.Stream = Stream; + mail->param.A2DP_SetMasterRole_param.Flag = Flag; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_HF_CreateServiceLink(hf_chan_handle_t Chan, bt_bdaddr_t *Addr) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HF_CreateServiceLink_req; + mail->param.HF_CreateServiceLink_param.Chan = Chan; + mail->param.HF_CreateServiceLink_param.Addr = Addr; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_HF_DisconnectServiceLink(hf_chan_handle_t Chan) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HF_DisconnectServiceLink_req; + mail->param.HF_DisconnectServiceLink_param.Chan = Chan; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_HF_CreateAudioLink(hf_chan_handle_t Chan) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HF_CreateAudioLink_req; + mail->param.HF_CreateAudioLink_param.Chan = Chan; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_HF_DisconnectAudioLink(hf_chan_handle_t Chan) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HF_DisconnectAudioLink_req; + mail->param.HF_DisconnectAudioLink_param.Chan = Chan; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_HF_EnableSniffMode(hf_chan_handle_t Chan, BOOL Enable) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HF_EnableSniffMode_req; + mail->param.HF_EnableSniffMode_param.Chan = Chan; + mail->param.HF_EnableSniffMode_param.Enable = Enable; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_HF_SetMasterRole(hf_chan_handle_t Chan, BOOL Flag) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HF_SetMasterRole_req; + mail->param.HF_SetMasterRole_param.Chan = Chan; + mail->param.HF_SetMasterRole_param.Flag = Flag; + app_bt_mail_send(mail); + return 0; +} + +#ifdef BTIF_DIP_DEVICE +int app_bt_dip_QuryService(btif_dip_client_t *client, btif_remote_device_t* rem) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = DIP_QuryService_req; + mail->param.DIP_QuryService_param.remDev = rem; + mail->param.DIP_QuryService_param.dip_client = client; + app_bt_mail_send(mail); + return 0; +} +#endif + +#if defined (__HSP_ENABLE__) +int app_bt_HS_CreateServiceLink(HsChannel *Chan, bt_bdaddr_t *Addr) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HS_CreateServiceLink_req; + mail->param.HS_CreateServiceLink_param.Chan = Chan; + mail->param.HS_CreateServiceLink_param.Addr = Addr; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_HS_CreateAudioLink(HsChannel *Chan) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HS_CreateAudioLink_req; + mail->param.HS_CreateAudioLink_param.Chan = Chan; + app_bt_mail_send(mail); + return 0; +} + + +int app_bt_HS_DisconnectAudioLink(HsChannel *Chan) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HS_DisconnectAudioLink_req; + mail->param.HS_DisconnectAudioLink_param.Chan = Chan; + app_bt_mail_send(mail); + return 0; +} + +int app_bt_HS_DisconnectServiceLink(HsChannel *Chan) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HS_DisconnectServiceLink_req; + mail->param.HS_DisconnectServiceLink_param.Chan = Chan; + app_bt_mail_send(mail); + return 0; +} + + +int app_bt_HS_EnableSniffMode(HsChannel *Chan, BOOL Enable) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = HS_EnableSniffMode_req; + mail->param.HS_EnableSniffMode_param.Chan = Chan; + mail->param.HS_EnableSniffMode_param.Enable = Enable; + app_bt_mail_send(mail); + return 0; +} + +#endif +int app_bt_start_custom_function_in_bt_thread( + uint32_t param0, uint32_t param1, uint32_t funcPtr) +{ + APP_BT_MAIL* mail; + app_bt_mail_alloc(&mail); + mail->src_thread = (uint32_t)osThreadGetId(); + mail->request_id = BT_Custom_Func_req; + mail->param.CustomFunc_param.func_ptr = funcPtr; + mail->param.CustomFunc_param.param0 = param0; + mail->param.CustomFunc_param.param1 = param1; + app_bt_mail_send(mail); + return 0; +} + + diff --git a/services/bt_app/app_bt_func.h b/services/bt_app/app_bt_func.h new file mode 100644 index 0000000..3cdf64f --- /dev/null +++ b/services/bt_app/app_bt_func.h @@ -0,0 +1,351 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BT_FUNC_H__ +#define __APP_BT_FUNC_H__ + +#include "cmsis_os.h" +#include "hal_trace.h" + +#ifdef __cplusplus +extern "C" { +#endif +#include "me_api.h" +#include "a2dp_api.h" +#include "hfp_api.h" +#include "dip_api.h" + +typedef enum _bt_fn_req { + Me_switch_sco_req = 0, + ME_SwitchRole_req = 1, + ME_SetConnectionRole_req = 2, + MeDisconnectLink_req = 3, + ME_StopSniff_req = 4, + ME_SetAccessibleMode_req = 5, + Me_SetLinkPolicy_req = 6, + CMGR_SetSniffTimer_req = 7, + CMGR_SetSniffInofToAllHandlerByRemDev_req = 8, + A2DP_OpenStream_req = 9, + A2DP_CloseStream_req = 10, + A2DP_SetMasterRole_req = 11, + HF_CreateServiceLink_req = 12, + HF_DisconnectServiceLink_req = 13, + HF_CreateAudioLink_req = 14, + HF_DisconnectAudioLink_req = 15, + HF_EnableSniffMode_req = 16, + HF_SetMasterRole_req = 17, +#if defined (__HSP_ENABLE__) + HS_CreateServiceLink_req = 18, + HS_CreateAudioLink_req = 19, + HS_DisconnectAudioLink_req = 20, + HS_EnableSniffMode_req = 21, + HS_DisconnectServiceLink_req = 22, +#endif + BT_Control_SleepMode_req = 23, + BT_Custom_Func_req = 24, + ME_StartSniff_req = 25, +#ifdef BTIF_DIP_DEVICE + DIP_QuryService_req = 26, +#endif + A2DP_Force_OpenStream_req = 27, + HF_Force_CreateServiceLink_req = 28, + BT_Red_Ccmp_Client_Open = 29, + BT_Set_Access_Mode_Test = 30, + BT_Set_Adv_Mode_Test = 31, + Write_Controller_Memory_Test = 32, + Read_Controller_Memory_Test = 33, +}bt_fn_req; +typedef void (*APP_BTTHREAD_REQ_CUSTOMER_CALL_CB_T)(void *, void *); + +typedef union _bt_fn_param { + // BtStatus Me_switch_sco(uint16_t scohandle) + struct { + uint16_t scohandle; + } Me_switch_sco_param; + + // BtStatus ME_SwitchRole(btif_remote_device_t *remDev) + struct { + btif_remote_device_t* remDev; + } ME_SwitchRole_param; + + //BtConnectionRole ME_SetConnectionRole(BtConnectionRole role) + struct { + btif_connection_role_t role; + } BtConnectionRole_param; + + // void MeDisconnectLink(btif_remote_device_t* remDev) + struct { + btif_remote_device_t* remDev; + } MeDisconnectLink_param; + + //BtStatus ME_StopSniff(btif_remote_device_t *remDev) + struct { + btif_remote_device_t* remDev; + } ME_StopSniff_param; + + struct { + btif_remote_device_t* remDev; + btif_sniff_info_t sniffInfo; + } ME_StartSniff_param; + + struct { + bool isEnable; + } ME_BtControlSleepMode_param; + + struct { + bool isEnable; + } ME_BtSetAdvMode_param; + + //BtStatus ME_SetAccessibleMode(btif_accessible_mode_t mode, const btif_access_mode_info_t *info) + struct { + btif_accessible_mode_t mode; + btif_access_mode_info_t info; + } ME_SetAccessibleMode_param; + + //BtStatus Me_SetLinkPolicy(btif_remote_device_t *remDev, btif_link_policy_t policy) + struct { + btif_remote_device_t *remDev; + btif_link_policy_t policy; + } Me_SetLinkPolicy_param; + + /*BtStatus CMGR_SetSniffTimer(CmgrHandler *Handler, + btif_sniff_info_t* SniffInfo, + TimeT Time) + */ + struct { + btif_cmgr_handler_t *Handler; + btif_sniff_info_t SniffInfo; + TimeT Time; + } CMGR_SetSniffTimer_param; + + /*BtStatus CMGR_SetSniffInofToAllHandlerByRemDev(btif_sniff_info_t* SniffInfo, + btif_remote_device_t *RemDev) + */ + struct { + btif_sniff_info_t SniffInfo; + btif_remote_device_t *RemDev; + } CMGR_SetSniffInofToAllHandlerByRemDev_param; + + //BtStatus A2DP_OpenStream(a2dp_stream_t *Stream, bt_bdaddr_t *Addr) + struct { + a2dp_stream_t *Stream; + bt_bdaddr_t *Addr; + } A2DP_OpenStream_param; + + //BtStatus A2DP_CloseStream(a2dp_stream_t *Stream); + struct { + a2dp_stream_t *Stream; + } A2DP_CloseStream_param; + + //BtStatus A2DP_SetMasterRole(a2dp_stream_t *Stream, BOOL Flag); + struct { + a2dp_stream_t *Stream; + BOOL Flag; + } A2DP_SetMasterRole_param; + + //BtStatus HF_CreateServiceLink(HfChannel *Chan, bt_bdaddr_t *Addr) + struct { + hf_chan_handle_t Chan; + bt_bdaddr_t *Addr; + } HF_CreateServiceLink_param; + + //bt_status_t HF_DisconnectServiceLink(hf_chan_handle_t Chan) + struct { + hf_chan_handle_t Chan; + } HF_DisconnectServiceLink_param; + + //bt_status_t HF_CreateAudioLink(hf_chan_handle_t Chan) + struct { + hf_chan_handle_t Chan; + } HF_CreateAudioLink_param; + + //bt_status_t HF_DisconnectAudioLink(hf_chan_handle_t Chan) + struct { + hf_chan_handle_t Chan; + } HF_DisconnectAudioLink_param; + + //bt_status_t HF_EnableSniffMode(hf_chan_handle_t Chan, BOOL Enable) + struct { + hf_chan_handle_t Chan; + BOOL Enable; + } HF_EnableSniffMode_param; + + //bt_status_t HF_SetMasterRole(hf_chan_handle_t Chan, BOOL Flag); + struct { + hf_chan_handle_t Chan; + BOOL Flag; + } HF_SetMasterRole_param; + +#ifdef BTIF_DIP_DEVICE + struct { + btif_remote_device_t* remDev; + btif_dip_client_t *dip_client; + } DIP_QuryService_param; +#endif + +#if defined (__HSP_ENABLE__) + //bt_status_t HS_CreateServiceLink(HsChannel *Chan, bt_bdaddr_t *Addr) + struct { + HsChannel *Chan; + bt_bdaddr_t *Addr; + } HS_CreateServiceLink_param; + + //BtStatus HS_CreateAudioLink(HsChannel *Chan) + struct { + HsChannel *Chan; + } HS_CreateAudioLink_param; + + //BtStatus HS_DisconnectAudioLink(HsChannel *Chan) + struct { + HsChannel *Chan; + } HS_DisconnectAudioLink_param; + + //BtStatus HS_DisconnectServiceLink(HsChannel *Chan) + struct { + HsChannel *Chan; + } HS_DisconnectServiceLink_param; + + //BtStatus HS_EnableSniffMode(HsChannel *Chan, BOOL Enable) + struct { + HsChannel *Chan; + BOOL Enable; + } HS_EnableSniffMode_param; +#endif + + struct { + uint32_t func_ptr; + uint32_t param0; + uint32_t param1; + } CustomFunc_param; + + struct { + uint32_t addr; + uint32_t memval; + uint8_t type; + } Me_writecontrollermem_param; + + struct { + uint32_t addr; + uint8_t len; + uint8_t type; + } Me_readcontrollermem_param; + +} bt_fn_param; + +typedef struct { + uint32_t src_thread; + uint32_t request_id; + bt_fn_param param; +} APP_BT_MAIL; + +typedef struct +{ + btif_remote_device_t *remDev; + btif_link_policy_t policy; +} BT_SET_LINKPOLICY_REQ_T; + +int app_bt_mail_init(void); + +int app_bt_Me_switch_sco(uint16_t scohandle); + +int app_bt_ME_SwitchRole(btif_remote_device_t* remDev); + +int app_bt_ME_SetConnectionRole(btif_connection_role_t role); + +int app_bt_MeDisconnectLink(btif_remote_device_t* remDev); + +int app_bt_ME_StopSniff(btif_remote_device_t *remDev); + +int app_bt_ME_SetAccessibleMode(btif_accessible_mode_t mode, const btif_access_mode_info_t *info); + +int app_bt_Me_SetLinkPolicy(btif_remote_device_t *remDev, btif_link_policy_t policy); + +int app_bt_CMGR_SetSniffTimer(btif_cmgr_handler_t *Handler, + btif_sniff_info_t* SniffInfo, + TimeT Time); + +int app_bt_CMGR_SetSniffInfoToAllHandlerByRemDev(btif_sniff_info_t* SniffInfo, + btif_remote_device_t *RemDev); + +int app_bt_A2DP_OpenStream(a2dp_stream_t *Stream, bt_bdaddr_t *Addr); + +int app_bt_A2DP_CloseStream(a2dp_stream_t *Stream); + +int app_bt_A2DP_SetMasterRole(a2dp_stream_t *Stream, BOOL Flag); + +int app_bt_HF_CreateServiceLink(hf_chan_handle_t Chan, bt_bdaddr_t *Addr); + +int app_bt_HF_DisconnectServiceLink(hf_chan_handle_t Chan); + +int app_bt_HF_CreateAudioLink(hf_chan_handle_t Chan); + +int app_bt_HF_DisconnectAudioLink(hf_chan_handle_t Chan); + +int app_bt_HF_EnableSniffMode(hf_chan_handle_t Chan, BOOL Enable); + +int app_bt_HF_SetMasterRole(hf_chan_handle_t Chan, BOOL Flag); + +void app_bt_accessible_manager_process(const btif_event_t *Event); +void app_bt_role_manager_process(const btif_event_t* Event); +void app_bt_sniff_manager_process(const btif_event_t *Event); +//void app_bt_golbal_handle_hook(const btif_event_t *Event); + +int app_bt_ME_ControlSleepMode(bool isEnabled); + +#ifdef BTIF_DIP_DEVICE +int app_bt_dip_QuryService(btif_dip_client_t *client, btif_remote_device_t* rem); +#endif + +#if defined (__HSP_ENABLE__) +int app_bt_HS_CreateServiceLink(HsChannel *Chan, bt_bdaddr_t *Addr); + +int app_bt_HS_CreateAudioLink(HsChannel *Chan); + +int app_bt_HS_DisconnectAudioLink(HsChannel *Chan); + +int app_bt_HS_DisconnectServiceLink(HsChannel *Chan); + +int app_bt_HS_EnableSniffMode(HsChannel *Chan, BOOL Enable); + +#endif +bool app_is_access_mode_set_pending(void); +void app_set_pending_access_mode(void); +void app_bt_set_linkpolicy(btif_remote_device_t *remDev, btif_link_policy_t policy); +void app_check_pending_stop_sniff_op(void); +BT_SET_LINKPOLICY_REQ_T* app_bt_pop_pending_set_linkpolicy(void); +void app_retry_setting_access_mode(void); +void app_set_accessmode(btif_accessible_mode_t mode); + +int app_bt_start_custom_function_in_bt_thread( + uint32_t param0, uint32_t param1, uint32_t funcPtr); +int app_bt_ME_StartSniff(btif_remote_device_t *remDev, btif_sniff_info_t* sniffInfo); + +#ifdef FPGA +int app_bt_ME_SetAccessibleMode_Fortest(btif_accessible_mode_t mode, const btif_access_mode_info_t *info); + +int app_bt_ME_Set_Advmode_Fortest(uint8_t en); + +int app_bt_ME_Write_Controller_Memory_Fortest(uint32_t addr,uint32_t val,uint8_t type); + +int app_bt_ME_Read_Controller_Memory_Fortest(uint32_t addr,uint32_t len,uint8_t type); + + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __APP_BT_FUNC_H__ */ + diff --git a/services/bt_app/app_bt_hid.cpp b/services/bt_app/app_bt_hid.cpp new file mode 100644 index 0000000..25dce5d --- /dev/null +++ b/services/bt_app/app_bt_hid.cpp @@ -0,0 +1,246 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef BTIF_HID_DEVICE +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_chipid.h" +#include "analog.h" +#include "app_audio.h" +#include "app_battery.h" +#include "hal_trace.h" +#include "app_status_ind.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif +#include "besbt.h" +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "bt_if.h" +#include "os_api.h" +#include "app_bt_func.h" +#include "bt_drv_interface.h" +#include "app.h" +#include "bt_drv_reg_op.h" +#include "besbt_cfg.h" +#include "me_api.h" +#include "app_tws_ibrt.h" +#include "app_bt_hid.h" +#include "hid_api.h" + +static bool shutter_mode = false; +static bool send_capture_pending = false; + +#define APP_BT_HID_DELAY_SEND_CAPTURE_MS 500 +osTimerId app_bt_hid_delay_send_timer_id = 0; +static void app_bt_hid_delay_send_timer_handler(void const *param); +osTimerDef (APP_BT_HID_DELAY_SEND_CAPTURE_TIMER, app_bt_hid_delay_send_timer_handler); + +extern struct BT_DEVICE_T app_bt_device; + +static void app_bt_hid_delay_send_timer_handler(void const *param) +{ + hid_channel_t chan = (hid_channel_t)param; + app_bt_start_custom_function_in_bt_thread((uint32_t)&chan, (uint32_t)NULL, (uint32_t)app_bt_hid_send_capture); +} + +static void app_bt_hid_delay_send_capture(hid_channel_t chan) +{ + if (app_bt_hid_delay_send_timer_id) + { + osTimerStop(app_bt_hid_delay_send_timer_id); + osTimerDelete(app_bt_hid_delay_send_timer_id); + app_bt_hid_delay_send_timer_id = 0; + } + + app_bt_hid_delay_send_timer_id = osTimerCreate(osTimer(APP_BT_HID_DELAY_SEND_CAPTURE_TIMER), osTimerOnce, chan); + + if (!app_bt_hid_delay_send_timer_id) + { + TRACE(1, "%s create timer failed", __func__); + return; + } + + TRACE(2, "%s channel %p", __func__, chan); + + osTimerStart(app_bt_hid_delay_send_timer_id, APP_BT_HID_DELAY_SEND_CAPTURE_MS); +} + +static void app_bt_hid_callback(hid_channel_t chan, const hid_callback_parms_t *param) +{ + btif_hid_callback_param_t *info = (btif_hid_callback_param_t *)param; + + TRACE(9, "%s channel %p event %d errno %02x %02x:%02x:%02x:%02x:%02x:%02x", + __func__, chan, info->event, info->error_code, + info->remote.address[0], info->remote.address[1], info->remote.address[2], + info->remote.address[3], info->remote.address[4], info->remote.address[5]); + + switch (info->event) + { + case BTIF_HID_EVENT_CONN_OPENED: + shutter_mode = true; + if (send_capture_pending) + { + app_bt_hid_delay_send_capture(chan); + send_capture_pending = false; + } + break; + case BTIF_HID_EVENT_CONN_CLOSED: + shutter_mode = false; + break; + default: + break; + } + app_tws_ibrt_profile_callback(BTIF_APP_HID_PROFILE_ID, (void *)chan, (void *)param); +} + +void app_bt_hid_init(void) +{ + //TRACE(2, "%s sink_enable %d", __func__, besbt_cfg.sink_enable); + //if (besbt_cfg.sink_enable) + { + btif_hid_init(app_bt_hid_callback, HID_DEVICE_ROLE); + + for (int i = 0; i < BT_DEVICE_NUM; ++i) + { + app_bt_device.hid_channel[i] = btif_hid_channel_alloc(); + TRACE(2, "app_bt_hid_init device: %d hid_channle: %p", i, app_bt_device.hid_channel[i]); + } + } +} + +void app_bt_hid_profile_connect(bt_bdaddr_t *bdaddr) +{ + static bt_bdaddr_t remote; + + remote = *bdaddr; + + TRACE(7, "%s address %02x:%02x:%02x:%02x:%02x:%02x", __func__, + remote.address[0], remote.address[1], remote.address[2], + remote.address[3], remote.address[4], remote.address[5]); + + app_bt_start_custom_function_in_bt_thread((uint32_t)&remote, (uint32_t)NULL, (uint32_t)btif_hid_connect); +} + +void app_bt_hid_profile_disconnect(hid_channel_t chnl) +{ + TRACE(1, "%s channel %p", __func__, chnl); + + app_bt_start_custom_function_in_bt_thread((uint32_t)chnl, (uint32_t)NULL, (uint32_t)btif_hid_disconnect); +} + +int app_bt_nvrecord_get_latest_device_addr(bt_bdaddr_t *addr) +{ + btif_device_record_t record; + int found_addr_count = 0; + int paired_dev_count = nv_record_get_paired_dev_count(); + + if (paired_dev_count > 0 && BT_STS_SUCCESS == nv_record_enum_dev_records(0, &record)) + { + *addr = record.bdAddr; + found_addr_count = 1; + } + + return found_addr_count; +} + +void app_bt_hid_enter_shutter_mode(void) +{ + bt_bdaddr_t remote; + + TRACE(1, "%s", __func__); + + if (!app_bt_nvrecord_get_latest_device_addr(&remote)) + { + TRACE(1, "%s latest device not found", __func__); + return; + } + + if (!shutter_mode) + { + app_bt_hid_profile_connect(&remote); + shutter_mode = true; + } + else + { + TRACE(1, "%s already in shutter mode", __func__); + } +} + +void app_bt_hid_exit_shutter_mode(void) +{ + hid_channel_t chnl = NULL; + int i = 0; + + TRACE(0, "%s", __func__); + + for (; i < BT_DEVICE_NUM; ++i) + { + chnl = app_bt_device.hid_channel[i]; + if (btif_hid_is_connected(chnl)) + { + app_bt_hid_profile_disconnect(chnl); + } + } + + shutter_mode = false; +} + +void app_bt_hid_send_capture(hid_channel_t chnl) +{ + for (int i = 0; i < BT_DEVICE_NUM; ++i) + { + if (btif_hid_is_connected(app_bt_device.hid_channel[i])) + { + chnl = app_bt_device.hid_channel[i]; + break; + } + } + + TRACE(3, "%s channel %p state %d", __func__, chnl, btif_hid_get_state(chnl)); + + if (btif_hid_is_connected(chnl)) + { + send_capture_pending = false; + + btif_hid_keyboard_input_report(chnl, HID_MOD_KEY_NULL, HID_KEY_CODE_ENTER); + btif_hid_keyboard_input_report(chnl, HID_MOD_KEY_NULL, HID_KEY_CODE_NULL); + + btif_hid_keyboard_send_ctrl_key(chnl, HID_CTRL_KEY_VOLUME_INC); + btif_hid_keyboard_send_ctrl_key(chnl, HID_CTRL_KEY_NULL); + } + else + { + send_capture_pending = true; + + app_bt_hid_enter_shutter_mode(); + } + +} + +#endif /* BTIF_HID_DEVICE */ + diff --git a/services/bt_app/app_bt_hid.h b/services/bt_app/app_bt_hid.h new file mode 100644 index 0000000..f0655e5 --- /dev/null +++ b/services/bt_app/app_bt_hid.h @@ -0,0 +1,79 @@ + +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BT_HID_H__ +#define __APP_BT_HID_H__ + +#ifdef BTIF_HID_DEVICE + +#include "bluetooth.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HID_CTRL_KEY_NULL 0x00 +#define HID_CTRL_KEY_POWER 0x01 +#define HID_CTRL_KEY_PLAY 0x02 +#define HID_CTRL_KEY_PAUSE 0x04 +#define HID_CTRL_KEY_STOP 0x08 +#define HID_CTRL_KEY_EJECT 0x10 +#define HID_CTRL_KEY_PLAY_PAUSE 0x20 +#define HID_CTRL_KEY_VOLUME_INC 0x40 +#define HID_CTRL_KEY_VOLUME_DEC 0x80 + +#define HID_MOD_KEY_NULL 0x00 +#define HID_MOD_KEY_L_CTRL 0x01 +#define HID_MOD_KEY_L_SHIFT 0x02 +#define HID_MOD_KEY_L_ALT 0x04 +#define HID_MOD_KEY_L_WIN 0x08 +#define HID_MOD_KEY_R_CTRL 0x10 +#define HID_MOD_KEY_R_SHIFT 0x20 +#define HID_MOD_KEY_R_ALT 0x40 +#define HID_MOD_KEY_R_WIN 0x80 + +#define HID_KEY_CODE_NULL 0x00 +#define HID_KEY_CODE_A 0x04 +#define HID_KEY_CODE_Z 0x1d +#define HID_KEY_CODE_1 0x1e +#define HID_KEY_CODE_9 0x26 +#define HID_KEY_CODE_0 0x27 +#define HID_KEY_CODE_ENTER 0x28 +#define HID_KEY_CODE_ESC 0x29 +#define HID_KEY_CODE_DEL 0x2a +#define HID_KEY_CODE_TAB 0x2b +#define HID_KEY_CODE_SPACE 0x2c +#define HID_KEY_CODE_VOLUP 0x80 +#define HID_KEY_CODE_VOLDN 0x81 + +typedef struct hid_control_t* hid_channel_t; + +void app_bt_hid_init(void); + +void app_bt_hid_enter_shutter_mode(void); + +void app_bt_hid_exit_shutter_mode(void); + +void app_bt_hid_send_capture(hid_channel_t chnl); + +#ifdef __cplusplus +} +#endif + +#endif /* BTIF_HID_DEVICE */ + +#endif /* __APP_BT_HID_H__ */ + diff --git a/services/bt_app/app_bt_media_manager.cpp b/services/bt_app/app_bt_media_manager.cpp new file mode 100644 index 0000000..1394e03 --- /dev/null +++ b/services/bt_app/app_bt_media_manager.cpp @@ -0,0 +1,2434 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include + +#include "cmsis_os.h" +#include "cmsis.h" +#include "app_bt_trace.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_chipid.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" +#include "app_bt_stream.h" +#include "app_overlay.h" +#include "app_audio.h" +#include "app_utils.h" +#include "nvrecord.h" +#if defined(IBRT) +#include "app_ibrt_if.h" +#else +#include "app_media_player.h" +#endif + +#include "resources.h" +#ifdef MEDIA_PLAYER_SUPPORT +#include "app_media_player.h" +#endif + +#include "bt_drv.h" +#include "apps.h" +#include "app_bt_func.h" + +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_hfp.h" + +#include "app_bt_media_manager.h" +#include "app_thread.h" + +#include "app_ring_merge.h" +#include "bt_if.h" +#include "audio_prompt_sbc.h" +#include "app_ai_if.h" + + +int bt_sco_player_forcemute(bool mic_mute, bool spk_mute); +int bt_sco_player_get_codetype(void); +extern struct BT_DEVICE_T app_bt_device; +extern enum AUD_SAMPRATE_T a2dp_sample_rate; + +struct bt_media_manager +{ + uint16_t media_active[BT_DEVICE_NUM]; + uint8_t media_current_call_state[BT_DEVICE_NUM]; + uint8_t media_curr_sbc; + uint8_t media_curr_sco; + uint16_t curr_active_media; // low 8 bits are out direciton, while high 8 bits are in direction +}; + +static char _strm_type_str[168]; +static char *_catstr(char *dst, const char *src) +{ + while(*dst) dst++; + while((*dst++ = *src++)); + return --dst; +} +static const char *strmtype2str(uint16_t stream_type) +{ + const char *s = NULL; + char _cat = 0, first = 1, *d = NULL; + _strm_type_str[0] = '\0'; + d = _strm_type_str; + d = _catstr(d, "["); + if (stream_type != 0) + { + for (int i = 15 ; i >= 0; i--) + { + _cat = 1; + //TRACE_AUD_MGR_I("i=%d,stream_type=0x%d,stream_type&(1<%d", bt_meida.media_curr_sbc, id); + bt_meida.media_curr_sbc = id; +} + +static void bt_media_set_current_media(uint16_t media_type) +{ + // out direction + if (media_type < 0x100) + { + bt_meida.curr_active_media &= (~0xFF); + bt_meida.curr_active_media |= media_type; + } + else + { + //bt_meida.curr_active_media &= (~0xFF00); + bt_meida.curr_active_media |= media_type; + } + + TRACE_AUD_MGR_I("curr_active_media is set to 0x%x->:%s", bt_meida.curr_active_media, strmtype2str(bt_meida.curr_active_media)); +} + +static void bt_media_clear_current_media(uint16_t media_type) +{ + if (media_type < 0x100) + { + bt_meida.curr_active_media &= (~0xFF); + } + else + { + bt_meida.curr_active_media &= (~media_type); + } + TRACE_AUD_MGR_I("clear media 0x%x curr media 0x%x", media_type, bt_meida.curr_active_media); +} +#ifdef VOICE_DATAPATH +#if !ISOLATED_AUDIO_STREAM_ENABLED +static void bt_media_clear_all_media_type(void) +{ + uint8_t i; + for(i=0; i:%s,device id = 0x%x,media_id = 0x%x", + stream_type, + strmtype2str(stream_type), + device_id, + media_id); + +#ifdef __BT_ONE_BRING_TWO__ + TRACE_AUD_MGR_I( + "[HANDLE_START] media_active[0] = 0x%x->:%s", + bt_meida.media_active[0], + strmtype2str(bt_meida.media_active[0])); + TRACE_AUD_MGR_I( + "[HANDLE_START] media_active[1] = 0x%x->:%s", + bt_meida.media_active[1], + strmtype2str(bt_meida.media_active[1])); + TRACE_AUD_MGR_I( + "[HANDLE_START] curr_active_media = 0x%x->:%s", + bt_meida.curr_active_media, + strmtype2str(bt_meida.curr_active_media)); +#else + TRACE_AUD_MGR_I( + "[HANDLE_START] media_active = 0x%x->:%s", + bt_meida.media_active[0], + strmtype2str(bt_meida.media_active[0])); + TRACE_AUD_MGR_I( + "[HANDLE_START] curr_active_media = 0x%x->:%s", + bt_meida.curr_active_media, + strmtype2str(bt_meida.curr_active_media)); +#endif + + switch(stream_type) + { +#ifdef RB_CODEC + case BT_STREAM_RBCODEC: + if(!bt_media_rbcodec_start_process(stream_type,device_id, (AUD_ID_ENUM)media_id, NULL, NULL)) + goto exit; + break; +#endif + +#ifdef VOICE_DATAPATH + case BT_STREAM_CAPTURE: + if (bt_media_get_current_media() & BT_STREAM_CAPTURE) + { + TRACE_AUD_MGR_I("[HANDLE_START] capture stream exist ,do nothing"); + return; + } + + if (bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + goto exit; + } + +#ifdef MEDIA_PLAYER_SUPPORT +#if !ISOLATED_AUDIO_STREAM_ENABLED + if(bt_media_is_media_active_by_type(BT_STREAM_MEDIA)) + { + return; + } +#endif +#endif + if (!bt_media_voicepath_start_process(BT_STREAM_CAPTURE, device_id, ( AUD_ID_ENUM )media_id, ( uint32_t )NULL, ( uint32_t )NULL)) + goto exit; + break; +#endif + +#ifdef __AI_VOICE__ + case BT_STREAM_AI_VOICE: + if (bt_media_get_current_media() & BT_STREAM_AI_VOICE) + { + TRACE_AUD_MGR_I("[HANDLE_START] ai voice stream exist ,do nothing"); + return; + } + + if (bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + TRACE_AUD_MGR_I("[HANDLE_START] SCO stream exist ,do nothing"); + goto exit; + } + + if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + if(bt_media_get_current_media() & BT_STREAM_SBC) + { + TRACE_AUD_MGR_I("[HANDLE_START] CLOSE SBC."); + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_clear_current_media(BT_STREAM_SBC); + } + } + + if (!bt_media_ai_voice_start_process(BT_STREAM_AI_VOICE, device_id, ( AUD_ID_ENUM )media_id, ( uint32_t )NULL, ( uint32_t )NULL)) + goto exit; + break; +#endif +#ifdef __THIRDPARTY + case BT_STREAM_THIRDPARTY_VOICE: + if (bt_media_get_current_media() & BT_STREAM_THIRDPARTY_VOICE) + { + TRACE_AUD_MGR_I("[HANDLE_START]there is a thirdparty voice stream exist ,do nothing"); + return; + } + + if (bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + TRACE_AUD_MGR_I("[HANDLE_START]there is a SCO stream exist ,do nothing"); + goto exit; + } + + if (!bt_media_thirdparty_voice_start_process(BT_STREAM_THIRDPARTY_VOICE, device_id, ( AUD_ID_ENUM )media_id, ( uint32_t )NULL, ( uint32_t )NULL)) + goto exit; + break; +#endif + + case BT_STREAM_SBC: + { + uint8_t media_pre_sbc = bt_meida.media_curr_sbc; + ////because voice is the highest priority and media report will stop soon + //// so just store the sbc type + if (bt_meida.media_curr_sbc == BT_DEVICE_NUM) + bt_meida.media_curr_sbc = device_id; + TRACE_AUD_MGR_I("[HANDLE_START] pre/cur_sbc = %d/%d", media_pre_sbc, bt_meida.media_curr_sbc); + +#ifdef MEDIA_PLAYER_SUPPORT +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + /// clear the pending stop flag if it is set + audio_prompt_clear_pending_stream(PENDING_TO_STOP_A2DP_STREAMING); +#endif + + if (bt_media_is_media_active_by_type(BT_STREAM_MEDIA)) + { + goto exit; + } +#endif +#ifdef RB_CODEC + if (bt_media_is_media_active_by_type(BT_STREAM_RBCODEC)) + { + goto exit; + } +#endif + +#ifdef VOICE_DATAPATH +#if !ISOLATED_AUDIO_STREAM_ENABLED + if (bt_media_is_media_active_by_type(BT_STREAM_CAPTURE)) + { + goto exit; + } +#endif +#endif + +#ifdef __AI_VOICE__ + if (bt_media_is_media_active_by_type(BT_STREAM_AI_VOICE) || ai_if_is_ai_stream_mic_open()) + { + TRACE_AUD_MGR_I("[HANDLE_START] ai voice stream exist"); + goto exit; + } +#endif + +#ifdef AUDIO_LINEIN + if(bt_media_is_media_active_by_type(BT_STREAM_LINEIN)) + { + if(bt_media_get_current_media() & BT_STREAM_LINEIN) + { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP, (uint8_t)BT_STREAM_LINEIN, 0,0); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START, BT_STREAM_SBC, device_id, 0); + return; + } + } +#endif + + if(bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + ////sbc and voice is all on so set sys freq to 104m + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_104M); + return; + } +#ifdef __BT_ONE_BRING_TWO__ + else if (btapp_hfp_is_call_active()) + { + //do nothing + TRACE_AUD_MGR_I("[HANDLE_START] skip sbc start, because HF_CALL_ACTIVE"); + } + else if(bt_media_is_media_active_by_device(BT_STREAM_SBC,other_device_id)) + { +#if !defined(__MULTIPOINT_A2DP_PREEMPT__) + //if another device is the active stream do nothing + if(bt_meida.media_curr_sbc == other_device_id) + { + + ///2 device is play sbc,so set sys freq to 104m + app_audio_manager_switch_a2dp((enum BT_DEVICE_ID_T)bt_meida.media_curr_sbc); + app_audio_sendrequest_param((uint8_t)APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_RESTART, 0, APP_SYSFREQ_104M); + return; + } +#else + if (bt_meida.media_curr_sbc == other_device_id) + { + app_audio_manager_switch_a2dp(device_id); + app_audio_sendrequest( APP_BT_STREAM_A2DP_SBC, + (uint8_t)(APP_BT_SETTING_SETUP), + (uint32_t)(app_bt_device.sample_rate[device_id] & A2D_STREAM_SAMP_FREQ_MSK)); + app_audio_sendrequest_param(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_RESTART, 0, APP_SYSFREQ_104M); + return; + } +#endif + ////if curr active media is not sbc,wrong~~ + if(0 == (bt_media_get_current_media() & BT_STREAM_SBC)) + { + ASSERT(0,"curr_active_media is wrong!"); + } + ///stop the old audio sbc and start the new audio sbc + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_CLOSE, 0); + } +#endif + else + { + //start audio sbc stream + if (media_pre_sbc != bt_meida.media_curr_sbc) + { + app_audio_manager_switch_a2dp(device_id); + bt_media_set_current_media(BT_STREAM_SBC); + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, + (uint8_t)(APP_BT_SETTING_SETUP), + (uint32_t)(app_bt_device.sample_rate[device_id] & A2D_STREAM_SAMP_FREQ_MSK)); + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, ( uint8_t )APP_BT_SETTING_OPEN, 0); + } + } + } + break; + +#ifdef MEDIA_PLAYER_SUPPORT + case BT_STREAM_MEDIA: + #ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + isMergingPrompt = IS_PROMPT_NEED_MERGING(media_id); + #endif + + if( +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + audio_prompt_is_playing_ongoing() || +#endif + app_audio_list_playback_exist()) + { + if (!bt_media_cur_is_bt_stream_media()) + { + bt_media_clear_media_type(BT_STREAM_MEDIA,device_id); + } + media_id = PROMPT_ID_FROM_ID_VALUE(media_id); + APP_AUDIO_STATUS aud_status; + aud_status.id = APP_PLAY_BACK_AUDIO; + aud_status.aud_id = media_id; + + app_audio_list_append(&aud_status); + break; + } + +#ifdef AUDIO_LINEIN + if(bt_media_is_media_active_by_type(BT_STREAM_LINEIN)) + { + if(bt_media_get_current_media() & BT_STREAM_LINEIN) + { + APP_AUDIO_STATUS aud_status; + aud_status.id = media_id; + app_play_audio_lineinmode_start(&aud_status); + bt_media_clear_media_type(BT_STREAM_MEDIA, device_id); + } + }else +#endif + //first,if the voice is active so mix "dudu" to the stream + if(bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + if(bt_media_get_current_media() & BT_STREAM_VOICE) + { +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + // if the playback is not triggered yet, we just use the stand-alone prompt playing + if (!bt_is_playback_triggered()) + { + isMergingPrompt = false; + } +#endif + //if call is not active so do media report + if((btapp_hfp_is_call_active() && !btapp_hfp_incoming_calls()) || + (app_bt_stream_isrun(APP_BT_STREAM_HFP_PCM))) + { +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + bt_media_clear_media_type(BT_STREAM_MEDIA, device_id); + if (isMergingPrompt) + { + audio_prompt_start_playing(media_id, sco_sample_rate); + goto exit; + } + else + { + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_CLOSE, 0); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); + bt_media_set_current_media(BT_STREAM_MEDIA); + } +#else + //in three way call merge "dudu" + TRACE_AUD_MGR_I("[HANDLE_START] BT_STREAM_VOICE-->app_ring_merge_start\n"); + app_ring_merge_start(); + //meida is done here + bt_media_clear_media_type(BT_STREAM_MEDIA, device_id); +#endif + } + else + { +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + bt_media_clear_media_type(BT_STREAM_MEDIA, device_id); + if (isMergingPrompt) + { + audio_prompt_start_playing(media_id, sco_sample_rate); + goto exit; + } + else + { + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_CLOSE, 0); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); + bt_media_set_current_media(BT_STREAM_MEDIA); + } +#else + TRACE_AUD_MGR_I("[HANDLE_START] stop sco and do media report\n"); + bt_media_set_current_media(BT_STREAM_MEDIA); + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_CLOSE, 0); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); +#endif + } + } + else if(bt_media_get_current_media() & BT_STREAM_MEDIA) + { + bt_media_set_current_media(BT_STREAM_MEDIA); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); + } + else + { + ///if voice is active but current is not voice something is unkown + bt_media_clear_media_type(BT_STREAM_MEDIA, device_id); +#ifdef __BT_ONE_BRING_TWO__ + TRACE_AUD_MGR_I("[HANDLE_START] voice_act media_act = %x,%x,curr_media = %x", + bt_meida.media_active[0],bt_meida.media_active[1], bt_meida.curr_active_media); +#else + TRACE_AUD_MGR_I("[HANDLE_START] voice_act media_act = %x,curr_media = %x", + bt_meida.media_active[0], bt_meida.curr_active_media); + +#endif + } + } + else if (btapp_hfp_is_call_active()) + { + bt_media_set_current_media(BT_STREAM_MEDIA); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); + } +#ifdef VOICE_DATAPATH +#if !ISOLATED_AUDIO_STREAM_ENABLED + else if( bt_media_is_media_active_by_type(BT_STREAM_CAPTURE) ) + { + if(bt_media_get_current_media() & BT_STREAM_MEDIA) + { + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); + } + else + { + goto exit; + } + } +#endif +#endif + ////if sbc active so + else if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + if(bt_media_get_current_media() & BT_STREAM_SBC) + { +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + // if the playback is not triggered yet, we just use the stand-alone prompt playing + if (!bt_is_playback_triggered()) + { + isMergingPrompt = false; + } + + bt_media_clear_media_type(BT_STREAM_MEDIA, device_id); + if (isMergingPrompt) + { + audio_prompt_start_playing(media_id,a2dp_sample_rate); + goto exit; + } + else + { + TRACE_AUD_MGR_I("[HANDLE_START] START prompt."); + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_set_current_media(BT_STREAM_MEDIA); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); + } +#else +#ifdef __BT_WARNING_TONE_MERGE_INTO_STREAM_SBC__ + if (PROMPT_ID_FROM_ID_VALUE(media_id) == AUD_ID_BT_WARNING) + { + TRACE_AUD_MGR_I("[HANDLE_START] BT_STREAM_SBC-->app_ring_merge_start\n"); + app_ring_merge_start(); + //meida is done here + bt_media_clear_media_type(BT_STREAM_MEDIA, device_id); + } + else +#endif + { + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_set_current_media(BT_STREAM_MEDIA); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); + } +#endif // #ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + } + else if(bt_media_get_current_media() & BT_STREAM_MEDIA) + { + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); + } + else if ((bt_media_get_current_media()&0xFF) == 0) + { + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); + } + else + { + ASSERT(0,"media in sbc current wrong"); + } + } + /// just play the media + else + { + bt_media_set_current_media(BT_STREAM_MEDIA); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, media_id); + } + break; +#endif + case BT_STREAM_VOICE: +#ifdef HFP_NO_PRERMPT + if(app_audio_manager_get_active_sco_num() != BT_DEVICE_NUM) + return; +#endif + app_audio_manager_set_active_sco_num(device_id); + +#ifdef VOICE_DATAPATH + if(bt_media_is_media_active_by_type(BT_STREAM_CAPTURE)) + { + if(bt_media_get_current_media() & BT_STREAM_CAPTURE) + { + app_audio_sendrequest(APP_BT_STREAM_VOICEPATH, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_clear_current_media(BT_STREAM_CAPTURE); + } + } +#endif +#ifdef __AI_VOICE__ + if(bt_media_is_media_active_by_type(BT_STREAM_AI_VOICE)) + { + if(bt_media_get_current_media() & BT_STREAM_AI_VOICE) + { + app_audio_sendrequest(APP_BT_STREAM_AI_VOICE, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_clear_current_media(BT_STREAM_AI_VOICE); + } + } +#endif +#ifdef __THIRDPARTY + if(bt_media_is_media_active_by_type(BT_STREAM_THIRDPARTY_VOICE)) { + if(bt_media_get_current_media() & BT_STREAM_THIRDPARTY_VOICE) { + app_audio_sendrequest(APP_BT_STREAM_THIRDPARTY_VOICE, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_clear_current_media(BT_STREAM_THIRDPARTY_VOICE); + } + } +#endif + +#ifdef MEDIA_PLAYER_SUPPORT +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + /// clear the pending stop flag if it is set + audio_prompt_clear_pending_stream(PENDING_TO_STOP_A2DP_STREAMING); +#endif + + if(bt_media_is_media_active_by_type(BT_STREAM_MEDIA)) + { + //if call is active ,so disable media report + if(bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + if(bt_media_get_current_media() & BT_STREAM_MEDIA) + { + if (app_play_audio_get_aud_id() == AUD_ID_BT_CALL_INCOMING_NUMBER) + { + //if meida is open ,close media clear all media type + TRACE_AUD_MGR_I("[HANDLE_START] call active so start sco and stop media report\n"); +#ifdef __AUDIO_QUEUE_SUPPORT__ + app_audio_list_clear(); +#endif + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_clear_media_type(BT_STREAM_MEDIA, device_id); + bt_media_set_current_media(BT_STREAM_VOICE); + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_OPEN, 0); + } + } + } + else + { + ////call is not active so media report continue + } + } + else +#endif + if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + ///if sbc is open stop sbc + if(bt_media_get_current_media() & BT_STREAM_SBC) + { + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_CLOSE, 0); + } + ////start voice stream + bt_media_set_current_media(BT_STREAM_VOICE); + app_audio_sendrequest_param(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_OPEN, 0, APP_SYSFREQ_104M); + } + else + { + //voice is open already so do nothing + if(bt_media_get_current_media() & BT_STREAM_VOICE) + { +#if defined(__BT_ONE_BRING_TWO__) + if(bt_get_sco_number()>1 +#ifdef CHIP_BEST1000 + && hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2 +#endif + ) + { + app_audio_manager_swap_sco(device_id); +#if defined(__HF_KEEP_ONE_ALIVE__) + if (btif_hf_check_AudioConnect_status(app_bt_device.hf_channel[other_device_id])) + { + TRACE_AUD_MGR_I("[MEDIA_START] Disconnect another AudioLink"); + btif_hf_disc_audio_link(app_bt_device.hf_channel[other_device_id]); + } +#endif + } +#endif + } + else + { + bt_media_set_current_media(BT_STREAM_VOICE); + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_OPEN, 0); + } + } + + break; +#ifdef AUDIO_LINEIN + case BT_STREAM_LINEIN: + if(!bt_media_is_media_active_by_type(BT_STREAM_SBC | BT_STREAM_MEDIA | BT_STREAM_VOICE)) + { + app_audio_sendrequest(APP_PLAY_LINEIN_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_LINEIN); + } + break; +#endif + + default: + ASSERT(0,"bt_media_open ERROR TYPE"); + break; + + } + +#if defined(RB_CODEC) || defined(VOICE_DATAPATH) || defined(MEDIA_PLAYER_SUPPORT) || defined(__AI_VOICE__) +exit: + return; +#endif +} + +#ifdef RB_CODEC + +static bool bt_media_rbcodec_stop_process(uint16_t stream_type,enum BT_DEVICE_ID_T device_id, uint32_t ptr) +{ + int ret_SendReq2AudioThread = -1; + bt_media_clear_media_type(stream_type,device_id); + //if current stream is the stop one ,so stop it + if(bt_media_get_current_media() & BT_STREAM_RBCODEC ) + { + ret_SendReq2AudioThread = app_audio_sendrequest(APP_BT_STREAM_RBCODEC, (uint8_t)APP_BT_SETTING_CLOSE, ptr); + bt_media_clear_current_media(BT_STREAM_RBCODEC); + TRACE_AUD_MGR_I("[RBCODEC][STOPED]"); + } + + if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + enum BT_DEVICE_ID_T sbc_id = bt_media_get_active_device_by_type(BT_STREAM_SBC); + TRACE_AUD_MGR_I("[RBCODEC][STOPED] sbc_id %d",sbc_id); + if(sbc_id < BT_DEVICE_NUM) + { + bt_meida.media_curr_sbc = sbc_id; + } + } + else + { + bt_meida.media_curr_sbc = BT_DEVICE_NUM; + } + + TRACE_AUD_MGR_I("[RBCODEC][STOPED] bt_meida.media_curr_sbc %d",bt_meida.media_curr_sbc); + + if(bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + } + else if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + enum BT_DEVICE_ID_T sbc_id = bt_media_get_active_device_by_type(BT_STREAM_SBC); + if(sbc_id < BT_DEVICE_NUM) + { +#ifdef __TWS__ + bt_media_clear_media_type(BT_STREAM_SBC,sbc_id); + bt_media_clear_current_media(BT_STREAM_SBC); + notify_tws_player_status(APP_BT_SETTING_OPEN); +#else + bt_parse_store_sbc_sample_rate(app_bt_device.sample_rate[sbc_id]); + ret_SendReq2AudioThread = app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_SBC); +#endif + } + } + else if(bt_media_is_media_active_by_type(BT_STREAM_MEDIA)) + { + //do nothing + } +} +#endif + +#ifdef VOICE_DATAPATH +bool bt_media_voicepath_stop_process(uint16_t stream_type,enum BT_DEVICE_ID_T device_id) +{ + int ret_SendReq2AudioThread __attribute__((unused)); + ret_SendReq2AudioThread= -1; + bt_media_clear_media_type(stream_type,device_id); + //if current stream is the stop one ,so stop it + if(bt_media_get_current_media() & BT_STREAM_CAPTURE) + { + ret_SendReq2AudioThread = app_audio_sendrequest(APP_BT_STREAM_VOICEPATH, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_clear_current_media(BT_STREAM_CAPTURE); + TRACE_AUD_MGR_I("[VOICEPATH][STOPED] Voice Path STOPED! "); + } + + if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + enum BT_DEVICE_ID_T sbc_id = bt_media_get_active_device_by_type(BT_STREAM_SBC); + TRACE_AUD_MGR_I("[VOICEPATH][STOPED] sbc_id %d",sbc_id); + if(sbc_id < BT_DEVICE_NUM) + { + bt_meida.media_curr_sbc = sbc_id; + } + } + else + { + bt_meida.media_curr_sbc = BT_DEVICE_NUM; + } + + TRACE_AUD_MGR_I("[VOICEPATH][STOPED] bt_meida.media_curr_sbc %d",bt_meida.media_curr_sbc); + + if(bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + } +#if !ISOLATED_AUDIO_STREAM_ENABLED + else if(bt_media_is_media_active_by_type(BT_STREAM_MEDIA)) + { + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_MEDIA); + } + else if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + enum BT_DEVICE_ID_T sbc_id = bt_media_get_active_device_by_type(BT_STREAM_SBC); + if(sbc_id < BT_DEVICE_NUM) + { +#ifdef __TWS__ + bt_media_clear_media_type(BT_STREAM_SBC,sbc_id); + bt_media_clear_current_media(BT_STREAM_SBC); + notify_tws_player_status(APP_BT_SETTING_OPEN); +#else + //bt_parse_store_sbc_sample_rate(app_bt_device.sample_rate[sbc_id]); + ret_SendReq2AudioThread = app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_SBC); +#endif + } + } +#endif + return true; +} +#endif + +#ifdef __AI_VOICE__ +bool bt_media_ai_voice_stop_process(uint16_t stream_type, enum BT_DEVICE_ID_T device_id) +{ + bt_media_clear_media_type(BT_STREAM_AI_VOICE, device_id); + //if current stream is the stop one ,stop it + if(bt_media_get_current_media() & BT_STREAM_AI_VOICE) + { + app_audio_sendrequest(APP_BT_STREAM_AI_VOICE, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_clear_current_media(BT_STREAM_AI_VOICE); + TRACE_AUD_MGR_I("[AI_VOICE][STOPED]"); + +#ifdef IBRT + if(!bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + app_ibrt_if_force_audio_retrigger(); + } +#endif + } + +#ifndef IBRT + enum BT_DEVICE_ID_T sbc_id = BT_DEVICE_NUM; + sbc_id = bt_media_get_active_device_by_type(BT_STREAM_SBC); + TRACE_AUD_MGR_I("[AI_VOICE][STOPED] sbc_id %d",sbc_id); + bt_meida.media_curr_sbc = sbc_id; + + TRACE_AUD_MGR_I("[AI_VOICE][STOPED] bt_meida.media_curr_sbc %d",bt_meida.media_curr_sbc); + + if(bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + } + else if(sbc_id < BT_DEVICE_NUM) + { + if(!(bt_media_get_current_media() & BT_STREAM_SBC)) + { + //bt_parse_store_sbc_sample_rate(app_bt_device.sample_rate[sbc_id]); + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, + (uint8_t)(APP_BT_SETTING_SETUP), + (uint32_t)(app_bt_device.sample_rate[sbc_id] & A2D_STREAM_SAMP_FREQ_MSK)); + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_SBC); + } + } +#endif + return true; +} +#endif + +#ifdef __THIRDPARTY +bool bt_media_thirdparty_voice_stop_process(uint16_t stream_type, enum BT_DEVICE_ID_T device_id) +{ + bt_media_clear_media_type(BT_STREAM_THIRDPARTY_VOICE, device_id); + //if current stream is the stop one ,stop it + if(bt_media_get_current_media() & BT_STREAM_THIRDPARTY_VOICE) + { + app_audio_sendrequest(APP_BT_STREAM_THIRDPARTY_VOICE, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_clear_current_media(BT_STREAM_THIRDPARTY_VOICE); + TRACE_AUD_MGR_I("THIRDPARTY VOICE STOPED! "); + } + return true; +} +#endif + +/* + bt_media_stop function is called to stop media by app or media play callback + sbc is just stop by a2dp stream suspend or close + voice is just stop by hfp audio disconnect + media is stop by media player finished call back + +*/ +void bt_media_stop(uint16_t stream_type,enum BT_DEVICE_ID_T device_id) +{ + TRACE_AUD_MGR_I("[HANDLE_STOP] type= 0x%x->:%s, device id = 0x%x",stream_type,strmtype2str(stream_type),device_id); +#ifdef __BT_ONE_BRING_TWO__ + TRACE_AUD_MGR_I("[HANDLE_STOP] media_active[0] = 0x%x->:%s", + bt_meida.media_active[0], strmtype2str(bt_meida.media_active[0])); + TRACE_AUD_MGR_I("[HANDLE_STOP] media_active[1] = 0x%x->:%s", + bt_meida.media_active[1], strmtype2str(bt_meida.media_active[1])); + TRACE_AUD_MGR_I("[HANDLE_STOP] curr_active_media = 0x%x->:%s", + bt_meida.curr_active_media, strmtype2str(bt_meida.curr_active_media)); +#else + TRACE_AUD_MGR_I("[HANDLE_STOP] media_active = 0x%x->:%s", + bt_meida.media_active[0], strmtype2str(bt_meida.media_active[0])); + TRACE_AUD_MGR_I("[HANDLE_STOP] curr_active_media = 0x%x->:%s", + bt_meida.curr_active_media, strmtype2str(bt_meida.curr_active_media)); +#endif + + if (!bt_media_is_media_active_by_device(stream_type, device_id)&& + !(bt_media_get_current_media()&stream_type)) + { + return; + } + + switch(stream_type) + { +#ifdef VOICE_DATAPATH + case BT_STREAM_CAPTURE: + bt_media_voicepath_stop_process(stream_type,device_id); + break; +#endif +#ifdef __AI_VOICE__ + case BT_STREAM_AI_VOICE: + bt_media_ai_voice_stop_process(stream_type, device_id); + break; +#endif +#ifdef __THIRDPARTY + case BT_STREAM_THIRDPARTY_VOICE: + bt_media_thirdparty_voice_stop_process(stream_type, device_id); + break; +#endif + + case BT_STREAM_SBC: + { +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + if (!audio_prompt_check_on_stopping_stream( + PENDING_TO_STOP_A2DP_STREAMING, device_id)) + { + TRACE_AUD_MGR_I("[HANDLE_STOP] Pending stop BT_STREAM_SBC"); + return; + } + +#else + if (app_ring_merge_isrun()) + { + TRACE_AUD_MGR_I("[HANDLE_STOP] pending BT_STREAM_SBC"); + app_ring_merge_save_pending_start_stream_op(PENDING_TO_STOP_A2DP_STREAMING, device_id); + return; + } +#endif + + uint8_t media_pre_sbc = bt_meida.media_curr_sbc; + TRACE_AUD_MGR_I("[HANDLE_STOP] SBC STOPPING id:%d/%d", bt_meida.media_curr_sbc, device_id); + + ////if current media is sbc ,stop the sbc streaming + bt_media_clear_media_type(stream_type,device_id); + + //if current stream is the stop one ,so stop it + if ((bt_media_get_current_media() & BT_STREAM_SBC) +#if !defined(IBRT) + && bt_meida.media_curr_sbc == device_id +#endif + ) + { + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_clear_current_media(BT_STREAM_SBC); + TRACE_AUD_MGR_I("[HANDLE_STOP] SBC STOPED!"); + } + + if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + enum BT_DEVICE_ID_T sbc_id = bt_media_get_active_device_by_type(BT_STREAM_SBC); + if(sbc_id < BT_DEVICE_NUM) + { + bt_meida.media_curr_sbc = sbc_id; + } + } + else + { + bt_meida.media_curr_sbc = BT_DEVICE_NUM; + } + + if(bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + + } + else if(bt_media_is_media_active_by_type(BT_STREAM_MEDIA)) + { + //do nothing + } +#ifdef VOICE_DATAPATH +#if !ISOLATED_AUDIO_STREAM_ENABLED + else if(bt_media_is_media_active_by_type(BT_STREAM_CAPTURE)) + { + //do nothing + } +#endif +#endif + else if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + enum BT_DEVICE_ID_T sbc_id = bt_media_get_active_device_by_type(BT_STREAM_SBC); + if (sbc_id < BT_DEVICE_NUM && + (media_pre_sbc != bt_meida.media_curr_sbc)) + { + app_audio_manager_switch_a2dp(sbc_id); + bt_media_set_current_media(BT_STREAM_SBC); + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, + (uint8_t)(APP_BT_SETTING_SETUP), + (uint32_t)(app_bt_device.sample_rate[sbc_id] & A2D_STREAM_SAMP_FREQ_MSK)); + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_OPEN, 0); + } + } + } + break; +#ifdef MEDIA_PLAYER_SUPPORT + case BT_STREAM_MEDIA: + bt_media_clear_media_type(BT_STREAM_MEDIA,device_id); + + if(bt_media_is_media_active_by_type(BT_STREAM_MEDIA)) + { + //also have media report so do nothing + } + else if(bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + if(bt_media_get_current_media() & BT_STREAM_VOICE) + { + //do nothing + } + else if(bt_media_get_current_media() & BT_STREAM_MEDIA) + { + ///media report is end ,so goto voice + uint8_t curr_sco_id; + curr_sco_id = app_audio_manager_get_active_sco_num(); + if (curr_sco_id!=BT_DEVICE_NUM) + { + bt_media_set_media_type(BT_STREAM_VOICE, (enum BT_DEVICE_ID_T)curr_sco_id); + bt_media_set_current_media(BT_STREAM_VOICE); +#ifdef __BT_ONE_BRING_TWO__ + app_audio_manager_swap_sco((enum BT_DEVICE_ID_T)curr_sco_id); +#endif + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_OPEN, 0); + } + } + + } + else if (btapp_hfp_is_call_active()) + { + //do nothing + } + +#ifdef VOICE_DATAPATH +#if !ISOLATED_AUDIO_STREAM_ENABLED + else if(bt_media_is_media_active_by_type(BT_STREAM_CAPTURE)) + { + app_audio_sendrequest(APP_BT_STREAM_VOICEPATH, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_CAPTURE); + } +#endif +#endif +#ifdef __AI_VOICE__ + else if(bt_media_is_media_active_by_type(BT_STREAM_AI_VOICE) || ai_if_is_ai_stream_mic_open()) + { + bt_media_clear_current_media(BT_STREAM_MEDIA); + if (bt_media_is_media_active_by_type(BT_STREAM_AI_VOICE) && !(bt_media_get_current_media() & BT_STREAM_AI_VOICE)) + { + app_audio_sendrequest(APP_BT_STREAM_AI_VOICE, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_AI_VOICE); + } + } +#endif + else if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + ///if another device is also in sbc mode + enum BT_DEVICE_ID_T sbc_id = bt_media_get_active_sbc_device(); + bt_media_set_media_type(BT_STREAM_SBC, sbc_id); + app_audio_manager_switch_a2dp(sbc_id); + bt_media_set_current_media(BT_STREAM_SBC); + + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, + (uint8_t)(APP_BT_SETTING_SETUP), + (uint32_t)(app_bt_device.sample_rate[sbc_id] & A2D_STREAM_SAMP_FREQ_MSK)); + + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_OPEN, 0); + } + else + { + //have no meida task,so goto idle + bt_media_set_current_media(0); + } + break; +#endif + case BT_STREAM_VOICE: + + if(!bt_media_is_media_active_by_device(BT_STREAM_VOICE,device_id)||!(bt_media_get_current_media() & BT_STREAM_VOICE)) + { + TRACE_AUD_MGR_I("[HANDLE_STOP] bt_media_stop already stop"); + bt_media_clear_media_type(stream_type, device_id); + return ; + } + +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + if (!audio_prompt_check_on_stopping_stream( + PENDING_TO_STOP_SCO_STREAMING, device_id)) + { + return; + } + +#else + if (app_ring_merge_isrun()) + { + TRACE_AUD_MGR_I("[HANDLE_STOP] bt_media_stop pending BT_STREAM_VOICE"); + app_ring_merge_save_pending_start_stream_op(PENDING_TO_STOP_SCO_STREAMING, device_id); + return; + } +#endif + + app_audio_manager_set_active_sco_num(BT_DEVICE_NUM); + bt_media_clear_media_type(stream_type, device_id); + +#ifdef MEDIA_PLAYER_SUPPORT + if(bt_media_is_media_active_by_type(BT_STREAM_MEDIA)) + { + if(bt_media_get_current_media() & BT_STREAM_MEDIA) + { + //do nothing + } + +#ifdef VOICE_DATAPATH +#if !ISOLATED_AUDIO_STREAM_ENABLED + else if(bt_media_is_media_active_by_type(BT_STREAM_CAPTURE)) + { + bt_media_clear_all_media_type(); + app_audio_sendrequest(APP_BT_STREAM_VOICEPATH, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_CAPTURE); + } +#endif +#endif + else if (bt_media_get_current_media() & BT_STREAM_VOICE) + { + TRACE_AUD_MGR_W("[HANDLE_STOP] voice and media is all on,media should be the current media"); + if(!bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_CLOSE, 0); + } + } + else if (bt_media_get_current_media() & BT_STREAM_SBC) + { + TRACE_AUD_MGR_W("[HANDLE_STOP] voice and media is all on,media should be the current media"); + if(!bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_CLOSE, 0); + } + } + } + else +#endif + if(bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { +#ifdef __BT_ONE_BRING_TWO__ + if(bt_get_sco_number()>1 +#ifdef CHIP_BEST1000 + && hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2 +#endif + ) + { + TRACE_AUD_MGR_W("[HANDLE_STOP] bt_media_stop, but another soc need connect"); + enum BT_DEVICE_ID_T voice_dev_id = bt_media_get_active_device_by_type(BT_STREAM_VOICE); +#ifdef HFP_NO_PRERMPT + app_audio_manager_set_active_sco_num(voice_dev_id); +#else + app_audio_manager_swap_sco(voice_dev_id); +#ifdef __HF_KEEP_ONE_ALIVE__ + enum BT_DEVICE_ID_T other_voice_dev_id = (voice_dev_id == BT_DEVICE_ID_1) ? BT_DEVICE_ID_2 : BT_DEVICE_ID_1;; + if (btif_hf_check_AudioConnect_status(app_bt_device.hf_channel[other_voice_dev_id])) + { + TRACE_AUD_MGR_I("[HANDLE_STOP] Disconnect another AudioLink"); + app_bt_HF_DisconnectAudioLink(app_bt_device.hf_channel[other_voice_dev_id]); + } +#endif +#endif + } + bt_media_set_current_media(BT_STREAM_VOICE); +#endif + } + else if (btapp_hfp_is_call_active()) + { + TRACE_AUD_MGR_I("[HANDLE_STOP] stop in HF_CALL_ACTIVE and no sco need"); + bt_media_set_current_media(0); + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_CLOSE, 0); + bt_media_clear_media_type(BT_STREAM_VOICE, device_id); + { + enum BT_DEVICE_ID_T sbc_id = bt_media_get_active_sbc_device(); + if(sbc_id < BT_DEVICE_NUM ) + { + app_audio_manager_switch_a2dp(sbc_id); + bt_media_set_current_media(BT_STREAM_SBC); + app_audio_sendrequest( APP_BT_STREAM_A2DP_SBC, + (uint8_t)(APP_BT_SETTING_SETUP), + (uint32_t)(app_bt_device.sample_rate[sbc_id] & A2D_STREAM_SAMP_FREQ_MSK)); + app_audio_sendrequest( APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_OPEN, 0); + } + } + } +#ifdef VOICE_DATAPATH +#if !ISOLATED_AUDIO_STREAM_ENABLED + else if(bt_media_is_media_active_by_type(BT_STREAM_CAPTURE)) + { + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_CLOSE, 0); + app_audio_sendrequest(APP_BT_STREAM_VOICEPATH, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_CAPTURE); + } +#endif +#endif + else if(bt_media_is_media_active_by_type(BT_STREAM_SBC)) + { + ///if another device is also in sbc mode + enum BT_DEVICE_ID_T sbc_id = bt_media_get_active_sbc_device(); + if( sbc_id < BT_DEVICE_NUM /*&& device_id == sbc_id*/ ) + { + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_CLOSE, 0); + app_audio_manager_switch_a2dp(sbc_id); + bt_media_set_current_media(BT_STREAM_SBC); + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, + (uint8_t)(APP_BT_SETTING_SETUP), + (uint32_t)(app_bt_device.sample_rate[sbc_id] & A2D_STREAM_SAMP_FREQ_MSK)); + app_audio_sendrequest(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_OPEN, 0); + } + } + else + { + bt_media_set_current_media(0); + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_CLOSE, 0); + } + +#if ISOLATED_AUDIO_STREAM_ENABLED +#ifdef VOICE_DATAPATH + if(bt_media_is_media_active_by_type(BT_STREAM_CAPTURE)) + { + app_audio_sendrequest(APP_BT_STREAM_VOICEPATH, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_CAPTURE); + } +#endif +#endif +#ifdef __THIRDPARTY + if(bt_media_is_media_active_by_type(BT_STREAM_THIRDPARTY_VOICE)) { + app_audio_sendrequest(APP_BT_STREAM_THIRDPARTY_VOICE, (uint8_t)APP_BT_SETTING_OPEN, 0); + bt_media_set_current_media(BT_STREAM_THIRDPARTY_VOICE); + } +#endif + break; +#ifdef RB_CODEC + case BT_STREAM_RBCODEC: + bt_media_rbcodec_stop_process(stream_type, device_id, 0); + break; +#endif +#ifdef AUDIO_LINEIN + case BT_STREAM_LINEIN: + if(bt_media_is_media_active_by_type(BT_STREAM_LINEIN)) + { + app_audio_sendrequest(APP_PLAY_LINEIN_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE, 0); + if(bt_media_get_current_media() & BT_STREAM_LINEIN) + bt_media_set_current_media(0); + + bt_media_clear_media_type(stream_type,device_id); + } + break; +#endif + default: + ASSERT(0,"[HANDLE_STOP] ERROR TYPE: %x", stream_type); + break; + } +#ifdef __BT_ONE_BRING_TWO__ + TRACE_AUD_MGR_I("[HANDLE_STOP] end media_active = %x,%x,curr_active_media = %x", + bt_meida.media_active[0],bt_meida.media_active[1], bt_meida.curr_active_media); +#else + TRACE_AUD_MGR_I("[HANDLE_STOP] end media_active = %x%s", + bt_meida.media_active[0], strmtype2str(bt_meida.media_active[0])); + TRACE_AUD_MGR_I("[HANDLE_STOP] end curr_active_media = %x%s", + bt_meida.curr_active_media, strmtype2str(bt_meida.curr_active_media)); +#endif +} + +void app_media_stop_media(uint16_t stream_type,enum BT_DEVICE_ID_T device_id) +{ +#ifdef MEDIA_PLAYER_SUPPORT +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + audio_prompt_stop_playing(); +#endif + + if(bt_media_is_media_active_by_type(BT_STREAM_MEDIA) || app_audio_list_playback_exist()) + { +#ifdef __AUDIO_QUEUE_SUPPORT__ + ////should have no sbc + app_audio_list_clear(); +#endif + if(bt_media_get_current_media() & BT_STREAM_MEDIA) + { + TRACE_AUD_MGR_I("[STOP_MEDIA]"); + //bt_media_set_current_media(0); + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE, 0); + } + bt_media_clear_media_type(BT_STREAM_MEDIA, device_id); + if(bt_media_is_media_active_by_type(BT_STREAM_VOICE)) + { + enum BT_DEVICE_ID_T currScoId = BT_DEVICE_NUM; + currScoId = (enum BT_DEVICE_ID_T)app_audio_manager_get_active_sco_num(); + + if (currScoId == BT_DEVICE_NUM) + { + for (uint8_t i=0; ibdAddr.addr, 6); + btif_hf_get_remote_bdaddr(app_bt_device.hf_channel[bt_meida.media_curr_sco], &bdaddr); + DUMP8("%02x ", bdaddr.address, 6); +#if defined(HFP_1_6_ENABLE) + uint32_t code_type; + uint32_t code_type_reg; + code_type = app_audio_manager_get_scocodecid(); + code_type_reg = BTDIGITAL_REG(0xD0222000); + if (code_type == BTIF_HF_SCO_CODEC_MSBC) + { + BTDIGITAL_REG(0xD0222000) = (code_type_reg & (~(7<<1))) | (3<<1); + TRACE_AUD_MGR_I("[SCO_CHK] MSBC REG:0xD0222000=0x%08x B:%d", BTDIGITAL_REG(0xD0222000), (BTDIGITAL_REG(0xD0222000)>>15)&1); + + } + else + { + BTDIGITAL_REG(0xD0222000) = (code_type_reg & (~(7<<1))) | (2<<1); + TRACE_AUD_MGR_I("[SCO_CHK] CVSD REG:0xD0222000=0x%08x B:%d", BTDIGITAL_REG(0xD0222000), (BTDIGITAL_REG(0xD0222000)>>15)&1); + } +#else + uint32_t code_type_reg; + code_type_reg = BTDIGITAL_REG(0xD0222000); + BTDIGITAL_REG(0xD0222000) = (code_type_reg & (~(7<<1))) | (2<<1); + TRACE_AUD_MGR_I("[SCO_CHK] CVSD REG:0xD0222000=0x%08x B:%d", BTDIGITAL_REG(0xD0222000), (BTDIGITAL_REG(0xD0222000)>>15)&1); +#endif + } +#else +#if defined(DEBUG) +#if defined(IBRT) + if (app_tws_ibrt_mobile_link_connected()) +#endif + { + hf_chan_handle_t hf_chan = app_bt_device.hf_channel[bt_meida.media_curr_sco]; + if (hf_chan && (cmgrHandler = btif_hf_get_chan_manager_handler(hf_chan))) + { + TRACE_AUD_MGR_I("[SCO_CHK] curSco:%d type:%d Interval:%d", + bt_meida.media_curr_sco, + btif_cmgr_get_sco_connect_sco_link_type(cmgrHandler), + btif_cmgr_get_sco_connect_sco_rx_parms_sco_transmission_interval(cmgrHandler)); + } + } +#endif +#endif + TRACE_AUD_MGR_I("[SCO_CHK] exit"); + return 0; +} + +int app_audio_manager_swap_sco(enum BT_DEVICE_ID_T id) +{ + if(bt_get_sco_number()<=1) + return 0; +#if defined(HFP_1_6_ENABLE) + uint8_t curr_sco_id; + curr_sco_id = app_audio_manager_get_active_sco_num(); +#endif + bt_bdaddr_t bdAdd; + uint16_t scohandle; + //if (HF_GetRemoteBDAddr(&app_bt_device.hf_channel[id], &bdAdd)){ + if ( btif_hf_get_remote_bdaddr(app_bt_device.hf_channel[id], &bdAdd)) + { + //TRACE_AUD_MGR_I("[SCO SWAP]switch_sco to id:%d sco:%x", id, app_bt_device.hf_channel[id].cmgrHandler.scoConnect); + + //DUMP8("%02x ", app_bt_device.hf_channel[id].cmgrHandler.remDev->bdAddr.addr, 6); + //DUMP8("%02x ", bdAdd.address, 6); + + /* + TRACE_AUD_MGR_I("[SCO_SWAP] state:%d type:%d hdl:%x ", app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scostate, + app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoLinkType, + app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoHciHandle); + TRACE_AUD_MGR_I("[SCO_SWAP] tx[bw:%d rbw:%d ml:%d vs:%d rt:%d pktyp:%d]", app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoTxParms.transmitBandwidth, + app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoTxParms.receiveBandwidth, + app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoTxParms.maxLatency, + app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoTxParms.voiceSetting, + app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoTxParms.retransmissionEffort, + app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoTxParms.eScoPktType); + + TRACE_AUD_MGR_I("[SCO_SWAP] rx[itv:%d ret:%d rxl:%d txl:%d]", app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoRxParms.scoTransmissionInterval, + app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoRxParms.scoRetransmissionWindow, + app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoRxParms.scoRxPacketLen, + app_bt_device.hf_channel[id].cmgrHandler.scoConnect->scoRxParms.scoTxPacketLen); + */ + + app_audio_manager_set_active_sco_num(id); + scohandle = btif_hf_get_sco_hcihandle(app_bt_device.hf_channel[id]); + if (scohandle != BTIF_HCI_INVALID_HANDLE) + { + app_bt_Me_switch_sco(scohandle); + } + app_bt_stream_volume_ptr_update(bdAdd.address); + app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_SET, app_bt_stream_volume_get_ptr()->hfp_vol); +#if defined(HFP_1_6_ENABLE) + if(curr_sco_id != id) + { + TRACE_AUD_MGR_I("[SCO_SWAP] try restart"); + bt_sco_player_forcemute(true,true); + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_RESTART, 0); + } +#endif + app_audio_manager_sco_status_checker(); + } + return 0; +} + +int app_audio_manager_ctrl_volume_handle(APP_MESSAGE_BODY *msg_body) +{ + enum APP_AUDIO_MANAGER_VOLUME_CTRL_T volume_ctrl; + uint16_t volume_level = 0; + + volume_ctrl = (enum APP_AUDIO_MANAGER_VOLUME_CTRL_T)msg_body->message_ptr; + volume_level = (uint16_t)msg_body->message_Param0; + + switch (volume_ctrl) + { + case APP_AUDIO_MANAGER_VOLUME_CTRL_SET: + app_bt_stream_volumeset(volume_level); + break; + case APP_AUDIO_MANAGER_VOLUME_CTRL_UP: + app_bt_stream_volumeup(); + btapp_hfp_report_speak_gain(); + btapp_a2dp_report_speak_gain(); + break; + case APP_AUDIO_MANAGER_VOLUME_CTRL_DOWN: + app_bt_stream_volumedown(); + btapp_hfp_report_speak_gain(); + btapp_a2dp_report_speak_gain(); + break; + default: + break; + } + + return 0; +} + +int app_audio_manager_tune_samplerate_ratio_handle(APP_MESSAGE_BODY *msg_body) +{ + enum AUD_STREAM_T stream = AUD_STREAM_NUM; + float ratio = 1.0f; + + stream = (enum AUD_STREAM_T)msg_body->message_ptr; + ratio = *(float *)&msg_body->message_Param0; + + TRACE_AUD_MGR_I("[TUNE] %d", (int32_t)(ratio * 10000000)); + af_codec_tune(stream, ratio); + + return 0; +} + +static bool app_audio_manager_init = false; + + +int app_audio_manager_sendrequest(uint8_t massage_id, uint16_t stream_type, uint8_t device_id, uint16_t aud_id) +{ + uint32_t audevt; + uint32_t msg0; + APP_MESSAGE_BLOCK msg; + + if(app_audio_manager_init == false) + return -1; + + // only allow prompt playing if powering-off is on-going + if (app_is_power_off_in_progress()) + { + if ((APP_BT_STREAM_MANAGER_START == massage_id) && + (BT_STREAM_MEDIA != stream_type)) + { + return -1; + } + } + + msg.mod_id = APP_MODUAL_AUDIO_MANAGE; + APP_AUDIO_MANAGER_SET_MESSAGE(audevt, massage_id, stream_type); + APP_AUDIO_MANAGER_SET_MESSAGE0(msg0,device_id,aud_id); + msg.msg_body.message_id = audevt; + msg.msg_body.message_ptr = msg0; + msg.msg_body.message_Param0 = msg0; + msg.msg_body.message_Param1 = 0; + msg.msg_body.message_Param2 = 0; + app_mailbox_put(&msg); + + return 0; +} + +int app_audio_manager_sendrequest_need_callback( + uint8_t massage_id, uint16_t stream_type, uint8_t device_id, uint16_t aud_id, uint32_t cb, uint32_t cb_param) +{ + uint32_t audevt; + uint32_t msg0; + APP_MESSAGE_BLOCK msg; + + if(app_audio_manager_init == false) + return -1; + + msg.mod_id = APP_MODUAL_AUDIO_MANAGE; + APP_AUDIO_MANAGER_SET_MESSAGE(audevt, massage_id, stream_type); + APP_AUDIO_MANAGER_SET_MESSAGE0(msg0,device_id,aud_id); + msg.msg_body.message_id = audevt; + msg.msg_body.message_ptr = msg0; + msg.msg_body.message_Param0 = msg0; + msg.msg_body.message_Param1 = cb; + msg.msg_body.message_Param2 = cb_param; + app_mailbox_put(&msg); + + return 0; +} + +int app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_T volume_ctrl, uint16_t volume_level) +{ + uint32_t audevt; + APP_MESSAGE_BLOCK msg; + osThreadId currThreadId; + + if(app_audio_manager_init == false) + return -1; + + msg.mod_id = APP_MODUAL_AUDIO_MANAGE; + APP_AUDIO_MANAGER_SET_MESSAGE(audevt, APP_BT_STREAM_MANAGER_CTRL_VOLUME, 0); + msg.msg_body.message_id = audevt; + msg.msg_body.message_ptr = (uint32_t)volume_ctrl; + msg.msg_body.message_Param0 = (uint32_t)volume_level; + msg.msg_body.message_Param1 = 0; + msg.msg_body.message_Param2 = 0; + currThreadId = osThreadGetId(); + if (currThreadId == af_thread_tid_get() || + currThreadId == app_os_tid_get()) + { + app_audio_manager_ctrl_volume_handle(&msg.msg_body); + } + else + { + app_mailbox_put(&msg); + } + return 0; +} + +int app_audio_manager_tune_samplerate_ratio(enum AUD_STREAM_T stream, float ratio) +{ + uint32_t audevt; + APP_MESSAGE_BLOCK msg; + osThreadId currThreadId; + + if(app_audio_manager_init == false) + return -1; + + msg.mod_id = APP_MODUAL_AUDIO_MANAGE; + APP_AUDIO_MANAGER_SET_MESSAGE(audevt, APP_BT_STREAM_MANAGER_TUNE_SAMPLERATE_RATIO, 0); + msg.msg_body.message_id = audevt; + msg.msg_body.message_ptr = (uint32_t)stream; + msg.msg_body.message_Param0 = *(uint32_t *)∶ + msg.msg_body.message_Param1 = 0; + msg.msg_body.message_Param2 = 0; + + currThreadId = osThreadGetId(); + if (currThreadId == af_thread_tid_get() || + currThreadId == app_os_tid_get()) + { + app_audio_manager_tune_samplerate_ratio_handle(&msg.msg_body); + } + else + { + app_mailbox_put(&msg); + } + + return 0; +} + + +#if defined(VOICE_DATAPATH) && defined(MIX_MIC_DURING_MUSIC) +static bool app_audio_handle_pre_processing(APP_MESSAGE_BODY *msg_body) +{ + uint16_t stream_type; + APP_AUDIO_MANAGER_GET_STREAM_TYPE(msg_body->message_id, stream_type); + + bool isToResetCaptureStream = false; + if ((BT_STREAM_SBC == stream_type) || (BT_STREAM_MEDIA == stream_type)) + { + if (app_audio_manager_capture_is_active()) + { + isToResetCaptureStream = true; + } + } + + if (isToResetCaptureStream) + { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP, + BT_STREAM_CAPTURE, 0, 0); + + APP_MESSAGE_BLOCK msg; + msg.msg_body = *msg_body; + msg.mod_id = APP_MODUAL_AUDIO_MANAGE; + + app_mailbox_put(&msg); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START, + BT_STREAM_CAPTURE, 0, 0); + + return false; + } + else + { + return true; + } +} +#endif + +static int app_audio_manager_handle_process(APP_MESSAGE_BODY *msg_body) +{ + int nRet = 0; + + APP_AUDIO_MANAGER_MSG_STRUCT aud_manager_msg; + APP_AUDIO_MANAGER_CALLBACK_T callback_fn = NULL; + uint32_t callback_param = 0; + + if(app_audio_manager_init == false) + return -1; + +#if defined(VOICE_DATAPATH) && defined(MIX_MIC_DURING_MUSIC) + bool isContinue = app_audio_handle_pre_processing(msg_body); + if (!isContinue) + { + return -1; + } +#endif + + APP_AUDIO_MANAGER_GET_ID(msg_body->message_id, aud_manager_msg.id); + APP_AUDIO_MANAGER_GET_STREAM_TYPE(msg_body->message_id, aud_manager_msg.stream_type); + APP_AUDIO_MANAGER_GET_DEVICE_ID(msg_body->message_Param0, aud_manager_msg.device_id); + APP_AUDIO_MANAGER_GET_AUD_ID(msg_body->message_Param0, aud_manager_msg.aud_id); + APP_AUDIO_MANAGER_GET_CALLBACK((uintptr_t)msg_body->message_Param1, callback_fn); + APP_AUDIO_MANAGER_GET_CALLBACK_PARAM(msg_body->message_Param2, callback_param); + + TRACE_AUD_MGR_I( + "[handle_process] id %d %s type 0x%x %s", + aud_manager_msg.id, + handleId2str(aud_manager_msg.id), + aud_manager_msg.stream_type, + strmtype2str(aud_manager_msg.stream_type)); + + switch (aud_manager_msg.id) + { + case APP_BT_STREAM_MANAGER_START: + bt_media_start(aud_manager_msg.stream_type,(enum BT_DEVICE_ID_T) aud_manager_msg.device_id, aud_manager_msg.aud_id); + break; + case APP_BT_STREAM_MANAGER_STOP: + bt_media_stop(aud_manager_msg.stream_type, (enum BT_DEVICE_ID_T)aud_manager_msg.device_id); + break; + case APP_BT_STREAM_MANAGER_SWITCHTO_SCO: + bt_media_switch_to_voice(aud_manager_msg.stream_type, (enum BT_DEVICE_ID_T)aud_manager_msg.device_id); + break; + case APP_BT_STREAM_MANAGER_STOP_MEDIA: + app_media_stop_media(aud_manager_msg.stream_type, (enum BT_DEVICE_ID_T)aud_manager_msg.device_id); + break; + case APP_BT_STREAM_MANAGER_UPDATE_MEDIA: + app_media_update_media(aud_manager_msg.stream_type, (enum BT_DEVICE_ID_T)aud_manager_msg.device_id); + break; + case APP_BT_STREAM_MANAGER_SWAP_SCO: + app_audio_manager_swap_sco((enum BT_DEVICE_ID_T)aud_manager_msg.device_id); + break; + case APP_BT_STREAM_MANAGER_CTRL_VOLUME: + app_audio_manager_ctrl_volume_handle(msg_body); + break; + case APP_BT_STREAM_MANAGER_TUNE_SAMPLERATE_RATIO: + app_audio_manager_tune_samplerate_ratio_handle(msg_body); + break; + default: + break; + } + if (callback_fn) + { + callback_fn(aud_manager_msg.id, callback_param); + } + return nRet; +} + +void bt_media_volume_ptr_update_by_mediatype(uint16_t stream_type) +{ + bt_bdaddr_t *bdAdd =NULL; + bt_bdaddr_t temp; + btif_remote_device_t *remDev = NULL; + uint8_t id; + + TRACE_AUD_MGR_I("[VOLUME_PTR] enter"); + if (stream_type & bt_media_get_current_media()) + { + switch (stream_type) + { + case BT_STREAM_SBC: + id = bt_meida.media_curr_sbc; + ASSERT(idaddress); + } + break; + case BT_STREAM_VOICE: + id = app_audio_manager_get_active_sco_num(); + ASSERT(idaddress); + } + break; + case BT_STREAM_MEDIA: + default: + break; + } + } + TRACE_AUD_MGR_I("[VOLUME_PTR] exit"); +} + +int app_audio_manager_set_active_sco_num(enum BT_DEVICE_ID_T id) +{ + bt_meida.media_curr_sco = id; + return 0; +} + +int app_audio_manager_get_active_sco_num(void) +{ + return bt_meida.media_curr_sco; +} + +hf_chan_handle_t* app_audio_manager_get_active_sco_chnl(void) +{ + int curr_sco; + + curr_sco = app_audio_manager_get_active_sco_num(); + if (curr_sco != BT_DEVICE_NUM) + { + return &app_bt_device.hf_channel[curr_sco]; + } + return NULL; +} + +#if defined(HFP_1_6_ENABLE) +#ifdef __BT_ONE_BRING_TWO__ +static uint16_t app_audio_manage_scocodecid[BT_DEVICE_NUM] = {BTIF_HF_SCO_CODEC_CVSD, BTIF_HF_SCO_CODEC_CVSD}; +#else +static uint16_t app_audio_manage_scocodecid[BT_DEVICE_NUM] = {BTIF_HF_SCO_CODEC_CVSD}; +#endif + +int app_audio_manager_set_scocodecid(enum BT_DEVICE_ID_T dev_id, uint16_t codec_id) +{ + app_audio_manage_scocodecid[dev_id] = codec_id; + return 0; +} + +int app_audio_manager_get_scocodecid(void) +{ + int scocodecid = BTIF_HF_SCO_CODEC_NONE; + if (bt_meida.media_curr_sco != BT_DEVICE_NUM) + { + scocodecid = app_audio_manage_scocodecid[bt_meida.media_curr_sco]; + } + return scocodecid; +} +#endif + + +int app_audio_manager_switch_a2dp(enum BT_DEVICE_ID_T id) +{ + bt_bdaddr_t* bdAdd =NULL; + btif_remote_device_t *remDev = NULL; + +#ifndef __MULTIPOINT_A2DP_PREEMPT__ + if(bt_meida.media_curr_sbc == id) + { + TRACE_AUD_MGR_I("[A2DP_SWITCH]the disconnected dev not working"); + return 0; + } +#endif + + remDev = btif_a2dp_get_remote_device(app_bt_device.a2dp_connected_stream[id]); + if (remDev) + { + TRACE_AUD_MGR_I("[A2DP_SWITCH] switch_a2dp to id:%d", id); + bdAdd = btif_me_get_remote_device_bdaddr(remDev); + app_bt_stream_volume_ptr_update(bdAdd->address); + bt_meida.media_curr_sbc = id; + } + return 0; +} + +bool app_audio_manager_a2dp_is_active(enum BT_DEVICE_ID_T id) +{ + uint16_t media_type; + bool nRet = false; + + media_type = bt_media_get_current_media(); + if (media_type & BT_STREAM_SBC) + { + if (bt_meida.media_curr_sbc == id) + { + nRet = true; + } + } + +#ifndef BES_AUTOMATE_TEST + TRACE_AUD_MGR_I("[A2DP_ACTIVE] nRet:%d type:%d %d/%d", nRet, media_type, id, bt_meida.media_curr_sbc); +#endif + return nRet; +} + +bool app_audio_manager_hfp_is_active(enum BT_DEVICE_ID_T id) +{ + uint16_t media_type; + bool nRet = false; + + media_type = bt_media_get_current_media(); + if (media_type & BT_STREAM_VOICE) + { + if (bt_meida.media_curr_sco == id) + { + nRet = true; + } + } + +#ifndef BES_AUTOMATE_TEST + TRACE_AUD_MGR_I("[SCO_ACTIVE] nRet:%d type:%d %d/%d", nRet, media_type, id, bt_meida.media_curr_sco); +#endif + return nRet; +} + +#ifdef VOICE_DATAPATH +bool app_audio_manager_capture_is_active(void) +{ + uint16_t media_type; + bool nRet = false; + + media_type = bt_media_get_current_media(); + if (media_type & BT_STREAM_CAPTURE) + { + nRet = true; + } + + return nRet; +} +#endif + +bool app_audio_manager_media_is_active(void) +{ + uint16_t media_type; + bool nRet = false; + + media_type = bt_media_get_current_media(); + if (media_type & BT_STREAM_MEDIA) + { + nRet = true; + } + + return nRet; +} + +void app_audio_manager_open(void) +{ + if(app_audio_manager_init) + { + return; + } + bt_meida.media_curr_sbc = BT_DEVICE_NUM; + bt_meida.media_curr_sco = BT_DEVICE_NUM; + bt_meida.curr_active_media = 0; + app_set_threadhandle(APP_MODUAL_AUDIO_MANAGE, app_audio_manager_handle_process); + app_audio_manager_init = true; + +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + audio_prompt_init_handler(); +#endif +} + +void app_audio_manager_close(void) +{ + app_set_threadhandle(APP_MODUAL_AUDIO_MANAGE, NULL); + app_audio_manager_init = false; +} + +#ifdef RB_CODEC + +static bool app_rbcodec_play_status = false; + +static bool app_rbplay_player_mode = false; + +bool app_rbplay_is_localplayer_mode(void) +{ + return app_rbplay_player_mode; +} + +bool app_rbplay_mode_switch(void) +{ + return (app_rbplay_player_mode = !app_rbplay_player_mode); +} + +void app_rbplay_set_player_mode(bool isInPlayerMode) +{ + app_rbplay_player_mode = isInPlayerMode; +} + +void app_rbcodec_ctr_play_onoff(bool on ) +{ + TRACE_AUD_MGR_I("[RBCODEC] onoff %d ,turnon:%d ", app_rbcodec_play_status,on); + + if(app_rbcodec_play_status == on) + return; + app_rbcodec_play_status = on; + if(on) + app_audio_manager_sendrequest( APP_BT_STREAM_MANAGER_START, BT_STREAM_RBCODEC, 0, 0); + else + app_audio_manager_sendrequest( APP_BT_STREAM_MANAGER_STOP, BT_STREAM_RBCODEC, 0, 0); +} + +void app_rbcodec_ctl_set_play_status(bool st) +{ + app_rbcodec_play_status = st; + TRACE_AUD_MGR_I("[RBCODEC] curr_status%d", app_rbcodec_play_status); +} + +bool app_rbcodec_get_play_status(void) +{ + TRACE_AUD_MGR_I("[RBCODEC] play_status:%d", app_rbcodec_play_status); + return app_rbcodec_play_status; +} + +void app_rbcodec_toggle_play_stop(void) +{ + if(app_rbcodec_get_play_status()) + { + app_rbcodec_ctr_play_onoff(false); + } + else + { + app_rbcodec_ctr_play_onoff(true); + } +} + +bool app_rbcodec_check_hfp_active(void ) +{ + return (bool)bt_media_is_media_active_by_type(BT_STREAM_VOICE); +} +#endif + +void app_ibrt_sync_mix_prompt_req_handler(uint8_t* ptrParam, uint16_t paramLen) +{ +#ifdef TWS_PROMPT_SYNC + app_tws_cmd_sync_mix_prompt_req_handler(ptrParam, paramLen); +#endif +} + +void app_audio_decode_err_force_trigger(void) +{ +#ifndef IBRT + trigger_media_play((AUD_ID_ENUM)AUDIO_ID_BT_MUTE, 0, false); +#endif +} + + + diff --git a/services/bt_app/app_bt_media_manager.h b/services/bt_app/app_bt_media_manager.h new file mode 100644 index 0000000..247e59e --- /dev/null +++ b/services/bt_app/app_bt_media_manager.h @@ -0,0 +1,144 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BT_MEDIA_MANAGER_H__ +#define __APP_BT_MEDIA_MANAGER_H__ + +#include "resources.h" +#ifdef __cplusplus +extern "C" { +#endif +#include "btapp.h" + +#define BT_STREAM_DIRECTION_OUT 0 +#define BT_STREAM_DIRECTION_IN 1 + +// direction is out +#define BT_STREAM_SBC 0x1 +#define BT_STREAM_MEDIA 0x2 +#define BT_STREAM_VOICE 0x4 +#ifdef AUDIO_LINEIN +#define BT_STREAM_LINEIN 0x8 +#endif +#ifdef RB_CODEC +#define BT_STREAM_RBCODEC 0x10 //from rockbox decoder +#endif + +// direction is in +#ifdef VOICE_DATAPATH +#define BT_STREAM_CAPTURE 0x100 +#endif + +#ifdef __AI_VOICE__ +#define BT_STREAM_AI_VOICE 0x200 +#endif + +#define BT_STREAM_THIRDPARTY_VOICE 0x400 + +#define BT_STREAM_TYPE_MASK (BT_STREAM_SBC | BT_STREAM_MEDIA | BT_STREAM_VOICE) + + +enum APP_BT_MEDIA_MANAGER_ID_T { + APP_BT_STREAM_MANAGER_START = 0, + APP_BT_STREAM_MANAGER_STOP, + APP_BT_STREAM_MANAGER_SWITCHTO_SCO, + APP_BT_STREAM_MANAGER_STOP_MEDIA, + APP_BT_STREAM_MANAGER_UPDATE_MEDIA, + APP_BT_STREAM_MANAGER_SWAP_SCO, + APP_BT_STREAM_MANAGER_CTRL_VOLUME, + APP_BT_STREAM_MANAGER_TUNE_SAMPLERATE_RATIO, + APP_BT_STREAM_MANAGER_NUM, +}; + +typedef struct { + uint8_t id; + uint16_t stream_type; + uint8_t device_id; + uint16_t aud_id; + +}APP_AUDIO_MANAGER_MSG_STRUCT; + +enum APP_AUDIO_MANAGER_VOLUME_CTRL_T { + APP_AUDIO_MANAGER_VOLUME_CTRL_SET = 0, + APP_AUDIO_MANAGER_VOLUME_CTRL_UP, + APP_AUDIO_MANAGER_VOLUME_CTRL_DOWN, + APP_AUDIO_MANAGER_VOLUME_CTRL_NUM, +}; + +typedef void (*APP_AUDIO_MANAGER_CALLBACK_T)(uint32_t status, uint32_t param); + +#define APP_AUDIO_MANAGER_SET_MESSAGE(appevt, id, stream_type) (appevt = (((uint32_t)id&0xffff)<<16)|(stream_type&0xffff)) +#define APP_AUDIO_MANAGER_SET_MESSAGE0(appmsg, device_id,aud_id) (appmsg = (((uint32_t)device_id&0xffff)<<16)|(aud_id&0xffff)) +#define APP_AUDIO_MANAGER_GET_ID(appevt, id) (id = (appevt>>16)&0xffff) +#define APP_AUDIO_MANAGER_GET_STREAM_TYPE(appevt, stream_type) (stream_type = appevt&0xffff) +#define APP_AUDIO_MANAGER_GET_DEVICE_ID(appmsg, device_id) (device_id = (appmsg>>16)&0xffff) +#define APP_AUDIO_MANAGER_GET_AUD_ID(appmsg, aud_id) (aud_id = appmsg&0xffff) +#define APP_AUDIO_MANAGER_GET_CALLBACK(appmsg, callback) (callback = (APP_AUDIO_MANAGER_CALLBACK_T)appmsg) +#define APP_AUDIO_MANAGER_GET_CALLBACK_PARAM(appmsg, param) (param = appmsg) + +int app_audio_manager_sendrequest(uint8_t massage_id,uint16_t stream_type, uint8_t device_id, uint16_t aud_id); +int app_audio_manager_sendrequest_need_callback( + uint8_t massage_id, uint16_t stream_type, uint8_t device_id, uint16_t aud_id, uint32_t cb, uint32_t cb_param); +void app_audio_manager_open(void); + +void bt_media_start(uint16_t stream_type,enum BT_DEVICE_ID_T device_id,uint16_t media_id); +void bt_media_stop(uint16_t stream_type,enum BT_DEVICE_ID_T device_id); +void bt_media_switch_to_voice(uint16_t stream_type,enum BT_DEVICE_ID_T device_id); +uint16_t bt_media_get_media_active(enum BT_DEVICE_ID_T device_id); +uint8_t bt_media_is_media_active_by_type(uint16_t media_type); +void bt_media_volume_ptr_update_by_mediatype(uint16_t stream_type); +int app_audio_manager_set_active_sco_num(enum BT_DEVICE_ID_T id); +int app_audio_manager_get_active_sco_num(void); +hf_chan_handle_t* app_audio_manager_get_active_sco_chnl(void); +int app_audio_manager_swap_sco(enum BT_DEVICE_ID_T id); +uint8_t bt_media_is_media_active_by_device(uint16_t media_type,enum BT_DEVICE_ID_T device_id); +uint16_t bt_media_get_current_media(void); +int app_audio_manager_sco_status_checker(void); +int app_audio_manager_switch_a2dp(enum BT_DEVICE_ID_T id); +bool app_audio_manager_a2dp_is_active(enum BT_DEVICE_ID_T id); +bool app_audio_manager_capture_is_active(void); +bool app_audio_manager_media_is_active(void); +bool app_audio_manager_hfp_is_active(enum BT_DEVICE_ID_T id); +int app_audio_manager_set_scocodecid(enum BT_DEVICE_ID_T dev_id, uint16_t codec_id); +int app_audio_manager_get_scocodecid(void); +bool bt_media_is_media_idle(void); +uint8_t bt_media_device_enumerate_media_type_by_prior(); +void bt_media_clean_up(void); + +bool bt_media_is_media_active_by_sbc(void); +#ifdef RB_CODEC +bool app_rbplay_is_localplayer_mode(void); +bool app_rbplay_mode_switch(void); +void app_rbplay_set_player_mode(bool isInPlayerMode); +void app_rbcodec_ctr_play_onoff(bool on ); +bool app_rbcodec_get_play_status(void); +void app_rbcodec_toggle_play_stop(void); +#endif + +void app_stop_a2dp_media_stream(uint8_t devId); +void app_stop_sco_media_stream(uint8_t devId); +int app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_T volume_ctrl, uint16_t volume_level); +int app_audio_manager_tune_samplerate_ratio(enum AUD_STREAM_T stream, float ratio); +bool bt_media_cur_is_bt_stream_media(void); +bool bt_media_is_sbc_media_active(void); +void bt_media_current_sbc_set(uint8_t id); +void app_ibrt_sync_mix_prompt_req_handler(uint8_t* ptrParam, uint16_t paramLen); +void app_audio_decode_err_force_trigger(void); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/services/bt_app/app_bt_stream.cpp b/services/bt_app/app_bt_stream.cpp new file mode 100644 index 0000000..1f755e1 --- /dev/null +++ b/services/bt_app/app_bt_stream.cpp @@ -0,0 +1,8185 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +//#include "mbed.h" +#include +#include + +#include "cmsis_os.h" +#include "app_bt_trace.h" +#include "tgt_hardware.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_cmu.h" +#include "hal_overlay.h" +#include "analog.h" +#include "avdtp_i.h" +#include "app_bt_stream.h" +#include "app_overlay.h" +#include "app_audio.h" +#include "app_utils.h" +#ifdef ANC_APP +#include "app_anc.h" +#endif +#include "anc_wnr.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "resample_coef.h" +#include "hal_codec.h" +#include "hal_i2s.h" +#include "hal_bootmode.h" +#ifdef MEDIA_PLAYER_SUPPORT +#include "resources.h" +#include "app_media_player.h" +#endif +#ifdef __FACTORY_MODE_SUPPORT__ +#include "app_factory_audio.h" +#endif +#ifdef TX_RX_PCM_MASK +#include "hal_chipid.h" +#endif + +#ifdef __IAG_BLE_INCLUDE__ +#include "app_ble_mode_switch.h" +#endif + +#ifdef VOICE_DATAPATH +#include "app_voicepath.h" +#endif + +#if defined(__AI_VOICE__)||defined(BISTO_ENABLED) +#include "app_ai_voice.h" +#include "app_ai_if.h" +#endif + +#ifdef AI_AEC_CP_ACCEL +#include "app_ai_algorithm.h" +#endif + +#include "app_ring_merge.h" +#include "bt_drv.h" +#include "bt_xtal_sync.h" +#include "bt_drv_reg_op.h" +#include "besbt.h" +#include "hal_chipid.h" +#include "cqueue.h" +#include "btapp.h" +#include "app_hfp.h" +#include "app_bt.h" +#include "os_api.h" +#include "audio_process.h" +#include "app_a2dp.h" +#include "audio_dump.h" +#if (A2DP_DECODER_VER == 2) +#include "a2dp_decoder.h" +#endif +#if defined(__AUDIO_SPECTRUM__) +#include "audio_spectrum.h" +#endif + +#if defined(BONE_SENSOR_TDM) +#include "speech_utils.h" +#include "lis25ba.h" +#include "tdm_stream.h" +#endif + +#if defined(ANC_NOISE_TRACKER) +#include "noise_tracker.h" +#include "noise_tracker_callback.h" +#endif + +#if defined(IBRT) +#include "app_ibrt_if.h" +#include "app_tws_ctrl_thread.h" +#include "app_tws_ibrt_audio_analysis.h" +#include "app_tws_ibrt_audio_sync.h" +#include "app_ibrt_a2dp.h" +#include "app_ibrt_rssi.h" +#undef MUSIC_DELAY_CONTROL +#endif + +#if defined(AUDIO_ANC_FB_ADJ_MC) +#include "adj_mc.h" +#include "fftfilt2.h" +#endif + + +// NOTE: Modify parameters for your project. +// #define A2DP_STREAM_AUDIO_DUMP + +#if defined(__SW_IIR_EQ_PROCESS__) +static uint8_t audio_eq_sw_iir_index = 0; +extern const IIR_CFG_T * const audio_eq_sw_iir_cfg_list[]; +#endif + +#if defined(__HW_FIR_EQ_PROCESS__) +static uint8_t audio_eq_hw_fir_index = 0; +extern const FIR_CFG_T * const audio_eq_hw_fir_cfg_list[]; +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) +static uint8_t audio_eq_hw_dac_iir_index = 0; +extern const IIR_CFG_T * const audio_eq_hw_dac_iir_cfg_list[]; +#endif + +#include "audio_prompt_sbc.h" + +#if defined(__HW_IIR_EQ_PROCESS__) +static uint8_t audio_eq_hw_iir_index = 0; +extern const IIR_CFG_T * const audio_eq_hw_iir_cfg_list[]; +#endif + +#if defined(HW_DC_FILTER_WITH_IIR) +#include "hw_filter_codec_iir.h" +#include "hw_codec_iir_process.h" + +hw_filter_codec_iir_cfg POSSIBLY_UNUSED adc_iir_cfg = { + .bypass = 0, + .iir_device = HW_CODEC_IIR_ADC, +#if 1 + .iir_cfg = { + .iir_filtes_l = { + .iir_bypass_flag = 0, + .iir_counter = 2, + .iir_coef = { + {{0.994406, -1.988812, 0.994406}, {1.000000, -1.988781, 0.988843}}, // iir_designer('highpass', 0, 20, 0.7, 16000); + {{4.0, 0.0, 0.0}, {1.0, 0.0, 0.0}}, + } + }, + .iir_filtes_r = { + .iir_bypass_flag = 0, + .iir_counter = 2, + .iir_coef = { + {{0.994406, -1.988812, 0.994406}, {1.000000, -1.988781, 0.988843}}, + {{4.0, 0.0, 0.0}, {1.0, 0.0, 0.0}}, + } + } + } +#else + .iir_cfg = { + .gain0 = 0, + .gain1 = 0, + .num = 1, + .param = { + {IIR_TYPE_HIGH_PASS, 0, 20.0, 0.7}, + } + } +#endif +}; + +hw_filter_codec_iir_state *hw_filter_codec_iir_st; +#endif + +#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST3003)|| \ + defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST1000) || \ + defined(CHIP_BEST2000) || defined(CHIP_BEST3001) || defined(CHIP_BEST2001) \ + +#undef AUDIO_RESAMPLE_ANTI_DITHER + +#else +#define AUDIO_RESAMPLE_ANTI_DITHER +#endif + +#include "audio_cfg.h" + +//#define SCO_DMA_SNAPSHOT_DEBUG + +extern uint8_t bt_audio_get_eq_index(AUDIO_EQ_TYPE_T audio_eq_type,uint8_t anc_status); +extern uint32_t bt_audio_set_eq(AUDIO_EQ_TYPE_T audio_eq_type,uint8_t index); +extern uint8_t bt_audio_updata_eq_for_anc(uint8_t anc_status); + +#include "app_bt_media_manager.h" + +#include "string.h" +#include "hal_location.h" + +#include "bt_drv_interface.h" + +#include "audio_resample_ex.h" + +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST2001) +#define BT_INIT_XTAL_SYNC_FCAP_RANGE (0x1FF) +#else +#define BT_INIT_XTAL_SYNC_FCAP_RANGE (0xFF) +#endif +#define BT_INIT_XTAL_SYNC_MIN (20) +#define BT_INIT_XTAL_SYNC_MAX (BT_INIT_XTAL_SYNC_FCAP_RANGE - BT_INIT_XTAL_SYNC_MIN) + +#ifdef __THIRDPARTY +#include "app_thirdparty.h" +#endif + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) +#include"anc_process.h" + +#ifdef ANC_FB_MC_96KHZ +#define DELAY_SAMPLE_MC (29*2) // 2:ch +#define SAMPLERATE_RATIO_THRESHOLD (4) //384 = 96*4 +#else +#define DELAY_SAMPLE_MC (31*2) // 2:ch +#define SAMPLERATE_RATIO_THRESHOLD (8) //384 = 48*8 +#endif + +static int32_t delay_buf_bt[DELAY_SAMPLE_MC]; +#endif + +#ifdef ANC_APP +static uint8_t anc_status_record = 0xff; +#endif + +#if defined(SCO_DMA_SNAPSHOT) + +#ifdef PCM_FAST_MODE +#define MASTER_MOBILE_BTCLK_OFFSET (4) +#elif TX_RX_PCM_MASK +#define MASTER_MOBILE_BTCLK_OFFSET (8) +#else +#define MASTER_MOBILE_BTCLK_OFFSET (4) +#endif +#define MASTER_MOBILE_BTCNT_OFFSET (MASTER_MOBILE_BTCLK_OFFSET*625) + +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) || defined(CHIP_BEST2001) +#define MUTE_PATTERN (0x55) +#else +#define MUTE_PATTERN (0x00) +#endif + +extern void app_tws_ibrt_audio_mobile_clkcnt_get(uint32_t btclk, uint16_t btcnt, + uint32_t *mobile_master_clk, uint16_t *mobile_master_cnt); + +static uint8_t *playback_buf_codecpcm; +static uint32_t playback_size_codecpcm; +static uint8_t *capture_buf_codecpcm; +static uint32_t capture_size_codecpcm; + +static uint8_t *playback_buf_btpcm; +static uint32_t playback_size_btpcm; +static uint8_t *capture_buf_btpcm; +static uint32_t capture_size_btpcm; + +#ifdef TX_RX_PCM_MASK +static uint8_t *playback_buf_btpcm_copy=NULL; +static uint32_t playback_size_btpcm_copy=0; +static uint8_t *capture_buf_btpcm_copy=NULL; +static uint32_t capture_size_btpcm_copy=0; +#endif + +volatile int sco_btpcm_mute_flag=0; +volatile int sco_disconnect_mute_flag=0; + +static uint8_t *playback_buf_btpcm_cache=NULL; + +static enum AUD_SAMPRATE_T playback_samplerate_codecpcm; +static int32_t mobile_master_clk_offset_init; +#endif + +enum PLAYER_OPER_T +{ + PLAYER_OPER_START, + PLAYER_OPER_STOP, + PLAYER_OPER_RESTART, +}; + +#if defined(AF_ADC_I2S_SYNC) +extern "C" void hal_codec_capture_enable(void); +extern "C" void hal_codec_capture_enable_delay(void); + +static uint32_t codec_capture_cnt = 0; +static uint32_t codec_playback_cnt = 0; +#endif + +#if (AUDIO_OUTPUT_VOLUME_DEFAULT < 1) || (AUDIO_OUTPUT_VOLUME_DEFAULT > 17) +#error "AUDIO_OUTPUT_VOLUME_DEFAULT out of range" +#endif +int8_t stream_local_volume = (AUDIO_OUTPUT_VOLUME_DEFAULT); +#ifdef AUDIO_LINEIN +int8_t stream_linein_volume = (AUDIO_OUTPUT_VOLUME_DEFAULT); +#endif + +struct btdevice_volume *btdevice_volume_p; +struct btdevice_volume current_btdevice_volume; + +#ifdef __BT_ANC__ +uint8_t bt_sco_samplerate_ratio = 0; +static uint8_t *bt_anc_sco_dec_buf; +extern void us_fir_init(void); +extern uint32_t voicebtpcm_pcm_resample (short* src_samp_buf, uint32_t src_smpl_cnt, short* dst_samp_buf); +#endif + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) +static enum AUD_BITS_T sample_size_play_bt; +static enum AUD_SAMPRATE_T sample_rate_play_bt; +static uint32_t data_size_play_bt; + +static uint8_t *playback_buf_bt; +static uint32_t playback_size_bt; +static int32_t playback_samplerate_ratio_bt; + +static uint8_t *playback_buf_mc; +static uint32_t playback_size_mc; +static enum AUD_CHANNEL_NUM_T playback_ch_num_bt; +#ifdef AUDIO_ANC_FB_ADJ_MC +uint32_t adj_mc_capture_sample_rate; +#endif +#endif + +#if defined(MUSIC_DELAY_CONTROL) && (defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A)|| defined(CHIP_BEST1400)|| defined(CHIP_BEST1402)) +static enum AUD_BITS_T lowdelay_sample_size_play_bt; +static enum AUD_SAMPRATE_T lowdelay_sample_rate_play_bt; +static uint32_t lowdelay_data_size_play_bt; +static enum AUD_CHANNEL_NUM_T lowdelay_playback_ch_num_bt; +#endif + +extern uint8_t current_a2dp_non_type; + + +extern void bt_media_clear_media_type(uint16_t media_type,enum BT_DEVICE_ID_T device_id); + +extern "C" uint8_t is_sbc_mode (void); +uint8_t bt_sbc_mode; +extern "C" uint8_t __attribute__((section(".fast_text_sram"))) is_sbc_mode(void) +{ + return bt_sbc_mode; +} + +extern "C" uint8_t is_sco_mode (void); + +uint8_t bt_sco_mode; +extern "C" uint8_t __attribute__((section(".fast_text_sram"))) is_sco_mode(void) +{ + return bt_sco_mode; +} + +#define APP_BT_STREAM_TRIGGER_TIMEROUT (2000) + +#define TRIGGER_CHECKER_A2DP_PLAYERBLACK (1<<0) +#define TRIGGER_CHECKER_A2DP_DONE (TRIGGER_CHECKER_A2DP_PLAYERBLACK) + +#define TRIGGER_CHECKER_HFP_BTPCM_PLAYERBLACK (1<<1) +#define TRIGGER_CHECKER_HFP_BTPCM_CAPTURE (1<<2) +#define TRIGGER_CHECKER_HFP_AUDPCM_PLAYERBLACK (1<<3) +#define TRIGGER_CHECKER_HFP_AUDPCM_CAPTURE (1<<4) +#define TRIGGER_CHECKER_HFP_DONE (TRIGGER_CHECKER_HFP_BTPCM_PLAYERBLACK|TRIGGER_CHECKER_HFP_BTPCM_CAPTURE|TRIGGER_CHECKER_HFP_AUDPCM_PLAYERBLACK|TRIGGER_CHECKER_HFP_AUDPCM_CAPTURE) + + +static bool app_bt_stream_trigger_enable = 0; +static uint32_t app_bt_stream_trigger_checker = 0; +static void app_bt_stream_trigger_timeout_cb(void const *n); +osTimerDef(APP_BT_STREAM_TRIGGER_TIMEOUT, app_bt_stream_trigger_timeout_cb); +osTimerId app_bt_stream_trigger_timeout_id = NULL; + +static void app_bt_stream_trigger_timeout_cb(void const *n) +{ + TRACE_AUD_STREAM_I("[STRM_TRIG][CHK]timeout_cb\n"); + if (app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC)){ + TRACE_AUD_STREAM_I("[STRM_TRIG][CHK]-->A2DP_SBC\n"); +#if defined(IBRT) + app_ibrt_if_force_audio_retrigger(); +#else + app_audio_sendrequest_param(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_RESTART, 0, 0); +#endif + }else if (app_bt_stream_isrun(APP_BT_STREAM_HFP_PCM)){ + TRACE_AUD_STREAM_I("[STRM_TRIG][CHK]-->HFP_PCM\n"); + app_audio_sendrequest(APP_BT_STREAM_HFP_PCM, (uint8_t)APP_BT_SETTING_RESTART, 0); + } + +} + +static int app_bt_stream_trigger_checker_init(void) +{ + if (app_bt_stream_trigger_timeout_id == NULL){ + app_bt_stream_trigger_enable = false; + app_bt_stream_trigger_checker = 0; + app_bt_stream_trigger_timeout_id = osTimerCreate(osTimer(APP_BT_STREAM_TRIGGER_TIMEOUT), osTimerOnce, NULL); + } + + return 0; +} + +static int app_bt_stream_trigger_checker_start(void) +{ + app_bt_stream_trigger_checker = 0; + app_bt_stream_trigger_enable = true; + osTimerStart(app_bt_stream_trigger_timeout_id, APP_BT_STREAM_TRIGGER_TIMEROUT); + return 0; +} + +static int app_bt_stream_trigger_checker_stop(void) +{ + app_bt_stream_trigger_enable = false; + app_bt_stream_trigger_checker = 0; + osTimerStop(app_bt_stream_trigger_timeout_id); + return 0; +} + +int app_bt_stream_trigger_checker_handler(uint32_t trigger_checker) +{ + bool trigger_ok = false; + + if (app_bt_stream_trigger_enable){ + app_bt_stream_trigger_checker |= trigger_checker; + if (app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC)){ + if (app_bt_stream_trigger_checker == TRIGGER_CHECKER_A2DP_DONE){ + trigger_ok = true; + } + }else if (app_bt_stream_isrun(APP_BT_STREAM_HFP_PCM)){ + if (app_bt_stream_trigger_checker == TRIGGER_CHECKER_HFP_DONE){ + trigger_ok = true; + } + } + if (trigger_ok){ + TRACE_AUD_STREAM_I("[STRM_TRIG][CHK] ok\n"); + app_bt_stream_trigger_checker_stop(); + } + } + return 0; +} + +#ifdef A2DP_LHDC_ON +extern struct BT_DEVICE_T app_bt_device; +#if defined(A2DP_LHDC_V3) +#define LHDC_AUDIO_96K_BUFF_SIZE (256*2*4*8) +//#define LHDC_AUDIO_96K_16BITS_BUFF_SIZE (256*2*2*8) + +#define LHDC_AUDIO_BUFF_SIZE (256*2*4*4) +//#define LHDC_AUDIO_16BITS_BUFF_SIZE (256*2*2*4) +#define LHDC_LLC_AUDIO_BUFF_SIZE (256*2*2*2) +#else +#define LHDC_AUDIO_BUFF_SIZE (512*2*4) +//#define LHDC_AUDIO_16BITS_BUFF_SIZE (512*2*2) +#endif +#endif +uint16_t gStreamplayer = APP_BT_STREAM_INVALID; + +uint32_t a2dp_audio_more_data(uint8_t codec_type, uint8_t *buf, uint32_t len); +int a2dp_audio_init(void); +int a2dp_audio_deinit(void); +enum AUD_SAMPRATE_T a2dp_sample_rate = AUD_SAMPRATE_48000; +uint32_t a2dp_data_buf_size; +#ifdef RB_CODEC +extern int app_rbplay_audio_onoff(bool onoff, uint16_t aud_id); +#endif + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +int app_a2dp_source_linein_on(bool on); +#endif +#if defined(APP_I2S_A2DP_SOURCE) +#include "app_status_ind.h" +#include "app_a2dp_source.h" +//player channel should <= capture channel number +//player must be 2 channel +#define LINEIN_PLAYER_CHANNEL (2) +#ifdef __AUDIO_INPUT_MONO_MODE__ +#define LINEIN_CAPTURE_CHANNEL (1) +#else +#define LINEIN_CAPTURE_CHANNEL (2) +#endif + +#if (LINEIN_CAPTURE_CHANNEL == 1) +#define LINEIN_PLAYER_BUFFER_SIZE (1024*LINEIN_PLAYER_CHANNEL) +#define LINEIN_CAPTURE_BUFFER_SIZE (LINEIN_PLAYER_BUFFER_SIZE/2) +#elif (LINEIN_CAPTURE_CHANNEL == 2) +#define LINEIN_PLAYER_BUFFER_SIZE (1024*LINEIN_PLAYER_CHANNEL) +//#define LINEIN_CAPTURE_BUFFER_SIZE (LINEIN_PLAYER_BUFFER_SIZE) +#define LINEIN_CAPTURE_BUFFER_SIZE (1024*10) +#endif + +static int16_t *app_linein_play_cache = NULL; + +int8_t app_linein_buffer_is_empty(void) +{ + if (app_audio_pcmbuff_length()) + { + return 0; + } + else + { + return 1; + } +} + +uint32_t app_linein_pcm_come(uint8_t * pcm_buf, uint32_t len) +{ + //DUMP16("%d ", pcm_buf, 10); + DUMP8("0x%02x ", pcm_buf, 10); + TRACE_AUD_STREAM_I("app_linein_pcm_come"); + app_audio_pcmbuff_put(pcm_buf, len); + + return len; +} + +uint32_t app_linein_need_pcm_data(uint8_t* pcm_buf, uint32_t len) +{ + +#if (LINEIN_CAPTURE_CHANNEL == 1) + app_audio_pcmbuff_get((uint8_t *)app_linein_play_cache, len/2); + //app_play_audio_lineinmode_more_data((uint8_t *)app_linein_play_cache,len/2); + app_bt_stream_copy_track_one_to_two_16bits((int16_t *)pcm_buf, app_linein_play_cache, len/2/2); +#elif (LINEIN_CAPTURE_CHANNEL == 2) + app_audio_pcmbuff_get((uint8_t *)pcm_buf, len); + //app_play_audio_lineinmode_more_data((uint8_t *)pcm_buf, len); +#endif + +#if defined(__AUDIO_OUTPUT_MONO_MODE__) + merge_stereo_to_mono_16bits((int16_t *)buf, (int16_t *)pcm_buf, len/2); +#endif + +#ifdef ANC_APP + bt_audio_updata_eq_for_anc(app_anc_work_status()); +#endif + + audio_process_run(pcm_buf, len); + + return len; +} +extern "C" void pmu_linein_onoff(unsigned char en); +extern "C" int hal_analogif_reg_read(unsigned short reg, unsigned short *val); +int app_a2dp_source_I2S_onoff(bool onoff) +{ + static bool isRun = false; + uint8_t *linein_audio_cap_buff = 0; + uint8_t *linein_audio_play_buff = 0; + uint8_t *linein_audio_loop_buf = NULL; + struct AF_STREAM_CONFIG_T stream_cfg; + + TRACE_AUD_STREAM_I("app_a2dp_source_I2S_onoff work:%d op:%d", isRun, onoff); + + if (isRun == onoff) + return 0; + + if (onoff) + { + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_104M); + app_overlay_select(APP_OVERLAY_A2DP); + app_audio_mempool_init(); + app_audio_mempool_get_buff(&linein_audio_cap_buff, LINEIN_CAPTURE_BUFFER_SIZE); +// app_audio_mempool_get_buff(&linein_audio_play_buff, LINEIN_PLAYER_BUFFER_SIZE); +// app_audio_mempool_get_buff(&linein_audio_loop_buf, LINEIN_PLAYER_BUFFER_SIZE<<2); +// app_audio_pcmbuff_init(linein_audio_loop_buf, LINEIN_PLAYER_BUFFER_SIZE<<2); + +#if (LINEIN_CAPTURE_CHANNEL == 1) + app_audio_mempool_get_buff((uint8_t **)&app_linein_play_cache, LINEIN_PLAYER_BUFFER_SIZE/2/2); + //app_play_audio_lineinmode_init(LINEIN_CAPTURE_CHANNEL, LINEIN_PLAYER_BUFFER_SIZE/2/2); +#elif (LINEIN_CAPTURE_CHANNEL == 2) + //app_play_audio_lineinmode_init(LINEIN_CAPTURE_CHANNEL, LINEIN_PLAYER_BUFFER_SIZE/2); +#endif + + sRet = memset_s(&stream_cfg, sizeof(stream_cfg), 0, sizeof(stream_cfg)); + if (sRet){ + TRACE_AUD_STREAM_W("func-s line:%d sRet:%d %s ", __LINE__, sRet, __func__); + } + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = (enum AUD_CHANNEL_NUM_T)LINEIN_PLAYER_CHANNEL; + stream_cfg.sample_rate = AUD_SAMPRATE_44100; + +#if 0 +#if FPGA==0 + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; +#else + stream_cfg.device = AUD_STREAM_USE_EXT_CODEC; +#endif + + stream_cfg.vol = 10;//stream_linein_volume; + //TRACE_AUD_STREAM_I("vol = %d",stream_linein_volume); + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.handler = app_linein_need_pcm_data; + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(linein_audio_play_buff); + stream_cfg.data_size = LINEIN_PLAYER_BUFFER_SIZE; + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); +#endif + +#if 1 + stream_cfg.device = AUD_STREAM_USE_I2S0_SLAVE; +// stream_cfg.io_path = AUD_INPUT_PATH_LINEIN; +// stream_cfg.handler = app_linein_pcm_come; + stream_cfg.handler = a2dp_source_linein_more_pcm_data; +// stream_cfg.handler = app_linein_pcm_come; + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(linein_audio_cap_buff); + stream_cfg.data_size = LINEIN_CAPTURE_BUFFER_SIZE;//2k + +// pmu_linein_onoff(1); + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + + audio_process_open(stream_cfg.sample_rate, stream_cfg.bits, stream_cfg.channel_num, NULL, 0); + + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); +#endif + //app_status_indication_set(APP_STATUS_INDICATION_LINEIN_ON); + } + else + { +// clear buffer data + a2dp_source.pcm_queue.write=0; + a2dp_source.pcm_queue.len=0; + a2dp_source.pcm_queue.read=0; +// pmu_linein_onoff(0); + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + //app_status_indication_set(APP_STATUS_INDICATION_LINEIN_OFF); + app_overlay_unloadall(); + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_32K); + } + + isRun = onoff; + TRACE_AUD_STREAM_I("%s end!\n", __func__); + return 0; +} +#endif + +enum AUD_SAMPRATE_T bt_parse_sbc_sample_rate(uint8_t sbc_samp_rate) +{ + enum AUD_SAMPRATE_T sample_rate; + sbc_samp_rate = sbc_samp_rate & A2D_STREAM_SAMP_FREQ_MSK; + + switch (sbc_samp_rate) + { + case A2D_SBC_IE_SAMP_FREQ_16: +// sample_rate = AUD_SAMPRATE_16000; +// break; + case A2D_SBC_IE_SAMP_FREQ_32: +// sample_rate = AUD_SAMPRATE_32000; +// break; + case A2D_SBC_IE_SAMP_FREQ_48: + sample_rate = AUD_SAMPRATE_48000; + break; + case A2D_SBC_IE_SAMP_FREQ_44: + sample_rate = AUD_SAMPRATE_44100; + break; +#if defined(A2DP_LHDC_ON) || defined(A2DP_LDAC_ON) || defined(A2DP_SCALABLE_ON) + case A2D_SBC_IE_SAMP_FREQ_96: + sample_rate = AUD_SAMPRATE_96000; + break; +#endif + + default: + ASSERT(0, "[%s] 0x%x is invalid", __func__, sbc_samp_rate); + break; + } + return sample_rate; +} + +void bt_store_sbc_sample_rate(enum AUD_SAMPRATE_T sample_rate) +{ + a2dp_sample_rate = sample_rate; +} + +enum AUD_SAMPRATE_T bt_get_sbc_sample_rate(void) +{ + return a2dp_sample_rate; +} + +enum AUD_SAMPRATE_T bt_parse_store_sbc_sample_rate(uint8_t sbc_samp_rate) +{ + enum AUD_SAMPRATE_T sample_rate; + + sample_rate = bt_parse_sbc_sample_rate(sbc_samp_rate); + bt_store_sbc_sample_rate(sample_rate); + + return sample_rate; +} + +int bt_sbc_player_setup(uint8_t freq) +{ + struct AF_STREAM_CONFIG_T *stream_cfg = NULL; + static uint8_t sbc_samp_rate = 0xff; + uint32_t ret; + + if (sbc_samp_rate == freq) + return 0; + + switch (freq) + { + case A2D_SBC_IE_SAMP_FREQ_16: + case A2D_SBC_IE_SAMP_FREQ_32: + case A2D_SBC_IE_SAMP_FREQ_48: + a2dp_sample_rate = AUD_SAMPRATE_48000; + break; +#if defined(A2DP_LHDC_ON) || defined(A2DP_LDAC_ON) || defined(A2DP_SCALABLE_ON) + case A2D_SBC_IE_SAMP_FREQ_96: + a2dp_sample_rate = AUD_SAMPRATE_96000; + break; +#if defined(A2DP_LDAC_ON) + case A2D_SBC_IE_SAMP_FREQ_88: + a2dp_sample_rate = AUD_SAMPRATE_88200; + break; +#endif +#endif + case A2D_SBC_IE_SAMP_FREQ_44: + a2dp_sample_rate = AUD_SAMPRATE_44100; + break; + default: + break; + } + TRACE_AUD_STREAM_I("%s:Sample rate :%d", __func__, a2dp_sample_rate); + + ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg, true); + if (ret == 0) { + stream_cfg->sample_rate = a2dp_sample_rate; + af_stream_setup(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, stream_cfg); + } + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + ret = af_stream_get_cfg(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &stream_cfg, true); + if (ret == 0) { + stream_cfg->sample_rate = a2dp_sample_rate; + sample_rate_play_bt=stream_cfg->sample_rate; + af_stream_setup(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, stream_cfg); + anc_mc_run_setup(hal_codec_anc_convert_rate(sample_rate_play_bt)); + } +#endif + + sbc_samp_rate = freq; + +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + if (audio_prompt_is_playing_ongoing()) + { + audio_prompt_forcefully_stop(); + } +#endif + + return 0; +} + +void merge_stereo_to_mono_16bits(int16_t *src_buf, int16_t *dst_buf, uint32_t src_len) +{ + uint32_t i = 0; + for (i = 0; i < src_len; i+=2) + { + dst_buf[i] = (src_buf[i]>>1) + (src_buf[i+1]>>1); + dst_buf[i+1] = dst_buf[i]; + } +} + +void merge_stereo_to_mono_24bits(int32_t *src_buf, int32_t *dst_buf, uint32_t src_len) +{ + uint32_t i = 0; + for (i = 0; i < src_len; i+=2) + { + dst_buf[i] = (src_buf[i]>>1) + (src_buf[i+1]>>1); + dst_buf[i+1] = dst_buf[i]; + } +} + +static char _player_type_str[168]; +static char *_catstr(char *dst, const char *src) { + while(*dst) dst++; + while((*dst++ = *src++)); + return --dst; +} +const char *player2str(uint16_t player_type) { + const char *s = NULL; + char _cat = 0, first = 1, *d = NULL; + _player_type_str[0] = '\0'; + d = _player_type_str; + d = _catstr(d, "["); + if (player_type != 0) { + for (int i = 15 ; i >= 0; i--) { + _cat = 1; + //TRACE_AUD_STREAM_I("i=%d,player_type=0x%d,player_type&(1<=0x80 && a2dp_Get_curr_a2dp_conhdl()<=0x82) + { + btofs = btdrv_rf_bitoffset_get( a2dp_Get_curr_a2dp_conhdl() -0x80); + + if(calib_reset==1) + { + calib_reset=0; + + bt_clock_total_mutius=0; + + bt_old_clock_us=btcnt; + bt_old_clock_mutius=btclk; + + bt_total_offset_us=0; + + + local_total_samples=0; + local_total_frames=0; + local_clock_ms = 0; + + bt_local_clock_s=0; + bt_clock_us = 0; + bt_clock_ms = 0; + + bt_old_offset_us=btofs; + + calib_factor_offset=0.0f; + calib_factor_flag=0; + calib_total_delay=0; + calib_flag=0; + } + else + { + btoffset=btofs-bt_old_offset_us; + + if(btoffset<-BT_USPERCLK/3) + { + btoffset=btoffset+BT_USPERCLK; + } + else if(btoffset>BT_USPERCLK/3) + { + btoffset=btoffset-BT_USPERCLK; + } + + bt_total_offset_us=bt_total_offset_us+btoffset; + bt_old_offset_us=btofs; + + local_total_frames++; + if(lowdelay_sample_size_play_bt==AUD_BITS_16) + { + smplcnt=len/(2*lowdelay_playback_ch_num_bt); + } + else + { + smplcnt=len/(4*lowdelay_playback_ch_num_bt); + } + + local_total_samples=local_total_samples+smplcnt; + + bt_clock_us=btcnt-bt_old_clock_us-bt_total_offset_us; + + btoffset=btclk-bt_old_clock_mutius; + if(btoffset<0) + { + btoffset=0; + } + bt_clock_total_mutius=bt_clock_total_mutius+btoffset; + + bt_old_clock_us=btcnt; + bt_old_clock_mutius=btclk; + + if((bt_clock_total_mutius>BT_MUTIUSPERSECOND)&&(local_total_samples>lowdelay_sample_rate_play_bt)) + { + bt_local_clock_s++; + bt_clock_total_mutius=bt_clock_total_mutius-BT_MUTIUSPERSECOND; + local_total_samples=local_total_samples-lowdelay_sample_rate_play_bt; + } + + bt_clock_ms=(bt_clock_total_mutius*BT_USPERCLK/1000)+bt_clock_us/625; + local_clock_ms=(local_total_samples*1000)/lowdelay_sample_rate_play_bt; + + local_clock_ms=local_clock_ms+calib_total_delay; + + //TRACE_AUD_STREAM_I("A2DP bt_clock_ms:%8d,local_clock_ms:%8d,bt_total_offset_us:%8d\n",bt_clock_ms, local_clock_ms,bt_total_offset_us); + + if(bt_clock_ms>(local_clock_ms+CALIB_DEVIATION_MS)) + { +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + app_resample_tune(a2dp_resample, CALIB_FACTOR_DELAY); +#else + af_codec_tune(AUD_STREAM_PLAYBACK, CALIB_FACTOR_DELAY); +#endif + calib_factor_flag=1; + //TRACE_AUD_STREAM_I("*************1***************"); + } + else if(bt_clock_ms<(local_clock_ms-CALIB_DEVIATION_MS)) + { +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + app_resample_tune(a2dp_resample, -CALIB_FACTOR_DELAY); +#else + af_codec_tune(AUD_STREAM_PLAYBACK, -CALIB_FACTOR_DELAY); +#endif + calib_factor_flag=-1; + //TRACE_AUD_STREAM_I("*************-1***************"); + } + else + { + if((calib_factor_flag==1||calib_factor_flag==-1)&&(bt_clock_ms==local_clock_ms)) + { + if(calib_factor_offset=0x80 && a2dp_Get_curr_a2dp_conhdl()<=0x82) + { + uint32_t bitoffset = btdrv_rf_bitoffset_get( a2dp_Get_curr_a2dp_conhdl() -0x80); + if(app_if_need_fix_target_rxbit() == false) + { + if(bitoffsetSLOT_SIZE-XTAL_OFFSET) + bitoffset = SLOT_SIZE-XTAL_OFFSET; + } +#ifdef BT_XTAL_SYNC_SLOW + bt_xtal_sync_new(bitoffset,app_if_need_fix_target_rxbit(),BT_XTAL_SYNC_MODE_WITH_MOBILE); +#else + bt_xtal_sync_new_new(bitoffset,app_if_need_fix_target_rxbit(),BT_XTAL_SYNC_MODE_WITH_MOBILE); +#endif + } + +#else + bt_xtal_sync(BT_XTAL_SYNC_MODE_MUSIC); +#endif +#endif + +#ifndef FPGA + uint8_t codec_type = bt_sbc_player_get_codec_type(); + uint32_t overlay_id = 0; + if(codec_type == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) + { + overlay_id = APP_OVERLAY_A2DP_AAC; + } + else if(codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { +#if defined(A2DP_LHDC_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LHDC) + { + overlay_id = APP_OVERLAY_A2DP_LHDC; + } +#endif + +#if defined(A2DP_LDAC_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LDAC) + { + overlay_id = APP_OVERLAY_A2DP_LDAC; + } +#endif + +#if defined(A2DP_SCALABLE_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_SCALABLE) + { + overlay_id = APP_OVERLAY_A2DP_SCALABLE; + } +#endif + } + else + { + overlay_id = APP_OVERLAY_A2DP; + } + + memset(buf, 0, len); + + if(app_get_current_overlay() != overlay_id) + { + return len; + } +#endif + +#ifdef PLAYBACK_FORCE_48K + app_playback_resample_run(force48k_resample, buf, len); +#else +#if (A2DP_DECODER_VER == 2) + a2dp_audio_playback_handler(buf, len); +#else +#ifndef FPGA + a2dp_audio_more_data(overlay_id, buf, len); +#endif +#endif +#endif + +#ifdef __AUDIO_SPECTRUM__ + audio_spectrum_run(buf, len); +#endif + + +#ifdef __KWS_AUDIO_PROCESS__ + short* pdata = (short*)buf; + short pdata_mono = 0; + for(unsigned int i = 0;i=EQ_SW_IIR_LIST_NUM) + return -1; +#endif +#ifdef __HW_FIR_EQ_PROCESS__ + if (index >=EQ_HW_FIR_LIST_NUM) + return -1; +#endif +#ifdef __HW_DAC_IIR_EQ_PROCESS__ + if (index >=EQ_HW_DAC_IIR_LIST_NUM) + return -1; +#endif +#ifdef __HW_IIR_EQ_PROCESS__ + if (index >=EQ_HW_IIR_LIST_NUM) + return -1; +#endif + g_current_eq_index = index; + return index; +} + +void bt_audio_updata_eq(uint8_t index) +{ + TRACE_AUD_STREAM_I("[EQ] update idx = %d", index); +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__)|| defined(__HW_DAC_IIR_EQ_PROCESS__)|| defined(__HW_IIR_EQ_PROCESS__) + AUDIO_EQ_TYPE_T audio_eq_type; +#ifdef __SW_IIR_EQ_PROCESS__ + audio_eq_type = AUDIO_EQ_TYPE_SW_IIR; +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ + audio_eq_type = AUDIO_EQ_TYPE_HW_FIR; +#endif + +#ifdef __HW_DAC_IIR_EQ_PROCESS__ + audio_eq_type = AUDIO_EQ_TYPE_HW_DAC_IIR; +#endif + +#ifdef __HW_IIR_EQ_PROCESS__ + audio_eq_type = AUDIO_EQ_TYPE_HW_IIR; +#endif + bt_audio_set_eq(audio_eq_type,index); +#endif +} + + +#ifdef ANC_APP +uint8_t bt_audio_updata_eq_for_anc(uint8_t anc_status) +{ + anc_status = app_anc_work_status(); + if(anc_status_record != anc_status) + { + anc_status_record = anc_status; + TRACE_AUD_STREAM_I("[EQ] update anc_status = %d", anc_status); +#ifdef __SW_IIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_SW_IIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_SW_IIR,anc_status)); +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_HW_FIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_HW_FIR,anc_status)); +#endif + +#ifdef __HW_DAC_IIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_HW_DAC_IIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_HW_DAC_IIR,anc_status)); +#endif + +#ifdef __HW_IIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_HW_IIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_HW_IIR,anc_status)); +#endif + } + return 0; +} +#endif + +uint8_t bt_audio_get_eq_index(AUDIO_EQ_TYPE_T audio_eq_type,uint8_t anc_status) +{ + uint8_t index_eq=0; + +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__)|| defined(__HW_DAC_IIR_EQ_PROCESS__)|| defined(__HW_IIR_EQ_PROCESS__) + switch (audio_eq_type) + { +#if defined(__SW_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_SW_IIR: + { + if(anc_status) + { + index_eq=audio_eq_sw_iir_index+1; + } + else + { + index_eq=audio_eq_sw_iir_index; + } + + } + break; +#endif + +#if defined(__HW_FIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_FIR: + { + if(a2dp_sample_rate == AUD_SAMPRATE_44100) { + index_eq = 0; + } else if(a2dp_sample_rate == AUD_SAMPRATE_48000) { + index_eq = 1; + } else if(a2dp_sample_rate == AUD_SAMPRATE_96000) { + index_eq = 2; + } else { + ASSERT(0, "[%s] sample_rate_recv(%d) is not supported", __func__, a2dp_sample_rate); + } + audio_eq_hw_fir_index=index_eq; + + if(anc_status) + { + index_eq=index_eq+3; + } + } + break; +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_DAC_IIR: + { + if(anc_status) + { + index_eq=audio_eq_hw_dac_iir_index+1; + } + else + { + index_eq=audio_eq_hw_dac_iir_index; + } + } + break; +#endif + +#if defined(__HW_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_IIR: + { + if(anc_status) + { + index_eq=audio_eq_hw_iir_index+1; + } + else + { + index_eq=audio_eq_hw_iir_index; + } + } + break; +#endif + default: + { + ASSERT(false,"[%s]Error eq type!",__func__); + } + } +#endif + return index_eq; +} + + +uint32_t bt_audio_set_eq(AUDIO_EQ_TYPE_T audio_eq_type, uint8_t index) +{ + const FIR_CFG_T *fir_cfg=NULL; + const IIR_CFG_T *iir_cfg=NULL; + + TRACE_AUD_STREAM_I("[EQ] set type=%d,index=%d", audio_eq_type,index); + +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__)|| defined(__HW_DAC_IIR_EQ_PROCESS__)|| defined(__HW_IIR_EQ_PROCESS__) + switch (audio_eq_type) + { +#if defined(__SW_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_SW_IIR: + { + if(index >= EQ_SW_IIR_LIST_NUM) + { + TRACE_AUD_STREAM_W("[EQ] SET index %u > EQ_SW_IIR_LIST_NUM", index); + return 1; + } + + iir_cfg=audio_eq_sw_iir_cfg_list[index]; + } + break; +#endif + +#if defined(__HW_FIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_FIR: + { + if(index >= EQ_HW_FIR_LIST_NUM) + { + TRACE_AUD_STREAM_W("[EQ] SET index %u > EQ_HW_FIR_LIST_NUM", index); + return 1; + } + + fir_cfg=audio_eq_hw_fir_cfg_list[index]; + } + break; +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_DAC_IIR: + { + if(index >= EQ_HW_DAC_IIR_LIST_NUM) + { + TRACE_AUD_STREAM_W("[EQ] SET index %u > EQ_HW_DAC_IIR_LIST_NUM", index); + return 1; + } + + iir_cfg=audio_eq_hw_dac_iir_cfg_list[index]; + } + break; +#endif + +#if defined(__HW_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_IIR: + { + if(index >= EQ_HW_IIR_LIST_NUM) + { + TRACE_AUD_STREAM_W("[EQ] SET index %u > EQ_HW_IIR_LIST_NUM", index); + return 1; + } + + iir_cfg=audio_eq_hw_iir_cfg_list[index]; + } + break; +#endif + default: + { + ASSERT(false,"[%s]Error eq type!",__func__); + } + } +#endif + +#ifdef AUDIO_SECTION_ENABLE + const IIR_CFG_T *iir_cfg_from_audio_section = (const IIR_CFG_T *)load_audio_cfg_from_audio_section(AUDIO_PROCESS_TYPE_IIR_EQ); + if (iir_cfg_from_audio_section) + { + iir_cfg = iir_cfg_from_audio_section; + } +#endif + + return audio_eq_set_cfg(fir_cfg,iir_cfg,audio_eq_type); +} + +#define A2DP_PLAYER_PLAYBACK_WATER_LINE ((uint32_t)(3.f * a2dp_audio_latency_factor_get() + 0.5f)) +#define A2DP_PLAYER_PLAYBACK_WATER_LINE_UPPER (25) + +/******************************** + AUD_BITS_16 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/2*1000000LL/stream_cfg->sample_rate; + AUD_BITS_24 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/4*1000000LL/stream_cfg->sample_rate; + + dma_buffer_delay_us + scalable delay = 864/sample*1000*n ms + scalable delay = 864/44100*1000*13 = 117ms + scalable delay = 864/96000*1000*6 = 118ms + waterline delay = 864/sample*1000*n ms + waterline delay = 864/44100*1000*3 = 58ms + waterline delay = 864/96000*1000*3 = 27ms + audio_delay = scalable delay + waterline delay + *********************************/ + +#define A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_HIRES_MTU (13) +#define A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_HIRES_BASE (9000) +#define A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_HIRES_US (A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_HIRES_BASE*A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_HIRES_MTU) + +#define A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_BASERES_MTU (6) +#define A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_BASERES_BASE (19500) +#define A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_BASERES_US (A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_BASERES_BASE*A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_BASERES_MTU) + +/******************************** + AUD_BITS_16 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/2*1000000LL/stream_cfg->sample_rate; + AUD_BITS_24 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/4*1000000LL/stream_cfg->sample_rate; + + dma_buffer_delay_us + aac delay = 1024/sample*1000*n ms + aac delay = 1024/44100*1000*5 = 116ms + waterline delay = 1024/sample*1000*n ms + waterline delay = 1024/44100*1000*3 = 69ms + audio_delay = aac delay + waterline delay + *********************************/ +#ifndef A2DP_PLAYER_PLAYBACK_DELAY_AAC_MTU +#ifdef A2DP_PLAYER_PLAYBACK_WATER_LINE +#define A2DP_PLAYER_PLAYBACK_DELAY_AAC_MTU (3) +#else +#define A2DP_PLAYER_PLAYBACK_DELAY_AAC_MTU (6) +#endif +#endif +#define A2DP_PLAYER_PLAYBACK_DELAY_AAC_BASE (23000) +#define A2DP_PLAYER_PLAYBACK_DELAY_AAC_US (A2DP_PLAYER_PLAYBACK_DELAY_AAC_BASE*A2DP_PLAYER_PLAYBACK_DELAY_AAC_MTU) + +/******************************** + AUD_BITS_16 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/2*1000000LL/stream_cfg->sample_rate; + AUD_BITS_24 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/4*1000000LL/stream_cfg->sample_rate; + + sbc delay = 128/sample*n ms + sbc delay = 128/44100*45 = 130ms + sbc_delay = sbc delay(23219us) + waterline delay = 128/sample*SBC_FRAME_MTU*n ms + waterline delay = 128/44100*5*3 = 43ms + audio_delay = aac delay + waterline delay +*********************************/ +#define A2DP_PLAYER_PLAYBACK_DELAY_SBC_FRAME_MTU (5) +#ifndef A2DP_PLAYER_PLAYBACK_DELAY_SBC_MTU +#ifdef A2DP_PLAYER_PLAYBACK_WATER_LINE +#define A2DP_PLAYER_PLAYBACK_DELAY_SBC_MTU (35) +#else +#define A2DP_PLAYER_PLAYBACK_DELAY_SBC_MTU (50) +#endif +#endif +#define A2DP_PLAYER_PLAYBACK_DELAY_SBC_BASE (2800) +#define A2DP_PLAYER_PLAYBACK_DELAY_SBC_US (A2DP_PLAYER_PLAYBACK_DELAY_SBC_BASE*A2DP_PLAYER_PLAYBACK_DELAY_SBC_MTU) + +#if defined(A2DP_LHDC_ON) +/******************************** + AUD_BITS_16 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/2*1000000LL/stream_cfg->sample_rate; + AUD_BITS_24 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/4*1000000LL/stream_cfg->sample_rate; + + lhdc delay = 512/sample*1000*n ms + lhdc delay = *28 = 149ms + audio_delay = lhdc delay + + lhdc_v2 delay = 512/96000*1000*38 = 202ms + lhdc_v3 delay = 256/96000*1000*58 = 154ms + audio_delay = lhdc_v3 delay +*********************************/ +#if defined(IBRT) +#if defined(A2DP_LHDC_V3) +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_MTU (68) +#else +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_MTU (38) +#endif +#else +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_MTU (28) +#endif + +#if defined(A2DP_LHDC_V3) +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_BASE (2666) +#else +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_BASE (5333) +#endif +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_US (A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_MTU*A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_BASE) + +/******************************** + AUD_BITS_16 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/2*1000000LL/stream_cfg->sample_rate; + AUD_BITS_24 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/4*1000000LL/stream_cfg->sample_rate; + + lhdc delay = 512/sample*1000*n ms + lhdc_v2 delay = 512/48000*1000*14 = 149ms + lhdc_v3 delay = 256/48000*1000*28 = 149ms + audio_delay = lhdc delay +*********************************/ +#if defined(A2DP_LHDC_V3) +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_MTU (38) +#else +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_MTU (14) +#endif + +#if defined(A2DP_LHDC_V3) +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_BASE (5333) +#else +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_BASE (10666) +#endif +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_US (A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_MTU*A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_BASE) + +/******************************** + AUD_BITS_16 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/2*1000000LL/stream_cfg->sample_rate; + AUD_BITS_24 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/4*1000000LL/stream_cfg->sample_rate; + + lhdc delay = 512/sample*1000*n ms + lhdc_v2 delay = 512/48000*1000*9 = 96ms + lhdc_v3 delay = 256/48000*1000*19 = 101ms + audio_delay = lhdc delay +*********************************/ +#if defined(IBRT) +#if defined(A2DP_LHDC_V3) +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_MTU (15) +#else +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_MTU (9) +#endif +#else +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_MTU (6) +#endif + +#if defined(A2DP_LHDC_V3) +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_BASE (5333) +#else +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_BASE (10666) +#endif +#define A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_US (A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_MTU*A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_BASE) +#endif + +#if defined(A2DP_LDAC_ON) +/******************************** + AUD_BITS_16 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/2*1000000LL/stream_cfg->sample_rate; + AUD_BITS_24 + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/4*1000000LL/stream_cfg->sample_rate; + + ldac delay = 256/sample*1000*n ms + ldac delay = 256/96000*1000*56 = 149ms + audio_delay = ldac delay +*********************************/ +#define A2DP_PLAYER_PLAYBACK_DELAY_LDAC_FRAME_MTU (5) +#define A2DP_PLAYER_PLAYBACK_DELAY_LDAC_MTU (60) +#define A2DP_PLAYER_PLAYBACK_DELAY_LDAC_BASE (2667) +#define A2DP_PLAYER_PLAYBACK_DELAY_LDAC_US (A2DP_PLAYER_PLAYBACK_DELAY_LDAC_BASE*A2DP_PLAYER_PLAYBACK_DELAY_LDAC_MTU) +#endif + +enum BT_STREAM_TRIGGER_STATUS_T { + BT_STREAM_TRIGGER_STATUS_NULL = 0, + BT_STREAM_TRIGGER_STATUS_INIT, + BT_STREAM_TRIGGER_STATUS_WAIT, + BT_STREAM_TRIGGER_STATUS_OK, +}; + +static uint32_t tg_acl_trigger_time = 0; +static uint32_t tg_acl_trigger_start_time = 0; +static uint32_t tg_acl_trigger_init_time = 0; +static enum BT_STREAM_TRIGGER_STATUS_T bt_stream_trigger_status = BT_STREAM_TRIGGER_STATUS_NULL; + +void app_bt_stream_playback_irq_notification(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream); + +inline void app_bt_stream_trigger_stauts_set(enum BT_STREAM_TRIGGER_STATUS_T stauts) +{ + TRACE_AUD_STREAM_I("[STRM_TRIG] stauts_set %d->%d", bt_stream_trigger_status,stauts); + bt_stream_trigger_status = stauts; +} + +inline enum BT_STREAM_TRIGGER_STATUS_T app_bt_stream_trigger_stauts_get(void) +{ + TRACE_AUD_STREAM_I("[STRM_TRIG] stauts_get:%d", bt_stream_trigger_status); + return bt_stream_trigger_status; +} + +uint32_t app_bt_stream_get_dma_buffer_delay_us(void) +{ + uint32_t dma_buffer_delay_us = 0; + struct AF_STREAM_CONFIG_T *stream_cfg = NULL; + if (!af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg, false)){ + if (stream_cfg->bits <= AUD_BITS_16){ + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/2*1000000LL/stream_cfg->sample_rate; + }else{ + dma_buffer_delay_us = stream_cfg->data_size/stream_cfg->channel_num/4*1000000LL/stream_cfg->sample_rate; + } + } + return dma_buffer_delay_us; +} + +uint32_t app_bt_stream_get_dma_buffer_samples(void) +{ + uint32_t dma_buffer_delay_samples = 0; + struct AF_STREAM_CONFIG_T *stream_cfg = NULL; + if (!af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg, false)){ + if (stream_cfg->bits <= AUD_BITS_16){ + dma_buffer_delay_samples = stream_cfg->data_size/stream_cfg->channel_num/2; + }else{ + dma_buffer_delay_samples = stream_cfg->data_size/stream_cfg->channel_num/4; + } + } + return dma_buffer_delay_samples; +} + +#if defined(IBRT) +typedef enum { + APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_IDLE, + APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_ONPROCESS, + APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_SYNCOK, +}APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_TYPE; + +#define APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_CNT_LIMIT (100) +void app_bt_stream_ibrt_set_trigger_time(APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger); +void app_bt_stream_ibrt_auto_synchronize_initsync_start(APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger); +static APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T app_bt_stream_ibrt_auto_synchronize_trigger; +static uint32_t app_bt_stream_ibrt_auto_synchronize_cnt = 0; +int app_bt_stream_ibrt_audio_mismatch_stopaudio(void); +void app_bt_stream_ibrt_auto_synchronize_hungup(void); +void app_bt_stream_ibrt_auto_synchronize_stop(void); +static APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_TYPE ibrt_auto_synchronize_status = APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_IDLE; + +int app_bt_stream_ibrt_auto_synchronize_status_set(APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_TYPE status) +{ + TRACE_AUD_STREAM_I("[AUTO_SYNC] status:%d", status); + ibrt_auto_synchronize_status = status; + return 0; +} + +APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_TYPE app_bt_stream_ibrt_auto_synchronize_status_get(void) +{ + TRACE_AUD_STREAM_I("[AUTO_SYNC] status:%d", ibrt_auto_synchronize_status); + return ibrt_auto_synchronize_status; +} + +int app_bt_stream_ibrt_auto_synchronize_trigger_start(btif_media_header_t * header, unsigned char *buf, unsigned int len) +{ + APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger = &app_bt_stream_ibrt_auto_synchronize_trigger; + app_bt_stream_ibrt_auto_synchronize_stop(); + TRACE_AUD_STREAM_I("[AUTO_SYNC] trigger:%d Seq:%d timestamp:%d SubSeq:%d/%d currSeq:%d", + sync_trigger->trigger_time, + sync_trigger->audio_info.sequenceNumber, + sync_trigger->audio_info.timestamp, + sync_trigger->audio_info.curSubSequenceNumber, + sync_trigger->audio_info.totalSubSequenceNumber, + header->sequenceNumber + ); + + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + if (app_tws_ibrt_slave_ibrt_link_connected()){ + if (sync_trigger->trigger_time >= bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle)){ + app_bt_stream_ibrt_set_trigger_time(sync_trigger); + }else{ + TRACE_AUD_STREAM_W("[AUTO_SYNC]failed trigger(%d)-->tg(%d) need resume", bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle), + sync_trigger->trigger_time); + app_ibrt_if_force_audio_retrigger(); + //app_tws_ibrt_audio_sync_mismatch_resume_notify(); + } + }else{ + TRACE_AUD_STREAM_I("[AUTO_SYNC] ok but currRole:%d mismatch\n", p_ibrt_ctrl->current_role); + app_ibrt_if_force_audio_retrigger(); + } + + return 0; +} + +int app_bt_stream_ibrt_auto_synchronize_dataind_cb(btif_media_header_t * header, unsigned char *buf, unsigned int len) +{ + APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger = &app_bt_stream_ibrt_auto_synchronize_trigger; + bool synchronize_ok = false; + int32_t timestamp_diff = 0; + int32_t dma_buffer_samples = 0; + int32_t frame_totle_samples = 0; + + frame_totle_samples = sync_trigger->audio_info.totalSubSequenceNumber * sync_trigger->audio_info.frame_samples; + timestamp_diff = sync_trigger->audio_info.timestamp - header->timestamp; + + TRACE_AUD_STREAM_I("[AUTO_SYNC][DATAIND] seq:%d/%d timestamp:%d/%d cnt:%d", header->sequenceNumber, + sync_trigger->audio_info.sequenceNumber, + header->timestamp, + sync_trigger->audio_info.timestamp, + app_bt_stream_ibrt_auto_synchronize_cnt); + + if (++app_bt_stream_ibrt_auto_synchronize_cnt > APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_CNT_LIMIT){ + app_bt_stream_ibrt_auto_synchronize_stop(); + TRACE_AUD_STREAM_W("[AUTO_SYNC][DATAIND] SYNCHRONIZE_CNT_LIMIT, we need force retrigger"); + app_ibrt_if_force_audio_retrigger(); + }else if (app_tws_ibrt_mobile_link_connected()){ + app_bt_stream_ibrt_auto_synchronize_stop(); + TRACE_AUD_STREAM_W("[AUTO_SYNC][DATAIND] find role to master, we need force retrigger"); + app_ibrt_if_force_audio_retrigger(); + }else if (sync_trigger->audio_info.sequenceNumber < header->sequenceNumber){ + app_bt_stream_ibrt_auto_synchronize_stop(); + TRACE_AUD_STREAM_W("[AUTO_SYNC][DATAIND] seq timestamp:%d/%d mismatch need resume", header->timestamp, + sync_trigger->audio_info.timestamp); + app_ibrt_if_force_audio_retrigger(); + }else{ + if (header->sequenceNumber >= sync_trigger->audio_info.sequenceNumber && + !sync_trigger->audio_info.totalSubSequenceNumber){ + synchronize_ok = true; + }else if (header->timestamp == sync_trigger->audio_info.timestamp){ + synchronize_ok = true; + } + + dma_buffer_samples = app_bt_stream_get_dma_buffer_samples()/2; + + if (sync_trigger->audio_info.timestamp >= header->timestamp && sync_trigger->audio_info.totalSubSequenceNumber){ + if (timestamp_diff < dma_buffer_samples){ + TRACE_AUD_STREAM_I("[AUTO_SYNC][DATAIND] timestamp_diff < dma_buffer_samples synchronize ok"); + synchronize_ok = true; + }else if (timestamp_diff < frame_totle_samples){ + TRACE_AUD_STREAM_I("[AUTO_SYNC][DATAIND] timestamp_diff < frame_totle_samples synchronize ok"); + synchronize_ok = true; + } + } + + if (!synchronize_ok && header->sequenceNumber >= sync_trigger->audio_info.sequenceNumber){ + + TRACE_AUD_STREAM_I("[AUTO_SYNC][DATAIND] timestamp %d vs %d", sync_trigger->audio_info.timestamp - header->timestamp, + frame_totle_samples); + if ((sync_trigger->audio_info.timestamp - header->timestamp) <= (uint32_t)(frame_totle_samples*3)){ + sync_trigger->audio_info.sequenceNumber++; + TRACE_AUD_STREAM_I("[AUTO_SYNC][DATAIND] timestamp try sequenceNumber:%d", header->sequenceNumber); + } + } + + //flush all + a2dp_audio_synchronize_dest_packet_mut(0); + + if (synchronize_ok){ + A2DP_AUDIO_LASTFRAME_INFO_T lastframe_info; + if (a2dp_audio_lastframe_info_get(&lastframe_info) < 0){ + TRACE_AUD_STREAM_I("[AUTO_SYNC][DATAIND]synchronize ok but lastframe error"); + goto exit; + } + + TRACE_AUD_STREAM_I("[AUTO_SYNC][DATAIND]synchronize ok timestamp_diff:%d frame_samples:%d", timestamp_diff, + lastframe_info.frame_samples); + sync_trigger->trigger_type = APP_TWS_IBRT_AUDIO_TRIGGER_TYPE_LOCAL; + sync_trigger->audio_info.sequenceNumber = header->sequenceNumber; + sync_trigger->audio_info.timestamp = header->timestamp; + if (sync_trigger->audio_info.totalSubSequenceNumber){ + sync_trigger->audio_info.curSubSequenceNumber = timestamp_diff/lastframe_info.frame_samples; + TRACE_AUD_STREAM_I("[AUTO_SYNC][DATAIND]synchronize ok tstmp_diff:%d/%d SubSeq:%d", timestamp_diff, sync_trigger->audio_info.frame_samples, + sync_trigger->audio_info.curSubSequenceNumber); + }else{ + sync_trigger->audio_info.curSubSequenceNumber = 0; + } + sync_trigger->audio_info.totalSubSequenceNumber = lastframe_info.totalSubSequenceNumber; + sync_trigger->audio_info.frame_samples = lastframe_info.frame_samples; + if (sync_trigger->audio_info.totalSubSequenceNumber && + sync_trigger->audio_info.curSubSequenceNumber >= sync_trigger->audio_info.totalSubSequenceNumber){ + TRACE_AUD_STREAM_W("[AUTO_SYNC][DATAIND]synchronize ok but sbc & timestamp is ms so force trigger"); + app_bt_stream_ibrt_auto_synchronize_stop(); + app_ibrt_if_force_audio_retrigger(); + }else{ + a2dp_audio_detect_store_packet_callback_register(app_bt_stream_ibrt_auto_synchronize_trigger_start); + } + }else{ + a2dp_audio_detect_first_packet(); + } + } +exit: + return 0; +} + +void app_bt_stream_ibrt_auto_synchronize_start(APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger) +{ + TRACE_AUD_STREAM_I("[AUTO_SYNC][DATAIND] trigger_time:%d seq:%d timestamp:%d SubSeq:%d/%d", sync_trigger->trigger_time, + sync_trigger->audio_info.sequenceNumber, + sync_trigger->audio_info.timestamp, + sync_trigger->audio_info.curSubSequenceNumber, + sync_trigger->audio_info.totalSubSequenceNumber + ); + app_bt_stream_ibrt_auto_synchronize_status_set(APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_ONPROCESS); + app_bt_stream_ibrt_auto_synchronize_cnt = 0; + app_bt_stream_ibrt_auto_synchronize_trigger = *sync_trigger; + a2dp_audio_detect_next_packet_callback_register(app_bt_stream_ibrt_auto_synchronize_dataind_cb); + a2dp_audio_detect_first_packet(); +} + + +void app_bt_stream_ibrt_auto_synchronize_hungup(void) +{ + a2dp_audio_detect_next_packet_callback_register(NULL); + a2dp_audio_detect_store_packet_callback_register(NULL); +} + +void app_bt_stream_ibrt_auto_synchronize_stop(void) +{ + app_bt_stream_ibrt_auto_synchronize_hungup(); + app_bt_stream_ibrt_auto_synchronize_cnt = 0; + app_bt_stream_ibrt_auto_synchronize_status_set(APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_IDLE); +} + +bool app_bt_stream_ibrt_auto_synchronize_on_porcess(void) +{ + bool nRet = true; + APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_TYPE synchronize_status = app_bt_stream_ibrt_auto_synchronize_status_get(); + if (synchronize_status == APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_IDLE){ + nRet = false; + } + return nRet; +} + +void app_bt_stream_ibrt_start_sbc_player_callback(uint32_t status, uint32_t param) +{ + if (app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC)){ + TRACE_AUD_STREAM_I("start_sbc_player_cb trigger(%d)-->tg(%d)", param, ((APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *)(uintptr_t)param)->trigger_time); + app_bt_stream_ibrt_set_trigger_time((APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *)(uintptr_t)param); + }else{ + TRACE_AUD_STREAM_I("start_sbc_player_cb try again"); + app_audio_manager_sendrequest_need_callback( + APP_BT_STREAM_MANAGER_START,BT_STREAM_SBC, + BT_DEVICE_ID_1, + MAX_RECORD_NUM, + (uint32_t)(uintptr_t)app_bt_stream_ibrt_start_sbc_player_callback, + (uint32_t)param); + } +} + +int app_bt_stream_ibrt_start_sbc_player(APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger) +{ + TRACE_AUD_STREAM_I("start_sbc_player tg(%d)", sync_trigger->trigger_time); + app_audio_manager_sendrequest_need_callback( + APP_BT_STREAM_MANAGER_START,BT_STREAM_SBC, + BT_DEVICE_ID_1, + MAX_RECORD_NUM, + (uint32_t)(uintptr_t)app_bt_stream_ibrt_start_sbc_player_callback, + (uint32_t)(uintptr_t)sync_trigger); + return 0; +} + +uint16_t app_bt_stream_ibrt_trigger_seq_diff_calc(int32_t dma_samples, int32_t frame_samples, int32_t total_subseq, int32_t interval) +{ + float seq_factor = 1.0f; + if (total_subseq){ + seq_factor = (float)(dma_samples/frame_samples)/(float)total_subseq; + }else{ + seq_factor = (float)(dma_samples/frame_samples); + } + return (uint16_t)(seq_factor * (float)interval); +} + +#define MOBILE_LINK_PLAYBACK_INFO_TRIG_DUMMY_DMA_CNT (5) +#define SYNCHRONIZE_DATAIND_CNT_LIMIT (25) + +static int synchronize_need_discards_dma_cnt = 0; +static int synchronize_dataind_cnt = 0; + +int app_bt_stream_ibrt_auto_synchronize_initsync_dataind_cb_v2(btif_media_header_t * header, unsigned char *buf, unsigned int len) +{ + bool synchronize_ok = false; + bool discards_samples_finished = false; + int dest_discards_samples = 0; + uint32_t list_samples = 0; + uint32_t curr_ticks = 0; + A2DP_AUDIO_HEADFRAME_INFO_T headframe_info; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger = &app_bt_stream_ibrt_auto_synchronize_trigger; + + synchronize_dataind_cnt++; + if (app_tws_ibrt_mobile_link_connected()){ + TRACE_AUD_STREAM_W("[AUTO_SYNCV2] mobile_link is connect retrigger because role switch"); + app_ibrt_if_force_audio_retrigger(); + return 0; + } + + if (synchronize_dataind_cnt >= SYNCHRONIZE_DATAIND_CNT_LIMIT){ + TRACE_AUD_STREAM_W("[AUTO_SYNCV2] mobile_link is connect retrigger because CNT_LIMIT"); + app_ibrt_if_force_audio_retrigger(); + return 0; + } + + dest_discards_samples = app_bt_stream_get_dma_buffer_samples()/2*synchronize_need_discards_dma_cnt; + a2dp_audio_convert_list_to_samples(&list_samples); + if ((int)list_samples > dest_discards_samples){ + discards_samples_finished = true; + a2dp_audio_discards_samples(dest_discards_samples); + } + a2dp_audio_decoder_headframe_info_get(&headframe_info); + TRACE_AUD_STREAM_I("[AUTO_SYNCV2] sample:%d->%d seq:%d sub_seq:%d/%d", + list_samples,dest_discards_samples, + headframe_info.sequenceNumber, + headframe_info.curSubSequenceNumber, + headframe_info.totalSubSequenceNumber); + + curr_ticks = bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle); + TRACE_AUD_STREAM_I("[AUTO_SYNCV2] trig:%x/%x", curr_ticks, sync_trigger->trigger_time); + + if (discards_samples_finished){ + if (sync_trigger->trigger_time > curr_ticks){ + synchronize_ok = true; + }else{ + TRACE_AUD_STREAM_I("[AUTO_SYNCV2] synchronize_failed"); + app_ibrt_if_force_audio_retrigger(); + return 0; + } + } + if (synchronize_ok){ + TRACE_AUD_STREAM_I("[AUTO_SYNCV2] synchronize_ok"); + tg_acl_trigger_time = sync_trigger->trigger_time; + btdrv_syn_trigger_codec_en(1); + btdrv_syn_clr_trigger(); + btdrv_enable_playback_triggler(ACL_TRIGGLE_MODE); + bt_syn_set_tg_ticks(sync_trigger->trigger_time, p_ibrt_ctrl->ibrt_conhandle, BT_TRIG_SLAVE_ROLE); + app_tws_ibrt_audio_analysis_start(sync_trigger->handler_cnt, AUDIO_ANALYSIS_CHECKER_INTERVEL_INVALID); + app_tws_ibrt_audio_sync_start(); + app_tws_ibrt_audio_sync_new_reference(sync_trigger->factor_reference); + TRACE_AUD_STREAM_I("[AUTO_SYNCV2] trigger curr(%d)-->tg(%d)", + bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle), + sync_trigger->trigger_time); + synchronize_need_discards_dma_cnt = 0; + synchronize_dataind_cnt = 0; + a2dp_audio_detect_first_packet_clear(); + a2dp_audio_detect_next_packet_callback_register(NULL); + a2dp_audio_detect_store_packet_callback_register(NULL); + }else{ + a2dp_audio_detect_first_packet(); + } + + return 0; +} + +void app_bt_stream_ibrt_mobile_link_playback_info_receive(APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger) +{ + uint32_t tg_tick = 0; + uint32_t next_dma_cnt = 0; + A2DP_AUDIO_LASTFRAME_INFO_T lastframe_info; + A2DP_AUDIO_SYNCFRAME_INFO_T sync_info; + A2DP_AUDIO_HEADFRAME_INFO_T headframe_info; + APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger_loc = &app_bt_stream_ibrt_auto_synchronize_trigger; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + TRACE_AUD_STREAM_I("[AUTO_SYNCV2][INFO_RECV] session:%d hdl:%d clk:%d cnt:%d seq:%d/%d/%d", sync_trigger->a2dp_session, + sync_trigger->handler_cnt, + sync_trigger->trigger_bt_clk, + sync_trigger->trigger_bt_cnt, + sync_trigger->audio_info.sequenceNumber, + sync_trigger->audio_info.curSubSequenceNumber, + sync_trigger->audio_info.totalSubSequenceNumber); + + if (app_bt_stream_ibrt_auto_synchronize_on_porcess()){ + TRACE_AUD_STREAM_W("[AUTO_SYNCV2][INFO_RECV] auto_synchronize_on_porcess skip it"); + return; + } + + if (!app_bt_is_a2dp_streaming(BTIF_DEVICE_ID_1)){ + TRACE_AUD_STREAM_W("[AUTO_SYNCV2][INFO_RECV] streaming not ready skip it"); + app_bt_stream_ibrt_audio_mismatch_stopaudio(); + return; + } + + if (a2dp_ibrt_session_get() != sync_trigger->a2dp_session){ + TRACE_AUD_STREAM_W("[AUTO_SYNCV2][INFO_RECV] session mismatch skip it loc:%d rmt:%d", a2dp_ibrt_session_get(), sync_trigger->a2dp_session); + TRACE_AUD_STREAM_W("[AUTO_SYNCV2][INFO_RECV] session froce resume and try retrigger"); + a2dp_ibrt_session_set(sync_trigger->a2dp_session); + app_bt_stream_ibrt_audio_mismatch_stopaudio(); + return; + } + + if (a2dp_audio_lastframe_info_get(&lastframe_info) < 0){ + TRACE_AUD_STREAM_W("[AUTO_SYNCV2][INFO_RECV] lastframe not ready mismatch_stopaudio"); + app_bt_stream_ibrt_audio_mismatch_stopaudio(); + return; + } + + *sync_trigger_loc = *sync_trigger; + + sync_info.sequenceNumber = sync_trigger->audio_info.sequenceNumber; + sync_info.timestamp = sync_trigger->audio_info.timestamp; + sync_info.curSubSequenceNumber = sync_trigger->audio_info.curSubSequenceNumber; + sync_info.totalSubSequenceNumber = sync_trigger->audio_info.totalSubSequenceNumber; + sync_info.frame_samples = sync_trigger->audio_info.frame_samples; + if (a2dp_audio_synchronize_packet(&sync_info, A2DP_AUDIO_SYNCFRAME_MASK_ALL)){ + TRACE_AUD_STREAM_W("[AUTO_SYNCV2][INFO_RECV] synchronize_packe mismatch"); + app_ibrt_if_force_audio_retrigger(); + return; + } + + a2dp_audio_decoder_headframe_info_get(&headframe_info); + TRACE_AUD_STREAM_I("[AUTO_SYNCV2][INFO_RECV] sync with master packet step1 seq:%d sub_seq:%d/%d", + headframe_info.sequenceNumber, + headframe_info.curSubSequenceNumber, + headframe_info.totalSubSequenceNumber); + a2dp_audio_discards_samples(lastframe_info.list_samples); + a2dp_audio_decoder_headframe_info_get(&headframe_info); + TRACE_AUD_STREAM_I("[AUTO_SYNCV2][INFO_RECV] sync with master packet step2 seq:%d sub_seq:%d/%d", + headframe_info.sequenceNumber, + headframe_info.curSubSequenceNumber, + headframe_info.totalSubSequenceNumber); + + uint32_t btclk; + uint16_t btcnt; + uint32_t mobile_master_clk = 0; + uint16_t mobile_master_cnt = 0; + int64_t mobile_master_us = 0; + btclk = btdrv_syn_get_curr_ticks()/2; + btcnt = 0; + app_tws_ibrt_audio_mobile_clkcnt_get(btclk, btcnt, + &mobile_master_clk, &mobile_master_cnt); + mobile_master_us = (int64_t)mobile_master_clk * (int64_t)SLOT_SIZE + (int64_t)mobile_master_cnt; + + uint32_t rmt_mobile_master_clk = sync_trigger->trigger_bt_clk; + uint16_t rmt_mobile_master_cnt = sync_trigger->trigger_bt_cnt; + int64_t rmt_mobile_master_us = 0; + int64_t tmp_mobile_master_us = 0; + rmt_mobile_master_us = (int64_t)rmt_mobile_master_clk * (int64_t)SLOT_SIZE + (int64_t)rmt_mobile_master_cnt; + + uint32_t dma_buffer_us = 0; + dma_buffer_us = app_bt_stream_get_dma_buffer_delay_us()/2; + + tmp_mobile_master_us = rmt_mobile_master_us; + do{ + if (tmp_mobile_master_us - mobile_master_us >= 0){ + break; + } + tmp_mobile_master_us += dma_buffer_us; + next_dma_cnt++; + }while(1); + next_dma_cnt += MOBILE_LINK_PLAYBACK_INFO_TRIG_DUMMY_DMA_CNT ; + tmp_mobile_master_us += dma_buffer_us * (MOBILE_LINK_PLAYBACK_INFO_TRIG_DUMMY_DMA_CNT-1); + synchronize_need_discards_dma_cnt = next_dma_cnt + a2dp_audio_frame_delay_get() - 1; + synchronize_dataind_cnt = 0; + TRACE_AUD_STREAM_I("[AUTO_SYNCV2][INFO_RECV] loc:%08x%08x rmt:%08x%08x tg:%08x%08x", (uint32_t)((uint64_t)mobile_master_us>>32U), (uint32_t)((uint64_t)mobile_master_us&0xffffffff), + (uint32_t)((uint64_t)rmt_mobile_master_us>>32U), (uint32_t)((uint64_t)rmt_mobile_master_us&0xffffffff), + (uint32_t)((uint64_t)tmp_mobile_master_us>>32U), (uint32_t)((uint64_t)tmp_mobile_master_us&0xffffffff)); + + tmp_mobile_master_us = tmp_mobile_master_us/SLOT_SIZE; + + tg_tick = tmp_mobile_master_us * 2; + tg_tick &= 0x0fffffff; + + sync_trigger_loc->trigger_type = APP_TWS_IBRT_AUDIO_TRIGGER_TYPE_LOCAL; + sync_trigger_loc->trigger_time = tg_tick; + sync_trigger_loc->handler_cnt += next_dma_cnt; + a2dp_audio_detect_next_packet_callback_register(app_bt_stream_ibrt_auto_synchronize_initsync_dataind_cb_v2); + a2dp_audio_detect_first_packet(); + + + TRACE_AUD_STREAM_I("[AUTO_SYNCV2][INFO_RECV] mobile clk:%x/%x tg:%x", bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle)/2, + mobile_master_clk, + tg_tick/2); + + TRACE_AUD_STREAM_I("[AUTO_SYNCV2][INFO_RECV] master_us:%x/%x/%x dma_cnt:%d/%d", (int32_t)mobile_master_us, (int32_t)rmt_mobile_master_us, (int32_t)tmp_mobile_master_us, + next_dma_cnt, sync_trigger_loc->handler_cnt); +} + + +void app_bt_stream_ibrt_set_trigger_time(APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger) +{ + uint32_t curr_ticks = 0; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + uint32_t tg_tick = sync_trigger->trigger_time; + A2DP_AUDIO_SYNCFRAME_INFO_T sync_info; + int synchronize_ret; + A2DP_AUDIO_LASTFRAME_INFO_T lastframe_info; + A2DP_AUDIO_HEADFRAME_INFO_T headframe_info; + + if (app_bt_stream_ibrt_auto_synchronize_on_porcess()){ + TRACE_AUD_STREAM_W("[STRM_TRIG][A2DP][IBRT] auto_synchronize_on_porcess skip it"); + return; + } + + if (!app_bt_is_a2dp_streaming(BTIF_DEVICE_ID_1)){ + TRACE_AUD_STREAM_W("[STRM_TRIG][A2DP][IBRT] streaming not ready skip it"); + app_bt_stream_ibrt_audio_mismatch_stopaudio(); + return; + } + + if (a2dp_ibrt_session_get() != sync_trigger->a2dp_session){ + TRACE_AUD_STREAM_W("[STRM_TRIG][A2DP][IBRT] session mismatch skip it loc:%d rmt:%d", a2dp_ibrt_session_get(), sync_trigger->a2dp_session); + TRACE_AUD_STREAM_W("[STRM_TRIG][A2DP][IBRT] session froce resume and try retrigger"); + a2dp_ibrt_session_set(sync_trigger->a2dp_session); + app_bt_stream_ibrt_audio_mismatch_stopaudio(); + return; + } + + if (a2dp_audio_lastframe_info_get(&lastframe_info) < 0){ + TRACE_AUD_STREAM_W("[STRM_TRIG][A2DP][IBRT] lastframe not ready mismatch_stopaudio"); + app_bt_stream_ibrt_audio_mismatch_stopaudio(); + return; + } + + if (a2dp_audio_decoder_headframe_info_get(&headframe_info) < 0){ + TRACE_AUD_STREAM_W("[STRM_TRIG][A2DP][IBRT] lastframe not ready mismatch_stopaudio"); + app_bt_stream_ibrt_audio_mismatch_stopaudio(); + goto exit; + } + TRACE_AUD_STREAM_W("[STRM_TRIG][A2DP][IBRT] info base_seq:%d/%d", headframe_info.sequenceNumber, sync_trigger->sequenceNumberStart); + + a2dp_audio_detect_next_packet_callback_register(NULL); + a2dp_audio_detect_store_packet_callback_register(NULL); + + sync_info.sequenceNumber = sync_trigger->sequenceNumberStart; + synchronize_ret = a2dp_audio_synchronize_packet(&sync_info, A2DP_AUDIO_SYNCFRAME_MASK_SEQ); + if (synchronize_ret){ + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][IBRT] synchronize_packet failed"); + app_bt_stream_ibrt_audio_mismatch_stopaudio(); + goto exit; + } + + curr_ticks = bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle); + if (tg_tick < curr_ticks){ + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][IBRT] synchronize tick failed:%x->%x", curr_ticks, tg_tick); + app_bt_stream_ibrt_audio_mismatch_stopaudio(); + goto exit; + } + sync_info.sequenceNumber = sync_trigger->audio_info.sequenceNumber; + sync_info.timestamp = sync_trigger->audio_info.timestamp; + sync_info.curSubSequenceNumber = sync_trigger->audio_info.curSubSequenceNumber; + sync_info.totalSubSequenceNumber = sync_trigger->audio_info.totalSubSequenceNumber; + sync_info.frame_samples = sync_trigger->audio_info.frame_samples; + + if (app_tws_ibrt_slave_ibrt_link_connected()){ + if (app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC)){ + if (sync_trigger->trigger_type == APP_TWS_IBRT_AUDIO_TRIGGER_TYPE_INIT_SYNC){ + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][IBRT] TRIGGER_TYPE_INIT_SYNC needskip:%d", sync_trigger->trigger_skip_frame); + //limter to water line upper + uint32_t list_samples = 0; + uint32_t limter_water_line_samples = 0; + limter_water_line_samples = (a2dp_audio_dest_packet_mut_get() * lastframe_info.list_samples); + a2dp_audio_convert_list_to_samples(&list_samples); + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][IBRT] synchronize:%d/%d", list_samples, limter_water_line_samples); + if (list_samples > limter_water_line_samples){ + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][IBRT] skip discards:%d", list_samples - limter_water_line_samples); + a2dp_audio_discards_samples(list_samples - limter_water_line_samples); + } + app_bt_stream_ibrt_auto_synchronize_initsync_start(sync_trigger); + app_bt_stream_ibrt_auto_synchronize_status_set(APP_TWS_IBRT_AUDIO_SYNCHRONIZE_STATUS_SYNCOK); + } + }else if (!app_bt_stream_isrun(APP_BT_STREAM_HFP_PCM)){ + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][IBRT] sbc player not active, so try to start it"); + app_bt_stream_ibrt_auto_synchronize_trigger = *sync_trigger; + app_bt_stream_ibrt_audio_mismatch_stopaudio(); + } + }else{ + TRACE_AUD_STREAM_W("[STRM_TRIG][A2DP][IBRT] Not Connected"); + } +exit: + return; +} + +void app_bt_stream_ibrt_audio_mismatch_resume(void) +{ + ibrt_a2dp_status_t a2dp_status; + + a2dp_ibrt_sync_get_status(&a2dp_status); + + TRACE_AUD_STREAM_I("[MISMATCH] resume state:%d", a2dp_status.state); + + if (a2dp_status.state == BTIF_AVDTP_STRM_STATE_STREAMING){ + if (app_tws_ibrt_mobile_link_connected()){ + TRACE_AUD_STREAM_I("[MISMATCH] resume find role switch so force retrigger"); + app_ibrt_if_force_audio_retrigger(); + }else{ + app_tws_ibrt_audio_sync_mismatch_resume_notify(); + } + } +} + +void app_bt_stream_ibrt_audio_mismatch_stopaudio_cb(uint32_t status, uint32_t param) +{ + TRACE_AUD_STREAM_I("[MISMATCH] stopaudio_cb"); + + if (app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC)){ + TRACE_AUD_STREAM_I("[MISMATCH] stopaudio_cb try again"); + app_audio_manager_sendrequest_need_callback( + APP_BT_STREAM_MANAGER_STOP,BT_STREAM_SBC, + BT_DEVICE_ID_1, + MAX_RECORD_NUM, + (uintptr_t)app_bt_stream_ibrt_audio_mismatch_stopaudio_cb, + (uint32_t)NULL); + }else{ + app_bt_stream_ibrt_audio_mismatch_resume(); + } +} + +int app_bt_stream_ibrt_audio_mismatch_stopaudio(void) +{ + ibrt_a2dp_status_t a2dp_status; + + a2dp_ibrt_sync_get_status(&a2dp_status); + + TRACE_AUD_STREAM_I("[MISMATCH] stopaudio state:%d sco:%d sbc:%d media:%d", a2dp_status.state, + app_audio_manager_hfp_is_active(BT_DEVICE_ID_1), + app_audio_manager_a2dp_is_active(BT_DEVICE_ID_1), + app_bt_stream_isrun(APP_PLAY_BACK_AUDIO)); + + if (a2dp_status.state == BTIF_AVDTP_STRM_STATE_STREAMING){ + if (app_audio_manager_a2dp_is_active(BT_DEVICE_ID_1)){ + TRACE_AUD_STREAM_I("[MISMATCH] stopaudio"); + app_audio_sendrequest_param(APP_BT_STREAM_A2DP_SBC, (uint8_t)APP_BT_SETTING_RESTART, 0, APP_SYSFREQ_52M); + app_bt_stream_ibrt_audio_mismatch_resume(); + }else{ + if (app_ibrt_ui_is_profile_exchanged()){ + if (!bt_media_is_sbc_media_active()){ + TRACE_AUD_STREAM_I("[MISMATCH] stopaudio not active resume it & force retrigger"); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,BT_STREAM_SBC, BT_DEVICE_ID_1,MAX_RECORD_NUM); + app_ibrt_if_force_audio_retrigger(); + }else{ + if (app_bt_stream_isrun(APP_PLAY_BACK_AUDIO) +#ifdef MEDIA_PLAYER_SUPPORT + &&app_play_audio_get_aud_id() == AUDIO_ID_BT_MUTE +#endif + ){ + TRACE_AUD_STREAM_I("[MISMATCH] stopaudio resum on process skip it"); + }else{ + TRACE_AUD_STREAM_I("[MISMATCH] stopaudio cancel_media and force retrigger"); + app_ibrt_if_force_audio_retrigger(); + } + } + }else{ + TRACE_AUD_STREAM_I("[MISMATCH] stopaudio profile not exchanged skip it"); + } + } + } + + return 0; +} +#endif + +void app_bt_stream_set_trigger_time(uint32_t trigger_time_us) +{ + struct AF_STREAM_CONFIG_T *stream_cfg = NULL; + uint32_t curr_ticks = 0; + uint32_t dma_buffer_delay_us = 0; + uint32_t tg_acl_trigger_offset_time = 0; + + + if (trigger_time_us){ +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + uint16_t conhandle = INVALID_HANDLE; + if (app_tws_ibrt_mobile_link_connected()){ + conhandle = p_ibrt_ctrl->mobile_conhandle; + curr_ticks = bt_syn_get_curr_ticks(conhandle); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + conhandle = p_ibrt_ctrl->ibrt_conhandle; + curr_ticks = bt_syn_get_curr_ticks(conhandle); + }else{ + return; + } +#else + curr_ticks = btdrv_syn_get_curr_ticks(); +#endif + af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg, false); + btdrv_syn_trigger_codec_en(0); + btdrv_syn_clr_trigger(); + + btdrv_enable_playback_triggler(ACL_TRIGGLE_MODE); + + dma_buffer_delay_us = app_bt_stream_get_dma_buffer_delay_us(); + dma_buffer_delay_us /= 2; + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][SETTIME] %d-%d-%d dma_sz:%d dly:%d", stream_cfg->sample_rate, stream_cfg->channel_num, stream_cfg->bits, + stream_cfg->data_size, dma_buffer_delay_us); + + tg_acl_trigger_offset_time = US_TO_BTCLKS(trigger_time_us-dma_buffer_delay_us); + tg_acl_trigger_time = curr_ticks + tg_acl_trigger_offset_time; + tg_acl_trigger_start_time = curr_ticks; +#if defined(IBRT) + bt_syn_set_tg_ticks(tg_acl_trigger_time, conhandle, BT_TRIG_SLAVE_ROLE); + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][SETTIME] %d->%d trig_dly:%d aud_dly:%dus", + curr_ticks, tg_acl_trigger_time, trigger_time_us-dma_buffer_delay_us, trigger_time_us+dma_buffer_delay_us); +#else + bt_syn_set_tg_ticks(tg_acl_trigger_time, 0, BT_TRIG_NONE_ROLE); + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][SETTIME] %d->%d trig_dly:%d aud_dly:%dus", + curr_ticks, tg_acl_trigger_time, trigger_time_us-dma_buffer_delay_us, trigger_time_us+dma_buffer_delay_us); +#endif + + btdrv_syn_trigger_codec_en(1); + app_bt_stream_trigger_stauts_set(BT_STREAM_TRIGGER_STATUS_WAIT); + }else{ + tg_acl_trigger_time = 0; + tg_acl_trigger_start_time = 0; + btdrv_syn_trigger_codec_en(0); + btdrv_syn_clr_trigger(); + app_bt_stream_trigger_stauts_set(BT_STREAM_TRIGGER_STATUS_NULL); + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][SETTIME] trigger clear"); + } +} + +void app_bt_stream_trigger_result(void) +{ + uint32_t curr_ticks = 0; + + if(tg_acl_trigger_time){ +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (app_tws_ibrt_mobile_link_connected()){ + curr_ticks = bt_syn_get_curr_ticks(p_ibrt_ctrl->mobile_conhandle); + bt_syn_trig_checker(p_ibrt_ctrl->mobile_conhandle); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + curr_ticks = bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle); + bt_syn_trig_checker(p_ibrt_ctrl->ibrt_conhandle); + }else{ + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][RESULT] mobile_link:%d %04x ibrt_link:%d %04x", app_tws_ibrt_mobile_link_connected(), p_ibrt_ctrl->mobile_conhandle, + app_tws_ibrt_slave_ibrt_link_connected(), p_ibrt_ctrl->ibrt_conhandle); + } +#else + curr_ticks = btdrv_syn_get_curr_ticks(); +#endif + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][RESULT] trig:%d curr:%d tg:%d start:%d", (curr_ticks - (uint32_t)US_TO_BTCLKS(app_bt_stream_get_dma_buffer_delay_us()/2)), + curr_ticks, tg_acl_trigger_time, tg_acl_trigger_start_time); + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][RESULT] tg_trig_diff:%d trig_diff:%d", (uint32_t)BTCLKS_TO_US(curr_ticks-tg_acl_trigger_time), + (uint32_t)BTCLKS_TO_US(curr_ticks-tg_acl_trigger_start_time)); + app_bt_stream_set_trigger_time(0); + app_bt_stream_trigger_stauts_set(BT_STREAM_TRIGGER_STATUS_OK); + A2DP_AUDIO_HEADFRAME_INFO_T headframe_info; + a2dp_audio_decoder_headframe_info_get(&headframe_info); + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][RESULT] synchronize_ok :%d", headframe_info.sequenceNumber); + } +} + +void app_bt_stream_playback_irq_notification(enum AUD_STREAM_ID_T id, enum AUD_STREAM_T stream) +{ + if (id != AUD_STREAM_ID_0 || stream != AUD_STREAM_PLAYBACK) { + return; + } + app_bt_stream_trigger_result(); +#if defined(IBRT) + app_tws_ibrt_audio_analysis_interrupt_tick(); +#endif +} +extern void a2dp_audio_set_mtu_limit(uint8_t mut); +extern float a2dp_audio_latency_factor_get(void); +extern uint8_t a2dp_lhdc_config_llc_get(void); + +void app_bt_stream_trigger_init(void) +{ +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (app_tws_ibrt_mobile_link_connected()){ + tg_acl_trigger_init_time = bt_syn_get_curr_ticks(p_ibrt_ctrl->mobile_conhandle); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + tg_acl_trigger_init_time = bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle); + }else{ + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][INIT] mobile_link:%d %04x ibrt_link:%d %04x", app_tws_ibrt_mobile_link_connected(), p_ibrt_ctrl->mobile_conhandle, + app_tws_ibrt_slave_ibrt_link_connected(), p_ibrt_ctrl->ibrt_conhandle); + } +#else + tg_acl_trigger_init_time = btdrv_syn_get_curr_ticks(); +#endif + app_bt_stream_set_trigger_time(0); +#ifdef PLAYBACK_USE_I2S + af_i2s_sync_config(AUD_STREAM_PLAYBACK, AF_I2S_SYNC_TYPE_BT, false); + af_i2s_sync_config(AUD_STREAM_PLAYBACK, AF_I2S_SYNC_TYPE_BT, true); +#else + af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, false); + af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, true); +#endif + app_bt_stream_trigger_stauts_set(BT_STREAM_TRIGGER_STATUS_INIT); +} + +void app_bt_stream_trigger_deinit(void) +{ + app_bt_stream_set_trigger_time(0); +} + +void app_bt_stream_trigger_start(uint8_t offset) +{ + float tg_trigger_time = 0; + uint32_t curr_ticks; + struct AF_STREAM_CONFIG_T *stream_cfg = NULL; + af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg, false); + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (app_tws_ibrt_mobile_link_connected()){ + curr_ticks = bt_syn_get_curr_ticks(p_ibrt_ctrl->mobile_conhandle); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + curr_ticks = bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle); + }else{ + return; + } +#else + curr_ticks = btdrv_syn_get_curr_ticks(); +#endif + + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][START] init(%d)-->set_trig(%d) %dus", tg_acl_trigger_init_time, curr_ticks, (uint32_t)BTCLKS_TO_US(curr_ticks-tg_acl_trigger_init_time)); + +#if defined(A2DP_AAC_ON) + if(bt_sbc_player_get_codec_type() == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC){ + tg_trigger_time = A2DP_PLAYER_PLAYBACK_DELAY_AAC_US * a2dp_audio_latency_factor_get(); + tg_trigger_time += offset*A2DP_PLAYER_PLAYBACK_DELAY_AAC_BASE; +#if (A2DP_DECODER_VER < 2) + a2dp_audio_set_mtu_limit(A2DP_PLAYER_PLAYBACK_DELAY_AAC_MTU); +#endif + }else +#endif + if(bt_sbc_player_get_codec_type() == BTIF_AVDTP_CODEC_TYPE_NON_A2DP){ +#if defined(A2DP_SCALABLE_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_SCALABLE){ + if(stream_cfg->sample_rate > AUD_SAMPRATE_48000){ + tg_trigger_time = A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_HIRES_US * a2dp_audio_latency_factor_get(); + + tg_trigger_time += offset*A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_HIRES_BASE; +#if (A2DP_DECODER_VER < 2) + a2dp_audio_set_mtu_limit(A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_HIRES_MTU); +#endif + }else{ + tg_trigger_time = A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_BASERES_US * a2dp_audio_latency_factor_get(); + tg_trigger_time += offset*A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_BASERES_BASE; +#if (A2DP_DECODER_VER < 2) + a2dp_audio_set_mtu_limit(A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_BASERES_MTU); +#endif + } + } +#endif +#if defined(A2DP_LHDC_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LHDC){ + if (a2dp_lhdc_config_llc_get()){ + tg_trigger_time = A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_US * a2dp_audio_latency_factor_get(); + tg_trigger_time += offset*A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_BASE; +#if (A2DP_DECODER_VER < 2) + a2dp_audio_set_mtu_limit(A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_MTU); +#endif + }else if(stream_cfg->sample_rate > AUD_SAMPRATE_48000){ + tg_trigger_time = A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_US * a2dp_audio_latency_factor_get(); + tg_trigger_time += offset*A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_BASE; +#if (A2DP_DECODER_VER < 2) + a2dp_audio_set_mtu_limit(A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_MTU); +#endif + }else{ + tg_trigger_time = A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_US * a2dp_audio_latency_factor_get(); + tg_trigger_time += offset*A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_BASE; +#if (A2DP_DECODER_VER < 2) + a2dp_audio_set_mtu_limit(A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_MTU); +#endif + } + } +#endif +#if defined(A2DP_LDAC_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LDAC){ + uint32_t frame_mtu = A2DP_PLAYER_PLAYBACK_DELAY_LDAC_FRAME_MTU; +#if (A2DP_DECODER_VER == 2) + A2DP_AUDIO_LASTFRAME_INFO_T lastframe_info; + if (!a2dp_audio_lastframe_info_get(&lastframe_info)){ + frame_mtu = lastframe_info.totalSubSequenceNumber; + } +#endif + tg_trigger_time = A2DP_PLAYER_PLAYBACK_DELAY_LDAC_US * a2dp_audio_latency_factor_get(); + tg_trigger_time += offset*A2DP_PLAYER_PLAYBACK_DELAY_LDAC_BASE*frame_mtu; +#if (A2DP_DECODER_VER < 2) + a2dp_audio_set_mtu_limit(A2DP_PLAYER_PLAYBACK_DELAY_LDAC_MTU); +#endif + TRACE_AUD_STREAM_I("[STRM_TRIG][A2DP][START] [%d,%d,%d]", A2DP_PLAYER_PLAYBACK_DELAY_LDAC_MTU,A2DP_PLAYER_PLAYBACK_DELAY_LDAC_BASE,A2DP_PLAYER_PLAYBACK_DELAY_LDAC_US); + + } +#endif + }else + { + uint32_t frame_mtu = A2DP_PLAYER_PLAYBACK_DELAY_SBC_FRAME_MTU; +#if (A2DP_DECODER_VER == 2) + A2DP_AUDIO_LASTFRAME_INFO_T lastframe_info; + if (!a2dp_audio_lastframe_info_get(&lastframe_info)){ + frame_mtu = lastframe_info.totalSubSequenceNumber; + } +#endif + tg_trigger_time = A2DP_PLAYER_PLAYBACK_DELAY_SBC_US; + tg_trigger_time += offset*A2DP_PLAYER_PLAYBACK_DELAY_SBC_BASE*frame_mtu; +#if (A2DP_DECODER_VER < 2) + a2dp_audio_set_mtu_limit(A2DP_PLAYER_PLAYBACK_DELAY_SBC_MTU); +#endif + } + app_bt_stream_set_trigger_time((uint32_t)tg_trigger_time); +} + +bool app_bt_stream_trigger_onprocess(void) +{ + if (app_bt_stream_trigger_stauts_get() == BT_STREAM_TRIGGER_STATUS_INIT){ + return true; + }else{ + return false; + } +} + +#if defined(IBRT) +#ifdef A2DP_CP_ACCEL +#define APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME (8) +#define APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME_LHDC (12) + +#else +#define APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME (4) +#endif + +APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T app_bt_stream_ibrt_auto_synchronize_initsync_trigger; + +int app_bt_stream_ibrt_auto_synchronize_initsync_dataind_cb(btif_media_header_t * header, unsigned char *buf, unsigned int len) +{ + APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger = &app_bt_stream_ibrt_auto_synchronize_initsync_trigger; + bool synchronize_ok = false; + A2DP_AUDIO_LASTFRAME_INFO_T lastframe_info; + + TRACE_AUD_STREAM_I("[AUTO_SYNC][INITSYNC][DATAIND] dataind_seq:%d/%d timestamp:%d/%d", header->sequenceNumber, + sync_trigger->audio_info.sequenceNumber, + header->timestamp, + sync_trigger->audio_info.timestamp); + + if (a2dp_audio_lastframe_info_get(&lastframe_info)<0){ + TRACE_AUD_STREAM_W("[AUTO_SYNC][INITSYNC][DATAIND] force retrigger"); + app_ibrt_if_force_audio_retrigger(); + return 0; + } + + if (app_bt_stream_trigger_stauts_get() != BT_STREAM_TRIGGER_STATUS_WAIT){ + TRACE_AUD_STREAM_W("[AUTO_SYNC][INITSYNC][DATAIND] already end"); + a2dp_audio_detect_next_packet_callback_register(NULL); + a2dp_audio_detect_store_packet_callback_register(NULL); + return 0; + } + + if (sync_trigger->audio_info.sequenceNumber < header->sequenceNumber){ + TRACE_AUD_STREAM_W("[AUTO_SYNC][INITSYNC][DATAIND] force retrigger"); + app_ibrt_if_force_audio_retrigger(); + }else{ + if (header->sequenceNumber >= sync_trigger->audio_info.sequenceNumber){ + synchronize_ok = true; + } + + if (synchronize_ok && app_bt_stream_trigger_stauts_get() != BT_STREAM_TRIGGER_STATUS_WAIT){ + TRACE_AUD_STREAM_W("[AUTO_SYNC][INITSYNC][DATAIND] synchronize_failed"); + app_ibrt_if_force_audio_retrigger(); + return 0; + } +#ifdef A2DP_PLAYER_PLAYBACK_WATER_LINE + //limter to water line upper + uint32_t list_samples = 0; + uint32_t limter_water_line_samples = 0; + limter_water_line_samples = (a2dp_audio_dest_packet_mut_get() * lastframe_info.list_samples); + a2dp_audio_convert_list_to_samples(&list_samples); + TRACE_AUD_STREAM_W("[AUTO_SYNC][INITSYNC][DATAIND] synchronize:%d/%d", list_samples, limter_water_line_samples); + if (list_samples > limter_water_line_samples){ + TRACE_AUD_STREAM_W("[AUTO_SYNC][INITSYNC][DATAIND] skip discards:%d", list_samples - limter_water_line_samples); + a2dp_audio_discards_samples(list_samples - limter_water_line_samples); + } +#else + //flush all + a2dp_audio_synchronize_dest_packet_mut(0); +#endif + if (synchronize_ok){ + A2DP_AUDIO_HEADFRAME_INFO_T headframe_info; + a2dp_audio_decoder_headframe_info_get(&headframe_info); + TRACE_AUD_STREAM_W("[AUTO_SYNC][INITSYNC][DATAIND] synchronize_ok :%d", headframe_info.sequenceNumber); + a2dp_audio_detect_next_packet_callback_register(NULL); + a2dp_audio_detect_store_packet_callback_register(NULL); + }else{ + a2dp_audio_detect_first_packet(); + } + } + return 0; +} + +void app_bt_stream_ibrt_auto_synchronize_initsync_start(APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T *sync_trigger) +{ + TRACE_AUD_STREAM_I("[AUTO_SYNC][INITSYNC] start trigger_time:%d seq:%d timestamp:%d SubSeq:%d/%d", sync_trigger->trigger_time, + sync_trigger->audio_info.sequenceNumber, + sync_trigger->audio_info.timestamp, + sync_trigger->audio_info.curSubSequenceNumber, + sync_trigger->audio_info.totalSubSequenceNumber + ); + app_bt_stream_ibrt_auto_synchronize_initsync_trigger = *sync_trigger; + a2dp_audio_detect_next_packet_callback_register(app_bt_stream_ibrt_auto_synchronize_initsync_dataind_cb); + a2dp_audio_detect_first_packet(); + if (app_tws_ibrt_slave_ibrt_link_connected()){ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (sync_trigger->trigger_time > bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle)){ + uint32_t tg_tick = sync_trigger->trigger_time; + btdrv_syn_trigger_codec_en(1); + btdrv_syn_clr_trigger(); + btdrv_enable_playback_triggler(ACL_TRIGGLE_MODE); + bt_syn_set_tg_ticks(tg_tick, p_ibrt_ctrl->ibrt_conhandle, BT_TRIG_SLAVE_ROLE); + tg_acl_trigger_time = tg_tick; + app_bt_stream_trigger_stauts_set(BT_STREAM_TRIGGER_STATUS_WAIT); + TRACE_AUD_STREAM_I("[AUTO_SYNC][INITSYNC] start slave trigger curr(%d)-->tg(%d)", bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle), tg_tick); + app_tws_ibrt_audio_analysis_start(sync_trigger->handler_cnt, AUDIO_ANALYSIS_CHECKER_INTERVEL_INVALID); + app_tws_ibrt_audio_sync_start(); + app_tws_ibrt_audio_sync_new_reference(sync_trigger->factor_reference); + }else{ + TRACE_AUD_STREAM_I("[AUTO_SYNC][INITSYNC] start slave failed trigger(%d)-->tg(%d) need resume", + bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle), + sync_trigger->trigger_time); + app_tws_ibrt_audio_sync_mismatch_resume_notify(); + } + } +} + +int app_bt_stream_ibrt_audio_master_detect_next_packet_cb(btif_media_header_t * header, unsigned char *buf, unsigned int len) +{ +#ifdef A2DP_PLAYER_PLAYBACK_WATER_LINE + A2DP_AUDIO_SYNCFRAME_INFO_T sync_info; + A2DP_AUDIO_HEADFRAME_INFO_T headframe_info; +#endif + + if(app_bt_stream_trigger_stauts_get() == BT_STREAM_TRIGGER_STATUS_INIT){ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + int32_t dma_buffer_samples = app_bt_stream_get_dma_buffer_samples()/2; + + if (app_tws_ibrt_slave_ibrt_link_connected()){ + TRACE_AUD_STREAM_W("[AUTO_SYNC][MASTER] cache ok but currRole:%d mismatch\n", p_ibrt_ctrl->current_role); + app_ibrt_if_force_audio_retrigger(); + }else if (!app_ibrt_ui_is_profile_exchanged() && + !app_ibrt_if_start_ibrt_onporcess() && + !app_ibrt_sync_a2dp_status_onporcess()){ + if (p_ibrt_ctrl->mobile_mode == IBRT_SNIFF_MODE){ + //flush all + a2dp_audio_synchronize_dest_packet_mut(0); + a2dp_audio_detect_first_packet(); + TRACE_AUD_STREAM_I("[AUTO_SYNC][MASTER] cache skip delay dma trigger1\n"); + return 0; + } + TRACE_AUD_STREAM_I("[AUTO_SYNC][MASTER] cache ok use dma trigger1\n"); + a2dp_audio_detect_next_packet_callback_register(NULL); + a2dp_audio_detect_store_packet_callback_register(NULL); +#ifdef A2DP_PLAYER_PLAYBACK_WATER_LINE + app_bt_stream_trigger_start(A2DP_PLAYER_PLAYBACK_WATER_LINE); +#else + app_bt_stream_trigger_start(0); +#endif + }else if (app_ibrt_if_start_ibrt_onporcess() || + app_ibrt_sync_a2dp_status_onporcess() || + app_ibrt_waiting_cmd_rsp()){ + //flush all + a2dp_audio_synchronize_dest_packet_mut(0); + a2dp_audio_detect_first_packet(); + TRACE_AUD_STREAM_I("[AUTO_SYNC][MASTER] cache skip profile_exchanged sync_a2dp_status_onporcess\n"); + return 0; + }else{ + if (p_ibrt_ctrl->tws_mode == IBRT_SNIFF_MODE || + p_ibrt_ctrl->mobile_mode == IBRT_SNIFF_MODE){ + //flush all + a2dp_audio_synchronize_dest_packet_mut(0); + a2dp_audio_detect_first_packet(); + TRACE_AUD_STREAM_I("[AUTO_SYNC][MASTER] cache skip delay dma trigger2\n"); + return 0; + } + uint8_t codec_type = bt_sbc_player_get_codec_type(); +#ifdef A2DP_PLAYER_PLAYBACK_WATER_LINE + uint32_t dest_waterline_samples = 0; + uint32_t list_samples = 0; + dest_waterline_samples = app_bt_stream_get_dma_buffer_samples()/2*A2DP_PLAYER_PLAYBACK_WATER_LINE; + a2dp_audio_convert_list_to_samples(&list_samples); + if (list_samples < dest_waterline_samples){ + a2dp_audio_detect_first_packet(); + TRACE_AUD_STREAM_I("[AUTO_SYNC][MASTER] cache skip fill data sample:%d\n", list_samples); + return 0; + } + a2dp_audio_decoder_headframe_info_get(&headframe_info); + if(codec_type == BTIF_AVDTP_CODEC_TYPE_LHDC) + { + sync_info.sequenceNumber = headframe_info.sequenceNumber; + } + else + { + sync_info.sequenceNumber = headframe_info.sequenceNumber + 1; + } + a2dp_audio_synchronize_packet(&sync_info, A2DP_AUDIO_SYNCFRAME_MASK_SEQ); +#else + a2dp_audio_synchronize_dest_packet_mut(0); +#endif + TRACE_AUD_STREAM_I("[AUTO_SYNC][MASTER] cache ok use dma trigger2\n"); + //uint8_t codec_type = bt_sbc_player_get_codec_type(); +#ifdef A2DP_CP_ACCEL + if(codec_type == BTIF_AVDTP_CODEC_TYPE_LHDC) + { + app_bt_stream_trigger_start(APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME_LHDC - a2dp_audio_frame_delay_get()); + } + else + { + app_bt_stream_trigger_start(APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME - a2dp_audio_frame_delay_get()); + } +#else + app_bt_stream_trigger_start(APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME); +#endif + APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T sync_trigger; + A2DP_AUDIO_HEADFRAME_INFO_T headframe_info; + A2DP_AUDIO_LASTFRAME_INFO_T lastframe_info; + sync_trigger.trigger_time = tg_acl_trigger_time; + if(codec_type == BTIF_AVDTP_CODEC_TYPE_LHDC) + { + sync_trigger.trigger_skip_frame = APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME_LHDC - a2dp_audio_frame_delay_get(); + } + else + { + sync_trigger.trigger_skip_frame = APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME - a2dp_audio_frame_delay_get(); + } + sync_trigger.trigger_type = APP_TWS_IBRT_AUDIO_TRIGGER_TYPE_INIT_SYNC; + if (a2dp_audio_lastframe_info_get(&lastframe_info)<0){ + goto exit; + } + + a2dp_audio_decoder_headframe_info_get(&headframe_info); + sync_trigger.sequenceNumberStart = headframe_info.sequenceNumber; + if(codec_type == BTIF_AVDTP_CODEC_TYPE_LHDC) + { + sync_trigger.audio_info.sequenceNumber = lastframe_info.sequenceNumber + APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME_LHDC; + if (lastframe_info.totalSubSequenceNumber){ + sync_trigger.audio_info.timestamp = lastframe_info.timestamp + + (lastframe_info.totalSubSequenceNumber * lastframe_info.frame_samples) * + APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME_LHDC; + }else{ + sync_trigger.audio_info.timestamp = lastframe_info.timestamp + dma_buffer_samples * APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME_LHDC; + } + } + else + { + sync_trigger.audio_info.sequenceNumber = lastframe_info.sequenceNumber + APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME; + if (lastframe_info.totalSubSequenceNumber){ + sync_trigger.audio_info.timestamp = lastframe_info.timestamp + + (lastframe_info.totalSubSequenceNumber * lastframe_info.frame_samples) * + APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME; + }else{ + sync_trigger.audio_info.timestamp = lastframe_info.timestamp + dma_buffer_samples * APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME; + } + } + sync_trigger.audio_info.curSubSequenceNumber = lastframe_info.curSubSequenceNumber; + sync_trigger.audio_info.totalSubSequenceNumber = lastframe_info.totalSubSequenceNumber; + sync_trigger.audio_info.frame_samples = lastframe_info.frame_samples; + sync_trigger.factor_reference = a2dp_audio_get_output_config()->factor_reference; + sync_trigger.a2dp_session = a2dp_ibrt_session_get(); + sync_trigger.handler_cnt = 0; + + app_bt_stream_ibrt_auto_synchronize_initsync_start(&sync_trigger); + + if (app_tws_ibrt_mobile_link_connected() && + app_ibrt_ui_is_profile_exchanged()){ + tws_ctrl_send_cmd_high_priority(APP_TWS_CMD_SET_TRIGGER_TIME, (uint8_t*)&sync_trigger, sizeof(APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T)); + } + } + }else{ + if(app_bt_stream_trigger_stauts_get() == BT_STREAM_TRIGGER_STATUS_NULL){ + TRACE_AUD_STREAM_W("[AUTO_SYNC][MASTER] audio not ready skip it"); + }else{ + TRACE_AUD_STREAM_I("[AUTO_SYNC][MASTER] unhandle status:%d", app_bt_stream_trigger_stauts_get()); + app_ibrt_if_force_audio_retrigger(); + } + } +exit: + return 0; +} + +int app_bt_stream_ibrt_audio_master_detect_next_packet_start(void) +{ + TRACE_AUD_STREAM_I("[AUTO_SYNC][MASTER] start"); + + a2dp_audio_detect_next_packet_callback_register(app_bt_stream_ibrt_audio_master_detect_next_packet_cb); + return 0; +} + +#define SLAVE_DETECT_NEXT_PACKET_TO_RETRIGGER_THRESHOLD (120) +static uint32_t slave_detect_next_packet_cnt = 0; +int app_bt_stream_ibrt_audio_slave_detect_next_packet_waitforever_cb(btif_media_header_t * header, unsigned char *buf, unsigned int len) +{ + if (app_tws_ibrt_mobile_link_connected() || ++slave_detect_next_packet_cnt > SLAVE_DETECT_NEXT_PACKET_TO_RETRIGGER_THRESHOLD){ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TRACE_AUD_STREAM_W("[AUTO_SYNC][SLAVE] detect_next_packet ok but currRole:%d mismatch packet_cnt:%d\n", p_ibrt_ctrl->current_role, + slave_detect_next_packet_cnt); + slave_detect_next_packet_cnt = 0; + app_ibrt_if_force_audio_retrigger(); + }else{ + TRACE_AUD_STREAM_I("[AUTO_SYNC][SLAVE] detect_next_packet cnt:%d\n", slave_detect_next_packet_cnt); + a2dp_audio_detect_first_packet(); + } + return 0; +} + +int app_bt_stream_ibrt_audio_slave_detect_next_packet_cb(btif_media_header_t * header, unsigned char *buf, unsigned int len) +{ + if(app_bt_stream_trigger_onprocess()){ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + int32_t dma_buffer_samples = app_bt_stream_get_dma_buffer_samples()/2; + + if (app_tws_ibrt_mobile_link_connected()){ + TRACE_AUD_STREAM_W("[AUTO_SYNC][SLAVE]cache ok but currRole:%d mismatch\n", p_ibrt_ctrl->current_role); + app_ibrt_if_force_audio_retrigger(); + }else{ + if (app_tws_ibrt_slave_ibrt_link_connected() && + (p_ibrt_ctrl->tws_mode == IBRT_SNIFF_MODE || + p_ibrt_ctrl->mobile_mode == IBRT_SNIFF_MODE || + !app_ibrt_ui_is_profile_exchanged())){ + //flush all + a2dp_audio_synchronize_dest_packet_mut(0); + a2dp_audio_detect_first_packet(); + TRACE_AUD_STREAM_W("[AUTO_SYNC][SLAVE]cache skip delay dma trigger2\n"); + return 0; + } + TRACE_AUD_STREAM_I("[AUTO_SYNC][SLAVE]cache ok use dma trigger2\n"); + //flush all + a2dp_audio_synchronize_dest_packet_mut(0); + uint8_t codec_type = bt_sbc_player_get_codec_type(); +#ifdef A2DP_CP_ACCEL + if(codec_type == BTIF_AVDTP_CODEC_TYPE_LHDC) + { + app_bt_stream_trigger_start(APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME_LHDC - a2dp_audio_frame_delay_get()); + } + else + { + app_bt_stream_trigger_start(APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME - a2dp_audio_frame_delay_get()); + } +#else + app_bt_stream_trigger_start(APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME); +#endif + APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T sync_trigger = {0,}; + A2DP_AUDIO_LASTFRAME_INFO_T lastframe_info = {0,}; + sync_trigger.trigger_time = tg_acl_trigger_time; + if(codec_type == BTIF_AVDTP_CODEC_TYPE_LHDC) + { + sync_trigger.trigger_skip_frame = APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME_LHDC - a2dp_audio_frame_delay_get(); + } + else + { + sync_trigger.trigger_skip_frame = APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME - a2dp_audio_frame_delay_get(); + } + sync_trigger.trigger_type = APP_TWS_IBRT_AUDIO_TRIGGER_TYPE_INIT_SYNC; + if (a2dp_audio_lastframe_info_get(&lastframe_info)<0){ + goto exit; + } + if(codec_type == BTIF_AVDTP_CODEC_TYPE_LHDC) + { + sync_trigger.audio_info.sequenceNumber = lastframe_info.sequenceNumber + APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME_LHDC; + sync_trigger.audio_info.timestamp = lastframe_info.timestamp + dma_buffer_samples * APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME_LHDC; + } + else + { + sync_trigger.audio_info.sequenceNumber = lastframe_info.sequenceNumber + APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME; + sync_trigger.audio_info.timestamp = lastframe_info.timestamp + dma_buffer_samples * APP_BT_STREAM_IBRT_AUTO_SYNCHRONIZE_INITSYNC_SKIP_FRAME; + } + sync_trigger.audio_info.curSubSequenceNumber = lastframe_info.curSubSequenceNumber; + sync_trigger.audio_info.totalSubSequenceNumber = lastframe_info.totalSubSequenceNumber; + sync_trigger.audio_info.frame_samples = lastframe_info.frame_samples; + sync_trigger.factor_reference = a2dp_audio_get_output_config() ? a2dp_audio_get_output_config()->factor_reference : 1.0f; + sync_trigger.a2dp_session = a2dp_ibrt_session_get(); + sync_trigger.handler_cnt = 0; + + app_bt_stream_ibrt_auto_synchronize_initsync_start(&sync_trigger); + } + } +exit: + return 0; +} + +int app_bt_stream_ibrt_audio_slave_detect_next_packet_start(int need_autotrigger) +{ + TRACE_AUD_STREAM_I("[AUTO_SYNC][SLAVE] start"); + slave_detect_next_packet_cnt = 0; + if (need_autotrigger){ + a2dp_audio_detect_next_packet_callback_register(app_bt_stream_ibrt_audio_slave_detect_next_packet_waitforever_cb); + }else{ + app_tws_ibrt_audio_analysis_start(0, AUDIO_ANALYSIS_CHECKER_INTERVEL_INVALID); + app_tws_ibrt_audio_sync_start(); + a2dp_audio_detect_next_packet_callback_register(app_bt_stream_ibrt_audio_slave_detect_next_packet_cb); + } + return 0; +} + +#else +int app_bt_stream_detect_next_packet_cb(btif_media_header_t * header, unsigned char *buf, unsigned int len) +{ + if(app_bt_stream_trigger_onprocess()){ + TRACE_AUD_STREAM_I("[AUTO_SYNC] start"); + app_bt_stream_trigger_start(0); + } + return 0; +} +#endif + +void app_audio_buffer_check(void) +{ + bool buffer_check = (APP_AUDIO_BUFFER_SIZE + APP_CAPTURE_AUDIO_BUFFER_SIZE) <= syspool_original_size(); + + TRACE_AUD_STREAM_I("audio buf size[%d] capture buf size[%d] total available space[%d]", + APP_AUDIO_BUFFER_SIZE, APP_CAPTURE_AUDIO_BUFFER_SIZE, syspool_original_size()); + + ASSERT(buffer_check, + "Audio buffer[%d]+Capture buffer[%d] exceeds the maximum ram sapce[%d]", + APP_AUDIO_BUFFER_SIZE, APP_CAPTURE_AUDIO_BUFFER_SIZE, syspool_original_size()); +} + +static bool isRun = false; + +int bt_sbc_player(enum PLAYER_OPER_T on, enum APP_SYSFREQ_FREQ_T freq) +{ + struct AF_STREAM_CONFIG_T stream_cfg; + enum AUD_SAMPRATE_T sample_rate; + const char *g_log_player_oper_str[] = + { + "PLAYER_OPER_START", + "PLAYER_OPER_STOP", + "PLAYER_OPER_RESTART", + }; + + uint8_t* bt_audio_buff = NULL; + + uint8_t POSSIBLY_UNUSED *bt_eq_buff = NULL; + uint32_t POSSIBLY_UNUSED eq_buff_size = 0; + uint8_t POSSIBLY_UNUSED play_samp_size; + TRACE_AUD_STREAM_I("[A2DP_PLAYER] work:%d op:%s freq:%d :sample:%d \n", isRun, g_log_player_oper_str[on], freq,a2dp_sample_rate); + + bt_set_playback_triggered(false); + + if ((isRun && on == PLAYER_OPER_START) || (!isRun && on == PLAYER_OPER_STOP)) + { + TRACE_AUD_STREAM_W("[A2DP_PLAYER],fail,isRun=%x,on=%x",isRun,on); + return 0; + } + + uint8_t codec_type = bt_sbc_player_get_codec_type(); + + if (on == PLAYER_OPER_STOP || on == PLAYER_OPER_RESTART) + { +#ifdef __THIRDPARTY + start_by_sbc = false; +#endif + +#ifdef PLAYBACK_USE_I2S + hal_cmu_audio_resample_enable(); +#endif + +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + bool isToClearActiveMedia = audio_prompt_clear_pending_stream(PENDING_TO_STOP_A2DP_STREAMING); + if (isToClearActiveMedia) + { + // clear active media mark + bt_media_clear_media_type(BT_STREAM_SBC, BT_DEVICE_ID_1); + bt_media_current_sbc_set(BT_DEVICE_NUM); + } +#endif + +#if defined(IBRT) + app_bt_stream_ibrt_auto_synchronize_stop(); + app_tws_ibrt_audio_analysis_stop(); + app_tws_ibrt_audio_sync_stop(); +#endif + +#if (A2DP_DECODER_VER == 2) + a2dp_audio_stop(); +#endif + af_codec_set_playback_post_handler(NULL); + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) +#ifdef AUDIO_ANC_FB_ADJ_MC + af_stream_stop(ADJ_MC_STREAM_ID, AUD_STREAM_CAPTURE); +#endif + af_stream_stop(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK); +#endif + +#if defined(MUSIC_DELAY_CONTROL) && (defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A)|| defined(CHIP_BEST1400)|| defined(CHIP_BEST1402)) + calib_reset = 1; + af_stream_dma_tc_irq_disable(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); +#endif + af_stream_dma_tc_irq_disable(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + +#if defined(__AUDIO_SPECTRUM__) + audio_spectrum_close(); +#endif + + audio_process_close(); + + TRACE_AUD_STREAM_I("[A2DP_PLAYER] syspool free size: %d/%d", syspool_free_size(), syspool_total_size()); + +#if !(defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE)) + af_codec_tune(AUD_STREAM_PLAYBACK, 0); +#endif + + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) +#ifdef AUDIO_ANC_FB_ADJ_MC + af_stream_close(ADJ_MC_STREAM_ID, AUD_STREAM_CAPTURE); +#endif + + af_stream_close(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK); +#endif + + bt_sbc_mode = 0; + +#ifdef VOICE_DATAPATH + app_voicepath_set_stream_state(AUDIO_OUTPUT_STREAMING, false); + app_voicepath_set_pending_started_stream(AUDIO_OUTPUT_STREAMING, false); +#endif +#ifdef AI_AEC_CP_ACCEL + cp_aec_deinit(); +#endif + af_set_irq_notification(NULL); + if (on == PLAYER_OPER_STOP) + { + + osThreadId ctrl_thread_id = NULL; + osPriority ctrl_thread_priority; + ctrl_thread_id = osThreadGetId(); + ctrl_thread_priority = osThreadGetPriority(ctrl_thread_id); + osThreadSetPriority(ctrl_thread_id, osPriorityLow); + app_bt_stream_trigger_checker_stop(); +#ifdef USER_REBOOT_PLAY_MUSIC_AUTO + TRACE_AUD_STREAM_I("[A2DP_PLAYER] hal_sw_bootmode_clear HAL_SW_BOOTMODE_LOCAL_PLAYER!!!!!!"); + hal_sw_bootmode_clear(HAL_SW_BOOTMODE_LOCAL_PLAYER); +#endif +#ifdef __A2DP_PLAYER_USE_BT_TRIGGER__ + app_bt_stream_trigger_deinit(); +#endif +#ifndef FPGA +#ifdef BT_XTAL_SYNC + bt_term_xtal_sync(false); +#ifndef BT_XTAL_SYNC_NO_RESET + bt_term_xtal_sync_default(); +#endif +#endif +#endif + a2dp_audio_deinit(); +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__)&&defined(AUDIO_ANC_FB_ADJ_MC) + adj_mc_deinit(); +#endif + app_overlay_unloadall(); +#ifdef __THIRDPARTY + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_STOP2MIC); + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_START); +#endif + app_sysfreq_req(APP_SYSFREQ_USER_BT_A2DP, APP_SYSFREQ_32K); + osThreadSetPriority(ctrl_thread_id, ctrl_thread_priority); + af_set_priority(AF_USER_SBC, osPriorityAboveNormal); + +#if defined(__AI_VOICE__)||defined(BISTO_ENABLED) + app_ai_if_inform_music_or_prompt_status(false, 0); +#endif + +#if defined(IBRT) + app_ibrt_if_exec_sleep_hook_blocker_clr(APP_IBRT_IF_SLEEP_HOOK_BLOCKER_A2DP_STREAMING); +#endif + } + } + + if (on == PLAYER_OPER_START || on == PLAYER_OPER_RESTART) + { +#if USER_REBOOT_PLAY_MUSIC_AUTO + TRACE_AUD_STREAM_I("[A2DP_PLAYER] hal_sw_bootmode_set HAL_SW_BOOTMODE_LOCAL_PLAYER!!!!!!"); + hal_sw_bootmode_set(HAL_SW_BOOTMODE_LOCAL_PLAYER); +#endif + +#if defined(__AI_VOICE__)||defined(BISTO_ENABLED) + app_ai_if_inform_music_or_prompt_status(true, a2dp_sample_rate); + app_ai_if_pre_music_or_prompt_check(); +#endif +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + audio_prompt_stop_playing(); +#endif + +#if defined(IBRT) + app_ibrt_if_exec_sleep_hook_blocker_set(APP_IBRT_IF_SLEEP_HOOK_BLOCKER_A2DP_STREAMING); +#endif +#ifdef __THIRDPARTY + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_STOP); +#endif + af_set_priority(AF_USER_SBC, osPriorityHigh); + bt_media_volume_ptr_update_by_mediatype(BT_STREAM_SBC); + stream_local_volume = btdevice_volume_p->a2dp_vol; + app_audio_mempool_init_with_specific_size(APP_AUDIO_BUFFER_SIZE); + +#ifdef __BT_ONE_BRING_TWO__ + if (btif_me_get_activeCons()>1) + { + if (freq < APP_SYSFREQ_104M) { + freq = APP_SYSFREQ_104M; + } + } +#endif +#ifdef __PC_CMD_UART__ + if (freq < APP_SYSFREQ_104M) { + freq = APP_SYSFREQ_104M; + } +#endif +#if defined(__SW_IIR_EQ_PROCESS__)&&defined(__HW_FIR_EQ_PROCESS__)&&defined(CHIP_BEST1000) + if (audio_eq_hw_fir_cfg_list[bt_audio_get_eq_index(AUDIO_EQ_TYPE_HW_FIR,0)]->len>128) + { + if (freq < APP_SYSFREQ_104M) + { + freq = APP_SYSFREQ_104M; + } + } +#endif +#if defined(APP_MUSIC_26M) && !defined(__SW_IIR_EQ_PROCESS__)&& !defined(__HW_IIR_EQ_PROCESS__)&& !defined(__HW_FIR_EQ_PROCESS__) + if (freq < APP_SYSFREQ_26M) { + freq = APP_SYSFREQ_26M; + } +#else + if (freq < APP_SYSFREQ_52M) { + freq = APP_SYSFREQ_52M; + } +#endif + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + if (freq < APP_SYSFREQ_104M) { + freq = APP_SYSFREQ_104M; + } +#endif + TRACE_AUD_STREAM_I("[A2DP_PLAYER] codec_type:%d", codec_type); +#if defined(A2DP_AAC_ON) + if (codec_type == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) { + if(freq < APP_SYSFREQ_52M) { + freq = APP_SYSFREQ_52M; + } + } +#endif +#if defined(A2DP_SCALABLE_ON) + if (codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + if(a2dp_sample_rate==44100) + { + if(freq < APP_SYSFREQ_78M) { + freq = APP_SYSFREQ_78M; + } + } + else if(a2dp_sample_rate==96000) + { + if (freq < APP_SYSFREQ_208M) { + freq = APP_SYSFREQ_208M; + } + } + } + TRACE_AUD_STREAM_I("[A2DP_PLAYER] a2dp_sample_rate=%d",a2dp_sample_rate); +#endif + +#if defined(__AUDIO_DRC__) || defined(__AUDIO_DRC2__) + freq = (freq < APP_SYSFREQ_208M)?APP_SYSFREQ_208M:freq; +#endif + +#ifdef AUDIO_OUTPUT_SW_GAIN + freq = (freq < APP_SYSFREQ_104M)?APP_SYSFREQ_104M:freq; +#endif + +#ifdef PLAYBACK_FORCE_48K + freq = (freq < APP_SYSFREQ_104M)?APP_SYSFREQ_104M:freq; +#endif + +#ifdef A2DP_CP_ACCEL + // Default freq for SBC + freq = APP_SYSFREQ_26M; +#if defined(A2DP_AAC_ON) + if (codec_type == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) { + freq = APP_SYSFREQ_26M; + } +#endif + +#if defined(A2DP_LHDC_ON) || defined(A2DP_SCALABLE_ON) || defined(A2DP_LDAC_ON) + if (codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP){ + freq = APP_SYSFREQ_52M; + } + + if (a2dp_sample_rate==AUD_SAMPRATE_96000) + { + freq = APP_SYSFREQ_104M; + } +#endif +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + if (freq < APP_SYSFREQ_52M) { + freq = APP_SYSFREQ_52M; + } +#endif +#if defined(A2DP_LDAC_ON) + if (codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP){ + if (a2dp_sample_rate==AUD_SAMPRATE_96000 || a2dp_sample_rate==AUD_SAMPRATE_88200) + { + freq = APP_SYSFREQ_104M; + }else + { + freq = APP_SYSFREQ_52M; + } + } +#endif +#endif + freq = APP_SYSFREQ_52M; + app_sysfreq_req(APP_SYSFREQ_USER_BT_A2DP, freq); + TRACE_AUD_STREAM_I("[A2DP_PLAYER] sysfreq %d", freq); + TRACE_AUD_STREAM_I("[A2DP_PLAYER] sysfreq calc : %d\n", hal_sys_timer_calc_cpu_freq(5, 0)); + + if (on == PLAYER_OPER_START) + { + af_set_irq_notification(app_bt_stream_playback_irq_notification); + ASSERT(!app_ring_merge_isrun(), "Ring playback will be abnormal, please check."); + if (0) + { + } +#if defined(A2DP_AAC_ON) + else if (codec_type == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC) + { + app_overlay_select(APP_OVERLAY_A2DP_AAC); + } +#endif + + else if (codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + TRACE(1,"current_a2dp_non_type %d", current_a2dp_non_type); +#if defined(A2DP_LHDC_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LHDC) + { + app_overlay_select(APP_OVERLAY_A2DP_LHDC); + } +#endif +#if defined(A2DP_SCALABLE_ON) + else if (current_a2dp_non_type == A2DP_NON_CODEC_TYPE_SCALABLE) + { + app_overlay_select(APP_OVERLAY_A2DP_SCALABLE); + } +#endif +#if defined(A2DP_LDAC_ON) + else if (current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LDAC) + { + TRACE_AUD_STREAM_I("[A2DP_PLAYER] ldac overlay select \n"); //toto + app_overlay_select(APP_OVERLAY_A2DP_LDAC); + } +#endif + } + else + { + app_overlay_select(APP_OVERLAY_A2DP); + } + +#ifdef BT_XTAL_SYNC + +#ifdef __TWS__ + if(app_tws_mode_is_only_mobile()) + { + btdrv_rf_bit_offset_track_enable(false); + } + else +#endif + { + btdrv_rf_bit_offset_track_enable(true); + } + bt_init_xtal_sync(BT_XTAL_SYNC_MODE_MUSIC, BT_INIT_XTAL_SYNC_MIN, BT_INIT_XTAL_SYNC_MAX, BT_INIT_XTAL_SYNC_FCAP_RANGE); +#endif // BT_XTAL_SYNC +#ifdef __THIRDPARTY + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_START2MIC); +#endif + + bt_sbc_mode = 1; + } + +#ifdef __THIRDPARTY + //app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_STOP); + start_by_sbc = true; + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_START); +#endif +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + sample_rate = AUD_SAMPRATE_50781; +#else + sample_rate = a2dp_sample_rate; +#endif + +#ifdef PLAYBACK_USE_I2S + hal_cmu_audio_resample_disable(); +#endif + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; +#ifdef PLAYBACK_FORCE_48K + stream_cfg.sample_rate = AUD_SAMPRATE_48000; +#else + stream_cfg.sample_rate = sample_rate; +#endif + +#ifdef FPGA + stream_cfg.device = AUD_STREAM_USE_EXT_CODEC; +#else +#ifdef PLAYBACK_USE_I2S + stream_cfg.device = AUD_STREAM_USE_I2S0_MASTER; +#else + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; +#endif +#endif +#ifdef PLAYBACK_USE_I2S + stream_cfg.io_path = AUD_IO_PATH_NULL; +#else + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; +#endif + + stream_cfg.vol = stream_local_volume; + stream_cfg.handler = bt_sbc_player_more_data; + + + if (codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP){ +#if defined(A2DP_SCALABLE_ON) + if (current_a2dp_non_type == A2DP_NON_CODEC_TYPE_SCALABLE){ + stream_cfg.data_size = SCALABLE_FRAME_SIZE*8; + } +#endif +#if defined(A2DP_LHDC_ON) + if (current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LHDC){ +#if defined(A2DP_LHDC_V3) + if (bt_get_sbc_sample_rate() == AUD_SAMPRATE_96000) { + stream_cfg.data_size = LHDC_AUDIO_96K_BUFF_SIZE; + } else { + stream_cfg.data_size = LHDC_AUDIO_BUFF_SIZE; + } + if (a2dp_lhdc_config_llc_get()){ + TRACE_AUD_STREAM_I("[A2DP_PLAYER] USE LHDC_LLC"); + stream_cfg.data_size = LHDC_LLC_AUDIO_BUFF_SIZE; + } +#else + stream_cfg.data_size = LHDC_AUDIO_BUFF_SIZE; +#endif + } +#endif +#if defined(A2DP_LDAC_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LDAC) + { + stream_cfg.data_size = BT_AUDIO_BUFF_SIZE_LDAC; + } +#endif + }else + +#if defined(A2DP_AAC_ON) + if (codec_type == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC){ + stream_cfg.data_size = BT_AUDIO_BUFF_AAC_SIZE; + }else +#endif + { + if (stream_cfg.sample_rate == AUD_SAMPRATE_44100){ + stream_cfg.data_size = BT_AUDIO_BUFF_SBC_44P1K_SIZE; + }else{ + stream_cfg.data_size = BT_AUDIO_BUFF_SBC_48K_SIZE; + } + } + + stream_cfg.bits = AUD_BITS_16; + +#ifdef A2DP_EQ_24BIT + stream_cfg.data_size *= 2; + stream_cfg.bits = AUD_BITS_24; +#elif defined(A2DP_SCALABLE_ON) || defined(A2DP_LHDC_ON) || defined(A2DP_LDAC_ON) + if (codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) { + stream_cfg.data_size *= 2; + stream_cfg.bits = AUD_BITS_24; + } +#endif + +#if 0//defined(A2DP_LHDC_ON) + if (codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + if(bt_sbc_player_get_sample_bit() == AUD_BITS_16) + { + stream_cfg.bits = AUD_BITS_16; + } + } +#endif + + a2dp_data_buf_size = stream_cfg.data_size; + + app_audio_mempool_get_buff(&bt_audio_buff, stream_cfg.data_size); + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(bt_audio_buff); +#if defined(MUSIC_DELAY_CONTROL) && (defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A)|| defined(CHIP_BEST1400)|| defined(CHIP_BEST1402)) + lowdelay_sample_size_play_bt=stream_cfg.bits; + lowdelay_sample_rate_play_bt=stream_cfg.sample_rate; + lowdelay_data_size_play_bt=stream_cfg.data_size; + lowdelay_playback_ch_num_bt=stream_cfg.channel_num; +#endif + + +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + uint8_t* promptTmpSourcePcmDataBuf; + uint8_t* promptTmpTargetPcmDataBuf; + uint8_t* promptPcmDataBuf; + uint8_t* promptResamplerBuf; + + app_audio_mempool_get_buff(&promptTmpSourcePcmDataBuf, AUDIO_PROMPT_SOURCE_PCM_BUFFER_SIZE); + app_audio_mempool_get_buff(&promptTmpTargetPcmDataBuf, AUDIO_PROMPT_TARGET_PCM_BUFFER_SIZE); + app_audio_mempool_get_buff(&promptPcmDataBuf, AUDIO_PROMPT_PCM_BUFFER_SIZE); + app_audio_mempool_get_buff(&promptResamplerBuf, AUDIO_PROMPT_BUF_SIZE_FOR_RESAMPLER); + + audio_prompt_buffer_config(MIX_WITH_A2DP_STREAMING, + stream_cfg.channel_num, + stream_cfg.bits, + promptTmpSourcePcmDataBuf, + promptTmpTargetPcmDataBuf, + promptPcmDataBuf, + AUDIO_PROMPT_PCM_BUFFER_SIZE, + promptResamplerBuf, + AUDIO_PROMPT_BUF_SIZE_FOR_RESAMPLER); +#endif + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + sample_size_play_bt=stream_cfg.bits; + sample_rate_play_bt=stream_cfg.sample_rate; + data_size_play_bt=stream_cfg.data_size; + playback_buf_bt=stream_cfg.data_ptr; + playback_size_bt=stream_cfg.data_size; + if(sample_rate_play_bt==AUD_SAMPRATE_96000) + { + playback_samplerate_ratio_bt=4; + } + else + { + playback_samplerate_ratio_bt=8; + } + playback_ch_num_bt=stream_cfg.channel_num; + mid_p_8_old_l=0; + mid_p_8_old_r=0; +#endif + +#ifdef PLAYBACK_FORCE_48K + force48k_resample= app_force48k_resample_any_open( stream_cfg.channel_num, + app_force48k_resample_iter, stream_cfg.data_size / stream_cfg.channel_num, + (float)sample_rate / AUD_SAMPRATE_48000); +#endif + + TRACE(4, "A2DP Playback: sample rate: %d, bits = %d, channel number = %d, data size:%d", + stream_cfg.sample_rate, + stream_cfg.bits, + stream_cfg.channel_num, + stream_cfg.data_size); + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + stream_cfg.bits = sample_size_play_bt; + stream_cfg.channel_num = playback_ch_num_bt; + stream_cfg.sample_rate = sample_rate_play_bt; + stream_cfg.device = AUD_STREAM_USE_MC; + stream_cfg.vol = 0; +#ifdef AUDIO_ANC_FB_ADJ_MC + stream_cfg.handler = audio_adj_mc_data_playback_a2dp; +#else + stream_cfg.handler = audio_mc_data_playback_a2dp; +#endif + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + app_audio_mempool_get_buff(&bt_audio_buff, data_size_play_bt*playback_samplerate_ratio_bt); + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(bt_audio_buff); + stream_cfg.data_size = data_size_play_bt*playback_samplerate_ratio_bt; + + playback_buf_mc=stream_cfg.data_ptr; + playback_size_mc=stream_cfg.data_size; + + anc_mc_run_init(hal_codec_anc_convert_rate(sample_rate_play_bt)); + + memset(delay_buf_bt,0,sizeof(delay_buf_bt)); + + af_stream_open(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &stream_cfg); + //ASSERT(ret == 0, "af_stream_open playback failed: %d", ret); +#ifdef AUDIO_ANC_FB_ADJ_MC + adj_mc_capture_sample_rate = sample_rate_play_bt / 3; + adj_mc_init(ADJ_MC_FRAME_LEN); + memset(&stream_cfg, 0, sizeof(stream_cfg)); + stream_cfg.channel_num = (enum AUD_CHANNEL_NUM_T)ADJ_MC_CHANNEL_NUM; + stream_cfg.data_size = ADJ_MC_BUF_SIZE; + stream_cfg.sample_rate = (enum AUD_SAMPRATE_T)adj_mc_capture_sample_rate; + stream_cfg.bits = AUD_BITS_16; + stream_cfg.vol = 12; + stream_cfg.chan_sep_buf = true; + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.io_path = AUD_INPUT_PATH_ASRMIC; + stream_cfg.handler = adj_mc_filter_estimate; + stream_cfg.data_ptr = adj_mc_buf; + TRACE(2,"[A2DP_PLAYER] capture sample_rate:%d, data_size:%d",stream_cfg.sample_rate,stream_cfg.data_size); + af_stream_open(ADJ_MC_STREAM_ID, AUD_STREAM_CAPTURE, &stream_cfg); +#endif + +#endif + +#ifdef A2DP_STREAM_AUDIO_DUMP + audio_dump_init(1024, sizeof(int), 1); +#endif + +#ifdef __HEAR_THRU_PEAK_DET__ + PEAK_DETECTOR_CFG_T peak_detector_cfg; + peak_detector_cfg.fs = stream_cfg.sample_rate; + peak_detector_cfg.bits = stream_cfg.bits; + peak_detector_cfg.factor_up = 0.6; + peak_detector_cfg.factor_down = 2.0; + peak_detector_cfg.reduce_dB = -30; + peak_detector_init(); + peak_detector_setup(&peak_detector_cfg); +#endif + +#if defined(__AUDIO_SPECTRUM__) + audio_spectrum_open(stream_cfg.sample_rate, stream_cfg.bits); +#endif + +#if defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) + eq_buff_size = stream_cfg.data_size*2; +#elif defined(__HW_FIR_EQ_PROCESS__) && !defined(__HW_IIR_EQ_PROCESS__) + + play_samp_size = (stream_cfg.bits <= AUD_BITS_16) ? 2 : 4; +#if defined(CHIP_BEST2000) + eq_buff_size = stream_cfg.data_size * sizeof(int32_t) / play_samp_size; +#elif defined(CHIP_BEST1000) + eq_buff_size = stream_cfg.data_size * sizeof(int16_t) / play_samp_size; +#elif defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) + eq_buff_size = stream_cfg.data_size; +#endif +#elif !defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) + eq_buff_size = stream_cfg.data_size; +#else + eq_buff_size = 0; + bt_eq_buff = NULL; +#endif + + if(eq_buff_size > 0) + { + app_audio_mempool_get_buff(&bt_eq_buff, eq_buff_size); + } + +#if defined(IBRT) + enum AUD_CHANNEL_NUM_T sw_ch_num = AUD_CHANNEL_NUM_1; +#else + enum AUD_CHANNEL_NUM_T sw_ch_num = stream_cfg.channel_num; +#endif + + audio_process_open(stream_cfg.sample_rate, stream_cfg.bits, sw_ch_num, stream_cfg.channel_num, stream_cfg.data_size/stream_cfg.channel_num/(stream_cfg.bits <= AUD_BITS_16 ? 2 : 4)/2, bt_eq_buff, eq_buff_size); + +// disable audio eq config on a2dp start for audio tuning tools +#ifndef __PC_CMD_UART__ +#ifdef __SW_IIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_SW_IIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_SW_IIR,0)); +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_HW_FIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_HW_FIR,0)); +#endif + +#ifdef __HW_DAC_IIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_HW_DAC_IIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_HW_DAC_IIR,0)); +#endif + +#ifdef __HW_IIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_HW_IIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_HW_IIR,0)); +#endif +#endif + +#ifdef ANC_APP + anc_status_record = 0xff; +#endif + +#if defined(IBRT) + APP_TWS_IBRT_AUDIO_SYNC_CFG_T sync_config; + sync_config.factor_reference = TWS_IBRT_AUDIO_SYNC_FACTOR_REFERENCE; + sync_config.factor_fast_limit = TWS_IBRT_AUDIO_SYNC_FACTOR_FAST_LIMIT; + sync_config.factor_slow_limit = TWS_IBRT_AUDIO_SYNC_FACTOR_SLOW_LIMIT;; + sync_config.dead_zone_us = TWS_IBRT_AUDIO_SYNC_DEAD_ZONE_US; + app_tws_ibrt_audio_sync_reconfig(&sync_config); +#else +#if !(defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE)) + af_codec_tune(AUD_STREAM_PLAYBACK, 0); +#endif +#endif + if (on == PLAYER_OPER_START) + { + // This might use all of the rest buffer in the mempool, + // so it must be the last configuration before starting stream. +#if (A2DP_DECODER_VER == 2) + A2DP_AUDIO_OUTPUT_CONFIG_T output_config; + A2DP_AUDIO_CODEC_TYPE a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_SBC; + output_config.sample_rate = sample_rate; + output_config.num_channels = 2; + #ifdef A2DP_EQ_24BIT + output_config.bits_depth = 24; + #else + output_config.bits_depth = 16; + #endif + output_config.frame_samples = app_bt_stream_get_dma_buffer_samples()/2; + output_config.factor_reference = 1.0f; +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + uint8_t codec_type = bt_sbc_player_get_codec_type(); + float dest_packet_mut = 0; + int need_autotrigger = a2dp_ibrt_stream_need_autotrigger_getandclean_flag(); + + uint32_t offset_mut = 0; + switch (codec_type) + { + case BTIF_AVDTP_CODEC_TYPE_SBC: + a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_SBC; + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_SBC_MTU; + #ifdef A2DP_PLAYER_PLAYBACK_WATER_LINE + offset_mut = A2DP_PLAYER_PLAYBACK_DELAY_SBC_FRAME_MTU * A2DP_PLAYER_PLAYBACK_WATER_LINE; + #endif + break; + case BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC: + a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_MPEG2_4_AAC; + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_AAC_MTU; + #ifdef A2DP_PLAYER_PLAYBACK_WATER_LINE + offset_mut = A2DP_PLAYER_PLAYBACK_WATER_LINE; + #endif + break; + case BTIF_AVDTP_CODEC_TYPE_NON_A2DP: +#if defined(A2DP_LHDC_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LHDC) + { + a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_LHDC; + if (a2dp_lhdc_config_llc_get()){ + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_MTU; + }else if (sample_rate > AUD_SAMPRATE_48000){ + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_MTU; + }else{ + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_MTU; + } + } +#endif +#if defined(A2DP_LDAC_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LDAC) + { + a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_LDAC; + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_LDAC_MTU; + } +#endif + + +#if defined(A2DP_SCALABLE_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_SCALABLE) + { + a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_SCALABL; + if (sample_rate > AUD_SAMPRATE_48000){ + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_HIRES_MTU; + }else{ + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_BASERES_MTU; + } + } +#endif + + break; + default: + break; + } + output_config.factor_reference = TWS_IBRT_AUDIO_SYNC_FACTOR_REFERENCE; +#if defined(A2DP_LHDC_ON) || defined(A2DP_SCALABLE_ON) || defined(A2DP_LDAC_ON) + if (codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + if(bt_sbc_player_get_sample_bit() == AUD_BITS_16) + { + output_config.curr_bits = AUD_BITS_16; + } + else + { + output_config.curr_bits = AUD_BITS_24; + } + } +#endif + + dest_packet_mut *= a2dp_audio_latency_factor_get(); + A2DP_AUDIO_CHANNEL_SELECT_E a2dp_audio_channel_sel = A2DP_AUDIO_CHANNEL_SELECT_STEREO; + switch ((AUDIO_CHANNEL_SELECT_E)p_ibrt_ctrl->audio_chnl_sel) + { + case AUDIO_CHANNEL_SELECT_STEREO: + a2dp_audio_channel_sel = A2DP_AUDIO_CHANNEL_SELECT_STEREO; + break; + case AUDIO_CHANNEL_SELECT_LRMERGE: + a2dp_audio_channel_sel = A2DP_AUDIO_CHANNEL_SELECT_LRMERGE; + break; + case AUDIO_CHANNEL_SELECT_LCHNL: + a2dp_audio_channel_sel = A2DP_AUDIO_CHANNEL_SELECT_LCHNL; + break; + case AUDIO_CHANNEL_SELECT_RCHNL: + a2dp_audio_channel_sel = A2DP_AUDIO_CHANNEL_SELECT_RCHNL; + break; + default: + break; + } + dest_packet_mut += offset_mut; + a2dp_audio_init(freq, a2dp_audio_codec_type, &output_config, a2dp_audio_channel_sel, (uint16_t)dest_packet_mut); + + app_tws_ibrt_audio_analysis_interval_set(sample_rate > AUD_SAMPRATE_48000 ? AUDIO_ANALYSIS_INTERVAL*2 : AUDIO_ANALYSIS_INTERVAL); + if (app_tws_ibrt_mobile_link_connected()){ + app_tws_ibrt_audio_analysis_start(0, AUDIO_ANALYSIS_CHECKER_INTERVEL_INVALID); + app_tws_ibrt_audio_sync_start(); + app_bt_stream_ibrt_audio_master_detect_next_packet_start(); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + app_bt_stream_ibrt_audio_slave_detect_next_packet_start(need_autotrigger); + }else{ + TRACE_AUD_STREAM_E("[A2DP_PLAYER] mobile_link:%d %04x ibrt_link:%d %04x", app_tws_ibrt_mobile_link_connected(), p_ibrt_ctrl->mobile_conhandle, + app_tws_ibrt_slave_ibrt_link_connected(), p_ibrt_ctrl->ibrt_conhandle); + } +#else + uint8_t codec_type = bt_sbc_player_get_codec_type(); + uint16_t dest_packet_mut = 0; + + switch (codec_type) + { + case BTIF_AVDTP_CODEC_TYPE_SBC: + a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_SBC; + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_SBC_MTU; + break; + case BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC: + a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_MPEG2_4_AAC; + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_AAC_MTU; + break; + case BTIF_AVDTP_CODEC_TYPE_NON_A2DP: +#if defined(A2DP_LHDC_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LHDC) + { + a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_LHDC; + if (a2dp_lhdc_config_llc_get()){ + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_LHDC_LLC_MTU; + }else if (sample_rate > AUD_SAMPRATE_48000){ + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_LHDC_HIRES_MTU; + }else{ + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_LHDC_BASERES_MTU; + } + } +#endif +#if defined(A2DP_LDAC_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_LDAC) + { + a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_LDAC; + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_LDAC_MTU; + } +#endif +#if defined(A2DP_SCALABLE_ON) + if(current_a2dp_non_type == A2DP_NON_CODEC_TYPE_SCALABLE) + { + a2dp_audio_codec_type = A2DP_AUDIO_CODEC_TYPE_SCALABL; + if (sample_rate > AUD_SAMPRATE_48000){ + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_HIRES_MTU; + }else{ + dest_packet_mut = A2DP_PLAYER_PLAYBACK_DELAY_SCALABLE_BASERES_MTU; + } + } +#endif + + if (codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + if(bt_sbc_player_get_sample_bit() == AUD_BITS_16) + { + output_config.curr_bits = AUD_BITS_16; + } + else + { + output_config.curr_bits = AUD_BITS_24; + } + } + + break; + default: + break; + } +#if defined(A2DP_LHDC_ON) + if (codec_type == BTIF_AVDTP_CODEC_TYPE_NON_A2DP) + { + if(bt_sbc_player_get_sample_bit() == AUD_BITS_16) + { + output_config.curr_bits = AUD_BITS_16; + } + else + { + output_config.curr_bits = AUD_BITS_24; + } + } +#endif + a2dp_audio_init(freq,a2dp_audio_codec_type, &output_config, A2DP_AUDIO_CHANNEL_SELECT_STEREO, dest_packet_mut); + a2dp_audio_detect_next_packet_callback_register(app_bt_stream_detect_next_packet_cb); +#endif + a2dp_audio_start(); +#else + a2dp_audio_init(); +#endif + } + + +#if defined(MUSIC_DELAY_CONTROL) && (defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A)|| defined(CHIP_BEST1400)|| defined(CHIP_BEST1402)) + calib_reset = 1; +#endif + af_stream_dma_tc_irq_enable(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_codec_set_playback_post_handler(bt_sbc_player_playback_post_handler); +#ifdef __A2DP_PLAYER_USE_BT_TRIGGER__ + app_bt_stream_trigger_init(); +#endif +#ifdef VOICE_DATAPATH + if (app_voicepath_get_stream_state(VOICEPATH_STREAMING)) + { + app_voicepath_set_pending_started_stream(AUDIO_OUTPUT_STREAMING, true); + } + else + { + app_voicepath_set_stream_state(AUDIO_OUTPUT_STREAMING, true); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + } +#else + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); +#endif +#ifdef AI_AEC_CP_ACCEL + cp_aec_init(); +#endif + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + af_stream_start(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK); + #ifdef AUDIO_ANC_FB_ADJ_MC + af_stream_start(ADJ_MC_STREAM_ID, AUD_STREAM_CAPTURE); + #endif +#endif + +#ifdef __THIRDPARTY + //app_thirdparty_specific_lib_event_handle(THIRDPARTY_ID_NO1,THIRDPARTY_OTHER_EVENT); +#endif + app_bt_stream_trigger_checker_start(); + } + + isRun = (on != PLAYER_OPER_STOP); + return 0; +} + +#if defined(SCO_DMA_SNAPSHOT) +static uint32_t sco_trigger_wait_codecpcm = 0; +static uint32_t sco_trigger_wait_btpcm = 0; +void app_bt_stream_sco_trigger_set_codecpcm_triggle(uint8_t triggle_en) +{ + sco_trigger_wait_codecpcm = triggle_en; +} + +uint32_t app_bt_stream_sco_trigger_wait_codecpcm_triggle(void) +{ + return sco_trigger_wait_codecpcm; +} + +void app_bt_stream_sco_trigger_set_btpcm_triggle(uint32_t triggle_en) +{ + sco_trigger_wait_btpcm = triggle_en; +} + +uint32_t app_bt_stream_sco_trigger_wait_btpcm_triggle(void) +{ + return sco_trigger_wait_btpcm; +} + +int app_bt_stream_sco_trigger_codecpcm_tick(void) +{ + if(app_bt_stream_sco_trigger_wait_codecpcm_triggle()){ + app_bt_stream_sco_trigger_set_codecpcm_triggle(0); +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (app_tws_ibrt_mobile_link_connected()){ + TRACE_AUD_STREAM_I("[SCO_PLAYER] codecpcm_tick:%x/%x", btdrv_syn_get_curr_ticks(), bt_syn_get_curr_ticks(p_ibrt_ctrl->mobile_conhandle)); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + TRACE_AUD_STREAM_I("[SCO_PLAYER] codecpcm_tick:%x/%x", btdrv_syn_get_curr_ticks(), bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle)); + }else{ + TRACE_AUD_STREAM_E("[SCO_PLAYER] codecpcm_tick mobile_link:%d %04x ibrt_link:%d %04x", app_tws_ibrt_mobile_link_connected(), p_ibrt_ctrl->mobile_conhandle, + app_tws_ibrt_slave_ibrt_link_connected(), p_ibrt_ctrl->ibrt_conhandle); + } +#else + uint16_t conhdl = 0xFFFF; + int curr_sco; + + curr_sco = app_audio_manager_get_active_sco_num(); + if (curr_sco != BT_DEVICE_NUM) + { + conhdl = btif_hf_get_remote_hci_handle(*app_audio_manager_get_active_sco_chnl()); + } + if (conhdl != 0xFFFF){ + TRACE_AUD_STREAM_I("[SCO_PLAYER] codecpcm_tick:%x", bt_syn_get_curr_ticks(conhdl)); + } +#endif + btdrv_syn_clr_trigger(); + return 1; + } + return 0; +} + +int app_bt_stream_sco_trigger_btpcm_tick(void) +{ + if(app_bt_stream_sco_trigger_wait_btpcm_triggle()){ + app_bt_stream_sco_trigger_set_btpcm_triggle(0); + btdrv_set_bt_pcm_triggler_en(0); +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (app_tws_ibrt_mobile_link_connected()){ + TRACE_AUD_STREAM_I("[SCO_PLAYER] btpcm_tick:%x/%x", btdrv_syn_get_curr_ticks(), bt_syn_get_curr_ticks(p_ibrt_ctrl->mobile_conhandle)); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + TRACE_AUD_STREAM_I("[SCO_PLAYER] btpcm_tick:tick:%x/%x", btdrv_syn_get_curr_ticks(), bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle)); + }else{ + TRACE_AUD_STREAM_I("[SCO_PLAYER] btpcm_tick: mobile_link:%d %04x ibrt_link:%d %04x", app_tws_ibrt_mobile_link_connected(), p_ibrt_ctrl->mobile_conhandle, + app_tws_ibrt_slave_ibrt_link_connected(), p_ibrt_ctrl->ibrt_conhandle); + } +#else + uint16_t conhdl = 0xFFFF; + int curr_sco; + + curr_sco = app_audio_manager_get_active_sco_num(); + if (curr_sco != BT_DEVICE_NUM) + { + conhdl = btif_hf_get_remote_hci_handle(*app_audio_manager_get_active_sco_chnl()); + } + TRACE_AUD_STREAM_I("[SCO_PLAYER] btpcm_tick:%x", bt_syn_get_curr_ticks(conhdl)); +#endif + btdrv_syn_clr_trigger(); + return 1; + } + return 0; +} + + +void app_bt_stream_sco_trigger_btpcm_start(void ) +{ + uint32_t curr_ticks = 0; + uint32_t tg_acl_trigger_offset_time = 0; + uint16_t conhdl = 0xFFFF; + + uint32_t lock; + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (app_tws_ibrt_mobile_link_connected()){ + conhdl = p_ibrt_ctrl->mobile_conhandle; +#ifdef __SW_TRIG__ + btdrv_sync_sw_trig_store_conhdl(p_ibrt_ctrl->mobile_conhandle); +#endif + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + conhdl = p_ibrt_ctrl->ibrt_conhandle; +#ifdef __SW_TRIG__ + btdrv_sync_sw_trig_store_conhdl(p_ibrt_ctrl->ibrt_conhandle); +#endif + }else{ + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] btpcm_startr mobile:%d %04x ibrt:%d %04x", app_tws_ibrt_mobile_link_connected(), p_ibrt_ctrl->mobile_conhandle, + app_tws_ibrt_slave_ibrt_link_connected(), p_ibrt_ctrl->ibrt_conhandle); + } +#else + int curr_sco; + curr_sco = app_audio_manager_get_active_sco_num(); + if (curr_sco != BT_DEVICE_NUM) + { + conhdl = btif_hf_get_remote_hci_handle(*app_audio_manager_get_active_sco_chnl()); + } +#endif + + lock = int_lock(); + curr_ticks = bt_syn_get_curr_ticks(conhdl); + + tg_acl_trigger_offset_time = (curr_ticks+0x180) - ((curr_ticks+0x180)%192); + + btdrv_set_bt_pcm_triggler_en(0); + btdrv_set_bt_pcm_en(0); + btdrv_syn_clr_trigger(); + btdrv_enable_playback_triggler(SCO_TRIGGLE_MODE); + +#if defined(IBRT) + if (app_tws_ibrt_mobile_link_connected()){ + bt_syn_set_tg_ticks(tg_acl_trigger_offset_time, p_ibrt_ctrl->mobile_conhandle, BT_TRIG_SLAVE_ROLE); + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] btpcm_startr set ticks:%d,",tg_acl_trigger_offset_time); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + bt_syn_set_tg_ticks(tg_acl_trigger_offset_time, p_ibrt_ctrl->ibrt_conhandle, BT_TRIG_SLAVE_ROLE); + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] btpcm_startr set ticks:%d,",tg_acl_trigger_offset_time); + }else{ + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] btpcm_startr mobile:%d %04x ibrt:%d %04x", app_tws_ibrt_mobile_link_connected(), p_ibrt_ctrl->mobile_conhandle, + app_tws_ibrt_slave_ibrt_link_connected(), p_ibrt_ctrl->ibrt_conhandle); + } + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] btpcm_startr get ticks:%d,",curr_ticks); + +#else + bt_syn_set_tg_ticks(tg_acl_trigger_offset_time, conhdl, BT_TRIG_SLAVE_ROLE); +#endif + btdrv_set_bt_pcm_triggler_en(1); + btdrv_set_bt_pcm_en(1); + app_bt_stream_sco_trigger_set_btpcm_triggle(1); + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] btpcm_startr curr:%x, trig:%x, curr:%x", + btdrv_syn_get_curr_ticks(), + tg_acl_trigger_offset_time, + bt_syn_get_curr_ticks(conhdl)); + int_unlock(lock); +} + +void app_bt_stream_sco_trigger_btpcm_stop(void) +{ + return; +} + + +#define TIRG_DELAY_THRESHOLD_325US (15) //total:TIRG_DELAY_THRESHOLD_325US*325us +#define TIRG_DELAY_MAX (20) //total:20*TIRG_DELAY_325US*325us + +#define TIRG_DELAY_325US (96) //total:TIRG_DELAY_325US*325us It' up to the codec and bt pcm pingpang buffer. + +void app_bt_stream_sco_trigger_codecpcm_start(uint32_t btclk, uint16_t btcnt ) +{ + uint32_t curr_ticks = 0; + uint32_t tg_acl_trigger_offset_time = 0; + uint32_t lock; + uint16_t conhdl = 0xFFFF; + //must lock the interrupts when set trig ticks. + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (app_tws_ibrt_mobile_link_connected()){ + conhdl = p_ibrt_ctrl->mobile_conhandle; + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + conhdl = p_ibrt_ctrl->ibrt_conhandle; + }else{ + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] codecpcm_start mobile_link:%d %04x ibrt_link:%d %04x", app_tws_ibrt_mobile_link_connected(), p_ibrt_ctrl->mobile_conhandle, + app_tws_ibrt_slave_ibrt_link_connected(), p_ibrt_ctrl->ibrt_conhandle); + } +#else + int curr_sco; + curr_sco = app_audio_manager_get_active_sco_num(); + if (curr_sco != BT_DEVICE_NUM) + { + conhdl = btif_hf_get_remote_hci_handle(*app_audio_manager_get_active_sco_chnl()); + } +#endif + + lock = int_lock(); + curr_ticks = bt_syn_get_curr_ticks(conhdl); + TRACE_AUD_STREAM_I("[[STRM_TRIG][SCO] codecpcm_start 1 curr:%d clk:%dcnt:%d", curr_ticks,btclk,btcnt); +#ifdef LOW_DELAY_SCO + tg_acl_trigger_offset_time=btclk+12+MASTER_MOBILE_BTCLK_OFFSET; +#else + tg_acl_trigger_offset_time=btclk+24+MASTER_MOBILE_BTCLK_OFFSET; +#endif + + tg_acl_trigger_offset_time = tg_acl_trigger_offset_time * 2; + if(tg_acl_trigger_offset_timeTIRG_DELAY_MAX) + { + tirg_delay=TIRG_DELAY_MAX; + TRACE_AUD_STREAM_W("[STRM_TRIG][SCO] codecpcm_start bt clk convolution!"); + } + tg_acl_trigger_offset_time=tg_acl_trigger_offset_time+tirg_delay*TIRG_DELAY_325US; + TRACE_AUD_STREAM_W("[STRM_TRIG][SCO] codecpcm_start need more tirg_delay:%d offset:%d curr:%d,",tirg_delay,tg_acl_trigger_offset_time,curr_ticks); + } + tg_acl_trigger_offset_time &= 0x0fffffff; + + btdrv_syn_trigger_codec_en(0); +// af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, false); +// af_codec_sync_config(AUD_STREAM_CAPTURE, AF_CODEC_SYNC_TYPE_BT, false); + btdrv_syn_clr_trigger(); + + +#if defined(IBRT) + if (app_tws_ibrt_mobile_link_connected()){ + bt_syn_set_tg_ticks(tg_acl_trigger_offset_time, p_ibrt_ctrl->mobile_conhandle, BT_TRIG_SLAVE_ROLE); + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] codecpcm_start set 2 offset:%d",tg_acl_trigger_offset_time); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + bt_syn_set_tg_ticks(tg_acl_trigger_offset_time, p_ibrt_ctrl->ibrt_conhandle, BT_TRIG_SLAVE_ROLE); + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] codecpcm_start set 2 offset:%d",tg_acl_trigger_offset_time); + }else{ + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] codecpcm_start mobile_link:%d %04x ibrt_link:%d %04x", app_tws_ibrt_mobile_link_connected(), p_ibrt_ctrl->mobile_conhandle, + app_tws_ibrt_slave_ibrt_link_connected(), p_ibrt_ctrl->ibrt_conhandle); + } +#else + bt_syn_set_tg_ticks(tg_acl_trigger_offset_time, conhdl, BT_TRIG_SLAVE_ROLE); +#endif + btdrv_syn_trigger_codec_en(1); + app_bt_stream_sco_trigger_set_codecpcm_triggle(1); + + btdrv_enable_playback_triggler(ACL_TRIGGLE_MODE); + + int_unlock(lock); + + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] codecpcm_start enable curr:%x trig:%x curr:%x", + btdrv_syn_get_curr_ticks(), + tg_acl_trigger_offset_time, + curr_ticks); + + + +// af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, true); +// af_codec_sync_config(AUD_STREAM_CAPTURE, AF_CODEC_SYNC_TYPE_BT, true); + + +} + +void app_bt_stream_sco_trigger_codecpcm_stop(void) +{ +#ifdef PLAYBACK_USE_I2S + af_i2s_sync_config(AUD_STREAM_PLAYBACK, AF_I2S_SYNC_TYPE_BT, false); +#else + af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, false); +#endif + af_codec_sync_config(AUD_STREAM_CAPTURE, AF_CODEC_SYNC_TYPE_BT, false); +} +#endif + +void speech_tx_aec_set_frame_len(int len); +int voicebtpcm_pcm_echo_buf_queue_init(uint32_t size); +void voicebtpcm_pcm_echo_buf_queue_reset(void); +void voicebtpcm_pcm_echo_buf_queue_deinit(void); +int voicebtpcm_pcm_audio_init(int sco_sample_rate, int codec_sample_rate); +int voicebtpcm_pcm_audio_deinit(void); +uint32_t voicebtpcm_pcm_audio_data_come(uint8_t *buf, uint32_t len); +uint32_t voicebtpcm_pcm_audio_more_data(uint8_t *buf, uint32_t len); +int store_voicebtpcm_m2p_buffer(unsigned char *buf, unsigned int len); +int get_voicebtpcm_p2m_frame(unsigned char *buf, unsigned int len); +static uint32_t mic_force_mute = 0; +static uint32_t spk_force_mute = 0; +static uint32_t bt_sco_player_code_type = 0; + +static enum AUD_CHANNEL_NUM_T sco_play_chan_num; +static enum AUD_CHANNEL_NUM_T sco_cap_chan_num; + +bool bt_sco_codec_is_msbc(void) +{ + bool en = false; +#ifdef HFP_1_6_ENABLE + if (app_audio_manager_get_scocodecid() == BTIF_HF_SCO_CODEC_MSBC) + { + en = true; + } + else +#endif + { + en = false; + } + + return en; +} + +void bt_sco_mobile_clkcnt_get(uint32_t btclk, uint16_t btcnt, + uint32_t *mobile_master_clk, uint16_t *mobile_master_cnt) +{ +#if defined(IBRT) + app_tws_ibrt_audio_mobile_clkcnt_get(btclk, btcnt, mobile_master_clk, mobile_master_cnt); +#else + uint16_t conhdl = 0xFFFF; + int32_t clock_offset; + uint16_t bit_offset; + int curr_sco; + + curr_sco = app_audio_manager_get_active_sco_num(); + if (curr_sco != BT_DEVICE_NUM){ + conhdl = btif_hf_get_remote_hci_handle(*app_audio_manager_get_active_sco_chnl()); + } + + if (conhdl != 0xFFFF){ + bt_drv_reg_op_piconet_clk_offset_get(conhdl, &clock_offset, &bit_offset); + //TRACE_AUD_STREAM_I("mobile piconet clk:%d bit:%d loc clk:%d cnt:%d", clock_offset, bit_offset, btclk, btcnt); + btdrv_slave2master_clkcnt_convert(btclk, btcnt, + clock_offset, bit_offset, + mobile_master_clk, mobile_master_cnt); + }else{ + TRACE_AUD_STREAM_W("[STRM_TRIG][SCO] mobile_clkcnt_get warning conhdl NULL conhdl:%x", conhdl); + *mobile_master_clk = 0; + *mobile_master_cnt = 0; + } +#endif +} + + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + +#ifdef CHIP_BEST1000 +#error "Unsupport SW_SCO_RESAMPLE on best1000 by now" +#endif +#ifdef NO_SCO_RESAMPLE +#error "Conflicted config: NO_SCO_RESAMPLE and SW_SCO_RESAMPLE" +#endif + +// The decoded playback data in the first irq is output to DAC after the second irq (PING-PONG buffer) +#define SCO_PLAY_RESAMPLE_ALIGN_CNT 2 + +static uint8_t sco_play_irq_cnt; +static bool sco_dma_buf_err; +static struct APP_RESAMPLE_T *sco_capture_resample; +static struct APP_RESAMPLE_T *sco_playback_resample; + +static int bt_sco_capture_resample_iter(uint8_t *buf, uint32_t len) +{ + voicebtpcm_pcm_audio_data_come(buf, len); + return 0; +} + +static int bt_sco_playback_resample_iter(uint8_t *buf, uint32_t len) +{ + voicebtpcm_pcm_audio_more_data(buf, len); + return 0; +} + +#endif +#if defined(SCO_DMA_SNAPSHOT) +extern int process_downlink_bt_voice_frames(uint8_t *in_buf, uint32_t in_len, uint8_t *out_buf,uint32_t out_len,int32_t codec_type); +extern int process_uplink_bt_voice_frames(uint8_t *in_buf, uint32_t in_len, uint8_t *ref_buf, uint32_t ref_len, uint8_t *out_buf,uint32_t out_len,int32_t codec_type); +#define MSBC_FRAME_LEN (60) +#define PCM_LEN_PER_FRAME (240) +#define CAL_FRAME_NUM (22) + +static void bt_sco_codec_tuning(void) +{ + uint32_t btclk; + uint16_t btcnt; + + uint32_t mobile_master_clk; + uint16_t mobile_master_cnt; + + uint32_t mobile_master_clk_offset; + int32_t mobile_master_cnt_offset; + + static float fre_offset=0.0f; + static int32_t mobile_master_cnt_offset_init; + static int32_t mobile_master_cnt_offset_old; + static uint32_t first_proc_flag=0; +#if defined( __AUDIO_RESAMPLE__) && !defined(AUDIO_RESAMPLE_ANTI_DITHER) + static uint32_t frame_counter=0; + static int32_t mobile_master_cnt_offset_max=0; + static int32_t mobile_master_cnt_offset_min=0; + static int32_t mobile_master_cnt_offset_resample=0; + + int32_t offset_max=0; + int32_t offset_min=0; +#endif + + bt_drv_reg_op_dma_tc_clkcnt_get(&btclk, &btcnt); + bt_sco_mobile_clkcnt_get(btclk, btcnt, + &mobile_master_clk, &mobile_master_cnt); + +#if defined(SCO_DMA_SNAPSHOT_DEBUG) + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] tune btclk:%d,btcnt:%d,",mobile_master_clk,mobile_master_cnt); +#endif + + mobile_master_clk_offset=(mobile_master_clk-mobile_master_clk_offset_init)%12; + mobile_master_cnt_offset=mobile_master_clk_offset*625+(625-mobile_master_cnt); + mobile_master_cnt_offset=mobile_master_cnt_offset-(MASTER_MOBILE_BTCNT_OFFSET+mobile_master_cnt_offset_init); + + if(app_bt_stream_sco_trigger_codecpcm_tick()) + { + fre_offset=0.0f; + if(mobile_master_clk_offsetmobile_master_cnt_offset_max) + { + mobile_master_cnt_offset_max=mobile_master_cnt_offset; + } + + if(mobile_master_cnt_offset=CAL_FRAME_NUM) + { + if(mobile_master_cnt_offset_minoffset_max) + { + mobile_master_cnt_offset_resample=mobile_master_cnt_offset_max-offset_max; + } + else + { + mobile_master_cnt_offset_resample=0; + } + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] tune mobile_master_cnt_offset:%d/%d",mobile_master_cnt_offset_min,mobile_master_cnt_offset_max); + mobile_master_cnt_offset=mobile_master_cnt_offset_resample; + + if(first_proc_flag==0) + { + fre_offset=((int32_t)(mobile_master_cnt_offset*0.5f))*0.0000001f + +(mobile_master_cnt_offset-mobile_master_cnt_offset_old)*0.0000001f; + first_proc_flag=1; + } + else + { + fre_offset=fre_offset+((int32_t)(mobile_master_cnt_offset*0.5f))*0.0000001f + +(mobile_master_cnt_offset-mobile_master_cnt_offset_old)*0.0000001f; + first_proc_flag=1; + } + + mobile_master_cnt_offset_old=mobile_master_cnt_offset; +#if defined(SCO_DMA_SNAPSHOT_DEBUG) + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] tune mobile_master_cnt_offset:%d", mobile_master_cnt_offset); +#endif + mobile_master_cnt_offset_max=0; + mobile_master_cnt_offset_min=0; + frame_counter=0; + } + } + else +#endif + { + fre_offset=fre_offset+((int32_t)(mobile_master_cnt_offset*0.5f))*0.00000001f + +(mobile_master_cnt_offset-mobile_master_cnt_offset_old)*0.00000001f; + + mobile_master_cnt_offset_old=mobile_master_cnt_offset; + //TRACE_AUD_STREAM_I("mobile_master_cnt_offset:%d",mobile_master_cnt_offset); + first_proc_flag=1; + + } + +#if defined(SCO_DMA_SNAPSHOT_DEBUG) + TRACE_AUD_STREAM_I("[STRM_TRIG][SCO] tune fre_offset:%d",(int)(fre_offset*10000000.0f)); +#endif + if(first_proc_flag==1) + { + if(fre_offset>0.0001f)fre_offset=0.0001f; + if(fre_offset<-0.0001f)fre_offset=-0.0001f; + } +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + app_resample_tune(playback_samplerate_codecpcm, fre_offset); +#else + af_codec_tune(AUD_STREAM_NUM, fre_offset); +#endif + + return; +} +#endif +extern CQueue* get_tx_esco_queue_ptr(); + +#if defined(BONE_SENSOR_TDM) +#define MIC_TDM_FRAME_MS (15) +#define MIC_TDM_MAX_CH (3) +static int16_t mic_tdm_buf[SPEECH_FRAME_MS_TO_LEN(16000, MIC_TDM_FRAME_MS)]; + +// forward +static uint32_t bt_sco_codec_capture_data(uint8_t *buf, uint32_t len); + +uint32_t tdm_callback_func(uint8_t *buf_ptr, uint32_t frame_len) +{ + int16_t *pcm_buf = (int16_t *)buf_ptr; + + // TODO: Check frame_len, depend on sample rate + + for (uint32_t i = 0; i < frame_len; i++) + { + mic_tdm_buf[i] = pcm_buf[i]; + } + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + ASSERT(0, "[%s] Do not support defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE)", __func__); +#endif + + return 0; +} + +void bt_sco_get_tdm_buffer(uint8_t **buf, uint32_t *len) +{ + *buf = (uint8_t *)&mic_tdm_buf[0]; + *len = sizeof(mic_tdm_buf); +} +#endif + +#if defined(ANC_NOISE_TRACKER) +static int16_t *anc_buf = NULL; +#endif + + +#if defined(ANC_WNR_ENABLED) +#if defined(SPEECH_TX_24BIT) +static int32_t wnr_buf[256*2]; +#else +static short wnr_buf[256*2]; +#endif +#endif +//#define BT_SCO_HANDLER_PROFILE + +//( codec:mic-->btpcm:tx +// codec:mic +static uint32_t bt_sco_codec_capture_data(uint8_t *buf, uint32_t len) +{ + app_bt_stream_trigger_checker_handler(TRIGGER_CHECKER_HFP_AUDPCM_CAPTURE); + +#if defined(ANC_NOISE_TRACKER) + int16_t *pcm_buf = (int16_t *)buf; + uint32_t pcm_len = len / sizeof(short); + uint32_t ch_num = SPEECH_CODEC_CAPTURE_CHANNEL_NUM + ANC_NOISE_TRACKER_CHANNEL_NUM; + uint32_t remain_ch_num = SPEECH_CODEC_CAPTURE_CHANNEL_NUM; + + +#if defined(SPEECH_TX_AEC_CODEC_REF) + ch_num += 1; + remain_ch_num += 1; +#endif + + ASSERT(pcm_len % ch_num == 0, "[%s] input data length error", __FUNCTION__); + + // assume anc mic in ch0 + for (uint32_t i = 0, j = 0; i < pcm_len; i += ch_num, j += ANC_NOISE_TRACKER_CHANNEL_NUM) + { + for (uint32_t ch = 0; ch < ANC_NOISE_TRACKER_CHANNEL_NUM; ch++) + anc_buf[j + ch] = pcm_buf[i + ch]; + } + + noise_tracker_process(anc_buf, pcm_len / ch_num * ANC_NOISE_TRACKER_CHANNEL_NUM); + + for (uint32_t i = 0, j = 0; i < pcm_len; i += ch_num, j += remain_ch_num) + { + for (uint32_t chi = ANC_NOISE_TRACKER_CHANNEL_NUM, cho = 0; chi < ch_num; chi++, cho++) + pcm_buf[j + cho] = pcm_buf[i + chi]; + } + + len = len / ch_num * remain_ch_num; +#endif + +#if defined(AF_ADC_I2S_SYNC) + //TRACE_AUD_STREAM_I("[SCO][MIC] cnt = %d", codec_capture_cnt++); +#endif + +#if defined(ANC_WNR_ENABLED) + +#if defined(SPEECH_TX_24BIT) + int32_t *pcm_buf = (int32_t *)buf; + uint32_t pcm_len = len / sizeof(int32_t); +#else + int16_t *pcm_buf = (int16_t *)buf; + uint32_t pcm_len = len / sizeof(short); +#endif + + for(uint32_t i=0;i>8); + } + int_unlock(lock); + } +#endif + + + //TRACE_AUD_STREAM_I("pcm length:%d",len); + + //processing clock + bt_sco_codec_tuning(); + + + //processing mic + uint8_t *capture_pcm_frame_p=capture_buf_codecpcm+pingpang*(capture_size_codecpcm)/2; + //uint8_t *dst=(uint8_t *)(playback_buf_btpcm+(pingpang)*playback_size_btpcm/2); + uint8_t *dst=playback_buf_btpcm_cache; + uint8_t *ref_pcm_frame_p=playback_buf_codecpcm+(pingpang^1)*(playback_size_codecpcm)/2; + +#if defined(HFP_1_6_ENABLE) + process_uplink_bt_voice_frames(capture_pcm_frame_p,len, + ref_pcm_frame_p,(playback_size_codecpcm)/2, + dst,len,app_audio_manager_get_scocodecid()); +#else + process_uplink_bt_voice_frames(capture_pcm_frame_p,len, + ref_pcm_frame_p,(playback_size_codecpcm)/2, + dst,len,BTIF_HF_SCO_CODEC_CVSD); +#endif + +#if defined(BT_SCO_HANDLER_PROFILE) + uint32_t end_ticks = hal_fast_sys_timer_get(); + TRACE_AUD_STREAM_I("[SCO][MIC] takes %d us", + FAST_TICKS_TO_US(end_ticks - start_ticks)); +#endif + + return len; + +#else + +#if defined(BT_SCO_HANDLER_PROFILE) + uint32_t start_ticks = hal_fast_sys_timer_get(); +#endif + +#if defined(BONE_SENSOR_TDM) + int16_t *pcm_buf = (int16_t *)buf; + uint32_t frame_len = len / sizeof(short) / SPEECH_CODEC_CAPTURE_CHANNEL_NUM; + uint32_t ch_num = SPEECH_CODEC_CAPTURE_CHANNEL_NUM + 1; + + ASSERT(SPEECH_CODEC_CAPTURE_CHANNEL_NUM < MIC_TDM_MAX_CH, "[%s] SPEECH_CODEC_CAPTURE_CHANNEL_NUM(%d) is invalid", __func__, SPEECH_CODEC_CAPTURE_CHANNEL_NUM); + // TODO: Check len, depend on sample rate + + for (uint32_t ch = 0; ch < SPEECH_CODEC_CAPTURE_CHANNEL_NUM; ch++) + { + for (uint32_t i = 0; i < frame_len; i++) + { + mic_tdm_buf[ch_num * i + ch] = pcm_buf[SPEECH_CODEC_CAPTURE_CHANNEL_NUM * i + ch]; + } + } + + return len; +#endif + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + if(hal_cmu_get_audio_resample_status()) + { + if (af_stream_buffer_error(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE)) { + sco_dma_buf_err = true; + } + // The decoded playback data in the first irq is output to DAC after the second irq (PING-PONG buffer), + // so it is aligned with the capture data after 2 playback irqs. + if (sco_play_irq_cnt < SCO_PLAY_RESAMPLE_ALIGN_CNT) { + // Skip processing + return len; + } + app_capture_resample_run(sco_capture_resample, buf, len); + } + else +#endif + { + voicebtpcm_pcm_audio_data_come(buf, len); + } + +#if defined(BT_SCO_HANDLER_PROFILE) + uint32_t end_ticks = hal_fast_sys_timer_get(); + TRACE_AUD_STREAM_I("[SCO][MIC] takes %d us", + FAST_TICKS_TO_US(end_ticks - start_ticks)); +#endif + + return len; +#endif +} + +#ifdef _SCO_BTPCM_CHANNEL_ +// btpcm:tx +static uint32_t bt_sco_btpcm_playback_data(uint8_t *buf, uint32_t len) +{ + app_bt_stream_trigger_checker_handler(TRIGGER_CHECKER_HFP_BTPCM_PLAYERBLACK); + +#if defined(SCO_DMA_SNAPSHOT) + return len; +#else + +#if defined(BT_SCO_HANDLER_PROFILE) + uint32_t start_ticks = hal_fast_sys_timer_get(); +#endif + + get_voicebtpcm_p2m_frame(buf, len); + +#if defined(BT_SCO_HANDLER_PROFILE) + uint32_t end_ticks = hal_fast_sys_timer_get(); + TRACE_AUD_STREAM_I("[SCO][SPK] takes %d us", + FAST_TICKS_TO_US(end_ticks - start_ticks)); +#endif + + return len; + +#endif +} +//) + +#if defined(AF_ADC_I2S_SYNC) +void codec_capture_i2s_enable(void) +{ + uint32_t lock; + + TRACE_AUD_STREAM_I("[SCO][IIS] Start...", __func__); + + lock = int_lock(); + hal_codec_capture_enable(); + hal_i2s_enable(HAL_I2S_ID_0); + int_unlock(lock); + +} +#endif + +extern CQueue* get_rx_esco_queue_ptr(); + +static volatile bool is_codec_stream_started = false; +#ifdef PCM_PRIVATE_DATA_FLAG + +void bt_sco_btpcm_get_pcm_priv_data(struct PCM_DATA_FLAG_T *pcm_data, uint8_t *buf, uint32_t len) +{ + uint8_t frame_num = len/120; + for(uint8_t i=0; i>5)&3; + pcm_data[i].btclk = buf[head_pos+6]|(buf[head_pos+8]<<8)|(buf[head_pos+10]<<16)|(buf[head_pos+12]<<24); + pcm_data[i].reserved = buf[head_pos+14]|(buf[head_pos+16]<<8)|(buf[head_pos+18]<<16)|(buf[head_pos+20]<<24); + //clear private msg in buffer + for(uint8_t j=0; jcodec:spk +// btpcm:rx +extern void bt_drv_reg_op_set_music_ongong_flag(); +extern void bt_drv_reg_op_clear_music_ongong_flag(); +static uint32_t bt_sco_btpcm_capture_data(uint8_t *buf, uint32_t len) +{ + int POSSIBLY_UNUSED sRet = 0; + + app_bt_stream_trigger_checker_handler(TRIGGER_CHECKER_HFP_BTPCM_CAPTURE); + +#ifdef __BT_ONE_BRING_TWO__ + if(a2dp_is_music_ongoing()) + bt_drv_reg_op_set_music_ongong_flag(); + else + bt_drv_reg_op_clear_music_ongong_flag(); +#endif +#if defined(PCM_PRIVATE_DATA_FLAG) && defined(PCM_FAST_MODE) + bt_sco_btpcm_get_pcm_priv_data(pcm_data_param, buf, len); + +#endif + +#if defined(SCO_DMA_SNAPSHOT) + uint32_t btclk; + uint16_t btcnt; + + uint32_t mobile_master_clk; + uint16_t mobile_master_cnt; + + bool codec_stream_trig = false; + +#if defined(BT_SCO_HANDLER_PROFILE) + uint32_t start_ticks = hal_fast_sys_timer_get(); +#endif + + if((is_codec_stream_started == false)&&(buf==capture_buf_btpcm)) + { + if(!af_stream_buffer_error(AUD_STREAM_ID_1, AUD_STREAM_CAPTURE)) + { + bt_drv_reg_op_dma_tc_clkcnt_get(&btclk, &btcnt); + bt_sco_mobile_clkcnt_get(btclk, btcnt,&mobile_master_clk, &mobile_master_cnt); + hal_sys_timer_delay_us(1); + if(!af_stream_buffer_error(AUD_STREAM_ID_1, AUD_STREAM_CAPTURE)) + { + codec_stream_trig = true; + } + } + } +/* + uint32_t curr_ticks; + + ibbt_ctrl_t *p_ibbt_ctrl = app_tws_ibbt_get_bt_ctrl_ctx(); + if (app_tws_ibbt_tws_link_connected()){ + curr_ticks = bt_syn_get_curr_ticks(IBBT_MASTER == p_ibbt_ctrl->current_role ? p_ibbt_ctrl->mobile_conhandle : p_ibbt_ctrl->ibbt_conhandle); + TRACE_AUD_STREAM_I("bt_sco_btpcm_capture_data +++++++++++++++++++++++++++++++++curr_ticks:%d,",curr_ticks); + }else{ + curr_ticks = btdrv_syn_get_curr_ticks(); + TRACE_AUD_STREAM_I("--------------------------------------"); + } +*/ + sco_btpcm_mute_flag=0; + + if (codec_stream_trig) { + if (app_bt_stream_sco_trigger_btpcm_tick()) { + af_stream_dma_tc_irq_enable(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_dma_tc_irq_disable(AUD_STREAM_ID_1, AUD_STREAM_CAPTURE); + +#if defined(SCO_DMA_SNAPSHOT_DEBUG) + af_stream_dma_tc_irq_enable(AUD_STREAM_ID_1, AUD_STREAM_CAPTURE); +#endif + TRACE_AUD_STREAM_I("[SCO][BTPCMRX] buf:%p,capture_buf_btpcm:%p",buf,capture_buf_btpcm); + + // uint16_t *source=(uint16_t *)buf; + // DUMP16("%02x,", source, MSBC_FRAME_LEN); + +#if defined(BONE_SENSOR_TDM) +#if defined(AF_ADC_I2S_SYNC) + hal_i2s_enable_delay(HAL_I2S_ID_0); + // hal_codec_capture_enable_delay(); +#endif + tdm_stream_start(); +#endif + mobile_master_clk_offset_init=mobile_master_clk%12; + app_bt_stream_sco_trigger_codecpcm_start(mobile_master_clk,mobile_master_cnt); + is_codec_stream_started = true; + +#if defined(SCO_DMA_SNAPSHOT_DEBUG) + TRACE_AUD_STREAM_I("[SCO][BTPCMRX] btclk:%d,btcnt:%d,",mobile_master_clk,mobile_master_cnt); +#endif + } + } else { +#if defined(SCO_DMA_SNAPSHOT_DEBUG) + bt_drv_reg_op_dma_tc_clkcnt_get(&btclk, &btcnt); + bt_sco_mobile_clkcnt_get(btclk, btcnt,&mobile_master_clk, &mobile_master_cnt); + TRACE_AUD_STREAM_I("[SCO][BTPCMRX]:btclk:%d,btcnt:%d,",mobile_master_clk,mobile_master_cnt); +#endif + } + +#if defined(BT_SCO_HANDLER_PROFILE) + uint32_t end_ticks = hal_fast_sys_timer_get(); + TRACE_AUD_STREAM_I("[SCO][BTPCMRX] takes %d us", + FAST_TICKS_TO_US(end_ticks - start_ticks)); +#endif + + return len; + +#else +#if defined(BT_SCO_HANDLER_PROFILE) + uint32_t start_ticks = hal_fast_sys_timer_get(); +#endif + + if(!is_sco_mode()){ + TRACE_AUD_STREAM_E("[SCO][BTPCMRX] player exit!"); + memset(buf,0x0,len); + return len; + } + +#if defined(TX_RX_PCM_MASK) + TRACE_AUD_STREAM_I("[SCO][BTPCMRX] TX_RX_PCM_MASK"); + CQueue* Rx_esco_queue_temp = NULL; + Rx_esco_queue_temp = get_rx_esco_queue_ptr(); + if(bt_sco_codec_is_msbc() && btdrv_is_pcm_mask_enable() ==1 ) + { + memset(buf,0,len); + int status = 0; + len /= 2; + uint8_t rx_data[len]; + status = DeCQueue(Rx_esco_queue_temp,rx_data,len); + for(uint32_t i = 0; imobile_conhandle -0x80); + } + else if (app_tws_ibrt_slave_ibrt_link_connected()) + { + valid = true; + bitoffset = btdrv_rf_bitoffset_get(p_ibrt_ctrl->ibrt_conhandle -0x80); + } + + if(valid) + { + if(app_if_need_fix_target_rxbit() == false) + { + if(bitoffsetSLOT_SIZE-XTAL_OFFSET) + bitoffset = SLOT_SIZE-XTAL_OFFSET; + } +#ifdef BT_XTAL_SYNC_SLOW + bt_xtal_sync_new_new(bitoffset,app_if_need_fix_target_rxbit(),BT_XTAL_SYNC_MODE_WITH_MOBILE); +#else + bt_xtal_sync_new(bitoffset,app_if_need_fix_target_rxbit(),BT_XTAL_SYNC_MODE_WITH_MOBILE); +#endif + } +#endif +#else + bt_xtal_sync(BT_XTAL_SYNC_MODE_VOICE); +#endif +#endif + +#if defined(AF_ADC_I2S_SYNC) + //TRACE_AUD_STREAM_I("[%s] cnt = %d", __func__, codec_playback_cnt++); +#endif + +#if defined(SCO_DMA_SNAPSHOT) + //processing ping pang flag + int pingpang; + + if(buf==playback_buf_codecpcm) + { + pingpang=0; + } + else + { + pingpang=1; + } +#ifdef TX_RX_PCM_MASK + //processing btpcm.(It must be from CPU's copy ) + if(btdrv_is_pcm_mask_enable()==1&&bt_sco_codec_is_msbc()) + { + uint32_t lock; + uint32_t i; + //must lock the interrupts when exchanging data. + lock = int_lock(); + uint16_t *capture_dst=(uint16_t *)(capture_buf_btpcm + pingpang * capture_size_btpcm / 2); + + for( i =0; i> 8); + } + source_len >>= 1; + } + process_downlink_bt_voice_frames(source,source_len, + playbakce_pcm_frame_p,(playback_size_codecpcm)/sco_play_chan_num/2,app_audio_manager_get_scocodecid()); +#else + process_downlink_bt_voice_frames(source,(playback_size_btpcm)/2, + playbakce_pcm_frame_p,(playback_size_codecpcm)/sco_play_chan_num/2,BTIF_HF_SCO_CODEC_CVSD); +#endif + + if (sco_play_chan_num == AUD_CHANNEL_NUM_2) { + // Convert mono data to stereo data +#if defined(SPEECH_RX_24BIT) + app_bt_stream_copy_track_one_to_two_24bits((int32_t *)playbakce_pcm_frame_p, (int32_t *)playbakce_pcm_frame_p, playback_size_codecpcm / 2 / sco_play_chan_num / sizeof(int32_t)); +#else + app_bt_stream_copy_track_one_to_two_16bits((int16_t *)playbakce_pcm_frame_p, (int16_t *)playbakce_pcm_frame_p, playback_size_codecpcm / 2 / sco_play_chan_num / sizeof(int16_t)); +#endif + } + return len; +#else +#if defined(BT_SCO_HANDLER_PROFILE) + uint32_t start_ticks = hal_fast_sys_timer_get(); +#endif + + uint8_t *dec_buf; + uint32_t mono_len; + +#if defined(SPEECH_RX_24BIT) + len /= 2; +#endif + +#ifdef __BT_ANC__ + mono_len = len / sco_play_chan_num / bt_sco_samplerate_ratio; + dec_buf = bt_anc_sco_dec_buf; +#else + mono_len = len / sco_play_chan_num; + dec_buf = buf; +#endif + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + if(hal_cmu_get_audio_resample_status()) + { + if (sco_play_irq_cnt < SCO_PLAY_RESAMPLE_ALIGN_CNT) { + sco_play_irq_cnt++; + } + if (sco_dma_buf_err || af_stream_buffer_error(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK)) { + sco_dma_buf_err = false; + sco_play_irq_cnt = 0; + app_resample_reset(sco_playback_resample); + app_resample_reset(sco_capture_resample); + voicebtpcm_pcm_echo_buf_queue_reset(); + TRACE_AUD_STREAM_I("[SCO][SPK]: DMA buffer error: reset resample"); + } + app_playback_resample_run(sco_playback_resample, dec_buf, mono_len); + } + else +#endif + { +#ifdef __BT_ANC__ + bt_anc_sco_down_sample_16bits((int16_t *)dec_buf, (int16_t *)buf, mono_len / 2); +#else + if (sco_play_chan_num == AUD_CHANNEL_NUM_2) { + // Convert stereo data to mono data (to save into echo_buf) + app_bt_stream_copy_track_two_to_one_16bits((int16_t *)dec_buf, (int16_t *)buf, mono_len / 2); + } +#endif + voicebtpcm_pcm_audio_more_data(dec_buf, mono_len); + } + +#ifdef __BT_ANC__ + voicebtpcm_pcm_resample((int16_t *)dec_buf, mono_len / 2, (int16_t *)buf); +#endif + +#if defined(SPEECH_RX_24BIT) + len <<= 1; +#endif + + if (sco_play_chan_num == AUD_CHANNEL_NUM_2) { + // Convert mono data to stereo data +#if defined(SPEECH_RX_24BIT) + app_bt_stream_copy_track_one_to_two_24bits((int32_t *)buf, (int32_t *)buf, len / 2 / sizeof(int32_t)); +#else + app_bt_stream_copy_track_one_to_two_16bits((int16_t *)buf, (int16_t *)buf, len / 2 / sizeof(int16_t)); +#endif + } + + if (spk_force_mute) + { + memset(buf, 0, len); + } + +#if defined(BT_SCO_HANDLER_PROFILE) + uint32_t end_ticks = hal_fast_sys_timer_get(); + TRACE_AUD_STREAM_I("[SCO][SPK] takes %d us", + FAST_TICKS_TO_US(end_ticks - start_ticks)); +#endif + + return len; +#endif +} + +int bt_sco_player_forcemute(bool mic_mute, bool spk_mute) +{ + mic_force_mute = mic_mute; + spk_force_mute = spk_mute; + return 0; +} + +int bt_sco_player_get_codetype(void) +{ + if (gStreamplayer & APP_BT_STREAM_HFP_PCM) + { + return bt_sco_player_code_type; + } + else + { + return 0; + } +} + +#if defined(AUDIO_ANC_FB_MC_SCO) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) +static uint32_t audio_mc_data_playback_sco(uint8_t *buf, uint32_t mc_len_bytes) +{ + // uint32_t begin_time; + //uint32_t end_time; + // begin_time = hal_sys_timer_get(); + // TRACE_AUD_STREAM_I("phone cancel: %d",begin_time); + + float left_gain; + float right_gain; + int32_t playback_len_bytes,mc_len_bytes_8; + int32_t i,j,k; + int delay_sample; + + mc_len_bytes_8=mc_len_bytes/8; + + hal_codec_get_dac_gain(&left_gain,&right_gain); + + TRACE_AUD_STREAM_I("[SCO][SPK][MC] playback_samplerate_ratio: %d,ch:%d,sample_size:%d.",playback_samplerate_ratio_bt,playback_ch_num_bt,sample_size_play_bt); + TRACE_AUD_STREAM_I("[SCO][SPK][MC] len: %d",mc_len_bytes); + + // TRACE_AUD_STREAM_I("left_gain: %d",(int)(left_gain*(1<<12))); + // TRACE_AUD_STREAM_I("right_gain: %d",(int)(right_gain*(1<<12))); + + playback_len_bytes=mc_len_bytes/playback_samplerate_ratio_bt; + + if (sample_size_play_bt == AUD_BITS_16) + { + int16_t *sour_p=(int16_t *)(playback_buf_bt+playback_size_bt/2); + int16_t *mid_p=(int16_t *)(buf); + int16_t *mid_p_8=(int16_t *)(buf+mc_len_bytes-mc_len_bytes_8); + int16_t *dest_p=(int16_t *)buf; + + if(buf == playback_buf_mc) + { + sour_p=(int16_t *)playback_buf_bt; + } + + if(playback_ch_num_bt==AUD_CHANNEL_NUM_2) + { + delay_sample=DELAY_SAMPLE_MC; + + for(i=0,j=0;ihfp_vol; + app_audio_manager_sco_status_checker(); + +#if defined(HFP_1_6_ENABLE) + bt_sco_player_code_type = app_audio_manager_get_scocodecid(); +#endif + + if (freq < APP_SYSFREQ_104M) + { + freq = APP_SYSFREQ_104M; + } + +#if defined(AUDIO_ANC_FB_MC_SCO) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + if (freq < APP_SYSFREQ_208M) { + freq = APP_SYSFREQ_208M; + } +#endif + +#if defined(SCO_CP_ACCEL) + freq = APP_SYSFREQ_52M; +#endif + + app_sysfreq_req(APP_SYSFREQ_USER_BT_SCO, freq); + TRACE_AUD_STREAM_I("[SCO_PLAYER] sysfreq:%d", freq); + TRACE_AUD_STREAM_I("[SCO_PLAYER] sysfreq calc : %d\n", hal_sys_timer_calc_cpu_freq(5, 0)); + +#ifndef FPGA + app_overlay_select(APP_OVERLAY_HFP); +#ifdef BT_XTAL_SYNC + bt_init_xtal_sync(BT_XTAL_SYNC_MODE_VOICE, BT_INIT_XTAL_SYNC_MIN, BT_INIT_XTAL_SYNC_MAX, BT_INIT_XTAL_SYNC_FCAP_RANGE); +#endif +#endif + btdrv_rf_bit_offset_track_enable(true); + +#if !defined(SCO_DMA_SNAPSHOT) + int aec_frame_len = speech_get_frame_size(speech_codec_get_sample_rate(), 1, SPEECH_SCO_FRAME_MS); + speech_tx_aec_set_frame_len(aec_frame_len); +#endif + + bt_sco_player_forcemute(false, false); + + bt_sco_mode = 1; + + app_audio_mempool_init(); + +#ifndef _SCO_BTPCM_CHANNEL_ + memset(&hf_sendbuff_ctrl, 0, sizeof(hf_sendbuff_ctrl)); +#endif + + sample_rate = speech_codec_get_sample_rate(); + + sco_cap_chan_num = (enum AUD_CHANNEL_NUM_T)SPEECH_CODEC_CAPTURE_CHANNEL_NUM; + +#if defined(FPGA) + sco_cap_chan_num = AUD_CHANNEL_NUM_2; +#endif + +#if defined(SPEECH_TX_AEC_CODEC_REF) + sco_cap_chan_num = (enum AUD_CHANNEL_NUM_T)(sco_cap_chan_num + 1); +#endif + +#if defined(ANC_NOISE_TRACKER) + sco_cap_chan_num = (enum AUD_CHANNEL_NUM_T)(sco_cap_chan_num + ANC_NOISE_TRACKER_CHANNEL_NUM); +#endif + +#ifdef PLAYBACK_USE_I2S + hal_cmu_audio_resample_disable(); +#endif + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + // codec:mic + stream_cfg.channel_num = sco_cap_chan_num; + stream_cfg.data_size = speech_get_af_buffer_size(sample_rate, sco_cap_chan_num, SPEECH_SCO_FRAME_MS); + +#if defined(__AUDIO_RESAMPLE__) && defined(NO_SCO_RESAMPLE) + // When __AUDIO_RESAMPLE__ is defined, + // resample is off by default on best1000, and on by default on other platforms +#ifndef CHIP_BEST1000 + hal_cmu_audio_resample_disable(); +#endif +#endif + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + if (sample_rate == AUD_SAMPRATE_8000) + { + stream_cfg.sample_rate = AUD_SAMPRATE_8463; + } + else if (sample_rate == AUD_SAMPRATE_16000) + { + stream_cfg.sample_rate = AUD_SAMPRATE_16927; + } +#ifdef RESAMPLE_ANY_SAMPLE_RATE + sco_capture_resample = app_capture_resample_any_open( stream_cfg.channel_num, + bt_sco_capture_resample_iter, stream_cfg.data_size / 2, + (float)CODEC_FREQ_26M / CODEC_FREQ_24P576M); +#else + sco_capture_resample = app_capture_resample_open(sample_rate, stream_cfg.channel_num, + bt_sco_capture_resample_iter, stream_cfg.data_size / 2); +#endif + uint32_t mono_cap_samp_cnt = stream_cfg.data_size / 2 / 2 / stream_cfg.channel_num; + uint32_t cap_irq_cnt_per_frm = ((mono_cap_samp_cnt * stream_cfg.sample_rate + (sample_rate - 1)) / sample_rate + + (aec_frame_len - 1)) / aec_frame_len; + if (cap_irq_cnt_per_frm == 0) { + cap_irq_cnt_per_frm = 1; + } +#else + stream_cfg.sample_rate = sample_rate; +#endif + +#if defined(SPEECH_TX_24BIT) + stream_cfg.bits = AUD_BITS_24; + stream_cfg.data_size *= 2; +#else + stream_cfg.bits = AUD_BITS_16; +#endif + stream_cfg.vol = stream_local_volume; + +#ifdef FPGA + stream_cfg.device = AUD_STREAM_USE_EXT_CODEC; +#else + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; +#endif + stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; + stream_cfg.handler = bt_sco_codec_capture_data; + app_audio_mempool_get_buff(&bt_audio_buff, stream_cfg.data_size); + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(bt_audio_buff); + +#if defined(SCO_DMA_SNAPSHOT) + capture_buf_codecpcm=stream_cfg.data_ptr; + capture_size_codecpcm=stream_cfg.data_size; +#endif + TRACE_AUD_STREAM_I("[SCO_PLAYER] capture sample_rate:%d, data_size:%d",stream_cfg.sample_rate,stream_cfg.data_size); + +#if defined(ANC_WNR_ENABLED) + if(app_anc_work_status()) + { + anc_wnr_close(); + anc_wnr_ctrl(stream_cfg.sample_rate, speech_get_frame_size(stream_cfg.sample_rate, 1, SPEECH_SCO_FRAME_MS)); + anc_release_gain(); + anc_wnr_open(ANC_WNR_OPEN_MODE_CONFIGURE); + } + else + { + anc_wnr_ctrl(stream_cfg.sample_rate, speech_get_frame_size(stream_cfg.sample_rate, 1, SPEECH_SCO_FRAME_MS)); + } +#endif + + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + +#if defined(HW_DC_FILTER_WITH_IIR) + hw_filter_codec_iir_st = hw_filter_codec_iir_create(stream_cfg.sample_rate, stream_cfg.channel_num, stream_cfg.bits, &adc_iir_cfg); +#endif + +#if defined(CHIP_BEST2300) + btdrv_set_bt_pcm_triggler_delay(60); +#elif defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST2001) + +#if defined(SCO_DMA_SNAPSHOT) + btdrv_set_bt_pcm_triggler_delay(2); +#else + btdrv_set_bt_pcm_triggler_delay(60); +#endif + +#elif defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) + +#if defined(SCO_DMA_SNAPSHOT) + btdrv_set_bt_pcm_triggler_delay(2); +#else + btdrv_set_bt_pcm_triggler_delay(59); +#endif + +#else + btdrv_set_bt_pcm_triggler_delay(55); +#endif + // codec:spk + sample_rate = speech_codec_get_sample_rate(); +#if defined(CHIP_BEST1000) + sco_play_chan_num = AUD_CHANNEL_NUM_2; +#else +#ifdef PLAYBACK_USE_I2S + sco_play_chan_num = AUD_CHANNEL_NUM_2; +#else + sco_play_chan_num = AUD_CHANNEL_NUM_1; +#endif +#endif + +#if defined(BONE_SENSOR_TDM) +#if defined(AF_ADC_I2S_SYNC) + codec_capture_cnt = 0; + codec_playback_cnt = 0; +#endif + lis25ba_init(); + tdm_stream_register(tdm_callback_func); +#endif + + stream_cfg.channel_num = sco_play_chan_num; + // stream_cfg.data_size = BT_AUDIO_SCO_BUFF_SIZE * stream_cfg.channel_num; + stream_cfg.data_size = speech_get_af_buffer_size(sample_rate, sco_play_chan_num, SPEECH_SCO_FRAME_MS); +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + if (sample_rate == AUD_SAMPRATE_8000) + { + stream_cfg.sample_rate = AUD_SAMPRATE_8463; + } + else if (sample_rate == AUD_SAMPRATE_16000) + { + stream_cfg.sample_rate = AUD_SAMPRATE_16927; + } +#ifdef RESAMPLE_ANY_SAMPLE_RATE + sco_playback_resample = app_playback_resample_any_open( AUD_CHANNEL_NUM_1, + bt_sco_playback_resample_iter, stream_cfg.data_size / stream_cfg.channel_num / 2, + (float)CODEC_FREQ_24P576M / CODEC_FREQ_26M); +#else + sco_playback_resample = app_playback_resample_open(sample_rate, AUD_CHANNEL_NUM_1, + bt_sco_playback_resample_iter, stream_cfg.data_size / stream_cfg.channel_num / 2); +#endif + sco_play_irq_cnt = 0; + sco_dma_buf_err = false; + + uint32_t mono_play_samp_cnt = stream_cfg.data_size / 2 / 2 / stream_cfg.channel_num; + uint32_t play_irq_cnt_per_frm = ((mono_play_samp_cnt * stream_cfg.sample_rate + (sample_rate - 1)) / sample_rate + + (aec_frame_len - 1)) / aec_frame_len; + if (play_irq_cnt_per_frm == 0) { + play_irq_cnt_per_frm = 1; + } + uint32_t play_samp_cnt_per_frm = mono_play_samp_cnt * play_irq_cnt_per_frm; + uint32_t cap_samp_cnt_per_frm = mono_cap_samp_cnt * cap_irq_cnt_per_frm; + uint32_t max_samp_cnt_per_frm = (play_samp_cnt_per_frm >= cap_samp_cnt_per_frm) ? play_samp_cnt_per_frm : cap_samp_cnt_per_frm; + uint32_t echo_q_samp_cnt = (((max_samp_cnt_per_frm + mono_play_samp_cnt * SCO_PLAY_RESAMPLE_ALIGN_CNT) * + // convert to 8K/16K sample cnt + sample_rate +(stream_cfg.sample_rate - 1)) / stream_cfg.sample_rate + + // aligned with aec_frame_len + (aec_frame_len - 1)) / aec_frame_len * aec_frame_len; + if (echo_q_samp_cnt == 0) { + echo_q_samp_cnt = aec_frame_len; + } + voicebtpcm_pcm_echo_buf_queue_init(echo_q_samp_cnt * 2); +#else + stream_cfg.sample_rate = sample_rate; +#endif + +#ifdef __BT_ANC__ + // Mono channel decoder buffer (8K or 16K sample rate) + app_audio_mempool_get_buff(&bt_anc_sco_dec_buf, stream_cfg.data_size / 2 / sco_play_chan_num); + // The playback size for the actual sample rate + bt_sco_samplerate_ratio = 6/(sample_rate/AUD_SAMPRATE_8000); + stream_cfg.data_size *= bt_sco_samplerate_ratio; +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + stream_cfg.sample_rate = AUD_SAMPRATE_50781; +#else + stream_cfg.sample_rate = AUD_SAMPRATE_48000; +#endif + //damic_init(); + //init_amic_dc_bt(); + //ds_fir_init(); + us_fir_init(); +#endif + stream_cfg.bits = AUD_BITS_16; +#ifdef PLAYBACK_USE_I2S + stream_cfg.device = AUD_STREAM_USE_I2S0_MASTER; + stream_cfg.io_path = AUD_IO_PATH_NULL; +#else + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; +#endif + stream_cfg.handler = bt_sco_codec_playback_data; + +#if defined(SPEECH_RX_24BIT) + stream_cfg.bits = AUD_BITS_24; + stream_cfg.data_size *= 2; +#endif + +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + uint8_t* promptTmpSourcePcmDataBuf; + uint8_t* promptTmpTargetPcmDataBuf; + uint8_t* promptPcmDataBuf; + uint8_t* promptResamplerBuf; + + sco_sample_rate = stream_cfg.sample_rate; + app_audio_mempool_get_buff(&promptTmpSourcePcmDataBuf, AUDIO_PROMPT_SOURCE_PCM_BUFFER_SIZE); + app_audio_mempool_get_buff(&promptTmpTargetPcmDataBuf, AUDIO_PROMPT_TARGET_PCM_BUFFER_SIZE); + app_audio_mempool_get_buff(&promptPcmDataBuf, AUDIO_PROMPT_PCM_BUFFER_SIZE); + app_audio_mempool_get_buff(&promptResamplerBuf, AUDIO_PROMPT_BUF_SIZE_FOR_RESAMPLER); + + audio_prompt_buffer_config(MIX_WITH_SCO_STREAMING, + stream_cfg.channel_num, + stream_cfg.bits, + promptTmpSourcePcmDataBuf, + promptTmpTargetPcmDataBuf, + promptPcmDataBuf, + AUDIO_PROMPT_PCM_BUFFER_SIZE, + promptResamplerBuf, + AUDIO_PROMPT_BUF_SIZE_FOR_RESAMPLER); +#endif + + app_audio_mempool_get_buff(&bt_audio_buff, stream_cfg.data_size); + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(bt_audio_buff); + + TRACE_AUD_STREAM_I("[SCO_PLAYER] playback sample_rate:%d, data_size:%d",stream_cfg.sample_rate,stream_cfg.data_size); + +#if defined(AUDIO_ANC_FB_MC_SCO) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + sample_size_play_bt=stream_cfg.bits; + sample_rate_play_bt=stream_cfg.sample_rate; + data_size_play_bt=stream_cfg.data_size; + playback_buf_bt=stream_cfg.data_ptr; + playback_size_bt=stream_cfg.data_size; + +#ifdef __BT_ANC__ + playback_samplerate_ratio_bt=8; +#else + if (sample_rate_play_bt == AUD_SAMPRATE_8000) + { + playback_samplerate_ratio_bt=8*3*2; + } + else if (sample_rate_play_bt == AUD_SAMPRATE_16000) + { + playback_samplerate_ratio_bt=8*3; + } +#endif + + playback_ch_num_bt=stream_cfg.channel_num; +#endif + +#if defined(SCO_DMA_SNAPSHOT) + playback_buf_codecpcm=stream_cfg.data_ptr; + playback_size_codecpcm=stream_cfg.data_size; + playback_samplerate_codecpcm=stream_cfg.sample_rate; +#endif + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + + af_stream_dma_tc_irq_enable(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + + af_codec_set_playback_post_handler(bt_sco_codec_playback_data_post_handler); + +#if defined(AUDIO_ANC_FB_MC_SCO) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + stream_cfg.bits = sample_size_play_bt; + stream_cfg.channel_num = playback_ch_num_bt; + stream_cfg.sample_rate = sample_rate_play_bt; + stream_cfg.device = AUD_STREAM_USE_MC; + stream_cfg.vol = 0; + stream_cfg.handler = audio_mc_data_playback_sco; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + + app_audio_mempool_get_buff(&bt_audio_buff, data_size_play_bt*playback_samplerate_ratio_bt); + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(bt_audio_buff); + stream_cfg.data_size = data_size_play_bt*playback_samplerate_ratio_bt; + + playback_buf_mc=stream_cfg.data_ptr; + playback_size_mc=stream_cfg.data_size; + + anc_mc_run_init(hal_codec_anc_convert_rate(sample_rate_play_bt)); + + memset(delay_buf_bt,0,sizeof(delay_buf_bt)); + + af_stream_open(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &stream_cfg); +#endif + +#if defined(BONE_SENSOR_TDM) + tdm_stream_open(); + +#if defined(AF_ADC_I2S_SYNC) + af_codec_bt_trigger_config(true, bt_sco_bt_trigger_callback); +#endif +#endif + +#if defined(ANC_NOISE_TRACKER) + app_audio_mempool_get_buff( + (uint8_t **)&anc_buf, + speech_get_frame_size( + speech_codec_get_sample_rate(), + ANC_NOISE_TRACKER_CHANNEL_NUM, + SPEECH_SCO_FRAME_MS) * sizeof(int16_t)); + noise_tracker_init(nt_demo_words_cb, ANC_NOISE_TRACKER_CHANNEL_NUM, -20); +#endif + + // Must call this function before af_stream_start + // Get all free app audio buffer except SCO_BTPCM used(2k) + voicebtpcm_pcm_audio_init(speech_sco_get_sample_rate(), speech_codec_get_sample_rate()); + + /* + TRACE_AUD_STREAM_I("[SCO_PLAYER] start codec %d", FAST_TICKS_TO_US(hal_fast_sys_timer_get())); +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + af_stream_start(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK); +#endif + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + */ + +#ifdef SPEECH_SIDETONE + hal_codec_sidetone_enable(); +#endif + +#ifdef _SCO_BTPCM_CHANNEL_ + stream_cfg.bits = AUD_BITS_16; + stream_cfg.sample_rate = speech_sco_get_sample_rate(); + stream_cfg.channel_num = AUD_CHANNEL_NUM_1; + // stream_cfg.data_size = BT_AUDIO_SCO_BUFF_SIZE * stream_cfg.channel_num; + + if (bt_sco_codec_is_msbc()) + { + stream_cfg.data_size = speech_get_af_buffer_size(stream_cfg.sample_rate, stream_cfg.channel_num, SPEECH_SCO_FRAME_MS)/2; + } + else + { + stream_cfg.data_size = speech_get_af_buffer_size(stream_cfg.sample_rate, stream_cfg.channel_num, SPEECH_SCO_FRAME_MS); + } + + // btpcm:rx + stream_cfg.device = AUD_STREAM_USE_BT_PCM; + stream_cfg.handler = bt_sco_btpcm_capture_data; + app_audio_mempool_get_buff(&bt_audio_buff, stream_cfg.data_size); + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(bt_audio_buff); + + TRACE_AUD_STREAM_I("[SCO_PLAYER] sco btpcm sample_rate:%d, data_size:%d",stream_cfg.sample_rate,stream_cfg.data_size); + +#if defined(SCO_DMA_SNAPSHOT) + sco_btpcm_mute_flag=0; + sco_disconnect_mute_flag=0; + + capture_buf_btpcm=stream_cfg.data_ptr; + capture_size_btpcm=stream_cfg.data_size; +#ifdef TX_RX_PCM_MASK + capture_size_btpcm_copy=stream_cfg.data_size/4;//only need ping or pang; + app_audio_mempool_get_buff(&capture_buf_btpcm_copy, capture_size_btpcm_copy); +#endif +#endif + af_stream_open(AUD_STREAM_ID_1, AUD_STREAM_CAPTURE, &stream_cfg); + + // btpcm:tx + stream_cfg.device = AUD_STREAM_USE_BT_PCM; + stream_cfg.handler = bt_sco_btpcm_playback_data; + app_audio_mempool_get_buff(&bt_audio_buff, stream_cfg.data_size); + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(bt_audio_buff); + +#if defined(SCO_DMA_SNAPSHOT) + playback_buf_btpcm=stream_cfg.data_ptr; + playback_size_btpcm=stream_cfg.data_size; +#ifdef TX_RX_PCM_MASK + playback_size_btpcm_copy=stream_cfg.data_size/4; //only need ping or pang; + app_audio_mempool_get_buff(&playback_buf_btpcm_copy, playback_size_btpcm_copy); +#endif + //only need ping or pang; + app_audio_mempool_get_buff(&playback_buf_btpcm_cache, stream_cfg.data_size/2); +#endif + + af_stream_open(AUD_STREAM_ID_1, AUD_STREAM_PLAYBACK, &stream_cfg); + +#if !(defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE)) + af_codec_tune(AUD_STREAM_NUM, 0); +#endif + + TRACE_AUD_STREAM_I("[SCO_PLAYER] start btpcm %d", FAST_TICKS_TO_US(hal_fast_sys_timer_get())); + af_stream_start(AUD_STREAM_ID_1, AUD_STREAM_PLAYBACK); + af_stream_start(AUD_STREAM_ID_1, AUD_STREAM_CAPTURE); +#if defined(SCO_DMA_SNAPSHOT) + af_stream_dma_tc_irq_enable(AUD_STREAM_ID_1, AUD_STREAM_CAPTURE); + +#ifdef PLAYBACK_USE_I2S + af_i2s_sync_config(AUD_STREAM_PLAYBACK, AF_I2S_SYNC_TYPE_BT, true); +#else + af_codec_sync_config(AUD_STREAM_PLAYBACK, AF_CODEC_SYNC_TYPE_BT, true); +#endif + af_codec_sync_config(AUD_STREAM_CAPTURE, AF_CODEC_SYNC_TYPE_BT, true); + + btdrv_disable_playback_triggler(); + app_bt_stream_sco_trigger_btpcm_start(); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); +#endif + + is_codec_stream_started = false; + +#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) || defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || defined(CHIP_BEST2001) +#if defined(CVSD_BYPASS) + btdrv_cvsd_bypass_enable(bt_sco_codec_is_msbc()); +#endif +#if !defined(SCO_DMA_SNAPSHOT) + btdrv_pcm_enable(); +#endif +#endif + +#endif + +#ifdef FPGA + app_bt_stream_volumeset(stream_local_volume); + //btdrv_set_bt_pcm_en(1); +#endif + app_bt_stream_trigger_checker_start(); + TRACE_AUD_STREAM_I("[SCO_PLAYER] on"); + } + else + { +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + bool isToClearActiveMedia= audio_prompt_clear_pending_stream(PENDING_TO_STOP_SCO_STREAMING); + if (isToClearActiveMedia) + { + bt_media_clear_media_type(BT_STREAM_VOICE, BT_DEVICE_ID_1); + } +#endif + app_bt_stream_trigger_checker_stop(); +#if defined(SCO_DMA_SNAPSHOT) +#ifdef TX_RX_PCM_MASK + playback_buf_btpcm_copy=NULL; + capture_buf_btpcm_copy=NULL; + playback_size_btpcm_copy=0; + capture_size_btpcm_copy=0; +#endif +#endif + +#ifdef __THIRDPARTY + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO2,THIRDPARTY_MIC_CLOSE); +#endif +#if defined(SCO_DMA_SNAPSHOT) + app_bt_stream_sco_trigger_codecpcm_stop(); +#endif + af_stream_dma_tc_irq_disable(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_codec_set_playback_post_handler(NULL); + + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); +#if defined(AUDIO_ANC_FB_MC_SCO) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + af_stream_stop(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK); +#endif + is_codec_stream_started = false; + +#if defined(BONE_SENSOR_TDM) + tdm_stream_stop(); +#endif + +#if !(defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE)) + af_codec_tune(AUD_STREAM_NUM, 0); +#endif + +#ifdef _SCO_BTPCM_CHANNEL_ + af_stream_stop(AUD_STREAM_ID_1, AUD_STREAM_CAPTURE); + af_stream_stop(AUD_STREAM_ID_1, AUD_STREAM_PLAYBACK); + + af_stream_close(AUD_STREAM_ID_1, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_1, AUD_STREAM_PLAYBACK); +#endif +#ifdef TX_RX_PCM_MASK + if (btdrv_is_pcm_mask_enable()==1 && bt_drv_reg_op_pcm_get()) + { + bt_drv_reg_op_pcm_set(0); + TRACE_AUD_STREAM_I("[SCO_PLAYER] PCM UNMASK"); + } +#endif +#if defined(PCM_FAST_MODE) + btdrv_open_pcm_fast_mode_disable(); +#endif + +#if defined(HW_DC_FILTER_WITH_IIR) + hw_filter_codec_iir_destroy(hw_filter_codec_iir_st); +#endif + + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); +#if defined(AUDIO_ANC_FB_MC_SCO) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + af_stream_close(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK); +#endif + +#if defined(BONE_SENSOR_TDM) + tdm_stream_close(); +#endif + +#ifdef SPEECH_SIDETONE + hal_codec_sidetone_disable(); +#endif + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_SCO_RESAMPLE) + app_capture_resample_close(sco_capture_resample); + sco_capture_resample = NULL; + app_capture_resample_close(sco_playback_resample); + sco_playback_resample = NULL; +#endif + +#if defined(__AUDIO_RESAMPLE__) && defined(NO_SCO_RESAMPLE) +#ifndef CHIP_BEST1000 + // When __AUDIO_RESAMPLE__ is defined, + // resample is off by default on best1000, and on by default on other platforms + hal_cmu_audio_resample_enable(); +#endif +#endif + +#ifdef PLAYBACK_USE_I2S + hal_cmu_audio_resample_enable(); +#endif + + bt_sco_mode = 0; + +#ifdef __BT_ANC__ + bt_anc_sco_dec_buf = NULL; + //damic_deinit(); + //app_cap_thread_stop(); +#endif + voicebtpcm_pcm_audio_deinit(); + +#if defined(BONE_SENSOR_TDM) + lis25ba_deinit(); +#endif + +#ifndef FPGA +#ifdef BT_XTAL_SYNC + bt_term_xtal_sync(false); +#ifndef BT_XTAL_SYNC_NO_RESET + bt_term_xtal_sync_default(); +#endif +#endif +#endif +#if defined(HFP_1_6_ENABLE) + TRACE(1,"clear sco tx fifo codec:%d",bt_sco_player_code_type); + bt_drv_reg_op_sco_txfifo_reset(bt_sco_player_code_type); + bt_sco_player_code_type = BTIF_HF_SCO_CODEC_NONE; +#else + bt_drv_reg_op_sco_txfifo_reset(1); +#endif + +#if defined(ANC_WNR_ENABLED) + if (app_anc_work_status()) { + anc_wnr_close(); + anc_release_gain(); + anc_wnr_open(ANC_WNR_OPEN_MODE_STANDALONE); + } +#endif + +#ifdef __IAG_BLE_INCLUDE__ + app_ble_force_switch_adv(BLE_SWITCH_USER_SCO, true); +#endif + + TRACE_AUD_STREAM_I("[SCO_PLAYER] off"); + app_overlay_unloadall(); + app_sysfreq_req(APP_SYSFREQ_USER_BT_SCO, APP_SYSFREQ_32K); + af_set_priority(AF_USER_SCO, osPriorityAboveNormal); + + //bt_syncerr set to default(0x07) +// BTDIGITAL_REG_SET_FIELD(REG_BTCORE_BASE_ADDR, 0x0f, 0, 0x07); +#ifdef __THIRDPARTY + //app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_START); + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO3,THIRDPARTY_START); + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_KWS,THIRDPARTY_CALL_STOP); +#endif +#if defined(IBRT) + app_ibrt_if_exec_sleep_hook_blocker_clr(APP_IBRT_IF_SLEEP_HOOK_BLOCKER_HFP_SCO); + app_ibrt_ui_rssi_reset(); +#endif + } + + isRun=on; + return 0; +} + +#ifdef AUDIO_LINEIN +#include "app_status_ind.h" +//player channel should <= capture channel number +//player must be 2 channel +#define LINEIN_PLAYER_CHANNEL (2) +#ifdef __AUDIO_OUTPUT_MONO_MODE__ +#define LINEIN_CAPTURE_CHANNEL (1) +#else +#define LINEIN_CAPTURE_CHANNEL (2) +#endif + +#if (LINEIN_CAPTURE_CHANNEL == 1) +#define LINEIN_PLAYER_BUFFER_SIZE (1024*LINEIN_PLAYER_CHANNEL) +#define LINEIN_CAPTURE_BUFFER_SIZE (LINEIN_PLAYER_BUFFER_SIZE/2) +#elif (LINEIN_CAPTURE_CHANNEL == 2) +#define LINEIN_PLAYER_BUFFER_SIZE (1024*LINEIN_PLAYER_CHANNEL) +#define LINEIN_CAPTURE_BUFFER_SIZE (LINEIN_PLAYER_BUFFER_SIZE) +#endif + +int8_t app_linein_buffer_is_empty(void) +{ + if (app_audio_pcmbuff_length()){ + return 0; + }else{ + return 1; + } +} + +uint32_t app_linein_pcm_come(uint8_t * pcm_buf, uint32_t len) +{ + app_audio_pcmbuff_put(pcm_buf, len); + + return len; +} + +uint32_t app_linein_need_pcm_data(uint8_t* pcm_buf, uint32_t len) +{ +#if (LINEIN_CAPTURE_CHANNEL == 1) + app_audio_pcmbuff_get((uint8_t *)app_linein_play_cache, len/2); + app_play_audio_lineinmode_more_data((uint8_t *)app_linein_play_cache,len/2); + app_bt_stream_copy_track_one_to_two_16bits((int16_t *)pcm_buf, app_linein_play_cache, len/2/2); +#elif (LINEIN_CAPTURE_CHANNEL == 2) + app_audio_pcmbuff_get((uint8_t *)pcm_buf, len); + app_play_audio_lineinmode_more_data((uint8_t *)pcm_buf, len); +#endif + +#if defined(__AUDIO_OUTPUT_MONO_MODE__) + merge_stereo_to_mono_16bits((int16_t *)buf, (int16_t *)pcm_buf, len/2); +#endif + +#ifdef ANC_APP + bt_audio_updata_eq_for_anc(app_anc_work_status()); +#else + bt_audio_updata_eq(app_audio_get_eq()); +#endif + + audio_process_run(pcm_buf, len); + + return len; +} + +int app_play_linein_onoff(bool onoff) +{ + static bool isRun = false; + uint8_t *linein_audio_cap_buff = 0; + uint8_t *linein_audio_play_buff = 0; + uint8_t *linein_audio_loop_buf = NULL; + struct AF_STREAM_CONFIG_T stream_cfg; + + uint8_t POSSIBLY_UNUSED *bt_eq_buff = NULL; + uint32_t POSSIBLY_UNUSED eq_buff_size; + uint8_t POSSIBLY_UNUSED play_samp_size; + + TRACE_AUD_STREAM_I("[LINEIN_PLAYER] work:%d op:%d", isRun, onoff); + + if (isRun == onoff) + return 0; + + if (onoff){ + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_104M); + app_overlay_select(APP_OVERLAY_A2DP); + app_audio_mempool_init(); + app_audio_mempool_get_buff(&linein_audio_cap_buff, LINEIN_CAPTURE_BUFFER_SIZE); + app_audio_mempool_get_buff(&linein_audio_play_buff, LINEIN_PLAYER_BUFFER_SIZE); + app_audio_mempool_get_buff(&linein_audio_loop_buf, LINEIN_PLAYER_BUFFER_SIZE<<2); + app_audio_pcmbuff_init(linein_audio_loop_buf, LINEIN_PLAYER_BUFFER_SIZE<<2); + +#if (LINEIN_CAPTURE_CHANNEL == 1) + app_audio_mempool_get_buff((uint8_t **)&app_linein_play_cache, LINEIN_PLAYER_BUFFER_SIZE/2/2); + app_play_audio_lineinmode_init(LINEIN_CAPTURE_CHANNEL, LINEIN_PLAYER_BUFFER_SIZE/2/2); +#elif (LINEIN_CAPTURE_CHANNEL == 2) + app_play_audio_lineinmode_init(LINEIN_CAPTURE_CHANNEL, LINEIN_PLAYER_BUFFER_SIZE/2); +#endif + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = (enum AUD_CHANNEL_NUM_T)LINEIN_PLAYER_CHANNEL; +#if defined(__AUDIO_RESAMPLE__) + stream_cfg.sample_rate = AUD_SAMPRATE_50781; +#else + stream_cfg.sample_rate = AUD_SAMPRATE_44100; +#endif +#if FPGA==0 + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; +#else + stream_cfg.device = AUD_STREAM_USE_EXT_CODEC; +#endif + stream_cfg.vol = stream_linein_volume; + TRACE_AUD_STREAM_I("[LINEIN_PLAYER] vol = %d",stream_linein_volume); + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.handler = app_linein_need_pcm_data; + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(linein_audio_play_buff); + stream_cfg.data_size = LINEIN_PLAYER_BUFFER_SIZE; + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + sample_size_play_bt=stream_cfg.bits; + sample_rate_play_bt=stream_cfg.sample_rate; + data_size_play_bt=stream_cfg.data_size; + playback_buf_bt=stream_cfg.data_ptr; + playback_size_bt=stream_cfg.data_size; + if(sample_rate_play_bt==AUD_SAMPRATE_96000) + { + playback_samplerate_ratio_bt=4; + } + else + { + playback_samplerate_ratio_bt=8; + } + playback_ch_num_bt=stream_cfg.channel_num; + mid_p_8_old_l=0; + mid_p_8_old_r=0; +#endif + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + +#if defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) + eq_buff_size = stream_cfg.data_size*2; +#elif defined(__HW_FIR_EQ_PROCESS__) && !defined(__HW_IIR_EQ_PROCESS__) + + play_samp_size = (stream_cfg.bits <= AUD_BITS_16) ? 2 : 4; +#if defined(CHIP_BEST2000) + eq_buff_size = stream_cfg.data_size * sizeof(int32_t) / play_samp_size; +#elif defined(CHIP_BEST1000) + eq_buff_size = stream_cfg.data_size * sizeof(int16_t) / play_samp_size; +#elif defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) + eq_buff_size = stream_cfg.data_size; +#endif + +#elif !defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) + eq_buff_size = stream_cfg.data_size; +#else + eq_buff_size = 0; + bt_eq_buff = NULL; +#endif + + if(eq_buff_size>0) + { + app_audio_mempool_get_buff(&bt_eq_buff, eq_buff_size); + } + +#if defined(IBRT) + enum AUD_CHANNEL_NUM_T sw_ch_num = AUD_CHANNEL_NUM_1; +#else + enum AUD_CHANNEL_NUM_T sw_ch_num = stream_cfg.channel_num; +#endif + + audio_process_open(stream_cfg.sample_rate, stream_cfg.bits, sw_ch_num, stream_cfg.channel_num, stream_cfg.data_size/stream_cfg.channel_num/(stream_cfg.bits <= AUD_BITS_16 ? 2 : 4)/2, bt_eq_buff, eq_buff_size); + +#ifdef __SW_IIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_SW_IIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_SW_IIR,0)); +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_HW_FIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_HW_FIR,0)); +#endif + +#ifdef __HW_DAC_IIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_HW_DAC_IIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_HW_DAC_IIR,0)); +#endif + +#ifdef __HW_IIR_EQ_PROCESS__ + bt_audio_set_eq(AUDIO_EQ_TYPE_HW_IIR,bt_audio_get_eq_index(AUDIO_EQ_TYPE_HW_IIR,0)); +#endif + +#ifdef ANC_APP + anc_status_record = 0xff; +#endif + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + uint8_t *bt_audio_buff = NULL; + stream_cfg.bits = sample_size_play_bt; + stream_cfg.channel_num = playback_ch_num_bt; + stream_cfg.sample_rate = sample_rate_play_bt; + stream_cfg.device = AUD_STREAM_USE_MC; + stream_cfg.vol = 0; + stream_cfg.handler = audio_mc_data_playback_a2dp; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + + app_audio_mempool_get_buff(&bt_audio_buff, data_size_play_bt*playback_samplerate_ratio_bt); + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(bt_audio_buff); + stream_cfg.data_size = data_size_play_bt*playback_samplerate_ratio_bt; + + playback_buf_mc=stream_cfg.data_ptr; + playback_size_mc=stream_cfg.data_size; + + anc_mc_run_init(hal_codec_anc_convert_rate(sample_rate_play_bt)); + + memset(delay_buf_bt,0,sizeof(delay_buf_bt)); + + af_stream_open(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &stream_cfg); + //ASSERT(ret == 0, "af_stream_open playback failed: %d", ret); +#endif + + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + +#if defined(AUDIO_ANC_FB_MC) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + af_stream_start(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK); +#endif + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + stream_cfg.bits = AUD_BITS_16; +#if defined(__AUDIO_RESAMPLE__) + stream_cfg.sample_rate = AUD_SAMPRATE_50781; +#else + stream_cfg.sample_rate = AUD_SAMPRATE_44100; +#endif +#if FPGA==0 + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; +#else + stream_cfg.device = AUD_STREAM_USE_EXT_CODEC; +#endif + stream_cfg.io_path = AUD_INPUT_PATH_LINEIN; + stream_cfg.channel_num = (enum AUD_CHANNEL_NUM_T)LINEIN_CAPTURE_CHANNEL; + stream_cfg.channel_map = (enum AUD_CHANNEL_MAP_T)hal_codec_get_input_path_cfg(stream_cfg.io_path); + stream_cfg.handler = app_linein_pcm_come; + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(linein_audio_cap_buff); + stream_cfg.data_size = LINEIN_CAPTURE_BUFFER_SIZE; + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + }else { + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + + audio_process_close(); + + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + + app_overlay_unloadall(); + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_32K); + } + + isRun = onoff; + TRACE_AUD_STREAM_I("[LINEIN_PLAYER] end!\n"); + return 0; +} +#endif + +int app_bt_stream_open(APP_AUDIO_STATUS* status) +{ + int nRet = -1; + uint16_t player = status->id; + APP_AUDIO_STATUS next_status; + enum APP_SYSFREQ_FREQ_T freq = (enum APP_SYSFREQ_FREQ_T)status->freq; + + TRACE_AUD_STREAM_I("[STRM_PLAYER][OPEN] prev:0x%x%s freq:%d", gStreamplayer, player2str(gStreamplayer), freq); + TRACE_AUD_STREAM_I("[STRM_PLAYER][OPEN] cur:0x%x%s freq:%d", player, player2str(player), freq); + + APP_AUDIO_STATUS streamToClose; + + if (gStreamplayer != APP_BT_STREAM_INVALID) + { +#if !ISOLATED_AUDIO_STREAM_ENABLED + TRACE_AUD_STREAM_I("[STRM_PLAYER][OPEN] close 0x%x%s prev opening", gStreamplayer, player2str(gStreamplayer)); + nRet = app_bt_stream_close(gStreamplayer); + if (nRet) + { + return -1; + } + else + { + streamToClose.id = gStreamplayer; + app_audio_list_rmv_callback(&streamToClose, &next_status, APP_BT_SETTING_Q_POS_TAIL, false); + } +#else + if (gStreamplayer & player) + { + TRACE_AUD_STREAM_I("[STRM_PLAYER][OPEN] 0x%x%s has opened", player, player2str(player)); + return -1; + } + + if (player >= APP_BT_STREAM_BORDER_INDEX) + { + if (APP_BT_INPUT_STREAM_INDEX(gStreamplayer) > 0) + { + TRACE_AUD_STREAM_I("[STRM_PLAYER][OPEN] close 0x%x%s prev opening", gStreamplayer, player2str(gStreamplayer)); + } + } + else + { + if (APP_BT_OUTPUT_STREAM_INDEX(gStreamplayer) > 0) + { + TRACE_AUD_STREAM_I("[STRM_PLAYER][OPEN] close 0x%x%s prev opening", gStreamplayer, player2str(gStreamplayer)); + uint16_t player2close = APP_BT_OUTPUT_STREAM_INDEX(gStreamplayer); + nRet = app_bt_stream_close(player2close); + if (nRet) + { + return -1; + } + else + { + streamToClose.id = player2close; + app_audio_list_rmv_callback(&streamToClose, &next_status, APP_BT_SETTING_Q_POS_TAIL, false); + } + } + } +#endif + } + + switch (player) + { + case APP_BT_STREAM_HFP_PCM: + case APP_BT_STREAM_HFP_CVSD: + case APP_BT_STREAM_HFP_VENDOR: + nRet = bt_sco_player(true, freq); + break; + case APP_BT_STREAM_A2DP_SBC: + case APP_BT_STREAM_A2DP_AAC: + case APP_BT_STREAM_A2DP_VENDOR: + nRet = bt_sbc_player(PLAYER_OPER_START, freq); + break; +#ifdef __FACTORY_MODE_SUPPORT__ + case APP_FACTORYMODE_AUDIO_LOOP: + nRet = app_factorymode_audioloop(true, freq); + break; +#endif +#ifdef MEDIA_PLAYER_SUPPORT + case APP_PLAY_BACK_AUDIO: + nRet = app_play_audio_onoff(true, status); + break; +#endif + +#ifdef RB_CODEC + case APP_BT_STREAM_RBCODEC: + nRet = app_rbplay_audio_onoff(true, 0); + break; +#endif + +#ifdef AUDIO_LINEIN + case APP_PLAY_LINEIN_AUDIO: + nRet = app_play_linein_onoff(true); + break; +#endif + +#if defined(APP_LINEIN_A2DP_SOURCE) + case APP_A2DP_SOURCE_LINEIN_AUDIO: + nRet = app_a2dp_source_linein_on(true); + break; +#endif +#if defined(APP_I2S_A2DP_SOURCE) + case APP_A2DP_SOURCE_I2S_AUDIO: + nRet = app_a2dp_source_I2S_onoff(true); + break; +#endif + +#ifdef VOICE_DATAPATH + case APP_BT_STREAM_VOICEPATH: + nRet = app_voicepath_start_audio_stream(); + break; +#endif +#ifdef __AI_VOICE__ + case APP_BT_STREAM_AI_VOICE: + nRet = app_ai_voice_start_mic_stream(); + break; +#endif +#ifdef __THIRDPARTY + case APP_BT_STREAM_THIRDPARTY_VOICE: + nRet = app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_KWS, THIRDPARTY_MIC_OPEN); + break; +#endif + default: + nRet = -1; + break; + } + + if (!nRet) + { + gStreamplayer |= player; + TRACE_AUD_STREAM_I("[STRM_PLAYER][OPEN] updated to 0x%x%s", gStreamplayer, player2str(gStreamplayer)); + } + return nRet; +} + +int app_bt_stream_close(uint16_t player) +{ + int nRet = -1; + TRACE_AUD_STREAM_I("[STRM_PLAYER][CLOSE] gStreamplayer: 0x%x%s", gStreamplayer, player2str(gStreamplayer)); + TRACE_AUD_STREAM_I("[STRM_PLAYER][CLOSE] player:0x%x%s", gStreamplayer, player2str(gStreamplayer)); + + if ((gStreamplayer & player) != player) + { + return -1; + } + + switch (player) + { + case APP_BT_STREAM_HFP_PCM: + case APP_BT_STREAM_HFP_CVSD: + case APP_BT_STREAM_HFP_VENDOR: + nRet = bt_sco_player(false, APP_SYSFREQ_32K); + break; + case APP_BT_STREAM_A2DP_SBC: + case APP_BT_STREAM_A2DP_AAC: + case APP_BT_STREAM_A2DP_VENDOR: + nRet = bt_sbc_player(PLAYER_OPER_STOP, APP_SYSFREQ_32K); + break; +#ifdef __FACTORY_MODE_SUPPORT__ + case APP_FACTORYMODE_AUDIO_LOOP: + nRet = app_factorymode_audioloop(false, APP_SYSFREQ_32K); + break; +#endif +#ifdef MEDIA_PLAYER_SUPPORT + case APP_PLAY_BACK_AUDIO: + nRet = app_play_audio_onoff(false, NULL); + break; +#endif +#ifdef RB_CODEC + case APP_BT_STREAM_RBCODEC: + nRet = app_rbplay_audio_onoff(false, 0); + break; +#endif + +#ifdef AUDIO_LINEIN + case APP_PLAY_LINEIN_AUDIO: + nRet = app_play_linein_onoff(false); + break; +#endif + +#if defined(APP_LINEIN_A2DP_SOURCE) + case APP_A2DP_SOURCE_LINEIN_AUDIO: + nRet = app_a2dp_source_linein_on(false); + break; +#endif +#if defined(APP_I2S_A2DP_SOURCE) + case APP_A2DP_SOURCE_I2S_AUDIO: + nRet = app_a2dp_source_I2S_onoff(false); + break; +#endif + +#ifdef VOICE_DATAPATH + case APP_BT_STREAM_VOICEPATH: + nRet = app_voicepath_stop_audio_stream(); + break; +#endif +#ifdef __AI_VOICE__ + case APP_BT_STREAM_AI_VOICE: + nRet = app_ai_voice_stop_mic_stream(); + break; +#endif +#ifdef __THIRDPARTY + case APP_BT_STREAM_THIRDPARTY_VOICE: + nRet = app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_KWS, THIRDPARTY_MIC_CLOSE); + break; +#endif + default: + nRet = -1; + break; + } + if (!nRet) + { + gStreamplayer &= (~player); + TRACE_AUD_STREAM_I("[STRM_PLAYER][CLOSE] updated to 0x%x%s", gStreamplayer, player2str(gStreamplayer)); + } + return nRet; +} + +int app_bt_stream_setup(uint16_t player, uint8_t status) +{ + int nRet = -1; + + TRACE_AUD_STREAM_I("[STRM_PLAYER][SETUP] prev:%d%s sample:%d", gStreamplayer, player2str(gStreamplayer), status); + TRACE_AUD_STREAM_I("[STRM_PLAYER][SETUP] cur:%d%s sample:%d", player, player2str(player), status); + + switch (player) + { + case APP_BT_STREAM_HFP_PCM: + case APP_BT_STREAM_HFP_CVSD: + case APP_BT_STREAM_HFP_VENDOR: + break; + case APP_BT_STREAM_A2DP_SBC: + case APP_BT_STREAM_A2DP_AAC: + case APP_BT_STREAM_A2DP_VENDOR: + bt_sbc_player_setup(status); + break; + default: + nRet = -1; + break; + } + + return nRet; +} + +int app_bt_stream_restart(APP_AUDIO_STATUS* status) +{ + int nRet = -1; + uint16_t player = status->id; + enum APP_SYSFREQ_FREQ_T freq = (enum APP_SYSFREQ_FREQ_T)status->freq; + + TRACE_AUD_STREAM_I("[STRM_PLAYER][RESTART] prev:%d%s freq:%d", gStreamplayer, player2str(gStreamplayer), freq); + TRACE_AUD_STREAM_I("[STRM_PLAYER][RESTART] cur:%d%s freq:%d", player, player2str(player), freq); + + if ((gStreamplayer & player) != player) + { + return -1; + } + + switch (player) + { + case APP_BT_STREAM_HFP_PCM: + case APP_BT_STREAM_HFP_CVSD: + case APP_BT_STREAM_HFP_VENDOR: + nRet = bt_sco_player(false, freq); + nRet = bt_sco_player(true, freq); + break; + case APP_BT_STREAM_A2DP_SBC: + case APP_BT_STREAM_A2DP_AAC: + case APP_BT_STREAM_A2DP_VENDOR: +#if defined(IBRT) + ibrt_a2dp_status_t a2dp_status; + a2dp_ibrt_sync_get_status(&a2dp_status); + TRACE_AUD_STREAM_I("[STRM_PLAYER][RESTART] state:%d", a2dp_status.state); + if (a2dp_status.state == BTIF_AVDTP_STRM_STATE_STREAMING){ + if (app_audio_manager_a2dp_is_active(BT_DEVICE_ID_1)){ + TRACE_AUD_STREAM_I("[STRM_PLAYER][RESTART] resume"); + nRet = bt_sbc_player(PLAYER_OPER_STOP, freq); + nRet = bt_sbc_player(PLAYER_OPER_START, freq); + }else{ + if (app_ibrt_ui_is_profile_exchanged()){ + TRACE_AUD_STREAM_I("[STRM_PLAYER][RESTART] force_audio_retrigger"); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,BT_STREAM_SBC, BT_DEVICE_ID_1,MAX_RECORD_NUM); + app_ibrt_if_force_audio_retrigger(); + } + } + } +#elif defined(__BT_ONE_BRING_TWO__) + if (btif_me_get_activeCons()>1) + { + enum APP_SYSFREQ_FREQ_T sysfreq; + +#ifdef A2DP_CP_ACCEL + sysfreq = APP_SYSFREQ_26M; +#else + sysfreq = APP_SYSFREQ_104M; +#endif + app_sysfreq_req(APP_SYSFREQ_USER_BT_A2DP, sysfreq); + bt_media_volume_ptr_update_by_mediatype(BT_STREAM_SBC); + app_bt_stream_volumeset(btdevice_volume_p->a2dp_vol); + } +#endif + break; +#ifdef __FACTORY_MODE_SUPPORT__ + case APP_FACTORYMODE_AUDIO_LOOP: + break; +#endif +#ifdef MEDIA_PLAYER_SUPPORT + case APP_PLAY_BACK_AUDIO: + break; +#endif + default: + nRet = -1; + break; + } + + return nRet; +} + +void app_bt_stream_volumeup(void) +{ +#if defined AUDIO_LINEIN + if(app_bt_stream_isrun(APP_PLAY_LINEIN_AUDIO)) + { + stream_linein_volume ++; + if (stream_linein_volume > TGT_VOLUME_LEVEL_15) + stream_linein_volume = TGT_VOLUME_LEVEL_15; + app_bt_stream_volumeset(stream_linein_volume); + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][UP] set linein volume %d\n", stream_linein_volume); + }else +#endif + { + if (app_bt_stream_isrun(APP_BT_STREAM_HFP_PCM)) + { + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][UP] hfp volume"); + + int8_t updatedVol = btdevice_volume_p->hfp_vol; + updatedVol++; + if (updatedVol > TGT_VOLUME_LEVEL_15) + { + updatedVol = TGT_VOLUME_LEVEL_15; + } + uint32_t lock = nv_record_pre_write_operation(); + btdevice_volume_p->hfp_vol = updatedVol; + nv_record_post_write_operation(lock); + current_btdevice_volume.hfp_vol=updatedVol; + if (updatedVol < TGT_VOLUME_LEVEL_15) + { + app_bt_stream_volumeset(updatedVol); + } + if (btdevice_volume_p->hfp_vol == TGT_VOLUME_LEVEL_15) + { +#ifdef MEDIA_PLAYER_SUPPORT + media_PlayAudio(AUD_ID_BT_WARNING,0); +#endif + } + + } + else if ((app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC)) || + (app_bt_stream_isrun(APP_BT_STREAM_INVALID))) + { + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][UP] a2dp volume"); + int8_t updatedVol = btdevice_volume_p->a2dp_vol; + updatedVol++; + if (updatedVol > TGT_VOLUME_LEVEL_15) + { + updatedVol = TGT_VOLUME_LEVEL_15; + } + uint32_t lock = nv_record_pre_write_operation(); + btdevice_volume_p->a2dp_vol = updatedVol; + nv_record_post_write_operation(lock); + current_btdevice_volume.a2dp_vol=updatedVol; + if (updatedVol < TGT_VOLUME_LEVEL_15) + { + app_bt_stream_volumeset(updatedVol); + } + if (btdevice_volume_p->a2dp_vol == TGT_VOLUME_LEVEL_15) + { +#ifdef MEDIA_PLAYER_SUPPORT + media_PlayAudio(AUD_ID_BT_WARNING,0); +#endif + } + } + + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][UP] a2dp: %d", btdevice_volume_p->a2dp_vol); + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][UP] hfp: %d", btdevice_volume_p->hfp_vol); + } +#ifndef FPGA + nv_record_touch_cause_flush(); +#endif +} + +void app_bt_set_volume(uint16_t type,uint8_t level) +{ + if ((type&APP_BT_STREAM_HFP_PCM) && app_bt_stream_isrun(APP_BT_STREAM_HFP_PCM)) { + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL] set hfp volume"); + if (level >= TGT_VOLUME_LEVEL_MUTE && level <= TGT_VOLUME_LEVEL_15) + { + uint32_t lock = nv_record_pre_write_operation(); + btdevice_volume_p->hfp_vol = level; + nv_record_post_write_operation(lock); + app_bt_stream_volumeset(btdevice_volume_p->hfp_vol); + } + if (btdevice_volume_p->hfp_vol == TGT_VOLUME_LEVEL_0) + { +#ifdef MEDIA_PLAYER_SUPPORT + media_PlayAudio(AUD_ID_BT_WARNING,0); +#endif + } + } + if ((type&APP_BT_STREAM_A2DP_SBC) && ((app_bt_stream_isrun(APP_BT_STREAM_INVALID)) || + (app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC)))) { + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL] set a2dp volume"); + if (level >= TGT_VOLUME_LEVEL_MUTE && level <= TGT_VOLUME_LEVEL_15) + { + uint32_t lock = nv_record_pre_write_operation(); + btdevice_volume_p->a2dp_vol = level; + nv_record_post_write_operation(lock); + app_bt_stream_volumeset(btdevice_volume_p->a2dp_vol); + } + if (btdevice_volume_p->a2dp_vol == TGT_VOLUME_LEVEL_MUTE) + { +#ifdef MEDIA_PLAYER_SUPPORT + media_PlayAudio(AUD_ID_BT_WARNING,0); +#endif + } + } + + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL] a2dp: %d", btdevice_volume_p->a2dp_vol); + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL] hfp: %d", btdevice_volume_p->hfp_vol); +#ifndef FPGA + nv_record_touch_cause_flush(); +#endif +} + +void app_bt_stream_volumedown(void) +{ +#if defined AUDIO_LINEIN + if(app_bt_stream_isrun(APP_PLAY_LINEIN_AUDIO)) + { + stream_linein_volume --; + if (stream_linein_volume < TGT_VOLUME_LEVEL_MUTE) + stream_linein_volume = TGT_VOLUME_LEVEL_MUTE; + app_bt_stream_volumeset(stream_linein_volume); + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][DONW] set linein volume %d\n", stream_linein_volume); + }else +#endif + { + if (app_bt_stream_isrun(APP_BT_STREAM_HFP_PCM)) { + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][DONW] set hfp volume"); + + int8_t updatedVol = btdevice_volume_p->hfp_vol; + updatedVol--; + if (updatedVol < TGT_VOLUME_LEVEL_0) + { + updatedVol = TGT_VOLUME_LEVEL_0; + } + + uint32_t lock = nv_record_pre_write_operation(); + btdevice_volume_p->hfp_vol = updatedVol; + nv_record_post_write_operation(lock); + current_btdevice_volume.hfp_vol=updatedVol; + app_bt_stream_volumeset(updatedVol); + if (btdevice_volume_p->hfp_vol == TGT_VOLUME_LEVEL_0) + { +#ifdef MEDIA_PLAYER_SUPPORT + media_PlayAudio(AUD_ID_BT_WARNING,0); +#endif + } + } else if ((app_bt_stream_isrun(APP_BT_STREAM_INVALID)) || + (app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC))) { + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][DONW] set a2dp volume"); + int8_t updatedVol = btdevice_volume_p->a2dp_vol; + updatedVol--; + if (updatedVol < TGT_VOLUME_LEVEL_MUTE) + { + updatedVol = TGT_VOLUME_LEVEL_MUTE; + } + + uint32_t lock = nv_record_pre_write_operation(); + btdevice_volume_p->a2dp_vol = updatedVol; + nv_record_post_write_operation(lock); + current_btdevice_volume.a2dp_vol=updatedVol; + app_bt_stream_volumeset(updatedVol); + if (btdevice_volume_p->a2dp_vol == TGT_VOLUME_LEVEL_MUTE) + { +#ifdef MEDIA_PLAYER_SUPPORT + media_PlayAudio(AUD_ID_BT_WARNING,0); +#endif + } + } + + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][DONW] a2dp: %d", btdevice_volume_p->a2dp_vol); + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][DONW] hfp: %d", btdevice_volume_p->hfp_vol); + } +#ifndef FPGA + nv_record_touch_cause_flush(); +#endif +} + +void app_bt_stream_volumeset_handler(int8_t vol) +{ + uint32_t ret; + struct AF_STREAM_CONFIG_T *stream_cfg = NULL; + ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg, false); + if (ret == 0) { + stream_cfg->vol = vol; + af_stream_setup(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, stream_cfg); + } +#if (defined(AUDIO_ANC_FB_MC)||defined(AUDIO_ANC_FB_MC_SCO)) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + ret = af_stream_get_cfg(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &stream_cfg, false); + if (ret == 0) { + stream_cfg->vol = vol; + af_stream_setup(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, stream_cfg); + } +#endif +} + +int app_bt_stream_volumeset(int8_t vol) +{ + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][SET] vol=%d", vol); + + if (vol > TGT_VOLUME_LEVEL_15) + vol = TGT_VOLUME_LEVEL_15; + if (vol < TGT_VOLUME_LEVEL_MUTE) + vol = TGT_VOLUME_LEVEL_MUTE; + + stream_local_volume = vol; +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + if ((!app_bt_stream_isrun(APP_PLAY_BACK_AUDIO)) && + (audio_prompt_is_allow_update_volume())) +#else + if (!app_bt_stream_isrun(APP_PLAY_BACK_AUDIO)) +#endif + { + app_bt_stream_volumeset_handler(vol); + } + return 0; +} + +int app_bt_stream_local_volume_get(void) +{ + return stream_local_volume; +} + +uint8_t app_bt_stream_a2dpvolume_get(void) +{ + // return btdevice_volume_p->a2dp_vol; + return current_btdevice_volume.a2dp_vol; +} + +uint8_t app_bt_stream_hfpvolume_get(void) +{ + //return btdevice_volume_p->hfp_vol; + return current_btdevice_volume.hfp_vol; + +} + +void app_bt_stream_a2dpvolume_reset(void) +{ + btdevice_volume_p->a2dp_vol = NVRAM_ENV_STREAM_VOLUME_A2DP_VOL_DEFAULT ; + current_btdevice_volume.a2dp_vol=NVRAM_ENV_STREAM_VOLUME_A2DP_VOL_DEFAULT; +} + +void app_bt_stream_hfpvolume_reset(void) +{ + btdevice_volume_p->hfp_vol = NVRAM_ENV_STREAM_VOLUME_HFP_VOL_DEFAULT; + current_btdevice_volume.hfp_vol=NVRAM_ENV_STREAM_VOLUME_HFP_VOL_DEFAULT; +} + +void app_bt_stream_volume_ptr_update(uint8_t *bdAddr) +{ + static struct btdevice_volume stream_volume = {NVRAM_ENV_STREAM_VOLUME_A2DP_VOL_DEFAULT,NVRAM_ENV_STREAM_VOLUME_HFP_VOL_DEFAULT}; + +#ifndef FPGA + nvrec_btdevicerecord *record = NULL; + + memset(¤t_btdevice_volume, 0, sizeof(btdevice_volume)); + + if (bdAddr && !nv_record_btdevicerecord_find((bt_bdaddr_t*)bdAddr,&record)) + { + btdevice_volume_p = &(record->device_vol); + DUMP8("0x%02x ", bdAddr, BTIF_BD_ADDR_SIZE); + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][UPDATE] a2dp_vol:%d hfp_vol:%d ptr:%p", btdevice_volume_p->a2dp_vol, btdevice_volume_p->hfp_vol,btdevice_volume_p); + } + else +#endif + { + btdevice_volume_p = &stream_volume; + TRACE_AUD_STREAM_I("[STRM_PLAYER][VOL][UPDATE] default"); + if (bdAddr){ + DUMP8("0x%02x ", bdAddr, BTIF_BD_ADDR_SIZE); + } + } + current_btdevice_volume.a2dp_vol=btdevice_volume_p->a2dp_vol; + current_btdevice_volume.hfp_vol=btdevice_volume_p->hfp_vol; + +} + +struct btdevice_volume * app_bt_stream_volume_get_ptr(void) +{ + return btdevice_volume_p; +} + +bool app_bt_stream_isrun(uint16_t player) +{ + if ((gStreamplayer & player) == player) + { + return true; + } + else + { + return false; + } +} + +int app_bt_stream_closeall() +{ + TRACE_AUD_STREAM_I("[STRM_PLAYER][CLOSEALL]"); + + bt_sco_player(false, APP_SYSFREQ_32K); + bt_sbc_player(PLAYER_OPER_STOP, APP_SYSFREQ_32K); + +#ifdef MEDIA_PLAYER_SUPPORT + app_play_audio_onoff(false, 0); +#endif +#ifdef RB_CODEC + app_rbplay_audio_onoff(false, 0); +#endif + +#ifdef VOICE_DATAPATH + app_voicepath_stop_audio_stream(); +#endif + + gStreamplayer = APP_BT_STREAM_INVALID; + + return 0; +} + +void app_bt_stream_copy_track_one_to_two_24bits(int32_t *dst_buf, int32_t *src_buf, uint32_t src_len) +{ + // Copy from tail so that it works even if dst_buf == src_buf + for (int i = (int)(src_len - 1); i >= 0; i--) + { + dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = src_buf[i]; + } +} + +void app_bt_stream_copy_track_one_to_two_16bits(int16_t *dst_buf, int16_t *src_buf, uint32_t src_len) +{ + // Copy from tail so that it works even if dst_buf == src_buf + for (int i = (int)(src_len - 1); i >= 0; i--) + { + dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = src_buf[i]; + } +} + +void app_bt_stream_copy_track_two_to_one_16bits(int16_t *dst_buf, int16_t *src_buf, uint32_t dst_len) +{ + for (uint32_t i = 0; i < dst_len; i++) + { + dst_buf[i] = src_buf[i*2]; + } +} + +void app_bt_stream_adaptive_frequency_adjusting(void) +{ +#if 0//(A2DP_DECODER_VER == 2) + if (app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC)){ + if (!a2dp_audio_sysfreq_boost_running()){ + a2dp_audio_sysfreq_boost_start(1); + } + } +#endif +} + +#ifdef PLAYBACK_FORCE_48K +static int app_force48k_resample_iter(uint8_t *buf, uint32_t len) +{ + uint8_t codec_type = bt_sbc_player_get_codec_type(); + uint32_t overlay_id = 0; + if(0){ +#if defined(A2DP_LHDC_ON) + }else if(codec_type == BTIF_AVDTP_CODEC_TYPE_LHDC){ + overlay_id = APP_OVERLAY_A2DP_LHDC; +#endif +#if defined(A2DP_AAC_ON) + }else if(codec_type == BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC){ + overlay_id = APP_OVERLAY_A2DP_AAC; +#endif + }else if(codec_type == BTIF_AVDTP_CODEC_TYPE_SBC){ + overlay_id = APP_OVERLAY_A2DP; + } + a2dp_audio_more_data(overlay_id, buf, len); + return 0; +} + +struct APP_RESAMPLE_T *app_force48k_resample_any_open(enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step) +{ + return app_playback_resample_any_open(chans, cb, iter_len, ratio_step); +} +#endif + +// ======================================================= +// APP RESAMPLE +// ======================================================= + +#ifndef MIX_MIC_DURING_MUSIC +#include "resample_coef.h" +#endif + +static APP_RESAMPLE_BUF_ALLOC_CALLBACK resamp_buf_alloc = app_audio_mempool_get_buff; + +static void memzero_int16(void *dst, uint32_t len) +{ + if (dst) + { + int16_t *dst16 = (int16_t *)dst; + int16_t *dst16_end = dst16 + len / 2; + + while (dst16 < dst16_end) + { + *dst16++ = 0; + } + } + else + { + TRACE_AUD_STREAM_I("WRN: receive null pointer"); + } +} + +struct APP_RESAMPLE_T *app_resample_open_with_preallocated_buf(enum AUD_STREAM_T stream, const struct RESAMPLE_COEF_T *coef, enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step, uint8_t* buf, uint32_t bufSize) +{ + TRACE_AUD_STREAM_I("[STRM_PLAYER][PROMPT_MIXER][OPEN]"); + struct APP_RESAMPLE_T *resamp; + struct RESAMPLE_CFG_T cfg; + enum RESAMPLE_STATUS_T status; + uint32_t size, resamp_size; + + resamp_size = audio_resample_ex_get_buffer_size(chans, AUD_BITS_16, coef->phase_coef_num); + + size = sizeof(struct APP_RESAMPLE_T); + size += ALIGN(iter_len, 4); + size += resamp_size; + + ASSERT(size < bufSize, "Pre-allocated buffer size %d is smaller than the needed size %d", + bufSize, size); + + resamp = (struct APP_RESAMPLE_T *)buf; + buf += sizeof(*resamp); + resamp->stream = stream; + resamp->cb = cb; + resamp->iter_buf = buf; + buf += ALIGN(iter_len, 4); + resamp->iter_len = iter_len; + resamp->offset = iter_len; + resamp->ratio_step = ratio_step; + + memset(&cfg, 0, sizeof(cfg)); + cfg.chans = chans; + cfg.bits = AUD_BITS_16; + cfg.ratio_step = ratio_step; + cfg.coef = coef; + cfg.buf = buf; + cfg.size = resamp_size; + + status = audio_resample_ex_open(&cfg, (RESAMPLE_ID *)&resamp->id); + ASSERT(status == RESAMPLE_STATUS_OK, "%s: Failed to open resample: %d", __func__, status); + +#ifdef CHIP_BEST1000 + hal_cmu_audio_resample_enable(); +#endif + + return resamp; +} + + +static struct APP_RESAMPLE_T *app_resample_open(enum AUD_STREAM_T stream, const struct RESAMPLE_COEF_T *coef, enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step) +{ + TRACE_AUD_STREAM_I("[STRM_PLAYER][RESAMPLE][OPEN] ratio: %d/1000", uint32_t(ratio_step * 1000)); + struct APP_RESAMPLE_T *resamp; + struct RESAMPLE_CFG_T cfg; + enum RESAMPLE_STATUS_T status; + uint32_t size, resamp_size; + uint8_t *buf; + + resamp_size = audio_resample_ex_get_buffer_size(chans, AUD_BITS_16, coef->phase_coef_num); + + size = sizeof(struct APP_RESAMPLE_T); + size += ALIGN(iter_len, 4); + size += resamp_size; + + resamp_buf_alloc(&buf, size); + + resamp = (struct APP_RESAMPLE_T *)buf; + buf += sizeof(*resamp); + resamp->stream = stream; + resamp->cb = cb; + resamp->iter_buf = buf; + buf += ALIGN(iter_len, 4); + resamp->iter_len = iter_len; + resamp->offset = iter_len; + resamp->ratio_step = ratio_step; + + memset(&cfg, 0, sizeof(cfg)); + cfg.chans = chans; + cfg.bits = AUD_BITS_16; + cfg.ratio_step = ratio_step; + cfg.coef = coef; + cfg.buf = buf; + cfg.size = resamp_size; + + status = audio_resample_ex_open(&cfg, (RESAMPLE_ID *)&resamp->id); + ASSERT(status == RESAMPLE_STATUS_OK, "%s: Failed to open resample: %d", __func__, status); + +#ifdef CHIP_BEST1000 + hal_cmu_audio_resample_enable(); +#endif + + return resamp; +} + +static int app_resample_close(struct APP_RESAMPLE_T *resamp) +{ +#ifdef CHIP_BEST1000 + hal_cmu_audio_resample_disable(); +#endif + + if (resamp) + { + audio_resample_ex_close((RESAMPLE_ID *)resamp->id); + } + + return 0; +} + +struct APP_RESAMPLE_T *app_playback_resample_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len) +{ + const struct RESAMPLE_COEF_T *coef = NULL; + + if (sample_rate == AUD_SAMPRATE_8000) + { + coef = &resample_coef_8k_to_8p4k; + } + else if (sample_rate == AUD_SAMPRATE_16000) + { + coef = &resample_coef_8k_to_8p4k; + } + else if (sample_rate == AUD_SAMPRATE_32000) + { + coef = &resample_coef_32k_to_50p7k; + } + else if (sample_rate == AUD_SAMPRATE_44100) + { + coef = &resample_coef_44p1k_to_50p7k; + } + else if (sample_rate == AUD_SAMPRATE_48000) + { + coef = &resample_coef_48k_to_50p7k; + } + else + { + ASSERT(false, "%s: Bad sample rate: %u", __func__, sample_rate); + } + + return app_resample_open(AUD_STREAM_PLAYBACK, coef, chans, cb, iter_len, 0); +} + +#ifdef RESAMPLE_ANY_SAMPLE_RATE +struct APP_RESAMPLE_T *app_playback_resample_any_open(enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step) +{ + const struct RESAMPLE_COEF_T *coef = &resample_coef_any_up256; + + return app_resample_open(AUD_STREAM_PLAYBACK, coef, chans, cb, iter_len, ratio_step); +} + +struct APP_RESAMPLE_T *app_playback_resample_any_open_with_pre_allocated_buffer(enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step, uint8_t* ptrBuf, uint32_t bufSize) +{ + const struct RESAMPLE_COEF_T *coef = &resample_coef_any_up256; + + return app_resample_open_with_preallocated_buf( + AUD_STREAM_PLAYBACK, coef, chans, cb, iter_len, ratio_step, ptrBuf, bufSize); +} + +struct APP_RESAMPLE_T *app_capture_resample_14k7_to_16k(enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step, uint8_t* ptrBuf, uint32_t bufSize) +{ + const struct RESAMPLE_COEF_T *coef = &resample_coef_44p1k_to_48k; + + return app_resample_open_with_preallocated_buf( + AUD_STREAM_PLAYBACK, coef, chans, cb, iter_len, ratio_step, ptrBuf, bufSize); +} + +#endif + +int app_playback_resample_close(struct APP_RESAMPLE_T *resamp) +{ + return app_resample_close(resamp); +} + +int app_playback_resample_run(struct APP_RESAMPLE_T *resamp, uint8_t *buf, uint32_t len) +{ + uint32_t in_size, out_size; + struct RESAMPLE_IO_BUF_T io; + enum RESAMPLE_STATUS_T status; + int ret; + //uint32_t lock; + + if (resamp == NULL) + { + goto _err_exit; + } + + io.out_cyclic_start = NULL; + io.out_cyclic_end = NULL; + + if (resamp->offset < resamp->iter_len) + { + io.in = resamp->iter_buf + resamp->offset; + io.in_size = resamp->iter_len - resamp->offset; + io.out = buf; + io.out_size = len; + + //lock = int_lock(); + status = audio_resample_ex_run((RESAMPLE_ID *)resamp->id, &io, &in_size, &out_size); + //int_unlock(lock); + if (status != RESAMPLE_STATUS_OUT_FULL && status != RESAMPLE_STATUS_IN_EMPTY && + status != RESAMPLE_STATUS_DONE) + { + goto _err_exit; + } + + buf += out_size; + len -= out_size; + resamp->offset += in_size; + + ASSERT(len == 0 || resamp->offset == resamp->iter_len, + "%s: Bad resample offset: len=%d offset=%u iter_len=%u", + __func__, len, resamp->offset, resamp->iter_len); + } + + while (len) + { + ret = resamp->cb(resamp->iter_buf, resamp->iter_len); + if (ret) + { + goto _err_exit; + } + + io.in = resamp->iter_buf; + io.in_size = resamp->iter_len; + io.out = buf; + io.out_size = len; + + //lock = int_lock(); + status = audio_resample_ex_run((RESAMPLE_ID *)resamp->id, &io, &in_size, &out_size); + //int_unlock(lock); + if (status != RESAMPLE_STATUS_OUT_FULL && status != RESAMPLE_STATUS_IN_EMPTY && + status != RESAMPLE_STATUS_DONE) + { + goto _err_exit; + } + + ASSERT(out_size <= len, "%s: Bad resample out_size: out_size=%u len=%d", __func__, out_size, len); + ASSERT(in_size <= resamp->iter_len, "%s: Bad resample in_size: in_size=%u iter_len=%u", __func__, in_size, resamp->iter_len); + + buf += out_size; + len -= out_size; + if (in_size != resamp->iter_len) + { + resamp->offset = in_size; + + ASSERT(len == 0, "%s: Bad resample len: len=%d out_size=%u", __func__, len, out_size); + } + } + + return 0; + +_err_exit: + if (resamp) + { + app_resample_reset(resamp); + } + + memzero_int16(buf, len); + + return 1; +} + +struct APP_RESAMPLE_T *app_capture_resample_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len) +{ + const struct RESAMPLE_COEF_T *coef = NULL; + + if (sample_rate == AUD_SAMPRATE_8000) + { + coef = &resample_coef_8p4k_to_8k; + } + else if (sample_rate == AUD_SAMPRATE_16000) + { + // Same coef as 8K sample rate + coef = &resample_coef_8p4k_to_8k; + } + else + { + ASSERT(false, "%s: Bad sample rate: %u", __func__, sample_rate); + } + + return app_resample_open(AUD_STREAM_CAPTURE, coef, chans, cb, iter_len, 0); + +} + +#ifdef RESAMPLE_ANY_SAMPLE_RATE +struct APP_RESAMPLE_T *app_capture_resample_any_open(enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step) +{ + const struct RESAMPLE_COEF_T *coef = &resample_coef_any_up256; + return app_resample_open(AUD_STREAM_CAPTURE, coef, chans, cb, iter_len, ratio_step); +} +#endif + +int app_capture_resample_close(struct APP_RESAMPLE_T *resamp) +{ + return app_resample_close(resamp); +} + +int app_capture_resample_run(struct APP_RESAMPLE_T *resamp, uint8_t *buf, uint32_t len) +{ + uint32_t in_size, out_size; + struct RESAMPLE_IO_BUF_T io; + enum RESAMPLE_STATUS_T status; + int ret; + + if (resamp == NULL) + { + goto _err_exit; + } + + io.out_cyclic_start = NULL; + io.out_cyclic_end = NULL; + + if (resamp->offset < resamp->iter_len) + { + io.in = buf; + io.in_size = len; + io.out = resamp->iter_buf + resamp->offset; + io.out_size = resamp->iter_len - resamp->offset; + + status = audio_resample_ex_run((RESAMPLE_ID *)resamp->id, &io, &in_size, &out_size); + if (status != RESAMPLE_STATUS_OUT_FULL && status != RESAMPLE_STATUS_IN_EMPTY && + status != RESAMPLE_STATUS_DONE) + { + goto _err_exit; + } + + buf += in_size; + len -= in_size; + resamp->offset += out_size; + + ASSERT(len == 0 || resamp->offset == resamp->iter_len, + "%s: Bad resample offset: len=%d offset=%u iter_len=%u", + __func__, len, resamp->offset, resamp->iter_len); + + if (resamp->offset == resamp->iter_len) + { + ret = resamp->cb(resamp->iter_buf, resamp->iter_len); + if (ret) + { + goto _err_exit; + } + } + } + + while (len) + { + io.in = buf; + io.in_size = len; + io.out = resamp->iter_buf; + io.out_size = resamp->iter_len; + + status = audio_resample_ex_run((RESAMPLE_ID *)resamp->id, &io, &in_size, &out_size); + if (status != RESAMPLE_STATUS_OUT_FULL && status != RESAMPLE_STATUS_IN_EMPTY && + status != RESAMPLE_STATUS_DONE) + { + goto _err_exit; + } + + ASSERT(in_size <= len, "%s: Bad resample in_size: in_size=%u len=%u", __func__, in_size, len); + ASSERT(out_size <= resamp->iter_len, "%s: Bad resample out_size: out_size=%u iter_len=%u", __func__, out_size, resamp->iter_len); + + buf += in_size; + len -= in_size; + if (out_size == resamp->iter_len) + { + ret = resamp->cb(resamp->iter_buf, resamp->iter_len); + if (ret) + { + goto _err_exit; + } + } + else + { + resamp->offset = out_size; + + ASSERT(len == 0, "%s: Bad resample len: len=%u in_size=%u", __func__, len, in_size); + } + } + + return 0; + +_err_exit: + if (resamp) + { + app_resample_reset(resamp); + } + + memzero_int16(buf, len); + + return 1; +} + +void app_resample_reset(struct APP_RESAMPLE_T *resamp) +{ + audio_resample_ex_flush((RESAMPLE_ID *)resamp->id); + resamp->offset = resamp->iter_len; +} + +void app_resample_tune(struct APP_RESAMPLE_T *resamp, float ratio) +{ + float new_step; + + if (resamp == NULL) + { + return; + } + + TRACE_AUD_STREAM_I("%s: stream=%d ratio=%d", __FUNCTION__, resamp->stream, FLOAT_TO_PPB_INT(ratio)); + + if (resamp->stream == AUD_STREAM_PLAYBACK) { + new_step = resamp->ratio_step + resamp->ratio_step * ratio; + } else { + new_step = resamp->ratio_step - resamp->ratio_step * ratio; + } + audio_resample_ex_set_ratio_step(resamp->id, new_step); +} + +APP_RESAMPLE_BUF_ALLOC_CALLBACK app_resample_set_buf_alloc_callback(APP_RESAMPLE_BUF_ALLOC_CALLBACK cb) +{ + APP_RESAMPLE_BUF_ALLOC_CALLBACK old_cb; + + old_cb = resamp_buf_alloc; + resamp_buf_alloc = cb; + + return old_cb; +} + +#ifdef TX_RX_PCM_MASK + +#ifdef SCO_DMA_SNAPSHOT + +#define MSBC_LEN 60 + +void store_encode_frame2buff() +{ + if(bt_sco_codec_is_msbc()) + { + uint32_t len; + //processing uplink msbc data. + if(playback_buf_btpcm_copy!=NULL) + { + len=playback_size_btpcm_copy-MSBC_LEN; + memcpy((uint8_t *)(*(volatile uint32_t *)(MIC_BUFF_ADRR_REG)),playback_buf_btpcm_copy,MSBC_LEN); + memcpy(playback_buf_btpcm_copy,playback_buf_btpcm_copy+MSBC_LEN,len); + } + //processing downlink msbc data. + if(capture_buf_btpcm_copy!=NULL) + { + len=capture_size_btpcm_copy-MSBC_LEN; + memcpy(capture_buf_btpcm_copy,capture_buf_btpcm_copy+MSBC_LEN,len); + memcpy(capture_buf_btpcm_copy+len,(uint8_t *)(*(volatile uint32_t *)(RX_BUFF_ADRR)),MSBC_LEN); + } +#if defined(CHIP_BEST2300A) + uint8_t sco_toggle = *(volatile uint8_t *)(RX_BUFF_ADRR+8); + pcm_data_param[sco_toggle].curr_time = *(volatile uint32_t *)(RX_BUFF_ADRR+4); + pcm_data_param[sco_toggle].toggle = sco_toggle; + pcm_data_param[sco_toggle].flag = *(volatile uint8_t *)(RX_BUFF_ADRR+9); + pcm_data_param[sco_toggle].counter = *(volatile uint16_t *)(RX_BUFF_ADRR+10); +#endif + } + return; +} +#else +extern CQueue* get_tx_esco_queue_ptr(); +extern CQueue* get_rx_esco_queue_ptr(); +void store_encode_frame2buff() +{ + CQueue* Tx_esco_queue_temp = NULL; + CQueue* Rx_esco_queue_temp = NULL; + Tx_esco_queue_temp = get_tx_esco_queue_ptr(); + Rx_esco_queue_temp = get_rx_esco_queue_ptr(); + unsigned int len; + len= 60; + int status = 0; + if(bt_sco_codec_is_msbc()) + { + status = DeCQueue(Tx_esco_queue_temp,(uint8_t *)(*(volatile uint32_t *)(MIC_BUFF_ADRR_REG)),len); + if(status){ + //TRACE_AUD_STREAM_I("TX DeC Fail"); + } + status =EnCQueue(Rx_esco_queue_temp, (uint8_t *)(*(volatile uint32_t *)(RX_BUFF_ADRR)), len); + if(status){ + //TRACE_AUD_STREAM_I("RX EnC Fail"); + } + } + +} +#endif +#endif + +int app_bt_stream_init(void) +{ + app_bt_stream_trigger_checker_init(); + return 0; +} + diff --git a/services/bt_app/app_bt_stream.h b/services/bt_app/app_bt_stream.h new file mode 100644 index 0000000..9d2c4db --- /dev/null +++ b/services/bt_app/app_bt_stream.h @@ -0,0 +1,242 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BT_STREAM_H__ +#define __APP_BT_STREAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_aud.h" +#include "stdint.h" +#define BT_AUDIO_BUFF_AAC_SIZE (1024*2*2*2) + +#if defined(__3M_PACK__) +#define BT_AUDIO_BUFF_SBC_SIZE (128*7*2*2*2) +#else +#define BT_AUDIO_BUFF_SBC_44P1K_SIZE (128*5*2*2*2) +#define BT_AUDIO_BUFF_SBC_48K_SIZE (128*6*2*2*2) +#endif + +#if defined(A2DP_LDAC_ON) +#define BT_AUDIO_BUFF_SIZE_LDAC (256*4*2*2*2) +#endif + +#define BT_AUDIO_CACHE_2_UNCACHE(addr) \ + ((unsigned char *)((unsigned int)addr & ~(0x04000000))) + +// #if BT_AUDIO_BUFF_SIZE < BT_AUDIO_SCO_BUFF_SIZE * 4 +// #error BT_AUDIO_BUFF_SIZE must be at least BT_AUDIO_SCO_BUFF_SIZE * 4 +// #endif + +// low 11 bits are output streams index while high 5 bits are input streams index +// one output stream and one input stream can exit at the same time, +// while two streams with the same direction are mutex +#define APP_BT_STREAM_BORDER_BIT_OFFSET 12 +// the index < the border is the output stream +// the index >= the border is the input stream +#define APP_BT_STREAM_BORDER_INDEX (1 << APP_BT_STREAM_BORDER_BIT_OFFSET) + +// output streams +#define APP_BT_STREAM_HFP_PCM (1 << 0) +#define APP_BT_STREAM_HFP_CVSD (1 << 1) +#define APP_BT_STREAM_HFP_VENDOR (1 << 2) +#define APP_BT_STREAM_A2DP_SBC (1 << 3) +#define APP_BT_STREAM_A2DP_AAC (1 << 4) +#define APP_BT_STREAM_A2DP_VENDOR (1 << 5) +#ifdef __FACTORY_MODE_SUPPORT__ +#define APP_FACTORYMODE_AUDIO_LOOP (1 << 6) +#endif +#define APP_PLAY_BACK_AUDIO (1 << 7) +#ifdef RB_CODEC +#define APP_BT_STREAM_RBCODEC (1 << 8) +#endif +#ifdef AUDIO_LINEIN +#define APP_PLAY_LINEIN_AUDIO (1 << 9) +#endif +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(__APP_A2DP_SOURCE__)||(APP_I2S_A2DP_SOURCE) +#define APP_A2DP_SOURCE_LINEIN_AUDIO (1 << 10) +#define APP_A2DP_SOURCE_I2S_AUDIO (1 << 11) +#endif + + +// input streams +#ifdef VOICE_DATAPATH +#define APP_BT_STREAM_VOICEPATH (1 << APP_BT_STREAM_BORDER_BIT_OFFSET) +#endif + +#ifdef __AI_VOICE__ +#define APP_BT_STREAM_AI_VOICE (1 << (APP_BT_STREAM_BORDER_BIT_OFFSET+1)) +#endif + +#ifdef __THIRDPARTY +#define APP_BT_STREAM_THIRDPARTY_VOICE (1 << (APP_BT_STREAM_BORDER_BIT_OFFSET+2)) +#endif + +#define APP_BT_STREAM_INVALID 0 + +#define APP_BT_OUTPUT_STREAM_INDEX(player) ((player) & ((1 << APP_BT_STREAM_BORDER_BIT_OFFSET) - 1)) +#define APP_BT_INPUT_STREAM_INDEX(player) ((player) & (~((1 << APP_BT_STREAM_BORDER_BIT_OFFSET) - 1))) + +#include + +enum APP_BT_SETTING_T { + APP_BT_SETTING_OPEN = 0, + APP_BT_SETTING_CLOSE, + APP_BT_SETTING_SETUP, + APP_BT_SETTING_RESTART, + APP_BT_SETTING_CLOSEALL, + APP_BT_SETTING_CLOSEMEDIA, + APP_BT_SETTING_NUM, +}; + +enum APP_BT_AUDIO_Q_POS { + APP_BT_SETTING_Q_POS_HEAD = 0, + APP_BT_SETTING_Q_POS_TAIL = 1, +}; + +typedef struct { + uint16_t id; + uint16_t status; + + uint16_t aud_type; + uint16_t aud_id; + + uint8_t freq; +}APP_AUDIO_STATUS; + +const char *player2str(uint16_t player_type); + +int app_bt_stream_init(void); + +int app_bt_stream_open(APP_AUDIO_STATUS* status); + +int app_bt_stream_close(uint16_t player); + +int app_bt_stream_setup(uint16_t player, uint8_t status); + +int app_bt_stream_restart(APP_AUDIO_STATUS* status); + +int app_bt_stream_closeall(); + +bool app_bt_stream_isrun(uint16_t player); + +void app_bt_set_volume(uint16_t type,uint8_t level); + +void app_bt_stream_volumeup(void); + +void app_bt_stream_volumedown(void); + +void app_bt_stream_volume_ptr_update(uint8_t *bdAddr); + +struct btdevice_volume * app_bt_stream_volume_get_ptr(void); + +int app_bt_stream_volumeset(int8_t vol); + +uint8_t app_bt_stream_a2dpvolume_get(void); + +uint8_t app_bt_stream_hfpvolume_get(void); + +void app_bt_stream_a2dpvolume_reset(void); + +void app_bt_stream_hfpvolume_reset(void); + +void app_bt_stream_copy_track_one_to_two_24bits(int32_t *dst_buf, int32_t *src_buf, uint32_t src_len); + +void app_bt_stream_copy_track_one_to_two_16bits(int16_t *dst_buf, int16_t *src_buf, uint32_t src_len); + +void app_bt_stream_copy_track_two_to_one_16bits(int16_t *dst_buf, int16_t *src_buf, uint32_t dst_len); + +enum AUD_SAMPRATE_T bt_get_sbc_sample_rate(void); + +void bt_store_sbc_sample_rate(enum AUD_SAMPRATE_T sample_rate); + +enum AUD_SAMPRATE_T bt_parse_store_sbc_sample_rate(uint8_t sbc_samp_rate); + +bool app_bt_stream_is_mic_mix_during_music_enabled(void); +void app_bt_sream_set_mix_mic_flag(bool isEnable); +void bt_sbc_mix_mic_init(void); +void bt_sbc_mix_mic_deinit(void); +uint32_t bt_sbc_codec_capture_data(uint8_t *buf, uint32_t len); + +void app_audio_buffer_check(void); + +// ======================================================= +// APP RESAMPLE +// ======================================================= + +#include "hal_aud.h" + +typedef int (*APP_RESAMPLE_BUF_ALLOC_CALLBACK)(uint8_t **buff, uint32_t size); + +typedef int (*APP_RESAMPLE_ITER_CALLBACK)(uint8_t *buf, uint32_t len); + +struct APP_RESAMPLE_T { + enum AUD_STREAM_T stream; + void *id; + APP_RESAMPLE_ITER_CALLBACK cb; + uint8_t *iter_buf; + uint32_t iter_len; + uint32_t offset; + float ratio_step; +}; + +struct APP_RESAMPLE_T *app_playback_resample_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len); +struct APP_RESAMPLE_T *app_playback_resample_any_open(enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step); +struct APP_RESAMPLE_T *app_playback_resample_any_open_with_pre_allocated_buffer(enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step, uint8_t* ptrBuf, uint32_t bufSize); + +struct APP_RESAMPLE_T *app_capture_resample_14k7_to_16k(enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step, uint8_t* ptrBuf, uint32_t bufSize); + +int app_playback_resample_close(struct APP_RESAMPLE_T *resamp); +int app_playback_resample_run(struct APP_RESAMPLE_T *resamp, uint8_t *buf, uint32_t len); + +struct APP_RESAMPLE_T *app_capture_resample_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len); +struct APP_RESAMPLE_T *app_capture_resample_any_open(enum AUD_CHANNEL_NUM_T chans, + APP_RESAMPLE_ITER_CALLBACK cb, uint32_t iter_len, + float ratio_step); +int app_capture_resample_close(struct APP_RESAMPLE_T *resamp); +int app_capture_resample_run(struct APP_RESAMPLE_T *resamp, uint8_t *buf, uint32_t len); + +void app_resample_reset(struct APP_RESAMPLE_T *resamp); +void app_resample_tune(struct APP_RESAMPLE_T *resamp, float ratio); +APP_RESAMPLE_BUF_ALLOC_CALLBACK app_resample_set_buf_alloc_callback(APP_RESAMPLE_BUF_ALLOC_CALLBACK cb); +uint16_t app_bt_stream_ibrt_trigger_seq_diff_calc(int32_t dma_samples, int32_t frame_samples, int32_t sub_seq, int32_t interval); +void app_bt_stream_volumeset_handler(int8_t vol); + +#ifdef TX_RX_PCM_MASK +void store_encode_frame2buff(); +#endif + +#ifdef BONE_SENSOR_TDM +void bt_sco_get_tdm_buffer(uint8_t **buf, uint32_t *len); +#endif +int app_bt_stream_local_volume_get(void); + +bool bt_is_playback_triggered(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/bt_app/app_bt_trace.h b/services/bt_app/app_bt_trace.h new file mode 100644 index 0000000..ec0da09 --- /dev/null +++ b/services/bt_app/app_bt_trace.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BT_TRACE_H__ +#define __APP_BT_TRACE_H__ + +#include "hal_trace.h" + +#ifdef ENABLE_COMPRESS_LOG +#define TRACE_AUD_MGR_D(str, ...) hal_trace_dummy(str, ##__VA_ARGS__) +//LOG_DEBUG(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][MGR][DBG]"str, ##__VA_ARGS__) +#define TRACE_AUD_MGR_I(str, ...) LOG_INFO(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][MGR]"str, ##__VA_ARGS__) +#define TRACE_AUD_MGR_W(str, ...) LOG_WARN(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][MGR][WARN]"str, ##__VA_ARGS__) +#define TRACE_AUD_MGR_E(str, ...) LOG_ERROR(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][MGR][ERR]"str, ##__VA_ARGS__) +#else +#define TRACE_AUD_MGR_D(str, ...) hal_trace_dummy(str, ##__VA_ARGS__) +//LOG_DEBUG(LOG_MOD(AUDFLG), "[AUD][MGR][DBG]"str, ##__VA_ARGS__) +#define TRACE_AUD_MGR_I(str, ...) LOG_INFO(LOG_MOD(AUDFLG), "[AUD][MGR]"str, ##__VA_ARGS__) +#define TRACE_AUD_MGR_W(str, ...) LOG_WARN(LOG_MOD(AUDFLG), "[AUD][MGR][WARN]"str, ##__VA_ARGS__) +#define TRACE_AUD_MGR_E(str, ...) LOG_ERROR(LOG_MOD(AUDFLG), "[AUD][MGR][ERR]"str, ##__VA_ARGS__) +#endif + +#ifdef ENABLE_COMPRESS_LOG +#define TRACE_AUD_HDL_D(str, ...) hal_trace_dummy(str, ##__VA_ARGS__) +//LOG_DEBUG(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][HDL][DBG]"str, ##__VA_ARGS__) +#define TRACE_AUD_HDL_I(str, ...) LOG_INFO(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][HDL]"str, ##__VA_ARGS__) +#define TRACE_AUD_HDL_W(str, ...) LOG_WARN(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][HDL][WARN]"str, ##__VA_ARGS__) +#define TRACE_AUD_HDL_E(str, ...) LOG_ERROR(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][HDL][ERR]"str, ##__VA_ARGS__) +#else +#define TRACE_AUD_HDL_D(str, ...) hal_trace_dummy(str, ##__VA_ARGS__) +//LOG_DEBUG(LOG_MOD(AUDFLG), "[AUD][HDL][DBG]"str, ##__VA_ARGS__) +#define TRACE_AUD_HDL_I(str, ...) LOG_INFO(LOG_MOD(AUDFLG), "[AUD][HDL]"str, ##__VA_ARGS__) +#define TRACE_AUD_HDL_W(str, ...) LOG_WARN(LOG_MOD(AUDFLG), "[AUD][HDL][WARN]"str, ##__VA_ARGS__) +#define TRACE_AUD_HDL_E(str, ...) LOG_ERROR(LOG_MOD(AUDFLG), "[AUD][HDL][ERR]"str, ##__VA_ARGS__) +#endif + +#ifdef ENABLE_COMPRESS_LOG +#define TRACE_AUD_STREAM_D(str, ...) hal_trace_dummy(str, ##__VA_ARGS__) +//LOG_DEBUG(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][STRM][DBG]"str, ##__VA_ARGS__) +#define TRACE_AUD_STREAM_I(str, ...) LOG_INFO(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][STRM]"str, ##__VA_ARGS__) +#define TRACE_AUD_STREAM_W(str, ...) LOG_WARN(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][STRM][WARN]"str, ##__VA_ARGS__) +#define TRACE_AUD_STREAM_E(str, ...) LOG_ERROR(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][STRM][ERR]"str, ##__VA_ARGS__) +#else +#define TRACE_AUD_STREAM_D(str, ...) hal_trace_dummy(str, ##__VA_ARGS__) +//LOG_DEBUG(LOG_MOD(AUDFLG), "[AUD][STRM][DBG]"str, ##__VA_ARGS__) +#define TRACE_AUD_STREAM_I(str, ...) LOG_INFO(LOG_MOD(AUDFLG), "[AUD][STRM]"str, ##__VA_ARGS__) +#define TRACE_AUD_STREAM_W(str, ...) LOG_WARN(LOG_MOD(AUDFLG), "[AUD][STRM][WARN]"str, ##__VA_ARGS__) +#define TRACE_AUD_STREAM_E(str, ...) LOG_ERROR(LOG_MOD(AUDFLG), "[AUD][STRM][ERR]"str, ##__VA_ARGS__) +#endif + +#ifdef ENABLE_COMPRESS_LOG +#define TRACE_MEDIA_PLAYER_D(str, ...) hal_trace_dummy(str, ##__VA_ARGS__) +//LOG_DEBUG(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][STRM][DBG]"str, ##__VA_ARGS__) +#define TRACE_MEDIA_PLAYESTREAM_I(str, ...) LOG_INFO(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][STRM]"str, ##__VA_ARGS__) +#define TRACE_MEDIA_PLAYESTREAM_W(str, ...) LOG_WARN(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][STRM][WARN]"str, ##__VA_ARGS__) +#define TRACE_MEDIA_PLAYESTREAM_E(str, ...) LOG_ERROR(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][STRM][ERR]"str, ##__VA_ARGS__) +#else +#define TRACE_MEDIA_PLAYESTREAM_D(str, ...) hal_trace_dummy(str, ##__VA_ARGS__) +//LOG_DEBUG(LOG_MOD(AUDFLG), "[AUD][STRM][DBG]"str, ##__VA_ARGS__) +#define TRACE_MEDIA_PLAYESTREAM_I(str, ...) LOG_INFO(LOG_MOD(AUDFLG), "[AUD][STRM]"str, ##__VA_ARGS__) +#define TRACE_MEDIA_PLAYESTREAM_W(str, ...) LOG_WARN(LOG_MOD(AUDFLG), "[AUD][STRM][WARN]"str, ##__VA_ARGS__) +#define TRACE_MEDIA_PLAYESTREAM_E(str, ...) LOG_ERROR(LOG_MOD(AUDFLG), "[AUD][STRM][ERR]"str, ##__VA_ARGS__) +#endif + +#endif diff --git a/services/bt_app/app_btgatt.cpp b/services/bt_app/app_btgatt.cpp new file mode 100644 index 0000000..c00e7a1 --- /dev/null +++ b/services/bt_app/app_btgatt.cpp @@ -0,0 +1,35 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef __GATT_OVER_BR_EDR__ +#include "hal_trace.h" +#include "plat_types.h" +#include "app_btgatt.h" +#include "btgatt_api.h" + +void app_btgatt_addsdp(uint16_t pServiceUUID, uint16_t startHandle, uint16_t endHandle) +{ + TRACE(1, "%s", __func__); + btif_btgatt_addsdp(pServiceUUID, startHandle, endHandle); +} + +void app_btgatt_init(void) +{ + TRACE(1, "%s", __func__); + btif_btgatt_init(); +} + +#endif + diff --git a/services/bt_app/app_btgatt.h b/services/bt_app/app_btgatt.h new file mode 100644 index 0000000..5aab65b --- /dev/null +++ b/services/bt_app/app_btgatt.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BTGATT_H__ +#define __APP_BTGATT_H__ + +#define ATT_SERVICE_UUID 0x0118 +#ifdef __cplusplus +extern "C" { +#endif +void app_btgatt_init(void); +void app_btgatt_addsdp(uint16_t pServiceUUID, uint16_t startHandle, uint16_t endHandle); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/bt_app/app_btmap_sms.cpp b/services/bt_app/app_btmap_sms.cpp new file mode 100644 index 0000000..8a669ae --- /dev/null +++ b/services/bt_app/app_btmap_sms.cpp @@ -0,0 +1,242 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_chipid.h" +#include "analog.h" +#include "app_audio.h" +#include "app_battery.h" +#include "app_status_ind.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif +#include "hfp_api.h" +#include "besbt.h" +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "bt_if.h" +#include "app_hfp.h" +#include "app_fp_rfcomm.h" +#include "os_api.h" +#include "app_bt_func.h" +#ifdef BT_USB_AUDIO_DUAL_MODE +#include "btusb_audio.h" +#endif +#ifdef __THIRDPARTY +#include "app_thirdparty.h" +#endif + +#include "bt_drv_interface.h" + +#ifdef VOICE_DATAPATH +#include "app_voicepath.h" +#endif +#include "app.h" +#ifdef __AI_VOICE__ +#include "ai_control.h" +#endif + +#if defined(IBRT) +#include "app_ibrt_if.h" +#include "app_tws_ibrt_cmd_sync_hfp_status.h" +#include "app_ibrt_hf.h" +#include "app_tws_ibrt.h" +#endif + +#if defined(__BTMAP_ENABLE__) +#include "obex_api.h" +#include "map_api.h" +#include "app_btmap_sms.h" + +extern struct BT_DEVICE_T app_bt_device; +struct SMS_MSG_T app_sms_msg; + +#define CHACK_BTMAP_STATE_STAYING_MS 2000 +osTimerId app_btmap_state_check_handling_timer_id = NULL; +static int app_btmap_state_check_handling_handler(void const *param); +osTimerDef (APP_BTMAP_STATE_CHECK_HANDLING_TIMER, (void (*)(void const *))app_btmap_state_check_handling_handler); + + +static int btmap_sms_session_event_handler(btif_map_session_handle_t handle, + btif_map_session_event_t event, btif_map_session_cb_param_t *param) +{ + TRACE(1,"%s", __func__); + btif_map_session_function_param_t func_param; + switch (event) { + case BTIF_MAP_SESSION_EVENT_OPEN: + func_param.p.SetFolder.folder[0] = "root"; + func_param.p.SetFolder.folder[1] = "telecom"; + func_param.p.SetFolder.folder[2] = "msg"; + func_param.p.SetFolder.folder[3] = NULL; + func_param.p.SetFolder.up_level = 0; + btif_map_set_folder(handle, &func_param); + break; + case BTIF_MAP_SESSION_EVENT_CLOSE: + break; + default: + break; + } + return 0; +} + +void app_btmap_connected_callback(void* param, void* map_session) +{ + TRACE(1,"%s", __func__); +#if defined(IBRT) + app_tws_ibrt_profile_callback(BTIF_APP_MAP_PROFILE_ID,(void *)param,(void *)map_session); +#endif +} + +void app_btmap_sms_init(void) +{ + TRACE(1,"%s", __func__); + int i = 0; + btif_map_initialize(); + btif_map_callback_register(app_btmap_connected_callback); + // only map mas client supported now + for (i = 0; i < BT_DEVICE_NUM; ++i) { + app_bt_device.map_session_handle[i] = btif_map_create_session(); + } +} + +void app_btmap_sms_open(BT_DEVICE_ID_T id, bt_bdaddr_t *remote) +{ + TRACE(1,"%s", __func__); + btif_map_session_config_t config; + btif_map_session_handle_t handle = NULL; + handle = app_bt_device.map_session_handle[id]; + + if (handle == NULL) { + TRACE(2,"%s:handle is NULL, id=%d", __func__, id); + return; + } + + TRACE(2,"btmap_sms_open:id=%d,remote=0x%p", id, remote); + DUMP8("0x%02x-", remote, 6); + + config.type = BTIF_MAP_SESSION_TYPE_MAS; + config.obex_role = BTIF_OBEX_SESSION_ROLE_CLIENT; + btif_map_session_open(handle, remote, &config, btmap_sms_session_event_handler); +} + +void app_btmap_sms_close(BT_DEVICE_ID_T id) +{ + TRACE(1,"%s", __func__); + btif_map_session_handle_t handle = NULL; + handle = app_bt_device.map_session_handle[id]; + + if (handle == NULL) { + TRACE(2,"%s:handle is NULL, id=%d", __func__, id); + return; + } + + btif_map_session_close(handle); +} + +void app_btmap_sms_send(BT_DEVICE_ID_T id, char* telNum, char* msg) +{ + btif_map_session_handle_t handle = NULL; + handle = app_bt_device.map_session_handle[id]; + + if (handle == NULL) { + TRACE(2,"%s:handle is NULL, id=%d", __func__, id); + return; + } + + btif_map_send_sms(handle, telNum, msg); +} + +bool app_btmap_check_is_connected(BT_DEVICE_ID_T id) +{ + TRACE(1,"%s", __func__); + btif_map_session_handle_t handle = NULL; + handle = app_bt_device.map_session_handle[id]; + + return btif_map_check_is_connected(handle); +} + +bool app_btmap_check_is_idle(BT_DEVICE_ID_T id) +{ + TRACE(1,"%s", __func__); + btif_map_session_handle_t handle = NULL; + handle = app_bt_device.map_session_handle[id]; + + return btif_map_check_is_idle(handle); +} + + +void app_btmap_sms_save(BT_DEVICE_ID_T id, char* telNum, char* msg) +{ + TRACE(1,"%s", __func__); + app_sms_msg.telNum = telNum; + app_sms_msg.msg = msg; + app_sms_msg.telNumLen = strlen(telNum); + app_sms_msg.msgLen = strlen(msg); + + if (NULL == app_btmap_state_check_handling_timer_id) + { + app_btmap_state_check_handling_timer_id = + osTimerCreate(osTimer(APP_BTMAP_STATE_CHECK_HANDLING_TIMER), osTimerOnce, NULL); + } + + osTimerStart(app_btmap_state_check_handling_timer_id, CHACK_BTMAP_STATE_STAYING_MS); +} + +void app_btmap_sms_resend(void) +{ + TRACE(1,"%s", __func__); + + app_btmap_sms_send(BT_DEVICE_ID_1, app_sms_msg.telNum, app_sms_msg.msg); + memset((void *)app_sms_msg.telNum, 0, app_sms_msg.telNumLen); + memset((void *)app_sms_msg.msg, 0, app_sms_msg.msgLen); +} +static uint8_t resendTime = 0; +static int app_btmap_state_check_handling_handler(void const *param) +{ + TRACE(1,"%s", __func__); + resendTime++; + if(resendTime >= 6) + { + resendTime = 0; + return -1; + } + + if(true == app_btmap_check_is_connected(BT_DEVICE_ID_1)) + { + app_btmap_sms_resend(); + } + else + { + osTimerStart(app_btmap_state_check_handling_timer_id, CHACK_BTMAP_STATE_STAYING_MS); + } + return 0; +} + +#endif /* __BTMAP_ENABLE__ */ diff --git a/services/bt_app/app_btmap_sms.h b/services/bt_app/app_btmap_sms.h new file mode 100644 index 0000000..dcfefac --- /dev/null +++ b/services/bt_app/app_btmap_sms.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BTMAP_SMS_H__ +#define __APP_BTMAP_SMS_H__ + +#include "bluetooth.h" +#include "btapp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void app_btmap_sms_init(void); +void app_btmap_sms_open(BT_DEVICE_ID_T id, bt_bdaddr_t *remote); +void app_btmap_sms_close(BT_DEVICE_ID_T id); +void app_btmap_sms_send(BT_DEVICE_ID_T id, char* telNum, char* msg); +bool app_btmap_check_is_connected(BT_DEVICE_ID_T id); +void app_btmap_sms_save(BT_DEVICE_ID_T id, char* telNum, char* msg); +void app_btmap_sms_resend(void); +bool app_btmap_check_is_idle(BT_DEVICE_ID_T id); + + +struct SMS_MSG_T{ + char* telNum; + char* msg; + uint8_t telNumLen; + uint32_t msgLen; +}; + +#ifdef __cplusplus +} +#endif + +#endif /*__APP_BTMAP_SMS_H__*/ + diff --git a/services/bt_app/app_dip.cpp b/services/bt_app/app_dip.cpp new file mode 100644 index 0000000..7340f1d --- /dev/null +++ b/services/bt_app/app_dip.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "btif_sys_config.h" + +#ifdef BTIF_DIP_DEVICE + +#include +#include "cmsis_os.h" +#include "hal_trace.h" +#include "dip_api.h" +#include "plat_types.h" +#include "app_bt.h" +#include "app_dip.h" +#include "nvrecord_bt.h" + +#if defined(ENHANCED_STACK) +#include "sdp_api.h" +#include "me_api.h" +#endif + +#if defined(IBRT) +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_ctrl_thread.h" +#include "app_ibrt_peripheral_manager.h" +#include "app_ibrt_if.h" +#include "app_tws_if.h" +#endif + +#if defined(__AI_VOICE__) || defined(BISTO_ENABLED) +#include "app_ai_if.h" +#endif + +#if defined(__AI_VOICE__) +#include "ai_thread.h" +#endif + +void app_dip_sync_dip_info(void); + +static void app_dip_callback(bt_bdaddr_t *_addr, bool ios_flag) +{ + btif_remote_device_t *p_remote_dev = btif_me_get_remote_device_by_bdaddr(_addr); + + TRACE(2,"%s dev %p addr :", __func__, p_remote_dev); + DUMP8("%x ", _addr->address, 6); + +#if defined(IBRT) + if (TWS_LINK == app_tws_ibrt_get_remote_link_type(p_remote_dev)) + { + TRACE(1,"%s connect type is TWS", __func__); + return; + } + + app_dip_sync_dip_info(); +#endif + +#if defined(__AI_VOICE__) || defined(BISTO_ENABLED) + app_ai_if_mobile_connect_handle(_addr); +#endif +} + +#if defined(IBRT) +void app_dip_sync_info_prepare_handler(uint8_t *buf, uint16_t *length) +{ + uint32_t offset = 0; + ibrt_ctrl_t *p_g_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + bt_bdaddr_t *mobile_addr = &p_g_ibrt_ctrl->mobile_addr; + uint16_t vend_id = 0; + uint16_t vend_id_source = 0; + + btif_dip_get_record_vend_id_and_source(mobile_addr, &vend_id, &vend_id_source); + memcpy(buf, mobile_addr->address, 6); + offset += 6; + memcpy(buf+offset, (uint8_t *)&vend_id, 2); + offset += 2; + memcpy(buf+offset, (uint8_t *)&vend_id_source, 2); + offset += 2; + + *length = offset; +} + +void app_dip_sync_info_received_handler(uint8_t *buf, uint16_t length) +{ + bt_bdaddr_t mobile_addr; + uint16_t vend_id = 0; + uint16_t vend_id_source = 0; + uint32_t offset = 0; + nvrec_btdevicerecord *record = NULL; + + memcpy(mobile_addr.address, buf, 6); + offset += 6; + memcpy((uint8_t *)&vend_id, buf+offset, 2); + offset += 2; + memcpy((uint8_t *)&vend_id_source, buf+offset, 2); + offset += 2; + TRACE(2, "%s vend_id 0x%x vend_id_source 0x%x addr:", __func__, vend_id, vend_id_source); + DUMP8("0x%x ", mobile_addr.address, 6); + + if (vend_id && !nv_record_btdevicerecord_find(&mobile_addr, &record)) + { + nv_record_btdevicerecord_set_vend_id_and_source(record, vend_id, vend_id_source); + } +} + +void app_dip_sync_init(void) +{ + TWS_SYNC_USER_T user_app_dip_t = { + app_dip_sync_info_prepare_handler, + app_dip_sync_info_received_handler, + NULL, + NULL, + NULL, + }; + + app_tws_if_register_sync_user(TWS_SYNC_USER_DIP, &user_app_dip_t); +} + +void app_dip_sync_dip_info(void) +{ + app_tws_if_sync_info(TWS_SYNC_USER_DIP); +} +#endif + +void app_dip_init(void) +{ + btif_dip_init(app_dip_callback); +} + +#endif + diff --git a/services/bt_app/app_dip.h b/services/bt_app/app_dip.h new file mode 100644 index 0000000..34345d3 --- /dev/null +++ b/services/bt_app/app_dip.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_DIP_H__ +#define __APP_DIP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//the mobile connect type +typedef enum { + MOBILE_CONNECT_IDLE, + MOBILE_CONNECT_IOS, + MOBILE_CONNECT_ANDROID, +} MOBILE_CONN_TYPE_E; + +void app_dip_sync_init(void); +void app_dip_init(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/bt_app/app_fp_rfcomm.cpp b/services/bt_app/app_fp_rfcomm.cpp new file mode 100644 index 0000000..63b20e0 --- /dev/null +++ b/services/bt_app/app_fp_rfcomm.cpp @@ -0,0 +1,859 @@ +#include +#include +#include +#include "cmsis.h" +#include "cmsis_os.h" +#include "hal_trace.h" +#include "os_api.h" +#include "bt_if.h" +#include "app_bt.h" +#include "app_spp.h" +#include "spp_api.h" +#include "sdp_api.h" +#include "app_bt_func.h" +#include "app_rfcomm_mgr.h" +#include "app_fp_rfcomm.h" +#ifdef IBRT +#include "app_tws_ibrt.h" +#include "app_tws_if.h" +#endif + +osMutexDef(fp_rfcomm_mutex); +osMutexDef(fp_rfcomm_credit_mutex); + + +#define FP_RFCOMM_TX_PKT_CNT 6 + +/* 128 bit UUID in Big Endian df21fe2c-2515-4fdb-8886-f12c4d67927c */ +static const uint8_t FP_RFCOMM_UUID_128[16] = { + 0x7C, 0x92, 0x67, 0x4D, 0x2C, 0xF1, 0x86, 0x88, 0xDB, 0x4F, 0x15, 0x25, 0x2C, 0xFE, 0x21, 0xDF}; + +typedef struct +{ + uint8_t isConnected; + int8_t serviceIndex; + uint8_t isRfcommInitialized; +} FpRFcommServiceEnv_t; + +typedef union +{ + struct + { + uint8_t isCompanionAppInstalled : 1; + uint8_t isSilentModeSupported : 1; + uint8_t reserve : 6; + } env; + uint8_t content; +} FpCapabilitiesEnv_t; + +typedef struct +{ + uint8_t isRightRinging : 1; + uint8_t isLeftRinging : 1; + uint8_t reserve : 6; +} FpRingStatus_t; + +static FpRFcommServiceEnv_t fp_rfcomm_service = {false, -1, false}; + +static FpCapabilitiesEnv_t fp_capabilities = {false, false, 0}; + +static __attribute__((unused)) FpRingStatus_t fp_ring_status = {false, false, 0}; + +btif_sdp_record_t* fpSppSdpRecord; + +extern "C" void app_gfps_get_battery_levels(uint8_t *pCount, uint8_t *pBatteryLevel); +extern "C" uint8_t *appm_get_current_ble_addr(void); + +static int fp_rfcomm_data_received(void *pDev, uint8_t process, uint8_t *pData, uint16_t dataLen); +static void app_fp_msg_send_active_components_rsp(void); +static void app_fp_msg_send_message_ack(uint8_t msgGroup, uint8_t msgCode); +static void app_fp_msg_send_message_nak(uint8_t reason, uint8_t msgGroup, uint8_t msgCode); +static void fp_rfcomm_data_handler(uint8_t* ptr, uint16_t len); +// update this value if the maximum possible tx data size is bigger than current value +#define FP_RFCOMM_TX_BUF_CHUNK_SIZE 64 +#define FP_RFCOMM_TX_BUF_CHUNK_CNT FP_RFCOMM_TX_PKT_CNT +#define FP_RFCOMM_TX_BUF_SIZE (FP_RFCOMM_TX_BUF_CHUNK_CNT * FP_RFCOMM_TX_BUF_CHUNK_SIZE) + +static uint32_t fp_rfcomm_tx_buf_next_allocated_chunk = 0; +static uint32_t fp_rfcomm_tx_buf_allocated_chunk_cnt = 0; +static uint8_t fp_rfcomm_tx_buf[FP_RFCOMM_TX_BUF_CHUNK_CNT][FP_RFCOMM_TX_BUF_CHUNK_SIZE]; + +static uint8_t *fp_rfcomm_tx_buf_addr(uint32_t chunk) +{ + return fp_rfcomm_tx_buf[chunk]; +} + +static int32_t fp_rfcomm_alloc_tx_chunk(void) +{ + uint32_t lock = int_lock_global(); + + if (fp_rfcomm_tx_buf_allocated_chunk_cnt >= FP_RFCOMM_TX_BUF_CHUNK_CNT) + { + int_unlock_global(lock); + return -1; + } + + uint32_t returnedChunk = fp_rfcomm_tx_buf_next_allocated_chunk; + + fp_rfcomm_tx_buf_allocated_chunk_cnt++; + fp_rfcomm_tx_buf_next_allocated_chunk++; + if (FP_RFCOMM_TX_BUF_CHUNK_CNT == fp_rfcomm_tx_buf_next_allocated_chunk) + { + fp_rfcomm_tx_buf_next_allocated_chunk = 0; + } + + int_unlock_global(lock); + return returnedChunk; +} + +static bool fp_rfcomm_free_tx_chunk(void) +{ + uint32_t lock = int_lock_global(); + if (0 == fp_rfcomm_tx_buf_allocated_chunk_cnt) + { + int_unlock_global(lock); + return false; + } + + fp_rfcomm_tx_buf_allocated_chunk_cnt--; + int_unlock_global(lock); + return true; +} + +static void fp_rfcomm_reset_tx_buf(void) +{ + uint32_t lock = int_lock_global(); + fp_rfcomm_tx_buf_allocated_chunk_cnt = 0; + fp_rfcomm_tx_buf_next_allocated_chunk = 0; + int_unlock_global(lock); +} + +#define GFPS_FIND_MY_BUDS_CMD_STOP 0x0 +#define GFPS_FIND_MY_BUDS_CMD_START 0x1 + +#define FIND_MY_BUDS_CMD_STOP_MASTER 0x00 +#define FIND_MY_BUDS_CMD_STOP_SLAVE 0x01 +#define FIND_MY_BUDS_CMD_START_MASTER 0x10 +#define FIND_MY_BUDS_CMD_START_SLAVE 0x11 + +#define FIND_MY_BUDS_STATUS_SLAVE_MASK 0x1 +#define FIND_MY_BUDS_STATUS_MASTER_MASK 0x2 +uint8_t find_buds_flag = 0; + +#include "app_status_ind.h" +#include "apps.h" + +void app_set_find_my_buds(uint8_t mode) +{ +#ifdef IBRT + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + TRACE(2,"%s, mode = %d,role = %d", __func__, mode,p_ibrt_ctrl->current_role); + + switch (mode) + { + case FIND_MY_BUDS_CMD_STOP_MASTER: + if(find_buds_flag & FIND_MY_BUDS_STATUS_MASTER_MASK) + { + /* stop beeping master */ + if (IBRT_SLAVE != p_ibrt_ctrl->current_role) + { + //app_set_find_my_buds_status(false); + app_voice_stop(APP_STATUS_INDICATION_FIND_MY_BUDS, 0); + find_buds_flag &= ~(FIND_MY_BUDS_STATUS_MASTER_MASK); + } + } + break; + case FIND_MY_BUDS_CMD_STOP_SLAVE: + if(find_buds_flag & FIND_MY_BUDS_STATUS_SLAVE_MASK) + { + /* stop beeping slave */ + if (IBRT_SLAVE == p_ibrt_ctrl->current_role) + { + app_voice_stop(APP_STATUS_INDICATION_FIND_MY_BUDS, 0); + find_buds_flag &= ~(FIND_MY_BUDS_STATUS_SLAVE_MASK); + } + } + break; + case FIND_MY_BUDS_CMD_START_MASTER: + if(!(find_buds_flag & FIND_MY_BUDS_STATUS_MASTER_MASK)) + { + /* start beep master */ + if (IBRT_SLAVE != p_ibrt_ctrl->current_role) + { + app_voice_report(APP_STATUS_INDICATION_FIND_MY_BUDS, 0); + + find_buds_flag |= FIND_MY_BUDS_STATUS_MASTER_MASK; + } + } + break; + case FIND_MY_BUDS_CMD_START_SLAVE: + if(!(find_buds_flag & FIND_MY_BUDS_STATUS_SLAVE_MASK)) + { + /* start beep slave */ + if (IBRT_SLAVE == p_ibrt_ctrl->current_role) + { + app_voice_report(APP_STATUS_INDICATION_FIND_MY_BUDS, 0); + + find_buds_flag |= FIND_MY_BUDS_STATUS_SLAVE_MASK; + } + } + break; + default: + break; + } +#else + switch (mode) + { + case GFPS_FIND_MY_BUDS_CMD_START: + app_voice_report(APP_STATUS_INDICATION_FIND_MY_BUDS, 0); + break; + case GFPS_FIND_MY_BUDS_CMD_STOP: + app_voice_stop(APP_STATUS_INDICATION_FIND_MY_BUDS, 0); + default: + break; + } +#endif +} + +osTimerId ring_timeout_timer_id = NULL; +static void gfps_find_devices_ring_timeout_handler(void const *param); +osTimerDef (GFPS_FIND_DEVICES_RING_TIMEOUT, gfps_find_devices_ring_timeout_handler); +#define GFPS_FIND_MY_BUDS_CMD_STOP_DUAL 0x0 +#define GFPS_FIND_MY_BUDS_CMD_START_MASTER_ONLY 0x1 +#define GFPS_FIND_MY_BUDS_CMD_START_SLAVE_ONLY 0x2 +#define GFPS_FIND_MY_BUDS_CMD_START_DUAL 0x3 +static void gfps_set_find_my_buds(uint8_t cmd) +{ + TRACE(2,"%s, cmd = %d", __func__, cmd); +#ifdef IBRT + if(GFPS_FIND_MY_BUDS_CMD_STOP_DUAL == cmd) + { + app_set_find_my_buds(FIND_MY_BUDS_CMD_STOP_MASTER); + app_set_find_my_buds(FIND_MY_BUDS_CMD_STOP_SLAVE); + } + else if(GFPS_FIND_MY_BUDS_CMD_START_MASTER_ONLY == cmd) //right ring, stop left + { + app_set_find_my_buds(FIND_MY_BUDS_CMD_STOP_SLAVE); + app_set_find_my_buds(FIND_MY_BUDS_CMD_START_MASTER); + } + else if(GFPS_FIND_MY_BUDS_CMD_START_SLAVE_ONLY == cmd) //left ring, stop right + { + app_set_find_my_buds(FIND_MY_BUDS_CMD_STOP_MASTER); + app_set_find_my_buds(FIND_MY_BUDS_CMD_START_SLAVE); + } + else if(GFPS_FIND_MY_BUDS_CMD_START_DUAL == cmd) //both ring + { + app_set_find_my_buds(FIND_MY_BUDS_CMD_START_MASTER); + app_set_find_my_buds(FIND_MY_BUDS_CMD_START_SLAVE); + } +#else + app_set_find_my_buds(cmd); +#endif +} +static void gfps_find_devices_ring_timeout_handler(void const *param) +{ + TRACE(0,"gfps_find_devices_ring_timeout_handler"); + app_bt_start_custom_function_in_bt_thread(GFPS_FIND_MY_BUDS_CMD_STOP_DUAL, 0, \ + (uint32_t)gfps_set_find_my_buds); +} + +void fp_rfcomm_ring_timer_set(uint8_t period) +{ + TRACE(2,"%s, period = %d", __func__, period); + if (ring_timeout_timer_id == NULL) + { + ring_timeout_timer_id = osTimerCreate(osTimer(GFPS_FIND_DEVICES_RING_TIMEOUT), osTimerOnce, NULL); + } + + osTimerStop(ring_timeout_timer_id); + if(period) + { + osTimerStart(ring_timeout_timer_id, period*1000); + } +} + +static void fp_rfcomm_ring_request_handling(uint8_t* requestdata, uint16_t datalen) +{ + TRACE(1,"%s,[RFCOMM][FMD] request",__func__); + DUMP8("%02x ", requestdata, datalen); + app_fp_msg_send_message_ack(FP_MSG_GROUP_DEVICE_ACTION, FP_MSG_DEVICE_ACTION_RING); + if (datalen > 1) + { + fp_rfcomm_ring_timer_set(requestdata[1]); + } + + gfps_set_find_my_buds(requestdata[0]); + + // TODO: implement the continuous audio prompt playing state machine +#if 0 + uint8_t isAllowed = false; + uint8_t isChangePeerDevStatus = false; + switch (request) + { + case 3: + { + if (IS_CONNECTED_WITH_TWS() && + ((0 == fp_ring_status.isLeftRinging) && + (0 == fp_ring_status.isRightRinging))) + { + // TODO: start ringing on both sides + fp_ring_status.isLeftRinging = true; + fp_ring_status.isRightRinging = true; + + isAllowed = true; + } + break; + } + case 1: + if (0 == fp_ring_status.isRightRinging) + { + if (((fp_ring_status.isLeftRinging) && app_tws_is_right_side()) || + app_tws_is_left_side()) + { + isChangePeerDevStatus = true; + } + + if (isChangePeerDevStatus && !IS_CONNECTED_WITH_TWS()) + { + break; + } + + // start right ring + if (app_tws_is_left_side()) + { + // TODO: start ringing on peer device + } + else if (app_tws_is_right_side()) + { + // TODO: start local ringing + } + + if (fp_ring_status.isLeftRinging) + { + // stop left ring + if (app_tws_is_right_side()) + { + // TODO: stop ringing on peer device + } + else if (app_tws_is_left_side()) + { + // TODO: stop local ringing + } + } + + fp_ring_status.isLeftRinging = false; + fp_ring_status.isRightRinging = true; + + isAllowed = true; + } + break; + case 2: + if (0 == fp_ring_status.isLeftRinging) + { + if (((fp_ring_status.isRightRinging) && app_tws_is_left_side()) || + app_tws_is_right_side()) + { + isChangePeerDevStatus = true; + } + + if (isChangePeerDevStatus && !IS_CONNECTED_WITH_TWS()) + { + break; + } + + // start left ring + if (app_tws_is_right_side()) + { + // TODO: start ringing on peer device + } + else if (app_tws_is_left_side()) + { + // TODO: start local ringing + } + + if (fp_ring_status.isRightRinging) + { + // stop left ring + if (app_tws_is_left_side()) + { + // TODO: stop ringing on peer device + } + else if (app_tws_is_right_side()) + { + // TODO: stop local ringing + } + } + + fp_ring_status.isLeftRinging = true; + fp_ring_status.isRightRinging = false; + isAllowed = true; + } + break; + case 0: + if (IS_CONNECTED_WITH_TWS() && + ((1 == fp_ring_status.isLeftRinging) && + (1 == fp_ring_status.isRightRinging))) + { + // TODO: stop ringing on both sides + fp_ring_status.isLeftRinging = false; + fp_ring_status.isRightRinging = false; + + isAllowed = true; + } + else + { + if (((fp_ring_status.isLeftRinging) && app_tws_is_right_side()) || + ((fp_ring_status.isRightRinging) && app_tws_is_left_side())) + { + isChangePeerDevStatus = true; + } + + if (isChangePeerDevStatus && !IS_CONNECTED_WITH_TWS()) + { + break; + } + + // stop right ring + if (fp_ring_status.isRightRinging) + { + if (app_tws_is_left_side()) + { + // TODO: stop ringing on peer device + } + else if (app_tws_is_right_side()) + { + // TODO: stop local ringing + } + } + + if (fp_ring_status.isLeftRinging) + { + // stop left ring + if (app_tws_is_right_side()) + { + // TODO: stop ringing on peer device + } + else if (app_tws_is_left_side()) + { + // TODO: stop local ringing + } + } + + fp_ring_status.isLeftRinging = false; + fp_ring_status.isRightRinging = false; + + isAllowed = true; + } + break; + default: + isAllowed = false; + break; + } + + if (isAllowed) + { + app_fp_msg_send_message_ack(FP_MSG_GROUP_DEVICE_ACTION, FP_MSG_DEVICE_ACTION_RING); + } + else + { + app_fp_msg_send_message_nak(FP_MSG_NAK_REASON_NOT_ALLOWED, + FP_MSG_GROUP_DEVICE_ACTION, FP_MSG_DEVICE_ACTION_RING); + } +#endif +} + +#define FP_ACCUMULATED_DATA_BUF_SIZE 128 +static uint8_t fp_accumulated_data_buf[FP_ACCUMULATED_DATA_BUF_SIZE]; +static uint16_t fp_accumulated_data_size = 0; + +static void fp_rfcomm_reset_data_accumulator(void) +{ + fp_accumulated_data_size = 0; + memset(fp_accumulated_data_buf, 0, sizeof(fp_accumulated_data_buf)); +} + +static void fp_rfcomm_data_accumulator(uint8_t* ptr, uint16_t len) +{ + ASSERT((fp_accumulated_data_size + len) < sizeof(fp_accumulated_data_buf), + "fp accumulcate buffer is overflow!"); + + memcpy(&fp_accumulated_data_buf[fp_accumulated_data_size], ptr, len); + fp_accumulated_data_size += len; + + uint16_t msgTotalLen; + FP_MESSAGE_STREAM_T* msgStream; + + while (fp_accumulated_data_size >= FP_MESSAGE_RESERVED_LEN) + { + msgStream = (FP_MESSAGE_STREAM_T *)fp_accumulated_data_buf; + msgTotalLen = ((msgStream->dataLenHighByte << 8)|msgStream->dataLenLowByte) + + FP_MESSAGE_RESERVED_LEN; + ASSERT(msgTotalLen < sizeof(fp_accumulated_data_buf), + "Wrong fp msg len %d received!", msgTotalLen); + if (fp_accumulated_data_size >= msgTotalLen) + { + fp_rfcomm_data_handler(fp_accumulated_data_buf, msgTotalLen); + fp_accumulated_data_size -= msgTotalLen; + memmove(fp_accumulated_data_buf, &fp_accumulated_data_buf[msgTotalLen], + fp_accumulated_data_size); + } + else + { + break; + } + } +} + +static void fp_rfcomm_data_handler(uint8_t* ptr, uint16_t len) +{ + FP_MESSAGE_STREAM_T* pMsg = (FP_MESSAGE_STREAM_T *)ptr; + uint16_t datalen = 0; + TRACE(2,"fp rfcomm receives msg group %d code %d", + pMsg->messageGroup, pMsg->messageCode); + + switch (pMsg->messageGroup) + { + case FP_MSG_GROUP_DEVICE_INFO: + { + switch (pMsg->messageCode) + { + case FP_MSG_DEVICE_INFO_ACTIVE_COMPONENTS_REQ: + app_fp_msg_send_active_components_rsp(); + break; + case FP_MSG_DEVICE_INFO_TELL_CAPABILITIES: + fp_capabilities.content = pMsg->data[0]; + TRACE(3,"cap 0x%x isCompanionAppInstalled %d isSilentModeSupported %d", + fp_capabilities.content, fp_capabilities.env.isCompanionAppInstalled, + fp_capabilities.env.isSilentModeSupported); + break; + default: + break; + } + } + case FP_MSG_GROUP_DEVICE_ACTION: + { + switch (pMsg->messageCode) + { + case FP_MSG_DEVICE_ACTION_RING: + datalen = (pMsg->dataLenHighByte<<8)+pMsg->dataLenLowByte; + fp_rfcomm_ring_request_handling(pMsg->data, datalen); + break; + default: + break; + } + break; + } + default: + break; + } +} + +static int fp_rfcomm_data_received(void *pDev, uint8_t process, uint8_t *pData, uint16_t dataLen) +{ + TRACE(1,"%s",__func__); + //DUMP8("0x%02x ",pData, dataLen); + fp_rfcomm_data_accumulator(pData, dataLen); + return 0; +} + +static void fp_rfcomm_connected_handler(void) +{ + if (!fp_rfcomm_service.isConnected) + { + fp_rfcomm_service.isConnected = true; + + fp_rfcomm_reset_data_accumulator(); + app_fp_msg_send_model_id(); + app_fp_msg_send_updated_ble_addr(); + app_fp_msg_send_battery_levels(); + } +} + +static bool fp_rfcomm_callback(RFCOMM_EVENT_E event, + uint8_t instanceIndex, uint16_t connHandle, + uint8_t* pBtAddr, uint8_t* pSentDataBuf, uint16_t sentDataLen) +{ + TRACE(2,"%s,event is %d",__func__,event); + switch (event) + { + case RFCOMM_INCOMING_CONN_REQ: + { + TRACE(0,"Connected Indication RFComm device info:"); + TRACE(2,"hci handle is 0x%x service index %d", + connHandle, instanceIndex); + if (pBtAddr) + { + TRACE(0,"Bd addr is:"); + DUMP8("%02x ", pBtAddr, 6); + } + + fp_rfcomm_connected_handler(); + break; + } + case RFCOMM_CONNECTED: + { + if (pBtAddr) + { + TRACE(0,"Bd addr is:"); + DUMP8("%02x ", pBtAddr, 6); + } + + fp_rfcomm_connected_handler(); + break; + } + case RFCOMM_DISCONNECTED: + { + TRACE(0,"Disconnected Rfcomm device info:"); + TRACE(0,"Bd addr is:"); + DUMP8("%02x ", pBtAddr, 6); + TRACE(1,"hci handle is 0x%x", connHandle); + + TRACE(1,"::RFCOMM_DISCONNECTED %d", event); + + fp_rfcomm_service.isConnected = false; + fp_rfcomm_reset_tx_buf(); + break; + } + case RFCOMM_TX_DONE: + { + TRACE(1,"Rfcomm dataLen %d sent out", sentDataLen); + fp_rfcomm_free_tx_chunk(); + break; + } + default: + { + TRACE(1,"Unkown rfcomm event %d", event); + break; + } + } + + return true; +} + +static void app_fp_disconnect_rfcomm_handler(void) +{ + if (fp_rfcomm_service.isConnected) + { + app_rfcomm_close(fp_rfcomm_service.serviceIndex); + } +} + +void app_fp_disconnect_rfcomm(void) +{ + app_bt_start_custom_function_in_bt_thread(0, + 0, + ( uint32_t )app_fp_disconnect_rfcomm_handler); +} + +static void app_fp_rfcomm_send_handler(uint8_t *ptrData, uint32_t length) +{ + int8_t ret = app_rfcomm_write(fp_rfcomm_service.serviceIndex, ptrData, length); + if (0 != ret) + { + fp_rfcomm_free_tx_chunk(); + } +} + +void app_fp_rfcomm_send(uint8_t *ptrData, uint32_t length) +{ + if (!fp_rfcomm_service.isConnected) + { + return; + } + + int32_t chunk = fp_rfcomm_alloc_tx_chunk(); + if (-1 == chunk) + { + TRACE(0,"Fast pair rfcomm tx buffer used out!"); + return; + } + + ASSERT(length < FP_RFCOMM_TX_BUF_CHUNK_SIZE, + "FP_RFCOMM_TX_BUF_CHUNK_SIZE is %d which is smaller than %d, need to increase!", + FP_RFCOMM_TX_BUF_CHUNK_SIZE, + length); + + uint8_t *txBufAddr = fp_rfcomm_tx_buf_addr(chunk); + memcpy(txBufAddr, ptrData, length); + app_bt_start_custom_function_in_bt_thread(( uint32_t )txBufAddr, + ( uint32_t )length, + ( uint32_t )app_fp_rfcomm_send_handler); +} + +bt_status_t app_fp_rfcomm_init(void) +{ + TRACE(1,"%s",__func__); + bt_status_t stat = BT_STS_SUCCESS; + + if (!fp_rfcomm_service.isRfcommInitialized) + { + osMutexId mid; + mid = osMutexCreate(osMutex(fp_rfcomm_mutex)); + if (!mid) { + ASSERT(0, "cannot create mutex"); + } + + fp_rfcomm_service.isRfcommInitialized = true; + + RFCOMM_CONFIG_T tConfig; + tConfig.callback = fp_rfcomm_callback; + tConfig.tx_pkt_cnt = FP_RFCOMM_TX_PKT_CNT; + tConfig.rfcomm_128bit_uuid = FP_RFCOMM_UUID_128; + tConfig.rfcomm_ch = RFCOMM_CHANNEL_FP; + tConfig.app_id = BTIF_APP_SPP_SERVER_FP_RFCOMM_ID; + tConfig.spp_handle_data_event_func = fp_rfcomm_data_received; + tConfig.mutexId = mid; + tConfig.creditMutexId = osMutexCreate(osMutex(fp_rfcomm_credit_mutex)); + int8_t index = app_rfcomm_open(&tConfig); + + if (-1 == index) + { + TRACE(0,"fast pair rfcomm open failed"); + return BT_STS_FAILED; + } + + fp_rfcomm_service.isConnected = false; + fp_rfcomm_service.serviceIndex = index; + } + else + { + TRACE(0,"already initialized."); + } + + return stat; +} + +bool app_is_fp_rfcomm_connected(void) +{ + return fp_rfcomm_service.isConnected; +} + +// use cases for fp message stream +void app_fp_msg_enable_bt_silence_mode(bool isEnable) +{ + if (fp_capabilities.env.isSilentModeSupported) + { + FP_MESSAGE_STREAM_T req = {FP_MSG_GROUP_BLUETOOTH_EVENT, 0, 0, 0}; + if (isEnable) + { + req.messageCode = FP_MSG_BT_EVENT_ENABLE_SILENCE_MODE; + } + else + { + req.messageCode = FP_MSG_BT_EVENT_DISABLE_SILENCE_MODE; + } + + app_fp_rfcomm_send((uint8_t *)&req, FP_MESSAGE_RESERVED_LEN); + } + else + { + TRACE(0,"fp silence mode is not supported."); + } +} + +void app_fp_msg_send_model_id(void) +{ + TRACE(1,"%s",__func__); +#ifndef IS_USE_CUSTOM_FP_INFO + uint32_t model_id = 0x2B677D; +#else + uint32_t model_id = app_bt_get_model_id(); +#endif + uint8_t modelID[3]; + modelID[0] = (model_id >> 16) & 0xFF; + modelID[1] = (model_id >> 8) & 0xFF; + modelID[2] = ( model_id )&0xFF; + + uint16_t rawDataLen = sizeof(modelID); + + FP_MESSAGE_STREAM_T req = + {FP_MSG_GROUP_DEVICE_INFO, + FP_MSG_DEVICE_INFO_MODEL_ID, + (uint8_t)(rawDataLen >> 8), + (uint8_t)(rawDataLen & 0xFF)}; + memcpy(req.data, modelID, sizeof(modelID)); + + app_fp_rfcomm_send(( uint8_t * )&req, FP_MESSAGE_RESERVED_LEN + rawDataLen); +} + +void app_fp_msg_send_updated_ble_addr(void) +{ + FP_MESSAGE_STREAM_T req = + {FP_MSG_GROUP_DEVICE_INFO, + FP_MSG_DEVICE_INFO_BLE_ADD_UPDATED, + 0, + 6}; + + uint8_t *ptr = appm_get_current_ble_addr(); + + for (uint8_t index = 0; index < 6; index++) + { + req.data[index] = ptr[5 - index]; + } + + app_fp_rfcomm_send(( uint8_t * )&req, FP_MESSAGE_RESERVED_LEN + 6); +} + +void app_fp_msg_send_battery_levels(void) +{ + TRACE(1,"%s",__func__); + FP_MESSAGE_STREAM_T req = + {FP_MSG_GROUP_DEVICE_INFO, + FP_MSG_DEVICE_INFO_BATTERY_UPDATED, + 0, + 3}; + + uint8_t batteryLevelCount = 0; + app_gfps_get_battery_levels(&batteryLevelCount, req.data); + + app_fp_rfcomm_send(( uint8_t * )&req, FP_MESSAGE_RESERVED_LEN + 3); +} + +static __attribute__((unused)) void app_fp_msg_send_active_components_rsp(void) +{ + FP_MESSAGE_STREAM_T req = {FP_MSG_GROUP_DEVICE_INFO, FP_MSG_DEVICE_INFO_ACTIVE_COMPONENTS_RSP, 0, 1}; + +#if defined(IBRT) + if (app_tws_ibrt_tws_link_connected()) + { + req.data[0] = FP_MSG_BOTH_BUDS_ACTIVE; + } + else + { + if (app_tws_is_left_side()) + { + req.data[0] = FP_MSG_LEFT_BUD_ACTIVE; + } + else + { + req.data[0] = FP_MSG_RIGHT_BUD_ACTIVE; + } + } +#else + req.data[0] = FP_MSG_BOTH_BUDS_ACTIVE; +#endif + + app_fp_rfcomm_send((uint8_t *)&req, FP_MESSAGE_RESERVED_LEN+1); +} + +static __attribute__((unused)) void app_fp_msg_send_message_ack(uint8_t msgGroup, uint8_t msgCode) +{ + FP_MESSAGE_STREAM_T req = {FP_MSG_GROUP_ACKNOWLEDGEMENT, FP_MSG_ACK, 0, 2}; + + req.data[0] = msgGroup; + req.data[1] = msgCode; + + app_fp_rfcomm_send((uint8_t *)&req, FP_MESSAGE_RESERVED_LEN+2); +} + +static __attribute__((unused)) void app_fp_msg_send_message_nak(uint8_t reason, uint8_t msgGroup, uint8_t msgCode) +{ + FP_MESSAGE_STREAM_T req = {FP_MSG_GROUP_ACKNOWLEDGEMENT, FP_MSG_NAK, 0, 3}; + + req.data[0] = reason; + req.data[1] = msgGroup; + req.data[2] = msgCode; + + app_fp_rfcomm_send((uint8_t *)&req, FP_MESSAGE_RESERVED_LEN+3); +} + diff --git a/services/bt_app/app_fp_rfcomm.h b/services/bt_app/app_fp_rfcomm.h new file mode 100644 index 0000000..604d7e8 --- /dev/null +++ b/services/bt_app/app_fp_rfcomm.h @@ -0,0 +1,68 @@ +#ifndef __APP_FP_RFCOMM_H__ +#define __APP_FP_RFCOMM_H__ + +#define FP_MESSAGE_RESERVED_LEN 4 // at least 4 bytes +// TODO: increase this value if needed +#define FP_MESSAGE_STREAM_MAX_ADDITIONAL_DATA_LEN 16 +typedef struct +{ + uint8_t messageGroup; + uint8_t messageCode; + uint8_t dataLenHighByte; + uint8_t dataLenLowByte; + uint8_t data[FP_MESSAGE_STREAM_MAX_ADDITIONAL_DATA_LEN]; +} __attribute__((packed)) FP_MESSAGE_STREAM_T; + +// The values is posted at FP spec 8/27/19 revision +#define FP_MSG_GROUP_BLUETOOTH_EVENT 0x01 +#define FP_MSG_BT_EVENT_ENABLE_SILENCE_MODE 0x01 +#define FP_MSG_BT_EVENT_DISABLE_SILENCE_MODE 0x02 + +#define FP_MSG_GROUP_COMPANION_APP_EVENT 0x02 +#define FP_MSG_COMPANION_APP_LOG_BUF_FULL 0x01 + +#define FP_MSG_GROUP_DEVICE_INFO 0x03 +#define FP_MSG_DEVICE_INFO_MODEL_ID 0x01 +#define FP_MSG_DEVICE_INFO_BLE_ADD_UPDATED 0x02 +#define FP_MSG_DEVICE_INFO_BATTERY_UPDATED 0x03 +#define FP_MSG_DEVICE_INFO_REMAINING_BATTERY_TIME 0x04 +#define FP_MSG_DEVICE_INFO_ACTIVE_COMPONENTS_REQ 0x05 +#define FP_MSG_DEVICE_INFO_ACTIVE_COMPONENTS_RSP 0x06 +#define FP_MSG_DEVICE_INFO_TELL_CAPABILITIES 0x07 +#define FP_MSG_DEVICE_INFO_PLATFORM_TYPE 0x08 + +#define FP_MSG_GROUP_DEVICE_ACTION 0x04 +#define FP_MSG_DEVICE_ACTION_RING 0x01 + +#define FP_MSG_NEITHER_BUD_ACTIVE 0x00 +#define FP_MSG_RIGHT_BUD_ACTIVE 0x01 +#define FP_MSG_LEFT_BUD_ACTIVE 0x02 +#define FP_MSG_BOTH_BUDS_ACTIVE 0x03 + +#define FP_MSG_GROUP_ACKNOWLEDGEMENT 0xFF +#define FP_MSG_ACK 0x01 +#define FP_MSG_NAK 0x02 + +#define FP_MSG_NAK_REASON_NOT_SUPPORTED 0x00 +#define FP_MSG_NAK_REASON_DEVICE_BUSY 0x01 +#define FP_MSG_NAK_REASON_NOT_ALLOWED 0x02 + +#ifdef __cplusplus +extern "C" { +#endif + +void app_fp_rfcomm_send(uint8_t *ptrData, uint32_t length); +bt_status_t app_fp_rfcomm_init(void); +void app_fp_disconnect_rfcomm(void); +bool app_is_fp_rfcomm_connected(void); + +void app_fp_msg_enable_bt_silence_mode(bool isEnable); +void app_fp_msg_send_model_id(void); +void app_fp_msg_send_updated_ble_addr(void); +void app_fp_msg_send_battery_levels(void); + +#ifdef __cplusplus +} +#endif + +#endif // __APP_FP_RFCOMM_H__ diff --git a/services/bt_app/app_hfp.cpp b/services/bt_app/app_hfp.cpp new file mode 100644 index 0000000..ca540be --- /dev/null +++ b/services/bt_app/app_hfp.cpp @@ -0,0 +1,2154 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +//#include "mbed.h" +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_chipid.h" +#include "analog.h" +#include "app_audio.h" +#include "app_battery.h" +#include "app_status_ind.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_bt.h" +#endif +#include "hfp_api.h" +#include "besbt.h" +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "resources.h" +#include "app_bt_media_manager.h" +#include "bt_if.h" +#include "app_hfp.h" +#include "app_fp_rfcomm.h" +#include "os_api.h" +#include "app_bt_func.h" +#ifdef BT_USB_AUDIO_DUAL_MODE +#include "btusb_audio.h" +#endif +#ifdef __THIRDPARTY +#include "app_thirdparty.h" +#endif + +#include "bt_drv_interface.h" + +#ifdef __IAG_BLE_INCLUDE__ +#include "app_ble_mode_switch.h" +#endif + +#ifdef VOICE_DATAPATH +#include "app_voicepath.h" +#endif +#include "app.h" +#ifdef __AI_VOICE__ +#include "ai_control.h" +#endif + +#if defined(IBRT) +#include "app_ibrt_if.h" +#include "app_tws_ibrt_cmd_sync_hfp_status.h" +#include "app_ibrt_hf.h" +#include "besaud_api.h" +#endif + +#include "bt_drv_reg_op.h" + +#ifdef BISTO_ENABLED +#include "gsound_custom_bt.h" +#endif + +#if defined(__BTMAP_ENABLE__) +#include "app_btmap_sms.h" +#endif + + +#ifdef __INTERCONNECTION__ +#define HF_COMMAND_HUAWEI_BATTERY_HEAD "AT+HUAWEIBATTERY=" +#define BATTERY_REPORT_NUM 2 +#define BATTERY_REPORT_TYPE_BATTERY_LEVEL 1 +#define BATTERY_REPORT_KEY_LEFT_BATTERY_LEVEL 2 +#define BATTERY_REPORT_KEY_LEFT_CHARGE_STATE 3 +char ATCommand[42]; +const char* huawei_self_defined_command_response = "+HUAWEIBATTERY=OK"; +#endif + +/* hfp */ +int store_voicebtpcm_m2p_buffer(unsigned char *buf, unsigned int len); +int get_voicebtpcm_p2m_frame(unsigned char *buf, unsigned int len); + +int store_voicecvsd_buffer(unsigned char *buf, unsigned int len); +int store_voicemsbc_buffer(unsigned char *buf, unsigned int len); + +void btapp_hfp_mic_need_skip_frame_set(int32_t skip_frame); +void a2dp_dual_slave_handling_refresh(void); +void a2dp_dual_slave_setup_during_sco(enum BT_DEVICE_ID_T currentId); + +extern "C" bool bt_media_cur_is_bt_stream_media(void); +bool bt_is_sco_media_open(); +extern bool app_audio_list_playback_exist(void); +#ifdef GFPS_ENABLED +extern "C" void app_exit_fastpairing_mode(void); +#endif + +extern void app_bt_profile_connect_manager_hf(enum BT_DEVICE_ID_T id, hf_chan_handle_t Chan, struct hfp_context *ctx); +#ifdef __BT_ONE_BRING_TWO__ +extern void hfcall_next_sta_handler(hf_event_t event); +#endif +#ifndef _SCO_BTPCM_CHANNEL_ +struct hf_sendbuff_control hf_sendbuff_ctrl; +#endif +#ifdef __INTERACTION__ +const char* oppo_self_defined_command_response = "+VDSF:7"; +#endif +#if defined(SCO_LOOP) +#define HF_LOOP_CNT (20) +#define HF_LOOP_SIZE (360) + +static uint8_t hf_loop_buffer[HF_LOOP_CNT*HF_LOOP_SIZE]; +static uint32_t hf_loop_buffer_len[HF_LOOP_CNT]; +static uint32_t hf_loop_buffer_valid = 1; +static uint32_t hf_loop_buffer_size = 0; +static char hf_loop_buffer_w_idx = 0; +#endif + +static void app_hfp_set_starting_media_pending_flag(bool isEnabled, uint8_t devId); +void app_hfp_resume_pending_voice_media(void); + +static void app_hfp_mediaplay_delay_resume_timer_cb(void const *n) +{ + app_hfp_resume_pending_voice_media(); +} + +#define HFP_MEDIAPLAY_DELAY_RESUME_IN_MS 3000//This time must be greater than SOUND_CONNECTED play time. +static void app_hfp_mediaplay_delay_resume_timer_cb(void const *n); +osTimerDef (APP_HFP_MEDIAPLAY_DELAY_RESUME_TIMER, app_hfp_mediaplay_delay_resume_timer_cb); +osTimerId app_hfp_mediaplay_delay_resume_timer_id = NULL; + +#ifdef __IAG_BLE_INCLUDE__ +static void app_hfp_resume_ble_adv(void); +#endif + +#define HFP_AUDIO_CLOSED_DELAY_RESUME_ADV_IN_MS 1500 +static void app_hfp_audio_closed_delay_resume_ble_adv_timer_cb(void const *n); +osTimerDef (APP_HFP_AUDIO_CLOSED_DELAY_RESUME_BLE_ADV_TIMER, + app_hfp_audio_closed_delay_resume_ble_adv_timer_cb); +osTimerId app_hfp_audio_closed_delay_resume_ble_adv_timer_id = NULL; + +extern struct BT_DEVICE_T app_bt_device; + +#if defined(SUPPORT_BATTERY_REPORT) || defined(SUPPORT_HF_INDICATORS) +#ifdef __BT_ONE_BRING_TWO__ + static uint8_t battery_level[BT_DEVICE_NUM] = {0xff, 0xff}; +#else + static uint8_t battery_level[BT_DEVICE_NUM] = {0xff}; +#endif + +static uint8_t report_battery_level = 0xff; +void app_hfp_set_battery_level(uint8_t level) +{ + osapi_lock_stack(); + if (report_battery_level == 0xff) { + report_battery_level = level; + osapi_notify_evm(); + } + osapi_unlock_stack(); +} + +int app_hfp_battery_report_reset(uint8_t bt_device_id) +{ + ASSERT(bt_device_id < BT_DEVICE_NUM, "bt_device_id error"); + battery_level[bt_device_id] = 0xff; + return 0; +} + + +#ifdef __INTERACTION_CUSTOMER_AT_COMMAND__ +#define HF_COMMAND_BATTERY_HEAD "AT+VDBTY=" +#define HF_COMMAND_VERSION_HEAD "AT+VDRV=" +#define HF_COMMAND_FEATURE_HEAD "AT+VDSF=" +#define REPORT_NUM 3 +#define LEFT_UNIT_REPORT 1 +#define RIGHT_UNIT_REPORT 2 +#define BOX_REPORT 3 +char ATCommand[42]; + +bt_status_t Send_customer_battery_report_AT_command(hf_chan_handle_t chan_h, uint8_t level) +{ + TRACE(0,"Send battery report at commnad."); + /// head and keyNumber + sprintf(ATCommand, "%s%d", HF_COMMAND_BATTERY_HEAD,REPORT_NUM); + /// keys and corresponding values + sprintf(ATCommand, "%s,%d,%d,%d,%d,%d,%d\r", ATCommand, LEFT_UNIT_REPORT, level, RIGHT_UNIT_REPORT, level, BOX_REPORT, 9); + /// send AT command + return btif_hf_send_at_cmd(chan_h, ATCommand); +} + +bt_status_t Send_customer_phone_feature_support_AT_command(hf_chan_handle_t chan_h, uint8_t val) +{ + TRACE(0,"Send_customer_phone_feature_support_AT_command."); + /// keys and corresponding values + sprintf(ATCommand, "%s%d\r", HF_COMMAND_FEATURE_HEAD,val); + /// send AT command + return btif_hf_send_at_cmd(chan_h, ATCommand); +} + +bt_status_t Send_customer_version_report_AT_command(hf_chan_handle_t chan_h) +{ + TRACE(0,"Send version report at commnad."); + /// head and keyNumber + sprintf(ATCommand, "%s%d", HF_COMMAND_VERSION_HEAD,REPORT_NUM); + /// keys and corresponding values + sprintf(ATCommand, "%s,%d,%d,%d,%d,%d,%d\r", ATCommand, LEFT_UNIT_REPORT, 0x1111, RIGHT_UNIT_REPORT, 0x2222, BOX_REPORT,0x3333); + /// send AT command + return btif_hf_send_at_cmd(chan_h, ATCommand); +} +#endif + +#ifdef __INTERCONNECTION__ +uint8_t ask_is_selfdefined_battery_report_AT_command_support(void) +{ + TRACE(0,"ask if mobile support self-defined at commnad."); + uint8_t *pSelfDefinedCommandSupport = app_battery_get_mobile_support_self_defined_command_p(); + *pSelfDefinedCommandSupport = 0; + + sprintf(ATCommand, "%s?", HF_COMMAND_HUAWEI_BATTERY_HEAD); + btif_hf_send_at_cmd((hf_chan_handle_t)app_bt_device.hf_channel[BT_DEVICE_ID_1], ATCommand); + + return 0; +} + + +uint8_t send_selfdefined_battery_report_AT_command(void) +{ + uint8_t *pSelfDefinedCommandSupport = app_battery_get_mobile_support_self_defined_command_p(); + uint8_t batteryInfo = 0; + + if(*pSelfDefinedCommandSupport) + { + app_battery_get_info(NULL, &batteryInfo, NULL); + + /// head and keyNumber + sprintf(ATCommand, "%s%d", HF_COMMAND_HUAWEI_BATTERY_HEAD, BATTERY_REPORT_NUM); + + /// keys and corresponding values + sprintf(ATCommand, "%s,%d,%d,%d,%d", ATCommand, BATTERY_REPORT_KEY_LEFT_BATTERY_LEVEL, batteryInfo&0x7f, BATTERY_REPORT_KEY_LEFT_CHARGE_STATE, (batteryInfo&0x80)?1:0); + + /// send AT command + btif_hf_send_at_cmd((hf_chan_handle_t)app_bt_device.hf_channel[BT_DEVICE_ID_1], ATCommand); + } + return 0; +} +#endif + +int app_hfp_battery_report(uint8_t level) +{ + // Care: BT_DEVICE_NUM<-->{0xff, 0xff, ...} + bt_status_t status = BT_STS_LAST_CODE; + hf_chan_handle_t chan; + + uint8_t i; + int nRet = 0; + + if (level>9) + return -1; + + for(i=0; iclose"); + hf_id = BT_DEVICE_ID_1; + en = false; + hf_siri_chnl = app_bt_device.hf_channel[BT_DEVICE_ID_1]; + } +#ifdef __BT_ONE_BRING_TWO__ + else if(btif_hf_is_voice_rec_active(app_bt_device.hf_channel[BT_DEVICE_ID_2]) == true){ + TRACE(0,"2->close"); + hf_id = BT_DEVICE_ID_2; + en = false; + hf_siri_chnl = app_bt_device.hf_channel[BT_DEVICE_ID_2]; + } +#endif + else{ + open_siri_flag =1; + en = true; +#ifdef __BT_ONE_BRING_TWO__ + hf_id = (enum BT_DEVICE_ID_T)app_hfp_get_chnl_via_remDev(&hf_siri_chnl); +#else + hf_id = BT_DEVICE_ID_1; +#endif + TRACE(1,"a2dp id = %d",hf_id); + } + } + TRACE(4,"[%s]id =%d/%d/%d",__func__,hf_id,open_siri_flag,en); + if(hf_id == BT_DEVICE_NUM) + hf_id = BT_DEVICE_ID_1; + + if((btif_get_hf_chan_state(app_bt_device.hf_channel[hf_id]) == BTIF_HF_STATE_OPEN)) { + res = btif_hf_enable_voice_recognition(app_bt_device.hf_channel[hf_id], en); + } + + TRACE(3,"[%s] Line =%d, res = %d", __func__, __LINE__, res); + + return 0; +} +#endif + +#define _THREE_WAY_ONE_CALL_COUNT__ 1 +#ifdef _THREE_WAY_ONE_CALL_COUNT__ +static enum BT_DEVICE_ID_T hfp_cur_call_chnl = BT_DEVICE_NUM; +static int8_t cur_chnl_call_on_active[BT_DEVICE_NUM] = {0}; +int app_bt_get_audio_up_id(void); + +void app_hfp_3_way_call_counter_set(enum BT_DEVICE_ID_T id,uint8_t set) +{ + if (set > 0) { + cur_chnl_call_on_active[id]++; + if (cur_chnl_call_on_active[id] > BT_DEVICE_NUM) + cur_chnl_call_on_active[id] = 2; + } else { + cur_chnl_call_on_active[id]--; + if (cur_chnl_call_on_active[id] < 0) + cur_chnl_call_on_active[id] = 0; + if (app_bt_device.hfchan_call[id] == 1) + cur_chnl_call_on_active[id] = 1; + } + TRACE(1,"call_on_active = %d",cur_chnl_call_on_active[id]); +} + +void app_hfp_set_cur_chnl_id(uint8_t id) +{ + if (hfp_cur_call_chnl == BT_DEVICE_NUM) { + hfp_cur_call_chnl = (enum BT_DEVICE_ID_T)id; + cur_chnl_call_on_active[id] = 1; + } + TRACE(3,"%s hfp_cur_call_chnl = %d id=%d",__func__,hfp_cur_call_chnl,id); +} + +uint8_t app_hfp_get_cur_call_chnl(void ** chnl) +{ + TRACE(2,"%s hfp_cur_call_chnl = %d",__func__,hfp_cur_call_chnl); + if(hfp_cur_call_chnl != BT_DEVICE_NUM){ + return hfp_cur_call_chnl; + } + return BT_DEVICE_NUM; +} + +void app_hfp_clear_cur_call_chnl(enum BT_DEVICE_ID_T id) +{ + hfp_cur_call_chnl = BT_DEVICE_NUM; + cur_chnl_call_on_active[id] = 0; + TRACE(2,"%s id= %d",__func__,id); +} + +void app_hfp_cur_call_chnl_reset(enum BT_DEVICE_ID_T id) +{ + if(id == hfp_cur_call_chnl) + hfp_cur_call_chnl = BT_DEVICE_NUM; + TRACE(3,"%s hfp_cur_call_chnl = %d id=%d",__func__,hfp_cur_call_chnl,id); +} + +bool app_hfp_cur_chnl_is_on_3_way_calling(void) +{ + uint8_t i = 0; + TRACE(1,"hfp_cur_call_chnl = %d",hfp_cur_call_chnl); +#ifdef __BT_ONE_BRING_TWO__ + TRACE(2,"cur_chnl_call_on_active[0] = %d [1] = %d",cur_chnl_call_on_active[0], + cur_chnl_call_on_active[1]); +#else + TRACE(1,"cur_chnl_call_on_active[0] = %d",cur_chnl_call_on_active[0]); +#endif + if(hfp_cur_call_chnl == BT_DEVICE_NUM) + return false; + for(i=0;i1){ + break; + } + } + if(i == BT_DEVICE_NUM) + return false; + return true; +} +#endif +#if !defined(FPGA) && defined(__BTIF_EARPHONE__) +static void hfp_app_status_indication(enum BT_DEVICE_ID_T chan_id, struct hfp_context *ctx) +{ +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T chan_id_other = (chan_id==BT_DEVICE_ID_1)?(BT_DEVICE_ID_2):(BT_DEVICE_ID_1); +#else + enum BT_DEVICE_ID_T chan_id_other =BT_DEVICE_ID_1; +#endif + switch(ctx->event) + { + /* + case HF_EVENT_SERVICE_CONNECTED: + break; + case HF_EVENT_SERVICE_DISCONNECTED: + break; + */ + case BTIF_HF_EVENT_CURRENT_CALL_STATE: + TRACE(2,"!!!HF_EVENT_CURRENT_CALL_STATE chan_id:%d, call_number:%s\n", chan_id, ctx->call_number); + if(app_bt_device.hfchan_callSetup[chan_id] == BTIF_HF_CALL_SETUP_IN){ + //////report incoming call number + //app_status_set_num(ctx->call_number); +#ifdef __BT_WARNING_TONE_MERGE_INTO_STREAM_SBC__ + app_voice_report(APP_STATUS_RING_WARNING,chan_id); +#endif + } + break; + case BTIF_HF_EVENT_CALL_IND: + if(ctx->call == BTIF_HF_CALL_NONE && app_bt_device.hfchan_call[chan_id] == BTIF_HF_CALL_ACTIVE){ + //////report call hangup voice + TRACE(1,"!!!HF_EVENT_CALL_IND APP_STATUS_INDICATION_HANGUPCALL chan_id:%d\n",chan_id); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP_MEDIA,BT_STREAM_VOICE,chan_id,0); + ///disable media prompt + if(app_bt_device.hf_endcall_dis[chan_id] == false) + { + TRACE(0,"HANGUPCALL PROMPT"); + //app_voice_report(APP_STATUS_INDICATION_HANGUPCALL,chan_id); + } +#if defined(_THREE_WAY_ONE_CALL_COUNT__) + if(app_hfp_get_cur_call_chnl(NULL) == chan_id){ + app_hfp_clear_cur_call_chnl(chan_id); + } +#endif + } +#if defined(_THREE_WAY_ONE_CALL_COUNT__) + else if((ctx->call == BTIF_HF_CALL_ACTIVE) && + (app_bt_get_audio_up_id() == chan_id)) + { + app_hfp_set_cur_chnl_id(chan_id); + } +#endif + break; + case BTIF_HF_EVENT_CALLSETUP_IND: + if(ctx->call_setup == BTIF_HF_CALL_SETUP_NONE && + (app_bt_device.hfchan_call[chan_id] != BTIF_HF_CALL_ACTIVE) && + (app_bt_device.hfchan_callSetup[chan_id] != BTIF_HF_CALL_SETUP_NONE)) { + ////check the call refuse and stop media of (ring and call number) + TRACE(1,"!!!HF_EVENT_CALLSETUP_IND APP_STATUS_INDICATION_REFUSECALL chan_id:%d\n",chan_id); + #if 0//def __BT_ONE_BRING_TWO__ + if (app_bt_device.hf_audio_state[chan_id_other] == BTIF_HF_AUDIO_DISCON){ + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP_MEDIA,BT_STREAM_VOICE,chan_id,0); + app_voice_report(APP_STATUS_INDICATION_REFUSECALL,chan_id); + } + #else + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP_MEDIA,BT_STREAM_VOICE,chan_id,0); +#if !defined(IBRT) && defined(MEDIA_PLAYER_SUPPORT) + app_voice_report(APP_STATUS_INDICATION_REFUSECALL,chan_id);/////////////du���� +#endif + #endif + if((app_bt_device.hfchan_call[chan_id_other] == BTIF_HF_CALL_ACTIVE) && + (app_bt_device.hf_audio_state[chan_id_other] == BTIF_HF_AUDIO_CON)){ + app_bt_device.curr_hf_channel_id = chan_id_other; + } + }else if(ctx->call_setup == BTIF_HF_CALL_SETUP_NONE && + (app_bt_device.hfchan_callSetup[chan_id] != BTIF_HF_CALL_SETUP_NONE) && + (app_bt_device.hfchan_call[chan_id] == BTIF_HF_CALL_ACTIVE)){ + TRACE(1,"!!!HF_EVENT_CALLSETUP_IND APP_STATUS_INDICATION_ANSWERCALL but noneed sco chan_id:%d\n",chan_id); +#ifdef _THREE_WAY_ONE_CALL_COUNT__ + if(app_bt_device.hf_callheld[chan_id] == BTIF_HF_CALL_HELD_NONE) { + if(app_hfp_get_cur_call_chnl(NULL) == chan_id) { + app_hfp_3_way_call_counter_set(chan_id,0); + } + } +#endif /* _THREE_WAY_ONE_CALL_COUNT__ */ + +#ifdef MEDIA_PLAYER_SUPPORT + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP_MEDIA, BT_STREAM_MEDIA ,chan_id, 0); +#endif + } +#if defined(_THREE_WAY_ONE_CALL_COUNT__) + else if((ctx->call_setup != BTIF_HF_CALL_SETUP_NONE) && + (app_bt_device.hfchan_call[chan_id] == BTIF_HF_CALL_ACTIVE)){ + if(app_hfp_get_cur_call_chnl(NULL) == chan_id){ + app_hfp_3_way_call_counter_set(chan_id,1); + } + } +#endif + break; + /* + case HF_EVENT_AUDIO_CONNECTED: + TRACE(1,"!!!HF_EVENT_AUDIO_CONNECTED APP_STATUS_INDICATION_ANSWERCALL chan_id:%d\n",chan_id); + // app_voice_report(APP_STATUS_INDICATION_ANSWERCALL,chan_id);//////////////duһ�� + break; + */ + case BTIF_HF_EVENT_RING_IND: +#ifdef MEDIA_PLAYER_SUPPORT + app_voice_report(APP_STATUS_INDICATION_INCOMINGCALL,chan_id); +#endif + break; + default: + break; + } +} +#endif + + +struct BT_DEVICE_ID_DIFF chan_id_flag; +#ifdef __BT_ONE_BRING_TWO__ +void hfp_chan_id_distinguish(hf_chan_handle_t chan) +{ + if(chan == app_bt_device.hf_channel[BT_DEVICE_ID_1]){ + chan_id_flag.id = BT_DEVICE_ID_1; + }else if(chan == app_bt_device.hf_channel[BT_DEVICE_ID_2]){ + chan_id_flag.id = BT_DEVICE_ID_2; + } +} +#endif + +int hfp_volume_get(enum BT_DEVICE_ID_T id) +{ + int vol = TGT_VOLUME_LEVEL_15; + + nvrec_btdevicerecord *record = NULL; + bt_bdaddr_t bdAdd; + if (btif_hf_get_remote_bdaddr(app_bt_device.hf_channel[id], &bdAdd) && !nv_record_btdevicerecord_find(&bdAdd,&record)){ + vol = record->device_vol.hfp_vol - 2; + }else if (app_audio_manager_hfp_is_active(id)){ + vol = app_bt_stream_hfpvolume_get() - 2; + }else{ + vol = TGT_VOLUME_LEVEL_15; + } + + if (vol > 15) + vol = 15; + if (vol < 0) + vol = 0; + +#ifndef BES_AUTOMATE_TEST + TRACE(2,"hfp get vol raw:%d loc:%d", vol, vol+2); +#endif + return (vol); +} + +void hfp_volume_local_set(enum BT_DEVICE_ID_T id, int8_t vol) +{ + nvrec_btdevicerecord *record = NULL; + bt_bdaddr_t bdAdd; + if (btif_hf_get_remote_bdaddr(app_bt_device.hf_channel[id], &bdAdd)){ + if (!nv_record_btdevicerecord_find(&bdAdd,&record)){ + nv_record_btdevicerecord_set_hfp_vol(record, vol); + } + } + + if(app_bt_stream_volume_get_ptr()->hfp_vol != vol){ +#if defined(NEW_NV_RECORD_ENABLED) + nv_record_btdevicevolume_set_hfp_vol(app_bt_stream_volume_get_ptr(), vol); +#endif +#ifndef FPGA + nv_record_touch_cause_flush(); +#endif + } +} + +int hfp_volume_set(enum BT_DEVICE_ID_T id, int vol) +{ + if (vol > 15) + vol = 15; + if (vol < 0) + vol = 0; + + hfp_volume_local_set(id, vol+2); + if (app_audio_manager_hfp_is_active(id)){ + app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_SET, vol+2); + } + + TRACE(2,"hfp put vol raw:%d loc:%d", vol, vol+2); + return 0; +} + +static uint8_t call_setup_running_on = 0; +void hfp_call_setup_running_on_set(uint8_t set) +{ + call_setup_running_on = set; +} + +void hfp_call_setup_running_on_clr(void) +{ + call_setup_running_on = 0; +} + +uint8_t hfp_get_call_setup_running_on_state(void) +{ + TRACE(2,"%s state = %d",__func__,call_setup_running_on); + return call_setup_running_on; +} + +static void hfp_connected_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1; +#endif + +#ifdef GFPS_ENABLED + app_exit_fastpairing_mode(); +#endif + + app_bt_clear_connecting_profiles_state(chan_id_flag.id); + + TRACE(1,"::HF_EVENT_SERVICE_CONNECTED Chan_id:%d\n", chan_id_flag.id); + app_bt_device.phone_earphone_mark = 1; + +#if !defined(FPGA) && defined(__BTIF_EARPHONE__) + if (ctx->state == BTIF_HF_STATE_OPEN) { + ////report connected voice + app_bt_device.hf_conn_flag[chan_id_flag.id] = 1; + } +#endif +#if defined(SUPPORT_BATTERY_REPORT) || defined(SUPPORT_HF_INDICATORS) + uint8_t battery_level; + app_hfp_battery_report_reset(chan_id_flag.id); + app_battery_get_info(NULL, &battery_level, NULL); + app_hfp_set_battery_level(battery_level); +#endif + // app_bt_stream_hfpvolume_reset(); + btif_hf_report_speaker_volume(chan, hfp_volume_get(chan_id_flag.id)); + +#if defined(HFP_DISABLE_NREC) + btif_hf_disable_nrec(chan); +#endif + +#ifdef __BT_ONE_BRING_TWO__ + ////if a call is active and start bt open reconnect procedure, process the curr_hf_channel_id + if((app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON) + ||(app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_IN)){ + app_bt_device.curr_hf_channel_id = anotherDevice; + }else{ + app_bt_device.curr_hf_channel_id = chan_id_flag.id; + } +#endif + +#if defined(__BTMAP_ENABLE__) && defined(BTIF_DIP_DEVICE) + if ((btif_dip_get_process_status(app_bt_get_remoteDev(chan_id_flag.id)))&& (app_btmap_check_is_idle(chan_id_flag.id))) + { + app_btmap_sms_open(chan_id_flag.id, &ctx->remote_dev_bdaddr); + } +#endif + + app_bt_profile_connect_manager_hf(chan_id_flag.id, chan, ctx); +#ifdef __INTERCONNECTION__ + ask_is_selfdefined_battery_report_AT_command_support(); +#endif +#ifdef __INTERACTION_CUSTOMER_AT_COMMAND__ + Send_customer_phone_feature_support_AT_command(chan,7); + Send_customer_battery_report_AT_command(chan, battery_level); +#endif +} + +static void hfp_disconnected_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ + TRACE(2,"::HF_EVENT_SERVICE_DISCONNECTED Chan_id:%d, reason=%x\n", chan_id_flag.id, ctx->disc_reason); +#if defined(HFP_1_6_ENABLE) + btif_hf_set_negotiated_codec(chan, BTIF_HF_SCO_CODEC_CVSD); +#endif +#if !defined(FPGA) && defined(__BTIF_EARPHONE__) + if(app_bt_device.hf_conn_flag[chan_id_flag.id] ){ + ////report device disconnected voice + app_bt_device.hf_conn_flag[chan_id_flag.id] = 0; + } +#endif + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_VOICE,chan_id_flag.id,MAX_RECORD_NUM); + for (uint8_t i=0; iaudio_data, ctx->audio_data_len); + + idx = hf_sendbuff_ctrl.index % HF_SENDBUFF_MEMPOOL_NUM; + get_voicebtpcm_p2m_frame(&(hf_sendbuff_ctrl.mempool[idx].buffer[0]), ctx->audio_data_len); + hf_sendbuff_ctrl.mempool[idx].packet.data = &(hf_sendbuff_ctrl.mempool[idx].buffer[0]); + hf_sendbuff_ctrl.mempool[idx].packet.dataLen = ctx->audio_data_len; + hf_sendbuff_ctrl.mempool[idx].packet.flags = BTIF_BTP_FLAG_NONE; + if(!app_bt_device.hf_mute_flag){ + btif_hf_send_audio_data(chan, &hf_sendbuff_ctrl.mempool[idx].packet); + } + hf_sendbuff_ctrl.index++; + } +#endif + +#ifdef __BT_ONE_BRING_TWO__ + } +#endif + +#if defined(SCO_LOOP) + memcpy(hf_loop_buffer + hf_loop_buffer_w_idx*HF_LOOP_SIZE, Info->p.audioData->data, Info->p.audioData->len); + hf_loop_buffer_len[hf_loop_buffer_w_idx] = Info->p.audioData->len; + hf_loop_buffer_w_idx = (hf_loop_buffer_w_idx+1)%HF_LOOP_CNT; + ++hf_loop_buffer_size; + + if (hf_loop_buffer_size >= 18 && hf_loop_buffer_valid == 1) { + hf_loop_buffer_valid = 0; + idx = hf_loop_buffer_w_idx-17<0?(HF_LOOP_CNT-(17-hf_loop_buffer_w_idx)):hf_loop_buffer_w_idx-17; + pkt.flags = BTP_FLAG_NONE; + pkt.dataLen = hf_loop_buffer_len[idx]; + pkt.data = hf_loop_buffer + idx*HF_LOOP_SIZE; + HF_SendAudioData(Chan, &pkt); + } +#endif +} + +static void hfp_call_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1; +#endif + +#ifdef __BT_ONE_BRING_TWO__ + TRACE(8,"::HF_EVENT_CALL_IND %d chan_id %dx call %d %d held %d %d audio_state %d %d\n", + ctx->call, chan_id_flag.id, + app_bt_device.hfchan_call[BT_DEVICE_ID_1], app_bt_device.hfchan_call[BT_DEVICE_ID_2], + app_bt_device.hf_callheld[BT_DEVICE_ID_1], app_bt_device.hf_callheld[BT_DEVICE_ID_2], + app_bt_device.hf_audio_state[BT_DEVICE_ID_1], app_bt_device.hf_audio_state[BT_DEVICE_ID_2]); +#else + TRACE(2,"::HF_EVENT_CALL_IND chan_id:%d, call:%d\n",chan_id_flag.id, ctx->call); +#endif + if(ctx->call == BTIF_HF_CALL_NONE) + { + hfp_call_setup_running_on_clr(); +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("Call hangup ok."); +#endif + app_bt_device.hf_callheld[chan_id_flag.id] = BTIF_HF_CALL_HELD_NONE; + } + else if(ctx->call == BTIF_HF_CALL_ACTIVE) + { +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("Call setup ok."); +#endif + + ///call is active so check if it's a outgoing call + if(app_bt_device.hfchan_callSetup[chan_id_flag.id] == BTIF_HF_CALL_SETUP_ALERT) + { + TRACE(1,"HF CALLACTIVE TIME=%d",hal_sys_timer_get()); + if(TICKS_TO_MS(hal_sys_timer_get()-app_bt_device.hf_callsetup_time[chan_id_flag.id])<1000) + { + TRACE(0,"DISABLE HANGUPCALL PROMPT"); + app_bt_device.hf_endcall_dis[chan_id_flag.id] = true; + } + } + /////stop media of (ring and call number) and switch to sco +#if defined (HFP_NO_PRERMPT) + if(app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE){ + }else +#endif + { +#ifdef __BT_ONE_BRING_TWO__ + TRACE(1,"%s another %d,hf_callheld %d",__func__,anotherDevice,app_bt_device.hf_callheld[anotherDevice]); + if((btapp_hfp_get_call_state()) + &&(app_bt_device.hf_callheld[anotherDevice] == BTIF_HF_CALL_HELD_NONE)) +#else + if(btapp_hfp_get_call_state()) +#endif + { + TRACE(0,"DON'T SIWTCH_TO_SCO"); + app_bt_device.hfchan_call[chan_id_flag.id] = ctx->call; + return; + } + else + { +#ifndef ENABLE_HFP_AUDIO_PENDING_FOR_MEDIA + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_SWITCHTO_SCO,BT_STREAM_VOICE,chan_id_flag.id,0); +#endif + } + } + } + else + { +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("Call hangup ok."); +#endif + } + + +#if !defined(FPGA) && defined(__BTIF_EARPHONE__) + hfp_app_status_indication(chan_id_flag.id, ctx); +#endif + + + if(ctx->call == BTIF_HF_CALL_ACTIVE){ +#if defined (HFP_NO_PRERMPT) +#else + app_bt_device.curr_hf_channel_id = chan_id_flag.id; +#endif + } +#ifdef __BT_ONE_BRING_TWO__ + else if((ctx->call == BTIF_HF_CALL_NONE)&& + ((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE)|| + (app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_IN)|| + (app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_OUT) || + (app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_ALERT))){ + app_bt_device.curr_hf_channel_id = anotherDevice; + } +#endif + TRACE(1,"!!!HF_EVENT_CALL_IND curr_hf_channel_id:%d\n",app_bt_device.curr_hf_channel_id); + app_bt_device.hfchan_call[chan_id_flag.id] = ctx->call; + if(ctx->call == BTIF_HF_CALL_NONE) + { + app_bt_device.hf_endcall_dis[chan_id_flag.id] = false; + } +#if defined( __BT_ONE_BRING_TWO__) + if(bt_get_sco_number() > 1 +#ifdef CHIP_BEST1000 + && hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2 +#endif + ){ + ////a call is active: + if(app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_ACTIVE){ +#if !defined(HFP_NO_PRERMPT) + if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){ + app_bt_device.curr_hf_channel_id = chan_id_flag.id; +#ifdef __HF_KEEP_ONE_ALIVE__ +#ifdef ENABLE_HFP_AUDIO_PENDING_FOR_MEDIA + if (bt_media_cur_is_bt_stream_media()) + { + app_hfp_set_starting_media_pending_flag(true, chan_id_flag.id); + } + else +#endif + { + app_hfp_start_voice_media(chan_id_flag.id); + } +#else + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_SWAP_SCO,BT_STREAM_SBC, chan_id_flag.id, 0); +#endif + } + app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_ENABLE; + app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_DISABLE; +#endif + }else{ + ////a call is hung up: + ///if one device setup a sco connect so get the other device's sco state, if both connect mute the earlier one + if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){ + app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_ENABLE; + app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_DISABLE; + } + } + } +#endif + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_UPDATE_MEDIA,BT_STREAM_VOICE,chan_id_flag.id,MAX_RECORD_NUM); +} + +extern uint8_t once_event_case; +extern void startonce_delay_event_Timer_(int ms); +extern void bt_drv_clear_skip_flag(); +static void hfp_callsetup_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ +#ifdef __BT_ONE_BRING_TWO__ + //clear flag_skip_resv and flag_skip_retx + bt_drv_clear_skip_flag(); + enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1; +#endif + + TRACE(2,"::HF_EVENT_CALLSETUP_IND chan_id:%d, callSetup =%d\n", chan_id_flag.id, ctx->call_setup); + if(ctx->call_setup == 0x03) + { + once_event_case = 8; + startonce_delay_event_Timer_(1000); + } + if((ctx->call_setup & 0x03) != 0){ + hfp_call_setup_running_on_set(1); + } +#if !defined(FPGA) && defined(__BTIF_EARPHONE__) + hfp_app_status_indication(chan_id_flag.id, ctx); +#endif + + if (BTIF_HF_CALL_SETUP_NONE != ctx->call_setup) + { + // exit sniff mode and stay active + app_bt_active_mode_set(ACTIVE_MODE_KEEPEER_SCO_STREAMING, + UPDATE_ACTIVE_MODE_FOR_ALL_LINKS); + } + else + { + // resume sniff mode + app_bt_active_mode_clear(ACTIVE_MODE_KEEPEER_SCO_STREAMING, + UPDATE_ACTIVE_MODE_FOR_ALL_LINKS); + } + +#ifdef __BT_ONE_BRING_TWO__ + TRACE(2,"call [0]/[1] =%d / %d",app_bt_device.hfchan_call[BT_DEVICE_ID_1],app_bt_device.hfchan_call[BT_DEVICE_ID_2]); + TRACE(2,"audio [0]/[1] =%d / %d",app_bt_device.hf_audio_state[BT_DEVICE_ID_1],app_bt_device.hf_audio_state[BT_DEVICE_ID_2]); + + app_bt_device.callSetupBitRec |= (1 << ctx->call_setup); + if(ctx->call_setup == 0){ + //do nothing + }else{ + +#ifdef BT_USB_AUDIO_DUAL_MODE + if(!btusb_is_bt_mode()) + { + TRACE(0,"btusb_usbaudio_close doing."); + btusb_usbaudio_close(); + } +#endif +#if defined (HFP_NO_PRERMPT) + if(((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE)&& + (app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_NONE))|| + ((app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_IN)&& + (app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_NONE))){ + app_bt_device.curr_hf_channel_id = anotherDevice; + } + else if((app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_ACTIVE)&& + (app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE)){ + }else{ + app_bt_device.curr_hf_channel_id = chan_id_flag.id; + } +#else + if((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE)||((app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_IN)&&(app_bt_device.hfchan_call[chan_id_flag.id] != BTIF_HF_CALL_ACTIVE))){ + app_bt_device.curr_hf_channel_id = anotherDevice; + }else{ + app_bt_device.curr_hf_channel_id = chan_id_flag.id; + } +#endif + } + TRACE(1,"!!!HF_EVENT_CALLSETUP_IND curr_hf_channel_id:%d\n",app_bt_device.curr_hf_channel_id); +#endif + app_bt_device.hfchan_callSetup[chan_id_flag.id] = ctx->call_setup; + /////call is alert so remember this time + if(app_bt_device.hfchan_callSetup[chan_id_flag.id] == BTIF_HF_CALL_SETUP_ALERT ) + { + TRACE(1,"HF CALLSETUP TIME=%d",hal_sys_timer_get()); + app_bt_device.hf_callsetup_time[chan_id_flag.id] = hal_sys_timer_get(); + } + if(app_bt_device.hfchan_callSetup[chan_id_flag.id]== BTIF_HF_CALL_SETUP_IN){ + btif_hf_list_current_calls(chan); + } + + if((app_bt_device.hfchan_callSetup[chan_id_flag.id] == 0) && + (app_bt_device.hfchan_call[chan_id_flag.id]==0)){ + hfp_call_setup_running_on_clr(); + } +} + +static void hfp_current_call_state_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ + TRACE(1,"::HF_EVENT_CURRENT_CALL_STATE chan_id:%d\n", chan_id_flag.id); +#if !defined(FPGA) && defined(__BTIF_EARPHONE__) + hfp_app_status_indication(chan_id_flag.id,ctx); +#endif +} +void app_hfp_mute_upstream(uint8_t devId, bool isMute); + +static void hfp_audio_connected_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ + +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1; +#endif +#if defined(HFP_1_6_ENABLE) + hf_chan_handle_t chan_tmp; +#endif +#ifdef __AI_VOICE__ + ai_function_handle(CALLBACK_STOP_SPEECH, NULL, 0); + ai_function_handle(CALLBACK_AI_APP_KEEPALIVE_POST_HANDLER, NULL, 0); // check +#endif + if(ctx->status != BT_STS_SUCCESS) + return; +#if defined(IBRT) + app_ibrt_if_sniff_checker_start(APP_IBRT_IF_SNIFF_CHECKER_USER_HFP); +#endif + + btdrv_set_powerctrl_rssi_low(0xffff); + btapp_hfp_mic_need_skip_frame_set(2); + +#ifdef __BT_ONE_BRING_TWO__ +#ifdef SUSPEND_ANOTHER_DEV_A2DP_STREAMING_WHEN_CALL_IS_COMING + if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){ + TRACE(0,"::HF_EVENT_AUDIO_CONNECTED no need to update state"); + return; + } + hfp_suspend_another_device_a2dp(); +#endif +#endif +#ifdef __BT_ONE_BRING_TWO__ + a2dp_dual_slave_setup_during_sco(chan_id_flag.id); +#endif + +#if defined(HFP_1_6_ENABLE) + chan_tmp = app_bt_device.hf_channel[chan_id_flag.id]; + uint16_t codec_id; +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if(p_ibrt_ctrl->current_role==IBRT_SLAVE) + { + codec_id= p_ibrt_ctrl->ibrt_sco_codec; + } + else +#endif + { + codec_id = btif_hf_get_negotiated_codec(chan_tmp); + } + TRACE(2,"::HF_EVENT_AUDIO_CONNECTED chan_id:%d, codec_id:%d\n", chan_id_flag.id, codec_id); + app_audio_manager_set_scocodecid(chan_id_flag.id, codec_id); + + + // bt_drv_reg_op_sco_txfifo_reset(codec_id); +#else + TRACE(1,"::HF_EVENT_AUDIO_CONNECTED chan_id:%d\n", chan_id_flag.id); + // bt_drv_reg_op_sco_txfifo_reset(1); +#endif +#if defined (HFP_NO_PRERMPT) + if(((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE)&& + (app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_DISCON))&& + ((app_bt_device.hf_audio_state[chan_id_flag.id] == BTIF_HF_AUDIO_DISCON)&& + (app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_ACTIVE))){ + app_bt_device.phone_earphone_mark = 0; + app_bt_device.hf_mute_flag = 0; + }else if((app_bt_device.hf_audio_state[chan_id_flag.id] == BTIF_HF_AUDIO_CON)|| + (app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON)){ + }else +#endif + { + app_bt_device.phone_earphone_mark = 0; + app_bt_device.hf_mute_flag = 0; + } + app_bt_device.hf_audio_state[chan_id_flag.id] = BTIF_HF_AUDIO_CON; + +#if defined(__FORCE_REPORTVOLUME_SOCON__) + btif_hf_report_speaker_volume(chan, hfp_volume_get(chan_id_flag.id)); +#endif + +#ifdef __BT_ONE_BRING_TWO__ + if( bt_get_sco_number()>1 +#ifdef CHIP_BEST1000 + && hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2 +#endif + ){ + if(app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_ACTIVE){ +#if !defined (HFP_NO_PRERMPT) +#ifndef __HF_KEEP_ONE_ALIVE__ + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_SWAP_SCO,BT_STREAM_SBC, chan_id_flag.id, 0); +#endif + app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_ENABLE; + app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_DISABLE; +#else + if((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_NONE)&& + (app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_DISCON)) + app_bt_device.curr_hf_channel_id = chan_id_flag.id; +#ifdef _THREE_WAY_ONE_CALL_COUNT__ + app_hfp_set_cur_chnl_id(chan_id_flag.id); + TRACE(4,"%s :%d : app_bt_device.hf_callheld[%d]: %d\n", __func__, __LINE__, chan_id_flag.id, app_bt_device.hf_callheld[chan_id_flag.id]); + if(app_bt_device.hf_callheld[chan_id_flag.id] == BTIF_HF_CALL_HELD_ACTIVE){ + if(app_hfp_get_cur_call_chnl(NULL) == chan_id_flag.id) + app_hfp_3_way_call_counter_set(chan_id_flag.id,1); + }else if((app_bt_device.hf_callheld[chan_id_flag.id] == BTIF_HF_CALL_HELD_NONE) || + (app_bt_device.hf_callheld[chan_id_flag.id] == BTIF_HF_CALL_HELD_NO_ACTIVE)){ + if(app_hfp_get_cur_call_chnl(NULL) == chan_id_flag.id) + app_hfp_3_way_call_counter_set(chan_id_flag.id,0); + } +#endif +#endif + }else if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){ + app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_DISABLE; + app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_ENABLE; + } + }else{ + ///if one device setup a sco connect so get the other device's sco state, if both connect mute the earlier one + if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){ + app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_DISABLE; + } + app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_ENABLE; + } +#ifndef __HF_KEEP_ONE_ALIVE__ + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,BT_STREAM_VOICE,chan_id_flag.id,MAX_RECORD_NUM); +#endif +#if defined (HFP_NO_PRERMPT) + TRACE(2,"call[id_other] =%d audio[id_other] = %d",app_bt_device.hfchan_call[anotherDevice], + app_bt_device.hf_audio_state[anotherDevice]); + if(/*(app_bt_device.hfchan_call[anotherDevice] == HF_CALL_ACTIVE)&&*/ + (app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON)){ + }else +#endif + { + if (bt_media_cur_is_bt_stream_media()) + { + app_hfp_start_voice_media(chan_id_flag.id); + app_bt_device.curr_hf_channel_id = chan_id_flag.id; + } + else + { +#ifdef __BT_ONE_BRING_TWO__ + TRACE(1,"%s another[%d] hf_audio_state %d,",__func__,anotherDevice,app_bt_device.hf_audio_state[anotherDevice]); + + if(BTIF_HF_AUDIO_CON == app_bt_device.hf_audio_state[anotherDevice]) + { + TRACE(1,"disconnect current audio link and don't swith to current sco"); + btif_hf_disc_audio_link(app_bt_device.hf_channel[chan_id_flag.id]); + app_bt_device.curr_hf_channel_id = anotherDevice; + } +#else + if(bt_is_sco_media_open()) + { + TRACE(0,"disconnect current audio link and don't swith to current sco"); + app_bt_HF_DisconnectAudioLink(app_bt_device.hf_channel[chan_id_flag.id]); + } +#endif + else + { + app_hfp_start_voice_media(chan_id_flag.id); + app_bt_device.curr_hf_channel_id = chan_id_flag.id; + } + } + } +#else +#ifdef _THREE_WAY_ONE_CALL_COUNT__ + app_hfp_set_cur_chnl_id(chan_id_flag.id); +#endif +#ifdef ENABLE_HFP_AUDIO_PENDING_FOR_MEDIA + if (bt_media_cur_is_bt_stream_media()) + { + app_hfp_set_starting_media_pending_flag(true, BT_DEVICE_ID_1); + } + else +#endif + { + app_hfp_start_voice_media(BT_DEVICE_ID_1); + } +#endif + +#ifdef __IAG_BLE_INCLUDE__ + app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_HFP_ON, true); +#endif +} + +static void hfp_audio_disconnected_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ +#ifdef __BT_ONE_BRING_TWO__ + //clear flag_skip_resv and flag_skip_retx + bt_drv_clear_skip_flag(); + enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1; +#endif + +#ifdef BT_USB_AUDIO_DUAL_MODE + if(!btusb_is_bt_mode()) + { + TRACE(0,"btusb_usbaudio_open doing."); + btusb_usbaudio_open(); + } +#endif + app_hfp_set_starting_media_pending_flag(false, 0); +#if defined(IBRT) + app_ibrt_if_sniff_checker_stop(APP_IBRT_IF_SNIFF_CHECKER_USER_HFP); +#endif + +#ifdef __BT_ONE_BRING_TWO__ +#ifdef SUSPEND_ANOTHER_DEV_A2DP_STREAMING_WHEN_CALL_IS_COMING + if (app_bt_is_to_resume_music_player(anotherDevice)) + { + app_bt_resume_music_player(anotherDevice); + } +#endif +#endif + +#ifdef __BT_ONE_BRING_TWO__ + a2dp_dual_slave_handling_refresh(); +#endif + TRACE(1,"::HF_EVENT_AUDIO_DISCONNECTED chan_id:%d\n", chan_id_flag.id); + if(app_bt_device.hfchan_call[chan_id_flag.id] == BTIF_HF_CALL_ACTIVE){ + app_bt_device.phone_earphone_mark = 1; + } + + app_bt_device.hf_audio_state[chan_id_flag.id] = BTIF_HF_AUDIO_DISCON; + + /* Dont clear callsetup status when audio disc: press iphone volume button + will disc audio link, but the iphone incoming call is still exist. The + callsetup status will be reported after call rejected or answered. */ + //app_bt_device.hfchan_callSetup[chan_id_flag.id] = BTIF_HF_CALL_SETUP_NONE; + +#ifdef __IAG_BLE_INCLUDE__ + if (!app_bt_is_in_reconnecting()) + { + app_hfp_resume_ble_adv(); + } + + app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_HFP_ON, false); +#endif + +#if defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) || defined(CHIP_BEST1400) || defined(CHIP_BEST1402) + bt_drv_reg_op_clean_flags_of_ble_and_sco(); +#endif + +#ifdef __BT_ONE_BRING_TWO__ + if (btif_get_hf_chan_state(app_bt_device.hf_channel[anotherDevice]) != BTIF_HF_STATE_OPEN){ + TRACE(2,"!!!HF_EVENT_AUDIO_DISCONNECTED hfchan_call[%d]:%d\n",anotherDevice, + app_bt_device.hfchan_call[anotherDevice]); + } + if ((app_bt_device.hfchan_call[anotherDevice] == BTIF_HF_CALL_ACTIVE) || + (app_bt_device.hfchan_callSetup[anotherDevice] == BTIF_HF_CALL_SETUP_IN)){ + // app_bt_device.curr_hf_channel_id = chan_id_flag.id_other; + TRACE(1,"!!!HF_EVENT_AUDIO_DISCONNECTED app_bt_device.curr_hf_channel_id:%d\n", + app_bt_device.curr_hf_channel_id); + } else { + app_bt_device.curr_hf_channel_id = chan_id_flag.id; + } +#if defined(_THREE_WAY_ONE_CALL_COUNT__) + if (chan_id_flag.id == app_hfp_get_cur_call_chnl(NULL)) { + app_hfp_cur_call_chnl_reset(chan_id_flag.id); + } +#endif + app_bt_device.hf_voice_en[chan_id_flag.id] = HF_VOICE_DISABLE; + if(app_bt_device.hf_audio_state[anotherDevice] == BTIF_HF_AUDIO_CON){ + app_bt_device.hf_voice_en[anotherDevice] = HF_VOICE_ENABLE; + TRACE(1,"chan_id:%d AUDIO_DISCONNECTED, then enable id_other voice",chan_id_flag.id); + } + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP, BT_STREAM_VOICE, + chan_id_flag.id, MAX_RECORD_NUM); +#else + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP, BT_STREAM_VOICE, + BT_DEVICE_ID_1, MAX_RECORD_NUM); + +#endif + app_bt_device.callSetupBitRec = 0; + //app_hfp_mute_upstream(chan_id_flag.id, true); +#if defined(HFP_1_6_ENABLE) + uint16_t codec_id = btif_hf_get_negotiated_codec(app_bt_device.hf_channel[chan_id_flag.id]); + bt_drv_reg_op_sco_txfifo_reset(codec_id); +#else + bt_drv_reg_op_sco_txfifo_reset(1); +#endif + + app_bt_active_mode_clear(ACTIVE_MODE_KEEPEER_SCO_STREAMING, + UPDATE_ACTIVE_MODE_FOR_ALL_LINKS); +} + +static void hfp_ring_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ +#if !defined(FPGA) && defined(__BTIF_EARPHONE__) && defined(MEDIA_PLAYER_SUPPORT) +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T anotherDevice = (BT_DEVICE_ID_1 == chan_id_flag.id)?BT_DEVICE_ID_2:BT_DEVICE_ID_1; +#endif + TRACE(1,"::HF_EVENT_RING_IND chan_id:%d\n", chan_id_flag.id); + TRACE(1,"btif_hf_is_inbandring_enabled:%d",btif_hf_is_inbandring_enabled(chan)); +#if defined(__BT_ONE_BRING_TWO__) + if((app_bt_device.hf_audio_state[chan_id_flag.id] != BTIF_HF_AUDIO_CON) && + (app_bt_device.hf_audio_state[anotherDevice] != BTIF_HF_AUDIO_CON)) + app_voice_report(APP_STATUS_INDICATION_INCOMINGCALL,chan_id_flag.id); +#else + +#if defined(IBRT) + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if(p_ibrt_ctrl->current_role == IBRT_SLAVE) + return; +#endif + if(app_bt_device.hf_audio_state[chan_id_flag.id] != BTIF_HF_AUDIO_CON) + app_voice_report(APP_STATUS_INDICATION_INCOMINGCALL,chan_id_flag.id); +#endif +#endif +} + +static void hfp_speak_volume_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ + TRACE(2,"::HF_EVENT_SPEAKER_VOLUME chan_id:%d,speaker gain = %d\n", + chan_id_flag.id, ctx->speaker_volume); + hfp_volume_set(chan_id_flag.id, (int)ctx->speaker_volume); +} + +static void hfp_voice_rec_state_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ + TRACE(2,"::HF_EVENT_VOICE_REC_STATE chan_id:%d,voice_rec_state = %d\n", + chan_id_flag.id, ctx->voice_rec_state); +} + +static void hfp_bes_test_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ + //TRACE(0,"HF_EVENT_BES_TEST content =d", Info->p.ptr); +} + +static void hfp_read_ag_ind_status_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ + TRACE(1,"HF_EVENT_READ_AG_INDICATORS_STATUS %s\n", __func__); +} + +static void hfp_call_held_ind_handler(hf_chan_handle_t chan, struct hfp_context *ctx) +{ +#if defined( __BT_ONE_BRING_TWO__) + TRACE(8,"::HF_EVENT_CALLHELD_IND %d chan_id %d call %d %d held %d %d audio_state %d %d\n", + ctx->call_held, chan_id_flag.id, + app_bt_device.hfchan_call[BT_DEVICE_ID_1], app_bt_device.hfchan_call[BT_DEVICE_ID_2], + app_bt_device.hf_callheld[BT_DEVICE_ID_1], app_bt_device.hf_callheld[BT_DEVICE_ID_2], + app_bt_device.hf_audio_state[BT_DEVICE_ID_1], app_bt_device.hf_audio_state[BT_DEVICE_ID_2]); +#else + TRACE(2,"::HF_EVENT_CALLHELD_IND chan_id:%d HELD_STATUS = %d \n",chan_id_flag.id, ctx->call_held); +#endif +#if defined(_THREE_WAY_ONE_CALL_COUNT__) +#if defined( __BT_ONE_BRING_TWO__) + if (app_bt_device.hf_audio_state[chan_id_flag.id] == BTIF_HF_AUDIO_CON && (ctx->call_held == BTIF_HF_CALL_HELD_NONE || ctx->call_held == BTIF_HF_CALL_HELD_ACTIVE)) { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_SWITCHTO_SCO, BT_STREAM_VOICE, chan_id_flag.id, 0); + } +#endif + app_bt_device.hf_callheld[chan_id_flag.id] = ctx->call_held; + if(ctx->call_held == BTIF_HF_CALL_HELD_ACTIVE){ + if(app_hfp_get_cur_call_chnl(NULL) == chan_id_flag.id) + app_hfp_3_way_call_counter_set(chan_id_flag.id,1); + }else if((ctx->call_held == BTIF_HF_CALL_HELD_NONE) || + (ctx->call_held == BTIF_HF_CALL_HELD_NO_ACTIVE)){ + if(app_hfp_get_cur_call_chnl(NULL) == chan_id_flag.id) + app_hfp_3_way_call_counter_set(chan_id_flag.id,0); + }else{ + TRACE(0,"UNKNOWN CMD.IGNORE"); + } +#endif +} + +static uint8_t skip_frame_cnt = 0; +void app_hfp_set_skip_frame(uint8_t frames) +{ + skip_frame_cnt = frames; +} +uint8_t app_hfp_run_skip_frame(void) +{ + if(skip_frame_cnt >0){ + skip_frame_cnt--; + return 1; + } + return 0; +} +uint8_t hfp_is_service_connected(uint8_t device_id) +{ + if(device_id >= BT_DEVICE_NUM) + return 0; + return app_bt_device.hf_conn_flag[device_id]; +} +#if HF_VERSION_1_6 == XA_ENABLED +//HfCommand hf_codec_sel_command; +#endif + +static uint8_t app_hfp_is_starting_media_pending_flag = false; +static uint8_t app_hfp_pending_dev_id; +bool app_hfp_is_starting_media_pending(void) +{ + return app_hfp_is_starting_media_pending_flag; +} +static uint8_t upstreamMute = 0xff; +void app_hfp_mute_upstream(uint8_t devId, bool isMute) +{ + if (upstreamMute != isMute){ + TRACE(3,"%s devId %d isMute %d",__func__,devId,isMute); + upstreamMute = isMute; + if (isMute){ + btdrv_set_bt_pcm_en(0); + }else{ + btdrv_set_bt_pcm_en(1); + } + } +} + +static void app_hfp_set_starting_media_pending_flag(bool isEnabled, uint8_t devId) +{ + TRACE(1,"%s %d.Current state %d toEnable %d",__func__,__LINE__, + app_hfp_is_starting_media_pending_flag, isEnabled); + if ((app_hfp_is_starting_media_pending_flag && isEnabled) || + (!app_hfp_is_starting_media_pending_flag && !isEnabled)) + { + return; + } + + app_hfp_is_starting_media_pending_flag = isEnabled; + + app_hfp_pending_dev_id = devId; +#if 0 + if (isEnabled) + { + if (!app_hfp_mediaplay_delay_resume_timer_id ) { + app_hfp_mediaplay_delay_resume_timer_id = + osTimerCreate(osTimer(APP_HFP_MEDIAPLAY_DELAY_RESUME_TIMER), + osTimerOnce, NULL); + } + osTimerStart(app_hfp_mediaplay_delay_resume_timer_id , + HFP_MEDIAPLAY_DELAY_RESUME_IN_MS); + } +#endif +} + +void app_hfp_start_voice_media(uint8_t devId) +{ + app_hfp_set_starting_media_pending_flag(false, 0); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START, + BT_STREAM_VOICE, devId, MAX_RECORD_NUM); +} + +void app_hfp_resume_pending_voice_media(void) +{ + if (btapp_hfp_is_dev_sco_connected(app_hfp_pending_dev_id)) + { + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START, + BT_STREAM_VOICE, app_hfp_pending_dev_id, MAX_RECORD_NUM); + app_hfp_set_starting_media_pending_flag(false, 0); + } +} + +#include "app_bt_func.h" +void hfp_multipoint_audio_manage_a2dp_callback() +{ +#ifdef SUSPEND_ANOTHER_DEV_A2DP_STREAMING_WHEN_CALL_IS_COMING + int i = 0; + int j = 0; + TRACE(1,"%s",__func__); + + for(i =0;ichan_sel_remDev; + // default channel is NULL + *(ctx->chan_sel_channel) = NULL; + for(i = 0 ; i < BT_DEVICE_NUM ; i++) { + // Other profile connected + curr_channel = app_bt_device.hf_channel[i]; + if (app_bt_is_any_profile_connected(i)) { + matching_remdev = app_bt_get_connected_profile_remdev(i); + TRACE(3,"device_id=%d, hfp_select_channel : remdev=0x%x:0x%x.", i, wanted_remdev, matching_remdev); + TRACE(1,"device_id=%d, hfp_select_channel : other_profile_connected.", i); + if (wanted_remdev == matching_remdev) { + TRACE(2,"device_id=%d, hfp_select_channel : found_same_remdev : 0x%x", i, &(app_bt_device.hf_channel[i])); + if (btif_get_hf_chan_state(curr_channel) == BTIF_HF_STATE_CLOSED) { + TRACE(1,"device_id=%d, hfp_select_channel : current_channel_is_closed, good.", i); + *(ctx->chan_sel_channel) = (uint32_t *)curr_channel; + } + else { + TRACE(2,"device_id=%d, hfp_select_channel : other_profile_connected: current_channel_is_not_closed %d, ohno.", i, btif_get_hf_chan_state(curr_channel)); + TRACE(1,"device_id=%d, hfp_select_channel : other_profile_connected: missed right channel, found nothing, return", i); + } + return; + } + else { + TRACE(1,"device_id=%d, hfp_select_channel : different_remdev, see next device id", i); + } + } + else { + TRACE(1,"device_id=%d, hfp_select_channel : other_profile_not_connected.", i); + // first found idle device id is min device id we want + // Assume : other profile will use device id ascending + // TODO to keep other profile use device id ascending + if (btif_get_hf_chan_state(curr_channel) == BTIF_HF_STATE_CLOSED) { + TRACE(1,"device_id=%d, hfp_select_channel : current_channel_is_closed, choose this idle channel.", i); + *(ctx->chan_sel_channel) = (uint32_t *)curr_channel; + } + else { + TRACE(2,"device_id=%d, hfp_select_channel : no_other_profile_connected : current_channel_is_not_closed %d, ohno.", i, btif_get_hf_chan_state(curr_channel)); + TRACE(1,"device_id=%d, hfp_select_channel : no_other_profile_connected : missed right channel, found nothing, return", i); + } + return; + } + } +} +#endif +#endif + +void app_hfp_event_callback(hf_chan_handle_t chan, struct hfp_context *ctx) +{ + struct bt_cb_tag* bt_drv_func_cb = bt_drv_get_func_cb_ptr(); + +#ifdef __BT_ONE_BRING_TWO__ + if (ctx->event == BTIF_HF_EVENT_SELECT_CHANNEL) { +#if defined(__BT_SELECT_PROF_DEVICE_ID__) + _app_hfp_select_channel(chan, ctx); +#endif + return; + } + hfp_chan_id_distinguish(chan); +#else + if (ctx->event == BTIF_HF_EVENT_SELECT_CHANNEL) { + return; + } + chan_id_flag.id = BT_DEVICE_ID_1; +#endif + switch(ctx->event) { + case BTIF_HF_EVENT_SERVICE_CONNECTED: + hfp_connected_ind_handler(chan, ctx); + break; + case BTIF_HF_EVENT_AUDIO_DATA_SENT: + hfp_audio_data_sent_handler(chan, ctx); + break; + case BTIF_HF_EVENT_AUDIO_DATA: + hfp_audio_data_handler(chan, ctx); + break; + case BTIF_HF_EVENT_SERVICE_DISCONNECTED: + hfp_disconnected_ind_handler(chan, ctx); + break; + case BTIF_HF_EVENT_CALL_IND: + hfp_call_ind_handler(chan, ctx); + break; + case BTIF_HF_EVENT_CALLSETUP_IND: + hfp_callsetup_ind_handler(chan, ctx); + break; + case BTIF_HF_EVENT_CURRENT_CALL_STATE: + hfp_current_call_state_handler(chan, ctx); + break; + case BTIF_HF_EVENT_AUDIO_CONNECTED: + #ifdef IBRT + { + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + bt_drv_reg_op_set_agc_thd(p_ibrt_ctrl->current_role == IBRT_MASTER,true); + + if(!btif_besaud_is_connected()) + { + bt_drv_reg_op_hack_max_slot(p_ibrt_ctrl->mobile_conhandle-0x80,1); + } + } + #endif + + if(bt_drv_func_cb->bt_switch_agc != NULL) + { + bt_drv_func_cb->bt_switch_agc(BT_HFP_WORK_MODE); + } + + hfp_audio_connected_handler(chan, ctx); + break; + case BTIF_HF_EVENT_AUDIO_DISCONNECTED: + + if(bt_drv_func_cb->bt_switch_agc != NULL) + { + bt_drv_func_cb->bt_switch_agc(BT_IDLE_MODE); + } + + hfp_audio_disconnected_handler(chan, ctx); + break; + case BTIF_HF_EVENT_RING_IND: + hfp_ring_ind_handler(chan, ctx); + break; + case BTIF_HF_EVENT_SPEAKER_VOLUME: + hfp_speak_volume_handler(chan, ctx); + break; +#ifdef SUPPORT_SIRI + case BTIF_HF_EVENT_SIRI_STATUS: + break; +#endif + case BTIF_HF_EVENT_BES_TEST: + hfp_bes_test_handler(chan, ctx); + break; + case BTIF_HF_EVENT_READ_AG_INDICATORS_STATUS: + hfp_read_ag_ind_status_handler(chan, ctx); + break; + case BTIF_HF_EVENT_CALLHELD_IND: + hfp_call_held_ind_handler(chan, ctx); + break; + case BTIF_HF_EVENT_COMMAND_COMPLETE: + break; + case BTIF_HF_EVENT_AT_RESULT_DATA: + TRACE(1,"received AT command: %s", ctx->ptr); +#ifdef __INTERACTION__ + if(!memcmp(oppo_self_defined_command_response, ctx->ptr, strlen(oppo_self_defined_command_response))) + { + for(int i=0; iptr, strlen(huawei_self_defined_command_response)+1)) + { + uint8_t *pSelfDefinedCommandSupport = app_battery_get_mobile_support_self_defined_command_p(); + *pSelfDefinedCommandSupport = 1; + + TRACE(0,"send self defined AT command to mobile."); + send_selfdefined_battery_report_AT_command(); + } +#endif + break; + + case BTIF_HF_EVENT_VOICE_REC_STATE: + hfp_voice_rec_state_ind_handler(chan, ctx); + break; + + default: + break; + } + +#ifdef __BT_ONE_BRING_TWO__ + hfcall_next_sta_handler(ctx->event); +#endif + +#if defined(IBRT) + app_tws_ibrt_profile_callback(BTIF_APP_HFP_PROFILE_ID,(void *)chan, (void *)ctx); +#endif +} + +uint8_t btapp_hfp_get_call_state(void) +{ + uint8_t i; + for (i = 0; i < BT_DEVICE_NUM; i++) { + if (app_bt_device.hfchan_call[i] == BTIF_HF_CALL_ACTIVE) { + return 1; + } + } + return 0; +} + +uint8_t btapp_hfp_get_call_setup(void) +{ + uint8_t i; + for (i = 0; i < BT_DEVICE_NUM; i++){ + if ((app_bt_device.hfchan_callSetup[i] != BTIF_HF_CALL_SETUP_NONE)){ + return (app_bt_device.hfchan_callSetup[i]); + } + } + return 0; +} + +uint8_t btapp_hfp_incoming_calls(void) +{ + uint8_t i; + for (i = 0; i < BT_DEVICE_NUM; i++) { + if (app_bt_device.hfchan_callSetup[i] == BTIF_HF_CALL_SETUP_IN) { + return 1; + } + } + return 0; +} + +bool btapp_hfp_is_call_active(void) +{ + uint8_t i; + for (i = 0; i < BT_DEVICE_NUM; i++){ + if ((app_bt_device.hfchan_call[i] == BTIF_HF_CALL_ACTIVE) && + (app_bt_device.hf_audio_state[i] == BTIF_HF_AUDIO_CON)) { + return true; + } + } + return false; +} + +bool btapp_hfp_is_sco_active(void) +{ + uint8_t i; + for (i = 0; i < BT_DEVICE_NUM; i++) { + if (app_bt_device.hf_audio_state[i] == BTIF_HF_AUDIO_CON) { + return true; + } + } + return false; +} + +bool btapp_hfp_is_dev_call_active(uint8_t devId) +{ + return ((app_bt_device.hfchan_call[devId] == BTIF_HF_CALL_ACTIVE) && + (app_bt_device.hf_audio_state[devId] == BTIF_HF_AUDIO_CON)); +} + +bool btapp_hfp_is_dev_sco_connected(uint8_t devId) +{ + return (app_bt_device.hf_audio_state[devId] == BTIF_HF_AUDIO_CON); +} + +uint8_t btapp_hfp_get_call_active(void) +{ + uint8_t i; + for (i = 0; i < BT_DEVICE_NUM; i++) { + if ((app_bt_device.hfchan_call[i] == BTIF_HF_CALL_ACTIVE) || + (app_bt_device.hfchan_callSetup[i] == BTIF_HF_CALL_SETUP_ALERT)){ + + return 1; + } + } + return 0; +} + +void btapp_hfp_report_speak_gain(void) +{ + uint8_t i; + btif_remote_device_t *remDev = NULL; + btif_link_mode_t mode = BTIF_BLM_SNIFF_MODE; + hf_chan_handle_t chan; + + + for(i = 0; i < BT_DEVICE_NUM; i++) { + osapi_lock_stack(); + remDev = (btif_remote_device_t *)btif_hf_cmgr_get_remote_device(app_bt_device.hf_channel[i]); + if (remDev){ + mode = btif_me_get_current_mode(remDev); + } else { + mode = BTIF_BLM_SNIFF_MODE; + } + chan = app_bt_device.hf_channel[i]; + if ((btif_get_hf_chan_state(chan) == BTIF_HF_STATE_OPEN) && + (mode == BTIF_BLM_ACTIVE_MODE)) { + btif_hf_report_speaker_volume(chan, hfp_volume_get((enum BT_DEVICE_ID_T)i)); + } + osapi_unlock_stack(); + } + + +} + +uint8_t btapp_hfp_need_mute(void) +{ + return app_bt_device.hf_mute_flag; +} + +int32_t hfp_mic_need_skip_frame_cnt = 0; + +bool btapp_hfp_mic_need_skip_frame(void) +{ + bool nRet; + + if (hfp_mic_need_skip_frame_cnt > 0) { + hfp_mic_need_skip_frame_cnt--; + nRet = true; + } else { + app_hfp_mute_upstream(0, false); + nRet = false; + } + return nRet; +} + +void btapp_hfp_mic_need_skip_frame_set(int32_t skip_frame) +{ + hfp_mic_need_skip_frame_cnt = skip_frame; +} + +#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) +typedef void (*btapp_set_sco_switch_cmd_callback)(void); + +btapp_set_sco_switch_cmd_callback set_sco_switch_cmd_callback; + +void btapp_sco_switch_set_pcm(void) +{ + TRACE(0,"btapp_sco_switch_set_pcm\n"); + TRACE(1,"0xd02201b0 = 0x%x before\n",*(volatile uint32_t *)(0xd02201b0)); + osDelay(20); + btdrv_pcm_enable(); + TRACE(1,"0xd02201b0 = 0x%x after\n",*(volatile uint32_t *)(0xd02201b0)); +} +#endif + +void app_hfp_init(void) +{ + hfp_hfcommand_mempool_init(); +#if defined(ENHANCED_STACK) + btif_hfp_initialize(); +#endif /* ENHANCED_STACK */ + app_bt_device.curr_hf_channel_id = BT_DEVICE_ID_1; + app_bt_device.hf_mute_flag = 0; + + for (uint8_t i = 0; i < BT_DEVICE_NUM; i++) { + app_bt_device.hf_channel[i] = btif_hf_create_channel(); + if (!app_bt_device.hf_channel[i]) { + ASSERT(0, "Serious error: cannot create hf channel\n"); + } + btif_hf_init_channel(app_bt_device.hf_channel[i]); + app_bt_device.hfchan_call[i] = 0; + app_bt_device.hfchan_callSetup[i] = 0; + app_bt_device.hf_audio_state[i] = BTIF_HF_AUDIO_DISCON, + app_bt_device.hf_conn_flag[i] = false; + app_bt_device.hf_voice_en[i] = 0; + } + btif_hf_register_callback(app_hfp_event_callback); +#if defined(SUPPORT_BATTERY_REPORT) || defined(SUPPORT_HF_INDICATORS) + Besbt_hook_handler_set(BESBT_HOOK_USER_3, app_hfp_battery_report_proc); +#endif + +#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) + set_sco_switch_cmd_callback = btapp_sco_switch_set_pcm; +#endif + app_hfp_mute_upstream(chan_id_flag.id, true); +} + +void app_hfp_enable_audio_link(bool isEnable) +{ + return; +} + +#if defined(IBRT) +int hfp_ibrt_service_connected_mock(void) +{ + if (btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_1]) == BTIF_HF_STATE_OPEN){ + TRACE(0,"::HF_EVENT_SERVICE_CONNECTED mock"); + app_bt_device.hf_conn_flag[chan_id_flag.id] = 1; + }else{ + TRACE(1,"::HF_EVENT_SERVICE_CONNECTED mock need check chan_state:%d", btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_1])); + } + + return 0; +} + +int hfp_ibrt_sync_get_status(ibrt_hfp_status_t *hfp_status) +{ + hfp_status->audio_state = (uint8_t)app_bt_device.hf_audio_state[BT_DEVICE_ID_1]; + hfp_status->volume = hfp_volume_get(BT_DEVICE_ID_1); + hfp_status->lmp_sco_hdl = 0; + + if (hfp_status->audio_state == BTIF_HF_AUDIO_CON && + app_tws_ibrt_mobile_link_connected()) + { + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + uint16_t sco_connhdl = btif_me_get_scohdl_by_connhdl(p_ibrt_ctrl->mobile_conhandle); + hfp_status->lmp_sco_hdl = bt_drv_reg_op_lmp_sco_hdl_get(sco_connhdl); + TRACE(2,"ibrt_ui_log:get sco lmp hdl %04x %02x\n", sco_connhdl, hfp_status->lmp_sco_hdl); + } + + return 0; +} + +int hfp_ibrt_sync_set_status(ibrt_hfp_status_t *hfp_status) +{ + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + btif_remote_device_t *remDev = NULL; + + TRACE(4,"%s audio_state:%d volume:%d lmp_scohdl:%02x", __func__, hfp_status->audio_state, + hfp_status->volume, hfp_status->lmp_sco_hdl); + + app_bt_device.hf_audio_state[BT_DEVICE_ID_1] = (btif_audio_state_t)hfp_status->audio_state; + + if (app_tws_ibrt_mobile_link_connected()){ + remDev = btif_me_get_remote_device_by_handle(p_ibrt_ctrl->mobile_conhandle); + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + remDev = btif_me_get_remote_device_by_handle(p_ibrt_ctrl->ibrt_conhandle); + } + + if (remDev){ + app_bt_stream_volume_ptr_update((uint8_t *) btif_me_get_remote_device_bdaddr(remDev)); + }else{ + app_bt_stream_volume_ptr_update(NULL); + } + + hfp_volume_set(BT_DEVICE_ID_1, hfp_status->volume); + + p_ibrt_ctrl->ibrt_sco_lmphdl = 0; + + if (hfp_status->audio_state == BTIF_HF_AUDIO_CON && + hfp_status->lmp_sco_hdl != 0 && + app_tws_ibrt_slave_ibrt_link_connected()) + { + uint16_t sco_connhdl = 0x0100; //SYNC_HFP_STATUS arrive before mock sniffer_sco, so use 0x0100 directly + if (bt_drv_reg_op_lmp_sco_hdl_set(sco_connhdl, hfp_status->lmp_sco_hdl)) + { + TRACE(2,"ibrt_ui_log:set sco %04x lmp hdl %02x\n", sco_connhdl, hfp_status->lmp_sco_hdl); + } + else + { + // SYNC_HFP_STATUS may so much faster lead bt_drv_reg_op_lmp_sco_hdl_set fail, backup the value + p_ibrt_ctrl->ibrt_sco_lmphdl = hfp_status->lmp_sco_hdl; + } + } + + return 0; +} + +int hfp_ibrt_sco_audio_connected(hfp_sco_codec_t codec, uint16_t sco_connhdl) +{ + int ret = BT_STS_SUCCESS; + ibrt_ctrl_t *p_ibrt_ctrl = NULL; + + TRACE(0,"::HF_EVENT_AUDIO_CONNECTED mock"); + + app_bt_device.hf_audio_state[BT_DEVICE_ID_1] = BTIF_HF_AUDIO_CON; + btif_hf_set_negotiated_codec(app_bt_device.hf_channel[BT_DEVICE_ID_1] ,codec); + app_audio_manager_set_scocodecid(BT_DEVICE_ID_1,codec); +#ifdef ENABLE_HFP_AUDIO_PENDING_FOR_MEDIA + if (bt_media_cur_is_bt_stream_media()) + { + app_hfp_set_starting_media_pending_flag(true, BT_DEVICE_ID_1); + } + else +#endif + { + app_hfp_start_voice_media(BT_DEVICE_ID_1); + } + app_ibrt_if_sniff_checker_start(APP_IBRT_IF_SNIFF_CHECKER_USER_HFP); + + struct bt_cb_tag* bt_drv_func_cb = bt_drv_get_func_cb_ptr(); + if(bt_drv_func_cb->bt_switch_agc != NULL) + { + bt_drv_func_cb->bt_switch_agc(BT_HFP_WORK_MODE); + } + + p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + if (p_ibrt_ctrl->ibrt_sco_lmphdl != 0) + { + // set backuped lmphdl if it is failed in hfp_ibrt_sync_set_status + TRACE(2,"ibrt_ui_log:set sco %04x lmp hdl %02x\n", sco_connhdl, p_ibrt_ctrl->ibrt_sco_lmphdl); + bt_drv_reg_op_lmp_sco_hdl_set(sco_connhdl, p_ibrt_ctrl->ibrt_sco_lmphdl); + p_ibrt_ctrl->ibrt_sco_lmphdl = 0; + } + + return ret; +} + +int hfp_ibrt_sco_audio_disconnected(void) +{ + int ret = BT_STS_SUCCESS; + TRACE(0,"::HF_EVENT_AUDIO_DISCONNECTED mock"); + app_bt_device.hf_audio_state[BT_DEVICE_ID_1] = BTIF_HF_AUDIO_DISCON; + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_VOICE,BT_DEVICE_ID_1,0); + app_ibrt_if_sniff_checker_stop(APP_IBRT_IF_SNIFF_CHECKER_USER_HFP); + + struct bt_cb_tag* bt_drv_func_cb = bt_drv_get_func_cb_ptr(); + if(bt_drv_func_cb->bt_switch_agc != NULL) + { + bt_drv_func_cb->bt_switch_agc(BT_IDLE_MODE); + } + return ret; +} + +#endif diff --git a/services/bt_app/app_hfp.h b/services/bt_app/app_hfp.h new file mode 100644 index 0000000..7547be3 --- /dev/null +++ b/services/bt_app/app_hfp.h @@ -0,0 +1,81 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_HFP_H__ +#define __APP_HFP_H__ + +#include "bluetooth.h" +#include "btapp.h" + +#define HF_VOICE_DISABLE 0 +#define HF_VOICE_ENABLE 1 + +#define HF_SENDBUFF_SIZE (320) +#define HF_SENDBUFF_MEMPOOL_NUM (2) + +struct hf_sendbuff_control { + struct { + btif_bt_packet_t packet; + uint8_t buffer[HF_SENDBUFF_SIZE]; + } mempool[HF_SENDBUFF_MEMPOOL_NUM]; + uint8_t index; +}; + + +#ifndef _SCO_BTPCM_CHANNEL_ +extern struct hf_sendbuff_control hf_sendbuff_ctrl; +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* */ + +#if defined(SUPPORT_BATTERY_REPORT) || defined(SUPPORT_HF_INDICATORS) +int app_hfp_battery_report(uint8_t level); +bt_status_t app_hfp_send_at_command(const char *cmd); +#else +static inline int app_hfp_battery_report(uint8_t level) {return 0;} +#endif + +uint8_t btapp_hfp_get_call_state(void); + +uint8_t btapp_hfp_incoming_calls(void); + +bool btapp_hfp_is_call_active(void); + +bool btapp_hfp_is_sco_active(void); + +void btapp_hfp_report_speak_gain(void); + +bool btapp_hfp_mic_need_skip_frame(void); + +uint8_t btapp_hfp_need_mute(void); + +#ifdef __INTERCONNECTION__ +uint8_t ask_is_selfdefined_battery_report_AT_command_support(void); + +uint8_t send_selfdefined_battery_report_AT_command(void); +#endif + +uint8_t app_hfp_get_chnl_via_remDev(hf_chan_handle_t * p_hfp_chnl); +bool app_hfp_curr_audio_up(hf_chan_handle_t hfp_chnl); +int hfp_volume_set(enum BT_DEVICE_ID_T id, int vol); + + +#ifdef __cplusplus +} +#endif /* */ +#endif /*__APP_HFP_H__*/ + diff --git a/services/bt_app/app_hsp.cpp b/services/bt_app/app_hsp.cpp new file mode 100644 index 0000000..bd94e1e --- /dev/null +++ b/services/bt_app/app_hsp.cpp @@ -0,0 +1,362 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_chipid.h" +#include "analog.h" +#include "app_audio.h" +#include "app_status_ind.h" +#include "bluetooth.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" + + + +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_bt.h" + +#include "nvrecord.h" + +#include "apps.h" +#include "resources.h" + +#include "app_bt_media_manager.h" + +#if defined(__HSP_ENABLE__) && defined(__BT_ONE_BRING_TWO__) +#error can not defined at the same time. +#endif + +#if defined (__HSP_ENABLE__) + +#define MODIFY_HS_CALL_SETUP_IN HF_CALL_SETUP_IN +#define MODIFY_HS_CALL_ACTIVE HF_CALL_ACTIVE +#define MODIFY_HS_CALL_NONE HF_CALL_NONE + + +extern struct BT_DEVICE_ID_DIFF chan_id_flag; +extern struct BT_DEVICE_T app_bt_device; + +#if defined(SCO_LOOP) +#define HF_LOOP_CNT (20) +#define HF_LOOP_SIZE (360) + + +extern uint8_t hf_loop_buffer[HF_LOOP_CNT*HF_LOOP_SIZE]; +extern uint32_t hf_loop_buffer_len[HF_LOOP_CNT]; +extern uint32_t hf_loop_buffer_valid ; +extern uint32_t hf_loop_buffer_size ; +extern char hf_loop_buffer_w_idx ; + +#endif + +#ifndef _SCO_BTPCM_CHANNEL_ +extern struct hf_sendbuff_control hf_sendbuff_ctrl; +#endif + + + +#ifdef __BT_ONE_BRING_TWO__ +extern void hfp_chan_id_distinguish(HfChannel *Chan); +#endif + +extern int store_voicebtpcm_m2p_buffer(unsigned char *buf, unsigned int len); +extern int get_voicebtpcm_p2m_frame(unsigned char *buf, unsigned int len); +extern int store_voicecvsd_buffer(unsigned char *buf, unsigned int len); +extern int store_voicemsbc_buffer(unsigned char *buf, unsigned int len); +extern int hfp_volume_get(enum BT_DEVICE_ID_T id); +extern void hfp_volume_local_set(int8_t vol); +extern int hfp_volume_set(enum BT_DEVICE_ID_T id, int vol); +extern void app_bt_profile_connect_manager_hs(enum BT_DEVICE_ID_T id, HsChannel *Chan, HsCallbackParms *Info);; + +#ifdef __BT_ONE_BRING_TWO__ +void hsp_chan_id_distinguish(HsChannel *Chan) +{ + if(Chan == &app_bt_device.hs_channel[BT_DEVICE_ID_1]){ + chan_id_flag.id = BT_DEVICE_ID_1; + chan_id_flag.id_other = BT_DEVICE_ID_2; + }else if(Chan == &app_bt_device.hsf_channel[BT_DEVICE_ID_2]){ + chan_id_flag.id = BT_DEVICE_ID_2; + chan_id_flag.id_other = BT_DEVICE_ID_1; + } +} +#endif + +int app_hsp_hscommand_mempool_init(void) +{ + app_hfp_hfcommand_mempool_init(); + return 0; +} + +int app_hsp_hscommand_mempool_calloc(HsCommand **hs_cmd_p) +{ + app_hfp_hfcommand_mempool_calloc(hs_cmd_p); + return 0; +} + +int app_hsp_hscommand_mempool_free(HsCommand *hs_cmd_p) +{ + app_hfp_hfcommand_mempool_free(hs_cmd_p); + return 0; +} +#if 0 +#define app_hsp_hscommand_mempool app_hfp_hfcommand_mempool +#define app_hsp_hscommand_mempool_init app_hfp_hfcommand_mempool_init +#define app_hsp_hscommand_mempool_calloc app_hfp_hfcommand_mempool_calloc +#define app_hsp_hscommand_mempool_free app_hfp_hfcommand_mempool_free +#endif + + +XaStatus app_hs_handle_cmd(HsChannel *Chan,uint8_t cmd_type) +{ + HsCommand *hs_cmd_p; + int8_t ret = 0; + switch(cmd_type){ + case APP_REPORT_SPEAKER_VOL_CMD: + app_hsp_hscommand_mempool_calloc(&hs_cmd_p); + if (hs_cmd_p){ + if(HS_ReportSpeakerVolume(Chan,hfp_volume_get(chan_id_flag.id), hs_cmd_p) != BT_STATUS_PENDING) + { + app_hsp_hscommand_mempool_free(hs_cmd_p); + ret = -1; + } + } + break; + case APP_CPKD_CMD: + app_hsp_hscommand_mempool_calloc(&hs_cmd_p); + if (hs_cmd_p){ + if(HS_CKPD_CONTROL(Chan,hs_cmd_p) != BT_STATUS_PENDING) + { + app_hsp_hscommand_mempool_free(hs_cmd_p); + ret = -1; + } + } + break; + default: + break; + } + + return ret ; + +} + + + +// because hfp and hsp can not exist simultaneously , so we do not need to alloc 2 cmd pool! +void app_hsp_init(void) +{ + + + app_hsp_hscommand_mempool_init(); + + app_bt_device.curr_hs_channel_id = BT_DEVICE_ID_1; + app_bt_device.hs_mute_flag = 0; + + for(uint8_t i=0; ievent); + + switch(Info->event) + { + case HS_EVENT_SERVICE_CONNECTED: + TRACE(1,"::HS_EVENT_SERVICE_CONNECTED Chan_id:%d\n", chan_id_flag.id); + app_bt_profile_connect_manager_hs(chan_id_flag.id, Chan, Info); +#if !defined(FPGA) && defined(__BTIF_EARPHONE__) + if(Chan->state == HF_STATE_OPEN){ + ////report connected voice + app_bt_device.hs_conn_flag[chan_id_flag.id] = 1; + + } +#endif + app_bt_stream_volume_ptr_update((uint8_t *)Info->p.remDev->bdAddr.addr); + if(app_hs_handle_cmd(Chan,APP_REPORT_SPEAKER_VOL_CMD) !=0) + TRACE(0,"app_hs_handle_cmd err"); + + break; + case HS_EVENT_AUDIO_DATA_SENT: + TRACE(1,"::HF_EVENT_AUDIO_DATA_SENT %d\n", Info->event); +#if defined(SCO_LOOP) + hf_loop_buffer_valid = 1; +#endif + break; + case HS_EVENT_AUDIO_DATA: + TRACE(0,"HF_EVENT_AUDIO_DATA"); + { + +#ifndef _SCO_BTPCM_CHANNEL_ + uint32_t idx = 0; + if (app_bt_stream_isrun(APP_BT_STREAM_HFP_PCM)){ + store_voicebtpcm_m2p_buffer(Info->p.audioData->data, Info->p.audioData->len); + + idx = hf_sendbuff_ctrl.index%HF_SENDBUFF_MEMPOOL_NUM; + get_voicebtpcm_p2m_frame(&(hf_sendbuff_ctrl.mempool[idx].buffer[0]), Info->p.audioData->len); + hf_sendbuff_ctrl.mempool[idx].packet.data = &(hf_sendbuff_ctrl.mempool[idx].buffer[0]); + hf_sendbuff_ctrl.mempool[idx].packet.dataLen = Info->p.audioData->len; + hf_sendbuff_ctrl.mempool[idx].packet.flags = BTP_FLAG_NONE; + if(!app_bt_device.hf_mute_flag){ + HF_SendAudioData(Chan, &hf_sendbuff_ctrl.mempool[idx].packet); + } + hf_sendbuff_ctrl.index++; + } +#endif + + } + +#if defined(SCO_LOOP) + memcpy(hf_loop_buffer + hf_loop_buffer_w_idx*HF_LOOP_SIZE, Info->p.audioData->data, Info->p.audioData->len); + hf_loop_buffer_len[hf_loop_buffer_w_idx] = Info->p.audioData->len; + hf_loop_buffer_w_idx = (hf_loop_buffer_w_idx+1)%HF_LOOP_CNT; + ++hf_loop_buffer_size; + + if (hf_loop_buffer_size >= 18 && hf_loop_buffer_valid == 1) { + hf_loop_buffer_valid = 0; + idx = hf_loop_buffer_w_idx-17<0?(HF_LOOP_CNT-(17-hf_loop_buffer_w_idx)):hf_loop_buffer_w_idx-17; + pkt.flags = BTP_FLAG_NONE; + pkt.dataLen = hf_loop_buffer_len[idx]; + pkt.data = hf_loop_buffer + idx*HF_LOOP_SIZE; + HF_SendAudioData(Chan, &pkt); + } +#endif + break; + case HS_EVENT_SERVICE_DISCONNECTED: + TRACE(2,"::HS_EVENT_SERVICE_DISCONNECTED Chan_id:%d, reason=%x\n", chan_id_flag.id,Info->p.remDev->discReason); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_VOICE,chan_id_flag.id,MAX_RECORD_NUM); + +#if !defined(FPGA) && defined(__BTIF_EARPHONE__) + if(app_bt_device.hs_conn_flag[chan_id_flag.id] ){ + ////report device disconnected voice + app_bt_device.hs_conn_flag[chan_id_flag.id] = 0; + + } +#endif + app_bt_stream_volume_ptr_update(NULL); + + app_bt_profile_connect_manager_hs(chan_id_flag.id, Chan, Info); + for (uint8_t i=0; istatus == BT_STATUS_SUCCESS){ + TRACE(1,"::HS_EVENT_AUDIO_CONNECTED chan_id:%d\n", chan_id_flag.id); + if((Chan->state == HF_STATE_OPEN) && (app_bt_device.hs_conn_flag[chan_id_flag.id] == 1)){ + app_bt_device.hschan_call[BT_DEVICE_ID_1] = MODIFY_HS_CALL_ACTIVE; + } + + app_bt_device.curr_hs_channel_id = chan_id_flag.id; + + app_bt_device.phone_earphone_mark = 0; + app_bt_device.hs_mute_flag = 0; + + app_bt_device.hs_audio_state[chan_id_flag.id] = HF_AUDIO_CON; + +#if defined(__FORCE_REPORTVOLUME_SOCON__) + + app_hs_handle_cmd(Chan,APP_REPORT_SPEAKER_VOL_CMD); + +#endif + + if (bt_media_cur_is_bt_stream_media()) + { + app_hfp_set_starting_media_pending_flag(true, BT_DEVICE_ID_1); + } + else + { + app_hfp_start_voice_media(BT_DEVICE_ID_1); + } + + } + break; + case HS_EVENT_AUDIO_DISCONNECTED: + TRACE(1,"::HS_EVENT_AUDIO_DISCONNECTED chan_id:%d\n", chan_id_flag.id); + + if(app_bt_device.hschan_call[chan_id_flag.id] == HF_CALL_ACTIVE){ + app_bt_device.phone_earphone_mark = 1; + } + + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_STOP,BT_STREAM_VOICE,BT_DEVICE_ID_1,MAX_RECORD_NUM); + + break; + + case HS_EVENT_RING_IND: + TRACE(1,"::HS_EVENT_RING_IND chan_id:%d\n", chan_id_flag.id); +#if !defined(FPGA) && defined(__BTIF_EARPHONE__) +// if(app_bt_device.hs_audio_state[chan_id_flag.id] != HF_AUDIO_CON) + app_voice_report(APP_STATUS_INDICATION_INCOMINGCALL,chan_id_flag.id); +#endif + + break; + case HS_EVENT_SPEAKER_VOLUME: + TRACE(2,"::HS_EVENT_SPEAKER_VOLUME chan_id:%d,speaker gain = %x\n", chan_id_flag.id,Info->p.ptr); + hfp_volume_set(chan_id_flag.id, (int)(uint32_t)Info->p.ptr); + break; + + case HS_EVENT_COMMAND_COMPLETE: + TRACE(2,"::EVENT_HS_COMMAND_COMPLETE chan_id:%d %x\n", chan_id_flag.id, (HsCommand *)Info->p.ptr); + if (Info->p.ptr) + app_hsp_hscommand_mempool_free((HsCommand *)Info->p.ptr); + break; + default: + break; + + } +} + + +#endif diff --git a/services/bt_app/app_keyhandle.cpp b/services/bt_app/app_keyhandle.cpp new file mode 100644 index 0000000..85e221c --- /dev/null +++ b/services/bt_app/app_keyhandle.cpp @@ -0,0 +1,1534 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +//#include "mbed.h" +#include +#include "cmsis.h" +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "analog.h" + + +#include "hfp_api.h" +#include "me_api.h" +#include "a2dp_api.h" +#include "avdtp_api.h" +#include "avctp_api.h" +#include "avrcp_api.h" + +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_key.h" +#include "app_audio.h" + +#include "apps.h" +#include "app_bt_stream.h" +#include "app_bt_media_manager.h" +#include "app_bt.h" +#include "app_bt_func.h" +#include "app_hfp.h" +#include "bt_if.h" +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +#include "nvrecord_env.h" +#endif + +#include "os_api.h" +extern struct BT_DEVICE_T app_bt_device; +//BT_DEVICE_ID_T g_current_device_id=BT_DEVICE_NUM; //used to change sco by one-bring-two +//BT_DEVICE_ID_T g_another_device_id=BT_DEVICE_NUM; //used to change sco by one-bring-two + +#ifdef BTIF_HID_DEVICE +#include "app_bt_hid.h" +#endif + +#ifdef SUPPORT_SIRI +extern int app_hfp_siri_report(); +extern int app_hfp_siri_voice(bool en); +int open_siri_flag = 0; +void bt_key_handle_siri_key(enum APP_KEY_EVENT_T event) +{ + switch(event) + { + case APP_KEY_EVENT_NONE: + if(open_siri_flag == 1){ + TRACE(0,"open siri"); + app_hfp_siri_voice(true); + open_siri_flag = 0; + } /*else { + TRACE(0,"evnet none close siri"); + app_hfp_siri_voice(false); + }*/ + break; + case APP_KEY_EVENT_LONGLONGPRESS: + case APP_KEY_EVENT_UP: + //TRACE(0,"long long/up/click event close siri"); + //app_hfp_siri_voice(false); + break; + default: + TRACE(1,"unregister down key event=%x",event); + break; + } +} + +#endif + +//bool hf_mute_flag = 0; + +#if defined (__HSP_ENABLE__) + +extern XaStatus app_hs_handle_cmd(HsChannel *Chan,uint8_t cmd_type); + +void hsp_handle_key(uint8_t hsp_key) +{ + HsCommand *hs_cmd_p; + HsChannel *hs_channel_tmp = NULL; + uint8_t ret= 0; +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T another_device_id = (app_bt_device.curr_hs_channel_id == BT_DEVICE_ID_1) ? BT_DEVICE_ID_2 : BT_DEVICE_ID_1; + TRACE(1,"!!!hsp_handle_key curr_hf_channel=%d\n",app_bt_device.curr_hs_channel_id); + hs_channel_tmp = (app_bt_device.curr_hs_channel_id == BT_DEVICE_ID_1) ? &(app_bt_device.hs_channel[BT_DEVICE_ID_1]) : &(app_bt_device.hs_channel[BT_DEVICE_ID_2]); +#else + hs_channel_tmp = &(app_bt_device.hs_channel[BT_DEVICE_ID_1]); +#endif + + if(hsp_key == HSP_KEY_CKPD_CONTROL) + { + TRACE(0,"hsp_key = HSP_KEY_CKPD_CONTROL"); + if(app_hs_handle_cmd(hs_channel_tmp,APP_CPKD_CMD) !=0) + TRACE(0,"app_hs_handle_cmd err"); + + } + else if(hsp_key == HSP_KEY_CHANGE_TO_PHONE) + { + TRACE(0,"hsp_key = HSP_KEY_CHANGE_TO_PHONE"); + HS_DisconnectAudioLink(hs_channel_tmp); + } + else if(hsp_key == HSP_KEY_ADD_TO_EARPHONE) + { + TRACE(0,"hsp_key = HSP_KEY_ADD_TO_EARPHONE"); + HS_CreateAudioLink(hs_channel_tmp); + } + + +} +#endif +#ifdef __BT_ONE_BRING_TWO__ +uint8_t gHfcallNextSta = HFCALL_NEXT_STA_NULL; +void hfcall_next_sta_handler(hf_event_t event) +{ + TRACE(0,"!!!hfcall_next_sta_handler curr_hf_channel=%d,gHfcallNextSta %d\n",app_bt_device.curr_hf_channel_id,gHfcallNextSta); + //hf_chan_handle_t hf_channel_curr = app_bt_device.hf_channel[app_bt_device.curr_hf_channel_id]; + enum BT_DEVICE_ID_T another_device_id = (app_bt_device.curr_hf_channel_id == BT_DEVICE_ID_1) ? BT_DEVICE_ID_2 : BT_DEVICE_ID_1; + hf_chan_handle_t hf_channel_another = app_bt_device.hf_channel[another_device_id]; + + switch(gHfcallNextSta){ + case HFCALL_NEXT_STA_NULL: + break; + case HFCALL_NEXT_STA_ANOTHER_ANSWER: + if(event == BTIF_HF_EVENT_AUDIO_DISCONNECTED) + { + TRACE(0,"NEXT_ACTION = HFP_ANSWER_ANOTHER_CALL\n"); + btif_hf_answer_call(hf_channel_another); + gHfcallNextSta = HFCALL_NEXT_STA_NULL; + } + case HFCALL_NEXT_STA_ANOTHER_ADDTOEARPHONE: + if(event == BTIF_HF_EVENT_AUDIO_DISCONNECTED) + { + TRACE(0,"NEXT_ACTION = HFP_ANOTHER_ADDTOEARPHONE\n"); + btif_hf_create_audio_link(hf_channel_another); + gHfcallNextSta = HFCALL_NEXT_STA_NULL; + } + break; + } +} +#endif +void hfp_handle_key(uint8_t hfp_key) +{ + hf_chan_handle_t hf_channel_curr = app_bt_device.hf_channel[app_bt_device.curr_hf_channel_id]; +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T another_device_id = (app_bt_device.curr_hf_channel_id == BT_DEVICE_ID_1) ? BT_DEVICE_ID_2 : BT_DEVICE_ID_1; + hf_chan_handle_t hf_channel_another = app_bt_device.hf_channel[another_device_id]; +#endif + switch(hfp_key) + { + case HFP_KEY_ANSWER_CALL: + ///answer a incomming call + TRACE(0,"avrcp_key = HFP_KEY_ANSWER_CALL\n"); + btif_hf_answer_call(hf_channel_curr); + break; + case HFP_KEY_HANGUP_CALL: + TRACE(0,"avrcp_key = HFP_KEY_HANGUP_CALL\n"); + btif_hf_hang_up_call(hf_channel_curr); + break; + case HFP_KEY_REDIAL_LAST_CALL: + ///redail the last call + TRACE(0,"avrcp_key = HFP_KEY_REDIAL_LAST_CALL\n"); + btif_hf_redial_call(hf_channel_curr); + break; + case HFP_KEY_CHANGE_TO_PHONE: + ///remove sco and voice change to phone + if(app_bt_is_hfp_audio_on()) + { + TRACE(0,"avrcp_key = HFP_KEY_CHANGE_TO_PHONE\n"); + btif_hf_disc_audio_link(hf_channel_curr); + } + break; + case HFP_KEY_ADD_TO_EARPHONE: + ///add a sco and voice change to earphone + if(!app_bt_is_hfp_audio_on()) + { + TRACE(0,"avrcp_key = HFP_KEY_ADD_TO_EARPHONE ver:%x\n", btif_hf_get_version(hf_channel_curr)); +#if defined(HFP_1_6_ENABLE) + //if (hf_channel_tmp->negotiated_codec == HF_SCO_CODEC_MSBC){ + if (btif_hf_get_negotiated_codec(hf_channel_curr) == BTIF_HF_SCO_CODEC_MSBC) { + TRACE(0,"at+bcc"); +#ifdef __HFP_OK__ + hfp_handle_add_to_earphone_1_6(hf_channel_curr); +#endif + TRACE(0,"CreateAudioLink"); + btif_hf_create_audio_link(hf_channel_curr); + } else +#endif + { + TRACE(0,"CreateAudioLink"); + btif_hf_create_audio_link(hf_channel_curr); + } + } + break; + case HFP_KEY_MUTE: + TRACE(0,"avrcp_key = HFP_KEY_MUTE\n"); + app_bt_device.hf_mute_flag = 1; + break; + case HFP_KEY_CLEAR_MUTE: + TRACE(0,"avrcp_key = HFP_KEY_CLEAR_MUTE\n"); + app_bt_device.hf_mute_flag = 0; + break; + case HFP_KEY_THREEWAY_HOLD_AND_ANSWER: + TRACE(0,"avrcp_key = HFP_KEY_THREEWAY_HOLD_AND_ANSWER\n"); + btif_hf_call_hold(hf_channel_curr, BTIF_HF_HOLD_HOLD_ACTIVE_CALLS, 0); + break; + case HFP_KEY_THREEWAY_HANGUP_AND_ANSWER: + TRACE(0,"avrcp_key = HFP_KEY_THREEWAY_HOLD_SWAP_ANSWER\n"); + btif_hf_call_hold(hf_channel_curr, BTIF_HF_HOLD_RELEASE_ACTIVE_CALLS, 0); + break; + case HFP_KEY_THREEWAY_HOLD_REL_INCOMING: + TRACE(0,"avrcp_key = HFP_KEY_THREEWAY_HOLD_REL_INCOMING\n"); + btif_hf_call_hold(hf_channel_curr, BTIF_HF_HOLD_RELEASE_HELD_CALLS, 0); + break; +#ifdef __BT_ONE_BRING_TWO__ + case HFP_KEY_DUAL_HF_HANGUP_ANOTHER: + TRACE(0,"avrcp_key = HFP_KEY_DUAL_HF_HANGUP_ANOTHER\n"); + btif_hf_hang_up_call(hf_channel_another); + break; + case HFP_KEY_DUAL_HF_HANGUP_CURR_ANSWER_ANOTHER: + TRACE(0,"avrcp_key = HFP_KEY_DUAL_HF_HANGUP_CURR_ANSWER_ANOTHER\n"); + btif_hf_hang_up_call(hf_channel_curr); + gHfcallNextSta = HFCALL_NEXT_STA_ANOTHER_ANSWER; + break; + case HFP_KEY_DUAL_HF_HOLD_CURR_ANSWER_ANOTHER: + TRACE(0,"avrcp_key = HFP_KEY_DUAL_HF_HOLD_CURR_ANSWER_ANOTHER\n"); +#ifdef __HFP_OK__ + hf_answer_call(hf_channel_another); +#endif + break; + case HFP_KEY_DUAL_HF_CHANGETOPHONE_ANSWER_ANOTHER: + TRACE(0,"avrcp_key = HFP_KEY_DUAL_HF_CHANGETOPHONE_ANSWER_ANOTHER\n"); + btif_hf_disc_audio_link(hf_channel_curr); + gHfcallNextSta = HFCALL_NEXT_STA_ANOTHER_ANSWER; + break; + case HFP_KEY_DUAL_HF_CHANGETOPHONE_ANOTHER_ADDTOEARPHONE: + TRACE(0,"avrcp_key = HFP_KEY_DUAL_HF_CHANGETOPHONE_ANOTHER_ADDTOEARPHONE\n"); + btif_hf_disc_audio_link(hf_channel_curr); + gHfcallNextSta = HFCALL_NEXT_STA_ANOTHER_ADDTOEARPHONE; + break; + case HFP_KEY_DUAL_HF_HANGUP_ANOTHER_ADDTOEARPHONE: + TRACE(0,"avrcp_key = HFP_KEY_DUAL_HF_HANGUP_ANOTHER_ADDTOEARPHONE\n"); + btif_hf_hang_up_call(hf_channel_curr); + gHfcallNextSta = HFCALL_NEXT_STA_ANOTHER_ADDTOEARPHONE; + break; +#endif + + default : + break; + } +} + +//bool a2dp_play_pause_flag = 0; +uint8_t get_avrcp_via_a2dp_id(uint8_t a2dp_id); +extern void a2dp_handleKey(uint8_t a2dp_key) +{ + btif_avrcp_channel_t* avrcp_channel_tmp = NULL; + enum BT_DEVICE_ID_T avrcp_id = BT_DEVICE_NUM; + if(app_bt_device.a2dp_state[app_bt_device.curr_a2dp_stream_id] == 0) + return; + +#ifdef __BT_ONE_BRING_TWO__ + TRACE(1,"!!!a2dp_handleKey curr_a2dp_stream_id=%d\n",app_bt_device.curr_a2dp_stream_id); + avrcp_id = (enum BT_DEVICE_ID_T )get_avrcp_via_a2dp_id(app_bt_device.curr_a2dp_stream_id); + if(avrcp_id == BT_DEVICE_NUM) + avrcp_id = BT_DEVICE_ID_1; + avrcp_channel_tmp = app_bt_device.avrcp_channel[avrcp_id]; +#else + avrcp_id = BT_DEVICE_ID_1; + avrcp_channel_tmp = app_bt_device.avrcp_channel[avrcp_id]; +#endif + + if (!btif_avrcp_is_control_channel_connected(avrcp_channel_tmp)) + { + TRACE(1, "avrcp_key %d the channel is not connected", a2dp_key); + return; + } + + switch(a2dp_key) + { + case AVRCP_KEY_STOP: + TRACE(0,"avrcp_key = AVRCP_KEY_STOP"); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_STOP,TRUE); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_STOP,FALSE); + app_bt_device.a2dp_play_pause_flag = 0; + break; + case AVRCP_KEY_PLAY: + TRACE(0,"avrcp_key = AVRCP_KEY_PLAY"); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_PLAY,TRUE); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_PLAY,FALSE); + app_bt_device.a2dp_play_pause_flag = 1; + break; + case AVRCP_KEY_PAUSE: + TRACE(0,"avrcp_key = AVRCP_KEY_PAUSE"); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_PAUSE,TRUE); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_PAUSE,FALSE); + app_bt_device.a2dp_play_pause_flag = 0; + break; + case AVRCP_KEY_FORWARD: + TRACE(0,"avrcp_key = AVRCP_KEY_FORWARD"); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_FORWARD,TRUE); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_FORWARD,FALSE); + app_bt_device.a2dp_play_pause_flag = 1; + break; + case AVRCP_KEY_BACKWARD: + TRACE(0,"avrcp_key = AVRCP_KEY_BACKWARD"); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_BACKWARD,TRUE); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_BACKWARD,FALSE); + app_bt_device.a2dp_play_pause_flag = 1; + break; + case AVRCP_KEY_VOLUME_UP: + TRACE(0,"avrcp_key = AVRCP_KEY_VOLUME_UP"); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_VOLUME_UP,TRUE); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_VOLUME_UP,FALSE); + break; + case AVRCP_KEY_VOLUME_DOWN: + TRACE(0,"avrcp_key = AVRCP_KEY_VOLUME_DOWN"); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_VOLUME_DOWN,TRUE); + btif_avrcp_set_panel_key(avrcp_channel_tmp,BTIF_AVRCP_POP_VOLUME_DOWN,FALSE); + break; + default : + break; + } +} + +//uint8_t phone_earphone_mark = 0; +#if 0//def __BT_ONE_BRING_TWO__ +#define HF_CHANNEL_SWITCH_HOOK_USER APP_BT_GOLBAL_HANDLE_HOOK_USER_0 + +enum HF_CHANNEL_SWITCH_STATUS{ + HF_CHANNEL_SWITCH_STATUS_IDLE, + HF_CHANNEL_SWITCH_STATUS_ONPROCESS, +}; + +struct HF_CHANNEL_SWITCH_ENV_T{ + BT_DEVICE_ID_T old_device_id; + hf_chan_handle_t hf_channel_old; + BT_DEVICE_ID_T new_device_id; + hf_chan_handle_t hf_channel_new; + enum HF_CHANNEL_SWITCH_STATUS status; +}hf_channel_switch_env; + +static void bt_key_hf_channel_switch_hook(const btif_event_t *Event); + +static void bt_key_hf_channel_switch_stop(void) +{ + hf_channel_switch_env.status = HF_CHANNEL_SWITCH_STATUS_IDLE; + hf_channel_switch_env.old_device_id = BT_DEVICE_NUM; + hf_channel_switch_env.hf_channel_old = NULL; + hf_channel_switch_env.new_device_id = BT_DEVICE_NUM; + hf_channel_switch_env.hf_channel_new = NULL; + app_bt_global_handle_hook_set(HF_CHANNEL_SWITCH_HOOK_USER, NULL); +} + +#ifdef __HF_KEEP_ONE_ALIVE__ +static void bt_key_hf_channel_switch_active(BT_DEVICE_ID_T current_id, BT_DEVICE_ID_T another_id) +{ + TRACE(2,"switch_active %d-->%d", current_id, another_id); + + hf_channel_switch_env.old_device_id = current_id; + hf_channel_switch_env.hf_channel_old = (app_bt_device.hf_channel[current_id]); + + hf_channel_switch_env.new_device_id = another_id; + hf_channel_switch_env.hf_channel_new = (app_bt_device.hf_channel[another_id]); + + app_bt_HF_DisconnectAudioLink(hf_channel_switch_env.hf_channel_old); + app_bt_HF_CreateAudioLink(hf_channel_switch_env.hf_channel_new); +} +#endif + +static void bt_key_hf_channel_switch_start(void) +{ + uint8_t i; + + TRACE(2,"%s status:%d enter",__func__, hf_channel_switch_env.status ); + if (hf_channel_switch_env.status == HF_CHANNEL_SWITCH_STATUS_ONPROCESS){ + return; + } + + for (i=0; i= BTIF_HF_CALL_SETUP_OUT) && + current_call == BTIF_HF_CALL_NONE) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_OUTGOING!!!!"); + status = HFCALL_MACHINE_CURRENT_OUTGOING; + } + // current AG is calling. + else if( (current_callSetup ==BTIF_HF_CALL_SETUP_NONE) && + current_call == BTIF_HF_CALL_ACTIVE && + current_callheld != BTIF_HF_CALL_HELD_ACTIVE) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_CALLING!!!!"); + status = HFCALL_MACHINE_CURRENT_CALLING; + } + // current AG is 3way incomming. + else if( current_callSetup ==BTIF_HF_CALL_SETUP_IN && + current_call == BTIF_HF_CALL_ACTIVE && + current_callheld == BTIF_HF_CALL_HELD_NONE) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_3WAY_INCOMMING!!!!"); + status = HFCALL_MACHINE_CURRENT_3WAY_INCOMMING; + } + // current AG is 3way hold calling. + else if( current_callSetup ==BTIF_HF_CALL_SETUP_NONE && + current_call == BTIF_HF_CALL_ACTIVE && + current_callheld == BTIF_HF_CALL_HELD_ACTIVE) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING!!!!"); + status = HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING; + } + else + { + TRACE(0,"current hfcall machine status is not found!!!!!!"); + } +#else + // current AG is idle , another AG is idle. + if( current_callSetup ==BTIF_HF_CALL_SETUP_NONE && + current_call == BTIF_HF_CALL_NONE && + current_audioState == BTIF_HF_AUDIO_DISCON && + another_callSetup==BTIF_HF_CALL_SETUP_NONE && + another_call == BTIF_HF_CALL_NONE && + another_audioState == BTIF_HF_AUDIO_DISCON ) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_IDLE_ANOTHER_IDLE!!!!"); + status = HFCALL_MACHINE_CURRENT_IDLE_ANOTHER_IDLE; + } + // current AG is on incomming , another AG is idle. + else if( current_callSetup == BTIF_HF_CALL_SETUP_IN && + current_call == BTIF_HF_CALL_NONE && + another_callSetup==BTIF_HF_CALL_SETUP_NONE && + another_call == BTIF_HF_CALL_NONE && + another_audioState == BTIF_HF_AUDIO_DISCON ) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_IDLE!!!!"); + status = HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_IDLE; + } + // current AG is on outgoing , another AG is idle. + else if( current_callSetup >= BTIF_HF_CALL_SETUP_OUT && + current_call == BTIF_HF_CALL_NONE && + another_callSetup == BTIF_HF_CALL_SETUP_NONE && + another_call == BTIF_HF_CALL_NONE && + another_audioState == BTIF_HF_AUDIO_DISCON ) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_IDLE!!!!"); + status = HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_IDLE; + } + // current AG is on calling , another AG is idle. + else if( current_callSetup == BTIF_HF_CALL_SETUP_NONE && + current_call == BTIF_HF_CALL_ACTIVE && + current_callheld != BTIF_HF_CALL_HELD_ACTIVE&& + another_callSetup == BTIF_HF_CALL_SETUP_NONE && + another_call == BTIF_HF_CALL_NONE && + another_audioState == BTIF_HF_AUDIO_DISCON ) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_IDLE!!!!"); + status = HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_IDLE; + } + // current AG is 3way incomming , another AG is idle. + else if( current_callSetup ==BTIF_HF_CALL_SETUP_IN && + current_call == BTIF_HF_CALL_ACTIVE && + current_callheld == BTIF_HF_CALL_HELD_NONE&& + another_callSetup == BTIF_HF_CALL_SETUP_NONE && + another_call == BTIF_HF_CALL_NONE && + another_audioState == BTIF_HF_AUDIO_DISCON ) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_3WAY_INCOMMING_ANOTHER_IDLE!!!!"); + status = HFCALL_MACHINE_CURRENT_3WAY_INCOMMING_ANOTHER_IDLE; + } + // current AG is 3way hold calling , another AG is without connecting. + else if( current_callSetup ==BTIF_HF_CALL_SETUP_NONE && + current_call == BTIF_HF_CALL_ACTIVE && + current_callheld == BTIF_HF_CALL_HELD_ACTIVE&& + another_callSetup == BTIF_HF_CALL_SETUP_NONE && + another_call == BTIF_HF_CALL_NONE && + another_audioState == BTIF_HF_AUDIO_DISCON ) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING_ANOTHER_IDLE!!!!"); + status = HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING_ANOTHER_IDLE; + } + // current AG is incomming , another AG is incomming too. + else if( current_callSetup == BTIF_HF_CALL_SETUP_IN && + current_call == BTIF_HF_CALL_NONE && + current_callheld == BTIF_HF_CALL_HELD_NONE&& + another_callSetup == BTIF_HF_CALL_SETUP_IN && + another_call == BTIF_HF_CALL_NONE && + another_callheld == BTIF_HF_CALL_HELD_NONE) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_INCOMMING!!!!"); + status = HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_INCOMMING; + } + // current AG is outgoing , another AG is incomming too. + else if( current_callSetup == BTIF_HF_CALL_SETUP_OUT && + current_call == BTIF_HF_CALL_NONE && + current_callheld == BTIF_HF_CALL_HELD_NONE&& + another_callSetup == BTIF_HF_CALL_SETUP_IN && + another_call == BTIF_HF_CALL_NONE && + another_callheld == BTIF_HF_CALL_HELD_NONE) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_INCOMMING!!!!"); + status = HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_INCOMMING; + } + // current AG is calling , another AG is incomming. + else if( current_callSetup == BTIF_HF_CALL_SETUP_NONE && + current_call == BTIF_HF_CALL_ACTIVE && + current_callheld == BTIF_HF_CALL_HELD_NONE&& + another_callSetup == BTIF_HF_CALL_SETUP_IN && + another_call == BTIF_HF_CALL_NONE && + another_callheld == BTIF_HF_CALL_HELD_NONE) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_INCOMMING!!!!"); + status = HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_INCOMMING; + } + // current AG is on calling , another AG calling changed to phone. + else if( current_callSetup == BTIF_HF_CALL_SETUP_NONE && + current_call == BTIF_HF_CALL_ACTIVE && + current_callheld == BTIF_HF_CALL_HELD_NONE&& + another_callSetup == BTIF_HF_CALL_SETUP_NONE && + another_call == BTIF_HF_CALL_ACTIVE && + another_callheld == BTIF_HF_CALL_HELD_NONE&& + another_audioState == BTIF_HF_AUDIO_DISCON) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_CHANGETOPHONE!!!!"); + status = HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_CHANGETOPHONE; + } + // current AG is on calling , another AG calling is hold. + else if( current_callSetup == BTIF_HF_CALL_SETUP_NONE && + current_call == BTIF_HF_CALL_ACTIVE && + current_callheld == BTIF_HF_CALL_HELD_NONE&& + another_callSetup == BTIF_HF_CALL_SETUP_NONE && + another_call == BTIF_HF_CALL_ACTIVE && + another_callheld == BTIF_HF_CALL_HELD_ACTIVE) + { + TRACE(0,"current hfcall machine status is HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_HOLD!!!!"); + status = HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_HOLD; + } + else + { + TRACE(0,"current hfcall machine status is not found!!!!!!"); + } +#endif +// TRACE(0,"%s status is %d",__func__,status); + return status; +} + +void bt_key_handle_func_click(void) +{ + TRACE(0,"%s enter",__func__); + + HFCALL_MACHINE_ENUM hfcall_machine = app_get_hfcall_machine(); + switch(hfcall_machine) + { + case HFCALL_MACHINE_CURRENT_IDLE: + { + if(app_bt_device.a2dp_play_pause_flag == 0){ + a2dp_handleKey(AVRCP_KEY_PLAY); + }else{ + a2dp_handleKey(AVRCP_KEY_PAUSE); + } + } + break; + case HFCALL_MACHINE_CURRENT_INCOMMING: + hfp_handle_key(HFP_KEY_ANSWER_CALL); + break; + case HFCALL_MACHINE_CURRENT_OUTGOING: + hfp_handle_key(HFP_KEY_HANGUP_CALL); + break; + case HFCALL_MACHINE_CURRENT_CALLING: + hfp_handle_key(HFP_KEY_HANGUP_CALL); + break; + case HFCALL_MACHINE_CURRENT_3WAY_INCOMMING: + hfp_handle_key(HFP_KEY_THREEWAY_HANGUP_AND_ANSWER); + break; + case HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING: + hfp_handle_key(HFP_KEY_THREEWAY_HOLD_AND_ANSWER); + break; +#ifdef __BT_ONE_BRING_TWO__ + case HFCALL_MACHINE_CURRENT_IDLE_ANOTHER_IDLE: + { + if(app_bt_device.a2dp_play_pause_flag == 0){ + a2dp_handleKey(AVRCP_KEY_PLAY); + }else{ + a2dp_handleKey(AVRCP_KEY_PAUSE); + } + } + break; + case HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_IDLE: + hfp_handle_key(HFP_KEY_ANSWER_CALL); + break; + case HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_IDLE: + hfp_handle_key(HFP_KEY_HANGUP_CALL); + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_IDLE: + hfp_handle_key(HFP_KEY_HANGUP_CALL); + break; + case HFCALL_MACHINE_CURRENT_3WAY_INCOMMING_ANOTHER_IDLE: + hfp_handle_key(HFP_KEY_THREEWAY_HANGUP_AND_ANSWER); + break; + case HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING_ANOTHER_IDLE: + hfp_handle_key(HFP_KEY_THREEWAY_HOLD_AND_ANSWER); + break; + case HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_INCOMMING: + break; + case HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_INCOMMING: + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_INCOMMING: + hfp_handle_key(HFP_KEY_DUAL_HF_HANGUP_CURR_ANSWER_ANOTHER); + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_CHANGETOPHONE: + hfp_handle_key(HFP_KEY_DUAL_HF_HANGUP_ANOTHER_ADDTOEARPHONE); + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_HOLD: + hfp_handle_key(HFP_KEY_DUAL_HF_HANGUP_CURR_ANSWER_ANOTHER); + break; +#endif + default: + break; + } +#if defined (__HSP_ENABLE__) + //now we know it is HSP active ! + if(app_bt_device.hs_conn_flag[app_bt_device.curr_hs_channel_id] == 1){ + hsp_handle_key(HSP_KEY_CKPD_CONTROL); + } +#endif +#if HF_CUSTOM_FEATURE_SUPPORT & HF_CUSTOM_FEATURE_SIRI_REPORT + open_siri_flag = 0; +#endif + return; +} +void bt_key_handle_func_doubleclick(void) +{ + TRACE(0,"%s enter",__func__); + + HFCALL_MACHINE_ENUM hfcall_machine = app_get_hfcall_machine(); + +#ifdef SUPPORT_SIRI + open_siri_flag=0; +#endif + + switch(hfcall_machine) + { + case HFCALL_MACHINE_CURRENT_IDLE: +#ifdef BTIF_HID_DEVICE + app_bt_hid_send_capture(app_bt_device.hid_channel[BT_DEVICE_ID_1]); +#else + hfp_handle_key(HFP_KEY_REDIAL_LAST_CALL); +#endif + break; + case HFCALL_MACHINE_CURRENT_INCOMMING: + break; + case HFCALL_MACHINE_CURRENT_OUTGOING: + break; + case HFCALL_MACHINE_CURRENT_CALLING: + if(app_bt_device.hf_mute_flag == 0){ + hfp_handle_key(HFP_KEY_MUTE); + app_bt_device.hf_mute_flag = 1; + }else{ + hfp_handle_key(HFP_KEY_CLEAR_MUTE); + app_bt_device.hf_mute_flag = 0; + } + break; + case HFCALL_MACHINE_CURRENT_3WAY_INCOMMING: + hfp_handle_key(HFP_KEY_THREEWAY_HOLD_REL_INCOMING); + break; + case HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING: + break; +#ifdef __BT_ONE_BRING_TWO__ + case HFCALL_MACHINE_CURRENT_IDLE_ANOTHER_IDLE: +#ifdef BTIF_HID_DEVICE + app_bt_hid_send_capture(app_bt_device.hid_channel[BT_DEVICE_ID_1]); +#else + hfp_handle_key(HFP_KEY_REDIAL_LAST_CALL); +#endif + break; + case HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_IDLE: + break; + case HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_IDLE: + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_IDLE: + if(app_bt_device.hf_mute_flag == 0){ + hfp_handle_key(HFP_KEY_MUTE); + }else{ + hfp_handle_key(HFP_KEY_CLEAR_MUTE); + } + break; + case HFCALL_MACHINE_CURRENT_3WAY_INCOMMING_ANOTHER_IDLE: + hfp_handle_key(HFP_KEY_THREEWAY_HOLD_REL_INCOMING); + break; + case HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING_ANOTHER_IDLE: + break; + case HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_INCOMMING: + break; + case HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_INCOMMING: + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_INCOMMING: + hfp_handle_key(HFP_KEY_DUAL_HF_HANGUP_ANOTHER); + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_CHANGETOPHONE: + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_HOLD: + break; +#endif + default: + break; + } +} +void bt_key_handle_func_longpress(void) +{ + TRACE(0,"%s enter",__func__); + HFCALL_MACHINE_ENUM hfcall_machine = app_get_hfcall_machine(); +#ifdef SUPPORT_SIRI + open_siri_flag=0; +#endif + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); + + switch(hfcall_machine) + { + case HFCALL_MACHINE_CURRENT_IDLE: + { +#if HF_CUSTOM_FEATURE_SUPPORT & HF_CUSTOM_FEATURE_SIRI_REPORT + if(open_siri_flag == 0 ) + { + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); + open_siri_flag = 1; + } +#endif + } + break; + case HFCALL_MACHINE_CURRENT_INCOMMING: + hfp_handle_key(HFP_KEY_HANGUP_CALL); + break; + case HFCALL_MACHINE_CURRENT_OUTGOING: + break; + case HFCALL_MACHINE_CURRENT_CALLING: + { + if(app_bt_device.phone_earphone_mark == 0){ + //call is active, switch from earphone to phone + hfp_handle_key(HFP_KEY_CHANGE_TO_PHONE); + }else if(app_bt_device.phone_earphone_mark == 1){ + //call is active, switch from phone to earphone + hfp_handle_key(HFP_KEY_ADD_TO_EARPHONE); + } + } + break; + case HFCALL_MACHINE_CURRENT_3WAY_INCOMMING: + { + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); + hfp_handle_key(HFP_KEY_THREEWAY_HOLD_AND_ANSWER); + } + break; + case HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING: + hfp_handle_key(HFP_KEY_THREEWAY_HANGUP_AND_ANSWER); + break; +#ifdef __BT_ONE_BRING_TWO__ + case HFCALL_MACHINE_CURRENT_IDLE_ANOTHER_IDLE: +#ifdef BTIF_HID_DEVICE + Hid_Send_capture(&app_bt_device.hid_channel[BT_DEVICE_ID_1]); +#endif + break; + case HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_IDLE: + hfp_handle_key(HFP_KEY_HANGUP_CALL); + break; + case HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_IDLE: + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_IDLE: + { + if(app_bt_device.phone_earphone_mark == 0){ + //call is active, switch from earphone to phone + hfp_handle_key(HFP_KEY_CHANGE_TO_PHONE); + }else if(app_bt_device.phone_earphone_mark == 1){ + //call is active, switch from phone to earphone + hfp_handle_key(HFP_KEY_ADD_TO_EARPHONE); + } + } + break; + case HFCALL_MACHINE_CURRENT_3WAY_INCOMMING_ANOTHER_IDLE: + hfp_handle_key(HFP_KEY_THREEWAY_HOLD_AND_ANSWER); + break; + case HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING_ANOTHER_IDLE: + hfp_handle_key(HFP_KEY_THREEWAY_HANGUP_AND_ANSWER); + break; + case HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_INCOMMING: + break; + case HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_INCOMMING: + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_INCOMMING: + hfp_handle_key(HFP_KEY_DUAL_HF_CHANGETOPHONE_ANSWER_ANOTHER); + //hfp_handle_key(HFP_KEY_DUAL_HF_HOLD_CURR_ANSWER_ANOTHER); + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_CHANGETOPHONE: + hfp_handle_key(HFP_KEY_DUAL_HF_CHANGETOPHONE_ANOTHER_ADDTOEARPHONE); + break; + case HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_HOLD: + hfp_handle_key(HFP_KEY_DUAL_HF_HANGUP_CURR_ANSWER_ANOTHER); + break; +#endif + default: + break; + } +#if defined (__HSP_ENABLE__) + if(hfcall_machine == HFCALL_MACHINE_NUM){ + if(app_bt_device.hs_conn_flag[app_bt_device.curr_hs_channel_id] == 1){ //now we know it is HSP active ! + if(app_bt_device.phone_earphone_mark == 0){ + //call is active, switch from earphone to phone + hsp_handle_key(HSP_KEY_CHANGE_TO_PHONE); + }else if(app_bt_device.phone_earphone_mark == 1){ + //call is active, switch from phone to earphone + hsp_handle_key(HSP_KEY_ADD_TO_EARPHONE); + } + } + } +#endif +} + +void bt_key_handle_func_key(enum APP_KEY_EVENT_T event) +{ + switch (event) { + case APP_KEY_EVENT_UP: + case APP_KEY_EVENT_CLICK: + bt_key_handle_func_click(); + break; + case APP_KEY_EVENT_DOUBLECLICK: + bt_key_handle_func_doubleclick(); + break; + case APP_KEY_EVENT_LONGPRESS: + bt_key_handle_func_longpress(); + break; + default: + TRACE(0,"unregister func key event=%x", event); + break; + } +} + +#if 0 +void bt_key_handle_func_key(enum APP_KEY_EVENT_T event) +{ +#ifdef __BT_ONE_BRING_TWO__ + //if(g_current_device_id == BT_DEVICE_NUM) + BT_DEVICE_ID_T current_device_id; + BT_DEVICE_ID_T another_device_id; + + current_device_id = app_bt_device.curr_hf_channel_id; + another_device_id = (current_device_id == BT_DEVICE_ID_1) ? BT_DEVICE_ID_2 : BT_DEVICE_ID_1; +#endif + + switch(event) + { +#ifndef __BT_ONE_BRING_TWO__ + case APP_KEY_EVENT_UP: + case APP_KEY_EVENT_CLICK: + bt_key_handle_func_click(); + break; + case APP_KEY_EVENT_DOUBLECLICK: + bt_key_handle_func_doubleclick(); + break; + case APP_KEY_EVENT_LONGPRESS: + bt_key_handle_func_longpress(); + break; +#else + case APP_KEY_EVENT_UP: + case APP_KEY_EVENT_CLICK: + TRACE(8,"!!!APP_KEY_EVENT_CLICK callsetup %d %d call %d %d held %d %d audio_state %d %d\n", + app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1], app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2], + app_bt_device.hfchan_call[BT_DEVICE_ID_1], app_bt_device.hfchan_call[BT_DEVICE_ID_2], + app_bt_device.hf_callheld[BT_DEVICE_ID_1], app_bt_device.hf_callheld[BT_DEVICE_ID_2], + app_bt_device.hf_audio_state[BT_DEVICE_ID_1], app_bt_device.hf_audio_state[BT_DEVICE_ID_2]); + + if((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(app_bt_device.hf_audio_state[BT_DEVICE_ID_1] == BTIF_HF_AUDIO_DISCON)&& + (app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_NONE)&&(app_bt_device.hf_audio_state[BT_DEVICE_ID_2] == BTIF_HF_AUDIO_DISCON)){ + if(app_bt_device.a2dp_play_pause_flag == 0){ + a2dp_handleKey(AVRCP_KEY_PLAY); + }else{ + a2dp_handleKey(AVRCP_KEY_PAUSE); + } + } + + if(((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_IN)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_NONE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] != BTIF_HF_CALL_SETUP_ALERT))) { + //hfp_handle_key(HFP_KEY_ANSWER_CALL); + /* (A incoming && B no active) */ + TRACE(0,"!!!!answer call hf_channel=0\n"); + btif_hf_answer_call(app_bt_device.hf_channel[BT_DEVICE_ID_1]); + } else if ((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_IN)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] != BTIF_HF_CALL_SETUP_ALERT)) { + //hfp_handle_key(HFP_KEY_ANSWER_CALL); + /* B incoming && A no active */ + TRACE(0,"!!!!answer call hf_channel=1\n"); + btif_hf_answer_call(app_bt_device.hf_channel[BT_DEVICE_ID_2]); + } + + if (((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_OUT)||(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_ALERT))&&(app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_NONE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_NONE)) { + TRACE(0,"!!!!call out hangup hf_channel=0\n"); + //hfp_handle_key(HFP_KEY_HANGUP_CALL); + /* (A outgoing && B no active no setup */ + btif_hf_hang_up_call(app_bt_device.hf_channel[BT_DEVICE_ID_1]); + } else if (((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_OUT)||(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_ALERT))&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)) { + TRACE(0,"!!!!call out hangup hf_channel=1\n"); + //hfp_handle_key(HFP_KEY_HANGUP_CALL); + /* B outgoing && A no active no setup */ + btif_hf_hang_up_call(app_bt_device.hf_channel[BT_DEVICE_ID_2]); + } + + if(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_ACTIVE){ + if((app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_NONE) && + (app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_NONE)) { + if (app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_IN) { + /* A 1-call active 1-call incoming && B on active no setup */ + TRACE(0,"!!!!release active calls hf_channel=0\n"); + btif_hf_call_hold(app_bt_device.hf_channel[BT_DEVICE_ID_1], BTIF_HF_HOLD_RELEASE_ACTIVE_CALLS, 0); + } else { + /* A active && B no active no setup */ + //hfp_handle_key(HFP_KEY_HANGUP_CALL); + TRACE(0,"!!!!hangup call hf_channel=0\n"); + if (app_bt_device.hf_callheld[BT_DEVICE_ID_1] == BTIF_HF_CALL_HELD_NO_ACTIVE) { + btif_hf_call_hold(app_bt_device.hf_channel[BT_DEVICE_ID_1], BTIF_HF_HOLD_HOLD_ACTIVE_CALLS, 0); + } + btif_hf_hang_up_call(app_bt_device.hf_channel[BT_DEVICE_ID_1]); + } + }else if(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_IN){ + //hfp_handle_key(HFP_KEY_DUAL_HF_HANGUP_CURR_ANSWER_ANOTHER); + /* A active && B incoming */ + TRACE(0,"!!!!1hangup active and answer incoming\n"); + btif_hf_hang_up_call(app_bt_device.hf_channel[BT_DEVICE_ID_1]); + btif_hf_answer_call(app_bt_device.hf_channel[BT_DEVICE_ID_2]); + } + }else if(app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_ACTIVE){ + if((app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE) && + (app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)) { + if (app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_IN) { + /* B 1-call active 1-call incoming && A on active no setup */ + TRACE(0,"!!!!release active calls hf_channel=1\n"); + btif_hf_call_hold(app_bt_device.hf_channel[BT_DEVICE_ID_2], BTIF_HF_HOLD_RELEASE_ACTIVE_CALLS, 0); + } else { + /* B active && A no active no setup */ + //hfp_handle_key(HFP_KEY_HANGUP_CALL); + TRACE(0,"!!!!hangup call hf_channel=1\n"); + if (app_bt_device.hf_callheld[BT_DEVICE_ID_2] == BTIF_HF_CALL_HELD_NO_ACTIVE) { + btif_hf_call_hold(app_bt_device.hf_channel[BT_DEVICE_ID_2], BTIF_HF_HOLD_HOLD_ACTIVE_CALLS, 0); + } + btif_hf_hang_up_call(app_bt_device.hf_channel[BT_DEVICE_ID_2]); + } + }else if(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_IN){ + //hfp_handle_key(HFP_KEY_DUAL_HF_HANGUP_CURR_ANSWER_ANOTHER); + /* B active && A incoming */ + TRACE(0,"!!!!2hangup active and answer incoming\n"); + btif_hf_hang_up_call(app_bt_device.hf_channel[BT_DEVICE_ID_2]); + btif_hf_answer_call(app_bt_device.hf_channel[BT_DEVICE_ID_1]); + } + } + + /* A active && B active */ + if((app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_ACTIVE) && + (app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_ACTIVE)){ + TRACE(0,"!!!two call both active\n"); + hfp_handle_key(HFP_KEY_HANGUP_CALL); + } +#ifdef SUPPORT_SIRI + //TRACE(0,"powerkey close siri"); + //app_hfp_siri_voice(false); + open_siri_flag = 0; +#endif + + break; + case APP_KEY_EVENT_DOUBLECLICK: + TRACE(8,"!!!APP_KEY_EVENT_DOUBLECLICK callsetup %d %d call %d %d held %d %d audio_state %d %d\n", + app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1], app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2], + app_bt_device.hfchan_call[BT_DEVICE_ID_1], app_bt_device.hfchan_call[BT_DEVICE_ID_2], + app_bt_device.hf_callheld[BT_DEVICE_ID_1], app_bt_device.hf_callheld[BT_DEVICE_ID_2], + app_bt_device.hf_audio_state[BT_DEVICE_ID_1], app_bt_device.hf_audio_state[BT_DEVICE_ID_2]); + + //if(((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(app_bt_device.hf_channel[BT_DEVICE_ID_2].state == HF_STATE_CLOSED))|| + if(((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&& + (btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_2]) == BTIF_HF_STATE_CLOSED))|| + ((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_NONE))){ + hfp_handle_key(HFP_KEY_REDIAL_LAST_CALL); + } + + if(((app_bt_device.hf_audio_state[BT_DEVICE_ID_1] == BTIF_HF_AUDIO_CON)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_NONE))|| + ((app_bt_device.hf_audio_state[BT_DEVICE_ID_2] == BTIF_HF_AUDIO_CON)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE))){ + if(app_bt_device.hf_mute_flag == 0){ + hfp_handle_key(HFP_KEY_MUTE); + }else{ + hfp_handle_key(HFP_KEY_CLEAR_MUTE); + } + } + + if((app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_IN)){ + /* A active && B incoming */ + //hfp_handle_key(HFP_KEY_DUAL_HF_HANGUP_ANOTHER); + TRACE(0,"!!!!1keep active and reject incoming\n"); + btif_hf_hang_up_call(app_bt_device.hf_channel[BT_DEVICE_ID_2]); + } else if ((app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_IN)){ + /* B active && A incoming */ + //hfp_handle_key(HFP_KEY_DUAL_HF_HANGUP_ANOTHER); + TRACE(0,"!!!!2keep active and reject incoming\n"); + btif_hf_hang_up_call(app_bt_device.hf_channel[BT_DEVICE_ID_1]); + } else if ((app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_IN)) { + /* A 1-call active and 1-call incoming */ + TRACE(0,"!!!!release incoming call hf_channel=0\n"); + btif_hf_call_hold(app_bt_device.hf_channel[BT_DEVICE_ID_1], BTIF_HF_HOLD_RELEASE_HELD_CALLS, 0); + } else if ((app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_IN)) { + /* B 1-call active and 1-call incoming */ + TRACE(0,"!!!!release incoming call hf_channel=1\n"); + btif_hf_call_hold(app_bt_device.hf_channel[BT_DEVICE_ID_2], BTIF_HF_HOLD_RELEASE_HELD_CALLS, 0); + } + + break; + + case APP_KEY_EVENT_TRIPLECLICK: + TRACE(5,"!!!APP_KEY_EVENT_TRIPLECLICK callsetup %d %d call %d %d,phone_earphone_mark %d\n", + app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1], app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2], + app_bt_device.hfchan_call[BT_DEVICE_ID_1], app_bt_device.hfchan_call[BT_DEVICE_ID_2], + app_bt_device.phone_earphone_mark); + if(((app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_NONE))|| + ((app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE))){ + if(app_bt_device.phone_earphone_mark == 0){ + hfp_handle_key(HFP_KEY_CHANGE_TO_PHONE); + }else if(app_bt_device.phone_earphone_mark == 1){ + hfp_handle_key(HFP_KEY_ADD_TO_EARPHONE); + } + } + break; + case APP_KEY_EVENT_LONGPRESS: +#ifdef SUPPORT_SIRI + open_siri_flag=0; +#endif + + + +//one bring two: long press switch sco + TRACE(8,"!!!APP_KEY_EVENT_LONGPRESS callsetup %d %d call %d %d held %d %d audio_state %d %d\n", + app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1], app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2], + app_bt_device.hfchan_call[BT_DEVICE_ID_1], app_bt_device.hfchan_call[BT_DEVICE_ID_2], + app_bt_device.hf_callheld[BT_DEVICE_ID_1], app_bt_device.hf_callheld[BT_DEVICE_ID_2], + app_bt_device.hf_audio_state[BT_DEVICE_ID_1], app_bt_device.hf_audio_state[BT_DEVICE_ID_2]); + + TRACE(6,"app_bt_device.curr_hf_channel_id=%d, g_curr=%d curr=%d another:%d scoHciHandle:%x/%x", app_bt_device.curr_hf_channel_id,current_device_id, + current_device_id, another_device_id, + //app_bt_device.hf_channel[current_device_id].cmgrHandler.scoConnect->scoHciHandle + //,app_bt_device.hf_channel[another_device_id].cmgrHandler.scoConnect->scoHciHandle); + btif_hf_get_sco_hcihandle(app_bt_device.hf_channel[current_device_id]), + btif_hf_get_sco_hcihandle(app_bt_device.hf_channel[another_device_id])); + if((app_bt_device.hfchan_call[current_device_id] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_call[another_device_id] != BTIF_HF_CALL_ACTIVE) + &&(app_bt_device.hfchan_callSetup[another_device_id] == BTIF_HF_CALL_SETUP_IN)){//A is active, B is incoming call + TRACE(2,"HFP_KEY_DUAL_HF_HOLD_CURR_ANSWER_ANOTHER: current=%d, g_current_device_id=%d",app_bt_device.curr_hf_channel_id, current_device_id); +#ifndef FPGA + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); +#endif + //hfp_handle_key(HFP_KEY_DUAL_HF_HOLD_CURR_ANSWER_ANOTHER); //hold and answer + //app_bt_device.curr_hf_channel_id = another_device_id; + btif_hf_answer_call(app_bt_device.hf_channel[another_device_id]); + btif_hf_call_hold(app_bt_device.hf_channel[current_device_id], BTIF_HF_HOLD_HOLD_ACTIVE_CALLS, 0); + } else if ((app_bt_device.hfchan_call[another_device_id] == BTIF_HF_CALL_ACTIVE) && + (app_bt_device.hfchan_call[current_device_id] != BTIF_HF_CALL_ACTIVE) && + (app_bt_device.hfchan_callSetup[current_device_id] == BTIF_HF_CALL_SETUP_IN)) + { + TRACE(2,"HFP_KEY_DUAL_HF_HOLD_CURR_ANSWER_ANOTHER: current=%d, g_current_device_id=%d",app_bt_device.curr_hf_channel_id, current_device_id); +#ifndef FPGA + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); +#endif + btif_hf_answer_call(app_bt_device.hf_channel[current_device_id]); + btif_hf_call_hold(app_bt_device.hf_channel[another_device_id], BTIF_HF_HOLD_HOLD_ACTIVE_CALLS, 0); + } else if (app_bt_device.hfchan_call[current_device_id] == BTIF_HF_CALL_ACTIVE && + app_bt_device.hf_callheld[current_device_id] == BTIF_HF_CALL_HELD_NONE && + app_bt_device.hf_callheld[another_device_id] == BTIF_HF_CALL_HELD_NO_ACTIVE) + { + TRACE(0,"!!!!1switch hold call and active call\n"); +#ifndef FPGA + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); +#endif + btif_hf_call_hold(app_bt_device.hf_channel[current_device_id], BTIF_HF_HOLD_HOLD_ACTIVE_CALLS, 0); + btif_hf_call_hold(app_bt_device.hf_channel[another_device_id], BTIF_HF_HOLD_HOLD_ACTIVE_CALLS, 0); + } else if (app_bt_device.hfchan_call[another_device_id] == BTIF_HF_CALL_ACTIVE && + app_bt_device.hf_callheld[another_device_id] == BTIF_HF_CALL_HELD_NONE && + app_bt_device.hf_callheld[current_device_id] == BTIF_HF_CALL_HELD_NO_ACTIVE) + { + TRACE(0,"!!!!2switch hold call and active call\n"); +#ifndef FPGA + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); +#endif + btif_hf_call_hold(app_bt_device.hf_channel[another_device_id], BTIF_HF_HOLD_HOLD_ACTIVE_CALLS, 0); + btif_hf_call_hold(app_bt_device.hf_channel[current_device_id], BTIF_HF_HOLD_HOLD_ACTIVE_CALLS, 0); + } else if((app_bt_device.hfchan_call[current_device_id] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_call[another_device_id] == BTIF_HF_CALL_ACTIVE) + &&(app_bt_device.hfchan_callSetup[current_device_id] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_callSetup[another_device_id] == BTIF_HF_CALL_SETUP_NONE)){//A is active, B is active + TRACE(2,"AB is active: current=%d, g_current_device_id=%d",app_bt_device.curr_hf_channel_id, current_device_id); +#ifndef FPGA + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); +#endif + if (bt_get_sco_number()>1){ +#ifdef __HF_KEEP_ONE_ALIVE__ + bt_key_hf_channel_switch_active(current_device_id, another_device_id); +#else + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_SWAP_SCO,BT_STREAM_SBC, another_device_id, 0); +#endif + app_bt_device.hf_voice_en[current_device_id] = HF_VOICE_DISABLE; + app_bt_device.hf_voice_en[another_device_id] = HF_VOICE_ENABLE; + app_bt_device.curr_hf_channel_id = another_device_id; + }else{ + bt_key_hf_channel_switch_start(); + } + } else if((app_bt_device.hfchan_call[current_device_id] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_call[another_device_id] == BTIF_HF_CALL_ACTIVE) + &&((app_bt_device.hfchan_callSetup[current_device_id] == BTIF_HF_CALL_SETUP_IN)||(app_bt_device.hfchan_callSetup[another_device_id] == BTIF_HF_CALL_SETUP_IN))){ + TRACE(2,"AB is active and incoming call: current=%d, g_current_device_id=%d",app_bt_device.curr_hf_channel_id, current_device_id); +#ifndef FPGA + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); +#endif + if (bt_get_sco_number()>1){ +#ifdef __HF_KEEP_ONE_ALIVE__ + bt_key_hf_channel_switch_active(current_device_id, another_device_id); +#else + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_SWAP_SCO, BT_STREAM_SBC, another_device_id, 0); +#endif + app_bt_device.hf_voice_en[current_device_id] = HF_VOICE_DISABLE; + app_bt_device.hf_voice_en[another_device_id] = HF_VOICE_ENABLE; + app_bt_device.curr_hf_channel_id = another_device_id; + }else{ + bt_key_hf_channel_switch_start(); + } + } else if(((app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_NONE))|| + ((app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE))){ +//three call + TRACE(0,"three way call"); +#ifndef FPGA + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); +#endif + hfp_handle_key(HFP_KEY_THREEWAY_HOLD_AND_ANSWER); +#if 0 + if(app_bt_device.phone_earphone_mark == 0){ + hfp_handle_key(HFP_KEY_CHANGE_TO_PHONE); + }else if(app_bt_device.phone_earphone_mark == 1){ + hfp_handle_key(HFP_KEY_ADD_TO_EARPHONE); + } +#endif + } else if(((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_IN)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_NONE))|| + ((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_IN)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE))){ + hfp_handle_key(HFP_KEY_HANGUP_CALL); + } +#ifdef BTIF_HID_DEVICE + else if(((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&( btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_2])== BTIF_HF_STATE_CLOSED))|| + ((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_NONE))){ + + Hid_Send_capture(&app_bt_device.hid_channel[BT_DEVICE_ID_1]); + } +#endif +#ifdef SUPPORT_SIRI + else if((open_siri_flag == 0) && + (((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(btif_get_hf_chan_state(app_bt_device.hf_channel[BT_DEVICE_ID_2]) == BTIF_HF_STATE_CLOSED))|| + //(((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(app_bt_device.hf_channel[BT_DEVICE_ID_2].state == BTIF_HF_STATE_CLOSED))|| + ((app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_NONE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_NONE)&&(app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_NONE)))){ +#ifndef FPGA + app_voice_report(APP_STATUS_INDICATION_WARNING, 0); +#endif + open_siri_flag = 1; + } +#endif + + + + #if 0 + if((app_bt_device.hfchan_call[BT_DEVICE_ID_1] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_2] == BTIF_HF_CALL_SETUP_IN)){ + hfp_handle_key(HFP_KEY_DUAL_HF_HOLD_CURR_ANSWER_ANOTHER); + }else if((app_bt_device.hfchan_call[BT_DEVICE_ID_2] == BTIF_HF_CALL_ACTIVE)&&(app_bt_device.hfchan_callSetup[BT_DEVICE_ID_1] == BTIF_HF_CALL_SETUP_IN)){ + hfp_handle_key(HFP_KEY_DUAL_HF_HOLD_CURR_ANSWER_ANOTHER); + } +#endif + break; +#endif/* __BT_ONE_BRING_TWO__ */ + default: + TRACE(1,"unregister func key event=%x",event); + break; + } +} +#endif +void app_bt_volumeup() +{ + app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_UP, 0); +} + + +void app_bt_volumedown() +{ + app_audio_manager_ctrl_volume(APP_AUDIO_MANAGER_VOLUME_CTRL_DOWN, 0); +} + +#if defined(__APP_KEY_FN_STYLE_A__) +void bt_key_handle_up_key(enum APP_KEY_EVENT_T event) +{ +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + struct nvrecord_env_t *nvrecord_env=NULL; +#endif + switch(event) + { + case APP_KEY_EVENT_UP: + case APP_KEY_EVENT_CLICK: + app_bt_volumeup(); + break; + case APP_KEY_EVENT_LONGPRESS: + a2dp_handleKey(AVRCP_KEY_FORWARD); + break; +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + case APP_KEY_EVENT_DOUBLECLICK: + //debug switch src mode + nv_record_env_get(&nvrecord_env); + if(app_bt_device.src_or_snk==BT_DEVICE_SRC) + { + nvrecord_env->src_snk_flag.src_snk_mode =BT_DEVICE_SNK; + } + else + { + nvrecord_env->src_snk_flag.src_snk_mode =BT_DEVICE_SRC; + } + nv_record_env_set(nvrecord_env); + app_reset(); + break; +#endif + default: + TRACE(1,"unregister up key event=%x",event); + break; + } +} + + +void bt_key_handle_down_key(enum APP_KEY_EVENT_T event) +{ + switch(event) + { + case APP_KEY_EVENT_UP: + case APP_KEY_EVENT_CLICK: + app_bt_volumedown(); + break; + case APP_KEY_EVENT_LONGPRESS: + a2dp_handleKey(AVRCP_KEY_BACKWARD); + + break; + default: + TRACE(1,"unregister down key event=%x",event); + break; + } +} +#else //#elif defined(__APP_KEY_FN_STYLE_B__) +void bt_key_handle_up_key(enum APP_KEY_EVENT_T event) +{ + TRACE(1,"%s",__func__); + switch(event) + { + case APP_KEY_EVENT_REPEAT: + app_bt_volumeup(); + break; + case APP_KEY_EVENT_UP: + case APP_KEY_EVENT_CLICK: + a2dp_handleKey(AVRCP_KEY_FORWARD); + break; + default: + TRACE(1,"unregister up key event=%x",event); + break; + } +} + + +void bt_key_handle_down_key(enum APP_KEY_EVENT_T event) +{ + switch(event) + { + case APP_KEY_EVENT_REPEAT: + app_bt_volumedown(); + break; + case APP_KEY_EVENT_UP: + case APP_KEY_EVENT_CLICK: + a2dp_handleKey(AVRCP_KEY_BACKWARD); + break; + default: + TRACE(1,"unregister down key event=%x",event); + break; + } +} +#endif + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +void bt_key_handle_source_func_key(enum APP_KEY_EVENT_T event) +{ + TRACE(2,"%s,%d",__FUNCTION__,event); + static bool onaudioloop = false; + switch(event) + { + case APP_KEY_EVENT_UP: + case APP_KEY_EVENT_CLICK: + app_a2dp_source_find_sink(); + break; + case APP_KEY_EVENT_DOUBLECLICK: + if(app_bt_device.a2dp_state[0]==1) + { + onaudioloop = onaudioloop?false:true; + if (onaudioloop) + { + app_a2dp_start_stream(); + + } + else + { + app_a2dp_suspend_stream(); + } + } + break; + case APP_KEY_EVENT_TRIPLECLICK: + app_a2dp_start_stream(); + break; + default: + TRACE(1,"unregister down key event=%x",event); + break; + } +} +#endif + +APP_KEY_STATUS bt_key; +static void bt_update_key_event(uint32_t code, uint8_t event) +{ + TRACE(3,"%s code:%d evt:%d",__func__, code, event); + + bt_key.code = code; + bt_key.event = event; + osapi_notify_evm(); +} + +void bt_key_send(APP_KEY_STATUS *status) +{ + uint32_t lock = int_lock(); + bool isKeyBusy = false; + if (0xff != bt_key.code) + { + isKeyBusy = true; + } + int_unlock(lock); + + if (!isKeyBusy) + { + app_bt_start_custom_function_in_bt_thread( + (uint32_t)status->code, + (uint32_t)status->event, + (uint32_t)bt_update_key_event); + } +} + +void bt_key_handle(void) +{ + osapi_lock_stack(); + if(bt_key.code != 0xff) + { + TRACE(3,"%s code:%d evt:%d",__func__, bt_key.code, bt_key.event); + switch(bt_key.code) + { + case BTAPP_FUNC_KEY: +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + if(app_bt_device.src_or_snk==BT_DEVICE_SRC) + { + bt_key_handle_source_func_key((enum APP_KEY_EVENT_T)bt_key.event); + } + else +#endif + { + bt_key_handle_func_key((enum APP_KEY_EVENT_T)bt_key.event); + } + break; + case BTAPP_VOLUME_UP_KEY: + bt_key_handle_up_key((enum APP_KEY_EVENT_T)bt_key.event); + break; + case BTAPP_VOLUME_DOWN_KEY: + bt_key_handle_down_key((enum APP_KEY_EVENT_T)bt_key.event); + break; +#ifdef SUPPORT_SIRI + case BTAPP_RELEASE_KEY: + bt_key_handle_siri_key((enum APP_KEY_EVENT_T)bt_key.event); + break; +#endif + default: + TRACE(0,"bt_key_handle undefined key"); + break; + } + bt_key.code = 0xff; + } + osapi_unlock_stack(); +} + +void bt_key_init(void) +{ + Besbt_hook_handler_set(BESBT_HOOK_USER_2, bt_key_handle); +#ifdef __BT_ONE_BRING_TWO__ + //bt_key_hf_channel_switch_init(); +#endif + bt_key.code = 0xff; + bt_key.event = 0xff; +} + diff --git a/services/bt_app/app_media_player.cpp b/services/bt_app/app_media_player.cpp new file mode 100644 index 0000000..6cd4def --- /dev/null +++ b/services/bt_app/app_media_player.cpp @@ -0,0 +1,1504 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include +#include +#include "cmsis.h" +#include "cmsis_os.h" +#include "app_bt_trace.h" +#include "tgt_hardware.h" + +#ifdef MEDIA_PLAYER_SUPPORT + +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_cmu.h" +#include "analog.h" +#include "app_bt_stream.h" +#include "app_overlay.h" +#include "app_audio.h" +#include "app_utils.h" + +#include "res_audio_data.h" +#include "res_audio_data_cn.h" +#include "resources.h" +#include "app_media_player.h" +#include "res_audio_ring.h" +#include "audio_prompt_sbc.h" +#include "app_bt.h" +#include "besbt.h" + +#include "cqueue.h" +#include "btapp.h" +#include "app_bt_media_manager.h" +#ifdef VOICE_DATAPATH +#include "app_voicepath.h" +#include "app_ai_if.h" +#endif + +#if defined(AUDIO_ANC_FB_MC_MEDIA) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) +#include"anc_process.h" +#include "hal_codec.h" +#endif + +#ifdef __THIRDPARTY +#include "app_thirdparty.h" +#endif +#if defined(IBRT) +#include "app_tws_ibrt.h" +#include "app_ibrt_if.h" +#include "app_ibrt_voice_report.h" +#endif +#ifdef __INTERACTION__ +uint8_t g_findme_fadein_vol = TGT_VOLUME_LEVEL_0; +#endif +static char need_init_decoder = 1; +static btif_sbc_decoder_t *media_sbc_decoder = NULL; + +#define SBC_TEMP_BUFFER_SIZE 64 +#define SBC_QUEUE_SIZE (SBC_TEMP_BUFFER_SIZE*16) +CQueue media_sbc_queue; + +static float * media_sbc_eq_band_gain = NULL; + +#ifdef __BT_ANC__ +#define APP_AUDIO_PLAYBACK_BUFF_SIZE (1024*3) +#else +#define APP_AUDIO_PLAYBACK_BUFF_SIZE (1024*4) +#endif + +#if defined(AUDIO_ANC_FB_MC_MEDIA) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) +static enum AUD_BITS_T sample_size_play_bt; +static enum AUD_SAMPRATE_T sample_rate_play_bt; +static uint32_t data_size_play_bt; + +static uint8_t *playback_buf_bt; +static uint32_t playback_size_bt; +static int32_t playback_samplerate_ratio_bt; + +static uint8_t *playback_buf_mc; +static uint32_t playback_size_mc; +static enum AUD_CHANNEL_NUM_T playback_ch_num_bt; +#endif + + + +#define SBC_FRAME_LEN 64 //0x5c /* pcm 512 bytes*/ +static U8* g_app_audio_data = NULL; +static uint32_t g_app_audio_length = 0; +static uint32_t g_app_audio_read = 0; + +static uint32_t g_play_continue_mark = 0; + +static uint8_t app_play_sbc_stop_proc_cnt = 0; + +static uint16_t g_prompt_chnlsel = PROMOT_ID_BIT_MASK_CHNLSEl_ALL; + +//for continue play + +#define MAX_SOUND_NUMBER 10 + +typedef struct tMediaSoundMap +{ + U8* data; //total files + uint32_t fsize; //file index + +}_tMediaSoundMap; + +const tMediaSoundMap* media_sound_map; + +const tMediaSoundMap media_sound_map_cn[MAX_SOUND_NUMBER] = +{ + {(U8*)CN_SOUND_ZERO, sizeof(CN_SOUND_ZERO) }, + {(U8*)CN_SOUND_ONE, sizeof(CN_SOUND_ONE) }, + {(U8*)CN_SOUND_TWO, sizeof(CN_SOUND_TWO) }, + {(U8*)CN_SOUND_THREE, sizeof(CN_SOUND_THREE) }, + {(U8*)CN_SOUND_FOUR, sizeof(CN_SOUND_FOUR) }, + {(U8*)CN_SOUND_FIVE, sizeof(CN_SOUND_FIVE) }, + {(U8*)CN_SOUND_SIX, sizeof(CN_SOUND_SIX) }, + {(U8*)CN_SOUND_SEVEN, sizeof(CN_SOUND_SEVEN) }, + {(U8*)CN_SOUND_EIGHT, sizeof(CN_SOUND_EIGHT) }, + {(U8*)CN_SOUND_NINE, sizeof(CN_SOUND_NINE) }, +}; + +const tMediaSoundMap media_sound_map_en[MAX_SOUND_NUMBER] = +{ + {(U8*)EN_SOUND_ZERO, sizeof(EN_SOUND_ZERO) }, + {(U8*)EN_SOUND_ONE, sizeof(EN_SOUND_ONE) }, + {(U8*)EN_SOUND_TWO, sizeof(EN_SOUND_TWO) }, + {(U8*)EN_SOUND_THREE, sizeof(EN_SOUND_THREE) }, + {(U8*)EN_SOUND_FOUR, sizeof(EN_SOUND_FOUR) }, + {(U8*)EN_SOUND_FIVE, sizeof(EN_SOUND_FIVE) }, + {(U8*)EN_SOUND_SIX, sizeof(EN_SOUND_SIX) }, + {(U8*)EN_SOUND_SEVEN, sizeof(EN_SOUND_SEVEN) }, + {(U8*)EN_SOUND_EIGHT, sizeof(EN_SOUND_EIGHT) }, + {(U8*)EN_SOUND_NINE, sizeof(EN_SOUND_NINE) }, +}; + +const uint8_t BT_MUTE[] = { +#include "res/SOUND_MUTE.txt" +}; + +char Media_player_number[MAX_PHB_NUMBER]; + +typedef struct tPlayContContext +{ + uint32_t g_play_continue_total; //total files + uint32_t g_play_continue_n; //file index + + uint32_t g_play_continue_fread; //per file have readed + + U8 g_play_continue_array[MAX_PHB_NUMBER]; + +}_tPlayContContext; + +tPlayContContext pCont_context; + +APP_AUDIO_STATUS MSG_PLAYBACK_STATUS; +APP_AUDIO_STATUS* ptr_msg_playback = &MSG_PLAYBACK_STATUS; + +static int g_language = MEDIA_DEFAULT_LANGUAGE; +#ifdef AUDIO_LINEIN +static enum AUD_SAMPRATE_T app_play_audio_sample_rate = AUD_SAMPRATE_16000; +#endif + +#define PREFIX_AUDIO(name) ((g_language==MEDIA_DEFAULT_LANGUAGE) ? EN_##name : CN_##name) + +#define PROMPT_MIX_PROPERTY_PTR_FROM_ENTRY_INDEX(index) \ + ((PROMPT_MIX_PROPERTY_T *)((uintptr_t)__mixprompt_property_table_start + \ + (index)*sizeof(PROMPT_MIX_PROPERTY_T))) + +int media_audio_init(void) +{ + const float EQLevel[25] = { + 0.0630957, 0.0794328, 0.1, 0.1258925, 0.1584893, + 0.1995262, 0.2511886, 0.3162278, 0.398107 , 0.5011872, + 0.6309573, 0.794328 , 1, 1.258925 , 1.584893 , + 1.995262 , 2.5118864, 3.1622776, 3.9810717, 5.011872 , + 6.309573 , 7.943282 , 10 , 12.589254, 15.848932 + };//-12~12 + uint8_t *buff = NULL; + uint8_t i; + + app_audio_mempool_get_buff((uint8_t **)&media_sbc_eq_band_gain, CFG_HW_AUD_EQ_NUM_BANDS*sizeof(float)); + + for (i=0; itws_mode) + { + return; + } + + bool isPlayPendingPrompt = false; + uint16_t promptIdToPlay = 0; + + uint32_t lock = int_lock_global(); + if (pending_sync_prompt_cnt > 0) + { + isPlayPendingPrompt = true; + promptIdToPlay = pendingSyncPromptId[pending_sync_prompt_out_index]; + pending_sync_prompt_out_index++; + if (PENDING_SYNC_PROMPT_BUFFER_CNT == pending_sync_prompt_out_index) + { + pending_sync_prompt_out_index = 0; + } + pending_sync_prompt_cnt--; + } + int_unlock_global(lock); + + if (isPlayPendingPrompt) + { + TRACE_MEDIA_PLAYESTREAM_I("[POP_PENDING_PROMPT] 0x%x to play", promptIdToPlay); + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START, + BT_STREAM_MEDIA, 0, promptIdToPlay); + } +} +#endif + +void trigger_media_play(AUD_ID_ENUM id, uint8_t device_id, uint16_t aud_pram) +{ + uint16_t convertedId = (uint8_t)id; + convertedId |= aud_pram; + app_audio_manager_sendrequest(APP_BT_STREAM_MANAGER_START,BT_STREAM_MEDIA,device_id,convertedId); +} +void trigger_media_stop(AUD_ID_ENUM id, uint8_t device_id) +{ + /* Only the stop loop mode is supported */ + if (id == AUDIO_ID_FIND_MY_BUDS) + app_play_sbc_stop_proc_cnt = 1; +} + +uint32_t media_playAudioSideSelect(AUD_ID_ENUM id,uint8_t device_id, uint16_t side_select) +{ + trigger_media_play(id, device_id, PROMOT_ID_BIT_MASK_MERGING|side_select); + return 0; +} + + +uint32_t media_PlayAudio(AUD_ID_ENUM id,uint8_t device_id) +{ + trigger_media_play(id, device_id, PROMOT_ID_BIT_MASK_MERGING|PROMOT_ID_BIT_MASK_CHNLSEl_ALL); + return 0; +} + +void media_PlayAudio_standalone(AUD_ID_ENUM id, uint8_t device_id) +{ + trigger_media_play(id, device_id, false); +} + +void media_PlayAudio_locally(AUD_ID_ENUM id, uint8_t device_id) +{ + trigger_media_play(id, device_id, PROMOT_ID_BIT_MASK_MERGING|PROMOT_ID_BIT_MASK_CHNLSEl_ALL); +} + +void media_PlayAudio_standalone_locally(AUD_ID_ENUM id, uint8_t device_id) +{ + trigger_media_play(id, device_id, PROMOT_ID_BIT_MASK_CHNLSEl_ALL); +} + +void media_PlayAudio_remotely(AUD_ID_ENUM id, uint8_t device_id) +{ + trigger_media_play(id, device_id, PROMOT_ID_BIT_MASK_MERGING|PROMOT_ID_BIT_MASK_CHNLSEl_ALL); +} + +void media_PlayAudio_standalone_remotely(AUD_ID_ENUM id, uint8_t device_id) +{ + trigger_media_play(id, device_id, PROMOT_ID_BIT_MASK_CHNLSEl_ALL); +} + +AUD_ID_ENUM media_GetCurrentPrompt(uint8_t device_id) +{ + AUD_ID_ENUM currentPromptId = AUD_ID_INVALID; + if (app_bt_stream_isrun(APP_PLAY_BACK_AUDIO)) + { + currentPromptId = app_get_current_standalone_promptId(); + } +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + else if (audio_prompt_is_playing_ongoing()) + { + currentPromptId = (AUD_ID_ENUM)audio_prompt_get_prompt_id(); + } +#endif + return currentPromptId; +} + +#define IsDigit(c) (((c)>='0')&&((c)<='9')) +void media_Set_IncomingNumber(const char* pNumber) +{ + char *p_num = Media_player_number; + uint8_t cnt = 0; + for(uint8_t idx = 0; idx < MAX_PHB_NUMBER; idx++) { + if(*(pNumber + idx) == 0) + break; + + if(IsDigit(*(pNumber + idx))) { + *(p_num + cnt) = *(pNumber + idx); + TRACE_MEDIA_PLAYESTREAM_I("[INCOMINGNUMBER] cnt %d ,p_num %d", cnt, *(p_num + cnt)); + cnt ++; + } + } +} + +PROMPT_MIX_PROPERTY_T* get_prompt_mix_property(uint16_t promptId) +{ + for (uint32_t index = 0; + index < ((uint32_t)(uintptr_t)__mixprompt_property_table_end - + (uint32_t)(uintptr_t)__mixprompt_property_table_start) / sizeof(PROMPT_MIX_PROPERTY_T); + index++) + { + if (PROMPT_MIX_PROPERTY_PTR_FROM_ENTRY_INDEX(index)->promptId == promptId) + { + return PROMPT_MIX_PROPERTY_PTR_FROM_ENTRY_INDEX(index); + } + } + + return NULL; +} +/* +Reference information for how to pass +parameters into PROMPT_MIX_PROPERTY_TO_ADD: + +PROMPT_MIX_PROPERTY_TO_ADD( +promptId, +volume_level_override, +coeff_for_mix_prompt_for_music, +coeff_for_mix_music_for_music, +coeff_for_mix_prompt_for_call, +coeff_for_mix_call_for_call) +*/ +void media_runtime_audio_prompt_update(uint16_t id, uint8_t** ptr, uint32_t* len) +{ + switch (id) + { + case AUD_ID_POWER_ON: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_POWER_ON: (U8*)CN_POWER_ON; //aud_get_reouce((AUD_ID_ENUM)id, &g_app_audio_length, &type); + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_POWER_ON): sizeof(CN_POWER_ON); + break; + case AUD_ID_POWER_OFF: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_POWER_OFF: (U8*)CN_POWER_OFF; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_POWER_OFF): sizeof(CN_POWER_OFF); + break; + case AUD_ID_BT_PAIR_ENABLE: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_PAIR_ENABLE: (U8*)CN_BT_PAIR_ENABLE; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_PAIR_ENABLE): sizeof(CN_BT_PAIR_ENABLE); + break; + case AUD_ID_BT_PAIRING: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_BT_PAIRING: (U8*)CN_BT_PAIRING; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_PAIRING): sizeof(CN_BT_PAIRING); + break; + case AUD_ID_BT_PAIRING_SUC: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_PAIRING_SUCCESS: (U8*)CN_BT_PAIRING_SUCCESS; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_PAIRING_SUCCESS): sizeof(CN_BT_PAIRING_SUCCESS); + break; + case AUD_ID_BT_PAIRING_FAIL: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_PAIRING_FAIL: (U8*)CN_BT_PAIRING_FAIL; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_PAIRING_FAIL): sizeof(CN_BT_PAIRING_FAIL); + break; + case AUD_ID_BT_CALL_REFUSE: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_REFUSE: (U8*)CN_BT_REFUSE; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_REFUSE): sizeof(CN_BT_REFUSE); + break; + case AUD_ID_BT_CALL_OVER: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_OVER: (U8*)CN_BT_OVER; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_OVER): sizeof(CN_BT_OVER); + break; + case AUD_ID_BT_CALL_ANSWER: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_ANSWER: (U8*)CN_BT_ANSWER; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_ANSWER): sizeof(CN_BT_ANSWER); + break; + case AUD_ID_BT_CALL_HUNG_UP: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_HUNG_UP: (U8*)CN_BT_HUNG_UP; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_HUNG_UP): sizeof(CN_BT_HUNG_UP); + break; + case AUD_ID_BT_CALL_INCOMING_CALL: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_INCOMING_CALL: (U8*)CN_BT_INCOMING_CALL; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_INCOMING_CALL): sizeof(CN_BT_INCOMING_CALL); + break; + case AUD_ID_BT_CHARGE_PLEASE: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_CHARGE_PLEASE: (U8*)CN_CHARGE_PLEASE; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_CHARGE_PLEASE): sizeof(CN_CHARGE_PLEASE); + break; + case AUD_ID_BT_CHARGE_FINISH: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_CHARGE_FINISH: (U8*)CN_CHARGE_FINISH; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_CHARGE_FINISH): sizeof(CN_CHARGE_FINISH); + break; + case AUD_ID_BT_CONNECTED: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_CONNECTED: (U8*)CN_BT_CONNECTED; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_CONNECTED): sizeof(CN_BT_CONNECTED); + break; + case AUD_ID_BT_DIS_CONNECT: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_DIS_CONNECT: (U8*)CN_BT_DIS_CONNECT; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_DIS_CONNECT): sizeof(CN_BT_DIS_CONNECT); + break; + case AUD_ID_BT_WARNING: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_WARNING: (U8*)CN_BT_WARNING; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_WARNING): sizeof(CN_BT_WARNING); + break; + case AUDIO_ID_BT_ALEXA_START: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_ALEXA_START: (U8*)CN_BT_ALEXA_START; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_ALEXA_START): sizeof(CN_BT_ALEXA_START); + break; + case AUDIO_ID_BT_ALEXA_STOP: + case AUDIO_ID_FIND_MY_BUDS: + case AUDIO_ID_FIND_TILE: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_ALEXA_STOP: (U8*)CN_BT_ALEXA_STOP; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_ALEXA_STOP): sizeof(CN_BT_ALEXA_STOP); + break; + case AUDIO_ID_BT_GSOUND_MIC_OPEN: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_GSOUND_MIC_OPEN: (U8*)CN_BT_GSOUND_MIC_OPEN; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_GSOUND_MIC_OPEN): sizeof(CN_BT_GSOUND_MIC_OPEN); + break; + case AUDIO_ID_BT_GSOUND_MIC_CLOSE: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_GSOUND_MIC_CLOSE: (U8*)CN_BT_GSOUND_MIC_CLOSE; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_GSOUND_MIC_CLOSE): sizeof(CN_BT_GSOUND_MIC_CLOSE); + break; + case AUDIO_ID_BT_GSOUND_NC: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_GSOUND_NC: (U8*)CN_BT_GSOUND_NC; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_GSOUND_NC): sizeof(CN_BT_GSOUND_NC); + break; + case AUD_ID_LANGUAGE_SWITCH: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_LANGUAGE_SWITCH: (U8*)CN_LANGUAGE_SWITCH; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_LANGUAGE_SWITCH): sizeof(CN_LANGUAGE_SWITCH); + break; + case AUDIO_ID_BT_MUTE: + g_app_audio_data = (U8*)BT_MUTE; + g_app_audio_length = sizeof(BT_MUTE); + break; + case AUD_ID_NUM_0: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_SOUND_ZERO: (U8*)CN_SOUND_ZERO; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_SOUND_ZERO): sizeof(CN_SOUND_ZERO); + break; + case AUD_ID_NUM_1: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_SOUND_ONE: (U8*)CN_SOUND_ONE; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_SOUND_ONE): sizeof(CN_SOUND_ONE); + break; + case AUD_ID_NUM_2: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_SOUND_TWO: (U8*)CN_SOUND_TWO; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_SOUND_TWO): sizeof(CN_SOUND_TWO); + break; + case AUD_ID_NUM_3: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_SOUND_THREE: (U8*)CN_SOUND_THREE; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_SOUND_THREE): sizeof(CN_SOUND_THREE); + break; + case AUD_ID_NUM_4: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_SOUND_FOUR: (U8*)CN_SOUND_FOUR; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_SOUND_FOUR): sizeof(CN_SOUND_FOUR); + break; + case AUD_ID_NUM_5: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_SOUND_FIVE: (U8*)CN_SOUND_FIVE; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_SOUND_FIVE): sizeof(CN_SOUND_FIVE); + break; + case AUD_ID_NUM_6: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_SOUND_SIX: (U8*)CN_SOUND_SIX; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_SOUND_SIX): sizeof(CN_SOUND_SIX); + break; + case AUD_ID_NUM_7: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_SOUND_SEVEN: (U8*)CN_SOUND_SEVEN; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_SOUND_SEVEN): sizeof(CN_SOUND_SEVEN); + break; + case AUD_ID_NUM_8: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_SOUND_EIGHT: (U8*)CN_SOUND_EIGHT; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_SOUND_EIGHT): sizeof(CN_SOUND_EIGHT); + break; + case AUD_ID_NUM_9: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)EN_SOUND_NINE: (U8*)CN_SOUND_NINE; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(EN_SOUND_NINE): sizeof(CN_SOUND_NINE); + break; +#ifdef __BT_WARNING_TONE_MERGE_INTO_STREAM_SBC__ + case AUD_ID_RING_WARNING: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)? (U8*)RES_AUD_RING_SAMPRATE_16000: (U8*)RES_AUD_RING_SAMPRATE_16000; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)? sizeof(RES_AUD_RING_SAMPRATE_16000): sizeof(RES_AUD_RING_SAMPRATE_16000); + break; +#endif +#ifdef __INTERACTION__ + case AUD_ID_BT_FINDME: + g_app_audio_data = (g_language==MEDIA_DEFAULT_LANGUAGE)?(U8*)EN_BT_FINDME: (U8*)CN_BT_FINDME; + g_app_audio_length = (g_language==MEDIA_DEFAULT_LANGUAGE)?sizeof(EN_BT_FINDME): sizeof(CN_BT_FINDME); + break; +#endif + case AUDIO_ID_BT_DUDU: + g_app_audio_data = (U8*)EN_BT_DUDU; + g_app_audio_length = sizeof(EN_BT_DUDU); + break; + case AUDIO_ID_BT_DU: + g_app_audio_data = (U8*)EN_BT_DUDU; + g_app_audio_length = sizeof(EN_BT_DUDU); + break; + default: + g_app_audio_length = 0; + break; + } + + *ptr = g_app_audio_data; + *len = g_app_audio_length; +} + +void media_Play_init_audio(uint16_t aud_id) +{ + + if (aud_id == AUD_ID_BT_CALL_INCOMING_NUMBER) + { + g_play_continue_mark = 1; + + if (g_language == MEDIA_DEFAULT_LANGUAGE) + media_sound_map = media_sound_map_en; + else + media_sound_map = media_sound_map_cn; + + memset(&pCont_context, 0x0, sizeof(pCont_context)); + + pCont_context.g_play_continue_total = strlen((const char*)Media_player_number); + + for (uint32_t i=0;( i 0; i--){ + *(buf+j) = *(buf+j)*i/len; + j++; + } + + return len; +} + +static uint32_t need_fadein_len = 0; +static uint32_t need_fadein_len_processed = 0; + +int app_play_sbc_more_data_fadein_config(uint32_t len) +{ + TRACE_MEDIA_PLAYESTREAM_I("[FADEIN] config l:%d", len); + need_fadein_len = len; + need_fadein_len_processed = 0; + return 0; +} +uint32_t app_play_sbc_more_data_fadein(int16_t *buf, uint32_t len) +{ + uint32_t i; + uint32_t j = 0; + uint32_t base; + uint32_t dest; + + base = need_fadein_len_processed; + dest = need_fadein_len_processed + len < need_fadein_len ? + need_fadein_len_processed + len : + need_fadein_len_processed; + + if (base >= dest){ +// TRACE_MEDIA_PLAYESTREAM_I("skip fadein"); + return len; + } +// TRACE_MEDIA_PLAYESTREAM_I("fadein l:%d base:%d dest:%d", len, base, dest); +// DUMP16("%5d ", buf, 20); +// DUMP16("%5d ", buf+len-19, 20); + + for (i = base; i < dest; i++){ + *(buf+j) = *(buf+j)*i/need_fadein_len; + j++; + } + + need_fadein_len_processed += j; +// DUMP16("%05d ", buf, 20); +// DUMP16("%5d ", buf+len-19, 20); + return len; +} + +uint32_t app_play_single_sbc_more_data(uint8_t *buf, uint32_t len) +{ + //int32_t stime, etime; + //U16 byte_decode; + uint32_t l = 0; + + //TRACE_MEDIA_PLAYESTREAM_I("app_play_sbc_more_data : %d, %d", g_app_audio_read, g_app_audio_length); + + if (g_app_audio_read < g_app_audio_length){ + unsigned int available_len = 0; + unsigned int store_len = 0; + + available_len = AvailableOfCQueue(&media_sbc_queue); + store_len = (g_app_audio_length - g_app_audio_read) > available_len ? available_len :(g_app_audio_length - g_app_audio_read); + store_sbc_buffer((unsigned char *)(g_app_audio_data + g_app_audio_read), store_len); + g_app_audio_read += store_len; + } + + + l = decode_sbc_frame(buf, len); + + if (l != len) + { + g_app_audio_read = g_app_audio_length; + //af_stream_stop(AUD_STREAM_PLAYBACK); + //af_stream_close(AUD_STREAM_PLAYBACK); + TRACE_MEDIA_PLAYESTREAM_I("[SINGLE_SBC_MORE_DATA][END] length:%d len:%d l:%d", g_app_audio_length, len, l); + } + + return l; +} + + +/* play continue sound */ +uint32_t app_play_continue_sbc_more_data(uint8_t *buf, uint32_t len) +{ + + uint32_t l, n, fsize = 0; + + U8* pdata =NULL; + +// store data + unsigned int available_len = 0; + unsigned int store_len = 0; + + if (pCont_context.g_play_continue_n < pCont_context.g_play_continue_total){ + do { + n = pCont_context.g_play_continue_n; + pdata = media_sound_map[pCont_context.g_play_continue_array[n]].data; + fsize = media_sound_map[pCont_context.g_play_continue_array[n]].fsize; + + available_len = AvailableOfCQueue(&media_sbc_queue); + if (!available_len) + break; + + store_len = (fsize - pCont_context.g_play_continue_fread) > available_len ? available_len :(fsize - pCont_context.g_play_continue_fread); + store_sbc_buffer((unsigned char *)(pdata + pCont_context.g_play_continue_fread), store_len); + pCont_context.g_play_continue_fread += store_len; + if (pCont_context.g_play_continue_fread == fsize){ + pCont_context.g_play_continue_n++; + pCont_context.g_play_continue_fread = 0; + } + }while(pCont_context.g_play_continue_n < pCont_context.g_play_continue_total); + } + + l = decode_sbc_frame(buf, len); + + if (l !=len){ + TRACE_MEDIA_PLAYESTREAM_I("[CONTINUE_SBC_MORE_DATA][END]"); + } + + return l; +} + +uint32_t app_play_sbc_channel_select(int16_t *dst_buf, int16_t *src_buf, uint32_t src_len) +{ +#if defined(IBRT) + if (IS_PROMPT_CHNLSEl_ALL(g_prompt_chnlsel) || app_ibrt_voice_report_is_me(PROMPT_CHNLSEl_FROM_ID_VALUE(g_prompt_chnlsel))) + { + // Copy from tail so that it works even if dst_buf == src_buf + for (int i = (int)(src_len - 1); i >= 0; i--) + { + dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = src_buf[i]; + } + } + else + { + // Copy from tail so that it works even if dst_buf == src_buf + for (int i = (int)(src_len - 1); i >= 0; i--) + { + dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = 0; + } + } +#else + if (IS_PROMPT_CHNLSEl_ALL(g_prompt_chnlsel)) + { + // Copy from tail so that it works even if dst_buf == src_buf + for (int i = (int)(src_len - 1); i >= 0; i--) + { + dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = src_buf[i]; + } + } + else if (IS_PROMPT_CHNLSEl_LCHNL(g_prompt_chnlsel)) + { + // Copy from tail so that it works even if dst_buf == src_buf + for (int i = (int)(src_len - 1); i >= 0; i--) + { + dst_buf[i*2 + 0] = src_buf[i]; + dst_buf[i*2 + 1] = 0; + } + } + else if (IS_PROMPT_CHNLSEl_RCHNL(g_prompt_chnlsel)) + { + // Copy from tail so that it works even if dst_buf == src_buf + for (int i = (int)(src_len - 1); i >= 0; i--) + { + dst_buf[i*2 + 0] = 0; + dst_buf[i*2 + 1] = src_buf[i]; + } + } + else + { + // Copy from tail so that it works even if dst_buf == src_buf + for (int i = (int)(src_len - 1); i >= 0; i--) + { + dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = 0; + } + } +#endif + return 0; +} + +#ifdef __BT_ANC__ +extern uint8_t bt_sco_samplerate_ratio ; +extern void us_fir_init (void); +extern U32 us_fir_run (short* src_buf, short* dst_buf, U32 in_samp_num); +#endif + +uint32_t g_cache_buff_sz = 0; + +static int16_t *app_play_sbc_cache = NULL; +uint32_t app_play_sbc_more_data(uint8_t *buf, uint32_t len) +{ +#if defined(IBRT) + app_ibrt_voice_report_trigger_checker(); +#endif + +#ifdef VOICE_DATAPATH + if (app_voicepath_get_stream_pending_state(VOICEPATH_STREAMING)) + { + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + #ifdef MIX_MIC_DURING_MUSIC + app_voicepath_enable_hw_sidetone(0, HW_SIDE_TONE_MAX_ATTENUATION_COEF); + #endif + app_voicepath_set_stream_state(VOICEPATH_STREAMING, true); + app_voicepath_set_pending_started_stream(VOICEPATH_STREAMING, false); + } +#endif + uint32_t l = 0; + + memset(buf, 0, len); + +#if defined(MEDIA_PLAY_24BIT) + len /= 2; +#endif + +#ifdef __BT_ANC__ + uint32_t dec_len = len/bt_sco_samplerate_ratio; +#endif + + if(app_play_sbc_cache) + memset(app_play_sbc_cache, 0, g_cache_buff_sz); + + if (app_play_sbc_stop_proc_cnt) { + if (app_play_sbc_stop_proc_cnt == 1) { + app_play_sbc_stop_proc_cnt = 2; + } else if (app_play_sbc_stop_proc_cnt == 2) { + app_play_sbc_stop_proc_cnt = 3; + + // For 8K sample rate data, it takes about 4ms (or 12ms if h/w resample in use) from codec to DAC PA. + // The playback stream should be stopped after the last data arrives at DAC PA, otherwise there + // might be some pop sound. + app_play_audio_stop(); + } + } else { + if (app_play_sbc_cache) { +#ifdef __BT_ANC__ + len = dec_len; +#endif + if (g_play_continue_mark) { + l = app_play_continue_sbc_more_data((uint8_t *)app_play_sbc_cache, len/2); + } else { + l = app_play_single_sbc_more_data((uint8_t *)app_play_sbc_cache, len/2); + } + if (l != len / 2) { +#ifdef __BT_ANC__ + len = dec_len*3; +#endif + memset(app_play_sbc_cache+l, 0, len/2-l); + app_play_sbc_stop_proc_cnt = 1; + } +#ifdef __BT_ANC__ + len = dec_len*3; + l = l*3; + us_fir_run((short*)app_play_sbc_cache, (short*)buf, dec_len/2/2); + app_play_sbc_channel_select((int16_t*)buf, (int16_t*)buf, len/2/2); +#else + app_play_sbc_channel_select((int16_t *)buf, app_play_sbc_cache, len/2/2); +#endif + +#if defined(MEDIA_PLAY_24BIT) + int32_t *buf32 = (int32_t *)buf; + int16_t *buf16 = (int16_t *)buf; + + for (int16_t i = len/2 - 1; i >= 0; i--) { + buf32[i] = ((int32_t)buf16[i] << 8); + } + len *= 2; +#endif + } else { +#if defined(MEDIA_PLAY_24BIT) + len *= 2; +#endif + memset(buf, 0, len); + } + } + + return l; +} + +#ifdef AUDIO_LINEIN +static uint8_t app_play_lineinmode_merge = 0; +static uint8_t app_play_lineinmode_mode = 0; + +inline static void app_play_audio_lineinmode_mono_merge(int16_t *aud_buf_mono, int16_t *ring_buf_mono, uint32_t aud_buf_len) +{ + uint32_t i = 0; + for (i = 0; i < aud_buf_len; i++) { + aud_buf_mono[i] = (aud_buf_mono[i]>>1) + (ring_buf_mono[i]>>1); + } +} + +inline static void app_play_audio_lineinmode_stereo_merge(int16_t *aud_buf_stereo, int16_t *ring_buf_mono, uint32_t aud_buf_len) +{ + uint32_t aud_buf_stereo_offset = 0; + uint32_t ring_buf_mono_offset = 0; + for (aud_buf_stereo_offset = 0; aud_buf_stereo_offset < aud_buf_len; ) { + aud_buf_stereo[aud_buf_stereo_offset] = aud_buf_stereo[aud_buf_stereo_offset] + (ring_buf_mono[ring_buf_mono_offset]>>1); + aud_buf_stereo_offset++; + aud_buf_stereo[aud_buf_stereo_offset] = aud_buf_stereo[aud_buf_stereo_offset] + (ring_buf_mono[ring_buf_mono_offset]>>1); + aud_buf_stereo_offset++; + ring_buf_mono_offset++; + } +} + +uint32_t app_play_audio_lineinmode_more_data(uint8_t *buf, uint32_t len) +{ + uint32_t l = 0; + if (app_play_lineinmode_merge && app_play_sbc_cache){ + TRACE(1,"line in mode:%d ", len); + if (app_play_lineinmode_mode == 1){ + if (g_play_continue_mark){ + l = app_play_continue_sbc_more_data((uint8_t *)app_play_sbc_cache, len); + }else{ + l = app_play_single_sbc_more_data((uint8_t *)app_play_sbc_cache, len); + } + if (l != len){ + memset(app_play_sbc_cache+l, 0, len-l); + app_play_lineinmode_merge = 0; + } + app_play_audio_lineinmode_mono_merge((int16_t *)buf, (int16_t *)app_play_sbc_cache, len/2); + }else if (app_play_lineinmode_mode == 2){ + if (g_play_continue_mark){ + l = app_play_continue_sbc_more_data((uint8_t *)app_play_sbc_cache, len/2); + }else{ + l = app_play_single_sbc_more_data((uint8_t *)app_play_sbc_cache, len/2); + } + if (l != len/2){ + memset(app_play_sbc_cache+l, 0, len/2-l); + app_play_lineinmode_merge = 0; + } + app_play_audio_lineinmode_stereo_merge((int16_t *)buf, (int16_t *)app_play_sbc_cache, len/2); + } + } + + return l; +} + +int app_play_audio_lineinmode_init(uint8_t mode, uint32_t buff_len) +{ + TRACE(1,"lapp_play_audio_lineinmode_init:%d ", buff_len); + app_play_lineinmode_mode = mode; + app_audio_mempool_get_buff((uint8_t **)&app_play_sbc_cache, buff_len); + media_audio_init(); + return 0; +} + +int app_play_audio_lineinmode_start(APP_AUDIO_STATUS* status) +{ + if (app_play_audio_sample_rate == AUD_SAMPRATE_44100){ + LOCK_APP_AUDIO_QUEUE(); + APP_AUDIO_DeCQueue(&media_sbc_queue, 0, APP_AUDIO_LengthOfCQueue(&media_sbc_queue)); + UNLOCK_APP_AUDIO_QUEUE(); + app_play_lineinmode_merge = 1; + need_init_decoder = 1; + media_Play_init_audio(status->aud_id); + } + return 0; +} + +int app_play_audio_lineinmode_stop(APP_AUDIO_STATUS* status) +{ + app_play_lineinmode_merge = 0; + return 0; +} +#endif + + +#if defined(AUDIO_ANC_FB_MC_MEDIA) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) +#define DELAY_SAMPLE_MC (33*2) // 2:ch +static int32_t delay_buf_media[DELAY_SAMPLE_MC]; +static uint32_t audio_mc_data_playback_media(uint8_t *buf, uint32_t mc_len_bytes) +{ + uint32_t begin_time; + //uint32_t end_time; + begin_time = hal_sys_timer_get(); + TRACE_MEDIA_PLAYESTREAM_I("[PLAYBACK_MEDIA][MC] %d",begin_time); + + float left_gain; + float right_gain; + int32_t playback_len_bytes,mc_len_bytes_8; + int32_t i,j,k; + int delay_sample; + + mc_len_bytes_8=mc_len_bytes/8; + + hal_codec_get_dac_gain(&left_gain,&right_gain); + + //TRACE_MEDIA_PLAYESTREAM_I("playback_samplerate_ratio: %d",playback_samplerate_ratio); + + // TRACE_MEDIA_PLAYESTREAM_I("left_gain: %d",(int)(left_gain*(1<<12))); + // TRACE_MEDIA_PLAYESTREAM_I("right_gain: %d",(int)(right_gain*(1<<12))); + + playback_len_bytes=mc_len_bytes/playback_samplerate_ratio_bt; + + if (sample_size_play_bt == AUD_BITS_16) + { + int16_t *sour_p=(int16_t *)(playback_buf_bt+playback_size_bt/2); + int16_t *mid_p=(int16_t *)(buf); + int16_t *mid_p_8=(int16_t *)(buf+mc_len_bytes-mc_len_bytes_8); + int16_t *dest_p=(int16_t *)buf; + + if(buf == playback_buf_mc) + { + sour_p=(int16_t *)playback_buf_bt; + } + + delay_sample=DELAY_SAMPLE_MC; + + for(i=0,j=0;iaud_id); + aud_pram = PROMPT_PRAM_FROM_ID_VALUE(status->aud_id); + g_prompt_chnlsel = PROMPT_CHNLSEl_FROM_ID_VALUE(aud_pram); + TRACE_MEDIA_PLAYESTREAM_I("[MEDIA_ONOFF] aud_id:%04x %s aud_pram:%04x chnlsel:%d", status->aud_id, aud_id2str(aud_id), aud_pram, g_prompt_chnlsel); + + media_Play_init_audio(aud_id); + app_play_audio_set_aud_id(aud_id); + if (!g_app_audio_length){ + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE, 0); + return 0; + } + +#if defined(AUDIO_ANC_FB_MC_MEDIA) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_104M); +#else + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_52M); +#endif + af_set_priority(AF_USER_AUDIO, osPriorityHigh); + app_audio_mempool_init_with_specific_size(APP_AUDIO_BUFFER_SIZE); + media_audio_init(); + +#if (defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE))&&defined(ENHANCED_STACK) + if(app_bt_device.src_or_snk == BT_DEVICE_SRC) + { + app_a2dp_source_init(); + } +#endif + + btif_sbc_init_decoder(media_sbc_decoder); + btif_sbc_decode_frames(media_sbc_decoder, + g_app_audio_data, g_app_audio_length, + &bytes_parsed, + NULL, 0, + NULL); + switch (media_sbc_decoder->streamInfo.sampleFreq) + { + case BTIF_SBC_CHNL_SAMPLE_FREQ_16: + sample_rate = AUD_SAMPRATE_16000; + break; + case BTIF_SBC_CHNL_SAMPLE_FREQ_32: + sample_rate = AUD_SAMPRATE_32000; + break; + case BTIF_SBC_CHNL_SAMPLE_FREQ_44_1: + sample_rate = AUD_SAMPRATE_44100; + break; + case BTIF_SBC_CHNL_SAMPLE_FREQ_48: + sample_rate = AUD_SAMPRATE_48000; + break; + default: + sample_rate = AUD_SAMPRATE_16000; + break; + } + +#ifdef PLAYBACK_USE_I2S + hal_cmu_audio_resample_disable(); +#endif + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + +#if defined(MEDIA_PLAY_24BIT) + stream_cfg.bits = AUD_BITS_24; +#else + stream_cfg.bits = AUD_BITS_16; +#endif + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; +#ifdef __BT_ANC__ + stream_cfg.sample_rate = AUD_SAMPRATE_48000 ; +#else + stream_cfg.sample_rate = AUD_SAMPRATE_16000; +#endif +#ifdef PLAYBACK_USE_I2S + stream_cfg.device = AUD_STREAM_USE_I2S0_MASTER; + stream_cfg.io_path = AUD_IO_PATH_NULL; +#else + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; +#endif +#ifdef __INTERACTION__ + if(aud_id == AUD_ID_BT_FINDME) + { + stream_cfg.vol = g_findme_fadein_vol; + } + else +#endif + { + stream_cfg.vol = TGT_VOLUME_LEVEL_WARNINGTONE; + } + stream_cfg.handler = app_play_sbc_more_data; + + stream_cfg.data_size = APP_AUDIO_PLAYBACK_BUFF_SIZE; + +#if defined(MEDIA_PLAY_24BIT) + stream_cfg.data_size *= 2; +#endif + + g_cache_buff_sz = stream_cfg.data_size/2/2 ; + + app_audio_mempool_get_buff((uint8_t **)&app_play_sbc_cache, g_cache_buff_sz); + app_audio_mempool_get_buff(&bt_audio_buff, stream_cfg.data_size); + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(bt_audio_buff); + +#ifdef __BT_ANC__ + bt_sco_samplerate_ratio = 3; + us_fir_init(); +#endif + +#if defined(AUDIO_ANC_FB_MC_MEDIA) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + sample_size_play_bt=stream_cfg.bits; + sample_rate_play_bt=stream_cfg.sample_rate; + data_size_play_bt=stream_cfg.data_size; + playback_buf_bt=stream_cfg.data_ptr; + playback_size_bt=stream_cfg.data_size; +#ifdef __BT_ANC__ + playback_samplerate_ratio_bt=8; +#else + playback_samplerate_ratio_bt=8*3; +#endif + playback_ch_num_bt=stream_cfg.channel_num; +#endif + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + +#if defined(AUDIO_ANC_FB_MC_MEDIA) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + stream_cfg.bits = sample_size_play_bt; + stream_cfg.channel_num = playback_ch_num_bt; + stream_cfg.sample_rate = sample_rate_play_bt; + stream_cfg.device = AUD_STREAM_USE_MC; + stream_cfg.vol = 0; + stream_cfg.handler = audio_mc_data_playback_media; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + + app_audio_mempool_get_buff(&bt_audio_buff, data_size_play_bt*playback_samplerate_ratio_bt); + stream_cfg.data_ptr = BT_AUDIO_CACHE_2_UNCACHE(bt_audio_buff); + stream_cfg.data_size = data_size_play_bt*playback_samplerate_ratio_bt; + + playback_buf_mc=stream_cfg.data_ptr; + playback_size_mc=stream_cfg.data_size; + + anc_mc_run_init(hal_codec_anc_convert_rate(sample_rate_play_bt)); + af_stream_open(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &stream_cfg); +#endif + +#if !(defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE)) + af_codec_tune(AUD_STREAM_NUM, 0); +#endif + +#if defined(IBRT) + app_ibrt_voice_report_trigger_init(aud_id, aud_pram); +#endif + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + +#if defined(AUDIO_ANC_FB_MC_MEDIA) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + af_stream_start(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK); +#endif + + + } else { + +#ifdef VOICE_DATAPATH + app_voicepath_set_stream_state(AUDIO_OUTPUT_STREAMING, false); + app_voicepath_set_pending_started_stream(AUDIO_OUTPUT_STREAMING, false); +#endif +#if !(defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE)) + af_codec_tune(AUD_STREAM_PLAYBACK, 0); +#endif + + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + +#if defined(AUDIO_ANC_FB_MC_MEDIA) && defined(ANC_APP) && !defined(__AUDIO_RESAMPLE__) + af_stream_stop(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK); + af_stream_close(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK); +#endif +#if defined(IBRT) + app_ibrt_voice_report_trigger_deinit(); +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + audio_prompt_stop_playing(); +#endif +#endif +#ifdef PLAYBACK_USE_I2S + hal_cmu_audio_resample_enable(); +#endif + + app_play_sbc_cache = NULL; + g_cache_buff_sz = 0; + g_prompt_chnlsel = PROMOT_ID_BIT_MASK_CHNLSEl_ALL; + app_play_audio_set_aud_id(MAX_RECORD_NUM); + af_set_priority(AF_USER_AUDIO, osPriorityAboveNormal); + app_sysfreq_req(APP_SYSFREQ_USER_APP_0, APP_SYSFREQ_32K); + + app_audio_playback_done(); +#if defined(__THIRDPARTY) + app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_NO1,THIRDPARTY_START); +#endif + + } + isRun = onoff; + + return 0; +} + +static void app_stop_local_prompt_playing(void) +{ + app_audio_sendrequest(APP_PLAY_BACK_AUDIO, APP_BT_SETTING_CLOSE, 0); +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + audio_prompt_stop_playing(); +#endif +} + +void app_stop_both_prompt_playing(void) +{ + app_stop_local_prompt_playing(); + app_tws_stop_peer_prompt(); +} + +void app_tws_cmd_stop_prompt_handler(uint8_t* ptrParam, uint16_t paramLen) +{ + TRACE_MEDIA_PLAYESTREAM_I("[STOP_PROMPT_HANDLER]"); + app_stop_local_prompt_playing(); +} +#endif + diff --git a/services/bt_app/app_media_player.h b/services/bt_app/app_media_player.h new file mode 100644 index 0000000..1cbbddb --- /dev/null +++ b/services/bt_app/app_media_player.h @@ -0,0 +1,180 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_MEDIA_PLAYER_H__ +#define __APP_MEDIA_PLAYER_H__ + +#include "resources.h" +#include "app_bt_stream.h" + +#define MEDIA_DEFAULT_LANGUAGE (0) + +typedef enum +{ + T_AUDIO_ID = 0x0, + + T_AUDIO_NUMBER, + +}MEDIA_AUDIO_TYPE; + +#define MAX_PHB_NUMBER 20 + +#define PROMOT_ID_BIT_MASK (0xff << 8) +#define PROMOT_ID_BIT_MASK_MERGING (1 << 15) +#define PROMOT_ID_BIT_MASK_CHNLSEl_LCHNL (1 << 14) +#define PROMOT_ID_BIT_MASK_CHNLSEl_RCHNL (1 << 13) +#define PROMOT_ID_BIT_MASK_CHNLSEl_ALL (PROMOT_ID_BIT_MASK_CHNLSEl_LCHNL|PROMOT_ID_BIT_MASK_CHNLSEl_RCHNL) + +#define IS_PROMPT_NEED_MERGING(promptId) ((promptId)&PROMOT_ID_BIT_MASK_MERGING ? true : false) +#define PROMPT_ID_FROM_ID_VALUE(promptIdVal) ((promptIdVal)&(~PROMOT_ID_BIT_MASK)) +#define PROMPT_CHNLSEl_FROM_ID_VALUE(promptIdVal) ((promptIdVal)&PROMOT_ID_BIT_MASK_CHNLSEl_ALL) +#define PROMPT_PRAM_FROM_ID_VALUE(promptIdVal) ((promptIdVal)&PROMOT_ID_BIT_MASK) +#define IS_PROMPT_CHNLSEl_ALL(promptId) (((promptId)&PROMOT_ID_BIT_MASK_CHNLSEl_ALL) == PROMOT_ID_BIT_MASK_CHNLSEl_ALL ? true : false) +#define IS_PROMPT_CHNLSEl_LCHNL(promptId) (((promptId)&PROMOT_ID_BIT_MASK_CHNLSEl_ALL) == PROMOT_ID_BIT_MASK_CHNLSEl_RCHNL ? true : false) +#define IS_PROMPT_CHNLSEl_RCHNL(promptId) (((promptId)&PROMOT_ID_BIT_MASK_CHNLSEl_ALL) == PROMOT_ID_BIT_MASK_CHNLSEl_LCHNL ? true : false) + +typedef struct +{ + uint16_t id; + uint16_t status; + // APP_AUDIO_STATUS + uint16_t aud_type; + uint16_t aud_id; + char phb_number[MAX_PHB_NUMBER]; +}msg_num_ptr; + +typedef struct +{ + uint16_t promptId; + int16_t volume_level_override; + float coeff_for_mix_prompt_for_music; + float coeff_for_mix_music_for_music; + float coeff_for_mix_prompt_for_call; + float coeff_for_mix_call_for_call; + +} __attribute__((packed)) PROMPT_MIX_PROPERTY_T; + +#define PROMPT_MIX_PROPERTY_TO_ADD(promptId, \ + volume_level_override, \ + coeff_for_mix_prompt_for_music, \ + coeff_for_mix_music_for_music, \ + coeff_for_mix_prompt_for_call, \ + coeff_for_mix_call_for_call) \ +static PROMPT_MIX_PROPERTY_T promptId##_entry __attribute__((used, section(".mixprompt_property_table"))) = \ + {(promptId), \ + (volume_level_override), \ + (coeff_for_mix_prompt_for_music), \ + (coeff_for_mix_music_for_music), \ + (coeff_for_mix_prompt_for_call), \ + (coeff_for_mix_call_for_call), \ + }; + +extern uint32_t __mixprompt_property_table_start[]; +extern uint32_t __mixprompt_property_table_end[]; + +#ifdef __cplusplus +extern "C" { +#endif + +//uint32_t media_playAudioSideSelect(AUD_ID_ENUM id,uint8_t device_id, uint8_t side_select); +// Prompt will be played on the both sides if they're connected. +// If there are music/phone call on-going, the prompt will be mixed. +uint32_t media_PlayAudio(AUD_ID_ENUM id,uint8_t device_id); + +uint32_t media_playAudioSideSelect(AUD_ID_ENUM id,uint8_t device_id, uint16_t side_select); + +// Prompt will be played locally no matter whether earbuds are connected or not +// If there are music/phone call on-going, the prompt will be mixed. +void media_PlayAudio_locally(AUD_ID_ENUM id, uint8_t device_id); + +// Prompt will be played on peer device only if they're connected. +// If there are music/phone call on-going, the music or phone call output will be stopped +// until the prompt playing is completed. +void media_PlayAudio_remotely(AUD_ID_ENUM id, uint8_t device_id); + +// Prompt will be played on the both sides if they're connected. +// If there are music/phone call on-going, the music or phone call output will be stopped +// until the prompt playing is completed. +void media_PlayAudio_standalone(AUD_ID_ENUM id, uint8_t device_id); + +// Prompt will be played locally no matter whether earbuds are connected or not +// If there are music/phone call on-going, the music or phone call output will be stopped +// until the prompt playing is completed. +void media_PlayAudio_standalone_locally(AUD_ID_ENUM id, uint8_t device_id); + +// Prompt will be played on the peer device only if they're connected. +// If there are music/phone call on-going, the music or phone call output will be stopped +// until the prompt playing is completed. +void media_PlayAudio_standalone_remotely(AUD_ID_ENUM id, uint8_t device_id); + +void media_Set_IncomingNumber(const char* pNumber); + +void media_FreeMemory(void* data); + +int app_play_audio_onoff(bool on, APP_AUDIO_STATUS* status); + +void stand_alone_prompt_supervision_timer_init(void); + +void app_play_audio_set_lang(int L); + +int app_play_audio_get_lang(); + +void app_audio_playback_done(void); + +void media_runtime_audio_prompt_update(uint16_t id, uint8_t** ptr, uint32_t* len); + +PROMPT_MIX_PROPERTY_T* get_prompt_mix_property(uint16_t promptId); + +AUD_ID_ENUM media_GetCurrentPrompt(uint8_t device_id); + +AUD_ID_ENUM app_get_current_standalone_promptId(void); + +void update_standalone_prompt_volume(int8_t vol); + +void app_tws_cmd_stop_prompt_handler(uint8_t* ptrParam, uint16_t paramLen); + +void app_stop_both_prompt_playing(void); + +void app_tws_stop_peer_prompt(void); + +int app_play_audio_stop(void); + +int app_play_audio_get_aud_id(void); + +void trigger_media_play(AUD_ID_ENUM id, uint8_t device_id, uint16_t aud_pram); +void trigger_media_stop(AUD_ID_ENUM id, uint8_t device_id); + + +#ifdef AUDIO_LINEIN +uint32_t app_play_audio_lineinmode_more_data(uint8_t *buf, uint32_t len); + +int app_play_audio_lineinmode_init(uint8_t mode, uint32_t buff_len); + +int app_play_audio_lineinmode_start(APP_AUDIO_STATUS* status); + +int app_play_audio_lineinmode_stop(APP_AUDIO_STATUS* status); + +#endif + +void app_tws_sync_prompt_check(void); + +void app_tws_sync_prompt_manager_reset(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/bt_app/app_rfcomm_mgr.cpp b/services/bt_app/app_rfcomm_mgr.cpp new file mode 100644 index 0000000..3dca0cb --- /dev/null +++ b/services/bt_app/app_rfcomm_mgr.cpp @@ -0,0 +1,382 @@ +#include "string.h" +#include "app_rfcomm_mgr.h" +extern "C" { +#include "hal_trace.h" +#include "cmsis_os.h" +#include "cqueue.h" +#include "spp_api.h" +#include "os_api.h" +#include "bt_if.h" +#include "app_bt.h" +} + +typedef struct +{ + uint8_t instanceIndex; + + struct spp_device *sppDev; + +#if SPP_SERVER == XA_ENABLED + struct spp_service *sppService; + btif_sdp_record_t *sppSdpRecord; +#endif + + rfcomm_callback_func callback; + osMutexId service_mutex_id; +} RfcommService_t; + +#define RFCOMM_SERVER_MAX_CHANNEL_CNT 4 + +static RfcommService_t RfcommServiceInstance[RFCOMM_SERVER_MAX_CHANNEL_CNT]; +static uint8_t rfcomm_service_used_instance_cnt = 0; +#define RFCOMM_RECV_BUFFER_SIZE 2048 +#define RFCOMM_RECV_BUFFER_POOL_SIZE (RFCOMM_SERVER_MAX_CHANNEL_CNT * RFCOMM_RECV_BUFFER_SIZE) + +static uint8_t rfcomm_rx_buf[RFCOMM_RECV_BUFFER_POOL_SIZE]; +static uint32_t rfcomm_rx_buf_allocated_offset = 0; + +/**************************************************************************** + * SPP SDP Entries + ****************************************************************************/ +static const uint8_t RFCOMM_NULL_UUID_128[16] = { + 0x00, +}; + +static const U8 rfcommClassId[] = { + SDP_ATTRIB_HEADER_8BIT(17), /* Data Element Sequence, 17 bytes */ + SDP_UUID_128BIT(RFCOMM_NULL_UUID_128), /* 128 bit UUID in Big Endian */ +}; + +static uint8_t rfcommClassIdArray[RFCOMM_SERVER_MAX_CHANNEL_CNT*sizeof(rfcommClassId)] = +{ + +}; + +static const U8 RfcommProtoDescList[] = { + SDP_ATTRIB_HEADER_8BIT(12), /* Data element sequence, 12 bytes */ + + /* Each element of the list is a Protocol descriptor which is a + * data element sequence. The first element is L2CAP which only + * has a UUID element. + */ + SDP_ATTRIB_HEADER_8BIT(3), /* Data element sequence for L2CAP, 3 + * bytes + */ + + SDP_UUID_16BIT(PROT_L2CAP), /* Uuid16 L2CAP */ + + /* Next protocol descriptor in the list is RFCOMM. It contains two + * elements which are the UUID and the channel. Ultimately this + * channel will need to filled in with value returned by RFCOMM. + */ + + /* Data element sequence for RFCOMM, 5 bytes */ + SDP_ATTRIB_HEADER_8BIT(5), + + SDP_UUID_16BIT(PROT_RFCOMM), /* Uuid16 RFCOMM */ + + /* Uint8 RFCOMM channel number - value can vary */ + SDP_UINT_8BIT(0) +}; + +static uint8_t RfcommProtoDescListArray[RFCOMM_SERVER_MAX_CHANNEL_CNT*sizeof(RfcommProtoDescList)] = +{ + +}; + +/* + * BluetoothProfileDescriptorList + */ +static const U8 ProfileDescList[] = { + SDP_ATTRIB_HEADER_8BIT(8), /* Data element sequence, 8 bytes */ + + /* Data element sequence for ProfileDescriptor, 6 bytes */ + SDP_ATTRIB_HEADER_8BIT(6), + + SDP_UUID_16BIT(SC_SERIAL_PORT), /* Uuid16 SPP */ + SDP_UINT_16BIT(0x0102) /* As per errata 2239 */ +}; + +/* SPP attributes. + * + * This is a ROM template for the RAM structure used to register the + * SPP SDP record. + */ +static sdp_attribute_t rfcommAttributes[] = { + SDP_ATTRIBUTE(AID_SERVICE_CLASS_ID_LIST, rfcommClassId), + + SDP_ATTRIBUTE(AID_PROTOCOL_DESC_LIST, RfcommProtoDescList), + + SDP_ATTRIBUTE(AID_BT_PROFILE_DESC_LIST, ProfileDescList), +}; + +static sdp_attribute_t rfcommAttributesArray[RFCOMM_SERVER_MAX_CHANNEL_CNT][ARRAY_SIZE(rfcommAttributes)] = +{ + +}; + +osThreadId app_rfcomm_get_rx_thread_id(uint8_t serviceIndex) +{ + if (serviceIndex < rfcomm_service_used_instance_cnt) + { + return RfcommServiceInstance[serviceIndex].sppDev->reader_thread_id; + } + else + { + ASSERT(false, "Wrong rfcomm service index %d", serviceIndex); + } +} + +uint8_t app_rfcomm_get_instance_index(void* dev) +{ + for (uint8_t index = 0;index < rfcomm_service_used_instance_cnt;index++) + { + if ((struct spp_device *)dev == (RfcommServiceInstance[index].sppDev)) + { + return index; + } + } + + ASSERT(false, "invalid rfcomm callback triggered!"); + return 0; +} + +static void app_rfcomm_org_callback(struct spp_device *locDev, struct spp_callback_parms *info) +{ + uint8_t index = app_rfcomm_get_instance_index(locDev); + RfcommService_t* pService = &(RfcommServiceInstance[index]); + RFCOMM_EVENT_E event; + uint16_t sentDataLen = 0; + uint8_t* sentDataBuf = NULL; + + if (BTIF_SPP_EVENT_REMDEV_CONNECTED_IND == info->event) + { + event = RFCOMM_INCOMING_CONN_REQ; + } + else if (BTIF_SPP_EVENT_REMDEV_CONNECTED == info->event) + { + event = RFCOMM_CONNECTED; + } + else if (BTIF_SPP_EVENT_REMDEV_DISCONNECTED == info->event) + { + event = RFCOMM_DISCONNECTED; + } + else if (BTIF_SPP_EVENT_DATA_SENT == info->event) + { + struct spp_tx_done* pTxDone = (struct spp_tx_done *)(info->p.other); + sentDataBuf = pTxDone->tx_buf; + sentDataLen = pTxDone->tx_data_length; + event = RFCOMM_TX_DONE; + } + else + { + event = RFCOMM_UNKNOWN_EVENT; + } + + uint8_t* pBtAddr = NULL; + if (info->p.remDev) + { + pBtAddr = btif_me_get_remote_device_bdaddr(info->p.remDev)->address; + + if (pService->callback) + { + bool ret = pService->callback(event, + index, + btif_me_get_remote_device_hci_handle(info->p.remDev), + pBtAddr, + sentDataBuf, + sentDataLen); + + if (!ret) + { + if (RFCOMM_INCOMING_CONN_REQ == event) + { + // reject the incoming connection request + info->status = BT_STS_CANCELLED; + } + } + } + } +} + +osMutexId app_rfcomm_service_get_mutex(uint8_t instanceIndex) +{ + return RfcommServiceInstance[instanceIndex].service_mutex_id; +} + +static bt_status_t app_rfcomm_service_init(RfcommService_t *service, + sdp_attribute_t *sdpAttributes, + int attributeCount, int serviceId, uint32_t app_id, + spp_handle_data_event_func_t dataRecCallback, + int txPacketCount, + osMutexId mutexId, + osMutexId creditMutexId) { + service->sppService = btif_create_spp_service(); + service->sppDev = btif_create_spp_device(); + + service->sppDev->portType = BTIF_SPP_SERVER_PORT; + uint8_t* ptrRxBuf = &rfcomm_rx_buf[rfcomm_rx_buf_allocated_offset]; + uint32_t rxBufSize = RFCOMM_RECV_BUFFER_SIZE; + + rfcomm_rx_buf_allocated_offset += rxBufSize; + + ASSERT(rfcomm_rx_buf_allocated_offset <= RFCOMM_RECV_BUFFER_POOL_SIZE, + "RFComm rx buffer overflow! Need %d actual %d", + rfcomm_rx_buf_allocated_offset, RFCOMM_RECV_BUFFER_POOL_SIZE); + + btif_spp_init_rx_buf(service->sppDev, ptrRxBuf, + rxBufSize); + + service->sppSdpRecord = btif_sdp_create_record(); + + btif_sdp_record_param_t param; + param.attrs = sdpAttributes, + param.attr_count = attributeCount; + param.COD = BTIF_COD_MAJOR_PERIPHERAL; + btif_sdp_record_setup(service->sppSdpRecord, ¶m); + + service->sppService->rf_service.serviceId = serviceId; + service->sppService->numPorts = 0; + service->sppDev->app_id = app_id; + service->sppDev->spp_handle_data_event_func = dataRecCallback; + // TODO: add more in other files + service->sppDev->creditMutex = creditMutexId; + + btif_spp_service_setup(service->sppDev, service->sppService, service->sppSdpRecord); + btif_spp_init_device(service->sppDev, txPacketCount, mutexId); + + return btif_spp_open(service->sppDev, NULL, app_rfcomm_org_callback); +} + +void app_rfcomm_read(uint8_t instanceIndex, uint8_t* pBuf, uint16_t* ptrLen) +{ + if (instanceIndex >= rfcomm_service_used_instance_cnt) + { + return; + } + + uint16_t lenToRead = *ptrLen; + + btif_spp_read(RfcommServiceInstance[instanceIndex].sppDev, + (char *)pBuf, &lenToRead); + *ptrLen = lenToRead; +} + +int8_t app_rfcomm_write(uint8_t instanceIndex, const uint8_t* pBuf, uint16_t length) +{ + if (instanceIndex >= rfcomm_service_used_instance_cnt) + { + return -1; + } + + uint16_t len = (uint16_t)length; + if (BT_STS_SUCCESS != btif_spp_write(RfcommServiceInstance[instanceIndex].sppDev, + (char *)pBuf, &len)) + { + return -1; + } + else + { + return 0; + } +} + +bool app_rfcomm_removesdpservice(uint8_t instanceIndex) +{ + if (instanceIndex >= rfcomm_service_used_instance_cnt) + { + return false; + } + + return (BT_STS_SUCCESS == btif_sdp_remove_record(&(RfcommServiceInstance[instanceIndex].sppSdpRecord))); +} + +bool app_rfcomm_addsdpservice(uint8_t instanceIndex) +{ + if (instanceIndex >= rfcomm_service_used_instance_cnt) + { + return false; + } + + return (BT_STS_SUCCESS == btif_sdp_add_record(&(RfcommServiceInstance[instanceIndex].sppSdpRecord))); +} + +void app_rfcomm_close(uint8_t instanceIndex) +{ + if (instanceIndex >= rfcomm_service_used_instance_cnt) + { + return; + } + btif_spp_close(RfcommServiceInstance[instanceIndex].sppDev); +} + +int8_t app_rfcomm_open(RFCOMM_CONFIG_T* ptConfig) +{ + if (rfcomm_service_used_instance_cnt >= RFCOMM_SERVER_MAX_CHANNEL_CNT) + { + return -1; + } + + RfcommService_t* sppServiceInstance = + &RfcommServiceInstance[rfcomm_service_used_instance_cnt]; + + sppServiceInstance->callback = ptConfig->callback; + + memcpy(&rfcommClassIdArray[rfcomm_service_used_instance_cnt*sizeof(rfcommClassId)], + rfcommClassId, sizeof(rfcommClassId)); + for (int32_t index = 0;index < 16;index++) + { + rfcommClassIdArray[rfcomm_service_used_instance_cnt*sizeof(rfcommClassId) + 3 + index] + = ptConfig->rfcomm_128bit_uuid[15-index]; + } + + memcpy(&RfcommProtoDescListArray[rfcomm_service_used_instance_cnt*sizeof(RfcommProtoDescList)], + RfcommProtoDescList, sizeof(RfcommProtoDescList)); + memcpy(&RfcommProtoDescListArray[rfcomm_service_used_instance_cnt*sizeof(RfcommProtoDescList) + 13], + &(ptConfig->rfcomm_ch), 1); + + memcpy(&rfcommAttributesArray[rfcomm_service_used_instance_cnt], + rfcommAttributes, sizeof(rfcommAttributes)); + + rfcommAttributesArray[rfcomm_service_used_instance_cnt][0].value = &rfcommClassIdArray[rfcomm_service_used_instance_cnt*sizeof(rfcommClassId)]; + rfcommAttributesArray[rfcomm_service_used_instance_cnt][1].value = &RfcommProtoDescListArray[rfcomm_service_used_instance_cnt*sizeof(RfcommProtoDescList)]; + + sppServiceInstance->instanceIndex = rfcomm_service_used_instance_cnt; + + bt_status_t status = app_rfcomm_service_init( + sppServiceInstance, rfcommAttributesArray[rfcomm_service_used_instance_cnt], + ARRAY_SIZE(rfcommAttributes), + ptConfig->rfcomm_ch, ptConfig->app_id, + ptConfig->spp_handle_data_event_func, + ptConfig->tx_pkt_cnt, + ptConfig->mutexId, + ptConfig->creditMutexId); + + if (status != BT_STS_SUCCESS) + { + return -1; + } + else + { + return rfcomm_service_used_instance_cnt++; + } +} + +void app_rfcomm_mgr_init(void) +{ + memset(&RfcommServiceInstance, 0, sizeof(RfcommServiceInstance)); + rfcomm_service_used_instance_cnt = 0; +} + +// Add services to sdp database, currently invoked on connection +// +void app_rfcomm_services_add_sdp(void) { + +} + +// Remove services from sdp database, currently invoked on disconnection +// +void app_rfcomm_services_remove_sdp(void) { + +} + diff --git a/services/bt_app/app_rfcomm_mgr.h b/services/bt_app/app_rfcomm_mgr.h new file mode 100644 index 0000000..f9b89eb --- /dev/null +++ b/services/bt_app/app_rfcomm_mgr.h @@ -0,0 +1,62 @@ +#ifndef __APP_RFCOMM_MGR_H__ +#define __APP_RFCOMM_MGR_H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include "cmsis_os.h" + +#if defined(__3M_PACK__) +#define L2CAP_MTU 980 +#else +#define L2CAP_MTU 672 +#endif + +#define SPP_MAX_PACKET_SIZE L2CAP_MTU +#define MAXIMUM_RFCOMM_TX_SIZE ((L2CAP_MTU) - 10) +#define SPP_TX_BUF_DATA_SIZE 4096 +#define SPP_MAX_PACKET_NUM \ + ((int)(SPP_TX_BUF_DATA_SIZE / MAXIMUM_RFCOMM_TX_SIZE)) + +typedef enum +{ + RFCOMM_INCOMING_CONN_REQ = 0, + RFCOMM_CONNECTED, + RFCOMM_DISCONNECTED, + RFCOMM_TX_DONE, + RFCOMM_UNKNOWN_EVENT +} RFCOMM_EVENT_E; + +typedef bool (*rfcomm_callback_func)(RFCOMM_EVENT_E event, uint8_t serviceIndex, + uint16_t connHandle, uint8_t* pBtAddr, uint8_t* pSentDataBuf, uint16_t sentDataLen); + +typedef int (*spp_handle_data_event_func_t)(void *pDev, uint8_t process, uint8_t *pData, uint16_t dataLen); + +typedef struct +{ + uint8_t rfcomm_ch; + uint8_t tx_pkt_cnt; + uint32_t app_id; + const uint8_t* rfcomm_128bit_uuid; + rfcomm_callback_func callback; + spp_handle_data_event_func_t spp_handle_data_event_func; + osMutexId mutexId; + osMutexId creditMutexId; +} RFCOMM_CONFIG_T; + +int8_t app_rfcomm_open(RFCOMM_CONFIG_T* ptConfig); +void app_rfcomm_close(uint8_t instanceIndex); +int8_t app_rfcomm_write(uint8_t instanceIndex, const uint8_t* pBuf, uint16_t length); +void app_rfcomm_read(uint8_t instanceIndex, uint8_t* pBuf, uint16_t* ptrLen); +void app_rfcomm_mgr_init(void); +uint8_t app_rfcomm_get_instance_index(void* dev); +osThreadId app_rfcomm_get_rx_thread_id(uint8_t serviceIndex); +void app_rfcomm_services_add_sdp(void); +void app_rfcomm_services_remove_sdp(void); + +#ifdef __cplusplus +} +#endif + +#endif // __APP_RFCOMM_MGR_H__ + diff --git a/services/bt_app/app_ring_merge.cpp b/services/bt_app/app_ring_merge.cpp new file mode 100644 index 0000000..35e5fd7 --- /dev/null +++ b/services/bt_app/app_ring_merge.cpp @@ -0,0 +1,403 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "hal_trace.h" +#include "audioflinger.h" +#include "app_ring_merge.h" +#include "res_audio_ring.h" + +// control queue access +osMutexId app_ring_merge_mutex_id = NULL; +osMutexDef(app_ring_merge_mutex); + +extern "C" void app_stop_a2dp_media_stream(uint8_t devId); +extern "C" void app_stop_sco_media_stream(uint8_t devId); + +static void app_ring_merge_finished_callback(void); + +enum APP_RING_MERGE_STATUS { + APP_RING_MERGE_STATUS_STOP, + APP_RING_MERGE_STATUS_START, + APP_RING_MERGE_STATUS_RUNNING +}; + +struct APP_RING_MERGE_CONFIG_T { + APP_RING_MERGE_STATUS status; + int16_t * pbuf; + uint32_t len; + uint32_t next; + AUD_BITS_T bits; + enum APP_RING_MERGE_PLAY_T play; + AF_STREAM_HANDLER_T handler; + + uint8_t pendingStopOp; + int8_t savedStoppedStreamId; +}; + +struct APP_RING_MERGE_CONFIG_T app_ring_merge_config = { + .status = APP_RING_MERGE_STATUS_STOP, + .pbuf = NULL, + .len = 0, + .next = 0, + .bits = AUD_BITS_16, + .play = APP_RING_MERGE_PLAY_QTY, + .handler = NULL}; + +template +static DataType convertTo(int16_t x) +{ + return (x); +} + +template <> +int32_t convertTo(int16_t x) +{ + return (x << 8); +} + +template +static void app_ring_merge_track_2_in_1(DataType *src_buf0, int16_t *src_buf1, DataType *dst_buf, uint32_t src_len) +{ + uint32_t i = 0; + for (i = 0; i < src_len; i++) + { + dst_buf[i] = (src_buf0[i] >> 1) + ((convertTo(src_buf1[i])) >> 1); + } +} + +/* +static void app_ring_merge_track_2_in_1_16bits(int16_t *src_buf0, int16_t *src_buf1, int16_t *dst_buf, uint32_t src_len) +{ + app_ring_merge_track_2_in_1(src_buf0, src_buf1, dst_buf, src_len); +} + +static void app_ring_merge_track_2_in_1_24bits(int32_t *src_buf0, int16_t *src_buf1, int32_t *dst_buf, uint32_t src_len) +{ + app_ring_merge_track_2_in_1(src_buf0, src_buf1, dst_buf, src_len); +} +*/ + +template +static uint32_t app_ring_merge_oneshot_more_data_impl(uint8_t *buf, uint32_t len) +{ + uint32_t need_len = len / sizeof(DataType); + DataType *pBuf = ( DataType * )buf; + + uint32_t curr_size = 0; + + if (app_ring_merge_config.next == app_ring_merge_config.len) + { + return len; + } + + if (need_len > app_ring_merge_config.len) + { + app_ring_merge_track_2_in_1(pBuf, app_ring_merge_config.pbuf, pBuf, app_ring_merge_config.len); + app_ring_merge_config.next = app_ring_merge_config.len; + app_ring_merge_finished_callback(); + } + else + { + if ((app_ring_merge_config.len - app_ring_merge_config.next) >= need_len) + { + app_ring_merge_track_2_in_1(pBuf, app_ring_merge_config.pbuf + app_ring_merge_config.next, pBuf, need_len); + app_ring_merge_config.next += need_len; + } + else + { + curr_size = app_ring_merge_config.len - app_ring_merge_config.next; + app_ring_merge_track_2_in_1(pBuf, app_ring_merge_config.pbuf + app_ring_merge_config.next, pBuf, curr_size); + app_ring_merge_config.next = app_ring_merge_config.len; + app_ring_merge_finished_callback(); + } + } + return len; +} + +static uint32_t app_ring_merge_oneshot_more_data(uint8_t *buf, uint32_t len) +{ + uint32_t ret = 0; + + if (app_ring_merge_config.bits == AUD_BITS_16) + ret = app_ring_merge_oneshot_more_data_impl(buf, len); + else if (app_ring_merge_config.bits == AUD_BITS_24) + ret = app_ring_merge_oneshot_more_data_impl(buf, len); + else + TRACE(1,"[%s] warning not suitable callback available", __func__); + + return ret; +} + +template +static uint32_t app_ring_merge_periodic_more_data_impl(uint8_t *buf, uint32_t len) +{ + uint32_t need_len = len / sizeof(DataType); + uint32_t remain_size = len / sizeof(DataType); + uint32_t curr_size = 0; + DataType *pBuf = ( DataType * )buf; + if (need_len > app_ring_merge_config.len) + { + do + { + if (app_ring_merge_config.next) + { + curr_size = app_ring_merge_config.len - app_ring_merge_config.next; + app_ring_merge_track_2_in_1(pBuf, app_ring_merge_config.pbuf + app_ring_merge_config.next, pBuf, curr_size); + remain_size -= curr_size; + app_ring_merge_config.next = 0; + } + else if (remain_size > app_ring_merge_config.len) + { + app_ring_merge_track_2_in_1(pBuf + curr_size, app_ring_merge_config.pbuf, pBuf + curr_size, app_ring_merge_config.len); + curr_size += app_ring_merge_config.len; + remain_size -= app_ring_merge_config.len; + } + else + { + app_ring_merge_track_2_in_1(pBuf + curr_size, app_ring_merge_config.pbuf, pBuf + curr_size, remain_size); + app_ring_merge_config.next = remain_size; + remain_size = 0; + } + } while (remain_size); + } + else + { + if ((app_ring_merge_config.len - app_ring_merge_config.next) >= need_len) + { + app_ring_merge_track_2_in_1(pBuf, app_ring_merge_config.pbuf + app_ring_merge_config.next, pBuf, need_len); + app_ring_merge_config.next += need_len; + } + else + { + curr_size = app_ring_merge_config.len - app_ring_merge_config.next; + app_ring_merge_track_2_in_1(pBuf, app_ring_merge_config.pbuf + app_ring_merge_config.next, pBuf, curr_size); + app_ring_merge_config.next = need_len - curr_size; + app_ring_merge_track_2_in_1(pBuf + curr_size, app_ring_merge_config.pbuf, pBuf + curr_size, app_ring_merge_config.next); + } + } + return len; +} + +static uint32_t app_ring_merge_periodic_more_data(uint8_t *buf, uint32_t len) +{ + uint32_t ret = 0; + + if (app_ring_merge_config.bits == AUD_BITS_16) + ret = app_ring_merge_periodic_more_data_impl(buf, len); + else if (app_ring_merge_config.bits == AUD_BITS_24) + ret = app_ring_merge_periodic_more_data_impl(buf, len); + else + TRACE(1,"[%s] warning not suitable callback available", __func__); + + return ret; +} + + +uint32_t app_ring_merge_more_data(uint8_t *buf, uint32_t len) +{ + uint32_t nRet = len; + + osMutexWait(app_ring_merge_mutex_id, osWaitForever); + if (app_ring_merge_config.handler && + app_ring_merge_config.status != APP_RING_MERGE_STATUS_STOP) + { + if (app_ring_merge_config.status == APP_RING_MERGE_STATUS_START) + { + app_ring_merge_config.status = APP_RING_MERGE_STATUS_RUNNING; + } + nRet = app_ring_merge_config.handler(buf, len); + } + osMutexRelease(app_ring_merge_mutex_id); + + return nRet; +} + +int app_ring_merge_setup(int16_t *buf, uint32_t len, enum APP_RING_MERGE_PLAY_T play) +{ + TRACE(3,"%s mode:%d len:%d", __func__, play, len); + + osMutexWait(app_ring_merge_mutex_id, osWaitForever); + + app_ring_merge_config.status = APP_RING_MERGE_STATUS_STOP; + app_ring_merge_config.pbuf = ( int16_t * )buf; + app_ring_merge_config.len = len; + app_ring_merge_config.next = 0; + + app_ring_merge_config.play = play; + + if (play == APP_RING_MERGE_PLAY_ONESHOT) + { + app_ring_merge_config.handler = app_ring_merge_oneshot_more_data; + } + else if (play == APP_RING_MERGE_PLAY_PERIODIC) + { + app_ring_merge_config.handler = app_ring_merge_periodic_more_data; + } + + osMutexRelease(app_ring_merge_mutex_id); + + return 0; +} + +int app_ring_merge_init(void) +{ + if (app_ring_merge_mutex_id == NULL) + { + app_ring_merge_mutex_id = osMutexCreate((osMutex(app_ring_merge_mutex))); + } + + app_ring_merge_config.savedStoppedStreamId = -1; + return 0; +} + +int app_ring_merge_deinit(void) +{ + osMutexWait(app_ring_merge_mutex_id, osWaitForever); + + app_ring_merge_config.status = APP_RING_MERGE_STATUS_STOP; + app_ring_merge_config.pbuf = NULL; + app_ring_merge_config.len = 0; + app_ring_merge_config.next = 0; + app_ring_merge_config.bits = AUD_BITS_16; + app_ring_merge_config.play = APP_RING_MERGE_PLAY_QTY; + app_ring_merge_config.handler = NULL; + + app_ring_merge_config.savedStoppedStreamId = -1; + + osMutexRelease(app_ring_merge_mutex_id); + + return 0; +} + +int app_ring_merge_start(void) +{ + uint32_t ret; + struct AF_STREAM_CONFIG_T *stream_cfg = NULL; + + ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg, true); + if(ret != 0){ + TRACE(0,"Failed to get stream cfg"); + return 0; + } + TRACE(4,"%s: sample_rate: %d, bits: %d, channel: %d\n", + __func__, + stream_cfg->sample_rate, + stream_cfg->bits, + stream_cfg->channel_num); + + osMutexWait(app_ring_merge_mutex_id, osWaitForever); +#ifdef __BT_WARNING_TONE_MERGE_INTO_STREAM_SBC__ + switch (stream_cfg->sample_rate) + { + case AUD_SAMPRATE_8000: + app_ring_merge_setup(( int16_t * )RES_AUD_RING_SAMPRATE_8000, sizeof(RES_AUD_RING_SAMPRATE_8000) / sizeof(int16_t), APP_RING_MERGE_PLAY_ONESHOT); + app_ring_merge_config.next = 0; + app_ring_merge_config.status = APP_RING_MERGE_STATUS_START; + break; + case AUD_SAMPRATE_16000: + TRACE(0,"sample rate 16000 merge"); + app_ring_merge_setup(( int16_t * )RES_AUD_RING_SAMPRATE_16000, sizeof(RES_AUD_RING_SAMPRATE_16000) / sizeof(int16_t), APP_RING_MERGE_PLAY_ONESHOT); + app_ring_merge_config.next = 0; + app_ring_merge_config.status = APP_RING_MERGE_STATUS_START; + break; + case AUD_SAMPRATE_44100: + app_ring_merge_setup(( int16_t * )RES_AUD_RING_SAMPRATE_44100, sizeof(RES_AUD_RING_SAMPRATE_44100) / sizeof(int16_t), APP_RING_MERGE_PLAY_ONESHOT); + app_ring_merge_config.next = 0; + app_ring_merge_config.status = APP_RING_MERGE_STATUS_START; + break; + + case AUD_SAMPRATE_48000: + app_ring_merge_setup(( int16_t * )RES_AUD_RING_SAMPRATE_48000, sizeof(RES_AUD_RING_SAMPRATE_48000) / sizeof(int16_t), APP_RING_MERGE_PLAY_ONESHOT); + app_ring_merge_config.next = 0; + app_ring_merge_config.status = APP_RING_MERGE_STATUS_START; + break; + case AUD_SAMPRATE_22050: + case AUD_SAMPRATE_24000: + case AUD_SAMPRATE_96000: + case AUD_SAMPRATE_192000: + case AUD_SAMPRATE_NULL: + default: + app_ring_merge_config.next = 0; + app_ring_merge_config.status = APP_RING_MERGE_STATUS_START; + break; + } +#else + app_ring_merge_setup(( int16_t * )RES_AUD_RING_SAMPRATE_8000, + sizeof(RES_AUD_RING_SAMPRATE_8000) / sizeof(int16_t), + APP_RING_MERGE_PLAY_ONESHOT); + + app_ring_merge_config.next = 0; + app_ring_merge_config.status = APP_RING_MERGE_STATUS_START; +#endif + app_ring_merge_config.bits = stream_cfg->bits; + + app_ring_merge_config.savedStoppedStreamId = -1; + + osMutexRelease(app_ring_merge_mutex_id); + + return 0; +} + +int app_ring_merge_stop(void) +{ + osMutexWait(app_ring_merge_mutex_id, osWaitForever); + app_ring_merge_config.status = APP_RING_MERGE_STATUS_STOP; + app_ring_merge_config.next = 0; + osMutexRelease(app_ring_merge_mutex_id); + + app_ring_merge_finished_callback(); + + return 0; +} + +bool app_ring_merge_isrun(void) +{ + bool running = false; + osMutexWait(app_ring_merge_mutex_id, osWaitForever); + if (app_ring_merge_config.status == APP_RING_MERGE_STATUS_RUNNING) + { + running = true; + } + osMutexRelease(app_ring_merge_mutex_id); + return running; +} + +void app_ring_merge_save_pending_start_stream_op(uint8_t pendingStopOp, uint8_t deviceId) +{ + app_ring_merge_config.pendingStopOp = pendingStopOp; + app_ring_merge_config.savedStoppedStreamId = deviceId; +} + +static void app_ring_merge_finished_callback(void) +{ + TRACE(1,"%s", __func__); + app_ring_merge_config.status = APP_RING_MERGE_STATUS_STOP; + + if (app_ring_merge_config.savedStoppedStreamId >= 0) + { + if (PENDING_TO_STOP_A2DP_STREAMING == app_ring_merge_config.pendingStopOp) + { + TRACE(0,"Stop the pending stopped a2dp media stream."); + app_stop_a2dp_media_stream(app_ring_merge_config.savedStoppedStreamId); + } + else if (PENDING_TO_STOP_SCO_STREAMING == app_ring_merge_config.pendingStopOp) + { + TRACE(0,"Stop the pending stopped sco media stream."); + app_stop_sco_media_stream(app_ring_merge_config.savedStoppedStreamId); + } + } + app_ring_merge_config.savedStoppedStreamId = -1; +} diff --git a/services/bt_app/app_ring_merge.h b/services/bt_app/app_ring_merge.h new file mode 100644 index 0000000..0fc647f --- /dev/null +++ b/services/bt_app/app_ring_merge.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_RING_MERGE_H__ +#define __APP_RING_MERGE_H__ + +enum APP_RING_MERGE_PLAY_T { + APP_RING_MERGE_PLAY_ONESHOT = 0, + APP_RING_MERGE_PLAY_PERIODIC, + + APP_RING_MERGE_PLAY_QTY = 0xff +}; + +#define PENDING_TO_STOP_A2DP_STREAMING 0 +#define PENDING_TO_STOP_SCO_STREAMING 1 + +uint32_t app_ring_merge_more_data(uint8_t *buf, uint32_t len); + +int app_ring_merge_setup(int16_t *buf, uint32_t len, enum APP_RING_MERGE_PLAY_T play); + +int app_ring_merge_init(void); + +int app_ring_merge_deinit(void); + +int app_ring_merge_start(void); + +int app_ring_merge_stop(void); + +bool app_ring_merge_isrun(void); + +void app_ring_merge_save_pending_start_stream_op(uint8_t pendingStopOp, uint8_t deviceId); + + +#endif + diff --git a/services/bt_app/app_sec.cpp b/services/bt_app/app_sec.cpp new file mode 100644 index 0000000..0c8c003 --- /dev/null +++ b/services/bt_app/app_sec.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "apps.h" +#include "hal_trace.h" +#include "me_api.h" +#include "bt_if.h" +#include "nvrecord.h" +#if defined(IBRT) +#include "app_ibrt_if.h" +#endif + +void pair_handler_func(enum pair_event evt, const btif_event_t *event) +{ + switch(evt) { + case PAIR_EVENT_NUMERIC_REQ: + break; + case PAIR_EVENT_COMPLETE: +#if defined(_AUTO_TEST_) + AUTO_TEST_SEND("Pairing ok."); +#endif + +#ifndef FPGA +#ifdef MEDIA_PLAYER_SUPPORT + if (btif_me_get_callback_event_err_code(event) == BTIF_BEC_NO_ERROR) { +#if defined(IBRT) + app_voice_report(APP_STATUS_INDICATION_PAIRSUCCEED,0); +#endif + } else { + app_voice_report(APP_STATUS_INDICATION_PAIRFAIL,0); + } +#endif +#endif +#if defined(IBRT) + if (app_ibrt_if_is_audio_active()){ + TRACE(0,"!!!!!!!!!! flash_touch"); + nv_record_execute_async_flush(); + }else{ + TRACE(0,"!!!!!!!!!! flash_flush"); + nv_record_flash_flush(); + } +#elif !defined(__BT_ONE_BRING_TWO__) + nv_record_flash_flush(); +#endif + break; + default: + break; + } +} + +void auth_handler_func(void) +{ + /*currently do nothing*/ + return; +} diff --git a/services/bt_app/app_spp.cpp b/services/bt_app/app_spp.cpp new file mode 100644 index 0000000..ab9f007 --- /dev/null +++ b/services/bt_app/app_spp.cpp @@ -0,0 +1,257 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_chipid.h" +#include "analog.h" +#include "app_audio.h" +#include "app_status_ind.h" +#include "app_bt_stream.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "nvrecord_dev.h" +#include "umm_malloc.h" + +#include "cqueue.h" +#include "resources.h" +#include "app_spp.h" +#include "spp_api.h" +#include "sdp_api.h" +#include "app_spp.h" +#include "plat_types.h" + +#define SPP_MAX_PACKET_NUM 10 + +struct spp_device *app_create_spp_device(void) +{ + return btif_create_spp_device(); +} + +bt_status_t app_spp_send_data(struct spp_device *osDev_t, uint8_t* ptrData, uint16_t *length) +{ + bt_status_t status = BT_STS_FAILED; + uint8_t *ptrBuf = NULL; + uint16_t len = *length; + + if(!osDev_t->spp_connected_flag) { + TRACE(1,"%s spp don't connect\n", __func__); + return status; + } + + TRACE(2,"%s length %d", __func__, len); + //DUMP8("0x%02x ",ptrData,length); + + ptrBuf = (uint8_t *)umm_malloc(len); + if(NULL == ptrBuf) { + TRACE(1,"%s failed to malloc for tx buffer", __func__); + return status; + } + memcpy(ptrBuf, ptrData, len); + + status = btif_spp_write(osDev_t, (char *)ptrBuf, length); + if(status != BT_STS_SUCCESS) { + TRACE(2,"%s spp send error status %d", __func__, status); + umm_free(( void * )ptrBuf); + } + + return status; +} + +void app_spp_open(struct spp_device *osDev_t, + btif_remote_device_t *btDevice, + btif_sdp_record_param_t *param, + osMutexId mid, + uint8_t service_id, + spp_callback_t callback) +{ + btif_sdp_record_t *spp_sdp_record = NULL; + +#if SPP_SERVER == XA_ENABLED + struct spp_service *spp_service_t; + + if(osDev_t->portType == BTIF_SPP_SERVER_PORT) { + spp_service_t = btif_create_spp_service(); + spp_service_t->rf_service.serviceId = service_id; + spp_service_t->numPorts = 0; + + spp_sdp_record = btif_sdp_create_record(); + btif_sdp_record_setup(spp_sdp_record, param); + btif_spp_service_setup(osDev_t, spp_service_t, spp_sdp_record); + } +#endif + + btif_spp_init_device(osDev_t, SPP_MAX_PACKET_NUM, mid); + btif_spp_open(osDev_t, btDevice, callback); +} + + +#if defined(__BQB_PROFILE_TEST__) + +#if 1 +static struct spp_device *spp_test_dev; +osMutexDef(client_spp_test_mutex); +static uint8_t spp_test_rx_buf[SPP_RECV_BUFFER_SIZE]; +#define TEST_PORT_SPP 0x1101 +static const uint8_t SppTestSearchReq[] = { + /* First parameter is the search pattern in data element format. It + * is a list of 3 UUIDs. + */ + /* Data Element Sequence, 9 bytes */ + SDP_ATTRIB_HEADER_8BIT(9), + SDP_UUID_16BIT(TEST_PORT_SPP), + SDP_UUID_16BIT(PROT_L2CAP), /* L2CAP UUID in Big Endian */ + SDP_UUID_16BIT(PROT_RFCOMM), /* UUID for RFCOMM in Big Endian */ + /* The second parameter is the maximum number of bytes that can be + * be received for the attribute list. + */ + 0x00, + 0x64, /* Max number of bytes for attribute is 100 */ + SDP_ATTRIB_HEADER_8BIT(9), + SDP_UINT_16BIT(AID_PROTOCOL_DESC_LIST), + SDP_UINT_16BIT(AID_BT_PROFILE_DESC_LIST), + SDP_UINT_16BIT(AID_ADDITIONAL_PROT_DESC_LISTS) +}; +int spp_test_handle_data_event_func(void *pDev, uint8_t process, uint8_t *pData, uint16_t dataLen) +{ + TRACE(1,"%s", __func__); + return 0; +} +static void spp_test_client_callback(struct spp_device *locDev, struct spp_callback_parms *Info) +{ + TRACE(2,"%s event %d", __func__, Info->event); + switch (Info->event) + { + case BTIF_SPP_EVENT_REMDEV_CONNECTED: + TRACE(1,"::SPP_EVENT_REMDEV_CONNECTED %d\n", Info->event); + break; + + case BTIF_SPP_EVENT_REMDEV_DISCONNECTED: + TRACE(1,"::SPP_EVENT_REMDEV_DISCONNECTED %d\n", Info->event); + break; + + case BTIF_SPP_EVENT_DATA_SENT: + TRACE(1,"::SPP_EVENT_DATA_SENT %d\n", Info->event); + break; + + default: + TRACE(1,"::unknown event %d\n", Info->event); + break; + } +} +#endif + +#if 0 +void app_spp_test_client_open(btif_remote_device_t *remote_device) +{ +#if 1 + TRACE(1,"[%s]", __func__); + bt_status_t status; + osMutexId mid; + + if(spp_test_dev == NULL) + spp_test_dev = app_create_spp_device(); + //app_spp_init_tx_buf(NULL); + btif_spp_init_rx_buf(spp_test_dev, spp_test_rx_buf, SPP_RECV_BUFFER_SIZE); + + mid = osMutexCreate(osMutex(client_spp_test_mutex)); + if (!mid) + { + ASSERT(0, "cannot create mutex"); + } + spp_test_dev->portType = BTIF_SPP_CLIENT_PORT; + spp_test_dev->app_id = 0x8000; + spp_test_dev->spp_handle_data_event_func = spp_test_handle_data_event_func; + + btif_spp_init_device(spp_test_dev, SPP_MAX_PACKET_NUM, mid); + + spp_test_dev->sppDev.type.client.rfcommServiceSearchRequestPtr = (uint8_t*)SppTestSearchReq; + spp_test_dev->sppDev.type.client.rfcommServiceSearchRequestLen = sizeof(SppTestSearchReq); + status = btif_spp_open(spp_test_dev, remote_device, spp_test_client_callback); + TRACE(2,"%s status is %d", __func__, status); +#endif +} +#endif + +void pts_spp_client_init(void) +{ + TRACE(1,"[%s]", __func__); + //bt_status_t status; + osMutexId mid; + + if(spp_test_dev == NULL) + spp_test_dev = app_create_spp_device(); + //app_spp_init_tx_buf(NULL); + btif_spp_init_rx_buf(spp_test_dev, spp_test_rx_buf, SPP_RECV_BUFFER_SIZE); + + mid = osMutexCreate(osMutex(client_spp_test_mutex)); + if (!mid) + { + ASSERT(0, "cannot create mutex"); + } + spp_test_dev->portType = BTIF_SPP_CLIENT_PORT; + spp_test_dev->app_id = 0x8000; + spp_test_dev->spp_handle_data_event_func = spp_test_handle_data_event_func; + + btif_spp_init_device(spp_test_dev, SPP_MAX_PACKET_NUM, mid); + + spp_test_dev->sppDev.type.client.rfcommServiceSearchRequestPtr = (uint8_t*)SppTestSearchReq; + spp_test_dev->sppDev.type.client.rfcommServiceSearchRequestLen = sizeof(SppTestSearchReq); +} + +#include "conmgr_api.h" +btif_remote_device_t *btif_cmgr_pts_get_remDev(btif_cmgr_handler_t *cmgr_handler); +extern btif_cmgr_handler_t* pts_cmgr_handler; +void pts_cmgr_callback(btif_cmgr_handler_t *cHandler, + cmgr_event_t Event, + bt_status_t Status) +{ + btif_remote_device_t *remDev = btif_cmgr_pts_get_remDev(pts_cmgr_handler); + + TRACE(2,"%s Event %d", __func__, Event); + if (Event == BTIF_BTEVENT_LINK_CONNECT_IND || + Event == BTIF_BTEVENT_LINK_CONNECT_CNF) + { + if (Status == BT_STS_SUCCESS) + { + TRACE(2,"connect ok cHandler %p remDev=%x",cHandler, remDev); + btif_spp_open(spp_test_dev, remDev, spp_test_client_callback); + } + else + { + TRACE(0,"connect failed"); + } + } + + if (Event == BTIF_BTEVENT_LINK_DISCONNECT) + { + if (Status == BT_STS_SUCCESS) + { + TRACE(0,"disconnect ok"); + } + else + { + TRACE(0,"disconnect failed"); + } + } +} +#endif + diff --git a/services/bt_app/app_spp.h b/services/bt_app/app_spp.h new file mode 100644 index 0000000..5647f70 --- /dev/null +++ b/services/bt_app/app_spp.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_SPP_H__ +#define __APP_SPP_H__ + +#include "spp_api.h" +#include "sdp_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__3M_PACK__) +#define L2CAP_MTU 980 +#else +#define L2CAP_MTU 672 +#endif + +#define SPP_RECV_BUFFER_SIZE L2CAP_MTU*4 +#define SPP_MAX_DATA_PACKET_SIZE L2CAP_MTU + +#ifdef ENHANCED_STACK +#define BTIF_APP_SPP_SERVER_GSOUND_CTL_ID BTIF_APP_SPP_SERVER_ID_1 +#define BTIF_APP_SPP_SERVER_GSOUND_AUD_ID BTIF_APP_SPP_SERVER_ID_2 +#define BTIF_APP_SPP_SERVER_TOTA_ID BTIF_APP_SPP_SERVER_ID_3 +#define BTIF_APP_SPP_SERVER_BES_OTA_ID BTIF_APP_SPP_SERVER_ID_4 +#define BTIF_APP_SPP_SERVER_AI_VOICE_ID BTIF_APP_SPP_SERVER_ID_5 +#define BTIF_APP_SPP_SERVER_GREEN_ID BTIF_APP_SPP_SERVER_ID_6 +#define BTIF_APP_SPP_SERVER_RED_ID BTIF_APP_SPP_SERVER_ID_7 +#define BTIF_APP_SPP_SERVER_FP_RFCOMM_ID BTIF_APP_SPP_SERVER_ID_8 +#define BTIF_APP_SPP_SERVER_TOTA_GENERAL_ID BTIF_APP_SPP_SERVER_ID_9 + + +#define BTIF_APP_SPP_CLIENT_AI_VOICE_ID BTIF_APP_SPP_CLIENT_ID_1 +#define BTIF_APP_SPP_CLIENT_CCMP_ID BTIF_APP_SPP_CLIENT_ID_2 +#define BTIF_APP_SPP_CLIENT_RED_ID BTIF_APP_SPP_CLIENT_ID_3 + +/*--------------------------------------------------------------------------- + * rfcomm channel number + * should be from 1 to 30 + */ +enum RFCOMM_CHANNEL_NUM { + RFCOMM_CHANNEL_GS_CONTROL = RFCOMM_CHANNEL_1, + RFCOMM_CHANNEL_GS_AUDIO = RFCOMM_CHANNEL_2, + RFCOMM_CHANNEL_TOTA = RFCOMM_CHANNEL_3, + RFCOMM_CHANNEL_BES_OTA = RFCOMM_CHANNEL_4, + RFCOMM_CHANNEL_AI_VOICE = RFCOMM_CHANNEL_5, + RFCOMM_CHANNEL_GREEN = RFCOMM_CHANNEL_6, + RFCOMM_CHANNEL_RED = RFCOMM_CHANNEL_7, + RFCOMM_CHANNEL_FP = RFCOMM_CHANNEL_8, + RFCOMM_CHANNEL_TOTA_GENERAL = RFCOMM_CHANNEL_9, +}; +#endif + +struct spp_device *app_create_spp_device(void); +#if 0 +void app_spp_register_connect_callback(struct spp_device *osDev_t, spp_event_callback_t callback); +void app_spp_register_disconnect_callback(struct spp_device *osDev_t, spp_event_callback_t callback); +void app_spp_register_tx_done(struct spp_device *osDev_t, spp_event_callback_t callback); +#endif +bt_status_t app_spp_send_data(struct spp_device *osDev_t, uint8_t* ptrData, uint16_t *length); +void app_spp_open(struct spp_device *osDev_t, btif_remote_device_t *btDevice, btif_sdp_record_param_t *param, osMutexId mid, uint8_t service_id, spp_callback_t callback); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/bt_app/audio_prompt_sbc.cpp b/services/bt_app/audio_prompt_sbc.cpp new file mode 100644 index 0000000..ba87c83 --- /dev/null +++ b/services/bt_app/audio_prompt_sbc.cpp @@ -0,0 +1,1074 @@ +#include "audio_prompt_sbc.h" +#include "hal_trace.h" +#include "string.h" +#include "app_bt_stream.h" +#include "app_bt_media_manager.h" +#include "app_utils.h" +#include "cmsis.h" + + +#include "bt_drv_interface.h" +#include "audioflinger.h" +#include "app_media_player.h" +#if defined(IBRT) +#include "app_tws_ibrt.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_ctrl_thread.h" +#include "app_ibrt_if.h" +#endif +#include "app_audio.h" +#include "apps.h" +#ifdef MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED + +#define AUDIO_PROMPT_RESAMPLE_ITER_NUM 256 + +#ifdef TWS_PROMPT_SYNC +extern void tws_sync_mix_prompt_start_handling(void); +extern void tws_reset_mix_prompt_trigger_ticks(void); +extern void tws_enable_mix_prompt(bool isEnable); +#endif + + +extern void app_stop_a2dp_media_stream(uint8_t devId); +extern void app_stop_sco_media_stream(uint8_t devId); +extern void app_bt_stream_copy_track_one_to_two_16bits(int16_t *dst_buf, int16_t *src_buf, uint32_t src_len); + +static uint32_t audio_prompt_sbc_decode(uint8_t* pcm_buffer, uint32_t expectedOutputSize, uint8_t isReset); + +static btif_sbc_decoder_t audio_prompt_sbc_decoder; + +static float audio_prompt_sbc_eq_band_gain[8] = {1, 1, 1, 1, 1, 1, 1, 1}; + +// keep the current volume +#define KEEP_CURRENT_VOLUME_FOR_MIX_PROMPT -1 + +// from TGT_VOLUME_LEVEL_T or KEEP_CURRENT_VOLUME_FOR_MIX_PROMPT +#define DEFAULT_VOLUME_FOR_MIX_PROMPT KEEP_CURRENT_VOLUME_FOR_MIX_PROMPT + +#define DEFAULT_COEFF_FOR_MIX_PROMPT_FOR_MUSIC 1.0 +#define DEFAULT_COEFF_FOR_MIX_MUSIC_FOR_MUSIC 0.4 +#define DEFAULT_COEFF_FOR_MIX_PROMPT_FOR_CALL 1.0 +#define DEFAULT_COEFF_FOR_MIX_CALL_FOR_CALL 0.4 + +#define DEFAULT_OVERLAP_LENGTH 128 + +static int audio_prompt_sbc_init_decoder(void) +{ + btif_sbc_init_decoder(&audio_prompt_sbc_decoder); + return 0; +} + +typedef struct +{ + uint32_t wholeEncodedDataLen; + uint32_t leftEncodedDataLen; + uint8_t* promptDataBuf; + uint16_t tmpSourcePcmDataLen; + uint16_t tmpSourcePcmDataOutIndex; + uint8_t* tmpSourcePcmDataBuf; + uint8_t* tmpTargetPcmDataBuf; + CQueue pcmDataQueue; + uint8_t isResetDecoder; + uint8_t isAudioPromptDecodingDone; + uint8_t targetBytesCntPerSample; + uint32_t targetSampleRate; + struct APP_RESAMPLE_T * resampler; + uint32_t targetPcmChunkSize; + float resampleRatio; + uint8_t* bufForResampler; + uint32_t resampleBufLen; + uint8_t pendingStopOp; + int8_t savedStoppedStreamId; + uint8_t targetChannelCnt; + uint8_t mixType; + uint16_t promptId; + int16_t volume_level_override; + uint16_t promptPram; + float coeff_for_mix_prompt_for_music; + float coeff_for_mix_music_for_music; + float coeff_for_mix_prompt_for_call; + float coeff_for_mix_call_for_call; + uint8_t isMixPromptOn; + int16_t currentVol; + uint16_t mergeInOverlapLength; + uint16_t mergeOutOverlapLength; + float mergeInWeight; + float mergeOutWeight; + float mergeStep; +} AUDIO_PROMPT_ENV_T; + +static AUDIO_PROMPT_ENV_T audio_prompt_env; + +static void audio_prompt_set_pending_stop_op(uint8_t op) +{ + audio_prompt_env.pendingStopOp = op; + TRACE(1,"pendingStopOp is set to %d", op); +} + +static uint8_t audio_prompt_get_pending_stop_op(void) +{ + return audio_prompt_env.pendingStopOp; +} + +static void audio_prompt_set_saved_stopped_stream_id(int8_t id) +{ + audio_prompt_env.savedStoppedStreamId = id; + TRACE(1,"savedStoppedStreamId is set to %d", id); +} + +static int8_t audio_prompt_get_saved_stopped_stream_id(void) +{ + return audio_prompt_env.savedStoppedStreamId; +} + +void audio_prompt_init_handler(void) +{ + memset((uint8_t *)&audio_prompt_env, 0, sizeof(audio_prompt_env)); + audio_prompt_set_saved_stopped_stream_id(-1); +} + +bool audio_prompt_is_allow_update_volume(void) +{ + bool isAllow = true; + + uint32_t lock = int_lock_global(); + + isAllow= (!(audio_prompt_env.isMixPromptOn))|| + (KEEP_CURRENT_VOLUME_FOR_MIX_PROMPT == + audio_prompt_env.volume_level_override); + + int_unlock_global(lock); + + return isAllow; +} + +bool audio_prompt_is_playing_ongoing(void) +{ + bool isPlayingOnGoing = false; + uint32_t lock = int_lock_global(); + if (audio_prompt_env.isMixPromptOn) + { + isPlayingOnGoing = true; + } + int_unlock_global(lock); + return isPlayingOnGoing; +} + +#ifdef TWS_PROMPT_SYNC + +#define MEDIA_SHORT_TRIGGER_DELAY 8 +#define MEDIA_LONG_TRIGGER_DELAY 12 + +#define PROMPT_TICKS_OFFSET_TO_TRIGGER_MIX 10 // 3.25 ms + +static uint32_t mix_prompt_trigger_ticks = 0; +static uint32_t playback_interval_in_ticks = 0; +static uint32_t playback_last_irq_ticks = 0; +static uint8_t isStartMixPrompt = false; + +static uint32_t get_prompt_trigger_delay(uint16_t promptId) +{ + switch (promptId) + { + case AUDIO_ID_BT_GSOUND_MIC_OPEN: + case AUDIO_ID_BT_GSOUND_MIC_CLOSE: + // TODO: add more case for specific prompts here if you wanna it played sooner + return MEDIA_SHORT_TRIGGER_DELAY; + default: + return MEDIA_LONG_TRIGGER_DELAY; + } +} + +bool tws_calculate_mix_prompt_trigger_ticks(uint16_t promptId) +{ + if (0 == mix_prompt_trigger_ticks) + { + if ((playback_interval_in_ticks > 0)&&(playback_last_irq_ticks > 0)) + { + mix_prompt_trigger_ticks = playback_last_irq_ticks+ + get_prompt_trigger_delay(promptId)*playback_interval_in_ticks; + //TRACE(1,"playback_last_irq_ticks %d",playback_last_irq_ticks); + //TRACE(2,"playback_interval_in_ticks %d mix_prompt_trigger_ticks %d",playback_interval_in_ticks, mix_prompt_trigger_ticks); + return true; + } + } + + return false; +} + +void tws_enable_mix_prompt(bool isEnable) +{ + TRACE(1,"isStartMixPrompt to %d.", isEnable); + isStartMixPrompt = isEnable; +} + +void tws_set_mix_prompt_trigger_ticks(uint32_t ticks) +{ + mix_prompt_trigger_ticks = ticks; +} + +void tws_sync_mix_prompt_start_handling(void) +{ + if (!app_tws_ibrt_tws_link_connected()) + { + tws_enable_mix_prompt(true); + } + else + { + tws_enable_mix_prompt(false); + } +} + +bool tws_is_mix_prompt_allowed_to_start(void) +{ + return isStartMixPrompt; +} + +void app_ibrt_send_mix_prompt_req(void) +{ + if (app_tws_ibrt_tws_link_connected()) + { + APP_TWS_CMD_MIX_PROMPT_SYNC_T req; + req.promptId = audio_prompt_get_prompt_id(); + req.promptPram = audio_prompt_env.promptPram; + req.trigger_time = mix_prompt_trigger_ticks; + req.sampleRate = audio_prompt_get_sample_rate(); + tws_ctrl_send_cmd(APP_TWS_CMD_SYNC_MIX_PROMPT_REQ,(uint8_t*)&req,sizeof(APP_TWS_CMD_MIX_PROMPT_SYNC_T)); + } +} + +bool tws_sync_mix_prompt_handling(void) +{ + if (!tws_is_mix_prompt_allowed_to_start()) + { + if (tws_calculate_mix_prompt_trigger_ticks(audio_prompt_get_prompt_id())) + { + // get the trigger ticks, send request to slave + app_ibrt_send_mix_prompt_req(); + } + return false; + } + else + { + return true; + } +} + +uint32_t tws_get_mix_prompt_trigger_ticks(void) +{ + return mix_prompt_trigger_ticks; +} + +void tws_reset_mix_prompt_trigger_ticks(void) +{ + mix_prompt_trigger_ticks = 0; + playback_interval_in_ticks = 0; + playback_last_irq_ticks = 0; + isStartMixPrompt = false; +} + +void app_tws_stop_peer_prompt(void) +{ + uint8_t stub_param = 0; + + tws_ctrl_send_cmd(APP_TWS_CMD_STOP_PEER_PROMPT_REQ, &stub_param, sizeof(stub_param)); +} + +void tws_playback_ticks_check_for_mix_prompt(void) +{ + if ((!audio_prompt_is_playing_ongoing()) || tws_is_mix_prompt_allowed_to_start()) + { + //TRACE(0,"check for mix prompt<1>"); + return; + } + + uint32_t curr_ticks = 0; + uint16_t conhandle = INVALID_HANDLE; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + uint32_t btclk; + uint16_t btcnt; + int32_t offset; + + if (app_tws_ibrt_mobile_link_connected()){ + conhandle = p_ibrt_ctrl->mobile_conhandle; + }else if (app_tws_ibrt_slave_ibrt_link_connected()){ + conhandle = p_ibrt_ctrl->ibrt_conhandle; + }else{ + TRACE(0,"check for mix prompt<2>"); + tws_enable_mix_prompt(true); + return; + } + + bt_drv_reg_op_dma_tc_clkcnt_get(&btclk, &btcnt); + if(conhandle>=0x80){ + offset = bt_syn_get_offset_ticks(conhandle); + }else{ + offset = 0; + } + curr_ticks = (2*btclk + offset) & 0x0fffffff; + + if (mix_prompt_trigger_ticks > 0) + { + if (curr_ticks >= mix_prompt_trigger_ticks) + { + TRACE(2,"ticks<1> %d - trigger ticks %d", curr_ticks,mix_prompt_trigger_ticks); + tws_enable_mix_prompt(true); + } + else if ((curr_ticks < mix_prompt_trigger_ticks) && + ((mix_prompt_trigger_ticks - curr_ticks) < PROMPT_TICKS_OFFSET_TO_TRIGGER_MIX)) + { + TRACE(2,"ticks<2> %d - trigger ticks %d", curr_ticks,mix_prompt_trigger_ticks); + tws_enable_mix_prompt(true); + } + } + + if (0 != playback_last_irq_ticks) + { + playback_interval_in_ticks = curr_ticks-playback_last_irq_ticks; + } + + playback_last_irq_ticks = curr_ticks; +} + +void app_tws_cmd_sync_mix_prompt_req_handler(uint8_t* ptrParam, uint16_t paramLen) +{ + uint16_t promptPram = 0xFFFF; + uint32_t curr_ticks = 0xFFFFFFFF; + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + + APP_TWS_CMD_MIX_PROMPT_SYNC_T* pReq = (APP_TWS_CMD_MIX_PROMPT_SYNC_T *)ptrParam; + TRACE(2,"promptId, trigger_time:0x%x, %d", + pReq->promptId, pReq->trigger_time); + + audio_prompt_stop_playing(); + + if (app_tws_ibrt_slave_ibrt_link_connected()) + { + curr_ticks = bt_syn_get_curr_ticks(p_ibrt_ctrl->ibrt_conhandle); + } + + if ((!app_tws_ibrt_slave_ibrt_link_connected()) || + ((curr_ticks > pReq->trigger_time) && + ((curr_ticks - pReq->trigger_time) > PROMPT_TICKS_OFFSET_TO_TRIGGER_MIX))) + { + TRACE(0,"return directly."); + return; + } + + tws_set_mix_prompt_trigger_ticks(pReq->trigger_time); + promptPram = pReq->promptId | pReq->promptPram; + audio_prompt_start_playing(promptPram, pReq->sampleRate); + if (curr_ticks >= pReq->trigger_time) + { + TRACE(1,"Instant passed %d",curr_ticks); + tws_enable_mix_prompt(true); + } + else if ((curr_ticks < pReq->trigger_time) && + ((pReq->trigger_time - curr_ticks) < PROMPT_TICKS_OFFSET_TO_TRIGGER_MIX)){ + TRACE(1,"Instant near %d",curr_ticks); + tws_enable_mix_prompt(true); + } +} +#endif + +static int audio_prompt_resample_iter(uint8_t *buf, uint32_t len) +{ + if (!buf) + { + TRACE(0, "NULL pointer received in %s", __func__); + return -1; + } + + uint32_t leftLen = audio_prompt_env.tmpSourcePcmDataLen - audio_prompt_env.tmpSourcePcmDataOutIndex; + uint32_t lenToFetch; + + if (leftLen >= len) + { + lenToFetch = len; + } + else + { + lenToFetch = leftLen; + } + + memcpy(buf, audio_prompt_env.tmpSourcePcmDataBuf + audio_prompt_env.tmpSourcePcmDataOutIndex, + lenToFetch); + audio_prompt_env.tmpSourcePcmDataOutIndex += lenToFetch; + + memset(buf + lenToFetch, 0, len - lenToFetch); + + return 0; +} + +void audio_prompt_buffer_config(uint8_t mixType, + uint8_t channel_cnt, + uint8_t bitNumPerSample, + uint8_t *tmpSourcePcmDataBuf, + uint8_t *tmpTargetPcmDataBuf, + uint8_t *pcmDataBuf, + uint32_t pcmBufLen, + uint8_t *bufForResampler, + uint32_t resampleBufLen) +{ + af_lock_thread(); + audio_prompt_env.mixType = mixType; + audio_prompt_env.targetChannelCnt = channel_cnt; + if (24 == bitNumPerSample) + { + audio_prompt_env.targetBytesCntPerSample = 4; + } + else if (16 == bitNumPerSample) + { + audio_prompt_env.targetBytesCntPerSample = 2; + } + else + { + ASSERT(false, "bitNumPerSample %d is not supported by prompt mixer yet!", bitNumPerSample); + } + + audio_prompt_env.tmpSourcePcmDataBuf = tmpSourcePcmDataBuf; + audio_prompt_env.tmpTargetPcmDataBuf = tmpTargetPcmDataBuf; + audio_prompt_env.bufForResampler = bufForResampler; + audio_prompt_env.resampleBufLen = resampleBufLen; + + InitCQueue(&(audio_prompt_env.pcmDataQueue), pcmBufLen, (CQItemType *)(pcmDataBuf)); + af_unlock_thread(); +} + + +uint16_t audio_prompt_get_prompt_id(void) +{ + return audio_prompt_env.promptId; +} + +uint32_t audio_prompt_get_sample_rate(void) +{ + return audio_prompt_env.targetSampleRate; +} + +bool audio_prompt_start_playing(uint16_t promptPram, uint32_t targetSampleRate) +{ + uint16_t promptId = PROMPT_ID_FROM_ID_VALUE(promptPram); + + if (audio_prompt_is_playing_ongoing()) + { + return false; + } + + TRACE(0, "[%s]", __func__); + +#ifdef TWS_PROMPT_SYNC + bool isPlayingLocally = false; + if (app_tws_ibrt_tws_link_connected()) + { + isPlayingLocally = false; + } + else + { + isPlayingLocally = true; + } +#endif + + promptId = PROMPT_ID_FROM_ID_VALUE(promptId); + + uint32_t lock = int_lock_global(); + audio_prompt_env.isMixPromptOn = true; + + uint8_t* promptDataPtr = NULL; + uint32_t promptDataLen = 0; + PROMPT_MIX_PROPERTY_T* pPromptProperty = NULL; + +#ifdef MEDIA_PLAYER_SUPPORT + media_runtime_audio_prompt_update(promptId, &promptDataPtr, &promptDataLen); + pPromptProperty = get_prompt_mix_property(promptId); +#endif + + if (NULL == pPromptProperty) + { + TRACE(0,"use default mix property"); + + // use default property + audio_prompt_env.volume_level_override = DEFAULT_VOLUME_FOR_MIX_PROMPT; + + audio_prompt_env.coeff_for_mix_prompt_for_call = DEFAULT_COEFF_FOR_MIX_PROMPT_FOR_CALL; + audio_prompt_env.coeff_for_mix_call_for_call = DEFAULT_COEFF_FOR_MIX_CALL_FOR_CALL; + audio_prompt_env.coeff_for_mix_prompt_for_music = DEFAULT_COEFF_FOR_MIX_PROMPT_FOR_MUSIC; + audio_prompt_env.coeff_for_mix_music_for_music = DEFAULT_COEFF_FOR_MIX_MUSIC_FOR_MUSIC; + } + else + { + audio_prompt_env.volume_level_override = + pPromptProperty->volume_level_override; + + audio_prompt_env.coeff_for_mix_prompt_for_call = + pPromptProperty->coeff_for_mix_prompt_for_call; + audio_prompt_env.coeff_for_mix_call_for_call = + pPromptProperty->coeff_for_mix_call_for_call; + audio_prompt_env.coeff_for_mix_prompt_for_music = + pPromptProperty->coeff_for_mix_prompt_for_music; + audio_prompt_env.coeff_for_mix_music_for_music = + pPromptProperty->coeff_for_mix_music_for_music; + } + + if (KEEP_CURRENT_VOLUME_FOR_MIX_PROMPT != audio_prompt_env.volume_level_override) + { + // if the prompt's volume is smaller than the current volume, don't change it + if (audio_prompt_env.volume_level_override <= app_bt_stream_local_volume_get()) + { + audio_prompt_env.volume_level_override = KEEP_CURRENT_VOLUME_FOR_MIX_PROMPT; + } + } + + audio_prompt_env.promptId = promptId; + audio_prompt_env.promptPram = PROMPT_PRAM_FROM_ID_VALUE(promptPram); + audio_prompt_env.promptDataBuf = promptDataPtr; + audio_prompt_env.isResetDecoder = true; + audio_prompt_env.isAudioPromptDecodingDone = false; + audio_prompt_env.wholeEncodedDataLen = promptDataLen; + audio_prompt_env.leftEncodedDataLen = audio_prompt_env.wholeEncodedDataLen; + audio_prompt_env.targetSampleRate = targetSampleRate; + + audio_prompt_env.resampleRatio = ((float)AUDIO_PROMPT_SBC_SAMPLE_RATE_VALUE) / audio_prompt_env.targetSampleRate; + audio_prompt_env.targetPcmChunkSize = (uint32_t)(AUDIO_PROMPT_SBC_PCM_DATA_SIZE_PER_FRAME/audio_prompt_env.resampleRatio); + + audio_prompt_env.resampler = app_playback_resample_any_open_with_pre_allocated_buffer(( enum AUD_CHANNEL_NUM_T )AUDIO_PROMPT_SBC_CHANNEL_COUNT, + audio_prompt_resample_iter, + AUDIO_PROMPT_RESAMPLE_ITER_NUM, + audio_prompt_env.resampleRatio, + audio_prompt_env.bufForResampler, + audio_prompt_env.resampleBufLen); + + // audio resample out size should be even + uint16_t targetOverlapLength = ((uint16_t)(DEFAULT_OVERLAP_LENGTH / audio_prompt_env.resampleRatio) / 2 * 2); + audio_prompt_env.mergeInOverlapLength = targetOverlapLength * audio_prompt_env.targetChannelCnt; + audio_prompt_env.mergeOutOverlapLength = targetOverlapLength * audio_prompt_env.targetChannelCnt; + audio_prompt_env.mergeInWeight = 0.f; + audio_prompt_env.mergeOutWeight = 1.f; + audio_prompt_env.mergeStep = 1.f / (targetOverlapLength - 1); + + audio_prompt_set_saved_stopped_stream_id(-1); + + int_unlock_global(lock); + + TRACE(1,"start audio prompt. target sample rate %d", targetSampleRate); + + app_sysfreq_req(APP_SYSFREQ_USER_PROMPT_MIXER, APP_SYSFREQ_104M); + +#ifdef TWS_PROMPT_SYNC + if (!isPlayingLocally) + { + tws_sync_mix_prompt_start_handling(); + } + else + { + tws_enable_mix_prompt(true); + } +#endif + + + return true; +} + +void audio_prompt_forcefully_stop(void) +{ + app_playback_resample_close(audio_prompt_env.resampler); + audio_prompt_set_saved_stopped_stream_id(-1); + audio_prompt_env.isAudioPromptDecodingDone = true; + audio_prompt_env.leftEncodedDataLen = 0; + app_sysfreq_req(APP_SYSFREQ_USER_PROMPT_MIXER, APP_SYSFREQ_32K); +#if defined(IBRT) && defined(MEDIA_PLAYER_SUPPORT) + app_tws_sync_prompt_check(); +#endif +} + +bool audio_prompt_check_on_stopping_stream(uint8_t pendingStopOp, uint8_t deviceId) +{ + uint32_t lock = int_lock_global(); + if (audio_prompt_env.isMixPromptOn) + { + if (bt_is_playback_triggered()) + { + TRACE(1,"Prompt mixing ongoing, pending op:%d", pendingStopOp); + audio_prompt_env.pendingStopOp = pendingStopOp; + audio_prompt_set_saved_stopped_stream_id(deviceId); + int_unlock_global(lock); + return false; + } + else + { + int_unlock_global(lock); + audio_prompt_stop_playing(); + return true; + } + } + + int_unlock_global(lock); + return true; +} + +bool audio_prompt_clear_pending_stream(uint8_t op) +{ + bool isToClearActiveMedia = false; + + TRACE(4, + "%s stop_id %d pendingStopOp %d op %d", + __func__, + audio_prompt_get_saved_stopped_stream_id(), + audio_prompt_env.pendingStopOp, + op); + + if (-1 != audio_prompt_get_saved_stopped_stream_id()) + { + uint32_t lock = int_lock_global(); + if ((PENDING_TO_STOP_A2DP_STREAMING == op) && + (PENDING_TO_STOP_A2DP_STREAMING == audio_prompt_get_pending_stop_op())) + { + audio_prompt_set_saved_stopped_stream_id(-1); + audio_prompt_set_pending_stop_op(PENDING_TO_STOP_STREAM_INVALID); + isToClearActiveMedia = true; + } + else if ((PENDING_TO_STOP_SCO_STREAMING == op) && + (PENDING_TO_STOP_SCO_STREAMING == audio_prompt_get_pending_stop_op())) + { + audio_prompt_set_saved_stopped_stream_id(-1); + audio_prompt_set_pending_stop_op(PENDING_TO_STOP_STREAM_INVALID); + isToClearActiveMedia = true; + } + int_unlock_global(lock); + } + + return isToClearActiveMedia; +} + +void audio_prompt_stop_playing(void) +{ + if (!audio_prompt_env.isMixPromptOn) + { + return; + } + + TRACE(0,"Stop audio prompt."); + + app_playback_resample_close(audio_prompt_env.resampler); + + uint32_t lock = int_lock_global(); + + audio_prompt_env.leftEncodedDataLen = 0; + audio_prompt_env.isMixPromptOn = false; + +#ifdef TWS_PROMPT_SYNC + tws_reset_mix_prompt_trigger_ticks(); +#endif + + int_unlock_global(lock); + + if (KEEP_CURRENT_VOLUME_FOR_MIX_PROMPT != audio_prompt_env.volume_level_override) + { + // restore the volume + app_bt_stream_volumeset_handler(app_bt_stream_local_volume_get()); + } + + lock = int_lock_global(); + + uint8_t pendingStopOp; + int8_t savedStoppedStreamId; + + pendingStopOp = audio_prompt_env.pendingStopOp; + savedStoppedStreamId = audio_prompt_get_saved_stopped_stream_id(); + + audio_prompt_set_saved_stopped_stream_id(-1); + + int_unlock_global(lock); + + if (savedStoppedStreamId >= 0) + { + if (PENDING_TO_STOP_A2DP_STREAMING == pendingStopOp) + { + TRACE(0,"Stop the pending stopped a2dp media stream."); + app_stop_a2dp_media_stream(savedStoppedStreamId); + } + else if (PENDING_TO_STOP_SCO_STREAMING == pendingStopOp) + { + TRACE(0,"Stop the pending stopped sco media stream."); + app_stop_sco_media_stream(savedStoppedStreamId); + } + } + + app_sysfreq_req(APP_SYSFREQ_USER_PROMPT_MIXER, APP_SYSFREQ_32K); + +#if defined(IBRT) && defined(MEDIA_PLAYER_SUPPORT) + app_tws_sync_prompt_check(); +#endif + //check if there is any pending prompt need to play + APP_AUDIO_STATUS status_next; + APP_AUDIO_STATUS aud_status; + aud_status.id = APP_PLAY_BACK_AUDIO; + if (app_audio_list_rmv_callback(&aud_status, &status_next,APP_BT_SETTING_Q_POS_HEAD, true)) + { + TRACE(4,"%s next id: 0x%x%s, aud_id %d", __func__, status_next.id, player2str(status_next.id), status_next.aud_id); +#if defined(IBRT) + app_ibrt_if_voice_report_handler(status_next.aud_id, true); +#endif + } + +} + +template +static inline DstType prompt_data_ssat(int32_t in) +{ + DstType out; + + if (sizeof(DstType) == 2) { + out = __SSAT(in, 16); + } else { + out = __SSAT(in, 24); + } + + return out; +} + +template +static inline DstType prompt_data_extend(int16_t in) +{ + DstType out; + + if (sizeof(DstType) == 2) { + out = in; + } else { + out = (in << 8); + } + + return out; +} + +template +static void audio_prompt_crossfade(DstType *dst_buf, DstType *src_buf1, int16_t *src_buf0, + float coeff_for_source, float coeff_for_prompt, + uint32_t merge_in_end, uint32_t merge_out_start, uint32_t src_len) +{ + uint32_t i = 0; + if (audio_prompt_env.targetChannelCnt == 2) { + float weight = audio_prompt_env.mergeInWeight; + for (; i < merge_in_end; i += 2) { + /* TODO: increase coeff by step instead of calcualted every step */ + float coeff0 = 1 - weight + weight * coeff_for_source; + float coeff1 = weight * coeff_for_prompt; + + float tmp0 = coeff0 * src_buf1[i] + coeff1 * prompt_data_extend(src_buf0[i]); + float tmp1 = coeff0 * src_buf1[i + 1] + coeff1 * prompt_data_extend(src_buf0[i + 1]); + dst_buf[i] = prompt_data_ssat((int32_t)tmp0); + dst_buf[i + 1] = prompt_data_ssat((int32_t)tmp1); + + weight += audio_prompt_env.mergeStep; + } + audio_prompt_env.mergeInOverlapLength -= merge_in_end; + audio_prompt_env.mergeInWeight = weight; + } else if (audio_prompt_env.targetChannelCnt == 1) { + float weight = audio_prompt_env.mergeInWeight; + for (; i < merge_in_end; i++) { + float coeff0 = 1 - weight + weight * coeff_for_source; + float coeff1 = weight * coeff_for_prompt; + + float tmp0 = coeff0 * src_buf1[i] + coeff1 * prompt_data_extend(src_buf0[i]); + dst_buf[i] = prompt_data_ssat((int32_t)tmp0); + + weight += audio_prompt_env.mergeStep; + } + audio_prompt_env.mergeInOverlapLength -= merge_in_end; + audio_prompt_env.mergeInWeight = weight; + } else { + ASSERT(0, "[%s] channel number %d not supported", __FUNCTION__, audio_prompt_env.targetChannelCnt); + } + for (; i < merge_out_start; i++) { + float mix_value = coeff_for_prompt * prompt_data_extend(src_buf0[i]) + + coeff_for_source * src_buf1[i]; + dst_buf[i] = prompt_data_ssat((int32_t)mix_value); + } + if (audio_prompt_env.targetChannelCnt == 2) { + float weight = audio_prompt_env.mergeOutWeight; + for (; i < src_len; i += 2) { + float coeff0 = (1 - weight + weight * coeff_for_source); + float coeff1 = weight * coeff_for_prompt; + + float tmp0 = coeff0 * src_buf1[i] + coeff1 * prompt_data_extend(src_buf0[i]); + float tmp1 = coeff0 * src_buf1[i + 1] + coeff1 * prompt_data_extend(src_buf0[i + 1]); + dst_buf[i] = prompt_data_ssat((int32_t)tmp0); + dst_buf[i + 1] = prompt_data_ssat((int32_t)tmp1); + + weight -= audio_prompt_env.mergeStep; + } + audio_prompt_env.mergeOutOverlapLength -= src_len - merge_out_start; + audio_prompt_env.mergeOutWeight = weight; + } else if (audio_prompt_env.targetChannelCnt == 1) { + float weight = audio_prompt_env.mergeOutWeight; + for (; i < src_len; i++) { + float coeff0 = (1 - weight + weight * coeff_for_source); + float coeff1 = weight * coeff_for_prompt; + + float tmp0 = coeff0 * src_buf1[i] + coeff1 * prompt_data_extend(src_buf0[i]); + dst_buf[i] = prompt_data_ssat((int32_t)tmp0); + + weight -= audio_prompt_env.mergeStep; + } + audio_prompt_env.mergeOutOverlapLength -= src_len - merge_out_start; + audio_prompt_env.mergeOutWeight = weight; + } else { + ASSERT(0, "[%s] channel number %d not supported", __FUNCTION__, audio_prompt_env.targetChannelCnt); + } +} + +static void audio_prompt_processing_handler_func(uint32_t acquiredPcmDataLen, uint8_t* pcmDataToMerge) +{ +#ifdef TWS_PROMPT_SYNC + uint16_t prompt_chnlsel = PROMPT_CHNLSEl_FROM_ID_VALUE(audio_prompt_env.promptPram); +#endif + + uint32_t pcmDataToGetFromPrompt = acquiredPcmDataLen/(audio_prompt_env.targetChannelCnt*audio_prompt_env.targetBytesCntPerSample/2); + + while ((uint32_t)LengthOfCQueue(&(audio_prompt_env.pcmDataQueue)) < pcmDataToGetFromPrompt) + { + if (audio_prompt_env.isAudioPromptDecodingDone) + { + break; + } + + // decode the audio prompt + uint32_t returnedPcmDataLen = audio_prompt_sbc_decode(audio_prompt_env.tmpSourcePcmDataBuf, + AUDIO_PROMPT_SBC_PCM_DATA_SIZE_PER_FRAME, + audio_prompt_env.isResetDecoder); + + if (returnedPcmDataLen < AUDIO_PROMPT_SBC_PCM_DATA_SIZE_PER_FRAME) + { + audio_prompt_env.isAudioPromptDecodingDone = true; + } + + audio_prompt_env.isResetDecoder = false; + audio_prompt_env.tmpSourcePcmDataLen = returnedPcmDataLen; + audio_prompt_env.tmpSourcePcmDataOutIndex = 0; + + // do resmpling + if (audio_prompt_env.targetSampleRate != AUDIO_PROMPT_SBC_SAMPLE_RATE_VALUE) + { + uint32_t targetPcmSize = returnedPcmDataLen; + if (AUDIO_PROMPT_SBC_PCM_DATA_SIZE_PER_FRAME == returnedPcmDataLen) + { + targetPcmSize = audio_prompt_env.targetPcmChunkSize; + } + else + { + targetPcmSize = (uint32_t)(returnedPcmDataLen/audio_prompt_env.resampleRatio); + } + + targetPcmSize = (targetPcmSize/4)*4; + + app_playback_resample_run(audio_prompt_env.resampler, + audio_prompt_env.tmpTargetPcmDataBuf, + targetPcmSize); + + // fill into pcm data queue + EnCQueue(&(audio_prompt_env.pcmDataQueue), audio_prompt_env.tmpTargetPcmDataBuf, targetPcmSize); + } + else + { + EnCQueue(&(audio_prompt_env.pcmDataQueue), audio_prompt_env.tmpSourcePcmDataBuf, returnedPcmDataLen); + } + } + + uint32_t pcmDataLenToMerge = pcmDataToGetFromPrompt; + if ((uint32_t)LengthOfCQueue(&(audio_prompt_env.pcmDataQueue)) < pcmDataToGetFromPrompt) + { + pcmDataLenToMerge = LengthOfCQueue(&(audio_prompt_env.pcmDataQueue)); + } + + if (pcmDataLenToMerge == 0) + goto exit; + + // copy to multiple channel if needed + if (audio_prompt_env.targetChannelCnt > 1) + { + // get the data + DeCQueue(&(audio_prompt_env.pcmDataQueue), audio_prompt_env.tmpSourcePcmDataBuf, pcmDataLenToMerge); + app_bt_stream_copy_track_one_to_two_16bits(( int16_t * )audio_prompt_env.tmpTargetPcmDataBuf, + ( int16_t * )audio_prompt_env.tmpSourcePcmDataBuf, + pcmDataLenToMerge / sizeof(uint16_t)); + } + else + { + DeCQueue(&(audio_prompt_env.pcmDataQueue), audio_prompt_env.tmpTargetPcmDataBuf, pcmDataLenToMerge); + } + +#ifdef TWS_PROMPT_SYNC + if (IS_PROMPT_CHNLSEl_ALL(prompt_chnlsel) || app_ibrt_voice_report_is_me(prompt_chnlsel)) +#endif + { + // merge the data + int16_t *src_buf0 = (int16_t *)audio_prompt_env.tmpTargetPcmDataBuf; + uint32_t src_len = pcmDataLenToMerge*audio_prompt_env.targetChannelCnt/sizeof(uint16_t); + + float coeff_for_prompt; + float coeff_for_source; + + if (MIX_WITH_A2DP_STREAMING == audio_prompt_env.mixType) { + coeff_for_prompt = audio_prompt_env.coeff_for_mix_prompt_for_music; + coeff_for_source = audio_prompt_env.coeff_for_mix_music_for_music; + } else { + coeff_for_prompt = audio_prompt_env.coeff_for_mix_prompt_for_call; + coeff_for_source = audio_prompt_env.coeff_for_mix_call_for_call; + } + + /* + * 0 --------------- merge_in_end --- merge_out_start --- src_len + * |---- merge in ---------|---- merge ------|----- merge out ---| + * Split data into three segments, merge in stands for merge begin crossfade, merge out for merge end crossfade. + * In merge begin crossfade stage, old data is music/sco pcm data, new data is merged data. + * In merge end crossfade stage, old data is merged data, new data is music/sco data. + * Assume music/soc is a, ring is b, then merged data is x = m * a + p * b, + * merge begin final data y = (1 - w) * a + w * x = (1 - w + w * m) * a + w * p * b for w = 0:step:1, + * merge end final data y = (1 - w) * a + w * x = (1 - w + w * m) * a + w * p * b for w = 1:-step:0. + */ + uint32_t merge_in_end = 0; + if (audio_prompt_env.mergeInOverlapLength > 0) { + TRACE(3, "[%s] bytes_per_sample %d, channel_num %d", __FUNCTION__, + audio_prompt_env.targetBytesCntPerSample, audio_prompt_env.targetChannelCnt); + TRACE(2, "[%s] merge start, remain %d", __FUNCTION__, audio_prompt_env.mergeInOverlapLength); + merge_in_end = MIN(audio_prompt_env.mergeInOverlapLength, src_len); + } + + uint32_t merge_out_start = src_len; + /* TODO: calc remain decoded pcm samples for DEFAULT_OVERLAP_LENGTH > 128 */ + if (audio_prompt_env.leftEncodedDataLen == 0) { + if (LengthOfCQueue(&(audio_prompt_env.pcmDataQueue)) < audio_prompt_env.mergeOutOverlapLength / audio_prompt_env.targetChannelCnt * (int32_t)sizeof(uint16_t)) { + TRACE(2, "[%s] merge end, remain %d", __FUNCTION__, audio_prompt_env.mergeOutOverlapLength); + merge_out_start = src_len - (audio_prompt_env.mergeOutOverlapLength - LengthOfCQueue(&(audio_prompt_env.pcmDataQueue)) / sizeof(uint16_t) * audio_prompt_env.targetChannelCnt); + } + } + + //TRACE(3, "[%s] merge_in_end = %d, merge_out_start = %d", __FUNCTION__, merge_in_end, merge_out_start); + //TRACE(3, "[%s] pcm queue size = %d, src_len = %d", __FUNCTION__, LengthOfCQueue(&(audio_prompt_env.pcmDataQueue)), src_len); + + if (2 == audio_prompt_env.targetBytesCntPerSample) + { + int16_t *src_buf1 = (int16_t *)pcmDataToMerge; + int16_t *dst_buf = (int16_t *)pcmDataToMerge; + + audio_prompt_crossfade(dst_buf, src_buf1, src_buf0, + coeff_for_source, coeff_for_prompt, + merge_in_end, merge_out_start, src_len); + } + else if (4 == audio_prompt_env.targetBytesCntPerSample) + { + int32_t *src_buf1 = (int32_t *)pcmDataToMerge; + int32_t *dst_buf = (int32_t *)pcmDataToMerge; + + audio_prompt_crossfade(dst_buf, src_buf1, src_buf0, + coeff_for_source, coeff_for_prompt, + merge_in_end, merge_out_start, src_len); + } + } + +exit: + if (audio_prompt_env.mergeOutOverlapLength == 0) + { + // prompt playing is completed + audio_prompt_stop_playing(); + app_sysfreq_req(APP_SYSFREQ_USER_PROMPT_MIXER, APP_SYSFREQ_32K); + } + +} + +void audio_prompt_processing_handler(uint32_t acquiredPcmDataLen, uint8_t* pcmDataToMerge) +{ +#ifdef TWS_PROMPT_SYNC + if (!tws_sync_mix_prompt_handling()) + { + return; + } +#endif + + af_lock_thread(); + + if (audio_prompt_env.leftEncodedDataLen == + audio_prompt_env.wholeEncodedDataLen) + { + if (KEEP_CURRENT_VOLUME_FOR_MIX_PROMPT != audio_prompt_env.volume_level_override) + { + // first entering, coordinate the volume here + app_bt_stream_volumeset_handler(audio_prompt_env.volume_level_override); + } + } + + uint32_t gotDataLen = 0; + while (gotDataLen < acquiredPcmDataLen) + { + uint32_t lenToGet; + if ((acquiredPcmDataLen - gotDataLen) > AUDIO_PROMPT_PCM_FILL_UNIT_SIZE) + { + lenToGet = AUDIO_PROMPT_PCM_FILL_UNIT_SIZE; + } + else + { + lenToGet = acquiredPcmDataLen - gotDataLen; + } + + audio_prompt_processing_handler_func(lenToGet, pcmDataToMerge+gotDataLen); + gotDataLen += lenToGet; + } + af_unlock_thread(); +} + +static uint32_t audio_prompt_sbc_decode(uint8_t* pcm_buffer, uint32_t expectedOutputSize, uint8_t isReset) +{ + if (isReset) + { + audio_prompt_sbc_init_decoder(); + } + + uint32_t sbcDataBytesToDecode; + unsigned int pcm_offset = 0; + uint16_t byte_decode; + int8_t ret; + btif_sbc_pcm_data_t audio_prompt_PcmDecData; + +get_again: + audio_prompt_PcmDecData.data = pcm_buffer+pcm_offset; + audio_prompt_PcmDecData.dataLen = 0; + + if (audio_prompt_env.leftEncodedDataLen > AUDIO_PROMPT_SBC_ENCODED_DATA_SIZE_PER_FRAME) + { + sbcDataBytesToDecode = AUDIO_PROMPT_SBC_ENCODED_DATA_SIZE_PER_FRAME; + } + else + { + sbcDataBytesToDecode = audio_prompt_env.leftEncodedDataLen; + } + + ret = btif_sbc_decode_frames(&audio_prompt_sbc_decoder, + audio_prompt_env.promptDataBuf+audio_prompt_env.wholeEncodedDataLen-audio_prompt_env.leftEncodedDataLen, + sbcDataBytesToDecode, &byte_decode, + &audio_prompt_PcmDecData, expectedOutputSize-pcm_offset, + audio_prompt_sbc_eq_band_gain); + + + audio_prompt_env.leftEncodedDataLen -= byte_decode; + + pcm_offset += audio_prompt_PcmDecData.dataLen; + + if (0 == audio_prompt_env.leftEncodedDataLen) + { + goto exit; + } + + if (expectedOutputSize == pcm_offset) + { + goto exit; + } + + if ((ret == BT_STS_CONTINUE) || (ret == BT_STS_SUCCESS)) { + goto get_again; + } + +exit: + return pcm_offset; +} +#endif // MIX_AUDIO_PROMPT_WITH_A2DP_MEDIA_ENABLED diff --git a/services/bt_app/audio_prompt_sbc.h b/services/bt_app/audio_prompt_sbc.h new file mode 100644 index 0000000..65e1844 --- /dev/null +++ b/services/bt_app/audio_prompt_sbc.h @@ -0,0 +1,118 @@ +#ifndef __AUDIO_PROMPT_SBC_H__ +#define __AUDIO_PROMPT_SBC_H__ +#include "stdint.h" +#include "cqueue.h" +#include "codec_sbc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MIX_WITH_A2DP_STREAMING 0 +#define MIX_WITH_SCO_STREAMING 1 + +#define PENDING_TO_STOP_A2DP_STREAMING 0 +#define PENDING_TO_STOP_SCO_STREAMING 1 +#define PENDING_TO_STOP_STREAM_INVALID (0xFF) + +typedef struct +{ + uint8_t channelCnt; + uint8_t channelMode; + uint8_t bitPool; + uint8_t sizePerSample; + uint8_t sampleRate; + uint8_t numBlocks; + uint8_t numSubBands; + uint8_t mSbcFlag; + uint8_t allocMethod; +} AUDIO_PROMPT_SBC_CONFIG_T; + +#ifdef TWS_PROMPT_SYNC +typedef struct { + uint16_t promptId; + uint16_t promptPram; + uint32_t sampleRate; + uint32_t trigger_time; +}APP_TWS_CMD_MIX_PROMPT_SYNC_T; + +#endif + +typedef struct +{ + uint8_t dev_id; + uint16_t voicePrompt; +} app_tws_voice_prompt_to_play_t; + +#define IS_IGNORME_SBC_FRAME_HEADER (1) +#define AUDIO_PROMPT_SBC_FRAME_HEADER_LEN (4) + +#define AUDIO_PROMPT_SBC_CHANNEL_COUNT (1) +#define AUDIO_PROMPT_SBC_CHANNEL_MODE (BTIF_SBC_CHNL_MODE_MONO) + +#define AUDIO_PROMPT_SOURCE_PCM_BUFFER_SIZE (512) +#define AUDIO_PROMPT_TARGET_PCM_BUFFER_SIZE (AUDIO_PROMPT_SOURCE_PCM_BUFFER_SIZE*3) +#define AUDIO_PROMPT_PCM_BUFFER_SIZE (AUDIO_PROMPT_SOURCE_PCM_BUFFER_SIZE*4) + +#define AUDIO_PROMPT_SBC_BLOCK_SIZE 40 +#define AUDIO_PROMPT_SBC_SIZE_PER_SAMPLE (2)// 16 bits, 1 channel + + +#define AUDIO_PROMPT_SBC_SAMPLE_RATE_VALUE 16000 + +#define AUDIO_PROMPT_SBC_FRAME_PERIOD_IN_MS (24) + +#define AUDIO_PROMPT_SBC_PCM_DATA_SIZE_PER_FRAME 256 + +#define AUDIO_PROMPT_PCM_FILL_UNIT_SIZE (AUDIO_PROMPT_SBC_PCM_DATA_SIZE_PER_FRAME*2) + +#define AUDIO_PROMPT_SBC_ENCODED_DATA_SIZE_PER_FRAME (AUDIO_PROMPT_SBC_BLOCK_SIZE*4) + +#define AUDIO_PROMPT_BUF_SIZE_FOR_RESAMPLER 800 + +uint32_t audio_prompt_sbc_get_frame_len(void); + +void audio_prompt_init_handler(void); + +bool audio_prompt_is_playing_ongoing(void); + +void audio_prompt_buffer_config(uint8_t mixType, + uint8_t channel_cnt, + uint8_t bitNumPerSample, + uint8_t *tmpSourcePcmDataBuf, + uint8_t *tmpTargetPcmDataBuf, + uint8_t *pcmDataBuf, + uint32_t pcmBufLen, + uint8_t *bufForResampler, + uint32_t resampleBufLen); + +bool audio_prompt_start_playing(uint16_t promptId, uint32_t targetSampleRate); + +void audio_prompt_stop_playing(void); + +void audio_prompt_processing_handler(uint32_t acquiredPcmDataLen, + uint8_t *pcmDataToMerge); + +bool audio_prompt_check_on_stopping_stream(uint8_t pendingStopOp, uint8_t deviceId); + +void audio_prompt_forcefully_stop(void); + +bool audio_prompt_is_allow_update_volume(void); + +uint16_t audio_prompt_get_prompt_id(void); + +uint32_t audio_prompt_get_sample_rate(void); + +#ifdef TWS_PROMPT_SYNC +void tws_playback_ticks_check_for_mix_prompt(void); +void app_tws_cmd_sync_mix_prompt_req_handler(uint8_t *ptrParam, uint16_t paramLen); +#endif + +bool audio_prompt_clear_pending_stream(uint8_t op); + +#ifdef __cplusplus +} +#endif + +#endif // __AUDIO_PROMPT_SBC_H__ + diff --git a/services/bt_app/besbt.h b/services/bt_app/besbt.h new file mode 100644 index 0000000..896040d --- /dev/null +++ b/services/bt_app/besbt.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/*** + * besbt.h + */ + +#ifndef BESBT_H +#define BESBT_H + +enum BESBT_HOOK_USER_T { + BESBT_HOOK_USER_0 = 0, + BESBT_HOOK_USER_1, + BESBT_HOOK_USER_2, + BESBT_HOOK_USER_3, + BESBT_HOOK_USER_QTY +}; + +typedef void (*BESBT_HOOK_HANDLER)(void); + +#ifdef __cplusplus +extern "C" { +#endif + +void BesbtInit(void); +void BesbtThread(void const *argument); +int Besbt_hook_handler_set(enum BESBT_HOOK_USER_T user, BESBT_HOOK_HANDLER handler); +unsigned char *bt_get_local_address(void); +void bt_set_local_address(unsigned char* btaddr); +unsigned char *bt_get_ble_local_address(void); +const char *bt_get_local_name(void); +void bt_set_local_name(const char* name); +const char *bt_get_ble_local_name(void); +void gen_bt_addr_for_debug(void); +void bt_set_ble_local_address(uint8_t* bleAddr); + +#ifdef __cplusplus +} +#endif +#endif /* BESBT_H */ diff --git a/services/bt_app/besbt_cfg.h b/services/bt_app/besbt_cfg.h new file mode 100644 index 0000000..aebc04e --- /dev/null +++ b/services/bt_app/besbt_cfg.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/*** + * besbt_cfg.h + */ + +#ifndef BESBT_CFG_H +#define BESBT_CFG_H +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct besbt_cfg_t{ + bool sniff; + bool force_use_cvsd; + bool one_bring_two; + bool avdtp_cp_enable; + bool source_enable; + bool lhdc_v3; +}; +extern struct besbt_cfg_t besbt_cfg; + +#ifdef __cplusplus +} +#endif +#endif /* BESBT_H */ diff --git a/services/bt_app/besmain.cpp b/services/bt_app/besmain.cpp new file mode 100644 index 0000000..b57a713 --- /dev/null +++ b/services/bt_app/besmain.cpp @@ -0,0 +1,524 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +//#include "mbed.h" +#include +#include +#include "string.h" +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_chipid.h" +#include "analog.h" +#include "apps.h" +#include "app_status_ind.h" +#include "app_utils.h" +#include "app_bt_stream.h" +#include "nvrecord_dev.h" +#include "tgt_hardware.h" +#include "besbt_cfg.h" +#include "hfp_api.h" +#include "app_bt_func.h" +#include "rwapp_config.h" +#include "bt_if.h" +#include "os_api.h" +#include "dip_api.h" +#if defined(ENHANCED_STACK) +#include "sdp_api.h" +#endif +#ifdef BTIF_DIP_DEVICE +#include "app_dip.h" +#endif + +#ifdef TEST_OVER_THE_AIR_ENANBLED +#include "app_tota.h" +#endif +extern "C" { +#ifdef __IAG_BLE_INCLUDE__ +#include "besble.h" +#endif +#ifdef TX_RX_PCM_MASK +#include "hal_intersys.h" +#include "app_audio.h" +#include "app_bt_stream.h" +#endif +#include "bt_drv_interface.h" + +#ifdef __GATT_OVER_BR_EDR__ +#include "app_btgatt.h" +#endif + +#ifdef VOICE_DATAPATH +#include "app_voicepath.h" +#endif + +#ifdef __AI_VOICE__ +#include "app_ai_if.h" +#endif + +#ifdef GFPS_ENABLED +#include "app_fp_rfcomm.h" +#endif + +void BESHCI_Open(void); +void BESHCI_Poll(void); +void BESHCI_SCO_Data_Start(void); +void BESHCI_SCO_Data_Stop(void); +void BESHCI_LockBuffer(void); +void BESHCI_UNLockBuffer(void); +} +#include "besbt.h" + +#include "cqueue.h" +#include "app_bt.h" +#include "btapp.h" +#if defined(__BTMAP_ENABLE__) +#include "app_btmap_sms.h" +#endif + +#if defined(IBRT) +#include "app_tws_ibrt_cmd_handler.h" +#include "app_tws_ctrl_thread.h" +#include "app_ibrt_peripheral_manager.h" +#include "app_ibrt_if.h" +#endif + +#ifdef __AI_VOICE__ +#include "ai_thread.h" +#endif + +#if defined(IBRT) +rssi_t raw_rssi[2]; +#endif + +struct besbt_cfg_t besbt_cfg = { +#ifdef __BTIF_SNIFF__ + .sniff = true, +#else + .sniff = false, +#endif + + .force_use_cvsd = false, + +#ifdef __BT_ONE_BRING_TWO__ + .one_bring_two = true, +#else + .one_bring_two = false, +#endif +#ifdef __A2DP_AVDTP_CP__ + .avdtp_cp_enable = true, +#else + .avdtp_cp_enable = false, +#endif +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + .source_enable = true, +#else + .source_enable = false, +#endif +#ifdef A2DP_LHDC_V3 + .lhdc_v3 = true, +#else + .lhdc_v3 = false, +#endif +}; + +osMessageQDef(evm_queue, 128, uint32_t); +osMessageQId evm_queue_id; + +/* besbt thread */ +#ifndef BESBT_STACK_SIZE +#if defined(ENHANCED_STACK) +#ifdef __IAG_BLE_INCLUDE__ +#define BESBT_STACK_SIZE 6144 +#else +#define BESBT_STACK_SIZE (3326) +#endif +#else +#ifdef __IAG_BLE_INCLUDE__ +#define BESBT_STACK_SIZE 5120 +#else +#if defined(IBRT) +#define BESBT_STACK_SIZE (3328) +#else +#define BESBT_STACK_SIZE (2304) +#endif +#endif +#endif +#endif + +osThreadDef(BesbtThread, (osPriorityAboveNormal), 1, (BESBT_STACK_SIZE), "bes_bt_main"); + + +static BESBT_HOOK_HANDLER bt_hook_handler[BESBT_HOOK_USER_QTY] = {0}; + +int Besbt_hook_handler_set(enum BESBT_HOOK_USER_T user, BESBT_HOOK_HANDLER handler) +{ + bt_hook_handler[user]= handler; + return 0; +} + +static void Besbt_hook_proc(void) +{ + uint8_t i; + for (i=0; i= addr_size / 2) { + j = 0; + } + } + + j = addr_size / 2; + for (i = 0; i < ulen; i++) { + bt_addr[j++] ^= user[i]; + if (j >= addr_size) { + j = addr_size / 2; + } + } + + TRACE(0,"Modified debug BT addr is:"); + DUMP8("%02x ", bt_addr, BTIF_BD_ADDR_SIZE); +} + +#if !defined(ENHANCED_STACK) +static void __set_local_dev_name(void) +{ + dev_addr_name devinfo; + + devinfo.btd_addr = bt_get_local_address(); + devinfo.ble_addr = bt_get_ble_local_address(); + devinfo.localname = bt_get_local_name(); + devinfo.ble_name = bt_get_ble_local_name(); + +#ifndef FPGA + nvrec_dev_localname_addr_init(&devinfo); +#endif + bt_set_local_dev_name((const unsigned char*)devinfo.localname, strlen(devinfo.localname) + 1); +} +#endif + +static void add_randomness(void) +{ + uint32_t generatedSeed = hal_sys_timer_get(); + + //avoid bt address collision low probability + for (uint8_t index = 0; index < sizeof(bt_addr); index++) { + generatedSeed ^= (((uint32_t)(bt_addr[index])) << (hal_sys_timer_get()&0xF)); + } + srand(generatedSeed); +} + +static void __set_bt_sco_num(void) +{ + uint8_t sco_num; + +#ifdef CHIP_BEST1000 + if(hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2) +#endif + { + sco_num = 2; + } +#ifdef CHIP_BEST1000 + else + { + sco_num = 1; + } +#endif +#if defined(__BT_ONE_BRING_TWO__)//&&defined(HFP_NO_PRERMPT) + sco_num = 1; +#endif + bt_set_sco_number(sco_num); +} + +#if defined(ENHANCED_STACK) +void app_notify_stack_ready(uint8_t ready_flag); +static void stack_ready_callback(int status) +{ + dev_addr_name devinfo; + + devinfo.btd_addr = bt_get_local_address(); + devinfo.ble_addr = bt_get_ble_local_address(); + devinfo.localname = bt_get_local_name(); + devinfo.ble_name = bt_get_ble_local_name(); + +#ifndef FPGA + nvrec_dev_localname_addr_init(&devinfo); +#endif + bt_set_local_dev_name((const unsigned char*)devinfo.localname, strlen(devinfo.localname) + 1); + + bt_stack_config((const unsigned char*)devinfo.localname, strlen(devinfo.localname) + 1); + + app_notify_stack_ready(STACK_READY_BT); +} +#endif /* ENHANCED_STACK */ + +int besmain(void) +{ + enum APP_SYSFREQ_FREQ_T sysfreq; + +#if !defined(BLE_ONLY_ENABLED) +#ifdef A2DP_CP_ACCEL + sysfreq = APP_SYSFREQ_26M; +#else + sysfreq = APP_SYSFREQ_52M; +#endif +#else + sysfreq = APP_SYSFREQ_26M; +#endif + + BESHCI_Open(); +#if defined( TX_RX_PCM_MASK) + if(btdrv_is_pcm_mask_enable()==1) + hal_intersys_mic_open(HAL_INTERSYS_ID_1,store_encode_frame2buff); +#endif + __set_bt_sco_num(); + add_randomness(); + +#ifdef __IAG_BLE_INCLUDE__ + bes_ble_init(); +#endif + + btif_set_btstack_chip_config(bt_drv_get_btstack_chip_config()); + + /* bes stack init */ + bt_stack_initilize(); + +#if defined(ENHANCED_STACK) + bt_stack_register_ready_callback(stack_ready_callback); + btif_sdp_init(); +#endif + +#if defined(ENHANCED_STACK) + btif_cmgr_handler_init(); +#endif + + a2dp_init(); + btif_avrcp_init(&app_bt_device); + +#ifdef __AI_VOICE__ + app_ai_voice_init(); +#endif +#if defined(VOICE_DATAPATH) + app_voicepath_init(); +#endif +#ifdef GFPS_ENABLED + app_fp_rfcomm_init(); +#endif + + app_hfp_init(); +#if defined(__HSP_ENABLE_) + app_hsp_init(); +#endif +#if defined(__BTMAP_ENABLE__) + app_btmap_sms_init(); +#endif +#if defined(__GATT_OVER_BR_EDR__) + app_btgatt_init(); +#endif + + /* pair callback init */ + bt_pairing_init(pair_handler_func); + bt_authing_init(auth_handler_func); + + a2dp_hid_init(); + a2dp_codec_init(); + +#ifdef BTIF_HID_DEVICE + app_bt_hid_init(); +#endif + +#ifdef BTIF_DIP_DEVICE + app_dip_init(); +#endif + +#if defined(ENHANCED_STACK) + //register_hci_delete_con_send_complete_cmd_callback(HciSendCompletePacketCommandRightNow); + + /* bt local name */ + /* + nvrec_dev_localname_addr_init(&devinfo); + */ +#else + + register_hci_delete_con_send_complete_cmd_callback(HciSendCompletePacketCommandRightNow); + + __set_local_dev_name(); +#endif +#if defined(IBRT) + app_ibrt_set_cmdhandle(TWS_CMD_IBRT, app_ibrt_cmd_table_get); + app_ibrt_set_cmdhandle(TWS_CMD_CUSTOMER, app_ibrt_customif_cmd_table_get); +#if defined(IBRT_OTA) || defined(__GMA_OTA_TWS__) || defined(BISTO_ENABLED) + app_ibrt_set_cmdhandle(TWS_CMD_IBRT_OTA, app_ibrt_ota_tws_cmd_table_get); +#endif +#ifdef __INTERACTION__ + app_ibrt_set_cmdhandle(TWS_CMD_OTA, app_ibrt_ota_cmd_table_get); +#endif + tws_ctrl_thread_init(); + app_ibrt_peripheral_thread_init(); +#endif + +#if defined(APP_LINEIN_A2DP_SOURCE) + app_source_init(); +#endif + +#if defined(ENHANCED_STACK) + /* + __set_local_dev_name(); + bt_stack_config(); + */ +#else + bt_stack_config(); +#endif + //init bt key + bt_key_init(); +#ifdef TEST_OVER_THE_AIR_ENANBLED + app_tota_init(); +#endif + osapi_notify_evm(); + while(1) { + app_sysfreq_req(APP_SYSFREQ_USER_BT_MAIN, APP_SYSFREQ_32K); + osMessageGet(evm_queue_id, osWaitForever); + app_sysfreq_req(APP_SYSFREQ_USER_BT_MAIN, sysfreq); + // BESHCI_LockBuffer(); +#ifdef __LOCK_AUDIO_THREAD__ + bool stream_a2dp_sbc_isrun = app_bt_stream_isrun(APP_BT_STREAM_A2DP_SBC); + if (stream_a2dp_sbc_isrun) { + af_lock_thread(); + } +#endif + bt_process_stack_events(); + +#ifdef __IAG_BLE_INCLUDE__ + bes_ble_schedule(); +#endif + + Besbt_hook_proc(); + +#ifdef __LOCK_AUDIO_THREAD__ + if (stream_a2dp_sbc_isrun) { + af_unlock_thread(); + } +#endif + // BESHCI_UNLockBuffer(); + BESHCI_Poll(); + +#if defined(IBRT) + app_ibrt_data_send_handler(); + app_ibrt_data_receive_handler(); + app_ibrt_ui_controller_dbg_state_checker(); + app_ibrt_ui_stop_ibrt_condition_checker(); +#endif + app_check_pending_stop_sniff_op(); + + } + + return 0; +} + +void BesbtThread(void const *argument) +{ + besmain(); +} +osThreadId besbt_tid; +void BesbtInit(void) +{ + + evm_queue_id = osMessageCreate(osMessageQ(evm_queue), NULL); + /* bt */ + besbt_tid = osThreadCreate(osThread(BesbtThread), NULL); + TRACE(1,"BesbtThread: %p\n", besbt_tid); +} diff --git a/services/bt_app/btapp.h b/services/bt_app/btapp.h new file mode 100644 index 0000000..cdadd7e --- /dev/null +++ b/services/bt_app/btapp.h @@ -0,0 +1,423 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BTAPP_H__ +#define __BTAPP_H__ + +#include "app_key.h" +#include "hfp_api.h" +#include "a2dp_api.h" +#include "app_a2dp_codecs.h" +#ifdef BTIF_HID_DEVICE +#include "app_bt_hid.h" +#endif +#if defined(__BTMAP_ENABLE__) +#include "map_api.h" +#endif + +//#define __EARPHONE_STAY_BOTH_SCAN__ + +/* bt config */ +#ifdef _SCO_BTPCM_CHANNEL_ +#define SYNC_CONFIG_PATH (0<<8|1<<4|1<<0) /* all links use hci */ +#else +#define SYNC_CONFIG_PATH (0<<8|0<<4|0<<0) /* all links use hci */ +#endif +#define SYNC_CONFIG_MAX_BUFFER (0) /* (e)sco use Packet size */ +#ifdef CVSD_BYPASS +#define SYNC_CONFIG_CVSD_BYPASS (1) /* use pcm over hci */ +#else +#define SYNC_CONFIG_CVSD_BYPASS (0) /* use pcm over hci */ +#endif +#define INQ_EXT_RSP_LEN 240 +///a2dp app include +/* a2dp */ +/* Default SBC codec configuration */ +/* data type for the SBC Codec Information Element*/ +/***************************************************************************** +** Constants +*****************************************************************************/ +/* the length of the SBC Media Payload header. */ +#define A2D_SBC_MPL_HDR_LEN 1 + +/* the LOSC of SBC media codec capabilitiy */ +#define A2D_SBC_INFO_LEN 6 + +/* for Codec Specific Information Element */ +#if defined(A2DP_SCALABLE_ON) +#define A2D_SCALABLE_IE_SAMP_FREQ_MSK 0xFF /* b7-b0 sampling frequency */ +#endif + +#if defined(A2DP_LHDC_ON) +#define A2D_LHDC__IE_SAMP_FREQ_MSK 0xFF /* b7-b0 sampling frequency */ +#endif + + +#define A2D_STREAM_SAMP_FREQ_MSK 0xFF /* b7-b4 sampling frequency */ + +#define A2D_SBC_IE_SAMP_FREQ_MSK 0xF0 /* b7-b4 sampling frequency */ + +#define A2D_SBC_IE_SAMP_FREQ_16 0x80 /* b7:16 kHz */ +#define A2D_SBC_IE_SAMP_FREQ_32 0x40 /* b6:32 kHz */ +#define A2D_SBC_IE_SAMP_FREQ_44 0x20 /* b5:44.1kHz */ +#define A2D_SBC_IE_SAMP_FREQ_48 0x10 /* b4:48 kHz */ + +#ifdef A2DP_SCALABLE_ON +#define A2D_SBC_IE_SAMP_FREQ_96 0x08 /* b4:96 kHz */ +#endif + +#ifdef A2DP_LHDC_ON +#ifndef A2D_SBC_IE_SAMP_FREQ_96 +#define A2D_SBC_IE_SAMP_FREQ_96 0x08 /* b4:96 kHz */ +#endif +#endif + +#ifdef A2DP_LDAC_ON +#ifndef A2DP_LDAC_OCTET_NUMBER +#define A2DP_LDAC_OCTET_NUMBER (8) +#endif + +#ifndef A2D_SBC_IE_SAMP_FREQ_96 +#define A2D_SBC_IE_SAMP_FREQ_96 0x08 /* b4:96 kHz */ +#endif +#ifndef A2D_SBC_IE_SAMP_FREQ_88 +#define A2D_SBC_IE_SAMP_FREQ_88 0x04 /* b4:88.2 kHz */ +#endif +#endif + +#define A2D_SBC_IE_BIT_NUM_16 0x16 +#define A2D_SBC_IE_BIT_NUM_24 0x24 + +#define A2D_SBC_IE_CH_MD_MSK 0x0F /* b3-b0 channel mode */ +#define A2D_SBC_IE_CH_MD_MONO 0x08 /* b3: mono */ +#define A2D_SBC_IE_CH_MD_DUAL 0x04 /* b2: dual */ +#define A2D_SBC_IE_CH_MD_STEREO 0x02 /* b1: stereo */ +#define A2D_SBC_IE_CH_MD_JOINT 0x01 /* b0: joint stereo */ + +#define A2D_SBC_IE_BLOCKS_MSK 0xF0 /* b7-b4 number of blocks */ +#define A2D_SBC_IE_BLOCKS_4 0x80 /* 4 blocks */ +#define A2D_SBC_IE_BLOCKS_8 0x40 /* 8 blocks */ +#define A2D_SBC_IE_BLOCKS_12 0x20 /* 12blocks */ +#define A2D_SBC_IE_BLOCKS_16 0x10 /* 16blocks */ + +#define A2D_SBC_IE_SUBBAND_MSK 0x0C /* b3-b2 number of subbands */ +#define A2D_SBC_IE_SUBBAND_4 0x08 /* b3: 4 */ +#define A2D_SBC_IE_SUBBAND_8 0x04 /* b2: 8 */ + +#define A2D_SBC_IE_ALLOC_MD_MSK 0x03 /* b1-b0 allocation mode */ +#define A2D_SBC_IE_ALLOC_MD_S 0x02 /* b1: SNR */ +#define A2D_SBC_IE_ALLOC_MD_L 0x01 /* b0: loundess */ + +#define A2D_SBC_IE_MIN_BITPOOL 2 +#define A2D_SBC_IE_MAX_BITPOOL 250 + +#ifdef __cplusplus +extern "C" { +#endif + +//extern A2dpStream a2dp_stream; +//extern btif_avdtp_codec_t a2dp_avdtpcodec; +extern const unsigned char a2dp_codec_elements[]; +//extern enum AUD_SAMPRATE_T a2dp_sample_rate; + +//#define AVRCP_TRACK_CHANGED + +#define AVRCP_KEY_NULL 0 +#define AVRCP_KEY_STOP 1 +#define AVRCP_KEY_PLAY 2 +#define AVRCP_KEY_PAUSE 3 +#define AVRCP_KEY_FORWARD 4 +#define AVRCP_KEY_BACKWARD 5 +#define AVRCP_KEY_VOLUME_UP 6 +#define AVRCP_KEY_VOLUME_DOWN 7 + +#define HFP_KEY_ANSWER_CALL 8 +#define HFP_KEY_HANGUP_CALL 9 +#define HFP_KEY_REDIAL_LAST_CALL 10 +#define HFP_KEY_CHANGE_TO_PHONE 11 +#define HFP_KEY_ADD_TO_EARPHONE 12 +#define HFP_KEY_MUTE 13 +#define HFP_KEY_CLEAR_MUTE 14 +//3way calls oper +#define HFP_KEY_THREEWAY_HOLD_AND_ANSWER 15 +#define HFP_KEY_THREEWAY_HANGUP_AND_ANSWER 16 +#define HFP_KEY_THREEWAY_HOLD_REL_INCOMING 17 +#define HFP_KEY_THREEWAY_HOLD_ADD_HELD_CALL 18 + +#ifdef __BT_ONE_BRING_TWO__ +#define HFP_KEY_DUAL_HF_HANGUP_ANOTHER 19 +#define HFP_KEY_DUAL_HF_HANGUP_CURR_ANSWER_ANOTHER 20 +#define HFP_KEY_DUAL_HF_HOLD_CURR_ANSWER_ANOTHER 21 +#define HFP_KEY_DUAL_HF_CHANGETOPHONE_ANSWER_ANOTHER 22 +#define HFP_KEY_DUAL_HF_CHANGETOPHONE_ANOTHER_ADDTOEARPHONE 23 +#define HFP_KEY_DUAL_HF_HANGUP_ANOTHER_ADDTOEARPHONE 24 +#endif + +//hsp +#define HSP_KEY_CKPD_CONTROL 21 +#define HSP_KEY_ADD_TO_EARPHONE 22 +#define HSP_KEY_CHANGE_TO_PHONE 23 + +typedef enum +{ + HFCALL_MACHINE_CURRENT_IDLE = 0, //0 + HFCALL_MACHINE_CURRENT_INCOMMING, //1 + HFCALL_MACHINE_CURRENT_OUTGOING, //2 + HFCALL_MACHINE_CURRENT_CALLING, //3 + HFCALL_MACHINE_CURRENT_3WAY_INCOMMING, //4 + HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING, //5 + HFCALL_MACHINE_CURRENT_IDLE_ANOTHER_IDLE, //6 + HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_IDLE, //7 + HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_IDLE, //8 + HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_IDLE, //9 + HFCALL_MACHINE_CURRENT_3WAY_INCOMMING_ANOTHER_IDLE, //10 + HFCALL_MACHINE_CURRENT_3WAY_HOLD_CALLING_ANOTHER_IDLE, //11 + HFCALL_MACHINE_CURRENT_INCOMMING_ANOTHER_INCOMMING, //12 + HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_INCOMMING, //13 + HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_CHANGETOPHONE, //14 + HFCALL_MACHINE_CURRENT_OUTGOING_ANOTHER_INCOMMING, //15 + HFCALL_MACHINE_CURRENT_CALLING_ANOTHER_HOLD, //16 + HFCALL_MACHINE_NUM +} HFCALL_MACHINE_ENUM; + +typedef enum +{ + HFCALL_NEXT_STA_NULL = 0, //0 + HFCALL_NEXT_STA_ANOTHER_ANSWER, //1 + HFCALL_NEXT_STA_ANOTHER_ADDTOEARPHONE, //2 + HFCALL_NEXT_STA_NUM +} HFCALL_NEXT_STA_ENUM; + +#if defined (__HSP_ENABLE__) +void hsp_callback(HsChannel *Chan, HsCallbackParms *Info); +#endif + +#define APP_REPORT_SPEAKER_VOL_CMD 0x01 +#define APP_CPKD_CMD 0x02 +#define SPP_MAX_TX_PACKET_NUM 5 +#define AVRCP_PDU_PARAM_MAX_LEN 40 + + +enum BT_DEVICE_ID_T{ + BT_DEVICE_ID_1 = 0, +#ifdef __BT_ONE_BRING_TWO__ + BT_DEVICE_ID_2, +#endif + BT_DEVICE_NUM +}; + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +enum BT_DEVICE_SRC_SNK_T{ + BT_DEVICE_SNK=0, + BT_DEVICE_SRC +}; +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +#define APP_BD_ADDR_SIZE 6 +typedef struct APP_BT_BD_ADDR { + U8 addr[APP_BD_ADDR_SIZE]; +} APP_BT_BD_ADDR; +#endif +#endif + +struct BT_DEVICE_T{ + btif_a2dp_stream_t* a2dp_stream[BT_DEVICE_NUM]; + uint8_t avdtp_cp[BT_DEVICE_NUM]; + btif_a2dp_stream_t* a2dp_lhdc_stream[BT_DEVICE_NUM]; + uint8_t a2dp_lhdc_llc[BT_DEVICE_NUM]; + + btif_a2dp_stream_t* a2dp_ldac_stream[BT_DEVICE_NUM]; + int channel_mode; + + btif_a2dp_stream_t* a2dp_aac_stream[BT_DEVICE_NUM]; + + btif_a2dp_stream_t* a2dp_scalable_stream[BT_DEVICE_NUM]; + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + uint8_t src_or_snk;//src or snk fkag + uint8_t input_onoff; + APP_BT_BD_ADDR inquried_snk_bdAddr; /* Device Address */ + //BT_BD_ADDR rmt_bdAddr; /* Device Address */ +#endif + + a2dp_stream_t * a2dp_connected_stream[BT_DEVICE_NUM]; + a2dp_stream_t * a2dp_outconfiged_stream[BT_DEVICE_NUM]; + btif_remote_device_t * a2dp_outconfiged_rem[BT_DEVICE_NUM]; + enum BT_DEVICE_ID_T curr_a2dp_stream_id; + uint16_t current_a2dp_conhdl; + + + uint8_t a2dp_state[BT_DEVICE_NUM]; + uint8_t a2dp_streamming[BT_DEVICE_NUM]; + uint8_t a2dp_play_pause_flag; + uint8_t avrcpPendingKey; + uint8_t latestPausedDevId; + uint8_t avrcpPressedKey; + uint8_t avrcpVolumeSync; + btif_avdtp_codec_type_t codec_type[BT_DEVICE_NUM]; + + uint8_t sample_rate[BT_DEVICE_NUM]; + uint8_t sample_bit[BT_DEVICE_NUM]; + uint8_t avrcp_state[BT_DEVICE_NUM]; + btif_avrcp_channel_t* avrcp_channel[BT_DEVICE_NUM]; + + hf_chan_handle_t hf_channel[BT_DEVICE_NUM]; +#if defined (__HSP_ENABLE__) + HsChannel hs_channel[BT_DEVICE_NUM]; +#endif +#if defined (__BTMAP_ENABLE__) + btif_map_session_handle_t map_session_handle[BT_DEVICE_NUM]; +#endif + enum BT_DEVICE_ID_T curr_hf_channel_id; + btif_hf_call_setup_t hfchan_callSetup[BT_DEVICE_NUM]; + btif_hf_call_active_t hfchan_call[BT_DEVICE_NUM]; + btif_audio_state_t hf_audio_state[BT_DEVICE_NUM]; + btif_hf_call_held_state hf_callheld[BT_DEVICE_NUM]; + uint32_t hf_callsetup_time[BT_DEVICE_NUM]; +#if defined (__HSP_ENABLE__) + enum BT_DEVICE_ID_T curr_hs_channel_id; + HsCallActiveState hschan_call[BT_DEVICE_NUM]; + HsAudioConnectState hs_audio_state[BT_DEVICE_NUM]; +#endif +#ifdef BTIF_AVRCP_ADVANCED_CONTROLLER + uint32_t avrcp_advancedPdu_size; + void *avrcp_cmd1[BT_DEVICE_NUM]; + void *avrcp_cmd2[BT_DEVICE_NUM]; + void *avrcp_get_capabilities_rsp[BT_DEVICE_NUM]; + void *avrcp_control_rsp[BT_DEVICE_NUM]; + void *avrcp_notify_rsp[BT_DEVICE_NUM]; + uint8_t volume_report[BT_DEVICE_NUM]; + void *avrcp_volume_cmd[BT_DEVICE_NUM]; + + void *avrcp_custom_cmd[BT_DEVICE_NUM]; +#ifdef AVRCP_TRACK_CHANGED + uint8_t track_changed[BT_DEVICE_NUM]; +#endif +#endif + uint8_t hf_conn_flag[BT_DEVICE_NUM]; + uint8_t hf_voice_en[BT_DEVICE_NUM]; + uint8_t hf_endcall_dis[BT_DEVICE_NUM]; + uint8_t hf_mute_flag; + uint8_t phone_earphone_mark; +#if defined (__HSP_ENABLE__) + uint8_t hs_conn_flag[BT_DEVICE_NUM]; + uint8_t hs_voice_en[BT_DEVICE_NUM]; + uint8_t hs_mute_flag; +#endif +#ifdef BTIF_HID_DEVICE + hid_channel_t hid_channel[BT_DEVICE_NUM]; +#endif + + uint8_t callSetupBitRec; +}; + + + +struct BT_DEVICE_ID_DIFF{ + enum BT_DEVICE_ID_T id; +#ifdef __BT_ONE_BRING_TWO__ + enum BT_DEVICE_ID_T id_other; +#endif +}; + +/////app key handle include +void a2dp_handleKey(uint8_t a2dp_key); +void hfp_handle_key(uint8_t hfp_key); +void hsp_handle_key(uint8_t hsp_key); +void btapp_a2dp_report_speak_gain(void); + +#ifdef __POWERKEY_CTRL_ONOFF_ONLY__ +#define BTAPP_FUNC_KEY APP_KEY_CODE_FN1 +#define BTAPP_VOLUME_UP_KEY APP_KEY_CODE_FN2 +#define BTAPP_VOLUME_DOWN_KEY APP_KEY_CODE_FN3 +#ifdef SUPPORT_SIRI +#define BTAPP_RELEASE_KEY APP_KEY_CODE_NONE +#endif +#else +#define BTAPP_FUNC_KEY APP_KEY_CODE_PWR +#define BTAPP_VOLUME_UP_KEY APP_KEY_CODE_FN1 +#define BTAPP_VOLUME_DOWN_KEY APP_KEY_CODE_FN2 +#ifdef SUPPORT_SIRI +#define BTAPP_RELEASE_KEY APP_KEY_CODE_NONE +#endif +#endif +void bt_key_init(void); +void bt_key_send(APP_KEY_STATUS *status); +void bt_key_handle(void); + +void a2dp_callback(a2dp_stream_t *Stream, const a2dp_callback_parms_t *Info); +void avrcp_init(void); +//void avrcp_callback(AvrcpChannel *chnl, const AvrcpCallbackParms *Parms); + +void avrcp_callback_CT(btif_avrcp_chnl_handle_t chnl, const avrcp_callback_parms_t *Parms); +void avrcp_callback_TG(btif_avrcp_chnl_handle_t chnl, const avrcp_callback_parms_t *Parms); +int a2dp_volume_get(enum BT_DEVICE_ID_T id); +int a2dp_volume_get_tws(void); +bool avrcp_get_tg_play_status_play_pause(void); +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) || defined(__APP_A2DP_SOURCE__) +#ifdef __TWS__ +//void avrcp_set_slave_volume(uint8_t transid,int8_t volume); +#endif + + +//#define AVRCP_TRACK_CHANGED +void a2dp_set_config_codec(btif_avdtp_codec_t *config_codec,const btif_a2dp_callback_parms_t *Info); + +void a2dp_callback_source(a2dp_stream_t *Stream, const a2dp_callback_parms_t *Info); +void app_a2dp_source_init(void); +void app_source_init(void); + +void app_a2dp_source_find_sink(void); +void avrcp_source_callback_TG(btif_avrcp_chnl_handle_t chnl, const avrcp_callback_parms_t *Parms); +void app_a2dp_start_stream(void); +void app_a2dp_suspend_stream(void); +#endif + +/** + * Convert BES BD_ADDR to virtual + * BES Device ID + */ +bool a2dp_id_from_bdaddr(bt_bdaddr_t *bd_addr, uint8_t *id); + +void bt_key_handle_func_click(); +void bt_key_handle_func_doubleclick(); +void bt_key_handle_func_longpress(); + + +void bt_sbc_player_set_codec_type(uint8_t type); +uint8_t bt_sbc_player_get_codec_type(void); +uint8_t bt_sbc_player_get_sample_bit(void); +#if defined(A2DP_LDAC_ON) +int bt_ldac_player_get_channelmode(void); +int bt_get_ladc_sample_rate(void); +#endif + +uint8_t app_bt_avrcp_get_notify_trans_id(void); +void app_bt_avrcp_set_notify_trans_id(uint8_t trans_id); +uint8_t app_bt_avrcp_get_ctl_trans_id(void); +void app_bt_avrcp_set_ctl_trans_id(uint8_t trans_id); + + +#if defined(IBRT) +#if defined(ENHANCED_STACK) +uint32_t app_avrcp_save_ctxs(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len); +uint32_t app_avrcp_restore_ctxs(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len); +#endif /* ENHANCED_STACK */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BTAPP_H__ */ diff --git a/services/bt_app/res_audio_data.h b/services/bt_app/res_audio_data.h new file mode 100644 index 0000000..2804a4c --- /dev/null +++ b/services/bt_app/res_audio_data.h @@ -0,0 +1,154 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifdef MEDIA_PLAYER_SUPPORT + +const uint8_t EN_POWER_ON [] = { +#include "res/en/SOUND_POWER_ON.txt" +}; + +const uint8_t EN_POWER_OFF [] = { +#include "res/en/SOUND_POWER_OFF.txt" +}; + +const uint8_t EN_SOUND_ZERO[] = { +#include "res/en/SOUND_ZERO.txt" +}; + +const uint8_t EN_SOUND_ONE[] = { +#include "res/en/SOUND_ONE.txt" +}; + +const uint8_t EN_SOUND_TWO[] = { +#include "res/en/SOUND_TWO.txt" +}; + +const uint8_t EN_SOUND_THREE[] = { +#include "res/en/SOUND_THREE.txt" +}; + +const uint8_t EN_SOUND_FOUR[] = { +#include "res/en/SOUND_FOUR.txt" +}; + +const uint8_t EN_SOUND_FIVE[] = { +#include "res/en/SOUND_FIVE.txt" +}; + +const uint8_t EN_SOUND_SIX[] = { +#include "res/en/SOUND_SIX.txt" +}; + +const uint8_t EN_SOUND_SEVEN [] = { +#include "res/en/SOUND_SEVEN.txt" +}; + +const uint8_t EN_SOUND_EIGHT [] = { +#include "res/en/SOUND_EIGHT.txt" +}; + +const uint8_t EN_SOUND_NINE [] = { +#include "res/en/SOUND_NINE.txt" +}; + +const uint8_t EN_BT_PAIR_ENABLE[] = { +#include "res/en/SOUND_PAIR_ENABLE.txt" +}; + +const uint8_t EN_BT_PAIRING[] = { +#include "res/en/SOUND_PAIRING.txt" +}; + +const uint8_t EN_BT_PAIRING_FAIL[] = { +#include "res/en/SOUND_PAIRING_FAIL.txt" +}; + +const uint8_t EN_BT_PAIRING_SUCCESS[] = { +#include "res/en/SOUND_PAIRING_SUCCESS.txt" +}; + +const uint8_t EN_BT_REFUSE[] = { +#include "res/en/SOUND_REFUSE.txt" +}; + +const uint8_t EN_BT_OVER[] = { +#include "res/en/SOUND_OVER.txt" +}; + +const uint8_t EN_BT_ANSWER[] = { +#include "res/en/SOUND_ANSWER.txt" +}; + +const uint8_t EN_BT_HUNG_UP[] = { +#include "res/en/SOUND_HUNG_UP.txt" +}; + +const uint8_t EN_BT_CONNECTED [] = { +#include "res/en/SOUND_CONNECTED.txt" +}; + +const uint8_t EN_BT_DIS_CONNECT [] = { +#include "res/en/SOUND_DIS_CONNECT.txt" +}; + +const uint8_t EN_BT_INCOMING_CALL [] = { +#include "res/en/SOUND_INCOMING_CALL.txt" +}; + +const uint8_t EN_CHARGE_PLEASE[] = { +#include "res/en/SOUND_CHARGE_PLEASE.txt" +}; + +const uint8_t EN_CHARGE_FINISH[] = { +#include "res/en/SOUND_CHARGE_FINISH.txt" +}; + +const uint8_t EN_LANGUAGE_SWITCH[] = { +#include "res/en/SOUND_LANGUAGE_SWITCH.txt" +}; + +const uint8_t EN_BT_WARNING[] = { +#include "res/en/SOUND_WARNING.txt" +}; + +const uint8_t EN_BT_ALEXA_START[] = { +#include "res/en/SOUND_ALEXA_START.txt" +}; + +const uint8_t EN_BT_ALEXA_STOP[] = { +#include "res/en/SOUND_ALEXA_STOP.txt" +}; + +const uint8_t EN_BT_GSOUND_MIC_OPEN[] = { +#include "res/en/SOUND_GSOUND_MIC_OPEN.txt" +}; + +const uint8_t EN_BT_GSOUND_MIC_CLOSE[] = { +#include "res/en/SOUND_GSOUND_MIC_CLOSE.txt" +}; + +const uint8_t EN_BT_DUDU[] = { +#include "res/en/dudu.txt" +}; +const uint8_t EN_BT_GSOUND_NC[] = { +#include "res/en/SOUND_GSOUND_NC.txt" +}; +#ifdef __INTERACTION__ +const uint8_t EN_BT_FINDME[] = { +#include "res/en/SOUND_FINDME.txt" +}; +#endif +#endif diff --git a/services/bt_app/res_audio_data_cn.h b/services/bt_app/res_audio_data_cn.h new file mode 100644 index 0000000..941879c --- /dev/null +++ b/services/bt_app/res_audio_data_cn.h @@ -0,0 +1,153 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __RES_AUDIO_DATA_CN_H +#define __RES_AUDIO_DATA_CN_H + +const uint8_t CN_POWER_ON [] = { +#include "res/cn/SOUND_POWER_ON.txt" +}; + +const uint8_t CN_POWER_OFF [] = { +#include "res/cn/SOUND_POWER_OFF.txt" +}; + +const uint8_t CN_SOUND_ZERO[] = { +#include "res/cn/SOUND_ZERO.txt" +}; + +const uint8_t CN_SOUND_ONE[] = { +#include "res/cn/SOUND_ONE.txt" +}; + +const uint8_t CN_SOUND_TWO[] = { +#include "res/cn/SOUND_TWO.txt" +}; + +const uint8_t CN_SOUND_THREE[] = { +#include "res/cn/SOUND_THREE.txt" +}; + +const uint8_t CN_SOUND_FOUR[] = { +#include "res/cn/SOUND_FOUR.txt" +}; + +const uint8_t CN_SOUND_FIVE[] = { +#include "res/cn/SOUND_FIVE.txt" +}; + +const uint8_t CN_SOUND_SIX[] = { +#include "res/cn/SOUND_SIX.txt" +}; + +const uint8_t CN_SOUND_SEVEN[] = { +#include "res/cn/SOUND_SEVEN.txt" +}; + +const uint8_t CN_SOUND_EIGHT[] = { +#include "res/cn/SOUND_EIGHT.txt" +}; + +const uint8_t CN_SOUND_NINE[] = { +#include "res/cn/SOUND_NINE.txt" +}; + +const uint8_t CN_BT_PAIR_ENABLE[] = { +#include "res/cn/SOUND_PAIR_ENABLE.txt" +}; + +const uint8_t CN_BT_PAIRING [] = { +#include "res/cn/SOUND_PAIRING.txt" +}; + +const uint8_t CN_BT_PAIRING_FAIL[] = { +#include "res/cn/SOUND_PAIRING_FAIL.txt" +}; + +const uint8_t CN_BT_PAIRING_SUCCESS[] = { +#include "res/cn/SOUND_PAIRING_SUCCESS.txt" +}; + +const uint8_t CN_BT_REFUSE[] = { +#include "res/cn/SOUND_REFUSE.txt" +}; + +const uint8_t CN_BT_OVER[] = { +#include "res/cn/SOUND_OVER.txt" +}; + +const uint8_t CN_BT_ANSWER[] = { +#include "res/cn/SOUND_ANSWER.txt" +}; + + +const uint8_t CN_BT_HUNG_UP[] = { +#include "res/cn/SOUND_HUNG_UP.txt" +}; + +const uint8_t CN_BT_INCOMING_CALL [] = { +#include "res/cn/SOUND_INCOMING_CALL.txt" +}; + +const uint8_t CN_BT_CONNECTED [] = { +#include "res/cn/SOUND_CONNECTED.txt" +}; + +const uint8_t CN_BT_DIS_CONNECT [] = { +#include "res/cn/SOUND_DIS_CONNECT.txt" +}; + +const uint8_t CN_CHARGE_PLEASE[] = { +#include "res/cn/SOUND_CHARGE_PLEASE.txt" +}; + +const uint8_t CN_CHARGE_FINISH[] = { +#include "res/cn/SOUND_CHARGE_FINISH.txt" +}; + +const uint8_t CN_LANGUAGE_SWITCH[] = { +#include "res/cn/SOUND_LANGUAGE_SWITCH.txt" +}; + +const uint8_t CN_BT_WARNING[] = { +#include "res/cn/SOUND_WARNING.txt" +}; + +const uint8_t CN_BT_ALEXA_START[] = { + +}; + +const uint8_t CN_BT_ALEXA_STOP[] = { + +}; + +const uint8_t CN_BT_GSOUND_MIC_OPEN[] = { + +}; + +const uint8_t CN_BT_GSOUND_MIC_CLOSE[] = { + +}; + +const uint8_t CN_BT_GSOUND_NC[] = { + +}; +#ifdef __INTERACTION__ +const uint8_t CN_BT_FINDME[] = { +#include "res/cn/SOUND_FINDME.txt" +}; +#endif +#endif + diff --git a/services/bt_app/res_audio_ring.h b/services/bt_app/res_audio_ring.h new file mode 100644 index 0000000..cb7dc0d --- /dev/null +++ b/services/bt_app/res_audio_ring.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +const int16_t RES_AUD_RING_SAMPRATE_8000 [] = { +#include "res/ring/SOUND_RING_8000.txt" +}; +#ifdef __BT_WARNING_TONE_MERGE_INTO_STREAM_SBC__ + +const int16_t RES_AUD_RING_SAMPRATE_16000 [] = { +#include "res/ring/SOUND_RING_16000.txt" +}; +const int16_t RES_AUD_RING_SAMPRATE_44100[] = { +#include "res/ring/SOUND_RING_44100.txt" +}; + +const int16_t RES_AUD_RING_SAMPRATE_48000 [] = { +#include "res/ring/SOUND_RING_48000.txt" +}; +#endif diff --git a/services/bt_if_enhanced/Makefile b/services/bt_if_enhanced/Makefile new file mode 100644 index 0000000..e976daa --- /dev/null +++ b/services/bt_if_enhanced/Makefile @@ -0,0 +1,130 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +src_obj := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)a2dp/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)a2dp/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)avrcp/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)avrcp/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)conmgr/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)conmgr/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hci/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hci/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)l2cap/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)l2cap/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)me/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)me/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)sdp/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)sdp/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)spp/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)spp/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hfp/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hfp/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)os/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)os/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)rfcomm/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)rfcomm/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)sync/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)sync/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)besaud/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)besaud/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)dip/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)dip/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)map/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)map/*.cpp)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hid/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hid/*.cpp)) + +ifeq ($(GATT_OVER_BR_EDR),1) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)btgatt/*.c)) +src_obj += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)btgatt/*.cpp)) +endif + +obj_s := $(filter %.s, $(src_obj)) +obj_c := $(filter %.c, $(src_obj)) +obj_cpp := $(filter %.cpp, $(src_obj)) + +ifeq ($(IBRT), 1) +BTAPI_LIB_NAME := ibrt_libbt_api +else +BTAPI_LIB_NAME := $(CHIP)_libbt_api +endif + +ifeq ($(HFP_1_6_ENABLE), 1) +BTAPI_LIB_NAME := $(BTAPI_LIB_NAME)_sbc_enc +endif + +ifeq ($(SBC_FUNC_IN_ROM), 1) +BTAPI_LIB_NAME := $(BTAPI_LIB_NAME)_sbc_in_rom +endif + +ifeq ($(BT_RF_PREFER), 2M) +BTAPI_LIB_NAME := $(BTAPI_LIB_NAME)_2m +endif + +ifeq ($(BT_RF_PREFER), 3M) +BTAPI_LIB_NAME := $(BTAPI_LIB_NAME)_3m +endif + +ifeq ($(BT_ONE_BRING_TWO), 1) +BTAPI_LIB_NAME := $(BTAPI_LIB_NAME)_1b2 +endif + +ifeq ($(BLE), 1) +BTAPI_LIB_NAME := $(BTAPI_LIB_NAME)_ble +endif + +ifeq ($(KERNEL),RTX) +BTAPI_LIB_NAME := $(BTAPI_LIB_NAME)_RTX +endif +ifeq ($(KERNEL),RTX5) +BTAPI_LIB_NAME := $(BTAPI_LIB_NAME)_RTX5 +endif + +$(BTAPI_LIB_NAME)-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +obj-y += $(BTAPI_LIB_NAME).a + +ccflags-y += \ + $(BT_IF_INCLUDES) \ + -Iservices/bt_if_enhanced/conmgr \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/app_ai/inc \ + -Iservices/audio_process \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iservices/ble_app \ + -Iservices/ble_stack/common/api/ \ + -Iservices/bt_app \ + -Iservices/resources/ \ + -Iservices/osif \ + -Iservices/auto_test/ \ + -Iapps/audioplayers \ + -Iapps/main/ \ + -Iapps/key/ \ + -Iplatform/drivers/ana/ \ + -Iplatform/drivers/bt/ \ + -Iutils/intersyshci \ + -Iservices/ibrt/inc \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/bt_app/a2dp_codecs/include + +ifeq ($(GATT_OVER_BR_EDR),1) +ccflags-y += \ + -Iservices/ble_stack/hl/src/l2c/l2cm \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/hl/inc \ + -Iservices/ble_stack/ke/api +endif + +CFLAGS_bt_if.o += -DBESLIB_INFO=$(BESLIB_INFO) + +ifeq ($(ANC_APP),1) +CFLAGS_besaud_api.o += -DANC_APP +endif + diff --git a/services/bt_if_enhanced/inc/a2dp_api.h b/services/bt_if_enhanced/inc/a2dp_api.h new file mode 100644 index 0000000..47cf7c4 --- /dev/null +++ b/services/bt_if_enhanced/inc/a2dp_api.h @@ -0,0 +1,634 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _A2DP_API_H +#define _A2DP_API_H +#include "bluetooth.h" +#include "avrcp_api.h" + +#include "avdtp_api.h" +#include "conmgr_api.h" +#include "codec_sbc.h" + +typedef enum{ + BTIF_DEVICE_ID_1 = 0, +#ifdef __BT_ONE_BRING_TWO__ + BTIF_DEVICE_ID_2, +#endif + BTIF_DEVICE_NUM +}btif_dev_it_e; + +typedef void a2dp_stream_t; +typedef void a2dp_callback_parms_t; + +typedef uint8_t btif_a2dp_event_t; + + +#define A2DP_AAC_OCTET_NUMBER (6) +#define A2DP_AAC_OCTET0_MPEG2_AAC_LC 0x80 +#define A2DP_AAC_OCTET1_SAMPLING_FREQUENCY_44100 0x01 +#define A2DP_AAC_OCTET2_CHANNELS_1 0x08 +#define A2DP_AAC_OCTET2_CHANNELS_2 0x04 +#define A2DP_AAC_OCTET2_SAMPLING_FREQUENCY_48000 0x80 +#define A2DP_AAC_OCTET3_VBR_SUPPORTED 0x80 +/** Accept or reject by calling btif_a2dp_open_stream_rsp(). + */ +#define BTIF_A2DP_EVENT_STREAM_OPEN_IND 1 + +/** This event is the response to a call from btif_a2dp_open_stream() or + * btif_a2dp_open_stream_rsp(). + */ +#define BTIF_A2DP_EVENT_STREAM_OPEN 2 + +/** This event is received during the establishment of an + * outgoing stream (btif_a2dp_open_stream()) to indicate the capabilities of the + * remote device. This event may also be received after calling + * btif_a2dp_get_stream_capabilities(). + */ +#define BTIF_A2DP_EVENT_CODEC_INFO 3 + +/** This event is received during the establishment of an + * outgoing stream (btif_a2dp_open_stream()) to indicated the capabilities of the + * remote device. This event may also be received after calling + * btif_a2dp_get_stream_capabilities(). + * + */ +#define BTIF_A2DP_EVENT_CP_INFO 4 + +/** If this event is received, then the remote device + * supports the Delay Reporting feature. + */ +#define BTIF_A2DP_EVENT_DELAY_REPORTING_INFO 5 + +/** This event is received when a stream is opening and + * all matching capabilities have been found. The application must call + * btif_a2dp_set_stream_config() to configure the stream. If successful, the + * stream will be opened. btif_a2dp_close_stream() can also be called to close + * the stream. This event is only received on outgoing connections. + */ +#define BTIF_A2DP_EVENT_GET_CONFIG_IND 6 + +/** This event is received after calling btif_a2dp_get_stream_capabilities(). This + * event is received after all the capabilities of the remote device have + * been indicated (see BTIF_A2DP_EVENT_CODEC_INFO and BTIF_A2DP_EVENT_CP_INFO). + */ +#define BTIF_A2DP_EVENT_GET_CAP_CNF 7 + +/** This event is received when an open stream has been + * closed. This can happen as a result of a call to btif_a2dp_close_stream(), if + * the stream has been closed by the remote device, if a link loss has been + * detected, or if the remote device rejects a request to open the stream. + * + */ +#define BTIF_A2DP_EVENT_STREAM_CLOSED 8 + +/** This event is received when an open stream has been + * set to the idle state. result of a call to btif_a2dp_idle_stream(). + */ +#define BTIF_A2DP_EVENT_STREAM_IDLE 9 + +/** When the remote device requests streaming to begin, this event will be + * received . The application can accept or reject + * this request by calling btif_a2dp_start_stream_rsp(). (Note: this event + * will be received only after BTIF_A2DP_EVENT_STREAM_OPEN_IND but it may arrive + * before BTIF_A2DP_EVENT_STREAM_OPEN.) + */ +#define BTIF_A2DP_EVENT_STREAM_START_IND 10 + +/** When streaming has been started, this event will be received. This can happen as the result to a call to + * btif_a2dp_start_stream() or btif_a2dp_start_stream_rsp(). + */ +#define BTIF_A2DP_EVENT_STREAM_STARTED 11 + +/** When streaming has been suspended, this event will be received . as the result to a call to + * btif_a2dp_suspend_stream(), or when the remote device suspends the stream. + */ +#define BTIF_A2DP_EVENT_STREAM_SUSPENDED 12 + +/** When the remote device wishes to reconfigure an open stream, this event + * is received by the application. The application can accept or reject + * the request by calling btif_a2dp_reconfig_stream_rsp(). + * + */ +#define BTIF_A2DP_EVENT_STREAM_RECONFIG_IND 13 + +/** When an open stream is reconfigured, this event is received by the + * application. + * + */ +#define BTIF_A2DP_EVENT_STREAM_RECONFIG_CNF 14 + +/** This event is received when the remote device requests the security + * process to begin. The application responds to this request by calling + * btif_a2dp_security_control_rsp(). + */ +#define BTIF_A2DP_EVENT_STREAM_SECURITY_IND 15 + +/** This event is received when the remote device responds + * to the security process request. + */ +#define BTIF_A2DP_EVENT_STREAM_SECURITY_CNF 16 + +/** When the stream is aborted, this event is received by the application. + * This can happen in response to a request from the remote device to abort + * the stream, or as the result of a call to btif_a2dp_abort_stream(). When a + * stream is aborted, the stream is closed. + */ +#define BTIF_A2DP_EVENT_STREAM_ABORTED 17 + +/** This event is received when stream data has been received from the remote + * device. The data is raw and is not parsed by A2DP. It should contain + * a single media packet. + */ +#define BTIF_A2DP_EVENT_STREAM_DATA_IND 18 + +/** This event is received when raw data has been sent to the remote device. + * This happens as the result of a call to btif_a2dp_stream_send_raw_packet(). + * + */ +#define BTIF_A2DP_EVENT_STREAM_PACKET_SENT 19 + +/** This event is received when SBC data has been sent to the remote device. + * This happens as the result of a call to btif_a2dp_stream_send_sbc_packet(). + */ +#define BTIF_A2DP_EVENT_STREAM_SBC_PACKET_SENT 20 + +/** This event is received by a Source when the Sink reports the value of its + * buffer/processing delay. This may happen when the stream is configured + * (or reconfigured), and when the stream is in the streaming state. + * + */ +#define BTIF_A2DP_EVENT_DELAY_REPORT_IND 21 + +/** This event is received by a Sink when the Source acknowldeges the + * transmitted buffer/processing delay. + */ +#define BTIF_A2DP_EVENT_DELAY_REPORT_CNF 22 + +/** When the the lower level AVDTP connection is established between the + * local and remote devices, this event will be generated. + * + * During this callback, the 'p.device' parameter contains a pointer to the + * device that was connected. + */ +#define BTIF_A2DP_EVENT_AVDTP_CONNECT 23 + +/** When the the lower level AVDTP connection is disconnected, this event + * will be generated. + * + */ +#define BTIF_A2DP_EVENT_AVDTP_DISCONNECT 24 + +#if BTIF_AV_WORKER +/* Confirms has received configuration information after an + * btif_avdtp_get_config() request. + */ +#define BTIF_A2DP_AVDTP_EVENT_GET_CFG_CNF 27 + +/* Confirms has sent configuration information after an + * btif_avdtp_open_stream() request. + */ +#define BTIF_A2DP_AVDTP_EVENT_SET_CFG_CNF 28 + +#endif + +#define BTIF_A2DP_EVENT_STREAM_STARTED_MOCK 29 + +//user define @biao +#define BTIF_A2DP_EVENT_AVDTP_CLOSE_IND 81 +#define BTIF_A2DP_EVENT_AVDTP_DISCOVER_IND 82 +#define BTIF_A2DP_EVENT_AVDTP_DISCOVER_RSP 83 +//#define AVDTP_EVENT_STREAM_CLOSE_IND + +/* event that let app level to see a stream is good to select */ +#define BTIF_A2DP_EVENT_STREAM_SELECT 84 +/* event that let app level to confirm stream(sep) state */ +#define BTIF_A2DP_EVENT_STREAM_STATE_CFM 85 + +typedef uint8_t btif_a2dp_error_t; + +#define BTIF_A2DP_ERR_NO_ERROR 0x00 + +#define BTIF_A2DP_ERR_BAD_SERVICE 0x80 + +#define BTIF_A2DP_ERR_INSUFFICIENT_RESOURCE 0x81 + +#define BTIF_A2DP_ERR_INVALID_CODEC_TYPE 0xC1 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_CODEC_TYPE AVDTP_ERR_NOT_SUPPORTED_CODEC_TYPE + +#define BTIF_A2DP_ERR_INVALID_SAMPLING_FREQUENCY 0xC3 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_SAMP_FREQ 0xC4 + +/** Channel mode not valid + * + * SBC + * MPEG-1,2 Audio + * ATRAC family + */ +#define BTIF_A2DP_ERR_INVALID_CHANNEL_MODE 0xC5 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_CHANNEL_MODE 0xC6 + +#define BTIF_A2DP_ERR_INVALID_SUBBANDS 0xC7 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_SUBBANDS 0xC8 + +#define BTIF_A2DP_ERR_INVALID_ALLOCATION_METHOD 0xC9 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_ALLOC_METHOD 0xCA + +#define BTIF_A2DP_ERR_INVALID_MIN_BITPOOL_VALUE 0xCB + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_MIN_BITPOOL_VALUE 0xCC + +#define BTIF_A2DP_ERR_INVALID_MAX_BITPOOL_VALUE 0xCD + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_MAX_BITPOOL_VALUE 0xCE + +#define BTIF_A2DP_ERR_INVALID_LAYER 0xCF + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_LAYER 0xD0 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_CRC 0xD1 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_MPF 0xD2 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_VBR 0xD3 + +#define BTIF_A2DP_ERR_INVALID_BIT_RATE 0xD4 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_BIT_RATE 0xD5 + +#define BTIF_A2DP_ERR_INVALID_OBJECT_TYPE 0xD6 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_OBJECT_TYPE 0xD7 + +#define BTIF_A2DP_ERR_INVALID_CHANNELS 0xD8 + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_CHANNELS 0xD9 + +#define A2DP_SCALABLE_OCTET_NUMBER (7) + +#define BTIF_A2DP_ERR_INVALID_VERSION 0xDA + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_VERSION 0xDB + +#define BTIF_A2DP_ERR_NOT_SUPPORTED_MAXIMUM_SUL 0xDC + +#define BTIF_A2DP_ERR_INVALID_BLOCK_LENGTH 0xDD + +#define BTIF_A2DP_ERR_INVALID_CP_TYPE 0xE0 + +#define BTIF_A2DP_ERR_INVALID_CP_FORMAT 0xE1 + +#define BTIF_A2DP_ERR_UNKNOWN_ERROR AVDTP_ERR_UNKNOWN_ERROR + +typedef U16 btif_a22dp_version_t; + +typedef U16 btif_a2dp_features_t; + +/* Audio Player */ +#define BTIF_A2DP_SRC_FEATURE_PLAYER 0x01 + +/* Microphone */ +#define BTIF_A2DP_SRC_FEATURE_MIC 0x02 + +/* Tuner */ +#define BTIF_A2DP_SRC_FEATURE_TUNER 0x04 + +/* Mixer */ +#define BTIF_A2DP_SRC_FEATURE_MIXER 0x08 + +/* Headphones */ +#define BTIF_A2DP_SNK_FEATURE_HEADPHONE 0x01 + +/* Loudspeaker */ +#define BTIF_A2DP_SNK_FEATURE_SPEAKER 0x02 + +/* Audio Recorder */ +#define BTIF_A2DP_SNK_FEATURE_RECORDER 0x04 + +/* Amplifier */ +#define BTIF_A2DP_SNK_FEATURE_AMP 0x08 + +typedef U8 btif_a2dp_endpoint_type_t; + +/* The stream is a source */ +#define BTIF_A2DP_STREAM_TYPE_SOURCE 0 + +/* The stream is a sink */ +#define BTIF_A2DP_STREAM_TYPE_SINK 1 + +typedef uint8_t btif_a2dp_stream_state_t; + +/* The stream is closed */ +#define BTIF_A2DP_STREAM_STATE_CLOSED 0 + +/* The stream is idle */ +#define BTIF_A2DP_STREAM_STATE_IDLE 1 + +/* The stream is open */ +#define BTIF_A2DP_STREAM_STATE_OPEN 2 + +/* The stream is streaming */ +#define BTIF_A2DP_STREAM_STATE_STREAMING 3 + +/* Unknown state */ +#define BTIF_A2DP_STREAM_STATE_UNKNOWN 0xFF + +typedef void (*btif_a2dp_callback) (a2dp_stream_t * Stream, const a2dp_callback_parms_t * Info); + + +typedef void btif_av_device_t; + +struct btif_get_codec_cap_t +{ + uint8_t ** cap; + uint16_t * cap_len; + bool done; +}; + +typedef struct { + btif_a2dp_event_t event; + uint8_t subevt; + uint16_t len; + I8 status; + btif_a2dp_error_t error; + btif_a2dp_error_t discReason; + union { + btif_avdtp_content_prot_t *cp; + btif_avdtp_codec_t *codec; + btif_avdtp_capability_t *capability; + btif_avdtp_config_request_t *configReq; /* AVDTP Config request */ + btif_bt_packet_t *btPacket; /* Raw Transmit packet */ + btif_a2dp_sbc_packet_t *sbcPacket; /* SBC Transmit packet */ + uint8_t *data; /* Receive data */ + uint16_t delayMs; /* Buffering/processing delay of + * the Sink. + */ + btif_avdtp_stream_info_t *streamInfo; /* Stream information */ + btif_av_device_t *device; /* The connecting or disconnectin device. */ + struct btif_get_codec_cap_t *get_cap; + + a2dp_stream_t *dstStream; /* Stream to switch */ + } p; + btif_remote_device_t *remDev; +} btif_a2dp_callback_parms_t; + +typedef struct { + list_entry_t node; /* Used internally by A2DP. */ + btif_avdtp_stream_info_t info; /* Stream information */ +} btif_a2dp_streamInfo_t; + +typedef struct { +#if defined(__TWS__) + btif_avdtp_codec_t setconfig_codec; +#endif /* */ + bool free; + uint8_t state; + a2dp_stream_t *a2dp_stream; //stack A2dpStream object +} btif_a2dp_stream_t; + + + +#ifdef __cplusplus +extern "C" { +#endif + + void btif_a2dp_init(void); + + int a2dp_hid_init(void); + + btif_a2dp_stream_t *btif_a2dp_alloc_stream(void); + + uint16_t btif_avdtp_parse_mediaHeader(btif_media_header_t * header, + btif_a2dp_callback_parms_t * Info, uint8_t avdtp_cp); + + void btif_app_a2dp_avrcpadvancedpdu_mempool_init(); + + void btif_app_a2dp_avrcpadvancedpdu_mempool_calloc(void **buf); + + void btif_app_a2dp_avrcpadvancedpdu_mempool_free(void *buf); + + void a2dp_set_config_codec(btif_avdtp_codec_t * config_codec, + const btif_a2dp_callback_parms_t * Info); + + btif_avdtp_codec_type_t btif_a2dp_get_stream_register_codec_type(a2dp_stream_t *stream); + + bt_status_t btif_a2dp_register(a2dp_stream_t *Stream, + btif_a2dp_endpoint_type_t stream_type, + btif_avdtp_codec_t *Codec, + btif_avdtp_content_prot_t *Prot, + uint8_t Priority, + uint8_t Device_id, + btif_a2dp_callback Callback); + + bt_status_t btif_a2dp_add_content_protection(a2dp_stream_t *Stream, btif_avdtp_content_prot_t *Prot); + + bt_status_t btif_a2dp_deregister(a2dp_stream_t * Stream); + + int8_t btif_a2dp_is_register_codec_same(a2dp_stream_t *src_stream, a2dp_stream_t *dst_stream); + + void btif_a2dp_lhdc_config_tws_audio(const a2dp_callback_parms_t * info); + + void btif_a2dp_aac_config_tws_audio(const a2dp_callback_parms_t * info); + + void btif_a2dp_sbc_config_tws_audio(const a2dp_callback_parms_t * info); + + void btif_a2dp_tws_set_mobile_codec_info(const a2dp_callback_parms_t * info); + + void btif_a2dp_set_copy_protection_enable(a2dp_stream_t *stream, bool enable); + + btif_remote_device_t *btif_a2dp_get_remote_device(a2dp_stream_t * stream); + + uint8_t *btif_a2dp_get_stream_devic_cmgrHandler_remdev_bdAddr(a2dp_stream_t * Stream); + + void *btif_a2dp_get_stream_device(a2dp_stream_t * Stream); + + void *btif_a2dp_get_stream_devic_cmgrHandler_bt_handler(a2dp_stream_t * Stream); + + void *btif_a2dp_get_stream_devic_cmgrHandler_remdev(a2dp_stream_t * Stream); + + uint8_t btif_a2dp_get_stream_devic_cmgrHandler_remdev_role(a2dp_stream_t * Stream); + + btif_cmgr_handler_t *btif_a2dp_get_stream_devic_cmgrHandler(a2dp_stream_t * Stream); + + void btif_me_set_sniffer_env(uint8_t sniffer_acitve, uint8_t sniffer_role, + uint8_t * monitored_addr, uint8_t * sniffer_addr); + + uint16_t btif_me_get_remote_device_hci_handle(btif_remote_device_t * rdev); + + bt_bdaddr_t *btif_a2dp_stream_conn_remDev_bdAddr(a2dp_stream_t * Stream); + + uint8_t *btif_a2dp_get_remote_device_version(btif_remote_device_t * remDev); + + btif_a2dp_event_t btif_a2dp_get_cb_event(a2dp_callback_parms_t * info); + + bt_status_t btif_a2dp_set_sink_delay(a2dp_stream_t * Stream, U16 delayMs); + + bt_status_t btif_a2dp_set_stream_config(a2dp_stream_t * Stream, + btif_avdtp_codec_t * Codec, + btif_avdtp_content_prot_t * Cp); + + bt_status_t btif_a2dp_open_stream(a2dp_stream_t * Stream, bt_bdaddr_t * Addr); + + bt_status_t btif_a2dp_disc_stream(a2dp_stream_t * Stream); + + bt_status_t btif_a2dp_start_stream(a2dp_stream_t * Stream); + + bt_status_t btif_a2dp_idle_stream(a2dp_stream_t * Stream); + + bt_status_t btif_a2dp_suspend_stream(a2dp_stream_t * Stream); + + bt_status_t btif_a2dp_start_stream_rsp(a2dp_stream_t * Stream, btif_a2dp_error_t error); + + bt_status_t btif_a2dp_close_stream(a2dp_stream_t * Stream); + + bt_status_t btif_a2dp_reconfig_stream_rsp(a2dp_stream_t * Stream, + btif_a2dp_error_t Error, + btif_avdtp_capability_type_t Type); + + bt_status_t btif_a2dp_reconfig_stream(a2dp_stream_t * Stream, + btif_avdtp_codec_t * codec_cfg, + btif_avdtp_content_prot_t * cp); + + uint8_t btif_a2dp_security_control_req(a2dp_stream_t *stream, uint8_t *data, uint16_t len); + uint8_t btif_a2dp_security_control_rsp(a2dp_stream_t *stream,uint8_t* data,uint16_t len, uint8_t error); + + bt_status_t btif_a2dp_open_stream_rsp(a2dp_stream_t * Stream, + btif_a2dp_error_t Error, + btif_avdtp_capability_type_t CapType); + + bool btif_a2dp_stream_has_remote_device(btif_a2dp_stream_t * stream); + + bt_bdaddr_t *btif_a2dp_stream_get_remote_bd_addr(btif_a2dp_stream_t * stream); + + btif_a2dp_stream_t *btif_get_a2dp_stream(a2dp_stream_t * stream); + + btif_a2dp_endpoint_type_t btif_a2dp_get_stream_type(a2dp_stream_t * Stream); + + btif_avdtp_stream_state_t btif_a2dp_get_stream_state(a2dp_stream_t * Stream); + + uint8_t btif_a2dp_get_stream_loc_strmId(a2dp_stream_t * Stream); + + uint8_t btif_a2dp_get_stream_rem_strmId(a2dp_stream_t * Stream); + + uint16_t btif_a2dp_get_stream_chnl_sigchnl_l2ChannelId(a2dp_stream_t * Stream); + + void btif_a2dp_set_stream_state(a2dp_stream_t * Stream, btif_avdtp_stream_state_t state); + + void btif_a2dp_reset_stream_state(a2dp_stream_t *stream); + + void btif_a2dp_set_stream_conn_l2ChannelId(a2dp_stream_t * Stream, uint16_t id); + + void btif_a2dp_set_stream_chnl_conn_l2ChannelId(a2dp_stream_t * Stream, uint16_t id); + + void btif_a2dp_set_stream_chnl_sigChnl_l2ChannelId(a2dp_stream_t * Stream, uint16_t id); + + void btif_a2dp_set_stream_loc_streamId(a2dp_stream_t * Stream, uint8_t id); + + void btif_a2dp_set_stream_remote_streamId(a2dp_stream_t * Stream, uint8_t id); + + void btif_a2dp_discover(a2dp_stream_t* Stream); + + BOOL btif_a2dp_is_stream_device_has_delay_reporting(a2dp_stream_t * Stream); + + btif_avdtp_codec_t *btif_a2dp_get_stream_codec(a2dp_stream_t * Stream); + + btif_avdtp_codec_t *btif_a2dp_get_stream_codecCfg(a2dp_stream_t * Stream); + + uint16_t btif_a2dp_get_stream_conn_remDev_hciHandle(a2dp_stream_t * Stream); + + uint16_t btif_a2dp_get_stream_device_cmgrhandler_remDev_hciHandle(a2dp_stream_t * Stream); + + btif_avdtp_codec_t *btif_a2dp_get_avdtp_setconfig_codec(a2dp_stream_t * stream); + + bt_status_t btif_a2dp_get_stream_capabilities(a2dp_stream_t * Stream); + + bt_status_t btif_a2dp_stream_send_sbc_packet(a2dp_stream_t * stream, + btif_a2dp_sbc_packet_t * Packet, + btif_sbc_stream_info_short_t * StreamInfo); + + void btif_a2dp_sync_avdtp_streaming_state(bt_bdaddr_t *addr); + + void btif_app_a2dp_source_init(void); + + uint8_t btif_a2dp_get_cb_error(const btif_a2dp_callback_parms_t * Info); + + uint8_t btif_a2dp_set_dst_stream(a2dp_callback_parms_t *Info, a2dp_stream_t *stream); + + btif_remote_device_t *btif_a2dp_get_stream_conn_remDev(a2dp_stream_t * stream); + + uint8_t btif_a2dp_get_stream_codec_element(a2dp_stream_t * stream,uint8_t index); + + bt_status_t btif_a2dp_set_master_role(a2dp_stream_t * Stream, BOOL Flag); + + uint16_t btif_a2dp_get_stream_conn_l2ChannelId(a2dp_stream_t * Stream); + + btif_media_header_t *btif_a2dp_get_stream_media_header(a2dp_stream_t * stream); + + int tws_if_get_a2dpbuff_available(void); + + int a2dp_codec_init(void); + void btif_a2dp_lock_same_deviceid_endpoint(a2dp_stream_t * Stream,btif_remote_device_t *remDev); + void btif_a2dp_unlock_same_deviceid_endpoint(a2dp_stream_t * Stream,btif_remote_device_t *remDev); + void btif_a2dp_unlock_the_connected_stream_byRemdev(btif_remote_device_t* RemDev); + + uint8_t btif_a2dp_trylock_the_other_id_by_configedid(btif_remote_device_t* RemDev); + + uint8_t btif_a2dp_confirm_stream_state(a2dp_stream_t *Stream, uint8_t old_state, uint8_t new_state); + + void btif_a2dp_lock_deviceid_endpoint(uint8_t id); + + void btif_a2dp_unlock_deviceid_endpoint(uint8_t unused_id); + + bool btif_a2dp_is_disconnected(a2dp_stream_t *Stream); + + uint8_t btif_a2dp_get_avrcpadvancedpdu_trans_id(void* pdu); + void btif_a2dp_set_avrcpadvancedpdu_trans_id(void* pdu, uint8_t trans_id); + + btif_remote_device_t *btif_a2dp_get_remote_device_from_cbparms(a2dp_stream_t *Stream, const a2dp_callback_parms_t *info); + + btif_avdtp_codec_type_t btif_a2dp_get_codec_type(const a2dp_callback_parms_t *info); + void btif_a2dp_set_codec_info_func(void (*func)(btif_dev_it_e dev_num, const uint8_t *codec)); + void btif_a2dp_get_codec_info_func(void (*func)(btif_dev_it_e dev_num, uint8_t *codec)); + +#if defined(IBRT) + void btif_reset_app_bt_device_streaming(uint8_t bt_dev_idx, uint8_t rm_detbl_idx , uint8_t avd_ctx_device_idx); + void btif_a2dp_set_codec_info(btif_dev_it_e dev_num, const uint8_t *codec); + void btif_a2dp_get_codec_info(btif_dev_it_e dev_num, uint8_t *codec); +#endif +#if defined(IBRT) +#if defined(ENHANCED_STACK) + uint32_t btif_a2dp_profile_save_ctx(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len); + uint32_t btif_a2dp_profile_restore_ctx(uint8_t *buf, uint32_t buf_len); + uint8_t btif_a2dp_is_critical_avdtp_cmd_handling(void); + void btif_a2dp_critical_avdtp_cmd_timeout(void); +#endif /* *ENHANCED_STACK */ +#endif /* IBRT */ + + /* Callout functions, do not call directly */ + uint8_t a2dp_stream_confirm_stream_state(uint8_t index, uint8_t old_state, uint8_t new_state); + uint8_t a2dp_stream_locate_the_connected_dev_id(a2dp_stream_t *Stream); + +void btif_a2dp_get_info(uint8_t devIndex, btif_avdtp_codec_type_t* pCodec, + uint8_t* pSampleRate, uint8_t* pSampleBit); + +#ifdef __cplusplus +} +#endif /* */ +#endif /* */ diff --git a/services/bt_if_enhanced/inc/avctp_api.h b/services/bt_if_enhanced/inc/avctp_api.h new file mode 100644 index 0000000..b5cc808 --- /dev/null +++ b/services/bt_if_enhanced/inc/avctp_api.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _AVCTP_API_H +#define _AVCTP_API_H + +typedef uint8_t btif_avctp_event_t; + +#define BTIF_AVCTP_CONNECT_EVENT 1 + +#define BTIF_AVCTP_CONNECT_IND_EVENT 2 + +#define BTIF_AVCTP_DISCONNECT_EVENT 3 + +#define BTIF_AVCTP_COMMAND_EVENT 4 + +#define BTIF_AVCTP_RESPONSE_EVENT 5 + +#define BTIF_AVCTP_REJECT_EVENT 6 + +#define BTIF_AVCTP_TX_DONE_EVENT 8 + +#define BTIF_AVCTP_OPERANDS_EVENT 9 + +#define BTIF_AVCTP_LAST_EVENT 9 + +#define BTIF_AVCTP_CTYPE_CONTROL 0x00 +#define BTIF_AVCTP_CTYPE_STATUS 0x01 +#define BTIF_AVCTP_CTYPE_SPECIFIC_INQUIRY 0x02 +#define BTIF_AVCTP_CTYPE_NOTIFY 0x03 +#define BTIF_AVCTP_CTYPE_GENERAL_INQUIRY 0x04 +#define BTIF_AVCTP_CTYPE_BROWSING 0x80 +#define BTIF_AVCTP_CTYPE_RESERVED 0x0A + +typedef U8 avctp_response_t; + +#define BTIF_AVCTP_RESPONSE_NOT_IMPLEMENTED 0x08 +#define BTIF_AVCTP_RESPONSE_ACCEPTED 0x09 +#define BTIF_AVCTP_RESPONSE_REJECTED 0x0A +#define BTIF_AVCTP_RESPONSE_IN_TRANSITION 0x0B +#define BTIF_AVCTP_RESPONSE_IMPLEMENTED_STABLE 0x0C +#define BTIF_AVCTP_RESPONSE_CHANGED 0x0D +#define BTIF_AVCTP_RESPONSE_INTERIM 0x0F +#define BTIF_AVCTP_RESPONSE_BROWSING 0x40 + +typedef U8 btif_avctp_opcode_t; + +#define BTIF_AVCTP_OPCODE_VENDOR_DEPENDENT 0x00 +#define BTIF_AVCTP_OPCODE_UNIT_INFO 0x30 +#define BTIF_AVCTP_OPCODE_SUBUNIT_INFO 0x31 +#define BTIF_AVCTP_OPCODE_PASS_THROUGH 0x7C + +#define BTIF_AVCTP_PACKET_TYPE_SINGLE 0 +#define BTIF_AVCTP_PACKET_TYPE_START 1 +#define BTIF_AVCTP_PACKET_TYPE_CONTINUE 2 +#define BTIF_AVCTP_PACKET_TYPE_END 3 + +typedef U8 btif_avctp_errorcode_t; + +#define BTIF_AVRCP_ERR_INVALID_CMD 0x00 +#define BTIF_AVRCP_ERR_INVALID_PARM 0x01 + +typedef void avctp_cmdframe_t; +typedef void avctp_rspframe_t; + +typedef struct { + + /* Callback parameter object, depending on "event" */ + union { + + void *remDev; + + void *cmdFrame; + + void *rspFrame; + } p; +} avctp_callback_parms_t; + +#endif /* */ diff --git a/services/bt_if_enhanced/inc/avdtp_api.h b/services/bt_if_enhanced/inc/avdtp_api.h new file mode 100644 index 0000000..185ad59 --- /dev/null +++ b/services/bt_if_enhanced/inc/avdtp_api.h @@ -0,0 +1,223 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _AVDTP_API_H +#define _AVDTP_API_H + +#include "stdint.h" +#include "bluetooth.h" + +/* Signal Commands */ +#define BTIF_AVDTP_SIG_DISCOVER 0x01 +#define BTIF_AVDTP_SIG_GET_CAPABILITIES 0x02 +#define BTIF_AVDTP_SIG_SET_CONFIG 0x03 +#define BTIF_AVDTP_SIG_GET_CONFIG 0x04 +#define BTIF_AVDTP_SIG_RECONFIG 0x05 +#define BTIF_AVDTP_SIG_OPEN 0x06 +#define BTIF_AVDTP_SIG_START 0x07 +#define BTIF_AVDTP_SIG_CLOSE 0x08 +#define BTIF_AVDTP_SIG_SUSPEND 0x09 +#define BTIF_AVDTP_SIG_ABORT 0x0A +#define BTIF_AVDTP_SIG_SECURITY_CTRL 0x0B +#define BTIF_AVDTP_SIG_GET_ALL_CAPABILITIES 0x0C +#define BTIF_AVDTP_SIG_DELAYREPORT 0x0D + +#ifndef avdtp_codec_t +#define avdtp_codec_t void +#endif +#ifndef avdtp_channel_t +#define avdtp_channel_t void +#endif + +typedef uint8_t btif_avdtp_codec_type_t; +typedef uint16_t btif_avdtp_content_prot_type_t; +typedef uint8_t btif_avdtp_capability_type_t; + +#define BTIF_AVDTP_CP_TYPE_DTCP 0x0001 + +#define BTIF_AVDTP_CP_TYPE_SCMS_T 0x0002 + +#define BTIF_AVDTP_SRV_CAT_MEDIA_TRANSPORT 0x01 +#define BTIF_AVDTP_SRV_CAT_REPORTING 0x02 +#define BTIF_AVDTP_SRV_CAT_RECOVERY 0x03 +#define BTIF_AVDTP_SRV_CAT_CONTENT_PROTECTION 0x04 +#define BTIF_AVDTP_SRV_CAT_HEADER_COMPRESSION 0x05 +#define BTIF_AVDTP_SRV_CAT_MULTIPLEXING 0x06 +#define BTIF_AVDTP_SRV_CAT_MEDIA_CODEC 0x07 +#define BTIF_AVDTP_SRV_CAT_DELAY_REPORTING 0x08 + +typedef uint16_t btif_avdtp_codec_sample_rate_t; + +#define BTIF_AVDTP_CODEC_TYPE_SBC 0x00 + +#define BTIF_AVDTP_CODEC_TYPE_MPEG1_2_AUDIO 0x01 + +#define BTIF_AVDTP_CODEC_TYPE_MPEG2_4_AAC 0x02 + +#define BTIF_AVDTP_CODEC_TYPE_ATRAC 0x04 + +#define BTIF_AVDTP_CODEC_TYPE_OPUS 0x08 + +#define BTIF_AVDTP_CODEC_TYPE_H263 0x01 + +#define BTIF_AVDTP_CODEC_TYPE_MPEG4_VSP 0x02 + +#define BTIF_AVDTP_CODEC_TYPE_H263_PROF3 0x03 + +#define BTIF_AVDTP_CODEC_TYPE_H263_PROF8 0x04 + +#define BTIF_AVDTP_CODEC_TYPE_LHDC 0xFF + +#define BTIF_AVDTP_CODEC_TYPE_NON_A2DP 0xFF + +#define BTIF_AVDTP_MAX_CODEC_ELEM_SIZE 10 + +#define BTIF_AVDTP_MAX_CP_VALUE_SIZE 10 + +typedef uint8_t btif_avdtp_stream_state_t; + +/** The stream is idle and not configured. Streaming is not possible. + */ +#define BTIF_AVDTP_STRM_STATE_IDLE 0 + +/** A stream is configured, but not open. This state will only occur in + * certain cases where a request to open the stream is rejected, and the + * operation cannot be aborted. + * + * AVDTP_AbortStream() must be called to exit this state. + */ +#define BTIF_AVDTP_STRM_STATE_CONFIGURED 1 + +/** The stream is open and configured. Streaming can be initiated after the + * stream is open by calling AVDTP_StartStream(). + */ +#define BTIF_AVDTP_STRM_STATE_OPEN 2 + +/** The stream is active. Stream data (media packets) can be sent only in + * this state. + */ +#define BTIF_AVDTP_STRM_STATE_STREAMING 3 + +#define BTIF_AVDTP_STRM_STATE_CLOSING 4 + +#define BTIF_AVDTP_STRM_STATE_ABORTING 5 + +typedef U8 btif_avdtp_error_t; + +#define BTIF_AVDTP_ERR_NO_ERROR 0x00 + +#define BTIF_AVDTP_ERR_BAD_HEADER_FORMAT 0x01 + +#define BTIF_AVDTP_ERR_BAD_LENGTH 0x11 + +#define BTIF_AVDTP_ERR_BAD_ACP_SEID 0x12 + +#define BTIF_AVDTP_ERR_IN_USE 0x13 + +#define BTIF_AVDTP_ERR_NOT_IN_USE 0x14 + +#define BTIF_AVDTP_ERR_BAD_SERV_CATEGORY 0x17 + +#define BTIF_AVDTP_ERR_BAD_PAYLOAD_FORMAT 0x18 + +#define BTIF_AVDTP_ERR_NOT_SUPPORTED_COMMAND 0x19 + +#define BTIF_AVDTP_ERR_INVALID_CAPABILITIES 0x1A + +#define BTIF_AVDTP_ERR_BAD_RECOVERY_TYPE 0x22 + +#define BTIF_AVDTP_ERR_BAD_MEDIA_TRANSPORT_FORMAT 0x23 + +#define BTIF_AVDTP_ERR_BAD_RECOVERY_FORMAT 0x25 + +#define BTIF_AVDTP_ERR_BAD_ROHC_FORMAT 0x26 + +#define BTIF_AVDTP_ERR_BAD_CP_FORMAT 0x27 + +#define BTIF_AVDTP_ERR_BAD_MULTIPLEXING_FORMAT 0x28 + +#define BTIF_AVDTP_ERR_UNSUPPORTED_CONFIGURATION 0x29 + +#define BTIF_AVDTP_ERR_BAD_STATE 0x31 + +#define BTIF_AVDTP_ERR_NOT_SUPPORTED_CODEC_TYPE 0xC2 + +#define BTIF_AVDTP_ERR_UNKNOWN_ERROR 0xFF + +typedef struct { + btif_avdtp_content_prot_type_t cpType; + uint8_t dataLen; + uint8_t *data; +}__attribute__((packed)) btif_avdtp_content_prot_t; + +typedef struct { + btif_avdtp_codec_type_t codecType; + uint8_t elemLen; + uint8_t *elements; + uint8_t *pstreamflags; + bool discoverable; +}__attribute__((packed)) btif_avdtp_codec_t ; + +typedef struct { + btif_avdtp_capability_type_t type; + union { + btif_avdtp_codec_t codec; + btif_avdtp_content_prot_t cp; + } p; +} btif_avdtp_capability_t; + +typedef struct { + btif_avdtp_codec_t codec; + btif_avdtp_content_prot_t cp; + BOOL delayReporting; +} btif_avdtp_config_request_t; + + +typedef uint8_t btif_avdtp_streamId_t; +typedef uint8_t btif_avdtp_media_type; +typedef uint8_t btif_avdtp_strm_endpoint_type_t; + +typedef struct { + btif_avdtp_streamId_t id; + bool inUse; + btif_avdtp_media_type mediaType; + btif_avdtp_strm_endpoint_type_t streamType; +} btif_avdtp_stream_info_t; + +typedef struct { + U8 version; + U8 padding; + U8 marker; + U8 payloadType; + U16 sequenceNumber; + U32 timestamp; + U32 ssrc; + U8 csrcCount; + U32 csrcList[15]; +} btif_avdtp_media_header_t; +typedef btif_avdtp_media_header_t btif_media_header_t; + +typedef void btif_avdtp_stream_t; + +#ifdef __cplusplus +extern "C" { + +#endif + btif_avdtp_codec_type_t btif_avdtp_get_stream_codec_type(btif_avdtp_stream_t * stream); + +#ifdef __cplusplus +} +#endif /* */ +#endif /* */ diff --git a/services/bt_if_enhanced/inc/avrcp_api.h b/services/bt_if_enhanced/inc/avrcp_api.h new file mode 100644 index 0000000..426cb52 --- /dev/null +++ b/services/bt_if_enhanced/inc/avrcp_api.h @@ -0,0 +1,1703 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _AVRCP_API_H +#define _AVRCP_API_H +#include "me_api.h" +#include "avctp_api.h" +#include "bluetooth.h" +#include "plat_types.h" +#include "cqueue.h" + +#define BTIF_AVRCP_MAX_CHAR_SETS 10 + +#define BTIF_AVTP_HEADER_LEN 10 + +#define BTIF_AVRCP_RX_FRAG_BUFF_SIZE 672 //L2CAP_DEFAULT_MTU + +typedef btif_avctp_event_t btif_avrcp_event_t; +typedef void *btif_avrcp_chnl_handle_t; +typedef void *btif_app_bt_device_t; + + +/** The transport layer is connected and commands/responses can now + * be exchanged. + */ +#define BTIF_AVRCP_EVENT_CONNECT BTIF_AVCTP_CONNECT_EVENT + +/** The application will receive this event when a lower layer connection + * (L2CAP) has been disconnected. Both the target and controller of the + * connection are notified. + * + * During this callback, the 'p.remDev' parameter is valid. + */ +#define BTIF_AVRCP_EVENT_DISCONNECT BTIF_AVCTP_DISCONNECT_EVENT + +/** A remote device is attempting to connect the transport layer. + * Only the acceptor of the connection is notified. + */ +#define BTIF_AVRCP_EVENT_CONNECT_IND BTIF_AVCTP_CONNECT_IND_EVENT + +/* Group: Events for the exchange of basic AV/C commands that are not routed + * to the panel subunit. + */ +#define BTIF_AVRCP_EVENT_COMMAND BTIF_AVCTP_COMMAND_EVENT + +/** A AV/C response was received from the remote device (target). This event + * is received for responses not routed to the panel subunit. + */ +#define BTIF_AVRCP_EVENT_RESPONSE BTIF_AVCTP_RESPONSE_EVENT + +/** The remote device (target) rejected the AV/C command. This event is + * received for responses not routed to the panel subunit. + */ +#define BTIF_AVRCP_EVENT_REJECT BTIF_AVCTP_REJECT_EVENT + +/** A command (see AVRCP_SendCommand) or response (see AVRCP_SendResponse) + * has been sent. + */ +#define BTIF_AVRCP_EVENT_TX_DONE BTIF_AVCTP_TX_DONE_EVENT + +/** Additional operand data has been received for the previous + * AVRCP_EVENT_COMMAND or AVRCP_EVENT_RESPONSE. + */ +#define BTIF_AVRCP_EVENT_OPERANDS BTIF_AVCTP_OPERANDS_EVENT + +/** An AV/C command has timed out. + */ +#define BTIF_AVRCP_EVENT_CMD_TIMEOUT ( BTIF_AVCTP_LAST_EVENT + 1) + +/* Group: Events for the exchange of standard AV/C panel subunit commands. + */ + +#define BTIF_AVRCP_EVENT_PANEL_PRESS ( BTIF_AVCTP_LAST_EVENT + 2) + +/** The key corresponding to a panel operation has been held down on the + * remote controller device for at least AVRCP_PANEL_PRESSHOLD_TIME. + */ +#define BTIF_AVRCP_EVENT_PANEL_HOLD ( BTIF_AVCTP_LAST_EVENT + 3) + +/** The key corresponding to a panel operation has been released on the + * remote controller device. + */ +#define BTIF_AVRCP_EVENT_PANEL_RELEASE ( BTIF_AVCTP_LAST_EVENT + 4) + +/** A panel response has been received from the remote target device. + * All fields of "p.panelCnf" are valid. + */ +#define BTIF_AVRCP_EVENT_PANEL_CNF ( BTIF_AVCTP_LAST_EVENT + 5) + +/* Group: Events for the exchange of Bluetooth specific advanced AV/C + * commands routed through the panel subunit. + */ + +/** Advanced status information has been received from the controller. + */ +#define BTIF_AVRCP_EVENT_ADV_INFO ( BTIF_AVCTP_LAST_EVENT + 6) + +/** An advanced request was received and requires a response by the + * application. + */ +#define BTIF_AVRCP_EVENT_ADV_REQ ( BTIF_AVCTP_LAST_EVENT + 7) + +/** The notification of a registered event has been received. + */ +#define BTIF_AVRCP_EVENT_ADV_NOTIFY ( BTIF_AVCTP_LAST_EVENT + 8) + +/** An Advanced command was sent successfully to the target and a response + * was received. + */ +#define BTIF_AVRCP_EVENT_ADV_RESPONSE ( BTIF_AVCTP_LAST_EVENT + 9) + +/** No response was received for an Advanced command and it has timed out. + * This event is received for advanced commands routed to the panel subunit. + */ +#define BTIF_AVRCP_EVENT_ADV_CMD_TIMEOUT ( BTIF_AVCTP_LAST_EVENT + 10) + +/** An Advanced PDU was sent successfully. + */ +#define BTIF_AVRCP_EVENT_ADV_TX_DONE ( BTIF_AVCTP_LAST_EVENT + 11) + +/* Group: Connection events for establishing and releasing the AVRCP browsing + * channel. The browsing channel is used for the exchange of AVCTP-based + * commands/responses which contain Bluetooth specific media + * operations. + */ +#define BTIF_AVRCP_EVENT_BROWSE_CONNECT ( BTIF_AVCTP_LAST_EVENT + 12) + +/** The application will receive this event when a lower layer connection + * (L2CAP) has been disconnected. Both the target and controller of the + * connection are notified. + */ +#define BTIF_AVRCP_EVENT_BROWSE_DISCONNECT ( BTIF_AVCTP_LAST_EVENT + 13) + +/** remote device is attempting to connect the browsing channel. + */ +#define BTIF_AVRCP_EVENT_BROWSE_CONNECT_IND ( BTIF_AVCTP_LAST_EVENT + 14) + +/* Group: Events for the exchange of browsing channel commands. + */ +#define BTIF_AVRCP_EVENT_BROWSE_REQ ( BTIF_AVCTP_LAST_EVENT + 15) + +#define BTIF_AVRCP_EVENT_BROWSE_INFO ( BTIF_AVCTP_LAST_EVENT + 16) + +#define BTIF_AVRCP_EVENT_BROWSE_RESPONSE ( BTIF_AVCTP_LAST_EVENT + 17) + +#define BTIF_AVRCP_EVENT_BROWSE_CMD_TIMEOUT ( BTIF_AVCTP_LAST_EVENT + 18) + +#define BTIF_AVRCP_EVENT_BROWSE_TX_DONE ( BTIF_AVCTP_LAST_EVENT + 19) + +#define BTIF_AVRCP_EVENT_LAST ( BTIF_AVCTP_LAST_EVENT + 19) + +typedef uint16_t avrcp_role_t; + +/* Controller: Player/recorder features supported ("play" and "stop") */ +#define BTIF_AVRCP_CT_CATEGORY_1 0x0001 + +/* Controller: Monitor/amplifier features supported ("volume up" and "volume down") */ +#define BTIF_AVRCP_CT_CATEGORY_2 0x0002 + +/* Controller: Tuner features supported ("channel up" and "channel down") */ +#define BTIF_AVRCP_CT_CATEGORY_3 0x0004 + +/* Controller: Menu features supported ("root menu", "up", "down", "left", + * "right", and "select") + */ +#define BTIF_AVRCP_CT_CATEGORY_4 0x0008 + +/* Target: Player/recorder features supported ("play" and "stop") */ +#define BTIF_AVRCP_TG_CATEGORY_1 0x0100 + +/* Target: Monitor/amplifier features supported ("volume up" and "volume down") */ +#define BTIF_AVRCP_TG_CATEGORY_2 0x0200 + +/* Target: Tuner features supported ("channel up" and "channel down") */ +#define BTIF_AVRCP_TG_CATEGORY_3 0x0400 + +/* Target: Menu features supported ("root menu", "up", "down", "left", + * "right", and "select") + */ +#define BTIF_AVRCP_TG_CATEGORY_4 0x0800 + +/* Target: Player settings supported */ +#define BTIF_AVRCP_TG_PLAYER_SETTINGS 0x1000 + +/* Target: Group navigation supported */ +#define BTIF_AVRCP_TG_GROUP_NAV 0x2000 + +/* Target: Media browsing is supported */ +#define BTIF_AVRCP_TG_BROWSING 0x4000 + +/* Target: Multiple media players */ +#define BTIF_AVRCP_TG_MULTIPLE_PLAYERS 0x8000 + +typedef uint8_t avrcp_ctype_t; + +#define BTIF_AVRCP_CTYPE_CONTROL BTIF_ AVCTP_CTYPE_CONTROL +#define BTIF_AVRCP_CTYPE_STATUS BTIF_AVCTP_CTYPE_STATUS +#define BTIF_AVRCP_CTYPE_SPECIFIC_INQUIRY BTIF_ AVCTP_CTYPE_SPECIFIC_INQUIRY +#define BTIF_AVRCP_CTYPE_NOTIFY BTIF_AVCTP_CTYPE_NOTIFY +#define BTIF_AVRCP_CTYPE_GENERAL_INQUIRY BTIF_AVCTP_CTYPE_GENERAL_INQUIRY + +#define BTIF_AVRCP_CTYPE_BROWSING BTIF_AVCTP_CTYPE_BROWSING + +typedef avctp_response_t avrcp_response_t; + +#define BTIF_AVRCP_RESPONSE_NOT_IMPLEMENTED BTIF_AVCTP_RESPONSE_NOT_IMPLEMENTED +#define BTIF_AVRCP_RESPONSE_ACCEPTED AVCTP_RESPONSE_ACCEPTED +#define BTIF_AVRCP_RESPONSE_REJECTED AVCTP_RESPONSE_REJECTED +#define BTIF_AVRCP_RESPONSE_IN_TRANSITION AVCTP_RESPONSE_IN_TRANSITION +#define BTIF_AVRCP_RESPONSE_IMPLEMENTED_STABLE AVCTP_RESPONSE_IMPLEMENTED_STABLE +#define BTIF_AVRCP_RESPONSE_CHANGED AVRCP_RESP_CHANGED +#define BTIF_AVRCP_RESPONSE_INTERIM AVCTP_RESPONSE_INTERIM + +#define BTIF_AVRCP_RESPONSE_BROWSING AVCTP_RESPONSE_BROWSING + +#define BTIF_AVRCP_RESPONSE_SKIPPED 0xF0 + +#define BTIF_AVRCP_RESPONSE_TIMEOUT 0xF1 + +typedef uint8_t avrcp_opcode_t; + +#define BTIF_AVRCP_OPCODE_VENDOR_DEPENDENT AVRCP_VENDOR_DEP_IND +#define BTIF_AVRCP_OPCODE_UNIT_INFO AVRCP_UINT_INFO_IND +#define BTIF_AVRCP_OPCODE_SUBUNIT_INFO AVRCP_SUBUNIT_INFO_IND +#define BTIF_AVRCP_OPCODE_PASS_THROUGH AVRCP_PASSTHROUGH_IND + +typedef avctp_cmdframe_t avrcp_cmdframe_t; +typedef avctp_rspframe_t avrcp_rspframe_t; + +typedef uint8_t avrcp_subunit_type_t; + +#define BTIF_AVRCP_SUBUNIT_PANEL 0x09 +#define BTIF_AVRCP_SUBUNIT_UNIT 0x1F + +typedef U16 avrcp_panel_operation_t; + +#define BTIF_AVRCP_POP_SELECT 0x0000 +#define BTIF_AVRCP_POP_UP 0x0001 +#define BTIF_AVRCP_POP_DOWN 0x0002 +#define BTIF_AVRCP_POP_LEFT 0x0003 +#define BTIF_AVRCP_POP_RIGHT 0x0004 +#define BTIF_AVRCP_POP_RIGHT_UP 0x0005 +#define BTIF_AVRCP_POP_RIGHT_DOWN 0x0006 +#define BTIF_AVRCP_POP_LEFT_UP 0x0007 +#define BTIF_AVRCP_POP_LEFT_DOWN 0x0008 +#define BTIF_AVRCP_POP_ROOT_MENU 0x0009 +#define BTIF_AVRCP_POP_SETUP_MENU 0x000A +#define BTIF_AVRCP_POP_CONTENTS_MENU 0x000B +#define BTIF_AVRCP_POP_FAVORITE_MENU 0x000C +#define BTIF_AVRCP_POP_EXIT 0x000D + +#define BTIF_AVRCP_POP_0 0x0020 +#define BTIF_AVRCP_POP_1 0x0021 +#define BTIF_AVRCP_POP_2 0x0022 +#define BTIF_AVRCP_POP_3 0x0023 +#define BTIF_AVRCP_POP_4 0x0024 +#define BTIF_AVRCP_POP_5 0x0025 +#define BTIF_AVRCP_POP_6 0x0026 +#define BTIF_AVRCP_POP_7 0x0027 +#define BTIF_AVRCP_POP_8 0x0028 +#define BTIF_AVRCP_POP_9 0x0029 +#define BTIF_AVRCP_POP_DOT 0x002A +#define BTIF_AVRCP_POP_ENTER 0x002B +#define BTIF_AVRCP_POP_CLEAR 0x002C + +#define BTIF_AVRCP_POP_CHANNEL_UP 0x0030 +#define BTIF_AVRCP_POP_CHANNEL_DOWN 0x0031 +#define BTIF_AVRCP_POP_PREVIOUS_CHANNEL 0x0032 +#define BTIF_AVRCP_POP_SOUND_SELECT 0x0033 +#define BTIF_AVRCP_POP_INPUT_SELECT 0x0034 +#define BTIF_AVRCP_POP_DISPLAY_INFO 0x0035 +#define BTIF_AVRCP_POP_HELP 0x0036 +#define BTIF_AVRCP_POP_PAGE_UP 0x0037 +#define BTIF_AVRCP_POP_PAGE_DOWN 0x0038 + +#define BTIF_AVRCP_POP_POWER 0x0040 +#define BTIF_AVRCP_POP_VOLUME_UP 0x0041 +#define BTIF_AVRCP_POP_VOLUME_DOWN 0x0042 +#define BTIF_AVRCP_POP_MUTE 0x0043 +#define BTIF_AVRCP_POP_PLAY 0x0044 +#define BTIF_AVRCP_POP_STOP 0x0045 +#define BTIF_AVRCP_POP_PAUSE 0x0046 +#define BTIF_AVRCP_POP_RECORD 0x0047 +#define BTIF_AVRCP_POP_REWIND 0x0048 +#define BTIF_AVRCP_POP_FAST_FORWARD 0x0049 +#define BTIF_AVRCP_POP_EJECT 0x004A +#define BTIF_AVRCP_POP_FORWARD 0x004B +#define BTIF_AVRCP_POP_BACKWARD 0x004C + +#define BTIF_AVRCP_POP_ANGLE 0x0050 +#define BTIF_AVRCP_POP_SUBPICTURE 0x0051 + +#define BTIF_AVRCP_POP_F1 0x0071 +#define BTIF_AVRCP_POP_F2 0x0072 +#define BTIF_AVRCP_POP_F3 0x0073 +#define BTIF_AVRCP_POP_F4 0x0074 +#define BTIF_AVRCP_POP_F5 0x0075 + +#define BTIF_AVRCP_POP_VENDOR_UNIQUE 0x007E + +#define BTIF_AVRCP_POP_NEXT_GROUP 0x017E +#define BTIF_AVRCP_POP_PREV_GROUP 0x027E + +#define BTIF_AVRCP_POP_RESERVED 0x007F + +#define BTIF_AVRCP_NUM_EVENTS 13 +#define BTIF_AVRCP_MAX_NOTIFICATIONS 15 + +#define BTIF_AVRCP_SUBUNIT_OP_QUEUE_MAX 15 + +/*--------------------------------------------------------------------------- + * avrcp operation code + */ +typedef U8 btif_avrcp_operation_t; + +#define BTIF_AVRCP_OP_GET_CAPABILITIES 0x10 + +#define BTIF_AVRCP_OP_LIST_PLAYER_SETTING_ATTRIBS 0x11 + +#define BTIF_AVRCP_OP_LIST_PLAYER_SETTING_VALUES 0x12 + +#define BTIF_AVRCP_OP_GET_PLAYER_SETTING_VALUE 0x13 + +#define BTIF_AVRCP_OP_SET_PLAYER_SETTING_VALUE 0x14 + +#define BTIF_AVRCP_OP_GET_PLAYER_SETTING_ATTR_TEXT 0x15 + +#define BTIF_AVRCP_OP_GET_PLAYER_SETTING_VALUE_TEXT 0x16 + +#define BTIF_AVRCP_OP_INFORM_DISP_CHAR_SET 0x17 + +#define BTIF_AVRCP_OP_INFORM_BATT_STATUS 0x18 + +#define BTIF_AVRCP_OP_GET_MEDIA_INFO 0x20 + +#define BTIF_AVRCP_OP_GET_PLAY_STATUS 0x30 + +#define BTIF_AVRCP_OP_REGISTER_NOTIFY 0x31 + +#define BTIF_AVRCP_OP_REQUEST_CONT_RESP 0x40 + +#define BTIF_AVRCP_OP_ABORT_CONT_RESP 0x41 + +#define BTIF_AVRCP_OP_SET_ABSOLUTE_VOLUME 0x50 + +#define BTIF_AVRCP_OP_SET_ADDRESSED_PLAYER 0x60 + +#define BTIF_AVRCP_OP_SET_BROWSED_PLAYER 0x70 + +#define BTIF_AVRCP_OP_GET_FOLDER_ITEMS 0x71 + +#define BTIF_AVRCP_OP_CHANGE_PATH 0x72 + +#define BTIF_AVRCP_OP_GET_ITEM_ATTRIBUTES 0x73 + +#define BTIF_AVRCP_OP_PLAY_ITEM 0x74 + +#define BTIF_AVRCP_OP_SEARCH 0x80 + +#define BTIF_AVRCP_OP_ADD_TO_NOW_PLAYING 0x90 + +#define BTIF_AVRCP_OP_GENERAL_REJECT 0xA0 + +#define BTIF_AVRCP_OP_CUSTOM_CMD 0xF0 + +typedef uint8_t avrcp_error_code_t; + +#define BTIF_AVRCP_INVALID_CMD_ERR 0x00 +#define BTIF_AVRCP_INVALID_PARM_ERR 0x01 +#define BTIF_AVRCP_PARM_NOT_FOUND_ERR 0x02 +#define BTIF_AVRCP_INTERNAL_ERROR_ERR 0x03 +#define BTIF_AVRCP_NO_ERROR_ERR 0x04 +#define BTIF_AVRCP_UIDS_CHANGED_ERR 0x05 +#define BTIF_AVRCP_ERR_UNKNOWN_ERROR 0x06 +#define BTIF_AVRCP_ERR_INVALID_DIRECTION 0x07 +#define BTIF_AVRCP_ERR_NON_DIRECTORY 0x08 +#define BTIF_AVRCP_ERR_DOES_NOT_EXIST 0x09 +#define BTIF_AVRCP_ERR_INVALID_SCOPE 0x0A +#define BTIF_AVRCP_ERR_OUT_OF_BOUNDS 0x0B +#define BTIF_AVRCP_ERR_IS_DIRECTORY 0x0C +#define BTIF_AVRCP_ERR_MEDIA_IN_USE 0x0D +#define BTIF_AVRCP_ERR_NOW_PLAYING_FULL 0x0E +#define BTIF_AVRCP_ERR_NO_SEARCH_SUPPORT 0x0F +#define BTIF_AVRCP_ERR_SEARCH_IN_PROGRESS 0x10 +#define BTIF_AVRCP_ERR_INVALID_PLAYER_ID 0x11 +#define BTIF_AVRCP_ERR_NOT_BROWSABLE 0x12 +#define BTIF_AVRCP_ERR_NOT_ADDRESSED 0x13 +#define BTIF_AVRCP_ERR_NO_SEARCH_RESULTS 0x14 +#define BTIF_AVRCP_ERR_NO_AVAIL_PLAYERS 0x15 +#define BTIF_AVRCP_ERR_ADDR_PLAYER_CHANGED 0x16 + +/*--------------------------------------------------------------------------- + * event Id + */ +typedef uint8_t avrcp_event_Id_t; + +#define BTIF_AVRCP_EID_MEDIA_STATUS_CHANGED 0x01 /* Change in media status */ + +#define BTIF_AVRCP_EID_TRACK_CHANGED 0x02 /* Current track changed */ + +#define BTIF_AVRCP_EID_TRACK_END 0x03 /* Reached end of track */ + +#define BTIF_AVRCP_EID_TRACK_START 0x04 /* Reached track start */ + +#define BTIF_AVRCP_EID_PLAY_POS_CHANGED 0x05 /* Change in playback position. + * Returned after the specified + * playback notification change + * notification interval. + */ + +#define BTIF_AVRCP_EID_BATT_STATUS_CHANGED 0x06 /* Change in battery status */ +#define BTIF_AVRCP_EID_SYS_STATUS_CHANGED 0x07 /* Change in system status */ +#define BTIF_AVRCP_EID_APP_SETTING_CHANGED 0x08 /* Change in player + * application setting + */ + +#define BTIF_AVRCP_EID_NOW_PLAYING_CONTENT_CHANGED 0x09 /* Contents of the now playing + * list have changed + */ + +#define BTIF_AVRCP_EID_AVAILABLE_PLAYERS_CHANGED 0x0A /* The available players have + * changed + */ + +#define BTIF_AVRCP_EID_ADDRESSED_PLAYER_CHANGED 0x0B /* The addressed player has + * changed + */ + +#define BTIF_AVRCP_EID_UIDS_CHANGED 0x0C /* The UIDS have changed */ + +#define BTIF_AVRCP_EID_VOLUME_CHANGED 0x0D /* The volume was changed */ + +#define BTIF_AVRCP_EID_FLAG_INTERIM 0x80 /* Used Internally */ + +/*--------------------------------------------------------------------------- + * even mask + */ +typedef uint16_t avrcp_event_mask_t; + +#define BTIF_AVRCP_ENABLE_PLAY_STATUS_CHANGED 0x0001 /* Change in playback + * status + */ +#define BTIF_AVRCP_ENABLE_MEDIA_STATUS_CHANGED 0x0001 /* Alias */ +#define BTIF_AVRCP_ENABLE_TRACK_CHANGED 0x0002 /* Current track changed */ +#define BTIF_AVRCP_ENABLE_TRACK_END 0x0004 /* Reached end of track */ +#define BTIF_AVRCP_ENABLE_TRACK_START 0x0008 /* Reached track start */ +#define BTIF_AVRCP_ENABLE_PLAY_POS_CHANGED 0x0010 /* Change in playback + * position + */ +#define BTIF_AVRCP_ENABLE_BATT_STATUS_CHANGED 0x0020 /* Change in battery + * status + */ +#define BTIF_AVRCP_ENABLE_SYS_STATUS_CHANGED 0x0040 /* Change in system status */ +#define BTIF_AVRCP_ENABLE_APP_SETTING_CHANGED 0x0080 /* Change in player + * application setting + */ + +#define BTIF_AVRCP_ENABLE_NOW_PLAYING_CHANGED 0x0100 /* Change in the now + * playing list + */ +#define BTIF_AVRCP_ENABLE_AVAIL_PLAYERS_CHANGED 0x0200 /* Available players + * changed + */ +#define BTIF_AVRCP_ENABLE_ADDRESSED_PLAYER_CHANGED 0x0400 /* Addressed player changed */ +#define BTIF_AVRCP_ENABLE_UIDS_CHANGED 0x0800 /* UIDS changed */ +#define BTIF_AVRCP_ENABLE_VOLUME_CHANGED 0x1000 /* Volume Changed */ + +typedef uint8_t btif_avrcp_capabilityId; + +#define BTIF_AVRCP_CAPABILITY_COMPANY_ID 2 +#define BTIF_AVRCP_CAPABILITY_EVENTS_SUPPORTED 3 + +/*--------------------------------------------------------------------------- + * player attrId type + */ +typedef uint8_t avrcp_playerAttrId; + +#define BTIF_AVRCP_PLAYER_EQ_STATUS 1 /* Player equalizer status */ +#define BTIF_AVRCP_PLAYER_REPEAT_STATUS 2 /* Player repeat status */ +#define BTIF_AVRCP_PLAYER_SHUFFLE_STATUS 3 /* Player Shuffle status */ +#define BTIF_AVRCP_PLAYER_SCAN_STATUS 4 /* Player scan status */ + +/*--------------------------------------------------------------------------- + * playerattrId mask type + */ +typedef uint16_t avrcp_player_attrId_mask_t; + +#define BTIF_AVRCP_ENABLE_PLAYER_EQ_STATUS 0x0001 +#define BTIF_AVRCP_ENABLE_PLAYER_REPEAT_STATUS 0x0002 +#define BTIF_AVRCP_ENABLE_PLAYER_SHUFFLE_STATUS 0x0004 +#define BTIF_AVRCP_ENABLE_PLAYER_SCAN_STATUS 0x0008 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_5 0x0010 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_6 0x0020 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_7 0x0040 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_8 0x0080 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_9 0x0100 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_10 0x0200 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_11 0x0400 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_12 0x0800 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_13 0x1000 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_14 0x2000 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_15 0x4000 +#define BTIF_AVRCP_ENABLE_PLAYER_EXTENSION_ID_16 0x8000 + +#ifndef BTIF_AVRCP_MAX_FOLDER_DEPTH +#define BTIF_AVRCP_MAX_FOLDER_DEPTH 10 +#endif + +typedef uint8_t avrcp_eq_value_t; + +#define BTIF_AVRCP_EQ_OFF 1 +#define BTIF_AVRCP_EQ_ON 2 + +typedef uint8_t avrcp_repeat_value_t; + +#define BTIF_AVRCP_REPEAT_OFF 1 +#define BTIF_AVRCP_REPEAT_SINGLE 2 +#define BTIF_AVRCP_REPEAT_ALL 3 +#define BTIF_AVRCP_REPEAT_GROUP 4 + +typedef uint8_t avrcp_shuffle_value_t; + +#define BTIF_AVRCP_SHUFFLE_OFF 1 +#define BTIF_AVRCP_SHUFFLE_ALL 2 +#define BTIF_AVRCP_SHUFFLE_GROUP 3 + +typedef uint8_t avrcp_scan_value_t; + +#define BTIF_AVRCP_SCAN_OFF 1 +#define BTIF_AVRCP_SCAN_ALL 2 +#define BTIF_AVRCP_SCAN_GROUP 3 + +typedef uint8_t avrcp_ext_value_t; + +typedef uint8_t avrcp_battery_status_t; + +#define BTIF_AVRCP_BATT_STATUS_NORMAL 0 +#define BTIF_AVRCP_BATT_STATUS_WARNING 1 +#define BTIF_AVRCP_BATT_STATUS_CRITICAL 2 +#define BTIF_AVRCP_BATT_STATUS_EXTERNAL 3 +#define BTIF_AVRCP_BATT_STATUS_FULL_CHARGE 4 + +typedef uint8_t avrcp_system_status_t; + +#define BTIF_AVRCP_SYS_POWER_ON 0 +#define BTIF_AVRCP_SYS_POWER_OFF 1 +#define BTIF_AVRCP_SYS_UNPLUGGED 2 + +typedef uint32_t avrcp_media_attrId_t; + +#define BTIF_AVRCP_MEDIA_ATTR_TITLE 0x00000001 +#define BTIF_AVRCP_MEDIA_ATTR_ARTIST 0x00000002 +#define BTIF_AVRCP_MEDIA_ATTR_ALBUM 0x00000003 +#define BTIF_AVRCP_MEDIA_ATTR_TRACK 0x00000004 +#define BTIF_AVRCP_MEDIA_ATTR_NUM_TRACKS 0x00000005 +#define BTIF_AVRCP_MEDIA_ATTR_GENRE 0x00000006 +#define BTIF_AVRCP_MEDIA_ATTR_DURATION 0x00000007 + +typedef uint32_t avrcp_media_attrId_mask_t; + +#define BTIF_AVRCP_ENABLE_MEDIA_ATTR_TITLE 0x01 +#define BTIF_AVRCP_ENABLE_MEDIA_ATTR_ARTIST 0x02 +#define BTIF_AVRCP_ENABLE_MEDIA_ATTR_ALBUM 0x04 +#define BTIF_AVRCP_ENABLE_MEDIA_ATTR_TRACK 0x08 +#define BTIF_AVRCP_ENABLE_MEDIA_ATTR_NUM_TRACKS 0x10 +#define BTIF_AVRCP_ENABLE_MEDIA_ATTR_GENRE 0x20 +#define BTIF_AVRCP_ENABLE_MEDIA_ATTR_DURATION 0x40 + +typedef uint8_t avrcp_media_status_t; + +#define BTIF_AVRCP_MEDIA_STOPPED 0x00 +#define BTIF_AVRCP_MEDIA_PLAYING 0x01 +#define BTIF_AVRCP_MEDIA_PAUSED 0x02 +#define BTIF_AVRCP_MEDIA_FWD_SEEK 0x03 +#define BTIF_AVRCP_MEDIA_REV_SEEK 0x04 +#define BTIF_AVRCP_MEDIA_ERROR 0xFF + +typedef uint16_t avrcp_version_t; + +/* Unable to determine the Hands Free Profile version that is supported */ +#define BTIF_AVRCP_VERSION_UNKNOWN 0x0000 + +/* Supports Version 1.0 of the AVRCP Profile */ +#define BTIF_AVRCP_VERSION_1_0 0x0100 + +/* Supports Version 1.3 of the AVRCP Profile */ +#define BTIF_AVRCP_VERSION_1_3 0x0103 + +/* Supports Version 1.4 of the AVRCP Profile */ +#define BTIF_AVRCP_VERSION_1_4 0x0104 + +typedef uint16_t avrcp_features_t; + +/* Player/recorder features supported ("play" and "stop") */ +#define BTIF_AVRCP_FEATURES_CATEGORY_1 0x0001 + +/* Monitor/amplifier features supported ("volume up" and "volume down") */ +#define BTIF_AVRCP_FEATURES_CATEGORY_2 0x0002 + +/* Tuner features supported ("channel up" and "channel down") */ +#define BTIF_AVRCP_FEATURES_CATEGORY_3 0x0004 + +/* Menu features supported ("root menu", "up", "down", "left", "right", and + * "select") + */ +#define BTIF_AVRCP_FEATURES_CATEGORY_4 0x0008 + +/* Player settings supported */ +#define BTIF_AVRCP_FEATURES_PLAYER_SETTINGS 0x0010 + +/* Group navigation supported */ +#define BTIF_AVRCP_FEATURES_GROUP_NAV 0x0020 + +#define BTIF_AVRCP_FEATURES_BROWSING 0x0040 + +#define BTIF_AVRCP_FEATURES_MULTIPLE_PLAYERS 0x0080 + +typedef uint8_t avrcp_maj_player_type_t; + +#define BTIF_AVRCP_MAJ_PLAYER_AUDIO 0x01 +#define BTIF_AVRCP_MAJ_PLAYER_VIDEO 0x02 +#define BTIF_AVRCP_MAJ_PLAYER_AUD_BCAST 0x04 +#define BTIF_AVRCP_MAJ_PLAYER_VID_BCAST 0x08 + +typedef uint32_t avrcp_player_sub_type_t; + +#define BTIF_AVRCP_PLAYER_SUB_AUDIO_BOOK 0x00000001 +#define BTIF_AVRCP_PLAYER_SUB_PODCAST 0x00000002 + +typedef uint8_t avrcp_scope_t; + +#define BTIF_AVRCP_SCOPE_MEDIA_PLAYER_LIST 0x00 +#define BTIF_AVRCP_SCOPE_VIRTUAL_FILESYS 0x01 +#define BTIF_AVRCP_SCOPE_SEARCH 0x02 +#define BTIF_AVRCP_SCOPE_NOW_PLAYING 0x03 + +typedef uint8_t avrcp_chg_path_direction_t; + +#define BTIF_AVRCP_DIR_UP 0x00 +#define BTIF_AVRCP_DIR_DOWN 0x01 + +typedef uint8_t avrcp_plyr_featr_byte_t; + +/* Byte 0 */ + +#define BTIF_AVRCP_BRWS_0_FEAT_SELECT 0x01 +#define BTIF_AVRCP_BRWS_0_FEAT_UP 0x02 +#define BTIF_AVRCP_BRWS_0_FEAT_DOWN 0x04 +#define BTIF_AVRCP_BRWS_0_FEAT_LEFT 0x08 +#define BTIF_AVRCP_BRWS_0_FEAT_RIGHT 0x10 +#define BTIF_AVRCP_BRWS_0_FEAT_RIGHT_UP 0x20 +#define BTIF_AVRCP_BRWS_0_FEAT_RIGHT_DOWN 0x40 +#define BTIF_AVRCP_BRWS_0_FEAT_LEFT_UP 0x80 + +/* Byte 1 */ + +#define BTIF_AVRCP_BRWS_1_FEAT_LEFT_DOWN 0x01 +#define BTIF_AVRCP_BRWS_1_FEAT_ROOT_MENU 0x02 +#define BTIF_AVRCP_BRWS_1_FEAT_SETUP_MENU 0x04 +#define BTIF_AVRCP_BRWS_1_FEAT_CONTENTS_MENU 0x08 +#define BTIF_AVRCP_BRWS_1_FEAT_FAVORITE_MENU 0x10 +#define BTIF_AVRCP_BRWS_1_FEAT_EXIT 0x20 +#define BTIF_AVRCP_BRWS_1_FEAT_0 0x40 +#define BTIF_AVRCP_BRWS_1_FEAT_1 0x80 + +/* Byte 2 */ + +#define BTIF_AVRCP_BRWS_2_FEAT_2 0x01 +#define BTIF_AVRCP_BRWS_2_FEAT_3 0x02 +#define BTIF_AVRCP_BRWS_2_FEAT_4 0x04 +#define BTIF_AVRCP_BRWS_2_FEAT_5 0x08 +#define BTIF_AVRCP_BRWS_2_FEAT_6 0x10 +#define BTIF_AVRCP_BRWS_2_FEAT_7 0x20 +#define BTIF_AVRCP_BRWS_2_FEAT_8 0x40 +#define BTIF_AVRCP_BRWS_2_FEAT_9 0x80 + +/* Byte 3 */ + +#define BTIF_AVRCP_BRWS_3_FEAT_DOT 0x01 +#define BTIF_AVRCP_BRWS_3_FEAT_ENTER 0x02 +#define BTIF_AVRCP_BRWS_3_FEAT_CLEAR 0x04 +#define BTIF_AVRCP_BRWS_3_FEAT_CHNL_UP 0x08 +#define BTIF_AVRCP_BRWS_3_FEAT_CHNL_DOWN 0x10 +#define BTIF_AVRCP_BRWS_3_FEAT_PREV_CHNL 0x20 +#define BTIF_AVRCP_BRWS_3_FEAT_SOUND_SEL 0x40 +#define BTIF_AVRCP_BRWS_3_FEAT_INPUT_SEL 0x80 + +/* Byte 4 */ + +#define BTIF_AVRCP_BRWS_3_FEAT_DISPLAY_INFO 0x01 +#define BTIF_AVRCP_BRWS_4_FEAT_HELP 0x02 +#define BTIF_AVRCP_BRWS_4_FEAT_PG_UP 0x04 +#define BTIF_AVRCP_BRWS_4_FEAT_PG_DOWN 0x08 +#define BTIF_AVRCP_BRWS_4_FEAT_POWER 0x10 +#define BTIF_AVRCP_BRWS_4_FEAT_VOL_UP 0x20 +#define BTIF_AVRCP_BRWS_4_FEAT_VOL_DOWN 0x40 +#define BTIF_AVRCP_BRWS_4_FEAT_MUTE 0x80 + +/* Byte 5 */ + +#define BTIF_AVRCP_BRWS_5_FEAT_PLAY 0x01 +#define BTIF_AVRCP_BRWS_5_FEAT_STOP 0x02 +#define BTIF_AVRCP_BRWS_5_FEAT_PAUSE 0x04 +#define BTIF_AVRCP_BRWS_5_FEAT_RECORD 0x08 +#define BTIF_AVRCP_BRWS_5_FEAT_REWIND 0x10 +#define BTIF_AVRCP_BRWS_5_FEAT_FF 0x20 +#define BTIF_AVRCP_BRWS_5_FEAT_EJECT 0x40 +#define BTIF_AVRCP_BRWS_5_FEAT_FORWARD 0x80 + +/* Byte 6 */ + +#define BTIF_AVRCP_BRWS_6_FEAT_BACKWARD 0x01 +#define BTIF_AVRCP_BRWS_6_FEAT_ANGLE 0x02 +#define BTIF_AVRCP_BRWS_6_FEAT_SUBPIC 0x04 +#define BTIF_AVRCP_BRWS_6_FEAT_F1 0x08 +#define BTIF_AVRCP_BRWS_6_FEAT_F2 0x10 +#define BTIF_AVRCP_BRWS_6_FEAT_F3 0x20 +#define BTIF_AVRCP_BRWS_6_FEAT_F4 0x40 +#define BTIF_AVRCP_BRWS_6_FEAT_F5 0x80 + +/* Byte 7 */ + +#define BTIF_AVRCP_BRWS_7_FEAT_VENDOR_UNIQUE 0x01 +#define BTIF_AVRCP_BRWS_7_FEAT_GROUP_NAV 0x02 +#define BTIF_AVRCP_BRWS_7_FEAT_ADVANCED_CTRL 0x04 +#define BTIF_AVRCP_BRWS_7_FEAT_BROWSING 0x08 +#define BTIF_AVRCP_BRWS_7_FEAT_SEARCHING 0x10 +#define BTIF_AVRCP_BRWS_7_FEAT_ADD_TO_PLAYING 0x20 +#define BTIF_AVRCP_BRWS_7_FEAT_UIDS_UNIQUE 0x40 +#define BTIF_AVRCP_BRWS_7_FEAT_BRWS_WHEN_ADDRESSED 0x80 + +/* Byte 8 */ + +#define BTIF_AVRCP_BRWS_8_SEARCH_WHEN_ADDRESSED 0x01 +#define BTIF_AVRCP_BRWS_8_NOW_PLAYING 0x02 +#define BTIF_AVRCP_BRWS_8_UID_PERSISTENT 0x04 + +typedef uint8_t avrcp_item_type_t; + +#define BTIF_AVRCP_ITEM_MEDIA_PLAYER 0x01 +#define BTIF_AVRCP_ITEM_FOLDER 0x02 +#define BTIF_AVRCP_ITEM_MEDIA_ELEMENT 0x03 + +typedef uint8_t avrcp_folder_type_t; + +#define BTIF_AVRCP_FOLDER_TYPE_MIXED 0x00 +#define BTIF_AVRCP_FOLDER_TYPE_TITLES 0x01 +#define BTIF_AVRCP_FOLDER_TYPE_ALBUMS 0x02 +#define BTIF_AVRCP_FOLDER_TYPE_ARTISTS 0x03 +#define BTIF_AVRCP_FOLDER_TYPE_GENRES 0x04 +#define BTIF_AVRCP_FOLDER_TYPE_PLAYLISTS 0x05 +#define BTIF_AVRCP_FOLDER_TYPE_YEARS 0x06 + +typedef uint8_t avrcp_is_playable_t; +typedef uint16_t avrcp_capabilityId_t; +typedef void avrcp_advanced_pdu_t; + +#define BTIF_AVRCP_IS_NOT_PLAYABLE 0x00 +#define BTIF_AVRCP_IS_PLAYABLE 0x01 + +typedef uint8_t avrcp_media_type_t; + +#define BTIF_AVRCP_MEDIA_TYPE_AUDIO 0x00 +#define BTIF_AVRCP_MEIDA_TYPE_VIDEO 0x01 + +#define BTIF_AVCTP_RESPONSE_INTERIM 0x0F + +typedef struct { + + /* Index 0 == Off, Index 1 == On */ + const char *string[2]; + uint8_t len[2]; +} avrcp_eq_string_t; + +typedef struct { + + /* Index 0 == Off, Index 1 == Single, Index 2 == All, Index 3 == Group */ + const char *string[4]; + uint8_t len[4]; +} avrcp_repeat_string_t; + +typedef struct { + + /* Index 0 == Off, Index 1 == All, Index 2 == Group */ + const char *string[3]; + uint8_t len[3]; +} avrcp_shuffle_string_t; + +typedef struct { + + /* Index 0 == Off, Index 1 == All, Index 2 == Group */ + const char *string[3]; + uint8_t len[3]; +} avrcp_scan_string_t; + +#ifndef BTIF_AVRCP_MAX_PLAYER_STRINGS +#define BTIF_AVRCP_MAX_PLAYER_STRINGS 5 +#endif +/*-------------------------------------------------------------------------- + * NUM PLAYER SETTINGS constant + */ + +#define BTIF_AVRCP_PANEL_STATE_NONE 0 + +#define BTIF_AVRCP_PANEL_STATE_C_IDLE 1 +#define BTIF_AVRCP_PANEL_STATE_C_PRESS 2 +#define BTIF_AVRCP_PANEL_STATE_C_PRESS_R 3 +#define BTIF_AVRCP_PANEL_STATE_C_RELEASE 4 +#define BTIF_AVRCP_PANEL_STATE_C_SKIP 5 + +#define BTIF_AVRCP_PANEL_STATE_T_IDLE 101 +#define BTIF_AVRCP_PANEL_STATE_T_PRESS 102 +#define BTIF_AVRCP_PANEL_STATE_T_HOLD 103 + +typedef struct { + + /* Number of extended player settings */ + uint8_t numStrings; + const char *string[BTIF_AVRCP_MAX_PLAYER_STRINGS]; /* The player setting string */ + uint8_t len[BTIF_AVRCP_MAX_PLAYER_STRINGS]; /* The player setting string length */ +} avrcp_ext_string_t; +typedef uint8_t avrcp_player_attrId_t; + +typedef struct { + avrcp_player_attrId_t attrId; /* Media Player Attribute ID */ + union { + avrcp_eq_value_t eq; + avrcp_repeat_value_t repeat; + avrcp_shuffle_value_t shuffle; + avrcp_scan_value_t scan; + avrcp_ext_value_t extValue; + uint8_t value; /* Used Internally */ + } setting; +} avrcp_player_setting_t; + +typedef struct { + const char *attrString; /* Media Player Attribute Text */ + uint8_t attrLen; /* Length of the Attribute Text */ + union { + avrcp_eq_string_t eq; /* Equalizer status */ + avrcp_repeat_string_t repeat; /* Repeat mode status */ + avrcp_shuffle_string_t shuffle; /* Shuffle mode status */ + avrcp_scan_string_t scan; /* Scan mode status */ + avrcp_ext_string_t ext; /* Extended settings status */ + } setting; +} avrcp_player_strings_t; + +typedef struct { + avrcp_media_attrId_t attrId; /* Media element attribute ID */ + const char *string; /* The media element */ + uint16_t length; /* Length of the media element */ +} avrcp_media_info_t; + +typedef struct { + uint8_t numCharSets; + uint16_t charSets[BTIF_AVRCP_MAX_CHAR_SETS]; +} avrcp_char_sets_t; + +typedef struct { + uint32_t length; + + uint32_t position; + avrcp_media_status_t mediaStatus; +} avrcp_media_play_status_t; + +typedef struct { + uint16_t nameLen; + const char *name; +} avrcp_folder_t; + +typedef struct { + + /* Used Internally */ + list_entry_t node; + + /* Used Internally */ + uint16_t playerId; + + /* Major Player Type */ + avrcp_maj_player_type_t majorType; + + /* Player Sub Type */ + avrcp_player_sub_type_t subType; + + /* Current media play status */ + avrcp_media_status_t mediaStatus; + + /* Player feature bitmask */ + avrcp_plyr_featr_byte_t features[16]; + + /* Displayable character set */ + uint16_t charSet; + + /* Player name length */ + uint16_t nameLen; + + /* Player name */ + const char *name; + + /* Folder depth */ + uint16_t folderDepth; + + /* Current folder */ + avrcp_folder_t folder[BTIF_AVRCP_MAX_FOLDER_DEPTH]; + + /* Number of items in the current folder */ + uint32_t numItems; +} avrcp_media_player_item_t; +typedef uint16_t avrcp_event_mask_t; +typedef uint8_t avrcp_operation_t; + +typedef struct _AvrcpFolderItem { + + /* The UID of this media element */ + uint8_t uid[8]; + + /* Folder Type */ + avrcp_folder_type_t folderType; + + /* Is Playable Flag */ + avrcp_is_playable_t isPlayable; + + /* Character Set */ + uint16_t charSet; + + /* The name length of this media element */ + uint16_t nameLen; + + /* The name of this media element */ + uint8_t *name; +} avrcp_folder_item_t; + +typedef struct { + + /* Attribute ID */ + avrcp_media_attrId_t attrId; + + /* Character Set */ + uint16_t charSet; + + /* Attribute Length */ + uint16_t valueLen; + + /* Attribute Name */ + uint8_t *value; +} avrcp_media_attribute_t; + +typedef struct { + + /* The UID of this media element */ + uint8_t uid[8]; + + /* Media type (audio or video) */ + avrcp_media_type_t mediaType; + + /* Character Set */ + uint16_t charSet; + + /* The name length of this media element */ + uint16_t nameLen; + + /* The name of this media element */ + uint8_t *name; + + /* Number of media attributes */ + uint8_t numAttrs; + + /* Media Attributes */ + avrcp_media_attribute_t attrs[BTIF_AVRCP_NUM_MEDIA_ATTRIBUTES]; +} avrcp_media_element_item_t; + +typedef uint8_t avrcp_Item_type_t; + +typedef struct { + + /* Media Item Type */ + avrcp_Item_type_t itemType; + + /* The Media Item */ + union { + avrcp_media_player_item_t player; + avrcp_folder_item_t folder; + avrcp_media_element_item_t element; + } item; +} avrcp_media_item_t; + +typedef struct { + + /* The most significant 32 bits of the track index information. */ + uint32_t msU32; + + /* The least significant 32 bits of the track index information. */ + uint32_t lsU32; +} avrcp_track_struct_t; + +typedef struct { + + /* Transaction ID of the request */ + uint32_t transId; + union { + + /* Contains an item to be played on the addressed media player. This + * is valid when "advOp" is set to AVRCP_OP_PLAY_ITEM or + * AVRCP_OP_ADD_TO_NOW_PLAYING. + */ + struct { + avrcp_scope_t scope; + uint8_t uid[8]; + uint16_t uidCounter; + } item; + } p; +} avrcp_adv_req_parms_t; + +typedef union { + + /* The value of each player setting. This is valid when "advOp" is set + * to AVRCP_OP_SET_PLAYER_SETTING_VALUE. + */ + avrcp_player_setting_t playerSetting; + struct { + + /* Bitmask that describes which + * attributes are being reported + */ + avrcp_player_attrId_mask_t attrMask; + + /* The equalizer setting. */ + avrcp_eq_value_t eq; + + /* The repeat setting. */ + avrcp_repeat_value_t repeat; + + /* The shuffle setting. */ + avrcp_shuffle_value_t shuffle; + + /* The scan setting. */ + avrcp_scan_value_t scan; + +#if BTIF_AVRCP_NUM_PLAYER_SETTINGS > 4 + /* Extended player setting. */ + avrcp_ext_value_t extValue[BTIF_AVRCP_NUM_PLAYER_SETTINGS - 4]; + +#endif /* */ + } setting; + + /* The list of character sets displayable on the controller. + * This is valid when "advOp" is set to AVRCP_OP_INFORM_DISP_CHAR_SET. The + * default is 106 (UTF-8). + */ + avrcp_char_sets_t charSet; + + /* The battery status of the controller. + * This is valid when "advOp" is set to AVRCP_OP_INFORM_BATT_STATUS. + */ + avrcp_battery_status_t battStatus; + +#if BTIF_AVRCP_VERSION_1_3_ONLY == BTIF_DISABLED + /* The Absolute Volume + * This is valid when "advOp" is set to AVRCP_OP_SET_ABSOLUTE_VOLUME. + */ + uint8_t volume; + + /* The addressed player + * This is valid when "advOp" is set to AVRCP_OP_SET_ADDRESSED_PLAYER. + */ + avrcp_media_player_item_t *addrPlayer; + +#endif /* BTIF_AVRCP_VERSION_1_3_ONLY == BTIF_DISABLED */ +} avrcp_adv_inf_parms_t; + +typedef struct { + avrcp_player_attrId_t attrId; + uint16_t charSet; + uint8_t length; + const char *string; +} avrcp_player_attrib_t; + +typedef struct { + uint8_t valueId; + uint16_t charSet; + uint8_t length; + const char *string; +} avrcp_player_settings_t; + +typedef struct { + U32 attrId; + uint16_t charSet; + uint16_t length; + const char *string; +} avrcp_media_attr_t; +typedef uint16_t avrcp_player_attrId_mask_t; + +typedef struct { + uint32_t length; + uint32_t position; + uint8_t mediaStatus; +} adv_play_status_t; + +typedef union { + + /* The capabilities of the target. + * This is valid when "advOp" is set to AVRCP_OP_GET_CAPABILITIES. + */ + struct { + + /* The type of capability. */ + uint8_t type; + + /* The capability info. */ + union { + + /* The list of company IDs. + * (type == AVRCP_CAPABILITY_COMPANY_ID) + */ + struct { + + /* The number of supported company IDs. */ + uint8_t numIds; + + /* An array of company IDs (3 bytes each). */ + uint8_t *ids; + } companyId; + + /* A bitmask of the supported events. + * (type == AVRCP_CAPABILITY_EVENTS_SUPPORTED) + */ + uint16_t eventMask; + } info; + } capability; + + /* A bitmask that indicates the player settings supported by + * the target device. + * This is valid when "advOp" is set to + * AVRCP_OP_LIST_PLAYER_SETTING_ATTRIBS. + */ + uint16_t attrMask; + + /* The list of values for the requested attribute on the target + * device. + * This is valid when "advOp" is set to AVRCP_OP_LIST_PLAYER_SETTING_VALUES. + */ + struct { + + /* The number of supported value IDs. */ + uint8_t numIds; + + /* An array of value ID (1 byte each). */ + uint8_t *ids; + } attrValues; + + /* The text of each player setting attribute. + * This is valid when "advOp" is set to + * AVRCP_OP_GET_PLAYER_SETTING_ATTR_TEXT + */ + struct { + + /* The number of attribute IDs returned. */ + uint8_t numIds; + + /* An array of attribute text information */ + avrcp_player_attrib_t txt[BTIF_AVRCP_NUM_PLAYER_SETTINGS]; + } attrStrings; + + /* The value of each player setting. + * This is valid when "advOp" is set to AVRCP_OP_GET_PLAYER_SETTING_VALUE. + */ + struct { + + /* Bitmask that describes which + * attributes are being reported + */ + avrcp_player_attrId_mask_t attrMask; + + /* The equalizer setting. */ + avrcp_eq_value_t eq; + + /* The repeat setting. */ + avrcp_repeat_value_t repeat; + + /* The shuffle setting. */ + avrcp_shuffle_value_t shuffle; + + /* The scan setting. */ + avrcp_scan_value_t scan; + +#if BTIF_AVRCP_NUM_PLAYER_SETTINGS > 4 + /* Extended player setting. */ + avrcp_ext_value_t extValue[BTIF_AVRCP_NUM_PLAYER_SETTINGS - 4]; + +#endif /* */ + } setting; + + /* The list of setting values for the requested attribute on the target. + * This is valid when "advOp" is set to + * AVRCP_OP_GET_PLAYER_SETTING_VALUE_TEXT. + */ + struct { + + /* The number of settings returned */ + uint8_t numSettings; + + /* An array of value text information */ + avrcp_player_settings_t txt[BTIF_AVRCP_NUM_PLAYER_SETTINGS]; + } settingStrings; + + /* The list of element values for the current track on the + * target. This is valid when "advOp" is set to AVRCP_OP_GET_MEDIA_INFO. + */ + struct { + + /* The number of elements returned */ + uint8_t numIds; + + /* An array of element value text information */ + avrcp_media_attr_t txt[BTIF_AVRCP_NUM_MEDIA_ATTRIBUTES]; + } element; + + adv_play_status_t playStatus; + +#if BTIF_AVRCP_VERSION_1_3_ONLY == BTIF_DISABLED + /* The Absolute Volume + * This is valid when "advOp" is set to AVRCP_OP_SET_ABSOLUTE_VOLUME. + */ + uint8_t volume; + +#endif /* BTIF_AVRCP_VERSION_1_3_ONLY == BTIF_DISABLED */ +} avrcp_adv_rsp_parms_t; + +/*--------------------------------------------------------------------------- + * AvrcpNotifyParms structure + * + * Defines the callback parameters for AVRCP_EVENT_ADV_RESPONSE when "advOp" is + * set to AVRCP_OP_REGISTER_NOTIFY, and for the AVRCP_EVENT_ADV_NOTIFY event. + */ +typedef struct { + + /* Defines the event ID that was received */ + avrcp_event_Id_t event; + union { + + /* Play status of the media. Valid when the event ID is + * AVRCP_EID_MEDIA_STATUS_CHANGED. + */ + avrcp_media_status_t mediaStatus; + + /* The current track. Valid when the event ID is + * AVRCP_EID_TRACK_CHANGED. + */ + avrcp_track_struct_t track; + + /* The position (ms) of the current track. Valid when the event + * ID is AVRCP_EID_PLAY_POS_CHANGED. + */ + uint32_t position; + + /* The battery status of the target. Valid when the event ID is + * AVRCP_EID_BATT_STATUS_CHANGED. + */ + avrcp_battery_status_t battStatus; + + /* The system status of the target. Valid when the event ID is + * AVRCP_EID_SYS_STATUS_CHANGED. + */ + avrcp_system_status_t sysStatus; + + /* The player settings. Valid when the event ID is + * AVRCP_EID_APP_SETTING_CHANGED + */ + struct { + + /* Bitmask that describes which + * attributes are being reported + */ + avrcp_player_attrId_mask_t attrMask; + + /* The equalizer setting. */ + avrcp_eq_value_t eq; + + /* The repeat setting. */ + avrcp_repeat_value_t repeat; + + /* The shuffle setting. */ + avrcp_shuffle_value_t shuffle; + + /* The scan setting. */ + avrcp_scan_value_t scan; + +#if BTIF_AVRCP_NUM_PLAYER_SETTINGS > 4 + /* Extended player setting. */ + avrcp_ext_value_t extValue[BTIF_AVRCP_NUM_PLAYER_SETTINGS - 4]; + +#endif /* */ + } setting; + +#if BTIF_AVRCP_VERSION_1_3_ONLY == BTIF_DISABLED + /* Absolute volume. Valid when the event ID is + * AVRCP_EID_VOLUME_CHANGED. + */ + uint8_t volume; + + /* The addressed player. Valid when the event ID is + * AVRCP_EID_ADDRESSED_PLAYER_CHANGED. + */ + struct { + uint16_t playerId; + uint16_t uidCounter; + } addrPlayer; + + /* The UID counter. Valid when the event ID is + * AVRCP_EID_UIDS_CHANGED. + */ + uint16_t uidCounter; + +#endif /* BTIF_AVRCP_VERSION_1_3_ONLY == BTIF_DISABLED */ + } p; +} avrcp_adv_notify_parms_t; + +typedef struct { + uint8_t transId; + union { + + /* Folder Item. Valid when "advOp" is AVRCP_OP_GET_FOLDER_ITEMS */ + struct { + avrcp_scope_t scope; /* The requested scope */ + uint32_t start; /* The starting item */ + uint32_t end; /* The ending item */ + uint8_t numAttrs; /* Number of attributes requested */ + uint8_t *attrList; /* List of attributes requested */ + } folder; + + /* Path. Valid when "advOp" is AVRCP_OP_CHANGE_PATH */ + struct { + uint16_t uidCounter; /* Current UID counter */ + uint8_t direction; /* Direction to change in the path (up or down) */ + uint8_t *uid; /* UID of folder to change to (down) */ + } chPath; + + /* Item Attributes. Valid when "advOp" is AVRCP_OP_GET_ITEM_ATTRIBUTES */ + struct { + avrcp_scope_t scope; /* The requested scope */ + uint8_t *uid; /* UID of the requested item */ + uint16_t uidCounter; /* Current UID counter */ + uint8_t numAttrs; /* Number of attributes requested */ + uint8_t *attrList; /* List of attributes requested */ + } attr; + + /* Search. Valid when "advOp" is AVRCP_OP_SEARCH */ + struct { + uint16_t charSet; /* Character set of the search string */ + uint16_t len; /* Length of the search string */ + uint8_t *str; /* Search string */ + } search; + } p; +} avrcp_browse_req_parms_t; + +typedef union { + /* The browsed player. Valid when "advOp" is AVRCP_OP_SET_BROWSED_PLAYER + */ + avrcp_media_player_item_t *brwsPlayer; +} avrcp_browse_inf_parms_t; + +typedef union { + /* Browsed Player. Valid when "advOp" is AVRCP_OP_SET_BROWSED_PLAYER */ + struct { + uint16_t uidCounter; /* Current UID counter */ + uint32_t numItems; /* Number of items in the current path */ + uint16_t charSet; /* Character set used by the player */ + uint8_t fDepth; /* Number of folder length/name pairs to follow */ + uint8_t *list; /* List of folder names */ + } brwsPlayer; + + /* Folder Items. Valid when "advOp" is AVRCP_OP_GET_FOLDER_ITEMS */ + struct { + uint16_t uidCounter; /* Current UID counter */ + uint32_t numItems; /* Number of items in the current path */ + uint8_t *list; /* List of items returned */ + } fldrItems; + + /* Change Path. Valid when "advOp" is AVRCP_OP_CHANGE_PATH */ + struct { + uint32_t numItems; /* Number of items in the current path */ + } chPath; + + /* Item Attributes. Valid when "advOp" is AVRCP_OP_GET_ITEM_ATTRIBUTES */ + struct { + uint8_t numAttrs; /* Number of attributes returned */ + uint8_t *list; /* List of attributes returned */ + } itemAttrs; + + /* Search. Valid when "advOp" is AVRCP_OP_SEARCH */ + struct { + uint16_t uidCounter; /* Current UID counter */ + uint32_t numItems; /* Number of items found in the search */ + } search; +} avrcp_browse_rsp_parms_t; + +typedef struct { + + /* Operation to which the remote target responded */ + uint16_t operation; + + /* The press state of the key in the command to which + * the target responded. + */ + BOOL press; + + /* Response from the target. May indicate + * an "extended" response code such as + * AVRCP_RESPONSE_SKIPPED or AVRCP_RESPONSE_TIMEOUT. + */ + uint8_t response; +} avrcp_panel_cnf_t; +typedef struct { + + /* Operation corresponding to the key pressed, held, or + * released. AVRCP will only indicate a new operation + * when the previous one has been _RELEASE'd. + */ + uint16_t operation; +} avrcp_panel_ind_t; + +/* Channel Packet */ +typedef struct { + list_entry_t node; + U8 transId; + U8 msgType; + U8 msgHdrLen; + U8 msgHdr[BTIF_AVTP_HEADER_LEN]; + U8 txIdSize; + U16 txId; + U16 txDataLen; + U8 *txData; + U32 context; +} avtp_packet_t; + +typedef struct { + list_entry_t node; /* Used internally by AVCTP. */ + uint8_t transId; /* Transaction ID */ + uint8_t ctype; /* 4 bits */ + uint8_t subunitType; /* 5 bits */ + uint8_t subunitId; /* 3 bits */ + uint8_t opcode; /* 8 bits */ + uint8_t headerLen; /* Header length */ + uint8_t header[6]; /* Header information */ + uint16_t operandLen; /* Length of buffer in "operands" */ + uint8_t *operands; /* Buffer containing the command data */ + BOOL more; /* Indicates whether to expect additional + * frames containing more operand data. */ + avtp_packet_t avtpPacket; /* For sending over AVTP */ + + // EvmTimer timer; /* Timer for the command */ +} avctp_cmd_frame_t; + +enum { + BTIF_AVRCP_STATE_DISCONNECTED, + BTIF_AVRCP_STATE_CONNECTED +}; +typedef void avrcp_callback_parms_t; + +typedef void (*btif_avrcp_callback)(btif_avrcp_chnl_handle_t chnl, const avrcp_callback_parms_t *parms); + +static POSSIBLY_UNUSED inline btif_avctp_event_t btif_convert_avrcp_event(btif_avrcp_event_t event) +{ + return (btif_avctp_event_t) event; +} + +#define BTIF_AVRCP_EVENT(stack_avrcp_event) btif_convert_avrcp_event(stack_avrcp_event) +#define BTIF_AVRCP_ERROR_CODE(statck_error_code) statck_error_code + +typedef struct +{ + list_entry_t node; + U8 op; + U16 parm_len; + U8 *parms; + U8 trans_id; + + BOOL more; + U16 cur_len; + U16 bytes_to_send; + U8 cont_op; + BOOL abort; + + BOOL internal; + U8 response; + U8 error; + + BOOL is_cmd; + U8 ctype; /* 4 bits */ +} btif_avrcp_advanced_cmd_pdu_t ; + +typedef struct +{ + bool free; + uint8_t state; + list_entry_t tx_cmd_list; + CQueue tx_op_queue; + uint8_t tx_op_queue_buff[BTIF_AVRCP_SUBUNIT_OP_QUEUE_MAX*3]; // 3 bytes per operation + avctp_cmd_frame_t rx_cmd_frame; + uint8_t rx_frag_buff[BTIF_AVRCP_RX_FRAG_BUFF_SIZE]; + uint32_t rx_frag_buff_offset; + struct + { + avrcp_event_mask_t rem_eventMask; + btif_avrcp_advanced_cmd_pdu_t *tx_cmd; + } adv; + btif_avrcp_callback cb; + btif_avrcp_chnl_handle_t avrcp_channel_handle; +} btif_avrcp_channel_t; + +typedef struct +{ + btif_avrcp_advanced_cmd_pdu_t *tx_cmd; + avrcp_adv_rsp_parms_t rsp; + avrcp_adv_notify_parms_t notify; +} btif_avrcp_rsp_adv; + +typedef struct +{ + btif_avrcp_event_t event; + btif_avrcp_channel_t *channel; + bt_status_t status; + uint8_t error_code; + btif_avrcp_operation_t adv_op; + union + { + avctp_cmd_frame_t *cmdFrame; + btif_avrcp_rsp_adv adv; + avrcp_panel_cnf_t panel_cnf; + avrcp_panel_ind_t panel_ind; + } p; +} btif_avrcp_callback_parms_t; + +#ifdef __cplusplus +extern "C" { +#endif + + void btif_avrcp_init(btif_app_bt_device_t btif_app_bt_device); + + bt_status_t btif_avrcp_register(btif_avrcp_channel_t *channel, btif_avrcp_callback cb, avrcp_features_t feat); + + btif_avrcp_channel_t *btif_alloc_avrcp_channel(void); + + btif_avrcp_channel_t *btif_get_avrcp_channel(btif_avrcp_chnl_handle_t handle); + + btif_avctp_event_t btif_avrcp_get_callback_event(const avrcp_callback_parms_t * parms); + + bool btif_avrcp_state_connected(btif_avrcp_channel_t * channel); + + void btif_avrcp_set_volume_cmd(void *cmd, uint8_t transid, int8_t volume); + + void btif_avrcp_register_read_remote_sdp_callback(void (*cb)(btif_avrcp_chnl_handle_t chnl, uint16_t version, uint16_t features)); + + void btif_avrcp_send_custom_cmd_generic(btif_avrcp_channel_t * chnl, uint8_t * ptrData, + uint32_t len); + bt_status_t btif_avrcp_ct_accept_custom_cmd_rsp(btif_avrcp_channel_t * chnl, void *cmd_res, + uint8_t isAccept); + bt_status_t btif_avrcp_connect(btif_avrcp_channel_t * channel, bt_bdaddr_t * addr); + + bt_status_t btif_avrcp_connect_rsp(btif_avrcp_channel_t * chnl, BOOL accept); + + bt_status_t btif_avrcp_disconnect(btif_avrcp_chnl_handle_t channel); + + bt_status_t btif_avrcp_ct_get_play_status(btif_avrcp_channel_t * channel, + + avrcp_advanced_pdu_t * cmd); + avrcp_version_t btif_get_avrcp_version(btif_avrcp_channel_t * channel); + + bt_status_t btif_avrcp_ct_get_capabilities(btif_avrcp_channel_t * channel, + avrcp_advanced_pdu_t * pdu, + btif_avrcp_capabilityId capabilityId); + + void btif_set_avrcp_state(btif_avrcp_channel_t * channel, uint8_t avrcp_state); + + uint8_t btif_get_avrcp_state(btif_avrcp_channel_t * channel); + + bool btif_avrcp_is_control_channel_connected(btif_avrcp_channel_t * channel); + + btif_remote_device_t *btif_avrcp_get_remote_device(btif_avrcp_chnl_handle_t handle); + + uint8_t btif_avrcp_get_channel_panel_int_state(btif_avrcp_chnl_handle_t handle); + + uint8_t btif_avrcp_get_channel_avrcp_state(btif_avrcp_chnl_handle_t handle); + + void btif_avrcp_set_register_notify_check_callback(bool (*cb)(uint8_t event), void (*resp_cb)(uint8_t event)); + + bt_status_t btif_avrcp_ct_register_notification(btif_avrcp_channel_t * channel, + avrcp_advanced_pdu_t * pdu, + btif_avrcp_event_t eventId, uint32_t interval); + void btif_avrcp_ct_register_notify_response_check(btif_avrcp_channel_t * channel, uint8_t event); + bt_status_t btif_get_avrcp_cb_channel_state(const avrcp_callback_parms_t * parms); + + avrcp_error_code_t btif_get_avrcp_cb_channel_error_code(const avrcp_callback_parms_t * parms); + + btif_avrcp_operation_t btif_get_avrcp_cb_channel_advOp(const avrcp_callback_parms_t * parms); + + void *btif_get_avrcp_cb_txPdu(const avrcp_callback_parms_t * parms); + + btif_avrcp_operation_t btif_get_avrcp_cb_txPdu_Op(const avrcp_callback_parms_t * parms); + + uint8_t btif_get_avrcp_pdu_ctype(void * adv_pdu); + + uint8_t btif_get_avrcp_cb_txPdu_transId(const avrcp_callback_parms_t * parms); + + avrcp_role_t btif_get_avrcp_cb_channel_role(btif_avrcp_channel_t * channel); + + avrcp_panel_cnf_t *btif_get_panel_cnf(const avrcp_callback_parms_t * parms); + + avrcp_role_t btif_get_avrcp_channel_role(btif_avrcp_channel_t * channel); + + adv_play_status_t *btif_get_avrcp_adv_rsp_play_status(const avrcp_callback_parms_t * parms); + + avrcp_adv_rsp_parms_t *btif_get_avrcp_adv_rsp(const avrcp_callback_parms_t * parms); + + avrcp_adv_notify_parms_t *btif_get_avrcp_adv_notify(const avrcp_callback_parms_t * parms); + + avrcp_event_mask_t btif_get_avrcp_adv_rem_event_mask(btif_avrcp_channel_t * channel); + + void btif_set_avrcp_adv_rem_event_mask(btif_avrcp_channel_t * channel, uint16_t mask); + + void btif_set_app_bt_device_avrcp_notify_rsp_ctype(avrcp_advanced_pdu_t * cmd, uint8_t type); + + uint8_t btif_get_app_bt_device_avrcp_notify_rsp_transid(avrcp_advanced_pdu_t * cmd); + + bt_status_t btif_avrcp_ct_get_media_Info(btif_avrcp_channel_t * channel, + + avrcp_advanced_pdu_t * cmd, + avrcp_media_attrId_mask_t mediaMask); + avctp_cmd_frame_t *btif_get_avrcp_cmd_frame(const avrcp_callback_parms_t * parms); + + void btif_avrcp_set_capabilities_rsp_cmd(avrcp_advanced_pdu_t * cmd_pdu, uint8_t transId, + + uint8_t type); + + void btif_avrcp_set_control_rsp_cmd(avrcp_advanced_pdu_t * cmd_pdu, uint8_t transId, + uint8_t type); + + void btif_avrcp_set_control_rsp_cmd_witherror(avrcp_advanced_pdu_t * cmd_pdu, uint8_t transId, uint8_t type, uint8_t error); + + bt_status_t btif_avrcp_ct_get_capabilities_rsp(btif_avrcp_channel_t * channel, + avrcp_advanced_pdu_t * cmd_pdu, + avrcp_capabilityId_t capid, uint16_t mask); + + bt_status_t btif_avrcp_ct_get_capabilities_company_id_rsp(btif_avrcp_channel_t * channel, avrcp_advanced_pdu_t * cmd_pdu); + + bt_status_t btif_avrcp_ct_accept_absolute_volume_rsp(btif_avrcp_channel_t * channel, + avrcp_advanced_pdu_t * cmd_pdu, + uint8_t volume); + + void btif_avrcp_set_notify_rsp_cmd(avrcp_advanced_pdu_t * cmd_pdu, uint8_t transId, + uint8_t type); + + void btif_avrcp_set_notify_rsp_cmd_witherror(avrcp_advanced_pdu_t * cmd_pdu, uint8_t transId, uint8_t type, uint8_t error); + + void btif_avrcp_recheck_vol_ctrl_flag(uint8_t * flag); + + bt_status_t btif_avrcp_ct_get_absolute_volume_rsp(btif_avrcp_channel_t * channel, + avrcp_advanced_pdu_t * cmd_pdu, + uint8_t volume); + + bt_status_t btif_avrcp_tg_absolute_volume_notify(btif_avrcp_channel_t * channel, avrcp_advanced_pdu_t * cmd_pdu, uint8_t volume); + + uint16_t btif_avrcp_get_cmgrhandler_remDev_hciHandle(btif_avrcp_channel_t * channel); + + avrcp_panel_cnf_t *btif_get_avrcp_panel_cnf(const avrcp_callback_parms_t * parms); + + avrcp_panel_ind_t *btif_get_avrcp_panel_ind(const avrcp_callback_parms_t * parms); + + bt_status_t btif_avrcp_set_panel_key(btif_avrcp_channel_t * channel, avrcp_panel_operation_t op, + bool press); + + uint8_t btif_avrcp_get_ctl_trans_id(btif_avrcp_channel_t * channel); + void btif_avrcp_set_ctl_trans_id(btif_avrcp_channel_t * channel, uint8_t trans_id); + + bt_status_t btif_avrcp_ct_set_absolute_volume(btif_avrcp_channel_t *channel, avrcp_advanced_pdu_t *_pdu, uint8_t volume); + + void btif_avrcp_set_channel_adv_event_mask(btif_avrcp_chnl_handle_t handle, uint16_t mask); + + bt_status_t btif_avrcp_tg_send_general_rsp(btif_avrcp_channel_t * channel, avrcp_advanced_pdu_t * cmd_pdu, uint8_t op, uint8_t error_code); + + bt_status_t btif_avrcp_ct_invalid_volume_rsp(btif_avrcp_channel_t * channel, avrcp_advanced_pdu_t * cmd_pdu); + +#if defined(IBRT) + uint32_t btif_avrcp_profile_save_ctxs(btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len); + uint32_t btif_avrcp_profile_restore_ctxs(uint8_t *buf, uint32_t buf_len); +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/bt_if_enhanced/inc/avtp_api.h b/services/bt_if_enhanced/inc/avtp_api.h new file mode 100644 index 0000000..9c4b65d --- /dev/null +++ b/services/bt_if_enhanced/inc/avtp_api.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __AVTP_API_H_ +#define __AVTP_API_H_ + +/* Message Types */ +#define BTIF_AVTP_MSG_TYPE_COMMAND 0 +#define BTIF_AVTP_MSG_TYPE_ACCEPT 2 +#define BTIF_AVTP_MSG_TYPE_REJECT 3 + +#endif /* __AVTP_H_ */ diff --git a/services/bt_if_enhanced/inc/besaud_api.h b/services/bt_if_enhanced/inc/besaud_api.h new file mode 100644 index 0000000..a7953d6 --- /dev/null +++ b/services/bt_if_enhanced/inc/besaud_api.h @@ -0,0 +1,44 @@ +#ifndef __BESAUD_API_H__ +#define __BESAUD_API_H__ + +#include "cqueue.h" +#include "bluetooth.h" +#include "me_api.h" + +#define BTIF_BESAUD_EVENT_CONTROL_CONNECTED 0x21 + +#define BTIF_BESAUD_EVENT_CONTROL_DISCONNECTED 0x22 + +#define BTIF_BESAUD_EVENT_CONTROL_DATA_IND 0x23 + +#define BTIF_BESAUD_EVENT_CONTROL_DATA_SENT 0x24 + +#define BTIF_BESAUD_EVENT_CONTROL_SET_IDLE 0x30 + +typedef uint16_t btif_besaud_event; + +typedef void (*btif_besaud_status_change_callback)(btif_besaud_event event); + +typedef void (*btif_besaud_data_received_callback)(uint8_t*, uint16_t); + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t btif_besaud_is_connected(void); +uint8_t btif_besaud_is_cmd_sending(void); +void btif_besaud_clear_cmd_sending(void); +void btif_besaud_client_create(btif_remote_device_t *dev); +void btif_besaud_server_create(btif_besaud_status_change_callback callback); +void btif_besaud_data_received_register(btif_besaud_data_received_callback callback); +void btif_besaud_send_cmd(uint8_t* cmd, uint16_t len); +bt_status_t btif_besaud_send_cmd_no_wait(uint8_t* cmd, uint16_t len); +void btif_besaud_status_changed(btif_besaud_event event); +btif_remote_device_t *btif_besaud_get_peer_device(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/bt_if_enhanced/inc/besble_debug.h b/services/bt_if_enhanced/inc/besble_debug.h new file mode 100644 index 0000000..5ce9e5f --- /dev/null +++ b/services/bt_if_enhanced/inc/besble_debug.h @@ -0,0 +1,188 @@ +#ifndef __BESBLE_DEBUG_H +#define __BESBLE_DEBUG_H + +#include "hal_uart.h" + +const char *DebugMask2Prefix(uint8_t mask); + +#define DEBUG_PREFIX_FORMAT "%s<%s> " +#define DEBUG_SUFFIX_FORMAT "\n" + +#define LOG_HCI_TAG "[BLE HCI]: " +#define LOG_L2C_TAG "[BLE L2C]: " +#define LOG_ATT_TAG "[BLE ATT]: " +#define LOG_GATT_TAG "[BLE GATT]: " +#define LOG_SMP_TAG "[BLE SMP]: " + +#define LOG_GAP_TAG "[BLE GAP]: " +#define LOG_APP_TAG "[BLE APP]: " +#define LOG_BLE_TAG "[BLE]: " +#define LOG_HTP_TAG "[BLE HTP]: " + +#define GAP_ERROR 1 +#define GAP_OUT 2 +#define GATT_ERROR 3 +#define GATT_OUT 4 +#define ATT_ERROR 5 +#define ATT_OUT 6 +#define L2C_ERROR 7 +#define L2C_OUT 8 +#define HCI_ERROR 9 +#define HCI_OUT 10 +#define SMP_ERROR 11 +#define SMP_OUT 12 +#define APP_ERROR 13 +#define APP_OUT 14 +/* Profile macro start */ +#define PRF_HT_ERROR 15 +#define PRF_HT_OUT 16 +/* Profile macro end */ +#define BLE_ERROR 30 +#define BLE_OUT 31 + +#define DebugOut(mask, str, ...) \ + do \ + { \ + const char *prefix = NULL; \ + prefix = DebugMask2Prefix(mask); \ + TRACE(1, DEBUG_PREFIX_FORMAT, prefix, __FUNCTION__); \ + TRACE(1, str, ##__VA_ARGS__); \ + } while (0) + +#if 0 +#define DEBUG_HCI_DBG 1 +#define DEBUG_GAP_DBG 0 +#define DEBUG_GATT_DBG 0 +#define DEBUG_ATT_DBG 0 +#define DEBUG_L2C_DBG 0 +#define DEBUG_SMP_DBG 0 +#define DEBUG_APP_DBG 0 +#define DEBUG_PRF_DBG 0 +#define DEBUG_BLE_DBG 0 + +#else +/* ble debug macro switch */ +#define DEBUG_HCI_DBG 0 +#define DEBUG_GAP_DBG 0 +#define DEBUG_GATT_DBG 0 +#define DEBUG_ATT_DBG 0 +#define DEBUG_L2C_DBG 0 +#define DEBUG_SMP_DBG 0 +#define DEBUG_APP_DBG 0 +#define DEBUG_PRF_DBG 0 +#define DEBUG_BLE_DBG 0 +#endif + +#if DEBUG_HCI_DBG +#define BLE_HCI_DBG(str,...) DebugOut(HCI_OUT, str, ##__VA_ARGS__) +#define BLE_HCI_ERR(str,...) DebugOut(HCI_ERROR, str, ##__VA_ARGS__) +#define BLE_HCI_FUNC_ENTER() TRACE(LOG_BLE_TAG"%s line: %d +++\n", __FUNCTION__, __LINE__) +#define BLE_HCI_FUNC_LEAVE() TRACE(LOG_BLE_TAG"%s line: %d ---\n", __FUNCTION__, __LINE__) +#else +#define BLE_HCI_DBG(str,...) +#define BLE_HCI_ERR(str,...) DebugOut(HCI_ERROR, str, ##__VA_ARGS__) +#define BLE_HCI_FUNC_ENTER() +#define BLE_HCI_FUNC_LEAVE() +#endif + +#if DEBUG_GAP_DBG +#define BLE_GAP_DBG(str,...) DebugOut(GAP_OUT, str, ##__VA_ARGS__) +#define BLE_GAP_ERR(str,...) DebugOut(GAP_ERROR, str, ##__VA_ARGS__) +#define BLE_GAP_FUNC_ENTER() TRACE(LOG_GAP_TAG"%s line: %d +++\n", __FUNCTION__, __LINE__) +#define BLE_GAP_FUNC_LEAVE() TRACE(LOG_GAP_TAG"%s line: %d ---\n", __FUNCTION__, __LINE__) +#else +#define BLE_GAP_DBG(str,...) +#define BLE_GAP_ERR(str,...) DebugOut(GAP_ERROR, str, ##__VA_ARGS__) +#define BLE_GAP_FUNC_ENTER() +#define BLE_GAP_FUNC_LEAVE() +#endif + +#if DEBUG_GATT_DBG +#define BLE_GATT_DBG(str,...) DebugOut(GATT_OUT, str, ##__VA_ARGS__) +#define BLE_GATT_ERR(str,...) DebugOut(GATT_ERROR, str, ##__VA_ARGS__) +#define BLE_GATT_FUNC_ENTER() TRACE(LOG_GATT_TAG"%s line: %d +++\n", __FUNCTION__, __LINE__) +#define BLE_GATT_FUNC_LEAVE() TRACE(LOG_GATT_TAG"%s line: %d ---\n", __FUNCTION__, __LINE__) +#else +#define BLE_GATT_DBG(str,...) +#define BLE_GATT_ERR(str,...) DebugOut(GATT_ERROR, str, ##__VA_ARGS__) +#define BLE_GATT_FUNC_ENTER() +#define BLE_GATT_FUNC_LEAVE() +#endif + +#if DEBUG_ATT_DBG +#define BLE_ATT_DBG(str,...) DebugOut(ATT_OUT, str, ##__VA_ARGS__) +#define BLE_ATT_ERR(str,...) DebugOut(ATT_ERROR, str, ##__VA_ARGS__) +#define BLE_ATT_FUNC_ENTER() TRACE(LOG_ATT_TAG"%s line: %d +++\n", __FUNCTION__, __LINE__) +#define BLE_ATT_FUNC_LEAVE() TRACE(LOG_ATT_TAG"%s line: %d ---\n", __FUNCTION__, __LINE__) +#else +#define BLE_ATT_DBG(str,...) +#define BLE_ATT_ERR(str,...) DebugOut(ATT_ERROR, str, ##__VA_ARGS__) +#define BLE_ATT_FUNC_ENTER() +#define BLE_ATT_FUNC_LEAVE() +#endif + +#if DEBUG_L2C_DBG +#define BLE_L2C_DBG(str,...) DebugOut(L2C_OUT, str, ##__VA_ARGS__) +#define BLE_L2C_ERR(str,...) DebugOut(L2C_ERROR, str, ##__VA_ARGS__) +#define BLE_L2C_FUNC_ENTER() TRACE(LOG_L2C_TAG"%s line: %d +++\n", __FUNCTION__, __LINE__) +#define BLE_L2C_FUNC_LEAVE() TRACE(LOG_L2C_TAG"%s line: %d ---\n", __FUNCTION__, __LINE__) +#else +#define BLE_L2C_DBG(str,...) +#define BLE_L2C_ERR(str,...) DebugOut(L2C_ERROR, str, ##__VA_ARGS__) +#define BLE_L2C_FUNC_ENTER() +#define BLE_L2C_FUNC_LEAVE() +#endif + +#if DEBUG_L2C_DBG +#define BLE_SMP_DBG(str,...) DebugOut(SMP_OUT, str, ##__VA_ARGS__) +#define BLE_SMP_ERR(str,...) DebugOut(SMP_ERROR, str, ##__VA_ARGS__) +#define BLE_SMP_FUNC_ENTER() TRACE(LOG_SMP_TAG"%s line: %d +++\n", __FUNCTION__, __LINE__) +#define BLE_SMP_FUNC_LEAVE() TRACE(LOG_SMP_TAG"%s line: %d ---\n", __FUNCTION__, __LINE__) +#else +#define BLE_SMP_DBG(str,...) +#define BLE_SMP_ERR(str,...) DebugOut(SMP_ERROR, str, ##__VA_ARGS__) +#define BLE_SMP_FUNC_ENTER() +#define BLE_SMP_FUNC_LEAVE() +#endif + +#if DEBUG_APP_DBG +#define BLE_APP_DBG(str,...) DebugOut(APP_OUT, str, ##__VA_ARGS__) +#define BLE_APP_ERR(str,...) DebugOut(APP_ERROR, str, ##__VA_ARGS__) +#define BLE_APP_FUNC_ENTER() TRACE(LOG_APP_TAG"%s line: %d +++\n", __FUNCTION__, __LINE__) +#define BLE_APP_FUNC_LEAVE() TRACE(LOG_APP_TAG"%s line: %d ---\n", __FUNCTION__, __LINE__) +#else +#define BLE_APP_DBG(str,...) +#define BLE_APP_ERR(str,...) DebugOut(APP_ERROR, str, ##__VA_ARGS__) +#define BLE_APP_FUNC_ENTER() +#define BLE_APP_FUNC_LEAVE() +#endif + +#if DEBUG_PRF_DBG +#define BLE_PRF_HP_DBG(str,...) DebugOut(PRF_HT_OUT, str, ##__VA_ARGS__) +#define BLE_PRF_HP_ERR(str,...) DebugOut(PRF_HT_ERROR, str, ##__VA_ARGS__) +#define BLE_PRF_HP_FUNC_ENTER() TRACE(LOG_HTP_TAG"%s line: %d +++\n", __FUNCTION__, __LINE__) +#define BLE_PRF_HP_FUNC_LEAVE() TRACE(LOG_HTP_TAG"%s line: %d ---\n", __FUNCTION__, __LINE__) +#else +#define BLE_PRF_HP_DBG(str,...) +#define BLE_PRF_HP_ERR(str,...) DebugOut(PRF_HT_ERROR, str, ##__VA_ARGS__) +#define BLE_PRF_HP_FUNC_ENTER() +#define BLE_PRF_HP_FUNC_LEAVE() +#endif + +#if DEBUG_BLE_DBG +#define BLE_DBG(str,...) DebugOut(BLE_OUT, str, ##__VA_ARGS__) +#define BLE_ERR(str,...) DebugOut(BLE_ERROR, str, ##__VA_ARGS__) +#define BLE_FUNC_ENTER() TRACE(LOG_BLE_TAG"%s line: %d +++\n", __FUNCTION__, __LINE__) +#define BLE_FUNC_LEAVE() TRACE(LOG_BLE_TAG"%s line: %d ---\n", __FUNCTION__, __LINE__) +#define BLE_DUMP8(x,y,z) DUMP8(x,y,z) + +#else +#define BLE_DBG(str,...) +#define BLE_ERR(str,...) DebugOut(BLE_ERROR, str, ##__VA_ARGS__) +#define BLE_FUNC_ENTER() +#define BLE_FUNC_LEAVE() +#define BLE_DUMP8(x,y,z) + +#endif + +#endif diff --git a/services/bt_if_enhanced/inc/bluetooth.h b/services/bt_if_enhanced/inc/bluetooth.h new file mode 100644 index 0000000..ef87303 --- /dev/null +++ b/services/bt_if_enhanced/inc/bluetooth.h @@ -0,0 +1,443 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BLUETOOTH_H__ +#define __BLUETOOTH_H__ +#include "stdint.h" +#include "string.h" +#include "btif_sys_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BOOL_DEFINED +typedef unsigned int BOOL; /* IGNORESTYLE */ +#endif + +typedef unsigned int U32; +typedef unsigned short U16; +typedef unsigned char U8; + +typedef int S32; +typedef short S16; +typedef char S8; + +#ifndef U32_PTR_DEFINED +typedef U32 U32_PTR; + +#define U32_PTR_DEFINED +#endif /* U32_PTR_DEFINED */ + +/* Variable sized integers. Used to optimize processor efficiency by + * using the most efficient data size for counters, arithmatic, etc. + */ +typedef unsigned long I32; + +#ifndef XA_INTEGER_SIZE +#define XA_INTEGER_SIZE 4 +#endif + +#if XA_INTEGER_SIZE == 4 +typedef unsigned long I16; +typedef unsigned long I8; +#elif XA_INTEGER_SIZE == 2 +typedef unsigned short I16; +typedef unsigned short I8; +#elif XA_INTEGER_SIZE == 1 +typedef unsigned short I16; +typedef unsigned char I8; +#else +#error No XA_INTEGER_SIZE specified! +#endif + +typedef void (*PFV) (void); + +/* Boolean Definitions */ +#ifndef TRUE +#define TRUE (1==1) +#endif /* TRUE */ + +#ifndef FALSE +#define FALSE (0==1) +#endif /* FALSE */ + +#ifndef TimeT +typedef U32 TimeT; +#endif + +#ifndef BtPriority +typedef U8 BtPriority; +#endif + +/** Bluetooth Address */ +typedef struct { + uint8_t address[6]; +} __attribute__ ((packed)) bt_bdaddr_t; + +#define BTIF_BD_ADDR_SIZE 6 +#define BTIF_LINK_KEY_SIZE 16 +typedef struct _list_entr { + struct _list_entr *Flink; + struct _list_entr *Blink; + unsigned int resv; +} list_entry_t; + +/*--------------------------------------------------------------------------- + * + * Doubly-linked list manipulation routines. Some are implemented as + * macros but logically are procedures. + */ +#ifndef BTIF_LIST_MACROS +//void InitializeListHead(ListEntry *head); +#define initialize_list_head(ListHead) (\ + (ListHead)->Flink = (ListHead)->Blink = (ListHead) ) + +#define initialize_list_entry(Entry) (\ + (Entry)->Flink = (Entry)->Blink = 0 ) + +#define is_entry_available(Entry) (\ + ((Entry)->Flink == 0)) + +#ifndef is_list_empty +//BOOL is_list_empty(ListEntry *head); +#define is_list_empty(ListHead) (\ + ((ListHead)->Flink == (ListHead))) +#endif + +#define get_head_list(ListHead) (ListHead)->Flink + +#define get_tail_list(ListHead) (ListHead)->Blink + +#define get_next_node(Node) (Node)->Flink + +#define get_prior_node(Node) (Node)->Blink + +#define is_node_connected(n) (((n)->Blink->Flink == (n)) && ((n)->Flink->Blink == (n))) +BOOL is_list_circular(list_entry_t * list); + +#define list_assert(exp) (ASSERT(exp, "%s %s, %d\n", #exp, __func__, __LINE__)) + +//void InsertTailList(ListEntry *head, ListEntry *entry); +void _insert_tail_list(list_entry_t * head, list_entry_t * entry); + +#define insert_tail_list(a, b) (list_assert(is_list_circular(a)), \ + _insert_tail_list(a, b), \ + list_assert(is_list_circular(a))) + +void insert_head_list(list_entry_t * head, list_entry_t * entry); +void _insert_head_list(list_entry_t * head, list_entry_t * entry); + +#define insert_head_list(a, b) (list_assert(is_list_circular(a)), \ + _insert_head_list(a, b), \ + list_assert(is_list_circular(a))) + +list_entry_t *remove_head_list(list_entry_t * head); +list_entry_t *_remove_head_list(list_entry_t * head); + +#define remove_head_list(a) (list_assert(is_list_circular(a)), \ + _remove_head_list(a)) + +void remove_entry_list(list_entry_t * entry); +BOOL is_node_on_list(list_entry_t * head, list_entry_t * node); +U8 get_list_number(list_entry_t * head); +BOOL is_list_circular(list_entry_t * list); +void move_list(list_entry_t * dest, list_entry_t * src); +#endif + +#define iterate_list_safe(head, cur, next, type) \ + for ( (cur) = (type) get_head_list(head) ; \ + (next) = (type) get_next_node(&(cur)->node), \ + (cur) != (type) (head); \ + (cur) = (next)) + +/*--------------------------------------------------------------------------- + * IterateList() + * + * Sets up ordinary traversal of a list. The current member must NOT + * be removed during iteration. Must be followed by a block of code + * containing the body of the iteration. + * + * For example: + * BtSecurityRecord *record; + * IterateList(MEC(secList), record, BtSecurityRecord *) { + * [...do something with "record", but do not remove it!...] + * } + * + * Parameters: + * head - Head of list (address of ListEntry structure) + * cur - Variable to use for current list member + * type - Structure type of cur and next. + */ +#define iterate_list(head, cur, type) \ + for ( (cur) = (type) get_head_list(&(head)) ; \ + (cur) != (type) &(head); \ + (cur) = (type) get_next_node(&(cur)->node) ) + +enum _bt_status { + BT_STS_SUCCESS = 0, + BT_STS_FAILED = 1, + BT_STS_PENDING = 2, + BT_STS_BUSY = 11, + BT_STS_NO_RESOURCES = 12, + BT_STS_NOT_FOUND = 13, + BT_STS_DEVICE_NOT_FOUND = 14, + BT_STS_CONNECTION_FAILED = 15, + BT_STS_TIMEOUT = 16, + BT_STS_NO_CONNECTION = 17, + BT_STS_INVALID_PARM = 18, + BT_STS_IN_PROGRESS = 19, + BT_STS_RESTRICTED = 20, + BT_STS_INVALID_TYPE = 21, + BT_STS_HCI_INIT_ERR = 22, + BT_STS_NOT_SUPPORTED = 23, + BT_STS_IN_USE = 5, + BT_STS_SDP_CONT_STATE = 24, + BT_STS_CONTINUE =24, + BT_STS_CANCELLED = 25, + + /* The last defined status code */ + BT_STS_LAST_CODE = BT_STS_CANCELLED, +}; + +typedef uint32_t bt_status_t; + +typedef struct _evm_timer evm_timer_t; +typedef void (*evm_timer_notify) (evm_timer_t *); + +struct _evm_timer { + list_entry_t node; /* Used internally by the Event Manager */ + void *context; /* Context area for use by callers */ + evm_timer_notify func; /* Function to call when timer fires */ + + /* === Internal use only === */ + TimeT time; /* Amount of time to wait */ + TimeT startTime; /* System time when the timer started */ +}; + +/*--------------------------------------------------------------------------- + * btif_packet_flags type + * + * This type is used by L2CAP and protocols that use directly L2CAP + * to manage the status of a particular BtPacket. + */ +typedef uint16_t btif_packet_flags; + +#define BTIF_BTP_FLAG_NONE 0x0000 /* No current flags */ +#define BTIF_BTP_FLAG_INUSE 0x0001 /* Used only by packet owner */ +#define BTIF_BTP_FLAG_LSYSTEM 0x0002 /* Used only by L2CAP */ +#define BTIF_BTP_FLAG_TAIL 0x0004 /* Used only by L2CAP Applications */ +#define BTIF_BTP_FLAG_RDEV 0x0008 /* Used only by L2CAP */ +#define BTIF_BTP_FLAG_FCS 0x0010 /* FCS field is valid, set only by L2CAP */ +#define BTIF_BTP_FLAG_NON_FLUSH 0x0020 /* Used by L2CAP, HCI or packet owner */ +#define BTIF_BTP_FLAG_ENHANCED 0x0040 /* Used only by L2CAP */ +#define BTIF_BTP_FLAG_SEGMENTED 0x0080 /* Used only by L2CAP */ +#define BTIF_BTP_FLAG_TXDONE 0x0100 /* Used only by L2CAP */ +#define BTIF_BTP_FLAG_USER 0x0200 /* Used only by L2CAP */ +#define BTIF_BTP_FLAG_IMMEDIATE 0x0400 /* Used only by L2CAP */ + +/* End of btif_packet_flags */ + +#define BTIF_BT_PACKET_HEADER_LEN 25 + +typedef struct { + list_entry_t node; + uint8_t *data; /* Points to a buffer of user data. */ + uint16_t dataLen; /* Indicates the length of "data" in bytes. */ + uint16_t flags; /* Must be initialized to BTIF_BTP_FLAG_NONE by + * applications running on top of L2CAP. + */ + +#if BTIF_L2CAP_PRIORITY == BTIF_ENABLED + BtPriority priority; +#endif + + /* Group: The following fields are for internal use only by the stack. */ + void *ulpContext; + uint8_t *tail; + uint16_t tailLen; + +#ifdef BTIF_XA_STATISTICS + U32 rfc_timer; + U32 hci_timer; + U32 l2cap_timer; + +#endif + uint16_t llpContext; + uint16_t remoteCid; + +#if BTIF_L2CAP_NUM_ENHANCED_CHANNELS > 0 + uint8_t segStart; + uint16_t segNum; + uint16_t segCount; + uint8_t fcs[2]; + +#endif + uint8_t hciPackets; + uint8_t headerLen; + uint8_t header[BTIF_BT_PACKET_HEADER_LEN]; +} btif_bt_packet_t; + +/*--------------------------------------------------------------------------- + * le_to_host16() + *--------------------------------------------------------------------------- + * + * Synopsis: Retrieve a 16-bit number from the given buffer. The number + * is in Little-Endian format. + * + * Return: 16-bit number. + */ +U16 le_to_host16(const U8 * ptr); + +/*--------------------------------------------------------------------------- + * be_to_host16() + *--------------------------------------------------------------------------- + * + * Synopsis: Retrieve a 16-bit number from the given buffer. The number + * is in Big-Endian format. + * + * Return: 16-bit number. + */ +U16 be_to_host16(const U8* ptr); +/*--------------------------------------------------------------------------- + * be_to_host32() + *--------------------------------------------------------------------------- + * + * Synopsis: Retrieve a 32-bit number from the given buffer. The number + * is in Big-Endian format. + * + * Return: 32-bit number. + */ +U32 be_to_host32(const U8* ptr); +/*--------------------------------------------------------------------------- + * store_le16() + *--------------------------------------------------------------------------- + * + * Synopsis: Store 16 bit value into a buffer in Little Endian format. + * + * Return: void + */ +void store_le16(U8 *buff, U16 le_value); + +/*--------------------------------------------------------------------------- + * store_le32() + *--------------------------------------------------------------------------- + * + * Synopsis: Store 32 bit value into a buffer in Little Endian format. + * + * Return: void + */ +void store_le32(U8 *buff, U32 le_value); + +/*--------------------------------------------------------------------------- + * store_be16() + *--------------------------------------------------------------------------- + * + * Synopsis: Store 16 bit value into a buffer in Big Endian format. + * + * Return: void + */ +void store_be16(U8 *buff, U16 be_value); + +/*--------------------------------------------------------------------------- + * store_be32() + *--------------------------------------------------------------------------- + * + * Synopsis: Store 32 bit value into a buffer in Big Endian format. + * + * Return: void + */ +void store_be32(U8 *buff, U32 be_value); + +#if defined(ENHANCED_STACK) +/* Copy, compare bluetooth Address */ +static inline int ba_cmp(const bt_bdaddr_t *ba1, const bt_bdaddr_t *ba2) +{ + return memcmp(ba1, ba2, sizeof(bt_bdaddr_t )); +} + +static inline void ba_cpy( bt_bdaddr_t *dst, const bt_bdaddr_t *src) +{ + memcpy(dst, src, sizeof(bt_bdaddr_t )); +} + +#define BTIF_CTX_INIT(buff) \ + POSSIBLY_UNUSED unsigned int __offset = 2; \ + POSSIBLY_UNUSED unsigned char *__buff = buff; + +#define BTIF_CTX_STR_BUF(buff,len) \ + memcpy(__buff+__offset, buff, len); \ + __offset += len; + +#define BTIF_CTX_LDR_BUF(buff,len) \ + memcpy(buff, __buff+__offset, len); \ + __offset += len; + +#define BTIF_CTX_STR_VAL8(v) \ + __buff[__offset] = v&0xFF; \ + __offset += 1; + +#define BTIF_CTX_LDR_VAL8(v) \ + v = __buff[__offset]; \ + __offset += 1; + +#define BTIF_CTX_STR_VAL16(v) \ + __buff[__offset] = v&0xFF; \ + __buff[__offset+1] = (v>>8)&0xFF; \ + __offset += 2; + +#define BTIF_CTX_LDR_VAL16(v) \ + v = __buff[__offset]; \ + v |= __buff[__offset+1]<<8; \ + __offset += 2; + +#define BTIF_CTX_STR_VAL32(v) \ + __buff[__offset] = v&0xFF; \ + __buff[__offset+1] = (v>>8)&0xFF; \ + __buff[__offset+2] = (v>>16)&0xFF; \ + __buff[__offset+3] = (v>>24)&0xFF; \ + __offset += 4; + +#define BTIF_CTX_LDR_VAL32(v) \ + v = __buff[__offset]; \ + v |= __buff[__offset+1]<<8; \ + v |= __buff[__offset+2]<<16; \ + v |= __buff[__offset+3]<<24; \ + __offset += 4; + +#define BTIF_CTX_GET_BUF_CURR() __buff + +#define BTIF_CTX_GET_BUF_HEAD() __buff + +#define BTIF_CTX_GET_OFFSET() __offset + +#define BTIF_CTX_GET_DATA_LEN() (__buff[0] | __buff[1]<<8) + +#define BTIF_CTX_GET_TOTAL_LEN() (BTIF_CTX_GET_DATA_LEN()+2) + +#define BTIF_CTX_SAVE_UPDATE_DATA_LEN() \ + __buff[0] = (__offset-2)&0xFF; \ + __buff[1] = ((__offset-2)>>8)&0xFF; + +struct btif_ctx_content { + unsigned char *buff; + unsigned int buff_len; +}; +#endif /* ENHANCED_STACK */ + +#ifdef __cplusplus +} +#endif /* */ +#endif /*__BLUETOOTH_H__*/ diff --git a/services/bt_if_enhanced/inc/bt_if.h b/services/bt_if_enhanced/inc/bt_if.h new file mode 100644 index 0000000..0f758c9 --- /dev/null +++ b/services/bt_if_enhanced/inc/bt_if.h @@ -0,0 +1,169 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BT_IF_H_ +#define __BT_IF_H_ +#include +#include "bluetooth.h" +#include "btif_sys_config.h" +#include "me_api.h" + +//Application ID,indentify profle app context +#define BTIF_APP_INVALID_ID (0x00000000u) +#define BTIF_APP_HFP_PROFILE_ID (0x00000001u) +#define BTIF_APP_A2DP_PROFILE_ID (0x00000002u) +#define BTIF_APP_AVRCP_PROFILE_ID (0x00000004u) +#define BTIF_APP_MAP_PROFILE_ID (0X00000008u) +#define BTIF_APP_HID_PROFILE_ID (0X00000010u) + +#define BTIF_APP_SPP_SERVER_START_ID (0x00000020u) +#define BTIF_APP_SPP_SERVER_ID_1 (BTIF_APP_SPP_SERVER_START_ID) +#define BTIF_APP_SPP_SERVER_ID_2 (BTIF_APP_SPP_SERVER_START_ID << 1) +#define BTIF_APP_SPP_SERVER_ID_3 (BTIF_APP_SPP_SERVER_START_ID << 2) +#define BTIF_APP_SPP_SERVER_ID_4 (BTIF_APP_SPP_SERVER_START_ID << 3) +#define BTIF_APP_SPP_SERVER_ID_5 (BTIF_APP_SPP_SERVER_START_ID << 4) +#define BTIF_APP_SPP_SERVER_ID_6 (BTIF_APP_SPP_SERVER_START_ID << 5) +#define BTIF_APP_SPP_SERVER_ID_7 (BTIF_APP_SPP_SERVER_START_ID << 6) +#define BTIF_APP_SPP_SERVER_ID_8 (BTIF_APP_SPP_SERVER_START_ID << 7) +#define BTIF_APP_SPP_SERVER_ID_9 (BTIF_APP_SPP_SERVER_START_ID << 8) +#define BTIF_APP_SPP_SERVER_ID_10 (BTIF_APP_SPP_SERVER_START_ID << 9) +#define BTIF_APP_SPP_SERVER_END_ID (BTIF_APP_SPP_SERVER_ID_10) +#define BTIF_APP_SPP_SERVER_OFFSET (4) +#define BTIF_APP_SPP_SERVER_NUM (10) +#define BTIF_APP_SPP_SERVER_MASK (0x000003FF< 0 then SEC_SetPin() + * must be called in response to this event with a pin length >= + * p.pinReq.pinLen. + */ +#define BTIF_BTEVENT_PIN_REQ 53 + +/** Pairing operation is complete. + */ +#define BTIF_BTEVENT_PAIRING_COMPLETE 54 + +/** Authentication operation complete. "p.remDev" is valid. */ +#define BTIF_BTEVENT_AUTHENTICATE_CNF 55 + +/** Encryption operation complete. "p.remDev" is valid. */ +#define BTIF_BTEVENT_ENCRYPT_COMPLETE 56 + +/** Security mode 3 operation complete. "p.secMode" is valid. */ +#define BTIF_BTIF_BTEVENT_SECURITY3_COMPLETE 57 + +/** A link key is returned. "p.bdLinkKey" is valid. */ +#define BTIF_BTEVENT_RETURN_LINK_KEYS 58 + +/** Out of Band data has been received from the host controller. */ +#define BTIF_BTEVENT_LOCAL_OOB_DATA 59 + +/** Request a Pass Key for simple pairing when "errCode" is BEC_NO_ERROR. The + * application should call SEC_SetPassKey() to provide the passkey or reject + * the request, and optionally save the link key. + */ +#define BTIF_BTEVENT_PASS_KEY_REQ 60 + +/** Request a User Confirmation for simple pairing when "errCode" is + * BEC_NO_ERROR. + */ +#define BTIF_BTEVENT_CONFIRM_NUMERIC_REQ 61 + +#define BTIF_BTEVENT_DISPLAY_NUMERIC_IND 62 + +#define BTIF_BTEVENT_CONN_PACKET_TYPE_CHNG 63 + +#define BTIF_SDEVENT_QUERY_RSP 70 + +#define BTIF_SDEVENT_QUERY_ERR 71 + +#define BTIF_SDEVENT_QUERY_FAILED 72 + +#define BTIF_BTEVENT_SELECT_DEVICE_REQ 80 + +#define BTIF_BTEVENT_DEVICE_ADDED 81 + +#define BTIF_BTEVENT_DEVICE_DELETED 82 + +#define BTIF_BTEVENT_MAX_SLOT_CHANGED 83 + +#define BTIF_BTEVENT_SNIFFER_CONTROL_DONE 84 + +#define BTIF_BTEVENT_LINK_POLICY_CHANGED 85 + +#define BTIF_BTEVENT_DEFAULT_LINK_POLICY_CHANGED 86 + +#define BTIF_BTEVENT_BES_AUD_CONNECTED 200 + +#define BTIF_BTEVENT_BES_AUD_DISCONNECTED 201 + +#define BTIF_STACK_LINK_DISCONNECT_COMPLETE 220 + +typedef uint32_t btif_event_mask_t; + +#define BTIF_BEM_NO_EVENTS 0x00000000 +#define BTIF_BEM_INQUIRY_RESULT 0x00000001 +#define BTIF_BEM_INQUIRY_COMPLETE 0x00000002 +#define BTIF_BEM_INQUIRY_CANCELED 0x00000004 +#define BTIF_BEM_LINK_CONNECT_IND 0x00000008 +#define BTIF_BEM_SCO_CONNECT_IND 0x00000010 +#define BTIF_BEM_LINK_DISCONNECT 0x00000020 +#define BTIF_BEM_LINK_CONNECT_CNF 0x00000040 +#define BTIF_BEM_LINK_CON_RESTRICT 0x00000080 +#define BTIF_BEM_MODE_CHANGE 0x00000100 +#define BTIF_BEM_ACCESSIBLE_CHANGE 0x00000200 +#define BTIF_BEM_AUTHENTICATED 0x00000400 +#define BTIF_BEM_ENCRYPTION_CHANGE 0x00000800 +#define BTIF_BEM_SECURITY_CHANGE 0x00001000 +#define BTIF_BEM_ROLE_CHANGE 0x00002000 +#define BTIF_BEM_SCO_DISCONNECT 0x00004000 +#define BTIF_BEM_SCO_CONNECT_CNF 0x00008000 +#define BTIF_BEM_SIMPLE_PAIRING_COMPLETE 0x00010000 +#define BTIF_BEM_REMOTE_FEATURES 0x00020000 +#define BTIF_BEM_REM_HOST_FEATURES 0x00040000 +#define BTIF_BEM_LINK_SUPERV_TIMEOUT_CHANGED 0x00080000 +#define BTIF_BEM_SET_SNIFF_SUBR_PARMS 0x00100000 +#define BTIF_BEM_SNIFF_SUBRATE_INFO 0x00200000 +#define BTIF_BEM_SET_INQ_MODE 0x00400000 +#define BTIF_BEM_SET_INQ_RSP_TX_PWR 0x00800000 +#define BTIF_BEM_SET_EXT_INQ_RESP 0x01000000 +#define BTIF_BEM_SET_ERR_DATA_REP 0x02000000 +#define BTIF_BEM_KEY_PRESSED 0x04000000 +#define BTIF_BEM_CONN_PACKET_TYPE_CHNG 0x08000000 +#define BTIF_BEM_QOS_SETUP_COMPLETE 0x10000000 +#define BTIF_BEM_MAX_SLOT_CHANGED 0x20000000 +#define BTIF_BEM_SNIFFER_CONTROL_DONE 0x40000000 +#define BTIF_BEM_LINK_POLICY_CHANGED 0x80000000 +#define BTIF_BEM_ALL_EVENTS 0xffffffff + +typedef uint8_t btif_error_code_t; + +#define BTIF_BEC_NO_ERROR 0x00 +#define BTIF_BEC_UNKNOWN_HCI_CMD 0x01 +#define BTIF_BEC_NO_CONNECTION 0x02 +#define BTIF_BEC_HARDWARE_FAILURE 0x03 +#define BTIF_BEC_PAGE_TIMEOUT 0x04 +#define BTIF_BEC_AUTHENTICATE_FAILURE 0x05 +#define BTIF_BEC_MISSING_KEY 0x06 +#define BTIF_BEC_MEMORY_FULL 0x07 +#define BTIF_BEC_CONNECTION_TIMEOUT 0x08 +#define BTIF_BEC_MAX_CONNECTIONS 0x09 +#define BTIF_BEC_MAX_SCO_CONNECTIONS 0x0a +#define BTIF_BEC_ACL_ALREADY_EXISTS 0x0b +#define BTIF_BEC_COMMAND_DISALLOWED 0x0c +#define BTIF_BEC_LIMITED_RESOURCE 0x0d +#define BTIF_BEC_SECURITY_ERROR 0x0e +#define BTIF_BEC_PERSONAL_DEVICE 0x0f +#define BTIF_BEC_HOST_TIMEOUT 0x10 +#define BTIF_BEC_UNSUPPORTED_FEATURE 0x11 +#define BTIF_BEC_INVALID_HCI_PARM 0x12 +#define BTIF_BEC_USER_TERMINATED 0x13 +#define BTIF_BEC_LOW_RESOURCES 0x14 +#define BTIF_BEC_POWER_OFF 0x15 +#define BTIF_BEC_LOCAL_TERMINATED 0x16 +#define BTIF_BEC_REPEATED_ATTEMPTS 0x17 +#define BTIF_BEC_PAIRING_NOT_ALLOWED 0x18 +#define BTIF_BEC_UNKNOWN_LMP_PDU 0x19 +#define BTIF_BEC_UNSUPPORTED_REMOTE 0x1a +#define BTIF_BEC_SCO_OFFSET_REJECT 0x1b +#define BTIF_BEC_SCO_INTERVAL_REJECT 0x1c +#define BTIF_BEC_SCO_AIR_MODE_REJECT 0x1d +#define BTIF_BEC_INVALID_LMP_PARM 0x1e +#define BTIF_BEC_UNSPECIFIED_ERR 0x1f +#define BTIF_BEC_UNSUPPORTED_LMP_PARM 0x20 +#define BTIF_BEC_ROLE_CHG_NOT_ALLOWED 0x21 +#define BTIF_BEC_LMP_RESPONSE_TIMEOUT 0x22 +#define BTIF_BEC_LMP_TRANS_COLLISION 0x23 +#define BTIF_BEC_LMP_PDU_NOT_ALLOWED 0x24 +#define BTIF_BEC_ENCRYP_MODE_NOT_ACC 0x25 +#define BTIF_BEC_UNIT_KEY_USED 0x26 +#define BTIF_BEC_QOS_NOT_SUPPORTED 0x27 +#define BTIF_BEC_INSTANT_PASSED 0x28 +#define BTIF_BEC_PAIR_UNITKEY_NO_SUPP 0x29 +#define BTIF_BEC_NOT_FOUND 0xf1 +#define BTIF_BEC_REQUEST_CANCELLED 0xf2 + +#define BTIF_BEC_INVALID_SDP_PDU 0xd1 +#define BTIF_BEC_SDP_DISCONNECT 0xd2 +#define BTIF_BEC_SDP_NO_RESOURCES 0xd3 +#define BTIF_BEC_SDP_INTERNAL_ERR 0xd4 + +#define BTIF_BEC_STORE_LINK_KEY_ERR 0xe0 + +typedef uint32_t btif_iac_t; + +#define BTIF_BT_IAC_GIAC 0x9E8B33 /* General/Unlimited Inquiry Access Code */ +#define BTIF_BT_IAC_LIAC 0x9E8B00 /* Limited Dedicated Inquiry Access Code */ + +typedef uint8_t btif_link_type_t; + +#define BTIF_BLT_SCO 0x00 +#define BTIF_BLT_ACL 0x01 +#define BTIF_BLT_ESCO 0x02 + +typedef U16 btif_acl_packet; + +#define BTIF_BAPT_NO_2_DH1 0x0002 +#define BTIF_BAPT_NO_3_DH1 0x0004 +#define BTIF_BAPT_DM1 0x0008 +#define BTIF_BAPT_DH1 0x0010 +#define BTIF_BAPT_NO_2_DH3 0x0100 +#define BTIF_BAPT_NO_3_DH3 0x0200 +#define BTIF_BAPT_DM3 0x0400 +#define BTIF_BAPT_DH3 0x0800 +#define BTIF_BAPT_NO_2_DH5 0x1000 +#define BTIF_BAPT_NO_3_DH5 0x2000 +#define BTIF_BAPT_DM5 0x4000 +#define BTIF_BAPT_DH5 0x8000 + +#define BTIF_2M_PACKET (BTIF_BAPT_DM1|BTIF_BAPT_DH1|BTIF_BAPT_NO_3_DH1|BTIF_BAPT_NO_3_DH3|BTIF_BAPT_DM3|BTIF_BAPT_DH3|BTIF_BAPT_NO_3_DH5) +#define BTIF_3M_PACKET (BTIF_BAPT_DM1|BTIF_BAPT_DH1|BTIF_BAPT_DM3|BTIF_BAPT_DH3|BTIF_BAPT_DM5|BTIF_BAPT_DH5) +#define BTIF_1_SLOT_PACKET (BTIF_BAPT_DM1|BTIF_BAPT_DH1|BTIF_BAPT_NO_3_DH1|BTIF_BAPT_NO_2_DH3|BTIF_BAPT_NO_3_DH3|BTIF_BAPT_NO_2_DH5|BTIF_BAPT_NO_3_DH5) +#define BTIF_3_SLOT_PACKET (BTIF_BAPT_DM1|BTIF_BAPT_NO_3_DH3|BTIF_BAPT_NO_2_DH5|BTIF_BAPT_NO_3_DH5) + +typedef uint16_t btif_link_policy_t; + +#define BTIF_BLP_DISABLE_ALL 0x0000 +#define BTIF_BLP_MASTER_SLAVE_SWITCH 0x0001 +#define BTIF_BLP_HOLD_MODE 0x0002 +#define BTIF_BLP_SNIFF_MODE 0x0004 +#define BTIF_BLP_PARK_MODE 0x0008 +#define BTIF_BLP_SCATTER_MODE 0x0010 + +/* Mask must be updated if new policy values are added */ +#define BLP_MASK 0xfff0 /* Disables ScatterNet bit */ +#define BLP_SCATTER_MASK 0xffe0 /* Enables ScatterNet bit */ + +typedef uint8_t btif_accessible_mode_t; + +#define BTIF_BAM_NOT_ACCESSIBLE 0x00 /* Non-discoverable or connectable */ +#define BTIF_BAM_GENERAL_ACCESSIBLE 0x03 /* General discoverable and connectable */ +#define BTIF_BAM_LIMITED_ACCESSIBLE 0x13 /* Limited discoverable and connectable */ +#define BTIF_BAM_CONNECTABLE_ONLY 0x02 /* Connectable but not discoverable */ +#define BTIF_BAM_DISCOVERABLE_ONLY 0x01 /* Discoverable but not connectable */ +#define BTIF_BT_DEFAULT_ACCESS_MODE_PAIR BTIF_BAM_GENERAL_ACCESSIBLE +#define BTIF_BAM_INVALID_ACCESS_MODE 0xFF + +/* End of BtAccessibleMode */ + +typedef uint8_t btif_oob_data_present_t; + +#define BTIF_OOB_DATA_NOT_PRESENT 0 /* No Out of Band Data is present */ +#define BTIF_OOB_DATA_PRESENT 1 /* Out of Band Data is present */ + +typedef uint8_t btif_auth_requirements_t; + +#define BTIF_MITM_PROTECT_NOT_REQUIRED 0x00 /* No Man in the Middle protection */ +#define BTIF_MITM_PROTECT_REQUIRED 0x01 /* Man in the Middle protection req */ + +typedef uint8_t btif_link_mode_t; + +#define BTIF_BLM_ACTIVE_MODE 0x00 +#define BTIF_BLM_HOLD_MODE 0x01 +#define BTIF_BLM_SNIFF_MODE 0x02 +#define BTIF_BLM_PARK_MODE 0x03 +#define BTIF_BLM_SCATTER_MODE 0x04 + +typedef uint8_t btif_link_key_type_t; + +#define BTIF_COMBINATION_KEY 0x00 +#define BTIF_LOCAL_UNIT_KEY 0x01 +#define BTIF_REMOTE_UNIT_KEY 0x02 +#define BTIF_DEBUG_COMBINATION_KEY 0x03 +#define BTIF_UNAUTH_COMBINATION_KEY 0x04 +#define BTIF_AUTH_COMBINATION_KEY 0x05 +#define BTIF_CHANGED_COMBINATION_KEY 0x06 +#define BTIF_IBRT_STORE_ADDR_ONLY 0x07 + +typedef uint8_t btif_connection_role_t; + +#define BTIF_BCR_MASTER 0x00 +#define BTIF_BCR_SLAVE 0x01 +#define BTIF_BCR_ANY 0x02 +#define BTIF_BCR_UNKNOWN 0x03 +#define BTIF_BCR_PSLAVE 0x04 +#define BTIF_BCR_PMASTER 0x05 + +typedef uint8_t btif_stack_state_t; + +typedef enum { + HCI_CMD_COMPLETE_USER_IBRT_CMD = 0, + HCI_CMD_COMPLETE_USER_BLE = 1, + HCI_CMD_COMPLETE_USER_RESEVER_1 = 2, + HCI_CMD_COMPLETE_USER_RESEVER_2 = 3, + HCI_CMD_COMPLETE_USER_RESEVER_3 = 4, + HCI_CMD_COMPLETE_USER_RESEVER_4 = 5, + + HCI_CMD_COMPLETE_USER_NUM, +}HCI_CMD_COMPLETE_USER_E; + +/* The stack has completed initialization of the radio hardware. */ +#define BTIF_BTSS_NOT_INITIALIZED 0 + +/* The stack is initialized. */ +#define BTIF_BTSS_INITIALIZED 1 + +/* The stack has encountered an error while initializing the radio hardware. */ +#define BTIF_BTSS_INITIALIZE_ERR 2 + +/* The stack is deinitializing. */ +#define BTIF_BTSS_DEINITIALIZE 3 + +/* End of BtStackState */ +typedef void btif_remote_device_t; + + +typedef void btif_BtDeviceContext; + + +/* Forward declaration of the callback parameters */ +typedef void btif_event_t; + +typedef void (*btif_callback) (const void *); +typedef void (*ibrt_cmd_status_callback)(const uint8_t *para); +typedef void (*ibrt_cmd_complete_callback)(const uint8_t *para); +typedef uint8_t (*btif_callback_ext) (const void *); +typedef uint8_t (*btif_callback_ext2) (void); +typedef void (*btif_callback_ext3) (void); + +typedef uint8_t btif_inquiry_mode_t; + +#define BTIF_INQ_MODE_NORMAL 0 /* Normal Inquiry Response format */ +#define BTIF_INQ_MODE_RSSI 1 /* RSSI Inquiry Response format */ +#define BTIF_INQ_INVALID_RSSI 127 /* RSSI Inquiry Response format */ +#define BTIF_INQ_MODE_EXTENDED 2 /* Extended or RSSI Inquiry Response format */ + +typedef uint8_t btif_rem_dev_state_t; + +#define BTIF_BDS_DISCONNECTED 0x00 +#define BTIF_BDS_OUT_CON 0x01 /* Starting an out going connection */ +#define BTIF_BDS_IN_CON 0x02 /* In process of incoming connection */ +#define BTIF_BDS_CONNECTED 0x03 /* Connected */ +#define BTIF_BDS_OUT_DISC 0x04 /* Starting an out going disconnect */ +#define BTIF_BDS_OUT_DISC2 0x05 /* Disconnect status received */ +#define BTIF_BDS_OUT_CON2 0x06 /* In SCO, used when connection request has + been sent */ + +typedef uint8_t btif_eir_data_type_t; + +#define BTIF_EIR_FLAGS 0x01 +#define BTIF_EIR_SRV_CLASS_16_PART 0x02 +#define BTIF_EIR_SRV_CLASS_16_WHOLE 0x03 +#define BTIF_EIR_SRV_CLASS_32_PART 0x04 +#define BTIF_EIR_SRV_CLASS_32_WHOLE 0x05 +#define BTIF_EIR_SRV_CLASS_128_PART 0x06 +#define BTIF_EIR_SRV_CLASS_128_WHOLE 0x07 +#define BTIF_EIR_REM_NAME_PART 0x08 +#define BTIF_EIR_REM_NAME_WHOLE 0x09 +#define BTIF_EIR_TX_POWER 0x0A +#define BTIF_EIR_MAN_SPECIFIC 0xFF + +#define BTIF_BR_USE_FEC (0<<0) +#define BTIF_BR_NOT_USE_FEC (1<<0) +#define BTIF_BR_NO_PKT_PRFER_AVALB (0<<1) +#define BTIF_BR_USE_1_SLOT_PKT (1<<1) +#define BTIF_BR_USE_3_SLOT_PKT (2<<1) +#define BTIF_BR_USE_5_SLOT_PKT (3<<1) +#define BTIF_EDR_USE_DM1_PKT (0<<3) +#define BTIF_EDR_USE_2MB_PKT (1<<3) +#define BTIF_EDR_USE_3MB_PKT (2<<3) +#define BTIF_EDR_NO_PKT_PRFER_AVALB (0<<5) +#define BTIF_EDR_USE_1_SLOT_PTK (1<<5) +#define BTIF_EDR_USE_3_SLOT_PTK (2<<5) +#define BTIF_EDR_USE_5_SLOT_PTK (3<<5) + +#define CONN_AUTO_ACCEPT_DISABLE 0x01 + +#define CONN_AUTO_ACCEPT_ENABLE_WITH_MSS_DISABLE 0x02 + +#define CONN_AUTO_ACCEPT_ENABLE_WITH_MSS_ENABLE 0x03 +/*--------------------------------------------------------------------------- + * btif_class_of_device_t type + * + * Bit pattern representing the class of device along with the + * supported services. There can be more than one supported service. + * Service classes can be ORed together. The Device Class is composed + * of a major device class plus a minor device class. ORing together + * each service class plus one major device class plus one minor device + * class creates the class of device value. The minor device class is + * interpreted in the context of the major device class. + */ + +typedef uint32_t btif_class_of_device_t; + +/* Group: Major Service Classes. Can be ORed together */ +#define BTIF_COD_LIMITED_DISCOVERABLE_MODE 0x00002000 +#define BTIF_COD_POSITIONING 0x00010000 +#define BTIF_COD_NETWORKING 0x00020000 +#define BTIF_COD_RENDERING 0x00040000 +#define BTIF_COD_CAPTURING 0x00080000 +#define BTIF_COD_OBJECT_TRANSFER 0x00100000 +#define BTIF_COD_AUDIO 0x00200000 +#define BTIF_COD_TELEPHONY 0x00400000 +#define BTIF_COD_INFORMATION 0x00800000 + +/* Group: Major Device Classes (Select one) */ +#define BTIF_COD_MAJOR_MISCELLANEOUS 0x00000000 +#define BTIF_COD_MAJOR_COMPUTER 0x00000100 +#define BTIF_COD_MAJOR_PHONE 0x00000200 +#define BTIF_COD_MAJOR_LAN_ACCESS_POINT 0x00000300 +#define BTIF_COD_MAJOR_AUDIO 0x00000400 +#define BTIF_COD_MAJOR_PERIPHERAL 0x00000500 +#define BTIF_COD_MAJOR_IMAGING 0x00000600 +#define BTIF_COD_MAJOR_UNCLASSIFIED 0x00001F00 + +/* Group: Minor Device Class - Computer Major class */ +#define BTIF_COD_MINOR_COMP_UNCLASSIFIED 0x00000000 +#define BTIF_COD_MINOR_COMP_DESKTOP 0x00000004 +#define BTIF_COD_MINOR_COMP_SERVER 0x00000008 +#define BTIF_COD_MINOR_COMP_LAPTOP 0x0000000C +#define BTIF_COD_MINOR_COMP_HANDHELD 0x00000010 +#define BTIF_COD_MINOR_COMP_PALM 0x00000014 +#define BTIF_COD_MINOR_COMP_WEARABLE 0x00000018 + +/* Group: Minor Device Class - Phone Major class */ +#define BTIF_COD_MINOR_PHONE_UNCLASSIFIED 0x00000000 +#define BTIF_COD_MINOR_PHONE_CELLULAR 0x00000004 +#define BTIF_COD_MINOR_PHONE_CORDLESS 0x00000008 +#define BTIF_COD_MINOR_PHONE_SMART 0x0000000C +#define BTIF_COD_MINOR_PHONE_MODEM 0x00000010 +#define BTIF_COD_MINOR_PHONE_ISDN 0x00000014 + +/* Group: Minor Device Class - LAN Access Point Major class */ +#define BTIF_COD_MINOR_LAN_0 0x00000000 /* fully available */ +#define BTIF_COD_MINOR_LAN_17 0x00000020 /* 1-17% utilized */ +#define BTIF_COD_MINOR_LAN_33 0x00000040 /* 17-33% utilized */ +#define BTIF_COD_MINOR_LAN_50 0x00000060 /* 33-50% utilized */ +#define BTIF_COD_MINOR_LAN_67 0x00000080 /* 50-67% utilized */ +#define BTIF_COD_MINOR_LAN_83 0x000000A0 /* 67-83% utilized */ +#define BTIF_COD_MINOR_LAN_99 0x000000C0 /* 83-99% utilized */ +#define BTIF_COD_MINOR_LAN_NO_SERVICE 0x000000E0 /* 100% utilized */ + +/* Group: Minor Device Class - Audio Major class */ +#define BTIF_COD_MINOR_AUDIO_UNCLASSIFIED 0x00000000 +#define BTIF_COD_MINOR_AUDIO_HEADSET 0x00000004 +#define BTIF_COD_MINOR_AUDIO_HANDSFREE 0x00000008 +#define BTIF_COD_MINOR_AUDIO_MICROPHONE 0x00000010 +#define BTIF_COD_MINOR_AUDIO_LOUDSPEAKER 0x00000014 +#define BTIF_COD_MINOR_AUDIO_HEADPHONES 0x00000018 +#define BTIF_COD_MINOR_AUDIO_PORTABLEAUDIO 0x0000001C +#define BTIF_COD_MINOR_AUDIO_CARAUDIO 0x00000020 +#define BTIF_COD_MINOR_AUDIO_SETTOPBOX 0x00000024 +#define BTIF_COD_MINOR_AUDIO_HIFIAUDIO 0x00000028 +#define BTIF_COD_MINOR_AUDIO_VCR 0x0000002C +#define BTIF_COD_MINOR_AUDIO_VIDEOCAMERA 0x00000030 +#define BTIF_COD_MINOR_AUDIO_CAMCORDER 0x00000034 +#define BTIF_COD_MINOR_AUDIO_VIDEOMONITOR 0x00000038 +#define BTIF_COD_MINOR_AUDIO_VIDEOSPEAKER 0x0000003C +#define BTIF_COD_MINOR_AUDIO_CONFERENCING 0x00000040 +#define BTIF_COD_MINOR_AUDIO_GAMING 0x00000048 + +/* Group: Minor Device Class - Peripheral Major class */ +#define BTIF_COD_MINOR_PERIPH_KEYBOARD 0x00000040 +#define BTIF_COD_MINOR_PERIPH_POINTING 0x00000080 +#define BTIF_COD_MINOR_PERIPH_COMBOKEY 0x000000C0 +/* Group: Minor Device Class - ORed with Peripheral Minor Device class */ +#define BTIF_COD_MINOR_PERIPH_UNCLASSIFIED 0x00000000 +#define BTIF_COD_MINOR_PERIPH_JOYSTICK 0x00000004 +#define BTIF_COD_MINOR_PERIPH_GAMEPAD 0x00000008 +#define BTIF_COD_MINOR_PERIPH_REMOTECTRL 0x0000000C +#define BTIF_COD_MINOR_PERIPH_SENSING 0x00000010 +#define BTIF_COD_MINOR_PERIPH_DIGITIZER 0x00000014 +#define BTIF_COD_MINOR_PERIPH_CARD_RDR 0x00000018 + +/* Group: Minor Device Class - Imaging Major class */ +#define BTIF_COD_MINOR_IMAGE_UNCLASSIFIED 0x00000000 +#define BTIF_COD_MINOR_IMAGE_DISPLAY 0x00000010 +#define BTIF_COD_MINOR_IMAGE_CAMERA 0x00000020 +#define BTIF_COD_MINOR_IMAGE_SCANNER 0x00000040 +#define BTIF_COD_MINOR_IMAGE_PRINTER 0x00000080 + +/* Group: Masks used to isolate the class of device components */ +#define BTIF_COD_SERVICE_MASK 0x00ffC000 /* Less LIAC bit */ +#define BTIF_COD_MAJOR_MASK 0x00001F00 +#define BTIF_COD_MINOR_MASK 0x000000FC +#define BTIF_COD_LIMITED_DISC_MASK 0x00002000 /* LIAC bit */ + +/* End of btif_class_of_device_t */ + +//when report_format=0,data_format will set the interval(unit:slot) +//when report_format=1,data_format will set the packet total num +//when report_format=2,data_format has no meaning +#define FLAG_RESET_DATA 2 +#define FLAG_START_DATA 1 +#define FLAG_GET_DATA 0 + +#define REP_FORMAT_TIME 0 +#define REP_FORMAT_PACKET 1 +#define REP_FORMAT_STOP_GET 2 + + +//Vendor defined error code +#define BTIF_EVT_ERROR_SCO_UNKNOWN (0xE8) +#define BTIF_EVT_ERROR_ACL_UNKNOWN (0xE9) + + +typedef struct { + list_entry_t node; + uint8_t opType; +} btif_operation_t; + +typedef struct { + + /* the mandatory sniff interval range for controllers is between 0x0006 and 0x0540. + * The value is expressed in 0.625 ms increments (0x0006 = 3.75 ms). + * + * The actual interval selected by the radio will be returned in + * a BTEVENT_MODE_CHANGE event. + */ + + uint16_t maxInterval; + + /* Minimum acceptable interval between each consecutive sniff period. + * Must be an even number between 0x0002 and 0xFFFE, and be less than + * "maxInterval". Like maxInterval this value is expressed in + * 0.625 ms increments. + */ + uint16_t minInterval; + + /* The number of master-to-slave transmission slots during which + * a device should listen for traffic (sniff attempt). + * Expressed in 0.625 ms increments. May be between 0x0001 and 0x7FFF. + */ + uint16_t attempt; + + /* The amount of time before a sniff timeout occurs. Expressed in + * 1.25 ms increments. May be between 0x0000 and 0x7FFF, but the mandatory + * range for controllers is 0x0000 to 0x0028. + */ + uint16_t timeout; +} btif_sniff_info_t; + +typedef struct { + + /* May be any number between 0x0000 and 0xFFFE. The value is expressed in 0.625 ms + * increments. + */ + uint16_t maxLatency; + + /* any number between 0x0000 and 0xFFFE. The value is expressed in + * 0.625 ms increments. + */ + uint16_t minRemoteTimeout; + + /* Minimum base sniff subrate timeout that the local device may use. + * May be any number between 0x0000 and 0xFFFE. The value is expressed in + * 0.625 ms increments. + */ + uint16_t minLocalTimeout; +} btif_sniff_subrate_parms_t; + +typedef struct { + uint16_t inqInterval; /* Inquiry scan interval */ + uint16_t inqWindow; /* Inquiry scan Window */ + uint16_t pageInterval; /* Page scan interval */ + uint16_t pageWindow; /* Page scan window */ +} btif_access_mode_info_t; + +typedef struct { + list_entry_t node; /* For internal stack use only. */ + btif_callback callback; /* Pointer to callback function */ + btif_event_mask_t emask; /* For internal stack use only. */ +} btif_handler; + +/* Internal types required for BtRemoteDevice structure */ +typedef uint8_t btif_auth_state_t; + +typedef uint8_t btif_encrypt_state_t; + +typedef uint8_t btif_authorize_state_t; + +typedef uint8_t btif_sec_access_state_t; + +typedef uint8_t btif_link_rx_state_t; + +typedef uint8_t btif_op_type_t; + +typedef struct { + + /* Reserved */ + uint8_t flags; + + /* Service Type: 0 = No Traffic, 1 = Best Effort, 2 Guaranteed */ + uint8_t serviceType; + + /* Token Rate in octets per second */ + uint32_t tokenRate; + + /* Peak Bandwidth in octets per second */ + uint32_t peakBandwidth; + + /* Latency in microseconds */ + uint32_t latency; + + /* Delay Variation in microseconds */ + uint32_t delayVariation; +} btif_qos_info_t; + +typedef struct { + bt_bdaddr_t bdAddr; + BOOL trusted; + uint8_t linkKey[16]; + btif_link_key_type_t keyType; + + uint8_t pinLen; +} btif_device_record_t; + +typedef struct { + btif_operation_t op; + uint8_t len; + uint8_t data[31]; +} btif_write_adv_data_op_t; + +typedef struct { + uint16_t interval_min; + uint16_t interval_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t peer_addr_type; + bt_bdaddr_t bd_addr; + uint8_t adv_chanmap; + uint8_t adv_filter_policy; +} btif_adv_para_struct_t; + +typedef struct { + btif_operation_t op; + btif_adv_para_struct_t adv_para; +} btif_write_adv_para_op_t; + +typedef struct { + btif_operation_t op; + uint8_t en; +} btif_write_adv_en_op_t; + +#define BLE_ADV_REPORT_MAX_LEN 31 + +typedef struct { + uint8_t type; + uint8_t addr_type; + bt_bdaddr_t addr; + uint8_t data_len; + uint8_t data[BLE_ADV_REPORT_MAX_LEN]; + int8_t rssi; +} btif_ble_adv_report; + +typedef struct { + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_addr_type; + uint8_t scan_filter_policy; +} btif_scan_para_struct_t; + +typedef struct { + btif_operation_t op; + btif_scan_para_struct_t scan_para; +} btif_write_scan_para_op_t; + +typedef struct { + btif_operation_t op; + uint8_t scan_en; + uint32_t filter_duplicat; +} btif_write_scan_en_op_t; + +typedef struct +{ + bt_bdaddr_t bdAddr; /* Device Address */ + uint8_t linkKey[16]; +} btif_dev_linkkey; + +typedef struct +{ + U8 psRepMode; + U8 psMode; + U16 clockOffset; +} bt_page_scanInfo_t; + +typedef struct +{ + bt_bdaddr_t bdAddr; /* Device Address */ + bt_page_scanInfo_t psi; /* Page scan info used for connecting */ + U8 psPeriodMode; + U32 classOfDevice; + + /* RSSI in dBm (-127 to +20). Only valid when controller reports RSSI with + * in inquiry results (also see ME_SetInquiryMode). Otherwise it will be + * set to BT_INVALID_RSSI. + */ + S8 rssi; + + /* Extended Inquiry response. Only valid when controller reports an + * extended inquiry (also see ME_SetInquiryMode). Otherwise it will be + * set to all 0's. + */ + U8 extInqResp[240]; + + /* Describes the format of the current inquiry result */ + U8 inqMode; + +} bt_Inquiry_result_t; + +typedef struct +{ + /* Event causing callback. Always valid.*/ + uint8_t eType; + + /* Error code. See BtEventType for guidance on whether errCode is valid. */ + uint8_t errCode; + + /* Pointer to handler. Only valid for events directed to BtHandlers. */ + btif_handler *handler; + + /* Parameters */ + union + { + btif_accessible_mode_t aMode; /* New access mode */ + void *remDev; /* Pointer to remote device */ + bt_bdaddr_t bdAddr; /* Device Address */ + void *meToken; /* Me command token */ + U8 pMode; /* Simple Pairing Mode */ + +#ifdef __TWS_RECONNECT_USE_BLE__ + struct + { + U8 *data; + U16 len; + } twsBleReport; +#endif + bt_Inquiry_result_t inqResult; + + void *secToken; /* Security Token */ + void *token; + + /* Information for BTEVENT_PAIRING_COMPLETE */ + struct + { + void *remDev; + btif_link_key_type_t keyType; + } pairingInfo; + + /* Information for BTEVENT_PIN_REQ */ + struct + { + void *remDev; + + /* If > 0 then the pin length returned in SEC_SetPin must be >= pinLen */ + U8 pinLen; + } pinReq; + + /* Information for BTEVENT_SET_INQUIRY_MODE_CNF */ + btif_inquiry_mode_t inqMode; + + /* Information for BTEVENT_SET_INQ_TX_PWR_LVL_CNF */ + S8 inqTxPwr; + + /* Information for BTEVENT_REMOTE_FEATURES */ + struct + { + bt_bdaddr_t bdAddr; + U8 features[8]; + } remoteFeatures; + + /* Information for BTEVENT_REM_HOST_FEATURES */ + struct + { + bt_bdaddr_t bdAddr; + U8 features[8]; + } remHostFeatures; + + /* Information for BTEVENT_LINK_SUPERV_TIMEOUT_CHANGED */ + struct + { + void *remDev; + U16 timeout; + } linkSupervision; + + /* Information for BTEVENT_MAX_SLOT_CHANGED */ + struct + { + U16 connHandle; + U8 maxSlot; + } maxSlotChanged; + + /* Information for BTEVENT_QOS_SETUP_COMPLETE */ + struct + { + + /* Reserved */ + U8 flags; + + /* Service Type: 0 = No Traffic, 1 = Best Effort, 2 Guaranteed */ + U8 serviceType; + + /* Token Rate in octets per second */ + U32 tokenRate; + + /* Peak Bandwidth in octets per second */ + U32 peakBandwidth; + + /* Latency in microseconds */ + U32 latency; + + /* Delay Variation in microseconds */ + U32 delayVariation; + } qos; + + /* Result for BTEVENT_SET_SNIFF_SUBRATING_PARMS_CNF */ + btif_sniff_subrate_parms_t *sniffSubrateParms; + + /* Information for BTEVENT_SNIFF_SUBRATE_INFO */ + struct + { + /* Pointer to the remote device */ + void *remDev; + + /* Maximum latency for data being transmitted from the local + * device to the remote device. + */ + U16 maxTxLatency; + + /* Maximum latency for data being received by the local + * device from the remote device. + */ + U16 maxRxLatency; + + /* The base sniff subrate timeout in baseband slots that the + * remote device shall use. + */ + U16 minRemoteTimeout; + + /* The base sniff subrate timeout in baseband slots that the + * local device will use. + */ + U16 minLocalTimeout; + } sniffSubrateInfo; + + /* Result for BTEVENT_LOCAL_OOB_DATA */ + struct + { + /* Simple Pairing Hash C from the local device */ + U8 hashC[16]; + + /* Simple Pairing Randomizer R the local device */ + U8 randR[16]; + } oobData; + + /* Information for BTEVENT_CONFIRM_NUMERIC_REQ, BTEVENT_PASS_KEY_REQ, + * and BTEVENT_DISPLAY_NUMERIC_IND + */ + struct + { + void *remDev; /* Pointer to the remote device */ + U32 numeric; /* Numeric value received from Secure + * Simple Pairing (not valid for + * BTEVENT_PASS_KEY_REQ + */ + + U8 bondingMode; /* Bonding has been requested */ + } userIoReq; + + /* Result for BTEVENT_ENCRYPTION_CHANGE event. */ + struct + { + void *remDev; + U8 mode; /* New encryption mode (uses the + * BtEncryptMode type) */ + } encrypt; + + /* Result for BTEVENT_KEY_PRESSED */ + struct + { + bt_bdaddr_t bdAddr; /* Address of the device sending the keypress */ + U8 parm; /* The value of the keypress parameter */ + } keyPress; + + struct + { + void *remDev; + + /* If disconnection was successful, contains BEC_NO_ERROR. + * errCode will contain the disconnect reason. + * + * Unsuccessful disconnections will contain an error code + * as generated by the radio. In this case, errCode can be + * ignored. + */ + btif_error_code_t status; + } disconnect; + + /* Result for the BTEVENT_SCO_DATA_CNF event */ + struct + { + void *remDev; /* Pointer to remote device */ + void *scoCon; /* SCO connection */ + void *scoPacket; /* SCO Packet Handled */ + } scoPacketHandled; + + /* Result for the BTEVENT_SCO_CONNECT_CNF && BTEVENT_SCO_CONNECT_IND + events. + */ + struct + { + void *remDev; /* Pointer to remote device */ + U16 scoHandle; /* SCO Connection handle for HCI */ + void *scoCon; /* SCO connection */ + U8 scoLinkType;/* SCO link type */ + void *scoTxParms; /* Pointer to eSCO TX parameters */ + void *scoRxParms; /* Pointer to eSCO RX parameters */ + } scoConnect; + + /* Result for the BTEVENT_SCO_DATA_IND event */ + struct + { + void *remDev; /* Pointer to remote device */ + U16 scoHandle; /* SCO Connection handle for HCI */ + void *scoCon; /* SCO connection. */ + U8 len; /* SCO data len */ + U8 *ptr; /* SCO data ptr */ + U8 errFlags; /* Erroneous Data Reporting */ + } scoDataInd; + + /* Result for the BTEVENT_SECURITY_CHANGE and + * BTEVENT_SECURITY3_COMPLETE events + */ + struct + { + U8 mode; /* New security mode (uses the BtSecurityMode + * type). */ + BOOL encrypt; /* Indicate if encryption set or not */ + } secMode; + + /* Results for the BTEVENT_MODE_CHANGE event */ + struct + { + void *remDev; + uint8_t curMode; + U16 interval; + } modeChange; + + /* Results for BTEVENT_ROLE_CHANGE */ + struct + { + void *remDev; + uint8_t newRole; /* New role */ + } roleChange; + + /* Results for BTEVENT_ACL_DATA_ACTIVE */ + struct + { + void *remDev; + uint16_t dataLen; /* ACL data length */ + } aclDataActive; + + /* Results for BTEVENT_ACL_DATA_NOT_ACTIVE */ + struct + { + void *remDev; + uint16_t dataLen; /* ACL data length */ + } aclDataNotActive; + struct + { + uint8_t status; + bt_bdaddr_t bdAddr; /* Address of the device sending the keypress */ + }name_rsp; + struct + { + btif_remote_device_t *conn; + }conn_req; + } edata; +} event_t; + +typedef struct +{ + event_t *evt; + btif_event_mask_t mask; +} me_event_t; +typedef bool (*ibrt_io_capbility_callback)(void *bdaddr); +typedef void (*ibrt_disconnect_callback)(const void *event); +typedef void (*btif_cmgr_callback) (void *handler, uint8_t event, bt_status_t status); +typedef void (*btif_global_handle)(const btif_event_t *Event); + +#ifdef __cplusplus +extern "C" { +#endif /* */ + bt_status_t btif_me_get_tws_slave_mobile_rssi(uint16_t ConnHandle); + + void btif_me_set_sniffer_env(uint8_t sniffer_acitve, uint8_t sniffer_role, + uint8_t * monitored_addr, uint8_t * sniffer_addr); + BOOL btif_me_get_remote_device_initiator(btif_remote_device_t * rdev); + uint16_t btif_me_get_remote_device_hci_handle(btif_remote_device_t * rdev); + btif_remote_device_t* btif_me_get_remote_device_by_handle(uint16_t hci_handle); + uint16_t btif_me_get_hci_handle_by_remote_dev(btif_remote_device_t *p_remote_dev); + btif_remote_device_t* btif_me_get_remote_device_by_bdaddr(bt_bdaddr_t *bdaddr); + uint8_t btif_me_get_remote_device_op_optype(btif_remote_device_t * rdev); + btif_connection_role_t btif_me_get_remote_device_role(btif_remote_device_t * rdev); + void btif_me_set_remote_device_role(btif_remote_device_t * rdev, uint8_t role); + BOOL *btif_me_get_remote_device_new_link_key(btif_remote_device_t * rdev); + void *btif_me_get_remote_device_parms(btif_remote_device_t * rdev); + bt_status_t btif_me_exchange_bt_addr(uint16_t connHandle); + bool btif_me_role_switch_pending(uint16_t handle); + bool btif_me_is_tws_role_switch_pending(); + bool btif_me_is_exechange_bt_addr_pending(); + bool is_btif_me_current_role_bcr_master(btif_remote_device_t * device); + bt_status_t btif_me_inquiry(uint32_t lap, uint8_t len, uint8_t maxResp); + bt_status_t btif_me_ble_add_dev_to_whitelist(uint8_t addr_type, bt_bdaddr_t * addr); + bt_status_t btif_me_ble_clear_whitelist(void); + bt_status_t btif_me_ble_set_private_address(bt_bdaddr_t * addr); + bt_status_t btif_me_ble_set_adv_data(uint8_t len, uint8_t * data); + bt_status_t btif_me_ble_set_scan_rsp_data(U8 len, U8 * data); + bt_status_t btif_me_ble_set_adv_parameters(btif_adv_para_struct_t * para); + bt_status_t btif_me_ble_set_adv_en(uint8_t en); + bt_status_t btif_me_ble_set_scan_parameter(btif_scan_para_struct_t * para); + bt_status_t btif_me_ble_set_scan_en(uint8_t scan_en, uint8_t filter_duplicate); + bt_status_t btif_me_ble_receive_adv_report(void (*cb)(const btif_ble_adv_report* report)); + bt_status_t btif_sec_find_device_record(const bt_bdaddr_t * bdAddr, + btif_device_record_t * record); + + uint8_t btif_sec_set_io_capabilities(uint8_t ioCap); + uint8_t btif_sec_set_authrequirements(uint8_t authRequirements); + uint8_t btif_me_get_callback_event_type(const btif_event_t * event); + uint8_t btif_me_get_callback_event_rem_dev_role(const btif_event_t * event); + bt_bdaddr_t *btif_me_get_callback_event_rem_dev_bd_addr(const btif_event_t * event); + bt_bdaddr_t *btif_me_get_callback_event_disconnect_rem_dev_bd_addr(const btif_event_t * + event); + btif_remote_device_t *btif_me_get_callback_event_disconnect_rem_dev(const btif_event_t * + event); + btif_remote_device_t *btif_me_get_callback_event_role_change_rem_dev(const btif_event_t *event); + uint8_t btif_me_get_callback_event_disconnect_rem_dev_disc_reason_saved(const btif_event_t * + event); + uint8_t btif_me_get_callback_event_disconnect_rem_dev_disc_reason(const btif_event_t * + event); + + uint8_t btif_me_get_pendCons(void); + + uint8_t btif_me_get_activeCons(void); + + void btif_me_set_pendCons(uint8_t pendCons); + + void btif_me_set_activeCons(uint8_t activeCons ); + + btif_remote_device_t *btif_me_get_callback_event_rem_dev(const btif_event_t * event); + + btif_BtDeviceContext* btif_me_get_bt_device_context(const btif_event_t * event); + + uint16_t btif_me_get_scohdl_by_connhdl(uint16_t conn_handle); + btif_remote_device_t *btif_me_get_callback_event_sco_connect_rem_dev(const btif_event_t * + event); + uint8_t btif_me_get_callback_event_role_change_new_role(const btif_event_t * event); + bt_bdaddr_t *btif_me_get_callback_event_inq_result_bd_addr(const btif_event_t * event); + uint8_t *btif_me_get_callback_event_inq_result_bd_addr_addr(const btif_event_t * event); + uint8_t btif_me_get_callback_event_inq_result_inq_mode(const btif_event_t * event); + uint8_t btif_me_get_callback_event_rssi(const btif_event_t *event); + uint8_t *btif_me_get_callback_event_inq_result_ext_inq_resp(const btif_event_t * event); + uint32_t btif_me_get_callback_event_inq_result_classofdevice(const btif_event_t *event); + uint8_t btif_me_get_callback_event_err_code(const btif_event_t * event); + uint8_t btif_me_get_callback_event_a_mode(const btif_event_t * event); + uint16_t btif_me_get_callback_event_max_slot_changed_connHandle(const btif_event_t * event); + uint8_t btif_me_get_callback_event_max_slot_changed_max_slot(const btif_event_t * event); + uint8_t btif_me_get_callback_event_mode_change_curMode(const btif_event_t * event); + uint16_t btif_me_get_callback_event_mode_change_interval(const btif_event_t * event); + + uint16_t btif_me_get_callback_event_remote_dev_name(const btif_event_t * event, uint8_t** ppName); + + bt_status_t btif_me_get_remote_device_name(const bt_bdaddr_t * bdAddr, btif_global_handle handler); + + uint8_t btif_me_get_ext_inq_data(uint8_t * eir, btif_eir_data_type_t type, + uint8_t * outBuffer, uint8_t Length); + bt_status_t btif_me_cancel_inquiry(void); + bt_status_t btif_sec_delete_device_record(const bt_bdaddr_t * bdAddr); + bt_status_t btif_me_cancel_create_link(btif_handler * handler, + btif_remote_device_t * rdev); + void btif_me_set_handler(void *handler, btif_callback cb); + uint8_t btif_me_set_connection_role(uint8_t role); + bt_status_t btif_me_disconnect_link(btif_handler * handler, + btif_remote_device_t * rdev); + bt_status_t btif_me_set_link_policy(btif_remote_device_t * rdev, + btif_link_policy_t policy); + bt_status_t btif_me_set_link_lowlayer_monitor(btif_remote_device_t * rdev, uint8_t control_flag,uint8_t report_format, + uint32_t data_format,uint8_t report_unit); + bt_status_t btif_me_set_connection_qos_info(btif_remote_device_t * rdev, + btif_qos_info_t * qosInfo); + void btif_me_fake_tws_disconnect(uint16_t hci_handle, uint8_t reason); + void btif_me_fake_mobile_disconnect(uint16_t hci_handle, uint8_t reason); + void btif_me_fake_tws_connect(uint8_t status, uint16_t hci_handle, bt_bdaddr_t * bdAddr); + void btif_me_reset_bt_controller(void); + void btif_me_fake_mobile_connect(uint8_t status, uint16_t hci_handle, bt_bdaddr_t *bdAddr); + + bt_status_t btif_me_set_lbrt_enable(uint16_t connHandle, uint8_t enable); + bt_status_t btif_me_set_accessible_mode(btif_accessible_mode_t mode, + const btif_access_mode_info_t * info); + bt_status_t btif_me_write_page_timeout(uint16_t timeout); + bool btif_me_is_op_in_progress(btif_remote_device_t * rdev); + bt_status_t btif_me_switch_role(btif_remote_device_t * rdev); + bt_status_t btif_me_register_global_handler(void *handler); + void *btif_me_register_accept_handler(void *handler); + bt_status_t btif_me_set_event_mask(void *handler, btif_event_mask_t mask); + void *btif_me_get_bt_handler(void); + bt_status_t btif_me_set_bt_address(uint8_t * btAddr); + bt_status_t btif_me_set_local_device_name(const U8 *name, U8 length); + bt_status_t btif_me_set_ble_bd_address(uint8_t * btAddr); + bt_status_t btif_sec_add_device_record(btif_device_record_t * record); + bt_status_t btif_enum_device_record(U16 dev_id, btif_device_record_t *record); + bt_bdaddr_t *btif_me_get_remote_device_bdaddr(btif_remote_device_t * rdev); + btif_rem_dev_state_t btif_me_get_remote_device_state(btif_remote_device_t * rdev); + btif_link_mode_t btif_me_get_remote_device_mode(btif_remote_device_t * rdev); + btif_authorize_state_t btif_me_get_remote_device_auth_state(btif_remote_device_t * rdev); + bt_status_t btif_me_write_link_superv_timeout(uint16_t handle, uint16_t slots); + btif_link_mode_t btif_me_get_current_mode(btif_remote_device_t * rdev); + btif_connection_role_t btif_me_get_current_role(btif_remote_device_t * rdev); + + bt_status_t btif_me_start_sniff(btif_remote_device_t * rdev, btif_sniff_info_t* info); + + bt_status_t btif_me_stop_sniff(btif_remote_device_t * rdev); + + bt_status_t btif_me_accept_incoming_link(const btif_event_t *event,btif_remote_device_t * rdev, btif_connection_role_t role); + + bt_status_t btif_me_reject_incoming_link(btif_remote_device_t * rdev, btif_error_code_t reason); + + bt_status_t btif_me_start_tws_role_switch(uint16_t slaveConnHandle, uint16_t mobileConnHandle); + bt_status_t btif_me_set_sco_tx_silence(uint16_t connHandle, uint8_t silence_on); + void btif_me_increase_active_counts(void); + bool btif_me_is_sending_data_to_peer_dev_pending(void); + btif_handler *btif_me_get_me_handler(void); + bt_status_t btif_me_force_disconnect_link_with_reason(btif_handler * handler, + btif_remote_device_t * rdev, + uint8_t reason, BOOL forceDisconnect); + + void btif_me_sec_set_io_cap_rsp_reject_ext(BOOL(*ext_fn) (void *)); + void btif_me_write_bt_sleep_enable(uint8_t sleep_en); + void btif_me_write_bt_page_scan_type(uint8_t scan_type); + void btif_me_write_bt_inquiry_scan_type(uint8_t scan_type); + +#if IS_USE_INTERNAL_ACL_DATA_PATH + bt_status_t btif_me_send_data_to_peer_dev(uint16_t connHandle, uint8_t dataLen, uint8_t * data); +#endif /* */ + void btif_bt_call_back(const btif_event_t * event); + void btif_me_init_handler(btif_handler * handler); + bt_status_t btif_me_dbg_sniffer_interface(uint16_t connHandle, uint8_t subCode); + bt_status_t btif_me_switch_sco(uint16_t scohandle); + uint8_t *btif_me_get_remote_device_version(btif_remote_device_t * rdev); + void *btif_me_get_cmgr_handler(); + bt_status_t btif_bind_cmgr_handler(void *cmgr_handler, bt_bdaddr_t * bdAddr,btif_cmgr_callback Callback); + bt_status_t btif_create_acl_to_slave(void *cmgr_handler, bt_bdaddr_t * bdAddr,btif_cmgr_callback Callback); + bt_status_t btif_register_cmgr_handle(void *cmgr_handler,btif_cmgr_callback Callback); + void btif_me_update_cmgr_info(void *cmgr_handler,btif_BtDeviceContext* bt_device_context,btif_remote_device_t * rdev); + void btif_me_unregister_globa_handler(btif_handler * handler); + void btif_me_set_inquiry_mode(uint8_t mode); + void btif_me_inquiry_result_setup(uint8_t *inquiry_buff, bool rssi, + bool extended_mode); + btif_remote_device_t *btif_me_enumerate_remote_devices(uint32_t devid); + + uint8_t btif_me_get_remote_sevice_encrypt_state(btif_remote_device_t* rdev); + + uint8_t btif_me_get_remote_device_disc_reason_saved(btif_remote_device_t * device); + + + uint8_t btif_me_get_remote_device_disc_reason(btif_remote_device_t * device); + + void btif_me_event_report(me_event_t *event); + void btif_me_init_peer_headset_addr(uint8_t *p_remote_addr); + bt_bdaddr_t * btif_me_get_peer_headset_addr(void); + uint8_t btif_me_get_remote_device_link_mode(btif_remote_device_t* rdev); + uint8_t btif_me_get_remote_device_bt_role(btif_remote_device_t* rdev); + bt_status_t btif_me_change_packet_type(btif_remote_device_t *rdev, btif_acl_packet packetTypes); + void btif_me_cobuf_state_dump(void); + void btif_me_hcibuff_state_dump(void); + bt_status_t btif_me_read_controller_memory(uint32_t addr, uint32_t len,uint8_t type); + bt_status_t btif_me_write_controller_memory(uint32_t addr,uint32_t val,uint8_t type); + bt_status_t btif_me_qos_set_up(uint16_t conn_handle); + void btif_set_sco_max_number(uint8_t num); + uint8_t btif_get_sco_max_number(); +#if defined(IBRT) + // ibrt fast ack toggle + #define IBRT_FAST_ACK_OFF (0) + #define IBRT_FAST_ACK_ON (1) + // ibrt fast direction + #define IBRT_FAST_ACK_TX 0 + #define IBRT_FAST_ACK_RX 1 + // ibrt slave flow control + #define IBRT_SLAVE_FLOW_CTRL_ON IBRT_FAST_ACK_OFF + #define IBRT_SLAVE_FLOW_CTRL_OFF IBRT_FAST_ACK_ON + + bt_status_t btif_me_enable_fastack(uint16_t conhdl, uint8_t direction, uint8_t enable); + bt_status_t btif_me_start_ibrt(U16 slaveConnHandle, U16 mobileConnHandle); + bt_status_t btif_me_stop_ibrt(uint8_t enable,uint8_t reason); + bt_status_t btif_me_suspend_ibrt(void); + bt_status_t btif_me_ibrt_mode_init(bool enable); + bt_status_t btif_me_ibrt_role_switch(uint8_t switch_op); + + void btif_me_set_ibrt_mobile_hci_handle(uint16_t hci_handle); + uint16_t btif_me_get_ibrt_mobile_hci_handle(void); + + void btif_me_set_devctx_state(uint8_t ctx_idx, uint16_t state); + void btif_me_set_devctx_link(uint8_t ctx_idx, btif_remote_device_t * rm_dev); + bt_bdaddr_t* btif_me_get_devctx_btaddr(uint8_t ctx_idx); + btif_remote_device_t* btif_me_get_remote_device(uint8_t dev_index); + void btif_me_free_tws_outgoing_dev(uint8_t *peer_tws_addr); + btif_remote_device_t* btif_me_get_devctx_remote_device(uint8_t ctx_idx); + btif_remote_device_t * btif_me_avdev_ctx_get_conn_remote_device(uint8_t dev_idx); + + uint32_t btif_me_save_record_ctx(uint8_t *ctx_buffer, uint8_t *addr); + uint32_t btif_me_set_record_ctx(uint8_t *ctx_buffer, uint8_t *addr); + uint32_t btif_me_save_me_ctx(uint8_t *ctx_buffer, uint16_t dev_id); + uint32_t btif_me_set_me_ctx(uint8_t *ctx_buffer, uint16_t dev_id); + uint8_t btif_me_get_mobile_avdev_index(uint16_t mobile_handle); + uint8_t btif_me_get_free_avdev_index(void); + uint32_t btif_me_save_avdev_ctx(uint8_t* ctx_buffer, uint16_t dev_id); + uint32_t btif_me_set_avdev_ctx(uint8_t *ctx_buffer, uint16_t dev_id, uint8_t rm_devtbl_idx); + void btif_me_conn_auto_accept_enable(uint8_t *condition); + uint8_t btif_me_get_callback_event_encty_mode(const btif_event_t * event); + btif_dev_linkkey *btif_me_get_callback_link_key(const btif_event_t *event); + void btif_me_register_ibrt_disconnect_callback(btif_callback cb); + bt_status_t btif_me_set_tws_poll_interval(uint16_t conn_handle, uint16_t poll_interval); + bt_status_t btif_me_resume_ibrt(uint8_t enable); + void btif_me_write_scan_activity_specific(uint16_t opcode, uint16_t scan_interval, uint16_t scan_window); + void btif_me_write_dbg_sniffer(const uint8_t subcode, const uint16_t connhandle); + void btif_me_ibrt_simu_hci_event_disallow(uint8_t opcode1, uint8_t opcode2); + void btif_me_register_conn_req_pre_treatment_callback(btif_callback cb); + void btif_me_register_cmd_status_callback(btif_callback cb); + void btif_me_register_cmd_complete_callback(HCI_CMD_COMPLETE_USER_E index,btif_callback cb); + bt_status_t btif_me_ibrt_conn_connected(bt_bdaddr_t *bt_addr, uint16_t conhdl); + bt_status_t btif_me_ibrt_conn_disconnected(bt_bdaddr_t *bt_addr, uint16_t conhdl, uint8_t status, uint8_t reason); + void btif_me_register_ibrt_io_capbility_callback(ibrt_io_capbility_callback cb); + bt_status_t btif_me_auth_req(uint16_t conn_handle); + void btif_me_set_ecc_ibrt_data_test(uint8_t ecc_data_test_en, uint8_t ecc_data_len, uint16_t ecc_count, uint32_t data_pattern); + void btif_me_send_prefer_rate(uint16_t connhdl, uint8_t rate); +#endif +#ifdef __cplusplus +} +#endif /* */ +#endif /* __ME_H */ diff --git a/services/bt_if_enhanced/inc/mei_api.h b/services/bt_if_enhanced/inc/mei_api.h new file mode 100644 index 0000000..1a48fda --- /dev/null +++ b/services/bt_if_enhanced/inc/mei_api.h @@ -0,0 +1,53 @@ +/**************************************************************************** + * + * File: + * $Id: mei_api.h 886 2009-02-24 14:40:12Z brentk $ + * $Product: BES Blue SDK v3.x $ + * $Revision: 886 $ + * + * Description: + * Public types, defines, and prototypes for accessing the + * upper layer of the Management Entity. + * + * Copyright 1999-2005 Extended Systems, Inc. + * Portions copyright BES. + * All rights reserved. All unpublished rights reserved. + * + * Unpublished Confidential Information of BES. + * Do Not Disclose. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __MEI_API__H__ +#define __MEI_API__H__ + +/*--------------------------------------------------------------------------- + * + * Authenticate State of a Remote Device (BtAuthState). The typedef is in + * mei_api.h + */ +#define BTIF_BAS_NOT_AUTHENTICATED 0x00 +#define BTIF_BAS_START_AUTHENTICATE 0x01 +#define BTIF_BAS_WAITING_KEY_REQ 0x02 +#define BTIF_BAS_SENDING_KEY 0x03 +#define BTIF_BAS_WAITING_FOR_IO 0x04 +#define BTIF_BAS_WAITING_FOR_IO_R 0x05 +#define BTIF_BAS_WAITING_FOR_KEY 0x06 +#define BTIF_BAS_WAITING_FOR_KEY_R 0x07 +#define BTIF_BAS_AUTHENTICATED 0x08 + +#define BTIF_DBG_SNIFFER_SCO_STOP 0 +#define BTIF_DBG_SNIFFER_SCO_START 1 +#define BTIF_DBG_SNIFFER_ACL_SWOTCH 2 +#define BTIF_DBG_SEND_MAX_SLOT_REQ 3 + +#endif /* __ME_H */ diff --git a/services/bt_if_enhanced/inc/obex_api.h b/services/bt_if_enhanced/inc/obex_api.h new file mode 100644 index 0000000..5118f5f --- /dev/null +++ b/services/bt_if_enhanced/inc/obex_api.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __OBEX_API_H__ +#define __OBEX_API_H__ + +#include "bluetooth.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + BTIF_OBEX_SESSION_ROLE_CLIENT = 0, + BTIF_OBEX_SESSION_ROLE_SERVER, // 1 +} btif_obex_session_role_t; + +#ifdef __cplusplus +} +#endif + +#endif /* __OBEX_API_H__ */ + diff --git a/services/bt_if_enhanced/inc/os_api.h b/services/bt_if_enhanced/inc/os_api.h new file mode 100644 index 0000000..8bcc8dd --- /dev/null +++ b/services/bt_if_enhanced/inc/os_api.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __OS_API__H__ +#define __OS_API__H__ + +#include "bluetooth.h" + +#ifdef __cplusplus +extern "C" { +#endif + typedef void (*osapi_timer_notify) (void); + + void osapi_stop_hardware(void); + + void osapi_resume_hardware(void); + + void osapi_memcopy(U8 * dest, const U8 * source, U32 numBytes); + + void osapi_lock_stack(void); + + void osapi_unlock_stack(void); + + void osapi_notify_evm(void); + + uint8_t osapi_lock_is_exist(void); + +#ifdef __cplusplus +} +#endif +#endif/*__OS_API__H__*/ diff --git a/services/bt_if_enhanced/inc/rfcomm_api.h b/services/bt_if_enhanced/inc/rfcomm_api.h new file mode 100644 index 0000000..bb52519 --- /dev/null +++ b/services/bt_if_enhanced/inc/rfcomm_api.h @@ -0,0 +1,309 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __RFCOMM_API_H__ +#define __RFCOMM_API_H__ +#include "bluetooth.h" +#include "me_api.h" +#include "bt_if.h" + +typedef void *rf_channel_t; + +typedef uint8_t rf_event_t; + +#define BTIF_RFEVENT_OPEN_IND 1 +#define BTIF_RFEVENT_OPEN 2 +#define BTIF_RFEVENT_CLOSE_IND 3 +#define BTIF_RFEVENT_CLOSED 4 +#define BTIF_RFEVENT_DATA_IND 5 +#define BTIF_RFEVENT_PACKET_HANDLED 6 +#define BTIF_RFEVENT_TEST_CNF 7 +#define BTIF_RFEVENT_PORT_NEG_IND 8 +#define BTIF_RFEVENT_PORT_NEG_CNF 9 +#define BTIF_RFEVENT_PORT_STATUS_IND 10 +#define BTIF_RFEVENT_PORT_STATUS_CNF 11 +#define BTIF_RFEVENT_MODEM_STATUS_IND 12 +#define BTIF_RFEVENT_MODEM_STATUS_CNF 13 +#define BTIF_RFEVENT_LINE_STATUS_IND 14 +#define BTIF_RFEVENT_LINE_STATUS_CNF 15 +#define BTIF_RFEVENT_FLOW_OFF_IND 16 +#define BTIF_RFEVENT_FLOW_ON_IND 17 +#define BTIF_RFEVENT_RESOURCE_FREE 18 +#define BTIF_RFEVENT_FRAME_SIZE_CHANGED 19 + +typedef uint8_t rf_signals; +#define RFCOMM_FLOW 0x02 +#define RFCOMM_RTC 0x04 +#define RFCOMM_RTR 0x08 +#define RFCOMM_IC 0x40 +#define RFCOMM_DV 0x80 + +#define RFCOMM_DSR 0x04 +#define RFCOMM_CTS 0x08 +#define RFCOMM_RI 0x40 +#define RFCOMM_CD 0x80 + +#define RFCOMM_DTR 0x04 +#define RFCOMM_RTS 0x08 + +typedef uint8_t rf_data_format; +#define RFCOMM_DATA_BITS_5 0x00 +#define RFCOMM_DATA_BITS_6 0x02 +#define RFCOMM_DATA_BITS_7 0x01 +#define RFCOMM_DATA_BITS_8 0x03 + +#define RFCOMM_STOP_BITS_1 0x00 +#define RFCOMM_STOP_BITS_1_5 0x04 + +#define RFCOMM_PARITY_NONE 0x00 +#define RFCOMM_PARITY_ON 0x08 + +#define RFCOMM_PARITY_TYPE_ODD 0x00 +#define RFCOMM_PARITY_TYPE_EVEN 0x20 +#define RFCOMM_PARITY_TYPE_MARK 0x10 +#define RFCOMM_PARITY_TYPE_SPACE 0x30 + +#define RFCOMM_DATA_BITS_MASK 0x03 +#define RFCOMM_STOP_BITS_MASK 0x04 +#define RFCOMM_PARITY_MASK 0x08 +#define RFCOMM_PARITY_TYPE_MASK 0x30 + +typedef uint8_t rf_line_status; +#define RFCOMM_LINE_ERROR 0x01 +#define RFCOMM_OVERRUN 0x02 +#define RFCOMM_PARITY 0x04 +#define RFCOMM_FRAMING 0x08 + +typedef uint8_t rf_signals; +#define RFCOMM_FLOW 0x02 +#define RFCOMM_RTC 0x04 /* Set when sender is ready to communicate. */ +#define RFCOMM_RTR 0x08 /* Set when sender is ready to receive data. */ +#define RFCOMM_IC 0x40 /* Set when a call is incoming. */ +#define RFCOMM_DV 0x80 /* Set when valid data is being sent. */ + +#define RFCOMM_DSR 0x04 +#define RFCOMM_CTS 0x08 +#define RFCOMM_RI 0x40 +#define RFCOMM_CD 0x80 + +#define RFCOMM_DTR 0x04 +#define RFCOMM_RTS 0x08 + +struct rf_modem_status +{ + rf_signals signals; + uint8_t break_len; +}; + +typedef uint16_t rf_port_settings_mask; + +#define RFCOMM_PARM_BAUDRATE 0x0001 +#define RFCOMM_PARM_DATABITS 0x0002 +#define RFCOMM_PARM_STOPBITS 0x0004 +#define RFCOMM_PARM_PARITY 0x0008 +#define RFCOMM_PARM_PARITY_TYPE 0x0010 +#define RFCOMM_PARM_DATA_FORMAT (RFCOMM_PARM_DATABITS | RFCOMM_PARM_STOPBITS | \ + RFCOMM_PARM_PARITY | RFCOMM_PARM_PARITY_TYPE) +#define RFCOMM_PARM_XON_CHAR 0x0020 +#define RFCOMM_PARM_XOFF_CHAR 0x0040 + +#define RFCOMM_PARM_XON_INPUT 0x0100 +#define RFCOMM_PARM_XON_OUTPUT 0x0200 +#define RFCOMM_PARM_RTR_INPUT 0x0400 +#define RFCOMM_PARM_RTR_OUTPUT 0x0800 +#define RFCOMM_PARM_RTC_INPUT 0x1000 +#define RFCOMM_PARM_RTC_OUTPUT 0x2000 + +#define RFCOMM_PARM_FLOW_RTS_CTS (RFCOMM_PARM_RTR_INPUT | RFCOMM_PARM_RTR_OUTPUT) +#define RFCOMM_PARM_FLOW_DTR_DSR (RFCOMM_PARM_RTC_INPUT | RFCOMM_PARM_RTC_OUTPUT) +#define RFCOMM_PARM_FLOW_XON_XOFF (RFCOMM_PARM_XON_INPUT | RFCOMM_PARM_XON_OUTPUT) + +typedef uint8_t rf_flow_control; + +#define RFCOMM_FLOW_CTRL_NONE 0x00 +#define RFCOMM_XON_ON_INPUT 0x01 +#define RFCOMM_XON_ON_OUTPUT 0x02 +#define RFCOMM_RTR_ON_INPUT 0x04 +#define RFCOMM_RTR_ON_OUTPUT 0x08 +#define RFCOMM_RTC_ON_INPUT 0x10 +#define RFCOMM_RTC_ON_OUTPUT 0x20 + +#define RFCOMM_FLOW_RTS_CTS (RFCOMM_RTR_ON_INPUT | RFCOMM_RTR_ON_OUTPUT) +#define RFCOMM_FLOW_DTR_DSR (RFCOMM_RTC_ON_INPUT | RFCOMM_RTC_ON_OUTPUT) +#define RFCOMM_FLOW_XON_XOFF (RFCOMM_XON_ON_INPUT | RFCOMM_XON_ON_OUTPUT) + +typedef uint8_t rf_data_format; +#define RFCOMM_DATA_BITS_5 0x00 +#define RFCOMM_DATA_BITS_6 0x02 +#define RFCOMM_DATA_BITS_7 0x01 +#define RFCOMM_DATA_BITS_8 0x03 +#define RFCOMM_STOP_BITS_1 0x00 +#define RFCOMM_STOP_BITS_1_5 0x04 +#define RFCOMM_PARITY_NONE 0x00 +#define RFCOMM_PARITY_ON 0x08 +#define RFCOMM_PARITY_TYPE_ODD 0x00 +#define RFCOMM_PARITY_TYPE_EVEN 0x20 +#define RFCOMM_PARITY_TYPE_MARK 0x10 +#define RFCOMM_PARITY_TYPE_SPACE 0x30 +#define RFCOMM_DATA_BITS_MASK 0x03 +#define RFCOMM_STOP_BITS_MASK 0x04 +#define RFCOMM_PARITY_MASK 0x08 +#define RFCOMM_PARITY_TYPE_MASK 0x30 + +typedef uint8_t rf_baud_rate; + +#define RFCOMM_BAUD_2400 0x00 +#define RFCOMM_BAUD_4800 0x01 +#define RFCOMM_BAUD_7200 0x02 +#define RFCOMM_BAUD_9600 0x03 +#define RFCOMM_BAUD_19200 0x04 +#define RFCOMM_BAUD_38400 0x05 +#define RFCOMM_BAUD_57600 0x06 +#define RFCOMM_BAUD_115200 0x07 +#define RFCOMM_BAUD_230400 0x08 + +typedef struct _rf_port_settings +{ + rf_baud_rate baudRate; + rf_data_format dataFormat; + rf_flow_control flowControl; + uint8_t xonChar; + uint8_t xoffChar; + rf_port_settings_mask parmMask; +} rf_port_settings; + +struct rf_callback_prams +{ + rf_event_t event; + int status; + uint16_t data_len; + union + { + btif_bt_packet_t *packet; + U8 *data; + struct rf_modem_status *modem_status; + rf_line_status *line_status; + rf_port_settings *port_settings; + btif_remote_device_t *remDev; + } ptrs; +}; + +typedef void (*rf_callback_func) (rf_channel_t chan, struct rf_callback_prams * parms); + +struct rf_chan_info +{ + rf_callback_func callback; + uint16_t max_frame_size; + uint8_t priority; + void *priv; +}; + +struct rf_service +{ + uint8_t serviceId; +}; + +struct _rf_channel +{ + rf_callback_func callback; + int8_t server_channel; + uint32_t rfcomm_handle; + uint32_t app_id; + void *priv; + list_entry_t tx_queue; +}; + +#ifdef __cplusplus +extern "C" { +#endif /* */ +void btif_rfcomm_ctx_input_init(void *para); +rf_channel_t btif_rf_create_channel(void); + +void btif_rf_free_channel(rf_channel_t chan_h); + +bt_status_t btif_rf_register_server_channel(rf_channel_t chan_h, + struct rf_service *service, uint8_t credit); +bt_status_t btif_rf_deregister_server_channel(rf_channel_t chan_h, struct rf_service *service); + +bt_status_t btif_rf_deregister_service(struct rf_service *service); + +uint16_t btif_rf_frame_size(rf_channel_t chan_h); + +bt_status_t btif_rf_respond_channel(rf_channel_t chan_h, bool accept); + +bt_status_t btif_rf_accept_channel(rf_channel_t chan_h); +#define btif_rf_accept_channel(c) btif_rf_respond_channel(c, true) + +bt_status_t btif_rf_reject_channel(rf_channel_t chan_h); +#define btif_rf_reject_channel(c) btif_rf_respond_channel(c, false) + +#if BTIF_RF_SEND_CONTROL == BTIF_ENABLED +bt_status_t btif_rf_send_port_settings(rf_channel_t chan_h, rf_port_settings * PortSettings); + +bt_status_t btif_rf_request_port_settings(rf_channel_t chan_h, rf_port_settings * portSettings); +#define btif_rf_request_port_settings(c, p) btif_rf_send_port_settings(c, p) + +bt_status_t btif_rf_request_port_status(rf_channel_t chan_h); +#define btif_rf_request_port_status(c) btif_rf_send_port_settings(c, NULL) + +bt_status_t btif_rf_set_modem_status(rf_channel_t chan_h, + struct rf_modem_status *modem_status); +#endif /*BTIF_RF_SEND_CONTROL == BTIF_ENABLED */ + +bt_status_t btif_rf_open_client_channel(btif_remote_device_t * RemDev, + uint8_t server_id, rf_channel_t chan_h, uint8_t credit); + +bt_status_t btif_rf_close_channel(rf_channel_t chan_h); + +bt_status_t btif_rf_send_data(rf_channel_t chan_h, btif_bt_packet_t * Packet); + +bt_status_t btif_rf_advance_credit(rf_channel_t chan_h, uint8_t credit); + +bool btif_rf_credit_flow_enabled(rf_channel_t chan_h); + +bt_status_t btif_rf_setup_channel(rf_channel_t chan_h, struct rf_chan_info *info); + +void *btif_rf_get_channel_priv(rf_channel_t chan); +uint32_t btif_rf_get_app_id(rf_channel_t chan_h); + +uint32_t btif_rf_get_rfcomm_handle(rf_channel_t chan_h); +bt_status_t btif_rf_set_rfcomm_handle(rf_channel_t chan_h, uint32_t rfcomm_handle); +uint8_t btif_rf_get_server_channel(rf_channel_t chan_h); + +uint16_t btif_rf_max_frame_size_configure(void); +void btif_rf_set_app_id(rf_channel_t chan_h,uint32_t app_id); + +#if defined(IBRT) +#if defined(ENHANCED_STACK) +uint32_t btif_save_rfc_ctx(uint8_t *ctx_buffer, uint8_t MuxId); +uint32_t btif_set_rfc_ctx(uint8_t* ctx_buffer, uint16_t MuxId, uint8_t rm_devtbl_idx); +uint32_t btif_rfc_get_session_l2c_handle(uint16_t hci_handle); +bool btif_rfc_is_dlci_channel_connected(uint32_t session_l2c_handle,uint32_t app_id); +#else +uint32_t btif_save_rfc_ctx(uint8_t *ctx_buffer, uint8_t MuxId); +uint32_t btif_set_rfc_ctx(uint8_t* ctx_buffer, uint16_t MuxId, uint8_t rm_devtbl_idx); +uint32_t btif_save_rfcomm_channel_ctx(uint8_t *ctx_buffer, uint8_t MuxId, uint32_t app_id); +uint32_t btif_set_rfcomm_channel_ctx(uint8_t *ctx_buffer, uint8_t MuxId, uint32_t app_id); +#endif +bool btif_rf_is_rfcomm_channel_connected(uint8_t mux_id,uint32_t app_id); +btif_remote_device_t* btif_rfc_get_mux_remote_device(uint8_t mux_idx); +uint8_t btif_rfc_get_mux_index(uint16_t hci_handle); +uint8_t btif_rfc_get_mux_state(uint8_t mux_idx); +#endif + +#ifdef __cplusplus +} +#endif +#endif /*__RFCOMM_API_H__*/ diff --git a/services/bt_if_enhanced/inc/sco_api.h b/services/bt_if_enhanced/inc/sco_api.h new file mode 100644 index 0000000..a5507a0 --- /dev/null +++ b/services/bt_if_enhanced/inc/sco_api.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _SCO_API_H +#define _SCO_API_H +#include "btlib_type.h" + +/* notify upper layer */ +enum sco_event_enum { + SCO_OPENED, + SCO_CLOSED +}; + +#ifdef __cplusplus +extern "C" { +#endif + int8 sco_register_link(struct bdaddr_t *bdaddr, + void (*sco_notify_callback) (enum sco_event_enum event, void *pdata), void *link); + int8 sco_open_link(struct bdaddr_t *bdaddr, + void (*sco_notify_callback) (enum sco_event_enum event, void *pdata, void *link), void *link); + int8 sco_close_link(struct bdaddr_t *bdaddr1, uint8 reason, void *link); + int8 sco_unregister_link(struct bdaddr_t *bdaddr); + int8 sco_init(void); + int8 sco_exit(void); + void sco_conn_opened_ind(struct bdaddr_t *bdaddr_remote); + void sco_conn_closed_ind(struct bdaddr_t *bdaddr_remote); +#ifdef __cplusplus + extern "C" { +#endif + +#endif /**/ diff --git a/services/bt_if_enhanced/inc/sdp_api.h b/services/bt_if_enhanced/inc/sdp_api.h new file mode 100644 index 0000000..b8807b2 --- /dev/null +++ b/services/bt_if_enhanced/inc/sdp_api.h @@ -0,0 +1,521 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __SDP_API_H__ +#define __SDP_API_H__ + +#include "me_api.h" + +#define BTIF_SDP_RECORD_NUM_MAX (10) +#define BTIF_SDP_QUERY_TOKEN_NUM_MAX (4) + +typedef void btif_sdp_record_t; + +typedef uint8_t sdp_query_type; +#define BTIF_BSQT_ATTRIB_REQ 0x04 +#define BTIF_BSQT_SERVICE_SEARCH_ATTRIB_REQ 0x06 +typedef uint8_t sdp_query_resp; +#define BTIF_BSQR_ERROR_RESP 0x01 +#define BTIF_BSQR_SERVICE_SEARCH_RESP 0x03 +#define BTIF_BSQR_ATTRIB_RESP 0x05 +#define BTIF_BSQR_SERVICE_SEARCH_ATTRIB_RESP 0x07 + +#if SDP_SERVER_SUPPORT == XA_ENABLED +#define BTIF_SDP_SERVER_ATTRIBS 3 +#define BTIF_SDP_SERVER_TX_SIZE (SDP_SERVER_SEND_SIZE - 5) +#define BTIF_SDP_SERV_OWN_HANDLE 0x00000000 +#define BTIF_SDP_SERV_FIRST_HANDLE 0x00010000 +#define BTIF_SDP_SERV_BOGUS_HANDLE 0xffffffff +#define BTIF_SDP_ZERO_SERVICE_DATABASE_STATE_SIZE 5 +#endif /* SDP_SERVER_SUPPORT == XA_ENABLED */ + +typedef uint16_t sdp_service_class_uuid; +#define BTIF_SC_SERVICE_DISCOVERY_SERVER 0x1000 +#define BTIF_SC_BROWSE_GROUP_DESC 0x1001 +#define BTIF_SC_PUBLIC_BROWSE_GROUP 0x1002 +#define BTIF_SC_SERIAL_PORT 0x1101 +#define BTIF_SC_LAN_ACCESS_PPP 0x1102 +#define BTIF_SC_DIALUP_NETWORKING 0x1103 +#define BTIF_SC_IRMC_SYNC 0x1104 +#define BTIF_SC_OBEX_OBJECT_PUSH 0x1105 +#define BTIF_SC_OBEX_FILE_TRANSFER 0x1106 +#define BTIF_SC_IRMC_SYNC_COMMAND 0x1107 +#define BTIF_SC_HEADSET 0x1108 +#define BTIF_SC_CORDLESS_TELEPHONY 0x1109 +#define BTIF_SC_AUDIO_SOURCE 0x110A +#define BTIF_SC_AUDIO_SINK 0x110B +#define BTIF_SC_AV_REMOTE_CONTROL_TARGET 0x110C +#define BTIF_SC_AUDIO_DISTRIBUTION 0x110D +#define BTIF_SC_AV_REMOTE_CONTROL 0x110E +#define BTIF_SC_VIDEO_CONFERENCING 0x110F +#define BTIF_SC_INTERCOM 0x1110 +#define BTIF_SC_FAX 0x1111 +#define BTIF_SC_HEADSET_AUDIO_GATEWAY 0x1112 +#define BTIF_SC_WAP 0x1113 +#define BTIF_SC_WAP_CLIENT 0x1114 +#define BTIF_SC_PANU 0x1115 +#define BTIF_SC_NAP 0x1116 +#define BTIF_SC_GN 0x1117 +#define BTIF_SC_DIRECT_PRINTING 0x1118 +#define BTIF_SC_REFERENCE_PRINTING 0x1119 +#define BTIF_SC_IMAGING 0x111A +#define BTIF_SC_IMAGING_RESPONDER 0x111B +#define BTIF_SC_IMAGING_AUTOMATIC_ARCHIVE 0x111C +#define BTIF_SC_IMAGING_REFERENCED_OBJECTS 0x111D +#define BTIF_SC_HANDSFREE 0x111E +#define BTIF_SC_HANDSFREE_AUDIO_GATEWAY 0x111F +#define BTIF_SC_DIRECT_PRINTING_REF_OBJECTS 0x1120 +#define BTIF_SC_REFLECTED_UI 0x1121 +#define BTIF_SC_BASIC_PRINTING 0x1122 +#define BTIF_SC_PRINTING_STATUS 0x1123 +#define BTIF_SC_HUMAN_INTERFACE_DEVICE 0x1124 +#define BTIF_SC_HCR 0x1125 +#define BTIF_SC_HCR_PRINT 0x1126 +#define BTIF_SC_HCR_SCAN 0x1127 +#define BTIF_SC_ISDN 0x1128 +#define BTIF_SC_VIDEO_CONFERENCING_GW 0x1129 +#define BTIF_SC_UDI_MT 0x112A +#define BTIF_SC_UDI_TA 0x112B +#define BTIF_SC_AUDIO_VIDEO 0x112C +#define BTIF_SC_SIM_ACCESS 0x112D +#define BTIF_SC_PBAP_CLIENT 0x112E +#define BTIF_SC_PBAP_SERVER 0x112F +#define BTIF_SC_PBAP_PROFILE 0x1130 +#define BTIF_SC_MAP_SERVER 0x1132 +#define BTIF_SC_MAP_NOTIFY_SERVER 0x1133 +#define BTIF_SC_MAP_PROFILE 0x1134 +#define BTIF_SC_PNP_INFO 0x1200 +#define BTIF_SC_GENERIC_NETWORKING 0x1201 +#define BTIF_SC_GENERIC_FILE_TRANSFER 0x1202 +#define BTIF_SC_GENERIC_AUDIO 0x1203 +#define BTIF_SC_GENERIC_TELEPHONY 0x1204 +#define BTIF_SC_UPNP_SERVICE 0x1205 +#define BTIF_SC_UPNP_IP_SERVICE 0x1206 +#define BTIF_SC_ESDP_UPNP_IP_PAN 0x1300 +#define BTIF_SC_ESDP_UPNP_IP_LAP 0x1301 +#define BTIF_SC_ESDP_UPNP_L2CAP 0x1302 +#define BTIF_SC_VIDEO_SOURCE 0x1303 +#define BTIF_SC_VIDEO_SINK 0x1304 +#define BTIF_SC_VIDEO_DISTRIBUTION 0x1305 + +typedef uint8_t sdp_parsing_mode; +#define BTIF_BSPM_BEGINNING 0x00 +#define BTIF_BSPM_RESUME 0x01 +#define BTIF_BSPM_CONT_STATE 0x02 +#define BTIF_BSPM_NO_SKIP 0x04 + +typedef uint8_t sdp_query_mode; +#define BTIF_BSQM_FIRST 0x00 +#define BTIF_BSQM_CONTINUE 0x01 +#define BTIF_BSQM_DONT_CARE 0xFF + +typedef U8 SdpDataElemType; +#define DETD_NIL 0x00 +#define DETD_UINT 0x08 +#define DETD_SINT 0x10 +#define DETD_UUID 0x18 +#define DETD_TEXT 0x20 +#define DETD_BOOL 0x28 +#define DETD_SEQ 0x30 +#define DETD_ALT 0x38 +#define DETD_URL 0x40 +#define DETD_MASK 0xf8 + +typedef uint8_t sdp_data_elem_size; +#define DESD_1BYTE 0x00 +#define DESD_2BYTES 0x01 +#define DESD_4BYTES 0x02 +#define DESD_8BYTES 0x03 +#define DESD_16BYTES 0x04 +#define DESD_ADD_8BITS 0x05 +#define DESD_ADD_16BITS 0x06 +#define DESD_ADD_32BITS 0x07 +#define DESD_MASK 0x07 + +#define SDP_ATTRIBUTE(attribId, attrib) \ + { attribId, \ + sizeof(attrib), \ + attrib, \ + 0x0000 } + +#define SDP_ATTRIBUTE_ARM(attribId, attrib) \ + { attribId, \ + sizeof(attrib), \ + 0, \ + 0x0000 } + +#define SDP_ATTRIB_HEADER_8BIT(size) \ + DETD_SEQ + DESD_ADD_8BITS, \ + size + +#define SDP_ATTRIB_HEADER_16BIT(size) \ + DETD_SEQ + DESD_ADD_16BITS, \ + (U8)(((size) & 0xff00) >> 8), \ + (U8)((size) & 0x00ff) + +#define SDP_ATTRIB_HEADER_32BIT(size) \ + DETD_SEQ + DESD_ADD_32BITS, \ + (U8)(((size) & 0xff000000) >> 24), \ + (U8)(((size) & 0x00ff0000) >> 16), \ + (U8)(((size) & 0x0000ff00) >> 8), \ + (U8)((size) & 0x000000ff) + +#define SDP_ATTRIB_HEADER_ALT_8BIT(size) \ + DETD_ALT + DESD_ADD_8BITS, \ + size + +#define SDP_ATTRIB_HEADER_ALT_16BIT(size) \ + DETD_ALT + DESD_ADD_16BITS, \ + (U8)(((size) & 0xff00) >> 8), \ + (U8)((size) & 0x00ff) + +#define SDP_ATTRIB_HEADER_ALT_32BIT(size) \ + DETD_ALT + DESD_ADD_32BITS, \ + (U8)(((size) & 0xff000000) >> 24), \ + (U8)(((size) & 0x00ff0000) >> 16), \ + (U8)(((size) & 0x0000ff00) >> 8), \ + (U8)((size) & 0x000000ff) + +#define SDP_UUID_16BIT(uuid) \ + DETD_UUID + DESD_2BYTES, \ + (U8)(((uuid) & 0xff00) >> 8), \ + (U8)((uuid) & 0x00ff) + +#define SDP_UUID_32BIT(uuid) \ + DETD_UUID + DESD_4BYTES, \ + (U8)(((uuid) & 0xff000000) >> 24), \ + (U8)(((uuid) & 0x00ff0000) >> 16), \ + (U8)(((uuid) & 0x0000ff00) >> 8), \ + (U8)((uuid) & 0x000000ff) + +#define SDP_UUID_128BIT(uuid) \ + DETD_UUID + DESD_16BYTES, \ + (U8)(uuid[15]), \ + (U8)(uuid[14]), \ + (U8)(uuid[13]), \ + (U8)(uuid[12]), \ + (U8)(uuid[11]), \ + (U8)(uuid[10]), \ + (U8)(uuid[9]), \ + (U8)(uuid[8]), \ + (U8)(uuid[7]), \ + (U8)(uuid[6]), \ + (U8)(uuid[5]), \ + (U8)(uuid[4]), \ + (U8)(uuid[3]), \ + (U8)(uuid[2]), \ + (U8)(uuid[1]), \ + (U8)(uuid[0]) + +#define SDP_UINT_8BIT(uint) \ + DETD_UINT + DESD_1BYTE, \ + (U8)(uint) + +#define SDP_UINT_16BIT(uint) \ + DETD_UINT + DESD_2BYTES, \ + (U8)(((uint) & 0xff00) >> 8), \ + (U8)((uint) & 0x00ff) + +#define SDP_UINT_32BIT(uint) \ + DETD_UINT + DESD_4BYTES, \ + (U8)(((uint) & 0xff000000) >> 24), \ + (U8)(((uint) & 0x00ff0000) >> 16), \ + (U8)(((uint) & 0x0000ff00) >> 8), \ + (U8)((uint) & 0x000000ff) + +#define SDP_UINT_64BIT(uint) \ + DETD_UINT + DESD_8BYTES, \ + uint + +#define SDP_UINT_128BIT(uint) \ + DETD_UINT + DESD_16BYTES, \ + uint + +#define SDP_TEXT_8BIT(size) \ + DETD_TEXT + DESD_ADD_8BITS,\ + (U8)(size) + +#define SDP_TEXT_16BIT(size) \ + DETD_TEXT + DESD_ADD_16BITS,\ + (U8)(((size) & 0xff00) >> 8),\ + (U8)((size) & 0x00ff) + +#define SDP_TEXT_32BIT(size) \ + DETD_TEXT + DESD_ADD_32BITS, \ + (U8)(((size) & 0xff000000) >> 24), \ + (U8)(((size) & 0x00ff0000) >> 16), \ + (U8)(((size) & 0x0000ff00) >> 8), \ + (U8)((size) & 0x000000ff) + +#define SDP_BOOL(value) \ + DETD_BOOL + DESD_1BYTE, \ + (U8)(value) + +typedef uint16_t sdp_service_class_uuid; +#define SC_SERVICE_DISCOVERY_SERVER 0x1000 +#define SC_BROWSE_GROUP_DESC 0x1001 +#define SC_PUBLIC_BROWSE_GROUP 0x1002 +#define SC_SERIAL_PORT 0x1101 +#define SC_LAN_ACCESS_PPP 0x1102 +#define SC_DIALUP_NETWORKING 0x1103 +#define SC_IRMC_SYNC 0x1104 +#define SC_OBEX_OBJECT_PUSH 0x1105 +#define SC_OBEX_FILE_TRANSFER 0x1106 +#define SC_IRMC_SYNC_COMMAND 0x1107 +#define SC_HEADSET 0x1108 +#define SC_CORDLESS_TELEPHONY 0x1109 +#define SC_AUDIO_SOURCE 0x110A +#define SC_AUDIO_SINK 0x110B +#define SC_AV_REMOTE_CONTROL_TARGET 0x110C +#define SC_AUDIO_DISTRIBUTION 0x110D +#define SC_AV_REMOTE_CONTROL 0x110E +#define SC_VIDEO_CONFERENCING 0x110F +#define SC_INTERCOM 0x1110 +#define SC_FAX 0x1111 +#define SC_HEADSET_AUDIO_GATEWAY 0x1112 +#define SC_WAP 0x1113 +#define SC_WAP_CLIENT 0x1114 +#define SC_PANU 0x1115 +#define SC_NAP 0x1116 +#define SC_GN 0x1117 +#define SC_DIRECT_PRINTING 0x1118 +#define SC_REFERENCE_PRINTING 0x1119 +#define SC_IMAGING 0x111A +#define SC_IMAGING_RESPONDER 0x111B +#define SC_IMAGING_AUTOMATIC_ARCHIVE 0x111C +#define SC_IMAGING_REFERENCED_OBJECTS 0x111D +#define SC_HANDSFREE 0x111E +#define SC_HANDSFREE_AUDIO_GATEWAY 0x111F +#define SC_DIRECT_PRINTING_REF_OBJECTS 0x1120 +#define SC_REFLECTED_UI 0x1121 +#define SC_BASIC_PRINTING 0x1122 +#define SC_PRINTING_STATUS 0x1123 +#define SC_HUMAN_INTERFACE_DEVICE 0x1124 +#define SC_HCR 0x1125 +#define SC_HCR_PRINT 0x1126 +#define SC_HCR_SCAN 0x1127 +#define SC_ISDN 0x1128 +#define SC_VIDEO_CONFERENCING_GW 0x1129 +#define SC_UDI_MT 0x112A +#define SC_UDI_TA 0x112B +#define SC_AUDIO_VIDEO 0x112C +#define SC_SIM_ACCESS 0x112D +#define SC_PBAP_CLIENT 0x112E +#define SC_PBAP_SERVER 0x112F +#define SC_PBAP_PROFILE 0x1130 +#define SC_MAP_SERVER 0x1132 +#define SC_MAP_NOTIFY_SERVER 0x1133 +#define SC_MAP_PROFILE 0x1134 +#define SC_PNP_INFO 0x1200 +#define SC_GENERIC_NETWORKING 0x1201 +#define SC_GENERIC_FILE_TRANSFER 0x1202 +#define SC_GENERIC_AUDIO 0x1203 +#define SC_GENERIC_TELEPHONY 0x1204 +#define SC_UPNP_SERVICE 0x1205 +#define SC_UPNP_IP_SERVICE 0x1206 +#define SC_ESDP_UPNP_IP_PAN 0x1300 +#define SC_ESDP_UPNP_IP_LAP 0x1301 +#define SC_ESDP_UPNP_L2CAP 0x1302 +#define SC_VIDEO_SOURCE 0x1303 +#define SC_VIDEO_SINK 0x1304 +#define SC_VIDEO_DISTRIBUTION 0x1305 + +typedef uint16_t sdp_protocol_uuid; +#define PROT_SDP 0x0001 +#define PROT_UDP 0x0002 +#define PROT_RFCOMM 0x0003 +#define PROT_TCP 0x0004 +#define PROT_TCS_BIN 0x0005 +#define PROT_TCS_AT 0x0006 +#define PROT_OBEX 0x0008 +#define PROT_IP 0x0009 +#define PROT_FTP 0x000A +#define PROT_HTTP 0x000C +#define PROT_WSP 0x000E +#define PROT_BNEP 0x000F +#define PROT_UPNP 0x0010 +#define PROT_HIDP 0x0011 +#define PROT_HCR_CONTROL_CHANNEL 0x0012 +#define PROT_HCR_DATA_CHANNEL 0x0014 +#define PROT_HCR_NOTIFICATION 0x0016 +#define PROT_AVCTP 0x0017 +#define PROT_AVDTP 0x0019 +#define PROT_AVCTP_BROWSING 0x001B +#define PROT_UDI_C 0x001D +#define PROT_L2CAP 0x0100 + +typedef uint16_t sdp_attribute_id; +#define AID_SERVICE_RECORD_HANDLE 0x0000 +#define AID_SERVICE_CLASS_ID_LIST 0x0001 +#define AID_SERVICE_RECORD_STATE 0x0002 +#define AID_SERVICE_ID 0x0003 +#define AID_PROTOCOL_DESC_LIST 0x0004 +#define AID_BROWSE_GROUP_LIST 0x0005 +#define AID_LANG_BASE_ID_LIST 0x0006 +#define AID_SERVICE_INFO_TIME_TO_LIVE 0x0007 +#define AID_SERVICE_AVAILABILITY 0x0008 +#define AID_BT_PROFILE_DESC_LIST 0x0009 +#define AID_DOC_URL 0x000a +#define AID_CLIENT_EXEC_URL 0x000b +#define AID_ICON_URL 0x000c +#define AID_ADDITIONAL_PROT_DESC_LISTS 0x000d +#define AID_SERVICE_NAME 0x0000 +#define AID_SERVICE_DESCRIPTION 0x0001 +#define AID_PROVIDER_NAME 0x0002 +#define AID_IP_SUBNET 0x0200 +#define AID_GROUP_ID 0x0200 +#define AID_VERSION_NUMBER_LIST 0x0200 +#define AID_SERVICE_DATABASE_STATE 0x0201 +#define AID_SERVICE_VERSION 0x0300 +#define AID_EXTERNAL_NETWORK 0x0301 +#define AID_SUPPORTED_DATA_STORES_LIST 0x0301 +#define AID_FAX_CLASS_1_SUPPORT 0x0302 +#define AID_REMOTE_AUDIO_VOL_CONTROL 0x0302 +#define AID_FAX_CLASS_20_SUPPORT 0x0303 +#define AID_SUPPORTED_FORMATS_LIST 0x0303 +#define AID_FAX_CLASS_2_SUPPORT 0x0304 +#define AID_AUDIO_FEEDBACK_SUPPORT 0x0305 +#define AID_NETWORK_ADDRESS 0x0306 +#define AID_WAP_GATEWAY 0x0307 +#define AID_HOME_PAGE_URL 0x0308 +#define AID_WAP_STACK_TYPE 0x0309 +#define AID_SECURITY_DESC 0x030A +#define AID_NET_ACCESS_TYPE 0x030B +#define AID_MAX_NET_ACCESS_RATE 0x030C +#define AID_IPV4_SUBNET 0x030D +#define AID_IPV6_SUBNET 0x030E +#define AID_SUPPORTED_CAPABILITIES 0x0310 +#define AID_SUPPORTED_FEATURES 0x0311 +#define AID_SUPPORTED_FUNCTIONS 0x0312 +#define AID_TOTAL_IMAGE_DATA_CAPACITY 0x0313 +#define AID_SUPPORTED_REPOSITORIES 0x0314 +#define AID_MAS_INSTANCE_ID 0x0315 +#define AID_SUPPORTED_MESSAGE_TYPES 0x0316 +#define AID_SUPPORTED_DOC_FORMATS 0x0350 +#define AID_SUPPORTED_CHAR_REPERTOIRES 0x0352 +#define AID_SUPPORTED_XHTML_IMAGE_FORMATS 0x0354 +#define AID_COLOR_SUPPORTED 0x0356 +#define AID_PRINTER_1284ID 0x0358 +#define AID_DUPLEX_SUPPORTED 0x035E +#define AID_SUPPORTED_MEDIA_TYPES 0x0360 +#define AID_MAX_MEDIA_WIDTH 0x0362 +#define AID_MAX_MEDIA_LENGTH 0x0364 +#define AID_HID_PARSERVERSION 0x201 +#define AID_HID_DEVICESUBCLASS 0x202 +#define AID_HID_CONTRYCODE 0x203 +#define AID_HID_VIRTUALCABLE 0x204 +#define AID_HID_RECONNECTINITIATE 0x205 +#define AID_HID_DESCRIPTORLIST 0x206 +#define AID_HID_LANGIDBASELIST 0x207 +#define AID_HID_BATTERYPOWER 0x209 +#define AID_HID_REMOTEWAKE 0x20A +#define AID_HID_SUPERVISIONTIMEOUT 0x20C +#define AID_HID_NORMALLYCONNECTABLE 0x20D +#define AID_HID_BOOTDEVICE 0x20E +#define AID_HID_SSRHOSTMAXLATENCY 0x20F +#define AID_HID_SSRHOSTMINTIMEOUT 0x210 + +U16 sdp_get_u16(U8 * buff); +#define sdp_get_u16(buff) be_to_host16((buff)) +U32 sdp_get_u32(U8 * buff); +#define sdp_get_u32(buff) BEtoHost32((buff)) +void sdp_put_u16(U8 * buff, U16 val); +#define sdp_put_u16(buff,val) StoreBE16((buff),(val)) +void sdp_put_u32(U8 * buff, U32 val); +#define sdp_put_u32(buff,val) StoreBE32((buff),(val)) + +typedef struct btif_sdp_attribute { + uint16_t id; + uint16_t len; + const uint8_t *value; + uint16_t flags; +} __attribute__ ((__packed__)) sdp_attribute_t; + +typedef struct btif_sdp_query_info { + const uint8_t *parms; + uint16_t parm_len; + sdp_query_type query_type; + sdp_attribute_id attr_id; + uint16_t uuid; + sdp_parsing_mode mode; + btif_callback callback; + void *priv; +} __attribute__ ((__packed__)) btif_sdp_query_info_t; + +typedef struct btif_sdp_record_param { + sdp_attribute_t *attrs; + uint32_t attr_count; + uint32_t COD; +} __attribute__ ((__packed__)) btif_sdp_record_param_t; + + +typedef struct btif_sdp_query_token +{ + btif_remote_device_t *rm; /* The remote device to query. An ACL + * connection must exist with this device + * before the query is started. */ + struct btif_sdp_query_info info; + uint8_t channel; + uint8_t response_buff[666]; + uint32_t response_buff_len; +} __attribute__ ((__packed__)) btif_sdp_query_token_t; + +#ifdef __cplusplus +extern "C" { +#endif + + bt_status_t btif_sdp_init(void); + + btif_sdp_record_t *btif_sdp_create_record(void); + + void btif_sdp_free_record(btif_sdp_record_t* record); + + void *btif_sdp_get_record_priv(btif_sdp_record_t *record); + + bt_status_t btif_sdp_record_setup(btif_sdp_record_t *record, btif_sdp_record_param_t *param); + + btif_sdp_query_token_t *btif_sdp_create_query_token(void); + + void btif_sdp_free_token(btif_sdp_query_token_t * query_token); + + int btif_sdp_set_query_token(btif_sdp_query_token_t * query_token, btif_sdp_query_info_t *info); + + int btif_sdp_set_remote_device(btif_sdp_query_token_t * query_token, + btif_remote_device_t * r_device); + + bt_status_t btif_sdp_query(btif_sdp_query_token_t * query_token, sdp_query_mode mode); + + bt_status_t btif_sdp_parse_attrs(btif_sdp_query_token_t * query_token); + + btif_remote_device_t *btif_sdp_get_remote_device(btif_sdp_query_token_t * query_token); + + uint8_t btif_sdp_get_server_id(btif_sdp_query_token_t * query_token); + + void *btif_sdp_get_token_priv(btif_sdp_query_token_t * query_token); + + bt_status_t btif_sdp_add_record(btif_sdp_record_t * record); + + bt_status_t btif_sdp_remove_record(btif_sdp_record_t * record); + + void btif_sdp_set_parsing_mode(btif_sdp_query_token_t * query_token, sdp_parsing_mode mode); + + bt_status_t btif_spp_insert_rfcomm_chan(btif_sdp_record_t *record, uint8_t channel); + + btif_sdp_query_token_t *btif_me_get_callback_event_sdp_token(const btif_event_t *event); +#ifdef __cplusplus +} +#endif +#endif /*__SDP_API_H__*/ diff --git a/services/bt_if_enhanced/inc/spp_api.h b/services/bt_if_enhanced/inc/spp_api.h new file mode 100644 index 0000000..7ed7aec --- /dev/null +++ b/services/bt_if_enhanced/inc/spp_api.h @@ -0,0 +1,178 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __SPP_API_H__ +#define __SPP_API_H__ + +#include "sdp_api.h" +#include "cmsis_os.h" +#include "cqueue.h" +#include "rfcomm_api.h" + +#define SPP_DEVICE_NUM 6 +#define SPP_SERVICE_NUM 6 + +typedef uint16_t spp_event_t; +#define BTIF_SPP_EVENT_REMDEV_CONNECTED 0 +#define BTIF_SPP_EVENT_REMDEV_DISCONNECTED 1 +#define BTIF_SPP_EVENT_DATA_SENT 2 +#define BTIF_SPP_EVENT_REMDEV_DISCONNECTED_IND 3 +#define BTIF_SPP_EVENT_REMDEV_CONNECTED_IND 4 + +typedef uint8_t spp_port_t; + +#define BTIF_SPP_SERVER_PORT 0x01 +#define BTIF_SPP_CLIENT_PORT 0x02 + +#define SPP_RX_SIGNAL_ID 0x04 + +struct spp_device; + +struct spp_tx_done { + uint8_t *tx_buf; + uint16_t tx_data_length; +}; + +struct spp_client { + btif_remote_device_t *remDev; + uint8_t serverId; + btif_sdp_query_token_t *sdpToken; + uint8_t* rfcommServiceSearchRequestPtr; + uint8_t rfcommServiceSearchRequestLen; +}; + +struct spp_service { + struct rf_service rf_service; + const uint8_t *name; + uint16_t nameLen; + uint16_t numPorts; + btif_sdp_record_t *sdpRecord; + uint8_t service_used_flag; +}; + +struct spp_callback_parms { + spp_event_t event; + int status; + union { + void *other; + btif_remote_device_t *remDev; + } p; +}; + +typedef void (*spp_callback_t)(struct spp_device *locDev, + struct spp_callback_parms *Info); + +typedef int (*spp_handle_data_event_func_t)(void *pDev, uint8_t process, uint8_t *pData, uint16_t dataLen); + +struct _spp_dev { + union { + struct spp_client client; + struct spp_service *sppService; + } type; +}; + +struct spp_device { + spp_port_t portType; + uint32_t app_id; + osThreadId reader_thread_id; + osMutexId mutex_id; + CQueue rx_queue; + uint8_t *rx_buffer; + uint32_t rx_buffer_size; + uint32_t tx_packet_num; + void *priv; + spp_callback_t spp_callback; + spp_handle_data_event_func_t spp_handle_data_event_func; + uint8_t serialNumber; + uint8_t spp_connected_flag; + uint8_t sppUsedFlag; + uint8_t close_pending; + struct _spp_dev sppDev; + void *_channel; + uint8_t initial_credit; + uint8_t credit_give_limit; + osMutexId creditMutex; + bt_bdaddr_t btaddr; +}; + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#ifdef __cplusplus +extern "C" { +#endif + +bt_status_t btif_spp_init_device(struct spp_device *dev, uint16_t numPackets, osMutexId mid); +bt_status_t btif_spp_init_rx_buf(struct spp_device *dev, uint8_t *rx_buf, uint32_t size); +bool btif_sppos_is_txpacket_available(struct spp_device *dev); +bt_status_t btif_spp_open(struct spp_device *dev, + btif_remote_device_t *btDevice, + spp_callback_t callback); +bt_status_t btif_spp_open_client(struct spp_device *dev, + bt_bdaddr_t *bdaddr, + spp_callback_t callback); +bt_status_t btif_spp_open_server(struct spp_device *dev, + spp_callback_t callback); +bt_status_t btif_spp_disconnect(struct spp_device *dev); +bt_status_t btif_spp_close(struct spp_device *dev); +void btif_spp_close_device(struct spp_device *dev); +bt_status_t btif_spp_read(struct spp_device *dev, char *buffer, uint16_t *nBytes); +bt_status_t btif_spp_write(struct spp_device *dev, char *buffer, uint16_t *nBytes); +bt_status_t btif_spp_service_setup(struct spp_device *dev, + struct spp_service *service, + btif_sdp_record_t *record); +bt_status_t btif_ccmp_open(struct spp_device *dev, + btif_remote_device_t *btDevice, + spp_callback_t callback, + uint8_t port); +struct spp_device *btif_create_spp_device(void); +void btif_destroy_spp_device(struct spp_device *dev_t); +struct spp_device *btif_spp_get_device(uint32_t app_id); +struct spp_service *btif_create_spp_service(void); +void btif_destroy_spp_service(struct spp_service *spp_service_p); +uint32_t btif_spp_get_app_id(struct spp_device *dev); +uint32_t btif_spp_get_rfcomm_handle(struct spp_device *dev); +uint8_t btif_spp_get_server_channel(struct spp_device *dev); +const char *btif_spp_event2str(spp_event_t event); + +typedef void (*btif_bt_spp_app_callback_func)(void* spp_devi, void* spp_para); +void btif_register_bt_spp_callback_func(btif_bt_spp_app_callback_func func); +uint32_t btif_spp_profile_save_ctx(uint32_t app_id,btif_remote_device_t *rem_dev, uint8_t *buf, uint32_t buf_len); +uint32_t btif_spp_profile_restore_ctx(uint8_t *buf, uint32_t buf_len); + +/*--------------------------------------------------------------------------- + * rfcomm channel number + * should be from 1 to 30 + */ +enum RFCOMM_CHANNEL_NUM_ { + RFCOMM_CHANNEL_1 = 10, + RFCOMM_CHANNEL_2, + RFCOMM_CHANNEL_3, + RFCOMM_CHANNEL_4, + RFCOMM_CHANNEL_5, + RFCOMM_CHANNEL_6, + RFCOMM_CHANNEL_7, + RFCOMM_CHANNEL_8, + RFCOMM_CHANNEL_9, + RFCOMM_CHANNEL_10, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __SPP_API_H__ */ diff --git a/services/bt_if_enhanced/inc/spp_task.h b/services/bt_if_enhanced/inc/spp_task.h new file mode 100644 index 0000000..ca70d0a --- /dev/null +++ b/services/bt_if_enhanced/inc/spp_task.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __SPP_TASK_H__ +#define __SPP_TASK_H__ + +#include "cmsis_os.h" +#include "cqueue.h" +#include "rfcomm_api.h" +#include "sdp_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +osThreadId create_spp_read_thread(void); + +void close_spp_read_thread(void); + +int spp_mailbox_put(struct spp_device *dev, uint8_t spp_dev_num, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* __SPP_TASK_H__ */ diff --git a/services/bt_if_enhanced/inc/tws_role_switch.h b/services/bt_if_enhanced/inc/tws_role_switch.h new file mode 100644 index 0000000..6565417 --- /dev/null +++ b/services/bt_if_enhanced/inc/tws_role_switch.h @@ -0,0 +1,101 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __TWS_ROLE_SWITCH__H__ +#define __TWS_ROLE_SWITCH__H__ + +#include "bluetooth.h" + +enum TWS_DATA_STRUCTURE +{ + BT_ME = 0, + BT_HCI, + CMGR_CONTEXT, + + BT_L2CAP, + BT_RFC, + + RFCOMM_CHANNEL, + AVRCP_CONTEXT, + APP_BT_DEVICE, + AVDEV_CONTEXT, + SLAVE_SAVE_DATA_OK, +}; + +enum PSM_CONTEXT_TYPE +{ + PSM_CONTEXT_SDP = 0x01, //SDP + PSM_CONTEXT_RFC = 0x02, //RFCOMM MUX,HFP and SPP share + PSM_CONTEXT_AVDTP = 0x04, //A2DP + PSM_CONTEXT_AVCTP = 0x08, //AVRCP + + PSM_CONTEXT_INVALID = 0x80, +}; + +#define BT_RPOFILE_FINAL_FLAG (0x55) + +enum PROFILE_CONTEXT_FLAG +{ +#if defined(ENHANCED_STACK) + BT_HFP_FLAG = 0x01, + BT_A2DP_FLAG = 0x02, + BT_AVRCP_FLAG = 0x04, + BT_MAP_FLAG =0x08, + BT_HID_FLAG = 0x10, + + //add new profile flag here + + BT_SPP_FLAG = 0x80, //SPP has multiple app id(total BTIF_APP_SPP_NUM),BT_SPP_FLAG flag should be at high bit +#else + BT_COMMON_FLAG = 0x01, + BT_RFC_MUX_FLAG = 0x02, + BT_HFP_FLAG = 0x04, + BT_A2DP_FLAG = 0x08, + BT_A2DP_CONTINUE_FLAG = 0x10, + BT_AVRCP_FLAG = 0x20, + BT_SPP_FLAG = 0x40, + + DATA_COMPLETE_FLAG = 0x80, +#endif +}; + +#define BT_ALL_CONTEXT_PSM (PSM_CONTEXT_SDP | PSM_CONTEXT_RFC | PSM_CONTEXT_AVDTP | PSM_CONTEXT_AVCTP) + +#if defined(ENHANCED_STACK) +#define BT_ALL_CONTEXT_FLAG (BT_HFP_FLAG | BT_A2DP_FLAG | BT_AVRCP_FLAG | BT_MAP_FLAG | BT_SPP_FLAG | BT_HID_FLAG) +#else +#define BT_ALL_CONTEXT_FLAG (BT_COMMON_FLAG | BT_RFC_MUX_FLAG | BT_HFP_FLAG | BT_A2DP_FLAG | BT_A2DP_CONTINUE_FLAG | BT_AVRCP_FLAG | SPP_SERVER_INTERACTION_FLAG) +#endif + +#define BT_ALL_RFC_APP_ID (BTIF_APP_HFP_PROFILE_ID | BT_SPP_FLAG) + +#define BT_EARPHONE_BASIC_APP_ID (BTIF_APP_HFP_PROFILE_ID | BTIF_APP_A2DP_PROFILE_ID | BTIF_APP_AVRCP_PROFILE_ID) + +enum TWS_CHANNEL_TYPE +{ + HF_RF_CHANNEL = 0, + UNKNOWN_CHANNEL, +}; + +#ifdef __cplusplus +extern "C" { +#endif /* */ + + +#ifdef __cplusplus +} +#endif /* */ +#endif /* __ME_H */ diff --git a/services/bt_profiles_enhanced/Makefile b/services/bt_profiles_enhanced/Makefile new file mode 100644 index 0000000..0235a64 --- /dev/null +++ b/services/bt_profiles_enhanced/Makefile @@ -0,0 +1,101 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)protocols/*/*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)protocols/*/*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)protocols/*/*.cpp)) + +ifeq ($(AUTO_TEST),1) +obj_s += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)protocols/test/*/*.s)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)protocols/test/*/*.c)) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)protocols/test/*/*.cpp)) +endif + +obj_s += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)common/*.s)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)common/*.c)) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)common/*.cpp)) + +obj_s += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)besport/*.s)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)besport/*.c)) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)besport/*.cpp)) + +obj_s += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hci/*.s)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hci/*.c)) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)hci/*.cpp)) + +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)main/bt_schedule.c)) + +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)applications/hshf/hshf_app.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)applications/hshf/bt_schedule.c)) + +obj_s += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)lib_proc/*.s)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)lib_proc/*.c)) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)lib_proc/*.cpp)) + +ifeq ($(IBRT), 1) +BTPROFILE_LIB_NAME := ibrt_libbt_profiles +else +BTPROFILE_LIB_NAME := $(CHIP)_libbt_profiles +endif + +ifeq ($(HFP_1_6_ENABLE), 1) +BTPROFILE_LIB_NAME := $(BTPROFILE_LIB_NAME)_sbc_enc +endif + +ifeq ($(ROM_UTILS_ON),1) +BTPROFILE_LIB_NAME := $(BTPROFILE_LIB_NAME)_romaac +endif + +ifeq ($(BLE),1) +BTPROFILE_LIB_NAME := $(BTPROFILE_LIB_NAME)_ble +endif + +ifeq ($(BT_RF_PREFER), 2M) +BTPROFILE_LIB_NAME := $(BTPROFILE_LIB_NAME)_2m +endif + +ifeq ($(BT_RF_PREFER), 3M) +BTPROFILE_LIB_NAME := $(BTPROFILE_LIB_NAME)_3m +endif + +ifeq ($(KERNEL),RTX) +BTPROFILE_LIB_NAME := $(BTPROFILE_LIB_NAME)_RTX +endif +ifeq ($(KERNEL),RTX5) +BTPROFILE_LIB_NAME := $(BTPROFILE_LIB_NAME)_RTX5 +endif + +$(BTPROFILE_LIB_NAME)-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +obj-y += $(BTPROFILE_LIB_NAME).a + +CFLAGS_a2dp.o += -O3 + +CFLAGS_btm.o += -DBESLIB_INFO=$(BESLIB_INFO) + +subdir-ccflags-y += \ + -Iservices/osif/ \ + -Iservices/auto_test \ + $(BT_IF_INCLUDES) \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/bridge/ \ + -Iservices/ble_stack/ke/api/ \ + -Iservices/ble_stack/ble_ip/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/api/ \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iutils/intersyshci \ + -Iservices/bt_app \ + -Iservices/audioflinger \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iservices/ibrt_core/inc \ + -Iutils/lockcqueue \ + -Iapps/key \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iapps/audioplayers diff --git a/services/bt_profiles_enhanced/inc/a2dp.h b/services/bt_profiles_enhanced/inc/a2dp.h new file mode 100644 index 0000000..6c54e4a --- /dev/null +++ b/services/bt_profiles_enhanced/inc/a2dp.h @@ -0,0 +1,187 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __A2DP_H__ +#define __A2DP_H__ + +#include "btlib_type.h" +#include "a2dp_i.h" +#include "avdtp_i.h" + +#define AVDTP_CODEC_CAP_MAX_LENGTH (32) + +#define AVDTP_VER_1_2 0x0102 +#define AVDTP_VER_1_3 0x0103 +#define AVDTP_LOCAL_VERSION AVDTP_VER_1_3 + +#define A2DP_VER_1_2 0x0102 +#define A2DP_VER_1_3 0x0103 +#define A2DP_LOCAL_VERSION A2DP_VER_1_3 + +#define A2DP_MEDIA_TYPE_AUDIO 0x00 + +#define A2DP_CODEC_SBC 0x00 +#define A2DP_CODEC_MPEG12_AUDIO 0x01 +#define A2DP_CODEC_MPEG24_AAC 0x02 +#define A2DP_CODEC_ATRAC 0x03 +#define A2DP_CODEC_VENDOR_SPECIFIC 0xff + +#define A2DP_SAMPLING_FREQ_16000 (1 << 3) +#define A2DP_SAMPLING_FREQ_32000 (1 << 2) +#define A2DP_SAMPLING_FREQ_44100 (1 << 1) +#define A2DP_SAMPLING_FREQ_48000 1 + +#define A2DP_CHANNEL_MODE_MONO (1 << 3) +#define A2DP_CHANNEL_MODE_DUAL_CHANNEL (1 << 2) +#define A2DP_CHANNEL_MODE_STEREO (1 << 1) +#define A2DP_CHANNEL_MODE_JOINT_STEREO 1 + +#define A2DP_BLOCK_LENGTH_4 (1 << 3) +#define A2DP_BLOCK_LENGTH_8 (1 << 2) +#define A2DP_BLOCK_LENGTH_12 (1 << 1) +#define A2DP_BLOCK_LENGTH_16 1 + +#define A2DP_SUBBANDS_4 (1 << 1) +#define A2DP_SUBBANDS_8 1 + +#define A2DP_ALLOCATION_SNR (1 << 1) +#define A2DP_ALLOCATION_LOUDNESS 1 + +struct a2dp_sep { + uint8 type; //src or snk + struct avdtp_local_sep *sep; +}; + +struct get_codec_cap_t { + uint8 ** cap; + uint16 * cap_len; + bool done; +}; + +struct sbc_codec_cap { + uint32 rfa0:4; + uint32 media_type:4; + uint32 media_codec_type:8; + uint32 channel_mode:4; + uint32 frequency:4; + uint32 allocation_method:2; + uint32 subbands:2; + uint32 block_length:4; + uint8 min_bitpool; + uint8 max_bitpool; +} __attribute__ ((packed)); + +#define AAC_OCTECT0_MPEG2_AAC_LC 0x80 +#define AAC_OCTECT1_SAMP_FREQ_44100 0x01 +#define AAC_OCTECT2_SAMP_FREQ_48000 0x8 +#define AAC_OCTECT2_CHAN_MODE_MONO 0x08 +#define AAC_OCTECT2_CHAN_MODE_STEREO 0x04 + +struct aac_codec_cap { + uint32 media_type:8; //Audio 0x00 + uint32 media_codec_type:8; //MEPG-2,4 AAC 0x02 + uint32 object_types_support:8; //MPEG-2 AAC LC 0x80 + uint32 samp_freq_441:8; //44100 0x01 + uint32 channel_mode:4; //1(0x8) 2(0x4) 1 2(0xc) + uint32 samp_freq_48k:4; //48000 0x8- + uint32 max_peak_bitrate_high:7; + uint32 vbr_supported:1; + uint8 max_peak_bitrate_low2; + uint8 max_peak_bitrate_low1; +} __attribute__ ((packed)); + +#define LHDC_CODEC_SAMP_RATE_96000 0x01 +#define LHDC_CODEC_SAMP_RATE_88200 0x02 +#define LHDC_CODEC_SAMP_RATE_48000 0x04 +#define LHDC_CODEC_SAMP_RATE_44100 0x08 +#define LHDC_CODEC_BITS_PER_SAMP_24 0x10 +#define LHDC_CODEC_BITS_PER_SAMP_16 0x20 + +#define LHDC_CODEC_VERSION_V3 0x01 +#define LHDC_CODEC_VERSION_LOWER 0x00 +#define LHDC_CODEC_VERSION_MASK 0x0f +#define LHDC_CODEC_MAX_SR_900 0x00 +#define LHDC_CODEC_MAX_SR_500 0x10 +#define LHDC_CODEC_MAX_SR_400 0x20 +#define LHDC_CODEC_MAX_LLC_EN 0x40 +#define LHDC_CODEC_MAX_SR_MASK 0xf0 + +#define LHDC_CODEC_COF_CSC_DISABLE 0x01 +#define LHDC_CODEC_COF_CSC 0x02 +#define LHDC_CODEC_COF_CSC_PRE 0x04 +#define LHDC_CODEC_COF_CSC_RFU 0x08 + +struct lhdc_codec_cap { + uint8 media_type; //Audio 0x00 + uint8 media_codec_type; //Vendor-Specific Codec 0xff + uint8 vendor_id[4]; //3a 05 00 00 + uint8 codec_id[2]; //32 4c (Lower Ver.) or 33 4c (V3) + uint8 sample_rate; + uint8 max_sr_ver; + uint8 cof_csc; +} __attribute__ ((packed)); + +#define LDAC_CODEC_SAMP_FREQ_96000 0x04 +#define LDAC_CODEC_SAMP_FREQ_88200 0x08 +#define LDAC_CODEC_SAMP_FREQ_48000 0x10 +#define LDAC_CODEC_SAMP_FREQ_44100 0x20 + +#define LDAC_CODEC_CHAN_MODE_STEREO 0x01 +#define LDAC_CODEC_CHAN_MODE_DUAL 0x02 +#define LDAC_CODEC_CHAN_MODE_MONO 0x04 + +struct ldac_codec_cap { + uint8 media_type; //Audio 0x00 + uint8 media_codec_type; //Vendor-Specific Codec 0xff + uint8 vendor_id[4]; //2d 01 00 00 + uint8 codec_id[2]; //aa 00 + uint8 sample_freq; + uint8 chan_mode; +} __attribute__ ((packed)); + +#define SCALABLE_CODEC_BITS_16 0x00 +#define SCALABLE_CODEC_BITS_24 0x08 +#define SCALABLE_CODEC_SAMP_48000 0x10 +#define SCALABLE_CODEC_SAMP_44100 0x20 +#define SCALABLE_CODEC_SAMP_32000 0x40 +#define SCALABLE_CODEC_SAMP_96000 0x80 + +struct scalable_codec_cap { + uint8 media_type; //Audio 0x00 + uint8 media_codec_type; //Vendor-Specific Codec 0xff + uint8 vendor_id[4]; //75 00 00 00 + uint8 codec_id[2]; //03 01 + uint8 sample_rate; +} __attribute__ ((packed)); + +U16 a2dp_MediaPacketSize(struct a2dp_control_t *Stream); +#define a2dp_MediaPacketSize(s) (l2cap_get_tx_mtu((s)->l2capSignalHandle)) + +#if defined(__cplusplus) +extern "C" { +#endif + +U16 a2dp_create_media_header(struct a2dp_control_t *a2dp_ctl, U8 *buffer); +void a2dp_notifyCallback(uint8 event, uint32 l2cap_channel, void *pData, uint8 reason); +void a2dp_dataRecvCallback(uint32 l2cap_handle, struct pp_buff *ppb); +int8 a2dp_close(struct a2dp_control_t * stream); +void doDisconnect(void); +#if defined(__cplusplus) +} +#endif + +#endif /* __A2DP_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/a2dp_i.h b/services/bt_profiles_enhanced/inc/a2dp_i.h new file mode 100644 index 0000000..684a5b3 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/a2dp_i.h @@ -0,0 +1,179 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __A2DP_I_H__ +#define __A2DP_I_H__ + +#include "btlib_type.h" +#include "btm_i.h" +#include "avdtp.h" +#include "avdtp_i.h" +#include "sdp.h" + +#define A2DP_RECVDATA_BUF_SIZE 48 + +/* notify upper layer */ +enum a2dp_event_t +{ + /* user command event*/ + AV_CONNECT_REQ = 1, + AV_DISCONNECT_REQ, //210 + AV_TRANS_REQ, + AV_SUSPEND_REQ, + AV_START_REQ, + AV_ABORT_REQ, + AV_SET_CONFIG_REQ, + AV_RECONF_REQ, + + /* internal event */ + // AV_EVNT_BEGIN, + AV_CONN_OPENED, //217 + AV_CONN_CLOSED, + + AV_MEDIA_GET_CAP_IND, + AV_MEDIA_SET_CFG_IND, + AV_MEDIA_GET_CFG_CFM, + AV_MEDIA_STREAM_CLOSE, //219 + AV_MEDIA_STREAM_ABORT, //219 + AV_MEDIA_RECONF_IND, + AV_MEDIA_DISCOVERY_COMPLETE, + + AV_MEDIA_OPENED, //219 + AV_MEDIA_STREAM_START, //219 + AV_MEDIA_STREAM_DATA_IND, //219 + AV_MEDIA_STREAM_SUSPEND, //219 + AV_MEDIA_FREQ_CHANGED, //219 + AV_CONN_REQ_FAIL, + AV_MEDIA_SECURITY_CONTROL_CMD, + AV_MEDIA_SECURITY_CONTROL_CFM +}; + +enum av_conn_state_enum +{ + AV_STOP, + AV_STANDBY = 1, //ready + AV_QUERING, //sdp quering + AV_CONNECTING, //initializing + AV_OPEN, //AV_SIG_ACTIVE, + AV_CONNECTED, + AV_STREAMING +}; + + +struct a2dp_control_t +{ + struct bdaddr_t remote; + bool cp_enable; + uint8 disc_reason; + uint32 l2capSignalHandle; + uint32 l2capMediaHandle; + uint32 freq; + uint16 avdtp_local_version; + uint16 avdtp_remote_version; + uint16 a2dp_remote_features; + uint8 channel_mode; + + enum av_conn_state_enum state; /*check if it is connecting now, if it is connecting,the hf_connect_req will not work */ + + struct a2dp_sep *sep; //bind to lsep + struct avdtp_control_t *avdtp; + //struct avdtp_stream *stream; + void *avdtp_codec_req; + void *avdtp_cp_req; + struct avdtp_media_codec_capability *avdtp_codec_cap; + struct avdtp_media_content_protect_capability *avdtp_content_protect_cap; + uint8 type; + struct avdtp_local_sep *lsep; + + void (*indicate)(struct a2dp_control_t *stream, uint8 event, void *pData); + void (*data_cb)(struct a2dp_control_t *stream,struct pp_buff *ppb); + uint8 sep_prio; + struct a2dp_control_t* next; + avdtp_media_header_t media_header; + struct sdp_request sdp_request; + uint8 device_id; +}; + +struct a2dp_ctx_input { + struct ctx_content ctx; + struct bdaddr_t *remote; + struct a2dp_control_t *a2dp_ctl; + struct avdtp_control_t *avdtp_ctl; + struct avdtp_local_sep *local_sep; + uint32 l2capSignalHandle; + uint32 l2capMediaHandle; + void (*indicate_callback)(struct a2dp_control_t *stream, uint8 event, void *pData); + void (*data_callback)(struct a2dp_control_t *stream, struct pp_buff *ppb); +}; + +struct a2dp_ctx_output { +}; + +extern struct a2dp_control_t *a2dp_ctl_list; + +//int8 av_register_datacallback(struct a2dp_control_t *stream,void (*data_callback)(struct a2dp_control_t* stream, struct pp_buff *ppb)); + +#if defined(__cplusplus) +extern "C" { +#endif + +void a2dp_stack_init(void); +/*---- a2dp_app.c ----*/ +//void app_callback(struct a2dp_control_t* stream, uint8 event, void *pData); +void data_callback_av(struct a2dp_control_t *stream, struct pp_buff *ppb); + +/*----a2dp.c----*/ +int8 a2dp_register(struct a2dp_control_t *stream, + void (*indicate_callback)(struct a2dp_control_t *stream, uint8 event, void *pData), + void (*data_callback)(struct a2dp_control_t *stream, struct pp_buff *ppb)); +int a2dp_unregister(struct a2dp_control_t *ctl); + +enum av_conn_state_enum av_getState(struct a2dp_control_t*stream) ; +void av_setState( struct a2dp_control_t *stream, enum av_conn_state_enum state); +int8 av_turnOn(struct a2dp_control_t *stream); +int8 av_turnOff(struct a2dp_control_t * stream); + +int8 av_connectReq(struct a2dp_control_t *stream, struct bdaddr_t *peer); +int8 av_disconnectReq(struct a2dp_control_t *stream); +//int8 av_sendData(uint8 *data, uint32 datalen); + +void av_reset_a2dp_state(struct a2dp_control_t * stream); + +const char *a2dp_state2str(enum av_conn_state_enum state); + +int8 av_suspendReq(struct a2dp_control_t *stream); +int8 av_startReq( struct a2dp_control_t *stream); +int8 av_abortReq( struct a2dp_control_t *stream); +int8 av_setConfReq( struct a2dp_control_t *stream); /// +int8 av_reconfReq( struct a2dp_control_t *stream ); /// + +void av_discoverCap(struct a2dp_control_t *stream); +int8 av_setSinkDelay(struct a2dp_control_t *stream, uint16 delay_ms); +int8 av_security_control_req(struct a2dp_control_t *stream, uint8_t *data, uint16_t len); +int8 av_security_control_resp(struct a2dp_control_t *stream, uint8_t *data, uint16_t len, uint8 error); +uint32 av_getFreq( struct a2dp_control_t *stream); +void av_setFreq( struct a2dp_control_t *stream, uint32 frequency); +uint8 av_getChannelMode(struct a2dp_control_t *stream); + +struct avdtp_control_t *a2dp_get_avdtp_control(struct a2dp_control_t *stream); +uint32 a2dp_save_ctx(struct a2dp_control_t *a2dp_ctl, uint8_t *buf, uint32_t buf_len); +uint32 a2dp_restore_ctx(struct a2dp_ctx_input *input, struct a2dp_ctx_output *output); + +#if defined(__cplusplus) +} +#endif + +#endif /* __A2DP_I_H__ */ diff --git a/services/bt_profiles_enhanced/inc/avctp.h b/services/bt_profiles_enhanced/inc/avctp.h new file mode 100644 index 0000000..3ed7b1b --- /dev/null +++ b/services/bt_profiles_enhanced/inc/avctp.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __AVCTP_H__ +#define __AVCTP_H__ + +#include "avctp_i.h" +#include "l2cap_i.h" + +#ifndef PSM_AVCTP +#endif + +#define AVCTP_DEFAULT_MTU 127 +#define AVCTP_DEFAULT_CREDITS 7 + +#define AVCTP_MAX_L2CAP_MTU 1013 +#define AVCTP_MAX_CREDITS 40 + +/* flow control states */ +#define AVCTP_CFC_DISABLED 0 +#define AVCTP_CFC_ENABLED AVCTP_DEFAULT_CREDITS + +#define AVCTP_CFG_SESSIONS_MAX 2 /* means how many l2cap channel */ + +struct avctp_resp { + struct avctp_header header; + void *avrcp_resp; +} __attribute__ ((packed)); + +#endif /* __AVCTP_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/avctp_i.h b/services/bt_profiles_enhanced/inc/avctp_i.h new file mode 100644 index 0000000..234b1fa --- /dev/null +++ b/services/bt_profiles_enhanced/inc/avctp_i.h @@ -0,0 +1,173 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __AVCTP_I_H__ +#define __AVCTP_I_H__ + +#include "btlib.h" +#include "co_ppbuff.h" +#include "bt_co_list.h" +#include "btm_i.h" +#include "l2cap_i.h" + +enum avctp_event_enum { + AVCTP_CHANNEL_CONN_REQ, + AVCTP_CHANNEL_OPEN, + AVCTP_CHANNEL_NEW_OPENED, + AVCTP_CHANNEL_TX_HANDLED, + AVCTP_CHANNEL_CLOSED +}; + +enum avctp_ctl_state_enum { + AVCTP_CTL_FREE, + AVCTP_CTL_INUSE +}; + +enum avctp_frame_type_enum { + AVCTP_FRAME_ADV_CMD, + AVCTP_FRAME_ADV_RSP, + AVCTP_FRAME_PNL_CMD, + AVCTP_FRAME_PNL_RSP, + AVCTP_FRAME_UNITINFO_CMD, + AVCTP_FRAME_UNITINFO_RSP, + AVCTP_FRAME_SUBUNITINFO_RSP, +}; + +enum avctp_tx_status_enum { + AVCTP_TX_IDLE, + AVCTP_TX_BUSY, +}; + +enum avctp_role_enum { + AVCTP_MASTER, + AVCTP_SLAVE +}; + +#define AVCTP_CFG_SERVER_CHANNEL 0x08 + +/* +struct avctp_session { + struct list_node list; + + uint32 l2cap_handle; + + struct bdaddr_t remote; + + void (*notify_callback) (uint8 event, struct avctp_session *s, void *pdata); + void (*datarecv_callback) (struct avctp_session *s, struct pp_buff *ppb); +}; +*/ + +#define AVCTP_PKT_HEADER_PROFILE_ID 0x110E + +#define AVCTP_PKT_HEADER_VALID_PID 0 +#define AVCTP_PKT_HEADER_INVALID_PID 1 + +#define AVCTP_PKT_HEADER_IS_CMD 0 +#define AVCTP_PKT_HEADER_IS_RESPONSE 1 + +enum avctp_packet_type +{ + AVCTP_PACKET_TYPE_SINGLE = 0, + AVCTP_PACKET_TYPE_START = 1, + AVCTP_PACKET_TYPE_CONTINUE = 2, + AVCTP_PACKET_TYPE_END = 3, +}; + +struct avctp_header { + uint32 + ipid_ind : 1, + com_or_resp : 1, + packet_type : 2, + trans_label : 4; + uint8 profile_ind[2]; +}__attribute__ ((packed)); + +struct avctp_frame_t { + struct list_node node; + struct avctp_header header; + int8 frame_type; + bool need_free; + uint8 *data; + uint32 data_len; + uint32 data_offset; +}; + +struct avctp_control_t { + struct list_node node; + struct list_node tx_list; + + struct bdaddr_t remote; + struct avctp_header header; + int8 server_channel; + uint32 l2cap_handle; + + int8 tx_status; + + enum avctp_ctl_state_enum ctl_state; + + enum avctp_role_enum role; + int (*notify_callback)(struct avctp_control_t *avctp_ctl, uint8 event, uint32 handle, void *pdata); + void (*datarecv_callback)(struct avctp_control_t *avctp_ctl, uint32 handle, struct pp_buff *ppb); +}; + +struct avctp_ctx_input { + struct ctx_content ctx; + struct bdaddr_t *remote; + uint32 l2cap_handle; + struct avctp_control_t *avctp_ctl; +}; + +struct avctp_ctx_output { +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +int avctp_l2cap_notify_callback(enum l2cap_event_enum event, uint32 l2cap_handle, void *pdata, uint8 reason); +void avctp_l2cap_datarecv_callback(uint32 l2cap_handle, struct pp_buff *ppb); + +int8 avctp_init(struct avctp_control_t *avctp_ctl); +int8 avctp_init_service(void); + +int8 avctp_register_server (struct avctp_control_t *avctp_ctl, int8 server_channel, + int (*avctp_notify_callback)(struct avctp_control_t *avctp_ctl, uint8 event, uint32 handle, void *pdata), + void (*avctp_datarecv_callback)(struct avctp_control_t *avctp_ctl, uint32 handle, struct pp_buff *ppb) + ); + +int8 avctp_unregister_server (struct avctp_control_t *avctp_ctl, int8 server_channel); + +void avctp_init_packet_header(struct avctp_control_t *avctp_ctl, struct avctp_frame_t *frame, + int8 is_cmd, int8 ipid_ind, uint16 profile_ind); +int8 avctp_send_message(struct avctp_control_t *avctp_ctl, struct avctp_frame_t *frame); +int8 avctp_close(struct avctp_control_t *avctp_ctl); +int8 avctp_open_i(struct avctp_control_t *avctp_ctl, struct bdaddr_t *remote, + int (*avctp_notify_callback)(struct avctp_control_t *avctp_ctl, uint8 event, uint32 handle, void *pdata), + void (*avctp_datarecv_callback)(struct avctp_control_t *avctp_ctl, uint32 handle, struct pp_buff *ppb), + uint32 *avctp_handle); +int8 avctp_disconnectReq (struct avctp_control_t *avctp_ctl); + +uint32 avctp_get_l2cap_handle(struct avctp_control_t *avctp_ctl); +uint16 avctp_get_conn_handle(struct avctp_control_t *avctp_ctl); +uint32 avctp_save_ctx(struct avctp_control_t *avctp_ctl, uint8_t *buf, uint32_t buf_len); +uint32 avctp_restore_ctx(struct avctp_ctx_input *input, struct avctp_ctx_output *output); + +#if defined(__cplusplus) +} +#endif + +#endif /* __AVCTP_I_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/avdtp.h b/services/bt_profiles_enhanced/inc/avdtp.h new file mode 100644 index 0000000..0eb0482 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/avdtp.h @@ -0,0 +1,333 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __AVDTP_H__ +#define __AVDTP_H__ + +#include "avdtp_i.h" +#include "l2cap_i.h" +#include "btm.h" + +#define MAX_SEID 0x3E + +#define AVDTP_DISCOVER 0x01 +#define AVDTP_GET_CAPABILITIES 0x02 +#define AVDTP_SET_CONFIGURATION 0x03 +#define AVDTP_GET_CONFIGURATION 0x04 +#define AVDTP_RECONFIGURE 0x05 +#define AVDTP_OPEN 0x06 +#define AVDTP_START 0x07 +#define AVDTP_CLOSE 0x08 +#define AVDTP_SUSPEND 0x09 +#define AVDTP_ABORT 0x0A +#define AVDTP_SECURITY_CONTROL 0x0B +#define AVDTP_GET_ALL_CAPABILITIES 0x0C +#define AVDTP_DELAYREPORT 0x0D + +#define AVDTP_PKT_TYPE_SINGLE 0x00 +#define AVDTP_PKT_TYPE_START 0x01 +#define AVDTP_PKT_TYPE_CONTINUE 0x02 +#define AVDTP_PKT_TYPE_END 0x03 + +#define AVDTP_MSG_TYPE_COMMAND 0x00 +#define AVDTP_MSG_TYPE_GENERAL_REJECT 0x01 +#define AVDTP_MSG_TYPE_ACCEPT 0x02 +#define AVDTP_MSG_TYPE_REJECT 0x03 + +/* AVDTP error definitions */ +#define AVDTP_BAD_HEADER_FORMAT 0x01 +#define AVDTP_BAD_LENGTH 0x11 +#define AVDTP_BAD_ACP_SEID 0x12 +#define AVDTP_SEP_IN_USE 0x13 +#define AVDTP_SEP_NOT_IN_USE 0x14 +#define AVDTP_BAD_SERV_CATEGORY 0x17 +#define AVDTP_BAD_PAYLOAD_FORMAT 0x18 +#define AVDTP_NOT_SUPPORTED_COMMAND 0x19 +#define AVDTP_INVALID_CAPABILITIES 0x1A +#define AVDTP_BAD_RECOVERY_TYPE 0x22 +#define AVDTP_BAD_MEDIA_TRANSPORT_FORMAT 0x23 +#define AVDTP_BAD_RECOVERY_FORMAT 0x25 +#define AVDTP_BAD_REPORT_FORMAT 0x65 +#define AVDTP_BAD_ROHC_FORMAT 0x26 +#define AVDTP_BAD_CP_FORMAT 0x27 +#define AVDTP_BAD_MULTIPLEXING_FORMAT 0x28 +#define AVDTP_UNSUPPORTED_CONFIGURATION 0x29 +#define AVDTP_BAD_STATE 0x31 + +#define AVDTP_CONN_TIMEOUT //(HZ * 30) +#define AVDTP_DISC_TIMEOUT //(HZ * 20) +#define AVDTP_AUTH_TIMEOUT //(HZ * 25) + +#define AVDTP_DEFAULT_MTU 127 +#define AVDTP_DEFAULT_CREDITS 7 + +#define AVDTP_MAX_L2CAP_MTU 1013 +#define AVDTP_MAX_CREDITS 40 + +#define AVDTP_PPB_HEAD_RESERVE 8 +#define AVDTP_PPB_TAIL_RESERVE 2 +#define AVDTP_PPB_RESERVE (AVDTP_PPB_HEAD_RESERVE + AVDTP_PPB_TAIL_RESERVE) + +typedef struct +{ + U8 version; /* RTP Version */ + + U8 padding; /* If the padding bit is set, the packet contains + * one or more additional padding octets at the end, + * which are not parts of the payload. The last + * octet of the padding contains a count of how many + * padding octets should be ignored. + */ + + U8 marker; /* Profile dependent. Used to mark significant + * events such as frame boundaries in the packet + * stream. + */ + + U8 payloadType; /* Profile dependent. Identifies the RTP payload + * type. + */ + + U16 sequenceNumber; /* Incremented by one for each packet sent */ + + U32 timestamp; /* Time stamp of the sample */ + + U32 ssrc; /* Synchronization source */ + + U8 csrcCount; /* The number of CSRC (Contributing Source) + * identifiers that follow the fixed header. + */ + + U32 csrcList[15]; /* List of CSRC identifiers */ + +} avdtp_media_header_t; + +struct avdtp_header +{ + uint32 message_type : 2; + uint32 packet_type : 2; + uint32 transaction : 4; + uint32 signal_id : 6; + uint32 rfa0 : 2; + // uint32 unused:16; +} __attribute__((packed)); + +struct seid_req +{ + uint32 message_type : 2; + uint32 packet_type : 2; + uint32 transaction : 4; + uint32 signal_id : 6; + uint32 rfa0 : 2; + uint32 rfa1 : 2; + uint32 acp_seid : 6; + uint8 param[0]; + // uint32 unused:8; +} __attribute__((packed)); + +struct discover_resp +{ + // struct avdtp_header header; + // struct seid_info *seps; + uint32 message_type : 2; + uint32 packet_type : 2; + uint32 transaction : 4; + uint32 signal_id : 6; + uint32 rfa0 : 2; + + uint32 rfa1 : 1; + uint32 inuse : 1; + uint32 seid : 6; + uint32 rfa2 : 3; + uint32 type : 1; + uint32 media_type : 4; +} __attribute__((packed)); + +struct discover_rej +{ + // struct avdtp_header header; + // struct seid_info *seps; + uint32 message_type : 2; + uint32 packet_type : 2; + uint32 transaction : 4; + uint32 signal_id : 6; + uint32 rfa0 : 2; + uint8 error_code; +} __attribute__((packed)); + + + +struct security_control_req +{ + //avdtp hrader + uint32 message_type : 2; + uint32 packet_type : 2; + uint32 transaction : 4; + uint32 signal_id : 6; + uint32 rfa0 : 2; + uint32 rfa2 : 2; + uint32 acp_seid : 6; + //Content Protection Method Dependent Data + uint8 *data; +} __attribute__((packed)); + +struct security_control_resp +{ + struct avdtp_header header; + uint8 *data; +} __attribute__((packed)); + +struct getcap_resp +{ + struct avdtp_header header; + uint8 *caps; +} __attribute__((packed)); + +struct getcap_req +{ + uint32 message_type : 2; + uint32 packet_type : 2; + uint32 transaction : 4; + uint32 signal_id : 6; + uint32 rfa0 : 2; + uint32 rfa2 : 2; + uint32 ACP_seid : 6; +} __attribute__((packed)); + + +struct start_req +{ + struct avdtp_header header; + + uint8 first_seid; + uint8 *other_seids; +} __attribute__((packed)); + +struct suspend_req +{ + struct avdtp_header header; + + uint8 first_seid; + uint8 *other_seids; +} __attribute__((packed)); + +struct setconf_req +{ + // struct avdtp_header header; + uint32 message_type : 2; + uint32 packet_type : 2; + uint32 transaction : 4; + uint32 signal_id : 6; + uint32 rfa0 : 2; + + uint32 rfa2 : 2; + uint32 acp_seid : 6; + uint32 rfa1 : 2; + uint32 int_seid : 6; + + uint8 *caps; +} __attribute__((packed)); + +struct reconf_req +{ + // struct avdtp_header header; + uint32 message_type : 2; + uint32 packet_type : 2; + uint32 transaction : 4; + uint32 signal_id : 6; + uint32 rfa0 : 2; + + uint32 rfa2 : 2; + uint32 acp_seid : 6; + + uint8 *caps; +} __attribute__((packed)); +struct general_rej +{ + uint32 message_type : 2; + uint32 packet_type : 2; + uint32 transaction : 4; + //uint32 rfa0:8; + uint32 signal_id : 6; //modified by owen.liu, for support version 1.3 + uint32 rfa0 : 2; +} __attribute__((packed)); + +struct seid_rej +{ + // struct avdtp_header header; + uint32 message_type : 2; + uint32 packet_type : 2; + uint32 transaction : 4; + uint32 signal_id : 6; + uint32 rfa0 : 2; + + uint32 error : 8; + uint32 unused : 8; +} __attribute__((packed)); + +struct conf_rej +{ + struct avdtp_header header; + uint8 category; + uint8 error; +} __attribute__((packed)); + +struct stream_rej +{ + struct avdtp_header header; + uint8 acp_seid; + uint8 error; +} __attribute__((packed)); + +struct avdtp_session +{ + uint32 l2cap_handle; + uint8 state; +} __attribute__((packed)); + +enum avdtp_session_state_enum +{ + AVDTP_SESSION_CLOSE, /* l2cap connection closed, wait for openning, and then can send out sabm request */ + AVDTP_SESSION_CONNECTED, /* l2cap channel created */ + AVDTP_SESSION_OPEN /* avdtp session open, ready for start stream */ +}; + + + +//int8 avdtp_open(struct avdtp_session *session, struct avdtp_stream *stream); + +/* flow control states */ +#define AVDTP_CFC_DISABLED 0 +#define AVDTP_CFC_ENABLED AVDTP_DEFAULT_CREDITS + +#define AVDTP_CFG_SESSIONS_MAX 5 /* means how many l2cap channel */ + +#if defined(__cplusplus) +extern "C" { +#endif + + +int8 avdtp_send(uint32 avdtp_handle, uint8 *data, uint32 datalen); +int avdtp_l2cap_notify_callback(enum l2cap_event_enum event, uint32 l2cap_handle, void *pdata, uint8 reason); +void avdtp_l2cap_datarecv_callback(uint32 l2cap_handle, struct pp_buff *ppb); +struct avdtp_control_t *avdtp_ctl_search_l2caphandle(uint32 l2cap_handle); +void avdtp_free_remote_sep_list(void); +struct avdtp_local_sep* avdtp_find_same_device_other_sep(struct avdtp_local_sep *sep); +#if defined(__cplusplus) +} +#endif + +#endif /* __AVDTP_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/avdtp_i.h b/services/bt_profiles_enhanced/inc/avdtp_i.h new file mode 100644 index 0000000..c72e189 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/avdtp_i.h @@ -0,0 +1,302 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __AVDTP_I_H__ +#define __AVDTP_I_H__ + +#include "btlib.h" +#include "co_ppbuff.h" +#include "bt_co_list.h" +#include "bt_common.h" +#include "avdtp.h" + +enum avdtp_event_enum +{ + AVDTP_OPENED, + AVDTP_ACCEPT_OPENED, + AVDTP_MEDIA_OPENED, + AVDTP_CLOSED +}; + +typedef enum +{ + AVDTP_STATE_IDLE, + AVDTP_STATE_DISCOVER, + AVDTP_STATE_GETCAP, + AVDTP_STATE_SETCONFIG, + AVDTP_STATE_CONFIGURED, + AVDTP_STATE_OPEN, + AVDTP_STATE_STREAMING, + AVDTP_STATE_CLOSING, + AVDTP_STATE_ABORTING +} avdtp_state_t; + +/* SEP types definitions */ +#define AVDTP_SEP_TYPE_SOURCE 0x00 +#define AVDTP_SEP_TYPE_SINK 0x01 + +/* Media types definitions */ +#define AVDTP_MEDIA_TYPE_AUDIO 0x00 +#define AVDTP_MEDIA_TYPE_VIDEO 0x01 +#define AVDTP_MEDIA_TYPE_MULTIMEDIA 0x02 + +/* SEP capability categories */ +#define AVDTP_MEDIA_TRANSPORT 0x01 +#define AVDTP_REPORTING 0x02 +#define AVDTP_RECOVERY 0x03 +#define AVDTP_CONTENT_PROTECTION 0x04 +#define AVDTP_HEADER_COMPRESSION 0x05 +#define AVDTP_MULTIPLEXING 0x06 +#define AVDTP_MEDIA_CODEC 0x07 +#define AVDTP_DELAY_REPORTING 0x08 + +#define AVDTP_CFG_SERVER_CHANNEL 0x07 + +/* AVDTP Content Protection Type */ +#define AVDTP_CP_TYPE_DTCP 0x0001 +#define AVDTP_CP_TYPE_SCMS_T 0x0002 + +struct seid_info +{ + uint32 rfa0 : 1; + uint32 inuse : 1; + uint32 seid : 6; + uint32 rfa2 : 3; + uint32 type : 1; + uint32 media_type : 4; + // uint32 unused:16; +} __attribute__((packed)); +struct avdtp_service_capability +{ + uint8 category; + uint8 length; + uint8 data[1]; +} __attribute__((packed)); + +struct avdtp_media_codec_capability +{ + uint8 media_codec_type; + uint8 len; + uint8 *data; +} __attribute__((packed)); + + +struct avdtp_media_content_protect_capability +{ + uint16 protect_type; + uint8 len; + uint8 *data; +} __attribute__((packed)); + + +struct avdtp_media_delay_report_capability +{ + uint8 len; +} __attribute__((packed)); + +struct avdtp_service_cap_req +{ + struct avdtp_service_capability *cap; + uint8 parse_error; +}__attribute__((packed)); + + + +struct avdtp_config_request +{ + struct avdtp_service_cap_req *trans_cap; + struct avdtp_service_cap_req *codec_cap; + struct avdtp_service_cap_req *cp_cap; + struct avdtp_service_cap_req *dr_cap; + struct avdtp_service_cap_req *rp_cap; + struct avdtp_service_cap_req *mp_cap; + struct avdtp_service_cap_req *hc_cap; + struct avdtp_service_cap_req *rc_cap; + + struct avdtp_service_cap_req *unknown_cap; +}; + +struct avdtp_local_sep +{ + struct seid_info info; + uint8 codec; + struct avdtp_sep_ind *ind; + struct avdtp_sep_cfm *cfm; + void *user_data; + void *a2dp_stream; + uint8 delay_reporting_support; + uint16 dr_delay_ms; + uint8 device_id; + struct avdtp_local_sep *next; +}; + +struct avdtp_remote_sep +{ + uint8 seid; + uint8 transact_id; + uint8 delay_reporting_support; + uint16 avdtp_cp_type; + struct avdtp_service_capability *codec; + struct avdtp_remote_sep *next; +}; + +struct avdtp_control_t +{ + int8 avdtp_channel; + struct bdaddr_t remote; + uint8 remote_seid; + uint8 same_sepid_workaround_for_redmi5; + uint8 delay_reporting_enabled_on_the_stream; + + void (*notify_callback)(uint8 event, uint32 l2cap_channel, void *pdata, uint8 reason); + void (*datarecv_callback)(uint32 l2cap_channel, struct pp_buff *ppb); + void (*discover_cb)(struct avdtp_control_t *avdtp_ctl, struct avdtp_remote_sep *); + uint8 discover_cnt; + + avdtp_state_t state; + + struct avdtp_session *signal_session; + struct avdtp_session *media_session; + void *a2dp_stream; + struct avdtp_local_sep *local_sep; + BOOLEAN initiator; + struct avdtp_control_t *next; + void * cur_op; + + uint8 delay_resp_discover_req; + uint8 discover_req_transaction; +}; + +struct avdtp_ctx_input { + struct ctx_content ctx; + struct bdaddr_t *remote; + struct avdtp_control_t *avdtp_ctl; + avdtp_state_t state; + uint32_t seid; + uint32 sig_handle; + uint32 med_handle; + void (*avdtp_notify_callback)(uint8 event, uint32 l2cap_channel, void *pdata, uint8 reason); + void (*avdtp_datarecv_callback)(uint32 l2cap_handle, struct pp_buff *ppb); +}; + +struct avdtp_ctx_output { + struct avdtp_control_t *avdtp_ctl; + struct avdtp_local_sep *local_sep; +}; + +//callback functions for dealing with remote response to local command +struct avdtp_sep_cfm +{ + void (*setconf)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep ); + void (*getconf)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep ); + void (*open)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep ); + void (*start)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep ); + void (*suspend)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep ); + void (*close)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep ); + void (*abort)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep ); + void (*reconf)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep ); + void (*security_control)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep , struct avdtp_media_content_protect_capability* cp); +}; +//callback functions to deal with remote command +struct avdtp_sep_ind +{ + uint8 *(*getcap)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep , uint16 *len, uint8 sig_type); + int8 (*setconf)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep , struct avdtp_config_request* cfg_req); + int8 (*open)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep); + int8 (*start)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep); + int8 (*suspend)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep); + int8 (*close)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep); + int8 (*abort)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep); + int8 (*reconf)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep, struct avdtp_config_request* cfg_req); + int8 (*security_control)(struct avdtp_control_t *avdtp_ctl,struct avdtp_local_sep *local_sep , struct avdtp_media_content_protect_capability* cp); +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +int8 avdtp_init(int8 server_channel, + void (*avdtp_notify_callback)(uint8 event, uint32 l2cap_channel, void *pdata, uint8 reason), + void (*avdtp_datarecv_callback)(uint32 l2cap_handle, struct pp_buff *ppb)); +uint32 avdtp_open_i(void *a2dp_ctl, struct bdaddr_t *remote); +int8 avdtp_close_i(struct bdaddr_t *remote); + +int8 avdtp_send_delay_report(struct avdtp_control_t * avdtp_ctl, uint16 delay_ms); + +int8 avdtp_send_security_control_req(struct avdtp_control_t *stream, uint8_t *data, uint16_t len); + +int8 avdtp_send_security_control_resp(struct avdtp_control_t *stream, + uint8_t *data, uint16_t len, uint8 error); + +struct avdtp_local_sep *avdtp_register_sep(uint8 device_id, + uint8 type, + struct avdtp_sep_ind *indi, + struct avdtp_sep_cfm *cnfm); +int8 avdtp_unregister_sep(struct avdtp_local_sep *sep); +int8 avdtp_discover(void (*discover_cb)(struct avdtp_control_t *avdtp_ctl, struct avdtp_remote_sep *),uint32_t l2csig_handle); +int8 avdtp_force_close(uint32_t l2csig_handle); +void avdtp_discover_cap(uint32_t l2csig_handle); +int8 avdtp_set_configuration(struct avdtp_control_t *avdtp_ctl, struct avdtp_remote_sep *rsep, uint8 local_sepid, uint8 *conf_data, uint16 caps_len); + +int8 avdtp_send_command_with_param(struct avdtp_control_t *avdtp_ctl, uint32 signal_id, uint8 *params, uint32 param_len); + +#define avdtp_send_command_len3(c,s) \ + avdtp_send_command_with_param(c,s,NULL,0) + +#define avdtp_open(avdtp_ctl) \ + avdtp_send_command_len3(avdtp_ctl, AVDTP_OPEN) + +#define avdtp_start(avdtp_ctl) \ + avdtp_send_command_len3(avdtp_ctl, AVDTP_START) + +#define avdtp_close(avdtp_ctl) \ + avdtp_send_command_len3(avdtp_ctl, AVDTP_CLOSE) + +#define avdtp_suspend(avdtp_ctl) \ + avdtp_send_command_len3((avdtp_ctl), AVDTP_SUSPEND) + +#define avdtp_abort(avdtp_ctl) \ + avdtp_send_command_len3((avdtp_ctl), AVDTP_ABORT) + +//int8 avdtp_discover(struct avdtp_session *session, void (*discover_cb)(struct avdtp_session *s, GSList *sep, uint8 err, void *user_data)); + +uint32 avdtp_get_signal_l2cap_handle(struct avdtp_control_t *avdtp_ctl); +uint32 avdtp_get_media_l2cap_handle(struct avdtp_control_t *avdtp_ctl); +uint32 avdtp_save_ctx(struct avdtp_control_t *avdtp_ctl, uint8_t *buf, uint32_t buf_len); +uint32 avdtp_restore_ctx(struct avdtp_ctx_input *input, struct avdtp_ctx_output *output); +void avdtp_set_synced_streaming_state(struct bdaddr_t *addr); + +void pts_send_discover_cmd(void); +void pts_send_get_capability_cmd(void); +void pts_send_set_configuration_cmd(void); +void pts_send_get_configuration_cmd(void); +void pts_send_reconfigure_cmd(void); +void pts_send_open_cmd(void); +void pts_send_close_cmd(void); +void pts_send_abort_cmd(void); +void pts_send_get_all_capability_cmd(void); +void pts_send_suspend_cmd(void); +void pts_send_start_cmd(void); + +const char *avdtp_state2str(avdtp_state_t state); +const char *avdtp_event2str(enum avdtp_event_enum event); + + +#if defined(__cplusplus) +} +#endif + +#endif /* __AVDTP_I_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/avrcp.h b/services/bt_profiles_enhanced/inc/avrcp.h new file mode 100644 index 0000000..2ae9d0a --- /dev/null +++ b/services/bt_profiles_enhanced/inc/avrcp.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __AVRCP_H__ +#define __AVRCP_H__ + +#include "btlib_type.h" +#include "avctp_i.h" + +#define AVRCP_BT_COMPANY_ID "\x00\x19\x58" + + /* Define Opcode */ +#define AVRCP_OPCODE_UNIT_INFO 0x30 +#define AVRCP_OPCODE_SUBUNIT_INFO 0x31 +#define AVRCP_OPCODE_PASS_THROUGH 0x7C +#define AVRCP_OPCODE_VENDOR_DEP 0x00 + +/* Define Command Type*/ +#define AVRCP_CTYPE_CONTROL 0x00 +#define AVRCP_CTYPE_STATUS 0x01 +#define AVRCP_CTYPE_NOTIFY 0x03 +#define AVCTP_CTYPE_GENERAL_INQUIRY 0x04 + +/* Response */ +#define AVRCP_RESPONSE_STABLE 0x0C + +/* Define PASSTHROUGH OP_ID */ +#define AVRCP_OP_ID_PLAY 0x44 +#define AVRCP_OP_ID_STOP 0x45 +#define AVRCP_OP_ID_PAUSE 0x46 +#define AVRCP_OP_ID_REC 0x47 +#define AVRCP_OP_ID_FB 0x48 +#define AVRCP_OP_ID_FF 0x49 +#define AVRCP_OP_ID_FW 0x4B +#define AVRCP_OP_ID_BW 0x4C + +#define AVRCP_OP_NEXT_GROUP 0x017E +#define AVRCP_OP_PREV_GROUP 0x027E + +#define AVRCP_BTN_PUSHED 0x00 +#define AVRCP_BTN_RELEASED 0x80 +int avrcp_notify_callback(struct avctp_control_t *avctp_ctl, uint8 event, uint32 handle, void *pdata); +void avrcp_datarecv_callback(struct avctp_control_t *avctp_ctl, uint32 handle, struct pp_buff *ppb); + +#endif /* __AVRCP_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/avrcp_i.h b/services/bt_profiles_enhanced/inc/avrcp_i.h new file mode 100644 index 0000000..5c18f3b --- /dev/null +++ b/services/bt_profiles_enhanced/inc/avrcp_i.h @@ -0,0 +1,237 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __AVRCP_I_H__ +#define __AVRCP_I_H__ + +#include "bt_co_list.h" +#include "btlib_type.h" +#include "btm_i.h" +#include "avctp_i.h" +#include "sdp.h" + +#define AVRCP_RECVDATA_BUF_SIZE 48 + +#define AVRCP_UINT_INFO_IND 0x30 +#define AVRCP_SUBUNIT_INFO_IND 0x31 +#define AVRCP_PASSTHROUGH_IND 0x7C +#define AVRCP_VENDOR_DEP_IND 0x00 + +#define AVRCP_RESP_NOT_IMPLEMENTED 0x08 +#define AVRCP_RESP_ACCEPT 0x09 +#define AVRCP_RESP_REJECT 0x0A +#define AVRCP_RESP_STABLE 0x0C +#define AVRCP_RESP_CHANGED 0x0D +#define AVRCP_RESP_INTERIM 0x0F + +#define AVRCP_OP_GET_CAPABILITIES 0x10 +#define AVRCP_OP_LIST_PLAYER_SETTING_ATTRIBS 0x11 +#define AVRCP_OP_LIST_PLAYER_SETTING_VALUES 0x12 +#define AVRCP_OP_GET_PLAYER_SETTING_VALUE 0x13 +#define AVRCP_OP_SET_PLAYER_SETTING_VALUE 0x14 +#define AVRCP_OP_GET_PLAYER_SETTING_ATTR_TEXT 0x15 +#define AVRCP_OP_GET_PLAYER_SETTING_VALUE_TEXT 0x16 +#define AVRCP_OP_INFORM_DISP_CHAR_SET 0x17 +#define AVRCP_OP_INFORM_BATT_STATUS 0x18 +#define AVRCP_OP_GET_MEDIA_INFO 0x20 +#define AVRCP_OP_GET_PLAY_STATUS 0x30 +#define AVRCP_OP_REGISTER_NOTIFY 0x31 +#define AVRCP_OP_REQUEST_CONT_RESP 0x40 +#define AVRCP_OP_ABORT_CONT_RESP 0x41 +#define AVRCP_OP_SET_ABSOLUTE_VOLUME 0x50 +#define AVRCP_OP_SET_ADDRESSED_PLAYER 0x60 +#define AVRCP_OP_SET_BROWSED_PLAYER 0x70 +#define AVRCP_OP_GET_FOLDER_ITEMS 0x71 +#define AVRCP_OP_CHANGE_PATH 0x72 +#define AVRCP_OP_GET_ITEM_ATTRIBUTES 0x73 +#define AVRCP_OP_PLAY_ITEM 0x74 +#define AVRCP_OP_SEARCH 0x80 +#define AVRCP_OP_ADD_TO_NOW_PLAYING 0x90 +#define AVRCP_OP_GENERAL_REJECT 0xA0 +#define AVRCP_OP_CUSTOM_CMD 0xF0 + +enum avrcp_role_enum { + AVRCP_MASTER, + AVRCP_SLAVE +}; +enum avrcp_event_t { +// AVRCP_TURN_ON = 1, +// AVRCP_TURN_OFF, + AVRCP_PLAY_REQ = 1, //241 + AVRCP_PAUSE_REQ, + AVRCP_STOP_REQ, + AVRCP_RECORD_REQ, + AVRCP_FORWARD_REQ, + AVRCP_BACKWARD_REQ, + AVRCP_FAST_FORWARD_START_REQ, + AVRCP_FAST_BACKWARD_START_REQ, + AVRCP_FF_FB_STOP_REQ, + AVRCP_CONN_REQ, //250 + AVRCP_DISCONN_REQ, + +// AV_C_EVNT_BEGIN, + AVRCP_CHANNEL_OPENED, + AVRCP_CHANNEL_NEW_OPEN, + AVRCP_CHANNEL_CLOSED, + AVRCP_CHANNEL_TX_HANDLED, + AVRCP_CHANNEL_RESPONSE, + AVRCP_CHANNEL_COMMAND, + AVRCP_CHANNEL_DATA_IND, + AVRCP_RESPONSE //no more than 15 +}; + + +enum avrcp_state_enum { + AVRCP_STOP, + AVRCP_STANDBY = 1, //ready + AVRCP_QUERING, + AVRCP_CONNECTING, + AVRCP_CONNECTED + // AVRCP_BUSY +}; + +enum music_state_enum { + MUSIC_NO_ACTION, + MUSIC_PLAYING, + MUSIC_PAUSE, + MUSIC_RESUME, + MUSIC_STOP +}; + +struct avrcp_control_t { + struct list_node node; + struct avctp_control_t avctp_ctl; + enum avrcp_role_enum role; + struct bdaddr_t remote; + enum avrcp_state_enum state; + uint32 handle; + uint8 op_code; + uint8 op_id; + struct avctp_frame_t pnl_cmd; + struct avctp_frame_t adv_cmd; + struct avctp_frame_t adv_rsp; + struct avctp_frame_t unitinfo_cmd; + struct avctp_frame_t subunitinfo_cmd; + uint8 pnl_cmd_buff[64]; + uint8 adv_cmd_buff[128]; + uint8 adv_rsp_buff[128]; + uint8 unitinfo_cmd_buff[64]; + uint8 is_src_playing; + uint8 is_volume_sync; + + void (*indicate) (struct avrcp_control_t *avrcp_ctl, uint8 event, void *pdata); + void (*data_cb) (struct avrcp_control_t *avrcp_ctl, struct pp_buff *ppb); + + struct sdp_request sdp_request; + uint16 remote_avctp_version; + uint16 remote_avrcp_version; + uint16 remote_support_features; + bool conn_avctp_after_sdp; +}; + +struct avrcp_advanced_cmd_pdu { + struct list_node node; + uint8 op; + U16 parm_len; + U8 *parms; + U8 trans_id; + + BOOL more; + U16 cur_len; + U16 bytes_to_send; + U8 cont_op; + BOOL abort; + + BOOL internal; + U8 response; + U8 error; + + BOOL is_cmd; + U8 ctype; /* 4 bits */ +}; + +struct avrcp_adv_cmd_rsp_cb_parms { + uint8 rsp; + uint8 subunit_type; + uint8 subunit_id; + uint8 op_code; + uint8 *origin_data; + uint8 *op_data; + uint16 op_data_len; +}; + +struct avrcp_adv_cmd_cb_parms { + uint8 ctype; + uint8 subunit_type; + uint8 subunit_id; + uint8 op_code; + uint8 *origin_data; + uint8 *op_data; + uint16 op_data_len; +}; + +struct avrcp_ctx_input { + struct ctx_content ctx; + struct bdaddr_t *remote; + struct avrcp_control_t *avrcp_ctl; +}; + +struct avrcp_ctx_output { +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +/* AVRCP APP */ +void app_callback(uint8 event, void *pdata); + +/* AVRCP */ +int8 avrcp_init_inst(struct avrcp_control_t *avrcp_ctl, void (*indicate) (struct avrcp_control_t *avrcp_ctl, uint8 event, void *pdata), + void (*datarecv_callback) (struct avrcp_control_t *avrcp_ctl, struct pp_buff *ppb)); + +enum avrcp_state_enum avrcp_getState(struct avrcp_control_t *avrcp_ctl); +void avrcp_setState(struct avrcp_control_t *avrcp_ctl, enum avrcp_state_enum state); +int8 avrcp_turnOn(struct avrcp_control_t *avrcp_ctl); +int8 avrcp_turnOff(struct avrcp_control_t *avrcp_ctl); +int8 avrcp_connectReq(struct avrcp_control_t *avrcp_ctl, struct bdaddr_t *peer); +int8 avrcp_disconnectReq(struct avrcp_control_t *avrcp_ctl); +int8 avrcp_send_cmd(struct avrcp_control_t *avrcp_ctl, int op); + +/* Used by Controller to Send Command */ +bool avrcp_is_advanced_command_can_send(struct avrcp_control_t * avrcp_ctl, bool is_cmd); +int8 avrcp_send_advanced_command(struct avrcp_control_t *avrcp_ctl, struct avrcp_advanced_cmd_pdu *pdu); +int8 avrcp_send_advanced_response(struct avrcp_control_t *avrcp_ctl, struct avrcp_advanced_cmd_pdu *pdu); +int8 avrcp_send_panel_key(struct avrcp_control_t *avrcp_ctl, uint16 op, uint8 press); +bool avrcp_is_control_channel_connected(struct avrcp_control_t *avrcp_ctl); +int8 avrcp_is_panel_cmd_can_send(struct avrcp_control_t *avrcp_ctl); +int8 avrcp_send_panel_response(struct avrcp_control_t *avrcp_ctl, uint16 op, uint8 press, uint8 response); +int8 avrcp_send_unit_info_cmd(struct avrcp_control_t *avrcp_ctl); +int8 avrcp_send_unit_info_response(struct avrcp_control_t *avrcp_ctl); +int8 avrcp_send_subunit_info_response(struct avrcp_control_t *avrcp_ctl); +void avrcp_register_panel_command_tx_handled_callback(void (*cb)(struct avrcp_control_t *avrcp_ctl, void *pdata)); + +struct avctp_control_t *avrcp_get_avctp_control(struct avrcp_control_t *avrcp_ctl); +uint16 avrcp_get_conn_handle(struct avrcp_control_t* avrcp_ctl); +uint32 avrcp_save_ctx(struct avrcp_control_t *avrcp_ctl, uint8_t *buf, uint32_t buf_len); +uint32 avrcp_restore_ctx(struct avrcp_ctx_input *input, struct avrcp_ctx_output *output); + +#if defined(__cplusplus) +} +#endif + +#endif /* __AVRCP_I_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/bes_os.h b/services/bt_profiles_enhanced/inc/bes_os.h new file mode 100644 index 0000000..612f283 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/bes_os.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include +#include + +/* all platform dependences shoule be included only here */ + +#include "cmsis_os.h" +#include "cmsis.h" +#include "plat_types.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "string.h" +#include "tgt_hardware.h" +#include "bt_drv_reg_op.h" +#include "intersyshci.h" +#include "besbt_cfg.h" +#include "osif.h" +#include "ddbif.h" +#include "btlib_type.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#define Plt_Assert ASSERT +#define Plt_TICKS_TO_MS(ticks) TICKS_TO_MS(ticks) +#define Plt_DUMP8 DUMP8 + +#define OS_CRITICAL_METHOD 0 +#define OS_ENTER_CRITICAL() uint32_t os_lock = int_lock() +#define OS_EXIT_CRITICAL() int_unlock(os_lock) +#define OSTimeDly(a) osDelay((a)*2) + + +#if defined(__cplusplus) +} +#endif \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/besaud.h b/services/bt_profiles_enhanced/inc/besaud.h new file mode 100644 index 0000000..77a6901 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/besaud.h @@ -0,0 +1,198 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __BESAUD_H__ +#define __BESAUD_H__ + +#include "bluetooth.h" +#include "bt_co_list.h" +#include "btm.h" +#include "btlib_type.h" + +#define BESAUD_PACKET_COUNT (5) + +typedef struct _BesaudCallbackParms BesaudCallbackParms; +typedef struct _BesaudChannel BesaudChannel; + +typedef struct _BesaudConn BesaudConn; +typedef struct _BesaudConnCallbackParms BesaudConnCallbackParms; + +typedef void (*BesaudConnCallback)(BesaudConn *Conn, BesaudConnCallbackParms *Parms); + +/* Connection State */ +struct _BesaudConn { + uint32 l2cap_handle; + uint8 state; + BesaudConnCallback callback; +}; + +struct _BesaudConnCallbackParms { + uint8 event; + int8 status; + uint16 dataLen; + union { + struct btm_conn_item_t *remDev; + uint8 *data; + } ptrs; +}; + +int8 BesaudDisconnect(struct btm_conn_item_t *RemDev); +BOOL BesaudIsConnected(BesaudConn *Conn); +int8 BesaudConnect(BesaudChannel *chnl, struct btm_conn_item_t *RemDev); + +typedef uint16 BesaudEvent; + +typedef struct +{ + struct list_node node; + uint8* pBuf; + uint16 pDataLength; +} BesaudPacket; + +struct _BesaudCallbackParms{ + BesaudEvent event; + + int8 status; + int8 errCode; + BesaudChannel *chnl; + union{ + struct btm_conn_item_t *remDev; + BesaudPacket Packet; + }p; +}; + +/*-------------------------------------------------------------------------- + * BESAUDChannelStates type + * + * This type enumerates the possible BESAUD channel connection + * states. + */ +typedef uint8 BesaudChannelStates; + +/* End of HfChannelStates */ + +typedef void (*BesaudCallback)(BesaudChannel *Chan, BesaudCallbackParms *Info); + + +struct _BesaudChannel{ + struct list_node node; + struct btm_conn_item_t *remDev; + BesaudCallback callback; /* Application callback*/ + BesaudConn besaudc_conn; + BesaudChannelStates state; /* Current connection state */ + uint16 flags; /* Current connection flags */ + struct list_node freeTxPacketList; + struct list_node pendingTxPacketList; + uint8 initiator; + uint8 tx_state; + BesaudPacket *curr_tx_packet; +}; + +#ifndef BESAUDC_MAX_MTU +#define BESAUDC_MAX_MTU L2CAP_MTU +#endif + + +#ifndef BESAUDI_MAX_MTU +#define BESAUDI_MAX_MTU L2CAP_MTU +#endif + + +////besaud channel state +#define BESAUD_STATE_DISCONNECTED 0 +#define BESAUD_STATE_CONN_PENDING 1 +#define BESAUD_STATE_CONN_INCOMING 2 +#define BESAUD_STATE_DISC_PENDING 3 +#define BESAUD_STATE_DISC_INCOMING 4 +#define BESAUD_STATE_CONNECTED 5 + +////channel tx state +#define BESAUD_TX_STATE_IDLE 0 +#define BESAUD_TX_STATE_IN_TX 1 + +#define BESAUD_REPORT_TYPE_INPUT 1 +#define BESAUD_REPORT_TYPE_OUTPUT 2 +#define BESAUD_REPORT_TYPE_FEATURE 3 + + + +#define BESAUD_TRANS_TYPE_HANDSHAKE 0 +#define BESAUD_TRANS_TYPE_CONTROL 1 +#define BESAUD_TRANS_TYPE_GET_REPORT 4 +#define BESAUD_TRANS_TYPE_SET_REPORT 5 +#define BESAUD_TRANS_TYPE_GET_PROTOCAL 6 +#define BESAUD_TRANS_TYPE_SET_PROTOCAL 7 +#define BESAUD_TRANS_TYPE_GET_IDLE 8 +#define BESAUD_TRANS_TYPE_SET_IDLE 9 +#define BESAUD_TRANS_TYPE_DATA 10 +#define BESAUD_TRANS_TYPE_DATAC 11 + + +#define BESAUD_HANDSHAKE_SUCCESS 0 +#define BESAUD_HANDSHAKE_NOT_READY 1 +#define BESAUD_HANDSHAKE_INVALID_REPORTID 2 +#define BESAUD_HANDSHAKE_UNSUPPORT_REQUEST 3 +#define BESAUD_HANDSHAKE_INVALID_PARAM 4 +#define BESAUD_HANDSHAKE_ERROR_UNKNOWN 0xe +#define BESAUD_HANDSHAKE_ERROR_FATAL 0xF + + +#define BESAUD_CONTROL_NOP 0 +#define BESAUD_CONTROL_HARD_RESET 1 +#define BESAUD_CONTROL_SOFT_RESET 2 +#define BESAUD_CONTROL_SUSPEND 3 +#define BESAUD_CONTROL_EXIT_SUSPEND 4 +#define BESAUD_CONTROL_VIRTUAL_CABLE_UNPLUG 5 + +#define BESAUD_CHANNEL_TYPE_INTERRUPT 0 +#define BESAUD_CHANNEL_TYPE_CONTROL 1 + + + +#define BESAUD_DATA_TXSTATE_IDLE 0 +#define BESAUD_DATA_TXSTATE_SEND 1 + + + +#define BESAUD_EVENT_CONTROL_CONNECTED 0x21 + +#define BESAUD_EVENT_CONTROL_DISCONNECTED 0x22 + +#define BESAUD_EVENT_CONTROL_DATA_IND 0x23 + +#define BESAUD_EVENT_CONTROL_DATA_SENT 0x24 + + +#define BESAUD_EVENT_CONTROL_SET_IDLE 0x30 + +#if defined(__cplusplus) +extern "C" { +#endif + +int8 BESAUD_Init(void); +int8 Besaud_Register(BesaudChannel *chnl, + BesaudCallback callback + ); +int8 Besaud_Connect(BesaudChannel *chnl, struct btm_conn_item_t *RemDev); +int8 Besaud_Disconnect(BesaudChannel *chnl); +int8 Besaud_Send_packet(BesaudChannel *chnl, char *buffer, uint16 nBytes); +int8 Besaud_Send_cmd_packet(BesaudChannel *chnl, char *buffer, uint16 nBytes); + +#if defined(__cplusplus) +} +#endif + +#endif /* __BESAUD_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/besaudalloc.h b/services/bt_profiles_enhanced/inc/besaudalloc.h new file mode 100644 index 0000000..58bbc7f --- /dev/null +++ b/services/bt_profiles_enhanced/inc/besaudalloc.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __BESAUDALLOC_H__ +#define __BESAUDALLOC_H__ + +typedef struct _BtBesaudContext { + struct list_node channelList; + uint16 besaudcpsm; +} BtBesaudContext; + +extern BtBesaudContext besaudContext; +#define BESAUD(s) (besaudContext.s) + +int8 BesaudAlloc(void); + +#endif /* __BESAUDALLOC_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/bt_co_list.h b/services/bt_profiles_enhanced/inc/bt_co_list.h new file mode 100644 index 0000000..42e4241 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/bt_co_list.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __BT_CO_LIST_H__ +#define __BT_CO_LIST_H__ + +#include "btlib_more.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ITER_WARN "list too much loop=%d!!!!" + +#if !defined(ITER_ASSERT) + +#if defined(ASSERT_SHOW_FILE_FUNC) +#define ITER_ASSERT(head) hal_trace_assert_dump(__FILE__, __FUNCTION__, __LINE__, ITER_WARN, (head)->__iter__cnt) +#elif defined(ASSERT_SHOW_FILE) +#define ITER_ASSERT(head) hal_trace_assert_dump(__FILE__, __FUNCTION__, __LINE__, ITER_WARN, (head)->__iter__cnt) +#elif defined(ASSERT_SHOW_FUNC) +#define ITER_ASSERT(head) hal_trace_assert_dump(__FUNCTION__, __LINE__, ITER_WARN, (head)->__iter__cnt) +#else +#define ITER_ASSERT(head) hal_trace_assert_dump(ITER_WARN, (head)->__iter__cnt) +#endif + +#endif /* ITER_ASSERT */ + +#if 1 +#define ITER_INIT(head) ,(head)->__iter__cnt = 0 +#define ITER_CHK(head) ,((head)->__iter__cnt>100?ITER_ASSERT((head)):(void)((head)->__iter__cnt++)) +#else +#define ITER_INIT(head) +#define ITER_CHK(head) +#endif + +#ifndef OFFSETOF +#define OFFSETOF(type, member) ((unsigned int) &((type *)0)->member) +#endif + +#ifndef CONTAINER_OF +#define CONTAINER_OF(ptr, type, member) ((type *)( (char *)ptr - OFFSETOF(type,member) )) +#endif + +struct list_node { + struct list_node *next; + struct list_node *prev; + unsigned int __iter__cnt; +}; + +#define DEF_LIST_HEAD(head) \ + struct list_node head = { &(head), &(head) } + +#define INIT_LIST_HEAD(head) do { \ + (head)->next = (head); (head)->prev = (head); \ +} while (0) + +void colist_addto_head(struct list_node *n, struct list_node *head); +void colist_addto_tail(struct list_node *n, struct list_node *head); +void colist_delete(struct list_node *entry); +void colist_moveto_head(struct list_node *list, struct list_node *head); +int colist_is_node_on_list(struct list_node *list, struct list_node *node); +struct list_node *colist_get_head(struct list_node *head); +int colist_is_list_empty(struct list_node *head); + +#define colist_structure(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) +#define colist_iterate(pos, head) \ + for (pos = (head)->next ITER_INIT((head)); pos != (head); \ + pos = pos->next ITER_CHK((head))) +#define colist_iterate_prev(pos, head) \ + for (pos = (head)->prev ITER_INIT((head)); pos != (head); \ + pos = pos->prev ITER_CHK((head)) +#define colist_iterate_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next ITER_INIT((head)); pos != (head); \ + pos = n, n = pos->next ITER_CHK((head))) +#define colist_iterate_entry(pos, type, head, member) \ + for (pos = colist_structure((head)->next, type, member) ITER_INIT((head)); \ + &pos->member != (head); \ + pos = colist_structure(pos->member.next, type, member) ITER_CHK((head))) +#define colist_iterate_entry_safe(pos, n, type, head, member) \ + for (pos = colist_structure((head)->next, type, member), \ + n = colist_structure(pos->member.next, type, member) ITER_INIT((head)); \ + &pos->member != (head); \ + pos = n, n = colist_structure(n->member.next, type, member) ITER_CHK((head))) + +#ifdef __cplusplus +} +#endif + +#endif /* __BT_CO_LIST_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/bt_common.h b/services/bt_profiles_enhanced/inc/bt_common.h new file mode 100644 index 0000000..732d6ac --- /dev/null +++ b/services/bt_profiles_enhanced/inc/bt_common.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BT_COMMON_H__ +#define __BT_COMMON_H__ + +/* This file should be included in every source code file in stack */ + +#include "bt_sys_cfg.h" // include cobt.h, cobt.h is independent header for including definations about bluetooth +#include "btlib_type.h" // global types +#include "platform_deps.h" // all platform dependence are in here +#include "debug_cfg.h" +#include "btlib.h" // some utility or helper macros, functions +#include "btlib_more.h" // some utility or helper macros, functions + +#include "debug_print.h" +#include "packer.h" +#include "cobuf.h" +#include "btm_hci.h" +#include "hci.h" + +#endif /* __BT_COMMON_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/bt_schedule.h b/services/bt_profiles_enhanced/inc/bt_schedule.h new file mode 100644 index 0000000..6417764 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/bt_schedule.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __BT_SCHEDULE__ +#define __BT_SCHEDULE__ + +#include "debug_print.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +void bt_schedule(void); + +#if defined(__cplusplus) +} +#endif + +#endif \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/bt_sys_cfg.h b/services/bt_profiles_enhanced/inc/bt_sys_cfg.h new file mode 100644 index 0000000..fe3d4dd --- /dev/null +++ b/services/bt_profiles_enhanced/inc/bt_sys_cfg.h @@ -0,0 +1,413 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __BT_SYS_CFG_H__ +#define __BT_SYS_CFG_H__ + +#include "cobt.h" + +/* for debug usage */ +#if !defined(DEBUG) +#define DEBUG 0 +#endif + +#define ESCO_ENABLE 1 + +#define ADS_IDE 0 +#define BA_GCC 1 + +#if DEBUG == 1 +#define DBG_DEBUG_PRINT_ENABLE 1 +#define DBG_COBUF_NEED_STATISTIC 1 +#else /*must NOT change the following macro*/ +#define DBG_DEBUG_PRINT_ENABLE 0 +#define DBG_COBUF_NEED_STATISTIC 0 +#endif + +#define DBG_PPBUFF_NEED_STATISTIC 1 + +/* config memory block size and count */ +#define COBUF_SIZE_N1 8 +#define COBUF_SIZE_N2 16 +#define COBUF_SIZE_N3 32 +#define COBUF_SIZE_N4 64 +#define COBUF_SIZE_N5 128 +#define COBUF_SIZE_N6 ((L2CAP_DEFAULT_MTU+3)/4*4) + +#if defined(CHIP_BEST1402) || defined(CHIP_BEST1400) +#define COBUF_NUMS_N1 32 +#define COBUF_NUMS_N2 45 +#define COBUF_NUMS_N3 39 +#define COBUF_NUMS_N4 20 +#define COBUF_NUMS_N5 10 +#define COBUF_NUMS_N6 6 +#else +#define COBUF_NUMS_N1 64 +#define COBUF_NUMS_N2 90 +#define COBUF_NUMS_N3 78 +#define COBUF_NUMS_N4 40 +#define COBUF_NUMS_N5 20 +#define COBUF_NUMS_N6 18 +#endif + +/* SCO */ +#ifdef CVSD_BYPASS +#define BTM_SYNC_CONN_AUDIO_SETTING_DEFAULT 0x0040 +#else +#define BTM_SYNC_CONN_AUDIO_SETTING_DEFAULT 0x0060 +#endif +#define BTM_SYNC_CONN_AUDIO_SETTING_IN_CODING_LINEAR 0x0000 /* Linear */ +#define BTM_SYNC_CONN_AUDIO_SETTING_IN_CODING_ULAW 0x0100 /* u-law */ +#define BTM_SYNC_CONN_AUDIO_SETTING_IN_CODING_ALAW 0x0200 /* a-law */ +#define BTM_SYNC_CONN_AUDIO_SETTING_IN_DATA_ONES 0x0000 /* 1's complement */ +#define BTM_SYNC_CONN_AUDIO_SETTING_IN_DATA_TWOS 0x0040 /* 2's complement */ +#define BTM_SYNC_CONN_AUDIO_SETTING_IN_DATA_SM 0x0080 /* Sign-Magnitude */ +#define BTM_SYNC_CONN_AUDIO_SETTING_IN_SAMPLE_8BIT 0x0000 /* 8 bit */ +#define BTM_SYNC_CONN_AUDIO_SETTING_IN_SAMPLE_16BIT 0x0020 /* 16 bit */ +#define BTM_SYNC_CONN_AUDIO_SETTING_CVSD 0x0000 /* CVSD */ +#define BTM_SYNC_CONN_AUDIO_SETTING_ULAW 0x0001 /* u-LAW */ +#define BTM_SYNC_CONN_AUDIO_SETTING_ALAW 0x0002 /* A-LAW */ +#define BTM_SYNC_CONN_AUDIO_SETTING_TRANSPNT 0x0003 /* msbc */ +#define BTM_SYNC_CONN_AUDIO_SETTING_MSBC 0x0060 + +#define BTM_SYNC_CONN_AUDIO_PARAM_SCO 1 +#define BTM_SYNC_CONN_AUDIO_PARAM_S1 2 +#define BTM_SYNC_CONN_AUDIO_PARAM_S2 3 +#define BTM_SYNC_CONN_AUDIO_PARAM_S3 4 +#define BTM_SYNC_CONN_AUDIO_PARAM_S4 5 +#define BTM_SYNC_CONN_AUDIO_PARAM_CUSTOM 6 +#define BTM_SYNC_CONN_AUDIO_PARAM_T1 7 +#define BTM_SYNC_CONN_AUDIO_PARAM_T2 8 + +#define BTM_SYNC_CONN_AUDIO_DEFAULT_PARMS BTM_SYNC_CONN_AUDIO_PARAM_S4 + +/* HFP */ +#define HFP_CMD_FLOW_CONTROL_ENABLE 1 +#define HFP_CMD_SYST_TX_TIMEOUT_VAL_MS 3000 + +#define HFP_HF_CHANNEL 7 + +#define HFP_HF_FEAT_ECNR 0x00000001 +#define HFP_HF_FEAT_3WAY 0x00000002 +#define HFP_HF_FEAT_CLI 0x00000004 +#define HFP_HF_FEAT_VR 0x00000008 +#define HFP_HF_FEAT_RVC 0x00000010 +#define HFP_HF_FEAT_ECS 0x00000020 +#define HFP_HF_FEAT_ECC 0x00000040 +#define HFP_HF_FEAT_CODEC 0x00000080 +#define HFP_HF_FEAT_HF_IND 0x00000100 +#define HFP_HF_FEAT_ESCO_S4_T2 0x00000200 + +#define HFP_HF_SDP_FEAT_MASK 0x001f +#define HFP_HF_SDP_FEAT_WBS 0x0020 + +#define HFP_AG_FEAT_3WAY 0x00000001 +#define HFP_AG_FEAT_ECNR 0x00000002 +#define HFP_AG_FEAT_VR 0x00000004 +#define HFP_AG_FEAT_INBAND 0x00000008 +#define HFP_AG_FEAT_VTAG 0x00000010 +#define HFP_AG_FEAT_REJ_CALL 0x00000020 +#define HFP_AG_FEAT_ECS 0x00000040 +#define HFP_AG_FEAT_ECC 0x00000080 +#define HFP_AG_FEAT_EXT_ERR 0x00000100 +#define HFP_AG_FEAT_CODEC 0x00000200 +#define HFP_AG_FEAT_HF_IND 0x00000400 +#define HFP_AG_FEAT_ESCO_S4_T2 0x00000800 + +#define HFP_AG_SDP_FEAT_MASK 0x001f +#define HFP_AG_SDP_FEAT_WBS 0x0020 + +#if defined(HFP_1_6_ENABLE) +#define HFP_HF_FEATURES ( \ + HFP_HF_FEAT_CLI | \ + HFP_HF_FEAT_RVC | \ + HFP_HF_FEAT_ECS | \ + HFP_HF_FEAT_ECC | \ + HFP_HF_FEAT_CODEC | \ + HFP_HF_FEAT_ECNR | \ + HFP_HF_FEAT_3WAY | \ + HFP_HF_FEAT_VR | \ + HFP_HF_FEAT_ESCO_S4_T2 \ + ) +#define HFP_HF_SDP_FEATURES ((HFP_HF_FEATURES & HFP_HF_SDP_FEAT_MASK) | HFP_HF_SDP_FEAT_WBS) + +#define HFP_AG_FEATURES ( \ + HFP_AG_FEAT_3WAY | \ + HFP_AG_FEAT_ECNR | \ + HFP_AG_FEAT_REJ_CALL | \ + HFP_AG_FEAT_ECS | \ + HFP_AG_FEAT_ECC | \ + HFP_AG_FEAT_CODEC | \ + HFP_AG_FEAT_ESCO_S4_T2 \ + ) +#define HFP_AG_SDP_FEATURES ((HFP_AG_FEATURES & HFP_AG_SDP_FEAT_MASK) | HFP_AG_SDP_FEAT_WBS) +#else +#define HFP_HF_FEATURES ( \ + HFP_HF_FEAT_CLI | \ + HFP_HF_FEAT_RVC | \ + HFP_HF_FEAT_ECS | \ + HFP_HF_FEAT_ECC \ + ) +#define HFP_HF_SDP_FEATURES (HFP_HF_FEATURES & HFP_HF_SDP_FEAT_MASK) + +#define HFP_AG_FEATURES ( \ + HFP_AG_FEAT_REJ_CALL | \ + HFP_AG_FEAT_ECS | \ + HFP_AG_FEAT_ECC | \ + ) +#define HFP_AG_SDP_FEATURES ((HFP_AG_FEATURES & HFP_AG_SDP_FEAT_MASK) | HFP_AG_SDP_FEAT_WBS) +#endif + +/* btm */ +/* +btm upper layers (l2cap,profiles) use ppb to pass incoming data. +we cannot change all usage now. +it is a bad idea for alloc ppb (only one time used in callback) for incoming data. +so to setup a fix buffer to alloc ppb inplace to avoid alloc ppb dynamicly failure. +*/ +#define HCIBUFF_STATISTIC_ENABLE 1 + +#define CFG_BTM_USE_INPLACE_BUFFER_FOR_ACL 1 +#define CFG_BTM_DISC_ACL_IN_BTM_TIMER 0 +#define CFG_BTM_DROP_TX_ACL_WHEN_DISCONNECT_PENDING 1 // meaningless when CFG_BTM_DISC_ACL_IN_BTM_TIMER=1 + +#define MAX_SDP_SOCK_NUMBER 2 +#define NUM_BT_DEVICES 2 +#define NUM_SCO_CONNS 2 +#define NUM_BLE_DEVICES 2 + +#define CFG_VOICE_SETTING_DEFAULT 0x0043 + +#if defined(__3M_PACK__) +#define CFG_HCI_ACL_DATA_SIZE 1040 +#else +#define CFG_HCI_ACL_DATA_SIZE 800 +#endif + +#define CFG_HCI_EVT_DATA_SIZE 300 +#define CFG_HCI_SCO_DATA_SIZE 180 +#define CFG_HCI_NUM_ACL_BUFFERS 6 +#define CFG_HCI_NUM_SCO_BUFFERS 6 + +#define BTM_DEVICEDB_SIZE 6 +#define BTM_PINCODE_MAX_LEN 8 /*include '\0'*/ +#define BTM_NAME_MAX_LEN 248 /*include '\0'*/ + +#define BTM_CFG_TIMEOUT_BEFORE_LOWPOWER 5 +#define BTM_INQUIRY_RESULT_UNUSED_TIMEOUT 30 /*seconds, decide the time out to destory an inquiry result structure*/ +#define BTM_DISCONN_WAITING_TIME 1 /* changed by marvin.zhu. seconds, decide the timeout be disconnect an acl link after it is not used by l2cap*/ +#define BTM_HCI_HOST_FLOW_CONTROL_ENABLE (1) +#define BTM_BLE_USE_INTERNAL_QUEUE_CACHE_ENABLE (1) /* if 1, for ble acl data, stack will use a internal queue to cache ble data, hci buff will be release imm */ +#define BTM_FC_BLE_TX_USE_BT_BUFFER_FORCE (0) +#define BTM_FC_HOST_TO_CONTROLLER_RESV_ACL_BUF_NUM (1) +#define BTM_FC_HOST_TO_CONTROLLER_CMD_BUF_NUM (24) +#define BTM_FC_HOST_TO_CONTROLLER_ACL_BUF_NUM (10) /* this value will be overide by read buffer size command reaponse, tx queue will be this value */ +#define BTM_FC_CONTROLLER_TO_HOST_ACL_BUF_NUM (CFG_HCI_NUM_ACL_BUFFERS) +#if BTM_BLE_USE_INTERNAL_QUEUE_CACHE_ENABLE==1 +#define BTM_BLE_INTERNAL_QUEUE_BUF_NUM (BTM_FC_CONTROLLER_TO_HOST_ACL_BUF_NUM) +#endif + +#if BTM_BLE_USE_INTERNAL_QUEUE_CACHE_ENABLE==1 +#if (BTM_BLE_INTERNAL_QUEUE_BUF_NUM= BTM_FC_CONTROLLER_TO_HOST_ACL_BUF_NUM" +#endif +#endif + +#define BTM_FC_CONTROLLER_TO_HOST_EVT_BUF_NUM (25) +#define BTM_FC_HOST_TO_CONTROLLER_SCO_BUF_NUM (6) +#define BTM_FC_CONTROLLER_TO_HOST_SCO_BUF_NUM (6) +#define BTM_CFG_CON_ACL_MAX (7) + +/* audio connection config */ +#define HCI_CFG_SYNC_TX_BANDWIDTH 0x00001F40 +#define HCI_CFG_SYNC_RX_BANDWIDTH 0x00001F40 +#define HCI_CFG_SYNC_MAX_LATENCY 0xffff +#define HCI_CFG_SYNC_RETX_EFFORT 0x2 +//#define HCI_CFG_SYNC_PKT_TYPE HCI_PKT_TYPE_HV3 +#if ESCO_ENABLE +#define HCI_CFG_SYNC_SCO_PKTS (PACKET_TYPE_HV1 | PACKET_TYPE_HV2 | PACKET_TYPE_HV3) +#define HCI_CFG_SYNC_PKT_TYPE (PACKET_TYPE_HV1 | PACKET_TYPE_HV2 | PACKET_TYPE_HV3 | PACKET_TYPE_EV3) +#else +#define HCI_CFG_SYNC_PKT_TYPE (PACKET_TYPE_HV1_FLAG | PACKET_TYPE_HV2_FLAG | PACKET_TYPE_HV3_FLAG) +#endif +#define HCI_CFG_INPUT_CODING INPUT_CODING_LINEAR +#define HCI_CFG_INPUT_DATA_FORMAT INPUT_DATA_FORMAT_1S +#define HCI_CFG_INPUT_SAMPLE_SIZE INPUT_SAMPLE_SIZE_8BITS +#if defined(HFP_1_6_ENABLE) +#define HCI_CFG_AIR_CODING_FORMAT AIR_CODING_FORMAT_MSBC +#else +#define HCI_CFG_AIR_CODING_FORMAT AIR_CODING_FORMAT_CVSD +#endif +#define HCI_CFG_LINEAR_PCM_BITPOS 0x00 + +#define HCI_CFG_VOICE_SETTING (HCI_CFG_INPUT_CODING& \ + HCI_CFG_INPUT_DATA_FORMAT& \ + HCI_CFG_INPUT_SAMPLE_SIZE& \ + HCI_CFG_AIR_CODING_FORMAT& \ + (HCI_CFG_LINEAR_PCM_BITPOS<<2)) + + + +#define HCI_CFG_SNIFF_MAX_INTERVAL 0x0320 +#define HCI_CFG_SNIFF_MIN_INTERVAL 0x0300 +#define HCI_CFG_SNIFF_ATTEMPT 0x08 +#define HCI_CFG_SNIFF_TIMEOUT 0x00 + +#define HCI_CFG_LINK_POLICY_LOWPOWER HCI_LP_ENABLE_ROLE_SWITCH_MASK \ + |HCI_LP_ENABLE_SNIFF_MODE_MASK + + +/* 10*1.28 seconds */ +#define HCI_CFG_INQUIRY_TIMEOUT 10 +/* unlimited */ +#define HCI_CFG_INQUIRY_RESPONSE_NUM 0 + +#define CFG_DEFAULT_PAGE_TIMEOUT 0x2000 + +#define CFG_COD_LIMITED_DISCOVERABLE_MODE 0x00002000 +#define CFG_COD_POSITIONING 0x00010000 +#define CFG_COD_NETWORKING 0x00020000 +#define CFG_COD_RENDERING 0x00040000 +#define CFG_COD_CAPTURING 0x00080000 +#define CFG_COD_OBJECT_TRANSFER 0x00100000 +#define CFG_COD_AUDIO 0x00200000 +#define CFG_COD_TELEPHONY 0x00400000 +#define CFG_COD_INFORMATION 0x00800000 +#define CFG_COD_MAJOR_MISCELLANEOUS 0x00000000 +#define CFG_COD_MAJOR_COMPUTER 0x00000100 +#define CFG_COD_MAJOR_PHONE 0x00000200 +#define CFG_COD_MAJOR_LAN_ACCESS_POINT 0x00000300 +#define CFG_COD_MAJOR_AUDIO 0x00000400 +#define CFG_COD_MAJOR_PERIPHERAL 0x00000500 +#define CFG_COD_MAJOR_IMAGING 0x00000600 +#define CFG_COD_MAJOR_UNCLASSIFIED 0x00001F00 +#define CFG_COD_MINOR_AUDIO_UNCLASSIFIED 0x00000000 +#define CFG_COD_MINOR_AUDIO_HEADSET 0x00000004 +#define CFG_COD_MINOR_AUDIO_HANDSFREE 0x00000008 +#define CFG_COD_MINOR_AUDIO_MICROPHONE 0x00000010 +#define CFG_COD_MINOR_AUDIO_LOUDSPEAKER 0x00000014 +#define CFG_COD_MINOR_AUDIO_HEADPHONES 0x00000018 +#define CFG_COD_MINOR_AUDIO_PORTABLEAUDIO 0x0000001C +#define CFG_COD_MINOR_AUDIO_CARAUDIO 0x00000020 +#define CFG_COD_MINOR_AUDIO_SETTOPBOX 0x00000024 +#define CFG_COD_MINOR_AUDIO_HIFIAUDIO 0x00000028 +#define CFG_COD_MINOR_AUDIO_VCR 0x0000002C +#define CFG_COD_MINOR_AUDIO_VIDEOCAMERA 0x00000030 +#define CFG_COD_MINOR_AUDIO_CAMCORDER 0x00000034 +#define CFG_COD_MINOR_AUDIO_VIDEOMONITOR 0x00000038 +#define CFG_COD_MINOR_AUDIO_VIDEOSPEAKER 0x0000003C +#define CFG_COD_MINOR_AUDIO_CONFERENCING 0x00000040 +#define CFG_COD_MINOR_AUDIO_GAMING 0x00000048 +#define CFG_CLASS_OF_DEVICE (CFG_COD_MAJOR_AUDIO|CFG_COD_MINOR_AUDIO_HEADSET|CFG_COD_AUDIO|CFG_COD_RENDERING) + +// Minor device class for CFG_COD_MAJOR_PERIPHERAL +#define CFG_COD_MINOR_PERIPH_KEYBOARD 0x00000040 +#define CFG_COD_MINOR_PERIPH_POINTING 0x00000080 +#define CFG_COD_MINOR_PERIPH_COMBOKEY 0x000000C0 + +#ifdef _SCO_BTPCM_CHANNEL_ +#define CFG_SYNC_CONFIG_PATH (0<<8|1<<4|1<<0) /* all links use hci */ +#else +#define CFG_SYNC_CONFIG_PATH (0<<8|0<<4|0<<0) /* all links use hci */ +#endif +#define CFG_SYNC_CONFIG_MAX_BUFFER (0) /* (e)sco use Packet size */ +#ifdef _CVSD_BYPASS_ +#define CFG_SYNC_CONFIG_CVSD_BYPASS (1) /* use pcm over hci */ +#else +#define CFG_SYNC_CONFIG_CVSD_BYPASS (0) /* use pcm over hci */ +#endif + +#define CFG_LP_SNIFF_MODE 0x0000 + +#define EDR_ENABLED 0 + +#define CFG_BT_DEFAULT_PAGE_SCAN_WINDOW 0x12 +#define CFG_BT_DEFAULT_PAGE_SCAN_INTERVAL 0x800 +#define CFG_BT_DEFAULT_INQ_SCAN_WINDOW 0x12 +#define CFG_BT_DEFAULT_INQ_SCAN_INTERVAL 0x800 + +#define CFG_INQ_TYPE 1 +#define CFG_PAGE_TYPE 1 + +/* l2cap */ +#define SSP_RECONNECT 1 +#define L2CAP_AUTH_NEED_ENCRYPTION 1/* default value in spec */ + +#if defined(__3M_PACK__) +#define L2CAP_CFG_MTU 1021 +#else +#define L2CAP_CFG_MTU 679 +#endif +#define L2CAP_DEFAULT_MTU L2CAP_CFG_MTU +#define L2CAP_MIN_MTU 48 + +#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF + +#define L2CAP_DEFAULT_QOS_SERVICE_TYPE L2CAP_QOS_BEST_EFFORT +#define L2CAP_DEFAULT_QOS_TOKEN_RATE 0x00000000 +#define L2CAP_DEFAULT_QOS_TOKEN_BUCKET_SIZE 0x00000000 +#define L2CAP_DEFAULT_QOS_PEEK_BANDWIDTH 0x00000000 +#define L2CAP_DEFAULT_QOS_LATENCY 0xffffffff +#define L2CAP_DEFAULT_QOS_DELAY_VARIATION 0xffffffff + + +#define L2CAP_DEFAULT_RFC_MODE L2CAP_MODE_BASE +#define L2CAP_DEFAULT_RFC_TXWINDOW 32 /*1 to 32*/ +#define L2CAP_DEFAULT_RFC_MAXTRANSMIT 32 +#define L2CAP_DEFAULT_RFC_RETRANSMISSION_TIMEOUT 1000 +#define L2CAP_DEFAULT_RFC_MONITOR_TIMEOUT 1000 +#define L2CAP_DEFAULT_RFC_MPS 0xFFFF + +#define L2CAP_DEFAULT_FCS_TYPE L2CAP_FCS_TYPE_16_BIT + +/* used for pp_buff */ +#define L2CAP_PPB_HEAD_RESERVE 4 /*len+cid+control+sdulen 2+2+2+2*/ +#define L2CAP_PPB_TAIL_RESERVE 0 /* fcs 2 */ +#define L2CAP_PPB_RESERVE (L2CAP_PPB_HEAD_RESERVE + L2CAP_PPB_TAIL_RESERVE) + +#define L2CAP_CFG_FLUSH_TO L2CAP_DEFAULT_FLUSH_TO + +#define L2CAP_CFG_QOS_SERVICE_TYPE L2CAP_DEFAULT_QOS_SERVICE_TYPE +#define L2CAP_CFG_QOS_TOKEN_RATE 0x00000000 +#define L2CAP_CFG_QOS_TOKEN_BUCKET_SIZE 0x00000000 +#define L2CAP_CFG_QOS_PEEK_BANDWIDTH 0x00000000 +#define L2CAP_CFG_QOS_LATENCY 0xffffffff +#define L2CAP_CFG_QOS_DELAY_VARIATION 0xffffffff + +#define L2CAP_CFG_RFC_MODE L2CAP_DEFAULT_RFC_MODE /*L2CAP_MODE_BASE*/ +/* below is only available when rfc mode is not base mode*/ +#define L2CAP_CFG_RFC_TXWINDOW 32 /*1 to 32*/ +#define L2CAP_CFG_RFC_MAXTRANSMIT 32 +#define L2CAP_CFG_RFC_RETRANSMISSION_TIMEOUT 1000 +#define L2CAP_CFG_RFC_MONITOR_TIMEOUT 1000 +#define L2CAP_CFG_RFC_MPS 0xFFFF + +/* L2CAP_RTX: The Responsive Timeout eXpired timer is used to terminate + the channel when the remote endpoint is unresponsive to signalling + requests (min 1s, max 60s) */ +#define L2CAP_CFG_RTX 60 +/* L2CAP_RTX_MAXN: Maximum number of Request retransmissions before + terminating the channel identified by the request. The decision + should be based on the flush timeout of the signalling link. If the + flush timeout is infinite, no retransmissions should be performed */ +#define L2CAP_CFG_RTX_MAXN 0 +/* L2CAP_ERTX: The Extended Response Timeout eXpired timer is used in + place of the RTC timer when a L2CAP_ConnectRspPnd event is received + (min 60s, max 300s) */ +#define L2CAP_CFG_ERTX 300 + + +#endif /* __BT_SYS_CFG_H__ */ diff --git a/services/bt_profiles_enhanced/inc/btgatt.h b/services/bt_profiles_enhanced/inc/btgatt.h new file mode 100644 index 0000000..d5e58da --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btgatt.h @@ -0,0 +1,138 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef __GATT_OVER_BR_EDR__ +#ifndef __BTGATT_H__ +#define __BTGATT_H__ +#include "cmsis_os.h" +#include "stdbool.h" +#include "bt_co_list.h" +#include "btlib_type.h" +#include "btm.h" + +#define BTGATT_PACKET_COUNT (5) + +typedef struct _BtgattCallbackParms BtgattCallbackParms; +typedef struct _BtgattChannel BtgattChannel; +typedef struct _BtgattConn BtgattConn; +typedef struct _BtgattConnCallbackParms BtgattConnCallbackParms; + +typedef void (*BtgattConnCallback)(BtgattConn *Conn, BtgattConnCallbackParms *Parms); + +/* Connection State */ +struct _BtgattConn { + uint32 l2cap_handle; + uint8 state; + BtgattConnCallback callback; +}; + +struct _BtgattConnCallbackParms { + uint8 event; + int8 status; + uint16 dataLen; + union { + struct btm_conn_item_t *remDev; + uint8 *data; + } ptrs; +}; + +typedef uint16 BtgattEvent; + +typedef struct +{ + struct list_node node; + uint8* pBuf; + uint16 pDataLength; +} BtgattPacket; + +struct _BtgattCallbackParms{ + BtgattEvent event; + + int8 status; + int8 errCode; + BtgattChannel *chnl; + union{ + struct btm_conn_item_t *remDev; + BtgattPacket Packet; + }p; +}; + +typedef struct _BtBtgattContext { + struct list_node channelList; + uint16 btgattcpsm; +} BtBtgattContext; + +/*-------------------------------------------------------------------------- + * BTGATTChannelStates type + * + * This type enumerates the possible BTGATT channel connection + * states. + */ +typedef uint8 BtgattChannelStates; + +/* End of HfChannelStates */ +typedef void (*BtgattCallback)(BtgattChannel *Chan, BtgattCallbackParms *Info); + +struct _BtgattChannel{ + struct list_node node; + struct btm_conn_item_t *remDev; + BtgattCallback callback; /* Application callback*/ + BtgattConn btgattc_conn; + BtgattChannelStates state; /* Current connection state */ + uint16 flags; /* Current connection flags */ + struct list_node freeTxPacketList; + struct list_node pendingTxPacketList; + uint8 initiator; + uint8 tx_state; + BtgattPacket *curr_tx_packet; +}; + +////btgatt channel state +#define BTGATT_STATE_DISCONNECTED 0 +#define BTGATT_STATE_CONN_PENDING 1 +#define BTGATT_STATE_CONN_INCOMING 2 +#define BTGATT_STATE_DISC_PENDING 3 +#define BTGATT_STATE_DISC_INCOMING 4 +#define BTGATT_STATE_CONNECTED 5 + +////channel tx state +#define BTGATT_TX_STATE_IDLE 0 +#define BTGATT_TX_STATE_IN_TX 1 + + +#define BTGATT_EVENT_CONTROL_CONNECTED 0x21 +#define BTGATT_EVENT_CONTROL_DISCONNECTED 0x22 +#define BTGATT_EVENT_CONTROL_DATA_IND 0x23 +#define BTGATT_EVENT_CONTROL_DATA_SENT 0x24 + +#define BTGATT(s) (btgattContext.s) + +#if defined(__cplusplus) +extern "C" { +#endif +int8 Btgatt_init(void); +int8 Btgatt_Register(BtgattChannel *chnl, BtgattCallback callback); +int8 Btgatt_Connect(BtgattChannel *chnl, struct btm_conn_item_t *RemDev); +int8 Btgatt_Disconnect(BtgattChannel *chnl); +int8 Btgatt_Send_packet(BtgattChannel *chnl, char *buffer, uint16 nBytes); +int8 Btgatt_Send_cmd_packet(BtgattChannel *chnl, char *buffer, uint16 nBytes); +bool Btgatt_Is_Connected(BtgattConn *Conn); +void Btgatt_addsdp(uint16_t pServiceUUID, uint16_t startHandle, uint16_t endHandle); +#if defined(__cplusplus) +} +#endif + +#endif /* __BTGATT_H__ */ +#endif diff --git a/services/bt_profiles_enhanced/inc/btlib.h b/services/bt_profiles_enhanced/inc/btlib.h new file mode 100644 index 0000000..3db3c63 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btlib.h @@ -0,0 +1,152 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BTLIB_H__ +#define __BTLIB_H__ + +#include "bt_common.h" +#include "hci.h" +#include "co_timer.h" +#include "btm.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +int8 btlib_send_hci_cmd(uint16 opcode, uint8 *param_data_ptr, uint8 param_len); +int8 btlib_send_acl_data( uint16 conn_handle, uint8 *data_ptr, uint16 data_len, uint8 *priv); +int8 btlib_hcicmd_acl_connect(struct bdaddr_t *bdaddr, + uint16 pkt_type, + uint8 page_scan_repetition_mode, + uint16 clk_off, + uint8 allow_role_switch); +int8 btlib_hcicmd_addsyc_conn(struct btm_conn_item_t *conn); +int8 btlib_hcicmd_addsco_conn(struct btm_conn_item_t *conn, uint16 pkt_type); +int8 btlib_hcicmd_write_scan_enable(uint8 scan_enable); +int8 btlib_hcicmd_write_current_iac_lap(uint8 num); +int8 btlib_hcicmd_reject_conn_req(struct bdaddr_t *bdaddr, uint8 reason); +int8 btlib_hcicmd_accep_conn_req(struct bdaddr_t *bdaddr, uint8 role); +int8 btlib_hcicmd_switch_role(struct bdaddr_t *bdaddr, uint8 role); +int8 btlib_hcicmd_write_page_timeout(uint16_t timeout); +int8 btlib_hcicmd_write_superv_timeout(uint16 connhandle, uint16 superv_timeout); +int8 btlib_hcicmd_create_connection_cancel(struct bdaddr_t *bdaddr); +int8 btlib_hcicmd_set_extended_inquiry_response(uint8 fec, uint8 *buff, uint32 len); +int8 btlib_hcicmd_start_tws_exchange(uint16_t tws_slave_conn_handle, uint16_t mobile_conn_handle); +int8 btlib_hcicmd_enable_lmp_filter(uint16_t conhdl, uint8_t enable); +int8 btlib_hcicmd_enable_fastack(uint16_t conhdl, uint8_t direction, uint8_t enable); +int8 btlib_hcicmd_suspend_ibrt(void); +int8 btlib_hcicmd_stop_ibrt(uint8_t enable,uint8_t reason); +int8 btlib_hcicmd_ibrt_mode_init(uint8_t enable); +int8 btlib_hcicmd_ibrt_role_switch(uint8_t switch_op); +int8 btlib_hcicmd_start_ibrt(uint16 slaveConnHandle, uint16 mobileConnHandle); +int8 btlib_hcicmd_resume_ibrt(uint8_t enable); +int8 btlib_hcicmd_set_tws_pool_interval(uint16_t conn_handle, uint16_t poll_interval); +int8 btlib_hcicmd_set_normal_sync_pos(uint8_t flag, uint8_t linkid, uint8_t normalSyncPos); +int8 btlib_hcicmd_set_connection_qos_info(void *remDev, void *qosInfo); +int8 btlib_hcicmd_set_sniffer_env(uint8 sniffer_active, uint8 sniffer_role, struct bdaddr_t *monitor_bdaddr, struct bdaddr_t *sniffer_bdaddr); +int8 btlib_hcicmd_get_slave_mobile_rssi(uint16_t conn_handle); +int8 btlib_hcicmd_set_link_lbrt_enable(uint16 conn_handle, uint8 enable); +int8 btlib_hcicmd_qos_setup(uint16 conn_handle); +int8 btlib_hcicmd_ble_write_random_addr(struct bdaddr_t *bdaddr); +int8 btlib_hcicmd_ble_write_adv_param(struct hci_write_adv_param *para); +int8 btlib_hcicmd_ble_write_adv_data(U8 len, U8 *data); +int8 btlib_hcicmd_ble_write_scan_rsp_data(U8 len, U8 *data); +int8 btlib_hcicmd_ble_write_adv_en(uint8 en); +int8 btlib_hcicmd_ble_write_scan_param(struct hci_write_ble_scan_param *para); +int8 btlib_hcicmd_ble_write_scan_en(uint8 scan_en, uint8 filter_duplicate); +int8 btlib_hcicmd_ble_clear_wl(void); +int8 btlib_hcicmd_ble_add_dev_to_wl(uint8 addr_type, struct bdaddr_t *bdaddr); +int8 btlib_hcicmd_tws_bdaddr_exchange(uint16 conn_handle); +int8 btlib_hcicmd_accept_sync_conn_req(struct bdaddr_t *bdaddr, uint32 tx_bandwidth, uint32 rx_bandwidth, uint16 max_latency, uint16 voice_setting, uint8 retx_effort, uint16 pkt_type); + +int8 btlib_hcicmd_pincode_reply(struct bdaddr_t *bdaddr, uint8 *pin, int8 pinlen); + +int8 btlib_hcicmd_pincode_neg_reply(struct bdaddr_t *bdaddr); +int8 btlib_hcicmd_linkkey_reply(struct bdaddr_t *bdaddr, uint8 *linkkey); +int8 btlib_hcicmd_linkkey_neg_reply(struct bdaddr_t *bdaddr); + +int8 btlib_hcicmd_authentication_req (uint16 conn_handle); +int8 btlib_hcicmd_write_auth_enable(uint8 flag); +int8 btlib_hcicmd_set_conn_encryption (uint16 conn_handle, uint8 encry_enable); +int8 btlib_hcicmd_disconnect (uint16 conn_handle, uint8 reason); + +int8 btlib_hcicmd_write_classofdevice (uint8 *class_de); +int8 btlib_hcicmd_write_localname (uint8 *local_name); +int8 btlib_hcicmd_set_bdaddr (uint8 *address); +int8 btlib_hcicmd_set_ble_bdaddr (const uint8 *address); +int8 btlib_hcicmd_write_memory(uint32 addr, uint32 value, uint8 bytelen); + +int8 btlib_hcicmd_sniff_mode(uint16 conn_handle, + uint16 sniff_max_interval, + uint16 sniff_min_interval, + uint16 sniff_attempt, + uint16 sniff_timeout); + +int8 btlib_hcicmd_exit_sniff_mode(uint16 conn_handle); +int8 btlib_hcicmd_bt_role_discovery(uint16 conn_handle); +int8 btlib_hcicmd_read_remote_version_info(uint16 conn_handle); +int8 btlib_hcicmd_read_remote_supported_feat(uint16 conn_handle); +int8 btlib_hcicmd_read_remote_extended_feat(uint16 conn_handle, uint8 page_n); +int8 btlib_hcicmd_write_link_policy(uint16 conn_handle, uint16 link_policy_settings); +int8 btlib_hcicmd_lowlayer_monitor(uint16 conn_handle, uint8 control_flag, uint8 report_format, uint32 data_format, uint8 report_unit); +int8 btlib_hcicmd_read_stored_linkkey(struct bdaddr_t *bdaddr, uint8 read_all_flag); +int8 btlib_hcicmd_write_stored_linkkey(struct bdaddr_t *bdaddr, uint8 *linkkey); +int8 btlib_hcicmd_delete_stored_linkkey(struct bdaddr_t *bdaddr, uint8 delete_all_flag); + +int8 btlib_hcicmd_inquiry(uint32 lap, uint8 inq_period, uint8 num_rs); +int8 btlib_hcicmd_inquiry_cancel(void); + +int8 btlib_hcicmd_remote_name_request(struct hci_cp_remote_name_request *req); +int8 btlib_hcicmd_remote_name_cancel(struct bdaddr_t *bdaddr); +int8 btlib_hcicmd_write_pagescan_type (const uint8 pagescan_type); +int8 btlib_hcicmd_write_inqscan_type (const uint8 inqscan_type); +int8 btlib_hcicmd_write_sleep_enable(uint8 sleep_en); +int8 btlib_hcicmd_write_inquiry_mode(uint8 mode); +int8 btlib_hcicmd_set_sco_switch (const uint16 sco_handle); +int8 btlib_hcicmd_dbg_sniffer_interface (const uint8 subcode, const uint16 connhandle); +int8 btlib_hcicmd_sco_tx_silence (const uint16 connhandle, const uint8 slience_on); + +extern void delay_ms(int num); +extern char *co_strncat( char *dst, const char *src, uint32 n ); +extern void *co_memcpy_reverse(void *dst, const void *src, uint32 n); +extern void *co_memcpy(void *dst, const void *src, uint32 n); +extern int co_memcmp( const void *s1, const void *s2, uint32 n ); +extern int co_strncmp( const char *s1, const char *s2, uint32 n ); +extern char *co_strncpy( char *dst, const char *src, uint32 n ); +extern char *co_strcpy( char *dst, const char *src ); +extern void *co_memset( void *s, int c, uint32 n); + +#define bdaddr_equal(addr1, addr2) \ + (co_memcmp((const void *)(addr1),(const void *)(addr2),6) == \ + 0 ? TRUE : FALSE) + +#define bdaddr_set(dest, src) \ + do { \ + memcpy((void *)(dest),(void *)(src),6); \ + } while (0); + +static inline void bdaddr_cpy(struct bdaddr_t *dst, const struct bdaddr_t *src) { + co_memcpy(dst, src, sizeof(struct bdaddr_t)); +} + +void print_bdaddr(const struct bdaddr_t *bdaddr); +int ba2str(const struct bdaddr_t *bdaddr, char *str); +int sprintf(char *buf, const char *fmt, ...); + +#if defined(__cplusplus) +} +#endif + +#endif /* __BTLIB_H__ */ diff --git a/services/bt_profiles_enhanced/inc/btlib_more.h b/services/bt_profiles_enhanced/inc/btlib_more.h new file mode 100644 index 0000000..baa0a66 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btlib_more.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __BT_LIB_MORE_H__ +#define __BT_LIB_MORE_H__ + +#include "cobuf.h" +#include "co_printf.h" +#include "btlib_type.h" + +#endif /* __BT_LIB_MORE_H__ */ diff --git a/services/bt_profiles_enhanced/inc/btlib_type.h b/services/bt_profiles_enhanced/inc/btlib_type.h new file mode 100644 index 0000000..b46257e --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btlib_type.h @@ -0,0 +1,321 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __BTLIB_TYPE_H__ +#define __BTLIB_TYPE_H__ + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef SUCCESS +#define SUCCESS 0 +#endif + +#ifndef FAILURE +#define FAILURE 1 +#endif + +#ifndef INPROGRESS +#define INPROGRESS 2 +#endif + +#ifndef L2C_DISCONNECT_ITSELF +#define L2C_DISCONNECT_ITSELF (0x5E) +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + + +typedef unsigned char BtStatus; + +#define BT_STATUS_SUCCESS 0 /* Successful and complete */ +#define BT_STATUS_FAILED 1 /* Operation failed */ +#define BT_STATUS_PENDING 2 /* Successfully started but pending */ +#define BT_STATUS_DISCONNECT 3 /* Link disconnected */ +#define BT_STATUS_NO_LINK 4 /* No Link layer Connection exists */ +#define BT_STATUS_IN_USE 5 /* Operation failed - already in use. */ +/* IrDA specific return codes */ +#define BT_STATUS_MEDIA_BUSY 6 /* IRDA: Media is busy */ +#define BT_STATUS_MEDIA_NOT_BUSY 7 /* IRDA: Media is not busy */ +#define BT_STATUS_NO_PROGRESS 8 /* IRDA: IrLAP not making progress */ +#define BT_STATUS_LINK_OK 9 /* IRDA: No progress condition cleared */ +#define BT_STATUS_SDU_OVERRUN 10 /* IRDA: Sent more data than current SDU size */ +/* Bluetooth specific return codes */ +#define BT_STATUS_BUSY 11 +#define BT_STATUS_NO_RESOURCES 12 +#define BT_STATUS_NOT_FOUND 13 +#define BT_STATUS_DEVICE_NOT_FOUND 14 +#define BT_STATUS_CONNECTION_FAILED 15 +#define BT_STATUS_TIMEOUT 16 +#define BT_STATUS_NO_CONNECTION 17 +#define BT_STATUS_INVALID_PARM 18 +#define BT_STATUS_IN_PROGRESS 19 +#define BT_STATUS_RESTRICTED 20 +#define BT_STATUS_INVALID_TYPE 21 +#define BT_STATUS_HCI_INIT_ERR 22 +#define BT_STATUS_NOT_SUPPORTED 23 +#define BT_STATUS_CONTINUE 24 +#define BT_STATUS_CANCELLED 25 + +/* The last defined status code */ +#define BT_STATUS_LAST_CODE 25 + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + + +typedef unsigned char byte; /* Unsigned 8 bit quantity */ +typedef unsigned char uint8; /* Unsigned 8 bit quantity */ +typedef unsigned char uint8_t; /* Unsigned 8 bit quantity */ +typedef signed char int8; /* Signed 8 bit quantity */ +typedef unsigned short uint16; /* Unsigned 16 bit quantity */ +typedef signed short int16; /* Signed 16 bit quantity */ +typedef unsigned int uint32; /* Unsigned 32 bit quantity */ +typedef signed int int32; /* Signed 32 bit quantity */ + +typedef unsigned char BOOLEAN; +typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ +typedef signed char INT8S; /* Signed 8 bit quantity */ +typedef unsigned short INT16U; /* Unsigned 16 bit quantity */ +typedef signed short INT16S; /* Signed 16 bit quantity */ +typedef unsigned int INT32U; /* Unsigned 32 bit quantity */ +typedef signed int INT32S; /* Signed 32 bit quantity */ +typedef float FP32; /* Single precision floating point */ +typedef double FP64; /* Double precision floating point */ + + +typedef unsigned char u8; +#if 0 +typedef signed char s8; +typedef unsigned short u16; +typedef signed short s16; +typedef unsigned int u32; +typedef signed int s32; +typedef unsigned long long u64; +typedef signed long long s64; +#endif + +typedef uint16 CNH; + + + +typedef struct { + uint8 A[6]; +} __attribute__ ((packed)) BD_ADDR; + +typedef struct{ + uint8 A[10]; +} __attribute__ ((packed)) CHANMAP; + + +typedef struct { + uint8 A[3]; +} __attribute__ ((packed)) LAP; + + +typedef struct { + uint8 A[3]; +} __attribute__ ((packed)) CLASS; + + +typedef struct { + uint8 A[16]; +} __attribute__ ((packed)) PIN_CODE; + + +typedef struct { + uint8 A[16]; +} __attribute__ ((packed)) LINK_KEY; + + +typedef struct { + uint8 A[4]; +} __attribute__ ((packed)) SRES; + + +typedef struct { + uint8 A[12]; +} __attribute__ ((packed)) ACO; + + + +typedef struct { + uint8 A[8]; +} __attribute__ ((packed)) FEATURES; + + +typedef struct { + uint8 A[14]; +} __attribute__ ((packed)) NAME_VEC; + + + +struct bdaddr_t { + uint8 addr[6]; +}__attribute__ ((packed)); + + struct class_of_device_t { + uint8 A[3]; +}__attribute__ ((packed)); + + struct link_key_t{ + uint8 A[16]; +}__attribute__ ((packed)); + +#define STR_BE32(buff,num) ( (((U8*)buff)[0] = (U8) ((num)>>24)), \ + (((U8*)buff)[1] = (U8) ((num)>>16)), \ + (((U8*)buff)[2] = (U8) ((num)>>8)), \ + (((U8*)buff)[3] = (U8) (num)) ) + +#define STR_BE16(buff,num) ( (((U8*)buff)[0] = (U8) ((num)>>8)), \ + (((U8*)buff)[1] = (U8) (num)) ) + +#define BEtoHost16(ptr) (U16)( ((U16) *((U8*)(ptr)) << 8) | \ + ((U16) *((U8*)(ptr)+1)) ) + +#define BEtoHost32(ptr) (U32)( ((U32) *((U8*)(ptr)) << 24) | \ + ((U32) *((U8*)(ptr)+1) << 16) | \ + ((U32) *((U8*)(ptr)+2) << 8) | \ + ((U32) *((U8*)(ptr)+3)) ) + +/* Store value into a buffer in Little Endian format */ +#define StoreLE16(buff,num) ( ((buff)[1] = (U8) ((num)>>8)), \ + ((buff)[0] = (U8) (num)) ) + +#define StoreLE32(buff,num) ( ((buff)[3] = (U8) ((num)>>24)), \ + ((buff)[2] = (U8) ((num)>>16)), \ + ((buff)[1] = (U8) ((num)>>8)), \ + ((buff)[0] = (U8) (num)) ) + +/* Store value into a buffer in Big Endian format */ +#define StoreBE16(buff,num) ( ((buff)[0] = (U8) ((num)>>8)), \ + ((buff)[1] = (U8) (num)) ) + +#define StoreBE32(buff,num) ( ((buff)[0] = (U8) ((num)>>24)), \ + ((buff)[1] = (U8) ((num)>>16)), \ + ((buff)[2] = (U8) ((num)>>8)), \ + ((buff)[3] = (U8) (num)) ) + + +#define LEtoHost16(ptr) (U16)(((U16) *((U8*)(ptr)+1) << 8) | \ + (U16) *((U8*)(ptr))) + +#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) +#define BDADDR_ALL (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}) +#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}}) + +#define CTX_INIT(buff) \ + POSSIBLY_UNUSED unsigned int __offset = 2; \ + POSSIBLY_UNUSED unsigned char *__buff = buff; + +#define CTX_STR_BUF(buff,len) \ + memcpy(__buff+__offset, buff, len); \ + __offset += len; + +#define CTX_LDR_BUF(buff,len) \ + memcpy(buff, __buff+__offset, len); \ + __offset += len; + +#define CTX_STR_VAL8(v) \ + __buff[__offset] = v&0xFF; \ + __offset += 1; + +#define CTX_LDR_VAL8(v) \ + v = __buff[__offset]; \ + __offset += 1; + +#define CTX_STR_VAL16(v) \ + __buff[__offset] = v&0xFF; \ + __buff[__offset+1] = (v>>8)&0xFF; \ + __offset += 2; + +#define CTX_LDR_VAL16(v) \ + v = __buff[__offset]; \ + v |= __buff[__offset+1]<<8; \ + __offset += 2; + +#define CTX_STR_VAL32(v) \ + __buff[__offset] = v&0xFF; \ + __buff[__offset+1] = (v>>8)&0xFF; \ + __buff[__offset+2] = (v>>16)&0xFF; \ + __buff[__offset+3] = (v>>24)&0xFF; \ + __offset += 4; + +#define CTX_LDR_VAL32(v) \ + v = __buff[__offset]; \ + v |= __buff[__offset+1]<<8; \ + v |= __buff[__offset+2]<<16; \ + v |= __buff[__offset+3]<<24; \ + __offset += 4; + +#define CTX_GET_BUF_CURR() __buff + +#define CTX_GET_BUF_HEAD() __buff + +#define CTX_GET_OFFSET() __offset + +#define CTX_GET_DATA_LEN() (__buff[0] | __buff[1]<<8) + +#define CTX_GET_TOTAL_LEN() (CTX_GET_DATA_LEN()+2) + +#define CTX_SAVE_UPDATE_DATA_LEN() \ + __buff[0] = (__offset-2)&0xFF; \ + __buff[1] = ((__offset-2)>>8)&0xFF; + +struct ctx_content { + uint8 *buff; + uint32 buff_len; +}; + +#endif /* __BTLIB_TYPE_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/btm.h b/services/bt_profiles_enhanced/inc/btm.h new file mode 100644 index 0000000..418f242 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btm.h @@ -0,0 +1,410 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __BTM_H__ +#define __BTM_H__ + +#include "bt_sys_cfg.h" +#include "btlib_type.h" +#include "bt_co_list.h" +#include "btm_devicedb.h" +#include "btm_security.h" +#include "btm_i.h" + +struct btm_device_mode_t +{ + enum device_mode_dis_enum discoverable; + enum device_mode_conn_enum connectable; +}; + +struct btm_inquiry_result_item_t +{ + struct list_node list; + + struct bdaddr_t remote; + + uint16 timeout_count; /*=0: disable , count down to 1: timeout happen*/ + + /* received in inquiry result */ + uint8 page_scan_repetition_mode; + uint8 page_scan_period_mode; + uint8 class_dev[3]; + uint16 clk_off; +}; + +typedef uint8 connection_role; + +#define BCR_MASTER 0x00 +#define BCR_SLAVE 0x01 +#define BCR_ANY 0x02 + +#define GAP_INVALID_CONIDX 0xFF +#define BTM_MAX_LINK_NUMS 0x02 +#define BTM_MAX_xSCO_NUMS 0x02 + +#define BTM_FEAT_3SLOT_PACKETS 0,0,0x01 +#define BTM_FEAT_5SLOT_PACKETS 0,0,0x02 +#define BTM_FEAT_ENCRYPTION 0,0,0x04 +#define BTM_FEAT_SLOT_OFFSET 0,0,0x08 +#define BTM_FEAT_TIMING_ACC 0,0,0x10 +#define BTM_FEAT_ROLE_SWITCH 0,0,0x20 +#define BTM_FEAT_HOLD_MODE 0,0,0x40 +#define BTM_FEAT_SNIFF_MODE 0,0,0x80 +#define BTM_FEAT_PWR_CTRL_REQ 0,1,0x02 +#define BTM_FEAT_CQDDR 0,1,0x04 +#define BTM_FEAT_SCO_LINK 0,1,0x08 +#define BTM_FEAT_HV2_PACKETS 0,1,0x10 +#define BTM_FEAT_HV3_PACKETS 0,1,0x20 +#define BTM_FEAT_ULAW_SYNC_DATA 0,1,0x40 +#define BTM_FEAT_ALAW_SYNC_DATA 0,1,0x80 +#define BTM_FEAT_CVSD_SYNC_DATA 0,2,0x01 +#define BTM_FEAT_PAGE_PARA_NEGO 0,2,0x02 +#define BTM_FEAT_PWR_CTRL 0,2,0x04 +#define BTM_FEAT_TRANS_SYNC_DATA 0,2,0x08 +#define BTM_FEAT_FLOW_CTRL_LST_BIT 0,2,0x10 +#define BTM_FEAT_FLOW_CTRL_MID_BIT 0,2,0x20 +#define BTM_FEAT_FLOW_CTRL_MST_BIT 0,2,0x40 +#define BTM_FEAT_BROADCAST_ENCRYT 0,2,0x80 +#define BTM_FEAT_EDR_2M_MODE 0,3,0x02 +#define BTM_FEAT_EDR_3M_MODE 0,3,0x04 +#define BTM_FEAT_ENHANCED_ISCAN 0,3,0x08 +#define BTM_FEAT_INTERLACED_ISCAN 0,3,0x10 +#define BTM_FEAT_INTERLACED_PSCAN 0,3,0x20 +#define BTM_FEAT_RSSI_WITH_INQRES 0,3,0x40 +#define BTM_FEAT_ESCO_LINK 0,3,0x80 +#define BTM_FEAT_EV4_PACKETS 0,4,0x01 +#define BTM_FEAT_EV5_PACKETS 0,4,0x02 +#define BTM_FEAT_AFH_CAPAB_SLAVE 0,4,0x08 +#define BTM_FEAT_AFH_CLASS_SLAVE 0,4,0x10 +#define BTM_FEAT_BREDR_NOT_SUPP 0,4,0x20 +#define BTM_FEAT_LE_CTRL_SUPP 0,4,0x40 +#define BTM_FEAT_3SLOT_EDR_ACL 0,4,0x80 +#define BTM_FEAT_5SLOT_EDR_ACL 0,5,0x01 +#define BTM_FEAT_SNIFF_SUBRATING 0,5,0x02 +#define BTM_FEAT_PAUSE_ENCRYPT 0,5,0x04 +#define BTM_FEAT_AFH_CAPAB_MASTER 0,5,0x08 +#define BTM_FEAT_AFH_CLASS_MASTER 0,5,0x10 +#define BTM_FEAT_EDR_ESCO_2M_MODE 0,5,0x20 +#define BTM_FEAT_EDR_ESCO_3M_MODE 0,5,0x40 +#define BTM_FEAT_3SLOT_EDR_ESCO 0,5,0x80 +#define BTM_FEAT_EXTENDED_INQRES 0,6,0x01 +#define BTM_FEAT_SIMU_LE_BREDR_CTRL 0,6,0x02 +#define BTM_FEAT_SECURE_SIMPLE_PAIR 0,6,0x08 +#define BTM_FEAT_ENCAPSULATED_PDU 0,6,0x10 +#define BTM_FEAT_ERR_DATA_REPORT 0,6,0x20 +#define BTM_FEAT_NONFLUSH_PBF 0,6,0x40 +#define BTM_FEAT_LINKSUPTO_CHANGE 0,7,0x01 +#define BTM_FEAT_INQ_TX_PWR_LEVEL 0,7,0x02 +#define BTM_FEAT_ENHANCED_PWR_CTRL 0,7,0x04 +#define BTM_FEAT_EXTENDED_FEATURES 0,7,0x80 +#define BTM_FEAT_SSP_HOST_SUPP 1,0,0x01 +#define BTM_FEAT_LE_HOST_SUPP 1,0,0x02 +#define BTM_FEAT_SIMU_LE_BREDR_HOST 1,0,0x04 +#define BTM_FEAT_SEC_CONN_HOST_SUPP 1,0,0x08 +#define BTM_FEAT_SLAVE_BROAD_MSTOP 2,0,0x01 +#define BTM_FEAT_SLAVE_BROAD_SLVOP 2,0,0x02 +#define BTM_FEAT_SYNCHRON_TRAIN 2,0,0x04 +#define BTM_FEAT_SYNCHRON_SCAN 2,0,0x08 +#define BTM_FEAT_INQRES_NOTIFY 2,0,0x10 +#define BTM_FEAT_GENERAL_INTERSCAN 2,0,0x20 +#define BTM_FEAT_COARSE_CLOCK_ADJ 2,0,0x40 +#define BTM_FEAT_SEC_CONN_CTRL_SUPP 2,1,0x01 +#define BTM_FEAT_PING 2,1,0x02 +#define BTM_FEAT_TRAIN_NUDGING 2,1,0x08 +#define BTM_FEAT_SLOT_AVAIL_MASK 2,1,0x10 + +#define BTM_MAX_FEATURE_PAGE (3) + +struct btm_feature_t +{ + uint8 max_page; + uint8 feature[8]; +}; + +#define BTM_AUTH_WAIT_CMPL 0x01 +#define BTM_AUTH_WAIT_MSS 0x02 +#define REMOTE_VERSION_LEN 5 + +struct btm_conn_item_t +{ + struct list_node list; + struct list_node sco_conn_list; + struct pp_buff_head tx_queue; + struct pp_buff * ppb_recv; + + struct bdaddr_t remote; + void *cmgr_handler; + uint16 conn_handle; + + uint8 used; + /*1: positive connet to the remote or 0: negtive be connected*/ + uint8 positive; + + /* received in inquiry result */ + uint8 page_scan_repetition_mode; + uint16 clk_off; + +#if CFG_BTM_DISC_ACL_IN_BTM_TIMER==1 + uint8 disconn_flag; /*if this is need to disconn*/ + uint8 disconn_count; /*to undercount to disconn*/ +#endif + uint8 discReason_saved; + uint8 discReason; + uint8 lowpower_flag; /*if is lowpower. decided to buffer tx data*/ + uint8 lowpower_count; /*to count when to enter lowpower*/ + uint8 sniff_count; /*to count how many sniff req sent*/ + uint8 role_switch_pending; + uint8 authen_enable_flag; + uint8 authen_pending; + uint8 encry_enable_flag;/*tell if the entryption is enabled in this acl conn*/ + uint8 encry_need_flag;/*tell if the entryption is need*/ + connection_role role; + uint8 state; + uint8 mode; + uint8 authState; + uint8 io_cap; + uint8 oob_present; + uint8 authen_requirement; + uint8 conn_dev_idx; + uint16 rx_complete_count; /* Host HCI RX packets complete number, controller to host flow control */ + uint8 remote_version[5]; + struct btm_feature_t remote_feature[BTM_MAX_FEATURE_PAGE]; +#if (BTM_HCI_HOST_FLOW_CONTROL_ENABLE == 1) + uint8 fc_bt_tx_acl_unconfirmed; +#endif +#if (CFG_BTM_USE_INPLACE_BUFFER_FOR_ACL==1) + uint8 *btm_acl_inplace_buff; +#endif +}; + +#define IS_REMOTE_FEAT_SUPPORT(conn, FEAT_MASK) \ + btm_is_remote_feature_support(conn, FEAT_MASK) + +struct btm_sco_conn_item_t +{ + struct list_node list; + struct btm_conn_item_t *conn; /*acl connection*/ + uint16 conn_handle; + uint8 link_type; /* HCI_LINK_TYPE_ESCO or HCI_LINK_TYPE_SCO */ + enum conn_sco_stat_enum status; + connection_role role; + uint8 index; + uint8 used; +}; + +enum btm_stack_state { + BTM_STACK_Initializing = 0, + BTM_STACK_Ready = 1, +}; + +enum btm_stack_init_sub_state { + BTM_INIT_ST_RESET = 0, + BTM_INIT_ST_SET_VOICE_SETTTING, + BTM_INIT_ST_READ_BUFFER_SIZE, + BTM_INIT_ST_LE_READ_BUFFER_SIZE, + BTM_INIT_ST_HOST_BUFFER_SIZE, + BTM_INIT_ST_SET_HCITOHOST_FLOW_CONTROL, + BTM_INIT_ST_WRITE_PAGE_TIEMOUT, + BTM_INIT_ST_READ_PAGE_TIMEOUT, + BTM_INIT_ST_SET_BLE_ADDRESS, + BTM_INIT_ST_SET_BD_ADDRESS, + BTM_INIT_ST_SET_EVENT_MASK, + BTM_INIT_ST_SET_BLE_EVENT_MASK, + BTM_INIT_ST_READ_LOCAL_VER_INFO, + BTM_INIT_ST_READ_LOCAL_SUP_COMMANDS, + BTM_INIT_ST_READ_LOCAL_FEATURES, + BTM_INIT_ST_READ_LOCAL_EXT_FEATURES, + BTM_INIT_ST_READ_LOCAL_EXT_FEATURES_1, + BTM_INIT_ST_READ_LOCAL_EXT_FEATURES_2, + BTM_INIT_ST_READ_BD_ADDRESS, + BTM_INIT_ST_READ_INQUIRY_MODE, + BTM_INIT_ST_READ_DEF_ERR_DATA_REPORTING, + BTM_INIT_ST_WRITE_SAMPLE_PAIRING_MODE, + BTM_INIT_ST_WRITE_CLASS_OF_DEVICE, + BTM_INIT_ST_WRITE_LOCAL_NAME, + BTM_INIT_ST_WRITE_SYNC_CONFIG, + BTM_INIT_ST_WRITE_DEF_ERR_DATA_REPORTING, + BTM_INIT_ST_WRITE_DEFAULT_LP_SETTINGS, + BTM_INIT_ST_WRITE_PAGESCAN_ACTIVITY, + BTM_INIT_ST_WRITE_INQUIRYSCAN_ACTIVITY, + BTM_INIT_ST_WRITE_INQUIRYSCAN_TYPE, + BTM_INIT_ST_WRITE_PAGESCAN_TYPE, + + BTM_INIT_ST_NUM, +}; + +struct btm_sync_conn_param { + uint16 max_latency; + uint16 packet_type; + uint16 voice_setting; + uint8 retrans_effort; + uint32 receive_bandwidth; + uint32 transmit_bandwidth; +}; + +struct btm_ctrl_t { + enum btm_stack_state stack_state; + enum btm_stack_init_sub_state init_sub_state; + uint16 init_sub_state_opcode; + uint8 pairing_flag; /*tell whether the device in pairing state, 1:yes, 0:no*/ + uint32 pairing_timeout; + void (*btm_pairing_notify_callback)(enum btm_pairing_event event,void *pdata); + uint8 security_waitfor_linkkey_reply; + struct bdaddr_t security_waitfor_linkkey_reply_bdaddr; + + // local + uint8 bt_version; + uint8 bt_features[8]; + uint8 bt_ext_features[2][8]; + + // esco + uint8 sco_param_select; + uint8 sco_default_param_select; + struct btm_sync_conn_param sco_custom_param; + + // security + uint8 security_bonding_mode; + uint8 security_auth_requirements; + uint8 security_io_capability; + uint8 security_oob_present; + +#if (BTM_HCI_HOST_FLOW_CONTROL_ENABLE == 1) + uint16 fc_bt_tx_cmd_left; + uint8 fc_bt_tx_acl_left; + uint8 fc_bt_tx_acl_total; + uint8 fc_bt_rx_acl_left; + +#ifdef __IAG_BLE_INCLUDE__ + uint8 fc_ble_tx_acl_left; + uint8 fc_ble_tx_acl_total; + uint8 fc_ble_share_bt_tx_packet; + uint8 bleAclRxPacketsLeft; + uint8 bleFlags; +#endif + +#endif /* BTM_HCI_HOST_FLOW_CONTROL_ENABLE */ + void (*btm_event_report)(uint16 evt_id, void* pdata); + void (*btm_cmgr_event_report)(uint16 evt_id, void* conn); + bool conn_req_cb_enable; + uint8 con_num; + + uint8 sync_cmd_busy; + hci_buff_t *sync_cmd_curr; +}; + +#define BTM(x) btm_ctrl.x + +struct btm_conn_env_t { + struct btm_conn_item_t *conn_item; +}; + +struct btm_pts_ctrl_t{ + uint8_t pts_mode ; + uint8_t pts_accept ; +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +extern struct btm_pts_ctrl_t btm_pts_ctrl; +extern struct btm_ctrl_t btm_ctrl; +struct btm_inquiry_result_item_t *btm_inquiry_result_search ( struct bdaddr_t *bdaddr ); +struct btm_inquiry_result_item_t *btm_inquiry_result_find_or_add ( struct bdaddr_t *bdaddr ); +struct btm_conn_item_t *btm_conn_add_new ( struct bdaddr_t *bdaddr ); +struct btm_conn_item_t *btm_conn_search ( struct bdaddr_t *bdaddr ); +uint16 btm_conn_find_scohdl_by_connhdl(uint16 conn_handle); +struct btm_conn_item_t *btm_conn_search_linkup ( struct bdaddr_t *bdaddr ); +struct btm_conn_item_t *btm_conn_find_or_add ( struct bdaddr_t *bdaddr ); +struct btm_sco_conn_item_t *btm_conn_sco_find_or_add( struct btm_conn_item_t *conn); +struct btm_conn_item_t *btm_conn_acl_search_by_handle( uint16 conn_handle); +struct btm_sco_conn_item_t *btm_conn_sco_search_by_handle( uint16 conn_handle); +bool btm_is_remote_feature_support(struct btm_conn_item_t* conn, uint8 page, uint8 i, uint8 mask); +void btm_conn_disconnect_process(uint16 handle, uint8 status, uint8 reason); +int8 btlib_hcicmd_read_remote_name(struct bdaddr_t *bdaddr, uint8 page_scan_repetition_mode, uint16 clk_off); +void btm_sco_conn_status_notify (struct bdaddr_t *remote_bdaddr, enum conn_sco_stat_enum sco_conn_notify_type); +void btm_conn_acl_process_tx(struct btm_conn_item_t *conn); +int8 btm_conn_acl_send_ppb_done(uint16 conn_handle, struct pp_buff *ppb); +void btm_register_event_report( void (*evt_cb)(uint16 evt_id, void *pdata)); +void btm_register_cmgr_event_report(void (*evt_cb)(uint16 evt_id, void* conn)); +extern uint8 gapc_get_conidx(uint16 conhdl); +extern void gapc_inc_rx_packet_count(uint8 idx,uint8 inc_count); +extern uint8 gapc_get_rx_packet_counnt(uint8 idx); +extern uint8 gapc_get_conn_handle(uint8 idx); +extern void gapc_rx_packet_count_reset(uint8 idx); +bool btm_conn_need_authentication(struct btm_conn_item_t *conn); +uint8 btm_conn_allocate_dev_idx(void); +void btm_conn_free_dev_idx(uint8 idx); +void btm_conn_set_item_by_idx(struct btm_conn_item_t *p_conn_item, uint8 dev_idx); +struct l2cap_conn *l2cap_conn_search(struct bdaddr_t *bdaddr); +struct l2cap_conn *l2cap_conn_add_new(struct bdaddr_t *bdaddr); +struct bdaddr_t *btm_get_address_from_rem_dev(struct btm_conn_item_t *rem_dev); +struct btm_conn_item_t * btm_conn_get_item_by_idx(uint8 dev_idx); +uint8 btm_get_bt_version(void); +uint8 btm_get_bt_features(uint8 index); +void btm_print_statistic(void); +void btm_conn_delete_free(struct btm_conn_item_t *conn); +struct btm_sco_conn_item_t *btm_conn_sco_find( struct btm_conn_item_t *conn); +struct btm_sco_conn_item_t *btm_sco_malloc_add( struct btm_conn_item_t *conn); +void btm_sco_delete_free(struct btm_sco_conn_item_t *sco); +int8 btm_get_pending_hci_cmd(uint16 opcode, struct hci_cmd_packet **cmd); +bool btm_acl_role_switch_pending(uint16_t conn_handle); + +#if (CFG_BTM_USE_INPLACE_BUFFER_FOR_ACL==1) +void btm_inplacebuff_init(void); +#endif +#if (BTM_HCI_HOST_FLOW_CONTROL_ENABLE == 1) +void btm_fc_init(void); +// bt : host to controller +void btm_fc_bt_host_to_controller_cmd_tx_left_update(uint16 v); +void btm_fc_bt_host_to_controller_cmd_tx_left_dec(uint8 v); +int8 btm_fc_bt_host_to_controller_cmd_can_send(void); +void btm_fc_bt_host_to_controller_acl_unconfirmed_inc(uint16 handle, uint8 v); +void btm_fc_bt_host_to_controller_acl_unconfirmed_dec(uint16 handle, uint8 v); +void btm_fc_bt_host_to_controller_acl_counter_inc(uint8 v); +void btm_fc_bt_host_to_controller_acl_counter_dec(uint8 v); +int8 btm_fc_bt_host_to_controller_can_send(void); +int8 btm_fc_bt_hci_buff_list_pop(uint8 type, hci_buff_t **buff); +#if defined(__IAG_BLE_INCLUDE__) +void bleUpdateFlowControl(uint16 handle); +void BleHciSendCompletedPackets(BOOL TimerFired, BOOL isForceSend); +bool bridge_get_ble_handle(uint16 connHandle); +BOOL btm_ble_conn_is_up(uint16 handle); +// bt : host to controller +void btm_fc_ble_host_to_controller_acl_unconfirmed_inc(uint16 handle, uint8 v); +void btm_fc_ble_host_to_controller_acl_unconfirmed_dec(uint16 handle, uint8 v); +void btm_fc_ble_host_to_controller_acl_counter_inc(uint8 v); +void btm_fc_ble_host_to_controller_acl_counter_dec(uint8 v); +int8 btm_fc_ble_host_to_controller_can_send(void); +void btm_fc_ble_host_to_controller_flow_check(void); +#endif /* __IAG_BLE_INCLUDE__ */ +// bt : controller to host +void btm_fc_bt_controller_to_host_acl_counter_inc(uint8 v); +void btm_fc_bt_controller_to_host_acl_counter_dec(uint8 v); +void btm_fc_bt_update_host_num_complete_pkts(uint16 handle, uint8 inc, bool right_now); +void btm_fc_bt_send_host_num_completed_pkts(void *arg); +void btm_fc_print_statistic(void); + +#endif /* BTM_HCI_HOST_FLOW_CONTROL_ENABLE */ +uint8_t btm_sco_conn_count(); +uint8_t btm_get_sco_max_number(); +void btm_set_sco_max_number(uint8_t num); +#ifdef __cplusplus +} +#endif + +#endif /* __BTM_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/btm_devicedb.h b/services/bt_profiles_enhanced/inc/btm_devicedb.h new file mode 100644 index 0000000..a623883 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btm_devicedb.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __BTM_DEVICEDB_H__ +#define __BTM_DEVICEDB_H__ + +#include "btlib_type.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +int8 btm_devicedb_get_latest_device ( struct bdaddr_t *bdaddr ); +int8 btm_devicedb_save_latest_device (struct bdaddr_t *bdaddr ); +int8 btm_devicedb_save_latest_device_profile (struct bdaddr_t *bdaddr, uint8* profile); + +#if defined(__cplusplus) +} +#endif + +#endif /* __BTM_DEVICEDB_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/btm_fast_init.h b/services/bt_profiles_enhanced/inc/btm_fast_init.h new file mode 100644 index 0000000..94b661e --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btm_fast_init.h @@ -0,0 +1,15 @@ +#ifndef __BTM_FAST_INIT__ +#define __BTM_FAST_INIT__ +#include +#include "btlib_type.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +void btm_fast_init(uint8_t* bt_addr, uint8_t* ble_addr); + +#ifdef __cplusplus +} +#endif +#endif//__BTM_FAST_INIT__ diff --git a/services/bt_profiles_enhanced/inc/btm_handle_hcievent.h b/services/bt_profiles_enhanced/inc/btm_handle_hcievent.h new file mode 100644 index 0000000..0e7a328 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btm_handle_hcievent.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __BTM_HANDLE_HCIEVENT_H__ +#define __BTM_HANDLE_HCIEVENT_H__ + +#include "btlib.h" +#include "btm_hci.h" +typedef bool (*ibrt_io_capbility_callback)(void *bdaddr); + +void btm_event_handle(uint8 *param, uint8 *priv, uint8 *donot_free); +void btm_ble_acl_handle(uint16 conn_handle, uint8 *data_p, uint16 data_len, uint8 *priv, uint8 *donot_free); +void btm_acl_handle(uint16 conn_handle, uint8 *data_p, uint16 data_len, uint8 *priv, uint8 *donot_free); +void btm_sco_handle(uint16 conn_handle, uint8 *data_p, uint16 data_len, uint8 *priv, uint8 *donot_free); +void btm_process_conn_complete_evt(struct hci_evt_packet_t *pkt); +//void btm_process_conn_req_evt(struct hci_evt_packet_t *pkt); +int8 btm_create_acl_connection_fail_process(struct btm_conn_item_t *conn, uint8 status, struct bdaddr_t *bdaddr); + +void btm_process_pin_code_req_evt(struct hci_evt_packet_t *pkt); +void btm_process_link_key_req_evt(struct hci_evt_packet_t *pkt); +void btm_process_link_key_notify_evt(struct hci_evt_packet_t *pkt); +void btm_process_authentication_complete_evt(struct hci_evt_packet_t *pkt); +void btm_process_simple_pairing_complete_evt(struct hci_evt_packet_t *pkt); +void btm_process_encryption_change_evt(struct hci_evt_packet_t *pkt); +void btm_process_remote_name_req_complete_evt(struct hci_evt_packet_t *pkt); +void btm_process_inquiry_complete_evt(struct hci_evt_packet_t *pkt); +void btm_process_inquiry_result_evt(struct hci_evt_packet_t *pkt, uint8 rssi, uint8 extinq); +void btm_process_mode_change_evt(struct hci_evt_packet_t *pkt); +void btm_process_acl_data_active_evt(void *conn, uint16_t len); +void btm_process_acl_data_not_active_evt(void *conn, uint16_t len); +void btm_process_num_of_complete_evt(struct hci_evt_packet_t *pkt); +void btm_process_read_remote_version_complete_evt(struct hci_evt_packet_t *pkt); +void btm_process_read_remote_supported_feature_complete_evt(struct hci_evt_packet_t *pkt); +void btm_process_read_remote_extended_feature_complete_evt(struct hci_evt_packet_t *pkt); +void btm_process_cmd_complete_inquiry_cancel (uint8 *data); +void btm_process_cmd_complete_remote_name_cancel(uint8 *data); +void btm_process_cmd_complete_evt(struct hci_evt_packet_t *pkt); +void btm_process_cmd_complete_read_buffer_size(uint8 *data); +void btm_process_return_linkkeys_evt (struct hci_evt_packet_t *pkt); +void btm_acl_handle_nocopy(uint16 conn_handle, uint16 data_len, uint8 *data_p); +extern void hcile_acl_rx_data_received(uint16 conn_handle, uint16 data_len, uint8 *data_p); +extern int hci_no_operation_cmd_cmp_evt_handler(uint16_t opcode, void const *param); +extern uint8_t hcile_evt_received(uint8_t code, uint8_t length, uint8 *data_p); +void btm_process_vendor_evt(struct hci_evt_packet_t *pkt); + +#endif /* __BTM_HANDLE_HCIEVENT_H__ */ diff --git a/services/bt_profiles_enhanced/inc/btm_hci.h b/services/bt_profiles_enhanced/inc/btm_hci.h new file mode 100644 index 0000000..56b6c4e --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btm_hci.h @@ -0,0 +1,551 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __BTM_HCI_H__ +#define __BTM_HCI_H__ + +#include "bt_sys_cfg.h" +#include "string.h" + +/* HCI Error Codes */ +#define HCI_STATUS_OK 0x00 +#define HCI_ERR_UNKNOWN_HCI_CMD 0x01 +#define HCI_ERR_NO_CONNECTION 0x02 +#define HCI_ERR_HARDWARE_FAILURE 0x03 +#define HCI_ERR_PAGE_TIMEOUT 0x04 +#define HCI_ERR_AUTH_FAILURE 0x05 +#define HCI_ERR_KEY_MISSING 0x06 +#define HCI_ERR_MEMORY_FULL 0x07 +#define HCI_ERR_CONN_TIMEOUT 0x08 +#define HCI_ERR_MAX_NUM_CONNS 0x09 +#define HCI_ERR_MAX_SCO_CONNS 0x0A +#define HCI_ERR_ACL_ALREADY_EXISTS 0x0B +#define HCI_ERR_CMD_DISALLOWED 0x0C +#define HCI_ERR_HOST_REJ_NO_RESOURCES 0x0D +#define HCI_ERR_HOST_REJ_SECURITY 0x0E +#define HCI_ERR_HOST_REJ_PERSONAL_DEV 0x0F +#define HCI_ERR_HOST_TIMEOUT 0x10 +#define HCI_ERR_UNSUPP_FEATUR_PARM_VAL 0x11 +#define HCI_ERR_INVAL_HCI_PARM_VAL 0x12 +#define HCI_ERR_CONN_TERM_USER_REQ 0x13 +#define HCI_ERR_CONN_TERM_LOW_RESOURCES 0x14 +#define HCI_ERR_CONN_TERM_POWER_OFF 0x15 +#define HCI_ERR_CONN_TERM_LOCAL_HOST 0x16 +#define HCI_ERR_REPEATED_ATTEMPTS 0x17 +#define HCI_ERR_PAIRING_DISALLOWED 0x18 +#define HCI_ERR_UNKNOWN_LMP_PDU 0x19 +#define HCI_ERR_UNSUPP_REMOTE_FEATURE 0x1A +#define HCI_ERR_SCO_OFFSET_REJECTED 0x1B +#define HCI_ERR_SCO_INTERVAL_REJECTED 0x1C +#define HCI_ERR_SCO_AIR_MODE_REJECTED 0x1D +#define HCI_ERR_INVALID_LMP_PARM 0x1E +#define HCI_ERR_UNSPECIFIED_ERROR 0x1F +#define HCI_ERR_UNSUPP_LMP_PARM 0x20 +#define HCI_ERR_ROLE_CHANGE_DISALLOWED 0x21 +#define HCI_ERR_LMP_RESPONSE_TIMEDOUT 0x22 +#define HCI_ERR_LMP_ERR_TRANSACT_COLL 0x23 +#define HCI_ERR_LMP_PDU_DISALLOWED 0x24 +#define HCI_ERR_ENCRYPTN_MODE_UNACCEPT 0x25 +#define HCI_ERR_UNIT_KEY_USED 0x26 +#define HCI_ERR_QOS_NOT_SUPPORTED 0x27 +#define HCI_ERR_INSTANT_PASSED 0x28 +#define HCI_ERR_PAIRING_W_UNIT_KEY_UNSUPP 0x29 +#define HCI_ERR_DIFFERENT_TRANSACTION_COLLISION 0x2A +#define HCI_ERR_INSUFF_RESOURCES_FOR_SCATTER_MODE 0x2B +#define HCI_ERR_QOS_UNACCEPTABLE_PARAMETER 0x2C +#define HCI_ERR_QOS_REJECTED 0x2D +#define HCI_ERR_CHANNEL_CLASSIF_NOT_SUPPORTED 0x2E +#define HCI_ERR_INSUFFICIENT_SECURITY 0x2F +#define HCI_ERR_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30 +#define HCI_ERR_SCATTER_MODE_NO_LONGER_REQUIRED 0x31 +#define HCI_ERR_ROLE_SWITCH_PENDING 0x32 +#define HCI_ERR_SCATTER_MODE_PARM_CHNG_PENDING 0x33 +#define HCI_ERR_RESERVED_SLOT_VIOLATION 0x34 +#define HCI_ERR_SWITCH_FAILED 0x35 +#define HCI_ERR_EXTENDED_INQ_RESP_TOO_LARGE 0x36 +#define HCI_ERR_SECURE_SIMPLE_PAIR_NOT_SUPPORTED 0x37 +#define HCI_ERR_HOST_BUSY_PAIRING 0x38 + +/* voice setting*/ +#define INPUT_CODING_LINEAR 0x0000 +#define INPUT_CODING_ULAW 0x0100 +#define INPUT_CODING_ALAW 0x0200 +#define INPUT_DATA_FORMAT_1S 0x0000 +#define INPUT_DATA_FORMAT_2S 0x0040 +#define INPUT_DATA_FORMAT_SIGN 0x0080 +#define INPUT_DATA_FORMAT_UNSIGN 0x00C0 +#define INPUT_SAMPLE_SIZE_8BITS 0x0000 +#define INPUT_SAMPLE_SIZE_16BITS 0x0020 +#define AIR_CODING_FORMAT_CVSD 0x0000 +#define AIR_CODING_FORMAT_ULAW 0x0001 +#define AIR_CODING_FORMAT_ALAW 0x0002 +#define AIR_CODING_FORMAT_TRANSPARENT 0x0003 +#define AIR_CODING_FORMAT_MSBC 0x0060 + + +/* ACL */ +#define HCI_PKT_TYPE_DM1 0x0008 +#define HCI_PKT_TYPE_DH1 0x0010 +#define HCI_PKT_TYPE_DM3 0x0400 +#define HCI_PKT_TYPE_DH3 0x0800 +#define HCI_PKT_TYPE_DM5 0x4000 +#define HCI_PKT_TYPE_DH5 0x8000 +#define HCI_PKT_TYPE_ACL 0xcc18 + +/* sco esco */ +#define HCI_PKT_TYPE_HV1 0x0001 +#define HCI_PKT_TYPE_HV2 0x0002 +#define HCI_PKT_TYPE_HV3 0x0004 +#define HCI_PKT_TYPE_EV3 0x0008 +#define HCI_PKT_TYPE_EV4 0x0010 +#define HCI_PKT_TYPE_EV5 0x0020 +#define HCI_PKT_TYPE_2EV3 0x0040 +#define HCI_PKT_TYPE_3EV3 0x0080 +#define HCI_PKT_TYPE_2EV5 0x0100 +#define HCI_PKT_TYPE_3EV5 0x0200 +#define HCI_PKT_TYPE_SCO 0x003f + + +#define HCI_HANDLE_MASK 0x0FFF +#define HCI_FLAG_PB_MASK 0x3000 +#define HCI_FLAG_BROADCAST_MASK 0xC000 + + + +#define BROADCAST_NONE 0x0000 +#define BROADCAST_ACTIVE 0x4000 +#define BROADCAST_PARKED 0x8000 + + +/*create connection param*/ +#define ALLOW_ROLE_SWITCH_YES 0x01 +#define ALLOW_ROLE_SWITCH_NO 0x00 + + +/*accept connection req param*/ +#define ROLE_BECAME_MASTER 0x00 +#define ROLE_REMAIN_SLAVE 0x01 + + +/* link policy */ +#define HCI_LP_ENABLE_ROLE_SWITCH_MASK 0x01 +#define HCI_LP_ENABLE_HOLD_MODE_MASK 0x02 +#define HCI_LP_ENABLE_SNIFF_MODE_MASK 0x04 +#define HCI_LP_ENABLE_PARK_MODE_MASK 0x08 + + +#ifdef __IAG_BLE_INCLUDE__ +#define HCI_BLE_SUBEVT_CODE_CONNECT_CPMPLETE 1 +#endif /* __IAG_BLE_INCLUDE__ */ + +/****************************************************************************************** + * Event Evtcode Definition (OLD) + *****************************************************************************************/ +#define HCI_MasterLinkKeyCompleteEvt_Code 0x0A +#define HCI_PageScanModeChangeEvt_Code 0x1F +#define HCI_PageScanRepetitionModeChangeEvt_Code 0x20 +#define HCI_InquiryResultEvt_withRSSI 0x22 + +#define HCI_EV_INQUIRY_COMPLETE 0x01 + struct hci_ev_inquiry_complete { + uint8 status; +}__attribute__ ((packed)); + +#define HCI_EV_INQUIRY_RESULT 0x02 +#define HCI_EV_INQUIRY_RESULT_RSSI 0x22 +#define HCI_EV_INQUIRY_RESULT_EXTINQ 0x2F + +#define PAGE_SCAN_REPETITION_MODE_R0 0x00 +#define PAGE_SCAN_REPETITION_MODE_R1 0x01 +#define PAGE_SCAN_REPETITION_MODE_R2 0x02 +#define PAGE_SCAN_PERIOD_MODE_P0 0x00 +#define PAGE_SCAN_PERIOD_MODE_P1 0x01 +#define PAGE_SCAN_PERIOD_MODE_P2 0x02 + struct hci_ev_inquiry_result { + uint8 num_responses; + struct bdaddr_t bdaddr; + uint8 page_scan_repetition_mode; + uint8 reserved1; + uint8 reserved2;/*must be 0*/ + uint8 class_dev[3]; + uint16 clk_off; +}__attribute__ ((packed)); + + + +#define HCI_EV_CONN_COMPLETE 0x03 + struct hci_ev_conn_complete { + uint8 status; + uint16 handle; + struct bdaddr_t bdaddr; + uint8 link_type; + uint8 encr_mode; +}__attribute__ ((packed)); + +#define HCI_EV_CONN_REQUEST 0x04 + +#define HCI_LINK_TYPE_SCO 0x00 +#define HCI_LINK_TYPE_ACL 0x01 +#define HCI_LINK_TYPE_ESCO 0x02 + struct hci_ev_conn_request { + struct bdaddr_t bdaddr; + uint8 class_dev[3]; + uint8 link_type; +}__attribute__ ((packed)); + +#define HCI_EV_DISCONN_COMPLETE 0x05 + struct hci_ev_disconn_complete { + uint8 status; + uint16 handle; + uint8 reason; +}__attribute__ ((packed)); + +#define HCI_EV_AUTHENTICATION_COMPLETE 0x06 + struct hci_ev_authentication_complete { + uint8 status; + uint16 handle; +}__attribute__ ((packed)); + +#define HCI_EV_REMOTENAMEREQ_COMPLETE 0x07 +#define HCI_REMOTENAME_MAX 248 + struct hci_ev_remote_name_req_complete { + uint8 status; + struct bdaddr_t bdaddr; + uint8 name[HCI_REMOTENAME_MAX]; +}__attribute__ ((packed)); + +#define HCI_EV_ENCRYPTION_CHANGE 0x08 + struct hci_ev_encryption_change { + uint8 status; + uint16 conn_handle; + uint8 encryption_enable; +}__attribute__ ((packed)); + + +#define HCI_EV_READ_REMOTE_FEATURES 0x0B + struct hci_ev_read_remote_features{ + uint8 status; + uint16 conn_handle; + uint8 features[8]; +}__attribute__ ((packed)); + + +#define HCI_EV_READ_REMOTE_VERSION 0x0C + struct hci_ev_read_remote_version{ + uint8 status; + uint16 conn_handle; + uint8 lmp_version; + uint16 manufacturer_name; + uint16 lmp_subversion; +}__attribute__ ((packed)); + + + +#define HCI_EV_QOSSETUP_COMPLETE 0x0D + + struct hci_ev_qossetup_complete{ + uint8 status; + uint16 conn_handle; + uint8 flags; + uint8 service_type; + uint32 token_rate; + uint32 peak_bandwith; + uint32 latency; + uint32 delay_v; +}__attribute__ ((packed)); + + +#define HCI_EV_CMD_COMPLETE 0x0e + + struct hci_ev_cmd_complete{ + uint8 num_hci_cmd_packets; + uint16 cmd_opcode; + uint8 param[1]; +}__attribute__ ((packed)); + +#define HCI_EV_CMD_STATUS 0x0f + struct hci_ev_cmd_status{ + uint8 status; + uint8 num_hci_cmd_packets; + uint16 cmd_opcode; +}__attribute__ ((packed)); + +#define HCI_EV_HARDWARE_ERROR 0x10 + struct hci_ev_hardware_error{ + uint8 hw_code; +}__attribute__ ((packed)); + + +#define HCI_EV_ROLE_CHANGE 0x12 + struct hci_ev_role_change{ + uint8 status; + struct bdaddr_t bdaddr; + uint8 new_role; +}__attribute__ ((packed)); + + struct hci_ev_cmd_complete_read_stored_linkkey{ + uint8 status; + uint16 max_num_keys; + uint8 num_keys_read; +}__attribute__ ((packed)); + + struct hci_ev_cmd_complete_le_read_buffer_size{ + uint8 status; + uint16 le_data_packet_length; + uint8 total_num_le_data_packets; +}__attribute__ ((packed)); + + struct hci_ev_cmd_complete_role_discovery{ + uint8 status; + uint16 connection_handle; + uint8 current_role; +}__attribute__ ((packed)); + + +struct hci_ev_cmd_complete_read_local_version{ + uint8 status; + uint8 hci_version; + uint16 hci_revision; + uint8 lmp_version; + uint16 manu_name; + uint16 lmp_subversion; +}__attribute__ ((packed)); + +struct hci_ev_cmd_complete_read_local_sup_features{ + uint8 status; + uint8 features[8]; +}__attribute__ ((packed)); + +struct hci_ev_cmd_complete_read_local_ext_features{ + uint8 status; + uint8 page_num; + uint8 max_page_num; + uint8 features[8]; +}__attribute__ ((packed)); + +#define HCI_EV_NUM_OF_CMPLT 0x13 + struct hci_ev_num_of_complete{ + uint8 num_handle; + uint16 handle; + uint16 num_of_comp; +}__attribute__ ((packed)); + + struct hci_ev_num_of_complete_item{ + uint16 handle; + uint16 num_of_comp; +}__attribute__ ((packed)); + +#define HCI_EV_MODE_CHANGE 0x14 + +#define HCI_MODE_ACTIVE 0x00 +#define HCI_MODE_HOLD 0x01 +#define HCI_MODE_SNIFF 0x02 +#define HCI_MODE_PARK 0x03 + + struct hci_ev_mode_change { + uint8 status; + uint16 handle; + uint8 current_mode; + uint16 interval; +}__attribute__ ((packed)); + +#define HCI_EV_RETURN_LINKKEYS 0x15 + + struct hci_ev_return_linkkeys{ + uint8 num_keys; + struct bdaddr_t bdaddr; + uint8 link_key[16]; +}__attribute__ ((packed)); + +struct hci_evt_packet_t { + uint8 evt_code; + uint8 length; + uint8 data[1]; +}__attribute__ ((packed)); + +#define HCI_EV_PIN_CODE_REQ 0x16 + struct hci_ev_pin_code_req { + struct bdaddr_t bdaddr; +}__attribute__ ((packed)); + +#define HCI_EV_LINK_KEY_REQ 0x17 + struct hci_ev_link_key_req { + struct bdaddr_t bdaddr; +}__attribute__ ((packed)); + +#define HCI_EV_LINK_KEY_NOTIFY 0x18 + struct hci_ev_link_key_notify { + struct bdaddr_t bdaddr; + uint8 link_key[16]; + uint8 key_type; +}__attribute__ ((packed)); + +#define HCI_EV_DATABUF_OVERFLOW 0x1A + struct hci_ev_databuf_overflow{ + uint8 link_type; +}__attribute__ ((packed)); + + +#define HCI_EV_MAX_SLOT_CHANGE 0x1B + struct hci_ev_max_slot_change { + uint16 handle; + uint8 max_slots; +}__attribute__ ((packed)); + +#define HCI_EV_READ_CLKOFF_Code 0x1C + struct hci_ev_read_clkoff{ + uint8 status; + uint16 handle; + uint16 clkoff; +}__attribute__ ((packed)); + +#define HCI_EV_CONNPKT_TYPE_CHANGE 0x1D + struct hci_ev_connpkt_type_change { + uint8 status; + uint16 handle; + uint16 pkt_type; +}__attribute__ ((packed)); + +#define HCI_EV_QOS_VIOLATION 0x1E + struct hci_ev_qos_violation { + uint16 handle; +}__attribute__ ((packed)); + +#define HCI_EV_FLOW_SPECIFICATION 0x21 + struct hci_ev_flow_specification { + uint8 status; + uint16 handle; + uint8 flags; + uint8 flow_dir; + uint8 service_type; + uint32 token_rate; + uint32 token_bucket; + uint32 peak_bandwidth; + uint32 latency; +}__attribute__ ((packed)); + +#define HCI_EV_READ_REMOTE_EXTFEATURES 0x23 + struct hci_ev_read_remote_extfeatures { + uint8 status; + uint16 handle; + uint8 page_num; + uint8 max_page_num; + uint8 ext_features[8]; +}__attribute__ ((packed)); + +#define HCI_EV_SYNC_CONN_COMPLETE 0x2c + struct hci_ev_sync_conn_complete { + uint8 status; + uint16 handle; + struct bdaddr_t bdaddr; + uint8 link_type; + uint8 tx_interval; + uint8 retx_window; + uint16 rx_pkt_length; + uint16 tx_pkt_length; + uint8 air_mode; +}__attribute__ ((packed)); + +#define HCI_EV_ENCRYPT_KEY_REFRESH_COMPLETE 0x30 + +#define HCI_EV_IO_CAPABILITY_REQUEST 0x31 +struct hci_ev_io_capability_request { + struct bdaddr_t bdaddr; +}__attribute__ ((packed)); + +#define HCI_EV_IO_CAPABILITY_RESPONSE 0x32 +struct hci_ev_io_capability_response { + struct bdaddr_t bdaddr; + uint8 io_capability; + uint8 oob_data_present; + uint8 authentication_requirement; +}__attribute__ ((packed)); + +#define HCI_EV_USER_CONFIRMATION_REQUEST 0x33 +struct hci_ev_user_confirmation_request { + struct bdaddr_t bdaddr; +}__attribute__ ((packed)); + +#define HCI_EV_SIMPLE_PAIRING_COMPLETE 0x36 +struct hci_ev_simple_pairing_complete{ + uint8 status; + struct bdaddr_t bdaddr; +}__attribute__ ((packed)); + +#define HCI_EV_LINK_SUPERV_TIMEOUT_CHANGED 0x38 + +#define HCI_LE_META_EVT 0x3E +#define HCI_LE_EV_CONN_COMPLETE 0x01 +#define HCI_LE_EV_ADV_REPORT 0x02 + +#define HCI_EV_SYNC_CONN_CHANGE 0x2D + struct hci_ev_sync_conn_change { + uint8 status; + uint16 handle; + uint8 tx_interval; + uint8 retx_window; + uint16 rx_pkt_length; + uint16 tx_pkt_length; +}__attribute__ ((packed)); + +#define HCI_EV_SNIFF_SUBRATING 0x2E + struct hci_ev_sniff_subrating { + uint8 status; + uint16 handle; + uint16 maximum_transmit_lantency; + uint16 maximum_receive_lantency; + uint16 minimum_remote_timeout; + uint16 minimum_local_timeout; +}__attribute__ ((packed)); + +#define HCI_EV_DEBUG 0xFF + struct hci_ev_debug { + uint16 debug_evt_code; + uint8 param[1]; +}__attribute__ ((packed)); + +struct get_buffer +{ + /// length of buffer + uint8_t length; + /// data of 128 bytes length + uint8_t data[128]; +}; + +struct hci_ev_rd_mem_cmp_evt +{ + ///Status + uint8_t status; + ///buffer structure to return + struct get_buffer buf; +}; + +/* vendor event */ +#define HCI_EV_VENDOR_EVENT (0xFF) + +//sub event code +#define HCI_DBG_TRACE_WARNING_EVT_CODE 0x01 +#define HCI_SCO_SNIFFER_STATUS_EVT_CODE 0x02 +#define HCI_ACL_SNIFFER_STATUS_EVT_CODE 0x03 +#define HCI_TWS_EXCHANGE_CMP_EVT_CODE 0x04 +#define HCI_NOTIFY_CURRENT_ADDR_EVT_CODE 0x05 +#define HCI_NOTIFY_DATA_XFER_EVT_CODE 0x06 +#define HCI_START_SWITCH_EVT_CODE 0x09 +#define HCI_LL_MONITOR_EVT_CODE 0x0A +#define HCI_DBG_LMP_MESSAGE_RECORD_EVT_SUBCODE 0x0B +#define HCI_GET_TWS_SLAVE_MOBILE_RSSI_CODE 0x0C + +#endif /* __BTM_HCI_H__ */ diff --git a/services/bt_profiles_enhanced/inc/btm_i.h b/services/bt_profiles_enhanced/inc/btm_i.h new file mode 100644 index 0000000..17a9da6 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btm_i.h @@ -0,0 +1,648 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __BTM_I_H__ +#define __BTM_I_H__ + +#include "btlib_type.h" +#include "co_ppbuff.h" +#include "bt_sys_cfg.h" +#include "hci.h" +#include "btm_hci.h" + +#define SUPPORT_AV 1 +#define SUPPORT_AV_C 1 +#define SUPPORT_OPP 0 +#define SUPPORT_FTP 0 +#define SUPPORT_SPP 1 +#define SUPPORT_AG 0 +#define SUPPORT_DUN 0 +#define SUPPORT_HSHF 0 //sdk +#define SUPPORT_HID 0 + +#define SUPPORT_OBEX 0 +#define SUPPORT_PBAP 0 + +#define SUPPORT_L2CAP_ENHANCED_RETRANS 0 + +#define PROFILE_NONE 0x00 +#define PROFILE_HSHF 0x01 +#define PROFILE_SPP 0x02 +#define PROFILE_OPP 0x04 +#define PROFILE_FTP 0x08 +#define PROFILE_AG 0x10 +#define PROFILE_AV 0x20 +#define PROFILE_DUN 0x40 +#define PROFILE_AV_C 0x80 + +#define ASCP_CMD_BASE 0x00 +#define HSHF_CMD_BASE 0x10 +#define SPP_CMD_BASE 0x20 +#define OPP_CMD_BASE 0x30 +#define FTP_CMD_BASE 0x40 +#define AV_CMD_BASE 0x50 +#define AG_CMD_BASE 0x60 +#define DUN_CMD_BASE 0x70 + +#define ASCP_EVNT_BASE 0x80 +#define HSHF_EVNT_BASE 0x90 +#define SPP_EVNT_BASE 0xA0 +#define OPP_EVNT_BASE 0xB0 +#define FTP_EVNT_BASE 0xC0 +#define MISC_EVNT_BASE 0xC0 //BUG 15 owen.liu +#define AV_EVNT_BASE 0xD0 +#define AG_EVNT_BASE 0xE0 +#define DUN_EVNT_BASE 0xF0 //share with AV_C (used in AT) +#define AV_C_EVNT_BASE 0xF0 //share with DUN(used in ascp) + +#define BT_ECODE_NO_ERROR 0x00 +#define BT_ECODE_UNKNOWN_HCI_CMD 0x01 +#define BT_ECODE_NO_CONNECTION 0x02 +#define BT_ECODE_HARDWARE_FAILURE 0x03 +#define BT_ECODE_PAGE_TIMEOUT 0x04 +#define BT_ECODE_AUTHENTICATE_FAILURE 0x05 +#define BT_ECODE_MISSING_KEY 0x06 +#define BT_ECODE_MEMORY_FULL 0x07 +#define BT_ECODE_CONNECTION_TIMEOUT 0x08 +#define BT_ECODE_MAX_CONNECTIONS 0x09 +#define BT_ECODE_MAX_SCO_CONNECTIONS 0x0a +#define BT_ECODE_ACL_ALREADY_EXISTS 0x0b +#define BT_ECODE_COMMAND_DISALLOWED 0x0c +#define BT_ECODE_LIMITED_RESOURCE 0x0d +#define BT_ECODE_SECURITY_ERROR 0x0e +#define BT_ECODE_PERSONAL_DEVICE 0x0f +#define BT_ECODE_CONN_ACCEPT_TIMEOUT 0x10 +#define BT_ECODE_UNSUPPORTED_FEATURE 0x11 +#define BT_ECODE_INVALID_HCI_PARM 0x12 +#define BT_ECODE_REMOTE_USER_TERMINATED 0x13 +#define BT_ECODE_LOW_RESOURCES 0x14 +#define BT_ECODE_POWER_OFF 0x15 +#define BT_ECODE_LOCAL_TERMINATED 0x16 +#define BT_ECODE_REPEATED_ATTEMPTS 0x17 +#define BT_ECODE_PAIRING_NOT_ALLOWED 0x18 +#define BT_ECODE_UNKNOWN_LMP_PDU 0x19 +#define BT_ECODE_UNSUPPORTED_REMOTE 0x1a +#define BT_ECODE_SCO_OFFSET_REJECT 0x1b +#define BT_ECODE_SCO_INTERVAL_REJECT 0x1c +#define BT_ECODE_SCO_AIR_MODE_REJECT 0x1d +#define BT_ECODE_INVALID_LMP_PARM 0x1e +#define BT_ECODE_UNSPECIFIED_ERR 0x1f +#define BT_ECODE_UNSUPPORTED_LMP_PARM 0x20 +#define BT_ECODE_ROLE_CHG_NOT_ALLOWED 0x21 +#define BT_ECODE_LMP_RESPONSE_TIMEOUT 0x22 +#define BT_ECODE_LMP_TRANS_COLLISION 0x23 +#define BT_ECODE_LMP_PDU_NOT_ALLOWED 0x24 +#define BT_ECODE_ENCRYP_MODE_NOT_ACC 0x25 +#define BT_ECODE_UNIT_KEY_USED 0x26 +#define BT_ECODE_QOS_NOT_SUPPORTED 0x27 +#define BT_ECODE_INSTANT_PASSED 0x28 +#define BT_ECODE_PAIR_UNITKEY_NO_SUPP 0x29 +#define BT_ECODE_NOT_FOUND 0xf1 +#define BT_ECODE_REQUEST_CANCELLED 0xf2 + +enum device_mode_dis_enum{ + DEVICE_MODE_DISCOVERABLE = 0x01, + DEVICE_MODE_NON_DISCOVERABLE = 0x0 +}; +enum device_mode_conn_enum{ + DEVICE_MODE_CONNECTABLE = 0x01, + DEVICE_MODE_NON_CONNECTABLE = 0x0, + DEVICE_MODE_NO_CHANGE = 0x04 +}; + +enum acl_pkt_boundary_enum{ + ACL_START = 0x02, + ACL_CONTINUE = 0x01 +}; +enum btm_security_event_enum { + BTM_SECURITY_AUTORITY_SUCCESS=1, + BTM_SECURITY_AUTORITY_FAILURE +}; + +enum btm_l2cap_event_enum { + BTM_EV_CONN_ACL_OPENED=1, + BTM_EV_CONN_ACL_CLOSED, + BTM_EV_SECURITY_AUTORITY_SUCCESS, + BTM_EV_SECURITY_AUTORITY_FAILURE +}; + +enum conn_sco_stat_enum{ + BTM_CONN_SCO_OPENED=1, + BTM_CONN_SCO_CLOSED, + BTM_CONN_SCO_WAIT /*the sco connection is waiting for the acl connection to be connected first*/ +}; + +enum btm_pairing_event +{ + PAIRING_OK, + PAIRING_TIMEOUT, + PAIRING_FAILED, + UNPAIR_OK +}; // change + +/* enum for inquiry events */ +enum btm_inquiry_event { + INQUIRY_DONE, // inquiry is done + NEW_REMOTE_DEV_IND, // found a new remote device + INQUIRY_CANCEL_OK, // cancel inquiry + INQUIRY_CANCEL_FAIL +}; + +enum btm_name_event +{ + NAME_DONE, + NAME_FAIL, + NAME_CANCEL_OK, + NAME_CANCEL_FAIL +}; + +typedef void (*btm_pairing_callback_t)(enum btm_pairing_event event,void *pdata); + +typedef void (*btm_chip_init_ready_callback_t)(int status); + +/*bt event definition to application layer*/ +#define BTEVENT_INQUIRY_RESULT 1 + +#define BTEVENT_INQUIRY_COMPLETE 2 + +#define BTEVENT_INQUIRY_CANCELED 3 + +#define BTEVENT_LINK_CONNECT_IND 4 + +#define BTEVENT_SCO_CONNECT_IND 5 + +#define BTEVENT_LINK_DISCONNECT 6 + +#define BTEVENT_LINK_CONNECT_CNF 7 + +#define BTEVENT_LINK_CON_RESTRICT 8 + +#define BTEVENT_MODE_CHANGE 9 + +#define BTEVENT_ACCESSIBLE_CHANGE 10 + +#define BTEVENT_AUTHENTICATED 11 + +#define BTEVENT_ENCRYPTION_CHANGE 12 + +#define BTEVENT_SECURITY_CHANGE 13 + +#define BTEVENT_ROLE_CHANGE 14 + +#define BTEVENT_SCO_DISCONNECT 15 + +#define BTEVENT_SCO_CONNECT_CNF 16 + +#define BTEVENT_SIMPLE_PAIRING_COMPLETE 17 + +#define BTEVENT_REMOTE_FEATURES 18 + +#define BTEVENT_REM_HOST_FEATURES 19 + +#define BTEVENT_LINK_SUPERV_TIMEOUT_CHANGED 20 + +#define BTEVENT_SET_SNIFF_SUBRATING_PARMS_CNF 21 + +#define BTEVENT_SNIFF_SUBRATE_INFO 22 + +#define BTEVENT_SET_INQUIRY_MODE_CNF 23 + +#define BTEVENT_SET_INQ_TX_PWR_LVL_CNF 24 + +#define BTEVENT_SET_EXT_INQUIRY_RESP_CNF 25 + +#define BTEVENT_SET_ERR_DATA_REPORTING_CNF 26 + +#define BTEVENT_KEY_PRESSED 27 + +#define BTEVENT_QOS_SETUP_COMPLETE 28 + +#ifdef __TWS_RECONNECT_USE_BLE__ +#define BTEVENT_TWS_BLE_ADV_REPORT_EVENT 29 +#endif /* */ + +/** an ACL connection has received an internal data transmit + * request while it is in hold, park or sniff mode. The data will still be + * passed to the radio in park and sniff modes. However, hold mode will + * block data transmit. It may be necessary to return the ACL to active + * mode to restore normal data transfer. + */ +#define BTEVENT_ACL_DATA_NOT_ACTIVE 99 + +/* +Indicate that an ACL connection is sending or receiving data +while it is in active mode. Then, keep resetting the sniff timer. +*/ +#define BTEVENT_ACL_DATA_ACTIVE 98 +/** Indicates that the HCI failed to initialize. + */ +#define BTEVENT_HCI_INIT_ERROR 100 + +#define BTEVENT_HCI_INITIALIZED 101 +/** Indicates that a fatal error has occurred in the radio or the HCI transport. + */ +#define BTEVENT_HCI_FATAL_ERROR 102 + +/** Indicates that the HCI has been deinitialized. + */ +#define BTEVENT_HCI_DEINITIALIZED 103 + +/** Indicates that the HCI cannot be initialized. + */ +#define BTEVENT_HCI_FAILED 104 + +#define BTEVENT_HCI_COMMAND_SENT 105 + +/** Indicates the name of a remote device or cancellation of a name request. + */ +#define BTEVENT_NAME_RESULT 30 + +#define BTEVENT_SCO_DATA_IND 31 + +/** Outgoing SCO data has been sent and the packet is free for re-use by + * the application. + */ +#define BTEVENT_SCO_DATA_CNF 32 + +#define BTEVENT_LINK_CONNECT_REQ 33 + +/** Incoming link accept complete. */ +#define BTEVENT_LINK_ACCEPT_RSP 34 + +/** Incoming link reject complete. . */ +#define BTEVENT_LINK_REJECT_RSP 35 + +#define BTEVENT_COMMAND_COMPLETE 36 + +#define BTEVENT_SCO_CONNECT_REQ 37 + +/** Set Audio/Voice settings complete. */ +#define BTEVENT_SCO_VSET_COMPLETE 38 + +/** SCO link connection process started. */ +#define BTEVENT_SCO_STARTED 39 + +/** Select Device operation complete, "p.select" is valid. */ +#define BTEVENT_DEVICE_SELECTED 40 + +/** The eSCO connection has changed. "p.scoConnect" is valid. + */ +#define BTEVENT_SCO_CONN_CHNG 41 + +/* Group: Security-related events. */ + +/** Indicates access request is successful. "p.secToken" is valid. */ +#define BTEVENT_ACCESS_APPROVED 50 + +/** Indicates access request failed. "p.secToken" is valid. */ +#define BTEVENT_ACCESS_DENIED 51 + +/** Request authorization when "errCode" is BEC_NO_ERROR. + * "p.remDev" is valid. + */ +#define BTEVENT_AUTHORIZATION_REQ 52 + +/** Request a Pin for pairing when "errCode" is BEC_NO_ERROR. + * "p.pinReq" is valid. If p.pinReq.pinLen is > 0 then SEC_SetPin() + * must be called in response to this event with a pin length >= + * p.pinReq.pinLen. + */ +#define BTEVENT_PIN_REQ 53 + +/** Pairing operation is complete. + */ +#define BTEVENT_PAIRING_COMPLETE 54 + +/** Authentication operation complete. "p.remDev" is valid. */ +#define BTEVENT_AUTHENTICATE_CNF 55 + +/** Encryption operation complete. "p.remDev" is valid. */ +#define BTEVENT_ENCRYPT_COMPLETE 56 + +/** Security mode 3 operation complete. "p.secMode" is valid. */ +#define BTEVENT_SECURITY3_COMPLETE 57 + +/** A link key is returned. "p.bdLinkKey" is valid. */ +#define BTEVENT_RETURN_LINK_KEYS 58 + +/** Out of Band data has been received from the host controller. */ +#define BTEVENT_LOCAL_OOB_DATA 59 + +/** Request a Pass Key for simple pairing when "errCode" is BEC_NO_ERROR. The + * application should call SEC_SetPassKey() to provide the passkey or reject + * the request, and optionally save the link key. + */ +#define BTEVENT_PASS_KEY_REQ 60 + +/** Request a User Confirmation for simple pairing when "errCode" is + * BEC_NO_ERROR. + */ + +#define BTEVENT_CONFIRM_NUMERIC_REQ 61 + +#define BTEVENT_DISPLAY_NUMERIC_IND 62 + +#define BTEVENT_CONN_PACKET_TYPE_CHNG 63 + +#define SDEVENT_QUERY_RSP 70 + +#define SDEVENT_QUERY_ERR 71 + +#define SDEVENT_QUERY_FAILED 72 + +#define BTEVENT_SELECT_DEVICE_REQ 80 + +#define BTEVENT_DEVICE_ADDED 81 + +#define BTEVENT_DEVICE_DELETED 82 + +#define BTEVENT_MAX_SLOT_CHANGED 83 + +#define BTEVENT_SNIFFER_CONTROL_DONE 84 + +#define BTEVENT_LINK_POLICY_CHANGED 85 + +/* added for pass command status to up level */ +#define BTEVENT_COMMAND_STATUS 86 + +typedef uint32_t event_mask_t; + +#define BTM_EVTMASK_NO_EVENTS 0x00000000 +#define BTM_EVTMASK_INQUIRY_RESULT 0x00000001 +#define BTM_EVTMASK_INQUIRY_COMPLETE 0x00000002 +#define BTM_EVTMASK_INQUIRY_CANCELED 0x00000004 +#define BTM_EVTMASK_LINK_CONNECT_IND 0x00000008 +#define BTM_EVTMASK_SCO_CONNECT_IND 0x00000010 +#define BTM_EVTMASK_LINK_DISCONNECT 0x00000020 +#define BTM_EVTMASK_LINK_CONNECT_CNF 0x00000040 +#define BTM_EVTMASK_LINK_CON_RESTRICT 0x00000080 +#define BTM_EVTMASK_MODE_CHANGE 0x00000100 +#define BTM_EVTMASK_ACCESSIBLE_CHANGE 0x00000200 +#define BTM_EVTMASK_AUTHENTICATED 0x00000400 +#define BTM_EVTMASK_ENCRYPTION_CHANGE 0x00000800 +#define BTM_EVTMASK_SECURITY_CHANGE 0x00001000 +#define BTM_EVTMASK_ROLE_CHANGE 0x00002000 +#define BTM_EVTMASK_SCO_DISCONNECT 0x00004000 +#define BTM_EVTMASK_SCO_CONNECT_CNF 0x00008000 +#define BTM_EVTMASK_SIMPLE_PAIRING_COMPLETE 0x00010000 +#define BTM_EVTMASK_REMOTE_FEATURES 0x00020000 +#define BTM_EVTMASK_REM_HOST_FEATURES 0x00040000 +#define BTM_EVTMASK_LINK_SUPERV_TIMEOUT_CHANGED 0x00080000 +#define BTM_EVTMASK_SET_SNIFF_SUBR_PARMS 0x00100000 +#define BTM_EVTMASK_SNIFF_SUBRATE_INFO 0x00200000 +#define BTM_EVTMASK_SET_INQ_MODE 0x00400000 +#define BTM_EVTMASK_SET_INQ_RSP_TX_PWR 0x00800000 +#define BTM_EVTMASK_SET_EXT_INQ_RESP 0x01000000 +#define BTM_EVTMASK_SET_ERR_DATA_REP 0x02000000 +#define BTM_EVTMASK_KEY_PRESSED 0x04000000 +#define BTM_EVTMASK_CONN_PACKET_TYPE_CHNG 0x08000000 +#define BTM_EVTMASK_QOS_SETUP_COMPLETE 0x10000000 +#define BTM_EVTMASK_MAX_SLOT_CHANGED 0x20000000 +#define BTM_EVTMASK_SNIFFER_CONTROL_DONE 0x40000000 +#define BTM_EVTMASK_LINK_POLICY_CHANGED 0x80000000 +#define BTM_EVTMASK_ALL_EVENTS 0xffffffff + +#define BTM_ACL_ST_DISCONNECTED 0x00 +#define BTM_ACL_ST_OUT_CON 0x01 +#define BTM_ACL_ST_IN_CON 0x02 +#define BTM_ACL_ST_CONNECTED 0x03 +#define BTM_ACL_ST_OUT_DISC 0x04 +#define BTM_ACL_ST_OUT_DISC2 0x05 +#define BTM_ACL_ST_OUT_CON2 0x06 + +#define BTM_CMGR_INIT_REQ 0x00 +#define BTM_CMGR_DEINIT_REQ 0x01 + +/* event param of BTEVENT_LINK_CONNECT_IND*/ +struct acl_open_data{ + struct btm_conn_item_t* conn; //acl connection + uint8 err_code; + uint32 emask; +}; +struct conn_req_data{ + struct btm_conn_item_t *conn; + uint32 emask; +}; +struct acl_close_data{ + struct btm_conn_item_t *conn; + struct hci_ev_disconn_complete *param; + uint8 status; + uint8 reason; + uint32 emask; +}; + +struct sco_open_data{ + struct btm_sco_conn_item_t* conn; + uint8 err_code; + uint32 emask; +}; + +struct sco_close_data{ + struct btm_sco_conn_item_t *conn; + struct hci_ev_disconn_complete *param; + uint8 status; + uint8 reason; + uint32 emask; +}; + +struct accessible_change_data{ + enum device_mode_dis_enum discoverable; + enum device_mode_conn_enum connectable; + uint8 err_code; + uint32 emask; +}; + +struct inquiry_cancel_data{ + uint8 err_code; + uint32 emask; +}; + +struct command_status_data{ + uint8 status; + uint8 num_hci_cmd_packets; + uint16 cmd_opcode; + uint32 emask; +}; + +struct role_change_data{ + struct btm_conn_item_t *rem_dev; + uint8 new_role; + uint8 err_code; + uint32 emask; +}; + +struct mode_change_data{ + struct btm_conn_item_t *rem_dev; + uint8 cur_mode; + uint16 interval; + uint8 err_code; + uint32 emask; +}; + +struct acl_data_active{ + struct btm_conn_item_t *rem_dev; + uint16 data_len; + uint8 err_code; + uint32 emask; +}; + +struct acl_data_not_active{ + struct btm_conn_item_t *rem_dev; + uint16 data_len; + uint8 err_code; + uint32 emask; +}; + +struct authenticaion_complete_data{ + struct btm_conn_item_t *rem_dev; + uint32 emask; + uint8 err_code; +}; + +struct simple_pairing_complete_data{ + struct btm_conn_item_t *rem_dev; + uint32 emask; + uint8 err_code; +}; + +struct encryption_change_data{ + struct btm_conn_item_t *rem_dev; + uint8 mode; + uint32 emask; + uint8 err_code; +}; + +struct inquiry_result_data{ + uint8 *data; + uint8 is_rssi; + uint8 is_extinq; + uint8 err_code; + uint32 emask; +}; + +struct name_rsp_data{ + uint8 status; + struct bdaddr_t bdaddr; + uint32 emask; +}; +struct inquiry_complete_data{ + uint8 status; + uint8 err_code; + uint32 emask; +}; + +struct btm_ctx_input { + struct bdaddr_t *remote; + struct ctx_content ctx; + uint16 conn_handle; +}; + +struct btm_ctx_output { + uint16 conn_handle; +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +struct l2cap_channel; + +int8 btm_init(void); + +int8 btm_register_chip_init_ready_callback(btm_chip_init_ready_callback_t cb); + +int8 btm_device_mode_set(enum device_mode_dis_enum discoverable, enum device_mode_conn_enum connectable); +int8 btm_device_write_iac(uint8 num); +int8 btm_device_write_page_scan_activity(uint16 interval, uint16 window); +int8 btm_device_write_inquiry_scan_activity(uint16 interval, uint16 window); + +int8 btm_conn_sco_is_open (struct btm_conn_item_t *conn); +uint16 btm_conn_acl_get_conn_handle ( struct bdaddr_t *remote_bdaddr); + + +int8 btm_conn_acl_req ( struct bdaddr_t *remote_bdaddr); +int8 btm_conn_acl_is_open( struct bdaddr_t *remote_bdaddr); + +int8 btm_conn_sco_req ( struct bdaddr_t *remote_bdaddr); + +int8 btm_conn_sco_disconnect(struct bdaddr_t *remote_bdaddr, uint8 reason); //added by zmchen on 20070205 +int8 btm_conn_acl_senddata (struct bdaddr_t *remote_bdaddr, uint8 *data_buf_p, uint16 data_buf_len); + +int8 btm_conn_acl_send_ppb (uint16 conn_handle, struct pp_buff *ppb); +int8 btm_conn_acl_send_continue_ppb (uint16 conn_handle, struct pp_buff *ppb); + +void btm_conn_acl_fake_connection_complete(uint8_t status, struct bdaddr_t *bdAddr); +int8 btm_conn_acl_close(struct bdaddr_t *bdaddr, uint8 reason); + +int8 btm_security_askfor_authority(uint16 conn_handle, uint16 psm, struct l2cap_channel *l2cap_channel); + +void btm_pairing_enter(uint32 pairing_timeout, btm_pairing_callback_t callback); + +/* for pairing that needs remote device address */ +void btm_start_pairing( struct bdaddr_t remote_addr, btm_pairing_callback_t callback); + +void btm_unpair_reomte(struct bdaddr_t remote_addr, btm_pairing_callback_t callback); + +void btm_pairing_register_callback(btm_pairing_callback_t callback); + +void btm_pairing_exit(void); + +void btm_direct_set_audio_param(uint8 param); +uint8 btm_get_audio_default_param(void); +void btm_set_audio_default_param(uint8 param); + +/* inquiry functions */ +void btm_start_inquiry(void (*btm_start_inquiry_notify_callback)(enum btm_inquiry_event event, void *pData), uint8 inq_period, uint8 num_rsp); +void btm_cancel_inquiry(void (*btm_start_inquiry_notify_callback)(enum btm_inquiry_event event, void *pData)); +void btm_remote_name_request(struct hci_cp_remote_name_request *req, void (*btm_name_notify_callback)(enum btm_name_event event,void *pData)); +void btm_remote_name_cancel(struct bdaddr_t *remote, void (*btm_name_notify_callback)(enum btm_name_event event,void *pData)); + +void btm_hcicmd_sniff_mode(struct bdaddr_t *remote_bdaddr, uint16 sniff_max_interval,uint16 sniff_min_interval, uint16 sniff_attempt,uint16 sniff_timeout); +int8 btm_exit_sniff (struct bdaddr_t *remote_bdaddr); + +typedef void (*bt_hci_vendor_event_handler_func)(uint8_t* pbuf, uint32_t length); +void register_hci_vendor_event_handler_callback(bt_hci_vendor_event_handler_func func); + +typedef bool (*bt_hci_sync_airmode_check_ind_func)(uint8_t status); +void register_hci_sync_airmode_check_ind_callback(bt_hci_sync_airmode_check_ind_func func); + +uint32 btm_save_ctx(struct bdaddr_t *remote, uint8_t *buf, uint32_t buf_len); +uint32 btm_restore_ctx(struct btm_ctx_input *input, struct btm_ctx_output *output); + +int8 btm_sync_conn_audio_connected(struct bdaddr_t *bdAddr, uint16_t conhdl); +int8 btm_sync_conn_audio_disconnected(struct bdaddr_t *bdAddr, uint16_t conhdl); + +int8 btm_acl_conn_connected(struct bdaddr_t *bdAddr, uint16 conn_handle); +int8 btm_acl_conn_disconnected(struct bdaddr_t *bdAddr, uint16 conn_handle, uint8_t status, uint8_t reason); + +const char *btm_state2str(uint8 state); +const char *btm_errorcode2str(uint32 errorcode); +const char *btm_cmd_opcode2str(uint16 opcode); + +struct btstack_chip_config_t +{ + uint16_t hci_dbg_set_sync_config_cmd_opcode; + uint16_t hci_dbg_set_sco_switch_cmd_opcode; +}; + +struct btstack_chip_config_t* btm_get_btstack_chip_config(void); +void btm_set_btstack_chip_config(void* config); +int8 btm_device_set_ecc_ibrt_data_test(uint8 ecc_data_test_en, uint8 ecc_data_len, uint16 ecc_count, uint32 data_pattern); +int8 btm_device_send_prefer_rate(uint16 connhdl, uint8 rate); +#if defined(__cplusplus) +} +#endif + +#endif /* __BTM_I_H__ */ diff --git a/services/bt_profiles_enhanced/inc/btm_security.h b/services/bt_profiles_enhanced/inc/btm_security.h new file mode 100644 index 0000000..074a91d --- /dev/null +++ b/services/bt_profiles_enhanced/inc/btm_security.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __BTM_SECURITY_H__ +#define __BTM_SECURITY_H__ + +struct btm_security_auth_pending_item_t { + struct list_node list; +}; + +#define BTM_BONDING_NOT_REQUIRED 0x00 +#define BTM_DEDICATED_BONDING 0x02 +#define BTM_GENERAL_BONDING 0x04 +#define BTM_BONDING_NOT_ALLOWED 0x10 + +#define BTM_AUTH_MITM_PROTECT_NOT_REQUIRED 0x00 +#define BTM_AUTH_MITM_PROTECT_REQUIRED 0x01 + +#define BTM_IO_DISPLAY_ONLY 0 +#define BTM_IO_DISPLAY_YESNO 1 +#define BTM_IO_KEYBOARD_ONLY 2 +#define BTM_IO_NO_IO 3 + +/*api to handle hci event */ +void btm_security_link_key_notify(struct bdaddr_t *remote, uint8 *linkkey, uint8 key_type); +void btm_security_pin_code_req(struct bdaddr_t *remote); +void btm_security_link_key_req(struct bdaddr_t *remote); +void btm_security_authen_complete(uint8 status, uint16 conn_handle); +void btm_security_encryption_change(uint8 status, uint16 conn_handle, uint8 encrypt_en); + +#endif /* __BTM_SECURITY_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/co_lib.h b/services/bt_profiles_enhanced/inc/co_lib.h new file mode 100644 index 0000000..db4f705 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/co_lib.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __CO_LIB_H__ +#define __CO_LIB_H__ + +char ascii_char2val(const char c); +int ascii_str2val( const char str[], char base); +int ascii_strn2val( const char str[], char base, char n); + +#define __set_mask(var, mask) {var |= mask;} +#define __test_mask(var, mask) (var & mask) +//#define __test_and_clear_mask(var, mask) ((var & mask)?(var &= ~mask,1):0) + +#endif /* __CO_LIB_H__ */ diff --git a/services/bt_profiles_enhanced/inc/co_ppbuff.h b/services/bt_profiles_enhanced/inc/co_ppbuff.h new file mode 100644 index 0000000..595b62a --- /dev/null +++ b/services/bt_profiles_enhanced/inc/co_ppbuff.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __CO_PPBUFF_H__ +#define __CO_PPBUFF_H__ + +#include "btlib_type.h" +#include "btlib_more.h" +#include "bt_co_list.h" + +/* protocol type */ +#define PPB_GET_PROTO_TYPE(ppb) (ppb->flag & 0x0F) +#define PPB_SET_PROTO_TYPE(ppb,type) ppb->flag |= type + +#define PP_BUFF_FLAG_NORMAL 0x00 /* normal buffer */ +#define PP_BUFF_FLAG_L2CAPE 0x01 /* l2cap enhanced retrans buffer */ + +/* alloc type */ +#define PPB_GET_ALLOC_TYPE(ppb) (ppb->flag & 0xF0) +#define PPB_SET_ALLOC_TYPE(ppb,type) ppb->flag |= type + +#define PP_BUFF_FLAG_ALLOC_DYNAMIC 0x10 /* dynamic alloced, free inside */ +#define PP_BUFF_FLAG_ALLOC_INPLACE 0x20 /* inplace alloced, free outside */ + +struct pp_buff { + struct pp_buff *next; + struct pp_buff *prev; + + uint16 len; + uint16 flag; + uint8 *head; + uint8 *data; + uint8 *tail; + uint8 *end; + + void *context; +#if DBG_PPBUFF_NEED_STATISTIC==1 + struct list_node node; + uint32 ca; +#endif +}; + +struct pp_buff_head { + struct pp_buff *next; + struct pp_buff *prev; + uint32 qlen; +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +struct pp_buff *ppb_alloc(uint32 size); +struct pp_buff *ppb_alloc_inplace(uint32 size, uint8 *inplace_buff, uint32 inplace_buff_len); +void ppb_free( struct pp_buff *ppb); +uint8 *ppb_put(struct pp_buff *ppb, uint32 len); +void ppb_put_data(struct pp_buff *ppb, uint8 *data, uint32 len); +uint8 *ppb_push(struct pp_buff *ppb, uint32 len); +uint8 *ppb_pull(struct pp_buff *ppb, uint32 len); +void ppb_reserve(struct pp_buff *ppb, int len); +void ppb_trim(struct pp_buff *ppb, unsigned int len); +struct pp_buff *ppb_peek(struct pp_buff_head *list_); +struct pp_buff *ppb_peek_tail(struct pp_buff_head *list_); +void ppb_queue_head_init(struct pp_buff_head *list); +void ppb_queue_after(struct pp_buff_head *list, struct pp_buff *prev,struct pp_buff *newpp); +void ppb_queue_head(struct pp_buff_head *list, struct pp_buff *newpp); +void ppb_queue_tail(struct pp_buff_head *list, struct pp_buff *newpp); +struct pp_buff *ppb_dequeue(struct pp_buff_head *list); +void ppb_insert(struct pp_buff *newpp, struct pp_buff *prev, struct pp_buff *next, struct pp_buff_head *list); +void ppb_append(struct pp_buff *old, struct pp_buff *newpp, struct pp_buff_head *list); +void ppb_unlink(struct pp_buff *ppb, struct pp_buff_head *list); +struct pp_buff *ppb_dequeue_tail(struct pp_buff_head *list); +struct pp_buff *ppb_alloc_fixpacket(uint32 size); +void ppb_print_statistic(void); + +#if defined(__cplusplus) +} +#endif + +#endif /* __CO_PPBUFF_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/co_printf.h b/services/bt_profiles_enhanced/inc/co_printf.h new file mode 100644 index 0000000..83a679e --- /dev/null +++ b/services/bt_profiles_enhanced/inc/co_printf.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __CO_PRINTF_H__ +#define __CO_PRINTF_H__ + +int co_strlen( const char *s ); +int co_printf(const char *format, ...); +char *co_strstr(const char *s1, const char *s2); +int co_sprintf(char *out, const char *format, ...); + +#endif /* __CO_PRINTF_H__ */ diff --git a/services/bt_profiles_enhanced/inc/co_queue.h b/services/bt_profiles_enhanced/inc/co_queue.h new file mode 100644 index 0000000..72eeff5 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/co_queue.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __COQUEUE_H__ +#define __COQUEUE_H__ + +#include + +typedef void (*coqueue_destroy_func_t)(void *data); + +struct coqueue_entry { + void *data; + struct coqueue_entry *next; +}; + +struct coqueue { + int ref_count; + struct coqueue_entry *head; + struct coqueue_entry *tail; + unsigned int entries; +}; + +struct coqueue *coqueue_create(void); +void coqueue_destroy(struct coqueue *coqueue, coqueue_destroy_func_t destroy); +bool coqueue_push_tail(struct coqueue *coqueue, void *data); +bool coqueue_push_head(struct coqueue *coqueue, void *data); +bool coqueue_push_after(struct coqueue *coqueue, const void *entry, void *data); +void *coqueue_pop_head(struct coqueue *coqueue); +void *coqueue_peek_head(struct coqueue *coqueue); +void *coqueue_peek_tail(struct coqueue *coqueue); +typedef bool (*coqueue_match_func_t)(const void *data, const void *match_data); +void *coqueue_search(struct coqueue *coqueue, coqueue_match_func_t function, + const void *match_data); +bool coqueue_delete(struct coqueue *coqueue, const void *data); +void *coqueue_delete_if(struct coqueue *coqueue, coqueue_match_func_t function, + const void *user_data); +unsigned int coqueue_delete_all(struct coqueue *coqueue, coqueue_match_func_t function, + void *user_data, coqueue_destroy_func_t destroy); + +#endif /*__COQUEUE_H__*/ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/co_timer.h b/services/bt_profiles_enhanced/inc/co_timer.h new file mode 100644 index 0000000..9411458 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/co_timer.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __CO_TIMER_H__ +#define __CO_TIMER_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +int co_timer_is_running (uint8 *timer_id); +void co_timer_init(unsigned char timer_task_prio, unsigned int *ptos ); +void co_timer_del(uint8 *timer_handle); +void co_timer_cfg(uint8 *timer_handle, unsigned int millisecond, void (*timer_func)(void *), void *arg, int times); +void co_timer_resume(uint8 *timer_handle ); +void co_timer_restart(uint8 *timer_handle ); +void co_timer_update_and_restart(uint8 *timer_handle,unsigned int millisecond);; +void co_timer_start(uint8 *timer_handle); +void co_timer_stop(uint8 *timer_handle); +int co_timer_new(uint8 *timer_handle, unsigned int millisecond, void (*timer_func)(void *), void *arg, int times); +void co_timer_reset(void ); +void co_timer_reduce(uint8 *timer_handle, unsigned int reduece_ms); +void co_timer_reduce_all(unsigned int reduece_ms); +void co_timer_check(void); + +#if defined(__cplusplus) +} +#endif + +#endif /* __CO_TIMER_H__ */ diff --git a/services/bt_profiles_enhanced/inc/cobt.h b/services/bt_profiles_enhanced/inc/cobt.h new file mode 100644 index 0000000..350bea2 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/cobt.h @@ -0,0 +1,349 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + #ifndef __CO_BT_H__ + #define __CO_BT_H__ + +#define BLUETOOTH_20 1 + +/* Allow Role Switch HCI:4.6.8 */ +#define MASTER_ROLE 0 +#define SLAVE_ROLE 1 + +/* Allow Role Switch HCI:4.5.5 */ +#define ROLE_SWITCH_NOT_ALLOWED 0 +#define ROLE_SWITCH_ALLOWED 1 + +/* AcceptConnection Role HCI:4.5.8 */ +#define ACCEPT_SWITCH_TO_MASTER 0 +#define ACCEPT_REMAIN_SLAVE 1 + +/* Packet Type Flags HCI:4.5.14 */ +#define PACKET_TYPE_DM1_FLAG 0x0008 +#define PACKET_TYPE_DH1_FLAG 0x0010 +#define PACKET_TYPE_DM3_FLAG 0x0400 +#define PACKET_TYPE_DH3_FLAG 0x0800 +#define PACKET_TYPE_DM5_FLAG 0x4000 +#define PACKET_TYPE_DH5_FLAG 0x8000 + +#define PACKET_TYPE_EV3_FLAG 0x0001 +#define PACKET_TYPE_EV4_FLAG 0x0002 +#define PACKET_TYPE_EV5_FLAG 0x0004 + +#define PACKET_TYPE_HV1_FLAG 0x0020 +#define PACKET_TYPE_HV2_FLAG 0x0040 +#define PACKET_TYPE_HV3_FLAG 0x0080 + +#ifdef BLUETOOTH_20//used in change packet type +#define PACKET_TYPE_2_DH1_FLAG 0x0002 +#define PACKET_TYPE_3_DH1_FLAG 0x0004 +#define PACKET_TYPE_2_DH3_FLAG 0x0100 +#define PACKET_TYPE_3_DH3_FLAG 0x0200 +#define PACKET_TYPE_2_DH5_FLAG 0x1000 +#define PACKET_TYPE_3_DH5_FLAG 0x2000 +#define EDR_2M_PACKET_TYPE_MASK (PACKET_TYPE_2_DH1_FLAG|\ + PACKET_TYPE_2_DH3_FLAG|\ + PACKET_TYPE_2_DH5_FLAG) + + +#define EDR_3M_PACKET_TYPE_MASK (PACKET_TYPE_3_DH1_FLAG|\ + PACKET_TYPE_3_DH3_FLAG|\ + PACKET_TYPE_3_DH5_FLAG) +#define ALL_ACL_PACKET_MASK (PACKET_TYPE_DH5_FLAG|\ + PACKET_TYPE_DM5_FLAG|\ + PACKET_TYPE_DH3_FLAG|\ + PACKET_TYPE_DM3_FLAG|\ + PACKET_TYPE_DH1_FLAG|\ + PACKET_TYPE_DM1_FLAG|\ + EDR_2M_PACKET_TYPE_MASK |\ + EDR_3M_PACKET_TYPE_MASK) + +#define ACL_1M_PACKET_MASK (PACKET_TYPE_DH5_FLAG|\ + PACKET_TYPE_DM5_FLAG|\ + PACKET_TYPE_DH3_FLAG|\ + PACKET_TYPE_DM3_FLAG|\ + PACKET_TYPE_DH1_FLAG|\ + PACKET_TYPE_DM1_FLAG) + +#define ACL_1SLOT_PACKET_MASK (PACKET_TYPE_DH1_FLAG|\ + PACKET_TYPE_DM1_FLAG|\ + PACKET_TYPE_2_DH1_FLAG|\ + PACKET_TYPE_3_DH1_FLAG) + +#define PACKET_TYPE_2_EV3_FLAG 0x0040 +#define PACKET_TYPE_3_EV3_FLAG 0x0080 +#define PACKET_TYPE_2_EV5_FLAG 0x0100 +#define PACKET_TYPE_3_EV5_FLAG 0x0200 +#endif +/* add for spec 1.2 HCI 7.1.26 */ +#define PACKET_TYPE_HV1 0x0001 +#define PACKET_TYPE_HV2 0x0002 +#define PACKET_TYPE_HV3 0x0004 +#define PACKET_TYPE_EV3 0x0008 +#define PACKET_TYPE_EV4 0x0010 +#define PACKET_TYPE_EV5 0x0020 +#define PACKET_TYPE_NO_2_EV3 0x0040 +#define PACKET_TYPE_NO_3_EV3 0x0080 +#define PACKET_TYPE_NO_2_EV5 0x0100 +#define PACKET_TYPE_NO_3_EV5 0x0200 + +#ifdef BLUETOOTH_20//used in set up synchronous link +#define PACKET_TYPE_2_EV3 0x0040 +#define PACKET_TYPE_3_EV3 0x0080 +#define PACKET_TYPE_2_EV5 0x0100 +#define PACKET_TYPE_3_EV5 0x0200 +#endif + +/* Packet Boundary Flag HCI:4.4.3 */ +#define CONT_HL_FRAG 0x01 +#define FIRST_HL_FRAG 0x02 +#define LMP_FRAG 0x03 + +/* Packet Broadcast Flag HCI:4.4.3 */ +#define POINT_TO_POINT 0x00 +#define ACTIVE_BCST 0x01 +#define PICONET_BCST 0x02 + +/* Park mode defines LMP:3.17 */ +#define MACCESS_MSK 0x0F +#define ACCSCHEM_MSK 0xF0 + +/* Device Supported Features defines LMP:5.1.1 */ +#define THREE_SLOT_FEATURE 0x01 +#define FIVE_SLOT_FEATURE 0x02 +#define ENCRYPT_FEATURE 0x04 +#define SLOTOFF_FEATURE 0x08 +#define TIMEACC_FEATURE 0x10 +#define SWITCH_FEATURE 0x20 +#define HOLD_FEATURE 0x40 +#define SNIFF_FEATURE 0x80 + +#define PARK_FEATURE 0x01 +#define RSSI_FEATURE 0x02 +#define QUALITY_FEATURE 0x04 +#define SCO_FEATURE 0x08 +#define HV2_FEATURE 0x10 +#define HV3_FEATURE 0x20 +#define ULAW_FEATURE 0x40 +#define ALAW_FEATURE 0x80 + +//#define EV3_FEATURE 0x20 + + +#define CVSD_FEATURE 0x01 +#define PAGING_FEATURE 0x02 +#define POWER_FEATURE 0x04 +#define TRANSPARENT_FEATURE 0x08 +#define FLOWLEAST_FEATURE 0x10 +#define FLOWMID_FEATURE 0x20 +#define FLOWMOST_FEATURE 0x40 +#define BCENCRYPT_FEATURE 0x80 + +#define ACL_2M_FEATURE 0x02 +#define ACL_3M_FEATURE 0x04 + +#define ENHANCEINQSCAN_FEATURE 0x08 +#define INTERINQSCAN_FEATURE 0x10 +#define INTERPGSCAN_FEATURE 0x20 +#define RSSIINQ_FEATURE 0x40 +#define EV3_FEATURE 0x80 + +#define EV4_FEATURE 0x01 +#define EV5_FEATURE 0x02 +#define AFHCAPSL_FEATURE 0x08 +#define AFHCLASSSL_FEATURE 0x10 +#define ACL_3SLOTS_FEATURE 0x80 + + +#define ACL_5SLOTS_FEATURE 0x01 +#define SNIFF_SUBRATING_FEATURE 0x02 +#define PAUSE_ENCRYPTION_FEATURE 0x04 +#define AFHCAPMS_FEATURE 0x08 +#define AFHCLASSMS_FEATURE 0x10 +#ifdef BLUETOOTH_20 +#define ESCO_2M_FEATURE 0x20 +#define ESCO_3M_FEATURE 0x40 +#define ESCO_3SLOTS_FEATURE 0x80 +#else +#define ESCO_2M_FEATURE 0x00 +#define ESCO_3M_FEATURE 0x00 +#define ESCO_3SLOTS_FEATURE 0x00 +#endif + + +/* Packet and buffer sizes. These sizes do not include payload header (except for FHS */ +/* packet where there is no payload header) since payload header is written or read by */ +/* the BOOST in a different control structure part (TX/RXPHDR) */ +#define FHS_PACKET_SIZE 18 +#define DM1_PACKET_SIZE 17 +#define DH1_PACKET_SIZE 27 +#define DV_ACL_PACKET_SIZE 9 +#define DM3_PACKET_SIZE 121 +#define DH3_PACKET_SIZE 183 +#define DM5_PACKET_SIZE 224 +#define DH5_PACKET_SIZE 339 +#define AUX1_PACKET_SIZE 29 + +#define HV1_PACKET_SIZE 10 +#define HV2_PACKET_SIZE 20 +#define HV3_PACKET_SIZE 30 + +//add by yfwen for BT1.2 eSco packet +#define EV3_PACKET_SIZE 30 +#define EV4_PACKET_SIZE 120 +#define EV5_PACKET_SIZE 180 + +#ifdef BLUETOOTH_20 +#define DH1_2_PACKET_SIZE 54 +#define DH1_3_PACKET_SIZE 83 +#define DH3_2_PACKET_SIZE 367 +#define DH3_3_PACKET_SIZE 552 +#define DH5_2_PACKET_SIZE 679 +#define DH5_3_PACKET_SIZE 1021 + +#define EV3_2_PACKET_SIZE 60 +#define EV3_3_PACKET_SIZE 90 +#define EV5_2_PACKET_SIZE 360 +#define EV5_3_PACKET_SIZE 540 +#endif + + +/* SCO Packet coding LMP:5.1 */ +#define SCO_PACKET_HV1 0x00 +#define SCO_PACKET_HV2 0x01 +#define SCO_PACKET_HV3 0x02 +/* ESCO Packet type coding LMP 5 in spec 1.2 page 437 */ +#define ESCO_PACKET_EV3 0x07 +#define ESCO_PACKET_EV4 0x0C +#define ESCO_PACKET_EV5 0x0D +#define ESCO_PACKET_2EV3 0x26 +#define ESCO_PACKET_3EV3 0x37 +#define ESCO_PACKET_2EV5 0x2C +#define ESCO_PACKET_3EV5 0x3D + +#ifdef BLUETOOTH_20 +#define ESCO_PACKET_2_EV3 0x26 +#define ESCO_PACKET_3_EV3 0x37 +#define ESCO_PACKET_2_EV5 0x2C +#define ESCO_PACKET_3_EV5 0x3D +#endif + +#define MAX_EV3_LENGTH 0x001E +#define MAX_EV4_LENGTH 0x0078 +#define MAX_EV5_LENGTH 0x00B4 +#ifdef BLUETOOTH_20 +#define MAX_2_EV3_LENGTH 0x003C +#define MAX_2_EV5_LENGTH 0x0168 +#define MAX_3_EV3_LENGTH 0x005A +#define MAX_3_EV5_LENGTH 0x021C +#endif + +/* Tsco (ScoInterval) BaseBand:4.4.2.1 */ +#define TSCO_HV1 2 +#define TSCO_HV2 4 +#define TSCO_HV3 6 + +//add by yfwen for BT1.2 eSco packet +#define TESCO_EV3 6 // +#define TESCO_EV4 16 +#define TESCO_EV5 16 + +/* Inquiry train repetition length , Baseband :Table 10.4 */ +/* - 256 repetitions if no SCO */ +/* - 512 repetitions if 1 SCO */ +/* - 768 repetitions if 2 SCO */ +#define INQ_TRAIN_LENGTH_NO_SCO 256 +#define INQ_TRAIN_LENGTH_1_SCO 512 +#define INQ_TRAIN_LENGTH_2_SCO 768 + +/* Counter for train length, Npage (N*16 slots) depends on the slave page scan mode and */ +/* the number of active SCO: */ +/* | SR mode | no SCO | one SCO | two SCO | */ +/* | R0 | >=1 | >=2 | >=3 | */ +/* | R1 | >=128 | >=256 | >=384 | */ +/* | R2 | >=256 | >=512 | >=768 | */ +#define PAGE_TRAIN_LENGTH_R0 1 +#define PAGE_TRAIN_LENGTH_R1 128 +#define PAGE_TRAIN_LENGTH_R2 256 + +/* Baseband timeout default value, Baseband timers: 1.1 */ +#define PAGE_RESP_TO_DEF 8 +#define INQ_RESP_TO_DEF 128 +#define NEW_CONNECTION_TO_DEF 32 + +/* Voice mute pattern defines */ +#define MU_LAW_MUTE 0xFF +#define ALAW_CVSD_MUTE 0x55 + +/* Air Mode LMP:5.1 */ +#define MU_LAW_MODE 0 +#define A_LAW_MODE 1 +#define CVSD_MODE 2 +#define TRANSPARENT_MODE 3 + +/* Timing Control Flags LMP:5.1 */ +#define TIM_CHANGE_FLAG 0x01 +#define INIT2_FLAG 0x02 +#define ACCESS_WIN_FLAG 0x04 + +/* Data Rate defines LMP:5.1 */ +#define FEC_RATE_MSK 0x01 +#define USE_FEC_RATE 0x00 +#define NO_FEC_RATE 0x01 +#define PREF_PACK_MSK 0x06 +#define NO_PREF_PACK_SIZE 0x00 +#define USE_1_SLOT_PACKET 0x02 +#define USE_3_SLOT_PACKET 0x04 +#define USE_5_SLOT_PACKET 0x06 +#define USE_SLOT_MASK 0x06 + +#define USE_DM1_PACKET 0x00 +#define USE_2M_PACKET 0x08 +#define USE_3M_PACKET 0x10 +#define EDR_NO_PREF_PACK_SIZE 0x00 +#define EDR_USE_1_SLOT_PACKET 0x20 +#define EDR_USE_3_SLOT_PACKET 0x40 +#define EDR_USE_5_SLOT_PACKET 0x60 +#define EDR_USE_SLOT_MASK 0x60 + +/* Bluetooth bandwidth */ + +#define BT_8000_BANDWIDTH 0x00001F40 +#define NOT_CARE_WIDTH 0xFFFFFFFF + +/* Voice setting HCI:4.7.29 & 4.7.30 */ +#define INPUT_COD_LIN 0x0000 +#define INPUT_COD_MULAW 0x0100 +#define INPUT_COD_ALAW 0x0200 +#define INPUT_COD_MSK 0x0300 +#define INPUT_DATA_1COMP 0x0000 +#define INPUT_DATA_2COMP 0x0040 +#define INPUT_DATA_SMAG 0x0080 +#define INPUT_DATAFORM_MSK 0x00C0 +#define INPUT_SAMP_8BIT 0x0000 +#define INPUT_SAMP_16BIT 0x0020 +#define INPUT_SAMPSIZE_MSK 0x0020 +#define LIN_PCM_BIT_POS_MSK 0x001C +#define AIR_COD_CVSD 0x0000 +#define AIR_COD_MULAW 0x0001 +#define AIR_COD_ALAW 0x0002 +#define AIR_TRANSPARENT_DATA 0x0003 +#define AIR_COD_MSK 0x0003 + + + +#endif /* __CO_BT_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/cobuf.h b/services/bt_profiles_enhanced/inc/cobuf.h new file mode 100644 index 0000000..75e3fff --- /dev/null +++ b/services/bt_profiles_enhanced/inc/cobuf.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef _COBUF_H +#define _COBUF_H +#include "bt_sys_cfg.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/*must be 4 align*/ +struct cobuf_statistic_packet +{ + unsigned short stat_flag; /*must be 0x5a5a if used, or 0xa5a5 if released*/ + unsigned short alloc_place_id; + unsigned short block_index; + unsigned short realsize; +}; + +struct cobuf_base +{ + struct cobuf_base *link; +#if DBG_COBUF_NEED_STATISTIC == 1 + struct cobuf_statistic_packet statistic; +#endif + unsigned char buf[2]; +}; + +void init_buf( struct cobuf_base **head, + struct cobuf_base *first, + int elm_size, + int buf_num); +unsigned char* alloc_buf(struct cobuf_base **head_ptr); +unsigned char* alloc_buf_infiq(struct cobuf_base **head_ptr); +void free_buf(unsigned char *buf); + +void cobuf_init(void); + +#if DBG_COBUF_NEED_STATISTIC == 1 +#define DBG_COBUF_STATISTIC_PLACE_RECORD_ENABLE 1 +#define DBG_COBUF_STATISTIC_PLACE_RECORD_OPTIMIZE_ENABLE 1 + +unsigned char *_cobuf_malloc_with_statistic(int size, char *module_str, int line); +unsigned char *_cobuf_malloc_with_statistic_infiq(int size, char *module_str, int line); +void _cobuf_free_with_statistic(unsigned char *buf); + +#if BA_GCC==1 +#define __CO_MODULE __func__ +#endif + +#define cobuf_malloc(size) _cobuf_malloc_with_statistic(size,(char *)__CO_MODULE,__LINE__) +#define cobuf_malloc_infiq(size) _cobuf_malloc_with_statistic_infiq(size,(char *)__CO_MODULE,__LINE__) +#define cobuf_free(buf) _cobuf_free_with_statistic(buf); + +#else + +unsigned char *_cobuf_malloc(int size); +unsigned char *_cobuf_malloc_infiq(int size); +void _cobuf_free(unsigned char *buf); +#define cobuf_malloc(size) _cobuf_malloc(size) +#define cobuf_malloc_infiq(size) _cobuf_malloc_infiq(size) +#define cobuf_free(buf) _cobuf_free(buf) + +#endif + +unsigned char *cobuf_zmalloc(int size); +void cobuf_print_statistic(void); +void cobuf_print_block_statistic(void); +void cobuf_print_place_statistic(void); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/services/bt_profiles_enhanced/inc/data_link.h b/services/bt_profiles_enhanced/inc/data_link.h new file mode 100644 index 0000000..2b6850f --- /dev/null +++ b/services/bt_profiles_enhanced/inc/data_link.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __DATA_LINK_H__ +#define __DATA_LINK_H__ + +#include "bt_co_list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum data_link_type { + DL_TYPE_VALUE_U8 = 0, + DL_TYPE_VALUE_U16, + DL_TYPE_VALUE_U32, + DL_TYPE_VALUE_S8, + DL_TYPE_VALUE_S16, + DL_TYPE_VALUE_S32, + DL_TYPE_VALUE_FLOAT, + DL_TYPE_VALUE_DOUBLE, + DL_TYPE_BUFFER, +}; + +struct data_link { + struct list_node node; + enum data_link_type type; + uint32 len; + union { + unsigned char _u8; + unsigned short _u16; + unsigned int _u32; + unsigned char _s8; + unsigned short _s16; + unsigned int _s32; + //float _float; + //double _double; + uint8 *_ptr; + } data; +}; + +#define link_to_tail(data,head) \ + colist_addto_tail(data,head) + +#define iter_data_link(head,node) \ + colist_iterate_entry(node,struct data_link,&head->node,node) + +#define data_link_total_len(head,p) \ + { \ + uint32 _total_len = 0; \ + struct data_link *node = NULL; \ + iter_data_link(head, node) { \ + _total_len += node->len; \ + } \ + *p = _total_len; \ + } + + +#ifdef __cplusplus +} +#endif + +#endif /* __DATA_LINK_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/debug_cfg.h b/services/bt_profiles_enhanced/inc/debug_cfg.h new file mode 100644 index 0000000..7785fd8 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/debug_cfg.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/////////////////////////////////////// +/* For Debug Print Module */ +/* */ +/////////////////////////////////////// + +#define DBG_ERROR_LEVEL 1 +#define DBG_WARNING_LEVEL 2 +#define DBG_INFO_LEVEL 3 + + +/*NEED TO DEFINE OUTPUT METHOD*/ +#define DEBUG_PRINT TRACE + + +/*Moudle list need to set*/ +/*set debug level for each file*/ + +#define a2dp_LEVEL DBG_ERROR_LEVEL +#define avctp_LEVEL DBG_ERROR_LEVEL +#define avdtp_LEVEL DBG_INFO_LEVEL +#define avrcp_LEVEL DBG_ERROR_LEVEL +#define AUDIO_CODEC_LEVEL DBG_ERROR_LEVEL +#define btm_handle_hcievent_LEVEL DBG_ERROR_LEVEL +#define btm_LEVEL DBG_ERROR_LEVEL +#define HCI_LEVEL DBG_INFO_LEVEL +#define hshf_app_LEVEL DBG_ERROR_LEVEL +#define i2s_LEVEL DBG_ERROR_LEVEL +#define l2cap_LEVEL DBG_INFO_LEVEL +#define LC_LEVEL DBG_ERROR_LEVEL +#define LMP_LEVEL DBG_ERROR_LEVEL +#define LMP_UI_LEVEL DBG_ERROR_LEVEL +#define rfcomm_LEVEL DBG_INFO_LEVEL +#define SBC_LEVEL DBG_ERROR_LEVEL +#define sco_LEVEL DBG_ERROR_LEVEL +#define sdp_LEVEL DBG_INFO_LEVEL +#define sdp_client_LEVEL DBG_ERROR_LEVEL +#define sdp_server_LEVEL DBG_INFO_LEVEL +#define spp_app_LEVEL DBG_WARNING_LEVEL +#define sppnew_LEVEL DBG_WARNING_LEVEL + + +/////////////////////////////////////// +/* For Debug cpu use Module */ +/* */ +/////////////////////////////////////// + +#define EXT_LINE_SET_HIGH +#define EXT_LINE_SET_LOW + + diff --git a/services/bt_profiles_enhanced/inc/debug_print.h b/services/bt_profiles_enhanced/inc/debug_print.h new file mode 100644 index 0000000..bddb45d --- /dev/null +++ b/services/bt_profiles_enhanced/inc/debug_print.h @@ -0,0 +1,131 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +/* +usage: + +0.make sure globle cfg control DBG_DEBUG_PRINT_ENABLE is 1 + +1.set your module in your source code file at the top(MUST). + #undef MOUDLE + #define MOUDLE BB + #include "debug_print.h" + +2.define the module debug level in debug_cfg.h, + NOTICE,if no define, then no print + + #define BB_LEVEL INFO_LEVEL + +3.use DEBUG_INFO,DEBUG_WARNING,and DEBUG_ERROR in your module's codes + +4.DEBUG_ASSERT always work. + +*/ +#ifndef __DEBUG_PRINT_H__ +#define __DEBUG_PRINT_H__ + +#include "bt_common.h" +#include "debug_cfg.h" + +#ifdef ENABLE_COMPRESS_LOG +#define TRACE_BTPRF_V(num,str, ...) LOG_VERBOSE(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), str, ##__VA_ARGS_ +#define TRACE_BTPRF_I(num,str, ...) LOG_INFO(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), str, ##__VA_ARGS__) +#define TRACE_BTPRF_W(num,str, ...) LOG_WARN(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), str, ##__VA_ARGS__) +#define TRACE_BTPRF_E(num,str, ...) LOG_ERROR(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), str, ##__VA_ARGS__)__) +#else +#define TRACE_BTPRF_D(num,str, ...) LOG_DEBUG(LOG_MOD(BTPRF), str, ##__VA_ARGS__) +#define TRACE_BTPRF_I(num,str, ...) LOG_INFO(LOG_MOD(BTPRF), str, ##__VA_ARGS__) +#define TRACE_BTPRF_W(num,str, ...) LOG_WARN(LOG_MOD(BTPRF), str, ##__VA_ARGS__) +#define TRACE_BTPRF_E(num,str, ...) LOG_ERROR(LOG_MOD(BTPRF), str, ##__VA_ARGS__) +#endif + +// used for global cfg control, to set if debug_print feature enable +#if DBG_DEBUG_PRINT_ENABLE == 1 + +#define _CONCAT(a, b) a##b +#define CONCAT(a, b) _CONCAT(a, b) +#define _NAME(a) #a +#define NAME(a) _NAME(a) + +#define WHERESTR "[module %s, line %d]: " +#define WHEREARG NAME(MOUDLE), __LINE__ +#define DEBUGPRINT2(num,...) TRACE(num,__VA_ARGS__) + +#define CO_DEBUG_PRINTF(num,level,...) do{ \ + DEBUGPRINT2(num,__VA_ARGS__);\ + }while(0); + + + +#if ( CONCAT(MOUDLE, _LEVEL) >= DBG_INFO_LEVEL ) +#define DEBUG_INFO(num,...) CO_DEBUG_PRINTF(num,"INF", __VA_ARGS__) +#else +#define DEBUG_INFO(...) +#endif + + +#if ( CONCAT(MOUDLE, _LEVEL) >= DBG_WARNING_LEVEL ) +#define DEBUG_WARNING(num,...) CO_DEBUG_PRINTF(num,"WAR", __VA_ARGS__) +#else +#define DEBUG_WARNING(...) +#endif + + +#if ( CONCAT(MOUDLE, _LEVEL) >= DBG_ERROR_LEVEL ) +#define DEBUG_ERROR(num,...) CO_DEBUG_PRINTF(num,"ERR", __VA_ARGS__) +#else +#define DEBUG_ERROR(...) +#endif + +#if 0 +#define DEBUG_ASSERT(expr) do{\ + if (expr)\ + { ; }\ + else \ + {CO_DEBUG_PRINTF("ASSERT","%s",#expr)}\ + }while(0); +#endif + +/*only dump at info level*/ +#if ( CONCAT(MOUDLE, _LEVEL) >= INFO_LEVEL ) +void _debug_print_dump_data(char *mem, int mem_size); +#define DEBUG_DUMP_DATA(memaddr, memlen) do{ \ + DEBUGPRINT2(2,"\r\n" WHERESTR , WHEREARG);\ + DEBUGPRINT2(0,"\r\n");\ + Plt_DUMP8("%02x ", (char *)memaddr,memlen);\ + }while(0); + +#else +#define DEBUG_DUMP_DATA(...) +#endif + + +#define DEBUG_RAW(...) DEBUG_PRINT(__VA_ARGS__) + +#define DEBUG_IMM(...) TRACE_IMM(__VA_ARGS__) + +#else + +#define DEBUG_IMM(...) +#define DEBUG_INFO(...) +#define DEBUG_WARNING(...) +#define DEBUG_ERROR(...) +#define DEBUG_ASSERT(expr) +#define DEBUG_DUMP_DATA(...) +#define DEBUG_RAW(...) +#endif + +#endif /* __DEBUG_PRINT_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/dip.h b/services/bt_profiles_enhanced/inc/dip.h new file mode 100644 index 0000000..7d60289 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/dip.h @@ -0,0 +1,109 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __DIP_H__ +#define __DIP_H__ + +#include "sdp.h" +#include "btlib_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// customize +#if !defined(DIP_VENDOR_ID) +#define DIP_VENDOR_ID 0x02B0 //BesTechnic(Shanghai),Ltd +#endif +#if !defined(DIP_PRODUCT_ID) +#define DIP_PRODUCT_ID 0x0000 +#endif +#if !defined(DIP_PRODUCT_VERSION) +#define DIP_PRODUCT_VERSION 0x001F //0.1.F +#endif + +#define DIP_SPECIFICATION 0x0103 + +// values should keep untouched +#define DIP_VENDID_SOURCE_BTSIG 0x0001 +#define DIP_VENDID_SOURCE_USBIF 0x0002 + +#define ATTRID_SPECIFICATION_ID 0x0200 +#define ATTRID_VENDOR_ID 0x0201 +#define ATTRID_PRODUCT_ID 0x0202 +#define ATTRID_PRODUCT_VERSION 0x0203 +#define ATTRID_PRIMARY_RECORD 0x0204 +#define ATTRID_VENDOR_ID_SOURCE 0x0205 + +enum dip_event { + DIP_EVENT_SDP_REQ_FAIL, + DIP_EVENT_SDP_REQ_SUCCESS, +}; + +enum dip_ctrl_state { + DIP_CTRL_ST_IDLE = 0, + DIP_CTRL_ST_SDP_REQUESTING, +}; + +struct dip_device_info +{ + uint16 spec_id; + uint16 vend_id; + uint16 prod_id; + uint16 prod_ver; + uint8 prim_rec; + uint16 vend_id_source; +}; + +enum dip_sdp_req_fail_reason { + DIP_FAIL_REASON_NO_ERROR = 0, + DIP_FAIL_REASON_SDP_ERROR, + DIP_FAIL_REASON_SDP_CHANNEL_CLOSE, +}; + +struct dip_sdp_req_fail { + enum dip_sdp_req_fail_reason reason; +}; + +struct dip_callback_param { + enum dip_event event; + union { + struct dip_sdp_req_fail fail; + }p; +}; + +struct dip_control_t; +typedef void (*dip_callback_t)(struct dip_control_t *ctrl, struct dip_callback_param *param); + +struct dip_control_t { + struct bdaddr_t remote; + enum dip_ctrl_state state; + struct dip_device_info device_info; + uint8 device_info_valid; + dip_callback_t callback; + struct sdp_request sdp_request; +}; + +int8 dip_register_sdp(void); +int8 dip_deregister_sdp(void); +int8 dip_init(struct dip_control_t *ctrl, dip_callback_t callback); +int8 dip_send_sdp_request(struct dip_control_t *ctrl, struct bdaddr_t *remote); +int8 dip_is_idle(struct dip_control_t *ctrl); + +#ifdef __cplusplus +} +#endif + +#endif /* __DIP_H__ */ diff --git a/services/bt_profiles_enhanced/inc/hci.h b/services/bt_profiles_enhanced/inc/hci.h new file mode 100644 index 0000000..3243320 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/hci.h @@ -0,0 +1,1263 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __HCI_H__ +#define __HCI_H__ + +#include "string.h" +#include "btlib_type.h" +#include "stdint.h" +#include "bt_sys_cfg.h" +#include "hci_buff.h" + +#ifdef IBRT +typedef void (*hci_tx_buf_tss_process_cb_type)(void); +typedef void (*bt_hci_acl_ecc_softbit_handler_func)(uint16_t*,uint16_t*, uint16_t, uint8_t*); +#endif + +typedef enum hci_command_type { + CMD_TYPE_SYNC_GLOBAL_ONLY = 0, + CMD_TYPE_SYNC_CONN_ONLY, + CMD_TYPE_SYNC_MULTI, + CMD_TYPE_FREE, +} hci_command_type_t; + +#define HCI_MAX_PARAM_SIZE 255 +#define HCI_COMMAND_FIFO_SIZE 258 /* size of the transmit fifo */ +/* Packet types : */ +#define HCI_CMD_PACKET 0x01 +#define HCI_ACL_PACKET 0x02 +#define HCI_SCO_PACKET 0x03 +#define HCI_EVT_PACKET 0x04 +#define HCI_BLE_PACKET 0x05//to distinush from acl to ble data +#define HCI_ACL_PACKET_TX 0x12 /* internal: used for trace only */ + +/* HCI_COMMAND_STATUS_EVT_FIXED_SIZE = evtcode (1) + len (1) + status (1) + num packet (1) + opcode (2) */ +#define HCI_COMMAND_STATUS_EVT_FIXED_SIZE 6 + +/* HCI_COMMAND_COMP_EVT_FIXED_SIZE = evtcode (1) + len (1) + num packet (1) + opcode (2) + ... */ +#define HCI_COMMAND_COMP_EVT_FIXED_SIZE 5 + +/* HCI_COMMAND_EVT_FIXED_SIZE = evtcode (1) + len (1) + ... */ +#define HCI_COMMAND_EVT_FIXED_SIZE 2 + +/* HCI_COMMAND_EVT_FIXED_SIZE = evtcode (1) + len (1) + msgclass(1) + msgtag(1) + ... */ +#define HCI_DEBUG_EVT_FIXED_SIZE 4 + +#define HCI_DEBUG_GROUP_CODE 0x3F +#define HCI_DEBUG_PRINT_EVENT_CLASS 0x00 + +/* this variable should be use to perform a control flow for HCI commands */ +#define HCI_NUM_COMMAND_PACKETS 1 + +#define BLE_ACL_DATA_HDR_LEN 5//HCI_ACL_HDR_LEN + HCI_TRANSPORT_HDR_LEN + +#define BLE_ADV_DATA_LENGTH 31 +#define BLE_SCAN_RSP_DATA_LENGTH 31 + + +/****************************************************************************************** + OGF opcodes group define + hence the values +******************************************************************************************/ +#define HCI_OGF_BIT_OFFSET ((INT8U) 10) /* Number of bit shifts */ + + +#define HCI_OPCODE_MASK 0x03FF + + +/****************************************************************************************** + OCF opcode defines +******************************************************************************************/ + +/****************************************************************************************** + OCF opcode defines - Link Control Commands (OGF: 0x01) +******************************************************************************************/ +//#define HCI_INQUIRY 0x0401 +#define HCI_INQUIRY_CANCEL 0x0402 +#define HCI_PERIODIC_INQUIRY_MODE 0x0403 +#define HCI_EXIT_PERIODIC_INQUIRY_MODE 0x0404 +//#define HCI_CREATE_CONNECTION 0x0405 +//#define HCI_DISCONNECT 0x0406 +#define HCI_ADDSCO_CONN 0x0407 +//#define HCI_CREATE_CONNECTION_CANCEL 0x0408 +//#define HCI_ACCEPT_CONNECTION_REQ 0x0409 +//#define HCI_REJECT_CONNECTION_REQ 0x040A +//#define HCI_LINK_KEY_REQ_REPLY 0x040B +//#define HCI_LINK_KEY_REQ_NEG_REPLY 0x040C +//#define HCI_PIN_CODE_REQ_REPLY 0x040D +//#define HCI_PIN_CODE_REQ_NEG_REPLY 0x040E +#define HCI_CHANGE_CONN_PKT_TYPE 0x040F +//#define HCI_AUTH_REQ 0x0411 +//#define HCI_SET_CONN_ENCRYPTION 0x0413 +#define HCI_CHANGE_CONN_LINK_KEY 0x0415 +#define HCI_MASTER_LINK_KEY 0x0417 +//#define HCI_REMOTE_NAME_REQ 0x0419 +//#define HCI_REMOTE_NAME_CANCEL 0x041A +#define HCI_READ_REMOTE_SUP_FEATURES 0x041B +#define HCI_READ_REMOTE_VER_INFO 0x041D +#define HCI_READ_CLOCK_OFFSET 0x041F +#define HCI_READREMOTE_EXT_FEATURES 0x041C +#define HCI_READ_LMP_HANDLE 0x0420 +//#define HCI_SETUP_SYNC_CONN 0x0428 +//#define HCI_ACCEPT_SYNC_CONN 0x0429 +//#define HCI_REJECT_SYNC_CONN 0x042A + +/****************************************************************************************** + OCF opcode defines - Link Policy Commands (OGF 0x02) + ******************************************************************************************/ +#define HCI_HOLD_MODE 0x0801 +#define HCI_PARK_MODE 0x0805 +#define HCI_EXIT_PARK_MODE 0x0806 +//#define HCI_QOS_SETUP 0x0807 +#define HCI_ROLE_DISCOVERY 0x0809 +//#define HCI_SWITCH_ROLE 0x080B +#define HCI_READ_LP_SETTINGS 0x080C //LP:LINK POLICY +#define HCI_READ_DEFAULT_LP_SETTINGS 0x080E +#define HCI_WRITE_DEFAULT_LP_SETTINGS 0x080F +#define HCI_FLOW_SPECIFICATION 0x0810 + +/****************************************************************************************** + OCF opcode defines -Host Controller and Baseband Commands (OGF 0x03) +******************************************************************************************/ +#define HCI_SET_EVENT_MASK 0x0C01 +#define HCI_RESET 0x0C03 +#define HCI_SET_EVENT_FILTER 0x0C05 +#define HCI_FLUSH 0x0C08 +#define HCI_READ_PIN_TYPE 0x0C09 +#define HCI_WRITE_PIN_TYPE 0x0C0A +#define HCI_CREATE_NEW_UNIT_KEY 0x0C0B +//#define HCI_DELETE_STORED_LINK_KEY 0x0C12 +//#define HCI_WRITE_LOCAL_NAME 0x0C13 +#define HCI_READ_LOCAL_NAME 0x0C14 +#define HCI_READ_CONN_ACCEPT_TIMEOUT 0x0C15 +#define HCI_WRITE_CONN_ACCEPT_TIMEOUT 0x0C16 +#define HCI_READ_PAGE_TIMEOUT 0x0C17 +#define HCI_WRITE_PAGE_TIMEOUT 0x0C18 +#define HCI_READ_SCAN_ENABLE 0x0C19 +//#define HCI_WRITE_SCAN_ENABLE 0x0C1A +#define HCI_READ_PAGESCAN_ACTIVITY 0x0C1B +#define HCI_WRITE_PAGESCAN_ACTIVITY 0x0C1C +#define HCI_READ_INQUIRYSCAN_ACTIVITY 0x0C1D +#define HCI_WRITE_INQUIRYSCAN_ACTIVITY 0x0C1E +#define HCI_READ_AUTH_ENABLE 0x0C1F +//#define HCI_WRITE_AUTH_ENABLE 0x0C20 +#define HCI_READ_ENCRY_MODE 0x0C21 +#define HCI_WRITE_ENCRY_MODE 0x0C22 +#define HCI_READ_CLASS_OF_DEVICE 0x0C23 +//#define HCI_WRITE_CLASS_OF_DEVICE 0x0C24 +#define HCI_READ_VOICE_SETTING 0x0C25 +#define HCI_WRITE_VOICE_SETTING 0x0C26 +#define HCI_READ_AUTO_FLUSH_TIMEOUT 0x0C27 +#define HCI_WRITE_AUTO_FLUSH_TIMEOUT 0x0C28 +#define HCI_READ_NUM_BCAST_RETRANSMIT 0x0C29 +#define HCI_WRITE_NUM_BCAST_RETRANSMIT 0x0C2A +#define HCI_READ_HOLD_MODE_ACTIVITY 0x0C2B +#define HCI_WRITE_HOLD_MODE_ACTIVITY 0x0C2C +#define HCI_READ_TX_POWER_LEVEL 0x0C2D +#define HCI_READ_SYNC_FLOW_CON_ENABLE 0x0C2E +#define HCI_WRITE_SYNC_FLOW_CON_ENABLE 0x0C2F +#define HCI_SET_HCTOHOST_FLOW_CONTROL 0x0C31 +#define HCI_HOST_BUFFER_SIZE 0x0C33 +#define HCI_HOST_NUM_COMPLETED_PACKETS 0x0C35 +#define HCI_READ_LINK_SUPERV_TIMEOUT 0x0C36 +//#define HCI_WRITE_LINK_SUPERV_TIMEOUT 0x0C37 +#define HCI_READ_NUM_SUPPORTED_IAC 0x0C38 +#define HCI_READ_CURRENT_IAC_LAP 0x0C39 +#define HCI_WRITE_CURRENT_IAC_LAP 0x0C3A +#define HCI_READ_PAGESCAN_PERIOD_MODE 0x0C3B +#define HCI_WRITE_PAGESCAN_PERIOD_MODE 0x0C3C + +#define HCI_READ_PAGESCAN_MODE 0x0C3D +#define HCI_WRITE_PAGESCAN_MODE 0x0C3E + +#define SET_AFH_HOST_CHL_CLASSFICAT 0x0C3F +#define HCI_READ_INQUIRYSCAN_TYPE 0x0C42 +#define HCI_WRITE_INQUIRYSCAN_TYPE 0x0C43 +#define HCI_READ_INQUIRY_MODE 0x0C44 +#define HCI_WRITE_INQUIRY_MODE 0x0C45 +#define HCI_READ_PAGESCAN_TYPE 0x0C46 +//#define HCI_WRITE_PAGESCAN_TYPE 0x0C47 +#define HCI_READ_AFH_CHL_ASSESS_MODE 0x0C48 +#define HCI_WRITE_AFH_CHL_ASSESS_MODE 0x0C49 +#define HCI_WRITE_EXTENDED_INQ_RESP 0x0C52 +#define HCI_WRITE_SIMPLE_PAIRING_MODE 0x0C56 +#define HCI_READ_DEF_ERR_DATA_REPORTING 0x0C5A +#define HCI_WRITE_DEF_ERR_DATA_REPORTING 0x0C5B + +/****************************************************************************************** + OCF opcode defines -Information Parameters (OGF 0x04) +******************************************************************************************/ +#define HCI_READ_LOCAL_VER_INFO 0x1001 +#define HCI_READ_LOCAL_SUP_COMMANDS 0x1002 +#define HCI_READ_LOCAL_SUP_FEATURES 0x1003 +#define HCI_READ_LOCAL_EXT_FEATURES 0x1004 +#define HCI_READ_BUFFER_SIZE 0x1005 +#define HCI_READ_BD_ADDR 0x1009 + +/****************************************************************************************** + OCF opcode defines -Status Parameters (0GF 0X05) +******************************************************************************************/ +#define HCI_READ_FAILED_CONTACT_COUNT 0x1401 +#define HCI_RESET_FAILED_CONTACT_COUNT 0x1402 +#define HCI_READ_LINK_QUALITY 0x1403 +#define HCI_READ_RSSI 0x1405 +#define HCI_READ_AFH_CHANNEL_MAP 0x1406 +#define HCI_READ_CLOCK 0x1407 + +/****************************************************************************************** + *OCF opcode defines -Testing Commands (OGF 0X06) +******************************************************************************************/ +#define HCI_READ_LOOPBACK_MODE 0x1801 +#define HCI_WRITE_LOOPBACK_MODE 0x1802 +#define HCI_ENABLE_DUT_MODE 0x1803 + +/****************************************************************************************** + *OCF opcode defines -BLE Commands (OGF 0X08) +******************************************************************************************/ +#define HCI_BLE_SET_EVENT_MASK 0x2001 +#define HCI_LE_READ_BUFFER_SIZE 0x2002 + + +/****************************************************************************************** + *OCF opcode defines -Vendor Commands (OGF 0xff) +******************************************************************************************/ + +/* +#define HCI_READ_LMP_PARAM 0x2001 +#define HCI_SET_AFH 0x2002 +#define HCI_SET_BD_ADDR 0x2004 +#define HCI_PRJ_VERSION 0x2005 +#define HCI_GET_PKT_STATICS 0x2006 +#define HCI_READ_MEMORY 0x2007 +#define HCI_WRITE_MEMORY 0x2008 +#define HCI_READ_HW_REGISTER 0x2009 +#define HCI_WRITE_HW_REGISTER 0x200A +#define HCI_TEST_CONTROL 0x200B +#define HCI_SEND_PDU 0x2010 +#define HCI_SET_SCO_CHANNEL 0x2011 +#define HCI_SET_ESCO_CHANNEL 0x2012 +#define HCI_DBG_OPCODE 0x203f +#define HCI_SET_UART_BAUD_RATE 0x2013 +#define HCI_SET_UART_PORT 0x2014 +#define HCI_SET_CLOCK 0x2015 +#define HCI_GET_PKTS_ERR 0x2016 +#define HCI_DEEP_SLEEP 0x2019 +#define HCI_SET_SCOOVER_TYPE 0x201A +#define HCI_GET_SCOOVER_TYPE 0x201B +*/ + +#define HCI_READ_LMP_PARAM 0xFC01 +#define HCI_SET_AFH 0xFC02 +//#define HCI_SET_BD_ADDR 0xFC04 +#define HCI_PRJ_VERSION 0xFC05 +#define HCI_GET_PKT_STATICS 0xFC06 +//#define HCI_READ_MEMORY 0xFC07 +//#define HCI_WRITE_MEMORY 0xFC08 +#define HCI_READ_HW_REGISTER 0xFC09 +#define HCI_WRITE_HW_REGISTER 0xFC0A +#define HCI_TEST_CONTROL 0xFC0B +#define HCI_SEND_PDU 0xFC10 +#define HCI_SET_SCO_CHANNEL 0xFC11 +#define HCI_SET_ESCO_CHANNEL 0xFC12 +#define HCI_DBG_OPCODE 0xFC3f +#define HCI_SET_UART_BAUD_RATE 0xFC13 +#define HCI_SET_UART_PORT 0xFC14 +#define HCI_SET_CLOCK 0xFC15 +#define HCI_GET_PKTS_ERR 0xFC16 +#define HCI_DEEP_SLEEP 0xFC19 +//#define HCI_SET_SCOOVER_TYPE 0xFC1A +#define HCI_SET_SCOOVER_TYPE 0xFC04 +//#define HCI_GET_SCOOVER_TYPE 0xFC1B +#define HCI_GET_SCOOVER_TYPE 0xFC03 + +#define HCI_CONFIG_WRITE 0xFC1C +#define HCI_CONFIG_READ 0xFC1D +#define HCI_CONFIG_FIXED_FREQ 0xFC1E +#define HCI_CONFIG_HOP_FREQ 0xFC1F +#define HCI_GET_IVT_SECCODE 0xfc20 +#define HCI_SET_IVT_SECCODE 0xfc21 +#define HCI_SET_CLK_DBGMODE 0xfc22 +#define HCI_SET_SLAVE_TEST_MODE 0xfc23 + +#define HCI_OGF_VENDOR 0x3f +#define HCI_OCF_CONFIG_WRITE 0x1C +#define HCI_OCF_CONFIG_READ 0x1D + + + +#define HCI_EVTCODE_VENDOR 0xff + + +#define HCI_GET_OGF(val) ((unsigned int)val>>10) +#define HCI_GET_OCF(val) ((unsigned int)val & 0x3ff) +#define HCI_GET_OPCODE(ogf,ocf) ((ogf<<10) + ocf) + +#ifdef HCI_AFH +#define HCI_AFHEvt_Code 0xFD +#define HCI_ChannelEvt_Code 0xFE +#endif + + + + + +/****************************************************************************************** + *OCF opcode defines -Debug Commands (OGF ) +******************************************************************************************/ + +/* LM/HCI Errors */ +#define HCI_ERROR_NO_ERROR 0x00 +#define HCI_ERROR_UNKNOWN_HCI_CMD 0x01 +#define HCI_ERROR_NO_CONNECTION 0x02 +#define HCI_ERROR_HARDWARE_FAILURE 0x03 +#define HCI_ERROR_PAGE_TIMEOUT 0x04 +#define HCI_ERROR_AUTHENTICATE_FAILURE 0x05 +#define HCI_ERROR_MISSING_KEY 0x06 +#define HCI_ERROR_MEMORY_FULL 0x07 +#define HCI_ERROR_CONNECTION_TIMEOUT 0x08 +#define HCI_ERROR_MAX_CONNECTIONS 0x09 +#define HCI_ERROR_MAX_SCO_CONNECTIONS 0x0a +#define HCI_ERROR_ACL_ALREADY_EXISTS 0x0b +#define HCI_ERROR_COMMAND_DISALLOWED 0x0c +#define HCI_ERROR_LIMITED_RESOURCE 0x0d +#define HCI_ERROR_SECURITY_ERROR 0x0e +#define HCI_ERROR_PERSONAL_DEVICE 0x0f +#define HCI_ERROR_HOST_TIMEOUT 0x10 +#define HCI_ERROR_UNSUPPORTED_FEATURE 0x11 +#define HCI_ERROR_INVALID_HCI_PARM 0x12 +#define HCI_ERROR_USER_TERMINATED 0x13 +#define HCI_ERROR_LOW_RESOURCES 0x14 +#define HCI_ERROR_POWER_OFF 0x15 +#define HCI_ERROR_LOCAL_TERMINATED 0x16 +#define HCI_ERROR_REPEATED_ATTEMPTS 0x17 +#define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 +#define HCI_ERROR_UNKNOWN_LMP_PDU 0x19 +#define HCI_ERROR_UNSUPPORTED_REMOTE 0x1a +#define HCI_ERROR_SCO_OFFSET_REJECT 0x1b +#define HCI_ERROR_SCO_INTERVAL_REJECT 0x1c +#define HCI_ERROR_SCO_AIR_MODE_REJECT 0x1d +#define HCI_ERROR_INVALID_LMP_PARM 0x1e +#define HCI_ERROR_UNSPECIFIED_ERR 0x1f +#define HCI_ERROR_UNSUPPORTED_LMP_PARM 0x20 +#define HCI_ERROR_ROLE_CHG_NOT_ALLOWED 0x21 +#define HCI_ERROR_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_ERROR_LMP_TRANS_COLLISION 0x23 +#define HCI_ERROR_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ERROR_ENCRYP_MODE_NOT_ACC 0x25 +#define HCI_ERROR_UNIT_KEY_USED 0x26 +#define HCI_ERROR_QOS_NOT_SUPPORTED 0x27 +#define HCI_ERROR_INSTANT_PASSED 0x28 +#define HCI_ERROR_PAIR_UNITKEY_NO_SUPP 0x29 +#define HCI_ERROR_NOT_FOUND 0xf1 +#define HCI_ERROR_REQUEST_CANCELLED 0xf2 +#define HCI_ERROR_INVALID_SDP_PDU 0xd1 +#define HCI_ERROR_SDP_DISCONNECT 0xd2 +#define HCI_ERROR_SDP_NO_RESOURCES 0xd3 +#define HCI_ERROR_SDP_INTERNAL_ERR 0xd4 +#define HCI_ERROR_STORE_LINK_KEY_ERR 0xe0 + + +/**************************************************************************** + + HCI_COMMAND, Define Parammeter Length + *****************************************************************************/ +#define HCI_INQUIRY_PARAM_LEN ((INT8U) 5) +#define HCI_INQUIRY_CANCEL_PARAM_LEN ((INT8U) 0) +#define HCI_PERIODIC_INQUIRY_MODE_PARAM_LEN ((INT8U) 9) +#define HCI_EXIT_PERIODIC_INQUIRY_MODE_PARAM_LEN ((INT8U) 0) +#define HCI_CREATE_CONNECTION_PARAM_LEN ((INT8U) 13) +#define HCI_DISCONNECT_PARAM_LEN ((INT8U) 3) +#define HCI_ADD_SCO_CONNECTION_PARAM_LEN ((INT8U) 4) +#define HCI_ACCEPT_CONNECTION_REQ_PARAM_LEN ((INT8U) 7) +#define HCI_REJECT_CONNECTION_REQ_PARAM_LEN ((INT8U) 7) +#define HCI_LINK_KEY_REQ_REPLY_PARAM_LEN ((INT8U) 22) +#define HCI_LINK_KEY_REQ_NEG_REPLY_PARAM_LEN ((INT8U) 6) +#define HCI_PIN_CODE_REQ_REPLY_PARAM_LEN ((INT8U) 23) +#define HCI_PIN_CODE_REQ_NEG_REPLY_PARAM_LEN ((INT8U) 6) +#define HCI_CHANGE_CONN_PKT_TYPE_PARAM_LEN ((INT8U) 4) +#define HCI_AUTH_REQ_PARAM_LEN ((INT8U) 2) +#define HCI_SET_CONN_ENCRYPTION_PARAM_LEN ((INT8U) 3) +#define HCI_CHANGE_CONN_LINK_KEY_PARAM_LEN ((INT8U) 2) +#define HCI_MASTER_LINK_KEY_PARAM_LEN ((INT8U) 1) +#define HCI_REMOTE_NAME_REQ_PARAM_LEN ((INT8U) 10) +#define HCI_REMOTE_NAME_REQ_CANCEL_LEN ((INT8U) 6) +#define HCI_READ_REMOTE_SUPP_FEATURES_PARAM_LEN ((INT8U) 2) +#define HCI_READ_REMOTE_SUPP_FEATURES_EXT_LEN ((INT8U) 3) +#define HCI_READ_REMOTE_VER_INFO_PARAM_LEN ((INT8U) 2) +#define HCI_READ_CLOCK_OFFSET_PARAM_LEN ((INT8U) 2) +#define HCI_READ_LMP_HANDLE_PARAM_LEN ((INT8U) 2) +#define HCI_SETUP_SYNC_CONNECTION_PARAM_LEN ((INT8U) 17) +#define HCI_ACCEPT_SYNC_CONNECTION_PARAM_LEN ((INT8U) 21) +#define HCI_REJECT_SYNC_CONNECTION_PARAM_LEN ((INT8U) 7) + +#define HCI_HOLD_MODE_PARAM_LEN ((INT8U) 6) +#define HCI_SNIFF_MODE_PARAM_LEN ((INT8U) 10) +#define HCI_EXIT_SNIFF_MODE_PARAM_LEN ((INT8U) 2) +#define HCI_PARK_MODE_PARAM_LEN ((INT8U) 6) +#define HCI_EXIT_PARK_MODE_PARAM_LEN ((INT8U) 2) +#define HCI_QOS_SETUP_PARAM_LEN ((INT8U) 20) +#define HCI_ROLE_DISCOVERY_PARAM_LEN ((INT8U) 2) +#define HCI_SWITCH_ROLE_PARAM_LEN ((INT8U) 7) +#define HCI_READ_LINK_POLICY_SETTINGS_PARAM_LEN ((INT8U) 2) +#define HCI_WRITE_LINK_POLICY_SETTINGS_PARAM_LEN ((INT8U) 4) +#define HCI_READ_DEF_LP_SETTINGS_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_DEF_LP_SETTINGS_PARAM_LEN ((INT8U) 2) + +#define HCI_SET_EVENT_MASK_PARAM_LEN ((INT8U) 8) +#define HCI_RESET_PARAM_LEN ((INT8U) 0) +#define HCI_SET_EVENT_FILTER_PARAM_LEN ((INT8U) 8) /* Variable */ +#define HCI_FLUSH_PARAM_LEN ((INT8U) 2) +#define HCI_READ_PIN_TYPE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_PIN_TYPE_PARAM_LEN ((INT8U) 1) +#define HCI_CREATE_NEW_UNIT_KEY_PARAM_LEN ((INT8U) 0) +#define HCI_READ_STORED_LINK_KEY_PARAM_LEN ((INT8U) 7) +#define HCI_WRITE_STORED_LINK_KEY_PARAM_LEN ((INT8U) 23) /* Variable */ +#define HCI_DELETE_STORED_LINK_KEY_PARAM_LEN ((INT8U) 7) +#define HCI_CHANGE_LOCAL_NAME_PARAM_LEN ((INT8U) 248) +#define HCI_READ_LOCAL_NAME_PARAM_LEN ((INT8U) 0) +#define HCI_READ_CONN_ACCEPT_TIMEOUT_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_CONN_ACCEPT_TIMEOUT_PARAM_LEN ((INT8U) 2) +#define HCI_READ_PAGE_TIMEOUT_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_PAGE_TIMEOUT_PARAM_LEN ((INT8U) 2) +#define HCI_READ_SCAN_ENABLE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_SCAN_ENABLE_PARAM_LEN ((INT8U) 1) +#define HCI_READ_PAGESCAN_ACTIVITY_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_PAGESCAN_ACTIVITY_PARAM_LEN ((INT8U) 4) +#define HCI_READ_INQUIRYSCAN_ACTIVITY_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_INQUIRYSCAN_ACTIVITY_PARAM_LEN ((INT8U) 4) +#define HCI_READ_AUTH_ENABLE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_AUTH_ENABLE_PARAM_LEN ((INT8U) 1) +#define HCI_READ_ENC_MODE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_ENC_MODE_PARAM_LEN ((INT8U) 1) +#define HCI_READ_CLASS_OF_DEVICE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_CLASS_OF_DEVICE_PARAM_LEN ((INT8U) 3) +#define HCI_READ_VOICE_SETTING_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_VOICE_SETTING_PARAM_LEN ((INT8U) 2) +#define HCI_READ_AUTO_FLUSH_TIMEOUT_PARAM_LEN ((INT8U) 2) +#define HCI_WRITE_AUTO_FLUSH_TIMEOUT_PARAM_LEN ((INT8U) 4) +#define HCI_READ_NUM_BCAST_RETXS_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_NUM_BCAST_RETXS_PARAM_LEN ((INT8U) 1) +#define HCI_READ_HOLD_MODE_ACTIVITY_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_HOLD_MODE_ACTIVITY_PARAM_LEN ((INT8U) 1) +#define HCI_READ_TX_POWER_LEVEL_PARAM_LEN ((INT8U) 3) +#define HCI_READ_SYNC_FLOW_CON_ENABLE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_SYNC_FLOW_CON_ENABLE_PARAM_LEN ((INT8U) 1) +#define HCI_SET_HCTOHOST_FLOW_CONTROL_PARAM_LEN ((INT8U) 1) +#define HCI_HOST_BUFFER_SIZE_PARAM_LEN ((INT8U) 7) +#define HCI_HOST_NUM_COMPLETED_PACKETS_PARAM_LEN ((INT8U) 5) /* Variable */ +#define HCI_READ_LINK_SUPERV_TIMEOUT_PARAM_LEN ((INT8U) 2) +#define HCI_WRITE_LINK_SUPERV_TIMEOUT_PARAM_LEN ((INT8U) 4) +#define HCI_READ_NUM_SUPPORTED_IAC_PARAM_LEN ((INT8U) 0) +#define HCI_READ_CURRENT_IAC_LAP_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_CURRENT_IAC_LAP_PARAM_LEN ((INT8U) 4) /* Variable */ +#define HCI_READ_PAGESCAN_PERIOD_MODE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_PAGESCAN_PERIOD_MODE_PARAM_LEN ((INT8U) 1) +#define HCI_READ_PAGESCAN_MODE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_PAGESCAN_MODE_PARAM_LEN ((INT8U) 1) + +#define HCI_READ_INQUIRYSCAN_TYPE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_INQUIRYSCAN_TYPE_PARAM_LEN ((INT8U) 1) +#define HCI_READ_INQUIRY_MODE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_INQUIRY_MODE_PARAM_LEN ((INT8U) 1) + +#define HCI_READ_AFH_CHANNEL_ASSESSMENT_MODE_LEN ((INT8U) 0) +#define HCI_WRITE_AFH_CHANNEL_ASSESSMENT_MODE_LEN ((INT8U) 1) + + +#define HCI_READ_LOCAL_VER_INFO_PARAM_LEN ((INT8U) 0) +#define HCI_READ_LOCAL_SUPP_CMD_PARAM_LEN ((INT8U) 0) +#define HCI_READ_LOCAL_SUPP_FEATURES_PARAM_LEN ((INT8U) 0) +#define HCI_READ_LOCAL_FEATURES_EXT_PARAM_LEN ((INT8U) 1) +#define HCI_READ_BUFFER_SIZE_PARAM_LEN ((INT8U) 0) +#define HCI_READ_COUNTRY_CODE_PARAM_LEN ((INT8U) 0) +#define HCI_READ_BD_ADDR_PARAM_LEN ((INT8U) 0) + +#define HCI_READ_FAILED_CONTACT_COUNT_PARAM_LEN ((INT8U) 2) +#define HCI_RESET_FAILED_CONTACT_COUNT_PARAM_LEN ((INT8U) 2) +#define HCI_GET_LINK_QUALITY_PARAM_LEN ((INT8U) 2) +#define HCI_READ_RSSI_PARAM_LEN ((INT8U) 2) +#define HCI_READ_AFH_CHANNEL_MAP_PARAM_LEN ((INT8U) 2) +#define HCI_READ_CLOCK_PARAM_LEN ((INT8U) 3) + +#define HCI_READ_LOOPBACK_MODE_PARAM_LEN ((INT8U) 0) +#define HCI_WRITE_LOOPBACK_MODE_PARAM_LEN ((INT8U) 1) +#define HCI_ENABLE_DUT_MODE_PARAM_LEN ((INT8U) 0) + +#define HCI_DEBUG_REQUEST_PARAM_LEN ((INT8U) 2) + + +/****************************************************************************** + Event Parameter Lengths + *****************************************************************************/ +#define HCI_EV_INQUIRY_COMPLETE_PARAM_LEN ((INT8U) 1) +#define HCI_EV_INQUIRY_RESULT_PARAM_LEN ((INT8U) 15) /* Variable */ +#define HCI_EV_CONN_COMPLETE_PARAM_LEN ((INT8U) 11) +#define HCI_EV_CONN_REQUEST_PARAM_LEN ((INT8U) 10) +#define HCI_EV_DISCONNECT_COMPLETE_PARAM_LEN ((INT8U) 4) +#define HCI_EV_AUTH_COMPLETE_PARAM_LEN ((INT8U) 3) +#define HCI_EV_REMOTE_NAME_REQ_COMPLETE_MAX_LEN ((INT8U) 255) +#define HCI_EV_REMOTE_NAME_REQ_COMPLETE_BASIC_LEN ((INT8U) 7) +#define HCI_EV_ENCRYPTION_CHANGE_PARAM_LEN ((INT8U) 4) +#define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE_PARAM_LEN ((INT8U) 3) +#define HCI_EV_MASTER_LINK_KEY_COMPLETE_PARAM_LEN ((INT8U) 4) +#define HCI_EV_READ_REM_SUPP_FEATURES_COMPLETE_PARAM_LEN ((INT8U) 11) +#define HCI_EV_READ_REMOTE_VER_INFO_COMPLETE_PARAM_LEN ((INT8U) 8) +#define HCI_EV_QOS_SETUP_COMPLETE_PARAM_LEN ((INT8U) 21) +#define HCI_EV_COMMAND_COMPLETE_PARAM_LEN ((INT8U) 3) /* Variable see below */ +#define HCI_EV_COMMAND_STATUS_PARAM_LEN ((INT8U) 4) +#define HCI_EV_HARDWARE_ERROR_PARAM_LEN ((INT8U) 1) +#define HCI_EV_FLUSH_OCCURRED_PARAM_LEN ((INT8U) 2) +#define HCI_EV_ROLE_CHANGE_PARAM_LEN ((INT8U) 8) +#define HCI_EV_NUMBER_COMPLETED_PKTS_PARAM_LEN ((INT8U) 5) /* Variable */ +#define HCI_EV_MODE_CHANGE_PARAM_LEN ((INT8U) 6) +#define HCI_EV_RETURN_LINK_KEYS_PARAM_LEN ((INT8U) 23) /* Variable */ +#define HCI_EV_PIN_CODE_REQ_PARAM_LEN ((INT8U) 6) +#define HCI_EV_LINK_KEY_REQ_PARAM_LEN ((INT8U) 6) +#define HCI_EV_LINK_KEY_NOTIFICATION_PARAM_LEN ((INT8U) 23) +#define HCI_EV_LOOPBACK_COMMAND_PARAM_LEN ((INT8U) 0) /* Variable */ +#define HCI_EV_DATA_BUFFER_OVERFLOW_PARAM_LEN ((INT8U) 1) +#define HCI_EV_MAX_SLOTS_CHANGE_PARAM_LEN ((INT8U) 3) +#define HCI_EV_READ_CLOCK_OFFSET_COMPLETE_PARAM_LEN ((INT8U) 5) +#define HCI_EV_CONN_PACKET_TYPE_CHANGED_PARAM_LEN ((INT8U) 5) +#define HCI_EV_QOS_VIOLATION_PARAM_LEN ((INT8U) 2) +#define HCI_EV_PAGE_SCAN_MODE_CHANGE_PARAM_LEN ((INT8U) 7) +#define HCI_EV_PAGE_SCAN_REP_MODE_CHANGE_PARAM_LEN ((INT8U) 7) +#define HCI_EV_DEBUG_PARAM_LEN ((INT8U) 20 ) + + +/****************************************************************************** + HCI_COMMAND_COMPLETE, Argument Length Definitions (not full length) + 3 From Command Complete + Return Parameters. + When an argument length is dependant on the number of elements in the array + the defined length contains the constant parameter lengths only. The full + array length must be calculated. + *****************************************************************************/ +#define HCI_INQUIRY_CANCEL_ARG_LEN ((INT8U) 1) +#define HCI_PERIODIC_INQ_MODE_ARG_LEN ((INT8U) 1) +#define HCI_EXIT_PERIODIC_INQ_MODE_ARG_LEN ((INT8U) 1) +#define HCI_CREATE_CONN_CANCEL_ARG_LEN ((INT8U) 6) +#define HCI_LINK_KEY_REQ_REPLY_ARG_LEN ((INT8U) 7) +#define HCI_LINK_KEY_REQ_NEG_REPLY_ARG_LEN ((INT8U) 7) +#define HCI_PIN_CODE_REQ_REPLY_ARG_LEN ((INT8U) 7) +#define HCI_PIN_CODE_REQ_NEG_REPLY_ARG_LEN ((INT8U) 7) +#define HCI_ROLE_DISCOVERY_ARG_LEN ((INT8U) 4) +#define HCI_READ_LINK_POLICY_SETTINGS_ARG_LEN ((INT8U) 5) +#define HCI_WRITE_LINK_POLICY_SETTINGS_ARG_LEN ((INT8U) 3) +#define HCI_SET_SNIFF_SUBRATING_SETTINGS_ARG_LEN ((INT8U) 3) +#define HCI_SET_EVENT_MASK_ARG_LEN ((INT8U) 1) +#define HCI_RESET_ARG_LEN ((INT8U) 1) +#define HCI_SET_EVENT_FILTER_ARG_LEN ((INT8U) 1) +#define HCI_FLUSH_ARG_LEN ((INT8U) 4) +#define HCI_READ_PIN_TYPE_ARG_LEN ((INT8U) 2) +#define HCI_WRITE_PIN_TYPE_ARG_LEN ((INT8U) 1) +#define HCI_CREATE_NEW_UNIT_KEY_ARG_LEN ((INT8U) 1) +#define HCI_READ_STORED_LINK_KEY_ARG_LEN ((INT8U) 5) +#define HCI_WRITE_STORED_LINK_KEY_ARG_LEN ((INT8U) 2) +#define HCI_DELETE_STORED_LINK_KEY_ARG_LEN ((INT8U) 3) +#define HCI_CHANGE_LOCAL_NAME_ARG_LEN ((INT8U) 1) +#define HCI_READ_LOCAL_NAME_ARG_LEN ((INT8U) 249) +#define HCI_READ_CONN_ACCEPT_TIMEOUT_ARG_LEN ((INT8U) 3) +#define HCI_WRITE_CONN_ACCEPT_TIMEOUT_ARG_LEN ((INT8U) 1) +#define HCI_READ_PAGE_TIMEOUT_ARG_LEN ((INT8U) 3) +#define HCI_WRITE_PAGE_TIMEOUT_ARG_LEN ((INT8U) 1) +#define HCI_READ_SCAN_ENABLE_ARG_LEN ((INT8U) 2) +#define HCI_WRITE_SCAN_ENABLE_ARG_LEN ((INT8U) 1) +#define HCI_READ_PAGESCAN_ACTIVITY_ARG_LEN ((INT8U) 5) +#define HCI_WRITE_PAGESCAN_ACTIVITY_ARG_LEN ((INT8U) 1) +#define HCI_READ_INQUIRYSCAN_ACTIVITY_ARG_LEN ((INT8U) 5) +#define HCI_WRITE_INQUIRYSCAN_ACTIVITY_ARG_LEN ((INT8U) 1) +#define HCI_READ_AUTH_ENABLE_ARG_LEN ((INT8U) 2) +#define HCI_WRITE_AUTH_ENABLE_ARG_LEN ((INT8U) 1) +#define HCI_READ_ENC_MODE_ARG_LEN ((INT8U) 2) +#define HCI_WRITE_ENC_MODE_ARG_LEN ((INT8U) 1) +#define HCI_READ_CLASS_OF_DEVICE_ARG_LEN ((INT8U) 4) +#define HCI_WRITE_CLASS_OF_DEVICE_ARG_LEN ((INT8U) 1) +#define HCI_READ_VOICE_SETTING_ARG_LEN ((INT8U) 3) +#define HCI_WRITE_VOICE_SETTING_ARG_LEN ((INT8U) 1) +#define HCI_READ_AUTO_FLUSH_TIMEOUT_ARG_LEN ((INT8U) 5) +#define HCI_WRITE_AUTO_FLUSH_TIMEOUT_ARG_LEN ((INT8U) 3) +#define HCI_READ_NUM_BCASTXS_ARG_LEN ((INT8U) 2) +#define HCI_WRITE_NUM_BCASTXS_ARG_LEN ((INT8U) 1) +#define HCI_READ_HOLD_MODE_ACTIVITY_ARG_LEN ((INT8U) 2) +#define HCI_WRITE_HOLD_MODE_ACTIVITY_ARG_LEN ((INT8U) 1) +#define HCI_READ_TX_POWER_LEVEL_ARG_LEN ((INT8U) 4) +#define HCI_READ_SCO_FLOW_CON_ENABLE_ARG_LEN ((INT8U) 2) +#define HCI_WRITE_SCO_FLOW_CON_ENABLE_ARG_LEN ((INT8U) 1) +#define HCI_SET_HC_TO_H_FLOW_CONTROL_ARG_LEN ((INT8U) 1) +#define HCI_HOST_BUFFER_SIZE_ARG_LEN ((INT8U) 1) +#define HCI_HOST_NUM_COMPLETED_PKTS_ARG_LEN ((INT8U) 1) +#define HCI_READ_LINK_SUPERV_TIMEOUT_ARG_LEN ((INT8U) 5) +#define HCI_WRITE_LINK_SUPERV_TIMEOUT_ARG_LEN ((INT8U) 3) +#define HCI_READ_NUM_SUPPORTED_IAC_ARG_LEN ((INT8U) 2) +#define HCI_READ_CURRENT_IAC_LAP_ARG_LEN ((INT8U) 5) /* Variable */ +#define HCI_WRITE_CURRENT_IAC_LAP_ARG_LEN ((INT8U) 1) +#define HCI_READ_PAGESCAN_PERIOD_MODE_ARG_LEN ((INT8U) 2) +#define HCI_WRITE_PAGESCAN_PERIOD_MODE_ARG_LEN ((INT8U) 1) +#define HCI_READ_PAGESCAN_MODE_ARG_LEN ((INT8U) 2) +#define HCI_WRITE_PAGESCAN_MODE_ARG_LEN ((INT8U) 1) +#define HCI_READ_INQUIRYSCAN_TYPE_ARG_LEN ((INT8U) 2) /* Add for spec 1.2 */ +#define HCI_WRITE_INQUIRYSCAN_TYPE_ARG_LEN ((INT8U) 1) /* Add for spec 1.2 */ +#define HCI_READ_INQUIRY_MODE_ARG_LEN ((INT8U) 2) /* Add for spec 1.2 */ +#define HCI_WRITE_INQUIRY_MODE_ARG_LEN ((INT8U) 1) /* Add for spec 1.2 */ + + +#define HCI_READ_LOCAL_VER_INFO_ARG_LEN ((INT8U) 9) +#define HCI_READ_LOCAL_FEATURES_LEN ((INT8U) 9) +#define HCI_READ_BUFFER_SIZE_ARG_LEN ((INT8U) 8) +#define HCI_READ_COUNTRY_CODE_ARG_LEN ((INT8U) 2) +#define HCI_READ_BD_ADDR_ARG_LEN ((INT8U) 7) +#define HCI_READ_FAILED_CONTACT_COUNT_ARG_LEN ((INT8U) 5) +#define HCI_RESET_FAILED_CONTACT_COUNT_ARG_LEN ((INT8U) 3) +#define HCI_GET_LINK_QUALITY_ARG_LEN ((INT8U) 4) +#define HCI_READ_RSSI_ARG_LEN ((INT8U) 4) +#define HCI_READ_LOOPBACK_MODE_ARG_LEN ((INT8U) 2) +#define HCI_WRITE_LOOPBACK_MODE_ARG_LEN ((INT8U) 1) +#define HCI_ENABLE_DUT_ARG_LEN ((INT8U) 1) +#define HCI_MNFR_EXTENSION_ARG_LEN ((INT8U) 1) + + +/*HCI_CMD_PACKET: 0x01 + opcode(2 bytes)+length(1 byte)+data[255]*/ + + +struct hci_cmd_packet +{ + struct list_node node; + uint8 misc_data; /* to adjust with lmp_handle_msg */ + uint8 cmd_flag; /*must be 0x01*/ + uint16 opcode; + uint16 handle; + uint8 length; + uint8 data[1]; +} __attribute__ ((packed)); + +struct hci_acl_packet +{ + INT16U conn_handle; + INT16U length; + INT8U *data; +} __attribute__ ((packed)); +struct hci_sco_packet +{ + INT16U conn_handle; + INT8U length; + INT8U *data; +} __attribute__ ((packed)); + + +struct hci_evt_packet +{ + uint8 evt_flag; /*must be 0x04*/ + uint8 evt_code; + uint8 length; + uint8 data[1]; +} __attribute__ ((packed)); + + +#define HCI_INQUIRY 0x0401 + +struct hci_cp_inquiry +{ + uint8 lap[3]; + uint8 length; + uint8 num_rsp; +} __attribute__ ((packed)); + +#define HCI_CREATE_CONNECTION 0x0405 +struct hci_cp_create_conn +{ + struct bdaddr_t bdaddr; + uint16 pkt_type; + uint8 page_scan_repetition_mode; + uint8 reserved; + uint16 clk_off; + uint8 allow_role_switch; +} __attribute__ ((packed)); + +#define HCI_DISCONNECT 0x0406 +struct hci_cp_disconnect +{ + uint16 handle; + uint8 reason; +} __attribute__ ((packed)); + +#define HCI_ADDSCO_CONN 0x0407 +struct hci_cp_addsco_conn +{ + uint16 conn_handle; + uint16 pkt_type; +} __attribute__ ((packed)); + +#define HCI_CREATE_CONNECTION_CANCEL 0x0408 +struct hci_create_connection_cancel +{ + struct bdaddr_t bdaddr; +} __attribute__ ((packed)); + +#define HCI_ACCEPT_CONNECTION_REQ 0x0409 +struct hci_cp_accept_conn_req +{ + struct bdaddr_t bdaddr; + + uint8 role; +} __attribute__ ((packed)); + +#define HCI_REJECT_CONNECTION_REQ 0x040A +struct hci_cp_reject_conn_req +{ + struct bdaddr_t bdaddr; + uint8 reason; +} __attribute__ ((packed)); +#define HCI_LINK_KEY_REQ_REPLY 0x040B +struct hci_cp_link_key_reply +{ + struct bdaddr_t bdaddr; + uint8 link_key[16]; +} __attribute__ ((packed)); + +#define HCI_LINK_KEY_REQ_NEG_REPLY 0x040C +struct hci_cp_link_key_neg_reply +{ + struct bdaddr_t bdaddr; +} __attribute__ ((packed)); + +#define HCI_PIN_CODE_REQ_REPLY 0x040D +struct hci_cp_pin_code_reply +{ + struct bdaddr_t bdaddr; + uint8 pin_len; + uint8 pin_code[16]; +} __attribute__ ((packed)); + +#define HCI_PIN_CODE_REQ_NEG_REPLY 0x040E +struct hci_cp_pin_code_neg_reply +{ + struct bdaddr_t bdaddr; +} __attribute__ ((packed)); +#define HCI_CHANGE_CONN_PKT_TYPE 0x040F +struct hci_cp_change_conn_pkt_type +{ + uint16 conn_handle; + uint16 pkt_type; +} __attribute__ ((packed)); + + +#define HCI_AUTH_REQ 0x0411 +struct hci_cp_auth_req +{ + uint16 conn_handle; +} __attribute__ ((packed)); + +#define HCI_SET_CONN_ENCRYPTION 0x0413 +struct hci_cp_set_conn_encryption +{ + uint16 conn_handle; + uint8 encryption_enable; +} __attribute__ ((packed)); + + +#define HCI_REMOTE_NAME_REQ 0x0419 +struct hci_cp_remote_name_request +{ + struct bdaddr_t bdaddr; + uint8 page_scan_repetition_mode; + uint8 reserved; + uint16 clk_off; +} __attribute__ ((packed)); + +#define HCI_REMOTE_NAME_CANCEL 0x041A +struct hci_cp_remote_name_cancel +{ + struct bdaddr_t bdaddr; +} __attribute__ ((packed)); + +#define HCI_REMOTE_SUPPORTED_FEATURES 0x041B +struct hci_cp_remote_supported_feat +{ + uint16 conn_handle; +} __attribute__ ((packed)); + +#define HCI_REMOTE_EXTENDED_FEATURES 0x041C +struct hci_cp_remote_extended_feat +{ + uint16 conn_handle; + uint8 page_num; +} __attribute__ ((packed)); + +#define HCI_REMOTE_VERSION_INFO 0x041D +struct hci_cp_remote_version_info +{ + uint16 conn_handle; +} __attribute__ ((packed)); + +#define HCI_SETUP_SYNC_CONN 0x0428 +struct hci_cp_setup_sync_conn +{ + uint16 conn_handle; + uint32 tx_bandwidth; + uint32 rx_bandwidth; + uint16 max_latency; + uint16 voice_setting; + uint8 retx_effort; + uint16 pkt_type; +} __attribute__ ((packed)); + +#define HCI_ACCEPT_SYNC_CONN 0x0429 +struct hci_cp_accept_sync_conn +{ + struct bdaddr_t bdaddr; + uint32 tx_bandwidth; + uint32 rx_bandwidth; + uint16 max_latency; + uint16 voice_setting; + uint8 retx_effort; + uint16 pkt_type; +} __attribute__ ((packed)); + + +#define HCI_REJECT_SYNC_CONN 0x042A +struct hci_cp_reject_sync_conn +{ + struct bdaddr_t bdaddr; + uint8 reason; +} __attribute__ ((packed)); + +#define HCI_IO_CAPABILIRY_RESPONSE 0x042B +struct hci_cp_io_capability_request_reply +{ + struct bdaddr_t bdaddr; + uint8 io_caps; + uint8 oob_present; + uint8 auth_requirements; +}__attribute__ ((packed)); + +#define HCI_IO_CAPABILIRY_NEGATIVE_REPLY 0x0434 +struct hci_cp_io_capability_negative_reply +{ + struct bdaddr_t bdaddr; + uint8 reason; +}__attribute__ ((packed)); + +#define HCI_USER_CONFIRMATION_REPLY 0x042C +#define HCI_USER_CONFIRMATION_NEG_REPLY 0x042D +struct hci_cp_usr_confirmation_reply +{ + struct bdaddr_t bdaddr; +}__attribute__ ((packed)); + +#define HCI_SNIFF_MODE 0x0803 +struct hci_cp_sniff_mode +{ + uint16 conn_handle; + uint16 sniff_max_interval; + uint16 sniff_min_interval; + uint16 sniff_attempt; + uint16 sniff_timeout; +} __attribute__ ((packed)); + +#define HCI_EXIT_SNIFF_MODE 0x0804 +struct hci_cp_exit_sniff_mode +{ + uint16 conn_handle; +} __attribute__ ((packed)); + +#define HCI_QOS_SETUP 0x0807 +struct hci_qos_setup +{ + uint16 conn_handle; + uint8 unused; + uint8 service_type; + uint32 token_rate; + uint32 peak_bandwidth; + uint32 latency; + uint32 delay_variation; +} __attribute__ ((packed)); + +#define HCI_ROLE_DISCOVERY 0x0809 +struct hci_write_role_discovery +{ + uint16 conn_handle; +} __attribute__ ((packed)); + +#define HCI_SWITCH_ROLE 0x080B +struct hci_witch_role +{ + struct bdaddr_t bdaddr; + uint8 role; +} __attribute__ ((packed)); + +#define HCI_WRITE_LP_SETTINGS 0x080D +struct hci_cp_write_link_policy +{ + uint16 conn_handle; + uint16 link_policy_settings; +} __attribute__ ((packed)); + +#define HCI_SNIFF_SUBRATING 0x0811 +struct hci_cp_sniff_subrating +{ + uint16 conn_handle; + uint16 maximum_lantency; + uint16 minimum_remote_timeout; + uint16 minimum_local_timeout; +} __attribute__ ((packed)); + + +#define HCI_WRITE_SCAN_ENABLE 0x0C1A +struct hci_cp_write_scan_enable +{ + uint8 scan_enable; +} __attribute__ ((packed)); + +#define HCI_WRITE_CLASS_OF_DEVICE 0x0C24 +struct hci_cp_write_class_of_device +{ + uint8 class_dev[3]; +} __attribute__ ((packed)); + +#define HCI_WRITE_LOCAL_NAME 0x0C13 +struct hci_cp_write_local_name +{ + uint8 local_name[BTM_NAME_MAX_LEN]; +} __attribute__ ((packed)); + +// HCI_WRITE_EXTENDED_INQ_RESP +struct hci_write_extended_inquiry_response +{ + uint8 fec; + uint8 eir[240]; +} __attribute__ ((packed)); + +#define HCI_LOWLAYER_MONITOR 0xFC9b +struct hci_cp_lowlayer_monitor +{ + uint16 conn_handle; + uint8 control_flag; + uint8 report_format; + uint32 data_format; + uint8 report_unit; +} __attribute__ ((packed)); + +#define HCI_READ_STORED_LINK_KEY 0x0C0D +struct hci_cp_read_stored_linkkey +{ + struct bdaddr_t bdaddr; + uint8 read_all_flag; +} __attribute__ ((packed)); + +#define HCI_WRITE_STORED_LINK_KEY 0x0C11 +#define HCI_HS_STORED_LINK_KEY 0x201C // +struct hci_cp_write_stored_linkkey +{ + uint8 num_keys_to_write; + struct bdaddr_t bdaddr; + uint8 link_key[16]; +} __attribute__ ((packed)); + +#define HCI_DELETE_STORED_LINK_KEY 0x0C12 +struct hci_cp_delete_stored_linkkey +{ + struct bdaddr_t bdaddr; + uint8 delete_all_flag; +} __attribute__ ((packed)); + +#define HCI_WRITE_AUTH_ENABLE 0x0C20 +struct hci_cp_write_auth_enable +{ + uint8 enable_flag; +} __attribute__ ((packed)); + + +#define HCI_SET_BD_ADDR 0xFC72 +struct hci_cp_set_bdaddr +{ + uint8 addr_type; /* 0 bt, 1 ble */ + struct bdaddr_t bdaddr; +} __attribute__ ((packed)); + +#define HCI_WRITE_MEMORY 0xFC02 +struct hci_cp_write_memory +{ + uint32 address; + uint8 type; + uint8 length; + uint32 value; +} __attribute__ ((packed)); + +#define HCI_READ_MEMORY 0xFC01 +struct hci_cp_read_memory +{ + uint32 address; + uint8 type; + uint8 length; +} __attribute__ ((packed)); + +#define HCI_WRITE_CURRENT_IAC_LAP 0x0C3A +struct hci_write_current_iac_lap +{ + uint8 iac_lap[4]; +} __attribute__ ((packed)); + + +#define HCI_WRITE_INQSCAN_TYPE 0x0C43 +struct hci_write_inqscan_type +{ + uint8 inqscan_type; +} __attribute__ ((packed)); + +#define HCC_DBG_WRITE_SLEEP_EXWAKEUP_EN 0xFC77 + + +#define HCI_WRITE_INQ_MODE 0x0C45 +struct hci_write_inqmode +{ + uint8 inqmode; +} __attribute__ ((packed)); + +#define HCI_WRITE_PAGESCAN_TYPE 0x0C47 +struct hci_write_pagescan_type +{ + uint8 pagescan_type; +} __attribute__ ((packed)); + +//set sco path +#define HCI_DBG_SET_SYNC_CONFIG_CMD_OPCODE 0xFC8F +#define HCC_DBG_SET_SCO_SWITCH 0xFC89 + +#define HCI_DBG_SET_SYNC_CONFIG_CMD_OPCODE_OLD_VER 0xFC51 +#define HCC_DBG_SET_SCO_SWITCH_OLD_VER 0xFC62 + +struct hci_set_switch_sco +{ + uint16 sco_handle; +} __attribute__ ((packed)); + +#define HCI_DBG_SCO_TX_SILENCE_CMD_OPCODE 0xFC94 +struct hci_dbg_sco_tx_silence_cmd +{ + uint16 connhandle; + uint8 silence_on; +} __attribute__ ((packed)); + +#define HCI_DBG_SNIFFER_CMD_OPCODE 0xFC95 +struct hci_dbg_sniffer_interface +{ + uint16 connhandle; + uint8 subcode; +} __attribute__ ((packed)); + +#define HCI_WRITE_LINK_SUPERV_TIMEOUT 0x0C37 +struct hci_write_superv_timeout +{ + uint16 connhandle; + uint16 superv_timeout; +} __attribute__ ((packed)); + +#define HCI_DBG_START_TWS_EXCHANGE_CMD_OPCODE 0xFC91 +struct hci_start_tws_exchange +{ + uint16 tws_slave_conn_handle; + uint16 mobile_conn_handle; +} __attribute__ ((packed)); + +#define HCI_DBG_SET_SNIFFER_ENV_CMD_OPCODE 0xFC8E +struct hci_set_sniffer_env +{ + uint8 sniffer_active; + uint8 sniffer_role; + struct bdaddr_t monitor_bdaddr; + struct bdaddr_t sniffer_bdaddr; +} __attribute__ ((packed)); + +#define HCI_DBG_ENABLE_FASTACK_CMD_OPCODE 0xFCA1 +struct hci_enable_fastack +{ + uint16 conn_handle; + uint8 direction; + uint8 enable; +} __attribute__ ((packed)); + +#define HCI_DBG_ENABLE_IBRT_MODE_CMD_OPCODE 0xFCA2 +struct hci_ibrt_mode_op +{ + uint8 enable; + uint8 switchOp; +} __attribute__ ((packed)); + +#define HCI_DBG_START_IBRT_CMD_OPCODE 0xFCA3 +struct hci_start_ibrt +{ + uint16 slaveConnHandle; + uint16 mobilConnHandle; +} __attribute__ ((packed)); + +#define HCI_DBG_GET_TWS_SLAVE_OF_MOBILE_RSSI_CMD_OPCODE 0xFCA4 +struct hci_get_tws_slave_of_mobile_rssi +{ + uint16 conn_handle; +} __attribute__ ((packed)); + +#define HCI_DBG_STOP_IBRT_CMD_OPCODE 0xFCA8 +struct hci_stop_ibrt +{ + uint8 enable; + uint8 reason; +} __attribute__ ((packed)); + +#define HCI_DBG_STOP_MULTI_POINT_IBRT_CMD_OPCODE 0xFCBF +struct hci_stop_multi_point_ibrt +{ + uint16 mobile_conhdl; + uint8 reason; +} __attribute__ ((packed)); + +#define HCI_DBG_RESUME_IBRT_CMD_OPCODE 0xFCAC +struct hci_resume_ibrt +{ + uint8 enable; +} __attribute__ ((packed)); + + +#define HCI_DBG_SET_LINK_LBRT_CMD_OPCODE 0xFC97 +struct hci_set_link_lbrt_enable +{ + uint16 conn_handle; + uint8 enable; +} __attribute__ ((packed)); + +#define HCI_DBG_IBRT_SWITCH_CMD_OPCODE 0xFCBE +struct hci_ibrt_switch +{ + uint16 conn_handle; +} __attribute__ ((packed)); + +#define HCC_WRITE_RANDOM_ADDR 0x2005 +struct hci_write_random_addr +{ + struct bdaddr_t bdaddr; +} __attribute__ ((packed)); + +#define HCC_WRITE_ADV_PARAMETER 0x2006 +struct hci_write_adv_param +{ + uint16 interval_min; + uint16 interval_max; + uint8 adv_type; + uint8 own_addr_type; + uint8 peer_addr_type; + struct bdaddr_t bdaddr; + uint8 adv_chanmap; + uint8 adv_filter_policy; +} __attribute__ ((packed)); + +#define HCC_WRITE_ADV_DATA 0x2008 +struct hci_write_adv_data +{ + uint8 len; + uint8 data[BLE_ADV_DATA_LENGTH]; +} __attribute__ ((packed)); + +#define HCC_WRITE_SCAN_RSP_DATA 0x2009 +struct hci_write_scan_rsp_data +{ + uint8 len; + uint8 data[BLE_SCAN_RSP_DATA_LENGTH]; +} __attribute__ ((packed)); + +#define HCC_WRITE_ADV_ENABLE 0x200A +struct hci_write_adv_en +{ + uint8 en; +} __attribute__ ((packed)); + +#define HCC_WRITE_BLE_SCAN_PARAMETER 0x200B +struct hci_write_ble_scan_param +{ + uint8 scan_type; + uint16 scan_interval; + uint16 scan_window; + uint8 own_addr_type; + uint8 scan_filter_policy; +} __attribute__ ((packed)); + +#define HCC_WRITE_BLE_SCAN_ENABLE 0x200C +struct hci_write_ble_can_en +{ + uint8 scan_en; + uint8 filter_duplicat; +} __attribute__ ((packed)); + + +#define HCC_CLEAR_WHITE_LIST 0x2010 +#define HCC_ADD_DEVICE_TO_WHITELIST 0x2011 +struct hci_add_device_to_wl +{ + uint8 addr_type; + struct bdaddr_t bdaddr; +} __attribute__ ((packed)); + +#define HCI_DBG_BTADDR_EXCHANGE_CMD_OPCODE 0xFC92 +struct hci_tws_bdaddr_exchange +{ + uint16 conn_handle; +} __attribute__ ((packed)); + +#define HCI_DBG_SEND_PREFER_RATE_CMD_OPCODE 0xFCA9 +struct hci_dbg_send_prefer_rate +{ + uint16 conn_handle; + uint8 rate; +} __attribute__ ((packed)); + +#define HCI_DBG_SET_ECC_DATA_TEST_CMD_OPCODE 0xFCBB + +#if defined(__cplusplus) +extern "C" { +#endif + +int8 btlib_hcicmd_dbg_send_prefer_rate(uint16 conn_handle, uint8 rate); +int8 btlib_send_hci_cmd_direct(uint16 opcode, uint8 *param_data_ptr, uint8 param_len); +void hci_rxtx_buff_process(void); +int8 hci_simulate_event(uint8 event, uint8 *buff, uint32 buff_len); +void hci_rx_data_ind(hci_buff_t *hci_buff); +void hci_bt_tx_acl_flush(uint16 handle); +void hci_bt_command_sync_flush(uint16 handle); +void hci_ble_tx_acl_flush(uint16 handle); +#if (BTM_BLE_USE_INTERNAL_QUEUE_CACHE_ENABLE==1) +void hci_ble_rx_acl_flush(uint16 handle); +#endif +int8 hcicmd_msg_dispatch (struct hci_cmd_packet *head); +struct hci_cmd_packet *hcicmd_packet_create (uint16 opcode, uint8 param_len); +int8 hcicmd_sync_cmd_done(void); +int8 hcicmd_get_current_sync_cmd(struct hci_cmd_packet **head); +int8 btlib_send_ble_data( uint16 conn_handle, uint8 *data_ptr, uint16 data_len, uint8 *priv); +uint8 hci_receive_ble_handle(uint16 connHandle); + +typedef void (*event_handle_t)(uint8 *param, uint8 *priv, uint8 *donot_free); +typedef void (*acl_handle_t)(uint16 handle, uint8 *data, uint16 data_len, uint8 *priv, uint8 *donot_free); +typedef void (*sco_handle_t)(uint16 handle, uint8 *data, uint16 data_len, uint8 *priv, uint8* donot_free); + +int8 btlib_register_hci_rx_handle(event_handle_t event_handle,acl_handle_t acl_handle, sco_handle_t sco_handle); +void hci_callback(uint8 type, uint16 conn_handle, uint8 *data, uint16 length, uint8 *priv, uint8 *donot_free); +int8 btlib_hcicmd_write_controller_memory(uint32_t addr, uint32_t val,uint8_t type); +int8 btlib_hcicmd_read_controller_memory(uint32_t addr, uint32_t len,uint8_t type); + +#if defined(__cplusplus) +} +#endif + +#endif /* __HCI_H__ */ diff --git a/services/bt_profiles_enhanced/inc/hci_buff.h b/services/bt_profiles_enhanced/inc/hci_buff.h new file mode 100644 index 0000000..1fd4377 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/hci_buff.h @@ -0,0 +1,177 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __HCI_BUFF_H__ +#define __HCI_BUFF_H__ + +// abbrs +// HCI_BUFF -> HB hb +// HCI_BUFF_TYPE -> HBT +// HCI_BUFF_DATA_HEAD_TYPE -> HBDHT + +#include "string.h" +#include "btlib_type.h" +#include "stdint.h" +#include "bt_co_list.h" + +#define DUMP_PUSH_POP_TIME 0 + +#if defined(__cplusplus) +extern "C" { +#endif + +// hci buffer type +#define HBT_COMMAND 0x01 +#define HBT_COMMAND_SYNC 0x11 +#define HBT_RX_ACL 0x02 +#define HBT_RX_SCO 0x03 +#define HBT_EVENT 0x04 +#define HBT_TX_ACL 0x05 +#define HBT_TX_SCO 0x06 +#define HBT_RX_BLE 0x07 +#define HBT_TX_BLE 0x08 +#define HBT_RX 0x09 + +#define HB_TYPE(hci_buff) (hci_buff->type) +#define HB_OPCODE(hci_buff) (hci_buff->u.opcode) +#define HB_HANDLE(hci_buff) (hci_buff->u.handle) +#define HB_DATA(hci_buff) (hci_buff->data) +#define HB_DATA_LEN(hci_buff) (hci_buff->data_len) +#define HB_PRIV(hci_buff) (hci_buff->priv) +#define HB_SHOULD_FREE(hci_buff) (hci_buff->should_free) + +typedef struct { + struct list_node node; + uint8 type; + uint8 should_free; + union { + uint16 handle; + uint16 opcode; + } u; + uint16 data_len; + uint8 *data; + void *priv; +#if defined(DUMP_PUSH_POP_TIME) + uint32 push_time; +#endif +} hci_buff_t; + +#define hci_buff_list_iter_begin(type,hci_buff,error) \ + do{ \ + hci_buff_t *__hci_buff = NULL; \ + struct list_node *__list = hci_buff_get_pend_list(type); \ + struct list_node *__pos = NULL, *__next = NULL; \ + error = 0; \ + if (__list == NULL) { \ + error = 1; \ + break; \ + } \ + colist_iterate_safe(__pos, __next, __list) \ + { \ + __hci_buff = colist_structure(__pos, hci_buff_t, node); \ + if (__hci_buff == NULL) { \ + error = 2; \ + } else {\ + hci_buff = __hci_buff; \ + } + +#define hci_buff_list_iter_end() \ + } \ + }while(0); + +/* + @brief To init list (add buff to free list, pend list is empty) + @return SUCCESS/FAILURE +*/ +int8 hci_buff_list_init(void); +/* + @brief To get pend list + @param type - buffer type + @return list +*/ +struct list_node *hci_buff_get_pend_list(uint8 type); +/* + @brief To push buff to list tail + @param type - buffer type + @param buff - buffer + @return SUCCESS/FAILURE +*/ +int8 hci_buff_list_push(hci_buff_t *buff); +/* + @brief To push buff to list head + @param type - buffer type + @param buff - buffer + @return SUCCESS/FAILURE +*/ +int8 hci_buff_list_push_front(hci_buff_t *buff); +/* + @brief To see list head but no delete operation + @param type - buffer type + @param buff - buffer to store head + @return SUCCESS/FAILURE +*/ +int8 hci_buff_list_peek(uint8 type, hci_buff_t **buff); +/* + @brief To get list head and delete it from list + @param type - buffer type + @param buff - buffer to store head + @return SUCCESS/FAILURE +*/ +int8 hci_buff_list_pop(uint8 type, hci_buff_t **buff); +/* + @brief To remove a buffer from pending buffer + @param buff - buffer to remove + @return SUCCESS/FAILURE +*/ +int8 hci_buff_list_remove(hci_buff_t *buff); +/* + @brief To see if list is empty + @param type - buffer type + @return 1 - empty, 0 - empty +*/ +int8 hci_buff_list_is_empty(uint8 type); +/* + @brief To dump list + @param type - buffer type +*/ +void hci_buff_list_dump(uint8 type); +/* + @brief To alloc a buffer + @param type - buffer type + @param buff - buffer to store head + @return SUCCESS/FAILURE +*/ +int8 hci_buff_alloc(uint8 type, hci_buff_t **buff); +/* + @brief To free a buffer + @param type - buffer type + @param buff - buffer to store head + @return SUCCESS/FAILURE +*/ +int8 hci_buff_free(hci_buff_t *buff); +/* + @brief To print hcibuff statistic + @return SUCCESS/FAILURE +*/ +int8 hci_buff_print_statistic(void); +int8 hci_buff_rx_print_statistic(void); +void hci_buff_list_filter_handle_peek(uint8 type,uint16 handle,bool equal,hci_buff_t **peek_buff); +#if defined(__cplusplus) +} +#endif + +#endif /* __HCI_BUFF_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/hfp.h b/services/bt_profiles_enhanced/inc/hfp.h new file mode 100644 index 0000000..e268790 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/hfp.h @@ -0,0 +1,148 @@ +#ifndef __HFP_H__ +#define __HFP_H__ +#include "btlib_type.h" + +struct hfp_response { + const char *data; + unsigned int offset; +}; + +enum hfp_result { + HFP_RESULT_OK = 0, + HFP_RESULT_CONNECT = 1, + HFP_RESULT_RING = 2, + HFP_RESULT_NO_CARRIER = 3, + HFP_RESULT_ERROR = 4, + HFP_RESULT_NO_DIALTONE = 6, + HFP_RESULT_BUSY = 7, + HFP_RESULT_NO_ANSWER = 8, + HFP_RESULT_DELAYED = 9, + HFP_RESULT_BLACKLISTED = 10, + HFP_RESULT_CME_ERROR = 11, +}; + +enum hfp_error { + HFP_ERROR_AG_FAILURE = 0, + HFP_ERROR_NO_CONNECTION_TO_PHONE = 1, + HFP_ERROR_OPERATION_NOT_ALLOWED = 3, + HFP_ERROR_OPERATION_NOT_SUPPORTED = 4, + HFP_ERROR_PH_SIM_PIN_REQUIRED = 5, + HFP_ERROR_SIM_NOT_INSERTED = 10, + HFP_ERROR_SIM_PIN_REQUIRED = 11, + HFP_ERROR_SIM_PUK_REQUIRED = 12, + HFP_ERROR_SIM_FAILURE = 13, + HFP_ERROR_SIM_BUSY = 14, + HFP_ERROR_INCORRECT_PASSWORD = 16, + HFP_ERROR_SIM_PIN2_REQUIRED = 17, + HFP_ERROR_SIM_PUK2_REQUIRED = 18, + HFP_ERROR_MEMORY_FULL = 20, + HFP_ERROR_INVALID_INDEX = 21, + HFP_ERROR_MEMORY_FAILURE = 23, + HFP_ERROR_TEXT_STRING_TOO_LONG = 24, + HFP_ERROR_INVALID_CHARS_IN_TEXT_STRING = 25, + HFP_ERROR_DIAL_STRING_TO_LONG = 26, + HFP_ERROR_INVALID_CHARS_IN_DIAL_STRING = 27, + HFP_ERROR_NO_NETWORK_SERVICE = 30, + HFP_ERROR_NETWORK_TIMEOUT = 31, + HFP_ERROR_NETWORK_NOT_ALLOWED = 32, +}; + +typedef void (*hfp_destroy_func_t)(void *user_data); +typedef void (*hfp_debug_func_t)(const char *str, void *user_data); + +typedef void (*hfp_command_func_t)(const char *command, void *user_data); +extern struct hshf_control *hshf_ctl; + +typedef void (*hfp_hf_result_func_t)(struct hfp_response *context, + void *user_data); + +typedef void (*hfp_response_func_t)(enum hfp_result result, + enum hfp_error cme_err, + void *user_data); + +#if defined(__cplusplus) +extern "C" { +#endif + +#if !defined(HFP_MOBILE_AG_ROLE) +void hf_process_input(struct hshf_control *hfp, const char *data, size_t len); +#else +void ag_process_input(struct hshf_control *hfp, const char *data, size_t len); +#endif + +bool hfp_hf_send_command(struct hshf_control *hfp, hfp_response_func_t resp_cb, + void *user_data, const char *data, unsigned int len); +bool hfp_hf_send_command_do(struct hshf_control *hfp, hfp_response_func_t resp_cb, + void *user_data, const char *data, unsigned int len, bool is_cust_cmd ,uint8 param); + +#define hfp_hf_send_command(h,rc,ud,d,dl) hfp_hf_send_command_do(h,rc,ud,d,dl,false,0xFF) + +#define hfp_hf_send_command_private(h,rc,ud,d,dl,param) hfp_hf_send_command_do(h,rc,ud,d,dl,false,param) + + + +bool hfp_context_get_string(struct hfp_response *context, char *buf, + uint8_t len); + +void hfp_context_skip_field(struct hfp_response *context); + +void skip_whitespace(struct hfp_response *context); + +bool hfp_hf_register(struct hshf_control *hfp, hfp_hf_result_func_t callback, + const char *prefix, + void *user_data, + hfp_destroy_func_t destroy); + +bool hfp_hf_unregister(struct hshf_control *hfp, const char *prefix); + +bool hfp_context_open_container(struct hfp_response *context); + +bool hfp_context_close_container(struct hfp_response *context); + +bool hfp_context_get_unquoted_string(struct hfp_response *context, + char *buf, uint8_t len); + +bool hfp_context_has_next(struct hfp_response *context); + +bool hfp_context_get_range(struct hfp_response *context, unsigned int *min, + unsigned int *max); + +bool hfp_context_get_number(struct hfp_response *context, + unsigned int *val); + +void hfp_hf_destory_resource(struct hshf_control *hfp); + +void hf_rfcomm_data_recv_cb(uint32 rfcomm_handle, + struct pp_buff *ppb, void *priv); + +void hf_rfcomm_notify_cb(enum rfcomm_event_enum event, + uint32 rfcomm_handle, + void *data, uint8 reason, void *priv); + +struct hshf_control *hfp_search_address(struct bdaddr_t *bdaddr); + +bool hfp_msbc_is_enable(struct bdaddr_t *bdaddr); +struct hshf_control *hf_find_unused_channel(void); +#if defined(HFP_MOBILE_AG_ROLE) +struct hfp_mobile_module_handler; +void hfp_ag_send_call_active_status(struct hshf_control *hfp, bool active); +void hfp_ag_send_callsetup_status(struct hshf_control *hfp, uint8 status); +void hfp_ag_send_callheld_status(struct hshf_control *hfp, uint8 status); +void hfp_ag_send_calling_ring(struct hshf_control *hfp, const char* number); +bool hfp_ag_set_speaker_gain(struct hshf_control *hfp, uint8 volume); +bool hfp_ag_set_microphone_gain(struct hshf_control *hfp, uint8 volume); +bool hfp_ag_send_result_code(struct hshf_control *hfp, const char *data, int len); +void hfp_ag_register_mobile_module(struct hshf_control* hfp, struct hfp_mobile_module_handler* handler); +void hfp_ag_send_result_ok(struct hshf_control *hfp); +void hfp_ag_send_result_error(struct hshf_control *hfp); +void hfp_ag_send_service_status(struct hshf_control *hfp, bool enabled); +void hfp_ag_send_mobile_signal_level(struct hshf_control *hfp, uint8 level); +void hfp_ag_send_mobile_roam_status(struct hshf_control *hfp, bool enabled); +bool hfp_ag_send_mobile_battery_level(struct hshf_control *hfp, uint8 level); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /*__HFP_H__*/ diff --git a/services/bt_profiles_enhanced/inc/hid_i.h b/services/bt_profiles_enhanced/inc/hid_i.h new file mode 100644 index 0000000..334f770 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/hid_i.h @@ -0,0 +1,176 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "bt_co_list.h" +#include "btlib_type.h" +#include "btm_i.h" +#include "sdp.h" + +#ifndef __HID_I_H__ +#define __HID_I_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + HID_STATE_CLOSED, + HID_STATE_STANDBY = 1, // ready + HID_STATE_QUERING, + HID_STATE_CONNECTING, + HID_STATE_WAITING_INTRUPT_CHANNEL, + HID_STATE_CONNECTING_INTRUPT_CHANNEL, + HID_STATE_OPEN, + HID_STATE_DISCONNECTING, +} hid_state_t; + +typedef enum { + HID_EVENT_REMOTE_NOT_SUPPORT = 1, + HID_EVENT_CONN_OPENED, + HID_EVENT_CONN_CLOSED, +} hid_event_t; + +typedef enum { + HID_SESSION_CLOSE, + HID_SESSION_CONNECTING, + HID_SESSION_OPEN, +} hid_session_state_t; + +typedef enum { + HID_PENDING_OP_NULL = 0, + HID_PENDING_OP_GET_REPORT, + HID_PENDING_OP_GET_PROTOCOL, + HID_PENDING_OP_SET_REPORT, + HID_PENDING_OP_SET_PROTOCOL, +} hid_pending_op_t; + +struct hid_session_t { + uint32 l2cap_handle; + hid_session_state_t state; +}; + +struct hid_callback_parms_t +{ + hid_event_t event; + uint8_t error_code; + struct bdaddr_t remote; +}; + +#define HID_BOOT_PROTOCOL_MODE 0x0 +#define HID_REPORT_PROTOCOL_MODE 0x1 + +typedef enum { + HID_REPORT_TYPE_OTHER = 0, + HID_REPORT_TYPE_INPUT, + HID_REPORT_TYPE_OUTPUT, + HID_REPORT_TYPE_FEATURE, +} hid_report_type_enum_t; + +#define HID_FRAME_DATA_MAX_LEN 11 /* DM1 is recommended packet */ +extern struct hid_stack_interface_t hid_stack_if; + +struct hid_report_data_t { + uint8_t report_id; + uint8_t data[HID_FRAME_DATA_MAX_LEN]; + uint8_t data_len; +}; + +struct hid_frame_t { + uint8_t header; + uint8_t data[HID_FRAME_DATA_MAX_LEN]; + uint8_t data_len; + bool waiting_rsp; + hid_pending_op_t pending_op; +}; + +struct hid_frame_node_t { + struct list_node node; + struct hid_frame_t frame; +}; + +struct hid_rx_msg_t { + uint8_t msg_type; + uint8_t param; + uint8_t data_len; + uint8_t *data; +}; + +struct hid_control_t { + struct bdaddr_t remote; + bool initiator; + bool is_hid_device_role; + struct hid_session_t control_session; + struct hid_session_t interrupt_session; + hid_state_t state; + hid_pending_op_t pending_op; + uint8 pending_protocol_set; + uint8 unplug_op_pending; + uint8 local_protocol_mode; + uint8 remote_protocol_mode; + uint8 remote_report_descriptor_has_report_id; + uint8 disc_reason; + void (*hid_callback)(struct hid_control_t *hid_ctl, const struct hid_callback_parms_t *info); + struct sdp_request sdp_request; + struct hid_report_data_t device_input_data; + struct hid_report_data_t device_output_data; + struct hid_report_data_t device_feature_data; + struct list_node ctrl_tx_list; + struct list_node intr_tx_list; + bool ctrl_tx_busy; + bool intr_tx_busy; + bool use_interrupt_channel; +}; + +struct hid_stack_interface_t { + struct hid_control_t *(*hid_alloc_standby_control)(void *remote); + struct hid_control_t *(*hid_search_from_control_handle)(uint32_t l2cap_handle); + struct hid_control_t *(*hid_search_from_interrupt_handle)(uint32_t l2cap_handle); + struct hid_control_t *(*hid_search_from_remote_bdaddr)(void *remote); +}; + +struct hid_ctx_input { + struct ctx_content ctx; + struct bdaddr_t *remote; + struct hid_control_t *hid_ctl; + uint32 hid_ctrl_handle; + uint32 hid_intr_handle; +}; + +int hid_stack_init(struct hid_stack_interface_t *stack_if, uint8_t is_hid_device_role); + +int hid_connect_req(struct hid_control_t *hid_ctl); + +void hid_disconnect_req(struct hid_control_t *hid_ctl); + +hid_state_t hid_get_state(struct hid_control_t *hid_ctl); + +int hid_send_handshake(struct hid_control_t *hid_ctl, uint8_t code); + +void hid_keyboard_input_report(struct hid_control_t *hid_ctl, uint8_t modifier_key, uint8_t key_code); + +void hid_keyboard_send_ctrl_key(struct hid_control_t *hid_ctl, uint8_t ctrl_key); + +int hid_l2cap_control_notify_callback(enum l2cap_event_enum event, uint32 l2cap_handle, void *pdata, uint8 reason); +int hid_l2cap_interrupt_notify_callback(enum l2cap_event_enum event, uint32 l2cap_handle, void *pdata, uint8 reason); +void hid_l2cap_control_data_receive(uint32 l2cap_handle, struct pp_buff *ppb); +void hid_l2cap_interrupt_data_receive(uint32 l2cap_handle, struct pp_buff *ppb); + +#ifdef __cplusplus +} +#endif + +#endif /* __HID_I_H__ */ + diff --git a/services/bt_profiles_enhanced/inc/hshf.h b/services/bt_profiles_enhanced/inc/hshf.h new file mode 100644 index 0000000..47724d0 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/hshf.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HSHF_H__ +#define __HSHF_H__ + +#include "btlib_type.h" + +#include "rfcomm_i.h" +#include "sco_i.h" + +#define HS_CFG_SERVER_CHANNEL 0x12 +#define HF_CFG_SERVER_CHANNEL 0x13 + +#define HF_CFG_MAX_RX_CREDIT 207 +#define HF_CFG_CREDIT_GIVE_LIMIT 20 + +/* Functions */ +int8 hs_init ( void (*indicate_callback) ( uint8 event, void *pdata )); +int8 hs_close(void); + +void hs_rfcomm_datarecv_callback(uint32 rfcomm_handle, struct pp_buff *ppb, void *priv); +void hs_rfcomm_notify_callback(enum rfcomm_event_enum event, + uint32 rfcomm_handle, void *pData, + uint8 reason, void *priv); + +#endif /* __HSHF_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/hshf_i.h b/services/bt_profiles_enhanced/inc/hshf_i.h new file mode 100644 index 0000000..20de5fe --- /dev/null +++ b/services/bt_profiles_enhanced/inc/hshf_i.h @@ -0,0 +1,408 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HSHF_I_H__ +#define __HSHF_I_H__ + +#include "btlib_type.h" +#include "rfcomm_i.h" +#include "co_queue.h" +#include "bt_co_list.h" +#include "sdp.h" +#include "bt_sys_cfg.h" + +//#define _THREE_WAY_CALL + +//#define PRO_PCDEMO +struct hshf_control; + +typedef void (*hfp_callback_t)(struct hshf_control *, uint8_t, void *); + +enum hshf_tx_status { + HFP_TX_IDLE = 0, + HFP_TX_BUSY, +}; + +/* notify upper layer */ +enum hshf_event_t { + /* user command event*/ + HSHF_ENTER_PAIRING = 1, + HSHF_EXIT_PAIRING, + HF_DIAL_NUM_REQ, + HF_ANSWER_REQ, + HF_REJECT_REQ, + HF_ENDCALL_REQ, + HF_TRANSFER_REQ, + HF_DIAL_LASTNUM_REQ, + HF_TRANSMIT_DTMF, + HF_VOICE_DIAL_REQ, //10 + HF_VOICE_DIAL_CANCEL_REQ, + HSHF_CONNECT_REQ, + HF_DISCONNECT_REQ, + HSHF_SPK_VOL_UP, + HSHF_SPK_VOL_DOWN, + HSHF_TOGGLE_MIC, + HSHF_TOGGLE_LED, + HSHF_TOGGLE_VOLBTN, + HF_ANSWER_ENDCALL_CONN, // answer @ ring, end @ talking, connect@idle + HF_REJ_REDIAL_TRANS_CONN, // reject @ ring, redial @ connected, transfer @ talking + HF_RELEASE_HOLD_REJECT_WAIT_REQ, //21 + HF_RELEASE_ACTVIE_ACCEPT_OTHER_REQ, + HF_HOLD_ACTIVE_ACCEPT_OTHER_REQ, + HF_CONFERENCE_REQ, + HSHF_SET_PB_STORAGE, + HSHF_GET_PB_ITEM, + + HF_HCI_RXTX_IND, + + /* internal event */ + HSHF_EVNT_BEGIN, //28 + HSHF_RFCOMM_OPENED, //29 + HSHF_CONN_OPENED, + HSHF_CONN_CLOSED, + HSHF_CONN_REQ_FAIL, + HF_AG_SUPPORTED_FEATURE_IND, + HF_AG_SUPPORTED_INDICATOR_IND, + HF_AG_CURRENT_INDICATOR_IND, + HF_INDICATOR_EVENT_IND, + HF_CIEV_CALL_IND, + HF_CIEV_SERVICE_IND, + HF_CIEV_CALLSETUP_IND, //38 + HF_CALLER_ID_IND, + HF_VOICE_IND, + HSHF_RING_IND, //41 + HSHF_AUDIOCONN_OPENED, + HSHF_AUDIOCONN_CLOSED, + HSHF_SPK_VOL_IND, + HSHF_MIC_VOL_IND, + HF_IN_BAND_RING_IND, + HSHF_PAIR_OK, //47 + HSHF_PAIR_TOUT, + HSHF_PAIR_FAILED, + //// NEW for three way call + HF_CIEW_CALLHELD_IND, + HF_CCWA_IND, + HF_VOICE_REQ, + // for enter pairing and test mode by combkey + HSHF_ENTER_TESTMODE, + HSHF_CALL_IND, + HF_EVENT_AT_RESULT_DATA, +}; + +enum hshf_callsetup { + CALL_SETUP_NONE, + CALL_SETUP_INCOMING, + CALL_SETUP_OUTGOING, + CALL_SETUP_REMOTE_ALERT, + CALL_SETUP_ESTABLISHED +}; + +enum hshf_call { + CALL_NONE = 0, + CALL_ESTABLISHED +}; + +enum hshf_profile { + PRO_BOTH = 0, + PRO_HEADSET, + PRO_HANDSFREE, + PRO_EXIT, + PRO_SHOW +}; + +enum hshf_conn_state { + STOP, + STANDBY = 1, + LISTENING , //ready + QUERING, + CONNECTING, + AT_EXCHANGING, + CONNECTED, + SCOCONNECTED +}; + +enum hshf_pb_location { + LOCATION_SM = 0, + LOCATION_ME, + LOCATION_MT, + LOCATION_DC, + LOCATION_RC, + LOCATION_MC, + LOCATION_LD +}; + +enum hshf_pb_action { + ACTION_PREV = 0, + ACTION_NEXT +}; + +enum hfp_indicator { + HFP_INDICATOR_SERVICE = 0, + HFP_INDICATOR_CALL, + HFP_INDICATOR_CALLSETUP, + HFP_INDICATOR_CALLHELD, + HFP_INDICATOR_SIGNAL, + HFP_INDICATOR_ROAM, + HFP_INDICATOR_BATTCHG, + HFP_INDICATOR_LAST +}; + +typedef void (*ciev_func_t)(struct hshf_control *chan, uint8_t val); + +struct indicator { + uint8_t index; + uint8_t min; + uint8_t max; + uint8_t val; + bool disable; + ciev_func_t cb; +}; + +struct indicator; + +#define HFP_HF_IND_ENHANCED_SAFETY 1 +#define HFP_HF_IND_BATTERY_LEVEL 2 + +struct hf_ind_enhanced_safety { + bool local_support; + bool remote_support; + bool enabled; + uint8_t value; /* 0 or 1 */ +}; + +struct hf_ind_battery_level { + bool local_support; + bool remote_support; + bool enabled; + uint8_t value; /* 0 ~ 100 */ +}; + +struct hf_indicator { + struct hf_ind_enhanced_safety enhanced_safety; + struct hf_ind_battery_level battery_level; +}; + +#define MAX_DIAL_NUM_SIZE 0x10 +#define MAX_SAVED_CALL_NUM 4 + +#define CODEC_ID_CVSD 0x01 +#define CODEC_ID_MSBC 0x02 +struct hfp_codec { + uint8_t type; + bool local_supported; + bool remote_supported; +}; + +#if defined(HFP_MOBILE_AG_ROLE) +struct hfp_ag_call_info +{ + uint8_t direction; // 0 outgoing, 1 incoming + uint8_t state; // 0 active, 1 held, 2 outgoing dialing, 3 outgoing alerting, 4 incoming, 5 waiting, 6 held by Response and Hold + uint8_t mode; // 0 voice, 1 data, 2 fax + uint8_t multiparty; // 0 is not one of multiparty call parties, 1 is one of. + const char* number; // calling number, optional +}; + +typedef int (*hfp_mobile_handler)(void* hfp_chan); +typedef int (*hfp_mobile_handler_int)(void* hfp_chan, int n); +typedef int (*hfp_mobile_handler_str)(void* hfp_chan, const char* s); +typedef int (*hfp_mobile_iterate_call_handler)(void* hfp_chan, struct hfp_ag_call_info* out); +typedef const char* (*hfp_mobile_query_operator_handler)(void* hfp_chan); + +struct hfp_mobile_module_handler +{ + hfp_mobile_handler answer_call; + hfp_mobile_handler hungup_call; + hfp_mobile_handler dialing_last_number; + hfp_mobile_handler release_held_calls; + hfp_mobile_handler release_active_and_accept_calls; + hfp_mobile_handler hold_active_and_accept_calls; + hfp_mobile_handler add_held_call_to_conversation; + hfp_mobile_handler connect_remote_two_calls; + hfp_mobile_handler disable_mobile_nrec; + hfp_mobile_handler_int release_specified_active_call; + hfp_mobile_handler_int hold_all_calls_except_specified_one; + hfp_mobile_handler_int hf_battery_change; /* battery level 0 ~ 100 */ + hfp_mobile_handler_int hf_spk_gain_change; /* speaker gain 0 ~ 15 */ + hfp_mobile_handler_int hf_mic_gain_change; /* mic gain 0 ~ 15 */ + hfp_mobile_handler_int transmit_dtmf_code; + hfp_mobile_handler_int memory_dialing_call; + hfp_mobile_handler_str dialing_call; + hfp_mobile_handler_str handle_at_command; + hfp_mobile_query_operator_handler query_current_operator; + hfp_mobile_iterate_call_handler iterate_current_call; +}; +#endif + +struct hshf_control { + struct list_node hfp_node; + struct bdaddr_t remote; + uint32_t rfcomm_handle; + uint8 listen_channel; + uint8 disc_reason; + uint8 audio_up; + struct coqueue *cmd_queue; + +#if HFP_CMD_FLOW_CONTROL_ENABLE==1 + unsigned int tx_time; + uint8_t tx_timeout_timer; + enum hshf_tx_status tx_status; +#endif + + struct coqueue *event_handlers; + uint8_t negotiated_codec; + + struct hfp_codec codecs[2]; + + struct indicator ag_ind[HFP_INDICATOR_LAST]; + + struct hf_indicator hf_ind; + + uint32_t chld_features; + + uint8 bsir_enable; + uint8 status_call; /* Phone status info - call */ + uint8 status_service; /* Phone status info - service */ + uint8 status_callsetup; /* Phone status info - callsetup*/ + uint8 status_callheld; /* Phone status info - callheld*/ + +#if defined(HFP_MOBILE_AG_ROLE) + uint32_t slc_completed: 1; + uint32_t ag_status_report_enable: 1; + uint32_t calling_line_notify: 1; + uint32_t call_waiting_notify: 1; + uint32_t extended_error_enable: 1; + struct hfp_mobile_module_handler* mobile_module; +#endif + + uint32_t hf_features; /*hf supported feature bitmap: */ + /* bit 0 - EC/NR function */ + /* 1 - Call waiting and 3-way calling */ + /* 2 - CLI presentation capability */ + /* 3 - Voice recognition activation */ + /* 4 - Remote volume control */ + /* 5 - Enhance call status */ + /* 6 - Enhanced call control */ + uint32_t ag_features; /* AG supported feature bitmap */ + /* bit0 - 3-way calling */ + /* 1 - EC/NR function */ + /* 2 - Voice recognition */ + /* 3 - In-band ring tone */ + /* 4 - Attach a number to a voice tag*/ + /* 5 - Ablility to reject a call */ + /* 6 - Enhanced call status */ + /* 7 - Enhanced call control */ + /* 8 - extended error result codes*/ + + enum hshf_conn_state state; /*check if it is connecting now, + if it is connecting,the hf_connect_req + will not work + */ + uint8 speak_volume; + uint8 mic_gain; + uint8 voice_rec; + uint8 voice_rec_param; + bool client_enabled; + char caller_id[MAX_DIAL_NUM_SIZE+1]; /* incoming caller id */ + + struct sdp_request sdp_request; + char *ptr; +}; + +struct hfp_ctx_input { + struct ctx_content ctx; + struct bdaddr_t *remote; + uint32 rfcomm_handle; + struct hshf_control *hfp_ctl; +}; + +struct hfp_ctx_output { + uint32 rfcomm_handle; +}; + +#if defined(__cplusplus) +extern "C" { +#endif +/*----hshf.c----*/ +enum hshf_conn_state hshf_get_state(struct hshf_control *chan); +void hshf_set_state(struct hshf_control *chan, enum hshf_conn_state state); +const char *hshf_state2str(enum hshf_conn_state state); +const char *hshf_event2str(enum hshf_event_t event); + +typedef struct { + uint8 length; + char *caller_id; +} hf_caller_id_ind_t; + +int8 hf_release_sco(struct bdaddr_t *bdaddr, uint8 reason); + +/*----connect.c----*/ +int8 hf_disconnect_req(struct hshf_control *chan); +int8 hshf_exit_sniff(struct hshf_control *chan); +int8 hshf_connect_req (struct hshf_control *hshf_ctl, struct bdaddr_t *remote); + +/* - hfp.c - */ +int8 hshf_create_codec_connection(struct bdaddr_t *bdaddr, struct hshf_control *chan); +int8 hf_createSCO(struct bdaddr_t *bdaddr, void *chan); +int hfp_init(hfp_callback_t callback); + +int hf_open_chan(struct hshf_control *chan); + +int8 hf_close_chan(struct hshf_control *chan); + +bool hshf_disable_nrec(struct hshf_control *chan); + +bool hshf_report_speaker_volume(struct hshf_control *chan, uint8_t gain); + +bool hshf_send_custom_cmd(struct hshf_control *chan, const char *cmd); + +bool hshf_hungup_call(struct hshf_control *chan); + +bool hshf_dial_number(struct hshf_control *chan, uint8 *number, uint16 len); + +bool hshf_answer_call(struct hshf_control *chan); + +bool hshf_redial_call(struct hshf_control *chan); + +bool hshf_batt_report(struct hshf_control *chan, uint8_t level); + +bool hshf_call_hold(struct hshf_control *chan, int8 action, int8 index); + +void hshf_set_hf_indicator_enabled(bool enable); +bool hshf_report_enhanced_safety(struct hshf_control *chan, uint8_t value); +bool hshf_report_battery_level(struct hshf_control* chan, uint8_t value); + +bool hshf_update_indicators_value(struct hshf_control *chan, uint8_t assigned_num, uint8_t level); +bool hshf_hf_indicators_1(struct hshf_control *chan); +bool hshf_hf_indicators_2(struct hshf_control *chan); +bool hshf_hf_indicators_3(struct hshf_control *chan); +bool hshf_codec_conncetion(struct hshf_control *chan); +bool hshf_list_current_calls(struct hshf_control *chan); + +bool hshf_enable_voice_recognition(struct hshf_control *chan, uint8_t en); + +bool hshf_is_voice_recognition_active(struct hshf_control *chan); + +uint32 hfp_get_rfcomm_handle(struct hshf_control *hfp_ctl); + +uint32 hfp_save_ctx(struct hshf_control *hfp_ctl, uint8_t *buf, uint32_t buf_len); + +uint32 hfp_restore_ctx(struct hfp_ctx_input *input, struct hfp_ctx_output *output); + +#if defined(__cplusplus) +} +#endif + +#endif /* __HSHF_I_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/l2cap.h b/services/bt_profiles_enhanced/inc/l2cap.h new file mode 100644 index 0000000..33b5b7d --- /dev/null +++ b/services/bt_profiles_enhanced/inc/l2cap.h @@ -0,0 +1,358 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __L2CAP_H__ +#define __L2CAP_H__ + +#include "btlib_type.h" +#include "co_ppbuff.h" +#include "bt_co_list.h" +#include "l2cap_i.h" +#include "btm_i.h" + +typedef void (*l2cap_sdp_disconnect_callback)(const void *para); +typedef uint8 (*btm_get_ibrt_role_callback)(const void *para); +typedef uint8 (*btm_get_tss_state_callback)(const void *para); +/* base frame */ +#define L2CAP_SIG_CID 0x0001 +#define L2CAP_CONNECTIONLESS_CID 0x0002 + +#define L2CAP_CHANNEL_NUM_PER_LINK (9) /* rfcomm (1) + avrcp (1) + avdtp (2) + sdp (4) + extra (1) */ +#define CID_INDEX_OFFSET (0x40) +#define l2cap_cid_to_index(cid) (cid - CID_INDEX_OFFSET) +#define l2cap_index_to_cid(index) (index + CID_INDEX_OFFSET) + +struct l2cap_hdr { + uint16 len; + uint16 cid; +}__attribute__ ((packed)); + +/* command code */ +#define L2CAP_SIG_REJ 0x01 +#define L2CAP_SIG_CONN_REQ 0x02 +#define L2CAP_SIG_CONN_RSP 0x03 +#define L2CAP_SIG_CFG_REQ 0x04 +#define L2CAP_SIG_CFG_RSP 0x05 +#define L2CAP_SIG_DISCONN_REQ 0x06 +#define L2CAP_SIG_DISCONN_RSP 0x07 +#define L2CAP_SIG_ECHO_REQ 0x08 +#define L2CAP_SIG_ECHO_RSP 0x09 +#define L2CAP_SIG_INFO_REQ 0x0A +#define L2CAP_SIG_INFO_RSP 0x0B + +//Not used since inter-operation with special BT insturement +#if 0 +/* indentifier id */ +#define L2C_SIG_ID_REMAP_OFFSET (100) +#define L2C_SIG_CONN_REQ_ID (1) +#define L2C_SIG_DISCONN_REQ_ID (21) +#define L2C_SIG_CONFIG_REQ_ID (41) +#define L2C_SIG_ECHO_REQ_ID (61) +#define L2CAP_SIG_INFO_REQ_ID (81) +#define L2CAP_SIG_DEFAULT_ID (1) +#endif + +struct l2cap_sig_hdr { + byte code; + byte id; + uint16 len; +}__attribute__ ((packed)); + + +#define L2CAP_SIG_REASON_NOT_UNDERSTOOD 0x0 +#define L2CAP_SIG_REASON_MTU_EXCEED 0x1 +#define L2CAP_SIG_REASON_INVALID_CID 0x2 +struct l2cap_sig_rej { + + uint16 reason; +/*data*/ + uint16 scid; /*the data len is 0 - 4*/ + uint16 dcid; +}__attribute__ ((packed)); + +struct l2cap_sig_conn_req { + uint16 psm; + uint16 scid; +}__attribute__ ((packed)); + +#define L2CAP_SIG_RESULT_SUCCESS 0x0 +#define L2CAP_SIG_RESULT_PENDING 0x1 +#define L2CAP_SIG_RESULT_REFUSE_PSM 0x2 +#define L2CAP_SIG_RESULT_REFUSE_SECURITY 0x3 +#define L2CAP_SIG_RESULT_REFUSE_RESOURCE 0x4 + +#define L2CAP_SIG_RESULT_PENDING_NOINFO 0x00 +#define L2CAP_SIG_RESULT_PENDING_AUTHEN 0x01 +#define L2CAP_SIG_RESULT_PENDING_AUTHOR 0x02 +struct l2cap_sig_conn_rsp { + uint16 dcid; + uint16 scid; + + uint16 result; + uint16 status; /*only defined when result = pending */ +}__attribute__ ((packed)); + +struct l2cap_sig_cfg_req { + uint16 dcid; + uint16 flags; /* bit0=1:continue bit0=0:complete */ +}__attribute__ ((packed)); + +#define L2CAP_CFGRSP_SUCCESS 0x0000 +#define L2CAP_CFGRSP_UNACCEPT_PARAMS 0x0001 +#define L2CAP_CFGRSP_REJ 0x0002 +#define L2CAP_CFGRSP_UNKNOWN 0x0003 +struct l2cap_sig_cfg_rsp { + uint16 scid; + uint16 flags; + uint16 result; +}__attribute__ ((packed)); + +#define L2CAP_CFG_TYPE_MTU 0x01 +#define L2CAP_CFG_TYPEF_FLUSH_TO 0x02 +#define L2CAP_CFG_TYPE_QOS 0x03 +#define L2CAP_CFG_TYPE_RFC 0x04 //retransmission and flow control +#define L2CAP_CFG_TYPE_FCS 0x05 +#define L2CAP_CFG_TYPE_EFS 0x05 //extended flow specification +#define L2CAP_CFG_TYPE_EWS 0x06 //extended window size +struct l2cap_sig_cfg_opt_hdr{ + byte type; + byte len; +}__attribute__ ((packed)); + +struct l2cap_sig_cfg_opt_mtu { + + uint16 mtu; +}__attribute__ ((packed)); +struct l2cap_sig_cfg_opt_flushto { + + uint16 flushto; +}__attribute__ ((packed)); + +#define L2CAP_QOS_NO_TRAFFIC 0x00 +#define L2CAP_QOS_BEST_EFFORT 0x01 +#define L2CAP_QOS_GUARANTEED 0x02 +struct l2cap_sig_cfg_opt_qos { + + byte flags; + byte service_type; + uint32 token_rate; + uint32 token_size; + uint32 bandwidth; + uint32 latency; + uint32 delay_variation; +}__attribute__ ((packed)); + +#define L2CAP_MODE_BASE 0 +#define L2CAP_MODE_RETRANSMISSION 1 +#define L2CAP_MODE_FLOWCONTROL 2 +#define L2CAP_MODE_ENHANCED_RETRANSMISSION 3 +#define L2CAP_MODE_STREAMING 4 +struct l2cap_sig_cfg_opt_rfc { + + byte mode; + byte txwindow; + byte maxtransmit; + uint16 retransmission_timeout; + uint16 monitor_timeout; + uint16 mps; +}__attribute__ ((packed)); + +#define L2CAP_FCS_TYPE_NONE 0x00 +#define L2CAP_FCS_TYPE_16_BIT 0x01 +struct l2cap_sig_cfg_opt_fcs { + byte type; +}__attribute__ ((packed)); + +struct l2cap_sig_disconn_req { + + uint16 dcid; + uint16 scid; +}__attribute__ ((packed)); + +struct l2cap_sig_disconn_rsp { + uint16 dcid; + uint16 scid; +}__attribute__ ((packed)); + +#define L2CAP_INFOTYPE_CONNLESS_MTU 0x01 +#define L2CAP_INFOTYPE_EXTENED_FEATURE 0x02 +struct l2cap_sig_info_req { + uint16 infotype; +}__attribute__ ((packed)); + +#define L2CAP_INFOTYPE_SUCCESS 0x00 +#define L2CAP_INFOTYPE_NOT_SUPPORT 0x01 + +#define L2CAP_INFOTYPE_SUPPORT_FLOWCONTROL_MASK 0x01 +#define L2CAP_INFOTYPE_SUPPORT_RETRANSMISSION_MASK 0x02 +#define L2CAP_INFOTYPE_SUPPORT_BIQOS_MASK 0x04 +struct l2cap_sig_info_rsp { + uint16 infotype; + uint16 result; + /*if result == success, data: mtu(2 bytes), feature mask(4 bytes) */ + uint32 mask; +}__attribute__ ((packed)); + +//supported extern features by l2cap +#define L2CAP_EXFEATURE_FLOW_CONTROL (1<<0) +#define L2CAP_EXFEATURE_RETRANS_MODE (1<<1) +#define L2CAP_EXFEATURE_BIDIRECT_QOS (1<<2) +#define L2CAP_EXFEATURE_ENHANCED_RETRANS (1<<3) +#define L2CAP_EXFEATURE_STREAMING_MODE (1<<4) +#define L2CAP_EXFEATURE_FCS_OPTIONS (1<<5) +#define L2CAP_EXFEATURE_EXT_FLOW_SPEC (1<<6) +#define L2CAP_EXFEATURE_FIXED_CHANNELS (1<<7) +#define L2CAP_EXFEATURE_EXT_WINDOW_SIZE (1<<8) +#define L2CAP_EXFEATURE_UCD_RECEPTION (1<<9) + +#define L2CAP_SIG_CFG_MTU_MASK (1<<0) +#define L2CAP_SIG_CFG_FLUSHTO_MASK (1<<1) +#define L2CAP_SIG_CFG_QOS_MASK (1<<2) +#define L2CAP_SIG_CFG_RFC_MASK (1<<3) +#define L2CAP_SIG_CFG_FCS_MASK (1<<4) + +struct config_in_t { + uint8 cfgin_flag; + struct l2cap_sig_cfg_opt_mtu mtu_local; + struct l2cap_sig_cfg_opt_flushto flushto_remote; + struct l2cap_sig_cfg_opt_qos qos_remote; + struct l2cap_sig_cfg_opt_rfc rfc_local; + struct l2cap_sig_cfg_opt_fcs fcs_remote; +}; + +struct config_out_t { + uint8 cfgout_flag; + struct l2cap_sig_cfg_opt_mtu mtu_remote; + struct l2cap_sig_cfg_opt_flushto flushto_local; + struct l2cap_sig_cfg_opt_qos qos_local; + struct l2cap_sig_cfg_opt_rfc rfc_remote; + struct l2cap_sig_cfg_opt_fcs fcs_local; +}; + +#define L2C_NOTIFY_RESULT_ACCEPT (0) +#define L2C_NOTIFY_RESULT_REJECT (1) +#define L2C_NOTIFY_RESULT_UPPER_LAYER_HANDLED (2) + +struct l2cap_registered_psm_item_t { + struct list_node list; + uint16 psm; + int8 conn_count; /*how many conn can be created*/ + int (*l2cap_notify_callback)(enum l2cap_event_enum event, uint32 l2cap_handle, void *pdata, uint8 reason); + void (*l2cap_datarecv_callback)(uint32 l2cap_handle, struct pp_buff *ppb); +}; + +enum l2cap_channel_state_enum { + L2CAP_CLOSE, /*baseband connection closed, wait for hci conn openning, and then can send out conn request signal*/ + L2CAP_WAIT_DISCONNECT, + L2CAP_WAITING, /* waitf for the baseband connection to send out conn req signal */ + L2CAP_AUTH_PENDING, /* waiting for baseband authentication or encryption */ + L2CAP_WAIT_CONNECTION_RSP, + L2CAP_WAIT_CONFIG, + L2CAP_WAIT_CONFIG_REQ_RSP, + L2CAP_WAIT_CONFIG_RSP, + L2CAP_WAIT_CONFIG_REQ, + L2CAP_OPEN +}; + +struct l2cap_channel{ + struct list_node list; + + struct l2cap_conn *conn; + + + uint32 l2cap_handle; + + uint16 scid; + uint16 dcid; + uint16 psm_remote; + + uint8 used; /* channel used or not*/ + uint8 initiator; /* local or peer initate l2cap channel*/ + uint8 sigid_last_send; /*to save our last request signal id*/ + uint8 sigid_last_recv; /*to save the last remote's request signal id*/ + + //max co timer num is less than 255 in our stack,so just one byte is ok + uint8 disconnect_req_timeout_timer;/*to avoid disconnect req not response,so we need to give a timeout flag*/ + uint8 close_delay_timer; + uint8 wait_conn_req_timer; + uint8 wait_config_req_timer; + + uint8 disconnect_req_reason; + /* for config req and resp */ + uint8 wait_cfg_req_done; + struct config_in_t cfgin; + struct config_out_t cfgout; + + + enum l2cap_channel_state_enum state; + + int (*l2cap_notify_callback)(enum l2cap_event_enum event, uint32 l2cap_handle, void *pdata, uint8 reason); + void (*l2cap_datarecv_callback)(uint32 l2cap_handle, struct pp_buff *ppb); +#if SUPPORT_L2CAP_ENHANCED_RETRANS==1 + struct l2cap_enhanced_channel *eChannel; + uint8 channel_mode; +#endif +}; + +struct l2cap_conn { + struct list_node list; + struct bdaddr_t remote; + uint16 conn_handle; + uint8 sigid; + uint8 inuse; + + uint8 disconnect_by_acl; + uint8 disconnect_reason; + uint8 delay_free_conn_timer; + + struct list_node channels; + struct l2cap_channel l2c_channel_array[L2CAP_CHANNEL_NUM_PER_LINK]; +}; + +struct l2cap_conn_req_param_t { + uint16 conn_handle; + uint16 remote_scid; + uint16 psm; + uint8 identifier; + struct bdaddr_t remote_addr; +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +struct l2cap_channel * l2cap_accept_conn_req(struct l2cap_conn_req_param_t* req); +void l2cap_reject_conn_req(struct l2cap_conn_req_param_t* req, uint16 reason); + +int8 l2cap_send_frame_done(uint16 conn_handle, struct pp_buff *ppb); +uint8* l2cap_make_sig_req(struct l2cap_channel *channel,uint8 sig_code,uint16 sig_datalen,struct pp_buff *ppb); +struct l2cap_conn *l2cap_conn_search_conn_handle(uint16 conn_handle); +struct l2cap_channel *l2cap_channel_search_l2cap_conn(struct l2cap_conn * conn, uint16 psm); +uint16 l2cap_get_conn_handle(struct bdaddr_t *bdaddr); +void l2cap_channel_add_new(struct l2cap_conn *conn,struct l2cap_channel *channel); +struct l2cap_channel *l2cap_channel_search_scid(struct l2cap_conn *conn, uint16 scid); +struct l2cap_channel *l2cap_channel_search_psm(struct l2cap_conn *conn, uint16 psm); +//uint32 l2cap_save_channel_ctx(uint8 *ctxs_buffer, uint16 mobile_handle); +//uint32 l2cap_set_channels_ctx(uint8 *ctxs_buffer, uint8 dev_tbl_idx); +struct l2cap_channel *l2cap_channel_malloc(struct l2cap_conn *conn,uint16 psm,uint16 scid); +void l2cap_channel_free(struct l2cap_channel *channel); +void l2cap_find_and_free_pending_avdtp_channel(struct bdaddr_t* remote); +#if defined(__cplusplus) +} +#endif + +#endif /* __L2CAP_H__ */ diff --git a/services/bt_profiles_enhanced/inc/l2cap_er.h b/services/bt_profiles_enhanced/inc/l2cap_er.h new file mode 100644 index 0000000..5e8aade --- /dev/null +++ b/services/bt_profiles_enhanced/inc/l2cap_er.h @@ -0,0 +1,168 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + + +#ifndef __L2CAP_ER_H__ +#define __L2CAP_ER_H__ + +#include "l2cap.h" +#include "co_ppbuff.h" + +#if SUPPORT_L2CAP_ENHANCED_RETRANS==1 + +/* retransmission and flow control options for enhanced retransmission mode */ +#define L2CAPE_RFC_TXWINDOW 5 //in enhanced retransmission mode, this value should be between 1 and 63. 10 is just a reference, need to be modified. +#define L2CAPE_RFC_MAXTRANSMIT 3 +#define L2CAPE_RFC_RETRANSMISSION_TIMEOUT 2000 +#define L2CAPE_RFC_MONITOR_TIMEOUT 12000 +#define L2CAPE_RFC_MPS 666//666L2CAP_CFG_MTU - L2CAPE_CONTROL_LEN - L2CAPE_SDULEN_LEN - L2CAPE_FCS_LEN + +#define L2CAPE_CONTROL_LEN 2 +#define L2CAPE_SDULEN_LEN 2 +#define L2CAPE_FCS_LEN 2 +#define L2CAPE_PPB_RESERVE (L2CAPE_CONTROL_LEN+L2CAP_PPB_RESERVE) //in our design SAR is always 00, so L2CAPE_SDULEN_LEN is useless + +#define L2CAPE_STATE_XMIT 0x00 +#define L2CAPE_STATE_WAIT_F 0x01 + +#define L2CAPE_STATE_RECV 0x00 +#define L2CAPE_STATE_REJ_SEND 0x01 +#define L2CAPE_STATE_SREJ_SEND 0x02 + +#define L2CAPE_FLAG_REMOTE_BUSY (1<<0) +#define L2CAPE_FLAG_LOCAL_BUSY (1<<1) +#define L2CAPE_FLAG_RNR_SENT (1<<2) +/* After S-frame with P-bit set, a rej frame with F-bit is 0 was received before receive a frame with F-bit is set, this flag will be set. */ +#define L2CAPE_FLAG_REJ_ACTIONED (1<<3) +#define L2CAPE_FLAG_SREJ_ACTIONED (1<<4) +#define L2CAPE_FLAG_SEND_REJ (1<<5) +#define L2CAPE_FLAG_F_BIT_SET (1<<6) //indicate the bit in received frame +#define L2CAPE_FLAG_P_BIT_SET (1<<7) +#define L2CAPE_FLAG_FCS_USED (1<<8) +#define L2CAPE_FLAG_SET_F_BIT (1<<9) //indicate the bit will be set or not in sending frame +#define L2CAPE_FLAG_SET_P_BIT (1<<10) +#define L2CAPE_FLAG_SEND_ACK (1<<11) //when receive SAR_UNSEG or SAR_END, this bit is set + +#define L2CAPE_SREJ_SUPPORTED FALSE + +#define L2CAPE_EVENT_DATA_REQUEST 0x00 +#define L2CAPE_EVENT_LOCAL_BUSY_DETECTED 0x01 +#define L2CAPE_EVENT_LOCAL_BUSY_CLEAR 0x02 +#define L2CAPE_EVENT_RECV_REQSEQ_F 0x03 +#define L2CAPE_EVENT_RECV_F 0x04 +#define L2CAPE_EVENT_RETRANSMIT_EXPIRED 0x05 +#define L2CAPE_EVENT_MONITOR_EXPIRED 0x06 +#define L2CAPE_EVENT_RECV_I_FRAME 0x07 +#define L2CAPE_EVENT_RECV_RR 0x08 +#define L2CAPE_EVENT_RECV_REJ 0x09 +#define L2CAPE_EVENT_RECV_RNR 0x0A +#define L2CAPE_EVENT_RECV_SREJ 0x0B + +#define L2CAPE_SAR_UNSEG 0x00 +#define L2CAPE_SAR_START 0x01 +#define L2CAPE_SAR_END 0x02 +#define L2CAPE_SAR_CONTINUE 0x03 + +#define L2CAPE_SFRAME_TYPE_RR 0x00 +#define L2CAPE_SFRAME_TYPE_REJ 0x01 +#define L2CAPE_SFRAME_TYPE_RNR 0x02 +#define L2CAPE_SFRAME_TYPE_SREJ 0x03 + +struct l2cap_enhanced_control_i { + uint32 i_bit:1; + uint32 txSeq:6; + uint32 f_bit:1; + uint32 reqSeq:6; + uint32 sar:2; +}__attribute__ ((packed)); + +struct l2cap_enhanced_control_s { + uint32 s_bit:1; + uint32 reserve1:1; + uint32 type:2; + uint32 p_bit:1; + uint32 reserve2:2; + uint32 f_bit:1; + uint32 reqSeq:6; + uint32 reserve3:2; +}__attribute__ ((packed)); + +/* this struct is used to store sending data, we don't support segment, so sequence is always 0 */ +struct l2cap_enhanced_packet { + struct pp_buff *ppb; //a whole frame before segmented is stored in this ppb + struct l2cap_enhanced_packet *next; + struct l2cap_enhanced_control_i *i_frame; + //uint8 sequence; //the position of this packet in the origion frame +}; + +union l2cap_enhanced_control { + void *arg; + struct l2cap_enhanced_control_i *i_frame; + struct l2cap_enhanced_control_s *s_frame; +}; + +struct l2cap_enhanced_channel { + uint32 flags; + uint8 tx_state; + uint8 rx_state; + + uint8 maxRxWindow; + uint8 maxTransmit; + uint16 retransTimeout; + uint16 monitorTimeout; + uint16 sendAckTimeout; + uint8 retransTimer; + uint8 monitorTimer; + uint8 sendAckTimer; + + /* sending peer variables and sequence numbers */ + uint8 maxTxWindow; + uint8 nextTxSeq; //the next I-frame to be transmitted + uint8 expectedAckSeq; //the next I-frame expected to be acknowledged by receiving peer + uint8 unackedFrames; //holds the number of unacknowledged I-frames + struct l2cap_enhanced_packet *sendingList; //hold the unacknowledged I-frames and pending I-frames + struct l2cap_enhanced_packet *pendingList; //hold the pending I-frames, it is a member of sendingList + uint8 retryIframes[64]; //holds a retry counter for each I-frame that is sent within the receiving device's TxWindow + //uint8 pendingFrames; //holds the number of pending I-frames + //struct pp_buff *send_buf; //it's used as a queue, and store encapsulated data can be sent directly by __l2cap_send_data_ppb + uint8 retryCount; //holds the number of times an S-frame operation is retried + //uint8 framesSent; + + /* receiving peer variables and sequence numbers */ + uint8 txSeqRx; //the sequence of new I-frame + uint8 reqSeqRx; //the sequence number in an acknowledgement frame to request I-frame with TxSeq=ReqSeq and acknowledge receipt of I-frames up to and including (ReqSeq-1) + uint8 expectedTxSeq; //the value of TxSeq expected in the next I-frame + uint8 lastAckSeq; + //uint8 bufferSeq; //in this design, bufferSeq-1 is used as lastAckSeq + uint8 currentRxWindow; + uint8 bufferSeqSrej; + uint8 srejSaveReqSeq; + struct pp_buff *recv_buf; //the latest received ppb buffer + struct pp_buff *seg_buf; //when the SDU is segmented, we use this buffer to do reassemble + + union l2cap_enhanced_control control_field; +}; + +struct pp_buff *l2cap_enre_data_ppb_alloc(struct l2cap_channel *channel, uint32 len); +void l2cap_enre_free_channel(struct l2cap_enhanced_channel *eCh); +int8 l2cap_enre_send_data_ppb(struct l2cap_channel *channel, struct pp_buff *ppb); +void l2cap_enre_receive_data(struct l2cap_channel *channel, struct pp_buff *ppb); +uint8 l2cap_enre_channel_add_new(struct l2cap_channel *channel); + +#endif //if SUPPORT_L2CAP_ENHANCED_RETRANS==1 + +#endif /* __L2CAP_ER_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/l2cap_i.h b/services/bt_profiles_enhanced/inc/l2cap_i.h new file mode 100644 index 0000000..8982468 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/l2cap_i.h @@ -0,0 +1,125 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __L2CAP_I_H__ +#define __L2CAP_I_H__ + +#include "co_ppbuff.h" +#include "btlib_type.h" +#include "btm_i.h" +#include "data_link.h" + +#define PSM_SDP 0x0001 +#define PSM_RFCOMM 0x0003 +#define PSM_BNEP 0x000F +#define PSM_HID_CTRL 0x0011 +#define PSM_HID_INTR 0x0013 +#define PSM_UPNP 0x0015 +#define PSM_AVCTP 0x0017 +#define PSM_AVDTP 0x0019 +#define PSM_AVCTP_BROWSING 0x001B +#define PSM_ATT 0x001F +#define PSM_BESAUD 0x0033 + +#define L2CAP_BESAUD_EXTRA_CHAN_ID 0x0b0e + +enum l2cap_event_enum { + L2CAP_CHANNEL_CONN_REQ, + L2CAP_CHANNEL_OPENED, + L2CAP_CHANNEL_NEW_OPENED, + L2CAP_CHANNEL_TX_HANDLED, + L2CAP_CHANNEL_CLOSED, +}; + +struct l2cap_ctx_input { + struct ctx_content ctx; + struct bdaddr_t *remote; + uint32 l2cap_handle; + uint16 conn_handle; + int (*l2cap_notify_callback)(enum l2cap_event_enum event, uint32 l2cap_handle, void *pdata, uint8 reason); + void (*l2cap_datarecv_callback)(uint32 l2cap_handle, struct pp_buff *ppb); +}; + +struct l2cap_ctx_output { + uint32 l2cap_handle; +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +int8 l2cap_init ( void ); + + +int8 l2cap_register (uint16 psm, + int8 l2cap_conn_count_max, + int (*l2cap_notify_callback)(enum l2cap_event_enum event, uint32 l2cap_handle, void *pdata, uint8 reason), + void (*l2cap_datarecv_callback)(uint32 l2cap_handle, struct pp_buff *ppb) + ); + + +uint32 l2cap_open (struct bdaddr_t *remote, + uint16 psm, + int (*l2cap_notify_callback)(enum l2cap_event_enum event, uint32 l2cap_handle, void *pdata, uint8 reason), + void (*l2cap_datarecv_callback)(uint32 l2cap_handle, struct pp_buff *ppb) + ); + +void l2cap_create_besaud_extra_channel(void* remote, uint16_t channel_id, + int (*notify_callback)(enum l2cap_event_enum event, uint32 l2cap_handle, void *pdata, uint8 reason), + void (*datarecv_callback)(uint32 l2cap_handle, struct pp_buff *ppb)); + +int8 l2cap_close (uint32 l2cap_handle); + +struct pp_buff *l2cap_data_ppb_alloc(uint32 l2cap_handle, uint32 datalen); + +int8 l2cap_send_data_link(uint32 l2cap_handle, struct data_link *head, void *context); + +int8 l2cap_send_data_ppb( uint32 l2cap_handle, struct pp_buff *ppb); + +int8 l2cap_send_data_auto_fragment(uint32 l2cap_handle, const uint8* data, uint32 len, void *context); + +int8 l2cap_send_data( uint32 l2cap_handle, uint8 *data, uint32 datalen, void *context); + +int8 l2cap_unregister(uint16 psm); + +int8 l2cap_close_delay (uint32 l2cap_handle, int delay_sec); + +int32 l2cap_get_tx_mtu(uint32 l2cap_handle); + +const char *l2cap_event2str(enum l2cap_event_enum event); +const char *l2cap_psm2str(uint32 psm); + +/* below is called by lower layer (btm) */ +void l2cap_btm_notify_callback(enum btm_l2cap_event_enum event, uint16 conn_handle, void *pdata, uint8 reason); +void l2cap_btm_datarecv_callback (uint16 conn_handle, struct pp_buff *ppb); + +int8 l2cap_send_frame(uint16 conn_handle, struct pp_buff *ppb); + +struct bdaddr_t *l2cap_get_conn_remote_addr(uint32 l2cap_handle); +struct l2cap_channel *l2cap_channel_search_l2caphandle(uint32 l2cap_handle); + +uint32 l2cap_save_ctx(uint32 l2cap_handle, uint8_t *buf, uint32_t buf_len); +uint32 l2cap_restore_ctx(struct l2cap_ctx_input *input, struct l2cap_ctx_output *output); + +void l2cap_pts_send_disconnect_channel(void); +void l2cap_pts_send_l2cap_data(void); + +#if defined(__cplusplus) +} +#endif + +#endif /* __L2CAP_I_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/map_bmessage_builder.h b/services/bt_profiles_enhanced/inc/map_bmessage_builder.h new file mode 100644 index 0000000..2c8b8e6 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/map_bmessage_builder.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef MAP_BMESSAGE_BUILDER_H_INCLUDED +#define MAP_BMESSAGE_BUILDER_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +//------ 20191129 MAP_SPEC_V11 ------// +//------ This is simple version : ASCII as UTF8 ------// + +//------ MAP_SPEC_V11 3.1.3 Message format (x-bt/message) ------// +//------ VAR - VARIABLE, VAL - VALUE ------// +#define MAP_BMSG_CRLF "\r\n" +#define MAP_BMSG_object_BEGIN "BEGIN:BMSG\r\n" +#define MAP_BMSG_object_END "END:BMSG\r\n" +#define MAP_BMSG_version_VAR "VERSION:" +#define MAP_BMSG_readstatus_VAR "STATUS:" +#define MAP_BMSG_type_VAR "TYPE:" +#define MAP_BMSG_folder_VAR "FOLDER:" +#define MAP_BMSG_envelope_BEGIN "BEGIN:BENV\r\n" +#define MAP_BMSG_envelope_END "END:BENV\r\n" +#define MAP_BMSG_content_BEGIN "BEGIN:BBODY\r\n" +#define MAP_BMSG_content_END "END:BBODY\r\n" +#define MAP_BMSG_body_part_id_VAR "PARTID:" +#define MAP_BMSG_body_encoding_property_VAR "ENCODING:" +#define MAP_BMSG_body_charset_property_VAR "CHARSET:" +#define MAP_BMSG_body_language_property_VAR "LANGUAGE:" +#define MAP_BMSG_body_content_length_property_VAR "LENGTH:" +#define MAP_BMSG_body_content_BEGIN "BEGIN:MSG\r\n" +#define MAP_BMSG_body_content_END "END:MSG\r\n" + +#define MAP_BMSG_version_VAL_10 "1.0\r\n" +#define MAP_BMSG_readstatus_VAL_READ "READ\r\n" +#define MAP_BMSG_readstatus_VAL_UNREAD "UNREAD\r\n" +#define MAP_BMSG_type_VAL_EMAIL "EMAIL\r\n" +#define MAP_BMSG_type_VAL_SMS_GSM "SMS_GSM\r\n" +#define MAP_BMSG_type_VAL_SMS_CDMA "SMS_CDMA\r\n" +#define MAP_BMSG_type_VAL_MMS "MMS\r\n" +#define MAP_BMSG_body_encoding_VAL_8BIT "8BIT\r\n" +#define MAP_BMSG_body_encoding_VAL_G7BIT "G-7BIT\r\n" + +#define MAP_BMSG_vcard_BEGIN "BEGIN:VCARD\r\n" +#define MAP_BMSG_vcard_END "END:VCARD\r\n" +#define MAP_BMSG_vcard_version_VAR "VERSION:" +#define MAP_BMSG_vcard_name_VAR "N:" +#define MAP_BMSG_vcard_tel_VAR "TEL:" +#define MAP_BMSG_vcard_email_VAR "EMAIL:" + +typedef struct { + uint8 *buff; + uint32 buff_len; + uint32 msg_len; +} map_bmsg_t; + +#define BMSG_BEGIN(bmsg) \ + { \ + map_bmsg_t *__bmsg = bmsg; + +#define BMSG_ADD(str) \ + map_bmsg_builder_add(__bmsg,(const char *)str,strlen((char *)str)) + +#define BMSG_ADD_BUFF(buff,buff_len) \ + map_bmsg_builder_add(__bmsg,buff,buff_len) + +#define BMSG_END() \ + } + +int32 map_bmsg_builder_init(map_bmsg_t *bmsg, uint8 *buff, uint32 buff_len); +int32 map_bmsg_builder_add(map_bmsg_t *bmsg, const char *buff, uint32 buff_len); +uint32 map_bmsg_builder_get_length(map_bmsg_t *bmsg); + +#ifdef __cplusplus +} +#endif + +#endif // MAP_BMESSAGE_BUILDER_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/map_protocol.h b/services/bt_profiles_enhanced/inc/map_protocol.h new file mode 100644 index 0000000..c17563e --- /dev/null +++ b/services/bt_profiles_enhanced/inc/map_protocol.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef MAP_PROTOCOL_H_INCLUDED +#define MAP_PROTOCOL_H_INCLUDED + +#include "obex_tlv.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//------ MAP_SPEC_V10 5.3.2 Flags and Name ------// +typedef unsigned int map_obex_flag_t; +#define map_obex_flag_GoBackToRoot (0x02) +#define map_obex_flag_GoDown1Level (0x02) +#define map_obex_flag_GoUp1Level (0x03) + +//------ MAP_SPEC_V10 6.3.1 Application Parameters Header ------// +#define map_appparam_tlv_ID_Transparent (0x0B) +#define map_appparam_tlv_ID_Retry (0x0C) +#define map_appparam_tlv_ID_Charset (0x14) +#define map_appparam_tlv_VAL_Charset_native (0x00) +#define map_appparam_tlv_VAL_Charset_UTF8 (0x01) + +//------ INTERACES : all in one now -------/ +#define map_appparam_tlv_add_Transparent(tlv,val) \ + obex_tlv_add_1Byte(tlv, map_appparam_tlv_ID_Transparent, val) + +#define map_appparam_tlv_add_Retry(tlv,val) \ + obex_tlv_add_1Byte(tlv, map_appparam_tlv_ID_Retry, val) + +#define map_appparam_tlv_add_Charset(tlv,val) \ + obex_tlv_add_1Byte(tlv, map_appparam_tlv_ID_Charset, val) + +typedef enum { + MAP_BMSG_TYPE_EMAIL = 0, + MAP_BMSG_TYPE_SMS_GSM, // 1 + MAP_BMSG_TYPE_SMS_CDMA, // 2 + MAP_BMSG_TYPE_MMS, // 3 +} map_bmessage_type_t; + +#ifdef __cplusplus +} +#endif + +#endif // MAP_PROTOCOL_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/map_sdp.h b/services/bt_profiles_enhanced/inc/map_sdp.h new file mode 100644 index 0000000..8303b47 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/map_sdp.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef MAP_SDP_H_INCLUDED +#define MAP_SDP_H_INCLUDED + +#include "bt_common.h" +#include "bt_co_list.h" +#include "btlib_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MAP_SDP_EVT_SUCCESS = 0, + MAP_SDP_EVT_NOT_FOUND, // 1 + MAP_SDP_EVT_CONNECT_FAIL, // 2 + MAP_SDP_EVT_CONNECT_CLOSE, // 3 +} map_sdp_event_t; + +typedef struct { + uint32 rfcomm_channel; + uint32 l2cap_psm; + uint16 profile_version; + uint8 mas_instance_id; + uint8 supported_message_types; + uint32 map_supported_features; +} map_sdp_server_property_t; + +typedef struct { + union { + struct { + map_sdp_server_property_t property; + } success; + struct { + uint8 reason; + } connect_fail; + } u; +} map_sdp_callback_param; + +typedef int32 (*map_sdp_callback_t)(map_sdp_event_t event, map_sdp_callback_param *cb_param, void *priv); + +int32 map_sdp_request(struct bdaddr_t *remote, void *priv); +int32 map_sdp_register(map_sdp_server_property_t *property); + +#ifdef __cplusplus +} +#endif + +#endif // MAP_SDP_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/map_session.h b/services/bt_profiles_enhanced/inc/map_session.h new file mode 100644 index 0000000..b39a778 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/map_session.h @@ -0,0 +1,212 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef MAP_SESSION_H_INCLUDED +#define MAP_SESSION_H_INCLUDED + +#include "obex_session.h" +#include "map_protocol.h" +#include "map_bmessage_builder.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAP_SESSION_FOLDER_LEVEL_MAX (32) +#define MAP_MAX_PACKET_LENGTH (512) +#define MAP_OBEX_VERSION (0x10) + +typedef enum { + MAP_SESSION_TYPE_MAS = 0, + MAP_SESSION_TYPE_MNS, // 1 +} map_session_type_t; + +typedef struct { + map_session_type_t type; + obex_session_role_t obex_role; +} map_session_config_t; + +typedef enum { + MAP_FUNC_NONE = 0, + MAP_FUNC_SendEvent, + MAP_FUNC_SetNotificationRegistration, + MAP_FUNC_SetFolder, + MAP_FUNC_GetFolderListing, + MAP_FUNC_GetMessagesListing, + MAP_FUNC_GetMessage, + MAP_FUNC_SetMessageStatus, + MAP_FUNC_PushMessage, + MAP_FUNC_UpdateInbox, +} map_session_function_t; + +typedef struct { + union { + struct { + uint32 bmsg_offset; + } PushMessage; + struct { + uint8 level; + } SetFolder; + } state; +} map_session_function_state_t; + +typedef enum { + MAP_SESSION_ERR_NO_ERROR = 0, + MAP_SESSION_ERR_SDP_REQUEST_FAIL, // 1 + MAP_SESSION_ERR_CHANNEL_CLOSE, // 2 +} map_session_error_t; + +typedef struct { + union { + struct { + map_session_error_t error; + uint8 error_detail; + } close; + struct { + uint8 *packet; + uint32 packet_len; + } data; + struct { + struct bdaddr_t *remote; + } open; + } p; +} map_session_cb_param_t; + +typedef enum { + MAP_SESSION_EVENT_OPEN_IND = 0, + MAP_SESSION_EVENT_OPEN, // 1 + MAP_SESSION_EVENT_CLOSE, // 2 +} map_session_event_t; + +typedef enum { + MAP_SESSION_STATE_CLOSE = 0, + MAP_SESSION_STATE_SDP_REQUESTING, // 1 + MAP_SESSION_STATE_OPENING, // 2 + MAP_SESSION_STATE_CONNECTING, // 3 + MAP_SESSION_STATE_OPEN, // 4 + MAP_SESSION_STATE_CONNECTED, // 5 +} map_session_state_t; + +struct _map_session_t; + +typedef int32 (*map_session_event_handler_t)(struct _map_session_t *, map_session_event_t event, map_session_cb_param_t *param); + +typedef struct { + union { + struct + { + } SendEvent; + struct + { + } SetNotificationRegistration; + struct + { + char *folder[MAP_SESSION_FOLDER_LEVEL_MAX]; + uint8 folder_level; + uint8 up_level; + } SetFolder; + struct + { + } GetFolderListing; + struct + { + } GetMessagesListing; + struct + { + } GetMessage; + struct + { + } SetMessageStatus; + struct + { + char *folder; + uint32 folder_len; + char *msg_body; + uint32 msg_body_len; + uint8 retry; + uint8 transparent; + map_bmessage_type_t type; + char *originator_name; + uint32 originator_name_len; + char *originator_tel; + uint32 originator_tel_len; + char *receipt_name; + uint32 receipt_name_len; + char *receipt_tel; + uint32 receipt_tel_len; + } PushMessage; + struct + { + } UpdateInbox; + } p; +} map_session_function_param_t; + +typedef enum { + MAP_FUNC_ACTION_NONE = 0, + MAP_FUNC_ACTION_START, + MAP_FUNC_ACTION_STOP, + MAP_FUNC_ACTION_REQUEST, + MAP_FUNC_ACTION_RESPONSE, + MAP_FUNC_ACTION_CONNECTED, +} map_session_function_action_t; + +typedef struct { + void *priv; + union { + struct { + uint8 *packet; + uint32 packet_len; + } request; + struct { + uint8 *packet; + uint32 packet_len; + } response; + } p; +} map_session_function_action_param_t; + +typedef struct _map_session_t { + map_session_config_t config; + map_session_state_t state; + obex_session_t obex_session; + obex_transmission_t obex_transm; + struct sdp_request sdp_request; + map_sdp_callback_t sdp_callback; + map_sdp_server_property_t remote_server_property; + struct bdaddr_t remote; + map_session_event_handler_t event_handler; + uint8 transm_buffer[MAP_MAX_PACKET_LENGTH]; + uint8 tlv_buffer[MAP_MAX_PACKET_LENGTH]; + uint8 bmsg_buffer[MAP_MAX_PACKET_LENGTH]; + map_bmsg_t bmsg; + map_session_function_t function; + map_session_function_param_t function_param; + map_session_function_state_t function_state; +} map_session_t; + +typedef void (*map_callback_t) (obex_session_cb_param_t * param, map_session_t * map_session); + +void map_callback_register(map_callback_t callback); +int32 map_session_init(map_session_t *session, map_session_config_t *cfg, map_session_event_handler_t event_handler); +int32 map_session_open(map_session_t *session, struct bdaddr_t *remote); +int32 map_session_close(map_session_t *session); +int32 map_session_exec_function(map_session_t *session, map_session_function_t func, map_session_function_param_t *param); +int32 map_session_restore(map_session_t *session, uint32 conn_id,uint32 server_chnl); +bool map_session_check_is_idle(map_session_t *map_session); + +#ifdef __cplusplus +} +#endif + +#endif // MAP_SESSION_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/md5.h b/services/bt_profiles_enhanced/inc/md5.h new file mode 100644 index 0000000..74d2df5 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/md5.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __MD5_H__ +#define __MD5_H__ + +#include "obex_i.h" +#include "btlib_type.h" + +#if OBEX_AUTHENTICATION == 1 + +typedef struct _xMD5Context { + uint32 buf[4]; + uint32 bytes[2]; + uint32 in[16]; +} xMD5Context; + +void MD5(void *dest, void *orig, uint16 len); +void xMD5Init(xMD5Context * ctx); +void xMD5Update(xMD5Context * ctx, const uint8 * buf, uint16 len); +void xMD5Final(uint8 digest [ AUTH_NONCE_LEN ], xMD5Context * ctx); + +#endif + +#endif /* __MD5_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/obex.h b/services/bt_profiles_enhanced/inc/obex.h new file mode 100644 index 0000000..996c80c --- /dev/null +++ b/services/bt_profiles_enhanced/inc/obex.h @@ -0,0 +1,122 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __OBEX_H__ +#define __OBEX_H__ + +#include "rfcomm_i.h" + +enum obex_event_t{ + OBEX_EVENT_TP_CONNECTED, + OBEX_EVENT_TP_DISCONNECTED, + OBEX_EVENT_CONNECTED, + OBEX_EVENT_DISCONNECTED, + OBEX_EVENT_GET, + OBEX_EVENT_SET_PATH, + OBEX_EVENT_ABORT, + OBEX_EVENT_SUCCESS, + OBEX_EVENT_FAILED, + OBEX_EVENT_TIMEOUT +}; + +#define OBEX_FINAL_BIT 0x80 + +#define OBEX_OPCODE_CONNECT 0x00 +#define OBEX_OPCODE_DISCONNECT 0x01 +#define OBEX_OPCODE_PUT 0x02 +#define OBEX_OPCODE_GET 0x03 +#define OBEX_OPCODE_SET_PATH 0x05 +#define OBEX_OPCODE_ABORT 0xFF + +typedef uint8 obex_respcode; + +#define OBEX_RESP_CONTINUE 0x10 /* Continue */ +#define OBEX_RESP_SUCCESS 0x20 /* OK, Success */ + +#define OBEX_RESP_CREATED 0x21 /* Created */ +#define OBEX_RESP_ACCEPTED 0x22 /* Accepted */ +#define OBEX_RESP_NON_AUTHOR_INFO 0x23 /* Non-Authoritative Information */ +#define OBEX_RESP_NO_CONTENT 0x24 /* No Content */ +#define OBEX_RESP_RESET_CONTENT 0x25 /* Reset Content */ +#define OBEX_RESP_PARTIAL_CONTENT 0x26 /* Partial Content */ + +#define OBEX_RESP_MULTIPLE_CHOICES 0x30 /* Multiple Choices */ +#define OBEX_RESP_MOVED_PERMANENT 0x31 /* Moved Permanently */ +#define OBEX_RESP_MOVED_TEMPORARY 0x32 /* Moved Temporarily */ +#define OBEX_RESP_SEE_OTHER 0x33 /* See Other */ +#define OBEX_RESP_NOT_MODIFIED 0x34 /* Not Modified */ +#define OBEX_RESP_USE_PROXY 0x35 /* Use Proxy */ + +#define OBEX_RESP_BAD_REQUEST 0x40 /* Bad Request */ +#define OBEX_RESP_UNAUTHORIZED 0x41 /* Unauthorized */ +#define OBEX_RESP_PAYMENT_REQUIRED 0x42 /* Payment Required */ +#define OBEX_RESP_FORBIDDEN 0x43 /* Forbidden - operation is understood but refused */ +#define OBEX_RESP_NOT_FOUND 0x44 /* Not Found */ +#define OBEX_RESP_METHOD_NOT_ALLOWED 0x45 /* Method Not Allowed */ +#define OBEX_RESP_NOT_ACCEPTABLE 0x46 /* Not Acceptable */ +#define OBEX_RESP_PROXY_AUTHEN_REQ 0x47 /* Proxy Authentication Required */ +#define OBEX_RESP_REQUEST_TIME_OUT 0x48 /* Request Timed Out */ +#define OBEX_RESP_CONFLICT 0x49 /* Conflict */ + +#define OBEX_RESP_GONE 0x4a /* Gone */ +#define OBEX_RESP_LENGTH_REQUIRED 0x4b /* Length Required */ +#define OBEX_RESP_PRECONDITION_FAILED 0x4c /* Precondition Failed */ +#define OBEX_RESP_REQ_ENTITY_TOO_LARGE 0x4d /* Requested entity is too large */ +#define OBEX_RESP_REQ_URL_TOO_LARGE 0x4e /* Requested URL is too large */ +#define OBEX_RESP_UNSUPPORT_MEDIA_TYPE 0x4f /* Unsupported Media Type */ + +#define OBEX_RESP_INTERNAL_SERVER_ERR 0x50 /* Internal Server Error */ +#define OBEX_RESP_NOT_IMPLEMENTED 0x51 /* Not Implemented */ +#define OBEX_RESP_BAD_GATEWAY 0x52 /* Bad Gateway */ +#define OBEX_RESP_SERVICE_UNAVAILABLE 0x53 /* Service Unavailable */ +#define OBEX_RESP_GATEWAY_TIMEOUT 0x54 /* Gateway Timeout */ +#define OBEX_RESP_HTTP_VER_NO_SUPPORT 0x55 /* HTTP version not supported */ + +#define OBEX_RESP_DATABASE_FULL 0x60 /* Database Full */ +#define OBEX_RESP_DATABASE_LOCKED 0x61 /* Database Locked */ + +typedef uint8 obex_header; + +#define OBEX_HEADER_COUNT 0xC0 /* (4-byte) Number of objects */ +#define OBEX_HEADER_NAME 0x01 /* (Unicode) Object name */ +#define OBEX_HEADER_TYPE 0x42 /* (ByteSeq) MIME type of object */ +#define OBEX_HEADER_LENGTH 0xC3 /* (4-byte) Object length */ +#define OBEX_HEADER_TIME_ISO 0x44 /* (ByteSeq, ISO 8601 format) Creation or modification time for object (preferred format). */ +#define OBEX_HEADER_TIME_COMPAT 0xC4 /* (4-byte) Creation or modification time for object for backward-compatibility. */ +#define OBEX_HEADER_DESCRIPTION 0x05 /* (Unicode) Text description of object */ +#define OBEX_HEADER_TARGET 0x46 /* (ByteSeq) Target ID for operation */ +#define OBEX_HEADER_HTTP 0x47 /* (ByteSeq) An HTTP 1.x header (URL for object) */ +#define OBEX_HEADER_BODY 0x48 /* Not for use by OBEX applications */ +#define OBEX_HEADER_END_BODY 0x49 /* Not for use by OBEX applications */ +#define OBEX_HEADER_WHO 0x4A /* (ByteSeq) Who ID identifies service providing the object */ +#define OBEX_HEADER_CONNID 0xCB /* (4-byte) Identifies the connection for which the operation is directed */ +#define OBEX_HEADER_APP_PARAMS 0x4C /* (ByteSeq) Application parameters */ +#define OBEX_HEADER_AUTH_CHAL 0x4D /* (ByteSeq) Authentication challenge */ +#define OBEX_HEADER_AUTH_RESP 0x4E /* (ByteSeq) Authentication response */ +#define OBEX_HEADER_OBJECT_CLASS 0x4F /* (ByteSeq) OBEX Object class of object */ + +#define MAX_OBEX_TX_BUF_LEN 128 //need to be confirm +#define MAX_OBEX_PACKET_SIZE 0x0200 //need to be confirm, 512 + +#define OBEX_CFG_SERVER_CHANNEL 0x14 //need to be confirm + +int8 obex_init(void (*indicate_callback)(enum obex_event_t event)); +int8 obex_close(void); +void obex_rfcomm_notifyCallback(enum rfcomm_event_enum event, uint32 rfcomm_handle, void *pData, uint8 reason, void *priv); +void obex_rfcomm_dataRecvCallback(uint32 rfcomm_handle, struct pp_buff *ppb, void *priv); +//int8 obex_sendData(struct obex_client *client); + +#endif /* __OBEX_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/obex_ascii_unicode.h b/services/bt_profiles_enhanced/inc/obex_ascii_unicode.h new file mode 100644 index 0000000..0724139 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/obex_ascii_unicode.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef OBEX_ASCII_UNICODE_H_INCLUDED +#define OBEX_ASCII_UNICODE_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/* IrDA Object Exchange Protocol IrOBEX 2.1 OBEX Headers */ +/* +For Unicode text, the length field (immediately following the header ID) includes the 2 bytes of the null +terminator (0x00, 0x00). Therefore the length of the string ¡±Jumar¡± would be 12 bytes; 5 visible +characters plus the null terminator, each two bytes in length. +*/ + +/* It is not a real UNICODE. It is 2 bytes presentation of ASCII. */ + +uint32 obex_ascii_to_unicode(uint8 *ascii, uint32 ascii_len_without_null, uint8 *unicode, uint32 unicode_len_with_null); + +#ifdef __cplusplus +} +#endif + +#endif // OBEX_ASCII_UNICODE_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/obex_i.h b/services/bt_profiles_enhanced/inc/obex_i.h new file mode 100644 index 0000000..a017c50 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/obex_i.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __OBEX_I_H__ +#define __OBEX_I_H__ + +#include "obex.h" +#include "sdp.h" + +#define OBEX_AUTHENTICATION 0 +#define AUTH_NONCE_LEN 16 + +typedef uint8 obex_opcode; + +enum obex_conn_state_enum{ + OBEX_TP_CONNECTING, + OBEX_TP_CONNECTED, + OBEX_TP_DISCONNECTING, + OBEX_TP_DISCONNECTED +}; + +enum obex_state_enum{ + OBEX_IDLE, + OBEX_STANDBY, + OBEX_CONNECTING, + OBEX_CONNECTED, + OBEX_DISCONNECTING, + //OBEX_DISCONNECTED, + OBEX_GET, + OBEX_ABORT, + OBEX_SET_PATH +}; + +#define OBEX_FLAG_CONTINUE 0x01 +#define OBEX_FLAG_CHALLENGE 0x02 + +struct obex_client{ + uint8 flags; + obex_opcode opcode; + + void (*indicate_cb)(enum obex_event_t event); + void (*data_cb)(uint8 *data, uint16 len); + + uint8 *tx_buffer; + uint16 tx_length; + + uint8 rfcomm_handle; +}; + +struct obex_control_t{ + uint8_t timer_handle; + struct bdaddr_t remote; + //uint8 rfcomm_handle; + + enum obex_conn_state_enum conn_state; + enum obex_state_enum state; + + /*uint16 sendlen; + char sendData[OBEX_SENDDATA_BUF_SIZE];*/ + + void (*indicate_cb)(enum obex_event_t event); + void (*data_cb)(struct pp_buff *ppb); + + struct obex_client *pbap_client; +}; + +int8 obex_turnOn(struct obex_client *client); +int8 obex_turnOff(void); +int8 obex_parse_tx(struct obex_client *client); + +#endif /* __OBEX_I_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/obex_if.h b/services/bt_profiles_enhanced/inc/obex_if.h new file mode 100644 index 0000000..b2035a0 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/obex_if.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef OBEX_IF_H_INCLUDED +#define OBEX_IF_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif // OBEX_IF_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/obex_protocol.h b/services/bt_profiles_enhanced/inc/obex_protocol.h new file mode 100644 index 0000000..c34d486 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/obex_protocol.h @@ -0,0 +1,137 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef OBEX_PROTOCOL_H_INCLUDED +#define OBEX_PROTOCOL_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define OBEX_HOST16_TO_BE(value,ptr) \ + *(ptr+0) = ((value)>>8)&0xFF; \ + *(ptr+1) = ((value))&0xFF + +#define OBEX_HOST16_TO_LE(value,ptr) \ + *(ptr+0) = ((value))&0xFF; \ + *(ptr+1) = ((value)>>8)&0xFF + +#define OBEX_BE_TO_HOST16(ptr) \ + (*(ptr+0))<<8|(*(ptr+1)) + +#define OBEX_HOST32_TO_BE(value,ptr) \ + *(ptr+0) = ((value)>>24)&0xFF; \ + *(ptr+1) = ((value)>>16)&0xFF; \ + *(ptr+2) = ((value)>>8)&0xFF; \ + *(ptr+3) = ((value))&0xFF \ + +#define OBEX_HOST32_TO_LE(value,ptr) \ + *(ptr+0) = ((value))&0xFF; \ + *(ptr+1) = ((value)>>8)&0xFF; \ + *(ptr+2) = ((value)>>16)&0xFF; \ + *(ptr+3) = ((value)>>24)&0xFF \ + +#define OBEX_BE_TO_HOST32(ptr) \ + (*(ptr+0))<<24|(*(ptr+1))<<16|(*(ptr+2))<<8|(*(ptr+3)) + +//----- Max 128 ASCII for 'Name' ... Unicode String ------// +#define OBEX_UNICODE_STRING_SIZE_MAX (256) + +//------ GOEP_SPEC_V1.1 5.2 OBEX HEADERS ------// +typedef unsigned char obex_header_type_t; +#define obex_header_type_UnicodeText 0x00 +#define obex_header_type_ByteSequence 0x40 +#define obex_header_type_1ByteQuality 0x80 +#define obex_header_type_4ByteQuality 0xC0 + +typedef unsigned char obex_header_id_t; + +#define obex_header_id_Count 0xC0 +#define obex_header_id_Name 0x01 +#define obex_header_id_Type 0x42 +#define obex_header_id_Length 0xC3 +#define obex_header_id_Time_ISO8601 0x44 +#define obex_header_id_Time_4byte 0xC4 +#define obex_header_id_Description 0x05 +#define obex_header_id_Target 0x46 +#define obex_header_id_HTTP 0x47 +#define obex_header_id_Body 0x48 +#define obex_header_id_EndofBody 0x49 +#define obex_header_id_Who 0x4A +#define obex_header_id_ConnectionID 0xCB +#define obex_header_id_ApplicationParameters 0x4C +#define obex_header_id_AuthenticateChallenge 0x4D +#define obex_header_id_AuthenticateResponse 0x4E +#define obex_header_id_ObjectClass 0x4F + +//------ IrDA Object Exchange Protocol 3.3 OBEX Operations and Opcode definitions ------// +typedef unsigned char obex_operation_opcode_t; + +#define obex_opcode_CONNECT 0x80 +#define obex_opcode_DISCONNECT 0x81 +#define obex_opcode_PUT 0x02 +#define obex_opcode_GET 0x03 +#define obex_opcode_RESERVED 0x04 +#define obex_opcode_SETPATH 0x85 +#define obex_opcode_ABORT 0xFF +#define obex_opcode_FINAL 0x80 + +//------ IrDA Object Exchange Protocol 3.2.1 Response Code values ------// +typedef unsigned char obex_operation_response_code_t; + +#define obex_response_code_Continue 0x10 +#define obex_response_code_OK_Success 0x20 +#define obex_response_code_Created 0x21 +#define obex_response_code_Accepted 0x22 +#define obex_response_code_Non_Authoritative_Information 0x23 +#define obex_response_code_No_Content 0x24 +#define obex_response_code_Reset_Content 0x25 +#define obex_response_code_Partial_Content 0x26 +#define obex_response_code_Multiple_Choices 0x30 +#define obex_response_code_Moved_Permanently 0x31 +#define obex_response_code_Moved_temporarily 0x32 +#define obex_response_code_See_Other 0x33 +#define obex_response_code_Not_modified 0x34 +#define obex_response_code_Use_Proxy 0x35 +#define obex_response_code_Bad_Request 0x40 +#define obex_response_code_Unauthorized 0x41 +#define obex_response_code_Payment_required 0x42 +#define obex_response_code_Forbidden 0x43 +#define obex_response_code_Not_Found 0x44 +#define obex_response_code_Method_not_allowed 0x45 +#define obex_response_code_Not_Acceptable 0x46 +#define obex_response_code_Proxy_Authentication_required 0x47 +#define obex_response_code_Request_Time_Out 0x48 +#define obex_response_code_Conflict 0x49 +#define obex_response_code_Gone 0x4A +#define obex_response_code_Length_Required 0x4B +#define obex_response_code_Precondition_failed 0x4C +#define obex_response_code_Requeste_dentity_too_large 0x4D +#define obex_response_code_Request_URL_too_large 0x4E +#define obex_response_code_Unsupported_media_type 0x4F +#define obex_response_code_Internal_Server_Error 0x50 +#define obex_response_code_Not_Implemented 0x51 +#define obex_response_code_Bad_Gateway 0x52 +#define obex_response_code_Service_Unavailable 0x53 +#define obex_response_code_Gateway_Timeout 0x54 +#define obex_response_code_HTTP_version_not_supported 0x55 +#define obex_response_code_Database_Full 0x60 +#define obex_response_code_Database_Locked 0x61 + +#ifdef __cplusplus +} +#endif + +#endif // OBEX_PROTOCOL_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/obex_session.h b/services/bt_profiles_enhanced/inc/obex_session.h new file mode 100644 index 0000000..8c87f74 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/obex_session.h @@ -0,0 +1,121 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef OBEX_SESSION_H_INCLUDED +#define OBEX_SESSION_H_INCLUDED + +#include "bt_common.h" +#include "bt_co_list.h" +#include "obex_protocol.h" +#include "obex_transmission.h" +#include "obex_transportlayer.h" +#include "map_sdp.h" +#include "sdp.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef enum { + OBEX_SESSION_EVT_OPEN_IND = 0, + OBEX_SESSION_EVT_OPEN, // 1 + OBEX_SESSION_EVT_REQUEST, // 2 + OBEX_SESSION_EVT_RESPONSE, // 3 + OBEX_SESSION_EVT_CLOSE, // 4 +} obex_session_event_t; + +typedef struct { + uint8 opcode; + uint8 *packet; + uint16 packet_len; + union { + struct { + struct { + uint8 obex_version_num; + uint8 flags; + uint16 obex_max_packet_len; + } connect; + struct { + uint8 flags; + uint16 constants; + } setpath; + } request; + struct { + struct { + uint8 obex_version_num; + uint8 flags; + uint16 obex_max_packet_len; + } connect; + } response; + } p; +} obex_session_cb_param_t; + +struct _obex_session_t; + +typedef int32 (*obex_session_event_handler_t)(struct _obex_session_t *session, obex_session_event_t event, obex_session_cb_param_t *param); + +typedef enum { + OBEX_SESSION_ROLE_CLIENT = 0, + OBEX_SESSION_ROLE_SERVER, // 1 +} obex_session_role_t; + +typedef enum { + OBEX_SESSION_STATE_CLOSE = 0, + OBEX_SESSION_STATE_CONNECTING, // 1 + OBEX_SESSION_STATE_OPEN, // 2 + OBEX_SESSION_STATE_DISCONNECTING, // 3 +} obex_session_state_t; + +typedef struct { + obex_session_role_t role; + uint32 remote_rfcomm_channel; + uint32 remote_l2cap_psm; + uint8 local_version; + uint16 max_obex_packet_length; + uint8 local_rfcomm_channel; + uint8 local_l2cap_psm; + obex_transport_type_t transport_type; + void *priv; +} obex_session_config_t; + +typedef struct _obex_session_t{ + obex_session_config_t config; + obex_session_state_t state; + obex_transport_t transport; + obex_transmission_t *transmission; + struct bdaddr_t remote; + uint32 connectionID; + obex_operation_opcode_t op; + obex_session_event_handler_t event_handler; +} obex_session_t; + +int32 obex_session_init(obex_session_t *session, obex_session_config_t *config, obex_session_event_handler_t event_handler); +int32 obex_session_open(obex_session_t *session, struct bdaddr_t *remote); +int32 obex_session_connect(obex_session_t *session, obex_transmission_t *transmission); +int32 obex_session_disconnect(obex_session_t *session, obex_transmission_t *transmission); +int32 obex_session_put(obex_session_t *session, obex_transmission_t *transmission); +int32 obex_session_get(obex_session_t *session, obex_transmission_t *transmission); +int32 obex_session_setpath(obex_session_t *session, obex_transmission_t *transmission); +int32 obex_session_abort(obex_session_t *session, obex_transmission_t *transmission); +int32 obex_session_response(obex_session_t *session, obex_transmission_t *transmission); +int32 obex_session_close(obex_session_t *session); +int32 obex_session_restore(obex_session_t *session,uint32 connectionID,uint32 server_chnl); + +#ifdef __cplusplus +} +#endif + +#endif // OBEX_SESSION_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/obex_tlv.h b/services/bt_profiles_enhanced/inc/obex_tlv.h new file mode 100644 index 0000000..0e8e386 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/obex_tlv.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef OBEX_TLV_H_INCLUDED +#define OBEX_TLV_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char obex_tlv_id_t; +typedef unsigned char obex_tlv_length_t; + +typedef struct { + uint8 *buff; + uint32 buff_max_len; + uint32 packet_len; +} obex_tlv_t; + +int32 obex_tlv_init(obex_tlv_t *tlv, uint8 *buff, uint32 buff_len); +int32 obex_tlv_add_1Byte(obex_tlv_t *tlv, obex_tlv_id_t id, uint8 value); +int32 obex_tlv_add_2Bytes(obex_tlv_t *tlv, obex_tlv_id_t id, uint16 value, bool is_le); +int32 obex_tlv_add_4Bytes(obex_tlv_t *tlv, obex_tlv_id_t id, uint32 value, bool is_le); +int32 obex_tlv_add_buffer(obex_tlv_t *tlv, obex_tlv_id_t id, obex_tlv_length_t lenght, uint8 *value); +uint32 obex_tlv_get_length(obex_tlv_t *tlv); + +#ifdef __cplusplus +} +#endif + +#endif // OBEX_TLV_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/obex_transmission.h b/services/bt_profiles_enhanced/inc/obex_transmission.h new file mode 100644 index 0000000..7f6792f --- /dev/null +++ b/services/bt_profiles_enhanced/inc/obex_transmission.h @@ -0,0 +1,161 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef OBEX_TRANSMISSION_H_INCLUDED +#define OBEX_TRANSMISSION_H_INCLUDED + +#include "bt_common.h" +#include "bt_co_list.h" +#include "obex_protocol.h" + +/*------ What Is A Transmission ------*/ +/* An user (application) fires a operation (CONNECT/DISCONNECT/PUT/GET/SETPATH/ABORT) to server to do something */ +/* The operation is in fact a packet of data which is called Transmission here */ +/* A Transmission is composed of fixed 'Field' plus some optional 'HEADER' */ +/* For the fixed 'Field', here using obex_transmisson_prepare to reserve the buffer in Transmission */ +/* For the optional 'Header', here using obex_transmisson_add_XXX to add it in Transmission */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint16 len; + uint8 *text; + uint8 valid; +} obex_transmission_header_Unicode_t; + +typedef struct { + uint16 len; + uint8 *buff; + uint8 valid; +} obex_transmission_header_ByteSequence_t; + +typedef struct { + uint8 value; + uint8 valid; +} obex_transmission_header_1ByteQuality; + +typedef struct { + uint32 value; + uint8 valid; +} obex_transmission_header_4ByteQuality; + +typedef struct { + obex_transmission_header_4ByteQuality Count; + obex_transmission_header_Unicode_t Name; + obex_transmission_header_ByteSequence_t Type; + obex_transmission_header_4ByteQuality Length; + obex_transmission_header_ByteSequence_t Time_ISO8601; + obex_transmission_header_4ByteQuality Time_4Bytes; + obex_transmission_header_Unicode_t Description; + obex_transmission_header_ByteSequence_t Target; + obex_transmission_header_ByteSequence_t HTTP; + obex_transmission_header_ByteSequence_t Body; + obex_transmission_header_ByteSequence_t EndOfBody; + obex_transmission_header_ByteSequence_t Who; + obex_transmission_header_4ByteQuality ConnectionID; + obex_transmission_header_ByteSequence_t AppParameters; + obex_transmission_header_ByteSequence_t AuthChallenge; + obex_transmission_header_ByteSequence_t AuthResponse; + obex_transmission_header_ByteSequence_t ObjectClass; +} obex_transmission_headers_t; + +typedef struct { + uint8 *buff; + uint16 packet_len; + uint16 max_buff_len; + bool is_final; + uint8 flag; +} obex_transmission_t; + +//------ Initialize a transmission in a give buffer ------// +int32 obex_transmission_init(obex_transmission_t *trasmission, uint8 *buff, uint32 len); +int32 obex_transmission_prepare(obex_transmission_t *trasmission, obex_operation_opcode_t operation_code); + +int32 obex_transmission_parse_headers(uint8 *buff, uint32 len, obex_transmission_headers_t *headers); + +bool obex_is_final_transmission(obex_transmission_t *transmission); +void obex_transmission_set_final(obex_transmission_t *transmission, bool final); +uint8 obex_transmission_get_flag(obex_transmission_t *transmission); +void obex_transmission_set_flag(obex_transmission_t *transmission, uint8 flag); + +#define obex_transmission_add_Count(tr,Count) \ + obex_transmission_add_4ByteQuantity(tr,obex_header_id_Count,Count) + +#define obex_transmission_add_Name(tr,name,name_len_without_null) \ + obex_transmission_add_Unicode(tr,obex_header_id_Name,name,name_len_without_null) + +#define obex_transmission_add_Type(tr,type,type_len_with_null) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_Type,type,type_len_with_null) + +#define obex_transmission_add_Length(tr,Length) \ + obex_transmission_add_4ByteQuantity(tr,obex_header_id_Length,Length) + +#define obex_transmission_add_Time_ISO8601t(tr,time,time_len) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_Time_ISO8601,time,time_len) + +#define obex_transmission_add_Time_4Byte(tr,Time) \ + obex_transmission_add_4ByteQuantity(tr,obex_header_id_Time_4byte,Time) + +#define obex_transmission_add_Description(tr,desc,desc_len_without_null) \ + obex_transmission_add_Unicode(tr,obex_header_id_Description,desc,desc_len_without_null) + +#define obex_transmission_add_Target(tr,uuid,uuid_len) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_Target,uuid,uuid_len) + +#define obex_transmission_add_HTTP(tr,http,http_len) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_HTTP,http,http_len) + +#define obex_transmission_add_Body(tr,body,body_len) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_Body,body,body_len) + +#define obex_transmission_add_EndOfBody(tr,body,body_len) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_EndofBody,body,body_len) + +#define obex_transmission_add_Who(tr,who,who_len) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_Who,who,who_len) + +#define obex_transmission_add_ConnectionID(tr,ConnectionID) \ + obex_transmission_add_4ByteQuantity(tr,obex_header_id_ConnectionID,ConnectionID) + +#define obex_transmission_add_ApplicationParameters(tr,tlv,tlv_len) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_ApplicationParameters,tlv,tlv_len) + +#define obex_transmission_add_AuthenticateChallenge(tr,ac,ac_len) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_AuthenticateChallenge,ac,ac_len) + +#define obex_transmission_add_AuthenticateResponse(tr,as,as_len) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_AuthenticateResponse,as,as_len) + +#define obex_transmission_add_ObjectClass(tr,oc,oc_len) \ + obex_transmission_add_ByteSequence(tr,obex_header_id_ObjectClass,oc,oc_len) + +//------ null terminated Unicode text, length prefixed with 2 byte unsigned integer ------// +int32 obex_transmission_add_Unicode(obex_transmission_t *tr, obex_header_id_t id, uint8 *ascii, uint32 ascii_len_without_null); +//------ byte sequence, length prefixed with 2 byte unsigned integer ------// +int32 obex_transmission_add_ByteSequence(obex_transmission_t *tr, obex_header_id_t id, uint8 *bytes, uint32 bytes_len); +//------ 1 byte quantity ------// +int32 obex_transmission_add_1ByteQuantity(obex_transmission_t *tr, obex_header_id_t id, uint8 value); +//------ 4 byte quantity ------// +int32 obex_transmission_add_4ByteQuantity(obex_transmission_t *tr, obex_header_id_t id, uint32 value); + + +#ifdef __cplusplus +} +#endif + +#endif // OBEX_TRANSMISSION_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/obex_transportlayer.h b/services/bt_profiles_enhanced/inc/obex_transportlayer.h new file mode 100644 index 0000000..aebb939 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/obex_transportlayer.h @@ -0,0 +1,122 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef OBEX_TRANSPORTLAYER_H_INCLUDED +#define OBEX_TRANSPORTLAYER_H_INCLUDED + +#include "bt_common.h" +#include "bt_co_list.h" +#include "rfcomm_i.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + OBEX_TRANSPORT_TYPE_RFCOMM = 0, + OBEX_TRANSPORT_TYPE_L2CAP, // 1 +} obex_transport_type_t; + +typedef enum { + OBEX_TRANSPORT_ROLE_CLIENT = 0, + OBEX_TRANSPORT_ROLE_SERVER, // 1 +} obex_transport_role_t; + +typedef enum { + OBEX_TRANSPORT_CONN_STATE_CLOSE = 0, + OBEX_TRANSPORT_CONN_STATE_CONNECTING, // 1 + OBEX_TRANSPORT_CONN_STATE_CONNECTED, // 2 + OBEX_TRANSPORT_CONN_STATE_DISCONNECTING, // 3 +} obex_transport_conn_state_t; + +typedef enum { + OBEX_TRANSPORT_LISTEN_STATE_IDLE = 0, + OBEX_TRANSPORT_LISTEN_STATE_LISTENING, // 1 +} obex_transport_listen_state_t; + +typedef struct { + obex_transport_type_t type; + union { + struct { + uint32 remote_channel; + uint32 local_channel; + uint32 rfcomm_handle; + } rfcomm; + struct { + uint32 psm; + uint32 channel; + } l2cap; + } u; + void *priv; +} obex_transport_config_t; + +typedef enum { + OBEX_TRANSPORT_EVENT_OPEN_IND = 0, + OBEX_TRANSPORT_EVENT_OPEN, // 1 + OBEX_TRANSPORT_EVENT_TX_HANDLED, // 2 + OBEX_TRANSPORT_EVENT_CLOSE,// 3 + OBEX_TRANSPORT_EVENT_DATA, // 4 +} obex_transport_event_t; + +typedef struct { + union { + struct { + } open_ind; + struct { + } open; + struct { + } tx_handled; + struct { + } close; + struct { + uint8 *buff; + uint32 len; + } data; + } u; +} obex_transport_cb_param_t; + +struct _obex_transport_t; + +typedef int32 (*obex_transport_connect_t) (struct _obex_transport_t *transport, struct bdaddr_t *remote); +typedef int32 (*obex_transport_listen_t) (struct _obex_transport_t *transport); +typedef int32 (*obex_transport_disconnect_t) (struct _obex_transport_t *transport); +typedef uint32 (*obex_transport_send_t)(struct _obex_transport_t *transport, uint8 *buff, uint32 buff_len); +typedef int32 (*obex_transport_event_handler_t)(struct _obex_transport_t *transport, obex_transport_event_t event, obex_transport_cb_param_t *param); + +typedef struct _obex_transport_t{ + struct list_node node; + obex_transport_conn_state_t conn_state; + obex_transport_listen_state_t listen_state; + obex_transport_config_t config; + + obex_transport_send_t send; + obex_transport_listen_t listen; + obex_transport_connect_t connect; + obex_transport_disconnect_t disconnect; + obex_transport_event_handler_t event_handler; +} obex_transport_t; + +const char *obex_transport_conn_state_2_str(obex_transport_conn_state_t state); +const char *obex_transport_event_2_str(obex_transport_event_t event); +int32 obex_transport_init(obex_transport_t *transport, obex_transport_config_t *config, obex_transport_event_handler_t event_handler); +int32 obex_transport_restore(obex_transport_t *transport,uint32 server_chnl); +void obex_rfcomm_notify_cb(enum rfcomm_event_enum event,uint32 rfcomm_handle,void *data, uint8 reason, void *priv); +void obex_rfcomm_data_recv_cb(uint32 rfcomm_handle,struct pp_buff *ppb, void *priv); + +#ifdef __cplusplus +} +#endif + +#endif // OBEX_TRANSPORTLAYER_H_INCLUDED diff --git a/services/bt_profiles_enhanced/inc/overide.h b/services/bt_profiles_enhanced/inc/overide.h new file mode 100644 index 0000000..c67c21b --- /dev/null +++ b/services/bt_profiles_enhanced/inc/overide.h @@ -0,0 +1,1013 @@ +/**************************************************************************** + * + * File: + * $Id: overide.h 2809 2011-10-11 21:42:02Z dliechty $ + * $Product: BES AV Profiles SDK v2.x $ + * $Revision: 2809 $ + * + * Description: Configuration overrides for the A2DP project. + * + * Created: June 15, 2004 + * + * Copyright 2004-2005 Extended Systems, Inc. + * Portions copyright BES. + * All rights reserved. All unpublished rights reserved. + * + * Unpublished Confidential Information of BES. + * Do Not Disclose. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __OVERIDE_H +#define __OVERIDE_H + +/* WARNING: The values in this overide.h file were selected specifically for + * this sample application. If you change them, the sample application may fail + * to compile or not work properly. + */ + +/**************************************************************************** + * + * Module Selection + * Please select the module/profiles which are needed + * + ****************************************************************************/ + +/* Initialize the necessary modules */ +#if defined (BES_AUD) +#if defined (__HSP_ENABLE__) +#define XA_LOAD_LIST XA_MODULE(CMGR) \ + XA_MODULE(HF) \ + XA_MODULE(HS) \ + XA_MODULE(AVDTP) \ + XA_MODULE(AVDEV) \ + XA_MODULE(A2DP) \ + XA_MODULE(AVRCP) \ + XA_MODULE(HID) \ + XA_MODULE(BESAUD) +#else +#define XA_LOAD_LIST XA_MODULE(CMGR) \ + XA_MODULE(HF) \ + XA_MODULE(AVDTP) \ + XA_MODULE(AVDEV) \ + XA_MODULE(A2DP) \ + XA_MODULE(AVRCP) \ + XA_MODULE(HID) \ + XA_MODULE(BESAUD) +#endif + +#else + +#if defined (__HSP_ENABLE__) +#define XA_LOAD_LIST XA_MODULE(CMGR) \ + XA_MODULE(HF) \ + XA_MODULE(HS) \ + XA_MODULE(AVDTP) \ + XA_MODULE(AVDEV) \ + XA_MODULE(A2DP) \ + XA_MODULE(AVRCP) \ + XA_MODULE(HID) +#else +#define XA_LOAD_LIST XA_MODULE(CMGR) \ + XA_MODULE(HF) \ + XA_MODULE(AVDTP) \ + XA_MODULE(AVDEV) \ + XA_MODULE(A2DP) \ + XA_MODULE(AVRCP) \ + XA_MODULE(HID) +#endif +#endif + /* XA_MODULE(HF) \ + XA_MODULE(OBEX) \ + XA_MODULE(GOEP) \ + XA_MODULE(OPUSH) \ + XA_MODULE(FTP) \ + XA_MODULE(CMGR) \ + XA_MODULE(SPPDRV) \ + XA_MODULE(OBEX) \ + XA_MODULE(GOEP) \ + XA_MODULE(HF) \ + XA_MODULE(HS) \ + */ + +/***************************************************************************** + * Global Definition for feature selection + * Based on BlueSDK Porting API.pdf + *****************************************************************************/ + +/* Part 1. Global definition */ +#define BT_STACK XA_ENABLED +#define TCP_STACK XA_DISABLED +#define IRDA_STACK XA_DISABLED + +#define BT_BEST_SYNC_CONFIG XA_ENABLED + +//#define XA_DEBUG XA_DISABLED /* enable debug */ +#ifndef XA_DEBUG +#define XA_DEBUG XA_DISABLED +#endif +#define XA_DEBUG_PRINT XA_DEBUG // enable debug information output, must imprement OS_Report +#define XA_ERROR_CHECK XA_ENABLED /* enable error check of stack */ +//#define XA_CONTEXT_PTR XA_ENABLED /* disable dymanical RAM allocation. The context structures are performed using "->" operand */ +#define XA_CONTEXT_PTR XA_DISABLED /* disable dymanical RAM allocation. The context structures are performed using "->" operand */ + +#define XA_INTEGER_SIZE 4 +#define XA_USE_ENDIAN_MACROS XA_DISABLED +//#define XA_MULTITASKING XA_DISABLED //Need implement OS_StartTimer, OS_CancelTimer, OS_NotifyEvm, OS_LockStack, OS_UnlockStack +#define XA_MULTITASKING XA_ENABLED //Need implement OS_StartTimer, OS_CancelTimer, OS_NotifyEvm, OS_LockStack, OS_UnlockStack +#define XA_EVENTMGR XA_ENABLED //Enable Event Manager (EVM) +//#define XA_SNIFFER XA_DISABLED //to sniff stack operation, need to disable in release stack +//#define XA_DECODER XA_DISABLED //to decode stack information in sniff and debug +//#define XA_STATISTICS XA_DISABLED /* Enable statistics */ +#define XA_SNIFFER XA_DISABLED //to sniff stack operation, need to disable in release stack +#define XA_DECODER XA_DEBUG //to decode stack information in sniff and debug +#define XA_STATISTICS XA_DISABLED /* Enable statistics */ + +/* Part 2. Global Configuration */ +#define BDADDR_NTOA_SIZE 18 + +#define NUM_BT_DEVICES 2 +#define NUM_SCO_CONNS 2 + +#define NUM_BLE_DEVICES 2 +/* Part 3. Management Entity Configuration */ +#define BT_ALLOW_SCAN_WHILE_CON XA_ENABLED +#define BT_SCO_HCI_DATA XA_DISABLED +#define BT_SCO_HCI_NUM_PACKETS (8 * NUM_SCO_CONNS) +#define BT_SCO_USE_LEGACY_CONNECT XA_DISABLED +#define BT_SECURITY XA_ENABLED +#define BT_SECURITY_TIMEOUT 80 //seconds + +//#define BT_DEFAULT_PAGE_SCAN_WINDOW 0 +//#define BT_DEFAULT_PAGE_SCAN_INTERVAL 0 +//#define BT_DEFAULT_INQ_SCAN_WINDOW 0 +//#define BT_DEFAULT_INQ_SCAN_INTERVAL 0 + +//#define BT_DEFAULT_PAGE_SCAN_WINDOW 0x20 +//#define BT_DEFAULT_PAGE_SCAN_INTERVAL 0x40 +#define BT_DEFAULT_PAGE_SCAN_WINDOW 0x12 +#define BT_DEFAULT_PAGE_SCAN_INTERVAL 0x800 +#define BT_DEFAULT_INQ_SCAN_WINDOW 0x12 +#define BT_DEFAULT_INQ_SCAN_INTERVAL 0x800 +#define BT_DEFAULT_ACCESS_MODE_NC BAM_GENERAL_ACCESSIBLE +#define BT_DEFAULT_ACCESS_MODE_C BAM_NOT_ACCESSIBLE + +#define BT_DEFAULT_ACCESS_MODE_PAIR BAM_GENERAL_ACCESSIBLE +#define BT_DEFAULT_ACCESS_MODE_NCON BAM_CONNECTABLE_ONLY +#define BT_DEFAULT_ACCESS_MODE_1C BAM_CONNECTABLE_ONLY +#define BT_DEFAULT_ACCESS_MODE_2C BAM_NOT_ACCESSIBLE + +#define BT_HCI_NUM_INIT_RETRIES 0x80 +#define BT_DEFAULT_PAGE_TIMEOUT 0x2000 //0x2000=5.12s +#define BT_DEFAULT_PAGE_TIMEOUT_IN_MS 5000 +#define BT_PACKET_HEADER_LEN 25 +#define NUM_KNOWN_DEVICES 10 +#define DS_NUM_SERVICES 8 + + +/* Part 4. HCI */ +#define HCI_RESET_TIMEOUT 10000 //=10s +#define HCI_NUM_PACKETS (2 * NUM_BT_DEVICES) +#define HCI_NUM_COMMANDS 1 +#define HCI_NUM_EVENTS 10 +#define HCI_CMD_PARM_LEN 248 +#define HCI_HOST_FLOW_CONTROL XA_ENABLED //IMPORTANT + +#define HCI_MAX_COMPLETED_PKTS 8 +#define HCI_SCO_FLOW_CONTROL XA_DISABLED //IMPORTANT +#define HCI_ALLOW_PRESCAN XA_DISABLED +#define HCI_NUM_ACL_TX_RESERVE 0 +#define HCI_NUM_UNCONN_RESERVE 0 +#if defined(A2DP_SCALABLE_ON) +#define HCI_ACL_DATA_SIZE 1000 +#else +#if defined(__3M_PACK__) +#define HCI_ACL_DATA_SIZE 1000 +#else +#define HCI_ACL_DATA_SIZE 800 +#endif +//#define HCI_ACL_DATA_SIZE 350 +#endif +#ifndef _SCO_BTPCM_CHANNEL_ +#define HCI_SCO_DATA_SIZE 180 +#else +#define HCI_SCO_DATA_SIZE 4 +#endif +//#define HCI_NUM_ACL_BUFFERS (L2CAP_ERTM_RX_WIN_SIZE * L2CAP_NUM_ENHANCED_CHANNELS) +#define HCI_NUM_ACL_BUFFERS 6 +#ifndef _SCO_BTPCM_CHANNEL_ +#define HCI_NUM_SCO_BUFFERS 6 +#else +#define HCI_NUM_SCO_BUFFERS 1 +#endif + +#define HCI3W_SLIDING_WINDOW (3) +#define HCI3W_MAX_PAYLOAD (0x0FFF) +#define HCI3W_MEM_POOL_SIZE (0x8000) +#define HCI3W_UART_MULTIPLIER (1) +#define HCI3W_TXQ_MAX (8) +#define HCI3W_CRC XA_ENABLED +#define HCI3W_OOF XA_ENABLED +#define HCI3W_DEBUG_TXQ XA_DISABLED + +#define BT_EXPOSE_BCCMD XA_DISABLED + + +/* Part 5. Connection Manager (CMGR) */ +#define CMGR_DEFAULT_SNIFF_EXIT_POLICY CMGR_SNIFF_EXIT_ON_AUDIO +#define CMGR_DEFAULT_SNIFF_TIMER CMGR_SNIFF_DONT_CARE +//#define CMGR_AUDIO_DEFAULT_PARMS CMGR_AUDIO_PARMS_S3 +//#define CMGR_AUDIO_DEFAULT_PARMS CMGR_AUDIO_PARMS_SCO +#define CMGR_AUDIO_DEFAULT_PARMS CMGR_AUDIO_PARMS_S4 +#define CMGR_MEMORY_EXTERNAL XA_DISABLED +#define CMGR_SNIFF_MIN_INTERVAL 800 +#define CMGR_SNIFF_MAX_INTERVAL 800 +#define CMGR_SNIFF_ATTEMPT 3 +#define CMGR_SNIFF_TIMEOUT 1 + + +/* Part 6. L2CAP definitions */ +//#define L2CAP_NUM_CHANNELS 10 +//#define L2CAP_NUM_ENHANCED_CHANNELS 3 +#define L2CAP_NUM_ENHANCED_CHANNELS 0 + +#if defined(__3M_PACK__) +#define L2CAP_MTU 1021 +#else +#define L2CAP_MTU 679 +#endif +#if L2CAP_NUM_ENHANCED_CHANNELS +#define L2CAP_MPS (L2CAP_MTU-7) +#else +#define L2CAP_MPS L2CAP_MTU +#endif + +#ifdef __ACC_FRAGMENT_COMPATIBLE__ +#define L2CAP_MTU_FOR_ACC 1024 +#endif + +#define L2CAP_NUM_PROTOCOLS 12 +#define L2CAP_PING_SUPPORT XA_DISABLED +#define L2CAP_FCS_OPTION L2FCS_16BIT + +#define L2CAP_NUM_GROUPS 0 //8 +#define L2CAP_GET_INFO_SUPPORT XA_DISABLED +#define L2CAP_FLEXIBLE_CONFIG XA_DISABLED +#define L2CAP_RTX_TIMEOUT 30 //seconds +#define L2CAP_ERTX_TIMEOUT 150 //seconds +#define L2CAP_ERTM_TX_WIN_SIZE 5 +#define L2CAP_ERTM_RX_WIN_SIZE 5 +#define L2CAP_ERTM_MAX_TRANSMIT 10 +#define L2CAP_ERTM_RETRANS_TIMEOUT 2000 //milliseconds +#define L2CAP_ERTM_MONITOR_TIMEOUT 12000 //MILLISECONDS +#define L2CAP_ERTM_ACK_TIMEOUT (L2CAP_ERTM_RETRANS_TIMEOUT/2) +#define L2CAP_ERTM_SREJ_ENABLE XA_DISABLED +#define L2CAP_ERTM_FRAGMENTS XA_DISABLED +#define L2CAP_ERTM_IMMEDIATE XA_DISABLED +#define L2CAP_FLOW_CONTROL XA_DISABLED +#define L2CAP_PRIORITY XA_DISABLED +//#define L2CAP_PRIORITY XA_ENABLED +#define L2CAP_DEREGISTER_FUNC XA_DISABLED +//#define L2CAP_NUM_SIGNAL_PACKETS (NUM_BT_DEVICES * L2CAP_NUM_ENHANCED_CHANNELS *4) +#define L2CAP_NUM_SIGNAL_PACKETS (NUM_BT_DEVICES * 2) +#define L2CAP_NUM_TX_PACKETS ((L2CAP_ERTM_TX_WIN_SIZE * L2CAP_NUM_ENHANCED_CHANNELS) + 2) +#define L2CAP_PRELUDE_SIZE 7 +#define L2CAP_VIOLATE_SPEC_MTU_NEG XA_DISABLED + +//Not documented +//#define L2CAP_DEFAULT_MTU 672 +//#define L2CAP_DEFAULT_MTU 335 +#define L2CAP_MINIMUM_MTU 0x0030 +#define L2CAP_MAXIMUM_MTU L2CAP_MTU +#define L2CAP_MANGLER_TESTING XA_DISABLED +#define L2CAP_ENHANCED_IOP_TESTING XA_DISABLED + +/* Part 7. SDP */ +#define SDP_CLIENT_SUPPORT XA_ENABLED +#define SDP_SERVER_SUPPORT XA_ENABLED +#define SDP_CLIENT_LOCAL_MTU L2CAP_MTU +#define SDP_PARSING_FUNCS XA_ENABLED +#define SDP_NUM_CLIENTS NUM_BT_DEVICES +#define SDP_ACTIVE_CLIENTS (NUM_BT_DEVICES) +#define SDP_SERVER_SEND_SIZE 128 +#define SDP_SERVER_MAX_LEVEL 4 +#define SDP_SERVER_LOCAL_MTU L2CAP_MTU +#define SDP_SERVER_MIN_REMOTE_MTU 48 + +/* Part 8. RFCOMM */ +#define RFCOMM_PROTOCOL XA_ENABLED +#define RF_SECURITY XA_ENABLED +#define RF_SEND_TEST XA_DISABLED //XA_ENABLED +#define RF_SEND_CONTROL XA_DISABLED //XA_ENABLED +#define NUM_RF_SERVERS 30 +#define NUM_RF_CHANNELS (NUM_RF_SERVERS * 2) +#define RF_MAX_FRAME_SIZE L2CAP_MTU-5 +#define RF_CONNECT_TIMEOUT 60000 //milliseconds +#define RF_T1_TIMEOUT 20000 //milliseconds +#define RF_T2_TIMEOUT 20000 //milliseconds + +#define RF_MIN_FRAME_SIZE 23 +#define RF_DEFAULT_FRAMESIZE 127 +#define RF_DEFAULT_PRIORITY 0 +#define RF_LOWEST_PRIORITY 63 + +/* Part 9. SPP */ +#define SPP_SERVER XA_ENABLED +#define SPP_CLIENT XA_ENABLED + +/* Part 10. Unplugfest testing */ +#define UPF_TWEAKS XA_DISABLED + +/*BES AUD data path*/ +#ifdef BES_AUD +#define BESAUD_DEVICE XA_ENABLED +#else +#define BESAUD_DEVICE XA_DISABLED +#endif + +/********************************************************************************** + * + * AV Profile SDK + * + **********************************************************************************/ +/* A2DP definitions */ + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +#define A2DP_SOURCE XA_ENABLED +#else +#define A2DP_SOURCE XA_DISABLED +#endif +#define A2DP_SINK XA_ENABLED +#define A2DP_MINOR_DEVICE_CLASS COD_MINOR_AUDIO_HIFIAUDIO +#define A2DP_SRC_FEATURES A2DP_SRC_FEATURE_PLAYER +#define A2DP_SNK_FEATURES (A2DP_SNK_FEATURE_SPEAKER | A2DP_SNK_FEATURE_HEADPHONE) +#define A2DP_MAX_STREAMINFOS 8 + +//#define A2DP_APP_USE_WMSDK XA_ENABLED //for Windows only +#define A2DP_APP_USE_WMSDK XA_DISABLED + +/* VDP */ +#define VDP_SOURCE XA_DISABLED +#define VDP_SINK XA_DISABLED +#define VDP_MINOR_DEVICE_CLASS COD_MINOR_AUDIO_VIDEOCAMERA +#define VDP_MAX_STREAMINFOS 8 + +/* AVDTP */ +#define AVDTP_RTX_SIG_TIMEOUT 3000 +#define AVDTP_MAX_CODEC_ELEM_SIZE 10 +#define AVDTP_MAX_CP_VALUE_SIZE 10 +#define AVDTP_NUM_TX_PACKETS 4 +#define AVDTP_TX_SIGNAL_MPS L2CAP_MINIMUM_MTU +#define AVDTP_RX_SIGNAL_MPS L2CAP_MPS +#define AVDTP_TX_STREAM_MPS L2CAP_MPS +#define AVDTP_RX_STREAM_MPS L2CAP_MPS +#define BT_STATUS_ABORTED (BT_STATUS_LAST_CODE + 1) +#define AV_WORKER 1 +/* AVRCP */ +#define AVRCP_VERSION_1_3_ONLY XA_DISABLED //XA_DISABLED +#define AVRCP_RTX_CMD_TIMEOUT 1000 +#define AVRCP_RTX_ADV_CMD_TIMEOUT 1000 +#define AVRCP_RTX_BROWSE_CMD_TIMEOUT 10000 +#define AVRCP_ADVANCED_TARGET XA_DISABLED + +#define AVRCP_ADVANCED_TARGET_SLIM XA_ENABLED +#define AVRCP_ADVANCED_CONTROLLER XA_ENABLED +#define AVRCP_PROVIDER_NAME 'M', 'V', 'I', 'E', 'W', '\0' +#define AVRCP_PROVIDER_NAME_LEN 6 +#define AVRCP_CT_SERVICE_NAME 'M', 'V', 'I', 'E', 'W', '\0' +#define AVRCP_CT_SERVICE_NAME_LEN 6 +#define AVRCP_TG_SERVICE_NAME 'M', 'V', 'I', 'E', 'W', '\0' +#define AVRCP_TG_SERVICE_NAME_LEN 6 +#define AVRCP_PANEL_COMPANY_ID "\xFF\xFF\xFF" +#define AVRCP_SUBUNIT_OP_QUEUE_MAX 15 +#define AVRCP_BLUETOOTH_COMPANY_ID "\x00\x19\x58" +#define AVRCP_MAX_CHAR_SETS 10 +#define AVRCP_ADVANCED_RESPONSE_SIZE 128 +#define AVRCP_NO_TRACK_CURRENTLY_SELECTED 0xFFFFFFFF +#define AVRCP_MAX_MEDIA_PLAYERS 10 +#define AVRCP_BROWSING_TARGET XA_DISABLED +#define AVRCP_BROWSING_CONTROLLER XA_DISABLED +#define AVRCP_LIST_PLAYERS_ENABLED XA_DISABLED /*((AVRCP_ADVANCED_TARGET == XA_ENABLED) && (AVRCP_VERSION_1_3_ONLY == XA_DISABLED))*/ +#define AVRCP_BROWSE_AUTO_ACCEPT XA_DISABLED +#define AVRCP_MAX_FOLDER_DEPTH 10 +#define AVRCP_NUM_PLAYER_SETTINGS 4 +#define AVRCP_MAX_PALYER_STRINGS 5 + +/* AVCTP */ + + +/********************************************************************************** + * + * BIP + * + **********************************************************************************/ +/* Value */ +#define BIP_SUPPORTED_CAPABILITIES 0x01 +#define BIP_SUPPORTED_FEATURES 0x0091 +#define BIP_SUPPORTED_FUNCTIONS 0x41EB +#define BIP_IMAGING_DATA_CAPACITY 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00 + +/* Constants */ +#define BIP_NUM_INITIATORS 1 +#define BIP_NUM_RESPONDERS 1 +#define BIP_MAX_PASSWORD_LEN 18 +#define BIP_MAX_USERID_LEN 20 +#define BIP_MAX_REALM_LEN 20 + +/********************************************************************************** + * + * BNEP + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +#define NUM_BNEP_PANUS 1 +#define BNEP_ETHERNET_EMULATION XA_DISABLED +#define BNEP_NUM_TIMERS 3 +#define BNEP_CONTROL_TIMEOUT 10 + +/********************************************************************************** + * + * BPP + * + **********************************************************************************/ +/* Value */ +#define BPP_1284ID \ + 'M','F','G',':','E','X','T','E','N','D','E','D','-','S', \ + 'Y','S','T','E','M','S',';','M','D','L',':','X','A','B', \ + 'T','P','r','i','n','t','e','r',';','D','E','S',':','X', \ + 'T','N','D','A','c','c','e','s','s',' ','B','l','u','e', \ + 't','o','o','t','h',' ','P','r','i','n','t','e','r',';', \ + 'S','N',':','1','2','3','4','5','\0' +#define BPP_1284ID_LEN 79 +#define BPP_DOC_FORMATS \ + 'a','p','p','l','i','c','a','t','i','o','n','/', \ + 'v','n','d','.','p','w','g','-','x','h','t','m','l','-', \ + 'p','r','i','n','t','+','x','m','l',':','1','.','0',',', \ + 't','e','x','t','/','p','l','a','i','n','\0' +#define BPP_DOC_FORMATS_LEN 51 +#define BPP_CHAR_REPERTOIRES \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff +#define BPP_IMG_FORMATS \ + 'i','m','a','g','e','/','j','p','e','g',',', \ + 'i','m','a','g','e','/','g','i','f',':','8','9','A','\0' +#define BPP_IMG_FORMATS_LEN 25 +#define BPP_COLOR_SUPPORTED TRUE +#define BPP_DUPLEX_SUPPORTED TRUE +#define BPP_MEDIA_TYPES \ + 's','t','a','t','i','o','e','r','y',',', \ + 'c','a','r','d','s','t','o','c','k',',', \ + 'e','n','v','e','l','o','p','e','\0' +#define BPP_MEDIA_TYPES_LEN 29 +#define BPP_MAX_MEDIA_WIDTH 210 +#define BPP_MAX_MEDIA_LENGTH 297 + + +/* Constants */ +#define BPP_NUM_SENDERS 1 +#define BPP_NUM_PRINTERS 1 +#define BPP_PRINT_STATUS XA_ENABLED +#define BPP_MAX_PASSWORD_LEN 20 +#define BPP_MAX_USERID_LEN 20 +#define BPP_MAX_REALM_LEN 20 + +/********************************************************************************** + * + * HFP + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +//wangjianjun +#if defined(HFP_1_6_ENABLE) +#define HF_VERSION_1_6 XA_ENABLED +#else +#define HF_VERSION_1_6 XA_DISABLED +#endif +//#define HF_VERSION_1_6 XA_ENABLED +#define HF_VREC XA_ENABLED +#define HF_FEATURE_ECHO_NOISE 0x00000001 +#define HF_FEATURE_CALL_WAITING 0x00000002 +#define HF_FEATURE_CLI_PRESENTATION 0x00000004 +#define HF_FEATURE_VOICE_RECOGNITION 0x00000008 +#define HF_FEATURE_VOLUME_CONTROL 0x00000010 + +#if HF_VERSION_1_6 == XA_ENABLED +#define HF_FEATURE_CODEC_NEGOTIATION 0x00000020 //wind band speech +#define HF_FEATURE_ENHANCED_CALL_STATUS 0x00000040 +#define HF_FEATURE_ENHANCED_CALL_CTRL 0x00000080 +#else +#define HF_FEATURE_ENHANCED_CALL_STATUS 0x00000020 +#define HF_FEATURE_ENHANCED_CALL_CTRL 0x00000040 +#endif + +//zjq add for hfp1.7 hf_indicators +#define HF_FEATURE_HF_INDICATORS 0x00000100 +#define HF_FEATURE_ESCO_S4 0x00000200 + +//only 5 bits avirable, no useful!!! +#if HF_VERSION_1_6 == XA_ENABLED +#define HF_SDK_FEATURES (HF_FEATURE_ECHO_NOISE \ + | HF_FEATURE_CALL_WAITING \ + | HF_FEATURE_CLI_PRESENTATION \ + | HF_FEATURE_VOICE_RECOGNITION \ + | HF_FEATURE_VOLUME_CONTROL \ + | HF_FEATURE_CODEC_NEGOTIATION \ + | HF_FEATURE_ENHANCED_CALL_STATUS \ + | HF_FEATURE_ENHANCED_CALL_CTRL \ + | HF_FEATURE_ESCO_S4) +#else + +#define HF_SDK_FEATURES (HF_FEATURE_ECHO_NOISE \ + | HF_FEATURE_CALL_WAITING \ + | HF_FEATURE_CLI_PRESENTATION \ + | HF_FEATURE_VOICE_RECOGNITION \ + | HF_FEATURE_VOLUME_CONTROL \ + | HF_FEATURE_ENHANCED_CALL_STATUS \ + | HF_FEATURE_ENHANCED_CALL_CTRL) +#endif + +#define HF_COMMAND_TIMEOUT 10000 +#define HF_USE_CALL_MANAGER XA_DISABLED //XA_ENABLED +#define HF_POLL_TIMEOUT 120000 +#define HF_POLL_TIMEOUT_ACTIVE 4000 +#define HF_RING_TIMEOUT 10000 +#define HF_TX_BUFFER_SIZE 128 //1024 +#define HF_RECV_BUFFER_SIZE HCI_ACL_DATA_SIZE //1024 +#define HF_USE_PHONEBOOK_COMMANDS XA_DISABLED +#define HF_USE_MESSAGING_COMMANDS XA_DISABLED +#define HF_USE_IIA XA_DISABLED +//#define HF_USE_RESP_HOLD XA_ENABLED +#define HF_USE_RESP_HOLD XA_DISABLED +#define HF_SNIFF_MIN_INTERVAL 0x0040 +#define HF_SNIFF_MAX_INTERVAL 0x0800 +#define HF_SNIFF_ATTEMPT 0x0160 +#define HF_SNIFF_TIMEOUT 0x0160 +#define HF_MEMORY_EXTERNAL XA_DISABLED +//#define HF_SECURITY_SETTINGS (BSL_AUTHORIZATION_IN | BSL_SECURITY_L2_IN | BSL_SECURITY_L2_OUT ) +#define HF_SECURITY_SETTINGS (BSL_SECURITY_L2_IN | BSL_SECURITY_L2_OUT ) +#define HF_CBSZ (256) +#define HF_MAX_BIA_STRING (40) +#define HF_DELAY_CHUP_OK_POLL XA_DISABLED +#define HF_DELAY_IND_SETUP_POLL XA_DISABLED + + +/********************************************************************************** + * + * HFP_AG + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +//wangjianjun for hfp AG +#define HFG_FEATURE_THREE_WAY_CALLS 0x00000001 +#define HFG_FEATURE_ECHO_NOISE 0x00000002 +#define HFG_FEATURE_VOICE_RECOGNITION 0x00000004 +#define HFG_FEATURE_RING_TONE 0x00000008 +#define HFG_FEATURE_VOICE_TAG 0x00000010 +#define HFG_FEATURE_REJECT 0x00000020 +#define HFG_FEATURE_ENHANCED_CALL_STATUS 0x00000040 +#define HFG_FEATURE_ENHANCED_CALL_CTRL 0x00000080 +#define HFG_FEATURE_EXTENDED_ERRORS 0x00000100 +#if HF_VERSION_1_6 == XA_ENABLED +#define HFG_FEATURE_CODEC_NEGOTATION 0x00000200 +#endif + +#define HFG_TX_BUFFER_SIZE 1024 +#define HFG_RECV_BUFFER_SIZE 1024 +#define HFG_USE_RESP_HOLD XA_DISABLED //XA_ENABLED +#define HFG_USE_IIA XA_ENABLED +#define HFG_SNIFF_TIMER 2000 +#define HFG_SNIFF_MIN_INTERVAL 800 +#define HFG_SNIFF_MAX_INTERVAL 8000 +#define HFG_SNIFF_ATTEMPT 1600 +#define HFG_SNIFF_TIMEOUT 1600 +#define HFG_MEMORY_EXTERNAL XA_DISABLED +#define HFG_SECURITY_SETTINGS (BSL_AUTHORIZATION_IN | BSL_SECURITY_L2_IN | BSL_SECURITY_L2_OUT ) +#define HFG_II_DESC_MAX 128 + + +/********************************************************************************** + * + * HCRP + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +#define HCRP_1284ID \ + 'M','F','G',':','i','A','n','y','w','h','e','r','e',';','M','D', \ + 'L',':','i','A','B','T','P','r','i','n','t','e','r',';','D','E', \ + 'S',':','i','A','n','y','w','h','e','r','e',' ','B','l','u','e', \ + 't','o','o','t','h',' ','P','r','i','n','t','e','r',';','S','N', \ + ':','1','2','3','4','5',';' +#define HCRP_1284ID_LEN 71 +#define HCRP_DEVICE_NAME 'i','A','B','t','P','r','i','n','t','e','r' +#define HCRP_DEVICE_NAME_LEN 11 +#define HCRP_FRIENDLY_NAME \ + 'i','A','n','y','w','h','e','r','e',' ','B','l','u','e','t','o', \ + 'o','t','h',' ','P','r','i','n','t','e','r' +#define HCRP_FRIENDLY_NAME_LEN 27 +#define HCRP_SERVER XA_DISABLED +#define HCRP_CLIENT XA_DISABLED +#define HCRP_CLIENT_CTL_MTU (L2CAP_MTU - 8) + +/********************************************************************************** + * + * HSP + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +#define HS_MAX_LEVEL 15 +#define HS_DEFAULT_LEVEL 7 +#define HS_SECURITY XA_ENABLED +#define HS_SECURITY_SETTINGS (BSL_AUTHORIZATION_IN | BSL_SECURITY_L2_IN | BSL_SECURITY_L2_OUT) +#define HS_MEMORY_EXTERNAL XA_DISABLED +#define HS_REMOTE_AUDIO_VOLUME_CONTROL TRUE + +#define HS_SNIFF_ATTEMPT 0x0160 +#define HS_SNIFF_TIMEOUT 0x0160 +#define HS_SNIFF_MAX_INTERVAL 0x0800 +#define HS_SNIFF_MIN_INTERVAL 0x0040 + +#define HS_RECV_BUFFER_SIZE HCI_ACL_DATA_SIZE +#define HS_TX_BUFFER_SIZE 128 + + +/********************************************************************************** + * + * HSP_AG + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +#define AG_SECURITY XA_ENABLED +#define AG_SECURITY_SETTINGS (BSL_AUTHORIZATION_IN | BSL_SECURITY_L2_IN | BSL_SECURITY_L2_OUT) +#define AG_SCO_SETTINGS XA_ENABLED +#define AG_RINGTIMER 5000 +#define AG_MAX_RING_COUNT 5 +#define AG_MAX_LEVEL 15 +#define AG_DEFAULT_LEVEL 7 +#define AG_DISCONNECT_REQUEST_NOTIFY XA_ENABLED +#define AG_MEMORY_EXTERNAL XA_DISABLED + + +/********************************************************************************** + * + * HID + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +#define HID_HOST XA_DISABLED +#ifndef HID_DEVICE +#define HID_DEVICE XA_DISABLED +#endif +#define HID_NUM_TX_PACKETS 5 +#define HID_NUM_SDP_ATTRIBUTES 24 +#define DEVICE_ID_NUM_SDP_ATTRIBUTES 7 +#define HID_DEVICE_RELEASE 0x0100 +#define HID_PARSER_VERSION 0x0111 +#define HID_DEVICE_SUBCLASS ((U8)(COD_MINOR_PERIPH_KEYBOARD)) +#define HID_COUNTRY_CODE 0x21 +#define HID_VIRTUAL_CABLE TRUE +#define HID_RECONNECT_INITIATE TRUE +#define HID_DESCRIPTOR_TYPE 0x22 +#define HID_DESCRIPTIOR_LEN 50 +#define HID_DESCRIPTOR \ + 0x05, 0x01, /* USAGE_PAGE(Generic Desktop) */ \ + 0x09, 0x02, /* USAGE(Mouse) */ \ + 0xA1, 0x01, /* COLLECTION(Application) */ \ + 0x09, 0x01, /* USAGE(Pointer) */ \ + 0xA1, 0x00, /* COLLECTION(Physical) */ \ + 0x05, 0x01, /* USAGE_PAGE(Generic Desktop) */ \ + 0x09, 0x30, /* USAGE(X) */ \ + 0x09, 0x31, /* USAGE(Y) */ \ + 0x15, 0x81, /* LOGICAL_MINIMUM(-127) */ \ + 0x25, 0x7F, /* LOGICAL_MAXIMUM(127) */ \ + 0x75, 0x08, /* REPORT_SIZE(8) */ \ + 0x95, 0x02, /* REPORT_COUNT(2) */ \ + 0x81, 0x06, /* INPUT(Data,Var,Rel) */ \ + 0xC0, /* END_COLLECTION */ \ + 0x05, 0x09, /* USAGE_PAGE(Button) */ \ + 0x19, 0x01, /* USAGE_MINIMUM(Button 1) */ \ + 0x29, 0x03, /* USAGE_MAXIMUM(Button 3) */ \ + 0x15, 0x00, /* LOGICAL_MINUMUM(0) */ \ + 0x25, 0x03, /* LOGICAL_MAXIMUM(1) */ \ + 0x95, 0x03, /* REPORT_COUNT(3) */ \ + 0x75, 0x01, /* REPORT_SIZE(1) */ \ + 0x81, 0x02, /* INPUT(Data,Var,Abs) */ \ + 0x95, 0x01, /* REPORT_COUNT(1) */ \ + 0x75, 0x05, /* REPORT_SIZE(5) */ \ + 0x81, 0x03, /* INPUT(Cnst,Var,Abs) */ \ + 0xC0 /* END_COLLECTION */ +#define HID_MAX_DESCRIPTOR_LEN 128 +#define HID_BATTERY_POWER FALSE +#define HID_REMOTE_WAKE TRUE +#define HID_SUPERVISION_TIMEOUT 0x7D00 +#define HID_NORMALLY_CONNECTABLE TRUE +#define HID_BOOT_DEVICE TRUE +#define HID_DEVID_SPEC_ID 0x0103 +#define HID_DEVID_VENDOR_ID 0x23A1 +#define HID_DEVID_VENDOR_ID_SRC 0x0001 +#define HID_DEVID_PRODUCT_ID 0x1234 +/********************************************************************************** + * + * DIP + * + **********************************************************************************/ +/* Value */ +#ifndef DIP_DEVICE +#define DIP_DEVICE XA_ENABLED +#endif + + +/********************************************************************************** + * + * MAP + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +#define MAP_NUM_CLIENTS 1 +#define MAP_NUM_SERVERS 1 +#define MAP_NOTIFICATION XA_ENABLED +#define MAP_BROWSING XA_ENABLED +#define MAP_DELETE XA_ENABLED +#define MAP_UPLOADING XA_ENABLED +#define MAP_MAX_APP_PARMS_LEN 255 +#define MAP_EMAIL_SUPPORTED XA_ENABLED +#define MAP_SMS_GSM_SUPPORTED XA_ENABLED +#define MAP_SMS_CDMA_SUPPORTED XA_DISABLED +#define MAP_MMS_SUPPORTED XA_ENABLED +#define MAP_NOTIFICATION_SUPPORTED XA_ENABLED +#define PUSH_MESSAGE_TYPE "x-bt/message" +#define PULL_MESSAGE_TYPE "x-bt/message" +#define SET_MESSAGE_STATUS_TYPE "x-bt/messageStatus" +#define GET_MESSAGE_LISTING_TYPE "x-bt/MAP-msg-listing" +#define GET_FOLDER_LISTING_TYPE "x-obex/folder-listing" +#define SET_NOTIFICATION_REGISTER_TYPE "x-bt/MAP-NotificationRegistration" +#define SEND_EVENT_TYPE "x-bt/MAP-event-report" +#define UPDATE_INBOX_TYPE "x-bt/MAP-messageUpdate" +#define MAP_UNKNOWN_OBJECT_LENGTH 0xFFFFFFFF + + +/********************************************************************************** + * + * PAN + * + **********************************************************************************/ +/* Value */ +#define PAN_PANU_NUM_ATTRIBUTES 9 +#define PAN_GN_NUM_ATTRIBUTES 11 +#define PAN_NAP_NUM_ATTRIBUTES 13 +#define PAN_NUM_SEARCH_ATTRIBUTES 21 +#define PAN_PKT_TYPE_LIST \ + SDP_UINT_16BIT(0x0800), /* Uint16 IPv4 */ \ + SDP_UINT_16BIT(0x0806) /* Uint16 ARP */ +#define PAN_SECURITY_LEVEL 0x0000 /* No security */ +#define PAN_PANU_SERVICE_NAME \ + 'P','e','r','s','o','n','a','l',' ','A','d','-','h','o','c',' ', \ + 'U','s','e','r',' ','S','e','r','v','i','c','e', 0x00 +#define PAN_PANU_SERVICE_DESCRIPTION \ + 'P','e','r','s','o','n','a','l',' ','A','d','-','h','o','c',' ', \ + 'U','s','e','r',' ','S','e','r','v','i','c','e', 0x00 +#define PAN_GN_SERVICE_NAME \ + 'G','r','o','u','p','A','d','-','h','o','c',' ', \ + 'N','e','t','w','o','r','k',' ','S','e','r','v','i','c','e', 0x00 +#define PAN_GN_SERVICE_DESCRIPTION \ + 'P','e','r','s','o','n','a','l',' ','G','r','o','u','p',' ', \ + 'A','d','-','h','o','c',' ','N','e','t','w','o','r','k',' ', \ + 'S','e','r','v','i','c','e', 0x00 +#define PAN_GN_IPV4_SUBNET '1','0','.','0','.','0','.','0','/','8' +#define PAN_GN_IPV6_SUBNET 'f','e','8','0',':',':','/','4','8' +#define PAN_NAP_SERVICE_NAME \ + 'N','e','t','w','o','r','k',' ','A','c','c','e','s','s',' ', \ + 'P','o','i','n','t',' ','S','e','r','v','i','c','e', 0x00 +#define PAN_NAP_SERVICE_DESCRIPTION \ + 'P','e','r','s','o','n','a','l',' ','A','d','-','h','o','c',' ', \ + 'N','e','t','w','o','r','k',' ','S','e','r','v','i','c','e', 0x00 +/*--------------------------------------------------------------------------- + * PAN_NAP_NET_ACCESS_TYPE constant + * 0x0000: PSTN, + * 0x0001: ISDN, + * 0x0002: DSL, + * 0x0003: Cable Modem, + * 0x0004: 10Mb Ethernet, + * 0x0005: 100Mb Ethernet, + * 0x0006: 4Mb Token Ring, + * 0x0007: 16Mb Token Ring, + * 0x0008: 100Mb Token Ring, + * 0x0009: FDDI, + * 0x000A: GSM, + * 0x000B: CDMA, + * 0x000C: GPRS, + * 0x000D: 3G, + * 0xFFFE: other. + */ +#define PAN_NAP_NET_ACCESS_TYPE 0x0005 /* 100Mb Ethernet */ +#define PAN_NAP_MAX_NET_ACCESS_RATE 10000000 /* 10Mb/sec */ +#define PAN_NAP_IPV4_SUBNET '1','0','.','0','.','0','.','0','/','8' +#define PAN_NAP_IPV6_SUBNET 'f','e','8','0',':',':','/','4','8' + +/* Constants */ +#define NUM_BT_PKTS (NUM_BNEP_PANUS * 4) +#define NUM_PAN_ARP_ADDRS 10 +#define PAN_LINK_LOCAL_SUBNET 0xA9FE0000 /*169.254.0.0*/ +#define PAN_ROLE_PANU XA_ENABLED +#define PAN_ROLE_GN XA_DISABLED +#define PAN_ROLE_NAP XA_DISABLED + + +/********************************************************************************** + * + * PBAP + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +#define PBAP_NUM_CLIENTS 1 +#define PBAP_NUM_SERVERS 1 +#define PBAP_MAX_PASSWORD_LEN 20 +#define PBAP_MAX_USERID_LEN 20 +#define PBAP_MAX_REALM_LEN 20 +#define PBAP_MAX_APP_PARMS_LEN 30 +#define PBAP_LOCAL_PHONEBOOK_SUPPORTED XA_ENABLED +#define PBAP_SIM_PHONEBOOK_SUPPORTED XA_ENABLED +#define PULL_PHONEBOOK_TYPE "x-bt/phonebook" +#define VCARD_LISTING_OBJECT_TYPE "x-bt/vcard-listing" +#define VCARD_OBJECT_TYPE "x-bt/vcard" +#define PBAP_UNKNOWN_OBJECT_LENGTH 0xFFFFFFFF +#define PBAP_FILTER_SIZE 8 + + +/********************************************************************************** + * + * SIM + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +#define SIM_SERVER XA_DISABLED +#define SIM_CLIENT XA_DISABLED +#define SIM_MAX_MSG_SIZE RF_MAX_FRAME_SIZE +#define SIM_MAX_APDU 276 +#define SIM_CLIENT_SECURITY_SETTINGS (BSL_AUTHORIZATION_IN | BSL_SECURITY_L2_IN | BSL_SECURITY_L2_OUT) +#define SIM_MAX_MSG_PARMS 3 + + +/********************************************************************************** + * + * TCS Binary + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +#define TCS_CORDLESS XA_DISABLED +#define TCS_WUG_MASTER XA_DISABLED +#define NUM_TCS_CONNS 1 +#define TCS_TIMEOUT_CONNECT_VAL (3 * 60 * 1000) +#define TCS_TIMEOUT_OUTPROCEED_VAL (30 * 1000) +#define TCS_COI_MAX 6 +#define TCS_MDATA_MAX (74 + TCS_COI_MAX) + + +/********************************************************************************** + * + * TCS Message + * + **********************************************************************************/ +/* Value */ + +/* Constants */ + + + +/********************************************************************************** + * + * Intercom + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +#define ICM_SECURITY XA_DISABLED +#define ICM_SCO_SETTINGS XA_DISABLED + + +/********************************************************************************** + * + * Cordless Profile + * + **********************************************************************************/ +/* Value */ + +/* Constants */ + + + + + +/********************************************************************************** + * + * OBEX + * + **********************************************************************************/ +/* Value */ + +/* Constants */ +//not documented +#define OBEX_RFCOMM_TRANSPORT XA_ENABLED +#define OBEX_ROLE_CLIENT XA_ENABLED +#define OBEX_DEINIT_FUNCS XA_ENABLED +#define OBEX_ROLE_SERVER XA_ENABLED +#define OBEX_TRANSPORT_FLOW_CTRL XA_ENABLED +#define OBEX_ALLOW_SERVER_TP_CONNECT XA_ENABLED +#define OBEX_PROVIDE_SDP_RESULTS XA_ENABLED +#define OBEX_SERVER_CONS_SIZE 2 +#define OBEX_DYNAMIC_OBJECT_SUPPORT XA_ENABLED +#define OBEX_PACKET_FLOW_CONTROL XA_ENABLED +#define OBEX_BODYLESS_GET XA_ENABLED +#define FTP_EXPANDED_API XA_ENABLED +#define OPUSH_EXPANDED_API XA_ENABLED + + +/********************************************************************************** + * + * Other defition without documentation + * + **********************************************************************************/ + +#define PME_APP_NAME "A2DP Sample Application" + +/* ============================================================ + * GOEP + */ +#define GOEP_SERVER_HB_SIZE 12 +#define GOEP_MAX_TYPE_LEN 100 + + + +/* =============================== + * Temp add by Jimmy + */ +#define OEM_STACK XA_DISABLED +#define AT_HANDSFREE XA_ENABLED +#define AT_DUN XA_DISABLED +#define AT_PHONEBOOK XA_DISABLED +#define AT_SMS XA_DISABLED +#define AT_ROLE_TERMINAL XA_ENABLED +#define AT_ROLE_MOBILE XA_DISABLED + +#define HF_CUSTOM_FEATURE_NULL (0x00) +//#define HF_CUSTOM_FEATURE_RESERVED (0x01 << 0) +#define HF_CUSTOM_FEATURE_BATTERY_REPORT (0x03 << 0) +#define HF_CUSTOM_FEATURE_DOCK (0x01 << 2) +#define HF_CUSTOM_FEATURE_SIRI_REPORT (0x01 << 3) +#define HF_CUSTOM_FEATURE_NR_REPORT (0x01 << 4) + +//#define HF_CUSTOM_FEATURE_SUPPORT (HF_CUSTOM_FEATURE_BATTERY_REPORT | HF_CUSTOM_FEATURE_SIRI_REPORT) +#ifndef HF_CUSTOM_FEATURE_SUPPORT +#ifdef SUPPORT_SIRI +#define HF_CUSTOM_FEATURE_SUPPORT (HF_CUSTOM_FEATURE_BATTERY_REPORT | HF_CUSTOM_FEATURE_SIRI_REPORT) +#else +#define HF_CUSTOM_FEATURE_SUPPORT (HF_CUSTOM_FEATURE_BATTERY_REPORT) +#endif /*SUPPORT_SIRI*/ +#endif /*HFt _CUSTOM_FEATURE_SUPPORT*/ + +#if HF_CUSTOM_FEATURE_SUPPORT +#define HF_CUSTOM_VENDOR_ID 0x0000 +#define HF_CUSTOM_PRODUCT_ID 0x0000 +#define HF_CUSTOM_VERSION_ID 0x0100 +#endif + +#define __BT_RECONNECT__ +#define __BT_HFP_RECONNECT__ +#define __BT_SNIFF__ +//#define __BT_ONE_BRING_TWO__ +//#define __BT_REAL_ONE_BRING_TWO__ +#define __EARPHONE__ +#define __AUTOPOWEROFF__ +#endif /* __OVERIDE_H */ + diff --git a/services/bt_profiles_enhanced/inc/packer.h b/services/bt_profiles_enhanced/inc/packer.h new file mode 100644 index 0000000..0558ee1 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/packer.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __PACKER_H__ +#define __PACKER_H__ + +#define WRITE_INT8(offset, p, data) \ + ( *(INT8U *)(((INT8U *)p) + offset) = (INT8U)data ) + +#define WRITE_INT16(offset, p, data) \ + WRITE_INT8(offset, p, (((INT16U)data) & 0xFF)); \ + WRITE_INT8((offset+1), p, ((((INT16U)data) >> 8) & 0xFF)) + +/* convert parameters into single data*/ +#define READ_INT8(offset, p) \ + ( *(INT8U *)(((INT8U *)p) + offset) ) + +#define READ_INT16(offset, p) \ + (INT16U )(READ_INT8(offset, p) + \ + (READ_INT8(offset+1, p) << 8)) + +#endif /* __PACKER_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/pbap.h b/services/bt_profiles_enhanced/inc/pbap.h new file mode 100644 index 0000000..b402bb7 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/pbap.h @@ -0,0 +1,20 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __PBAP_H__ +#define __PBAP_H__ + +#endif /* __PBAP_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/pbap_i.h b/services/bt_profiles_enhanced/inc/pbap_i.h new file mode 100644 index 0000000..418a140 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/pbap_i.h @@ -0,0 +1,203 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __PBAP_I_H__ +#define __PBAP_I_H__ + +#include "obex_i.h" + +#define PULL_PHONEBOOK_TYPE "x-bt/phonebook" +#define PULL_LISTING_TYPE "x-bt/vcard-listing" +#define PULL_VCARD_ENTRY_TYPE "x-bt/vcard" + +typedef uint8 vcard_sort_type; +#define VCARD_SORT_ORDER_INDEXED 0x00 /* Indexed sorting */ +#define VCARD_SORT_ORDER_ALPHA 0x01 /* Alphabetical sorting */ +#define VCARD_SORT_ORDER_PHONETICAL 0x02 /* Phonetical sorting */ + +typedef uint8 vcard_search_attribute; +#define VCARD_SEARCH_ATTRIB_NAME 0x00 /* Search by Name */ +#define VCARD_SEARCH_ATTRIB_NUMBER 0x01 /* Search by Number */ +#define VCARD_SEARCH_ATTRIB_SOUND 0x02 /* Search by Sound */ + +struct vcard_filter{ + uint32 low; + uint32 high; +}; + +#define VCARD_FILTER_VERSION 0 /* Version (Bit 0) */ +#define VCARD_FILTER_FN 1 /* Formatted Name (Bit 1) */ +#define VCARD_FILTER_N 2 /* Structured Presentation of Name (Bit 2) */ +#define VCARD_FILTER_PHOTO 3 /* Associated Image or Photo (Bit 3) */ +#define VCARD_FILTER_BDAY 4 /* Birthday (Bit 4) */ +#define VCARD_FILTER_ADR 5 /* Delivery Address (Bit 5) */ +#define VCARD_FILTER_LABEL 6 /* Delivery (Bit 6) */ +#define VCARD_FILTER_TEL 7 /* Telephone (Bit 7) */ +#define VCARD_FILTER_EMAIL 8 /* Electronic Mail Address (Bit 8) */ +#define VCARD_FILTER_MAILER 9 /* Electronic Mail (Bit 9) */ +#define VCARD_FILTER_TZ 10 /* Time Zone (Bit 10) */ +#define VCARD_FILTER_GEO 11 /* Geographic Position (Bit 11) */ +#define VCARD_FILTER_TITLE 12 /* Job (Bit 12) */ +#define VCARD_FILTER_ROLE 13 /* Role within the Organization (Bit 13) */ +#define VCARD_FILTER_LOGO 14 /* Organization Logo (Bit 14) */ +#define VCARD_FILTER_AGENT 15 /* vCard of Person Representing (Bit 15) */ +#define VCARD_FILTER_ORG 16 /* Name of Organization (Bit 16) */ +#define VCARD_FILTER_NOTE 17 /* Comments (Bit 17) */ +#define VCARD_FILTER_REV 18 /* Revision (Bit 18) */ +#define VCARD_FILTER_SOUND 19 /* Pronunciation of Name (Bit 19) */ +#define VCARD_FILTER_URL 20 /* Uniform Resource Locator (Bit 20) */ +#define VCARD_FILTER_UID 21 /* Unique ID (Bit 21) */ +#define VCARD_FILTER_KEY 22 /* Public Encryption Key (Bit 22) */ +#define VCARD_FILTER_NICKNAME 23 /* Nickname (Bit 23) */ +#define VCARD_FILTER_CATEGORIES 24 /* Categories (Bit 24) */ +#define VCARD_FILTER_PRODID 25 /* Product Id (Bit 25) */ +#define VCARD_FILTER_CLASS 26 /* Class Information (Bit 26) */ +#define VCARD_FILTER_SORT_STRING 27 /* Sort string (Bit 27) */ +#define VCARD_FILTER_TIMESTAMP 28 /* Time stamp (Bit 28) */ +/* Bits 29-38 Reserved for future use */ +#define VCARD_FILTER_PROPRIETARY 39 /* Use of a proprietary filter (Bit 39) */ +/* Bits 40-63 Reserved for proprietary filter usage */ + +typedef uint8 vcard_format; +#define VCARD_FORMAT_21 0x00 /* Version 2.1 format */ +#define VCARD_FORMAT_30 0x01 /* Version 3.0 format */ + +typedef uint8 app_parameter_tag; +#define PBAP_TAG_ORDER 0x01 /* 1-byte, 0x00 (indexed), 0x01 (alpha), or 0x02 (phonetic) */ +#define PBAP_TAG_SEARCH_VALUE 0x02 /* Variable length text string */ +#define PBAP_TAG_SEARCH_ATTRIB 0x03 /* 1-byte, 0x00 (Name), 0x01 (Number), or 0x02 (Sound) */ +#define PBAP_TAG_MAX_LIST_COUNT 0x04 /* 2-bytes, 0x0000 to 0xFFFF */ +#define PBAP_TAG_LIST_OFFSET 0x05 /* 2-bytes, 0x0000 to 0xFFFF */ +#define PBAP_TAG_FILTER 0x06 /* 8-bytes, 64 bit mask */ +#define PBAP_TAG_FORMAT 0x07 /* 1-byte, 0x00 = 2.1, 0x01 = 3.0 */ +#define PBAP_TAG_PHONEBOOK_SIZE 0x08 /* 2-bytes, 0x0000 to 0xFFFF */ +#define PBAP_TAG_MISSED_CALLS 0x09 /* 1-byte, 0x00 to 0xFF */ + +enum pbap_state{ + PBAP_TP_CONNECTING, + PBAP_TP_DISCONNECTING, + PBAP_IDLE, //transport connection idle, connection idle + PBAP_DISCONNECTING, //transport connection established, connection discarding + PBAP_TP_CONNECTED, //transport connection established, connection idle + PBAP_CONNECTING, //transport connection established, connection establishing + PBAP_CONNECTED, //transport connection established, connection established + PBAP_GET, + PBAP_ABORT, + PBAP_SET_PATH +}; + +enum pbap_event{ + PBAP_EVENT_IDLE, + PBAP_EVENT_TP_CONNECTED, + PBAP_EVENT_CONNECTED, + PBAP_EVENT_CONTINUE, + PBAP_EVENT_COMPLETE, +#if OBEX_AUTHENTICATION == 1 + PBAP_EVENT_AUTH, +#endif + PBAP_EVENT_NO_CONNECTION, + PBAP_EVENT_FAILED, + PBAP_EVENT_TIMEOUT +}; + +typedef uint8 pbap_opcode; +#define PBAP_OP_NULL 0x00 +#define PBAP_OP_CONNECT 0x01 +#define PBAP_PULL_PHONEBOOK 0x02 +#define PBAP_PULL_VCARDLIST 0x03 +#define PBAP_PULL_VCARDENTRY 0x04 +#define PBAP_OP_SET_PATH 0x05 +#define PBAP_OP_ABORT 0x06 +#define PBAP_OP_DISCONNECT 0x07 + +struct pbap_pull_phonebook_parms{ + char name[30]; + struct vcard_filter filter; + uint8 format; + uint16 maxListCount; + uint16 listStartOffset; +}; + +struct pbap_pull_list_parms{ + char folder[10]; + uint8 order; + char searchValue[20]; + uint8 searchAttribute; + uint16 maxListCount; + uint16 listStartOffset; +}; + +struct pbap_pull_entry_parms{ + char name[10]; + struct vcard_filter filter; +}; + +struct pbap_set_path_parms{ + char path[10]; +}; + +struct pbap_client{ + pbap_opcode opcode; + void (*pbap_client_callback)(enum pbap_event event); + + /*struct pbap_pull_phonebook_parms *pb_parms; + struct pbap_pull_list_parms *list_parms; + struct pbap_pull_entry_parms *entry_parms; + struct pbap_set_path_parms *setPath_parms;*/ + void *parms; + + uint8 *recData; + uint16 recLen; +}; + +#if OBEX_AUTHENTICATION == 1 +#include "md5.h" +#endif + +struct pbap_control_t{ + enum pbap_state state; + + uint8 connectID[4]; +#if OBEX_AUTHENTICATION == 1 + uint8 challenge[AUTH_NONCE_LEN]; + uint8 response[AUTH_NONCE_LEN]; + uint8 challenge_length; +#endif + struct pbap_client *pbap_client_app; +}; + +#define PBAP_SEM_TIMEOUT 100 + +int8 pbap_connectReq(void); +int8 pbap_disconnectReq(void); +//void pbap_pull_phonebook(struct pbap_pull_phonebook_parms *parms); +//void pbap_set_path(char *pathName); +//void pbap_pull_vCardListing(struct pbap_pull_list_parms *parms); +//void pbap_pull_vCardEntry(struct pbap_pull_entry_parms *parms); +int8 pbap_pull_phonebook(void); +int8 pbap_set_path(void); +int8 pbap_pull_vCardListing(void); +int8 pbap_pull_vCardEntry(void); +int8 pbap_abort(void); + +void pbap_client_init(struct pbap_client *client); +void pbap_client_exit(void); +void vcard_filter_set_bit(struct vcard_filter *filter, uint8 bit); +void vcard_filter_clear_bit(struct vcard_filter *filter, uint8 bit); +enum pbap_state pbap_getState(void); +int8 pbap_get_continue(void); + +#endif /* __PBAP_I_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/platform_deps.h b/services/bt_profiles_enhanced/inc/platform_deps.h new file mode 100644 index 0000000..ca40fe2 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/platform_deps.h @@ -0,0 +1,67 @@ + +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __PLATFORM_DEPS_H__ +#define __PLATFORM_DEPS_H__ + +#if defined(_WIN32) +#include "win32_os.h" +#else +#include "bes_os.h" +#endif + +// ------ HCI ------ // +#if defined(__cplusplus) +extern "C" { +#endif +void Plt_HciInit(void); +void Plt_HciSendData(unsigned char type, unsigned short cmd_conn, unsigned short len, unsigned char *buffer); +void Plt_HciSendBuffer(unsigned char type, unsigned char *buff, int len); +void Plt_NotifyScheduler(void); +void Plt_LockHCIBuffer(void); +void Plt_UNLockHCIBuffer(void); + +// ------ OS ------ // +//typedef enum { +// OS_STK_EVT_STACK_READY = 0, +// OS_STK_EVT_NOTIFY_EVM, // 1 +// OS_STK_EVT_EXIT_MAINLOOP, // 2 +//}OS_STACK_EVENT_T; + +char OS_Init(void); +void OS_LockStack(void); +void OS_UnlockStack(void); +unsigned char OS_LockIsExist(void); +void OS_StopHardware(void); +void OS_ResumeHardware(void); +//OS_STACK_EVENT_T OS_WaitEvent(unsigned int timeout_ms); +//char OS_SendEvent(OS_STACK_EVENT_T event); +void OS_NotifyEvm(void); +bool OS_WaitEvm(unsigned int timeout_ms); + +// ------ TIMER ------ // +void Plt_TimerWrapperInit(void); +void Plt_TimerWrapperStart(unsigned int ms); +void Plt_TimerWrapperStop(void); +void Plt_UNLockTimerWrapper(void); +void Plt_LockTimerWrapper(void); +unsigned int Plt_GetTicks(void); +unsigned int Plt_GetTicksMax(void); + +#if defined(__cplusplus) +} +#endif +#endif /* __PLATFORM_DEPS_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/rfcomm.h b/services/bt_profiles_enhanced/inc/rfcomm.h new file mode 100644 index 0000000..ffb4b53 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/rfcomm.h @@ -0,0 +1,236 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __RFCOMM_H__ +#define __RFCOMM_H__ + +#include "rfcomm_i.h" +#include "bt_co_list.h" + +#define RFCOMM_CONN_TIMEOUT //(HZ * 30) +#define RFCOMM_DISC_TIMEOUT //(HZ * 20) +#define RFCOMM_AUTH_TIMEOUT //(HZ * 25) + +#define RFCOMM_DEFAULT_MTU 672 +#define RFCOMM_DEFAULT_CREDITS 7 + +#define RFCOMM_MAX_CREDITS 40 + +#define RFCOMM_PPB_HEAD_RESERVE 8 +#define RFCOMM_PPB_TAIL_RESERVE 2 +#define RFCOMM_PPB_RESERVE (RFCOMM_PPB_HEAD_RESERVE + RFCOMM_PPB_TAIL_RESERVE) + +#define RFCOMM_SABM 0x2f +#define RFCOMM_DISC 0x43 +#define RFCOMM_UA 0x63 +#define RFCOMM_DM 0x0f +#define RFCOMM_UIH 0xef + +#define RFCOMM_TEST 0x08 +#define RFCOMM_FCON 0x28 +#define RFCOMM_FCOFF 0x18 +#define RFCOMM_MSC 0x38 +#define RFCOMM_RPN 0x24 +#define RFCOMM_RLS 0x14 +#define RFCOMM_PN 0x20 +#define RFCOMM_NSC 0x04 + +#define RFCOMM_V24_FC 0x02 +#define RFCOMM_V24_RTC 0x04 +#define RFCOMM_V24_RTR 0x08 +#define RFCOMM_V24_IC 0x40 +#define RFCOMM_V24_DV 0x80 + +#define RFCOMM_RPN_BR_2400 0x0 +#define RFCOMM_RPN_BR_4800 0x1 +#define RFCOMM_RPN_BR_7200 0x2 +#define RFCOMM_RPN_BR_9600 0x3 +#define RFCOMM_RPN_BR_19200 0x4 +#define RFCOMM_RPN_BR_38400 0x5 +#define RFCOMM_RPN_BR_57600 0x6 +#define RFCOMM_RPN_BR_115200 0x7 +#define RFCOMM_RPN_BR_230400 0x8 + +#define RFCOMM_RPN_DATA_5 0x0 +#define RFCOMM_RPN_DATA_6 0x1 +#define RFCOMM_RPN_DATA_7 0x2 +#define RFCOMM_RPN_DATA_8 0x3 + +#define RFCOMM_RPN_STOP_1 0 +#define RFCOMM_RPN_STOP_15 1 + +#define RFCOMM_RPN_PARITY_NONE 0x0 +#define RFCOMM_RPN_PARITY_ODD 0x1 +#define RFCOMM_RPN_PARITY_EVEN 0x3 +#define RFCOMM_RPN_PARITY_MARK 0x5 +#define RFCOMM_RPN_PARITY_SPACE 0x7 + +#define RFCOMM_RPN_FLOW_NONE 0x00 + +#define RFCOMM_RPN_XON_CHAR 0x11 +#define RFCOMM_RPN_XOFF_CHAR 0x13 + +#define RFCOMM_RPN_PM_BITRATE 0x0001 +#define RFCOMM_RPN_PM_DATA 0x0002 +#define RFCOMM_RPN_PM_STOP 0x0004 +#define RFCOMM_RPN_PM_PARITY 0x0008 +#define RFCOMM_RPN_PM_PARITY_TYPE 0x0010 +#define RFCOMM_RPN_PM_XON 0x0020 +#define RFCOMM_RPN_PM_XOFF 0x0040 +#define RFCOMM_RPN_PM_FLOW 0x3F00 + +#define RFCOMM_RPN_PM_ALL 0x3F7F + +#define RFCOMM_HANDLE_UNUSED 0xffffffff +#define RFCOMM_HANDLE_MAX_VALUE 0xffffff00 + + +struct rfcomm_hdr { + uint8 addr; + uint8 ctrl; + uint8 len; // Actual size can be 2 bytes +}__attribute__ ((packed)); + +struct rfcomm_cmd { + uint8 addr; + uint8 ctrl; + uint8 len; + uint8 fcs; +}__attribute__ ((packed)); + +struct rfcomm_mcc { + uint8 type; + uint8 len; +}__attribute__ ((packed)); + +struct rfcomm_pn { + uint8 dlci; + uint8 flow_ctrl; + uint8 priority; + uint8 ack_timer; + uint16 mtu; + uint8 max_retrans; + uint8 credits; +}__attribute__ ((packed)); + +struct rfcomm_rpn { + uint8 dlci; + uint8 bit_rate; + uint8 line_settings; + uint8 flow_ctrl; + uint8 xon_char; + uint8 xoff_char; + uint16 param_mask; +}__attribute__ ((packed)); + +struct rfcomm_rls { + uint8 dlci; + uint8 status; +}__attribute__ ((packed)); + +struct rfcomm_msc { + uint8 dlci; + uint8 v24_sig; +}__attribute__ ((packed)); + +enum rfcomm_session_state_enum { + SESSION_CLOSE, /*l2cap connection closed, wait for openning, and then can send out sabm request*/ + SESSION_CONNECT, /*l2cap channel created*/ + SESSION_WAITING_OPEN, /*has sent sabm of dlci 0, wait ack*/ + SESSION_OPEN, /* rfcomm session created, means dlci 0 created ok */ + SESSION_CLOSING /* all dlc disced, dlci 0 wait to close */ +}; + +struct rfcomm_session { + struct list_node list; + + uint8 initiator; + uint32 l2cap_handle; + + enum rfcomm_session_state_enum state; + + struct bdaddr_t remote; + struct list_node dlcs; +}; + + +enum rfcomm_dlc_state_enum { + DLC_CLOSE, + DLC_CONFIG, /*in dlc parameter config process*/ + DLC_CONNECTING, /* config passed, then send sabm,waiting for ack */ + DLC_OPEN, + DLC_DISCONNECT /*in dlc disconnection process*/ +}; + +struct rfcomm_dlc { + + struct list_node list; + struct rfcomm_session *session; + struct pp_buff_head tx_queue; + + uint32 rfcomm_handle; + uint8 dlci; + uint8 addr; + bool local_trx_ready; + bool peer_trx_ready; + + uint16 mtu; + uint8 priority; + uint8 v24_sig; + uint8 cfc; /* 0: no flow control; other: the credits we give remote;*/ + + uint8 rx_credits; /*the remote device's tx credits now*/ + uint8 tx_credits; /*our tx credits*/ + uint8 credit_give_limit; + osMutexId creditMutex; //!< used to manage the remote device's tx credit + + enum rfcomm_dlc_state_enum state; + + rfcomm_notify_callback_t rfcomm_notify_callback; + rfcomm_datarecv_callback_t rfcomm_datarecv_callback; + + /* + * for used by uplayer to it's own private info, mainly used for + * hfp channel address, hsp channel, spp channel, etc... + */ + void *priv; + struct { + void *priv; + } context; +}; + +struct rfcomm_registered_server_item_t { + struct list_node list; + int8 server_channel; + osMutexId creditMutex; + uint8 initial_credits; + uint8 credit_give_limit; + rfcomm_notify_callback_t rfcomm_notify_callback; + rfcomm_datarecv_callback_t rfcomm_datarecv_callback; + struct rfcomm_dlc *dlc; + /* + * used for server's private info + */ + void *priv; +}; + +/* flow control states */ +#define RFCOMM_CFC_DISABLED 0 +#define RFCOMM_CFC_ENABLED RFCOMM_DEFAULT_CREDITS + +#define RFCOMM_CFG_SESSIONS_MAX 5 /* means how many l2cap channel */ + +#endif /* __RFCOMM_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/rfcomm_i.h b/services/bt_profiles_enhanced/inc/rfcomm_i.h new file mode 100644 index 0000000..6106aa6 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/rfcomm_i.h @@ -0,0 +1,127 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __RFCOMM_I_H__ +#define __RFCOMM_I_H__ + +#include "co_ppbuff.h" +#include "l2cap_i.h" +#include "cmsis_os.h" + +enum rfcomm_event_enum { + RFCOMM_OPENED, + RFCOMM_NEW_OPENED, + RFCOMM_CLOSED, + RFCOMM_QUERY_FAIL, + RFCOMM_TX_FINISHED +}; + +struct rfcomm_config_t { + uint8 initial_credit; + uint8 credit_give_limit; + osMutexId creditMutex; +}; + +typedef void (*rfcomm_notify_callback_t)(enum rfcomm_event_enum event, + uint32 rfcomm_handle, + void *pdata, uint8 reason, void *priv); + +typedef void (*rfcomm_datarecv_callback_t)(uint32 rfcomm_handle, + struct pp_buff *ppb, void *priv); + +struct rfcomm_ctx_input { + struct ctx_content ctx; + struct bdaddr_t *remote; + uint32 l2cap_handle; + uint8 server_channel; + rfcomm_notify_callback_t rfcomm_notify_callback; + rfcomm_datarecv_callback_t rfcomm_datarecv_callback; +}; + +struct rfcomm_ctx_output { + uint32 rfcomm_handle; +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +int8 rfcomm_init(void); + +int8 rfcomm_register_server(int8 server_channel, + rfcomm_notify_callback_t notify_callback, + rfcomm_datarecv_callback_t datarecv_callback, + void *priv); + +int8 rfcomm_register_server_ex(int8 server_channel, + rfcomm_notify_callback_t notify_callback, + rfcomm_datarecv_callback_t datarecv_callback, + void *priv, + struct rfcomm_config_t *cfg); + +uint32 rfcomm_open(struct bdaddr_t *remote, int8 server_channel, + rfcomm_notify_callback_t notify_callback, + rfcomm_datarecv_callback_t datarecv_callback); + +uint32 rfcomm_open_ex(struct bdaddr_t *remote, int8 server_channel, + rfcomm_notify_callback_t rfcomm_notify_callback, + rfcomm_datarecv_callback_t rfcomm_datarecv_callback, + uint8 initial_credits, + uint8 credit_give_limit); + +int8 rfcomm_send (uint32 rfcomm_handle, uint8 *data, uint32 datalen, void *priv); + +int8 rfcomm_get_server_channel(uint32 rfcomm_handle); + +//int8 rfcomm_send_ppb (uint32 rfcomm_handle, struct pp_buff *ppb); + +//struct pp_buff *rfcomm_data_ppb_alloc (struct rfcomm_session *s, uint32 datalen); + +int8 rfcomm_close (uint32 rfcomm_handle); + +int8 rfcomm_unregister_server (int8 server_channel); + +int rfcomm_l2cap_notify_callback(enum l2cap_event_enum event, + uint32 l2cap_handle, void *pdata, uint8 reason); + +void rfcomm_l2cap_datarecv_callback(uint32 l2cap_handle, struct pp_buff *ppb); + +uint32 rfcomm_get_l2cap_handle(uint32 rfcomm_handle); + +uint32 rfcomm_save_ctx(uint32 rfcomm_handle, uint8_t *buf, uint32_t buf_len); + +uint32 rfcomm_restore_ctx(struct rfcomm_ctx_input *input, struct rfcomm_ctx_output *output); +void rfcomm_pts_register_dlci2_channel1(void); +void pts_rfcomm_close(void); +void pts_rfcomm_close_dlci0(void); +void pts_rfcomm_send_data(void); +struct rfcomm_session *rfcomm_session_search_l2caphandle(uint32 l2cap_handle); +struct rfcomm_session *rfcomm_session_search_bdaddr (struct bdaddr_t *bdaddr); +struct rfcomm_dlc *rfcomm_dlc_search(struct rfcomm_session *s, uint8 dlci); +const char *rfcomm_event2str(enum rfcomm_event_enum event); +uint32 rfcomm_get_rfcomm_handle(struct bdaddr_t *remote,int8 server_channel); + +struct rfcomm_registered_server_item_t *rfcomm_registered_server_search( + int8 server_channel ); + +int8 rfcomm_send_credits(struct rfcomm_session *s, uint8 addr, uint8 credits); +bool rfcomm_l2cap_channle_is_creating(struct bdaddr_t *remote); + +#if defined(__cplusplus) +} +#endif + +#endif /* __RFCOMM_I_H__ */ diff --git a/services/bt_profiles_enhanced/inc/sco.h b/services/bt_profiles_enhanced/inc/sco.h new file mode 100644 index 0000000..907e29a --- /dev/null +++ b/services/bt_profiles_enhanced/inc/sco.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __SCO_H__ +#define __SCO_H__ + +#include "sco_i.h" + +struct sco_item_t { + struct list_node list; + struct bdaddr_t remote_bdaddr; + + sco_notify_callback_t sco_notify_callback; + + void *priv; +}; + +#endif /* __SCO_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/sco_i.h b/services/bt_profiles_enhanced/inc/sco_i.h new file mode 100644 index 0000000..329b6f4 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/sco_i.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __SCO_I_H__ +#define __SCO_I_H__ + +#include "btlib_type.h" + +/* notify upper layer */ +enum sco_event_enum{ + SCO_OPENED, + SCO_CLOSED +}; + +typedef void (*sco_notify_callback_t)(enum sco_event_enum event, void *pdata, void *link_host); + +#if defined(__cplusplus) +extern "C" { +#endif + +int8 sco_register_link(struct bdaddr_t *bdaddr, + sco_notify_callback_t notify_callback, void *link_host); + +int8 sco_open_link(struct bdaddr_t *bdaddr, + sco_notify_callback_t notify_callback, void *link_host); + +int8 sco_close_link(struct bdaddr_t *bdaddr1, uint8 reason); + +int8 sco_unregister_link(struct bdaddr_t *bdaddr); + +int8 sco_init (void); + +int8 sco_exit (void); + +void sco_conn_opened_ind(struct bdaddr_t *bdaddr_remote); + +void sco_conn_closed_ind(struct bdaddr_t *bdaddr_remote); + +#if defined(__cplusplus) +} +#endif + +#endif /* __SCO_I_H__ */ \ No newline at end of file diff --git a/services/bt_profiles_enhanced/inc/sdp.h b/services/bt_profiles_enhanced/inc/sdp.h new file mode 100644 index 0000000..90dff0b --- /dev/null +++ b/services/bt_profiles_enhanced/inc/sdp.h @@ -0,0 +1,751 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SDP_H__ +#define __SDP_H__ + +#include "btlib_more.h" +#include "l2cap_i.h" +#include "bt_co_list.h" +#include "data_link.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SDP_PRIVATE_RECORD_LIST 1 +#define SDP_INVALID_HANDLE 0xFFFFFFFF + +/* + @brief PSM defination +*/ +#define SDP_PSM_SDP PSM_SDP +#define SDP_PSM_RFCOMM PSM_RFCOMM +#define SDP_PSM_AVCTP PSM_AVCTP +#define SDP_PSM_AVDTP PSM_AVDTP + +/* + @brief SDP data element type_size_table defination + bit0-5: len + bit6: 1 -- type_length is value + bit7: 0 -- len represent the size of data; 1 -- len represent the data size is contained + in the additional len bytes +*/ +#define SDP_DATA_LENGTH_MASK 0x3F +#define SDP_TYPE_SIZE_VALUE 0x40 +#define SDP_DATA_CONTAINED_IN_BYTE 0x80 + +/* + @brief PDU defination +*/ +#define SDP_PDU_ID_OFFSET 0 +#define SDP_TRANS_ID_OFFSET 1 +#define SDP_PARAM_LEN_OFFSET 3 +#define SDP_PDU_LEN 5 + +/* + @brief sdp_service_search_request defination + ServiceSearchPattern -- varies bytes + MaximumServiceRecordCount -- 2 bytes + ContinuationState -- 1-17 bytes +*/ +#define SDP_SERVICE_SEARCH_MIN_SIZE 8 +#define SDP_MAX_SER_RECORD_COUNT_LEN 2 + +/* + @brief sdp_service_attribute_request defination + ServiceRecordHandle -- 4 bytes + MaximumAttributeByteCount -- 2 bytes + AttributeIDList -- varies bytes + ContinuationState -- 1-17 bytes +*/ +#define SDP_SERVICE_ATTR_MIN_SIZE 12 +#define SDP_SER_RECORD_HANDLE_OFFSET 0 +#define SDP_SER_RECORD_HANDLE_LEN 4 +#define SDP_MAX_ATTR_BYTE_COUNT_OFFSET 4 +#define SDP_MAX_ATTR_BYTE_COUNT_LEN 2 +#define SDP_SER_ATTR_REQ_ID_LIST_OFFSET 6 + +/* + @brief sdp_service_search_attribute_request defination + ServiceSearchPattern -- varies bytes + MaximumAttributeByteCount -- 2 bytes + AttributeIDList -- varies bytes + ContinuationState -- 1-17 bytes +*/ +#define SDP_SERVICE_SEARCH_ATTR_MIN_SIZE 13 +//#define SDP_MAX_ATTR_BYTE_COUNT_LEN 2 + +/* + @brief Data element type defination + Refer to Table3.1 in Core_v5.0.pdf +*/ +#define DE_TYPE_MASK 0x1F +#define DE_TYPE_OFFSET 3 +enum data_element_type { + DE_TYPE_NIL = 0, + DE_TYPE_UINT = 1, + DE_TYPE_S2CMPLINT = 2, + DE_TYPE_UUID = 3, + DE_TYPE_TEXTSTR = 4, + DE_TYPE_BOOL = 5, + DE_TYPE_DESEQ = 6, + DE_TYPE_DEALT = 7, + DE_TYPE_URL = 8, +}; + +/* + @brief Data element size index defination + Refer to Table3.2 in Core_v5.0.pdf +*/ +#define DE_SIZE_MASK 0x07 +enum data_element_size { + DE_SIZE_0 = 0, + DE_SIZE_1 = 1, + DE_SIZE_2 = 2, + DE_SIZE_3 = 3, + DE_SIZE_4 = 4, + DE_SIZE_5 = 5, + DE_SIZE_6 = 6, + DE_SIZE_7 = 7, +}; + +/* + @brief SDP pdu id + Refer to 4.2 in Core_v5.0.pdf +*/ +enum sdp_pdu_id { + SDP_PDU_ErrorResponse = 0x01, + SDP_PDU_ServiceSearchRequest = 0x02, + SDP_PDU_ServiceSearchResponse = 0x03, + SDP_PDU_ServiceAttributeRequest = 0x04, + SDP_PDU_ServiceAttributeResponse = 0x05, + SDP_PDU_ServiceSearchAttributeRequest = 0x06, + SDP_PDU_ServiceSearchAttributeResponse = 0x07, +}; + +/* + @brief SDP Error Code + Refer to 4.4.1 SDP_ErrorResponse PDU +*/ +enum sdp_error_code { + SDP_Reserved_for_future_use = 0x0000, + SDP_Invalid_SDP_version = 0x0001, + SDP_Invalid_Service_Record_Handle = 0x0002, + SDP_Invalid_request_syntax = 0x0003, + SDP_Invalid_PDU_Size = 0x0004, + SDP_Invalid_Continuation_State = 0x0005, + SDP_Insufficient_Resources_to_satisfy_Request = 0x0006, +}; + +/* + @brief SDP Attribute ID Type +*/ +#define ATTR_ID_TYPE_RECORED_HANDLE \ + 0x00,0x00 + +/* + @brief SDP callback event +*/ +enum sdp_event { + SDP_EVT_TX_HANDLED = 0, + SDP_EVT_RESPONSE_ERROR, + SDP_EVT_CHANNEL_CLOSE, + SDP_EVT_TX_TIMEOUT, + SDP_EVT_RESPONSE, + SDP_EVT_UNKNOWN_ERROR, +}; + +/* + @brief SDP callback params +*/ +struct sdp_callback_params { + enum sdp_error_code error_code; + struct sdp_control_t *sdp_ctl; + struct { + uint8 *data; + uint32 data_len; + enum sdp_pdu_id response_pdu_id; + union { + struct { + uint8 *service_record_handle_list_buff; + uint32 service_record_handle_list_buff_len; + uint16 total_service_record_count; + uint16 current_service_record_count; + uint8 cont_state_len; + }service_search_response; + struct { + uint8 *attribute_list_buff; + uint32 attribute_list_buff_len; + uint16 attribute_list_bytes_count; + uint8 cont_state_len; + }service_search_attr_response; + }; + } response; +}; + +/* + @brief SDP connection role +*/ +enum sdp_connection_role { + SDP_ROLE_CLIENT = 0, + SDP_ROLE_SERVER, +}; + +/* + @brief SDP connection state +*/ +enum sdp_connection_state { + SDP_ST_STANDBY = 0, + SDP_ST_CONNECTING, + SDP_ST_CONNECTED, + SDP_ST_CLT_QUERING, + SDP_ST_DISCONNETING, +}; + +/* + @brief SDP tx state +*/ +enum sdp_tx_state { + SDP_TX_IDLE = 0, + SDP_TX_BUSY, +}; + +/* + @brief SDP ctl state +*/ +enum sdp_ctl_state { + SDP_CTL_FREE, + SDP_CTL_INUSE +}; + +/* + @brief SDP server record attribute +*/ +struct sdp_server_record_attr { + uint16 attr_id; + uint16 data_len; + const uint8 *data; + uint16 resv; +} __attribute__ ((__packed__)); + +/* + @brief SDP server record +*/ +struct sdp_server_record { + struct list_node node; + uint32 record_handle; + uint32 attr_list_count; + struct sdp_server_record_attr *attr_list; +}; + +/* + @brief SDP Request Callback +*/ +typedef void (*T_sdp_request_callback)(enum sdp_event event, struct sdp_callback_params *params, void *priv); + +/* + @brief SDP Request +*/ +struct sdp_request { + struct list_node node; + void *priv; + uint32 request_len; + uint8 *request_data; + struct bdaddr_t remote; + enum sdp_pdu_id type; + T_sdp_request_callback callback; +}; + +#define SDP_RESPONSE_SIZE (1024) +#define SDP_RESPONSE_HANDLES_SIZE (14) + +#define SDP_PACKET_HEADER_LEN (5) +#define SDP_PACKET_CONT_FIELD_LEN (1 + sizeof(SDP_CONT_STATE)) +#define SDP_PACKET_MAX_RSP_SDU_SIZE (128) + +/* + @brief SDP control struct +*/ +struct sdp_control_t +{ + struct list_node node; + enum sdp_connection_state conn_state; + enum sdp_ctl_state ctl_state; + enum sdp_connection_role role; + enum sdp_tx_state tx_state; + uint32 l2cap_handle; + struct bdaddr_t remote; + + // for server + uint32 max_attr_bytes_count; + uint16 response_trans_id; +#if defined(SDP_PRIVATE_RECORD_LIST) + struct list_node record_list; +#endif + uint16 refer_count; + uint8 response_pdu_header[SDP_PACKET_HEADER_LEN]; + uint32 response_handle_buff[SDP_RESPONSE_HANDLES_SIZE]; + uint8 response_handle_count; + uint8 response_handle_offset; + uint8 response_buff[SDP_RESPONSE_SIZE]; + uint32 response_buff_offset; + uint32 response_buff_len; + uint8 response_cont_data_len; + uint8 response_cont_data[16+1]; // 1 byte more to store cont data len + struct data_link response_data_list; + struct data_link response_head; + struct data_link response_data; + struct data_link response_cont; + + // for client + struct list_node request_list; + struct sdp_request *curr_request; + struct sdp_request *pending_request; + + uint16 request_trans_id; + uint8 request_cont_data_len; + uint8 request_cont_data[16+1]; // 1 byte more to store cont data len + uint8 request_pdu_header[5]; + struct data_link request_data_list; + struct data_link request_head; + struct data_link request_data; + struct data_link request_cont; +}; + + +/* + @brief Service Attribute ID +*/ +#define SERV_ATTRID_SERVICE_RECORD_HANDLE 0x0000 +#define SERV_ATTRID_SERVICE_CLASS_ID_LIST 0x0001 +#define SERV_ATTRID_SERVICE_RECORD_STATE 0x0002 +#define SERV_ATTRID_SERVICE_ID 0x0003 +#define SERV_ATTRID_PROTOCOL_DESC_LIST 0x0004 +#define SERV_ATTRID_BROWSE_GROUP_LIST 0x0005 +#define SERV_ATTRID_LANG_BASE_ID_LIST 0x0006 +#define SERV_ATTRID_SERVICE_INFO_TIME_TO_LIVE 0x0007 +#define SERV_ATTRID_SERVICE_AVAILABILITY 0x0008 +#define SERV_ATTRID_BT_PROFILE_DESC_LIST 0x0009 +#define SERV_ATTRID_DOC_URL 0x000a +#define SERV_ATTRID_CLIENT_EXEC_URL 0x000b +#define SERV_ATTRID_ICON_URL 0x000c +#define SERV_ATTRID_ADDITIONAL_PROT_DESC_LISTS 0x000d +#define SERV_ATTRID_SERVICE_NAME 0X0100 +#define SERV_ATTRID_PROVIDER_NAME 0X0102 +#define SERV_ATTRID_SDP_VERSION_NUMBER_LIST 0x0200 +#define SERV_ATTRID_SUPPORTED_FEATURES 0x0311 + +/* + @brief UUID +*/ +#define SERV_UUID_GENERIC_AUDIO 0x12,0x03 +#define SERV_UUID_HandsFree 0x11,0x1E +#define SERV_UUID_HandsFreeAudioGateway 0x11,0x1F +#define SERV_UUID_SDP 0x00,0x01 +#define SERV_UUID_UDP 0x00,0x02 +#define SERV_UUID_RFCOMM 0x00,0x03 +#define SERV_UUID_TCP 0x00,0x04 +#define SERV_UUID_TCS_BIN 0x00,0x05 +#define SERV_UUID_TCS_AT 0x00,0x06 +#define SERV_UUID_ATT 0x00,0x07 +#define SERV_UUID_OBEX 0x00,0x08 +#define SERV_UUID_IP 0x00,0x09 +#define SERV_UUID_FTP 0x00,0x0A +#define SERV_UUID_HTTP 0x00,0x0C +#define SERV_UUID_WSP 0x00,0x0E +#define SERV_UUID_BNEP 0x00,0x0F +#define SERV_UUID_UPNP 0x12,0x00 +#define SERV_UUID_HID_PROTOCOL 0x00,0x11 +#define SERV_UUID_HID_CTRL 0x00,0x11 +#define SERV_UUID_HID_INTR 0x00,0x13 +#define SERV_UUID_HardcopyControlChannel 0x00,0x12 +#define SERV_UUID_HardcopyDataChannel 0x00,0x14 +#define SERV_UUID_HardcopyNotification 0x00,0x16 +#define SERV_UUID_AVCTP 0x00,0x17 +#define SERV_UUID_AVDTP 0x00,0x19 +#define SERV_UUID_CMTP 0x00,0x1B +#define SERV_UUID_MCAPControlChannel 0x00,0x1E +#define SERV_UUID_MCAPDataChannel 0x00,0x1F +#define SERV_UUID_L2CAP 0x01,0x00 +#define SERV_UUID_SPP 0x11,0x01 +#define SERV_UUID_AUDIOSOURCE 0x11,0x0A +#define SERV_UUID_AUDIOSINK 0x11,0x0B +#define SERV_UUID_HID 0x11,0x24 +#define SERV_UUID_MAP 0x11,0x34 +#define SERV_UUID_AdvancedAudioDistribution 0x11,0x0D +#define SERV_UUID_AV_REMOTE_CONTROL 0x11,0x0E +#define SERV_UUID_AV_REMOTE_CONTROL_TARGET 0x11,0x0C +#define SERV_UUID_AV_REMOTE_CONTROL_CONTROLLER 0x11,0x0F + +/* + @brief Service Record defination helper macros +*/ +#define _U8VALUE(v) ((v)&0xFF) + +#define SDP_SPLIT_16BITS_BE(v) \ + _U8VALUE(v>>8),_U8VALUE(v) +#define SDP_SPLIT_32BITS_BE(v) \ + _U8VALUE(v>>24),_U8VALUE(v>>16),_U8VALUE(v>>8),_U8VALUE(v) + +#define X_SDP_COMBINE_16BITS_BE(a,b) \ + (_U8VALUE(a)<<8) | _U8VALUE(b) +#define SDP_COMBINE_16BITS_BE(...) \ + X_SDP_COMBINE_16BITS_BE(__VA_ARGS__) + +/* + @brief NIL +*/ +#define SDP_DE_NIL_H1_D0 \ + DE_TYPE_NIL<<3 + +/* + @brief Unsigned Integer +*/ +#define SDP_DE_UINT(size_index) \ + DE_TYPE_UINT<<3|size_index + +#define SDP_DE_UINT_H1_D1 \ + SDP_DE_UINT(DE_SIZE_0) + +#define SDP_DE_UINT_H1_D2 \ + SDP_DE_UINT(DE_SIZE_1) + +#define SDP_DE_UINT_H1_D4 \ + SDP_DE_UINT(DE_SIZE_2) + +#define SDP_DE_UINT_H1_D8 \ + SDP_DE_UINT(DE_SIZE_3) + +#define SDP_DE_UINT_H1_D16 \ + SDP_DE_UINT(DE_SIZE_4) + +/* + @brief Signed twos-complement integer +*/ +#define SDP_DE_S2CMPLINT(size_index) \ + DE_TYPE_S2CMPLINT<<3|size_index + +#define SDP_DE_S2CMPLINT_H1_D1 \ + SDP_DE_S2CMPLINT(DE_SIZE_0) + +#define SDP_DE_S2CMPLINT_H1_D2 \ + SDP_DE_S2CMPLINT(DE_SIZE_1) + +#define SDP_DE_S2CMPLINT_H1_D4 \ + SDP_DE_S2CMPLINT(DE_SIZE_2) + +#define SDP_DE_S2CMPLINT_H1_D8 \ + SDP_DE_S2CMPLINT(DE_SIZE_3) + +#define SDP_DE_S2CMPLINT_H1_D16 \ + SDP_DE_S2CMPLINT(DE_SIZE_4) + +/* + @brief UUID +*/ +#define SDP_DE_UUID(size_index) \ + DE_TYPE_UUID<<3|size_index + +#define SDP_DE_UUID_H1_D2 \ + SDP_DE_UUID(DE_SIZE_1) + +#define SDP_DE_UUID_H1_D4 \ + SDP_DE_UUID(DE_SIZE_2) + +#define SDP_DE_UUID_H1_D16 \ + SDP_DE_UUID(DE_SIZE_4) + +/* + @brief Text string +*/ +#define SDP_DE_TEXTSTR_8BITSIZE_H2_D(size) \ + DE_TYPE_TEXTSTR<<3|DE_SIZE_5,_U8VALUE(size) + +#define SDP_DE_TEXTSTR_16BITSIZE_H3_D(size) \ + DE_TYPE_TEXTSTR<<3|DE_SIZE_6,_U8VALUE(size),_U8VALUE(size>>8) + +#define SDP_DE_TEXTSTR_32BITSIZE_H5_D(size) \ + DE_TYPE_TEXTSTR<<3|DE_SIZE_7,_U8VALUE(size),U*VALUE(size>>8),_U8VALUE(size>>16),_U8VALUE(size>>24) + +/* + @brief Boolean +*/ +#define SDP_DE_BOOL_H1_D1 \ + DE_TYPE_BOOL<<3|DE_SIZE_0 + +/* + @brief Data element sequence +*/ +#define SDP_DE_DESEQ_8BITSIZE_H2_D(size) \ + DE_TYPE_DESEQ<<3|DE_SIZE_5,_U8VALUE(size) + +#define SDP_DE_DESEQ_16BITSIZE_H3_D(size) \ + DE_TYPE_DESEQ<<3|DE_SIZE_6,_U8VALUE(size),_U8VALUE(size>>8) + +#define SDP_DE_DESEQ_32BITSIZE_H5_D(size) \ + DE_TYPE_DESEQ<<3|DE_SIZE_7,_U8VALUE(size),U*VALUE(size>>8),_U8VALUE(size>>16),_U8VALUE(size>>24) + +/* + @brief Data element alternative +*/ +#define SDP_DE_DEALT_8BITSIZE_H2_D(size) \ + DE_TYPE_DEALT<<3|DE_SIZE_5,_U8VALUE(size) + +#define SDP_DE_DEALT_16BITSIZE_H3_D(size) \ + DE_TYPE_DEALT<<3|DE_SIZE_6,_U8VALUE(size),_U8VALUE(size>>8) + +#define SDP_DE_DEALT_32BITSIZE_H5_D(size) \ + DE_TYPE_DEALT<<3|DE_SIZE_7,_U8VALUE(size),_U8VALUE(size>>8),_U8VALUE(size>>16),_U8VALUE(size>>24) + +/* + @brief URL +*/ +#define SDP_DE_URL_8BITSIZE_H2_D(size) \ + DE_TYPE_URL<<3|DE_SIZE_5,_U8VALUE(size) + +#define SDP_DE_URL_16BITSIZE_H3_D(size) \ + DE_TYPE_URL<<3|DE_SIZE_6,_U8VALUE(size),_U8VALUE(size>>8) + +#define SDP_DE_URL_32BITSIZE_H5_D(size) \ + DE_TYPE_URL<<3|DE_SIZE_7,_U8VALUE(size),_U8VALUE(size>>8),_U8VALUE(size>>16),_U8VALUE(size>>24) + + +/* + @brief Define a attribute +*/ +#define SDP_DEF_ATTRIBUTE(attr_id,attrs) \ + { \ + attr_id,sizeof(attrs),attrs,0x0, \ + } + +/* + @brief SDP init + @param in_ctl - control instance + + @return error code - 0 for no error +*/ +int32 sdp_init(struct sdp_control_t *in_ctl); + +/* + @brief SDP init server record + @param in_attr_list - attr list + @param in_attr_list_len - attr list len in bytes + @param out_record - output record + + @return error code - 0 for no error +*/ +int32 sdp_init_server_record(struct sdp_server_record_attr *in_attr_list, uint32 in_attr_list_len, struct sdp_server_record *out_record); + +/* + @brief Parse an element from buffer + @param in_buff - buffer to parse + @param in_len - buffer length + @param out_type - element type + @param out_header_len - element total length + @param out_data_len - element data length + + @return error code - 0 for no error +*/ +int32 sdp_parse_data_element(uint8 *in_buff, uint32 in_len, + enum data_element_type *out_type, uint32 *out_header_len, uint32 *out_data_len); + +/* + @brief Gether all right size uuid in ServiceClassID attr + @param out_buff - buffer to fill + @param out_buff_len - buffer length + @param in_uuid_size - uuid size to find (in bytes) + @param out_len - output length (in bytes) + @param out_real_len - real uuid length (in bytes) + + @return error code - 0 for no error +*/ +int32 sdp_gether_global_service_uuids(uint8 in_uuid_size, uint8 *out_buff, uint32 out_buff_len, uint32 *out_len, uint32 *out_real_len); + +/* + @brief Get attribute from attribute list + Return attribute value data element (array) + @param in_buff - buffer to parse + @param in_len - buffer length + @param in_attr_id - attribute id buffer + @param in_attr_id_len - attribute id buffer len + @param out_attr - found attribute value buffer (array), it is a data element sequence (array) + @param out_attr - found attribute value buffer len (array) + @param in_out_max_attr_count - out_attr pointer count, we may found multiple attribute + @param out_attr_count - real found out_attr ponter count + + @return error code - 0 for no error +*/ +int32 sdp_get_attribute_from_attribute_list(uint8 *in_buff, uint32 in_len, + uint8 *in_attr_id, uint8 in_attr_id_len, uint32 *out_attr, uint32 *out_attr_len, uint32 in_out_attr_count, uint32 *out_attr_count); + +/* + @brief Iterate data element list + These macros are used when too much loops in one function + @param label - name for this iterate (any symbol, like L1,L2,...) + @param in_de_list_buff - element list buffer (uint8 *) + @param in_de_buff_len - element list buffer len (uint32) + @param out_de_buff - found data element buffer (uint8 *) + @param out_type - found data element type (enum data_element_type *) + @param out_header_len - found data element header len (uint32 *) + @param out_data_len - found data element data len (uint32 *) + @param out_error - 0 means no error (uint32 *) +*/ +#define SDP_ITERATE_DATA_ELEMENT_LIST_START(label,in_de_list_buff,in_de_buff_len,out_de_buff,out_type,out_header_len,out_data_len,out_error) \ + { \ + POSSIBLY_UNUSED int32 __ret = 0, __break = 0; \ + POSSIBLY_UNUSED uint8 *__buff = in_de_list_buff; \ + POSSIBLY_UNUSED uint32 __offset = 0, __buff_len = in_de_buff_len; \ + while (__offset < __buff_len) { \ + *out_error = 0; \ + __ret = sdp_parse_data_element(__buff, __buff_len-__offset, out_type, out_header_len, out_data_len); \ + out_de_buff = __buff; \ + if (__ret != 0) { \ + *out_error = 1; \ + } \ + __buff += *out_header_len + *out_data_len; \ + __offset += *out_header_len + *out_data_len; + +#define S_I_D_E_L_CONTINUE(label) \ + goto __finish_loop_##label; + +#define S_I_D_E_L_BREAK(label) \ + __break = 1; goto __finish_loop_##label; + +#define SDP_ITERATE_DATA_ELEMENT_LIST_END(label) \ + } \ + } + +#if 0 +#define SDP_ITERATE_DATA_ELEMENT_LIST_END(label) \ + POSSIBLY_UNUSED __finish_loop_##label: \ + if (__break) break; \ + } \ + } +#endif + +/* + @brief UUID Compare + @param uuid_a - uuid value a + @param uuid_a_len - uuid value a len + @param uuid_b - uuid value a + @param uuid_b_len - uuid value b len + + @return result, 1 if equal, or 0 +*/ +int32 sdp_uuid_cmp(uint8 *uuid_a, uint32 uuid_a_len, uint8 *uuid_b, uint32 uuid_b_len); + +/* + @brief Find uuid in data element list + An data elemement list means an array of data element who has buffer address and buffer length. + It can be a data element sequence/alternative or a few data elements in an array. + In common case, no matter sdp request or sdp response, data to be parsed in which will be a data element sequence. + + @param in_buff - buffer to parse + @param in_buff_len - buffer length + @param in_uuid - uuid to find + @param in_uuid_len - uuid length + + @return result, 0 means not found, 1 means found at least one +*/ +int32 sdp_find_uuid_in_data_element_list(uint8 *in_buff, uint32 in_len, uint8 *uuid, uint32 uuid_len); + + +/* + @brief Walk data element list + Details see sdp_find_uuid_in_data_element_list. + + @param in_buff - buffer to parse + @param in_buff_len - buffer length + @param cb - callback for caller to deal with current data element + @param stop - stop flag, 1 to stop walking + @param priv - priv data to pass into cb + + @return result, 0 - no error, non 0 - error +*/ +typedef void (*T_sdp_walk_data_element_list_cb)(enum data_element_type type, uint8 *parent_buff, uint8 *buff, \ + uint32 header_len, uint32 data_len, uint8 *stop, uint32 *priv); +int32 sdp_walk_data_element_list(uint8 *buff, uint32 buff_len, T_sdp_walk_data_element_list_cb cb, uint8 *stop, uint32 *priv); + +/* + @brief SDP client send a request to server + @param in_ctl - control instance + @param in_request - request to send + + @return error code - 0 for no error +*/ +int32 sdp_client_request(struct sdp_request *in_request); + +/* + @brief SDP close + @param in_ctl - control instance + + @return error code - 0 for no error +*/ +int32 sdp_close(struct sdp_control_t *in_ctl); + +/* + @brief SDP server add record + @param in_ctl - control instance + @param in_record - server record + + @return error code - 0 for no error +*/ +#if defined(SDP_PRIVATE_RECORD_LIST) +int32 sdp_server_add_record(struct sdp_control_t *in_ctl, struct sdp_server_record *in_record); +int32 sdp_server_remove_record(struct sdp_control_t *in_ctl, struct sdp_server_record *in_record); +#endif +int32 sdp_server_add_global_record(struct sdp_server_record *in_record); +int32 sdp_server_remove_global_record(struct sdp_server_record *in_record); +uint32 sdp_serv_find_sdp_record_handle(uint32 handle); + +/* + @brief Generate an data element in given buffer + @param in_buff - buffer to generate the data element + @param in_len - buffer length + @param in_type - element type + @param in_data - data buffer + @param in_data_len - element data length + @param out_header_len - output header len + + @return error code - 0 for no error +*/ +int32 sdp_generate_an_data_element(uint8 *in_buff, uint32 in_len, enum data_element_type type, int8 *in_data, uint32 in_data_len, uint32 *ou_header_len); + +/* + @brief Edit an data element length in given buffer + @param in_len - buffer length + @param in_buff - buffer to generate the data element + + @return error code - 0 for no error +*/ +int32 sdp_edit_data_element_length(uint8 *in_buff, uint32 in_buff_len, uint32 in_data_len); + +/* + @brief Convert sdp event to string + @param event - event + + @return event string or "[]" +*/ +const char *sdp_event2str(enum sdp_event event); + +uint16 sdp_serv_find_max_attr_id(const struct sdp_server_record *record, uint16 origin_max); + + +#ifdef __cplusplus +} +#endif + +#endif /* __SDP_H__ */ diff --git a/services/bt_profiles_enhanced/inc/sppnew.h b/services/bt_profiles_enhanced/inc/sppnew.h new file mode 100644 index 0000000..32b8bb4 --- /dev/null +++ b/services/bt_profiles_enhanced/inc/sppnew.h @@ -0,0 +1,152 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPPNEW_H__ +#define __SPPNEW_H__ + +#include "btlib_more.h" +#include "l2cap_i.h" +#include "bt_co_list.h" +#include "data_link.h" +#include "sdp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum sppnew_event { + SPPNEW_EVENT_OPEN, + SPPNEW_EVENT_NEW_OPEN, + SPPNEW_EVENT_DATA_IND, + SPPNEW_EVENT_CLOSE, + SPPNEW_EVENT_TX_HANDLED, + SPPNEW_EVENT_QUERY_FAIL, +}; + +enum sppnew_chnl_state { + SPPNEW_CHNL_STATE_CLOSE, + SPPNEW_CHNL_STATE_QUERING, + SPPNEW_CHNL_STATE_CONNECTING, + SPPNEW_CHNL_STATE_OUT_CLOSING, + SPPNEW_CHNL_STATE_OPEN, +}; + +enum sppnew_tx_state { + SPPNEW_TX_STATE_IDLE, + SPPNEW_TX_STATE_BUSY, +}; + +struct sppnew_callback_param { + union { + struct { + uint8 *buff; + uint32 buff_len; + } data_ind; + struct { + uint8 *buff; + uint32 buff_len; + } tx_handled; + struct { + void *remDev; + } open; + struct { + void *remDev; + } new_open; + struct { + uint8 reason; + void *remDev; + } close; + } p; +}; + +enum sppnew_device_type { + SPPNEW_DEVICE_TYPE_CLIENT, + SPPNEW_DEVICE_TYPE_SERVER, +}; + +struct sppnew_channel; +typedef int8 (*sppnew_callback)(struct sppnew_channel *chnl, enum sppnew_event event, struct sppnew_callback_param *param); + +struct sppnew_setup { + uint32 buad_rate; +}; + +struct sppnew_packet { + struct list_node node; + uint8 *buff; + uint32 buff_len; +}; + +struct sppnew_config { + #if 0 + uint8 *tx_buff; + uint32 tx_buff_len; + #endif + sppnew_callback callback; + uint8 local_server_channel; + uint32 tx_packet_list_length; + enum sppnew_device_type dev_type; + struct sppnew_packet *tx_free_packet; + void *priv; +}; + +struct sppnew_channel { + struct list_node node; + uint32 tx_size_max; + uint32 rfcomm_handle; + struct bdaddr_t bdaddr; + struct sppnew_config cfg; + uint8 remote_server_channel; + enum sppnew_chnl_state state; + enum sppnew_tx_state tx_state; + struct list_node tx_pend_list; + struct list_node tx_free_list; + struct sppnew_packet *tx_packet; + struct sdp_request sdp_request; +}; + +struct sppnew_ctx_input { + struct ctx_content ctx; + struct sppnew_channel *chnl; + struct sppnew_config *cfg; + uint32 rfcomm_handle; + struct bdaddr_t *remote; +}; + +struct sppnew_ctx_output { +}; + +int8 sppnew_init(struct sppnew_channel *chnl, struct sppnew_config *config); +int8 sppnew_open_server(struct sppnew_channel *chnl, struct rfcomm_config_t * cfg); +int8 sppnew_open_client(struct sppnew_channel *chnl, struct bdaddr_t *bdaddr, uint8 remote_channel); +int8 sppnew_query_and_open_client(struct sppnew_channel *chnl, struct bdaddr_t *bdaddr, uint8 *query, uint32 query_len); +int8 sppnew_write(struct sppnew_channel *chnl, uint8 *buff, uint32 buff_len); +int8 sppnew_setup(struct sppnew_channel *chnl, struct sppnew_setup *setup); +int8 sppnew_disconnect(struct sppnew_channel *chnl); +int8 sppnew_close(struct sppnew_channel *chnl); +enum sppnew_chnl_state sppnew_get_state(struct sppnew_channel *chnl); +void *sppnew_get_priv(struct sppnew_channel *chnl); +const char *sppnew_event2str(enum sppnew_event event); +void _sppnew_rfc_notify_callback(enum rfcomm_event_enum event, uint32 rfcomm_handle, void *pdata, uint8 reason, void *priv); +void _sppnew_rfc_datarecv_callbac(uint32 rfcomm_handle, struct pp_buff *ppb, void *priv); +void sppnew_delete_chnl_note(struct sppnew_channel *chnl); +uint32 sppnew_save_ctx(struct sppnew_channel *chnl, uint8_t *buf, uint32_t buf_len); +uint32 sppnew_restore_ctx(struct sppnew_ctx_input *input, struct sppnew_ctx_output *output); + +#ifdef __cplusplus +} +#endif + +#endif /* __SPPNEW_H__ */ diff --git a/services/bt_profiles_enhanced/inc/win32_os.h b/services/bt_profiles_enhanced/inc/win32_os.h new file mode 100644 index 0000000..fdcc9dc --- /dev/null +++ b/services/bt_profiles_enhanced/inc/win32_os.h @@ -0,0 +1,127 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include +#include +#include + +#ifndef __WIN32_OS__ +#define __WIN32_OS__ + +#if defined(__cplusplus) +extern "C" { +#endif + +//---- MACROS ----// +#define Plt_Assert(expr,...) assert(expr) +#define Plt_TICKS_TO_MS(ticks) (ticks) +#define POSSIBLY_UNUSED +#define ITER_ASSERT(...) +#define Plt_DUMP8(...) + +#define OS_CRITICAL_METHOD 0 +#define OS_ENTER_CRITICAL() +#define OS_EXIT_CRITICAL() +#define OSTimeDly(a) + +//---- TYPES ----// +typedef short I16; +typedef unsigned char U8; +typedef unsigned short U16; +typedef unsigned int U32; +typedef unsigned char BOOL; +#define ALIGNED(a) __attribute__((aligned(a))) +typedef U32 bt_status_t; + +enum _bt_status { + BT_STS_SUCCESS = 0, + BT_STS_FAILED = 1, + BT_STS_PENDING = 2, + BT_STS_BUSY = 11, + BT_STS_NO_RESOURCES = 12, + BT_STS_NOT_FOUND = 13, + BT_STS_DEVICE_NOT_FOUND = 14, + BT_STS_CONNECTION_FAILED = 15, + BT_STS_TIMEOUT = 16, + BT_STS_NO_CONNECTION = 17, + BT_STS_INVALID_PARM = 18, + BT_STS_IN_PROGRESS = 19, + BT_STS_RESTRICTED = 20, + BT_STS_INVALID_TYPE = 21, + BT_STS_HCI_INIT_ERR = 22, + BT_STS_NOT_SUPPORTED = 23, + BT_STS_IN_USE = 5, + BT_STS_SDP_CONT_STATE = 24, + BT_STS_CONTINUE =24, + BT_STS_CANCELLED = 25, + + /* The last defined status code */ + BT_STS_LAST_CODE = BT_STS_CANCELLED, +}; + +typedef struct { + unsigned char address[6]; +} __attribute__ ((packed)) bt_bdaddr_t; + +typedef unsigned char btif_link_key_type_t; + +typedef struct { + bt_bdaddr_t bdAddr; + bool trusted; + unsigned char linkKey[16]; + btif_link_key_type_t keyType; + + unsigned char pinLen; +} btif_device_record_t; + +typedef void (*ibrt_cmd_complete_callback)(const unsigned char *para); +typedef bool (*ibrt_io_capbility_callback)(void *bdaddr); + +#define BLE_ADV_REPORT_MAX_LEN 31 + +typedef struct { + unsigned char type; + unsigned char addr_type; + bt_bdaddr_t addr; + unsigned char data_len; + unsigned char data[BLE_ADV_REPORT_MAX_LEN]; + unsigned char rssi; +} btif_ble_adv_report; + +#define BTIF_BEC_USER_TERMINATED 0x13 + +//------ VARS ------// +#define BT_LOCAL_NAME "bes_enhanced_stack_core" +extern unsigned char bt_addr[6]; +extern unsigned char ble_addr[6]; + +extern struct besbt_cfg_t besbt_cfg; + +//------ DDB ------// +bt_status_t ddbif_delete_record(const bt_bdaddr_t *bdAddr); +bt_status_t ddbif_open(const bt_bdaddr_t *bdAddr); +bt_status_t ddbif_add_record(btif_device_record_t *record); +bt_status_t ddbif_find_record(const bt_bdaddr_t *bdAddr, btif_device_record_t *record); +bt_status_t ddbif_enum_device_records(I16 index, btif_device_record_t *record); + +//------ BTIF ------// +void btif_adv_event_report(const btif_ble_adv_report* event); + +#if defined(__cplusplus) +} +#endif + +#endif // __WIN32_OS__ diff --git a/services/communication/Makefile b/services/communication/Makefile new file mode 100644 index 0000000..eab9024 --- /dev/null +++ b/services/communication/Makefile @@ -0,0 +1,21 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ifeq ($(USE_KNOWLES),1) +obj-y += comminication_knowles/ +endif + +ccflags-y += \ + -Iapps/common \ + -Iplatform/drivers/usb/usb_dev/inc \ + -Iplatform/drivers/ana \ + $(BT_IF_INCLUDES) \ + -Iservices/communication/comminication_knowles \ + -Ithirdparty/knowles_uart_lib \ + -Iutils/crc32 \ + -Iservices/app_ai/inc + diff --git a/services/communication/comminication_knowles/Makefile b/services/communication/comminication_knowles/Makefile new file mode 100644 index 0000000..fb3fafc --- /dev/null +++ b/services/communication/comminication_knowles/Makefile @@ -0,0 +1,24 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) + +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + + +subdir-ccflags-y += \ + -Iapps/common \ + -Iplatform/drivers/usb/usb_dev/inc \ + -Iplatform/drivers/ana \ + -Iutils/crc32 \ + -Iservices/bt_app \ + -Iservices/communication/comminication_knowles \ + -Iservices/audio_dump/include \ + -Iutils/cqueue \ + $(BT_IF_INCLUDES) \ + -Ithirdparty/userapi/knowles_uart_app \ + -Ithirdparty/knowles_uart_lib \ + -Iservices/app_ai/inc + diff --git a/services/communication/comminication_knowles/communication_cmd_handle.cpp b/services/communication/comminication_knowles/communication_cmd_handle.cpp new file mode 100644 index 0000000..96f63c3 --- /dev/null +++ b/services/communication/comminication_knowles/communication_cmd_handle.cpp @@ -0,0 +1,78 @@ +#include "stdint.h" +#include "stdbool.h" +#include "plat_types.h" +#include "hal_chipid.h" +#include "hal_trace.h" +#include "string.h" +#include "hal_dma.h" +#include "communication_cmd_handle.h" + +static bool communication_cmd_inited = false; +static int (*send_reply_cb)(const unsigned char *, unsigned int); + +extern "C" int extend_cmd_pmu_open(void); + +int communication_cmd_init(int (* cb)(const unsigned char *, unsigned int)) +{ + if (!communication_cmd_inited){ + send_reply_cb = cb; + communication_cmd_inited = true; + } + return 0; +} + + +int communication_cmd_send_reply(const unsigned char *payload, unsigned int len) +{ + return send_reply_cb(payload, len); +} + +enum ERR_CODE communication_cmd_check_msg_hdr(struct message_t *msg) +{ + return ERR_NONE; +} + +void FloatToByte(float floatNum,unsigned char* byteArry) +{ + char* pchar=(char*)&floatNum; + for(u32 i=0;i>24); \ + *(ptr+2) = (uint8_t) (val>>16); \ + *(ptr+1) = (uint8_t) (val>>8); \ + *(ptr+0) = (uint8_t) val; \ + }while(0) + +int communication_cmd_init(int (* cb)(const unsigned char *, unsigned int)); + +int communication_cmd_send_reply(const unsigned char *payload, unsigned int len); + +enum ERR_CODE communication_cmd_check_msg_hdr(struct message_t *msg); + +enum ERR_CODE communication_cmd_handle_cmd(enum COMMUNICATION_CMD_TYPE cmd, unsigned char *param, unsigned int len); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/communication/comminication_knowles/communication_cmd_msg.h b/services/communication/comminication_knowles/communication_cmd_msg.h new file mode 100644 index 0000000..954097d --- /dev/null +++ b/services/communication/comminication_knowles/communication_cmd_msg.h @@ -0,0 +1,20 @@ +#ifndef __COMMUNICATION_CMD_MSG_H__ +#define __COMMUNICATION_CMD_MSG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum COMMUNICATION_CMD_TYPE { + COMMUNICATION_CMD_EQ_OP = 0xA1, + COMMUNICATION_CMD_DRC_OP = 0xA2, + COMMUNICATION_CMD_HF_OP = 0xA3, +}; + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/communication/comminication_knowles/communication_sysapi.cpp b/services/communication/comminication_knowles/communication_sysapi.cpp new file mode 100644 index 0000000..f5d934c --- /dev/null +++ b/services/communication/comminication_knowles/communication_sysapi.cpp @@ -0,0 +1,646 @@ +#include "cmsis_os.h" +#include "stdint.h" +#include "stdbool.h" +#include "string.h" +#include "cmsis_nvic.h" +#include "tool_msg.h" +#include "app_ai_if_config.h" +//#include "hal_timer_raw.h" +#include "hal_uart.h" +#include "hal_cmu.h" +#include "hal_bootmode.h" +#include "hal_iomux.h" +#include "pmu.h" +#include "app_thread.h" +#include "communication_sysapi.h" +#include "tgt_hardware.h" + +//#define FLASH_BASE 0x6C000000 +//#define FLASH_TO_FLASHX(d) ((uint32_t)(d) & 0x0FFFFFFF) + +#define WAIT_TRACE_TIMEOUT MS_TO_TICKS(200) + +static uint32_t send_timeout = MS_TO_TICKS(500); + +static const struct HAL_UART_CFG_T uart_cfg = { + HAL_UART_PARITY_NONE, +#ifdef __KNOWLES + HAL_UART_STOP_BITS_2, +#else + HAL_UART_STOP_BITS_1, +#endif + HAL_UART_DATA_BITS_8, + HAL_UART_FLOW_CONTROL_NONE, // RTC/CTS pins might be unavailable for some chip packages + HAL_UART_FIFO_LEVEL_1_2, + HAL_UART_FIFO_LEVEL_1_2, +#ifdef __PC_CMD_UART__ + 115200, +#else + 921600, +#endif + true, + false, + false, +}; +#ifdef __PC_CMD_UART__ +static const enum HAL_UART_ID_T comm_uart = HAL_UART_ID_0; +#else +#ifdef CHIP_BEST2300P +static const enum HAL_UART_ID_T comm_uart = HAL_UART_ID_2; +#else +static const enum HAL_UART_ID_T comm_uart = HAL_UART_ID_1; +#endif +#endif +static volatile enum UART_DMA_STATE uart_dma_rx_state = UART_DMA_IDLE; +static volatile uint32_t uart_dma_rx_size = 0; +static bool uart_opened = false; + + +static volatile bool cancel_xfer = false; + +static uint32_t xfer_err_time = 0; +static uint32_t xfer_err_cnt = 0; + +#ifdef __KNOWLES + +#include "Knowles_mic_demo.h" +#include "audio_dump.h" +#include "cqueue.h" + +uint32_t kw_start_index = 0; +uint32_t kw_end_index = 0; +bool is_markers_read_done = false; + +#ifdef KNOWLES_UART_DATA +uint8_t out_buf[ FRAME_SIZE ]; +uint8_t found = 0; + +static osMutexId uart_audio_pcmbuff_mutex_id = NULL; +osMutexDef(uart_audio_pcmbuff_mutex); + +typedef enum { + PP_PING = 0, + PP_PANG = 1 +} FIR_PP_T; + + +#define PP_PINGPANG(v) \ + (v == PP_PING ? PP_PANG: PP_PING) + +static FIR_PP_T pp_index=PP_PING; +static uint32_t uart_dma_interval; + +#define knowles_uart_packet_len FRAME_SIZE //640//20MS +static uint8_t audio_data_receive_buf[knowles_uart_packet_len*2]; //ping_pong_buffer + + +#ifdef SYSTEM_USE_PSRAM +#include "hal_location.h" +#define AMA_STREAM_UART_FIFO_SIZE (1024*32) +PSRAM_BSS_LOC static unsigned char ama_uart_buff[AMA_STREAM_UART_FIFO_SIZE]; +#else +#define AMA_STREAM_UART_FIFO_SIZE (1024*16) +static unsigned char ama_uart_buff[AMA_STREAM_UART_FIFO_SIZE]; +#endif +static CQueue ama_uart_queue = {0}; + +extern osThreadId knowles_uart_audio_tid; + +#define APP_UART_FLOW_CONTROL_TIMEOUT_INTERVEL (12) + +static void app_uart_flow_control_timeout_timer_cb(void const *n); +osTimerDef (APP_UART_FLOW_CONTROL_TIMEOUT, app_uart_flow_control_timeout_timer_cb); +osTimerId app_uart_flow_control_timeout_timer_id = NULL; + + + +static void app_uart_flow_control_timeout_timer_cb(void const *n) +{ + uint32_t available_buffer; + unsigned char get_next_chunk_cmd[4]; + smart_mic_get_nextchunk_cmd(get_next_chunk_cmd); + + available_buffer = avil_len_of_the_fifo(); + available_buffer = AMA_STREAM_UART_FIFO_SIZE - available_buffer; + + TRACE(1,"UART_FLOW_CONTROL: Available UART Buffer %d\n", available_buffer); + if(available_buffer > 1024) + { + //TRACE(0,"More than 1024 bytes availble hence sending next chunk command \n"); + send_data(get_next_chunk_cmd, 4); + osTimerStop(app_uart_flow_control_timeout_timer_id); + osTimerStart(app_uart_flow_control_timeout_timer_id, APP_UART_FLOW_CONTROL_TIMEOUT_INTERVEL); + } + else + { + //TRACE(0,"no buffer available hence triggering timer for 10ms\n"); + osTimerStop(app_uart_flow_control_timeout_timer_id); + osTimerStart(app_uart_flow_control_timeout_timer_id, APP_UART_FLOW_CONTROL_TIMEOUT_INTERVEL); + } +} + +void ama_uart_stream_fifo_init() +{ + if (uart_audio_pcmbuff_mutex_id == NULL) + { + uart_audio_pcmbuff_mutex_id = osMutexCreate((osMutex(uart_audio_pcmbuff_mutex))); + } + + pp_index=PP_PING; + + if (knowles_uart_audio_tid) + { + osSignalClear(knowles_uart_audio_tid, UART_OUT_SIGNAL_ID); + } + + memset(audio_data_receive_buf,0,sizeof(audio_data_receive_buf)); + InitCQueue(&ama_uart_queue, AMA_STREAM_UART_FIFO_SIZE, + (CQItemType *)ama_uart_buff); +} + +uint32_t ama_uart_get_fifo_data(uint8_t *buf) +{ + uint32_t avail = 0; + + avail = LengthOfCQueue(&ama_uart_queue); + if (avail > 0) { + if (avail < knowles_uart_packet_len) { + TRACE(2,"%s: Invalid UART STREAM SIZE: %d", __FUNCTION__, avail); + return 0; + } else { + //TRACE(1,"UART_GET_len %d",knowles_uart_packet_len); + if(!DeCQueue(&ama_uart_queue, buf, knowles_uart_packet_len)) + return knowles_uart_packet_len; + TRACE(2,"%s: queue get data error len %d", __func__, knowles_uart_packet_len); + return 0; + } + } else { + TRACE(0,"uart no stream to get"); + return 0; + } +} + +uint32_t avil_len_of_the_fifo() +{ + return LengthOfCQueue(&ama_uart_queue); +} + +extern "C" void OS_NotifyEvm(void); + +void send_message() +{ + OS_NotifyEvm(); +} +#endif +#endif + +static void uart_break_handler(void) +{ + TRACE(0,"****** Handle break ******"); + + cancel_xfer = true; + hal_uart_stop_dma_recv(comm_uart); + hal_uart_stop_dma_send(comm_uart); + uart_dma_rx_state = UART_DMA_ERROR; +} + +extern "C" uint8_t app_ai_is_stream_running(void); +static void uart_rx_dma_handler(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status) +{ + if (status.BE) { + uart_break_handler(); + return; + } + + // The DMA transfer has been cancelled +#ifndef KNOWLES_UART_DATA + if (uart_dma_rx_state != UART_DMA_START) { + return; + } +#endif + uart_dma_rx_size = xfer_size; + if (dma_error || status.FE || status.OE || status.PE || status.BE) { + TRACE(2,"UART-RX Error: dma_error=%d, status=0x%08x", dma_error, status.reg); + uart_dma_rx_state = UART_DMA_ERROR; + } else { + //TRACE(1,"UART-RX OK: rx_size=%d", uart_dma_rx_size); + uart_dma_rx_state = UART_DMA_DONE; + int ret = 0; + //TRACE(1,"UART DMA INTERUPT TIME=%d",hal_sys_timer_get()-uart_dma_interval); + uart_dma_interval=hal_sys_timer_get(); + if(app_ai_is_stream_running()) + { + if(!EnCQueue(&ama_uart_queue, (uint8_t *)&audio_data_receive_buf[pp_index*knowles_uart_packet_len], FRAME_SIZE)) + ret = FRAME_SIZE; + if (ret < FRAME_SIZE) { + TRACE(2,"%s:WARNING !!! UART STREAM OVERFLOW Dropping %d Bytes", __FUNCTION__, (FRAME_SIZE - ret)); + } + + osSignalSet(knowles_uart_audio_tid, UART_OUT_SIGNAL_ID); + } + pp_index=PP_PINGPANG(pp_index); + } +} + +void recv_data_state_get(enum UART_DMA_STATE *state) +{ + *state = uart_dma_rx_state; +} + +void recv_data_reset(void) +{ + union HAL_UART_IRQ_T mask; + mask.reg = 0; + mask.BE = 1; + hal_uart_irq_set_mask(comm_uart, mask); + uart_dma_rx_state = UART_DMA_IDLE; +} + +void init_transport(void) +{ + union HAL_UART_IRQ_T mask; + struct HAL_UART_CFG_T comm_uart_cfg; +#ifdef KNOWLES_UART_DATA + //audio_dump_init(320, 1); + ama_uart_stream_fifo_init(); +#endif + if (!uart_opened) { +#ifdef __PC_CMD_UART__ + hal_iomux_set_uart0(); +#else +#ifdef CHIP_BEST2300P + hal_iomux_init(cfg_pinmux_uart, ARRAY_SIZE(cfg_pinmux_uart)); +#else + hal_iomux_set_uart1(); +#endif +#endif + memcpy(&comm_uart_cfg, &uart_cfg, sizeof(comm_uart_cfg)); + hal_uart_open(comm_uart, &comm_uart_cfg); + mask.reg = 0; + mask.BE = 1; + mask.FE = 1; + mask.OE = 1; + mask.PE = 1; + + hal_uart_irq_set_dma_handler(comm_uart, uart_rx_dma_handler, NULL); + hal_uart_irq_set_mask(comm_uart, mask); + uart_opened = true; + } + + cancel_xfer = false; + + hal_uart_flush(comm_uart,0); +#ifdef KNOWLES_UART_DATA + if(recv_data(&audio_data_receive_buf[0], knowles_uart_packet_len*2) < 0) + TRACE(1,"%s error", __func__); + smart_mic_stream_header_parser_init(FRAME_SIZE); +#endif + + app_uart_flow_control_timeout_timer_id = osTimerCreate(osTimer(APP_UART_FLOW_CONTROL_TIMEOUT), osTimerOnce, NULL); + +} + + +void deinit_transport(void) +{ + union HAL_UART_IRQ_T mask; + + mask.reg = 0; + + //audio_dump_clear_up(); //added by punith + + hal_uart_stop_dma_recv(comm_uart);//punith + uart_dma_rx_state = UART_DMA_IDLE; + hal_uart_irq_set_mask(comm_uart, mask); + hal_uart_irq_set_dma_handler(comm_uart, NULL, NULL); + hal_uart_close(comm_uart); + + + hal_uart_flush(comm_uart,0); + uart_opened = false; + cancel_xfer = true; + + osTimerStop(app_uart_flow_control_timeout_timer_id); + if (osTimerDelete(app_uart_flow_control_timeout_timer_id) != osOK) + { + TRACE(0,"app_uart_flow_control_timeout_timer_id Failed !!!!"); + } + +} + + + + +void reinit_transport(void) +{ + union HAL_UART_IRQ_T mask; + struct HAL_UART_CFG_T comm_uart_cfg; + + uart_opened = false; + memcpy(&comm_uart_cfg, &uart_cfg, sizeof(comm_uart_cfg)); + hal_uart_open(comm_uart, &comm_uart_cfg); + mask.reg = 0; + mask.BE = 1; + mask.FE = 1; + mask.OE = 1; + mask.PE = 1; + hal_uart_irq_set_dma_handler(comm_uart, uart_rx_dma_handler, NULL); + hal_uart_irq_set_mask(comm_uart, mask); + uart_opened = true; + + cancel_xfer = false; + + hal_uart_flush(comm_uart,0); +} + +void set_send_timeout(uint32_t timeout) +{ + send_timeout = MS_TO_TICKS(timeout); +} + +int debug_read_enabled(void) +{ + return !!(hal_sw_bootmode_get() & HAL_SW_BOOTMODE_READ_ENABLED); +} + +int debug_write_enabled(void) +{ + return !!(hal_sw_bootmode_get() & HAL_SW_BOOTMODE_WRITE_ENABLED); +} + +static int uart_send_data(const unsigned char *buf, unsigned int len) +{ + uint32_t start; + uint32_t sent = 0; + + start = hal_sys_timer_get(); + while (sent < len) { + while (!cancel_xfer && !hal_uart_writable(comm_uart) && + hal_sys_timer_get() - start < send_timeout); + if (cancel_xfer) { + break; + } + if (hal_uart_writable(comm_uart)) { + hal_uart_putc(comm_uart, buf[sent++]); + } else { + break; + } + } + + if (sent != len) { + return 1; + } + + return 0; +} + +int send_data(const unsigned char *buf, unsigned int len) +{ + if (cancel_xfer) { + return -1; + } + + return uart_send_data(buf, len); +} + + +static struct HAL_DMA_DESC_T dma_desc[17] = {0}; + +static int uart_recv_data_dma(unsigned char *buf, unsigned int len, unsigned int expect) +{ + int ret; + union HAL_UART_IRQ_T mask; + + uint32_t desc_cnt = ARRAY_SIZE(dma_desc); + + if (uart_dma_rx_state != UART_DMA_IDLE) { + ret = -3; + goto _no_state_exit; + } + + uart_dma_rx_state = UART_DMA_START; + uart_dma_rx_size = 0; + +#ifdef KNOWLES_UART_DATA + ret = hal_uart_dma_recv_pingpang(comm_uart, buf, expect, &dma_desc[0], &desc_cnt); +#else + ret = hal_uart_dma_recv(comm_uart, buf, expect, &dma_desc[0], &desc_cnt); +#endif + + if (ret) { + uart_dma_rx_state = UART_DMA_ERROR; + goto err_exit; + } + + mask.reg = 0; + mask.BE = 1; + mask.FE = 1; + mask.OE = 1; + mask.PE = 1; + //mask.RT = 1; + hal_uart_irq_set_mask(comm_uart, mask); + +_no_state_exit: + TRACE(2,"%s ret %d", __func__, ret); + return ret; +err_exit: + TRACE(2,"%s err_exit ret %d", __func__, ret); + return -1; +} + +int recv_data(unsigned char *buf, unsigned int len) +{ + TRACE(3,"%s %d %d",__func__, cancel_xfer, len); + if (cancel_xfer) { + return -1; + } + return uart_recv_data_dma(buf, len, len); +} + +int recv_data_dma(unsigned char *buf, unsigned int len, unsigned int expect) +{ + if (cancel_xfer) { + return -1; + } + + return uart_recv_data_dma(buf, len, expect); +} + +static int uart_handle_error(void) +{ + TRACE(0,"****** Send break ******"); + + // Send break signal, to tell the peer to reset the connection + hal_uart_break_set(comm_uart); + osDelay(100); + hal_uart_break_clear(comm_uart); + + return 0; +} + +int handle_error(void) +{ + int ret = 0; + uint32_t err_time; + + osDelay(200); + + if (!cancel_xfer) { + ret = uart_handle_error(); + } + + xfer_err_cnt++; + err_time = hal_sys_timer_get(); + if (err_time - xfer_err_time > MS_TO_TICKS(5000)) { + xfer_err_cnt = 0; + } + xfer_err_time = err_time; + if (xfer_err_cnt < 2) { + osDelay(500); + } else if (xfer_err_cnt < 5) { + osDelay(1000); + } else { + osDelay(2000); + } + + return ret; +} + +static int uart_cancel_input(void) +{ + hal_uart_flush(comm_uart,0); + return 0; +} + +int cancel_input(void) +{ + return uart_cancel_input(); +} + +void system_reboot(void) +{ + hal_cmu_sys_reboot(); +} + +void system_shutdown(void) +{ + pmu_shutdown(); +} + +void system_set_bootmode(unsigned int bootmode) +{ + bootmode &= ~(HAL_SW_BOOTMODE_READ_ENABLED | HAL_SW_BOOTMODE_WRITE_ENABLED); + hal_sw_bootmode_set(bootmode); +} + +void system_clear_bootmode(unsigned int bootmode) +{ + bootmode &= ~(HAL_SW_BOOTMODE_READ_ENABLED | HAL_SW_BOOTMODE_WRITE_ENABLED); + hal_sw_bootmode_clear(bootmode); +} + +unsigned int system_get_bootmode(void) +{ + return hal_sw_bootmode_get(); +} + +void wait_trace_finished(void) +{ + uint32_t time; + int idle_cnt = 0; + + time = hal_sys_timer_get(); + + while (idle_cnt < 2 && hal_sys_timer_get() - time < WAIT_TRACE_TIMEOUT) { + osDelay(10); + idle_cnt = hal_trace_busy() ? 0 : (idle_cnt + 1); + } +} + +unsigned int get_current_time(void) +{ + return hal_sys_timer_get(); +} + +#ifdef KNOWLES_UART_DATA +uint8_t *uart_stream_buf; +bool send_start_speech = false; +extern bool is_markers_read_done; +#endif +#ifdef KNOWLES_UART_DATA +osThreadId knowles_uart_audio_tid = NULL; +static void uart_data_process_thread(const void *arg); +osThreadDef(uart_data_process_thread, (osPriorityAboveNormal), 1, (1024*12), "UART_DATA"); + +int app_ai_voice_uart_audio_init() +{ + ama_uart_stream_fifo_init(); + if(knowles_uart_audio_tid==NULL) + knowles_uart_audio_tid = osThreadCreate(osThread(uart_data_process_thread), NULL); + if (knowles_uart_audio_tid == NULL) { + TRACE(0,"[UART AUDIO]Create thread error\n"); + return -1; + } + + return 0; +} +void uart_data_process_thread(const void *arg) +{ + uint32_t ret = 0; + uint32_t frame_len=0; + //uint32_t stime,etime; + //stime=hal_sys_timer_get(); + + while(1) + { + //TRACE(0,"---in uart_process_thread\n"); + osEvent evt; + + if(avil_len_of_the_fifo()<=640){ + evt = osSignalWait(0x0, osWaitForever); + } + + //TRACE(1,"#####Available len of fifo %d####",avil_len_of_the_fifo()); + //get role from signal value + if(evt.status == osEventSignal) + { + if(evt.value.signals & UART_OUT_SIGNAL_ID) + { + if(app_ai_is_stream_running()) { + frame_len = ama_uart_get_fifo_data(uart_stream_buf); + } else { + frame_len = 0; + } + + if(frame_len != 0) { + TRACE(1,"--data start encode %d", frame_len); + //DUMP8("%02x ",uart_stream_buf,10); + + //stime=hal_sys_timer_get(); + + ret=voice_compression_handle(app_ai_get_encode_type(), uart_stream_buf, VOB_PCM_SIZE_TO_SAMPLE_CNT(640), app_ai_is_algorithm_engine_reset()); + app_ai_set_algorithm_engine_reset(false); + + ai_function_handle(API_DATA_SEND, NULL, 0); + + //etime=hal_sys_timer_get(); + //TRACE(1,"OPUS COST TIME %d", TICKS_TO_MS(etime-stime)); + //TRACE(2,"%s ====>sys freq calc : %d\n", __func__, hal_sys_timer_calc_cpu_freq(50, 0)); + audio_dump_add_channel_data(0, (short *)uart_stream_buf, frame_len/2); + audio_dump_run(); + send_message(); + if(ret < 0) { + goto __EXCEPTION; + } + } + } + } + + continue; + + __EXCEPTION: + app_ai_voice_stop_stream(); + } +} +#endif + diff --git a/services/communication/comminication_knowles/communication_sysapi.h b/services/communication/comminication_knowles/communication_sysapi.h new file mode 100644 index 0000000..89f9eee --- /dev/null +++ b/services/communication/comminication_knowles/communication_sysapi.h @@ -0,0 +1,92 @@ +#ifndef __COMMUNICATION_SYSAPI_H__ +#define __COMMUNICATION_SYSAPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 +#include "stdio.h" + +#define TRACE(str, ...) do { printf("%s/" str "\n", __FUNCTION__, __VA_ARGS__); } while (0) +#define ASSERT(cond, str, ...) \ + do { if (!(cond)) { printf("[ASSERT]%s/" str, __FUNCTION__, __VA_ARGS__); while (1); } } while (0) +#define TRACE_TIME(num,str, ...) TRACE(num,str, __VA_ARGS__) + +int write_sig_data(const unsigned char *data, unsigned int len); +int write_code_data(const unsigned char *data, unsigned int len); +void programmer_main(void); +#else +#include "hal_trace.h" +#include "hal_timer.h" + +#define TRACE_TIME(num,str, ...) TRACE(num+1,"[%05u] " str, TICKS_TO_MS(hal_sys_timer_get()), ##__VA_ARGS__) +#endif + +#define UART_OUT_SIGNAL_ID 0x19 +enum DOWNLOAD_TRANSPORT { + TRANSPORT_USB, + TRANSPORT_UART, +}; + +enum XFER_TIMEOUT { + XFER_TIMEOUT_SHORT, + XFER_TIMEOUT_MEDIUM, + XFER_TIMEOUT_LONG, + XFER_TIMEOUT_IDLE, + + XFER_TIMEOUT_QTY +}; + +enum UART_DMA_STATE { + UART_DMA_IDLE, + UART_DMA_START, + UART_DMA_DONE, + UART_DMA_ERROR, +}; + +void init_transport(void); +void deinit_transport(void); +void reinit_transport(void); +void set_send_timeout(uint32_t timeout); +int secure_settings_valid(void); +int secure_boot_enabled(void); +int usb_enabled(void); +int usb_connected(void); +unsigned short get_boot_security_value(void); +unsigned int get_boot_key_index(void); +int send_data(const unsigned char *buf, unsigned int len); +int recv_data(unsigned char *buf, unsigned int len); +int recv_data_dma(unsigned char *buf, unsigned int len, unsigned int expect); +void recv_data_state_get(enum UART_DMA_STATE *state); +void recv_data_reset(void); +int handle_error(void); +int cancel_input(void); + +int verify_signature(const unsigned char *key, const unsigned char *sig, const unsigned char *data, unsigned int len); + +int debug_read_enabled(void); +int debug_write_enabled(void); + +int get_flash_boot_flag(void); +void set_flash_boot_flag(int flag); +void system_reboot(void); +void system_shutdown(void); +void system_flash_boot(void); +void system_set_bootmode(unsigned int bootmode); +void system_clear_bootmode(unsigned int bootmode); +unsigned int system_get_bootmode(void); + +void wait_trace_finished(void); + +unsigned int get_current_time(void); +uint32_t ama_uart_get_fifo_data(uint8_t *buf); +uint32_t avil_len_of_the_fifo(); +void send_message(); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/communication/comminication_knowles/tool_msg.h b/services/communication/comminication_knowles/tool_msg.h new file mode 100644 index 0000000..a98d066 --- /dev/null +++ b/services/communication/comminication_knowles/tool_msg.h @@ -0,0 +1,185 @@ +#ifndef __TOOL_MSG_H__ +#define __TOOL_MSG_H__ + +#include "communication_cmd_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOOT_MAGIC_NUMBER 0xBE57EC1C +#define BOOT_HASH_TYPE_MD5 1 +#define BOOT_HASH_TYPE_SHA256 2 +#define BOOT_KEY_TYPE_RSA2048 1 +#define BOOT_KEY_TYPE_ECDSA192 2 +#define BOOT_KEY_TYPE_ECDSA256 3 + +#ifdef __PC_CMD_UART__ +#define PREFIX_CHAR 0x7b//{ +#else +#define PREFIX_CHAR 0xBE +#endif + +#define KEY_LEN (4 + 256 + 256) +#define SIG_LEN 256 + +#define BOOT_STRUCT_OFFSET_TO_SIGN(b) \ + ((unsigned char *)&((struct boot_struct_t *)(b))->hdr.security) +#define BOOT_STRUCT_LEN_TO_SIGN \ + ((unsigned int)&((struct boot_struct_t *)0)->sig[0] - \ + (unsigned int)&((struct boot_struct_t *)0)->hdr.security) + +#define SIG_MSG_OVERHEAD 8 +#define SIG_MSG_EXTRA_DATA_LEN (sizeof(struct boot_struct_t) + sizeof(struct code_sig_struct_t)) +#define SIG_MSG_TOTAL_LEN (SIG_MSG_OVERHEAD + SIG_MSG_EXTRA_DATA_LEN) + +#define CODE_MSG_OVERHEAD 8 +#define BURN_DATA_MSG_OVERHEAD 16 + +#define SECTOR_SIZE_64K (1 << 16) +#define SECTOR_SIZE_32K (1 << 15) +#define SECTOR_SIZE_16K (1 << 14) +#define SECTOR_SIZE_4K (1 << 12) + +#define MSG_TOTAL_LEN(msg) (sizeof((msg)->hdr) + (msg)->hdr.len + 1) + +enum MSG_TYPE { + TYPE_SYS = 0x00, + TYPE_READ = 0x01, + TYPE_WRITE = 0x02, + TYPE_BULK_READ = 0x03, + TYPE_SYNC = 0x50, + TYPE_SIG_INFO = 0x51, + TYPE_SIG = 0x52, + TYPE_CODE_INFO = 0x53, + TYPE_CODE = 0x54, + TYPE_RUN = 0x55, + TYPE_SECTOR_SIZE = 0x60, + TYPE_ERASE_BURN_START = 0x61, + TYPE_ERASE_BURN_DATA = 0x62, + TYPE_BURN_START = 0x63, + TYPE_BURN_DATA = 0x64, + TYPE_BURN_CMD = 0x65, + TYPE_GET_SECTOR_INFO = 0x66, +#if defined(__EXT_CMD_SUPPORT__) + TYPE_EXTEND_CMD = 0x67, +#endif + TYPE_COMMUNICATION_CMD = 0x68, +}; + +enum SYS_CMD_TYPE { + SYS_CMD_REBOOT = 0xF1, + SYS_CMD_SHUTDOWN = 0xF2, + SYS_CMD_FLASH_BOOT = 0xF3, + SYS_CMD_SET_BOOTMODE = 0xE1, + SYS_CMD_CLR_BOOTMODE = 0xE2, + SYS_CMD_GET_BOOTMODE = 0xE3, +}; + +enum ERR_CODE { + ERR_NONE = 0x00, + ERR_LEN = 0x01, + ERR_CHECKSUM = 0x02, + ERR_NOT_SYNC = 0x03, + ERR_NOT_SEC = 0x04, + ERR_SYNC_WORD = 0x05, + ERR_SYS_CMD = 0x06, + ERR_DATA_ADDR = 0x07, + ERR_DATA_LEN = 0x08, + ERR_ACCESS_RIGHT = 0x09, + + ERR_TYPE_INVALID = 0x0F, + + //ERR_BOOT_OK = 0x10, + ERR_BOOT_MAGIC = 0x11, + ERR_BOOT_SEC = 0x12, + ERR_BOOT_HASH_TYPE = 0x13, + ERR_BOOT_KEY_TYPE = 0x14, + ERR_BOOT_KEY_LEN = 0x15, + ERR_BOOT_SIG_LEN = 0x16, + ERR_BOOT_SIG = 0x17, + ERR_BOOT_CRC = 0x18, + ERR_BOOT_LEN = 0x19, + ERR_SIG_CODE_SIZE = 0x1A, + ERR_SIG_SIG_LEN = 0x1B, + ERR_SIG_INFO_MISSING = 0x1C, + + ERR_CODE_OK = 0x20, + ERR_BOOT_MISSING = 0x21, + ERR_CODE_SIZE_SIG = 0x22, + ERR_CODE_ADDR_SIZE = 0x23, + ERR_CODE_INFO_MISSING = 0x24, + ERR_CODE_CRC = 0x25, + ERR_CODE_SIG = 0x26, + + ERR_CODE_MISSING = 0x31, + + ERR_BURN_OK = 0x60, + ERR_SECTOR_SIZE = 0x61, + ERR_SECTOR_SEQ_OVERFLOW = 0x62, + ERR_BURN_INFO_MISSING = 0x63, + ERR_SECTOR_DATA_LEN = 0x64, + ERR_SECTOR_DATA_CRC = 0x65, + ERR_SECTOR_SEQ = 0x66, + ERR_ERASE_FLSH = 0x67, + ERR_BURN_FLSH = 0x68, + ERR_VERIFY_FLSH = 0x69, + ERR_BURN_CMD = 0x6A, + + ERR_TYPE_MISMATCHED = 0xE1, + ERR_SEQ_MISMATCHED = 0xE2, + ERR_BUF_TOO_SMALL = 0xE3, + + ERR_INTERNAL = 0xFF, +}; + +enum PARSE_STATE { + PARSE_HEADER, + PARSE_DATA, + PARSE_EXTRA, +}; + +struct message_t { + struct msg_hdr_t { + unsigned char prefix; + unsigned char type; + unsigned char seq; + unsigned char len; + } hdr; + unsigned char data[255]; +}; + +struct boot_struct_t { + struct boot_hdr_t { + unsigned int magic; + unsigned short security; + unsigned char hash_type; + unsigned char key_type; + unsigned short key_len; + unsigned short sig_len; + unsigned int build_info_start; + } hdr; + unsigned char key[KEY_LEN]; + unsigned char sig[SIG_LEN]; +}; + +struct code_sig_struct_t { + unsigned int code_size; + unsigned short sig_len; + unsigned short reserved; + unsigned char sig[SIG_LEN]; +}; + +struct exec_struct_t { + unsigned int entry; + unsigned int param; + unsigned int sp; + unsigned int reserved; +}; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/communication/communication_svr.cpp b/services/communication/communication_svr.cpp new file mode 100644 index 0000000..56176fc --- /dev/null +++ b/services/communication/communication_svr.cpp @@ -0,0 +1,600 @@ +#include "stdint.h" +#include "stdbool.h" +#include "plat_types.h" +#include "cmsis_os.h" +#include "cmsis_nvic.h" +#include "string.h" +#include "stdio.h" +#include "crc32.h" +#include "hal_trace.h" +#include "hal_iomux.h" +#include "hal_gpio.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_iomux.h" +#include "app_ai_if_config.h" +#include "communication_svr.h" +#include "communication_sysapi.h" + + +//====================================================================================================== + +enum COMMUNICATION_MSG { + COMMUNICATION_MSG_TX_REQ = 0, + COMMUNICATION_MSG_TX_DONE = 1, + COMMUNICATION_MSG_RX_REQ = 2, + COMMUNICATION_MSG_RX_DONE = 3, + COMMUNICATION_MSG_INIT = 4, + COMMUNICATION_MSG_REINIT = 5, + COMMUNICATION_MSG_RESET = 6, + COMMUNICATION_MSG_BREAK = 7, +}; + +const static uint8_t communication_process_log[8][26] = { + "COMMUNICATION_MSG_TX_REQ", + "COMMUNICATION_MSG_TX_DONE", + "COMMUNICATION_MSG_RX_REQ", + "COMMUNICATION_MSG_RX_DONE", + "COMMUNICATION_MSG_INIT", + "COMMUNICATION_MSG_REINIT", + "COMMUNICATION_MSG_RESET", + "COMMUNICATION_MSG_BREAK", +}; + +enum COMMUNICATION_MODE { + COMMUNICATION_MODE_NULL, + COMMUNICATION_MODE_TX, + COMMUNICATION_MODE_RX, + COMMUNICATION_MODE_ENABLE_IRQ, + COMMUNICATION_MODE_DISABLE_IRQ, +}; + + +#define COMMAND_BLOCK_MAX (5) +#define COMMAND_LEN_MAX (128) +#define COMMAND_TRANSMITTED_SIGNAL (1<<0) + +typedef struct { + uint8_t cmd_buf[COMMAND_LEN_MAX]; + uint8_t cmd_len; +} COMMAND_BLOCK; +osPoolDef (command_mempool, COMMAND_BLOCK_MAX, COMMAND_BLOCK); +osPoolId command_mempool = NULL; + + +#define COMMUNICATION_MAILBOX_MAX (10) +typedef struct { + uint32_t src_thread; + uint32_t system_time; + uint32_t message; + uint32_t parms1; + uint32_t parms2; +} COMMUNICATION_MAIL; + +osMailQDef (communication_mailbox, COMMUNICATION_MAILBOX_MAX, COMMUNICATION_MAIL); +static osMailQId communication_mailbox = NULL; +static uint8_t communication_mailbox_cnt = 0; + + +static osThreadId communication_tid = NULL; +static void communication_thread(void const *argument); +osThreadDef(communication_thread, osPriorityHigh, 1, 2048, "communication_server"); + +static bool uart_opened = false; +static int uart_error_detected = 0; + +#if defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) +static const enum HAL_UART_ID_T comm_uart = HAL_UART_ID_2; +#else +static const enum HAL_UART_ID_T comm_uart = HAL_UART_ID_1; +#endif + +static const struct HAL_UART_CFG_T uart_cfg = { + HAL_UART_PARITY_NONE, + HAL_UART_STOP_BITS_1, + HAL_UART_DATA_BITS_8, + HAL_UART_FLOW_CONTROL_NONE, + HAL_UART_FIFO_LEVEL_1_2, + HAL_UART_FIFO_LEVEL_1_2, +#if defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) + 1152000, +#else + 921600, +#endif + true, + true, + false, +}; + +static bool uart_rx_dma_is_running = false; + +static COMMAND_BLOCK *rx_command_block_p = NULL; + +static uint32_t uart_rx_idle_counter = 0; +static void uart_rx_idle_handler(void const *param); +osTimerDef(uart_rx_idle_timer, uart_rx_idle_handler); +static osTimerId uart_rx_idle_timer_id = NULL; + + +static communication_receive_func_typedef communication_receive_cb = NULL; + + +const static struct HAL_IOMUX_PIN_FUNCTION_MAP cfg_led2 = { + HAL_IOMUX_PIN_LED2, HAL_IOMUX_FUNC_GPIO, HAL_IOMUX_PIN_VOLTAGE_VBAT, HAL_IOMUX_PIN_PULLUP_ENABLE, +}; + + +inline int communication_mailbox_put(COMMUNICATION_MAIL* msg_src); +static void communication_process(COMMUNICATION_MAIL* mail_p); +int communication_io_mode_switch(enum COMMUNICATION_MODE mode); + + +static void uart_rx_dma_stop(void) +{ + union HAL_UART_IRQ_T mask; + + uint32_t lock = int_lock(); +// TRACE(1,"uart_rx_dma_stop:%d", uart_rx_dma_is_running); + if (uart_rx_dma_is_running){ + mask.reg = 0; + hal_uart_irq_set_mask(comm_uart, mask); + hal_uart_stop_dma_recv(comm_uart); + uart_rx_dma_is_running = false; + } + + int_unlock(lock); +} + +static void uart_rx_dma_start(void) +{ + union HAL_UART_IRQ_T mask; + + uint32_t lock = int_lock(); + +// TRACE(1,"uart_rx_dma_start:%d", uart_rx_dma_is_running); + + hal_uart_flush(comm_uart, 0); + //hal_uart_dma_recv(comm_uart, rx_command_block_p->cmd_buf, COMMAND_LEN_MAX, NULL, NULL); + mask.reg = 0; + mask.RT = 1; + //hal_uart_irq_set_mask(comm_uart, mask); + hal_uart_dma_recv_mask(comm_uart, rx_command_block_p->cmd_buf, COMMAND_LEN_MAX, NULL, NULL,&mask); + + uart_rx_dma_is_running = true; + + int_unlock(lock); +} + +static void uart_break_handler(void) +{ + union HAL_UART_IRQ_T mask; + COMMUNICATION_MAIL msg; + memset(&msg, 0, sizeof(msg)); + + TRACE(0,"UART-BREAK"); + mask.reg = 0; + hal_uart_irq_set_mask(comm_uart, mask); + hal_uart_flush(comm_uart, 0); + uart_error_detected = 1; + msg.message = COMMUNICATION_MSG_BREAK; + communication_mailbox_put(&msg); +} + +static void uart_rx_dma_handler(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status) +{ + COMMUNICATION_MAIL msg; + + //TRACE(8,"UART-RX size:%d dma_error=%d, status=0x%08x rt:%d fe:%d pe:%d be:%d oe:%d", xfer_size, dma_error, status, status.RT, status.FE, status.PE, status.BE, status.OE); + + if (status.BE) { + uart_break_handler(); + return; + } + + memset(&msg, 0, sizeof(COMMUNICATION_MAIL)); + msg.message = COMMUNICATION_MSG_RX_DONE; + + if (dma_error || status.FE|| status.PE || status.BE || status.OE ) { + uart_error_detected = 1; + uart_rx_dma_stop(); + msg.parms1 = false; + msg.message = COMMUNICATION_MSG_RESET; + communication_mailbox_put(&msg); + }else{ + if (xfer_size){ + msg.parms1 = true; + msg.parms2 = xfer_size; + communication_mailbox_put(&msg); + }else{ + uart_rx_dma_stop(); + msg.message = COMMUNICATION_MSG_RESET; + communication_mailbox_put(&msg); + } + } +} + +static void uart_tx_dma_handler(uint32_t xfer_size, int dma_error) +{ + COMMUNICATION_MAIL msg; + + memset(&msg, 0, sizeof(COMMUNICATION_MAIL)); + +// TRACE(2,"UART-TX size:%d dma_error=%d", xfer_size, dma_error); + + osSignalSet(communication_tid, COMMAND_TRANSMITTED_SIGNAL); + + msg.message = COMMUNICATION_MSG_TX_DONE; + + communication_mailbox_put(&msg); +} + +static void uart_init(void) +{ + struct HAL_UART_CFG_T comm_uart_cfg; + + if (!uart_opened) { + memcpy(&comm_uart_cfg, &uart_cfg, sizeof(comm_uart_cfg)); + hal_uart_open(comm_uart, &comm_uart_cfg); + hal_uart_irq_set_dma_handler(comm_uart, uart_rx_dma_handler, uart_tx_dma_handler); + uart_opened = true; + } + + hal_uart_flush(comm_uart, 0); +} + +static void uart_deinit(void) +{ + if (uart_opened) { + hal_uart_close(comm_uart); + uart_opened = false; + } +} + +static void uart_rx_idle_timer_start(void) +{ + uart_rx_idle_counter = 0; + TRACE(1,"[%s] enter...", __func__); + + if (uart_rx_idle_timer_id != NULL) { + osTimerStop(uart_rx_idle_timer_id); + osTimerStart(uart_rx_idle_timer_id, 100); + } +} + +#if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) +static void uart_rx_edge_detect_handler(enum HAL_GPIO_PIN_T pin) +{ + COMMUNICATION_MAIL msg = {0}; + + //disable led2 pin external interrupt mode... + communication_io_mode_switch(COMMUNICATION_MODE_DISABLE_IRQ); + + //post uart rx request... + msg.message = COMMUNICATION_MSG_RX_REQ; + communication_mailbox_put(&msg); +} +#endif + +static void uart_rx_idle_handler(void const *param) +{ + const uint8_t rx_idle_indicate[2] = {0x10,0x24}; + + if(uart_rx_idle_counter++ >= 150)//150 * 100 = 15s + { + TRACE(1,"[%s] enter...", __func__); + + uart_rx_idle_counter = 0; + + //stop virtual timer... + osTimerStop(uart_rx_idle_timer_id); + + //stop uart rx dma... + uart_rx_dma_stop(); + + //notify charge box uart rx dma has closed... + communication_io_mode_switch(COMMUNICATION_MODE_TX); + hal_uart_dma_send(comm_uart, rx_idle_indicate, 2, NULL, NULL); + osDelay(10); + + //config led2 pin as external interrupt mode... + communication_io_mode_switch(COMMUNICATION_MODE_ENABLE_IRQ); + } +} + + +int communication_io_mode_switch(enum COMMUNICATION_MODE mode) +{ + //best1400 and best1402 platform + switch (mode) + { + case COMMUNICATION_MODE_TX: { + #if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) + hal_iomux_single_wire_uart1_tx(); + #endif + } + break; + case COMMUNICATION_MODE_RX: { + #if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) + hal_iomux_single_wire_uart1_rx(); + #endif + } + break; + case COMMUNICATION_MODE_ENABLE_IRQ: { + #if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) + hal_iomux_single_wire_uart1_enable_irq(uart_rx_edge_detect_handler); + #endif + } + break; + case COMMUNICATION_MODE_DISABLE_IRQ: { + #if defined(CHIP_BEST1400) || defined(CHIP_BEST1402) + hal_iomux_single_wire_uart1_disable_irq(); + #endif + } + break; + default:break; + } + return 0; +} + +int communication_io_mode_init(void) +{ + communication_io_mode_switch(COMMUNICATION_MODE_RX); + + return 0; +} + +inline int communication_mailbox_put(COMMUNICATION_MAIL* msg_src) +{ + osStatus status; + + COMMUNICATION_MAIL *mail_p = NULL; + + if (msg_src == NULL) + { + return -1; + } + + mail_p = (COMMUNICATION_MAIL*)osMailAlloc(communication_mailbox, 0); + if (!mail_p){ + osEvent evt; + TRACE(0,"communication_mailbox"); + for (uint8_t i=0; imessage, + ((COMMUNICATION_MAIL *)(evt.value.p))->parms1, + ((COMMUNICATION_MAIL *)(evt.value.p))->parms2); + }else{ + break; + } + } + ASSERT(mail_p, "communication_mailbox error"); + } + mail_p->src_thread = (uint32_t)osThreadGetId(); + mail_p->system_time = hal_sys_timer_get(); + mail_p->message = msg_src->message; + mail_p->parms1 = msg_src->parms1; + mail_p->parms2 = msg_src->parms2; + status = osMailPut(communication_mailbox, mail_p); + if (osOK == status){ + communication_mailbox_cnt++; + } + + return (int)status; +} + +inline int communication_mailbox_free(COMMUNICATION_MAIL* mail_p) +{ + osStatus status; + + status = osMailFree(communication_mailbox, mail_p); + if (osOK == status){ + communication_mailbox_cnt--; + } + return (int)status; +} + +inline int communication_mailbox_get(COMMUNICATION_MAIL** mail_p) +{ + osEvent evt; + evt = osMailGet(communication_mailbox, osWaitForever); + if (evt.status == osEventMail) { + *mail_p = (COMMUNICATION_MAIL *)evt.value.p; + return 0; + } + return -1; +} + +static void communication_thread(void const *argument) +{ + while(1){ + COMMUNICATION_MAIL *mail_p = NULL; + if (!communication_mailbox_get(&mail_p)){ + communication_process(mail_p); + communication_mailbox_free(mail_p); + } + } +} + +int communication_command_block_alloc(COMMAND_BLOCK **cmd_blk) +{ + *cmd_blk = (COMMAND_BLOCK *)osPoolCAlloc (command_mempool); + ASSERT(*cmd_blk, "%s error", __func__); + return 0; +} + +void communication_command_block_free(COMMAND_BLOCK *cmd_blk) +{ + osPoolFree(command_mempool, cmd_blk); +} + +void communication_send_command(COMMAND_BLOCK *cmd_blk) +{ + COMMUNICATION_MAIL mail; + memset(&mail, 0, sizeof(mail)); + ASSERT(cmd_blk->cmd_len <=COMMAND_LEN_MAX, "%s len error", __func__); + mail.message = COMMUNICATION_MSG_TX_REQ; + mail.parms2 = (uint32_t)cmd_blk; + communication_mailbox_put(&mail); +} + +static void communication_process(COMMUNICATION_MAIL* mail_p) +{ + osEvent evt; + COMMAND_BLOCK *command_block_p; + COMMUNICATION_MAIL msg; + uint32_t lock; + + TRACE(2,"[%s]: %s", __func__, communication_process_log[mail_p->message]); + + memset(&msg, 0, sizeof(COMMUNICATION_MAIL)); + switch (mail_p->message) { + case COMMUNICATION_MSG_TX_REQ: + command_block_p = (COMMAND_BLOCK *)mail_p->parms2; + TRACE(1,"UART TX:%d", command_block_p->cmd_len); + DUMP8("%02x ", command_block_p->cmd_buf, command_block_p->cmd_len); + uart_rx_dma_stop(); + communication_io_mode_switch(COMMUNICATION_MODE_TX); + osSignalClear(communication_tid, COMMAND_TRANSMITTED_SIGNAL); + hal_uart_dma_send(comm_uart, command_block_p->cmd_buf, command_block_p->cmd_len, NULL, NULL); + evt = osSignalWait(COMMAND_TRANSMITTED_SIGNAL, 1000); + if (evt.status== osEventTimeout){ + ASSERT(0, "%s osEventTimeout", __func__); + } + communication_command_block_free(command_block_p); + while (!hal_uart_get_flag(comm_uart).TXFE || hal_uart_get_flag(comm_uart).BUSY){ + osThreadYield(); + } + communication_io_mode_switch(COMMUNICATION_MODE_RX); + if (!uart_error_detected){ + uart_rx_dma_start(); + uart_rx_idle_timer_start(); + } + break; + case COMMUNICATION_MSG_TX_DONE: + break; + case COMMUNICATION_MSG_RX_REQ: + communication_io_mode_init(); + uart_init(); + uart_rx_dma_start(); + uart_rx_idle_timer_start(); + break; + case COMMUNICATION_MSG_RX_DONE: + TRACE(2,"UART RX status:%d len:%d", mail_p->parms1, mail_p->parms2); + DUMP8("%02x ", rx_command_block_p->cmd_buf, mail_p->parms2); + TRACE(1,"%s", rx_command_block_p->cmd_buf); + + if(communication_receive_cb != NULL) + (*communication_receive_cb)(rx_command_block_p->cmd_buf, mail_p->parms2); + + memset(rx_command_block_p->cmd_buf, 0, mail_p->parms2); + + if (!uart_error_detected){ + uart_rx_dma_start(); + uart_rx_idle_timer_start(); + } + break; + case COMMUNICATION_MSG_REINIT: + uart_deinit(); + case COMMUNICATION_MSG_INIT: + uart_error_detected = 0; + communication_io_mode_init(); + uart_init(); + uart_rx_dma_start(); + uart_rx_idle_timer_id = osTimerCreate(osTimer(uart_rx_idle_timer), osTimerPeriodic, NULL); + uart_rx_idle_timer_start(); + break; + case COMMUNICATION_MSG_RESET: + case COMMUNICATION_MSG_BREAK: + lock = int_lock(); + uart_rx_dma_stop(); + communication_io_mode_switch(COMMUNICATION_MODE_RX); + hal_uart_flush(comm_uart, 0); + uart_rx_dma_start(); + uart_error_detected = 0; + int_unlock(lock); + uart_rx_idle_timer_start(); + break; + + default: + break; + } + +} + +void communication_init(void) +{ + COMMUNICATION_MAIL msg; + COMMAND_BLOCK *cmd_blk; + + memset(&msg, 0, sizeof(COMMUNICATION_MAIL)); + TRACE(1,"%s", __func__); + + if (command_mempool == NULL){ + command_mempool = osPoolCreate(osPool(command_mempool)); + } + + if (communication_mailbox == NULL){ + communication_mailbox = osMailCreate(osMailQ(communication_mailbox), NULL); + } + + if (communication_tid == NULL){ + communication_tid = osThreadCreate(osThread(communication_thread), NULL); + } + + if (rx_command_block_p == NULL){ + communication_command_block_alloc(&rx_command_block_p); + memset(rx_command_block_p->cmd_buf, 0, COMMAND_LEN_MAX); + rx_command_block_p->cmd_len = 0; + } + + msg.message = COMMUNICATION_MSG_INIT; + communication_mailbox_put(&msg); + + communication_command_block_alloc(&cmd_blk); + cmd_blk->cmd_buf[0] = 0xff; + cmd_blk->cmd_len = 1; + communication_send_command(cmd_blk); +} + +int communication_receive_register_callback(communication_receive_func_typedef p) +{ + if(p == NULL) + return -1; + + communication_receive_cb = p; + + TRACE(1,"[%s] register receive callback success\n", __func__); + + return 0; +} + +int communication_send_buf(uint8_t * buf, uint8_t len) +{ + COMMAND_BLOCK *cmd_blk; + + communication_command_block_alloc(&cmd_blk); + memcpy(cmd_blk->cmd_buf, buf, len); + cmd_blk->cmd_len = len; + communication_send_command(cmd_blk); + return 0; +} + +#ifdef KNOWLES_UART_DATA +#include "knowles_uart.h" + +void uart_audio_init() +{ + TRACE(1,"%s run!!!", __func__); + init_transport(); +} + +void uart_audio_deinit() +{ + deinit_transport(); + reopen_uart(); +} + +#endif + diff --git a/services/communication/communication_svr.h b/services/communication/communication_svr.h new file mode 100644 index 0000000..759ce78 --- /dev/null +++ b/services/communication/communication_svr.h @@ -0,0 +1,27 @@ +#ifndef __COMMUNICATION_SVR_H__ +#define __COMMUNICATION_SVR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef void (*communication_receive_func_typedef)(uint8_t *buf, uint8_t len); + +void communication_init(void); +int communication_receive_register_callback(communication_receive_func_typedef p); +int communication_send_buf(uint8_t * buf, uint8_t len); + + +#ifdef KNOWLES_UART_DATA +void uart_audio_init(); +void uart_audio_deinit(); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/cp_accel/Makefile b/services/cp_accel/Makefile new file mode 100644 index 0000000..23dd659 --- /dev/null +++ b/services/cp_accel/Makefile @@ -0,0 +1,15 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y += -Iapps/common -Iutils/cqueue + +ifeq ($(CP_ACCEL_DEBUG),1) +ccflags-y += -DCP_ACCEL_DEBUG +endif + diff --git a/services/cp_accel/cp_accel.c b/services/cp_accel/cp_accel.c new file mode 100644 index 0000000..0c07f9c --- /dev/null +++ b/services/cp_accel/cp_accel.c @@ -0,0 +1,418 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CHIP_HAS_CP + +#include "cp_accel.h" +#include "cmsis.h" +#include "cmsis_os.h" +#include "hal_cmu.h" +#include "hal_location.h" +#include "hal_mcu2cp.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "mpu.h" +#include "stdarg.h" +#include "system_cp.h" +#include "hal_memsc.h" +#include "string.h" +#include "app_utils.h" + +#ifdef CP_ACCEL_DEBUG +#define CP_ACCEL_TRACE(s, ...) TRACE(s, ##__VA_ARGS__) +#else +#define CP_ACCEL_TRACE(s, ...) +#endif + +#define CP_NO_FLASH_ACCESS + +#define CP_CRASH_START_TIMEOUT MS_TO_TICKS(100) +#define CP_TRACE_FLUSH_TIMEOUT MS_TO_TICKS(200) +#define CP_CRASH_DUMP_TIMEOUT MS_TO_TICKS(500) +#define CP_TRACE_BUF_FULL_INTVL MS_TO_TICKS(50) + +enum CP_SYS_EVENT_T { + CP_SYS_EVENT_NONE = 0, + CP_SYS_EVENT_CRASH_START, + CP_SYS_EVENT_CRASH_END, + CP_SYS_EVENT_TRACE_FLUSH, + CP_SYS_EVENT_TRACE_BUF_FULL, +}; + +static bool ram_inited; +static bool cp_accel_inited = false; +static struct cp_task_env_tag cp_task_env; +static CP_BSS_LOC volatile struct cp_env_tag cp_env; + +static CP_BSS_LOC volatile enum CP_SYS_EVENT_T cp_sys_evt; +static CP_BSS_LOC bool cp_in_crash; +static CP_BSS_LOC volatile uint8_t cp_in_sleep; +static CP_BSS_LOC uint32_t cp_buf_full_time; +static CP_BSS_LOC uint8_t req_event = 0, pending_event = 0; + +static CP_TEXT_SRAM_LOC int send_sys_ctrl_cp2mcu(uint32_t event) +{ + return hal_mcu2cp_send_cp(HAL_MCU2CP_ID_1, HAL_MCU2CP_MSG_TYPE_0, (unsigned char *)event, 0); +} + +static CP_TEXT_SRAM_LOC void cp_trace_crash_notify(enum HAL_TRACE_STATE_T state) +{ + uint32_t time; + + if (state == HAL_TRACE_STATE_CRASH_ASSERT_START || state == HAL_TRACE_STATE_CRASH_FAULT_START) { + cp_in_crash = true; + cp_sys_evt = CP_SYS_EVENT_CRASH_START; + mpu_close(); + send_sys_ctrl_cp2mcu(0); + + time = hal_sys_timer_get(); + while (cp_sys_evt == CP_SYS_EVENT_CRASH_START && + hal_sys_timer_get() - time < CP_CRASH_START_TIMEOUT); + } else { + cp_sys_evt = CP_SYS_EVENT_CRASH_END; + } +} + +static CP_TEXT_SRAM_LOC void cp_trace_buffer_ctrl(enum HAL_TRACE_BUF_STATE_T buf_state) +{ + uint32_t time; + + if (cp_sys_evt != CP_SYS_EVENT_NONE) { + return; + } + + time = hal_sys_timer_get(); + + if (buf_state == HAL_TRACE_BUF_STATE_FLUSH) { + cp_sys_evt = CP_SYS_EVENT_TRACE_FLUSH; + if (!cp_in_crash) { + send_sys_ctrl_cp2mcu(0); + } + + while (cp_sys_evt == CP_SYS_EVENT_TRACE_FLUSH && + hal_sys_timer_get() - time < CP_TRACE_FLUSH_TIMEOUT); + } else if (buf_state == HAL_TRACE_BUF_STATE_FULL || buf_state == HAL_TRACE_BUF_STATE_NEAR_FULL) { + if (time - cp_buf_full_time >= CP_TRACE_BUF_FULL_INTVL) { + cp_buf_full_time = time; + if (!cp_in_crash) { + cp_sys_evt = CP_SYS_EVENT_TRACE_BUF_FULL; + send_sys_ctrl_cp2mcu(0); + } + } + } +} + +static SRAM_TEXT_LOC unsigned int cp2mcu_sys_arrived(const unsigned char *data, unsigned int len) +{ + uint32_t time; + uint8_t task_id = 0; + + if (cp_sys_evt == CP_SYS_EVENT_TRACE_FLUSH) { + TRACE_FLUSH(); + cp_sys_evt = CP_SYS_EVENT_NONE; + } else if (cp_sys_evt == CP_SYS_EVENT_TRACE_BUF_FULL) { + TRACE(0," "); + cp_sys_evt = CP_SYS_EVENT_NONE; + } else if (cp_sys_evt == CP_SYS_EVENT_CRASH_START) { + cp_sys_evt = CP_SYS_EVENT_NONE; + + TRACE(0," "); + TRACE(0,"CP Crash starts ..."); + UNLOCK_CP_PROCESS(); //Forced release lock + + // Wait CP crash dump finishes in interrupt context + time = hal_sys_timer_get(); + while (cp_sys_evt != CP_SYS_EVENT_CRASH_END && + hal_sys_timer_get() - time < CP_CRASH_DUMP_TIMEOUT) { + if (cp_sys_evt == CP_SYS_EVENT_TRACE_FLUSH) { + TRACE_FLUSH(); + cp_sys_evt = CP_SYS_EVENT_NONE; + } + } + + for (task_id=0; task_id 1) { + cp_env.mcu2cp_tx_count--; + pending_event = cp_env.mcu2cp_tx_pending[0]; + hal_mcu2cp_send_mcu(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0, &pending_event, 1); + + for (uint8_t index = 0;index < cp_env.mcu2cp_tx_count-1;index++) { + cp_env.mcu2cp_tx_pending[index] = cp_env.mcu2cp_tx_pending[index+1]; + } + } else { + cp_env.mcu2cp_tx_count = 0; + } +} + +#if defined(__ARM_ARCH_8M_MAIN__) + +#define CP_CODE_MAP_BASE (ROM_BASE + 0x800) +#define CP_CODE_MAP_SIZE (RAMX_BASE + RAM_TOTAL_SIZE - CP_CODE_MAP_BASE) + +static CP_DATA_LOC const mpu_regions_t mpu_table_cp[] = { + {CP_CODE_MAP_BASE, CP_CODE_MAP_SIZE, MPU_ATTR_EXEC, MAIR_ATTR_INT_SRAM}, + {RAM_BASE, RAM_TOTAL_SIZE, MPU_ATTR_READ_WRITE, MAIR_ATTR_INT_SRAM}, + {CMU_BASE, 0x01000000, MPU_ATTR_READ_WRITE, MAIR_ATTR_DEVICE}, +}; +#else +static CP_DATA_LOC const mpu_regions_t mpu_table_cp[] = { + {0, 0x800, MPU_ATTR_NO_ACCESS}, + {FLASHX_BASE, 0x4000000, MPU_ATTR_NO_ACCESS}, + {FLASH_BASE, 0x4000000, MPU_ATTR_NO_ACCESS}, + {FLASH_NC_BASE, 0x4000000, MPU_ATTR_NO_ACCESS}, +}; +#endif + +static CP_TEXT_SRAM_LOC NOINLINE void accel_loop(void) +{ + uint32_t lock; + uint8_t task_index = 0, event_index = 0; + bool msg_flag = false; + uint8_t msg[CP_TASK_MAX][CP_EVENT_MAX]; + + mpu_setup_cp(mpu_table_cp, ARRAY_SIZE(mpu_table_cp)); + + while (1) { + lock = int_lock_global(); + msg_flag = cp_env.cp_msg_recv; + cp_env.cp_msg_recv = false; + memcpy(msg, (uint8_t *)cp_env.cp_msg, sizeof(cp_env.cp_msg)); + memset((uint8_t *)cp_env.cp_msg, 0, sizeof(cp_env.cp_msg)); + if (false == msg_flag) { + cp_in_sleep = true; + __WFI(); + cp_in_sleep = false; + } + int_unlock_global(lock); + + if (msg_flag) { + for (task_index = 0;task_index < CP_TASK_MAX;task_index++) { + for (event_index = 0;event_index < CP_EVENT_MAX;event_index++) { + LOCK_CP_PROCESS(); + if ((msg[task_index][event_index]) && (cp_task_env.p_desc[task_index].cp_work_main)) { + cp_task_env.p_desc[task_index].cp_work_main(event_index); + } + UNLOCK_CP_PROCESS(); + } + } + } + } +} + +static void accel_main(void) +{ + system_cp_init(!ram_inited); + TRACE(1, "%s", __func__); + + ram_inited = true; + + memset((uint8_t *)&cp_env, 0, sizeof(cp_env)); + + hal_trace_open_cp(); + + hal_mcu2cp_open_cp(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0, mcu2cp_msg_arrived, NULL, false); + hal_mcu2cp_open_cp(HAL_MCU2CP_ID_1, HAL_MCU2CP_MSG_TYPE_0, NULL, NULL, false); + + hal_mcu2cp_start_recv_cp(HAL_MCU2CP_ID_0); + //hal_mcu2cp_start_recv_cp(HAL_MCU2CP_ID_1); + + cp_accel_inited = true; + + accel_loop(); +} + +static SRAM_TEXT_LOC unsigned int cp2mcu_msg_arrived(const unsigned char *data, unsigned int len) +{ + uint8_t task_id = CP_TASK_ID_GET((uint32_t)data); + // TRACE(2, "%s, task_id = %d", __func__, task_id); + + if (task_id >= CP_TASK_MAX) { + return -1; + } + + if (cp_task_env.p_desc[task_id].mcu_evt_hdlr) { + cp_task_env.p_desc[task_id].mcu_evt_hdlr((uint32_t)data); + } + + return len; +} + +int cp_accel_open(enum CP_TASK_TYPE task_id, struct cp_task_desc const * p_task_desc) +{ + TRACE(4, "%s, task id = %d, cp_state = %d init %d", __func__, task_id, cp_task_env.p_desc[task_id].cp_accel_state, cp_accel_inited); + + if ((task_id >= CP_TASK_MAX) || (p_task_desc == NULL)) { + TRACE(1, "%s task id error", __func__); + return -1; + } + + if (cp_task_env.p_desc[task_id].cp_accel_state != CP_ACCEL_STATE_CLOSED) { + TRACE(1, "%s cp_accel_state error", __func__); + return -1; + } + + cp_task_env.p_desc[task_id].cp_accel_state = CP_ACCEL_STATE_OPENING; + cp_task_env.p_desc[task_id].cp_work_main = p_task_desc->cp_work_main; + cp_task_env.p_desc[task_id].cp_evt_hdlr = p_task_desc->cp_evt_hdlr; + cp_task_env.p_desc[task_id].mcu_evt_hdlr = p_task_desc->mcu_evt_hdlr; + cp_task_env.p_desc[task_id].mcu_sys_ctrl_hdlr = p_task_desc->mcu_sys_ctrl_hdlr; + + if (false == cp_accel_inited) { + hal_trace_cp_register(cp_trace_crash_notify, cp_trace_buffer_ctrl); + + hal_cmu_cp_enable(RAMCP_BASE + RAMCP_SIZE, (uint32_t)accel_main); + + hal_mcu2cp_open_mcu(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0, cp2mcu_msg_arrived, mcu2cp_msg_sent, false); + hal_mcu2cp_open_mcu(HAL_MCU2CP_ID_1, HAL_MCU2CP_MSG_TYPE_0, cp2mcu_sys_arrived, NULL, false); + + hal_mcu2cp_start_recv_mcu(HAL_MCU2CP_ID_0); + hal_mcu2cp_start_recv_mcu(HAL_MCU2CP_ID_1); + } + cp_task_env.p_desc[task_id].cp_accel_state = CP_ACCEL_STATE_OPENED; + + return 0; +} + +int cp_accel_close(enum CP_TASK_TYPE task_id) +{ + uint8_t i = 0; + + TRACE(4, "%s, task id = %d, cp_state = %d init %d", __func__, + task_id, cp_task_env.p_desc[task_id].cp_accel_state, cp_accel_inited); + LOCK_CP_PROCESS(); // avoid hangup + + if (cp_task_env.p_desc[task_id].cp_accel_state == CP_ACCEL_STATE_CLOSED) { + goto accel_close_end; + } + + cp_task_env.p_desc[task_id].cp_accel_state = CP_ACCEL_STATE_CLOSING; + cp_task_env.p_desc[task_id].cp_work_main = NULL; + cp_task_env.p_desc[task_id].cp_evt_hdlr = NULL; + cp_task_env.p_desc[task_id].mcu_evt_hdlr = NULL; + + for (i=0; i MAX_CP_MSG_NUM)) { + TRACE(2, + "send_evt error, cp_accel_inited = %d, event pending count = %d", + cp_accel_inited, + cp_env.mcu2cp_tx_count); + + TRACE(2, + "send evt task_id = %d, event = %d", + CP_TASK_ID_GET(event), + CP_EVENT_GET(event)); + return -1; + } + + // TRACE(1, "current CP tx count:%d", cp_env.mcu2cp_tx_count); + if (cp_env.mcu2cp_tx_count > 0) { + cp_env.mcu2cp_tx_pending[cp_env.mcu2cp_tx_count - 1] = event; + cp_env.mcu2cp_tx_count++; + } else { + req_event = event; + cp_env.mcu2cp_tx_count = 1; + hal_mcu2cp_send_mcu(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0, &req_event, 1); + } + + return 0; +} + +int CP_TEXT_SRAM_LOC cp_accel_send_event_cp2mcu(uint8_t event) +{ + return hal_mcu2cp_send_cp(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0, (unsigned char *)(uint32_t)event, 0); +} + +int SRAM_TEXT_LOC cp_accel_busy(enum CP_TASK_TYPE task_id) +{ + if (cp_task_env.p_desc[task_id].cp_accel_state != CP_ACCEL_STATE_CLOSED) { + if (cp_task_env.p_desc[task_id].cp_accel_state == CP_ACCEL_STATE_OPENED && cp_in_sleep && + !hal_mcu2cp_local_irq_pending_cp(HAL_MCU2CP_ID_0)) { + return false; + } + return true; + } + + return false; +} + +#endif + diff --git a/services/cp_accel/cp_accel.h b/services/cp_accel/cp_accel.h new file mode 100644 index 0000000..78c261f --- /dev/null +++ b/services/cp_accel/cp_accel.h @@ -0,0 +1,131 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __CP_ACCEL_H__ +#define __CP_ACCEL_H__ + +#include "plat_types.h" +#include "hal_location.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_CP_MSG_NUM 5 + +#define HAL_MEMSC_ID_CP HAL_MEMSC_ID_1 + +#define LOCK_CP_PROCESS() \ + while (hal_memsc_lock(HAL_MEMSC_ID_CP) == 0){} + +#define UNLOCK_CP_PROCESS() \ + hal_memsc_unlock(HAL_MEMSC_ID_CP); + +typedef unsigned int (*CP_ACCEL_CP_MAIN)(uint8_t event); + +typedef unsigned int (*CP_ACCEL_EVT_HDLR)(uint8_t event); + +/// Tasks types definition +enum CP_TASK_EVENT +{ + CP_EVENT_A2DP_DECODE = 0x00, + + CP_EVENT_SCO_PROCESSING = 0x00, + + CP_EVENT_AEC_PROCESSING = 0x0, + CP_EVENT_AEC_RESAMPLING_PROCESSING = 0x1, + + CP_EVENT_HW_PROCESSING = 0x0, + + /// Maximum number of event + CP_EVENT_MAX = 0x2, +}; + +enum MCU_TASK_EVENT +{ + MCU_EVENT_HW_DETECTED = 0, + MCU_EVENT_HW_NEW_DATA_AVAILABLE = 1, + MCU_EVENT_HW_UPSTREAM_DATA = 2, + MCU_EVENT_HW_START_VAD = 3, + MCU_EVENT_HW_CP_PROCESS_DONE = 4, + + MCU_EVENT_MAX, +}; + +/// Tasks types definition +enum CP_TASK_TYPE +{ + CP_TASK_A2DP_DECODE = 0x00, + CP_TASK_SCO = 0x01, + CP_TASK_AEC = 0x02, + CP_TASK_HW = 0x03, + /// Maximum number of tasks + CP_TASK_MAX, +}; + +typedef enum { + CP_ACCEL_STATE_CLOSED = 0, + CP_ACCEL_STATE_OPENING, + CP_ACCEL_STATE_OPENED, + CP_ACCEL_STATE_CLOSING, +}CP_ACCEL_STATE_E; + +/// Task descriptor grouping all information required. +struct cp_task_desc +{ + CP_ACCEL_STATE_E cp_accel_state; + CP_ACCEL_CP_MAIN cp_work_main; + CP_ACCEL_EVT_HDLR cp_evt_hdlr; + CP_ACCEL_EVT_HDLR mcu_evt_hdlr; + CP_ACCEL_EVT_HDLR mcu_sys_ctrl_hdlr; +}; +/// CP TASK environment structure +struct cp_task_env_tag +{ + struct cp_task_desc p_desc[CP_TASK_MAX]; +}; +/// cp environment definition +struct cp_env_tag +{ + uint8_t mcu2cp_tx_count; + uint8_t mcu2cp_tx_pending[MAX_CP_MSG_NUM]; + bool cp_msg_recv; + uint8_t cp_msg[CP_TASK_MAX][2]; +}; + +/// Retrieves task type from event id. +#define CP_TASK_ID_GET(cp_event_id) (((cp_event_id) & 0xF0) >> 4) +/// Retrieves event from event id. +#define CP_EVENT_GET(cp_event_id) ((cp_event_id) & 0x0F) +/// Builds the task identifier from the type and the index of that task. +#define CP_BUILD_ID(id, event) ( (uint8_t)(((id) << 4)|(event)) ) + +//int cp_accel_open(CP_ACCEL_CP_MAIN cp_main, CP_ACCEL_EVT_HDLR cp_hdlr, CP_ACCEL_EVT_HDLR mcu_hdlr); +int cp_accel_open(enum CP_TASK_TYPE task_id, struct cp_task_desc const * p_task_desc); + +int cp_accel_close(enum CP_TASK_TYPE task_id); + +int cp_accel_init_done(void); + +int cp_accel_send_event_mcu2cp(uint8_t event); + +int cp_accel_send_event_cp2mcu(uint8_t event); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/cp_accel/cp_queue.c b/services/cp_accel/cp_queue.c new file mode 100644 index 0000000..fab3260 --- /dev/null +++ b/services/cp_accel/cp_queue.c @@ -0,0 +1,137 @@ + +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/*** +* cqueue.c - c circle queue c file +*/ + +#include "cp_queue.h" +#include +#include "cmsis.h" +#include "hal_uart.h" +#include + +int InitCpQueue(CQueue *Q, unsigned int size, CQItemType *buf) +{ + Q->size = size; + Q->base = buf; + Q->len = 0; + if (!Q->base) + return CQ_ERR; + + Q->read = Q->write = 0; + return CQ_OK; +} + +int IsEmptyCpQueue(CQueue *Q) +{ + if (Q->len == 0) + return CQ_OK; + else + return CQ_ERR; +} + +int LengthOfCpQueue(CQueue *Q) +{ + return Q->len; +} + +int AvailableOfCpQueue(CQueue *Q) +{ + return (Q->size - Q->len); +} + +int EnCpQueue(CQueue *Q, CQItemType *e, unsigned int len) +{ + if (AvailableOfCQueue(Q) < len) { + return CQ_ERR; + } + + Q->len += len; + + uint32_t bytesToTheEnd = Q->size - Q->write; + if (bytesToTheEnd > len) + { + memcpy((uint8_t *)&Q->base[Q->write], (uint8_t *)e, len); + Q->write += len; + } + else + { + memcpy((uint8_t *)&Q->base[Q->write], (uint8_t *)e, bytesToTheEnd); + memcpy((uint8_t *)&Q->base[0], (((uint8_t *)e)+bytesToTheEnd), len-bytesToTheEnd); + Q->write = len-bytesToTheEnd; + } + + return CQ_OK; +} + +int DeCpQueue(CQueue *Q, CQItemType *e, unsigned int len) +{ + if(LengthOfCQueue(Q) < len) + return CQ_ERR; + + Q->len -= len; + + if(e != NULL) { + + uint32_t bytesToTheEnd = Q->size - Q->read; + if (bytesToTheEnd > len) + { + memcpy((uint8_t *)e, (uint8_t *)&Q->base[Q->read], len); + Q->read += len; + } + else + { + memcpy((uint8_t *)e, (uint8_t *)&Q->base[Q->read], bytesToTheEnd); + memcpy((((uint8_t *)e)+bytesToTheEnd), (uint8_t *)&Q->base[0], len-bytesToTheEnd); + Q->read = len-bytesToTheEnd; + } + } + else { + Q->read = (Q->read+len)%Q->size; + } + + return CQ_OK; +} + +int PeekCpQueue(CQueue *Q, unsigned int len_want, CQItemType **e1, unsigned int *len1, CQItemType **e2, unsigned int *len2) +{ + if(LengthOfCQueue(Q) < len_want) { + return CQ_ERR; + } + + *e1 = &(Q->base[Q->read]); + if((Q->write > Q->read) || (Q->size - Q->read >= len_want)) { + *len1 = len_want; + *e2 = NULL; + *len2 = 0; + return CQ_OK; + } + else { + *len1 = Q->size - Q->read; + *e2 = &(Q->base[0]); + *len2 = len_want - *len1; + return CQ_OK; + } + + return CQ_ERR; +} + +void ResetCpQueue(CQueue *Q) +{ + Q->len = 0; + Q->read = Q->write = 0; +} \ No newline at end of file diff --git a/services/cp_accel/cp_queue.h b/services/cp_accel/cp_queue.h new file mode 100644 index 0000000..00bfbe0 --- /dev/null +++ b/services/cp_accel/cp_queue.h @@ -0,0 +1,51 @@ + +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/*** +* cqueue.h - c circle queue c header +*/ + +#ifndef CP_QUEUE_H +#define CP_QUEUE_H 1 + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "cqueue.h" + +/* Init Queue */ +int InitCpQueue(CQueue *Q, unsigned int size, CQItemType *buf); +/* Is Queue Empty */ +int IsEmptyCpQueue(CQueue *Q); +/* Filled Length Of Queue */ +int LengthOfCpQueue(CQueue *Q); +/* Empty Length Of Queue */ +int AvailableOfCpQueue(CQueue *Q); +/* Push Data Into Queue (Tail) */ +int EnCpQueue(CQueue *Q, CQItemType *e, unsigned int len); +/* Pop Data Data From Queue (Front) */ +int DeCpQueue(CQueue *Q, CQItemType *e, unsigned int len); +/* Peek But Not Pop Data From Queue (Front) */ +int PeekCpQueue(CQueue *Q, unsigned int len_want, CQItemType **e1, unsigned int *len1, CQItemType **e2, unsigned int *len2); + +void ResetCpQueue(CQueue *Q); + +#if defined(__cplusplus) +} +#endif + +#endif /* CP_QUEUE_H */ diff --git a/services/hw_dsp/Makefile b/services/hw_dsp/Makefile new file mode 100644 index 0000000..931dd08 --- /dev/null +++ b/services/hw_dsp/Makefile @@ -0,0 +1,25 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.c)) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.cpp)) + +ifeq ($(HW_FILTER_CODEC_IIR),1) +ifeq ($(ANC_APP),1) +$(error "error: ANC_APP and HW_FILTER_CODEC_IIR can't be used in the same") +endif +ifeq ($(HW_DAC_IIR_EQ_PROCESS),1) +$(error "error: HW_DAC_IIR_EQ_PROCESS and HW_FILTER_CODEC_IIR can't be used in the same") +endif +endif + + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -Iservices/hw_dsp/inc \ + -Iservices/multimedia/audio/process/filters/include diff --git a/services/hw_dsp/inc/hw_filter_codec_iir.h b/services/hw_dsp/inc/hw_filter_codec_iir.h new file mode 100644 index 0000000..078e717 --- /dev/null +++ b/services/hw_dsp/inc/hw_filter_codec_iir.h @@ -0,0 +1,49 @@ +#ifndef __HW_FILTER_CODEC_IIR_H__ +#define __HW_FILTER_CODEC_IIR_H__ + +#include +#include "iir_process.h" +#include "hw_codec_iir_process.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + int32_t bypass; + HW_CODEC_IIR_TYPE_T iir_device; +#if 1 + HW_CODEC_IIR_CFG_F iir_cfg; +#else + IIR_CFG_T iir_cfg; +#endif +} hw_filter_codec_iir_cfg; + +struct hw_filter_codec_iir_state_; + +typedef struct hw_filter_codec_iir_state_ hw_filter_codec_iir_state; + +// Creat a instance from hw_filter_codec_iir module/class +// Common value include: sample rate, frame size and so on. +hw_filter_codec_iir_state *hw_filter_codec_iir_create(int32_t sample_rate, int32_t channel_num, int32_t bits, hw_filter_codec_iir_cfg *cfg); + +// Destory a hw_filter_codec_iir instance +int32_t hw_filter_codec_iir_destroy(hw_filter_codec_iir_state *st); + +// Just use modify instance configure +int32_t hw_filter_codec_iir_set_config(hw_filter_codec_iir_state *st, hw_filter_codec_iir_cfg *cfg); + +// Get/set some value or enable/disable some function +// int32_t hw_filter_codec_iir_ctl(hw_filter_codec_iir_state *st, int32_t ctl, void *ptr); + +// Do not need process function, because hardware run separately + +// Debug hw_filter_codec_iir instance +int32_t hw_filter_codec_iir_dump(hw_filter_codec_iir_state *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/hw_dsp/src/hw_filter_codec_iir.c b/services/hw_dsp/src/hw_filter_codec_iir.c new file mode 100644 index 0000000..a86154a --- /dev/null +++ b/services/hw_dsp/src/hw_filter_codec_iir.c @@ -0,0 +1,145 @@ +/******************************************************************************* +** namer: speech_eq +** description: fir and iir eq manager +** version:V0.9 +** author: Yunjie Huo +** modify: 2016.12.26 +** todo: 1. +*******************************************************************************/ +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "string.h" +#include "hw_filter_codec_iir.h" +#include "stdbool.h" +#include "hal_location.h" +#include "hw_codec_iir_process.h" +#include "tgt_hardware.h" + +#ifndef CODEC_OUTPUT_DEV +#define CODEC_OUTPUT_DEV CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV +#endif + +struct hw_filter_codec_iir_state_ +{ + // public + /* Basic info */ + int32_t sample_rate; + // int32_t frame_size; + int32_t channel_num; + int32_t bits; + + /* configure info */ + int32_t bypass; + int32_t need_value; + HW_CODEC_IIR_TYPE_T iir_device; + + // private + /* Parameters */ + int32_t iir_device_opened; + + /* DSP-related arrays */ + + /* Misc */ + // input and output buffer + +}; + +// just support 1 st +hw_filter_codec_iir_state iir_st; + +hw_filter_codec_iir_state *hw_filter_codec_iir_create(int32_t sample_rate, int32_t channel_num, int32_t bits, hw_filter_codec_iir_cfg *cfg) +{ + hw_filter_codec_iir_state *st = &iir_st; + + TRACE(4,"[%s] sample_rate = %d, channel_num = %d, bits = %d", __func__, sample_rate, channel_num, bits); + + // Set parameters + st->sample_rate = sample_rate; + st->channel_num = channel_num; + st->bits = bits; + + // Initialize internal variables + st->iir_device_opened = 0; + + // Malloc dynamic memory + + // Initialize dynamic memory + + hw_filter_codec_iir_set_config(st, cfg); + + return st; +} + +int32_t hw_filter_codec_iir_destroy(hw_filter_codec_iir_state *st) +{ + if (st->iir_device_opened) + { + hw_codec_iir_close(st->iir_device); + } + + st->bypass = 0; + st->iir_device = HW_CODEC_IIR_NOTYPE; + st->iir_device_opened = 0; + + return 0; +} + +int32_t hw_filter_codec_iir_set_config(hw_filter_codec_iir_state *st, hw_filter_codec_iir_cfg *cfg) +{ + st->bypass = cfg->bypass; + st->iir_device = cfg->iir_device; + + TRACE(2,"[%s] iir device = %d", __func__, st->iir_device); + + if (!st->iir_device_opened) + { + hw_codec_iir_open((enum AUD_SAMPRATE_T)st->sample_rate, st->iir_device,CODEC_OUTPUT_DEV); + } + +#if 1 + hw_codec_iir_set_coefs(&cfg->iir_cfg, st->iir_device); +#else + HW_CODEC_IIR_CFG_T *hw_iir_cfg=NULL; + + hw_iir_cfg = hw_codec_iir_get_cfg((enum AUD_SAMPRATE_T)st->sample_rate, &cfg->iir_cfg); + ASSERT(hw_iir_cfg != NULL, "[%s] codec IIR parameter error!", __func__); + hal_codec_iir_dump(hw_iir_cfg); + hw_codec_iir_set_cfg(hw_iir_cfg, (enum AUD_SAMPRATE_T)st->sample_rate, st->iir_device); +#endif + + + + return 0; +} + +// int32_t hw_filter_codec_iir_ctl(hw_filter_codec_iir_state *st, int32_t ctl, void *ptr) +// { +// switch(ctl) +// { +// case HW_FILTER_CODEC_IIR_SET_AAA: +// st->aaa = (*(int32_t*)ptr); +// break; + +// case HW_FILTER_CODEC_IIR_GET_AAA: +// (*(int32_t*)ptr) = (int32_t)st->aaa; +// break; + +// default: +// TRACE(2,"[%s] ctl(%d) is not valid", __func__, ctl); +// return -1; +// } + +// return 0; +// } + +int32_t hw_filter_codec_iir_dump(hw_filter_codec_iir_state *st) +{ + TRACE(1,"[%s]: ", __func__); + + // Add dump info + + // End + + return 0; +} \ No newline at end of file diff --git a/services/ibrt_core/Makefile b/services/ibrt_core/Makefile new file mode 100644 index 0000000..16b7eee --- /dev/null +++ b/services/ibrt_core/Makefile @@ -0,0 +1,94 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.c)) + +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.cpp)) + +src_obj := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +IBRT_LIB_NAME := libtws_ibrt + +ifeq ($(ENHANCED_STACK),1) +IBRT_LIB_NAME := $(IBRT_LIB_NAME)_enhanced_stack +endif + +ifeq ($(BLE), 1) +IBRT_LIB_NAME := $(IBRT_LIB_NAME)_ble +endif + +ifeq ($(ANC_APP), 1) +IBRT_LIB_NAME := $(IBRT_LIB_NAME)_anc +endif + +ifeq ($(KERNEL),RTX) +IBRT_LIB_NAME := $(IBRT_LIB_NAME)_RTX +endif +ifeq ($(KERNEL),RTX5) +IBRT_LIB_NAME := $(IBRT_LIB_NAME)_RTX5 +endif + +$(IBRT_LIB_NAME)-y := $(src_obj) + +obj-y := $(IBRT_LIB_NAME).a + +subdir-ccflags-y += \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iservices/multimedia/audio/process/resample/include \ + $(BT_IF_INCLUDES) \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iapps/key \ + -Iapps/main \ + -Iapps/battery \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/audioplayers/a2dp_decoder \ + -Iapps/factory \ + -Iservices/ai_voice/manager \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/common/api \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/hl/inc \ + -Iservices/ble_stack/ke/api \ + -Iservices/ble_app \ + -Iservices/ble_app/app_datapath \ + -Iservices/ble_app/app_tws \ + -Iservices/ble_app/app_main \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/osif \ + -Iservices/nv_section/factory_section \ + -Iservices/nv_section/log_section \ + -Iservices/app_ibrt/inc \ + -Iservices/bt_app/a2dp_codecs/include \ + -Ithirdparty/audio_codec_lib/liblhdc-dec/inc \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iutils/hwtimer_list \ + -Iservices/voicepath \ + -Iservices/app_tws/inc \ + -Iservices/app_ai/inc \ + -Iservices/ai_voice/protocol/gma/gma_crypto \ + -Iapps/anc/inc + +ifeq ($(IBRT),1) +subdir-ccflags-y += \ + -Iservices/ibrt_core/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/bt_app +endif + +CFLAGS_app_tws_ibrt.o += -DBESLIB_INFO=$(BESLIB_INFO) + diff --git a/services/ibrt_core/inc/app_ibrt_bt_profile_sync.h b/services/ibrt_core/inc/app_ibrt_bt_profile_sync.h new file mode 100644 index 0000000..d5a3c53 --- /dev/null +++ b/services/ibrt_core/inc/app_ibrt_bt_profile_sync.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_IBRT_BT_PROFILE_SYNC__ +#define __APP_IBRT_BT_PROFILE_SYNC__ + +#include "stdint.h" + + +#define LM_SP_P192_PRE_COMP_POINTS 4 +#define DEV_CLASS_LEN 3 +#define FEATURE_PAGE_MAX 3 +#define KEY_LEN 0x10 +#define SRES_LEN 0x04 +#define ACO_LEN 12 +#define PIN_CODE_MAX_LEN 0x10 +#define CHNL_MAP_LEN 0x0A +#define BD_NAME_SIZE 0xF8 // Was 0x20 for BLE HL +#define FEATS_LEN 0x08 + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t app_ibrt_pack_bt_profile_data(uint8_t* buf, uint16_t* len, uint16_t conhdl); +uint8_t app_ibrt_unpack_bt_profile_data(uint8_t* buf, uint16_t len); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/ibrt_core/inc/app_tws_besaud.h b/services/ibrt_core/inc/app_tws_besaud.h new file mode 100644 index 0000000..4be7bfd --- /dev/null +++ b/services/ibrt_core/inc/app_tws_besaud.h @@ -0,0 +1,42 @@ +#ifndef __APP_TWS_BESAUD_H__ +#define __APP_TWS_BESAUD_H__ + +#include "bluetooth.h" +#include "besaud_api.h" + +#define TWS_BESAUD_EVENT_CONTROL_CONNECTED (BTIF_BESAUD_EVENT_CONTROL_CONNECTED) + +#define TWS_BESAUD_EVENT_CONTROL_DISCONNECTED (BTIF_BESAUD_EVENT_CONTROL_DISCONNECTED) + +#define TWS_BESAUD_EVENT_CONTROL_DATA_IND (BTIF_BESAUD_EVENT_CONTROL_DATA_IND) + +#define TWS_BESAUD_EVENT_CONTROL_DATA_SENT (BTIF_BESAUD_EVENT_CONTROL_DATA_SENT) + +#define TWS_BESAUD_EVENT_CONTROL_SET_IDLE (BTIF_BESAUD_EVENT_CONTROL_SET_IDLE) + +typedef btif_besaud_event tws_besaud_event; + +typedef btif_besaud_status_change_callback tws_besaud_status_change_callback; + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t tws_besaud_is_connected(void); +uint8_t tws_besaud_is_cmd_sending(void); +void tws_besaud_client_create(btif_remote_device_t *dev); +void tws_besaud_server_create(tws_besaud_status_change_callback callback); +void tws_besaud_init(void); +void tws_besaud_send_cmd(uint8_t* cmd, uint16_t len); +bt_status_t tws_besaud_send_cmd_no_wait(uint8_t* cmd, uint16_t len); +void tws_besaud_status_changed(tws_besaud_event event); + +void tws_besaud_create_extra_channel(bt_bdaddr_t *remote); +void tws_besaud_extra_channel_send_data(const void* data, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/ibrt_core/inc/app_tws_ctrl_thread.h b/services/ibrt_core/inc/app_tws_ctrl_thread.h new file mode 100644 index 0000000..77626ff --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ctrl_thread.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_CTRL_THREAD__ +#define __APP_TWS_CTRL_THREAD__ + +#include "app_tws_ibrt.h" +#include "app_tws_ibrt_cmd_handler.h" +#include "app_ibrt_custom_cmd.h" + +#if (defined IBRT_OTA || defined __GMA_OTA_TWS__ || defined OTA_ENABLED) || defined __DUAL_MIC_RECORDING__ +#define APP_TWS_CTRL_BUFFER_MAX_LEN 672 +#else +#if (defined TILE_DATAPATH && defined GFPS_ENABLED) +#define APP_TWS_CTRL_BUFFER_MAX_LEN 512 +#else +#define APP_TWS_CTRL_BUFFER_MAX_LEN 300 //no more buf for 1400 +#endif +#endif +typedef void (*app_tws_cmd_send_function_t)(uint8_t*, uint16_t); + +typedef struct +{ + uint32_t cmdcode; + app_tws_cmd_send_function_t tws_cmd_send; +} __attribute__((packed)) app_tws_cmd_send_t; + +typedef enum +{ + PARA_NONE, + PARA_CODEC_TYPE, + PARA_PLAY_BACK, + PARA_BUFFER, + PARA_SYNC_TRIGGER, +} mail_para_type_e; + +typedef struct +{ + uint8_t *cmd_buffer; + uint16_t cmd_len; +} cmd_buffer_t; + +typedef struct +{ + uint32_t evt; + uint32_t arg; + uint32_t arg1; + uint32_t system_time; + cmd_buffer_t cmd_buff; +} TWS_MSG_BLOCK; + +#ifdef __cplusplus +extern "C" { +#endif +void tws_ctrl_thread_init(void); +void *tws_ctrl_mailbox_heap_malloc(uint32_t size); +void tws_ctrl_mailbox_heap_free(void *rmem); +int tws_ctrl_send_cmd(uint32_t cmd_code, uint8_t *p_buff, uint16_t length); +int tws_ctrl_send_rsp(uint16_t rsp_code, uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +int tws_ctrl_send_cmd_high_priority(uint32_t cmd_code, uint8_t *p_buff, uint16_t length); +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/ibrt_core/inc/app_tws_ibrt.h b/services/ibrt_core/inc/app_tws_ibrt.h new file mode 100644 index 0000000..e4c5515 --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ibrt.h @@ -0,0 +1,367 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_IBRT__ +#define __APP_TWS_IBRT__ +#include "app_tws_profile_sync.h" +#include "a2dp_api.h" +#include "cmsis_os.h" +#include "rfcomm_api.h" +#include "spp_api.h" +#include "hfp_api.h" +#include "bt_drv_reg_op.h" + +#define ACCESS_MODE_ARRAY_MAX 10 +#define APP_IBRT_RECONNECT_TIMEOUT_MS 5 + +#define LETOHOST16(ptr) (uint16_t)( ((uint16_t) *((uint8_t*)(ptr)+1) << 8) | \ + ((uint16_t) *((uint8_t*)(ptr))) ) + +#define LETOHOST32(ptr) (uint32_t)( ((uint32_t) *((uint8_t*)(ptr)+3) << 24) | \ + ((uint32_t) *((uint8_t*)(ptr)+2) << 16) | \ + ((uint32_t) *((uint8_t*)(ptr)+1) << 8) | \ + ((uint32_t) *((uint8_t*)(ptr))) ) + + +#define UINT16LOW(num) ((uint8_t)(num & 0xFF)) +#define UINT16HIGH(num) ((uint8_t)((num >> 8) & 0xFF)) + +#define APP_IBRT_SUPV_TO (0x640) + +#define NV_RAM_RECORD_NUM (10) + +#define INVALID_ERROR 0xFF +#define INVALID_HANDLE 0xFFFF +#define BD_ADDR_LEN 6 + +#define IBRT_DISABLE 0 +#define IBRT_ENABLE 1 +#define IBRT_SWITCH 2 + +#define IBRT_NONE_ROLE 0 +#define IBRT_SNIFFER_ROLE 1 +#define IBRT_FORWARD_ROLE 2 + +#define IBRT_TWS_SNIFF_MAX_INTERVAL (254) +#define IBRT_TWS_SNIFF_MIN_INTERVAL (254) + +#define IBRT_TWS_LINK_LARGE_DURATION (12) +#define IBRT_TWS_LINK_DEFAULT_DURATION (8) + +#define IBRT_TWS_PRIVATE_TWS_ENABLE (1) +#define IBRT_TWS_PRIVATE_TWS_DURATION (2) +#define IBRT_TWS_PRIVATE_TWS_INTERVAL (4) + +#define IBRT_ENCRYPT_DISABLE 0x00 +#define IBRT_ENCRYPT_ENABLE 0x01 +#define IBRT_ENCRYPT_REFRESH 0x02 + +#define IBRT_TWS_BT_TPOLL_DEFAULT (80) + +typedef uint8_t ibrt_link_mode_e; +#define IBRT_ACTIVE_MODE 0x00 +#define IBRT_HOLD_MODE 0x01 +#define IBRT_SNIFF_MODE 0x02 +#define IBRT_PARK_MODE 0x03 +#define IBRT_SCATTER_MODE 0x04 + +typedef enum +{ + NO_LINK_TYPE, + SNOOP_LINK, + MOBILE_LINK, + TWS_LINK, +} ibrt_link_type_e; + +typedef uint8_t ibrt_role_e; +#define IBRT_MASTER 0 +#define IBRT_SLAVE 1 +#define IBRT_UNKNOW 0xff + +/* + * tx data protect in tws switch + */ +#ifndef __TWS_SWITCH_TX_DATA_PROTECT__ +#define __TWS_SWITCH_TX_DATA_PROTECT__ +#endif + +typedef uint8_t tss_state_e; +#define TSS_IDLE_STATE (0x00) +#define TSS_CRITICAL_WAIT_STATE (0x01) + +#define TSS_TX_WAIT_STATE (0x02) +#define TSS_TIMER_WAIT_STATE (0x04) +#define TSS_CMD_STATE (0x08) +#define TSS_SLAVE_WAIT_STATE (0x10) + + +/* + * wait some high priority criticals to be finished + * such as sending accept response of avdtp start/suspend cmd + * then launch tws switch + */ +#define TSS_DELAY_CRITICAL_TIMEOUT_MS 50 + +/* + * wait profile layer tx data to hci txbuf list + * wait controller tx data to air + */ +#define TSS_DELAY_HCI_CMD_TIMEOUT_MS 20 + + + +// hci tx buf type mapping +#define IBRT_HBT_TX_ACL 0x05 //#define HBT_TX_ACL 0x05 +#define IBRT_HBT_TX_BLE 0x08 //#define HBT_TX_BLE 0x08 + +#define CODING_FORMAT_CVSD 0x02 +#define CODING_FORMAT_TRANSP 0x03 + +typedef struct +{ + uint8_t codec_type; + uint8_t sample_bit; + uint8_t sample_rate; + uint8_t vendor_para; +} __attribute__((packed)) ibrt_codec_t; + +typedef struct +{ + uint8_t backup_index; + uint8_t pickup_index; + uint8_t array_counter; + btif_accessible_mode_t access_mode_array[ACCESS_MODE_ARRAY_MAX]; +} access_mode_backup_t; + +typedef enum { + AUDIO_CHANNEL_SELECT_STEREO, + AUDIO_CHANNEL_SELECT_LRMERGE, + AUDIO_CHANNEL_SELECT_LCHNL, + AUDIO_CHANNEL_SELECT_RCHNL, +} AUDIO_CHANNEL_SELECT_E; + +typedef enum { + IBRT_ROLE_SWITCH_USER_AI = 0, + IBRT_ROLE_SWITCH_USER_OTA, + IBRT_ROLE_SWITCH_USER_COUNT +}IBRT_ROLE_SWITCH_USER_E; + +typedef struct +{ + bool lowlayer_monitor_enable; + + uint16_t long_private_poll_interval ; + uint16_t default_private_poll_interval; + uint16_t short_private_poll_interval; + + uint16_t default_private_poll_interval_in_sco; + uint16_t short_private_poll_interval_in_sco; + uint16_t default_bt_tpoll; + + bool tws_switch_tx_data_protect; + uint32_t tws_cmd_send_timeout; + uint32_t tws_cmd_send_counter_threshold; + uint32_t tws_switch_stable_timeout; + + uint16_t mobile_page_timeout; + uint16_t tws_connection_timeout; + + bool delay_exit_sniff; + uint32_t delay_ms_exit_sniff; + uint8_t audio_sync_mismatch_resume_version; +} ibrt_core_config_t; + +typedef struct +{ + int32_t mobile_diff_us; + int32_t tws_diff_us; +}diff_us_t; +typedef struct +{ + ibrt_role_e init_done; + ibrt_role_e nv_role; + ibrt_role_e current_role; + uint8_t role_switch_debonce_time; + rssi_t raw_rssi; + rssi_t peer_raw_rssi; + int32_t mobile_diff_us; + int32_t tws_diff_us; + int8_t cur_buf_size; + uint16_t local_battery_volt; + uint16_t peer_battery_volt; + bt_bdaddr_t local_addr; + bt_bdaddr_t peer_addr; + bt_bdaddr_t mobile_addr; + uint8_t mobile_linkKey[16]; + uint16_t ibrt_conhandle; + uint8_t ibrt_disc_reason; + uint16_t tws_conhandle; + uint16_t peer_tws_conhandle; + uint16_t mobile_conhandle;//if local dev is connected with mobile + uint16_t peer_mobile_conhandle; + uint32_t mobile_constate; + uint32_t tws_constate; + uint32_t ibrt_constate; + uint32_t ibrt_ai_role_switch_handle; //one bit represent a AI + uint32_t ibrt_role_switch_handle_user; //one bit represent a user + osMailQId tws_mailbox; + ibrt_codec_t a2dp_codec; + uint32_t audio_chnl_sel; + void *p_mobile_a2dp_profile; + void *p_mobile_hfp_profile; + void *p_mobile_avrcp_profile; + void *p_mobile_map_profile; + void *p_mobile_reseved0_profile; + void *p_mobile_reseved1_profile; + btif_remote_device_t *p_tws_remote_dev; + btif_remote_device_t *p_mobile_remote_dev; + btif_accessible_mode_t access_mode; + bool access_mode_sending; + bool is_ibrt_search_ui; + uint8_t tws_switch_local_done: 1; + uint8_t tws_switch_peer_done: 1; + uint8_t master_tws_switch_pending: 1; + uint8_t slave_tws_switch_pending: 1; + uint8_t avrcp_register_notify_event; + uint8_t avrcp_wait_register_notify_rsp; + osTimerId wait_profile_ready_timer_id; + osTimerId delay_profile_send_timer_id; + osTimerId delay_hci_tss_cmd_timer_id; + bool wait_profile; + uint8_t rx_profile_update; + uint8_t tx_profile_update; + ibrt_link_mode_e tws_mode; + ibrt_link_mode_e mobile_mode; + access_mode_backup_t access_mode_backup; + + uint8_t ibrt_sco_activate; + hfp_sco_codec_t ibrt_sco_codec; + uint16_t ibrt_sco_hcihandle; + uint8_t ibrt_sco_lmphdl; + bool ibrt_in_poweroff; + bool w4_ibrt_connected; + bool mobile_encryp_done; + uint32_t rx_seq_error; + uint32_t tws_cmd_send_time; + bool w4_stop_ibrt_for_rx_seq_error; + bool dbg_state_timer_ongoing; + bool stop_ibrt_timer_ongoing; + bool ibrt_stopped_due_to_checker; + bool phone_connect_happened; + bool wait4_reset_complete; + uint8_t reset_error_type; + tss_state_e tss_state; + bool mobile_pair_canceled; + uint16_t sync_id_mask; + uint8_t snoop_connected; + bool w4_tws_exit_sniff; + ibrt_core_config_t config; + uint32_t basic_profiles; +} ibrt_ctrl_t; + +typedef struct +{ + ibrt_role_e nv_role; + bt_bdaddr_t local_addr; + bt_bdaddr_t peer_addr; + bt_bdaddr_t mobile_addr; + uint32_t audio_chnl_sel; +} ibrt_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +void app_tws_ibrt_init(void); +void app_tws_ibrt_start(ibrt_config_t *config, bool is_search_ui); +void app_tws_ibrt_global_callback(const btif_event_t *event); +ibrt_link_type_e app_tws_ibrt_get_remote_link_type(btif_remote_device_t *remote_dev); +void app_tws_ibrt_set_a2dp_codec(const a2dp_callback_parms_t *info); +void app_tws_ibrt_profile_callback(uint32_t profile,void *param1,void *param2); +void app_tws_ibrt_spp_callback(void* spp_devi, void* spp_para); +struct BT_DEVICE_T* app_tws_ibrt_get_bt_device_ctx(void); +ibrt_ctrl_t* app_tws_ibrt_get_bt_ctrl_ctx(void); +bool app_tws_ibrt_mobile_link_connected(void); +bool app_tws_ibrt_tws_link_connected(void); +bt_status_t app_tws_ibrt_create_tws_connection(uint16_t page_timeout); +bt_status_t app_tws_ibrt_create_mobile_connection(uint16_t mobile_page_timeout,const bt_bdaddr_t *mobile_addr); +void app_tws_ibrt_proctect_bt_tx_type(uint16_t length); +bt_status_t app_tws_ibrt_disconnect_connection(btif_remote_device_t *remdev); +void app_tws_ibrt_clear_mobile_reconnecting(void); +void app_tws_ibrt_clear_tws_reconnecting(void); +void app_tws_ibrt_set_tws_reconnecting(void); +bool app_tws_ibrt_is_reconnecting_tws(void); +void app_bt_ibrt_reconnect_mobile_profile(bt_bdaddr_t mobile_addr); +void app_tws_ibrt_reset_bdaddr_to_nv_original(void); +void app_tws_ibrt_set_bdaddr_to_nv_master(void); +bt_status_t app_tws_ibrt_init_access_mode(btif_accessible_mode_t mode); +bt_status_t app_tws_ibrt_set_access_mode(btif_accessible_mode_t mode); +bt_status_t app_tws_ibrt_do_mss_with_mobile(void); +bt_status_t app_tws_ibrt_do_mss_with_tws(void); +bt_status_t app_tws_ibrt_exit_sniff_with_mobile(void); +bt_status_t app_tws_ibrt_exit_sniff_with_tws(void); +btif_connection_role_t app_tws_ibrt_get_local_tws_role(void); +btif_connection_role_t app_tws_ibrt_get_local_mobile_role(void); +void app_tws_ibrt_delay_slave_create_connection(void const *para); +void app_tws_ibrt_store_mobile_link_key(uint8_t *p_link_key); +ibrt_link_type_e app_tws_ibrt_get_link_type_by_addr(bt_bdaddr_t *p_addr); +bool app_tws_ibrt_slave_ibrt_link_connected(void); +void app_tws_ibrt_disconnect_callback(const btif_event_t * event); +void app_tws_ibrt_timing_control(bool enable, uint8_t type, uint16_t acl_interv_acl, uint16_t acl_interv_sco); +void app_tws_ibrt_sniff_timeout_handler(evm_timer_t *timer, unsigned int *skipInternalHandler); +void app_tws_ibrt_sniff_callback(const btif_event_t *event); +void app_tws_ibrt_use_the_same_bd_addr(void); +btif_accessible_mode_t app_tws_ibrt_access_mode_pickup(void); +void app_tws_ibrt_access_mode_backup(btif_accessible_mode_t mode); +void app_tws_ibrt_sdp_disconnect_callback(const void *para); +uint8_t app_tws_ibrt_role_get_callback(const void *para); +const char* app_tws_ibrt_role2str(uint8_t role); +bool app_tws_ibrt_key_already_exist(void *bdaddr); +bool btdrv_get_page_pscan_coex_enable(void); +void app_tws_ibrt_conn_req_pre_treatment_callback(const void *bd_addr); +void app_tws_ibrt_set_tws_pravite_interval(uint16_t tws_conhandle, uint16_t interval); +int app_ibrt_release_cmd_semphore(void); +int app_ibrt_clear_cmd_semphore(void); +void app_tws_ibrt_disconnect_mobile(void); +void app_tws_ibrt_disconnect_all_connection(void); +bool app_tws_ibrt_get_phone_connect_happened(void); +void app_tws_ibrt_clear_phone_connect_happened(void); +void app_tws_ibrt_set_phone_connect_happened(void); +void app_tws_ibrt_hci_tx_buf_tss_process(void); +void app_tws_ibrt_delay_hci_tss_cmd_timer_cb(void const *para); +void app_tws_ibrt_switch_role(void); +void app_tws_ibrt_set_tss_state(tss_state_e state); +tss_state_e app_tws_ibrt_get_tss_state(void); +void app_tws_ibrt_reset_tss_state(void); +void app_tws_ibrt_set_controller_rx_flow_stop(void); +void app_tws_ibrt_clear_controller_rx_flow_stop(void); +uint8_t app_tws_ibrt_get_audio_voice_active_state(void); +uint8_t app_tws_ibrt_get_tss_state_callback(const void *para); + +bool app_tws_ibrt_sync_airmode_check_ind_handler(uint8_t voice_setting); +void app_tws_ibrt_register_esco_auto_accept(void); +btif_remote_device_t *app_tws_get_mobile_rem_dev(void); +uint32_t app_tws_get_mobile_conn_state(void); +uint32_t app_tws_get_tws_conn_state(void); +uint16_t app_tws_get_tws_conhdl(void); +bool app_tws_ibrt_sync_airmode_check_ind_handler(uint8_t voice_setting); +uint8_t app_tws_ibrt_nv_role_get_callback(const void *para); +void app_tws_ibrt_update_basic_profiles(uint32_t profile_id,bool is_add); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/services/ibrt_core/inc/app_tws_ibrt_audio_analysis.h b/services/ibrt_core/inc/app_tws_ibrt_audio_analysis.h new file mode 100644 index 0000000..0e78f1b --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ibrt_audio_analysis.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_IBRT_AUDIO_ANALYSIS_H__ +#define __APP_TWS_IBRT_AUDIO_ANALYSIS_H__ + +#define AUDIO_ANALYSIS_INTERVAL (25) +#define AUDIO_ANALYSIS_CHECKER_INTERVEL_INVALID (1000) + +typedef struct { + uint32_t timestamp; + uint16_t sequenceNumber; + uint16_t curSubSequenceNumber; + uint16_t totalSubSequenceNumber; + uint16_t frame_samples; + uint32_t decoded_frames; + uint8_t undecode_frames; + uint8_t undecode_min_frames; + uint8_t undecode_max_frames; + uint8_t average_frames; + uint32_t sample_rate; +#if A2DP_DECODER_CHECKER + uint32_t check_sum; +#endif +} APP_TWS_IBRT_AUDIO_ANALYSIS_PLAYBACK_INFO_T; + +typedef struct { + APP_TWS_IBRT_AUDIO_ANALYSIS_PLAYBACK_INFO_T playback_info; + uint16_t mobile_cnt; + uint16_t bt_cnt; + uint32_t bt_clk; + uint32_t mobile_clk; + uint32_t handler_cnt; + int8_t compensate_cnt; + bool updated; +} APP_TWS_IBRT_AUDIO_ANALYSIS_INFO_T; + +typedef struct { + uint32_t tws_diff_clk; + uint16_t tws_diff_bit; + int32_t tws_diff_us; + uint32_t mobile_diff_clk; + uint16_t mobile_diff_cnt; + int32_t mobile_diff_us; +} APP_TWS_IBRT_AUDIO_ANALYSIS_RESULT_T; + +typedef enum { + AUDIO_ANALYSIS_STATUS_STOP, + AUDIO_ANALYSIS_STATUS_SUSPEND, + AUDIO_ANALYSIS_STATUS_START, + AUDIO_ANALYSIS_STATUS_DATA_VALID +}AUDIO_ANALYSIS_STATUS_E; + +void app_tws_ibrt_audio_mobile_clkcnt_get(uint32_t btclk, uint16_t btcnt, + uint32_t *mobile_master_clk, uint16_t *mobile_master_cnt); +APP_TWS_IBRT_AUDIO_ANALYSIS_RESULT_T *app_tws_ibrt_audio_analysis_result_get(void); +APP_TWS_IBRT_AUDIO_ANALYSIS_INFO_T *app_tws_ibrt_audio_analysis_local_info_get(void); +APP_TWS_IBRT_AUDIO_ANALYSIS_INFO_T *app_tws_ibrt_audio_analysis_remote_info_get(void); +int app_tws_ibrt_audio_analysis_status_get(void); +int app_tws_ibrt_audio_analysis_init(void); +int app_tws_ibrt_audio_analysis_start(uint32_t start_offset, uint32_t checker_intervel); +int app_tws_ibrt_audio_analysis_stop(void); +int app_tws_ibrt_audio_analysis_suspend(void); +int app_tws_ibrt_audio_analysis_resume(void); +int app_tws_ibrt_audio_analysis_skipnext(void); +uint32_t app_tws_ibrt_audio_analysis_interval_get(void); +int app_tws_ibrt_audio_analysis_interval_set(uint32_t analysis_interval); +uint32_t app_tws_ibrt_audio_analysis_tick_get(void); +int app_tws_ibrt_audio_analysis(APP_TWS_IBRT_AUDIO_ANALYSIS_INFO_T *local_info , + APP_TWS_IBRT_AUDIO_ANALYSIS_INFO_T *remote_info); +void app_tws_ibrt_audio_analysis_interrupt_tick(void); +void app_tws_ibrt_audio_analysis_audiohandler_tick(void); + + +#endif diff --git a/services/ibrt_core/inc/app_tws_ibrt_audio_sync.h b/services/ibrt_core/inc/app_tws_ibrt_audio_sync.h new file mode 100644 index 0000000..4c89e7e --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ibrt_audio_sync.h @@ -0,0 +1,146 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_IBRT_AUDIO_SYNC_H__ +#define __APP_TWS_IBRT_AUDIO_SYNC_H__ + +#define TWS_IBRT_AUDIO_SYNC_FACTOR_REFERENCE (1.0f - 80*1e-6) +//#define TWS_IBRT_AUDIO_SYNC_FACTOR_REFERENCE (1.0f) +#define TWS_IBRT_AUDIO_SYNC_FACTOR_FAST_LIMIT ( 0.0005f) +#define TWS_IBRT_AUDIO_SYNC_FACTOR_SLOW_LIMIT (-0.0005f) + +#define TWS_IBRT_AUDIO_SYNC_DEAD_ZONE_US (5) + +#define APP_TWS_IBRT_AUDIO_SYNC_MISMATCH_FLAG_NULL (0) +#define APP_TWS_IBRT_AUDIO_SYNC_MISMATCH_FLAG_NEEDRETRIGGER (1<<1) + +#define APP_TWS_IBRT_AUDIO_SYNC_SAMPLEING_FLAG_NULL (0) +#define APP_TWS_IBRT_AUDIO_SYNC_SAMPLEING_FLAG_DETECTER (1<<1) + +#ifdef __A2DP_AUDIO_SYNC_FIX_DIFF_NOPID__ +#define APP_TWS_IBRT_AUDIO_SYNC_TUNE_SKIP_NEXT_CNT (50) +#else +#define APP_TWS_IBRT_AUDIO_SYNC_TUNE_SKIP_NEXT_CNT (200) +#endif + +typedef enum { + APP_TWS_IBRT_AUDIO_TRIGGER_TYPE_INIT_SYNC, + APP_TWS_IBRT_AUDIO_TRIGGER_TYPE_RESUME, + APP_TWS_IBRT_AUDIO_TRIGGER_TYPE_LOCAL, +}APP_TWS_IBRT_AUDIO_TRIGGER_TYPE; + +typedef struct { + uint32_t timestamp; + uint16_t sequenceNumber; + uint8_t curSubSequenceNumber; + uint8_t totalSubSequenceNumber; + uint32_t frame_samples; +} APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_PLAYBACK_INFO_T; + +typedef struct +{ + uint32_t trigger_time; + uint8_t trigger_skip_frame; + APP_TWS_IBRT_AUDIO_TRIGGER_TYPE trigger_type; + APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_PLAYBACK_INFO_T audio_info; + uint16_t sequenceNumberStart; + float factor_reference; + uint8_t a2dp_session; + uint32_t handler_cnt; + uint32_t trigger_bt_clk; + uint16_t trigger_bt_cnt; +#ifdef __SW_TRIG__ + uint16_t tg_bitcnt; +#endif +}APP_TWS_IBRT_AUDIO_SYNC_TRIGGER_T; + +typedef struct +{ + uint32_t reseved; +}APP_TWS_IBRT_AUDIO_NEED_RETRIGGER_T; + +typedef struct +{ + float factor_reference; + uint32_t handler_cnt; +}APP_TWS_IBRT_AUDIO_SYNC_TUNE_T; + +typedef struct +{ + APP_TWS_IBRT_AUDIO_SYNC_TUNE_T sync_tune; + uint32_t new_reference_flag; +}APP_TWS_IBRT_AUDIO_SYNC_TUNE_REQ_T; + +typedef enum{ + APP_TWS_IBRT_AUDIO_SYNC_MISMATCH_RESUME_REQ_DISABLE, + APP_TWS_IBRT_AUDIO_SYNC_MISMATCH_RESUME_REQ_NULL, + APP_TWS_IBRT_AUDIO_SYNC_MISMATCH_RESUME_REQ_REQUEST, + APP_TWS_IBRT_AUDIO_SYNC_MISMATCH_RESUME_REQ_WAITRESUME, +}APP_TWS_IBRT_AUDIO_SYNC_MISMATCH_RESUME_REQ; + +typedef struct{ + float factor_reference; + float factor_fast_limit; + float factor_slow_limit; + uint32_t dead_zone_us; +}APP_TWS_IBRT_AUDIO_SYNC_CFG_T; + +float app_tws_ibrt_audio_sync_config_factor_reference_get(void); + +int app_tws_ibrt_audio_sync_sampleing_set_flag(uint32_t flag); + +int app_tws_ibrt_audio_sync_sampleing_get_flag(uint32_t *flag); + +int app_tws_ibrt_audio_sync_new_reference(float factor_reference); + +int app_tws_ibrt_audio_sync_reconfig(APP_TWS_IBRT_AUDIO_SYNC_CFG_T *config); + +bool app_tws_ibrt_audio_sync_playback_info_initdone(void); + +int app_tws_ibrt_audio_sync_init(void); + +int app_tws_ibrt_audio_sync_start(void); + +int app_tws_ibrt_audio_sync_restart(void); + +int app_tws_ibrt_audio_sync_stop(void); + +int app_tws_ibrt_audio_sync_tick(uint32_t tick); + +bool app_tws_ibrt_audio_sync_sampleing(float sample); + +int app_tws_ibrt_audio_sync_mismatch_tick(bool mismatch); + +int app_tws_ibrt_audio_sync_mismatch_resume_handle(uint32_t tick); + +int app_tws_ibrt_audio_sync_mismatch_resume_notify(void); + +int app_tws_ibrt_audio_sync_tune_request(APP_TWS_IBRT_AUDIO_SYNC_TUNE_REQ_T *sync_tune); + +bool app_tws_ibrt_audio_sync_tune_onprocess(void); + +int app_tws_ibrt_audio_sync_tune_handle(uint32_t tick); + +int app_tws_ibrt_audio_sync_tune_cancel(void); + +int app_tws_ibrt_audio_sync_tune_skip_next_cnt_proc(void); + +int app_tws_ibrt_audio_sync_tune_need_skip(void); + +void app_tws_ibrt_audio_sync_tune_skip_next_cnt(int32_t bypass_next_cnt); + +APP_TWS_IBRT_AUDIO_SYNC_CFG_T *app_tws_ibrt_audio_sync_config_default_get(void); + +#endif diff --git a/services/ibrt_core/inc/app_tws_ibrt_cmd_audio_analysis.h b/services/ibrt_core/inc/app_tws_ibrt_cmd_audio_analysis.h new file mode 100644 index 0000000..d5336ad --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ibrt_cmd_audio_analysis.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_IBRT_CMD_AUDIO_ANALYSIS_H__ +#define __APP_TWS_IBRT_CMD_AUDIO_ANALYSIS_H__ + +void app_ibrt_cmd_send_playback_info(uint8_t *p_buff, uint16_t length); +void app_ibrt_cmd_send_playback_info_handler(uint16_t rsp_seq, uint8_t *ptrParam, uint16_t paramLen); +void app_tws_ibrt_audio_analysis_send_info_done(uint16_t cmdcode, uint16_t rsp_seq, uint8_t *ptrParam, uint16_t paramLen); + +void app_ibrt_cmd_set_trigger(uint8_t *p_buff, uint16_t length); +void app_ibrt_cmd_set_trigger_handler(uint16_t rsp_seq, uint8_t *ptrParam, uint16_t paramLen); + +void app_ibrt_cmd_need_retrigger(uint8_t *p_buff, uint16_t length); +void app_ibrt_cmd_need_retrigger_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +void app_ibrt_cmd_audio_sync_tune(uint8_t *p_buff, uint16_t length); +void app_ibrt_cmd_audio_sync_tune_handler(uint16_t rsp_seq, uint8_t *ptrParam, uint16_t paramLen); + +void app_ibrt_cmd_audio_sync_set_latencyfactor(uint8_t *p_buff, uint16_t length); +void app_ibrt_cmd_audio_sync_set_latencyfactor_handler(uint16_t rsp_seq, uint8_t *ptrParam, uint16_t paramLen); + +#endif diff --git a/services/ibrt_core/inc/app_tws_ibrt_cmd_handler.h b/services/ibrt_core/inc/app_tws_ibrt_cmd_handler.h new file mode 100644 index 0000000..e9aab8f --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ibrt_cmd_handler.h @@ -0,0 +1,265 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_IBRT_CMD_HANDLER__ +#define __APP_TWS_IBRT_CMD_HANDLER__ +#include "app_tws_ibrt.h" +#include "app_tws_ibrt_cmd_audio_analysis.h" +#include "app_tws_ibrt_cmd_sync_hfp_status.h" +#include "app_tws_ibrt_cmd_sync_a2dp_status.h" +#include "app_ibrt_voice_report.h" +#include "app_ibrt_keyboard.h" + +#define IBRT_PROFILE_ARRAY_SIZE (12) +#define IBRT_WAIT_PROFILE_TIMEOUT (10000) +#define IBRT_NEW_PROFILE_WAIT_TIMEOUT (245) + +#define RSP_TIMEOUT_DEFAULT (5000) +#define RSP_TIMEOUT_FAST_ACK (1000) +#define APP_TWS_IBRT_MAX_DATA_SIZE (672) +#define APP_TWS_IBRT_CMDCODE_SIZE sizeof(uint16_t) +#define APP_TWS_IBRT_CMDSEQ_SIZE sizeof(uint16_t) +#define APP_TWS_IBRT_CMDHEAD_SIZE (APP_TWS_IBRT_CMDCODE_SIZE+APP_TWS_IBRT_CMDSEQ_SIZE) + +#define IBRT_BESAUD_RX_BUFF_SIZE (672) +#define IBRT_BESAUD_TX_BUFF_SIZE (672*4) +#define IBRT_TIMEOUT_INVALID (0) +#define app_ibrt_cmd_rsp_timeout_handler_null (0) +#define app_ibrt_cmd_rsp_handler_null (0) +#define app_ibrt_cmd_rx_handler_null (0) + +#define RSP_TIMEOUT_VOICE_REPORT (1000) + +typedef int (*TWS_CMD_HANDLER_T)(void **cmd_tbl, uint16_t *cmd_size); + +enum CMD_ID_T +{ + TWS_CMD_IBRT = 0, + TWS_CMD_CUSTOMER, + TWS_CMD_OTA, + TWS_CMD_IBRT_OTA, + TWS_CMD_NUM, +}; + +typedef enum +{ + APP_TWS_ACCEPT, + APP_TWS_NOT_ACCEPT, +} app_tws_switch_e; + +typedef enum +{ + APP_TWS_CMD_PROFILE_DATA_EXCHANGE = 0x8001, + APP_TWS_CMD_PROFILE_DATA_EXCHANGE_DONE = 0x8002, + APP_TWS_CMD_SET_CODEC_TYPE = 0x8003, + APP_TWS_CMD_RSP = 0x8004, + APP_TWS_CMD_SHARE_TWS_INFO = 0x8005, + APP_TWS_CMD_SWITCH_ROLE = 0x8006, + APP_TWS_CMD_SEND_PLAYBACK_INFO = 0x8007, + APP_TWS_CMD_SET_TRIGGER_TIME = 0x8008, + APP_TWS_CMD_NEED_RETRIGGER = 0x8009, + APP_TWS_CMD_SYNC_TUNE = 0x800A, + APP_TWS_CMD_SET_LATENCYFACTOR = 0x800B, + APP_TWS_CMD_START_IBRT = 0x800C, + APP_TWS_CMD_STOP_IBRT = 0x800D, + APP_TWS_CMD_SET_ENV = 0x800E, + APP_TWS_CMD_PROFILE_DATA_REQ = 0x800F, + APP_TWS_CMD_FAST_ACK_REQ = 0x8010, + APP_TWS_CMD_A2DP_STATUS_SYNC = 0x8011, + APP_TWS_CMD_HFP_STATUS_SYNC = 0x8012, + APP_TWS_CMD_VOICE_REPORT_REQUEST = 0x8013, + APP_TWS_CMD_VOICE_REPORT_START = 0x8014, + APP_TWS_CMD_KEYBOARD_REQUEST = 0x8015, + APP_TWS_CMD_TRANSFER_SM = 0x8016, + APP_TWS_CMD_SYNC_ANC_STATUS = 0x8017, + APP_TWS_CMD_SET_INTERVAL = 0x8018, + APP_TWS_CMD_NEW_MOBILE_INCOMING = 0x8019, + APP_TWS_CMD_GET_PEER_MOBILE_RSSI = 0x801A, + APP_TWS_CMD_NOTIFY_LINK_POLICY = 0x801B, + APP_TWS_CMD_SLAVE_CONNECT_BOX = 0x801C, + APP_TWS_CMD_SLAVE_CONNECT_BOX_RSP = 0x801D, + APP_TWS_CMD_SLAVE_DISCONNECT_BOX_RSP = 0x801E, + APP_TWS_CMD_SEND_CONTROLLER_PROFILE = 0x801F, + APP_TWS_CMD_REV_SNOOP_INFO_COMPLETE = 0x8020, + APP_TWS_CMD_GET_PEER_RAW_RSSI = 0x8021, + APP_TWS_CMD_SYNC_VOLUME_INFO = 0x8022, + APP_TWS_CMD_PERFORM_ACTION = 0x8023, + APP_TWS_CMD_EXIT_SNIFF_MODE = 0x8024, + APP_TWS_CMD_STOP_IBRT_FAILED = 0x8025, + APP_TWS_CMD_SHARE_COMMON_INFO = 0x8026, + APP_TWS_CMD_SYNC_MIX_PROMPT_REQ = 0x8027, + APP_TWS_CMD_STOP_PEER_PROMPT_REQ = 0x8028, + APP_TWS_CMD_LET_PEER_PLAY_PROMPT = 0x8029, + APP_TWS_CMD_PAIRING_MODE_REFRESH = 0x802A, + APP_TWS_CMD_LET_MASTER_PREPARE_RS = 0x802B, // for slave triggered role switch, BISTO need the master to control the gsound role switch + APP_TWS_CMD_LET_SLAVE_CONTINUE_RS = 0x802C, // for slave triggered role switch, tell the slave gsound role switch has completed + APP_TWS_CMD_AI_SEND_CMD_TO_PEER = 0x802D, // ai send cmd to peer whitout rsp + APP_TWS_CMD_AI_SEND_CMD_TO_PEER_WITH_RSP = 0x802E, // ai send cmd to peer whit rsp + APP_TWS_CMD_MOBILE_LINK_PLAYBACK_INFO = 0x802F, + APP_TWS_CMD_DISC_MOBILE = 0x8030, + APP_TWS_CMD_SPECIAL_ALL_CANCEL = 0xffff, +} app_tws_cmd_code_e; + +#define IBRT_TWS_PERFORM_USER_ACITON 0xff +#define IBRT_TWS_PERFORM_CONNECT_SECOND_MOBILE 0x01 +#define IBRT_TWS_PERFORM_DISCONNECT_MOBILE_TWS_LINK 0x02 +#define IBRT_TWS_PERFORM_PEER_TWS_SWITCH_DONE 0x03 +#define IBRT_TWS_PERFORM_CHOICE_MOBILE_CONNECT 0x04 +#define IBRT_TWS_PERFORM_AVRCP_NOTIFY_REGISTER 0x05 + +typedef void (*app_tws_cmd_send_handler_t)(uint8_t*, uint16_t); +typedef void (*app_tws_cmd_receivd_handler_t)(uint16_t, uint8_t*, uint16_t); +typedef void (*app_tws_rsp_timeout_handle_t)(uint16_t, uint8_t*, uint16_t); +typedef void (*app_tws_rsp_handle_t)(uint16_t, uint8_t*, uint16_t); +typedef void (*app_tws_cmd_tx_done_handler_t) (uint16_t, uint16_t, uint8_t*, uint16_t); + +typedef struct +{ + uint32_t cmdcode; + const char *log_cmd_code_str; + app_tws_cmd_send_handler_t tws_cmd_send; + app_tws_cmd_receivd_handler_t cmdhandler; /**< command handler function */ + uint32_t timeout_ms; + app_tws_rsp_timeout_handle_t app_tws_rsp_timeout_handle; + app_tws_rsp_handle_t app_tws_rsp_handle; + app_tws_cmd_tx_done_handler_t app_tws_cmd_tx_done_handler; +} __attribute__((packed)) app_tws_cmd_instance_t; + +typedef struct +{ + uint16_t opcode; + uint8_t conhdl_pos; + const char *log_cmd_code_str; +} __attribute__((packed)) app_ibrt_cmd_filter_t; + +typedef struct +{ + uint16_t cmdcode; + uint16_t cmdseq; + uint8_t content[APP_TWS_IBRT_MAX_DATA_SIZE]; +} __attribute__((packed)) app_tws_ibrt_cmd_t; + +void app_ibrt_cmd_handler_init(void); +int app_ibrt_cmd_table_get(void **cmd_tbl, uint16_t *cmd_size); +int app_ibrt_set_cmdhandle(enum CMD_ID_T cmd_id, TWS_CMD_HANDLER_T handler); +void app_ibrt_cmd_rx_handler(uint8_t* p_data_buff, uint16_t length); +void app_ibrt_data_send_handler(void); +void app_ibrt_data_receive_handler(void); +void app_ibrt_cmd_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +bool app_ibrt_send_cmd_without_rsp(uint16_t cmdcode, uint8_t *p_buff, uint16_t length); +void app_ibrt_send_cmd_with_rsp(uint16_t cmdcode, uint8_t *p_buff, uint16_t length); +bool app_ibrt_waiting_cmd_rsp(void); +void app_ibrt_profile_data_exchange_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_send_profiles(void); +void app_ibrt_send_tws_switch_cmd(uint8_t *p_buff, uint16_t length); +void app_ibrt_tws_switch_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_share_tws_info(uint8_t *p_buff, uint16_t length); +void app_ibrt_share_tws_info_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_send_cmd_rsp(uint8_t *p_buff, uint16_t length); +void app_ibrt_inform_start_ibrt_mode(uint8_t *p_buff, uint16_t length); +void app_ibrt_start_ibrt_mode_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_inform_stop_ibrt_mode(uint8_t *p_buff, uint16_t length); +void app_ibrt_stop_ibrt_mode_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_start_ibrt_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_stop_ibrt_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_stop_ibrt_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_start_ibrt_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_set_codec_type_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_set_codec_type_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_share_tws_info_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_share_tws_info_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_data_exchange_rsp_timeout_handler(uint8_t *p_buff, uint16_t length); +void app_ibrt_data_exchange_done(uint8_t *p_buff, uint16_t length); +void app_ibrt_data_exchange_done_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_set_env_cmd(uint8_t *p_buff, uint16_t length); +void app_ibrt_set_env_cmd_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_set_env_cmd_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_set_env_cmd_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_profile_data_req_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_send_profile_data_req(uint8_t *p_buff, uint16_t length); +uint8_t app_ibrt_send_profile_data(uint32_t profile_mask,bool tx_silence); +void app_ibrt_wait_profile_ready_timer_cb(void const *n); +void app_ibrt_delay_profile_send_timer_cb(void const *n); +void app_ibrt_delay_profile_send_timer(uint32_t millisec); +void app_ibrt_wait_profile_ready_timeout_handler(void); +void app_ibrt_profile_ready_notify(uint32_t profile); +uint8_t app_ibrt_profile_check_and_resync(void); +void app_ibrt_sync_profile_init_status(void); +void app_ibrt_fast_ack_req_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_send_fast_ack_req(uint8_t *p_buff, uint16_t length); +void app_ibrt_ibrt_fast_ack_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_fast_ack_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +uint16_t app_ibrt_find_cmd_table_index(uint16_t cmdcode, app_tws_cmd_instance_t **cmd_tbl); +void app_ibrt_transfer_sm(uint8_t *p_buff, uint16_t length); +void app_ibrt_transfer_sm_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_sync_anc_status(uint8_t *p_buff, uint16_t length); +void app_ibrt_sync_anc_status_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_set_interval(uint8_t *p_buff, uint16_t length); +void app_ibrt_set_interval_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_perform_action(uint8_t *p_buff, uint16_t length); +void app_ibrt_perform_action_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_init_tws_trx_cmd_queue(void); +void app_ibrt_reset_tws_trx_cmd_queue(void); +void app_ibrt_new_mobile_incoming(uint8_t *p_buff, uint16_t length); +void app_ibrt_new_mobile_incoming_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_notify_link_policy(uint8_t *p_buff, uint16_t length); +void app_ibrt_notify_link_policy_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_slave_connect_box(uint8_t *p_buff, uint16_t length); +void app_ibrt_slave_connect_box_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_slave_connect_box_rsp(uint8_t *p_buff, uint16_t length); +void app_ibrt_slave_connect_box_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_slave_disconnect_box_rsp(uint8_t *p_buff, uint16_t length); +void app_ibrt_slave_disconnect_box_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_new_mobile_incoming_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_new_mobile_incoming_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_ui_debug_controller_timer_cb(void const *current_evt); +void app_ibrt_recieve_bt_controller_profile_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_send_bt_controller_profile(uint8_t *p_buff, uint16_t input_length); +void app_ibrt_send_snoop_info_send_complete(uint8_t *p_buff, uint16_t length); +void app_ibrt_snoop_info_received_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_sync_volume_info_send(uint8_t *p_buff, uint16_t length); +void app_ibrt_get_volume_info_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_exit_sniff(uint8_t *p_buff, uint16_t length); +void app_ibrt_exit_sniff_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_stop_ibrt_failed(uint8_t *p_buff, uint16_t length); +void app_ibrt_stop_ibrt_failed_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_share_common_info(uint8_t *p_buff, uint16_t length); +void app_ibrt_share_common_info_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_share_common_info_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_share_common_info_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_sync_mix_prompt_req(uint8_t *p_buff, uint16_t length); +void app_ibrt_sync_mix_prompt_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_prompt_play_req_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_prompt_req(uint8_t *p_buff, uint16_t length); +void app_ibrt_stop_peer_prompt_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_stop_peer_prompt_req(uint8_t *p_buff, uint16_t length); +void app_ibrt_pairing_mode_refresh(uint8_t *p_buff, uint16_t length); +void app_ibrt_pairing_mode_refresh_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_let_master_prepare_rs(uint8_t *p_buff, uint16_t length); +void app_ibrt_master_prepare_rs(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_let_slave_continue_rs(uint8_t *p_buff, uint16_t length); +void app_ibrt_slave_continue_rs(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_ai_send_cmd_to_peer(uint8_t *p_buff, uint16_t length); +void app_ibrt_ai_rev_peer_cmd_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_ai_send_cmd_with_rsp_to_peer(uint8_t *p_buff, uint16_t length); +void app_ibrt_ai_rev_cmd_with_rsp_to_peer_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_ai_rev_cmd_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_ai_rev_cmd_rsp_from_peer_hanlder(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_send_mobile_link_playback_info(uint8_t *p_buff, uint16_t length); +void app_ibrt_send_mobile_link_playback_info_handler(uint16_t rsp_seq, uint8_t *ptrParam, uint16_t paramLen); +void app_ibrt_disconnect_mobile(uint8_t *p_buff, uint16_t length); +void app_ibrt_disconnect_mobile_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +#endif + diff --git a/services/ibrt_core/inc/app_tws_ibrt_cmd_sync_a2dp_status.h b/services/ibrt_core/inc/app_tws_ibrt_cmd_sync_a2dp_status.h new file mode 100644 index 0000000..a8ed734 --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ibrt_cmd_sync_a2dp_status.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_IBRT_CMD_SYNC_A2DP_STATUS_H__ +#define __APP_TWS_IBRT_CMD_SYNC_A2DP_STATUS_H__ + +typedef struct +{ + ibrt_codec_t codec; + uint8_t volume; + btif_avdtp_stream_state_t state; + float latency_factor; + uint32_t session; +} __attribute__((packed)) ibrt_a2dp_status_t; + +bool app_ibrt_sync_a2dp_status_onporcess(void); +void app_ibrt_sync_a2dp_status_set(bool status); + +void app_ibrt_sync_a2dp_status(void); +void app_ibrt_sync_a2dp_send_status(uint8_t *p_buff, uint16_t length); +void app_ibrt_sync_a2dp_send_status_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_sync_a2dp_send_status_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +void app_ibrt_sync_a2dp_send_status_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + + +#endif diff --git a/services/ibrt_core/inc/app_tws_ibrt_cmd_sync_hfp_status.h b/services/ibrt_core/inc/app_tws_ibrt_cmd_sync_hfp_status.h new file mode 100644 index 0000000..7ae6777 --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ibrt_cmd_sync_hfp_status.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_IBRT_CMD_SYNC_HFP_STATUS_H__ +#define __APP_TWS_IBRT_CMD_SYNC_HFP_STATUS_H__ + +typedef struct +{ + uint8_t audio_state; + uint8_t volume; + uint8_t lmp_sco_hdl; +} __attribute__((packed)) ibrt_hfp_status_t; + +void app_ibrt_sync_hfp_status(void); + +void app_ibrt_sync_hfp_send_status(uint8_t *p_buff, uint16_t length); + +void app_ibrt_sync_hfp_send_status_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +void app_ibrt_sync_hfp_send_status_rsp_timeout_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +void app_ibrt_sync_hfp_send_status_rsp_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +void app_ibrt_sync_hfp_status_done(uint16_t cmdcode, uint16_t rsp_seq, uint8_t *ptrParam, uint16_t paramLen); + +#endif diff --git a/services/ibrt_core/inc/app_tws_ibrt_mock.h b/services/ibrt_core/inc/app_tws_ibrt_mock.h new file mode 100644 index 0000000..d0cfdcc --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ibrt_mock.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_IBRT_MOCK_H__ +#define __APP_TWS_IBRT_MOCK_H__ + +typedef struct { + uint16_t curr_pkt_sequenceNumber; + uint32_t curr_pkt_timestamp; + uint32_t rcv_pkt_cnt; + uint16_t first_pkt_sequenceNumber; + uint32_t first_pkt_timestamp; + uint32_t bt_clk; + uint32_t bt_cnt; + uint32_t mobile_clk; + uint32_t mobile_cnt; +} A2DP_STREAM_MEDIA_INFO_T; + +int a2dp_stream_media_info_get(A2DP_STREAM_MEDIA_INFO_T *media_info); +int a2dp_stream_media_info_set(A2DP_STREAM_MEDIA_INFO_T *media_info); + +#endif diff --git a/services/ibrt_core/inc/app_tws_ibrt_queue.h b/services/ibrt_core/inc/app_tws_ibrt_queue.h new file mode 100644 index 0000000..a07ce2d --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ibrt_queue.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_BT_QUEUE_H__ +#define __APP_BT_QUEUE_H__ + +typedef struct __ibrt_queue +{ + CQueue queue; + void *mutex; +}ibrt_queue; + +void app_tws_ibrt_queue_init(ibrt_queue* ptrQueue, uint8_t* ptrBuf, uint32_t bufLen); +int app_tws_ibrt_queue_push(ibrt_queue* ptrQueue, uint8_t* ptrData, uint32_t length); +uint16_t app_tws_ibrt_queue_get_next_entry_length(ibrt_queue* ptrQueue); +void app_tws_ibrt_queue_pop(ibrt_queue* ptrQueue, uint8_t *ptrBuf, uint32_t len); +int app_tws_ibrt_dequeue(ibrt_queue *ptrQueue, void *e, unsigned int len); +int app_tws_ibrt_length_queue(ibrt_queue *ptrQueue); + +#endif // __APP_BT_QUEUE_H__ + diff --git a/services/ibrt_core/inc/app_tws_ibrt_trace.h b/services/ibrt_core/inc/app_tws_ibrt_trace.h new file mode 100644 index 0000000..6a0aead --- /dev/null +++ b/services/ibrt_core/inc/app_tws_ibrt_trace.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_IBRT_TRACE_H__ +#define __APP_TWS_IBRT_TRACE_H__ + +#include "hal_trace.h" + +extern const char *g_log_super_state_str[]; + +extern const char *g_log_action_str[]; + +extern const char *g_log_event_str[]; + +extern const char *g_log_status_str[]; + +extern const char *g_log_box_state_str[]; + +extern const char *g_log_link_type_str[]; + +extern const char *g_log_scan_trigger_str[]; + +extern const char *g_log_policy_trigger_str[]; + +extern const char *g_log_pairing_state_str[]; + +extern const char *g_log_error_type_str[]; + +extern const char *g_log_pair_mode_str[]; + +#ifdef ENABLE_COMPRESS_LOG +#define TRACE_VOICE_RPT_D(str, ...) LOG_DEBUG(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][VOICE_RPT][DBG]"str, ##__VA_ARGS__) +#define TRACE_VOICE_RPT_I(str, ...) LOG_INFO(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][VOICE_RPT]"str, ##__VA_ARGS__) +#define TRACE_VOICE_RPT_W(str, ...) LOG_WARN(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][VOICE_RPT][WARN]"str, ##__VA_ARGS__) +#define TRACE_VOICE_RPT_E(str, ...) LOG_ERROR(LOG_ATTR_ARG_NUM(COUNT_ARG_NUM(unused, ##__VA_ARGS__)), "[AUD][VOICE_RPT][ERR]"str, ##__VA_ARGS__) +#else +#define TRACE_VOICE_RPT_D(str, ...) LOG_DEBUG(LOG_MOD(AUDFLG), "[AUD][VOICE_RPT][DBG]"str, ##__VA_ARGS__) +#define TRACE_VOICE_RPT_I(str, ...) LOG_INFO(LOG_MOD(AUDFLG), "[AUD][VOICE_RPT]"str, ##__VA_ARGS__) +#define TRACE_VOICE_RPT_W(str, ...) LOG_WARN(LOG_MOD(AUDFLG), "[AUD][VOICE_RPT][WARN]"str, ##__VA_ARGS__) +#define TRACE_VOICE_RPT_E(str, ...) LOG_ERROR(LOG_MOD(AUDFLG), "[AUD][VOICE_RPT][ERR]"str, ##__VA_ARGS__) +#endif + +#endif diff --git a/services/ibrt_core/inc/app_tws_profile_sync.h b/services/ibrt_core/inc/app_tws_profile_sync.h new file mode 100644 index 0000000..31fc240 --- /dev/null +++ b/services/ibrt_core/inc/app_tws_profile_sync.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_PROFILE_SYNC__ +#define __APP_TWS_PROFILE_SYNC__ + +#include "spp_api.h" + +#define COMMON_DATA_ARRAY_LEN (164) +#define RFC_MUX_DATA_ARRAY_LEN (196) +#define HFP_DATA_ARRAY_LEN (284) +#define A2DP_DATA_ARRAY_LEN (196) +#define A2DP_CONTINUE_DATA_ARRAY_LEN (564) +#define AVRCP_DATA_ARRAY_LEN (612) +#define MAP_DATA_ARRAY_LEN (256) +#define HID_DATA_ARRAY_LEN (256) +#define SPP_DATA_ARRAY_LEN (256) + + +typedef struct +{ + uint8_t common_data[COMMON_DATA_ARRAY_LEN]; + uint8_t rfc_mux_data[RFC_MUX_DATA_ARRAY_LEN]; + uint8_t hfp_data[HFP_DATA_ARRAY_LEN]; + uint8_t a2dp_data[A2DP_DATA_ARRAY_LEN]; + uint8_t a2dp_continue_data[A2DP_CONTINUE_DATA_ARRAY_LEN]; + uint8_t avrcp_data[AVRCP_DATA_ARRAY_LEN]; + uint8_t map_data[MAP_DATA_ARRAY_LEN]; + uint8_t hid_data[HID_DATA_ARRAY_LEN]; + uint8_t spp_data[SPP_DEVICE_NUM][SPP_DATA_ARRAY_LEN]; + + uint16_t common_data_len; + uint16_t rfc_mux_data_len; + uint16_t hfp_data_len; + uint16_t a2dp_data_len; + uint16_t a2dp_continue_data_len; + uint16_t avrcp_data_len; + uint16_t map_data_len; + uint16_t hid_data_len; + uint16_t spp_data_len[SPP_DEVICE_NUM]; + uint32_t app_id[SPP_DEVICE_NUM]; + uint8_t spp_amount; + uint8_t spp_num; +} data_store_mem_t; + + +/* + * Sync tws master's mobile link profile to tws slave + */ +#define APP_TWS_NUM_BT_DEVICES 2 +#define APP_TWS_NUM_KNOWN_DEVICES 10 + + +void app_tws_profile_data_sync(uint8_t *p_buff, uint16_t length); +void app_tws_parse_profile_data(uint8_t *p_buff, uint32_t length); +void app_bt_update_bt_profile_manager(void); +void app_tws_profile_sync_complete_timer_trigger(void); +uint32_t app_tws_profile_data_tx(uint8_t flag,uint8_t *buf); +uint32_t app_tws_profile_data_rx(uint8_t flag,uint8_t *buf,uint32_t length); +void app_tws_profile_data_save_temporarily(uint8_t *p_buff, uint32_t length); +bool app_tws_profile_data_rx_needed(uint8_t profile_flag); +bool app_tws_profile_data_rx_completed(uint8_t final_flag); +void app_tws_profile_rx_parse(void); +uint8_t app_tws_profile_data_tx_filter(uint32_t profile_mask,uint8_t data_array[][2]); +bool app_tws_profile_data_tx_allowed(void); +bool app_tws_profile_connecting(void); +uint32_t app_tws_profile_mapping_data_fragment(uint8_t flag); +void ibrt_app_wait_data_send_to_peer_timeout_handler(void const *param); +void app_tws_profile_resume_a2dp_hfp(void); + +#endif + diff --git a/services/ibrt_core/inc/app_vendor_cmd_evt.h b/services/ibrt_core/inc/app_vendor_cmd_evt.h new file mode 100644 index 0000000..5d6e5d0 --- /dev/null +++ b/services/ibrt_core/inc/app_vendor_cmd_evt.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_VENDOR_EVT__ +#define __APP_VENDOR_EVT__ + +#define GET_HCI_HANDLE(ptr) ((unsigned short)(((unsigned short) *((ptr)+1) << 8) | ((unsigned short) *(ptr)))) + + + +//Sub code of Vendor event +#define HCI_DBG_TRACE_WARNING_EVT_CODE 0x01 +#define HCI_SCO_SNIFFER_STATUS_EVT_CODE 0x02 +#define HCI_ACL_SNIFFER_STATUS_EVT_CODE 0x03 +#define HCI_TWS_EXCHANGE_CMP_EVT_CODE 0x04 +#define HCI_NOTIFY_CURRENT_ADDR_EVT_CODE 0x05 +#define HCI_START_SWITCH_EVT_CODE 0x09 +#define HCI_LL_MONITOR_EVT_CODE 0x0A +#define HCI_DBG_LMP_MESSAGE_RECORD_EVT_SUBCODE 0x0B +#define HCI_GET_TWS_SLAVE_MOBILE_RSSI_CODE 0x0C +#define HCI_DBG_IBRT_SWITCH_COMPLETE_EVT_SUBCODE 0x0D +#define HCI_DBG_IBRT_CONNECTED_EVT_SUBCODE 0x0E +#define HCI_DBG_IBRT_DISCONNECTED_EVT_SUBCODE 0x0f +#define HCI_DBG_SNIFFER_INIT_CMP_EVT_SUBCODE 0x10 +#define HCI_DBG_RX_SEQ_ERROR_EVT_SUBCODE 0x11 +#define HCI_DBG_FA_TO_EVT_SUBCODE 0x14 +#define HCI_DBG_ECC_DATA_TEST_EVT_SUBCODE 0x15 +#define HCI_DBG_FRMERRIND_EVT_SUBCODE 0x16 +#define HCI_DBG_PKTERRIND_EVT_SUBCODE 0x17 + + +void app_hci_vendor_event_callback_init(void); +void app_hci_vendor_event_handler(uint8_t* pbuf, uint32_t length); +void btapp_sniffer_sco_start(uint16_t conhdl,uint8_t sco_status,uint8_t airmode,uint32_t bandwidth); +void btapp_sniffer_ibrt_op(uint16_t conhdl, uint8_t op, uint8_t status, uint8_t reason); +void app_ibrt_ui_rx_seq_error_handling_timer_cb(void const *current_evt); +void app_hci_vender_ibrt_disconnected_handle(uint8_t disc_reason); +void app_hci_vender_ibrt_fastack_to_handle(uint16_t mobile_conhdl); +#endif diff --git a/services/ibrt_ota/Makefile b/services/ibrt_ota/Makefile new file mode 100644 index 0000000..3ff20c3 --- /dev/null +++ b/services/ibrt_ota/Makefile @@ -0,0 +1,118 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.c)) + +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.cpp)) + +src_obj := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +IBRT_OTA_LIB_NAME := lib_ibrt_ota +ifeq ($(BLE), 1) +IBRT_OTA_LIB_NAME := $(IBRT_OTA_LIB_NAME)_ble +endif + +ifeq ($(KERNEL),RTX) +IBRT_OTA_LIB_NAME := $(IBRT_OTA_LIB_NAME)_RTX +endif +ifeq ($(KERNEL),RTX5) +IBRT_OTA_LIB_NAME := $(IBRT_OTA_LIB_NAME)_RTX5 +endif + +$(IBRT_OTA_LIB_NAME)-y := $(src_obj) + +obj-y += $(IBRT_OTA_LIB_NAME).a + +subdir-ccflags-y += -Iplatform/drivers/ana \ + -Iplatform/hal \ + -Iservices/bluedroid/adapter/src \ + -Iapps/key \ + -Iservices/audio_eq \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + $(BT_IF_INCLUDES) \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/nv_section/factory_section \ + -Iservices/resources \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iplatform/drivers/main \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iutils/retention_ram \ + -Iservices/audioflinger \ + -Iservices/app_ai/inc \ + -Iutils/lockcqueue \ + -Iutils/hwtimer_list/ \ + -Iutils/intersyshci \ + -Iutils/boot_struct \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/factory \ + -Iapps/ota \ + -Iservices/ble_app \ + -Iservices/ble_app/app_ota \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/bridge/ \ + -Iservices/ble_stack/hl/src/gap/ \ + -Iservices/ble_stack/hl/src/gap/gapc/ \ + -Iservices/ble_stack/hl/src/gap/gapm/ \ + -Iservices/ble_stack/hl/src/gap/smpc/ \ + -Iservices/ble_stack/ke/src/ \ + -Iservices/ble_stack/hl/src/gatt/attc/ \ + -Iservices/ble_stack/hl/src/gatt/attm/ \ + -Iservices/ble_stack/hl/src/gatt/atts/ \ + -Iservices/ble_stack/hl/src/gatt/gattc/ \ + -Iservices/ble_stack/hl/src/gatt/gattm/ \ + -Iservices/ble_stack/hl/src/gatt/ \ + -Iservices/ble_stack/hl/src/l2c/l2cc/ \ + -Iservices/ble_stack/hl/src/l2c/l2cm/ \ + -Iservices/ble_stack/hci/api/ \ + -Iservices/ble_stack/hci/src/ \ + -Iservices/ble_stack/app/src/ \ + -Iservices/ble_profiles/htp/htpt/api/ \ + -Iservices/ble_profiles/htp/htpt/src/ \ + -Iservices/ble_profiles/htp/ \ + -Iservices/ble_profiles/datapath/datapathps/api/ \ + -Iservices/ble_app/app_main/ \ + -Iservices/ble_app/app_htp/ \ + -Iservices/ble_app/app_datapath/ \ + -Iservices/bt_app \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/ble_app/app_vob \ + -Iservices/multimedia/speech/codec/codecs/adpcm \ + -Iservices/ble_app/app_smartvoice \ + -Iservices/ble_profiles/smartvoice \ + -Iservices/anc_spp_tool \ + -Iutils/crc32 \ + -Ithirdparty/userapi \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/norflash_api + +ifeq ($(OTA_ENABLE),1) +subdir-ccflags-y += \ + -Iservices/ibrt_ota/inc +endif + +ifeq ($(IBRT),1) +subdir-ccflags-y += \ + -Iservices/ibrt_ui/inc \ + -Iservices/ibrt_core/inc \ + -Iservices/app_ibrt/inc \ + -Iservices/bt_app +endif + +ifneq ($(OTA_CODE_OFFSET),0) +CFLAGS_ota_control.o += -DOTA_CODE_OFFSET=$(OTA_CODE_OFFSET) +endif diff --git a/services/ibrt_ota/inc/ota_bes.h b/services/ibrt_ota/inc/ota_bes.h new file mode 100644 index 0000000..355e4cf --- /dev/null +++ b/services/ibrt_ota/inc/ota_bes.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_OTA_H__ +#define __APP_OTA_H__ + +#define APP_OTA_CONNECTED (1 << 0) +#define APP_OTA_DISCONNECTED (~(1 << 0)) + +#ifdef __cplusplus +extern "C" { +#endif + +void app_ota_connected(uint8_t connType); +void app_ota_disconnected(uint8_t disconnType); +bool app_is_in_ota_mode(void); +void bes_ota_init(void); + +#define BES_OTA_UUID_128 {0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 } + +#if (BLE_OTA) +#define ota_val_char_val_uuid_128_content {0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77 } +#define ATT_DECL_PRIMARY_SERVICE_UUID { 0x00, 0x28 } +#define ATT_DECL_CHARACTERISTIC_UUID { 0x03, 0x28 } +#define ATT_DESC_CLIENT_CHAR_CFG_UUID { 0x02, 0x29 } +#endif +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/ibrt_ota/inc/ota_control.h b/services/ibrt_ota/inc/ota_control.h new file mode 100644 index 0000000..ec59555 --- /dev/null +++ b/services/ibrt_ota/inc/ota_control.h @@ -0,0 +1,426 @@ +#ifndef _OTA_CONTROL_H_ +#define _OTA_CONTROL_H_ + +#include "co_bt_defines.h" + +#define LOG_TAG "[OTA_CONTROL] " + +#define OTA_BES_CONTROL_DEBUG + +#ifdef OTA_BES_CONTROL_DEBUG +#define LOG_DBG(num,str,...) TRACE(num,LOG_TAG""str, ##__VA_ARGS__) // DEBUG OUTPUT +#define LOG_MSG(num,str,...) TRACE(num,LOG_TAG""str, ##__VA_ARGS__) // MESSAGE OUTPUT +#define LOG_ERR(num,str,...) TRACE(num,LOG_TAG"err:"""str, ##__VA_ARGS__) // ERROR OUTPUT + +#define LOG_FUNC_LINE() TRACE(2,LOG_TAG"%s:%d\n", __FUNCTION__, __LINE__) +#define LOG_FUNC_IN() TRACE(1,LOG_TAG"%s ++++\n", __FUNCTION__) +#define LOG_FUNC_OUT() TRACE(1,LOG_TAG"%s ----\n", __FUNCTION__) + +#define LOG_DUMP DUMP8 +#else +#define LOG_DBG(num,str,...) +#define LOG_MSG(num,str,...) TRACE(num,LOG_TAG""str, ##__VA_ARGS__) +#define LOG_ERR(num,str,...) TRACE(num,LOG_TAG"err:"""str, ##__VA_ARGS__) + +#define LOG_FUNC_LINE() +#define LOG_FUNC_IN() +#define LOG_FUNC_OUT() + +#define LOG_DUMP +#endif + +#define ERASE_LEN_UNIT 4096 + +#define OTA_SW_VERSION 1 +#define OTA_HW_VERSION 1 + +#define DATA_PATH_BLE 1 +#define DATA_PATH_SPP 2 + +#ifndef NORMAL_BOOT +#define NORMAL_BOOT 0xBE57EC1C +#endif +#ifndef COPY_NEW_IMAGE +#define COPY_NEW_IMAGE 0x5a5a5a5a +#endif + +#define OTA_TWS_INFO_SIZE 128 + +#define OTA_BUF_SIZE 1024 + +#define OTA_WATCH_DOG_PING_TIMER_ID 0 + +#ifndef NEW_IMAGE_FLASH_OFFSET +#define NEW_IMAGE_FLASH_OFFSET 0x180000 +#endif + +#define OTA_FLASH_LOGIC_ADDR (FLASH_NC_BASE) + +#define DATA_ACK_FOR_SPP_DATAPATH_ENABLED 1 +#define PUYA_FLASH_ERASE_LIMIT 0 + +#define OTA_RS_INFO_MASTER_SEND_RS_REQ_CMD 1 +#define OTA_RS_INFO_MASTER_DISCONECT_CMD 2 +#define OTAUPLOG_HEADSIZE (sizeof(otaUpgradeLog.randomCode) + sizeof(otaUpgradeLog.totalImageSize) + sizeof(otaUpgradeLog.crc32OfImage)) +#define FLASH_SECTOR_SIZE_IN_BYTES 4096 +#define OTA_OFFSET 0x1000 +#define OTA_INFO_IN_OTA_BOOT_SEC (FLASHX_BASE+OTA_OFFSET) +#define OTA_DATA_BUFFER_SIZE_FOR_BURNING FLASH_SECTOR_SIZE_IN_BYTES + +#define BES_OTA_START_MAGIC_CODE 0x54534542 // BEST + +#define BES_OTA_NAME_LENGTH 32 +#define BES_OTA_BLE_DATA_PACKET_MAX_SIZE 512 +#define BES_OTA_BT_DATA_PACKET_MAX_SIZE L2CAP_MTU + +#define IMAGE_RECV_FLASH_CHECK 1 // It's best to turn it on durning development and not a big deal off in the release. + +#define MAX_IMAGE_SIZE ((uint32_t)(NEW_IMAGE_FLASH_OFFSET - __APP_IMAGE_FLASH_OFFSET__)) + +#define MIN_SEG_ALIGN 256 +typedef void (*ota_transmit_data_t)(uint8_t* ptrData, uint32_t dataLen); +typedef void (*ota_transmission_done_t)(void); + +enum +{ + OTA_RESULT_ERR_RECV_SIZE = 2, + OTA_RESULT_ERR_FLASH_OFFSET, + OTA_RESULT_ERR_SEG_VERIFY, + OTA_RESULT_ERR_BREAKPOINT, + OTA_RESULT_ERR_IMAGE_SIZE, +}; + +/** + * @brief The format of the start OTA control packet + * + */ +typedef struct +{ + uint8_t packetType; // should be OTA_COMMAND_START + uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE + uint32_t imageSize; // total image size + uint32_t crc32OfImage; // crc32 of the whole image +} __attribute__ ((__packed__)) OTA_CONTROL_START_T; + +/** + * @brief The format of the start OTA response packet + * + */ +typedef struct +{ + uint8_t packetType; // should be OTA_RSP_START + uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE + uint16_t swVersion; + uint16_t hwVersion; + uint16_t MTU; // MTU exchange result, central will send images in the unit of MTU +} __attribute__ ((__packed__)) OTA_START_RSP_T; + +typedef struct +{ + uint32_t lengthOfFollowingData; + uint32_t startLocationToWriteImage; // the offset of the flash to start writing the image + uint32_t isToClearUserData : 1; + uint32_t isToRenameBT : 1; + uint32_t isToRenameBLE : 1; + uint32_t isToUpdateBTAddr : 1; + uint32_t isToUpdateBLEAddr : 1; + uint32_t reserve : 27; + uint8_t newBTName[BES_OTA_NAME_LENGTH]; + uint8_t newBLEName[BES_OTA_NAME_LENGTH]; + uint8_t newBTAddr[BD_ADDR_LEN]; + uint8_t newBLEAddr[BD_ADDR_LEN]; + uint32_t crcOfConfiguration; // CRC of data from lengthOfFollowingData to newBLEAddr +} __attribute__ ((__packed__)) OTA_FLOW_CONFIGURATION_T; + +/** + * @brief The format of the start OTA control packet + * + */ +typedef struct +{ + uint8_t packetType; // should be OTA_COMMAND_CONFIG_OTA + OTA_FLOW_CONFIGURATION_T config; +} __attribute__ ((__packed__)) OTA_COMMAND_CONFIG_T; + +/** + * @brief The format of the OTA configuration response packet + * + */ +typedef struct +{ + uint8_t packetType; // should be OTA_RSP_CONFIG + uint8_t isConfigurationDone; // 1 if the configuration has been done successfully, otherwise, 0 +} __attribute__ ((__packed__)) OTA_RSP_CONFIG_T; + + +/** + * @brief The format of the segment verification request + * + */ +typedef struct +{ + uint8_t packetType; // should be OTA_COMMAND_SEGMENT_VERIFY + uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE + uint32_t crc32OfSegment; // crc32 of the 1% segment +} __attribute__ ((__packed__)) OTA_CONTROL_SEGMENT_VERIFY_T; + +/** + * @brief The format of the segment verification request + * + */ +typedef struct +{ + uint8_t packetType; // should be OTA_RSP_SEGMENT_VERIFY + uint8_t isVerificationPassed; +} __attribute__ ((__packed__)) OTA_RSP_SEGMENT_VERIFY_T; + + +/** + * @brief The format of the OTA result response + * + */ +typedef struct +{ + uint8_t packetType; // should be OTA_RSP_RESULT + uint8_t isVerificationPassed; +} __attribute__ ((__packed__)) OTA_RSP_OTA_RESULT_T; + +/** + * @brief The format of the OTA reading flash content command + * + */ +typedef struct +{ + uint8_t packetType; // should be OTA_READ_FLASH_CONTENT + uint8_t isToStart; // true to start, false to stop + uint32_t startAddr; + uint32_t lengthToRead; +} __attribute__ ((__packed__)) OTA_READ_FLASH_CONTENT_REQ_T; + +/** + * @brief The format of the OTA reading flash content command + * + */ +typedef struct +{ + uint8_t packetType; // should be OTA_READ_FLASH_CONTENT + uint8_t isReadingReqHandledSuccessfully; +} __attribute__ ((__packed__)) OTA_READ_FLASH_CONTENT_RSP_T; + +typedef struct +{ + uint8_t packetType; // should be OTA_CONTROL_RESUME_VERIFY + uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE + uint8_t randomCode[32]; + uint32_t segmentSize; + uint32_t crc32; // CRC32 of randomCode and segment size +} __attribute__ ((__packed__)) OTA_CONTROL_RESUME_VERIFY_T; + +typedef struct +{ + uint8_t packetType; // should be OTA_RSP_RESUME_VERIFY + uint32_t breakPoint; + uint8_t randomCode[32]; + uint32_t crc32; // CRC32 of breakPoint and randomCode +} __attribute__ ((__packed__)) OTA_RSP_RESUME_VERIFY_T; + +typedef struct +{ + uint8_t packetType; // should be + uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE +} __attribute__ ((__packed__)) OTA_GET_VERSION_REQ_T; + +typedef struct +{ + uint8_t packetType; // should be + uint32_t magicCode; + uint8_t deviceType; + uint8_t leftVersion[4]; //or stereo version + uint8_t rightVersion[4]; //stereo not needed +} __attribute__ ((__packed__)) OTA_RSP_OTA_VERSION_T; + +typedef struct +{ + uint8_t packetType; // should be + uint8_t success; +} __attribute__ ((__packed__)) OTA_RSP_SELECTION_T; + + +typedef struct +{ + uint8_t packetType; // should be + uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE +} __attribute__ ((__packed__)) OTA_FORCE_REBOOT_T; + +typedef struct +{ + uint8_t packetType; // should be + uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE +} __attribute__ ((__packed__)) OTA_IMAGE_APPLY_REQ_T; + +typedef struct +{ + uint8_t packetType; // should be + uint8_t success; +} __attribute__ ((__packed__)) OTA_RSP_APPLY_T; + +typedef struct +{ + uint8_t packetType; +} __attribute__ ((__packed__)) OTA_START_ROLE_SWITCH_T; + +typedef struct +{ + uint8_t packetType; +} __attribute__ ((__packed__)) OTA_ROLE_SWITCH_COMPLETE_T; + +/** + * @brief The OTA handling data structure + * + */ +typedef struct +{ + uint8_t* dataBufferForBurning; + uint32_t dstFlashOffsetForNewImage; + uint32_t offsetInDataBufferForBurning; + uint32_t offsetInFlashToProgram; + uint32_t totalImageSize; + uint32_t alreadyReceivedDataSizeOfImage; + uint32_t offsetInFlashOfCurrentSegment; + uint32_t offsetOfImageOfCurrentSegment; + uint32_t crc32OfImage; + uint32_t crc32OfSegment; + uint8_t isOTAInProgress; + uint8_t isPendingForReboot; + uint32_t flasehOffsetOfUserDataPool; + uint32_t flasehOffsetOfFactoryDataPool; + + // configuration of the OTA + OTA_FLOW_CONFIGURATION_T configuration; + uint32_t AlreadyReceivedConfigurationLength; + + uint16_t dataPacketSize; + ota_transmit_data_t transmitHander; + uint32_t offsetInFlashToRead; + uint32_t leftSizeOfFlashContentToRead; + + uint8_t dataPathType; + + bool resume_at_breakpoint; + uint32_t breakPoint; + uint32_t i_log; +} OTA_CONTROL_ENV_T; + +typedef struct +{ + uint32_t magicNumber; // NORMAL_BOOT or COPY_NEW_IMAGE + uint32_t imageSize; + uint32_t imageCrc; +} FLASH_OTA_BOOT_INFO_T; + +typedef struct +{ + uint8_t randomCode[32]; + uint32_t totalImageSize; + uint32_t crc32OfImage; + uint32_t upgradeSize[(ERASE_LEN_UNIT - 32 - 2*sizeof(uint32_t)) / 4]; +}FLASH_OTA_UPGRADE_LOG_FLASH_T; + +/** + * @brief The control packet type + * + */ +typedef enum +{ + OTA_COMMAND_START = 0x80, // from central to device, to let OTA start + OTA_RSP_START, // from device to centrl, to let it know that it has been ready for OTA + OTA_COMMAND_SEGMENT_VERIFY, // from central to device, sent per 1% of image, inform device to do CRC check on those 1% + OTA_RSP_SEGMENT_VERIFY, + OTA_RSP_RESULT, + OTA_DATA_PACKET, + OTA_COMMAND_CONFIG_OTA, // from central to device, to configure the following OTA flow + OTA_RSP_CONFIG, + OTA_COMMAND_GET_OTA_RESULT, + OTA_READ_FLASH_CONTENT, + OTA_FLASH_CONTENT_DATA = 0x8A, + OTA_DATA_ACK, + OTA_COMMAND_RESUME_VERIFY, + OTA_RSP_RESUME_VERIFY, + OTA_COMMAND_GET_VERSION, + OTA_RSP_VERSION, + OTA_COMMAND_SIDE_SELECTION = 0x90, + OTA_RSP_SIDE_SELECTION, + OTA_COMMAND_IMAGE_APPLY, + OTA_RSP_IMAGE_APPLY, + OTA_RSP_START_ROLE_SWITCH = 0x95, + OTA_RSP_ROLE_SWITCH_COMPLETE, +} OTA_CONTROL_PACKET_TYPE_E; + +typedef struct +{ + uint8_t typeCode; + uint16_t rsp_seq; + uint16_t length; + uint8_t p_buff[OTA_TWS_INFO_SIZE]; +}OTA_IBRT_TWS_CMD_EXECUTED_RESULT_FROM_SLAVE_T; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Format of the data xfer handler function, to send data to central + * + * @param ptrData Pointer of the data to send + * @param dataLen Length of the data to send + * + */ + +extern void app_ibrt_ota_segment_crc_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +extern void app_ibrt_ota_start_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +extern void app_ibrt_ota_config_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +extern void app_ibrt_ota_image_crc_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +extern void app_ibrt_ota_get_version_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +extern void app_ibrt_ota_select_side_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); +extern void app_ibrt_ota_image_overwrite_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length); + +void ota_control_register_transmitter(ota_transmit_data_t transmit_handle); +void ota_control_update_MTU(uint16_t mtu); +void ota_update_info(void); +void ota_check_and_reboot_to_use_new_image(void); +void ota_control_reset_env(void); +void ota_execute_the_final_operation(void); +bool ota_is_in_progress(void); +void ota_control_set_datapath_type(uint8_t datapathType); +void ibrt_ota_send_start_response(bool isViaBle); +void ibrt_ota_send_configuration_response(bool isDone); +void ota_control_image_apply_rsp(uint8_t success); +void ibrt_ota_send_segment_verification_response(bool isPass); +void ibrt_ota_send_result_response(uint8_t isSuccessful); +void ota_randomCode_log(uint8_t randomCode[]); +void ota_control_send_resume_response(uint32_t breakPoint, uint8_t randomCode[]); +void ota_bes_handle_received_data(uint8_t *otaBuf, bool isViaBle,uint16_t dataLenth); +void ota_ibrt_handle_received_data(uint8_t *otaBuf, bool isViaBle, uint16_t len); +void ota_control_side_selection_rsp(uint8_t success); +uint8_t ota_control_get_datapath_type(void); +uint32_t app_get_magic_number(void); +void ota_flash_init(void); +void Bes_exit_ota_state(void); +void ibrt_ota_send_version_rsp(void); +void ota_upgradeLog_destroy(void); +void ota_status_change(bool status); +void ota_control_send_start_role_switch(void); +void ota_control_send_role_switch_complete(void); +uint8_t app_get_bes_ota_state(void); +bool app_check_is_ota_role_switch_initiator(void); +void app_set_ota_role_switch_initiator(bool is_initiate); +void bes_ota_send_role_switch_req(void); +void app_statistics_get_ota_pkt_in_role_switch(void); +bool app_check_user_can_role_switch_in_ota(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/ibrt_ota/inc/ota_spp.h b/services/ibrt_ota/inc/ota_spp.h new file mode 100644 index 0000000..0693ca3 --- /dev/null +++ b/services/ibrt_ota/inc/ota_spp.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_SPP_OTA_H__ +#define __APP_SPP_OTA_H__ + +#include "spp_api.h" +#include "sdp_api.h" +#include "ota_control.h" + +#if defined(__3M_PACK__) +#define L2CAP_MTU 980 +#else +#define L2CAP_MTU 672 +#endif + +#define OTA_SPP_MAX_PACKET_SIZE L2CAP_MTU +#define OTA_SPP_MAX_PACKET_NUM 5 + +#define OTA_SPP_RECV_BUFFER_SIZE L2CAP_MTU + +#define OTA_SPP_TX_BUF_SIZE (OTA_SPP_MAX_PACKET_SIZE*OTA_SPP_MAX_PACKET_NUM) + +#define APP_OTA_DATA_CMD_TIME_OUT_IN_MS 5000 + +typedef struct { + uint8_t otaSppTxBuf[OTA_SPP_TX_BUF_SIZE]; + uint8_t otaSppRxBuf[OTA_SPP_RECV_BUFFER_SIZE]; + btif_sdp_record_t *ota_sdp_record; + spp_service *otaSppService; + spp_device *ota_spp_dev; + bool permissionToApply; +} OtaContext; + +typedef void(*app_spp_ota_tx_done_t)(void); +void app_spp_ota_register_tx_done(app_spp_ota_tx_done_t callback); +void app_spp_ota_init(void); +void app_ota_send_cmd_via_spp(uint8_t* ptrData, uint16_t length); +void app_ota_send_data_via_spp(uint8_t* ptrData, uint32_t length); + +uint16_t app_spp_ota_tx_buf_size(void); +void app_spp_ota_init_tx_buf(uint8_t* ptr); +uint8_t* app_spp_ota_fill_data_into_tx_buf(uint8_t* ptrData, uint32_t dataLen); +void ota_disconnect(void); + + +#endif + diff --git a/services/ibrt_ui/Makefile b/services/ibrt_ui/Makefile new file mode 100644 index 0000000..0328482 --- /dev/null +++ b/services/ibrt_ui/Makefile @@ -0,0 +1,87 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.c)) + +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.cpp)) + +src_obj := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +IBRT_LIB_NAME := libtws_ibrt + +ifeq ($(ENHANCED_STACK),1) +IBRT_LIB_NAME := $(IBRT_LIB_NAME)_enhanced_stack +endif + +ifeq ($(BLE), 1) +IBRT_LIB_NAME := $(IBRT_LIB_NAME)_ble +endif + +ifeq ($(KERNEL),RTX) +IBRT_LIB_NAME := $(IBRT_LIB_NAME)_RTX +endif +ifeq ($(KERNEL),RTX5) +IBRT_LIB_NAME := $(IBRT_LIB_NAME)_RTX5 +endif + +$(IBRT_LIB_NAME)-y := $(src_obj) + +obj-y := $(IBRT_LIB_NAME).a + +subdir-ccflags-y += \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iservices/multimedia/audio/process/resample/include \ + $(BT_IF_INCLUDES) \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iapps/key \ + -Iapps/main \ + -Iapps/battery \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/audioplayers/a2dp_decoder \ + -Iapps/factory \ + -Iservices/ai_voice/manager \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/common/api \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/hl/inc \ + -Iservices/ble_stack/ke/api \ + -Iservices/ble_app \ + -Iservices/ble_app/app_datapath \ + -Iservices/ble_app/app_tws \ + -Iservices/ble_app/app_main \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/osif \ + -Iservices/nv_section/factory_section \ + -Iservices/nv_section/log_section \ + -Iservices/app_ibrt/inc \ + -Iservices/bt_app/a2dp_codecs/include \ + -Ithirdparty/audio_codec_lib/liblhdc-dec/inc \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iutils/hwtimer_list \ + -Iservices/voicepath \ + -Iservices/app_tws/inc \ + -Iservices/app_ai/inc \ + -Iservices/ai_voice/protocol/gma/gma_crypto \ + -Iservices/ibrt_ota/inc + +ifeq ($(IBRT),1) +subdir-ccflags-y += \ + -Iservices/ibrt_core/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/bt_app +endif + diff --git a/services/ibrt_ui/inc/app_ibrt_ui.h b/services/ibrt_ui/inc/app_ibrt_ui.h new file mode 100644 index 0000000..ea382fc --- /dev/null +++ b/services/ibrt_ui/inc/app_ibrt_ui.h @@ -0,0 +1,779 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TWS_IBRT_UI__ +#define __APP_TWS_IBRT_UI__ +#include "app_tws_ibrt.h" +#include "cmsis_os.h" +#include "bt_drv_reg_op.h" +#include "app_tws_ibrt_cmd_handler.h" + +#define SNOOP_INFO_DATA_HEADER 0XE1D2C3B4 +#define SNOOP_INFO_DATA_HEADER_LENGTH 4 +#define SNOOP_INFO_DATA_LENGTH_MAX 512 +#define SNOOP_SCAN_WINDOW_IN_MS 30 +#define SNOOP_SCAN_INTERVAL_IN_MS 60 +#define SNOOP_ADV_INTERVAL_IN_MS 20 + +#define IBRT_EVENT_Q_LENGTH (20) +#define MSS_RETRY_COUNTER_MAX (10) + +#define IBRT_UI_STOP_IBRT 1 +#define IBRT_UI_CONNECT_EVT(evt) ((evt == BTIF_BTEVENT_LINK_CONNECT_CNF)|| \ + (evt == BTIF_BTEVENT_LINK_CONNECT_IND)|| \ + (evt == BTIF_BTEVENT_ENCRYPTION_CHANGE)) + +#define IBRT_UI_DISCONNECT_EVT(evt) (evt == BTIF_STACK_LINK_DISCONNECT_COMPLETE) +#define IBRT_UI_INVALID_RSSI (100) + +#define IBRT_UI_MIN_RSSI (-100) +#define IBRT_UI_BLE_ADV_THRESHOLD (60000)//ms +/* + * IBRT UI event + */ +typedef uint8_t ibrt_controller_error_type; +#define IBRT_PEER_SM_RUNNING_TIMEOUT (0) +#define IBRT_CONTROLLER_TWS_NO_03 (1) +#define IBRT_CONTROLLER_MOBILE_NO_03 (2) +#define IBRT_CONTROLLER_TWS_NO_05 (3) +#define IBRT_CONTROLLER_MOBILE_NO_05 (4) +#define IBRT_CONTROLLER_DEAD (5) +#define IBRT_CONTROLLER_RX_SEQ_ERROR (6) +#define IBRT_MOBILE_ENCRYP_ERROR (7) +#define IBRT_TWS_BESAUD_CONNECT_ERROR (8) + +/* + * IBRT UI event + */ +#define IBRT_EVENT_TYPE_MASK (0X7F) +#define IBRT_SKIP_FALSE_TRIGGER_MASK (0x80) +typedef uint8_t ibrt_event_type; +#define IBRT_NONE_EVENT (0) +#define IBRT_OPEN_BOX_EVENT (1) +#define IBRT_FETCH_OUT_EVENT (2) +#define IBRT_PUT_IN_EVENT (3) +#define IBRT_CLOSE_BOX_EVENT (4) + +#define IBRT_WEAR_UP_EVENT (5) +#define IBRT_WEAR_DOWN_EVENT (6) + +#define IBRT_RECONNECT_EVENT (7) +#define IBRT_PHONE_CONNECT_EVENT (8) +#define IBRT_TRANSFER_EVENT (9) +#define IBRT_NEW_MOBILE_INCOMING_EVENT (10) + +//transfer event type +#define IBRT_PEER_OPEN_BOX_EVENT (11) +#define IBRT_PEER_FETCH_OUT_EVENT (12) +#define IBRT_PEER_WEAR_UP_EVENT (13) +#define IBRT_PEER_RECONNECT_EVENT (14) + +#define IBRT_TWS_SWITCH_EVENT (15) +#define IBRT_TWS_PAIRING_EVENT (16) +#define IBRT_FREEMAN_PAIRING_EVENT (17) +#define IBRT_CONNECT_SECOND_MOBILE_EVENT (18) +#define IBRT_DISCONNECT_MOBILE_TWS_EVENT (19) +#define IBRT_RX_SEQ_ERROR_RECOVER_EVENT (20) +#define IBRT_PROFILE_DATA_UPDATE_EVENT (21) +#define IBRT_TWS_CONNECT_SYNC_INFO_EVENT (22) +#define IBRT_CHOICE_MOIBLE_CONNECT_EVENT (23) + +#define IBRT_IS_RECONNECT_EVENT(event) ((event == IBRT_RECONNECT_EVENT) || (event == IBRT_PEER_RECONNECT_EVENT)) +#define IBRT_RECONNECT_EVENT_TYPE(event) ((event == IBRT_RECONNECT_EVENT) || (event == IBRT_PEER_RECONNECT_EVENT)) +#define IBRT_CONNECT_MOBILE_EVENT(event) ((event == IBRT_OPEN_BOX_EVENT)||(event == IBRT_FETCH_OUT_EVENT)|| \ + (event == IBRT_WEAR_UP_EVENT) ||(event == IBRT_PEER_OPEN_BOX_EVENT)|| \ + (event == IBRT_PEER_FETCH_OUT_EVENT) || (event == IBRT_PEER_WEAR_UP_EVENT) || \ + (event == IBRT_RECONNECT_EVENT)) + +#define IBRT_IS_TRANSFER_EVENT(event) ((event == IBRT_PEER_OPEN_BOX_EVENT) || (event == IBRT_PEER_FETCH_OUT_EVENT) || \ + (event == IBRT_PEER_WEAR_UP_EVENT) || (event == IBRT_TRANSFER_EVENT)) + +#define IBRT_RECONNECT_EVENT_QUEUED() (app_ibrt_ui_event_has_been_queued(IBRT_RECONNECT_EVENT) || app_ibrt_ui_event_has_been_queued(IBRT_PEER_RECONNECT_EVENT)) +#define IBRT_TRANSFER_EVENT_FILTER(event) (IBRT_IS_TRANSFER_EVENT(event) && app_ibrt_ui_event_has_been_queued(event)) +#define IBRT_RECONNECT_EVENT_FILTER(event) (IBRT_RECONNECT_EVENT_TYPE(event) && IBRT_RECONNECT_EVENT_QUEUED()) + +#define IBRT_UI_RADICAL_SAN_INTERVAL_BY_NV_ROLE ((app_tws_ibrt_get_bt_ctrl_ctx()->nv_role) ? \ + app_ibrt_ui_get_ctx()->config.radical_scan_interval_nv_slave : \ + app_ibrt_ui_get_ctx()->config.radical_scan_interval_nv_master) + +#define IBRT_BOTH_HEADSET_WEARED(p_ibrt_ui) ((p_ibrt_ui->box_state == IBRT_OUT_BOX_WEARED) && \ + (p_ibrt_ui->peer_tws_info.box_state == IBRT_OUT_BOX_WEARED) && \ + p_ibrt_ui->config.wear_updown_detect_supported) + +typedef uint8_t ibrt_box_state; +/* + * BOX state + */ +#define IBRT_BOX_UNKNOWN (0) +#define IBRT_IN_BOX_CLOSED (1) +#define IBRT_IN_BOX_OPEN (2) +#define IBRT_OUT_BOX (3) +#define IBRT_OUT_BOX_WEARED (4) +/* + * BOX connect state + */ +#define IBRT_BOX_CONNECT_IDLE (0) +#define IBRT_BOX_CONNECT_MASTER (1<<0) +#define IBRT_BOX_CONNECT_SLAVE (1<<1) + +//HCI opcode +#define IBRT_HCI_CREATE_CON_CMD_OPCODE 0x0405 +#define IBRT_HCI_EXIT_SNIFF_MODE_CMD_OPCODE 0x0804 +#define IBRT_HCI_SWITCH_ROLE_CMD_OPCODE 0x080B +#define IBRT_HCI_STOP_IBRT_OPCODE 0xFCA8 +#define IBRT_HCI_START_IBRT_OPCODE 0xFCA3 +#define IBRT_HCI_RESET_OPCODE 0x0C03 +#define IBRT_HCI_DSIC_CON_CMD_OPCODE 0x0406 +#define IBRT_HCI_SET_ENV_CMD_OPCODE 0xFC8E + +typedef enum +{ + START_IBRT_TRIGGER_EXIT, + TWS_SWITCH_TRIGGER_EXIT, +} ibrt_ui_exit_sniff_trigger_e; + +typedef enum +{ + TWS_INIT_TRIGGER, + MOBILE_INIT_TRIGGER, + START_IBRT_TRIGGER, + EXCHANGE_PROFILE_TRIGGER, + SCO_CONNECTED_TRIGGER, + SCO_DISCONNECT_TRIGGER, + MOBILE_MSS_TRIGGER, + OTA_START_TRIGGER, + OTA_STOP_TRIGGER, + START_DUAL_MIC_RECORDING_TRIGGER, + STOP_DUAL_MIC_RECORDING_TRIGGER, +} ibrt_ui_trigger_link_policy_e; + +typedef enum +{ + IBRT_CONNECTE_TRIGGER, + IBRT_DISCONNECT_TRIGGER, + IBRT_RECONNECT_TWS_TRIGGER, + IBRT_RECONNECT_MOBILE_TRIGGER, + IBRT_CLOSE_SCAN_TIMER_TRIGGER, + IBRT_SEARCH_SLAVE_TRIGGER, + IBRT_MASTER_CON_SLAVE_TRIGGER, + IBRT_NV_SLAVE_CLOSE_PSCAN_TRIGGER, + IBRT_NV_SLAVE_REOPEN_PSCAN_TRIGGER, + IBRT_FREEMAN_PAIR_TRIGGER, + IBRT_CLOSE_BOX_TRIGGER, + IBRT_OPEN_BOX_TRIGGER, + IBRT_ENTER_PAIRING_MODE_TRIGGER, + IBRT_ROLE_CHANGE_TRIGGER, + IBRT_A2DP_PLAYING_TRIGGER, + IBRT_A2DP_SUSPEND_TRIGGER, + IBRT_SCO_PLAYING_TRIGGER, + IBRT_SCO_SUSPEND_TRIGGER, + IBRT_FASTPAIR_TRIGGER, + IBRT_CLOSE_ALL_SCAN, + IBRT_RESTORE_SCAN, + IBRT_TRIGGER_NUM, +} ibrt_ui_trigger_scan_e; + +typedef enum +{ + IBRT_PAIR_IDLE, + IBRT_PAIR_W4_TWS_DISCONNECTED, + IBRT_PAIR_W4_MOBILE_DISCONNECTED, + IBRT_PAIR_W4_TWS_CONNECTED, + IBRT_PAIR_W4_TWS_INFO_EXCHANGED, +} ibrt_pairing_state_e; + +typedef enum +{ + IBRT_PAIR_ACTION_IDLE, + IBRT_PAIR_ACTION_TWS_DISCONNECTED, + IBRT_PAIR_ACTION_MOBILE_DISCONNECTED, + IBRT_PAIR_ACTION_TWS_CONNECTED, + IBRT_PAIR_ACTION_TWS_INFO_EXCHANGED, +} ibrt_pairing_action_e; + +typedef enum +{ + IBRT_UI_IDLE, + IBRT_UI_IDLE_WAIT, + IBRT_UI_W4_TWS_CONNECTION, + IBRT_UI_W4_TWS_INFO_EXCHANGE_COMPLETE, + IBRT_UI_W4_MOBILE_CONNECTION, + IBRT_UI_W4_MOBILE_MSS_COMPLETE, + IBRT_UI_W4_SET_ENV_COMPLETE, + IBRT_UI_W4_MOBILE_ENTER_ACTIVE_MODE, + IBRT_UI_W4_START_IBRT_COMPLETE, + IBRT_UI_W4_IBRT_DATA_EXCHANGE_COMPLETE, + IBRT_UI_W4_TWS_SWITCH_COMPLETE, + IBRT_UI_W4_TWS_STOP_IBRT_COMPLETE, + IBRT_UI_W4_TWS_BT_MSS_COMPLETE, + IBRT_UI_W4_TWS_DISCONNECTED, + IBRT_UI_W4_MOBILE_DISCONNECTED, + IBRT_UI_W4_TWS_DISCONNECT_TO_IDLE, + IBRT_UI_W4_MOBILE_CONNECTION_TO_IDLE, + IBRT_UI_W4_NEW_MOBILE_INCOMING_RSP, + IBRT_UI_W4_BLE_CONNECTION, + IBRT_UI_W4_SNOOP_INFO_COMPLETE, + IBRT_UI_W4_PHONE_CONNECT_FAILED, + IBRT_UI_W4_TWS_SWITCH_PREPARE_COMPLETE, + IBRT_UI_W4_BOTH_ACTIVE, + //Add new state + + IBRT_UI_W4_SM_STOP, + IBRT_UI_W4_END, + IBRT_UI_W4_UNKNOWN, +} ibrt_ui_state_e; + +//Mapping to ibrt ui state +typedef enum +{ + IBRT_ACTION_IDLE, + IBRT_ACTION_IDLE_WAIT, + IBRT_ACTION_TWS_CONNECT, + IBRT_ACTION_INFO_EXCHANGE, + IBRT_ACTION_MOBILE_CONNECT, + IBRT_ACTION_MOBILE_MSS_COMPLETE, + IBRT_ACTION_SET_ENV_COMPLETE, + IBRT_ACTION_MOBILE_ENTER_ACTIVE_MODE, + IBRT_ACTION_START_IBRT, + IBRT_ACTION_DATA_EXCHANGE, + IBRT_ACTION_TWS_SWITCH, + IBRT_ACTION_STOP_IBRT, + IBRT_ACTION_TWS_BT_MSS_COMPLETE, + IBRT_ACTION_TWS_DISCONNECT, + IBRT_ACTION_MOBILE_DISCONNECT, //14 + IBRT_ACTION_TWS_DISCONNECT_TO_IDLE, + IBRT_ACTION_MOBILE_CONNECTION_TO_IDLE, + IBRT_ACTION_NEW_MOBILE_INCOMING_RSP, + IBRT_ACTION_BLE_CONNECTION, + IBRT_ACTION_SNOOP_INFO_COMPLETE, + IBRT_ACTION_PHONE_CONNECT_FAILED, + IBRT_ACTION_TWS_SWITCH_PREPARE_COMPLETE, + IBRT_ACTION_BOTH_ACTIVE, + //Add new action + + IBRT_ACTION_SM_STOP, + IBRT_ACTION_END, +} ibrt_action_e; + +typedef struct +{ + uint8_t num_hci_cmd_packets; + uint16_t cmd_opcode; + uint8_t param[1]; +} __attribute__ ((packed)) ibrt_cmd_comp_t; + +typedef struct +{ + bool w4_set_env_complete; + bool w4_exit_sniff_complete; + bool w4_start_ibrt; +} ibrt_start_ctrl_t; + +typedef struct +{ + ibrt_action_e action; + ibrt_ui_state_e state; +} ibrt_act_state_t; + +typedef enum +{ + IBRT_UI_NO_ERROR, + IBRT_UI_RSP_TIMEOUT, + IBRT_UI_NOT_ACCEPT, + IBRT_UI_CONNECT_FAILED, + IBRT_UI_STATUS_ERROR, + IBRT_UI_CONNECTION_TIMEOUT=0x08, + IBRT_UI_ACL_ALREADY_EXIST=0x0B, + IBRT_UI_CMD_DISALLOWED=0X0C, + IBRT_UI_LIMITED_RESOURCE =0x0D, + IBRT_UI_HOST_ACCEPT_TIMEOUT=0x10, + IBRT_UI_CONN_TERM_USER_REQ=0x13, + IBRT_UI_CONN_TERM_LOW_RESOURCES=0x14, + IBRT_UI_MOBILE_CONN_DISCONNECTED=0X2A, + IBRT_UI_TWS_CONN_DISCONNECTED=0X2B, + IBRT_UI_SNOOP_DISCONNECTED=0X2C, + IBRT_UI_CONNECTION_INCOMING=0x99, + IBRT_UI_EVT_STATUS_ERROR=0x9A, + IBRT_UI_TWS_CMD_SEND_FAILED=0X9B, + IBRT_UI_MOBILE_PAIR_CANCLED=0X9C, +} ibrt_ui_error_e; + +typedef enum +{ + IBRT_CONNECT_MOBILE_FAILED, + IBRT_MOBILE_DISCONNECTED, + IBRT_MOBILE_NV_EMPTY, + IBRT_TWS_PAIR_MODE_ENTER, + IBRT_FREEMAN_PAIR_MODE_ENTER, + IBRT_SCAN_TIMEOUT, + IBRT_MOBILE_CONNECTED, + IBRT_SNOOP_CONNECTED, + IBRT_CLOSE_BOX, + IBRT_USE_PEER_PAIRING_MODE, +} trigger_pairing_mode_type_e; + +typedef struct +{ + uint16_t battery_volt; + uint16_t mobile_conhandle; + uint16_t tws_conhandle; + rssi_t raw_rssi; + int32_t mobile_diff_us; + int32_t tws_diff_us; + int8_t cur_buf_size; +} app_ui_rssi_battery_info_t; + +typedef struct +{ + bt_bdaddr_t mobile_addr; + bt_bdaddr_t nv_mobile_addr; + ibrt_box_state box_state; + ibrt_role_e ibrt_role; + uint8_t running_event; + uint8_t sco_acitve; + uint8_t mobile_connected:1;//ibrt master should set this variable + uint8_t ibrt_connected:1;//ibrt slave should set this variable + uint8_t ibrt_sm_running:1; + uint8_t connecting_mobile:1; + uint32_t constate; + uint8_t pairing_mode; + bool need_peer_connect_mobile; +} __attribute__((packed)) app_tws_info_t; + +typedef struct +{ + ibrt_event_type ibrt_event_q[IBRT_EVENT_Q_LENGTH]; + uint8_t front; + uint8_t rear; +} ibrt_event_manager_t; + +typedef struct +{ + bool freeman_enable; + bool freeman_dont_role_switch; + bool tws_use_same_addr; + bool wear_updown_tws_switch_enable; + bool slave_reconnect_enable; + bool enter_pairing_mode; + bool freeman_accept_mobile_new_pairing; + bool enter_pairing_on_empty_mobile_addr; + bool enter_pairing_on_reconnect_mobile_failed; + bool enter_pairing_on_reconnect_mobile_failed_once; + bool enter_pairing_on_mobile_disconnect; + + bool check_plugin_excute_closedbox_event; + bool nv_slave_enter_pairing_on_mobile_disconnect; + bool nv_slave_enter_pairing_on_empty_mobile_addr; + bool disc_tws_before_reconnect_mobile; + bool snoop_via_ble_enable; + bool tws_switch_according_to_rssi_value; + bool disable_tws_switch; + bool disable_stop_ibrt; + bool lowlayer_monitor_enable; + bool delay_exit_sniff; + bool share_tws_info_done; + uint32_t delay_ms_exit_sniff; + bool mobile_incoming_filter_unpaired; + uint8_t rssi_threshold; + uint8_t role_switch_timer_threshold; + uint16_t close_box_event_wait_response_timeout; + uint16_t reconnect_wait_ready_timeout; + uint16_t reconnect_mobile_wait_ready_timeout; + uint16_t reconnect_tws_wait_ready_timeout; + uint16_t reconnect_mobile_wait_response_timeout; + uint16_t reconnect_ibrt_wait_response_timeout; + uint16_t nv_master_reconnect_tws_wait_response_timeout; + uint16_t nv_slave_reconnect_tws_wait_response_timeout; + uint32_t disable_bt_scan_timeout; + uint16_t open_reconnect_mobile_max_times; + uint16_t open_reconnect_tws_max_times; + uint16_t reconnect_mobile_max_times; + uint16_t reconnect_tws_max_times; + uint16_t reconnect_ibrt_max_times; + uint8_t tws_reconnect_cycle; + uint8_t mobile_reconnect_cycle; + + uint16_t long_private_poll_interval ; + uint16_t default_private_poll_interval; + uint16_t short_private_poll_interval; + + uint16_t default_private_poll_interval_in_sco; + uint16_t short_private_poll_interval_in_sco; + uint16_t default_bt_tpoll; + + uint16_t tws_page_timeout_on_last_success; + uint16_t tws_page_timeout_on_last_failed; + uint16_t tws_page_timeout_on_reconnect_mobile_success; + uint16_t tws_page_timeout_on_reconnect_mobile_failed; + + uint16_t mobile_page_timeout; + uint16_t tws_connection_timeout; + uint8_t profile_concurrency_supported; + uint8_t connect_new_mobile_enable; + uint16_t wait_time_before_disc_tws; + bt_bdaddr_t new_mobile_address; + + uint32_t rx_seq_error_timeout; + uint32_t rx_seq_error_threshold; + uint32_t rx_seq_recover_wait_timeout; + uint32_t rssi_monitor_timeout; + bool wear_updown_detect_supported; + uint32_t stop_ibrt_timeout; + + uint16_t radical_scan_interval_nv_slave; + uint16_t radical_scan_interval_nv_master; + uint32_t event_hung_timeout; + uint16_t rssi_tws_switch_threshold; + uint32_t stop_ibrt_wait_time_after_tws_switch; + uint32_t tws_conn_failed_wait_time; + uint32_t sm_running_timeout; + uint32_t peer_sm_running_timeout; + uint32_t connect_no_03_timeout; + uint32_t disconnect_no_05_timeout; + uint32_t reconnect_peer_sm_running_timeout; + + bool tws_switch_tx_data_protect; + uint32_t tws_cmd_send_timeout; + uint32_t tws_cmd_send_counter_threshold; + uint32_t tws_switch_stable_timeout; + bool invoke_event_when_box_closed; + bool tws_stay_when_close_box; + uint32_t free_tws_timeout; + bool filter_duplicate_event; + + uint8_t audio_sync_mismatch_resume_version; +} ibrt_ui_config_t; + +typedef struct +{ + uint8_t connection_index; + bool connected; + bool disconnect_enable; + bool master_notify_enable; + bool slave_scaning; + bt_bdaddr_t box_ble_addr; + uint8_t box_connect_state; + uint32_t snoop_info_data_length; + uint8_t data[SNOOP_INFO_DATA_LENGTH_MAX]; +} ibrt_ui_box_info_t; + +typedef struct +{ + ibrt_pairing_state_e tws_pair_state; + ibrt_pairing_state_e freeman_pair_state; + bool tws_pairing; + bool freeman_pairing; +} ibrt_pair_ctrl_t; + +typedef struct +{ + ibrt_ui_state_e super_state; + ibrt_ui_state_e wait_state; + ibrt_ui_state_e sub_state; + ibrt_ui_state_e next_state; + + ibrt_event_manager_t event_q_manager; + ibrt_event_type active_event; + + ibrt_box_state box_state; + ibrt_box_state box_state_future; + uint8_t ibrt_sm_running; + app_tws_info_t peer_tws_info; + + uint32_t sm_start_timestamp_ms; + + bool profile_exchanged; + bool tws_connect_success; + uint8_t reconnect_mobile_counter; + uint8_t reconnect_tws_counter; + uint8_t reconnect_ibrt_counter; + + ibrt_pair_ctrl_t pairing_ctrl; + + /*custom page scan parameters*/ + uint16_t pscan_cust_interval; + uint16_t pscan_cust_window; + uint8_t pscan_cust_type; + + /*search ui restore inqscan parameter when tws connected*/ + bool restore_iscan_para; + bool audio_mute_enable; + bool bonding_success; + bool tws_pscan_enhanced_enable; + bool encrypt_error_happened; + bool silent_mode; + bool need_peer_connect_mobile; + bool refresh_pairing_enable; + bool new_mobile_scan_enable; + /*for customer config*/ + ibrt_ui_config_t config; + + /*for box information*/ + ibrt_ui_box_info_t ibrt_ui_box; +} app_ibrt_ui_t; + +typedef struct +{ + bt_bdaddr_t master_bdaddr; + bt_bdaddr_t slave_bdaddr; +} ibrt_pairing_info_t; + +typedef struct +{ + int32_t a2dp_volume; + int32_t hfp_volume; +} ibrt_volume_info_t; + + +typedef struct +{ + bt_bdaddr_t mobile_addr; + uint8_t mobile_connected; + uint8_t sco_status; +} __attribute__((packed)) app_tws_start_ibrt_info_t; + +typedef bool (*APP_IBRT_UI_TWS_SWITCH_HANDLER_IND)(void); +typedef void (*APP_IBRT_UI_RSSI_BATTERY_HANDLER_IND)(void); +typedef bool (*APP_IBRT_UI_CONNECT_MOBILE_HANDLER_IND)(void); +typedef void (*APP_IBRT_UI_CMD_COMPLETE_HANDLER_IND)(ibrt_cmd_comp_t *); +typedef void (*APP_IBRT_UI_PAIRING_MODE_HANDLER_IND)(trigger_pairing_mode_type_e trigger_type); +typedef void (*APP_IBRT_UI_VENDER_EVENT_HANDLER_IND)(uint8_t, uint8_t *, uint8_t); +typedef void (*APP_IBRT_UI_GLOBAL_HANDLER_IND)(ibrt_link_type_e, uint8_t, uint8_t); +typedef void (*APP_IBRT_UI_GLOBAL_EVENT_UPDATE_IND)(ibrt_event_type, \ + ibrt_ui_state_e, \ + ibrt_ui_state_e, \ + ibrt_action_e, \ + ibrt_ui_error_e); +typedef void (*APP_IBRT_UI_CONNECTED_HANDLER_IND)(bt_bdaddr_t *); +typedef void (*APP_IBRT_UI_PROFILE_STATE_CHANGE_IND)(uint32_t, uint8_t); + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * function declare + */ +void app_ibrt_ui_init(void); +app_ibrt_ui_t* app_ibrt_ui_get_ctx(void); +void app_ibrt_ui_prepare_local_tws_info(app_tws_info_t *local_tws_info); +int app_ibrt_ui_event_entry(ibrt_event_type event); +bool app_ibrt_ui_execute_pending_event(void); +void app_ibrt_ui_global_handler(ibrt_link_type_e link_type, uint8_t evt_type, uint8_t status); +bool app_ibrt_ui_tws_switch_needed(bool ibrt_connected_now); +bool app_ibrt_ui_ibrt_start_needed(void); +bool app_ibrt_ui_ibrt_stop_needed(void); +bool app_ibrt_ui_connect_mobile_needed(void); +bool app_ibrt_ui_ibrt_connected(void); +void app_ibrt_ui_reset_peer_tws_info(void); +void app_ibrt_ui_vender_event_handler(uint8_t evt_type, uint8_t *buffer, uint8_t length); +void app_ibrt_ui_cmd_status_callback(const void *para); +void app_ibrt_ui_cmd_complete_callback(const void *para); +void app_ibrt_ui_judge_ibrt_role(void); +void app_ibrt_ui_reset_local_tws_info(void); +void app_ibrt_ui_event_handler(ibrt_action_e action,ibrt_ui_error_e status); +void app_ibrt_ui_subevent_handler(ibrt_ui_state_e action_state, ibrt_ui_error_e status); +void app_ibrt_ui_fetch_out_event_handler(ibrt_action_e action,ibrt_ui_error_e status); +void app_ibrt_ui_wear_up_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_wear_down_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_tws_switch_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_tws_connect_sync_info_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_new_mobile_incoming_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +uint16_t app_ibrt_ui_get_tws_page_timeout_value(); +void app_ibrt_ui_open_box_event_handler(ibrt_action_e action,ibrt_ui_error_e status); +void app_ibrt_ui_put_in_box_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_close_box_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_free_link_handler(ibrt_action_e action, ibrt_ui_error_e status, bool force_free); +bool app_ibrt_ui_peer_tws_sm_running(void); +ibrt_ui_state_e app_ibrt_ui_get_state_mapping_action(ibrt_action_e action); +void app_ibrt_ui_event_response_timer_cb(void const *n); +void app_ibrt_ui_dbg_state_timer_cb(void const *n); +void app_ibrt_ui_event_error_handling_timer_cb(void const *current_evt); +void app_ibrt_ui_disable_scan_timer_cb(void const *trigger_type); +void app_ibrt_ui_peer_sm_running_error_handler_cb(void const *trigger_type); +void app_ibrt_ui_disable_ble_timer_cb(void const *trigger_type); +void app_ibrt_ui_check_rssi_battery_timer_cb(void const *current_evt); +void app_ibrt_ui_common_sm(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_reconnect_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_connect_second_mobile_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_choice_mobile_connect_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_disconnect_mobile_tws_event_handler(ibrt_action_e action,ibrt_ui_error_e status); +void app_ibrt_ui_profile_data_update_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_choice_connect_second_mobile(void); +void app_ibrt_ui_choice_mobile_connect(uint8_t index); +void app_ibrt_ui_perform_received_action(uint8_t *p_buff, uint16_t length); +bool app_ibrt_ui_pagescan_enable_needed(ibrt_ui_trigger_scan_e trigger_type); +bool app_ibrt_ui_inqscan_enable_needed(void); +void app_ibrt_ui_judge_scan_type(ibrt_ui_trigger_scan_e trigger_type, ibrt_link_type_e link_type, uint8_t status); +void app_ibrt_ui_judge_link_policy(ibrt_ui_trigger_link_policy_e trigger_type, btif_link_policy_t policy); +void app_ibrt_ui_restart_event_handler(void); +void app_ibrt_ui_tws_switch_callback(void); +bool app_ibrt_ui_detect_sm_running_collision(void); +bool app_ibrt_ui_set_env_needed(void); +bool app_ibrt_ui_tws_bt_mss_needed(void); +bool app_ibrt_ui_transfer_sm_needed(void); +void app_ibrt_ui_profile_data_exchange(void); +void app_ibrt_ui_tws_transfer_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_phone_connect_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +bool app_ibrt_ui_none_event_happen(void); +bool app_ibrt_ui_none_event_happen(void); +void app_ibrt_ui_none_event_handler(ibrt_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_pairing_callback(const btif_event_t *event); +bool app_ibrt_ui_delay_start_ibrt_needed(void); +void app_ibrt_ui_action_state_mismatch_handler(ibrt_action_e action, ibrt_ui_error_e status); +bool app_ibrt_ui_is_profile_exchanged(void); +void app_ibrt_ui_set_profile_exchanged(void); +void app_ibrt_ui_clear_profile_exchanged(void); +bool app_ibrt_ui_get_freeman_enable(void); +bool app_ibrt_ui_is_role_switch_allowed(void); +bool app_ibrt_ui_get_nv_salve_enter_pairing_on_mobile_disconnect(void); +bool app_ibrt_ui_get_nv_salve_enter_pairing_on_empty_mobile_addr(void); +void app_ibrt_ui_set_tws_use_same_addr_enable(void); +bool app_ibrt_ui_get_tws_use_same_addr_enable(void); +void app_ibrt_ui_clear_tws_use_same_addr_enable(void); +void app_ibrt_ui_set_freeman_enable(void); +void app_ibrt_ui_clear_freeman_enable(void); +bool app_ibrt_ui_can_tws_switch(void); +bool app_ibrt_ui_tws_switch(void); +bool app_ibrt_ui_get_share_tws_info_done(void); +void app_ibrt_ui_set_share_tws_info_done(void); +void app_ibrt_ui_clear_share_tws_info_done(void); +bool app_ibrt_ui_get_slave_reconnect_enable(void); +void app_ibrt_ui_set_slave_reconnect_enable(void); +void app_ibrt_ui_clear_slave_reconnect_enable(void); +void app_ibrt_ui_set_wear_updown_tws_switch_enable(void); +void app_ibrt_ui_clear_wear_updown_tws_switch_enable(void); +bool app_ibrt_ui_get_wear_updown_tws_switch_enable(void); +void app_ibrt_ui_set_enter_pairing_mode(trigger_pairing_mode_type_e trigger_type); +void app_ibrt_ui_recover_rx_seq_error_timer_cb(void const *n); +bool app_ibrt_ui_get_enter_pairing_mode(void); +void app_ibrt_ui_clear_enter_pairing_mode(trigger_pairing_mode_type_e trigger_type); +void app_ibrt_ui_set_mobile_incoming_filter_unpaired(void); +void app_ibrt_ui_clear_mobile_incoming_filter_unpaired(void); +bool app_ibrt_ui_get_mobile_incoming_filter_unpaired(void); +void app_ibrt_ui_customer_set_bdaddr(uint8_t *nv_master_addr, uint8_t *nv_slave_addr); +bool app_ibrt_ui_is_tws_connecting(void); +bool app_ibrt_ui_is_mobile_connecting(void); +bool app_ibrt_ui_is_data_exchange_waiting(void); +bool app_ibrt_ui_is_tws_switching(void); +void app_ibrt_ui_register_connect_mobile_needed_ind(APP_IBRT_UI_CONNECT_MOBILE_HANDLER_IND handler); +void app_ibrt_ui_register_global_handler_ind(APP_IBRT_UI_GLOBAL_HANDLER_IND handler); +void app_ibrt_ui_register_global_event_update_ind(APP_IBRT_UI_GLOBAL_EVENT_UPDATE_IND handler); +void app_ibrt_ui_register_pairing_mode_ind(APP_IBRT_UI_PAIRING_MODE_HANDLER_IND set_pairing_callback, APP_IBRT_UI_PAIRING_MODE_HANDLER_IND clear_pairing_callback); +void app_ibrt_ui_register_cmd_complete_ind(APP_IBRT_UI_CMD_COMPLETE_HANDLER_IND cmd_complete_ind); +void app_ibrt_ui_register_vender_event_update_ind(APP_IBRT_UI_VENDER_EVENT_HANDLER_IND handler); +void app_ibrt_ui_register_profile_state_change_ind(APP_IBRT_UI_PROFILE_STATE_CHANGE_IND handler); +void app_ibrt_ui_profile_state_change_ind(uint32_t profile,uint8_t connected); +ibrt_ui_error_e app_ibrt_ui_event_queue_insert(ibrt_event_type event); +bool app_ibrt_ui_event_has_been_queued(ibrt_event_type event); +ibrt_ui_error_e app_ibrt_ui_event_queue_delete(ibrt_event_type *p_event); +bool app_ibrt_ui_event_queue_empty(void); +ibrt_ui_error_e app_ibrt_ui_event_queue_get_front(ibrt_event_type *p_event); +ibrt_ui_error_e app_ibrt_ui_event_queue_get_rear(ibrt_event_type *p_event); +void app_ibrt_ui_event_queue_init(void); +bool app_ibrt_ui_enter_idle_wait_needed(ibrt_event_type event, ibrt_event_type peer_event); +void app_ibrt_ui_event_update_entry(ibrt_event_type evt_type, \ + ibrt_ui_state_e old_state, \ + ibrt_ui_state_e new_state, \ + ibrt_action_e action, \ + ibrt_ui_error_e status); +uint8_t app_ibrt_ui_get_reconnect_tws_max_times(void); +uint8_t app_ibrt_ui_get_reconnect_mobile_max_times(void); +bool app_ibrt_ui_tws_switch_according_rssi_needed(void); +void app_ibrt_ui_update_feature_box_state(ibrt_event_type event); +void app_ibrt_ui_start_ble_adv_broadcasting(uint8_t pairing_status); +void app_ibrt_ui_stop_ble_adv_broadcasting(void); +uint8_t is_sco_mode (void); +void app_ibrt_ui_link_control_while_calling(void); +bool btdrv_get_accept_new_mobile_enable(void); +void app_ibrt_ui_reset_link_control_while_profile_exchanged(void); +bool app_ibrt_ui_tws_reconnect_one_cycle_ended(uint8_t reconnect_counter); +bool app_ibrt_ui_mobile_reconnect_one_cycle_ended(uint8_t reconnect_counter); +bool app_ibrt_ui_wait_ibrt_connected(void); +bool app_ibrt_ui_connect_mobile_event_pending(void); +uint16_t app_ibrt_ui_get_reconnect_mobile_wait_time(void); + +void app_ibrt_ui_box_init(bt_bdaddr_t *box_ble_addr); +bool app_ibrt_ui_get_snoop_via_ble_enable(void); +void app_ibrt_ui_set_snoop_via_ble_enable(void); +void app_ibrt_ui_clear_snoop_via_ble_enable(void); +void app_ibrt_ui_set_ble_connect_index(uint8_t index); +void app_ibrt_ui_set_box_ble_addr(bt_bdaddr_t *addr); +bt_bdaddr_t *app_ibrt_ui_get_box_ble_addr(void); +void app_ibrt_ui_set_master_notify_flag(bool notify_enable); +void app_ibrt_ui_set_slave_scaning(bool scan_enable); +bool app_ibrt_ui_is_slave_scaning(void); +void app_ibrt_ui_set_box_connect_state(uint8_t box_connect_state, bool force_set); +uint8_t app_ibrt_ui_clear_box_connect_state(uint8_t box_connect_state, bool force_clear); +void app_ibrt_ui_set_disconnect_enable(bool disconnect_enable); +uint8_t app_ibrt_ui_snoop_info_send_enable(void); +void app_ibrt_ui_connect_box(); +void app_ibrt_ui_disconnect_box(void); +uint32_t app_ibrt_ui_snoop_info_transport(uint8_t *buf, uint32_t len); +void app_ibrt_ui_snoop_info_handler(uint8_t *buf, uint32_t len); +void app_ibrt_ui_freeman_pairing_handler(ibrt_pairing_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_tws_pairing_handler(ibrt_pairing_action_e action, ibrt_ui_error_e status); +void app_ibrt_ui_clear_refresh_pairing_enable(void); +bool app_ibrt_ui_get_refresh_pairing_enable(void); +void app_ibrt_ui_set_refresh_pairing_enable(void); +bool app_ibrt_ui_re_enter_pairing_mode_enable(void); +void app_ibrt_ui_clear_peer_sm_running(void); +void app_ibrt_ui_set_peer_sm_running(void); +bool app_ibrt_ui_duplicate_event_can_filtered(ibrt_event_type t_event); +bool app_ibrt_ui_is_box_closed(void); +ibrt_box_state app_ibrt_ui_get_box_state(void); +void app_ibrt_ui_mobile_link_disconnect_error_handler(void); +void app_ibrt_ui_tws_link_disconnect_error_handler(void); +void app_ibrt_ui_start_reconnect_event(void); +bool app_ibrt_ui_start_reconnect_event_needed(ibrt_action_e action, ibrt_ui_error_e status); +bool app_ibrt_ui_get_audio_mute_enable(void); +void app_ibrt_ui_set_audio_mute_enable(void); +void app_ibrt_ui_clear_audio_mute_enable(void); +void app_ibrt_ui_controller_error_handling(ibrt_controller_error_type error_type, bool reset_controler); +void app_ibrt_ui_set_tws_connect_success_last(void); +void app_ibrt_ui_host_error_handling(ibrt_controller_error_type error_type); +void app_ibrt_ui_clear_tws_connect_success_last(void); +bool app_ibrt_ui_get_tws_connect_success_last(void); +void app_ibrt_ui_start_dbg_state_timer(void); +void app_ibrt_ui_stop_dbg_state_timer(void); +void app_ibrt_ui_controller_dbg_state_checker(void); +void app_ibrt_ui_tws_cmd_send_fail_error_handler(app_tws_cmd_code_e cmd_code); +void app_ibrt_ui_set_local_volume_info(uint8_t * p_buffer); +void app_ibrt_ui_stop_ibrt_condition_checker(void); +void app_ibrt_ui_stop_ibrt_timer_cb(void const *n); +bool app_ibrt_ui_stop_ibrt_timer_condition_fullfilled(void); +bool app_ibrt_if_is_audio_active(void); +void app_ibrt_ui_mobile_link_connected_callback(bt_bdaddr_t * addr); +void app_ibrt_ui_ibrt_link_connected_callback(bt_bdaddr_t * addr); +void app_ibrt_ui_tws_link_connected_callback(bt_bdaddr_t * addr); +void app_ibrt_ui_register_link_connected_ind(APP_IBRT_UI_CONNECTED_HANDLER_IND mobile_connected_ind, + APP_IBRT_UI_CONNECTED_HANDLER_IND ibrt_connected_ind, + APP_IBRT_UI_CONNECTED_HANDLER_IND tws_connected_ind); +void app_ibrt_ui_send_user_action(uint8_t *p_buff, uint16_t length); +void app_ibrt_ui_reboot_sdk(void); +void app_ibrt_ui_tws_switch_stable_timer_cb(void const *n); +void app_ibrt_ui_tws_switch_prepare_timer_cb(void const *n); +void app_ibrt_ui_disconnect_ble(void); +void app_ibrt_ui_register_tws_switch_needed_ind(APP_IBRT_UI_TWS_SWITCH_HANDLER_IND handler); +void app_hci_vender_ibrt_disconnected_callback(bool stop_for_seq_error,uint8_t disc_reason); +bool app_ibrt_ui_exit_mobile_sniff_mode_needed(ibrt_ui_exit_sniff_trigger_e exit_sniff_triiger); +bool app_ibrt_ui_exit_tws_sniff_mode_needed(ibrt_ui_exit_sniff_trigger_e exit_sniff_triiger); +void app_ibrt_ui_disconnect_tws_timer_cb(void const *n); +void app_ibrt_ui_exit_sniff(ibrt_ui_exit_sniff_trigger_e exit_sniff_trigger); +#ifdef __cplusplus +} +#endif +#endif + diff --git a/services/interconnection/Makefile b/services/interconnection/Makefile new file mode 100644 index 0000000..d75ada0 --- /dev/null +++ b/services/interconnection/Makefile @@ -0,0 +1,114 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)umm_malloc/*.c)) + +ifeq ($(INTERACTION),1) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)green/*.cpp)) +endif + +ifeq ($(INTERCONNECTION),1) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)red/*.c)) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)red/*.cpp)) +endif + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +subdir-ccflags-y += -Iplatform/drivers/ana \ + -Iplatform/hal \ + -Iservices/bluedroid/adapter/src \ + -Iapps/key \ + -Iservices/audio_process \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/retention_ram \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/factory \ + -Iservices/voicepath/gsound/gsound_target/ \ + -Iservices/ble_app \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/bridge/ \ + $(BT_IF_INCLUDES) \ + -Iservices/ble_stack/hl/src/gap/ \ + -Iservices/ble_stack/hl/src/gap/gapc/ \ + -Iservices/ble_stack/hl/src/gap/gapm/ \ + -Iservices/ble_stack/hl/src/gap/smpc/ \ + -Iservices/ble_stack/ke/src/ \ + -Iservices/ble_stack/hl/src/gatt/attc/ \ + -Iservices/ble_stack/hl/src/gatt/attm/ \ + -Iservices/ble_stack/hl/src/gatt/atts/ \ + -Iservices/ble_stack/hl/src/gatt/gattc/ \ + -Iservices/ble_stack/hl/src/gatt/gattm/ \ + -Iservices/ble_stack/hl/src/gatt/ \ + -Iservices/ble_stack/hl/src/l2c/l2cc/ \ + -Iservices/ble_stack/hl/src/l2c/l2cm/ \ + -Iservices/ble_stack/hci/api/ \ + -Iservices/ble_stack/hci/src/ \ + -Iservices/ble_stack/app/src/ \ + -Iservices/ble_profiles/htp/htpt/api/ \ + -Iservices/ble_profiles/htp/htpt/src/ \ + -Iservices/ble_profiles/htp/ \ + -Iservices/ble_app/app_main/ \ + -Iservices/ble_app/app_htp/ \ + -Iservices/bt_app/ \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/ble_app/app_voice/app_smartvoice \ + -Iservices/ble_profiles/voicepath/smartvoice \ + -Iservices/interconnection/red \ + -Iservices/interconnection/green \ + -Iservices/interconnection/umm_malloc \ + -Iservices/ota \ + -Iservices/app_ibrt/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/ibrt_core/inc \ + -Iservices/norflash_api \ + -Iservices/multimedia/opus121/include \ + -Iservices/multimedia/speech/application/Pcm8kCvsd/include \ + -Iservices/multimedia/speech/codec/codecs/adpcm \ + -Iservices/multimedia/speech/process/lc_mmse_ns/include \ + -Iservices/multimedia/speech/process/ns_and_ec/include \ + -Iservices/multimedia/speech/process/speech_2mic_ns2_denoise/include \ + -Iservices/multimedia/speech/process/dual_mic_denoise/include \ + -Iservices/multimedia/speech/process/audio_drc2/include \ + -Iservices/multimedia/speech/process/far_field_speech_enhancement/include \ + -Iservices/multimedia/speech/process/plc/include \ + -Iservices/multimedia/speech/process/common/include \ + -Iservices/voicepath \ + -Iservices/nv_section/factory_section \ + -Iservices/voicepath/smartvoice \ + -Iapps/battery \ + -Ithirdparty/userapi \ + -Iutils/crc16 \ + -Iutils/crc32 \ + -Iutils/rsa2048 \ + -Iutils/sha256 \ + -Iutils/aes256 \ + -Iutils/heap \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/norflash_api \ + +ifeq ($(VOICE_PROMPT),1) +ccflags-y += -DMEDIA_PLAYER_SUPPORT +endif diff --git a/services/interconnection/umm_malloc/dbglog.h b/services/interconnection/umm_malloc/dbglog.h new file mode 100644 index 0000000..a4004fa --- /dev/null +++ b/services/interconnection/umm_malloc/dbglog.h @@ -0,0 +1,104 @@ +/* ---------------------------------------------------------------------------- + * dbglog.h - A set of macros that cleans up code that needs to produce debug + * or log information. + * + * Many embedded systems still put a premium on code space and therefore need + * a way to conditionally compile in debug code. Yes, it can lead to code that + * runs differently depending on whether the debug code is cmpiled in or not + * but you need to be able to evaluate the tradeoff. + * + * See copyright notice in LICENSE.TXT + * ---------------------------------------------------------------------------- + * NOTE WELL that this file may be included multiple times - this allows you + * to set the trace level #define DBGLOG_LEVEL x + * + * To update which of the DBGLOG macros are compiled in, you must redefine the + * DBGLOG_LEVEL macro and the inlcude the dbglog.h file again, like this: + * + * #undef DBGLOG_LEVEL + * #define DBGLOG_LEVEL 6 + * #include "dbglog/dbglog.txt" + * + * To handle multiple inclusion, we need to first undefine any macros we define + * so that the compiler does not warn us that we are changing a macro. + * ---------------------------------------------------------------------------- + * The DBGLOG_LEVEL and DBGLOG_FUNCTION should be defined BEFORE this + * file is included or else the following defaults are used: + * + * #define DBGLOG_LEVEL 0 + * #define DBGLOG_FUNCTION printf + * ---------------------------------------------------------------------------- + * There are macros to handle the following decreasing levels of detail: + * + * 6 = TRACE + * 5 = DEBUG + * 4 = CRITICAL + * 3 = ERROR + * 2 = WARNING + * 1 = INFO + * 0 = FORCE - The DBGLOG_FUNCTION is always compiled in and is called only when + * the first parameter to the macro is non-0 + * ---------------------------------------------------------------------------- + */ +#ifndef __DBGLOG_H__ +#define __DBGLOG_H__ + +#include "hal_trace.h" + +#undef DBGLOG_TRACE +#undef DBGLOG_DEBUG +#undef DBGLOG_CRITICAL +#undef DBGLOG_ERROR +#undef DBGLOG_WARNING +#undef DBGLOG_INFO +#undef DBGLOG_FORCE + +#define DBGLOG_LEVEL 3 + +#ifndef DBGLOG_LEVEL +# define DBGLOG_LEVEL 0 +#endif + +#ifndef DBGLOG_FUNCTION +# define DBGLOG_FUNCTION TRACE +#endif + +/* ------------------------------------------------------------------------- */ + +#if DBGLOG_LEVEL >= 6 +# define DBGLOG_TRACE(num,format, ...) DBGLOG_FUNCTION(num,format, ## __VA_ARGS__) +#else +# define DBGLOG_TRACE(format, ...) +#endif + +#if DBGLOG_LEVEL >= 5 +# define DBGLOG_DEBUG(num,format, ...) DBGLOG_FUNCTION(num,format, ## __VA_ARGS__) +#else +# define DBGLOG_DEBUG(format, ...) +#endif + +#if DBGLOG_LEVEL >= 4 +# define DBGLOG_CRITICAL(num,format, ...) DBGLOG_FUNCTION(num,format, ## __VA_ARGS__) +#else +# define DBGLOG_CRITICAL(format, ...) +#endif + +#if DBGLOG_LEVEL >= 3 +# define DBGLOG_ERROR(num,format, ...) DBGLOG_FUNCTION(num,format, ## __VA_ARGS__) +#else +# define DBGLOG_ERROR(format, ...) +#endif + +#if DBGLOG_LEVEL >= 2 +# define DBGLOG_WARNING(num,format, ...) DBGLOG_FUNCTION(num,format, ## __VA_ARGS__) +#else +# define DBGLOG_WARNING(format, ...) +#endif + +#if DBGLOG_LEVEL >= 1 +# define DBGLOG_INFO(num,format, ...) DBGLOG_FUNCTION(num,format, ## __VA_ARGS__) +#else +# define DBGLOG_INFO(format, ...) +#endif + +#endif \ No newline at end of file diff --git a/services/interconnection/umm_malloc/umm_malloc.c b/services/interconnection/umm_malloc/umm_malloc.c new file mode 100644 index 0000000..a11504a --- /dev/null +++ b/services/interconnection/umm_malloc/umm_malloc.c @@ -0,0 +1,619 @@ +#include +#include +#include "stdint.h" +#include "cmsis_os.h" +#include "dbglog.h" +#include "umm_malloc.h" + +/* Use the default DBGLOG_LEVEL and DBGLOG_FUNCTION */ + +unsigned char umm_heap_array[UMM_MALLOC_CFG_HEAP_SIZE]; +/* ------------------------------------------------------------------------- */ + +UMM_H_ATTPACKPRE typedef struct umm_ptr_t { + unsigned short int next; + unsigned short int prev; +} UMM_H_ATTPACKSUF umm_ptr; + + +UMM_H_ATTPACKPRE typedef struct umm_block_t { + union { + umm_ptr used; + } header; + union { + umm_ptr free; + unsigned char data[4]; + } body; +} UMM_H_ATTPACKSUF umm_block; + +#define UMM_FREELIST_MASK (0x8000) +#define UMM_BLOCKNO_MASK (0x7FFF) + +/* ------------------------------------------------------------------------- */ + +umm_block *umm_heap = NULL; +unsigned short int umm_numblocks = 0; + +#define UMM_NUMBLOCKS (umm_numblocks) + +/* ------------------------------------------------------------------------ */ + +#define UMM_BLOCK(b) (umm_heap[b]) + +#define UMM_NBLOCK(b) (UMM_BLOCK(b).header.used.next) +#define UMM_PBLOCK(b) (UMM_BLOCK(b).header.used.prev) +#define UMM_NFREE(b) (UMM_BLOCK(b).body.free.next) +#define UMM_PFREE(b) (UMM_BLOCK(b).body.free.prev) +#define UMM_DATA(b) (UMM_BLOCK(b).body.data) + +static osMutexId umm_clock_mutex_id = NULL; +osMutexDef(umm_clock_mutex); + +/* ------------------------------------------------------------------------ */ +void LOCK_UMM_CLOCK(void) +{ + if(osMutexWait(umm_clock_mutex_id, osWaitForever) != osOK) + DBGLOG_INFO(1,"%s Error", __func__); +} + +void UNLOCK_UMM_CLOCK(void) +{ + if(osMutexRelease(umm_clock_mutex_id) != osOK) + DBGLOG_INFO(1,"%s Error", __func__); +} + +/* ------------------------------------------------------------------------ */ + +static void trace_umm_blocks_info( void ) { + unsigned short int blockSize = 0; + unsigned short int cf = 0; + + cf = UMM_NFREE(0); + blockSize = blockSize; + DBGLOG_INFO(1, "fisrt free block %d", cf); + + while( cf ) { + blockSize = (UMM_NBLOCK(cf) & UMM_BLOCKNO_MASK) - cf; + + DBGLOG_INFO(2, "Looking at block %6i size %6i\n", cf, blockSize ); + + cf = UMM_NFREE(cf); + } +} + +/* ------------------------------------------------------------------------ */ + +static unsigned short int umm_blocks( size_t size ) { + + /* + * The calculation of the block size is not too difficult, but there are + * a few little things that we need to be mindful of. + * + * When a block removed from the free list, the space used by the free + * pointers is available for data. That's what the first calculation + * of size is doing. + */ + + if( size <= (sizeof(((umm_block *)0)->body)) ) + return( 1 ); + + /* + * If it's for more than that, then we need to figure out the number of + * additional whole blocks the size of an umm_block are required. + */ + + size -= ( 1 + (sizeof(((umm_block *)0)->body)) ); + + return( 2 + size/(sizeof(umm_block)) ); +} + +/* ------------------------------------------------------------------------ */ +/* + * Split the block `c` into two blocks: `c` and `c + blocks`. + * + * - `new_freemask` should be `0` if `c + blocks` used, or `UMM_FREELIST_MASK` + * otherwise. + * + * Note that free pointers are NOT modified by this function. + */ +static void umm_split_block( unsigned short int c, + unsigned short int blocks, + unsigned short int new_freemask ) { + + UMM_NBLOCK(c+blocks) = (UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) | new_freemask; + UMM_PBLOCK(c+blocks) = c; + + UMM_PBLOCK(UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) = (c+blocks); + UMM_NBLOCK(c) = (c+blocks); +} + +/* ------------------------------------------------------------------------ */ + +static void umm_disconnect_from_free_list( unsigned short int c ) { + /* Disconnect this block from the FREE list */ + + UMM_NFREE(UMM_PFREE(c)) = UMM_NFREE(c); + UMM_PFREE(UMM_NFREE(c)) = UMM_PFREE(c); + + /* And clear the free block indicator */ + + UMM_NBLOCK(c) &= (~UMM_FREELIST_MASK); +} + +/* ------------------------------------------------------------------------ + * The umm_assimilate_up() function assumes that UMM_NBLOCK(c) does NOT + * have the UMM_FREELIST_MASK bit set! + */ + +static void umm_assimilate_up( unsigned short int c ) { + + if( UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_FREELIST_MASK ) { + /* + * The next block is a free block, so assimilate up and remove it from + * the free list + */ + + DBGLOG_DEBUG(2, "%d Assimilate up to next block %d, which is FREE\n", c, UMM_NBLOCK(c)); + + /* Disconnect the next block from the FREE list */ + + umm_disconnect_from_free_list( UMM_NBLOCK(c) ); + + /* Assimilate the next block with this one */ + + UMM_PBLOCK(UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_BLOCKNO_MASK) = c; + UMM_NBLOCK(c) = UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_BLOCKNO_MASK; + } +} + +/* ------------------------------------------------------------------------ + * The umm_assimilate_down() function assumes that UMM_NBLOCK(c) does NOT + * have the UMM_FREELIST_MASK bit set! + */ + +static unsigned short int umm_assimilate_down( unsigned short int c, unsigned short int freemask ) { + + UMM_NBLOCK(UMM_PBLOCK(c)) = UMM_NBLOCK(c) | freemask; + UMM_PBLOCK(UMM_NBLOCK(c)) = UMM_PBLOCK(c); + + return( UMM_PBLOCK(c) ); +} + +/* ------------------------------------------------------------------------- */ + +void umm_init( void ) { + /* init heap pointer and size, and memset it to 0 */ + umm_heap = (umm_block *)UMM_MALLOC_CFG_HEAP_ADDR; + umm_numblocks = (UMM_MALLOC_CFG_HEAP_SIZE / sizeof(umm_block)); + DBGLOG_DEBUG(3, "%s umm_heap %p blocks number %d", __func__, umm_heap, umm_numblocks); + + if (umm_clock_mutex_id == NULL) + { + umm_clock_mutex_id = osMutexCreate((osMutex(umm_clock_mutex))); + } + + memset(umm_heap, 0x00, UMM_MALLOC_CFG_HEAP_SIZE); + + /* setup initial blank heap structure */ + { + /* index of the 0th `umm_block` */ + const unsigned short int block_0th = 0; + /* index of the 1st `umm_block` */ + const unsigned short int block_1th = 1; + /* index of the latest `umm_block` */ + const unsigned short int block_last = UMM_NUMBLOCKS - 1; + + /* setup the 0th `umm_block`, which just points to the 1st */ + UMM_NBLOCK(block_0th) = block_1th; + UMM_NFREE(block_0th) = block_1th; + UMM_PFREE(block_0th) = block_1th; + + /* + * Now, we need to set the whole heap space as a huge free block. We should + * not touch the 0th `umm_block`, since it's special: the 0th `umm_block` + * is the head of the free block list. It's a part of the heap invariant. + * + * See the detailed explanation at the beginning of the file. + */ + + /* + * 1th `umm_block` has pointers: + * + * - next `umm_block`: the latest one + * - prev `umm_block`: the 0th + * + * Plus, it's a free `umm_block`, so we need to apply `UMM_FREELIST_MASK` + * + * And it's the last free block, so the next free block is 0. + */ + UMM_NBLOCK(block_1th) = block_last | UMM_FREELIST_MASK; + UMM_NFREE(block_1th) = 0; + UMM_PBLOCK(block_1th) = block_0th; + UMM_PFREE(block_1th) = block_0th; + + /* + * latest `umm_block` has pointers: + * + * - next `umm_block`: 0 (meaning, there are no more `umm_blocks`) + * - prev `umm_block`: the 1st + * + * It's not a free block, so we don't touch NFREE / PFREE at all. + */ + UMM_NBLOCK(block_last) = 0; + UMM_PBLOCK(block_last) = block_1th; + } +} + +/* ------------------------------------------------------------------------ */ + +void umm_free( void *ptr ) { + + unsigned short int c; + + /* If we're being asked to free a NULL pointer, well that's just silly! */ + + if( (void *)0 == ptr ) { + DBGLOG_DEBUG(0, "free a null pointer -> do nothing\n" ); + + return; + } + + /* + * FIXME: At some point it might be a good idea to add a check to make sure + * that the pointer we're being asked to free up is actually within + * the umm_heap! + * + * NOTE: See the new umm_info() function that you can use to see if a ptr is + * on the free list! + */ + + /* Protect the critical section... */ + UMM_CRITICAL_ENTRY(); + + /* Figure out which block we're in. Note the use of truncated division... */ + + c = (((char *)ptr)-(char *)(&(umm_heap[0])))/sizeof(umm_block); + + DBGLOG_DEBUG(2, "Freeing block %6i %p\n", c, ptr); + + /* Now let's assimilate this block with the next one if possible. */ + + umm_assimilate_up( c ); + + /* Then assimilate with the previous block if possible */ + + if( UMM_NBLOCK(UMM_PBLOCK(c)) & UMM_FREELIST_MASK ) { + + DBGLOG_DEBUG(1, "Assimilate down to next block %d, which is FREE\n", UMM_PBLOCK(c)); + + c = umm_assimilate_down(c, UMM_FREELIST_MASK); + } else { + /* + * The previous block is not a free block, so add this one to the head + * of the free list + */ + + DBGLOG_DEBUG(0, "Just add to head of free list\n" ); + + UMM_PFREE(UMM_NFREE(0)) = c; + UMM_NFREE(c) = UMM_NFREE(0); + UMM_PFREE(c) = 0; + UMM_NFREE(0) = c; + + UMM_NBLOCK(c) |= UMM_FREELIST_MASK; + } + + /* Release the critical section... */ + UMM_CRITICAL_EXIT(); +} + +/* ------------------------------------------------------------------------ */ + +void *umm_malloc( size_t size ) { + unsigned short int blocks; + unsigned short int blockSize = 0; + + unsigned short int bestSize; + unsigned short int bestBlock; + + unsigned short int cf; + + if (umm_heap == NULL) { + umm_init(); + } + + /* + * the very first thing we do is figure out if we're being asked to allocate + * a size of 0 - and if we are we'll simply return a null pointer. if not + * then reduce the size by 1 byte so that the subsequent calculations on + * the number of blocks to allocate are easier... + */ + + if( 0 == size ) { + DBGLOG_DEBUG(0, "malloc a block of 0 bytes -> do nothing\n" ); + + return( (void *)NULL ); + } + + /* Protect the critical section... */ + UMM_CRITICAL_ENTRY(); + + blocks = umm_blocks( size ); + + /* + * Now we can scan through the free list until we find a space that's big + * enough to hold the number of blocks we need. + * + * This part may be customized to be a best-fit, worst-fit, or first-fit + * algorithm + */ + + cf = UMM_NFREE(0); + + bestBlock = UMM_NFREE(0); + bestSize = 0x7FFF; + + while( cf ) { + blockSize = (UMM_NBLOCK(cf) & UMM_BLOCKNO_MASK) - cf; + + DBGLOG_DEBUG(2, "Looking at block %6i size %6i\n", cf, blockSize ); + +#if defined UMM_BEST_FIT + if( (blockSize >= blocks) && (blockSize < bestSize) ) { + bestBlock = cf; + bestSize = blockSize; + } +#elif defined UMM_FIRST_FIT + /* This is the first block that fits! */ + if( (blockSize >= blocks) ) + break; +#else +# error "No UMM_*_FIT is defined - check umm_malloc_cfg.h" +#endif + + cf = UMM_NFREE(cf); + } + + if( 0x7FFF != bestSize ) { + cf = bestBlock; + blockSize = bestSize; + } + + if( UMM_NBLOCK(cf) & UMM_BLOCKNO_MASK && blockSize >= blocks ) { + /* + * This is an existing block in the memory heap, we just need to split off + * what we need, unlink it from the free list and mark it as in use, and + * link the rest of the block back into the freelist as if it was a new + * block on the free list... + */ + + if( blockSize == blocks ) { + /* It's an exact fit and we don't neet to split off a block. */ + DBGLOG_DEBUG(2, "Allocating %6i blocks starting at %6i - exact\n", blocks, cf ); + + /* Disconnect this block from the FREE list */ + + umm_disconnect_from_free_list( cf ); + + } else { + /* It's not an exact fit and we need to split off a block. */ + DBGLOG_DEBUG(2, "Allocating %6i blocks starting at %6i - existing\n", blocks, cf ); + + /* + * split current free block `cf` into two blocks. The first one will be + * returned to user, so it's not free, and the second one will be free. + */ + umm_split_block( cf, blocks, UMM_FREELIST_MASK /*new block is free*/ ); + + /* + * `umm_split_block()` does not update the free pointers (it affects + * only free flags), but effectively we've just moved beginning of the + * free block from `cf` to `cf + blocks`. So we have to adjust pointers + * to and from adjacent free blocks. + */ + + /* previous free block */ + UMM_NFREE( UMM_PFREE(cf) ) = cf + blocks; + UMM_PFREE( cf + blocks ) = UMM_PFREE(cf); + + /* next free block */ + UMM_PFREE( UMM_NFREE(cf) ) = cf + blocks; + UMM_NFREE( cf + blocks ) = UMM_NFREE(cf); + } + } else { + /* Out of memory */ + + DBGLOG_DEBUG(1, "Can't allocate %5i blocks\n", blocks ); + trace_umm_blocks_info(); + + /* Release the critical section... */ + UMM_CRITICAL_EXIT(); + + return( (void *)NULL ); + } + + /* Release the critical section... */ + UMM_CRITICAL_EXIT(); + + return( (void *)&UMM_DATA(cf) ); +} + +/* ------------------------------------------------------------------------ */ + +void *umm_realloc( void *ptr, size_t size ) { + + unsigned short int blocks; + unsigned short int blockSize; + unsigned short int prevBlockSize = 0; + unsigned short int nextBlockSize = 0; + + unsigned short int c; + + size_t curSize; + + if (umm_heap == NULL) { + umm_init(); + } + + /* + * This code looks after the case of a NULL value for ptr. The ANSI C + * standard says that if ptr is NULL and size is non-zero, then we've + * got to work the same a malloc(). If size is also 0, then our version + * of malloc() returns a NULL pointer, which is OK as far as the ANSI C + * standard is concerned. + */ + + if( ((void *)NULL == ptr) ) { + DBGLOG_DEBUG(0, "realloc the NULL pointer - call malloc()\n" ); + + return( umm_malloc(size) ); + } + + /* + * Now we're sure that we have a non_NULL ptr, but we're not sure what + * we should do with it. If the size is 0, then the ANSI C standard says that + * we should operate the same as free. + */ + + if( 0 == size ) { + DBGLOG_DEBUG(0, "realloc to 0 size, just free the block\n" ); + + umm_free( ptr ); + + return( (void *)NULL ); + } + + /* + * Otherwise we need to actually do a reallocation. A naiive approach + * would be to malloc() a new block of the correct size, copy the old data + * to the new block, and then free the old block. + * + * While this will work, we end up doing a lot of possibly unnecessary + * copying. So first, let's figure out how many blocks we'll need. + */ + + blocks = umm_blocks( size ); + + /* Figure out which block we're in. Note the use of truncated division... */ + + c = (((char *)ptr)-(char *)(&(umm_heap[0])))/sizeof(umm_block); + + /* Figure out how big this block is ... the free bit is not set :-) */ + + blockSize = (UMM_NBLOCK(c) - c); + + /* Figure out how many bytes are in this block */ + + curSize = (blockSize*sizeof(umm_block))-(sizeof(((umm_block *)0)->header)); + + /* Protect the critical section... */ + UMM_CRITICAL_ENTRY(); + + /* Now figure out if the previous and/or next blocks are free as well as + * their sizes - this will help us to minimize special code later when we + * decide if it's possible to use the adjacent blocks. + * + * We set prevBlockSize and nextBlockSize to non-zero values ONLY if they + * are free! + */ + + if ((UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_FREELIST_MASK)) { + nextBlockSize = (UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_BLOCKNO_MASK) - UMM_NBLOCK(c); + } + + if ((UMM_NBLOCK(UMM_PBLOCK(c)) & UMM_FREELIST_MASK)) { + prevBlockSize = (c - UMM_PBLOCK(c)); + } + + DBGLOG_DEBUG(4, "realloc blocks %i blockSize %i nextBlockSize %i prevBlockSize %i\n", blocks, blockSize, nextBlockSize, prevBlockSize ); + + /* + * Ok, now that we're here we know how many blocks we want and the current + * blockSize. The prevBlockSize and nextBlockSize are set and we can figure + * out the best strategy for the new allocation as follows: + * + * 1. If the new block is the same size or smaller than the current block do + * nothing. + * 2. If the next block is free and adding it to the current block gives us + * enough memory, assimilate the next block. + * 3. If the prev block is free and adding it to the current block gives us + * enough memory, remove the previous block from the free list, assimilate + * it, copy to the new block. + * 4. If the prev and next blocks are free and adding them to the current + * block gives us enough memory, assimilate the next block, remove the + * previous block from the free list, assimilate it, copy to the new block. + * 5. Otherwise try to allocate an entirely new block of memory. If the + * allocation works free the old block and return the new pointer. If + * the allocation fails, return NULL and leave the old block intact. + * + * All that's left to do is decide if the fit was exact or not. If the fit + * was not exact, then split the memory block so that we use only the requested + * number of blocks and add what's left to the free list. + */ + + if (blockSize >= blocks) { + DBGLOG_DEBUG(1, "realloc the same or smaller size block - %i, do nothing\n", blocks ); + /* This space intentionally left blank */ + } else if ((blockSize + nextBlockSize) >= blocks) { + DBGLOG_DEBUG(1, "realloc using next block - %i\n", blocks ); + umm_assimilate_up( c ); + blockSize += nextBlockSize; + } else if ((prevBlockSize + blockSize) >= blocks) { + DBGLOG_DEBUG(1, "realloc using prev block - %i\n", blocks ); + umm_disconnect_from_free_list( UMM_PBLOCK(c) ); + c = umm_assimilate_down(c, 0); + memmove( (void *)&UMM_DATA(c), ptr, curSize ); + ptr = (void *)&UMM_DATA(c); + blockSize += prevBlockSize; + } else if ((prevBlockSize + blockSize + nextBlockSize) >= blocks) { + DBGLOG_DEBUG(1, "realloc using prev and next block - %i\n", blocks ); + umm_assimilate_up( c ); + umm_disconnect_from_free_list( UMM_PBLOCK(c) ); + c = umm_assimilate_down(c, 0); + memmove( (void *)&UMM_DATA(c), ptr, curSize ); + ptr = (void *)&UMM_DATA(c); + blockSize += (prevBlockSize + nextBlockSize); + } else { + DBGLOG_DEBUG(1, "realloc a completely new block %i\n", blocks ); + void *oldptr = ptr; + if( (ptr = umm_malloc( size )) ) { + DBGLOG_DEBUG(2, "realloc %i to a bigger block %i, copy, and free the old\n", blockSize, blocks ); + memcpy( ptr, oldptr, curSize ); + umm_free( oldptr ); + } else { + DBGLOG_DEBUG(2, "realloc %i to a bigger block %i failed - return NULL and leave the old block!\n", blockSize, blocks ); + /* This space intentionally left blnk */ + } + blockSize = blocks; + } + + /* Now all we need to do is figure out if the block fit exactly or if we + * need to split and free ... + */ + + if (blockSize > blocks ) { + DBGLOG_DEBUG(2, "split and free %i blocks from %i\n", blocks, blockSize ); + umm_split_block( c, blocks, 0 ); + umm_free( (void *)&UMM_DATA(c+blocks) ); + } + + /* Release the critical section... */ + UMM_CRITICAL_EXIT(); + + return( ptr ); +} + +/* ------------------------------------------------------------------------ */ + +void *umm_calloc( size_t num, size_t item_size ) { + void *ret; + + ret = umm_malloc((size_t)(item_size * num)); + + if (ret) + memset(ret, 0x00, (size_t)(item_size * num)); + + return ret; + } + +/* ------------------------------------------------------------------------ */ diff --git a/services/interconnection/umm_malloc/umm_malloc.h b/services/interconnection/umm_malloc/umm_malloc.h new file mode 100644 index 0000000..4aabecd --- /dev/null +++ b/services/interconnection/umm_malloc/umm_malloc.h @@ -0,0 +1,57 @@ +#ifndef UMM_MALLOC_H +#define UMM_MALLOC_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern unsigned char umm_heap_array[]; + +#ifndef size_t +typedef unsigned int size_t; +#endif + +/* Start addresses and the size of the heap */ +#define UMM_MALLOC_CFG_HEAP_ADDR (umm_heap_array) +#ifdef __DUAL_MIC_RECORDING__ +#define UMM_MALLOC_CFG_HEAP_SIZE (10 * 1024) +#else +#define UMM_MALLOC_CFG_HEAP_SIZE 0x1000 // 4K +#endif +/* A couple of macros to make packing structures less compiler dependent */ + +#define UMM_H_ATTPACKPRE +#define UMM_H_ATTPACKSUF __attribute__((__packed__)) + +#define UMM_BEST_FIT +#undef UMM_FIRST_FIT + +/* + * A couple of macros to make it easier to protect the memory allocator + * in a multitasking system. You should set these macros up to use whatever + * your system uses for this purpose. You can disable interrupts entirely, or + * just disable task switching - it's up to you + * + * NOTE WELL that these macros MUST be allowed to nest, because umm_free() is + * called from within umm_malloc() + */ + +#define UMM_CRITICAL_ENTRY() LOCK_UMM_CLOCK() +#define UMM_CRITICAL_EXIT() UNLOCK_UMM_CLOCK() + +/* ------------------------------------------------------------------------ */ + +void umm_init( void ); +void *umm_malloc( size_t size ); +void *umm_calloc( size_t num, size_t size ); +void *umm_realloc( void *ptr, size_t size ); +void umm_free( void *ptr ); + + +/* ------------------------------------------------------------------------ */ + +#ifdef __cplusplus +} +#endif + +#endif /* UMM_MALLOC_H */ diff --git a/services/lhdc_license/Makefile b/services/lhdc_license/Makefile new file mode 100644 index 0000000..7faae78 --- /dev/null +++ b/services/lhdc_license/Makefile @@ -0,0 +1,24 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.c)) + +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)src/*.cpp)) + +src_obj := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +LHDC_LICENSE_LIB_NAME := lib_lhdc_license +$(LHDC_LICENSE_LIB_NAME)-y := $(src_obj) +obj-y += $(LHDC_LICENSE_LIB_NAME).a + +subdir-ccflags-y += -Iplatform/drivers/ana \ + -Iplatform/hal \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iservices/bt_app/a2dp_codecs/include\ + -Iservices/bt_if_enhanced/inc + + + + + diff --git a/services/multimedia/Makefile b/services/multimedia/Makefile new file mode 100644 index 0000000..1be3199 --- /dev/null +++ b/services/multimedia/Makefile @@ -0,0 +1,104 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +mmlib_obj := + +mmlib_obj += algorithm/fft/src/ + +mmlib_obj += audio/process/adp/src/ +mmlib_obj += audio/process/anc/src/ +mmlib_obj += audio/process/fir2iir/src/ +mmlib_obj += audio/process/common/src/ +mmlib_obj += audio/process/drc/src/ +mmlib_obj += audio/process/filters/src/ +mmlib_obj += audio/process/limiter/src/ +mmlib_obj += audio/process/resample/src/ +mmlib_obj += audio/process/integer_resampling/src/ +mmlib_obj += audio/process/floatlimiter/src/ +mmlib_obj += audio/process/adj_mc/src/ + +ifeq ($(FM_ENABLE),1) +mmlib_obj += fm/ +endif + +ifeq ($(A2DP_OPUS_ON),1) +#mmlib_obj += opus121/src/ +endif + +ifeq ($(BT_APP),1) +mmlib_obj += audio/codec/sbc/src/ +endif + +ifeq ($(A2DP_AAC_ON),1) +aac_obj := +ifeq ($(FDKAAC_VERSION),2) +aac_obj += audio/codec/fdkaac_codec_2_0_1/libAACdec/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libAACenc/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libFDK/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libMpegTPDec/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libMpegTPEnc/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libPCMutils/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libSBRdec/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libSBRenc/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libSACdec/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libSACenc/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libDRCdec/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libArithCoding/src/ +aac_obj += audio/codec/fdkaac_codec_2_0_1/libSYS/src/ +else +aac_obj += audio/codec/fdkaac_codec/libAACdec/src/ +aac_obj += audio/codec/fdkaac_codec/libAACenc/src/ +aac_obj += audio/codec/fdkaac_codec/libFDK/src/ +aac_obj += audio/codec/fdkaac_codec/libMpegTPDec/src/ +aac_obj += audio/codec/fdkaac_codec/libMpegTPEnc/src/ +aac_obj += audio/codec/fdkaac_codec/libPCMutils/src/ +aac_obj += audio/codec/fdkaac_codec/libSBRdec/src/ +aac_obj += audio/codec/fdkaac_codec/libSBRenc/src/ +aac_obj += audio/codec/fdkaac_codec/libSYS/src/ +endif +ifeq ($(A2DP_CP_ACCEL),1) +fdkaac_codec-y := $(aac_obj) +mmlib_obj += fdkaac_codec.o +else +mmlib_obj += $(aac_obj) +endif +ifeq ($(ROM_UTILS_ON),1) +subdir-ccflags-y += -DFDK_FUNC_ATTR=WEAK +else +subdir-ccflags-y += -DFDK_FUNC_ATTR= +endif +endif + +#mmlib_obj += rbcodec/src/ + +ifeq ($(SPEECH_LIB),1) +mmlib_obj += speech/src/ +endif + +MULTIMEDIA_LIB_NAME := $(CHIP)_libmultimedia + +ifeq ($(ROM_UTILS_ON),1) +MULTIMEDIA_LIB_NAME := $(MULTIMEDIA_LIB_NAME)_romaac +endif + +ifeq ($(A2DP_CP_ACCEL),1) +MULTIMEDIA_LIB_NAME := $(MULTIMEDIA_LIB_NAME)_cp +endif + +ifeq ($(ANC_APP),1) +MULTIMEDIA_LIB_NAME := $(MULTIMEDIA_LIB_NAME)_anc +endif + +$(MULTIMEDIA_LIB_NAME)-y := $(mmlib_obj) + +rel_src_obj := +rel_src_obj += audio/process/anc/cfg/ +rel_src_obj += audio/process/filters/cfg/ +rel_src_obj += audio/process/resample/coef/ + +obj-y := $(MULTIMEDIA_LIB_NAME).a $(rel_src_obj) + +subdir-ccflags-y += \ + -Iutils/heap \ + + \ No newline at end of file diff --git a/services/multimedia/algorithm/fft/include/fft128dot.h b/services/multimedia/algorithm/fft/include/fft128dot.h new file mode 100644 index 0000000..f9e806a --- /dev/null +++ b/services/multimedia/algorithm/fft/include/fft128dot.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef FFTR4_FXP_H +#define FFTR4_FXP_H + +#define FFTR4_TWIDDLE_WIDTH 16 +#define FFTR4_DATA_WIDTH 16 +#define FFTR4_SCALE 6 + +/* Q1.15 */ +#define FFTR4_INPUT_FORMAT_X 1 +#define FFTR4_INPUT_FORMAT_Y 15 +#define FFTR4_INPUT_FORMAT (FFTR4_INPUT_FORMAT_X+FFTR4_INPUT_FORMAT_Y) + +/* Q1.15 */ +#define FFTR4_OUTPUT_FORMAT_X 1 +#define FFTR4_OUTPUT_FORMAT_Y 15 +#define FFTR4_OUTPUT_FORMAT (FFTR4_OUTPUT_FORMAT_X+FFTR4_OUTPUT_FORMAT_Y) + +typedef struct { + int re; + int im; +} FftData_t; + +typedef struct { + int re; + int im; +} FftTwiddle_t; + +typedef enum +{ + FFT_MODE = 0, + IFFT_MODE +}FftMode_t; + +void make_symmetric_twiddles(FftTwiddle_t w[], int N, int width); +void fftr4(int N, FftData_t x[], FftTwiddle_t w[], int twiddleWidth, int dataWidth, FftMode_t ifft); +void dibit_reverse_array(FftData_t *vector); +void dibit_reverse_array(FftData_t *vector); +unsigned int dibit_reverse_int(unsigned int x, unsigned int N); +FftData_t sat(FftData_t x, int width); +#endif diff --git a/services/multimedia/algorithm/fft/include/fftr4_fxp.h b/services/multimedia/algorithm/fft/include/fftr4_fxp.h new file mode 100644 index 0000000..e6c1512 --- /dev/null +++ b/services/multimedia/algorithm/fft/include/fftr4_fxp.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef FFTR4_FXP_H +#define FFTR4_FXP_H + +#define FFTR4_TWIDDLE_WIDTH 16 +#define FFTR4_DATA_WIDTH 16 +#define FFTR4_SCALE 6 + +/* Q1.15 */ +#define FFTR4_INPUT_FORMAT_X 1 +#define FFTR4_INPUT_FORMAT_Y 15 +#define FFTR4_INPUT_FORMAT (FFTR4_INPUT_FORMAT_X+FFTR4_INPUT_FORMAT_Y) + +/* Q1.15 */ +#define FFTR4_OUTPUT_FORMAT_X 1 +#define FFTR4_OUTPUT_FORMAT_Y 15 +#define FFTR4_OUTPUT_FORMAT (FFTR4_OUTPUT_FORMAT_X+FFTR4_OUTPUT_FORMAT_Y) + +typedef struct { + int re; + int im; +} FftData_t; + +typedef struct { + int re; + int im; +} FftTwiddle_t; + +typedef enum +{ + FFT_MODE = 0, + IFFT_MODE +}FftMode_t; + +void make_symmetric_twiddles(FftTwiddle_t w[], int N, int width); +void fftr4(int N, FftData_t x[], FftTwiddle_t w[], int twiddleWidth, int dataWidth, FftMode_t ifft); +void dibit_reverse_array(FftData_t *vector); +//void dibit_reverse_array(FftData_t *vector); +unsigned int dibit_reverse_int(unsigned int x, unsigned int N); + +#endif \ No newline at end of file diff --git a/services/multimedia/audio/codec/fdkaac_codec/ChangeLog b/services/multimedia/audio/codec/fdkaac_codec/ChangeLog new file mode 100644 index 0000000..a36902f --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/ChangeLog @@ -0,0 +1,42 @@ +0.1.6 + - Lots of minor assorted crash/fuzz fixes, mostly for the decoder but + also some for the encoder + +0.1.5 + - Updated upstream sources + - Fixed building with GCC 3.3 and 3.4 + - Fixed building with GCC 6 + - AArch64 optimizations + - Makefiles for building with MSVC + - Support building the code in C++11 mode + +0.1.4 + - Updated upstream sources, with minor changes to the decoder API + breaking the ABI. (Calling code using AUDIO_CHANNEL_TYPE may need to + be updated. A new option AAC_PCM_LIMITER_ENABLE has been added, enabled + by default, which incurs extra decoding delay.) + - PowerPC optimizations, fixes for building on AIX + - Support for reading streamed wav files in the encoder example + - Fix VBR encoding of sample rates over 64 kHz + +0.1.3 + - Updated upstream sources, with a number of crash fixes and new features + (including support for encoding 7.1) + +0.1.2 + - Fix a few more crashes + - Include dependency libs (such as -lm) in the pkg-config file + +0.1.1 + - Updated to a new upstream version from Android 4.2, fixing a lot of crashes + - Cleanup of autotools usage + - Make sure the shared library links to libm if necessary + - Performance improvements on x86 + - Added support for WG4/DVD audio channel mappings + - Minimized the differences to upstream + - Added an example encoder tool + +0.1.0 + - Initial release of fdk-aac + - autotools based build system + - Enable setting VBR bitrate modes diff --git a/services/multimedia/audio/codec/fdkaac_codec/NOTICE b/services/multimedia/audio/codec/fdkaac_codec/NOTICE new file mode 100644 index 0000000..82d307c --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/NOTICE @@ -0,0 +1,80 @@ +Software License for Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + +1. INTRODUCTION +Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de + diff --git a/services/multimedia/audio/codec/fdkaac_codec/README b/services/multimedia/audio/codec/fdkaac_codec/README new file mode 100644 index 0000000..866be99 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/README @@ -0,0 +1,3 @@ +NOTICE: +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android is modifyed by BES at 2018.08.22. +The base version about FDK AAC is e45ae429b9ca8f234eb861338a75b2d89cde206a diff --git a/services/multimedia/audio/codec/fdkaac_codec/libAACdec/include/aacdecoder_lib.h b/services/multimedia/audio/codec/fdkaac_codec/libAACdec/include/aacdecoder_lib.h new file mode 100644 index 0000000..89ba4af --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libAACdec/include/aacdecoder_lib.h @@ -0,0 +1,770 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/***************************** MPEG-4 AAC Decoder ************************** + + Author(s): Manuel Jander + +******************************************************************************/ + +/** + * \file aacdecoder_lib.h + * \brief FDK AAC decoder library interface header file. + * + +\page INTRO Introduction + +\section SCOPE Scope + +This document describes the high-level interface and usage of the ISO/MPEG-2/4 AAC Decoder +library developed by the Fraunhofer Institute for Integrated Circuits (IIS). +Depending on the library configuration, it implements decoding of AAC-LC (Low-Complexity), +HE-AAC (High-Efficiency AAC, v1 and v2), AAC-LD (Low-Delay) and AAC-ELD (Enhanced Low-Delay). + +All references to SBR (Spectral Band Replication) are only applicable to HE-AAC and AAC-ELD +versions of the library. All references to PS (Parametric Stereo) are only applicable to +HE-AAC v2 versions of the library. + +\section DecoderBasics Decoder Basics + +This document can only give a rough overview about the ISO/MPEG-2 and ISO/MPEG-4 AAC audio +coding standard. To understand all the terms in this document, you are encouraged to read +the following documents. + +- ISO/IEC 13818-7 (MPEG-2 AAC), which defines the syntax of MPEG-2 AAC audio bitstreams. +- ISO/IEC 14496-3 (MPEG-4 AAC, subpart 1 and 4), which defines the syntax of MPEG-4 AAC audio bitstreams. +- Lutzky, Schuller, Gayer, Krämer, Wabnik, "A guideline to audio codec delay", 116th AES Convention, May 8, 2004 + +MPEG Advanced Audio Coding is based on a time-to-frequency mapping of the signal. The signal +is partitioned into overlapping portions and transformed into frequency domain. The spectral +components are then quantized and coded.\n +An MPEG2 or MPEG4 AAC audio bitstream is composed of frames. Contrary to MPEG-1/2 Layer-3 (mp3), +the length of individual frames is not restricted to a fixed number of bytes, but can take on +any length between 1 and 768 bytes. + + +\page LIBUSE Library Usage + +\section InterfaceDescritpion API Description + +All API header files are located in the folder /include of the release package. They are described in +detail in this document. All header files are provided for usage in C/C++ programs. The AAC decoder library +API functions are located at aacdecoder_lib.h. + +In binary releases the decoder core resides in statically linkable libraries called for example libAACdec.a, +(Linux) or FDK_aacDec_lib (Microsoft Visual C++). + +\section Calling_Sequence Calling Sequence + +For decoding of ISO/MPEG-2/4 AAC or HE-AAC v2 bitstreams the following sequence is mandatory. Input read +and output write functions as well as the corresponding open and close functions are left out, since they +may be implemented differently according to the user's specific requirements. The example implementation in +main.cpp uses file-based input/output, and in such case call mpegFileRead_Open() to open an input file and +to allocate memory for the required structures, and the corresponding mpegFileRead_Close() to close opened +files and to de-allocate associated structures. mpegFileRead_Open() tries to detect the bitstream format and +in case of MPEG-4 file format or Raw Packets file format (a Fraunhofer IIS proprietary format) reads the Audio +Specific Config data (ASC). An unsuccessful attempt to recognize the bitstream format requires the user to +provide this information manually. For any other bitstream formats that are usually applicable in streaming +applications, the decoder itself will try to synchronize and parse the given bitstream fragment using the +FDK transport library. Hence, for streaming applications (without file access) this step is not necessary. + +-# Call aacDecoder_Open() to open and retrieve a handle to a new AAC decoder instance. +\dontinclude main.cpp +\skipline aacDecoder_Open +-# If out-of-band config data (Audio Specific Config (ASC) or Stream Mux Config (SMC)) is available, call +aacDecoder_ConfigRaw() to pass it to the decoder and before the decoding process starts. If this data is +not available in advance, the decoder will get it from the bitstream and configure itself while decoding +with aacDecoder_DecodeFrame(). +-# Begin decoding loop. +\skipline do { +-# Read data from bitstream file or stream into a client-supplied input buffer ("inBuffer" in main.cpp). +If it is very small like just 4, aacDecoder_DecodeFrame() will +repeatedly return ::AAC_DEC_NOT_ENOUGH_BITS until enough bits were fed by aacDecoder_Fill(). Only read data +when this buffer has completely been processed and is then empty. For file-based input execute +mpegFileRead_Read() or any other implementation with similar functionality. +-# Call aacDecoder_Fill() to fill the decoder's internal bitstream input buffer with the client-supplied +external bitstream input buffer. +\skipline aacDecoder_Fill +-# Call aacDecoder_DecodeFrame() which writes decoded PCM audio data to a client-supplied buffer. It is the +client's responsibility to allocate a buffer which is large enough to hold this output data. +\skipline aacDecoder_DecodeFrame +If the bitstream's configuration (number of channels, sample rate, frame size) is not known in advance, you may +call aacDecoder_GetStreamInfo() to retrieve a structure containing this information and then initialize an audio +output device. In the example main.cpp, if the number of channels or the sample rate has changed since program +start or since the previously decoded frame, the audio output device will be re-initialized. If WAVE file output +is chosen, a new WAVE file for each new configuration will be created. +\skipline aacDecoder_GetStreamInfo +-# Repeat steps 5 to 7 until no data to decode is available anymore, or if an error occured. +\skipline } while +-# Call aacDecoder_Close() to de-allocate all AAC decoder and transport layer structures. +\skipline aacDecoder_Close + +\section BufferSystem Buffer System + +There are three main buffers in an AAC decoder application. One external input buffer to hold bitstream +data from file I/O or elsewhere, one decoder-internal input buffer, and one to hold the decoded output +PCM sample data, whereas this output buffer may overlap with the external input buffer. + +The external input buffer is set in the example framework main.cpp and its size is defined by ::IN_BUF_SIZE. +You may freely choose different sizes here. To feed the data to the decoder-internal input buffer, use the +function aacDecoder_Fill(). This function returns important information about how many bytes in the +external input buffer have not yet been copied into the internal input buffer (variable bytesValid). +Once the external buffer has been fully copied, it can be re-filled again. +In case you want to re-fill it when there are still unprocessed bytes (bytesValid is unequal 0), you +would have to additionally perform a memcpy(), so that just means unnecessary computational overhead +and therefore we recommend to re-fill the buffer only when bytesValid is 0. + +\image latex dec_buffer.png "Lifecycle of the external input buffer" width=9cm + +The size of the decoder-internal input buffer is set in tpdec_lib.h (see define ::TRANSPORTDEC_INBUF_SIZE). +You may choose a smaller size under the following considerations: + +- each input channel requires 768 bytes +- the whole buffer must be of size 2^n + +So for example a stereo decoder: + +\f[ +TRANSPORTDEC\_INBUF\_SIZE = 2 * 768 = 1536 => 2048 +\f] + +tpdec_lib.h and TRANSPORTDEC_INBUF_SIZE are not part of the decoder's library interface. Therefore +only source-code clients may change this setting. If you received a library release, please ask us and +we can change this in order to meet your memory requirements. + +\page OutputFormat Decoder audio output + +\section OutputFormatObtaining Obtaining channel mapping information + +The decoded audio output format is indicated by a set of variables of the CStreamInfo structure. +While the members sampleRate, frameSize and numChannels might be quite self explaining, +pChannelType and pChannelIndices might require some more detailed explanation. + +These two arrays indicate what is each output channel supposed to be. Both array have +CStreamInfo::numChannels cells. Each cell of pChannelType indicates the channel type, described in +the enum ::AUDIO_CHANNEL_TYPE defined in FDK_audio.h. The cells of pChannelIndices indicate the sub index +among the channels starting with 0 among all channels of the same audio channel type. + +The indexing scheme is the same as for MPEG-2/4. Thus indices are counted upwards starting from the front +direction (thus a center channel if any, will always be index 0). Then the indices count up, starting always +with the left side, pairwise from front toward back. For detailed explanation, please refer to +ISO/IEC 13818-7:2005(E), chapter 8.5.3.2. + +In case a Program Config is included in the audio configuration, the channel mapping described within +it will be adopted. + +In case of MPEG-D Surround the channel mapping will follow the same criteria described in ISO/IEC 13818-7:2005(E), +but adding corresponding top channels to the channel types front, side and back, in order to avoid any +loss of information. + +\section OutputFormatChange Changing the audio output format + +The channel interleaving scheme and the actual channel order can be changed at runtime through the +parameters ::AAC_PCM_OUTPUT_INTERLEAVED and ::AAC_PCM_OUTPUT_CHANNEL_MAPPING. See the description of those +parameters and the decoder library function aacDecoder_SetParam() for more detail. + +\section OutputFormatExample Channel mapping examples + +The following examples illustrate the location of individual audio samples in the audio buffer that +is passed to aacDecoder_DecodeFrame() and the expected data in the CStreamInfo structure which can be obtained +by calling aacDecoder_GetStreamInfo(). + +\subsection ExamplesStereo Stereo + +In case of ::AAC_PCM_OUTPUT_INTERLEAVED set to 0 and ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1, +a AAC-LC bit stream which has channelConfiguration = 2 in its audio specific config would lead +to the following values in CStreamInfo: + +CStreamInfo::numChannels = 2 + +CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT } + +CStreamInfo::pChannelIndices = { 0, 1 } + +Since ::AAC_PCM_OUTPUT_INTERLEAVED is set to 0, the audio channels will be located as contiguous blocks +in the output buffer as follows: + +\verbatim + ... + ... +\endverbatim + +Where N equals to CStreamInfo::frameSize . + +\subsection ExamplesSurround Surround 5.1 + +In case of ::AAC_PCM_OUTPUT_INTERLEAVED set to 1 and ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1, +a AAC-LC bit stream which has channelConfiguration = 6 in its audio specific config, would lead +to the following values in CStreamInfo: + +CStreamInfo::numChannels = 6 + +CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT, ::ACT_FRONT, ::ACT_LFE, ::ACT_BACK, ::ACT_BACK } + +CStreamInfo::pChannelIndices = { 1, 2, 0, 0, 0, 1 } + +Since ::AAC_PCM_OUTPUT_CHANNEL_MAPPING is 1, WAV file channel ordering will be used. For a 5.1 channel +scheme, thus the channels would be: front left, front right, center, LFE, surround left, surround right. +Thus the third channel is the center channel, receiving the index 0. The other front channels are +front left, front right being placed as first and second channels with indices 1 and 2 correspondingly. +There is only one LFE, placed as the fourth channel and index 0. Finally both surround +channels get the type definition ACT_BACK, and the indices 0 and 1. + +Since ::AAC_PCM_OUTPUT_INTERLEAVED is set to 1, the audio channels will be placed in the output buffer +as follows: + +\verbatim + +
+ + + +
+ + +... + + +
+ +\endverbatim + +Where N equals to CStreamInfo::frameSize . + +\subsection ExamplesArib ARIB coding mode 2/1 + +In case of ::AAC_PCM_OUTPUT_INTERLEAVED set to 1 and ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1, +in case of a ARIB bit stream using coding mode 2/1 as described in ARIB STD-B32 Part 2 Version 2.1-E1, page 61, +would lead to the following values in CStreamInfo: + +CStreamInfo::numChannels = 3 + +CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT,:: ACT_BACK } + +CStreamInfo::pChannelIndices = { 0, 1, 0 } + +The audio channels will be placed as follows in the audio output buffer: + +\verbatim + + + + +... + + + +Where N equals to CStreamInfo::frameSize . + +\endverbatim + +*/ + +#ifndef AACDECODER_LIB_H +#define AACDECODER_LIB_H + +#include "machine_type.h" +#include "FDK_audio.h" + +#include "genericStds.h" + +#define AACDECODER_LIB_VL0 2 +#define AACDECODER_LIB_VL1 5 +#define AACDECODER_LIB_VL2 17 + +/** + * \brief AAC decoder error codes. + */ +typedef enum { + AAC_DEC_OK = 0x0000, /*!< No error occured. Output buffer is valid and error free. */ + AAC_DEC_OUT_OF_MEMORY = 0x0002, /*!< Heap returned NULL pointer. Output buffer is invalid. */ + AAC_DEC_UNKNOWN = 0x0005, /*!< Error condition is of unknown reason, or from a another module. Output buffer is invalid. */ + + /* Synchronization errors. Output buffer is invalid. */ + aac_dec_sync_error_start = 0x1000, + AAC_DEC_TRANSPORT_SYNC_ERROR = 0x1001, /*!< The transport decoder had syncronisation problems. Do not exit decoding. Just feed new + bitstream data. */ + AAC_DEC_NOT_ENOUGH_BITS = 0x1002, /*!< The input buffer ran out of bits. */ + aac_dec_sync_error_end = 0x1FFF, + + /* Initialization errors. Output buffer is invalid. */ + aac_dec_init_error_start = 0x2000, + AAC_DEC_INVALID_HANDLE = 0x2001, /*!< The handle passed to the function call was invalid (NULL). */ + AAC_DEC_UNSUPPORTED_AOT = 0x2002, /*!< The AOT found in the configuration is not supported. */ + AAC_DEC_UNSUPPORTED_FORMAT = 0x2003, /*!< The bitstream format is not supported. */ + AAC_DEC_UNSUPPORTED_ER_FORMAT = 0x2004, /*!< The error resilience tool format is not supported. */ + AAC_DEC_UNSUPPORTED_EPCONFIG = 0x2005, /*!< The error protection format is not supported. */ + AAC_DEC_UNSUPPORTED_MULTILAYER = 0x2006, /*!< More than one layer for AAC scalable is not supported. */ + AAC_DEC_UNSUPPORTED_CHANNELCONFIG = 0x2007, /*!< The channel configuration (either number or arrangement) is not supported. */ + AAC_DEC_UNSUPPORTED_SAMPLINGRATE = 0x2008, /*!< The sample rate specified in the configuration is not supported. */ + AAC_DEC_INVALID_SBR_CONFIG = 0x2009, /*!< The SBR configuration is not supported. */ + AAC_DEC_SET_PARAM_FAIL = 0x200A, /*!< The parameter could not be set. Either the value was out of range or the parameter does + not exist. */ + AAC_DEC_NEED_TO_RESTART = 0x200B, /*!< The decoder needs to be restarted, since the requiered configuration change cannot be + performed. */ + AAC_DEC_OUTPUT_BUFFER_TOO_SMALL = 0x200C, /*!< The provided output buffer is too small. */ + aac_dec_init_error_end = 0x2FFF, + + /* Decode errors. Output buffer is valid but concealed. */ + aac_dec_decode_error_start = 0x4000, + AAC_DEC_TRANSPORT_ERROR = 0x4001, /*!< The transport decoder encountered an unexpected error. */ + AAC_DEC_PARSE_ERROR = 0x4002, /*!< Error while parsing the bitstream. Most probably it is corrupted, or the system crashed. */ + AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD = 0x4003, /*!< Error while parsing the extension payload of the bitstream. The extension payload type + found is not supported. */ + AAC_DEC_DECODE_FRAME_ERROR = 0x4004, /*!< The parsed bitstream value is out of range. Most probably the bitstream is corrupt, or + the system crashed. */ + AAC_DEC_CRC_ERROR = 0x4005, /*!< The embedded CRC did not match. */ + AAC_DEC_INVALID_CODE_BOOK = 0x4006, /*!< An invalid codebook was signalled. Most probably the bitstream is corrupt, or the system + crashed. */ + AAC_DEC_UNSUPPORTED_PREDICTION = 0x4007, /*!< Predictor found, but not supported in the AAC Low Complexity profile. Most probably the + bitstream is corrupt, or has a wrong format. */ + AAC_DEC_UNSUPPORTED_CCE = 0x4008, /*!< A CCE element was found which is not supported. Most probably the bitstream is corrupt, or + has a wrong format. */ + AAC_DEC_UNSUPPORTED_LFE = 0x4009, /*!< A LFE element was found which is not supported. Most probably the bitstream is corrupt, or + has a wrong format. */ + AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA = 0x400A, /*!< Gain control data found but not supported. Most probably the bitstream is corrupt, or has + a wrong format. */ + AAC_DEC_UNSUPPORTED_SBA = 0x400B, /*!< SBA found, but currently not supported in the BSAC profile. */ + AAC_DEC_TNS_READ_ERROR = 0x400C, /*!< Error while reading TNS data. Most probably the bitstream is corrupt or the system + crashed. */ + AAC_DEC_RVLC_ERROR = 0x400D, /*!< Error while decoding error resillient data. */ + aac_dec_decode_error_end = 0x4FFF, + + /* Ancillary data errors. Output buffer is valid. */ + aac_dec_anc_data_error_start = 0x8000, + AAC_DEC_ANC_DATA_ERROR = 0x8001, /*!< Non severe error concerning the ancillary data handling. */ + AAC_DEC_TOO_SMALL_ANC_BUFFER = 0x8002, /*!< The registered ancillary data buffer is too small to receive the parsed data. */ + AAC_DEC_TOO_MANY_ANC_ELEMENTS = 0x8003, /*!< More than the allowed number of ancillary data elements should be written to buffer. */ + aac_dec_anc_data_error_end = 0x8FFF + + +} AAC_DECODER_ERROR; + +typedef enum { + AAC_DECODER_CHANNEL_SELECT_SELECT_STEREO , + AAC_DECODER_CHANNEL_SELECT_SELECT_LRMERGE, + AAC_DECODER_CHANNEL_SELECT_LCHNL, + AAC_DECODER_CHANNEL_SELECT_RCHNL, +} AAC_DECODER_CHANNEL_SELECT_E; + +/** Macro to identify initialization errors. */ +#define IS_INIT_ERROR(err) ( (((err)>=aac_dec_init_error_start) && ((err)<=aac_dec_init_error_end)) ? 1 : 0) +/** Macro to identify decode errors. */ +#define IS_DECODE_ERROR(err) ( (((err)>=aac_dec_decode_error_start) && ((err)<=aac_dec_decode_error_end)) ? 1 : 0) +/** Macro to identify if the audio output buffer contains valid samples after calling aacDecoder_DecodeFrame(). */ +#define IS_OUTPUT_VALID(err) ( ((err) == AAC_DEC_OK) || IS_DECODE_ERROR(err) ) + +/** + * \brief AAC decoder setting parameters + */ +typedef enum +{ + AAC_PCM_OUTPUT_INTERLEAVED = 0x0000, /*!< PCM output mode (1: interleaved (default); 0: not interleaved). */ + AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE = 0x0002, /*!< Defines how the decoder processes two channel signals: \n + 0: Leave both signals as they are (default). \n + 1: Create a dual mono output signal from channel 1. \n + 2: Create a dual mono output signal from channel 2. \n + 3: Create a dual mono output signal by mixing both channels (L' = R' = 0.5*Ch1 + 0.5*Ch2). */ + AAC_PCM_OUTPUT_CHANNEL_MAPPING = 0x0003, /*!< Output buffer channel ordering. 0: MPEG PCE style order, 1: WAV file channel order (default). */ + AAC_PCM_LIMITER_ENABLE = 0x0004, /*!< Enable signal level limiting. \n + -1: Auto-config. Enable limiter for all non-lowdelay configurations by default. \n + 0: Disable limiter in general. \n + 1: Enable limiter always. + It is recommended to call the decoder with a AACDEC_CLRHIST flag to reset all states when + the limiter switch is changed explicitly. */ + AAC_PCM_LIMITER_ATTACK_TIME = 0x0005, /*!< Signal level limiting attack time in ms. + Default confguration is 15 ms. Adjustable range from 1 ms to 15 ms. */ + AAC_PCM_LIMITER_RELEAS_TIME = 0x0006, /*!< Signal level limiting release time in ms. + Default configuration is 50 ms. Adjustable time must be larger than 0 ms. */ + AAC_PCM_MIN_OUTPUT_CHANNELS = 0x0011, /*!< Minimum number of PCM output channels. If higher than the number of encoded audio channels, + a simple channel extension is applied. \n + -1, 0: Disable channel extenstion feature. The decoder output contains the same number of + channels as the encoded bitstream. \n + 1: This value is currently needed only together with the mix-down feature. See + ::AAC_PCM_MAX_OUTPUT_CHANNELS and note 2 below. \n + 2: Encoded mono signals will be duplicated to achieve a 2/0/0.0 channel output + configuration. \n + 6: The decoder trys to reorder encoded signals with less than six channels to achieve + a 3/0/2.1 channel output signal. Missing channels will be filled with a zero signal. + If reordering is not possible the empty channels will simply be appended. Only + available if instance is configured to support multichannel output. \n + 8: The decoder trys to reorder encoded signals with less than eight channels to + achieve a 3/0/4.1 channel output signal. Missing channels will be filled with a + zero signal. If reordering is not possible the empty channels will simply be + appended. Only available if instance is configured to support multichannel output.\n + NOTE: \n + 1. The channel signalling (CStreamInfo::pChannelType and CStreamInfo::pChannelIndices) + will not be modified. Added empty channels will be signalled with channel type + AUDIO_CHANNEL_TYPE::ACT_NONE. \n + 2. If the parameter value is greater than that of ::AAC_PCM_MAX_OUTPUT_CHANNELS both will + be set to the same value. \n + 3. This parameter does not affect MPEG Surround processing. */ + AAC_PCM_MAX_OUTPUT_CHANNELS = 0x0012, /*!< Maximum number of PCM output channels. If lower than the number of encoded audio channels, + downmixing is applied accordingly. If dedicated metadata is available in the stream it + will be used to achieve better mixing results. \n + -1, 0: Disable downmixing feature. The decoder output contains the same number of channels + as the encoded bitstream. \n + 1: All encoded audio configurations with more than one channel will be mixed down to + one mono output signal. \n + 2: The decoder performs a stereo mix-down if the number encoded audio channels is + greater than two. \n + 6: If the number of encoded audio channels is greater than six the decoder performs a + mix-down to meet the target output configuration of 3/0/2.1 channels. Only + available if instance is configured to support multichannel output. \n + 8: This value is currently needed only together with the channel extension feature. + See ::AAC_PCM_MIN_OUTPUT_CHANNELS and note 2 below. Only available if instance is + configured to support multichannel output. \n + NOTE: \n + 1. Down-mixing of any seven or eight channel configuration not defined in ISO/IEC 14496-3 + PDAM 4 is not supported by this software version. \n + 2. If the parameter value is greater than zero but smaller than ::AAC_PCM_MIN_OUTPUT_CHANNELS + both will be set to same value. \n + 3. The operating mode of the MPEG Surround module will be set accordingly. \n + 4. Setting this param with any value will disable the binaural processing of the MPEG + Surround module (::AAC_MPEGS_BINAURAL_ENABLE=0). */ + + AAC_CONCEAL_METHOD = 0x0100, /*!< Error concealment: Processing method. \n + 0: Spectral muting. \n + 1: Noise substitution (see ::CONCEAL_NOISE). \n + 2: Energy interpolation (adds additional signal delay of one frame, see ::CONCEAL_INTER). \n */ + + AAC_DRC_BOOST_FACTOR = 0x0200, /*!< Dynamic Range Control: Scaling factor for boosting gain values. + Defines how the boosting DRC factors (conveyed in the bitstream) will be applied to the + decoded signal. The valid values range from 0 (don't apply boost factors) to 127 (fully + apply all boosting factors). */ + AAC_DRC_ATTENUATION_FACTOR = 0x0201, /*!< Dynamic Range Control: Scaling factor for attenuating gain values. Same as + AAC_DRC_BOOST_FACTOR but for attenuating DRC factors. */ + AAC_DRC_REFERENCE_LEVEL = 0x0202, /*!< Dynamic Range Control: Target reference level. Defines the level below full-scale + (quantized in steps of 0.25dB) to which the output audio signal will be normalized to by + the DRC module. The valid values range from 0 (full-scale) to 127 (31.75 dB below + full-scale). The value smaller than 0 switches off normalization. */ + AAC_DRC_HEAVY_COMPRESSION = 0x0203, /*!< Dynamic Range Control: En-/Disable DVB specific heavy compression (aka RF mode). + If set to 1, the decoder will apply the compression values from the DVB specific ancillary + data field. At the same time the MPEG-4 Dynamic Range Control tool will be disabled. By + default heavy compression is disabled. */ + + AAC_QMF_LOWPOWER = 0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing mode. \n + -1: Use internal default. Implies MPEG Surround partially complex accordingly. \n + 0: Use complex QMF data mode. \n + 1: Use real (low power) QMF data mode. \n */ + + AAC_MPEGS_ENABLE = 0x0500, /*!< MPEG Surround: Allow/Disable decoding of MPS content. Available only for decoders with MPEG + Surround support. */ + + AAC_TPDEC_CLEAR_BUFFER = 0x0603 /*!< Clear internal bit stream buffer of transport layers. The decoder will start decoding + at new data passed after this event and any previous data is discarded. */ + +} AACDEC_PARAM; + +/** + * \brief This structure gives information about the currently decoded audio data. + * All fields are read-only. + */ +typedef struct +{ + /* These five members are the only really relevant ones for the user. */ + INT sampleRate; /*!< The samplerate in Hz of the fully decoded PCM audio signal (after SBR processing). */ + INT frameSize; /*!< The frame size of the decoded PCM audio signal. \n + 1024 or 960 for AAC-LC \n + 2048 or 1920 for HE-AAC (v2) \n + 512 or 480 for AAC-LD and AAC-ELD */ + INT numChannels; /*!< The number of output audio channels in the decoded and interleaved PCM audio signal. */ + AUDIO_CHANNEL_TYPE *pChannelType; /*!< Audio channel type of each output audio channel. */ + UCHAR *pChannelIndices; /*!< Audio channel index for each output audio channel. + See ISO/IEC 13818-7:2005(E), 8.5.3.2 Explicit channel mapping using a program_config_element() */ + /* Decoder internal members. */ + INT aacSampleRate; /*!< Sampling rate in Hz without SBR (from configuration info). */ + INT profile; /*!< MPEG-2 profile (from file header) (-1: not applicable (e. g. MPEG-4)). */ + AUDIO_OBJECT_TYPE aot; /*!< Audio Object Type (from ASC): is set to the appropriate value for MPEG-2 bitstreams (e. g. 2 for AAC-LC). */ + INT channelConfig; /*!< Channel configuration (0: PCE defined, 1: mono, 2: stereo, ... */ + INT bitRate; /*!< Instantaneous bit rate. */ + INT aacSamplesPerFrame; /*!< Samples per frame for the AAC core (from ASC). \n + 1024 or 960 for AAC-LC \n + 512 or 480 for AAC-LD and AAC-ELD */ + INT aacNumChannels; /*!< The number of audio channels after AAC core processing (before PS or MPS processing). + CAUTION: This are not the final number of output channels! */ + AUDIO_OBJECT_TYPE extAot; /*!< Extension Audio Object Type (from ASC) */ + INT extSamplingRate; /*!< Extension sampling rate in Hz (from ASC) */ + + UINT outputDelay; /*!< The number of samples the output is additionally delayed by the decoder. */ + + UINT flags; /*!< Copy of internal flags. Only to be written by the decoder, and only to be read externally. */ + + SCHAR epConfig; /*!< epConfig level (from ASC): only level 0 supported, -1 means no ER (e. g. AOT=2, MPEG-2 AAC, etc.) */ + + /* Statistics */ + INT numLostAccessUnits; /*!< This integer will reflect the estimated amount of lost access units in case aacDecoder_DecodeFrame() + returns AAC_DEC_TRANSPORT_SYNC_ERROR. It will be < 0 if the estimation failed. */ + + UINT numTotalBytes; /*!< This is the number of total bytes that have passed through the decoder. */ + UINT numBadBytes; /*!< This is the number of total bytes that were considered with errors from numTotalBytes. */ + UINT numTotalAccessUnits; /*!< This is the number of total access units that have passed through the decoder. */ + UINT numBadAccessUnits; /*!< This is the number of total access units that were considered with errors from numTotalBytes. */ + + /* Metadata */ + SCHAR drcProgRefLev; /*!< DRC program reference level. Defines the reference level below full-scale. + It is quantized in steps of 0.25dB. The valid values range from 0 (0 dBFS) to 127 (-31.75 dBFS). + It is used to reflect the average loudness of the audio in LKFS accoring to ITU-R BS 1770. + If no level has been found in the bitstream the value is -1. */ + SCHAR drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154, this field indicates whether + light (MPEG-4 Dynamic Range Control tool) or heavy compression (DVB heavy compression) + dynamic range control shall take priority on the outputs. + For details, see ETSI TS 101 154, table C.33. Possible values are: \n + -1: No corresponding metadata found in the bitstream \n + 0: DRC presentation mode not indicated \n + 1: DRC presentation mode 1 \n + 2: DRC presentation mode 2 \n + 3: Reserved */ + +} CStreamInfo; + + +typedef struct AAC_DECODER_INSTANCE *HANDLE_AACDECODER; /*!< Pointer to a AAC decoder instance. */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * \brief Initialize ancillary data buffer. + * + * \param self AAC decoder handle. + * \param buffer Pointer to (external) ancillary data buffer. + * \param size Size of the buffer pointed to by buffer. + * \return Error code. + */ +LINKSPEC_H AAC_DECODER_ERROR +aacDecoder_AncDataInit ( HANDLE_AACDECODER self, + UCHAR *buffer, + int size ); + +/** + * \brief Get one ancillary data element. + * + * \param self AAC decoder handle. + * \param index Index of the ancillary data element to get. + * \param ptr Pointer to a buffer receiving a pointer to the requested ancillary data element. + * \param size Pointer to a buffer receiving the length of the requested ancillary data element. + * \return Error code. + */ +LINKSPEC_H AAC_DECODER_ERROR +aacDecoder_AncDataGet ( HANDLE_AACDECODER self, + int index, + UCHAR **ptr, + int *size ); + +/** + * \brief Set one single decoder parameter. + * + * \param self AAC decoder handle. + * \param param Parameter to be set. + * \param value Parameter value. + * \return Error code. + */ +LINKSPEC_H AAC_DECODER_ERROR +aacDecoder_SetParam ( const HANDLE_AACDECODER self, + const AACDEC_PARAM param, + const INT value ); + + +/** + * \brief Get free bytes inside decoder internal buffer + * \param self Handle of AAC decoder instance + * \param pFreeBytes Pointer to variable receving amount of free bytes inside decoder internal buffer + * \return Error code + */ +LINKSPEC_H AAC_DECODER_ERROR +aacDecoder_GetFreeBytes ( const HANDLE_AACDECODER self, + UINT *pFreeBytes); + +/** + * \brief Open an AAC decoder instance + * \param transportFmt The transport type to be used + * \return AAC decoder handle + */ +LINKSPEC_H HANDLE_AACDECODER +aacDecoder_Open ( TRANSPORT_TYPE transportFmt, UINT nrOfLayers ); + +/** + * \brief Explicitly configure the decoder by passing a raw AudioSpecificConfig (ASC) or a StreamMuxConfig (SMC), + * contained in a binary buffer. This is required for MPEG-4 and Raw Packets file format bitstreams + * as well as for LATM bitstreams with no in-band SMC. If the transport format is LATM with or without + * LOAS, configuration is assumed to be an SMC, for all other file formats an ASC. + * + * \param self AAC decoder handle. + * \param conf Pointer to an unsigned char buffer containing the binary configuration buffer (either ASC or SMC). + * \param length Length of the configuration buffer in bytes. + * \return Error code. + */ +LINKSPEC_H AAC_DECODER_ERROR +aacDecoder_ConfigRaw ( HANDLE_AACDECODER self, + UCHAR *conf[], + const UINT length[] ); + + +/** + * \brief Fill AAC decoder's internal input buffer with bitstream data from the external input buffer. + * The function only copies such data as long as the decoder-internal input buffer is not full. + * So it grabs whatever it can from pBuffer and returns information (bytesValid) so that at a + * subsequent call of %aacDecoder_Fill(), the right position in pBuffer can be determined to + * grab the next data. + * + * \param self AAC decoder handle. + * \param pBuffer Pointer to external input buffer. + * \param bufferSize Size of external input buffer. This argument is required because decoder-internally + * we need the information to calculate the offset to pBuffer, where the next + * available data is, which is then fed into the decoder-internal buffer (as much + * as possible). Our example framework implementation fills the buffer at pBuffer + * again, once it contains no available valid bytes anymore (meaning bytesValid equal 0). + * \param bytesValid Number of bitstream bytes in the external bitstream buffer that have not yet been + * copied into the decoder's internal bitstream buffer by calling this function. + * The value is updated according to the amount of newly copied bytes. + * \return Error code. + */ +LINKSPEC_H AAC_DECODER_ERROR +aacDecoder_Fill ( HANDLE_AACDECODER self, + UCHAR *pBuffer[], + const UINT bufferSize[], + UINT *bytesValid ); + +#define AACDEC_CONCEAL 1 /*!< Flag for aacDecoder_DecodeFrame(): Trigger the built-in error concealment module \ + to generate a substitute signal for one lost frame. New input data will not be + considered. */ +#define AACDEC_FLUSH 2 /*!< Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all delayed audio \ + without having new input data. Thus new input data will not be considered.*/ +#define AACDEC_INTR 4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data discontinuity. \ + Resync any internals as necessary. */ +#define AACDEC_CLRHIST 8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and history buffers.\ + CAUTION: This can cause discontinuities in the output signal. */ + +/** + * \brief Decode one audio frame + * + * \param self AAC decoder handle. + * \param pTimeData Pointer to external output buffer where the decoded PCM samples will be stored into. + * \param flags Bit field with flags for the decoder: \n + * (flags & AACDEC_CONCEAL) == 1: Do concealment. \n + * (flags & AACDEC_FLUSH) == 2: Discard input data. Flush filter banks (output delayed audio). \n + * (flags & AACDEC_INTR) == 4: Input data is discontinuous. Resynchronize any internals as necessary. + * \return Error code. + */ +LINKSPEC_H AAC_DECODER_ERROR +aacDecoder_DecodeFrame ( HANDLE_AACDECODER self, + INT_PCM *pTimeData, + const INT timeDataSize, + const UINT flags ); + +/** + * \brief De-allocate all resources of an AAC decoder instance. + * + * \param self AAC decoder handle. + * \return void + */ +LINKSPEC_H void aacDecoder_Close ( HANDLE_AACDECODER self ); + +LINKSPEC_CPP bool is_aacDecoder_Close ( HANDLE_AACDECODER self ); + +/** + * \brief Get CStreamInfo handle from decoder. + * + * \param self AAC decoder handle. + * \return Reference to requested CStreamInfo. + */ +LINKSPEC_H CStreamInfo* aacDecoder_GetStreamInfo( HANDLE_AACDECODER self ); + +/** + * \brief Get decoder library info. + * + * \param info Pointer to an allocated LIB_INFO structure. + * \return 0 on success + */ +LINKSPEC_H INT aacDecoder_GetLibInfo( LIB_INFO *info ); + +LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame_Config(UINT chnl_sel); + +#ifdef __cplusplus +} +#endif + +#endif /* AACDECODER_LIB_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libAACenc/include/aacenc_lib.h b/services/multimedia/audio/codec/fdkaac_codec/libAACenc/include/aacenc_lib.h new file mode 100644 index 0000000..f0caf3d --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libAACenc/include/aacenc_lib.h @@ -0,0 +1,1239 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/**************************** MPEG-4 HE-AAC Encoder ************************** + + Initial author: M. Lohwasser +******************************************************************************/ + +/** + * \file aacenc_lib.h + * \brief FDK AAC Encoder library interface header file. + * +\mainpage Introduction + +\section Scope + +This document describes the high-level interface and usage of the ISO/MPEG-2/4 AAC Encoder +library developed by the Fraunhofer Institute for Integrated Circuits (IIS). + +The library implements encoding on the basis of the MPEG-2 and MPEG-4 AAC Low-Complexity +standard, and depending on the library's configuration, MPEG-4 High-Efficiency AAC v2 and/or AAC-ELD standard. + +All references to SBR (Spectral Band Replication) are only applicable to HE-AAC or AAC-ELD versions +of the library. All references to PS (Parametric Stereo) are only applicable to HE-AAC v2 +versions of the library. + +\section encBasics Encoder Basics + +This document can only give a rough overview about the ISO/MPEG-2 and ISO/MPEG-4 AAC audio coding +standard. To understand all the terms in this document, you are encouraged to read the following documents. + +- ISO/IEC 13818-7 (MPEG-2 AAC), which defines the syntax of MPEG-2 AAC audio bitstreams. +- ISO/IEC 14496-3 (MPEG-4 AAC, subparts 1 and 4), which defines the syntax of MPEG-4 AAC audio bitstreams. +- Lutzky, Schuller, Gayer, Krämer, Wabnik, "A guideline to audio codec delay", 116th AES Convention, May 8, 2004 + +MPEG Advanced Audio Coding is based on a time-to-frequency mapping of the signal. The signal is +partitioned into overlapping portions and transformed into frequency domain. The spectral components +are then quantized and coded. \n +An MPEG-2 or MPEG-4 AAC audio bitstream is composed of frames. Contrary to MPEG-1/2 Layer-3 (mp3), the +length of individual frames is not restricted to a fixed number of bytes, but can take on any length +between 1 and 768 bytes. + + +\page LIBUSE Library Usage + +\section InterfaceDescription API Files + +All API header files are located in the folder /include of the release package. All header files +are provided for usage in C/C++ programs. The AAC encoder library API functions are located at +aacenc_lib.h. + +In binary releases the encoder core resides in statically linkable libraries called for example +libAACenc.a/libFDK.a (LINUX) or FDK_fastaaclib.lib (MS Visual C++) for the plain AAC-LC core encoder +and libSBRenc.a (LINUX) or FDK_sbrEncLib.lib (MS Visual C++) for the SBR (Spectral Band +Replication) and PS (Parametric Stereo) modules. + +\section CallingSequence Calling Sequence + +For encoding of ISO/MPEG-2/4 AAC bitstreams the following sequence is mandatory. Input read and output +write functions as well as the corresponding open and close functions are left out, since they may be +implemented differently according to the user's specific requirements. The example implementation in +main.cpp uses file-based input/output. + +-# Call aacEncOpen() to allocate encoder instance with required \ref encOpen "configuration".\n +\dontinclude main.cpp +\skipline hAacEncoder = +\skipline aacEncOpen +-# Call aacEncoder_SetParam() for each parameter to be set. AOT, samplingrate, channelMode, bitrate and transport type are \ref encParams "mandatory". +\code + ErrorStatus = aacEncoder_SetParam(hAacEncoder, parameter, value); +\endcode +-# Call aacEncEncode() with NULL parameters to \ref encReconf "initialize" encoder instance with present parameter set. +\skipline aacEncEncode +-# Call aacEncInfo() to retrieve a configuration data block to be transmitted out of band. This is required when using RFC3640 or RFC3016 like transport. +\dontinclude main.cpp +\skipline encInfo +\skipline aacEncInfo +-# Encode input audio data in loop. +\skip Encode as long as +\skipline do +\until { +Feed \ref feedInBuf "input buffer" with new audio data and provide input/output \ref bufDes "arguments" to aacEncEncode(). +\skipline aacEncEncode +\until ; +Write \ref writeOutData "output data" to file or audio device. \skipline while +-# Call aacEncClose() and destroy encoder instance. +\skipline aacEncClose + +\section encOpen Encoder Instance Allocation + +The assignment of the aacEncOpen() function is very flexible and can be used in the following way. +- If the amount of memory consumption is not an issue, the encoder instance can be allocated +for the maximum number of possible audio channels (for example 6 or 8) with the full functional range supported by the library. +This is the default open procedure for the AAC encoder if memory consumption does not need to be minimized. +\code aacEncOpen(&hAacEncoder,0,0) \endcode +- If the required MPEG-4 AOTs do not call for the full functional range of the library, encoder modules can be allocated selectively. +\verbatim +------------------------------------------------------ + AAC | SBR | PS | MD | FLAGS | value +-----+-----+-----+----+-----------------------+------- + X | - | - | - | (0x01) | 0x01 + X | X | - | - | (0x01|0x02) | 0x03 + X | X | X | - | (0x01|0x02|0x04) | 0x07 + X | - | - | X | (0x01 |0x10) | 0x11 + X | X | - | X | (0x01|0x02 |0x10) | 0x13 + X | X | X | X | (0x01|0x02|0x04|0x10) | 0x17 +------------------------------------------------------ + - AAC: Allocate AAC Core Encoder module. + - SBR: Allocate Spectral Band Replication module. + - PS: Allocate Parametric Stereo module. + - MD: Allocate Meta Data module within AAC encoder. +\endverbatim +\code aacEncOpen(&hAacEncoder,value,0) \endcode +- Specifying the maximum number of channels to be supported in the encoder instance can be done as follows. + - For example allocate an encoder instance which supports 2 channels for all supported AOTs. + The library itself may be capable of encoding up to 6 or 8 channels but in this example only 2 channel encoding is required and thus only buffers for 2 channels are allocated to save data memory. +\code aacEncOpen(&hAacEncoder,0,2) \endcode + - Additionally the maximum number of supported channels in the SBR module can be denoted separately.\n + In this example the encoder instance provides a maximum of 6 channels out of which up to 2 channels support SBR. + This encoder instance can produce for example 5.1 channel AAC-LC streams or stereo HE-AAC (v2) streams. + HE-AAC 5.1 multi channel is not possible since only 2 out of 6 channels support SBR, which saves data memory. +\code aacEncOpen(&hAacEncoder,0,6|(2<<8)) \endcode +\n + +\section bufDes Input/Output Arguments + +\subsection allocIOBufs Provide Buffer Descriptors +In the present encoder API, the input and output buffers are described with \ref AACENC_BufDesc "buffer descriptors". This mechanism allows a flexible handling +of input and output buffers without impact to the actual encoding call. Optional buffers are necessary e.g. for ancillary data, meta data input or additional output +buffers describing superframing data in DAB+ or DRM+.\n +At least one input buffer for audio input data and one output buffer for bitstream data must be allocated. The input buffer size can be a user defined multiple +of the number of input channels. PCM input data will be copied from the user defined PCM buffer to an internal input buffer and so input data can be less than one AAC audio frame. +The output buffer size should be 6144 bits per channel excluding the LFE channel. +If the output data does not fit into the provided buffer, an AACENC_ERROR will be returned by aacEncEncode(). +\dontinclude main.cpp +\skipline inputBuffer +\until outputBuffer +All input and output buffer must be clustered in input and output buffer arrays. +\skipline inBuffer +\until outBufferElSize +Allocate buffer descriptors +\skipline AACENC_BufDesc +\skipline AACENC_BufDesc +Initialize input buffer descriptor +\skipline inBufDesc +\until bufElSizes +Initialize output buffer descriptor +\skipline outBufDesc +\until bufElSizes + +\subsection argLists Provide Input/Output Argument Lists +The input and output arguments of an aacEncEncode() call are described in argument structures. +\dontinclude main.cpp +\skipline AACENC_InArgs +\skipline AACENC_OutArgs + +\section feedInBuf Feed Input Buffer +The input buffer should be handled as a modulo buffer. New audio data in the form of pulse-code- +modulated samples (PCM) must be read from external and be fed to the input buffer depending on its +fill level. The required sample bitrate (represented by the data type INT_PCM which is 16, 24 or 32 +bits wide) is fixed and depends on library configuration (usually 16 bit). + +\dontinclude main.cpp +\skipline WAV_InputRead +\until ; +After the encoder's internal buffer is fed with incoming audio samples, and aacEncEncode() +processed the new input data, update/move remaining samples in input buffer, simulating a modulo buffer: +\skipline outargs.numInSamples>0 +\until } + +\section writeOutData Output Bitstream Data +If any AAC bitstream data is available, write it to output file or device. This can be done once the +following condition is true: +\dontinclude main.cpp +\skip Valid bitstream available +\skipline outargs + +\skipline outBytes>0 + +If you use file I/O then for example call mpegFileWrite_Write() from the library libMpegFileWrite + +\dontinclude main.cpp +\skipline mpegFileWrite_Write + +\section cfgMetaData Meta Data Configuration + +If the present library is configured with Metadata support, it is possible to insert meta data side info into the generated +audio bitstream while encoding. + +To work with meta data the encoder instance has to be \ref encOpen "allocated" with meta data support. The meta data mode must be be configured with +the ::AACENC_METADATA_MODE parameter and aacEncoder_SetParam() function. +\code aacEncoder_SetParam(hAacEncoder, AACENC_METADATA_MODE, 0-2); \endcode + +This configuration indicates how to embed meta data into bitstrem. Either no insertion, MPEG or ETSI style. +The meta data itself must be specified within the meta data setup structure AACENC_MetaData. + +Changing one of the AACENC_MetaData setup parameters can be achieved from outside the library within ::IN_METADATA_SETUP input +buffer. There is no need to supply meta data setup structure every frame. If there is no new meta setup data available, the +encoder uses the previous setup or the default configuration in initial state. + +In general the audio compressor and limiter within the encoder library can be configured with the ::AACENC_METADATA_DRC_PROFILE parameter +AACENC_MetaData::drc_profile and and AACENC_MetaData::comp_profile. +\n + +\section encReconf Encoder Reconfiguration + +The encoder library allows reconfiguration of the encoder instance with new settings +continuously between encoding frames. Each parameter to be changed must be set with +a single aacEncoder_SetParam() call. The internal status of each parameter can be +retrieved with an aacEncoder_GetParam() call.\n +There is no stand-alone reconfiguration function available. When parameters were +modified from outside the library, an internal control mechanism triggers the necessary +reconfiguration process which will be applied at the beginning of the following +aacEncEncode() call. This state can be observed from external via the AACENC_INIT_STATUS +and aacEncoder_GetParam() function. The reconfiguration process can also be applied +immediately when all parameters of an aacEncEncode() call are NULL with a valid encoder +handle.\n\n +The internal reconfiguration process can be controlled from extern with the following access. +\code aacEncoder_SetParam(hAacEncoder, AACENC_CONTROL_STATE, AACENC_CTRLFLAGS); \endcode + + +\section encParams Encoder Parametrization + +All parameteres listed in ::AACENC_PARAM can be modified within an encoder instance. + +\subsection encMandatory Mandatory Encoder Parameters +The following parameters must be specified when the encoder instance is initialized. +\code +aacEncoder_SetParam(hAacEncoder, AACENC_AOT, value); +aacEncoder_SetParam(hAacEncoder, AACENC_BITRATE, value); +aacEncoder_SetParam(hAacEncoder, AACENC_SAMPLERATE, value); +aacEncoder_SetParam(hAacEncoder, AACENC_CHANNELMODE, value); +\endcode +Beyond that is an internal auto mode which preinitizializes the ::AACENC_BITRATE parameter +if the parameter was not set from extern. The bitrate depends on the number of effective +channels and sampling rate and is determined as follows. +\code +AAC-LC (AOT_AAC_LC): 1.5 bits per sample +HE-AAC (AOT_SBR): 0.625 bits per sample (dualrate sbr) +HE-AAC (AOT_SBR): 1.125 bits per sample (downsampled sbr) +HE-AAC v2 (AOT_PS): 0.5 bits per sample +\endcode + +\subsection channelMode Channel Mode Configuration +The input audio data is described with the ::AACENC_CHANNELMODE parameter in the +aacEncoder_SetParam() call. It is not possible to use the encoder instance with a 'number of +input channels' argument. Instead, the channelMode must be set as follows. +\code aacEncoder_SetParam(hAacEncoder, AACENC_CHANNELMODE, value); \endcode +The parameter is specified in ::CHANNEL_MODE and can be mapped from the number of input channels +in the following way. +\dontinclude main.cpp +\skip CHANNEL_MODE chMode = MODE_INVALID; +\until return + +\subsection encQual Audio Quality Considerations +The default encoder configuration is suggested to be used. Encoder tools such as TNS and PNS +are activated by default and are internally controlled (see \ref BEHAVIOUR_TOOLS). + +There is an additional quality parameter called ::AACENC_AFTERBURNER. In the default +configuration this quality switch is deactivated because it would cause a workload +increase which might be significant. If workload is not an issue in the application +we recommended to activate this feature. +\code aacEncoder_SetParam(hAacEncoder, AACENC_AFTERBURNER, 1); \endcode + +\subsection encELD ELD Auto Configuration Mode +For ELD configuration a so called auto configurator is available which configures SBR and the SBR ratio by itself. +The configurator is used when the encoder parameter ::AACENC_SBR_MODE and ::AACENC_SBR_RATIO are not set explicitely. + +Based on sampling rate and chosen bitrate per channel a reasonable SBR configuration will be used. +\verbatim +------------------------------------------------------------ + Sampling Rate | Channel Bitrate | SBR | SBR Ratio +-----------------+-----------------+------+----------------- + ]min, 16] kHz | min - 27999 | on | downsampled SBR + | 28000 - max | off | --- +-----------------+-----------------+------+----------------- + ]16 - 24] kHz | min - 39999 | on | downsampled SBR + | 40000 - max | off | --- +-----------------+-----------------+------+----------------- + ]24 - 32] kHz | min - 27999 | on | dualrate SBR + | 28000 - 55999 | on | downsampled SBR + | 56000 - max | off | --- +-----------------+-----------------+------+----------------- + ]32 - 44.1] kHz | min - 63999 | on | dualrate SBR + | 64000 - max | off | --- +-----------------+-----------------+------+----------------- + ]44.1 - 48] kHz | min - 63999 | on | dualrate SBR + | 64000 - max | off | --- +------------------------------------------------------------ +\endverbatim + + +\section audiochCfg Audio Channel Configuration +The MPEG standard refers often to the so-called Channel Configuration. This Channel Configuration is used for a fixed Channel +Mapping. The configurations 1-7 are predefined in MPEG standard and used for implicit signalling within the encoded bitstream. +For user defined Configurations the Channel Configuration is set to 0 and the Channel Mapping must be explecitly described with an appropriate +Program Config Element. The present Encoder implementation does not allow the user to configure this Channel Configuration from +extern. The Encoder implementation supports fixed Channel Modes which are mapped to Channel Configuration as follow. +\verbatim +------------------------------------------------------------------------------- + ChannelMode | ChCfg | front_El | side_El | back_El | lfe_El +-----------------------+--------+---------------+----------+----------+-------- +MODE_1 | 1 | SCE | | | +MODE_2 | 2 | CPE | | | +MODE_1_2 | 3 | SCE, CPE | | | +MODE_1_2_1 | 4 | SCE, CPE | | SCE | +MODE_1_2_2 | 5 | SCE, CPE | | CPE | +MODE_1_2_2_1 | 6 | SCE, CPE | | CPE | LFE +MODE_1_2_2_2_1 | 7 | SCE, CPE, CPE | | CPE | LFE +-----------------------+--------+---------------+----------+----------+-------- +MODE_7_1_REAR_SURROUND | 0 | SCE, CPE | | CPE, CPE | LFE +MODE_7_1_FRONT_CENTER | 0 | SCE, CPE, CPE | | CPE | LFE +------------------------------------------------------------------------------- + - SCE: Single Channel Element. + - CPE: Channel Pair. + - SCE: Low Frequency Element. +\endverbatim + +Moreover, the Table describes all fixed Channel Elements for each Channel Mode which are assigned to a speaker arrangement. The +arrangement includes front, side, back and lfe Audio Channel Elements.\n +This mapping of Audio Channel Elements is defined in MPEG standard for Channel Config 1-7. The Channel assignment for MODE_1_1, +MODE_2_2 and MODE_2_1 is used from the ARIB standard. All other configurations are defined as suggested in MPEG.\n +In case of Channel Config 0 or writing matrix mixdown coefficients, the encoder enables the writing of Program Config Element +itself as described in \ref encPCE. The configuration used in Program Config Element refers to the denoted Table.\n +Beside the Channel Element assignment the Channel Modes are resposible for audio input data channel mapping. The Channel Mapping +of the audio data depends on the selected ::AACENC_CHANNELORDER which can be MPEG or WAV like order.\n +Following Table describes the complete channel mapping for both Channel Order configurations. +\verbatim +--------------------------------------------------------------------------------------- +ChannelMode | MPEG-Channelorder | WAV-Channelorder +-----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--- +MODE_1 | 0 | | | | | | | | 0 | | | | | | | +MODE_2 | 0 | 1 | | | | | | | 0 | 1 | | | | | | +MODE_1_2 | 0 | 1 | 2 | | | | | | 2 | 0 | 1 | | | | | +MODE_1_2_1 | 0 | 1 | 2 | 3 | | | | | 2 | 0 | 1 | 3 | | | | +MODE_1_2_2 | 0 | 1 | 2 | 3 | 4 | | | | 2 | 0 | 1 | 3 | 4 | | | +MODE_1_2_2_1 | 0 | 1 | 2 | 3 | 4 | 5 | | | 2 | 0 | 1 | 4 | 5 | 3 | | +MODE_1_2_2_2_1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 | 6 | 7 | 0 | 1 | 4 | 5 | 3 +-----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--- +MODE_7_1_REAR_SURROUND | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 | 0 | 1 | 6 | 7 | 4 | 5 | 3 +MODE_7_1_FRONT_CENTER | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 | 6 | 7 | 0 | 1 | 4 | 5 | 3 +--------------------------------------------------------------------------------------- +\endverbatim + +The denoted mapping is important for correct audio channel assignment when using MPEG or WAV ordering. The incoming audio +channels are distributed MPEG like starting at the front channels and ending at the back channels. The distribution is used as +described in Table concering Channel Config and fix channel elements. Please see the following example for clarification. + +\verbatim +Example: MODE_1_2_2_1 - WAV-Channelorder 5.1 +------------------------------------------ + Input Channel | Coder Channel +--------------------+--------------------- + 2 (front center) | 0 (SCE channel) + 0 (left center) | 1 (1st of 1st CPE) + 1 (right center) | 2 (2nd of 1st CPE) + 4 (left surround) | 3 (1st of 2nd CPE) + 5 (right surround) | 4 (2nd of 2nd CPE) + 3 (LFE) | 5 (LFE) +------------------------------------------ +\endverbatim + + +\section suppBitrates Supported Bitrates + +The FDK AAC Encoder provides a wide range of supported bitrates. +The minimum and maximum allowed bitrate depends on the Audio Object Type. For AAC-LC the minimum +bitrate is the bitrate that is required to write the most basic and minimal valid bitstream. +It consists of the bitstream format header information and other static/mandatory information +within the AAC payload. The maximum AAC framesize allowed by the MPEG-4 standard +determines the maximum allowed bitrate for AAC-LC. For HE-AAC and HE-AAC v2 a library internal +look-up table is used. + +A good working point in terms of audio quality, sampling rate and bitrate, is at 1 to 1.5 +bits/audio sample for AAC-LC, 0.625 bits/audio sample for dualrate HE-AAC, 1.125 bits/audio sample +for downsampled HE-AAC and 0.5 bits/audio sample for HE-AAC v2. +For example for one channel with a sampling frequency of 48 kHz, the range from +48 kbit/s to 72 kbit/s achieves reasonable audio quality for AAC-LC. + +For HE-AAC and HE-AAC v2 the lowest possible audio input sampling frequency is 16 kHz because then the +AAC-LC core encoder operates in dual rate mode at its lowest possible sampling frequency, which is 8 kHz. +HE-AAC v2 requires stereo input audio data. + +Please note that in HE-AAC or HE-AAC v2 mode the encoder supports much higher bitrates than are +appropriate for HE-AAC or HE-AAC v2. For example, at a bitrate of more than 64 kbit/s for a stereo +audio signal at 44.1 kHz it usually makes sense to use AAC-LC, which will produce better audio +quality at that bitrate than HE-AAC or HE-AAC v2. + +\section reommendedConfig Recommended Sampling Rate and Bitrate Combinations + +The following table provides an overview of recommended encoder configuration parameters +which we determined by virtue of numerous listening tests. + +\subsection reommendedConfigLC AAC-LC, HE-AAC, HE-AACv2 in Dualrate SBR mode. +\verbatim +----------------------------------------------------------------------------------- +Audio Object Type | Bit Rate Range | Supported | Preferred | No. of + | [bit/s] | Sampling Rates | Sampl. | Chan. + | | [kHz] | Rate | + | | | [kHz] | +-------------------+------------------+-----------------------+------------+------- +AAC LC + SBR + PS | 8000 - 11999 | 22.05, 24.00 | 24.00 | 2 +AAC LC + SBR + PS | 12000 - 17999 | 32.00 | 32.00 | 2 +AAC LC + SBR + PS | 18000 - 39999 | 32.00, 44.10, 48.00 | 44.10 | 2 +AAC LC + SBR + PS | 40000 - 56000 | 32.00, 44.10, 48.00 | 48.00 | 2 +-------------------+------------------+-----------------------+------------+------- +AAC LC + SBR | 8000 - 11999 | 22.05, 24.00 | 24.00 | 1 +AAC LC + SBR | 12000 - 17999 | 32.00 | 32.00 | 1 +AAC LC + SBR | 18000 - 39999 | 32.00, 44.10, 48.00 | 44.10 | 1 +AAC LC + SBR | 40000 - 56000 | 32.00, 44.10, 48.00 | 48.00 | 1 +AAC LC + SBR | 16000 - 27999 | 32.00, 44.10, 48.00 | 32.00 | 2 +AAC LC + SBR | 28000 - 63999 | 32.00, 44.10, 48.00 | 44.10 | 2 +AAC LC + SBR | 64000 - 128000 | 32.00, 44.10, 48.00 | 48.00 | 2 +-------------------+------------------+-----------------------+------------+------- +AAC LC + SBR | 64000 - 69999 | 32.00, 44.10, 48.00 | 32.00 | 5, 5.1 +AAC LC + SBR | 70000 - 159999 | 32.00, 44.10, 48.00 | 44.10 | 5, 5.1 +AAC LC + SBR | 160000 - 245999 | 32.00, 44.10, 48.00 | 48.00 | 5 +AAC LC + SBR | 160000 - 265999 | 32.00, 44.10, 48.00 | 48.00 | 5.1 +-------------------+------------------+-----------------------+------------+------- +AAC LC | 8000 - 15999 | 11.025, 12.00, 16.00 | 12.00 | 1 +AAC LC | 16000 - 23999 | 16.00 | 16.00 | 1 +AAC LC | 24000 - 31999 | 16.00, 22.05, 24.00 | 24.00 | 1 +AAC LC | 32000 - 55999 | 32.00 | 32.00 | 1 +AAC LC | 56000 - 160000 | 32.00, 44.10, 48.00 | 44.10 | 1 +AAC LC | 160001 - 288000 | 48.00 | 48.00 | 1 +-------------------+------------------+-----------------------+------------+------- +AAC LC | 16000 - 23999 | 11.025, 12.00, 16.00 | 12.00 | 2 +AAC LC | 24000 - 31999 | 16.00 | 16.00 | 2 +AAC LC | 32000 - 39999 | 16.00, 22.05, 24.00 | 22.05 | 2 +AAC LC | 40000 - 95999 | 32.00 | 32.00 | 2 +AAC LC | 96000 - 111999 | 32.00, 44.10, 48.00 | 32.00 | 2 +AAC LC | 112000 - 320001 | 32.00, 44.10, 48.00 | 44.10 | 2 +AAC LC | 320002 - 576000 | 48.00 | 48.00 | 2 +-------------------+------------------+-----------------------+------------+------- +AAC LC | 160000 - 239999 | 32.00 | 32.00 | 5, 5.1 +AAC LC | 240000 - 279999 | 32.00, 44.10, 48.00 | 32.00 | 5, 5.1 +AAC LC | 280000 - 800000 | 32.00, 44.10, 48.00 | 44.10 | 5, 5.1 +----------------------------------------------------------------------------------- +\endverbatim \n + +\subsection reommendedConfigLD AAC-LD, AAC-ELD, AAC-ELD with SBR in Dualrate SBR mode. +\verbatim +----------------------------------------------------------------------------------- +Audio Object Type | Bit Rate Range | Supported | Preferred | No. of + | [bit/s] | Sampling Rates | Sampl. | Chan. + | | [kHz] | Rate | + | | | [kHz] | +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 18000 - 24999 | 32.00 - 44.10 | 32.00 | 1 +ELD + SBR | 25000 - 31999 | 32.00 - 48.00 | 32.00 | 1 +ELD + SBR | 32000 - 64000 | 32.00 - 48.00 | 48.00 | 1 +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 32000 - 51999 | 32.00 - 48.00 | 44.10 | 2 +ELD + SBR | 52000 - 128000 | 32.00 - 48.00 | 48.00 | 2 +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 72000 - 160000 | 44.10 - 48.00 | 48.00 | 3 +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 96000 - 212000 | 44.10 - 48.00 | 48.00 | 4 +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 120000 - 246000 | 44.10 - 48.00 | 48.00 | 5 +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 120000 - 266000 | 44.10 - 48.00 | 48.00 | 5.1 +-------------------+------------------+-----------------------+------------+------- +LD, ELD | 16000 - 19999 | 16.00 - 24.00 | 16.00 | 1 +LD, ELD | 20000 - 39999 | 16.00 - 32.00 | 24.00 | 1 +LD, ELD | 40000 - 49999 | 22.05 - 32.00 | 32.00 | 1 +LD, ELD | 50000 - 61999 | 24.00 - 44.10 | 32.00 | 1 +LD, ELD | 62000 - 84999 | 32.00 - 48.00 | 44.10 | 1 +LD, ELD | 85000 - 192000 | 44.10 - 48.00 | 48.00 | 1 +-------------------+------------------+-----------------------+------------+------- +LD, ELD | 64000 - 75999 | 24.00 - 32.00 | 32.00 | 2 +LD, ELD | 76000 - 97999 | 24.00 - 44.10 | 32.00 | 2 +LD, ELD | 98000 - 135999 | 32.00 - 48.00 | 44.10 | 2 +LD, ELD | 136000 - 384000 | 44.10 - 48.00 | 48.00 | 2 +-------------------+------------------+-----------------------+------------+------- +LD, ELD | 96000 - 113999 | 24.00 - 32.00 | 32.00 | 3 +LD, ELD | 114000 - 146999 | 24.00 - 44.10 | 32.00 | 3 +LD, ELD | 147000 - 203999 | 32.00 - 48.00 | 44.10 | 3 +LD, ELD | 204000 - 576000 | 44.10 - 48.00 | 48.00 | 3 +-------------------+------------------+-----------------------+------------+------- +LD, ELD | 128000 - 151999 | 24.00 - 32.00 | 32.00 | 4 +LD, ELD | 152000 - 195999 | 24.00 - 44.10 | 32.00 | 4 +LD, ELD | 196000 - 271999 | 32.00 - 48.00 | 44.10 | 4 +LD, ELD | 272000 - 768000 | 44.10 - 48.00 | 48.00 | 4 +-------------------+------------------+-----------------------+------------+------- +LD, ELD | 160000 - 189999 | 24.00 - 32.00 | 32.00 | 5 +LD, ELD | 190000 - 244999 | 24.00 - 44.10 | 32.00 | 5 +LD, ELD | 245000 - 339999 | 32.00 - 48.00 | 44.10 | 5 +LD, ELD | 340000 - 960000 | 44.10 - 48.00 | 48.00 | 5 +----------------------------------------------------------------------------------- +\endverbatim \n + +\subsection reommendedConfigELD AAC-ELD with SBR in Downsampled SBR mode. +\verbatim +----------------------------------------------------------------------------------- +Audio Object Type | Bit Rate Range | Supported | Preferred | No. of + | [bit/s] | Sampling Rates | Sampl. | Chan. + | | [kHz] | Rate | + | | | [kHz] | +-------------------+------------------+-----------------------+------------+------- +ELD + SBR | 18000 - 24999 | 16.00 - 22.05 | 22.05 | 1 +(downsampled SBR) | 25000 - 35999 | 22.05 - 32.00 | 24.00 | 1 + | 36000 - 64000 | 32.00 - 48.00 | 32.00 | 1 +----------------------------------------------------------------------------------- +\endverbatim \n + + +\page ENCODERBEHAVIOUR Encoder Behaviour + +\section BEHAVIOUR_BANDWIDTH Bandwidth + +The FDK AAC encoder usually does not use the full frequency range of the input signal, but restricts the bandwidth +according to certain library-internal settings. They can be changed in the table "bandWidthTable" in the +file bandwidth.cpp (if available). + +The encoder API provides the ::AACENC_BANDWIDTH parameter to adjust the bandwidth explicitly. +\code +aacEncoder_SetParam(hAacEncoder, AACENC_BANDWIDTH, value); +\endcode + +However it is not recommended to change these settings, because they are based on numerious listening +tests and careful tweaks to ensure the best overall encoding quality. + +Theoretically a signal of for example 48 kHz can contain frequencies up to 24 kHz, but to use this full range +in an audio encoder usually does not make sense. Usually the encoder has a very limited amount of +bits to spend (typically 128 kbit/s for stereo 48 kHz content) and to allow full range bandwidth would +waste a lot of these bits for frequencies the human ear is hardly able to perceive anyway, if at all. Hence it +is wise to use the available bits for the really important frequency range and just skip the rest. +At lower bitrates (e. g. <= 80 kbit/s for stereo 48 kHz content) the encoder will choose an even smaller +bandwidth, because an encoded signal with smaller bandwidth and hence less artifacts sounds better than a signal +with higher bandwidth but then more coding artefacts across all frequencies. These artefacts would occur if +small bitrates and high bandwidths are chosen because the available bits are just not enough to encode all +frequencies well. + +Unfortunately some people evaluate encoding quality based on possible bandwidth as well, but it is a two-sided +sword considering the trade-off described above. + +Another aspect is workload consumption. The higher the allowed bandwidth, the more frequency lines have to be +processed, which in turn increases the workload. + +\section FRAMESIZES_AND_BIT_RESERVOIR Frame Sizes & Bit Reservoir + +For AAC there is a difference between constant bit rate and constant frame +length due to the so-called bit reservoir technique, which allows the encoder to use less +bits in an AAC frame for those audio signal sections which are easy to encode, +and then spend them at a later point in +time for more complex audio sections. The extent to which this "bit exchange" +is done is limited to allow for reliable and relatively low delay real time +streaming. +Over a longer period in time the bitrate will be constant in the AAC constant +bitrate mode, e.g. for ISDN transmission. This means that in AAC each bitstream +frame will in general have a different length in bytes but over time it +will reach the target bitrate. One could also make an MPEG compliant +AAC encoder which always produces constant length packages for each AAC frame, +but the audio quality would be considerably worse since the bit reservoir +technique would have to be switched off completely. A higher bit rate would have +to be used to get the same audio quality as with an enabled bit reservoir. + +The maximum AAC frame length, regardless of the available bit reservoir, is defined +as 6144 bits per channel. + +For mp3 by the way, the same bit reservoir technique exists, but there each bit +stream frame has a constant length for a given bit rate (ignoring the +padding byte). In mp3 there is a so-called "back pointer" which tells +the decoder which bits belong to the current mp3 frame - and in general some or +many bits have been transmitted in an earlier mp3 frame. Basically this leads to +the same "bit exchange between mp3 frames" as in AAC but with virtually constant +length frames. + +This variable frame length at "constant bit rate" is not something special +in this Fraunhofer IIS AAC encoder. AAC has been designed in that way. + +\subsection BEHAVIOUR_ESTIM_AVG_FRAMESIZES Estimating Average Frame Sizes + +A HE-AAC v1 or v2 audio frame contains 2048 PCM samples per channel (there is +also one mode with 1920 samples per channel but this is only for special purposes +such as DAB+ digital radio). + +The number of HE-AAC frames \f$N\_FRAMES\f$ per second at 44.1 kHz is: + +\f[ +N\_FRAMES = 44100 / 2048 = 21.5332 +\f] + +At a bit rate of 8 kbps the average number of bits per frame \f$N\_BITS\_PER\_FRAME\f$ is: + +\f[ +N\_BITS\_PER\_FRAME = 8000 / 21.5332 = 371.52 +\f] + +which is about 46.44 bytes per encoded frame. + +At a bit rate of 32 kbps, which is quite high for single channel HE-AAC v1, it is: + +\f[ +N\_BITS\_PER\_FRAME = 32000 / 21.5332 = 1486 +\f] + +which is about 185.76 bytes per encoded frame. + +These bits/frame figures are average figures where each AAC frame generally has a different +size in bytes. To calculate the same for AAC-LC just use 1024 instead of 2048 PCM samples per +frame and channel. +For AAC-LD/ELD it is either 480 or 512 PCM samples per frame and channel. + + +\section BEHAVIOUR_TOOLS Encoder Tools + +The AAC encoder supports TNS, PNS, MS, Intensity and activates these tools depending on the audio signal and +the encoder configuration (i.e. bitrate or AOT). It is not required to configure these tools manually. + +PNS improves encoding quality only for certain bitrates. Therefore it makes sense to activate PNS only for +these bitrates and save the processing power required for PNS (about 10 % of the encoder) when using other +bitrates. This is done automatically inside the encoder library. PNS is disabled inside the encoder library if +an MPEG-2 AOT is choosen since PNS is an MPEG-4 AAC feature. + +If SBR is activated, the encoder automatically deactivates PNS internally. If TNS is disabled but PNS is allowed, +the encoder deactivates PNS calculation internally. + +*/ + +#ifndef _AAC_ENC_LIB_H_ +#define _AAC_ENC_LIB_H_ + +#include "machine_type.h" +#include "FDK_audio.h" + +#define AACENCODER_LIB_VL0 3 +#define AACENCODER_LIB_VL1 4 +#define AACENCODER_LIB_VL2 22 + +/** + * AAC encoder error codes. + */ +typedef enum { + AACENC_OK = 0x0000, /*!< No error happened. All fine. */ + + AACENC_INVALID_HANDLE = 0x0020, /*!< Handle passed to function call was invalid. */ + AACENC_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */ + AACENC_UNSUPPORTED_PARAMETER = 0x0022, /*!< Parameter not available. */ + AACENC_INVALID_CONFIG = 0x0023, /*!< Configuration not provided. */ + + AACENC_INIT_ERROR = 0x0040, /*!< General initialization error. */ + AACENC_INIT_AAC_ERROR = 0x0041, /*!< AAC library initialization error. */ + AACENC_INIT_SBR_ERROR = 0x0042, /*!< SBR library initialization error. */ + AACENC_INIT_TP_ERROR = 0x0043, /*!< Transport library initialization error. */ + AACENC_INIT_META_ERROR = 0x0044, /*!< Meta data library initialization error. */ + + AACENC_ENCODE_ERROR = 0x0060, /*!< The encoding process was interrupted by an unexpected error. */ + + AACENC_ENCODE_EOF = 0x0080 /*!< End of file reached. */ + +} AACENC_ERROR; + + +/** + * AAC encoder buffer descriptors identifier. + * This identifier are used within buffer descriptors AACENC_BufDesc::bufferIdentifiers. + */ +typedef enum { + /* Input buffer identifier. */ + IN_AUDIO_DATA = 0, /*!< Audio input buffer, interleaved INT_PCM samples. */ + IN_ANCILLRY_DATA = 1, /*!< Ancillary data to be embedded into bitstream. */ + IN_METADATA_SETUP = 2, /*!< Setup structure for embedding meta data. */ + + /* Output buffer identifier. */ + OUT_BITSTREAM_DATA = 3, /*!< Buffer holds bitstream output data. */ + OUT_AU_SIZES = 4 /*!< Buffer contains sizes of each access unit. This information + is necessary for superframing. */ + +} AACENC_BufferIdentifier; + + +/** + * AAC encoder handle. + */ +typedef struct AACENCODER *HANDLE_AACENCODER; + + +/** + * Provides some info about the encoder configuration. + */ +typedef struct { + + UINT maxOutBufBytes; /*!< Maximum number of encoder bitstream bytes within one frame. + Size depends on maximum number of supported channels in encoder instance. + For superframing (as used for example in DAB+), size has to be a multiple accordingly. */ + + UINT maxAncBytes; /*!< Maximum number of ancillary data bytes which can be inserted into + bitstream within one frame. */ + + UINT inBufFillLevel; /*!< Internal input buffer fill level in samples per channel. This parameter + will automatically be cleared if samplingrate or channel(Mode/Order) changes. */ + + UINT inputChannels; /*!< Number of input channels expected in encoding process. */ + + UINT frameLength; /*!< Amount of input audio samples consumed each frame per channel, depending + on audio object type configuration. */ + + UINT encoderDelay; /*!< Codec delay in PCM samples/channel. Depends on framelength and AOT. Does not + include framing delay for filling up encoder PCM input buffer. */ + + UCHAR confBuf[64]; /*!< Configuration buffer in binary format as an AudioSpecificConfig + or StreamMuxConfig according to the selected transport type. */ + + UINT confSize; /*!< Number of valid bytes in confBuf. */ + +} AACENC_InfoStruct; + + +/** + * Describes the input and output buffers for an aacEncEncode() call. + */ +typedef struct { + INT numBufs; /*!< Number of buffers. */ + void **bufs; /*!< Pointer to vector containing buffer addresses. */ + INT *bufferIdentifiers; /*!< Identifier of each buffer element. See ::AACENC_BufferIdentifier. */ + INT *bufSizes; /*!< Size of each buffer in 8-bit bytes. */ + INT *bufElSizes; /*!< Size of each buffer element in bytes. */ + +} AACENC_BufDesc; + + +/** + * Defines the input arguments for an aacEncEncode() call. + */ +typedef struct { + INT numInSamples; /*!< Number of valid input audio samples (multiple of input channels). */ + INT numAncBytes; /*!< Number of ancillary data bytes to be encoded. */ + +} AACENC_InArgs; + + +/** + * Defines the output arguments for an aacEncEncode() call. + */ +typedef struct { + INT numOutBytes; /*!< Number of valid bitstream bytes generated during aacEncEncode(). */ + INT numInSamples; /*!< Number of input audio samples consumed by the encoder. */ + INT numAncBytes; /*!< Number of ancillary data bytes consumed by the encoder. */ + +} AACENC_OutArgs; + + +/** + * Meta Data Compression Profiles. + */ +typedef enum { + AACENC_METADATA_DRC_NONE = 0, /*!< None. */ + AACENC_METADATA_DRC_FILMSTANDARD = 1, /*!< Film standard. */ + AACENC_METADATA_DRC_FILMLIGHT = 2, /*!< Film light. */ + AACENC_METADATA_DRC_MUSICSTANDARD = 3, /*!< Music standard. */ + AACENC_METADATA_DRC_MUSICLIGHT = 4, /*!< Music light. */ + AACENC_METADATA_DRC_SPEECH = 5 /*!< Speech. */ + +} AACENC_METADATA_DRC_PROFILE; + + +/** + * Meta Data setup structure. + */ +typedef struct { + + AACENC_METADATA_DRC_PROFILE drc_profile; /*!< MPEG DRC compression profile. See ::AACENC_METADATA_DRC_PROFILE. */ + AACENC_METADATA_DRC_PROFILE comp_profile; /*!< ETSI heavy compression profile. See ::AACENC_METADATA_DRC_PROFILE. */ + + INT drc_TargetRefLevel; /*!< Used to define expected level to: + Scaled with 16 bit. x*2^16. */ + INT comp_TargetRefLevel; /*!< Adjust limiter to avoid overload. + Scaled with 16 bit. x*2^16. */ + + INT prog_ref_level_present; /*!< Flag, if prog_ref_level is present */ + INT prog_ref_level; /*!< Programme Reference Level = Dialogue Level: + -31.75dB .. 0 dB ; stepsize: 0.25dB + Scaled with 16 bit. x*2^16.*/ + + UCHAR PCE_mixdown_idx_present; /*!< Flag, if dmx-idx should be written in programme config element */ + UCHAR ETSI_DmxLvl_present; /*!< Flag, if dmx-lvl should be written in ETSI-ancData */ + + SCHAR centerMixLevel; /*!< Center downmix level (0...7, according to table) */ + SCHAR surroundMixLevel; /*!< Surround downmix level (0...7, according to table) */ + + UCHAR dolbySurroundMode; /*!< Indication for Dolby Surround Encoding Mode. + - 0: Dolby Surround mode not indicated + - 1: 2-ch audio part is not Dolby surround encoded + - 2: 2-ch audio part is Dolby surround encoded */ +} AACENC_MetaData; + + +/** + * AAC encoder control flags. + * + * In interaction with the ::AACENC_CONTROL_STATE parameter it is possible to get information about the internal + * initialization process. It is also possible to overwrite the internal state from extern when necessary. + */ +typedef enum +{ + AACENC_INIT_NONE = 0x0000, /*!< Do not trigger initialization. */ + AACENC_INIT_CONFIG = 0x0001, /*!< Initialize all encoder modules configuration. */ + AACENC_INIT_STATES = 0x0002, /*!< Reset all encoder modules history buffer. */ + AACENC_INIT_TRANSPORT = 0x1000, /*!< Initialize transport lib with new parameters. */ + AACENC_RESET_INBUFFER = 0x2000, /*!< Reset fill level of internal input buffer. */ + AACENC_INIT_ALL = 0xFFFF /*!< Initialize all. */ +} +AACENC_CTRLFLAGS; + + +/** + * \brief AAC encoder setting parameters. + * + * Use aacEncoder_SetParam() function to configure, or use aacEncoder_GetParam() function to read + * the internal status of the following parameters. + */ +typedef enum +{ + AACENC_AOT = 0x0100, /*!< Audio object type. See ::AUDIO_OBJECT_TYPE in FDK_audio.h. + - 2: MPEG-4 AAC Low Complexity. + - 5: MPEG-4 AAC Low Complexity with Spectral Band Replication (HE-AAC). + - 29: MPEG-4 AAC Low Complexity with Spectral Band Replication and Parametric Stereo (HE-AAC v2). + This configuration can be used only with stereo input audio data. + - 23: MPEG-4 AAC Low-Delay. + - 39: MPEG-4 AAC Enhanced Low-Delay. Since there is no ::AUDIO_OBJECT_TYPE for ELD in + combination with SBR defined, enable SBR explicitely by ::AACENC_SBR_MODE parameter. */ + + AACENC_BITRATE = 0x0101, /*!< Total encoder bitrate. This parameter is mandatory and interacts with ::AACENC_BITRATEMODE. + - CBR: Bitrate in bits/second. + See \ref suppBitrates for details. */ + + AACENC_BITRATEMODE = 0x0102, /*!< Bitrate mode. Configuration can be different kind of bitrate configurations: + - 0: Constant bitrate, use bitrate according to ::AACENC_BITRATE. (default) + Within none LD/ELD ::AUDIO_OBJECT_TYPE, the CBR mode makes use of full allowed bitreservoir. + In contrast, at Low-Delay ::AUDIO_OBJECT_TYPE the bitreservoir is kept very small. + - 8: LD/ELD full bitreservoir for packet based transmission. */ + + AACENC_SAMPLERATE = 0x0103, /*!< Audio input data sampling rate. Encoder supports following sampling rates: + 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 */ + + AACENC_SBR_MODE = 0x0104, /*!< Configure SBR independently of the chosen Audio Object Type ::AUDIO_OBJECT_TYPE. + This parameter is for ELD audio object type only. + - -1: Use ELD SBR auto configurator (default). + - 0: Disable Spectral Band Replication. + - 1: Enable Spectral Band Replication. */ + + AACENC_GRANULE_LENGTH = 0x0105, /*!< Core encoder (AAC) audio frame length in samples: + - 1024: Default configuration. + - 512: Default LD/ELD configuration. + - 480: Optional length in LD/ELD configuration. */ + + AACENC_CHANNELMODE = 0x0106, /*!< Set explicit channel mode. Channel mode must match with number of input channels. + - 1-7 and 33,34: MPEG channel modes supported, see ::CHANNEL_MODE in FDK_audio.h. */ + + AACENC_CHANNELORDER = 0x0107, /*!< Input audio data channel ordering scheme: + - 0: MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE). (default) + - 1: WAVE file format channel ordering (e. g. 5.1: L, R, C, LFE, SL, SR). */ + + AACENC_SBR_RATIO = 0x0108, /*!< Controls activation of downsampled SBR. With downsampled SBR, the delay will be + shorter. On the other hand, for achieving the same quality level, downsampled SBR + needs more bits than dual-rate SBR. + With downsampled SBR, the AAC encoder will work at the same sampling rate as the + SBR encoder (single rate). + Downsampled SBR is supported for AAC-ELD and HE-AACv1. + - 1: Downsampled SBR (default for ELD). + - 2: Dual-rate SBR (default for HE-AAC). */ + + AACENC_AFTERBURNER = 0x0200, /*!< This parameter controls the use of the afterburner feature. + The afterburner is a type of analysis by synthesis algorithm which increases the + audio quality but also the required processing power. It is recommended to always + activate this if additional memory consumption and processing power consumption + is not a problem. If increased MHz and memory consumption are an issue then the MHz + and memory cost of this optional module need to be evaluated against the improvement + in audio quality on a case by case basis. + - 0: Disable afterburner (default). + - 1: Enable afterburner. */ + + AACENC_BANDWIDTH = 0x0203, /*!< Core encoder audio bandwidth: + - 0: Determine bandwidth internally (default, see chapter \ref BEHAVIOUR_BANDWIDTH). + - 1 to fs/2: Frequency bandwidth in Hertz. (Experts only, better do not + touch this value to avoid degraded audio quality) */ + + AACENC_PEAK_BITRATE = 0x0207, /*!< Peak bitrate configuration parameter to adjust maximum bits per audio frame. Bitrate is in bits/second. + The peak bitrate will internally be limited to the chosen bitrate ::AACENC_BITRATE as lower limit + and the number_of_effective_channels*6144 bit as upper limit. + + Setting the peak bitrate equal to ::AACENC_BITRATE does not necessarily mean that the audio frames + will be of constant size. Since the peak bitate is in bits/second, the frame sizes can vary by + one byte in one or the other direction over various frames. However, it is not recommended to reduce + the peak pitrate to ::AACENC_BITRATE - it would disable the bitreservoir, which would affect the + audio quality by a large amount. */ + + AACENC_TRANSMUX = 0x0300, /*!< Transport type to be used. See ::TRANSPORT_TYPE in FDK_audio.h. Following + types can be configured in encoder library: + - 0: raw access units + - 1: ADIF bitstream format + - 2: ADTS bitstream format + - 6: Audio Mux Elements (LATM) with muxConfigPresent = 1 + - 7: Audio Mux Elements (LATM) with muxConfigPresent = 0, out of band StreamMuxConfig + - 10: Audio Sync Stream (LOAS) */ + + AACENC_HEADER_PERIOD = 0x0301, /*!< Frame count period for sending in-band configuration buffers within LATM/LOAS + transport layer. Additionally this parameter configures the PCE repetition period + in raw_data_block(). See \ref encPCE. + - 0xFF: auto-mode default 10 for TT_MP4_ADTS, TT_MP4_LOAS and TT_MP4_LATM_MCP1, otherwise 0. + - n: Frame count period. */ + + AACENC_SIGNALING_MODE = 0x0302, /*!< Signaling mode of the extension AOT: + - 0: Implicit backward compatible signaling (default for non-MPEG-4 based + AOT's and for the transport formats ADIF and ADTS) + - A stream that uses implicit signaling can be decoded by every AAC decoder, even AAC-LC-only decoders + - An AAC-LC-only decoder will only decode the low-frequency part of the stream, resulting in a band-limited output + - This method works with all transport formats + - This method does not work with downsampled SBR + - 1: Explicit backward compatible signaling + - A stream that uses explicit backward compatible signaling can be decoded by every AAC decoder, even AAC-LC-only decoders + - An AAC-LC-only decoder will only decode the low-frequency part of the stream, resulting in a band-limited output + - A decoder not capable of decoding PS will only decode the AAC-LC+SBR part. + If the stream contained PS, the result will be a a decoded mono downmix + - This method does not work with ADIF or ADTS. For LOAS/LATM, it only works with AudioMuxVersion==1 + - This method does work with downsampled SBR + - 2: Explicit hierarchical signaling (default for MPEG-4 based AOT's and for all transport formats excluding ADIF and ADTS) + - A stream that uses explicit hierarchical signaling can be decoded only by HE-AAC decoders + - An AAC-LC-only decoder will not decode a stream that uses explicit hierarchical signaling + - A decoder not capable of decoding PS will not decode the stream at all if it contained PS + - This method does not work with ADIF or ADTS. It works with LOAS/LATM and the MPEG-4 File format + - This method does work with downsampled SBR + + For making sure that the listener always experiences the best audio quality, + explicit hierarchical signaling should be used. + This makes sure that only a full HE-AAC-capable decoder will decode those streams. + The audio is played at full bandwidth. + For best backwards compatibility, it is recommended to encode with implicit SBR signaling. + A decoder capable of AAC-LC only will then only decode the AAC part, which means the decoded + audio will sound band-limited. + + For MPEG-2 transport types (ADTS,ADIF), only implicit signaling is possible. + + For LOAS and LATM, explicit backwards compatible signaling only works together with AudioMuxVersion==1. + The reason is that, for explicit backwards compatible signaling, additional information will be appended to the ASC. + A decoder that is only capable of decoding AAC-LC will skip this part. + Nevertheless, for jumping to the end of the ASC, it needs to know the ASC length. + Transmitting the length of the ASC is a feature of AudioMuxVersion==1, it is not possible to transmit the + length of the ASC with AudioMuxVersion==0, therefore an AAC-LC-only decoder will not be able to parse a + LOAS/LATM stream that was being encoded with AudioMuxVersion==0. + + For downsampled SBR, explicit signaling is mandatory. The reason for this is that the + extension sampling frequency (which is in case of SBR the sampling frequqncy of the SBR part) + can only be signaled in explicit mode. + + For AAC-ELD, the SBR information is transmitted in the ELDSpecific Config, which is part of the + AudioSpecificConfig. Therefore, the settings here will have no effect on AAC-ELD.*/ + + AACENC_TPSUBFRAMES = 0x0303, /*!< Number of sub frames in a transport frame for LOAS/LATM or ADTS (default 1). + - ADTS: Maximum number of sub frames restricted to 4. + - LOAS/LATM: Maximum number of sub frames restricted to 2.*/ + + AACENC_AUDIOMUXVER = 0x0304, /*!< AudioMuxVersion to be used for LATM. (AudioMuxVersionA, currently not implemented): + - 0: Default, no transmission of tara Buffer fullness, no ASC length and including actual latm Buffer fullnes. + - 1: Transmission of tara Buffer fullness, ASC length and actual latm Buffer fullness. + - 2: Transmission of tara Buffer fullness, ASC length and maximum level of latm Buffer fullness. */ + + AACENC_PROTECTION = 0x0306, /*!< Configure protection in tranpsort layer: + - 0: No protection. (default) + - 1: CRC active for ADTS bitstream format. */ + + AACENC_ANCILLARY_BITRATE = 0x0500, /*!< Constant ancillary data bitrate in bits/second. + - 0: Either no ancillary data or insert exact number of bytes, denoted via + input parameter, numAncBytes in AACENC_InArgs. + - else: Insert ancillary data with specified bitrate. */ + + AACENC_METADATA_MODE = 0x0600, /*!< Configure Meta Data. See ::AACENC_MetaData for further details: + - 0: Do not embed any metadata. + - 1: Embed MPEG defined metadata only. + - 2: Embed all metadata. */ + + AACENC_CONTROL_STATE = 0xFF00, /*!< There is an automatic process which internally reconfigures the encoder instance + when a configuration parameter changed or an error occured. This paramerter allows + overwriting or getting the control status of this process. See ::AACENC_CTRLFLAGS. */ + + AACENC_NONE = 0xFFFF /*!< ------ */ + +} AACENC_PARAM; + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Open an instance of the encoder. + * + * Allocate memory for an encoder instance with a functional range denoted by the function parameters. + * Preinitialize encoder instance with default configuration. + * + * \param phAacEncoder A pointer to an encoder handle. Initialized on return. + * \param encModules Specify encoder modules to be supported in this encoder instance: + * - 0x0: Allocate memory for all available encoder modules. + * - else: Select memory allocation regarding encoder modules. Following flags are possible and can be combined. + * - 0x01: AAC module. + * - 0x02: SBR module. + * - 0x04: PS module. + * - 0x10: Metadata module. + * - example: (0x01|0x02|0x04|0x10) allocates all modules and is equivalent to default configuration denotet by 0x0. + * \param maxChannels Number of channels to be allocated. This parameter can be used in different ways: + * - 0: Allocate maximum number of AAC and SBR channels as supported by the library. + * - nChannels: Use same maximum number of channels for allocating memory in AAC and SBR module. + * - nChannels | (nSbrCh<<8): Number of SBR channels can be different to AAC channels to save data memory. + * + * \return + * - AACENC_OK, on succes. + * - AACENC_INVALID_HANDLE, AACENC_MEMORY_ERROR, AACENC_INVALID_CONFIG, on failure. + */ +AACENC_ERROR aacEncOpen( + HANDLE_AACENCODER *phAacEncoder, + const UINT encModules, + const UINT maxChannels + ); + + +/** + * \brief Close the encoder instance. + * + * Deallocate encoder instance and free whole memory. + * + * \param phAacEncoder Pointer to the encoder handle to be deallocated. + * + * \return + * - AACENC_OK, on success. + * - AACENC_INVALID_HANDLE, on failure. + */ +AACENC_ERROR aacEncClose( + HANDLE_AACENCODER *phAacEncoder + ); + + +/** + * \brief Encode audio data. + * + * This function is mainly for encoding audio data. In addition the function can be used for an encoder (re)configuration + * process. + * - PCM input data will be retrieved from external input buffer until the fill level allows encoding a single frame. + * This functionality allows an external buffer with reduced size in comparison to the AAC or HE-AAC audio frame length. + * - If the value of the input samples argument is zero, just internal reinitialization will be applied if it is + * requested. + * - At the end of a file the flushing process can be triggerd via setting the value of the input samples argument to -1. + * The encoder delay lines are fully flushed when the encoder returns no valid bitstream data AACENC_OutArgs::numOutBytes. + * Furthermore the end of file is signaled by the return value AACENC_ENCODE_EOF. + * - If an error occured in the previous frame or any of the encoder parameters changed, an internal reinitialization + * process will be applied before encoding the incoming audio samples. + * - The function can also be used for an independent reconfiguration process without encoding. The first parameter has to be a + * valid encoder handle and all other parameters can be set to NULL. + * - If the size of the external bitbuffer in outBufDesc is not sufficient for writing the whole bitstream, an internal + * error will be the return value and a reconfiguration will be triggered. + * + * \param hAacEncoder A valid AAC encoder handle. + * \param inBufDesc Input buffer descriptor, see AACENC_BufDesc: + * - At least one input buffer with audio data is expected. + * - Optionally a second input buffer with ancillary data can be fed. + * \param outBufDesc Output buffer descriptor, see AACENC_BufDesc: + * - Provide one output buffer for the encoded bitstream. + * \param inargs Input arguments, see AACENC_InArgs. + * \param outargs Output arguments, AACENC_OutArgs. + * + * \return + * - AACENC_OK, on success. + * - AACENC_INVALID_HANDLE, AACENC_ENCODE_ERROR, on failure in encoding process. + * - AACENC_INVALID_CONFIG, AACENC_INIT_ERROR, AACENC_INIT_AAC_ERROR, AACENC_INIT_SBR_ERROR, AACENC_INIT_TP_ERROR, + * AACENC_INIT_META_ERROR, on failure in encoder initialization. + * - AACENC_ENCODE_EOF, when flushing fully concluded. + */ +AACENC_ERROR aacEncEncode( + const HANDLE_AACENCODER hAacEncoder, + const AACENC_BufDesc *inBufDesc, + const AACENC_BufDesc *outBufDesc, + const AACENC_InArgs *inargs, + AACENC_OutArgs *outargs + ); + + +/** + * \brief Acquire info about present encoder instance. + * + * This function retrieves information of the encoder configuration. In addition to informative internal states, + * a configuration data block of the current encoder settings will be returned. The format is either Audio Specific Config + * in case of Raw Packets transport format or StreamMuxConfig in case of LOAS/LATM transport format. The configuration + * data block is binary coded as specified in ISO/IEC 14496-3 (MPEG-4 audio), to be used directly for MPEG-4 File Format + * or RFC3016 or RFC3640 applications. + * + * \param hAacEncoder A valid AAC encoder handle. + * \param pInfo Pointer to AACENC_InfoStruct. Filled on return. + * + * \return + * - AACENC_OK, on succes. + * - AACENC_INIT_ERROR, on failure. + */ +AACENC_ERROR aacEncInfo( + const HANDLE_AACENCODER hAacEncoder, + AACENC_InfoStruct *pInfo + ); + + +/** + * \brief Set one single AAC encoder parameter. + * + * This function allows configuration of all encoder parameters specified in ::AACENC_PARAM. Each parameter must be + * set with a separate function call. An internal validation of the configuration value range will be done and an + * internal reconfiguration will be signaled. The actual configuration adoption is part of the subsequent aacEncEncode() call. + * + * \param hAacEncoder A valid AAC encoder handle. + * \param param Parameter to be set. See ::AACENC_PARAM. + * \param value Parameter value. See parameter description in ::AACENC_PARAM. + * + * \return + * - AACENC_OK, on success. + * - AACENC_INVALID_HANDLE, AACENC_UNSUPPORTED_PARAMETER, AACENC_INVALID_CONFIG, on failure. + */ +AACENC_ERROR aacEncoder_SetParam( + const HANDLE_AACENCODER hAacEncoder, + const AACENC_PARAM param, + const UINT value + ); + + +/** + * \brief Get one single AAC encoder parameter. + * + * This function is the complement to aacEncoder_SetParam(). After encoder reinitialization with user defined settings, + * the internal status can be obtained of each parameter, specified with ::AACENC_PARAM. + * + * \param hAacEncoder A valid AAC encoder handle. + * \param param Parameter to be returned. See ::AACENC_PARAM. + * + * \return Internal configuration value of specifed parameter ::AACENC_PARAM. + */ +UINT aacEncoder_GetParam( + const HANDLE_AACENCODER hAacEncoder, + const AACENC_PARAM param + ); + + +/** + * \brief Get information about encoder library build. + * + * Fill a given LIB_INFO structure with library version information. + * + * \param info Pointer to an allocated LIB_INFO struct. + * + * \return + * - AACENC_OK, on success. + * - AACENC_INVALID_HANDLE, AACENC_INIT_ERROR, on failure. + */ +AACENC_ERROR aacEncGetLibInfo( + LIB_INFO *info + ); + + +#ifdef __cplusplus +} +#endif + +#endif /* _AAC_ENC_LIB_H_ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_archdef.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_archdef.h new file mode 100644 index 0000000..4bd33bd --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_archdef.h @@ -0,0 +1,266 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools *********************** + + Author(s): + Description: + +******************************************************************************/ + +#ifndef __ARCH_H__ +#define __ARCH_H__ + +/* Performance / Quality profile selector */ + #define FDK_HIGH_PERFORMANCE + +/* Unify some few toolchain specific defines to avoid having large "or" macro contraptions all over the source code. */ + +/* Take action against VisualStudio 2005 crosscompile problems. */ + +/* Use single macro (the GCC built in macro) for architecture identification independent of the particular toolchain */ +#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || (defined(_MSC_VER) && defined(_M_IX86)) || defined (__x86_64__) || (defined(_MSC_VER) && defined(_M_X64)) +#define __x86__ +#endif + +#if (defined(_M_ARM) || defined(__CC_ARM)) && !defined(__arm__) || defined(__TI_TMS470_V5__) && !defined(__arm__) +#define __arm__ +#endif + +#if defined(_ARCH_PPC) && !defined(__powerpc__) +#define __powerpc__ 1 +#endif + + + +/* Define __ARM_ARCH_5TE__ if armv5te features are supported */ +#if (__TARGET_ARCH_ARM == 5) || defined(__TARGET_FEATURE_DSPMUL) || (_M_ARM == 5) || defined(__ARM_ARCH_5TEJ__) || defined(__TI_TMS470_V5__) || \ + defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) +#define __ARM_ARCH_5TE__ +#endif + +/* Define __ARM_ARCH_6__ if the armv6 intructions are being supported. */ +#if (__TARGET_ARCH_ARM == 6) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6ZK__) +#define __ARM_ARCH_5TE__ +#define __ARM_ARCH_6__ +#endif + +/* Define __ARM_ARCH_7_A__ if the armv7 intructions are being supported. */ +#if defined(__TARGET_ARCH_7_R) || defined(__ARM_ARCH_7R__) +#define __ARM_ARCH_5TE__ +#define __ARM_ARCH_6__ +#define __ARM_ARCH_7_R__ +#endif + +/* Define __ARM_ARCH_7_A__ if the armv7 intructions are being supported. */ +#if defined(__TARGET_ARCH_7_A) || defined(__ARM_ARCH_7A__) +#define __ARM_ARCH_5TE__ +#define __ARM_ARCH_6__ +#define __ARM_ARCH_7_A__ +#endif + +/* Define __ARM_ARCH_7M__ if the ARMv7-M instructions are being supported, e.g. Cortex-M3. */ +#if defined(__TARGET_ARCH_7_M) || defined(__ARM_ARCH_7_M__) +#define __ARM_ARCH_7M__ +#endif + +/* Define __ARM_ARCH_7EM__ if the ARMv7-ME instructions are being supported, e.g. Cortex-M4. */ +#if defined(__TARGET_ARCH_7E_M) || defined(__ARM_ARCH_7E_M__) || defined(__ARM_ARCH_8M_MAIN__) +#undef __ARM_ARCH_7EM__ +#define __ARM_ARCH_7EM__ +#endif + +/* Detect and unify macros for neon feature. */ +#if defined(__TARGET_FEATURE_NEON) && !defined(__ARM_NEON__) +#define __ARM_NEON__ +#endif + +#ifdef _M_ARM +#include "armintr.h" +#endif + + +/* Define preferred Multiplication type */ +#if defined(FDK_HIGH_PERFORMANCE) && !defined(FDK_HIGH_QUALITY) /* FDK_HIGH_PERFORMANCE */ + +#if defined(__mips__) || defined(__sh__) +#define ARCH_PREFER_MULT_16x16 +#undef SINETABLE_16BIT +#undef POW2COEFF_16BIT +#undef LDCOEFF_16BIT +#undef WINDOWTABLE_16BIT + +#elif defined(__arm__) && defined(__ARM_ARCH_5TE__) /* cppp replaced: elif */ /* cppp replaced: elif */ +#define ARCH_PREFER_MULT_32x16 +#define SINETABLE_16BIT +#define POW2COEFF_16BIT +#define LDCOEFF_16BIT +#define WINDOWTABLE_16BIT + +#elif defined(__arm__) && defined(__ARM_ARCH_7M__) +#define ARCH_PREFER_MULT_32x16 +#define SINETABLE_16BIT +#define POW2COEFF_16BIT +#define LDCOEFF_16BIT +#define WINDOWTABLE_16BIT + +#elif defined(__arm__) && defined(__ARM_ARCH_7EM__) +#define ARCH_PREFER_MULT_32x32 +#define ARCH_PREFER_MULT_32x16 +#define SINETABLE_16BIT +#define POW2COEFF_16BIT +#define LDCOEFF_16BIT +#define WINDOWTABLE_16BIT + +#elif defined(__arm__) && !defined(__ARM_ARCH_5TE__) +#define ARCH_PREFER_MULT_16x16 +#undef SINETABLE_16BIT +#undef WINDOWTABLE_16BIT +#undef POW2COEFF_16BIT +#undef LDCOEFF_16BIT + +#elif defined(__aarch64__) || defined(__AARCH64EL__) +#define ARCH_PREFER_MULT_32x32 +#define ARCH_PREFER_MULT_32x16 +#define SINETABLE_16BIT +#define POW2COEFF_16BIT +#define LDCOEFF_16BIT +#define WINDOWTABLE_16BIT + +#elif defined(__x86__) /* cppp replaced: elif */ +#define ARCH_PREFER_MULT_32x16 +#define SINETABLE_16BIT +#define WINDOWTABLE_16BIT +#define POW2COEFF_16BIT +#define LDCOEFF_16BIT + +#elif defined(__powerpc__) +#define ARCH_PREFER_MULT_32x32 +#define ARCH_PREFER_MULT_32x16 +#define SINETABLE_16BIT +#define POW2COEFF_16BIT +#define LDCOEFF_16BIT +#define WINDOWTABLE_16BIT + +#else + + #warning >>>> Please set architecture characterization defines for your platform (FDK_HIGH_PERFORMANCE)! <<<< + +#endif /* Architecture switches */ + +#else /* neither FDK_HIGH_QUALITY or FDK_HIGH_PERFORMANCE */ + +#error Either set FDK_HIGH_QUALITY or FDK_HIGH_PERFORMANCE, but not both nor none of them. + +#endif /* End of quality/complexity tradeoff */ + +#define FDKTOOLS_PACKED_TABLES + + +#ifdef SINETABLE_16BIT + #define FIXP_STB FIXP_SGL /* STB sinus Tab used in transformation */ + #define FIXP_STP FIXP_SPK + #define STC(a) (FX_DBL2FXCONST_SGL(a)) +#else + #define FIXP_STB FIXP_DBL + #define FIXP_STP FIXP_DPK + #define STC(a) ((FIXP_DBL)(LONG)(a)) +#endif /* defined(SINETABLE_16BIT) */ + +#define STCP(cos,sin) { { STC(cos), STC(sin) } } + + +#ifdef WINDOWTABLE_16BIT + #define FIXP_WTB FIXP_SGL /* single FIXP_SGL values */ + #define FIXP_WTP FIXP_SPK /* packed FIXP_SGL values */ + #define WTC(a) FX_DBL2FXCONST_SGL(a) +#else /* SINETABLE_16BIT */ + #define FIXP_WTB FIXP_DBL + #define FIXP_WTP FIXP_DPK + #define WTC(a) (FIXP_DBL)(a) +#endif /* SINETABLE_16BIT */ + +#define WTCP(a,b) { { WTC(a), WTC(b) } } + + +#endif /* __ARCH_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_bitbuffer.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_bitbuffer.h new file mode 100644 index 0000000..3d431a3 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_bitbuffer.h @@ -0,0 +1,166 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools *********************** + + Author(s): M. Lohwasser + Description: common bitbuffer read/write routines + +******************************************************************************/ + +#ifndef __FDK_BITBUFFER_H__ +#define __FDK_BITBUFFER_H__ + + + +#include "machine_type.h" + +typedef struct +{ + UINT ValidBits; + UINT ReadOffset; + UINT WriteOffset; + UINT BitCnt; + UINT BitNdx; + + UCHAR *Buffer; + UINT bufSize; + UINT bufBits; +} FDK_BITBUF; + +typedef FDK_BITBUF *HANDLE_FDK_BITBUF; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern const UINT BitMask [32+1]; + +/** The BitBuffer Functions are called straight from FDK_bitstream Interface. + For Functions functional survey look there. +*/ + +void FDK_CreateBitBuffer (HANDLE_FDK_BITBUF *hBitBuffer, UCHAR *pBuffer, UINT bufSize) ; + +void FDK_InitBitBuffer (HANDLE_FDK_BITBUF hBitBuffer, UCHAR *pBuffer, + UINT bufSize, UINT validBits) ; + +void FDK_ResetBitBuffer (HANDLE_FDK_BITBUF hBitBuffer) ; + +void FDK_DeleteBitBuffer (HANDLE_FDK_BITBUF hBitBuffer) ; + +INT FDK_get (HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits) ; + +INT FDK_get32 (HANDLE_FDK_BITBUF hBitBuffer) ; + +void FDK_put (HANDLE_FDK_BITBUF hBitBuffer, UINT value, const UINT numberOfBits) ; + +INT FDK_getBwd (HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits); +void FDK_putBwd (HANDLE_FDK_BITBUF hBitBuffer, UINT value, const UINT numberOfBits) ; + +void FDK_pushBack (HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits, UCHAR config) ; +void FDK_pushForward (HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits, UCHAR config) ; + +void FDK_byteAlign (HANDLE_FDK_BITBUF hBitBuffer, UCHAR config) ; + +UINT FDK_getValidBits (HANDLE_FDK_BITBUF hBitBuffer) ; +INT FDK_getFreeBits (HANDLE_FDK_BITBUF hBitBuffer) ; + +void FDK_setBitCnt (HANDLE_FDK_BITBUF hBitBuffer, const UINT value) ; +INT FDK_getBitCnt (HANDLE_FDK_BITBUF hBitBuffer) ; + +void FDK_Feed (HANDLE_FDK_BITBUF hBitBuffer, UCHAR inputBuffer [], + const UINT bufferSize, UINT *bytesValid) ; + +void FDK_Copy (HANDLE_FDK_BITBUF hBitBufDst, HANDLE_FDK_BITBUF hBitBufSrc, UINT *bytesValid) ; + +void FDK_Fetch (HANDLE_FDK_BITBUF hBitBuffer, UCHAR outBuf[], UINT *writeBytes); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_bitstream.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_bitstream.h new file mode 100644 index 0000000..f3a7c26 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_bitstream.h @@ -0,0 +1,661 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools *********************** + + Author(s): M. Lohwasser + Description: bitstream interface to bitbuffer routines + +******************************************************************************/ + +#ifndef __FDK_BITSTREAM_H__ +#define __FDK_BITSTREAM_H__ + + + +#include "FDK_bitbuffer.h" +#include "machine_type.h" + +#include "genericStds.h" + +#define CACHE_BITS 32 + +typedef enum { + BS_READER, + BS_WRITER +} FDK_BS_CFG; + + +typedef struct +{ + UINT CacheWord ; + UINT BitsInCache ; + FDK_BITBUF hBitBuf; + UINT ConfigCache ; +} FDK_BITSTREAM; + +typedef FDK_BITSTREAM* HANDLE_FDK_BITSTREAM; + +/** + * \brief CreateBitStream Function. + * + * Create and initialize bitstream with extern allocated buffer. + * + * \param pBuffer Pointer to BitBuffer array. + * \param bufSize Length of BitBuffer array. (awaits size 2^n) + * \param config Initialize BitStream as Reader or Writer. + */ +FDK_INLINE +HANDLE_FDK_BITSTREAM FDKcreateBitStream (UCHAR *pBuffer, + UINT bufSize, + FDK_BS_CFG config = BS_READER) +{ + HANDLE_FDK_BITSTREAM hBitStream = (HANDLE_FDK_BITSTREAM) FDKcalloc(1, sizeof(FDK_BITSTREAM)); + FDK_InitBitBuffer(&hBitStream->hBitBuf, pBuffer, bufSize, 0) ; + + /* init cache */ + hBitStream->CacheWord = hBitStream->BitsInCache = 0 ; + hBitStream->ConfigCache = config ; + + return hBitStream ; +} + + +/** + * \brief Initialize BistreamBuffer. BitBuffer can point to filled BitBuffer array . + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param pBuffer Pointer to BitBuffer array. + * \param bufSize Length of BitBuffer array. (awaits size 2^n) + * \param validBits Number of valid BitBuffer filled Bits. + * \param config Initialize BitStream as Reader or Writer. + * \return void + */ +FDK_INLINE +void FDKinitBitStream (HANDLE_FDK_BITSTREAM hBitStream, + UCHAR *pBuffer, + UINT bufSize, + UINT validBits, + FDK_BS_CFG config = BS_READER) +{ + FDK_InitBitBuffer(&hBitStream->hBitBuf, pBuffer, bufSize, validBits) ; + + /* init cache */ + hBitStream->CacheWord = hBitStream->BitsInCache = 0 ; + hBitStream->ConfigCache = config ; +} + + +/** + * \brief ResetBitbuffer Function. Reset states in BitBuffer and Cache. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param config Initialize BitStream as Reader or Writer. + * \return void + */ +FDK_INLINE void FDKresetBitbuffer( HANDLE_FDK_BITSTREAM hBitStream, FDK_BS_CFG config = BS_READER) +{ + FDK_ResetBitBuffer( &hBitStream->hBitBuf ) ; + + /* init cache */ + hBitStream->CacheWord = hBitStream->BitsInCache = 0 ; + hBitStream->ConfigCache = config ; +} + + +/** DeleteBitStream. + + Deletes the in Create Bitstream allocated BitStream and BitBuffer. +*/ +FDK_INLINE void FDKdeleteBitStream (HANDLE_FDK_BITSTREAM hBitStream) +{ + FDK_DeleteBitBuffer(&hBitStream->hBitBuf) ; + FDKfree(hBitStream) ; +} + + +/** + * \brief ReadBits Function (forward). This function returns a number of sequential + * bits from the input bitstream. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param numberOfBits The number of bits to be retrieved. + * \return the requested bits, right aligned + * \return + */ +#define OPTIMIZE_FDKREADBITS + +FDK_INLINE UINT FDKreadBits(HANDLE_FDK_BITSTREAM hBitStream, + const UINT numberOfBits) +{ +#ifdef noOPTIMIZE_FDKREADBITS + INT missingBits = numberOfBits - hBitStream->BitsInCache; + if (missingBits > 0) + { + const UINT bits = hBitStream->CacheWord << missingBits; + const UINT validBits = FDK_getValidBits (&hBitStream->hBitBuf); + + if (validBits >= 32) + { + hBitStream->CacheWord = FDK_get32 (&hBitStream->hBitBuf) ; + hBitStream->BitsInCache = CACHE_BITS - missingBits; + } + else + { + hBitStream->CacheWord = FDK_get (&hBitStream->hBitBuf,validBits) ; + if (validBits >= missingBits) + { + hBitStream->BitsInCache = validBits - missingBits; + } + else + { + hBitStream->BitsInCache = 0; + hBitStream->CacheWord <<= missingBits - validBits; + } + } + + return ( bits | (hBitStream->CacheWord >> hBitStream->BitsInCache)) & BitMask[numberOfBits]; + } + + hBitStream->BitsInCache -= numberOfBits; + return ( hBitStream->CacheWord >> hBitStream->BitsInCache) & BitMask[numberOfBits]; + +#else + const UINT validMask = BitMask [numberOfBits] ; + + if (hBitStream->BitsInCache <= numberOfBits) + { + const INT validBits = FDK_getValidBits (&hBitStream->hBitBuf) ; + const INT freeBits = (CACHE_BITS-1) - hBitStream->BitsInCache ; + const INT bitsToRead = (freeBits <= validBits) ? freeBits : validBits ; + + hBitStream->CacheWord = (hBitStream->CacheWord << bitsToRead) | FDK_get (&hBitStream->hBitBuf,bitsToRead) ; + hBitStream->BitsInCache += bitsToRead ; + if (hBitStream->BitsInCache < numberOfBits) + { + hBitStream->CacheWord <<= numberOfBits - hBitStream->BitsInCache; + hBitStream->BitsInCache = 0; + return (hBitStream->CacheWord >> hBitStream->BitsInCache) & validMask ; + } + } + + hBitStream->BitsInCache -= numberOfBits ; + + return (hBitStream->CacheWord >> hBitStream->BitsInCache) & validMask ; +#endif +} + +FDK_INLINE UINT FDKreadBit(HANDLE_FDK_BITSTREAM hBitStream) +{ +#ifdef OPTIMIZE_FDKREADBITS + if (!hBitStream->BitsInCache) + { + const UINT validBits = FDK_getValidBits (&hBitStream->hBitBuf); + + if (validBits >= 32) + { + hBitStream->CacheWord = FDK_get32 (&hBitStream->hBitBuf); + hBitStream->BitsInCache = CACHE_BITS; + } + else if (validBits > 0) + { + hBitStream->CacheWord = FDK_get (&hBitStream->hBitBuf,validBits); + hBitStream->BitsInCache = validBits; + } + else + { + return 0; + } + } + hBitStream->BitsInCache--; + + return (hBitStream->CacheWord >> hBitStream->BitsInCache) & 1; +#else + return FDKreadBits(hBitStream,1); +#endif +} + +/** + * \brief Read2Bits Function (forward). This function 2 sequential + * bits from the input bitstream. It is the optimized version + of FDKreadBits() for readign 2 bits. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return the requested bits, right aligned + * \return + */ +inline UINT FDKread2Bits(HANDLE_FDK_BITSTREAM hBitStream) +{ + UINT BitsInCache = hBitStream->BitsInCache; + if (BitsInCache < 2) /* Comparison changed from 'less-equal' to 'less' */ + { + const INT validBits = FDK_getValidBits (&hBitStream->hBitBuf) ; + const INT freeBits = (CACHE_BITS-1) - BitsInCache ; + const INT bitsToRead = (freeBits <= validBits) ? freeBits : validBits ; + + hBitStream->CacheWord = (hBitStream->CacheWord << bitsToRead) | FDK_get (&hBitStream->hBitBuf,bitsToRead) ; + BitsInCache += bitsToRead; + } + hBitStream->BitsInCache = BitsInCache - 2; + return (hBitStream->CacheWord >> hBitStream->BitsInCache) & 0x3; +} + +/** + * \brief ReadBits Function (backward). This function returns a number of sequential bits + * from the input bitstream. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param numberOfBits The number of bits to be retrieved. + * \return the requested bits, right aligned + */ +FDK_INLINE UINT FDKreadBitsBwd(HANDLE_FDK_BITSTREAM hBitStream, + const UINT numberOfBits) +{ + const UINT validMask = BitMask [numberOfBits] ; + + if (hBitStream->BitsInCache <= numberOfBits) + { + const INT freeBits = (CACHE_BITS-1) - hBitStream->BitsInCache ; + + hBitStream->CacheWord = (hBitStream->CacheWord << freeBits) | FDK_getBwd (&hBitStream->hBitBuf,freeBits) ; + hBitStream->BitsInCache += freeBits ; + } + + hBitStream->BitsInCache -= numberOfBits ; + + return (hBitStream->CacheWord >> hBitStream->BitsInCache) & validMask ; +} + + +/** + * \brief return a number of bits from the bitBuffer. + * You have to know what you do! Cache has to be synchronized before using this + * function. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param numBits The number of bits to be retrieved. + * \return the requested bits, right aligned + */ +FDK_INLINE UINT FDKgetBits (HANDLE_FDK_BITSTREAM hBitStream, UINT numBits) +{ + return FDK_get (&hBitStream->hBitBuf, numBits) ; +} + + +/** + * \brief WriteBits Function. This function writes numberOfBits of value into bitstream. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param value Variable holds data to be written. + * \param numberOfBits The number of bits to be written. + * \return number of bits written + */ +FDK_INLINE UCHAR FDKwriteBits(HANDLE_FDK_BITSTREAM hBitStream, UINT value, + const UINT numberOfBits) +{ + const UINT validMask = BitMask [numberOfBits] ; + + if ((hBitStream->BitsInCache+numberOfBits) < CACHE_BITS) + { + hBitStream->BitsInCache += numberOfBits ; + hBitStream->CacheWord = (hBitStream->CacheWord << numberOfBits) | (value & validMask); + } + else + { + FDK_put(&hBitStream->hBitBuf, hBitStream->CacheWord, hBitStream->BitsInCache) ; + hBitStream->BitsInCache = numberOfBits ; + hBitStream->CacheWord = (value & validMask) ; + } + + return numberOfBits; +} + + +/** + * \brief WriteBits Function (backward). This function writes numberOfBits of value into bitstream. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param value Variable holds data to be written. + * \param numberOfBits The number of bits to be written. + * \return number of bits written + */ +FDK_INLINE UCHAR FDKwriteBitsBwd(HANDLE_FDK_BITSTREAM hBitStream, UINT value, + const UINT numberOfBits) +{ + const UINT validMask = BitMask [numberOfBits] ; + + if ((hBitStream->BitsInCache+numberOfBits) <= CACHE_BITS) + { + hBitStream->BitsInCache += numberOfBits ; + hBitStream->CacheWord = (hBitStream->CacheWord << numberOfBits) | (value & validMask); + } + else + { + FDK_putBwd(&hBitStream->hBitBuf, hBitStream->CacheWord, hBitStream->BitsInCache) ; + hBitStream->BitsInCache = numberOfBits ; + hBitStream->CacheWord = (value & validMask) ; + } + + return numberOfBits; +} + + +/** + * \brief SyncCache Function. Clear cache after read forward. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return void + */ +FDK_INLINE void FDKsyncCache (HANDLE_FDK_BITSTREAM hBitStream) +{ + if (hBitStream->ConfigCache == BS_READER) + FDK_pushBack (&hBitStream->hBitBuf,hBitStream->BitsInCache,hBitStream->ConfigCache) ; + else /* BS_WRITER */ + FDK_put(&hBitStream->hBitBuf, hBitStream->CacheWord, hBitStream->BitsInCache) ; + + hBitStream->BitsInCache = 0 ; + hBitStream->CacheWord = 0 ; +} + + +/** + * \brief SyncCache Function. Clear cache after read backwards. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return void + */ +FDK_INLINE void FDKsyncCacheBwd (HANDLE_FDK_BITSTREAM hBitStream) +{ + if (hBitStream->ConfigCache == BS_READER) { + FDK_pushForward (&hBitStream->hBitBuf,hBitStream->BitsInCache,hBitStream->ConfigCache) ; + } else { /* BS_WRITER */ + FDK_putBwd (&hBitStream->hBitBuf, hBitStream->CacheWord, hBitStream->BitsInCache) ; + } + + hBitStream->BitsInCache = 0 ; + hBitStream->CacheWord = 0 ; +} + + +/** + * \brief Byte Alignment Function. + * This function performs the byte_alignment() syntactic function on the input stream, + * i.e. some bits will be discarded/padded so that the next bits to be read/written will + * be aligned on a byte boundary with respect to the bit position 0. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return void + */ +FDK_INLINE void FDKbyteAlign (HANDLE_FDK_BITSTREAM hBitStream) +{ + FDKsyncCache (hBitStream) ; + FDK_byteAlign (&hBitStream->hBitBuf, (UCHAR)hBitStream->ConfigCache) ; +} + + +/** + * \brief Byte Alignment Function with anchor + * This function performs the byte_alignment() syntactic function on the input stream, + * i.e. some bits will be discarded so that the next bits to be read/written would be aligned + * on a byte boundary with respect to the given alignment anchor. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param alignmentAnchor bit position to be considered as origin for byte alignment + * \return void + */ +FDK_INLINE void FDKbyteAlign (HANDLE_FDK_BITSTREAM hBitStream, UINT alignmentAnchor) +{ + FDKsyncCache (hBitStream) ; + if (hBitStream->ConfigCache == BS_READER) { + FDK_pushForward (&hBitStream->hBitBuf, + (8 - ((alignmentAnchor - FDK_getValidBits(&hBitStream->hBitBuf)) & 0x07)) & 0x07, + hBitStream->ConfigCache) ; + } + else { + FDK_put (&hBitStream->hBitBuf, + 0, + (8 - ((FDK_getValidBits(&hBitStream->hBitBuf)-alignmentAnchor) & 0x07)) & 0x07 ); + } +} + + +/** + * \brief Push Back(Cache) / For / BiDirectional Function. + * PushBackCache function ungets a number of bits erroneously read/written by the last Get() call. + * NB: The number of bits to be stuffed back into the stream may never exceed the + * number of bits returned by the immediately preceding Get() call. + * + * PushBack function ungets a number of bits (combines cache and bitbuffer indices) + * PushFor function gets a number of bits (combines cache and bitbuffer indices) + * PushBiDirectional gets/ungets number of bits as defined in PusBack/For function + * NB: The sign of bits is not known, so the function checks direction and calls + * appropriate function. (positive sign pushFor, negative sign pushBack ) + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param numberOfBits The number of bits to be pushed back/for. + * \return void + */ +FDK_INLINE void FDKpushBackCache (HANDLE_FDK_BITSTREAM hBitStream, const UINT numberOfBits) +{ + FDK_ASSERT ((hBitStream->BitsInCache+numberOfBits)<=CACHE_BITS); + hBitStream->BitsInCache += numberOfBits ; +} + +FDK_INLINE void FDKpushBack (HANDLE_FDK_BITSTREAM hBitStream, const UINT numberOfBits) +{ + if ((hBitStream->BitsInCache+numberOfBits)ConfigCache == BS_READER) ) { + hBitStream->BitsInCache += numberOfBits ; + FDKsyncCache(hBitStream) ; /* sync cache to avoid invalid cache */ + } + else { + FDKsyncCache(hBitStream) ; + FDK_pushBack(&hBitStream->hBitBuf,numberOfBits,hBitStream->ConfigCache); + } +} + +FDK_INLINE void FDKpushFor (HANDLE_FDK_BITSTREAM hBitStream, const UINT numberOfBits) +{ + if ( (hBitStream->BitsInCache>numberOfBits) && (hBitStream->ConfigCache == BS_READER) ) { + hBitStream->BitsInCache -= numberOfBits; + } + else { + FDKsyncCache(hBitStream) ; + FDK_pushForward(&hBitStream->hBitBuf,numberOfBits,hBitStream->ConfigCache); + } +} + +FDK_INLINE void FDKpushBiDirectional (HANDLE_FDK_BITSTREAM hBitStream, const INT numberOfBits) +{ + if(numberOfBits>=0) FDKpushFor(hBitStream, numberOfBits) ; + else FDKpushBack(hBitStream, -numberOfBits) ; +} + + +/** + * \brief GetValidBits Function. Clear cache and return valid Bits from Bitbuffer. + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return amount of valid bits that still can be read or were already written. + * + */ +FDK_INLINE UINT FDKgetValidBits (HANDLE_FDK_BITSTREAM hBitStream) +{ + FDKsyncCache(hBitStream) ; + return FDK_getValidBits(&hBitStream->hBitBuf) ; +} + + +/** + * \brief return amount of unused Bits from Bitbuffer. + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return amount of free bits that still can be written into the bitstream + */ +FDK_INLINE INT FDKgetFreeBits (HANDLE_FDK_BITSTREAM hBitStream) +{ + return FDK_getFreeBits (&hBitStream->hBitBuf) ; +} + +/** + * \brief reset bitcounter in bitBuffer to zero. + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return void + */ +FDK_INLINE void FDKresetBitCnt (HANDLE_FDK_BITSTREAM hBitStream) +{ + FDKsyncCache (hBitStream) ; + FDK_setBitCnt (&hBitStream->hBitBuf, 0) ; +} + +/** + * \brief set bitcoutner in bitBuffer to given value. + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param value new value to be assigned to the bit counter + * \return void + */ +FDK_INLINE void FDKsetBitCnt (HANDLE_FDK_BITSTREAM hBitStream, UINT value) +{ + FDKsyncCache (hBitStream) ; + FDK_setBitCnt (&hBitStream->hBitBuf, value) ; +} + +/** + * \brief get bitcounter state from bitBuffer. + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return current bit counter value + */ +FDK_INLINE INT FDKgetBitCnt (HANDLE_FDK_BITSTREAM hBitStream) +{ + FDKsyncCache(hBitStream) ; + return FDK_getBitCnt(&hBitStream->hBitBuf) ; +} + + +/** + * \brief Fill the BitBuffer with a number of input bytes from external source. + * The bytesValid variable returns the number of ramaining valid bytes in extern inputBuffer. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param inputBuffer Pointer to input buffer with bitstream data. + * \param bufferSize Total size of inputBuffer array. + * \param bytesValid Input: number of valid bytes in inputBuffer. Output: bytes still left unread in inputBuffer. + * \return void + */ +FDK_INLINE void FDKfeedBuffer (HANDLE_FDK_BITSTREAM hBitStream, const UCHAR inputBuffer [], const UINT bufferSize, UINT *bytesValid) +{ + FDKsyncCache (hBitStream) ; + FDK_Feed(&hBitStream->hBitBuf, (UCHAR*)inputBuffer, bufferSize, bytesValid ) ; +} + + +/** + * \brief fill destination BitBuffer with a number of bytes from source BitBuffer. The + * bytesValid variable returns the number of ramaining valid bytes in source BitBuffer. + * + * \param hBSDst HANDLE_FDK_BITSTREAM handle to write data into + * \param hBSSrc HANDLE_FDK_BITSTREAM handle to read data from + * \param bytesValid Input: number of valid bytes in inputBuffer. Output: bytes still left unread in inputBuffer. + * \return void + */ +FDK_INLINE void FDKcopyBuffer (HANDLE_FDK_BITSTREAM hBSDst, HANDLE_FDK_BITSTREAM hBSSrc, UINT *bytesValid) +{ + FDKsyncCache (hBSSrc) ; + FDK_Copy (&hBSDst->hBitBuf, &hBSSrc->hBitBuf, bytesValid) ; +} + + +/** + * \brief fill the outputBuffer with all valid bytes hold in BitBuffer. The WriteBytes + * variable returns the number of written Bytes. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param outputBuffer Pointer to output buffer. + * \param writeBytes Number of bytes write to output buffer. + * \return void + */ +FDK_INLINE void FDKfetchBuffer(HANDLE_FDK_BITSTREAM hBitStream, UCHAR *outputBuffer, UINT *writeBytes) +{ + FDKsyncCache (hBitStream) ; + FDK_Fetch(&hBitStream->hBitBuf, outputBuffer, writeBytes); +} + + +#endif diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_core.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_core.h new file mode 100644 index 0000000..a00bf7c --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_core.h @@ -0,0 +1,109 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools *********************** + + Author(s): Manuel Jander + Description: FDK tools versioning support + +******************************************************************************/ + +#ifndef FDK_CORE_H +#define FDK_CORE_H + +#include "FDK_audio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Get FDK_tools library information. + * @return Return 0 on success and a negative errorcode on failure (see errorcodes.h). + */ +int FDK_toolsGetLibInfo(LIB_INFO *info); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_crc.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_crc.h new file mode 100644 index 0000000..f4e7ad9 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_crc.h @@ -0,0 +1,231 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/******************************** MPEG Audio Encoder ************************** + + Initial author: + contents/description: CRC calculation + +******************************************************************************/ + +#ifndef FDK_CRC_H +#define FDK_CRC_H + + + +#include "FDK_bitstream.h" + + +#define MAX_CRC_REGS 3 /*!< Maximal number of overlapping crc region in ADTS channel pair element is two. + Select three independent regions preventively. */ + +/** + * This structure describes single crc region used for crc calculation. + */ +typedef struct +{ + UCHAR isActive; + INT maxBits; + UINT bitBufCntBits; + UINT validBits; + +} CCrcRegData; + +/** + * CRC info structure. + */ +typedef struct +{ + CCrcRegData crcRegData[MAX_CRC_REGS]; /*!< Multiple crc region description. */ + const USHORT *pCrcLookup; /*!< Pointer to lookup table filled in FDK_crcInit(). */ + + USHORT crcPoly; /*!< CRC generator polynom. */ + USHORT crcMask; /*!< CRC mask. */ + USHORT startValue; /*!< CRC start value. */ + UCHAR crcLen; /*!< CRC length. */ + + UINT regStart; /*!< Start region marker for synchronization. */ + UINT regStop; /*!< Stop region marker for synchronization. */ + + USHORT crcValue; /*!< Crc value to be calculated. */ + +} FDK_CRCINFO; + +/** + * CRC info handle. + */ +typedef FDK_CRCINFO* HANDLE_FDK_CRCINFO; + + +/** + * \brief Initialize CRC structure. + * + * The function initializes existing crc info structure with denoted configuration. + * + * \param hCrcInfo Pointer to an outlying allocated crc info structure. + * \param crcPoly Configure crc polynom. + * \param crcStartValue Configure crc start value. + * \param crcLen Configure crc length. + * + * \return none + */ +void FDKcrcInit( + HANDLE_FDK_CRCINFO hCrcInfo, + const UINT crcPoly, + const UINT crcStartValue, + const UINT crcLen + ); + +/** + * \brief Reset CRC info structure. + * + * This function clears all intern states of the crc structure. + * + * \param hCrcInfo Pointer to crc info stucture. + * + * \return none + */ +void FDKcrcReset( + HANDLE_FDK_CRCINFO hCrcInfo + ); + + +/** + * \brief Start CRC region with maximum number of bits. + * + * This function marks position in bitstream to be used as start point for crc calculation. + * Bitstream range for crc calculation can be limited or kept dynamic depending on mBits parameter. + * The crc region has to be terminated with FDKcrcEndReg() in each case. + * + * \param hCrcInfo Pointer to crc info stucture. + * \param hBs Pointer to current bit buffer structure. + * \param mBits Number of bits in crc region to be calculated. + * - mBits > 0: Zero padding will be used for CRC calculation, if there + * are less than mBits bits available. + * - mBits < 0: No zero padding is done. + * - mBits = 0: The number of bits used in crc calculation is dynamically, + * depending on bitstream position between FDKcrcStartReg() and + * FDKcrcEndReg() call. + * + * \return ID for the created region, -1 in case of an error + */ +INT FDKcrcStartReg( + HANDLE_FDK_CRCINFO hCrcInfo, + const HANDLE_FDK_BITSTREAM hBs, + const INT mBits + ); + + +/** + * \brief Ends CRC region. + * + * This function terminates crc region specified with FDKcrcStartReg(). The number of bits in crc region depends + * on mBits parameter of FDKcrcStartReg(). + * This function calculates and updates crc in info structure. + * + * \param hCrcInfo Pointer to crc info stucture. + * \param hBs Pointer to current bit buffer structure. + * \param reg Crc region ID created in FDKcrcStartReg(). + * + * \return 0 on success + */ +INT FDKcrcEndReg( + HANDLE_FDK_CRCINFO hCrcInfo, + const HANDLE_FDK_BITSTREAM hBs, + const INT reg + ); + + +/** + * \brief This function returns crc value from info struct. + * + * \param hCrcInfo Pointer to crc info stucture. + * + * \return CRC value masked with crc length. + */ +USHORT FDKcrcGetCRC( + const HANDLE_FDK_CRCINFO hCrcInfo + ); + + +#endif /* FDK_CRC_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_hybrid.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_hybrid.h new file mode 100644 index 0000000..ec0e0fb --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_hybrid.h @@ -0,0 +1,273 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): Markus Lohwasser + Description: FDK Tools Hybrid Filterbank + +******************************************************************************/ + +#ifndef __FDK_HYBRID_H +#define __FDK_HYBRID_H + + + +#include "common_fix.h" + +/*--------------- enums -------------------------------*/ + +/** + * Hybrid Filterband modes. + */ +typedef enum { + THREE_TO_TEN, + THREE_TO_TWELVE, + THREE_TO_SIXTEEN + +} FDK_HYBRID_MODE; + + +/*--------------- structure definitions ---------------*/ +typedef struct FDK_HYBRID_SETUP *HANDLE_FDK_HYBRID_SETUP; + +typedef struct +{ + FIXP_DBL *bufferLFReal[3]; /*!< LF real filter states. */ + FIXP_DBL *bufferLFImag[3]; /*!< LF imag filter states. */ + FIXP_DBL *bufferHFReal[13]; /*!< HF real delay lines. */ + FIXP_DBL *bufferHFImag[13]; /*!< HF imag delay lines. */ + + INT bufferLFpos; /*!< Position to write incoming data into ringbuffer. */ + INT bufferHFpos; /*!< Delay line positioning. */ + INT nrBands; /*!< Number of QMF bands. */ + INT cplxBands; /*!< Number of complex QMF bands.*/ + UCHAR hfMode; /*!< Flag signalizes treatment of HF bands. */ + + FIXP_DBL *pLFmemory; /*!< Pointer to LF states buffer. */ + FIXP_DBL *pHFmemory; /*!< Pointer to HF states buffer. */ + + UINT LFmemorySize; /*!< Size of LF states buffer. */ + UINT HFmemorySize; /*!< Size of HF states buffer. */ + + HANDLE_FDK_HYBRID_SETUP pSetup; /*!< Pointer to filter setup. */ + +} FDK_ANA_HYB_FILTER; + + +typedef struct +{ + INT nrBands; /*!< Number of QMF bands. */ + INT cplxBands; /*!< Number of complex QMF bands.*/ + + HANDLE_FDK_HYBRID_SETUP pSetup; /*!< Pointer to filter setup. */ + +} FDK_SYN_HYB_FILTER; + +typedef FDK_ANA_HYB_FILTER *HANDLE_FDK_ANA_HYB_FILTER; +typedef FDK_SYN_HYB_FILTER *HANDLE_FDK_SYN_HYB_FILTER; + + +/** + * \brief Create one instance of Hybrid Analyis Filterbank. + * + * \param hAnalysisHybFilter Pointer to an outlying allocated Hybrid Analysis Filterbank structure. + * \param pLFmemory Pointer to outlying buffer used LF filtering. + * \param LFmemorySize Size of pLFmemory in bytes. + * \param pHFmemory Pointer to outlying buffer used HF delay line. + * \param HFmemorySize Size of pLFmemory in bytes. + * + * \return 0 on success. + */ +INT FDKhybridAnalysisOpen( + HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter, + FIXP_DBL *const pLFmemory, + const UINT LFmemorySize, + FIXP_DBL *const pHFmemory, + const UINT HFmemorySize + ); + + +/** + * \brief Initialize and configure Hybrdid Analysis Filterbank instance. + * + * \param hAnalysisHybFilter A Hybrid Analysis Filterbank handle. + * \param mode Select hybrid filter configuration. + * \param qmfBands Number of qmf bands to be processed. + * \param cplxBands Number of complex qmf bands to be processed. + * \param initStatesFlag Indicates whether the states buffer has to be cleared. + * + * \return 0 on success. + */ +INT FDKhybridAnalysisInit( + HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter, + const FDK_HYBRID_MODE mode, + const INT qmfBands, + const INT cplxBands, + const INT initStatesFlag + ); + + +/** + * \brief Adjust Hybrdid Analysis Filterbank states. + * + * \param hAnalysisHybFilter A Hybrid Analysis Filterbank handle. + * \param scalingValue Scaling value to be applied on filter states. + * + * \return 0 on success. + */ +INT FDKhybridAnalysisScaleStates( + HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter, + const INT scalingValue + ); + + +/** + * \brief Apply Hybrid Analysis Filterbank on Qmf input data. + * + * \param hAnalysisHybFilter A Hybrid Analysis Filterbank handle. + * \param pQmfReal Qmf input data. + * \param pQmfImag Qmf input data. + * \param pHybridReal Hybrid output data. + * \param pHybridImag Hybrid output data. + * + * \return 0 on success. + */ +INT FDKhybridAnalysisApply( + HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter, + const FIXP_DBL *const pQmfReal, + const FIXP_DBL *const pQmfImag, + FIXP_DBL *const pHybridReal, + FIXP_DBL *const pHybridImag + ); + + +/** + * \brief Close a Hybrid Analysis Filterbank instance. + * + * \param hAnalysisHybFilter Pointer to a Hybrid Analysis Filterbank instance. + * + * \return 0 on success. + */ +INT FDKhybridAnalysisClose( + HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter + ); + +/** + * \brief Initialize and configure Hybrdid Synthesis Filterbank instance. + * + * \param hSynthesisHybFilter A Hybrid Synthesis Filterbank handle. + * \param mode Select hybrid filter configuration. + * \param qmfBands Number of qmf bands to be processed. + * \param cplxBands Number of complex qmf bands to be processed. + * + * \return 0 on success. + */ +INT FDKhybridSynthesisInit( + HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter, + const FDK_HYBRID_MODE mode, + const INT qmfBands, + const INT cplxBands + ); + +/** + * \brief Apply Hybrid Analysis Filterbank on Hybrid data. + * + * \param hSynthesisHybFilter A Hybrid Analysis Filterbandk handle. + * \param pHybridReal Hybrid input data. + * \param pHybridImag Hybrid input data. + * \param pQmfReal Qmf output data. + * \param pQmfImag Qmf output data. + * + * \return 0 on success. + */ +INT FDKhybridSynthesisApply( + HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter, + const FIXP_DBL *const pHybridReal, + const FIXP_DBL *const pHybridImag, + FIXP_DBL *const pQmfReal, + FIXP_DBL *const pQmfImag + ); + + +#endif /* __FDK_HYBRID_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_tools_rom.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_tools_rom.h new file mode 100644 index 0000000..04c2032 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_tools_rom.h @@ -0,0 +1,270 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools *********************** + + Author(s): Oliver Moser + Description: ROM tables used by FDK tools + +******************************************************************************/ + +#ifndef __FDK_TOOLS_ROM_H__ +#define __FDK_TOOLS_ROM_H__ + +#include "common_fix.h" +#include "FDK_audio.h" + + +/* None radix2 rotation vectors */ +extern const FIXP_STB RotVectorReal60[60]; +extern const FIXP_STB RotVectorImag60[60]; +extern const FIXP_STB RotVectorReal240[240]; +extern const FIXP_STB RotVectorImag240[240]; +extern const FIXP_STB RotVectorReal480[480]; +extern const FIXP_STB RotVectorImag480[480]; + + +/* Regular sine tables */ +extern const FIXP_STP SineTable512[]; +extern const FIXP_STP SineTable480[]; + +/* AAC-LC windows */ +extern const FIXP_WTP SineWindow1024[]; +extern const FIXP_WTP KBDWindow1024[]; +extern const FIXP_WTP SineWindow128[]; +extern const FIXP_WTP KBDWindow128[]; + +extern const FIXP_WTP SineWindow960[]; +extern const FIXP_WTP KBDWindow960[]; +extern const FIXP_WTP SineWindow120[]; +extern const FIXP_WTP KBDWindow120[]; + +/* AAC-LD windows */ +extern const FIXP_WTP SineWindow512[]; +#define LowOverlapWindow512 SineWindow128 +extern const FIXP_WTP SineWindow480[]; +#define LowOverlapWindow480 SineWindow120 + + + +extern const FIXP_WTP SineWindow64[]; +extern const FIXP_WTP SineWindow32[]; + +/** + * \brief Helper table for window slope mapping. You should prefer the usage of the + * function FDKgetWindowSlope(), this table is only made public for some optimized + * access inside dct.cpp. + */ +extern const FIXP_WTP *const windowSlopes[2][3][9]; + +/** + * \brief Window slope access helper. Obtain a window of given length and shape. + * \param length Length of the window slope. + * \param shape Shape index of the window slope. 0: sine window, 1: Kaiser-Bessel. Any other + * value is applied a mask of 1 to, mapping it to either 0 or 1. + * \param Pointer to window slope or NULL if the requested window slope is not available. + */ +const FIXP_WTP * FDKgetWindowSlope(int length, int shape); + +extern const FIXP_WTP sin_twiddle_L64[]; + +/* + * Filter coefficient type definition + */ + +#if defined(ARCH_PREFER_MULT_16x16) || defined(ARCH_PREFER_MULT_32x16) + #define QMF_COEFF_16BIT +#endif + +#define QMF_FILTER_PROTOTYPE_SIZE 640 +#define QMF_NO_POLY 5 + +#ifdef QMF_COEFF_16BIT + #define FIXP_PFT FIXP_SGL + #define FIXP_QTW FIXP_SGL +#else + #define FIXP_PFT FIXP_DBL + #define FIXP_QTW FIXP_DBL +#endif + +#define QMF640_PFT_TABLE_SIZE (640/2 + QMF_NO_POLY) + +extern const FIXP_QTW qmf_phaseshift_cos32[32]; +extern const FIXP_QTW qmf_phaseshift_sin32[32]; +/* Adapted analysis post-twiddles for down-sampled HQ SBR */ +extern const FIXP_QTW qmf_phaseshift_cos_downsamp32[32]; +extern const FIXP_QTW qmf_phaseshift_sin_downsamp32[32]; +extern const FIXP_QTW qmf_phaseshift_cos64[64]; +extern const FIXP_QTW qmf_phaseshift_sin64[64]; + +extern const FIXP_PFT qmf_64[QMF640_PFT_TABLE_SIZE+QMF_NO_POLY]; + + + + + +#define QMF640_CLDFB_PFT_TABLE_SIZE (640) +#define QMF320_CLDFB_PFT_TABLE_SIZE (320) +#define QMF_CLDFB_PFT_SCALE 1 + +extern const FIXP_QTW qmf_phaseshift_cos32_cldfb[32]; +extern const FIXP_QTW qmf_phaseshift_sin32_cldfb[32]; +extern const FIXP_QTW qmf_phaseshift_cos64_cldfb[64]; +extern const FIXP_QTW qmf_phaseshift_sin64_cldfb[64]; + +extern const FIXP_PFT qmf_cldfb_640[QMF640_CLDFB_PFT_TABLE_SIZE]; +extern const FIXP_PFT qmf_cldfb_320[QMF320_CLDFB_PFT_TABLE_SIZE]; + + + + + +/* + * Raw Data Block list stuff. + */ +typedef enum { + element_instance_tag, + common_window, + global_gain, + ics_info, /* ics_reserved_bit, window_sequence, window_shape, max_sfb, scale_factor_grouping, predictor_data_present, ltp_data_present, ltp_data */ + max_sfb, + ms, /* ms_mask_present, ms_used */ + /*predictor_data_present,*/ /* part of ics_info */ + ltp_data_present, + ltp_data, + section_data, + scale_factor_data, + pulse, /* pulse_data_present, pulse_data */ + tns_data_present, + tns_data, + gain_control_data_present, + gain_control_data, + esc1_hcr, + esc2_rvlc, + spectral_data, + + scale_factor_data_usac, + core_mode, + common_tw, + lpd_channel_stream, + tw_data, + noise, + ac_spectral_data, + fac_data, + tns_active, /* introduced in MPEG-D usac CD */ + tns_data_present_usac, + common_max_sfb, + + + /* Non data list items */ + adtscrc_start_reg1, + adtscrc_start_reg2, + adtscrc_end_reg1, + adtscrc_end_reg2, + drmcrc_start_reg, + drmcrc_end_reg, + next_channel, + next_channel_loop, + link_sequence, + end_of_sequence +} rbd_id_t; + +struct element_list { + const rbd_id_t *id; + const struct element_list *next[2]; +}; + +typedef struct element_list element_list_t; +/** + * \brief get elementary stream pieces list for given parameters. + * \param aot audio object type + * \param epConfig the epConfig value from the current Audio Specific Config + * \param nChannels amount of channels contained in the current element. + * \param layer the layer of the current element. + * \return element_list_t parser guidance structure. + */ +const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epConfig, UCHAR nChannels, UCHAR layer); + + +#endif + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_trigFcts.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_trigFcts.h new file mode 100644 index 0000000..abddc3c --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/FDK_trigFcts.h @@ -0,0 +1,229 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): Haricharan Lakshman, Manuel Jander + Description: Trigonometric functions fixed point fractional implementation. + +******************************************************************************/ + + + +#include "common_fix.h" + +#include "FDK_tools_rom.h" + +/* Fixed point precision definitions */ +#define Q(format) ((FIXP_DBL)(((LONG)1) << (format))) + +#ifndef M_PI +#define M_PI (3.14159265358979323846f) +#endif + +/*! + * Inverse tangent function. + */ + +// --- fixp_atan() ---- +#define Q_ATANINP (25) // Input in q25, Output in q30 +#define Q_ATANOUT (30) +#define ATI_SF ((DFRACT_BITS-1)-Q_ATANINP) // 6 +#define ATI_SCALE ((float)(1<> shift; + + residual &= ( (1< (1< (1<<(LD-1))) { + FIXP_STP tmp; + /* Cosine/Sine simetry for angles greater than PI/4 */ + s = (1<>32; + return result ; +} + +#endif /* defined(__GNUC__) */ + +#endif /* __aarch64__ */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/abs.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/abs.h new file mode 100644 index 0000000..be941f7 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/abs.h @@ -0,0 +1,121 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools *********************** + + Author(s): M. Lohwasser + Description: fixed point abs definitions + +******************************************************************************/ + +#if !defined(__ABS_H__) +#define __ABS_H__ + + +#if defined(__mips__) /* cppp replaced: elif */ +#include "mips/abs_mips.h" + +#elif defined(__x86__) /* cppp replaced: elif */ +#include "x86/abs_x86.h" + +#endif /* all cores */ + +/************************************************************************* + ************************************************************************* + Software fallbacks for missing functions +************************************************************************** +**************************************************************************/ + +#if !defined(FUNCTION_fixabs_D) +inline FIXP_DBL fixabs_D(FIXP_DBL x) { return ((x) > (FIXP_DBL)(0)) ? (x) : -(x) ; } +#endif + +#if !defined(FUNCTION_fixabs_I) +inline INT fixabs_I(INT x) { return ((x) > (INT)(0)) ? (x) : -(x) ; } +#endif + +#if !defined(FUNCTION_fixabs_S) +inline FIXP_SGL fixabs_S(FIXP_SGL x) { return ((x) > (FIXP_SGL)(0)) ? (x) : -(x) ; } +#endif + +#endif /* __ABS_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/clz_arm.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/clz_arm.h new file mode 100644 index 0000000..ac1db66 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/clz_arm.h @@ -0,0 +1,122 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__arm__) + +#if defined(__GNUC__) && defined(__ARM_ARCH_5TE__) /* cppp replaced: elif */ + /* ARM gcc*/ + + #define FUNCTION_fixnormz_D + #define FUNCTION_fixnorm_D + + inline INT fixnormz_D(LONG value) + { + INT result; + asm("clz %0, %1 ": "=r"(result) : "r"(value) ); + return result; + } + + inline INT fixnorm_D(LONG value) + { + INT result; + if (value == 0) { + return 0; + } + if (value < 0) { + value = ~value; + } + result = fixnormz_D(value); + return result - 1; + } + +#endif /* arm toolchain */ + +#endif /* __arm__ */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/cplx_mul.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/cplx_mul.h new file mode 100644 index 0000000..1dd236d --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/cplx_mul.h @@ -0,0 +1,214 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__arm__) && defined(__GNUC__) /* cppp replaced: elif */ + +#if defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__) + #define FUNCTION_cplxMultDiv2_32x16 + #define FUNCTION_cplxMultDiv2_32x16X2 + //#define FUNCTION_cplxMult_32x16 + //#define FUNCTION_cplxMult_32x16X2 +#endif + +#define FUNCTION_cplxMultDiv2_32x32X2 +//#define FUNCTION_cplxMult_32x32X2 + +#ifdef FUNCTION_cplxMultDiv2_32x16 +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SPK wpk ) +{ + LONG tmp1,tmp2; + const LONG w = wpk.w; + + asm("smulwt %0, %3, %4;\n" + "rsb %1,%0,#0;\n" + "smlawb %0, %2, %4, %1;\n" + "smulwt %1, %2, %4;\n" + "smlawb %1, %3, %4, %1;\n" + : "=&r"(tmp1), "=&r"(tmp2) + : "r"(a_Re), "r"(a_Im), "r"(w) + ); + + *c_Re = tmp1; + *c_Im = tmp2; +} +#endif /* FUNCTION_cplxMultDiv2_32x16 */ + +#ifdef FUNCTION_cplxMultDiv2_32x16X2 +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + LONG tmp1, tmp2; + + asm("smulwb %0, %3, %5;\n" /* %7 = -a_Im * b_Im */ + "rsb %1,%0,#0;\n" + "smlawb %0, %2, %4, %1;\n" /* tmp1 = a_Re * b_Re - a_Im * b_Im */ + "smulwb %1, %2, %5;\n" /* %7 = a_Re * b_Im */ + "smlawb %1, %3, %4, %1;\n" /* tmp2 = a_Im * b_Re + a_Re * b_Im */ + : "=&r"(tmp1), "=&r"(tmp2) + : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im) + ); + + *c_Re = tmp1; + *c_Im = tmp2; +} +#endif /* FUNCTION_cplxMultDiv2_32x16X2 */ + +#ifdef FUNCTION_cplxMultAddDiv2_32x16X2 +inline void cplxMultAddDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + LONG tmp1, tmp2; + + asm("smulwb %0, %3, %5;\n" + "rsb %1,%0,#0;\n" + "smlawb %0, %2, %4, %1;\n" + "smulwb %1, %2, %5;\n" + "smlawb %1, %3, %4, %1;\n" + : "=&r"(tmp1), "=&r"(tmp2) + : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im) + ); + + *c_Re += tmp1; + *c_Im += tmp2; +} +#endif /* FUNCTION_cplxMultAddDiv2_32x16X2 */ + + +#ifdef FUNCTION_cplxMultDiv2_32x32X2 +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DBL b_Re, + const FIXP_DBL b_Im) +{ + LONG tmp1, tmp2; + +#ifdef __ARM_ARCH_6__ + asm( + "smmul %0, %2, %4;\n" /* tmp1 = a_Re * b_Re */ + "smmls %0, %3, %5, %0;\n" /* tmp1 -= a_Im * b_Im */ + "smmul %1, %2, %5;\n" /* tmp2 = a_Re * b_Im */ + "smmla %1, %3, %4, %1;\n" /* tmp2 += a_Im * b_Re */ + : "=&r"(tmp1), "=&r"(tmp2) + : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im) + : "r0" + ); +#else + LONG discard; + asm( + "smull %2, %0, %7, %6;\n" /* tmp1 = -a_Im * b_Im */ + "smlal %2, %0, %3, %5;\n" /* tmp1 += a_Re * b_Re */ + "smull %2, %1, %3, %6;\n" /* tmp2 = a_Re * b_Im */ + "smlal %2, %1, %4, %5;\n" /* tmp2 += a_Im * b_Re */ + : "=&r"(tmp1), "=&r"(tmp2), "=&r"(discard) + : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im), "r"(-a_Im) + ); + #endif + *c_Re = tmp1; + *c_Im = tmp2; +} +#endif /* FUNCTION_cplxMultDiv2_32x32X2 */ + + +#endif + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/fixmadd_arm.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/fixmadd_arm.h new file mode 100644 index 0000000..7650f7f --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/fixmadd_arm.h @@ -0,0 +1,160 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__arm__) + + /* ############################################################################# */ + #if defined(__GNUC__) && defined(__arm__) && !defined(__SYMBIAN32__) /* cppp replaced: elif */ + /* ############################################################################# */ + /* ARM GNU GCC */ + + #define FUNCTION_fixmadddiv2_DD + + #ifdef __ARM_ARCH_6__ + inline FIXP_DBL fixmadddiv2_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + INT result; + asm ("smmla %0, %1, %2, %3;\n" + : "=r" (result) + : "r" (a), "r" (b), "r"(x) ); + return result ; + } + #define FUNCTION_fixmsubdiv2_DD + inline FIXP_DBL fixmsubdiv2_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + INT result; + asm ("smmls %0, %1, %2, %3;\n" + : "=r" (result) + : "r" (a), "r" (b), "r"(x) ); + return result ; + } + #else /* __ARM_ARCH_6__ */ + inline FIXP_DBL fixmadddiv2_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + INT discard, result = x; + asm ("smlal %0, %1, %2, %3;\n" + : "=r" (discard), "+r" (result) + : "r" (a), "r" (b) ); + return result ; + } + #endif /* __ARM_ARCH_6__ */ + + #if defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__) + + #define FUNCTION_fixmadddiv2_DS + + inline FIXP_DBL fixmadddiv2_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { + INT result; + asm("smlawb %0, %1, %2, %3 " + : "=r" (result) + : "r" (a), "r" (b), "r" (x) ); + return result ; + } + + #endif /* defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__) */ + + #define FUNCTION_fixmadddiv2BitExact_DD + #define fixmadddiv2BitExact_DD(a, b, c) fixmadddiv2_DD(a, b, c) + + #define FUNCTION_fixmsubdiv2BitExact_DD + inline FIXP_DBL fixmsubdiv2BitExact_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + return x - fixmuldiv2BitExact_DD(a, b); + } + + #define FUNCTION_fixmadddiv2BitExact_DS + #define fixmadddiv2BitExact_DS(a, b, c) fixmadddiv2_DS(a, b, c) + + #define FUNCTION_fixmsubdiv2BitExact_DS + inline FIXP_DBL fixmsubdiv2BitExact_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { + return x - fixmuldiv2BitExact_DS(a, b); + } + /* ############################################################################# */ + #endif /* toolchain */ + /* ############################################################################# */ + +#endif /* __arm__ */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/fixmul_arm.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/fixmul_arm.h new file mode 100644 index 0000000..b64cc6c --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/fixmul_arm.h @@ -0,0 +1,142 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__arm__) + +#if defined(__GNUC__) && defined(__arm__) /* cppp replaced: elif */ +/* ARM with GNU compiler */ + +#define FUNCTION_fixmuldiv2_DD + +#define FUNCTION_fixmuldiv2BitExact_DD +#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b) +#define FUNCTION_fixmulBitExact_DD +#define fixmulBitExact_DD(a,b) fixmul_DD(a,b) + +#define FUNCTION_fixmuldiv2BitExact_DS +#define fixmuldiv2BitExact_DS(a,b) fixmuldiv2_DS(a,b) + +#define FUNCTION_fixmulBitExact_DS +#define fixmulBitExact_DS(a,b) fixmul_DS(a,b) + +#if defined(__ARM_ARCH_6__) || defined(__TARGET_ARCH_7E_M) +inline INT fixmuldiv2_DD (const INT a, const INT b) +{ + INT result ; + __asm__ ("smmul %0, %1, %2" : "=r" (result) + : "r" (a), "r" (b)) ; + return result ; +} +#else +inline INT fixmuldiv2_DD (const INT a, const INT b) +{ + INT discard, result ; + __asm__ ("smull %0, %1, %2, %3" : "=&r" (discard), "=r" (result) + : "r" (a), "r" (b)) ; + return result ; +} +#endif + +#if defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__) +#define FUNCTION_fixmuldiv2_SD +inline INT fixmuldiv2_SD (const SHORT a, const INT b) +{ + INT result ; + __asm__ ("smulwb %0, %1, %2" + : "=r" (result) + : "r" (b), "r" (a)) ; + return result ; +} +#endif + +#endif /* defined(__GNUC__) && defined(__arm__) */ + +#endif /* __arm__ */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/scale.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/scale.h new file mode 100644 index 0000000..575bb31 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/scale.h @@ -0,0 +1,152 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/******************************** Fraunhofer IIS *************************** + + Author(s): + Description: ARM scaling operations + +******************************************************************************/ + +#if defined(__GNUC__) /* GCC Compiler */ /* cppp replaced: elif */ + +#if defined(__ARM_ARCH_6__) + +inline static INT shiftRightSat(INT src, int scale) +{ + INT result; + asm( + "ssat %0,%2,%0;\n" + + : "=&r"(result) + : "r"(src>>scale), "M"(SAMPLE_BITS) + ); + + return result; +} + + #define SATURATE_INT_PCM_RIGHT_SHIFT(src, scale) shiftRightSat(src, scale) + +inline static INT shiftLeftSat(INT src, int scale) +{ + INT result; + asm( + "ssat %0,%2,%0;\n" + + : "=&r"(result) + : "r"(src<= 0) + *value <<= newscale; + else + *value >>= -newscale; +} + + + #define SATURATE_RIGHT_SHIFT(src, scale, dBits) \ + ( (((LONG)(src) ^ ((LONG)(src) >> (DFRACT_BITS-1)))>>(scale)) > (LONG)(((1U)<<((dBits)-1))-1)) \ + ? ((LONG)(src) >> (DFRACT_BITS-1)) ^ (LONG)(((1U)<<((dBits)-1))-1) \ + : ((LONG)(src) / ((LONG)1<<(scale))) + + #define SATURATE_LEFT_SHIFT(src, scale, dBits) \ + ( ((LONG)(src) ^ ((LONG)(src) >> (DFRACT_BITS-1))) > ((LONG)(((1U)<<((dBits)-1))-1) >> (scale)) ) \ + ? ((LONG)(src) >> (DFRACT_BITS-1)) ^ (LONG)(((1U)<<((dBits)-1))-1) \ + : ((LONG)(src) << (scale)) + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/scramble.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/scramble.h new file mode 100644 index 0000000..2f55c43 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/arm/scramble.h @@ -0,0 +1,158 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: bitreversal of input data + +******************************************************************************/ + +#if defined(FUNCTION_scramble) +#if defined(__GNUC__) /* cppp replaced: elif */ + +#define FUNCTION_scramble + +#if defined(__ARM_ARCH_5TE__) +#define USE_LDRD_STRD /* LDRD requires 8 byte data alignment. */ +#endif + +inline void scramble(FIXP_DBL x [], INT n) { + FDK_ASSERT(!(((INT)x)&(ALIGNMENT_DEFAULT-1))); + asm("mov r2, #1;\n" /* r2(m) = 1; */ + "sub r3, %1, #1;\n" /* r3 = n-1; */ + "mov r4, #0;\n" /* r4(j) = 0; */ + +"scramble_m_loop%=:\n" /* { */ + "mov r5, %1;\n" /* r5(k) = 1; */ + +"scramble_k_loop%=:\n" /* { */ + "mov r5, r5, lsr #1;\n" /* k >>= 1; */ + "eor r4, r4, r5;\n" /* j ^=k; */ + "ands r10, r4, r5;\n" /* r10 = r4 & r5; */ + "beq scramble_k_loop%=;\n" /* } while (r10 == 0); */ + + "cmp r4, r2;\n" /* if (r4 < r2) break; */ + "bcc scramble_m_loop_end%=;\n" + +#ifdef USE_LDRD_STRD + "mov r5, r2, lsl #3;\n" /* m(r5) = r2*4*2 */ + "ldrd r10, [%0, r5];\n" /* r10 = x[r5], x7 = x[r5+1] */ + "mov r6, r4, lsl #3;\n" /* j(r6) = r4*4*2 */ + "ldrd r8, [%0, r6];\n" /* r8 = x[r6], r9 = x[r6+1]; */ + "strd r10, [%0, r6];\n" /* x[r6,r6+1] = r10,r11; */ + "strd r8, [%0, r5];\n" /* x[r5,r5+1] = r8,r9; */ +#else + "mov r5, r2, lsl #3;\n" /* m(r5) = r2*4*2 */ + "ldr r10, [%0, r5];\n" + "mov r6, r4, lsl #3;\n" /* j(r6) = r4*4*2 */ + "ldr r11, [%0, r6];\n" + + "str r10, [%0, r6];\n" + "str r11, [%0, r5];\n" + + "add r5, r5, #4;" + "ldr r10, [%0, r5];\n" + "add r6, r6, #4;" + "ldr r11, [%0, r6];\n" + "str r10, [%0, r6];\n" + "str r11, [%0, r5];\n" +#endif +"scramble_m_loop_end%=:\n" + "add r2, r2, #1;\n" /* r2++; */ + "cmp r2, r3;\n" + "bcc scramble_m_loop%=;\n" /* } while (r2(m) < r3(n-1)); */ + : + : "r"(x), "r"(n) +#ifdef USE_LDRD_STRD + : "r2","r3", "r4","r5", "r10","r11", "r8","r9", "r6" ); +#else + : "r2","r3", "r4","r5", "r10","r11", "r6" ); +#endif +} +#else +/* Force C implementation if no assembler version available. */ +#undef FUNCTION_scramble +#endif /* Toolchain selection. */ + +#endif /* defined(FUNCTION_scramble) */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/autocorr2nd.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/autocorr2nd.h new file mode 100644 index 0000000..11797a1 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/autocorr2nd.h @@ -0,0 +1,128 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools *********************** + + Author(s): M. Lohwasser + Description: fixed point abs definitions + +******************************************************************************/ + +#ifndef _AUTOCORR_2ND_H +#define _AUTOCORR_2ND_H + + + +#include "common_fix.h" + +typedef struct { + FIXP_DBL r00r; + FIXP_DBL r11r; + FIXP_DBL r22r; + FIXP_DBL r01r; + FIXP_DBL r02r; + FIXP_DBL r12r; + FIXP_DBL r01i; + FIXP_DBL r02i; + FIXP_DBL r12i; + FIXP_DBL det; + int det_scale; +} ACORR_COEFS; + +#define LPC_ORDER 2 + + +INT +autoCorr2nd_real (ACORR_COEFS *ac, /*!< Pointer to autocorrelation coeffs */ + const FIXP_DBL *reBuffer, /*!< Pointer to to real part of spectrum */ + const int len /*!< Number of qmf slots */ + ); +INT +autoCorr2nd_cplx (ACORR_COEFS *ac, /*!< Pointer to autocorrelation coeffs */ + const FIXP_DBL *reBuffer, /*!< Pointer to to real part of spectrum */ + const FIXP_DBL *imBuffer, /*!< Pointer to imag part of spectrum */ + const int len /*!< Number of qmf slots */ + ); + + +#endif /* _AUTOCORR_2ND_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/clz.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/clz.h new file mode 100644 index 0000000..ef778e3 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/clz.h @@ -0,0 +1,198 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): Marc Gayer + Description: fixed point intrinsics + +******************************************************************************/ + +#if !defined(__CLZ_H__) +#define __CLZ_H__ + +#include "FDK_archdef.h" +#include "machine_type.h" + +#if defined(__arm__) +#include "arm/clz_arm.h" + +#elif defined(__aarch64__) || defined(__AARCH64EL__) +#include "aarch64/clz_aarch64.h" + +#elif defined(__mips__) /* cppp replaced: elif */ +#include "mips/clz_mips.h" + +#elif defined(__x86__) /* cppp replaced: elif */ +#include "x86/clz_x86.h" + +#elif defined(__powerpc__) +#include "ppc/clz_ppc.h" + +#endif /* all cores */ + + +/************************************************************************* + ************************************************************************* + Software fallbacks for missing functions. +************************************************************************** +**************************************************************************/ + +#if !defined(FUNCTION_fixnormz_S) +#ifdef FUNCTION_fixnormz_D +inline INT fixnormz_S (SHORT a) +{ + return fixnormz_D((INT)(a)); +} +#else +inline INT fixnormz_S (SHORT a) +{ + int leadingBits = 0; + a = ~a; + while(a & 0x8000) { + leadingBits++; + a <<= 1; + } + + return (leadingBits); +} +#endif +#endif + +#if !defined(FUNCTION_fixnormz_D) +inline INT fixnormz_D (LONG a) +{ + INT leadingBits = 0; + a = ~a; + while(a & 0x80000000) { + leadingBits++; + a <<= 1; + } + + return (leadingBits); +} +#endif + + +/***************************************************************************** + + functionname: fixnorm_D + description: Count leading ones or zeros of operand val for dfract/LONG INT values. + Return this value minus 1. Return 0 if operand==0. +*****************************************************************************/ +#if !defined(FUNCTION_fixnorm_S) +#ifdef FUNCTION_fixnorm_D +inline INT fixnorm_S(FIXP_SGL val) +{ + return fixnorm_D((INT)(val)); +} +#else +inline INT fixnorm_S(FIXP_SGL val) +{ + INT leadingBits = 0; + if ( val != (FIXP_SGL)0 ) { + if ( val < (FIXP_SGL)0 ) { + val = ~val; + } + leadingBits = fixnormz_S(val) - 1; + } + return (leadingBits); +} +#endif +#endif + +#if !defined(FUNCTION_fixnorm_D) +inline INT fixnorm_D(FIXP_DBL val) +{ + INT leadingBits = 0; + if ( val != (FIXP_DBL)0 ) { + if ( val < (FIXP_DBL)0 ) { + val = ~val; + } + leadingBits = fixnormz_D(val) - 1; + } + return (leadingBits); +} +#endif + +#endif /* __CLZ_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/common_fix.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/common_fix.h new file mode 100644 index 0000000..88456d7 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/common_fix.h @@ -0,0 +1,378 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): M. Lohwasser, M. Gayer + Description: Flexible fixpoint library configuration + +******************************************************************************/ + +#ifndef _COMMON_FIX_H +#define _COMMON_FIX_H + +#include "FDK_archdef.h" +#include "machine_type.h" + +/* ***** Start of former fix.h ****** */ + +/* Configure fractional or integer arithmetic */ + #define FIX_FRACT 0 /* Define this to "1" to use fractional arithmetic simulation in class fract instead of integer arithmetic */ + /* 1 for debug with extra runtime overflow checking. */ + +/* Define bit sizes of integer fixpoint fractional data types */ +#define FRACT_BITS 16 /* single precision */ +#define DFRACT_BITS 32 /* double precision */ +#define ACCU_BITS 40 /* double precision plus overflow */ + +/* Fixpoint equivalent type fot PCM audio time domain data. */ +#if defined(SAMPLE_BITS) +#if (SAMPLE_BITS == DFRACT_BITS) + #define FIXP_PCM FIXP_DBL + #define FX_PCM2FX_DBL(x) ((FIXP_DBL)(x)) + #define FX_DBL2FX_PCM(x) ((INT_PCM)(x)) +#elif (SAMPLE_BITS == FRACT_BITS) + #define FIXP_PCM FIXP_SGL + #define FX_PCM2FX_DBL(x) FX_SGL2FX_DBL((FIXP_SGL)(x)) + #define FX_DBL2FX_PCM(x) FX_DBL2FX_SGL(x) +#else + #error SAMPLE_BITS different from FRACT_BITS or DFRACT_BITS not implemented! +#endif +#endif + +/* ****** End of former fix.h ****** */ + +#define SGL_MASK ((1UL<> (DFRACT_BITS-FRACT_BITS-1)) + 1) > (((LONG)1< 0) ) ? \ + (FIXP_SGL)(SHORT)(((LONG)1<<(FRACT_BITS-1))-1):(FIXP_SGL)(SHORT)((((val) >> (DFRACT_BITS-FRACT_BITS-1)) + 1) >> 1) ) + + + +#define shouldBeUnion union /* unions are possible */ + + typedef SHORT FIXP_SGL; + typedef LONG FIXP_DBL; + +/* macros for compile-time conversion of constant float values to fixedpoint */ +#define FL2FXCONST_SPC FL2FXCONST_DBL + +#define MINVAL_DBL_CONST MINVAL_DBL +#define MINVAL_SGL_CONST MINVAL_SGL + +#define FL2FXCONST_SGL(val) \ +(FIXP_SGL)( ( (val) >= 0) ? \ +((( (double)(val) * (FRACT_FIX_SCALE) + (double)0.5 ) >= (double)(MAXVAL_SGL) ) ? (SHORT)(MAXVAL_SGL) : (SHORT)( (double)(val) * (double)(FRACT_FIX_SCALE) + (double)0.5)) : \ +((( (double)(val) * (FRACT_FIX_SCALE) - (double)0.5) <= (double)(MINVAL_SGL_CONST) ) ? (SHORT)(MINVAL_SGL_CONST) : (SHORT)( (double)(val) * (double)(FRACT_FIX_SCALE) - (double)0.5)) ) + +#define FL2FXCONST_DBL(val) \ +(FIXP_DBL)( ( (val) >= 0) ? \ +((( (double)(val) * (DFRACT_FIX_SCALE) + (double)0.5 ) >= (double)(MAXVAL_DBL) ) ? (LONG)(MAXVAL_DBL) : (LONG)( (double)(val) * (double)(DFRACT_FIX_SCALE) + (double)0.5)) : \ +((( (double)(val) * (DFRACT_FIX_SCALE) - (double)0.5) <= (double)(MINVAL_DBL_CONST) ) ? (LONG)(MINVAL_DBL_CONST) : (LONG)( (double)(val) * (double)(DFRACT_FIX_SCALE) - (double)0.5)) ) + +/* macros for runtime conversion of float values to integer fixedpoint. NO OVERFLOW CHECK!!! */ +#define FL2FX_SPC FL2FX_DBL +#define FL2FX_SGL(val) ( (val)>0.0f ? (SHORT)( (val)*(float)(FRACT_FIX_SCALE)+0.5f ) : (SHORT)( (val)*(float)(FRACT_FIX_SCALE)-0.5f ) ) +#define FL2FX_DBL(val) ( (val)>0.0f ? (LONG)( (val)*(float)(DFRACT_FIX_SCALE)+0.5f ) : (LONG)( (val)*(float)(DFRACT_FIX_SCALE)-0.5f ) ) + +/* macros for runtime conversion of fixedpoint values to other fixedpoint. NO ROUNDING!!! */ +#define FX_ACC2FX_SGL(val) ((FIXP_SGL)((val)>>(ACCU_BITS-FRACT_BITS))) +#define FX_ACC2FX_DBL(val) ((FIXP_DBL)((val)>>(ACCU_BITS-DFRACT_BITS))) +#define FX_SGL2FX_ACC(val) ((FIXP_ACC)((LONG)(val)<<(ACCU_BITS-FRACT_BITS))) +#define FX_SGL2FX_DBL(val) ((FIXP_DBL)((LONG)(val)<<(DFRACT_BITS-FRACT_BITS))) +#define FX_DBL2FX_SGL(val) ((FIXP_SGL)((val)>>(DFRACT_BITS-FRACT_BITS))) + +/* ############################################################# */ + +/* macros for runtime conversion of integer fixedpoint values to float. */ +/* This is just for temporary use and should not be required in a final version! */ + +/* #define FX_DBL2FL(val) ((float)(pow(2.,-31.)*(float)val)) */ /* version #1 */ +#define FX_DBL2FL(val) ((float)((double)(val)/(double)DFRACT_FIX_SCALE)) /* version #2 - identical to class dfract cast from dfract to float */ + +/* ############################################################# */ +#include "fixmul.h" + +FDK_INLINE LONG fMult(SHORT a, SHORT b) { return fixmul_SS(a, b); } +FDK_INLINE LONG fMult(SHORT a, LONG b) { return fixmul_SD(a, b); } +FDK_INLINE LONG fMult(LONG a, SHORT b) { return fixmul_DS(a, b); } +FDK_INLINE LONG fMult(LONG a, LONG b) { return fixmul_DD(a, b); } +FDK_INLINE LONG fPow2(LONG a) { return fixpow2_D(a); } +FDK_INLINE LONG fPow2(SHORT a) { return fixpow2_S(a); } + +FDK_INLINE INT fMultI(LONG a, SHORT b) { return ( (INT)(((1<<(FRACT_BITS-2)) + + fixmuldiv2_DD(a,((INT)b<>(FRACT_BITS-1)) ); } + +FDK_INLINE INT fMultIfloor(LONG a, INT b) { return ( (INT)((1 + + fixmuldiv2_DD(a,(b<> (FRACT_BITS-1)) ); } + +FDK_INLINE INT fMultIceil(LONG a, INT b) { return ( (INT)(((INT)0x7fff + + fixmuldiv2_DD(a,(b<> (FRACT_BITS-1)) ); } + +FDK_INLINE LONG fMultDiv2(SHORT a, SHORT b) { return fixmuldiv2_SS(a, b); } +FDK_INLINE LONG fMultDiv2(SHORT a, LONG b) { return fixmuldiv2_SD(a, b); } +FDK_INLINE LONG fMultDiv2(LONG a, SHORT b) { return fixmuldiv2_DS(a, b); } +FDK_INLINE LONG fMultDiv2(LONG a, LONG b) { return fixmuldiv2_DD(a, b); } +FDK_INLINE LONG fPow2Div2(LONG a) { return fixpow2div2_D(a); } +FDK_INLINE LONG fPow2Div2(SHORT a) { return fixpow2div2_S(a); } + +FDK_INLINE LONG fMultDiv2BitExact(LONG a, LONG b) { return fixmuldiv2BitExact_DD(a, b); } +FDK_INLINE LONG fMultDiv2BitExact(SHORT a, LONG b) { return fixmuldiv2BitExact_SD(a, b); } +FDK_INLINE LONG fMultDiv2BitExact(LONG a, SHORT b) { return fixmuldiv2BitExact_DS(a, b); } +FDK_INLINE LONG fMultBitExact(LONG a, LONG b) { return fixmulBitExact_DD(a, b); } +FDK_INLINE LONG fMultBitExact(SHORT a, LONG b) { return fixmulBitExact_SD(a, b); } +FDK_INLINE LONG fMultBitExact(LONG a, SHORT b) { return fixmulBitExact_DS(a, b); } + +/* ******************************************************************************** */ +#include "abs.h" + +FDK_INLINE FIXP_DBL fAbs(FIXP_DBL x) + { return fixabs_D(x); } +FDK_INLINE FIXP_SGL fAbs(FIXP_SGL x) + { return fixabs_S(x); } + +/* workaround for TI C6x compiler but not for TI ARM9E compiler */ +#if (!defined(__TI_COMPILER_VERSION__) || defined(__TI_TMS470_V5__)) && !defined(__LP64__) +FDK_INLINE INT fAbs(INT x) + { return fixabs_I(x); } +#endif + +/* ******************************************************************************** */ + +#include "clz.h" + +FDK_INLINE INT fNormz(FIXP_DBL x) + { return fixnormz_D(x); } +FDK_INLINE INT fNormz(FIXP_SGL x) + { return fixnormz_S(x); } +FDK_INLINE INT fNorm(FIXP_DBL x) + { return fixnorm_D(x); } +FDK_INLINE INT fNorm(FIXP_SGL x) + { return fixnorm_S(x); } + + +/* ******************************************************************************** */ +/* ******************************************************************************** */ +/* ******************************************************************************** */ + +#include "clz.h" +#define fixp_abs(x) fAbs(x) +#define fixMin(a,b) fMin(a,b) +#define fixMax(a,b) fMax(a,b) +#define CntLeadingZeros(x) fixnormz_D(x) +#define CountLeadingBits(x) fixnorm_D(x) + +#include "fixmadd.h" + +/* y = (x+0.5*a*b) */ +FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmadddiv2_DD(x, a, b); } +FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmadddiv2_SD(x, a, b); } +FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmadddiv2_DS(x, a, b); } +FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) + { return fixmadddiv2_SS(x, a, b); } + +FDK_INLINE FIXP_DBL fPow2AddDiv2(FIXP_DBL x, FIXP_DBL a) + { return fixpadddiv2_D(x, a); } +FDK_INLINE FIXP_DBL fPow2AddDiv2(FIXP_DBL x, FIXP_SGL a) + { return fixpadddiv2_S(x, a); } + + +/* y = 2*(x+0.5*a*b) = (2x+a*b) */ +FDK_INLINE FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmadd_DD(x, a, b); } +inline FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmadd_SD(x, a, b); } +inline FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmadd_DS(x, a, b); } +inline FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) + { return fixmadd_SS(x, a, b); } + +inline FIXP_DBL fPow2Add(FIXP_DBL x, FIXP_DBL a) + { return fixpadd_D(x, a); } +inline FIXP_DBL fPow2Add(FIXP_DBL x, FIXP_SGL a) + { return fixpadd_S(x, a); } + + +/* y = (x-0.5*a*b) */ +inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmsubdiv2_DD(x, a, b); } +inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmsubdiv2_SD(x, a, b); } +inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmsubdiv2_DS(x, a, b); } +inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) + { return fixmsubdiv2_SS(x, a, b); } + +/* y = 2*(x-0.5*a*b) = (2*x-a*b) */ +FDK_INLINE FIXP_DBL fMultSub(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmsub_DD(x, a, b); } +inline FIXP_DBL fMultSub(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmsub_SD(x, a, b); } +inline FIXP_DBL fMultSub(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmsub_DS(x, a, b); } +inline FIXP_DBL fMultSub(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) + { return fixmsub_SS(x, a, b); } + +FDK_INLINE FIXP_DBL fMultAddDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmadddiv2BitExact_DD(x, a, b); } +FDK_INLINE FIXP_DBL fMultAddDiv2BitExact(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmadddiv2BitExact_SD(x, a, b); } +FDK_INLINE FIXP_DBL fMultAddDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmadddiv2BitExact_DS(x, a, b); } +FDK_INLINE FIXP_DBL fMultSubDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmsubdiv2BitExact_DD(x, a, b); } +FDK_INLINE FIXP_DBL fMultSubDiv2BitExact(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmsubdiv2BitExact_SD(x, a, b); } +FDK_INLINE FIXP_DBL fMultSubDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmsubdiv2BitExact_DS(x, a, b); } + +#include "fixminmax.h" + +FDK_INLINE FIXP_DBL fMin(FIXP_DBL a, FIXP_DBL b) + { return fixmin_D(a,b); } +FDK_INLINE FIXP_DBL fMax(FIXP_DBL a, FIXP_DBL b) + { return fixmax_D(a,b); } + +FDK_INLINE FIXP_SGL fMin(FIXP_SGL a, FIXP_SGL b) + { return fixmin_S(a,b); } +FDK_INLINE FIXP_SGL fMax(FIXP_SGL a, FIXP_SGL b) + { return fixmax_S(a,b); } + +/* workaround for TI C6x compiler but not for TI ARM9E */ +#if ((!defined(__TI_COMPILER_VERSION__) || defined(__TI_TMS470_V5__)) && !defined(__LP64__)) || (FIX_FRACT == 1) +FDK_INLINE INT fMax(INT a, INT b) + { return fixmax_I(a,b); } +FDK_INLINE INT fMin(INT a, INT b) + { return fixmin_I(a,b); } +#endif + +inline UINT fMax(UINT a, UINT b) + { return fixmax_UI(a,b); } +inline UINT fMin(UINT a, UINT b) + { return fixmin_UI(a,b); } + +/* Complex data types */ +typedef shouldBeUnion { + /* vector representation for arithmetic */ + struct { + FIXP_SGL re; + FIXP_SGL im; + } v; + /* word representation for memory move */ + LONG w; +} FIXP_SPK; + +typedef shouldBeUnion { + /* vector representation for arithmetic */ + struct { + FIXP_DBL re; + FIXP_DBL im; + } v; + /* word representation for memory move */ + INT64 w; +} FIXP_DPK; + +#include "fixmul.h" +#include "fixmadd.h" +#include "cplx_mul.h" +#include "scale.h" +#include "fixpoint_math.h" + +#endif diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/cplx_mul.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/cplx_mul.h new file mode 100644 index 0000000..56e3453 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/cplx_mul.h @@ -0,0 +1,269 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#include "common_fix.h" + +#if !defined(__CPLX_Mult_H__) +#define __CPLX_Mult_H__ + +#if defined(__CC_ARM) || defined(__arm__) || defined(_M_ARM) /* cppp replaced: elif */ +#include "arm/cplx_mul.h" + +#elif defined(__GNUC__) && defined(__mips__) && __mips_isa_rev < 6 +#include "mips/cplx_mul.h" + +#endif /* #if defined all cores: bfin, arm, etc. */ + +/* ############################################################################# */ + +/* Fallback generic implementations */ + +#if !defined(FUNCTION_cplxMultDiv2_32x16X2) +#define FUNCTION_cplxMultDiv2_32x16X2 + +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + *c_Re = fMultDiv2(a_Re,b_Re) - fMultDiv2(a_Im,b_Im); + *c_Im = fMultDiv2(a_Re,b_Im) + fMultDiv2(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMultDiv2_32x16) +#define FUNCTION_cplxMultDiv2_32x16 + +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SPK w ) +{ + cplxMultDiv2(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im); +} +#endif + +#if !defined(FUNCTION_cplxMultAddDiv2_32x16X2) +#define FUNCTION_cplxMultAddDiv2_32x16X2 + +inline void cplxMultAddDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + *c_Re += fMultDiv2(a_Re,b_Re) - fMultDiv2(a_Im,b_Im); + *c_Im += fMultDiv2(a_Re,b_Im) + fMultDiv2(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMultSubDiv2_32x16X2) +#define FUNCTION_cplxMultSubDiv2_32x16X2 + +inline void cplxMultSubDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + *c_Re -= fMultDiv2(a_Re,b_Re) - fMultDiv2(a_Im,b_Im); + *c_Im -= fMultDiv2(a_Re,b_Im) + fMultDiv2(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMultDiv2_32x32X2) +#define FUNCTION_cplxMultDiv2_32x32X2 + +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DBL b_Re, + const FIXP_DBL b_Im) +{ + *c_Re = fMultDiv2(a_Re,b_Re) - fMultDiv2(a_Im,b_Im); + *c_Im = fMultDiv2(a_Re,b_Im) + fMultDiv2(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMultDiv2_32x32) +#define FUNCTION_cplxMultDiv2_32x32 + +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DPK w) +{ + cplxMultDiv2(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im); +} +#endif + +#if !defined(FUNCTION_cplxMultSubDiv2_32x32X2) +#define FUNCTION_cplxMultSubDiv2_32x32X2 + +inline void cplxMultSubDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DBL b_Re, + const FIXP_DBL b_Im) +{ + *c_Re -= fMultDiv2(a_Re,b_Re) - fMultDiv2(a_Im,b_Im); + *c_Im -= fMultDiv2(a_Re,b_Im) + fMultDiv2(a_Im,b_Re); +} +#endif + +/* ############################################################################# */ + +#if !defined(FUNCTION_cplxMult_32x16X2) +#define FUNCTION_cplxMult_32x16X2 + +inline void cplxMult( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + *c_Re = fMult(a_Re,b_Re) - fMult(a_Im,b_Im); + *c_Im = fMult(a_Re,b_Im) + fMult(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMult_32x16) +#define FUNCTION_cplxMult_32x16 + +inline void cplxMult( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SPK w ) +{ + cplxMult(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im); +} +#endif + +#if !defined(FUNCTION_cplxMult_32x32X2) +#define FUNCTION_cplxMult_32x32X2 + +inline void cplxMult( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DBL b_Re, + const FIXP_DBL b_Im) +{ + *c_Re = fMult(a_Re,b_Re) - fMult(a_Im,b_Im); + *c_Im = fMult(a_Re,b_Im) + fMult(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMult_32x32) +#define FUNCTION_cplxMult_32x32 +inline void cplxMult( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DPK w) +{ + cplxMult(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im); +} +#endif + +/* ############################################################################# */ + +#endif /* __CPLX_Mult_H__ */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/dct.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/dct.h new file mode 100644 index 0000000..c9cd0d6 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/dct.h @@ -0,0 +1,147 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: Library functions to calculate standard DCTs. This will most + likely be replaced by hand-optimized functions for the specific + target processor. + +******************************************************************************/ + +#ifndef __dct_H +#define __dct_H + + + +#include "common_fix.h" + +/** + * \brief Calculate DCT type II of given length. The DCT IV is + * calculated by a complex FFT, with some pre and post twiddeling. + * A factor of sqrt(2/(N-1)) is NOT applied. + * \param pDat pointer to input/output data (in place processing). + * \param size size of pDat. + * \param pDat_e pointer to an integer containing the exponent of the data + * referenced by pDat. The exponent is updated accordingly. + */ +void dct_II(FIXP_DBL *pDat, FIXP_DBL *tmp, int size, int *pDat_e); + +/** + * \brief Calculate DCT type III of given length. The DCT IV is + * calculated by a complex FFT, with some pre and post twiddeling. + * Note that the factor 0.5 for the sum term x[0] is 1.0 instead of 0.5. + * A factor of sqrt(2/N) is NOT applied. + * \param pDat pointer to input/output data (in place processing). + * \param size size of pDat. + * \param pDat_e pointer to an integer containing the exponent of the data + * referenced by pDat. The exponent is updated accordingly. + */ +void dct_III(FIXP_DBL *pDat, FIXP_DBL *tmp, int size, int *pDat_e); + +/** + * \brief Calculate DCT type IV of given length. The DCT IV is + * calculated by a complex FFT, with some pre and post twiddeling. + * A factor of sqrt(2/N) is NOT applied. + * \param pDat pointer to input/output data (in place processing). + * \param size size of pDat. + * \param pDat_e pointer to an integer containing the exponent of the data + * referenced by pDat. The exponent is updated accordingly. + */ +void dct_IV(FIXP_DBL *pDat,int size, int *pDat_e); + +/** + * \brief Calculate DST type IV of given length. The DST IV is + * calculated by a complex FFT, with some pre and post twiddeling. + * A factor of sqrt(2/N) is NOT applied. + * \param pDat pointer to input/output data (in place processing). + * \param size size of pDat. + * \param pDat_e pointer to an integer containing the exponent of the data + * referenced by pDat. The exponent is updated accordingly. + */ +void dst_IV(FIXP_DBL *pDat,int size, int *pDat_e); + + + +#endif diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fft.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fft.h new file mode 100644 index 0000000..c0890af --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fft.h @@ -0,0 +1,253 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): Josef Hoepfl, DSP Solutions + Description: Fix point FFT + +******************************************************************************/ + +#ifndef __FFT_H__ +#define __FFT_H__ + +#include "common_fix.h" + +/** + * \brief Perform an inplace complex valued FFT of length 2^n + * + * \param length Length of the FFT to be calculated. + * \param pInput Input/Output data buffer. The input data must have at least 1 bit scale headroom. + * The values are interleaved, real/imag pairs. + * \param scalefactor Pointer to an INT, which contains the current scale of the input data, + * which is updated according to the FFT scale. + */ +void fft(int length, FIXP_DBL *pInput, INT *scalefactor); + +/** + * \brief Perform an inplace complex valued IFFT of length 2^n + * + * \param length Length of the FFT to be calculated. + * \param pInput Input/Output data buffer. The input data must have at least 1 bit scale headroom. + * The values are interleaved, real/imag pairs. + * \param scalefactor Pointer to an INT, which contains the current scale of the input data, + * which is updated according to the IFFT scale. + */ +void ifft(int length, FIXP_DBL *pInput, INT *scalefactor); + + +/* + * Frequently used and fixed short length FFTs. + */ + +LNK_SECTION_CODE_L1 +static FORCEINLINE void fft_4(FIXP_DBL *x) +{ + FIXP_DBL a00, a10, a20, a30, tmp0, tmp1; + + a00 = (x[0] + x[4])>>1; /* Re A + Re B */ + a10 = (x[2] + x[6])>>1; /* Re C + Re D */ + a20 = (x[1] + x[5])>>1; /* Im A + Im B */ + a30 = (x[3] + x[7])>>1; /* Im C + Im D */ + + x[0] = a00 + a10; /* Re A' = Re A + Re B + Re C + Re D */ + x[1] = a20 + a30; /* Im A' = Im A + Im B + Im C + Im D */ + + tmp0 = a00 - x[4]; /* Re A - Re B */ + tmp1 = a20 - x[5]; /* Im A - Im B */ + + x[4] = a00 - a10; /* Re C' = Re A + Re B - Re C - Re D */ + x[5] = a20 - a30; /* Im C' = Im A + Im B - Im C - Im D */ + + a10 = a10 - x[6]; /* Re C - Re D */ + a30 = a30 - x[7]; /* Im C - Im D */ + + x[2] = tmp0 + a30; /* Re B' = Re A - Re B + Im C - Im D */ + x[6] = tmp0 - a30; /* Re D' = Re A - Re B - Im C + Im D */ + x[3] = tmp1 - a10; /* Im B' = Im A - Im B - Re C + Re D */ + x[7] = tmp1 + a10; /* Im D' = Im A - Im B + Re C - Re D */ +} + +LNK_SECTION_CODE_L1 +static FORCEINLINE void fft_8(FIXP_DBL *x) +{ + #define W_PiFOURTH STC(0x5a82799a) + + FIXP_DBL a00, a10, a20, a30; + FIXP_DBL y[16]; + + a00 = (x[0] + x[8])>>1; + a10 = x[4] + x[12]; + a20 = (x[1] + x[9])>>1; + a30 = x[5] + x[13]; + + y[0] = a00 + (a10>>1); + y[4] = a00 - (a10>>1); + y[1] = a20 + (a30>>1); + y[5] = a20 - (a30>>1); + + a00 = a00 - x[8]; + a10 = (a10>>1) - x[12]; + a20 = a20 - x[9]; + a30 = (a30>>1) - x[13]; + + y[2] = a00 + a30; + y[6] = a00 - a30; + y[3] = a20 - a10; + y[7] = a20 + a10; + + a00 = (x[2] + x[10])>>1; + a10 = x[6] + x[14]; + a20 = (x[3] + x[11])>>1; + a30 = x[7] + x[15]; + + y[8] = a00 + (a10>>1); + y[12] = a00 - (a10>>1); + y[9] = a20 + (a30>>1); + y[13] = a20 - (a30>>1); + + a00 = a00 - x[10]; + a10 = (a10>>1) - x[14]; + a20 = a20 - x[11]; + a30 = (a30>>1) - x[15]; + + y[10] = a00 + a30; + y[14] = a00 - a30; + y[11] = a20 - a10; + y[15] = a20 + a10; + + FIXP_DBL vr, vi, ur, ui; + + ur = y[0]>>1; + ui = y[1]>>1; + vr = y[8]; + vi = y[9]; + x[0] = ur + (vr>>1); + x[1] = ui + (vi>>1); + x[8] = ur - (vr>>1); + x[9] = ui - (vi>>1); + + ur = y[4]>>1; + ui = y[5]>>1; + vi = y[12]; + vr = y[13]; + x[4] = ur + (vr>>1); + x[5] = ui - (vi>>1); + x[12] = ur - (vr>>1); + x[13] = ui + (vi>>1); + + ur = y[10]; + ui = y[11]; + vr = fMultDiv2(ui+ur,W_PiFOURTH); + vi = fMultDiv2(ui-ur,W_PiFOURTH); + ur = y[2]; + ui = y[3]; + x[2] = (ur>>1) + vr; + x[3] = (ui>>1) + vi; + x[10] = (ur>>1) - vr; + x[11] = (ui>>1) - vi; + + ur = y[14]; + ui = y[15]; + vr = fMultDiv2(ui-ur,W_PiFOURTH); + vi = fMultDiv2(ui+ur,W_PiFOURTH); + ur = y[6]; + ui = y[7]; + x[6] = (ur>>1) + vr; + x[7] = (ui>>1) - vi; + x[14] = (ur>>1) - vr; + x[15] = (ui>>1) + vi; +} + +/** + * \brief FFT of fixed length 16 + */ +inline void fft_16(FIXP_DBL *x); + +/** + * \brief FFT of fixed length 32 + */ +inline void fft_32(FIXP_DBL *x); + + +#endif diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fft_rad2.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fft_rad2.h new file mode 100644 index 0000000..3e1c6e6 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fft_rad2.h @@ -0,0 +1,134 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): M. Lohwasser, M. Gayer + Description: + +******************************************************************************/ + +#ifndef _FFT_RAD2_H +#define _FFT_RAD2_H + + +#include "common_fix.h" + +/** + * \brief Performe an inplace complex valued FFT of 2^n length + * + * \param x Input/Output data buffer. The input data must have at least 1 bit scale headroom. + * The values are interleaved, real/imag pairs. + * \param ldn log2 of FFT length + * \param trigdata Pointer to a sinetable of a length of at least (2^ldn)/2 sine values. + * \param trigDataSize length of the sinetable "trigdata". + */ +void dit_fft(FIXP_DBL *x, const INT ldn, const FIXP_STP *trigdata, const INT trigDataSize) ; + +/** + * \brief Performe an inplace complex valued inverse FFT of 2^n length + * + * \param x Input/Output data buffer. The input data must have at least 1 bit scale headroom. + * The values are interleaved, real/imag pairs. + * \param ldn log2 of FFT length + * \param trigdata Pointer to a sinetable of a length of at least (2^ldn)/2 sine values. + * \param trigDataSize length of the sinetable "trigdata". + */ +void dit_ifft(FIXP_DBL *x, const INT ldn, const FIXP_STP *trigdata, const INT trigDataSize) ; + +/* Rest of the world. */ + +#define SCALEFACTOR2048 10 +#define SCALEFACTOR1024 9 +#define SCALEFACTOR512 8 +#define SCALEFACTOR256 7 +#define SCALEFACTOR128 6 +#define SCALEFACTOR64 5 +#define SCALEFACTOR32 4 +#define SCALEFACTOR16 3 +#define SCALEFACTOR8 2 +#define SCALEFACTOR4 1 +#define SCALEFACTOR2 1 + +#endif /* _FFT_RAD2_H */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixmadd.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixmadd.h new file mode 100644 index 0000000..9a6494c --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixmadd.h @@ -0,0 +1,306 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): M. Lohwasser, M. Gayer + Description: fixed point intrinsics + +******************************************************************************/ + +#if !defined(__FIXMADD_H__) +#define __FIXMADD_H__ + +#include "FDK_archdef.h" +#include "machine_type.h" +#include "fixmul.h" + +#if defined(__arm__) +#include "arm/fixmadd_arm.h" + +#elif defined(__mips__) /* cppp replaced: elif */ +#include "mips/fixmadd_mips.h" + +#endif /* all cores */ + +/************************************************************************* + ************************************************************************* + Software fallbacks for missing functions. +************************************************************************** +**************************************************************************/ + +/* Divide by two versions. */ + +#if !defined(FUNCTION_fixmadddiv2_DD) +inline FIXP_DBL fixmadddiv2_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) + { return (x + fMultDiv2 (a, b)); } +#endif + +#if !defined(FUNCTION_fixmadddiv2_SD) +inline FIXP_DBL fixmadddiv2_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmadddiv2_DS + return fixmadddiv2_DS(x, b, a); +#else + return fixmadddiv2_DD(x, FX_SGL2FX_DBL(a), b); +#endif +} +#endif + +#if !defined(FUNCTION_fixmadddiv2_DS) +inline FIXP_DBL fixmadddiv2_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmadddiv2_SD + return fixmadddiv2_SD(x, b, a); +#else + return fixmadddiv2_DD(x, a, FX_SGL2FX_DBL(b)); +#endif +} +#endif + +#if !defined(FUNCTION_fixmadddiv2_SS) +inline FIXP_DBL fixmadddiv2_SS (FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) + { return x + fMultDiv2(a,b); } +#endif + +#if !defined(FUNCTION_fixmsubdiv2_DD) +inline FIXP_DBL fixmsubdiv2_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) + { return (x - fMultDiv2 (a, b)); } +#endif + +#if !defined(FUNCTION_fixmsubdiv2_SD) +inline FIXP_DBL fixmsubdiv2_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmsubdiv2_DS + return fixmsubdiv2_DS(x, b, a); +#else + return fixmsubdiv2_DD(x, FX_SGL2FX_DBL(a), b); +#endif +} +#endif + +#if !defined(FUNCTION_fixmsubdiv2_DS) +inline FIXP_DBL fixmsubdiv2_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmsubdiv2_SD + return fixmsubdiv2_SD(x, b, a); +#else + return fixmsubdiv2_DD(x, a, FX_SGL2FX_DBL(b)); +#endif +} +#endif + +#if !defined(FUNCTION_fixmsubdiv2_SS) +inline FIXP_DBL fixmsubdiv2_SS (FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) + { return x - fMultDiv2(a,b); } +#endif + + +#if !defined(FUNCTION_fixmadddiv2BitExact_DD) +#define FUNCTION_fixmadddiv2BitExact_DD +inline FIXP_DBL fixmadddiv2BitExact_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + return x + fMultDiv2BitExact(a, b); +} +#endif +#if !defined(FUNCTION_fixmadddiv2BitExact_SD) +#define FUNCTION_fixmadddiv2BitExact_SD +inline FIXP_DBL fixmadddiv2BitExact_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmadddiv2BitExact_DS + return fixmadddiv2BitExact_DS(x, b, a); +#else + return x + fMultDiv2BitExact(a, b); +#endif +} +#endif +#if !defined(FUNCTION_fixmadddiv2BitExact_DS) +#define FUNCTION_fixmadddiv2BitExact_DS +inline FIXP_DBL fixmadddiv2BitExact_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmadddiv2BitExact_SD + return fixmadddiv2BitExact_SD(x, b, a); +#else + return x + fMultDiv2BitExact(a, b); +#endif +} +#endif + +#if !defined(FUNCTION_fixmsubdiv2BitExact_DD) +#define FUNCTION_fixmsubdiv2BitExact_DD +inline FIXP_DBL fixmsubdiv2BitExact_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + return x - fMultDiv2BitExact(a, b); +} +#endif +#if !defined(FUNCTION_fixmsubdiv2BitExact_SD) +#define FUNCTION_fixmsubdiv2BitExact_SD +inline FIXP_DBL fixmsubdiv2BitExact_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmsubdiv2BitExact_DS + return fixmsubdiv2BitExact_DS(x, b, a); +#else + return x - fMultDiv2BitExact(a, b); +#endif +} +#endif +#if !defined(FUNCTION_fixmsubdiv2BitExact_DS) +#define FUNCTION_fixmsubdiv2BitExact_DS +inline FIXP_DBL fixmsubdiv2BitExact_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmsubdiv2BitExact_SD + return fixmsubdiv2BitExact_SD(x, b, a); +#else + return x - fMultDiv2BitExact(a, b); +#endif +} +#endif + +/* Normal versions */ + +#if !defined(FUNCTION_fixmadd_DD) +inline FIXP_DBL fixmadd_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) + { return fixmadddiv2_DD(x,a,b)<<1; } +#endif +#if !defined(FUNCTION_fixmadd_SD) +inline FIXP_DBL fixmadd_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmadd_DS + return fixmadd_DS(x, b, a); +#else + return fixmadd_DD(x, FX_SGL2FX_DBL(a), b); +#endif +} +#endif +#if !defined(FUNCTION_fixmadd_DS) +inline FIXP_DBL fixmadd_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmadd_SD + return fixmadd_SD(x, b, a); +#else + return fixmadd_DD(x, a, FX_SGL2FX_DBL(b)); +#endif +} +#endif +#if !defined(FUNCTION_fixmadd_SS) +inline FIXP_DBL fixmadd_SS (FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) + { return (x + fMultDiv2(a,b))<<1; } +#endif + +#if !defined(FUNCTION_fixmsub_DD) +inline FIXP_DBL fixmsub_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) + { return fixmsubdiv2_DD(x,a,b)<<1; } +#endif +#if !defined(FUNCTION_fixmsub_SD) +inline FIXP_DBL fixmsub_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmsub_DS + return fixmsub_DS(x, b, a); +#else + return fixmsub_DD(x, FX_SGL2FX_DBL(a), b); +#endif +} +#endif +#if !defined(FUNCTION_fixmsub_DS) +inline FIXP_DBL fixmsub_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmsub_SD + return fixmsub_SD(x, b, a); +#else + return fixmsub_DD(x, a, FX_SGL2FX_DBL(b)); +#endif +} +#endif +#if !defined(FUNCTION_fixmsub_SS) +inline FIXP_DBL fixmsub_SS (FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) + { return (x - fMultDiv2(a,b))<<1; } +#endif + +#if !defined(FUNCTION_fixpow2adddiv2_D) +inline INT fixpadddiv2_D (FIXP_DBL x, const FIXP_DBL a) + { return (x + fPow2Div2(a)); } +#endif +#if !defined(FUNCTION_fixpow2add_D) +inline INT fixpadd_D (FIXP_DBL x, const FIXP_DBL a) + { return (x + fPow2(a)); } +#endif + +#if !defined(FUNCTION_fixpow2adddiv2_S) +inline INT fixpadddiv2_S (FIXP_DBL x, const FIXP_SGL a) + { return (x + fPow2Div2(a)); } +#endif +#if !defined(FUNCTION_fixpow2add_S) +inline INT fixpadd_S (FIXP_DBL x, const FIXP_SGL a) + { return (x + fPow2(a)); } +#endif + + + +#endif // __FIXMADD_H__ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixminmax.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixminmax.h new file mode 100644 index 0000000..076f67d --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixminmax.h @@ -0,0 +1,120 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): M. Lohwasser, M. Gayer + Description: min/max inline functions and defines + +******************************************************************************/ + +#ifndef FIXMINMAX__H +#define FIXMINMAX__H + +#include "FDK_archdef.h" +#include "machine_type.h" + +/* Inline Function to determine the smaller/bigger value of two values with same type. */ + + +template inline T fixmin (T a, T b) +{ + return (a < b ? a : b); +} + +template inline T fixmax (T a, T b) +{ + return (a > b ? a : b); +} + +#define fixmax_D(a,b) fixmax(a,b) +#define fixmin_D(a,b) fixmin(a,b) +#define fixmax_S(a,b) fixmax(a,b) +#define fixmin_S(a,b) fixmin(a,b) +#define fixmax_I(a,b) fixmax(a,b) +#define fixmin_I(a,b) fixmin(a,b) +#define fixmax_UI(a,b) fixmax(a,b) +#define fixmin_UI(a,b) fixmin(a,b) + + +#endif diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixmul.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixmul.h new file mode 100644 index 0000000..17dba13 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixmul.h @@ -0,0 +1,292 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): Stefan Gewinner + Description: fixed point multiplication + +******************************************************************************/ + +#if !defined(__FIXMUL_H__) +#define __FIXMUL_H__ + +#include "FDK_archdef.h" +#include "machine_type.h" + + +#if defined(__arm__) +#include "arm/fixmul_arm.h" + +#elif defined(__aarch64__) || defined(__AARCH64EL__) +#include "aarch64/fixmul_aarch64.h" + +#elif defined(__mips__) /* cppp replaced: elif */ +#include "mips/fixmul_mips.h" + +#elif defined(__x86__) /* cppp replaced: elif */ +#include "x86/fixmul_x86.h" + +#elif defined(__powerpc__) +#include "ppc/fixmul_ppc.h" + +#endif /* all cores */ + +/************************************************************************* + ************************************************************************* + Software fallbacks for missing functions +************************************************************************** +**************************************************************************/ + +#if !defined(FUNCTION_fixmuldiv2_DD) +#define FUNCTION_fixmuldiv2_DD +#if defined(_MSC_VER) || defined(__CC_ARM) || defined(__ANALOG_EXTENSIONS__) || defined(__TI_COMPILER_VERSION__) +#pragma message ("Extremely slow implementation of fixmuldiv2_DD !!") +#else +#warning Extremely slow implementation of fixmuldiv2_DD !! +#endif +inline LONG fixmuldiv2_DD (const LONG a, const LONG b) +{ + return (LONG) ((((INT64)a) * b) >> 32) ; +} +#endif + +#if !defined(FUNCTION_fixmuldiv2BitExact_DD) +#define FUNCTION_fixmuldiv2BitExact_DD +#if defined(_MSC_VER) || defined(__CC_ARM) || defined(__ANALOG_EXTENSIONS__) || defined(__TI_COMPILER_VERSION__) +#pragma message ("Extremely slow implementation of fixmuldiv2BitExact_DD !!") +#else +#warning Extremely slow implementation of fixmuldiv2BitExact_DD !! +#endif +inline LONG fixmuldiv2BitExact_DD (const LONG a, const LONG b) +{ + return (LONG) ((((INT64)a) * b) >> 32) ; +} +#endif + +#if !defined(FUNCTION_fixmul_DD) +#define FUNCTION_fixmul_DD +inline LONG fixmul_DD (const LONG a, const LONG b) + { return fixmuldiv2_DD (a, b) << 1 ; } +#endif + +#if !defined(FUNCTION_fixmulBitExact_DD) +#define FUNCTION_fixmulBitExact_DD +#if defined(_MSC_VER) || defined(__CC_ARM) || defined(__ANALOG_EXTENSIONS__) || defined(__TI_COMPILER_VERSION__) || defined(__XTENSA__) +#pragma message ("Extremely slow implementation of fixmulBitExact_DD !!") +#else +#warning Extremely slow implementation of fixmulBitExact_DD !! +#endif +inline LONG fixmulBitExact_DD (const LONG a, const LONG b) +{ + return ( (LONG) ((((INT64)a) * b) >> 32) ) << 1; +} +#endif + +#if !defined(FUNCTION_fixmuldiv2_SS) +#define FUNCTION_fixmuldiv2_SS +inline LONG fixmuldiv2_SS (const SHORT a, const SHORT b) + { return ((LONG)a*b); } +#endif + +#if !defined(FUNCTION_fixmul_SS) +#define FUNCTION_fixmul_SS +inline LONG fixmul_SS (const SHORT a, const SHORT b) + { return (a*b) <<1; } +#endif + +#if !defined(FUNCTION_fixmuldiv2_SD) +#define FUNCTION_fixmuldiv2_SD +inline LONG fixmuldiv2_SD (const SHORT a, const LONG b) +#ifdef FUNCTION_fixmuldiv2_DS + { return fixmuldiv2_DS(b, a); } +#else + { return fixmuldiv2_DD(FX_SGL2FX_DBL(a), b); } +#endif +#endif + +#if !defined(FUNCTION_fixmuldiv2_DS) +#define FUNCTION_fixmuldiv2_DS +inline LONG fixmuldiv2_DS (const LONG a, const SHORT b) +#ifdef FUNCTION_fixmuldiv2_SD + { return fixmuldiv2_SD(b, a); } +#else + { return fixmuldiv2_DD(a, FX_SGL2FX_DBL(b)); } +#endif +#endif + +#if !defined(FUNCTION_fixmuldiv2BitExact_SD) +#define FUNCTION_fixmuldiv2BitExact_SD +inline LONG fixmuldiv2BitExact_SD (const SHORT a, const LONG b) +#ifdef FUNCTION_fixmuldiv2BitExact_DS + { return fixmuldiv2BitExact_DS(b, a); } +#else + { return (LONG) ((((INT64)a) * b) >> 16) ; } +#endif +#endif + +#if !defined(FUNCTION_fixmuldiv2BitExact_DS) +#define FUNCTION_fixmuldiv2BitExact_DS +inline LONG fixmuldiv2BitExact_DS (const LONG a, const SHORT b) +#ifdef FUNCTION_fixmuldiv2BitExact_SD + { return fixmuldiv2BitExact_SD(b, a); } +#else + { return (LONG) ((((INT64)a) * b) >> 16) ; } +#endif +#endif + +#if !defined(FUNCTION_fixmul_SD) +#define FUNCTION_fixmul_SD +inline LONG fixmul_SD (const SHORT a, const LONG b) { +#ifdef FUNCTION_fixmul_DS + return fixmul_SD(b, a); +#else + return fixmuldiv2_SD (a, b) << 1 ; +#endif +} +#endif + +#if !defined(FUNCTION_fixmul_DS) +#define FUNCTION_fixmul_DS +inline LONG fixmul_DS (const LONG a, const SHORT b) { +#ifdef FUNCTION_fixmul_SD + return fixmul_SD(b, a); +#else + return fixmuldiv2_DS(a, b) << 1 ; +#endif +} +#endif + +#if !defined(FUNCTION_fixmulBitExact_SD) +#define FUNCTION_fixmulBitExact_SD +inline LONG fixmulBitExact_SD (const SHORT a, const LONG b) +#ifdef FUNCTION_fixmulBitExact_DS + { return fixmulBitExact_DS(b, a); } +#else + { return (LONG) (((((INT64)a) * b) >> 16) << 1); } +#endif +#endif + +#if !defined(FUNCTION_fixmulBitExact_DS) +#define FUNCTION_fixmulBitExact_DS +inline LONG fixmulBitExact_DS (const LONG a, const SHORT b) +#ifdef FUNCTION_fixmulBitExact_SD + { return fixmulBitExact_SD(b, a); } +#else + { return (LONG) (((((INT64)a) * b) >> 16) << 1); } +#endif +#endif + + +#if !defined(FUNCTION_fixpow2div2_D) +#ifdef ARCH_WA_16BITMULT +#error Fallback for fixpow2div2_D is not 16 bit safe ! +#endif +#define FUNCTION_fixpow2div2_D +inline LONG fixpow2div2_D (const LONG a) + { return fixmuldiv2_DD(a, a); } +#endif + +#if !defined(FUNCTION_fixpow2_D) +#ifdef ARCH_WA_16BITMULT +#error Fallback for fixpow2_D is not 16 bit safe ! +#endif +#define FUNCTION_fixpow2_D +inline LONG fixpow2_D (const LONG a) + { return fixpow2div2_D(a)<<1; } +#endif + +#if !defined(FUNCTION_fixpow2div2_S) +#define FUNCTION_fixpow2div2_S +inline LONG fixpow2div2_S (const SHORT a) + { return fixmuldiv2_SS(a, a); } +#endif + +#if !defined(FUNCTION_fixpow2_S) +#define FUNCTION_fixpow2_S +inline LONG fixpow2_S (const SHORT a) + { return fixpow2div2_S(a)<<1; } +#endif + + +#endif /* __FIXMUL_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixpoint_math.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixpoint_math.h new file mode 100644 index 0000000..510a41f --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/fixpoint_math.h @@ -0,0 +1,497 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): M. Gayer + Description: Fixed point specific mathematical functions + +******************************************************************************/ + +#ifndef __fixpoint_math_H +#define __fixpoint_math_H + + +#include "common_fix.h" + +#if !defined(FUNCTION_fIsLessThan) +/** + * \brief Compares two fixpoint values incl. scaling. + * \param a_m mantissa of the first input value. + * \param a_e exponent of the first input value. + * \param b_m mantissa of the second input value. + * \param b_e exponent of the second input value. + * \return non-zero if (a_m*2^a_e) < (b_m*2^b_e), 0 otherwise + */ +FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e) +{ + if (a_e > b_e) { + return (b_m >> fMin(a_e-b_e, DFRACT_BITS-1) > a_m); + } else { + return (a_m >> fMin(b_e-a_e, DFRACT_BITS-1) < b_m); + } +} + +FDK_INLINE INT fIsLessThan(FIXP_SGL a_m, INT a_e, FIXP_SGL b_m, INT b_e) +{ + if (a_e > b_e) { + return (b_m >> fMin(a_e-b_e, FRACT_BITS-1) > a_m); + } else { + return (a_m >> fMin(b_e-a_e, FRACT_BITS-1) < b_m); + } +} +#endif + + + +#define LD_DATA_SCALING (64.0f) +#define LD_DATA_SHIFT 6 /* pow(2, LD_DATA_SHIFT) = LD_DATA_SCALING */ + +/** + * \brief deprecated. Use fLog2() instead. + */ +FIXP_DBL CalcLdData(FIXP_DBL op); + +void LdDataVector(FIXP_DBL *srcVector, FIXP_DBL *destVector, INT number); + +FIXP_DBL CalcInvLdData(FIXP_DBL op); + + + extern const FIXP_DBL ldIntCoeff[]; +extern const FIXP_DBL invSqrtTab[]; +void InitLdInt(); +FIXP_DBL CalcLdInt(INT i); + +extern const USHORT sqrt_tab[49]; + +inline FIXP_DBL sqrtFixp_lookup(FIXP_DBL x) +{ + UINT y = (INT)x; + UCHAR is_zero=(y==0); + INT zeros=fixnormz_D(y) & 0x1e; + y<<=zeros; + UINT idx=(y>>26)-16; + USHORT frac=(y>>10)&0xffff; + USHORT nfrac=0xffff^frac; + UINT t=nfrac*sqrt_tab[idx]+frac*sqrt_tab[idx+1]; + t=t>>(zeros>>1); + return(is_zero ? 0 : t); +} + +inline FIXP_DBL sqrtFixp_lookup(FIXP_DBL x, INT *x_e) +{ + UINT y = (INT)x; + INT e; + + if (x == (FIXP_DBL)0) { + return x; + } + + /* Normalize */ + e=fixnormz_D(y); + y<<=e; + e = *x_e - e + 2; + + /* Correct odd exponent. */ + if (e & 1) { + y >>= 1; + e ++; + } + /* Get square root */ + UINT idx=(y>>26)-16; + USHORT frac=(y>>10)&0xffff; + USHORT nfrac=0xffff^frac; + UINT t=nfrac*sqrt_tab[idx]+frac*sqrt_tab[idx+1]; + + /* Write back exponent */ + *x_e = e >> 1; + return (FIXP_DBL)(LONG)(t>>1); +} + + + +FIXP_DBL sqrtFixp(FIXP_DBL op); + +void InitInvSqrtTab(); + +FIXP_DBL invSqrtNorm2(FIXP_DBL op, INT *shift); + +/***************************************************************************** + + functionname: invFixp + description: delivers 1/(op) + +*****************************************************************************/ +inline FIXP_DBL invFixp(FIXP_DBL op) +{ + INT tmp_exp ; + FIXP_DBL tmp_inv = invSqrtNorm2(op, &tmp_exp) ; + FDK_ASSERT((31-(2*tmp_exp+1))>=0) ; + return ( fPow2Div2( (FIXP_DBL)tmp_inv ) >> (31-(2*tmp_exp+1)) ) ; +} + + + +#if defined(__mips__) && (__GNUC__==2) + +#define FUNCTION_schur_div +inline FIXP_DBL schur_div(FIXP_DBL num,FIXP_DBL denum, INT count) +{ + INT result, tmp ; + __asm__ ("srl %1, %2, 15\n" + "div %3, %1\n" : "=lo" (result) + : "%d" (tmp), "d" (denum) , "d" (num) + : "hi" ) ; + return result<<16 ; +} + +/*###########################################################################################*/ +#elif defined(__mips__) && (__GNUC__==3) + +#define FUNCTION_schur_div +inline FIXP_DBL schur_div(FIXP_DBL num,FIXP_DBL denum, INT count) +{ + INT result, tmp; + + __asm__ ("srl %[tmp], %[denum], 15\n" + "div %[result], %[num], %[tmp]\n" + : [tmp] "+r" (tmp), [result]"=r"(result) + : [denum]"r"(denum), [num]"r"(num) + : "hi", "lo"); + return result << (DFRACT_BITS-16); +} + +/*###########################################################################################*/ +#elif defined(SIMULATE_MIPS_DIV) + +#define FUNCTION_schur_div +inline FIXP_DBL schur_div(FIXP_DBL num, FIXP_DBL denum, INT count) +{ + FDK_ASSERT (count<=DFRACT_BITS-1); + FDK_ASSERT (num>=(FIXP_DBL)0); + FDK_ASSERT (denum>(FIXP_DBL)0); + FDK_ASSERT (num <= denum); + + INT tmp = denum >> (count-1); + INT result = 0; + + while (num > tmp) + { + num -= tmp; + result++; + } + + return result << (DFRACT_BITS-count); +} + +/*###########################################################################################*/ +#endif /* target architecture selector */ + +#if !defined(FUNCTION_schur_div) +/** + * \brief Divide two FIXP_DBL values with given precision. + * \param num dividend + * \param denum divisor + * \param count amount of significant bits of the result (starting to the MSB) + * \return num/divisor + */ +FIXP_DBL schur_div(FIXP_DBL num,FIXP_DBL denum, INT count); +#endif + + + +FIXP_DBL mul_dbl_sgl_rnd (const FIXP_DBL op1, + const FIXP_SGL op2); + +/** + * \brief multiply two values with normalization, thus max precision. + * Author: Robert Weidner + * + * \param f1 first factor + * \param f2 secod factor + * \param result_e pointer to an INT where the exponent of the result is stored into + * \return mantissa of the product f1*f2 + */ +FIXP_DBL fMultNorm( + FIXP_DBL f1, + FIXP_DBL f2, + INT *result_e + ); + +inline FIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2) +{ + FIXP_DBL m; + INT e; + + m = fMultNorm(f1, f2, &e); + + m = scaleValueSaturate(m, e); + + return m; +} + +/** + * \brief Divide 2 FIXP_DBL values with normalization of input values. + * \param num numerator + * \param denum denomintator + * \return num/denum with exponent = 0 + */ +FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom, INT *result_e); + +/** + * \brief Divide 2 FIXP_DBL values with normalization of input values. + * \param num numerator + * \param denum denomintator + * \param result_e pointer to an INT where the exponent of the result is stored into + * \return num/denum with exponent = *result_e + */ +FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom); + +/** + * \brief Divide 2 FIXP_DBL values with normalization of input values. + * \param num numerator + * \param denum denomintator + * \return num/denum with exponent = 0 + */ +FIXP_DBL fDivNormHighPrec(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e); + +/** + * \brief Calculate log(argument)/log(2) (logarithm with base 2). deprecated. Use fLog2() instead. + * \param arg mantissa of the argument + * \param arg_e exponent of the argument + * \param result_e pointer to an INT to store the exponent of the result + * \return the mantissa of the result. + * \param + */ +FIXP_DBL CalcLog2(FIXP_DBL arg, INT arg_e, INT *result_e); + +/** + * \brief return 2 ^ (exp * 2^exp_e) + * \param exp_m mantissa of the exponent to 2.0f + * \param exp_e exponent of the exponent to 2.0f + * \param result_e pointer to a INT where the exponent of the result will be stored into + * \return mantissa of the result + */ +FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e, INT *result_e); + +/** + * \brief return 2 ^ (exp_m * 2^exp_e). This version returns only the mantissa with implicit exponent of zero. + * \param exp_m mantissa of the exponent to 2.0f + * \param exp_e exponent of the exponent to 2.0f + * \return mantissa of the result + */ +FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e); + +/** + * \brief return x ^ (exp * 2^exp_e), where log2(x) = baseLd_m * 2^(baseLd_e). This saves + * the need to compute log2() of constant values (when x is a constant). + * \param ldx_m mantissa of log2() of x. + * \param ldx_e exponent of log2() of x. + * \param exp_m mantissa of the exponent to 2.0f + * \param exp_e exponent of the exponent to 2.0f + * \param result_e pointer to a INT where the exponent of the result will be stored into + * \return mantissa of the result + */ +FIXP_DBL fLdPow( + FIXP_DBL baseLd_m, + INT baseLd_e, + FIXP_DBL exp_m, INT exp_e, + INT *result_e + ); + +/** + * \brief return x ^ (exp * 2^exp_e), where log2(x) = baseLd_m * 2^(baseLd_e). This saves + * the need to compute log2() of constant values (when x is a constant). This version + * does not return an exponent, which is implicitly 0. + * \param ldx_m mantissa of log2() of x. + * \param ldx_e exponent of log2() of x. + * \param exp_m mantissa of the exponent to 2.0f + * \param exp_e exponent of the exponent to 2.0f + * \return mantissa of the result + */ +FIXP_DBL fLdPow( + FIXP_DBL baseLd_m, INT baseLd_e, + FIXP_DBL exp_m, INT exp_e + ); + +/** + * \brief return (base * 2^base_e) ^ (exp * 2^exp_e). Use fLdPow() instead whenever possible. + * \param base_m mantissa of the base. + * \param base_e exponent of the base. + * \param exp_m mantissa of power to be calculated of the base. + * \param exp_e exponent of power to be calculated of the base. + * \param result_e pointer to a INT where the exponent of the result will be stored into. + * \return mantissa of the result. + */ +FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e, INT *result_e); + +/** + * \brief return (base * 2^base_e) ^ N + * \param base mantissa of the base + * \param base_e exponent of the base + * \param power to be calculated of the base + * \param result_e pointer to a INT where the exponent of the result will be stored into + * \return mantissa of the result + */ +FIXP_DBL fPowInt(FIXP_DBL base_m, INT base_e, INT N, INT *result_e); + +/** + * \brief calculate logarithm of base 2 of x_m * 2^(x_e) + * \param x_m mantissa of the input value. + * \param x_e exponent of the input value. + * \param pointer to an INT where the exponent of the result is returned into. + * \return mantissa of the result. + */ +FIXP_DBL fLog2(FIXP_DBL x_m, INT x_e, INT *result_e); + +/** + * \brief calculate logarithm of base 2 of x_m * 2^(x_e) + * \param x_m mantissa of the input value. + * \param x_e exponent of the input value. + * \return mantissa of the result with implicit exponent of LD_DATA_SHIFT. + */ +FIXP_DBL fLog2(FIXP_DBL x_m, INT x_e); + +/** + * \brief Add with saturation of the result. + * \param a first summand + * \param b second summand + * \return saturated sum of a and b. + */ +inline FIXP_SGL fAddSaturate(const FIXP_SGL a, const FIXP_SGL b) +{ + LONG sum; + + sum = (LONG)(SHORT)a + (LONG)(SHORT)b; + sum = fMax(fMin((INT)sum, (INT)MAXVAL_SGL), (INT)MINVAL_SGL); + return (FIXP_SGL)(SHORT)sum; +} + +/** + * \brief Add with saturation of the result. + * \param a first summand + * \param b second summand + * \return saturated sum of a and b. + */ +inline FIXP_DBL fAddSaturate(const FIXP_DBL a, const FIXP_DBL b) +{ + LONG sum; + + sum = (LONG)(a>>1) + (LONG)(b>>1); + sum = fMax(fMin((INT)sum, (INT)(MAXVAL_DBL>>1)), (INT)(MINVAL_DBL>>1)); + return (FIXP_DBL)(LONG)(sum<<1); +} + +//#define TEST_ROUNDING + + + + +/***************************************************************************** + + array for 1/n, n=1..80 + +****************************************************************************/ + + extern const FIXP_DBL invCount[80]; + + LNK_SECTION_INITCODE + inline void InitInvInt(void) {} + + +/** + * \brief Calculate the value of 1/i where i is a integer value. It supports + * input values from 1 upto 80. + * \param intValue Integer input value. + * \param FIXP_DBL representation of 1/intValue + */ +inline FIXP_DBL GetInvInt(int intValue) +{ + FDK_ASSERT((intValue > 0) && (intValue < 80)); + FDK_ASSERT(intValue<80); + return invCount[intValue]; +} + + +#endif + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mdct.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mdct.h new file mode 100644 index 0000000..84fd585 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mdct.h @@ -0,0 +1,243 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): Manuel Jander, Josef Hoepfl + Description: MDCT routines + +******************************************************************************/ + +#ifndef __MDCT_H__ +#define __MDCT_H__ + + + +#include "common_fix.h" + +#define MDCT_OUT_HEADROOM 2 /* Output additional headroom */ +#define MDCT_OUTPUT_SCALE (DFRACT_BITS-SAMPLE_BITS-MDCT_OUT_HEADROOM) +/* Refer to "Output word length" in ISO/IEC 14496-3:2008(E) 23.2.3.6 */ +#define MDCT_OUTPUT_GAIN 16 + +#if (SAMPLE_BITS == DFRACT_BITS) +#define IMDCT_SCALE(x) (INT_PCM)SATURATE_LEFT_SHIFT(x, -MDCT_OUTPUT_SCALE, SAMPLE_BITS) +#else +#define IMDCT_SCALE(x) (INT_PCM)SATURATE_RIGHT_SHIFT(x, MDCT_OUTPUT_SCALE, SAMPLE_BITS) +#endif +#define IMDCT_SCALE_DBL(x) (FIXP_DBL)(x) + +/** + * \brief MDCT persistent data + */ +typedef struct { + union { + FIXP_DBL *freq; + FIXP_DBL *time; + } overlap; /**< Pointer to overlap memory */ + + const FIXP_WTP *prev_wrs; /**< pointer to previous right window slope */ + int prev_tl; /**< previous tranform length */ + int prev_nr; /**< previous right window offset */ + int prev_fr; /**< previous right window slope length */ + int ov_offset; /**< overlap time data fill level */ + int ov_size; /**< Overlap buffer size in words */ + +} mdct_t; + +typedef mdct_t* H_MDCT; + +/** + * \brief Initialize as valid MDCT handle + * + * \param hMdct handle of an allocated MDCT handle. + * \param overlap pointer to FIXP_DBL overlap buffer. + * \param overlapBufferSize size in FIXP_DBLs of the given overlap buffer. + * \return void + */ +void mdct_init( H_MDCT hMdct, + FIXP_DBL *overlap, + INT overlapBufferSize ); + +/** + * \brief perform MDCT transform (time domain to frequency domain) with given parameters. + * + * \param hMdct handle of an allocated MDCT handle. + * \param spectrum pointer to where the resulting MDCT spectrum will be stored into. + * \param scalefactor pointer to the input scale shift value. Updated accordingly on return. + * \param input pointer to input time domain signal + * \param tl transformation length. + * \param nr right window slope offset (amount of window coefficients assumed to be 1.0) + * \param fr right overlap window slope length + * \param wrs pointer to the right side overlap window coefficients. + * \return number of input samples processed. + */ +INT mdct_block( + H_MDCT hMdct, + FIXP_DBL *spectrum, + INT *scalefactor, + INT_PCM *input, + INT tl, + INT nr, + INT fr, + const FIXP_WTB *wrs ); + + +/** + * \brief add/multiply 2/N transform gain and MPEG4 part 3 defined output gain (see definition + * of MDCT_OUTPUT_GAIN) to given mantissa factor and exponent. + * \param pGain pointer to the mantissa of a gain factor to be applied to IMDCT data. + * \param pExponent pointer to the exponent of a gain factor to be applied to IMDCT data. + * \param tl length of the IMDCT where the gain *pGain * (2 ^ *pExponent) will be applied to. + */ +void imdct_gain( + FIXP_DBL *pGain, + int *pExponent, + int tl + ); + +/** + * \brief drain buffered output samples into given buffer. Changes the MDCT state. + */ +INT imdct_drain( + H_MDCT hMdct, + FIXP_DBL * pTimeData, + INT nrSamplesRoom + ); + + +/** + * \brief Copy overlap time domain data to given buffer. Does not change the MDCT state. + * \return number of actually copied samples (ov + nr). + */ +INT imdct_copy_ov_and_nr( + H_MDCT hMdct, + FIXP_DBL * pTimeData, + INT nrSamples + ); + +/** + * \brief Adapt MDCT parameters for non-matching window slopes. + * \param hMdct handle of an allocated MDCT handle. + * \param pfl pointer to left overlap window side length. + * \param pnl pointer to length of the left n part of the window. + * \param tl transform length. + * \param wls pointer to the left side overlap window coefficients. + * \param noOutSamples desired number of output samples. + */ +void imdct_adapt_parameters(H_MDCT hMdct, int *pfl, int *pnl, int tl, const FIXP_WTP *wls, int noOutSamples); + +/** + * \brief perform several inverse MDCT transforms (frequency domain to time domain) with given parameters. + * + * \param hMdct handle of an allocated MDCT handle. + * \param output pointer to where the output time domain signal will be stored into. + * \param stride the stride factor for accessing time domain samples in output. + * \param spectrum pointer to the input MDCT spectra. + * \param scalefactors scale shift values of the input spectrum. + * \param nSpec number of MDCT spectrums. + * \param noOutSamples desired number of output samples. + * \param tl transform length. + * \param wls pointer to the left side overlap window coefficients. + * \param fl left overlap window side length. + * \param wrs pointer to the right side overlap window coefficients of all individual IMDCTs. + * \param fr right overlap window side length of all individual IMDCTs. + * \param gain factor to apply to output samples (if != 0). + * \return number of output samples returned. + */ +INT imdct_block( + H_MDCT hMdct, + FIXP_DBL *output, + FIXP_DBL *spectrum, + const SHORT scalefactor[], + const INT nSpec, + const INT noOutSamples, + const INT tl, + const FIXP_WTP *wls, + INT fl, + const FIXP_WTP *wrs, + const INT fr, + FIXP_DBL gain ); + + +#endif /* __MDCT_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/abs_mips.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/abs_mips.h new file mode 100644 index 0000000..5ed2584 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/abs_mips.h @@ -0,0 +1,107 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__mips__) + +#if defined(__GNUC__) && defined(__mips__) + + #if defined(__mips_dsp) + #define FUNCTION_fixabs_D + #define FUNCTION_fixabs_I + #define FUNCTION_fixabs_S + inline FIXP_DBL fixabs_D(FIXP_DBL x) { return __builtin_mips_absq_s_w(x); } + inline FIXP_SGL fixabs_S(FIXP_SGL x) { return ((x) > (FIXP_SGL)(0)) ? (x) : -(x) ; } + inline INT fixabs_I(INT x) { return __builtin_mips_absq_s_w(x); } + #endif /* __mips_dsp */ + +#endif /* defined(__GNUC__) && defined(__mips__) */ + +#endif /*__mips__ */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/clz_mips.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/clz_mips.h new file mode 100644 index 0000000..4b57e37 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/clz_mips.h @@ -0,0 +1,118 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__mips__) + +#if defined(__mips__) && (__GNUC__==2) && (mips>=32) + + #define FUNCTION_fixnormz_D + inline INT fixnormz_D(LONG value) + { + INT result; + __asm__ ("clz %0,%1" : "=d" (result) : "d" (value)); + + return result; + } + +#elif defined(__mips__) && (__GNUC__==3) && (__mips>=32) + + #define FUNCTION_fixnormz_D + INT inline fixnormz_D(LONG value) + { + INT result; + __asm__ ("clz %[result], %[value]" : [result] "=r" (result) : [value] "r" (value)) ; + + return result; + } + +#endif + +#endif /* __mips__ */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/cplx_mul.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/cplx_mul.h new file mode 100644 index 0000000..b83559f --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/cplx_mul.h @@ -0,0 +1,129 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + + +#if defined(__GNUC__) && defined(__mips__) + + +//#define FUNCTION_cplxMultDiv2_32x16 +//#define FUNCTION_cplxMultDiv2_32x16X2 +#define FUNCTION_cplxMultDiv2_32x32X2 +//#define FUNCTION_cplxMult_32x16 +//#define FUNCTION_cplxMult_32x16X2 +#define FUNCTION_cplxMult_32x32X2 + +#if defined(FUNCTION_cplxMultDiv2_32x32X2) +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + FIXP_DBL a_Re, + FIXP_DBL a_Im, + FIXP_DBL b_Re, + FIXP_DBL b_Im) +{ + *c_Re = (((long long)a_Re * (long long)b_Re) - ((long long)a_Im * (long long)b_Im))>>32; + *c_Im = (((long long)a_Re * (long long)b_Im) + ((long long)a_Im * (long long)b_Re))>>32; +} +#endif + +#if defined(FUNCTION_cplxMult_32x32X2) +inline void cplxMult( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + FIXP_DBL a_Re, + FIXP_DBL a_Im, + FIXP_DBL b_Re, + FIXP_DBL b_Im) +{ + *c_Re = ((((long long)a_Re * (long long)b_Re) - ((long long)a_Im * (long long)b_Im))>>32)<<1; + *c_Im = ((((long long)a_Re * (long long)b_Im) + ((long long)a_Im * (long long)b_Re))>>32)<<1; +} +#endif + +#endif /* defined(__GNUC__) && defined(__mips__) */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/fixmadd_mips.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/fixmadd_mips.h new file mode 100644 index 0000000..561d346 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/fixmadd_mips.h @@ -0,0 +1,95 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__mips__) + + +#endif /* __mips__ */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/fixmul_mips.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/fixmul_mips.h new file mode 100644 index 0000000..3846007 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/fixmul_mips.h @@ -0,0 +1,113 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__mips__) + +#if (__GNUC__) && defined(__mips__) /* cppp replaced: elif */ +/* MIPS GCC based compiler */ + +#define FUNCTION_fixmuldiv2_DD + +#define FUNCTION_fixmuldiv2BitExact_DD +#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b) + +inline INT fixmuldiv2_DD (const INT a, const INT b) +{ + INT result ; + result = ((long long)a * b)>>32; + return result ; +} + +#endif /* (__GNUC__) && defined(__mips__) */ + +#endif /* __mips__ */ + +#define FUNCTION_fixmulBitExact_DD +#define fixmulBitExact_DD fixmul_DD diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/scale.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/scale.h new file mode 100644 index 0000000..fd7aef4 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/scale.h @@ -0,0 +1,110 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: + +******************************************************************************/ + +#ifndef MIPS_SCALE_H +#define MIPS_SCALE_H + +#if defined(__mips_dsp) + +/*! +* +* \brief Scale input value by 2^{scale} and saturate output to 2^{dBits-1} +* \return scaled and saturated value +* +* This macro scales src value right or left and applies saturation to (2^dBits)-1 +* maxima output. +*/ +#define SATURATE_RIGHT_SHIFT(src, scale, dBits) \ + (__builtin_mips_shll_s_w((src)>>scale,(DFRACT_BITS-(dBits)))>>(DFRACT_BITS-(dBits))) + + +#endif /*__mips_dsp */ + +#endif /* MIPS_SCALE_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/scramble.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/scramble.h new file mode 100644 index 0000000..6237ca1 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/mips/scramble.h @@ -0,0 +1,121 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: + +******************************************************************************/ + +#ifndef MIPS_SCRAMBLE_H +#define MIPS_SCRAMBLE_H + +#define FUNCTION_scramble + +#if defined(FUNCTION_scramble) +inline void scramble(FIXP_DBL *x, INT n) { + INT m,j; + int ldn=1; + do {ldn++;} while((1<> (16-ldn); + + if (j>m) + { + FIXP_DBL tmp; + tmp=x[2*m]; + x[2*m]=x[2*j]; + x[2*j]=tmp; + + tmp=x[2*m+1]; + x[2*m+1]=x[2*j+1]; + x[2*j+1]=tmp; + } + } +} +#endif + +#endif /* MIPS_SCRAMBLE_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/ppc/clz_ppc.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/ppc/clz_ppc.h new file mode 100644 index 0000000..b0755c2 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/ppc/clz_ppc.h @@ -0,0 +1,102 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__powerpc__) && (defined(__GNUC__) || defined(__xlC__)) + +#define FUNCTION_fixnormz_D + +inline INT fixnormz_D(LONG value) +{ + INT result; + __asm__ ("cntlzw %0, %1" : "=r" (result) : "r" (value)); + return result; +} + +#endif /* __powerpc__ && (__GNUC__ || __xlC__) */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/ppc/fixmul_ppc.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/ppc/fixmul_ppc.h new file mode 100644 index 0000000..0f0b5d2 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/ppc/fixmul_ppc.h @@ -0,0 +1,115 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__powerpc__) && (defined(__GNUC__) || defined(__xlC__)) + +#define FUNCTION_fixmuldiv2_DD + +#define FUNCTION_fixmuldiv2BitExact_DD +#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b) + +#define FUNCTION_fixmulBitExact_DD +#define fixmulBitExact_DD(a,b) fixmul_DD(a,b) + +#define FUNCTION_fixmuldiv2BitExact_DS +#define fixmuldiv2BitExact_DS(a,b) fixmuldiv2_DS(a,b) + +#define FUNCTION_fixmulBitExact_DS +#define fixmulBitExact_DS(a,b) fixmul_DS(a,b) + + +inline INT fixmuldiv2_DD (const INT a, const INT b) +{ + INT result; + __asm__ ("mulhw %0, %1, %2" : "=r" (result) : "r" (a), "r" (b)); + return result; +} + +#endif /* __powerpc__ && (__GNUC__ || __xlC__) */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/qmf.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/qmf.h new file mode 100644 index 0000000..1e415b1 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/qmf.h @@ -0,0 +1,248 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*! + \file qmf.h + \brief Complex qmf analysis/synthesis + \author Markus Werner + +*/ +#ifndef __QMF_H +#define __QMF_H + + + +#include "common_fix.h" +#include "FDK_tools_rom.h" +#include "dct.h" + +/* + * Filter coefficient type definition + */ +#ifdef QMF_DATA_16BIT +#define FIXP_QMF FIXP_SGL +#define FX_DBL2FX_QMF FX_DBL2FX_SGL +#define FX_QMF2FX_DBL FX_SGL2FX_DBL +#define QFRACT_BITS FRACT_BITS +#else +#define FIXP_QMF FIXP_DBL +#define FX_DBL2FX_QMF +#define FX_QMF2FX_DBL +#define QFRACT_BITS DFRACT_BITS +#endif + +/* ARM neon optimized QMF analysis filter requires 32 bit input. + Implemented for RVCT only, currently disabled. See src/arm/qmf_arm.cpp:45 */ +#define FIXP_QAS FIXP_PCM +#define QAS_BITS SAMPLE_BITS + +#ifdef QMFSYN_STATES_16BIT +#define FIXP_QSS FIXP_SGL +#define QSS_BITS FRACT_BITS +#else +#define FIXP_QSS FIXP_DBL +#define QSS_BITS DFRACT_BITS +#endif + +/* Flags for QMF intialization */ +/* Low Power mode flag */ +#define QMF_FLAG_LP 1 +/* Filter is not symetric. This flag is set internally in the QMF initialization as required. */ +#define QMF_FLAG_NONSYMMETRIC 2 +/* Complex Low Delay Filter Bank (or std symmetric filter bank) */ +#define QMF_FLAG_CLDFB 4 +/* Flag indicating that the states should be kept. */ +#define QMF_FLAG_KEEP_STATES 8 +/* Complex Low Delay Filter Bank used in MPEG Surround Encoder */ +#define QMF_FLAG_MPSLDFB 16 +/* Complex Low Delay Filter Bank used in MPEG Surround Encoder allows a optimized calculation of the modulation in qmfForwardModulationHQ() */ +#define QMF_FLAG_MPSLDFB_OPTIMIZE_MODULATION 32 +/* Flag to indicate HE-AAC down-sampled SBR mode (decoder) -> adapt analysis post twiddling */ +#define QMF_FLAG_DOWNSAMPLED 64 + + +typedef struct +{ + int lb_scale; /*!< Scale of low band area */ + int ov_lb_scale; /*!< Scale of adjusted overlap low band area */ + int hb_scale; /*!< Scale of high band area */ + int ov_hb_scale; /*!< Scale of adjusted overlap high band area */ +} QMF_SCALE_FACTOR; + +struct QMF_FILTER_BANK +{ + const FIXP_PFT *p_filter; /*!< Pointer to filter coefficients */ + + void *FilterStates; /*!< Pointer to buffer of filter states + FIXP_PCM in analyse and + FIXP_DBL in synthesis filter */ + int FilterSize; /*!< Size of prototype filter. */ + const FIXP_QTW *t_cos; /*!< Modulation tables. */ + const FIXP_QTW *t_sin; + int filterScale; /*!< filter scale */ + + int no_channels; /*!< Total number of channels (subbands) */ + int no_col; /*!< Number of time slots */ + int lsb; /*!< Top of low subbands */ + int usb; /*!< Top of high subbands */ + + int outScalefactor; /*!< Scale factor of output data (syn only) */ + FIXP_DBL outGain; /*!< Gain output data (syn only) (init with 0x80000000 to ignore) */ + + UINT flags; /*!< flags */ + UCHAR p_stride; /*!< Stride Factor of polyphase filters */ + +}; + +typedef struct QMF_FILTER_BANK *HANDLE_QMF_FILTER_BANK; + +void +qmfAnalysisFiltering( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */ + FIXP_QMF **qmfReal, /*!< Pointer to real subband slots */ + FIXP_QMF **qmfImag, /*!< Pointer to imag subband slots */ + QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */ + const INT_PCM *timeIn, /*!< Time signal */ + const int stride, /*!< Stride factor of audio data */ + FIXP_QMF *pWorkBuffer /*!< pointer to temporal working buffer */ + ); + +void +qmfSynthesisFiltering( HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ + FIXP_QMF **QmfBufferReal, /*!< Pointer to real subband slots */ + FIXP_QMF **QmfBufferImag, /*!< Pointer to imag subband slots */ + const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */ + const int ov_len, /*!< Length of band overlap */ + INT_PCM *timeOut, /*!< Time signal */ + const int stride, /*!< Stride factor of audio data */ + FIXP_QMF *pWorkBuffer /*!< pointer to temporal working buffer */ + ); + +int +qmfInitAnalysisFilterBank( HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */ + FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */ + int noCols, /*!< Number of time slots */ + int lsb, /*!< Number of lower bands */ + int usb, /*!< Number of upper bands */ + int no_channels, /*!< Number of critically sampled bands */ + int flags); /*!< Flags */ + +void +qmfAnalysisFilteringSlot( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */ + FIXP_QMF *qmfReal, /*!< Low and High band, real */ + FIXP_QMF *qmfImag, /*!< Low and High band, imag */ + const INT_PCM *timeIn, /*!< Pointer to input */ + const int stride, /*!< stride factor of input */ + FIXP_QMF *pWorkBuffer /*!< pointer to temporal working buffer */ + ); + +int +qmfInitSynthesisFilterBank( HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */ + FIXP_QSS *pFilterStates, /*!< Pointer to filter state buffer */ + int noCols, /*!< Number of time slots */ + int lsb, /*!< Number of lower bands */ + int usb, /*!< Number of upper bands */ + int no_channels, /*!< Number of critically sampled bands */ + int flags); /*!< Flags */ + +void qmfSynthesisFilteringSlot( HANDLE_QMF_FILTER_BANK synQmf, + const FIXP_QMF *realSlot, + const FIXP_QMF *imagSlot, + const int scaleFactorLowBand, + const int scaleFactorHighBand, + INT_PCM *timeOut, + const int stride, + FIXP_QMF *pWorkBuffer); + +void +qmfChangeOutScalefactor (HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ + int outScalefactor /*!< New scaling factor for output data */ + ); + +void +qmfChangeOutGain (HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ + FIXP_DBL outputGain /*!< New gain for output data */ + ); + + + +#endif /* __QMF_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/scale.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/scale.h new file mode 100644 index 0000000..8e2c8dd --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/scale.h @@ -0,0 +1,250 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: Scaling operations + +******************************************************************************/ + +#ifndef SCALE_H +#define SCALE_H + +#include "common_fix.h" +#include "genericStds.h" +#include "fixminmax.h" + + #define SCALE_INLINE inline + + +#if defined(__arm__) /* cppp replaced: elif */ +#include "arm/scale.h" + +#elif defined(__mips__) /* cppp replaced: elif */ +#include "mips/scale.h" + +#endif + + +#include "../src/scale.cpp" + +#ifndef FUNCTION_scaleValue +/*! + * + * \brief Multiply input by \f$ 2^{scalefactor} \f$ + * + * \return Scaled input + * + */ +#define FUNCTION_scaleValue +inline +FIXP_DBL scaleValue(const FIXP_DBL value, /*!< Value */ + INT scalefactor /*!< Scalefactor */ + ) +{ + if(scalefactor > 0) + return (value<>(-scalefactor)); +} +#endif + +#ifndef FUNCTION_scaleValueSaturate +/*! + * + * \brief Multiply input by \f$ 2^{scalefactor} \f$ + * \param value The value to be scaled. + * \param the shift amount + * \return \f$ value * 2^scalefactor \f$ + * + */ +#define FUNCTION_scaleValueSaturate +inline +FIXP_DBL scaleValueSaturate( + const FIXP_DBL value, + INT scalefactor + ) +{ + if(scalefactor > 0) { + if (fNorm(value) < scalefactor && value != (FIXP_DBL)0) { + if (value > (FIXP_DBL)0) { + return (FIXP_DBL)MAXVAL_DBL; + } else { + return (FIXP_DBL)MINVAL_DBL; + } + } else { + return (value< scalefactor) { + return (FIXP_DBL)0; + } else { + return (value>>(-scalefactor)); + } + } +} +#endif + +#ifndef FUNCTION_scaleValueInPlace +/*! + * + * \brief Multiply input by \f$ 2^{scalefactor} \f$ in place + * + * \return void + * + */ +#define FUNCTION_scaleValueInPlace +inline +void scaleValueInPlace( + FIXP_DBL *value, /*!< Value */ + INT scalefactor /*!< Scalefactor */ + ) +{ + INT newscale; + /* Note: The assignment inside the if conditional allows combining a load with the compare to zero (on ARM and maybe others) */ + if ((newscale = (scalefactor)) >= 0) { + *(value) <<= newscale; + } else { + *(value) >>= -newscale; + } +} +#endif + +/*! + * + * \brief Scale input value by 2^{scale} and saturate output to 2^{dBits-1} + * \return scaled and saturated value + * + * This macro scales src value right or left and applies saturation to (2^dBits)-1 + * maxima output. + */ + +#ifndef SATURATE_RIGHT_SHIFT + #define SATURATE_RIGHT_SHIFT(src, scale, dBits) \ + ( (((LONG)(src)>>(scale)) > (LONG)(((1U)<<((dBits)-1))-1)) ? (LONG)(((1U)<<((dBits)-1))-1) \ + : (((LONG)(src)>>(scale)) < ~((LONG)(((1U)<<((dBits)-1))-1))) ? ~((LONG)(((1U)<<((dBits)-1))-1)) \ + : ((LONG)(src) >> (scale)) ) +#endif + +#ifndef SATURATE_LEFT_SHIFT + #define SATURATE_LEFT_SHIFT(src, scale, dBits) \ + ( ((LONG)(src) > ((LONG)(((1U)<<((dBits)-1))-1)>>(scale))) ? (LONG)(((1U)<<((dBits)-1))-1) \ + : ((LONG)(src) < ~((LONG)(((1U)<<((dBits)-1))-1)>>(scale))) ? ~((LONG)(((1U)<<((dBits)-1))-1)) \ + : ((LONG)(src) << (scale)) ) +#endif + +#ifndef SATURATE_SHIFT +#define SATURATE_SHIFT(src, scale, dBits) \ + ( ((scale) < 0) \ + ? SATURATE_LEFT_SHIFT((src), -(scale), (dBits)) \ + : SATURATE_RIGHT_SHIFT((src), (scale), (dBits)) ) +#endif + +/* + * Alternative shift and saturate left, saturates to -0.99999 instead of -1.0000 + * to avoid problems when inverting the sign of the result. + */ +#ifndef SATURATE_LEFT_SHIFT_ALT +#define SATURATE_LEFT_SHIFT_ALT(src, scale, dBits) \ + ( ((LONG)(src) > ((LONG)(((1U)<<((dBits)-1))-1)>>(scale))) ? (LONG)(((1U)<<((dBits)-1))-1) \ + : ((LONG)(src) < ~((LONG)(((1U)<<((dBits)-1))-2)>>(scale))) ? ~((LONG)(((1U)<<((dBits)-1))-2)) \ + : ((LONG)(src) << (scale)) ) +#endif + +#ifndef SATURATE_RIGHT_SHIFT_ALT + #define SATURATE_RIGHT_SHIFT_ALT(src, scale, dBits) \ + ( (((LONG)(src)>>(scale)) > (LONG)(((1U)<<((dBits)-1))-1)) ? (LONG)(((1U)<<((dBits)-1))-1) \ + : (((LONG)(src)>>(scale)) < ~((LONG)(((1U)<<((dBits)-1))-2))) ? ~((LONG)(((1U)<<((dBits)-1))-2)) \ + : ((LONG)(src) >> (scale)) ) +#endif + +#ifndef SATURATE_INT_PCM_RIGHT_SHIFT +#define SATURATE_INT_PCM_RIGHT_SHIFT(src, scale) SATURATE_RIGHT_SHIFT(src, scale, SAMPLE_BITS) +#endif + +#ifndef SATURATE_INT_PCM_LEFT_SHIFT +#define SATURATE_INT_PCM_LEFT_SHIFT(src, scale) SATURATE_LEFT_SHIFT(src, scale, SAMPLE_BITS) +#endif + +#endif /* #ifndef SCALE_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/scramble.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/scramble.h new file mode 100644 index 0000000..743e3b5 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/scramble.h @@ -0,0 +1,165 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: + +******************************************************************************/ + +#ifndef SCRAMBLE_H +#define SCRAMBLE_H + +#include "common_fix.h" + +#if defined(__arm__) +#include "arm/scramble.h" + +#elif defined(__mips__) && defined(__mips_dsp) /* cppp replaced: elif */ +#include "mips/scramble.h" + +#endif + +/***************************************************************************** + + functionname: scramble + description: bitreversal of input data + returns: + input: + output: + +*****************************************************************************/ +#if !defined(FUNCTION_scramble_sgl) + +inline void scramble_sgl(FIXP_SGL *x, INT n) +{ + INT m,k,j; + + for (m=1,j=0; m>1; (!((j^=k)&k)); k>>=1);} + + if (j>m) + { + FIXP_SGL tmp; + tmp=x[2*m]; + x[2*m]=x[2*j]; + x[2*j]=tmp; + + tmp=x[2*m+1]; + x[2*m+1]=x[2*j+1]; + x[2*j+1]=tmp; + } + } +} +#endif + +#if !defined(FUNCTION_scramble) + +/* default scramble functionality */ +inline void scramble(FIXP_DBL *x, INT n) +{ + INT m,k,j; + FDK_ASSERT(!(((UINT64)x)&(ALIGNMENT_DEFAULT-1))); + + for (m=1,j=0; m>1; (!((j^=k)&k)); k>>=1);} + + if (j>m) + { + FIXP_DBL tmp; + tmp=x[2*m]; + x[2*m]=x[2*j]; + x[2*j]=tmp; + + tmp=x[2*m+1]; + x[2*m+1]=x[2*j+1]; + x[2*j+1]=tmp; + } + } +} +#endif /* !defined(FUNCTION_scramble) */ + +#endif /* SCRAMBLE_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/abs_x86.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/abs_x86.h new file mode 100644 index 0000000..9dbc82a --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/abs_x86.h @@ -0,0 +1,106 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ +#if defined(__x86__) + + #if defined(__x86_64__) + + inline INT fixabs_D(INT x) { return ((x) > (INT)(0)) ? (x) : -(x) ; } + inline INT fixabs_S(INT x) { return ((x) > (INT)(0)) ? (x) : -(x) ; } + + #define fixabs_I(x) fixabs_D(x) + + #define FUNCTION_fixabs_S + #define FUNCTION_fixabs_D + #define FUNCTION_fixabs_I + + #endif /* __x86_64__ */ + +#endif /*__x86__ */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/clz_x86.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/clz_x86.h new file mode 100644 index 0000000..fc56f25 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/clz_x86.h @@ -0,0 +1,154 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__GNUC__) && (defined(__x86__) || defined(__x86_64__)) + + #define FUNCTION_fixnormz_D + #define FUNCTION_fixnorm_D + + inline INT fixnormz_D(LONG value) + { + INT result; + + if (value != 0) { + result = __builtin_clz(value); + } else { + result = 32; + } + return result; + } + + inline INT fixnorm_D(LONG value) + { + INT result; + if (value == 0) { + return 0; + } + if (value < 0) { + value = ~value; + } + result = fixnormz_D(value); + return result - 1; + } + + +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) + +#include + + #define FUNCTION_fixnormz_D + #define FUNCTION_fixnorm_D + + inline INT fixnormz_D(LONG value) + { + unsigned long result = 0; + unsigned char err; + err = _BitScanReverse(&result, value); + if (err) { + return 31 - result; + } else { + return 32; + } + } + + inline INT fixnorm_D(LONG value) + { + INT result; + if (value == 0) { + return 0; + } + if (value < 0) { + value = ~value; + } + result = fixnormz_D(value); + return result - 1; + } + +#endif /* toolchain */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/fixmul_x86.h b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/fixmul_x86.h new file mode 100644 index 0000000..e0374b2 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libFDK/include/x86/fixmul_x86.h @@ -0,0 +1,178 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS FDK Tools ********************** + + Author(s): + Description: fixed point intrinsics + +******************************************************************************/ + +#if defined(__x86__) + +#if defined(_MSC_VER) && defined(_M_IX86) +/* Intel x86 */ + +#define FUNCTION_fixmul_DD +#define FUNCTION_fixmuldiv2_DD +#define FUNCTION_fixmuldiv2BitExact_DD +#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b) +#define FUNCTION_fixmulBitExact_DD +#define fixmulBitExact_DD(a,b) fixmul_DD(a,b) + +#define FUNCTION_fixmuldiv2BitExact_DS +#define fixmuldiv2BitExact_DS(a,b) fixmuldiv2_DS(a,b) + +#define FUNCTION_fixmulBitExact_DS +#define fixmulBitExact_DS(a,b) fixmul_DS(a,b) + +inline INT fixmul_DD (INT a, const INT b) +{ + __asm + { + mov eax, a + imul b + shl edx, 1 + mov a, edx + } + return a ; +} + + +inline INT fixmuldiv2_DD (INT a, const INT b) +{ + __asm + { + mov eax, a + imul b + mov a, edx + } + return a ; +} + +/* ############################################################################# */ +#elif (defined(__GNUC__)||defined(__gnu_linux__)) && defined(__x86__) + +#define FUNCTION_fixmul_DD +#define FUNCTION_fixmuldiv2_DD + +#define FUNCTION_fixmuldiv2BitExact_DD +#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b) + +#define FUNCTION_fixmulBitExact_DD +#define fixmulBitExact_DD(a,b) fixmul_DD(a,b) + +#define FUNCTION_fixmuldiv2BitExact_DS +#define fixmuldiv2BitExact_DS(a,b) fixmuldiv2_DS(a,b) + +#define FUNCTION_fixmulBitExact_DS +#define fixmulBitExact_DS(a,b) fixmul_DS(a,b) + +inline INT fixmul_DD (INT a, const INT b) +{ + INT result; + + asm( "imul %2;\n" + "shl $1, %0;\n" + : "=d"(result), "+a"(a) + : "r"(b) ); + + return result; +} + + +inline INT fixmuldiv2_DD (INT a, const INT b) +{ + INT result; + + asm ( "imul %2;" + : "=d"(result), "+a"(a) + : "r"(b) ); + + return result; +} + +#endif /* (defined(__GNUC__)||defined(__gnu_linux__)) && defined(__x86__) */ + +#endif /* __x86__ */ + diff --git a/services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/mpegFileRead.h b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/mpegFileRead.h new file mode 100644 index 0000000..eca296f --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/mpegFileRead.h @@ -0,0 +1,194 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/***************************** MPEG-4 AAC Decoder ************************** + + Author(s): Manuel Jander + Description: Bitstream data provider for MP4 decoders + +******************************************************************************/ + +#include "machine_type.h" +#include "FDK_audio.h" + +#define MPFREAD_MP4FF_DISABLE + +#ifndef MPFREAD_MP4FF_DISABLE + /*!< If MPFREAD_MP4FF_ENABLE is set, include support for MPEG ISO fileformat. + If not set, no .mp4, .m4a and .3gp files can be used for input. */ + #define MPFREAD_MP4FF_ENABLE +#endif + +/* maximum number of layers which can be read */ +/* shall equal max number of layers read by iisisoff */ +#define FILEREAD_MAX_LAYERS (2) + +typedef struct STRUCT_FILEREAD *HANDLE_FILEREAD; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Open an MPEG audio file and try to detect its format. + * \param filename String of the filename to be opened. + * \param fileFormat Skip file format detection and use given format if fileFormat != FF_UNKNOWN. + Else store detected format into *fileFmt. + * \param transportType Skip transport type detection and use given format if transportType != TT_UNKNOWN. + Else store detected format into *fileFmt. + * \param conf Pointer to unsigned char to hold the AudioSpecificConfig of the input file, if + any (MPEG 4 file format). In case of RAW LATM it holds the StreamMuxConfig. + * \param confSize Pointer to an integer, where the length of the ASC or SMC (in case of RAW LATM) + is stored to. + * \return MPEG file read handle. + */ +HANDLE_FILEREAD mpegFileRead_Open( const char *filename, + FILE_FORMAT fileFormat, + TRANSPORT_TYPE transportType, + UCHAR *conf[], + UINT confSize[], + INT *noOfLayers + ); + +/** + * \brief Get the file format of the input file. + * \param hDataSrc MPEG file read handle. + * \return File format of the input file. + */ +FILE_FORMAT mpegFileRead_GetFileFormat(HANDLE_FILEREAD hDataSrc); + +/** + * \brief Get the transport type of the input file. + * \param hDataSrc MPEG file read handle. + * \return Transport type of the input file. + */ +TRANSPORT_TYPE mpegFileRead_GetTransportType(HANDLE_FILEREAD hDataSrc); + +/** + * \brief Read data from MPEG file. In case of packet file, read one packet, in case + * of streaming file with embedded synchronisation layer (LOAS/ADTS...), just + * fill the buffer. + * + * \param hMpegFile MPEG file read handle. + * \param inBuffer Pointer to input buffer. + * \param bufferSize Size of input buffer. + * \param bytesValid Number of bytes that were read. + * \return 0 on success, -1 if unsupported file format or file read error. + */ +int mpegFileRead_Read( HANDLE_FILEREAD hMpegFile, + UCHAR *inBuffer[], + UINT bufferSize, + UINT *bytesValid + ); + +/** + * \brief Seek in file from origin by given offset in frames. + * \param hMpegFile MPEG file read handle. + * \param origin If 0, the origin is the file beginning (absolute seek). + * If 1, the origin is the current position (relative seek). + * \param offset The amount of frames to seek from the given origin. + * \return 0 on sucess, -1 if offset < 0 or file read error. + */ +int mpegFileRead_seek( HANDLE_FILEREAD hMpegFile, + INT origin, + INT offset + ); + +/** + * \brief Get file position in percent. + * \param hMpegFile MPEG file read handle. + * \return File position in percent. + */ +int mpegFileRead_getPercent(HANDLE_FILEREAD hMpegFile); + + +/** + * \brief Close MPEG audio file. + * \param hMpegFile Mpeg file read handle. + * \return 0 on sucess. + */ +int mpegFileRead_Close(HANDLE_FILEREAD *hMpegFile); + +#ifdef __cplusplus +} +#endif diff --git a/services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/tp_data.h b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/tp_data.h new file mode 100644 index 0000000..7929735 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/tp_data.h @@ -0,0 +1,350 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/***************************** MPEG-4 AAC Decoder ************************** + + Author(s): Manuel Jander + Description: MPEG Transport data tables + +******************************************************************************/ + +#ifndef __TP_DATA_H__ +#define __TP_DATA_H__ + +#include "machine_type.h" +#include "FDK_audio.h" +#include "FDK_bitstream.h" + +/* + * Configuration + */ +#define TP_GA_ENABLE +/* #define TP_CELP_ENABLE */ +/* #define TP_HVXC_ENABLE */ +/* #define TP_SLS_ENABLE */ +//#define TP_ELD_ENABLE +/* #define TP_USAC_ENABLE */ +/* #define TP_RSVD50_ENABLE */ + +#if defined(TP_GA_ENABLE) || defined(TP_SLS_ENABLE) +#define TP_PCE_ENABLE /**< Enable full PCE support */ +#endif + +/** + * ProgramConfig struct. + */ +/* ISO/IEC 14496-3 4.4.1.1 Table 4.2 Program config element */ +#define PC_FSB_CHANNELS_MAX 16 /* Front/Side/Back channels */ +#define PC_LFE_CHANNELS_MAX 4 +#define PC_ASSOCDATA_MAX 8 +#define PC_CCEL_MAX 16 /* CC elements */ +#define PC_COMMENTLENGTH 256 + +typedef struct +{ +#ifdef TP_PCE_ENABLE + /* PCE bitstream elements: */ + UCHAR ElementInstanceTag; + UCHAR Profile; + UCHAR SamplingFrequencyIndex; + UCHAR NumFrontChannelElements; + UCHAR NumSideChannelElements; + UCHAR NumBackChannelElements; + UCHAR NumLfeChannelElements; + UCHAR NumAssocDataElements; + UCHAR NumValidCcElements; + + UCHAR MonoMixdownPresent; + UCHAR MonoMixdownElementNumber; + + UCHAR StereoMixdownPresent; + UCHAR StereoMixdownElementNumber; + + UCHAR MatrixMixdownIndexPresent; + UCHAR MatrixMixdownIndex; + UCHAR PseudoSurroundEnable; + + UCHAR FrontElementIsCpe[PC_FSB_CHANNELS_MAX]; + UCHAR FrontElementTagSelect[PC_FSB_CHANNELS_MAX]; + UCHAR FrontElementHeightInfo[PC_FSB_CHANNELS_MAX]; + + UCHAR SideElementIsCpe[PC_FSB_CHANNELS_MAX]; + UCHAR SideElementTagSelect[PC_FSB_CHANNELS_MAX]; + UCHAR SideElementHeightInfo[PC_FSB_CHANNELS_MAX]; + + UCHAR BackElementIsCpe[PC_FSB_CHANNELS_MAX]; + UCHAR BackElementTagSelect[PC_FSB_CHANNELS_MAX]; + UCHAR BackElementHeightInfo[PC_FSB_CHANNELS_MAX]; + + UCHAR LfeElementTagSelect[PC_LFE_CHANNELS_MAX]; + + UCHAR AssocDataElementTagSelect[PC_ASSOCDATA_MAX]; + + UCHAR CcElementIsIndSw[PC_CCEL_MAX]; + UCHAR ValidCcElementTagSelect[PC_CCEL_MAX]; + + UCHAR CommentFieldBytes; + UCHAR Comment[PC_COMMENTLENGTH]; +#endif /* TP_PCE_ENABLE */ + + /* Helper variables for administration: */ + UCHAR isValid; /*!< Flag showing if PCE has been read successfully. */ + UCHAR NumChannels; /*!< Amount of audio channels summing all channel elements including LFEs */ + UCHAR NumEffectiveChannels; /*!< Amount of audio channels summing only SCEs and CPEs */ + UCHAR elCounter; + +} CProgramConfig; + +typedef enum { + ASCEXT_UNKOWN = -1, + ASCEXT_SBR = 0x2b7, + ASCEXT_PS = 0x548, + ASCEXT_MPS = 0x76a, + ASCEXT_SAOC = 0x7cb, + ASCEXT_LDMPS = 0x7cc + +} TP_ASC_EXTENSION_ID; + +#ifdef TP_GA_ENABLE +/** + * GaSpecificConfig struct + */ +typedef struct { + UINT m_frameLengthFlag ; + UINT m_dependsOnCoreCoder ; + UINT m_coreCoderDelay ; + + UINT m_extensionFlag ; + UINT m_extensionFlag3 ; + + UINT m_layer; + UINT m_numOfSubFrame; + UINT m_layerLength; + +} CSGaSpecificConfig; +#endif /* TP_GA_ENABLE */ + + + + +#ifdef TP_ELD_ENABLE + +typedef enum { + ELDEXT_TERM = 0x0, /* Termination tag */ + ELDEXT_SAOC = 0x1, /* SAOC config */ + ELDEXT_LDSAC = 0x2 /* LD MPEG Surround config */ + /* reserved */ +} ASC_ELD_EXT_TYPE; + +typedef struct { + UCHAR m_frameLengthFlag; + + UCHAR m_sbrPresentFlag; + UCHAR m_useLdQmfTimeAlign; /* Use LD-MPS QMF in SBR to achive time alignment */ + UCHAR m_sbrSamplingRate; + UCHAR m_sbrCrcFlag; + +} CSEldSpecificConfig; +#endif /* TP_ELD_ENABLE */ + + + + +/** + * Audio configuration struct, suitable for encoder and decoder configuration. + */ +typedef struct { + + /* XYZ Specific Data */ + union { +#ifdef TP_GA_ENABLE + CSGaSpecificConfig m_gaSpecificConfig; /**< General audio specific configuration. */ +#endif /* TP_GA_ENABLE */ +#ifdef TP_ELD_ENABLE + CSEldSpecificConfig m_eldSpecificConfig; /**< ELD specific configuration. */ +#endif /* TP_ELD_ENABLE */ + } m_sc; + + /* Common ASC parameters */ +#ifdef TP_PCE_ENABLE + CProgramConfig m_progrConfigElement; /**< Program configuration. */ +#endif /* TP_PCE_ENABLE */ + + AUDIO_OBJECT_TYPE m_aot; /**< Audio Object Type. */ + UINT m_samplingFrequency; /**< Samplerate. */ + UINT m_samplesPerFrame; /**< Amount of samples per frame. */ + UINT m_directMapping; /**< Document this please !! */ + + AUDIO_OBJECT_TYPE m_extensionAudioObjectType; /**< Audio object type */ + UINT m_extensionSamplingFrequency; /**< Samplerate */ + + SCHAR m_channelConfiguration; /**< Channel configuration index */ + + SCHAR m_epConfig; /**< Error protection index */ + SCHAR m_vcb11Flag; /**< aacSectionDataResilienceFlag */ + SCHAR m_rvlcFlag; /**< aacScalefactorDataResilienceFlag */ + SCHAR m_hcrFlag; /**< aacSpectralDataResilienceFlag */ + + SCHAR m_sbrPresentFlag; /**< Flag indicating the presence of SBR data in the bitstream */ + SCHAR m_psPresentFlag; /**< Flag indicating the presence of parametric stereo data in the bitstream */ + UCHAR m_samplingFrequencyIndex; /**< Samplerate index */ + UCHAR m_extensionSamplingFrequencyIndex; /**< Samplerate index */ + SCHAR m_extensionChannelConfiguration; /**< Channel configuration index */ + +} CSAudioSpecificConfig; + +typedef INT (*cbUpdateConfig_t)(void*, const CSAudioSpecificConfig*); +typedef INT (*cbSsc_t)( + void*, HANDLE_FDK_BITSTREAM, + const AUDIO_OBJECT_TYPE coreCodec, + const INT samplingFrequency, + const INT muxMode, + const INT configBytes + ); +typedef INT (*cbSbr_t)( + void * self, + HANDLE_FDK_BITSTREAM hBs, + const INT sampleRateIn, + const INT sampleRateOut, + const INT samplesPerFrame, + const AUDIO_OBJECT_TYPE coreCodec, + const MP4_ELEMENT_ID elementID, + const INT elementIndex + ); + +typedef struct { + cbUpdateConfig_t cbUpdateConfig; /*!< Function pointer for Config change notify callback. */ + void *cbUpdateConfigData; /*!< User data pointer for Config change notify callback. */ + cbSsc_t cbSsc; /*!< Function pointer for SSC parser callback. */ + void *cbSscData; /*!< User data pointer for SSC parser callback. */ + cbSbr_t cbSbr; /*!< Function pointer for SBR header parser callback. */ + void *cbSbrData; /*!< User data pointer for SBR header parser callback. */ +} CSTpCallBacks; + +static const UINT SamplingRateTable[] = +{ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, + 0 +}; + +static inline +int getSamplingRateIndex( UINT samplingRate ) +{ + UINT sf_index, tableSize=sizeof(SamplingRateTable)/sizeof(UINT); + + for (sf_index=0; sf_indextableSize-1) { + return tableSize-1; + } + + return sf_index; +} + +/* + * Get Channel count from channel configuration + */ +static inline int getNumberOfTotalChannels(int channelConfig) +{ + switch (channelConfig) { + case 1: case 2: case 3: + case 4: case 5: case 6: + return channelConfig; + case 7: case 12: case 14: + return 8; + case 11: + return 7; + default: + return 0; + } +} + +static inline +int getNumberOfEffectiveChannels(const int channelConfig) +{ /* index: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 */ + const int n[] = {0,1,2,3,4,5,5,7,0,0, 0, 6, 7, 0, 7, 0}; + return n[channelConfig]; +} + +#endif /* __TP_DATA_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/tpdec_lib.h b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/tpdec_lib.h new file mode 100644 index 0000000..2b0fcb2 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPDec/include/tpdec_lib.h @@ -0,0 +1,521 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/************************** MPEG-4 Transport Decoder *********************** + + Author(s): Manuel Jander + Description: MPEG Transport decoder + +******************************************************************************/ + +#ifndef __TPDEC_LIB_H__ +#define __TPDEC_LIB_H__ + +#include "tp_data.h" + +#include "FDK_bitstream.h" + +#define TRANSPORTDEC_INBUF_SIZE ( 8192 ) /*!< Size is in bytes. + Set the transport input buffer size carefully and + assure that it fulfills the requirements of the + supported transport format(s). */ + +typedef enum { + TRANSPORTDEC_OK = 0, /*!< All fine. */ + + /* Synchronization errors. Wait for new input data and try again. */ + tpdec_sync_error_start = 0x100, + TRANSPORTDEC_NOT_ENOUGH_BITS, /*!< Out of bits. Provide more bits and try again. */ + TRANSPORTDEC_SYNC_ERROR, /*!< No sync was found or sync got lost. Keep trying. */ + tpdec_sync_error_end, + + /* Decode errors. Mostly caused due to bit errors. */ + tpdec_decode_error_start = 0x400, + TRANSPORTDEC_PARSE_ERROR, /*!< Bitstream data showed inconsistencies (wrong syntax). */ + TRANSPORTDEC_UNSUPPORTED_FORMAT, /*!< Unsupported format or feature found in the bitstream data. */ + TRANSPORTDEC_CRC_ERROR, /*!< CRC error encountered in bitstream data. */ + tpdec_decode_error_end, + + /* Fatal errors. Stop immediately on one of these errors! */ + tpdec_fatal_error_start = 0x200, + TRANSPORTDEC_UNKOWN_ERROR, /*!< An unknown error occured. */ + TRANSPORTDEC_INVALID_PARAMETER, /*!< An invalid parameter was passed to a function. */ + TRANSPORTDEC_NEED_TO_RESTART, /*!< The decoder needs to be restarted, since the requiered + configuration change cannot be performed. */ + tpdec_fatal_error_end + +} TRANSPORTDEC_ERROR; + + +/** Macro to identify decode errors. */ +#define TPDEC_IS_DECODE_ERROR(err) ( ((err>=tpdec_decode_error_start) && (err<=tpdec_decode_error_end)) ? 1 : 0) +/** Macro to identify fatal errors. */ +#define TPDEC_IS_FATAL_ERROR(err) ( ((err>=tpdec_fatal_error_start) && (err<=tpdec_fatal_error_end)) ? 1 : 0) + + +/** + * \brief Parameter identifiers for transportDec_SetParam() + */ +typedef enum { + TPDEC_PARAM_MINIMIZE_DELAY = 1, /** Delay minimization strategy. 0: none, 1: discard as many frames as possible. */ + TPDEC_PARAM_EARLY_CONFIG, /** Enable early config discovery. */ + TPDEC_PARAM_IGNORE_BUFFERFULLNESS, /** Ignore buffer fullness. */ + TPDEC_PARAM_SET_BITRATE, /** Set average bit rate for bit stream interruption frame misses estimation. */ + TPDEC_PARAM_RESET, /** Reset transport decoder instance status. */ + TPDEC_PARAM_BURST_PERIOD /** Set data reception burst period in mili seconds. */ +} TPDEC_PARAM; + +/* ISO/IEC 14496-3 4.4.1.1 Table 4.2 Program config element */ +#define PC_FSB_CHANNELS_MAX 16 /* Front/Side/Back channels */ +#define PC_LFE_CHANNELS_MAX 4 +#define PC_ASSOCDATA_MAX 8 +#define PC_CCEL_MAX 16 /* CC elements */ +#define PC_COMMENTLENGTH 256 +#define PC_NUM_HEIGHT_LAYER 3 + + +/*! + \brief Reset Program Config Element. + \param pPce Program Config Element structure. + \return void +*/ +void CProgramConfig_Reset ( CProgramConfig *pPce ); + +/*! + \brief Initialize Program Config Element. + \param pPce Program Config Element structure. + \return void +*/ +void CProgramConfig_Init ( CProgramConfig *pPce ); + +/*! + \brief Inquire state of present Program Config Element structure. + \param pPce Program Config Element structure. + \return 1 if the PCE structure is filled correct, + 0 if no valid PCE present. +*/ +int CProgramConfig_IsValid ( const CProgramConfig *pPce ); + +#ifdef TP_PCE_ENABLE +/*! + \brief Read Program Config Element. + \param pPce Program Config Element structure. + \param bs Bitstream buffer to read from. + \param alignAnchor Align bitstream to alignAnchor bits after all read operations. + \return void +*/ +void CProgramConfig_Read ( CProgramConfig *pPce, + HANDLE_FDK_BITSTREAM bs, + UINT alignAnchor ); + +/*! + \brief Compare two Program Config Elements. + \param pPce1 Pointer to first Program Config Element structure. + \param pPce2 Pointer to second Program Config Element structure. + \return -1 if PCEs are completely different, + 0 if PCEs are completely equal, + 1 if PCEs are different but have the same channel config, + 2 if PCEs have different channel config but same number of channels. +*/ +int CProgramConfig_Compare ( const CProgramConfig * const pPce1, + const CProgramConfig * const pPce2 ); + +/*! + \brief Get a Program Config Element that matches the predefined MPEG-4 channel configurations 1-14. + \param pPce Program Config Element structure. + \param channelConfig MPEG-4 channel configuration. + \return void +*/ +void CProgramConfig_GetDefault ( CProgramConfig *pPce, + const UINT channelConfig ); +#endif /* TP_PCE_ENABLE */ + +/** + * \brief Lookup and verify a given element. The decoder calls this + * method with every new element ID found in the bitstream. + * + * \param pPce A valid Program config structure. + * \param tag Tag of the current element to be looked up. + * \param channelIdx The current channel count of the decoder parser. + * \param chMapping Array to store the canonical channel mapping indexes. + * \param chType Array to store the audio channel type. + * \param chIndex Array to store the individual audio channel type index. + * \param elMapping Pointer where the canonical element index is stored. + * \param elType The element id of the current element to be looked up. + * + * \return Non-zero if the element belongs to the current program, zero + * if it does not. + */ +int CProgramConfig_LookupElement( + CProgramConfig *pPce, + UINT channelConfig, + const UINT tag, + const UINT channelIdx, + UCHAR chMapping[], + AUDIO_CHANNEL_TYPE chType[], + UCHAR chIndex[], + UCHAR *elMapping, + MP4_ELEMENT_ID elList[], + MP4_ELEMENT_ID elType + ); + +/** + * \brief Get table of elements in canonical order from a + * give program config field. + * \param pPce A valid program config structure. + * \param table An array where the element IDs are stored. + * \param elListSize The length of the table array. + * \param pChMapIdx Pointer to a field receiving the corresponding + * implicit channel configuration index of the given + * PCE. If none can be found it receives the value 0. + * \return Total element count including all SCE, CPE and LFE. + */ +int CProgramConfig_GetElementTable( const CProgramConfig *pPce, + MP4_ELEMENT_ID table[], + const INT elListSize, + UCHAR *pChMapIdx ); + +/** + * \brief Initialize a given AudioSpecificConfig structure. + * \param pAsc A pointer to an allocated CSAudioSpecificConfig struct. + * \return void + */ +void AudioSpecificConfig_Init(CSAudioSpecificConfig *pAsc); + +/** + * \brief Parse a AudioSpecificConfig from a given bitstream handle. + * + * \param pAsc A pointer to an allocated CSAudioSpecificConfig struct. + * \param hBs Bitstream handle. + * \param fExplicitBackwardCompatible Do explicit backward compatibility parsing if set (flag). + * \param cb pointer to structure holding callback information + * + * \return Total element count including all SCE, CPE and LFE. + */ +TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( + CSAudioSpecificConfig *pAsc, + HANDLE_FDK_BITSTREAM hBs, + int fExplicitBackwardCompatible, + CSTpCallBacks *cb + ); + +/* CELP stuff */ +enum { + MPE = 0, + RPE = 1, + fs8KHz = 0, + fs16KHz = 1 +}; + +/* Defintion of flags that can be passed to transportDecOpen() */ +#define TP_FLAG_MPEG4 1 + +/* Capability flags */ +#define CAPF_TPDEC_ADIF 0x00001000 /**< Flag indicating support for ADIF transport format. */ +#define CAPF_TPDEC_ADTS 0x00002000 /**< Flag indicating support for ADTS transport format. */ +#define CAPF_TPDEC_LOAS 0x00004000 /**< Flag indicating support for LOAS transport format. */ +#define CAPF_TPDEC_LATM 0x00008000 /**< Flag indicating support for LATM transport format. */ +#define CAPF_TPDEC_RAWPACKETS 0x00010000 /**< Flag indicating support for raw packets transport format. */ + +typedef struct TRANSPORTDEC *HANDLE_TRANSPORTDEC; + + +/** + * \brief Configure Transport Decoder via a binary coded AudioSpecificConfig or StreamMuxConfig. + * The previously requested configuration callback will be called as well. The buffer conf + * must containt a SMC in case of LOAS/LATM transport format, and an ASC elseways. + * + * \param hTp Handle of a transport decoder. + * \param conf UCHAR buffer of the binary coded config (ASC or SMC). + * \param length The length in bytes of the conf buffer. + * + * \return Error code. + */ +TRANSPORTDEC_ERROR transportDec_OutOfBandConfig( const HANDLE_TRANSPORTDEC hTp, + UCHAR *conf, + const UINT length, + const UINT layer ); + +/** + * \brief Open Transport medium for reading. + * + * \param transportDecFmt Format of the transport decoder medium to be accessed. + * \param flags Transport decoder flags. Currently only TP_FLAG_MPEG4, which signals a + * MPEG4 capable decoder (relevant for ADTS only). + * + * \return A pointer to a valid and allocated HANDLE_TRANSPORTDEC or a null pointer on failure. + */ +HANDLE_TRANSPORTDEC transportDec_Open( TRANSPORT_TYPE transportDecFmt, + const UINT flags ); + +/** + * \brief Register configuration change callback. + * \param hTp Handle of transport decoder. + * \param cbUpdateConfig Pointer to a callback function to handle audio config changes. + * \param user_data void pointer for user data passed to the callback as first parameter. + * \return 0 on success. + */ +int transportDec_RegisterAscCallback ( + HANDLE_TRANSPORTDEC hTp, + const cbUpdateConfig_t cbUpdateConfig, + void* user_data ); + +/** + * \brief Register SSC parser callback. + * \param hTp Handle of transport decoder. + * \param cbUpdateConfig Pointer to a callback function to handle SSC parsing. + * \param user_data void pointer for user data passed to the callback as first parameter. + * \return 0 on success. + */ +int transportDec_RegisterSscCallback ( + HANDLE_TRANSPORTDEC hTp, + const cbSsc_t cbSscParse, + void* user_data ); + +/** + * \brief Register SBR header parser callback. + * \param hTp Handle of transport decoder. + * \param cbUpdateConfig Pointer to a callback function to handle SBR header parsing. + * \param user_data void pointer for user data passed to the callback as first parameter. + * \return 0 on success. + */ +int transportDec_RegisterSbrCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSbr_t cbSbr, void* user_data); + +/** + * \brief Fill internal input buffer with bitstream data from the external input buffer. + * The function only copies such data as long as the decoder-internal input buffer is not full. + * So it grabs whatever it can from pBuffer and returns information (bytesValid) so that at a + * subsequent call of %transportDec_FillData(), the right position in pBuffer can be determined to + * grab the next data. + * + * \param hTp Handle of transportDec. + * \param pBuffer Pointer to external input buffer. + * \param bufferSize Size of external input buffer. This argument is required because decoder-internally + * we need the information to calculate the offset to pBuffer, where the next + * available data is, which is then fed into the decoder-internal buffer (as much + * as possible). Our example framework implementation fills the buffer at pBuffer + * again, once it contains no available valid bytes anymore (meaning bytesValid equal 0). + * \param bytesValid Number of bitstream bytes in the external bitstream buffer that have not yet been + * copied into the decoder's internal bitstream buffer by calling this function. + * The value is updated according to the amount of newly copied bytes. + * \param layer The layer the bitstream belongs to. + * \return Error code. + */ +TRANSPORTDEC_ERROR transportDec_FillData( + const HANDLE_TRANSPORTDEC hTp, + UCHAR *pBuffer, + const UINT bufferSize, + UINT *pBytesValid, + const INT layer ); + +/** + * \brief Get transportDec bitstream handle. + * \param hTp Pointer to a transport decoder handle. + * \return HANDLE_FDK_BITSTREAM bitstream handle. + */ +HANDLE_FDK_BITSTREAM transportDec_GetBitstream ( const HANDLE_TRANSPORTDEC hTp, const UINT layer ); + +/** + * \brief Get transport format. + * \param hTp Pointer to a transport decoder handle. + * \return The transport format. + */ +TRANSPORT_TYPE transportDec_GetFormat ( const HANDLE_TRANSPORTDEC hTp ); + +/** + * \brief Get the current buffer fullness value. + * + * \param hTp Handle of a transport decoder. + * + * \return Buffer fullness + */ +INT transportDec_GetBufferFullness( const HANDLE_TRANSPORTDEC hTp ); + +/** + * \brief Close and deallocate transportDec. + * \param phTp Pointer to a previously allocated transport decoder handle. + * \return void + */ +void transportDec_Close ( HANDLE_TRANSPORTDEC *phTp ); + +/** + * \brief Read one access unit from the transportDec medium. + * \param hTp Handle of transportDec. + * \param length On return, this value is overwritten with the actual access unit length in bits. + * Set to -1 if length is unknown. + * \return Error code. + */ +TRANSPORTDEC_ERROR transportDec_ReadAccessUnit ( const HANDLE_TRANSPORTDEC hTp, const UINT layer ); + +/** + * \brief Get the remaining amount of bits of the current access unit. The result + * can be below zero, meaning that too many bits have been read. + * \param hTp Handle of transportDec. + * \return amount of remaining bits. + */ +INT transportDec_GetAuBitsRemaining( const HANDLE_TRANSPORTDEC hTp, const UINT layer ); + +/** + * \brief Get the total amount of bits of the current access unit. + * \param hTp Handle of transportDec. + * \return amount of total bits. + */ +INT transportDec_GetAuBitsTotal( const HANDLE_TRANSPORTDEC hTp, const UINT layer ); + +/** + * \brief This function is required to be called when the decoder has finished parsing + * one Access Unit for bitstream housekeeping. + * \param hTp Transport Handle. + * \return Error code. + */ +TRANSPORTDEC_ERROR transportDec_EndAccessUnit ( const HANDLE_TRANSPORTDEC hTp ); + +/** + * \brief Obtain the amount of missing access units if applicable in case of + * a bit stream synchronization error. Each time transportDec_ReadAccessUnit() + * returns TRANSPORTDEC_SYNC_ERROR this function can be called to retrieve an estimate + * of the amount of missing access units. This works only in case of constant average + * bit rate (has to be known) and if the parameter TPDEC_PARAM_SET_BITRATE has been set + * accordingly. + * \param hTp Transport Handle. + * \param pNAccessUnits pointer to a memory location where the estimated lost frame count will be stored into. + * \return Error code. + */ +TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount ( INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp ); + + +/** + * \brief Set a given setting. + * \param hTp Transport Handle. + * \param param Identifier of the parameter to be changed. + * \param value Value for the parameter to be changed. + * \return Error code. + */ +TRANSPORTDEC_ERROR transportDec_SetParam ( const HANDLE_TRANSPORTDEC hTp, + const TPDEC_PARAM param, + const INT value ); + +/** + * \brief Get number of subframes (for LATM or ADTS) + * \param hTp Transport Handle. + * \return Number of ADTS/LATM subframes (return 1 for all other transport types). + */ +UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp); + + +/** + * \brief Get info structure of transport decoder library. + * \param info A pointer to an allocated LIB_INFO struct. + * \return Error code. + */ +TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info ); + +/* ADTS CRC support */ + +/** + * \brief Set current bitstream position as start of a new data region. + * \param hTp Transport handle. + * \param mBits Size in bits of the data region. Set to 0 if it should not be of a fixed size. + * \return Data region ID, which should be used when calling transportDec_CrcEndReg(). + */ +int transportDec_CrcStartReg ( const HANDLE_TRANSPORTDEC hTp, + const INT mBits ); + +/** + * \brief Set end of data region. + * \param hTp Transport handle. + * \param reg Data region ID, opbtained from transportDec_CrcStartReg(). + * \return void + */ +void transportDec_CrcEndReg ( const HANDLE_TRANSPORTDEC hTp, + const INT reg ); + +/** + * \brief Calculate ADTS crc and check if it is correct. The ADTS checksum is held internally. + * \param hTp Transport handle. + * \return Return TRANSPORTDEC_OK if the CRC is ok, or error if CRC is not correct. + */ +TRANSPORTDEC_ERROR transportDec_CrcCheck ( const HANDLE_TRANSPORTDEC hTp ); + + +#endif /* #ifndef __TPDEC_LIB_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/mpegFileWrite.h b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/mpegFileWrite.h new file mode 100644 index 0000000..eac5095 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/mpegFileWrite.h @@ -0,0 +1,140 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/***************************** MPEG-4 AAC Decoder ************************** + + Author(s): Manuel Jander + Description: Bitstream data provider for MP4 decoders + +******************************************************************************/ + +#include "machine_type.h" +#include "FDK_audio.h" + +/*!< If MPFWRITE_MP4FF_ENABLE is set, include support for MPEG ISO fileformat. + If not set, no .mp4, .m4a and .3gp files can be used for input. */ +/* #define MPFWRITE_MP4FF_ENABLE */ + +typedef struct STRUCT_FILEWRITE *HANDLE_FILEWRITE; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Open an MPEG audio file. + * \param mpegFileWrite_Filename String of the filename to be opened. + * \param fileFmt Transport format to use. + * \param conf + * \param confSize + * \return MPEG file write handle. + */ +HANDLE_FILEWRITE mpegFileWrite_Open( char *mpegFileWrite_Filename, + FILE_FORMAT fileFmt, + TRANSPORT_TYPE transportType, + UCHAR *conf, + UINT confSize + ); + +/** + * \brief Write to an MPEG audio file. + * \param inBuffer Buffer to write. + * \param bufferSize Size of buffer to write in bytes. + * \return 0 on sucess, -1 on unsupported file format or write error. + */ +int mpegFileWrite_Write( HANDLE_FILEWRITE hFileWrite, + UCHAR *inBuffer, + int bufferSize + ); + +/** + * \brief Deallocate memory and close file. + * \param hFileWrite MPEG file write handle. + * \return 0 on sucess. + */ +int mpegFileWrite_Close( HANDLE_FILEWRITE *hFileWrite ); + + +#ifdef __cplusplus +} +#endif diff --git a/services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/tp_data.h b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/tp_data.h new file mode 100644 index 0000000..e323720 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/tp_data.h @@ -0,0 +1,350 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/***************************** MPEG-4 AAC Decoder ************************** + + Author(s): Manuel Jander + Description: MPEG Transport data tables + +******************************************************************************/ + +#ifndef __TP_DATA_H__ +#define __TP_DATA_H__ + +#include "machine_type.h" +#include "FDK_audio.h" +#include "FDK_bitstream.h" + +/* + * Configuration + */ +#define TP_GA_ENABLE +/* #define TP_CELP_ENABLE */ +/* #define TP_HVXC_ENABLE */ +/* #define TP_SLS_ENABLE */ +#define TP_ELD_ENABLE +/* #define TP_USAC_ENABLE */ +/* #define TP_RSVD50_ENABLE */ + +#if defined(TP_GA_ENABLE) || defined(TP_SLS_ENABLE) +#define TP_PCE_ENABLE /**< Enable full PCE support */ +#endif + +/** + * ProgramConfig struct. + */ +/* ISO/IEC 14496-3 4.4.1.1 Table 4.2 Program config element */ +#define PC_FSB_CHANNELS_MAX 16 /* Front/Side/Back channels */ +#define PC_LFE_CHANNELS_MAX 4 +#define PC_ASSOCDATA_MAX 8 +#define PC_CCEL_MAX 16 /* CC elements */ +#define PC_COMMENTLENGTH 256 + +typedef struct +{ +#ifdef TP_PCE_ENABLE + /* PCE bitstream elements: */ + UCHAR ElementInstanceTag; + UCHAR Profile; + UCHAR SamplingFrequencyIndex; + UCHAR NumFrontChannelElements; + UCHAR NumSideChannelElements; + UCHAR NumBackChannelElements; + UCHAR NumLfeChannelElements; + UCHAR NumAssocDataElements; + UCHAR NumValidCcElements; + + UCHAR MonoMixdownPresent; + UCHAR MonoMixdownElementNumber; + + UCHAR StereoMixdownPresent; + UCHAR StereoMixdownElementNumber; + + UCHAR MatrixMixdownIndexPresent; + UCHAR MatrixMixdownIndex; + UCHAR PseudoSurroundEnable; + + UCHAR FrontElementIsCpe[PC_FSB_CHANNELS_MAX]; + UCHAR FrontElementTagSelect[PC_FSB_CHANNELS_MAX]; + UCHAR FrontElementHeightInfo[PC_FSB_CHANNELS_MAX]; + + UCHAR SideElementIsCpe[PC_FSB_CHANNELS_MAX]; + UCHAR SideElementTagSelect[PC_FSB_CHANNELS_MAX]; + UCHAR SideElementHeightInfo[PC_FSB_CHANNELS_MAX]; + + UCHAR BackElementIsCpe[PC_FSB_CHANNELS_MAX]; + UCHAR BackElementTagSelect[PC_FSB_CHANNELS_MAX]; + UCHAR BackElementHeightInfo[PC_FSB_CHANNELS_MAX]; + + UCHAR LfeElementTagSelect[PC_LFE_CHANNELS_MAX]; + + UCHAR AssocDataElementTagSelect[PC_ASSOCDATA_MAX]; + + UCHAR CcElementIsIndSw[PC_CCEL_MAX]; + UCHAR ValidCcElementTagSelect[PC_CCEL_MAX]; + + UCHAR CommentFieldBytes; + UCHAR Comment[PC_COMMENTLENGTH]; +#endif /* TP_PCE_ENABLE */ + + /* Helper variables for administration: */ + UCHAR isValid; /*!< Flag showing if PCE has been read successfully. */ + UCHAR NumChannels; /*!< Amount of audio channels summing all channel elements including LFEs */ + UCHAR NumEffectiveChannels; /*!< Amount of audio channels summing only SCEs and CPEs */ + UCHAR elCounter; + +} CProgramConfig; + +typedef enum { + ASCEXT_UNKOWN = -1, + ASCEXT_SBR = 0x2b7, + ASCEXT_PS = 0x548, + ASCEXT_MPS = 0x76a, + ASCEXT_SAOC = 0x7cb, + ASCEXT_LDMPS = 0x7cc + +} TP_ASC_EXTENSION_ID; + +#ifdef TP_GA_ENABLE +/** + * GaSpecificConfig struct + */ +typedef struct { + UINT m_frameLengthFlag ; + UINT m_dependsOnCoreCoder ; + UINT m_coreCoderDelay ; + + UINT m_extensionFlag ; + UINT m_extensionFlag3 ; + + UINT m_layer; + UINT m_numOfSubFrame; + UINT m_layerLength; + +} CSGaSpecificConfig; +#endif /* TP_GA_ENABLE */ + + + + +#ifdef TP_ELD_ENABLE + +typedef enum { + ELDEXT_TERM = 0x0, /* Termination tag */ + ELDEXT_SAOC = 0x1, /* SAOC config */ + ELDEXT_LDSAC = 0x2 /* LD MPEG Surround config */ + /* reserved */ +} ASC_ELD_EXT_TYPE; + +typedef struct { + UCHAR m_frameLengthFlag; + + UCHAR m_sbrPresentFlag; + UCHAR m_useLdQmfTimeAlign; /* Use LD-MPS QMF in SBR to achive time alignment */ + UCHAR m_sbrSamplingRate; + UCHAR m_sbrCrcFlag; + +} CSEldSpecificConfig; +#endif /* TP_ELD_ENABLE */ + + + + +/** + * Audio configuration struct, suitable for encoder and decoder configuration. + */ +typedef struct { + + /* XYZ Specific Data */ + union { +#ifdef TP_GA_ENABLE + CSGaSpecificConfig m_gaSpecificConfig; /**< General audio specific configuration. */ +#endif /* TP_GA_ENABLE */ +#ifdef TP_ELD_ENABLE + CSEldSpecificConfig m_eldSpecificConfig; /**< ELD specific configuration. */ +#endif /* TP_ELD_ENABLE */ + } m_sc; + + /* Common ASC parameters */ +#ifdef TP_PCE_ENABLE + CProgramConfig m_progrConfigElement; /**< Program configuration. */ +#endif /* TP_PCE_ENABLE */ + + AUDIO_OBJECT_TYPE m_aot; /**< Audio Object Type. */ + UINT m_samplingFrequency; /**< Samplerate. */ + UINT m_samplesPerFrame; /**< Amount of samples per frame. */ + UINT m_directMapping; /**< Document this please !! */ + + AUDIO_OBJECT_TYPE m_extensionAudioObjectType; /**< Audio object type */ + UINT m_extensionSamplingFrequency; /**< Samplerate */ + + SCHAR m_channelConfiguration; /**< Channel configuration index */ + + SCHAR m_epConfig; /**< Error protection index */ + SCHAR m_vcb11Flag; /**< aacSectionDataResilienceFlag */ + SCHAR m_rvlcFlag; /**< aacScalefactorDataResilienceFlag */ + SCHAR m_hcrFlag; /**< aacSpectralDataResilienceFlag */ + + SCHAR m_sbrPresentFlag; /**< Flag indicating the presence of SBR data in the bitstream */ + SCHAR m_psPresentFlag; /**< Flag indicating the presence of parametric stereo data in the bitstream */ + UCHAR m_samplingFrequencyIndex; /**< Samplerate index */ + UCHAR m_extensionSamplingFrequencyIndex; /**< Samplerate index */ + SCHAR m_extensionChannelConfiguration; /**< Channel configuration index */ + +} CSAudioSpecificConfig; + +typedef INT (*cbUpdateConfig_t)(void*, const CSAudioSpecificConfig*); +typedef INT (*cbSsc_t)( + void*, HANDLE_FDK_BITSTREAM, + const AUDIO_OBJECT_TYPE coreCodec, + const INT samplingFrequency, + const INT muxMode, + const INT configBytes + ); +typedef INT (*cbSbr_t)( + void * self, + HANDLE_FDK_BITSTREAM hBs, + const INT sampleRateIn, + const INT sampleRateOut, + const INT samplesPerFrame, + const AUDIO_OBJECT_TYPE coreCodec, + const MP4_ELEMENT_ID elementID, + const INT elementIndex + ); + +typedef struct { + cbUpdateConfig_t cbUpdateConfig; /*!< Function pointer for Config change notify callback. */ + void *cbUpdateConfigData; /*!< User data pointer for Config change notify callback. */ + cbSsc_t cbSsc; /*!< Function pointer for SSC parser callback. */ + void *cbSscData; /*!< User data pointer for SSC parser callback. */ + cbSbr_t cbSbr; /*!< Function pointer for SBR header parser callback. */ + void *cbSbrData; /*!< User data pointer for SBR header parser callback. */ +} CSTpCallBacks; + +static const UINT SamplingRateTable[] = +{ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, + 0 +}; + +static inline +int getSamplingRateIndex( UINT samplingRate ) +{ + UINT sf_index, tableSize=sizeof(SamplingRateTable)/sizeof(UINT); + + for (sf_index=0; sf_indextableSize-1) { + return tableSize-1; + } + + return sf_index; +} + +/* + * Get Channel count from channel configuration + */ +static inline int getNumberOfTotalChannels(int channelConfig) +{ + switch (channelConfig) { + case 1: case 2: case 3: + case 4: case 5: case 6: + return channelConfig; + case 7: case 12: case 14: + return 8; + case 11: + return 7; + default: + return 0; + } +} + +static inline +int getNumberOfEffectiveChannels(const int channelConfig) +{ /* index: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 */ + const int n[] = {0,1,2,3,4,5,5,7,0,0, 0, 6, 7, 0, 7, 0}; + return n[channelConfig]; +} + +#endif /* __TP_DATA_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/tpenc_lib.h b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/tpenc_lib.h new file mode 100644 index 0000000..e0e3226 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libMpegTPEnc/include/tpenc_lib.h @@ -0,0 +1,296 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/************************** MPEG-4 Transport Encoder ************************ + + Author(s): Manuel Jander + Description: MPEG Transport encode + +******************************************************************************/ + +#ifndef __TPENC_LIB_H__ +#define __TPENC_LIB_H__ + +#include "tp_data.h" +#include "FDK_bitstream.h" + +#define TRANSPORTENC_INBUF_SIZE 8192 + +typedef enum { + TRANSPORTENC_OK = 0, /*!< All fine. */ + TRANSPORTENC_NO_MEM, /*!< Out of memory. */ + TRANSPORTENC_UNKOWN_ERROR = 1, /*!< Unknown error (embarrasing). */ + TRANSPORTENC_INVALID_PARAMETER, /*!< An invalid parameter was passed to a function . */ + TRANSPORTENC_PARSE_ERROR, /*!< Bitstream data contained inconsistencies (wrong syntax). */ + TRANSPORTENC_UNSUPPORTED_FORMAT, /*!< Unsupported transport format. */ + TRANSPORTENC_NOT_ENOUGH_BITS, /*!< Out of bits. Provide more bits and try again. */ + + TRANSPORTENC_INVALID_CONFIG, /*!< Error in configuration. */ + TRANSPORTENC_LATM_INVALID_NR_OF_SUBFRAMES, /*!< LATM: number of subframes out of range. */ + TRANSPORTENC_LOAS_NOT_AVAILABLE, /*!< LOAS format not supported. */ + TRANSPORTENC_INVALID_LATM_ALIGNMENT, /*!< AudioMuxElement length not aligned to 1 byte. */ + + TRANSPORTENC_INVALID_TRANSMISSION_FRAME_LENGTH, /*!< Invalid transmission frame length (< 0). */ + TRANSPORTENC_INVALID_CELP_FRAME_LENGTH, /*!< Invalid CELP frame length found (>= 62). */ + TRANSPORTENC_INVALID_FRAME_BITS, /*!< Frame bits is not 40 and not 80. */ + TRANSPORTENC_INVALID_AOT, /*!< Unknown AOT found. */ + TRANSPORTENC_INVALID_AU_LENGTH /*!< Invalid Access Unit length (not byte-aligned). */ + +} TRANSPORTENC_ERROR; + +typedef struct TRANSPORTENC *HANDLE_TRANSPORTENC; + +/** + * \brief Determine a reasonable channel configuration on the basis of channel_mode. + * \param noChannels Number of audio channels. + * \return CHANNEL_MODE value that matches the given amount of audio channels. + */ +CHANNEL_MODE transportEnc_GetChannelMode( int noChannels ); + +/** + * \brief Register SBR heaqder writer callback. + * \param hTp Handle of transport decoder. + * \param cbUpdateConfig Pointer to a callback function to handle SBR header writing. + * \param user_data void pointer for user data passed to the callback as first parameter. + * \return 0 on success. + */ +int transportEnc_RegisterSbrCallback ( + HANDLE_TRANSPORTENC hTpEnc, + const cbSbr_t cbSbr, + void* user_data + ); + +/** + * \brief Register SSC writer callback. + * \param hTp Handle of transport decoder. + * \param cbUpdateConfig Pointer to a callback function to handle SSC writing. + * \param user_data void pointer for user data passed to the callback as first parameter. + * \return 0 on success. + */ +int transportEnc_RegisterSscCallback ( + HANDLE_TRANSPORTENC hTpEnc, + const cbSsc_t cbSsc, + void* user_data + ); + +/** + * \brief Write ASC from given parameters. + * \param asc A HANDLE_FDK_BITSTREAM where the ASC is written to. + * \param config Structure containing the codec configuration settings. + * \param cb callback information structure. + * \return 0 on success. + */ +int transportEnc_writeASC ( + HANDLE_FDK_BITSTREAM asc, + CODER_CONFIG *config, + CSTpCallBacks *cb + ); + + +/* Defintion of flags that can be passed to transportEnc_Open() */ +#define TP_FLAG_MPEG4 1 /** MPEG4 (instead of MPEG2) */ +#define TP_FLAG_LATM_AMV 2 /** LATM AudioMuxVersion */ +#define TP_FLAG_LATM_AMVA 4 /** LATM AudioMuxVersionA */ + +/** + * \brief Allocate transport encoder. + * \param phTpEnc Pointer to transport encoder handle. + * \return Error code. + */ +TRANSPORTENC_ERROR transportEnc_Open( HANDLE_TRANSPORTENC *phTpEnc ); + +/** + * \brief Init transport encoder. + * \param bsBuffer Pointer to transport encoder. + * \param bsBuffer Pointer to bitstream buffer. + * \param bsBufferSize Size in bytes of bsBuffer. + * \param transportFmt Format of the transport to be written. + * \param config Pointer to a valid CODER_CONFIG struct. + * \param flags Transport encoder flags. + * \return Error code. + */ +TRANSPORTENC_ERROR transportEnc_Init( + HANDLE_TRANSPORTENC hTpEnc, + UCHAR *bsBuffer, + INT bsBufferSize, + TRANSPORT_TYPE transportFmt, + CODER_CONFIG *config, + UINT flags + ); + +/** + * \brief Get transport encoder bitstream. + * \param hTp Pointer to a transport encoder handle. + * \return The handle to the requested FDK bitstream. + */ +HANDLE_FDK_BITSTREAM transportEnc_GetBitstream( HANDLE_TRANSPORTENC hTp ); + +/** + * \brief Get amount of bits required by the transport headers. + * \param hTp Handle of transport encoder. + * \param auBits Amount of payload bits required for the current subframe. + * \return Error code. + */ +INT transportEnc_GetStaticBits( HANDLE_TRANSPORTENC hTp, int auBits ); + +/** + * \brief Close transport encoder. This function assures that all allocated memory is freed. + * \param phTp Pointer to a previously allocated transport encoder handle. + */ +void transportEnc_Close( HANDLE_TRANSPORTENC *phTp ); + +/** + * \brief Write one access unit. + * \param hTp Handle of transport encoder. + * \param total_bits Amount of total access unit bits. + * \param bufferFullness Value of current buffer fullness in bits. + * \param noConsideredChannels Number of bitrate wise considered channels (all minus LFE channels). + * \return Error code. + */ +TRANSPORTENC_ERROR transportEnc_WriteAccessUnit( HANDLE_TRANSPORTENC hTp, + INT total_bits, + int bufferFullness, + int noConsideredChannels ); + +/** + * \brief Inform the transportEnc layer that writing of access unit has finished. This function + * is required to be called when the encoder has finished writing one Access + * one Access Unit for bitstream housekeeping. + * \param hTp Transport handle. + * \param pBits Pointer to an int, where the current amount of frame bits is passed + * and where the current amount of subframe bits is returned. + * + * OR: This integer is modified by the amount of extra bit alignment that may occurr. + * + * \return Error code. + */ +TRANSPORTENC_ERROR transportEnc_EndAccessUnit( HANDLE_TRANSPORTENC hTp, int *pBits); + +/* + * \brief Get a payload frame. + * \param hTpEnc Transport encoder handle. + * \param nBytes Pointer to an int to hold the frame size in bytes. Returns zero + * if currently there is no complete frame for output (number of sub frames > 1). + * \return Error code. + */ +TRANSPORTENC_ERROR transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc, int *nbytes); + +/* ADTS CRC support */ + +/** + * \brief Set current bitstream position as start of a new data region. + * \param hTpEnc Transport encoder handle. + * \param mBits Size in bits of the data region. Set to 0 if it should not be of a fixed size. + * \return Data region ID, which should be used when calling transportEnc_CrcEndReg(). + */ +int transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc, int mBits); + +/** + * \brief Set end of data region. + * \param hTpEnc Transport encoder handle. + * \param reg Data region ID, opbtained from transportEnc_CrcStartReg(). + * \return void + */ +void transportEnc_CrcEndReg(HANDLE_TRANSPORTENC hTpEnc, int reg); + +/** + * \brief Get AudioSpecificConfig or StreamMuxConfig from transport encoder handle and write it to dataBuffer. + * \param hTpEnc Transport encoder handle. + * \param cc Pointer to the current and valid configuration contained in a CODER_CONFIG struct. + * \param dataBuffer Bitbuffer holding binary configuration. + * \param confType Pointer to an UINT where the configuration type is returned (0:ASC, 1:SMC). + * \return Error code. + */ +TRANSPORTENC_ERROR transportEnc_GetConf( HANDLE_TRANSPORTENC hTpEnc, + CODER_CONFIG *cc, + FDK_BITSTREAM *dataBuffer, + UINT *confType ); + +/** + * \brief Get information (version among other things) of the transport encoder library. + * \param info Pointer to an allocated LIB_INFO struct. + * \return Error code. + */ +TRANSPORTENC_ERROR transportEnc_GetLibInfo( LIB_INFO *info ); + +#endif /* #ifndef __TPENC_LIB_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libPCMutils/include/limiter.h b/services/multimedia/audio/codec/fdkaac_codec/libPCMutils/include/limiter.h new file mode 100644 index 0000000..ca5eeb7 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libPCMutils/include/limiter.h @@ -0,0 +1,233 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/************************ FDK PCM postprocessor module ********************* + + Author(s): Matthias Neusinger + Description: Hard limiter for clipping prevention + +*******************************************************************************/ + +#ifndef _LIMITER_H_ +#define _LIMITER_H_ + + +#include "common_fix.h" + +#define TDL_ATTACK_DEFAULT_MS (15) /* default attack time in ms */ +#define TDL_RELEASE_DEFAULT_MS (50) /* default release time in ms */ + +#define TDL_GAIN_SCALING (15) /* scaling of gain value. */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef enum { + TDLIMIT_OK = 0, + + __error_codes_start = -100, + + TDLIMIT_INVALID_HANDLE, + TDLIMIT_INVALID_PARAMETER, + + __error_codes_end +} TDLIMITER_ERROR; + +struct TDLimiter; +typedef struct TDLimiter* TDLimiterPtr; + +/****************************************************************************** +* createLimiter * +* maxAttackMs: maximum and initial attack/lookahead time in milliseconds * +* releaseMs: release time in milliseconds (90% time constant) * +* threshold: limiting threshold * +* maxChannels: maximum and initial number of channels * +* maxSampleRate: maximum and initial sampling rate in Hz * +* returns: limiter handle * +******************************************************************************/ +TDLimiterPtr createLimiter(unsigned int maxAttackMs, + unsigned int releaseMs, + INT_PCM threshold, + unsigned int maxChannels, + unsigned int maxSampleRate); + + +/****************************************************************************** +* resetLimiter * +* limiter: limiter handle * +* returns: error code * +******************************************************************************/ +TDLIMITER_ERROR resetLimiter(TDLimiterPtr limiter); + + +/****************************************************************************** +* destroyLimiter * +* limiter: limiter handle * +* returns: error code * +******************************************************************************/ +TDLIMITER_ERROR destroyLimiter(TDLimiterPtr limiter); + +/****************************************************************************** +* applyLimiter * +* limiter: limiter handle * +* pGain : pointer to gains to be applied to the signal before limiting, * +* which are downscaled by TDL_GAIN_SCALING bit. * +* These gains are delayed by gain_delay, and smoothed. * +* Smoothing is done by a butterworth lowpass filter with a cutoff * +* frequency which is fixed with respect to the sampling rate. * +* It is a substitute for the smoothing due to windowing and * +* overlap/add, if a gain is applied in frequency domain. * +* gain_scale: pointer to scaling exponents to be applied to the signal before * +* limiting, without delay and without smoothing * +* gain_size: number of elements in pGain, currently restricted to 1 * +* gain_delay: delay [samples] with which the gains in pGain shall be applied * +* gain_delay <= nSamples * +* samples: input/output buffer containing interleaved samples * +* precision of output will be DFRACT_BITS-TDL_GAIN_SCALING bits * +* nSamples: number of samples per channel * +* returns: error code * +******************************************************************************/ +TDLIMITER_ERROR applyLimiter(TDLimiterPtr limiter, + INT_PCM* samples, + FIXP_DBL* pGain, + const INT* gain_scale, + const UINT gain_size, + const UINT gain_delay, + const UINT nSamples); + +/****************************************************************************** +* getLimiterDelay * +* limiter: limiter handle * +* returns: exact delay caused by the limiter in samples * +******************************************************************************/ +unsigned int getLimiterDelay(TDLimiterPtr limiter); + +/****************************************************************************** +* setLimiterNChannels * +* limiter: limiter handle * +* nChannels: number of channels ( <= maxChannels specified on create) * +* returns: error code * +******************************************************************************/ +TDLIMITER_ERROR setLimiterNChannels(TDLimiterPtr limiter, unsigned int nChannels); + +/****************************************************************************** +* setLimiterSampleRate * +* limiter: limiter handle * +* sampleRate: sampling rate in Hz ( <= maxSampleRate specified on create) * +* returns: error code * +******************************************************************************/ +TDLIMITER_ERROR setLimiterSampleRate(TDLimiterPtr limiter, unsigned int sampleRate); + +/****************************************************************************** +* setLimiterAttack * +* limiter: limiter handle * +* attackMs: attack time in ms ( <= maxAttackMs specified on create) * +* returns: error code * +******************************************************************************/ +TDLIMITER_ERROR setLimiterAttack(TDLimiterPtr limiter, unsigned int attackMs); + +/****************************************************************************** +* setLimiterRelease * +* limiter: limiter handle * +* releaseMs: release time in ms * +* returns: error code * +******************************************************************************/ +TDLIMITER_ERROR setLimiterRelease(TDLimiterPtr limiter, unsigned int releaseMs); + +/****************************************************************************** +* setLimiterThreshold * +* limiter: limiter handle * +* threshold: limiter threshold * +* returns: error code * +******************************************************************************/ +TDLIMITER_ERROR setLimiterThreshold(TDLimiterPtr limiter, INT_PCM threshold); + +#ifdef __cplusplus +} +#endif + + +#endif //#ifndef _LIMITER_H_ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libPCMutils/include/pcmutils_lib.h b/services/multimedia/audio/codec/fdkaac_codec/libPCMutils/include/pcmutils_lib.h new file mode 100644 index 0000000..5a32358 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libPCMutils/include/pcmutils_lib.h @@ -0,0 +1,334 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/************************ FDK PCM up/downmixing module ********************* + + Author(s): Christian Griebel + Description: Declares functions to interface with the PCM downmix processing + module. + +*******************************************************************************/ + +#ifndef _PCMUTILS_LIB_H_ +#define _PCMUTILS_LIB_H_ + +#include "machine_type.h" +#include "common_fix.h" +#include "FDK_audio.h" +#include "FDK_bitstream.h" + + +/* ------------------------ * + * ERROR CODES: * + * ------------------------ */ +typedef enum +{ + PCMDMX_OK = 0x0, /*!< No error happened. */ + + pcm_dmx_fatal_error_start, + PCMDMX_OUT_OF_MEMORY = 0x2, /*!< Not enough memory to set up an instance of the module. */ + PCMDMX_UNKNOWN = 0x5, /*!< Error condition is of unknown reason, or from a third + party module. */ + pcm_dmx_fatal_error_end, + + PCMDMX_INVALID_HANDLE, /*!< The given instance handle is not valid. */ + PCMDMX_INVALID_ARGUMENT, /*!< One of the parameters handed over is invalid. */ + PCMDMX_INVALID_CH_CONFIG, /*!< The given channel configuration is not supported and thus + no processing was performed. */ + PCMDMX_INVALID_MODE, /*!< The set configuration/mode is not applicable. */ + PCMDMX_UNKNOWN_PARAM, /*!< The handed parameter is not known/supported. */ + PCMDMX_UNABLE_TO_SET_PARAM, /*!< Unable to set the specific parameter. Most probably the + value ist out of range. */ + PCMDMX_CORRUPT_ANC_DATA /*!< The read ancillary data was corrupt. */ + +} PCMDMX_ERROR; + +/** Macro to identify fatal errors. */ +#define PCMDMX_IS_FATAL_ERROR(err) ( (((err)>=pcm_dmx_fatal_error_start) && ((err)<=pcm_dmx_fatal_error_end)) ? 1 : 0) + +/* ------------------------ * + * RUNTIME PARAMS: * + * ------------------------ */ +typedef enum +{ + DMX_BS_DATA_EXPIRY_FRAME, /*!< The number of frames without new metadata that have to go + by before the bitstream data expires. The value 0 disables + expiry. */ + DMX_BS_DATA_DELAY, /*!< The number of delay frames of the output samples compared + to the bitstream data. */ + MIN_NUMBER_OF_OUTPUT_CHANNELS, /*!< The minimum number of output channels. For all input + configurations that have less than the given channels the + module will modify the output automatically to obtain the + given number of output channels. Mono signals will be + duplicated. If more than two output channels are desired + the module just adds empty channels. The parameter value + must be either -1, 0, 1, 2, 6 or 8. If the value is + greater than zero and exceeds the value of parameter + MAX_NUMBER_OF_OUTPUT_CHANNELS the latter will be set to + the same value. Both values -1 and 0 disable the feature. */ + MAX_NUMBER_OF_OUTPUT_CHANNELS, /*!< The maximum number of output channels. For all input + configurations that have more than the given channels the + module will apply a mixdown automatically to obtain the + given number of output channels. The value must be either + -1, 0, 1, 2, 6 or 8. If it is greater than zero and lower + or equal than the value of MIN_NUMBER_OF_OUTPUT_CHANNELS + parameter the latter will be set to the same value. + The values -1 and 0 disable the feature. */ + DMX_DUAL_CHANNEL_MODE, /*!< Downmix mode for two channel audio data. */ + DMX_PSEUDO_SURROUND_MODE /*!< Defines how module handles pseudo surround compatible + signals. See PSEUDO_SURROUND_MODE type for details. */ +} PCMDMX_PARAM; + +/* Parameter value types */ +typedef enum +{ + NEVER_DO_PS_DMX = -1, /*!< Never create a pseudo surround compatible downmix. */ + AUTO_PS_DMX = 0, /*!< Create a pseudo surround compatible downmix only if + signalled in bitstreams meta data. (Default) */ + FORCE_PS_DMX = 1 /*!< Always create a pseudo surround compatible downmix. + CAUTION: This can lead to excessive signal cancellations + and signal level differences for non-compatible signals. */ +} PSEUDO_SURROUND_MODE; + +typedef enum +{ + STEREO_MODE = 0x0, /*!< Leave stereo signals as they are. */ + CH1_MODE = 0x1, /*!< Create a dual mono output signal from channel 1. */ + CH2_MODE = 0x2, /*!< Create a dual mono output signal from channel 2. */ + MIXED_MODE = 0x3 /*!< Create a dual mono output signal by mixing the two + channels. */ +} DUAL_CHANNEL_MODE; + + +/* ------------------------ * + * MODULES INTERFACE: * + * ------------------------ */ +typedef struct PCM_DMX_INSTANCE *HANDLE_PCM_DOWNMIX; + +/* Modules reset flags */ +#define PCMDMX_RESET_PARAMS ( 1 ) +#define PCMDMX_RESET_BS_DATA ( 2 ) +#define PCMDMX_RESET_FULL ( PCMDMX_RESET_PARAMS | PCMDMX_RESET_BS_DATA ) + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** Open and initialize an instance of the PCM downmix module + * @param [out] Pointer to a buffer receiving the handle of the new instance. + * @returns Returns an error code. + **/ +PCMDMX_ERROR pcmDmx_Open ( + HANDLE_PCM_DOWNMIX *pSelf + ); + +/** Set one parameter for one instance of the PCM downmix module. + * @param [in] Handle of PCM downmix instance. + * @param [in] Parameter to be set. + * @param [in] Parameter value. + * @returns Returns an error code. + **/ +PCMDMX_ERROR pcmDmx_SetParam ( + HANDLE_PCM_DOWNMIX self, + const PCMDMX_PARAM param, + const INT value + ); + +/** Get one parameter value of one PCM downmix module instance. + * @param [in] Handle of PCM downmix module instance. + * @param [in] Parameter to be set. + * @param [out] Pointer to buffer receiving the parameter value. + * @returns Returns an error code. + **/ +PCMDMX_ERROR pcmDmx_GetParam ( + HANDLE_PCM_DOWNMIX self, + const PCMDMX_PARAM param, + INT * const pValue + ); + +/** Read downmix meta-data directly from a given bitstream. + * @param [in] Handle of PCM downmix instance. + * @param [in] Handle of FDK bitstream buffer. + * @param [in] Length of ancillary data in bits. + * @param [in] Flag indicating wheter the ancillary data is from a MPEG-1/2 or an MPEG-4 stream. + * @returns Returns an error code. + **/ +PCMDMX_ERROR pcmDmx_Parse ( + HANDLE_PCM_DOWNMIX self, + HANDLE_FDK_BITSTREAM hBitStream, + UINT ancDataBits, + int isMpeg2 + ); + +/** Read downmix meta-data from a given data buffer. + * @param [in] Handle of PCM downmix instance. + * @param [in] Pointer to ancillary data buffer. + * @param [in] Size of ancillary data in bytes. + * @param [in] Flag indicating wheter the ancillary data is from a MPEG-1/2 or an MPEG-4 stream. + * @returns Returns an error code. + **/ +PCMDMX_ERROR pcmDmx_ReadDvbAncData ( + HANDLE_PCM_DOWNMIX self, + UCHAR *pAncDataBuf, + UINT ancDataBytes, + int isMpeg2 + ); + +/** Set the matrix mixdown information extracted from the PCE of an AAC bitstream. + * @param [in] Handle of PCM downmix instance. + * @param [in] Matrix mixdown index present flag extracted from PCE. + * @param [in] The 2 bit matrix mixdown index extracted from PCE. + * @param [in] The pseudo surround enable flag extracted from PCE. + * @returns Returns an error code. + **/ +PCMDMX_ERROR pcmDmx_SetMatrixMixdownFromPce ( + HANDLE_PCM_DOWNMIX self, + int matrixMixdownPresent, + int matrixMixdownIdx, + int pseudoSurroundEnable + ); + +/** Reset the module. + * @param [in] Handle of PCM downmix instance. + * @param [in] Flags telling which parts of the module shall be reset. + * @returns Returns an error code. + **/ +PCMDMX_ERROR pcmDmx_Reset ( + HANDLE_PCM_DOWNMIX self, + UINT flags + ); + +/** Create a mixdown, bypass or extend the output signal depending on the modules settings and the + * respective given input configuration. + * + * \param [in] Handle of PCM downmix module instance. + * \param [inout] Pointer to time buffer with decoded PCM samples. + * \param [in] The I/O block size which is the number of samples per channel. + * \param [inout] Pointer to buffer that holds the number of input channels and where the + * amount of output channels is written to. + * \param [in] Flag which indicates if output time data is writtern interleaved or as + * subsequent blocks. + * \param [inout] Array were the corresponding channel type for each output audio channel is + * stored into. + * \param [inout] Array were the corresponding channel type index for each output audio channel + * is stored into. + * \param [in] Array containing the output channel mapping to be used (from MPEG PCE ordering + * to whatever is required). + * \param [out] Pointer on a field receiving the scale factor that has to be applied on all + * samples afterwards. If the handed pointer is NULL the final scaling is done + * internally. + * @returns Returns an error code. + **/ +PCMDMX_ERROR pcmDmx_ApplyFrame ( + HANDLE_PCM_DOWNMIX self, + INT_PCM *pPcmBuf, + UINT frameSize, + INT *nChannels, + int fInterleaved, + AUDIO_CHANNEL_TYPE channelType[], + UCHAR channelIndices[], + const UCHAR channelMapping[][8], + INT *pDmxOutScale + ); + +/** Close an instance of the PCM downmix module. + * @param [inout] Pointer to a buffer containing the handle of the instance. + * @returns Returns an error code. + **/ +PCMDMX_ERROR pcmDmx_Close ( + HANDLE_PCM_DOWNMIX *pSelf + ); + +/** Get library info for this module. + * @param [out] Pointer to an allocated LIB_INFO structure. + * @returns Returns an error code. + */ +PCMDMX_ERROR pcmDmx_GetLibInfo( LIB_INFO *info ); + + +#ifdef __cplusplus +} +#endif + +#endif /* _PCMUTILS_LIB_H_ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libSBRdec/include/sbrdecoder.h b/services/multimedia/audio/codec/fdkaac_codec/libSBRdec/include/sbrdecoder.h new file mode 100644 index 0000000..4fbaa1a --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libSBRdec/include/sbrdecoder.h @@ -0,0 +1,347 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/************************ Fraunhofer IIS SBR decoder library ****************** + + Author(s): + Description: SBR decoder front-end prototypes and definitions. + +******************************************************************************/ + +#ifndef __SBRDECODER_H +#define __SBRDECODER_H + +#include "common_fix.h" + +#include "FDK_bitstream.h" +#include "FDK_audio.h" + + +#define SBR_DEBUG_EXTHLP "\ +--- SBR ---\n\ + 0x00000010 Ancillary data and SBR-Header\n\ + 0x00000020 SBR-Side info\n\ + 0x00000040 Decoded SBR-bitstream data, e.g. envelope data\n\ + 0x00000080 SBR-Bitstream statistics\n\ + 0x00000100 Miscellaneous SBR-messages\n\ + 0x00000200 SBR-Energies and gains in the adjustor\n\ + 0x00000400 Fatal SBR errors\n\ + 0x00000800 Transposer coefficients for inverse filtering\n\ +" + +/* Capability flags */ +#define CAPF_SBR_LP 0x00000001 /*!< Flag indicating library's capability of Low Power mode. */ +#define CAPF_SBR_HQ 0x00000002 /*!< Flag indicating library's capability of High Quality mode. */ +#define CAPF_SBR_DRM_BS 0x00000004 /*!< Flag indicating library's capability to decode DRM SBR data. */ +#define CAPF_SBR_CONCEALMENT 0x00000008 /*!< Flag indicating library's capability to conceal erroneous frames. */ +#define CAPF_SBR_DRC 0x00000010 /*!< Flag indicating library's capability for Dynamic Range Control. */ +#define CAPF_SBR_PS_MPEG 0x00000020 /*!< Flag indicating library's capability to do MPEG Parametric Stereo. */ +#define CAPF_SBR_PS_DRM 0x00000040 /*!< Flag indicating library's capability to do DRM Parametric Stereo. */ + +typedef enum +{ + SBRDEC_OK = 0, /*!< All fine. */ + /* SBRDEC_CONCEAL, */ + /* SBRDEC_NOSYNCH, */ + /* SBRDEC_ILLEGAL_PROGRAM, */ + /* SBRDEC_ILLEGAL_TAG, */ + /* SBRDEC_ILLEGAL_CHN_CONFIG, */ + /* SBRDEC_ILLEGAL_SECTION, */ + /* SBRDEC_ILLEGAL_SCFACTORS, */ + /* SBRDEC_ILLEGAL_PULSE_DATA, */ + /* SBRDEC_MAIN_PROFILE_NOT_IMPLEMENTED, */ + /* SBRDEC_GC_NOT_IMPLEMENTED, */ + /* SBRDEC_ILLEGAL_PLUS_ELE_ID, */ + SBRDEC_CREATE_ERROR, /*!< */ + SBRDEC_NOT_INITIALIZED, /*!< */ + SBRDEC_MEM_ALLOC_FAILED, /*!< Memory allocation failed. Probably not enough memory available. */ + SBRDEC_PARSE_ERROR, /*!< */ + SBRDEC_UNSUPPORTED_CONFIG, /*!< */ + SBRDEC_SET_PARAM_FAIL /*!< */ +} SBR_ERROR; + +typedef enum +{ + SBR_SYSTEM_BITSTREAM_DELAY, /*!< System: Switch to enable an additional SBR bitstream delay of one frame. */ + SBR_QMF_MODE, /*!< Set QMF mode, either complex or low power. */ + SBR_LD_QMF_TIME_ALIGN, /*!< Set QMF type, either LD-MPS or CLDFB. Relevant for ELD streams only. */ + SBR_FLUSH_DATA, /*!< Set internal state to flush the decoder with the next process call. */ + SBR_CLEAR_HISTORY, /*!< Clear all internal states (delay lines, QMF states, ...). */ + SBR_BS_INTERRUPTION /*!< Signal bit stream interruption. Value is ignored. */ +} SBRDEC_PARAM; + +typedef struct SBR_DECODER_INSTANCE *HANDLE_SBRDECODER; + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** + * \brief Allocates and initializes one SBR decoder instance. + * \param pSelf Pointer to where a SBR decoder handle is copied into. + * \return Error code. + */ +SBR_ERROR sbrDecoder_Open ( HANDLE_SBRDECODER *pSelf ); + +/** + * \brief Initialize a SBR decoder runtime instance. Must be called before decoding starts. + * + * \param self Handle to a SBR decoder instance. + * \param sampleRateIn Input samplerate of the SBR decoder instance. + * \param sampleRateOut Output samplerate of the SBR decoder instance. + * \param samplesPerFrame Number of samples per frames. + * \param coreCodec Audio Object Type (AOT) of the core codec. + * \param elementID Table with MPEG-4 element Ids in canonical order. + * \param forceReset Flag that enforces a complete decoder reset. + * + * \return Error code. + */ +SBR_ERROR sbrDecoder_InitElement ( + HANDLE_SBRDECODER self, + const int sampleRateIn, + const int sampleRateOut, + const int samplesPerFrame, + const AUDIO_OBJECT_TYPE coreCodec, + const MP4_ELEMENT_ID elementID, + const int elementIndex + ); + +/** + * \brief pass out of band SBR header to SBR decoder + * + * \param self Handle to a SBR decoder instance. + * \param hBs bit stream handle data source. + * \param elementID SBR element ID. + * \param elementIndex SBR element index. + * + * \return Error code. + */ +INT sbrDecoder_Header ( + HANDLE_SBRDECODER self, + HANDLE_FDK_BITSTREAM hBs, + const INT sampleRateIn, + const INT sampleRateOut, + const INT samplesPerFrame, + const AUDIO_OBJECT_TYPE coreCodec, + const MP4_ELEMENT_ID elementID, + const INT elementIndex + ); + +/** + * \brief Set a parameter of the SBR decoder runtime instance. + * \param self SBR decoder handle. + * \param param Parameter which will be set if successfull. + * \param value New parameter value. + * \return Error code. + */ +SBR_ERROR sbrDecoder_SetParam ( HANDLE_SBRDECODER self, + const SBRDEC_PARAM param, + const INT value ); + +/** + * \brief Feed DRC channel data into a SBR decoder runtime instance. + * + * \param self SBR decoder handle. + * \param ch Channel number to which the DRC data is associated to. + * \param numBands Number of DRC bands. + * \param pNextFact_mag Pointer to a table with the DRC factor magnitudes. + * \param nextFact_exp Exponent for all DRC factors. + * \param drcInterpolationScheme DRC interpolation scheme. + * \param winSequence Window sequence from core coder (eight short or one long window). + * \param pBandTop Pointer to a table with the top borders for all DRC bands. + * + * \return Error code. + */ +SBR_ERROR sbrDecoder_drcFeedChannel ( HANDLE_SBRDECODER self, + INT ch, + UINT numBands, + FIXP_DBL *pNextFact_mag, + INT nextFact_exp, + SHORT drcInterpolationScheme, + UCHAR winSequence, + USHORT *pBandTop ); + +/** + * \brief Disable SBR DRC for a certain channel. + * + * \param hSbrDecoder SBR decoder handle. + * \param ch Number of the channel that has to be disabled. + * + * \return None. + */ +void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self, + INT ch ); + + +/** + * \brief Parse one SBR element data extension data block. The bit stream position will + * be placed at the end of the SBR payload block. The remaining bits will be returned + * into *count if a payload length is given (byPayLen > 0). If no SBR payload length is + * given (bsPayLen < 0) then the bit stream position on return will be random after this + * function call in case of errors, and any further decoding will be completely pointless. + * This function accepts either normal ordered SBR data or reverse ordered DRM SBR data. + * + * \param self SBR decoder handle. + * \param hBs Bit stream handle as data source. + * \param count Pointer to an integer where the amount of parsed SBR payload bits is stored into. + * \param bsPayLen If > 0 this value is the SBR payload length. If < 0, the SBR payload length is unknown. + * \param flags CRC flag (0: EXT_SBR_DATA; 1: EXT_SBR_DATA_CRC) + * \param prev_element Previous MPEG-4 element ID. + * \param element_index Index of the current element. + * + * \return Error code. + */ +SBR_ERROR sbrDecoder_Parse ( + HANDLE_SBRDECODER self, + HANDLE_FDK_BITSTREAM hBs, + int *count, + int bsPayLen, + int crcFlag, + MP4_ELEMENT_ID prev_element, + int element_index, + int fGlobalIndependencyFlag + ); + +/** + * \brief This function decodes the given SBR bitstreams and applies SBR to the given time data. + * + * SBR-processing works InPlace. I.e. the calling function has to provide + * a time domain buffer timeData which can hold the completely decoded + * result. + * + * Left and right channel are read and stored according to the + * interleaving flag, frame length and number of channels. + * + * \param self Handle of an open SBR decoder instance. + * \param hSbrBs SBR Bitstream handle. + * \param timeData Pointer to input and finally upsampled output data. + * \param numChannels Pointer to a buffer holding the number of channels in time data buffer. + * \param sampleRate Output samplerate. + * \param channelMapping Channel mapping indices. + * \param interleaved Flag indicating if time data is stored interleaved (1: Interleaved time data, 0: non-interleaved timedata). + * \param coreDecodedOk Flag indicating if the core decoder did not find any error (0: core decoder found errors, 1: no errors). + * \param psDecoded Pointer to a buffer holding a flag. Input: PS is possible, Output: PS has been rendered. + * + * \return Error code. + */ +SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self, + INT_PCM *timeData, + int *numChannels, + int *sampleRate, + const UCHAR channelMapping[(8)], + const int interleaved, + const int coreDecodedOk, + UCHAR *psDecoded ); + + +/** + * \brief Close SBR decoder instance and free memory. + * \param self SBR decoder handle. + * \return Error Code. + */ +SBR_ERROR sbrDecoder_Close ( HANDLE_SBRDECODER *self ); + + +/** + * \brief Get SBR decoder library information. + * \param info Pointer to a LIB_INFO struct, where library information is written to. + * \return 0 on success, -1 if invalid handle or if no free element is available to write information to. + */ +INT sbrDecoder_GetLibInfo( LIB_INFO *info ); + +/** + * \brief Determine the modules output signal delay in samples. + * \param self SBR decoder handle. + * \return The number of samples signal delay added by the module. + */ +UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self ); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/codec/fdkaac_codec/libSBRenc/include/sbr_encoder.h b/services/multimedia/audio/codec/fdkaac_codec/libSBRenc/include/sbr_encoder.h new file mode 100644 index 0000000..eb9cbd1 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libSBRenc/include/sbr_encoder.h @@ -0,0 +1,430 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/*************************** Fraunhofer IIS *********************** + + Author(s): + Description: SBR encoder top level processing prototype + +******************************************************************************/ + +#ifndef __SBR_ENCODER_H +#define __SBR_ENCODER_H + +#include "common_fix.h" +#include "FDK_audio.h" + +#include "FDK_bitstream.h" + +/* core coder helpers */ +#define MAX_TRANS_FAC 8 +#define MAX_CODEC_FRAME_RATIO 2 +#define MAX_PAYLOAD_SIZE 256 + +typedef enum codecType +{ + CODEC_AAC=0, + CODEC_AACLD=1, + CODEC_UNSPECIFIED=99 +} CODEC_TYPE; + + +typedef struct +{ + INT bitRate; + INT nChannels; + INT sampleFreq; + INT transFac; + INT standardBitrate; +} CODEC_PARAM; + +typedef enum +{ + SBR_MONO, + SBR_LEFT_RIGHT, + SBR_COUPLING, + SBR_SWITCH_LRC +} SBR_STEREO_MODE; + +/* bitstream syntax flags */ +enum +{ + SBR_SYNTAX_LOW_DELAY = 0x0001, + SBR_SYNTAX_SCALABLE = 0x0002, + SBR_SYNTAX_CRC = 0x0004, + SBR_SYNTAX_DRM_CRC = 0x0008 +}; + +typedef enum +{ + FREQ_RES_LOW = 0, + FREQ_RES_HIGH +} FREQ_RES; + +typedef struct +{ + CODEC_TYPE coreCoder; /*!< LC or ELD */ + UINT bitrateFrom; /*!< inclusive */ + UINT bitrateTo; /*!< exclusive */ + + UINT sampleRate; /*!< */ + UCHAR numChannels; /*!< */ + + UCHAR startFreq; /*!< bs_start_freq */ + UCHAR startFreqSpeech; /*!< bs_start_freq for speech config flag */ + UCHAR stopFreq; /*!< bs_stop_freq */ + UCHAR stopFreqSpeech; /*!< bs_stop_freq for speech config flag */ + + UCHAR numNoiseBands; /*!< */ + UCHAR noiseFloorOffset; /*!< */ + SCHAR noiseMaxLevel; /*!< */ + SBR_STEREO_MODE stereoMode; /*!< */ + UCHAR freqScale; /*!< */ +} sbrTuningTable_t; + +typedef struct sbrConfiguration +{ + /* + core coder dependent configurations + */ + CODEC_PARAM codecSettings; /*!< Core coder settings. To be set from core coder. */ + INT SendHeaderDataTime; /*!< SBR header send update frequency in ms. */ + INT useWaveCoding; /*!< Flag: usage of wavecoding tool. */ + INT crcSbr; /*!< Flag: usage of SBR-CRC. */ + INT dynBwSupported; /*!< Flag: support for dynamic bandwidth in this combination. */ + INT parametricCoding; /*!< Flag: usage of parametric coding tool. */ + INT downSampleFactor; /*!< Sampling rate relation between the SBR and the core encoder. */ + FREQ_RES freq_res_fixfix[2];/*!< Frequency resolution of envelopes in frame class FIXFIX, for non-split case and split case */ + UCHAR fResTransIsLow; /*!< Frequency resolution of envelopes in transient frames: low (0) or variable (1) */ + + /* + core coder dependent tuning parameters + */ + INT tran_thr; /*!< SBR transient detector threshold (* 100). */ + INT noiseFloorOffset; /*!< Noise floor offset. */ + UINT useSpeechConfig; /*!< Flag: adapt tuning parameters according to speech. */ + + + + /* + core coder independent configurations + */ + INT sbrFrameSize; /*!< SBR frame size in samples. Will be calculated from core coder settings. */ + INT sbr_data_extra; /*!< Flag usage of data extra. */ + INT amp_res; /*!< Amplitude resolution. */ + INT ana_max_level; /*!< Noise insertion maximum level. */ + INT tran_fc; /*!< Transient detector start frequency. */ + INT tran_det_mode; /*!< Transient detector mode. */ + INT spread; /*!< Flag: usage of SBR spread. */ + INT stat; /*!< Flag: usage of static framing. */ + INT e; /*!< Number of envelopes when static framing is chosen. */ + SBR_STEREO_MODE stereoMode; /*!< SBR stereo mode. */ + INT deltaTAcrossFrames; /*!< Flag: allow time-delta coding. */ + FIXP_DBL dF_edge_1stEnv; /*!< Extra fraction delta-F coding is allowed to be more expensive. */ + FIXP_DBL dF_edge_incr; /*!< Increment dF_edge_1stEnv this much if dT-coding was used this frame. */ + INT sbr_invf_mode; /*!< Inverse filtering mode. */ + INT sbr_xpos_mode; /*!< Transposer mode. */ + INT sbr_xpos_ctrl; /*!< Transposer control. */ + INT sbr_xpos_level; /*!< Transposer 3rd order level. */ + INT startFreq; /*!< The start frequency table index. */ + INT stopFreq; /*!< The stop frequency table index. */ + INT useSaPan; /*!< Flag: usage of SAPAN stereo. */ + INT dynBwEnabled; /*!< Flag: usage of dynamic bandwidth. */ + INT bParametricStereo; /*!< Flag: usage of parametric stereo coding tool. */ + + /* + header_extra1 configuration + */ + UCHAR freqScale; /*!< Frequency grouping. */ + INT alterScale; /*!< Scale resolution. */ + INT sbr_noise_bands; /*!< Number of noise bands. */ + + + /* + header_extra2 configuration + */ + INT sbr_limiter_bands; /*!< Number of limiter bands. */ + INT sbr_limiter_gains; /*!< Gain of limiter. */ + INT sbr_interpol_freq; /*!< Flag: use interpolation in freq. direction. */ + INT sbr_smoothing_length; /*!< Flag: choose length 4 or 0 (=on, off). */ + UCHAR init_amp_res_FF; + FIXP_DBL threshold_AmpRes_FF_m; + SCHAR threshold_AmpRes_FF_e; +} sbrConfiguration, *sbrConfigurationPtr ; + +typedef struct SBR_CONFIG_DATA +{ + UINT sbrSyntaxFlags; /**< SBR syntax flags derived from AOT. */ + INT nChannels; /**< Number of channels. */ + + INT nSfb[2]; /**< Number of SBR scalefactor bands for LO_RES and HI_RES (?) */ + INT num_Master; /**< Number of elements in v_k_master. */ + INT sampleFreq; /**< SBR sampling frequency. */ + INT frameSize; + INT xOverFreq; /**< The SBR start frequency. */ + INT dynXOverFreq; /**< Used crossover frequency when dynamic bandwidth is enabled. */ + INT noQmfBands; /**< Number of QMF frequency bands. */ + INT noQmfSlots; /**< Number of QMF slots. */ + + UCHAR *freqBandTable[2]; /**< Frequency table for low and hires, only MAX_FREQ_COEFFS/2 +1 coeffs actually needed for lowres. */ + UCHAR *v_k_master; /**< Master BandTable where freqBandTable is derived from. */ + + + SBR_STEREO_MODE stereoMode; + INT noEnvChannels; /**< Number of envelope channels. */ + + INT useWaveCoding; /**< Flag indicates whether to use wave coding at all. */ + INT useParametricCoding; /**< Flag indicates whether to use para coding at all. */ + INT xposCtrlSwitch; /**< Flag indicates whether to switch xpos ctrl on the fly. */ + INT switchTransposers; /**< Flag indicates whether to switch xpos on the fly . */ + UCHAR initAmpResFF; + FIXP_DBL thresholdAmpResFF_m; + SCHAR thresholdAmpResFF_e; +} SBR_CONFIG_DATA, *HANDLE_SBR_CONFIG_DATA; + +typedef struct { + MP4_ELEMENT_ID elType; + INT bitRate; + int instanceTag; + UCHAR fParametricStereo; + UCHAR nChannelsInEl; + UCHAR ChannelIndex[2]; +} SBR_ELEMENT_INFO; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SBR_ENCODER *HANDLE_SBR_ENCODER; + +/** + * \brief Get the max required input buffer size including delay balancing space + * for N audio channels. + * \param noChannels Number of audio channels. + * \return Max required input buffer size in bytes. + */ +INT sbrEncoder_GetInBufferSize(int noChannels); + +INT sbrEncoder_Open( + HANDLE_SBR_ENCODER *phSbrEncoder, + INT nElements, + INT nChannels, + INT supportPS + ); + +/** + * \brief Get closest working bitrate to specified desired + * bitrate for a single SBR element. + * \param bitRate The desired target bit rate + * \param numChannels The amount of audio channels + * \param coreSampleRate The sample rate of the core coder + * \param aot The current Audio Object Type + * \return Closest working bit rate to bitRate value + */ +UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate, AUDIO_OBJECT_TYPE aot); + + +/** + * \brief Check whether downsampled SBR single rate is possible + * with given audio object type. + * \param aot The Audio object type. + * \return 0 when downsampled SBR is not possible, + * 1 when downsampled SBR is possible. + */ +UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot); + +/** + * \brief Initialize SBR Encoder instance. + * \param phSbrEncoder Pointer to a SBR Encoder instance. + * \param elInfo Structure that describes the element/channel arrangement. + * \param noElements Amount of elements described in elInfo. + * \param inputBuffer Pointer to the encoder audio buffer + * \param bandwidth Returns the core audio encoder bandwidth (output) + * \param bufferOffset Returns the offset for the audio input data in order to do delay balancing. + * \param numChannels Input: Encoder input channels. output: core encoder channels. + * \param sampleRate Input: Encoder samplerate. output core encoder samplerate. + * \param downSampleFactor Input: Relation between SBR and core coder sampling rate; + * \param frameLength Input: Encoder frameLength. output core encoder frameLength. + * \param aot Input: Desired AOT. output AOT to be used after parameter checking. + * \param delay Input: core encoder delay. Output: total delay because of SBR. + * \param transformFactor The core encoder transform factor (blockswitching). + * \param headerPeriod Repetition rate of the SBR header: + * - (-1) means intern configuration. + * - (1-10) corresponds to header repetition rate in frames. + * \return 0 on success, and non-zero if failed. + */ +INT sbrEncoder_Init( + HANDLE_SBR_ENCODER hSbrEncoder, + SBR_ELEMENT_INFO elInfo[(8)], + int noElements, + INT_PCM *inputBuffer, + INT *coreBandwidth, + INT *inputBufferOffset, + INT *numChannels, + INT *sampleRate, + UINT *downSampleFactor, + INT *frameLength, + AUDIO_OBJECT_TYPE aot, + int *delay, + int transformFactor, + const int headerPeriod, + ULONG statesInitFlag + ); + +/** + * \brief Do delay line buffers housekeeping. To be called after each encoded audio frame. + * \param hEnvEnc SBR Encoder handle. + * \param timeBuffer Pointer to the encoder audio buffer. + * \return 0 on success, and non-zero if failed. + */ +INT sbrEncoder_UpdateBuffers(HANDLE_SBR_ENCODER hEnvEnc, + INT_PCM *timeBuffer + ); + +/** + * \brief Close SBR encoder instance. + * \param phEbrEncoder Handle of SBR encoder instance to be closed. + * \return void + */ +void sbrEncoder_Close(HANDLE_SBR_ENCODER *phEbrEncoder); + +/** + * \brief Encode SBR data of one complete audio frame. + * \param hEnvEncoder Handle of SBR encoder instance. + * \param samples Time samples, always interleaved. + * \param timeInStride Channel stride factor of samples buffer. + * \param sbrDataBits Size of SBR payload in bits. + * \param sbrData SBR payload. + * \return 0 on success, and non-zero if failed. + */ +INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, + INT_PCM *samples, + UINT timeInStride, + UINT sbrDataBits[(8)], + UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE] + ); + +/** + * \brief Write SBR headers of one SBR element. + * \param sbrEncoder Handle of the SBR encoder instance. + * \param hBs Handle of bit stream handle to write SBR header to. + * \param element_index Index of the SBR element which header should be written. + * \param fSendHeaders Flag indicating that the SBR encoder should send more headers in the SBR payload or not. + * \return void + */ +void sbrEncoder_GetHeader(HANDLE_SBR_ENCODER sbrEncoder, + HANDLE_FDK_BITSTREAM hBs, + INT element_index, + int fSendHeaders); + +/** + * \brief SBR encoder bitrate estimation. + * \param hSbrEncoder SBR encoder handle. + * \return Estimated bitrate. + */ +INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder); + + +/** + * \brief Delay between input data and downsampled output data. + * \param hSbrEncoder SBR encoder handle. + * \return Delay. + */ +INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder); + +/** + * \brief Get decoder library version info. + * \param info Pointer to an allocated LIB_INFO struct, where library info is written to. + * \return 0 on sucess. + */ +INT sbrEncoder_GetLibInfo(LIB_INFO *info); + +void sbrPrintRAM(void); + +void sbrPrintROM(void); + +#ifdef __cplusplus + } +#endif + +#endif /* ifndef __SBR_MAIN_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/FDK_audio.h b/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/FDK_audio.h new file mode 100644 index 0000000..f335792 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/FDK_audio.h @@ -0,0 +1,633 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/************************** Fraunhofer IIS FDK SysLib ********************** + + Author(s): Manuel Jander + +******************************************************************************/ + +/** \file FDK_audio.h + * \brief Global audio struct and constant definitions. + */ + +#ifndef FDK_AUDIO_H +#define FDK_AUDIO_H + +#include "machine_type.h" +#include "genericStds.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * File format identifiers. + */ +typedef enum +{ + FF_UNKNOWN = -1, /**< Unknown format. */ + FF_RAW = 0, /**< No container, bit stream data conveyed "as is". */ + + FF_MP4_3GPP = 3, /**< 3GPP file format. */ + FF_MP4_MP4F = 4, /**< MPEG-4 File format. */ + + FF_RAWPACKETS = 5, /**< Proprietary raw packet file. */ + + FF_DRMCT = 12 /**< Digital Radio Mondial (DRM30/DRM+) CT proprietary file format. */ + +} FILE_FORMAT; + +/** + * Transport type identifiers. + */ +typedef enum +{ + TT_UNKNOWN = -1, /**< Unknown format. */ + TT_MP4_RAW = 0, /**< "as is" access units (packet based since there is obviously no sync layer) */ + TT_MP4_ADIF = 1, /**< ADIF bitstream format. */ + TT_MP4_ADTS = 2, /**< ADTS bitstream format. */ + + TT_MP4_LATM_MCP1 = 6, /**< Audio Mux Elements with muxConfigPresent = 1 */ + TT_MP4_LATM_MCP0 = 7, /**< Audio Mux Elements with muxConfigPresent = 0, out of band StreamMuxConfig */ + + TT_MP4_LOAS = 10, /**< Audio Sync Stream. */ + + TT_DRM = 12 /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */ + +} TRANSPORT_TYPE; + +#define TT_IS_PACKET(x) \ + ( ((x) == TT_MP4_RAW) \ + || ((x) == TT_DRM) \ + || ((x) == TT_MP4_LATM_MCP0) \ + || ((x) == TT_MP4_LATM_MCP1) ) + +/** + * Audio Object Type definitions. + */ +typedef enum +{ + AOT_NONE = -1, + AOT_NULL_OBJECT = 0, + AOT_AAC_MAIN = 1, /**< Main profile */ + AOT_AAC_LC = 2, /**< Low Complexity object */ + AOT_AAC_SSR = 3, + AOT_AAC_LTP = 4, + AOT_SBR = 5, + AOT_AAC_SCAL = 6, + AOT_TWIN_VQ = 7, + AOT_CELP = 8, + AOT_HVXC = 9, + AOT_RSVD_10 = 10, /**< (reserved) */ + AOT_RSVD_11 = 11, /**< (reserved) */ + AOT_TTSI = 12, /**< TTSI Object */ + AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */ + AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */ + AOT_GEN_MIDI = 15, /**< General MIDI object */ + AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */ + AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */ + AOT_RSVD_18 = 18, /**< (reserved) */ + AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */ + AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */ + AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */ + AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */ + AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */ + AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */ + AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */ + AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */ + AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */ + AOT_RSVD_28 = 28, /**< might become SSC */ + AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */ + AOT_MPEGS = 30, /**< MPEG Surround */ + + AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */ + + AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */ + AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */ + AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */ + AOT_RSVD_35 = 35, /**< might become DST */ + AOT_RSVD_36 = 36, /**< might become ALS */ + AOT_AAC_SLS = 37, /**< AAC + SLS */ + AOT_SLS = 38, /**< SLS */ + AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */ + + AOT_USAC = 42, /**< USAC */ + AOT_SAOC = 43, /**< SAOC */ + AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ + + /* Pseudo AOTs */ + AOT_DRM_AAC = 143, /**< Virtual AOT for DRM (ER-AAC-SCAL without SBR) */ + AOT_DRM_SBR = 144, /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR) */ + AOT_DRM_MPEG_PS = 145 /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR and MPEG-PS) */ + +} AUDIO_OBJECT_TYPE; + +#define CAN_DO_PS(aot) \ + ((aot) == AOT_AAC_LC \ +|| (aot) == AOT_SBR \ +|| (aot) == AOT_PS \ +|| (aot) == AOT_ER_BSAC \ +|| (aot) == AOT_DRM_AAC) + +#define IS_USAC(aot) \ + ((aot) == AOT_USAC) + +#define IS_LOWDELAY(aot) \ + ((aot) == AOT_ER_AAC_LD \ +|| (aot) == AOT_ER_AAC_ELD) + +/** Channel Mode ( 1-7 equals MPEG channel configurations, others are arbitrary). */ +typedef enum { + MODE_INVALID = -1, + MODE_UNKNOWN = 0, + MODE_1 = 1, /**< C */ + MODE_2 = 2, /**< L+R */ + MODE_1_2 = 3, /**< C, L+R */ + MODE_1_2_1 = 4, /**< C, L+R, Rear */ + MODE_1_2_2 = 5, /**< C, L+R, LS+RS */ + MODE_1_2_2_1 = 6, /**< C, L+R, LS+RS, LFE */ + MODE_1_2_2_2_1 = 7, /**< C, LC+RC, L+R, LS+RS, LFE */ + + + MODE_1_1 = 16, /**< 2 SCEs (dual mono) */ + MODE_1_1_1_1 = 17, /**< 4 SCEs */ + MODE_1_1_1_1_1_1 = 18, /**< 6 SCEs */ + MODE_1_1_1_1_1_1_1_1 = 19, /**< 8 SCEs */ + MODE_1_1_1_1_1_1_1_1_1_1_1_1 = 20, /**< 12 SCEs */ + + MODE_2_2 = 21, /**< 2 CPEs */ + MODE_2_2_2 = 22, /**< 3 CPEs */ + MODE_2_2_2_2 = 23, /**< 4 CPEs */ + MODE_2_2_2_2_2_2 = 24, /**< 6 CPEs */ + + MODE_2_1 = 30, /**< CPE,SCE (ARIB standard B32) */ + + MODE_7_1_REAR_SURROUND = 33, /**< C, L+R, LS+RS, Lrear+Rrear, LFE */ + MODE_7_1_FRONT_CENTER = 34 /**< C, LC+RC, L+R, LS+RS, LFE */ + +} CHANNEL_MODE; + +/** + * Speaker description tags. + * Do not change the enumeration values unless it keeps the following segmentation: + * - Bit 0-3: Horizontal postion (0: none, 1: front, 2: side, 3: back, 4: lfe) + * - Bit 4-7: Vertical position (0: normal, 1: top, 2: bottom) + */ +typedef enum { + ACT_NONE = 0x00, + ACT_FRONT = 0x01, /*!< Front speaker position (at normal height) */ + ACT_SIDE = 0x02, /*!< Side speaker position (at normal height) */ + ACT_BACK = 0x03, /*!< Back speaker position (at normal height) */ + ACT_LFE = 0x04, /*!< Low frequency effect speaker postion (front) */ + + ACT_TOP = 0x10, /*!< Top speaker area (for combination with speaker positions) */ + ACT_FRONT_TOP = 0x11, /*!< Top front speaker = (ACT_FRONT|ACT_TOP) */ + ACT_SIDE_TOP = 0x12, /*!< Top side speaker = (ACT_SIDE |ACT_TOP) */ + ACT_BACK_TOP = 0x13, /*!< Top back speaker = (ACT_BACK |ACT_TOP) */ + + ACT_BOTTOM = 0x20, /*!< Bottom speaker area (for combination with speaker positions) */ + ACT_FRONT_BOTTOM = 0x21, /*!< Bottom front speaker = (ACT_FRONT|ACT_BOTTOM) */ + ACT_SIDE_BOTTOM = 0x22, /*!< Bottom side speaker = (ACT_SIDE |ACT_BOTTOM) */ + ACT_BACK_BOTTOM = 0x23 /*!< Bottom back speaker = (ACT_BACK |ACT_BOTTOM) */ + +} AUDIO_CHANNEL_TYPE; + +typedef enum +{ + SIG_UNKNOWN = -1, + SIG_IMPLICIT = 0, + SIG_EXPLICIT_BW_COMPATIBLE = 1, + SIG_EXPLICIT_HIERARCHICAL = 2 + +} SBR_PS_SIGNALING; + +/** + * Audio Codec flags. + */ +#define AC_ER_VCB11 0x000001 /*!< aacSectionDataResilienceFlag flag (from ASC): 1 means use virtual codebooks */ +#define AC_ER_RVLC 0x000002 /*!< aacSpectralDataResilienceFlag flag (from ASC): 1 means use huffman codeword reordering */ +#define AC_ER_HCR 0x000004 /*!< aacSectionDataResilienceFlag flag (from ASC): 1 means use virtual codebooks */ +#define AC_SCALABLE 0x000008 /*!< AAC Scalable*/ +#define AC_ELD 0x000010 /*!< AAC-ELD */ +#define AC_LD 0x000020 /*!< AAC-LD */ +#define AC_ER 0x000040 /*!< ER syntax */ +#define AC_BSAC 0x000080 /*!< BSAC */ +#define AC_USAC 0x000100 /*!< USAC */ +#define AC_USAC_TW 0x000200 /*!< USAC time warped filter bank is active */ +#define AC_USAC_NOISE 0x000400 /*!< USAC noise filling is active */ +#define AC_USAC_HBE 0x000800 /*!< USAC harmonic bandwidth extension is active */ +#define AC_RSVD50 0x001000 /*!< Rsvd50 */ +#define AC_SBR_PRESENT 0x002000 /*!< SBR present flag (from ASC) */ +#define AC_SBRCRC 0x004000 /*!< SBR CRC present flag. Only relevant for AAC-ELD for now. */ +#define AC_PS_PRESENT 0x008000 /*!< PS present flag (from ASC or implicit) */ +#define AC_MPS_PRESENT 0x010000 /*!< MPS present flag (from ASC or implicit) */ +#define AC_DRM 0x020000 /*!< DRM bit stream syntax */ +#define AC_INDEP 0x040000 /*!< Independency flag */ +#define AC_MPS_RES 0x080000 /*!< MPS residual individual channel data. */ +#define AC_DAB 0x800000 /*!< DAB bit stream syntax */ +#define AC_LD_MPS 0x01000000 /*!< Low Delay MPS. */ + + +/* CODER_CONFIG::flags */ +#define CC_MPEG_ID 0x00100000 +#define CC_IS_BASELAYER 0x00200000 +#define CC_PROTECTION 0x00400000 +#define CC_SBR 0x00800000 +#define CC_SBRCRC 0x00010000 +#define CC_RVLC 0x01000000 +#define CC_VCB11 0x02000000 +#define CC_HCR 0x04000000 +#define CC_PSEUDO_SURROUND 0x08000000 +#define CC_USAC_NOISE 0x10000000 +#define CC_USAC_TW 0x20000000 +#define CC_USAC_HBE 0x40000000 + +/** Generic audio coder configuration structure. */ +typedef struct { + AUDIO_OBJECT_TYPE aot; /**< Audio Object Type (AOT). */ + AUDIO_OBJECT_TYPE extAOT; /**< Extension Audio Object Type (SBR). */ + CHANNEL_MODE channelMode; /**< Channel mode. */ + INT samplingRate; /**< Sampling rate. */ + INT extSamplingRate; /**< Extended samplerate (SBR). */ + INT bitRate; /**< Average bitrate. */ + int samplesPerFrame; /**< Number of PCM samples per codec frame and audio channel. */ + int noChannels; /**< Number of audio channels. */ + int bitsFrame; + int nSubFrames; /**< Amount of encoder subframes. 1 means no subframing. */ + int BSACnumOfSubFrame; /**< The number of the sub-frames which are grouped and transmitted in a super-frame (BSAC). */ + int BSAClayerLength; /**< The average length of the large-step layers in bytes (BSAC). */ + UINT flags; /**< flags */ + UCHAR matrixMixdownA; /**< Matrix mixdown index to put into PCE. Default value 0 means no mixdown coefficient, + valid values are 1-4 which correspond to matrix_mixdown_idx 0-3. */ + UCHAR headerPeriod; /**< Frame period for sending in band configuration buffers in the transport layer. */ + + UCHAR stereoConfigIndex; /**< USAC MPS stereo mode */ + UCHAR sbrMode; /**< USAC SBR mode */ + SBR_PS_SIGNALING sbrSignaling;/**< 0: implicit signaling, 1: backwards compatible explicit signaling, 2: hierarcical explicit signaling */ + + UCHAR sbrPresent; + UCHAR psPresent; +} CODER_CONFIG; + +/** MP4 Element IDs. */ +typedef enum +{ + ID_NONE = -1, /**< Invalid Element helper ID. */ + ID_SCE = 0, /**< Single Channel Element. */ + ID_CPE = 1, /**< Channel Pair Element. */ + ID_CCE = 2, /**< Coupling Channel Element. */ + ID_LFE = 3, /**< LFE Channel Element. */ + ID_DSE = 4, /**< Currently one Data Stream Element for ancillary data is supported. */ + ID_PCE = 5, /**< Program Config Element. */ + ID_FIL = 6, /**< Fill Element. */ + ID_END = 7, /**< Arnie (End Element = Terminator). */ + ID_EXT = 8, /**< Extension Payload (ER only). */ + ID_SCAL = 9, /**< AAC scalable element (ER only). */ + ID_LAST +} MP4_ELEMENT_ID; + +#define IS_CHANNEL_ELEMENT(elementId) \ + ((elementId) == ID_SCE \ +|| (elementId) == ID_CPE \ +|| (elementId) == ID_LFE) + +#define EXT_ID_BITS 4 /**< Size in bits of extension payload type tags. */ + +/** Extension payload types. */ +typedef enum { + EXT_FIL = 0x00, + EXT_FILL_DATA = 0x01, + EXT_DATA_ELEMENT = 0x02, + EXT_DATA_LENGTH = 0x03, + EXT_LDSAC_DATA = 0x09, + EXT_SAOC_DATA = 0x0a, + EXT_DYNAMIC_RANGE = 0x0b, + EXT_SAC_DATA = 0x0c, + EXT_SBR_DATA = 0x0d, + EXT_SBR_DATA_CRC = 0x0e +} EXT_PAYLOAD_TYPE; + + +/** + * Proprietary raw packet file configuration data type identifier. + */ +typedef enum +{ + TC_NOTHING = 0, /* No configuration available -> in-band configuration. */ + TC_RAW_ASC, /* Configuration data field is a raw AudioSpecificConfig. */ + TC_RAW_SMC, /* Configuration data field is a raw StreamMuxConfig. */ + TC_RAW_SDC /* Configuration data field is a raw Drm SDC. */ + +} TP_CONFIG_TYPE; + +/* + * ############################################################################################## + * Library identification and error handling + * ############################################################################################## + */ +/* \cond */ +#define MODULE_ID_MASK (0x000000ff) +#define MODULE_ID_SHIFT (24) + +typedef enum { + FDK_NONE = 0, + FDK_TOOLS = 1, + FDK_SYSLIB = 2, + FDK_AACDEC = 3, + FDK_AACENC = 4, + FDK_SBRDEC = 5, + FDK_SBRENC = 6, + FDK_TPDEC = 7, + FDK_TPENC = 8, + FDK_MPSDEC = 9, + FDK_MPEGFILEREAD = 10, + FDK_MPEGFILEWRITE = 11, + FDK_MP2DEC = 12, + FDK_DABDEC = 13, + FDK_DABPARSE = 14, + FDK_DRMDEC = 15, + FDK_DRMPARSE = 16, + FDK_AACLDENC = 17, + FDK_MP2ENC = 18, + FDK_MP3ENC = 19, + FDK_MP3DEC = 20, + FDK_MP3HEADPHONE = 21, + FDK_MP3SDEC = 22, + FDK_MP3SENC = 23, + FDK_EAEC = 24, + FDK_DABENC = 25, + FDK_DMBDEC = 26, + FDK_FDREVERB = 27, + FDK_DRMENC = 28, + FDK_METADATATRANSCODER = 29, + FDK_AC3DEC = 30, + FDK_PCMDMX = 31, + + FDK_MODULE_LAST + +} FDK_MODULE_ID; + +/* AAC capability flags */ +#define CAPF_AAC_LC 0x00000001 /**< Support flag for AAC Low Complexity. */ +#define CAPF_ER_AAC_LD 0x00000002 /**< Support flag for AAC Low Delay with Error Resilience tools. */ +#define CAPF_ER_AAC_SCAL 0x00000004 /**< Support flag for AAC Scalable. */ +#define CAPF_ER_AAC_LC 0x00000008 /**< Support flag for AAC Low Complexity with Error Resilience tools. */ +#define CAPF_AAC_480 0x00000010 /**< Support flag for AAC with 480 framelength. */ +#define CAPF_AAC_512 0x00000020 /**< Support flag for AAC with 512 framelength. */ +#define CAPF_AAC_960 0x00000040 /**< Support flag for AAC with 960 framelength. */ +#define CAPF_AAC_1024 0x00000080 /**< Support flag for AAC with 1024 framelength. */ +#define CAPF_AAC_HCR 0x00000100 /**< Support flag for AAC with Huffman Codeword Reordering. */ +#define CAPF_AAC_VCB11 0x00000200 /**< Support flag for AAC Virtual Codebook 11. */ +#define CAPF_AAC_RVLC 0x00000400 /**< Support flag for AAC Reversible Variable Length Coding. */ +#define CAPF_AAC_MPEG4 0x00000800 /**< Support flag for MPEG file format. */ +#define CAPF_AAC_DRC 0x00001000 /**< Support flag for AAC Dynamic Range Control. */ +#define CAPF_AAC_CONCEALMENT 0x00002000 /**< Support flag for AAC concealment. */ +#define CAPF_AAC_DRM_BSFORMAT 0x00004000 /**< Support flag for AAC DRM bistream format. */ +#define CAPF_ER_AAC_ELD 0x00008000 /**< Support flag for AAC Enhanced Low Delay with Error Resilience tools. */ +#define CAPF_ER_AAC_BSAC 0x00010000 /**< Support flag for AAC BSAC. */ +#define CAPF_AAC_SUPERFRAMING 0x00020000 /**< Support flag for AAC Superframing. */ + +/* Transport capability flags */ +#define CAPF_ADTS 0x00000001 /**< Support flag for ADTS transport format. */ +#define CAPF_ADIF 0x00000002 /**< Support flag for ADIF transport format. */ +#define CAPF_LATM 0x00000004 /**< Support flag for LATM transport format. */ +#define CAPF_LOAS 0x00000008 /**< Support flag for LOAS transport format. */ +#define CAPF_RAWPACKETS 0x00000010 /**< Support flag for RAW PACKETS transport format. */ +#define CAPF_DRM 0x00000020 /**< Support flag for DRM/DRM+ transport format. */ +#define CAPF_RSVD50 0x00000040 /**< Support flag for RSVD50 transport format */ + +/* SBR capability flags */ +#define CAPF_SBR_LP 0x00000001 /**< Support flag for SBR Low Power mode. */ +#define CAPF_SBR_HQ 0x00000002 /**< Support flag for SBR High Quality mode. */ +#define CAPF_SBR_DRM_BS 0x00000004 /**< Support flag for */ +#define CAPF_SBR_CONCEALMENT 0x00000008 /**< Support flag for SBR concealment. */ +#define CAPF_SBR_DRC 0x00000010 /**< Support flag for SBR Dynamic Range Control. */ +#define CAPF_SBR_PS_MPEG 0x00000020 /**< Support flag for MPEG Parametric Stereo. */ +#define CAPF_SBR_PS_DRM 0x00000040 /**< Support flag for DRM Parametric Stereo. */ + +/* MP2 encoder capability flags */ +#define CAPF_MP2ENC_SS 0x00000001 /**< Support flag for Seamless Switching. */ +#define CAPF_MP2ENC_DAB 0x00000002 /**< Support flag for Layer2 DAB. */ + +/* DAB capability flags */ +#define CAPF_DAB_MP2 0x00000001 /**< Support flag for Layer2 DAB. */ +#define CAPF_DAB_AAC 0x00000002 /**< Support flag for DAB+ (HE-AAC v2). */ +#define CAPF_DAB_PAD 0x00000004 /**< Support flag for PAD extraction. */ +#define CAPF_DAB_DRC 0x00000008 /**< Support flag for Dynamic Range Control. */ +#define CAPF_DAB_SURROUND 0x00000010 /**< Support flag for DAB Surround (MPS). */ + +/* DMB capability flags */ +#define CAPF_DMB_BSAC 0x00000001 /**< Support flag for ER AAC BSAC. */ +#define CAPF_DMB_DRC 0x00000008 /**< Support flag for Dynamic Range Control. */ +#define CAPF_DMB_SURROUND 0x00000010 /**< Support flag for DMB Surround (MPS). */ + +/* PCM up/downmmix capability flags */ +#define CAPF_DMX_BLIND 0x00000001 /**< Support flag for blind downmixing. */ +#define CAPF_DMX_PCE 0x00000002 /**< Support flag for guided downmix with data from MPEG-2/4 Program Config Elements (PCE). */ +#define CAPF_DMX_ARIB 0x00000004 /**< Support flag for PCE guided downmix with slightly different equations and levels to fulfill ARIB standard. */ +#define CAPF_DMX_DVB 0x00000008 /**< Support flag for guided downmix with data from DVB ancillary data fields. */ +#define CAPF_DMX_CH_EXP 0x00000010 /**< Support flag for simple upmixing by dublicating channels or adding zero channels. */ +/* \endcond */ + + +/* + * ############################################################################################## + * Library versioning + * ############################################################################################## + */ + +/** + * Convert each member of version numbers to one single numeric version representation. + * \param lev0 1st level of version number. + * \param lev1 2nd level of version number. + * \param lev2 3rd level of version number. + */ +#define LIB_VERSION(lev0, lev1, lev2) ((lev0<<24 & 0xff000000) | \ + (lev1<<16 & 0x00ff0000) | \ + (lev2<<8 & 0x0000ff00)) + +/** + * Build text string of version. + */ +#define LIB_VERSION_STRING(info) FDKsprintf((info)->versionStr, "%d.%d.%d", (((info)->version >> 24) & 0xff), (((info)->version >> 16) & 0xff), (((info)->version >> 8 ) & 0xff)) + +/** + * Library information. + */ +typedef struct LIB_INFO +{ + const char* title; + const char* build_date; + const char* build_time; + FDK_MODULE_ID module_id; + INT version; + UINT flags; + char versionStr[32]; +} LIB_INFO; + +/** Initialize library info. */ +static inline void FDKinitLibInfo( LIB_INFO* info ) +{ + int i; + + for (i = 0; i < FDK_MODULE_LAST; i++) { + info[i].module_id = FDK_NONE; + } +} + +/** Aquire supported features of library. */ +static inline UINT FDKlibInfo_getCapabilities( const LIB_INFO* info, FDK_MODULE_ID module_id ) +{ + int i; + + for (i=0; i + #ifndef _tstof /* For Visual Studio 6 */ + #ifdef _UNICODE + #include + #define _tstof(x) (float) wcstod(x, NULL) /* For Visual Studio 6 */ + #else + #define _tstof atof + #endif + #endif + + #ifndef _tstol /* For Visual Studio 6 */ + #ifdef _UNICODE + #define _tstol _wtol + #else + #define _tstol atol + #endif + #endif + + #ifndef _tstoi /* For Visual Studio 6 */ + #ifdef _UNICODE + #define _tstoi _wtoi + #else + #define _tstoi atoi + #endif + #endif + + #ifndef TEXTCHAR + #define TEXTCHAR char + #endif + + #ifndef _TEXT + #define _TEXT + #endif + +#else /* WIN32 */ + + #define TEXTCHAR char + #define _tcslen(a) FDKstrlen(a) + #define _tcscpy strcpy + #define _tcscmp FDKstrcmp + #define _tcsncmp FDKstrncmp + #define _tscanf scanf + #define _TEXT(x) x + #define _tfopen fopen + #define _ftprintf fprintf + #define _tcsncpy FDKstrncpy + #define _tstof FDKatof + #define _tstol FDKatol + #define _tstoi FDKatoi + #define _tcstol strtol + #define _istdigit isdigit +#endif /* WIN32 */ + +/* \endcond */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * Scans argc, argv and a scanf style format string for parameters and stores the + * values in the variable number of pointers passed to the function. + + For example: + \code + #define ARG_PARAM "(-a %d) (-v %1)" + #define ARG_VALUE &config->aot, &verbose + int nFoundArgs = IIS_ScanCmdl(argc, argv, ARG_PARAM, ARG_VALUE); + \endcode + wheras the wild-cards (\%d, \%1, ..) define the data type of the argument: + - \%1 boolean (e. g. -x) + - \%d integer (e. g. -x 23) + - \%f float (e. g. -x 3.4) + - \%y double (e. g. -x 31415926535897932384626433832795028841971693993751) + - \%s string (e. g. -x "file.dat") + - \%u unsigned character (e. g. -x 3) + - \%c signed character (e. g. -x -3) + More examples on how to use it are located in every (encoder/decoder) example framework. + + * \param argc Number of arguments. + * \param argv Complete character string of the command line arguments. + * \param pReqArgs A list of parameters and a corresponding list of memory addresses to + * assign each parameter to. + * + * \return Number of found arguments. + */ +INT IIS_ScanCmdl(INT argc, TEXTCHAR* argv[], const TEXTCHAR* pReqArgs, ...); + +#ifdef __cplusplus +} +#endif + +/** + * Reads a text file, assembles argc and argv parameters for each text line + * and calls the given function for each set of argc, argv parameters. + * + * \param param_filename Name of text file that should be parsed. + * \param pFunction Pointer to function that should be called for every text line found. + * + * \return 0 on success, 1 on failure. + */ +INT IIS_ProcessCmdlList(const TEXTCHAR* param_filename, int (*pFunction)(int, TEXTCHAR**)); + + +#endif /* __PARSER_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/conv_string.h b/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/conv_string.h new file mode 100644 index 0000000..5a0cef9 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/conv_string.h @@ -0,0 +1,136 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/************************** Fraunhofer IIS FDK SysLib ********************** + + Author(s): + +******************************************************************************/ + +/** \file conv_string.h + * \brief String conversion functions. + */ + +#ifndef _CONV_STRING_H +#define _CONV_STRING_H + + + +#include "genericStds.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * \brief Convert a bitbuffer to a hex string. + * \param string Hex string. + * \param charBuf Input buffer that has to be converted. + * \param charBufLength Size of the input buffer. + * \return Error code. + */ +INT charBuf2HexString(char *string, UCHAR *charBuf, INT charBufLength); + +/** + * \brief Convert a hex string to bits. + * \param string Hex string that has to be converted. + * \param charBuf Output buffer holding the bits, will be filled up with zeros. + * \param charBufLength Size of the output buffer. + * \return Error code. + */ +INT hexString2CharBuf(const char *string, UCHAR *charBuf, UINT charBufLength); + +/** + * \brief Convert a character representing a hex sign to the appropriate value. + * \param c Character that has to be converted. + * \return Converted value (value between 0 and 15), if 16, an error has occured. + */ +UCHAR hexChar2Dec(const char c); + +#ifdef __cplusplus +} +#endif + + +#endif /* _CONV_STRING_H */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/genericStds.h b/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/genericStds.h new file mode 100644 index 0000000..357b70a --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/genericStds.h @@ -0,0 +1,478 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/************************** Fraunhofer IIS FDK SysLib ********************** + + Author(s): + +******************************************************************************/ + +/** \file genericStds.h + \brief Generic Run-Time Support function wrappers and heap allocation monitoring. + */ + +#if !defined(__GENERICSTDS_H__) +#define __GENERICSTDS_H__ + +#include "machine_type.h" + + +/* Always increase verbosity of memory allocation in case of a debug built. DEBUG is defined globally in that case. */ +#if defined(DEBUG) || defined(FDK_DEBUG) +//#define MEMORY_MEASUREMENT +#endif + +#ifndef M_PI + #define M_PI 3.14159265358979323846 /*! Pi. Only used in example projects. */ +#endif + + +/* #define _CRT_SECURE_NO_DEPRECATE */ + + +/** + * Identifiers for various memory locations. They are used along with memory allocation + * functions like FDKcalloc_L() to specify the requested memory's location. + */ +typedef enum { + /* Internal */ + SECT_DATA_L1 = 0x2000, + SECT_DATA_L2, + SECT_DATA_L1_A, + SECT_DATA_L1_B, + SECT_CONSTDATA_L1, + + /* External */ + SECT_DATA_EXTERN = 0x4000, + SECT_CONSTDATA_EXTERN + +} MEMORY_SECTION; + + +/** + * The H_ prefix indicates header file version, the C_* prefix indicates the corresponding + * object version. + * + * Declaring memory areas requires to specify a unique name and a data type. Use the H_ macro + * for this purpose inside a header file. + * + * For defining a memory area your require additionally one or two sizes, depending if the + * memory should be organized into one or two dimensions. + * + * The macros containing the keyword AALLOC instead of ALLOC also do take care of returning + * aligned memory addresses (beyond the natural alignment of its type). The preprocesor macro + * ::ALIGNMENT_DEFAULT indicates the aligment to be used (this is hardware specific). + * + * The _L suffix indicates that the memory will be located in a specific section. This is + * useful to allocate critical memory section into fast internal SRAM for example. + * + */ + +#define H_ALLOC_MEM(name,type) type * Get ## name(int n=0); void Free ## name(type** p); \ + UINT GetRequiredMem ## name(void); + +/** See #H_ALLOC_MEM for description. */ +#define H_ALLOC_MEM_OVERLAY(name,type) type * Get ## name(int n=0); void Free ## name(type** p); \ + UINT GetRequiredMem ## name(void); + + + /** See #H_ALLOC_MEM for description. */ + #define C_ALLOC_MEM(name,type,num) \ + type * Get ## name(int n) { FDK_ASSERT((n) == 0); return ((type*)FDKcalloc(num, sizeof(type))); } \ + void Free ## name(type** p) { if (p != NULL) { FDKfree(*p); *p=NULL; } } \ + UINT GetRequiredMem ## name(void) { return ALGN_SIZE_EXTRES((num) * sizeof(type)); } + + /** See #H_ALLOC_MEM for description. */ + #define C_ALLOC_MEM_STATIC(name,type,num) \ + static type * Get ## name(int n) { FDK_ASSERT((n) == 0); return ((type*)FDKcalloc(num, sizeof(type))); } \ + static void Free ## name(type** p) { if (p != NULL) { FDKfree(*p); *p=NULL; } } \ + static UINT GetRequiredMem ## name(void) { return ALGN_SIZE_EXTRES((num) * sizeof(type)); } + + /** See #H_ALLOC_MEM for description. */ + #define C_ALLOC_MEM2(name,type,n1,n2) \ + type * Get ## name (int n) { FDK_ASSERT((n) < (n2)); return ((type*)FDKcalloc(n1, sizeof(type))); } \ + void Free ## name(type** p) { if (p != NULL) { FDKfree(*p); *p=NULL; } } \ + UINT GetRequiredMem ## name(void) { return ALGN_SIZE_EXTRES((n1) * sizeof(type)) * (n2); } + + /** See #H_ALLOC_MEM for description. */ + #define C_AALLOC_MEM(name,type,num) \ + type * Get ## name(int n) { FDK_ASSERT((n) == 0); return ((type*)FDKaalloc((num)*sizeof(type), ALIGNMENT_DEFAULT)); } \ + void Free ## name(type** p) { if (p != NULL) { FDKafree(*p); *p=NULL; } } \ + UINT GetRequiredMem ## name(void) { return ALGN_SIZE_EXTRES((num) * sizeof(type) + ALIGNMENT_DEFAULT + sizeof(void *)); } + + /** See #H_ALLOC_MEM for description. */ + #define C_AALLOC_MEM2(name,type,n1,n2) \ + type * Get ## name (int n) { FDK_ASSERT((n) < (n2)); return ((type*)FDKaalloc((n1)*sizeof(type), ALIGNMENT_DEFAULT)); } \ + void Free ## name(type** p) { if (p != NULL) { FDKafree(*p); *p=NULL; } } \ + UINT GetRequiredMem ## name(void) { return ALGN_SIZE_EXTRES((n1) * sizeof(type) + ALIGNMENT_DEFAULT + sizeof(void *)) * (n2); } + + /** See #H_ALLOC_MEM for description. */ + #define C_ALLOC_MEM_L(name,type,num,s) \ + type * Get ## name(int n) { FDK_ASSERT((n) == 0); return ((type*)FDKcalloc_L(num, sizeof(type), s)); } \ + void Free ## name(type** p) { if (p != NULL) { FDKfree_L(*p); *p=NULL; } } \ + UINT GetRequiredMem ## name(void) { return ALGN_SIZE_EXTRES((num) * sizeof(type)); } + + /** See #H_ALLOC_MEM for description. */ + #define C_ALLOC_MEM2_L(name,type,n1,n2,s) \ + type * Get ## name (int n) { FDK_ASSERT((n) < (n2)); return (type*)FDKcalloc_L(n1, sizeof(type), s); } \ + void Free ## name(type** p) { if (p != NULL) { FDKfree_L(*p); *p=NULL; } } \ + UINT GetRequiredMem ## name(void) { return ALGN_SIZE_EXTRES((n1) * sizeof(type)) * (n2); } + + /** See #H_ALLOC_MEM for description. */ + #define C_AALLOC_MEM_L(name,type,num,s) \ + type * Get ## name(int n) { FDK_ASSERT((n) == 0); return ((type*)FDKaalloc_L((num)*sizeof(type), ALIGNMENT_DEFAULT, s)); } \ + void Free ## name(type** p) { if (p != NULL) { FDKafree_L(*p); *p=NULL; } } \ + UINT GetRequiredMem ## name(void) { return ALGN_SIZE_EXTRES((num) * sizeof(type) + ALIGNMENT_DEFAULT + sizeof(void *)); } + + /** See #H_ALLOC_MEM for description. */ + #define C_AALLOC_MEM2_L(name,type,n1,n2,s) \ + type * Get ## name (int n) { FDK_ASSERT((n) < (n2)); return ((type*)FDKaalloc_L((n1)*sizeof(type), ALIGNMENT_DEFAULT, s)); } \ + void Free ## name(type** p) { if (p != NULL) { FDKafree_L(*p); *p=NULL; } } \ + UINT GetRequiredMem ## name(void) { return ALGN_SIZE_EXTRES((n1) * sizeof(type) + ALIGNMENT_DEFAULT + sizeof(void *)) * (n2); } + +/** See #H_ALLOC_MEM_OVERLAY for description. */ + + + #define C_ALLOC_MEM_OVERLAY(name,type,num,sect,tag) C_AALLOC_MEM_L(name,type,num,sect) + + + #define C_AALLOC_SCRATCH_START(name,type,n) \ + type _ ## name[(n)+(ALIGNMENT_DEFAULT+sizeof(type)-1)]; \ + type * name = (type*)ALIGN_PTR(_ ## name); \ + + #define C_ALLOC_SCRATCH_START(name,type,n) \ + type name[n]; + + #define C_AALLOC_SCRATCH_END(name,type,n) + #define C_ALLOC_SCRATCH_END(name,type,n) + + +/*-------------------------------------------- + * Runtime support declarations + *---------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + +#define USE_BUILTIN_STRING_FUNCTIONS +#include "hal_trace.h" + +#define FDKprintf(num,fmt, ...) hal_trace_printf(num,fmt,##__VA_ARGS__) +#define FDKprintfErr(num,fmt,...) hal_trace_printf(num,fmt,##__VA_ARGS__) +#define FDKfprintf(stream, fmt, ...) hal_trace_printf(0,fmt, ##__VA_ARGS__) +#define FDKsprintf(str, fmt, ...) hal_trace_printf(0,fmt, ##__VA_ARGS__) +#if 0 +/** printf() using stdout. If ::ARCH_WA_FLUSH_CONSOLE defined, a flush is done additionally after printf(). */ +void FDKprintf ( const char* szFmt, ...); + +/** printf() using stderr. If ::ARCH_WA_FLUSH_CONSOLE defined, a flush is done additionally after printf(). */ +void FDKprintfErr ( const char* szFmt, ...); + +/** Wrapper for 's getchar(). */ +int FDKgetchar(void); + +INT FDKfprintf(void *stream, const char *format, ...); +INT FDKsprintf(char *str, const char *format, ...); +#endif + + +const char *FDKstrchr(const char *s, INT c); +const char *FDKstrstr(const char *haystack, const char *needle); +char *FDKstrcpy(char *dest, const char *src); +char *FDKstrncpy(char *dest, const char *src, const UINT n); + +#define FDK_MAX_OVERLAYS 8 /**< Maximum number of memory overlays. */ + + +void *FDKcalloc (const UINT n, const UINT size); +void *FDKmalloc (const UINT size); +void FDKfree (void *ptr); + +/** + * Allocate and clear an aligned memory area. Use FDKafree() instead of FDKfree() for these memory areas. + * + * \param size Size of requested memory in bytes. + * \param alignment Alignment of requested memory in bytes. + * \return Pointer to allocated memory. + */ +void *FDKaalloc (const UINT size, const UINT alignment); + +/** + * Free an aligned memory area. + * + * \param ptr Pointer to be freed. + * \return void + */ +void FDKafree (void *ptr); + + +/** + * Allocate memory in a specific memory section. + * Requests can be made for internal or external memory. If internal memory is + * requested, FDKcalloc_L() first tries to use L1 memory, which sizes are defined + * by ::DATA_L1_A_SIZE and ::DATA_L1_B_SIZE. If no L1 memory is available, then + * FDKcalloc_L() tries to use L2 memory. If that fails as well, the requested + * memory is allocated at an extern location using the fallback FDKcalloc(). + * + * \param n See MSDN documentation on calloc(). + * \param size See MSDN documentation on calloc(). + * \param s Memory section. + * \return See MSDN documentation on calloc(). + */ +void *FDKcalloc_L(const UINT n, const UINT size, MEMORY_SECTION s); + +/** + * Allocate aligned memory in a specific memory section. + * See FDKcalloc_L() description for details - same applies here. + */ +void *FDKaalloc_L(const UINT size, const UINT alignment, MEMORY_SECTION s); + +/** + * Free memory that was allocated in a specific memory section. + */ +void FDKfree_L(void *ptr); + +/** + * Free aligned memory that was allocated in a specific memory section. + */ +void FDKafree_L(void *ptr); + +#include +#include +#include +#include +#include + +/*--------------------------------------------------------------------------------------- + * FUNCTION: FDKmemcpy + * DESCRIPTION: - copies memory from "src" to "dst" with length "size" bytes + * - compiled with FDK_DEBUG will give you warnings + *---------------------------------------------------------------------------------------*/ +inline void FDKmemcpy(void *dst, const void *src, const UINT size) +{ + + /* do the copy */ + memcpy(dst, src, size); +} + +inline void FDKmemmove(void *dst, const void *src, const UINT size) { memmove(dst, src, size); } +inline void FDKmemset(void *memPtr, const INT value, const UINT size) { memset(memPtr, value, size); } +inline void FDKmemclear(void *memPtr, const UINT size) { FDKmemset(memPtr,0,size); } +inline UINT FDKstrlen(const char *s) { return (UINT)strlen(s); } + +/* Compare function wrappers */ +inline INT FDKmemcmp(const void *s1, const void *s2, const UINT size) { return memcmp(s1, s2, size); } +inline INT FDKstrcmp(const char *s1, const char *s2) { return strcmp(s1, s2); } +inline INT FDKstrncmp(const char *s1, const char *s2, const UINT size) { return strncmp(s1, s2, size); } + + +/* Math function wrappers. Only intended for compatibility, not to be highly optimized. */ + +inline INT FDKabs(INT j) { return abs(j); } +inline double FDKfabs(double x) { return fabs(x); } +inline double FDKpow(double x, double y) { return pow(x,y); } +inline double FDKsqrt(double x) { return sqrt(x); } +inline double FDKatan(double x) { return atan(x); } +inline double FDKlog(double x) { return log(x); } +inline double FDKsin(double x) { return sin(x); } +inline double FDKcos(double x) { return cos(x); } +inline double FDKexp(double x) { return exp(x); } +inline double FDKatan2(double y, double x) { return atan2(y, x); } +inline double FDKacos(double x) { return acos(x); } +inline double FDKtan(double x) { return tan(x); } +inline double FDKfloor(double x) { return floor(x); } +inline double FDKceil(double x) { return ceil(x); } + +inline INT FDKatoi(const char *nptr) { return atoi(nptr); } +inline long FDKatol(const char *nptr) { return atol(nptr); } +inline float FDKatof(const char *nptr) { return (float)atof(nptr); } + + +#define FDKmax(a,b) ( (a) > (b) ? (a):(b)) +#define FDKmin(a,b) ( (a) < (b) ? (a):(b)) + +#define FDK_INT_MAX ((INT)0x7FFFFFFF) +#define FDK_INT_MIN ((INT)0x80000000) + +/* Math function wrappers. Only intended for compatibility, not to be highly optimized. */ +/* Used for debugging, dev code .. */ + +#define FDKlog2(a) (FDKlog(a)*1.442695041) /* log(2.0) = 1.442695041 */ +#define FDKlog10(a) (FDKlog(a)*0.434294482) /* 1.0/log(10.0) = 0.434294482 */ +/* LONG LONG FDKatoll(const char *nptr); */ +/* LONG LONG FDKatoq(const char *nptr); */ + + + + +/* FILE I/O */ + +/*! + * Check platform for endianess. + * + * \return 1 if platform is little endian, non-1 if platform is big endian. + */ +#ifdef __cplusplus +inline +#else +static +#endif +int IS_LITTLE_ENDIAN(void) { + int __dummy = 1; + return ( *( (UCHAR*)(&(__dummy) ) ) ); +} + +/*! + * Convert input value to little endian format. + * + * \param val Value to be converted. It may be in both big or little endian. + * \return Value in little endian format. + */ +#define TO_LITTLE_ENDIAN(val) \ + ( (IS_LITTLE_ENDIAN()) ? \ + (val) \ + : ( (((val) & 0xff) << 24) || (((val) & 0xff00)<< 8) || (((val) & 0xff0000)>>8) || (((val) & 0xff000000) >> 24) ) ) + + +/*! + * \fn FDKFILE *FDKfopen(const char *filename, const char *mode); + * Standard fopen() wrapper. + * \fn INT FDKfclose(FDKFILE *FP); + * Standard fclose() wrapper. + * \fn INT FDKfseek(FDKFILE *FP, LONG OFFSET, int WHENCE); + * Standard fseek() wrapper. + * \fn INT FDKftell(FDKFILE *FP); + * Standard ftell() wrapper. + * \fn INT FDKfflush(FDKFILE *fp); + * Standard fflush() wrapper. + * \fn UINT FDKfwrite(void *ptrf, INT size, UINT nmemb, FDKFILE *fp); + * Standard fwrite() wrapper. + * \fn UINT FDKfread(void *dst, INT size, UINT nmemb, FDKFILE *fp); + * Standard fread() wrapper. + */ +typedef void FDKFILE; +extern const INT FDKSEEK_SET, FDKSEEK_CUR, FDKSEEK_END; + +FDKFILE *FDKfopen(const char *filename, const char *mode); +INT FDKfclose(FDKFILE *FP); +INT FDKfseek(FDKFILE *FP, LONG OFFSET, int WHENCE); +INT FDKftell(FDKFILE *FP); +INT FDKfflush(FDKFILE *fp); +UINT FDKfwrite(void *ptrf, INT size, UINT nmemb, FDKFILE *fp); +UINT FDKfread(void *dst, INT size, UINT nmemb, FDKFILE *fp); +char* FDKfgets(void *dst, INT size, FDKFILE *fp); +void FDKrewind(FDKFILE *fp); +INT FDKfeof(FDKFILE *fp); + +/** + * \brief Write each member in little endian order. Convert automatically to host endianess. + * \param ptrf Pointer to memory where to read data from. + * \param size Size of each item to be written. + * \param nmemb Number of items to be written. + * \param fp File pointer of type FDKFILE. + * \return Number of items read on success and fread() error on failure. + */ +UINT FDKfwrite_EL(void *ptrf, INT size, UINT nmemb, FDKFILE *fp); + +/** + * \brief Read variable of size "size" as little endian. Convert automatically to host endianess. + * 4-byte alignment is enforced for 24 bit data, at 32 bit full scale. + * \param dst Pointer to memory where to store data into. + * \param size Size of each item to be read. + * \param nmemb Number of items to be read. + * \param fp File pointer of type FDKFILE. + * \return Number of items read on success and fread() error on failure. + */ +UINT FDKfread_EL(void *dst, INT size, UINT nmemb, FDKFILE *fp); + + +/** + * \brief Print FDK software disclaimer. + */ +void FDKprintDisclaimer(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __GENERICSTDS_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/machine_type.h b/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/machine_type.h new file mode 100644 index 0000000..9c71515 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/machine_type.h @@ -0,0 +1,357 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/************************** Fraunhofer IIS FDK SysLib ********************** + + Author(s): + +******************************************************************************/ + +/** \file machine_type.h + * \brief Type defines for various processors and compiler tools. + */ + +#if !defined(__MACHINE_TYPE_H__) +#define __MACHINE_TYPE_H__ + + +/* Library calling convention spec. __cdecl and friends might be added here as required. */ + #define LINKSPEC_H + #define LINKSPEC_CPP + + +/** + * collate all corresponding compiler specific macros to detect a debug build, and set the DEBUG macro if that is the case. + */ +#if defined(_DEBUG) +#define DEBUG +#endif + + +/* for doxygen the following docu parts must be separated */ +/** \var SCHAR + * Data type representing at least 1 byte signed integer on all supported platforms. + */ +/** \var UCHAR + * Data type representing at least 1 byte unsigned integer on all supported platforms. + */ +/** \var INT + * Data type representing at least 4 byte signed integer on all supported platforms. + */ +/** \var UINT + * Data type representing at least 4 byte unsigned integer on all supported platforms. + */ +/** \var LONG + * Data type representing 4 byte signed integer on all supported platforms. + */ +/** \var ULONG + * Data type representing 4 byte unsigned integer on all supported platforms. + */ +/** \var SHORT + * Data type representing 2 byte signed integer on all supported platforms. + */ +/** \var USHORT + * Data type representing 2 byte unsigned integer on all supported platforms. + */ +/** \var INT64 + * Data type representing 8 byte signed integer on all supported platforms. + */ +/** \var UINT64 + * Data type representing 8 byte unsigned integer on all supported platforms. + */ +/** \def SHORT_BITS + * Number of bits the data type short represents. sizeof() is not suited to get this info, + * because a byte is not always defined as 8 bits. + */ +/** \def CHAR_BITS + * Number of bits the data type char represents. sizeof() is not suited to get this info, + * because a byte is not always defined as 8 bits. + */ +/** \var INT_PCM + * Data type representing the width of input and output PCM samples. + */ + + + typedef signed int INT; + typedef unsigned int UINT; +#ifdef __LP64__ + /* force FDK long-datatypes to 4 byte */ + /* jdr: Use defines to avoid type alias problems on 64 bit machines. */ + #define LONG INT + #define ULONG UINT +#else /* __LP64__ */ + typedef signed long LONG; + typedef unsigned long ULONG; +#endif /* __LP64__ */ + typedef signed short SHORT; + typedef unsigned short USHORT; + typedef signed char SCHAR; + typedef unsigned char UCHAR; + + #define SHORT_BITS 16 + #define CHAR_BITS 8 + + +/* Define 64 bit base integer type. */ +#ifdef _MSC_VER + typedef __int64 INT64; + typedef unsigned __int64 UINT64; +#else + typedef long long INT64; + typedef unsigned long long UINT64; +#endif + +#ifndef NULL + #ifdef __cplusplus + #define NULL 0 + #else + #define NULL ((void *)0) + #endif +#endif + +/* Assert is functional on x86 PC's and also when debugging is turned on. */ +#if defined(DEBUG) || defined(__i686__) || defined(__i586__) || defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(FDK_DEBUG) || defined(FDK_ASSERT_ENABLE) + #include + #define FDK_ASSERT(x) assert(x) +#else + #define FDK_ASSERT(ignore) +#endif + + typedef SHORT INT_PCM; + #define WAV_BITS 16 + #define SAMPLE_BITS 16 + #define SAMPLE_MAX (((LONG)1<<(SAMPLE_BITS-1))-1) + #define SAMPLE_MIN (~SAMPLE_MAX) + +/*! +* \def RAM_ALIGN +* Used to align memory as prefix before memory declaration. For example: + \code + RAM_ALIGN + int myArray[16]; + \endcode + + Note, that not all platforms support this mechanism. For example with TI compilers + a preprocessor pragma is used, but to do something like + + \code + #define RAM_ALIGN #pragma DATA_ALIGN(x) + \encode + + would require the preprocessor to process this line twice to fully resolve it. Hence, + a fully platform-independant way to use alignment is not supported. + +* \def ALIGNMENT_DEFAULT +* Default alignment in bytes. +*/ +#if defined(__GNUC__) /* cppp replaced: elif */ + #define ALIGNMENT_DEFAULT 8 + #define RAM_ALIGN __attribute__((aligned(ALIGNMENT_DEFAULT))) +#else + #define ALIGNMENT_DEFAULT 8 + #define RAM_ALIGN +#endif + + +/*! +* \def RESTRICT +* The restrict keyword is supported by some platforms and RESTRICT maps to +* either the corresponding keyword on each platform or to void if the +* compiler does not provide such feature. +* +* \def WORD_ALIGNED(x) +* Tells the compiler that pointer x is WORD aligned. +* At the moment only supported by TI compilers. +* +* \def DWORD_ALIGNED(x) +* Tells the compiler that pointer x is DWORD aligned. +* At the moment only supported by TI compilers. +*/ + #define RESTRICT + #define WORD_ALIGNED(x) + #define DWORD_ALIGNED(x) + + +/*----------------------------------------------------------------------------------- + * ALIGN_SIZE + *-----------------------------------------------------------------------------------*/ +/*! + * \brief This macro aligns a given value depending on ::ALIGNMENT_DEFAULT. + * + * For example if #ALIGNMENT_DEFAULT equals 8, then: + * - ALIGN_SIZE(3) returns 8 + * - ALIGN_SIZE(8) returns 8 + * - ALIGN_SIZE(9) returns 16 + */ +#define ALIGN_SIZE(a) ((a)+ (((INT)ALIGNMENT_DEFAULT - ((INT)(a) & (ALIGNMENT_DEFAULT-1)) ) & (ALIGNMENT_DEFAULT-1))) + +/*----------------------------------------------------------------------------------- + * ALIGN_PTR + * cast (a) to width of pointer + *-----------------------------------------------------------------------------------*/ +/*! + * \brief This macro aligns a given address depending on ::ALIGNMENT_DEFAULT. + */ +#define ALIGN_PTR(a) ( (unsigned char*)(a) + (((INT)ALIGNMENT_DEFAULT - ((INT)(UINT64)(a) & (ALIGNMENT_DEFAULT-1)) ) & (ALIGNMENT_DEFAULT-1)) ) + + /* Alignment macro for libSYS heap implementation */ +#define ALIGNMENT_EXTRES ( ALIGNMENT_DEFAULT ) +#define ALGN_SIZE_EXTRES(a) ((a)+ (((INT)ALIGNMENT_EXTRES - ((INT)(a) & (ALIGNMENT_EXTRES-1)) ) & (ALIGNMENT_EXTRES-1))) + + +/*! + * \def FORCEINLINE + * Sometimes compiler do not do what they are told to do, and in case of inlining some + * additional command might be necessary depending on the platform. + * + * \def FDK_INLINE + * Defines how the compiler is told to inline stuff. + */ +#ifdef DEBUG +#undef FORCEINLINE +#define FORCEINLINE +#else +#ifndef FORCEINLINE + #if defined(__GNUC__) /* cppp replaced: elif */ + #define FORCEINLINE inline __attribute((always_inline)) + #else + #define FORCEINLINE + #endif +#endif +#endif + + /* for all other platforms */ + #define FDK_INLINE inline + + +/*! + * \def LNK_SECTION_DATA_L1 + * The LNK_SECTION_* defines allow memory to be drawn from specific memory + * sections. Used as prefix before variable declaration. + * + * \def LNK_SECTION_DATA_L2 + * See ::LNK_SECTION_DATA_L1 + * \def LNK_SECTION_L1_DATA_A + * See ::LNK_SECTION_DATA_L1 + * \def LNK_SECTION_L1_DATA_B + * See ::LNK_SECTION_DATA_L1 + * \def LNK_SECTION_CONSTDATA_L1 + * See ::LNK_SECTION_DATA_L1 + * \def LNK_SECTION_CONSTDATA + * See ::LNK_SECTION_DATA_L1 + * \def LNK_SECTION_CODE_L1 + * See ::LNK_SECTION_DATA_L1 + * \def LNK_SECTION_CODE_L2 + * See ::LNK_SECTION_DATA_L1 + * \def LNK_SECTION_INITCODE + * See ::LNK_SECTION_DATA_L1 + */ +/************************************************** + * Code Section macros + **************************************************/ + #define LNK_SECTION_CODE_L1 + #define LNK_SECTION_CODE_L2 + #define LNK_SECTION_INITCODE + +/* Memory section macros. */ + + /* default fall back */ + #define LNK_SECTION_DATA_L1 + #define LNK_SECTION_DATA_L2 + #define LNK_SECTION_CONSTDATA + #define LNK_SECTION_CONSTDATA_L1 + + #define LNK_SECTION_L1_DATA_A + #define LNK_SECTION_L1_DATA_B + + +#ifdef _MSC_VER + /* + * Sometimes certain features are excluded from compilation and therefore the warning 4065 may occur: + * "switch statement contains 'default' but no 'case' labels" + * We consider this warning irrelevant and disable it. + */ + #pragma warning( disable : 4065 ) +#endif + +#endif /* __MACHINE_TYPE_H__ */ diff --git a/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/wav_file.h b/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/wav_file.h new file mode 100644 index 0000000..16d5427 --- /dev/null +++ b/services/multimedia/audio/codec/fdkaac_codec/libSYS/include/wav_file.h @@ -0,0 +1,233 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/************************** Fraunhofer IIS FDK SysLib ********************** + + Author(s): Eric Allamanche + +******************************************************************************/ + +/** \file wav_file.h + * \brief Rudimentary WAVE file read/write support. + * + * The WAVE file reader/writer is intented to be used in the codec's example + * framework for easily getting started with encoding/decoding. Therefore + * it serves mainly for helping quickly understand how a codec's API actually + * works. + * Being a WAVE file reader/writer with very basic functionality, it may not be + * able to read WAVE files that come with unusual configurations. + * Details on how to use the interface functions can be found in every + * (encoder/decoder) example framework. + */ + +#ifndef __WAV_FILE_H__ +#define __WAV_FILE_H__ + + + +#include "genericStds.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEAKER_FRONT_LEFT 0x1 +#define SPEAKER_FRONT_RIGHT 0x2 +#define SPEAKER_FRONT_CENTER 0x4 +#define SPEAKER_LOW_FREQUENCY 0x8 +#define SPEAKER_BACK_LEFT 0x10 +#define SPEAKER_BACK_RIGHT 0x20 +#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40 +#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80 +#define SPEAKER_BACK_CENTER 0x100 +#define SPEAKER_SIDE_LEFT 0x200 +#define SPEAKER_SIDE_RIGHT 0x400 +#define SPEAKER_TOP_CENTER 0x800 +#define SPEAKER_TOP_FRONT_LEFT 0x1000 +#define SPEAKER_TOP_FRONT_CENTER 0x2000 +#define SPEAKER_TOP_FRONT_RIGHT 0x4000 +#define SPEAKER_TOP_BACK_LEFT 0x8000 +#define SPEAKER_TOP_BACK_CENTER 0x10000 +#define SPEAKER_TOP_BACK_RIGHT 0x20000 +#define SPEAKER_RESERVED 0x80000000 + +/*! + * RIFF WAVE file struct. + * For details see WAVE file format documentation (for example at http://www.wotsit.org). + */ +typedef struct WAV_HEADER +{ + char riffType[4]; + UINT riffSize; + char waveType[4]; + char formatType[4]; + UINT formatSize; + USHORT compressionCode; + USHORT numChannels; + UINT sampleRate; + UINT bytesPerSecond; + USHORT blockAlign; + USHORT bitsPerSample; + char dataType[4]; + UINT dataSize; +} WAV_HEADER; + +struct WAV +{ + WAV_HEADER header; + FDKFILE *fp; + UINT channelMask; +}; + +typedef struct WAV *HANDLE_WAV; + +/** + * \brief Open a WAV file handle for reading. + * + * \param pWav Pointer to a memory location, where a WAV handle is returned. + * \param filename File name to be opened. + * + * \return 0 on success and non-zero on failure. + */ +INT WAV_InputOpen (HANDLE_WAV *pWav, const char *filename); + +/** + * \brief Read samples from a WAVE file. The samples are automatically re-ordered to the + * native host endianess and scaled to full scale of the INT_PCM type, from + * whatever BPS the WAVE file had specified in its header data. + * + * \param wav Handle of WAV file. + * \param sampleBuffer Pointer to store audio data. + * \param numSamples Desired number of samples to read. + * \param nBufBits Size in bit of each audio sample of sampleBuffer. + * + * \return Number of samples actually read. + */ +INT WAV_InputRead (HANDLE_WAV wav, void *sampleBuffer, UINT numSamples, int nBufBits); + +/** + * \brief Close a WAV file reading handle. + * \param pWav Pointer to a WAV file reading handle. + * \return void + */ +void WAV_InputClose(HANDLE_WAV *pWav); + +/** + * \brief Open WAV output/writer handle. + * + * \param pWav Pointer to WAV handle to be returned. + * \param outputFilename File name of the file to be written to. + * \param sampleRate Desired samplerate of the resulting WAV file. + * \param numChannels Desired number of audio channels of the resulting WAV file. + * \param bitsPerSample Desired number of bits per audio sample of the resulting WAV file. + * + * \return 0: ok; -1: error + */ +INT WAV_OutputOpen(HANDLE_WAV *pWav, const char *outputFilename, INT sampleRate, INT numChannels, INT bitsPerSample); + +/** + * \brief Write data to WAV file asociated to WAV handle. + * + * \param wav Handle of WAV file + * \param sampleBuffer Pointer to audio samples, right justified integer values. + * \param numberOfSamples The number of individual audio sample valuesto be written. + * \param nBufBits Size in bits of each audio sample in sampleBuffer. + * \param nSigBits Amount of significant bits of each nBufBits in sampleBuffer. + * + * \return 0: ok; -1: error + */ +INT WAV_OutputWrite(HANDLE_WAV wav, void *sampleBuffer, UINT numberOfSamples, int nBufBits, int nSigBits); + +/** + * \brief Close WAV output handle. + * \param pWav Pointer to WAV handle. *pWav is set to NULL. + * \return void + */ +void WAV_OutputClose(HANDLE_WAV *pWav); + +#ifdef __cplusplus +} +#endif + + +#endif /* __WAV_FILE_H__ */ diff --git a/services/multimedia/audio/codec/sbc/inc/codec_sbc.h b/services/multimedia/audio/codec/sbc/inc/codec_sbc.h new file mode 100644 index 0000000..4047f19 --- /dev/null +++ b/services/multimedia/audio/codec/sbc/inc/codec_sbc.h @@ -0,0 +1,192 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _CODEC_SBC_H +#define _CODEC_SBC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "bluetooth.h" + +#define BTIF_SBC_USE_FIXED_POINT_ENABLED + +#ifdef BTIF_SBC_USE_FIXED_POINT_ENABLED +typedef S32 REAL; +#else +typedef float REAL; +#endif + +typedef U8 btif_sbc_sample_freq_t; +#define BTIF_SBC_CHNL_SAMPLE_FREQ_16 0 +#define BTIF_SBC_CHNL_SAMPLE_FREQ_32 1 +#define BTIF_SBC_CHNL_SAMPLE_FREQ_44_1 2 +#define BTIF_SBC_CHNL_SAMPLE_FREQ_48 3 + +typedef U8 btif_sbc_channel_mode_t; +#define BTIF_SBC_CHNL_MODE_MONO 0 +#define BTIF_SBC_CHNL_MODE_DUAL_CHNL 1 +#define BTIF_SBC_CHNL_MODE_STEREO 2 +#define BTIF_SBC_CHNL_MODE_JOINT_STEREO 3 + +typedef U8 btif_sbc_alloc_method_t; +#define BTIF_SBC_ALLOC_METHOD_LOUDNESS 0 +#define BTIF_SBC_ALLOC_METHOD_SNR 1 + +#define BTIF_SBC_MAX_NUM_BLK 16 +#define BTIF_SBC_MAX_NUM_SB 8 +#define BTIF_SBC_MAX_NUM_CHNL 2 +#define BTIF_SBC_MAX_PCM_DATA 512 + +#define BTIF_SBC_DEC_ALL 0 +#define BTIF_SBC_DEC_LEFT 1 +#define BTIF_SBC_DEC_RIGHT 2 + +#define BTIF_SBC_SPLIT_LEFT 1 +#define BTIF_SBC_SPLIT_RIGHT 2 + +#define BTIF_MSBC_BLOCKS 15 + +typedef U8 btif_sbc_alloc_method_t; +#define BTIF_SBC_ALLOC_METHOD_LOUDNESS 0 +#define BTIF_SBC_ALLOC_METHOD_SNR 1 + +typedef struct { + U8 bitPool; + btif_sbc_sample_freq_t sampleFreq; + btif_sbc_channel_mode_t channelMode; + btif_sbc_alloc_method_t allocMethod; + U8 numBlocks; + U8 numSubBands; + U8 numChannels; + U8 mSbcFlag; + U16 bitOffset; + U8 crc; + U8 fcs; + U8 join[BTIF_SBC_MAX_NUM_SB]; + U8 scale_factors[BTIF_SBC_MAX_NUM_CHNL][BTIF_SBC_MAX_NUM_SB]; + S32 scaleFactors[BTIF_SBC_MAX_NUM_CHNL][BTIF_SBC_MAX_NUM_SB]; + U16 levels[BTIF_SBC_MAX_NUM_CHNL][BTIF_SBC_MAX_NUM_SB]; + S8 bitNeed0[BTIF_SBC_MAX_NUM_SB]; + S8 bitNeed1[BTIF_SBC_MAX_NUM_SB]; + U8 bits[BTIF_SBC_MAX_NUM_CHNL][BTIF_SBC_MAX_NUM_SB]; + REAL sbSample[BTIF_SBC_MAX_NUM_BLK][BTIF_SBC_MAX_NUM_CHNL][BTIF_SBC_MAX_NUM_SB]; + U8 fcs_bak; +} btif_sbc_stream_info_t; +typedef struct { + U8 bitPool; + uint8_t sampleFreq; + uint8_t channelMode; + uint8_t allocMethod; + U8 numBlocks; + U8 numSubBands; + U8 numChannels; + U8 mSbcFlag; +} btif_sbc_stream_info_short_t; + +typedef struct { + btif_sbc_stream_info_t streamInfo; + U8 sFactorsJoint[BTIF_SBC_MAX_NUM_CHNL][BTIF_SBC_MAX_NUM_SB]; + REAL sbJoint[BTIF_SBC_MAX_NUM_BLK][BTIF_SBC_MAX_NUM_CHNL]; + S16 X0[80 * 2]; + S16 X1[80 * 2]; + U16 X0pos, X1pos; + REAL Y[16]; +} btif_sbc_encoder_t; + +typedef struct { + btif_sbc_stream_info_t streamInfo; + U16 maxPcmLen; + REAL V0[160]; + REAL V1[160]; + struct { + U8 stageBuff[BTIF_SBC_MAX_PCM_DATA]; + U16 stageLen; + U16 curStageOff; + U8 *rxBuff; + U16 rxSize; + U8 rxState; + } parser; +} btif_sbc_decoder_t; + +typedef struct { + list_entry_t node; + uint8_t *data; + uint16_t dataLen; + uint16_t frameSize; + btif_bt_packet_t packet; + uint16_t dataSent; + uint16_t frmDataSent; +} btif_a2dp_sbc_packet_t; + +typedef struct { + btif_sbc_sample_freq_t sampleFreq; + uint8_t numChannels; + uint16_t dataLen; + uint8_t *data; +} btif_sbc_pcm_data_t; + +uint16_t btif_sbc_frame_len(btif_sbc_stream_info_t *StreamInfo); +void btif_sbc_init_decoder(btif_sbc_decoder_t *Decoder); +bt_status_t btif_sbc_decode_frames(btif_sbc_decoder_t *Decoder, + uint8_t *Buff, + uint16_t Len, + uint16_t *BytesParsed, + btif_sbc_pcm_data_t *PcmData, + uint16_t MaxPcmData, + float* gains); + +bt_status_t btif_sbc_decode_frames_parser(btif_sbc_decoder_t *Decoder, + uint8_t *Buff, + uint16_t Len, + uint16_t *BytesParsed); + +bt_status_t btif_sbc_decode_frames_out_sbsamples(btif_sbc_decoder_t *Decoder, + uint8_t *Buff, + uint16_t Len, + uint16_t *BytesDecoded, + btif_sbc_pcm_data_t *PcmData, + uint16_t MaxPcmData, + float* gains, + uint8_t ChooseDecChannel, + REAL *SBSamplesBuf, + uint32_t SBSamplesBufLen, + uint32_t *SBSamplesBufUsed, + uint8_t ChooseSplitChannel); + +void btif_sbc_init_encoder(btif_sbc_encoder_t *Encoder); +bt_status_t btif_sbc_encode_frames(btif_sbc_encoder_t *Encoder, + btif_sbc_pcm_data_t *PcmData, + uint16_t *BytesEncoded, + uint8_t *Buff, + uint16_t *Len, + uint16_t MaxSbcData); +bt_status_t btif_sbc_encode_frames_with_sbsamples(btif_sbc_encoder_t *Encoder, + REAL *SBSamplesBuf, + uint32_t SBSamplesBufLen_bytes, + uint32_t *SBSamplesBufUsed_bytes, + uint8_t *Buff, + uint16_t *Len, + uint16_t MaxSbcData, + uint8_t *number_freame_encoded); + +void btif_plc_update_sbc_decoder_state(btif_sbc_encoder_t *Encoder, btif_sbc_pcm_data_t *PcmData, btif_sbc_decoder_t *Decoder, float *gain); + +#ifdef __cplusplus +} +#endif + +#endif /* CODEC_SBC */ diff --git a/services/multimedia/audio/process/adp/include/adp_arch.h b/services/multimedia/audio/process/adp/include/adp_arch.h new file mode 100644 index 0000000..fca9ee9 --- /dev/null +++ b/services/multimedia/audio/process/adp/include/adp_arch.h @@ -0,0 +1,232 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file arch.h + @brief Various architecture definitions Speex +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ARCH_H +#define ARCH_H + +/* A couple test to catch stupid option combinations */ +#ifdef FIXED_POINT + +#ifdef FLOATING_POINT +#error You cannot compile as floating point and fixed point at the same time +#endif +#ifdef _USE_SSE +#error SSE is only for floating-point +#endif +#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM)) +#error Make up your mind. What CPU do you have? +#endif +#ifdef VORBIS_PSYCHO +#error Vorbis-psy model currently not implemented in fixed-point +#endif + +#else + +#ifndef FLOATING_POINT +#error You now need to define either FIXED_POINT or FLOATING_POINT +#endif +#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) +#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions? +#endif +#ifdef FIXED_POINT_DEBUG +#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?" +#endif + + +#endif + +#ifndef OUTSIDE_SPEEX +//#include "speex/speexdsp_types.h" +#endif + +#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */ +#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */ +#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */ +#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */ +#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */ + +#ifdef FIXED_POINT + +typedef spx_int16_t spx_word16_t; +typedef spx_int32_t spx_word32_t; +typedef spx_word32_t spx_mem_t; +typedef spx_word16_t spx_coef_t; +typedef spx_word16_t spx_lsp_t; +typedef spx_word32_t spx_sig_t; + +#define Q15ONE 32767 + +#define LPC_SCALING 8192 +#define SIG_SCALING 16384 +#define LSP_SCALING 8192. +#define GAMMA_SCALING 32768. +#define GAIN_SCALING 64 +#define GAIN_SCALING_1 0.015625 + +#define LPC_SHIFT 13 +#define LSP_SHIFT 13 +#define SIG_SHIFT 14 +#define GAIN_SHIFT 6 + +#define VERY_SMALL 0 +#define VERY_LARGE32 ((spx_word32_t)2147483647) +#define VERY_LARGE16 ((spx_word16_t)32767) +#define Q15_ONE ((spx_word16_t)32767) + + +#ifdef FIXED_DEBUG +#include "fixed_debug.h" +#else + +#include "fixed_generic.h" + +#ifdef ARM5E_ASM +#include "fixed_arm5e.h" +#elif defined (ARM4_ASM) +#include "fixed_arm4.h" +#elif defined (BFIN_ASM) +#include "fixed_bfin.h" +#endif + +#endif + + +#else + +typedef float spx_mem_t; +typedef float spx_coef_t; +typedef float spx_lsp_t; +typedef float spx_sig_t; +typedef float spx_word16_t; +typedef float spx_word32_t; + +#define Q15ONE 1.0f +#define LPC_SCALING 1.f +#define SIG_SCALING 1.f +#define LSP_SCALING 1.f +#define GAMMA_SCALING 1.f +#define GAIN_SCALING 1.f +#define GAIN_SCALING_1 1.f + + +#define VERY_SMALL 1e-15f +#define VERY_LARGE32 1e15f +#define VERY_LARGE16 1e15f +#define Q15_ONE ((spx_word16_t)1.f) + +#define QCONST16(x,bits) (x) +#define QCONST32(x,bits) (x) + +#define NEG16(x) (-(x)) +#define NEG32(x) (-(x)) +#define EXTRACT16(x) (x) +#define EXTEND32(x) (x) +#define SHR16(a,shift) (a) +#define SHL16(a,shift) (a) +#define SHR32(a,shift) (a) +#define SHL32(a,shift) (a) +#define PSHR16(a,shift) (a) +#define PSHR32(a,shift) (a) +#define VSHR32(a,shift) (a) +#define SATURATE16(x,a) (x) +#define SATURATE32(x,a) (x) +#define SATURATE32PSHR(x,shift,a) (x) + +#define PSHR(a,shift) (a) +#define SHR(a,shift) (a) +#define SHL(a,shift) (a) +#define SATURATE(x,a) (x) + +#define ADD16(a,b) ((a)+(b)) +#define SUB16(a,b) ((a)-(b)) +#define ADD32(a,b) ((a)+(b)) +#define SUB32(a,b) ((a)-(b)) +#define MULT16_16_16(a,b) ((a)*(b)) +#define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b)) +#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b)) + +#define MULT16_32_Q11(a,b) ((a)*(b)) +#define MULT16_32_Q13(a,b) ((a)*(b)) +#define MULT16_32_Q14(a,b) ((a)*(b)) +#define MULT16_32_Q15(a,b) ((a)*(b)) +#define MULT16_32_P15(a,b) ((a)*(b)) + +#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b)) +#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b)) + +#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b)) +#define MAC16_16_Q13(c,a,b) ((c)+(a)*(b)) +#define MAC16_16_P13(c,a,b) ((c)+(a)*(b)) +#define MULT16_16_Q11_32(a,b) ((a)*(b)) +#define MULT16_16_Q13(a,b) ((a)*(b)) +#define MULT16_16_Q14(a,b) ((a)*(b)) +#define MULT16_16_Q15(a,b) ((a)*(b)) +#define MULT16_16_P15(a,b) ((a)*(b)) +#define MULT16_16_P13(a,b) ((a)*(b)) +#define MULT16_16_P14(a,b) ((a)*(b)) + +#define DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b)) +#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b)) +#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) +#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) + + +#endif + + +#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + +/* 2 on TI C5x DSP */ +#define BYTES_PER_CHAR 2 +#define BITS_PER_CHAR 16 +#define LOG2_BITS_PER_CHAR 4 + +#else + +#define BYTES_PER_CHAR 1 +#define BITS_PER_CHAR 8 +#define LOG2_BITS_PER_CHAR 3 + +#endif + + + +#ifdef FIXED_DEBUG +extern long long spx_mips; +#endif + + +#endif diff --git a/services/multimedia/audio/process/adp/include/adp_config.h b/services/multimedia/audio/process/adp/include/adp_config.h new file mode 100644 index 0000000..b00b4bd --- /dev/null +++ b/services/multimedia/audio/process/adp/include/adp_config.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +// Microsoft version of 'inline' + +#ifdef WIN32 +#define inline __inline +#endif + + +//#define FIXED_POINT + + +// In Visual Studio, _M_IX86_FP=1 means /arch:SSE was used, likewise +// _M_IX86_FP=2 means /arch:SSE2 was used. +// Also, enable both _USE_SSE and _USE_SSE2 if we're compiling for x86-64 +// #if _M_IX86_FP >= 1 || defined(_M_X64) +// #define _USE_SSE +// #endif +// +// #if _M_IX86_FP >= 2 || defined(_M_X64) +// #define _USE_SSE2 +// #endif + +// Visual Studio support alloca(), but it always align variables to 16-bit +// boundary, while SSE need 128-bit alignment. So we disable alloca() when +// SSE is enabled. +#define FLOATING_POINT +#define USE_SMALLFT + +/* We don't support visibility on Win32 */ +#define EXPORT + +#define USE_STATIC_MEMORY + +#define ADPFILTER_NUM 400 + + diff --git a/services/multimedia/audio/process/adp/include/adp_fftwrap.h b/services/multimedia/audio/process/adp/include/adp_fftwrap.h new file mode 100644 index 0000000..367c310 --- /dev/null +++ b/services/multimedia/audio/process/adp/include/adp_fftwrap.h @@ -0,0 +1,58 @@ +/* Copyright (C) 2005 Jean-Marc Valin + File: fftwrap.h + + Wrapper for various FFTs + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef FFTWRAP_H +#define FFTWRAP_H + +#include "adp_arch.h" + +/** Compute tables for an FFT */ +void *adp_spx_fft_init(int size); + +/** Destroy tables for an FFT */ +void adp_spx_fft_destroy(void *table); + +/** Forward (real to half-complex) transform */ +void adp_spx_fft(void *table, spx_word16_t *in, spx_word16_t *out); + +/** Backward (half-complex to real) transform */ +void adp_spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out); + +/** Forward (real to half-complex) transform of float data */ +void adp_spx_fft_float(void *table, float *in, float *out); + +/** Backward (half-complex to real) transform of float data */ +void adp_spx_ifft_float(void *table, float *in, float *out); + +#endif diff --git a/services/multimedia/audio/process/adp/include/adp_filter.h b/services/multimedia/audio/process/adp/include/adp_filter.h new file mode 100644 index 0000000..3803085 --- /dev/null +++ b/services/multimedia/audio/process/adp/include/adp_filter.h @@ -0,0 +1,47 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: fft transform + last mod: $Id: smallft.h,v 1.3 2003/09/16 18:35:45 jm Exp $ + + ********************************************************************/ +/** + @file adp_filter.h + @brief Discrete Rotational Fourier Transform (DRFT) +*/ + +#ifndef _ADP_FILTER_H_ +#define _ADP_FILTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "adp_config.h" + + + +struct adpparam +{ + void *fft_lookup; + int M; + float w_fft[ADPFILTER_NUM*2]; + float w[ADPFILTER_NUM*2]; + float u; +}; +extern void lms_block_fft(short *in, short *dest, short *out, struct adpparam *param,int upadat_flag); +extern void *adp_filter_init(int size); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/adp/include/adp_smallft.h b/services/multimedia/audio/process/adp/include/adp_smallft.h new file mode 100644 index 0000000..53f86ac --- /dev/null +++ b/services/multimedia/audio/process/adp/include/adp_smallft.h @@ -0,0 +1,46 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: fft transform + last mod: $Id: smallft.h,v 1.3 2003/09/16 18:35:45 jm Exp $ + + ********************************************************************/ +/** + @file smallft.h + @brief Discrete Rotational Fourier Transform (DRFT) +*/ + +#ifndef _V_SMFT_H_ +#define _V_SMFT_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** Discrete Rotational Fourier Transform lookup */ +struct drft_lookup{ + int n; + float *trigcache; + int *splitcache; +}; + +extern void adp_spx_drft_forward(struct drft_lookup *l,float *data); +extern void adp_spx_drft_backward(struct drft_lookup *l,float *data); +extern void adp_spx_drft_init(struct drft_lookup *l,int n); +extern void adp_spx_drft_clear(struct drft_lookup *l); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/anc/cfg/Makefile b/services/multimedia/audio/process/anc/cfg/Makefile new file mode 100644 index 0000000..fc4c186 --- /dev/null +++ b/services/multimedia/audio/process/anc/cfg/Makefile @@ -0,0 +1,31 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y := \ + -Iservices/multimedia/audio/process/anc/include \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/include \ + -Iutils/crc32 \ + -Iservices/multimedia/speech/src/process/ns_and_ec/inc \ + -Iservices/multimedia/speech/inc \ + -Iservices/multimedia/speech/src/process/common/inc \ + -Iservices/multimedia/speech/src/process/inc + +ccflags-y += -DUSE_CMSIS_F32_FFT + +ifeq ($(HW_DAC_IIR_EQ_PROCESS),1) +CFLAGS_anc_cfg.o += -D__HW_DAC_IIR_EQ_PROCESS__ +endif +ifeq ($(HW_IIR_EQ_PROCESS),1) +CFLAGS_anc_cfg.o += -D__HW_IIR_EQ_PROCESS__ +endif +ifeq ($(AUDIO_RESAMPLE),1) +CFLAGS_anc_cfg.o += -D__AUDIO_RESAMPLE__ +endif + +CFLAGS_fftfilt2.o += -DUSE_MED_MALLOC diff --git a/services/multimedia/audio/process/anc/cfg/anc_cfg.c b/services/multimedia/audio/process/anc/cfg/anc_cfg.c new file mode 100644 index 0000000..8f359bc --- /dev/null +++ b/services/multimedia/audio/process/anc/cfg/anc_cfg.c @@ -0,0 +1,2295 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "aud_section.h" +#include "aud_section_inc.h" +#include "tgt_hardware.h" +#include "hal_trace.h" +#include "anc_process.h" +#include "hal_location.h" +#include "hal_trace.h" +#include "hal_sysfreq.h" + +#ifdef USB_ANC_MC_EQ_TUNING +#include "string.h" +#include "hal_timer.h" +#include "hal_aud.h" +#include "hal_cmu.h" +#include "hal_dma.h" +#include "hal_iomux.h" +#include "hal_codec.h" +#include "audioflinger.h" +#include "pmu.h" +#include "analog.h" +#include "hal_norflash.h" +#include "stdint.h" +#include "crc32.h" +#include "hw_iir_process.h" +#include "hw_codec_iir_process.h" +#endif + +#ifdef AUDIO_ANC_FB_MC +#include "cmsis.h" +#endif + +#ifdef ANC_COEF_LIST_NUM +#if (ANC_COEF_LIST_NUM < 1) +#error "Invalid ANC_COEF_LIST_NUM configuration" +#endif +#else +#define ANC_COEF_LIST_NUM (1) +#endif + +extern const struct_anc_cfg * anc_coef_list_50p7k[ANC_COEF_LIST_NUM]; +extern const struct_anc_cfg * anc_coef_list_48k[ANC_COEF_LIST_NUM]; +extern const struct_anc_cfg * anc_coef_list_44p1k[ANC_COEF_LIST_NUM]; + +const struct_anc_cfg * WEAK anc_coef_list_50p7k[ANC_COEF_LIST_NUM] = { }; +const struct_anc_cfg * WEAK anc_coef_list_48k[ANC_COEF_LIST_NUM] = { }; +const struct_anc_cfg * WEAK anc_coef_list_44p1k[ANC_COEF_LIST_NUM] = { }; + +static enum ANC_INDEX cur_coef_idx=ANC_INDEX_0; +static enum AUD_SAMPRATE_T cur_coef_samprate; + + +#ifdef AUDIO_ANC_FB_MC +#define AUD_IIR_NUM (8) + +typedef struct { + aud_item anc_cfg_mc_l; + aud_item anc_cfg_mc_r; + float mc_history_l[AUD_IIR_NUM][4]; + float mc_history_r[AUD_IIR_NUM][4]; +} IIR_MC_CFG_T; + +static IIR_MC_CFG_T mc_iir_cfg; + +#endif + +#ifndef CODEC_OUTPUT_DEV +#define CODEC_OUTPUT_DEV CFG_HW_AUD_OUTPUT_PATH_SPEAKER_DEV +#endif + +int anc_load_cfg(void) +{ + int res = 0; + const struct_anc_cfg **list; + + anc_set_ch_map(CODEC_OUTPUT_DEV); + +#ifdef __AUDIO_RESAMPLE__ + res = anccfg_loadfrom_audsec(anc_coef_list_50p7k, anc_coef_list_48k, ANC_COEF_LIST_NUM); + list = anc_coef_list_50p7k; + TRACE(0,"50.7k!!!!"); + + if(res) { + TRACE(2,"[%s] WARNING(%d): Can not load anc coefficient from audio section!!!", __func__, res); + } else { + TRACE(1,"[%s] Load anc coefficient from audio section.", __func__); +#if (AUD_SECTION_STRUCT_VERSION == 1) + TRACE(5,"[%s] L: gain = %d, len = %d, dac = %d, adc = %d", __func__, list[0]->anc_cfg_ff_l.total_gain, list[0]->anc_cfg_ff_l.fir_len, list[0]->anc_cfg_ff_l.dac_gain_offset, list[0]->anc_cfg_ff_l.adc_gain_offset); + TRACE(5,"[%s] R: gain = %d, len = %d, dac = %d, adc = %d", __func__, list[0]->anc_cfg_ff_r.total_gain, list[0]->anc_cfg_ff_r.fir_len, list[0]->anc_cfg_ff_r.dac_gain_offset, list[0]->anc_cfg_ff_r.adc_gain_offset); +#elif (AUD_SECTION_STRUCT_VERSION == 2) + for(int i = 0; i < ANC_COEF_LIST_NUM; i++) { + TRACE(3,"appmode%d,FEEDFORWARD,L:gain %d,R:gain %d",i, list[i]->anc_cfg_ff_l.total_gain, list[i]->anc_cfg_ff_r.total_gain); + for(int j = 0; j anc_cfg_ff_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[2]); + } + + TRACE(3,"appmode%d,FEEDBACK,L:gain %d,R:gain %d",i, list[i]->anc_cfg_fb_l.total_gain, list[i]->anc_cfg_fb_r.total_gain); + for(int j = 0; j anc_cfg_fb_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[2]); + } + } +#elif (AUD_SECTION_STRUCT_VERSION == 3) + for(int i = 0; i < ANC_COEF_LIST_NUM; i++) { + TRACE(2,"appmode%d,FEEDFORWARD,L:gain %d",i, list[i]->anc_cfg_ff_l.total_gain); + for(int j = 0; j anc_cfg_ff_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[2]); + } + + TRACE(2,"appmode%d,FEEDBACK,L:gain %d",i, list[i]->anc_cfg_fb_l.total_gain); + for(int j = 0; j anc_cfg_fb_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[2]); + } + } +#endif + } + +#else + res = anccfg_loadfrom_audsec(anc_coef_list_48k, anc_coef_list_44p1k, ANC_COEF_LIST_NUM); + list = anc_coef_list_44p1k; + TRACE(0,"44.1k!!!!"); + + if(res) { + TRACE(2,"[%s] WARNING(%d): Can not load anc coefficient from audio section!!!", __func__, res); + } else { + TRACE(1,"[%s] Load anc coefficient from audio section.", __func__); +#if (AUD_SECTION_STRUCT_VERSION == 1) + TRACE(5,"[%s] L: gain = %d, len = %d, dac = %d, adc = %d", __func__, list[0]->anc_cfg_ff_l.total_gain, list[0]->anc_cfg_ff_l.fir_len, list[0]->anc_cfg_ff_l.dac_gain_offset, list[0]->anc_cfg_ff_l.adc_gain_offset); + TRACE(5,"[%s] R: gain = %d, len = %d, dac = %d, adc = %d", __func__, list[0]->anc_cfg_ff_r.total_gain, list[0]->anc_cfg_ff_r.fir_len, list[0]->anc_cfg_ff_r.dac_gain_offset, list[0]->anc_cfg_ff_r.adc_gain_offset); +#elif (AUD_SECTION_STRUCT_VERSION == 2) + for(int i = 0; i < ANC_COEF_LIST_NUM; i++) { + TRACE(3,"appmode%d,FEEDFORWARD,L:gain %d,R:gain %d",i, list[i]->anc_cfg_ff_l.total_gain, list[i]->anc_cfg_ff_r.total_gain); + for(int j = 0; j anc_cfg_ff_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[2]); + } + + TRACE(3,"appmode%d,FEEDBACK,L:gain %d,R:gain %d",i, list[i]->anc_cfg_fb_l.total_gain, list[i]->anc_cfg_fb_r.total_gain); + for(int j = 0; j anc_cfg_fb_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[2]); + } + } +#elif (AUD_SECTION_STRUCT_VERSION == 3) + for(int i = 0; i < ANC_COEF_LIST_NUM; i++) { + TRACE(2,"appmode%d,FEEDFORWARD,L:gain %d",i, list[i]->anc_cfg_ff_l.total_gain); + for(int j = 0; j anc_cfg_ff_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[2]); + } + + TRACE(2,"appmode%d,FEEDBACK,L:gain %d",i, list[i]->anc_cfg_fb_l.total_gain); + for(int j = 0; j anc_cfg_fb_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[2]); + } + } + +#endif + } + + res = anccfg_loadfrom_audsec(anc_coef_list_48k, anc_coef_list_44p1k, ANC_COEF_LIST_NUM); + list = anc_coef_list_48k; + TRACE(0,"48k!!!!"); + + if(res) { + TRACE(2,"[%s] WARNING(%d): Can not load anc coefficient from audio section!!!", __func__, res); + } else { + TRACE(1,"[%s] Load anc coefficient from audio section.", __func__); +#if (AUD_SECTION_STRUCT_VERSION == 1) + TRACE(5,"[%s] L: gain = %d, len = %d, dac = %d, adc = %d", __func__, list[0]->anc_cfg_ff_l.total_gain, list[0]->anc_cfg_ff_l.fir_len, list[0]->anc_cfg_ff_l.dac_gain_offset, list[0]->anc_cfg_ff_l.adc_gain_offset); + TRACE(5,"[%s] R: gain = %d, len = %d, dac = %d, adc = %d", __func__, list[0]->anc_cfg_ff_r.total_gain, list[0]->anc_cfg_ff_r.fir_len, list[0]->anc_cfg_ff_r.dac_gain_offset, list[0]->anc_cfg_ff_r.adc_gain_offset); +#elif (AUD_SECTION_STRUCT_VERSION == 2) + for(int i = 0; i < ANC_COEF_LIST_NUM; i++) { + TRACE(3,"appmode%d,FEEDFORWARD,L:gain %d,R:gain %d",i, list[i]->anc_cfg_ff_l.total_gain, list[i]->anc_cfg_ff_r.total_gain); + for(int j = 0; j anc_cfg_ff_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[2]); + } + + TRACE(3,"appmode%d,FEEDBACK,L:gain %d,R:gain %d",i, list[i]->anc_cfg_fb_l.total_gain, list[i]->anc_cfg_fb_r.total_gain); + for(int j = 0; j anc_cfg_fb_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[2]); + } + } +#elif (AUD_SECTION_STRUCT_VERSION == 3) + for(int i = 0; i < ANC_COEF_LIST_NUM; i++) { + TRACE(2,"appmode%d,FEEDFORWARD,L:gain %d",i, list[i]->anc_cfg_ff_l.total_gain); + for(int j = 0; j anc_cfg_ff_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_ff_l.iir_coef[j].coef_a[2]); + } + + TRACE(2,"appmode%d,FEEDBACK,L:gain %d",i, list[i]->anc_cfg_fb_l.total_gain); + for(int j = 0; j anc_cfg_fb_l.iir_coef[j].coef_b[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_b[2], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[0], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[1], \ + list[i]->anc_cfg_fb_l.iir_coef[j].coef_a[2]); + } + } +#endif + } +#endif + return res; +} + + + +int anc_select_coef(enum AUD_SAMPRATE_T rate,enum ANC_INDEX index,enum ANC_TYPE_T anc_type,ANC_GAIN_TIME anc_gain_delay) +{ + const struct_anc_cfg **list=NULL; + + if (index >= ANC_COEF_LIST_NUM) { + return 1; + } + +#ifdef CHIP_BEST1000 + switch(rate) + { + case AUD_SAMPRATE_96000: + list=anc_coef_list_48k; + break; + + case AUD_SAMPRATE_88200: + list=anc_coef_list_44p1k; + break; + + default: + break; + } + +#else + switch(rate) + { + case AUD_SAMPRATE_48000: + list=anc_coef_list_48k; + break; + + case AUD_SAMPRATE_44100: + list=anc_coef_list_44p1k; + break; + +#ifdef __AUDIO_RESAMPLE__ + case AUD_SAMPRATE_50781: + list=anc_coef_list_50p7k; + break; +#endif + + default: + break; + } +#endif + + ASSERT(list!=NULL&&list[index]!=NULL,"The coefs of Samprate %d is NULL", rate); + + if(anc_opened(anc_type)) + { + hal_sysfreq_req(HAL_SYSFREQ_USER_ANC,HAL_CMU_FREQ_52M); + anc_set_cfg(list[index],anc_type,anc_gain_delay); + hal_sysfreq_req(HAL_SYSFREQ_USER_ANC,HAL_CMU_FREQ_32K); +#ifdef AUDIO_ANC_FB_MC + mc_iir_cfg.anc_cfg_mc_l=(*list[index]).anc_cfg_mc_l; + mc_iir_cfg.anc_cfg_mc_r=(*list[index]).anc_cfg_mc_r; +#endif + } + + cur_coef_idx = index; + cur_coef_samprate=rate; + + return 0; +} + +enum ANC_INDEX anc_get_current_coef_index(void) +{ + return cur_coef_idx; +} + +enum AUD_SAMPRATE_T anc_get_current_coef_samplerate(void) +{ + return cur_coef_samprate; +} + +#ifdef AUDIO_ANC_FB_MC + +void anc_mc_run_init(enum AUD_SAMPRATE_T rate) +{ + const struct_anc_cfg **list=NULL; + + switch(rate) + { + case AUD_SAMPRATE_48000: + list=anc_coef_list_48k; + break; + + case AUD_SAMPRATE_44100: + list=anc_coef_list_44p1k; + break; + +#ifdef __AUDIO_RESAMPLE__ + case AUD_SAMPRATE_50781: + list=anc_coef_list_50p7k; + break; +#endif + default: + break; + } + + ASSERT(list!=NULL&&list[cur_coef_idx]!=NULL,"The coefs of Samprate %d is NULL", rate); + + mc_iir_cfg.anc_cfg_mc_l=(*list[cur_coef_idx]).anc_cfg_mc_l; + mc_iir_cfg.anc_cfg_mc_r=(*list[cur_coef_idx]).anc_cfg_mc_r; + + for(int j=0;j>2; + + gain_l = (mc_iir_cfg.anc_cfg_mc_l.total_gain/512.0f)*left_gain; + + if(mc_iir_cfg.anc_cfg_mc_l.iir_counter==0||mc_iir_cfg.anc_cfg_mc_l.iir_bypass_flag) + { + iir_buf = (int16_t *)buf; + + for(int j=0; j>3; + + gain_l = (mc_iir_cfg.anc_cfg_mc_l.total_gain/512.0f)*left_gain; + + if(mc_iir_cfg.anc_cfg_mc_l.iir_counter==0||mc_iir_cfg.anc_cfg_mc_l.iir_bypass_flag) + { + iir_buf = (int32_t *)buf; + for(int j=0; j>1; + + gain_l = (mc_iir_cfg.anc_cfg_mc_l.total_gain/512.0f)*left_gain; + num = mc_iir_cfg.anc_cfg_mc_l.iir_counter; + + if(num==0||mc_iir_cfg.anc_cfg_mc_l.iir_bypass_flag) + { + iir_buf = (int16_t *)buf; + + for(int j=0; j>2; + + gain_l = (mc_iir_cfg.anc_cfg_mc_l.total_gain/512.0f)*left_gain; + num = mc_iir_cfg.anc_cfg_mc_l.iir_counter; + + if(num==0) + { + iir_buf = (int32_t *)buf; + + for(int j=0; jhdr) + (msg)->hdr.len + 1) + +#define TRACE_TIME(num,str, ...) TRACE(1+num,"[%05u] " str, TICKS_TO_MS(hal_sys_timer_get()), ##__VA_ARGS__) + + +static unsigned char check_sum(const unsigned char *buf, unsigned char len) +{ + int i; + unsigned char sum = 0; + + for (i = 0; i < len; i++) { + sum += buf[i]; + } + + return sum; +} +static void trace_stage_info(const char *name) +{ + TRACE_TIME(1,"------ %s ------", name); +} +static void trace_rw_len_err(const char *name, unsigned int len) +{ + TRACE(2,"[%s] Length error: %u", name, len); +} +static void trace_rw_info(const char *name, unsigned int addr, unsigned int len) +{ + // TRACE(3,"[%s] addr=0x%08X len=%u", name, addr, len); +} + +static void trace_flash_cmd_info(const char *name) +{ + TRACE_TIME(1,"- %s -", name); +} + +static void trace_flash_cmd_len_err(const char *name, unsigned int len) +{ + TRACE(2,"Invalid %s cmd param len: %u", name, len); +} + +static void trace_flash_cmd_err(const char *name) +{ + TRACE_TIME(1,"%s failed", name); +} + +static void trace_flash_cmd_done(const char *name) +{ + TRACE_TIME(1,"%s done", name); +} + +int send_reply(const unsigned char *payload, unsigned int len) +{ + int ret = 0; + + if (len + 1 > sizeof(send_msg.data)) { + TRACE(1,"Packet length too long: %u", len); + return -1; + } + + send_msg.hdr.type = recv_msg.hdr.type; + send_msg.hdr.seq = recv_msg.hdr.seq; + send_msg.hdr.len = len; + memcpy(&send_msg.data[0], payload, len); + send_msg.data[len] = ~check_sum((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg) - 1); + + send_msg_push_seq=send_msg_push_seq%MAX_SNED_MSG_QUEUE; + send_msg_queue[send_msg_push_seq]=send_msg; + send_msg_push_seq++; + + return ret; +} +static enum ERR_CODE handle_read_cmd(unsigned int type, unsigned int addr, unsigned int len) +{ + union { + unsigned int data[1 + (MAX_READ_DATA_LEN + 3) / 4]; + unsigned char buf[(1 + (MAX_READ_DATA_LEN + 3) / 4) * 4]; + } d; + int i; + + int cnt; + unsigned int *p32; + unsigned short *p16; + + const char *name = NULL; + + if (type == TYPE_READ) { + name = "READ"; + } else { + return ERR_INTERNAL; + } + + + if (len > MAX_READ_DATA_LEN) { + trace_rw_len_err(name, len); + return ERR_DATA_LEN; + } + + + if (type == TYPE_READ) { + // Handle half-word and word register reading + if ((len & 0x03) == 0 && (addr & 0x03) == 0) { + cnt = len / 4; + p32 = (unsigned int *)&d.data[1]; + for (i = 0; i < cnt; i++) { + p32[i] = *((unsigned int *)addr + i); + } + } else if ((len & 0x01) == 0 && (addr & 0x01) == 0) { + cnt = len / 2; + p16 = (unsigned short *)&d.data[1]; + for (i = 0; i < cnt; i++) { + p16[i] = *((unsigned short *)addr + i); + } + } else { + memcpy(&d.data[1], (unsigned char *)addr, len); + } + } + + d.buf[3] = ERR_NONE; + send_reply((unsigned char *)&d.buf[3], 1 + len); + + return ERR_NONE; +} +static enum ERR_CODE handle_write_cmd(unsigned int addr, unsigned int len, unsigned char *wdata) +{ + unsigned int data; + int i; + int cnt; + const char *name = "WRITE"; + + trace_rw_info(name, addr, len); + + if (len > MAX_WRITE_DATA_LEN) { + trace_rw_len_err(name, len); + return ERR_DATA_LEN; + } + // Handle half-word and word register writing + if ((len & 0x03) == 0 && (addr & 0x03) == 0) { + cnt = len / 4; + for (i = 0; i < cnt; i++) { + data = wdata[4 * i] | (wdata[4 * i + 1] << 8) | (wdata[4 * i + 2] << 16) | (wdata[4 * i + 3] << 24); + *((unsigned int *)addr + i) = data; + } + } else if ((len & 0x01) == 0 && (addr & 0x01) == 0) { + cnt = len / 2; + for (i = 0; i < cnt; i++) { + data = wdata[2 * i] | (wdata[2 * i + 1] << 8); + *((unsigned short *)addr + i) = (unsigned short)data; + } + } else { + memcpy((unsigned char *)addr, wdata, len); + } + + data = ERR_NONE; + send_reply((unsigned char *)&data, 1); + + return ERR_NONE; +} +static struct_anc_cfg *get_anc_config(void) +{ + return &g_anc_config; +} + + +static void tool_anc_close(void) +{ + if(pcsuppt_anc_type & ANC_FEEDFORWARD) + { + anc_close(ANC_FEEDFORWARD); + af_anc_close(ANC_FEEDFORWARD); + } + + if(pcsuppt_anc_type & ANC_FEEDBACK) + { + anc_close(ANC_FEEDBACK); + af_anc_close(ANC_FEEDBACK); + } +} +static void tool_anc_open(void) +{ + if(pcsuppt_anc_type & ANC_FEEDFORWARD) + { + af_anc_open(ANC_FEEDFORWARD, anc_sample_rate, anc_sample_rate, NULL); + anc_open(ANC_FEEDFORWARD); + anc_set_gain(512,512,ANC_FEEDFORWARD); + +#ifdef AUDIO_ANC_TT_HW + af_anc_open(ANC_TALKTHRU, anc_sample_rate, anc_sample_rate, NULL); + anc_open(ANC_TALKTHRU); + anc_set_gain(512,512,ANC_TALKTHRU); +#endif + + } + + if(pcsuppt_anc_type & ANC_FEEDBACK) + { + af_anc_open(ANC_FEEDBACK, anc_sample_rate, anc_sample_rate, NULL); + anc_open(ANC_FEEDBACK); + anc_set_gain(512,512,ANC_FEEDBACK); + +#ifdef AUDIO_ANC_FB_MC_HW + anc_open(ANC_MUSICCANCLE); + anc_set_gain(512,512,ANC_MUSICCANCLE); +#endif + + } +} +#if !defined( AUDIO_ANC_TT_HW) +#if defined(__HW_IIR_EQ_PROCESS__) +static HW_IIR_CFG_T hw_iir_cfg; +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) +static HW_CODEC_IIR_CFG_T hw_codec_iir_cfg; +#endif +#endif + +static int handle_anc_cmd(enum ANC_CMD_T cmd, const uint8_t *data, uint32_t len) +{ + + unsigned char cret = ERR_NONE; + + switch (cmd) { + case ANC_CMD_CLOSE: + { + TRACE(0,"ANC_CMD_CLOSE ------"); + if (len != 0) + { + return ERR_LEN; + } + anc_disable(); + tool_anc_close(); + send_reply(&cret, 1); + break; + } + case ANC_CMD_OPEN: + { + TRACE(0,"ANC_CMD_OPEN ------"); + if (len != 0) { + return ERR_LEN; + } + hal_sysfreq_req(HAL_SYSFREQ_USER_ANC, HAL_CMU_FREQ_52M); + tool_anc_open(); + anc_enable(); + send_reply(&cret, 1); + break; + } + case ANC_CMD_GET_CFG: + { + TRACE(0,"ANC_CMD_GET_CFG ------"); + + struct_anc_cfg *anccfg_addr = get_anc_config(); + uint32_t addr = (uint32_t)anccfg_addr; + + if (len != 0) { + return ERR_LEN; + } + + TRACE(1,"send anccfg address 0x%x ------",addr); + send_reply((unsigned char *)&addr, sizeof(addr)); + break; + } + case ANC_CMD_APPLY_CFG: + { + TRACE(0,"ANC_CMD_APPLY_CFG ------"); + + if (len != 0) { + return ERR_LEN; + } + TRACE(0,"apply anccfg ------"); + // best2000_prod_test_anccfg_apply(); + struct_anc_cfg *anccfg = get_anc_config(); + + + //process ANC + if(pcsuppt_anc_type & ANC_FEEDFORWARD) + { + anc_set_cfg(anccfg,ANC_FEEDFORWARD,ANC_GAIN_NO_DELAY); +#ifdef AUDIO_ANC_TT_HW + //anc_set_cfg(anccfg,ANC_TALKTHRU,ANC_GAIN_NO_DELAY); +#endif + } + + if(pcsuppt_anc_type & ANC_FEEDBACK) + { + anc_set_cfg(anccfg,ANC_FEEDBACK,ANC_GAIN_NO_DELAY); +#ifdef AUDIO_ANC_FB_MC_HW + anc_set_cfg(anccfg,ANC_MUSICCANCLE,ANC_GAIN_NO_DELAY); +#endif + } +#ifdef AUDIO_ANC_FB_MC + //process MC + mc_iir_cfg.anc_cfg_mc_l=anccfg->anc_cfg_mc_l; + mc_iir_cfg.anc_cfg_mc_r=anccfg->anc_cfg_mc_r; +#endif + + if(anccfg->anc_cfg_mc_l.adc_gain_offset==0) + { + hal_codec_anc_adc_enable(ANC_FEEDFORWARD); + analog_aud_codec_anc_enable(ANC_FEEDFORWARD, true); + hal_codec_anc_adc_enable(ANC_FEEDBACK); + analog_aud_codec_anc_enable(ANC_FEEDBACK, true); + TRACE(0,"ADC UNMUTE........"); + } + else + { + hal_codec_anc_adc_disable(ANC_FEEDFORWARD); + analog_aud_codec_anc_enable(ANC_FEEDFORWARD, false); + hal_codec_anc_adc_disable(ANC_FEEDBACK); + analog_aud_codec_anc_enable(ANC_FEEDBACK, false); + TRACE(0,"ADC MUTE........"); + } + + if(anccfg->anc_cfg_mc_l.dac_gain_offset==0) + { + analog_aud_codec_nomute(); + TRACE(0,"DAC UNMUTE........"); + } + else + { + analog_aud_codec_mute(); + TRACE(0,"DAC MUTE........"); + } + +#if !defined( AUDIO_ANC_TT_HW) + +#if defined(__HW_IIR_EQ_PROCESS__) + //process EQ + if(anccfg->anc_cfg_tt_l.total_gain ==0) + { + hw_iir_cfg.iir_filtes_l.iir_counter=0; + } + else + { + hw_iir_cfg.iir_filtes_l.iir_counter=anccfg->anc_cfg_tt_l.iir_counter; + } + + if(anccfg->anc_cfg_tt_r.total_gain ==0) + { + hw_iir_cfg.iir_filtes_r.iir_counter=0; + } + else + { + hw_iir_cfg.iir_filtes_r.iir_counter=anccfg->anc_cfg_tt_r.iir_counter; + } + + for(int i=0;ianc_cfg_tt_l.iir_coef[i].coef_b[0]); + hw_iir_cfg.iir_filtes_l.iir_coef[i].coef_b[1]=(anccfg->anc_cfg_tt_l.iir_coef[i].coef_b[1]); + hw_iir_cfg.iir_filtes_l.iir_coef[i].coef_b[2]=(anccfg->anc_cfg_tt_l.iir_coef[i].coef_b[2]); + hw_iir_cfg.iir_filtes_l.iir_coef[i].coef_a[0]=(anccfg->anc_cfg_tt_l.iir_coef[i].coef_a[0]); + hw_iir_cfg.iir_filtes_l.iir_coef[i].coef_a[1]=(anccfg->anc_cfg_tt_l.iir_coef[i].coef_a[1]); + hw_iir_cfg.iir_filtes_l.iir_coef[i].coef_a[2]=(anccfg->anc_cfg_tt_l.iir_coef[i].coef_a[2]); + + hw_iir_cfg.iir_filtes_r.iir_coef[i].coef_b[0]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_b[0]); + hw_iir_cfg.iir_filtes_r.iir_coef[i].coef_b[1]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_b[1]); + hw_iir_cfg.iir_filtes_r.iir_coef[i].coef_b[2]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_b[2]); + hw_iir_cfg.iir_filtes_r.iir_coef[i].coef_a[0]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_a[0]); + hw_iir_cfg.iir_filtes_r.iir_coef[i].coef_a[1]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_a[1]); + hw_iir_cfg.iir_filtes_r.iir_coef[i].coef_a[2]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_a[2]); + } + + hw_iir_set_cfg(&hw_iir_cfg); +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) + +#if 0 + TRACE(1,"__HW_DAC_IIR_EQ_PROCESS__ ........"); + + TRACE(1,"eq gain: %d, counter: %d iir_bypass_flag: %d ",anccfg->anc_cfg_tt_l.total_gain, anccfg->anc_cfg_tt_l.iir_counter,anccfg->anc_cfg_tt_l.iir_bypass_flag); + TRACE(1,"eq dac_gain_offset %d, adc_gain_offset %d",anccfg->anc_cfg_tt_l.dac_gain_offset, anccfg->anc_cfg_tt_l.adc_gain_offset); + + for(int j = 0; j anc_cfg_tt_l.iir_coef[j].coef_b[0], \ + anccfg->anc_cfg_tt_l.iir_coef[j].coef_b[1], \ + anccfg->anc_cfg_tt_l.iir_coef[j].coef_b[2], \ + anccfg->anc_cfg_tt_l.iir_coef[j].coef_a[0], \ + anccfg->anc_cfg_tt_l.iir_coef[j].coef_a[1], \ + anccfg->anc_cfg_tt_l.iir_coef[j].coef_a[2]); + } +#endif + + //process EQ + if(anccfg->anc_cfg_tt_l.total_gain ==0) + { + hw_codec_iir_cfg.iir_filtes_l.iir_counter=0; + } + else + { + hw_codec_iir_cfg.iir_filtes_l.iir_counter=anccfg->anc_cfg_tt_l.iir_counter; + } + + if(anccfg->anc_cfg_tt_r.total_gain ==0) + { + hw_codec_iir_cfg.iir_filtes_r.iir_counter=0; + } + else + { + hw_codec_iir_cfg.iir_filtes_r.iir_counter=anccfg->anc_cfg_tt_r.iir_counter; + } + + for(int i=0;ianc_cfg_tt_l.iir_coef[i].coef_b[0]); + hw_codec_iir_cfg.iir_filtes_l.iir_coef[i].coef_b[1]=(anccfg->anc_cfg_tt_l.iir_coef[i].coef_b[1]); + hw_codec_iir_cfg.iir_filtes_l.iir_coef[i].coef_b[2]=(anccfg->anc_cfg_tt_l.iir_coef[i].coef_b[2]); + hw_codec_iir_cfg.iir_filtes_l.iir_coef[i].coef_a[0]=(anccfg->anc_cfg_tt_l.iir_coef[i].coef_a[0]); + hw_codec_iir_cfg.iir_filtes_l.iir_coef[i].coef_a[1]=(anccfg->anc_cfg_tt_l.iir_coef[i].coef_a[1]); + hw_codec_iir_cfg.iir_filtes_l.iir_coef[i].coef_a[2]=(anccfg->anc_cfg_tt_l.iir_coef[i].coef_a[2]); + + hw_codec_iir_cfg.iir_filtes_r.iir_coef[i].coef_b[0]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_b[0]); + hw_codec_iir_cfg.iir_filtes_r.iir_coef[i].coef_b[1]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_b[1]); + hw_codec_iir_cfg.iir_filtes_r.iir_coef[i].coef_b[2]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_b[2]); + hw_codec_iir_cfg.iir_filtes_r.iir_coef[i].coef_a[0]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_a[0]); + hw_codec_iir_cfg.iir_filtes_r.iir_coef[i].coef_a[1]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_a[1]); + hw_codec_iir_cfg.iir_filtes_r.iir_coef[i].coef_a[2]=(anccfg->anc_cfg_tt_r.iir_coef[i].coef_a[2]); + } + + if (anc_sample_rate == AUD_SAMPRATE_50781) + { + hw_codec_iir_set_cfg(&hw_codec_iir_cfg, AUD_SAMPRATE_50781, HW_CODEC_IIR_DAC); + } + else + { + hw_codec_iir_set_cfg(&hw_codec_iir_cfg, AUD_SAMPRATE_48000, HW_CODEC_IIR_DAC); + } +#endif +#endif + send_reply(&cret, 1); + break; + } + case ANC_CMD_CFG_SETUP: + { + TRACE(0,"ANC_CMD_CFG_SETUP ------"); + + int ret = 0; + bool diff; + bool high_performance_adc; + bool vcrystal_on; + uint16_t vcodec; + pctool_iocfg *iocfg1, *iocfg2; + + if(data[0]==1) + { + pcsuppt_anc_type = ANC_FEEDFORWARD; + } + else if(data[0]==2) + { + pcsuppt_anc_type = ANC_FEEDBACK; + } + else if(data[0]==3) + { + pcsuppt_anc_type = ANC_FEEDFORWARD|ANC_FEEDBACK; + } + + vcodec = (data[1] | (data[2] << 8)); + diff = (bool)data[3]; + high_performance_adc = false; //(bool)data[4]; // default 0 + anc_sample_rate = (data[5] | (data[6] << 8) | (data[7] << 16) | (data[8] << 24)); + vcrystal_on = data[9]; //(bool)data[?]; // default 0 + TRACE(4,"vcodec:%d,diff:%d,anc_sample_rate:%d,vcrystal_on:%d.", vcodec,diff,anc_sample_rate,vcrystal_on); + ret |= pmu_debug_config_vcrystal(vcrystal_on); + ret |= analog_debug_config_audio_output(diff); + ret |= analog_debug_config_codec(vcodec); + ret |= analog_debug_config_low_power_adc(!high_performance_adc); + if (anc_sample_rate == AUD_SAMPRATE_50781) { + hal_cmu_audio_resample_enable(); + } else { + hal_cmu_audio_resample_disable(); + } + iocfg1 = (pctool_iocfg *)(&data[10]); + iocfg2 = (pctool_iocfg *)(&data[12]); + TRACE(4,"io cfg:%d %d %d %d",iocfg1->io_pin,iocfg1->set_flag,iocfg2->io_pin,iocfg2->set_flag); + if(iocfg1->io_pin>=0) + anc_set_gpio(iocfg1->io_pin,iocfg1->set_flag); + if(iocfg2->io_pin>=0) + anc_set_gpio(iocfg2->io_pin,iocfg2->set_flag); + cret = ret ? ERR_INTERNAL : ERR_NONE; + + send_reply((unsigned char *)&cret, 1); + break; + } + case ANC_CMD_CHANNEL_SETUP: + { + + const enum AUD_CHANNEL_MAP_T channel_map_arr[16] = { + AUD_CHANNEL_MAP_CH0, + AUD_CHANNEL_MAP_CH1, + AUD_CHANNEL_MAP_CH2, + AUD_CHANNEL_MAP_CH3, + AUD_CHANNEL_MAP_CH4, + AUD_CHANNEL_MAP_CH5, + AUD_CHANNEL_MAP_CH6, + AUD_CHANNEL_MAP_CH7, + AUD_CHANNEL_MAP_DIGMIC_CH0, + AUD_CHANNEL_MAP_DIGMIC_CH1, + AUD_CHANNEL_MAP_DIGMIC_CH2, + AUD_CHANNEL_MAP_DIGMIC_CH3, + AUD_CHANNEL_MAP_DIGMIC_CH4, + AUD_CHANNEL_MAP_DIGMIC_CH5, + AUD_CHANNEL_MAP_DIGMIC_CH6, + AUD_CHANNEL_MAP_DIGMIC_CH7, + }; + anc_ff_mic_ch_l = channel_map_arr[data[0]]; + anc_ff_mic_ch_r = channel_map_arr[data[1]]; + anc_fb_mic_ch_l = channel_map_arr[data[2]]; + anc_fb_mic_ch_r = channel_map_arr[data[3]]; + TRACE(4,"anc_ff_mic_ch_l 0x%x,anc_ff_mic_ch_r 0x%x,anc_fb_mic_ch_l 0x%x,anc_fb_mic_ch_r 0x%x", + anc_ff_mic_ch_l, anc_ff_mic_ch_r, anc_fb_mic_ch_l, anc_fb_mic_ch_r); + + hal_iomux_set_dig_mic_clock_pin(data[4]); + hal_iomux_set_dig_mic_data0_pin(data[5]); + hal_iomux_set_dig_mic_data1_pin(data[6]); + hal_iomux_set_dig_mic_data2_pin(data[7]); + uint8_t phase = data[8]; +#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A) + analog_debug_config_vad_mic(!!(phase & (1 << 7))); + phase &= ~(1 << 7); +#endif + hal_codec_config_digmic_phase(phase); + + send_reply((unsigned char *)&cret, 1); + break; + } + case ANC_CMD_SET_SAMP_RATE: + { + bool opened; + + opened = (anc_opened(ANC_FEEDFORWARD) || anc_opened(ANC_FEEDBACK)); + if (opened) + { + anc_disable(); + tool_anc_close(); + } + anc_sample_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + if (anc_sample_rate == AUD_SAMPRATE_50781) { + hal_cmu_audio_resample_enable(); + } else { + hal_cmu_audio_resample_disable(); + } + if (opened) + { + tool_anc_open(); + anc_enable(); + } + send_reply((unsigned char *)&cret, 1); + break; + } + } + + return ERR_NONE; + } +static int get_sector_info(unsigned int addr, unsigned int *sector_addr, unsigned int *sector_len) +{ + int ret; + + ret = hal_norflash_get_boundary(HAL_NORFLASH_ID_0, addr, NULL, (uint32_t *)sector_addr); + if (ret) { + return ret; + } + + ret = hal_norflash_get_size(HAL_NORFLASH_ID_0, NULL, NULL, (uint32_t *)sector_len, NULL); + + return ret; +} +static int erase_sector(unsigned int sector_addr, unsigned int sector_len) +{ + return hal_norflash_erase(HAL_NORFLASH_ID_0, sector_addr, sector_len); +} + +static int erase_chip(void) +{ + return hal_norflash_erase_chip(HAL_NORFLASH_ID_0); +} + +static int burn_data(unsigned int addr, const unsigned char *data, unsigned int len) +{ + int ret; + + ret = hal_norflash_write(HAL_NORFLASH_ID_0, addr, data, len); + return ret; +} + +static int verify_flash_data(unsigned int addr, const unsigned char *data, unsigned int len) +{ + const unsigned char *fdata; + const unsigned char *mdata; + int i; + + fdata = (unsigned char *)addr; + mdata = data; + for (i = 0; i < len; i++) { + if (*fdata++ != *mdata++) { + --fdata; + --mdata; + TRACE(4,"*** Verify flash data failed: 0x%02X @ %p != 0x%02X @ %p", *fdata, fdata, *mdata, mdata); + return *fdata - *mdata; + } + } + return 0; +} +static enum ERR_CODE handle_sector_info_cmd(unsigned int addr) +{ + unsigned int sector_addr; + unsigned int sector_len; + unsigned char buf[9]; + int ret; + + ret = get_sector_info(addr, §or_addr, §or_len); + if (ret) { + return ERR_DATA_ADDR; + } + + TRACE(3,"addr=0x%08X sector_addr=0x%08X sector_len=%u", addr, sector_addr, sector_len); + + buf[0] = ERR_NONE; + memcpy(&buf[1], §or_addr, 4); + memcpy(&buf[5], §or_len, 4); + + send_reply(buf, 9); + + return ERR_NONE; +} +static enum ERR_CODE handle_flash_cmd(enum FLASH_CMD_TYPE cmd, unsigned char *param, unsigned int len) +{ + int ret = 0; + unsigned char cret = ERR_NONE; + const char *name = NULL; + + switch (cmd) { + case FLASH_CMD_ERASE_SECTOR: + { + unsigned int addr; + unsigned int size; + + if (cmd == FLASH_CMD_ERASE_SECTOR) + { + name = "ERASE_SECTOR"; + } + + trace_flash_cmd_info(name); + + if (len != 8) + { + trace_flash_cmd_len_err(name, len); + return ERR_LEN; + } + + addr = param[0] | (param[1] << 8) | (param[2] << 16) | (param[3] << 24); + size = param[4] | (param[5] << 8) | (param[6] << 16) | (param[7] << 24); + TRACE(2,"addr=0x%08X size=%u", addr, size); + + if (cmd == FLASH_CMD_ERASE_SECTOR) + { + ret = erase_sector(addr, size); + } + + if (ret) { + trace_flash_cmd_err(name); + return ERR_ERASE_FLSH; + } + + trace_flash_cmd_done(name); + + send_reply(&cret, 1); + break; + } + case FLASH_CMD_BURN_DATA: + { + unsigned int addr; + + if (cmd == FLASH_CMD_BURN_DATA) + { + name = "BURN_DATA"; + } + + trace_flash_cmd_info(name); + + if (len <= 4 || len > 20) { + trace_flash_cmd_len_err(name, len); + return ERR_LEN; + } + + addr = param[0] | (param[1] << 8) | (param[2] << 16) | (param[3] << 24); + TRACE(2,"addr=0x%08X len=%u", addr, len - 4); + + if (cmd == FLASH_CMD_BURN_DATA) + { + ret = burn_data(addr, ¶m[4], len - 4); + } + + if (ret) { + trace_flash_cmd_err(name); + return ERR_BURN_FLSH; + } + + TRACE_TIME(1,"%s verifying", name); + + if (cmd == FLASH_CMD_BURN_DATA) + { + ret = verify_flash_data(addr, ¶m[4], len - 4); + } + if (ret) { + TRACE(1,"%s verify failed", name); + return ERR_VERIFY_FLSH; + } + + trace_flash_cmd_done(name); + + send_reply(&cret, 1); + break; + } + case FLASH_CMD_ERASE_CHIP: { + name = "CMD_ERASE_CHIP"; + + trace_flash_cmd_info(name); + + if (len != 0) { + trace_flash_cmd_len_err(name, len); + return ERR_LEN; + } + + ret = erase_chip(); + if (ret) { + trace_flash_cmd_err(name); + return ERR_ERASE_FLSH; + } + + trace_flash_cmd_done(name); + + send_reply(&cret, 1); + break; + } + default: + TRACE(1,"Unsupported flash cmd: 0x%x", cmd); + return ERR_FLASH_CMD; + } + + return ERR_NONE; +} +/* +#define SECTOR_SIZE_64K (1 << 16) +#define SECTOR_SIZE_32K (1 << 15) +#define SECTOR_SIZE_16K (1 << 14) +#define SECTOR_SIZE_4K (1 << 12) +*/ +#define BURN_DATA_MSG_OVERHEAD 16 + +//static const unsigned int size_mask = SECTOR_SIZE_32K | SECTOR_SIZE_4K; + +enum PROGRAMMER_STATE { + PROGRAMMER_NONE, + PROGRAMMER_ERASE_BURN_START, + PROGRAMMER_SEC_REG_ERASE_BURN_START, +}; + + +#define BURN_BUFFER_LOC __attribute__((section(".burn_buffer"))) + +static unsigned char BURN_BUFFER_LOC data_buf[65536+2048]; +static enum PROGRAMMER_STATE programmer_state=PROGRAMMER_NONE; + +/* +static unsigned int count_set_bits(unsigned int i) +{ + i = i - ((i >> 1) & 0x55555555); + i = (i & 0x33333333) + ((i >> 2) & 0x33333333); + return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; +} +*/ + +static int send_burn_data_reply(enum ERR_CODE code, unsigned short sec_seq, unsigned char seq) +{ + int ret = 0; + enum MSG_TYPE type = TYPE_INVALID; + + if (programmer_state == PROGRAMMER_ERASE_BURN_START) { + type = TYPE_ERASE_BURN_DATA; + } + + send_msg.hdr.type = type; + send_msg.hdr.seq = recv_msg.hdr.seq; + send_msg.hdr.len = 3; + send_msg.data[0] = code; + send_msg.data[1] = sec_seq & 0xFF; + send_msg.data[2] = (sec_seq >> 8) & 0xFF; + send_msg.data[3] = ~check_sum((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg) - 1); + + send_msg_push_seq=send_msg_push_seq%MAX_SNED_MSG_QUEUE; + send_msg_queue[send_msg_push_seq]=send_msg; + send_msg_push_seq++; + + //ret = send_data((unsigned char *)&send_msg, MSG_TOTAL_LEN(&send_msg)); + return ret; +} + +int anc_cmd_receve_process(uint8_t *buf,uint32_t len) +{ + enum MSG_TYPE type; + enum ERR_CODE errcode=ERR_NONE; + unsigned char cret = ERR_NONE; + + if(len>sizeof(recv_msg)) + { + memcpy(&recv_msg,buf,sizeof(recv_msg)); + } + else + { + memcpy(&recv_msg,buf,len); + } + // Checksum + if (check_sum((unsigned char *)&recv_msg, MSG_TOTAL_LEN(&recv_msg)) != 0xFF) { + trace_stage_info("Checksum error"); + return ERR_CHECKSUM; + } + type = recv_msg.hdr.type; + + //TRACE(1,"COMMAND:0x%x",type); + + switch (type) { + case TYPE_SYS: + { + TRACE(0,"SYS CMD"); + break; + } + case TYPE_READ: + { + unsigned int addr; + unsigned int len; + + trace_stage_info("READ CMD"); + + addr = recv_msg.data[0] | (recv_msg.data[1] << 8) | (recv_msg.data[2] << 16) | (recv_msg.data[3] << 24); + len = recv_msg.data[4]; + + TRACE(2,"addr:0x%x,len:%d",addr,len); + + errcode = handle_read_cmd(type, addr, len); + if (errcode != ERR_NONE) { + return errcode; + } + break; + } + case TYPE_WRITE: + { + unsigned int addr; + unsigned int len; + unsigned char *wdata; + + // trace_stage_info("WRITE CMD"); + + addr = recv_msg.data[0] | (recv_msg.data[1] << 8) | (recv_msg.data[2] << 16) | (recv_msg.data[3] << 24); + len = recv_msg.hdr.len - 4; + wdata = &recv_msg.data[4]; + + errcode = handle_write_cmd(addr, len, wdata); + if (errcode != ERR_NONE) { + return errcode; + } + break; + } + case TYPE_ERASE_BURN_START: + { + TRACE(0,"TYPE_ERASE_BURN_START CMD"); + + if(programmer_state == PROGRAMMER_NONE) + { + trace_stage_info("ERASE_BURN_START"); + + burn_addr = recv_msg.data[0] | (recv_msg.data[1] << 8) | (recv_msg.data[2] << 16) | (recv_msg.data[3] << 24); + burn_total_len = recv_msg.data[4] | (recv_msg.data[5] << 8) | (recv_msg.data[6] << 16) | (recv_msg.data[7] << 24); + sector_size = recv_msg.data[8] | (recv_msg.data[9] << 8) | (recv_msg.data[10] << 16) | (recv_msg.data[11] << 24); + + TRACE(3,"burn_addr=0x%08X burn_total_len=%u sector_size=%u", burn_addr, burn_total_len, sector_size); + + /*if ((size_mask & sector_size) == 0 || count_set_bits(sector_size) != 1) + { + TRACE(2,"Unsupported sector_size=0x%08X mask=0x%08X", sector_size, size_mask); + return ERR_SECTOR_SIZE; + }*/ + + sector_cnt = burn_total_len / sector_size; + last_sector_len = burn_total_len % sector_size; + + if (last_sector_len) + { + sector_cnt++; + } + else + { + last_sector_len = sector_size; + } + + if (sector_cnt > 0xFFFF) + { + TRACE(1,"Sector seq overflow: %u", sector_cnt); + return ERR_SECTOR_SEQ_OVERFLOW; + } + + send_reply(&cret, 1); + + if (burn_total_len == 0) { + TRACE(0,"Burn length = 0"); + break; + } + + programmer_state = PROGRAMMER_ERASE_BURN_START; + + burn_len=0; + + + trace_stage_info("ERASE_BURN_START end"); + } + else + { + TRACE(1,"ERROR programmer_state status:%d",programmer_state); + } + break; + } + case TYPE_ERASE_BURN_DATA: + { + + if(programmer_state == PROGRAMMER_ERASE_BURN_START) + { + unsigned int dlen; + unsigned int mcrc; + unsigned int crc; + + dlen = recv_msg.data[0] | (recv_msg.data[1] << 8) | (recv_msg.data[2] << 16) | (recv_msg.data[3] << 24); + mcrc = recv_msg.data[4] | (recv_msg.data[5] << 8) | (recv_msg.data[6] << 16) | (recv_msg.data[7] << 24); + + cur_sector_seq = recv_msg.data[8] | (recv_msg.data[9] << 8); + + TRACE(2," sec_seq=%u dlen=%u", cur_sector_seq, dlen); + + if (cur_sector_seq >= sector_cnt) { + TRACE(2,"Bad sector seq: sec_seq=%u sector_cnt=%u", cur_sector_seq, sector_cnt); + send_burn_data_reply(ERR_SECTOR_SEQ, cur_sector_seq, recv_msg.hdr.seq); + return ERR_NONE; + } + + if (((cur_sector_seq + 1) == sector_cnt && dlen != last_sector_len) || + ((cur_sector_seq + 1) != sector_cnt && dlen != sector_size)) { + TRACE(2," Bad data len: sec_seq=%u dlen=%u", cur_sector_seq, dlen); + send_burn_data_reply(ERR_SECTOR_DATA_LEN, cur_sector_seq, recv_msg.hdr.seq); + return ERR_NONE; + } + + crc = crc32(0, (unsigned char *)&buf[BURN_DATA_MSG_OVERHEAD], dlen); + if (crc != mcrc) + { + TRACE(0,"Bad CRC"); + send_burn_data_reply(ERR_SECTOR_DATA_CRC, cur_sector_seq, recv_msg.hdr.seq); + return ERR_NONE; + } + + if(burn_len+dlen<=burn_total_len) + { + memcpy(&data_buf[burn_len],(unsigned char *)&buf[BURN_DATA_MSG_OVERHEAD], dlen); + burn_len=burn_len+dlen; + } + else + { + TRACE(2,"Error burn_len=%d,burn_total_len=%d", burn_len, burn_total_len); + } + + if(burn_len==burn_total_len) + { + TRACE(2,"BURN_DATA addr=0x%08X len=%u .........................", burn_addr, burn_total_len); + int ret=burn_data(burn_addr,data_buf,burn_total_len); + if (ret) + { + TRACE(2,"### FLASH_TASK: BURN_DATA failed: addr=0x%08X len=%u ###", burn_addr, burn_total_len); + return 0; + } + else + { + TRACE(0,"burn sucessful"); + } + ret = verify_flash_data(burn_addr,data_buf,burn_total_len); + if (ret) + { + TRACE(0,"verify failed"); + return ERR_VERIFY_FLSH; + } + else + { + TRACE(0,"verify sucessful"); + } + + } + + send_burn_data_reply(ERR_BURN_OK,cur_sector_seq,recv_msg.hdr.seq); + + } + else + { + TRACE(1,"ERROR programmer_state status:%d",programmer_state); + } + break; + } + case TYPE_FLASH_CMD: + { + trace_stage_info("FLASH CMD"); + + errcode = handle_flash_cmd((enum FLASH_CMD_TYPE)recv_msg.data[0], &recv_msg.data[1], recv_msg.hdr.len - 1); + + TRACE_TIME(1,"FLASH CMD ret=%d", errcode); + + if (errcode != ERR_NONE) { + return errcode; + } + break; + } + case TYPE_GET_SECTOR_INFO: + { + unsigned int addr; + + trace_stage_info("GET SECTOR INFO"); + + addr = recv_msg.data[0] | (recv_msg.data[1] << 8) | (recv_msg.data[2] << 16) | (recv_msg.data[3] << 24); + + errcode = handle_sector_info_cmd(addr); + if (errcode != ERR_NONE) { + return errcode; + } + break; + } + case TYPE_PROD_TEST: { + uint32_t cmd; + + trace_stage_info("ANC CMD"); + + cmd = recv_msg.data[0] | (recv_msg.data[1] << 8) | (recv_msg.data[2] << 16) | (recv_msg.data[3] << 24); + if (cmd != PROD_TEST_CMD_ANC) { + return ERR_TYPE_INVALID; + } + + if (recv_msg.hdr.len < 5) { + TRACE(1,"PROD_TEST/ANC msg length error: %d", recv_msg.hdr.len); + return ERR_LEN; + } + + errcode = handle_anc_cmd(recv_msg.data[4], &recv_msg.data[5], recv_msg.hdr.len - 5); + if (errcode != ERR_NONE) { + return errcode; + } + + break; + } + default: + TRACE(1,"COMMAND:0x%x",type); + + cret = ERR_TYPE_INVALID; + send_reply((unsigned char *)&cret, 1); + break; + + } + + + return 0; +} +int anc_cmd_send_process(uint8_t **pbuf,uint16_t *len) +{ + + + send_msg_pop_seq=send_msg_pop_seq%MAX_SNED_MSG_QUEUE; + *pbuf = (uint8_t *)&send_msg_queue[send_msg_pop_seq]; + *len = MSG_TOTAL_LEN(&send_msg); + send_msg_pop_seq++; + + return 0; +} +#endif + + + + + + + + + diff --git a/services/multimedia/audio/process/anc/include/anc_process.h b/services/multimedia/audio/process/anc/include/anc_process.h new file mode 100644 index 0000000..fab39c3 --- /dev/null +++ b/services/multimedia/audio/process/anc/include/anc_process.h @@ -0,0 +1,107 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ANC_PROCESS_H__ +#define __ANC_PROCESS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "aud_section.h" +#include "hal_aud.h" + +typedef enum { + ANC_NO_ERR=0, + ANC_TYPE_ERR, + ANC_GAIN_ERR, + ANC_OTHER_ERR, + ANC_ERR_TOTAL, +}ANC_ERROR; + +typedef enum { + ANC_GAIN_NO_DELAY=0, + ANC_GAIN_DELAY, + ANC_GAIN_TOTAL, +}ANC_GAIN_TIME; + + +typedef struct _aud_fir_item +{ + int32_t fir_bypass_flag; + int32_t fir_len; + int32_t fir_coef[AUD_COEF_LEN]; +} aud_fir_item; + +typedef struct _struct_anc_fir_cfg +{ + aud_fir_item anc_fir_cfg_ff_l; + aud_fir_item anc_fir_cfg_ff_r; + aud_fir_item anc_fir_cfg_fb_l; + aud_fir_item anc_fir_cfg_fb_r; + aud_fir_item anc_fir_cfg_tt_l; + aud_fir_item anc_fir_cfg_tt_r; + aud_fir_item anc_fir_cfg_mc_l; + aud_fir_item anc_fir_cfg_mc_r; +} struct_anc_fir_cfg; + +int anc_set_fir_cfg( struct_anc_fir_cfg * cfg, enum ANC_TYPE_T anc_type); + +int anc_opened(enum ANC_TYPE_T anc_type); +int anc_open(enum ANC_TYPE_T anc_type); +void anc_close(enum ANC_TYPE_T anc_type); + +int anc_disable(void); +int anc_enable(void); + +int anc_set_cfg(const struct_anc_cfg * cfg,enum ANC_TYPE_T anc_type,ANC_GAIN_TIME anc_gain_delay); +int anc_set_gain(int32_t gain_ch_l, int32_t gain_ch_r,enum ANC_TYPE_T anc_type); +int anc_get_gain(int32_t *gain_ch_l, int32_t *gain_ch_r,enum ANC_TYPE_T anc_type); +int anc_get_cfg_gain(int32_t *gain_ch_l, int32_t *gain_ch_r,enum ANC_TYPE_T anc_type); + + + + +//void AncPduHardwarCh0(const short Coef[], short CoefLen); +//void AncPduHardwarCh1(const short Coef[], short CoefLen); +void AncPduHardwarCh0(const short Coef[], short CoefLen,short gain); +void AncPduHardwarCh1(const short Coef[], short CoefLen,short gain); + +int anc_select_coef(enum AUD_SAMPRATE_T rate,enum ANC_INDEX index,enum ANC_TYPE_T anc_type,ANC_GAIN_TIME anc_gain_delay); +int anc_load_cfg(void); +int anc_cmd_receve_process(uint8_t *buf,uint32_t len); +int anc_cmd_send_process(uint8_t **pbuf,uint16_t *len); + +enum ANC_INDEX anc_get_current_coef_index(void); +enum AUD_SAMPRATE_T anc_get_current_coef_samplerate(void); +int anc_mc_run_stereo(uint8_t *buf, int len,float left_gain,float right_gain,enum AUD_BITS_T sample_bit); +int anc_mc_run_mono(uint8_t *buf, int len,float left_gain,enum AUD_BITS_T sample_bit); + +void anc_mc_run_init(enum AUD_SAMPRATE_T rate); +void anc_mc_run_setup(enum AUD_SAMPRATE_T rate); + +void anc_disable_gain_updated_when_pass0(uint8_t on); +void anc_set_ch_map( int32_t ch_map ); +void anc_fb_check_set(int32_t flag ); +void anc_fb_check_irq_handler(uint32_t status); +void anc_fb_check_param(void); +void anc_fb_check_stop_timer(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/anc/include/fftfilt2.h b/services/multimedia/audio/process/anc/include/fftfilt2.h new file mode 100644 index 0000000..a80a630 --- /dev/null +++ b/services/multimedia/audio/process/anc/include/fftfilt2.h @@ -0,0 +1,37 @@ +#ifndef FFTFILT2_H +#define FFTFILT2_H + +#include + +typedef struct +{ + float *filter; + int filter_length; + int nfft; +} FftFilt2Config; + +struct FftFilt2State_; + +typedef struct FftFilt2State_ FftFilt2State; + +#ifdef __cplusplus +extern "C" { +#endif + +FftFilt2State *fftfilt2_init(int sample_rate, int frame_size, const FftFilt2Config *config); + +void fftfilt2_destroy(FftFilt2State *st); + +void fftfilt2_process_float(FftFilt2State *st, float *filter,float *buf, int frame_size); + +void fftfilt2_process(FftFilt2State *st, float *filter,int16_t *buf, int frame_size); + +void fftfilt2_process2_float(FftFilt2State *st, float *filter,float *buf, int frame_size, int stride); + +void fftfilt2_process2(FftFilt2State *st, float *filter,int16_t *buf, int frame_size, int stride); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/audio/process/common/include/audio_memory.h b/services/multimedia/audio/process/common/include/audio_memory.h new file mode 100644 index 0000000..2fe9e13 --- /dev/null +++ b/services/multimedia/audio/process/common/include/audio_memory.h @@ -0,0 +1,69 @@ +#ifndef AUDIO_MEMORY_H +#define AUDIO_MEMORY_H + +#include "string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef VQE_SIMULATE + +#include "heap_api.h" + +extern heap_handle_t g_audio_heap; + +inline void audio_heap_init(void *begin_addr, size_t size) +{ + memset(begin_addr,0,size); + g_audio_heap = heap_register(begin_addr,size); +} + +inline void *audio_malloc(size_t size) +{ + return heap_malloc(g_audio_heap,size); +} + +inline void audio_free(void *p) +{ + heap_free(g_audio_heap,p); +} + +inline void *audio_calloc(size_t nmemb, size_t size) +{ + void *ptr = audio_malloc(nmemb*size); + if (ptr != NULL) + memset(ptr,0,nmemb*size); + return ptr; +} + +inline void *audio_realloc(void *ptr, size_t size) +{ + return heap_realloc(g_audio_heap,ptr,size); +} + +inline void audio_memory_info(size_t *total, + size_t *used, + size_t *max_used) +{ + heap_memory_info(g_audio_heap,total,used,max_used); +} +#else +#include +#include + +void audio_heap_init(void *begin_addr, size_t size); +void *audio_malloc(size_t size); +void audio_free(void *p); +void *audio_calloc(size_t nmemb, size_t size); +void *audio_realloc(void *ptr, size_t size); +void audio_memory_info(size_t *total, + size_t *used, + size_t *max_used); +#endif + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/audio/process/drc/include/drc.h b/services/multimedia/audio/process/drc/include/drc.h new file mode 100644 index 0000000..be3a3c6 --- /dev/null +++ b/services/multimedia/audio/process/drc/include/drc.h @@ -0,0 +1,81 @@ +#ifndef DRC_H +#define DRC_H + +#include + +#define MAX_DRC_FILTER_CNT_SUPPORT 2 + +#define DRC_BAND_NUM (3) + +enum +{ + DRC_FREQ_NULL = -1, + DRC_FREQ_50HZ = 1, + DRC_FREQ_63HZ, + DRC_FREQ_79HZ, + DRC_FREQ_100HZ, + DRC_FREQ_125HZ, + DRC_FREQ_158HZ, + DRC_FREQ_199HZ, + DRC_FREQ_251HZ, + DRC_FREQ_316HZ, + DRC_FREQ_398HZ, + DRC_FREQ_501HZ, + DRC_FREQ_630HZ, + DRC_FREQ_794HZ, + DRC_FREQ_1000HZ, + DRC_FREQ_1258HZ, + DRC_FREQ_1584HZ, + DRC_FREQ_1995HZ, + DRC_FREQ_2511HZ, + DRC_FREQ_3162HZ, + DRC_FREQ_3981HZ, + DRC_FREQ_5011HZ, + DRC_FREQ_6309HZ, + DRC_FREQ_7943HZ, + DRC_FREQ_10000HZ, + DRC_FREQ_12589HZ, + DRC_FREQ_15848HZ, + DRC_FREQ_19952HZ, +}; + +struct DrcBandConfig +{ + int threshold; + float makeup_gain; + int ratio; // set 1, bypass, reduce mips + int attack_time; + int release_time; + float scale_fact; // invalid +}; + +typedef struct +{ + int knee; + int filter_type[MAX_DRC_FILTER_CNT_SUPPORT]; // filter type is choosen from DRC_FREQ_NULL~DRC_FREQ_19952HZ + int band_num; + int look_ahead_time; + struct DrcBandConfig band_settings[DRC_BAND_NUM]; +} DrcConfig; + +struct DrcState_; + +typedef struct DrcState_ DrcState; + +#ifdef __cplusplus +extern "C" { +#endif + +DrcState *drc_create(int sample_rate, int frame_size, int sample_bit, int ch_num, const DrcConfig *config); + +int32_t drc_destroy(DrcState *st); + +int32_t drc_set_config(DrcState *st, const DrcConfig *config); + +int32_t drc_process(DrcState *st, uint8_t *buf, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/audio/process/filters/cfg/Makefile b/services/multimedia/audio/process/filters/cfg/Makefile new file mode 100644 index 0000000..2dbd4d1 --- /dev/null +++ b/services/multimedia/audio/process/filters/cfg/Makefile @@ -0,0 +1,13 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ifeq ($(AUDIO_RESAMPLE),1) +CFLAGS_eq_cfg.o += -D__AUDIO_RESAMPLE__ +endif + +ccflags-y := \ + -Iservices/multimedia/audio/process/filters/include \ diff --git a/services/multimedia/audio/process/filters/cfg/eq_cfg.c b/services/multimedia/audio/process/filters/cfg/eq_cfg.c new file mode 100644 index 0000000..d07ffba --- /dev/null +++ b/services/multimedia/audio/process/filters/cfg/eq_cfg.c @@ -0,0 +1,421 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "tgt_hardware.h" +#include "filter_debug_trace.h" +#include "iir_process.h" +#include "eq_cfg.h" +#include "hw_codec_iir_process.h" +#include "hw_iir_process.h" +#include "math.h" + +#define IIR_FIXED_Q (1<<27) + +#define PI (3.14159265358979) + +static HW_CODEC_IIR_CFG_T hw_codec_iir_eq; +static HW_IIR_CFG_T hw_iir_eq; + +void iir_lowshelf_coefs_generate(float gain, float fn, float Q, float *coefs) +{ + float A = (float)sqrtf(powf(10, gain / 20)); + float w0 = 2 * PI*fn; + float alpha = (float)sinf(w0)/(2*Q); + + float a0 = (A + 1) + (A - 1)*(float)cosf(w0) + 2 * (float)sqrtf(A)*alpha; + float a1 = (-2 * ((A - 1) + (A + 1)*(float)cosf(w0))); + float a2 = ((A + 1) + (A - 1)*(float)cosf(w0) - 2 * (float)sqrtf(A)*alpha); + float b0 = (A*((A + 1) - (A - 1)*(float)cosf(w0) + 2 *(float)sqrtf(A)*alpha)); + float b1 = (2 * A*((A - 1) - (A + 1)*(float)cosf(w0))); + float b2 = (A*((A + 1) - (A - 1)*(float)cosf(w0) - 2 * (float)sqrtf(A)*alpha)); + + coefs[0] = 1; + coefs[1] = a1 / a0; + coefs[2] = a2 / a0; + coefs[3] = b0 / a0; + coefs[4] = b1 / a0; + coefs[5] = b2 / a0; + +// IIR_TRACE(6,"fn = %f, gain = %f, Q = %f, A = %f, w0 = %f, alpha = %f", fn, gain, Q, A, w0, alpha); +// FILTER_DEBUG_TRACE(7,"[%s] %f, %f, %f, %f, %f, %f", __func__, (double)coefs[0], (double)coefs[1], (double)coefs[2], (double)coefs[3], (double)coefs[4], (double)coefs[5]); +} + +void iir_highshelf_coefs_generate(float gain, float fn, float Q, float *coefs) +{ + float A = (float)sqrtf(powf(10, gain / 20)); + float w0 = 2 * PI*fn; + float alpha = (float)sinf(w0) / (2 * Q); + + float a0 = (A + 1) - (A - 1)*(float)cosf(w0) + 2 * (float)sqrtf(A)*alpha; // a0 + float a1 = (2 * ((A - 1) - (A + 1)*(float)cosf(w0))); // a1 + float a2 = ((A + 1) - (A - 1)*(float)cosf(w0) - 2 * (float)sqrtf(A)*alpha); //a2 + float b0 = (A*((A + 1) + (A - 1)*(float)cosf(w0) + 2 * (float)sqrtf(A)*alpha)); //b0 + float b1 = (-2 * A*((A - 1) + (A + 1)*(float)cosf(w0))); // b1 + float b2 = (A*((A + 1) + (A - 1)*(float)cosf(w0) - 2 * (float)sqrtf(A)*alpha)); // b2 + + coefs[0] = 1; + coefs[1] = a1 / a0; + coefs[2] = a2 / a0; + coefs[3] = b0 / a0; + coefs[4] = b1 / a0; + coefs[5] = b2 / a0; + +// IIR_TRACE(6,"fn = %f, gain = %f, Q = %f, A = %f, w0 = %f, alpha = %f", fn, gain, Q, A, w0, alpha); + // FILTER_DEBUG_TRACE(7,"[%s] %f, %f, %f, %f, %f, %f", __func__, (double)coefs[0], (double)coefs[1], (double)coefs[2], (double)coefs[3], (double)coefs[4], (double)coefs[5]); +} + +// fn: Normalized frequency +void iir_peak_notch_coefs_generate(float gain, float fn, float Q, float *coefs) +{ +// float Fs = 1000.0 / 48000.0; +// float gain = -5.0; +// float fo = 1000.0; +// float Q = 0.7; + float A = (float)sqrtf(powf(10, gain/20)); + float w0 = 2*PI*fn; + float alpha = (float)sinf(w0)/(2*Q); + + float a0 = 1 + alpha/A; + float a1 = -2*(float)cosf(w0); + float a2 = 1 - alpha/A; + float b0 = 1 + alpha*A; + float b1 = -2*(float)cosf(w0); + float b2 = 1 - alpha*A; + + coefs[0] = 1; + coefs[1] = a1 / a0; + coefs[2] = a2 / a0; + coefs[3] = b0 / a0; + coefs[4] = b1 / a0; + coefs[5] = b2 / a0; + +// IIR_TRACE(6,"fn = %f, gain = %f, Q = %f, A = %f, w0 = %f, alpha = %f", fn, gain, Q, A, w0, alpha); + // FILTER_DEBUG_TRACE(7,"[%s] %f, %f, %f, %f, %f, %f", __func__, (double)coefs[0], (double)coefs[1], (double)coefs[2], (double)coefs[3], (double)coefs[4], (double)coefs[5]); +} + +void iir_highpass_coefs_generate(float gain, float fn, float Q, float *coefs) +{ + float w0 = 2 * PI*fn; + float alpha = (float)sinf(w0) / (2 * Q); + + float a0 = 1 + alpha; + float a1 = -2 * (float)cosf(w0); + float a2 = 1 - alpha; + float b0 = (1 + (float)cosf(w0))/2; + float b1 = -(1 + (float)cosf(w0)); + float b2 = (1 + (float)cosf(w0))/2; + + coefs[0] = 1; + coefs[1] = a1/a0; + coefs[2] = a2/a0; + coefs[3] = b0/a0; + coefs[4] = b1/a0; + coefs[5] = b2/a0; +} + +void iir_lowspass_coefs_generate(float gain, float fn, float Q, float *coefs) +{ + float w0 = 2 * PI*fn; + float alpha = (float)sinf(w0) / (2 * Q); + + float a0 = 1 + alpha; + float a1 = -2 * (float)cosf(w0); + float a2 = 1 - alpha; + float b0 = (1 - (float)cosf(w0))/2; + float b1 = 1 - (float)cosf(w0); + float b2 = (1 - (float)cosf(w0))/2; + + coefs[0] = 1; + coefs[1] = a1/a0; + coefs[2] = a2/a0; + coefs[3] = b0/a0; + coefs[4] = b1/a0; + coefs[5] = b2/a0; +} + +float iir_convert_db_to_multiple(float db) +{ + return (float)powf(10, db/20); +} + +void iir_coefs_generate(IIR_TYPE_T type, float gain, float fn, float Q, float *coefs) +{ + // As it is meaningless to set an eq at or above fs/2, just skip it when we receive + // such request. + if (fn >= 0.5f) + { + coefs[0] = 1; + coefs[1] = 0; + coefs[2] = 0; + coefs[3] = 1; + coefs[4] = 0; + coefs[5] = 0; + + FILTER_DEBUG_TRACE(1,"[%s] center frequency is above nyquist frequency, skip this band", __FUNCTION__); + return; + } + + if (type == IIR_TYPE_LOW_SHELF) + { + iir_lowshelf_coefs_generate(gain, fn, Q, coefs); + } + else if (type == IIR_TYPE_PEAK) + { + iir_peak_notch_coefs_generate(gain, fn, Q, coefs); + } + else if (type == IIR_TYPE_HIGH_SHELF) + { + iir_highshelf_coefs_generate(gain, fn, Q, coefs); + } + else if (type == IIR_TYPE_LOW_PASS) + { + iir_lowspass_coefs_generate(gain, fn, Q, coefs); + } + else if (type == IIR_TYPE_HIGH_PASS) + { + iir_highpass_coefs_generate(gain, fn, Q, coefs); + } + else + { + ASSERT(false, "[%s] %d is not supported", __func__, type); + } +} + +HW_CODEC_IIR_CFG_T *hw_codec_iir_get_cfg(enum AUD_SAMPRATE_T sample_rate, const IIR_CFG_T *ext_cfg) +{ + const IIR_CFG_T *cfg; + float coefs_l[6],coefs_r[6]; + float gain0,gain1; + int sample_rate_iir=sample_rate; + +#if defined(CHIP_BEST2001) +#ifdef __AUDIO_RESAMPLE__ + sample_rate_iir=50781.25f*8; +#else + switch(sample_rate) + { + case AUD_SAMPRATE_22050: + case AUD_SAMPRATE_44100: + case AUD_SAMPRATE_88200: + case AUD_SAMPRATE_176400: + case AUD_SAMPRATE_352800: + case AUD_SAMPRATE_705600: + sample_rate_iir=44100*8; + break; + + default: + sample_rate_iir=48000*8 ; + break; + }; +#endif +#endif + FILTER_DEBUG_TRACE(2,"%s,sample_rate:%d\n", __func__,sample_rate_iir); + + hw_codec_iir_eq.iir_filtes_l.iir_bypass_flag=1; + hw_codec_iir_eq.iir_filtes_r.iir_bypass_flag=1; + + if (ext_cfg) + { + cfg = ext_cfg; + } + else + { + FILTER_DEBUG_TRACE(0,"Error HW IIR CODEC cfg!"); + return NULL; + } + + // Check parameter + ASSERT(cfg->num <= AUD_DAC_IIR_NUM_EQ, "[%s] num(%d) is too large", __func__, cfg->num); + + gain0 = iir_convert_db_to_multiple(cfg->gain0); + gain1 = iir_convert_db_to_multiple(cfg->gain1); + + // FILTER_DEBUG_TRACE(3,"[%s] gain0 = %f, gain1 = %f", __func__, (double)gain0, (double)gain1); + FILTER_DEBUG_TRACE(2,"[%s] len = %d", __func__, cfg->num); + + for(int i=0; inum; i++) + { + if (cfg->param[i].fcparam[i].type, + cfg->param[i].gain, + cfg->param[i].fc / sample_rate_iir, + cfg->param[i].Q, + coefs_l); + } + else + { + FILTER_DEBUG_TRACE(2,"[%s]Error iir parameters i = %d", __func__, i); + coefs_l[0]=1.0f; + coefs_l[1]=0.0f; + coefs_l[2]=0.0f; + coefs_l[3]=1.0f; + coefs_l[4]=0.0f; + coefs_l[5]=0.0f; + } + + coefs_r[0]=coefs_l[0]; + coefs_r[1]=coefs_l[1]; + coefs_r[2]=coefs_l[2]; + coefs_r[3]=coefs_l[3]; + coefs_r[4]=coefs_l[4]; + coefs_r[5]=coefs_l[5]; + + if(i==0) + { + coefs_l[3] = coefs_l[3]*gain0; + coefs_l[4] = coefs_l[4]*gain0; + coefs_l[5] = coefs_l[5]*gain0; + + coefs_r[3] = coefs_r[3]*gain1; + coefs_r[4] = coefs_r[4]*gain1; + coefs_r[5] = coefs_r[5]*gain1; + } + + hw_codec_iir_eq.iir_filtes_l.iir_coef[i].coef_a[0]=(int32_t)((double)coefs_l[0]*(int32_t)IIR_FIXED_Q); + hw_codec_iir_eq.iir_filtes_l.iir_coef[i].coef_a[1]=(int32_t)((double)coefs_l[1]*(int32_t)IIR_FIXED_Q); + hw_codec_iir_eq.iir_filtes_l.iir_coef[i].coef_a[2]=(int32_t)((double)coefs_l[2]*(int32_t)IIR_FIXED_Q); + hw_codec_iir_eq.iir_filtes_l.iir_coef[i].coef_b[0]=(int32_t)((double)coefs_l[3]*(int32_t)IIR_FIXED_Q); + hw_codec_iir_eq.iir_filtes_l.iir_coef[i].coef_b[1]=(int32_t)((double)coefs_l[4]*(int32_t)IIR_FIXED_Q); + hw_codec_iir_eq.iir_filtes_l.iir_coef[i].coef_b[2]=(int32_t)((double)coefs_l[5]*(int32_t)IIR_FIXED_Q); + + hw_codec_iir_eq.iir_filtes_r.iir_coef[i].coef_a[0]=(int32_t)((double)coefs_r[0]*(int32_t)IIR_FIXED_Q); + hw_codec_iir_eq.iir_filtes_r.iir_coef[i].coef_a[1]=(int32_t)((double)coefs_r[1]*(int32_t)IIR_FIXED_Q); + hw_codec_iir_eq.iir_filtes_r.iir_coef[i].coef_a[2]=(int32_t)((double)coefs_r[2]*(int32_t)IIR_FIXED_Q); + hw_codec_iir_eq.iir_filtes_r.iir_coef[i].coef_b[0]=(int32_t)((double)coefs_r[3]*(int32_t)IIR_FIXED_Q); + hw_codec_iir_eq.iir_filtes_r.iir_coef[i].coef_b[1]=(int32_t)((double)coefs_r[4]*(int32_t)IIR_FIXED_Q); + hw_codec_iir_eq.iir_filtes_r.iir_coef[i].coef_b[2]=(int32_t)((double)coefs_r[5]*(int32_t)IIR_FIXED_Q); + + } + + /* + FILTER_DEBUG_TRACE(2,"\n[%s] coef_a = %d\n", __func__, hw_codec_iir_eq.iir_filtes_l.iir_coef[0].coef_a[0]); + FILTER_DEBUG_TRACE(2,"[%s] coef_a = %d\n", __func__, hw_codec_iir_eq.iir_filtes_l.iir_coef[0].coef_a[1]); + FILTER_DEBUG_TRACE(2,"[%s] coef_a = %d\n", __func__, hw_codec_iir_eq.iir_filtes_l.iir_coef[0].coef_a[2]); + FILTER_DEBUG_TRACE(2,"[%s] coef_a = %d\n", __func__, hw_codec_iir_eq.iir_filtes_l.iir_coef[0].coef_b[0]); + FILTER_DEBUG_TRACE(2,"[%s] coef_a = %d\n", __func__, hw_codec_iir_eq.iir_filtes_l.iir_coef[0].coef_b[1]); + FILTER_DEBUG_TRACE(2,"[%s] coef_a = %d\n", __func__, hw_codec_iir_eq.iir_filtes_l.iir_coef[0].coef_b[2]); + */ + if(cfg->num>=0) + { + hw_codec_iir_eq.iir_filtes_l.iir_bypass_flag=0; + hw_codec_iir_eq.iir_filtes_r.iir_bypass_flag=0; + + hw_codec_iir_eq.iir_filtes_l.iir_counter=cfg->num; + hw_codec_iir_eq.iir_filtes_r.iir_counter=cfg->num; + } + + return &hw_codec_iir_eq; +} + +HW_IIR_CFG_T *hw_iir_get_cfg(enum AUD_SAMPRATE_T sample_rate, const IIR_CFG_T* ext_cfg) +{ + const IIR_CFG_T *cfg; + float coefs_l[6],coefs_r[6]; + float gain0,gain1; + + if (ext_cfg) + { + cfg = ext_cfg; + } + else + { + FILTER_DEBUG_TRACE(0,"Error HW IIR cfg!"); + return NULL; + } + + FILTER_DEBUG_TRACE(3,"[%s]sample_rate:%d,iir num:%d.", __func__,sample_rate,cfg->num); + + // Check parameter + ASSERT(cfg->num <= AUD_IIR_NUM_EQ, "[%s] num(%d) is too large", __func__, cfg->num); + + gain0 = iir_convert_db_to_multiple(cfg->gain0); + gain1 = iir_convert_db_to_multiple(cfg->gain1); + + // FILTER_DEBUG_TRACE(3,"[%s] gain0 = %f, gain1 = %f", __func__, (double)gain0, (double)gain1); + + for(int i=0; inum; i++) + { + if (cfg->param[i].fcparam[i].type, + cfg->param[i].gain, + cfg->param[i].fc / sample_rate, + cfg->param[i].Q, + coefs_l); + } + else + { + FILTER_DEBUG_TRACE(2,"[%s]Error iir parameters i = %d", __func__, i); + coefs_l[0]=1.0f; + coefs_l[1]=0.0f; + coefs_l[2]=0.0f; + coefs_l[3]=1.0f; + coefs_l[4]=0.0f; + coefs_l[5]=0.0f; + } + + coefs_r[0]=coefs_l[0]; + coefs_r[1]=coefs_l[1]; + coefs_r[2]=coefs_l[2]; + coefs_r[3]=coefs_l[3]; + coefs_r[4]=coefs_l[4]; + coefs_r[5]=coefs_l[5]; + + if(i==0) + { + coefs_l[3] = coefs_l[3]*gain0; + coefs_l[4] = coefs_l[4]*gain0; + coefs_l[5] = coefs_l[5]*gain0; + + coefs_r[3] = coefs_r[3]*gain1; + coefs_r[4] = coefs_r[4]*gain1; + coefs_r[5] = coefs_r[5]*gain1; + } + + hw_iir_eq.iir_filtes_l.iir_coef[i].coef_a[0]=(int32_t)((double)coefs_l[0]*(int32_t)IIR_FIXED_Q); + hw_iir_eq.iir_filtes_l.iir_coef[i].coef_a[1]=(int32_t)((double)coefs_l[1]*(int32_t)IIR_FIXED_Q); + hw_iir_eq.iir_filtes_l.iir_coef[i].coef_a[2]=(int32_t)((double)coefs_l[2]*(int32_t)IIR_FIXED_Q); + hw_iir_eq.iir_filtes_l.iir_coef[i].coef_b[0]=(int32_t)((double)coefs_l[3]*(int32_t)IIR_FIXED_Q); + hw_iir_eq.iir_filtes_l.iir_coef[i].coef_b[1]=(int32_t)((double)coefs_l[4]*(int32_t)IIR_FIXED_Q); + hw_iir_eq.iir_filtes_l.iir_coef[i].coef_b[2]=(int32_t)((double)coefs_l[5]*(int32_t)IIR_FIXED_Q); + + hw_iir_eq.iir_filtes_r.iir_coef[i].coef_a[0]=(int32_t)((double)coefs_r[0]*(int32_t)IIR_FIXED_Q); + hw_iir_eq.iir_filtes_r.iir_coef[i].coef_a[1]=(int32_t)((double)coefs_r[1]*(int32_t)IIR_FIXED_Q); + hw_iir_eq.iir_filtes_r.iir_coef[i].coef_a[2]=(int32_t)((double)coefs_r[2]*(int32_t)IIR_FIXED_Q); + hw_iir_eq.iir_filtes_r.iir_coef[i].coef_b[0]=(int32_t)((double)coefs_r[3]*(int32_t)IIR_FIXED_Q); + hw_iir_eq.iir_filtes_r.iir_coef[i].coef_b[1]=(int32_t)((double)coefs_r[4]*(int32_t)IIR_FIXED_Q); + hw_iir_eq.iir_filtes_r.iir_coef[i].coef_b[2]=(int32_t)((double)coefs_r[5]*(int32_t)IIR_FIXED_Q); + + } + +/* + FILTER_DEBUG_TRACE(2,"\n[%s] coef_a0 = %d\n", __func__, hw_iir_eq.iir_filtes_l.iir_coef[0].coef_a[0]); + FILTER_DEBUG_TRACE(2,"[%s] coef_a1 = %d\n", __func__, hw_iir_eq.iir_filtes_l.iir_coef[0].coef_a[1]); + FILTER_DEBUG_TRACE(2,"[%s] coef_a2 = %d\n", __func__, hw_iir_eq.iir_filtes_l.iir_coef[0].coef_a[2]); + FILTER_DEBUG_TRACE(2,"[%s] coef_b0 = %d\n", __func__, hw_iir_eq.iir_filtes_l.iir_coef[0].coef_b[0]); + FILTER_DEBUG_TRACE(2,"[%s] coef_b1 = %d\n", __func__, hw_iir_eq.iir_filtes_l.iir_coef[0].coef_b[1]); + FILTER_DEBUG_TRACE(2,"[%s] coef_b2 = %d\n", __func__, hw_iir_eq.iir_filtes_l.iir_coef[0].coef_b[2]); +*/ + if(cfg->num>=0) + { + hw_iir_eq.iir_filtes_l.iir_counter=cfg->num; + hw_iir_eq.iir_filtes_r.iir_counter=cfg->num; + } + + return &hw_iir_eq; +} + diff --git a/services/multimedia/audio/process/filters/cfg/eq_cfg.h b/services/multimedia/audio/process/filters/cfg/eq_cfg.h new file mode 100644 index 0000000..3cd87f8 --- /dev/null +++ b/services/multimedia/audio/process/filters/cfg/eq_cfg.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __FIR_PROCESS_H__ +#define __FIR_PROCESS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void iir_lowshelf_coefs_generate(float gain, float fn, float Q, float *coefs); + +void iir_highshelf_coefs_generate(float gain, float fn, float Q, float *coefs); + +void iir_peak_notch_coefs_generate(float gain, float fn, float Q, float *coefs); + +void iir_highpass_coefs_generate(float gain, float fn, float Q, float *coefs); + +void iir_lowspass_coefs_generate(float gain, float fn, float Q, float *coefs); + +float iir_convert_db_to_multiple(float db); + +void iir_coefs_generate(IIR_TYPE_T type, float gain, float fn, float Q, float *coefs); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/filters/include/dsd_process.h b/services/multimedia/audio/process/filters/include/dsd_process.h new file mode 100644 index 0000000..a013268 --- /dev/null +++ b/services/multimedia/audio/process/filters/include/dsd_process.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __DSD_PROCESS_H__ +#define __DSD_PROCESS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "hal_aud.h" + +#define FIR_COEF_NUM 384 + +typedef struct { + int8_t gain0; + int8_t gain1; + int16_t len; + int32_t coef[FIR_COEF_NUM]; +} DSD_CFG_T; + +int dsd_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_BITS_T sample_bits,enum AUD_CHANNEL_NUM_T ch_num, void *eq_buf, uint32_t len); +int dsd_process(uint8_t *buf, uint32_t len); +int dsd_close(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/filters/include/filter_debug_trace.h b/services/multimedia/audio/process/filters/include/filter_debug_trace.h new file mode 100644 index 0000000..a5d58e0 --- /dev/null +++ b/services/multimedia/audio/process/filters/include/filter_debug_trace.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __FILTER_DEBUG_TRACE__ +#define __FILTER_DEBUG_TRACE__ +#include "hal_trace.h" + +#define FILTER_DEBUG_TRACE(n, s, ...) TRACE(n, s, ##__VA_ARGS__) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/filters/include/fir_process.h b/services/multimedia/audio/process/filters/include/fir_process.h new file mode 100644 index 0000000..7dbf21a --- /dev/null +++ b/services/multimedia/audio/process/filters/include/fir_process.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __FIR_PROCESS_H__ +#define __FIR_PROCESS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "hal_aud.h" + +#define FIR_COEF_NUM 384 + +typedef struct { + float gain; + int32_t len; + int32_t coef[FIR_COEF_NUM]; +} FIR_CFG_T; + +int fir_needed_size(enum AUD_BITS_T sample_bits, int32_t frame_size); +int fir_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_BITS_T sample_bits,enum AUD_CHANNEL_NUM_T ch_num, void *eq_buf, uint32_t len); +int fir_set_cfg(const FIR_CFG_T *cfg); +int fir_set_cfg_ch(const FIR_CFG_T *cfg,enum AUD_CHANNEL_NUM_T ch); +int fir_run(uint8_t *buf, uint32_t len); +int fir_close(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/audio/process/filters/include/hw_codec_iir_process.h b/services/multimedia/audio/process/filters/include/hw_codec_iir_process.h new file mode 100644 index 0000000..fcd2a65 --- /dev/null +++ b/services/multimedia/audio/process/filters/include/hw_codec_iir_process.h @@ -0,0 +1,97 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HW_CODEC_IIR_PROCESS_H__ +#define __HW_CODEC_IIR_PROCESS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "hal_aud.h" + +#if defined(CHIP_BEST1402) ||defined(CHIP_BEST2001) ||defined(CHIP_BEST2300A) +#define AUD_DAC_IIR_NUM_EQ (20) +#else +#define AUD_DAC_IIR_NUM_EQ (8) +#endif + +typedef enum { + HW_CODEC_IIR_NO_ERR=0, + HW_CODEC_IIR_TYPE_ERR, + HW_CODEC_IIR_SAMPLERATE_ERR, + HW_CODEC_IIR_COUNTER_ERR, + HW_CODEC_IIR_OTHER_ERR, + HW_CODEC_IIR_ERR_TOTAL, +}HW_CODEC_IIR_ERROR; + +typedef enum { + HW_CODEC_IIR_NOTYPE = 0, + HW_CODEC_IIR_DAC, + HW_CODEC_IIR_ADC, +}HW_CODEC_IIR_TYPE_T; + +typedef struct _hw_codec_iir_coefs +{ + int32_t coef_b[3]; + int32_t coef_a[3]; +}hw_codec_iir_coefs; + +typedef struct _hw_codec_iir_coefs_f +{ + float coef_b[3]; + float coef_a[3]; +}hw_codec_iir_coefs_f; + +typedef struct _hw_codec_iir_filters +{ + uint16_t iir_bypass_flag; + uint16_t iir_counter; + hw_codec_iir_coefs iir_coef[AUD_DAC_IIR_NUM_EQ]; +} HW_CODEC_IIR_FILTERS_T; + +typedef struct _hw_codec_iir_filters_f +{ + uint16_t iir_bypass_flag; + uint16_t iir_counter; + hw_codec_iir_coefs_f iir_coef[AUD_DAC_IIR_NUM_EQ]; +} HW_CODEC_IIR_FILTERS_F; + +typedef struct _hw_codec_iir_cfg_t +{ + HW_CODEC_IIR_FILTERS_T iir_filtes_l; + HW_CODEC_IIR_FILTERS_T iir_filtes_r; +} HW_CODEC_IIR_CFG_T; + +typedef struct _hw_codec_iir_cfg_f +{ + HW_CODEC_IIR_FILTERS_F iir_filtes_l; + HW_CODEC_IIR_FILTERS_F iir_filtes_r; +} HW_CODEC_IIR_CFG_F; + +int hw_codec_iir_open(enum AUD_SAMPRATE_T sample_rate, HW_CODEC_IIR_TYPE_T hw_iir_type, int32_t ch_map); +int hw_codec_iir_set_cfg( HW_CODEC_IIR_CFG_T *cfg, enum AUD_SAMPRATE_T sample_rate, HW_CODEC_IIR_TYPE_T hw_iir_type); +int hw_codec_iir_close( HW_CODEC_IIR_TYPE_T hw_iir_type); +HW_CODEC_IIR_CFG_T *hw_codec_iir_get_cfg(enum AUD_SAMPRATE_T sample_rate,const IIR_CFG_T* ext_cfg); +int hw_codec_iir_set_coefs(HW_CODEC_IIR_CFG_F *cfg, HW_CODEC_IIR_TYPE_T hw_iir_type); + +int hal_codec_iir_dump(HW_CODEC_IIR_CFG_T *cfg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/filters/include/hw_iir_process.h b/services/multimedia/audio/process/filters/include/hw_iir_process.h new file mode 100644 index 0000000..1449409 --- /dev/null +++ b/services/multimedia/audio/process/filters/include/hw_iir_process.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HW_IIR_PROCESS_H__ +#define __HW_IIR_PROCESS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "hal_aud.h" +#include "iir_process.h" + +#define AUD_IIR_NUM_EQ (8) + +typedef enum { + HW_IIR_NO_ERR=0, + HW_IIR_TYPE_ERR, + HW_IIR_SAMPLERATE_ERR, + HW_IIR_COUNTER_ERR, + HW_IIR_OTHER_ERR, + HW_IIR_ERR_TOTAL, +}HW_IIR_ERROR; + +typedef struct _hw_iir_coefs_t +{ + int32_t coef_b[3]; + int32_t coef_a[3]; +}HW_IIR_COEFS_T; + +typedef struct _hw_iir_filters_t +{ + uint16_t iir_counter; + HW_IIR_COEFS_T iir_coef[AUD_IIR_NUM_EQ]; +} HW_IIR_FILTERS_T; + +typedef struct _hw_iir_cfg_t +{ + HW_IIR_FILTERS_T iir_filtes_l; + HW_IIR_FILTERS_T iir_filtes_r; +} HW_IIR_CFG_T; + +int hw_iir_needed_size(enum AUD_BITS_T sample_bits, int32_t frame_size); +int hw_iir_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_BITS_T sample_bits,enum AUD_CHANNEL_NUM_T ch_num, void *eq_buf, uint32_t len); +int hw_iir_set_cfg(HW_IIR_CFG_T *cfg); +int hw_iir_run(uint8_t *buf, uint32_t len); +int hw_iir_close(void); +HW_IIR_CFG_T *hw_iir_get_cfg(enum AUD_SAMPRATE_T sample_rate, const IIR_CFG_T* ext_cfg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/filters/include/iir_process.h b/services/multimedia/audio/process/filters/include/iir_process.h new file mode 100644 index 0000000..7540942 --- /dev/null +++ b/services/multimedia/audio/process/filters/include/iir_process.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __IIR_PROCESS_H__ +#define __IIR_PROCESS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "hal_aud.h" + +#ifdef USB_EQ_TUNING + +#ifdef __SW_IIR_EQ_PROCESS__ +#define SW_IIR_PARAM_NUM (2) +#else +#define SW_IIR_PARAM_NUM (0) +#endif + +#ifdef __HW_DAC_IIR_EQ_PROCESS__ +#define HW_DAC_IIR_PARAM_NUM (8) +#else +#define HW_DAC_IIR_PARAM_NUM (0) +#endif + +#define IIR_PARAM_NUM (SW_IIR_PARAM_NUM + HW_DAC_IIR_PARAM_NUM) + +#else + +#define IIR_PARAM_NUM (20) + +#endif + +typedef enum { + IIR_TYPE_LOW_SHELF = 0, + IIR_TYPE_PEAK, + IIR_TYPE_HIGH_SHELF, + IIR_TYPE_LOW_PASS, + IIR_TYPE_HIGH_PASS, + IIR_TYPE_NUM +} IIR_TYPE_T; + +typedef struct { + IIR_TYPE_T type; + float gain; + float fc; + float Q; +} IIR_PARAM_T; + +typedef struct { + float gain0; + float gain1; + int num; + IIR_PARAM_T param[IIR_PARAM_NUM]; +} IIR_CFG_T; + +int iir_open(enum AUD_SAMPRATE_T sample_rate, enum AUD_BITS_T sample_bits,enum AUD_CHANNEL_NUM_T ch_num); +int iir_set_cfg(const IIR_CFG_T *cfg); +int iir_set_cfg_ch(const IIR_CFG_T *cfg, enum AUD_CHANNEL_NUM_T ch); +int iir_run(uint8_t *buf, uint32_t len); +int iir_close(void); + +int iir_set_gain_and_num(float gain0, float gain1, int num); +int iir_set_param(uint8_t index, const IIR_PARAM_T *param); + +void iir_update_cfg_tbl(uint8_t *buf, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/fir2iir/include/fir2iir.h b/services/multimedia/audio/process/fir2iir/include/fir2iir.h new file mode 100644 index 0000000..2624d6c --- /dev/null +++ b/services/multimedia/audio/process/fir2iir/include/fir2iir.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __FIR2IIR_H__ +#define __FIR2IIR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +// TODO: Add fir2iir_create and fir2iir_destroy functions. + +// weight: length is 512 +void fir2iir_process(double *RealCoeffs,double *ImagCoeffs,double iircoefaa[10][3], double iircoefbb[10][3], int numorder, int denorder, int maxiter, double *weight); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/audio/process/integer_resampling/include/integer_resampling.h b/services/multimedia/audio/process/integer_resampling/include/integer_resampling.h new file mode 100644 index 0000000..047699d --- /dev/null +++ b/services/multimedia/audio/process/integer_resampling/include/integer_resampling.h @@ -0,0 +1,39 @@ +#ifndef __INTEGER_RESAMPLING_H__ +#define __INTEGER_RESAMPLING_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + INTEGER_RESAMPLING_ITEM_48K_TO_16K = 0, + + INTEGER_RESAMPLING_ITEM_NUM +} INTEGER_RESAMPLING_ITEM_T; + +struct IntegerResamplingState_; + +typedef struct IntegerResamplingState_ IntegerResamplingState; + +// Creat a instance from integer_resampling module/class +IntegerResamplingState *integer_resampling_create(int32_t frame_size, int32_t channel_num, INTEGER_RESAMPLING_ITEM_T item, void *ext_alloc(int)); + +// Destory a integer_resampling instance +int32_t integer_resampling_destroy(IntegerResamplingState *st); + +// Get/set some value or enable/disable some function +int32_t integer_resampling_ctl(IntegerResamplingState *st, int32_t ctl, void *ptr); + +// Process speech stream +int32_t integer_resampling_process(IntegerResamplingState *st, int16_t *pcm_in, int32_t pcm_len, int16_t *pcm_out); + +// Debug integer_resampling instance +int32_t integer_resampling_dump(IntegerResamplingState *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/limiter/include/limiter.h b/services/multimedia/audio/process/limiter/include/limiter.h new file mode 100644 index 0000000..8af2717 --- /dev/null +++ b/services/multimedia/audio/process/limiter/include/limiter.h @@ -0,0 +1,29 @@ +#ifndef LIMITER_H +#define LIMITER_H + +#include + +typedef struct +{ + int32_t knee; + int32_t look_ahead_time; + int32_t threshold; + float makeup_gain; + int32_t ratio; // reserved + int32_t attack_time; + int32_t release_time; +} LimiterConfig; + +struct LimiterState_; + +typedef struct LimiterState_ LimiterState; + +LimiterState *limiter_create(int32_t sample_rate, int32_t frame_size, int32_t sample_bit, int32_t channel_number, const LimiterConfig *config); + +int32_t limiter_destroy(LimiterState *st); + +int32_t limiter_set_config(LimiterState *st, const LimiterConfig *config); + +int32_t limiter_process(LimiterState *st, uint8_t *buf, int32_t len); + +#endif \ No newline at end of file diff --git a/services/multimedia/audio/process/resample/coef/Makefile b/services/multimedia/audio/process/resample/coef/Makefile new file mode 100644 index 0000000..0b81fb7 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/Makefile @@ -0,0 +1,14 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y := \ + -Iservices/multimedia/audio/process/resample/include \ + +ifeq ($(RESAMPLE_ANY_SAMPLE_RATE),1) +CFLAGS_resample_coef.o += -DRESAMPLE_ANY_SAMPLE_RATE +endif + diff --git a/services/multimedia/audio/process/resample/coef/resample_16k_to_48k_filter.txt b/services/multimedia/audio/process/resample/coef/resample_16k_to_48k_filter.txt new file mode 100644 index 0000000..9399e60 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_16k_to_48k_filter.txt @@ -0,0 +1,16 @@ +//single phase coef Number:=30, upsample factor:=3, downsample factor:=1 + 0, -131, -260, 231, -261, 305, + -340, 350, -318, 223, -24, -354, + 1124,-3214,29795, 7194,-3688, 2546, +-1911, 1468,-1126, 847, -618, 433, + -290, 187, -113, -226, -14, 1, + 2, -55, -289, 93, -31, -43, + 160, -339, 599, -968, 1497,-2293, + 3637,-6571,20509,20509,-6571, 3637, +-2293, 1497, -968, 599, -339, 160, + -43, -31, 93, -289, -55, 2, + 1, -14, -226, -113, 187, -290, + 433, -618, 847,-1126, 1468,-1911, + 2546,-3688, 7194,29795,-3214, 1124, + -354, -24, 223, -318, 350, -340, + 305, -261, 231, -260, -131, 0, diff --git a/services/multimedia/audio/process/resample/coef/resample_32k_to_50p7k_filter.txt b/services/multimedia/audio/process/resample/coef/resample_32k_to_50p7k_filter.txt new file mode 100644 index 0000000..fd5e5b5 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_32k_to_50p7k_filter.txt @@ -0,0 +1,297 @@ +//#define FIRFILTER_NUM (24) +//#define UPSAMPLE_FACTOR_32TO50P7 73 +//#define DOWNSAMPLE_FACTOR_32TO50P7 46 + + -17, 115, 196, -309, 531, -803, + 1107, -1412, 1684, -1879, 1916, 30581, + 2348, -2071, 1788, -1469, 1135, -814, + 533, -305, 190, 119, -17, -1, + -17, 111, 202, -312, 530, -791, + 1078, -1354, 1579, -1688, 1493, 30565, + 2788, -2262, 1890, -1523, 1161, -824, + 533, -301, 183, 124, -17, 0, + -17, 107, 208, -314, 527, -778, + 1047, -1295, 1473, -1496, 1080, 30531, + 3237, -2453, 1990, -1576, 1186, -832, + 532, -297, 176, 128, -18, 0, + -16, 102, 214, -316, 524, -764, + 1015, -1234, 1366, -1306, 676, 30481, + 3694, -2642, 2088, -1627, 1210, -839, + 531, -292, 169, 133, -18, 0, + -16, 98, 219, -318, 519, -749, + 981, -1172, 1257, -1116, 281, 30415, + 4158, -2831, 2184, -1676, 1231, -845, + 529, -286, 161, 137, -18, -1, + -16, 94, 225, -319, 514, -733, + 947, -1108, 1148, -927, -103, 30332, + 4630, -3018, 2278, -1723, 1251, -850, + 525, -280, 154, 142, -18, -1, + -16, 90, 230, -319, 509, -716, + 911, -1044, 1039, -740, -477, 30232, + 5109, -3203, 2369, -1767, 1269, -853, + 521, -274, 146, 146, -18, -1, + -15, 86, 234, -319, 502, -698, + 875, -979, 929, -554, -840, 30116, + 5594, -3386, 2457, -1809, 1285, -855, + 517, -266, 138, 150, -18, -1, + -15, 82, 239, -319, 495, -679, + 837, -912, 819, -370, -1193, 29984, + 6086, -3566, 2543, -1849, 1300, -856, + 511, -259, 130, 155, -18, -1, + -15, 78, 243, -318, 488, -659, + 798, -845, 710, -189, -1534, 29836, + 6584, -3743, 2625, -1886, 1312, -855, + 504, -251, 121, 159, -18, -1, + -14, 75, 247, -316, 479, -639, + 759, -778, 600, -10, -1865, 29672, + 7087, -3918, 2705, -1920, 1323, -853, + 497, -242, 112, 164, -18, -1, + -14, 71, 250, -314, 470, -618, + 719, -710, 491, 167, -2184, 29493, + 7595, -4088, 2780, -1952, 1331, -850, + 489, -233, 103, 168, -17, -1, + -14, 67, 254, -312, 461, -596, + 678, -642, 382, 340, -2492, 29297, + 8108, -4256, 2853, -1981, 1338, -845, + 479, -224, 94, 173, -17, -1, + -13, 64, 257, -309, 451, -573, + 636, -573, 274, 511, -2789, 29086, + 8625, -4418, 2921, -2007, 1342, -839, + 469, -214, 85, 177, -17, -1, + -13, 60, 259, -306, 440, -550, + 594, -504, 167, 678, -3074, 28860, + 9146, -4577, 2986, -2030, 1344, -831, + 459, -203, 76, 182, -17, -1, + -13, 57, 262, -302, 428, -526, + 552, -435, 61, 841, -3347, 28620, + 9671, -4730, 3047, -2050, 1344, -822, + 447, -192, 66, 186, -16, -2, + -12, 53, 264, -298, 417, -502, + 509, -367, -44, 1001, -3608, 28364, + 10198, -4879, 3103, -2067, 1342, -812, + 434, -181, 57, 191, -16, -2, + -12, 50, 266, -293, 404, -477, + 466, -298, -148, 1156, -3857, 28094, + 10728, -5022, 3155, -2080, 1338, -800, + 421, -169, 47, 195, -16, -2, + -12, 47, 268, -289, 392, -451, + 422, -230, -250, 1308, -4094, 27809, + 11260, -5160, 3203, -2091, 1331, -787, + 407, -157, 37, 199, -15, -2, + -11, 44, 270, -283, 378, -426, + 379, -162, -350, 1455, -4320, 27511, + 11793, -5291, 3246, -2098, 1323, -772, + 392, -145, 27, 203, -15, -2, + -11, 41, 271, -278, 365, -399, + 335, -95, -449, 1598, -4533, 27199, + 12328, -5416, 3284, -2102, 1312, -756, + 376, -132, 17, 207, -14, -2, + -11, 38, 272, -272, 351, -373, + 291, -28, -546, 1736, -4734, 26874, + 12863, -5534, 3317, -2103, 1298, -739, + 359, -119, 7, 212, -13, -2, + -10, 35, 273, -265, 336, -346, + 248, 38, -641, 1869, -4922, 26536, + 13398, -5646, 3346, -2100, 1283, -720, + 342, -105, -3, 216, -13, -3, + -10, 32, 273, -258, 322, -319, + 204, 103, -733, 1997, -5099, 26185, + 13933, -5750, 3369, -2094, 1265, -700, + 324, -91, -14, 220, -12, -3, + -10, 30, 274, -251, 307, -292, + 161, 167, -823, 2121, -5264, 25822, + 14467, -5846, 3387, -2084, 1245, -678, + 305, -77, -24, 223, -11, -3, + -9, 27, 274, -244, 291, -265, + 117, 231, -911, 2239, -5416, 25447, + 15000, -5935, 3400, -2071, 1223, -656, + 285, -62, -35, 227, -10, -3, + -9, 24, 273, -237, 276, -238, + 75, 293, -997, 2351, -5556, 25060, + 15532, -6015, 3408, -2054, 1199, -631, + 265, -47, -45, 231, -9, -3, + -9, 22, 273, -229, 260, -210, + 32, 354, -1079, 2459, -5685, 24662, + 16061, -6088, 3409, -2033, 1172, -606, + 244, -32, -55, 234, -8, -4, + -8, 20, 272, -220, 244, -183, + -10, 414, -1160, 2561, -5801, 24253, + 16587, -6151, 3406, -2010, 1144, -579, + 223, -17, -66, 238, -7, -4, + -8, 17, 272, -212, 228, -156, + -52, 472, -1237, 2657, -5906, 23834, + 17110, -6206, 3397, -1982, 1113, -551, + 201, -1, -76, 241, -6, -4, + -8, 15, 271, -203, 212, -128, + -93, 529, -1311, 2748, -5999, 23405, + 17630, -6251, 3382, -1951, 1080, -522, + 178, 15, -87, 244, -5, -4, + -7, 13, 269, -195, 195, -101, + -133, 585, -1382, 2833, -6080, 22966, + 18145, -6287, 3361, -1917, 1044, -492, + 155, 31, -97, 247, -4, -4, + -7, 11, 268, -185, 179, -74, + -173, 639, -1451, 2912, -6150, 22518, + 18656, -6313, 3334, -1879, 1007, -460, + 131, 47, -107, 250, -2, -5, + -7, 9, 266, -176, 162, -47, + -212, 691, -1516, 2985, -6209, 22061, + 19161, -6330, 3302, -1837, 968, -428, + 107, 63, -117, 253, -1, -5, + -6, 7, 265, -167, 146, -21, + -250, 742, -1578, 3053, -6256, 21596, + 19661, -6336, 3264, -1792, 926, -394, + 82, 80, -127, 256, 0, -5, + -6, 5, 263, -157, 129, 5, + -287, 791, -1636, 3114, -6292, 21123, + 20155, -6332, 3220, -1743, 883, -360, + 57, 96, -138, 258, 2, -5, + -6, 4, 260, -147, 113, 31, + -324, 838, -1691, 3170, -6317, 20643, + 20643, -6317, 3170, -1691, 838, -324, + 31, 113, -147, 260, 4, -6, + -5, 2, 258, -138, 96, 57, + -360, 883, -1743, 3220, -6332, 20155, + 21123, -6292, 3114, -1636, 791, -287, + 5, 129, -157, 263, 5, -6, + -5, 0, 256, -127, 80, 82, + -394, 926, -1792, 3264, -6336, 19661, + 21596, -6256, 3053, -1578, 742, -250, + -21, 146, -167, 265, 7, -6, + -5, -1, 253, -117, 63, 107, + -428, 968, -1837, 3302, -6330, 19161, + 22061, -6209, 2985, -1516, 691, -212, + -47, 162, -176, 266, 9, -7, + -5, -2, 250, -107, 47, 131, + -460, 1007, -1879, 3334, -6313, 18656, + 22518, -6150, 2912, -1451, 639, -173, + -74, 179, -185, 268, 11, -7, + -4, -4, 247, -97, 31, 155, + -492, 1044, -1917, 3361, -6287, 18145, + 22966, -6080, 2833, -1382, 585, -133, + -101, 195, -195, 269, 13, -7, + -4, -5, 244, -87, 15, 178, + -522, 1080, -1951, 3382, -6251, 17630, + 23405, -5999, 2748, -1311, 529, -93, + -128, 212, -203, 271, 15, -8, + -4, -6, 241, -76, -1, 201, + -551, 1113, -1982, 3397, -6206, 17110, + 23834, -5906, 2657, -1237, 472, -52, + -156, 228, -212, 272, 17, -8, + -4, -7, 238, -66, -17, 223, + -579, 1144, -2010, 3406, -6151, 16587, + 24253, -5801, 2561, -1160, 414, -10, + -183, 244, -220, 272, 20, -8, + -4, -8, 234, -55, -32, 244, + -606, 1172, -2033, 3409, -6088, 16061, + 24662, -5685, 2459, -1079, 354, 32, + -210, 260, -229, 273, 22, -9, + -3, -9, 231, -45, -47, 265, + -631, 1199, -2054, 3408, -6015, 15532, + 25060, -5556, 2351, -997, 293, 75, + -238, 276, -237, 273, 24, -9, + -3, -10, 227, -35, -62, 285, + -656, 1223, -2071, 3400, -5935, 15000, + 25447, -5416, 2239, -911, 231, 117, + -265, 291, -244, 274, 27, -9, + -3, -11, 223, -24, -77, 305, + -678, 1245, -2084, 3387, -5846, 14467, + 25822, -5264, 2121, -823, 167, 161, + -292, 307, -251, 274, 30, -10, + -3, -12, 220, -14, -91, 324, + -700, 1265, -2094, 3369, -5750, 13933, + 26185, -5099, 1997, -733, 103, 204, + -319, 322, -258, 273, 32, -10, + -3, -13, 216, -3, -105, 342, + -720, 1283, -2100, 3346, -5646, 13398, + 26536, -4922, 1869, -641, 38, 248, + -346, 336, -265, 273, 35, -10, + -2, -13, 212, 7, -119, 359, + -739, 1298, -2103, 3317, -5534, 12863, + 26874, -4734, 1736, -546, -28, 291, + -373, 351, -272, 272, 38, -11, + -2, -14, 207, 17, -132, 376, + -756, 1312, -2102, 3284, -5416, 12328, + 27199, -4533, 1598, -449, -95, 335, + -399, 365, -278, 271, 41, -11, + -2, -15, 203, 27, -145, 392, + -772, 1323, -2098, 3246, -5291, 11793, + 27511, -4320, 1455, -350, -162, 379, + -426, 378, -283, 270, 44, -11, + -2, -15, 199, 37, -157, 407, + -787, 1331, -2091, 3203, -5160, 11260, + 27809, -4094, 1308, -250, -230, 422, + -451, 392, -289, 268, 47, -12, + -2, -16, 195, 47, -169, 421, + -800, 1338, -2080, 3155, -5022, 10728, + 28094, -3857, 1156, -148, -298, 466, + -477, 404, -293, 266, 50, -12, + -2, -16, 191, 57, -181, 434, + -812, 1342, -2067, 3103, -4879, 10198, + 28364, -3608, 1001, -44, -367, 509, + -502, 417, -298, 264, 53, -12, + -2, -16, 186, 66, -192, 447, + -822, 1344, -2050, 3047, -4730, 9671, + 28620, -3347, 841, 61, -435, 552, + -526, 428, -302, 262, 57, -13, + -1, -17, 182, 76, -203, 459, + -831, 1344, -2030, 2986, -4577, 9146, + 28860, -3074, 678, 167, -504, 594, + -550, 440, -306, 259, 60, -13, + -1, -17, 177, 85, -214, 469, + -839, 1342, -2007, 2921, -4418, 8625, + 29086, -2789, 511, 274, -573, 636, + -573, 451, -309, 257, 64, -13, + -1, -17, 173, 94, -224, 479, + -845, 1338, -1981, 2853, -4256, 8108, + 29297, -2492, 340, 382, -642, 678, + -596, 461, -312, 254, 67, -14, + -1, -17, 168, 103, -233, 489, + -850, 1331, -1952, 2780, -4088, 7595, + 29493, -2184, 167, 491, -710, 719, + -618, 470, -314, 250, 71, -14, + -1, -18, 164, 112, -242, 497, + -853, 1323, -1920, 2705, -3918, 7087, + 29672, -1865, -10, 600, -778, 759, + -639, 479, -316, 247, 75, -14, + -1, -18, 159, 121, -251, 504, + -855, 1312, -1886, 2625, -3743, 6584, + 29836, -1534, -189, 710, -845, 798, + -659, 488, -318, 243, 78, -15, + -1, -18, 155, 130, -259, 511, + -856, 1300, -1849, 2543, -3566, 6086, + 29984, -1193, -370, 819, -912, 837, + -679, 495, -319, 239, 82, -15, + -1, -18, 150, 138, -266, 517, + -855, 1285, -1809, 2457, -3386, 5594, + 30116, -840, -554, 929, -979, 875, + -698, 502, -319, 234, 86, -15, + -1, -18, 146, 146, -274, 521, + -853, 1269, -1767, 2369, -3203, 5109, + 30232, -477, -740, 1039, -1044, 911, + -716, 509, -319, 230, 90, -16, + -1, -18, 142, 154, -280, 525, + -850, 1251, -1723, 2278, -3018, 4630, + 30332, -103, -927, 1148, -1108, 947, + -733, 514, -319, 225, 94, -16, + -1, -18, 137, 161, -286, 529, + -845, 1231, -1676, 2184, -2831, 4158, + 30415, 281, -1116, 1257, -1172, 981, + -749, 519, -318, 219, 98, -16, + 0, -18, 133, 169, -292, 531, + -839, 1210, -1627, 2088, -2642, 3694, + 30481, 676, -1306, 1366, -1234, 1015, + -764, 524, -316, 214, 102, -16, + 0, -18, 128, 176, -297, 532, + -832, 1186, -1576, 1990, -2453, 3237, + 30531, 1080, -1496, 1473, -1295, 1047, + -778, 527, -314, 208, 107, -17, + 0, -17, 124, 183, -301, 533, + -824, 1161, -1523, 1890, -2262, 2788, + 30565, 1493, -1688, 1579, -1354, 1078, + -791, 530, -312, 202, 111, -17, + -1, -17, 119, 190, -305, 533, + -814, 1135, -1469, 1788, -2071, 2348, + 30581, 1916, -1879, 1684, -1412, 1107, + -803, 531, -309, 196, 115, -17, + diff --git a/services/multimedia/audio/process/resample/coef/resample_44p1k_to_48k_filter.txt b/services/multimedia/audio/process/resample/coef/resample_44p1k_to_48k_filter.txt new file mode 100644 index 0000000..a619afb --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_44p1k_to_48k_filter.txt @@ -0,0 +1,161 @@ +//single phase coef Number:=8, upsample factor:=160, downsample factor:=147 + -467,-2015, 7740,21207, 7855,-2009, -476, -9, + -458,-2020, 7625,21206, 7971,-2003, -485, -2, + -450,-2024, 7511,21203, 8086,-1996, -494, -2, + -441,-2028, 7397,21199, 8203,-1989, -503, -2, + -433,-2032, 7284,21193, 8319,-1982, -512, -2, + -425,-2035, 7170,21186, 8436,-1974, -521, -2, + -417,-2038, 7058,21177, 8553,-1965, -530, -2, + -409,-2040, 6945,21167, 8670,-1956, -540, -2, + -401,-2042, 6833,21155, 8787,-1946, -549, -3, + -393,-2044, 6722,21142, 8905,-1936, -559, -3, + -385,-2045, 6611,21128, 9023,-1925, -569, -3, + -378,-2045, 6500,21112, 9141,-1914, -579, -3, + -370,-2046, 6390,21095, 9259,-1902, -589, -3, + -363,-2045, 6280,21076, 9378,-1890, -599, -4, + -355,-2045, 6171,21056, 9497,-1877, -609, -4, + -348,-2044, 6063,21034, 9616,-1863, -619, -4, + -341,-2042, 5955,21011, 9735,-1849, -630, -4, + -334,-2041, 5847,20987, 9854,-1834, -640, -5, + -327,-2039, 5740,20961, 9973,-1819, -651, -5, + -320,-2036, 5634,20934,10093,-1803, -662, -5, + -314,-2033, 5528,20905,10212,-1786, -672, -6, + -307,-2030, 5422,20875,10332,-1769, -683, -6, + -301,-2026, 5318,20844,10451,-1751, -694, -6, + -294,-2023, 5213,20811,10571,-1733, -705, -7, + -288,-2018, 5110,20777,10691,-1714, -717, -7, + -282,-2014, 5007,20741,10811,-1694, -728, -7, + -275,-2009, 4904,20704,10930,-1674, -739, -8, + -269,-2004, 4803,20666,11050,-1653, -751, -8, + -264,-1998, 4701,20626,11170,-1631, -762, -9, + -258,-1993, 4601,20585,11290,-1609, -774, -9, + -252,-1986, 4501,20543,11409,-1586, -786, -10, + -246,-1980, 4402,20499,11529,-1562, -797, -10, + -241,-1973, 4303,20454,11648,-1538, -809, -11, + -235,-1966, 4205,20408,11768,-1513, -821, -11, + -230,-1959, 4108,20360,11887,-1487, -833, -12, + -225,-1952, 4012,20311,12006,-1461, -846, -12, + -219,-1944, 3916,20261,12125,-1434, -858, -13, + -214,-1936, 3821,20209,12244,-1406, -870, -13, + -209,-1928, 3726,20156,12363,-1378, -883, -14, + -204,-1919, 3632,20102,12481,-1348, -895, -15, + -199,-1911, 3539,20046,12600,-1318, -908, -15, + -195,-1902, 3447,19990,12718,-1288, -920, -16, + -190,-1893, 3355,19932,12836,-1256, -933, -17, + -185,-1883, 3264,19872,12953,-1224, -946, -18, + -181,-1874, 3174,19812,13071,-1191, -959, -18, + -176,-1864, 3085,19750,13188,-1158, -971, -19, + -172,-1854, 2996,19687,13305,-1124, -984, -20, + -168,-1844, 2908,19623,13421,-1088, -997, -21, + -164,-1834, 2821,19557,13537,-1053,-1011, -22, + -159,-1823, 2734,19491,13653,-1016,-1024, -23, + -155,-1812, 2649,19423,13769, -979,-1037, -23, + -151,-1801, 2564,19354,13884, -941,-1050, -24, + -148,-1790, 2480,19284,13999, -902,-1064, -25, + -144,-1779, 2396,19213,14113, -862,-1077, -26, + -140,-1768, 2314,19140,14227, -822,-1090, -27, + -136,-1756, 2232,19067,14340, -780,-1104, -29, + -133,-1745, 2151,18992,14453, -738,-1117, -30, + -129,-1733, 2071,18917,14566, -696,-1131, -31, + -126,-1721, 1991,18840,14678, -652,-1145, -32, + -122,-1709, 1913,18762,14790, -608,-1158, -33, + -119,-1697, 1835,18683,14901, -563,-1172, -34, + -116,-1684, 1758,18603,15011, -517,-1186, -36, + -113,-1672, 1682,18522,15122, -470,-1199, -37, + -109,-1659, 1606,18439,15231, -422,-1213, -38, + -106,-1647, 1532,18356,15340, -374,-1227, -40, + -103,-1634, 1458,18272,15448, -325,-1241, -41, + -101,-1621, 1385,18187,15556, -275,-1254, -43, + -98,-1608, 1313,18101,15663, -224,-1268, -44, + -95,-1595, 1241,18013,15770, -172,-1282, -46, + -92,-1582, 1171,17925,15876, -120,-1296, -47, + -89,-1569, 1101,17836,15981, -67,-1310, -49, + -87,-1556, 1032,17746,16085, -13,-1324, -51, + -84,-1542, 964,17655,16189, 42,-1337, -52, + -82,-1529, 897,17563,16292, 98,-1351, -54, + -79,-1516, 830,17471,16395, 154,-1365, -56, + -77,-1502, 765,17377,16497, 212,-1379, -58, + -75,-1489, 700,17282,16598, 270,-1393, -60, + -72,-1475, 636,17187,16698, 329,-1407, -62, + -70,-1461, 573,17091,16797, 389,-1420, -64, + -68,-1448, 511,16994,16896, 449,-1434, -66, + -66,-1434, 449,16896,16994, 511,-1448, -68, + -64,-1420, 389,16797,17091, 573,-1461, -70, + -62,-1407, 329,16698,17187, 636,-1475, -72, + -60,-1393, 270,16598,17282, 700,-1489, -75, + -58,-1379, 212,16497,17377, 765,-1502, -77, + -56,-1365, 154,16395,17471, 830,-1516, -79, + -54,-1351, 98,16292,17563, 897,-1529, -82, + -52,-1337, 42,16189,17655, 964,-1542, -84, + -51,-1324, -13,16085,17746, 1032,-1556, -87, + -49,-1310, -67,15981,17836, 1101,-1569, -89, + -47,-1296, -120,15876,17925, 1171,-1582, -92, + -46,-1282, -172,15770,18013, 1241,-1595, -95, + -44,-1268, -224,15663,18101, 1313,-1608, -98, + -43,-1254, -275,15556,18187, 1385,-1621, -101, + -41,-1241, -325,15448,18272, 1458,-1634, -103, + -40,-1227, -374,15340,18356, 1532,-1647, -106, + -38,-1213, -422,15231,18439, 1606,-1659, -109, + -37,-1199, -470,15122,18522, 1682,-1672, -113, + -36,-1186, -517,15011,18603, 1758,-1684, -116, + -34,-1172, -563,14901,18683, 1835,-1697, -119, + -33,-1158, -608,14790,18762, 1913,-1709, -122, + -32,-1145, -652,14678,18840, 1991,-1721, -126, + -31,-1131, -696,14566,18917, 2071,-1733, -129, + -30,-1117, -738,14453,18992, 2151,-1745, -133, + -29,-1104, -780,14340,19067, 2232,-1756, -136, + -27,-1090, -822,14227,19140, 2314,-1768, -140, + -26,-1077, -862,14113,19213, 2396,-1779, -144, + -25,-1064, -902,13999,19284, 2480,-1790, -148, + -24,-1050, -941,13884,19354, 2564,-1801, -151, + -23,-1037, -979,13769,19423, 2649,-1812, -155, + -23,-1024,-1016,13653,19491, 2734,-1823, -159, + -22,-1011,-1053,13537,19557, 2821,-1834, -164, + -21, -997,-1088,13421,19623, 2908,-1844, -168, + -20, -984,-1124,13305,19687, 2996,-1854, -172, + -19, -971,-1158,13188,19750, 3085,-1864, -176, + -18, -959,-1191,13071,19812, 3174,-1874, -181, + -18, -946,-1224,12953,19872, 3264,-1883, -185, + -17, -933,-1256,12836,19932, 3355,-1893, -190, + -16, -920,-1288,12718,19990, 3447,-1902, -195, + -15, -908,-1318,12600,20046, 3539,-1911, -199, + -15, -895,-1348,12481,20102, 3632,-1919, -204, + -14, -883,-1378,12363,20156, 3726,-1928, -209, + -13, -870,-1406,12244,20209, 3821,-1936, -214, + -13, -858,-1434,12125,20261, 3916,-1944, -219, + -12, -846,-1461,12006,20311, 4012,-1952, -225, + -12, -833,-1487,11887,20360, 4108,-1959, -230, + -11, -821,-1513,11768,20408, 4205,-1966, -235, + -11, -809,-1538,11648,20454, 4303,-1973, -241, + -10, -797,-1562,11529,20499, 4402,-1980, -246, + -10, -786,-1586,11409,20543, 4501,-1986, -252, + -9, -774,-1609,11290,20585, 4601,-1993, -258, + -9, -762,-1631,11170,20626, 4701,-1998, -264, + -8, -751,-1653,11050,20666, 4803,-2004, -269, + -8, -739,-1674,10930,20704, 4904,-2009, -275, + -7, -728,-1694,10811,20741, 5007,-2014, -282, + -7, -717,-1714,10691,20777, 5110,-2018, -288, + -7, -705,-1733,10571,20811, 5213,-2023, -294, + -6, -694,-1751,10451,20844, 5318,-2026, -301, + -6, -683,-1769,10332,20875, 5422,-2030, -307, + -6, -672,-1786,10212,20905, 5528,-2033, -314, + -5, -662,-1803,10093,20934, 5634,-2036, -320, + -5, -651,-1819, 9973,20961, 5740,-2039, -327, + -5, -640,-1834, 9854,20987, 5847,-2041, -334, + -4, -630,-1849, 9735,21011, 5955,-2042, -341, + -4, -619,-1863, 9616,21034, 6063,-2044, -348, + -4, -609,-1877, 9497,21056, 6171,-2045, -355, + -4, -599,-1890, 9378,21076, 6280,-2045, -363, + -3, -589,-1902, 9259,21095, 6390,-2046, -370, + -3, -579,-1914, 9141,21112, 6500,-2045, -378, + -3, -569,-1925, 9023,21128, 6611,-2045, -385, + -3, -559,-1936, 8905,21142, 6722,-2044, -393, + -3, -549,-1946, 8787,21155, 6833,-2042, -401, + -2, -540,-1956, 8670,21167, 6945,-2040, -409, + -2, -530,-1965, 8553,21177, 7058,-2038, -417, + -2, -521,-1974, 8436,21186, 7170,-2035, -425, + -2, -512,-1982, 8319,21193, 7284,-2032, -433, + -2, -503,-1989, 8203,21199, 7397,-2028, -441, + -2, -494,-1996, 8086,21203, 7511,-2024, -450, + -2, -485,-2003, 7971,21206, 7625,-2020, -458, + -9, -476,-2009, 7855,21207, 7740,-2015, -467, diff --git a/services/multimedia/audio/process/resample/coef/resample_44p1k_to_50p7k_filter.txt b/services/multimedia/audio/process/resample/coef/resample_44p1k_to_50p7k_filter.txt new file mode 100644 index 0000000..f3eefe8 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_44p1k_to_50p7k_filter.txt @@ -0,0 +1,157 @@ +//#define FIRFILTER_NUM (24) +//#define UPSAMPLE_FACTOR_44P1TO50P7 38 +//#define DOWNSAMPLE_FACTOR_44P1TO50P7 33 + + -16, 113, 198, -310, 530, -797, + 1092, -1384, 1634, -1789, 1718, 30578, + 2547, -2157, 1833, -1493, 1146, -818, + 532, -303, 186, 122, -17, -1, + -16, 105, 210, -315, 525, -772, + 1033, -1270, 1430, -1421, 922, 30517, + 3408, -2523, 2026, -1594, 1194, -834, + 531, -295, 173, 130, -17, 0, + -16, 97, 220, -318, 517, -743, + 970, -1151, 1222, -1056, 162, 30394, + 4298, -2885, 2211, -1689, 1236, -846, + 527, -284, 159, 139, -17, -1, + -15, 90, 230, -319, 507, -711, + 902, -1028, 1013, -696, -561, 30210, + 5215, -3242, 2387, -1775, 1272, -853, + 520, -272, 144, 147, -17, -1, + -15, 82, 239, -318, 493, -675, + 830, -901, 802, -342, -1245, 29966, + 6156, -3590, 2553, -1853, 1301, -855, + 510, -258, 128, 156, -17, -1, + -14, 75, 246, -316, 478, -637, + 755, -772, 591, 4, -1889, 29663, + 7118, -3927, 2708, -1921, 1322, -853, + 496, -242, 111, 164, -17, -1, + -13, 68, 253, -312, 460, -595, + 677, -641, 382, 340, -2491, 29302, + 8100, -4252, 2850, -1979, 1337, -845, + 479, -224, 94, 173, -17, -1, + -13, 61, 259, -306, 440, -551, + 597, -509, 175, 664, -3050, 28884, + 9097, -4561, 2979, -2027, 1343, -832, + 459, -204, 76, 181, -16, -1, + -12, 54, 263, -298, 418, -505, + 515, -377, -28, 975, -3566, 28410, + 10106, -4853, 3093, -2063, 1342, -814, + 436, -183, 58, 190, -15, -2, + -11, 48, 267, -290, 394, -457, + 432, -245, -226, 1272, -4038, 27884, + 11125, -5125, 3190, -2088, 1333, -790, + 410, -161, 39, 198, -15, -2, + -11, 42, 270, -279, 368, -407, + 348, -115, -418, 1553, -4466, 27305, + 12150, -5374, 3271, -2101, 1315, -762, + 381, -136, 20, 206, -14, -2, + -10, 37, 272, -268, 341, -356, + 264, 13, -604, 1817, -4848, 26677, + 13179, -5600, 3334, -2101, 1289, -728, + 349, -111, 1, 214, -12, -2, + -9, 31, 273, -255, 313, -304, + 181, 138, -781, 2063, -5186, 26002, + 14206, -5799, 3379, -2089, 1255, -689, + 314, -84, -19, 221, -11, -3, + -9, 26, 273, -241, 284, -252, + 98, 259, -950, 2290, -5480, 25282, + 15230, -5970, 3404, -2064, 1213, -645, + 277, -56, -39, 228, -9, -3, + -8, 22, 272, -226, 254, -200, + 16, 377, -1109, 2497, -5729, 24519, + 16247, -6111, 3409, -2025, 1163, -597, + 237, -27, -59, 235, -7, -3, + -8, 17, 271, -209, 223, -147, + -64, 489, -1259, 2684, -5934, 23717, + 17253, -6219, 3393, -1974, 1104, -544, + 195, 3, -79, 242, -5, -4, + -7, 13, 269, -193, 191, -95, + -142, 597, -1397, 2850, -6096, 22879, + 18246, -6293, 3356, -1910, 1038, -486, + 151, 33, -99, 247, -3, -4, + -6, 9, 266, -175, 160, -44, + -217, 698, -1524, 2994, -6215, 22007, + 19220, -6331, 3298, -1832, 964, -425, + 104, 65, -119, 253, 0, -5, + -6, 6, 262, -157, 128, 7, + -290, 793, -1639, 3117, -6294, 21104, + 20174, -6332, 3219, -1742, 882, -359, + 56, 96, -138, 258, 3, -5, + -5, 3, 258, -138, 96, 56, + -359, 882, -1742, 3219, -6332, 20174, + 21104, -6294, 3117, -1639, 793, -290, + 7, 128, -157, 262, 6, -6, + -5, 0, 253, -119, 65, 104, + -425, 964, -1832, 3298, -6331, 19220, + 22007, -6215, 2994, -1524, 698, -217, + -44, 160, -175, 266, 9, -6, + -4, -3, 247, -99, 33, 151, + -486, 1038, -1910, 3356, -6293, 18246, + 22879, -6096, 2850, -1397, 597, -142, + -95, 191, -193, 269, 13, -7, + -4, -5, 242, -79, 3, 195, + -544, 1104, -1974, 3393, -6219, 17253, + 23717, -5934, 2684, -1259, 489, -64, + -147, 223, -209, 271, 17, -8, + -3, -7, 235, -59, -27, 237, + -597, 1163, -2025, 3409, -6111, 16247, + 24519, -5729, 2497, -1109, 377, 16, + -200, 254, -226, 272, 22, -8, + -3, -9, 228, -39, -56, 277, + -645, 1213, -2064, 3404, -5970, 15230, + 25282, -5480, 2290, -950, 259, 98, + -252, 284, -241, 273, 26, -9, + -3, -11, 221, -19, -84, 314, + -689, 1255, -2089, 3379, -5799, 14206, + 26002, -5186, 2063, -781, 138, 181, + -304, 313, -255, 273, 31, -9, + -2, -12, 214, 1, -111, 349, + -728, 1289, -2101, 3334, -5600, 13179, + 26677, -4848, 1817, -604, 13, 264, + -356, 341, -268, 272, 37, -10, + -2, -14, 206, 20, -136, 381, + -762, 1315, -2101, 3271, -5374, 12150, + 27305, -4466, 1553, -418, -115, 348, + -407, 368, -279, 270, 42, -11, + -2, -15, 198, 39, -161, 410, + -790, 1333, -2088, 3190, -5125, 11125, + 27884, -4038, 1272, -226, -245, 432, + -457, 394, -290, 267, 48, -11, + -2, -15, 190, 58, -183, 436, + -814, 1342, -2063, 3093, -4853, 10106, + 28410, -3566, 975, -28, -377, 515, + -505, 418, -298, 263, 54, -12, + -1, -16, 181, 76, -204, 459, + -832, 1343, -2027, 2979, -4561, 9097, + 28884, -3050, 664, 175, -509, 597, + -551, 440, -306, 259, 61, -13, + -1, -17, 173, 94, -224, 479, + -845, 1337, -1979, 2850, -4252, 8100, + 29302, -2491, 340, 382, -641, 677, + -595, 460, -312, 253, 68, -13, + -1, -17, 164, 111, -242, 496, + -853, 1322, -1921, 2708, -3927, 7118, + 29663, -1889, 4, 591, -772, 755, + -637, 478, -316, 246, 75, -14, + -1, -17, 156, 128, -258, 510, + -855, 1301, -1853, 2553, -3590, 6156, + 29966, -1245, -342, 802, -901, 830, + -675, 493, -318, 239, 82, -15, + -1, -17, 147, 144, -272, 520, + -853, 1272, -1775, 2387, -3242, 5215, + 30210, -561, -696, 1013, -1028, 902, + -711, 507, -319, 230, 90, -15, + -1, -17, 139, 159, -284, 527, + -846, 1236, -1689, 2211, -2885, 4298, + 30394, 162, -1056, 1222, -1151, 970, + -743, 517, -318, 220, 97, -16, + 0, -17, 130, 173, -295, 531, + -834, 1194, -1594, 2026, -2523, 3408, + 30517, 922, -1421, 1430, -1270, 1033, + -772, 525, -315, 210, 105, -16, + -1, -17, 122, 186, -303, 532, + -818, 1146, -1493, 1833, -2157, 2547, + 30578, 1718, -1789, 1634, -1384, 1092, + -797, 530, -310, 198, 113, -16, + diff --git a/services/multimedia/audio/process/resample/coef/resample_48k_to_44p1k_filter.txt b/services/multimedia/audio/process/resample/coef/resample_48k_to_44p1k_filter.txt new file mode 100644 index 0000000..91d1904 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_48k_to_44p1k_filter.txt @@ -0,0 +1,148 @@ +//single phase coef Number:=8, upsample factor:=147, downsample factor:=160 + -433,-1703, 7924,20785, 8044,-1695, -441, -8, + -424,-1711, 7803,20783, 8165,-1686, -450, -2, + -416,-1718, 7684,20780, 8286,-1676, -459, -2, + -407,-1724, 7564,20775, 8408,-1666, -468, -2, + -399,-1731, 7446,20769, 8530,-1656, -477, -2, + -391,-1736, 7327,20761, 8652,-1645, -487, -2, + -383,-1741, 7209,20751, 8774,-1633, -496, -2, + -375,-1746, 7091,20739, 8897,-1620, -505, -3, + -367,-1750, 6974,20727, 9020,-1607, -515, -3, + -359,-1753, 6858,20712, 9143,-1594, -525, -3, + -352,-1757, 6742,20696, 9266,-1579, -534, -3, + -344,-1759, 6626,20678, 9390,-1564, -544, -3, + -337,-1761, 6511,20658, 9514,-1549, -554, -4, + -330,-1763, 6397,20637, 9638,-1533, -564, -4, + -322,-1764, 6283,20615, 9762,-1516, -574, -4, + -315,-1765, 6169,20590, 9886,-1498, -585, -4, + -308,-1765, 6057,20565,10011,-1480, -595, -5, + -301,-1765, 5944,20537,10135,-1461, -606, -5, + -295,-1765, 5833,20508,10260,-1442, -616, -5, + -288,-1764, 5722,20478,10385,-1421, -627, -6, + -282,-1762, 5611,20446,10510,-1400, -638, -6, + -275,-1761, 5502,20412,10634,-1379, -649, -6, + -269,-1759, 5392,20377,10759,-1356, -660, -7, + -263,-1756, 5284,20340,10884,-1333, -671, -7, + -256,-1753, 5176,20301,11009,-1309, -682, -8, + -250,-1750, 5069,20261,11134,-1284, -693, -8, + -244,-1746, 4963,20220,11259,-1259, -704, -9, + -239,-1742, 4857,20177,11383,-1233, -716, -9, + -233,-1738, 4752,20133,11508,-1206, -727, -10, + -227,-1733, 4648,20087,11632,-1178, -739, -10, + -222,-1729, 4544,20039,11757,-1150, -751, -11, + -216,-1723, 4441,19990,11881,-1121, -763, -11, + -211,-1718, 4339,19940,12005,-1091, -774, -12, + -206,-1712, 4238,19888,12129,-1060, -786, -12, + -200,-1705, 4137,19834,12253,-1029, -798, -13, + -195,-1699, 4037,19779,12376, -996, -810, -14, + -190,-1692, 3938,19723,12500, -963, -823, -14, + -186,-1685, 3840,19665,12623, -929, -835, -15, + -181,-1678, 3743,19606,12745, -894, -847, -16, + -176,-1670, 3646,19545,12868, -859, -860, -16, + -171,-1662, 3550,19483,12990, -822, -872, -17, + -167,-1654, 3455,19420,13112, -785, -885, -18, + -163,-1646, 3361,19355,13234, -747, -897, -19, + -158,-1637, 3267,19289,13355, -708, -910, -20, + -154,-1628, 3175,19222,13476, -668, -922, -21, + -150,-1619, 3083,19153,13596, -627, -935, -22, + -146,-1610, 2992,19083,13716, -586, -948, -23, + -142,-1600, 2902,19011,13836, -543, -961, -24, + -138,-1591, 2813,18938,13955, -500, -974, -25, + -134,-1581, 2724,18864,14073, -456, -987, -26, + -130,-1571, 2637,18789,14191, -411,-1000, -27, + -126,-1561, 2550,18712,14309, -365,-1013, -28, + -123,-1550, 2464,18634,14426, -319,-1026, -29, + -119,-1540, 2380,18555,14543, -271,-1039, -30, + -116,-1529, 2296,18474,14659, -222,-1052, -31, + -113,-1518, 2213,18393,14774, -173,-1065, -33, + -109,-1507, 2130,18310,14889, -123,-1078, -34, + -106,-1496, 2049,18226,15003, -72,-1091, -35, + -103,-1484, 1969,18141,15117, -19,-1104, -37, + -100,-1473, 1889,18054,15230, 34,-1117, -38, + -97,-1461, 1810,17967,15342, 87,-1131, -40, + -94,-1449, 1733,17878,15454, 142,-1144, -41, + -91,-1437, 1656,17788,15565, 198,-1157, -43, + -88,-1425, 1580,17698,15675, 255,-1170, -45, + -85,-1413, 1505,17606,15784, 312,-1183, -46, + -83,-1401, 1431,17513,15893, 371,-1196, -48, + -80,-1389, 1358,17419,16001, 430,-1210, -50, + -78,-1376, 1285,17323,16108, 490,-1223, -51, + -75,-1364, 1214,17227,16214, 551,-1236, -53, + -73,-1351, 1144,17130,16319, 614,-1249, -55, + -70,-1339, 1074,17032,16424, 677,-1262, -57, + -68,-1326, 1006,16933,16527, 741,-1275, -59, + -66,-1313, 938,16833,16630, 805,-1288, -61, + -63,-1301, 871,16732,16732, 871,-1301, -63, + -61,-1288, 805,16630,16833, 938,-1313, -66, + -59,-1275, 741,16527,16933, 1006,-1326, -68, + -57,-1262, 677,16424,17032, 1074,-1339, -70, + -55,-1249, 614,16319,17130, 1144,-1351, -73, + -53,-1236, 551,16214,17227, 1214,-1364, -75, + -51,-1223, 490,16108,17323, 1285,-1376, -78, + -50,-1210, 430,16001,17419, 1358,-1389, -80, + -48,-1196, 371,15893,17513, 1431,-1401, -83, + -46,-1183, 312,15784,17606, 1505,-1413, -85, + -45,-1170, 255,15675,17698, 1580,-1425, -88, + -43,-1157, 198,15565,17788, 1656,-1437, -91, + -41,-1144, 142,15454,17878, 1733,-1449, -94, + -40,-1131, 87,15342,17967, 1810,-1461, -97, + -38,-1117, 34,15230,18054, 1889,-1473, -100, + -37,-1104, -19,15117,18141, 1969,-1484, -103, + -35,-1091, -72,15003,18226, 2049,-1496, -106, + -34,-1078, -123,14889,18310, 2130,-1507, -109, + -33,-1065, -173,14774,18393, 2213,-1518, -113, + -31,-1052, -222,14659,18474, 2296,-1529, -116, + -30,-1039, -271,14543,18555, 2380,-1540, -119, + -29,-1026, -319,14426,18634, 2464,-1550, -123, + -28,-1013, -365,14309,18712, 2550,-1561, -126, + -27,-1000, -411,14191,18789, 2637,-1571, -130, + -26, -987, -456,14073,18864, 2724,-1581, -134, + -25, -974, -500,13955,18938, 2813,-1591, -138, + -24, -961, -543,13836,19011, 2902,-1600, -142, + -23, -948, -586,13716,19083, 2992,-1610, -146, + -22, -935, -627,13596,19153, 3083,-1619, -150, + -21, -922, -668,13476,19222, 3175,-1628, -154, + -20, -910, -708,13355,19289, 3267,-1637, -158, + -19, -897, -747,13234,19355, 3361,-1646, -163, + -18, -885, -785,13112,19420, 3455,-1654, -167, + -17, -872, -822,12990,19483, 3550,-1662, -171, + -16, -860, -859,12868,19545, 3646,-1670, -176, + -16, -847, -894,12745,19606, 3743,-1678, -181, + -15, -835, -929,12623,19665, 3840,-1685, -186, + -14, -823, -963,12500,19723, 3938,-1692, -190, + -14, -810, -996,12376,19779, 4037,-1699, -195, + -13, -798,-1029,12253,19834, 4137,-1705, -200, + -12, -786,-1060,12129,19888, 4238,-1712, -206, + -12, -774,-1091,12005,19940, 4339,-1718, -211, + -11, -763,-1121,11881,19990, 4441,-1723, -216, + -11, -751,-1150,11757,20039, 4544,-1729, -222, + -10, -739,-1178,11632,20087, 4648,-1733, -227, + -10, -727,-1206,11508,20133, 4752,-1738, -233, + -9, -716,-1233,11383,20177, 4857,-1742, -239, + -9, -704,-1259,11259,20220, 4963,-1746, -244, + -8, -693,-1284,11134,20261, 5069,-1750, -250, + -8, -682,-1309,11009,20301, 5176,-1753, -256, + -7, -671,-1333,10884,20340, 5284,-1756, -263, + -7, -660,-1356,10759,20377, 5392,-1759, -269, + -6, -649,-1379,10634,20412, 5502,-1761, -275, + -6, -638,-1400,10510,20446, 5611,-1762, -282, + -6, -627,-1421,10385,20478, 5722,-1764, -288, + -5, -616,-1442,10260,20508, 5833,-1765, -295, + -5, -606,-1461,10135,20537, 5944,-1765, -301, + -5, -595,-1480,10011,20565, 6057,-1765, -308, + -4, -585,-1498, 9886,20590, 6169,-1765, -315, + -4, -574,-1516, 9762,20615, 6283,-1764, -322, + -4, -564,-1533, 9638,20637, 6397,-1763, -330, + -4, -554,-1549, 9514,20658, 6511,-1761, -337, + -3, -544,-1564, 9390,20678, 6626,-1759, -344, + -3, -534,-1579, 9266,20696, 6742,-1757, -352, + -3, -525,-1594, 9143,20712, 6858,-1753, -359, + -3, -515,-1607, 9020,20727, 6974,-1750, -367, + -3, -505,-1620, 8897,20739, 7091,-1746, -375, + -2, -496,-1633, 8774,20751, 7209,-1741, -383, + -2, -487,-1645, 8652,20761, 7327,-1736, -391, + -2, -477,-1656, 8530,20769, 7446,-1731, -399, + -2, -468,-1666, 8408,20775, 7564,-1724, -407, + -2, -459,-1676, 8286,20780, 7684,-1718, -416, + -2, -450,-1686, 8165,20783, 7803,-1711, -424, + -8, -441,-1695, 8044,20785, 7924,-1703, -433, diff --git a/services/multimedia/audio/process/resample/coef/resample_48k_to_50p7k_filter.txt b/services/multimedia/audio/process/resample/coef/resample_48k_to_50p7k_filter.txt new file mode 100644 index 0000000..136b602 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_48k_to_50p7k_filter.txt @@ -0,0 +1,297 @@ +//#define FIRFILTER_NUM (24) +//#define UPSAMPLE_FACTOR_48TO50P7 73 +//#define DOWNSAMPLE_FACTOR_48TO50P7 69 + + -17, 115, 196, -309, 531, -803, + 1107, -1412, 1684, -1879, 1916, 30581, + 2348, -2071, 1788, -1469, 1135, -814, + 533, -305, 190, 119, -17, -1, + -17, 111, 202, -312, 530, -791, + 1078, -1354, 1579, -1688, 1493, 30565, + 2788, -2262, 1890, -1523, 1161, -824, + 533, -301, 183, 124, -17, 0, + -17, 107, 208, -314, 527, -778, + 1047, -1295, 1473, -1496, 1080, 30531, + 3237, -2453, 1990, -1576, 1186, -832, + 532, -297, 176, 128, -18, 0, + -16, 102, 214, -316, 524, -764, + 1015, -1234, 1366, -1306, 676, 30481, + 3694, -2642, 2088, -1627, 1210, -839, + 531, -292, 169, 133, -18, 0, + -16, 98, 219, -318, 519, -749, + 981, -1172, 1257, -1116, 281, 30415, + 4158, -2831, 2184, -1676, 1231, -845, + 529, -286, 161, 137, -18, -1, + -16, 94, 225, -319, 514, -733, + 947, -1108, 1148, -927, -103, 30332, + 4630, -3018, 2278, -1723, 1251, -850, + 525, -280, 154, 142, -18, -1, + -16, 90, 230, -319, 509, -716, + 911, -1044, 1039, -740, -477, 30232, + 5109, -3203, 2369, -1767, 1269, -853, + 521, -274, 146, 146, -18, -1, + -15, 86, 234, -319, 502, -698, + 875, -979, 929, -554, -840, 30116, + 5594, -3386, 2457, -1809, 1285, -855, + 517, -266, 138, 150, -18, -1, + -15, 82, 239, -319, 495, -679, + 837, -912, 819, -370, -1193, 29984, + 6086, -3566, 2543, -1849, 1300, -856, + 511, -259, 130, 155, -18, -1, + -15, 78, 243, -318, 488, -659, + 798, -845, 710, -189, -1534, 29836, + 6584, -3743, 2625, -1886, 1312, -855, + 504, -251, 121, 159, -18, -1, + -14, 75, 247, -316, 479, -639, + 759, -778, 600, -10, -1865, 29672, + 7087, -3918, 2705, -1920, 1323, -853, + 497, -242, 112, 164, -18, -1, + -14, 71, 250, -314, 470, -618, + 719, -710, 491, 167, -2184, 29493, + 7595, -4088, 2780, -1952, 1331, -850, + 489, -233, 103, 168, -17, -1, + -14, 67, 254, -312, 461, -596, + 678, -642, 382, 340, -2492, 29297, + 8108, -4256, 2853, -1981, 1338, -845, + 479, -224, 94, 173, -17, -1, + -13, 64, 257, -309, 451, -573, + 636, -573, 274, 511, -2789, 29086, + 8625, -4418, 2921, -2007, 1342, -839, + 469, -214, 85, 177, -17, -1, + -13, 60, 259, -306, 440, -550, + 594, -504, 167, 678, -3074, 28860, + 9146, -4577, 2986, -2030, 1344, -831, + 459, -203, 76, 182, -17, -1, + -13, 57, 262, -302, 428, -526, + 552, -435, 61, 841, -3347, 28620, + 9671, -4730, 3047, -2050, 1344, -822, + 447, -192, 66, 186, -16, -2, + -12, 53, 264, -298, 417, -502, + 509, -367, -44, 1001, -3608, 28364, + 10198, -4879, 3103, -2067, 1342, -812, + 434, -181, 57, 191, -16, -2, + -12, 50, 266, -293, 404, -477, + 466, -298, -148, 1156, -3857, 28094, + 10728, -5022, 3155, -2080, 1338, -800, + 421, -169, 47, 195, -16, -2, + -12, 47, 268, -289, 392, -451, + 422, -230, -250, 1308, -4094, 27809, + 11260, -5160, 3203, -2091, 1331, -787, + 407, -157, 37, 199, -15, -2, + -11, 44, 270, -283, 378, -426, + 379, -162, -350, 1455, -4320, 27511, + 11793, -5291, 3246, -2098, 1323, -772, + 392, -145, 27, 203, -15, -2, + -11, 41, 271, -278, 365, -399, + 335, -95, -449, 1598, -4533, 27199, + 12328, -5416, 3284, -2102, 1312, -756, + 376, -132, 17, 207, -14, -2, + -11, 38, 272, -272, 351, -373, + 291, -28, -546, 1736, -4734, 26874, + 12863, -5534, 3317, -2103, 1298, -739, + 359, -119, 7, 212, -13, -2, + -10, 35, 273, -265, 336, -346, + 248, 38, -641, 1869, -4922, 26536, + 13398, -5646, 3346, -2100, 1283, -720, + 342, -105, -3, 216, -13, -3, + -10, 32, 273, -258, 322, -319, + 204, 103, -733, 1997, -5099, 26185, + 13933, -5750, 3369, -2094, 1265, -700, + 324, -91, -14, 220, -12, -3, + -10, 30, 274, -251, 307, -292, + 161, 167, -823, 2121, -5264, 25822, + 14467, -5846, 3387, -2084, 1245, -678, + 305, -77, -24, 223, -11, -3, + -9, 27, 274, -244, 291, -265, + 117, 231, -911, 2239, -5416, 25447, + 15000, -5935, 3400, -2071, 1223, -656, + 285, -62, -35, 227, -10, -3, + -9, 24, 273, -237, 276, -238, + 75, 293, -997, 2351, -5556, 25060, + 15532, -6015, 3408, -2054, 1199, -631, + 265, -47, -45, 231, -9, -3, + -9, 22, 273, -229, 260, -210, + 32, 354, -1079, 2459, -5685, 24662, + 16061, -6088, 3409, -2033, 1172, -606, + 244, -32, -55, 234, -8, -4, + -8, 20, 272, -220, 244, -183, + -10, 414, -1160, 2561, -5801, 24253, + 16587, -6151, 3406, -2010, 1144, -579, + 223, -17, -66, 238, -7, -4, + -8, 17, 272, -212, 228, -156, + -52, 472, -1237, 2657, -5906, 23834, + 17110, -6206, 3397, -1982, 1113, -551, + 201, -1, -76, 241, -6, -4, + -8, 15, 271, -203, 212, -128, + -93, 529, -1311, 2748, -5999, 23405, + 17630, -6251, 3382, -1951, 1080, -522, + 178, 15, -87, 244, -5, -4, + -7, 13, 269, -195, 195, -101, + -133, 585, -1382, 2833, -6080, 22966, + 18145, -6287, 3361, -1917, 1044, -492, + 155, 31, -97, 247, -4, -4, + -7, 11, 268, -185, 179, -74, + -173, 639, -1451, 2912, -6150, 22518, + 18656, -6313, 3334, -1879, 1007, -460, + 131, 47, -107, 250, -2, -5, + -7, 9, 266, -176, 162, -47, + -212, 691, -1516, 2985, -6209, 22061, + 19161, -6330, 3302, -1837, 968, -428, + 107, 63, -117, 253, -1, -5, + -6, 7, 265, -167, 146, -21, + -250, 742, -1578, 3053, -6256, 21596, + 19661, -6336, 3264, -1792, 926, -394, + 82, 80, -127, 256, 0, -5, + -6, 5, 263, -157, 129, 5, + -287, 791, -1636, 3114, -6292, 21123, + 20155, -6332, 3220, -1743, 883, -360, + 57, 96, -138, 258, 2, -5, + -6, 4, 260, -147, 113, 31, + -324, 838, -1691, 3170, -6317, 20643, + 20643, -6317, 3170, -1691, 838, -324, + 31, 113, -147, 260, 4, -6, + -5, 2, 258, -138, 96, 57, + -360, 883, -1743, 3220, -6332, 20155, + 21123, -6292, 3114, -1636, 791, -287, + 5, 129, -157, 263, 5, -6, + -5, 0, 256, -127, 80, 82, + -394, 926, -1792, 3264, -6336, 19661, + 21596, -6256, 3053, -1578, 742, -250, + -21, 146, -167, 265, 7, -6, + -5, -1, 253, -117, 63, 107, + -428, 968, -1837, 3302, -6330, 19161, + 22061, -6209, 2985, -1516, 691, -212, + -47, 162, -176, 266, 9, -7, + -5, -2, 250, -107, 47, 131, + -460, 1007, -1879, 3334, -6313, 18656, + 22518, -6150, 2912, -1451, 639, -173, + -74, 179, -185, 268, 11, -7, + -4, -4, 247, -97, 31, 155, + -492, 1044, -1917, 3361, -6287, 18145, + 22966, -6080, 2833, -1382, 585, -133, + -101, 195, -195, 269, 13, -7, + -4, -5, 244, -87, 15, 178, + -522, 1080, -1951, 3382, -6251, 17630, + 23405, -5999, 2748, -1311, 529, -93, + -128, 212, -203, 271, 15, -8, + -4, -6, 241, -76, -1, 201, + -551, 1113, -1982, 3397, -6206, 17110, + 23834, -5906, 2657, -1237, 472, -52, + -156, 228, -212, 272, 17, -8, + -4, -7, 238, -66, -17, 223, + -579, 1144, -2010, 3406, -6151, 16587, + 24253, -5801, 2561, -1160, 414, -10, + -183, 244, -220, 272, 20, -8, + -4, -8, 234, -55, -32, 244, + -606, 1172, -2033, 3409, -6088, 16061, + 24662, -5685, 2459, -1079, 354, 32, + -210, 260, -229, 273, 22, -9, + -3, -9, 231, -45, -47, 265, + -631, 1199, -2054, 3408, -6015, 15532, + 25060, -5556, 2351, -997, 293, 75, + -238, 276, -237, 273, 24, -9, + -3, -10, 227, -35, -62, 285, + -656, 1223, -2071, 3400, -5935, 15000, + 25447, -5416, 2239, -911, 231, 117, + -265, 291, -244, 274, 27, -9, + -3, -11, 223, -24, -77, 305, + -678, 1245, -2084, 3387, -5846, 14467, + 25822, -5264, 2121, -823, 167, 161, + -292, 307, -251, 274, 30, -10, + -3, -12, 220, -14, -91, 324, + -700, 1265, -2094, 3369, -5750, 13933, + 26185, -5099, 1997, -733, 103, 204, + -319, 322, -258, 273, 32, -10, + -3, -13, 216, -3, -105, 342, + -720, 1283, -2100, 3346, -5646, 13398, + 26536, -4922, 1869, -641, 38, 248, + -346, 336, -265, 273, 35, -10, + -2, -13, 212, 7, -119, 359, + -739, 1298, -2103, 3317, -5534, 12863, + 26874, -4734, 1736, -546, -28, 291, + -373, 351, -272, 272, 38, -11, + -2, -14, 207, 17, -132, 376, + -756, 1312, -2102, 3284, -5416, 12328, + 27199, -4533, 1598, -449, -95, 335, + -399, 365, -278, 271, 41, -11, + -2, -15, 203, 27, -145, 392, + -772, 1323, -2098, 3246, -5291, 11793, + 27511, -4320, 1455, -350, -162, 379, + -426, 378, -283, 270, 44, -11, + -2, -15, 199, 37, -157, 407, + -787, 1331, -2091, 3203, -5160, 11260, + 27809, -4094, 1308, -250, -230, 422, + -451, 392, -289, 268, 47, -12, + -2, -16, 195, 47, -169, 421, + -800, 1338, -2080, 3155, -5022, 10728, + 28094, -3857, 1156, -148, -298, 466, + -477, 404, -293, 266, 50, -12, + -2, -16, 191, 57, -181, 434, + -812, 1342, -2067, 3103, -4879, 10198, + 28364, -3608, 1001, -44, -367, 509, + -502, 417, -298, 264, 53, -12, + -2, -16, 186, 66, -192, 447, + -822, 1344, -2050, 3047, -4730, 9671, + 28620, -3347, 841, 61, -435, 552, + -526, 428, -302, 262, 57, -13, + -1, -17, 182, 76, -203, 459, + -831, 1344, -2030, 2986, -4577, 9146, + 28860, -3074, 678, 167, -504, 594, + -550, 440, -306, 259, 60, -13, + -1, -17, 177, 85, -214, 469, + -839, 1342, -2007, 2921, -4418, 8625, + 29086, -2789, 511, 274, -573, 636, + -573, 451, -309, 257, 64, -13, + -1, -17, 173, 94, -224, 479, + -845, 1338, -1981, 2853, -4256, 8108, + 29297, -2492, 340, 382, -642, 678, + -596, 461, -312, 254, 67, -14, + -1, -17, 168, 103, -233, 489, + -850, 1331, -1952, 2780, -4088, 7595, + 29493, -2184, 167, 491, -710, 719, + -618, 470, -314, 250, 71, -14, + -1, -18, 164, 112, -242, 497, + -853, 1323, -1920, 2705, -3918, 7087, + 29672, -1865, -10, 600, -778, 759, + -639, 479, -316, 247, 75, -14, + -1, -18, 159, 121, -251, 504, + -855, 1312, -1886, 2625, -3743, 6584, + 29836, -1534, -189, 710, -845, 798, + -659, 488, -318, 243, 78, -15, + -1, -18, 155, 130, -259, 511, + -856, 1300, -1849, 2543, -3566, 6086, + 29984, -1193, -370, 819, -912, 837, + -679, 495, -319, 239, 82, -15, + -1, -18, 150, 138, -266, 517, + -855, 1285, -1809, 2457, -3386, 5594, + 30116, -840, -554, 929, -979, 875, + -698, 502, -319, 234, 86, -15, + -1, -18, 146, 146, -274, 521, + -853, 1269, -1767, 2369, -3203, 5109, + 30232, -477, -740, 1039, -1044, 911, + -716, 509, -319, 230, 90, -16, + -1, -18, 142, 154, -280, 525, + -850, 1251, -1723, 2278, -3018, 4630, + 30332, -103, -927, 1148, -1108, 947, + -733, 514, -319, 225, 94, -16, + -1, -18, 137, 161, -286, 529, + -845, 1231, -1676, 2184, -2831, 4158, + 30415, 281, -1116, 1257, -1172, 981, + -749, 519, -318, 219, 98, -16, + 0, -18, 133, 169, -292, 531, + -839, 1210, -1627, 2088, -2642, 3694, + 30481, 676, -1306, 1366, -1234, 1015, + -764, 524, -316, 214, 102, -16, + 0, -18, 128, 176, -297, 532, + -832, 1186, -1576, 1990, -2453, 3237, + 30531, 1080, -1496, 1473, -1295, 1047, + -778, 527, -314, 208, 107, -17, + 0, -17, 124, 183, -301, 533, + -824, 1161, -1523, 1890, -2262, 2788, + 30565, 1493, -1688, 1579, -1354, 1078, + -791, 530, -312, 202, 111, -17, + -1, -17, 119, 190, -305, 533, + -814, 1135, -1469, 1788, -2071, 2348, + 30581, 1916, -1879, 1684, -1412, 1107, + -803, 531, -309, 196, 115, -17, + diff --git a/services/multimedia/audio/process/resample/coef/resample_50p7k_to_44p1k_filter.txt b/services/multimedia/audio/process/resample/coef/resample_50p7k_to_44p1k_filter.txt new file mode 100644 index 0000000..dfd43da --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_50p7k_to_44p1k_filter.txt @@ -0,0 +1,34 @@ +//single phase coef Number:=6, upsample factor:=33, downsample factor:=38 + -1212, 4016,26371, 4690,-1301, -5, +-1125, 3378,26303, 5398,-1389, -5, +-1038, 2776,26167, 6138,-1476, -7, + -954, 2212,25964, 6908,-1560, -11, + -873, 1686,25695, 7706,-1641, -15, + -794, 1199,25362, 8530,-1718, -20, + -719, 749,24967, 9376,-1788, -26, + -649, 338,24512,10241,-1850, -33, + -582, -35,24000,11121,-1903, -43, + -519, -371,23434,12014,-1945, -54, + -461, -671,22817,12915,-1975, -67, + -407, -936,22153,13821,-1990, -82, + -357,-1167,21445,14727,-1989, -99, + -312,-1366,20698,15628,-1969, -120, + -270,-1534,19916,16521,-1930, -143, + -233,-1672,19102,17400,-1868, -170, + -199,-1783,18262,18262,-1783, -199, + -170,-1868,17400,19102,-1672, -233, + -143,-1930,16521,19916,-1534, -270, + -120,-1969,15628,20698,-1366, -312, + -99,-1989,14727,21445,-1167, -357, + -82,-1990,13821,22153, -936, -407, + -67,-1975,12915,22817, -671, -461, + -54,-1945,12014,23434, -371, -519, + -43,-1903,11121,24000, -35, -582, + -33,-1850,10241,24512, 338, -649, + -26,-1788, 9376,24967, 749, -719, + -20,-1718, 8530,25362, 1199, -794, + -15,-1641, 7706,25695, 1686, -873, + -11,-1560, 6908,25964, 2212, -954, + -7,-1476, 6138,26167, 2776,-1038, + -5,-1389, 5398,26303, 3378,-1125, + -5,-1301, 4690,26371, 4016,-1212, diff --git a/services/multimedia/audio/process/resample/coef/resample_50p7k_to_48k_filter.txt b/services/multimedia/audio/process/resample/coef/resample_50p7k_to_48k_filter.txt new file mode 100644 index 0000000..437abad --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_50p7k_to_48k_filter.txt @@ -0,0 +1,70 @@ +//single phase coef Number:=6, upsample factor:=69, downsample factor:=73 + -1179, 4401,25926, 4717,-1218, -8, +-1140, 4092,25911, 5041,-1257, -4, +-1101, 3791,25881, 5372,-1295, -5, +-1062, 3498,25836, 5711,-1334, -6, +-1024, 3213,25776, 6056,-1372, -7, + -985, 2936,25701, 6408,-1409, -8, + -948, 2667,25611, 6767,-1446, -10, + -910, 2407,25507, 7131,-1482, -11, + -873, 2155,25388, 7502,-1517, -13, + -837, 1911,25255, 7878,-1551, -15, + -802, 1676,25108, 8260,-1584, -18, + -767, 1449,24947, 8647,-1616, -20, + -732, 1231,24772, 9039,-1646, -23, + -699, 1021,24584, 9435,-1674, -26, + -666, 819,24383, 9835,-1700, -30, + -634, 626,24168,10240,-1725, -33, + -603, 441,23941,10647,-1747, -38, + -573, 265,23701,11058,-1768, -42, + -544, 97,23450,11471,-1785, -47, + -515, -64,23187,11886,-1800, -52, + -488, -216,22912,12303,-1812, -58, + -461, -360,22626,12722,-1821, -64, + -435, -497,22330,13142,-1827, -71, + -411, -625,22023,13562,-1830, -78, + -387, -746,21707,13982,-1828, -86, + -364, -860,21381,14402,-1823, -94, + -342, -967,21046,14822,-1814, -103, + -321,-1066,20702,15240,-1801, -112, + -300,-1158,20350,15656,-1783, -122, + -281,-1244,19991,16070,-1761, -133, + -263,-1322,19624,16482,-1734, -144, + -245,-1395,19250,16891,-1702, -157, + -228,-1461,18870,17295,-1665, -169, + -212,-1520,18484,17696,-1623, -183, + -197,-1574,18093,18093,-1574, -197, + -183,-1623,17696,18484,-1520, -212, + -169,-1665,17295,18870,-1461, -228, + -157,-1702,16891,19250,-1395, -245, + -144,-1734,16482,19624,-1322, -263, + -133,-1761,16070,19991,-1244, -281, + -122,-1783,15656,20350,-1158, -300, + -112,-1801,15240,20702,-1066, -321, + -103,-1814,14822,21046, -967, -342, + -94,-1823,14402,21381, -860, -364, + -86,-1828,13982,21707, -746, -387, + -78,-1830,13562,22023, -625, -411, + -71,-1827,13142,22330, -497, -435, + -64,-1821,12722,22626, -360, -461, + -58,-1812,12303,22912, -216, -488, + -52,-1800,11886,23187, -64, -515, + -47,-1785,11471,23450, 97, -544, + -42,-1768,11058,23701, 265, -573, + -38,-1747,10647,23941, 441, -603, + -33,-1725,10240,24168, 626, -634, + -30,-1700, 9835,24383, 819, -666, + -26,-1674, 9435,24584, 1021, -699, + -23,-1646, 9039,24772, 1231, -732, + -20,-1616, 8647,24947, 1449, -767, + -18,-1584, 8260,25108, 1676, -802, + -15,-1551, 7878,25255, 1911, -837, + -13,-1517, 7502,25388, 2155, -873, + -11,-1482, 7131,25507, 2407, -910, + -10,-1446, 6767,25611, 2667, -948, + -8,-1409, 6408,25701, 2936, -985, + -7,-1372, 6056,25776, 3213,-1024, + -6,-1334, 5711,25836, 3498,-1062, + -5,-1295, 5372,25881, 3791,-1101, + -4,-1257, 5041,25911, 4092,-1140, + -8,-1218, 4717,25926, 4401,-1179, diff --git a/services/multimedia/audio/process/resample/coef/resample_8k_to_8p4k_filter.txt b/services/multimedia/audio/process/resample/coef/resample_8k_to_8p4k_filter.txt new file mode 100644 index 0000000..631b3a1 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_8k_to_8p4k_filter.txt @@ -0,0 +1,224 @@ +//#define UPSAMPLE_FACTOR_8TO8P4 73 +//#define DOWNSAMPLE_FACTOR_8TO8P4 69 +//#define FIRFILTER_NUM_MONO_8TO8P4 18 + + -13, 936, -414, 500, -551, 588, + -590, 502,31399, 932, -790, 706, + -626, 547, -446, 946, -8, -41, + -18, 926, -381, 452, -477, 470, + -392, 84,31380, 1373, -992, 824, + -700, 594, -477, 954, -3, -8, + -22, 916, -348, 404, -402, 353, + -197, -324,31342, 1824,-1195, 942, + -773, 641, -508, 963, 3, -9, + -26, 904, -314, 356, -328, 237, + -4, -719,31286, 2285,-1399, 1060, + -847, 687, -538, 970, 9, -10, + -30, 893, -280, 308, -254, 122, + 186,-1102,31211, 2756,-1605, 1178, + -919, 732, -568, 977, 15, -10, + -33, 881, -246, 259, -180, 9, + 372,-1474,31118, 3237,-1811, 1296, + -991, 776, -596, 983, 21, -11, + -37, 868, -211, 211, -107, -104, + 555,-1833,31006, 3727,-2017, 1412, +-1062, 820, -624, 988, 28, -12, + -40, 855, -176, 163, -35, -214, + 734,-2179,30876, 4225,-2223, 1527, +-1132, 863, -651, 993, 35, -13, + -43, 841, -141, 115, 37, -323, + 908,-2512,30727, 4732,-2428, 1642, +-1201, 904, -677, 997, 43, -14, + -45, 827, -106, 68, 107, -430, + 1079,-2833,30561, 5247,-2633, 1754, +-1268, 945, -702, 1000, 51, -15, + -47, 813, -71, 21, 177, -535, + 1245,-3140,30376, 5769,-2836, 1865, +-1334, 984, -726, 1002, 59, -16, + -49, 798, -35, -26, 246, -638, + 1406,-3434,30174, 6299,-3037, 1975, +-1398, 1022, -748, 1003, 67, -17, + -51, 783, 0, -72, 313, -738, + 1563,-3715,29955, 6834,-3237, 2082, +-1461, 1059, -770, 1003, 76, -18, + -53, 768, 36, -118, 379, -836, + 1714,-3982,29718, 7376,-3434, 2187, +-1522, 1094, -790, 1003, 85, -20, + -54, 752, 71, -162, 444, -931, + 1860,-4236,29464, 7924,-3629, 2289, +-1580, 1128, -809, 1002, 95, -21, + -56, 736, 106, -206, 507,-1023, + 2000,-4476,29194, 8477,-3820, 2389, +-1637, 1160, -827, 1000, 105, -22, + -57, 720, 141, -250, 569,-1113, + 2135,-4703,28907, 9034,-4008, 2485, +-1692, 1190, -844, 996, 115, -23, + -58, 704, 175, -292, 629,-1199, + 2264,-4916,28605, 9596,-4192, 2579, +-1744, 1219, -859, 992, 125, -24, + -58, 687, 209, -333, 687,-1282, + 2387,-5115,28286,10161,-4372, 2669, +-1793, 1246, -873, 987, 136, -26, + -59, 670, 243, -374, 743,-1362, + 2504,-5300,27953,10729,-4547, 2755, +-1840, 1271, -886, 982, 147, -27, + -59, 654, 277, -413, 798,-1438, + 2615,-5472,27604,11300,-4717, 2838, +-1885, 1294, -897, 975, 159, -28, + -60, 637, 310, -451, 850,-1511, + 2719,-5631,27240,11873,-4881, 2917, +-1926, 1315, -906, 967, 171, -30, + -60, 620, 343, -488, 900,-1581, + 2818,-5775,26863,12447,-5040, 2992, +-1965, 1334, -914, 958, 183, -31, + -60, 603, 375, -524, 948,-1647, + 2910,-5907,26471,13022,-5193, 3062, +-2001, 1351, -921, 948, 195, -32, + -59, 586, 407, -558, 994,-1709, + 2995,-6025,26066,13598,-5339, 3128, +-2033, 1366, -926, 938, 208, -34, + -59, 568, 438, -591, 1038,-1767, + 3074,-6130,25648,14173,-5478, 3189, +-2062, 1379, -929, 926, 221, -35, + -59, 551, 469, -623, 1079,-1822, + 3146,-6221,25217,14748,-5610, 3245, +-2088, 1389, -931, 913, 235, -37, + -58, 534, 498, -653, 1118,-1872, + 3212,-6300,24775,15321,-5734, 3296, +-2111, 1397, -931, 900, 249, -38, + -58, 517, 528, -682, 1155,-1919, + 3271,-6366,24321,15892,-5851, 3342, +-2130, 1403, -929, 885, 263, -39, + -57, 500, 556, -710, 1189,-1962, + 3323,-6419,23855,16461,-5959, 3383, +-2146, 1406, -926, 870, 277, -41, + -56, 483, 584, -735, 1221,-2001, + 3369,-6460,23379,17027,-6058, 3418, +-2158, 1407, -921, 853, 291, -42, + -55, 466, 611, -760, 1251,-2035, + 3408,-6488,22893,17590,-6148, 3448, +-2166, 1405, -915, 836, 306, -44, + -54, 449, 637, -783, 1277,-2066, + 3441,-6504,22397,18148,-6229, 3471, +-2170, 1401, -907, 817, 321, -45, + -53, 433, 663, -804, 1302,-2093, + 3467,-6509,21892,18702,-6301, 3489, +-2171, 1394, -897, 798, 337, -46, + -52, 416, 688, -824, 1324,-2116, + 3486,-6502,21379,19250,-6362, 3501, +-2168, 1385, -886, 778, 352, -48, + -51, 400, 711, -842, 1343,-2135, + 3500,-6483,20857,19792,-6413, 3507, +-2161, 1374, -873, 756, 368, -49, + -50, 384, 734, -858, 1360,-2150, + 3506,-6453,20328,20328,-6453, 3506, +-2150, 1360, -858, 734, 384, -50, + -49, 368, 756, -873, 1374,-2161, + 3507,-6413,19792,20857,-6483, 3500, +-2135, 1343, -842, 711, 400, -51, + -48, 352, 778, -886, 1385,-2168, + 3501,-6362,19250,21379,-6502, 3486, +-2116, 1324, -824, 688, 416, -52, + -46, 337, 798, -897, 1394,-2171, + 3489,-6301,18702,21892,-6509, 3467, +-2093, 1302, -804, 663, 433, -53, + -45, 321, 817, -907, 1401,-2170, + 3471,-6229,18148,22397,-6504, 3441, +-2066, 1277, -783, 637, 449, -54, + -44, 306, 836, -915, 1405,-2166, + 3448,-6148,17590,22893,-6488, 3408, +-2035, 1251, -760, 611, 466, -55, + -42, 291, 853, -921, 1407,-2158, + 3418,-6058,17027,23379,-6460, 3369, +-2001, 1221, -735, 584, 483, -56, + -41, 277, 870, -926, 1406,-2146, + 3383,-5959,16461,23855,-6419, 3323, +-1962, 1189, -710, 556, 500, -57, + -39, 263, 885, -929, 1403,-2130, + 3342,-5851,15892,24321,-6366, 3271, +-1919, 1155, -682, 528, 517, -58, + -38, 249, 900, -931, 1397,-2111, + 3296,-5734,15321,24775,-6300, 3212, +-1872, 1118, -653, 498, 534, -58, + -37, 235, 913, -931, 1389,-2088, + 3245,-5610,14748,25217,-6221, 3146, +-1822, 1079, -623, 469, 551, -59, + -35, 221, 926, -929, 1379,-2062, + 3189,-5478,14173,25648,-6130, 3074, +-1767, 1038, -591, 438, 568, -59, + -34, 208, 938, -926, 1366,-2033, + 3128,-5339,13598,26066,-6025, 2995, +-1709, 994, -558, 407, 586, -59, + -32, 195, 948, -921, 1351,-2001, + 3062,-5193,13022,26471,-5907, 2910, +-1647, 948, -524, 375, 603, -60, + -31, 183, 958, -914, 1334,-1965, + 2992,-5040,12447,26863,-5775, 2818, +-1581, 900, -488, 343, 620, -60, + -30, 171, 967, -906, 1315,-1926, + 2917,-4881,11873,27240,-5631, 2719, +-1511, 850, -451, 310, 637, -60, + -28, 159, 975, -897, 1294,-1885, + 2838,-4717,11300,27604,-5472, 2615, +-1438, 798, -413, 277, 654, -59, + -27, 147, 982, -886, 1271,-1840, + 2755,-4547,10729,27953,-5300, 2504, +-1362, 743, -374, 243, 670, -59, + -26, 136, 987, -873, 1246,-1793, + 2669,-4372,10161,28286,-5115, 2387, +-1282, 687, -333, 209, 687, -58, + -24, 125, 992, -859, 1219,-1744, + 2579,-4192, 9596,28605,-4916, 2264, +-1199, 629, -292, 175, 704, -58, + -23, 115, 996, -844, 1190,-1692, + 2485,-4008, 9034,28907,-4703, 2135, +-1113, 569, -250, 141, 720, -57, + -22, 105, 1000, -827, 1160,-1637, + 2389,-3820, 8477,29194,-4476, 2000, +-1023, 507, -206, 106, 736, -56, + -21, 95, 1002, -809, 1128,-1580, + 2289,-3629, 7924,29464,-4236, 1860, + -931, 444, -162, 71, 752, -54, + -20, 85, 1003, -790, 1094,-1522, + 2187,-3434, 7376,29718,-3982, 1714, + -836, 379, -118, 36, 768, -53, + -18, 76, 1003, -770, 1059,-1461, + 2082,-3237, 6834,29955,-3715, 1563, + -738, 313, -72, 0, 783, -51, + -17, 67, 1003, -748, 1022,-1398, + 1975,-3037, 6299,30174,-3434, 1406, + -638, 246, -26, -35, 798, -49, + -16, 59, 1002, -726, 984,-1334, + 1865,-2836, 5769,30376,-3140, 1245, + -535, 177, 21, -71, 813, -47, + -15, 51, 1000, -702, 945,-1268, + 1754,-2633, 5247,30561,-2833, 1079, + -430, 107, 68, -106, 827, -45, + -14, 43, 997, -677, 904,-1201, + 1642,-2428, 4732,30727,-2512, 908, + -323, 37, 115, -141, 841, -43, + -13, 35, 993, -651, 863,-1132, + 1527,-2223, 4225,30876,-2179, 734, + -214, -35, 163, -176, 855, -40, + -12, 28, 988, -624, 820,-1062, + 1412,-2017, 3727,31006,-1833, 555, + -104, -107, 211, -211, 868, -37, + -11, 21, 983, -596, 776, -991, + 1296,-1811, 3237,31118,-1474, 372, + 9, -180, 259, -246, 881, -33, + -10, 15, 977, -568, 732, -919, + 1178,-1605, 2756,31211,-1102, 186, + 122, -254, 308, -280, 893, -30, + -10, 9, 970, -538, 687, -847, + 1060,-1399, 2285,31286, -719, -4, + 237, -328, 356, -314, 904, -26, + -9, 3, 963, -508, 641, -773, + 942,-1195, 1824,31342, -324, -197, + 353, -402, 404, -348, 916, -22, + -8, -3, 954, -477, 594, -700, + 824, -992, 1373,31380, 84, -392, + 470, -477, 452, -381, 926, -18, + -41, -8, 946, -446, 547, -626, + 706, -790, 932,31399, 502, -590, + 588, -551, 500, -414, 936, -13, + diff --git a/services/multimedia/audio/process/resample/coef/resample_8p4k_to_8k_filter.txt b/services/multimedia/audio/process/resample/coef/resample_8p4k_to_8k_filter.txt new file mode 100644 index 0000000..81d4436 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_8p4k_to_8k_filter.txt @@ -0,0 +1,189 @@ +//#define UPSAMPLE_FACTOR_8P4TO8 69 +//#define DOWNSAMPLE_FACTOR_8P4TO8 73 +//#define FIRFILTER_NUM_MONO_8P4TO8 16 + + 83, -774, 602, -839, 991,-1098, + 1072,30795, 1520,-1297, 1100, -900, + 635, -784, 80, 39, 86, -764, + 568, -778, 881, -899, 635,30775, + 1980,-1498, 1208, -959, 668, -793, + 77, 9, 89, -752, 533, -716, + 772, -703, 210,30735, 2450,-1700, + 1316,-1018, 700, -802, 73, 10, + 91, -741, 497, -654, 663, -508, + -203,30675, 2930,-1902, 1424,-1076, + 731, -810, 69, 11, 93, -728, + 461, -591, 554, -317, -604,30596, + 3421,-2105, 1530,-1133, 760, -817, + 64, 12, 95, -715, 425, -529, + 446, -128, -992,30496, 3921,-2306, + 1634,-1188, 789, -823, 59, 13, + 96, -702, 388, -466, 338, 58, +-1367,30377, 4431,-2508, 1738,-1242, + 816, -828, 54, 14, 97, -688, + 350, -403, 232, 241,-1729,30239, + 4949,-2708, 1839,-1295, 843, -833, + 48, 15, 98, -674, 313, -341, + 126, 420,-2077,30081, 5475,-2907, + 1939,-1346, 868, -836, 42, 16, + 99, -659, 275, -279, 22, 595, +-2412,29904, 6009,-3103, 2036,-1395, + 891, -839, 36, 18, 99, -644, + 237, -217, -80, 765,-2733,29709, + 6550,-3298, 2131,-1442, 913, -841, + 29, 19, 99, -628, 199, -156, + -181, 932,-3041,29494, 7098,-3490, + 2223,-1487, 934, -841, 22, 21, + 100, -613, 161, -96, -280, 1094, +-3334,29262, 7653,-3679, 2313,-1530, + 953, -841, 15, 22, 99, -597, + 123, -36, -377, 1250,-3613,29011, + 8213,-3864, 2399,-1571, 971, -840, + 7, 24, 99, -580, 85, 23, + -471, 1402,-3878,28742, 8778,-4045, + 2482,-1609, 987, -838, -1, 25, + 98, -564, 48, 81, -564, 1549, +-4129,28456, 9348,-4222, 2562,-1645, + 1001, -835, -10, 27, 98, -547, + 10, 138, -654, 1690,-4365,28153, + 9921,-4395, 2638,-1678, 1013, -830, + -19, 29, 97, -530, -27, 194, + -741, 1825,-4587,27832,10498,-4562, + 2710,-1709, 1024, -825, -28, 30, + 96, -513, -64, 248, -826, 1955, +-4795,27496,11079,-4723, 2778,-1737, + 1033, -819, -38, 32, 95, -496, + -100, 302, -908, 2078,-4988,27143, +11661,-4879, 2841,-1761, 1040, -811, + -48, 34, 93, -479, -136, 353, + -987, 2196,-5167,26775,12245,-5028, + 2900,-1783, 1045, -803, -59, 36, + 92, -462, -171, 404,-1062, 2307, +-5332,26391,12830,-5170, 2955,-1802, + 1048, -793, -70, 38, 90, -445, + -206, 453,-1135, 2412,-5482,25993, +13415,-5306, 3004,-1818, 1049, -782, + -81, 40, 89, -427, -240, 500, +-1205, 2511,-5619,25581,14001,-5433, + 3049,-1831, 1048, -770, -93, 42, + 87, -410, -274, 546,-1271, 2604, +-5741,25155,14585,-5553, 3088,-1840, + 1045, -757, -105, 44, 85, -393, + -307, 590,-1334, 2689,-5850,24715, +15169,-5664, 3122,-1846, 1040, -743, + -118, 46, 83, -376, -339, 632, +-1393, 2769,-5944,24263,15750,-5767, + 3151,-1848, 1033, -728, -131, 49, + 81, -359, -370, 672,-1449, 2841, +-6025,23798,16328,-5860, 3173,-1847, + 1024, -711, -144, 51, 79, -342, + -401, 710,-1501, 2907,-6093,23322, +16903,-5944, 3190,-1842, 1012, -694, + -157, 53, 77, -326, -431, 747, +-1550, 2967,-6148,22835,17475,-6018, + 3202,-1834, 999, -675, -171, 55, + 75, -309, -460, 781,-1595, 3020, +-6189,22337,18041,-6082, 3207,-1822, + 983, -655, -185, 57, 73, -293, + -487, 814,-1636, 3066,-6218,21829, +18603,-6136, 3206,-1807, 965, -634, + -200, 60, 71, -277, -514, 844, +-1674, 3105,-6234,21311,19159,-6178, + 3198,-1788, 945, -612, -215, 62, + 69, -261, -540, 873,-1708, 3138, +-6238,20785,19708,-6210, 3185,-1765, + 923, -589, -230, 64, 66, -245, + -565, 899,-1738, 3165,-6230,20250, +20250,-6230, 3165,-1738, 899, -565, + -245, 66, 64, -230, -589, 923, +-1765, 3185,-6210,19708,20785,-6238, + 3138,-1708, 873, -540, -261, 69, + 62, -215, -612, 945,-1788, 3198, +-6178,19159,21311,-6234, 3105,-1674, + 844, -514, -277, 71, 60, -200, + -634, 965,-1807, 3206,-6136,18603, +21829,-6218, 3066,-1636, 814, -487, + -293, 73, 57, -185, -655, 983, +-1822, 3207,-6082,18041,22337,-6189, + 3020,-1595, 781, -460, -309, 75, + 55, -171, -675, 999,-1834, 3202, +-6018,17475,22835,-6148, 2967,-1550, + 747, -431, -326, 77, 53, -157, + -694, 1012,-1842, 3190,-5944,16903, +23322,-6093, 2907,-1501, 710, -401, + -342, 79, 51, -144, -711, 1024, +-1847, 3173,-5860,16328,23798,-6025, + 2841,-1449, 672, -370, -359, 81, + 49, -131, -728, 1033,-1848, 3151, +-5767,15750,24263,-5944, 2769,-1393, + 632, -339, -376, 83, 46, -118, + -743, 1040,-1846, 3122,-5664,15169, +24715,-5850, 2689,-1334, 590, -307, + -393, 85, 44, -105, -757, 1045, +-1840, 3088,-5553,14585,25155,-5741, + 2604,-1271, 546, -274, -410, 87, + 42, -93, -770, 1048,-1831, 3049, +-5433,14001,25581,-5619, 2511,-1205, + 500, -240, -427, 89, 40, -81, + -782, 1049,-1818, 3004,-5306,13415, +25993,-5482, 2412,-1135, 453, -206, + -445, 90, 38, -70, -793, 1048, +-1802, 2955,-5170,12830,26391,-5332, + 2307,-1062, 404, -171, -462, 92, + 36, -59, -803, 1045,-1783, 2900, +-5028,12245,26775,-5167, 2196, -987, + 353, -136, -479, 93, 34, -48, + -811, 1040,-1761, 2841,-4879,11661, +27143,-4988, 2078, -908, 302, -100, + -496, 95, 32, -38, -819, 1033, +-1737, 2778,-4723,11079,27496,-4795, + 1955, -826, 248, -64, -513, 96, + 30, -28, -825, 1024,-1709, 2710, +-4562,10498,27832,-4587, 1825, -741, + 194, -27, -530, 97, 29, -19, + -830, 1013,-1678, 2638,-4395, 9921, +28153,-4365, 1690, -654, 138, 10, + -547, 98, 27, -10, -835, 1001, +-1645, 2562,-4222, 9348,28456,-4129, + 1549, -564, 81, 48, -564, 98, + 25, -1, -838, 987,-1609, 2482, +-4045, 8778,28742,-3878, 1402, -471, + 23, 85, -580, 99, 24, 7, + -840, 971,-1571, 2399,-3864, 8213, +29011,-3613, 1250, -377, -36, 123, + -597, 99, 22, 15, -841, 953, +-1530, 2313,-3679, 7653,29262,-3334, + 1094, -280, -96, 161, -613, 100, + 21, 22, -841, 934,-1487, 2223, +-3490, 7098,29494,-3041, 932, -181, + -156, 199, -628, 99, 19, 29, + -841, 913,-1442, 2131,-3298, 6550, +29709,-2733, 765, -80, -217, 237, + -644, 99, 18, 36, -839, 891, +-1395, 2036,-3103, 6009,29904,-2412, + 595, 22, -279, 275, -659, 99, + 16, 42, -836, 868,-1346, 1939, +-2907, 5475,30081,-2077, 420, 126, + -341, 313, -674, 98, 15, 48, + -833, 843,-1295, 1839,-2708, 4949, +30239,-1729, 241, 232, -403, 350, + -688, 97, 14, 54, -828, 816, +-1242, 1738,-2508, 4431,30377,-1367, + 58, 338, -466, 388, -702, 96, + 13, 59, -823, 789,-1188, 1634, +-2306, 3921,30496, -992, -128, 446, + -529, 425, -715, 95, 12, 64, + -817, 760,-1133, 1530,-2105, 3421, +30596, -604, -317, 554, -591, 461, + -728, 93, 11, 69, -810, 731, +-1076, 1424,-1902, 2930,30675, -203, + -508, 663, -654, 497, -741, 91, + 10, 73, -802, 700,-1018, 1316, +-1700, 2450,30735, 210, -703, 772, + -716, 533, -752, 89, 9, 77, + -793, 668, -959, 1208,-1498, 1980, +30775, 635, -899, 881, -778, 568, + -764, 86, 39, 80, -784, 635, + -900, 1100,-1297, 1520,30795, 1072, +-1098, 991, -839, 602, -774, 83, + diff --git a/services/multimedia/audio/process/resample/coef/resample_any_up256_filter.txt b/services/multimedia/audio/process/resample/coef/resample_any_up256_filter.txt new file mode 100644 index 0000000..dfb5844 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_any_up256_filter.txt @@ -0,0 +1,257 @@ +//single phase coef Number:=24, upsample factor:=256, + -23, 45, -102, 210, -386, 645, -982, 1374,-1777, 2135,-2405,32741,-2294, 2089,-1755, 1365, -979, 645, -388, 211, -103, 45, -23, 39, + -23, 44, -101, 208, -385, 644, -984, 1383,-1798, 2181,-2515,32739,-2181, 2043,-1733, 1355, -976, 645, -389, 212, -104, 46, -23, 1, + -22, 44, -100, 207, -384, 644, -987, 1392,-1819, 2225,-2624,32735,-2067, 1996,-1711, 1345, -973, 645, -390, 213, -105, 46, -23, 1, + -22, 43, -99, 205, -382, 643, -989, 1400,-1840, 2270,-2731,32729,-1952, 1948,-1688, 1335, -969, 645, -391, 215, -106, 47, -24, 1, + -22, 43, -98, 204, -380, 643, -991, 1408,-1860, 2313,-2837,32721,-1835, 1900,-1664, 1324, -966, 645, -392, 216, -107, 47, -24, 1, + -22, 42, -97, 202, -379, 642, -993, 1416,-1880, 2356,-2941,32711,-1717, 1851,-1641, 1314, -962, 645, -393, 217, -108, 48, -24, 1, + -22, 41, -96, 201, -377, 641, -995, 1424,-1899, 2398,-3045,32700,-1598, 1802,-1617, 1303, -958, 644, -394, 218, -108, 48, -24, 1, + -22, 41, -95, 199, -375, 640, -996, 1432,-1918, 2440,-3147,32686,-1478, 1752,-1592, 1291, -954, 644, -395, 219, -109, 49, -24, 1, + -21, 40, -94, 198, -373, 638, -998, 1439,-1936, 2481,-3247,32671,-1356, 1701,-1567, 1280, -950, 643, -396, 220, -110, 49, -24, 1, + -21, 40, -93, 196, -372, 637, -999, 1446,-1954, 2522,-3346,32653,-1233, 1650,-1542, 1268, -945, 642, -397, 221, -111, 49, -25, 1, + -21, 39, -92, 195, -370, 636,-1000, 1452,-1972, 2562,-3444,32634,-1109, 1598,-1517, 1256, -941, 642, -397, 222, -112, 50, -25, 1, + -21, 39, -91, 193, -368, 634,-1001, 1458,-1989, 2601,-3540,32613, -983, 1546,-1491, 1244, -936, 641, -398, 223, -112, 50, -25, 1, + -21, 38, -90, 191, -366, 633,-1001, 1464,-2006, 2639,-3635,32589, -857, 1494,-1464, 1231, -931, 639, -399, 224, -113, 51, -25, 1, + -20, 38, -89, 190, -364, 631,-1002, 1470,-2023, 2677,-3729,32564, -729, 1441,-1438, 1218, -926, 638, -399, 225, -114, 51, -25, 1, + -20, 37, -88, 188, -361, 629,-1002, 1476,-2039, 2714,-3821,32537, -599, 1387,-1411, 1205, -920, 637, -400, 226, -115, 52, -25, 1, + -20, 37, -87, 186, -359, 627,-1002, 1481,-2054, 2751,-3912,32508, -469, 1333,-1383, 1192, -915, 635, -400, 227, -115, 52, -25, 1, + -20, 36, -86, 184, -357, 625,-1002, 1486,-2069, 2787,-4001,32477, -337, 1278,-1356, 1178, -909, 634, -400, 228, -116, 53, -26, 1, + -20, 35, -85, 183, -355, 623,-1002, 1490,-2084, 2822,-4089,32444, -204, 1223,-1328, 1164, -903, 632, -400, 229, -117, 53, -26, 1, + -19, 35, -84, 181, -352, 621,-1001, 1494,-2098, 2857,-4176,32409, -70, 1167,-1299, 1150, -897, 630, -401, 229, -117, 53, -26, 1, + -19, 34, -82, 179, -350, 619,-1001, 1499,-2112, 2891,-4261,32373, 65, 1111,-1270, 1136, -891, 628, -401, 230, -118, 54, -26, 1, + -19, 34, -81, 177, -347, 616,-1000, 1502,-2126, 2924,-4345,32334, 202, 1055,-1241, 1121, -884, 626, -401, 231, -119, 54, -26, 1, + -19, 33, -80, 175, -345, 614, -999, 1506,-2139, 2957,-4427,32294, 340, 998,-1212, 1106, -878, 624, -400, 231, -119, 55, -26, 1, + -19, 33, -79, 173, -342, 611, -998, 1509,-2151, 2989,-4508,32251, 478, 940,-1182, 1091, -871, 622, -400, 232, -120, 55, -26, 1, + -19, 32, -78, 171, -340, 608, -996, 1512,-2163, 3020,-4588,32207, 618, 882,-1152, 1075, -864, 620, -400, 232, -121, 55, -27, 1, + -18, 31, -77, 169, -337, 606, -995, 1515,-2175, 3051,-4666,32161, 760, 824,-1122, 1060, -857, 617, -400, 233, -121, 56, -27, 2, + -18, 31, -76, 168, -334, 603, -993, 1517,-2187, 3080,-4743,32113, 902, 765,-1091, 1044, -849, 614, -399, 233, -122, 56, -27, 2, + -18, 30, -74, 166, -331, 600, -991, 1519,-2197, 3110,-4818,32063, 1045, 706,-1060, 1028, -842, 612, -399, 234, -122, 56, -27, 2, + -18, 30, -73, 164, -329, 597, -989, 1521,-2208, 3138,-4892,32011, 1190, 646,-1029, 1011, -834, 609, -399, 234, -123, 57, -27, 2, + -18, 29, -72, 162, -326, 593, -987, 1522,-2218, 3166,-4965,31958, 1335, 586, -997, 995, -826, 606, -398, 234, -123, 57, -27, 2, + -17, 28, -71, 159, -323, 590, -985, 1524,-2228, 3193,-5036,31902, 1482, 526, -965, 978, -818, 603, -397, 235, -124, 57, -27, 2, + -17, 28, -70, 157, -320, 587, -982, 1525,-2237, 3220,-5106,31845, 1630, 465, -933, 961, -810, 599, -397, 235, -124, 58, -27, 2, + -17, 27, -68, 155, -317, 583, -980, 1525,-2245, 3246,-5174,31786, 1779, 404, -901, 943, -801, 596, -396, 235, -125, 58, -28, 2, + -17, 27, -67, 153, -314, 580, -977, 1526,-2254, 3271,-5241,31725, 1929, 342, -868, 926, -793, 593, -395, 235, -125, 58, -28, 2, + -17, 26, -66, 151, -311, 576, -974, 1526,-2262, 3295,-5306,31662, 2080, 280, -835, 908, -784, 589, -394, 236, -125, 59, -28, 2, + -16, 26, -65, 149, -308, 572, -971, 1526,-2269, 3319,-5370,31597, 2232, 218, -801, 890, -775, 585, -393, 236, -126, 59, -28, 2, + -16, 25, -64, 147, -305, 568, -967, 1525,-2276, 3342,-5433,31531, 2385, 155, -768, 872, -766, 581, -392, 236, -126, 59, -28, 2, + -16, 24, -62, 145, -301, 565, -964, 1525,-2283, 3364,-5494,31463, 2539, 92, -734, 853, -757, 577, -391, 236, -126, 59, -28, 2, + -16, 24, -61, 143, -298, 561, -960, 1524,-2289, 3386,-5554,31393, 2694, 29, -700, 835, -747, 573, -389, 236, -127, 60, -28, 2, + -16, 23, -60, 140, -295, 556, -957, 1523,-2295, 3407,-5612,31321, 2850, -35, -666, 816, -738, 569, -388, 236, -127, 60, -28, 2, + -15, 23, -59, 138, -291, 552, -953, 1521,-2300, 3427,-5669,31247, 3007, -98, -631, 797, -728, 565, -387, 236, -127, 60, -28, 2, + -15, 22, -57, 136, -288, 548, -949, 1520,-2305, 3447,-5724,31172, 3165, -163, -596, 777, -718, 560, -385, 235, -127, 61, -28, 2, + -15, 21, -56, 134, -285, 544, -944, 1518,-2309, 3465,-5778,31094, 3324, -227, -561, 758, -708, 556, -384, 235, -128, 61, -29, 2, + -15, 21, -55, 131, -281, 539, -940, 1515,-2313, 3484,-5831,31015, 3484, -292, -526, 738, -698, 551, -382, 235, -128, 61, -29, 2, + -15, 20, -54, 129, -278, 535, -935, 1513,-2317, 3501,-5882,30935, 3645, -357, -490, 718, -687, 547, -380, 235, -128, 61, -29, 2, + -14, 20, -52, 127, -274, 530, -931, 1510,-2320, 3518,-5932,30852, 3807, -422, -454, 698, -677, 542, -379, 234, -128, 61, -29, 2, + -14, 19, -51, 125, -271, 526, -926, 1507,-2323, 3534,-5981,30768, 3970, -488, -418, 678, -666, 537, -377, 234, -128, 62, -29, 2, + -14, 18, -50, 122, -267, 521, -921, 1504,-2325, 3549,-6028,30682, 4133, -554, -382, 657, -655, 532, -375, 234, -129, 62, -29, 2, + -14, 18, -49, 120, -264, 516, -916, 1500,-2327, 3564,-6073,30594, 4298, -620, -345, 637, -644, 526, -373, 233, -129, 62, -29, 2, + -14, 17, -47, 118, -260, 511, -910, 1497,-2328, 3578,-6118,30505, 4463, -686, -309, 616, -633, 521, -371, 233, -129, 62, -29, 2, + -14, 17, -46, 115, -256, 506, -905, 1493,-2329, 3591,-6161,30414, 4630, -752, -272, 595, -621, 516, -369, 232, -129, 62, -29, 2, + -13, 16, -45, 113, -253, 501, -899, 1488,-2330, 3604,-6202,30321, 4797, -819, -235, 574, -610, 510, -367, 232, -129, 62, -29, 2, + -13, 16, -44, 111, -249, 496, -894, 1484,-2330, 3616,-6242,30227, 4964, -886, -198, 552, -598, 504, -364, 231, -129, 63, -29, 2, + -13, 15, -42, 108, -245, 491, -888, 1479,-2330, 3627,-6281,30130, 5133, -953, -160, 531, -586, 499, -362, 230, -129, 63, -29, 2, + -13, 14, -41, 106, -242, 486, -882, 1474,-2330, 3637,-6318,30033, 5303,-1020, -123, 509, -574, 493, -360, 230, -129, 63, -29, 2, + -13, 14, -40, 104, -238, 481, -876, 1469,-2328, 3647,-6354,29933, 5473,-1087, -85, 487, -562, 487, -357, 229, -129, 63, -29, 2, + -12, 13, -38, 101, -234, 476, -870, 1463,-2327, 3656,-6389,29832, 5644,-1155, -47, 465, -550, 481, -354, 228, -129, 63, -29, 2, + -12, 13, -37, 99, -230, 470, -863, 1457,-2325, 3665,-6422,29729, 5816,-1222, -9, 443, -538, 474, -352, 227, -129, 63, -29, 2, + -12, 12, -36, 97, -226, 465, -857, 1451,-2323, 3672,-6454,29625, 5988,-1290, 29, 420, -525, 468, -349, 226, -128, 63, -30, 2, + -12, 11, -35, 94, -222, 459, -850, 1445,-2320, 3679,-6484,29519, 6162,-1358, 68, 398, -512, 462, -346, 225, -128, 63, -30, 2, + -12, 11, -33, 92, -218, 454, -843, 1439,-2317, 3686,-6513,29412, 6336,-1426, 106, 375, -500, 455, -343, 224, -128, 63, -30, 2, + -11, 10, -32, 90, -215, 448, -836, 1432,-2314, 3691,-6541,29302, 6510,-1494, 145, 352, -487, 448, -340, 223, -128, 63, -30, 2, + -11, 10, -31, 87, -211, 442, -829, 1425,-2310, 3696,-6567,29192, 6686,-1562, 183, 329, -474, 442, -337, 222, -128, 63, -30, 1, + -11, 9, -30, 85, -207, 437, -822, 1418,-2306, 3701,-6593,29080, 6862,-1631, 222, 306, -460, 435, -334, 221, -127, 63, -30, 1, + -11, 9, -28, 82, -203, 431, -815, 1411,-2301, 3704,-6616,28966, 7038,-1699, 261, 283, -447, 428, -331, 220, -127, 63, -30, 1, + -11, 8, -27, 80, -199, 425, -808, 1403,-2296, 3707,-6639,28850, 7216,-1767, 300, 259, -434, 421, -328, 219, -127, 63, -30, 1, + -11, 7, -26, 78, -195, 419, -800, 1395,-2291, 3710,-6660,28734, 7394,-1835, 340, 236, -420, 414, -325, 218, -127, 63, -30, 1, + -10, 7, -25, 75, -191, 413, -793, 1387,-2285, 3711,-6680,28615, 7572,-1904, 379, 212, -406, 406, -321, 216, -126, 63, -30, 1, + -10, 6, -23, 73, -186, 407, -785, 1379,-2279, 3712,-6698,28495, 7751,-1972, 418, 188, -393, 399, -318, 215, -126, 63, -30, 1, + -10, 6, -22, 70, -182, 401, -777, 1370,-2272, 3713,-6715,28374, 7931,-2041, 458, 164, -379, 392, -314, 214, -126, 63, -30, 1, + -10, 5, -21, 68, -178, 395, -769, 1362,-2265, 3712,-6731,28251, 8111,-2109, 497, 140, -365, 384, -311, 212, -125, 63, -30, 1, + -10, 5, -20, 66, -174, 389, -761, 1353,-2258, 3711,-6746,28127, 8292,-2177, 537, 116, -350, 376, -307, 211, -125, 63, -30, 1, + -10, 4, -19, 63, -170, 383, -753, 1344,-2250, 3710,-6759,28001, 8473,-2246, 576, 92, -336, 369, -303, 209, -124, 63, -30, 1, + -9, 4, -17, 61, -166, 376, -745, 1335,-2242, 3707,-6771,27874, 8655,-2314, 616, 67, -322, 361, -300, 208, -124, 63, -30, 1, + -9, 3, -16, 58, -162, 370, -736, 1325,-2234, 3704,-6781,27746, 8838,-2382, 656, 43, -307, 353, -296, 206, -123, 63, -29, 1, + -9, 3, -15, 56, -158, 364, -728, 1315,-2225, 3701,-6791,27616, 9020,-2450, 696, 19, -293, 345, -292, 205, -123, 63, -29, 1, + -9, 2, -14, 53, -154, 357, -719, 1305,-2216, 3697,-6799,27484, 9204,-2518, 735, -6, -278, 337, -288, 203, -122, 63, -29, 1, + -9, 1, -12, 51, -149, 351, -711, 1295,-2206, 3692,-6806,27351, 9387,-2586, 775, -31, -263, 329, -284, 201, -122, 63, -29, 1, + -9, 1, -11, 49, -145, 345, -702, 1285,-2197, 3686,-6811,27217, 9572,-2654, 815, -56, -248, 320, -280, 200, -121, 62, -29, 1, + -8, 0, -10, 46, -141, 338, -693, 1274,-2186, 3680,-6816,27082, 9756,-2722, 855, -81, -233, 312, -276, 198, -120, 62, -29, 1, + -8, 0, -9, 44, -137, 332, -684, 1264,-2176, 3673,-6819,26945, 9941,-2790, 895, -105, -218, 303, -271, 196, -120, 62, -29, 1, + -8, -1, -8, 42, -133, 325, -675, 1253,-2165, 3666,-6821,26807,10126,-2857, 935, -130, -203, 295, -267, 194, -119, 62, -29, 1, + -8, -1, -7, 39, -128, 319, -666, 1242,-2154, 3658,-6822,26668,10312,-2925, 974, -156, -188, 286, -263, 192, -118, 62, -29, 1, + -8, -2, -5, 37, -124, 312, -657, 1231,-2142, 3649,-6821,26527,10498,-2992, 1014, -181, -172, 277, -258, 190, -118, 61, -29, 1, + -8, -2, -4, 34, -120, 305, -648, 1219,-2130, 3640,-6819,26385,10685,-3059, 1054, -206, -157, 269, -254, 188, -117, 61, -29, 1, + -7, -3, -3, 32, -116, 299, -638, 1208,-2118, 3630,-6816,26242,10871,-3126, 1094, -231, -141, 260, -249, 186, -116, 61, -29, 1, + -7, -3, -2, 30, -112, 292, -629, 1196,-2105, 3620,-6812,26097,11058,-3192, 1134, -256, -126, 251, -244, 184, -115, 61, -29, 1, + -7, -4, -1, 27, -107, 285, -619, 1184,-2092, 3609,-6807,25951,11245,-3259, 1173, -282, -110, 242, -240, 182, -114, 61, -29, 1, + -7, -4, 0, 25, -103, 279, -610, 1172,-2079, 3597,-6801,25804,11433,-3325, 1213, -307, -94, 233, -235, 180, -114, 60, -29, 1, + -7, -5, 2, 23, -99, 272, -600, 1160,-2065, 3585,-6793,25656,11621,-3391, 1253, -333, -78, 223, -230, 177, -113, 60, -28, 1, + -7, -5, 3, 20, -95, 265, -591, 1147,-2051, 3572,-6784,25507,11809,-3456, 1292, -358, -62, 214, -225, 175, -112, 60, -28, 1, + -6, -6, 4, 18, -91, 258, -581, 1135,-2037, 3558,-6774,25356,11997,-3522, 1332, -384, -47, 205, -220, 173, -111, 59, -28, 1, + -6, -6, 5, 16, -86, 252, -571, 1122,-2023, 3544,-6763,25205,12185,-3587, 1371, -409, -30, 195, -215, 170, -110, 59, -28, 1, + -6, -7, 6, 13, -82, 245, -561, 1109,-2008, 3530,-6751,25052,12374,-3652, 1410, -435, -14, 186, -210, 168, -109, 59, -28, 1, + -6, -7, 7, 11, -78, 238, -551, 1096,-1993, 3515,-6738,24898,12562,-3716, 1449, -460, 2, 176, -205, 166, -108, 58, -28, 1, + -6, -7, 8, 9, -74, 231, -541, 1083,-1977, 3499,-6723,24743,12751,-3781, 1488, -486, 18, 167, -200, 163, -107, 58, -28, 1, + -6, -8, 9, 7, -70, 224, -531, 1069,-1962, 3483,-6708,24587,12940,-3844, 1527, -511, 34, 157, -195, 161, -106, 58, -28, 0, + -6, -8, 10, 4, -65, 217, -521, 1056,-1946, 3466,-6691,24430,13129,-3908, 1566, -537, 51, 147, -189, 158, -105, 57, -27, 0, + -5, -9, 11, 2, -61, 210, -510, 1042,-1929, 3449,-6673,24272,13318,-3971, 1605, -562, 67, 138, -184, 155, -104, 57, -27, 0, + -5, -9, 12, 0, -57, 203, -500, 1029,-1913, 3431,-6654,24112,13507,-4034, 1644, -588, 83, 128, -179, 153, -103, 57, -27, 0, + -5, -10, 14, -2, -53, 197, -490, 1015,-1896, 3413,-6635,23952,13696,-4097, 1682, -613, 100, 118, -173, 150, -102, 56, -27, 0, + -5, -10, 15, -5, -49, 190, -480, 1001,-1879, 3394,-6614,23791,13885,-4159, 1720, -639, 116, 108, -168, 147, -100, 56, -27, 0, + -5, -11, 16, -7, -45, 183, -469, 986,-1861, 3374,-6592,23628,14075,-4220, 1759, -664, 133, 98, -162, 145, -99, 55, -27, 0, + -5, -11, 17, -9, -40, 176, -459, 972,-1844, 3354,-6569,23465,14264,-4282, 1797, -690, 150, 88, -156, 142, -98, 55, -27, 0, + -5, -11, 18, -11, -36, 169, -448, 958,-1826, 3334,-6545,23301,14453,-4342, 1834, -715, 166, 77, -151, 139, -97, 54, -26, 0, + -5, -12, 19, -13, -32, 162, -438, 943,-1807, 3313,-6520,23136,14642,-4403, 1872, -741, 183, 67, -145, 136, -96, 54, -26, 0, + -4, -12, 20, -15, -28, 155, -427, 929,-1789, 3291,-6494,22970,14831,-4463, 1909, -766, 199, 57, -139, 133, -94, 53, -26, 0, + -4, -13, 21, -18, -24, 148, -416, 914,-1770, 3269,-6467,22803,15020,-4522, 1947, -791, 216, 47, -134, 130, -93, 53, -26, 0, + -4, -13, 22, -20, -20, 141, -406, 899,-1751, 3247,-6439,22635,15209,-4581, 1984, -817, 233, 36, -128, 127, -92, 52, -26, 0, + -4, -14, 23, -22, -16, 134, -395, 884,-1732, 3224,-6410,22466,15398,-4640, 2021, -842, 250, 26, -122, 124, -90, 52, -25, 0, + -4, -14, 24, -24, -12, 127, -384, 869,-1713, 3201,-6380,22297,15586,-4698, 2057, -867, 266, 16, -116, 121, -89, 51, -25, 0, + -4, -14, 24, -26, -8, 120, -374, 854,-1693, 3177,-6349,22126,15775,-4755, 2094, -892, 283, 5, -110, 118, -88, 51, -25, 0, + -4, -15, 25, -28, -4, 113, -363, 839,-1673, 3152,-6317,21955,15963,-4812, 2130, -917, 300, -5, -104, 115, -86, 50, -25, -1, + -4, -15, 26, -30, 0, 106, -352, 823,-1653, 3127,-6284,21783,16151,-4869, 2166, -942, 317, -16, -98, 112, -85, 50, -25, -1, + -3, -15, 27, -32, 4, 100, -341, 808,-1633, 3102,-6250,21610,16339,-4925, 2202, -967, 333, -27, -92, 109, -83, 49, -24, -1, + -3, -16, 28, -34, 8, 93, -330, 792,-1612, 3076,-6216,21436,16527,-4980, 2237, -992, 350, -37, -85, 106, -82, 49, -24, -1, + -3, -16, 29, -36, 12, 86, -320, 777,-1591, 3050,-6180,21262,16714,-5035, 2273,-1016, 367, -48, -79, 102, -80, 48, -24, -1, + -3, -17, 30, -38, 16, 79, -309, 761,-1570, 3024,-6144,21087,16901,-5089, 2308,-1041, 384, -59, -73, 99, -79, 47, -24, -1, + -3, -17, 31, -40, 20, 72, -298, 745,-1549, 2997,-6107,20911,17088,-5143, 2342,-1065, 401, -69, -67, 96, -77, 47, -23, -1, + -3, -17, 32, -42, 24, 65, -287, 729,-1528, 2969,-6069,20735,17274,-5195, 2377,-1090, 417, -80, -60, 93, -76, 46, -23, -1, + -3, -18, 33, -44, 28, 58, -276, 713,-1506, 2941,-6030,20558,17461,-5248, 2411,-1114, 434, -91, -54, 89, -74, 45, -23, -1, + -3, -18, 33, -46, 31, 52, -265, 697,-1484, 2913,-5990,20380,17646,-5299, 2445,-1138, 451, -102, -48, 86, -73, 45, -23, -1, + -3, -18, 34, -48, 35, 45, -254, 681,-1462, 2884,-5949,20201,17832,-5350, 2478,-1162, 467, -112, -41, 82, -71, 44, -22, -1, + -2, -19, 35, -50, 39, 38, -243, 665,-1440, 2855,-5908,20022,18017,-5401, 2512,-1186, 484, -123, -35, 79, -69, 43, -22, -1, + -2, -19, 36, -52, 43, 31, -232, 649,-1418, 2826,-5865,19843,18202,-5451, 2545,-1210, 501, -134, -28, 75, -68, 43, -22, -1, + -2, -19, 37, -54, 46, 25, -221, 633,-1396, 2796,-5822,19662,18386,-5500, 2577,-1234, 517, -145, -22, 72, -66, 42, -21, -2, + -2, -20, 37, -55, 50, 18, -210, 616,-1373, 2766,-5778,19482,18570,-5548, 2610,-1257, 534, -156, -15, 68, -64, 41, -21, -2, + -2, -20, 38, -57, 54, 11, -199, 600,-1350, 2735,-5734,19300,18753,-5595, 2641,-1281, 550, -167, -9, 65, -62, 41, -21, -2, + -2, -20, 39, -59, 58, 5, -189, 583,-1327, 2704,-5688,19118,18936,-5642, 2673,-1304, 567, -178, -2, 61, -61, 40, -21, -2, + -2, -21, 40, -61, 61, -2, -178, 567,-1304, 2673,-5642,18936,19118,-5688, 2704,-1327, 583, -189, 5, 58, -59, 39, -20, -2, + -2, -21, 41, -62, 65, -9, -167, 550,-1281, 2641,-5595,18753,19300,-5734, 2735,-1350, 600, -199, 11, 54, -57, 38, -20, -2, + -2, -21, 41, -64, 68, -15, -156, 534,-1257, 2610,-5548,18570,19482,-5778, 2766,-1373, 616, -210, 18, 50, -55, 37, -20, -2, + -2, -21, 42, -66, 72, -22, -145, 517,-1234, 2577,-5500,18386,19662,-5822, 2796,-1396, 633, -221, 25, 46, -54, 37, -19, -2, + -1, -22, 43, -68, 75, -28, -134, 501,-1210, 2545,-5451,18202,19843,-5865, 2826,-1418, 649, -232, 31, 43, -52, 36, -19, -2, + -1, -22, 43, -69, 79, -35, -123, 484,-1186, 2512,-5401,18017,20022,-5908, 2855,-1440, 665, -243, 38, 39, -50, 35, -19, -2, + -1, -22, 44, -71, 82, -41, -112, 467,-1162, 2478,-5350,17832,20201,-5949, 2884,-1462, 681, -254, 45, 35, -48, 34, -18, -3, + -1, -23, 45, -73, 86, -48, -102, 451,-1138, 2445,-5299,17646,20380,-5990, 2913,-1484, 697, -265, 52, 31, -46, 33, -18, -3, + -1, -23, 45, -74, 89, -54, -91, 434,-1114, 2411,-5248,17461,20558,-6030, 2941,-1506, 713, -276, 58, 28, -44, 33, -18, -3, + -1, -23, 46, -76, 93, -60, -80, 417,-1090, 2377,-5195,17274,20735,-6069, 2969,-1528, 729, -287, 65, 24, -42, 32, -17, -3, + -1, -23, 47, -77, 96, -67, -69, 401,-1065, 2342,-5143,17088,20911,-6107, 2997,-1549, 745, -298, 72, 20, -40, 31, -17, -3, + -1, -24, 47, -79, 99, -73, -59, 384,-1041, 2308,-5089,16901,21087,-6144, 3024,-1570, 761, -309, 79, 16, -38, 30, -17, -3, + -1, -24, 48, -80, 102, -79, -48, 367,-1016, 2273,-5035,16714,21262,-6180, 3050,-1591, 777, -320, 86, 12, -36, 29, -16, -3, + -1, -24, 49, -82, 106, -85, -37, 350, -992, 2237,-4980,16527,21436,-6216, 3076,-1612, 792, -330, 93, 8, -34, 28, -16, -3, + -1, -24, 49, -83, 109, -92, -27, 333, -967, 2202,-4925,16339,21610,-6250, 3102,-1633, 808, -341, 100, 4, -32, 27, -15, -3, + -1, -25, 50, -85, 112, -98, -16, 317, -942, 2166,-4869,16151,21783,-6284, 3127,-1653, 823, -352, 106, 0, -30, 26, -15, -4, + -1, -25, 50, -86, 115, -104, -5, 300, -917, 2130,-4812,15963,21955,-6317, 3152,-1673, 839, -363, 113, -4, -28, 25, -15, -4, + 0, -25, 51, -88, 118, -110, 5, 283, -892, 2094,-4755,15775,22126,-6349, 3177,-1693, 854, -374, 120, -8, -26, 24, -14, -4, + 0, -25, 51, -89, 121, -116, 16, 266, -867, 2057,-4698,15586,22297,-6380, 3201,-1713, 869, -384, 127, -12, -24, 24, -14, -4, + 0, -25, 52, -90, 124, -122, 26, 250, -842, 2021,-4640,15398,22466,-6410, 3224,-1732, 884, -395, 134, -16, -22, 23, -14, -4, + 0, -26, 52, -92, 127, -128, 36, 233, -817, 1984,-4581,15209,22635,-6439, 3247,-1751, 899, -406, 141, -20, -20, 22, -13, -4, + 0, -26, 53, -93, 130, -134, 47, 216, -791, 1947,-4522,15020,22803,-6467, 3269,-1770, 914, -416, 148, -24, -18, 21, -13, -4, + 0, -26, 53, -94, 133, -139, 57, 199, -766, 1909,-4463,14831,22970,-6494, 3291,-1789, 929, -427, 155, -28, -15, 20, -12, -4, + 0, -26, 54, -96, 136, -145, 67, 183, -741, 1872,-4403,14642,23136,-6520, 3313,-1807, 943, -438, 162, -32, -13, 19, -12, -5, + 0, -26, 54, -97, 139, -151, 77, 166, -715, 1834,-4342,14453,23301,-6545, 3334,-1826, 958, -448, 169, -36, -11, 18, -11, -5, + 0, -27, 55, -98, 142, -156, 88, 150, -690, 1797,-4282,14264,23465,-6569, 3354,-1844, 972, -459, 176, -40, -9, 17, -11, -5, + 0, -27, 55, -99, 145, -162, 98, 133, -664, 1759,-4220,14075,23628,-6592, 3374,-1861, 986, -469, 183, -45, -7, 16, -11, -5, + 0, -27, 56, -100, 147, -168, 108, 116, -639, 1720,-4159,13885,23791,-6614, 3394,-1879, 1001, -480, 190, -49, -5, 15, -10, -5, + 0, -27, 56, -102, 150, -173, 118, 100, -613, 1682,-4097,13696,23952,-6635, 3413,-1896, 1015, -490, 197, -53, -2, 14, -10, -5, + 0, -27, 57, -103, 153, -179, 128, 83, -588, 1644,-4034,13507,24112,-6654, 3431,-1913, 1029, -500, 203, -57, 0, 12, -9, -5, + 0, -27, 57, -104, 155, -184, 138, 67, -562, 1605,-3971,13318,24272,-6673, 3449,-1929, 1042, -510, 210, -61, 2, 11, -9, -5, + 0, -27, 57, -105, 158, -189, 147, 51, -537, 1566,-3908,13129,24430,-6691, 3466,-1946, 1056, -521, 217, -65, 4, 10, -8, -6, + 0, -28, 58, -106, 161, -195, 157, 34, -511, 1527,-3844,12940,24587,-6708, 3483,-1962, 1069, -531, 224, -70, 7, 9, -8, -6, + 1, -28, 58, -107, 163, -200, 167, 18, -486, 1488,-3781,12751,24743,-6723, 3499,-1977, 1083, -541, 231, -74, 9, 8, -7, -6, + 1, -28, 58, -108, 166, -205, 176, 2, -460, 1449,-3716,12562,24898,-6738, 3515,-1993, 1096, -551, 238, -78, 11, 7, -7, -6, + 1, -28, 59, -109, 168, -210, 186, -14, -435, 1410,-3652,12374,25052,-6751, 3530,-2008, 1109, -561, 245, -82, 13, 6, -7, -6, + 1, -28, 59, -110, 170, -215, 195, -30, -409, 1371,-3587,12185,25205,-6763, 3544,-2023, 1122, -571, 252, -86, 16, 5, -6, -6, + 1, -28, 59, -111, 173, -220, 205, -47, -384, 1332,-3522,11997,25356,-6774, 3558,-2037, 1135, -581, 258, -91, 18, 4, -6, -6, + 1, -28, 60, -112, 175, -225, 214, -62, -358, 1292,-3456,11809,25507,-6784, 3572,-2051, 1147, -591, 265, -95, 20, 3, -5, -7, + 1, -28, 60, -113, 177, -230, 223, -78, -333, 1253,-3391,11621,25656,-6793, 3585,-2065, 1160, -600, 272, -99, 23, 2, -5, -7, + 1, -29, 60, -114, 180, -235, 233, -94, -307, 1213,-3325,11433,25804,-6801, 3597,-2079, 1172, -610, 279, -103, 25, 0, -4, -7, + 1, -29, 61, -114, 182, -240, 242, -110, -282, 1173,-3259,11245,25951,-6807, 3609,-2092, 1184, -619, 285, -107, 27, -1, -4, -7, + 1, -29, 61, -115, 184, -244, 251, -126, -256, 1134,-3192,11058,26097,-6812, 3620,-2105, 1196, -629, 292, -112, 30, -2, -3, -7, + 1, -29, 61, -116, 186, -249, 260, -141, -231, 1094,-3126,10871,26242,-6816, 3630,-2118, 1208, -638, 299, -116, 32, -3, -3, -7, + 1, -29, 61, -117, 188, -254, 269, -157, -206, 1054,-3059,10685,26385,-6819, 3640,-2130, 1219, -648, 305, -120, 34, -4, -2, -8, + 1, -29, 61, -118, 190, -258, 277, -172, -181, 1014,-2992,10498,26527,-6821, 3649,-2142, 1231, -657, 312, -124, 37, -5, -2, -8, + 1, -29, 62, -118, 192, -263, 286, -188, -156, 974,-2925,10312,26668,-6822, 3658,-2154, 1242, -666, 319, -128, 39, -7, -1, -8, + 1, -29, 62, -119, 194, -267, 295, -203, -130, 935,-2857,10126,26807,-6821, 3666,-2165, 1253, -675, 325, -133, 42, -8, -1, -8, + 1, -29, 62, -120, 196, -271, 303, -218, -105, 895,-2790, 9941,26945,-6819, 3673,-2176, 1264, -684, 332, -137, 44, -9, 0, -8, + 1, -29, 62, -120, 198, -276, 312, -233, -81, 855,-2722, 9756,27082,-6816, 3680,-2186, 1274, -693, 338, -141, 46, -10, 0, -8, + 1, -29, 62, -121, 200, -280, 320, -248, -56, 815,-2654, 9572,27217,-6811, 3686,-2197, 1285, -702, 345, -145, 49, -11, 1, -9, + 1, -29, 63, -122, 201, -284, 329, -263, -31, 775,-2586, 9387,27351,-6806, 3692,-2206, 1295, -711, 351, -149, 51, -12, 1, -9, + 1, -29, 63, -122, 203, -288, 337, -278, -6, 735,-2518, 9204,27484,-6799, 3697,-2216, 1305, -719, 357, -154, 53, -14, 2, -9, + 1, -29, 63, -123, 205, -292, 345, -293, 19, 696,-2450, 9020,27616,-6791, 3701,-2225, 1315, -728, 364, -158, 56, -15, 3, -9, + 1, -29, 63, -123, 206, -296, 353, -307, 43, 656,-2382, 8838,27746,-6781, 3704,-2234, 1325, -736, 370, -162, 58, -16, 3, -9, + 1, -30, 63, -124, 208, -300, 361, -322, 67, 616,-2314, 8655,27874,-6771, 3707,-2242, 1335, -745, 376, -166, 61, -17, 4, -9, + 1, -30, 63, -124, 209, -303, 369, -336, 92, 576,-2246, 8473,28001,-6759, 3710,-2250, 1344, -753, 383, -170, 63, -19, 4, -10, + 1, -30, 63, -125, 211, -307, 376, -350, 116, 537,-2177, 8292,28127,-6746, 3711,-2258, 1353, -761, 389, -174, 66, -20, 5, -10, + 1, -30, 63, -125, 212, -311, 384, -365, 140, 497,-2109, 8111,28251,-6731, 3712,-2265, 1362, -769, 395, -178, 68, -21, 5, -10, + 1, -30, 63, -126, 214, -314, 392, -379, 164, 458,-2041, 7931,28374,-6715, 3713,-2272, 1370, -777, 401, -182, 70, -22, 6, -10, + 1, -30, 63, -126, 215, -318, 399, -393, 188, 418,-1972, 7751,28495,-6698, 3712,-2279, 1379, -785, 407, -186, 73, -23, 6, -10, + 1, -30, 63, -126, 216, -321, 406, -406, 212, 379,-1904, 7572,28615,-6680, 3711,-2285, 1387, -793, 413, -191, 75, -25, 7, -10, + 1, -30, 63, -127, 218, -325, 414, -420, 236, 340,-1835, 7394,28734,-6660, 3710,-2291, 1395, -800, 419, -195, 78, -26, 7, -11, + 1, -30, 63, -127, 219, -328, 421, -434, 259, 300,-1767, 7216,28850,-6639, 3707,-2296, 1403, -808, 425, -199, 80, -27, 8, -11, + 1, -30, 63, -127, 220, -331, 428, -447, 283, 261,-1699, 7038,28966,-6616, 3704,-2301, 1411, -815, 431, -203, 82, -28, 9, -11, + 1, -30, 63, -127, 221, -334, 435, -460, 306, 222,-1631, 6862,29080,-6593, 3701,-2306, 1418, -822, 437, -207, 85, -30, 9, -11, + 1, -30, 63, -128, 222, -337, 442, -474, 329, 183,-1562, 6686,29192,-6567, 3696,-2310, 1425, -829, 442, -211, 87, -31, 10, -11, + 2, -30, 63, -128, 223, -340, 448, -487, 352, 145,-1494, 6510,29302,-6541, 3691,-2314, 1432, -836, 448, -215, 90, -32, 10, -11, + 2, -30, 63, -128, 224, -343, 455, -500, 375, 106,-1426, 6336,29412,-6513, 3686,-2317, 1439, -843, 454, -218, 92, -33, 11, -12, + 2, -30, 63, -128, 225, -346, 462, -512, 398, 68,-1358, 6162,29519,-6484, 3679,-2320, 1445, -850, 459, -222, 94, -35, 11, -12, + 2, -30, 63, -128, 226, -349, 468, -525, 420, 29,-1290, 5988,29625,-6454, 3672,-2323, 1451, -857, 465, -226, 97, -36, 12, -12, + 2, -29, 63, -129, 227, -352, 474, -538, 443, -9,-1222, 5816,29729,-6422, 3665,-2325, 1457, -863, 470, -230, 99, -37, 13, -12, + 2, -29, 63, -129, 228, -354, 481, -550, 465, -47,-1155, 5644,29832,-6389, 3656,-2327, 1463, -870, 476, -234, 101, -38, 13, -12, + 2, -29, 63, -129, 229, -357, 487, -562, 487, -85,-1087, 5473,29933,-6354, 3647,-2328, 1469, -876, 481, -238, 104, -40, 14, -13, + 2, -29, 63, -129, 230, -360, 493, -574, 509, -123,-1020, 5303,30033,-6318, 3637,-2330, 1474, -882, 486, -242, 106, -41, 14, -13, + 2, -29, 63, -129, 230, -362, 499, -586, 531, -160, -953, 5133,30130,-6281, 3627,-2330, 1479, -888, 491, -245, 108, -42, 15, -13, + 2, -29, 63, -129, 231, -364, 504, -598, 552, -198, -886, 4964,30227,-6242, 3616,-2330, 1484, -894, 496, -249, 111, -44, 16, -13, + 2, -29, 62, -129, 232, -367, 510, -610, 574, -235, -819, 4797,30321,-6202, 3604,-2330, 1488, -899, 501, -253, 113, -45, 16, -13, + 2, -29, 62, -129, 232, -369, 516, -621, 595, -272, -752, 4630,30414,-6161, 3591,-2329, 1493, -905, 506, -256, 115, -46, 17, -14, + 2, -29, 62, -129, 233, -371, 521, -633, 616, -309, -686, 4463,30505,-6118, 3578,-2328, 1497, -910, 511, -260, 118, -47, 17, -14, + 2, -29, 62, -129, 233, -373, 526, -644, 637, -345, -620, 4298,30594,-6073, 3564,-2327, 1500, -916, 516, -264, 120, -49, 18, -14, + 2, -29, 62, -129, 234, -375, 532, -655, 657, -382, -554, 4133,30682,-6028, 3549,-2325, 1504, -921, 521, -267, 122, -50, 18, -14, + 2, -29, 62, -128, 234, -377, 537, -666, 678, -418, -488, 3970,30768,-5981, 3534,-2323, 1507, -926, 526, -271, 125, -51, 19, -14, + 2, -29, 61, -128, 234, -379, 542, -677, 698, -454, -422, 3807,30852,-5932, 3518,-2320, 1510, -931, 530, -274, 127, -52, 20, -14, + 2, -29, 61, -128, 235, -380, 547, -687, 718, -490, -357, 3645,30935,-5882, 3501,-2317, 1513, -935, 535, -278, 129, -54, 20, -15, + 2, -29, 61, -128, 235, -382, 551, -698, 738, -526, -292, 3484,31015,-5831, 3484,-2313, 1515, -940, 539, -281, 131, -55, 21, -15, + 2, -29, 61, -128, 235, -384, 556, -708, 758, -561, -227, 3324,31094,-5778, 3465,-2309, 1518, -944, 544, -285, 134, -56, 21, -15, + 2, -28, 61, -127, 235, -385, 560, -718, 777, -596, -163, 3165,31172,-5724, 3447,-2305, 1520, -949, 548, -288, 136, -57, 22, -15, + 2, -28, 60, -127, 236, -387, 565, -728, 797, -631, -98, 3007,31247,-5669, 3427,-2300, 1521, -953, 552, -291, 138, -59, 23, -15, + 2, -28, 60, -127, 236, -388, 569, -738, 816, -666, -35, 2850,31321,-5612, 3407,-2295, 1523, -957, 556, -295, 140, -60, 23, -16, + 2, -28, 60, -127, 236, -389, 573, -747, 835, -700, 29, 2694,31393,-5554, 3386,-2289, 1524, -960, 561, -298, 143, -61, 24, -16, + 2, -28, 59, -126, 236, -391, 577, -757, 853, -734, 92, 2539,31463,-5494, 3364,-2283, 1525, -964, 565, -301, 145, -62, 24, -16, + 2, -28, 59, -126, 236, -392, 581, -766, 872, -768, 155, 2385,31531,-5433, 3342,-2276, 1525, -967, 568, -305, 147, -64, 25, -16, + 2, -28, 59, -126, 236, -393, 585, -775, 890, -801, 218, 2232,31597,-5370, 3319,-2269, 1526, -971, 572, -308, 149, -65, 26, -16, + 2, -28, 59, -125, 236, -394, 589, -784, 908, -835, 280, 2080,31662,-5306, 3295,-2262, 1526, -974, 576, -311, 151, -66, 26, -17, + 2, -28, 58, -125, 235, -395, 593, -793, 926, -868, 342, 1929,31725,-5241, 3271,-2254, 1526, -977, 580, -314, 153, -67, 27, -17, + 2, -28, 58, -125, 235, -396, 596, -801, 943, -901, 404, 1779,31786,-5174, 3246,-2245, 1525, -980, 583, -317, 155, -68, 27, -17, + 2, -27, 58, -124, 235, -397, 599, -810, 961, -933, 465, 1630,31845,-5106, 3220,-2237, 1525, -982, 587, -320, 157, -70, 28, -17, + 2, -27, 57, -124, 235, -397, 603, -818, 978, -965, 526, 1482,31902,-5036, 3193,-2228, 1524, -985, 590, -323, 159, -71, 28, -17, + 2, -27, 57, -123, 234, -398, 606, -826, 995, -997, 586, 1335,31958,-4965, 3166,-2218, 1522, -987, 593, -326, 162, -72, 29, -18, + 2, -27, 57, -123, 234, -399, 609, -834, 1011,-1029, 646, 1190,32011,-4892, 3138,-2208, 1521, -989, 597, -329, 164, -73, 30, -18, + 2, -27, 56, -122, 234, -399, 612, -842, 1028,-1060, 706, 1045,32063,-4818, 3110,-2197, 1519, -991, 600, -331, 166, -74, 30, -18, + 2, -27, 56, -122, 233, -399, 614, -849, 1044,-1091, 765, 902,32113,-4743, 3080,-2187, 1517, -993, 603, -334, 168, -76, 31, -18, + 2, -27, 56, -121, 233, -400, 617, -857, 1060,-1122, 824, 760,32161,-4666, 3051,-2175, 1515, -995, 606, -337, 169, -77, 31, -18, + 1, -27, 55, -121, 232, -400, 620, -864, 1075,-1152, 882, 618,32207,-4588, 3020,-2163, 1512, -996, 608, -340, 171, -78, 32, -19, + 1, -26, 55, -120, 232, -400, 622, -871, 1091,-1182, 940, 478,32251,-4508, 2989,-2151, 1509, -998, 611, -342, 173, -79, 33, -19, + 1, -26, 55, -119, 231, -400, 624, -878, 1106,-1212, 998, 340,32294,-4427, 2957,-2139, 1506, -999, 614, -345, 175, -80, 33, -19, + 1, -26, 54, -119, 231, -401, 626, -884, 1121,-1241, 1055, 202,32334,-4345, 2924,-2126, 1502,-1000, 616, -347, 177, -81, 34, -19, + 1, -26, 54, -118, 230, -401, 628, -891, 1136,-1270, 1111, 65,32373,-4261, 2891,-2112, 1499,-1001, 619, -350, 179, -82, 34, -19, + 1, -26, 53, -117, 229, -401, 630, -897, 1150,-1299, 1167, -70,32409,-4176, 2857,-2098, 1494,-1001, 621, -352, 181, -84, 35, -19, + 1, -26, 53, -117, 229, -400, 632, -903, 1164,-1328, 1223, -204,32444,-4089, 2822,-2084, 1490,-1002, 623, -355, 183, -85, 35, -20, + 1, -26, 53, -116, 228, -400, 634, -909, 1178,-1356, 1278, -337,32477,-4001, 2787,-2069, 1486,-1002, 625, -357, 184, -86, 36, -20, + 1, -25, 52, -115, 227, -400, 635, -915, 1192,-1383, 1333, -469,32508,-3912, 2751,-2054, 1481,-1002, 627, -359, 186, -87, 37, -20, + 1, -25, 52, -115, 226, -400, 637, -920, 1205,-1411, 1387, -599,32537,-3821, 2714,-2039, 1476,-1002, 629, -361, 188, -88, 37, -20, + 1, -25, 51, -114, 225, -399, 638, -926, 1218,-1438, 1441, -729,32564,-3729, 2677,-2023, 1470,-1002, 631, -364, 190, -89, 38, -20, + 1, -25, 51, -113, 224, -399, 639, -931, 1231,-1464, 1494, -857,32589,-3635, 2639,-2006, 1464,-1001, 633, -366, 191, -90, 38, -21, + 1, -25, 50, -112, 223, -398, 641, -936, 1244,-1491, 1546, -983,32613,-3540, 2601,-1989, 1458,-1001, 634, -368, 193, -91, 39, -21, + 1, -25, 50, -112, 222, -397, 642, -941, 1256,-1517, 1598,-1109,32634,-3444, 2562,-1972, 1452,-1000, 636, -370, 195, -92, 39, -21, + 1, -25, 49, -111, 221, -397, 642, -945, 1268,-1542, 1650,-1233,32653,-3346, 2522,-1954, 1446, -999, 637, -372, 196, -93, 40, -21, + 1, -24, 49, -110, 220, -396, 643, -950, 1280,-1567, 1701,-1356,32671,-3247, 2481,-1936, 1439, -998, 638, -373, 198, -94, 40, -21, + 1, -24, 49, -109, 219, -395, 644, -954, 1291,-1592, 1752,-1478,32686,-3147, 2440,-1918, 1432, -996, 640, -375, 199, -95, 41, -22, + 1, -24, 48, -108, 218, -394, 644, -958, 1303,-1617, 1802,-1598,32700,-3045, 2398,-1899, 1424, -995, 641, -377, 201, -96, 41, -22, + 1, -24, 48, -108, 217, -393, 645, -962, 1314,-1641, 1851,-1717,32711,-2941, 2356,-1880, 1416, -993, 642, -379, 202, -97, 42, -22, + 1, -24, 47, -107, 216, -392, 645, -966, 1324,-1664, 1900,-1835,32721,-2837, 2313,-1860, 1408, -991, 643, -380, 204, -98, 43, -22, + 1, -24, 47, -106, 215, -391, 645, -969, 1335,-1688, 1948,-1952,32729,-2731, 2270,-1840, 1400, -989, 643, -382, 205, -99, 43, -22, + 1, -23, 46, -105, 213, -390, 645, -973, 1345,-1711, 1996,-2067,32735,-2624, 2225,-1819, 1392, -987, 644, -384, 207, -100, 44, -22, + 1, -23, 46, -104, 212, -389, 645, -976, 1355,-1733, 2043,-2181,32739,-2515, 2181,-1798, 1383, -984, 644, -385, 208, -101, 44, -23, + 39, -23, 45, -103, 211, -388, 645, -979, 1365,-1755, 2089,-2294,32741,-2405, 2135,-1777, 1374, -982, 645, -386, 210, -102, 45, -23, diff --git a/services/multimedia/audio/process/resample/coef/resample_any_up512_32_filter.txt b/services/multimedia/audio/process/resample/coef/resample_any_up512_32_filter.txt new file mode 100644 index 0000000..f55a413 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_any_up512_32_filter.txt @@ -0,0 +1,513 @@ +//single phase coef Number:=32, upsample factor:=512, + 38, -4, -3, 15, -33, 58, -88, 125, -165, 208, -251, 291, -328, 359, -391,30674, -332, 331, -310, 279, -242, 202, -161, 121, -86, 56, -32, 14, -3, -4, 38, -43, + 37, -3, -4, 16, -34, 59, -91, 128, -169, 214, -259, 303, -345, 387, -449,30673, -273, 303, -293, 267, -233, 195, -156, 118, -84, 55, -31, 14, -2, -4, 38, 1, + 37, -3, -4, 16, -35, 61, -93, 131, -174, 220, -268, 315, -363, 415, -507,30673, -215, 274, -275, 255, -225, 189, -152, 115, -82, 53, -30, 13, -2, -5, 38, 1, + 37, -3, -4, 17, -36, 62, -95, 134, -178, 226, -276, 327, -380, 443, -564,30671, -155, 246, -257, 243, -216, 183, -147, 112, -79, 52, -29, 12, -1, -5, 38, 1, + 37, -2, -5, 18, -37, 64, -97, 137, -183, 232, -285, 339, -398, 471, -622,30670, -96, 218, -240, 231, -208, 177, -143, 109, -77, 50, -28, 12, -1, -5, 38, 1, + 37, -2, -5, 19, -38, 66, -100, 140, -187, 238, -293, 351, -415, 498, -679,30668, -36, 189, -222, 219, -199, 170, -138, 105, -75, 48, -27, 11, 0, -5, 38, 1, + 37, -2, -6, 19, -40, 67, -102, 144, -191, 244, -302, 363, -432, 526, -736,30665, 24, 161, -204, 207, -190, 164, -133, 102, -73, 47, -26, 10, 0, -6, 38, 1, + 37, -2, -6, 20, -41, 69, -104, 147, -196, 250, -310, 375, -450, 554, -793,30663, 84, 132, -186, 194, -182, 158, -129, 99, -70, 45, -25, 9, 1, -6, 39, 1, + 37, -1, -7, 21, -42, 70, -106, 150, -200, 257, -318, 387, -467, 581, -849,30660, 144, 103, -168, 182, -173, 152, -124, 96, -68, 44, -24, 9, 1, -6, 39, 1, + 37, -1, -7, 21, -43, 72, -108, 153, -205, 263, -327, 398, -484, 609, -905,30656, 205, 75, -150, 170, -164, 145, -120, 92, -66, 42, -23, 8, 1, -7, 39, 1, + 36, -1, -7, 22, -44, 73, -111, 156, -209, 269, -335, 410, -501, 636, -961,30652, 266, 46, -132, 158, -155, 139, -115, 89, -63, 40, -21, 7, 2, -7, 39, 1, + 36, 0, -8, 23, -45, 75, -113, 159, -213, 275, -343, 422, -518, 663,-1017,30648, 327, 17, -114, 145, -147, 133, -111, 86, -61, 39, -20, 7, 2, -7, 39, 1, + 36, 0, -8, 23, -46, 76, -115, 162, -218, 281, -352, 433, -535, 690,-1072,30643, 388, -12, -96, 133, -138, 126, -106, 82, -59, 37, -19, 6, 3, -8, 39, 1, + 36, 0, -9, 24, -47, 78, -117, 165, -222, 286, -360, 445, -552, 717,-1127,30638, 450, -41, -78, 121, -129, 120, -102, 79, -56, 36, -18, 5, 3, -8, 39, 1, + 36, 1, -9, 25, -48, 79, -119, 168, -226, 292, -368, 457, -569, 744,-1182,30632, 512, -70, -60, 108, -120, 113, -97, 76, -54, 34, -17, 4, 4, -8, 39, 1, + 36, 1, -10, 25, -49, 81, -121, 171, -230, 298, -376, 468, -586, 771,-1237,30626, 574, -99, -42, 96, -111, 107, -92, 73, -52, 32, -16, 4, 4, -8, 39, 1, + 36, 1, -10, 26, -50, 82, -124, 174, -235, 304, -385, 480, -603, 798,-1291,30620, 636, -128, -24, 83, -102, 101, -88, 69, -49, 31, -15, 3, 5, -9, 40, 1, + 36, 1, -11, 27, -51, 84, -126, 177, -239, 310, -393, 491, -620, 825,-1345,30613, 698, -157, -6, 71, -94, 94, -83, 66, -47, 29, -14, 2, 5, -9, 40, 1, + 35, 2, -11, 27, -52, 85, -128, 180, -243, 316, -401, 503, -637, 852,-1399,30606, 761, -187, 12, 58, -85, 88, -78, 63, -45, 27, -13, 2, 6, -9, 40, 1, + 35, 2, -11, 28, -53, 87, -130, 183, -247, 322, -409, 514, -653, 878,-1453,30598, 824, -216, 30, 46, -76, 81, -74, 59, -42, 26, -12, 1, 6, -10, 40, 1, + 35, 2, -12, 29, -54, 88, -132, 186, -251, 328, -417, 526, -670, 905,-1506,30590, 887, -245, 49, 33, -67, 75, -69, 56, -40, 24, -10, 0, 6, -10, 40, 1, + 35, 3, -12, 29, -55, 89, -134, 189, -256, 333, -425, 537, -686, 931,-1559,30582, 951, -275, 67, 21, -58, 69, -64, 52, -37, 22, -9, -1, 7, -10, 40, 1, + 35, 3, -13, 30, -56, 91, -136, 192, -260, 339, -433, 548, -703, 957,-1612,30573, 1014, -304, 85, 8, -49, 62, -60, 49, -35, 21, -8, -1, 7, -11, 40, 1, + 35, 3, -13, 31, -57, 92, -138, 195, -264, 345, -441, 560, -720, 983,-1665,30564, 1078, -334, 104, -4, -40, 56, -55, 46, -33, 19, -7, -2, 8, -11, 40, 1, + 35, 3, -14, 31, -58, 94, -140, 198, -268, 351, -449, 571, -736, 1010,-1717,30555, 1142, -364, 122, -17, -31, 49, -50, 42, -30, 17, -6, -3, 8, -11, 40, 1, + 35, 4, -14, 32, -59, 95, -143, 201, -272, 356, -457, 582, -752, 1036,-1769,30545, 1207, -393, 140, -29, -22, 43, -46, 39, -28, 16, -5, -4, 9, -11, 40, 1, + 35, 4, -14, 32, -60, 97, -145, 204, -276, 362, -465, 593, -769, 1061,-1821,30535, 1271, -423, 159, -42, -13, 36, -41, 36, -26, 14, -4, -4, 9, -12, 41, 1, + 34, 4, -15, 33, -61, 98, -147, 207, -280, 368, -473, 604, -785, 1087,-1872,30524, 1336, -453, 177, -54, -4, 30, -36, 32, -23, 13, -3, -5, 10, -12, 41, 1, + 34, 5, -15, 34, -62, 100, -149, 210, -284, 374, -481, 616, -801, 1113,-1923,30513, 1401, -482, 196, -67, 5, 23, -31, 29, -21, 11, -2, -6, 10, -12, 41, 1, + 34, 5, -16, 34, -63, 101, -151, 213, -288, 379, -489, 627, -817, 1139,-1974,30501, 1466, -512, 214, -80, 14, 17, -27, 25, -18, 9, 0, -6, 11, -13, 41, 1, + 34, 5, -16, 35, -63, 102, -153, 216, -293, 385, -497, 638, -833, 1164,-2025,30490, 1532, -542, 233, -92, 23, 10, -22, 22, -16, 8, 1, -7, 11, -13, 41, 1, + 34, 5, -16, 36, -64, 104, -155, 219, -297, 390, -504, 649, -849, 1190,-2075,30477, 1598, -572, 251, -105, 32, 3, -17, 19, -14, 6, 2, -8, 12, -13, 41, 1, + 34, 6, -17, 36, -65, 105, -157, 222, -301, 396, -512, 660, -865, 1215,-2125,30465, 1663, -602, 270, -118, 41, -3, -12, 15, -11, 4, 3, -9, 12, -14, 41, 1, + 34, 6, -17, 37, -66, 107, -159, 224, -305, 402, -520, 671, -881, 1240,-2175,30452, 1730, -632, 288, -130, 50, -10, -8, 12, -9, 2, 4, -9, 13, -14, 41, 1, + 34, 6, -18, 38, -67, 108, -161, 227, -309, 407, -528, 681, -897, 1265,-2225,30438, 1796, -662, 307, -143, 59, -16, -3, 8, -6, 1, 5, -10, 13, -14, 41, 1, + 33, 7, -18, 38, -68, 109, -163, 230, -312, 413, -535, 692, -913, 1290,-2274,30424, 1862, -692, 325, -156, 68, -23, 2, 5, -4, -1, 6, -11, 13, -14, 42, 1, + 33, 7, -18, 39, -69, 111, -165, 233, -316, 418, -543, 703, -929, 1315,-2323,30410, 1929, -723, 344, -169, 77, -29, 7, 1, -1, -3, 8, -12, 14, -15, 42, 1, + 33, 7, -19, 39, -70, 112, -167, 236, -320, 424, -551, 714, -944, 1340,-2372,30395, 1996, -753, 363, -181, 86, -36, 11, -2, 1, -4, 9, -12, 14, -15, 42, 1, + 33, 7, -19, 40, -71, 113, -169, 238, -324, 429, -558, 724, -960, 1365,-2420,30380, 2063, -783, 381, -194, 95, -43, 16, -5, 4, -6, 10, -13, 15, -15, 42, 1, + 33, 8, -20, 41, -72, 115, -171, 241, -328, 434, -566, 735, -976, 1389,-2469,30365, 2131, -813, 400, -207, 105, -49, 21, -9, 6, -8, 11, -14, 15, -16, 42, 1, + 33, 8, -20, 41, -73, 116, -173, 244, -332, 440, -573, 746, -991, 1414,-2516,30349, 2198, -844, 419, -220, 114, -56, 26, -12, 8, -9, 12, -15, 16, -16, 42, 1, + 33, 8, -20, 42, -74, 117, -175, 247, -336, 445, -581, 756,-1007, 1438,-2564,30333, 2266, -874, 437, -232, 123, -62, 31, -16, 11, -11, 13, -15, 16, -16, 42, 1, + 33, 9, -21, 42, -75, 119, -176, 249, -340, 450, -588, 767,-1022, 1463,-2612,30317, 2334, -904, 456, -245, 132, -69, 35, -19, 13, -13, 14, -16, 17, -17, 42, 1, + 33, 9, -21, 43, -76, 120, -178, 252, -343, 456, -596, 777,-1037, 1487,-2659,30300, 2402, -935, 475, -258, 141, -76, 40, -23, 16, -14, 16, -17, 17, -17, 42, 1, + 32, 9, -22, 44, -76, 121, -180, 255, -347, 461, -603, 788,-1053, 1511,-2705,30282, 2471, -965, 493, -271, 150, -82, 45, -26, 18, -16, 17, -18, 18, -17, 42, 1, + 32, 9, -22, 44, -77, 123, -182, 258, -351, 466, -610, 798,-1068, 1535,-2752,30264, 2539, -996, 512, -284, 159, -89, 50, -30, 21, -18, 18, -18, 18, -17, 43, 1, + 32, 10, -22, 45, -78, 124, -184, 260, -355, 472, -618, 809,-1083, 1559,-2798,30246, 2608,-1026, 531, -296, 169, -96, 55, -33, 23, -20, 19, -19, 19, -18, 43, 1, + 32, 10, -23, 45, -79, 125, -186, 263, -359, 477, -625, 819,-1098, 1583,-2844,30228, 2677,-1057, 550, -309, 178, -102, 60, -37, 26, -21, 20, -20, 19, -18, 43, 1, + 32, 10, -23, 46, -80, 127, -188, 266, -362, 482, -632, 829,-1113, 1606,-2890,30209, 2746,-1087, 568, -322, 187, -109, 64, -40, 28, -23, 21, -21, 20, -18, 43, 1, + 32, 11, -24, 47, -81, 128, -190, 268, -366, 487, -639, 839,-1128, 1630,-2935,30190, 2816,-1118, 587, -335, 196, -116, 69, -44, 31, -25, 22, -21, 20, -19, 43, 1, + 32, 11, -24, 47, -82, 129, -191, 271, -370, 492, -647, 850,-1143, 1653,-2981,30170, 2885,-1148, 606, -348, 205, -122, 74, -47, 33, -26, 24, -22, 21, -19, 43, 1, + 32, 11, -24, 48, -83, 130, -193, 273, -373, 497, -654, 860,-1158, 1676,-3025,30150, 2955,-1179, 625, -361, 214, -129, 79, -51, 36, -28, 25, -23, 21, -19, 43, 1, + 31, 11, -25, 48, -83, 132, -195, 276, -377, 503, -661, 870,-1172, 1700,-3070,30130, 3025,-1209, 643, -374, 224, -136, 84, -54, 38, -30, 26, -24, 21, -20, 43, 1, + 31, 12, -25, 49, -84, 133, -197, 279, -381, 508, -668, 880,-1187, 1723,-3114,30109, 3095,-1240, 662, -386, 233, -142, 89, -58, 40, -32, 27, -24, 22, -20, 43, 1, + 31, 12, -26, 49, -85, 134, -199, 281, -384, 513, -675, 890,-1201, 1746,-3158,30088, 3166,-1271, 681, -399, 242, -149, 94, -61, 43, -33, 28, -25, 22, -20, 43, 1, + 31, 12, -26, 50, -86, 135, -201, 284, -388, 518, -682, 900,-1216, 1769,-3202,30066, 3236,-1302, 700, -412, 251, -156, 98, -65, 45, -35, 29, -26, 23, -20, 44, 1, + 31, 13, -26, 51, -87, 137, -202, 286, -391, 523, -689, 910,-1230, 1791,-3246,30044, 3307,-1332, 719, -425, 260, -162, 103, -68, 48, -37, 31, -27, 23, -21, 44, 1, + 31, 13, -27, 51, -88, 138, -204, 289, -395, 528, -696, 919,-1245, 1814,-3289,30022, 3378,-1363, 737, -438, 270, -169, 108, -72, 50, -39, 32, -27, 24, -21, 44, 1, + 31, 13, -27, 52, -89, 139, -206, 291, -398, 533, -703, 929,-1259, 1836,-3332,29999, 3449,-1394, 756, -451, 279, -176, 113, -75, 53, -40, 33, -28, 24, -21, 44, 1, + 31, 13, -27, 52, -89, 140, -208, 294, -402, 538, -710, 939,-1273, 1859,-3374,29976, 3521,-1425, 775, -464, 288, -182, 118, -79, 55, -42, 34, -29, 25, -22, 44, 1, + 30, 14, -28, 53, -90, 142, -209, 296, -405, 542, -717, 949,-1288, 1881,-3417,29952, 3592,-1455, 794, -476, 297, -189, 123, -82, 58, -44, 35, -30, 25, -22, 44, 1, + 30, 14, -28, 53, -91, 143, -211, 299, -409, 547, -723, 958,-1302, 1903,-3459,29928, 3664,-1486, 813, -489, 306, -196, 128, -86, 60, -45, 36, -30, 26, -22, 44, 1, + 30, 14, -28, 54, -92, 144, -213, 301, -412, 552, -730, 968,-1316, 1925,-3501,29904, 3736,-1517, 832, -502, 316, -202, 132, -89, 63, -47, 38, -31, 26, -22, 44, 1, + 30, 14, -29, 54, -93, 145, -215, 304, -416, 557, -737, 977,-1330, 1947,-3542,29880, 3808,-1548, 850, -515, 325, -209, 137, -93, 65, -49, 39, -32, 27, -23, 44, 1, + 30, 15, -29, 55, -93, 146, -216, 306, -419, 562, -744, 987,-1343, 1969,-3583,29855, 3880,-1579, 869, -528, 334, -216, 142, -96, 68, -51, 40, -33, 27, -23, 44, 1, + 30, 15, -30, 56, -94, 148, -218, 308, -423, 566, -750, 996,-1357, 1991,-3624,29829, 3952,-1609, 888, -541, 343, -223, 147, -100, 70, -52, 41, -33, 28, -23, 45, 1, + 30, 15, -30, 56, -95, 149, -220, 311, -426, 571, -757, 1006,-1371, 2012,-3665,29803, 4025,-1640, 907, -553, 352, -229, 152, -103, 73, -54, 42, -34, 28, -24, 45, 1, + 30, 15, -30, 57, -96, 150, -221, 313, -429, 576, -764, 1015,-1385, 2034,-3705,29777, 4098,-1671, 926, -566, 362, -236, 157, -107, 75, -56, 43, -35, 29, -24, 45, 1, + 30, 16, -31, 57, -97, 151, -223, 316, -433, 581, -770, 1024,-1398, 2055,-3745,29751, 4171,-1702, 944, -579, 371, -243, 162, -110, 78, -58, 45, -36, 29, -24, 45, 1, + 29, 16, -31, 58, -97, 152, -225, 318, -436, 585, -777, 1034,-1412, 2076,-3785,29724, 4244,-1733, 963, -592, 380, -249, 167, -114, 80, -59, 46, -37, 30, -25, 45, 1, + 29, 16, -31, 58, -98, 153, -226, 320, -439, 590, -783, 1043,-1425, 2097,-3824,29697, 4317,-1764, 982, -605, 389, -256, 171, -117, 83, -61, 47, -37, 30, -25, 45, 1, + 29, 17, -32, 59, -99, 154, -228, 323, -443, 594, -790, 1052,-1439, 2118,-3864,29669, 4391,-1795, 1001, -618, 398, -263, 176, -121, 85, -63, 48, -38, 30, -25, 45, 1, + 29, 17, -32, 59, -100, 156, -229, 325, -446, 599, -796, 1061,-1452, 2139,-3902,29641, 4464,-1825, 1019, -630, 407, -269, 181, -124, 88, -64, 49, -39, 31, -25, 45, 1, + 29, 17, -32, 60, -100, 157, -231, 327, -449, 603, -802, 1070,-1465, 2160,-3941,29613, 4538,-1856, 1038, -643, 417, -276, 186, -128, 90, -66, 50, -40, 31, -26, 45, 1, + 29, 17, -33, 60, -101, 158, -233, 329, -452, 608, -809, 1079,-1478, 2180,-3979,29584, 4612,-1887, 1057, -656, 426, -283, 191, -131, 93, -68, 52, -40, 32, -26, 45, 1, + 29, 18, -33, 61, -102, 159, -234, 332, -455, 612, -815, 1088,-1491, 2201,-4017,29555, 4686,-1918, 1076, -669, 435, -289, 196, -135, 95, -70, 53, -41, 32, -26, 45, 1, + 29, 18, -33, 61, -103, 160, -236, 334, -459, 617, -821, 1097,-1504, 2221,-4055,29525, 4760,-1949, 1094, -682, 444, -296, 201, -138, 98, -71, 54, -42, 33, -27, 45, 2, + 28, 18, -34, 62, -103, 161, -237, 336, -462, 621, -827, 1106,-1517, 2241,-4093,29495, 4835,-1980, 1113, -694, 453, -303, 206, -142, 100, -73, 55, -43, 33, -27, 46, 2, + 28, 18, -34, 62, -104, 162, -239, 338, -465, 626, -833, 1114,-1530, 2261,-4130,29465, 4910,-2011, 1132, -707, 462, -309, 210, -145, 103, -75, 56, -43, 34, -27, 46, 2, + 28, 19, -34, 63, -105, 163, -240, 340, -468, 630, -840, 1123,-1543, 2281,-4167,29434, 4984,-2041, 1150, -720, 472, -316, 215, -149, 105, -77, 57, -44, 34, -27, 46, 2, + 28, 19, -35, 63, -106, 164, -242, 343, -471, 634, -846, 1132,-1555, 2301,-4203,29403, 5059,-2072, 1169, -733, 481, -323, 220, -153, 108, -78, 59, -45, 35, -28, 46, 2, + 28, 19, -35, 64, -106, 165, -244, 345, -474, 639, -852, 1140,-1568, 2321,-4240,29372, 5134,-2103, 1188, -745, 490, -329, 225, -156, 110, -80, 60, -46, 35, -28, 46, 2, + 28, 19, -35, 64, -107, 166, -245, 347, -477, 643, -858, 1149,-1580, 2340,-4276,29340, 5210,-2134, 1206, -758, 499, -336, 230, -160, 113, -82, 61, -46, 36, -28, 46, 2, + 28, 20, -36, 65, -108, 167, -247, 349, -480, 647, -864, 1157,-1593, 2360,-4311,29308, 5285,-2165, 1225, -771, 508, -343, 235, -163, 115, -84, 62, -47, 36, -29, 46, 2, + 28, 20, -36, 65, -109, 168, -248, 351, -483, 651, -870, 1166,-1605, 2379,-4347,29276, 5361,-2195, 1244, -784, 517, -349, 240, -167, 118, -85, 63, -48, 37, -29, 46, 2, + 27, 20, -36, 66, -109, 169, -249, 353, -486, 655, -875, 1174,-1617, 2398,-4382,29243, 5436,-2226, 1262, -796, 526, -356, 244, -170, 120, -87, 64, -49, 37, -29, 46, 2, + 27, 20, -37, 66, -110, 170, -251, 355, -489, 660, -881, 1182,-1629, 2417,-4417,29210, 5512,-2257, 1281, -809, 535, -363, 249, -174, 123, -89, 66, -49, 38, -29, 46, 2, + 27, 21, -37, 67, -111, 171, -252, 357, -492, 664, -887, 1191,-1642, 2436,-4451,29176, 5588,-2288, 1299, -822, 544, -369, 254, -177, 125, -90, 67, -50, 38, -30, 46, 2, + 27, 21, -37, 67, -111, 172, -254, 359, -495, 668, -893, 1199,-1654, 2455,-4485,29142, 5664,-2318, 1318, -834, 553, -376, 259, -181, 128, -92, 68, -51, 38, -30, 46, 2, + 27, 21, -38, 68, -112, 173, -255, 362, -498, 672, -899, 1207,-1665, 2473,-4519,29108, 5741,-2349, 1336, -847, 563, -382, 264, -184, 130, -94, 69, -52, 39, -30, 47, 2, + 27, 21, -38, 68, -113, 174, -257, 364, -500, 676, -904, 1215,-1677, 2492,-4553,29074, 5817,-2380, 1355, -860, 572, -389, 269, -188, 133, -96, 70, -52, 39, -31, 47, 2, + 27, 22, -38, 69, -113, 175, -258, 366, -503, 680, -910, 1223,-1689, 2510,-4587,29039, 5894,-2410, 1373, -872, 581, -396, 273, -191, 135, -97, 71, -53, 40, -31, 47, 2, + 27, 22, -39, 69, -114, 176, -259, 368, -506, 684, -915, 1231,-1701, 2528,-4620,29003, 5970,-2441, 1392, -885, 590, -402, 278, -195, 138, -99, 73, -54, 40, -31, 47, 2, + 27, 22, -39, 69, -115, 177, -261, 369, -509, 688, -921, 1239,-1712, 2547,-4652,28968, 6047,-2472, 1410, -897, 599, -409, 283, -198, 140, -101, 74, -55, 41, -31, 47, 2, + 26, 22, -39, 70, -115, 178, -262, 371, -512, 692, -926, 1247,-1724, 2564,-4685,28932, 6124,-2502, 1429, -910, 608, -415, 288, -202, 143, -103, 75, -55, 41, -32, 47, 2, + 26, 23, -40, 70, -116, 179, -264, 373, -514, 695, -932, 1255,-1735, 2582,-4717,28895, 6202,-2533, 1447, -922, 617, -422, 293, -205, 145, -104, 76, -56, 42, -32, 47, 2, + 26, 23, -40, 71, -117, 180, -265, 375, -517, 699, -937, 1262,-1747, 2600,-4749,28858, 6279,-2563, 1465, -935, 626, -429, 297, -208, 148, -106, 77, -57, 42, -32, 47, 2, + 26, 23, -40, 71, -117, 181, -266, 377, -520, 703, -943, 1270,-1758, 2618,-4781,28821, 6356,-2594, 1484, -947, 635, -435, 302, -212, 150, -108, 78, -58, 43, -32, 47, 2, + 26, 23, -40, 72, -118, 182, -268, 379, -522, 707, -948, 1278,-1769, 2635,-4812,28784, 6434,-2624, 1502, -960, 644, -442, 307, -215, 153, -109, 79, -58, 43, -33, 47, 2, + 26, 24, -41, 72, -118, 183, -269, 381, -525, 711, -953, 1285,-1780, 2652,-4843,28746, 6511,-2655, 1520, -972, 652, -448, 312, -219, 155, -111, 81, -59, 44, -33, 47, 2, + 26, 24, -41, 72, -119, 184, -270, 383, -528, 714, -959, 1293,-1791, 2669,-4874,28708, 6589,-2685, 1538, -985, 661, -455, 317, -222, 158, -113, 82, -60, 44, -33, 47, 2, + 26, 24, -41, 73, -120, 185, -271, 385, -530, 718, -964, 1300,-1802, 2686,-4904,28669, 6667,-2715, 1557, -997, 670, -461, 321, -226, 160, -115, 83, -61, 44, -34, 47, 2, + 25, 24, -42, 73, -120, 186, -273, 386, -533, 722, -969, 1307,-1813, 2703,-4934,28630, 6745,-2746, 1575,-1010, 679, -468, 326, -229, 163, -116, 84, -61, 45, -34, 48, 2, + 25, 25, -42, 74, -121, 186, -274, 388, -535, 725, -974, 1315,-1824, 2720,-4964,28591, 6823,-2776, 1593,-1022, 688, -474, 331, -233, 165, -118, 85, -62, 45, -34, 48, 2, + 25, 25, -42, 74, -122, 187, -275, 390, -538, 729, -979, 1322,-1834, 2737,-4994,28552, 6902,-2806, 1611,-1034, 697, -481, 336, -236, 167, -120, 86, -63, 46, -34, 48, 2, + 25, 25, -42, 75, -122, 188, -276, 392, -540, 732, -984, 1329,-1845, 2753,-5023,28512, 6980,-2837, 1629,-1047, 706, -487, 340, -240, 170, -121, 88, -64, 46, -35, 48, 2, + 25, 25, -43, 75, -123, 189, -278, 393, -543, 736, -989, 1336,-1855, 2769,-5052,28471, 7059,-2867, 1647,-1059, 715, -494, 345, -243, 172, -123, 89, -64, 47, -35, 48, 2, + 25, 26, -43, 75, -123, 190, -279, 395, -545, 739, -994, 1343,-1866, 2785,-5081,28431, 7137,-2897, 1665,-1071, 723, -500, 350, -246, 175, -125, 90, -65, 47, -35, 48, 2, + 25, 26, -43, 76, -124, 191, -280, 397, -548, 743, -999, 1350,-1876, 2802,-5109,28390, 7216,-2927, 1683,-1083, 732, -507, 355, -250, 177, -127, 91, -66, 48, -35, 48, 2, + 25, 26, -44, 76, -124, 191, -281, 399, -550, 746,-1004, 1357,-1886, 2817,-5137,28349, 7295,-2957, 1701,-1096, 741, -513, 359, -253, 180, -128, 92, -66, 48, -36, 48, 2, + 25, 26, -44, 77, -125, 192, -282, 400, -553, 750,-1009, 1364,-1896, 2833,-5165,28307, 7374,-2987, 1719,-1108, 750, -519, 364, -257, 182, -130, 93, -67, 49, -36, 48, 2, + 24, 26, -44, 77, -126, 193, -284, 402, -555, 753,-1013, 1371,-1906, 2849,-5193,28265, 7453,-3017, 1737,-1120, 759, -526, 369, -260, 185, -132, 94, -68, 49, -36, 48, 2, + 24, 27, -44, 77, -126, 194, -285, 404, -557, 756,-1018, 1378,-1916, 2864,-5220,28223, 7533,-3047, 1755,-1132, 767, -532, 373, -264, 187, -133, 96, -69, 49, -37, 48, 2, + 24, 27, -45, 78, -127, 195, -286, 405, -560, 759,-1023, 1384,-1926, 2880,-5247,28180, 7612,-3077, 1773,-1144, 776, -539, 378, -267, 189, -135, 97, -69, 50, -37, 48, 2, + 24, 27, -45, 78, -127, 195, -287, 407, -562, 763,-1027, 1391,-1936, 2895,-5274,28137, 7691,-3107, 1790,-1156, 785, -545, 383, -270, 192, -137, 98, -70, 50, -37, 48, 3, + 24, 27, -45, 78, -128, 196, -288, 408, -564, 766,-1032, 1398,-1946, 2910,-5300,28094, 7771,-3137, 1808,-1169, 793, -551, 387, -274, 194, -138, 99, -71, 51, -37, 48, 3, + 24, 28, -46, 79, -128, 197, -289, 410, -566, 769,-1036, 1404,-1955, 2925,-5326,28050, 7851,-3166, 1826,-1181, 802, -558, 392, -277, 197, -140, 100, -72, 51, -38, 48, 3, + 24, 28, -46, 79, -129, 198, -290, 411, -569, 772,-1041, 1411,-1965, 2939,-5352,28006, 7931,-3196, 1843,-1193, 811, -564, 397, -281, 199, -142, 101, -72, 52, -38, 49, 3, + 24, 28, -46, 80, -129, 199, -291, 413, -571, 775,-1045, 1417,-1974, 2954,-5377,27962, 8010,-3226, 1861,-1205, 819, -570, 401, -284, 201, -143, 102, -73, 52, -38, 49, 3, + 23, 28, -46, 80, -130, 199, -292, 414, -573, 778,-1050, 1423,-1983, 2969,-5403,27917, 8090,-3255, 1878,-1217, 828, -577, 406, -287, 204, -145, 103, -74, 53, -38, 49, 3, + 23, 29, -47, 80, -130, 200, -293, 416, -575, 781,-1054, 1430,-1993, 2983,-5428,27872, 8171,-3285, 1896,-1228, 836, -583, 411, -291, 206, -147, 105, -74, 53, -39, 49, 3, + 23, 29, -47, 81, -131, 201, -294, 417, -577, 784,-1058, 1436,-2002, 2997,-5452,27827, 8251,-3314, 1913,-1240, 845, -589, 415, -294, 209, -148, 106, -75, 53, -39, 49, 3, + 23, 29, -47, 81, -131, 201, -295, 419, -579, 787,-1063, 1442,-2011, 3011,-5476,27781, 8331,-3343, 1931,-1252, 854, -595, 420, -297, 211, -150, 107, -76, 54, -39, 49, 3, + 23, 29, -47, 81, -132, 202, -296, 420, -581, 790,-1067, 1448,-2020, 3025,-5500,27735, 8411,-3373, 1948,-1264, 862, -602, 424, -301, 213, -152, 108, -77, 54, -39, 49, 3, + 23, 29, -48, 82, -132, 203, -297, 422, -583, 793,-1071, 1454,-2029, 3039,-5524,27688, 8492,-3402, 1966,-1276, 871, -608, 429, -304, 216, -153, 109, -77, 55, -40, 49, 3, + 23, 30, -48, 82, -133, 204, -298, 423, -585, 796,-1075, 1460,-2037, 3052,-5548,27642, 8572,-3431, 1983,-1288, 879, -614, 433, -307, 218, -155, 110, -78, 55, -40, 49, 3, + 23, 30, -48, 82, -133, 204, -299, 425, -587, 799,-1079, 1466,-2046, 3066,-5571,27595, 8653,-3460, 2000,-1299, 887, -620, 438, -311, 221, -157, 111, -79, 56, -40, 49, 3, + 23, 30, -48, 83, -134, 205, -300, 426, -589, 802,-1083, 1472,-2055, 3079,-5594,27548, 8734,-3490, 2017,-1311, 896, -626, 443, -314, 223, -158, 112, -79, 56, -40, 49, 3, + 22, 30, -48, 83, -134, 206, -301, 427, -591, 805,-1087, 1477,-2063, 3092,-5616,27500, 8815,-3519, 2034,-1323, 904, -633, 447, -317, 225, -160, 113, -80, 56, -41, 49, 3, + 22, 30, -49, 83, -135, 206, -302, 429, -593, 807,-1091, 1483,-2071, 3105,-5639,27452, 8896,-3548, 2051,-1334, 913, -639, 452, -320, 228, -162, 114, -81, 57, -41, 49, 3, + 22, 31, -49, 84, -135, 207, -303, 430, -595, 810,-1095, 1489,-2080, 3118,-5661,27404, 8977,-3576, 2068,-1346, 921, -645, 456, -324, 230, -163, 116, -82, 57, -41, 49, 3, + 22, 31, -49, 84, -136, 207, -304, 431, -597, 813,-1099, 1494,-2088, 3131,-5682,27355, 9058,-3605, 2085,-1357, 929, -651, 461, -327, 232, -165, 117, -82, 58, -41, 49, 3, + 22, 31, -49, 84, -136, 208, -305, 433, -599, 815,-1103, 1500,-2096, 3144,-5704,27306, 9139,-3634, 2102,-1369, 938, -657, 465, -330, 235, -166, 118, -83, 58, -42, 49, 3, + 22, 31, -50, 85, -136, 209, -306, 434, -601, 818,-1106, 1505,-2104, 3156,-5725,27257, 9220,-3663, 2119,-1380, 946, -663, 470, -334, 237, -168, 119, -84, 59, -42, 49, 3, + 22, 32, -50, 85, -137, 209, -307, 435, -602, 820,-1110, 1510,-2112, 3168,-5746,27207, 9301,-3691, 2136,-1392, 954, -669, 474, -337, 239, -170, 120, -84, 59, -42, 49, 3, + 22, 32, -50, 85, -137, 210, -308, 436, -604, 823,-1114, 1516,-2120, 3180,-5766,27157, 9383,-3720, 2153,-1403, 962, -675, 478, -340, 242, -171, 121, -85, 59, -42, 50, 3, + 22, 32, -50, 85, -138, 210, -308, 437, -606, 825,-1117, 1521,-2128, 3192,-5786,27107, 9464,-3748, 2170,-1415, 970, -681, 483, -343, 244, -173, 122, -86, 60, -43, 50, 3, + 21, 32, -51, 86, -138, 211, -309, 439, -608, 828,-1121, 1526,-2135, 3204,-5806,27057, 9546,-3777, 2186,-1426, 979, -687, 487, -347, 246, -174, 123, -86, 60, -43, 50, 3, + 21, 32, -51, 86, -139, 212, -310, 440, -609, 830,-1124, 1531,-2143, 3216,-5826,27006, 9627,-3805, 2203,-1437, 987, -693, 492, -350, 248, -176, 124, -87, 61, -43, 50, 3, + 21, 33, -51, 86, -139, 212, -311, 441, -611, 833,-1128, 1536,-2150, 3228,-5845,26955, 9709,-3833, 2219,-1449, 995, -699, 496, -353, 251, -178, 125, -88, 61, -43, 50, 3, + 21, 33, -51, 87, -139, 213, -312, 442, -612, 835,-1131, 1541,-2158, 3239,-5865,26903, 9791,-3861, 2236,-1460, 1003, -705, 501, -356, 253, -179, 126, -88, 61, -43, 50, 3, + 21, 33, -51, 87, -140, 213, -312, 443, -614, 837,-1134, 1546,-2165, 3250,-5883,26852, 9873,-3889, 2252,-1471, 1011, -711, 505, -359, 255, -181, 127, -89, 62, -44, 50, 3, + 21, 33, -52, 87, -140, 214, -313, 444, -616, 840,-1138, 1551,-2172, 3261,-5902,26800, 9955,-3917, 2269,-1482, 1019, -717, 509, -362, 258, -182, 128, -90, 62, -44, 50, 4, + 21, 33, -52, 87, -141, 214, -314, 445, -617, 842,-1141, 1556,-2179, 3272,-5920,26747,10037,-3945, 2285,-1493, 1027, -723, 514, -366, 260, -184, 130, -91, 63, -44, 50, 4, + 21, 34, -52, 88, -141, 215, -315, 446, -619, 844,-1144, 1560,-2186, 3283,-5938,26695,10119,-3973, 2301,-1504, 1035, -729, 518, -369, 262, -186, 131, -91, 63, -44, 50, 4, + 21, 34, -52, 88, -141, 215, -315, 448, -620, 846,-1147, 1565,-2193, 3294,-5956,26642,10201,-4001, 2317,-1515, 1043, -735, 522, -372, 264, -187, 132, -92, 63, -45, 50, 4, + 20, 34, -52, 88, -142, 216, -316, 449, -622, 848,-1150, 1570,-2200, 3304,-5973,26588,10283,-4028, 2333,-1526, 1051, -740, 526, -375, 267, -189, 133, -93, 64, -45, 50, 4, + 20, 34, -53, 89, -142, 216, -317, 450, -623, 851,-1154, 1574,-2207, 3315,-5990,26535,10365,-4056, 2349,-1537, 1059, -746, 531, -378, 269, -190, 134, -93, 64, -45, 50, 4, + 20, 34, -53, 89, -142, 217, -317, 451, -625, 853,-1157, 1578,-2213, 3325,-6007,26481,10447,-4083, 2365,-1548, 1067, -752, 535, -381, 271, -192, 135, -94, 65, -45, 50, 4, + 20, 35, -53, 89, -143, 217, -318, 451, -626, 855,-1160, 1583,-2220, 3335,-6024,26427,10529,-4111, 2381,-1559, 1074, -758, 539, -384, 273, -193, 136, -95, 65, -46, 50, 4, + 20, 35, -53, 89, -143, 218, -319, 452, -627, 857,-1162, 1587,-2226, 3345,-6040,26372,10612,-4138, 2397,-1570, 1082, -763, 544, -388, 276, -195, 137, -95, 65, -46, 50, 4, + 20, 35, -53, 90, -143, 218, -319, 453, -629, 859,-1165, 1591,-2232, 3355,-6056,26317,10694,-4165, 2413,-1580, 1090, -769, 548, -391, 278, -196, 138, -96, 66, -46, 50, 4, + 20, 35, -54, 90, -144, 219, -320, 454, -630, 861,-1168, 1596,-2239, 3364,-6071,26262,10777,-4192, 2429,-1591, 1098, -775, 552, -394, 280, -198, 139, -96, 66, -46, 50, 4, + 20, 35, -54, 90, -144, 219, -321, 455, -631, 862,-1171, 1600,-2245, 3374,-6087,26207,10859,-4219, 2444,-1602, 1105, -781, 556, -397, 282, -199, 140, -97, 67, -46, 50, 4, + 20, 35, -54, 90, -144, 220, -321, 456, -633, 864,-1174, 1604,-2251, 3383,-6102,26151,10942,-4246, 2460,-1612, 1113, -786, 560, -400, 284, -201, 141, -98, 67, -47, 50, 4, + 19, 36, -54, 90, -145, 220, -322, 457, -634, 866,-1176, 1608,-2257, 3392,-6117,26095,11024,-4273, 2476,-1623, 1120, -792, 564, -403, 286, -203, 142, -98, 67, -47, 50, 4, + 19, 36, -54, 91, -145, 220, -323, 458, -635, 868,-1179, 1611,-2263, 3401,-6131,26039,11107,-4299, 2491,-1633, 1128, -797, 569, -406, 289, -204, 143, -99, 68, -47, 50, 4, + 19, 36, -54, 91, -145, 221, -323, 459, -636, 870,-1182, 1615,-2268, 3410,-6145,25983,11189,-4326, 2506,-1644, 1136, -803, 573, -409, 291, -206, 144, -100, 68, -47, 50, 4, + 19, 36, -55, 91, -145, 221, -324, 459, -637, 871,-1184, 1619,-2274, 3419,-6159,25926,11272,-4352, 2522,-1654, 1143, -808, 577, -412, 293, -207, 145, -100, 69, -48, 50, 4, + 19, 36, -55, 91, -146, 222, -324, 460, -639, 873,-1187, 1623,-2280, 3428,-6173,25869,11355,-4379, 2537,-1664, 1151, -814, 581, -415, 295, -209, 146, -101, 69, -48, 50, 4, + 19, 37, -55, 92, -146, 222, -325, 461, -640, 875,-1189, 1626,-2285, 3436,-6186,25811,11437,-4405, 2552,-1675, 1158, -820, 585, -418, 297, -210, 147, -102, 69, -48, 50, 4, + 19, 37, -55, 92, -146, 222, -325, 462, -641, 876,-1191, 1630,-2290, 3444,-6200,25754,11520,-4431, 2567,-1685, 1165, -825, 589, -421, 299, -211, 148, -102, 70, -48, 50, 4, + 19, 37, -55, 92, -147, 223, -326, 462, -642, 878,-1194, 1633,-2296, 3453,-6212,25696,11603,-4457, 2582,-1695, 1173, -830, 593, -424, 302, -213, 149, -103, 70, -48, 51, 4, + 19, 37, -55, 92, -147, 223, -326, 463, -643, 879,-1196, 1637,-2301, 3461,-6225,25637,11686,-4483, 2597,-1705, 1180, -836, 597, -427, 304, -214, 150, -104, 70, -49, 51, 4, + 19, 37, -56, 92, -147, 223, -327, 464, -644, 881,-1198, 1640,-2306, 3468,-6237,25579,11769,-4509, 2612,-1715, 1187, -841, 601, -430, 306, -216, 151, -104, 71, -49, 51, 4, + 18, 37, -56, 93, -147, 224, -327, 464, -645, 882,-1200, 1643,-2311, 3476,-6249,25520,11852,-4535, 2627,-1725, 1195, -847, 605, -433, 308, -217, 152, -105, 71, -49, 51, 5, + 18, 38, -56, 93, -148, 224, -328, 465, -646, 884,-1203, 1647,-2316, 3484,-6261,25461,11934,-4560, 2641,-1735, 1202, -852, 609, -435, 310, -219, 153, -105, 72, -49, 51, 5, + 18, 38, -56, 93, -148, 224, -328, 466, -647, 885,-1205, 1650,-2320, 3491,-6272,25402,12017,-4586, 2656,-1745, 1209, -857, 613, -438, 312, -220, 154, -106, 72, -49, 51, 5, + 18, 38, -56, 93, -148, 225, -328, 466, -648, 887,-1207, 1653,-2325, 3498,-6284,25342,12100,-4611, 2671,-1755, 1216, -863, 617, -441, 314, -222, 155, -107, 72, -50, 51, 5, + 18, 38, -56, 93, -148, 225, -329, 467, -649, 888,-1209, 1656,-2330, 3505,-6294,25282,12183,-4637, 2685,-1765, 1223, -868, 621, -444, 316, -223, 156, -107, 73, -50, 51, 5, + 18, 38, -57, 93, -148, 225, -329, 467, -649, 889,-1211, 1659,-2334, 3512,-6305,25222,12266,-4662, 2700,-1775, 1230, -873, 625, -447, 318, -225, 157, -108, 73, -50, 51, 5, + 18, 38, -57, 94, -149, 226, -330, 468, -650, 890,-1213, 1662,-2339, 3519,-6315,25162,12349,-4687, 2714,-1785, 1238, -878, 629, -450, 320, -226, 158, -108, 73, -50, 51, 5, + 18, 39, -57, 94, -149, 226, -330, 469, -651, 892,-1214, 1665,-2343, 3526,-6325,25101,12432,-4712, 2728,-1794, 1245, -883, 632, -453, 322, -227, 159, -109, 74, -50, 51, 5, + 18, 39, -57, 94, -149, 226, -330, 469, -652, 893,-1216, 1667,-2347, 3532,-6335,25040,12515,-4736, 2742,-1804, 1251, -889, 636, -455, 324, -229, 160, -110, 74, -51, 51, 5, + 17, 39, -57, 94, -149, 226, -331, 470, -653, 894,-1218, 1670,-2351, 3539,-6345,24979,12598,-4761, 2756,-1813, 1258, -894, 640, -458, 326, -230, 160, -110, 74, -51, 51, 5, + 17, 39, -57, 94, -149, 227, -331, 470, -653, 895,-1220, 1673,-2355, 3545,-6354,24917,12681,-4786, 2770,-1823, 1265, -899, 644, -461, 328, -232, 161, -111, 75, -51, 51, 5, + 17, 39, -57, 94, -150, 227, -331, 471, -654, 896,-1221, 1675,-2359, 3551,-6363,24855,12764,-4810, 2784,-1832, 1272, -904, 648, -464, 330, -233, 162, -111, 75, -51, 51, 5, + 17, 39, -57, 95, -150, 227, -332, 471, -655, 897,-1223, 1678,-2363, 3557,-6372,24793,12848,-4834, 2798,-1842, 1279, -909, 651, -466, 332, -234, 163, -112, 76, -51, 51, 5, + 17, 40, -58, 95, -150, 227, -332, 471, -655, 898,-1224, 1680,-2367, 3563,-6380,24731,12931,-4859, 2812,-1851, 1286, -914, 655, -469, 334, -236, 164, -113, 76, -51, 51, 5, + 17, 40, -58, 95, -150, 227, -332, 472, -656, 899,-1226, 1682,-2370, 3568,-6388,24669,13014,-4883, 2825,-1860, 1292, -919, 659, -472, 336, -237, 165, -113, 76, -52, 51, 5, + 17, 40, -58, 95, -150, 228, -333, 472, -657, 900,-1227, 1685,-2374, 3574,-6396,24606,13097,-4907, 2839,-1869, 1299, -924, 662, -475, 338, -238, 166, -114, 77, -52, 51, 5, + 17, 40, -58, 95, -151, 228, -333, 473, -657, 901,-1229, 1687,-2377, 3579,-6404,24543,13180,-4930, 2853,-1879, 1306, -929, 666, -477, 340, -240, 167, -114, 77, -52, 51, 5, + 17, 40, -58, 95, -151, 228, -333, 473, -658, 902,-1230, 1689,-2380, 3584,-6411,24479,13263,-4954, 2866,-1888, 1312, -934, 670, -480, 342, -241, 168, -115, 77, -52, 51, 5, + 17, 40, -58, 95, -151, 228, -333, 473, -658, 903,-1231, 1691,-2384, 3589,-6418,24416,13346,-4977, 2879,-1897, 1319, -939, 673, -483, 344, -242, 169, -115, 78, -52, 51, 5, + 16, 41, -58, 95, -151, 228, -333, 474, -659, 903,-1233, 1693,-2387, 3594,-6425,24352,13429,-5001, 2892,-1906, 1325, -943, 677, -485, 346, -244, 170, -116, 78, -53, 51, 5, + 16, 41, -58, 96, -151, 229, -334, 474, -659, 904,-1234, 1695,-2390, 3599,-6431,24288,13512,-5024, 2906,-1915, 1332, -948, 681, -488, 348, -245, 170, -117, 78, -53, 51, 6, + 16, 41, -59, 96, -151, 229, -334, 474, -660, 905,-1235, 1697,-2393, 3603,-6438,24224,13595,-5047, 2919,-1923, 1338, -953, 684, -491, 350, -246, 171, -117, 79, -53, 51, 6, + 16, 41, -59, 96, -151, 229, -334, 474, -660, 906,-1236, 1698,-2396, 3608,-6443,24159,13678,-5070, 2932,-1932, 1345, -958, 688, -493, 351, -248, 172, -118, 79, -53, 51, 6, + 16, 41, -59, 96, -151, 229, -334, 475, -660, 906,-1237, 1700,-2398, 3612,-6449,24094,13761,-5093, 2944,-1941, 1351, -962, 691, -496, 353, -249, 173, -118, 79, -53, 51, 6, + 16, 41, -59, 96, -152, 229, -334, 475, -661, 907,-1238, 1702,-2401, 3616,-6455,24029,13844,-5116, 2957,-1950, 1357, -967, 695, -498, 355, -250, 174, -119, 80, -53, 51, 6, + 16, 41, -59, 96, -152, 229, -335, 475, -661, 907,-1239, 1703,-2403, 3620,-6460,23964,13927,-5138, 2970,-1958, 1363, -972, 698, -501, 357, -252, 175, -119, 80, -54, 51, 6, + 16, 42, -59, 96, -152, 229, -335, 475, -661, 908,-1240, 1705,-2406, 3624,-6465,23898,14010,-5161, 2982,-1967, 1370, -976, 702, -503, 359, -253, 176, -120, 80, -54, 51, 6, + 16, 42, -59, 96, -152, 229, -335, 475, -662, 908,-1241, 1706,-2408, 3628,-6469,23833,14093,-5183, 2995,-1975, 1376, -981, 705, -506, 361, -254, 177, -120, 80, -54, 51, 6, + 16, 42, -59, 96, -152, 229, -335, 476, -662, 909,-1242, 1708,-2411, 3631,-6474,23767,14176,-5205, 3007,-1984, 1382, -986, 708, -509, 362, -255, 177, -121, 81, -54, 51, 6, + 15, 42, -59, 97, -152, 230, -335, 476, -662, 909,-1243, 1709,-2413, 3635,-6478,23700,14258,-5227, 3020,-1992, 1388, -990, 712, -511, 364, -257, 178, -121, 81, -54, 51, 6, + 15, 42, -59, 97, -152, 230, -335, 476, -662, 910,-1243, 1710,-2415, 3638,-6482,23634,14341,-5249, 3032,-2000, 1394, -995, 715, -513, 366, -258, 179, -122, 81, -54, 51, 6, + 15, 42, -59, 97, -152, 230, -335, 476, -663, 910,-1244, 1711,-2417, 3641,-6485,23567,14424,-5271, 3044,-2008, 1400, -999, 718, -516, 368, -259, 180, -123, 82, -55, 51, 6, + 15, 42, -60, 97, -152, 230, -335, 476, -663, 910,-1245, 1713,-2419, 3644,-6489,23500,14507,-5292, 3056,-2017, 1406,-1003, 722, -518, 370, -260, 181, -123, 82, -55, 51, 6, + 15, 43, -60, 97, -152, 230, -335, 476, -663, 911,-1245, 1714,-2420, 3647,-6492,23433,14590,-5314, 3068,-2025, 1412,-1008, 725, -521, 371, -262, 182, -124, 82, -55, 51, 6, + 15, 43, -60, 97, -152, 230, -335, 476, -663, 911,-1246, 1715,-2422, 3649,-6494,23365,14672,-5335, 3080,-2033, 1418,-1012, 728, -523, 373, -263, 182, -124, 83, -55, 51, 6, + 15, 43, -60, 97, -152, 230, -335, 476, -663, 911,-1246, 1715,-2424, 3652,-6497,23298,14755,-5356, 3091,-2041, 1423,-1017, 732, -526, 375, -264, 183, -125, 83, -55, 51, 6, + 15, 43, -60, 97, -152, 230, -335, 476, -663, 911,-1247, 1716,-2425, 3654,-6499,23230,14838,-5377, 3103,-2048, 1429,-1021, 735, -528, 377, -265, 184, -125, 83, -55, 51, 6, + 15, 43, -60, 97, -152, 230, -335, 476, -663, 912,-1247, 1717,-2426, 3656,-6501,23162,14920,-5398, 3114,-2056, 1435,-1025, 738, -530, 378, -266, 185, -126, 83, -55, 51, 6, + 15, 43, -60, 97, -152, 230, -335, 476, -663, 912,-1247, 1718,-2428, 3658,-6503,23094,15003,-5418, 3126,-2064, 1440,-1029, 741, -533, 380, -268, 186, -126, 84, -56, 51, 7, + 15, 43, -60, 97, -152, 230, -335, 476, -663, 912,-1247, 1718,-2429, 3660,-6505,23025,15085,-5439, 3137,-2072, 1446,-1034, 744, -535, 382, -269, 186, -127, 84, -56, 51, 7, + 14, 44, -60, 97, -152, 230, -335, 476, -663, 912,-1248, 1719,-2430, 3662,-6506,22956,15168,-5459, 3148,-2079, 1452,-1038, 747, -537, 383, -270, 187, -127, 84, -56, 51, 7, + 14, 44, -60, 97, -152, 230, -335, 476, -663, 912,-1248, 1719,-2431, 3664,-6507,22887,15250,-5479, 3159,-2087, 1457,-1042, 750, -540, 385, -271, 188, -128, 85, -56, 51, 7, + 14, 44, -60, 97, -152, 230, -335, 476, -663, 912,-1248, 1720,-2432, 3665,-6508,22818,15332,-5499, 3170,-2094, 1463,-1046, 754, -542, 387, -272, 189, -128, 85, -56, 51, 7, + 14, 44, -60, 97, -152, 230, -335, 476, -663, 912,-1248, 1720,-2433, 3667,-6508,22749,15415,-5519, 3181,-2102, 1468,-1050, 757, -544, 388, -273, 189, -128, 85, -56, 51, 7, + 14, 44, -60, 97, -152, 230, -335, 476, -663, 912,-1248, 1721,-2433, 3668,-6508,22679,15497,-5539, 3192,-2109, 1473,-1054, 760, -546, 390, -275, 190, -129, 85, -56, 51, 7, + 14, 44, -60, 97, -152, 230, -335, 475, -662, 911,-1248, 1721,-2434, 3669,-6508,22609,15579,-5558, 3203,-2116, 1479,-1058, 763, -549, 391, -276, 191, -129, 86, -57, 51, 7, + 14, 44, -60, 97, -152, 229, -334, 475, -662, 911,-1248, 1721,-2435, 3670,-6508,22539,15661,-5577, 3213,-2123, 1484,-1062, 766, -551, 393, -277, 192, -130, 86, -57, 51, 7, + 14, 44, -61, 97, -152, 229, -334, 475, -662, 911,-1248, 1721,-2435, 3670,-6507,22469,15744,-5597, 3224,-2130, 1489,-1066, 768, -553, 395, -278, 192, -130, 86, -57, 51, 7, + 14, 45, -61, 97, -152, 229, -334, 475, -662, 911,-1248, 1721,-2435, 3671,-6507,22398,15826,-5616, 3234,-2137, 1494,-1070, 771, -555, 396, -279, 193, -131, 86, -57, 51, 7, + 14, 45, -61, 97, -152, 229, -334, 475, -661, 911,-1248, 1721,-2436, 3672,-6506,22328,15908,-5634, 3244,-2144, 1499,-1073, 774, -557, 398, -280, 194, -131, 87, -57, 51, 7, + 14, 45, -61, 97, -152, 229, -334, 474, -661, 910,-1247, 1721,-2436, 3672,-6504,22257,15989,-5653, 3255,-2151, 1504,-1077, 777, -559, 399, -281, 195, -132, 87, -57, 51, 7, + 13, 45, -61, 97, -152, 229, -334, 474, -661, 910,-1247, 1721,-2436, 3672,-6503,22186,16071,-5671, 3265,-2158, 1509,-1081, 780, -562, 401, -282, 195, -132, 87, -57, 50, 7, + 13, 45, -61, 97, -152, 229, -333, 474, -661, 909,-1247, 1721,-2436, 3672,-6501,22114,16153,-5690, 3275,-2165, 1514,-1085, 783, -564, 402, -283, 196, -133, 87, -57, 50, 7, + 13, 45, -61, 97, -152, 229, -333, 473, -660, 909,-1246, 1720,-2436, 3672,-6499,22043,16235,-5708, 3284,-2171, 1519,-1088, 786, -566, 404, -284, 197, -133, 88, -58, 50, 7, + 13, 45, -61, 97, -152, 229, -333, 473, -660, 909,-1246, 1720,-2435, 3672,-6497,21971,16317,-5726, 3294,-2178, 1524,-1092, 788, -568, 405, -285, 197, -133, 88, -58, 50, 8, + 13, 45, -61, 97, -152, 228, -333, 473, -659, 908,-1245, 1719,-2435, 3671,-6494,21899,16398,-5744, 3304,-2184, 1529,-1096, 791, -570, 407, -286, 198, -134, 88, -58, 50, 8, + 13, 45, -61, 97, -152, 228, -333, 472, -659, 908,-1245, 1719,-2435, 3671,-6492,21827,16480,-5761, 3313,-2191, 1533,-1099, 794, -572, 408, -287, 199, -134, 88, -58, 50, 8, + 13, 46, -61, 97, -152, 228, -332, 472, -658, 907,-1244, 1718,-2434, 3670,-6489,21755,16561,-5779, 3323,-2197, 1538,-1103, 796, -574, 410, -288, 199, -135, 89, -58, 50, 8, + 13, 46, -61, 97, -152, 228, -332, 472, -658, 906,-1244, 1718,-2434, 3669,-6485,21683,16642,-5796, 3332,-2204, 1543,-1106, 799, -576, 411, -289, 200, -135, 89, -58, 50, 8, + 13, 46, -61, 97, -152, 228, -332, 471, -657, 906,-1243, 1717,-2433, 3669,-6482,21610,16724,-5813, 3341,-2210, 1547,-1110, 802, -578, 413, -290, 201, -136, 89, -58, 50, 8, + 13, 46, -61, 97, -152, 228, -331, 471, -657, 905,-1242, 1716,-2432, 3667,-6478,21537,16805,-5830, 3350,-2216, 1552,-1113, 804, -580, 414, -291, 201, -136, 89, -58, 50, 8, + 13, 46, -61, 97, -151, 227, -331, 470, -656, 905,-1241, 1715,-2431, 3666,-6474,21464,16886,-5847, 3359,-2222, 1556,-1116, 807, -582, 415, -292, 202, -136, 90, -58, 50, 8, + 12, 46, -61, 97, -151, 227, -331, 470, -656, 904,-1241, 1715,-2430, 3665,-6470,21391,16967,-5863, 3368,-2228, 1561,-1120, 809, -583, 417, -293, 203, -137, 90, -59, 50, 8, + 12, 46, -61, 97, -151, 227, -330, 469, -655, 903,-1240, 1714,-2429, 3663,-6466,21317,17048,-5880, 3377,-2234, 1565,-1123, 812, -585, 418, -294, 203, -137, 90, -59, 50, 8, + 12, 46, -61, 97, -151, 227, -330, 469, -654, 902,-1239, 1713,-2428, 3662,-6461,21244,17129,-5896, 3385,-2240, 1569,-1126, 814, -587, 419, -295, 204, -137, 90, -59, 50, 8, + 12, 46, -61, 97, -151, 227, -330, 468, -654, 901,-1238, 1711,-2427, 3660,-6456,21170,17210,-5912, 3394,-2245, 1573,-1130, 817, -589, 421, -296, 205, -138, 90, -59, 50, 8, + 12, 46, -61, 97, -151, 226, -329, 468, -653, 901,-1237, 1710,-2425, 3658,-6451,21096,17290,-5928, 3402,-2251, 1578,-1133, 819, -591, 422, -297, 205, -138, 91, -59, 50, 8, + 12, 47, -61, 97, -151, 226, -329, 467, -652, 900,-1236, 1709,-2424, 3656,-6445,21022,17371,-5943, 3410,-2257, 1582,-1136, 822, -593, 423, -298, 206, -139, 91, -59, 50, 8, + 12, 47, -61, 97, -151, 226, -329, 467, -652, 899,-1235, 1708,-2422, 3654,-6440,20948,17451,-5959, 3418,-2262, 1586,-1139, 824, -594, 425, -299, 206, -139, 91, -59, 50, 8, + 12, 47, -61, 97, -150, 226, -328, 466, -651, 898,-1234, 1706,-2421, 3651,-6434,20873,17532,-5974, 3426,-2267, 1590,-1142, 826, -596, 426, -300, 207, -139, 91, -59, 50, 9, + 12, 47, -61, 97, -150, 225, -328, 466, -650, 897,-1232, 1705,-2419, 3649,-6428,20799,17612,-5989, 3434,-2273, 1594,-1145, 829, -598, 427, -301, 208, -140, 91, -59, 50, 9, + 12, 47, -61, 97, -150, 225, -327, 465, -649, 896,-1231, 1704,-2417, 3646,-6421,20724,17692,-6004, 3442,-2278, 1598,-1148, 831, -600, 428, -302, 208, -140, 92, -59, 50, 9, + 12, 47, -61, 97, -150, 225, -327, 464, -648, 895,-1230, 1702,-2415, 3644,-6415,20649,17772,-6018, 3450,-2283, 1602,-1151, 833, -601, 430, -302, 209, -140, 92, -59, 50, 9, + 12, 47, -61, 97, -150, 224, -326, 464, -647, 894,-1228, 1700,-2413, 3641,-6408,20574,17852,-6033, 3457,-2288, 1605,-1154, 835, -603, 431, -303, 209, -141, 92, -60, 50, 9, + 11, 47, -61, 97, -150, 224, -326, 463, -647, 893,-1227, 1699,-2411, 3638,-6401,20499,17932,-6047, 3464,-2293, 1609,-1157, 838, -605, 432, -304, 210, -141, 92, -60, 50, 9, + 11, 47, -61, 96, -149, 224, -325, 462, -646, 891,-1226, 1697,-2409, 3635,-6394,20423,18012,-6061, 3472,-2298, 1613,-1160, 840, -606, 433, -305, 210, -141, 92, -60, 50, 9, + 11, 47, -61, 96, -149, 223, -325, 462, -645, 890,-1224, 1695,-2407, 3631,-6386,20347,18092,-6075, 3479,-2303, 1616,-1162, 842, -608, 434, -306, 211, -142, 93, -60, 49, 9, + 11, 47, -61, 96, -149, 223, -324, 461, -644, 889,-1223, 1693,-2404, 3628,-6379,20272,18171,-6089, 3486,-2308, 1620,-1165, 844, -609, 436, -307, 211, -142, 93, -60, 49, 9, + 11, 48, -61, 96, -149, 223, -324, 460, -643, 888,-1221, 1691,-2402, 3624,-6371,20196,18251,-6102, 3493,-2313, 1623,-1168, 846, -611, 437, -307, 212, -142, 93, -60, 49, 9, + 11, 48, -61, 96, -149, 222, -323, 460, -642, 886,-1220, 1689,-2399, 3621,-6363,20120,18330,-6115, 3500,-2317, 1627,-1170, 848, -612, 438, -308, 212, -143, 93, -60, 49, 9, + 11, 48, -61, 96, -149, 222, -323, 459, -641, 885,-1218, 1687,-2397, 3617,-6354,20043,18409,-6128, 3506,-2322, 1630,-1173, 850, -614, 439, -309, 213, -143, 93, -60, 49, 9, + 11, 48, -61, 96, -148, 222, -322, 458, -640, 884,-1216, 1685,-2394, 3613,-6346,19967,18488,-6141, 3513,-2326, 1634,-1176, 852, -616, 440, -310, 214, -143, 93, -60, 49, 9, + 11, 48, -61, 96, -148, 221, -322, 457, -639, 882,-1214, 1683,-2391, 3609,-6337,19890,18567,-6154, 3519,-2330, 1637,-1178, 854, -617, 441, -311, 214, -144, 94, -60, 49, 9, + 11, 48, -61, 96, -148, 221, -321, 456, -638, 881,-1213, 1681,-2388, 3604,-6328,19814,18646,-6166, 3526,-2335, 1640,-1181, 856, -618, 442, -311, 214, -144, 94, -60, 49, 10, + 11, 48, -61, 96, -148, 221, -321, 456, -636, 880,-1211, 1679,-2385, 3600,-6319,19737,18725,-6179, 3532,-2339, 1643,-1183, 858, -620, 443, -312, 215, -144, 94, -60, 49, 10, + 11, 48, -61, 96, -147, 220, -320, 455, -635, 878,-1209, 1676,-2382, 3596,-6309,19660,18804,-6191, 3538,-2343, 1646,-1185, 860, -621, 444, -313, 215, -145, 94, -60, 49, 10, + 10, 48, -61, 95, -147, 220, -319, 454, -634, 877,-1207, 1674,-2379, 3591,-6299,19583,18882,-6202, 3544,-2347, 1649,-1188, 861, -623, 445, -313, 216, -145, 94, -60, 49, 10, + 10, 48, -61, 95, -147, 219, -319, 453, -633, 875,-1205, 1671,-2376, 3586,-6289,19505,18961,-6214, 3549,-2351, 1652,-1190, 863, -624, 446, -314, 216, -145, 94, -60, 49, 10, + 10, 48, -61, 95, -147, 219, -318, 452, -632, 873,-1203, 1669,-2373, 3581,-6279,19428,19039,-6225, 3555,-2355, 1655,-1192, 865, -625, 447, -315, 217, -145, 94, -61, 49, 10, + 10, 48, -61, 95, -146, 219, -318, 451, -631, 872,-1201, 1666,-2369, 3576,-6269,19350,19117,-6237, 3561,-2359, 1658,-1195, 867, -627, 448, -316, 217, -146, 95, -61, 49, 10, + 10, 49, -61, 95, -146, 218, -317, 450, -629, 870,-1199, 1664,-2366, 3571,-6258,19273,19195,-6248, 3566,-2362, 1661,-1197, 868, -628, 449, -316, 218, -146, 95, -61, 49, 10, + 10, 49, -61, 95, -146, 218, -316, 449, -628, 868,-1197, 1661,-2362, 3566,-6248,19195,19273,-6258, 3571,-2366, 1664,-1199, 870, -629, 450, -317, 218, -146, 95, -61, 49, 10, + 10, 49, -61, 95, -146, 217, -316, 448, -627, 867,-1195, 1658,-2359, 3561,-6237,19117,19350,-6269, 3576,-2369, 1666,-1201, 872, -631, 451, -318, 219, -146, 95, -61, 48, 10, + 10, 49, -61, 94, -145, 217, -315, 447, -625, 865,-1192, 1655,-2355, 3555,-6225,19039,19428,-6279, 3581,-2373, 1669,-1203, 873, -632, 452, -318, 219, -147, 95, -61, 48, 10, + 10, 49, -60, 94, -145, 216, -314, 446, -624, 863,-1190, 1652,-2351, 3549,-6214,18961,19505,-6289, 3586,-2376, 1671,-1205, 875, -633, 453, -319, 219, -147, 95, -61, 48, 10, + 10, 49, -60, 94, -145, 216, -313, 445, -623, 861,-1188, 1649,-2347, 3544,-6202,18882,19583,-6299, 3591,-2379, 1674,-1207, 877, -634, 454, -319, 220, -147, 95, -61, 48, 10, + 10, 49, -60, 94, -145, 215, -313, 444, -621, 860,-1185, 1646,-2343, 3538,-6191,18804,19660,-6309, 3596,-2382, 1676,-1209, 878, -635, 455, -320, 220, -147, 96, -61, 48, 11, + 10, 49, -60, 94, -144, 215, -312, 443, -620, 858,-1183, 1643,-2339, 3532,-6179,18725,19737,-6319, 3600,-2385, 1679,-1211, 880, -636, 456, -321, 221, -148, 96, -61, 48, 11, + 10, 49, -60, 94, -144, 214, -311, 442, -618, 856,-1181, 1640,-2335, 3526,-6166,18646,19814,-6328, 3604,-2388, 1681,-1213, 881, -638, 456, -321, 221, -148, 96, -61, 48, 11, + 9, 49, -60, 94, -144, 214, -311, 441, -617, 854,-1178, 1637,-2330, 3519,-6154,18567,19890,-6337, 3609,-2391, 1683,-1214, 882, -639, 457, -322, 221, -148, 96, -61, 48, 11, + 9, 49, -60, 93, -143, 214, -310, 440, -616, 852,-1176, 1634,-2326, 3513,-6141,18488,19967,-6346, 3613,-2394, 1685,-1216, 884, -640, 458, -322, 222, -148, 96, -61, 48, 11, + 9, 49, -60, 93, -143, 213, -309, 439, -614, 850,-1173, 1630,-2322, 3506,-6128,18409,20043,-6354, 3617,-2397, 1687,-1218, 885, -641, 459, -323, 222, -149, 96, -61, 48, 11, + 9, 49, -60, 93, -143, 212, -308, 438, -612, 848,-1170, 1627,-2317, 3500,-6115,18330,20120,-6363, 3621,-2399, 1689,-1220, 886, -642, 460, -323, 222, -149, 96, -61, 48, 11, + 9, 49, -60, 93, -142, 212, -307, 437, -611, 846,-1168, 1623,-2313, 3493,-6102,18251,20196,-6371, 3624,-2402, 1691,-1221, 888, -643, 460, -324, 223, -149, 96, -61, 48, 11, + 9, 49, -60, 93, -142, 211, -307, 436, -609, 844,-1165, 1620,-2308, 3486,-6089,18171,20272,-6379, 3628,-2404, 1693,-1223, 889, -644, 461, -324, 223, -149, 96, -61, 47, 11, + 9, 49, -60, 93, -142, 211, -306, 434, -608, 842,-1162, 1616,-2303, 3479,-6075,18092,20347,-6386, 3631,-2407, 1695,-1224, 890, -645, 462, -325, 223, -149, 96, -61, 47, 11, + 9, 50, -60, 92, -141, 210, -305, 433, -606, 840,-1160, 1613,-2298, 3472,-6061,18012,20423,-6394, 3635,-2409, 1697,-1226, 891, -646, 462, -325, 224, -149, 96, -61, 47, 11, + 9, 50, -60, 92, -141, 210, -304, 432, -605, 838,-1157, 1609,-2293, 3464,-6047,17932,20499,-6401, 3638,-2411, 1699,-1227, 893, -647, 463, -326, 224, -150, 97, -61, 47, 11, + 9, 50, -60, 92, -141, 209, -303, 431, -603, 835,-1154, 1605,-2288, 3457,-6033,17852,20574,-6408, 3641,-2413, 1700,-1228, 894, -647, 464, -326, 224, -150, 97, -61, 47, 12, + 9, 50, -59, 92, -140, 209, -302, 430, -601, 833,-1151, 1602,-2283, 3450,-6018,17772,20649,-6415, 3644,-2415, 1702,-1230, 895, -648, 464, -327, 225, -150, 97, -61, 47, 12, + 9, 50, -59, 92, -140, 208, -302, 428, -600, 831,-1148, 1598,-2278, 3442,-6004,17692,20724,-6421, 3646,-2417, 1704,-1231, 896, -649, 465, -327, 225, -150, 97, -61, 47, 12, + 9, 50, -59, 91, -140, 208, -301, 427, -598, 829,-1145, 1594,-2273, 3434,-5989,17612,20799,-6428, 3649,-2419, 1705,-1232, 897, -650, 466, -328, 225, -150, 97, -61, 47, 12, + 9, 50, -59, 91, -139, 207, -300, 426, -596, 826,-1142, 1590,-2267, 3426,-5974,17532,20873,-6434, 3651,-2421, 1706,-1234, 898, -651, 466, -328, 226, -150, 97, -61, 47, 12, + 8, 50, -59, 91, -139, 206, -299, 425, -594, 824,-1139, 1586,-2262, 3418,-5959,17451,20948,-6440, 3654,-2422, 1708,-1235, 899, -652, 467, -329, 226, -151, 97, -61, 47, 12, + 8, 50, -59, 91, -139, 206, -298, 423, -593, 822,-1136, 1582,-2257, 3410,-5943,17371,21022,-6445, 3656,-2424, 1709,-1236, 900, -652, 467, -329, 226, -151, 97, -61, 47, 12, + 8, 50, -59, 91, -138, 205, -297, 422, -591, 819,-1133, 1578,-2251, 3402,-5928,17290,21096,-6451, 3658,-2425, 1710,-1237, 901, -653, 468, -329, 226, -151, 97, -61, 46, 12, + 8, 50, -59, 90, -138, 205, -296, 421, -589, 817,-1130, 1573,-2245, 3394,-5912,17210,21170,-6456, 3660,-2427, 1711,-1238, 901, -654, 468, -330, 227, -151, 97, -61, 46, 12, + 8, 50, -59, 90, -137, 204, -295, 419, -587, 814,-1126, 1569,-2240, 3385,-5896,17129,21244,-6461, 3662,-2428, 1713,-1239, 902, -654, 469, -330, 227, -151, 97, -61, 46, 12, + 8, 50, -59, 90, -137, 203, -294, 418, -585, 812,-1123, 1565,-2234, 3377,-5880,17048,21317,-6466, 3663,-2429, 1714,-1240, 903, -655, 469, -330, 227, -151, 97, -61, 46, 12, + 8, 50, -59, 90, -137, 203, -293, 417, -583, 809,-1120, 1561,-2228, 3368,-5863,16967,21391,-6470, 3665,-2430, 1715,-1241, 904, -656, 470, -331, 227, -151, 97, -61, 46, 12, + 8, 50, -58, 90, -136, 202, -292, 415, -582, 807,-1116, 1556,-2222, 3359,-5847,16886,21464,-6474, 3666,-2431, 1715,-1241, 905, -656, 470, -331, 227, -151, 97, -61, 46, 13, + 8, 50, -58, 89, -136, 201, -291, 414, -580, 804,-1113, 1552,-2216, 3350,-5830,16805,21537,-6478, 3667,-2432, 1716,-1242, 905, -657, 471, -331, 228, -152, 97, -61, 46, 13, + 8, 50, -58, 89, -136, 201, -290, 413, -578, 802,-1110, 1547,-2210, 3341,-5813,16724,21610,-6482, 3669,-2433, 1717,-1243, 906, -657, 471, -332, 228, -152, 97, -61, 46, 13, + 8, 50, -58, 89, -135, 200, -289, 411, -576, 799,-1106, 1543,-2204, 3332,-5796,16642,21683,-6485, 3669,-2434, 1718,-1244, 906, -658, 472, -332, 228, -152, 97, -61, 46, 13, + 8, 50, -58, 89, -135, 199, -288, 410, -574, 796,-1103, 1538,-2197, 3323,-5779,16561,21755,-6489, 3670,-2434, 1718,-1244, 907, -658, 472, -332, 228, -152, 97, -61, 46, 13, + 8, 50, -58, 88, -134, 199, -287, 408, -572, 794,-1099, 1533,-2191, 3313,-5761,16480,21827,-6492, 3671,-2435, 1719,-1245, 908, -659, 472, -333, 228, -152, 97, -61, 45, 13, + 8, 50, -58, 88, -134, 198, -286, 407, -570, 791,-1096, 1529,-2184, 3304,-5744,16398,21899,-6494, 3671,-2435, 1719,-1245, 908, -659, 473, -333, 228, -152, 97, -61, 45, 13, + 8, 50, -58, 88, -133, 197, -285, 405, -568, 788,-1092, 1524,-2178, 3294,-5726,16317,21971,-6497, 3672,-2435, 1720,-1246, 909, -660, 473, -333, 229, -152, 97, -61, 45, 13, + 7, 50, -58, 88, -133, 197, -284, 404, -566, 786,-1088, 1519,-2171, 3284,-5708,16235,22043,-6499, 3672,-2436, 1720,-1246, 909, -660, 473, -333, 229, -152, 97, -61, 45, 13, + 7, 50, -57, 87, -133, 196, -283, 402, -564, 783,-1085, 1514,-2165, 3275,-5690,16153,22114,-6501, 3672,-2436, 1721,-1247, 909, -661, 474, -333, 229, -152, 97, -61, 45, 13, + 7, 50, -57, 87, -132, 195, -282, 401, -562, 780,-1081, 1509,-2158, 3265,-5671,16071,22186,-6503, 3672,-2436, 1721,-1247, 910, -661, 474, -334, 229, -152, 97, -61, 45, 13, + 7, 51, -57, 87, -132, 195, -281, 399, -559, 777,-1077, 1504,-2151, 3255,-5653,15989,22257,-6504, 3672,-2436, 1721,-1247, 910, -661, 474, -334, 229, -152, 97, -61, 45, 14, + 7, 51, -57, 87, -131, 194, -280, 398, -557, 774,-1073, 1499,-2144, 3244,-5634,15908,22328,-6506, 3672,-2436, 1721,-1248, 911, -661, 475, -334, 229, -152, 97, -61, 45, 14, + 7, 51, -57, 86, -131, 193, -279, 396, -555, 771,-1070, 1494,-2137, 3234,-5616,15826,22398,-6507, 3671,-2435, 1721,-1248, 911, -662, 475, -334, 229, -152, 97, -61, 45, 14, + 7, 51, -57, 86, -130, 192, -278, 395, -553, 768,-1066, 1489,-2130, 3224,-5597,15744,22469,-6507, 3670,-2435, 1721,-1248, 911, -662, 475, -334, 229, -152, 97, -61, 44, 14, + 7, 51, -57, 86, -130, 192, -277, 393, -551, 766,-1062, 1484,-2123, 3213,-5577,15661,22539,-6508, 3670,-2435, 1721,-1248, 911, -662, 475, -334, 229, -152, 97, -60, 44, 14, + 7, 51, -57, 86, -129, 191, -276, 391, -549, 763,-1058, 1479,-2116, 3203,-5558,15579,22609,-6508, 3669,-2434, 1721,-1248, 911, -662, 475, -335, 230, -152, 97, -60, 44, 14, + 7, 51, -56, 85, -129, 190, -275, 390, -546, 760,-1054, 1473,-2109, 3192,-5539,15497,22679,-6508, 3668,-2433, 1721,-1248, 912, -663, 476, -335, 230, -152, 97, -60, 44, 14, + 7, 51, -56, 85, -128, 189, -273, 388, -544, 757,-1050, 1468,-2102, 3181,-5519,15415,22749,-6508, 3667,-2433, 1720,-1248, 912, -663, 476, -335, 230, -152, 97, -60, 44, 14, + 7, 51, -56, 85, -128, 189, -272, 387, -542, 754,-1046, 1463,-2094, 3170,-5499,15332,22818,-6508, 3665,-2432, 1720,-1248, 912, -663, 476, -335, 230, -152, 97, -60, 44, 14, + 7, 51, -56, 85, -128, 188, -271, 385, -540, 750,-1042, 1457,-2087, 3159,-5479,15250,22887,-6507, 3664,-2431, 1719,-1248, 912, -663, 476, -335, 230, -152, 97, -60, 44, 14, + 7, 51, -56, 84, -127, 187, -270, 383, -537, 747,-1038, 1452,-2079, 3148,-5459,15168,22956,-6506, 3662,-2430, 1719,-1248, 912, -663, 476, -335, 230, -152, 97, -60, 44, 14, + 7, 51, -56, 84, -127, 186, -269, 382, -535, 744,-1034, 1446,-2072, 3137,-5439,15085,23025,-6505, 3660,-2429, 1718,-1247, 912, -663, 476, -335, 230, -152, 97, -60, 43, 15, + 7, 51, -56, 84, -126, 186, -268, 380, -533, 741,-1029, 1440,-2064, 3126,-5418,15003,23094,-6503, 3658,-2428, 1718,-1247, 912, -663, 476, -335, 230, -152, 97, -60, 43, 15, + 6, 51, -55, 83, -126, 185, -266, 378, -530, 738,-1025, 1435,-2056, 3114,-5398,14920,23162,-6501, 3656,-2426, 1717,-1247, 912, -663, 476, -335, 230, -152, 97, -60, 43, 15, + 6, 51, -55, 83, -125, 184, -265, 377, -528, 735,-1021, 1429,-2048, 3103,-5377,14838,23230,-6499, 3654,-2425, 1716,-1247, 911, -663, 476, -335, 230, -152, 97, -60, 43, 15, + 6, 51, -55, 83, -125, 183, -264, 375, -526, 732,-1017, 1423,-2041, 3091,-5356,14755,23298,-6497, 3652,-2424, 1715,-1246, 911, -663, 476, -335, 230, -152, 97, -60, 43, 15, + 6, 51, -55, 83, -124, 182, -263, 373, -523, 728,-1012, 1418,-2033, 3080,-5335,14672,23365,-6494, 3649,-2422, 1715,-1246, 911, -663, 476, -335, 230, -152, 97, -60, 43, 15, + 6, 51, -55, 82, -124, 182, -262, 371, -521, 725,-1008, 1412,-2025, 3068,-5314,14590,23433,-6492, 3647,-2420, 1714,-1245, 911, -663, 476, -335, 230, -152, 97, -60, 43, 15, + 6, 51, -55, 82, -123, 181, -260, 370, -518, 722,-1003, 1406,-2017, 3056,-5292,14507,23500,-6489, 3644,-2419, 1713,-1245, 910, -663, 476, -335, 230, -152, 97, -60, 42, 15, + 6, 51, -55, 82, -123, 180, -259, 368, -516, 718, -999, 1400,-2008, 3044,-5271,14424,23567,-6485, 3641,-2417, 1711,-1244, 910, -663, 476, -335, 230, -152, 97, -59, 42, 15, + 6, 51, -54, 81, -122, 179, -258, 366, -513, 715, -995, 1394,-2000, 3032,-5249,14341,23634,-6482, 3638,-2415, 1710,-1243, 910, -662, 476, -335, 230, -152, 97, -59, 42, 15, + 6, 51, -54, 81, -121, 178, -257, 364, -511, 712, -990, 1388,-1992, 3020,-5227,14258,23700,-6478, 3635,-2413, 1709,-1243, 909, -662, 476, -335, 230, -152, 97, -59, 42, 15, + 6, 51, -54, 81, -121, 177, -255, 362, -509, 708, -986, 1382,-1984, 3007,-5205,14176,23767,-6474, 3631,-2411, 1708,-1242, 909, -662, 476, -335, 229, -152, 96, -59, 42, 16, + 6, 51, -54, 80, -120, 177, -254, 361, -506, 705, -981, 1376,-1975, 2995,-5183,14093,23833,-6469, 3628,-2408, 1706,-1241, 908, -662, 475, -335, 229, -152, 96, -59, 42, 16, + 6, 51, -54, 80, -120, 176, -253, 359, -503, 702, -976, 1370,-1967, 2982,-5161,14010,23898,-6465, 3624,-2406, 1705,-1240, 908, -661, 475, -335, 229, -152, 96, -59, 42, 16, + 6, 51, -54, 80, -119, 175, -252, 357, -501, 698, -972, 1363,-1958, 2970,-5138,13927,23964,-6460, 3620,-2403, 1703,-1239, 907, -661, 475, -335, 229, -152, 96, -59, 41, 16, + 6, 51, -53, 80, -119, 174, -250, 355, -498, 695, -967, 1357,-1950, 2957,-5116,13844,24029,-6455, 3616,-2401, 1702,-1238, 907, -661, 475, -334, 229, -152, 96, -59, 41, 16, + 6, 51, -53, 79, -118, 173, -249, 353, -496, 691, -962, 1351,-1941, 2944,-5093,13761,24094,-6449, 3612,-2398, 1700,-1237, 906, -660, 475, -334, 229, -151, 96, -59, 41, 16, + 6, 51, -53, 79, -118, 172, -248, 351, -493, 688, -958, 1345,-1932, 2932,-5070,13678,24159,-6443, 3608,-2396, 1698,-1236, 906, -660, 474, -334, 229, -151, 96, -59, 41, 16, + 6, 51, -53, 79, -117, 171, -246, 350, -491, 684, -953, 1338,-1923, 2919,-5047,13595,24224,-6438, 3603,-2393, 1697,-1235, 905, -660, 474, -334, 229, -151, 96, -59, 41, 16, + 6, 51, -53, 78, -117, 170, -245, 348, -488, 681, -948, 1332,-1915, 2906,-5024,13512,24288,-6431, 3599,-2390, 1695,-1234, 904, -659, 474, -334, 229, -151, 96, -58, 41, 16, + 5, 51, -53, 78, -116, 170, -244, 346, -485, 677, -943, 1325,-1906, 2892,-5001,13429,24352,-6425, 3594,-2387, 1693,-1233, 903, -659, 474, -333, 228, -151, 95, -58, 41, 16, + 5, 51, -52, 78, -115, 169, -242, 344, -483, 673, -939, 1319,-1897, 2879,-4977,13346,24416,-6418, 3589,-2384, 1691,-1231, 903, -658, 473, -333, 228, -151, 95, -58, 40, 17, + 5, 51, -52, 77, -115, 168, -241, 342, -480, 670, -934, 1312,-1888, 2866,-4954,13263,24479,-6411, 3584,-2380, 1689,-1230, 902, -658, 473, -333, 228, -151, 95, -58, 40, 17, + 5, 51, -52, 77, -114, 167, -240, 340, -477, 666, -929, 1306,-1879, 2853,-4930,13180,24543,-6404, 3579,-2377, 1687,-1229, 901, -657, 473, -333, 228, -151, 95, -58, 40, 17, + 5, 51, -52, 77, -114, 166, -238, 338, -475, 662, -924, 1299,-1869, 2839,-4907,13097,24606,-6396, 3574,-2374, 1685,-1227, 900, -657, 472, -333, 228, -150, 95, -58, 40, 17, + 5, 51, -52, 76, -113, 165, -237, 336, -472, 659, -919, 1292,-1860, 2825,-4883,13014,24669,-6388, 3568,-2370, 1682,-1226, 899, -656, 472, -332, 227, -150, 95, -58, 40, 17, + 5, 51, -51, 76, -113, 164, -236, 334, -469, 655, -914, 1286,-1851, 2812,-4859,12931,24731,-6380, 3563,-2367, 1680,-1224, 898, -655, 471, -332, 227, -150, 95, -58, 40, 17, + 5, 51, -51, 76, -112, 163, -234, 332, -466, 651, -909, 1279,-1842, 2798,-4834,12848,24793,-6372, 3557,-2363, 1678,-1223, 897, -655, 471, -332, 227, -150, 95, -57, 39, 17, + 5, 51, -51, 75, -111, 162, -233, 330, -464, 648, -904, 1272,-1832, 2784,-4810,12764,24855,-6363, 3551,-2359, 1675,-1221, 896, -654, 471, -331, 227, -150, 94, -57, 39, 17, + 5, 51, -51, 75, -111, 161, -232, 328, -461, 644, -899, 1265,-1823, 2770,-4786,12681,24917,-6354, 3545,-2355, 1673,-1220, 895, -653, 470, -331, 227, -149, 94, -57, 39, 17, + 5, 51, -51, 74, -110, 160, -230, 326, -458, 640, -894, 1258,-1813, 2756,-4761,12598,24979,-6345, 3539,-2351, 1670,-1218, 894, -653, 470, -331, 226, -149, 94, -57, 39, 17, + 5, 51, -51, 74, -110, 160, -229, 324, -455, 636, -889, 1251,-1804, 2742,-4736,12515,25040,-6335, 3532,-2347, 1667,-1216, 893, -652, 469, -330, 226, -149, 94, -57, 39, 18, + 5, 51, -50, 74, -109, 159, -227, 322, -453, 632, -883, 1245,-1794, 2728,-4712,12432,25101,-6325, 3526,-2343, 1665,-1214, 892, -651, 469, -330, 226, -149, 94, -57, 39, 18, + 5, 51, -50, 73, -108, 158, -226, 320, -450, 629, -878, 1238,-1785, 2714,-4687,12349,25162,-6315, 3519,-2339, 1662,-1213, 890, -650, 468, -330, 226, -149, 94, -57, 38, 18, + 5, 51, -50, 73, -108, 157, -225, 318, -447, 625, -873, 1230,-1775, 2700,-4662,12266,25222,-6305, 3512,-2334, 1659,-1211, 889, -649, 467, -329, 225, -148, 93, -57, 38, 18, + 5, 51, -50, 73, -107, 156, -223, 316, -444, 621, -868, 1223,-1765, 2685,-4637,12183,25282,-6294, 3505,-2330, 1656,-1209, 888, -649, 467, -329, 225, -148, 93, -56, 38, 18, + 5, 51, -50, 72, -107, 155, -222, 314, -441, 617, -863, 1216,-1755, 2671,-4611,12100,25342,-6284, 3498,-2325, 1653,-1207, 887, -648, 466, -328, 225, -148, 93, -56, 38, 18, + 5, 51, -49, 72, -106, 154, -220, 312, -438, 613, -857, 1209,-1745, 2656,-4586,12017,25402,-6272, 3491,-2320, 1650,-1205, 885, -647, 466, -328, 224, -148, 93, -56, 38, 18, + 5, 51, -49, 72, -105, 153, -219, 310, -435, 609, -852, 1202,-1735, 2641,-4560,11934,25461,-6261, 3484,-2316, 1647,-1203, 884, -646, 465, -328, 224, -148, 93, -56, 38, 18, + 5, 51, -49, 71, -105, 152, -217, 308, -433, 605, -847, 1195,-1725, 2627,-4535,11852,25520,-6249, 3476,-2311, 1643,-1200, 882, -645, 464, -327, 224, -147, 93, -56, 37, 18, + 4, 51, -49, 71, -104, 151, -216, 306, -430, 601, -841, 1187,-1715, 2612,-4509,11769,25579,-6237, 3468,-2306, 1640,-1198, 881, -644, 464, -327, 223, -147, 92, -56, 37, 19, + 4, 51, -49, 70, -104, 150, -214, 304, -427, 597, -836, 1180,-1705, 2597,-4483,11686,25637,-6225, 3461,-2301, 1637,-1196, 879, -643, 463, -326, 223, -147, 92, -55, 37, 19, + 4, 51, -48, 70, -103, 149, -213, 302, -424, 593, -830, 1173,-1695, 2582,-4457,11603,25696,-6212, 3453,-2296, 1633,-1194, 878, -642, 462, -326, 223, -147, 92, -55, 37, 19, + 4, 50, -48, 70, -102, 148, -211, 299, -421, 589, -825, 1165,-1685, 2567,-4431,11520,25754,-6200, 3444,-2290, 1630,-1191, 876, -641, 462, -325, 222, -146, 92, -55, 37, 19, + 4, 50, -48, 69, -102, 147, -210, 297, -418, 585, -820, 1158,-1675, 2552,-4405,11437,25811,-6186, 3436,-2285, 1626,-1189, 875, -640, 461, -325, 222, -146, 92, -55, 37, 19, + 4, 50, -48, 69, -101, 146, -209, 295, -415, 581, -814, 1151,-1664, 2537,-4379,11355,25869,-6173, 3428,-2280, 1623,-1187, 873, -639, 460, -324, 222, -146, 91, -55, 36, 19, + 4, 50, -48, 69, -100, 145, -207, 293, -412, 577, -808, 1143,-1654, 2522,-4352,11272,25926,-6159, 3419,-2274, 1619,-1184, 871, -637, 459, -324, 221, -145, 91, -55, 36, 19, + 4, 50, -47, 68, -100, 144, -206, 291, -409, 573, -803, 1136,-1644, 2506,-4326,11189,25983,-6145, 3410,-2268, 1615,-1182, 870, -636, 459, -323, 221, -145, 91, -54, 36, 19, + 4, 50, -47, 68, -99, 143, -204, 289, -406, 569, -797, 1128,-1633, 2491,-4299,11107,26039,-6131, 3401,-2263, 1611,-1179, 868, -635, 458, -323, 220, -145, 91, -54, 36, 19, + 4, 50, -47, 67, -98, 142, -203, 286, -403, 564, -792, 1120,-1623, 2476,-4273,11024,26095,-6117, 3392,-2257, 1608,-1176, 866, -634, 457, -322, 220, -145, 90, -54, 36, 19, + 4, 50, -47, 67, -98, 141, -201, 284, -400, 560, -786, 1113,-1612, 2460,-4246,10942,26151,-6102, 3383,-2251, 1604,-1174, 864, -633, 456, -321, 220, -144, 90, -54, 35, 20, + 4, 50, -46, 67, -97, 140, -199, 282, -397, 556, -781, 1105,-1602, 2444,-4219,10859,26207,-6087, 3374,-2245, 1600,-1171, 862, -631, 455, -321, 219, -144, 90, -54, 35, 20, + 4, 50, -46, 66, -96, 139, -198, 280, -394, 552, -775, 1098,-1591, 2429,-4192,10777,26262,-6071, 3364,-2239, 1596,-1168, 861, -630, 454, -320, 219, -144, 90, -54, 35, 20, + 4, 50, -46, 66, -96, 138, -196, 278, -391, 548, -769, 1090,-1580, 2413,-4165,10694,26317,-6056, 3355,-2232, 1591,-1165, 859, -629, 453, -319, 218, -143, 90, -53, 35, 20, + 4, 50, -46, 65, -95, 137, -195, 276, -388, 544, -763, 1082,-1570, 2397,-4138,10612,26372,-6040, 3345,-2226, 1587,-1162, 857, -627, 452, -319, 218, -143, 89, -53, 35, 20, + 4, 50, -46, 65, -95, 136, -193, 273, -384, 539, -758, 1074,-1559, 2381,-4111,10529,26427,-6024, 3335,-2220, 1583,-1160, 855, -626, 451, -318, 217, -143, 89, -53, 35, 20, + 4, 50, -45, 65, -94, 135, -192, 271, -381, 535, -752, 1067,-1548, 2365,-4083,10447,26481,-6007, 3325,-2213, 1578,-1157, 853, -625, 451, -317, 217, -142, 89, -53, 34, 20, + 4, 50, -45, 64, -93, 134, -190, 269, -378, 531, -746, 1059,-1537, 2349,-4056,10365,26535,-5990, 3315,-2207, 1574,-1154, 851, -623, 450, -317, 216, -142, 89, -53, 34, 20, + 4, 50, -45, 64, -93, 133, -189, 267, -375, 526, -740, 1051,-1526, 2333,-4028,10283,26588,-5973, 3304,-2200, 1570,-1150, 848, -622, 449, -316, 216, -142, 88, -52, 34, 20, + 4, 50, -45, 63, -92, 132, -187, 264, -372, 522, -735, 1043,-1515, 2317,-4001,10201,26642,-5956, 3294,-2193, 1565,-1147, 846, -620, 448, -315, 215, -141, 88, -52, 34, 21, + 4, 50, -44, 63, -91, 131, -186, 262, -369, 518, -729, 1035,-1504, 2301,-3973,10119,26695,-5938, 3283,-2186, 1560,-1144, 844, -619, 446, -315, 215, -141, 88, -52, 34, 21, + 4, 50, -44, 63, -91, 130, -184, 260, -366, 514, -723, 1027,-1493, 2285,-3945,10037,26747,-5920, 3272,-2179, 1556,-1141, 842, -617, 445, -314, 214, -141, 87, -52, 33, 21, + 4, 50, -44, 62, -90, 128, -182, 258, -362, 509, -717, 1019,-1482, 2269,-3917, 9955,26800,-5902, 3261,-2172, 1551,-1138, 840, -616, 444, -313, 214, -140, 87, -52, 33, 21, + 3, 50, -44, 62, -89, 127, -181, 255, -359, 505, -711, 1011,-1471, 2252,-3889, 9873,26852,-5883, 3250,-2165, 1546,-1134, 837, -614, 443, -312, 213, -140, 87, -51, 33, 21, + 3, 50, -43, 61, -88, 126, -179, 253, -356, 501, -705, 1003,-1460, 2236,-3861, 9791,26903,-5865, 3239,-2158, 1541,-1131, 835, -612, 442, -312, 213, -139, 87, -51, 33, 21, + 3, 50, -43, 61, -88, 125, -178, 251, -353, 496, -699, 995,-1449, 2219,-3833, 9709,26955,-5845, 3228,-2150, 1536,-1128, 833, -611, 441, -311, 212, -139, 86, -51, 33, 21, + 3, 50, -43, 61, -87, 124, -176, 248, -350, 492, -693, 987,-1437, 2203,-3805, 9627,27006,-5826, 3216,-2143, 1531,-1124, 830, -609, 440, -310, 212, -139, 86, -51, 32, 21, + 3, 50, -43, 60, -86, 123, -174, 246, -347, 487, -687, 979,-1426, 2186,-3777, 9546,27057,-5806, 3204,-2135, 1526,-1121, 828, -608, 439, -309, 211, -138, 86, -51, 32, 21, + 3, 50, -43, 60, -86, 122, -173, 244, -343, 483, -681, 970,-1415, 2170,-3748, 9464,27107,-5786, 3192,-2128, 1521,-1117, 825, -606, 437, -308, 210, -138, 85, -50, 32, 22, + 3, 50, -42, 59, -85, 121, -171, 242, -340, 478, -675, 962,-1403, 2153,-3720, 9383,27157,-5766, 3180,-2120, 1516,-1114, 823, -604, 436, -308, 210, -137, 85, -50, 32, 22, + 3, 49, -42, 59, -84, 120, -170, 239, -337, 474, -669, 954,-1392, 2136,-3691, 9301,27207,-5746, 3168,-2112, 1510,-1110, 820, -602, 435, -307, 209, -137, 85, -50, 32, 22, + 3, 49, -42, 59, -84, 119, -168, 237, -334, 470, -663, 946,-1380, 2119,-3663, 9220,27257,-5725, 3156,-2104, 1505,-1106, 818, -601, 434, -306, 209, -136, 85, -50, 31, 22, + 3, 49, -42, 58, -83, 118, -166, 235, -330, 465, -657, 938,-1369, 2102,-3634, 9139,27306,-5704, 3144,-2096, 1500,-1103, 815, -599, 433, -305, 208, -136, 84, -49, 31, 22, + 3, 49, -41, 58, -82, 117, -165, 232, -327, 461, -651, 929,-1357, 2085,-3605, 9058,27355,-5682, 3131,-2088, 1494,-1099, 813, -597, 431, -304, 207, -136, 84, -49, 31, 22, + 3, 49, -41, 57, -82, 116, -163, 230, -324, 456, -645, 921,-1346, 2068,-3576, 8977,27404,-5661, 3118,-2080, 1489,-1095, 810, -595, 430, -303, 207, -135, 84, -49, 31, 22, + 3, 49, -41, 57, -81, 114, -162, 228, -320, 452, -639, 913,-1334, 2051,-3548, 8896,27452,-5639, 3105,-2071, 1483,-1091, 807, -593, 429, -302, 206, -135, 83, -49, 30, 22, + 3, 49, -41, 56, -80, 113, -160, 225, -317, 447, -633, 904,-1323, 2034,-3519, 8815,27500,-5616, 3092,-2063, 1477,-1087, 805, -591, 427, -301, 206, -134, 83, -48, 30, 22, + 3, 49, -40, 56, -79, 112, -158, 223, -314, 443, -626, 896,-1311, 2017,-3490, 8734,27548,-5594, 3079,-2055, 1472,-1083, 802, -589, 426, -300, 205, -134, 83, -48, 30, 23, + 3, 49, -40, 56, -79, 111, -157, 221, -311, 438, -620, 887,-1299, 2000,-3460, 8653,27595,-5571, 3066,-2046, 1466,-1079, 799, -587, 425, -299, 204, -133, 82, -48, 30, 23, + 3, 49, -40, 55, -78, 110, -155, 218, -307, 433, -614, 879,-1288, 1983,-3431, 8572,27642,-5548, 3052,-2037, 1460,-1075, 796, -585, 423, -298, 204, -133, 82, -48, 30, 23, + 3, 49, -40, 55, -77, 109, -153, 216, -304, 429, -608, 871,-1276, 1966,-3402, 8492,27688,-5524, 3039,-2029, 1454,-1071, 793, -583, 422, -297, 203, -132, 82, -48, 29, 23, + 3, 49, -39, 54, -77, 108, -152, 213, -301, 424, -602, 862,-1264, 1948,-3373, 8411,27735,-5500, 3025,-2020, 1448,-1067, 790, -581, 420, -296, 202, -132, 81, -47, 29, 23, + 3, 49, -39, 54, -76, 107, -150, 211, -297, 420, -595, 854,-1252, 1931,-3343, 8331,27781,-5476, 3011,-2011, 1442,-1063, 787, -579, 419, -295, 201, -131, 81, -47, 29, 23, + 3, 49, -39, 53, -75, 106, -148, 209, -294, 415, -589, 845,-1240, 1913,-3314, 8251,27827,-5452, 2997,-2002, 1436,-1058, 784, -577, 417, -294, 201, -131, 81, -47, 29, 23, + 3, 49, -39, 53, -74, 105, -147, 206, -291, 411, -583, 836,-1228, 1896,-3285, 8171,27872,-5428, 2983,-1993, 1430,-1054, 781, -575, 416, -293, 200, -130, 80, -47, 29, 23, + 3, 49, -38, 53, -74, 103, -145, 204, -287, 406, -577, 828,-1217, 1878,-3255, 8090,27917,-5403, 2969,-1983, 1423,-1050, 778, -573, 414, -292, 199, -130, 80, -46, 28, 23, + 3, 49, -38, 52, -73, 102, -143, 201, -284, 401, -570, 819,-1205, 1861,-3226, 8010,27962,-5377, 2954,-1974, 1417,-1045, 775, -571, 413, -291, 199, -129, 80, -46, 28, 24, + 3, 49, -38, 52, -72, 101, -142, 199, -281, 397, -564, 811,-1193, 1843,-3196, 7931,28006,-5352, 2939,-1965, 1411,-1041, 772, -569, 411, -290, 198, -129, 79, -46, 28, 24, + 3, 48, -38, 51, -72, 100, -140, 197, -277, 392, -558, 802,-1181, 1826,-3166, 7851,28050,-5326, 2925,-1955, 1404,-1036, 769, -566, 410, -289, 197, -128, 79, -46, 28, 24, + 3, 48, -37, 51, -71, 99, -138, 194, -274, 387, -551, 793,-1169, 1808,-3137, 7771,28094,-5300, 2910,-1946, 1398,-1032, 766, -564, 408, -288, 196, -128, 78, -45, 27, 24, + 3, 48, -37, 50, -70, 98, -137, 192, -270, 383, -545, 785,-1156, 1790,-3107, 7691,28137,-5274, 2895,-1936, 1391,-1027, 763, -562, 407, -287, 195, -127, 78, -45, 27, 24, + 2, 48, -37, 50, -69, 97, -135, 189, -267, 378, -539, 776,-1144, 1773,-3077, 7612,28180,-5247, 2880,-1926, 1384,-1023, 759, -560, 405, -286, 195, -127, 78, -45, 27, 24, + 2, 48, -37, 49, -69, 96, -133, 187, -264, 373, -532, 767,-1132, 1755,-3047, 7533,28223,-5220, 2864,-1916, 1378,-1018, 756, -557, 404, -285, 194, -126, 77, -44, 27, 24, + 2, 48, -36, 49, -68, 94, -132, 185, -260, 369, -526, 759,-1120, 1737,-3017, 7453,28265,-5193, 2849,-1906, 1371,-1013, 753, -555, 402, -284, 193, -126, 77, -44, 26, 24, + 2, 48, -36, 49, -67, 93, -130, 182, -257, 364, -519, 750,-1108, 1719,-2987, 7374,28307,-5165, 2833,-1896, 1364,-1009, 750, -553, 400, -282, 192, -125, 77, -44, 26, 25, + 2, 48, -36, 48, -66, 92, -128, 180, -253, 359, -513, 741,-1096, 1701,-2957, 7295,28349,-5137, 2817,-1886, 1357,-1004, 746, -550, 399, -281, 191, -124, 76, -44, 26, 25, + 2, 48, -35, 48, -66, 91, -127, 177, -250, 355, -507, 732,-1083, 1683,-2927, 7216,28390,-5109, 2802,-1876, 1350, -999, 743, -548, 397, -280, 191, -124, 76, -43, 26, 25, + 2, 48, -35, 47, -65, 90, -125, 175, -246, 350, -500, 723,-1071, 1665,-2897, 7137,28431,-5081, 2785,-1866, 1343, -994, 739, -545, 395, -279, 190, -123, 75, -43, 26, 25, + 2, 48, -35, 47, -64, 89, -123, 172, -243, 345, -494, 715,-1059, 1647,-2867, 7059,28471,-5052, 2769,-1855, 1336, -989, 736, -543, 393, -278, 189, -123, 75, -43, 25, 25, + 2, 48, -35, 46, -64, 88, -121, 170, -240, 340, -487, 706,-1047, 1629,-2837, 6980,28512,-5023, 2753,-1845, 1329, -984, 732, -540, 392, -276, 188, -122, 75, -42, 25, 25, + 2, 48, -34, 46, -63, 86, -120, 167, -236, 336, -481, 697,-1034, 1611,-2806, 6902,28552,-4994, 2737,-1834, 1322, -979, 729, -538, 390, -275, 187, -122, 74, -42, 25, 25, + 2, 48, -34, 45, -62, 85, -118, 165, -233, 331, -474, 688,-1022, 1593,-2776, 6823,28591,-4964, 2720,-1824, 1315, -974, 725, -535, 388, -274, 186, -121, 74, -42, 25, 25, + 2, 48, -34, 45, -61, 84, -116, 163, -229, 326, -468, 679,-1010, 1575,-2746, 6745,28630,-4934, 2703,-1813, 1307, -969, 722, -533, 386, -273, 186, -120, 73, -42, 24, 25, + 2, 47, -34, 44, -61, 83, -115, 160, -226, 321, -461, 670, -997, 1557,-2715, 6667,28669,-4904, 2686,-1802, 1300, -964, 718, -530, 385, -271, 185, -120, 73, -41, 24, 26, + 2, 47, -33, 44, -60, 82, -113, 158, -222, 317, -455, 661, -985, 1538,-2685, 6589,28708,-4874, 2669,-1791, 1293, -959, 714, -528, 383, -270, 184, -119, 72, -41, 24, 26, + 2, 47, -33, 44, -59, 81, -111, 155, -219, 312, -448, 652, -972, 1520,-2655, 6511,28746,-4843, 2652,-1780, 1285, -953, 711, -525, 381, -269, 183, -118, 72, -41, 24, 26, + 2, 47, -33, 43, -58, 79, -109, 153, -215, 307, -442, 644, -960, 1502,-2624, 6434,28784,-4812, 2635,-1769, 1278, -948, 707, -522, 379, -268, 182, -118, 72, -40, 23, 26, + 2, 47, -32, 43, -58, 78, -108, 150, -212, 302, -435, 635, -947, 1484,-2594, 6356,28821,-4781, 2618,-1758, 1270, -943, 703, -520, 377, -266, 181, -117, 71, -40, 23, 26, + 2, 47, -32, 42, -57, 77, -106, 148, -208, 297, -429, 626, -935, 1465,-2563, 6279,28858,-4749, 2600,-1747, 1262, -937, 699, -517, 375, -265, 180, -117, 71, -40, 23, 26, + 2, 47, -32, 42, -56, 76, -104, 145, -205, 293, -422, 617, -922, 1447,-2533, 6202,28895,-4717, 2582,-1735, 1255, -932, 695, -514, 373, -264, 179, -116, 70, -40, 23, 26, + 2, 47, -32, 41, -55, 75, -103, 143, -202, 288, -415, 608, -910, 1429,-2502, 6124,28932,-4685, 2564,-1724, 1247, -926, 692, -512, 371, -262, 178, -115, 70, -39, 22, 26, + 2, 47, -31, 41, -55, 74, -101, 140, -198, 283, -409, 599, -897, 1410,-2472, 6047,28968,-4652, 2547,-1712, 1239, -921, 688, -509, 369, -261, 177, -115, 69, -39, 22, 27, + 2, 47, -31, 40, -54, 73, -99, 138, -195, 278, -402, 590, -885, 1392,-2441, 5970,29003,-4620, 2528,-1701, 1231, -915, 684, -506, 368, -259, 176, -114, 69, -39, 22, 27, + 2, 47, -31, 40, -53, 71, -97, 135, -191, 273, -396, 581, -872, 1373,-2410, 5894,29039,-4587, 2510,-1689, 1223, -910, 680, -503, 366, -258, 175, -113, 69, -38, 22, 27, + 2, 47, -31, 39, -52, 70, -96, 133, -188, 269, -389, 572, -860, 1355,-2380, 5817,29074,-4553, 2492,-1677, 1215, -904, 676, -500, 364, -257, 174, -113, 68, -38, 21, 27, + 2, 47, -30, 39, -52, 69, -94, 130, -184, 264, -382, 563, -847, 1336,-2349, 5741,29108,-4519, 2473,-1665, 1207, -899, 672, -498, 362, -255, 173, -112, 68, -38, 21, 27, + 2, 46, -30, 38, -51, 68, -92, 128, -181, 259, -376, 553, -834, 1318,-2318, 5664,29142,-4485, 2455,-1654, 1199, -893, 668, -495, 359, -254, 172, -111, 67, -37, 21, 27, + 2, 46, -30, 38, -50, 67, -90, 125, -177, 254, -369, 544, -822, 1299,-2288, 5588,29176,-4451, 2436,-1642, 1191, -887, 664, -492, 357, -252, 171, -111, 67, -37, 21, 27, + 2, 46, -29, 38, -49, 66, -89, 123, -174, 249, -363, 535, -809, 1281,-2257, 5512,29210,-4417, 2417,-1629, 1182, -881, 660, -489, 355, -251, 170, -110, 66, -37, 20, 27, + 2, 46, -29, 37, -49, 64, -87, 120, -170, 244, -356, 526, -796, 1262,-2226, 5436,29243,-4382, 2398,-1617, 1174, -875, 655, -486, 353, -249, 169, -109, 66, -36, 20, 27, + 2, 46, -29, 37, -48, 63, -85, 118, -167, 240, -349, 517, -784, 1244,-2195, 5361,29276,-4347, 2379,-1605, 1166, -870, 651, -483, 351, -248, 168, -109, 65, -36, 20, 28, + 2, 46, -29, 36, -47, 62, -84, 115, -163, 235, -343, 508, -771, 1225,-2165, 5285,29308,-4311, 2360,-1593, 1157, -864, 647, -480, 349, -247, 167, -108, 65, -36, 20, 28, + 2, 46, -28, 36, -46, 61, -82, 113, -160, 230, -336, 499, -758, 1206,-2134, 5210,29340,-4276, 2340,-1580, 1149, -858, 643, -477, 347, -245, 166, -107, 64, -35, 19, 28, + 2, 46, -28, 35, -46, 60, -80, 110, -156, 225, -329, 490, -745, 1188,-2103, 5134,29372,-4240, 2321,-1568, 1140, -852, 639, -474, 345, -244, 165, -106, 64, -35, 19, 28, + 2, 46, -28, 35, -45, 59, -78, 108, -153, 220, -323, 481, -733, 1169,-2072, 5059,29403,-4203, 2301,-1555, 1132, -846, 634, -471, 343, -242, 164, -106, 63, -35, 19, 28, + 2, 46, -27, 34, -44, 57, -77, 105, -149, 215, -316, 472, -720, 1150,-2041, 4984,29434,-4167, 2281,-1543, 1123, -840, 630, -468, 340, -240, 163, -105, 63, -34, 19, 28, + 2, 46, -27, 34, -43, 56, -75, 103, -145, 210, -309, 462, -707, 1132,-2011, 4910,29465,-4130, 2261,-1530, 1114, -833, 626, -465, 338, -239, 162, -104, 62, -34, 18, 28, + 2, 46, -27, 33, -43, 55, -73, 100, -142, 206, -303, 453, -694, 1113,-1980, 4835,29495,-4093, 2241,-1517, 1106, -827, 621, -462, 336, -237, 161, -103, 62, -34, 18, 28, + 2, 45, -27, 33, -42, 54, -71, 98, -138, 201, -296, 444, -682, 1094,-1949, 4760,29525,-4055, 2221,-1504, 1097, -821, 617, -459, 334, -236, 160, -103, 61, -33, 18, 29, + 1, 45, -26, 32, -41, 53, -70, 95, -135, 196, -289, 435, -669, 1076,-1918, 4686,29555,-4017, 2201,-1491, 1088, -815, 612, -455, 332, -234, 159, -102, 61, -33, 18, 29, + 1, 45, -26, 32, -40, 52, -68, 93, -131, 191, -283, 426, -656, 1057,-1887, 4612,29584,-3979, 2180,-1478, 1079, -809, 608, -452, 329, -233, 158, -101, 60, -33, 17, 29, + 1, 45, -26, 31, -40, 50, -66, 90, -128, 186, -276, 417, -643, 1038,-1856, 4538,29613,-3941, 2160,-1465, 1070, -802, 603, -449, 327, -231, 157, -100, 60, -32, 17, 29, + 1, 45, -25, 31, -39, 49, -64, 88, -124, 181, -269, 407, -630, 1019,-1825, 4464,29641,-3902, 2139,-1452, 1061, -796, 599, -446, 325, -229, 156, -100, 59, -32, 17, 29, + 1, 45, -25, 30, -38, 48, -63, 85, -121, 176, -263, 398, -618, 1001,-1795, 4391,29669,-3864, 2118,-1439, 1052, -790, 594, -443, 323, -228, 154, -99, 59, -32, 17, 29, + 1, 45, -25, 30, -37, 47, -61, 83, -117, 171, -256, 389, -605, 982,-1764, 4317,29697,-3824, 2097,-1425, 1043, -783, 590, -439, 320, -226, 153, -98, 58, -31, 16, 29, + 1, 45, -25, 30, -37, 46, -59, 80, -114, 167, -249, 380, -592, 963,-1733, 4244,29724,-3785, 2076,-1412, 1034, -777, 585, -436, 318, -225, 152, -97, 58, -31, 16, 29, + 1, 45, -24, 29, -36, 45, -58, 78, -110, 162, -243, 371, -579, 944,-1702, 4171,29751,-3745, 2055,-1398, 1024, -770, 581, -433, 316, -223, 151, -97, 57, -31, 16, 30, + 1, 45, -24, 29, -35, 43, -56, 75, -107, 157, -236, 362, -566, 926,-1671, 4098,29777,-3705, 2034,-1385, 1015, -764, 576, -429, 313, -221, 150, -96, 57, -30, 15, 30, + 1, 45, -24, 28, -34, 42, -54, 73, -103, 152, -229, 352, -553, 907,-1640, 4025,29803,-3665, 2012,-1371, 1006, -757, 571, -426, 311, -220, 149, -95, 56, -30, 15, 30, + 1, 45, -23, 28, -33, 41, -52, 70, -100, 147, -223, 343, -541, 888,-1609, 3952,29829,-3624, 1991,-1357, 996, -750, 566, -423, 308, -218, 148, -94, 56, -30, 15, 30, + 1, 44, -23, 27, -33, 40, -51, 68, -96, 142, -216, 334, -528, 869,-1579, 3880,29855,-3583, 1969,-1343, 987, -744, 562, -419, 306, -216, 146, -93, 55, -29, 15, 30, + 1, 44, -23, 27, -32, 39, -49, 65, -93, 137, -209, 325, -515, 850,-1548, 3808,29880,-3542, 1947,-1330, 977, -737, 557, -416, 304, -215, 145, -93, 54, -29, 14, 30, + 1, 44, -22, 26, -31, 38, -47, 63, -89, 132, -202, 316, -502, 832,-1517, 3736,29904,-3501, 1925,-1316, 968, -730, 552, -412, 301, -213, 144, -92, 54, -28, 14, 30, + 1, 44, -22, 26, -30, 36, -45, 60, -86, 128, -196, 306, -489, 813,-1486, 3664,29928,-3459, 1903,-1302, 958, -723, 547, -409, 299, -211, 143, -91, 53, -28, 14, 30, + 1, 44, -22, 25, -30, 35, -44, 58, -82, 123, -189, 297, -476, 794,-1455, 3592,29952,-3417, 1881,-1288, 949, -717, 542, -405, 296, -209, 142, -90, 53, -28, 14, 30, + 1, 44, -22, 25, -29, 34, -42, 55, -79, 118, -182, 288, -464, 775,-1425, 3521,29976,-3374, 1859,-1273, 939, -710, 538, -402, 294, -208, 140, -89, 52, -27, 13, 31, + 1, 44, -21, 24, -28, 33, -40, 53, -75, 113, -176, 279, -451, 756,-1394, 3449,29999,-3332, 1836,-1259, 929, -703, 533, -398, 291, -206, 139, -89, 52, -27, 13, 31, + 1, 44, -21, 24, -27, 32, -39, 50, -72, 108, -169, 270, -438, 737,-1363, 3378,30022,-3289, 1814,-1245, 919, -696, 528, -395, 289, -204, 138, -88, 51, -27, 13, 31, + 1, 44, -21, 23, -27, 31, -37, 48, -68, 103, -162, 260, -425, 719,-1332, 3307,30044,-3246, 1791,-1230, 910, -689, 523, -391, 286, -202, 137, -87, 51, -26, 13, 31, + 1, 44, -20, 23, -26, 29, -35, 45, -65, 98, -156, 251, -412, 700,-1302, 3236,30066,-3202, 1769,-1216, 900, -682, 518, -388, 284, -201, 135, -86, 50, -26, 12, 31, + 1, 43, -20, 22, -25, 28, -33, 43, -61, 94, -149, 242, -399, 681,-1271, 3166,30088,-3158, 1746,-1201, 890, -675, 513, -384, 281, -199, 134, -85, 49, -26, 12, 31, + 1, 43, -20, 22, -24, 27, -32, 40, -58, 89, -142, 233, -386, 662,-1240, 3095,30109,-3114, 1723,-1187, 880, -668, 508, -381, 279, -197, 133, -84, 49, -25, 12, 31, + 1, 43, -20, 21, -24, 26, -30, 38, -54, 84, -136, 224, -374, 643,-1209, 3025,30130,-3070, 1700,-1172, 870, -661, 503, -377, 276, -195, 132, -83, 48, -25, 11, 31, + 1, 43, -19, 21, -23, 25, -28, 36, -51, 79, -129, 214, -361, 625,-1179, 2955,30150,-3025, 1676,-1158, 860, -654, 497, -373, 273, -193, 130, -83, 48, -24, 11, 32, + 1, 43, -19, 21, -22, 24, -26, 33, -47, 74, -122, 205, -348, 606,-1148, 2885,30170,-2981, 1653,-1143, 850, -647, 492, -370, 271, -191, 129, -82, 47, -24, 11, 32, + 1, 43, -19, 20, -21, 22, -25, 31, -44, 69, -116, 196, -335, 587,-1118, 2816,30190,-2935, 1630,-1128, 839, -639, 487, -366, 268, -190, 128, -81, 47, -24, 11, 32, + 1, 43, -18, 20, -21, 21, -23, 28, -40, 64, -109, 187, -322, 568,-1087, 2746,30209,-2890, 1606,-1113, 829, -632, 482, -362, 266, -188, 127, -80, 46, -23, 10, 32, + 1, 43, -18, 19, -20, 20, -21, 26, -37, 60, -102, 178, -309, 550,-1057, 2677,30228,-2844, 1583,-1098, 819, -625, 477, -359, 263, -186, 125, -79, 45, -23, 10, 32, + 1, 43, -18, 19, -19, 19, -20, 23, -33, 55, -96, 169, -296, 531,-1026, 2608,30246,-2798, 1559,-1083, 809, -618, 472, -355, 260, -184, 124, -78, 45, -22, 10, 32, + 1, 43, -17, 18, -18, 18, -18, 21, -30, 50, -89, 159, -284, 512, -996, 2539,30264,-2752, 1535,-1068, 798, -610, 466, -351, 258, -182, 123, -77, 44, -22, 9, 32, + 1, 42, -17, 18, -18, 17, -16, 18, -26, 45, -82, 150, -271, 493, -965, 2471,30282,-2705, 1511,-1053, 788, -603, 461, -347, 255, -180, 121, -76, 44, -22, 9, 32, + 1, 42, -17, 17, -17, 16, -14, 16, -23, 40, -76, 141, -258, 475, -935, 2402,30300,-2659, 1487,-1037, 777, -596, 456, -343, 252, -178, 120, -76, 43, -21, 9, 33, + 1, 42, -17, 17, -16, 14, -13, 13, -19, 35, -69, 132, -245, 456, -904, 2334,30317,-2612, 1463,-1022, 767, -588, 450, -340, 249, -176, 119, -75, 42, -21, 9, 33, + 1, 42, -16, 16, -15, 13, -11, 11, -16, 31, -62, 123, -232, 437, -874, 2266,30333,-2564, 1438,-1007, 756, -581, 445, -336, 247, -175, 117, -74, 42, -20, 8, 33, + 1, 42, -16, 16, -15, 12, -9, 8, -12, 26, -56, 114, -220, 419, -844, 2198,30349,-2516, 1414, -991, 746, -573, 440, -332, 244, -173, 116, -73, 41, -20, 8, 33, + 1, 42, -16, 15, -14, 11, -8, 6, -9, 21, -49, 105, -207, 400, -813, 2131,30365,-2469, 1389, -976, 735, -566, 434, -328, 241, -171, 115, -72, 41, -20, 8, 33, + 1, 42, -15, 15, -13, 10, -6, 4, -5, 16, -43, 95, -194, 381, -783, 2063,30380,-2420, 1365, -960, 724, -558, 429, -324, 238, -169, 113, -71, 40, -19, 7, 33, + 1, 42, -15, 14, -12, 9, -4, 1, -2, 11, -36, 86, -181, 363, -753, 1996,30395,-2372, 1340, -944, 714, -551, 424, -320, 236, -167, 112, -70, 39, -19, 7, 33, + 1, 42, -15, 14, -12, 8, -3, -1, 1, 7, -29, 77, -169, 344, -723, 1929,30410,-2323, 1315, -929, 703, -543, 418, -316, 233, -165, 111, -69, 39, -18, 7, 33, + 1, 42, -14, 13, -11, 6, -1, -4, 5, 2, -23, 68, -156, 325, -692, 1862,30424,-2274, 1290, -913, 692, -535, 413, -312, 230, -163, 109, -68, 38, -18, 7, 33, + 1, 41, -14, 13, -10, 5, 1, -6, 8, -3, -16, 59, -143, 307, -662, 1796,30438,-2225, 1265, -897, 681, -528, 407, -309, 227, -161, 108, -67, 38, -18, 6, 34, + 1, 41, -14, 13, -9, 4, 2, -9, 12, -8, -10, 50, -130, 288, -632, 1730,30452,-2175, 1240, -881, 671, -520, 402, -305, 224, -159, 107, -66, 37, -17, 6, 34, + 1, 41, -14, 12, -9, 3, 4, -11, 15, -12, -3, 41, -118, 270, -602, 1663,30465,-2125, 1215, -865, 660, -512, 396, -301, 222, -157, 105, -65, 36, -17, 6, 34, + 1, 41, -13, 12, -8, 2, 6, -14, 19, -17, 3, 32, -105, 251, -572, 1598,30477,-2075, 1190, -849, 649, -504, 390, -297, 219, -155, 104, -64, 36, -16, 5, 34, + 1, 41, -13, 11, -7, 1, 8, -16, 22, -22, 10, 23, -92, 233, -542, 1532,30490,-2025, 1164, -833, 638, -497, 385, -293, 216, -153, 102, -63, 35, -16, 5, 34, + 1, 41, -13, 11, -6, 0, 9, -18, 25, -27, 17, 14, -80, 214, -512, 1466,30501,-1974, 1139, -817, 627, -489, 379, -288, 213, -151, 101, -63, 34, -16, 5, 34, + 1, 41, -12, 10, -6, -2, 11, -21, 29, -31, 23, 5, -67, 196, -482, 1401,30513,-1923, 1113, -801, 616, -481, 374, -284, 210, -149, 100, -62, 34, -15, 5, 34, + 1, 41, -12, 10, -5, -3, 13, -23, 32, -36, 30, -4, -54, 177, -453, 1336,30524,-1872, 1087, -785, 604, -473, 368, -280, 207, -147, 98, -61, 33, -15, 4, 34, + 1, 41, -12, 9, -4, -4, 14, -26, 36, -41, 36, -13, -42, 159, -423, 1271,30535,-1821, 1061, -769, 593, -465, 362, -276, 204, -145, 97, -60, 32, -14, 4, 35, + 1, 40, -11, 9, -4, -5, 16, -28, 39, -46, 43, -22, -29, 140, -393, 1207,30545,-1769, 1036, -752, 582, -457, 356, -272, 201, -143, 95, -59, 32, -14, 4, 35, + 1, 40, -11, 8, -3, -6, 17, -30, 42, -50, 49, -31, -17, 122, -364, 1142,30555,-1717, 1010, -736, 571, -449, 351, -268, 198, -140, 94, -58, 31, -14, 3, 35, + 1, 40, -11, 8, -2, -7, 19, -33, 46, -55, 56, -40, -4, 104, -334, 1078,30564,-1665, 983, -720, 560, -441, 345, -264, 195, -138, 92, -57, 31, -13, 3, 35, + 1, 40, -11, 7, -1, -8, 21, -35, 49, -60, 62, -49, 8, 85, -304, 1014,30573,-1612, 957, -703, 548, -433, 339, -260, 192, -136, 91, -56, 30, -13, 3, 35, + 1, 40, -10, 7, -1, -9, 22, -37, 52, -64, 69, -58, 21, 67, -275, 951,30582,-1559, 931, -686, 537, -425, 333, -256, 189, -134, 89, -55, 29, -12, 3, 35, + 1, 40, -10, 6, 0, -10, 24, -40, 56, -69, 75, -67, 33, 49, -245, 887,30590,-1506, 905, -670, 526, -417, 328, -251, 186, -132, 88, -54, 29, -12, 2, 35, + 1, 40, -10, 6, 1, -12, 26, -42, 59, -74, 81, -76, 46, 30, -216, 824,30598,-1453, 878, -653, 514, -409, 322, -247, 183, -130, 87, -53, 28, -11, 2, 35, + 1, 40, -9, 6, 2, -13, 27, -45, 63, -78, 88, -85, 58, 12, -187, 761,30606,-1399, 852, -637, 503, -401, 316, -243, 180, -128, 85, -52, 27, -11, 2, 35, + 1, 40, -9, 5, 2, -14, 29, -47, 66, -83, 94, -94, 71, -6, -157, 698,30613,-1345, 825, -620, 491, -393, 310, -239, 177, -126, 84, -51, 27, -11, 1, 36, + 1, 40, -9, 5, 3, -15, 31, -49, 69, -88, 101, -102, 83, -24, -128, 636,30620,-1291, 798, -603, 480, -385, 304, -235, 174, -124, 82, -50, 26, -10, 1, 36, + 1, 39, -8, 4, 4, -16, 32, -52, 73, -92, 107, -111, 96, -42, -99, 574,30626,-1237, 771, -586, 468, -376, 298, -230, 171, -121, 81, -49, 25, -10, 1, 36, + 1, 39, -8, 4, 4, -17, 34, -54, 76, -97, 113, -120, 108, -60, -70, 512,30632,-1182, 744, -569, 457, -368, 292, -226, 168, -119, 79, -48, 25, -9, 1, 36, + 1, 39, -8, 3, 5, -18, 36, -56, 79, -102, 120, -129, 121, -78, -41, 450,30638,-1127, 717, -552, 445, -360, 286, -222, 165, -117, 78, -47, 24, -9, 0, 36, + 1, 39, -8, 3, 6, -19, 37, -59, 82, -106, 126, -138, 133, -96, -12, 388,30643,-1072, 690, -535, 433, -352, 281, -218, 162, -115, 76, -46, 23, -8, 0, 36, + 1, 39, -7, 2, 7, -20, 39, -61, 86, -111, 133, -147, 145, -114, 17, 327,30648,-1017, 663, -518, 422, -343, 275, -213, 159, -113, 75, -45, 23, -8, 0, 36, + 1, 39, -7, 2, 7, -21, 40, -63, 89, -115, 139, -155, 158, -132, 46, 266,30652, -961, 636, -501, 410, -335, 269, -209, 156, -111, 73, -44, 22, -7, -1, 36, + 1, 39, -7, 1, 8, -23, 42, -66, 92, -120, 145, -164, 170, -150, 75, 205,30656, -905, 609, -484, 398, -327, 263, -205, 153, -108, 72, -43, 21, -7, -1, 37, + 1, 39, -6, 1, 9, -24, 44, -68, 96, -124, 152, -173, 182, -168, 103, 144,30660, -849, 581, -467, 387, -318, 257, -200, 150, -106, 70, -42, 21, -7, -1, 37, + 1, 39, -6, 1, 9, -25, 45, -70, 99, -129, 158, -182, 194, -186, 132, 84,30663, -793, 554, -450, 375, -310, 250, -196, 147, -104, 69, -41, 20, -6, -2, 37, + 1, 38, -6, 0, 10, -26, 47, -73, 102, -133, 164, -190, 207, -204, 161, 24,30665, -736, 526, -432, 363, -302, 244, -191, 144, -102, 67, -40, 19, -6, -2, 37, + 1, 38, -5, 0, 11, -27, 48, -75, 105, -138, 170, -199, 219, -222, 189, -36,30668, -679, 498, -415, 351, -293, 238, -187, 140, -100, 66, -38, 19, -5, -2, 37, + 1, 38, -5, -1, 12, -28, 50, -77, 109, -143, 177, -208, 231, -240, 218, -96,30670, -622, 471, -398, 339, -285, 232, -183, 137, -97, 64, -37, 18, -5, -2, 37, + 1, 38, -5, -1, 12, -29, 52, -79, 112, -147, 183, -216, 243, -257, 246, -155,30671, -564, 443, -380, 327, -276, 226, -178, 134, -95, 62, -36, 17, -4, -3, 37, + 1, 38, -5, -2, 13, -30, 53, -82, 115, -152, 189, -225, 255, -275, 274, -215,30673, -507, 415, -363, 315, -268, 220, -174, 131, -93, 61, -35, 16, -4, -3, 37, + 1, 38, -4, -2, 14, -31, 55, -84, 118, -156, 195, -233, 267, -293, 303, -273,30673, -449, 387, -345, 303, -259, 214, -169, 128, -91, 59, -34, 16, -4, -3, 37, + -43, 38, -4, -3, 14, -32, 56, -86, 121, -161, 202, -242, 279, -310, 331, -332,30674, -391, 359, -328, 291, -251, 208, -165, 125, -88, 58, -33, 15, -3, -4, 38, diff --git a/services/multimedia/audio/process/resample/coef/resample_any_up512_36_filter.txt b/services/multimedia/audio/process/resample/coef/resample_any_up512_36_filter.txt new file mode 100644 index 0000000..25f07b5 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_any_up512_36_filter.txt @@ -0,0 +1,513 @@ +//single phase coef Number:=36, upsample factor:=512, + 25, -45, 16, -40, 33, -42, 39, -41, 37, -34, 29, -24, 17, -10, 2, 6, -24,30302, 35, -22, 21, -23, 26, -31, 34, -38, 40, -43, 41, -43, 33, -40, 17, -46, 25, 44, + 24, -45, 16, -39, 32, -40, 37, -38, 34, -30, 24, -17, 7, 3, -16, 35, -82,30302, 94, -51, 39, -35, 36, -38, 40, -42, 43, -45, 42, -44, 34, -41, 17, -46, 25, 1, + 24, -45, 16, -39, 31, -39, 36, -36, 31, -26, 19, -10, -2, 16, -34, 63, -140,30301, 153, -79, 57, -48, 45, -45, 45, -46, 46, -47, 44, -45, 35, -41, 17, -46, 25, 1, + 24, -45, 15, -38, 30, -38, 34, -34, 28, -22, 13, -3, -11, 28, -52, 92, -198,30300, 212, -108, 75, -61, 54, -52, 50, -50, 49, -49, 45, -46, 36, -42, 18, -46, 25, 1, + 24, -45, 15, -38, 29, -37, 33, -32, 25, -19, 8, 4, -21, 41, -70, 120, -256,30298, 272, -137, 93, -74, 64, -59, 56, -54, 52, -52, 47, -47, 36, -42, 18, -46, 25, 1, + 24, -44, 15, -37, 29, -36, 31, -30, 22, -15, 3, 11, -30, 54, -88, 148, -314,30296, 332, -166, 112, -87, 73, -66, 61, -58, 55, -54, 49, -48, 37, -43, 18, -46, 25, 1, + 24, -44, 14, -37, 28, -35, 29, -27, 19, -11, -3, 18, -39, 66, -106, 176, -371,30294, 392, -194, 130, -99, 83, -73, 66, -62, 58, -56, 50, -49, 38, -43, 19, -47, 25, 1, + 24, -44, 14, -36, 27, -34, 28, -25, 16, -7, -8, 25, -48, 79, -124, 204, -428,30291, 452, -223, 148, -112, 92, -80, 72, -66, 61, -58, 52, -51, 39, -44, 19, -47, 25, 1, + 24, -44, 14, -36, 26, -33, 26, -23, 13, -3, -13, 32, -58, 91, -142, 232, -485,30288, 512, -252, 167, -125, 101, -87, 77, -71, 64, -60, 53, -52, 40, -44, 19, -47, 25, 1, + 24, -44, 13, -35, 26, -31, 25, -21, 11, 1, -18, 39, -67, 104, -160, 260, -541,30285, 573, -281, 185, -138, 111, -94, 82, -75, 67, -63, 55, -53, 40, -45, 20, -47, 25, 1, + 24, -43, 13, -35, 25, -30, 23, -19, 8, 5, -24, 46, -76, 117, -177, 288, -597,30281, 634, -310, 203, -151, 120, -101, 88, -79, 70, -65, 57, -54, 41, -45, 20, -47, 25, 1, + 24, -43, 13, -34, 24, -29, 21, -17, 5, 9, -29, 53, -85, 129, -195, 316, -653,30277, 695, -340, 222, -164, 130, -108, 93, -83, 73, -67, 58, -55, 42, -46, 20, -48, 25, 1, + 24, -43, 12, -34, 23, -28, 20, -14, 2, 13, -34, 60, -95, 142, -213, 344, -709,30272, 756, -369, 240, -177, 139, -115, 98, -87, 76, -69, 60, -56, 43, -46, 21, -48, 25, 2, + 24, -43, 12, -33, 22, -27, 18, -12, -1, 17, -39, 67, -104, 154, -231, 371, -765,30267, 818, -398, 259, -190, 149, -122, 104, -91, 79, -72, 61, -57, 43, -47, 21, -48, 25, 2, + 24, -43, 12, -32, 22, -26, 17, -10, -4, 21, -44, 74, -113, 167, -248, 399, -820,30262, 880, -427, 277, -202, 158, -129, 109, -95, 82, -74, 63, -58, 44, -47, 21, -48, 25, 2, + 24, -42, 11, -32, 21, -25, 15, -8, -7, 25, -50, 81, -122, 179, -266, 426, -875,30256, 942, -456, 296, -215, 168, -136, 114, -99, 85, -76, 65, -59, 45, -48, 22, -48, 25, 2, + 24, -42, 11, -31, 20, -24, 14, -6, -10, 29, -55, 88, -131, 191, -284, 454, -930,30250, 1004, -486, 314, -228, 177, -144, 120, -103, 88, -78, 66, -61, 46, -48, 22, -48, 25, 2, + 24, -42, 11, -31, 19, -22, 12, -3, -13, 33, -60, 95, -140, 204, -301, 481, -984,30244, 1067, -515, 333, -241, 186, -151, 125, -107, 91, -80, 68, -62, 46, -49, 22, -49, 25, 2, + 24, -42, 10, -30, 19, -21, 10, -1, -16, 37, -65, 101, -150, 216, -319, 509,-1039,30237, 1129, -545, 351, -254, 196, -158, 130, -111, 94, -83, 69, -63, 47, -49, 23, -49, 25, 2, + 24, -42, 10, -30, 18, -20, 9, 1, -19, 41, -70, 108, -159, 229, -336, 536,-1093,30230, 1192, -574, 370, -267, 205, -165, 136, -115, 97, -85, 71, -64, 48, -50, 23, -49, 25, 2, + 24, -41, 9, -29, 17, -19, 7, 3, -22, 45, -76, 115, -168, 241, -354, 563,-1147,30222, 1255, -604, 388, -280, 215, -172, 141, -119, 100, -87, 73, -65, 49, -50, 23, -49, 25, 2, + 24, -41, 9, -29, 16, -18, 6, 5, -25, 48, -81, 122, -177, 253, -371, 590,-1200,30214, 1319, -633, 407, -293, 224, -179, 146, -123, 103, -89, 74, -66, 50, -51, 24, -49, 25, 2, + 24, -41, 9, -28, 15, -17, 4, 7, -28, 52, -86, 129, -186, 266, -389, 617,-1254,30205, 1382, -663, 425, -306, 234, -186, 152, -127, 106, -91, 76, -67, 50, -51, 24, -50, 25, 2, + 24, -41, 8, -28, 15, -16, 2, 10, -31, 56, -91, 135, -195, 278, -406, 644,-1307,30197, 1446, -692, 444, -319, 243, -193, 157, -131, 109, -94, 77, -68, 51, -52, 24, -50, 25, 2, + 24, -41, 8, -27, 14, -15, 1, 12, -34, 60, -96, 142, -204, 290, -423, 671,-1359,30188, 1510, -722, 463, -332, 253, -200, 163, -135, 112, -96, 79, -70, 52, -52, 25, -50, 25, 2, + 24, -40, 8, -27, 13, -14, -1, 14, -36, 64, -101, 149, -213, 302, -441, 698,-1412,30178, 1574, -752, 481, -345, 262, -207, 168, -139, 115, -98, 80, -71, 53, -53, 25, -50, 25, 2, + 24, -40, 7, -26, 12, -12, -2, 16, -39, 68, -106, 156, -222, 314, -458, 724,-1464,30168, 1639, -782, 500, -358, 272, -215, 173, -143, 118, -100, 82, -72, 53, -53, 25, -50, 25, 2, + 24, -40, 7, -26, 12, -11, -4, 18, -42, 72, -112, 163, -231, 327, -475, 751,-1516,30158, 1703, -811, 519, -371, 281, -222, 179, -147, 121, -102, 84, -73, 54, -53, 26, -50, 25, 2, + 24, -40, 7, -25, 11, -10, -5, 20, -45, 76, -117, 169, -240, 339, -492, 777,-1568,30147, 1768, -841, 537, -384, 291, -229, 184, -151, 124, -105, 85, -74, 55, -54, 26, -51, 25, 2, + 24, -40, 6, -25, 10, -9, -7, 22, -48, 79, -122, 176, -249, 351, -509, 804,-1620,30136, 1833, -871, 556, -397, 300, -236, 189, -155, 127, -107, 87, -75, 56, -54, 26, -51, 25, 2, + 24, -39, 6, -24, 9, -8, -8, 25, -51, 83, -127, 183, -258, 363, -526, 830,-1671,30125, 1898, -901, 575, -410, 310, -243, 195, -159, 130, -109, 88, -76, 56, -55, 27, -51, 25, 2, + 24, -39, 6, -24, 9, -7, -10, 27, -54, 87, -132, 189, -267, 375, -543, 856,-1722,30113, 1964, -931, 593, -423, 319, -250, 200, -163, 133, -111, 90, -77, 57, -55, 27, -51, 25, 2, + 24, -39, 5, -23, 8, -6, -12, 29, -57, 91, -137, 196, -275, 387, -560, 882,-1773,30101, 2029, -961, 612, -436, 329, -257, 205, -167, 136, -113, 92, -78, 58, -56, 27, -51, 25, 2, + 24, -39, 5, -23, 7, -5, -13, 31, -59, 95, -142, 203, -284, 399, -577, 909,-1823,30088, 2095, -991, 631, -449, 338, -264, 211, -171, 139, -116, 93, -80, 59, -56, 28, -51, 25, 2, + 24, -39, 5, -22, 6, -4, -15, 33, -62, 99, -147, 209, -293, 411, -594, 935,-1874,30075, 2161,-1021, 649, -462, 348, -271, 216, -175, 142, -118, 95, -81, 59, -57, 28, -52, 25, 2, + 24, -38, 4, -22, 5, -2, -16, 35, -65, 102, -152, 216, -302, 423, -611, 960,-1924,30062, 2228,-1051, 668, -475, 357, -278, 221, -179, 145, -120, 96, -82, 60, -57, 28, -52, 25, 2, + 24, -38, 4, -21, 5, -1, -18, 37, -68, 106, -157, 223, -311, 435, -628, 986,-1973,30048, 2294,-1081, 687, -488, 367, -286, 227, -183, 148, -122, 98, -83, 61, -58, 28, -52, 25, 2, + 24, -38, 4, -21, 4, 0, -19, 39, -71, 110, -162, 229, -320, 447, -644, 1012,-2023,30034, 2361,-1111, 705, -501, 376, -293, 232, -187, 151, -124, 99, -84, 62, -58, 29, -52, 25, 2, + 24, -38, 3, -20, 3, 1, -21, 41, -74, 114, -167, 236, -328, 458, -661, 1038,-2072,30020, 2427,-1141, 724, -514, 386, -300, 237, -191, 154, -127, 101, -85, 62, -59, 29, -52, 25, 2, + 24, -38, 3, -20, 2, 2, -22, 44, -77, 117, -172, 242, -337, 470, -678, 1063,-2121,30005, 2494,-1171, 743, -527, 395, -307, 243, -195, 157, -129, 103, -86, 63, -59, 29, -52, 25, 2, + 24, -37, 3, -19, 2, 3, -24, 46, -79, 121, -177, 249, -346, 482, -694, 1089,-2170,29990, 2562,-1201, 761, -540, 405, -314, 248, -199, 160, -131, 104, -87, 64, -60, 30, -52, 25, 2, + 23, -37, 2, -19, 1, 4, -25, 48, -82, 125, -182, 255, -354, 494, -711, 1114,-2218,29974, 2629,-1231, 780, -553, 414, -321, 253, -203, 163, -133, 106, -88, 65, -60, 30, -53, 25, 2, + 23, -37, 2, -18, 0, 5, -27, 50, -85, 129, -187, 262, -363, 505, -727, 1139,-2267,29958, 2697,-1262, 799, -566, 424, -328, 259, -207, 166, -135, 107, -89, 65, -61, 30, -53, 25, 2, + 23, -37, 1, -18, -1, 6, -28, 52, -88, 132, -192, 268, -372, 517, -744, 1164,-2314,29942, 2764,-1292, 818, -579, 433, -335, 264, -211, 169, -138, 109, -91, 66, -61, 31, -53, 25, 2, + 23, -36, 1, -17, -1, 7, -30, 54, -91, 136, -197, 275, -380, 529, -760, 1190,-2362,29925, 2832,-1322, 836, -592, 443, -342, 269, -215, 172, -140, 110, -92, 67, -62, 31, -53, 25, 2, + 23, -36, 1, -17, -2, 8, -31, 56, -93, 140, -202, 281, -389, 540, -776, 1215,-2409,29908, 2901,-1352, 855, -605, 452, -349, 275, -219, 175, -142, 112, -93, 68, -62, 31, -53, 25, 2, + 23, -36, 0, -16, -3, 9, -33, 58, -96, 144, -206, 288, -397, 552, -793, 1239,-2457,29891, 2969,-1382, 874, -618, 462, -356, 280, -223, 178, -144, 114, -94, 68, -63, 32, -53, 25, 2, + 23, -36, 0, -16, -4, 11, -34, 60, -99, 147, -211, 294, -406, 563, -809, 1264,-2504,29873, 3038,-1413, 892, -631, 471, -363, 285, -227, 181, -146, 115, -95, 69, -63, 32, -54, 25, 2, + 23, -36, 0, -15, -4, 12, -36, 62, -102, 151, -216, 301, -414, 575, -825, 1289,-2550,29855, 3106,-1443, 911, -644, 481, -370, 290, -231, 184, -148, 117, -96, 70, -63, 32, -54, 25, 2, + 23, -35, -1, -15, -5, 13, -38, 64, -104, 155, -221, 307, -423, 586, -841, 1314,-2596,29836, 3175,-1473, 930, -657, 490, -377, 296, -235, 187, -151, 118, -97, 71, -64, 32, -54, 25, 2, + 23, -35, -1, -14, -6, 14, -39, 66, -107, 158, -226, 313, -431, 598, -857, 1338,-2643,29817, 3244,-1504, 948, -670, 499, -384, 301, -239, 190, -153, 120, -98, 71, -64, 33, -54, 25, 2, + 23, -35, -1, -14, -7, 15, -40, 68, -110, 162, -231, 320, -440, 609, -873, 1362,-2688,29798, 3314,-1534, 967, -682, 509, -391, 306, -243, 193, -155, 121, -99, 72, -65, 33, -54, 25, 2, + 23, -35, -2, -13, -7, 16, -42, 70, -113, 166, -235, 326, -448, 621, -889, 1387,-2734,29778, 3383,-1564, 986, -695, 518, -398, 312, -247, 196, -157, 123, -100, 73, -65, 33, -54, 25, 2, + 23, -35, -2, -13, -8, 17, -43, 72, -115, 169, -240, 332, -457, 632, -905, 1411,-2779,29758, 3453,-1594, 1004, -708, 528, -405, 317, -251, 199, -159, 124, -101, 74, -66, 34, -54, 25, 2, + 23, -34, -2, -12, -9, 18, -45, 74, -118, 173, -245, 339, -465, 643, -921, 1435,-2824,29738, 3522,-1625, 1023, -721, 537, -412, 322, -255, 202, -161, 126, -102, 74, -66, 34, -55, 25, 3, + 23, -34, -3, -12, -10, 19, -46, 76, -121, 176, -250, 345, -473, 654, -936, 1459,-2869,29717, 3592,-1655, 1042, -734, 546, -419, 327, -259, 204, -163, 128, -103, 75, -67, 34, -55, 24, 3, + 23, -34, -3, -11, -10, 20, -48, 79, -124, 180, -255, 351, -481, 666, -952, 1483,-2913,29696, 3663,-1685, 1060, -747, 556, -426, 333, -263, 207, -166, 129, -105, 76, -67, 34, -55, 24, 3, + 23, -34, -3, -11, -11, 21, -49, 81, -126, 184, -259, 357, -490, 677, -968, 1507,-2958,29674, 3733,-1716, 1079, -760, 565, -433, 338, -266, 210, -168, 131, -106, 76, -68, 35, -55, 24, 3, + 23, -33, -4, -10, -12, 22, -51, 83, -129, 187, -264, 364, -498, 688, -983, 1530,-3001,29652, 3803,-1746, 1098, -773, 574, -440, 343, -270, 213, -170, 132, -107, 77, -68, 35, -55, 24, 3, + 23, -33, -4, -10, -13, 23, -52, 85, -132, 191, -269, 370, -506, 699, -999, 1554,-3045,29630, 3874,-1776, 1116, -785, 584, -447, 348, -274, 216, -172, 134, -108, 78, -68, 35, -55, 24, 3, + 23, -33, -4, -9, -13, 24, -54, 87, -134, 194, -273, 376, -514, 710,-1014, 1577,-3088,29607, 3945,-1807, 1135, -798, 593, -454, 353, -278, 219, -174, 135, -109, 79, -69, 36, -55, 24, 3, + 23, -33, -5, -9, -14, 25, -55, 89, -137, 198, -278, 382, -523, 721,-1030, 1601,-3132,29584, 4016,-1837, 1153, -811, 602, -461, 359, -282, 222, -176, 137, -110, 79, -69, 36, -56, 24, 3, + 23, -33, -5, -8, -15, 26, -57, 90, -140, 201, -283, 388, -531, 732,-1045, 1624,-3174,29561, 4087,-1867, 1172, -824, 612, -468, 364, -286, 225, -178, 138, -111, 80, -70, 36, -56, 24, 3, + 23, -32, -5, -8, -16, 27, -58, 92, -142, 205, -287, 394, -539, 743,-1060, 1647,-3217,29537, 4159,-1898, 1190, -837, 621, -475, 369, -290, 228, -180, 140, -112, 81, -70, 37, -56, 24, 3, + 23, -32, -6, -7, -16, 29, -60, 94, -145, 208, -292, 401, -547, 754,-1076, 1670,-3259,29513, 4230,-1928, 1209, -849, 630, -482, 374, -294, 231, -183, 141, -113, 81, -71, 37, -56, 24, 3, + 23, -32, -6, -7, -17, 30, -61, 96, -148, 212, -297, 407, -555, 764,-1091, 1693,-3301,29489, 4302,-1958, 1227, -862, 640, -489, 379, -298, 233, -185, 143, -114, 82, -71, 37, -56, 24, 3, + 23, -32, -7, -6, -18, 31, -63, 98, -150, 215, -301, 413, -563, 775,-1106, 1716,-3343,29464, 4374,-1989, 1246, -875, 649, -496, 385, -302, 236, -187, 144, -115, 83, -72, 37, -56, 24, 3, + 23, -32, -7, -6, -19, 32, -64, 100, -153, 219, -306, 419, -571, 786,-1121, 1739,-3385,29439, 4446,-2019, 1264, -888, 658, -503, 390, -305, 239, -189, 146, -116, 83, -72, 38, -56, 24, 3, + 22, -31, -7, -5, -19, 33, -65, 102, -156, 222, -310, 425, -579, 797,-1136, 1761,-3426,29413, 4518,-2049, 1283, -900, 667, -509, 395, -309, 242, -191, 147, -117, 84, -72, 38, -57, 24, 3, + 22, -31, -8, -5, -20, 34, -67, 104, -158, 226, -315, 431, -587, 807,-1151, 1784,-3467,29387, 4590,-2080, 1301, -913, 676, -516, 400, -313, 245, -193, 149, -118, 85, -73, 38, -57, 24, 3, + 22, -31, -8, -4, -21, 35, -68, 106, -161, 229, -319, 437, -595, 818,-1165, 1806,-3507,29361, 4663,-2110, 1320, -926, 686, -523, 405, -317, 248, -195, 150, -119, 86, -73, 38, -57, 24, 3, + 22, -31, -8, -4, -21, 36, -70, 108, -163, 233, -324, 443, -602, 828,-1180, 1828,-3548,29334, 4735,-2140, 1338, -938, 695, -530, 410, -321, 251, -197, 152, -120, 86, -74, 39, -57, 24, 3, + 22, -30, -9, -4, -22, 37, -71, 110, -166, 236, -328, 448, -610, 839,-1195, 1850,-3588,29307, 4808,-2170, 1356, -951, 704, -537, 415, -325, 253, -199, 153, -121, 87, -74, 39, -57, 24, 3, + 22, -30, -9, -3, -23, 38, -72, 112, -168, 239, -333, 454, -618, 849,-1210, 1873,-3628,29280, 4881,-2201, 1375, -963, 713, -544, 421, -328, 256, -201, 155, -122, 88, -75, 39, -57, 24, 3, + 22, -30, -9, -3, -24, 39, -74, 114, -171, 243, -337, 460, -626, 860,-1224, 1894,-3667,29252, 4954,-2231, 1393, -976, 722, -550, 426, -332, 259, -203, 156, -123, 88, -75, 40, -57, 24, 3, + 22, -30, -10, -2, -24, 40, -75, 116, -174, 246, -342, 466, -633, 870,-1239, 1916,-3706,29224, 5027,-2261, 1411, -989, 731, -557, 431, -336, 262, -205, 158, -124, 89, -75, 40, -57, 24, 3, + 22, -30, -10, -2, -25, 41, -77, 118, -176, 250, -346, 472, -641, 881,-1253, 1938,-3745,29196, 5101,-2291, 1430,-1001, 740, -564, 436, -340, 265, -207, 159, -125, 90, -76, 40, -58, 24, 3, + 22, -29, -10, -1, -26, 42, -78, 120, -179, 253, -351, 478, -649, 891,-1267, 1959,-3784,29167, 5174,-2321, 1448,-1014, 750, -571, 441, -344, 268, -210, 160, -126, 90, -76, 40, -58, 24, 3, + 22, -29, -11, -1, -26, 43, -79, 121, -181, 256, -355, 483, -656, 901,-1282, 1981,-3823,29138, 5248,-2352, 1466,-1026, 759, -577, 446, -347, 270, -212, 162, -127, 91, -77, 41, -58, 24, 3, + 22, -29, -11, 0, -27, 44, -81, 123, -184, 260, -359, 489, -664, 911,-1296, 2002,-3861,29108, 5322,-2382, 1484,-1039, 768, -584, 451, -351, 273, -214, 163, -128, 92, -77, 41, -58, 24, 3, + 22, -29, -11, 0, -28, 45, -82, 125, -186, 263, -364, 495, -672, 922,-1310, 2024,-3899,29079, 5396,-2412, 1502,-1051, 777, -591, 456, -355, 276, -216, 165, -129, 92, -78, 41, -58, 24, 3, + 22, -28, -12, 1, -29, 46, -84, 127, -189, 266, -368, 501, -679, 932,-1324, 2045,-3936,29048, 5470,-2442, 1521,-1064, 786, -597, 461, -359, 279, -218, 166, -130, 93, -78, 41, -58, 24, 3, + 22, -28, -12, 1, -29, 47, -85, 129, -191, 269, -372, 506, -687, 942,-1338, 2066,-3974,29018, 5545,-2472, 1539,-1076, 795, -604, 466, -362, 281, -220, 168, -131, 94, -78, 42, -58, 24, 3, + 22, -28, -12, 2, -30, 48, -86, 131, -194, 273, -377, 512, -694, 952,-1352, 2086,-4011,28987, 5619,-2502, 1557,-1088, 804, -611, 471, -366, 284, -222, 169, -132, 94, -79, 42, -58, 24, 3, + 22, -28, -13, 2, -31, 49, -88, 133, -196, 276, -381, 518, -701, 962,-1366, 2107,-4047,28956, 5694,-2532, 1575,-1101, 813, -617, 476, -370, 287, -224, 171, -133, 95, -79, 42, -58, 24, 3, + 22, -28, -13, 3, -31, 50, -89, 134, -199, 279, -385, 523, -709, 972,-1380, 2128,-4084,28924, 5768,-2562, 1593,-1113, 821, -624, 481, -374, 290, -226, 172, -134, 96, -80, 42, -59, 24, 3, + 22, -27, -13, 3, -32, 51, -90, 136, -201, 282, -390, 529, -716, 981,-1393, 2148,-4120,28892, 5843,-2592, 1611,-1125, 830, -631, 486, -377, 293, -228, 173, -135, 96, -80, 43, -59, 24, 3, + 22, -27, -14, 4, -33, 52, -92, 138, -203, 286, -394, 534, -724, 991,-1407, 2169,-4156,28860, 5918,-2622, 1629,-1138, 839, -637, 491, -381, 295, -230, 175, -136, 97, -80, 43, -59, 24, 4, + 22, -27, -14, 4, -33, 53, -93, 140, -206, 289, -398, 540, -731, 1001,-1421, 2189,-4192,28827, 5993,-2652, 1647,-1150, 848, -644, 496, -385, 298, -232, 176, -137, 98, -81, 43, -59, 24, 4, + 21, -27, -14, 5, -34, 54, -94, 142, -208, 292, -402, 545, -738, 1011,-1434, 2209,-4227,28794, 6068,-2682, 1665,-1162, 857, -650, 501, -388, 301, -234, 178, -138, 98, -81, 43, -59, 24, 4, + 21, -26, -15, 5, -35, 54, -96, 143, -211, 295, -406, 551, -745, 1020,-1447, 2229,-4262,28761, 6144,-2711, 1682,-1174, 866, -657, 505, -392, 303, -236, 179, -139, 99, -82, 44, -59, 24, 4, + 21, -26, -15, 5, -36, 55, -97, 145, -213, 298, -410, 556, -752, 1030,-1461, 2249,-4297,28727, 6219,-2741, 1700,-1186, 875, -663, 510, -396, 306, -238, 180, -140, 100, -82, 44, -59, 23, 4, + 21, -26, -15, 6, -36, 56, -98, 147, -215, 302, -415, 562, -760, 1040,-1474, 2269,-4332,28693, 6295,-2771, 1718,-1199, 883, -670, 515, -399, 309, -240, 182, -141, 100, -82, 44, -59, 23, 4, + 21, -26, -16, 6, -37, 57, -100, 149, -218, 305, -419, 567, -767, 1049,-1487, 2288,-4366,28659, 6371,-2801, 1736,-1211, 892, -676, 520, -403, 311, -241, 183, -142, 101, -83, 44, -59, 23, 4, + 21, -26, -16, 7, -38, 58, -101, 151, -220, 308, -423, 572, -774, 1059,-1500, 2308,-4400,28624, 6447,-2830, 1753,-1223, 901, -683, 525, -407, 314, -243, 185, -143, 101, -83, 45, -59, 23, 4, + 21, -25, -16, 7, -38, 59, -102, 152, -222, 311, -427, 578, -781, 1068,-1513, 2327,-4433,28589, 6523,-2860, 1771,-1235, 910, -689, 530, -410, 317, -245, 186, -144, 102, -84, 45, -60, 23, 4, + 21, -25, -17, 8, -39, 60, -104, 154, -225, 314, -431, 583, -788, 1077,-1526, 2347,-4467,28553, 6599,-2890, 1789,-1247, 918, -696, 535, -414, 319, -247, 187, -145, 103, -84, 45, -60, 23, 4, + 21, -25, -17, 8, -40, 61, -105, 156, -227, 317, -435, 588, -795, 1087,-1539, 2366,-4500,28518, 6675,-2919, 1806,-1259, 927, -702, 539, -417, 322, -249, 189, -146, 103, -84, 45, -60, 23, 4, + 21, -25, -17, 9, -40, 62, -106, 158, -229, 320, -439, 593, -802, 1096,-1552, 2385,-4533,28482, 6751,-2949, 1824,-1271, 936, -709, 544, -421, 325, -251, 190, -147, 104, -85, 46, -60, 23, 4, + 21, -25, -18, 9, -41, 63, -107, 159, -232, 323, -443, 599, -808, 1105,-1565, 2404,-4565,28445, 6828,-2978, 1841,-1283, 944, -715, 549, -424, 327, -253, 191, -148, 105, -85, 46, -60, 23, 4, + 21, -24, -18, 10, -42, 64, -109, 161, -234, 326, -447, 604, -815, 1114,-1578, 2422,-4598,28408, 6905,-3007, 1859,-1295, 953, -721, 554, -428, 330, -255, 193, -149, 105, -85, 46, -60, 23, 4, + 21, -24, -18, 10, -42, 65, -110, 163, -236, 329, -451, 609, -822, 1123,-1590, 2441,-4630,28371, 6981,-3037, 1876,-1306, 961, -728, 558, -432, 333, -257, 194, -149, 106, -86, 46, -60, 23, 4, + 21, -24, -19, 10, -43, 66, -111, 164, -239, 332, -455, 614, -829, 1132,-1603, 2460,-4661,28334, 7058,-3066, 1894,-1318, 970, -734, 563, -435, 335, -259, 196, -150, 106, -86, 46, -60, 23, 4, + 21, -24, -19, 11, -44, 67, -113, 166, -241, 335, -459, 619, -836, 1141,-1615, 2478,-4693,28296, 7135,-3095, 1911,-1330, 978, -740, 568, -439, 338, -261, 197, -151, 107, -86, 47, -60, 23, 4, + 21, -23, -19, 11, -44, 68, -114, 168, -243, 338, -462, 624, -842, 1150,-1627, 2496,-4724,28258, 7212,-3125, 1928,-1342, 987, -747, 573, -442, 340, -262, 198, -152, 108, -87, 47, -60, 23, 4, + 21, -23, -20, 12, -45, 68, -115, 169, -245, 341, -466, 629, -849, 1159,-1640, 2514,-4755,28219, 7289,-3154, 1946,-1354, 995, -753, 577, -446, 343, -264, 199, -153, 108, -87, 47, -60, 23, 4, + 21, -23, -20, 12, -46, 69, -116, 171, -248, 344, -470, 634, -855, 1168,-1652, 2532,-4785,28180, 7367,-3183, 1963,-1365, 1004, -759, 582, -449, 346, -266, 201, -154, 109, -88, 47, -61, 23, 4, + 21, -23, -20, 13, -46, 70, -117, 173, -250, 347, -474, 639, -862, 1177,-1664, 2550,-4816,28141, 7444,-3212, 1980,-1377, 1012, -765, 587, -452, 348, -268, 202, -155, 109, -88, 48, -61, 23, 4, + 21, -23, -21, 13, -47, 71, -119, 174, -252, 350, -478, 644, -869, 1185,-1676, 2568,-4846,28102, 7522,-3241, 1997,-1388, 1020, -772, 591, -456, 351, -270, 203, -156, 110, -88, 48, -61, 23, 4, + 20, -22, -21, 14, -47, 72, -120, 176, -254, 353, -481, 649, -875, 1194,-1688, 2586,-4876,28062, 7599,-3270, 2014,-1400, 1029, -778, 596, -459, 353, -272, 205, -157, 111, -89, 48, -61, 23, 4, + 20, -22, -21, 14, -48, 73, -121, 178, -256, 355, -485, 654, -881, 1203,-1700, 2603,-4905,28022, 7677,-3299, 2031,-1412, 1037, -784, 600, -463, 356, -274, 206, -158, 111, -89, 48, -61, 23, 4, + 20, -22, -22, 14, -49, 74, -122, 179, -258, 358, -489, 659, -888, 1211,-1712, 2620,-4934,27981, 7755,-3328, 2048,-1423, 1045, -790, 605, -466, 358, -275, 207, -158, 112, -89, 48, -61, 23, 4, + 20, -22, -22, 15, -49, 75, -124, 181, -261, 361, -493, 664, -894, 1220,-1723, 2638,-4963,27941, 7833,-3357, 2065,-1435, 1054, -796, 609, -470, 361, -277, 209, -159, 112, -90, 49, -61, 22, 4, + 20, -21, -22, 15, -50, 76, -125, 183, -263, 364, -496, 669, -901, 1228,-1735, 2655,-4992,27899, 7911,-3385, 2082,-1446, 1062, -802, 614, -473, 363, -279, 210, -160, 113, -90, 49, -61, 22, 4, + 20, -21, -23, 16, -51, 76, -126, 184, -265, 367, -500, 673, -907, 1237,-1747, 2672,-5020,27858, 7989,-3414, 2099,-1457, 1070, -808, 619, -476, 366, -281, 211, -161, 113, -90, 49, -61, 22, 4, + 20, -21, -23, 16, -51, 77, -127, 186, -267, 369, -504, 678, -913, 1245,-1758, 2688,-5048,27816, 8067,-3443, 2115,-1469, 1078, -814, 623, -480, 368, -283, 212, -162, 114, -91, 49, -61, 22, 5, + 20, -21, -23, 17, -52, 78, -128, 187, -269, 372, -507, 683, -919, 1253,-1769, 2705,-5076,27774, 8145,-3471, 2132,-1480, 1086, -820, 628, -483, 371, -284, 214, -163, 115, -91, 49, -61, 22, 5, + 20, -21, -24, 17, -53, 79, -129, 189, -271, 375, -511, 687, -925, 1261,-1781, 2722,-5103,27732, 8224,-3500, 2149,-1491, 1094, -826, 632, -486, 373, -286, 215, -164, 115, -91, 50, -61, 22, 5, + 20, -20, -24, 17, -53, 80, -131, 190, -273, 378, -514, 692, -931, 1270,-1792, 2738,-5130,27689, 8302,-3528, 2165,-1502, 1102, -832, 636, -490, 375, -288, 216, -164, 116, -92, 50, -61, 22, 5, + 20, -20, -24, 18, -54, 81, -132, 192, -275, 380, -518, 697, -938, 1278,-1803, 2754,-5157,27646, 8381,-3556, 2182,-1514, 1110, -838, 641, -493, 378, -290, 217, -165, 116, -92, 50, -62, 22, 5, + 20, -20, -24, 18, -54, 82, -133, 194, -277, 383, -521, 701, -944, 1286,-1814, 2770,-5184,27602, 8459,-3585, 2198,-1525, 1118, -844, 645, -496, 380, -291, 219, -166, 117, -92, 50, -62, 22, 5, + 20, -20, -25, 19, -55, 82, -134, 195, -279, 386, -525, 706, -950, 1294,-1825, 2786,-5210,27559, 8538,-3613, 2215,-1536, 1126, -850, 650, -499, 383, -293, 220, -167, 117, -93, 50, -62, 22, 5, + 20, -19, -25, 19, -56, 83, -135, 197, -281, 388, -528, 710, -955, 1302,-1836, 2802,-5236,27515, 8617,-3641, 2231,-1547, 1134, -856, 654, -503, 385, -295, 221, -168, 118, -93, 51, -62, 22, 5, + 20, -19, -25, 20, -56, 84, -136, 198, -283, 391, -532, 715, -961, 1309,-1847, 2818,-5262,27470, 8696,-3669, 2248,-1558, 1142, -862, 658, -506, 388, -297, 222, -169, 118, -93, 51, -62, 22, 5, + 20, -19, -26, 20, -57, 85, -138, 200, -285, 394, -535, 719, -967, 1317,-1857, 2834,-5288,27426, 8775,-3697, 2264,-1569, 1150, -867, 663, -509, 390, -298, 223, -169, 119, -94, 51, -62, 22, 5, + 20, -19, -26, 20, -57, 86, -139, 201, -287, 396, -539, 724, -973, 1325,-1868, 2849,-5313,27381, 8854,-3725, 2280,-1580, 1158, -873, 667, -512, 392, -300, 225, -170, 119, -94, 51, -62, 22, 5, + 20, -19, -26, 21, -58, 87, -140, 203, -289, 399, -542, 728, -979, 1333,-1878, 2864,-5338,27335, 8933,-3753, 2296,-1591, 1166, -879, 671, -516, 395, -302, 226, -171, 120, -94, 51, -62, 22, 5, + 19, -18, -27, 21, -59, 87, -141, 204, -291, 401, -545, 733, -985, 1340,-1889, 2879,-5363,27290, 9012,-3780, 2312,-1601, 1173, -885, 676, -519, 397, -303, 227, -172, 120, -95, 52, -62, 22, 5, + 19, -18, -27, 22, -59, 88, -142, 206, -293, 404, -549, 737, -990, 1348,-1899, 2894,-5387,27244, 9091,-3808, 2328,-1612, 1181, -890, 680, -522, 399, -305, 228, -173, 121, -95, 52, -62, 21, 5, + 19, -18, -27, 22, -60, 89, -143, 207, -295, 407, -552, 741, -996, 1355,-1910, 2909,-5411,27197, 9171,-3836, 2344,-1623, 1189, -896, 684, -525, 402, -307, 229, -173, 122, -95, 52, -62, 21, 5, + 19, -18, -28, 22, -60, 90, -144, 208, -297, 409, -555, 745,-1001, 1363,-1920, 2924,-5435,27151, 9250,-3863, 2360,-1634, 1197, -902, 688, -528, 404, -308, 231, -174, 122, -95, 52, -62, 21, 5, + 19, -17, -28, 23, -61, 91, -145, 210, -299, 412, -558, 750,-1007, 1370,-1930, 2939,-5458,27104, 9330,-3891, 2376,-1644, 1204, -907, 692, -531, 406, -310, 232, -175, 123, -96, 52, -62, 21, 5, + 19, -17, -28, 23, -62, 91, -146, 211, -301, 414, -562, 754,-1012, 1377,-1940, 2953,-5482,27057, 9409,-3918, 2392,-1655, 1212, -913, 697, -534, 408, -312, 233, -176, 123, -96, 52, -62, 21, 5, + 19, -17, -29, 24, -62, 92, -147, 213, -303, 416, -565, 758,-1018, 1385,-1950, 2968,-5505,27009, 9489,-3945, 2407,-1665, 1219, -918, 701, -537, 411, -313, 234, -176, 124, -96, 53, -62, 21, 5, + 19, -17, -29, 24, -63, 93, -148, 214, -305, 419, -568, 762,-1023, 1392,-1960, 2982,-5527,26961, 9569,-3973, 2423,-1676, 1227, -924, 705, -540, 413, -315, 235, -177, 124, -97, 53, -62, 21, 5, + 19, -17, -29, 24, -63, 94, -150, 216, -307, 421, -571, 766,-1029, 1399,-1969, 2996,-5550,26913, 9649,-4000, 2439,-1686, 1234, -929, 709, -543, 415, -316, 236, -178, 125, -97, 53, -62, 21, 5, + 19, -16, -29, 25, -64, 94, -151, 217, -308, 424, -574, 770,-1034, 1406,-1979, 3010,-5572,26865, 9728,-4027, 2454,-1697, 1242, -935, 713, -547, 417, -318, 237, -179, 125, -97, 53, -62, 21, 5, + 19, -16, -30, 25, -64, 95, -152, 218, -310, 426, -577, 774,-1039, 1413,-1989, 3024,-5594,26816, 9808,-4054, 2469,-1707, 1249, -940, 717, -550, 420, -320, 238, -180, 125, -97, 53, -63, 21, 5, + 19, -16, -30, 26, -65, 96, -153, 220, -312, 428, -581, 778,-1045, 1420,-1998, 3037,-5615,26767, 9888,-4080, 2485,-1717, 1256, -946, 721, -553, 422, -321, 240, -180, 126, -98, 53, -63, 21, 5, + 19, -16, -30, 26, -66, 97, -154, 221, -314, 431, -584, 782,-1050, 1427,-2007, 3051,-5637,26718, 9968,-4107, 2500,-1728, 1264, -951, 725, -555, 424, -323, 241, -181, 126, -98, 54, -63, 21, 5, + 19, -15, -31, 26, -66, 97, -155, 222, -316, 433, -587, 786,-1055, 1434,-2017, 3064,-5658,26668,10048,-4134, 2515,-1738, 1271, -956, 729, -558, 426, -324, 242, -182, 127, -98, 54, -63, 21, 6, + 19, -15, -31, 27, -67, 98, -156, 224, -317, 435, -590, 790,-1060, 1440,-2026, 3077,-5678,26618,10129,-4160, 2530,-1748, 1278, -962, 733, -561, 428, -326, 243, -182, 127, -99, 54, -63, 21, 6, + 19, -15, -31, 27, -67, 99, -157, 225, -319, 438, -593, 794,-1065, 1447,-2035, 3090,-5699,26568,10209,-4187, 2546,-1758, 1285, -967, 737, -564, 430, -327, 244, -183, 128, -99, 54, -63, 20, 6, + 19, -15, -32, 27, -68, 100, -158, 226, -321, 440, -596, 798,-1070, 1454,-2044, 3103,-5719,26518,10289,-4213, 2561,-1768, 1293, -972, 741, -567, 432, -329, 245, -184, 128, -99, 54, -63, 20, 6, + 18, -15, -32, 28, -68, 100, -159, 228, -323, 442, -598, 802,-1075, 1460,-2053, 3116,-5739,26467,10369,-4240, 2575,-1778, 1300, -978, 745, -570, 435, -330, 246, -185, 129, -99, 54, -63, 20, 6, + 18, -14, -32, 28, -69, 101, -160, 229, -324, 444, -601, 805,-1080, 1467,-2062, 3129,-5758,26416,10450,-4266, 2590,-1788, 1307, -983, 749, -573, 437, -332, 247, -185, 129, -100, 54, -63, 20, 6, + 18, -14, -32, 29, -69, 102, -161, 230, -326, 447, -604, 809,-1085, 1473,-2071, 3141,-5778,26364,10530,-4292, 2605,-1798, 1314, -988, 752, -576, 439, -333, 248, -186, 130, -100, 55, -63, 20, 6, + 18, -14, -33, 29, -70, 103, -162, 232, -328, 449, -607, 813,-1090, 1480,-2079, 3154,-5797,26312,10610,-4318, 2620,-1807, 1321, -993, 756, -579, 441, -335, 249, -187, 130, -100, 55, -63, 20, 6, + 18, -14, -33, 29, -70, 103, -163, 233, -329, 451, -610, 817,-1094, 1486,-2088, 3166,-5816,26260,10691,-4344, 2635,-1817, 1328, -998, 760, -581, 443, -336, 250, -187, 131, -100, 55, -63, 20, 6, + 18, -14, -33, 30, -71, 104, -164, 234, -331, 453, -613, 820,-1099, 1492,-2096, 3178,-5834,26208,10772,-4370, 2649,-1827, 1335,-1003, 764, -584, 445, -338, 251, -188, 131, -101, 55, -63, 20, 6, + 18, -13, -34, 30, -71, 105, -165, 235, -333, 455, -615, 824,-1104, 1498,-2105, 3190,-5852,26156,10852,-4395, 2664,-1837, 1342,-1008, 768, -587, 447, -339, 252, -189, 131, -101, 55, -63, 20, 6, + 18, -13, -34, 30, -72, 105, -165, 237, -334, 457, -618, 827,-1108, 1505,-2113, 3202,-5870,26103,10933,-4421, 2678,-1846, 1348,-1013, 771, -590, 449, -341, 253, -189, 132, -101, 55, -63, 20, 6, + 18, -13, -34, 31, -72, 106, -166, 238, -336, 460, -621, 831,-1113, 1511,-2121, 3213,-5888,26050,11013,-4446, 2692,-1856, 1355,-1018, 775, -592, 451, -342, 254, -190, 132, -101, 55, -63, 20, 6, + 18, -13, -34, 31, -73, 107, -167, 239, -337, 462, -624, 834,-1118, 1517,-2129, 3225,-5905,25996,11094,-4472, 2707,-1865, 1362,-1023, 779, -595, 453, -344, 255, -191, 133, -101, 56, -63, 20, 6, + 18, -12, -35, 32, -74, 108, -168, 240, -339, 464, -626, 838,-1122, 1523,-2137, 3236,-5922,25942,11175,-4497, 2721,-1875, 1369,-1028, 782, -598, 455, -345, 256, -191, 133, -102, 56, -63, 19, 6, + 18, -12, -35, 32, -74, 108, -169, 242, -341, 466, -629, 841,-1127, 1528,-2145, 3248,-5939,25888,11255,-4522, 2735,-1884, 1375,-1033, 786, -601, 457, -346, 257, -192, 133, -102, 56, -63, 19, 6, + 18, -12, -35, 32, -75, 109, -170, 243, -342, 468, -632, 845,-1131, 1534,-2153, 3259,-5956,25834,11336,-4547, 2749,-1893, 1382,-1038, 789, -603, 459, -348, 258, -193, 134, -102, 56, -63, 19, 6, + 18, -12, -36, 33, -75, 110, -171, 244, -344, 470, -634, 848,-1135, 1540,-2161, 3270,-5972,25780,11417,-4572, 2763,-1902, 1388,-1043, 793, -606, 461, -349, 259, -193, 134, -102, 56, -63, 19, 6, + 18, -12, -36, 33, -76, 110, -172, 245, -345, 472, -637, 851,-1140, 1546,-2169, 3280,-5988,25725,11498,-4597, 2777,-1912, 1395,-1048, 797, -608, 463, -351, 260, -194, 135, -103, 56, -63, 19, 6, + 18, -11, -36, 33, -76, 111, -173, 246, -347, 474, -639, 854,-1144, 1551,-2176, 3291,-6004,25670,11579,-4621, 2790,-1921, 1401,-1052, 800, -611, 465, -352, 261, -194, 135, -103, 56, -63, 19, 6, + 18, -11, -36, 34, -77, 112, -174, 247, -348, 476, -642, 858,-1148, 1557,-2184, 3302,-6019,25614,11660,-4646, 2804,-1930, 1408,-1057, 804, -614, 466, -353, 262, -195, 135, -103, 56, -63, 19, 6, + 17, -11, -37, 34, -77, 112, -175, 249, -350, 478, -644, 861,-1152, 1562,-2191, 3312,-6034,25559,11741,-4671, 2818,-1939, 1414,-1062, 807, -616, 468, -355, 263, -196, 136, -103, 56, -63, 19, 6, + 17, -11, -37, 34, -78, 113, -175, 250, -351, 479, -647, 864,-1156, 1568,-2198, 3322,-6049,25503,11821,-4695, 2831,-1948, 1421,-1066, 810, -619, 470, -356, 264, -196, 136, -103, 57, -63, 19, 7, + 17, -11, -37, 35, -78, 113, -176, 251, -353, 481, -649, 867,-1160, 1573,-2206, 3332,-6064,25446,11902,-4719, 2845,-1957, 1427,-1071, 814, -621, 472, -357, 265, -197, 137, -104, 57, -63, 19, 7, + 17, -10, -37, 35, -78, 114, -177, 252, -354, 483, -651, 870,-1164, 1578,-2213, 3342,-6078,25390,11983,-4743, 2858,-1965, 1433,-1075, 817, -624, 474, -358, 266, -197, 137, -104, 57, -63, 19, 7, + 17, -10, -38, 35, -79, 115, -178, 253, -356, 485, -654, 873,-1168, 1583,-2220, 3352,-6092,25333,12064,-4767, 2871,-1974, 1439,-1080, 821, -626, 476, -360, 266, -198, 137, -104, 57, -63, 18, 7, + 17, -10, -38, 36, -79, 115, -179, 254, -357, 487, -656, 876,-1172, 1589,-2227, 3362,-6106,25276,12145,-4791, 2884,-1983, 1446,-1085, 824, -629, 477, -361, 267, -199, 138, -104, 57, -63, 18, 7, + 17, -10, -38, 36, -80, 116, -180, 255, -358, 489, -658, 879,-1176, 1594,-2233, 3371,-6120,25219,12226,-4815, 2898,-1991, 1452,-1089, 827, -631, 479, -362, 268, -199, 138, -104, 57, -63, 18, 7, + 17, -10, -39, 36, -80, 117, -180, 256, -360, 490, -661, 882,-1180, 1599,-2240, 3380,-6133,25161,12307,-4838, 2911,-2000, 1458,-1093, 831, -633, 481, -363, 269, -200, 138, -105, 57, -63, 18, 7, + 17, -9, -39, 37, -81, 117, -181, 257, -361, 492, -663, 885,-1184, 1604,-2247, 3390,-6146,25103,12388,-4862, 2923,-2008, 1464,-1098, 834, -636, 483, -365, 270, -200, 139, -105, 57, -63, 18, 7, + 17, -9, -39, 37, -81, 118, -182, 258, -362, 494, -665, 888,-1187, 1609,-2253, 3399,-6159,25045,12470,-4885, 2936,-2017, 1470,-1102, 837, -638, 484, -366, 271, -201, 139, -105, 57, -63, 18, 7, + 17, -9, -39, 37, -82, 118, -183, 259, -364, 496, -667, 891,-1191, 1613,-2260, 3408,-6171,24987,12551,-4909, 2949,-2025, 1476,-1106, 840, -641, 486, -367, 272, -201, 139, -105, 57, -63, 18, 7, + 17, -9, -40, 38, -82, 119, -184, 260, -365, 497, -670, 894,-1195, 1618,-2266, 3416,-6183,24928,12632,-4932, 2962,-2034, 1481,-1111, 843, -643, 488, -368, 272, -202, 140, -105, 58, -63, 18, 7, + 17, -9, -40, 38, -83, 120, -184, 261, -366, 499, -672, 897,-1198, 1623,-2272, 3425,-6195,24869,12713,-4955, 2974,-2042, 1487,-1115, 846, -645, 489, -370, 273, -202, 140, -105, 58, -63, 18, 7, + 17, -8, -40, 38, -83, 120, -185, 262, -368, 501, -674, 899,-1202, 1627,-2278, 3434,-6207,24810,12794,-4978, 2987,-2050, 1493,-1119, 850, -647, 491, -371, 274, -203, 140, -106, 58, -63, 18, 7, + 17, -8, -40, 39, -84, 121, -186, 263, -369, 502, -676, 902,-1205, 1632,-2285, 3442,-6218,24751,12875,-5000, 2999,-2058, 1499,-1123, 853, -650, 493, -372, 275, -203, 141, -106, 58, -63, 17, 7, + 17, -8, -41, 39, -84, 121, -187, 264, -370, 504, -678, 905,-1209, 1636,-2291, 3450,-6229,24691,12956,-5023, 3011,-2066, 1504,-1127, 856, -652, 494, -373, 276, -204, 141, -106, 58, -63, 17, 7, + 16, -8, -41, 39, -84, 122, -187, 265, -371, 506, -680, 907,-1212, 1641,-2296, 3458,-6240,24631,13037,-5045, 3024,-2074, 1510,-1132, 859, -654, 496, -374, 276, -204, 141, -106, 58, -63, 17, 7, + 16, -7, -41, 40, -85, 122, -188, 266, -373, 507, -682, 910,-1216, 1645,-2302, 3466,-6251,24571,13118,-5068, 3036,-2082, 1516,-1136, 862, -656, 498, -375, 277, -205, 142, -106, 58, -63, 17, 7, + 16, -7, -41, 40, -85, 123, -189, 267, -374, 509, -684, 912,-1219, 1649,-2308, 3474,-6261,24511,13199,-5090, 3048,-2090, 1521,-1140, 865, -659, 499, -376, 278, -205, 142, -106, 58, -63, 17, 7, + 16, -7, -42, 40, -86, 124, -190, 268, -375, 510, -686, 915,-1222, 1654,-2313, 3481,-6271,24450,13280,-5112, 3060,-2097, 1527,-1144, 868, -661, 501, -377, 279, -206, 142, -107, 58, -63, 17, 7, + 16, -7, -42, 40, -86, 124, -190, 269, -376, 512, -688, 917,-1225, 1658,-2319, 3489,-6281,24389,13361,-5134, 3071,-2105, 1532,-1148, 870, -663, 502, -379, 279, -206, 142, -107, 58, -63, 17, 7, + 16, -7, -42, 41, -87, 125, -191, 270, -377, 513, -690, 920,-1228, 1662,-2324, 3496,-6290,24328,13442,-5156, 3083,-2113, 1537,-1151, 873, -665, 504, -380, 280, -207, 143, -107, 58, -63, 17, 8, + 16, -6, -42, 41, -87, 125, -192, 271, -379, 515, -692, 922,-1231, 1666,-2330, 3503,-6300,24266,13523,-5177, 3095,-2120, 1543,-1155, 876, -667, 505, -381, 281, -207, 143, -107, 58, -63, 17, 8, + 16, -6, -43, 41, -87, 126, -192, 272, -380, 516, -694, 924,-1234, 1670,-2335, 3510,-6309,24205,13604,-5199, 3106,-2128, 1548,-1159, 879, -669, 507, -382, 281, -208, 143, -107, 58, -63, 17, 8, + 16, -6, -43, 42, -88, 126, -193, 273, -381, 517, -695, 927,-1237, 1674,-2340, 3517,-6317,24143,13685,-5220, 3118,-2135, 1553,-1163, 882, -671, 508, -383, 282, -208, 144, -107, 58, -63, 16, 8, + 16, -6, -43, 42, -88, 127, -194, 274, -382, 519, -697, 929,-1240, 1678,-2345, 3524,-6326,24081,13766,-5241, 3129,-2143, 1558,-1167, 885, -673, 510, -384, 283, -209, 144, -107, 59, -63, 16, 8, + 16, -6, -43, 42, -89, 127, -194, 274, -383, 520, -699, 931,-1243, 1681,-2350, 3531,-6334,24018,13847,-5262, 3140,-2150, 1563,-1170, 887, -675, 511, -385, 284, -209, 144, -107, 59, -63, 16, 8, + 16, -5, -44, 43, -89, 128, -195, 275, -384, 522, -701, 934,-1246, 1685,-2355, 3537,-6342,23956,13928,-5283, 3151,-2157, 1568,-1174, 890, -677, 512, -386, 284, -210, 144, -108, 59, -63, 16, 8, + 16, -5, -44, 43, -89, 128, -196, 276, -385, 523, -702, 936,-1249, 1689,-2359, 3543,-6349,23893,14009,-5304, 3162,-2164, 1573,-1178, 893, -679, 514, -387, 285, -210, 145, -108, 59, -63, 16, 8, + 16, -5, -44, 43, -90, 129, -196, 277, -386, 524, -704, 938,-1252, 1692,-2364, 3549,-6357,23830,14090,-5325, 3173,-2171, 1578,-1181, 895, -681, 515, -388, 286, -210, 145, -108, 59, -63, 16, 8, + 16, -5, -44, 43, -90, 129, -197, 278, -387, 526, -706, 940,-1254, 1696,-2369, 3555,-6364,23766,14170,-5345, 3184,-2178, 1583,-1185, 898, -683, 517, -389, 286, -211, 145, -108, 59, -63, 16, 8, + 16, -5, -45, 44, -90, 130, -198, 278, -388, 527, -707, 942,-1257, 1699,-2373, 3561,-6371,23703,14251,-5365, 3195,-2185, 1588,-1188, 900, -685, 518, -390, 287, -211, 145, -108, 59, -63, 16, 8, + 15, -4, -45, 44, -91, 130, -198, 279, -389, 528, -709, 944,-1259, 1702,-2377, 3567,-6377,23639,14332,-5386, 3205,-2192, 1593,-1192, 903, -687, 519, -391, 287, -212, 145, -108, 59, -62, 16, 8, + 15, -4, -45, 44, -91, 131, -199, 280, -390, 529, -711, 946,-1262, 1705,-2382, 3573,-6384,23575,14413,-5406, 3216,-2199, 1598,-1195, 905, -688, 521, -391, 288, -212, 146, -108, 59, -62, 15, 8, + 15, -4, -45, 44, -92, 131, -199, 281, -391, 531, -712, 948,-1264, 1709,-2386, 3578,-6390,23510,14493,-5425, 3226,-2205, 1602,-1199, 908, -690, 522, -392, 289, -212, 146, -108, 59, -62, 15, 8, + 15, -4, -46, 45, -92, 132, -200, 282, -392, 532, -714, 950,-1267, 1712,-2390, 3583,-6396,23446,14574,-5445, 3236,-2212, 1607,-1202, 910, -692, 523, -393, 289, -213, 146, -108, 59, -62, 15, 8, + 15, -4, -46, 45, -92, 132, -201, 282, -393, 533, -715, 952,-1269, 1715,-2394, 3589,-6401,23381,14655,-5465, 3247,-2219, 1611,-1205, 913, -694, 524, -394, 290, -213, 146, -108, 59, -62, 15, 8, + 15, -3, -46, 45, -93, 133, -201, 283, -394, 534, -717, 954,-1272, 1718,-2398, 3594,-6407,23316,14735,-5484, 3257,-2225, 1616,-1208, 915, -695, 526, -395, 290, -213, 147, -109, 59, -62, 15, 8, + 15, -3, -46, 46, -93, 133, -202, 284, -395, 535, -718, 955,-1274, 1721,-2401, 3598,-6412,23251,14816,-5503, 3267,-2231, 1620,-1212, 917, -697, 527, -396, 291, -214, 147, -109, 59, -62, 15, 8, + 15, -3, -46, 46, -93, 133, -202, 284, -396, 536, -719, 957,-1276, 1724,-2405, 3603,-6416,23186,14896,-5522, 3277,-2238, 1625,-1215, 920, -699, 528, -397, 292, -214, 147, -109, 59, -62, 15, 8, + 15, -3, -47, 46, -94, 134, -203, 285, -397, 537, -721, 959,-1278, 1726,-2409, 3608,-6421,23120,14977,-5541, 3286,-2244, 1629,-1218, 922, -701, 529, -397, 292, -214, 147, -109, 59, -62, 15, 8, + 15, -3, -47, 46, -94, 134, -203, 286, -398, 539, -722, 960,-1280, 1729,-2412, 3612,-6425,23054,15057,-5560, 3296,-2250, 1633,-1221, 924, -702, 530, -398, 293, -215, 147, -109, 59, -62, 14, 9, + 15, -3, -47, 47, -94, 135, -204, 286, -398, 540, -723, 962,-1282, 1732,-2416, 3616,-6429,22988,15138,-5579, 3306,-2256, 1638,-1224, 927, -704, 532, -399, 293, -215, 147, -109, 59, -62, 14, 9, + 15, -2, -47, 47, -95, 135, -205, 287, -399, 541, -725, 964,-1285, 1734,-2419, 3620,-6433,22922,15218,-5597, 3315,-2262, 1642,-1227, 929, -705, 533, -400, 294, -215, 148, -109, 59, -62, 14, 9, + 15, -2, -48, 47, -95, 136, -205, 288, -400, 542, -726, 965,-1286, 1737,-2422, 3624,-6436,22855,15298,-5615, 3324,-2268, 1646,-1230, 931, -707, 534, -401, 294, -216, 148, -109, 59, -62, 14, 9, + 15, -2, -48, 47, -95, 136, -206, 288, -401, 543, -727, 967,-1288, 1739,-2425, 3628,-6440,22788,15379,-5633, 3334,-2274, 1650,-1233, 933, -708, 535, -401, 295, -216, 148, -109, 59, -62, 14, 9, + 15, -2, -48, 48, -96, 136, -206, 289, -402, 544, -728, 968,-1290, 1742,-2428, 3632,-6443,22721,15459,-5651, 3343,-2280, 1654,-1236, 935, -710, 536, -402, 295, -216, 148, -109, 59, -62, 14, 9, + 15, -2, -48, 48, -96, 137, -207, 290, -402, 544, -729, 970,-1292, 1744,-2431, 3636,-6445,22654,15539,-5669, 3352,-2285, 1658,-1239, 937, -711, 537, -403, 296, -216, 148, -109, 59, -62, 14, 9, + 14, -1, -48, 48, -96, 137, -207, 290, -403, 545, -731, 971,-1294, 1746,-2434, 3639,-6448,22587,15619,-5687, 3361,-2291, 1662,-1241, 939, -713, 538, -404, 296, -217, 148, -109, 59, -62, 14, 9, + 14, -1, -49, 48, -97, 138, -208, 291, -404, 546, -732, 973,-1296, 1748,-2437, 3642,-6450,22519,15699,-5704, 3369,-2297, 1666,-1244, 941, -714, 539, -404, 296, -217, 149, -109, 59, -62, 13, 9, + 14, -1, -49, 48, -97, 138, -208, 291, -405, 547, -733, 974,-1297, 1750,-2439, 3645,-6452,22452,15779,-5721, 3378,-2302, 1669,-1247, 943, -716, 540, -405, 297, -217, 149, -109, 59, -61, 13, 9, + 14, -1, -49, 49, -97, 138, -208, 292, -405, 548, -734, 975,-1299, 1752,-2442, 3648,-6454,22384,15859,-5738, 3387,-2307, 1673,-1250, 945, -717, 541, -406, 297, -218, 149, -109, 59, -61, 13, 9, + 14, -1, -49, 49, -98, 139, -209, 293, -406, 549, -735, 976,-1300, 1754,-2444, 3651,-6455,22315,15939,-5755, 3395,-2313, 1677,-1252, 947, -718, 542, -406, 298, -218, 149, -109, 59, -61, 13, 9, + 14, 0, -49, 49, -98, 139, -209, 293, -407, 550, -736, 978,-1302, 1756,-2447, 3654,-6457,22247,16018,-5772, 3403,-2318, 1680,-1255, 949, -720, 543, -407, 298, -218, 149, -109, 59, -61, 13, 9, + 14, 0, -50, 49, -98, 139, -210, 294, -407, 550, -737, 979,-1303, 1758,-2449, 3656,-6458,22178,16098,-5788, 3412,-2323, 1684,-1257, 951, -721, 544, -407, 299, -218, 149, -109, 59, -61, 13, 9, + 14, 0, -50, 50, -98, 140, -210, 294, -408, 551, -738, 980,-1305, 1760,-2451, 3659,-6459,22110,16178,-5805, 3420,-2328, 1687,-1260, 952, -722, 545, -408, 299, -218, 149, -109, 59, -61, 13, 9, + 14, 0, -50, 50, -99, 140, -211, 295, -408, 552, -739, 981,-1306, 1762,-2453, 3661,-6459,22041,16257,-5821, 3428,-2333, 1691,-1262, 954, -724, 546, -409, 299, -219, 149, -109, 59, -61, 13, 9, + 14, 0, -50, 50, -99, 140, -211, 295, -409, 553, -740, 982,-1308, 1763,-2455, 3663,-6459,21971,16337,-5837, 3435,-2338, 1694,-1265, 956, -725, 547, -409, 300, -219, 149, -109, 59, -61, 12, 9, + 14, 0, -50, 50, -99, 141, -212, 296, -410, 553, -740, 983,-1309, 1765,-2457, 3665,-6459,21902,16416,-5853, 3443,-2343, 1697,-1267, 958, -726, 547, -410, 300, -219, 149, -109, 59, -61, 12, 9, + 14, 1, -51, 50, -100, 141, -212, 296, -410, 554, -741, 984,-1310, 1766,-2459, 3667,-6459,21832,16496,-5868, 3451,-2347, 1700,-1269, 959, -727, 548, -410, 300, -219, 150, -109, 59, -61, 12, 10, + 14, 1, -51, 51, -100, 141, -212, 297, -411, 555, -742, 985,-1311, 1768,-2460, 3669,-6459,21763,16575,-5884, 3458,-2352, 1704,-1271, 961, -728, 549, -411, 301, -219, 150, -109, 59, -61, 12, 10, + 14, 1, -51, 51, -100, 142, -213, 297, -411, 555, -743, 986,-1312, 1769,-2462, 3670,-6458,21693,16654,-5899, 3466,-2357, 1707,-1274, 962, -730, 550, -411, 301, -220, 150, -109, 59, -61, 12, 10, + 14, 1, -51, 51, -100, 142, -213, 297, -412, 556, -743, 987,-1313, 1770,-2463, 3672,-6457,21623,16733,-5914, 3473,-2361, 1710,-1276, 964, -731, 551, -412, 301, -220, 150, -109, 59, -60, 12, 10, + 14, 1, -51, 51, -101, 142, -213, 298, -412, 557, -744, 988,-1314, 1771,-2465, 3673,-6456,21552,16812,-5929, 3480,-2366, 1713,-1278, 965, -732, 551, -412, 302, -220, 150, -109, 59, -60, 12, 10, + 13, 2, -52, 51, -101, 143, -214, 298, -413, 557, -745, 989,-1315, 1773,-2466, 3674,-6454,21482,16891,-5944, 3487,-2370, 1716,-1280, 967, -733, 552, -413, 302, -220, 150, -109, 59, -60, 11, 10, + 13, 2, -52, 52, -101, 143, -214, 299, -413, 558, -746, 989,-1316, 1774,-2467, 3675,-6453,21411,16970,-5959, 3494,-2374, 1719,-1282, 968, -734, 553, -413, 302, -220, 150, -109, 59, -60, 11, 10, + 13, 2, -52, 52, -101, 143, -214, 299, -414, 558, -746, 990,-1317, 1775,-2468, 3676,-6451,21340,17049,-5973, 3501,-2378, 1721,-1284, 970, -735, 553, -414, 302, -220, 150, -109, 59, -60, 11, 10, + 13, 2, -52, 52, -102, 143, -215, 299, -414, 559, -747, 991,-1318, 1776,-2469, 3677,-6449,21269,17127,-5987, 3508,-2382, 1724,-1286, 971, -736, 554, -414, 303, -220, 150, -109, 59, -60, 11, 10, + 13, 2, -52, 52, -102, 144, -215, 300, -415, 559, -747, 991,-1319, 1776,-2470, 3677,-6446,21198,17206,-6001, 3514,-2386, 1727,-1288, 973, -737, 555, -415, 303, -221, 150, -109, 59, -60, 11, 10, + 13, 2, -53, 52, -102, 144, -215, 300, -415, 560, -748, 992,-1319, 1777,-2471, 3678,-6444,21126,17284,-6015, 3520,-2390, 1729,-1290, 974, -738, 555, -415, 303, -221, 150, -109, 59, -60, 11, 10, + 13, 3, -53, 53, -102, 144, -216, 301, -415, 560, -748, 993,-1320, 1778,-2472, 3678,-6441,21055,17363,-6028, 3527,-2394, 1732,-1291, 975, -738, 556, -415, 303, -221, 150, -109, 58, -60, 11, 10, + 13, 3, -53, 53, -103, 145, -216, 301, -416, 561, -749, 993,-1321, 1779,-2472, 3678,-6438,20983,17441,-6042, 3533,-2398, 1734,-1293, 976, -739, 556, -416, 304, -221, 150, -109, 58, -60, 10, 10, + 13, 3, -53, 53, -103, 145, -216, 301, -416, 561, -749, 994,-1321, 1779,-2473, 3678,-6434,20911,17519,-6055, 3539,-2401, 1737,-1295, 978, -740, 557, -416, 304, -221, 150, -109, 58, -59, 10, 10, + 13, 3, -53, 53, -103, 145, -217, 302, -416, 561, -750, 994,-1322, 1780,-2473, 3678,-6431,20839,17597,-6068, 3545,-2405, 1739,-1296, 979, -741, 558, -416, 304, -221, 150, -109, 58, -59, 10, 10, + 13, 3, -53, 53, -103, 145, -217, 302, -417, 562, -750, 995,-1322, 1780,-2474, 3678,-6427,20767,17675,-6081, 3551,-2408, 1742,-1298, 980, -742, 558, -417, 304, -221, 150, -109, 58, -59, 10, 10, + 13, 4, -54, 53, -104, 145, -217, 302, -417, 562, -750, 995,-1323, 1781,-2474, 3677,-6423,20694,17753,-6093, 3556,-2412, 1744,-1300, 981, -743, 559, -417, 304, -221, 150, -109, 58, -59, 10, 10, + 13, 4, -54, 54, -104, 146, -217, 302, -417, 562, -751, 995,-1323, 1781,-2474, 3677,-6419,20621,17831,-6106, 3562,-2415, 1746,-1301, 982, -743, 559, -417, 305, -221, 150, -109, 58, -59, 10, 11, + 13, 4, -54, 54, -104, 146, -218, 303, -418, 563, -751, 996,-1323, 1781,-2474, 3676,-6414,20549,17909,-6118, 3567,-2418, 1748,-1303, 983, -744, 560, -418, 305, -221, 150, -109, 58, -59, 10, 11, + 13, 4, -54, 54, -104, 146, -218, 303, -418, 563, -751, 996,-1323, 1781,-2474, 3675,-6409,20476,17986,-6130, 3573,-2421, 1750,-1304, 984, -745, 560, -418, 305, -221, 150, -109, 58, -59, 9, 11, + 13, 4, -54, 54, -104, 146, -218, 303, -418, 563, -752, 996,-1324, 1781,-2474, 3674,-6405,20403,18064,-6142, 3578,-2424, 1752,-1305, 985, -745, 560, -418, 305, -221, 150, -109, 58, -59, 9, 11, + 12, 4, -54, 54, -105, 147, -218, 303, -418, 563, -752, 996,-1324, 1781,-2474, 3673,-6399,20329,18141,-6154, 3583,-2427, 1754,-1307, 986, -746, 561, -418, 305, -221, 150, -109, 58, -59, 9, 11, + 12, 5, -55, 54, -105, 147, -219, 304, -419, 564, -752, 996,-1324, 1781,-2473, 3672,-6394,20256,18218,-6165, 3588,-2430, 1756,-1308, 987, -747, 561, -419, 305, -221, 150, -108, 58, -58, 9, 11, + 12, 5, -55, 55, -105, 147, -219, 304, -419, 564, -752, 997,-1324, 1781,-2473, 3670,-6388,20182,18296,-6176, 3593,-2433, 1758,-1309, 988, -747, 562, -419, 305, -221, 150, -108, 58, -58, 9, 11, + 12, 5, -55, 55, -105, 147, -219, 304, -419, 564, -752, 997,-1324, 1781,-2472, 3669,-6382,20108,18373,-6187, 3597,-2436, 1759,-1310, 988, -748, 562, -419, 305, -221, 150, -108, 57, -58, 9, 11, + 12, 5, -55, 55, -105, 147, -219, 304, -419, 564, -752, 997,-1324, 1781,-2472, 3667,-6376,20035,18449,-6198, 3602,-2438, 1761,-1312, 989, -748, 562, -419, 305, -221, 150, -108, 57, -58, 8, 11, + 12, 5, -55, 55, -105, 148, -219, 304, -419, 564, -752, 997,-1324, 1781,-2471, 3666,-6370,19960,18526,-6209, 3606,-2441, 1763,-1313, 990, -749, 563, -419, 305, -221, 150, -108, 57, -58, 8, 11, + 12, 5, -55, 55, -106, 148, -220, 305, -420, 564, -753, 997,-1324, 1780,-2470, 3664,-6364,19886,18603,-6219, 3611,-2443, 1764,-1314, 991, -749, 563, -420, 306, -221, 150, -108, 57, -58, 8, 11, + 12, 6, -56, 55, -106, 148, -220, 305, -420, 564, -753, 997,-1323, 1780,-2469, 3662,-6357,19812,18679,-6229, 3615,-2445, 1766,-1315, 991, -749, 563, -420, 306, -221, 150, -108, 57, -58, 8, 11, + 12, 6, -56, 55, -106, 148, -220, 305, -420, 564, -753, 997,-1323, 1779,-2468, 3659,-6350,19737,18756,-6239, 3619,-2448, 1767,-1316, 992, -750, 563, -420, 306, -221, 150, -108, 57, -58, 8, 11, + 12, 6, -56, 56, -106, 148, -220, 305, -420, 564, -752, 996,-1323, 1779,-2467, 3657,-6343,19663,18832,-6249, 3623,-2450, 1768,-1316, 992, -750, 564, -420, 306, -221, 149, -108, 57, -57, 8, 11, + 12, 6, -56, 56, -106, 148, -220, 305, -420, 564, -752, 996,-1323, 1778,-2466, 3655,-6335,19588,18908,-6259, 3627,-2452, 1770,-1317, 993, -751, 564, -420, 306, -221, 149, -107, 57, -57, 8, 11, + 12, 6, -56, 56, -106, 148, -220, 305, -420, 564, -752, 996,-1322, 1778,-2465, 3652,-6328,19513,18984,-6268, 3630,-2454, 1771,-1318, 993, -751, 564, -420, 306, -221, 149, -107, 57, -57, 7, 11, + 12, 6, -56, 56, -107, 149, -220, 305, -420, 564, -752, 996,-1322, 1777,-2464, 3649,-6320,19438,19060,-6277, 3634,-2456, 1772,-1319, 994, -751, 564, -420, 306, -221, 149, -107, 57, -57, 7, 11, + 12, 7, -56, 56, -107, 149, -221, 305, -420, 564, -752, 995,-1321, 1776,-2462, 3646,-6312,19363,19136,-6286, 3637,-2457, 1773,-1319, 994, -751, 564, -420, 305, -221, 149, -107, 56, -57, 7, 12, + 12, 7, -57, 56, -107, 149, -221, 305, -420, 564, -752, 995,-1321, 1775,-2461, 3644,-6303,19287,19212,-6295, 3640,-2459, 1774,-1320, 995, -752, 564, -420, 305, -221, 149, -107, 56, -57, 7, 12, + 12, 7, -57, 56, -107, 149, -221, 305, -420, 564, -752, 995,-1320, 1774,-2459, 3640,-6295,19212,19287,-6303, 3644,-2461, 1775,-1321, 995, -752, 564, -420, 305, -221, 149, -107, 56, -57, 7, 12, + 12, 7, -57, 56, -107, 149, -221, 305, -420, 564, -751, 994,-1319, 1773,-2457, 3637,-6286,19136,19363,-6312, 3646,-2462, 1776,-1321, 995, -752, 564, -420, 305, -221, 149, -107, 56, -56, 7, 12, + 11, 7, -57, 57, -107, 149, -221, 306, -420, 564, -751, 994,-1319, 1772,-2456, 3634,-6277,19060,19438,-6320, 3649,-2464, 1777,-1322, 996, -752, 564, -420, 305, -220, 149, -107, 56, -56, 6, 12, + 11, 7, -57, 57, -107, 149, -221, 306, -420, 564, -751, 993,-1318, 1771,-2454, 3630,-6268,18984,19513,-6328, 3652,-2465, 1778,-1322, 996, -752, 564, -420, 305, -220, 148, -106, 56, -56, 6, 12, + 11, 8, -57, 57, -107, 149, -221, 306, -420, 564, -751, 993,-1317, 1770,-2452, 3627,-6259,18908,19588,-6335, 3655,-2466, 1778,-1323, 996, -752, 564, -420, 305, -220, 148, -106, 56, -56, 6, 12, + 11, 8, -57, 57, -108, 149, -221, 306, -420, 564, -750, 992,-1316, 1768,-2450, 3623,-6249,18832,19663,-6343, 3657,-2467, 1779,-1323, 996, -752, 564, -420, 305, -220, 148, -106, 56, -56, 6, 12, + 11, 8, -58, 57, -108, 150, -221, 306, -420, 563, -750, 992,-1316, 1767,-2448, 3619,-6239,18756,19737,-6350, 3659,-2468, 1779,-1323, 997, -753, 564, -420, 305, -220, 148, -106, 55, -56, 6, 12, + 11, 8, -58, 57, -108, 150, -221, 306, -420, 563, -749, 991,-1315, 1766,-2445, 3615,-6229,18679,19812,-6357, 3662,-2469, 1780,-1323, 997, -753, 564, -420, 305, -220, 148, -106, 55, -56, 6, 12, + 11, 8, -58, 57, -108, 150, -221, 306, -420, 563, -749, 991,-1314, 1764,-2443, 3611,-6219,18603,19886,-6364, 3664,-2470, 1780,-1324, 997, -753, 564, -420, 305, -220, 148, -106, 55, -55, 5, 12, + 11, 8, -58, 57, -108, 150, -221, 305, -419, 563, -749, 990,-1313, 1763,-2441, 3606,-6209,18526,19960,-6370, 3666,-2471, 1781,-1324, 997, -752, 564, -419, 304, -219, 148, -105, 55, -55, 5, 12, + 11, 8, -58, 57, -108, 150, -221, 305, -419, 562, -748, 989,-1312, 1761,-2438, 3602,-6198,18449,20035,-6376, 3667,-2472, 1781,-1324, 997, -752, 564, -419, 304, -219, 147, -105, 55, -55, 5, 12, + 11, 9, -58, 57, -108, 150, -221, 305, -419, 562, -748, 988,-1310, 1759,-2436, 3597,-6187,18373,20108,-6382, 3669,-2472, 1781,-1324, 997, -752, 564, -419, 304, -219, 147, -105, 55, -55, 5, 12, + 11, 9, -58, 58, -108, 150, -221, 305, -419, 562, -747, 988,-1309, 1758,-2433, 3593,-6176,18296,20182,-6388, 3670,-2473, 1781,-1324, 997, -752, 564, -419, 304, -219, 147, -105, 55, -55, 5, 12, + 11, 9, -58, 58, -108, 150, -221, 305, -419, 561, -747, 987,-1308, 1756,-2430, 3588,-6165,18218,20256,-6394, 3672,-2473, 1781,-1324, 996, -752, 564, -419, 304, -219, 147, -105, 54, -55, 5, 12, + 11, 9, -59, 58, -109, 150, -221, 305, -418, 561, -746, 986,-1307, 1754,-2427, 3583,-6154,18141,20329,-6399, 3673,-2474, 1781,-1324, 996, -752, 563, -418, 303, -218, 147, -105, 54, -54, 4, 12, + 11, 9, -59, 58, -109, 150, -221, 305, -418, 560, -745, 985,-1305, 1752,-2424, 3578,-6142,18064,20403,-6405, 3674,-2474, 1781,-1324, 996, -752, 563, -418, 303, -218, 146, -104, 54, -54, 4, 13, + 11, 9, -59, 58, -109, 150, -221, 305, -418, 560, -745, 984,-1304, 1750,-2421, 3573,-6130,17986,20476,-6409, 3675,-2474, 1781,-1323, 996, -751, 563, -418, 303, -218, 146, -104, 54, -54, 4, 13, + 11, 10, -59, 58, -109, 150, -221, 305, -418, 560, -744, 983,-1303, 1748,-2418, 3567,-6118,17909,20549,-6414, 3676,-2474, 1781,-1323, 996, -751, 563, -418, 303, -218, 146, -104, 54, -54, 4, 13, + 11, 10, -59, 58, -109, 150, -221, 305, -417, 559, -743, 982,-1301, 1746,-2415, 3562,-6106,17831,20621,-6419, 3677,-2474, 1781,-1323, 995, -751, 562, -417, 302, -217, 146, -104, 54, -54, 4, 13, + 10, 10, -59, 58, -109, 150, -221, 304, -417, 559, -743, 981,-1300, 1744,-2412, 3556,-6093,17753,20694,-6423, 3677,-2474, 1781,-1323, 995, -750, 562, -417, 302, -217, 145, -104, 53, -54, 4, 13, + 10, 10, -59, 58, -109, 150, -221, 304, -417, 558, -742, 980,-1298, 1742,-2408, 3551,-6081,17675,20767,-6427, 3678,-2474, 1780,-1322, 995, -750, 562, -417, 302, -217, 145, -103, 53, -53, 3, 13, + 10, 10, -59, 58, -109, 150, -221, 304, -416, 558, -741, 979,-1296, 1739,-2405, 3545,-6068,17597,20839,-6431, 3678,-2473, 1780,-1322, 994, -750, 561, -416, 302, -217, 145, -103, 53, -53, 3, 13, + 10, 10, -59, 58, -109, 150, -221, 304, -416, 557, -740, 978,-1295, 1737,-2401, 3539,-6055,17519,20911,-6434, 3678,-2473, 1779,-1321, 994, -749, 561, -416, 301, -216, 145, -103, 53, -53, 3, 13, + 10, 10, -60, 58, -109, 150, -221, 304, -416, 556, -739, 976,-1293, 1734,-2398, 3533,-6042,17441,20983,-6438, 3678,-2472, 1779,-1321, 993, -749, 561, -416, 301, -216, 145, -103, 53, -53, 3, 13, + 10, 11, -60, 58, -109, 150, -221, 303, -415, 556, -738, 975,-1291, 1732,-2394, 3527,-6028,17363,21055,-6441, 3678,-2472, 1778,-1320, 993, -748, 560, -415, 301, -216, 144, -102, 53, -53, 3, 13, + 10, 11, -60, 59, -109, 150, -221, 303, -415, 555, -738, 974,-1290, 1729,-2390, 3520,-6015,17284,21126,-6444, 3678,-2471, 1777,-1319, 992, -748, 560, -415, 300, -215, 144, -102, 52, -53, 2, 13, + 10, 11, -60, 59, -109, 150, -221, 303, -415, 555, -737, 973,-1288, 1727,-2386, 3514,-6001,17206,21198,-6446, 3677,-2470, 1776,-1319, 991, -747, 559, -415, 300, -215, 144, -102, 52, -52, 2, 13, + 10, 11, -60, 59, -109, 150, -220, 303, -414, 554, -736, 971,-1286, 1724,-2382, 3508,-5987,17127,21269,-6449, 3677,-2469, 1776,-1318, 991, -747, 559, -414, 299, -215, 143, -102, 52, -52, 2, 13, + 10, 11, -60, 59, -109, 150, -220, 302, -414, 553, -735, 970,-1284, 1721,-2378, 3501,-5973,17049,21340,-6451, 3676,-2468, 1775,-1317, 990, -746, 558, -414, 299, -214, 143, -101, 52, -52, 2, 13, + 10, 11, -60, 59, -109, 150, -220, 302, -413, 553, -734, 968,-1282, 1719,-2374, 3494,-5959,16970,21411,-6453, 3675,-2467, 1774,-1316, 989, -746, 558, -413, 299, -214, 143, -101, 52, -52, 2, 13, + 10, 11, -60, 59, -109, 150, -220, 302, -413, 552, -733, 967,-1280, 1716,-2370, 3487,-5944,16891,21482,-6454, 3674,-2466, 1773,-1315, 989, -745, 557, -413, 298, -214, 143, -101, 51, -52, 2, 13, + 10, 12, -60, 59, -109, 150, -220, 302, -412, 551, -732, 965,-1278, 1713,-2366, 3480,-5929,16812,21552,-6456, 3673,-2465, 1771,-1314, 988, -744, 557, -412, 298, -213, 142, -101, 51, -51, 1, 14, + 10, 12, -60, 59, -109, 150, -220, 301, -412, 551, -731, 964,-1276, 1710,-2361, 3473,-5914,16733,21623,-6457, 3672,-2463, 1770,-1313, 987, -743, 556, -412, 297, -213, 142, -100, 51, -51, 1, 14, + 10, 12, -61, 59, -109, 150, -220, 301, -411, 550, -730, 962,-1274, 1707,-2357, 3466,-5899,16654,21693,-6458, 3670,-2462, 1769,-1312, 986, -743, 555, -411, 297, -213, 142, -100, 51, -51, 1, 14, + 10, 12, -61, 59, -109, 150, -219, 301, -411, 549, -728, 961,-1271, 1704,-2352, 3458,-5884,16575,21763,-6459, 3669,-2460, 1768,-1311, 985, -742, 555, -411, 297, -212, 141, -100, 51, -51, 1, 14, + 10, 12, -61, 59, -109, 150, -219, 300, -410, 548, -727, 959,-1269, 1700,-2347, 3451,-5868,16496,21832,-6459, 3667,-2459, 1766,-1310, 984, -741, 554, -410, 296, -212, 141, -100, 50, -51, 1, 14, + 9, 12, -61, 59, -109, 149, -219, 300, -410, 547, -726, 958,-1267, 1697,-2343, 3443,-5853,16416,21902,-6459, 3665,-2457, 1765,-1309, 983, -740, 553, -410, 296, -212, 141, -99, 50, -50, 0, 14, + 9, 12, -61, 59, -109, 149, -219, 300, -409, 547, -725, 956,-1265, 1694,-2338, 3435,-5837,16337,21971,-6459, 3663,-2455, 1763,-1308, 982, -740, 553, -409, 295, -211, 140, -99, 50, -50, 0, 14, + 9, 13, -61, 59, -109, 149, -219, 299, -409, 546, -724, 954,-1262, 1691,-2333, 3428,-5821,16257,22041,-6459, 3661,-2453, 1762,-1306, 981, -739, 552, -408, 295, -211, 140, -99, 50, -50, 0, 14, + 9, 13, -61, 59, -109, 149, -218, 299, -408, 545, -722, 952,-1260, 1687,-2328, 3420,-5805,16178,22110,-6459, 3659,-2451, 1760,-1305, 980, -738, 551, -408, 294, -210, 140, -98, 50, -50, 0, 14, + 9, 13, -61, 59, -109, 149, -218, 299, -407, 544, -721, 951,-1257, 1684,-2323, 3412,-5788,16098,22178,-6458, 3656,-2449, 1758,-1303, 979, -737, 550, -407, 294, -210, 139, -98, 49, -50, 0, 14, + 9, 13, -61, 59, -109, 149, -218, 298, -407, 543, -720, 949,-1255, 1680,-2318, 3403,-5772,16018,22247,-6457, 3654,-2447, 1756,-1302, 978, -736, 550, -407, 293, -209, 139, -98, 49, -49, 0, 14, + 9, 13, -61, 59, -109, 149, -218, 298, -406, 542, -718, 947,-1252, 1677,-2313, 3395,-5755,15939,22315,-6455, 3651,-2444, 1754,-1300, 976, -735, 549, -406, 293, -209, 139, -98, 49, -49, -1, 14, + 9, 13, -61, 59, -109, 149, -218, 297, -406, 541, -717, 945,-1250, 1673,-2307, 3387,-5738,15859,22384,-6454, 3648,-2442, 1752,-1299, 975, -734, 548, -405, 292, -208, 138, -97, 49, -49, -1, 14, + 9, 13, -61, 59, -109, 149, -217, 297, -405, 540, -716, 943,-1247, 1669,-2302, 3378,-5721,15779,22452,-6452, 3645,-2439, 1750,-1297, 974, -733, 547, -405, 291, -208, 138, -97, 48, -49, -1, 14, + 9, 13, -62, 59, -109, 149, -217, 296, -404, 539, -714, 941,-1244, 1666,-2297, 3369,-5704,15699,22519,-6450, 3642,-2437, 1748,-1296, 973, -732, 546, -404, 291, -208, 138, -97, 48, -49, -1, 14, + 9, 14, -62, 59, -109, 148, -217, 296, -404, 538, -713, 939,-1241, 1662,-2291, 3361,-5687,15619,22587,-6448, 3639,-2434, 1746,-1294, 971, -731, 545, -403, 290, -207, 137, -96, 48, -48, -1, 14, + 9, 14, -62, 59, -109, 148, -216, 296, -403, 537, -711, 937,-1239, 1658,-2285, 3352,-5669,15539,22654,-6445, 3636,-2431, 1744,-1292, 970, -729, 544, -402, 290, -207, 137, -96, 48, -48, -2, 15, + 9, 14, -62, 59, -109, 148, -216, 295, -402, 536, -710, 935,-1236, 1654,-2280, 3343,-5651,15459,22721,-6443, 3632,-2428, 1742,-1290, 968, -728, 544, -402, 289, -206, 136, -96, 48, -48, -2, 15, + 9, 14, -62, 59, -109, 148, -216, 295, -401, 535, -708, 933,-1233, 1650,-2274, 3334,-5633,15379,22788,-6440, 3628,-2425, 1739,-1288, 967, -727, 543, -401, 288, -206, 136, -95, 47, -48, -2, 15, + 9, 14, -62, 59, -109, 148, -216, 294, -401, 534, -707, 931,-1230, 1646,-2268, 3324,-5615,15298,22855,-6436, 3624,-2422, 1737,-1286, 965, -726, 542, -400, 288, -205, 136, -95, 47, -48, -2, 15, + 9, 14, -62, 59, -109, 148, -215, 294, -400, 533, -705, 929,-1227, 1642,-2262, 3315,-5597,15218,22922,-6433, 3620,-2419, 1734,-1285, 964, -725, 541, -399, 287, -205, 135, -95, 47, -47, -2, 15, + 9, 14, -62, 59, -109, 147, -215, 293, -399, 532, -704, 927,-1224, 1638,-2256, 3306,-5579,15138,22988,-6429, 3616,-2416, 1732,-1282, 962, -723, 540, -398, 286, -204, 135, -94, 47, -47, -3, 15, + 9, 14, -62, 59, -109, 147, -215, 293, -398, 530, -702, 924,-1221, 1633,-2250, 3296,-5560,15057,23054,-6425, 3612,-2412, 1729,-1280, 960, -722, 539, -398, 286, -203, 134, -94, 46, -47, -3, 15, + 8, 15, -62, 59, -109, 147, -214, 292, -397, 529, -701, 922,-1218, 1629,-2244, 3286,-5541,14977,23120,-6421, 3608,-2409, 1726,-1278, 959, -721, 537, -397, 285, -203, 134, -94, 46, -47, -3, 15, + 8, 15, -62, 59, -109, 147, -214, 292, -397, 528, -699, 920,-1215, 1625,-2238, 3277,-5522,14896,23186,-6416, 3603,-2405, 1724,-1276, 957, -719, 536, -396, 284, -202, 133, -93, 46, -46, -3, 15, + 8, 15, -62, 59, -109, 147, -214, 291, -396, 527, -697, 917,-1212, 1620,-2231, 3267,-5503,14816,23251,-6412, 3598,-2401, 1721,-1274, 955, -718, 535, -395, 284, -202, 133, -93, 46, -46, -3, 15, + 8, 15, -62, 59, -109, 147, -213, 290, -395, 526, -695, 915,-1208, 1616,-2225, 3257,-5484,14735,23316,-6407, 3594,-2398, 1718,-1272, 954, -717, 534, -394, 283, -201, 133, -93, 45, -46, -3, 15, + 8, 15, -62, 59, -108, 146, -213, 290, -394, 524, -694, 913,-1205, 1611,-2219, 3247,-5465,14655,23381,-6401, 3589,-2394, 1715,-1269, 952, -715, 533, -393, 282, -201, 132, -92, 45, -46, -4, 15, + 8, 15, -62, 59, -108, 146, -213, 289, -393, 523, -692, 910,-1202, 1607,-2212, 3236,-5445,14574,23446,-6396, 3583,-2390, 1712,-1267, 950, -714, 532, -392, 282, -200, 132, -92, 45, -46, -4, 15, + 8, 15, -62, 59, -108, 146, -212, 289, -392, 522, -690, 908,-1199, 1602,-2205, 3226,-5425,14493,23510,-6390, 3578,-2386, 1709,-1264, 948, -712, 531, -391, 281, -199, 131, -92, 44, -45, -4, 15, + 8, 15, -62, 59, -108, 146, -212, 288, -391, 521, -688, 905,-1195, 1598,-2199, 3216,-5406,14413,23575,-6384, 3573,-2382, 1705,-1262, 946, -711, 529, -390, 280, -199, 131, -91, 44, -45, -4, 15, + 8, 16, -62, 59, -108, 145, -212, 287, -391, 519, -687, 903,-1192, 1593,-2192, 3205,-5386,14332,23639,-6377, 3567,-2377, 1702,-1259, 944, -709, 528, -389, 279, -198, 130, -91, 44, -45, -4, 15, + 8, 16, -63, 59, -108, 145, -211, 287, -390, 518, -685, 900,-1188, 1588,-2185, 3195,-5365,14251,23703,-6371, 3561,-2373, 1699,-1257, 942, -707, 527, -388, 278, -198, 130, -90, 44, -45, -5, 16, + 8, 16, -63, 59, -108, 145, -211, 286, -389, 517, -683, 898,-1185, 1583,-2178, 3184,-5345,14170,23766,-6364, 3555,-2369, 1696,-1254, 940, -706, 526, -387, 278, -197, 129, -90, 43, -44, -5, 16, + 8, 16, -63, 59, -108, 145, -210, 286, -388, 515, -681, 895,-1181, 1578,-2171, 3173,-5325,14090,23830,-6357, 3549,-2364, 1692,-1252, 938, -704, 524, -386, 277, -196, 129, -90, 43, -44, -5, 16, + 8, 16, -63, 59, -108, 145, -210, 285, -387, 514, -679, 893,-1178, 1573,-2164, 3162,-5304,14009,23893,-6349, 3543,-2359, 1689,-1249, 936, -702, 523, -385, 276, -196, 128, -89, 43, -44, -5, 16, + 8, 16, -63, 59, -108, 144, -210, 284, -386, 512, -677, 890,-1174, 1568,-2157, 3151,-5283,13928,23956,-6342, 3537,-2355, 1685,-1246, 934, -701, 522, -384, 275, -195, 128, -89, 43, -44, -5, 16, + 8, 16, -63, 59, -107, 144, -209, 284, -385, 511, -675, 887,-1170, 1563,-2150, 3140,-5262,13847,24018,-6334, 3531,-2350, 1681,-1243, 931, -699, 520, -383, 274, -194, 127, -89, 42, -43, -6, 16, + 8, 16, -63, 59, -107, 144, -209, 283, -384, 510, -673, 885,-1167, 1558,-2143, 3129,-5241,13766,24081,-6326, 3524,-2345, 1678,-1240, 929, -697, 519, -382, 274, -194, 127, -88, 42, -43, -6, 16, + 8, 16, -63, 58, -107, 144, -208, 282, -383, 508, -671, 882,-1163, 1553,-2135, 3118,-5220,13685,24143,-6317, 3517,-2340, 1674,-1237, 927, -695, 517, -381, 273, -193, 126, -88, 42, -43, -6, 16, + 8, 17, -63, 58, -107, 143, -208, 281, -382, 507, -669, 879,-1159, 1548,-2128, 3106,-5199,13604,24205,-6309, 3510,-2335, 1670,-1234, 924, -694, 516, -380, 272, -192, 126, -87, 41, -43, -6, 16, + 8, 17, -63, 58, -107, 143, -207, 281, -381, 505, -667, 876,-1155, 1543,-2120, 3095,-5177,13523,24266,-6300, 3503,-2330, 1666,-1231, 922, -692, 515, -379, 271, -192, 125, -87, 41, -42, -6, 16, + 8, 17, -63, 58, -107, 143, -207, 280, -380, 504, -665, 873,-1151, 1537,-2113, 3083,-5156,13442,24328,-6290, 3496,-2324, 1662,-1228, 920, -690, 513, -377, 270, -191, 125, -87, 41, -42, -7, 16, + 7, 17, -63, 58, -107, 142, -206, 279, -379, 502, -663, 870,-1148, 1532,-2105, 3071,-5134,13361,24389,-6281, 3489,-2319, 1658,-1225, 917, -688, 512, -376, 269, -190, 124, -86, 40, -42, -7, 16, + 7, 17, -63, 58, -107, 142, -206, 279, -377, 501, -661, 868,-1144, 1527,-2097, 3060,-5112,13280,24450,-6271, 3481,-2313, 1654,-1222, 915, -686, 510, -375, 268, -190, 124, -86, 40, -42, -7, 16, + 7, 17, -63, 58, -106, 142, -205, 278, -376, 499, -659, 865,-1140, 1521,-2090, 3048,-5090,13199,24511,-6261, 3474,-2308, 1649,-1219, 912, -684, 509, -374, 267, -189, 123, -85, 40, -41, -7, 16, + 7, 17, -63, 58, -106, 142, -205, 277, -375, 498, -656, 862,-1136, 1516,-2082, 3036,-5068,13118,24571,-6251, 3466,-2302, 1645,-1216, 910, -682, 507, -373, 266, -188, 122, -85, 40, -41, -7, 16, + 7, 17, -63, 58, -106, 141, -204, 276, -374, 496, -654, 859,-1132, 1510,-2074, 3024,-5045,13037,24631,-6240, 3458,-2296, 1641,-1212, 907, -680, 506, -371, 265, -187, 122, -84, 39, -41, -8, 16, + 7, 17, -63, 58, -106, 141, -204, 276, -373, 494, -652, 856,-1127, 1504,-2066, 3011,-5023,12956,24691,-6229, 3450,-2291, 1636,-1209, 905, -678, 504, -370, 264, -187, 121, -84, 39, -41, -8, 17, + 7, 17, -63, 58, -106, 141, -203, 275, -372, 493, -650, 853,-1123, 1499,-2058, 2999,-5000,12875,24751,-6218, 3442,-2285, 1632,-1205, 902, -676, 502, -369, 263, -186, 121, -84, 39, -40, -8, 17, + 7, 18, -63, 58, -106, 140, -203, 274, -371, 491, -647, 850,-1119, 1493,-2050, 2987,-4978,12794,24810,-6207, 3434,-2278, 1627,-1202, 899, -674, 501, -368, 262, -185, 120, -83, 38, -40, -8, 17, + 7, 18, -63, 58, -105, 140, -202, 273, -370, 489, -645, 846,-1115, 1487,-2042, 2974,-4955,12713,24869,-6195, 3425,-2272, 1623,-1198, 897, -672, 499, -366, 261, -184, 120, -83, 38, -40, -9, 17, + 7, 18, -63, 58, -105, 140, -202, 272, -368, 488, -643, 843,-1111, 1481,-2034, 2962,-4932,12632,24928,-6183, 3416,-2266, 1618,-1195, 894, -670, 497, -365, 260, -184, 119, -82, 38, -40, -9, 17, + 7, 18, -63, 57, -105, 139, -201, 272, -367, 486, -641, 840,-1106, 1476,-2025, 2949,-4909,12551,24987,-6171, 3408,-2260, 1613,-1191, 891, -667, 496, -364, 259, -183, 118, -82, 37, -39, -9, 17, + 7, 18, -63, 57, -105, 139, -201, 271, -366, 484, -638, 837,-1102, 1470,-2017, 2936,-4885,12470,25045,-6159, 3399,-2253, 1609,-1187, 888, -665, 494, -362, 258, -182, 118, -81, 37, -39, -9, 17, + 7, 18, -63, 57, -105, 139, -200, 270, -365, 483, -636, 834,-1098, 1464,-2008, 2923,-4862,12388,25103,-6146, 3390,-2247, 1604,-1184, 885, -663, 492, -361, 257, -181, 117, -81, 37, -39, -9, 17, + 7, 18, -63, 57, -105, 138, -200, 269, -363, 481, -633, 831,-1093, 1458,-2000, 2911,-4838,12307,25161,-6133, 3380,-2240, 1599,-1180, 882, -661, 490, -360, 256, -180, 117, -80, 36, -39, -10, 17, + 7, 18, -63, 57, -104, 138, -199, 268, -362, 479, -631, 827,-1089, 1452,-1991, 2898,-4815,12226,25219,-6120, 3371,-2233, 1594,-1176, 879, -658, 489, -358, 255, -180, 116, -80, 36, -38, -10, 17, + 7, 18, -63, 57, -104, 138, -199, 267, -361, 477, -629, 824,-1085, 1446,-1983, 2884,-4791,12145,25276,-6106, 3362,-2227, 1589,-1172, 876, -656, 487, -357, 254, -179, 115, -79, 36, -38, -10, 17, + 7, 18, -63, 57, -104, 137, -198, 266, -360, 476, -626, 821,-1080, 1439,-1974, 2871,-4767,12064,25333,-6092, 3352,-2220, 1583,-1168, 873, -654, 485, -356, 253, -178, 115, -79, 35, -38, -10, 17, + 7, 19, -63, 57, -104, 137, -197, 266, -358, 474, -624, 817,-1075, 1433,-1965, 2858,-4743,11983,25390,-6078, 3342,-2213, 1578,-1164, 870, -651, 483, -354, 252, -177, 114, -78, 35, -37, -10, 17, + 7, 19, -63, 57, -104, 137, -197, 265, -357, 472, -621, 814,-1071, 1427,-1957, 2845,-4719,11902,25446,-6064, 3332,-2206, 1573,-1160, 867, -649, 481, -353, 251, -176, 113, -78, 35, -37, -11, 17, + 7, 19, -63, 57, -103, 136, -196, 264, -356, 470, -619, 810,-1066, 1421,-1948, 2831,-4695,11821,25503,-6049, 3322,-2198, 1568,-1156, 864, -647, 479, -351, 250, -175, 113, -78, 34, -37, -11, 17, + 6, 19, -63, 56, -103, 136, -196, 263, -355, 468, -616, 807,-1062, 1414,-1939, 2818,-4671,11741,25559,-6034, 3312,-2191, 1562,-1152, 861, -644, 478, -350, 249, -175, 112, -77, 34, -37, -11, 17, + 6, 19, -63, 56, -103, 135, -195, 262, -353, 466, -614, 804,-1057, 1408,-1930, 2804,-4646,11660,25614,-6019, 3302,-2184, 1557,-1148, 858, -642, 476, -348, 247, -174, 112, -77, 34, -36, -11, 18, + 6, 19, -63, 56, -103, 135, -194, 261, -352, 465, -611, 800,-1052, 1401,-1921, 2790,-4621,11579,25670,-6004, 3291,-2176, 1551,-1144, 854, -639, 474, -347, 246, -173, 111, -76, 33, -36, -11, 18, + 6, 19, -63, 56, -103, 135, -194, 260, -351, 463, -608, 797,-1048, 1395,-1912, 2777,-4597,11498,25725,-5988, 3280,-2169, 1546,-1140, 851, -637, 472, -345, 245, -172, 110, -76, 33, -36, -12, 18, + 6, 19, -63, 56, -102, 134, -193, 259, -349, 461, -606, 793,-1043, 1388,-1902, 2763,-4572,11417,25780,-5972, 3270,-2161, 1540,-1135, 848, -634, 470, -344, 244, -171, 110, -75, 33, -36, -12, 18, + 6, 19, -63, 56, -102, 134, -193, 258, -348, 459, -603, 789,-1038, 1382,-1893, 2749,-4547,11336,25834,-5956, 3259,-2153, 1534,-1131, 845, -632, 468, -342, 243, -170, 109, -75, 32, -35, -12, 18, + 6, 19, -63, 56, -102, 133, -192, 257, -346, 457, -601, 786,-1033, 1375,-1884, 2735,-4522,11255,25888,-5939, 3248,-2145, 1528,-1127, 841, -629, 466, -341, 242, -169, 108, -74, 32, -35, -12, 18, + 6, 19, -63, 56, -102, 133, -191, 256, -345, 455, -598, 782,-1028, 1369,-1875, 2721,-4497,11175,25942,-5922, 3236,-2137, 1523,-1122, 838, -626, 464, -339, 240, -168, 108, -74, 32, -35, -12, 18, + 6, 20, -63, 56, -101, 133, -191, 255, -344, 453, -595, 779,-1023, 1362,-1865, 2707,-4472,11094,25996,-5905, 3225,-2129, 1517,-1118, 834, -624, 462, -337, 239, -167, 107, -73, 31, -34, -13, 18, + 6, 20, -63, 55, -101, 132, -190, 254, -342, 451, -592, 775,-1018, 1355,-1856, 2692,-4446,11013,26050,-5888, 3213,-2121, 1511,-1113, 831, -621, 460, -336, 238, -166, 106, -72, 31, -34, -13, 18, + 6, 20, -63, 55, -101, 132, -189, 253, -341, 449, -590, 771,-1013, 1348,-1846, 2678,-4421,10933,26103,-5870, 3202,-2113, 1505,-1108, 827, -618, 457, -334, 237, -165, 105, -72, 30, -34, -13, 18, + 6, 20, -63, 55, -101, 131, -189, 252, -339, 447, -587, 768,-1008, 1342,-1837, 2664,-4395,10852,26156,-5852, 3190,-2105, 1498,-1104, 824, -615, 455, -333, 235, -165, 105, -71, 30, -34, -13, 18, + 6, 20, -63, 55, -101, 131, -188, 251, -338, 445, -584, 764,-1003, 1335,-1827, 2649,-4370,10772,26208,-5834, 3178,-2096, 1492,-1099, 820, -613, 453, -331, 234, -164, 104, -71, 30, -33, -14, 18, + 6, 20, -63, 55, -100, 131, -187, 250, -336, 443, -581, 760, -998, 1328,-1817, 2635,-4344,10691,26260,-5816, 3166,-2088, 1486,-1094, 817, -610, 451, -329, 233, -163, 103, -70, 29, -33, -14, 18, + 6, 20, -63, 55, -100, 130, -187, 249, -335, 441, -579, 756, -993, 1321,-1807, 2620,-4318,10610,26312,-5797, 3154,-2079, 1480,-1090, 813, -607, 449, -328, 232, -162, 103, -70, 29, -33, -14, 18, + 6, 20, -63, 55, -100, 130, -186, 248, -333, 439, -576, 752, -988, 1314,-1798, 2605,-4292,10530,26364,-5778, 3141,-2071, 1473,-1085, 809, -604, 447, -326, 230, -161, 102, -69, 29, -32, -14, 18, + 6, 20, -63, 54, -100, 129, -185, 247, -332, 437, -573, 749, -983, 1307,-1788, 2590,-4266,10450,26416,-5758, 3129,-2062, 1467,-1080, 805, -601, 444, -324, 229, -160, 101, -69, 28, -32, -14, 18, + 6, 20, -63, 54, -99, 129, -185, 246, -330, 435, -570, 745, -978, 1300,-1778, 2575,-4240,10369,26467,-5739, 3116,-2053, 1460,-1075, 802, -598, 442, -323, 228, -159, 100, -68, 28, -32, -15, 18, + 6, 20, -63, 54, -99, 128, -184, 245, -329, 432, -567, 741, -972, 1293,-1768, 2561,-4213,10289,26518,-5719, 3103,-2044, 1454,-1070, 798, -596, 440, -321, 226, -158, 100, -68, 27, -32, -15, 19, + 6, 20, -63, 54, -99, 128, -183, 244, -327, 430, -564, 737, -967, 1285,-1758, 2546,-4187,10209,26568,-5699, 3090,-2035, 1447,-1065, 794, -593, 438, -319, 225, -157, 99, -67, 27, -31, -15, 19, + 6, 21, -63, 54, -99, 127, -182, 243, -326, 428, -561, 733, -962, 1278,-1748, 2530,-4160,10129,26618,-5678, 3077,-2026, 1440,-1060, 790, -590, 435, -317, 224, -156, 98, -67, 27, -31, -15, 19, + 6, 21, -63, 54, -98, 127, -182, 242, -324, 426, -558, 729, -956, 1271,-1738, 2515,-4134,10048,26668,-5658, 3064,-2017, 1434,-1055, 786, -587, 433, -316, 222, -155, 97, -66, 26, -31, -15, 19, + 5, 21, -63, 54, -98, 126, -181, 241, -323, 424, -555, 725, -951, 1264,-1728, 2500,-4107, 9968,26718,-5637, 3051,-2007, 1427,-1050, 782, -584, 431, -314, 221, -154, 97, -66, 26, -30, -16, 19, + 5, 21, -63, 53, -98, 126, -180, 240, -321, 422, -553, 721, -946, 1256,-1717, 2485,-4080, 9888,26767,-5615, 3037,-1998, 1420,-1045, 778, -581, 428, -312, 220, -153, 96, -65, 26, -30, -16, 19, + 5, 21, -63, 53, -97, 125, -180, 238, -320, 420, -550, 717, -940, 1249,-1707, 2469,-4054, 9808,26816,-5594, 3024,-1989, 1413,-1039, 774, -577, 426, -310, 218, -152, 95, -64, 25, -30, -16, 19, + 5, 21, -62, 53, -97, 125, -179, 237, -318, 417, -547, 713, -935, 1242,-1697, 2454,-4027, 9728,26865,-5572, 3010,-1979, 1406,-1034, 770, -574, 424, -308, 217, -151, 94, -64, 25, -29, -16, 19, + 5, 21, -62, 53, -97, 125, -178, 236, -316, 415, -543, 709, -929, 1234,-1686, 2439,-4000, 9649,26913,-5550, 2996,-1969, 1399,-1029, 766, -571, 421, -307, 216, -150, 94, -63, 24, -29, -17, 19, + 5, 21, -62, 53, -97, 124, -177, 235, -315, 413, -540, 705, -924, 1227,-1676, 2423,-3973, 9569,26961,-5527, 2982,-1960, 1392,-1023, 762, -568, 419, -305, 214, -148, 93, -63, 24, -29, -17, 19, + 5, 21, -62, 53, -96, 124, -176, 234, -313, 411, -537, 701, -918, 1219,-1665, 2407,-3945, 9489,27009,-5505, 2968,-1950, 1385,-1018, 758, -565, 416, -303, 213, -147, 92, -62, 24, -29, -17, 19, + 5, 21, -62, 52, -96, 123, -176, 233, -312, 408, -534, 697, -913, 1212,-1655, 2392,-3918, 9409,27057,-5482, 2953,-1940, 1377,-1012, 754, -562, 414, -301, 211, -146, 91, -62, 23, -28, -17, 19, + 5, 21, -62, 52, -96, 123, -175, 232, -310, 406, -531, 692, -907, 1204,-1644, 2376,-3891, 9330,27104,-5458, 2939,-1930, 1370,-1007, 750, -558, 412, -299, 210, -145, 91, -61, 23, -28, -17, 19, + 5, 21, -62, 52, -95, 122, -174, 231, -308, 404, -528, 688, -902, 1197,-1634, 2360,-3863, 9250,27151,-5435, 2924,-1920, 1363,-1001, 745, -555, 409, -297, 208, -144, 90, -60, 22, -28, -18, 19, + 5, 21, -62, 52, -95, 122, -173, 229, -307, 402, -525, 684, -896, 1189,-1623, 2344,-3836, 9171,27197,-5411, 2909,-1910, 1355, -996, 741, -552, 407, -295, 207, -143, 89, -60, 22, -27, -18, 19, + 5, 21, -62, 52, -95, 121, -173, 228, -305, 399, -522, 680, -890, 1181,-1612, 2328,-3808, 9091,27244,-5387, 2894,-1899, 1348, -990, 737, -549, 404, -293, 206, -142, 88, -59, 22, -27, -18, 19, + 5, 22, -62, 52, -95, 120, -172, 227, -303, 397, -519, 676, -885, 1173,-1601, 2312,-3780, 9012,27290,-5363, 2879,-1889, 1340, -985, 733, -545, 401, -291, 204, -141, 87, -59, 21, -27, -18, 19, + 5, 22, -62, 51, -94, 120, -171, 226, -302, 395, -516, 671, -879, 1166,-1591, 2296,-3753, 8933,27335,-5338, 2864,-1878, 1333, -979, 728, -542, 399, -289, 203, -140, 87, -58, 21, -26, -19, 20, + 5, 22, -62, 51, -94, 119, -170, 225, -300, 392, -512, 667, -873, 1158,-1580, 2280,-3725, 8854,27381,-5313, 2849,-1868, 1325, -973, 724, -539, 396, -287, 201, -139, 86, -57, 20, -26, -19, 20, + 5, 22, -62, 51, -94, 119, -169, 223, -298, 390, -509, 663, -867, 1150,-1569, 2264,-3697, 8775,27426,-5288, 2834,-1857, 1317, -967, 719, -535, 394, -285, 200, -138, 85, -57, 20, -26, -19, 20, + 5, 22, -62, 51, -93, 118, -169, 222, -297, 388, -506, 658, -862, 1142,-1558, 2248,-3669, 8696,27470,-5262, 2818,-1847, 1309, -961, 715, -532, 391, -283, 198, -136, 84, -56, 20, -25, -19, 20, + 5, 22, -62, 51, -93, 118, -168, 221, -295, 385, -503, 654, -856, 1134,-1547, 2231,-3641, 8617,27515,-5236, 2802,-1836, 1302, -955, 710, -528, 388, -281, 197, -135, 83, -56, 19, -25, -19, 20, + 5, 22, -62, 50, -93, 117, -167, 220, -293, 383, -499, 650, -850, 1126,-1536, 2215,-3613, 8538,27559,-5210, 2786,-1825, 1294, -950, 706, -525, 386, -279, 195, -134, 82, -55, 19, -25, -20, 20, + 5, 22, -62, 50, -92, 117, -166, 219, -291, 380, -496, 645, -844, 1118,-1525, 2198,-3585, 8459,27602,-5184, 2770,-1814, 1286, -944, 701, -521, 383, -277, 194, -133, 82, -54, 18, -24, -20, 20, + 5, 22, -62, 50, -92, 116, -165, 217, -290, 378, -493, 641, -838, 1110,-1514, 2182,-3556, 8381,27646,-5157, 2754,-1803, 1278, -938, 697, -518, 380, -275, 192, -132, 81, -54, 18, -24, -20, 20, + 5, 22, -61, 50, -92, 116, -164, 216, -288, 375, -490, 636, -832, 1102,-1502, 2165,-3528, 8302,27689,-5130, 2738,-1792, 1270, -931, 692, -514, 378, -273, 190, -131, 80, -53, 17, -24, -20, 20, + 5, 22, -61, 50, -91, 115, -164, 215, -286, 373, -486, 632, -826, 1094,-1491, 2149,-3500, 8224,27732,-5103, 2722,-1781, 1261, -925, 687, -511, 375, -271, 189, -129, 79, -53, 17, -24, -21, 20, + 5, 22, -61, 49, -91, 115, -163, 214, -284, 371, -483, 628, -820, 1086,-1480, 2132,-3471, 8145,27774,-5076, 2705,-1769, 1253, -919, 683, -507, 372, -269, 187, -128, 78, -52, 17, -23, -21, 20, + 5, 22, -61, 49, -91, 114, -162, 212, -283, 368, -480, 623, -814, 1078,-1469, 2115,-3443, 8067,27816,-5048, 2688,-1758, 1245, -913, 678, -504, 369, -267, 186, -127, 77, -51, 16, -23, -21, 20, + 4, 22, -61, 49, -90, 113, -161, 211, -281, 366, -476, 619, -808, 1070,-1457, 2099,-3414, 7989,27858,-5020, 2672,-1747, 1237, -907, 673, -500, 367, -265, 184, -126, 76, -51, 16, -23, -21, 20, + 4, 22, -61, 49, -90, 113, -160, 210, -279, 363, -473, 614, -802, 1062,-1446, 2082,-3385, 7911,27899,-4992, 2655,-1735, 1228, -901, 669, -496, 364, -263, 183, -125, 76, -50, 15, -22, -21, 20, + 4, 22, -61, 49, -90, 112, -159, 209, -277, 361, -470, 609, -796, 1054,-1435, 2065,-3357, 7833,27941,-4963, 2638,-1723, 1220, -894, 664, -493, 361, -261, 181, -124, 75, -49, 15, -22, -22, 20, + 4, 23, -61, 48, -89, 112, -158, 207, -275, 358, -466, 605, -790, 1045,-1423, 2048,-3328, 7755,27981,-4934, 2620,-1712, 1211, -888, 659, -489, 358, -258, 179, -122, 74, -49, 14, -22, -22, 20, + 4, 23, -61, 48, -89, 111, -158, 206, -274, 356, -463, 600, -784, 1037,-1412, 2031,-3299, 7677,28022,-4905, 2603,-1700, 1203, -881, 654, -485, 355, -256, 178, -121, 73, -48, 14, -21, -22, 20, + 4, 23, -61, 48, -89, 111, -157, 205, -272, 353, -459, 596, -778, 1029,-1400, 2014,-3270, 7599,28062,-4876, 2586,-1688, 1194, -875, 649, -481, 353, -254, 176, -120, 72, -47, 14, -21, -22, 20, + 4, 23, -61, 48, -88, 110, -156, 203, -270, 351, -456, 591, -772, 1020,-1388, 1997,-3241, 7522,28102,-4846, 2568,-1676, 1185, -869, 644, -478, 350, -252, 174, -119, 71, -47, 13, -21, -23, 21, + 4, 23, -61, 48, -88, 109, -155, 202, -268, 348, -452, 587, -765, 1012,-1377, 1980,-3212, 7444,28141,-4816, 2550,-1664, 1177, -862, 639, -474, 347, -250, 173, -117, 70, -46, 13, -20, -23, 21, + 4, 23, -61, 47, -88, 109, -154, 201, -266, 346, -449, 582, -759, 1004,-1365, 1963,-3183, 7367,28180,-4785, 2532,-1652, 1168, -855, 634, -470, 344, -248, 171, -116, 69, -46, 12, -20, -23, 21, + 4, 23, -60, 47, -87, 108, -153, 199, -264, 343, -446, 577, -753, 995,-1354, 1946,-3154, 7289,28219,-4755, 2514,-1640, 1159, -849, 629, -466, 341, -245, 169, -115, 68, -45, 12, -20, -23, 21, + 4, 23, -60, 47, -87, 108, -152, 198, -262, 340, -442, 573, -747, 987,-1342, 1928,-3125, 7212,28258,-4724, 2496,-1627, 1150, -842, 624, -462, 338, -243, 168, -114, 68, -44, 11, -19, -23, 21, + 4, 23, -60, 47, -86, 107, -151, 197, -261, 338, -439, 568, -740, 978,-1330, 1911,-3095, 7135,28296,-4693, 2478,-1615, 1141, -836, 619, -459, 335, -241, 166, -113, 67, -44, 11, -19, -24, 21, + 4, 23, -60, 46, -86, 106, -150, 196, -259, 335, -435, 563, -734, 970,-1318, 1894,-3066, 7058,28334,-4661, 2460,-1603, 1132, -829, 614, -455, 332, -239, 164, -111, 66, -43, 10, -19, -24, 21, + 4, 23, -60, 46, -86, 106, -149, 194, -257, 333, -432, 558, -728, 961,-1306, 1876,-3037, 6981,28371,-4630, 2441,-1590, 1123, -822, 609, -451, 329, -236, 163, -110, 65, -42, 10, -18, -24, 21, + 4, 23, -60, 46, -85, 105, -149, 193, -255, 330, -428, 554, -721, 953,-1295, 1859,-3007, 6905,28408,-4598, 2422,-1578, 1114, -815, 604, -447, 326, -234, 161, -109, 64, -42, 10, -18, -24, 21, + 4, 23, -60, 46, -85, 105, -148, 191, -253, 327, -424, 549, -715, 944,-1283, 1841,-2978, 6828,28445,-4565, 2404,-1565, 1105, -808, 599, -443, 323, -232, 159, -107, 63, -41, 9, -18, -25, 21, + 4, 23, -60, 46, -85, 104, -147, 190, -251, 325, -421, 544, -709, 936,-1271, 1824,-2949, 6751,28482,-4533, 2385,-1552, 1096, -802, 593, -439, 320, -229, 158, -106, 62, -40, 9, -17, -25, 21, + 4, 23, -60, 45, -84, 103, -146, 189, -249, 322, -417, 539, -702, 927,-1259, 1806,-2919, 6675,28518,-4500, 2366,-1539, 1087, -795, 588, -435, 317, -227, 156, -105, 61, -40, 8, -17, -25, 21, + 4, 23, -60, 45, -84, 103, -145, 187, -247, 319, -414, 535, -696, 918,-1247, 1789,-2890, 6599,28553,-4467, 2347,-1526, 1077, -788, 583, -431, 314, -225, 154, -104, 60, -39, 8, -17, -25, 21, + 4, 23, -60, 45, -84, 102, -144, 186, -245, 317, -410, 530, -689, 910,-1235, 1771,-2860, 6523,28589,-4433, 2327,-1513, 1068, -781, 578, -427, 311, -222, 152, -102, 59, -38, 7, -16, -25, 21, + 4, 23, -59, 45, -83, 101, -143, 185, -243, 314, -407, 525, -683, 901,-1223, 1753,-2830, 6447,28624,-4400, 2308,-1500, 1059, -774, 572, -423, 308, -220, 151, -101, 58, -38, 7, -16, -26, 21, + 4, 23, -59, 44, -83, 101, -142, 183, -241, 311, -403, 520, -676, 892,-1211, 1736,-2801, 6371,28659,-4366, 2288,-1487, 1049, -767, 567, -419, 305, -218, 149, -100, 57, -37, 6, -16, -26, 21, + 4, 23, -59, 44, -82, 100, -141, 182, -240, 309, -399, 515, -670, 883,-1199, 1718,-2771, 6295,28693,-4332, 2269,-1474, 1040, -760, 562, -415, 302, -215, 147, -98, 56, -36, 6, -15, -26, 21, + 4, 23, -59, 44, -82, 100, -140, 180, -238, 306, -396, 510, -663, 875,-1186, 1700,-2741, 6219,28727,-4297, 2249,-1461, 1030, -752, 556, -410, 298, -213, 145, -97, 55, -36, 5, -15, -26, 21, + 4, 24, -59, 44, -82, 99, -139, 179, -236, 303, -392, 505, -657, 866,-1174, 1682,-2711, 6144,28761,-4262, 2229,-1447, 1020, -745, 551, -406, 295, -211, 143, -96, 54, -35, 5, -15, -26, 21, + 4, 24, -59, 43, -81, 98, -138, 178, -234, 301, -388, 501, -650, 857,-1162, 1665,-2682, 6068,28794,-4227, 2209,-1434, 1011, -738, 545, -402, 292, -208, 142, -94, 54, -34, 5, -14, -27, 21, + 4, 24, -59, 43, -81, 98, -137, 176, -232, 298, -385, 496, -644, 848,-1150, 1647,-2652, 5993,28827,-4192, 2189,-1421, 1001, -731, 540, -398, 289, -206, 140, -93, 53, -33, 4, -14, -27, 22, + 4, 24, -59, 43, -80, 97, -136, 175, -230, 295, -381, 491, -637, 839,-1138, 1629,-2622, 5918,28860,-4156, 2169,-1407, 991, -724, 534, -394, 286, -203, 138, -92, 52, -33, 4, -14, -27, 22, + 3, 24, -59, 43, -80, 96, -135, 173, -228, 293, -377, 486, -631, 830,-1125, 1611,-2592, 5843,28892,-4120, 2148,-1393, 981, -716, 529, -390, 282, -201, 136, -90, 51, -32, 3, -13, -27, 22, + 3, 24, -59, 42, -80, 96, -134, 172, -226, 290, -374, 481, -624, 821,-1113, 1593,-2562, 5768,28924,-4084, 2128,-1380, 972, -709, 523, -385, 279, -199, 134, -89, 50, -31, 3, -13, -28, 22, + 3, 24, -58, 42, -79, 95, -133, 171, -224, 287, -370, 476, -617, 813,-1101, 1575,-2532, 5694,28956,-4047, 2107,-1366, 962, -701, 518, -381, 276, -196, 133, -88, 49, -31, 2, -13, -28, 22, + 3, 24, -58, 42, -79, 94, -132, 169, -222, 284, -366, 471, -611, 804,-1088, 1557,-2502, 5619,28987,-4011, 2086,-1352, 952, -694, 512, -377, 273, -194, 131, -86, 48, -30, 2, -12, -28, 22, + 3, 24, -58, 42, -78, 94, -131, 168, -220, 281, -362, 466, -604, 795,-1076, 1539,-2472, 5545,29018,-3974, 2066,-1338, 942, -687, 506, -372, 269, -191, 129, -85, 47, -29, 1, -12, -28, 22, + 3, 24, -58, 41, -78, 93, -130, 166, -218, 279, -359, 461, -597, 786,-1064, 1521,-2442, 5470,29048,-3936, 2045,-1324, 932, -679, 501, -368, 266, -189, 127, -84, 46, -29, 1, -12, -28, 22, + 3, 24, -58, 41, -78, 92, -129, 165, -216, 276, -355, 456, -591, 777,-1051, 1502,-2412, 5396,29079,-3899, 2024,-1310, 922, -672, 495, -364, 263, -186, 125, -82, 45, -28, 0, -11, -29, 22, + 3, 24, -58, 41, -77, 92, -128, 163, -214, 273, -351, 451, -584, 768,-1039, 1484,-2382, 5322,29108,-3861, 2002,-1296, 911, -664, 489, -359, 260, -184, 123, -81, 44, -27, 0, -11, -29, 22, + 3, 24, -58, 41, -77, 91, -127, 162, -212, 270, -347, 446, -577, 759,-1026, 1466,-2352, 5248,29138,-3823, 1981,-1282, 901, -656, 483, -355, 256, -181, 121, -79, 43, -26, -1, -11, -29, 22, + 3, 24, -58, 40, -76, 90, -126, 160, -210, 268, -344, 441, -571, 750,-1014, 1448,-2321, 5174,29167,-3784, 1959,-1267, 891, -649, 478, -351, 253, -179, 120, -78, 42, -26, -1, -10, -29, 22, + 3, 24, -58, 40, -76, 90, -125, 159, -207, 265, -340, 436, -564, 740,-1001, 1430,-2291, 5101,29196,-3745, 1938,-1253, 881, -641, 472, -346, 250, -176, 118, -77, 41, -25, -2, -10, -30, 22, + 3, 24, -57, 40, -75, 89, -124, 158, -205, 262, -336, 431, -557, 731, -989, 1411,-2261, 5027,29224,-3706, 1916,-1239, 870, -633, 466, -342, 246, -174, 116, -75, 40, -24, -2, -10, -30, 22, + 3, 24, -57, 40, -75, 88, -123, 156, -203, 259, -332, 426, -550, 722, -976, 1393,-2231, 4954,29252,-3667, 1894,-1224, 860, -626, 460, -337, 243, -171, 114, -74, 39, -24, -3, -9, -30, 22, + 3, 24, -57, 39, -75, 88, -122, 155, -201, 256, -328, 421, -544, 713, -963, 1375,-2201, 4881,29280,-3628, 1873,-1210, 849, -618, 454, -333, 239, -168, 112, -72, 38, -23, -3, -9, -30, 22, + 3, 24, -57, 39, -74, 87, -121, 153, -199, 253, -325, 415, -537, 704, -951, 1356,-2170, 4808,29307,-3588, 1850,-1195, 839, -610, 448, -328, 236, -166, 110, -71, 37, -22, -4, -9, -30, 22, + 3, 24, -57, 39, -74, 86, -120, 152, -197, 251, -321, 410, -530, 695, -938, 1338,-2140, 4735,29334,-3548, 1828,-1180, 828, -602, 443, -324, 233, -163, 108, -70, 36, -21, -4, -8, -31, 22, + 3, 24, -57, 38, -73, 86, -119, 150, -195, 248, -317, 405, -523, 686, -926, 1320,-2110, 4663,29361,-3507, 1806,-1165, 818, -595, 437, -319, 229, -161, 106, -68, 35, -21, -4, -8, -31, 22, + 3, 24, -57, 38, -73, 85, -118, 149, -193, 245, -313, 400, -516, 676, -913, 1301,-2080, 4590,29387,-3467, 1784,-1151, 807, -587, 431, -315, 226, -158, 104, -67, 34, -20, -5, -8, -31, 22, + 3, 24, -57, 38, -72, 84, -117, 147, -191, 242, -309, 395, -509, 667, -900, 1283,-2049, 4518,29413,-3426, 1761,-1136, 797, -579, 425, -310, 222, -156, 102, -65, 33, -19, -5, -7, -31, 22, + 3, 24, -56, 38, -72, 83, -116, 146, -189, 239, -305, 390, -503, 658, -888, 1264,-2019, 4446,29439,-3385, 1739,-1121, 786, -571, 419, -306, 219, -153, 100, -64, 32, -19, -6, -7, -32, 23, + 3, 24, -56, 37, -72, 83, -115, 144, -187, 236, -302, 385, -496, 649, -875, 1246,-1989, 4374,29464,-3343, 1716,-1106, 775, -563, 413, -301, 215, -150, 98, -63, 31, -18, -6, -7, -32, 23, + 3, 24, -56, 37, -71, 82, -114, 143, -185, 233, -298, 379, -489, 640, -862, 1227,-1958, 4302,29489,-3301, 1693,-1091, 764, -555, 407, -297, 212, -148, 96, -61, 30, -17, -7, -6, -32, 23, + 3, 24, -56, 37, -71, 81, -113, 141, -183, 231, -294, 374, -482, 630, -849, 1209,-1928, 4230,29513,-3259, 1670,-1076, 754, -547, 401, -292, 208, -145, 94, -60, 29, -16, -7, -6, -32, 23, + 3, 24, -56, 37, -70, 81, -112, 140, -180, 228, -290, 369, -475, 621, -837, 1190,-1898, 4159,29537,-3217, 1647,-1060, 743, -539, 394, -287, 205, -142, 92, -58, 27, -16, -8, -5, -32, 23, + 3, 24, -56, 36, -70, 80, -111, 138, -178, 225, -286, 364, -468, 612, -824, 1172,-1867, 4087,29561,-3174, 1624,-1045, 732, -531, 388, -283, 201, -140, 90, -57, 26, -15, -8, -5, -33, 23, + 3, 24, -56, 36, -69, 79, -110, 137, -176, 222, -282, 359, -461, 602, -811, 1153,-1837, 4016,29584,-3132, 1601,-1030, 721, -523, 382, -278, 198, -137, 89, -55, 25, -14, -9, -5, -33, 23, + 3, 24, -55, 36, -69, 79, -109, 135, -174, 219, -278, 353, -454, 593, -798, 1135,-1807, 3945,29607,-3088, 1577,-1014, 710, -514, 376, -273, 194, -134, 87, -54, 24, -13, -9, -4, -33, 23, + 3, 24, -55, 35, -68, 78, -108, 134, -172, 216, -274, 348, -447, 584, -785, 1116,-1776, 3874,29630,-3045, 1554, -999, 699, -506, 370, -269, 191, -132, 85, -52, 23, -13, -10, -4, -33, 23, + 3, 24, -55, 35, -68, 77, -107, 132, -170, 213, -270, 343, -440, 574, -773, 1098,-1746, 3803,29652,-3001, 1530, -983, 688, -498, 364, -264, 187, -129, 83, -51, 22, -12, -10, -4, -33, 23, + 3, 24, -55, 35, -68, 76, -106, 131, -168, 210, -266, 338, -433, 565, -760, 1079,-1716, 3733,29674,-2958, 1507, -968, 677, -490, 357, -259, 184, -126, 81, -49, 21, -11, -11, -3, -34, 23, + 3, 24, -55, 34, -67, 76, -105, 129, -166, 207, -263, 333, -426, 556, -747, 1060,-1685, 3663,29696,-2913, 1483, -952, 666, -481, 351, -255, 180, -124, 79, -48, 20, -10, -11, -3, -34, 23, + 3, 24, -55, 34, -67, 75, -103, 128, -163, 204, -259, 327, -419, 546, -734, 1042,-1655, 3592,29717,-2869, 1459, -936, 654, -473, 345, -250, 176, -121, 76, -46, 19, -10, -12, -3, -34, 23, + 3, 25, -55, 34, -66, 74, -102, 126, -161, 202, -255, 322, -412, 537, -721, 1023,-1625, 3522,29738,-2824, 1435, -921, 643, -465, 339, -245, 173, -118, 74, -45, 18, -9, -12, -2, -34, 23, + 2, 25, -54, 34, -66, 74, -101, 124, -159, 199, -251, 317, -405, 528, -708, 1004,-1594, 3453,29758,-2779, 1411, -905, 632, -457, 332, -240, 169, -115, 72, -43, 17, -8, -13, -2, -35, 23, + 2, 25, -54, 33, -65, 73, -100, 123, -157, 196, -247, 312, -398, 518, -695, 986,-1564, 3383,29778,-2734, 1387, -889, 621, -448, 326, -235, 166, -113, 70, -42, 16, -7, -13, -2, -35, 23, + 2, 25, -54, 33, -65, 72, -99, 121, -155, 193, -243, 306, -391, 509, -682, 967,-1534, 3314,29798,-2688, 1362, -873, 609, -440, 320, -231, 162, -110, 68, -40, 15, -7, -14, -1, -35, 23, + 2, 25, -54, 33, -64, 71, -98, 120, -153, 190, -239, 301, -384, 499, -670, 948,-1504, 3244,29817,-2643, 1338, -857, 598, -431, 313, -226, 158, -107, 66, -39, 14, -6, -14, -1, -35, 23, + 2, 25, -54, 32, -64, 71, -97, 118, -151, 187, -235, 296, -377, 490, -657, 930,-1473, 3175,29836,-2596, 1314, -841, 586, -423, 307, -221, 155, -104, 64, -38, 13, -5, -15, -1, -35, 23, + 2, 25, -54, 32, -63, 70, -96, 117, -148, 184, -231, 290, -370, 481, -644, 911,-1443, 3106,29855,-2550, 1289, -825, 575, -414, 301, -216, 151, -102, 62, -36, 12, -4, -15, 0, -36, 23, + 2, 25, -54, 32, -63, 69, -95, 115, -146, 181, -227, 285, -363, 471, -631, 892,-1413, 3038,29873,-2504, 1264, -809, 563, -406, 294, -211, 147, -99, 60, -34, 11, -4, -16, 0, -36, 23, + 2, 25, -53, 32, -63, 68, -94, 114, -144, 178, -223, 280, -356, 462, -618, 874,-1382, 2969,29891,-2457, 1239, -793, 552, -397, 288, -206, 144, -96, 58, -33, 9, -3, -16, 0, -36, 23, + 2, 25, -53, 31, -62, 68, -93, 112, -142, 175, -219, 275, -349, 452, -605, 855,-1352, 2901,29908,-2409, 1215, -776, 540, -389, 281, -202, 140, -93, 56, -31, 8, -2, -17, 1, -36, 23, + 2, 25, -53, 31, -62, 67, -92, 110, -140, 172, -215, 269, -342, 443, -592, 836,-1322, 2832,29925,-2362, 1190, -760, 529, -380, 275, -197, 136, -91, 54, -30, 7, -1, -17, 1, -36, 23, + 2, 25, -53, 31, -61, 66, -91, 109, -138, 169, -211, 264, -335, 433, -579, 818,-1292, 2764,29942,-2314, 1164, -744, 517, -372, 268, -192, 132, -88, 52, -28, 6, -1, -18, 1, -37, 23, + 2, 25, -53, 30, -61, 65, -89, 107, -135, 166, -207, 259, -328, 424, -566, 799,-1262, 2697,29958,-2267, 1139, -727, 505, -363, 262, -187, 129, -85, 50, -27, 5, 0, -18, 2, -37, 23, + 2, 25, -53, 30, -60, 65, -88, 106, -133, 163, -203, 253, -321, 414, -553, 780,-1231, 2629,29974,-2218, 1114, -711, 494, -354, 255, -182, 125, -82, 48, -25, 4, 1, -19, 2, -37, 23, + 2, 25, -52, 30, -60, 64, -87, 104, -131, 160, -199, 248, -314, 405, -540, 761,-1201, 2562,29990,-2170, 1089, -694, 482, -346, 249, -177, 121, -79, 46, -24, 3, 2, -19, 3, -37, 24, + 2, 25, -52, 29, -59, 63, -86, 103, -129, 157, -195, 243, -307, 395, -527, 743,-1171, 2494,30005,-2121, 1063, -678, 470, -337, 242, -172, 117, -77, 44, -22, 2, 2, -20, 3, -38, 24, + 2, 25, -52, 29, -59, 62, -85, 101, -127, 154, -191, 237, -300, 386, -514, 724,-1141, 2427,30020,-2072, 1038, -661, 458, -328, 236, -167, 114, -74, 41, -21, 1, 3, -20, 3, -38, 24, + 2, 25, -52, 29, -58, 62, -84, 99, -124, 151, -187, 232, -293, 376, -501, 705,-1111, 2361,30034,-2023, 1012, -644, 447, -320, 229, -162, 110, -71, 39, -19, 0, 4, -21, 4, -38, 24, + 2, 25, -52, 28, -58, 61, -83, 98, -122, 148, -183, 227, -286, 367, -488, 687,-1081, 2294,30048,-1973, 986, -628, 435, -311, 223, -157, 106, -68, 37, -18, -1, 5, -21, 4, -38, 24, + 2, 25, -52, 28, -57, 60, -82, 96, -120, 145, -179, 221, -278, 357, -475, 668,-1051, 2228,30062,-1924, 960, -611, 423, -302, 216, -152, 102, -65, 35, -16, -2, 5, -22, 4, -38, 24, + 2, 25, -52, 28, -57, 59, -81, 95, -118, 142, -175, 216, -271, 348, -462, 649,-1021, 2161,30075,-1874, 935, -594, 411, -293, 209, -147, 99, -62, 33, -15, -4, 6, -22, 5, -39, 24, + 2, 25, -51, 28, -56, 59, -80, 93, -116, 139, -171, 211, -264, 338, -449, 631, -991, 2095,30088,-1823, 909, -577, 399, -284, 203, -142, 95, -59, 31, -13, -5, 7, -23, 5, -39, 24, + 2, 25, -51, 27, -56, 58, -78, 92, -113, 136, -167, 205, -257, 329, -436, 612, -961, 2029,30101,-1773, 882, -560, 387, -275, 196, -137, 91, -57, 29, -12, -6, 8, -23, 5, -39, 24, + 2, 25, -51, 27, -55, 57, -77, 90, -111, 133, -163, 200, -250, 319, -423, 593, -931, 1964,30113,-1722, 856, -543, 375, -267, 189, -132, 87, -54, 27, -10, -7, 9, -24, 6, -39, 24, + 2, 25, -51, 27, -55, 56, -76, 88, -109, 130, -159, 195, -243, 310, -410, 575, -901, 1898,30125,-1671, 830, -526, 363, -258, 183, -127, 83, -51, 25, -8, -8, 9, -24, 6, -39, 24, + 2, 25, -51, 26, -54, 56, -75, 87, -107, 127, -155, 189, -236, 300, -397, 556, -871, 1833,30136,-1620, 804, -509, 351, -249, 176, -122, 79, -48, 22, -7, -9, 10, -25, 6, -40, 24, + 2, 25, -51, 26, -54, 55, -74, 85, -105, 124, -151, 184, -229, 291, -384, 537, -841, 1768,30147,-1568, 777, -492, 339, -240, 169, -117, 76, -45, 20, -5, -10, 11, -25, 7, -40, 24, + 2, 25, -50, 26, -53, 54, -73, 84, -102, 121, -147, 179, -222, 281, -371, 519, -811, 1703,30158,-1516, 751, -475, 327, -231, 163, -112, 72, -42, 18, -4, -11, 12, -26, 7, -40, 24, + 2, 25, -50, 25, -53, 53, -72, 82, -100, 118, -143, 173, -215, 272, -358, 500, -782, 1639,30168,-1464, 724, -458, 314, -222, 156, -106, 68, -39, 16, -2, -12, 12, -26, 7, -40, 24, + 2, 25, -50, 25, -53, 53, -71, 80, -98, 115, -139, 168, -207, 262, -345, 481, -752, 1574,30178,-1412, 698, -441, 302, -213, 149, -101, 64, -36, 14, -1, -14, 13, -27, 8, -40, 24, + 2, 25, -50, 25, -52, 52, -70, 79, -96, 112, -135, 163, -200, 253, -332, 463, -722, 1510,30188,-1359, 671, -423, 290, -204, 142, -96, 60, -34, 12, 1, -15, 14, -27, 8, -41, 24, + 2, 25, -50, 24, -52, 51, -68, 77, -94, 109, -131, 157, -193, 243, -319, 444, -692, 1446,30197,-1307, 644, -406, 278, -195, 135, -91, 56, -31, 10, 2, -16, 15, -28, 8, -41, 24, + 2, 25, -50, 24, -51, 50, -67, 76, -91, 106, -127, 152, -186, 234, -306, 425, -663, 1382,30205,-1254, 617, -389, 266, -186, 129, -86, 52, -28, 7, 4, -17, 15, -28, 9, -41, 24, + 2, 25, -49, 24, -51, 50, -66, 74, -89, 103, -123, 146, -179, 224, -293, 407, -633, 1319,30214,-1200, 590, -371, 253, -177, 122, -81, 48, -25, 5, 6, -18, 16, -29, 9, -41, 24, + 2, 25, -49, 23, -50, 49, -65, 73, -87, 100, -119, 141, -172, 215, -280, 388, -604, 1255,30222,-1147, 563, -354, 241, -168, 115, -76, 45, -22, 3, 7, -19, 17, -29, 9, -41, 24, + 2, 25, -49, 23, -50, 48, -64, 71, -85, 97, -115, 136, -165, 205, -267, 370, -574, 1192,30230,-1093, 536, -336, 229, -159, 108, -70, 41, -19, 1, 9, -20, 18, -30, 10, -42, 24, + 2, 25, -49, 23, -49, 47, -63, 69, -83, 94, -111, 130, -158, 196, -254, 351, -545, 1129,30237,-1039, 509, -319, 216, -150, 101, -65, 37, -16, -1, 10, -21, 19, -30, 10, -42, 24, + 2, 25, -49, 22, -49, 46, -62, 68, -80, 91, -107, 125, -151, 186, -241, 333, -515, 1067,30244, -984, 481, -301, 204, -140, 95, -60, 33, -13, -3, 12, -22, 19, -31, 11, -42, 24, + 2, 25, -48, 22, -48, 46, -61, 66, -78, 88, -103, 120, -144, 177, -228, 314, -486, 1004,30250, -930, 454, -284, 191, -131, 88, -55, 29, -10, -6, 14, -24, 20, -31, 11, -42, 24, + 2, 25, -48, 22, -48, 45, -59, 65, -76, 85, -99, 114, -136, 168, -215, 296, -456, 942,30256, -875, 426, -266, 179, -122, 81, -50, 25, -7, -8, 15, -25, 21, -32, 11, -42, 24, + 2, 25, -48, 21, -47, 44, -58, 63, -74, 82, -95, 109, -129, 158, -202, 277, -427, 880,30262, -820, 399, -248, 167, -113, 74, -44, 21, -4, -10, 17, -26, 22, -32, 12, -43, 24, + 2, 25, -48, 21, -47, 43, -57, 61, -72, 79, -91, 104, -122, 149, -190, 259, -398, 818,30267, -765, 371, -231, 154, -104, 67, -39, 17, -1, -12, 18, -27, 22, -33, 12, -43, 24, + 2, 25, -48, 21, -46, 43, -56, 60, -69, 76, -87, 98, -115, 139, -177, 240, -369, 756,30272, -709, 344, -213, 142, -95, 60, -34, 13, 2, -14, 20, -28, 23, -34, 12, -43, 24, + 1, 25, -48, 20, -46, 42, -55, 58, -67, 73, -83, 93, -108, 130, -164, 222, -340, 695,30277, -653, 316, -195, 129, -85, 53, -29, 9, 5, -17, 21, -29, 24, -34, 13, -43, 24, + 1, 25, -47, 20, -45, 41, -54, 57, -65, 70, -79, 88, -101, 120, -151, 203, -310, 634,30281, -597, 288, -177, 117, -76, 46, -24, 5, 8, -19, 23, -30, 25, -35, 13, -43, 24, + 1, 25, -47, 20, -45, 40, -53, 55, -63, 67, -75, 82, -94, 111, -138, 185, -281, 573,30285, -541, 260, -160, 104, -67, 39, -18, 1, 11, -21, 25, -31, 26, -35, 13, -44, 24, + 1, 25, -47, 19, -44, 40, -52, 53, -60, 64, -71, 77, -87, 101, -125, 167, -252, 512,30288, -485, 232, -142, 91, -58, 32, -13, -3, 13, -23, 26, -33, 26, -36, 14, -44, 24, + 1, 25, -47, 19, -44, 39, -51, 52, -58, 61, -66, 72, -80, 92, -112, 148, -223, 452,30291, -428, 204, -124, 79, -48, 25, -8, -7, 16, -25, 28, -34, 27, -36, 14, -44, 24, + 1, 25, -47, 19, -43, 38, -49, 50, -56, 58, -62, 66, -73, 83, -99, 130, -194, 392,30294, -371, 176, -106, 66, -39, 18, -3, -11, 19, -27, 29, -35, 28, -37, 14, -44, 24, + 1, 25, -46, 18, -43, 37, -48, 49, -54, 55, -58, 61, -66, 73, -87, 112, -166, 332,30296, -314, 148, -88, 54, -30, 11, 3, -15, 22, -30, 31, -36, 29, -37, 15, -44, 24, + 1, 25, -46, 18, -42, 36, -47, 47, -52, 52, -54, 56, -59, 64, -74, 93, -137, 272,30298, -256, 120, -70, 41, -21, 4, 8, -19, 25, -32, 33, -37, 29, -38, 15, -45, 24, + 1, 25, -46, 18, -42, 36, -46, 45, -49, 49, -50, 50, -52, 54, -61, 75, -108, 212,30300, -198, 92, -52, 28, -11, -3, 13, -22, 28, -34, 34, -38, 30, -38, 15, -45, 24, + 1, 25, -46, 17, -41, 35, -45, 44, -47, 46, -46, 45, -45, 45, -48, 57, -79, 153,30301, -140, 63, -34, 16, -2, -10, 19, -26, 31, -36, 36, -39, 31, -39, 16, -45, 24, + 1, 25, -46, 17, -41, 34, -44, 42, -45, 43, -42, 40, -38, 36, -35, 39, -51, 94,30302, -82, 35, -16, 3, 7, -17, 24, -30, 34, -38, 37, -40, 32, -39, 16, -45, 24, + 44, 25, -46, 17, -40, 33, -43, 41, -43, 40, -38, 34, -31, 26, -23, 21, -22, 35,30302, -24, 6, 2, -10, 17, -24, 29, -34, 37, -41, 39, -42, 33, -40, 16, -45, 25, diff --git a/services/multimedia/audio/process/resample/coef/resample_any_up64_filter.txt b/services/multimedia/audio/process/resample/coef/resample_any_up64_filter.txt new file mode 100644 index 0000000..eabfeb4 --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_any_up64_filter.txt @@ -0,0 +1,65 @@ +//single phase coef Number:=32, upsample factor:=64, + -3, 25, -40, 74, -121, 189, -278, 389, -521, 668, -824, 981,-1132, 1277,-1468,32737, -987, 1053, -999, 897, -770, 634, -500, 377, -271, 185, -120, 73, -39, 25, -2, -3, + -3, 25, -40, 74, -123, 192, -284, 400, -540, 700, -875, 1062,-1259, 1494,-1929,32708, -488, 822, -862, 810, -714, 598, -477, 363, -263, 181, -118, 72, -39, 24, -2, -1, + -3, 26, -40, 75, -124, 195, -289, 410, -558, 730, -924, 1138,-1382, 1703,-2372,32651, 29, 585, -721, 719, -655, 559, -453, 349, -255, 177, -115, 70, -38, 24, -2, -1, + -3, 26, -41, 75, -125, 197, -294, 419, -574, 757, -969, 1211,-1500, 1904,-2795,32565, 564, 343, -576, 626, -593, 519, -428, 333, -246, 171, -112, 69, -38, 23, -1, -1, + -4, 26, -41, 75, -125, 198, -297, 427, -588, 783,-1011, 1280,-1613, 2097,-3197,32451, 1115, 95, -428, 530, -530, 478, -401, 317, -236, 166, -109, 67, -37, 23, -1, -1, + -4, 26, -40, 75, -125, 199, -300, 433, -601, 806,-1051, 1345,-1719, 2281,-3580,32309, 1683, -158, -277, 431, -464, 434, -373, 299, -225, 160, -106, 65, -36, 22, -1, -1, + -4, 26, -40, 75, -125, 199, -302, 438, -612, 826,-1087, 1406,-1820, 2456,-3942,32139, 2266, -415, -122, 330, -396, 389, -343, 280, -214, 153, -102, 63, -35, 21, 0, -1, + -4, 26, -40, 74, -125, 199, -303, 442, -621, 845,-1120, 1462,-1915, 2622,-4284,31941, 2865, -675, 34, 227, -327, 342, -313, 261, -202, 146, -98, 61, -33, 21, 0, -1, + -4, 26, -40, 74, -124, 199, -304, 445, -629, 861,-1150, 1514,-2003, 2778,-4604,31715, 3478, -939, 193, 122, -256, 294, -281, 240, -189, 138, -93, 59, -32, 20, 1, -1, + -4, 26, -39, 73, -123, 198, -303, 447, -635, 874,-1176, 1561,-2086, 2924,-4904,31463, 4105,-1205, 353, 16, -183, 245, -248, 219, -175, 130, -89, 56, -31, 19, 1, -1, + -5, 26, -39, 72, -121, 196, -302, 447, -639, 885,-1199, 1604,-2161, 3061,-5183,31184, 4744,-1472, 515, -92, -109, 195, -214, 196, -161, 121, -84, 53, -29, 18, 2, -1, + -5, 26, -38, 71, -120, 194, -300, 446, -641, 894,-1219, 1642,-2231, 3187,-5440,30879, 5396,-1741, 677, -200, -34, 143, -179, 173, -147, 112, -78, 50, -27, 17, 2, -1, + -5, 25, -37, 70, -118, 191, -297, 445, -642, 900,-1235, 1675,-2293, 3303,-5677,30548, 6059,-2011, 840, -310, 41, 90, -143, 150, -131, 103, -73, 47, -26, 16, 3, -2, + -5, 25, -36, 68, -116, 188, -294, 442, -641, 904,-1248, 1704,-2349, 3408,-5892,30192, 6733,-2280, 1002, -420, 118, 37, -106, 125, -116, 93, -67, 43, -24, 15, 3, -2, + -5, 25, -35, 67, -113, 185, -290, 438, -639, 906,-1257, 1728,-2398, 3503,-6086,29811, 7416,-2548, 1165, -530, 195, -17, -69, 100, -99, 83, -61, 40, -22, 14, 4, -2, + -5, 25, -34, 65, -110, 181, -285, 432, -634, 905,-1263, 1747,-2440, 3587,-6260,29406, 8108,-2815, 1326, -640, 272, -72, -31, 75, -83, 72, -54, 36, -20, 13, 4, -2, + -5, 24, -33, 63, -107, 177, -280, 426, -629, 901,-1266, 1761,-2475, 3661,-6413,28978, 8808,-3079, 1487, -749, 350, -127, 7, 48, -65, 61, -48, 32, -18, 11, 5, -2, + -5, 24, -32, 61, -104, 172, -274, 419, -621, 896,-1266, 1771,-2503, 3724,-6545,28527, 9515,-3341, 1645, -858, 427, -182, 46, 22, -48, 50, -41, 28, -16, 10, 5, -2, + -5, 23, -31, 59, -101, 167, -267, 411, -612, 888,-1262, 1776,-2525, 3776,-6657,28055,10228,-3599, 1802, -966, 505, -237, 85, -5, -30, 39, -34, 24, -13, 9, 6, -2, + -5, 23, -30, 57, -97, 162, -260, 402, -602, 878,-1255, 1776,-2539, 3818,-6749,27561,10946,-3852, 1956,-1073, 581, -292, 124, -32, -12, 27, -27, 20, -11, 8, 7, -2, + -5, 22, -29, 54, -93, 156, -252, 392, -590, 866,-1244, 1771,-2547, 3849,-6821,27046,11669,-4101, 2107,-1178, 657, -348, 164, -60, 7, 15, -19, 16, -8, 6, 7, -3, + -5, 22, -27, 52, -89, 150, -243, 381, -577, 852,-1231, 1762,-2548, 3869,-6874,26512,12394,-4343, 2254,-1281, 733, -403, 203, -87, 25, 3, -12, 11, -6, 5, 8, -3, + -5, 21, -26, 50, -85, 144, -234, 369, -563, 835,-1214, 1749,-2542, 3879,-6908,25959,13121,-4579, 2398,-1382, 807, -457, 242, -115, 44, -10, -4, 6, -3, 3, 9, -3, + -5, 21, -24, 47, -81, 137, -225, 356, -547, 817,-1195, 1731,-2530, 3879,-6923,25388,13850,-4808, 2538,-1481, 880, -511, 282, -143, 63, -22, 4, 2, -1, 2, 9, -3, + -5, 20, -23, 44, -77, 130, -215, 343, -530, 797,-1173, 1709,-2512, 3869,-6919,24799,14578,-5029, 2672,-1577, 951, -564, 320, -170, 82, -35, 12, -3, 2, 0, 10, -3, + -5, 20, -22, 42, -72, 123, -205, 329, -512, 775,-1148, 1682,-2487, 3849,-6898,24195,15305,-5241, 2802,-1670, 1020, -616, 359, -198, 101, -47, 20, -8, 5, -1, 11, -3, + -4, 19, -20, 39, -67, 116, -194, 314, -492, 751,-1120, 1652,-2456, 3819,-6859,23575,16031,-5443, 2926,-1759, 1088, -667, 397, -225, 120, -60, 28, -13, 8, -3, 11, -3, + -4, 18, -18, 36, -63, 109, -183, 298, -472, 725,-1089, 1617,-2419, 3780,-6804,22941,16753,-5636, 3044,-1846, 1154, -717, 434, -252, 139, -73, 36, -18, 10, -4, 12, -3, + -4, 18, -17, 33, -58, 101, -171, 282, -451, 698,-1056, 1579,-2376, 3731,-6732,22294,17471,-5818, 3156,-1928, 1217, -766, 471, -279, 158, -86, 44, -23, 13, -6, 13, -4, + -4, 17, -15, 31, -53, 93, -160, 266, -428, 669,-1021, 1537,-2327, 3673,-6644,21634,18184,-5988, 3261,-2006, 1277, -813, 506, -305, 177, -98, 53, -28, 16, -7, 13, -4, + -4, 16, -14, 28, -48, 85, -148, 249, -405, 639, -983, 1492,-2273, 3607,-6541,20962,18890,-6146, 3359,-2080, 1335, -858, 541, -331, 195, -111, 61, -33, 19, -9, 14, -4, + -4, 16, -12, 25, -43, 77, -136, 231, -381, 608, -944, 1443,-2213, 3532,-6423,20281,19590,-6291, 3450,-2149, 1391, -902, 575, -357, 214, -123, 69, -38, 22, -11, 15, -4, + -4, 15, -11, 22, -38, 69, -123, 214, -357, 575, -902, 1391,-2149, 3450,-6291,19590,20281,-6423, 3532,-2213, 1443, -944, 608, -381, 231, -136, 77, -43, 25, -12, 16, -4, + -4, 14, -9, 19, -33, 61, -111, 195, -331, 541, -858, 1335,-2080, 3359,-6146,18890,20962,-6541, 3607,-2273, 1492, -983, 639, -405, 249, -148, 85, -48, 28, -14, 16, -4, + -4, 13, -7, 16, -28, 53, -98, 177, -305, 506, -813, 1277,-2006, 3261,-5988,18184,21634,-6644, 3673,-2327, 1537,-1021, 669, -428, 266, -160, 93, -53, 31, -15, 17, -4, + -4, 13, -6, 13, -23, 44, -86, 158, -279, 471, -766, 1217,-1928, 3156,-5818,17471,22294,-6732, 3731,-2376, 1579,-1056, 698, -451, 282, -171, 101, -58, 33, -17, 18, -4, + -3, 12, -4, 10, -18, 36, -73, 139, -252, 434, -717, 1154,-1846, 3044,-5636,16753,22941,-6804, 3780,-2419, 1617,-1089, 725, -472, 298, -183, 109, -63, 36, -18, 18, -4, + -3, 11, -3, 8, -13, 28, -60, 120, -225, 397, -667, 1088,-1759, 2926,-5443,16031,23575,-6859, 3819,-2456, 1652,-1120, 751, -492, 314, -194, 116, -67, 39, -20, 19, -4, + -3, 11, -1, 5, -8, 20, -47, 101, -198, 359, -616, 1020,-1670, 2802,-5241,15305,24195,-6898, 3849,-2487, 1682,-1148, 775, -512, 329, -205, 123, -72, 42, -22, 20, -5, + -3, 10, 0, 2, -3, 12, -35, 82, -170, 320, -564, 951,-1577, 2672,-5029,14578,24799,-6919, 3869,-2512, 1709,-1173, 797, -530, 343, -215, 130, -77, 44, -23, 20, -5, + -3, 9, 2, -1, 2, 4, -22, 63, -143, 282, -511, 880,-1481, 2538,-4808,13850,25388,-6923, 3879,-2530, 1731,-1195, 817, -547, 356, -225, 137, -81, 47, -24, 21, -5, + -3, 9, 3, -3, 6, -4, -10, 44, -115, 242, -457, 807,-1382, 2398,-4579,13121,25959,-6908, 3879,-2542, 1749,-1214, 835, -563, 369, -234, 144, -85, 50, -26, 21, -5, + -3, 8, 5, -6, 11, -12, 3, 25, -87, 203, -403, 733,-1281, 2254,-4343,12394,26512,-6874, 3869,-2548, 1762,-1231, 852, -577, 381, -243, 150, -89, 52, -27, 22, -5, + -3, 7, 6, -8, 16, -19, 15, 7, -60, 164, -348, 657,-1178, 2107,-4101,11669,27046,-6821, 3849,-2547, 1771,-1244, 866, -590, 392, -252, 156, -93, 54, -29, 22, -5, + -2, 7, 8, -11, 20, -27, 27, -12, -32, 124, -292, 581,-1073, 1956,-3852,10946,27561,-6749, 3818,-2539, 1776,-1255, 878, -602, 402, -260, 162, -97, 57, -30, 23, -5, + -2, 6, 9, -13, 24, -34, 39, -30, -5, 85, -237, 505, -966, 1802,-3599,10228,28055,-6657, 3776,-2525, 1776,-1262, 888, -612, 411, -267, 167, -101, 59, -31, 23, -5, + -2, 5, 10, -16, 28, -41, 50, -48, 22, 46, -182, 427, -858, 1645,-3341, 9515,28527,-6545, 3724,-2503, 1771,-1266, 896, -621, 419, -274, 172, -104, 61, -32, 24, -5, + -2, 5, 11, -18, 32, -48, 61, -65, 48, 7, -127, 350, -749, 1487,-3079, 8808,28978,-6413, 3661,-2475, 1761,-1266, 901, -629, 426, -280, 177, -107, 63, -33, 24, -5, + -2, 4, 13, -20, 36, -54, 72, -83, 75, -31, -72, 272, -640, 1326,-2815, 8108,29406,-6260, 3587,-2440, 1747,-1263, 905, -634, 432, -285, 181, -110, 65, -34, 25, -5, + -2, 4, 14, -22, 40, -61, 83, -99, 100, -69, -17, 195, -530, 1165,-2548, 7416,29811,-6086, 3503,-2398, 1728,-1257, 906, -639, 438, -290, 185, -113, 67, -35, 25, -5, + -2, 3, 15, -24, 43, -67, 93, -116, 125, -106, 37, 118, -420, 1002,-2280, 6733,30192,-5892, 3408,-2349, 1704,-1248, 904, -641, 442, -294, 188, -116, 68, -36, 25, -5, + -2, 3, 16, -26, 47, -73, 103, -131, 150, -143, 90, 41, -310, 840,-2011, 6059,30548,-5677, 3303,-2293, 1675,-1235, 900, -642, 445, -297, 191, -118, 70, -37, 25, -5, + -1, 2, 17, -27, 50, -78, 112, -147, 173, -179, 143, -34, -200, 677,-1741, 5396,30879,-5440, 3187,-2231, 1642,-1219, 894, -641, 446, -300, 194, -120, 71, -38, 26, -5, + -1, 2, 18, -29, 53, -84, 121, -161, 196, -214, 195, -109, -92, 515,-1472, 4744,31184,-5183, 3061,-2161, 1604,-1199, 885, -639, 447, -302, 196, -121, 72, -39, 26, -5, + -1, 1, 19, -31, 56, -89, 130, -175, 219, -248, 245, -183, 16, 353,-1205, 4105,31463,-4904, 2924,-2086, 1561,-1176, 874, -635, 447, -303, 198, -123, 73, -39, 26, -4, + -1, 1, 20, -32, 59, -93, 138, -189, 240, -281, 294, -256, 122, 193, -939, 3478,31715,-4604, 2778,-2003, 1514,-1150, 861, -629, 445, -304, 199, -124, 74, -40, 26, -4, + -1, 0, 21, -33, 61, -98, 146, -202, 261, -313, 342, -327, 227, 34, -675, 2865,31941,-4284, 2622,-1915, 1462,-1120, 845, -621, 442, -303, 199, -125, 74, -40, 26, -4, + -1, 0, 21, -35, 63, -102, 153, -214, 280, -343, 389, -396, 330, -122, -415, 2266,32139,-3942, 2456,-1820, 1406,-1087, 826, -612, 438, -302, 199, -125, 75, -40, 26, -4, + -1, -1, 22, -36, 65, -106, 160, -225, 299, -373, 434, -464, 431, -277, -158, 1683,32309,-3580, 2281,-1719, 1345,-1051, 806, -601, 433, -300, 199, -125, 75, -40, 26, -4, + -1, -1, 23, -37, 67, -109, 166, -236, 317, -401, 478, -530, 530, -428, 95, 1115,32451,-3197, 2097,-1613, 1280,-1011, 783, -588, 427, -297, 198, -125, 75, -41, 26, -4, + -1, -1, 23, -38, 69, -112, 171, -246, 333, -428, 519, -593, 626, -576, 343, 564,32565,-2795, 1904,-1500, 1211, -969, 757, -574, 419, -294, 197, -125, 75, -41, 26, -3, + -1, -2, 24, -38, 70, -115, 177, -255, 349, -453, 559, -655, 719, -721, 585, 29,32651,-2372, 1703,-1382, 1138, -924, 730, -558, 410, -289, 195, -124, 75, -40, 26, -3, + -1, -2, 24, -39, 72, -118, 181, -263, 363, -477, 598, -714, 810, -862, 822, -488,32708,-1929, 1494,-1259, 1062, -875, 700, -540, 400, -284, 192, -123, 74, -40, 25, -3, + -3, -2, 25, -39, 73, -120, 185, -271, 377, -500, 634, -770, 897, -999, 1053, -987,32737,-1468, 1277,-1132, 981, -824, 668, -521, 389, -278, 189, -121, 74, -40, 25, -3, diff --git a/services/multimedia/audio/process/resample/coef/resample_coef.c b/services/multimedia/audio/process/resample/coef/resample_coef.c new file mode 100644 index 0000000..5429aee --- /dev/null +++ b/services/multimedia/audio/process/resample/coef/resample_coef.c @@ -0,0 +1,177 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "hal_location.h" +#include "resample_coef.h" + +#define COEF_DEF(n) FLASH_RODATA_DEF(n) + +static const int16_t COEF_DEF(filter_50p7k_to_48k)[] = { + #include "resample_50p7k_to_48k_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_50p7k_to_48k) = { + .upsample_factor = 69, + .downsample_factor = 73, + .phase_coef_num = 6, + .total_coef_num = ARRAY_SIZE(filter_50p7k_to_48k), + .coef_group = filter_50p7k_to_48k, +}; + +static const int16_t COEF_DEF(filter_50p7k_to_44p1k)[] = { + #include "resample_50p7k_to_44p1k_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_50p7k_to_44p1k) = { + .upsample_factor = 33, + .downsample_factor = 38, + .phase_coef_num = 6, + .total_coef_num = ARRAY_SIZE(filter_50p7k_to_44p1k), + .coef_group = filter_50p7k_to_44p1k, +}; + +static const int16_t COEF_DEF(filter_44p1k_to_48k)[] = { + #include "resample_44p1k_to_48k_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_44p1k_to_48k) = { + .upsample_factor = 160, + .downsample_factor = 147, + .phase_coef_num = 8, + .total_coef_num = ARRAY_SIZE(filter_44p1k_to_48k), + .coef_group = filter_44p1k_to_48k, +}; + +static const int16_t COEF_DEF(filter_48k_to_44p1k)[] = { + #include "resample_48k_to_44p1k_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_48k_to_44p1k) = { + .upsample_factor = 147, + .downsample_factor = 160, + .phase_coef_num = 8, + .total_coef_num = ARRAY_SIZE(filter_48k_to_44p1k), + .coef_group = filter_48k_to_44p1k, +}; + +static const int16_t COEF_DEF(filter_32k_to_50p7k)[] = { + #include "resample_32k_to_50p7k_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_32k_to_50p7k) = { + .upsample_factor = 73, + .downsample_factor = 46, + .phase_coef_num = 24, + .total_coef_num = ARRAY_SIZE(filter_32k_to_50p7k), + .coef_group = filter_32k_to_50p7k, +}; + +static const int16_t COEF_DEF(filter_44p1k_to_50p7k)[] = { + #include "resample_44p1k_to_50p7k_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_44p1k_to_50p7k) = { + .upsample_factor = 38, + .downsample_factor = 33, + .phase_coef_num = 24, + .total_coef_num = ARRAY_SIZE(filter_44p1k_to_50p7k), + .coef_group = filter_44p1k_to_50p7k, +}; + +static const int16_t COEF_DEF(filter_48k_to_50p7k)[] = { + #include "resample_48k_to_50p7k_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_48k_to_50p7k) = { + .upsample_factor = 73, + .downsample_factor = 69, + .phase_coef_num = 24, + .total_coef_num = ARRAY_SIZE(filter_48k_to_50p7k), + .coef_group = filter_48k_to_50p7k, +}; + +static const int16_t COEF_DEF(filter_8k_to_8p4k)[] = { + #include "resample_8k_to_8p4k_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_8k_to_8p4k) = { + .upsample_factor = 73, + .downsample_factor = 69, + .phase_coef_num = 18, + .total_coef_num = ARRAY_SIZE(filter_8k_to_8p4k), + .coef_group = filter_8k_to_8p4k, +}; + +static const int16_t COEF_DEF(filter_8p4k_to_8k)[] = { + #include "resample_8p4k_to_8k_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_8p4k_to_8k) = { + .upsample_factor = 69, + .downsample_factor = 73, + .phase_coef_num = 16, + .total_coef_num = ARRAY_SIZE(filter_8p4k_to_8k), + .coef_group = filter_8p4k_to_8k, +}; + +static const int16_t COEF_DEF(filter_16k_to_48k)[] = { + #include "resample_16k_to_48k_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_16k_to_48k) = { + .upsample_factor = 3, + .downsample_factor = 1, + .phase_coef_num = 30, + .total_coef_num = ARRAY_SIZE(filter_16k_to_48k), + .coef_group = filter_16k_to_48k, +}; + +#ifdef RESAMPLE_ANY_SAMPLE_RATE +static const int16_t COEF_DEF(filter_any_up64)[] = { + #include "resample_any_up64_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_any_up64) = { + .upsample_factor = 64, + .downsample_factor = 0, + .phase_coef_num = 32, + .total_coef_num = ARRAY_SIZE(filter_any_up64), + .coef_group = filter_any_up64, +}; + +static const int16_t COEF_DEF(filter_any_up256)[] = { + #include "resample_any_up256_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_any_up256) = { + .upsample_factor = 256, + .downsample_factor = 0, + .phase_coef_num = 24, + .total_coef_num = ARRAY_SIZE(filter_any_up256), + .coef_group = filter_any_up256, +}; + +static const int16_t COEF_DEF(filter_any_up512_32)[] = { + #include "resample_any_up512_32_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_any_up512_32) = { + .upsample_factor = 512, + .downsample_factor = 0, + .phase_coef_num = 32, + .total_coef_num = ARRAY_SIZE(filter_any_up512_32), + .coef_group = filter_any_up512_32, +}; + +static const int16_t COEF_DEF(filter_any_up512_36)[] = { + #include "resample_any_up512_36_filter.txt" +}; +const struct RESAMPLE_COEF_T COEF_DEF(resample_coef_any_up512_36) = { + .upsample_factor = 512, + .downsample_factor = 0, + .phase_coef_num = 36, + .total_coef_num = ARRAY_SIZE(filter_any_up512_36), + .coef_group = filter_any_up512_36, +}; +#endif + diff --git a/services/multimedia/audio/process/resample/include/audio_resample.h b/services/multimedia/audio/process/resample/include/audio_resample.h new file mode 100644 index 0000000..17b9069 --- /dev/null +++ b/services/multimedia/audio/process/resample/include/audio_resample.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __AUDIO_RESAMPLER_H__ +#define __AUDIO_RESAMPLER_H__ + +#error "audio_resample.h/c have been obsolete. Please use audio_resample_ex.h/c instead" + +#if 0 +#ifdef __cplusplus +extern "C" { +#endif + +enum audio_resample_status_t{ + AUDIO_RESAMPLE_STATUS_SUCESS = 0, + AUDIO_RESAMPLE_STATUS_CONTINUE, + AUDIO_RESAMPLE_STATUS_FAILED, +}; + +enum resample_id_t{ + RESAMPLE_ID_8TO8P4 = 0, + RESAMPLE_ID_8P4TO8, + RESAMPLE_ID_NUM +}; + +#define RESAMPLE_TYPE_DOWN_STEREO 0x1 +#define RESAMPLE_TYPE_UP_MONO 0x2 +#define RESAMPLE_TYPE_DOWN_MONO 0x4 + +enum audio_resample_status_t audio_resample_open(int type, enum resample_id_t resample_id_up, + enum resample_id_t resample_id_down, uint8_t *up_buf, uint8_t *down_buf, void* (* alloc_ext)(int)); +enum audio_resample_status_t audio_resample_cfg(int type, short *OutBuf, int OutLen); +enum audio_resample_status_t audio_resample_run(int type, short *InBuf, int InLen); +void audio_resample_close(void); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/services/multimedia/audio/process/resample/include/audio_resample_ex.h b/services/multimedia/audio/process/resample/include/audio_resample_ex.h new file mode 100644 index 0000000..fe59444 --- /dev/null +++ b/services/multimedia/audio/process/resample/include/audio_resample_ex.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __AUDIO_RESAMPLER_EX_H__ +#define __AUDIO_RESAMPLER_EX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_aud.h" + +enum RESAMPLE_STATUS_T { + RESAMPLE_STATUS_OK = 0, + RESAMPLE_STATUS_ERROR, + RESAMPLE_STATUS_NO_COEF, + RESAMPLE_STATUS_NO_COEF_GROUP, + RESAMPLE_STATUS_BAD_COEF_NUM, + RESAMPLE_STATUS_BAD_FACTOR, + RESAMPLE_STATUS_NO_BUF, + RESAMPLE_STATUS_BUF_MISALIGN, + RESAMPLE_STATUS_BUF_TOO_SMALL, + RESAMPLE_STATUS_BAD_ID, + + RESAMPLE_STATUS_OUT_FULL, + RESAMPLE_STATUS_IN_EMPTY, + RESAMPLE_STATUS_DONE, +}; + +struct RESAMPLE_COEF_T { + uint16_t upsample_factor; + uint16_t downsample_factor; + uint8_t phase_coef_num; + uint16_t total_coef_num; + const int16_t *coef_group; +}; + +struct RESAMPLE_CFG_T { + enum AUD_CHANNEL_NUM_T chans; + enum AUD_BITS_T bits; + float ratio_step; + const struct RESAMPLE_COEF_T *coef; + void *buf; + uint32_t size; +}; + +struct RESAMPLE_IO_BUF_T { + const void *in; + uint32_t in_size; + void *out; + uint32_t out_size; + // For cyclic output buffer + void *out_cyclic_start; + void *out_cyclic_end; +}; + +typedef void *RESAMPLE_ID; + +uint32_t audio_resample_ex_get_buffer_size(enum AUD_CHANNEL_NUM_T chans, enum AUD_BITS_T bits, uint8_t phase_coef_num); +enum RESAMPLE_STATUS_T audio_resample_ex_open(const struct RESAMPLE_CFG_T *cfg, RESAMPLE_ID *id_ptr); +enum RESAMPLE_STATUS_T audio_resample_ex_run(RESAMPLE_ID id, const struct RESAMPLE_IO_BUF_T *io, uint32_t *in_size_ptr, uint32_t *out_size_ptr); +void audio_resample_ex_close(RESAMPLE_ID id); +void audio_resample_ex_flush(RESAMPLE_ID id); + +enum RESAMPLE_STATUS_T audio_resample_ex_set_ratio_step(RESAMPLE_ID id, float ratio_step); +enum RESAMPLE_STATUS_T audio_resample_ex_get_ratio_step(RESAMPLE_ID id, float *ratio_step); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/resample/include/audio_resample_ex_32bit.h b/services/multimedia/audio/process/resample/include/audio_resample_ex_32bit.h new file mode 100644 index 0000000..ae8eab4 --- /dev/null +++ b/services/multimedia/audio/process/resample/include/audio_resample_ex_32bit.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __AUDIO_RESAMPLER_EX_H__ +#define __AUDIO_RESAMPLER_EX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_aud.h" + +enum RESAMPLE_STATUS_T { + RESAMPLE_STATUS_OK = 0, + RESAMPLE_STATUS_ERROR, + RESAMPLE_STATUS_NO_COEF, + RESAMPLE_STATUS_NO_COEF_GROUP, + RESAMPLE_STATUS_BAD_COEF_NUM, + RESAMPLE_STATUS_BAD_FACTOR, + RESAMPLE_STATUS_NO_BUF, + RESAMPLE_STATUS_BUF_MISALIGN, + RESAMPLE_STATUS_BUF_TOO_SMALL, + RESAMPLE_STATUS_BAD_ID, + + RESAMPLE_STATUS_OUT_FULL, + RESAMPLE_STATUS_IN_EMPTY, + RESAMPLE_STATUS_DONE, +}; + +struct RESAMPLE_COEF_T { + uint16_t upsample_factor; + uint16_t downsample_factor; + uint8_t phase_coef_num; + uint16_t total_coef_num; + const int16_t *coef_group; +}; + +struct RESAMPLE_CFG_T { + enum AUD_CHANNEL_NUM_T chans; + enum AUD_BITS_T bits; + float ratio_step; + const struct RESAMPLE_COEF_T *coef; + void *buf; + uint32_t size; +}; + +struct RESAMPLE_IO_BUF_T { + const void *in; + uint32_t in_size; + void *out; + uint32_t out_size; + // For cyclic output buffer + void *out_cyclic_start; + void *out_cyclic_end; +}; + +typedef void *RESAMPLE_ID; + +uint32_t audio_resample_ex_get_buffer_size_32bit(enum AUD_CHANNEL_NUM_T chans, enum AUD_BITS_T bits, uint8_t phase_coef_num); +enum RESAMPLE_STATUS_T audio_resample_ex_open_32bit(const struct RESAMPLE_CFG_T *cfg, RESAMPLE_ID *id_ptr); +enum RESAMPLE_STATUS_T audio_resample_ex_run_32bit(RESAMPLE_ID id, const struct RESAMPLE_IO_BUF_T *io, uint32_t *in_size_ptr, uint32_t *out_size_ptr); +void audio_resample_ex_close_32bit(RESAMPLE_ID id); +void audio_resample_ex_flush_32bit(RESAMPLE_ID id); + +enum RESAMPLE_STATUS_T audio_resample_ex_set_ratio_step_32bit(RESAMPLE_ID id, float ratio_step); +enum RESAMPLE_STATUS_T audio_resample_ex_get_ratio_step_32bit(RESAMPLE_ID id, float *ratio_step); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/audio/process/resample/include/resample_coef.h b/services/multimedia/audio/process/resample/include/resample_coef.h new file mode 100644 index 0000000..7de0ada --- /dev/null +++ b/services/multimedia/audio/process/resample/include/resample_coef.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __RESAMPLE_COEF_H__ +#define __RESAMPLE_COEF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "audio_resample_ex.h" + +extern const struct RESAMPLE_COEF_T resample_coef_50p7k_to_48k; +extern const struct RESAMPLE_COEF_T resample_coef_50p7k_to_44p1k; +extern const struct RESAMPLE_COEF_T resample_coef_44p1k_to_48k; +extern const struct RESAMPLE_COEF_T resample_coef_48k_to_44p1k; + +extern const struct RESAMPLE_COEF_T resample_coef_32k_to_50p7k; +extern const struct RESAMPLE_COEF_T resample_coef_44p1k_to_50p7k; +extern const struct RESAMPLE_COEF_T resample_coef_48k_to_50p7k; +extern const struct RESAMPLE_COEF_T resample_coef_8k_to_8p4k; +extern const struct RESAMPLE_COEF_T resample_coef_8p4k_to_8k; + +extern const struct RESAMPLE_COEF_T resample_coef_16k_to_48k; + +extern const struct RESAMPLE_COEF_T resample_coef_any_up64; +extern const struct RESAMPLE_COEF_T resample_coef_any_up256; +extern const struct RESAMPLE_COEF_T resample_coef_any_up512_32; +extern const struct RESAMPLE_COEF_T resample_coef_any_up512_36; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/Pcm8k_Cvsd.h b/services/multimedia/speech/inc/Pcm8k_Cvsd.h new file mode 100644 index 0000000..477a2f7 --- /dev/null +++ b/services/multimedia/speech/inc/Pcm8k_Cvsd.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +///////////////////////////////////////////////////////////////////////// +//PCM8K <=> CVSD +///////////////////////////////////////////////////////////////////////// +#ifndef _PCM8K_CVSD_H_ +#define _PCM8K_CVSD_H_ + + + +//max num of input samples +#define MAXNUMOFSAMPLES 128 + + +//resample delay +#define RESAMPLE_DELAY 32 + + +void Pcm8k_CvsdInit(void); +void Pcm8kToCvsd(short *PcmInBuf, unsigned char *CvsdOutBuf, int numsample); +void CvsdToPcm8k(unsigned char *CvsdInBuf, short *PcmOutBuf, int numsample, int LossFlag); + + +#endif + + + + + + + + + + + + diff --git a/services/multimedia/speech/inc/SubBandBasedAEC.h b/services/multimedia/speech/inc/SubBandBasedAEC.h new file mode 100644 index 0000000..a687e93 --- /dev/null +++ b/services/multimedia/speech/inc/SubBandBasedAEC.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SubBandAec_H__ +#define __SubBandAec_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + int bypass; + int filter_size; +} SubBandAecConfig; + +struct SubBandAecState_; + +typedef struct SubBandAecState_ SubBandAecState; + +SubBandAecState *SubBandAec_init(int sample_rate, int frame_size, const SubBandAecConfig *cfg); + +void SubBandAec_destroy(SubBandAecState *st); + +int32_t SubBandAec_process(SubBandAecState *st, short *datain, short *echoref, short *dataout, short Len); + +float SubBandAec_get_required_mips(SubBandAecState *st); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/multimedia/speech/inc/VoiceActivityDetection.h b/services/multimedia/speech/inc/VoiceActivityDetection.h new file mode 100644 index 0000000..67e7cdb --- /dev/null +++ b/services/multimedia/speech/inc/VoiceActivityDetection.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __VOICEACTIVITYDETECTION_H__ +#define __VOICEACTIVITYDETECTION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + float snrthd; + float energythd; +} VADConfig; + +struct VADState_; + +typedef struct VADState_ VADState; + +VADState *VAD_process_state_init(int32_t sample_rate, int32_t frame_size, const VADConfig *cfg); + +int32_t VAD_set_config(VADState *st, const VADConfig *cfg); + +short VAD_process_run(VADState *st, short *in); + +int32_t VAD_destroy(VADState *st); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/ae_macros.h b/services/multimedia/speech/inc/ae_macros.h new file mode 100644 index 0000000..2fde189 --- /dev/null +++ b/services/multimedia/speech/inc/ae_macros.h @@ -0,0 +1,7 @@ +#ifndef AE_MACROS_H +#define AE_MACROS_H + +#define CONSTRUCT_FUNC_NAME_A(p, c, m) p ## _ ## c ## _ ## m +#define CONSTRUCT_FUNC_NAME(p, c, m) CONSTRUCT_FUNC_NAME_A(p, c, m) + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/ae_math.h b/services/multimedia/speech/inc/ae_math.h new file mode 100644 index 0000000..12c022d --- /dev/null +++ b/services/multimedia/speech/inc/ae_math.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef AE_MATH_H +#define AE_MATH_H + +#include +#include + +#ifdef __arm__ +#include "arm_math.h" +#endif + +#define AE_PI 3.14159265358979323846f + +#define EPS (1e-7f) + +#define AE_CLAMP(x,lo,hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x)) + +#ifdef __arm__ +#define AE_SSAT16(x) __SSAT((int32_t)(x), 16) +#define AE_SSAT24(x) __SSAT((int32_t)(x), 24) +#else +#define AE_SSAT16(x) AE_CLAMP(x,-32768,32767) +#define AE_SSAT24(x) AE_CLAMP(x,-16777216,16777215) +#endif + +#define AE_ABS(x) ((x) > 0 ? (x) : (-(x))) + +#define AE_FLOOR(x) (floorf(x)) + +#define AE_ROUND(x) (roundf(x)) + +#define AE_INT(x) ((int)(x)) + +// deal with x > -1 && x < 0 +#define AE_SIGN(x) ((AE_INT(x) == 0 && (x) < 0) ? "-" : "") + +#define AE_FRAC(x) ((int)(((x) > 0 ? ((x) - AE_INT(x)) : (AE_INT(x) - (x))) * 1000000)) + +#define AE_MIN(a,b) ((a) < (b) ? (a) : (b)) + +#define AE_MAX(a,b) ((a) > (b) ? (a) : (b)) + +#define SQUARE(x) ((x) * (x)) + +#define DB2LIN(x) (powf(10.f, (x) / 20.f)) + +#ifdef VQE_SIMULATE +#define AE_SIN(x) sinf(x) +#define AE_COS(x) cosf(x) +#else +#define AE_SIN(x) arm_sin_f32(x) +#define AE_COS(x) arm_cos_f32(x) +#endif + +int ae_gcd(int u, int v); + +int ipow(int base, int exp); + +float ipowf(float base, int exp); + +float pow_int(float base, int exp); + +float expint(int n, float x); + +float sqrt_approx(float z); + +#define AE_RAND_MAX (32767) + +void ae_srand(unsigned int init); + +int ae_rand(void); + +void speech_conv(float *x, float *y, short len1,int len2, float *out); + +void scale_int16(int16_t *pDst, int16_t *pSrc, float scale, uint32_t blockSize); + +int32_t nextpow2(int32_t N); + +#endif diff --git a/services/multimedia/speech/inc/agc.h b/services/multimedia/speech/inc/agc.h new file mode 100644 index 0000000..2711a5a --- /dev/null +++ b/services/multimedia/speech/inc/agc.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef AGC_H +#define AGC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int32_t bypass; + int32_t target_level; + int32_t compression_gain; + int32_t limiter_enable; +} AgcConfig; + +struct AgcState_; + +typedef struct AgcState_ AgcState; + +AgcState *agc_state_create(int32_t sample_rate, int32_t frame_size, const AgcConfig *cfg); + +int32_t agc_state_destroy(AgcState *st); + +int32_t agc_set_config(AgcState *st, const AgcConfig *cfg); + +int32_t agc_process(AgcState *st, int16_t *pcm_buf, int32_t pcm_len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/anc_assist_algo.h b/services/multimedia/speech/inc/anc_assist_algo.h new file mode 100644 index 0000000..8ffd147 --- /dev/null +++ b/services/multimedia/speech/inc/anc_assist_algo.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + + +#ifndef __AF_ANC_H__ +#define __AF_ANC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_aud.h" + +//#define AF_ANC_DUMP_DATA + + +#if defined(_24BITS_ENABLE) +#define _SAMPLE_BITS (24) +typedef int ASSIST_PCM_T; +#else +#define _SAMPLE_BITS (16) +typedef short ASSIST_PCM_T; +#endif + + +typedef enum{ + AF_ANC_OFF = 0, + AF_ANC_ON, +}AF_ANC_STATUS_T; + +typedef enum{ + AF_ANC_MUSIC = 0, + AF_ANC_STANDALONE, +}AF_ANC_MODE_T; + + +typedef struct LeakageDetectionState_ LeakageDetectionState; +LeakageDetectionState *LeakageDetection_create(int frame_size,int delay0); +void LeakageDetection_destroy(LeakageDetectionState *st); +int LeakageDetection_process(LeakageDetectionState *leak_st,AF_ANC_STATUS_T adapflag,ASSIST_PCM_T *fb_buf,ASSIST_PCM_T *ref_buf,int pcm_len); +void LeakageDetection_adjust_delay(LeakageDetectionState *st, int delay0); + +void get_pilot_data(uint8_t *buf,int len); + + + + + +typedef struct ANCAssistMulti_ ANCAssistMultiState; + +ANCAssistMultiState * ANCAssistMulti_create(int sample_rate, int frame_size,int fftsize); +void ANCAssistMulti_process(ANCAssistMultiState *st, ASSIST_PCM_T *inF, ASSIST_PCM_T *inB,ASSIST_PCM_T *inR,int frame_len); +void ANCAssistMulti_destroy(ANCAssistMultiState * st); + + + + +//need to implement +void anc_assist_change_curve(int curve_id); +// void audio_adpt_status_set_anc_mode(uint8_t mode, bool init); +// void audio_engine_set_anc_gain(int32_t gain_ch_l, int32_t gain_ch_r, int type); +// int af_anc_sync_wind_status(uint8_t status); +bool audio_engine_tt_is_on(); +// bool anc_usb_app_get_status(); +// void audio_adpt_status_set_wind_status(int state); +void anc_assist_set_anc_gain(float gain_ch_l, float gain_ch_r,enum ANC_TYPE_T anc_type); + + +extern bool app_anc_work_status(); +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/audio_drc2.h b/services/multimedia/speech/inc/audio_drc2.h new file mode 100644 index 0000000..65c22ac --- /dev/null +++ b/services/multimedia/speech/inc/audio_drc2.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __AUDIO_DRC2_H__ +#define __AUDIO_DRC2_H__ + +#include + +#define MAX_LOOK_AHEAD_TIME (10) + +typedef struct { + int knee; + int look_ahead_time; + int threshold; + float makeup_gain; + int ratio; + int attack_time; + int release_time; +} DRC2_CFG_T; + +#ifdef __cplusplus +extern "C" { +#endif + +void audio_drc2_open(int sample_rate, int sample_bits, int ch_num); +void audio_drc2_close(void); +void audio_drc2_process(uint8_t *buf_p_l, uint8_t *buf_p_r, uint32_t pcm_len); +void audio_drc2_set_cfg(const DRC2_CFG_T *cfg); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/buffer_manager.h b/services/multimedia/speech/inc/buffer_manager.h new file mode 100644 index 0000000..a6109e8 --- /dev/null +++ b/services/multimedia/speech/inc/buffer_manager.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef BUFFER_MANAGER_H +#define BUFFER_MANAGER_H + +#include + +struct BufferManager_; + +typedef struct BufferManager_ BufferManager; + +typedef enum +{ + BUFFER_MANAGER_CACHING = 0, + BUFFER_MANAGER_CACHE_OK = 1, + BUFFER_MANAGER_FLUSH = 2 +} BufferManagerStatus; + +#ifdef __cplusplus +extern "C" { +#endif + +// Buffer management for decoupling codec frame size and vqe frame size, +// vqe frame size must be larger than codec frame size. +// When init buffer manager, input buffer should inited by +// buffer_manager_create(codec_frame_size, vqe_frame_size) +// output buffer should inited by +// buffer_manager_create(vqe_frame_size, codec_frame_size) +BufferManager *buffer_manager_create(int inlen, int outlen, int sample_size); + +void buffer_manager_destroy(BufferManager *st); + +BufferManagerStatus buffer_manager_process(BufferManager *st, void *inbuf, int inlen, void *outbuf, int outlen); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/compexp.h b/services/multimedia/speech/inc/compexp.h new file mode 100644 index 0000000..5e79463 --- /dev/null +++ b/services/multimedia/speech/inc/compexp.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef COMPEXP_H +#define COMPEXP_H + +#include + +typedef struct +{ + int32_t bypass; + float comp_threshold; + float comp_ratio; + float expand_threshold; + float expand_ratio; + float attack_time; + float release_time; + float makeup_gain; + int32_t delay; +} CompexpConfig; + +typedef struct CompexpState_ CompexpState; + +#ifdef __cplusplus +extern "C" { +#endif + +CompexpState *compexp_create(int32_t sample_rate, int32_t frame_size, const CompexpConfig *config); + +int32_t compexp_destroy(CompexpState *st); + +int32_t compexp_set_config(CompexpState *st, const CompexpConfig *cfg); + +int32_t compexp_process(CompexpState *st, int16_t *pcm_buf, int32_t pcm_len); + +float compexp_get_required_mips(CompexpState *st); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/crossfade.h b/services/multimedia/speech/inc/crossfade.h new file mode 100644 index 0000000..90ea826 --- /dev/null +++ b/services/multimedia/speech/inc/crossfade.h @@ -0,0 +1,58 @@ +#ifndef CROSSFADE_H +#define CROSSFADE_H + +#include + +enum CROSSFADE_STATUS_T { + CROSSFADE_STATUS_OK = 0, + CROSSFADE_STATUS_ERROR, + CROSSFADE_STATUS_NO_BUF, + CROSSFADE_STATUS_BUF_MISALIGN, + CROSSFADE_STATUS_BUF_TOO_SMALL, +}; + +typedef struct +{ + float overlap_time; + float coef1; + float coef2; + + void *buf; + uint32_t size; +} CrossFadeConfig; + +typedef void *CrossFadeId; + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t crossfade_get_buffer_size(void); + +enum CROSSFADE_STATUS_T crossfade_init(int32_t sample_rate, int32_t sample_bits, CrossFadeConfig *cfg, CrossFadeId *id); + +void crossfade_destroy(CrossFadeId id); + +/* + * outbuf = (1 - weight) * inbuf1 + weight * (coef1 * inbuf1 + coef2 * inbuf2) + * = (1 - weight + weight * coef1) * inbuf1 + weight * coef2 * inbuf2 + * = (1 - (1 - coef1) * weight) * inbuf1 + weight * coef2 * inbuf2; + * out_ch_num = max(ch_num1, ch_num2); + * final data is outbuf = inbuf1 * coef1 + inbuf2 * coef2; + * + * fadein: + * crossfade_process(st, NULL, 1, inbuf, ch_num, outbuf, frame_size); + * + * fadeout: + * crossfade_process(st, inbuf, ch_num, NULL, 1, frame_size); + * + * crossfade: (ch_num1 == ch_num2 || ch_num1 == 1 || ch_num2 == 1) + * crossfade_process(st, inbuf1, ch_num1, inbuf2, ch_num2, outbuf, frame_size); + */ +bool crossfade_process(CrossFadeId id, void *inbuf1, int32_t ch_num1, void *inbuf2, int32_t ch_num2, void *outbuf, int32_t frame_size); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/cvsd_codec.h b/services/multimedia/speech/inc/cvsd_codec.h new file mode 100644 index 0000000..2c82779 --- /dev/null +++ b/services/multimedia/speech/inc/cvsd_codec.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/******************************************************************************* +** namer£ºCVSD CODEC header +** description£ºCVSD encoder and CVSD decoder header +** version£ºV1.0 +** author: xuml +** modify£º2015.8.21. +*******************************************************************************/ + +#ifndef _CVSD_CODEC_H_ +#define _CVSD_CODEC_H_ + + +//Q fixed +#define CVSD_Q 10 + +struct CvsdEncSt +{ + unsigned short CvsdEncJudgeAlpha; + int CvsdEncLastData; + int CvsdEncDelta; + int CvsdEncFirstFrameFlag; + int FilterState0[3]; + int FilterState1[3]; + int FilterState2[3]; +}; +//decoder +struct CvsdDecSt +{ + unsigned short CvsdDecJudgeAlpha; + int CvsdDecLastData; + int CvsdDecDelta; + int FilterState0[3]; + int FilterState1[3]; + int FilterState2[3]; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +//encoder +void CvsdEncInit(struct CvsdEncSt *CvsdEnc); +int CvsdEncode(struct CvsdEncSt *CvsdEnc, short *pInPutData, short *pOutPutdata, int iEncSize); + +//decoder +void CvsdDecInit(struct CvsdDecSt *CvsdDec); +int CvsdDecode(struct CvsdDecSt *CvsdDec, short *pInPutData, short *pOutPutdata, int iDecSize); + +#ifdef __cplusplus +} +#endif + +#endif + + + + + + + + + + + + diff --git a/services/multimedia/speech/inc/dual_mic_denoise.h b/services/multimedia/speech/inc/dual_mic_denoise.h new file mode 100644 index 0000000..06c95ca --- /dev/null +++ b/services/multimedia/speech/inc/dual_mic_denoise.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __DUAL_MIC_DENOISE_H__ +#define __DUAL_MIC_DENOISE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define DUAL_MIC_DENOISE_GET_CALIBRATION_COEF_LEN (0) +#define DUAL_MIC_DENOISE_GET_CALIBRATION_COEF (1) +#define DUAL_MIC_DENOISE_SET_CALIBRATION_COEF (2) + +typedef struct { + int bypass; + float alpha_h; + float alpha_slow; + float alpha_fast; + float thegma; + float thre_corr; + float thre_filter_diff; + float cal_left_gain; + float cal_right_gain; + int delay_mono_sample; + int wnr_enable; +} DUAL_MIC_DENOISE_CFG_T; + +/** + * @brief Initialization + * + * @param alloc_ext The allocate extent RAM + * @param cfg The configuration set parameter + */ +void dual_mic_denoise_init(int32_t sample_rate, int32_t frame_size, const DUAL_MIC_DENOISE_CFG_T *cfg, void* (* alloc_ext)(int)); + +/** + * @brief Run + * + * @param in input sample buffer + * sample rate: 16k; + * sample bit: 16; + * channel num: 2; + * LRLRLR......: Left: main mic, Right: assist mic + * @param out output sample buffer + * sample rate: 16k; + * sample bit: 16; + * channel num: 1; + * @param[in] len The length is sample number + */ +void dual_mic_denoise_run(short *in, short len, short *out); + +/** + * @brief Calibrate left and right gain + * + * @param in Same as dual_mic_denoise_run definition + * @param[in] len Same as dual_mic_denoise_run definition + * @param[out] cfg Return calibrate configure parameter + */ +void dual_mic_denoise_Cal_Gain(short *in, short len, DUAL_MIC_DENOISE_CFG_T *cfg); + +/** + * @brief Oppose initialization + */ +void dual_mic_denoise_deinit(void); + +int dual_mic_denoise_ctl(int ctl, void *ptr); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/echo_canceller.h b/services/multimedia/speech/inc/echo_canceller.h new file mode 100644 index 0000000..8b8c91d --- /dev/null +++ b/services/multimedia/speech/inc/echo_canceller.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef ECHO_CANCELLER_H +#define ECHO_CANCELLER_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + int32_t bypass; + int32_t hpf_enabled; + int32_t af_enabled; + int32_t nlp_enabled; + int32_t clip_enabled; + int32_t stsupp_enabled; + int32_t ns_enabled; + int32_t cng_enabled; + // af config + int32_t blocks; + int32_t delay; + // nlp config + float min_ovrd; + float target_supp; + // ns config + float noise_supp; + // cng config + int32_t cng_type; // 0 - white noise, 1 - pink noise + float cng_level; + // clip + float clip_threshold; + int32_t banks; +} Ec2FloatConfig; + +struct Ec2FloatState_; + +typedef struct Ec2FloatState_ Ec2FloatState; + +Ec2FloatState *ec2float_create(int sample_rate, int frame_size, bool cp, const Ec2FloatConfig *cfg); + +int32_t ec2float_destroy(Ec2FloatState *st); + +int32_t ec2float_set_config(Ec2FloatState *st, const Ec2FloatConfig *cfg, bool cp); + +int32_t ec2float_stereo(Ec2FloatState *st, int16_t *pcm_in, int16_t *pcm_ref1, int16_t *pcm_ref2, int32_t pcm_len, int16_t *pcm_out); + +int32_t ec2float_process(Ec2FloatState *st, int16_t *pcm_in, int16_t *pcm_ref, int32_t pcm_len, int16_t *pcm_out); + +int32_t ec2float_set_external_vad(Ec2FloatState *st, bool vad); + +float ec2float_get_required_mips(Ec2FloatState *st); + +float *ec2float_get_fir_filter_coeffs(Ec2FloatState *st); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/ext_fft_f32.h b/services/multimedia/speech/inc/ext_fft_f32.h new file mode 100644 index 0000000..a841644 --- /dev/null +++ b/services/multimedia/speech/inc/ext_fft_f32.h @@ -0,0 +1,137 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "arm_math.h" + +#ifndef VQE_SIMULATE +#include "hal_trace.h" +#else +#define ASSERT(cond, str, ...) { if (!(cond)) { fprintf(stderr, str, ##__VA_ARGS__); while(1); } } +#define TRACE(str, ...) do { fprintf(stdout, str, ##__VA_ARGS__); fprintf(stdout, "\n"); } while (0) +#endif + +// Enable this MACRO, Get same data with speex fft +// Some case can disable this MACRO to reduce MIPS +// #define _FFT_PRECISION + +struct ext_f32_config { + float *in; + float *out; + arm_rfft_fast_instance_f32 fft; + int32_t N; + int32_t mode; +}; + +static void *ext_f32_fft_init(int32_t size, int32_t mode, void *ext_malloc(int)) +{ + arm_status status; + struct ext_f32_config *st = ext_malloc(1 * sizeof(struct ext_f32_config)); + st->mode = mode; + + st->in = ext_malloc(size * sizeof(float)); + + if (st->mode) + { + st->out = ext_malloc(size * sizeof(float)); + } + else + { + st->out = NULL; + } + + status = arm_rfft_fast_init_f32(&(st->fft), size); + ASSERT(status == ARM_MATH_SUCCESS, "FFTWRAP: arm cmsis f32 fft init error %d", status); + st->N = size; + + return st; +} + +static void ext_f32_fft_destroy(void *table, void ext_free(void *)) +{ + struct ext_f32_config *st = (struct ext_f32_config *)table; + + ext_free(st->in); + + if (st->mode) { + ext_free(st->out); + } + + ext_free(st); +} + +static POSSIBLY_UNUSED void ext_f32_fft(void *table, float *in, float *out) +{ + struct ext_f32_config *st = (struct ext_f32_config *)table; + const int32_t N = st->N; + float *iptr = st->in; + float *optr = NULL; + + if (st->mode) + { + optr = st->out; + } + else + { + optr = out; + } + + /* We need to make a copy as fft modify input data */ + for (int32_t i = 0; i < N; i++) + iptr[i] = in[i]; + + arm_rfft_fast_f32(&(st->fft), iptr, optr, 0); + + if (st->mode) + { + out[0] = optr[0]; + for (int32_t i = 1; i < N - 1; i++) { + out[i] = optr[i + 1]; + } + out[N - 1] = optr[1]; + } + +#if defined(_FFT_PRECISION) + for (int32_t i = 0; i < N; i++) + out[i] = out[i] / N; +#endif +} + +static POSSIBLY_UNUSED void ext_f32_ifft(void *table, float *in, float *out) +{ + struct ext_f32_config *st = (struct ext_f32_config *)table; + const int32_t N = st->N; + float *iptr = st->in; + +#if defined(_FFT_PRECISION) + for (int32_t i = 0; i < N; i++) { + in[i] = in[i] * N; + } +#endif + + if (st->mode) + { + iptr[0] = in[0]; + iptr[1] = in[N - 1]; + for (int32_t i = 1; i < N - 1; i++) { + iptr[i + 1] = in[i]; + } + } + else + { + iptr = in; + } + + arm_rfft_fast_f32(&(st->fft), iptr, out, 1); +} diff --git a/services/multimedia/speech/inc/ext_heap.h b/services/multimedia/speech/inc/ext_heap.h new file mode 100644 index 0000000..3cb244f --- /dev/null +++ b/services/multimedia/speech/inc/ext_heap.h @@ -0,0 +1,101 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "string.h" + +#ifndef VQE_SIMULATE +#include "hal_trace.h" +#else +#define ASSERT(cond, str, ...) { if (!(cond)) { fprintf(stderr, str, ##__VA_ARGS__); while(1); } } +#define TRACE(num, str, ...) do { fprintf(stdout, str, ##__VA_ARGS__); fprintf(stdout, "\n"); } while (0) +#endif + +#ifndef HEAP_BUFF_SIZE +#define HEAP_BUFF_SIZE (1024 * 12) +#endif + +static uint8_t heap_buff[HEAP_BUFF_SIZE]; +static uint32_t heap_buff_size_used; + +static int32_t ext_heap_init(void) +{ + TRACE(2, "[%s] Heap size = %d", __func__, HEAP_BUFF_SIZE); + + heap_buff_size_used = 0; + memset((uint8_t *)heap_buff, 0, HEAP_BUFF_SIZE); + return 0; +} + +static POSSIBLY_UNUSED int32_t ext_heap_deinit(void) +{ + TRACE(4,"[%s] heap = %d, used = %d, free = %d", __func__, HEAP_BUFF_SIZE, heap_buff_size_used, HEAP_BUFF_SIZE - heap_buff_size_used); + + return 0; +} + +static POSSIBLY_UNUSED uint32_t ext_heap_get_used_buff_size() +{ + return heap_buff_size_used; +} + +static uint32_t ext_heap_get_free_buff_size() +{ + return HEAP_BUFF_SIZE - heap_buff_size_used; +} + +static void *ext_get_buff(uint32_t size) +{ + uint32_t buff_size_free; + uint8_t *buf_ptr = &heap_buff[heap_buff_size_used]; + + buff_size_free = ext_heap_get_free_buff_size(); + + if (size % 4){ + size = size + (4 - size % 4); + } + + TRACE(3,"[%s] Free: %d; Alloc: %d", __func__, buff_size_free, size); + + ASSERT(size <= buff_size_free, "[%s] size = %d > free size = %d", __func__, size, buff_size_free); + + heap_buff_size_used += size; + // TRACE("Allocate %d, now used %d left %d", size, heap_buff_size_used, ext_heap_get_free_buff_size()); + + return (void *)buf_ptr; +} + +static void *ext_alloc(int size) +{ + void *mem_ptr = ext_get_buff(size); + + memset(mem_ptr, 0, size); + + return mem_ptr; +} + +static POSSIBLY_UNUSED void *ext_malloc(int size) +{ + return ext_alloc(size); +} + +static POSSIBLY_UNUSED void *ext_calloc(int nitems, int size) +{ + return ext_alloc(nitems * size); +} + +static POSSIBLY_UNUSED void ext_free(void *mem_ptr) +{ + ; +} diff --git a/services/multimedia/speech/inc/far_field_speech_enhancement.h b/services/multimedia/speech/inc/far_field_speech_enhancement.h new file mode 100644 index 0000000..61eae52 --- /dev/null +++ b/services/multimedia/speech/inc/far_field_speech_enhancement.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __FAR_FIELD_SPEECH_ENHANCEMENT_H__ +#define __FAR_FIELD_SPEECH_ENHANCEMENT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void far_field_speech_enhancement_init(void); +void far_field_speech_enhancement_start(void); +void far_field_speech_enhancement_process(short *in); +void far_field_speech_enhancement_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/fftfilt.h b/services/multimedia/speech/inc/fftfilt.h new file mode 100644 index 0000000..b5f35c5 --- /dev/null +++ b/services/multimedia/speech/inc/fftfilt.h @@ -0,0 +1,37 @@ +#ifndef FFTFILT_H +#define FFTFILT_H + +#include + +typedef struct +{ + float *filter; + int filter_length; + int nfft; +} FftFiltConfig; + +struct FftFiltState_; + +typedef struct FftFiltState_ FftFiltState; + +#ifdef __cplusplus +extern "C" { +#endif + +FftFiltState *fftfilt_init(int sample_rate, int frame_size, const FftFiltConfig *config); + +void fftfilt_destroy(FftFiltState *st); + +void fftfilt_process_float(FftFiltState *st, float *buf, int frame_size); + +void fftfilt_process(FftFiltState *st, int16_t *buf, int frame_size); + +void fftfilt_process2_float(FftFiltState *st, float *buf, int frame_size, int stride); + +void fftfilt_process2(FftFiltState *st, int16_t *buf, int frame_size, int stride); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/frame_resize.h b/services/multimedia/speech/inc/frame_resize.h new file mode 100644 index 0000000..dc014bc --- /dev/null +++ b/services/multimedia/speech/inc/frame_resize.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef FRAME_RESIZE_H +#define FRAME_RESIZE_H + +#include "stdint.h" + +struct FrameResizeState_; + +typedef struct FrameResizeState_ FrameResizeState; + +typedef int32_t(*CAPTURE_HANDLER_T)(void *, void *, int32_t *); + +typedef int32_t(*PLAYBACK_HANDLER_T)(void *, int32_t *); + +#ifdef __cplusplus +extern "C" { +#endif + +FrameResizeState *frame_resize_create(int codec_frame_size, + int codec_capture_channel, + int vqe_frame_size, + int capture_sample_size, + int playback_sample_size, + int aec_enable, + const CAPTURE_HANDLER_T capture_handler, + const PLAYBACK_HANDLER_T playback_handler); + +void frame_resize_destroy(FrameResizeState *st); + +void frame_resize_process_capture(FrameResizeState *st, void *pcm_buf, void *ref_buf, int32_t *pcm_len); + +void frame_resize_process_playback(FrameResizeState *st, void *pcm_buf, int32_t *pcm_len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/g726.h b/services/multimedia/speech/inc/g726.h new file mode 100644 index 0000000..3a14b5c --- /dev/null +++ b/services/multimedia/speech/inc/g726.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __G726_H +#define __G726_H + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned long g726_Encode(unsigned char *speech,char *bitstream, uint32_t sampleCount, uint8_t isReset); +unsigned long g726_Decode(char *bitstream,unsigned char *speech, uint32_t sampleCount, uint8_t isReset); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/multimedia/speech/inc/g72x.h b/services/multimedia/speech/inc/g72x.h new file mode 100644 index 0000000..a06eafc --- /dev/null +++ b/services/multimedia/speech/inc/g72x.h @@ -0,0 +1,112 @@ +/* + * This source code is a product of Sun Microsystems, Inc. and is provided + * for unrestricted use. Users may copy or modify this source code without + * charge. + * + * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING + * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun source code is provided with no support and without any obligation on + * the part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * g72x.h + * + * Header file for CCITT conversion routines. + * + */ + +#include "math.h" + +#ifndef _G72X_H +#define _G72X_H + +#define AUDIO_ENCODING_ULAW (1) /* ISDN u-law */ +#define AUDIO_ENCODING_ALAW (2) /* ISDN A-law */ +#define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */ + +/* + * The following is the definition of the state structure + * used by the G.721/G.723 encoder and decoder to preserve their internal + * state between successive calls. The meanings of the majority + * of the state structure fields are explained in detail in the + * CCITT Recommendation G.721. The field names are essentially indentical + * to variable names in the bit level description of the coding algorithm + * included in this Recommendation. + */ +typedef struct g726_state_s { + long yl; /* Locked or steady state step size multiplier. */ + int yu; /* Unlocked or non-steady state step size multiplier. */ + int dms; /* Short term energy estimate. */ + int dml; /* Long term energy estimate. */ + int ap; /* Linear weighting coefficient of 'yl' and 'yu'. */ + + int a[2]; /* Coefficients of pole portion of prediction filter. */ + int b[6]; /* Coefficients of zero portion of prediction filter. */ + int pk[2]; /* Signs of previous two samples of a partially + * reconstructed signal. */ + short dq[6];/* int here fails in newupdate on encode! + * Previous 6 samples of the quantized difference + * signal represented in an internal floating point + * format. + */ + int sr[2]; /* Previous 2 samples of the quantized difference + * signal represented in an internal floating point + * format. */ + int td; /* delayed tone detect, new in 1988 version */ +} g726_state; + +/* External function definitions. */ + +void g726_init_state( g726_state *); + +int g726_32_encoder( + int sample, + int in_coding, + g726_state *state_ptr); +int g726_32_decoder( + int code, + int out_coding, + g726_state *state_ptr); +int g726_16_encoder( + int sample, + int in_coding, + g726_state *state_ptr); +int g726_16_decoder( + int code, + int out_coding, + g726_state *state_ptr); +int g726_24_encoder( + int sample, + int in_coding, + g726_state *state_ptr); +int g726_24_decoder( + int code, + int out_coding, + g726_state *state_ptr); +int g726_40_encoder( + int sample, + int in_coding, + g726_state *state_ptr); +int g726_40_decoder( + int code, + int out_coding, + g726_state *state_ptr); + +#endif /* !_G72X_H */ + diff --git a/services/multimedia/speech/inc/iir_resample.h b/services/multimedia/speech/inc/iir_resample.h new file mode 100644 index 0000000..9fdffa1 --- /dev/null +++ b/services/multimedia/speech/inc/iir_resample.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef IIR_RESAMPLE_H +#define IIR_RESAMPLE_H + +#include + +enum IIR_RESAMPLE_MODE +{ + IIR_RESAMPLE_MODE_1TO2 = 0, + IIR_RESAMPLE_MODE_1TO3, + IIR_RESAMPLE_MODE_1TO6, + IIR_RESAMPLE_MODE_2TO1, + IIR_RESAMPLE_MODE_3TO1, + IIR_RESAMPLE_MODE_6TO1, + IIR_RESAMPLE_MODE_NUM, +}; + +struct IirResampleState_; + +typedef struct IirResampleState_ IirResampleState; + +#ifdef __cplusplus +extern "C" { +#endif + +IirResampleState *iir_resample_init(int frame_size, enum IIR_RESAMPLE_MODE mode); + +void iir_resample_destroy(IirResampleState *st); + +int iir_resample_needed_out_count(IirResampleState *st, int in_size); + +// frame_size is input buffer frame_size +void iir_resample_process(IirResampleState *st, int16_t *in, int16_t *out, int in_size); + +enum IIR_RESAMPLE_MODE iir_resample_choose_mode(int sr_in, int sr_out); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/iirfilt.h b/services/multimedia/speech/inc/iirfilt.h new file mode 100644 index 0000000..6275314 --- /dev/null +++ b/services/multimedia/speech/inc/iirfilt.h @@ -0,0 +1,81 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef IIRFILT_H +#define IIRFILT_H + +#include + +enum IIR_BIQUARD_TYPE +{ + // pass through + IIR_BIQUARD_PASS = 0, + // raw filter + IIR_BIQUARD_RAW, + // low pass filter + IIR_BIQUARD_LPF, + // high pass filter + IIR_BIQUARD_HPF, + // band pass filter, constant skirt gain, peak gain = Q + IIR_BIQUARD_BPF0, + // band pass filter, const 0 dB peak gain + IIR_BIQUARD_BPF1, + // notch filter + IIR_BIQUARD_NOTCH, + // allpass filter + IIR_BIQUARD_APF, + // peakingEQ + IIR_BIQUARD_PEAKINGEQ, + // low shelf filter + IIR_BIQUARD_LOWSHELF, + // high shelf filter + IIR_BIQUARD_HIGHSHELF, + IIR_BIQUARD_QTY +}; + +struct IirBiquardState +{ + float a1, a2, b0, b1, b2; + float s0, s1, s2; +}; + +typedef struct IirBiquardState IirBiquardState; + +void iirfilt_design(IirBiquardState *st, int fs, int f0, float gain, float q, enum IIR_BIQUARD_TYPE type); + +void iirfilt_raw(IirBiquardState *st, float b0, float b1, float b2, float a1, float a2); + +void iirfilt_reset(IirBiquardState *st, int stages); + +void iirfilt_process(IirBiquardState *st, int stages, int16_t *buf, int frame_size); + +void iirfilt_process_int24(IirBiquardState *st, int stages, int32_t *buf, int frame_size); + +void iirfilt_process_float(IirBiquardState *st, int stages, float *buf, int frame_size); + +/* Deal with master gain in iir */ +void iirfilt_process2(IirBiquardState *st, int stages, float master_gain, int16_t *buf, int frame_size); + +void iirfilt_process2_int24(IirBiquardState *st, int stages, float master_gain, int32_t *buf, int frame_size); + +void iirfilt_process2_float(IirBiquardState *st, int stages, float master_gain, float *buf, int frame_size); + +void iirfilt_process3(IirBiquardState *st, int stages, float master_gain, int16_t *buf, int frame_size, int stride); + +void iirfilt_process3_int24(IirBiquardState *st, int stages, float master_gain, int32_t *buf, int frame_size, int stride); + +void iirfilt_process3_float(IirBiquardState *st, int stages, float master_gain, float *buf, int frame_size, int stride); + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/lc_mmse_ns.h b/services/multimedia/speech/inc/lc_mmse_ns.h new file mode 100644 index 0000000..11a2877 --- /dev/null +++ b/services/multimedia/speech/inc/lc_mmse_ns.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __LC_MMSE_NS_H__ +#define __LC_MMSE_NS_H__ + +#include + +#define LC_MMSE_NS_ENABLE_RES_ECHO + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int32_t bypass; + float denoise_dB; +} SpeechNs2Config; + +struct SpeechNs2State_; + +typedef struct SpeechNs2State_ SpeechNs2State; + +SpeechNs2State *speech_ns2_create(int32_t sample_rate, int32_t frame_size, const SpeechNs2Config *cfg); + +int32_t speech_ns2_destroy(SpeechNs2State *st); + +int32_t speech_ns2_set_config(SpeechNs2State *st, const SpeechNs2Config *cfg); + +int32_t speech_ns2_process(SpeechNs2State *st, int16_t *pcm_buf, int32_t pcm_len); + +int32_t speech_ns2_set_echo_state(SpeechNs2State *st, void *echo_state); + +int32_t speech_ns2_set_echo_suppress(SpeechNs2State *st, int32_t echo_suppress); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/lc_mmse_ns_float.h b/services/multimedia/speech/inc/lc_mmse_ns_float.h new file mode 100644 index 0000000..c6c7194 --- /dev/null +++ b/services/multimedia/speech/inc/lc_mmse_ns_float.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __LC_MMSE_NS_FLOAT_H__ +#define __LC_MMSE_NS_FLOAT_H__ + +// #define LC_MMSE_NS_ENABLE_RES_ECHO + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int32_t bypass; + float denoise_dB; + int32_t banks; +} SpeechNs2FloatConfig; + +struct SpeechNs2FloatState_; + +typedef struct SpeechNs2FloatState_ SpeechNs2FloatState; + +SpeechNs2FloatState *speech_ns2float_create(int32_t sample_rate, int32_t frame_size, bool cp, const SpeechNs2FloatConfig *cfg); + +int32_t speech_ns2float_destroy(SpeechNs2FloatState *st); + +int32_t speech_ns2float_set_config(SpeechNs2FloatState *st, const SpeechNs2FloatConfig *cfg, bool cp); + +int32_t speech_ns2float_process(SpeechNs2FloatState *st, int16_t *pcm_buf, int32_t pcm_len); + +int32_t speech_ns2float_set_echo_state(SpeechNs2FloatState *st, void *echo_state); + +int32_t speech_ns2float_set_echo_suppress(SpeechNs2FloatState *st, int32_t echo_suppress); + +void speech_ns2float_set_external_vad(SpeechNs2FloatState *st, bool vad); + +float speech_ns2float_get_required_mips(SpeechNs2FloatState *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/leftright_denoise.h b/services/multimedia/speech/inc/leftright_denoise.h new file mode 100644 index 0000000..68c0c38 --- /dev/null +++ b/services/multimedia/speech/inc/leftright_denoise.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __LEFTRIGHT_DENOISE_H__ +#define __LEFTRIGHT_DENOISE_H__ + +#include +#include "ae_macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int32_t bypass; + float delay_taps; // MIC L/R delay samples. 0: 适用于麦克è·ç¦»ä¸º<2cm; 1: 适用于麦克è·ç¦»ä¸º2cmå·¦å³; 2: 适用于麦克è·ç¦»ä¸º4cmå·¦å³ + int32_t freq_smooth_enable; // 1: 频域滤波打开; 0: 频域滤波关闭; 默认打开 + int32_t wnr_enable; // wind noise reduction enable + int32_t delay_enable; +} LeftRightDenoiseConfig; + +struct LeftRightDenoiseState_; + +typedef struct LeftRightDenoiseState_ LeftRightDenoiseState; + +#ifndef LEFTRIGHT_DENOISE_IMPL +#define LEFTRIGHT_DENOISE_IMPL float +#endif + +#define leftright_denoise_create CONSTRUCT_FUNC_NAME(leftright_denoise, LEFTRIGHT_DENOISE_IMPL, create) +#define leftright_denoise_destroy CONSTRUCT_FUNC_NAME(leftright_denoise, LEFTRIGHT_DENOISE_IMPL, destroy) +#define leftright_denoise_set_config CONSTRUCT_FUNC_NAME(leftright_denoise, LEFTRIGHT_DENOISE_IMPL, set_config) +#define leftright_denoise_process CONSTRUCT_FUNC_NAME(leftright_denoise, LEFTRIGHT_DENOISE_IMPL, process) +#define leftright_denoise_get_delay CONSTRUCT_FUNC_NAME(leftright_denoise, LEFTRIGHT_DENOISE_IMPL, get_delay) + +LeftRightDenoiseState *leftright_denoise_create(int32_t sample_rate, int32_t frame_size, const LeftRightDenoiseConfig *cfg); + +int32_t leftright_denoise_destroy(LeftRightDenoiseState *st); + +int32_t leftright_denoise_set_config(LeftRightDenoiseState *st, const LeftRightDenoiseConfig *cfg); + +int32_t leftright_denoise_process(LeftRightDenoiseState *st, short *pcm_buf, int32_t pcm_len, short *out_buf); + +int32_t leftright_denoise_get_delay(LeftRightDenoiseState *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/lpc_plc_api.h b/services/multimedia/speech/inc/lpc_plc_api.h new file mode 100644 index 0000000..5d74999 --- /dev/null +++ b/services/multimedia/speech/inc/lpc_plc_api.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef LPC_PLC_API_H +#define LPC_PLC_API_H + +#include + +struct LpcPlcState_; + +typedef struct LpcPlcState_ LpcPlcState; + +#ifdef __cplusplus +extern "C" { +#endif + +LpcPlcState *lpc_plc_create(int32_t sample_rate); + +void lpc_plc_destroy(LpcPlcState *st); + +void lpc_plc_save(LpcPlcState *st, int16_t *buf); + +void lpc_plc_generate(LpcPlcState *st, int16_t *buf, int16_t *encbuf); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/main_classify.h b/services/multimedia/speech/inc/main_classify.h new file mode 100644 index 0000000..d163ca9 --- /dev/null +++ b/services/multimedia/speech/inc/main_classify.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_NOISE_CLASSIFY_H__ +#define __SPEECH_NOISE_CLASSIFY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct ClassifyState_; +typedef struct ClassifyState_ ClassifyState; + +ClassifyState *classify_create(int sample_rate, int frame_size); +int classify_destroy(ClassifyState *state); +int classify_process(ClassifyState *state, short *inF, int last_classify_res); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/med_aec3_comm.h b/services/multimedia/speech/inc/med_aec3_comm.h new file mode 100644 index 0000000..dd05e67 --- /dev/null +++ b/services/multimedia/speech/inc/med_aec3_comm.h @@ -0,0 +1,122 @@ + +#ifndef _MED_AEC3_COMM_H_ +#define _MED_AEC3_COMM_H_ + +/***************************************************************************** + 1 ÆäËûÍ·Îļþ°üº¬ +*****************************************************************************/ +#include "codec_typedefine.h" +#include "med_fft.h" +#include "codec_com_codec.h" +#include "med_aec3_main.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/***************************************************************************** + 2 ºê¶¨Òå +*****************************************************************************/ +/* FFT IFFT»Øµ÷º¯Êý */ +typedef VOS_VOID (*MED_AEC_FFT_CALLBACK)(VOS_INT16 *, VOS_INT16 *); + +#ifdef AEC_ONLY_SUPPORT_8k +#ifdef SPEECH_STREAM_UNIT_128 +#define MED_AEC_FFT_LEN_NB (256) +#else +#define MED_AEC_FFT_LEN_NB (240) +#endif +#define MED_AEC_MAX_FFT_LEN (MED_AEC_FFT_LEN_NB) /* ¿í´øFFT³¤¶È */ +#else +#ifdef SPEECH_STREAM_UNIT_128 +#define MED_AEC_FFT_LEN_NB (256) +#define MED_AEC_FFT_LEN_WB (512) +#else +#define MED_AEC_FFT_LEN_NB (240) +#define MED_AEC_FFT_LEN_WB (480) +#endif +#define MED_AEC_MAX_FFT_LEN (MED_AEC_FFT_LEN_WB) /* ¿í´øFFT³¤¶È */ +#endif + +#define MED_AEC_HF_AF_M (6) + +/* ÁÙʱȫ¾ÖÊý×飬¹©AEC¸÷Ä£¿éʹÓà */ +//extern VOS_INT16 g_ashwMedAecTmp1Len640[MED_AEC_MAX_FFT_LEN]; +//extern VOS_INT16 g_ashwMedAecTmp2Len640[MED_AEC_MAX_FFT_LEN]; +//extern VOS_INT32 g_aswMedAecTmp1Len320[CODEC_FRAME_LENGTH_WB]; +//extern VOS_INT32 g_aswMedAecTmp1Len640[MED_AEC_MAX_FFT_LEN]; + +/* AEC ¹«¹²ºê¶¨Òå*/ +//#define MED_AEC_GetshwVecTmp640Ptr1() (&g_ashwMedAecTmp1Len640[0]) /* ÁÙʱȫ¾ÖÊý×éÖ¸Õë ³¤¶È640 INT16 */ +//#define MED_AEC_GetshwVecTmp640Ptr2() (&g_ashwMedAecTmp2Len640[0]) /* ÁÙʱȫ¾ÖÊý×éÖ¸Õë ³¤¶È640 INT16 */ +//#define MED_AEC_GetswVecTmp320Ptr1() (&g_aswMedAecTmp1Len320[0]) /* ÁÙʱȫ¾ÖÊý×éÖ¸Õë ³¤¶È320 INT32 */ +//#define MED_AEC_GetswVecTmp640Ptr1() (&g_aswMedAecTmp1Len640[0]) /* ÁÙʱȫ¾ÖÊý×éÖ¸Õë ³¤¶È640 INT32 */ + +#define MED_AEC_OFFSET_THD (60) /* ÑÓ³Ù²¹³¥ãÐÖµ */ +#define MED_AEC_MAX_OFFSET (960) /* ×î´ó²¹³¥³¤¶È£¬µ¥Î»²ÉÑùµã Q0*/ +#define MED_AEC_MAX_TAIL_LEN (960) /* ×î´óβ¶Ë³¤¶È£¬µ¥Î»ms£¬×î´óÖ§³Ö60msβ¶ËÑÓ³Ù Q0*/ +/***************************************************************************** + 3 ö¾Ù¶¨Òå +*****************************************************************************/ +/* AF FFT³¤¶È */ +enum MED_AEC_AF_FFT_LEN_ENUM +{ +#ifdef SPEECH_STREAM_UNIT_128 + MED_AEC_AF_FFT_LEN_NB = 256, /* Õ­´øFFT³¤¶È */ + MED_AEC_AF_FFT_LEN_WB = 512, /* ¿í´øFFT³¤¶È */ +#else + MED_AEC_AF_FFT_LEN_NB = 240, /* Õ­´øFFT³¤¶È */ + MED_AEC_AF_FFT_LEN_WB = 480, /* ¿í´øFFT³¤¶È */ +#endif + MED_AEC_AF_FFT_LEN_BUTT +}; +typedef VOS_INT16 MED_AEC_AF_FFT_LEN_ENUM_INT16; + +/* ¿ª¹ØÁ¿Ã¶¾Ù */ +enum CODEC_SWITCH_ENUM +{ + CODEC_SWITCH_OFF = 0, + CODEC_SWITCH_ON, + CODEC_SWITCH_BUTT +}; +typedef VOS_UINT16 CODEC_SWITCH_ENUM_UINT16; + +/***************************************************************************** + 4 È«¾Ö±äÁ¿ÉùÃ÷ +*****************************************************************************/ + +/***************************************************************************** + 5 STRUCT¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 6 UNION¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 7 OTHERS¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 8 º¯ÊýÉùÃ÷ +*****************************************************************************/ +#ifdef DEBUG_AEC +static VOS_VOID fprint_vec_int32(FILE *fd, VOS_INT32 *buf, VOS_INT32 len) +{ + for (VOS_INT32 i = 0; i < len - 1; i++) { + fprintf(fd, "%d ", buf[i]); + } + fprintf(fd, "%d\n", buf[len - 1]); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* end of med_aec_main.h*/ + diff --git a/services/multimedia/speech/inc/med_aec3_main.h b/services/multimedia/speech/inc/med_aec3_main.h new file mode 100644 index 0000000..60a3f72 --- /dev/null +++ b/services/multimedia/speech/inc/med_aec3_main.h @@ -0,0 +1,78 @@ + + +/***************************************************************************** + 1 ÆäËûÍ·Îļþ°üº¬ +*****************************************************************************/ +#include "v_typdef.h" + +#ifndef _MED_AEC3_MAIN_H_ +#define _MED_AEC3_MAIN_H_ + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/***************************************************************************** + 2 ºê¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 3 ö¾Ù¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 4 È«¾Ö±äÁ¿ÉùÃ÷ +*****************************************************************************/ + +/***************************************************************************** + 5 STRUCT¶¨Òå +*****************************************************************************/ +typedef VOS_VOID (*NS_HANDLER_T)(VOS_VOID *stNs, VOS_INT16 *shwBuf, VOS_INT32 swFrameLength); + +/* AEC²ÎÊý³õʼ»¯½Ó¿Ú */ +typedef struct +{ + VOS_BOOL enEAecEnable; /* AEC: ÔöÇ¿ÃâÌáAECʹÄÜ¿ª¹Ø */ + VOS_BOOL enHpfEnable; /* HPF: ¸ßͨÂ˲¨¿ª¹Ø */ + VOS_BOOL enAfEnable; /* AF : ×ÔÊÊÓ¦Â˲¨¿ª¹Ø */ + VOS_BOOL enNsEnable; /* NS : ÔëÉùÒÖÖÆ¿ª¹Ø */ + VOS_INT16 shwDelayLength; /* DELAY: ¹Ì¶¨ÑÓʱ */ +} MED_AEC3_NV_STRU; + +/***************************************************************************** + 6 UNION¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 7 OTHERS¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 8 º¯ÊýÉùÃ÷ +*****************************************************************************/ +extern VOS_UINT32 MED_AEC3_Main( + VOS_VOID *pAecInstance, + VOS_INT16 *pshwMicIn, + VOS_INT16 *pshwSpkIn, + VOS_INT16 *pshwLineOut); +extern VOS_VOID* MED_AEC3_Create(void); +extern VOS_UINT32 MED_AEC3_Destroy(VOS_VOID **ppAecObj); +extern VOS_UINT32 MED_AEC3_SetPara ( + VOS_VOID *pAecInstance, + MED_AEC3_NV_STRU *pstNv, + VOS_INT32 enSampleRate); +extern VOS_UINT32 MED_AEC3_SetExtenalNsHandle( + VOS_VOID *pAecInstance, + VOS_VOID *pstNs, + NS_HANDLER_T swNsHandler); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* end of med_aec_main.h*/ + diff --git a/services/multimedia/speech/inc/med_aec3_main_internal.h b/services/multimedia/speech/inc/med_aec3_main_internal.h new file mode 100644 index 0000000..90cb7db --- /dev/null +++ b/services/multimedia/speech/inc/med_aec3_main_internal.h @@ -0,0 +1,93 @@ + + +/***************************************************************************** + 1 ÆäËûÍ·Îļþ°üº¬ +*****************************************************************************/ +#include "codec_typedefine.h" +#include "med_aec_comm.h" +#include "med_aec3_main.h" +#include "med_aec_hf_af.h" +#include "med_aec_hf_nlp.h" +#include "med_aec_hpf.h" +#include "med_emph_filter.h" +#include "med_aec_delay.h" + +#ifndef _MED_AEC3_MAIN_INTERNAL_H_ +#define _MED_AEC3_MAIN_INTERNAL_H_ + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* NS ÄÚ²¿½á¹¹Ìå */ +typedef struct +{ + VOS_VOID *stNs; + NS_HANDLER_T swHandler; +} MED_AEC3_HF_NS_STRU; + +/* AECÄÚ²¿×´Ì¬½á¹¹ */ +typedef struct +{ + MED_OBJ_HEADER + VOS_BOOL shwIsEAecEnable; + VOS_BOOL shwIsHpfEnable; + VOS_BOOL shwIsPreEmpEnable; + VOS_BOOL shwIsAfEnable; + VOS_BOOL shwIsNsEnable; + VOS_INT16 shwFrameLength; + VOS_INT16 shwDelayLength; + MED_AEC_DELAY_STRU stEAecDelay; + MED_AEC_HF_AF_STRU stEAecHfAf; + MED_AEC_HPF_STRU stEAecMicHpf; + MED_AEC_HPF_STRU stEAecSpkHpf; + MED_AEC3_HF_NS_STRU stEAecNs; +#ifdef MED_AEC_PREEMPH_ENABLE + MED_PREEMPH_STRU stPreEmpMc; + MED_PREEMPH_STRU stPreEmpFar; + MED_DEEMPH_STRU stDeEmpMc; +#endif +} MED_AEC3_OBJ_STRU; + + + +/***************************************************************************** + 2 ºê¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 3 ö¾Ù¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 4 È«¾Ö±äÁ¿ÉùÃ÷ +*****************************************************************************/ + +/***************************************************************************** + 5 STRUCT¶¨Òå +*****************************************************************************/ + + +/***************************************************************************** + 6 UNION¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 7 OTHERS¶¨Òå +*****************************************************************************/ + +/***************************************************************************** + 8 º¯ÊýÉùÃ÷ +*****************************************************************************/ + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* end of med_aec_main.h*/ + diff --git a/services/multimedia/speech/inc/ns3.h b/services/multimedia/speech/inc/ns3.h new file mode 100644 index 0000000..17ce6bd --- /dev/null +++ b/services/multimedia/speech/inc/ns3.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef NS3_H +#define NS3_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + NS3_SUPPRESSION_LOW = 0, + NS3_SUPPRESSION_MID = 1, + NS3_SUPPRESSION_HIGH = 2, + NS3_SUPPRESSION_VERY_HIGH = 3 +} NS3_SUPPRESSION_MODE; + +typedef struct +{ + int32_t bypass; + NS3_SUPPRESSION_MODE mode; +} Ns3Config; + +struct Ns3State_; + +typedef struct Ns3State_ Ns3State; + +#define CONSTRUCT_FUNC_NAME_A(p, c, m) p ## _ ## c ## _ ## m +#define CONSTRUCT_FUNC_NAME(p, c, m) CONSTRUCT_FUNC_NAME_A(p, c, m) + +#ifndef NS3_IMPL +#define NS3_IMPL fixed +#endif + +#define ns3_create CONSTRUCT_FUNC_NAME(ns3, NS3_IMPL, init) +#define ns3_destroy CONSTRUCT_FUNC_NAME(ns3, NS3_IMPL, destroy) +#define ns3_set_config CONSTRUCT_FUNC_NAME(ns3, NS3_IMPL, set_config) +#define ns3_process CONSTRUCT_FUNC_NAME(ns3, NS3_IMPL, process) +#define ns3_get_required_mips CONSTRUCT_FUNC_NAME(ns3, NS3_IMPL, get_required_mips) + +Ns3State *ns3_create(int32_t sample_rate, int32_t frame_size, const Ns3Config *cfg); + +int32_t ns3_destroy(Ns3State *st); + +int32_t ns3_set_config(Ns3State *st, const Ns3Config *cfg); + +int32_t ns3_process(Ns3State *st, int16_t *pcm_buf, int32_t pcm_len); + +float ns3_get_required_mips(Ns3State *st); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/plc_16000.h b/services/multimedia/speech/inc/plc_16000.h new file mode 100644 index 0000000..ac7dd6e --- /dev/null +++ b/services/multimedia/speech/inc/plc_16000.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/******************************************************** +SBC Example PLC ANSI-C Source Code +File: sbcplc.h +*****************************************************************************/ +#ifndef SBCPLC_H +#define SBCPLC_H + +#define FS 120 /* Frame Size */ +#define N 256 /* 16ms - Window Length for pattern matching */ +#define M 64 /* 4ms - Template for matching */ +#define LHIST (N+FS-1) /* Length of history buffer required */ +#define SBCRT 60 /* SBC Reconvergence Time (samples) */ +#define OLAL 60 /* OverLap-Add Length (samples) */ + +//SBCRT + OLAL must be <=FS + +/* PLC State Information */ +struct PLC_State +{ + short hist[LHIST + OLAL + FS + SBCRT + OLAL]; + short bestlag; + int nbf; +}; +extern unsigned char indices0[57]; +/* Prototypes */ +void InitPLC(struct PLC_State *plc_state); +void PLC_bad_frame(struct PLC_State *plc_state, short *ZIRbuf, short *out); +void PLC_good_frame(struct PLC_State *plc_state, short *in, short *out); +#endif /* SBCPLC_H */ + diff --git a/services/multimedia/speech/inc/plc_8000.h b/services/multimedia/speech/inc/plc_8000.h new file mode 100644 index 0000000..b5fc76b --- /dev/null +++ b/services/multimedia/speech/inc/plc_8000.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +///////////////////////////////////////////////////////////////////////// +//Packets Loss Concealment / +///////////////////////////////////////////////////////////////////////// +#ifndef _PLC_8000_H_ +#define _PLC_8000_H_ + + +typedef struct PlcSt_8000_ PlcSt_8000; + +PlcSt_8000 *speech_plc_8000_init(void* (* speex_alloc_ext)(int)); +int speech_plc_8000(PlcSt_8000 *lc, short *InBuf, int len); + +#endif + + + + + + + + + + + + diff --git a/services/multimedia/speech/inc/recognition.h b/services/multimedia/speech/inc/recognition.h new file mode 100644 index 0000000..17f9172 --- /dev/null +++ b/services/multimedia/speech/inc/recognition.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __RECOGNITION_H__ +#define __RECOGNITION_H__ + +#include "vad.h" +#include "mfcc.h" + +#define VOICE_RECOGNITION_NN (120) +#define VOICE_RECOGNITION_OVLP (60) +#define VOICE_RECOGNITION_FFTFRAME (240) +#define VOICE_RECOGNITION_MODE_NUM_MAX (8) + +typedef struct{ + vad_t vad; + mfcc_t mfcc; + mfcc_vct_t mfcc_vct; + int tag; + short in_tmp[VOICE_RECOGNITION_NN * 2 + VOICE_RECOGNITION_OVLP]; + int dis_thr; + mfcc_vct_t *mode[VOICE_RECOGNITION_MODE_NUM_MAX]; + unsigned char mode_num; +} mfcc_extract_t; + +int speech_recognition_process(mfcc_extract_t *mfcc_exec, short *buf, unsigned int len); + +#endif // __RECOGNITION_H__ + diff --git a/services/multimedia/speech/inc/sensormic_denoise.h b/services/multimedia/speech/inc/sensormic_denoise.h new file mode 100644 index 0000000..185ce6d --- /dev/null +++ b/services/multimedia/speech/inc/sensormic_denoise.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SENSORMIC_DENOISE_H__ +#define __SENSORMIC_DENOISE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int32_t bypass; + int32_t blend_en; + // float left_gain; // MIC Leftå¢žç›Šè¡¥å¿ + // float right_gain; // MIC Rightå¢žç›Šè¡¥å¿ + int32_t delay_tapsM; // MIC L/R delay samples. 0: 适用于麦克è·ç¦»ä¸º<2cm; 1: 适用于麦克è·ç¦»ä¸º2cmå·¦å³; 2: 适用于麦克è·ç¦»ä¸º4cmå·¦å³ + int32_t delay_tapsS; + // int32_t delay_tapsC; + // float coefH[2][5]; // {{a0,a1,a2,a3,a4},{b0,b1,b2,b3,b4}} + // float coefL[2][5]; // {{a0,a1,a2,a3,a4},{b0,b1,b2,b3,b4}} + int32_t crossover_freq; + float *ff_fb_coeff; + int ff_fb_coeff_len; +} SensorMicDenoiseConfig; + +struct SensorMicDenoiseState_; + +typedef struct SensorMicDenoiseState_ SensorMicDenoiseState; + +//SensorMicDenoiseState *sensormic_denoise_create(int32_t sample_rate, int32_t frame_size, const SensorMicDenoiseConfig *cfg); +SensorMicDenoiseState *sensormic_denoise_create(int32_t sample_rate, int32_t frame_size, int32_t fft_size,int32_t ps_size,const SensorMicDenoiseConfig *cfg); + +int32_t sensormic_denoise_trace(SensorMicDenoiseState *st); + +int32_t sensormic_denoise_destroy(SensorMicDenoiseState *st); + +int32_t sensormic_denoise_set_config(SensorMicDenoiseState *st, const SensorMicDenoiseConfig *cfg); + +int32_t sensormic_denoise_process(SensorMicDenoiseState *st, short *pcm_buf, int32_t pcm_len, short *out_buf); + +bool sensormic_denoise_get_vad(SensorMicDenoiseState *st); + +void sensormic_denoise_set_anc_status(SensorMicDenoiseState *st, bool anc_enable); + +float sensormic_denoise_get_required_mips(SensorMicDenoiseState *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/single_mic_NNDenoise.h b/services/multimedia/speech/inc/single_mic_NNDenoise.h new file mode 100644 index 0000000..4093051 --- /dev/null +++ b/services/multimedia/speech/inc/single_mic_NNDenoise.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SINGLE_MIC_NN_DENOISE_H__ +#define __SINGLE_MIC_NN_DENOISE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +struct NNDenoiseState_; + +typedef struct NNDenoiseState_ NNDenoiseState; + + + +NNDenoiseState * single_mic_NN_denoise_create(int32_t sr, int32_t frame_size,int32_t post_coef); +void single_mic_NN_denoise_destroy(NNDenoiseState * st); +void single_mic_NN_denoise_run(NNDenoiseState * st,int16_t* input_buf); + + + + + + + + + + + + + + + + +// NNDenoiseState *speech_ns2_create(int32_t sample_rate, int32_t frame_size, const SpeechNs2Config *cfg); + +// int32_t speech_ns2_destroy(NNDenoiseState *st); + +// int32_t speech_ns2_set_config(SpeechNs2State *st, const SpeechNs2Config *cfg); + +// int32_t speech_ns2_process(SpeechNs2State *st, int16_t *pcm_buf, int32_t pcm_len); + +// int32_t speech_ns2_set_echo_state(SpeechNs2State *st, void *echo_state); + +// int32_t speech_ns2_set_echo_suppress(SpeechNs2State *st, int32_t echo_suppress); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/spectrum.h b/services/multimedia/speech/inc/spectrum.h new file mode 100644 index 0000000..4904622 --- /dev/null +++ b/services/multimedia/speech/inc/spectrum.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef SPECTRUM_H +#define SPECTRUM_H + +#include + +#define MAX_FREQ_NUM (10) + +typedef struct +{ + int freq_num; + int freq_list[MAX_FREQ_NUM]; +} SpectrumConfig; + +struct SpectrumState_; + +typedef struct SpectrumState_ SpectrumState; + +#ifdef __cplusplus +extern "C" { +#endif + +SpectrumState *spectrum_init(int sample_rate, int frame_size, const SpectrumConfig *config); + +void spectrum_destroy(SpectrumState *st); + +/* Update input buffer, must be called every block */ +void spectrum_analysis(SpectrumState *st, const float *x); + +/* Calculate spectrum, should be called when needed */ +void spectrum_process(SpectrumState *st, float *spectrum, int spectrum_num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/spectrum_fix.h b/services/multimedia/speech/inc/spectrum_fix.h new file mode 100644 index 0000000..46f16b4 --- /dev/null +++ b/services/multimedia/speech/inc/spectrum_fix.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef SPECTRUM_FIX_H +#define SPECTRUM_FIX_H + +#include + +#define MAX_FREQ_NUM (10) + +typedef struct +{ + int freq_num; + int freq_list[MAX_FREQ_NUM]; +} SpectrumFixConfig; + +struct SpectrumFixState_; + +typedef struct SpectrumFixState_ SpectrumFixState; + +#ifdef __cplusplus +extern "C" { +#endif + +SpectrumFixState *spectrum_fix_init(int sample_rate, int frame_size, const SpectrumFixConfig *config); + +void spectrum_fix_destroy(SpectrumFixState *st); + +/* Update input buffer, must be called every block */ +void spectrum_fix_analysis(SpectrumFixState *st, const int16_t *x); + +/* Calculate spectrum, should be called when needed */ +void spectrum_fix_process(SpectrumFixState *st, int16_t *spectrum, int spectrum_num); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/speech_2mic_ns2_denoise.h b/services/multimedia/speech/inc/speech_2mic_ns2_denoise.h new file mode 100644 index 0000000..6b4b538 --- /dev/null +++ b/services/multimedia/speech/inc/speech_2mic_ns2_denoise.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_2MIC_NS2_DENOISE_H__ +#define __SPEECH_2MIC_NS2_DENOISE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int32_t bypass; + float delay_taps; // MIC L/R delay samples. 0: 适用于麦克è·ç¦»ä¸º<2cm; 1: 适用于麦克è·ç¦»ä¸º2cmå·¦å³; 2: 适用于麦克è·ç¦»ä¸º4cmå·¦å³ + int32_t freq_smooth_enable; // 1: 频域滤波打开; 0: 频域滤波关闭; 默认打开 + int32_t wnr_enable; // wind noise reduction enable +} Speech2MicNs2Config; + +struct Speech2MicNs2State_; + +typedef struct Speech2MicNs2State_ Speech2MicNs2State; + +#define CONSTRUCT_FUNC_NAME_A(p, c, m) p ## _ ## c ## _ ## m +#define CONSTRUCT_FUNC_NAME(p, c, m) CONSTRUCT_FUNC_NAME_A(p, c, m) + +#ifndef SPEECH_2MIC_NS2_DENOISE_IMPL +#define SPEECH_2MIC_NS2_DENOISE_IMPL float +#endif + +#define speech_2mic_ns2_create CONSTRUCT_FUNC_NAME(speech_2mic_ns2, SPEECH_2MIC_NS2_DENOISE_IMPL, create) +#define speech_2mic_ns2_destroy CONSTRUCT_FUNC_NAME(speech_2mic_ns2, SPEECH_2MIC_NS2_DENOISE_IMPL, destroy) +#define speech_2mic_ns2_set_config CONSTRUCT_FUNC_NAME(speech_2mic_ns2, SPEECH_2MIC_NS2_DENOISE_IMPL, set_config) +#define speech_2mic_ns2_process CONSTRUCT_FUNC_NAME(speech_2mic_ns2, SPEECH_2MIC_NS2_DENOISE_IMPL, process) +#define speech_2mic_ns2_get_delay CONSTRUCT_FUNC_NAME(speech_2mic_ns2, SPEECH_2MIC_NS2_DENOISE_IMPL, get_delay) +#define speech_2mic_ns2_get_required_mips CONSTRUCT_FUNC_NAME(speech_2mic_ns2, SPEECH_2MIC_NS2_DENOISE_IMPL, get_required_mips) + +Speech2MicNs2State *speech_2mic_ns2_create(int32_t sample_rate, int32_t frame_size, const Speech2MicNs2Config *cfg); + +int32_t speech_2mic_ns2_destroy(Speech2MicNs2State *st); + +int32_t speech_2mic_ns2_set_config(Speech2MicNs2State *st, const Speech2MicNs2Config *cfg); + +int32_t speech_2mic_ns2_process(Speech2MicNs2State *st, short *pcm_buf, int32_t pcm_len, short *out_buf); + +int32_t speech_2mic_ns2_get_delay(Speech2MicNs2State *st); + +float speech_2mic_ns2_get_required_mips(Speech2MicNs2State *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_3mic_ns.h b/services/multimedia/speech/inc/speech_3mic_ns.h new file mode 100644 index 0000000..6907ab6 --- /dev/null +++ b/services/multimedia/speech/inc/speech_3mic_ns.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_3MIC_NS_H__ +#define __SPEECH_3MIC_NS_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int32_t bypass; + int32_t blend_en; + int32_t authen_en; + float delay_tapsM; // MIC L/R delay samples. 0: 适用于麦克è·ç¦»ä¸º<2cm; 1: 适用于麦克è·ç¦»ä¸º2cmå·¦å³; 2: 适用于麦克è·ç¦»ä¸º4cmå·¦å³ + int32_t delay_tapsS; + float denoise_dB; + // float coefH[2][5]; // {{a0,a1,a2,a3,a4},{b0,b1,b2,b3,b4}} + // float coefL[2][5]; // {{a0,a1,a2,a3,a4},{b0,b1,b2,b3,b4}} + int32_t crossover_freq; + int32_t freq_smooth_enable; // 1: 频域滤波打开; 0: 频域滤波关闭; 默认打开 + int32_t wnr_enable; // wind noise reduction enable +} Speech3MicNsConfig; + +struct Speech3MicNsState_; + +typedef struct Speech3MicNsState_ Speech3MicNsState; + +Speech3MicNsState *speech_3mic_ns_create(int32_t sample_rate, int32_t frame_size, const Speech3MicNsConfig *cfg); + +int32_t speech_3mic_ns_destroy(Speech3MicNsState *st); + +int32_t speech_3mic_ns_set_config(Speech3MicNsState *st, const Speech3MicNsConfig *cfg); + +int32_t speech_3mic_ns_process(Speech3MicNsState *st, short *pcm_buf, int32_t pcm_len, short *out_buf); + +float speech_3mic_get_required_mips(Speech3MicNsState *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_aec.h b/services/multimedia/speech/inc/speech_aec.h new file mode 100644 index 0000000..9fea405 --- /dev/null +++ b/services/multimedia/speech/inc/speech_aec.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_AEC_H__ +#define __SPEECH_AEC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEECH_AEC_GET_LIB_ST (0) + +/* +60 +16383 +4 +*/ +typedef struct { + int32_t bypass; + int32_t delay; + int32_t leak_estimate; + int32_t leak_estimate_shift; +} SpeechAecConfig; + +struct SpeechAecState_; + +typedef struct SpeechAecState_ SpeechAecState; + +// Creat a instance from speech_aec module/class +// Common value include: sample rate, frame size and so on. +SpeechAecState *speech_aec_create(int32_t sample_rate, int32_t frame_size, const SpeechAecConfig *cfg); + +// Destory a speech aec instance +int32_t speech_aec_destroy(SpeechAecState *st); + +// Just use modify instance configure +int32_t speech_aec_set_config(SpeechAecState *st, const SpeechAecConfig *cfg); + +// Get/set some value or enable/disable some function +int32_t speech_aec_ctl(SpeechAecState *st, int32_t ctl, void *ptr); + +// Process speech stream +int32_t speech_aec_process(SpeechAecState *st, int16_t *pcm_in, int16_t *pcm_ref, int32_t pcm_len, int16_t *pcm_out); + +// Debug speech_aec instance +int32_t speech_aec_dump(SpeechAecState *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_aec2.h b/services/multimedia/speech/inc/speech_aec2.h new file mode 100644 index 0000000..d5b0b86 --- /dev/null +++ b/services/multimedia/speech/inc/speech_aec2.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_AEC2_H__ +#define __SPEECH_AEC2_H__ + +#include "plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + int32_t bypass; + int32_t enEAecEnable; + int32_t enHpfEnable; + int32_t enAfEnable; + int32_t enNsEnable; + int32_t enNlpEnable; + int32_t enCngEnable; + int32_t shwDelayLength; + float shwNlpBandSortIdx; + float shwNlpBandSortIdxLow; + float shwNlpTargetSupp; + float shwNlpMinOvrd; +} SpeechAec2Config; + +struct SpeechAec2State_; + +typedef struct SpeechAec2State_ SpeechAec2State; + +SpeechAec2State *speech_aec2_create(int32_t sample_rate, int32_t frame_size, const SpeechAec2Config *cfg); + +int32_t speech_aec2_destroy(SpeechAec2State *inst); + +int32_t speech_aec2_set_config(SpeechAec2State *st, const SpeechAec2Config *cfg); + +int32_t speech_aec2_process(SpeechAec2State *inst, int16_t *pcm_in, int16_t *pcm_ref, int32_t pcm_len); + + +#ifdef __cplusplus +} +#endif + +#endif//__BT_SCO_CHAIN_WEBRTC_H__ \ No newline at end of file diff --git a/services/multimedia/speech/inc/speech_cfg.h b/services/multimedia/speech/inc/speech_cfg.h new file mode 100644 index 0000000..f4b4c19 --- /dev/null +++ b/services/multimedia/speech/inc/speech_cfg.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_CFG_H__ +#define __SPEECH_CFG_H__ + +// Speech process module +#include "speech_dc_filter.h" +#include "speech_iir_calibration.h" +#include "speech_fir_calibration.h" +#include "speech_aec.h" +#include "speech_aec2.h" +#include "echo_canceller.h" +#include "dual_mic_denoise.h" +#include "speech_2mic_ns2_denoise.h" +#include "sensormic_denoise.h" +#include "leftright_denoise.h" +#include "speech_3mic_ns.h" +#include "triple_mic_denoise3.h" +#include "far_field_speech_enhancement.h" +#include "speech_ns.h" +#include "lc_mmse_ns.h" +#include "lc_mmse_ns_float.h" +#include "ns3.h" +#include "wnr.h" +#include "VoiceActivityDetection.h" +#include "speech_noise_gate.h" +#include "compexp.h" +#include "agc.h" +#include "speech_eq.h" +#include "speech_gain.h" +#include "speech_ff_2mic_ns2.h" +#include "SubBandBasedAEC.h" +// Tool module +#include "speech_utils.h" +#include "speech_ssat.h" +#include "speech_memory.h" +#include "iir_resample.h" +#include "frame_resize.h" +#include "ae_math.h" +// Other module +#include "wind_detection_2mic.h" + + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/speech_config.h b/services/multimedia/speech/inc/speech_config.h new file mode 100644 index 0000000..a769d03 --- /dev/null +++ b/services/multimedia/speech/inc/speech_config.h @@ -0,0 +1,16 @@ +#ifndef SPEECH_CONFIG_H +#define SPEECH_CONFIG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int16_t speech_data_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_dc_filter.h b/services/multimedia/speech/inc/speech_dc_filter.h new file mode 100644 index 0000000..8d8ec34 --- /dev/null +++ b/services/multimedia/speech/inc/speech_dc_filter.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_DC_FILTER_H__ +#define __SPEECH_DC_FILTER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEECH_DC_FILTER_GAIN_Q (10) + +#define SPEECH_DC_FILTER_SET_CHANNEL_NUM (0) +#define SPEECH_DC_FILTER_SET_DATA_SEPARATION (1) + +typedef struct { + int32_t bypass; + float gain; +} SpeechDcFilterConfig; + +struct SpeechDcFilterState_; + +typedef struct SpeechDcFilterState_ SpeechDcFilterState; + +// Creat a instance from speech_dc_filter module/class +// Common value include: sample rate, frame size and so on. +SpeechDcFilterState *speech_dc_filter_create(int32_t sample_rate, const SpeechDcFilterConfig *cfg); + +// Destory a speech dc_filter instance +int32_t speech_dc_filter_destroy(SpeechDcFilterState *st); + +// Just use modify instance configure +int32_t speech_dc_filter_set_config(SpeechDcFilterState *st, const SpeechDcFilterConfig *cfg); + +// Get/set some value or enable/disable some function +int32_t speech_dc_filter_ctl(SpeechDcFilterState *st, int32_t ctl, void *ptr); + +// Process speech stream +int32_t speech_dc_filter_process(SpeechDcFilterState *st, int16_t *pcm_buf, int32_t pcm_len); + +int32_t speech_dc_filter_process_int24(SpeechDcFilterState *st, int32_t *pcm_buf, int32_t pcm_len); + +// Debug speech_dc_filter instance +int32_t speech_dc_filter_dump(SpeechDcFilterState *st); + +float speech_dc_filter_get_required_mips(SpeechDcFilterState *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_eq.h b/services/multimedia/speech/inc/speech_eq.h new file mode 100644 index 0000000..df87562 --- /dev/null +++ b/services/multimedia/speech/inc/speech_eq.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef SPEECH_EQ_H +#define SPEECH_EQ_H + +#include "iirfilt.h" + +// use more frame_size * sizeof(float) ram +#ifdef __arm__ +#define EQ_USE_CMSIS_IIR +#endif + +#define MAX_VQE_EQ_BAND 6 + +typedef struct +{ + enum IIR_BIQUARD_TYPE type; + union + { + /* Raw config, used when type is IIR_BIQUARD_RAW */ + struct + { + float a1; float a2; float b0; float b1; float b2; + } raw; + /* Generate coeffs using user defined params, used in other type */ + struct + { + float f0; float gain; float q; + } design; + }; +} BiquardParam; + +typedef struct +{ + int32_t bypass; + float gain; + int32_t num; + BiquardParam params[MAX_VQE_EQ_BAND]; +} EqConfig; + +typedef struct EqState_ EqState; + +#ifdef __cplusplus +extern "C" { +#endif + +EqState *eq_init(int32_t sample_rate, int32_t frame_size, const EqConfig *cfg); + +int32_t eq_destroy(EqState *st); + +int32_t eq_set_config(EqState *st, const EqConfig *cfg); + +int32_t eq_process(EqState *st, int16_t *pcm_buf, int32_t pcm_len); + +int32_t eq_process_int24(EqState *st, int32_t *pcm_buf, int32_t pcm_len); + +int32_t eq_process_float(EqState *st, float *pcm_buf, int32_t pcm_len); + +int32_t eq_process2(EqState *st, int16_t *pcm_buf, int32_t pcm_len, int32_t stride); + +int32_t eq_process2_int24(EqState *st, int32_t *pcm_buf, int32_t pcm_len, int32_t stride); + +int32_t eq_process2_float(EqState *st, float *pcm_buf, int32_t pcm_len, int32_t stride); + +float eq_get_required_mips(EqState *st); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/speech_ff_2mic_ns2.h b/services/multimedia/speech/inc/speech_ff_2mic_ns2.h new file mode 100644 index 0000000..af42ea1 --- /dev/null +++ b/services/multimedia/speech/inc/speech_ff_2mic_ns2.h @@ -0,0 +1,19 @@ +#ifndef __SPEECH_FF_2MIC_NS2_H__ +#define __SPEECH_FF_2MIC_NS2_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct SpeechFF2MicNs2State_; +typedef struct SpeechFF2MicNs2State_ SpeechFF2MicNs2State; +SpeechFF2MicNs2State *speech_ff_2mic_ns2_create(int sample_rate, int frame_size); +int32_t speech_ff_2mic_ns2_destroy(SpeechFF2MicNs2State *st); +void speech_ff_2mic_ns2_process(SpeechFF2MicNs2State *st, short *inF, short *inR); +int32_t speech_2mic_ns6_process(SpeechFF2MicNs2State *st, short *pcm_buf, int32_t pcm_len, short *out_buf); +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/speech_ff_3mic_ns1.h b/services/multimedia/speech/inc/speech_ff_3mic_ns1.h new file mode 100644 index 0000000..97220a0 --- /dev/null +++ b/services/multimedia/speech/inc/speech_ff_3mic_ns1.h @@ -0,0 +1,18 @@ +#ifndef __SPEECH_FF_3MIC_NS1_H__ +#define __SPEECH_FF_3MIC_NS1_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct SpeechFF3MicNs1State_; +typedef struct SpeechFF3MicNs1State_ SpeechFF3MicNs1State; +SpeechFF3MicNs1State *speech_ff_3mic_ns1_create(int sample_rate, int frame_size); +int32_t speech_ff_3mic_ns1_destroy(SpeechFF3MicNs1State *st); +int32_t speech_3mic_ns1_process(SpeechFF3MicNs1State *st, short *pcm_buf, short *ref_buf, int32_t pcm_len, short *out_buf); +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/speech_fir_calibration.h b/services/multimedia/speech/inc/speech_fir_calibration.h new file mode 100644 index 0000000..d343684 --- /dev/null +++ b/services/multimedia/speech/inc/speech_fir_calibration.h @@ -0,0 +1,54 @@ +#ifndef SPEECH_FIR_CALIBRATION_H +#define SPEECH_FIR_CALIBRATION_H + +#include "fftfilt.h" + +// i.e. only support 4 channels +#define SPEECH_FIR_CALIB_MAX_NUM (3) + +typedef struct +{ + float *filter; + int filter_length; +} CalibChannelConfig; + +typedef struct +{ + int bypass; + int mic_num; + float delay; // fraction delay for main mic + CalibChannelConfig calib[SPEECH_FIR_CALIB_MAX_NUM]; +} SpeechFirCalibConfig; + +typedef struct SpeechFirCalibState_ SpeechFirCalibState; + +#define CONSTRUCT_FUNC_NAME_A(p, c, m) p ## _ ## c ## _ ## m +#define CONSTRUCT_FUNC_NAME(p, c, m) CONSTRUCT_FUNC_NAME_A(p, c, m) + +#ifndef FIR_CALIB_IMPL +#if defined(VQE_SIMULATE) +#define FIR_CALIB_IMPL fir +#else +#define FIR_CALIB_IMPL hwfir +#endif +#endif + +#define speech_fir_calib_init CONSTRUCT_FUNC_NAME(speech, FIR_CALIB_IMPL, calib_init) +#define speech_fir_calib_destroy CONSTRUCT_FUNC_NAME(speech, FIR_CALIB_IMPL, calib_destroy) +#define speech_fir_calib_process CONSTRUCT_FUNC_NAME(speech, FIR_CALIB_IMPL, calib_process) + +#ifdef __cplusplus +extern "C" { +#endif + +SpeechFirCalibState *speech_fir_calib_init(int32_t sample_rate, int32_t frame_size, const SpeechFirCalibConfig *config); + +void speech_fir_calib_destroy(SpeechFirCalibState *st); + +void speech_fir_calib_process(SpeechFirCalibState *st, int16_t *buf, int32_t frame_size); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/speech_gain.h b/services/multimedia/speech/inc/speech_gain.h new file mode 100644 index 0000000..b5db667 --- /dev/null +++ b/services/multimedia/speech/inc/speech_gain.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_GAIN_H__ +#define __SPEECH_GAIN_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEECH_GAIN_SET_AAA (0) +#define SPEECH_GAIN_GET_AAA (1) + +typedef struct { + int32_t bypass; + float gain_dB; +} SpeechGainConfig; + +struct SpeechGainState_; + +typedef struct SpeechGainState_ SpeechGainState; + +// Creat a instance from speech_gain module/class +// Common value include: sample rate, frame size and so on. +SpeechGainState *speech_gain_create(int32_t sample_rate, int32_t frame_size, const SpeechGainConfig *cfg); + +// Destory a speech gain instance +int32_t speech_gain_destroy(SpeechGainState *st); + +// Just use modify instance configure +int32_t speech_gain_set_config(SpeechGainState *st, const SpeechGainConfig *cfg); + +// Get/set some value or enable/disable some function +// int32_t speech_gain_ctl(SpeechGainState *st, int32_t ctl, void *ptr); + +// Process speech stream +int32_t speech_gain_process(SpeechGainState *st, int16_t *pcm_buf, int32_t pcm_len); + +// Debug speech_gain instance +int32_t speech_gain_dump(SpeechGainState *st); + +float speech_gain_get_required_mips(SpeechGainState *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_iir.h b/services/multimedia/speech/inc/speech_iir.h new file mode 100644 index 0000000..94fd6a5 --- /dev/null +++ b/services/multimedia/speech/inc/speech_iir.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_IIR_H__ +#define __SPEECH_IIR_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEECH_IIR_COEFF_LEN (5) + +typedef float SPEECH_RX_EQ_PCOEFFS_T[SPEECH_IIR_COEFF_LEN]; + +typedef struct { + int32_t numStages; + + // { + // {b10, b11, b12, a11, a12}, + // {b20, b21, b22, a21, a22}, + // ... + // } + // const float (*pCoeffs)[SPEECH_IIR_COEFF_LEN]; + SPEECH_RX_EQ_PCOEFFS_T *pCoeffs; +} SPEECH_IIR_CFG_T; + +typedef void SPEECH_IIR_STATE_T; + +// Initial speech_iir module/class +int speech_iir_init(void); + +// Deinitial speech_iir module/calss +int speech_iir_deinit(void); + +// Creat a instance from speech_iir module/class +// Common value include: sample rate, frame size and so on. +SPEECH_IIR_STATE_T *speech_iir_create(const SPEECH_IIR_CFG_T *cfg); + +// Destory a speech iir instance +int speech_iir_destroy(SPEECH_IIR_STATE_T *inst); + +// Just use modify instance configure +int speech_iir_set_config(SPEECH_IIR_STATE_T *inst, const SPEECH_IIR_CFG_T *cfg); + +// Process speech stream +int speech_iir_process(SPEECH_IIR_STATE_T *inst, int16_t *pcm_buf, int32_t pcm_len); + +// Debug speech_iir instance +int speech_iir_dump(SPEECH_IIR_STATE_T *inst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_iir_calibration.h b/services/multimedia/speech/inc/speech_iir_calibration.h new file mode 100644 index 0000000..24ab5cd --- /dev/null +++ b/services/multimedia/speech/inc/speech_iir_calibration.h @@ -0,0 +1,24 @@ +#ifndef SPEECH_IIR_CALIBRATION_H +#define SPEECH_IIR_CALIBRATION_H + +#include "speech_eq.h" + +// i.e. only support 4 channels +#define SPEECH_IIR_CALIB_MAX_NUM (3) + +typedef struct +{ + int bypass; + int mic_num; + EqConfig calib[SPEECH_IIR_CALIB_MAX_NUM]; +} SpeechIirCalibConfig; + +typedef struct SpeechIirCalibState_ SpeechIirCalibState; + +SpeechIirCalibState *speech_iir_calib_init(int32_t sample_rate, int32_t frame_size, const SpeechIirCalibConfig *config); + +void speech_iir_calib_destroy(SpeechIirCalibState *st); + +void speech_iir_calib_process(SpeechIirCalibState *st, int16_t *buf, int32_t frame_size); + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/speech_memory.h b/services/multimedia/speech/inc/speech_memory.h new file mode 100644 index 0000000..133dee9 --- /dev/null +++ b/services/multimedia/speech/inc/speech_memory.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_MEMORY_H__ +#define __SPEECH_MEMORY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef VQE_SIMULATE +#include "med_memory.h" + +#define speech_heap_init(a, b) med_heap_init(a, b) +#define speech_heap_add_block(a, b) med_heap_add_block(a, b) +#define speech_malloc(a) med_malloc(a) +#define speech_realloc(a, b) med_realloc(a, b) +#define speech_calloc(a, b) med_calloc(a, b) +#define speech_free(a) med_free(a) +#define speech_memory_info(a, b, c) med_memory_info(a, b, c) + +#define speech_heap_set_cp(a) med_heap_set_cp(a) +#else +#include +#include + +void speech_heap_init(void *begin_addr, size_t size); +void *speech_malloc(size_t size); +void speech_free(void *p); +void *speech_calloc(size_t nmemb, size_t size); +void *speech_realloc(void *ptr, size_t size); +void speech_memory_info(size_t *total, + size_t *used, + size_t *max_used); + +#define speech_heap_set_cp(a) +#endif + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/speech_mics_calibration.h b/services/multimedia/speech/inc/speech_mics_calibration.h new file mode 100644 index 0000000..2ae3faf --- /dev/null +++ b/services/multimedia/speech/inc/speech_mics_calibration.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_MICS_CALIBRATION_H__ +#define __SPEECH_MICS_CALIBRATION_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// #define SPEECH_MICS_CALIBRATION_SET_MODE (0) +// #define SPEECH_MICS_CALIBRATION_GET_MODE (1) + +#define SPEECH_MICS_CALIBRATION_GET_COEF_LEN (2) +#define SPEECH_MICS_CALIBRATION_GET_COEF (3) +#define SPEECH_MICS_CALIBRATION_SET_COEF (4) + +#define SPEECH_MICS_CALIBRATION_GET_PS_MSE (5) + +#define SPEECH_MICS_CALIBRATION_GET_MICOUT_LEN (10) +#define SPEECH_MICS_CALIBRATION_GET_MIC1OUT (11) +#define SPEECH_MICS_CALIBRATION_GET_MIC2OUT (12) +#define SPEECH_MICS_CALIBRATION_GET_MIC3OUT (13) +#define SPEECH_MICS_CALIBRATION_GET_MIC4OUT (14) +#define SPEECH_MICS_CALIBRATION_GET_MIC5OUT (15) +#define SPEECH_MICS_CALIBRATION_GET_MIC6OUT (16) + +// mode +#define SPEECH_MICS_CALIBRATION_MODE_CALIBRATION (0) +#define SPEECH_MICS_CALIBRATION_MODE_VERIFY (1) +#define SPEECH_MICS_CALIBRATION_MODE_NULL (2) + +// Return status +#define SPEECH_MICS_CALIBRATION_RET_READY (0) +#define SPEECH_MICS_CALIBRATION_RET_BUSY (1) +#define SPEECH_MICS_CALIBRATION_RET_OK (2) + + +typedef struct { + int32_t enable; + // int32_t mode; + int32_t setup_time; + int32_t calibration_time; + int32_t verify_time; +} SPEECH_MICS_CALIBRATION_CFG_T; + +typedef void *SPEECH_MICS_CALIBRATION_STATE_T; + +// Creat a instance from speech_mics_calibration module/class +// Common value include: sample rate, frame size and so on. +SPEECH_MICS_CALIBRATION_STATE_T *speech_mics_calibration_create(SPEECH_MICS_CALIBRATION_CFG_T *cfg, int frame_size, int sample_rate); + +// Destory a speech mics_calibration instance +int speech_mics_calibration_destroy(SPEECH_MICS_CALIBRATION_STATE_T *inst); + +// Just use modify instance configure +int speech_mics_calibration_set_config(SPEECH_MICS_CALIBRATION_STATE_T *inst, SPEECH_MICS_CALIBRATION_CFG_T *cfg); + +// Enable some function +int speech_mics_calibration_ctl(SPEECH_MICS_CALIBRATION_STATE_T *inst, int ctl, void *ptr); + +// Process speech stream +int speech_mics_calibration_process(SPEECH_MICS_CALIBRATION_STATE_T *inst, int16_t *pcm_mic1, int16_t *pcm_mic2, int32_t pcm_len); + +// Test: verify calibration effect +int speech_mics_calibration_test_verify(SPEECH_MICS_CALIBRATION_STATE_T *inst, int16_t *pcm_mic1, int16_t *pcm_mic2, int32_t pcm_len); + +// Debug speech_mics_calibration instance +int speech_mics_calibration_dump(SPEECH_MICS_CALIBRATION_STATE_T *inst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_noise_gate.h b/services/multimedia/speech/inc/speech_noise_gate.h new file mode 100644 index 0000000..3c6174d --- /dev/null +++ b/services/multimedia/speech/inc/speech_noise_gate.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _SPEECH_NOISE_GATE_H_ +#define _SPEECH_NOISE_GATE_H_ + +#include + +typedef struct { + int32_t bypass; + int32_t data_threshold; + int32_t data_shift; + float factor_up; + float factor_down; +} NoisegateConfig; + +struct NoisegateState_; + +typedef struct NoisegateState_ NoisegateState; + +#ifdef __cplusplus +extern "C" { +#endif + +NoisegateState* speech_noise_gate_create(int32_t sample_rate, int32_t frame_size, const NoisegateConfig *cfg); +int32_t speech_noise_gate_destroy(NoisegateState *st); +int32_t speech_noise_gate_set_config(NoisegateState *st, const NoisegateConfig *cfg); + +int32_t speech_noise_gate_process(NoisegateState *st, int16_t *pcm_buf, int32_t pcm_len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_ns.h b/services/multimedia/speech/inc/speech_ns.h new file mode 100644 index 0000000..5c1abf4 --- /dev/null +++ b/services/multimedia/speech/inc/speech_ns.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_NS_H__ +#define __SPEECH_NS_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEECH_NS_SET_AEC_STATE (0) +#define SPEECH_NS_SET_AEC_SUPPRESS (1) + +typedef struct { + int32_t bypass; + float denoise_dB; +} SpeechNsConfig; + +struct SpeechNsState_; + +typedef struct SpeechNsState_ SpeechNsState; + +// Creat a instance from speech_ns module/class +// Common value include: sample rate, frame size and so on. +SpeechNsState *speech_ns_create(int32_t sample_rate, int32_t frame_size, const SpeechNsConfig *cfg); + +// Destory a speech ns instance +int32_t speech_ns_destroy(SpeechNsState *st); + +// Just use modify instance configure +int32_t speech_ns_set_config(SpeechNsState *st, const SpeechNsConfig *cfg); + +// Get/set some value or enable/disable some function +int32_t speech_ns_ctl(SpeechNsState *st, int32_t ctl, void *ptr); + +// Process speech stream +int32_t speech_ns_process(SpeechNsState *st, int16_t *pcm_buf, int32_t pcm_len); + +// Debug speech_ns instance +int32_t speech_ns_dump(SpeechNsState *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_peak_detector.h b/services/multimedia/speech/inc/speech_peak_detector.h new file mode 100644 index 0000000..e23010b --- /dev/null +++ b/services/multimedia/speech/inc/speech_peak_detector.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_PEAK_DETECTOR_H__ +#define __SPEECH_PEAK_DETECTOR_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// return_type +#define SPEECH_PEAK_DETECTOR_RETURN_MEAN (0) +#define SPEECH_PEAK_DETECTOR_RETURN_ARRAY (1) + +typedef struct { + int return_type; + float factor_up; + float factor_down; +} SPEECH_PEAK_DETECTOR_CFG_T; + +typedef void *SPEECH_PEAK_DETECTOR_STATE_T; + +// Creat a instance from speech_peak_detector module/class +// Common value include: sample rate, frame size and so on. +SPEECH_PEAK_DETECTOR_STATE_T *speech_peak_detector_create(SPEECH_PEAK_DETECTOR_CFG_T *cfg, int frame_size, int sample_rate); + +// Destory a speech peak_detector instance +int speech_peak_detector_destroy(SPEECH_PEAK_DETECTOR_STATE_T *inst); + +// Just use modify instance configure +int speech_peak_detector_set_config(SPEECH_PEAK_DETECTOR_STATE_T *inst, SPEECH_PEAK_DETECTOR_CFG_T *cfg); + +// Enable some function +int speech_peak_detector_ctl(SPEECH_PEAK_DETECTOR_STATE_T *inst, int ctl, void *ptr); + +// Process speech stream +int speech_peak_detector_process(SPEECH_PEAK_DETECTOR_STATE_T *inst, int16_t *pcm_buf, int32_t pcm_len, float *out); + +// Debug speech_peak_detector instance +int speech_peak_detector_dump(SPEECH_PEAK_DETECTOR_STATE_T *inst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/speech_ssat.h b/services/multimedia/speech/inc/speech_ssat.h new file mode 100644 index 0000000..1cdfafc --- /dev/null +++ b/services/multimedia/speech/inc/speech_ssat.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_SSAT_H__ +#define __SPEECH_SSAT_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) && defined(__arm__) +#include "cmsis.h" +static inline int16_t speech_ssat_int16(int32_t in) +{ + int16_t out; + + out = __SSAT(in,16); + + return out; +} + +static inline int32_t speech_ssat_int24(int32_t in) +{ + int32_t out; + + out = __SSAT(in, 24); + + return out; +} +#else +static inline int16_t speech_ssat_int16(int32_t in) +{ + int16_t out; + + if (in>32767) + { + in = 32767; + } + else if (in<-32768) + { + in = -32768; + } + out = (int16_t)in; + return out; +} + +static inline int32_t speech_ssat_int24(int32_t in) +{ + int32_t out; + + if (in > 0x7fffff) { + in = 0x7fffff; + } else if (in < -0x800000) { + in = -0x800000; + } + out = (int32_t)in; + return out; +} +#endif + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +template +static inline DataType speech_ssat(int in) +{ + if (sizeof(DataType) == sizeof(int16_t)) + return speech_ssat_int16(in); + else + return speech_ssat_int24(in); +} +#endif + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/speech_utils.h b/services/multimedia/speech/inc/speech_utils.h new file mode 100644 index 0000000..91fe3f8 --- /dev/null +++ b/services/multimedia/speech/inc/speech_utils.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_UTILS_H__ +#define __SPEECH_UTILS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +// len = fs / 1000 * ms +#if defined(LOW_DELAY_SCO) +// len = fs / 1000 * ms +#define SPEECH_FRAME_MS_TO_LEN(fs, ms) (( (fs) / 1000 * (ms) )/2) +#else +// len = fs / 1000 * ms +#define SPEECH_FRAME_MS_TO_LEN(fs, ms) ( (fs) / 1000 * (ms) ) +#endif +#define SPEECH_FRAME_LEN_TO_MS(fs, len) ( (len) / ( (fs) / 1000) ) + + +inline void speech_set_int16(short *dst, short v, int len) +{ + for (int i=0; i +#include "speech_config.h" + +typedef struct +{ + int32_t bypass; + int32_t endfire_enable; + int32_t broadside_enable; + + // endfire beamforming config + float delay_taps; + int32_t freq_smooth_enable; + int32_t wnr_enable; + + // broadsize beamforming config +} TripleMicDenoise3Config; + +struct TripleMicDenoise3State_; + +typedef struct TripleMicDenoise3State_ TripleMicDenoise3State; + +TripleMicDenoise3State *triple_mic_denoise3_init(int32_t sample_rate, int32_t frame_size, const TripleMicDenoise3Config *cfg); + +void triple_mic_denoise3_destroy(TripleMicDenoise3State *st); + +// accept 3 channel interleaved pcm stream, ch0 is main mic, ch1 is endfire reference mic, ch2 is broadside reference mic +int32_t triple_mic_denoise3_process(TripleMicDenoise3State *st, speech_data_t *pcm_buf, int32_t pcm_len, speech_data_t *out_buf); + +float triple_mic_denoise3_get_required_mips(TripleMicDenoise3State *st); + +#endif \ No newline at end of file diff --git a/services/multimedia/speech/inc/wind_detection_2mic.h b/services/multimedia/speech/inc/wind_detection_2mic.h new file mode 100644 index 0000000..f272bc3 --- /dev/null +++ b/services/multimedia/speech/inc/wind_detection_2mic.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __WIND_DETECTION_H__ +#define __WIND_DETECTION_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int32_t bypass; + float power_thd; +} WindDetection2MicConfig; + +struct WindDetection2MicState_; + +typedef struct WindDetection2MicState_ WindDetection2MicState; + + +WindDetection2MicState *WindDetection2Mic_create(int sample_rate, int sample_bits, int frame_size, const WindDetection2MicConfig *cfg); + +void WindDetection2Mic_destroy(WindDetection2MicState *st); + +int32_t WindDetection2Mic_set_config(WindDetection2MicState *st, const WindDetection2MicConfig *cfg); + +uint8_t wind_state_detect(uint8_t pre_wind_st, float wind_indictor, float *windindicator_cache, float *windthd, uint8_t *cur_wind_st); + +float WindDetection2Mic_process_16bit(WindDetection2MicState *st, short *inF, short *inR, uint32_t frame_len, float *wind_power); + +float WindDetection2Mic_process_24bit(WindDetection2MicState *st, int *inF, int *inR, uint32_t frame_len, float *wind_power); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/multimedia/speech/inc/wnr.h b/services/multimedia/speech/inc/wnr.h new file mode 100644 index 0000000..4c9e0f3 --- /dev/null +++ b/services/multimedia/speech/inc/wnr.h @@ -0,0 +1,33 @@ +#ifndef __WNR_H__ +#define __WNR_H__ + +#include "iirfilt.h" + +typedef struct +{ + int32_t bypass; + int lpf_cutoff; + int hpf_cutoff; + float power_ratio_thr; // ratio of the power spectrum of the lower frequencies over the total power spectrum for all frequencies + float power_thr; // normalized power of the low frequencies +} WnrConfig; + +struct WnrState_; + +typedef struct WnrState_ WnrState; + +#ifdef __cplusplus +extern "C" { +#endif + +WnrState* wnr_create(int32_t sample_rate, int32_t frame_size, const WnrConfig *config); + +void wnr_destroy(WnrState *st); + +void wnr_process(WnrState *st, int16_t *buf, int frameSize); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/norflash_api/Makefile b/services/norflash_api/Makefile new file mode 100644 index 0000000..5f25758 --- /dev/null +++ b/services/norflash_api/Makefile @@ -0,0 +1,47 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y += -Iplatform/hal \ + -Iutils/heap \ + -Iplatform/drivers/ana + +ifeq ($(FLASH_SUSPEND),1) +CFLAGS_norflash_api.o += -DFLASH_SUSPEND +endif + +ifeq ($(FLASH_REMAP),1) +CFLAGS_norflash_api.o += -DFLASH_REMAP +endif + +ifneq ($(OTA_CODE_OFFSET),) +CFLAGS_norflash_api.o += -DOTA_CODE_OFFSET=$(OTA_CODE_OFFSET) +endif + +ifneq ($(OTA_REMAP_OFFSET),) +CFLAGS_norflash_api.o += -DOTA_REMAP_OFFSET=$(OTA_REMAP_OFFSET) +endif + +ifeq ($(PUYA_FLASH_ERASE_PAGE_ENABLE),1) +CFLAGS_norflash_api.o += -DPUYA_FLASH_ERASE_PAGE_ENABLE +endif + +ifeq ($(USB_AUDIO_APP),1) +ifneq (,$(filter $(BTUSB_AUDIO_MODE) $(BT_USB_AUDIO_DUAL_MODE), 1)) +export FLASH_API_SIMPLE ?= 1 +endif +endif + +ifeq ($(FLASH_API_SIMPLE),1) +CFLAGS_norflash_api.o += -DFLASH_API_SIMPLE +else +ifeq ($(FLASH_API_HIGHPERFORMANCE),1) +CFLAGS_norflash_api.o += -DFLASH_API_HIGHPERFORMANCE +else +CFLAGS_norflash_api.o += -DFLASH_API_NORMAL +endif +endif + diff --git a/services/norflash_api/norflash_api.cpp b/services/norflash_api/norflash_api.cpp new file mode 100644 index 0000000..1dd28f6 --- /dev/null +++ b/services/norflash_api/norflash_api.cpp @@ -0,0 +1,1665 @@ +#include "stdio.h" +#include "string.h" +#include "cmsis.h" +#ifdef RTOS +#include "cmsis_os.h" +#else +#include "hal_timer.h" +#endif +#include "pmu.h" +#include "hal_sleep.h" +#include "hal_trace.h" +#include "hal_norflash.h" +#include "norflash_api.h" + +#if 0 +#define NORFLASH_API_TRACE(str,...) TRACE(str, ##__VA_ARGS__) +#else +#define NORFLASH_API_TRACE(str,...) +#endif + +#define API_IS_ALIGN(v,size) (((v/size)*size) == v) + +static NORFLASH_API_INFO norflash_api_info = {false,}; +static OPERA_INFO_LIST opera_info_list[NORFLASH_API_OPRA_LIST_LEN]; +static DATA_LIST data_list[NORFLASH_API_WRITE_BUFF_LEN]; +static int suspend_number = 0; + +static void* _norflash_api_malloc(uint32_t size) +{ + uint32_t i; + + if(size == sizeof(OPRA_INFO)) + { + for(i = 0; i < NORFLASH_API_OPRA_LIST_LEN; i++) + { + if(opera_info_list[i].is_used == false) + { + opera_info_list[i].is_used = true; + return (void*)&opera_info_list[i].opera_info; + } + } + return NULL; + } + else if(size == NORFLASH_API_SECTOR_SIZE) + { + for(i = 0; i < NORFLASH_API_WRITE_BUFF_LEN; i++) + { + if(data_list[i].is_used == false) + { + data_list[i].is_used = true; + return (void*)data_list[i].buffer; + } + } + return NULL; + } + else + { + ASSERT(0,"%s: size(0x%x) error!", __func__, size); + } +} + +static void _norflash_api_free(void *p) +{ + uint32_t i; + + for(i = 0; i < NORFLASH_API_OPRA_LIST_LEN; i++) + { + if((uint8_t*)&opera_info_list[i].opera_info == p) + { + opera_info_list[i].is_used = false; + return; + } + } + + for(i = 0; i < NORFLASH_API_WRITE_BUFF_LEN; i++) + { + if(data_list[i].buffer == p) + { + data_list[i].is_used = false; + return; + } + } + + ASSERT(0,"%s: p(%p) error!", __func__, p); +} + +static MODULE_INFO* _get_module_info(enum NORFLASH_API_MODULE_ID_T mod_id) +{ + return &norflash_api_info.mod_info[mod_id]; +} + +static OPRA_INFO* _get_tail(MODULE_INFO *mod_info,bool is_remove) +{ + OPRA_INFO *opera_node = NULL; + OPRA_INFO *pre_node = NULL; + OPRA_INFO *tmp; + + pre_node = mod_info->opera_info; + tmp = mod_info->opera_info; + while(tmp) + { + opera_node = tmp; + tmp = opera_node->next; + if(tmp) + { + pre_node = opera_node; + } + } + if(is_remove) + { + if(pre_node) + { + pre_node->next = NULL; + } + } + if(opera_node) + { + opera_node->lock = true; + } + return opera_node; +} + +static void _opera_del(MODULE_INFO *mod_info,OPRA_INFO *node) +{ + OPRA_INFO *opera_node = NULL; + OPRA_INFO *pre_node = NULL; + OPRA_INFO *tmp; + + pre_node = mod_info->opera_info; + tmp = mod_info->opera_info; + while(tmp) + { + opera_node = tmp; + if(opera_node == node) + { + if(mod_info->opera_info == opera_node) + { + mod_info->opera_info = NULL; + } + else + { + pre_node->next = NULL; + } + if(node->buff) + { + _norflash_api_free(node->buff); + } + _norflash_api_free(node); + break; + } + tmp = opera_node->next; + if(tmp) + { + pre_node = opera_node; + } + } +} + +static uint32_t _get_ew_count(MODULE_INFO *mod_info) +{ + OPRA_INFO *opera_node = NULL; + OPRA_INFO *tmp; + uint32_t count = 0; + + tmp = mod_info->opera_info; + while(tmp) + { + opera_node = tmp; + count ++; + tmp = opera_node->next; + } + return count; +} + +static uint32_t _get_w_count(MODULE_INFO *mod_info) +{ + OPRA_INFO *opera_node = NULL; + OPRA_INFO *tmp; + uint32_t count = 0; + + tmp = mod_info->opera_info; + while(tmp) + { + opera_node = tmp; + if(opera_node->type == NORFLASH_API_WRITTING) + { + count ++; + } + tmp = opera_node->next; + } + return count; +} + +static uint32_t _get_e_count(MODULE_INFO *mod_info) +{ + OPRA_INFO *opera_node = NULL; + OPRA_INFO *tmp; + uint32_t count = 0; + + tmp = mod_info->opera_info; + while(tmp) + { + opera_node = tmp; + if(opera_node->type == NORFLASH_API_ERASING) + { + count ++; + } + tmp = opera_node->next; + } + return count; +} + +static MODULE_INFO* _get_cur_mod(void) +{ + uint32_t i; + MODULE_INFO *mod_info = NULL; + uint32_t tmp_mod_id = NORFLASH_API_MODULE_ID_COUNT; + + if(norflash_api_info.cur_mod) + { + return norflash_api_info.cur_mod; + } + + tmp_mod_id = norflash_api_info.cur_mod_id; + for(i = 0; i < NORFLASH_API_MODULE_ID_COUNT; i++) + { + tmp_mod_id = tmp_mod_id + 1 >= NORFLASH_API_MODULE_ID_COUNT ? 0 : tmp_mod_id + 1; + mod_info = _get_module_info((enum NORFLASH_API_MODULE_ID_T)tmp_mod_id); + if(mod_info->is_inited) + { + if(_get_ew_count(mod_info) > 0) + { + return mod_info; + } + } + } + return NULL; +} + +static enum NORFLASH_API_MODULE_ID_T _get_mod_id(MODULE_INFO *mod_info) +{ + uint32_t i; + enum NORFLASH_API_MODULE_ID_T mod_id = NORFLASH_API_MODULE_ID_COUNT; + MODULE_INFO *tmp_mod_info = NULL; + + for(i = 0; i < NORFLASH_API_MODULE_ID_COUNT; i++) + { + tmp_mod_info = _get_module_info((enum NORFLASH_API_MODULE_ID_T)i); + if(tmp_mod_info == mod_info) + { + mod_id = (enum NORFLASH_API_MODULE_ID_T)i; + break; + } + } + return mod_id; +} + +#ifdef FLASH_REMAP +static void _flash_remap_start(enum HAL_NORFLASH_ID_T id,uint32_t addr, uint32_t len) +{ + uint32_t remap_addr; + uint32_t remap_len; + uint32_t remap_offset; + enum HAL_NORFLASH_RET_T ret; + + remap_addr = OTA_CODE_OFFSET; + remap_len = OTA_REMAP_OFFSET - OTA_CODE_OFFSET; + remap_offset = OTA_REMAP_OFFSET; + + // NORFLASH_API_TRACE(3,"%s: id = %d,addr = 0x%x,len = 0x%x.", __func__,id,addr,len); + if((addr & 0x3ffffff) + len <= (remap_addr & 0x3ffffff) || + (addr & 0x3ffffff) >= (remap_addr & 0x3ffffff) + remap_len) + { + // NORFLASH_API_TRACE(3,"%s: Not in the remap area.",__func__); + return; + } + + if(((addr & 0x3ffffff) < (remap_addr & 0x3ffffff) && + (addr & 0x3ffffff) + len > (remap_addr & 0x3ffffff)) || + ((addr & 0x3ffffff) < (remap_addr & 0x3ffffff) + remap_len && + (addr & 0x3ffffff) + len > (remap_addr & 0x3ffffff) + remap_len)) + { + ASSERT(0,"%s: Address ranges bad!addr = 0x%x, len=0x%x,remap_addr=0x%x,remap_len=0x%x", + __func__, addr, len, remap_addr, remap_len); + } + + if(!hal_norflash_get_remap_status(id)) + { + // NORFLASH_API_TRACE(3,"%s: Unremap to enable remap.",__func__); + ret = hal_norflash_enable_remap(id, remap_addr, remap_len, remap_offset); + ASSERT(ret == HAL_NORFLASH_OK, "%s: Failed to enable remap(0x%x,0x%x,0x%x), ret = %d", + __func__, remap_addr, remap_len, remap_offset, ret); + } + else + { + // NORFLASH_API_TRACE(3,"%s: Remaped to disable remap.",__func__); + ret = hal_norflash_disable_remap(id); + ASSERT(ret == HAL_NORFLASH_OK, "%s: Failed to disable remap, ret = %d", + __func__, ret); + } +} + +static void _flash_remap_done(enum HAL_NORFLASH_ID_T id,uint32_t addr, uint32_t len) +{ + uint32_t remap_addr; + uint32_t remap_len; + uint32_t remap_offset; + enum HAL_NORFLASH_RET_T ret; + + remap_addr = OTA_CODE_OFFSET; + remap_len = OTA_REMAP_OFFSET - OTA_CODE_OFFSET; + remap_offset = OTA_REMAP_OFFSET; + + // NORFLASH_API_TRACE(3, "%s: id = %d,addr = 0x%x,len = 0x%x.", __func__,id,addr,len); + if((addr & 0x3ffffff) + len <= (remap_addr & 0x3ffffff) || + (addr & 0x3ffffff) >= (remap_addr & 0x3ffffff) + remap_len) + { + // NORFLASH_API_TRACE(3,"%s: Not in the remap area.",__func__); + return; + } + + if(((addr & 0x3ffffff) < (remap_addr & 0x3ffffff) && + (addr & 0x3ffffff) + len > (remap_addr & 0x3ffffff)) || + ((addr & 0x3ffffff) < (remap_addr & 0x3ffffff) + remap_len && + (addr & 0x3ffffff) + len > (remap_addr & 0x3ffffff) + remap_len)) + { + ASSERT(0,"%s: Address ranges bad!addr = 0x%x, len=0x%x,remap_addr=0x%x,remap_len=0x%x", + __func__, addr, len, remap_addr, remap_len); + } + + if(!hal_norflash_get_remap_status(id)) + { + // NORFLASH_API_TRACE(3, "%s: Unremap to enable remap.",__func__); + ret = hal_norflash_enable_remap(id, remap_addr, remap_len, remap_offset); + ASSERT(ret == HAL_NORFLASH_OK, "%s: Failed to enable remap(0x%x,0x%x,0x%x), ret = %d", + __func__, remap_addr, remap_len, remap_offset, ret); + } + else + { + // NORFLASH_API_TRACE(3, "%s: Remaped to disable remap.",__func__); + ret = hal_norflash_disable_remap(id); + ASSERT(ret == HAL_NORFLASH_OK, "%s: Failed to disable remap, ret = %d", + __func__, ret); + } +} + + +#define FLASH_REMAP_START _flash_remap_start +#define FLASH_REMAP_DONE _flash_remap_done +#else +#define FLASH_REMAP_START(...) +#define FLASH_REMAP_DONE(...) +#endif + +static int32_t _opera_read(MODULE_INFO *mod_info, + uint32_t addr, + uint8_t *buff, + uint32_t len) +{ + OPRA_INFO *opera_node = NULL; + OPRA_INFO *e_node = NULL; + OPRA_INFO *w_node = NULL; + OPRA_INFO *tmp; + uint32_t r_offs; + uint32_t sec_start; + uint32_t sec_len; + + sec_len = mod_info->mod_sector_len; + sec_start = (addr/sec_len)*sec_len; + tmp = mod_info->opera_info; + while(tmp) + { + opera_node = tmp; + tmp = opera_node->next; + if(opera_node->addr == sec_start) + { + if(opera_node->type == NORFLASH_API_WRITTING) + { + w_node = opera_node; + break; + } + else + { + e_node = opera_node; + break; + } + } + } + + if(w_node) + { + r_offs = addr - sec_start; + memcpy(buff,w_node->buff + r_offs,len); + } + else + { + if(e_node) + { + memset(buff,0xff,len); + } + else + { + FLASH_REMAP_START(mod_info->dev_id,addr,len); + memcpy(buff,(uint8_t*)addr,len); + FLASH_REMAP_DONE(mod_info->dev_id,addr,len); + /* + HAL_NORFLASH_RET_T result; + result = hal_norflash_read(mod_info->dev_id,addr,buff,len); + if(result != HAL_NORFLASH_OK) + { + NORFLASH_API_TRACE(2,"%s: hal_norflash_read failed,result = %d.", + __func__,result); + return result; + } + */ + } + } + return 0; +} + +static int32_t _e_opera_add(MODULE_INFO *mod_info, + uint32_t addr, + uint32_t len + ) +{ + OPRA_INFO *opera_node = NULL; + OPRA_INFO *pre_node = NULL; + OPRA_INFO *tmp; + int32_t ret = 0; + + // delete opera nodes with the same address when add the erase opera node. + pre_node = mod_info->opera_info; + tmp = mod_info->opera_info; + while(tmp) + { + opera_node = tmp; + tmp = opera_node->next; + + if(opera_node->addr == addr) + { + if(opera_node->lock == false) + { + if(opera_node == mod_info->opera_info) + { + mod_info->opera_info = tmp; + } + else + { + pre_node->next = tmp; + } + if(opera_node->type == NORFLASH_API_WRITTING) + { + if(opera_node->buff) + { + _norflash_api_free(opera_node->buff); + } + } + _norflash_api_free(opera_node); + } + else + { + if(opera_node->type == NORFLASH_API_ERASING) + { + NORFLASH_API_TRACE(3,"%s: erase is merged! addr = 0x%x,len = 0x%x.", + __func__, + opera_node->addr, + opera_node->len); + ret = 0; + goto _func_end; + } + } + } + + if(tmp) + { + pre_node = opera_node; + } + } + + // add new node to header. + opera_node = (OPRA_INFO*)_norflash_api_malloc(sizeof(OPRA_INFO)); + if(opera_node == NULL) + { + NORFLASH_API_TRACE(3,"%s:%d,_norflash_api_malloc failed! size = %d.", + __func__,__LINE__,sizeof(OPRA_INFO)); + ret = 1; + goto _func_end; + } + opera_node->type = NORFLASH_API_ERASING; + opera_node->addr = addr; + opera_node->len = len; + opera_node->w_offs = 0; + opera_node->w_len = 0; + opera_node->buff = NULL; + opera_node->lock = false; + opera_node->next = mod_info->opera_info; + mod_info->opera_info = opera_node; + ret = 0; +_func_end: + + return ret; +} + +static int32_t _w_opera_add(MODULE_INFO *mod_info, + uint32_t addr, + uint32_t len, + uint8_t *buff) +{ + OPRA_INFO *opera_node = NULL; + OPRA_INFO *e_node = NULL; + OPRA_INFO *w_node = NULL; + OPRA_INFO *tmp; + uint32_t w_offs; + uint32_t w_len; + uint32_t sec_start; + uint32_t sec_len; + uint32_t w_end1; + uint32_t w_end2; + uint32_t w_start; + uint32_t w_end; + uint32_t w_len_new; + int32_t ret = 0; + + sec_len = mod_info->mod_sector_len; + sec_start = (addr/sec_len)*sec_len; + w_offs = addr - sec_start; + w_len = len; + tmp = mod_info->opera_info; + while(tmp) + { + opera_node = tmp; + tmp = opera_node->next; + + if(opera_node->addr == sec_start) + { + if(opera_node->type == NORFLASH_API_WRITTING) + { + if(!opera_node->lock) + { + // select the first w_node in the list. + w_node = opera_node; + break; + } + } + else + { + e_node = opera_node; + break; + } + } + } + + if(w_node) + { + memcpy(w_node->buff + w_offs,buff,w_len); + w_start = w_node->w_offs <= w_offs ? w_node->w_offs:w_offs; + w_end1 = w_node->w_offs + w_node->w_len; + w_end2 = w_offs + w_len; + w_end = w_end1 >= w_end2 ? w_end1 : w_end2; + w_len_new = w_end - w_start; + w_node->w_offs = w_start; + w_node->w_len = w_len_new; + opera_node = w_node; + ret = 0; + } + else + { + opera_node = (OPRA_INFO*)_norflash_api_malloc(sizeof(OPRA_INFO)); + if(opera_node == NULL) + { + NORFLASH_API_TRACE(3,"%s:%d,_norflash_api_malloc failed! size = %d.", + __func__,__LINE__,sizeof(OPRA_INFO)); + ret = 1; + goto _func_end; + } + opera_node->type = NORFLASH_API_WRITTING; + opera_node->addr = sec_start; + opera_node->len = sec_len; + opera_node->w_offs = w_offs; + opera_node->w_len = w_len; + opera_node->buff = (uint8_t*)_norflash_api_malloc(opera_node->len); + if(opera_node->buff == NULL) + { + _norflash_api_free(opera_node); + NORFLASH_API_TRACE(3,"%s:%d,_norflash_api_malloc failed! size = %d.", + __func__,__LINE__,opera_node->len); + ret = 1; + goto _func_end; + } + if(e_node) + { + memset(opera_node->buff,0xff,opera_node->len); + } + else + { + memcpy(opera_node->buff,(uint8_t*)opera_node->addr,opera_node->len); + } + memcpy(opera_node->buff + w_offs,buff,w_len); + opera_node->lock = false; + opera_node->next = mod_info->opera_info; + mod_info->opera_info = opera_node; + ret = 0; + } + +_func_end: + return ret; +} + +bool _opera_flush(MODULE_INFO *mod_info,bool nosuspend) +{ + OPRA_INFO *cur_opera_info = NULL; + enum HAL_NORFLASH_RET_T result; + bool opera_is_completed = false; + NORFLASH_API_OPERA_RESULT opera_result; + bool ret = false; + bool suspend; + +#if defined(FLASH_SUSPEND) + suspend = true; +#else + suspend = false; +#endif + suspend = nosuspend == true ? false: suspend; + + if(!mod_info->cur_opera_info) + { + mod_info->cur_opera_info = _get_tail(mod_info, false); + } + + if(!mod_info->cur_opera_info) + { + return false; + } + + ret = true; + cur_opera_info = mod_info->cur_opera_info; + if(cur_opera_info->type == NORFLASH_API_WRITTING) + { + if(mod_info->state == NORFLASH_API_STATE_IDLE) + { + suspend_number = 0; + if(cur_opera_info->w_len > 0) + { + NORFLASH_API_TRACE(5,"%s: %d,hal_norflash_write_suspend,addr = 0x%x,len = 0x%x,suspend = %d.", + __func__,__LINE__, + cur_opera_info->addr + cur_opera_info->w_offs, + cur_opera_info->w_len, + suspend); + + FLASH_REMAP_START(mod_info->dev_id,cur_opera_info->addr + cur_opera_info->w_offs,cur_opera_info->w_len); + pmu_flash_write_config(); + result = hal_norflash_write_suspend(mod_info->dev_id, + cur_opera_info->addr + cur_opera_info->w_offs, + cur_opera_info->buff + cur_opera_info->w_offs, + cur_opera_info->w_len, + suspend); + pmu_flash_read_config(); + FLASH_REMAP_DONE(mod_info->dev_id,cur_opera_info->addr + cur_opera_info->w_offs,cur_opera_info->w_len); + } + else + { + result = HAL_NORFLASH_OK; + } + + if(result == HAL_NORFLASH_OK) + { + opera_is_completed = true; + goto __opera_is_completed; + } + else if(result == HAL_NORFLASH_SUSPENDED) + { + mod_info->state = NORFLASH_API_STATE_WRITTING_SUSPEND; + } + else + { + ASSERT(0, "%s: %d, hal_norflash_write_suspend failed,result = %d",__func__,__LINE__,result); + } + } + else if(mod_info->state == NORFLASH_API_STATE_WRITTING_SUSPEND) + { + suspend_number ++; + FLASH_REMAP_START(mod_info->dev_id,cur_opera_info->addr + cur_opera_info->w_offs,cur_opera_info->w_len); + pmu_flash_write_config(); + result = hal_norflash_write_resume(mod_info->dev_id, + suspend); + pmu_flash_read_config(); + FLASH_REMAP_DONE(mod_info->dev_id,cur_opera_info->addr + cur_opera_info->w_offs,cur_opera_info->w_len); + if(result == HAL_NORFLASH_OK) + { + opera_is_completed = true; + goto __opera_is_completed; + } + else if(result == HAL_NORFLASH_SUSPENDED) + { + mod_info->state = NORFLASH_API_STATE_WRITTING_SUSPEND; + } + else + { + ASSERT(0, "%s: %d, hal_norflash_write_resume failed,result = %d",__func__,__LINE__,result); + } + } + else + { + ASSERT(0, "%s: %d, mod_info->state error,state = %d",__func__,__LINE__,mod_info->state); + } + } + else + { + if(mod_info->state == NORFLASH_API_STATE_IDLE) + { + suspend_number = 0; + NORFLASH_API_TRACE(5,"%s: %d,hal_norflash_erase_suspend,addr = 0x%x,len = 0x%x,suspend = %d.", + __func__,__LINE__, + cur_opera_info->addr, + cur_opera_info->len, + suspend); + FLASH_REMAP_START(mod_info->dev_id, cur_opera_info->addr, cur_opera_info->len); + pmu_flash_write_config(); + result = hal_norflash_erase_suspend(mod_info->dev_id, + cur_opera_info->addr, + cur_opera_info->len, + suspend); + pmu_flash_read_config(); + FLASH_REMAP_DONE(mod_info->dev_id, cur_opera_info->addr, cur_opera_info->len); + if(result == HAL_NORFLASH_OK) + { + opera_is_completed = true; + goto __opera_is_completed; + } + else if(result == HAL_NORFLASH_SUSPENDED) + { + mod_info->state = NORFLASH_API_STATE_ERASE_SUSPEND; + } + else + { + ASSERT(0, "%s: %d, hal_norflash_erase_suspend failed,result = %d",__func__,__LINE__,result); + } + } + else if(mod_info->state == NORFLASH_API_STATE_ERASE_SUSPEND) + { + suspend_number ++; + FLASH_REMAP_START(mod_info->dev_id, cur_opera_info->addr, cur_opera_info->len); + pmu_flash_write_config(); + result = hal_norflash_erase_resume(mod_info->dev_id, + suspend); + pmu_flash_read_config(); + FLASH_REMAP_DONE(mod_info->dev_id, cur_opera_info->addr, cur_opera_info->len); + if(result == HAL_NORFLASH_OK) + { + opera_is_completed = true; + goto __opera_is_completed; + } + else if(result == HAL_NORFLASH_SUSPENDED) + { + mod_info->state = NORFLASH_API_STATE_ERASE_SUSPEND; + } + else + { + ASSERT(0, "%s: %d, hal_norflash_write_resume failed,result = %d", + __func__,__LINE__,result); + } + } + else + { + ASSERT(0, "%s: %d, mod_info->state error,state = %d", + __func__,__LINE__,mod_info->state); + } + } + +__opera_is_completed: + + if(opera_is_completed) + { + mod_info->state = NORFLASH_API_STATE_IDLE; + if(!nosuspend + && mod_info->cb_func + && ((cur_opera_info->w_len > 0 && cur_opera_info->type == NORFLASH_API_WRITTING) + || (cur_opera_info->len > 0 && cur_opera_info->type == NORFLASH_API_ERASING)) + ) + { + NORFLASH_API_TRACE(6,"%s: w/e done.type = %d,addr = 0x%x,w_len = 0x%x,len = 0x%x,suspend_num = %d.", + __func__, + cur_opera_info->type, + cur_opera_info->addr + cur_opera_info->w_offs, + cur_opera_info->w_len, + cur_opera_info->len, + suspend_number); + if(cur_opera_info->type == NORFLASH_API_WRITTING) + { + opera_result.addr = cur_opera_info->addr + cur_opera_info->w_offs; + opera_result.len = cur_opera_info->w_len; + } + else + { + opera_result.addr = cur_opera_info->addr; + opera_result.len = cur_opera_info->len; + } + opera_result.type = cur_opera_info->type; + opera_result.result = NORFLASH_API_OK; + opera_result.remain_num = _get_ew_count(mod_info) - 1; + mod_info->cb_func(&opera_result); + } + _opera_del(mod_info,cur_opera_info); + mod_info->cur_opera_info = NULL; + } + + return ret; +} + +void _flush_disable(enum NORFLASH_API_USER user_id,uint32_t cb) +{ + norflash_api_info.allowed_cb[user_id] = (NOFLASH_API_FLUSH_ALLOWED_CB)cb; +} + +void _flush_enable(enum NORFLASH_API_USER user_id) +{ + norflash_api_info.allowed_cb[user_id] = NULL; +} + +bool _flush_is_allowed(void) +{ + bool ret = true; + uint32_t user_id; + + for(user_id = NORFLASH_API_USER_CP; user_id < NORFLASH_API_USER_COUNTS; user_id ++) + { + if(norflash_api_info.allowed_cb[user_id]) + { + if(!norflash_api_info.allowed_cb[user_id]()) + { + ret = false; + } + else + { + norflash_api_info.allowed_cb[user_id] = NULL; + } + } + } + return ret; +} + +//------------------------------------------------------------------- +// APIS Function. +//------------------------------------------------------------------- +enum NORFLASH_API_RET_T norflash_api_init(void) +{ + uint32_t i; + + memset((void*)&norflash_api_info,0,sizeof(NORFLASH_API_INFO)); + norflash_api_info.cur_mod_id = NORFLASH_API_MODULE_ID_COUNT; + norflash_api_info.is_inited = true; + norflash_api_info.cur_mod = NULL; + for(i = 0; i < NORFLASH_API_MODULE_ID_COUNT; i++) + { + norflash_api_info.mod_info[i].state = NORFLASH_API_STATE_UNINITED; + } + +#if !defined(FLASH_API_SIMPLE) +#if defined(FLASH_SUSPEND) + hal_sleep_set_sleep_hook(HAL_SLEEP_HOOK_NORFLASH_API, norflash_api_flush); +#else + hal_sleep_set_deep_sleep_hook(HAL_DEEP_SLEEP_HOOK_NORFLASH_API, norflash_api_flush); +#endif +#endif + + return NORFLASH_API_OK; +} + +enum NORFLASH_API_RET_T norflash_api_register( + enum NORFLASH_API_MODULE_ID_T mod_id, + enum HAL_NORFLASH_ID_T dev_id, + uint32_t mod_base_addr, + uint32_t mod_len, + uint32_t mod_block_len, + uint32_t mod_sector_len, + uint32_t mod_page_len, + uint32_t buffer_len, + NORFLASH_API_OPERA_CB cb_func + ) +{ + MODULE_INFO *mod_info = NULL; + + NORFLASH_API_TRACE(5,"%s: mod_id = %d,dev_id = %d,mod_base_addr = 0x%x,mod_len = 0x%x,", + __func__,mod_id,dev_id,mod_base_addr,mod_len); + NORFLASH_API_TRACE(4,"mod_block_len = 0x%x,mod_sector_len = 0x%x,mod_page_len = 0x%x,buffer_len = 0x%x.", + mod_block_len,mod_sector_len,mod_page_len,buffer_len); + if(!norflash_api_info.is_inited) + { + NORFLASH_API_TRACE(2,"%s: %d, norflash_api uninit!",__func__,__LINE__); + return NORFLASH_API_ERR_UNINIT; + } + + if(mod_id >= NORFLASH_API_MODULE_ID_COUNT) + { + NORFLASH_API_TRACE(2,"%s : mod_id error! mod_id = %d.",__func__, mod_id); + return NORFLASH_API_BAD_MOD_ID; + } + + if(dev_id >= HAL_NORFLASH_ID_NUM) + { + NORFLASH_API_TRACE(2,"%s : dev_id error! mod_id = %d.",__func__,dev_id); + return NORFLASH_API_BAD_DEV_ID; + } + + if(buffer_len < mod_sector_len || !API_IS_ALIGN(buffer_len,mod_sector_len)) + { + NORFLASH_API_TRACE(2,"%s : buffer_len error buffer_len = %d.",__func__, buffer_len); + return NORFLASH_API_BAD_BUFF_LEN; + } + mod_info = _get_module_info(mod_id); + if(mod_info->is_inited) + { + // NORFLASH_API_TRACE(3,"%s: %d, norflash_async[%d] has registered!",__func__,__LINE__,mod_id); + return NORFLASH_API_OK; //NORFLASH_API_ERR_HASINIT; + } + mod_info->dev_id = dev_id; + mod_info->mod_id = mod_id; + mod_info->mod_base_addr = mod_base_addr; + mod_info->mod_len = mod_len; + mod_info->mod_block_len = mod_block_len; + mod_info->mod_sector_len = mod_sector_len; + mod_info->mod_page_len = mod_page_len; + mod_info->buff_len = buffer_len; + mod_info->cb_func = cb_func; + mod_info->opera_info = NULL; + mod_info->cur_opera_info = NULL; + mod_info->state = NORFLASH_API_STATE_IDLE; + mod_info->is_inited = true; + return NORFLASH_API_OK; +} + +enum NORFLASH_API_RET_T norflash_api_read( + enum NORFLASH_API_MODULE_ID_T mod_id, + uint32_t start_addr, + uint8_t *buffer, + uint32_t len + ) +{ + MODULE_INFO *mod_info = NULL; + int32_t result; + enum NORFLASH_API_RET_T ret; + uint32_t lock; + + NORFLASH_API_TRACE(4,"%s:mod_id = %d,start_addr = 0x%x,len = 0x%x", + __func__,mod_id, start_addr, len); + ASSERT(buffer,"%s:buffer is null! ", + __func__); + if(!norflash_api_info.is_inited) + { + NORFLASH_API_TRACE(1,"%s: norflash_api uninit!",__func__); + return NORFLASH_API_ERR_UNINIT; + } + if(mod_id >= NORFLASH_API_MODULE_ID_COUNT) + { + NORFLASH_API_TRACE(2,"%s : mod_id error! mod_id = %d.",__func__, mod_id); + return NORFLASH_API_BAD_MOD_ID; + } + + mod_info = _get_module_info(mod_id); + if(!mod_info->is_inited) + { + NORFLASH_API_TRACE(2,"%s : module unregistered! mod_id = %d.",__func__, mod_id); + return NORFLASH_API_ERR_UNINIT; + } + + if(start_addr < mod_info->mod_base_addr + || start_addr + len > mod_info->mod_base_addr + mod_info->mod_len) + { + NORFLASH_API_TRACE(3,"%s : reading out of range! start_address = 0x%x,len = 0x%x.", + __func__, start_addr, len); + return NORFLASH_API_BAD_ADDR; + } + + if(len == 0) + { + NORFLASH_API_TRACE(2,"%s : len error! len = %d.", + __func__, len); + return NORFLASH_API_BAD_LEN; + } + lock = int_lock_global(); + result = _opera_read(mod_info,start_addr,(uint8_t*)buffer,len); + + if(result) + { + ret = NORFLASH_API_ERR; + } + else + { + ret = NORFLASH_API_OK; + } + int_unlock_global(lock); + NORFLASH_API_TRACE(2,"%s: done. ret = %d.",__func__,ret); + return ret; +} + +enum NORFLASH_API_RET_T norflash_sync_read( + enum NORFLASH_API_MODULE_ID_T mod_id, + uint32_t start_addr, + uint8_t *buffer, + uint32_t len + ) +{ + MODULE_INFO *mod_info = NULL; + uint32_t lock; + + NORFLASH_API_TRACE(4,"%s:mod_id = %d,start_addr = 0x%x,len = 0x%x", + __func__,mod_id,start_addr,len); + ASSERT(buffer,"%s:%d,buffer is null! ", + __func__,__LINE__); + if(!norflash_api_info.is_inited) + { + NORFLASH_API_TRACE(1,"%s: norflash_api uninit!", __func__); + return NORFLASH_API_ERR_UNINIT; + } + if(mod_id >= NORFLASH_API_MODULE_ID_COUNT) + { + NORFLASH_API_TRACE(2,"%s : mod_id error! mod_id = %d.", __func__, mod_id); + return NORFLASH_API_BAD_MOD_ID; + } + + mod_info = _get_module_info(mod_id); + if(!mod_info->is_inited) + { + NORFLASH_API_TRACE(2,"%s : module unregistered! mod_id = %d.",__func__, mod_id); + return NORFLASH_API_ERR_UNINIT; + } + + if(start_addr < mod_info->mod_base_addr + || start_addr + len > mod_info->mod_base_addr + mod_info->mod_len) + { + NORFLASH_API_TRACE(3,"%s : reading out of range! start_address = 0x%x,len = 0x%x.", + __func__, start_addr, len); + return NORFLASH_API_BAD_ADDR; + } + + if(len == 0) + { + NORFLASH_API_TRACE(2,"%s : len error! len = %d.", + __func__, len); + return NORFLASH_API_BAD_LEN; + } + + lock = int_lock_global(); + FLASH_REMAP_START(mod_info->dev_id,start_addr, len); + memcpy(buffer,(uint8_t*)start_addr,len); + FLASH_REMAP_DONE(mod_info->dev_id,start_addr, len); + NORFLASH_API_TRACE(1,"%s: done.",__func__); + int_unlock_global(lock); + + return NORFLASH_API_OK; +} + +enum NORFLASH_API_RET_T norflash_api_erase( + enum NORFLASH_API_MODULE_ID_T mod_id, + uint32_t start_addr, + uint32_t len, + bool async + ) +{ + MODULE_INFO *mod_info = NULL; + MODULE_INFO *cur_mod_info = NULL; + uint32_t lock; + int32_t result; + bool bresult = false; + enum NORFLASH_API_RET_T ret; + + NORFLASH_API_TRACE(5,"%s: mod_id = %d,start_addr = 0x%x,len = 0x%x,async = %d.", + __func__,mod_id,start_addr,len,async); + if(!norflash_api_info.is_inited) + { + NORFLASH_API_TRACE(1,"%s: norflash_api uninit!",__func__); + return NORFLASH_API_ERR_UNINIT; + } + if(mod_id >= NORFLASH_API_MODULE_ID_COUNT) + { + NORFLASH_API_TRACE(2,"%s : invalid mod_id! mod_id = %d.",__func__, mod_id); + return NORFLASH_API_BAD_MOD_ID; + } + + mod_info = _get_module_info(mod_id); + if(!mod_info->is_inited) + { + NORFLASH_API_TRACE(2,"%s : module unregistered! mod_id = %d.",__func__, mod_id); + return NORFLASH_API_ERR_UNINIT; + } + + if(start_addr < mod_info->mod_base_addr + || start_addr + len > mod_info->mod_base_addr + mod_info->mod_len) + { + NORFLASH_API_TRACE(3,"%s : erase out of range! start_address = 0x%x,len = 0x%x.", + __func__,start_addr,len); + return NORFLASH_API_BAD_ADDR; + } + + if(!API_IS_ALIGN(start_addr,mod_info->mod_sector_len)) + { + NORFLASH_API_TRACE(2,"%s : start_address no alignment! start_address = %d.", + __func__, start_addr); + return NORFLASH_API_BAD_ADDR; + } + + if( +#ifdef PUYA_FLASH_ERASE_PAGE_ENABLE + len != mod_info->mod_page_len && +#endif + len != mod_info->mod_sector_len && + len != mod_info->mod_block_len) + { + NORFLASH_API_TRACE(2,"%s : len error. len = %d!", + __func__, len); + return NORFLASH_API_BAD_LEN; + } + +#if defined(FLASH_API_SIMPLE) + async = false; +#endif + if(async) + { + lock = int_lock_global(); + + // add to opera_info chain header. + result = _e_opera_add(mod_info,start_addr,len); + if(result == 0) + { + ret = NORFLASH_API_OK; + } + else + { + ret = NORFLASH_API_BUFFER_FULL; + } + int_unlock_global(lock); + NORFLASH_API_TRACE(4,"%s: _e_opera_add done. start_addr = 0x%x,len = 0x%x,ret = %d.", + __func__,start_addr,len,ret); + } + else + { + lock = int_lock_global(); + // Handle the suspend operation. + if(norflash_api_info.cur_mod != NULL + && mod_info != norflash_api_info.cur_mod) + { + cur_mod_info = norflash_api_info.cur_mod; + while(cur_mod_info->state != NORFLASH_API_STATE_IDLE) + { + if(!_flush_is_allowed()) + { + continue; + } + bresult = _opera_flush(cur_mod_info,true); + if(!bresult) + { + norflash_api_info.cur_mod = NULL; + } + } + } + + // flush all of cur module opera. + // norflash_api_info.cur_mod_id = mod_id; + do{ + if(!_flush_is_allowed()) + { + continue; + } + bresult = _opera_flush(mod_info,true); + }while(bresult); + FLASH_REMAP_START(mod_info->dev_id,start_addr,len); + pmu_flash_write_config(); + result = hal_norflash_erase(mod_info->dev_id,start_addr, len); + pmu_flash_read_config(); + FLASH_REMAP_DONE(mod_info->dev_id,start_addr,len); + if(result == HAL_NORFLASH_OK) + { + ret = NORFLASH_API_OK; + } + else if(result == HAL_NORFLASH_BAD_ADDR) + { + ret = NORFLASH_API_BAD_ADDR; + } + else if(result == HAL_NORFLASH_BAD_LEN) + { + ret = NORFLASH_API_BAD_LEN; + } + else + { + ret = NORFLASH_API_ERR; + } + int_unlock_global(lock); + NORFLASH_API_TRACE(4,"%s: hal_norflash_erase done. start_addr = 0x%x,len = 0x%x,ret = %d.", + __func__,start_addr,len,ret); + } + //NORFLASH_API_TRACE(2,"%s: done.ret = %d.",__func__, ret); + return ret; +} + +enum NORFLASH_API_RET_T norflash_api_write( + enum NORFLASH_API_MODULE_ID_T mod_id, + uint32_t start_addr, + const uint8_t *buffer, + uint32_t len, + bool async + ) +{ + MODULE_INFO *mod_info = NULL; + MODULE_INFO *cur_mod_info = NULL; + uint32_t lock; + int32_t result; + bool bresult = false; + enum NORFLASH_API_RET_T ret; + + NORFLASH_API_TRACE(4,"%s: mod_id = %d,start_addr = 0x%x,len = 0x%x.", + __func__,mod_id,start_addr,len); + + if(!norflash_api_info.is_inited) + { + NORFLASH_API_TRACE(1,"%s: norflash_api uninit!",__func__); + return NORFLASH_API_ERR_UNINIT; + } + + if(mod_id > NORFLASH_API_MODULE_ID_COUNT) + { + NORFLASH_API_TRACE(2,"%s : mod_id error! mod_id = %d.",__func__, mod_id); + return NORFLASH_API_BAD_MOD_ID; + } + + mod_info = _get_module_info(mod_id); + if(!mod_info->is_inited) + { + NORFLASH_API_TRACE(2,"%s :module unregistered! mod_id = %d.",__func__, mod_id); + return NORFLASH_API_ERR_UNINIT; + } + + + if(start_addr < mod_info->mod_base_addr + || start_addr + len > mod_info->mod_base_addr + mod_info->mod_len) + { + NORFLASH_API_TRACE(3,"%s : writting out of range! start_address = 0x%x,len = 0x%x.", + __func__,mod_info->mod_base_addr,mod_info->mod_len); + return NORFLASH_API_BAD_ADDR; + } + + if(len == 0) + { + NORFLASH_API_TRACE(2,"%s : len error! len = %d.", + __func__,len); + return NORFLASH_API_BAD_LEN; + } +#if defined(FLASH_API_SIMPLE) + async = false; +#endif + if(async) + { + // add to opera_info chain header. + lock = int_lock_global(); + result = _w_opera_add(mod_info,start_addr,len,(uint8_t*)buffer); + if(result == 0) + { + ret = NORFLASH_API_OK; + } + else + { + ret = NORFLASH_API_BUFFER_FULL; + } + int_unlock_global(lock); + NORFLASH_API_TRACE(4,"%s: _w_opera_add done. start_addr = 0x%x,len = 0x%x,ret = %d.", + __func__,start_addr,len,ret); + } + else + { + lock = int_lock_global(); + + // flush the opera of currently being processed. + if(norflash_api_info.cur_mod != NULL + && mod_info != norflash_api_info.cur_mod) + { + cur_mod_info = norflash_api_info.cur_mod; + while(cur_mod_info->state != NORFLASH_API_STATE_IDLE) + { + if(!_flush_is_allowed()) + { + continue; + } + bresult = _opera_flush(cur_mod_info,true); + if(!bresult) + { + norflash_api_info.cur_mod = NULL; + } + } + } + + // flush all of cur module opera. + do{ + if(!_flush_is_allowed()) + { + continue; + } + bresult = _opera_flush(mod_info,true); + }while(bresult); + FLASH_REMAP_START(mod_info->dev_id,start_addr,len); + pmu_flash_write_config(); + result = hal_norflash_write(mod_info->dev_id,start_addr, buffer, len); + pmu_flash_read_config(); + FLASH_REMAP_DONE(mod_info->dev_id,start_addr,len); + if(result == HAL_NORFLASH_OK) + { + ret = NORFLASH_API_OK; + } + else if(result == HAL_NORFLASH_BAD_ADDR) + { + ret = NORFLASH_API_BAD_ADDR; + } + else if(result == HAL_NORFLASH_BAD_LEN) + { + ret = NORFLASH_API_BAD_LEN; + } + else + { + ret = NORFLASH_API_ERR; + } + int_unlock_global(lock); + NORFLASH_API_TRACE(4,"%s: hal_norflash_write done. start_addr = 0x%x,len = 0x%x,ret = %d.", + __func__,start_addr,len,ret); + } + return ret; +} + +// -1: error, 0:all pending flash op flushed, 1:still pending flash op to be flushed +int norflash_api_flush(void) +{ + enum NORFLASH_API_MODULE_ID_T mod_id = NORFLASH_API_MODULE_ID_COUNT; + MODULE_INFO *mod_info = NULL; + uint32_t lock; + bool bret = false; + + lock = int_lock_global(); + if(!norflash_api_info.is_inited) + { + NORFLASH_API_TRACE(1,"%s: norflash_api uninit!",__func__); + int_unlock_global(lock); + return -1; + } +#if defined(FLASH_API_SIMPLE) + int_unlock_global(lock); + return 0; +#endif + + if(!_flush_is_allowed()) + { + int_unlock_global(lock); + return 0; + } + + mod_info = _get_cur_mod(); + if(!mod_info) + { + int_unlock_global(lock); + return 0; + } + mod_id = _get_mod_id(mod_info); + + norflash_api_info.cur_mod_id = mod_id; + norflash_api_info.cur_mod = mod_info; + bret = _opera_flush(mod_info,false); + if(!bret) + { + norflash_api_info.cur_mod = NULL; + } + int_unlock_global(lock); + + return 1; +} + +bool norflash_api_buffer_is_free( + enum NORFLASH_API_MODULE_ID_T mod_id) +{ + MODULE_INFO *mod_info = NULL; + uint32_t count; + + if(mod_id >= NORFLASH_API_MODULE_ID_COUNT) + { + ASSERT(0,"%s : mod_id error! mod_id = %d.",__func__, mod_id); + } + + mod_info = _get_module_info(mod_id); + if(!mod_info->is_inited) + { + ASSERT(0,"%s : mod_id error! mod_id = %d.",__func__, mod_id); + } + + count = _get_ew_count(mod_info); + if(count > 0) + { + return false; + } + else + { + return true; + } +} + +uint32_t norflash_api_get_used_buffer_count( + enum NORFLASH_API_MODULE_ID_T mod_id, + enum NORFLASH_API_OPRATION_TYPE type + ) +{ + MODULE_INFO *mod_info = NULL; + uint32_t count = 0; + + if(mod_id >= NORFLASH_API_MODULE_ID_COUNT) + { + ASSERT(0,"%s : mod_id error! mod_id = %d.",__func__, mod_id); + } + + mod_info = _get_module_info(mod_id); + if(!mod_info->is_inited) + { + ASSERT(0,"%s : mod_id error! mod_id = %d.",__func__, mod_id); + } + if(type & NORFLASH_API_WRITTING) + { + count = _get_w_count(mod_info); + } + + if(type & NORFLASH_API_ERASING) + { + count += _get_e_count(mod_info); + } + return count; +} + +uint32_t norflash_api_get_free_buffer_count( + enum NORFLASH_API_OPRATION_TYPE type + ) +{ + MODULE_INFO *mod_info = NULL; + uint32_t i; + uint32_t used_count = 0; + uint32_t free_count = 0; + + if(type & NORFLASH_API_WRITTING) + { + for(i = NORFLASH_API_MODULE_ID_LOG_DUMP; i < NORFLASH_API_MODULE_ID_COUNT; i ++) + { + mod_info = _get_module_info((enum NORFLASH_API_MODULE_ID_T)i); + if(mod_info->is_inited) + { + used_count += _get_w_count(mod_info); + } + } + ASSERT(used_count <= NORFLASH_API_OPRA_LIST_LEN,"writting opra count error!"); + free_count += (NORFLASH_API_OPRA_LIST_LEN - used_count); + } + + if(type & NORFLASH_API_ERASING) + { + for(i = NORFLASH_API_MODULE_ID_LOG_DUMP; i < NORFLASH_API_MODULE_ID_COUNT; i ++) + { + mod_info = _get_module_info((enum NORFLASH_API_MODULE_ID_T)i); + if(mod_info->is_inited) + { + used_count += _get_e_count(mod_info); + } + } + ASSERT(used_count <= NORFLASH_API_OPRA_LIST_LEN,"erase opra count error!"); + free_count += (NORFLASH_API_OPRA_LIST_LEN - used_count); + } + return free_count; +} + + +void norflash_api_flush_all(void) +{ + int ret; + int cnt = 0; + + norflash_api_flush_enable_all(); + do + { + ret = norflash_api_flush(); + if(ret == 1) + { + cnt ++; + } + } while (1 == ret); + + NORFLASH_API_TRACE(2,"%s: done. cnt = %d.",__func__,cnt); +} + +void norflash_api_flush_disable(enum NORFLASH_API_USER user_id,uint32_t cb) +{ + if(!norflash_api_info.is_inited) + { + return; + } + ASSERT(user_id < NORFLASH_API_USER_COUNTS, "%s: user_id(%d) error!", __func__, user_id); + _flush_disable(user_id,cb); +} + +void norflash_api_flush_enable(enum NORFLASH_API_USER user_id) +{ + if(!norflash_api_info.is_inited) + { + return; + } + ASSERT(user_id < NORFLASH_API_USER_COUNTS, "%s: user_id(%d) too large!", __func__, user_id); + _flush_enable(user_id); +} + +void norflash_api_flush_enable_all(void) +{ + uint32_t user_id; + + if(!norflash_api_info.is_inited) + { + return; + } + for(user_id = NORFLASH_API_USER_CP; user_id < NORFLASH_API_USER_COUNTS; user_id ++) + { + _flush_enable((enum NORFLASH_API_USER)user_id); + } +} + + +enum NORFLASH_API_STATE norflash_api_get_state(enum NORFLASH_API_MODULE_ID_T mod_id) +{ + ASSERT(mod_id < NORFLASH_API_MODULE_ID_COUNT,"%s : mod_id error! mod_id = %d.",__func__, mod_id); + return norflash_api_info.mod_info[mod_id].state; +} + +void norflash_flush_all_pending_op(void) +{ + norflash_api_flush_all(); +} + +void app_flush_pending_flash_op(enum NORFLASH_API_MODULE_ID_T module, + enum NORFLASH_API_OPRATION_TYPE type) +{ + hal_trace_pause(); + do + { + norflash_api_flush(); + if (NORFLASH_API_ALL != type) + { + if (0 == norflash_api_get_used_buffer_count(module, type)) + { + break; + } + } + else + { + if (norflash_api_buffer_is_free(module)) + { + break; + } + } + osDelay(10); + } while (1); + + hal_trace_continue(); +} + +void app_flash_page_erase(enum NORFLASH_API_MODULE_ID_T module, uint32_t flashOffset) +{ + // check whether the flash has been erased + bool isEmptyPage = true; + uint32_t *ptrStartFlashAddr = ( uint32_t * )(FLASH_NC_BASE + flashOffset); + for (uint32_t index = 0; index < FLASH_SECTOR_SIZE / sizeof(uint32_t); index++) + { + if (0xFFFFFFFF != ptrStartFlashAddr[index]) + { + isEmptyPage = false; + break; + } + } + + if (isEmptyPage) + { + return; + } + + uint32_t lock; + enum NORFLASH_API_RET_T ret; + + flashOffset &= 0xFFFFFF; + do + { + lock = int_lock_global(); + hal_trace_pause(); + ret = norflash_api_erase(module, + (FLASH_NC_BASE + flashOffset), + FLASH_SECTOR_SIZE, + true); + hal_trace_continue(); + int_unlock_global(lock); + + if (NORFLASH_API_OK == ret) + { + TRACE(1,"%s: norflash_api_erase ok!", __func__); + break; + } + else if (NORFLASH_API_BUFFER_FULL == ret) + { + TRACE(0,"Flash async cache overflow! To flush it."); + app_flush_pending_flash_op(module, NORFLASH_API_ERASING); + } + else + { + ASSERT(0, "%s: norflash_api_erase failed. ret = %d", __FUNCTION__, ret); + } + } while (1); +} + +void app_flash_page_program(enum NORFLASH_API_MODULE_ID_T module, + uint32_t flashOffset, + uint8_t *ptr, + uint32_t len, + bool synWrite) +{ + uint32_t lock; + enum NORFLASH_API_RET_T ret; + bool is_async = false; + + flashOffset &= 0xFFFFFF; + + if (synWrite) + { + is_async = false; + } + else + { + is_async = true; + } + + do + { + lock = int_lock_global(); + hal_trace_pause(); + + ret = norflash_api_write(module, + (FLASH_NC_BASE + flashOffset), + ptr, + len, + is_async); + + hal_trace_continue(); + + int_unlock_global(lock); + + if (NORFLASH_API_OK == ret) + { + TRACE(1,"%s: norflash_api_write ok!", __func__); + break; + } + else if (NORFLASH_API_BUFFER_FULL == ret) + { + TRACE(0,"Flash async cache overflow! To flush it."); + app_flush_pending_flash_op(module, NORFLASH_API_WRITTING); + } + else + { + ASSERT(0, "%s: norflash_api_write failed. ret = %d", __FUNCTION__, ret); + } + } while (1); +} + + diff --git a/services/norflash_api/norflash_api.h b/services/norflash_api/norflash_api.h new file mode 100644 index 0000000..b8f237d --- /dev/null +++ b/services/norflash_api/norflash_api.h @@ -0,0 +1,225 @@ +#ifndef _NORFLASH_ASYNC_API_H_ +#define _NORFLASH_ASYNC_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_norflash.h" + +#define FLASH_SECTOR_SIZE 4096 + +enum NORFLASH_API_MODULE_ID_T +{ + NORFLASH_API_MODULE_ID_LOG_DUMP, + NORFLASH_API_MODULE_ID_USERDATA, + NORFLASH_API_MODULE_ID_OTA, + NORFLASH_API_MODULE_ID_OTA_UPGRADE_LOG, + NORFLASH_API_MODULE_ID_FREE, + NORFLASH_API_MODULE_ID_CRASH_DUMP, + NORFLASH_API_MODULE_ID_COREDUMP, + NORFLASH_API_MODULE_ID_FACTORY, + NORFLASH_API_MODULE_ID_HOTWORD_MODEL, + NORFLASH_API_MODULE_ID_USERDATA_EXT, + NORFLASH_API_MODULE_ID_INTERACTION_OTA, + NORFLASH_API_MODULE_ID_GMA_OTA, + NORFLASH_API_MODULE_ID_COUNT, +}; + +enum NORFLASH_API_RET_T +{ + NORFLASH_API_OK, + NORFLASH_API_BUFFER_FULL, + NORFLASH_API_BAD_DEV_ID, + NORFLASH_API_BAD_MOD_ID, + NORFLASH_API_BAD_BUFF_LEN, + NORFLASH_API_BAD_ADDR, + NORFLASH_API_BAD_LEN, + NORFLASH_API_ERR_UNINIT, + NORFLASH_API_ERR_HASINIT, + NORFLASH_API_ERR, +}; + +enum NORFLASH_API_OPRATION_TYPE +{ + NORFLASH_API_WRITTING = 0x01, + NORFLASH_API_ERASING = 0x02, + NORFLASH_API_ALL = 0x03 +}; + + +typedef struct +{ + enum NORFLASH_API_OPRATION_TYPE type; + uint32_t addr; + uint32_t len; + uint32_t remain_num; + enum NORFLASH_API_RET_T result; +}NORFLASH_API_OPERA_RESULT; + +enum NORFLASH_API_STATE +{ + NORFLASH_API_STATE_UNINITED, + NORFLASH_API_STATE_IDLE, + NORFLASH_API_STATE_WRITTING, + NORFLASH_API_STATE_WRITTING_SUSPEND, + NORFLASH_API_STATE_WRITTING_RESUME, + NORFLASH_API_STATE_ERASE, + NORFLASH_API_STATE_ERASE_SUSPEND, + NORFLASH_API_STATE_ERASE_RESUME, +}; + +enum NORFLASH_API_USER +{ + NORFLASH_API_USER_CP, + NORFLASH_API_USER_COUNTS, +}; + +typedef void (* NORFLASH_API_OPERA_CB)(void* opera_result); +typedef bool (*NOFLASH_API_FLUSH_ALLOWED_CB)(void); + +typedef struct _opera_info +{ + enum NORFLASH_API_OPRATION_TYPE type; + uint32_t addr; + uint32_t len; + uint32_t w_offs; + uint32_t w_len; + uint8_t *buff; + bool lock; + struct _opera_info *next; +}OPRA_INFO; + + +typedef struct +{ + bool is_inited; + enum HAL_NORFLASH_ID_T dev_id; + enum NORFLASH_API_MODULE_ID_T mod_id; + uint32_t mod_base_addr; + uint32_t mod_len; + uint32_t mod_block_len; + uint32_t mod_sector_len; + uint32_t mod_page_len; + uint32_t buff_len; + NORFLASH_API_OPERA_CB cb_func; + OPRA_INFO *opera_info; + OPRA_INFO *cur_opera_info; + enum NORFLASH_API_STATE state; +}MODULE_INFO; + +typedef struct +{ + bool is_inited; + MODULE_INFO mod_info[NORFLASH_API_MODULE_ID_COUNT]; + enum NORFLASH_API_MODULE_ID_T cur_mod_id; + MODULE_INFO* cur_mod; + NOFLASH_API_FLUSH_ALLOWED_CB allowed_cb[NORFLASH_API_USER_COUNTS]; +}NORFLASH_API_INFO; + +#if defined(FLASH_API_SIMPLE) +#define NORFLASH_API_WRITE_BUFF_LEN (0) +#endif +#if defined(FLASH_API_HIGHPERFORMANCE) +#define NORFLASH_API_WRITE_BUFF_LEN (4) +#endif +#if defined(FLASH_API_NORMAL) +#define NORFLASH_API_WRITE_BUFF_LEN (1) +#endif +#define NORFLASH_API_OPRA_LIST_LEN (NORFLASH_API_WRITE_BUFF_LEN + 1)*3 +#define NORFLASH_API_SECTOR_SIZE 4096 + +typedef struct +{ + bool is_used; + OPRA_INFO opera_info; +}OPERA_INFO_LIST; + +typedef struct +{ + bool is_used; + uint8_t buffer[NORFLASH_API_SECTOR_SIZE]; +}DATA_LIST; + +enum NORFLASH_API_RET_T norflash_api_init(void); + +enum NORFLASH_API_RET_T norflash_api_register( + enum NORFLASH_API_MODULE_ID_T mod_id, + enum HAL_NORFLASH_ID_T dev_id, + uint32_t mod_base_addr, + uint32_t mod_len, + uint32_t mod_block_len, + uint32_t mod_sector_len, + uint32_t mod_page_len, + uint32_t buffer_len, + NORFLASH_API_OPERA_CB cb_func + ); + +// read flash buffer or flash,priority read flash buffer. +enum NORFLASH_API_RET_T norflash_api_read( + enum NORFLASH_API_MODULE_ID_T mod_id, + uint32_t start_addr, + uint8_t *buffer, + uint32_t len + ); + +// read flash. +enum NORFLASH_API_RET_T norflash_sync_read( + enum NORFLASH_API_MODULE_ID_T mod_id, + uint32_t start_addr, + uint8_t *buffer, + uint32_t len + ); + +enum NORFLASH_API_RET_T norflash_api_erase( + enum NORFLASH_API_MODULE_ID_T mod_id, + uint32_t start_addr, + uint32_t len, + bool async + ); + +enum NORFLASH_API_RET_T norflash_api_write( + enum NORFLASH_API_MODULE_ID_T mod_id, + uint32_t start_addr, + const uint8_t *buffer, + uint32_t len, + bool async + ); + +int norflash_api_flush(void); + +bool norflash_api_buffer_is_free( + enum NORFLASH_API_MODULE_ID_T mod_id); + +uint32_t norflash_api_get_used_buffer_count( + enum NORFLASH_API_MODULE_ID_T mod_id, + enum NORFLASH_API_OPRATION_TYPE type + ); + +uint32_t norflash_api_get_free_buffer_count( + enum NORFLASH_API_OPRATION_TYPE type + ); +void norflash_api_flush_all(void); +void norflash_api_flush_disable(enum NORFLASH_API_USER user_id,uint32_t cb); +void norflash_api_flush_enable(enum NORFLASH_API_USER user_id); +void norflash_api_flush_enable_all(void); +enum NORFLASH_API_STATE norflash_api_get_state(enum NORFLASH_API_MODULE_ID_T mod_id); + +void norflash_flush_all_pending_op(void); + +void app_flush_pending_flash_op(enum NORFLASH_API_MODULE_ID_T module, + enum NORFLASH_API_OPRATION_TYPE type); + +void app_flash_page_erase(enum NORFLASH_API_MODULE_ID_T module, uint32_t flashOffset); + +void app_flash_page_program(enum NORFLASH_API_MODULE_ID_T module, + uint32_t flashOffset, + uint8_t *ptr, + uint32_t len, + bool synWrite); + +#ifdef __cplusplus +} +#endif + +#endif //_NORFLASH_ASYNC_API_H_ diff --git a/services/nv_section/Makefile b/services/nv_section/Makefile new file mode 100644 index 0000000..f8eee2d --- /dev/null +++ b/services/nv_section/Makefile @@ -0,0 +1,10 @@ +obj-y := aud_section/ +obj-y += customparam_section/ +obj-y += log_section/ +obj-y += factory_section/ + +ifeq ($(FPGA),1) +obj-y += fpga_section/ +else +obj-y += userdata_section/ +endif \ No newline at end of file diff --git a/services/nv_section/aud_section/Makefile b/services/nv_section/aud_section/Makefile new file mode 100644 index 0000000..1f1ca77 --- /dev/null +++ b/services/nv_section/aud_section/Makefile @@ -0,0 +1,12 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -I$(obj)/../../nv_section/aud_section \ + -I$(obj)/../../nv_section/include \ + -Iutils/crc32 diff --git a/services/nv_section/aud_section/aud_section.c b/services/nv_section/aud_section/aud_section.c new file mode 100644 index 0000000..b5d0f90 --- /dev/null +++ b/services/nv_section/aud_section/aud_section.c @@ -0,0 +1,215 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "hal_trace.h" +#include "aud_section.h" +#include "crc32.h" +#include "tgt_hardware.h" +#include "string.h" +#include "hal_norflash.h" +#include "cmsis.h" +#ifdef __ARMCC_VERSION +#include "link_sym_armclang.h" +#endif + +extern uint32_t __aud_start[]; + +#ifndef ANC_COEF_LIST_NUM +#define ANC_COEF_LIST_NUM 0 +#endif + +#define MAGIC_NUMBER 0xBE57 +#define USERDATA_VERSION 0x0001 + +static uint32_t section_device_length[AUDIO_SECTION_DEVICE_NUM] = { + AUDIO_SECTION_LENGTH_ANC, + AUDIO_SECTION_LENGTH_AUDIO, + AUDIO_SECTION_LENGTH_SPEECH, +}; + +static uint32_t audio_section_get_device_addr_offset(uint32_t device) +{ + ASSERT(device < AUDIO_SECTION_DEVICE_NUM, "[%s] device(%d) >= AUDIO_SECTION_DEVICE_NUM", __func__, device); + + uint32_t addr_offset = 0; + + for (uint32_t i=0; ihead.magic = MAGIC_NUMBER; + section_ptr->head.version = USERDATA_VERSION; + section_ptr->device = device; + section_ptr->cfg_len = len; + + // calculate crc + crc = crc32(0, (unsigned char *)section_ptr + AUDIO_SECTION_CFG_RESERVED_LEN, len - AUDIO_SECTION_CFG_RESERVED_LEN); + section_ptr->head.crc = crc; + + addr_start = (uint32_t)__aud_start + audio_section_get_device_addr_offset(device); + +#ifdef AUDIO_SECTION_DEBUG + TRACE(2,"[%s] len = %d", __func__, len); + TRACE(2,"[%s] addr_start = 0x%x", __func__, addr_start); + TRACE(2,"[%s] block length = 0x%x", __func__, section_device_length[device]); +#endif + + // FIXME: CHECK return value + enum HAL_NORFLASH_RET_T flash_opt_res; + uint32_t flag = int_lock(); + flash_opt_res = hal_norflash_erase(HAL_NORFLASH_ID_0, addr_start, section_device_length[device]); + int_unlock(flag); + + if (flash_opt_res) + { + TRACE(2,"[%s] ERROR: erase flash res = %d", __func__, flash_opt_res); + return flash_opt_res; + } + + flag = int_lock(); + flash_opt_res = hal_norflash_write(HAL_NORFLASH_ID_0, addr_start, (uint8_t *)section_ptr, len); + int_unlock(flag); + + if (flash_opt_res) + { + TRACE(2,"[%s] ERROR: write flash res = %d", __func__, flash_opt_res); + return flash_opt_res; + } + + +#ifdef AUDIO_SECTION_DEBUG + TRACE(1,"********************[%s]********************", __func__); + TRACE(1,"magic: 0x%x", section_ptr->head.magic); + TRACE(1,"version: 0x%x", section_ptr->head.version); + TRACE(1,"crc: 0x%x", section_ptr->head.crc); + TRACE(1,"device: %d", section_ptr->device); + TRACE(1,"cfg_len: %d", section_ptr->cfg_len); + TRACE(0,"********************END********************"); +#endif + + // audio_section_t *section_read_ptr = audio_section_get_device_ptr(device); + // check + + return 0; +} + +int audio_section_load_cfg(uint32_t device, uint8_t *cfg, uint32_t len) +{ + audio_section_t *section_ptr = audio_section_get_device_ptr(device); + uint32_t crc = 0; + +#ifdef AUDIO_SECTION_DEBUG + TRACE(1,"********************[%s]********************", __func__); + TRACE(1,"magic: 0x%x", section_ptr->head.magic); + TRACE(1,"version: 0x%x", section_ptr->head.version); + TRACE(1,"crc: 0x%x", section_ptr->head.crc); + TRACE(1,"device: %d", section_ptr->device); + TRACE(1,"cfg_len: %d", section_ptr->cfg_len); + TRACE(0,"********************END********************"); +#endif + + if(section_ptr->head.magic != MAGIC_NUMBER) + { + TRACE(3,"[%s] WARNING: Different magic number (%x != %x)", __func__, section_ptr->head.magic, MAGIC_NUMBER); + return -1; + } + + // Calculate crc and check crc value + crc = crc32(0, (unsigned char *)section_ptr + AUDIO_SECTION_CFG_RESERVED_LEN, len - AUDIO_SECTION_CFG_RESERVED_LEN); + + if(section_ptr->head.crc != crc) + { + TRACE(3,"[%s] WARNING: Different crc (%x != %x)", __func__, section_ptr->head.crc, crc); + return -2; + } + + if(section_ptr->device != device) + { + TRACE(3,"[%s] WARNING: Different device (%d != %d)", __func__, section_ptr->device, device); + return -3; + } + + if(section_ptr->cfg_len != len) + { + TRACE(3,"[%s] WARNING: Different length (%d != %d)", __func__, section_ptr->cfg_len, len); + return -4; + } + + memcpy(cfg, section_ptr, len); + + return 0; +} + +int anccfg_loadfrom_audsec(const struct_anc_cfg *list[], const struct_anc_cfg *list_44p1k[], uint32_t count) +{ +#ifdef PROGRAMMER + + return 1; + +#else // !PROGRAMMER + +#ifdef CHIP_BEST1000 + ASSERT(0, "[%s] Can not support anc load in this branch!!!", __func__); +#else + unsigned int re_calc_crc,i; + const pctool_aud_section *audsec_ptr; + + audsec_ptr = (pctool_aud_section *)__aud_start; + TRACE(3,"0x%x,0x%x,0x%x",audsec_ptr->sec_head.magic,audsec_ptr->sec_head.version,audsec_ptr->sec_head.crc); + if (audsec_ptr->sec_head.magic != aud_section_magic) { + TRACE(0,"Invalid aud section - magic"); + return 1; + } + re_calc_crc = crc32(0,(unsigned char *)&(audsec_ptr->sec_body),sizeof(audsec_body)-4); + if (re_calc_crc != audsec_ptr->sec_head.crc){ + TRACE(0,"crc verify failure, invalid aud section."); + return 1; + } + TRACE(0,"Valid aud section."); + for(i=0;isec_body.anc_config.anc_config_arr[i].anc_cfg[PCTOOL_SAMPLERATE_48X8K]); +#if (AUD_SECTION_STRUCT_VERSION == 3) + for(i=0;isec_body.anc_config.anc_config_arr[i].anc_cfg[PCTOOL_SAMPLERATE_48X8K]); +#else + for(i=0;isec_body.anc_config.anc_config_arr[i].anc_cfg[PCTOOL_SAMPLERATE_44_1X8K]); +#endif +#endif + + return 0; + +#endif // !PROGRAMMER +} + diff --git a/services/nv_section/aud_section/aud_section.h b/services/nv_section/aud_section/aud_section.h new file mode 100644 index 0000000..c7d1616 --- /dev/null +++ b/services/nv_section/aud_section/aud_section.h @@ -0,0 +1,204 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __aud_section_h__ +#define __aud_section_h__ + +#include "section_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define aud_section_debug +#ifdef aud_section_debug +#define aud_trace TRACE +#else +#define aud_trace(...) +#endif +#include "hal_aud.h" +#define audsec_tag "audsec_tag" + +#define aud_section_magic 0xdad1 +#define aud_section_struct_version 1 + +#define AUD_COEF_LEN (500) +#if (AUD_SECTION_STRUCT_VERSION == 1) +#define AUD_IIR_NUM (6) +#elif (AUD_SECTION_STRUCT_VERSION == 2) +#define AUD_IIR_NUM (8) +#elif (AUD_SECTION_STRUCT_VERSION == 3) +#define AUD_IIR_NUM (8) +#else +#error "Can not support this version!!!" +#endif + +typedef struct _anc_rir_coefs { + int32_t coef_b[3]; + int32_t coef_a[3]; +} anc_iir_coefs; + +typedef struct _aud_item { + int32_t total_gain; + + uint16_t iir_bypass_flag; + uint16_t iir_counter; + anc_iir_coefs iir_coef[AUD_IIR_NUM]; + +#if (AUD_SECTION_STRUCT_VERSION == 1) + uint16_t fir_bypass_flag; + uint16_t fir_len; + int16_t fir_coef[AUD_COEF_LEN]; + int8_t pos_tab[16]; +#elif (AUD_SECTION_STRUCT_VERSION == 2) + int32_t reserved_for_drc[32]; +#elif (AUD_SECTION_STRUCT_VERSION == 3) + +#endif + int16_t reserved1; + int8_t dac_gain_offset; // in qdb (quater of dB) + int8_t adc_gain_offset; // in qdb (quater of dB) +} aud_item; + +typedef struct { +#if (AUD_SECTION_STRUCT_VERSION == 1) + aud_item anc_cfg_ff_l; + aud_item anc_cfg_ff_r; + aud_item anc_cfg_fb_l; + aud_item anc_cfg_fb_r; +#elif (AUD_SECTION_STRUCT_VERSION == 2) + aud_item anc_cfg_ff_l; + aud_item anc_cfg_ff_r; + aud_item anc_cfg_fb_l; + aud_item anc_cfg_fb_r; + + aud_item anc_cfg_tt_l; + aud_item anc_cfg_tt_r; + aud_item anc_cfg_mc_l; + aud_item anc_cfg_mc_r; +#elif (AUD_SECTION_STRUCT_VERSION == 3) + aud_item anc_cfg_ff_l; + aud_item anc_cfg_fb_l; + aud_item anc_cfg_tt_l; + aud_item anc_cfg_mc_l; +#endif + +} struct_anc_cfg; + +enum ANC_INDEX { + ANC_INDEX_0 = 0, + ANC_INDEX_1, + ANC_INDEX_2, + ANC_INDEX_3, + ANC_INDEX_TOTAL, +}; + +typedef struct { + unsigned char anc_ver[16]; + unsigned char batch_info[16]; + unsigned char serial[16]; +} anc_ident; + +enum auditem_sample_enum_t { +#if (AUD_SECTION_STRUCT_VERSION == 3) + PCTOOL_SAMPLERATE_48X8K, +#else + PCTOOL_SAMPLERATE_44_1X8K, + PCTOOL_SAMPLERATE_48X8K, + PCTOOL_SAMPLERATE_50_7X8K = PCTOOL_SAMPLERATE_48X8K, +#endif + PCTOOL_AUDITEM_SAMPLERATE_COUNT +}; + +typedef struct { + struct_anc_cfg anc_cfg[PCTOOL_AUDITEM_SAMPLERATE_COUNT]; +} pctool_struct_anc_cfg; + +#if (AUD_SECTION_STRUCT_VERSION == 3) +#define PCTOOL_ANC_APPMODE_COUNT 15 +#define ANC_SECTIONE_SIZE (16*1024) +#else +#define PCTOOL_ANC_APPMODE_COUNT 4 +#define ANC_SECTIONE_SIZE (64*1024) +#endif + +typedef struct { + pctool_struct_anc_cfg anc_config_arr[PCTOOL_ANC_APPMODE_COUNT]; +} pctool_anc_config_t; + +#define PCTOOL_AUDSEC_RESERVED_LEN (ANC_SECTIONE_SIZE -sizeof(section_head_t) - sizeof(anc_ident) - sizeof(pctool_anc_config_t)) + +typedef struct { + anc_ident ancIdent; + pctool_anc_config_t anc_config; + unsigned char reserved[PCTOOL_AUDSEC_RESERVED_LEN]; +} audsec_body; + +typedef struct { + section_head_t sec_head; + audsec_body sec_body; +} pctool_aud_section; + +typedef struct { + uint8_t io_pin; + uint8_t set_flag; +} pctool_iocfg; +/* +typedef struct{ + uint8_t digmic_ck_iomux_pin; + uint8_t digmic_d0_iomux_pin; + uint8_t digmic_d1_iomux_pin; + uint8_t digmic_d2_iomux_pin; + uint8_t digmic_phase; +}digital_mic_cfg; +*/ + +// Add audio and speech support +#define AUDIO_SECTION_DEBUG + +// Device +#define AUDIO_SECTION_DEVICE_ANC (0) +#define AUDIO_SECTION_DEVICE_AUDIO (1) +#define AUDIO_SECTION_DEVICE_SPEECH (2) +#define AUDIO_SECTION_DEVICE_NUM (3) + +// If add device, need add length to section_device_length +#define AUDIO_SECTION_LENGTH_ANC (1024*8) +#define AUDIO_SECTION_LENGTH_AUDIO (1024*8) +#define AUDIO_SECTION_LENGTH_SPEECH (1024*8) + +#define AUDIO_SECTION_CFG_RESERVED_LEN (sizeof(audio_section_t)) + +typedef struct { + section_head_t head; + uint32_t device; + uint32_t cfg_len; +} audio_section_t; + +// README: Important!!!!!! +// App cfg struecture must define reserved like follow: +// typedef struct { +// uint8_t reserved[AUDIO_SECTION_CFG_RESERVED_LEN]; +// custom_cfg_t custom_cfg; +// } audio_section_custom_cfg_t; + +int audio_section_store_cfg(uint32_t device, uint8_t *cfg, uint32_t len); +int audio_section_load_cfg(uint32_t device, uint8_t *cfg, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/nv_section/aud_section/aud_section_inc.h b/services/nv_section/aud_section/aud_section_inc.h new file mode 100644 index 0000000..9a3eb94 --- /dev/null +++ b/services/nv_section/aud_section/aud_section_inc.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __aud_section_inc_h__ +#define __aud_section_inc_h__ +#ifdef __cplusplus +extern "C" { +#endif + +#include "aud_section.h" + +int anccfg_loadfrom_audsec(const struct_anc_cfg *list[], const struct_anc_cfg *list_44p1k[], uint32_t count); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/services/nv_section/customparam_section/Makefile b/services/nv_section/customparam_section/Makefile new file mode 100644 index 0000000..95b10db --- /dev/null +++ b/services/nv_section/customparam_section/Makefile @@ -0,0 +1,13 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -I$(obj)/../../nv_section/customparam_section \ + -I$(obj)/../../nv_section/include \ + -I$(obj)/../platform/cmsis/inc \ + -Iutils/crc32 diff --git a/services/nv_section/customparam_section/customparam_section.c b/services/nv_section/customparam_section/customparam_section.c new file mode 100644 index 0000000..b6c780f --- /dev/null +++ b/services/nv_section/customparam_section/customparam_section.c @@ -0,0 +1,114 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "hal_trace.h" +#include "customparam_section.h" +#include + +extern uint32_t __custom_parameter_start[]; + +static uint8_t isCustomParamSectionValid = false; + +void nv_custom_parameter_section_init(void) +{ + isCustomParamSectionValid = false; + + if (CUSTOMPARAM_MAGIC_CODE == + ((CUSTOM_PARAM_SECTION_HEADER_T *)__custom_parameter_start)->magic_code) + { + // check whether the length is correct + uint8_t* startLogicAddr = (uint8_t *)__custom_parameter_start; + + CUSTOM_PARAM_SECTION_HEADER_T* pSectoinHeader = + (CUSTOM_PARAM_SECTION_HEADER_T *)startLogicAddr; + + uint32_t totalDataLen = OFFSETOF(CUSTOM_PARAM_SECTION_HEADER_T, entryCount) + + pSectoinHeader->length; + + if (totalDataLen > CUSTOMPARAM_SECTION_SIZE) + { + return; + } + + uint32_t offset = sizeof(CUSTOM_PARAM_SECTION_HEADER_T); + for (uint32_t entry = 0;entry < pSectoinHeader->entryCount;entry++) + { + CUSTOM_PARAM_ENTRY_HEADER_T* pEntryHeader = + (CUSTOM_PARAM_ENTRY_HEADER_T *)((uint8_t *)__custom_parameter_start + offset); + offset += (sizeof(CUSTOM_PARAM_ENTRY_HEADER_T) + pEntryHeader->paramLen); + if (offset > CUSTOMPARAM_SECTION_SIZE) + { + return; + } + } + + isCustomParamSectionValid = true; + + uint8_t serialNumber[CUSTOM_PARAM_SERIAL_NUM_LEN]; + uint32_t serialNumParamLen = 0; + bool isSuccessfullyLoaded = nv_custom_parameter_section_get_entry(CUSTOM_PARAM_SERIAL_NUM_INDEX, serialNumber, + &serialNumParamLen); + if (isSuccessfullyLoaded) + { + TRACE(0,"Serial number is:"); + DUMP8("%02x ", serialNumber, sizeof(serialNumber)); + } + } +} + +bool nv_custom_parameter_section_get_entry(uint16_t paramIndex, uint8_t* pParamVal, uint32_t* pParamLen) +{ + if (isCustomParamSectionValid) + { + uint8_t* startLogicAddr = (uint8_t *)__custom_parameter_start; + + CUSTOM_PARAM_SECTION_HEADER_T* pSectoinHeader = + (CUSTOM_PARAM_SECTION_HEADER_T *)startLogicAddr; + + uint32_t offset = sizeof(CUSTOM_PARAM_SECTION_HEADER_T); + for (uint32_t entry = 0;entry < pSectoinHeader->entryCount;entry++) + { + CUSTOM_PARAM_ENTRY_HEADER_T* pEntryHeader = + (CUSTOM_PARAM_ENTRY_HEADER_T *)((uint8_t *)__custom_parameter_start + offset); + if (paramIndex == pEntryHeader->paramIndex) + { + memcpy(pParamVal, ((uint8_t *)pEntryHeader)+sizeof(CUSTOM_PARAM_ENTRY_HEADER_T), + pEntryHeader->paramLen); + *pParamLen = pEntryHeader->paramLen; + return true; + } + offset += (sizeof(CUSTOM_PARAM_ENTRY_HEADER_T) + pEntryHeader->paramLen); + } + } + + return false; +} + +#if defined(BISTO_ENABLED)||defined(GFPS_ENABLED) +uint32_t Get_ModelId(void) +{ + uint8_t Model_ID[CUSTOM_PARAM_Model_ID_LEN]; + uint32_t ModelIdValue, Model_ID_ParamLen = 0; + if(nv_custom_parameter_section_get_entry( CUSTOM_PARAM_Mode_ID_INDEX, + Model_ID, &Model_ID_ParamLen)) + { + ModelIdValue = (Model_ID[0]<<16) | (Model_ID[1]<<8) | Model_ID[2]; + TRACE(1,"Model id is :0x%08x\n",ModelIdValue); + return ModelIdValue; + } + return 0; +} +#endif diff --git a/services/nv_section/customparam_section/customparam_section.h b/services/nv_section/customparam_section/customparam_section.h new file mode 100644 index 0000000..60da94c --- /dev/null +++ b/services/nv_section/customparam_section/customparam_section.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __CUSTOMPARAM_SECTION_H__ +#define __CUSTOMPARAM_SECTION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +// Could be customized +#define CUSTOMPARAM_MAGIC_CODE 0x54534542 +#define CUSTOMPARAM_VERSION 1 + +#define CUSTOMPARAM_SECTION_SIZE 4096 // one flash page + +typedef struct +{ + uint32_t magic_code; // fixed value as CUSTOMPARAM_MAGIC_CODE + uint16_t version; + uint16_t length; // length in bytes of the following data in the section + uint16_t entryCount; + // following are parameter entries + +} __attribute__((packed)) CUSTOM_PARAM_SECTION_HEADER_T; + +typedef struct +{ + uint16_t paramIndex; + uint16_t paramLen; + // following are the parameter content with length paramLen +} __attribute__((packed)) CUSTOM_PARAM_ENTRY_HEADER_T; + +#define CUSTOM_PARAM_Mode_ID_INDEX 0 +#define CUSTOM_PARAM_Model_ID_LEN 3 + +#define CUSTOM_PARAM_SERIAL_NUM_INDEX 0 +#define CUSTOM_PARAM_SERIAL_NUM_LEN 16 +typedef struct +{ + uint8_t sn[CUSTOM_PARAM_SERIAL_NUM_LEN]; +} CUSTOM_PARAM_SERIAL_NUM_T; + +// TODO: +// Add your own custom parameters here + + +void nv_custom_parameter_section_init(void); +bool nv_custom_parameter_section_get_entry( + uint16_t paramIndex, uint8_t* pParamVal, uint32_t* pParamLen); +uint32_t Get_ModelId(void); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/services/nv_section/factory_section/Makefile b/services/nv_section/factory_section/Makefile new file mode 100644 index 0000000..75afec6 --- /dev/null +++ b/services/nv_section/factory_section/Makefile @@ -0,0 +1,16 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -Iplatform/cmsis/inc \ + -Iplatform/hal \ + -Iplatform/drivers/ana \ + -Iutils/heap \ + -Iutils/crc32 \ + -Iservices/norflash_api + diff --git a/services/nv_section/factory_section/factory_section.c b/services/nv_section/factory_section/factory_section.c new file mode 100644 index 0000000..5c3203c --- /dev/null +++ b/services/nv_section/factory_section/factory_section.c @@ -0,0 +1,273 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis.h" +#include "plat_types.h" +#include "tgt_hardware.h" +#include "string.h" +#include "crc32.h" +#include "factory_section.h" +#include "pmu.h" +#include "hal_trace.h" +#include "hal_norflash.h" +#include "norflash_api.h" +#include "heap_api.h" + +extern uint32_t __factory_start[]; +extern uint32_t __factory_end[]; + +static factory_section_t *factory_section_p = NULL; +static uint8_t nv_record_dev_rev = nvrec_current_version; + +#ifndef BTIF_BD_ADDR_SIZE +#define BTIF_BD_ADDR_SIZE 6 +#endif +static void factory_callback(void* param) +{ + NORFLASH_API_OPERA_RESULT *opera_result; + + opera_result = (NORFLASH_API_OPERA_RESULT*)param; + + TRACE(5,"%s:type = %d, addr = 0x%x,len = 0x%x,result = %d.", + __func__, + opera_result->type, + opera_result->addr, + opera_result->len, + opera_result->result); +} + +void factory_section_init(void) +{ + enum NORFLASH_API_RET_T result; + uint32_t sector_size = 0; + uint32_t block_size = 0; + uint32_t page_size = 0; + + hal_norflash_get_size(HAL_NORFLASH_ID_0, + NULL, + &block_size, + §or_size, + &page_size); + result = norflash_api_register(NORFLASH_API_MODULE_ID_FACTORY, + HAL_NORFLASH_ID_0, + ((uint32_t)__factory_start)&0x00FFFFFF, + (uint32_t)__factory_end - (uint32_t)__factory_start, + block_size, + sector_size, + page_size, + FACTORY_SECTOR_SIZE, + factory_callback + ); + ASSERT(result == NORFLASH_API_OK,"nv_record_init: module register failed! result = %d.",result); +} + +int factory_section_open(void) +{ + factory_section_p = (factory_section_t *)__factory_start; + + if (factory_section_p->head.magic != nvrec_dev_magic){ + factory_section_p = NULL; + return -1; + } + if ((factory_section_p->head.version < nvrec_mini_version) || + (factory_section_p->head.version > nvrec_current_version)) + { + factory_section_p = NULL; + return -1; + } + + nv_record_dev_rev = factory_section_p->head.version; + + if (1 == nv_record_dev_rev) + { + if (factory_section_p->head.crc != + crc32(0,(unsigned char *)(&(factory_section_p->head.reserved0)), + sizeof(factory_section_t)-2-2-4-(5+63+2+2+2+1+8)*sizeof(int))){ + factory_section_p = NULL; + return -1; + } + + memcpy(bt_addr, factory_section_p->data.bt_address, BTIF_BD_ADDR_SIZE); + memcpy(ble_addr, factory_section_p->data.ble_address, BTIF_BD_ADDR_SIZE); + TRACE(2,"%s sucess btname:%s", __func__, factory_section_p->data.device_name); + } + else + { + // check the data length + if (((uint32_t)(&((factory_section_t *)0)->data.rev2_reserved0)+ + factory_section_p->data.rev2_data_len) > 4096) + { + TRACE(1,"nv rec dev data len %d has exceeds the facory sector size!.", + factory_section_p->data.rev2_data_len); + return -1; + } + + if (factory_section_p->data.rev2_crc != + crc32(0,(unsigned char *)(&(factory_section_p->data.rev2_reserved0)), + factory_section_p->data.rev2_data_len)){ + factory_section_p = NULL; + return -1; + } + + + memcpy(bt_addr, factory_section_p->data.rev2_bt_addr, BTIF_BD_ADDR_SIZE); + memcpy(ble_addr, factory_section_p->data.rev2_ble_addr, BTIF_BD_ADDR_SIZE); + TRACE(2,"%s sucess btname:%s", __func__, (char *)factory_section_p->data.rev2_bt_name); + } + + DUMP8("%02x ", bt_addr, 6); + DUMP8("%02x ", ble_addr, 6); + return 0; +} + +uint8_t* factory_section_get_bt_address(void) +{ + if (factory_section_p) + { + if (1 == nv_record_dev_rev) + { + return (uint8_t *)&(factory_section_p->data.bt_address); + } + else + { + return (uint8_t *)&(factory_section_p->data.rev2_bt_addr); + } + } + else + { + return NULL; + } +} + +uint8_t* factory_section_get_bt_name(void) +{ + if (factory_section_p) + { + if (1 == nv_record_dev_rev) + { + return (uint8_t *)&(factory_section_p->data.device_name); + } + else + { + return (uint8_t *)&(factory_section_p->data.rev2_bt_name); + } + } + else + { + return (uint8_t *)BT_LOCAL_NAME; + } +} + +uint8_t* factory_section_get_ble_name(void) +{ + if (factory_section_p) + { + if (1 == nv_record_dev_rev) + { + return (uint8_t *)BLE_DEFAULT_NAME; + } + else + { + return (uint8_t *)&(factory_section_p->data.rev2_ble_name); + } + } + else + { + return (uint8_t *)BLE_DEFAULT_NAME; + } +} + +uint32_t factory_section_get_version(void) +{ + if (factory_section_p) + { + return nv_record_dev_rev; + } + + return 0; +} + +int factory_section_xtal_fcap_get(unsigned int *xtal_fcap) +{ + if (factory_section_p){ + if (1 == nv_record_dev_rev) + { + *xtal_fcap = factory_section_p->data.xtal_fcap; + } + else + { + *xtal_fcap = factory_section_p->data.rev2_xtal_fcap; + } + return 0; + }else{ + return -1; + } +} + +int factory_section_xtal_fcap_set(unsigned int xtal_fcap) +{ + uint8_t *mempool = NULL; + uint32_t lock; + enum NORFLASH_API_RET_T ret; + + if (factory_section_p){ + TRACE(1,"factory_section_xtal_fcap_set:%d", xtal_fcap); + syspool_init(); + syspool_get_buff((uint8_t **)&mempool, 0x1000); + memcpy(mempool, factory_section_p, 0x1000); + if (1 == nv_record_dev_rev) + { + ((factory_section_t *)mempool)->data.xtal_fcap = xtal_fcap; + ((factory_section_t *)mempool)->head.crc = crc32(0,(unsigned char *)(&(((factory_section_t *)mempool)->head.reserved0)),sizeof(factory_section_t)-2-2-4); + } + else + { + ((factory_section_t *)mempool)->data.rev2_xtal_fcap = xtal_fcap; + ((factory_section_t *)mempool)->data.rev2_crc = + crc32(0,(unsigned char *)(&(factory_section_p->data.rev2_reserved0)), + factory_section_p->data.rev2_data_len); + } + lock = int_lock_global(); + + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_FACTORY,(uint32_t)(__factory_start)&0x00FFFFFF,0x1000,false); + ASSERT(ret == NORFLASH_API_OK,"factory_section_xtal_fcap_set: erase failed! ret = %d.",ret); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_FACTORY,(uint32_t)(__factory_start)&0x00FFFFFF,(uint8_t *)mempool,0x1000,false); + ASSERT(ret == NORFLASH_API_OK,"factory_section_xtal_fcap_set: write failed! ret = %d.",ret); + + int_unlock_global(lock); + + return 0; + }else{ + return -1; + } +} + +void factory_section_original_btaddr_get(uint8_t *btAddr) +{ + if(factory_section_p){ + TRACE(0,"get factory_section_p"); + if (1 == nv_record_dev_rev) + { + memcpy(btAddr, factory_section_p->data.bt_address, BTIF_BD_ADDR_SIZE); + } + else + { + memcpy(btAddr, factory_section_p->data.rev2_bt_addr, BTIF_BD_ADDR_SIZE); + } + }else{ + TRACE(0,"get bt_addr"); + memcpy(btAddr, bt_addr, BTIF_BD_ADDR_SIZE); + } +} diff --git a/services/nv_section/factory_section/factory_section.h b/services/nv_section/factory_section/factory_section.h new file mode 100644 index 0000000..6dea1d3 --- /dev/null +++ b/services/nv_section/factory_section/factory_section.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __FACTORY_SECTIONS_H__ +#define __FACTORY_SECTIONS_H__ + +#define ALIGN4 __attribute__((aligned(4))) +#define nvrec_mini_version 1 +#define nvrec_dev_magic 0xba80 +#define nvrec_current_version 2 +#define FACTORY_SECTOR_SIZE 4096 +typedef struct{ + unsigned short magic; + unsigned short version; + unsigned int crc ; + unsigned int reserved0; + unsigned int reserved1; +}section_head_t; + +typedef struct{ + unsigned char device_name[248+1] ALIGN4; + unsigned char bt_address[8] ALIGN4; + unsigned char ble_address[8] ALIGN4; + unsigned char tester_address[8] ALIGN4; + unsigned int xtal_fcap ALIGN4; + unsigned int rev1_data_len; + + unsigned int rev2_data_len; + unsigned int rev2_crc; + unsigned int rev2_reserved0; + unsigned int rev2_reserved1; + unsigned int rev2_bt_name[63]; + unsigned int rev2_bt_addr[2]; + unsigned int rev2_ble_addr[2]; + unsigned int rev2_dongle_addr[2]; + unsigned int rev2_xtal_fcap; + unsigned int rev2_ble_name[8]; +}factory_section_data_t; + +typedef struct{ + section_head_t head; + factory_section_data_t data; +}factory_section_t; + +#ifdef __cplusplus +extern "C" { +#endif + +void factory_section_init(void); +int factory_section_open(void); +void factory_section_original_btaddr_get(uint8_t *btAddr); +int factory_section_xtal_fcap_get(unsigned int *xtal_fcap); +int factory_section_xtal_fcap_set(unsigned int xtal_fcap); +uint8_t* factory_section_get_bt_address(void); +uint8_t* factory_section_get_bt_name(void); +uint8_t* factory_section_get_ble_name(void); +uint32_t factory_section_get_version(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/nv_section/fpga_section/Makefile b/services/nv_section/fpga_section/Makefile new file mode 100644 index 0000000..9534b5e --- /dev/null +++ b/services/nv_section/fpga_section/Makefile @@ -0,0 +1,39 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -I$(obj)/../../nv_section/fpga_section \ + -I$(obj)/../../nv_section/include \ + -I$(obj)/../platform/cmsis/inc \ + -Iutils/crc32 \ + $(BT_IF_INCLUDES) \ + -Iutils/hexdump \ + -Iapps/key \ + -Iservices/bt_app \ + -Iplatform/drivers/ana \ + -Iservices/nv_section/customparam_section \ + -Iservices/ble_stack/common/api \ + -Iservices/ble_stack/ble_ip \ + -Iutils/heap \ + -Iservices/nvrecord \ + -Iservices/norflash_api \ + -Iservices/nv_setion/userdata_section \ + -Iplatform/drivers/norflash \ + -Iplatform/hal \ + -Iplatform/cmsis/inc + +ccflags-y += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) + +ifeq ($(FLASH_SUSPEND),1) +ccflags-y += -DFLASH_SUSPEND +endif + +ifeq ($(TX_IQ_CAL),1) +subdir-ccflags-y += -DTX_IQ_CAL +endif + diff --git a/services/nv_section/fpga_section/nvrecord_ble.c b/services/nv_section/fpga_section/nvrecord_ble.c new file mode 100644 index 0000000..16073e9 --- /dev/null +++ b/services/nv_section/fpga_section/nvrecord_ble.c @@ -0,0 +1,440 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) +#include +#include +#include +#include "nvrecord_extension.h" +#include "nvrecord_ble.h" +#include "hal_trace.h" +#include "co_math.h" +#include "tgt_hardware.h" +#include "hal_timer.h" +#include "besbt.h" + +#define ble_nv_debug +#ifdef ble_nv_debug +#define ble_trace TRACE +#else +#define ble_trace +#endif + +static NV_RECORD_PAIRED_BLE_DEV_INFO_T *nvrecord_ble_p = NULL; +static uint8_t INVALID_ADDR[BTIF_BD_ADDR_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +void nvrecord_rebuild_paired_ble_dev_info(NV_RECORD_PAIRED_BLE_DEV_INFO_T *pPairedBtInfo) +{ + memset(( uint8_t * )pPairedBtInfo, 0, sizeof(NV_RECORD_PAIRED_BLE_DEV_INFO_T)); + pPairedBtInfo->saved_list_num = 0; //init saved num + + uint8_t index; + //avoid ble irk collision low probability + uint32_t generatedSeed = hal_sys_timer_get(); + for (uint8_t index = 0; index < sizeof(bt_addr); index++) + { + generatedSeed ^= (((uint32_t)(bt_addr[index])) << (hal_sys_timer_get() & 0xF)); + } + srand(generatedSeed); + + // generate a new IRK + for (index = 0; index < BLE_IRK_SIZE; index++) + { + pPairedBtInfo->self_info.ble_irk[index] = ( uint8_t )co_rand_word(); + } +} + +static bool blerec_specific_value_prepare(const BleDeviceinfo *param_rec) +{ + // Preparations before adding new ble record: + // 1. If not existing. Check the record count. If it's BLE_RECORD_NUM, + // move 0-(BLE_RECORD_NUM-2) right side by one slot, to discard the last one and + // leave slot 0, decrease the record number. + // If it's smaller than BLE_RECORD_NUM, move 0-(count-1) right side by one slot, leave slot 0, + // don't change the record number. + // 2. If existing already and the location is entryToFree , move 0-(entryToFree-1) + // right side by one slot, leave slot 0. Decrease the record number for adding the new one. + + bool isEntryExisting = false; + uint8_t entryToFree = 0; + NV_RECORD_PAIRED_BLE_DEV_INFO_T *dest_ptr; + + dest_ptr = nvrecord_ble_p; + TRACE(3,"%s start search addr %p list_num=%d", __func__, dest_ptr, dest_ptr->saved_list_num); + + if (dest_ptr->saved_list_num > 0) + { + for (uint8_t i = 0; i < dest_ptr->saved_list_num; i++) + { + if (0 == memcmp(dest_ptr->ble_nv[i].peer_bleAddr, param_rec->peer_bleAddr, BLE_ADDR_SIZE)) + { + ble_trace(2,"%s Find the existing entry %d", __func__, i); + DUMP8("%02x ", ( uint8_t * )param_rec, sizeof(BleDeviceinfo)); + DUMP8("%02x ", ( uint8_t * )&dest_ptr->ble_nv[i], sizeof(BleDeviceinfo)); + if (!memcmp(( uint8_t * )param_rec, ( uint8_t * )&dest_ptr->ble_nv[i], sizeof(BleDeviceinfo))) + { + ble_trace(0,"The new coming BLE device info is the same as the recorded."); + return false; + } + memset(&(dest_ptr->ble_nv[i]), 0, sizeof(BleDeviceinfo)); + entryToFree = i; + dest_ptr->saved_list_num--; + isEntryExisting = true; + break; + } + } + } + else + { + return true; + } + + if (!isEntryExisting) + { + if (BLE_RECORD_NUM == dest_ptr->saved_list_num) + { + TRACE(0,"<=====>blerec list is full,delete the oldest and add param_rec to list"); + for (uint8_t k = 0; k < BLE_RECORD_NUM - 1; k++) + { + memcpy(&(dest_ptr->ble_nv[BLE_RECORD_NUM - 1 - k]), + &(dest_ptr->ble_nv[BLE_RECORD_NUM - 2 - k]), + sizeof(BleDeviceinfo)); + } + dest_ptr->saved_list_num--; + } + else + { + for (uint8_t k = 0; k < dest_ptr->saved_list_num; k++) + { + memcpy(&(dest_ptr->ble_nv[dest_ptr->saved_list_num - k]), + &(dest_ptr->ble_nv[dest_ptr->saved_list_num - 1 - k]), + sizeof(BleDeviceinfo)); + } + } + } + else + { + for (uint8_t list_updata = 0; list_updata < entryToFree; list_updata++) + { + memcpy(&(dest_ptr->ble_nv[entryToFree - list_updata]), + &(dest_ptr->ble_nv[entryToFree - list_updata - 1]), + sizeof(BleDeviceinfo)); + } + } + + return true; +} + +void nv_record_blerec_init(void) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (NULL == nvrecord_ble_p) + { + nvrecord_ble_p = &(nvrecord_extension_p->ble_pair_info); + if (!memcmp(nvrecord_ble_p->self_info.ble_addr, INVALID_ADDR, BTIF_BD_ADDR_SIZE)) + { + memcpy(nvrecord_ble_p->self_info.ble_addr, bt_get_ble_local_address(), BTIF_BD_ADDR_SIZE); + } + } + nv_record_post_write_operation(lock); +} + +NV_RECORD_PAIRED_BLE_DEV_INFO_T* nv_record_blerec_get_ptr(void) +{ + return nvrecord_ble_p; +} + +void nv_record_blerec_get_local_irk(uint8_t *pIrk) +{ + memcpy(pIrk, nvrecord_ble_p->self_info.ble_irk, BLE_IRK_SIZE); +} + +bool nv_record_blerec_get_bd_addr_from_irk(uint8_t *pBdAddr, uint8_t *pIrk) +{ + if (nvrecord_ble_p->saved_list_num > 0) + { + for (uint8_t index = 0; index < nvrecord_ble_p->saved_list_num; index++) + { + if (!memcmp(pIrk, nvrecord_ble_p->ble_nv[index].IRK, BLE_IRK_SIZE)) + { + memcpy(pBdAddr, nvrecord_ble_p->ble_nv[index].peer_bleAddr, BLE_ADDR_SIZE); + return true; + } + } + return false; + } + else + { + return false; + } +} + +int nv_record_blerec_add(const BleDeviceinfo *param_rec) +{ + int nRet = 0; + + uint8_t isNeedToUpdateNv = true; + isNeedToUpdateNv = blerec_specific_value_prepare(param_rec); + + if (isNeedToUpdateNv) + { + uint32_t lock = nv_record_pre_write_operation(); + + //add device info into nv struct + memcpy(nvrecord_ble_p->ble_nv[0].peer_bleAddr, param_rec->peer_bleAddr, BLE_ADDR_SIZE); //addr + nvrecord_ble_p->ble_nv[0].EDIV = param_rec->EDIV; //EDIV + memcpy(nvrecord_ble_p->ble_nv[0].RANDOM, param_rec->RANDOM, BLE_ENC_RANDOM_SIZE); //RANDOM + memcpy(nvrecord_ble_p->ble_nv[0].LTK, param_rec->LTK, BLE_LTK_SIZE); //LTK + memcpy(nvrecord_ble_p->ble_nv[0].IRK, param_rec->IRK, BLE_IRK_SIZE); //IRK + nvrecord_ble_p->ble_nv[0].bonded = param_rec->bonded; //bond status + nvrecord_ble_p->saved_list_num++; //updata saved num + nv_record_post_write_operation(lock); + + nv_record_update_runtime_userdata(); + nv_record_execute_async_flush(); + TRACE(2,"%s CURRENT BLE LIST NUM=%d", __func__, nvrecord_ble_p->saved_list_num); + } + +#ifdef ble_nv_debug + for (uint8_t k = 0; k < nvrecord_ble_p->saved_list_num; k++) + { + TRACE(0,"========================================="); + TRACE(1,"Num %d BLE record:", k); + TRACE(0,"BLE addr:"); + DUMP8("%02x ", ( uint8_t * )nvrecord_ble_p->ble_nv[k].peer_bleAddr, BLE_ADDR_SIZE); + TRACE(1,"NV EDIV %d and random is:", nvrecord_ble_p->ble_nv[k].EDIV); + DUMP8("%02x ", ( uint8_t * )nvrecord_ble_p->ble_nv[k].RANDOM, BLE_ENC_RANDOM_SIZE); + TRACE(0,"NV LTK:"); + DUMP8("%02x ", ( uint8_t * )nvrecord_ble_p->ble_nv[k].LTK, BLE_LTK_SIZE); + TRACE(0,"NV irk:"); + DUMP8("%02x ", ( uint8_t * )nvrecord_ble_p->ble_nv[k].IRK, BLE_IRK_SIZE); + } +#endif + return nRet; +} + +uint8_t nv_record_ble_fill_irk(uint8_t *irkToFill) +{ + NV_RECORD_PAIRED_BLE_DEV_INFO_T *find_ptr = nvrecord_ble_p; + + if ((NULL == find_ptr) || (0 == find_ptr->saved_list_num)) + { + return 0; + } + + if (find_ptr->saved_list_num > 0) + { + for (uint8_t index = 0; index < find_ptr->saved_list_num; index++) + { + memcpy(irkToFill + index * BLE_IRK_SIZE, find_ptr->ble_nv[index].IRK, BLE_IRK_SIZE); + } + return find_ptr->saved_list_num; + } + else + { + return 0; + } +} + +//when master send encription req,if bonded,use ltk to bonding again(skip the pair step) +bool nv_record_ble_record_find_ltk_through_static_bd_addr(uint8_t *pBdAddr, uint8_t *ltk) +{ + NV_RECORD_PAIRED_BLE_DEV_INFO_T *find_ptr = nvrecord_ble_p; + + if ((NULL == find_ptr) || (0 == find_ptr->saved_list_num)) + { + TRACE(3,"%s find data failed, ptr:%x, list_num:%d", __func__, (uint32_t)find_ptr, find_ptr->saved_list_num); + return false; + } + + for (uint8_t find_index = 0; find_index < find_ptr->saved_list_num; find_index++) + { + if (!memcmp(find_ptr->ble_nv[find_index].peer_bleAddr, pBdAddr, BLE_ADDR_SIZE)) + { + ble_trace(2,"%s FIND LTK IN NV SUCCESS %p", __func__, find_ptr->ble_nv[find_index].LTK); + memcpy(ltk, find_ptr->ble_nv[find_index].LTK, BLE_LTK_SIZE); + return true; + } + } + return false; +} + +bool nv_record_ble_record_Once_a_device_has_been_bonded(void) +{ + NV_RECORD_PAIRED_BLE_DEV_INFO_T *find_ptr = nvrecord_ble_p; + + if ((NULL == find_ptr) || (0 == find_ptr->saved_list_num)) + { + return false; + } + + for (uint8_t find_index = 0; find_index < find_ptr->saved_list_num; find_index++) + { + if (find_ptr->ble_nv[find_index].bonded == true) + { + return true; + } + } + return false; +} + +void nv_record_ble_delete_entry(uint8_t *pBdAddr) +{ + NV_RECORD_PAIRED_BLE_DEV_INFO_T *find_ptr = nvrecord_ble_p; + + if ((NULL == find_ptr) || (0 == find_ptr->saved_list_num)) + { + return; + } + + int8_t indexToDelete = -1; + + for (uint8_t find_index = 0; find_index < find_ptr->saved_list_num; find_index++) + { + if (!memcmp(find_ptr->ble_nv[find_index].peer_bleAddr, pBdAddr, BLE_ADDR_SIZE)) + { + indexToDelete = find_index; + break; + } + } + + if (indexToDelete >= 0) + { + uint32_t lock = nv_record_pre_write_operation(); + + uint8_t index; + for (index = indexToDelete; index < find_ptr->saved_list_num - 1; index++) + { + memcpy(&(find_ptr->ble_nv[index]), + &(find_ptr->ble_nv[index + 1]), + sizeof(BleDeviceinfo)); + } + + memset(( uint8_t * )&(find_ptr->ble_nv[index]), 0, sizeof(BleDeviceinfo)); + find_ptr->saved_list_num--; + nv_record_update_runtime_userdata(); + nv_record_post_write_operation(lock); + } +} + +#ifdef TWS_SYSTEM_ENABLED +static bool tws_use_same_ble_addr(uint8_t *peer_ble_addr) +{ + TRACE(1,"[%s] peer addr:", __func__); + DUMP8("%x ", peer_ble_addr, BTIF_BD_ADDR_SIZE); + + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + + if (!memcmp(pNvExtRec->ble_pair_info.self_info.ble_addr, peer_ble_addr, BTIF_BD_ADDR_SIZE)) + { + return true; + } + + return false; +} + +void nv_record_extension_update_tws_ble_info(NV_RECORD_PAIRED_BLE_DEV_INFO_T *info) +{ + ASSERT(info, "null pointer received in [%s]", __func__); + + bool isNvExtentionPendingForUpdate = false; + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + + if (tws_use_same_ble_addr(info->self_info.ble_addr)) + { + if (memcmp(&pNvExtRec->ble_pair_info.self_info, &info->self_info, sizeof(BLE_BASIC_INFO_T))) + { + TRACE(0,"save the peer ble info to self_info"); + memcpy(&pNvExtRec->ble_pair_info.self_info, &info->self_info, sizeof(BLE_BASIC_INFO_T)); + nv_record_extension_update(); + isNvExtentionPendingForUpdate = true; + } + } + + if (memcmp(&pNvExtRec->tws_info.ble_info, &info->self_info, sizeof(BLE_BASIC_INFO_T))) + { + TRACE(0,"save the peer ble info to tws_info"); + memcpy(&pNvExtRec->tws_info.ble_info, &info->self_info, sizeof(BLE_BASIC_INFO_T)); + nv_record_extension_update(); + isNvExtentionPendingForUpdate = true; + } + + if (isNvExtentionPendingForUpdate) + { + nv_record_execute_async_flush(); + } + + TRACE(0,"peer addr:"); + DUMP8("0x%02x ", pNvExtRec->tws_info.ble_info.ble_addr,BTIF_BD_ADDR_SIZE); + TRACE(0,"peer irk"); + DUMP8("0x%02x ", pNvExtRec->tws_info.ble_info.ble_irk, BLE_IRK_SIZE); +} + +void nv_record_tws_exchange_ble_info(void) +{ + TRACE(1,"[%s]+++", __func__); + return; + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + uint8_t ble_address[6] = {0, 0, 0, 0, 0, 0}; + + if (tws_use_same_ble_addr(pNvExtRec->tws_info.ble_info.ble_addr)) + { + TRACE(0,"tws use same ble addr"); + return; + } + + if (!memcmp(pNvExtRec->tws_info.ble_info.ble_addr, ble_address, BTIF_BD_ADDR_SIZE)) + { + TRACE(0,"don't have tws ble addr"); + return; + } + +#ifdef BLE_USE_RPA + uint8_t temp_ble_irk[BLE_IRK_SIZE]; + memcpy(temp_ble_irk, pNvExtRec->ble_pair_info.self_info.ble_irk, BLE_IRK_SIZE); + memcpy(pNvExtRec->ble_pair_info.self_info.ble_irk, pNvExtRec->tws_info.ble_info.ble_irk, BLE_IRK_SIZE); + memcpy(pNvExtRec->tws_info.ble_info.ble_irk, temp_ble_irk, BLE_IRK_SIZE); + TRACE(0,"current local ble irk:"); + DUMP8("0x%02x ", pNvExtRec->ble_pair_info.self_info.ble_irk, BLE_IRK_SIZE); +#else + uint8_t temp_ble_addr[BTIF_BD_ADDR_SIZE]; + memcpy(temp_ble_addr, pNvExtRec->ble_pair_info.self_info.ble_addr, BTIF_BD_ADDR_SIZE); + memcpy(pNvExtRec->ble_pair_info.self_info.ble_addr, pNvExtRec->tws_info.ble_info.ble_addr, BTIF_BD_ADDR_SIZE); + memcpy(pNvExtRec->tws_info.ble_info.ble_addr, temp_ble_addr, BTIF_BD_ADDR_SIZE); + memcpy(bt_get_ble_local_address(), pNvExtRec->ble_pair_info.self_info.ble_addr, BTIF_BD_ADDR_SIZE); + TRACE(0,"current local ble addr:"); + DUMP8("0x%02x ", pNvExtRec->ble_pair_info.self_info.ble_addr, BTIF_BD_ADDR_SIZE); + + bt_set_ble_local_address(pNvExtRec->ble_pair_info.self_info.ble_addr); +#endif + + nv_record_extension_update(); + TRACE(1,"[%s]---", __func__); +} + +uint8_t *nv_record_tws_get_self_ble_info(void) +{ + TRACE(1,"[%s]+++", __func__); + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + + TRACE(0,"current local ble addr:"); + DUMP8("0x%02x ", pNvExtRec->ble_pair_info.self_info.ble_addr, BTIF_BD_ADDR_SIZE); + + TRACE(1,"[%s]---", __func__); + return pNvExtRec->ble_pair_info.self_info.ble_addr; +} +#endif + +#endif //#if defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nv_section/fpga_section/nvrecord_ble.h b/services/nv_section/fpga_section/nvrecord_ble.h new file mode 100644 index 0000000..bcaf9d7 --- /dev/null +++ b/services/nv_section/fpga_section/nvrecord_ble.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) + +#ifndef NVRECORD_BLE_H +#define NVRECORD_BLE_H + +#include "nvrecord_extension.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int nv_record_blerec_add(const BleDeviceinfo *param_rec); +bool nv_record_ble_record_find_ltk_through_static_bd_addr(uint8_t* pBdAddr, uint8_t *ltk); +bool nv_record_ble_record_Once_a_device_has_been_bonded(void); +void nv_record_ble_delete_entry(uint8_t* pBdAddr); +uint8_t nv_record_ble_fill_irk(uint8_t* ltkToFill); +void nv_record_blerec_init(void); +NV_RECORD_PAIRED_BLE_DEV_INFO_T* nv_record_blerec_get_ptr(void); +void nv_record_blerec_get_local_irk(uint8_t* pIrk); +bool nv_record_blerec_get_bd_addr_from_irk(uint8_t* pBdAddr, uint8_t* pIrk); +void nvrecord_rebuild_paired_ble_dev_info(NV_RECORD_PAIRED_BLE_DEV_INFO_T* pPairedBtInfo); + +#ifdef TWS_SYSTEM_ENABLED +void nv_record_extension_update_tws_ble_info(NV_RECORD_PAIRED_BLE_DEV_INFO_T *info); +void nv_record_tws_exchange_ble_info(void); +uint8_t *nv_record_tws_get_self_ble_info(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif +#endif // #if defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nv_section/fpga_section/nvrecord_bt.c b/services/nv_section/fpga_section/nvrecord_bt.c new file mode 100644 index 0000000..1e16034 --- /dev/null +++ b/services/nv_section/fpga_section/nvrecord_bt.c @@ -0,0 +1,455 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) +#include +#include +#include +#include "nvrecord_extension.h" +#include "nvrecord_bt.h" +#include "hal_trace.h" + +nvrec_btdevicerecord g_fpga_ram_record; +void ram_record_ddbrec_init(void) +{ + g_fpga_ram_record.record.trusted = false; +} + +bt_status_t ram_record_ddbrec_find(const bt_bdaddr_t* bd_ddr, nvrec_btdevicerecord **record) +{ + if (g_fpga_ram_record.record.trusted && \ + !memcmp(&g_fpga_ram_record.record.bdAddr.address[0], &bd_ddr->address[0], 6)) + { + *record = &g_fpga_ram_record; + return BT_STS_SUCCESS; + } + else + { + return BT_STS_FAILED; + } +} + +bt_status_t ram_record_ddbrec_add(const nvrec_btdevicerecord* param_rec) +{ + g_fpga_ram_record = *param_rec; + g_fpga_ram_record.record.trusted = true; + return BT_STS_SUCCESS; +} + +bt_status_t ram_record_ddbrec_delete(const bt_bdaddr_t *bdaddr) +{ + if (g_fpga_ram_record.record.trusted && \ + !memcmp(&g_fpga_ram_record.record.bdAddr.address[0], &bdaddr->address[0], 6)) + { + g_fpga_ram_record.record.trusted = false; + } + return BT_STS_SUCCESS; +} + +void nvrecord_rebuild_paired_bt_dev_info(NV_RECORD_PAIRED_BT_DEV_INFO_T* pPairedBtInfo) +{ + memset((uint8_t *)pPairedBtInfo, 0, sizeof(NV_RECORD_PAIRED_BT_DEV_INFO_T)); + pPairedBtInfo->pairedDevNum = 0; +} + +void nv_record_btdevicerecord_set_a2dp_profile_active_state(btdevice_profile* device_plf, bool isActive) +{ + device_plf->hsp_act = isActive; +} + +void nv_record_btdevicerecord_set_hfp_profile_active_state(btdevice_profile* device_plf, bool isActive) +{ + device_plf->hsp_act = isActive; +} + +void nv_record_btdevicerecord_set_hsp_profile_active_state(btdevice_profile* device_plf, bool isActive) +{ + device_plf->hsp_act = isActive; +} + +void nv_record_btdevicerecord_set_a2dp_profile_codec(btdevice_profile* device_plf, uint8_t a2dpCodec) +{ + device_plf->a2dp_codectype = a2dpCodec; +} + +int nv_record_get_paired_dev_count(void) +{ + if (NULL == nvrecord_extension_p) + { + return 0; + } + + return nvrecord_extension_p->bt_pair_info.pairedDevNum; +} + +/* +return: + -1: enum dev failure. + 0: without paired dev. + 1: only 1 paired dev,store@record1. + 2: get 2 paired dev.notice:record1 is the latest record. +*/ +int nv_record_enum_latest_two_paired_dev(btif_device_record_t* record1,btif_device_record_t* record2) +{ + if((NULL == record1) || (NULL == record2) || (NULL == nvrecord_extension_p)) + { + return -1; + } + + if (nvrecord_extension_p->bt_pair_info.pairedDevNum > 0) + { + if (1 == nvrecord_extension_p->bt_pair_info.pairedDevNum) + { + memcpy((uint8_t *)record1, (uint8_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[0]), + sizeof(btif_device_record_t)); + return 1; + } + else + { + memcpy((uint8_t *)record1, (uint8_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[0]), + sizeof(btif_device_record_t)); + memcpy((uint8_t *)record2, (uint8_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[1]), + sizeof(btif_device_record_t)); + return 2; + } + } + else + { + return 0; + } +} + +static void nv_record_print_dev_record(const btif_device_record_t* record) +{ + +} + +void nv_record_all_ddbrec_print(void) +{ + if (NULL == nvrecord_extension_p) + { + TRACE(0,"No BT paired dev."); + return; + } + + if (nvrecord_extension_p->bt_pair_info.pairedDevNum > 0) + { + for(uint8_t tmp_i=0; tmp_i < nvrecord_extension_p->bt_pair_info.pairedDevNum; tmp_i++) + { + btif_device_record_t record; + bt_status_t ret_status; + ret_status = nv_record_enum_dev_records(tmp_i, &record); + if (BT_STS_SUCCESS == ret_status) + { + nv_record_print_dev_record(&record); + } + } + } + else + { + TRACE(0,"No BT paired dev."); + } +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_enum_dev_records(unsigned short index,btif_device_record_t* record) +{ + btif_device_record_t *recaddr = NULL; + + if((index >= nvrecord_extension_p->bt_pair_info.pairedDevNum) || (NULL == nvrecord_extension_p)) + { + return BT_STS_FAILED; + } + + recaddr = (btif_device_record_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[index].record); + memcpy(record, recaddr, sizeof(btif_device_record_t)); + nv_record_print_dev_record(record); + return BT_STS_SUCCESS; +} + +static int8_t nv_record_get_bt_pairing_info_index(const uint8_t* btAddr) +{ + NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = + (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); + + for (uint8_t index = 0; index < pBtDevInfo->pairedDevNum; index++) + { + if (!memcmp(pBtDevInfo->pairedBtDevInfo[index].record.bdAddr.address, + btAddr, BTIF_BD_ADDR_SIZE)) + { + return (int8_t)index; + } + } + + return -1; +} + +/********************************************** +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +**********************************************/ +static bt_status_t POSSIBLY_UNUSED nv_record_ddbrec_add(const btif_device_record_t* param_rec) +{ + if ((NULL == param_rec) || (NULL == nvrecord_extension_p)) + { + return BT_STS_FAILED; + } + + uint32_t lock = nv_record_pre_write_operation(); + + bool isFlushNv = false; + + // try to find the entry + int8_t indexOfEntry = -1; + NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = + (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); + indexOfEntry = nv_record_get_bt_pairing_info_index(param_rec->bdAddr.address); + + if (-1 == indexOfEntry) + { + // don't exist, need to add to the head of the entry list + if (MAX_BT_PAIRED_DEVICE_COUNT == pBtDevInfo->pairedDevNum) + { + for (uint8_t k = 0; k < MAX_BT_PAIRED_DEVICE_COUNT - 1; k++) + { + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[MAX_BT_PAIRED_DEVICE_COUNT - 1 - k]), + (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[MAX_BT_PAIRED_DEVICE_COUNT - 2 - k]), + sizeof(nvrec_btdevicerecord)); + } + pBtDevInfo->pairedDevNum--; + } + else + { + for (uint8_t k = 0; k < pBtDevInfo->pairedDevNum; k++) + { + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[pBtDevInfo->pairedDevNum - k]), + (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[pBtDevInfo->pairedDevNum - 1 - k]), + sizeof(nvrec_btdevicerecord)); + } + } + + // fill the default value + nvrec_btdevicerecord* nvrec_pool_record = &(pBtDevInfo->pairedBtDevInfo[0]); + memcpy((uint8_t *)&(nvrec_pool_record->record), (uint8_t *)param_rec, + sizeof(btif_device_record_t)); + nvrec_pool_record->device_vol.a2dp_vol = NVRAM_ENV_STREAM_VOLUME_A2DP_VOL_DEFAULT; + nvrec_pool_record->device_vol.hfp_vol = NVRAM_ENV_STREAM_VOLUME_HFP_VOL_DEFAULT; + nvrec_pool_record->device_plf.hfp_act = false; + nvrec_pool_record->device_plf.hsp_act = false; + nvrec_pool_record->device_plf.a2dp_act = false; +#ifdef BTIF_DIP_DEVICE + nvrec_pool_record->vend_id = 0; + nvrec_pool_record->vend_id_source = 0; +#endif + + pBtDevInfo->pairedDevNum++; + + // need to flush the nv record + isFlushNv = true; + } + else + { + // exist + // check whether it's already at the head + // if not, move it to the head + if (indexOfEntry > 0) + { + nvrec_btdevicerecord record; + memcpy((uint8_t *)&record, (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry]), + sizeof(record)); + + // if not, move it to the head + for (uint8_t k = 0; k < indexOfEntry; k++) + { + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry - k]), + (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry - 1 - k]), + sizeof(nvrec_btdevicerecord)); + } + + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0]), (uint8_t *)&record, + sizeof(record)); + + // update the link info + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0].record), (uint8_t *)param_rec, + sizeof(btif_device_record_t)); + + // need to flush the nv record + isFlushNv = true; + } + // else, check whether the link info needs to be updated + else + { + if (memcmp((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0].record), + (uint8_t *)param_rec, sizeof(btif_device_record_t))) + { + // update the link info + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0].record), (uint8_t *)param_rec, + sizeof(btif_device_record_t)); + + // need to flush the nv record + isFlushNv = true; + } + } + } + + TRACE(1,"paired Bt dev:%d", pBtDevInfo->pairedDevNum); + TRACE(1,"Is to flush nv: %d", isFlushNv); + nv_record_all_ddbrec_print(); + + if (isFlushNv) + { + nv_record_update_runtime_userdata(); + } + + nv_record_post_write_operation(lock); + + return BT_STS_SUCCESS; +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_add(SECTIONS_ADP_ENUM type, void *record) +{ + bt_status_t retstatus = BT_STS_FAILED; + + if ((NULL == record) || (section_none == type)) + { + return BT_STS_FAILED; + } + + switch(type) + { + case section_usrdata_ddbrecord: + retstatus = ram_record_ddbrec_add(record); + break; + default: + break; + } + + return retstatus; +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_ddbrec_find(const bt_bdaddr_t* bd_ddr, btif_device_record_t *record) +{ + if ((NULL == bd_ddr) || (NULL == record) || (NULL == nvrecord_extension_p)) + { + return BT_STS_FAILED; + } + + int8_t indexOfEntry = -1; + NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = + (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); + indexOfEntry = nv_record_get_bt_pairing_info_index(bd_ddr->address); + + if (-1 == indexOfEntry) + { + return BT_STS_FAILED; + } + else + { + memcpy((uint8_t *)record, (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry].record), + sizeof(btif_device_record_t)); + return BT_STS_SUCCESS; + } +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_ddbrec_delete(const bt_bdaddr_t *bdaddr) +{ + ram_record_ddbrec_delete(bdaddr); + return BT_STS_SUCCESS; +} + +int nv_record_btdevicerecord_find(const bt_bdaddr_t *bd_ddr, nvrec_btdevicerecord **record) +{ + ram_record_ddbrec_find(bd_ddr, record); + return 0; +} + +void nv_record_btdevicerecord_set_a2dp_vol(nvrec_btdevicerecord* pRecord, int8_t vol) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (vol != pRecord->device_vol.a2dp_vol) + { + nv_record_update_runtime_userdata(); + pRecord->device_vol.a2dp_vol = vol; + } + + nv_record_post_write_operation(lock); +} + +void nv_record_btdevicerecord_set_hfp_vol(nvrec_btdevicerecord* pRecord, int8_t vol) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (vol != pRecord->device_vol.hfp_vol) + { + nv_record_update_runtime_userdata(); + pRecord->device_vol.hfp_vol = vol; + } + + nv_record_post_write_operation(lock); +} + +void nv_record_btdevicevolume_set_a2dp_vol(btdevice_volume* device_vol, int8_t vol) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (vol != device_vol->a2dp_vol) + { + nv_record_update_runtime_userdata(); + device_vol->a2dp_vol = vol; + } + + nv_record_post_write_operation(lock); + +} + +void nv_record_btdevicevolume_set_hfp_vol(btdevice_volume* device_vol, int8_t vol) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (vol != device_vol->hfp_vol) + { + nv_record_update_runtime_userdata(); + device_vol->hfp_vol = vol; + } + + nv_record_post_write_operation(lock); + +} + +void nv_record_btdevicerecord_set_vend_id_and_source(nvrec_btdevicerecord* pRecord, int16_t vend_id, int16_t vend_id_source) +{ +#ifdef BTIF_DIP_DEVICE + TRACE(2, "%s vend id 0x%x", __func__, vend_id); + uint32_t lock = nv_record_pre_write_operation(); + if (vend_id != pRecord->vend_id) + { + nv_record_update_runtime_userdata(); + pRecord->vend_id = vend_id; + pRecord->vend_id_source = vend_id_source; + } + + nv_record_post_write_operation(lock); +#endif +} + +#endif //#if defined(NEW_NV_RECORD_ENABLED) + diff --git a/services/nv_section/fpga_section/nvrecord_bt.h b/services/nv_section/fpga_section/nvrecord_bt.h new file mode 100644 index 0000000..1cebb37 --- /dev/null +++ b/services/nv_section/fpga_section/nvrecord_bt.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) + +#ifndef NVRECORD_BT_H +#define NVRECORD_BT_H + +#include "nvrecord_extension.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NVRAM_ENV_STREAM_VOLUME_A2DP_VOL_DEFAULT (AUDIO_OUTPUT_VOLUME_DEFAULT) +#define NVRAM_ENV_STREAM_VOLUME_HFP_VOL_DEFAULT (AUDIO_OUTPUT_VOLUME_DEFAULT) + +void nv_record_btdevicerecord_set_a2dp_vol(nvrec_btdevicerecord* pRecord, int8_t vol); +void nv_record_btdevicerecord_set_hfp_vol(nvrec_btdevicerecord* pRecord, int8_t vol); +void nv_record_btdevicevolume_set_a2dp_vol(btdevice_volume* device_vol, int8_t vol); +void nv_record_btdevicevolume_set_hfp_vol(btdevice_volume* device_vol, int8_t vol); +void nv_record_btdevicerecord_set_vend_id_and_source(nvrec_btdevicerecord* pRecord, int16_t vend_id, int16_t vend_id_source); +void nv_record_btdevicerecord_set_a2dp_profile_active_state(btdevice_profile* device_plf, bool isActive); +void nv_record_btdevicerecord_set_hfp_profile_active_state(btdevice_profile* device_plf, bool isActive); +void nv_record_btdevicerecord_set_hsp_profile_active_state(btdevice_profile* device_plf, bool isActive); +int nv_record_enum_latest_two_paired_dev(btif_device_record_t* record1,btif_device_record_t* record2); +void nv_record_all_ddbrec_print(void); +void nv_record_update_runtime_userdata(void); +void nvrecord_rebuild_paired_bt_dev_info(NV_RECORD_PAIRED_BT_DEV_INFO_T* pPairedBtInfo); +int nv_record_btdevicerecord_find(const bt_bdaddr_t *bd_ddr, nvrec_btdevicerecord **record); +void nv_record_btdevicerecord_set_a2dp_profile_codec(btdevice_profile* device_plf, uint8_t a2dpCodec); +bt_status_t nv_record_ddbrec_delete(const bt_bdaddr_t *bdaddr); +bt_status_t nv_record_enum_dev_records(unsigned short index,btif_device_record_t* record); +bt_status_t nv_record_ddbrec_find(const bt_bdaddr_t *bd_ddr, btif_device_record_t*record); +bt_status_t nv_record_add(SECTIONS_ADP_ENUM type,void *record); +int nv_record_get_paired_dev_count(void); +void ram_record_ddbrec_init(void); +bt_status_t ram_record_ddbrec_find(const bt_bdaddr_t* bd_ddr, nvrec_btdevicerecord **record); +bt_status_t ram_record_ddbrec_add(const nvrec_btdevicerecord* param_rec); +bt_status_t ram_record_ddbrec_delete(const bt_bdaddr_t *bdaddr); +#ifdef __cplusplus +} +#endif +#endif +#endif // #if defined(NEW_NV_RECORD_ENABLED) + diff --git a/services/nv_section/fpga_section/nvrecord_env.c b/services/nv_section/fpga_section/nvrecord_env.c new file mode 100644 index 0000000..f68979c --- /dev/null +++ b/services/nv_section/fpga_section/nvrecord_env.c @@ -0,0 +1,111 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) +#include +#include +#include +#include "nvrecord_extension.h" +#include "nvrecord_env.h" +#include "hal_trace.h" + +static struct nvrecord_env_t localSystemInfo; + +void nvrecord_rebuild_system_env(struct nvrecord_env_t* pSystemEnv) +{ + memset((uint8_t *)pSystemEnv, 0, sizeof(struct nvrecord_env_t)); + + pSystemEnv->media_language.language = NVRAM_ENV_MEDIA_LANGUAGE_DEFAULT; + pSystemEnv->ibrt_mode.mode = NVRAM_ENV_TWS_MODE_DEFAULT; + pSystemEnv->ibrt_mode.tws_connect_success = 0; + pSystemEnv->factory_tester_status.status = NVRAM_ENV_FACTORY_TESTER_STATUS_DEFAULT; + + pSystemEnv->voice_key_enable = false; + pSystemEnv->aiManagerInfo.setedCurrentAi = 0; + pSystemEnv->aiManagerInfo.aiStatusDisableFlag = 0; + pSystemEnv->aiManagerInfo.amaAssistantEnableStatus = 1; + + localSystemInfo = *pSystemEnv; +} + +int nv_record_env_get(struct nvrecord_env_t **nvrecord_env) +{ + if (NULL == nvrecord_env) + { + return -1; + } + localSystemInfo.ibrt_mode.tws_connect_success = true; + *nvrecord_env = &localSystemInfo; + + return 0; +} + +int nv_record_env_set(struct nvrecord_env_t *nvrecord_env) +{ + if (NULL == nvrecord_extension_p) + { + return -1; + } + + uint32_t lock = nv_record_pre_write_operation(); + nvrecord_extension_p->system_info = *nvrecord_env; + + nv_record_update_runtime_userdata(); + nv_record_post_write_operation(lock); + return 0; +} + +void nv_record_update_ibrt_info(uint32_t newMode, bt_bdaddr_t *ibrtPeerAddr) +{ + if (NULL == nvrecord_extension_p) + { + return; + } + + uint32_t lock = nv_record_pre_write_operation(); + + TRACE(2,"##%s,%d",__func__,newMode); + nvrecord_extension_p->system_info.ibrt_mode.mode = newMode; + memcpy(nvrecord_extension_p->system_info.ibrt_mode.record.bdAddr.address, + ibrtPeerAddr->address, BTIF_BD_ADDR_SIZE); + + nv_record_update_runtime_userdata(); + nv_record_post_write_operation(lock); +} + + +void nv_record_update_factory_tester_status(uint32_t status) +{ + if (NULL == nvrecord_extension_p) + { + return; + } + + uint32_t lock = nv_record_pre_write_operation(); + + nvrecord_extension_p->system_info.factory_tester_status.status = status; + + nv_record_update_runtime_userdata(); + nv_record_post_write_operation(lock); +} + +int nv_record_env_init(void) +{ + nv_record_open(section_usrdata_ddbrecord); + return 0; +} +#endif // #if defined(NEW_NV_RECORD_ENABLED) + + diff --git a/services/nv_section/fpga_section/nvrecord_env.h b/services/nv_section/fpga_section/nvrecord_env.h new file mode 100644 index 0000000..fbc1532 --- /dev/null +++ b/services/nv_section/fpga_section/nvrecord_env.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) + +#ifndef NVRECORD_ENV_H +#define NVRECORD_ENV_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "me_api.h" +#include "nvrecord_extension.h" + +#define NVRAM_ENV_MEDIA_LANGUAGE_DEFAULT (0) +#define NVRAM_ENV_TWS_MODE_DEFAULT (0xff) +#define NVRAM_ENV_FACTORY_TESTER_STATUS_DEFAULT (0xaabbccdd) +#define NVRAM_ENV_FACTORY_TESTER_STATUS_TEST_PASS (0xffffaa55) + +int nv_record_env_init(void); +int nv_record_env_get(struct nvrecord_env_t **nvrecord_env); +int nv_record_env_set(struct nvrecord_env_t *nvrecord_env); +void nv_record_update_ibrt_info(uint32_t newMode,bt_bdaddr_t *ibrtPeerAddr); +void nvrecord_rebuild_system_env(struct nvrecord_env_t* pSystemEnv); +void nv_record_update_factory_tester_status(uint32_t status); + +#ifdef __cplusplus +} +#endif +#endif +#endif // #if defined(NEW_NV_RECORD_ENABLED) + diff --git a/services/nv_section/fpga_section/nvrecord_externsion.c b/services/nv_section/fpga_section/nvrecord_externsion.c new file mode 100644 index 0000000..6058ddf --- /dev/null +++ b/services/nv_section/fpga_section/nvrecord_externsion.c @@ -0,0 +1,547 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef NEW_NV_RECORD_ENABLED +#include +#include +#include +#include "cmsis.h" +#include "nvrecord_extension.h" +#include "hal_trace.h" +#include "crc32.h" +#include "hal_norflash.h" +#include "norflash_api.h" +#include "norflash_drv.h" +#include "nvrecord_bt.h" +#include "nvrecord_env.h" +#include "nvrecord_ble.h" +#include "nvrecord_dma_config.h" +#include "nvrecord_fp_account_key.h" +#include "customparam_section.h" +#include "mpu.h" +#include "besbt.h" + +extern uint32_t __userdata_start[]; +extern uint32_t __userdata_end[]; +extern void nvrecord_rebuild_system_env(struct nvrecord_env_t* pSystemEnv); +extern void nvrecord_rebuild_paired_bt_dev_info(NV_RECORD_PAIRED_BT_DEV_INFO_T* pPairedBtInfo); +#ifdef GFPS_ENABLED +extern void nvrecord_rebuild_fp_account_key(NV_FP_ACCOUNT_KEY_RECORD_T* pFpAccountKey); +#endif +#ifdef NVREC_BAIDU_DATA_SECTION +extern void nvrecord_rebuild_dma_configuration(NV_DMA_CONFIGURATION_T* pDmaConfig); +#endif + +typedef enum +{ + NV_STATE_IDLE, + NV_STATE_ERASED, +}NV_STATE; + +NV_EXTENSION_RECORD_T *nvrecord_extension_p = NULL; +static uint8_t isNvExtentionPendingForUpdate = false; +static NV_STATE isNvExtentionState = NV_STATE_IDLE; +/* + *Note: the NV_EXTENSION_MIRROR_RAM_SIZE must be power of 2 + */ +#if defined(__ARM_ARCH_8M_MAIN__) +#define __NV_BUF_MPU_ALIGNED __ALIGNED(0x20) +#else +/* + * armv7 mpu require the address must be aligned to the section size and + * the section size must be algined to power of 2 + */ +#define __NV_BUF_MPU_ALIGNED __ALIGNED(NV_EXTENSION_MIRROR_RAM_SIZE) +#endif + +static NV_MIRROR_BUF_T local_extension_data __NV_BUF_MPU_ALIGNED + __attribute__((section(".sram_data"))) = +{ + .nv_record = { + { // header + NV_EXTENSION_MAGIC_NUMBER, + NV_EXTENSION_MAJOR_VERSION, + NV_EXTENSION_MINOR_VERSION, + NV_EXTENSION_VALID_LEN, + 0, + }, + + { // system info + }, + + { // bt_pair_info + 0 + }, + + { // ble_pair_info + + }, + +#ifdef TWS_SYSTEM_ENABLED + { // tws_info + + }, +#endif + +#ifdef GFPS_ENABLED + { // fp_account_key_rec + 0 + }, +#endif + +#ifdef NVREC_BAIDU_DATA_SECTION + { // dma_config + BAIDU_DATA_DEF_FM_FREQ, + }, +#endif + +#ifdef TILE_DATAPATH + { + {0} + }, +#endif + +#if defined(BISTO_ENABLED) + { + true, + GSOUND_OTA_STATUS_NONE, + 0, + 0, + }, +#endif + +#ifdef TX_IQ_CAL + { + BT_IQ_INVALID_MAGIC_NUM, + {0}, + {0}, + }, +#endif + // TODO: + // If want to extend the nvrecord while keeping the history information, + // append the new items to the tail of NV_EXTENSION_RECORD_T and + // set their intial content here + } +}; +STATIC_ASSERT(sizeof(local_extension_data) <= NV_EXTENSION_MIRROR_RAM_SIZE, "NV local buffer too small"); + +static void _nv_record_extension_init(void) +{ + enum NORFLASH_API_RET_T result; + uint32_t sector_size = 0; + uint32_t block_size = 0; + uint32_t page_size = 0; + + hal_norflash_get_size(HAL_NORFLASH_ID_0, + NULL, + &block_size, + §or_size, + &page_size); + result = norflash_api_register(NORFLASH_API_MODULE_ID_USERDATA_EXT, + HAL_NORFLASH_ID_0, + ((uint32_t)__userdata_start), + ((uint32_t)__userdata_end - (uint32_t)__userdata_start), + block_size, + sector_size, + page_size, + NV_EXTENSION_SIZE*2, + nv_extension_callback + ); + ASSERT(result == NORFLASH_API_OK,"_nv_record_extension_init: module register failed! result = %d.",result); +} + +uint32_t nv_record_pre_write_operation(void) +{ + uint32_t lock = int_lock_global(); + mpu_clear(MPU_ID_USER_DATA_SECTION); + return lock; +} + +void nv_record_post_write_operation(uint32_t lock) +{ + int ret = 0; + uint32_t nv_start = (uint32_t)&local_extension_data.nv_record; + uint32_t len = NV_EXTENSION_MIRROR_RAM_SIZE; + + ret = mpu_set(MPU_ID_USER_DATA_SECTION, nv_start, len, 0, MPU_ATTR_READ); + int_unlock_global(lock); + TRACE(2,"set mpu 0x%x len %d result %d", nv_start, len, ret); +} + +static void nv_record_extension_init(void) +{ + if (NULL == nvrecord_extension_p) + { + uint32_t lock = nv_record_pre_write_operation(); + _nv_record_extension_init(); + nvrecord_extension_p = &local_extension_data.nv_record; + NVRECORD_HEADER_T* pExtRecInFlash = + &(((NV_EXTENSION_RECORD_T *)__userdata_start)->header); + TRACE(2,"nv ext magic 0x%x valid len %d", pExtRecInFlash->magicNumber, + pExtRecInFlash->validLen); + + if ((NV_EXTENSION_MAJOR_VERSION == pExtRecInFlash->majorVersion) && + (NV_EXTENSION_MAGIC_NUMBER == pExtRecInFlash->magicNumber)) + { + // check whether the data length is valid + if (pExtRecInFlash->validLen <= (NV_EXTENSION_SIZE-NV_EXTENSION_HEADER_SIZE)) + { + // check crc32 + uint32_t crc = crc32(0,((uint8_t *)pExtRecInFlash + NV_EXTENSION_HEADER_SIZE), + pExtRecInFlash->validLen); + TRACE(2,"generated crc32 0x%x crc32 in flash 0x%x", + crc, pExtRecInFlash->crc32); + if (crc == pExtRecInFlash->crc32) + { + // correct + TRACE(0,"Nv extension is valid."); + + TRACE(1,"Former nv ext valid len %d", pExtRecInFlash->validLen); + TRACE(1,"Current FW version nv ext valid len %d", NV_EXTENSION_VALID_LEN); + + if (NV_EXTENSION_VALID_LEN < pExtRecInFlash->validLen) + { + TRACE(0,"Valid length of extension must be increased," + "jump over the recovery but use the default value."); + } + else + { + memcpy(((uint8_t *)nvrecord_extension_p) + NV_EXTENSION_HEADER_SIZE, + ((uint8_t *)pExtRecInFlash) + NV_EXTENSION_HEADER_SIZE, pExtRecInFlash->validLen); + + // frimware updates the nv extension data structure + if (pExtRecInFlash->validLen < NV_EXTENSION_VALID_LEN) + { + // update the version number + nvrecord_extension_p->header.minorVersion = NV_EXTENSION_MINOR_VERSION; + + // re-calculate the crc32 + nvrecord_extension_p->header.crc32 = crc32(0, ((uint8_t *)nvrecord_extension_p + NV_EXTENSION_HEADER_SIZE), + NV_EXTENSION_VALID_LEN); + // need to update the content in the flash + nv_record_extension_update(); + } + + goto exit; + } + } + } + } + + // the nv extension is invalid, should be recreated + nvrecord_rebuild_system_env(&(nvrecord_extension_p->system_info)); + nvrecord_rebuild_paired_bt_dev_info(&(nvrecord_extension_p->bt_pair_info)); + nvrecord_rebuild_paired_ble_dev_info(&(nvrecord_extension_p->ble_pair_info)); + #ifdef GFPS_ENABLED + nvrecord_rebuild_fp_account_key(&(nvrecord_extension_p->fp_account_key_rec)); + #endif + + #ifdef NVREC_BAIDU_DATA_SECTION + nvrecord_rebuild_dma_configuration(&(nvrecord_extension_p->dma_config)); + #endif + + pExtRecInFlash->crc32 = crc32(0, ((uint8_t *)nvrecord_extension_p + NV_EXTENSION_HEADER_SIZE), + NV_EXTENSION_VALID_LEN); + // need to update the content in the flash + nv_record_extension_update(); + + exit: + nv_record_post_write_operation(lock); + + } +} + +NV_EXTENSION_RECORD_T* nv_record_get_extension_entry_ptr(void) +{ + return nvrecord_extension_p; +} + +void nv_record_extension_update(void) +{ + isNvExtentionPendingForUpdate = true; +} + +static void nv_record_extension_flush(bool is_async) +{ + enum NORFLASH_API_RET_T ret; + uint32_t lock; + uint32_t crc; + +#if defined(FLASH_SUSPEND) && defined(NVREC_BURN_TEST) + static uint32_t stime = 0; + if (hal_sys_timer_get() - stime > MS_TO_TICKS(20000)) { + stime = hal_sys_timer_get(); + isNvExtentionPendingForUpdate = true; + } +#endif + + if (isNvExtentionPendingForUpdate) + { + if(is_async) + { + lock = int_lock_global(); + if(isNvExtentionState == NV_STATE_IDLE) + { + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)(__userdata_start), + NV_EXTENSION_SIZE, + true + ); + if(ret == NORFLASH_API_OK) + { + isNvExtentionState = NV_STATE_ERASED; + TRACE(2,"%s: norflash_api_erase ok,addr = 0x%x.",__func__,(uint32_t)__userdata_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + // do nothing. + } + else + { + ASSERT(0,"%s: norflash_api_erase err,ret = %d,addr = 0x%x.",__func__,ret,(uint32_t)__userdata_start); + } + } + if(isNvExtentionState == NV_STATE_ERASED) + { + uint32_t tmpLock = nv_record_pre_write_operation(); + crc = crc32(0,(uint8_t *)nvrecord_extension_p + NV_EXTENSION_HEADER_SIZE, + NV_EXTENSION_VALID_LEN); + nvrecord_extension_p->header.crc32 = crc; + nv_record_post_write_operation(tmpLock); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)(__userdata_start), + (uint8_t *)nvrecord_extension_p, + NV_EXTENSION_SIZE, + true); + if(ret == NORFLASH_API_OK) + { + isNvExtentionPendingForUpdate = false; + isNvExtentionState = NV_STATE_IDLE; + TRACE(2,"%s: norflash_api_write ok,addr = 0x%x.",__func__,(uint32_t)__userdata_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + // do nothing. + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.",__func__,ret,(uint32_t)__userdata_start); + } + } + int_unlock_global(lock); + } + else + { + if(isNvExtentionState == NV_STATE_IDLE) + { + do + { + lock = int_lock_global(); + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)(__userdata_start), + NV_EXTENSION_SIZE, + false + ); + int_unlock_global(lock); + if(ret == NORFLASH_API_OK) + { + isNvExtentionState = NV_STATE_ERASED; + TRACE(2,"%s: norflash_api_erase ok,addr = 0x%x.",__func__,(uint32_t)__userdata_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_ERASING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_erase err,ret = %d,addr = 0x%x.",__func__,ret,(uint32_t)__userdata_start); + } + }while(ret == NORFLASH_API_BUFFER_FULL); + } + + if(isNvExtentionState == NV_STATE_ERASED) + { + do + { + lock = nv_record_pre_write_operation(); + crc = crc32(0,(uint8_t *)nvrecord_extension_p + NV_EXTENSION_HEADER_SIZE, + NV_EXTENSION_VALID_LEN); + nvrecord_extension_p->header.crc32 = crc; + ret = norflash_api_write(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)(__userdata_start), + (uint8_t *)nvrecord_extension_p, + NV_EXTENSION_SIZE, + true); + nv_record_post_write_operation(lock); + if(ret == NORFLASH_API_OK) + { + isNvExtentionPendingForUpdate = false; + isNvExtentionState = NV_STATE_IDLE; + TRACE(2,"%s: norflash_api_write ok,addr = 0x%x.",__func__,(uint32_t)__userdata_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_WRITTING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.",__func__,ret,(uint32_t)__userdata_start); + } + }while(ret == NORFLASH_API_BUFFER_FULL); + + do + { + norflash_api_flush(); + }while(norflash_api_get_used_buffer_count(NORFLASH_API_MODULE_ID_USERDATA_EXT,NORFLASH_API_ALL) > 0); + } + } + } +} + +void nv_extension_callback(void* param) +{ + NORFLASH_API_OPERA_RESULT *opera_result; + opera_result = (NORFLASH_API_OPERA_RESULT*)param; + + TRACE(6,"%s:type = %d, addr = 0x%x,len = 0x%x,remain = %d,result = %d.", + __func__, + opera_result->type, + opera_result->addr, + opera_result->len, + opera_result->remain_num, + opera_result->result); +} + +void nv_record_init(void) +{ + nv_record_open(section_usrdata_ddbrecord); + + nv_custom_parameter_section_init(); +} + +bt_status_t nv_record_open(SECTIONS_ADP_ENUM section_id) +{ + nv_record_extension_init(); + return BT_STS_SUCCESS; +} + +void nv_record_update_runtime_userdata(void) +{ + nv_record_extension_update(); +} + + +int nv_record_touch_cause_flush(void) +{ + nv_record_update_runtime_userdata(); + return 0; +} + +void nv_record_sector_clear(void) +{ + uint32_t lock; + enum NORFLASH_API_RET_T ret; + + lock = int_lock_global(); + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)__userdata_start, + NV_EXTENSION_SIZE, + false); + nvrecord_extension_p = NULL; + int_unlock_global(lock); + nv_record_update_runtime_userdata(); + ASSERT(ret == NORFLASH_API_OK, + "nv_record_sector_clear: norflash_api_erase failed! ret = %d.",ret); +} + +void nv_record_rebuild(void) +{ + nv_record_sector_clear(); + nv_record_extension_init(); +} + +void nv_record_flash_flush(void) +{ +} + +int nv_record_flash_flush_in_sleep(void) +{ + nv_record_extension_flush(true); + return 0; +} + +#if defined(OTA_ENABLED) +void nv_record_extension_update_gsound_ota_session(uint8_t gsoundOtaStatus, + uint32_t totalImageSize, + const char *session) +{ + NV_EXTENSION_RECORD_T* pNvExtRec = nv_record_get_extension_entry_ptr(); + TRACE(2,"gsound ota status is %d, is start is %d", + pNvExtRec->gsound_info.gsoundOtaStatus, + gsoundOtaStatus); + + if (pNvExtRec->gsound_info.gsoundOtaStatus != gsoundOtaStatus) + { + if (GSOUND_OTA_STATUS_NONE == gsoundOtaStatus) + { + pNvExtRec->gsound_info.gsoundOtaOffset = 0; + memset(pNvExtRec->gsound_info.gsoundOtaSessionString, + 0, + sizeof(pNvExtRec->gsound_info.gsoundOtaSessionString)); + } + else if (GSOUND_OTA_STAGE_ONGOING == gsoundOtaStatus) + { + ASSERT(totalImageSize, "Received total image size is 0."); + ASSERT(session, "Received session pointer is NULL."); + pNvExtRec->gsound_info.gsoundOtaImageSize = totalImageSize; + memcpy(pNvExtRec->gsound_info.gsoundOtaSessionString, session, strlen(session)+1); + } + else if (GSOUND_OTA_STATUS_COMPLETE == gsoundOtaStatus) + { + ASSERT(GSOUND_OTA_STAGE_ONGOING == pNvExtRec->gsound_info.gsoundOtaStatus, + "Wrong status transmission."); + ASSERT(totalImageSize == pNvExtRec->gsound_info.gsoundOtaImageSize, + "total image size changed."); + + pNvExtRec->gsound_info.gsoundOtaOffset = totalImageSize; + } + + pNvExtRec->gsound_info.gsoundOtaStatus = gsoundOtaStatus; + + TRACE(1,"update gsound ota status to %d", pNvExtRec->gsound_info.gsoundOtaStatus); + nv_record_extension_update(); + nv_record_flash_flush(); + } +} + +void nv_record_extension_update_gsound_ota_progress(uint32_t otaOffset) +{ + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + if ((GSOUND_OTA_STAGE_ONGOING == pNvExtRec->gsound_info.gsoundOtaStatus) && + (otaOffset <= pNvExtRec->gsound_info.gsoundOtaImageSize)) + { + pNvExtRec->gsound_info.gsoundOtaOffset = otaOffset; + nv_record_extension_update(); + nv_record_flash_flush(); + } +} +#endif +#endif // #if defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nv_section/fpga_section/nvrecord_externsion.h b/services/nv_section/fpga_section/nvrecord_externsion.h new file mode 100644 index 0000000..d650f07 --- /dev/null +++ b/services/nv_section/fpga_section/nvrecord_externsion.h @@ -0,0 +1,316 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef NEW_NV_RECORD_ENABLED + +#ifndef __NVRECORD_EXTENSION_H__ +#define __NVRECORD_EXTENSION_H__ +#include "bluetooth.h" +#include "me_api.h" +#include "btif_sys_config.h" + +// increase by 1 if the nvrecord's whole data structure is changed and the content needs to be rebuilt +#define NV_EXTENSION_MAJOR_VERSION 2 +// increase by 1 if the new items are appended to the tail of the former nvrecord's data structure +#define NV_EXTENSION_MINOR_VERSION 1 + +#define NV_EXTENSION_SIZE 4096 // one flash page +#define NV_EXTENSION_HEADER_SIZE sizeof(NVRECORD_HEADER_T) // magic number and valid length +#define NV_EXTENSION_MAGIC_NUMBER 0x4E455854 +#define NV_EXTENSION_VALID_LEN (sizeof(NV_EXTENSION_RECORD_T) - sizeof(NVRECORD_HEADER_T)) + +/* unused, just for backwards compatible */ +#define section_name_ddbrec "ddbrec" + +/* BT paired device info */ +#define MAX_BT_PAIRED_DEVICE_COUNT 8 + +/* BLE paired device information */ +#define BLE_RECORD_NUM 5 + +#define BLE_ADDR_SIZE 6 +#define BLE_ENC_RANDOM_SIZE 8 +#define BLE_LTK_SIZE 16 +#define BLE_IRK_SIZE 16 + +#define BLE_STATIC_ADDR 0 +#define BLE_RANDOM_ADDR 1 + +#ifdef GFPS_ENABLED +/* fast pair account key */ +#define FP_ACCOUNT_KEY_RECORD_NUM 5 +#define FP_ACCOUNT_KEY_SIZE 16 +#define FP_MAX_NAME_LEN 64 +#endif + +// TODO: should be increased if NV_EXTENSION_MIRROR_RAM_SIZE exceeds this value + +#define TILE_INFO_SIZE 400 +#define BT_FREQENCY_RANGE_NUM 3 +#define BT_IQ_INVALID_MAGIC_NUM 0xFFFFFFFF +#define BT_IQ_VALID_MAGIC_NUM 0x5a5a5a5a +typedef struct +{ + uint32_t validityMagicNum; + uint16_t gain_cal_val[BT_FREQENCY_RANGE_NUM]; + uint16_t phase_cal_val[BT_FREQENCY_RANGE_NUM]; +} BT_IQ_CALIBRATION_CONFIG_T; + +/* nv record header data structure */ +typedef struct +{ + uint32_t magicNumber; + uint16_t majorVersion; // should be NV_EXTENSION_MAJOR_VERSION + uint16_t minorVersion; // should be NV_EXTENSION_MINOR_VERSION + uint32_t validLen; // should be the valid content in this nv record version + uint32_t crc32; // crc32 of following valid values in the nv extention section +} NVRECORD_HEADER_T; + +/* system information */ +typedef struct { + int8_t language; +} media_language_t; + +#if defined(APP_LINEIN_A2DP_SOURCE) || defined(APP_I2S_A2DP_SOURCE) +typedef struct { + int8_t src_snk_mode; +} src_snk_t; +#endif + +typedef struct { + uint32_t mode; + btif_device_record_t record; + bool tws_connect_success; +} ibrt_mode_t; + +typedef struct { + uint32_t status; +} factory_tester_status_t; + +typedef struct { + uint8_t setedCurrentAi; + uint8_t currentAiSpec; + uint8_t aiStatusDisableFlag; + uint8_t amaAssistantEnableStatus; +} AI_MANAGER_INFO_T; + +struct nvrecord_env_t { + media_language_t media_language; +#if defined(APP_LINEIN_A2DP_SOURCE) || defined(APP_I2S_A2DP_SOURCE) + src_snk_t src_snk_flag; +#endif + ibrt_mode_t ibrt_mode; + factory_tester_status_t factory_tester_status; + + uint8_t flag_value[8]; + bool voice_key_enable; + AI_MANAGER_INFO_T aiManagerInfo; +}; + +typedef struct btdevice_volume { + int8_t a2dp_vol; + int8_t hfp_vol; +} btdevice_volume; + +typedef struct btdevice_profile { + bool hfp_act; + bool hsp_act; + bool a2dp_act; + uint8_t a2dp_codectype; +} btdevice_profile; + +typedef struct { + btif_device_record_t record; + btdevice_volume device_vol; + btdevice_profile device_plf; +#ifdef BTIF_DIP_DEVICE + uint16_t vend_id; + uint16_t vend_id_source; + uint16_t reserve; +#endif +} nvrec_btdevicerecord; + +typedef struct { + uint32_t pairedDevNum; + nvrec_btdevicerecord pairedBtDevInfo[MAX_BT_PAIRED_DEVICE_COUNT]; +} NV_RECORD_PAIRED_BT_DEV_INFO_T; + +typedef enum { + section_usrdata_ddbrecord, + section_none +} SECTIONS_ADP_ENUM; + +#if defined(OTA_ENABLED) +typedef enum { + OTA_STATUS_NONE = 0, + OTA_STAGE_ONGOING = 1, + OTA_STATUS_COMPLETE = 2, + OTA_STATUS_NUM, +} GSOUND_OTA_STATUS_E; +#endif + +typedef struct { + uint8_t ble_addr[BTIF_BD_ADDR_SIZE]; + uint8_t ble_irk[BLE_IRK_SIZE]; +} BLE_BASIC_INFO_T; + +typedef struct { + uint8_t peer_bleAddr[BLE_ADDR_SIZE]; + uint16_t EDIV; + uint8_t RANDOM[BLE_ENC_RANDOM_SIZE]; + uint8_t LTK[BLE_LTK_SIZE]; + uint8_t IRK[BLE_IRK_SIZE]; + uint8_t bonded; + +} BleDeviceinfo; + +typedef struct { + uint32_t saved_list_num; + BLE_BASIC_INFO_T self_info; + BleDeviceinfo ble_nv[BLE_RECORD_NUM]; +} NV_RECORD_PAIRED_BLE_DEV_INFO_T; + +#ifdef TWS_SYSTEM_ENABLED +typedef struct { + BLE_BASIC_INFO_T ble_info; +} TWS_INFO_T; +#endif // #ifdef TWS_SYSTEM_ENABLED + +#ifdef GFPS_ENABLED +typedef struct { + uint8_t key[FP_ACCOUNT_KEY_SIZE]; + +} NV_FP_ACCOUNT_KEY_ENTRY_T; + +typedef struct { + uint32_t key_count; + NV_FP_ACCOUNT_KEY_ENTRY_T accountKey[FP_ACCOUNT_KEY_RECORD_NUM]; + uint16_t nameLen; + uint8_t name[FP_MAX_NAME_LEN]; +} NV_FP_ACCOUNT_KEY_RECORD_T; +#endif // #ifdef GFPS_ENABLED + +#ifdef NVREC_BAIDU_DATA_SECTION +/* DMA owned configuration information */ +typedef struct { + int32_t fmfreq; + char rand[BAIDU_DATA_RAND_LEN + 1]; + +} NV_DMA_CONFIGURATION_T; +#endif // #ifdef NVREC_BAIDU_DATA_SECTION + +#ifdef TILE_DATAPATH +typedef struct { + uint8_t tileInfo[TILE_INFO_SIZE]; +} NV_TILE_INFO_CONFIG_T; +#endif + +#if defined(BISTO_ENABLED) +typedef struct { + uint8_t isGsoundEnabled; + uint8_t gsoundOtaStatus; + uint32_t gsoundOtaOffset; + uint32_t gsoundOtaImageSize; + uint8_t gsoundOtaSessionString[16]; +} NV_GSOUND_INFO_T; +#endif + +typedef struct { + NVRECORD_HEADER_T header; + struct nvrecord_env_t system_info; + NV_RECORD_PAIRED_BT_DEV_INFO_T bt_pair_info; + NV_RECORD_PAIRED_BLE_DEV_INFO_T ble_pair_info; + +#ifdef TWS_SYSTEM_ENABLED + TWS_INFO_T tws_info; +#endif + +#ifdef GFPS_ENABLED + NV_FP_ACCOUNT_KEY_RECORD_T fp_account_key_rec; +#endif + +#ifdef NVREC_BAIDU_DATA_SECTION + NV_DMA_CONFIGURATION_T dma_config; +#endif + +#ifdef TILE_DATAPATH + NV_TILE_INFO_CONFIG_T tileConfig; +#endif + +#if defined(BISTO_ENABLED) + NV_GSOUND_INFO_T gsound_info; +#endif + +#ifdef TX_IQ_CAL + BT_IQ_CALIBRATION_CONFIG_T btIqCalConfig; +#endif + // TODO: If wanna OTA to update the nv record, two choices: + // 1. Change above data structures and increase NV_EXTENSION_MAJOR_VERSION. + // Then the nv record will be rebuilt and the whole history information will be cleared + // 2. Don't touch above data structures but just add new items here and increase NV_EXTENSION_MINOR_VERSION. + // Then the nv record will keep all the whole hisotry. +} NV_EXTENSION_RECORD_T; + +typedef union { + NV_EXTENSION_RECORD_T nv_record; + /* + * dummy data, just make sure the mirror buffer's size is + * "NV_EXTENSION_MIRROR_RAM_SIZE" + */ + uint8_t dummy_data[NV_EXTENSION_MIRROR_RAM_SIZE]; +} NV_MIRROR_BUF_T; + +#ifdef __cplusplus +extern "C" { +#endif + +extern NV_EXTENSION_RECORD_T *nvrecord_extension_p; + +int nv_record_env_init(void); + +NV_EXTENSION_RECORD_T *nv_record_get_extension_entry_ptr(void); + +void nv_record_extension_update(void); + +void nv_extension_callback(void *param); + +int nv_record_touch_cause_flush(void); + +void nv_record_sector_clear(void); + +void nv_record_flash_flush(void); + +int nv_record_flash_flush_in_sleep(void); + +void nv_record_execute_async_flush(void); + +void nv_record_update_runtime_userdata(void); + +void nv_record_rebuild(void); + +uint32_t nv_record_pre_write_operation(void); + +void nv_record_post_write_operation(uint32_t lock); + +bt_status_t nv_record_open(SECTIONS_ADP_ENUM section_id); + +void nv_record_init(void); + +#ifdef __cplusplus +} +#endif +#endif +#endif //#if defined(NEW_NV_RECORD_ENABLED) + diff --git a/services/nv_section/include/section_def.h b/services/nv_section/include/section_def.h new file mode 100644 index 0000000..4260727 --- /dev/null +++ b/services/nv_section/include/section_def.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __section_def_h__ +#define __section_def_h__ + +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint16_t magic; + uint16_t version; + uint32_t crc; + uint32_t reserved0; + uint32_t reserved1; +} section_head_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/nv_section/log_section/Makefile b/services/nv_section/log_section/Makefile new file mode 100644 index 0000000..f786224 --- /dev/null +++ b/services/nv_section/log_section/Makefile @@ -0,0 +1,22 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -Iutils/crc32 \ + -Iutils/heap \ + -Iplatform/drivers/ana \ + -Iservices/norflash_api + +ifeq ($(TRACE_DUMP2FLASH),1) +ccflags-y += -DTRACE_DUMP2FLASH +endif + +ifeq ($(TRACE_CRLF),1) +ccflags-y += -DTRACE_CRLF +endif + diff --git a/services/nv_section/log_section/coredump_section.c b/services/nv_section/log_section/coredump_section.c new file mode 100644 index 0000000..0dfda81 --- /dev/null +++ b/services/nv_section/log_section/coredump_section.c @@ -0,0 +1,198 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include + +#include "cmsis.h" +#include "coredump_section.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_norflash.h" +#include "norflash_api.h" + +/* +Usage: +arm-none-eabi-gdb elf_file -ex "target remote | ./tools/bins/lin64/CrashDebug --elf elf_file --dump coredump.dat" +*/ + +extern uint32_t __coredump_section_start; +extern uint32_t __coredump_section_end; + +static const uint32_t coredump_flash_start_addr = (uint32_t)&__coredump_section_start; +static const uint32_t coredump_flash_end_addr = (uint32_t)&__coredump_section_end; +static uint32_t coredump_flash_addr_offset = (uint32_t)&__coredump_section_start; + +void coredump_to_flash_init() +{ + uint32_t block_size = 0; + uint32_t sector_size = 0; + uint32_t page_size = 0; + uint32_t buffer_len = 0; + enum NORFLASH_API_RET_T result; + + hal_norflash_get_size(HAL_NORFLASH_ID_0,NULL, &block_size, §or_size, &page_size); + buffer_len = COREDUMP_SECTOR_SIZE; + TRACE(4,"%s: coredump_flash_start_addr = 0x%x, coredump_flash_end_addr = 0x%x, buff_len = 0x%x.", + __func__, + coredump_flash_start_addr, + coredump_flash_end_addr, + buffer_len); + + result = norflash_api_register( + NORFLASH_API_MODULE_ID_COREDUMP, + HAL_NORFLASH_ID_0, + coredump_flash_start_addr, + coredump_flash_end_addr - coredump_flash_start_addr, + block_size, + sector_size, + page_size, + buffer_len, + NULL + ); + + if(result == NORFLASH_API_OK) + { + TRACE(0,"coredump_to_flash_init ok."); + } + else + { + TRACE(1,"coredump_to_flash_init failed,result = %d.",result); + } +} + +void core_dump_erase_section() +{ + //erase whole core dump section + enum NORFLASH_API_RET_T ret = 0; + uint32_t lock; + do + { + lock = int_lock_global(); + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_COREDUMP, coredump_flash_addr_offset, + COREDUMP_SECTOR_SIZE, false); + int_unlock_global(lock); + if(ret != NORFLASH_API_OK) + { + TRACE(3,"%s:offset = 0x%x,ret = %d.", + __func__,coredump_flash_addr_offset,ret); + } + coredump_flash_addr_offset += COREDUMP_SECTOR_SIZE; + if (coredump_flash_addr_offset == coredump_flash_end_addr) + { + coredump_flash_addr_offset = coredump_flash_start_addr; + break; + } + } while (1); +} + +int32_t core_dump_write_large(const uint8_t* ptr,uint32_t len) +{ + enum NORFLASH_API_RET_T ret; + uint32_t write_len; + uint32_t remain_len = len; + uint32_t lock; + //TRACE(4,"%s offset = 0x%x ptr = 0x%x len=0x%x",__func__, coredump_flash_addr_offset, ptr, len); + do + { + if (coredump_flash_addr_offset % COREDUMP_SECTOR_SIZE != 0) + { + write_len = COREDUMP_SECTOR_SIZE - (coredump_flash_addr_offset - (coredump_flash_addr_offset & ~COREDUMP_SECTOR_SIZE_MASK)); + lock = int_lock_global(); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_COREDUMP, + coredump_flash_addr_offset, + ptr, + write_len, + false); + int_unlock_global(lock); + if(ret != NORFLASH_API_OK) + { + TRACE(4,"%s: addr = 0x%x,write_len = 0x%x,ret = %d.", + __func__,coredump_flash_addr_offset,write_len,ret); + return (int32_t)ret; + } + coredump_flash_addr_offset += write_len; + ptr += write_len; + remain_len -= write_len; + } + + if (remain_len < COREDUMP_SECTOR_SIZE) + { + lock = int_lock_global(); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_COREDUMP, + coredump_flash_addr_offset, + ptr, + remain_len, + false); + int_unlock_global(lock); + if(ret != NORFLASH_API_OK) + { + TRACE(4,"%s: addr = 0x%x,remain_len = 0x%x,ret = %d.", + __func__,coredump_flash_addr_offset,remain_len,ret); + return (int32_t)ret; + } + coredump_flash_addr_offset += remain_len; + ptr += remain_len; + remain_len = 0; + } + else + { + lock = int_lock_global(); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_COREDUMP, + coredump_flash_addr_offset, + ptr, + COREDUMP_SECTOR_SIZE, + false); + int_unlock_global(lock); + if(ret != NORFLASH_API_OK) + { + TRACE(3,"%s: addr = 0x%x,ret = %d.", + __func__,coredump_flash_addr_offset,ret); + return (int32_t)ret; + } + coredump_flash_addr_offset += COREDUMP_SECTOR_SIZE; + ptr += COREDUMP_SECTOR_SIZE; + remain_len -= COREDUMP_SECTOR_SIZE; + } + } while (remain_len > 0); + //TRACE(3,"%s offset = 0x%x ptr = 0x%x",__func__, coredump_flash_addr_offset, ptr); + return 0; +} + +int32_t core_dump_write(const uint8_t* ptr,uint32_t len) +{ + enum NORFLASH_API_RET_T ret; + uint32_t i; + uint32_t lock; + //TRACE(2,"%s: len = 0x%x", __func__,len); + //write by byte to avoid cross flash sector boundary + for (i = 0; i < len; i++) + { + lock = int_lock_global(); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_COREDUMP, + coredump_flash_addr_offset++, + ptr++, + 1, + false); + int_unlock_global(lock); + if(ret != NORFLASH_API_OK) + { + TRACE(4,"%s: offset = 0x%x ret = %d ch =%02x", + __func__,coredump_flash_addr_offset,ret,*(ptr-1)); + } + } + return 0; +} + diff --git a/services/nv_section/log_section/coredump_section.h b/services/nv_section/log_section/coredump_section.h new file mode 100644 index 0000000..7e20277 --- /dev/null +++ b/services/nv_section/log_section/coredump_section.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef _COREDUMP_SECTION_H +#define _COREDUMP_SECTION_H +#define COREDUMP_SECTOR_SIZE 0x1000 +#define COREDUMP_SECTOR_SIZE_MASK 0xFFF +#define COREDUMP_BUFFER_LEN (COREDUMP_SECTOR_SIZE*2) +#define COREDUMP_NORFALSH_BUFFER_LEN (COREDUMP_BUFFER_LEN) +#if defined(__cplusplus) +extern "C" { +#endif + +void coredump_to_flash_init(); +void core_dump_erase_section(); +int32_t core_dump_write_large(const uint8_t* ptr,uint32_t len); +int32_t core_dump_write(const uint8_t* ptr,uint32_t len); + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/services/nv_section/log_section/crash_dump_section.c b/services/nv_section/log_section/crash_dump_section.c new file mode 100644 index 0000000..c3de28a --- /dev/null +++ b/services/nv_section/log_section/crash_dump_section.c @@ -0,0 +1,664 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if 0 +#include "cmsis.h" +#include "crash_dump_section.h" + +#if defined(CRASH_DUMP_SECTION_SIZE) && (CRASH_DUMP_SECTION_SIZE > 0) + +#include "hal_bootmode.h" +#include "hal_norflash.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "heap_api.h" +#include "pmu.h" +#include "stdio.h" +#include "string.h" + +extern uint32_t __crash_dump_start[]; +extern uint32_t __crash_dump_end[]; + +extern const char sys_build_info[]; + +#define DUMPED_MSP_BYTES 32 +#define DUMPED_PSP_BYTES 32 + +// #undef CRASH_DUMP_SECTION_SIZE + +#define CRASH_DUMP_FRAME_NUM (((uint32_t)__crash_dump_end - (uint32_t)__crash_dump_start)/CRASH_DUMP_FRAME_SIZE) + +#ifdef TRACE_CRLF +#define NEW_LINE_STR "\r\n" +#else +#define NEW_LINE_STR "\n" +#endif + +static struct CRASH_OUTPUT_BUF_T *crash_dump_section_p = NULL; +static struct CRASH_OUTPUT_BUF_T *crash_output_p = NULL; +static bool crash_dump_init = false; + +static uint8_t isCrashHappened = false; +static uint8_t isCrashDumpExisting = false; + +static void crashdump_dump_output(const unsigned char *buf, unsigned int buf_len) +{ + if (crash_dump_init){ + if ((crash_output_p->hdr.bufpos+buf_len) <= OFFSETOF(struct CRASH_OUTPUT_BUF_T, buf)){ + memcpy(crash_output_p->buf+crash_output_p->hdr.bufpos, buf, buf_len); + crash_output_p->hdr.bufpos += buf_len; + }else{ + memcpy(crash_output_p->buf+crash_output_p->hdr.bufpos, buf, OFFSETOF(struct CRASH_OUTPUT_BUF_T, buf)-crash_output_p->hdr.bufpos); + crash_output_p->hdr.bufpos += OFFSETOF(struct CRASH_OUTPUT_BUF_T, buf)-crash_output_p->hdr.bufpos; + } + } +} + +int crashdump_get_empty_section(uint32_t *seqnum, struct CRASH_OUTPUT_BUF_T **crash_dump_addr) +{ + struct CRASH_OUTPUT_BUF_T *p; + int32_t lastWrittenIndex = -1, index = 0; + int32_t max = -1; + + for (p = (struct CRASH_OUTPUT_BUF_T *)__crash_dump_start; p < (struct CRASH_OUTPUT_BUF_T *)__crash_dump_end; p++){ + // TRACE(2,"magic code is 0x%x seqnum is 0x%x", p->magicCode, (uint32_t)(p->seqnum)); + + if ((CRASH_DUMP_MAGIC_CODE == p->hdr.magicCode) && (0xffffffff != (uint32_t)(p->hdr.seqnum))) + { + if (max < p->hdr.seqnum){ + max = p->hdr.seqnum; + lastWrittenIndex = index; + } + } + + index++; + } + + if (-1 != lastWrittenIndex) + { + crashdump_set_existing_flag(true); + TRACE(1,"The last written dump log is at index %d", lastWrittenIndex); + lastWrittenIndex++; + if (lastWrittenIndex == (((uint32_t)__crash_dump_end-(uint32_t)__crash_dump_start)/sizeof(struct CRASH_OUTPUT_BUF_T))) + { + lastWrittenIndex = 0; + } + + *crash_dump_addr = (struct CRASH_OUTPUT_BUF_T *)((uint32_t)__crash_dump_start + + lastWrittenIndex*sizeof(struct CRASH_OUTPUT_BUF_T)); + *seqnum = max+1; + } + else + { + crashdump_set_existing_flag(false); + TRACE(0,"No dump log saved yet!"); + *seqnum = 0; + *crash_dump_addr = (struct CRASH_OUTPUT_BUF_T *)__crash_dump_start; + } + + + TRACE(1,"Next crash dump addr 0x%x", *crash_dump_addr); + return 0; +} + +void crashdump_flush_buffer(void) +{ + uint32_t sent_cnt; + uint32_t send_frame_size; + const uint32_t max_frame_size = 256; + + sent_cnt = 0; + while (sent_cnt < crash_output_p->hdr.bufpos) { + send_frame_size = crash_output_p->hdr.bufpos - sent_cnt; + if (send_frame_size > max_frame_size) { + send_frame_size = max_frame_size; + } + + TRACE_FLUSH(); + TRACE_OUTPUT(crash_output_p->buf + sent_cnt, send_frame_size); + TRACE_FLUSH(); + sent_cnt += send_frame_size; + } +} + +int crashdump_init(void) +{ + const char separate_line[] = NEW_LINE_STR "----------------------------------------" NEW_LINE_STR; + uint32_t dump_section_idx; + int len; + char crash_buf[100]; + + if (crash_dump_init) + return 0; + + crash_dump_init = true; + + hal_sw_bootmode_set(HAL_SW_BOOTMODE_REBOOT_FLASH_FLUSH); + + crashdump_get_empty_section(&dump_section_idx, &crash_dump_section_p); + + syspool_init(); + syspool_get_buff((uint8_t **)&crash_output_p, sizeof(struct CRASH_OUTPUT_BUF_T)); + crash_output_p->hdr.bufpos = 0; + + crash_output_p->hdr.magicCode = CRASH_DUMP_MAGIC_CODE; + crash_output_p->hdr.seqnum = dump_section_idx; + crash_output_p->hdr.partnum = CRASH_DUMP_FRAME_NUM; + crashdump_dump_output((unsigned char *)separate_line, sizeof(separate_line) - 1); + len = snprintf(crash_buf, sizeof(crash_buf), "%08lX/%08lX" NEW_LINE_STR, crash_output_p->hdr.seqnum, crash_output_p->hdr.partnum); + crashdump_dump_output((unsigned char *)crash_buf, len); + crashdump_dump_output((unsigned char *)sys_build_info, strlen(sys_build_info)); + crashdump_dump_output((unsigned char *)separate_line, sizeof(separate_line) - 1); + +#if defined(TRACE_DUMP2FLASH) + { + const unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + + hal_trace_get_history_buffer(&e1, &len1, &e2, &len2); + if (e1 && len1) { + crashdump_dump_output(e1, len1); + } + if (e2 && len2) { + crashdump_dump_output(e2, len2); + } + } +#endif + crashdump_dump_output((unsigned char *)separate_line, sizeof(separate_line) - 1); + + crashdump_dumptoflash(); + return 0; +} + +#if defined(CRASH_DUMP_SECTION_SIZE) && (CRASH_DUMP_SECTION_SIZE > 0) +static void crashdump_state_handler(enum HAL_TRACE_STATE_T state) +{ + if (state == HAL_TRACE_STATE_CRASH_START) { + crashdump_init(); + } +} +#endif + +bool crashdump_is_crash_happened(void) +{ + return isCrashHappened; +} + +bool crashdump_is_crash_dump_existing(void) +{ + return isCrashDumpExisting; +} + +void crashdump_set_existing_flag(uint8_t isExisting) +{ + isCrashDumpExisting = isExisting; +} + +int32_t crashdump_get_latest_flash_offset(void) +{ + if (crashdump_is_crash_dump_existing()) + { + if ((uint32_t)__crash_dump_start == (uint32_t)crash_dump_section_p) + { + return ((uint32_t)__crash_dump_end - sizeof(struct CRASH_OUTPUT_BUF_T))&0x3FFFFF; + } + else + { + return ((uint32_t)crash_dump_section_p - sizeof(struct CRASH_OUTPUT_BUF_T))&0x3FFFFF; + } + } + else + { + return -1; + } +} + +void crashdump_test_flash_access(void) +{ + TRACE(1,"Did crash just happen: %d", crashdump_is_crash_happened()); + + TRACE(1,"Did crash ever happen: %d", crashdump_is_crash_dump_existing()); + + int32_t latestCrashDumpFlashOffset = crashdump_get_latest_flash_offset(); + if (latestCrashDumpFlashOffset > 0) + { + TRACE(2,"The latest crash dump flash offset 0x%x flash logic addr 0x%x", + latestCrashDumpFlashOffset, + latestCrashDumpFlashOffset + FLASH_NC_BASE); + + struct CRASH_OUTPUT_BUF_T* pBuf = + (struct CRASH_OUTPUT_BUF_T *)(latestCrashDumpFlashOffset + FLASH_NC_BASE); + TRACE(1,"Valid content size of the dump log is %d", pBuf->hdr.bufpos); + TRACE(1,"Logic address of the trace buffer is 0x%x", pBuf->buf); + TRACE(1,"Up to %d logs can be saved in the flash", pBuf->hdr.partnum); + TRACE(1,"Log seq number is %d", pBuf->hdr.seqnum); + + for (int i = 0; i < pBuf->hdr.bufpos;i++) + { + TRACE_NOCRLF(1,"%c", pBuf->buf[i]); + } + } + else + { + TRACE(0,"No crash dump log in flash."); + } + + TRACE(0,"========================================="); +} + +#endif // (CRASH_DUMP_SECTION_SIZE > 0) + +void crashdump_set_crash_happened_flag(uint8_t isHappened) +{ +#if defined(CRASH_DUMP_SECTION_SIZE) && (CRASH_DUMP_SECTION_SIZE > 0) + isCrashHappened = isHappened; +#endif +} + +void crashdump_dumptoflash(void) +{ +#if defined(CRASH_DUMP_SECTION_SIZE) && (CRASH_DUMP_SECTION_SIZE > 0) + uint32_t lock; + uint32_t dump_section_idx; + + crashdump_get_empty_section(&dump_section_idx, &crash_dump_section_p); + lock = int_lock_global(); + pmu_flash_write_config(); + hal_norflash_erase(HAL_NORFLASH_ID_0,(uint32_t)crash_dump_section_p,sizeof(struct CRASH_OUTPUT_BUF_T)); + hal_norflash_write(HAL_NORFLASH_ID_0,(uint32_t)crash_dump_section_p,(uint8_t *)crash_output_p, sizeof(struct CRASH_OUTPUT_BUF_T)); + pmu_flash_read_config(); + int_unlock_global(lock); +#endif +} + +void crashdump_init_section_info(void) +{ +#if defined(CRASH_DUMP_SECTION_SIZE) && (CRASH_DUMP_SECTION_SIZE > 0) + uint32_t dump_section_idx; + crashdump_get_empty_section(&dump_section_idx, &crash_dump_section_p); + + hal_trace_app_register(crashdump_state_handler, crashdump_dump_output); +#endif +} +#else +#include +#include +#include "crash_dump_section.h" +#include +#include "hal_timer.h" +#include "hal_norflash.h" +#include "norflash_api.h" +#include "cmsis.h" +#include "hal_cache.h" +#include "hal_sleep.h" +#include "pmu.h" +#include "heap_api.h" + +extern uint32_t __crash_dump_start; +extern uint32_t __crash_dump_end; +extern void syspool_init_specific_size(uint32_t size); + +static const uint32_t crash_dump_flash_start_addr = (uint32_t)&__crash_dump_start; +static const uint32_t crash_dump_flash_end_addr = (uint32_t)&__crash_dump_end; +static uint32_t crash_dump_flash_len; +static CRASH_DATA_BUFFER crash_data_buffer; +static uint32_t crash_dump_w_seqnum = 0; +static uint32_t crash_dump_flash_offs = 0; +static uint32_t crash_dump_cur_dump_seqnum; +static uint32_t crash_dump_total_len = 0; +static bool crash_dump_is_init = false; +static uint8_t crash_dump_is_happend = 0; +static uint32_t crash_dump_type; +HAL_TRACE_APP_NOTIFY_T crash_dump_notify_cb = NULL; +HAL_TRACE_APP_OUTPUT_T crash_dump_output_cb = NULL; +HAL_TRACE_APP_OUTPUT_T crash_dump_fault_cb = NULL; +static enum NORFLASH_API_RET_T _flash_api_read(uint32_t addr, uint8_t* buffer, uint32_t len) +{ + + return norflash_sync_read(NORFLASH_API_MODULE_ID_CRASH_DUMP, + addr, + buffer, + len); +} + + +static int32_t _crash_dump_get_seqnum(uint32_t * dump_seqnum, uint32_t *sector_seqnum) +{ + uint32_t i; + uint32_t count; + static enum NORFLASH_API_RET_T result; + CRASH_DUMP_HEADER_T crash_dump_header; + uint32_t max_dump_seqnum = 0; + uint32_t max_sector_seqnum = 0; + bool is_existed = false; + + count = (crash_dump_flash_end_addr-crash_dump_flash_start_addr)/CRASH_DUMP_BUFFER_LEN; + for(i = 0; i < count; i++) + { + result = _flash_api_read( + crash_dump_flash_start_addr + i*CRASH_DUMP_BUFFER_LEN, + (uint8_t*)&crash_dump_header, + sizeof(CRASH_DUMP_HEADER_T)); + if(result == NORFLASH_API_OK) + { + if(crash_dump_header.magic == CRASH_DUMP_MAGIC_CODE + && crash_dump_header.version == CRASH_DUMP_VERSION + ) + { + is_existed = true; + if(crash_dump_header.seqnum > max_dump_seqnum) + { + max_dump_seqnum = crash_dump_header.seqnum; + max_sector_seqnum = i; + } + } + } + else + { + ASSERT(0,"_crash_dump_get_seqnum: _flash_api_read failed!result = %d.",result); + } + } + if(is_existed) + { + *dump_seqnum = max_dump_seqnum + 1; + *sector_seqnum = max_sector_seqnum + 1 >= count ? 0: max_sector_seqnum + 1; + } + else + { + *dump_seqnum = 0; + *sector_seqnum = 0; + } + return 0; +} +static void _crash_dump_notify(enum HAL_TRACE_STATE_T state) +{ + uint32_t lock; + CRASH_DATA_BUFFER *data_buff = NULL; + + if(!crash_dump_is_init) + { + return; + } + if(state == HAL_TRACE_STATE_CRASH_ASSERT_START) + { + crash_dump_type = CRASH_DUMP_ASSERT_CODE; + } + else if(state == HAL_TRACE_STATE_CRASH_FAULT_START) + { + crash_dump_type = CRASH_DUMP_EXCEPTION_CODE; + } + CRASH_DUMP_TRACE(2,"__CRASH_DUMP:%s: state = %d.",__func__,state); + CRASH_DUMP_TRACE(3,"__CRASH_DUMP:%s: start_addr = 0x%x,end_addr = 0x%x.", + __func__,crash_dump_flash_start_addr,crash_dump_flash_end_addr); + CRASH_DUMP_TRACE(3,"__CRASH_DUMP:%s: dump_seqnum = 0x%x,flash_offset = 0x%x.", + __func__,crash_dump_cur_dump_seqnum,crash_dump_flash_offs); + + if(HAL_TRACE_STATE_CRASH_END == state) + { + lock = int_lock_global(); + data_buff = &crash_data_buffer; + crash_dump_write(crash_dump_flash_start_addr + crash_dump_flash_offs, + data_buff->buffer,data_buff->offset); + int_unlock_global(lock); + } +} + +static void _crash_dump_output(const unsigned char *buf, unsigned int buf_len) +{ + //uint32_t len,len1; + uint32_t uint_len; + uint32_t written_len; + uint32_t remain_len; + CRASH_DUMP_HEADER_T log_header; + CRASH_DATA_BUFFER *data_buff = NULL; + + if(!crash_dump_is_init) + { + return; + } + + if(strstr((char*)buf,CRASH_DUMP_PREFIX) != NULL) + { + return; + } + + data_buff = &crash_data_buffer; + remain_len = buf_len; + written_len = 0; + do{ + if(data_buff->offset == 0) + { + CRASH_DUMP_TRACE(4,"__CRASH_DUMP:%s:%d offset = 0.w_seqnum = %d,dump_seqnum = %d.", + __func__,__LINE__,crash_dump_w_seqnum,crash_dump_cur_dump_seqnum); + memset((uint8_t*)&log_header,0,sizeof(log_header)); + log_header.magic = CRASH_DUMP_MAGIC_CODE; + log_header.version = CRASH_DUMP_VERSION; + log_header.seqnum = crash_dump_cur_dump_seqnum; + log_header.reseved[0] = '\0'; + log_header.reseved[1] = '\0'; + log_header.reseved[2] = '\0'; + log_header.reseved[3] = '\n'; + memcpy(data_buff->buffer + data_buff->offset, + (uint8_t*)&log_header, + sizeof(log_header)); + + data_buff->offset += sizeof(log_header); + crash_dump_cur_dump_seqnum ++; + } + + if(data_buff->offset + remain_len > CRASH_DUMP_SECTOR_SIZE) + { + uint_len = (CRASH_DUMP_SECTOR_SIZE - data_buff->offset); + } + else + { + uint_len = remain_len; + } + if(uint_len > 0) + { + memcpy(data_buff->buffer + data_buff->offset, + buf + written_len, + uint_len); + data_buff->offset += uint_len; + written_len += uint_len; + crash_dump_total_len += uint_len; + } + + if(data_buff->offset == CRASH_DUMP_SECTOR_SIZE) + { + crash_dump_write(crash_dump_flash_start_addr + crash_dump_flash_offs, + data_buff->buffer,data_buff->offset); + + crash_dump_flash_offs = crash_dump_flash_offs + data_buff->offset >= crash_dump_flash_len ?\ + 0 : crash_dump_flash_offs + data_buff->offset; + data_buff->offset = 0; + } + remain_len -= uint_len; + }while(remain_len > 0); +} + +static void _crash_dump_fault(const unsigned char *buf, unsigned int buf_len) +{ + _crash_dump_output(buf,buf_len); +} + +void crash_dump_init(void) +{ + uint32_t block_size = 0; + uint32_t sector_size = 0; + uint32_t page_size = 0; + uint32_t buffer_len = 0; + uint32_t dump_seqnum = 0; + uint32_t sector_seqnum = 0; + enum NORFLASH_API_RET_T result; + + hal_norflash_get_size(HAL_NORFLASH_ID_0,NULL, &block_size, §or_size, &page_size); + buffer_len = CRASH_DUMP_NORFALSH_BUFFER_LEN; + CRASH_DUMP_TRACE(4,"__CRASH_DUMP:%s: crash_dump_start = 0x%x, crash_dump_end = 0x%x, buff_len = 0x%x.", + __func__, + crash_dump_flash_start_addr, + crash_dump_flash_end_addr, + buffer_len); + + result = norflash_api_register( + NORFLASH_API_MODULE_ID_CRASH_DUMP, + HAL_NORFLASH_ID_0, + crash_dump_flash_start_addr, + crash_dump_flash_end_addr - crash_dump_flash_start_addr, + block_size, + sector_size, + page_size, + buffer_len, + NULL + ); + + if(result == NORFLASH_API_OK) + { + CRASH_DUMP_TRACE(1,"__CRASH_DUMP:%s: norflash_api_register ok.", __func__); + } + else + { + CRASH_DUMP_TRACE(2,"__CRASH_DUMP:%s: norflash_api_register failed,result = %d", __func__, result); + return; + } + + crash_dump_notify_cb = _crash_dump_notify; + crash_dump_output_cb = _crash_dump_output; + crash_dump_fault_cb = _crash_dump_fault; + + hal_trace_app_custom_register(crash_dump_notify_handler,crash_dump_output_handler,crash_dump_fault_handler); + _crash_dump_get_seqnum(&dump_seqnum,§or_seqnum); + crash_dump_cur_dump_seqnum = dump_seqnum; + crash_dump_flash_len = crash_dump_flash_end_addr - crash_dump_flash_start_addr; + crash_dump_flash_offs = sector_seqnum*CRASH_DUMP_BUFFER_LEN; + crash_data_buffer.offset = 0; + crash_data_buffer.buffer = NULL; + crash_dump_w_seqnum = 0; + crash_dump_total_len = 0; + crash_dump_is_init = true; +} + +void crash_dump_init_buffer(void) +{ + crash_data_buffer.offset = 0; + syspool_init_specific_size(CRASH_DUMP_BUFFER_LEN); + syspool_get_buff(&(crash_data_buffer.buffer), CRASH_DUMP_BUFFER_LEN); +} + +int32_t crash_dump_read(uint32_t addr,uint8_t* ptr,uint32_t len) +{ + enum NORFLASH_API_RET_T ret; + + ret = norflash_sync_read(NORFLASH_API_MODULE_ID_CRASH_DUMP, + addr, + ptr, + len); + if(ret != NORFLASH_API_OK) + { + CRASH_DUMP_TRACE(4,"__CRASH_DUMP:%s: norflash_sync_read,addr = 0x%x,len = 0x%x,ret = %d.", + __func__,addr,len,ret); + return ret; + } + return 0; +} + +int32_t crash_dump_write(uint32_t addr,uint8_t* ptr,uint32_t len) +{ + enum NORFLASH_API_RET_T ret; + + if(CRASH_LOG_ALIGN(addr,CRASH_DUMP_SECTOR_SIZE) != addr) + { + CRASH_DUMP_TRACE(2,"__CRASH_DUMP:%s: addr not aligned! addr = 0x%x.",__func__,addr); + return (int32_t)NORFLASH_API_BAD_ADDR; + } + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_CRASH_DUMP, + addr, + CRASH_DUMP_SECTOR_SIZE, + false); + if(ret != NORFLASH_API_OK) + { + CRASH_DUMP_TRACE(3,"__CRASH_DUMP:%s: norflash_api_erase failed! addr = 0x%x,ret = %d.", + __func__,addr,ret); + return (int32_t)ret; + } + ret = norflash_api_write(NORFLASH_API_MODULE_ID_CRASH_DUMP, + addr, + ptr, + len, + false); + if(ret != NORFLASH_API_OK) + { + CRASH_DUMP_TRACE(4,"__CRASH_DUMP:%s: norflash_api_write,addr = 0x%x,len = 0x%x,ret = %d.", + __func__,addr,len,ret); + return (int32_t)ret; + } + return 0; +} + +void crash_dump_notify_handler(enum HAL_TRACE_STATE_T state) +{ + if ((state == HAL_TRACE_STATE_CRASH_ASSERT_START) + || (state == HAL_TRACE_STATE_CRASH_FAULT_START)) { + norflash_api_flush_enable_all(); + crash_dump_init_buffer(); + } + + if(crash_dump_notify_cb) + { + crash_dump_notify_cb(state); + } +} + +void crash_dump_output_handler(const unsigned char *buf, unsigned int buf_len) +{ + if(crash_dump_output_cb) + { + crash_dump_output_cb(buf,buf_len); + } +} + +void crash_dump_fault_handler(const unsigned char *buf, unsigned int buf_len) +{ + if(crash_dump_fault_cb) + { + crash_dump_fault_cb(buf,buf_len); + } +} + +void crash_dump_set_flag(uint8_t is_happend) +{ + crash_dump_is_happend = is_happend; +} + +void crash_dump_register(HAL_TRACE_APP_NOTIFY_T notify_cb,HAL_TRACE_APP_OUTPUT_T crash_output_cb,HAL_TRACE_APP_OUTPUT_T crash_fault_cb) +{ + crash_dump_notify_cb = notify_cb; + crash_dump_output_cb = crash_output_cb; + crash_dump_fault_cb = crash_fault_cb; +} + +CRASH_DATA_BUFFER* crash_dump_get_buffer(void) +{ + return &crash_data_buffer; +} + +uint32_t crash_dump_get_type(void) +{ + return crash_dump_type; +} + + +#endif + diff --git a/services/nv_section/log_section/crash_dump_section.h b/services/nv_section/log_section/crash_dump_section.h new file mode 100644 index 0000000..1e35984 --- /dev/null +++ b/services/nv_section/log_section/crash_dump_section.h @@ -0,0 +1,152 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __CRASH_DUMP_SECTION_H__ +#define __CRASH_DUMP_SECTION_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#if 0 +#include "plat_types.h" + +#define CRASH_DUMP_MAGIC_CODE 0x504D5544 +#define CRASH_DUMP_ASSERT_CODE 0xEB6D0924 +#define CRASH_DUMP_EXCEPTION_CODE 0xC78BA332 +/* + * Total number of core registers stored + */ +#define CRASH_DUMP_REGISTERS_NUM 17 +#define CRASH_DUMP_REGISTERS_NUM_BYTES ((CRASH_DUMP_REGISTERS_NUM)*4) +/* + * Number bytes to store from stack + * - this is total, not per PSP/MSP + */ +#define CRASH_DUMP_STACK_NUM_BYTES 384 +#define CRASH_DUMP_FRAME_SIZE (1024*16) + +typedef struct { + uint32_t magicCode; // must be CRASH_DUMP_MAGIC_CODE + int32_t seqnum; // increased by 1 per crash + uint32_t partnum; // maximum crash log count saved in the flash + uint32_t reserved; + uint32_t bufpos; // valid content in the following buf array + uint32_t liteDumpOffset; + uint32_t crashCode; +} CRASH_OUTPUT_BUF_HEADER_T; + +/** + * This structure MUST be a total size + * of 0x4000 + */ +struct CRASH_OUTPUT_BUF_T { + CRASH_OUTPUT_BUF_HEADER_T hdr; + uint8_t buf[CRASH_DUMP_FRAME_SIZE - sizeof(CRASH_OUTPUT_BUF_HEADER_T)]; +}; + +/** Tell whether the system reboots because of a fresh assert or hardfault. */ +bool crashdump_is_crash_happened(void); +void crashdump_set_existing_flag(uint8_t isExisting); +/** + * Tell the flash offset of the latest crash dump + * -1 means there is no crash dump in the flash. + * Other values are the valid flash offset of the latest happend crash dump log. + */ +int32_t crashdump_get_latest_flash_offset(void); +/** Tell whether there is any crash dump logs in the flash. */ +bool crashdump_is_crash_dump_existing(void); +void crashdump_set_crash_happened_flag(uint8_t isHappened); +void crashdump_dumptoflash(void); +void crashdump_init_section_info(void); +#else + +#include "hal_trace.h" + +#define CRASH_DUMP_PREFIX "__CRASH_DUMP:" +#define CRASH_DUMP_TRACE(num,fmt, ...) TRACE(num,fmt, ##__VA_ARGS__) +#define CRASH_LOG_ALIGN(x,a) (uint32_t)(((x + a - 1)/a) * a) + + +#define CRASH_DUMP_SECTOR_SIZE 0x1000 +#define CRASH_DUMP_BUFFER_LEN (CRASH_DUMP_SECTOR_SIZE*2) +#define CRASH_DUMP_NORFALSH_BUFFER_LEN (CRASH_DUMP_BUFFER_LEN) + +#define DATA_BUFFER_STATE_FREE 0 +#define DATA_BUFFER_STATE_WRITTING 0x1 +#define DATA_BUFFER_STATE_WRITTEN 0x2 + +#define CRASH_DUMP_MAGIC_CODE 0x504D5544 +#define CRASH_DUMP_VERSION 0x00010001 + +#define CRASH_DUMP_ASSERT_CODE 0xEB6D0924 +#define CRASH_DUMP_EXCEPTION_CODE 0xC78BA332 + +typedef struct +{ + uint32_t magic; + uint32_t version; + uint32_t seqnum; + uint8_t reseved[4]; +}CRASH_DUMP_HEADER_T; + + +#define CRASH_DUMP_FRAME_SIZE (CRASH_DUMP_BUFFER_LEN) +typedef struct{ + uint32_t offset; + uint8_t *buffer; +}CRASH_DATA_BUFFER; + +void crash_dump_init(void); +void crash_dump_init_buffer(void); +int32_t crash_dump_read(uint32_t addr,uint8_t* ptr,uint32_t len); +int32_t crash_dump_write(uint32_t addr,uint8_t* ptr,uint32_t len); +void crash_dump_notify_handler(enum HAL_TRACE_STATE_T state); +void crash_dump_output_handler(const unsigned char *buf, unsigned int buf_len); +void crash_dump_fault_handler(const unsigned char *buf, unsigned int buf_len); +void crash_dump_set_flag(uint8_t is_happend); +void crash_dump_register(HAL_TRACE_APP_NOTIFY_T notify_cb,HAL_TRACE_APP_OUTPUT_T crash_output_cb,HAL_TRACE_APP_OUTPUT_T crash_fault_cb); +CRASH_DATA_BUFFER* crash_dump_get_buffer(void); +uint32_t crash_dump_get_type(void); + +// --gsound crash dump ------------- +typedef struct { + uint32_t magicCode; // must be CRASH_DUMP_MAGIC_CODE + uint32_t seqnum; // increased by 1 per crash + uint32_t partnum; // maximum crash log count saved in the flash + uint32_t reserved; + uint32_t bufpos; // valid content in the following buf array + uint32_t liteDumpOffset; + uint32_t crashCode; +} CRASH_OUTPUT_BUF_HEADER_T; + +/** + * This structure MUST be a total size + * of 0x1000 + */ + +struct CRASH_OUTPUT_BUF_T { + CRASH_OUTPUT_BUF_HEADER_T hdr; + uint8_t buf[CRASH_DUMP_FRAME_SIZE - sizeof(CRASH_OUTPUT_BUF_HEADER_T)]; +}; + +// --gsound crash dump end ------------- + +#endif +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/nv_section/log_section/log_section.c b/services/nv_section/log_section/log_section.c new file mode 100644 index 0000000..98601a5 --- /dev/null +++ b/services/nv_section/log_section/log_section.c @@ -0,0 +1,628 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include +#include "hal_trace.h" +#include "log_section.h" +#include +#include "hal_timer.h" +#include "hal_norflash.h" +#include "norflash_api.h" +#include "cmsis.h" +#include "hal_cache.h" +#include "hal_sleep.h" +#include "pmu.h" + +// #define DUMP_NO_ROLLBACK +#define LOG_DUMP_PREFIX "__LOG_DUMP:" +#if 0 +#define LOG_DUMP_TRACE(num,fmt, ...) TRACE(num,fmt, ##__VA_ARGS__) +#else +#define LOG_DUMP_TRACE(num,fmt, ...) +#endif +#define LOG_DUMP_TRACE_FORCE(num,fmt, ...) TRACE(num,fmt, ##__VA_ARGS__) +#define DUMP_LOG_ALIGN(x,a) (uint32_t)(((x + a - 1)/a) * a) + +extern uint32_t __log_dump_start; +extern uint32_t __log_dump_end; + +extern void watchdog_ping(void); + +static const uint32_t log_dump_flash_start_addr = (uint32_t)&__log_dump_start; +static const uint32_t log_dump_flash_end_addr = (uint32_t)&__log_dump_end; +static uint32_t log_dump_flash_len; + +static DATA_BUFFER data_buffer_list[LOG_DUMP_SECTOR_BUFFER_COUNT]; +static uint32_t log_dump_w_seqnum = 0; +static uint32_t log_dump_f_seqnum = 0; +static uint32_t log_dump_flash_offs = 0; +static uint32_t log_dump_cur_dump_seqnum; +static bool log_dump_is_init = false; +static bool log_dump_is_immediately; +static bool log_dump_is_bootup = true; +static enum LOG_DUMP_FLUSH_STATE log_dump_flash_state = LOG_DUMP_FLASH_STATE_IDLE; + +static enum NORFLASH_API_RET_T _flash_api_read(uint32_t addr, uint8_t* buffer, uint32_t len) +{ + + return norflash_sync_read(NORFLASH_API_MODULE_ID_LOG_DUMP, + addr, + buffer, + len); +} + +static void _flash_api_flush(void) +{ + hal_trace_pause(); + do + { + norflash_api_flush(); + } while(!norflash_api_buffer_is_free(NORFLASH_API_MODULE_ID_LOG_DUMP)); + + hal_trace_continue(); +} + +static enum NORFLASH_API_RET_T _flash_api_erase(uint32_t addr, + bool is_async) +{ + uint32_t lock; + enum NORFLASH_API_RET_T ret = NORFLASH_API_OK; + + if(log_dump_is_immediately) + { + is_async = false; + } + do + { + + lock = int_lock_global(); + hal_trace_pause(); + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_LOG_DUMP, + addr, + LOG_DUMP_SECTOR_SIZE, + is_async); + hal_trace_continue(); + int_unlock_global(lock); + + if (NORFLASH_API_OK == ret) + { + // LOG_DUMP_TRACE(1,LOG_DUMP_PREFIX"%s: norflash_api_erase ok!",__func__); + break; + } + else if(NORFLASH_API_BUFFER_FULL == ret) + { + norflash_api_flush(); + if(is_async) + { + break; + } + } + else + { + ASSERT(0, "_flash_api_erase: norflash_api_erase failed. ret = %d,addr = 0x%x.", ret,addr); + } + } while (1); + + return ret; +} + +static enum NORFLASH_API_RET_T _flash_api_write(uint32_t addr, + uint8_t* ptr, + uint32_t len, + bool is_async) +{ + uint32_t lock; + enum NORFLASH_API_RET_T ret = NORFLASH_API_OK; + + if(log_dump_is_immediately) + { + is_async = false; + } + + do + { + lock = int_lock_global(); + hal_trace_pause(); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_LOG_DUMP, + addr, + ptr, + len, + is_async); + + hal_trace_continue(); + + int_unlock_global(lock); + + if (NORFLASH_API_OK == ret) + { + // LOG_DUMP_TRACE(1,LOG_DUMP_PREFIX"%s: norflash_api_write ok!",__func__); + break; + } + else if (NORFLASH_API_BUFFER_FULL == ret) + { + norflash_api_flush(); + if(is_async) + { + LOG_DUMP_TRACE(1,LOG_DUMP_PREFIX"%s: norflash api buffer full",__func__); + break; + } + } + else + { + ASSERT(0,"_flash_api_write: norflash_api_write failed. ret = %d",ret); + } + }while (1); + + return ret; +} + +static int32_t _get_seqnum(uint32_t * dump_seqnum, uint32_t *sector_seqnum) +{ +#ifndef DUMP_NO_ROLLBACK + uint32_t i; + uint32_t count; + static enum NORFLASH_API_RET_T result; + LOG_DUMP_HEADER log_dump_header; + uint32_t max_dump_seqnum = 0; + uint32_t max_sector_seqnum = 0; + bool is_existed = false; + + count = (log_dump_flash_end_addr-log_dump_flash_start_addr)/LOG_DUMP_SECTOR_SIZE; + for(i = 0; i < count; i++) + { + result = _flash_api_read( + log_dump_flash_start_addr + i*LOG_DUMP_SECTOR_SIZE, + (uint8_t*)&log_dump_header, + sizeof(LOG_DUMP_HEADER)); + if(result == NORFLASH_API_OK) + { + if(log_dump_header.magic == DUMP_LOG_MAGIC + && log_dump_header.version == DUMP_LOG_VERSION + ) + { + is_existed = true; + if(log_dump_header.seqnum > max_dump_seqnum) + { + max_dump_seqnum = log_dump_header.seqnum; + max_sector_seqnum = i; + } + } + } + else + { + ASSERT(0,"_get_cur_sector_seqnum: _flash_api_read failed!result = %d.",result); + } + } + if(is_existed) + { + *dump_seqnum = max_dump_seqnum + 1; + *sector_seqnum = max_sector_seqnum + 1 >= count ? 0: max_sector_seqnum + 1; + } + else + { + *dump_seqnum = 0; + *sector_seqnum = 0; + } +#else + { + LOG_DUMP_HEADER log_dump_header; + _flash_api_read( + log_dump_flash_start_addr, + (uint8_t*)&log_dump_header, + sizeof(LOG_DUMP_HEADER)); + *dump_seqnum = 0; + *sector_seqnum = 0; + } +#endif + return 0; +} + +static int _log_dump_flush(uint32_t buff_state,bool is_async) +{ + enum NORFLASH_API_RET_T result; + static uint32_t total_len = 0; + DATA_BUFFER *data_buff; + + if(log_dump_flash_state == LOG_DUMP_FLASH_STATE_IDLE + && (log_dump_flash_offs % LOG_DUMP_SECTOR_SIZE) == 0) + { + LOG_DUMP_TRACE(3,LOG_DUMP_PREFIX"%s:%d,state = idle,addr = 0x%x.", + __func__,__LINE__,log_dump_flash_start_addr + log_dump_flash_offs); + result = _flash_api_erase(log_dump_flash_start_addr + log_dump_flash_offs,is_async); + if(result == NORFLASH_API_OK) + { + LOG_DUMP_TRACE(3,LOG_DUMP_PREFIX"%s:%d,erase ok,addr = 0x%x,", + __func__,__LINE__,log_dump_flash_start_addr + log_dump_flash_offs); + log_dump_flash_state = LOG_DUMP_FLASH_STATE_ERASED; + } + else + { + LOG_DUMP_TRACE(3,LOG_DUMP_PREFIX"%s: _flash_api_erase failed!addr = 0x%x,ret = %d.", + __func__,log_dump_flash_start_addr + log_dump_flash_offs, result); + } + } + else if(log_dump_flash_state == LOG_DUMP_FLASH_STATE_ERASED || + log_dump_flash_state == LOG_DUMP_FLASH_STATE_WRITTING) + { + data_buff = &data_buffer_list[log_dump_f_seqnum]; + if((data_buff->state & buff_state) != 0 + && data_buff->offset > 0) + { + LOG_DUMP_TRACE(3,LOG_DUMP_PREFIX"%s:%d,state = ERASED,f_seqnum = %d.", + __func__,__LINE__,log_dump_f_seqnum); + log_dump_flash_state = LOG_DUMP_FLASH_STATE_WRITTING; + result = _flash_api_write( + log_dump_flash_start_addr + log_dump_flash_offs, + data_buff->buffer, + data_buff->offset, + is_async); + if(result == NORFLASH_API_OK) + { + LOG_DUMP_TRACE(5,LOG_DUMP_PREFIX"%s:%d,write ok,addr = 0x%x,f_seqnum = 0x%x,total_len = 0x%x.", + __func__,__LINE__, + log_dump_flash_start_addr + log_dump_flash_offs, + log_dump_f_seqnum, + total_len); + + data_buff->state = DATA_BUFFER_STATE_FREE; + log_dump_f_seqnum = log_dump_f_seqnum + 1 == LOG_DUMP_SECTOR_BUFFER_COUNT ? + 0 : log_dump_f_seqnum + 1; + total_len += data_buff->offset; + + log_dump_flash_offs = log_dump_flash_offs + data_buff->offset >= log_dump_flash_len ? + 0 : log_dump_flash_offs + data_buff->offset; + log_dump_flash_state = LOG_DUMP_FLASH_STATE_IDLE; + } + else + { + LOG_DUMP_TRACE(2,LOG_DUMP_PREFIX"%s: _flash_api_write failed!ret = %d.",__func__,result); + return 3; + } + } + } + else + { + LOG_DUMP_TRACE(3,LOG_DUMP_PREFIX"%s:%d state = %d.", + __func__,__LINE__,log_dump_flash_state); + } + return 0; +} + +void _log_dump_flush_remain(void) +{ + uint32_t i; + uint32_t unfree_count = 0; + + do{ + unfree_count = 0; + for(i = 0; i < LOG_DUMP_SECTOR_BUFFER_COUNT; i++) + { + if(data_buffer_list[i].state != DATA_BUFFER_STATE_FREE) + { + unfree_count ++; + } + } + if(unfree_count == 0) + { + break; + } + _log_dump_flush(DATA_BUFFER_STATE_WRITTING | DATA_BUFFER_STATE_WRITTEN,false); + }while(1); + + _flash_api_flush(); +} + +int log_dump_flush_all(void) +{ + norflash_api_flush_enable_all(); + log_dump_is_immediately = true; + _log_dump_flush_remain(); + return 0; +} +int log_dump_flush(void) +{ + if(!log_dump_is_init) + { + return 0; + } + + return _log_dump_flush(DATA_BUFFER_STATE_WRITTEN, true); +} + +void log_dump_notify_handler(enum HAL_TRACE_STATE_T state) +{ + //uint32_t lock; + + if(!log_dump_is_init) + { + return; + } + LOG_DUMP_TRACE(3,LOG_DUMP_PREFIX"%s: state = %d,start_addr = 0x%x,end_addr = 0x%x.", + __func__,state,log_dump_flash_start_addr,log_dump_flash_end_addr); + LOG_DUMP_TRACE(3,LOG_DUMP_PREFIX"%s: dump_seqnum = 0x%x,flash_offset = 0x%x.", + __func__,log_dump_cur_dump_seqnum,log_dump_flash_offs); + + if(state == HAL_TRACE_STATE_CRASH_ASSERT_START + || state == HAL_TRACE_STATE_CRASH_FAULT_START) + { + norflash_api_flush_enable_all(); + log_dump_is_immediately = true; + } + else + { + LOG_DUMP_TRACE(2,LOG_DUMP_PREFIX" crash end."); + //lock = int_lock_global(); + _log_dump_flush_remain(); + //int_unlock_global(lock); + } +} + +void log_dump_output_handler(const unsigned char *buf, unsigned int buf_len) +{ + uint32_t write_len; + uint32_t written_len; + uint32_t remain_len; + LOG_DUMP_HEADER log_header; + DATA_BUFFER *data_buff; + + if(!log_dump_is_init) + { + return; + } + + if(strstr((char*)buf,LOG_DUMP_PREFIX) != NULL) + { + return; + } + + data_buff = &data_buffer_list[log_dump_w_seqnum]; + remain_len = buf_len; + written_len = 0; + do{ + if(data_buff->state == DATA_BUFFER_STATE_FREE + || data_buff->state == DATA_BUFFER_STATE_WRITTEN) + { + // LOG_DUMP_TRACE(3,LOG_DUMP_PREFIX"%s:%d data_buff->state is free.w_seqnum = %d.", + // __func__,__LINE__,log_dump_w_seqnum); + data_buff->state = DATA_BUFFER_STATE_WRITTING; + data_buff->offset = 0; + memset(data_buff->buffer,0,LOG_DUMP_SECTOR_SIZE); + + } + if(data_buff->offset == 0) + { +#ifndef DUMP_NO_ROLLBACK + // LOG_DUMP_TRACE(4,LOG_DUMP_PREFIX"%s:%d offset = 0.w_seqnum = %d,dump_seqnum = %d.", + // __func__,__LINE__,log_dump_w_seqnum,log_dump_cur_dump_seqnum); + memset((uint8_t*)&log_header,0,sizeof(log_header)); + log_header.magic = DUMP_LOG_MAGIC; + log_header.version = DUMP_LOG_VERSION; + log_header.seqnum = log_dump_cur_dump_seqnum; + if(log_dump_is_bootup) + { + log_header.is_bootup = 1; + log_dump_is_bootup = false; + } + else + { + log_header.is_bootup = 0; + } + log_header.reseved[0] = '\0'; + log_header.reseved[1] = '\0'; + log_header.reseved[2] = '\n'; + + memcpy(data_buff->buffer + data_buff->offset, + (uint8_t*)&log_header, + sizeof(log_header)); + + data_buff->offset += sizeof(log_header); +#else + if(log_dump_cur_dump_seqnum*LOG_DUMP_SECTOR_SIZE >= log_dump_flash_len) + { + log_header = log_header; + log_dump_is_bootup = log_dump_is_bootup; + break; + } +#endif + log_dump_cur_dump_seqnum ++; + } + + if(data_buff->offset + remain_len > LOG_DUMP_SECTOR_SIZE) + { + write_len = (LOG_DUMP_SECTOR_SIZE - data_buff->offset); + } + else + { + write_len = remain_len; + } + + if(write_len > 0) + { + memcpy(data_buff->buffer + data_buff->offset, + buf + written_len, + write_len); + data_buff->offset += write_len; + written_len += write_len; + } + + if(data_buff->offset == LOG_DUMP_SECTOR_SIZE) + { + data_buff->state = DATA_BUFFER_STATE_WRITTEN; + } + + remain_len -= write_len; + + if(data_buff->offset == LOG_DUMP_SECTOR_SIZE) + { + log_dump_w_seqnum = log_dump_w_seqnum + 1 == LOG_DUMP_SECTOR_BUFFER_COUNT ? + 0 : log_dump_w_seqnum + 1; + if(log_dump_w_seqnum == log_dump_f_seqnum) + { + log_dump_f_seqnum = log_dump_f_seqnum + 1 == LOG_DUMP_SECTOR_BUFFER_COUNT ? + 0 : log_dump_f_seqnum + 1; + } + // LOG_DUMP_TRACE(4,LOG_DUMP_PREFIX"%s:%d w_seqnum = %d,dump_seqnum = %d.", + // __func__,__LINE__,log_dump_w_seqnum,log_dump_cur_dump_seqnum); + + data_buff = &data_buffer_list[log_dump_w_seqnum]; + + ASSERT(data_buff->state == DATA_BUFFER_STATE_FREE || + data_buff->state == DATA_BUFFER_STATE_WRITTEN, + "log_dump_output_handler: data_buff state error! state = %d.", + data_buff->state); + } + }while(remain_len > 0); + +} + +void log_dump_callback(void* param) +{ + NORFLASH_API_OPERA_RESULT *opera_result; + + opera_result = (NORFLASH_API_OPERA_RESULT*)param; + + LOG_DUMP_TRACE_FORCE(6,LOG_DUMP_PREFIX"%s:type = %d, addr = 0x%x,len = 0x%x,remain = %d,result = %d.", + __func__, + opera_result->type, + opera_result->addr, + opera_result->len, + opera_result->remain_num, + opera_result->result); + { + static uint32_t is_fst = 1; + if(is_fst) + { + LOG_DUMP_TRACE(3,LOG_DUMP_PREFIX"%s:log_dump_start = 0x%x, log_dump_end = 0x%x.", + __func__, + log_dump_flash_start_addr, + log_dump_flash_end_addr); + is_fst = 0; + } + } +} + +void log_dump_init(void) +{ + uint32_t block_size = 0; + uint32_t sector_size = 0; + uint32_t page_size = 0; + uint32_t buffer_len = 0; + uint32_t dump_seqnum = 0; + uint32_t sector_seqnum = 0; + enum NORFLASH_API_RET_T result; + uint32_t i; + + log_dump_flash_len = log_dump_flash_end_addr - log_dump_flash_start_addr; + hal_norflash_get_size(HAL_NORFLASH_ID_0,NULL, &block_size, §or_size, &page_size); + buffer_len = LOG_DUMP_NORFALSH_BUFFER_LEN; + /* + LOG_DUMP_TRACE(4,LOG_DUMP_PREFIX"%s: log_dump_start = 0x%x, log_dump_len = 0x%x, buff_len = 0x%x.", + __func__, + log_dump_flash_start_addr, + log_dump_flash_len, + buffer_len); + */ + result = norflash_api_register( + NORFLASH_API_MODULE_ID_LOG_DUMP, + HAL_NORFLASH_ID_0, + log_dump_flash_start_addr, + log_dump_flash_end_addr - log_dump_flash_start_addr, + block_size, + sector_size, + page_size, + buffer_len, + log_dump_callback + ); + + if(result == NORFLASH_API_OK) + { + /* + LOG_DUMP_TRACE(1,LOG_DUMP_PREFIX"%s: norflash_api_register ok.", __func__); + */ + } + else + { + /* + LOG_DUMP_TRACE(2,LOG_DUMP_PREFIX"%s: norflash_api_register failed,result = %d.", __func__, result); + */ + return; + } + hal_trace_app_register(log_dump_notify_handler, log_dump_output_handler); + hal_sleep_set_sleep_hook(HAL_SLEEP_HOOK_DUMP_LOG, log_dump_flush); + _get_seqnum(&dump_seqnum,§or_seqnum); + log_dump_cur_dump_seqnum = dump_seqnum; + log_dump_flash_offs = sector_seqnum*LOG_DUMP_SECTOR_SIZE; + memset((uint8_t*)&data_buffer_list,0,sizeof(data_buffer_list)); + for(i = 0;i < LOG_DUMP_SECTOR_BUFFER_COUNT; i++) + { + data_buffer_list[i].state = DATA_BUFFER_STATE_FREE; + data_buffer_list[i].offset = 0; + } + log_dump_w_seqnum = 0; + log_dump_f_seqnum = 0; + log_dump_flash_state = LOG_DUMP_FLASH_STATE_IDLE; + log_dump_is_immediately = false; + log_dump_is_init = true; +} + +void log_dump_clear(void) +{ + uint32_t i; + uint32_t addr; + uint32_t lock = int_lock_global(); + + for(i = 0; i < log_dump_flash_len/LOG_DUMP_SECTOR_SIZE; i++) + { + addr = log_dump_flash_start_addr + i*LOG_DUMP_SECTOR_SIZE; + _flash_api_erase(addr,false); + } + + int_unlock_global(lock); +} + +#if 0 +uint8_t test_buff_r[LOG_DUMP_SECTOR_SIZE]; + +uint32_t test_log_dump_from_flash(uint32_t addr,uint32_t size) +{ + //uint32_t start_addr; + uint32_t i; + //uint8_t value = 0; + int32_t ret = 0; + enum NORFLASH_API_RET_T result = HAL_NORFLASH_OK; + + LOG_DUMP_TRACE(1,LOG_DUMP_PREFIX"%s enter!!!", __func__); + + for(i = 0; i < size/LOG_DUMP_SECTOR_SIZE; i++) + { + result = _flash_api_read((uint32_t)(addr)+ (i*LOG_DUMP_SECTOR_SIZE), + test_buff_r,LOG_DUMP_SECTOR_SIZE); + if(result != NORFLASH_API_OK) + { + ret = -1; + //LOG_DUMP_TRACE(2,LOG_DUMP_PREFIX"%s ret=%d", __func__, ret); + goto _func_end; + } + LOG_DUMP_TRACE(1,LOG_DUMP_PREFIX"%s", test_buff_r); + } + LOG_DUMP_TRACE(1,LOG_DUMP_PREFIX"%s end!!!", __func__); + +_func_end: + LOG_DUMP_TRACE(1,LOG_DUMP_PREFIX"_debug: flash checking end. ret = %d.",ret); + return ret; +} +#endif + diff --git a/services/nv_section/log_section/log_section.h b/services/nv_section/log_section/log_section.h new file mode 100644 index 0000000..efe8db6 --- /dev/null +++ b/services/nv_section/log_section/log_section.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __LOG_SECTION_H__ +#define __LOG_SECTION_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include + +#if 0 +void init_dump_log(void); +void dump_whole_logs(void); +//void log_update_time_stamp(void); +//void set_dump_log_flush(bool isEnable); +//bool is_dump_log_flush_pending(void); +//void flush_dump_log_handler(void); +void clear_dump_log(void); +uint32_t test_dump_log_from_flash(uint32_t addr,uint32_t size); +#else + +#define LOG_DUMP_SECTOR_SIZE 0x1000 +#define LOG_DUMP_SECTOR_BUFFER_COUNT 4 +#define LOG_DUMP_BUFFER_LEN (LOG_DUMP_SECTOR_SIZE*LOG_DUMP_SECTOR_BUFFER_COUNT) +#define LOG_DUMP_NORFALSH_BUFFER_LEN (LOG_DUMP_BUFFER_LEN*2) + +#define DATA_BUFFER_STATE_FREE 0 +#define DATA_BUFFER_STATE_WRITTING 0x1 +#define DATA_BUFFER_STATE_WRITTEN 0x2 + +#define DUMP_LOG_MAGIC 0xd5151001 +#define DUMP_LOG_VERSION 0x00010001 +// #define DUMP_LOG_NEWLINE '\n' + +enum LOG_DUMP_FLUSH_STATE +{ + LOG_DUMP_FLASH_STATE_IDLE, + LOG_DUMP_FLASH_STATE_ERASED, + LOG_DUMP_FLASH_STATE_WRITTING, + LOG_DUMP_FLASH_STATE_WRITTEN, +}; + +typedef struct +{ + uint32_t magic; + uint32_t version; + uint32_t seqnum; + uint8_t is_bootup; + uint8_t reseved[3]; +}LOG_DUMP_HEADER; + + +typedef struct{ + uint32_t state; + uint32_t offset; + uint8_t buffer[LOG_DUMP_SECTOR_SIZE]; +}DATA_BUFFER; + +void log_dump_init(void); +int log_dump_flush(void); +int log_dump_flush_all(void); +void log_dump_notify_handler(enum HAL_TRACE_STATE_T state); +void log_dump_output_handler(const unsigned char *buf, unsigned int buf_len); +void log_dump_callback(void* param); +void log_dump_clear(void); + +//uint32_t test_log_dump_from_flash(uint32_t addr,uint32_t size); +#endif +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/services/nv_section/nv_section_dbg.h b/services/nv_section/nv_section_dbg.h new file mode 100644 index 0000000..5618ac8 --- /dev/null +++ b/services/nv_section/nv_section_dbg.h @@ -0,0 +1,46 @@ +/** + * @file nv_section_dbg.h + * @author BES NV_SEC team + * @version 0.1 + * @date 2020-04-22 + * + * @copyright Copyright (c) 2015-2020 BES Technic. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + */ + + +#ifndef __NV_SECTION_DBG_H__ +#define __NV_SECTION_DBG_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +/*****************************header include********************************/ +#include "hal_trace.h" + +/******************************macro defination*****************************/ +#define LOG_V(str, ...) LOG_VERBOSE(LOG_MOD(NV_SEC), str, ##__VA_ARGS__) +#define LOG_D(str, ...) LOG_DEBUG(LOG_MOD(NV_SEC), str, ##__VA_ARGS__) +#define LOG_I(str, ...) LOG_INFO(LOG_MOD(NV_SEC), str, ##__VA_ARGS__) +#define LOG_W(str, ...) LOG_WARN(LOG_MOD(NV_SEC), str, ##__VA_ARGS__) +#define LOG_E(str, ...) LOG_ERROR(LOG_MOD(NV_SEC), str, ##__VA_ARGS__) + +/******************************type defination******************************/ + +/****************************function declearation**************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __NV_SECTION_DBG_H__ */ \ No newline at end of file diff --git a/services/nv_section/userdata_section/Makefile b/services/nv_section/userdata_section/Makefile new file mode 100644 index 0000000..87fc5f5 --- /dev/null +++ b/services/nv_section/userdata_section/Makefile @@ -0,0 +1,63 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +all_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +all_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +filtout_c := +filtout_cpp := + +ifneq ($(BISTO_ENABLE),1) +filtout_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*gsound.c)) +filtout_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*gsound.cpp)) +endif + +ifneq ($(OTA_ENABLE), 1) +filtout_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*ota.c)) +filtout_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*ota.cpp)) +endif + +obj_c := $(filter-out $(filtout_c),$(all_c)) +obj_cpp := $(filter-out $(filtout_cpp),$(all_cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -I$(obj)/../../nv_section/userdata_section \ + -I$(obj)/../../nv_section/include \ + -I$(obj)/../platform/cmsis/inc \ + -Iutils/crc32 \ + $(BT_IF_INCLUDES) \ + -Iutils/hexdump \ + -Iapps/key \ + -Iservices/bt_app \ + -Iplatform/drivers/ana \ + -Iservices/nv_section/customparam_section \ + -Iservices/nv_section/factory_section \ + -Iservices/ble_stack/common/api \ + -Iservices/ble_stack/ble_ip \ + -Iutils/heap \ + -Iservices/nvrecord \ + -Iservices/norflash_api \ + -Iservices/nv_setion/userdata_section \ + -Iservices/voicepath/gsound/gsound_target_api_read_only \ + -Iservices/voicepath/gsound/gsound_custom/inc \ + -Iplatform/drivers/norflash \ + -Iplatform/hal \ + -Iplatform/cmsis/inc \ + -Iservices/osif/ \ + -Iservices/ota \ + -Iutils/cqueue \ + -Iservices/nv_section \ + -Iutils/aes_cmac + +ccflags-y += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) + +ifeq ($(FLASH_SUSPEND),1) +ccflags-y += -DFLASH_SUSPEND +endif + +ifeq ($(TX_IQ_CAL),1) +subdir-ccflags-y += -DTX_IQ_CAL +endif + diff --git a/services/nv_section/userdata_section/nvrecord_ble.c b/services/nv_section/userdata_section/nvrecord_ble.c new file mode 100644 index 0000000..5e9819e --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_ble.c @@ -0,0 +1,468 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) +#include +#include +#include +#include "nvrecord_extension.h" +#include "nvrecord_ble.h" +#include "hal_trace.h" +#include "co_math.h" +#include "tgt_hardware.h" +#include "hal_timer.h" +#include "besbt.h" + +#define ble_nv_debug +#ifdef ble_nv_debug +#define ble_trace TRACE +#else +#define ble_trace +#endif + +static NV_RECORD_PAIRED_BLE_DEV_INFO_T *nvrecord_ble_p = NULL; +static uint8_t INVALID_ADDR[BTIF_BD_ADDR_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +void nvrecord_rebuild_paired_ble_dev_info(NV_RECORD_PAIRED_BLE_DEV_INFO_T *pPairedBtInfo) +{ + memset(( uint8_t * )pPairedBtInfo, 0, sizeof(NV_RECORD_PAIRED_BLE_DEV_INFO_T)); + pPairedBtInfo->saved_list_num = 0; //init saved num + + uint8_t index; + //avoid ble irk collision low probability + uint32_t generatedSeed = hal_sys_timer_get(); + for (uint8_t index = 0; index < sizeof(bt_addr); index++) + { + generatedSeed ^= (((uint32_t)(bt_addr[index])) << (hal_sys_timer_get() & 0xF)); + } + srand(generatedSeed); + + // generate a new IRK + for (index = 0; index < BLE_IRK_SIZE; index++) + { + pPairedBtInfo->self_info.ble_irk[index] = ( uint8_t )co_rand_word(); + } +} + +static bool blerec_specific_value_prepare(const BleDeviceinfo *param_rec) +{ + // Preparations before adding new ble record: + // 1. If not existing. Check the record count. If it's BLE_RECORD_NUM, + // move 0-(BLE_RECORD_NUM-2) right side by one slot, to discard the last one and + // leave slot 0, decrease the record number. + // If it's smaller than BLE_RECORD_NUM, move 0-(count-1) right side by one slot, leave slot 0, + // don't change the record number. + // 2. If existing already and the location is entryToFree , move 0-(entryToFree-1) + // right side by one slot, leave slot 0. Decrease the record number for adding the new one. + + bool isEntryExisting = false; + uint8_t entryToFree = 0; + NV_RECORD_PAIRED_BLE_DEV_INFO_T *dest_ptr; + + dest_ptr = nvrecord_ble_p; + TRACE(3,"%s start search addr %p list_num=%d", __func__, dest_ptr, dest_ptr->saved_list_num); + + if (dest_ptr->saved_list_num > 0) + { + for (uint8_t i = 0; i < dest_ptr->saved_list_num; i++) + { + if (0 == memcmp(dest_ptr->ble_nv[i].peer_bleAddr, param_rec->peer_bleAddr, BLE_ADDR_SIZE)) + { + ble_trace(2,"%s Find the existing entry %d", __func__, i); + DUMP8("%02x ", ( uint8_t * )param_rec, sizeof(BleDeviceinfo)); + DUMP8("%02x ", ( uint8_t * )&dest_ptr->ble_nv[i], sizeof(BleDeviceinfo)); + if (!memcmp(( uint8_t * )param_rec, ( uint8_t * )&dest_ptr->ble_nv[i], sizeof(BleDeviceinfo))) + { + ble_trace(0,"The new coming BLE device info is the same as the recorded."); + return false; + } + memset(&(dest_ptr->ble_nv[i]), 0, sizeof(BleDeviceinfo)); + entryToFree = i; + dest_ptr->saved_list_num--; + isEntryExisting = true; + break; + } + } + } + else + { + return true; + } + + if (!isEntryExisting) + { + if (BLE_RECORD_NUM == dest_ptr->saved_list_num) + { + TRACE(0,"<=====>blerec list is full,delete the oldest and add param_rec to list"); + for (uint8_t k = 0; k < BLE_RECORD_NUM - 1; k++) + { + memcpy(&(dest_ptr->ble_nv[BLE_RECORD_NUM - 1 - k]), + &(dest_ptr->ble_nv[BLE_RECORD_NUM - 2 - k]), + sizeof(BleDeviceinfo)); + } + dest_ptr->saved_list_num--; + } + else + { + for (uint8_t k = 0; k < dest_ptr->saved_list_num; k++) + { + memcpy(&(dest_ptr->ble_nv[dest_ptr->saved_list_num - k]), + &(dest_ptr->ble_nv[dest_ptr->saved_list_num - 1 - k]), + sizeof(BleDeviceinfo)); + } + } + } + else + { + for (uint8_t list_updata = 0; list_updata < entryToFree; list_updata++) + { + memcpy(&(dest_ptr->ble_nv[entryToFree - list_updata]), + &(dest_ptr->ble_nv[entryToFree - list_updata - 1]), + sizeof(BleDeviceinfo)); + } + } + + return true; +} + +void nv_record_blerec_init(void) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (NULL == nvrecord_ble_p) + { + nvrecord_ble_p = &(nvrecord_extension_p->ble_pair_info); + if (!memcmp(nvrecord_ble_p->self_info.ble_addr, INVALID_ADDR, BTIF_BD_ADDR_SIZE)) + { + memcpy(nvrecord_ble_p->self_info.ble_addr, bt_get_ble_local_address(), BTIF_BD_ADDR_SIZE); + } + } + nv_record_post_write_operation(lock); +} + +NV_RECORD_PAIRED_BLE_DEV_INFO_T* nv_record_blerec_get_ptr(void) +{ + return nvrecord_ble_p; +} + +void nv_record_blerec_get_local_irk(uint8_t *pIrk) +{ + memcpy(pIrk, nvrecord_ble_p->self_info.ble_irk, BLE_IRK_SIZE); +} + +bool nv_record_blerec_get_bd_addr_from_irk(uint8_t *pBdAddr, uint8_t *pIrk) +{ + if (nvrecord_ble_p->saved_list_num > 0) + { + for (uint8_t index = 0; index < nvrecord_ble_p->saved_list_num; index++) + { + if (!memcmp(pIrk, nvrecord_ble_p->ble_nv[index].IRK, BLE_IRK_SIZE)) + { + memcpy(pBdAddr, nvrecord_ble_p->ble_nv[index].peer_bleAddr, BLE_ADDR_SIZE); + return true; + } + } + return false; + } + else + { + return false; + } +} + +int nv_record_blerec_add(const BleDeviceinfo *param_rec) +{ + int nRet = 0; + + uint8_t isNeedToUpdateNv = true; + isNeedToUpdateNv = blerec_specific_value_prepare(param_rec); + + if (isNeedToUpdateNv) + { + uint32_t lock = nv_record_pre_write_operation(); + + //add device info into nv struct + memcpy(nvrecord_ble_p->ble_nv[0].peer_bleAddr, param_rec->peer_bleAddr, BLE_ADDR_SIZE); //addr + nvrecord_ble_p->ble_nv[0].EDIV = param_rec->EDIV; //EDIV + memcpy(nvrecord_ble_p->ble_nv[0].RANDOM, param_rec->RANDOM, BLE_ENC_RANDOM_SIZE); //RANDOM + memcpy(nvrecord_ble_p->ble_nv[0].LTK, param_rec->LTK, BLE_LTK_SIZE); //LTK + memcpy(nvrecord_ble_p->ble_nv[0].IRK, param_rec->IRK, BLE_IRK_SIZE); //IRK + nvrecord_ble_p->ble_nv[0].bonded = param_rec->bonded; //bond status + nvrecord_ble_p->saved_list_num++; //updata saved num + nv_record_post_write_operation(lock); + + nv_record_update_runtime_userdata(); + nv_record_flash_flush(); + TRACE(2,"%s CURRENT BLE LIST NUM=%d", __func__, nvrecord_ble_p->saved_list_num); + } + +#ifdef ble_nv_debug + for (uint8_t k = 0; k < nvrecord_ble_p->saved_list_num; k++) + { + TRACE(0,"========================================="); + TRACE(1,"Num %d BLE record:", k); + TRACE(0,"BLE addr:"); + DUMP8("%02x ", ( uint8_t * )nvrecord_ble_p->ble_nv[k].peer_bleAddr, BLE_ADDR_SIZE); + TRACE(1,"NV EDIV %d and random is:", nvrecord_ble_p->ble_nv[k].EDIV); + DUMP8("%02x ", ( uint8_t * )nvrecord_ble_p->ble_nv[k].RANDOM, BLE_ENC_RANDOM_SIZE); + TRACE(0,"NV LTK:"); + DUMP8("%02x ", ( uint8_t * )nvrecord_ble_p->ble_nv[k].LTK, BLE_LTK_SIZE); + TRACE(0,"NV irk:"); + DUMP8("%02x ", ( uint8_t * )nvrecord_ble_p->ble_nv[k].IRK, BLE_IRK_SIZE); + } +#endif + return nRet; +} + +uint8_t nv_record_ble_fill_irk(uint8_t *irkToFill) +{ + NV_RECORD_PAIRED_BLE_DEV_INFO_T *find_ptr = nvrecord_ble_p; + + if ((NULL == find_ptr) || (0 == find_ptr->saved_list_num)) + { + return 0; + } + + if (find_ptr->saved_list_num > 0) + { + for (uint8_t index = 0; index < find_ptr->saved_list_num; index++) + { + memcpy(irkToFill + index * BLE_IRK_SIZE, find_ptr->ble_nv[index].IRK, BLE_IRK_SIZE); + } + return find_ptr->saved_list_num; + } + else + { + return 0; + } +} + +//when master send encription req,if bonded,use ltk to bonding again(skip the pair step) +bool nv_record_ble_record_find_ltk_through_static_bd_addr(uint8_t *pBdAddr, uint8_t *ltk) +{ + NV_RECORD_PAIRED_BLE_DEV_INFO_T *find_ptr = nvrecord_ble_p; + + if ((NULL == find_ptr) || (0 == find_ptr->saved_list_num)) + { + TRACE(3,"%s find data failed, ptr:%x, list_num:%d", __func__, (uint32_t)find_ptr, find_ptr->saved_list_num); + return false; + } + + for (uint8_t find_index = 0; find_index < find_ptr->saved_list_num; find_index++) + { + if (!memcmp(find_ptr->ble_nv[find_index].peer_bleAddr, pBdAddr, BLE_ADDR_SIZE)) + { + ble_trace(2,"%s FIND LTK IN NV SUCCESS %p", __func__, find_ptr->ble_nv[find_index].LTK); + memcpy(ltk, find_ptr->ble_nv[find_index].LTK, BLE_LTK_SIZE); + return true; + } + } + return false; +} + +bool nv_record_ble_record_Once_a_device_has_been_bonded(void) +{ + NV_RECORD_PAIRED_BLE_DEV_INFO_T *find_ptr = nvrecord_ble_p; + + if ((NULL == find_ptr) || (0 == find_ptr->saved_list_num)) + { + return false; + } + + for (uint8_t find_index = 0; find_index < find_ptr->saved_list_num; find_index++) + { + if (find_ptr->ble_nv[find_index].bonded == true) + { + return true; + } + } + return false; +} + +void nv_record_ble_delete_entry(uint8_t *pBdAddr) +{ + NV_RECORD_PAIRED_BLE_DEV_INFO_T *find_ptr = nvrecord_ble_p; + + if ((NULL == find_ptr) || (0 == find_ptr->saved_list_num)) + { + return; + } + + int8_t indexToDelete = -1; + + for (uint8_t find_index = 0; find_index < find_ptr->saved_list_num; find_index++) + { + if (!memcmp(find_ptr->ble_nv[find_index].peer_bleAddr, pBdAddr, BLE_ADDR_SIZE)) + { + indexToDelete = find_index; + break; + } + } + + if (indexToDelete >= 0) + { + uint32_t lock = nv_record_pre_write_operation(); + + uint8_t index; + for (index = indexToDelete; index < find_ptr->saved_list_num - 1; index++) + { + memcpy(&(find_ptr->ble_nv[index]), + &(find_ptr->ble_nv[index + 1]), + sizeof(BleDeviceinfo)); + } + + memset(( uint8_t * )&(find_ptr->ble_nv[index]), 0, sizeof(BleDeviceinfo)); + find_ptr->saved_list_num--; + nv_record_update_runtime_userdata(); + + nv_record_post_write_operation(lock); + } +} + +#ifdef TWS_SYSTEM_ENABLED +static bool tws_use_same_ble_addr(uint8_t *peer_ble_addr) +{ + TRACE(1,"[%s] peer addr:", __func__); + DUMP8("%x ", peer_ble_addr, BTIF_BD_ADDR_SIZE); + + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + + if (!memcmp(pNvExtRec->ble_pair_info.self_info.ble_addr, peer_ble_addr, BTIF_BD_ADDR_SIZE)) + { + return true; + } + + return false; +} + +void nv_record_extension_update_tws_ble_info(NV_RECORD_PAIRED_BLE_DEV_INFO_T *info) +{ + ASSERT(info, "null pointer received in [%s]", __func__); + + bool isNvExtentionPendingForUpdate = false; + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + + /// disable the MPU protection for write operation + uint32_t lock = nv_record_pre_write_operation(); + + if (tws_use_same_ble_addr(info->self_info.ble_addr)) + { + if (memcmp(&pNvExtRec->ble_pair_info.self_info, &info->self_info, sizeof(BLE_BASIC_INFO_T))) + { + TRACE(0,"save the peer ble info to self_info"); + + memcpy(&pNvExtRec->ble_pair_info.self_info, &info->self_info, sizeof(BLE_BASIC_INFO_T)); + nv_record_extension_update(); + isNvExtentionPendingForUpdate = true; + } + } + + if (memcmp(&pNvExtRec->tws_info.ble_info, &info->self_info, sizeof(BLE_BASIC_INFO_T))) + { + TRACE(0,"save the peer ble info to tws_info"); + + memcpy(&pNvExtRec->tws_info.ble_info, &info->self_info, sizeof(BLE_BASIC_INFO_T)); + nv_record_extension_update(); + isNvExtentionPendingForUpdate = true; + } + + if (isNvExtentionPendingForUpdate) + { + nv_record_flash_flush(); + } + + /// enable the MPU protection after the write operation + nv_record_post_write_operation(lock); + + TRACE(0,"peer addr:"); + DUMP8("0x%02x ", pNvExtRec->tws_info.ble_info.ble_addr,BTIF_BD_ADDR_SIZE); + TRACE(0,"peer irk"); + DUMP8("0x%02x ", pNvExtRec->tws_info.ble_info.ble_irk, BLE_IRK_SIZE); +} + +void nv_record_tws_exchange_ble_info(void) +{ + TRACE(1,"[%s]+++", __func__); + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + uint8_t ble_address[6] = {0, 0, 0, 0, 0, 0}; + + if (tws_use_same_ble_addr(pNvExtRec->tws_info.ble_info.ble_addr)) + { + TRACE(0,"tws use same ble addr"); + return; + } + + if (!memcmp(pNvExtRec->tws_info.ble_info.ble_addr, ble_address, BTIF_BD_ADDR_SIZE)) + { + TRACE(0,"don't have tws ble addr"); + return; + } + + /// disable the MPU protection for write operation + uint32_t lock = nv_record_pre_write_operation(); + +#ifdef BLE_USE_RPA + uint8_t temp_ble_irk[BLE_IRK_SIZE]; + memcpy(temp_ble_irk, pNvExtRec->ble_pair_info.self_info.ble_irk, BLE_IRK_SIZE); + memcpy(pNvExtRec->ble_pair_info.self_info.ble_irk, pNvExtRec->tws_info.ble_info.ble_irk, BLE_IRK_SIZE); + memcpy(pNvExtRec->tws_info.ble_info.ble_irk, temp_ble_irk, BLE_IRK_SIZE); + TRACE(0,"current local ble irk:"); + DUMP8("0x%02x ", pNvExtRec->ble_pair_info.self_info.ble_irk, BLE_IRK_SIZE); +#else + uint8_t temp_ble_addr[BTIF_BD_ADDR_SIZE]; + memcpy(temp_ble_addr, pNvExtRec->ble_pair_info.self_info.ble_addr, BTIF_BD_ADDR_SIZE); + memcpy(pNvExtRec->ble_pair_info.self_info.ble_addr, pNvExtRec->tws_info.ble_info.ble_addr, BTIF_BD_ADDR_SIZE); + memcpy(pNvExtRec->tws_info.ble_info.ble_addr, temp_ble_addr, BTIF_BD_ADDR_SIZE); + memcpy(bt_get_ble_local_address(), pNvExtRec->ble_pair_info.self_info.ble_addr, BTIF_BD_ADDR_SIZE); + TRACE(0,"current local ble addr:"); + DUMP8("0x%02x ", pNvExtRec->ble_pair_info.self_info.ble_addr, BTIF_BD_ADDR_SIZE); + + bt_set_ble_local_address(pNvExtRec->ble_pair_info.self_info.ble_addr); +#endif + + nv_record_extension_update(); + + /// enable the MPU protection after the write operation + nv_record_post_write_operation(lock); + + TRACE(1,"[%s]---", __func__); +} + +uint8_t *nv_record_tws_get_self_ble_info(void) +{ + TRACE(1,"[%s]+++", __func__); + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + + TRACE(0,"current local ble addr:"); + DUMP8("0x%02x ", pNvExtRec->ble_pair_info.self_info.ble_addr, BTIF_BD_ADDR_SIZE); + + TRACE(1,"[%s]---", __func__); + return pNvExtRec->ble_pair_info.self_info.ble_addr; +} + +uint8_t *nv_record_tws_get_peer_ble_addr(void) +{ + TRACE(1,"[%s]+++", __func__); + NV_EXTENSION_RECORD_T *pNvExtRec = nv_record_get_extension_entry_ptr(); + + TRACE(0,"current peer ble addr:"); + DUMP8("0x%02x ", pNvExtRec->ble_pair_info.ble_nv[0].peer_bleAddr, BTIF_BD_ADDR_SIZE); + + TRACE(1,"[%s]---", __func__); + return pNvExtRec->ble_pair_info.ble_nv[0].peer_bleAddr; +} + +#endif + +#endif //#if defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nv_section/userdata_section/nvrecord_ble.h b/services/nv_section/userdata_section/nvrecord_ble.h new file mode 100644 index 0000000..3fe57ab --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_ble.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) + +#ifndef NVRECORD_BLE_H +#define NVRECORD_BLE_H + +#include "nvrecord_extension.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int nv_record_blerec_add(const BleDeviceinfo *param_rec); +bool nv_record_ble_record_find_ltk_through_static_bd_addr(uint8_t* pBdAddr, uint8_t *ltk); +bool nv_record_ble_record_Once_a_device_has_been_bonded(void); +void nv_record_ble_delete_entry(uint8_t* pBdAddr); +uint8_t nv_record_ble_fill_irk(uint8_t* ltkToFill); +void nv_record_blerec_init(void); +NV_RECORD_PAIRED_BLE_DEV_INFO_T* nv_record_blerec_get_ptr(void); +void nv_record_blerec_get_local_irk(uint8_t* pIrk); +bool nv_record_blerec_get_bd_addr_from_irk(uint8_t* pBdAddr, uint8_t* pIrk); +void nvrecord_rebuild_paired_ble_dev_info(NV_RECORD_PAIRED_BLE_DEV_INFO_T* pPairedBtInfo); + +#ifdef TWS_SYSTEM_ENABLED +void nv_record_extension_update_tws_ble_info(NV_RECORD_PAIRED_BLE_DEV_INFO_T *info); +void nv_record_tws_exchange_ble_info(void); +uint8_t *nv_record_tws_get_self_ble_info(void); +uint8_t *nv_record_tws_get_peer_ble_addr(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif +#endif // #if defined(NEW_NV_RECORD_ENABLED) + diff --git a/services/nv_section/userdata_section/nvrecord_bt.c b/services/nv_section/userdata_section/nvrecord_bt.c new file mode 100644 index 0000000..3eeb604 --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_bt.c @@ -0,0 +1,506 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) +#include +#include +#include +#include "nvrecord_extension.h" +#include "nvrecord_bt.h" +#include "hal_trace.h" + +void ram_record_ddbrec_init(void) +{ +} + +void nvrecord_rebuild_paired_bt_dev_info(NV_RECORD_PAIRED_BT_DEV_INFO_T* pPairedBtInfo) +{ + memset((uint8_t *)pPairedBtInfo, 0, sizeof(NV_RECORD_PAIRED_BT_DEV_INFO_T)); + + pPairedBtInfo->pairedDevNum = 0; +} + +void nv_record_btdevicerecord_set_a2dp_profile_active_state(btdevice_profile* device_plf, bool isActive) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (isActive != device_plf->a2dp_act) + { + nv_record_update_runtime_userdata(); + } + device_plf->a2dp_act = isActive; + + nv_record_post_write_operation(lock); +} + +void nv_record_btdevicerecord_set_hfp_profile_active_state(btdevice_profile* device_plf, bool isActive) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (isActive != device_plf->hfp_act) + { + nv_record_update_runtime_userdata(); + } + device_plf->hfp_act = isActive; + + nv_record_post_write_operation(lock); +} + +void nv_record_btdevicerecord_set_hsp_profile_active_state(btdevice_profile* device_plf, bool isActive) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (isActive != device_plf->hsp_act) + { + nv_record_update_runtime_userdata(); + } + device_plf->hsp_act = isActive; + + nv_record_post_write_operation(lock); +} + +void nv_record_btdevicerecord_set_a2dp_profile_codec(btdevice_profile* device_plf, uint8_t a2dpCodec) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (a2dpCodec != device_plf->a2dp_codectype) + { + nv_record_update_runtime_userdata(); + } + device_plf->a2dp_codectype = a2dpCodec; + + nv_record_post_write_operation(lock); +} + +int nv_record_get_paired_dev_count(void) +{ + if (NULL == nvrecord_extension_p) + { + return 0; + } + + return nvrecord_extension_p->bt_pair_info.pairedDevNum; +} + +/* +return: + -1: enum dev failure. + 0: without paired dev. + 1: only 1 paired dev,store@record1. + 2: get 2 paired dev.notice:record1 is the latest record. +*/ +int nv_record_enum_latest_two_paired_dev(btif_device_record_t* record1,btif_device_record_t* record2) +{ + if((NULL == record1) || (NULL == record2) || (NULL == nvrecord_extension_p)) + { + return -1; + } + + if (nvrecord_extension_p->bt_pair_info.pairedDevNum > 0) + { + if (1 == nvrecord_extension_p->bt_pair_info.pairedDevNum) + { + memcpy((uint8_t *)record1, (uint8_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[0]), + sizeof(btif_device_record_t)); + return 1; + } + else + { + memcpy((uint8_t *)record1, (uint8_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[0]), + sizeof(btif_device_record_t)); + memcpy((uint8_t *)record2, (uint8_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[1]), + sizeof(btif_device_record_t)); + return 2; + } + } + else + { + return 0; + } +} + +static void nv_record_print_dev_record(const btif_device_record_t* record) +{ + TRACE(0,"nv record bdAddr = "); + DUMP8("%02x ",record->bdAddr.address,sizeof(record->bdAddr.address)); + TRACE(0,"record_trusted = "); + DUMP8("%d ",&record->trusted,sizeof((uint8_t)record->trusted)); + TRACE(0,"record_linkKey = "); + DUMP8("%02x ",record->linkKey,sizeof(record->linkKey)); + TRACE(0,"record_keyType = "); + DUMP8("%x ",&record->keyType,sizeof(record->keyType)); + TRACE(0,"record_pinLen = "); + DUMP8("%x ",&record->pinLen,sizeof(record->pinLen)); +} + +void nv_record_all_ddbrec_print(void) +{ + if (NULL == nvrecord_extension_p) + { + TRACE(0,"No BT paired dev."); + return; + } + + if (nvrecord_extension_p->bt_pair_info.pairedDevNum > 0) + { + for(uint8_t tmp_i=0; tmp_i < nvrecord_extension_p->bt_pair_info.pairedDevNum; tmp_i++) + { + btif_device_record_t record; + bt_status_t ret_status; + ret_status = nv_record_enum_dev_records(tmp_i, &record); + if (BT_STS_SUCCESS == ret_status) + { + nv_record_print_dev_record(&record); + } + } + } + else + { + TRACE(0,"No BT paired dev."); + } +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_enum_dev_records(unsigned short index,btif_device_record_t* record) +{ + btif_device_record_t *recaddr = NULL; + + if((index >= nvrecord_extension_p->bt_pair_info.pairedDevNum) || (NULL == nvrecord_extension_p)) + { + return BT_STS_FAILED; + } + + recaddr = (btif_device_record_t *)&(nvrecord_extension_p->bt_pair_info.pairedBtDevInfo[index].record); + memcpy(record, recaddr, sizeof(btif_device_record_t)); + nv_record_print_dev_record(record); + return BT_STS_SUCCESS; +} + +static int8_t nv_record_get_bt_pairing_info_index(const uint8_t* btAddr) +{ + NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = + (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); + + for (uint8_t index = 0; index < pBtDevInfo->pairedDevNum; index++) + { + if (!memcmp(pBtDevInfo->pairedBtDevInfo[index].record.bdAddr.address, + btAddr, BTIF_BD_ADDR_SIZE)) + { + return (int8_t)index; + } + } + + return -1; +} + +/********************************************** +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +**********************************************/ +static bt_status_t POSSIBLY_UNUSED nv_record_ddbrec_add(const btif_device_record_t* param_rec) +{ + if ((NULL == param_rec) || (NULL == nvrecord_extension_p)) + { + return BT_STS_FAILED; + } + + uint32_t lock = nv_record_pre_write_operation(); + + bool isFlushNv = false; + + // try to find the entry + int8_t indexOfEntry = -1; + NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = + (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); + indexOfEntry = nv_record_get_bt_pairing_info_index(param_rec->bdAddr.address); + + if (-1 == indexOfEntry) + { + // don't exist, need to add to the head of the entry list + if (MAX_BT_PAIRED_DEVICE_COUNT == pBtDevInfo->pairedDevNum) + { + for (uint8_t k = 0; k < MAX_BT_PAIRED_DEVICE_COUNT - 1; k++) + { + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[MAX_BT_PAIRED_DEVICE_COUNT - 1 - k]), + (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[MAX_BT_PAIRED_DEVICE_COUNT - 2 - k]), + sizeof(nvrec_btdevicerecord)); + } + pBtDevInfo->pairedDevNum--; + } + else + { + for (uint8_t k = 0; k < pBtDevInfo->pairedDevNum; k++) + { + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[pBtDevInfo->pairedDevNum - k]), + (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[pBtDevInfo->pairedDevNum - 1 - k]), + sizeof(nvrec_btdevicerecord)); + } + } + + // fill the default value + nvrec_btdevicerecord* nvrec_pool_record = &(pBtDevInfo->pairedBtDevInfo[0]); + memcpy((uint8_t *)&(nvrec_pool_record->record), (uint8_t *)param_rec, + sizeof(btif_device_record_t)); + nvrec_pool_record->device_vol.a2dp_vol = NVRAM_ENV_STREAM_VOLUME_A2DP_VOL_DEFAULT; + nvrec_pool_record->device_vol.hfp_vol = NVRAM_ENV_STREAM_VOLUME_HFP_VOL_DEFAULT; + nvrec_pool_record->device_plf.hfp_act = false; + nvrec_pool_record->device_plf.hsp_act = false; + nvrec_pool_record->device_plf.a2dp_act = false; +#ifdef BTIF_DIP_DEVICE + nvrec_pool_record->vend_id = 0; + nvrec_pool_record->vend_id_source = 0; +#endif + + pBtDevInfo->pairedDevNum++; + + // need to flush the nv record + isFlushNv = true; + } + else + { + // exist + // check whether it's already at the head + // if not, move it to the head + if (indexOfEntry > 0) + { + nvrec_btdevicerecord record; + memcpy((uint8_t *)&record, (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry]), + sizeof(record)); + + // if not, move it to the head + for (uint8_t k = 0; k < indexOfEntry; k++) + { + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry - k]), + (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry - 1 - k]), + sizeof(nvrec_btdevicerecord)); + } + + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0]), (uint8_t *)&record, + sizeof(record)); + + // update the link info + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0].record), (uint8_t *)param_rec, + sizeof(btif_device_record_t)); + + // need to flush the nv record + isFlushNv = true; + } + // else, check whether the link info needs to be updated + else + { + if (memcmp((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0].record), + (uint8_t *)param_rec, sizeof(btif_device_record_t))) + { + // update the link info + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[0].record), (uint8_t *)param_rec, + sizeof(btif_device_record_t)); + + // need to flush the nv record + isFlushNv = true; + } + } + } + + TRACE(1,"paired Bt dev:%d", pBtDevInfo->pairedDevNum); + TRACE(1,"Is to flush nv: %d", isFlushNv); + nv_record_all_ddbrec_print(); + + if (isFlushNv) + { + nv_record_update_runtime_userdata(); + } + + nv_record_post_write_operation(lock); + + return BT_STS_SUCCESS; +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_add(SECTIONS_ADP_ENUM type, void *record) +{ + bt_status_t retstatus = BT_STS_FAILED; + + if ((NULL == record) || (section_none == type)) + { + return BT_STS_FAILED; + } + + switch(type) + { + case section_usrdata_ddbrecord: + retstatus = nv_record_ddbrec_add(record); + break; + default: + break; + } + + return retstatus; +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_ddbrec_find(const bt_bdaddr_t* bd_ddr, btif_device_record_t *record) +{ + if ((NULL == bd_ddr) || (NULL == record) || (NULL == nvrecord_extension_p)) + { + return BT_STS_FAILED; + } + + int8_t indexOfEntry = -1; + NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = + (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); + indexOfEntry = nv_record_get_bt_pairing_info_index(bd_ddr->address); + + if (-1 == indexOfEntry) + { + return BT_STS_FAILED; + } + else + { + memcpy((uint8_t *)record, (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry].record), + sizeof(btif_device_record_t)); + return BT_STS_SUCCESS; + } +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_ddbrec_delete(const bt_bdaddr_t *bdaddr) +{ + if (NULL == nvrecord_extension_p) + { + return BT_STS_FAILED; + } + + int8_t indexOfEntry = -1; + NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = + (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); + indexOfEntry = nv_record_get_bt_pairing_info_index(bdaddr->address); + if (-1 == indexOfEntry) + { + return BT_STS_FAILED; + } + + uint32_t lock = nv_record_pre_write_operation(); + + for (uint8_t k = 0; k < pBtDevInfo->pairedDevNum - indexOfEntry - 1; k++) + { + memcpy((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry + k]), + (uint8_t *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry + 1 + k]), + sizeof(nvrec_btdevicerecord)); + } + + memset((uint8_t *)&(pBtDevInfo->pairedBtDevInfo[pBtDevInfo->pairedDevNum-1]), 0, + sizeof(nvrec_btdevicerecord)); + pBtDevInfo->pairedDevNum--; + + nv_record_update_runtime_userdata(); + + nv_record_post_write_operation(lock); + return BT_STS_SUCCESS; +} + +int nv_record_btdevicerecord_find(const bt_bdaddr_t *bd_ddr, nvrec_btdevicerecord **record) +{ + if ((NULL == bd_ddr) || (NULL == record) || (NULL == nvrecord_extension_p)) + { + return -1; + } + + int8_t indexOfEntry = -1; + NV_RECORD_PAIRED_BT_DEV_INFO_T* pBtDevInfo = + (NV_RECORD_PAIRED_BT_DEV_INFO_T *)(&(nvrecord_extension_p->bt_pair_info)); + indexOfEntry = nv_record_get_bt_pairing_info_index(bd_ddr->address); + + if (-1 == indexOfEntry) + { + return -1; + } + + *record = + (nvrec_btdevicerecord *)&(pBtDevInfo->pairedBtDevInfo[indexOfEntry]); + return 0; +} + +void nv_record_btdevicerecord_set_a2dp_vol(nvrec_btdevicerecord* pRecord, int8_t vol) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (vol != pRecord->device_vol.a2dp_vol) + { + nv_record_update_runtime_userdata(); + pRecord->device_vol.a2dp_vol = vol; + } + + + nv_record_post_write_operation(lock); +} + +void nv_record_btdevicerecord_set_hfp_vol(nvrec_btdevicerecord* pRecord, int8_t vol) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (vol != pRecord->device_vol.hfp_vol) + { + nv_record_update_runtime_userdata(); + pRecord->device_vol.hfp_vol = vol; + } + + nv_record_post_write_operation(lock); +} + +void nv_record_btdevicevolume_set_a2dp_vol(btdevice_volume* device_vol, int8_t vol) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (vol != device_vol->a2dp_vol) + { + nv_record_update_runtime_userdata(); + device_vol->a2dp_vol = vol; + } + + nv_record_post_write_operation(lock); + +} + +void nv_record_btdevicevolume_set_hfp_vol(btdevice_volume* device_vol, int8_t vol) +{ + uint32_t lock = nv_record_pre_write_operation(); + if (vol != device_vol->hfp_vol) + { + nv_record_update_runtime_userdata(); + device_vol->hfp_vol = vol; + } + + nv_record_post_write_operation(lock); + +} + +void nv_record_btdevicerecord_set_vend_id_and_source(nvrec_btdevicerecord* pRecord, int16_t vend_id, int16_t vend_id_source) +{ +#ifdef BTIF_DIP_DEVICE + TRACE(2, "%s vend id 0x%x", __func__, vend_id); + uint32_t lock = nv_record_pre_write_operation(); + if (vend_id != pRecord->vend_id) + { + nv_record_update_runtime_userdata(); + pRecord->vend_id = vend_id; + pRecord->vend_id_source = vend_id_source; + } + + nv_record_post_write_operation(lock); +#endif +} + +#endif //#if defined(NEW_NV_RECORD_ENABLED) + diff --git a/services/nv_section/userdata_section/nvrecord_bt.h b/services/nv_section/userdata_section/nvrecord_bt.h new file mode 100644 index 0000000..110ac30 --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_bt.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) + +#ifndef NVRECORD_BT_H +#define NVRECORD_BT_H + +#include "nvrecord_extension.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NVRAM_ENV_STREAM_VOLUME_A2DP_VOL_DEFAULT (AUDIO_OUTPUT_VOLUME_DEFAULT) +#define NVRAM_ENV_STREAM_VOLUME_HFP_VOL_DEFAULT (AUDIO_OUTPUT_VOLUME_DEFAULT) + +void nv_record_btdevicerecord_set_a2dp_vol(nvrec_btdevicerecord* pRecord, int8_t vol); +void nv_record_btdevicerecord_set_hfp_vol(nvrec_btdevicerecord* pRecord, int8_t vol); +void nv_record_btdevicevolume_set_a2dp_vol(btdevice_volume* device_vol, int8_t vol); +void nv_record_btdevicevolume_set_hfp_vol(btdevice_volume* device_vol, int8_t vol); +void nv_record_btdevicerecord_set_vend_id_and_source(nvrec_btdevicerecord* pRecord, int16_t vend_id, int16_t vend_id_source); +void nv_record_btdevicerecord_set_a2dp_profile_active_state(btdevice_profile* device_plf, bool isActive); +void nv_record_btdevicerecord_set_hfp_profile_active_state(btdevice_profile* device_plf, bool isActive); +void nv_record_btdevicerecord_set_hsp_profile_active_state(btdevice_profile* device_plf, bool isActive); +int nv_record_enum_latest_two_paired_dev(btif_device_record_t* record1,btif_device_record_t* record2); +void nv_record_all_ddbrec_print(void); +void nv_record_update_runtime_userdata(void); +void nvrecord_rebuild_paired_bt_dev_info(NV_RECORD_PAIRED_BT_DEV_INFO_T* pPairedBtInfo); +int nv_record_btdevicerecord_find(const bt_bdaddr_t *bd_ddr, nvrec_btdevicerecord **record); +void nv_record_btdevicerecord_set_a2dp_profile_codec(btdevice_profile* device_plf, uint8_t a2dpCodec); +bt_status_t nv_record_ddbrec_delete(const bt_bdaddr_t *bdaddr); +bt_status_t nv_record_enum_dev_records(unsigned short index,btif_device_record_t* record); +bt_status_t nv_record_ddbrec_find(const bt_bdaddr_t *bd_ddr, btif_device_record_t*record); +bt_status_t nv_record_add(SECTIONS_ADP_ENUM type,void *record); +int nv_record_get_paired_dev_count(void); +void ram_record_ddbrec_init(void); +#ifdef __cplusplus +} +#endif +#endif +#endif // #if defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nv_section/userdata_section/nvrecord_dma_config.c b/services/nv_section/userdata_section/nvrecord_dma_config.c new file mode 100644 index 0000000..084cd6d --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_dma_config.c @@ -0,0 +1,151 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef NEW_NV_RECORD_ENABLED + +#include +#include +#include "nvrecord_extension.h" +#include "nvrecord_dma_config.h" +#include "nvrecord.h" +#include "hal_trace.h" + +#ifdef NVREC_BAIDU_DATA_SECTION +extern uint32_t* __factory_start; + +void nvrecord_rebuild_dma_configuration(NV_DMA_CONFIGURATION_T* pDmaConfig) +{ + memset((uint8_t *)pDmaConfig, 0, sizeof(NV_DMA_CONFIGURATION_T)); + pDmaConfig->fmfreq = BAIDU_DATA_DEF_FM_FREQ; +} + +int nvrec_baidu_data_init(void) +{ + if (NULL == nvrecord_extension_p) + { + return -1; + } + + uint32_t lock = nv_record_pre_write_operation(); + nvrecord_rebuild_dma_configuration(&(nvrecord_extension_p->dma_config)); + nv_record_update_runtime_userdata(); + nv_record_post_write_operation(lock); + return 0; +} + +int nvrec_get_fm_freq(void) +{ + if (NULL == nvrecord_extension_p) + { + return -1; + } + + int _fmfreq = nvrecord_extension_p->dma_config.fmfreq; + + TRACE(2,"%s:get fm freq %d", __func__, _fmfreq); + return _fmfreq; +} + +int nvrec_set_fm_freq(int fmfreq) +{ + if (NULL == nvrecord_extension_p) + { + return -1; + } + + uint32_t lock = nv_record_pre_write_operation(); + nvrecord_extension_p->dma_config.fmfreq = fmfreq; + nv_record_update_runtime_userdata(); + nv_record_post_write_operation(lock); + +#if defined(NVREC_BAIDU_DATA_FLUSH_DIRECT) + nv_record_flash_flush_int(false); +#endif + + return 0; +} + +int nvrec_get_rand(char *rand) +{ + char _rand[BAIDU_DATA_RAND_LEN]; + int8_t copy_len = 0; + + if (NULL == rand) + { + return 1; + } + + if (NULL == nvrecord_extension_p) + { + //_rand = BAIDU_DATA_DEF_RAND; + copy_len = (sizeof(BAIDU_DATA_DEF_RAND)dma_config.rand, BAIDU_DATA_RAND_LEN); + } + + memcpy(rand, _rand, BAIDU_DATA_RAND_LEN); + TRACE(2,"%s:rand %s", __func__, rand); + return 0; +} + +int nvrec_set_rand(char *rand) +{ + if (NULL == rand) + { + return -1; + } + + if (NULL == nvrecord_extension_p) + { + return -1; + } + + uint32_t lock = nv_record_pre_write_operation(); + memcpy(nvrecord_extension_p->dma_config.rand, rand, BAIDU_DATA_RAND_LEN); + nv_record_update_runtime_userdata(); + nv_record_post_write_operation(lock); + +#if defined(NVREC_BAIDU_DATA_FLUSH_DIRECT) + nv_record_flash_flush_int(false); +#endif + + return 0; +} + +//#define GET_SN_FROM_FACTORY +int nvrec_dev_get_sn(char *sn) +{ + + if (NULL == sn) + { + return -1; + } +#ifdef GET_SN_FROM_FACTORY + unsigned int sn_addr; + sn_addr = (unsigned int)(__factory_start + rev2_dev_prod_sn); +#else + char sn_addr[BAIDU_DATA_SN_LEN] = "01234567890123sf"; +#endif + memcpy((void *)sn, (void *)sn_addr, BAIDU_DATA_SN_LEN); + + return 0; +} + +#endif // #ifdef NVREC_BAIDU_DATA_SECTION + +#endif // #ifdef NEW_NV_RECORD_ENABLED diff --git a/services/nv_section/userdata_section/nvrecord_dma_config.h b/services/nv_section/userdata_section/nvrecord_dma_config.h new file mode 100644 index 0000000..3a73d29 --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_dma_config.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef NEW_NV_RECORD_ENABLED +#ifdef NVREC_BAIDU_DATA_SECTION + +#ifndef __NVRECORD_DMA_CONFIG_H__ +#define __NVRECORD_DMA_CONFIG_H__ + +#include "nvrecord_extension.h" + +#define BAIDU_DATA_DEF_RAND "abcdefghi" + +#ifdef __cplusplus +extern "C" { +#endif + +int nvrec_baidu_data_init(void); +int nvrec_get_fm_freq(void); +int nvrec_set_fm_freq(int fmfreq); +int nvrec_get_rand(char *rand); +int nvrec_set_rand(char *rand); +void nvrecord_rebuild_dma_configuration(NV_DMA_CONFIGURATION_T* pDmaConfig); +int nvrec_dev_get_sn(char *sn); + +#ifdef __cplusplus +} +#endif +#endif +#endif // #ifdef NVREC_BAIDU_DATA_SECTION +#endif // #ifdef NEW_NV_RECORD_ENABLED + diff --git a/services/nv_section/userdata_section/nvrecord_env.c b/services/nv_section/userdata_section/nvrecord_env.c new file mode 100644 index 0000000..9cc2dbe --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_env.c @@ -0,0 +1,116 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) +#include +#include +#include +#include "nvrecord_extension.h" +#include "nvrecord_env.h" +#include "hal_trace.h" + +static struct nvrecord_env_t localSystemInfo; + +void nvrecord_rebuild_system_env(struct nvrecord_env_t* pSystemEnv) +{ + memset((uint8_t *)pSystemEnv, 0, sizeof(struct nvrecord_env_t)); + + pSystemEnv->media_language.language = NVRAM_ENV_MEDIA_LANGUAGE_DEFAULT; + pSystemEnv->ibrt_mode.mode = NVRAM_ENV_TWS_MODE_DEFAULT; + pSystemEnv->ibrt_mode.tws_connect_success = 0; + pSystemEnv->factory_tester_status.status = NVRAM_ENV_FACTORY_TESTER_STATUS_DEFAULT; + + pSystemEnv->aiManagerInfo.voice_key_enable = false; + pSystemEnv->aiManagerInfo.setedCurrentAi = 0; + pSystemEnv->aiManagerInfo.aiStatusDisableFlag = 0; + pSystemEnv->aiManagerInfo.amaAssistantEnableStatus = 1; + + localSystemInfo = *pSystemEnv; +} + +int nv_record_env_get(struct nvrecord_env_t **nvrecord_env) +{ + if (NULL == nvrecord_env) + { + return -1; + } + + if (NULL == nvrecord_extension_p) + { + return -1; + } + + localSystemInfo = nvrecord_extension_p->system_info; + *nvrecord_env = &localSystemInfo; + + return 0; +} + +int nv_record_env_set(struct nvrecord_env_t *nvrecord_env) +{ + if (NULL == nvrecord_extension_p) + { + return -1; + } + + uint32_t lock = nv_record_pre_write_operation(); + nvrecord_extension_p->system_info = *nvrecord_env; + + nv_record_update_runtime_userdata(); + nv_record_post_write_operation(lock); + return 0; +} + +void nv_record_update_ibrt_info(uint32_t newMode, bt_bdaddr_t *ibrtPeerAddr) +{ + if (NULL == nvrecord_extension_p) + { + return; + } + + uint32_t lock = nv_record_pre_write_operation(); + + TRACE(2,"##%s,%d",__func__,newMode); + nvrecord_extension_p->system_info.ibrt_mode.mode = newMode; + memcpy(nvrecord_extension_p->system_info.ibrt_mode.record.bdAddr.address, + ibrtPeerAddr->address, BTIF_BD_ADDR_SIZE); + + nv_record_update_runtime_userdata(); + nv_record_post_write_operation(lock); +} + + +void nv_record_update_factory_tester_status(uint32_t status) +{ + if (NULL == nvrecord_extension_p) + { + return; + } + + uint32_t lock = nv_record_pre_write_operation(); + + nvrecord_extension_p->system_info.factory_tester_status.status = status; + + nv_record_update_runtime_userdata(); + nv_record_post_write_operation(lock); +} + +int nv_record_env_init(void) +{ + nv_record_open(section_usrdata_ddbrecord); + return 0; +} +#endif // #if defined(NEW_NV_RECORD_ENABLED) + diff --git a/services/nv_section/userdata_section/nvrecord_env.h b/services/nv_section/userdata_section/nvrecord_env.h new file mode 100644 index 0000000..d772f8a --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_env.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) + +#ifndef NVRECORD_ENV_H +#define NVRECORD_ENV_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "me_api.h" +#include "nvrecord_extension.h" + +#define NVRAM_ENV_MEDIA_LANGUAGE_DEFAULT (0) +#define NVRAM_ENV_TWS_MODE_DEFAULT (0xff) +#define NVRAM_ENV_FACTORY_TESTER_STATUS_DEFAULT (0xaabbccdd) +#define NVRAM_ENV_FACTORY_TESTER_STATUS_TEST_PASS (0xffffaa55) + +int nv_record_env_init(void); +int nv_record_env_get(struct nvrecord_env_t **nvrecord_env); +int nv_record_env_set(struct nvrecord_env_t *nvrecord_env); +void nv_record_update_ibrt_info(uint32_t newMode,bt_bdaddr_t *ibrtPeerAddr); +void nvrecord_rebuild_system_env(struct nvrecord_env_t* pSystemEnv); +void nv_record_update_factory_tester_status(uint32_t status); + +#ifdef __cplusplus +} +#endif +#endif +#endif // #if defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nv_section/userdata_section/nvrecord_extension.c b/services/nv_section/userdata_section/nvrecord_extension.c new file mode 100644 index 0000000..b524eaf --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_extension.c @@ -0,0 +1,1091 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef NEW_NV_RECORD_ENABLED +#include +#include +#include +#include "cmsis.h" +#include "nvrecord_extension.h" +#include "hal_trace.h" +#include "crc32.h" +#include "hal_sleep.h" +#include "hal_norflash.h" +#include "norflash_api.h" +#include "norflash_drv.h" +#include "nvrecord_bt.h" +#include "nvrecord_env.h" +#include "nvrecord_ble.h" +#include "nvrecord_dma_config.h" +#include "nvrecord_fp_account_key.h" +#include "customparam_section.h" +#include "mpu.h" +#include "besbt.h" +#include "hal_timer.h" + +extern uint32_t __userdata_start[]; +extern uint32_t __userdata_end[]; +extern void nvrecord_rebuild_system_env(struct nvrecord_env_t* pSystemEnv); +extern void nvrecord_rebuild_paired_bt_dev_info(NV_RECORD_PAIRED_BT_DEV_INFO_T* pPairedBtInfo); +#ifdef GFPS_ENABLED +extern void nvrecord_rebuild_fp_account_key(NV_FP_ACCOUNT_KEY_RECORD_T* pFpAccountKey); +#endif +#ifdef NVREC_BAIDU_DATA_SECTION +extern void nvrecord_rebuild_dma_configuration(NV_DMA_CONFIGURATION_T* pDmaConfig); +#endif + +typedef enum +{ + NV_STATE_IDLE, + NV_STATE_MAIN_ERASING, + NV_STATE_MAIN_ERASED, + NV_STATE_MAIN_WRITTING, + NV_STATE_MAIN_WRITTEN, + NV_STATE_MAIN_DONE, + NV_STATE_BAK_ERASING, + NV_STATE_BAK_ERASED, + NV_STATE_BAK_WRITTING, + NV_STATE_BAK_WRITTEN, + NV_STATE_BAK_DONE, +}NV_STATE; + +typedef struct +{ + bool is_update; + NV_STATE state; + uint32_t written_size; +}NV_FLUSH_STATE; + +static NV_FLUSH_STATE nv_flsh_state; +static bool nvrec_init = false; +static uint32_t _user_data_main_start; +static uint32_t _user_data_bak_start; +static uint8_t _nv_burn_buf[NV_EXTENSION_PAGE_SIZE]; + +NV_EXTENSION_RECORD_T *nvrecord_extension_p = NULL; + +/* + *Note: the NV_EXTENSION_MIRROR_RAM_SIZE must be power of 2 + */ +#if defined(__ARM_ARCH_8M_MAIN__) +#define __NV_BUF_MPU_ALIGNED __ALIGNED(0x20) +#else +/* + * armv7 mpu require the address must be aligned to the section size and + * the section size must be algined to power of 2 + */ +#define __NV_BUF_MPU_ALIGNED __ALIGNED(NV_EXTENSION_MIRROR_RAM_SIZE) +#endif + +static NV_MIRROR_BUF_T local_extension_data __NV_BUF_MPU_ALIGNED + __attribute__((section(".sram_data"))) = +{ + .nv_record = { + { // header + NV_EXTENSION_MAGIC_NUMBER, + NV_EXTENSION_MAJOR_VERSION, + NV_EXTENSION_MINOR_VERSION, + NV_EXTENSION_VALID_LEN, + 0, + }, + + { // system info + }, + + { // bt_pair_info + 0 + }, + + { // ble_pair_info + + }, + +#ifdef TWS_SYSTEM_ENABLED + { // tws_info + + }, +#endif + +#ifdef GFPS_ENABLED + { // fp_account_key_rec + 0 + }, +#endif + +#ifdef NVREC_BAIDU_DATA_SECTION + { // dma_config + BAIDU_DATA_DEF_FM_FREQ, + }, +#endif + +#ifdef TILE_DATAPATH + { + {0} + }, +#endif + +#ifdef OTA_ENABLED + { + {0,}, + }, +#endif + +#if defined(BISTO_ENABLED) + { + true, + }, +#endif + +#if 1//def TX_IQ_CAL + { + BT_IQ_INVALID_MAGIC_NUM, + {0}, + {0}, + }, +#endif + // TODO: + // If want to extend the nvrecord while keeping the history information, + // append the new items to the tail of NV_EXTENSION_RECORD_T and + // set their intial content here + }, +}; + +STATIC_ASSERT(sizeof(local_extension_data) <= NV_EXTENSION_MIRROR_RAM_SIZE, "NV local buffer too small"); + +static int nv_record_extension_flush(bool is_async); + +#ifdef TILE_DATAPATH +static void nvrecord_rebuild_tileconfig(NV_TILE_INFO_CONFIG_T *tileConfig) +{ + memset((uint8_t*)tileConfig,0,sizeof(NV_TILE_INFO_CONFIG_T)); +} +#endif + +#ifdef OTA_ENABLED +static void nvrecord_rebuild_ota_info(NV_OTA_INFO_T *ota_info) +{ + memset((uint8_t *)ota_info, 0, OTA_DEVICE_CNT * sizeof(NV_OTA_INFO_T)); +} +#endif + +#if defined(BISTO_ENABLED) +static void nvrecord_rebuild_gsound_info(NV_GSOUND_INFO_T *gsound_info) +{ + memset((uint8_t*)gsound_info,0,sizeof(NV_GSOUND_INFO_T)); +} +#endif + +#if 1//def TX_IQ_CAL +static void nvrecord_rebuild_btiqcalconfig(BT_IQ_CALIBRATION_CONFIG_T *btIqCalConfig) +{ + memset((uint8_t*)btIqCalConfig,0,sizeof(BT_IQ_CALIBRATION_CONFIG_T)); + btIqCalConfig->validityMagicNum = BT_IQ_INVALID_MAGIC_NUM; +} +#endif + +static bool nv_record_data_is_valid(NV_EXTENSION_RECORD_T *nv_record) +{ + bool is_valid = false; + + NVRECORD_HEADER_T* pExtRecInFlash = &nv_record->header; + uint8_t* pData = (uint8_t*)nv_record + NV_EXTENSION_HEADER_SIZE; + + TRACE(0,"nv ext magic 0x%x valid len %d", pExtRecInFlash->magicNumber, + pExtRecInFlash->validLen); + + if ((NV_EXTENSION_MAJOR_VERSION == pExtRecInFlash->majorVersion) && + (NV_EXTENSION_MAGIC_NUMBER == pExtRecInFlash->magicNumber)) + { + // check whether the data length is valid + if (pExtRecInFlash->validLen <= NV_EXTENSION_SIZE-NV_EXTENSION_HEADER_SIZE) + { + // check crc32 + uint32_t crc = crc32(0, pData, pExtRecInFlash->validLen); + TRACE(1,"generated crc32: 0x%x, header crc: 0x%x", + crc, pExtRecInFlash->crc32); + if (crc == pExtRecInFlash->crc32) + { + // correct + TRACE(2,"Nv extension is valid."); + + TRACE(2,"Former nv ext valid len %d", pExtRecInFlash->validLen); + TRACE(2,"Current FW version nv ext valid len %d", NV_EXTENSION_VALID_LEN); + + if (NV_EXTENSION_VALID_LEN < pExtRecInFlash->validLen) + { + TRACE(0,"Valid length of extension must be increased," + "use the default value."); + } + else + { + if(NV_EXTENSION_VALID_LEN > pExtRecInFlash->validLen) + { + TRACE(2, "NV extension is extended! (0x%x) -> (0x%x)", + pExtRecInFlash->validLen,NV_EXTENSION_VALID_LEN); + } + is_valid = true; + } + } + } + } + + return is_valid; + +} + +static bool nv_record_items_is_valid(NV_EXTENSION_RECORD_T *nv_record) +{ + nv_record = nv_record; +#if 0 + NV_RECORD_PAIRED_BT_DEV_INFO_T *pbt_pair_info; + pbt_pair_info = &nv_record->bt_pair_info; + TRACE(1,"%s: pairedDevNum: %d ", __func__,pbt_pair_info->pairedDevNum); + for(uint8_t i = 0; i < pbt_pair_info->pairedDevNum; i++) + { + DUMP8("0x%x,", (uint8_t*)pbt_pair_info->pairedBtDevInfo[i].record.bdAddr.address,6); + } +#endif + // TODO: add cheking for nv_record items. + + return true; +} + +static void nv_record_set_default(NV_EXTENSION_RECORD_T *nv_record) +{ + memset((uint8_t*)nv_record, 0 ,sizeof(NV_EXTENSION_RECORD_T)); + nvrecord_rebuild_system_env(&(nv_record->system_info)); + nvrecord_rebuild_paired_bt_dev_info(&(nv_record->bt_pair_info)); + nvrecord_rebuild_paired_ble_dev_info(&(nv_record->ble_pair_info)); +#ifdef GFPS_ENABLED + nvrecord_rebuild_fp_account_key(&(nv_record->fp_account_key_rec)); +#endif + +#ifdef NVREC_BAIDU_DATA_SECTION + nvrecord_rebuild_dma_configuration(&(nv_record->dma_config)); +#endif + +#ifdef TILE_DATAPATH + nvrecord_rebuild_tileconfig(&nv_record->tileConfig); +#endif + +#if defined(BISTO_ENABLED) + nvrecord_rebuild_gsound_info(&nv_record->gsound_info); +#endif + +#ifdef OTA_ENABLED + nvrecord_rebuild_ota_info((NV_OTA_INFO_T *)&nv_record->ota_info); +#endif + +#if 1//def TX_IQ_CAL + nvrecord_rebuild_btiqcalconfig(&nv_record->btIqCalConfig); +#endif + + nv_record->header.magicNumber = NV_EXTENSION_MAGIC_NUMBER; + nv_record->header.majorVersion = NV_EXTENSION_MAJOR_VERSION; + nv_record->header.minorVersion = NV_EXTENSION_MINOR_VERSION; + nv_record->header.validLen = NV_EXTENSION_VALID_LEN; + nv_record->header.crc32 = + crc32(0, ((uint8_t *)nv_record + NV_EXTENSION_HEADER_SIZE), + NV_EXTENSION_VALID_LEN); +} + +static void _nv_record_extension_init(void) +{ + enum NORFLASH_API_RET_T result; + uint32_t sector_size = 0; + uint32_t block_size = 0; + uint32_t page_size = 0; + + hal_norflash_get_size(HAL_NORFLASH_ID_0, + NULL, + &block_size, + §or_size, + &page_size); + result = norflash_api_register(NORFLASH_API_MODULE_ID_USERDATA_EXT, + HAL_NORFLASH_ID_0, + ((uint32_t)__userdata_start), + ((uint32_t)__userdata_end - (uint32_t)__userdata_start), + block_size, + sector_size, + page_size, + NV_EXTENSION_SIZE*2, + nv_extension_callback + ); + ASSERT(result == NORFLASH_API_OK,"_nv_record_extension_init: module register failed! result = %d.",result); +} + +uint32_t nv_record_pre_write_operation(void) +{ + uint32_t lock = int_lock_global(); + mpu_clear(MPU_ID_USER_DATA_SECTION); + return lock; +} + +void nv_record_post_write_operation(uint32_t lock) +{ + int ret = 0; + uint32_t nv_start = (uint32_t)&local_extension_data.nv_record; + uint32_t len = NV_EXTENSION_MIRROR_RAM_SIZE; + + ret = mpu_set(MPU_ID_USER_DATA_SECTION, nv_start, len, 0, MPU_ATTR_READ); + int_unlock_global(lock); + TRACE(2,"set mpu 0x%x len %d result %d", nv_start, len, ret); +} + +static void nv_record_extension_init(void) +{ + uint32_t lock; + bool main_is_valid = false; + bool bak_is_valid = false; + bool data_is_valid = false; + + if(nvrec_init) + { + return; + } + _user_data_main_start = (uint32_t)__userdata_start; + _user_data_bak_start = (uint32_t)__userdata_start + NV_EXTENSION_SIZE; + + lock = nv_record_pre_write_operation(); + _nv_record_extension_init(); + + nv_flsh_state.is_update = false; + nv_flsh_state.written_size = 0; + nv_flsh_state.state = NV_STATE_IDLE; + + nvrecord_extension_p = &local_extension_data.nv_record; + + if(nvrecord_extension_p->header.magicNumber != NV_EXTENSION_MAGIC_NUMBER || + nvrecord_extension_p->header.majorVersion != NV_EXTENSION_MAJOR_VERSION || + nvrecord_extension_p->header.minorVersion != NV_EXTENSION_MINOR_VERSION || + nvrecord_extension_p->header.validLen >= (NV_EXTENSION_SIZE - NV_EXTENSION_HEADER_SIZE)) + { + ASSERT(0, "%s: local_extension_data error!(0x%x,0x%x,0x%x,0x%x)", + __func__, + nvrecord_extension_p->header.magicNumber, + nvrecord_extension_p->header.majorVersion, + nvrecord_extension_p->header.minorVersion, + nvrecord_extension_p->header.validLen); + } + + // Check main sector. + if(nv_record_data_is_valid((NV_EXTENSION_RECORD_T*)_user_data_main_start) + && nv_record_items_is_valid((NV_EXTENSION_RECORD_T*)_user_data_main_start)) + { + TRACE(2,"%s,main sector is valid.",__func__); + main_is_valid = true; + } + else + { + TRACE(1,"%s,main sector is invalid!",__func__); + main_is_valid = false; + } + + // Check bak secotr. + if(nv_record_data_is_valid((NV_EXTENSION_RECORD_T*)_user_data_bak_start) + && nv_record_items_is_valid((NV_EXTENSION_RECORD_T*)_user_data_main_start)) + { + TRACE(2,"%s,bak sector is valid.",__func__); + bak_is_valid = true; + } + else + { + TRACE(1,"%s,bak sector is invalid!",__func__); + bak_is_valid = false; + } + + if(main_is_valid) + { + data_is_valid = true; + if(!bak_is_valid) + { + nv_flsh_state.is_update = true; + nv_flsh_state.state = NV_STATE_MAIN_DONE; + } + } + else + { + if(bak_is_valid) + { + data_is_valid = true; + nv_flsh_state.is_update = true; + nv_flsh_state.state = NV_STATE_IDLE; + } + else + { + data_is_valid = false; + } + } + + if(data_is_valid) + { + TRACE(2,"%s,data is valid.", __func__); + if(main_is_valid) + { + memcpy((uint8_t *)nvrecord_extension_p + NV_EXTENSION_HEADER_SIZE, + (uint8_t *)_user_data_main_start + NV_EXTENSION_HEADER_SIZE, + NV_EXTENSION_VALID_LEN); + } + else + { + memcpy((uint8_t *)nvrecord_extension_p + NV_EXTENSION_HEADER_SIZE, + (uint8_t *)_user_data_bak_start + NV_EXTENSION_HEADER_SIZE, + NV_EXTENSION_VALID_LEN); + } + nvrecord_extension_p->header.crc32 = + crc32(0, + ((uint8_t *)nvrecord_extension_p + NV_EXTENSION_HEADER_SIZE), + nvrecord_extension_p->header.validLen); + } + else + { + TRACE(1,"%s,data invalid, rebuild... ",__func__); + nv_record_set_default(nvrecord_extension_p); + TRACE(2,"%s,rebuild crc = 0x%x. ",__func__,nvrecord_extension_p->header.crc32); + // need to update the content in the flash + nv_record_extension_update(); + } + + nvrec_init = true; + + nv_record_post_write_operation(lock); + + if(nv_flsh_state.is_update) + { + nv_record_extension_flush(false); + } + TRACE(2,"%s,done.", __func__); +} + +NV_EXTENSION_RECORD_T* nv_record_get_extension_entry_ptr(void) +{ + return nvrecord_extension_p; +} + +void nv_record_extension_update(void) +{ + nv_flsh_state.is_update = true; +} + +static int nv_record_extension_flush_main(bool is_async) +{ + uint32_t crc; + uint32_t lock; + enum NORFLASH_API_RET_T ret = NORFLASH_API_OK; + + if(NULL == nvrecord_extension_p) + { + TRACE(1,"%s,nvrecord_extension_p is null.", __func__); + goto _func_end; + } + + // TRACE(3, "%s is_async %d state %d", __func__, is_async, nv_flsh_state.state); + + if(is_async) + { + if(nv_flsh_state.state == NV_STATE_IDLE + && nv_flsh_state.is_update == true) + { + TRACE(3,"%s: async flush begin!", __func__); + } + + hal_trace_pause(); + lock = int_lock_global(); + + if(nv_flsh_state.state == NV_STATE_IDLE + || nv_flsh_state.state == NV_STATE_MAIN_ERASING) + { + if(nv_flsh_state.state == NV_STATE_IDLE) + { + nv_flsh_state.state = NV_STATE_MAIN_ERASING; + TRACE(4,"%s: NV_STATE_MAIN_ERASING", __func__); + } + + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)(__userdata_start), + NV_EXTENSION_SIZE, + true); + if(ret == NORFLASH_API_OK) + { + nv_flsh_state.state = NV_STATE_MAIN_ERASED; + TRACE(4,"%s: NV_STATE_MAIN_ERASED", __func__); + TRACE(4,"%s: norflash_api_erase ok,addr = 0x%x.",__func__,_user_data_main_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + norflash_api_flush(); + } + else + { + ASSERT(0,"%s: norflash_api_erase err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_main_start); + } + } + else if(nv_flsh_state.state == NV_STATE_MAIN_ERASED + || nv_flsh_state.state == NV_STATE_MAIN_WRITTING) + { + if(nv_flsh_state.state == NV_STATE_MAIN_ERASED) + { + nv_flsh_state.state = NV_STATE_MAIN_WRITTING; + TRACE(4,"%s: NV_STATE_MAIN_WRITTING", __func__); + } + uint32_t tmpLock = nv_record_pre_write_operation(); + crc = crc32(0,(uint8_t *)nvrecord_extension_p + NV_EXTENSION_HEADER_SIZE, + NV_EXTENSION_VALID_LEN); + nvrecord_extension_p->header.crc32 = crc; + ASSERT(nv_record_data_is_valid(nvrecord_extension_p) + && nv_record_items_is_valid(nvrecord_extension_p), + "%s nv_record is invalid!",__func__); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)(__userdata_start), + (uint8_t *)nvrecord_extension_p, + NV_EXTENSION_SIZE, + true); + nv_record_post_write_operation(tmpLock); + if(ret == NORFLASH_API_OK) + { + nv_flsh_state.is_update = false; + nv_flsh_state.state = NV_STATE_MAIN_WRITTEN; + TRACE(4,"%s: NV_STATE_MAIN_WRITTEN", __func__); + TRACE(4,"%s: norflash_api_write ok,addr = 0x%x.",__func__,_user_data_main_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + norflash_api_flush(); + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_main_start); + } + } + else + { + if(norflash_api_get_used_buffer_count(NORFLASH_API_MODULE_ID_USERDATA_EXT,NORFLASH_API_ALL) == 0) + { + nv_flsh_state.state = NV_STATE_MAIN_DONE; + // TRACE(1,"%s: NV_STATE_MAIN_DONE", __func__); + TRACE(1,"%s: async flush done.", __func__); + } + else + { + norflash_api_flush(); + } + } + int_unlock_global(lock); + hal_trace_continue(); + } + else + { + TRACE(4,"%s: sync flush begin!", __func__); + if(nv_flsh_state.state == NV_STATE_IDLE + || nv_flsh_state.state == NV_STATE_MAIN_ERASING) + { + do + { + hal_trace_pause(); + lock = int_lock_global(); + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)(__userdata_start), + NV_EXTENSION_SIZE, + true); + int_unlock_global(lock); + hal_trace_continue(); + if(ret == NORFLASH_API_OK) + { + nv_flsh_state.state = NV_STATE_MAIN_ERASED; + TRACE(4,"%s: norflash_api_erase ok,addr = 0x%x.",__func__, _user_data_main_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_ERASING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_erase err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_main_start); + } + + }while(ret == NORFLASH_API_BUFFER_FULL); + } + + if(nv_flsh_state.state == NV_STATE_MAIN_ERASED + || nv_flsh_state.state == NV_STATE_MAIN_WRITTING) + { + do + { + hal_trace_pause(); + uint32_t tmpLock = nv_record_pre_write_operation(); + crc = crc32(0,(uint8_t *)nvrecord_extension_p + NV_EXTENSION_HEADER_SIZE, + NV_EXTENSION_VALID_LEN); + nvrecord_extension_p->header.crc32 = crc; + ASSERT(nv_record_data_is_valid(nvrecord_extension_p) + && nv_record_items_is_valid(nvrecord_extension_p), + "%s nv_record is invalid!",__func__); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)(__userdata_start), + (uint8_t *)nvrecord_extension_p, + NV_EXTENSION_SIZE, + true); + nv_record_post_write_operation(tmpLock); + hal_trace_continue(); + if(ret == NORFLASH_API_OK) + { + nv_flsh_state.is_update = false; + nv_flsh_state.state = NV_STATE_MAIN_WRITTEN; + TRACE(4,"%s: norflash_api_write ok,addr = 0x%x.",__func__,_user_data_main_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_WRITTING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_main_start); + } + }while(ret == NORFLASH_API_BUFFER_FULL); + } + + do + { + norflash_api_flush(); + }while(norflash_api_get_used_buffer_count(NORFLASH_API_MODULE_ID_USERDATA_EXT,NORFLASH_API_ALL) > 0); + + nv_flsh_state.state = NV_STATE_MAIN_DONE; + TRACE(1,"%s: sync flush done.", __func__); + } +_func_end: + return (ret == NORFLASH_API_OK) ? 0:1; +} + +static int nv_record_extension_flush_bak(bool is_async) +{ + uint32_t lock; + enum NORFLASH_API_RET_T ret = NORFLASH_API_OK; + uint8_t *burn_buf = (uint8_t*)_nv_burn_buf; + + if(is_async) + { + hal_trace_pause(); + lock = int_lock_global(); + if(nv_flsh_state.state == NV_STATE_MAIN_DONE + || nv_flsh_state.state == NV_STATE_BAK_ERASING) + { + if(nv_flsh_state.state == NV_STATE_MAIN_DONE) + { + nv_flsh_state.state = NV_STATE_BAK_ERASING; + TRACE(3,"%s: async flush begin", __func__); + } + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA_EXT, + _user_data_bak_start, + NV_EXTENSION_SIZE, + true); + if(ret == NORFLASH_API_OK) + { + nv_flsh_state.state = NV_STATE_BAK_ERASED; + TRACE(4,"%s: norflash_api_erase ok,addr = 0x%x.", + __func__,_user_data_bak_start); + // TRACE(4,"%s: NV_STATE_BAK_ERASED", __func__); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + norflash_api_flush(); + } + else + { + ASSERT(0,"%s: norflash_api_erase err,ret = %d,addr = 0x%x.", + __func__,ret,_user_data_bak_start); + } + } + else if(nv_flsh_state.state == NV_STATE_BAK_ERASED + || nv_flsh_state.state == NV_STATE_BAK_WRITTING) + { + if(nv_flsh_state.state == NV_STATE_BAK_ERASED) + { + nv_flsh_state.state = NV_STATE_BAK_WRITTING; + nv_flsh_state.written_size = 0; + // TRACE(4,"%s: NV_STATE_BAK_WRITTING", __func__); + } + do + { + ret = norflash_api_read(NORFLASH_API_MODULE_ID_USERDATA_EXT, + _user_data_main_start + nv_flsh_state.written_size, + burn_buf, + NV_EXTENSION_PAGE_SIZE + ); + ASSERT(ret == NORFLASH_API_OK,"norflash_api_read failed! ret = %d, addr = 0x%x.", + (int32_t)ret,_user_data_main_start + nv_flsh_state.written_size); + + ret = norflash_api_write(NORFLASH_API_MODULE_ID_USERDATA_EXT, + _user_data_bak_start + nv_flsh_state.written_size, + burn_buf, + NV_EXTENSION_PAGE_SIZE, + true + ); + if(ret == NORFLASH_API_OK) + { + nv_flsh_state.written_size += NV_EXTENSION_PAGE_SIZE; + + if(nv_flsh_state.written_size == NV_EXTENSION_SIZE) + { + nv_flsh_state.state = NV_STATE_BAK_WRITTEN; + // TRACE(4,"%s: NV_STATE_BAK_WRITTEN", __func__); + break; + } + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + norflash_api_flush(); + break; + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.", + __func__,ret,_user_data_bak_start + nv_flsh_state.written_size); + } + }while(1); + } + else + { + if(norflash_api_get_used_buffer_count(NORFLASH_API_MODULE_ID_USERDATA_EXT,NORFLASH_API_ALL) == 0) + { + nv_flsh_state.state = NV_STATE_BAK_DONE; + TRACE(3,"%s: async flush done.", __func__); + } + else + { + norflash_api_flush(); + } + } + int_unlock_global(lock); + hal_trace_continue(); + } + else + { + TRACE(4,"%s: sync flush begin.", __func__); + if(nv_flsh_state.state == NV_STATE_MAIN_DONE + || nv_flsh_state.state == NV_STATE_BAK_ERASING) + { + do + { + hal_trace_pause(); + lock = int_lock_global(); + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA_EXT, + _user_data_bak_start, + NV_EXTENSION_SIZE, + true); + int_unlock_global(lock); + hal_trace_continue(); + if(ret == NORFLASH_API_OK) + { + nv_flsh_state.state = NV_STATE_BAK_ERASED; + TRACE(4,"%s: norflash_api_erase ok,addr = 0x%x.", + __func__, _user_data_bak_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_ERASING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_erase err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_bak_start); + } + }while(ret == NORFLASH_API_BUFFER_FULL); + } + + if(nv_flsh_state.state == NV_STATE_BAK_ERASED + || nv_flsh_state.state == NV_STATE_BAK_WRITTING) + { + nv_flsh_state.state = NV_STATE_BAK_WRITTING; + nv_flsh_state.written_size = 0; + + hal_trace_pause(); + do + { + lock = int_lock_global(); + ret = norflash_api_read(NORFLASH_API_MODULE_ID_USERDATA_EXT, + _user_data_main_start + nv_flsh_state.written_size, + burn_buf, + NV_EXTENSION_PAGE_SIZE + ); + ASSERT(ret == NORFLASH_API_OK,"norflash_api_read failed! ret = %d, addr = 0x%x.", + (int32_t)ret, _user_data_main_start + nv_flsh_state.written_size); + + ret = norflash_api_write(NORFLASH_API_MODULE_ID_USERDATA_EXT, + _user_data_bak_start + nv_flsh_state.written_size, + burn_buf, + NV_EXTENSION_PAGE_SIZE, + true + ); + int_unlock_global(lock); + if(ret == NORFLASH_API_OK) + { + nv_flsh_state.written_size += NV_EXTENSION_PAGE_SIZE; + if(nv_flsh_state.written_size == NV_EXTENSION_SIZE) + { + nv_flsh_state.state = NV_STATE_BAK_WRITTEN; + TRACE(3,"%s: NV_STATE_BAK_WRITTEN", __func__); + break; + } + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_WRITTING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.", + __func__,ret,_user_data_bak_start + nv_flsh_state.written_size); + } + }while(1); + } + hal_trace_continue(); + + // nv_flsh_state.state == NV_STATE_BAK_WRITTEN; + do + { + norflash_api_flush(); + }while(norflash_api_get_used_buffer_count(NORFLASH_API_MODULE_ID_USERDATA_EXT,NORFLASH_API_ALL) > 0); + + nv_flsh_state.state = NV_STATE_BAK_DONE; + TRACE(1,"%s: sync flush done.", __func__); + } + + if(nv_flsh_state.state == NV_STATE_BAK_DONE) + { + nv_flsh_state.state = NV_STATE_IDLE; + TRACE(1,"%s: NV_STATE_IDLE", __func__); + } + + return (ret == NORFLASH_API_OK) ? 0:1; +} + + +static int nv_record_extension_flush(bool is_async) +{ + int ret = 0; + // TRACE(3, "%s state %d is_update %d", __func__, nv_flsh_state.state, nv_flsh_state.is_update); + do{ + if(nv_flsh_state.state == NV_STATE_IDLE + && nv_flsh_state.is_update == FALSE) + { + break; + } + + if((nv_flsh_state.state == NV_STATE_IDLE + && nv_flsh_state.is_update == TRUE) + || nv_flsh_state.state == NV_STATE_MAIN_ERASING + || nv_flsh_state.state == NV_STATE_MAIN_ERASED + || nv_flsh_state.state == NV_STATE_MAIN_WRITTING + || nv_flsh_state.state == NV_STATE_MAIN_WRITTEN + ) + { + ret = nv_record_extension_flush_main(is_async); + if(is_async) + { + break; + } + } + + if(nv_flsh_state.state == NV_STATE_MAIN_DONE + || nv_flsh_state.state == NV_STATE_BAK_ERASING + || nv_flsh_state.state == NV_STATE_BAK_ERASED + || nv_flsh_state.state == NV_STATE_BAK_WRITTING + || nv_flsh_state.state == NV_STATE_BAK_WRITTEN + || nv_flsh_state.state == NV_STATE_BAK_DONE + ) + { + ret = nv_record_extension_flush_bak(is_async); + } + }while(!is_async); + return ret; +} + +void nv_extension_callback(void* param) +{ + NORFLASH_API_OPERA_RESULT *opera_result; + opera_result = (NORFLASH_API_OPERA_RESULT*)param; + + TRACE(6,"%s:type = %d, addr = 0x%x,len = 0x%x,remain = %d,result = %d.", + __func__, + opera_result->type, + opera_result->addr, + opera_result->len, + opera_result->remain_num, + opera_result->result); +} + +void nv_record_init(void) +{ + nv_record_open(section_usrdata_ddbrecord); + + nv_custom_parameter_section_init(); +} + +bt_status_t nv_record_open(SECTIONS_ADP_ENUM section_id) +{ + nv_record_extension_init(); +#ifdef FLASH_SUSPEND + hal_sleep_set_sleep_hook(HAL_SLEEP_HOOK_USER_NVRECORD, + nv_record_flash_flush_in_sleep); +#else + hal_sleep_set_deep_sleep_hook(HAL_DEEP_SLEEP_HOOK_USER_NVRECORD, + nv_record_flash_flush_in_sleep); +#endif + return BT_STS_SUCCESS; +} + +void nv_record_update_runtime_userdata(void) +{ + nv_record_extension_update(); +} + + +int nv_record_touch_cause_flush(void) +{ + nv_record_update_runtime_userdata(); + return 0; +} + +void nv_record_sector_clear(void) +{ + uint32_t lock; + enum NORFLASH_API_RET_T ret; + + lock = int_lock_global(); + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)__userdata_start, + NV_EXTENSION_SIZE, + false); + ASSERT(ret == NORFLASH_API_OK, + "%s: norflash_api_erase(0x%x) failed! ret = %d.", + __func__, (uint32_t)__userdata_start, (int32_t)ret); + + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA_EXT, + (uint32_t)__userdata_start + NV_EXTENSION_SIZE, + NV_EXTENSION_SIZE, + false); + ASSERT(ret == NORFLASH_API_OK, + "%s: norflash_api_erase(0x%x) failed! ret = %d.", + __func__, (uint32_t)__userdata_start + NV_EXTENSION_SIZE, (int32_t)ret); + //pmu_reboot(); + int_unlock_global(lock); +} + +void nv_record_rebuild(void) +{ + if(nvrecord_extension_p) + { + uint32_t nv_start; + TRACE(1,"%s: begin.", __func__); + uint32_t lock = int_lock_global(); + mpu_clear(MPU_ID_USER_DATA_SECTION); + nv_record_set_default(nvrecord_extension_p); + nv_start = (uint32_t)&local_extension_data.nv_record; + mpu_set(MPU_ID_USER_DATA_SECTION, nv_start, + NV_EXTENSION_MIRROR_RAM_SIZE, 0, MPU_ATTR_READ); + nv_record_extension_update(); + nv_record_flash_flush(); + int_unlock_global(lock); + TRACE(1,"%s: done.", __func__); + } + else + { + TRACE(1,"%s: begin. nvrecord_extension_p = null.", __func__); + uint32_t lock = int_lock_global(); + nv_record_sector_clear(); + nvrec_init = false; + nv_record_extension_init(); + int_unlock_global(lock); + TRACE(1,"%s: done.", __func__); + } +} + +#define NV_RECORD_FLUSH_EXECUTION_INTERVAL_MS (20*60*1000) +static uint32_t lastFlushCheckPointInMs = 0; + +static void nv_record_reset_flush_checkpoint(void) +{ + lastFlushCheckPointInMs = GET_CURRENT_MS();; +} + +static bool nv_record_is_timer_expired_to_check(void) +{ + uint32_t passedTimerMs; + uint32_t currentTimerMs = GET_CURRENT_MS(); + + if (0 == lastFlushCheckPointInMs) + { + passedTimerMs = currentTimerMs; + } + else + { + if (currentTimerMs > lastFlushCheckPointInMs) + { + passedTimerMs = currentTimerMs - lastFlushCheckPointInMs; + } + else + { + passedTimerMs = 0xFFFFFFFF - lastFlushCheckPointInMs + currentTimerMs + 1; + } + } + + if (passedTimerMs > NV_RECORD_FLUSH_EXECUTION_INTERVAL_MS) + { + return true; + } + else + { + return false; + } +} + +void nv_record_flash_flush(void) +{ + nv_record_extension_flush(false); + nv_record_reset_flush_checkpoint(); +} + +void nv_record_execute_async_flush(void) +{ + int ret = nv_record_extension_flush(true); + if (0 == ret) + { + nv_record_reset_flush_checkpoint(); + } +} + +int nv_record_flash_flush_in_sleep(void) +{ + if ((NV_STATE_IDLE == nv_flsh_state.state) && + !nv_record_is_timer_expired_to_check()) + { + return 0; + } + + nv_record_execute_async_flush(); + return 0; +} + +#endif // #if defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nv_section/userdata_section/nvrecord_extension.h b/services/nv_section/userdata_section/nvrecord_extension.h new file mode 100644 index 0000000..5f32691 --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_extension.h @@ -0,0 +1,362 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef NEW_NV_RECORD_ENABLED + +#ifndef __NVRECORD_EXTENSION_H__ +#define __NVRECORD_EXTENSION_H__ +#include "bluetooth.h" +#include "me_api.h" +#include "btif_sys_config.h" + +// increase by 1 if the nvrecord's whole data structure is changed and the content needs to be rebuilt +#define NV_EXTENSION_MAJOR_VERSION 3 +// increase by 1 if the new items are appended to the tail of the former nvrecord's data structure +#define NV_EXTENSION_MINOR_VERSION 1 + +#define NV_EXTENSION_SIZE 4096 // one flash page +#define NV_EXTENSION_PAGE_SIZE 256 +#define NV_EXTENSION_HEADER_SIZE sizeof(NVRECORD_HEADER_T) // magic number and valid length +#define NV_EXTENSION_MAGIC_NUMBER 0x4E455854 +#define NV_EXTENSION_VALID_LEN (sizeof(NV_EXTENSION_RECORD_T) - sizeof(NVRECORD_HEADER_T)) + +/* unused, just for backwards compatible */ +#define section_name_ddbrec "ddbrec" + +/* BT paired device info */ +#define MAX_BT_PAIRED_DEVICE_COUNT 8 + +/* BLE paired device information */ +#define BLE_RECORD_NUM 5 + +#define BLE_ADDR_SIZE 6 +#define BLE_ENC_RANDOM_SIZE 8 +#define BLE_LTK_SIZE 16 +#define BLE_IRK_SIZE 16 + +#define BLE_STATIC_ADDR 0 +#define BLE_RANDOM_ADDR 1 + +#ifdef GFPS_ENABLED +/* fast pair account key */ +#define FP_ACCOUNT_KEY_RECORD_NUM 5 +#define FP_ACCOUNT_KEY_SIZE 16 +#define FP_MAX_NAME_LEN 64 +#endif + +#ifdef OTA_ENABLED +#define MAX_VERSION_STRING_LEN 16 +#define OTA_DEVICE_CNT 2 //!< should be equal to OTA_DEVICE_NUM in @see OTA_DEVICE_E +#endif + +#ifdef BISTO_ENABLED +#ifdef GSOUND_HOTWORD_ENABLED +#define MODEL_FILE_EMBEDED 1 //!< define this macro when model file is emneded in our bin file + +#if MODEL_FILE_EMBEDED +#define HOTWORD_MODLE_MAX_NUM 11//!< need to adjust this value if support more model +#else +#define HOTWORD_MODLE_MAX_NUM 10 //!< need to adjust this value if support more model +#endif + +#endif // #ifdef GSOUND_HOTWORD_ENABLED +#endif // #ifdef BISTO_ENABLED + +// TODO: should be increased if NV_EXTENSION_MIRROR_RAM_SIZE exceeds this value + +#if defined(__AI_VOICE__ ) || (defined(BISTO_ENABLED)|| defined(GFPS_ENABLED)) +#define NV_EXTENSION_MIRROR_RAM_SIZE 0x800 +#else +#define NV_EXTENSION_MIRROR_RAM_SIZE 0x400 +#endif + +#define TILE_INFO_SIZE 400 +#define BT_FREQENCY_RANGE_NUM 3 +#define BT_IQ_INVALID_MAGIC_NUM 0xFFFFFFFF +#define BT_IQ_VALID_MAGIC_NUM 0x5a5a5a5a +typedef struct +{ + uint32_t validityMagicNum; + uint16_t gain_cal_val[BT_FREQENCY_RANGE_NUM]; + uint16_t phase_cal_val[BT_FREQENCY_RANGE_NUM]; +} BT_IQ_CALIBRATION_CONFIG_T; + +/* nv record header data structure */ +typedef struct +{ + uint32_t magicNumber; + uint16_t majorVersion; // should be NV_EXTENSION_MAJOR_VERSION + uint16_t minorVersion; // should be NV_EXTENSION_MINOR_VERSION + uint32_t validLen; // should be the valid content in this nv record version + uint32_t crc32; // crc32 of following valid values in the nv extention section +} NVRECORD_HEADER_T; + +/* system information */ +typedef struct { + int8_t language; +} media_language_t; + +#if defined(APP_LINEIN_A2DP_SOURCE) || defined(APP_I2S_A2DP_SOURCE) +typedef struct { + int8_t src_snk_mode; +} src_snk_t; +#endif + +typedef struct { + uint32_t mode; + btif_device_record_t record; + bool tws_connect_success; +} ibrt_mode_t; + +typedef struct { + uint32_t status; +} factory_tester_status_t; + +typedef struct { + bool voice_key_enable; + uint8_t setedCurrentAi; //if false, set ai default mode + uint8_t currentAiSpec; // + uint8_t aiStatusDisableFlag; //all ai disable flag + uint8_t amaAssistantEnableStatus; //ama enable flag +} AI_MANAGER_INFO_T; + +struct nvrecord_env_t { + media_language_t media_language; +#if defined(APP_LINEIN_A2DP_SOURCE) || defined(APP_I2S_A2DP_SOURCE) + src_snk_t src_snk_flag; +#endif + ibrt_mode_t ibrt_mode; + factory_tester_status_t factory_tester_status; + + uint8_t flag_value[8]; + AI_MANAGER_INFO_T aiManagerInfo; +}; + +typedef struct btdevice_volume { + int8_t a2dp_vol; + int8_t hfp_vol; +} btdevice_volume; + +typedef struct btdevice_profile { + bool hfp_act; + bool hsp_act; + bool a2dp_act; + uint8_t a2dp_codectype; +} btdevice_profile; + +typedef struct { + btif_device_record_t record; + btdevice_volume device_vol; + btdevice_profile device_plf; +#ifdef BTIF_DIP_DEVICE + uint16_t vend_id; + uint16_t vend_id_source; + uint16_t reserve; +#endif +} nvrec_btdevicerecord; + +typedef struct { + uint32_t pairedDevNum; + nvrec_btdevicerecord pairedBtDevInfo[MAX_BT_PAIRED_DEVICE_COUNT]; +} NV_RECORD_PAIRED_BT_DEV_INFO_T; + +typedef enum { + section_usrdata_ddbrecord, + section_none +} SECTIONS_ADP_ENUM; + +typedef struct { + uint8_t ble_addr[BTIF_BD_ADDR_SIZE]; + uint8_t ble_irk[BLE_IRK_SIZE]; +} BLE_BASIC_INFO_T; + +typedef struct { + uint8_t peer_bleAddr[BLE_ADDR_SIZE]; + uint16_t EDIV; + uint8_t RANDOM[BLE_ENC_RANDOM_SIZE]; + uint8_t LTK[BLE_LTK_SIZE]; + uint8_t IRK[BLE_IRK_SIZE]; + uint8_t bonded; + +} BleDeviceinfo; + +typedef struct { + uint32_t saved_list_num; + BLE_BASIC_INFO_T self_info; + BleDeviceinfo ble_nv[BLE_RECORD_NUM]; +} NV_RECORD_PAIRED_BLE_DEV_INFO_T; + +#ifdef TWS_SYSTEM_ENABLED +typedef struct { + BLE_BASIC_INFO_T ble_info; +} TWS_INFO_T; +#endif // #ifdef TWS_SYSTEM_ENABLED + +#ifdef GFPS_ENABLED +typedef struct { + uint8_t key[FP_ACCOUNT_KEY_SIZE]; + +} NV_FP_ACCOUNT_KEY_ENTRY_T; + +typedef struct { + uint32_t key_count; + NV_FP_ACCOUNT_KEY_ENTRY_T accountKey[FP_ACCOUNT_KEY_RECORD_NUM]; + uint16_t nameLen; + uint8_t name[FP_MAX_NAME_LEN]; +} NV_FP_ACCOUNT_KEY_RECORD_T; +#endif // #ifdef GFPS_ENABLED + +#ifdef NVREC_BAIDU_DATA_SECTION +/* DMA owned configuration information */ +typedef struct { + int32_t fmfreq; + char rand[BAIDU_DATA_RAND_LEN + 1]; + +} NV_DMA_CONFIGURATION_T; +#endif // #ifdef NVREC_BAIDU_DATA_SECTION + +#ifdef TILE_DATAPATH +typedef struct { + uint8_t tileInfo[TILE_INFO_SIZE]; +} NV_TILE_INFO_CONFIG_T; +#endif + +#if defined(OTA_ENABLED) +typedef struct { + // hotword model ID, arry size should equal to GSOUND_HOTWORD_MODEL_ID_BYTES + char modelId[5]; + + // start addr of the model + uint32_t startAddr; + + // length of model file + uint32_t len; +}HOTWORD_MODEL_INFO_T; + +typedef struct { + uint32_t imageSize; //!< image size of ongoing upgrade + uint32_t breakPoint; //!< break point of ongoing upgrade + char version[MAX_VERSION_STRING_LEN]; //!< version string of ongoing upgrade + uint8_t versionLen; //!< version string length of ongoing upgrade + uint8_t otaStatus; //!< status of ongoing upgrade + uint8_t user; //!< user of ongoing upgrade +} NV_OTA_INFO_T; +#endif + +#ifdef BISTO_ENABLED +typedef struct { + uint8_t isGsoundEnabled; + + // this is used for hotword model + // for non-hotword version, this should always be 0 + uint8_t supportedModelCnt; + +#ifdef GSOUND_HOTWORD_ENABLED + // store the hotword model info + HOTWORD_MODEL_INFO_T modelInfo[HOTWORD_MODLE_MAX_NUM]; +#endif +} NV_GSOUND_INFO_T; +#endif + +typedef struct { + NVRECORD_HEADER_T header; + struct nvrecord_env_t system_info; + NV_RECORD_PAIRED_BT_DEV_INFO_T bt_pair_info; + NV_RECORD_PAIRED_BLE_DEV_INFO_T ble_pair_info; + +#ifdef TWS_SYSTEM_ENABLED + TWS_INFO_T tws_info; +#endif + +#ifdef GFPS_ENABLED + NV_FP_ACCOUNT_KEY_RECORD_T fp_account_key_rec; +#endif + +#ifdef NVREC_BAIDU_DATA_SECTION + NV_DMA_CONFIGURATION_T dma_config; +#endif + +#ifdef TILE_DATAPATH + NV_TILE_INFO_CONFIG_T tileConfig; +#endif + +#ifdef OTA_ENABLED + NV_OTA_INFO_T ota_info[OTA_DEVICE_CNT]; +#endif + +#if defined(BISTO_ENABLED) + NV_GSOUND_INFO_T gsound_info; +#endif + +#if 1//def TX_IQ_CAL + BT_IQ_CALIBRATION_CONFIG_T btIqCalConfig; +#endif + // TODO: If wanna OTA to update the nv record, two choices: + // 1. Change above data structures and increase NV_EXTENSION_MAJOR_VERSION. + // Then the nv record will be rebuilt and the whole history information will be cleared + // 2. Don't touch above data structures but just add new items here and increase NV_EXTENSION_MINOR_VERSION. + // Then the nv record will keep all the whole hisotry. +} NV_EXTENSION_RECORD_T; + +typedef union { + NV_EXTENSION_RECORD_T nv_record; + /* + * dummy data, just make sure the mirror buffer's size is + * "NV_EXTENSION_MIRROR_RAM_SIZE" + */ + uint8_t dummy_data[NV_EXTENSION_MIRROR_RAM_SIZE]; +} NV_MIRROR_BUF_T; + +#ifdef __cplusplus +extern "C" { +#endif + +extern NV_EXTENSION_RECORD_T *nvrecord_extension_p; + +int nv_record_env_init(void); + +NV_EXTENSION_RECORD_T *nv_record_get_extension_entry_ptr(void); + +void nv_record_extension_update(void); + +void nv_extension_callback(void *param); + +int nv_record_touch_cause_flush(void); + +void nv_record_sector_clear(void); + +void nv_record_flash_flush(void); + +int nv_record_flash_flush_in_sleep(void); + +void nv_record_execute_async_flush(void); + +void nv_record_update_runtime_userdata(void); + +void nv_record_rebuild(void); + +uint32_t nv_record_pre_write_operation(void); + +void nv_record_post_write_operation(uint32_t lock); + +bt_status_t nv_record_open(SECTIONS_ADP_ENUM section_id); + +void nv_record_init(void); + +#ifdef __cplusplus +} +#endif +#endif +#endif //#if defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nv_section/userdata_section/nvrecord_fp_account_key.c b/services/nv_section/userdata_section/nvrecord_fp_account_key.c new file mode 100644 index 0000000..49fc174 --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_fp_account_key.c @@ -0,0 +1,168 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) +//#include "cmsis_os.h" +#include +#include +#include +#include "nvrecord_extension.h" +#include "nvrecord_fp_account_key.h" +#include "hal_trace.h" + +#ifdef GFPS_ENABLED + +static NV_FP_ACCOUNT_KEY_RECORD_T *nvrecord_fp_account_key_p = NULL; + +void nvrecord_rebuild_fp_account_key(NV_FP_ACCOUNT_KEY_RECORD_T* pFpAccountKey) +{ + memset((uint8_t *)pFpAccountKey, 0, sizeof(NV_FP_ACCOUNT_KEY_RECORD_T)); + pFpAccountKey->key_count = 0; +} + +NV_FP_ACCOUNT_KEY_RECORD_T* nv_record_get_fp_data_structure_info(void) +{ + return nvrecord_fp_account_key_p; +} + +void nv_record_update_fp_data_structure(NV_FP_ACCOUNT_KEY_RECORD_T* pFpData) +{ + if (!memcmp((uint8_t *)pFpData, (uint8_t *)nvrecord_fp_account_key_p, + sizeof(NV_FP_ACCOUNT_KEY_RECORD_T))) + { + // the updated fp data is the same as the local content, do nothing + } + else + { + uint32_t lock = nv_record_pre_write_operation(); + TRACE(0,"Fast pair non-volatile data needs to be updated to aligned with peer device."); + *nvrecord_fp_account_key_p = *pFpData; + nv_record_post_write_operation(lock); + nv_record_update_runtime_userdata(); + } +} + +void nv_record_fp_account_key_init(void) +{ + if (NULL == nvrecord_fp_account_key_p) + { + nvrecord_fp_account_key_p = &(nvrecord_extension_p->fp_account_key_rec); + } +} + +void nv_record_fp_account_key_add(NV_FP_ACCOUNT_KEY_ENTRY_T* param_rec) +{ + TRACE(0,"Add account key:"); + DUMP8("0x%02x ", param_rec->key, sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + uint32_t lock = nv_record_pre_write_operation(); + if (FP_ACCOUNT_KEY_RECORD_NUM == nvrecord_fp_account_key_p->key_count) + { + // discard the earliest key + memmove((uint8_t *)&(nvrecord_fp_account_key_p->accountKey[0]), + (uint8_t *)&(nvrecord_fp_account_key_p->accountKey[1]), + (FP_ACCOUNT_KEY_RECORD_NUM - 1)*sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + + nvrecord_fp_account_key_p->key_count--; + } + + memcpy((uint8_t *)&(nvrecord_fp_account_key_p->accountKey[nvrecord_fp_account_key_p->key_count]), + param_rec, + sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + + nvrecord_fp_account_key_p->key_count++; + nv_record_post_write_operation(lock); + nv_record_update_runtime_userdata(); +} + +void nv_record_fp_account_info_reset(void) +{ + uint32_t lock = nv_record_pre_write_operation(); + uint8_t size = nv_record_fp_account_key_count(); + for (uint8_t i = 0 ; i < size ; i++){ + memset((uint8_t *)&(nvrecord_fp_account_key_p->accountKey[i]), 0, + sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + } + nvrecord_fp_account_key_p->key_count = 0; + nv_record_post_write_operation(lock); + nv_record_fp_update_name(NULL, 0); +} + +void nv_record_fp_account_key_delete(void) +{ + nv_record_fp_account_info_reset(); +} + +bool nv_record_fp_account_key_get_by_index(uint8_t index, uint8_t* outputKey) +{ + if (nvrecord_fp_account_key_p->key_count < (index + 1)) + { + return false; + } + + memcpy(outputKey, (uint8_t *)&(nvrecord_fp_account_key_p->accountKey[index]), + sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + + TRACE(1,"Get account key %d as:", index); + DUMP8("0x%02x ", outputKey, sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + + return true; +} + +uint8_t nv_record_fp_account_key_count(void) +{ + ASSERT(nvrecord_fp_account_key_p->key_count <= FP_ACCOUNT_KEY_RECORD_NUM, "fp account exceed"); + return nvrecord_fp_account_key_p->key_count; +} + +void nv_record_fp_update_name(uint8_t* ptrName, uint32_t nameLen) +{ + TRACE(1,"update name len %d", nameLen); + uint32_t lock = nv_record_pre_write_operation(); + + memset(nvrecord_fp_account_key_p->name, 0, FP_MAX_NAME_LEN); + if (nameLen > 0) + { + DUMP8("0x%02x ", ptrName, nameLen); + memcpy(nvrecord_fp_account_key_p->name, ptrName, nameLen); + } + nvrecord_fp_account_key_p->nameLen = nameLen; + + nv_record_post_write_operation(lock); + nv_record_update_runtime_userdata(); +} + +uint8_t* nv_record_fp_get_name_ptr(uint32_t* ptrNameLen) +{ + *ptrNameLen = nvrecord_fp_account_key_p->nameLen; + return nvrecord_fp_account_key_p->name; +} + +void nv_record_fp_update_all(uint8_t *info) +{ + ASSERT(info, "null pointer received in [%s]", __func__); + + if (memcmp(nvrecord_fp_account_key_p, info, sizeof(NV_FP_ACCOUNT_KEY_RECORD_T))) + { + uint32_t lock = nv_record_pre_write_operation(); + memcpy(nvrecord_fp_account_key_p, info, sizeof(NV_FP_ACCOUNT_KEY_RECORD_T)); + nv_record_extension_update(); + TRACE(1,"received fp count num:%d", nvrecord_fp_account_key_p->key_count); + nv_record_post_write_operation(lock); + } +} + +#endif + +#endif // #if defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nv_section/userdata_section/nvrecord_fp_account_key.h b/services/nv_section/userdata_section/nvrecord_fp_account_key.h new file mode 100644 index 0000000..6f37035 --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_fp_account_key.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if defined(NEW_NV_RECORD_ENABLED) + +#ifdef GFPS_ENABLED + +#ifndef __NVRECORD_FP_ACCOUNT_KEY_H__ +#define __NVRECORD_FP_ACCOUNT_KEY_H__ + +#include "nvrecord_extension.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void nv_record_fp_account_key_add(NV_FP_ACCOUNT_KEY_ENTRY_T* param_rec); +void nv_record_fp_account_key_delete(); +void nv_record_fp_account_key_init(void); +bool nv_record_fp_account_key_get_by_index(uint8_t index, uint8_t* outputKey); +uint8_t nv_record_fp_account_key_count(void); +void nvrecord_rebuild_fp_account_key(NV_FP_ACCOUNT_KEY_RECORD_T* pFpAccountKey); +void nv_record_fp_update_name(uint8_t* ptrName, uint32_t nameLen); +uint8_t* nv_record_fp_get_name_ptr(uint32_t* ptrNameLen); +NV_FP_ACCOUNT_KEY_RECORD_T* nv_record_get_fp_data_structure_info(void); +void nv_record_update_fp_data_structure(NV_FP_ACCOUNT_KEY_RECORD_T* pFpData); + +void nv_record_fp_update_all(uint8_t *info); + +#ifdef __cplusplus +} +#endif +#endif + +#endif + +#endif // #if defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nv_section/userdata_section/nvrecord_gsound.c b/services/nv_section/userdata_section/nvrecord_gsound.c new file mode 100644 index 0000000..bc2b4d1 --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_gsound.c @@ -0,0 +1,426 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + +/*****************************header include********************************/ +#include "cmsis.h" +#include "nv_section_dbg.h" +#include "nvrecord_gsound.h" +#include "factory_section.h" + +#ifdef BISTO_ENABLED +#include "gsound_target_ota.h" + +#ifdef GSOUND_HOTWORD_ENABLED +#include "gsound_custom_hotword_common.h" +#endif +#endif + +/************************private macro defination***************************/ +#define HOTWORD_MODEL_MAX_SIZE (80 * 1024) //!< should adjust this value if +//!< hotword model size changed and should adjust the flash section size at +//!< the sametime., @see HOTWORD_SECTION_SIZE in common.mk + +#ifndef OTA_FLASH_LOGIC_ADDR +#define OTA_FLASH_LOGIC_ADDR (FLASH_NC_BASE) +#endif + +/************************private type defination****************************/ + +/************************extern function declearation***********************/ +#ifdef GSOUND_HOTWORD_ENABLED +extern uint32_t __hotword_model_start[]; +extern uint32_t __hotword_model_end[]; +#endif + +/**********************private function declearation************************/ + +/************************private variable defination************************/ +#ifdef GSOUND_HOTWORD_ENABLED +#ifdef MODEL_FILE_EMBEDED +const uint8_t EMBEDED_MODEL_FILE [] = { +#include "res/gs_hw/en_all.txt" //!< must correspond to specific model ID, @see DEFAULT_HOTWORD_MODEL_ID +}; + +/// NOTE: Add more embeded model file info here + +#define DEFAULT_MODEL_START_ADDR EMBEDED_MODEL_FILE //!< map to specific flash address within the bin file +#else /// #ifndef MODEL_FILE_EMBEDED +#define DEFAULT_MODEL_START_ADDR __hotword_model_start //!< map to specific flash address out of the bin file +#endif /// #ifdef MODEL_FILE_EMBEDED + +HOTWORD_MODEL_INFO_T defaultModel[DEFAULT_MODEL_NUM] = { + {DEFAULT_HOTWORD_MODEL_ID, (uint32_t)DEFAULT_MODEL_START_ADDR, HOTWORD_MODEL_MAX_SIZE}, + /// NOTE: Add other embeded model info here +}; + +char supportedModels[GSOUND_MAX_SUPPORTED_HOTWORD_MODELS_BYTES] = {}; +#endif /// #ifdef GSOUND_HOTWORD_ENABLED + +static NV_GSOUND_INFO_T *nvrecord_gsound_p = NULL; + +/****************************function defination****************************/ +void nv_record_gsound_rec_init(void) +{ + if (NULL == nvrecord_gsound_p) + { + nvrecord_gsound_p = &(nvrecord_extension_p->gsound_info); + } + +#ifdef GSOUND_HOTWORD_ENABLED + /// init default supported model file(s) + /// add to supported model file set(if it is not in this set) + LOG_I("supportedModelCnt:%d", nvrecord_gsound_p->supportedModelCnt); + if (0 == nvrecord_gsound_p->supportedModelCnt) //!< load default info at first time bootup + { + for (uint8_t i = 0; i < DEFAULT_MODEL_NUM; i++) + { + LOG_I("hotword_model_start:0x%x", + defaultModel[i].startAddr); + + nv_record_gsound_rec_add_new_model((void *)&defaultModel[i]); + } + } +#endif +} + +void nv_record_gsound_rec_get_ptr(void **ptr) +{ + *ptr = nvrecord_gsound_p; +} + +void nv_record_gsound_rec_updata_enable_state(bool enable) +{ + LOG_I("gsound enable state update:%d->%d", nvrecord_gsound_p->isGsoundEnabled, enable); + + if (nvrecord_gsound_p->isGsoundEnabled != enable) + { + /// disable the MPU protection for write operation + uint32_t lock = nv_record_pre_write_operation(); + + /// update the enable state + nvrecord_gsound_p->isGsoundEnabled = enable; + nv_record_extension_update(); + + /// enable the MPU protection after the write operation + nv_record_post_write_operation(lock); + } +} + +#ifdef GSOUND_HOTWORD_ENABLED +bool nv_record_gsound_rec_is_model_insert_allowed(const char *model) +{ + bool ret = true; + uint8_t i; + + if ((nvrecord_gsound_p->supportedModelCnt >= HOTWORD_MODLE_MAX_NUM) && + (0xFF != nvrecord_gsound_p->supportedModelCnt)) + { + for (i = 0; i < HOTWORD_MODLE_MAX_NUM; i++) + { + /// hotword model exist already + if (!memcmp(&nvrecord_gsound_p->modelInfo[i].modelId, model, strlen(model))) + { + break; + } + } + + if (HOTWORD_MODLE_MAX_NUM == i) + { + ret = false; + } + } + + return ret; +} + +bool nv_record_gsound_rec_add_new_model(void *pInfo) +{ + bool ret = true; + bool found = false; + uint32_t lock = 0; + + HOTWORD_MODEL_INFO_T *info = (HOTWORD_MODEL_INFO_T *)pInfo; + + if (INVALID_MODEL_NUM == nvrecord_gsound_p->supportedModelCnt) + { + lock = nv_record_pre_write_operation(); + nvrecord_gsound_p->supportedModelCnt = 0; + nv_record_post_write_operation(lock); + } + + if (info) + { + lock = nv_record_pre_write_operation(); + info->startAddr |= OTA_FLASH_LOGIC_ADDR; + + for (uint8_t i = 0; i < nvrecord_gsound_p->supportedModelCnt; i++) + { + /// hotword model exist already + if (!memcmp(&nvrecord_gsound_p->modelInfo[i].modelId, info->modelId, GSOUND_HOTWORD_MODEL_ID_BYTES)) + { + LOG_I("info->startAddr:%x", info->startAddr); + + ///.update the start address + if (info->startAddr) + { + nvrecord_gsound_p->modelInfo[i].startAddr = info->startAddr; + nvrecord_gsound_p->modelInfo[i].len = info->len; + } + + LOG_I("model already exist in user section, model_id:%s, model_addr:%x", + nvrecord_gsound_p->modelInfo[i].modelId, + nvrecord_gsound_p->modelInfo[i].startAddr); + found = true; + break; + } + } + + LOG_I("current supportedModelCnt:%d", nvrecord_gsound_p->supportedModelCnt); + + /// brand new model insert + if (!found) + { + memcpy(&nvrecord_gsound_p->modelInfo[nvrecord_gsound_p->supportedModelCnt], + info, + sizeof(HOTWORD_MODEL_INFO_T)); + + LOG_I("new added modelId:%s, startAddr:%x, modelFileLen:%x", info->modelId, info->startAddr, info->len); + nvrecord_gsound_p->supportedModelCnt++; + } + nv_record_post_write_operation(lock); + + /// new model file incoming, update flash info + if (!found) + { + /// flush the hotword info to flash + nv_record_update_runtime_userdata(); + nv_record_flash_flush(); + } + + LOG_I("current supportedModelCnt:%d", nvrecord_gsound_p->supportedModelCnt); + } + else + { + LOG_W("NULL pointer received in %s", __func__); + ret = false; + } + + return ret; +} + +uint32_t nv_record_gsound_rec_get_hotword_model_addr(const char *model_id, bool add_new, int32_t newModelLen) +{ + uint32_t addr = 0; + bool found = false; + + LOG_I("%s revceived model ID: %s", __func__, model_id); + if (nvrecord_gsound_p) + { + for (uint8_t i = 0; i < ARRAY_SIZE(nvrecord_gsound_p->modelInfo); i++) + { + if (!memcmp(nvrecord_gsound_p->modelInfo[i].modelId, model_id, 4)) + { + addr = nvrecord_gsound_p->modelInfo[i].startAddr; + found = true; + LOG_I("found saved model info, index:%d", i); + break; + } + } + } + + do + { + if (add_new && !found) + { + addr = (uint32_t)__hotword_model_start; + uint32_t tempAddr; + uint8_t startIdx = 0; +#ifdef MODEL_FILE_EMBEDED + startIdx = DEFAULT_MODEL_NUM; //!< set offset to skip the embeded model file info +#endif + + if (INVALID_MODEL_NUM == nvrecord_gsound_p->supportedModelCnt) + { + break; + } + + /// get the largest flash address + for (uint8_t i = startIdx; i < nvrecord_gsound_p->supportedModelCnt; i++) + { + tempAddr = nvrecord_gsound_p->modelInfo[i].startAddr + nvrecord_gsound_p->modelInfo[i].len; + if ((tempAddr & 0xFFFFFF) > (addr & 0xFFFFFF)) + { + addr = tempAddr; + } + } + + /// force 4K align the address + addr = F_4K_ALIGN(addr); + LOG_I("supportedModelCnt:%d, Largest address:0x%x", nvrecord_gsound_p->supportedModelCnt, addr); + + /// check is overwrite needed + if ((newModelLen + addr) > (uint32_t)__hotword_model_end || + (nvrecord_gsound_p->supportedModelCnt >= HOTWORD_MODLE_MAX_NUM)) + { + uint8_t cleanIdx = 0; //!< model file index to clean + addr = nvrecord_gsound_p->modelInfo[startIdx].startAddr; //!< init anchor point + uint32_t cleanSize = F_4K_ALIGN(addr + nvrecord_gsound_p->modelInfo[startIdx].len) - addr; //!< flash size to clean + + uint32_t lock = nv_record_pre_write_operation(); //!< disable the MPU for info update + uint32_t intLock = int_lock(); //!< lock the global interrupt + + /// remove the first record + for (uint8_t i = startIdx; i < (nvrecord_gsound_p->supportedModelCnt - 1); i++) + { + nvrecord_gsound_p->modelInfo[i] = nvrecord_gsound_p->modelInfo[i + 1]; + } + + /// decrease the number of supported model + nvrecord_gsound_p->supportedModelCnt--; + + while (cleanSize < newModelLen) + { + uint8_t headAdjacentIdx = 0xFF, tailAdjacentIdx = 0xFF; + uint32_t headAdjacentOffset = 0xFFFFFFFF, tailAdjacentOffset = 0xFFFFFFFF; + + /// find the adjacent chunck + for (uint8_t i = startIdx; i < nvrecord_gsound_p->supportedModelCnt; i++) + { + if (nvrecord_gsound_p->modelInfo[i].startAddr > addr) + { + if (nvrecord_gsound_p->modelInfo[i].startAddr - addr < tailAdjacentOffset) + { + tailAdjacentOffset = nvrecord_gsound_p->modelInfo[i].startAddr - addr; + tailAdjacentIdx = i; + } + } + else if (nvrecord_gsound_p->modelInfo[i].startAddr < addr) + { + if (addr - nvrecord_gsound_p->modelInfo[i].startAddr < headAdjacentOffset) + { + headAdjacentOffset = nvrecord_gsound_p->modelInfo[i].startAddr - addr; + headAdjacentIdx = i; + } + } + } + + LOG_I("headAdjacentIdx:%d, tailAdjacentIdx:%d", headAdjacentIdx, tailAdjacentIdx); + + /// find the smaller index, smaller index means older record + if (headAdjacentIdx > tailAdjacentIdx) + { + cleanSize += F_4K_ALIGN(nvrecord_gsound_p->modelInfo[tailAdjacentIdx].startAddr + + nvrecord_gsound_p->modelInfo[tailAdjacentIdx].len) - + nvrecord_gsound_p->modelInfo[tailAdjacentIdx].startAddr; + cleanIdx = tailAdjacentIdx; + } + else + { + addr = nvrecord_gsound_p->modelInfo[headAdjacentIdx].startAddr; + cleanSize += F_4K_ALIGN(addr + nvrecord_gsound_p->modelInfo[headAdjacentIdx].len) - addr; + cleanIdx = headAdjacentIdx; + } + + /// remove the first record + for (uint8_t i = cleanIdx; i < (nvrecord_gsound_p->supportedModelCnt - 1); i++) + { + nvrecord_gsound_p->modelInfo[i] = nvrecord_gsound_p->modelInfo[i + 1]; + } + + /// decrease the number of supported model + nvrecord_gsound_p->supportedModelCnt--; + } + + if ((addr < (uint32_t)__hotword_model_start) || + (addr > (uint32_t)__hotword_model_end)) + { + LOG_I("invalid addr found:0x%x, clean all model files", addr); + nvrecord_gsound_p->supportedModelCnt = startIdx; + addr = (uint32_t)__hotword_model_start; + } + + if (0 == nvrecord_gsound_p->supportedModelCnt) + { + /// invalid number used to identify with fist time bootup + nvrecord_gsound_p->supportedModelCnt = INVALID_MODEL_NUM; + } + + int_unlock(intLock); //!< unlock the global interrupt + nv_record_post_write_operation(lock); //!< enable the MPU + + /// flush the hotword info to flash + nv_record_update_runtime_userdata(); + nv_record_flash_flush(); + } + } + } while (0); + + return addr; +} + +int nv_record_gsound_rec_get_supported_model_id(char *models_out, + uint8_t *length_out) +{ + int ret= 0; + const char* terminator = NULL; + + if (INVALID_MODEL_NUM == nvrecord_gsound_p->supportedModelCnt) + { + memcpy(models_out, STRING_TERMINATOR_NULL, STRING_TERMINATOR_SIZE); + *length_out = STRING_TERMINATOR_SIZE; + } + else + { + for (uint8_t i = 0; i < nvrecord_gsound_p->supportedModelCnt; i++) + { + LOG_I("supported model_id:%s, model_addr:%x", + nvrecord_gsound_p->modelInfo[i].modelId, + nvrecord_gsound_p->modelInfo[i].startAddr); + + memcpy((supportedModels + i * GSOUND_HOTWORD_SUPPORTED_MODEL_ID_BYTES), + nvrecord_gsound_p->modelInfo[i].modelId, + GSOUND_HOTWORD_MODEL_ID_BYTES); + + if ((i + 1) == nvrecord_gsound_p->supportedModelCnt) + { + terminator = STRING_TERMINATOR_NULL; + } + else + { + terminator = SUPPORTED_HOTWORD_MODEL_DELIM; + } + memcpy(&supportedModels[(i * GSOUND_HOTWORD_SUPPORTED_MODEL_ID_BYTES) + GSOUND_HOTWORD_MODEL_ID_BYTES], + terminator, + STRING_TERMINATOR_SIZE); + } + + if (nvrecord_gsound_p->supportedModelCnt * GSOUND_HOTWORD_SUPPORTED_MODEL_ID_BYTES <= *length_out) + { + strcpy(models_out, supportedModels); + *length_out = strlen(supportedModels) + STRING_TERMINATOR_SIZE; + LOG_I("total supported model_id(length is %d):", *length_out); + DUMP8("0x%02x ", models_out, *length_out); + } + else + { + ret = -1; + LOG_W("supported model id length exceeded max length"); + } + } + + return ret; +} +#endif diff --git a/services/nv_section/userdata_section/nvrecord_gsound.h b/services/nv_section/userdata_section/nvrecord_gsound.h new file mode 100644 index 0000000..4656c0f --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_gsound.h @@ -0,0 +1,129 @@ +/*************************************************************************** +* +*Copyright 2015-2019 BES. +*All rights reserved. All unpublished rights reserved. +* +*No part of this work may be used or reproduced in any form or by any +*means, or stored in a database or retrieval system, without prior written +*permission of BES. +* +*Use of this work is governed by a license granted by BES. +*This work contains confidential and proprietary information of +*BES. which is protected by copyright, trade secret, +*trademark and other intellectual property rights. +* +****************************************************************************/ + + +#ifndef __NVRECORD_GSOUND_H__ +#define __NVRECORD_GSOUND_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +/*****************************header include********************************/ +#include "nvrecord_extension.h" + +/******************************macro defination*****************************/ +#define F_4K_ALIGN(val) (((val)+0xFFF)&~0xFFF) +#define IS_F_4K_ALIGNED(val) (val==(val&~0xFFF)) + +#define INVALID_MODEL_NUM 0xFF //!< used to distinguish from default 0 after first time bootup +#define DEFAULT_MODEL_NUM 1 //!< number of default supported hotword model +#define DEFAULT_HOTWORD_MODEL_ID "200Q" //!< default model ID, provided by Google + +/******************************type defination******************************/ + +/****************************function declearation**************************/ + +/** + * @brief Init the gsound info pointer which is pointing to the gsound info + * saved in nv_section + * + */ +void nv_record_gsound_rec_init(void); + +/** + * @brief Get the pointer of gsound info saved in nv_section + * + * @param ptr Pointer to get the result + */ +void nv_record_gsound_rec_get_ptr(void **ptr); + +/** + * @brief Update the enable state of gsound service in nv_section + * + * @param enable true for enable, false for disable + */ +void nv_record_gsound_rec_updata_enable_state(bool enable); + + +#ifdef GSOUND_HOTWORD_ENABLED +/*--------------------------------------------------------------------------- + * nv_record_gsound_rec_is_model_insert_allowed + *--------------------------------------------------------------------------- + * + *Synopsis: + * is input model is allowed to be a supported model + * + * Parameters: + * model : string of model ID + * + * Return: + * true : imput is allowed to be a supported model + * false : imput is not allowed to be a supported model + */ +bool nv_record_gsound_rec_is_model_insert_allowed(const char *model); + +/*--------------------------------------------------------------------------- + * nv_record_gsound_rec_add_new_model + *--------------------------------------------------------------------------- + * + *Synopsis: + * add a new hotword model + * + * Parameters: + * info : should be a pointer of structure HOTWORD_MODEL_INFO_T + * NOTE: startAddr of HOTWORD_MODEL_INFO_T is invalid here + * + * Return: + * true : add successfully + * false : fail to add + */ +bool nv_record_gsound_rec_add_new_model(void *info); + +/*--------------------------------------------------------------------------- + * nv_record_gsound_rec_get_hotword_model_addr + *--------------------------------------------------------------------------- + * + *Synopsis: + * get hotword model file address accroding to the model ID + * + * Parameters: + * model_id : model id + * addNew : the flag to mark if return an avaliable addr for new model + * when incoming model ID is not found in flash + * newModelLen: the length of new incoming model + * NOTE: only useful when addNew is true + * + * Return: + * the address of model file respective to given model ID + */ +uint32_t nv_record_gsound_rec_get_hotword_model_addr(const char *model_id, bool addNew, int32_t newModelLen); + +/** + * @brief get supported hotword model ID + * + * @param models_out : pointer of supported model id string + * @param length_out : length of supported model id string + */ +int nv_record_gsound_rec_get_supported_model_id(char *models_out, + uint8_t *length_out); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __NVRECORD_GSOUND_H__ */ \ No newline at end of file diff --git a/services/nv_section/userdata_section/nvrecord_ota.c b/services/nv_section/userdata_section/nvrecord_ota.c new file mode 100644 index 0000000..bf19ef3 --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_ota.c @@ -0,0 +1,177 @@ +/** + * @file nvrecord_ota.c + * @author BES AI team + * @version 0.1 + * @date 2020-04-21 + * + * @copyright Copyright (c) 2015-2020 BES Technic. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + */ + +/*****************************header include********************************/ +#include "string.h" +#include "nv_section_dbg.h" +#include "nvrecord_ota.h" +#include "ota_common.h" + +#ifdef BISTO_ENABLED +#include "nvrecord_gsound.h" +#endif + +/*********************external function declearation************************/ + +/************************private macro defination***************************/ + +/************************private type defination****************************/ + +/**********************private function declearation************************/ + +/************************private variable defination************************/ +static NV_OTA_INFO_T *nvrecord_ota_p = NULL; + +/****************************function defination****************************/ +void nv_record_ota_init(void) +{ + if (NULL == nvrecord_ota_p) + { + nvrecord_ota_p = nvrecord_extension_p->ota_info; + } +} + +void nv_record_ota_get_ptr(void **ptr) +{ + *ptr = nvrecord_ota_p; +} + +void nv_record_ota_update_breakpoint(uint8_t user, + uint8_t deviceIndex, + uint32_t otaOffset) +{ + NV_OTA_INFO_T *pOta = &nvrecord_ota_p[deviceIndex]; + bool update = false; + + ASSERT(OTA_STAGE_ONGOING == pOta->otaStatus, + "try to update break point when OTA not in progress"); + + uint32_t lock = nv_record_pre_write_operation(); + if (user != pOta->user) + { + LOG_I("OTA user update:%d->%d", pOta->user, user); + pOta->user = user; + update = true; + } + + if (otaOffset != pOta->breakPoint) + { + LOG_I("OTA break point update:%x->%x", pOta->breakPoint, otaOffset); + pOta->breakPoint = otaOffset; + update = true; + } + nv_record_post_write_operation(lock); + + if (update) + { + nv_record_extension_update(); + nv_record_execute_async_flush(); + } +} + +bool nv_record_ota_update_info(uint8_t user, + uint8_t deviceIndex, + uint8_t status, + uint32_t totalImageSize, + const char *session) +{ + NV_OTA_INFO_T *pOta = &nvrecord_ota_p[deviceIndex]; + + LOG_I("%s", __func__); + LOG_I("ota_status:%d->%d, user:%d, device_index:%d, imageSize:%d, version:%s", + pOta->otaStatus, + status, + user, + deviceIndex, + totalImageSize, + session); + + bool ret = true; + bool update = false; + +#ifdef GSOUND_HOTWORD_ENABLED + if ((OTA_USER_COLORFUL == user) && + (OTA_DEVICE_HOTWORD == deviceIndex)) + { + ret = nv_record_gsound_rec_is_model_insert_allowed(session); + } +#endif + + if (ret) + { + uint32_t lock = nv_record_pre_write_operation(); + if (!memcmp(pOta->version, session, strlen(session) + 1)) + { + memset(pOta->version, + 0, + ARRAY_SIZE(pOta->version)); + update = true; + } + + if (pOta->otaStatus != status) + { + pOta->otaStatus = status; + update = true; + LOG_I("update device %d ota status to %d", + deviceIndex, + pOta->otaStatus); + } + + if (OTA_STAGE_IDLE == status) + { + if (0 != pOta->breakPoint) + { + pOta->breakPoint = 0; + update = true; + } + } + else if (OTA_STAGE_ONGOING == status) + { + ASSERT(totalImageSize, "Received total image size is 0."); + ASSERT(session, "Received session pointer is NULL."); + + if (pOta->imageSize != totalImageSize) + { + pOta->imageSize = totalImageSize; + update = true; + } + } + else if (OTA_STAGE_DONE == status) + { + ASSERT(totalImageSize == pOta->imageSize, + "total image size changed:%d->%d.", pOta->imageSize, totalImageSize); + + if (totalImageSize != pOta->breakPoint) + { + pOta->breakPoint = totalImageSize; + update = true; + } + } + nv_record_post_write_operation(lock); + + if (update) + { + LOG_I("will update info into flash."); + nv_record_extension_update(); + nv_record_execute_async_flush(); + } + } + + return ret; +} diff --git a/services/nv_section/userdata_section/nvrecord_ota.h b/services/nv_section/userdata_section/nvrecord_ota.h new file mode 100644 index 0000000..adf400a --- /dev/null +++ b/services/nv_section/userdata_section/nvrecord_ota.h @@ -0,0 +1,86 @@ +/** + * @file nvrecord_ota.h + * @author BES AI team + * @version 0.1 + * @date 2020-04-21 + * + * @copyright Copyright (c) 2015-2020 BES Technic. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + */ + + +#ifndef __NVRECORD_OTA_H__ +#define __NVRECORD_OTA_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +/*****************************header include********************************/ +#include "nvrecord_extension.h" + +/******************************macro defination*****************************/ + +/******************************type defination******************************/ + +/****************************function declearation**************************/ +/** + * @brief Initialize the nvrecord pointer. + * + */ +void nv_record_ota_init(void); + +/** + * @brief Get the pointer of OTA info saved in flash. + * + * NOTE: OTA support mutiple devices(currently APP and hotword model file), so + * you need to use the device index and the pointer from this function you get + * to get the device specific OTA info. + * + * @param ptr pointer used to get the flash pointer + */ +void nv_record_ota_get_ptr(void **ptr); + +/** + * @brief Update the break point for OTA progress. + * + * @param user current user + * @param deviceIndex current deivce index + * @param otaOffset break point to update + */ +void nv_record_ota_update_breakpoint(uint8_t user, + uint8_t deviceIndex, + uint32_t otaOffset); + +/** + * @brief Update the OTA info. + * + * @param user current OTA user + * @param deviceIndex current device in OTA progress + * @param status OTA status(stage) to update, + * @see OTA_STAGE_E to get more details + * @param imageSize image size + * @param session OTA version string pointer + * @return true OTA info update successfully + * @return false OTA info update failed + */ +bool nv_record_ota_update_info(uint8_t user, + uint8_t deviceIndex, + uint8_t status, + uint32_t imageSize, + const char *session); + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __NVRECORD_OTA_H__ */ \ No newline at end of file diff --git a/services/nvrecord/Makefile b/services/nvrecord/Makefile new file mode 100644 index 0000000..1f71d37 --- /dev/null +++ b/services/nvrecord/Makefile @@ -0,0 +1,28 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y += \ + -Iutils/hexdump \ + -Iapps/key \ + -Iservices/bt_app \ + $(BT_IF_INCLUDES) \ + -Iutils/crc32 \ + -Iplatform/drivers/ana \ + -Iservices/nv_section/customparam_section \ + -Iservices/ble_stack/common/api \ + -Iservices/ble_stack/ble_ip \ + -Iutils/heap \ + -Iutils/encrypt \ + -Iservices/norflash_api \ + -Iservices/nv_setion/userdata_section + +CFLAGS_nvrecord.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) + +ifeq ($(FLASH_SUSPEND),1) +CFLAGS_nvrecord.o += -DFLASH_SUSPEND +endif + diff --git a/services/nvrecord/list_ext.c b/services/nvrecord/list_ext.c new file mode 100644 index 0000000..0b0a0e4 --- /dev/null +++ b/services/nvrecord/list_ext.c @@ -0,0 +1,255 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "stdio.h" +#include "cmsis_os.h" +#include "hal_trace.h" +#include "string.h" +#include "list_ext.h" + +static list_node_t *list_free_node_ext(list_t *list, list_node_t *node); + +void *zmalloc_ext (size_t size){ + void *ptr = NULL; + ptr = pool_malloc(size); + memset(ptr, 0, size); + return ptr; +} +// Returns a new, empty list. Returns NULL if not enough memory could be allocated +// for the list structure. The returned list must be freed with |list_free|. The +// |callback| specifies a function to be called whenever a list element is removed +// from the list. It can be used to release resources held by the list element, e.g. +// memory or file descriptor. |callback| may be NULL if no cleanup is necessary on +// element removal. +list_t *list_new_ext(list_free_cb callback) { + list_t *list = (list_t *)zmalloc_ext(sizeof(list_t)); + if (list) + list->free_cb = callback; + return list; +} + +// Frees the list. This function accepts NULL as an argument, in which case it +// behaves like a no-op. +void list_free_ext(list_t *list) { + if (list != NULL) + list_clear_ext(list); + pool_free(list); +} + +// Returns true if the list is empty (has no elements), false otherwise. +// Note that a NULL list is not the same as an empty list. This function +// does not accept a NULL list. +bool list_is_empty_ext(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + return (list->length == 0); +} + +// Returns the length of the list. This function does not accept a NULL list. +size_t list_length_ext(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + return list->length; +} + +// Returns the first element in the list without removing it. |list| may not +// be NULL or empty. +void *list_front_ext(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + bool nRet = list_is_empty_ext(list); + ASSERT(!nRet,"%s",__func__); + return list->head->data; +} + +// Returns the last element in the list without removing it. |list| may not +// be NULL or empty. +void *list_back_ext(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + bool nRet = list_is_empty_ext(list); + ASSERT(!nRet,"%s",__func__); + + return list->tail->data; +} + +bool list_insert_after_ext(list_t *list, list_node_t *prev_node, void *data) { + list_node_t *node = NULL; + ASSERT(list != NULL,"%s",__func__); + ASSERT(prev_node != NULL,"%s",__func__); + ASSERT(data != NULL,"%s",__func__); + + node = (list_node_t *)pool_malloc(sizeof(list_node_t)); + if (!node) + return false; + + node->next = prev_node->next; + node->data = data; + prev_node->next = node; + if (list->tail == prev_node) + list->tail = node; + ++list->length; + return true; +} + +#include "stdio.h" +// Inserts |data| at the beginning of |list|. Neither |data| nor |list| may be NULL. +// This function does not make a copy of |data| so the pointer must remain valid +// at least until the element is removed from the list or the list is freed. +// Returns true if |data| could be inserted, false otherwise (e.g. out of memory). +bool list_prepend_ext(list_t *list, void *data) { + list_node_t *node = NULL; + ASSERT(list != NULL,"%s",__func__); + ASSERT(data != NULL,"%s",__func__); + node = (list_node_t *)zmalloc_ext(sizeof(list_node_t)); + if (!node) + return false; + node->next = list->head; + node->data = data; + list->head = node; + if (list->tail == NULL) + list->tail = list->head; + ++list->length; + return true; +} + +// Inserts |data| at the end of |list|. Neither |data| nor |list| may be NULL. +// This function does not make a copy of |data| so the pointer must remain valid +// at least until the element is removed from the list or the list is freed. +// Returns true if |data| could be inserted, false otherwise (e.g. out of memory). +bool list_append_ext(list_t *list, void *data) { + list_node_t *node = NULL; + ASSERT(list != NULL,"%s",__func__); + ASSERT(data != NULL,"%s",__func__); + node = (list_node_t *)pool_malloc(sizeof(list_node_t)); + if (!node) + return false; + node->next = NULL; + node->data = data; + if (list->tail == NULL) { + list->head = node; + list->tail = node; + } else { + list->tail->next = node; + list->tail = node; + } + ++list->length; + return true; +} + +// Removes |data| from the list. Neither |list| nor |data| may be NULL. If |data| +// is inserted multiple times in the list, this function will only remove the first +// instance. If a free function was specified in |list_new|, it will be called back +// with |data|. This function returns true if |data| was found in the list and removed, +// false otherwise. +bool list_remove_ext(list_t *list, void *data) { + list_node_t *prev = NULL, *node = NULL; + ASSERT(list != NULL,"%s",__func__); + ASSERT(data != NULL,"%s",__func__); + + if (list_is_empty_ext(list)) + return false; + + if (list->head->data == data) { + list_node_t *next = list_free_node_ext(list, list->head); + if (list->tail == list->head) + list->tail = next; + list->head = next; + return true; + } + + for (prev = list->head, node = list->head->next; node; prev = node, node = node->next) + if (node->data == data) { + prev->next = list_free_node_ext(list, node); + if (list->tail == node) + list->tail = prev; + return true; + } + + return false; +} + +// Removes all elements in the list. Calling this function will return the list to the +// same state it was in after |list_new|. |list| may not be NULL. +void list_clear_ext(list_t *list) { + list_node_t *node = NULL; + ASSERT(list != NULL,"%s",__func__); + for (node = list->head; node; ) + node = list_free_node_ext(list, node); + list->head = NULL; + list->tail = NULL; + list->length = 0; +} + +// Iterates through the entire |list| and calls |callback| for each data element. +// If the list is empty, |callback| will never be called. It is safe to mutate the +// list inside the callback. If an element is added before the node being visited, +// there will be no callback for the newly-inserted node. Neither |list| nor +// |callback| may be NULL. +void list_foreach_ext(const list_t *list, list_iter_cb callback) { + list_node_t *node = NULL; + ASSERT(list != NULL,"%s",__func__); + ASSERT(callback != NULL,"%s",__func__); + + for (node = list->head; node; ) { + list_node_t *next = node->next; + callback(node->data); + node = next; + } +} + +// Returns an iterator to the first element in |list|. |list| may not be NULL. +// The returned iterator is valid as long as it does not equal the value returned +// by |list_end|. +list_node_t *list_begin_ext(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + return list->head; +} + +// Returns an iterator that points past the end of the list. In other words, +// this function returns the value of an invalid iterator for the given list. +// When an iterator has the same value as what's returned by this function, you +// may no longer call |list_next| with the iterator. |list| may not be NULL. +list_node_t *list_end_ext(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + return NULL; +} + +// Given a valid iterator |node|, this function returns the next value for the +// iterator. If the returned value equals the value returned by |list_end|, the +// iterator has reached the end of the list and may no longer be used for any +// purpose. +list_node_t *list_next_ext(const list_node_t *node) { + ASSERT(node != NULL,"%s",__func__); + return node->next; +} + +// Returns the value stored at the location pointed to by the iterator |node|. +// |node| must not equal the value returned by |list_end|. +void *list_node_ext(const list_node_t *node) { + ASSERT(node != NULL,"%s",__func__); + return node->data; +} + +static list_node_t *list_free_node_ext(list_t *list, list_node_t *node) { + list_node_t *next = NULL; + ASSERT(list != NULL,"%s",__func__); + ASSERT(node != NULL,"%s",__func__); + + next = node->next; + + if (list->free_cb) + list->free_cb(node->data); + pool_free(node); + --list->length; + + return next; +} diff --git a/services/nvrecord/list_ext.h b/services/nvrecord/list_ext.h new file mode 100644 index 0000000..2b6529e --- /dev/null +++ b/services/nvrecord/list_ext.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#pragma once + +#ifndef __LIST_H__ +#define __LIST_H__ + +#include +#include +#include "heap_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern heap_handle_t g_nv_mempool; + +#define pool_malloc(size) heap_malloc(g_nv_mempool,size) +#define pool_free(ptr) heap_free(g_nv_mempool,ptr) +#define pool_free_space() heap_free_size(g_nv_mempool) + +typedef void (*list_free_cb)(void *data); +typedef bool (*list_iter_cb)(void *data); + +typedef struct list_node_t { + struct list_node_t *next; + void *data; +} list_node_t; + +typedef struct list_t { + list_node_t *head; + list_node_t *tail; + size_t length; + list_free_cb free_cb; +} list_t; + +//struct list_t; +typedef struct list_t list_t; +void *zmalloc_ext (size_t size); +// Lifecycle. +list_t *list_new_ext(list_free_cb callback); +void list_free_ext(list_t *list); + +// Accessors. +bool list_is_empty_ext(const list_t *list); +size_t list_length_ext(const list_t *list); +void *list_front_ext(const list_t *list); +void *list_back_ext(const list_t *list); + +// Mutators. +bool list_insert_after_ext(list_t *list, list_node_t *prev_node, void *data); +bool list_prepend_ext(list_t *list, void *data); +bool list_append_ext(list_t *list, void *data); +bool list_remove_ext(list_t *list, void *data); +void list_clear_ext(list_t *list); + +// Iteration. +void list_foreach_ext(const list_t *list, list_iter_cb callback); + +list_node_t *list_begin_ext(const list_t *list); +list_node_t *list_end_ext(const list_t *list); +list_node_t *list_next_ext(const list_node_t *node); +void *list_node_ext(const list_node_t *node); + +#ifdef __cplusplus + } +#endif + +#endif//__FMDEC_H__ + diff --git a/services/nvrecord/nvrec_config.c b/services/nvrecord/nvrec_config.c new file mode 100644 index 0000000..aa76644 --- /dev/null +++ b/services/nvrecord/nvrec_config.c @@ -0,0 +1,326 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#define LOG_TAG "bt_osi_config" + +#include +#include +#include "stdio.h" +#include +#include +#include "list_ext.h" +#include "nvrecord.h" +#include "nvrec_config.h" +#include "hal_trace.h" +static nvrec_section_t *nvrec_section_new(const char *name); +static void nvrec_section_free(void *ptr); + +static nvrec_entry_t *nvrec_entry_new(const char *key,const char *value,const char *descrip); +static nvrec_entry_t *nvrec_entry_find(const nvrec_config_t *config, const char *section, const char *key); + +void *cfg_malloc (unsigned int size) +{ + void *ptr = NULL; + if(size == 0) + return NULL; + ptr = pool_malloc(size); + if(ptr == NULL) + { + printf("cfg_malloc......ERROR\n"); + } + return ptr; +} + +void *cfg_zmalloc (unsigned int size) +{ + void *ptr = NULL; + ptr = cfg_malloc(size); + memset(ptr, 0, size); + return ptr; +} + +void cfg_free (void *p_mem) +{ + pool_free(p_mem); +} + +nvrec_config_t *nvrec_config_new(const char *filename) { + nvrec_config_t *config; + //add your code at here +// printf("nvrec_config_new-->cfg_zmalloc..........................\r\n"); + config = (nvrec_config_t *)cfg_zmalloc(sizeof(nvrec_config_t)); + if(config) + config->sections = list_new_ext(nvrec_section_free); + + return config; +} + +void nvrec_config_free(nvrec_config_t *config) { + if (!config) + return; + + list_free_ext(config->sections); +// printf("nvrec_config_free-->cfg_free..........................\r\n"); + cfg_free(config); +} + +bool nvrec_config_has_section(const nvrec_config_t *config, const char *section) { + assert(config != NULL); + assert(section != NULL); + + return (nvrec_section_find(config, section) != NULL); +} + +bool nvrec_config_has_key(const nvrec_config_t *config, const char *section, const char *key) { + assert(config != NULL); + assert(section != NULL); + assert(key != NULL); + + return (nvrec_entry_find(config, section, key) != NULL); +} + +int nvrec_config_get_int(const nvrec_config_t *config, const char *section, const char *key, int def_value) { + nvrec_entry_t *entry = NULL; + char *endptr = NULL; + int ret = 0; + assert(config != NULL); + assert(section != NULL); + assert(key != NULL); + + entry = nvrec_entry_find(config, section, key); + if (!entry) + return def_value; + + ret = strtol(entry->value, &endptr, 0); + return (*endptr == '\0') ? ret : def_value; +} + +bool nvrec_config_get_bool(const nvrec_config_t *config, const char *section, const char *key, bool def_value) { + nvrec_entry_t *entry = NULL; + assert(config != NULL); + assert(section != NULL); + assert(key != NULL); + + entry = nvrec_entry_find(config, section, key); + if (!entry) + return def_value; + + if (!strcmp(entry->value, "true")) + return true; + if (!strcmp(entry->value, "false")) + return false; + + return def_value; +} + +const char *nvrec_config_get_string(const nvrec_config_t *config, const char *section, const char *key, const char *def_value) { + nvrec_entry_t *entry = NULL; + + assert(config != NULL); + assert(section != NULL); + assert(key != NULL); + + + + entry = nvrec_entry_find(config, section, key); + + if (!entry) + return def_value; + + return entry->value; +} + +void nvrec_config_set_int(nvrec_config_t *config, const char *section, const char *key, int value) { + + char value_str[32] = { 0 }; + assert(config != NULL); + assert(section != NULL); + assert(key != NULL); + + sprintf(value_str, "%d", value); + nvrec_config_set_string(config, section, key, value_str); +} + +void nvrec_config_set_bool(nvrec_config_t *config, const char *section, const char *key, bool value) { + assert(config != NULL); + assert(section != NULL); + assert(key != NULL); + + nvrec_config_set_string(config, section, key, value ? "true" : "false"); +} + +void *strdup_ext(const char *value) +{ + void *ptr = NULL; + + if(NULL != value) + { + size_t malloclen = (strlen(value)+1); + ptr = zmalloc_ext(malloclen); + memcpy(ptr,value,strlen(value)); + } + return ptr; +} + +static char *bdaddrdup(const char * string,unsigned int len) +{ + char *memory; + + if (!string) + return(NULL); + memory = cfg_zmalloc(len+1); + if (NULL != memory) + { + memcpy(memory,string,len); + return memory; + } + return(NULL); +} + +void nvrec_config_set_string(nvrec_config_t *config, const char *section, const char *key, const char *value) { + nvrec_entry_t *entry = NULL; + list_node_t *node = NULL; + nvrec_section_t *sec = nvrec_section_find(config, section); + if (!sec) { + sec = nvrec_section_new(section); + list_append_ext(config->sections, sec); + } + if(0 == strcmp(section,section_name_ddbrec)) + { + for (node = list_begin_ext(sec->entries); node != list_end_ext(sec->entries); node = list_next_ext(node)) + { + entry = list_node_ext(node); + if (0 == memcmp(entry->key, key, BTIF_BD_ADDR_SIZE)) + { + cfg_free(entry->value); + entry->value = (char *)strdup_ext(value); + return; + } + } + } + else + { + for (node = list_begin_ext(sec->entries); node != list_end_ext(sec->entries); node = list_next_ext(node)) + { + entry = list_node_ext(node); + if (!strcmp(entry->key, key)) + { + cfg_free(entry->value); + entry->value = (char *)strdup_ext(value); + return; + } + } + } + entry = nvrec_entry_new(key,value,section); + list_append_ext(sec->entries, entry); +} + +static nvrec_section_t *nvrec_section_new(const char *name) { + // printf("nvrec_section_new-->cfg_zmalloc..........................\r\n"); + nvrec_section_t *section = cfg_zmalloc(sizeof(nvrec_section_t)); + if (!section) + return NULL; + + section->name = strdup_ext(name); + section->entries = list_new_ext(nvrec_entry_free); + return section; +} + +static void nvrec_section_free(void *ptr) { + nvrec_section_t *section = ptr; + if (!ptr) + return; +// printf("nvrec_section_free-->cfg_free..........................\r\n"); + cfg_free(section->name); + list_free_ext(section->entries); + cfg_free(section); +} + +nvrec_section_t *nvrec_section_find(const nvrec_config_t *config, const char *section) { + nvrec_section_t *sec = NULL; + list_node_t *node = NULL; + for (node = list_begin_ext(config->sections); node != list_end_ext(config->sections); node = list_next_ext(node)) { + sec = list_node_ext(node); + if (!strcmp(sec->name, section)) + return sec; + } + + return NULL; +} + +static nvrec_entry_t *nvrec_entry_new(const char *key,const char *value,const char *descrip) +{ + nvrec_entry_t *entry = cfg_zmalloc(sizeof(nvrec_entry_t)); + if (!entry) + return NULL; + if(0 == strcmp(descrip,section_name_ddbrec)) + entry->key = bdaddrdup(key,BTIF_BD_ADDR_SIZE); + else + entry->key = strdup_ext(key); + entry->value = strdup_ext(value); + return entry; +} + +void nvrec_entry_free(void *ptr) { + nvrec_entry_t *entry = ptr; + if (!ptr) + return; +// printf("entry_free-->cfg_free..........................\r\n"); + cfg_free(entry->key); + cfg_free(entry->value); + cfg_free(entry); +} + +static nvrec_entry_t *nvrec_entry_find(const nvrec_config_t *config, const char *section, const char *key) { + list_node_t *node = NULL; + nvrec_section_t *sec = nvrec_section_find(config, section); + if (!sec) + return NULL; + if(0 == strcmp(section,section_name_ddbrec)) + { + for (node = list_begin_ext(sec->entries); node != list_end_ext(sec->entries); node = list_next_ext(node)) + { + nvrec_entry_t *entry = list_node_ext(node); + if (0 == memcmp((const void*)entry->key, (const void*)key, BTIF_BD_ADDR_SIZE)) + return entry; + } + return NULL; + } + else + { + for (node = list_begin_ext(sec->entries); node != list_end_ext(sec->entries); node = list_next_ext(node)) { + nvrec_entry_t *entry = list_node_ext(node); + if (!strcmp(entry->key, key)) + return entry; + } + + return NULL; + } +} +#if 0 +int nevrec_entry_remove(const config_t *config, const char *section, const char *key) { + list_node_t *node; + section_t *sec = section_find(config, section); + if (!sec) + return NULL; + for (node = list_begin_ext(sec->entries); node != list_end_ext(sec->entries); node = list_next_ext(node)) { + entry_t *entry = list_node_ext(node); + if (!strcmp(entry->key, key)) + list_remove_ext(sec->entries, entry); + return 0; + } + return 0; +} +#endif diff --git a/services/nvrecord/nvrec_config.h b/services/nvrecord/nvrec_config.h new file mode 100644 index 0000000..f3df2ba --- /dev/null +++ b/services/nvrecord/nvrec_config.h @@ -0,0 +1,108 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __OSI_CONFIG_H__ +#define __OSI_CONFIG_H__ + +// This module implements a configuration parser. Clients can query the +// contents of a configuration file through the interface provided here. +// The current implementation is read-only; mutations are only kept in +// memory. This parser supports the INI file format. + +// Implementation notes: +// - Key/value pairs that are not within a section are assumed to be under +// the |CONFIG_DEFAULT_SECTION| section. +// - Multiple sections with the same name will be merged as if they were in +// a single section. +// - Empty sections with no key/value pairs will be treated as if they do +// not exist. In other words, |nvrec_config_has_section| will return false for +// empty sections. +// - Duplicate keys in a section will overwrite previous values. + +#include +#include "list_ext.h" +// The default section name to use if a key/value pair is not defined within +// a section. +#define CONFIG_DEFAULT_SECTION "Global" +typedef struct { + char *key; + char *value; +} nvrec_entry_t; + +typedef struct { + char *name; + list_t *entries; +} nvrec_section_t; + +typedef struct nvrec_config { + list_t *sections; +}nvrec_config_t; + +// Loads the specified file and returns a handle to the config file. If there +// was a problem loading the file or allocating memory, this function returns +// NULL. Clients must call |nvrec_config_free| on the returned handle when it is no +// longer required. |filename| must not be NULL and must point to a readable +// file on the filesystem. +nvrec_config_t *nvrec_config_new(const char *filename); + +// Frees resources associated with the config file. No further operations may +// be performed on the |config| object after calling this function. |config| +// may be NULL. +void nvrec_config_free(nvrec_config_t *config); + +// Returns true if the config file contains a section named |section|. If +// the section has no key/value pairs in it, this function will return false. +// |config| and |section| must not be NULL. +bool nvrec_config_has_section(const nvrec_config_t *config, const char *section); + +// Returns true if the config file has a key named |key| under |section|. +// Returns false otherwise. |config|, |section|, and |key| must not be NULL. +bool nvrec_config_has_key(const nvrec_config_t *config, const char *section, const char *key); + +// Returns the integral value for a given |key| in |section|. If |section| +// or |key| do not exist, or the value cannot be fully converted to an integer, +// this function returns |def_value|. |config|, |section|, and |key| must not +// be NULL. +int nvrec_config_get_int(const nvrec_config_t *config, const char *section, const char *key, int def_value); + +// Returns the boolean value for a given |key| in |section|. If |section| +// or |key| do not exist, or the value cannot be converted to a boolean, this +// function returns |def_value|. |config|, |section|, and |key| must not be NULL. +bool nvrec_config_get_bool(const nvrec_config_t *config, const char *section, const char *key, bool def_value); + +// Returns the string value for a given |key| in |section|. If |section| or +// |key| do not exist, this function returns |def_value|. The returned string +// is owned by the config module and must not be freed. |config|, |section|, +// and |key| must not be NULL. |def_value| may be NULL. +const char *nvrec_config_get_string(const nvrec_config_t *config, const char *section, const char *key, const char *def_value); + +// Sets an integral value for the |key| in |section|. If |key| or |section| do +// not already exist, this function creates them. |config|, |section|, and |key| +// must not be NULL. +void nvrec_config_set_int(nvrec_config_t *config, const char *section, const char *key, int value); + +// Sets a boolean value for the |key| in |section|. If |key| or |section| do +// not already exist, this function creates them. |config|, |section|, and |key| +// must not be NULL. +void nvrec_config_set_bool(nvrec_config_t *config, const char *section, const char *key, bool value); + +// Sets a string value for the |key| in |section|. If |key| or |section| do +// not already exist, this function creates them. |config|, |section|, |key|, and +// |value| must not be NULL. +void nvrec_config_set_string(nvrec_config_t *config, const char *section, const char *key, const char *value); +nvrec_section_t *nvrec_section_find(const nvrec_config_t *config, const char *section); +void nvrec_entry_free(void *ptr); +#endif + diff --git a/services/nvrecord/nvrecord.c b/services/nvrecord/nvrecord.c new file mode 100644 index 0000000..8d9bee9 --- /dev/null +++ b/services/nvrecord/nvrecord.c @@ -0,0 +1,2013 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "hal_sleep.h" +#include "besbt.h" +#include "nvrecord.h" +#include "nvrecord_dev.h" +#include "nvrecord_env.h" +#include "crc32.h" +#include "hal_timer.h" +#include "hal_norflash.h" +#include "pmu.h" +#include "tgt_hardware.h" +#include "norflash_api.h" + +//#define NVREC_BURN_TEST +#define OS_DUMP8(x...) + +// factory section region +#define NVRECORD_CACHE_2_UNCACHE(addr) \ + ((unsigned char *)((unsigned int)addr & ~(0x04000000))) + +static bool dev_sector_valid = false; +uint8_t nv_record_dev_rev = NVREC_DEV_NEWEST_REV; +#define CLASSIC_BTNAME_LEN (BLE_NAME_LEN_IN_NV-5) +char classics_bt_name[CLASSIC_BTNAME_LEN]= "BES"; + +extern uint32_t __factory_start[]; + +/* + dev_version_and_magic, //0 + dev_crc, // 1 + dev_reserv1, // 2 + dev_reserv2, //3// 3 + dev_name, //[4~66] + dev_bt_addr = 67, //[67~68] + dev_ble_addr = 69, //[69~70] + dev_dongle_addr = 71, + dev_xtal_fcap = 73, //73 + dev_data_len = 74, + + dev_ble_name = 75, //[75~82] +*/ + +#if !defined(NEW_NV_RECORD_ENABLED) +#ifdef __ARMCC_VERSION +#define USERDATA_POOL_LOC __attribute__((section(".bss.userdata_pool"))) +#else +#define USERDATA_POOL_LOC __attribute__((section(".userdata_pool"))) +#endif + +//#define LINK_KEY_ENCRYPT +#ifdef LINK_KEY_ENCRYPT +#include "aes.h" +#define LINK_KEY_ENCRYPT_KEY "\x11\x07\x9e\x34\x9B\x5F\x80\x00\x00\x80\x00\x10\x00\x00\x00\x01" +#endif + +extern uint32_t __userdata_start[]; +extern uint32_t __userdata_end[]; +extern int nv_record_flash_flush_in_sleep(void); +static int nv_record_flash_flush_int(bool is_async); + +void nv_callback(void* param); + +nv_record_struct nv_record_config; +static bool nvrec_init = false; +static bool nvrec_mempool_init = false; + +static uint32_t _user_data_main_start; +static uint32_t _user_data_bak_start; + +static uint32_t USERDATA_POOL_LOC usrdata_ddblist_pool[1024]; + +static void nv_record_print_dev_record(const btif_device_record_t* record) +{ +#ifdef nv_record_debug + + nvrec_trace(0,"nv record bdAddr = "); + DUMP8("%02x ",record->bdAddr.address,sizeof(record->bdAddr.address)); + nvrec_trace(0,"record_trusted = "); + DUMP8("%d ",&record->trusted,sizeof((uint8_t)record->trusted)); + nvrec_trace(0,"record_linkKey = "); + DUMP8("%02x ",record->linkKey,sizeof(record->linkKey)); + nvrec_trace(0,"record_keyType = "); + DUMP8("%x ",&record->keyType,sizeof(record->keyType)); + nvrec_trace(0,"record_pinLen = "); + DUMP8("%x ",&record->pinLen,sizeof(record->pinLen)); + +#endif +} + +heap_handle_t g_nv_mempool = NULL; + +static void nv_record_mempool_init(void) +{ + unsigned char *poolstart = 0; + + poolstart = (unsigned char *)(usrdata_ddblist_pool+mempool_pre_offset); + if(!nvrec_mempool_init) + { + g_nv_mempool = heap_register((unsigned char*)poolstart, (size_t)(sizeof(usrdata_ddblist_pool)-(mempool_pre_offset*sizeof(uint32_t)))); + nvrec_mempool_init = TRUE; + } + /*add other memory pool */ + +} + +static bool nv_record_data_is_valid(void) +{ + uint32_t crc; + uint32_t flsh_crc; + uint32_t verandmagic; + + verandmagic = usrdata_ddblist_pool[0]; + if(((nvrecord_struct_version<<16)|nvrecord_magic) != verandmagic) + { + nvrec_trace(2,"%s: verandmagic error! verandmagic = 0x%x.",__func__,((nvrecord_struct_version<<16)|nvrecord_magic)); + return false; + } + crc = crc32(0,(uint8_t *)(&usrdata_ddblist_pool[pos_heap_contents]),(sizeof(usrdata_ddblist_pool)-(pos_heap_contents*sizeof(uint32_t)))); + flsh_crc = usrdata_ddblist_pool[pos_crc]; + if (flsh_crc == crc) + { + return true; + } + else + { + nvrec_trace(3,"%s: crc checking fail! flsh_crc = 0x%x,crc = 0x%x.",__func__,flsh_crc,crc); + return false; + } +} + +static bool nv_record_list_is_valid(void) +{ + nvrec_config_t *config = NULL; + nvrec_section_t *sec = NULL; + list_node_t *node = NULL; + list_node_t *sub_node = NULL; + nvrec_entry_t *entry = NULL; + bool ret = true; + uint32_t mem_start; + uint32_t mem_end; + + config = (nvrec_config_t *)usrdata_ddblist_pool[pos_config_addr]; + if(usrdata_ddblist_pool[pos_start_ram_addr] != (uint32_t)usrdata_ddblist_pool) + { + return false; + } + mem_start = (uint32_t)config; + mem_end = mem_start + (sizeof(usrdata_ddblist_pool)-(pos_heap_contents*sizeof(uint32_t))); + for (node = list_begin_ext(config->sections); node != list_end_ext(config->sections); node = list_next_ext(node)) + { + sec = list_node_ext(node); + + for (sub_node = list_begin_ext(sec->entries); sub_node != list_end_ext(sec->entries); sub_node = list_next_ext(sub_node)) + { + entry = list_node_ext(sub_node); + if(entry->key == NULL || entry->value == NULL) + { + ret = false; + break; + } + + if(((uint32_t)entry->key >= mem_start && (uint32_t)entry->key + strlen(entry->key) < mem_end) + && ((uint32_t)entry->value >= mem_start && (uint32_t)entry->value + strlen(entry->value) < mem_end)) + { + // nvrec_trace(4,"%s: entry = 0x%x,key = 0x%x, value = 0x%x.", + // __func__,(uint32_t)entry,(uint32_t)entry->key,(uint32_t)entry->value); + } + else + { + nvrec_trace(4,"%s: sec = 0x%x,name = %s, entries = 0x%x.", + __func__,(uint32_t)sec,sec->name,(uint32_t)sec->entries); + nvrec_trace(4,"%s: entry pointer error! entry = 0x%x,key = 0x%x, value = 0x%x.", + __func__,(uint32_t)entry,(uint32_t)entry->key,(uint32_t)entry->value); + ret = false; + break; + } + } + if(!ret) + { + break; + } + } + return ret; +} + +void nv_record_init(void) +{ + enum NORFLASH_API_RET_T result; + uint32_t sector_size = 0; + uint32_t block_size = 0; + uint32_t page_size = 0; + + hal_norflash_get_size(HAL_NORFLASH_ID_0, + NULL, + &block_size, + §or_size, + &page_size); + result = norflash_api_register(NORFLASH_API_MODULE_ID_USERDATA, + HAL_NORFLASH_ID_0, + ((uint32_t)__userdata_start), + (uint32_t)__userdata_end - (uint32_t)__userdata_start, + block_size, + sector_size, + page_size, + sizeof(usrdata_ddblist_pool)*2, + nv_callback + ); + ASSERT(result == NORFLASH_API_OK,"nv_record_init: module register failed! result = %d.",result); +} + +bt_status_t nv_record_open(SECTIONS_ADP_ENUM section_id) +{ + bt_status_t ret_status = BT_STS_FAILED; + uint32_t lock; + bool main_is_valid = false; + bool bak_is_valid = false; + bool data_is_valid = false; + if(nvrec_init) + { + return BT_STS_SUCCESS; + } + _user_data_main_start = (uint32_t)__userdata_start; + _user_data_bak_start = (uint32_t)__userdata_start + nvrecord_mem_pool_size; + + lock = int_lock_global(); + + nv_record_config.is_update = false; + nv_record_config.written_size = 0; + nv_record_config.state = NV_STATE_IDLE; + switch(section_id) + { + case section_usrdata_ddbrecord: + // userdata main sector checking. + memcpy((void *)usrdata_ddblist_pool,(void *)_user_data_main_start, + sizeof(usrdata_ddblist_pool)); + if( nv_record_data_is_valid() + && usrdata_ddblist_pool[pos_start_ram_addr]==(uint32_t)usrdata_ddblist_pool) + { + if(nv_record_list_is_valid()) + { + // nvrec_trace(1,"%s,main sector list valid.",__func__); + main_is_valid = true; + } + else + { + nvrec_trace(1,"%s,main sector list invalid.",__func__); + main_is_valid = false; + } + } + else + { + nvrec_trace(1,"%s,main sector data invalid.",__func__); + main_is_valid = false; + } + + // userdata bak sector checking. + memcpy((void *)usrdata_ddblist_pool,(void *)_user_data_bak_start, + sizeof(usrdata_ddblist_pool)); + if( nv_record_data_is_valid() + && usrdata_ddblist_pool[pos_start_ram_addr]==(uint32_t)usrdata_ddblist_pool) + { + if(nv_record_list_is_valid()) + { + // TRACE(1,"%s,bak sector list valid.",__func__); + bak_is_valid = true; + } + else + { + nvrec_trace(1,"%s,bak sector list invalid.",__func__); + bak_is_valid = false; + } + } + else + { + nvrec_trace(1,"%s,bak sector data invalid.",__func__); + bak_is_valid = false; + } + + if(main_is_valid) + { + memcpy((void *)usrdata_ddblist_pool,(void *)_user_data_main_start, + sizeof(usrdata_ddblist_pool)); + data_is_valid = true; + if(!bak_is_valid) + { + nv_record_config.is_update = true; + nv_record_config.state = NV_STATE_MAIN_DONE; + nv_record_config.config = (nvrec_config_t *)usrdata_ddblist_pool[pos_config_addr]; + nv_record_flash_flush_int(false); + } + } + else + { + if(bak_is_valid) + { + memcpy((void *)usrdata_ddblist_pool,(void *)_user_data_bak_start, + sizeof(usrdata_ddblist_pool)); + nv_record_config.config = (nvrec_config_t *)usrdata_ddblist_pool[pos_config_addr]; + data_is_valid = true; + nv_record_config.is_update = true; + nv_record_config.state = NV_STATE_IDLE; + nv_record_flash_flush_int(false); + } + else + { + data_is_valid = false; + } + } + + if(data_is_valid) + { + nv_record_config.config = (nvrec_config_t *)usrdata_ddblist_pool[pos_config_addr]; + // nvrec_trace(4,"%s,config=0x%x,g_nv_mempool=0x%x,ln=%d\n", + // nvrecord_tag,usrdata_ddblist_pool[pos_config_addr],g_nv_mempool,__LINE__); + g_nv_mempool = (heap_handle_t)(&usrdata_ddblist_pool[mempool_pre_offset]); + ret_status = BT_STS_SUCCESS; + } + else + { + nvrec_trace(1,"%s,userdata invalid. ",__func__); + ret_status = nv_record_config_rebuild(); + if(ret_status != BT_STS_SUCCESS) + { + break; + } + + ret_status = BT_STS_SUCCESS; + } + break; + default: + break; + } + nvrec_init = true; + + if (ret_status == BT_STS_SUCCESS) + { +#ifdef FLASH_SUSPEND + hal_sleep_set_sleep_hook(HAL_SLEEP_HOOK_USER_NVRECORD, + nv_record_flash_flush_in_sleep); +#else + hal_sleep_set_deep_sleep_hook(HAL_DEEP_SLEEP_HOOK_USER_NVRECORD, + nv_record_flash_flush_in_sleep); +#endif + } + + int_unlock_global(lock); + nvrec_trace(2,"%s,open,ret_status=%d\n",nvrecord_tag,ret_status); + return ret_status; +} + +bt_status_t nv_record_config_rebuild(void) +{ + nvrec_mempool_init = false; + memset(usrdata_ddblist_pool,0,sizeof(usrdata_ddblist_pool)); + usrdata_ddblist_pool[pos_version_and_magic] = ((nvrecord_struct_version<<16)|nvrecord_magic); + nv_record_mempool_init(); + nv_record_config.config = nvrec_config_new("PRECIOUS 4K."); + if(nv_record_config.config == NULL) + return BT_STS_FAILED; + + nvrec_init = true; + nv_record_config.is_update = true; + return BT_STS_SUCCESS; +} + +static size_t config_entries_get_ddbrec_length(const char *secname) +{ + size_t entries_len = 0; + + if(NULL != nv_record_config.config) + { + nvrec_section_t *sec = NULL; + sec = nvrec_section_find(nv_record_config.config,secname); + if (NULL != sec) + entries_len = sec->entries->length; + } + return entries_len; +} + +#if 0 +static bool config_entries_has_ddbrec(const btif_device_record_t* param_rec) +{ + char key[BD_ADDR_SIZE+1] = {0,}; + assert(param_rec != NULL); + + memcpy(key,param_rec->bdAddr.address,BTIF_BD_ADDR_SIZE); + if(nvrec_config_has_key(nv_record_config.config,section_name_ddbrec,(const char *)key)) + return true; + return false; +} +#endif + +static void config_entries_ddbdev_delete_head(void)//delete the oldest record. +{ + list_node_t *head_node = NULL; + list_t *entry = NULL; + nvrec_section_t *sec = NULL; + + sec = nvrec_section_find(nv_record_config.config,section_name_ddbrec); + entry = sec->entries; + head_node = list_begin_ext(entry); + if(NULL != head_node) + { + btif_device_record_t *rec = NULL; + unsigned int recaddr = 0; + + nvrec_entry_t *entry_temp = list_node_ext(head_node); + recaddr = nvrec_config_get_int(nv_record_config.config,section_name_ddbrec,entry_temp->key,0); + rec = (btif_device_record_t *)recaddr; + pool_free(rec); + nvrec_entry_free(entry_temp); + if(1 == config_entries_get_ddbrec_length(section_name_ddbrec)) + entry->head = entry->tail = NULL; + else + entry->head = list_next_ext(head_node); + pool_free(head_node); + entry->length -= 1; + } +} + +static void config_entries_ddbdev_delete_tail(void) +{ + list_node_t *node = NULL; + list_node_t *temp_ptr = NULL; + list_node_t *tailnode = NULL; + size_t entrieslen = 0; + nvrec_entry_t *entry_temp = NULL; + nvrec_section_t *sec = nvrec_section_find(nv_record_config.config,section_name_ddbrec); + btif_device_record_t *recaddr = NULL; + unsigned int addr = 0; + + if (!sec) + assert(0); + sec->entries->length -= 1; + entrieslen = sec->entries->length; + node = list_begin_ext(sec->entries); + while(entrieslen > 1) + { + node = list_next_ext(node); + entrieslen--; + } + tailnode = list_next_ext(node); + entry_temp = list_node_ext(tailnode); + addr = nvrec_config_get_int(nv_record_config.config,section_name_ddbrec,entry_temp->key,0); + recaddr = (btif_device_record_t *)addr; + pool_free(recaddr); + nvrec_entry_free(entry_temp); + //pool_free(entry_temp); + temp_ptr = node->next; + node->next = NULL; + pool_free(temp_ptr); + sec->entries->tail = node; +} + +static void config_entries_ddbdev_delete(const btif_device_record_t* param_rec) +{ + nvrec_section_t *sec = NULL; + list_node_t *entry_del = NULL; + list_node_t *entry_pre = NULL; + list_node_t *entry_next = NULL; + list_node_t *node = NULL; + btif_device_record_t *recaddr = NULL; + unsigned int addr = 0; + int pos = 0,pos_pre=0; + nvrec_entry_t *entry_temp = NULL; + + sec = nvrec_section_find(nv_record_config.config,section_name_ddbrec); + for(node=list_begin_ext(sec->entries);node!=NULL;node=list_next_ext(node)) + { + nvrec_entry_t *entries = list_node_ext(node); + pos++; + if(0 == memcmp(entries->key,param_rec->bdAddr.address,BTIF_BD_ADDR_SIZE)) + { + entry_del = node; + entry_next = entry_del->next; + break; + } + } + + if (entry_del){ + /*get entry_del pre node*/ + pos_pre = (pos-1); + pos=0; + node=list_begin_ext(sec->entries); + pos++; + while(pos < pos_pre) + { + node=list_next_ext(node); + pos += 1; + } + entry_pre = node; + + /*delete entry_del following...*/ + entry_temp = list_node_ext(entry_del); + addr = nvrec_config_get_int(nv_record_config.config,section_name_ddbrec,(char *)entry_temp->key,0); + assert(0!=addr); + recaddr = (btif_device_record_t *)addr; + pool_free(recaddr); + nvrec_entry_free(entry_temp); + //pool_free(entry_temp); + pool_free(entry_pre->next); + entry_pre->next = entry_next; + sec->entries->length -= 1; + } +} + +static bool config_entries_ddbdev_is_head(const btif_device_record_t* param_rec) +{ + list_node_t *head_node = NULL; + nvrec_section_t *sec = NULL; + list_t *entry = NULL; + nvrec_entry_t *entry_temp = NULL; + + sec = nvrec_section_find(nv_record_config.config,section_name_ddbrec); + entry = sec->entries; + head_node = list_begin_ext(entry); + entry_temp = list_node_ext(head_node); + if(0 == memcmp(entry_temp->key,param_rec->bdAddr.address,BTIF_BD_ADDR_SIZE)) + return true; + return false; +} + +static bool config_entries_ddbdev_is_tail(const btif_device_record_t* param_rec) +{ + list_node_t *node = NULL; + nvrec_entry_t *entry_temp = NULL; + + nvrec_section_t *sec = nvrec_section_find(nv_record_config.config,section_name_ddbrec); + if (!sec) + assert(0); + for (node = list_begin_ext(sec->entries); node != list_end_ext(sec->entries); node = list_next_ext(node)) + { + entry_temp = list_node_ext(node); + } + if(0 == memcmp(entry_temp->key,param_rec->bdAddr.address,BTIF_BD_ADDR_SIZE)) + return true; + return false; +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +static void config_specific_entry_value_delete(const btif_device_record_t* param_rec) +{ + if(config_entries_ddbdev_is_head(param_rec)) + config_entries_ddbdev_delete_head(); + else if(config_entries_ddbdev_is_tail(param_rec)) + config_entries_ddbdev_delete_tail(); + else + config_entries_ddbdev_delete(param_rec); + nv_record_update_runtime_userdata(); +} + + +/********************************************** +gyt add:list head is the odest,list tail is the latest. +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +**********************************************/ +static bt_status_t POSSIBLY_UNUSED nv_record_ddbrec_add(const btif_device_record_t* param_rec) +{ + btdevice_volume device_vol; + btdevice_profile device_plf; + char key[BTIF_BD_ADDR_SIZE+1] = {0,}; + nvrec_btdevicerecord *nvrec_pool_record = NULL; + bool ddbrec_exist = false; + bool is_flush = true; + int getint; +#ifdef BTIF_DIP_DEVICE + uint16_t vend_id = 0; + uint16_t vend_id_source = 0; +#endif + + device_vol.a2dp_vol = NVRAM_ENV_STREAM_VOLUME_A2DP_VOL_DEFAULT; + device_vol.hfp_vol = NVRAM_ENV_STREAM_VOLUME_HFP_VOL_DEFAULT; + device_plf.hfp_act = false; + device_plf.hsp_act = false; + device_plf.a2dp_act = false; + device_plf.a2dp_codectype = 0; + if(NULL == param_rec) + return BT_STS_FAILED; + memcpy(key,param_rec->bdAddr.address,BTIF_BD_ADDR_SIZE); + + getint = nvrec_config_get_int(nv_record_config.config,section_name_ddbrec,(char *)key,0); + if(getint){ + ddbrec_exist = true; + nvrec_pool_record = (nvrec_btdevicerecord *)getint; + device_vol.a2dp_vol = nvrec_pool_record->device_vol.a2dp_vol; + device_vol.hfp_vol = nvrec_pool_record->device_vol.hfp_vol; + device_plf.hfp_act = nvrec_pool_record->device_plf.hfp_act; + device_plf.hsp_act = nvrec_pool_record->device_plf.hsp_act; + device_plf.a2dp_act = nvrec_pool_record->device_plf.a2dp_act; + device_plf.a2dp_codectype = nvrec_pool_record->device_plf.a2dp_codectype; +#ifdef BTIF_DIP_DEVICE + vend_id = nvrec_pool_record->vend_id; + vend_id_source = nvrec_pool_record->vend_id_source; +#endif + if( memcmp(&nvrec_pool_record->record.bdAddr, ¶m_rec->bdAddr,sizeof(nvrec_pool_record->record.bdAddr)) == 0 + && memcmp(nvrec_pool_record->record.linkKey, param_rec->linkKey,sizeof(nvrec_pool_record->record.linkKey)) == 0 + && nvrec_pool_record->record.trusted == param_rec->trusted + && nvrec_pool_record->record.pinLen == param_rec->pinLen + && nvrec_pool_record->record.keyType == param_rec->keyType + && config_entries_ddbdev_is_tail(param_rec) + ){ + is_flush = false; + } + } + if(is_flush){ + if (pool_free_space() < sizeof(nvrec_btdevicerecord)) + { + nvrec_trace(1,"%s,free space of nvrec is not enough!",nvrecord_tag); + config_entries_ddbdev_delete_head(); + } + nvrec_pool_record = (nvrec_btdevicerecord *)pool_malloc(sizeof(nvrec_btdevicerecord)); + if(NULL == nvrec_pool_record){ + nvrec_trace(1,"%s,pool_malloc failure.",nvrecord_tag); + return BT_STS_FAILED; + } + nvrec_trace(2,"%s,pool_malloc addr = 0x%x\n",nvrecord_tag,(unsigned int)nvrec_pool_record); + memcpy(nvrec_pool_record,param_rec,sizeof(btif_device_record_t)); +#ifdef LINK_KEY_ENCRYPT + U8 linkKey[16]; + AES128_ECB_encrypt(param_rec->linkKey, LINK_KEY_ENCRYPT_KEY, linkKey); + memcpy(nvrec_pool_record->record.linkKey, linkKey, 16); +#endif + memcpy(key,param_rec->bdAddr.address,BTIF_BD_ADDR_SIZE); + + nvrec_pool_record->device_vol.a2dp_vol = device_vol.a2dp_vol; + nvrec_pool_record->device_vol.hfp_vol = device_vol.hfp_vol; + nvrec_pool_record->device_plf.hfp_act = device_plf.hfp_act; + nvrec_pool_record->device_plf.hsp_act = device_plf.hsp_act; + nvrec_pool_record->device_plf.a2dp_act = device_plf.a2dp_act; + nvrec_pool_record->device_plf.a2dp_codectype = device_plf.a2dp_codectype; +#ifdef BTIF_DIP_DEVICE + nvrec_pool_record->vend_id = vend_id; + nvrec_pool_record->vend_id_source = vend_id_source; +#endif + + if (ddbrec_exist){ + config_specific_entry_value_delete(param_rec); + } + if(DDB_RECORD_NUM == config_entries_get_ddbrec_length(section_name_ddbrec)) { + nvrec_trace(1,"%s,ddbrec list is full,delete the oldest and add param_rec to list.",nvrecord_tag); + config_entries_ddbdev_delete_head(); + } + nvrec_config_set_int(nv_record_config.config,section_name_ddbrec,(char *)key,(int)nvrec_pool_record); +#ifdef nv_record_debug + getint = nvrec_config_get_int(nv_record_config.config,section_name_ddbrec,(char *)key,0); + nvrec_trace(2,"%s,get pool_malloc addr = 0x%x\n",nvrecord_tag,(unsigned int)getint); +#endif + nv_record_update_runtime_userdata(); + } + return BT_STS_SUCCESS; +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_add(SECTIONS_ADP_ENUM type,void *record) +{ + bt_status_t retstatus = BT_STS_FAILED; + + if ((NULL == record) || (section_none == type)) + return BT_STS_FAILED; + switch(type) + { + case section_usrdata_ddbrecord: + retstatus = nv_record_ddbrec_add(record); + break; + default: + break; + } + + return retstatus; +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_ddbrec_find(const bt_bdaddr_t* bd_ddr,btif_device_record_t *record) +{ + unsigned int getint = 0; + char key[BTIF_BD_ADDR_SIZE+1] = {0,}; + btif_device_record_t *getrecaddr = NULL; + + if((NULL == nv_record_config.config) || (NULL == bd_ddr) || (NULL == record)) + return BT_STS_FAILED; + memcpy(key,bd_ddr->address,BTIF_BD_ADDR_SIZE); + getint = nvrec_config_get_int(nv_record_config.config,section_name_ddbrec,(char *)key,0); + if(0 == getint) + return BT_STS_FAILED; + getrecaddr = (btif_device_record_t *)getint; + memcpy(record,(void *)getrecaddr,sizeof(btif_device_record_t)); +#ifdef LINK_KEY_ENCRYPT + U8 linkKey[16]; + AES128_ECB_decrypt(getrecaddr->linkKey, LINK_KEY_ENCRYPT_KEY, linkKey); + memcpy(record->linkKey, linkKey, 16); +#endif + return BT_STS_SUCCESS; +} + +int nv_record_btdevicerecord_find(const bt_bdaddr_t *bd_ddr, nvrec_btdevicerecord **record) +{ + unsigned int getint = 0; + char key[BTIF_BD_ADDR_SIZE+1] = {0,}; + + if((NULL == nv_record_config.config) || (NULL == bd_ddr) || (NULL == record)) + return -1; + memcpy(key,bd_ddr->address, BTIF_BD_ADDR_SIZE); + getint = nvrec_config_get_int(nv_record_config.config,section_name_ddbrec,(char *)key,0); + if(0 == getint) + return -1; + *record = (nvrec_btdevicerecord *)getint; + return 0; +} + +void nv_record_btdevicerecord_set_a2dp_vol(nvrec_btdevicerecord* pRecord, int8_t vol) +{ + pRecord->device_vol.a2dp_vol = vol; +} + +void nv_record_btdevicerecord_set_hfp_vol(nvrec_btdevicerecord* pRecord, int8_t vol) +{ + pRecord->device_vol.hfp_vol = vol; +} + +void nv_record_btdevicevolume_set_a2dp_vol(btdevice_volume* device_vol, int8_t vol) +{ + device_vol->a2dp_vol = vol; +} + +void nv_record_btdevicevolume_set_hfp_vol(btdevice_volume* device_vol, int8_t vol) +{ + device_vol->hfp_vol = vol; +} + +void nv_record_btdevicerecord_set_vend_id_and_source(nvrec_btdevicerecord* pRecord, int16_t vend_id, int16_t vend_id_source) +{ +#ifdef BTIF_DIP_DEVICE + if (vend_id != pRecord->vend_id) + { + pRecord->vend_id = vend_id; + pRecord->vend_id_source = vend_id_source; + } +#endif +} + +void nv_record_btdevicerecord_set_a2dp_profile_active_state(btdevice_profile* device_plf, bool isActive) +{ + device_plf->a2dp_act = isActive; +} + +void nv_record_btdevicerecord_set_hfp_profile_active_state(btdevice_profile* device_plf, bool isActive) +{ + device_plf->hfp_act = isActive; +} + +void nv_record_btdevicerecord_set_hsp_profile_active_state(btdevice_profile* device_plf, bool isActive) +{ + device_plf->hsp_act = isActive; +} + +void nv_record_btdevicerecord_set_a2dp_profile_codec(btdevice_profile* device_plf, uint8_t a2dpCodec) +{ + device_plf->a2dp_codectype = a2dpCodec; +} + +uint32_t nv_record_pre_write_operation(void) +{ + return 0; +} + +void nv_record_post_write_operation(uint32_t lock) +{ + +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_ddbrec_delete(const bt_bdaddr_t *bdaddr) +{ + unsigned int getint = 0; + btif_device_record_t *getrecaddr = NULL; + char key[BTIF_BD_ADDR_SIZE+1] = {0,}; + + memcpy(key,bdaddr->address,BTIF_BD_ADDR_SIZE); + getint = nvrec_config_get_int(nv_record_config.config,section_name_ddbrec,(char *)key,0); + if(0 == getint) + return BT_STS_FAILED; + //found ddb record,del it and return succeed. + getrecaddr = (btif_device_record_t *)getint; + config_specific_entry_value_delete((const btif_device_record_t *)getrecaddr); + return BT_STS_SUCCESS; +} + +/* +this function should be surrounded by OS_LockStack and OS_UnlockStack when call. +*/ +bt_status_t nv_record_enum_dev_records(unsigned short index,btif_device_record_t* record) +{ + nvrec_section_t *sec = NULL; + list_node_t *node = NULL; + unsigned short pos = 0; + nvrec_entry_t *entry_temp = NULL; + btif_device_record_t *recaddr = NULL; + unsigned int addr = 0; + + if((index >= DDB_RECORD_NUM) || (NULL == record) || (NULL == nv_record_config.config)) + return BT_STS_FAILED; + sec = nvrec_section_find(nv_record_config.config,section_name_ddbrec); + if(NULL == sec) + return BT_STS_INVALID_PARM; + if(NULL == sec->entries) + return BT_STS_INVALID_PARM; + if(0 == sec->entries->length) + return BT_STS_FAILED; + if(index >= sec->entries->length) + return BT_STS_FAILED; + node = list_begin_ext(sec->entries); + + while(pos < index) + { + node = list_next_ext(node); + pos++; + } + entry_temp = list_node_ext(node); + addr = nvrec_config_get_int(nv_record_config.config,section_name_ddbrec,(char *)entry_temp->key,0); + if(0 == addr) + return BT_STS_FAILED; + recaddr = (btif_device_record_t *)addr; + memcpy(record,recaddr,sizeof(btif_device_record_t)); +#ifdef LINK_KEY_ENCRYPT + U8 linkKey[16]; + AES128_ECB_decrypt(recaddr->linkKey, LINK_KEY_ENCRYPT_KEY, linkKey); + memcpy(record->linkKey, linkKey, 16); +#endif + nv_record_print_dev_record(record); + return BT_STS_SUCCESS; +} + +/* +return: + -1: enum dev failure. + 0: without paired dev. + 1: only 1 paired dev,store@record1. + 2: get 2 paired dev.notice:record1 is the latest record. +*/ +int nv_record_enum_latest_two_paired_dev(btif_device_record_t* record1,btif_device_record_t* record2) +{ + bt_status_t getret1 = BT_STS_FAILED; + bt_status_t getret2 = BT_STS_FAILED; + nvrec_section_t *sec = NULL; + size_t entries_len = 0; + list_t *entry = NULL; + + if((NULL == record1) || (NULL == record2)) + return -1; + sec = nvrec_section_find(nv_record_config.config,section_name_ddbrec); + if(NULL == sec) + return 0; + entry = sec->entries; + if(NULL == entry) + return 0; + entries_len = entry->length; + if(0 == entries_len) + return 0; + else if(entries_len < 0) + return -1; + if(1 == entries_len) + { + getret1 = nv_record_enum_dev_records(0,record1); + if(BT_STS_SUCCESS == getret1) + return 1; + return -1; + } + + getret1 = nv_record_enum_dev_records(entries_len-1,record1); + getret2 = nv_record_enum_dev_records(entries_len-2,record2); + if((BT_STS_SUCCESS != getret1) || (BT_STS_SUCCESS != getret2)) + { + memset(record1,0x0,sizeof(btif_device_record_t)); + memset(record2,0x0,sizeof(btif_device_record_t)); + return -1; + } + return 2; +} + +int nv_record_touch_cause_flush(void) +{ + nv_record_update_runtime_userdata(); + return 0; +} + +void nv_record_all_ddbrec_print(void) +{ + list_t *entry = NULL; + int tmp_i = 0; + nvrec_section_t *sec = NULL; + size_t entries_len = 0; + + sec = nvrec_section_find(nv_record_config.config,section_name_ddbrec); + if(NULL == sec) + return; + entry = sec->entries; + if(NULL == entry) + return; + entries_len = entry->length; + if(0 == entries_len) + { + nvrec_trace(1,"%s: without btdevicerec.",__func__); + return; + } + for(tmp_i=0;tmp_ientries; + if(NULL == entry) + return 0; + + return entry->length; +} + + +void nv_record_sector_clear(void) +{ + uint32_t lock; + enum NORFLASH_API_RET_T ret,ret1; + + lock = int_lock_global(); + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA, + (uint32_t)__userdata_start, + sizeof(usrdata_ddblist_pool), + false); + ret1 = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA, + (uint32_t)__userdata_start + nvrecord_mem_pool_size, + sizeof(usrdata_ddblist_pool), + false); + nvrec_init = false; + nvrec_mempool_init = false; + int_unlock_global(lock); + ASSERT(ret == NORFLASH_API_OK,"nv_record_sector_clear: erase main sector failed! ret = %d.",ret); + ASSERT(ret1 == NORFLASH_API_OK,"nv_record_sector_clear: erase bak sector failed! ret1 = %d.",ret1); +} + +#define DISABLE_NV_RECORD_CRC_CHECK_BEFORE_FLUSH 1 +void nv_record_update_runtime_userdata(void) +{ + uint32_t lock; + + if (NULL == nv_record_config.config) + { + return; + } + lock = int_lock(); + nv_record_config.is_update = true; + +#if !DISABLE_NV_RECORD_CRC_CHECK_BEFORE_FLUSH + buffer_alloc_ctx* heapctx = memory_buffer_heap_getaddr(); + memcpy((void *)(&usrdata_ddblist_pool[pos_heap_contents]),heapctx,sizeof(buffer_alloc_ctx)); + uint32_t crc = crc32(0,(uint8_t *)(&usrdata_ddblist_pool[pos_heap_contents]),(sizeof(usrdata_ddblist_pool)-(pos_heap_contents*sizeof(uint32_t)))); + + usrdata_ddblist_pool[pos_crc] = crc; +#endif + + int_unlock(lock); +} + + +static int nv_record_flash_flush_main(bool is_async) +{ + uint32_t crc; + uint32_t lock; + enum NORFLASH_API_RET_T ret = NORFLASH_API_OK; + uint8_t *burn_buf = NULL; + uint32_t verandmagic; + + if(NULL == nv_record_config.config) + { + nvrec_trace(1,"%s,nv_record_config.config is null.\n", __func__); + goto _func_end; + } + + burn_buf = (uint8_t *)&usrdata_ddblist_pool[0]; + verandmagic = usrdata_ddblist_pool[0]; + ASSERT((((nvrecord_struct_version<<16)|nvrecord_magic) == verandmagic), + "%s: verandmagic = 0x%08x.", __func__, verandmagic); + + if(is_async) + { + hal_trace_pause(); + lock = int_lock_global(); + if(nv_record_config.state == NV_STATE_IDLE + || nv_record_config.state == NV_STATE_MAIN_ERASING) + { + if(nv_record_config.state == NV_STATE_IDLE) + { + nv_record_config.state = NV_STATE_MAIN_ERASING; + // nvrec_trace(1,"%s: NV_STATE_MAIN_ERASING", __func__); + } + + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA, + _user_data_main_start, + sizeof(usrdata_ddblist_pool), + true); + if(ret == NORFLASH_API_OK) + { + nv_record_config.state = NV_STATE_MAIN_ERASED; + // nvrec_trace(1,"%s: NV_STATE_MAIN_ERASED", __func__); + nvrec_trace(2,"%s: norflash_api_erase ok,addr = 0x%x.",__func__,_user_data_main_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + norflash_api_flush(); + } + else + { + ASSERT(0,"%s: norflash_api_erase err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_main_start); + } + } + else if(nv_record_config.state == NV_STATE_MAIN_ERASED + || nv_record_config.state == NV_STATE_MAIN_WRITTING) + { + if(nv_record_config.state == NV_STATE_MAIN_ERASED) + { + nv_record_config.state = NV_STATE_MAIN_WRITTING; + // nvrec_trace(1,"%s: NV_STATE_MAIN_WRITTING", __func__); + } + crc = crc32(0,(uint8_t *)(&usrdata_ddblist_pool[pos_heap_contents]),(sizeof(usrdata_ddblist_pool)-(pos_heap_contents*sizeof(uint32_t)))); + //nvrec_trace(2,"%s,crc=%x.\n",nvrecord_tag,crc); + usrdata_ddblist_pool[pos_version_and_magic] = ((nvrecord_struct_version<<16)|nvrecord_magic); + usrdata_ddblist_pool[pos_crc] = crc; + usrdata_ddblist_pool[pos_start_ram_addr] = (uint32_t)&usrdata_ddblist_pool; + usrdata_ddblist_pool[pos_reserv2] = 0; + usrdata_ddblist_pool[pos_config_addr] = (uint32_t)nv_record_config.config; + ASSERT(nv_record_list_is_valid(),"%s nv_record_list is invalid!",__func__); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_USERDATA, + _user_data_main_start, + burn_buf, + sizeof(usrdata_ddblist_pool), + true + ); + if(ret == NORFLASH_API_OK) + { + nv_record_config.is_update = false; + nv_record_config.state = NV_STATE_MAIN_WRITTEN; + // nvrec_trace(1,"%s: NV_STATE_MAIN_WRITTEN", __func__); + nvrec_trace(2,"%s: norflash_api_write ok,addr = 0x%x.",__func__,_user_data_main_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + norflash_api_flush(); + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_main_start); + } + } + else + { + if(norflash_api_get_used_buffer_count(NORFLASH_API_MODULE_ID_USERDATA,NORFLASH_API_ALL) == 0) + { + nv_record_config.state = NV_STATE_MAIN_DONE; + // nvrec_trace(1,"%s: NV_STATE_MAIN_DONE", __func__); + } + else + { + norflash_api_flush(); + } + } + int_unlock_global(lock); + hal_trace_continue(); + } + else + { + // nvrec_trace(1,"%s: sync flush begin!", __func__); + if(nv_record_config.state == NV_STATE_IDLE + || nv_record_config.state == NV_STATE_MAIN_ERASING) + { + do + { + hal_trace_pause(); + lock = int_lock_global(); + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA, + _user_data_main_start, + sizeof(usrdata_ddblist_pool), + true); + int_unlock_global(lock); + hal_trace_continue(); + if(ret == NORFLASH_API_OK) + { + nv_record_config.state = NV_STATE_MAIN_ERASED; + nvrec_trace(2,"%s: norflash_api_erase ok,addr = 0x%x.",__func__, _user_data_main_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_ERASING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_erase err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_main_start); + } + + }while(ret == NORFLASH_API_BUFFER_FULL); + } + + if(nv_record_config.state == NV_STATE_MAIN_ERASED) + { + do + { + hal_trace_pause(); + lock = int_lock_global(); + crc = crc32(0,(uint8_t *)(&usrdata_ddblist_pool[pos_heap_contents]),(sizeof(usrdata_ddblist_pool)-(pos_heap_contents*sizeof(uint32_t)))); + //nvrec_trace(2,"%s,crc=%x.\n",nvrecord_tag,crc); + usrdata_ddblist_pool[pos_version_and_magic] = ((nvrecord_struct_version<<16)|nvrecord_magic); + usrdata_ddblist_pool[pos_crc] = crc; + usrdata_ddblist_pool[pos_start_ram_addr] = (uint32_t)&usrdata_ddblist_pool; + usrdata_ddblist_pool[pos_reserv2] = 0; + usrdata_ddblist_pool[pos_config_addr] = (uint32_t)nv_record_config.config; + ASSERT(nv_record_list_is_valid(),"%s nv_record_list is invalid!",__func__); + ret = norflash_api_write(NORFLASH_API_MODULE_ID_USERDATA, + _user_data_main_start, + burn_buf, + sizeof(usrdata_ddblist_pool), + true + ); + int_unlock_global(lock); + hal_trace_continue(); + if(ret == NORFLASH_API_OK) + { + nv_record_config.is_update = false; + nv_record_config.state = NV_STATE_MAIN_WRITTEN; + nvrec_trace(2,"%s: norflash_api_write ok,addr = 0x%x.",__func__,_user_data_main_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_WRITTING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_main_start); + } + }while(ret == NORFLASH_API_BUFFER_FULL); + + do + { + norflash_api_flush(); + }while(norflash_api_get_used_buffer_count(NORFLASH_API_MODULE_ID_USERDATA,NORFLASH_API_ALL) > 0); + + nv_record_config.state = NV_STATE_MAIN_DONE; + nvrec_trace(1,"%s: sync flush done.", __func__); + } +#if 0 //#ifdef nv_record_debug + if (ret == NORFLASH_API_OK) + { + uint32_t recrc; + uint32_t crc; + uint8_t* burn_buf; + + uint8_t* read_buffer = (uint8_t*)__userdata_start; + + burn_buf = (uint8_t *)&usrdata_ddblist_pool[0]; + crc = ((uint32_t *)burn_buf)[pos_crc]; + recrc = crc32(0,((uint8_t *)read_buffer + sizeof(uint32_t)*pos_heap_contents),(sizeof(usrdata_ddblist_pool)-(pos_heap_contents*sizeof(uint32_t)))); + ASSERT(crc == recrc,"%s, 0x%x,recrc=%08x crc=%08x\n", + __func__,_user_data_main_start,recrc,crc); + TRACE(1,"%s crc ok.",__func__); + } +#endif + + } +_func_end: + return (ret == NORFLASH_API_OK) ? 0:1; +} + +static int nv_record_flash_flush_bak(bool is_async) +{ + uint32_t lock; + enum NORFLASH_API_RET_T ret = NORFLASH_API_OK; + uint8_t burn_buf[128]; + + if(is_async) + { + hal_trace_pause(); + lock = int_lock_global(); + if(nv_record_config.state == NV_STATE_MAIN_DONE + || nv_record_config.state == NV_STATE_BAK_ERASING) + { + if(nv_record_config.state == NV_STATE_MAIN_DONE) + { + nv_record_config.state = NV_STATE_BAK_ERASING; + // nvrec_trace(1,"%s: NV_STATE_BAK_ERASING", __func__); + } + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA, + _user_data_bak_start, + sizeof(usrdata_ddblist_pool), + true); + if(ret == NORFLASH_API_OK) + { + nv_record_config.state = NV_STATE_BAK_ERASED; + nvrec_trace(2,"%s: norflash_api_erase ok,addr = 0x%x.", + __func__,_user_data_bak_start); + // nvrec_trace(1,"%s: NV_STATE_BAK_ERASED", __func__); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + norflash_api_flush(); + } + else + { + ASSERT(0,"%s: norflash_api_erase err,ret = %d,addr = 0x%x.", + __func__,ret,_user_data_bak_start); + } + } + else if(nv_record_config.state == NV_STATE_BAK_ERASED + || nv_record_config.state == NV_STATE_BAK_WRITTING) + { + if(nv_record_config.state == NV_STATE_BAK_ERASED) + { + nv_record_config.state = NV_STATE_BAK_WRITTING; + nv_record_config.written_size = 0; + // nvrec_trace(1,"%s: NV_STATE_BAK_WRITTING", __func__); + } + do + { + ret = norflash_api_read(NORFLASH_API_MODULE_ID_USERDATA, + _user_data_main_start + nv_record_config.written_size, + burn_buf, + sizeof(burn_buf) + ); + ASSERT(ret == NORFLASH_API_OK,"norflash_api_read failed! ret = %d, addr = 0x%x.", + (int32_t)ret,_user_data_main_start + nv_record_config.written_size); + + ret = norflash_api_write(NORFLASH_API_MODULE_ID_USERDATA, + _user_data_bak_start + nv_record_config.written_size, + burn_buf, + sizeof(burn_buf), + true + ); + if(ret == NORFLASH_API_OK) + { + nv_record_config.written_size += sizeof(burn_buf); + + if(nv_record_config.written_size == nvrecord_mem_pool_size) + { + nv_record_config.state = NV_STATE_BAK_WRITTEN; + // nvrec_trace(1,"%s: NV_STATE_BAK_WRITTEN", __func__); + break; + } + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + norflash_api_flush(); + break; + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.", + __func__,ret,_user_data_bak_start + nv_record_config.written_size); + } + }while(1); + } + else + { + if(norflash_api_get_used_buffer_count(NORFLASH_API_MODULE_ID_USERDATA,NORFLASH_API_ALL) == 0) + { + // nvrec_trace(1,"%s: NV_STATE_BAK_DONE", __func__); + nv_record_config.state = NV_STATE_BAK_DONE; + } + else + { + norflash_api_flush(); + } + } + + int_unlock_global(lock); + hal_trace_continue(); + } + else + { + // nvrec_trace(1,"%s: sync flush begin.", __func__); + if(nv_record_config.state == NV_STATE_MAIN_DONE + || nv_record_config.state == NV_STATE_BAK_ERASING) + { + do + { + hal_trace_pause(); + lock = int_lock_global(); + ret = norflash_api_erase(NORFLASH_API_MODULE_ID_USERDATA, + _user_data_bak_start, + sizeof(usrdata_ddblist_pool), + true); + int_unlock_global(lock); + hal_trace_continue(); + if(ret == NORFLASH_API_OK) + { + nv_record_config.state = NV_STATE_BAK_ERASED; + nvrec_trace(2,"%s: norflash_api_erase ok,addr = 0x%x.", + __func__, _user_data_bak_start); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_ERASING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_erase err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_bak_start); + } + }while(ret == NORFLASH_API_BUFFER_FULL); + } + + if(nv_record_config.state == NV_STATE_BAK_ERASED) + { + nv_record_config.state = NV_STATE_BAK_WRITTING; + nv_record_config.written_size = 0; + do + { + hal_trace_pause(); + do + { + lock = int_lock_global(); + ret = norflash_api_read(NORFLASH_API_MODULE_ID_USERDATA, + _user_data_main_start + nv_record_config.written_size, + burn_buf, + sizeof(burn_buf) + ); + ASSERT(ret == NORFLASH_API_OK,"norflash_api_read failed! ret = %d, addr = 0x%x.", + (int32_t)ret, _user_data_main_start + nv_record_config.written_size); + + ret = norflash_api_write(NORFLASH_API_MODULE_ID_USERDATA, + _user_data_bak_start + nv_record_config.written_size, + burn_buf, + sizeof(burn_buf), + true + ); + int_unlock_global(lock); + if(ret == NORFLASH_API_OK) + { + nv_record_config.written_size += sizeof(burn_buf); + if(nv_record_config.written_size == nvrecord_mem_pool_size) + { + nv_record_config.state = NV_STATE_BAK_WRITTEN; + break; + } + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + nv_record_config.state = NV_STATE_BAK_WRITTING; + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_WRITTING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.", + __func__,ret,_user_data_bak_start + nv_record_config.written_size); + } + }while(1); + + hal_trace_continue(); + + if(ret == NORFLASH_API_OK) + { + nv_record_config.state = NV_STATE_BAK_WRITTEN; + nvrec_trace(3,"%s: norflash_api_write ok,addr = 0x%x,len = 0x%x.", + __func__,_user_data_bak_start,nv_record_config.written_size); + } + else if(ret == NORFLASH_API_BUFFER_FULL) + { + do + { + norflash_api_flush(); + }while(norflash_api_get_free_buffer_count(NORFLASH_API_WRITTING) == 0); + } + else + { + ASSERT(0,"%s: norflash_api_write err,ret = %d,addr = 0x%x.",__func__,ret,_user_data_bak_start); + } + }while(ret == NORFLASH_API_BUFFER_FULL); + + do + { + norflash_api_flush(); + }while(norflash_api_get_used_buffer_count(NORFLASH_API_MODULE_ID_USERDATA,NORFLASH_API_ALL) > 0); + nv_record_config.state = NV_STATE_BAK_DONE; + nvrec_trace(1,"%s: sync flush done.", __func__); + } + } + + if(nv_record_config.state == NV_STATE_BAK_DONE) + { + nv_record_config.state = NV_STATE_IDLE; + // nvrec_trace(1,"%s: NV_STATE_IDLE", __func__); + } + + return (ret == NORFLASH_API_OK) ? 0:1; +} + + +static int nv_record_flash_flush_int(bool is_async) +{ + int ret = 0; + do{ + if((nv_record_config.state == NV_STATE_IDLE + && nv_record_config.is_update == TRUE) + || nv_record_config.state == NV_STATE_MAIN_ERASING + || nv_record_config.state == NV_STATE_MAIN_ERASED + || nv_record_config.state == NV_STATE_MAIN_WRITTING + || nv_record_config.state == NV_STATE_MAIN_WRITTEN + ) + { + ret = nv_record_flash_flush_main(is_async); + if(is_async) + { + break; + } + } + + if(nv_record_config.state == NV_STATE_MAIN_DONE + || nv_record_config.state == NV_STATE_BAK_ERASING + || nv_record_config.state == NV_STATE_BAK_ERASED + || nv_record_config.state == NV_STATE_BAK_WRITTING + || nv_record_config.state == NV_STATE_BAK_WRITTEN + || nv_record_config.state == NV_STATE_BAK_DONE + ) + { + ret = nv_record_flash_flush_bak(is_async); + } + }while(0); + return ret; +} + +void nv_record_flash_flush(void) +{ + nv_record_flash_flush_int(false); +} + +int nv_record_flash_flush_in_sleep(void) +{ + nv_record_flash_flush_int(true); + return 0; +} + +void nv_callback(void* param) +{ + NORFLASH_API_OPERA_RESULT *opera_result; + //uint8_t *burn_buf; + + opera_result = (NORFLASH_API_OPERA_RESULT*)param; + + nvrec_trace(6,"%s:type = %d, addr = 0x%x,len = 0x%x,remain = %d,result = %d.", + __func__, + opera_result->type, + opera_result->addr, + opera_result->len, + opera_result->remain_num, + opera_result->result); + +#ifdef nv_record_debug + if (opera_result->result == NORFLASH_API_OK){ + if(opera_result->remain_num == 0 && + opera_result->type == NORFLASH_API_WRITTING) { + uint32_t recrc; + uint32_t crc; + uint8_t* read_buffer = (uint8_t*)opera_result->addr; + + crc = ((uint32_t *)read_buffer)[pos_crc]; + recrc = crc32(0, + ((uint8_t *)read_buffer + sizeof(uint32_t)*pos_heap_contents), + (sizeof(usrdata_ddblist_pool)-(pos_heap_contents*sizeof(uint32_t)))); + ASSERT(crc == recrc,"%s:addr=0x%x,recrc=0x%x crc=0x%x.", + __func__,opera_result->addr,recrc,crc); + } + } + else{ + ASSERT(0,"%s:flash write fail!addr=0x%x,result = %d.", + __func__,opera_result->addr,opera_result->result); + } +#endif + +} + +#ifdef NVREC_BAIDU_DATA_SECTION +#define BAIDU_DATA_FM_SPEC_VALUE (0xffee) +int nvrec_baidu_data_init(void) +{ + int _fmfreq = 0; + if (!nvrec_config_has_section(nv_record_config.config, BAIDU_DATA_SECTIN)) { + nvrec_trace(0,"no baidu section default, new one!"); + nvrec_config_set_int(nv_record_config.config, BAIDU_DATA_SECTIN, BAIDU_DATA_FM_KEY, BAIDU_DATA_DEF_FM_FREQ); + } + else { + nvrec_trace(1,"has baidu section, fmfreq is %d", nvrec_config_get_int(nv_record_config.config, BAIDU_DATA_SECTIN, BAIDU_DATA_FM_KEY, BAIDU_DATA_FM_SPEC_VALUE)); + _fmfreq = nvrec_config_get_int(nv_record_config.config, BAIDU_DATA_SECTIN, BAIDU_DATA_FM_KEY, BAIDU_DATA_FM_SPEC_VALUE); + if (_fmfreq == BAIDU_DATA_FM_SPEC_VALUE) { + nvrec_trace(1,"fm bas bad value, set to %d", BAIDU_DATA_DEF_FM_FREQ); + nvrec_config_set_int(nv_record_config.config, BAIDU_DATA_SECTIN, BAIDU_DATA_FM_KEY, BAIDU_DATA_DEF_FM_FREQ); + _fmfreq = nvrec_config_get_int(nv_record_config.config, BAIDU_DATA_SECTIN, BAIDU_DATA_FM_KEY, BAIDU_DATA_FM_SPEC_VALUE); + if (_fmfreq == BAIDU_DATA_FM_SPEC_VALUE) { + nvrec_trace(0,"get fm freq still fail!!!"); + ASSERT(0, "nvrecord fail, system down!"); + } + } + } + + return 0; +} + +int nvrec_get_fm_freq(void) +{ + int _fmfreq = 0; + _fmfreq = nvrec_config_get_int(nv_record_config.config, BAIDU_DATA_SECTIN, BAIDU_DATA_FM_KEY, BAIDU_DATA_FM_SPEC_VALUE); + if (_fmfreq == BAIDU_DATA_FM_SPEC_VALUE) { + nvrec_trace(1,"%s : get fm freq fail, reinit fmfreq data", __func__); + nvrec_baidu_data_init(); + } + _fmfreq = nvrec_config_get_int(nv_record_config.config, BAIDU_DATA_SECTIN, BAIDU_DATA_FM_KEY, BAIDU_DATA_FM_SPEC_VALUE); + if (_fmfreq == BAIDU_DATA_FM_SPEC_VALUE) { + nvrec_trace(1,"%s : get fm freq still fail", __func__); + ASSERT(0, "%s : nvrecord fail, system down!", __func__); + } + + nvrec_trace(2,"%s:get fm freq %d", __func__, _fmfreq); + return _fmfreq; +} + +int nvrec_set_fm_freq(int fmfreq) +{ + int t = hal_sys_timer_get(); + nvrec_trace(2,"%s:fmfreq %d", __func__, fmfreq); + nvrec_config_set_int(nv_record_config.config, BAIDU_DATA_SECTIN, BAIDU_DATA_FM_KEY, fmfreq); + nvrec_trace(2,"%s: use %d ms", __func__, TICKS_TO_MS(hal_sys_timer_get()-t)); + nv_record_config.is_update = true; + +#if defined(NVREC_BAIDU_DATA_FLUSH_DIRECT) + nv_record_flash_flush_int(false); +#endif + nvrec_trace(2,"%s: use %d ms", __func__, TICKS_TO_MS(hal_sys_timer_get()-t)); + + return 0; +} + +int nvrec_get_rand(char *rand) +{ + char * _rand = 0; + + if (rand == NULL) + return 1; + +#if 0 + _rand = nvrec_config_get_string(nv_record_config.config, BAIDU_DATA_SECTIN, BAIDU_DATA_RAND_KEY, BAIDU_DATA_DEF_RAND); + if (strcmp(_rand, BAIDU_DATA_DEF_RAND)==0 || _rand == NULL) { + TRACE(1,"%s : get rand fail!", __func__); + return 1; + } +#else + _rand = BAIDU_DATA_DEF_RAND; +#endif + + memcpy(rand, _rand, BAIDU_DATA_RAND_LEN); + + nvrec_trace(2,"%s:rand %s", __func__, rand); + + return 0; +} + +int nvrec_set_rand(char *rand) +{ + int t = hal_sys_timer_get(); + if (rand != NULL) + nvrec_trace(2,"%s:rand %s", __func__, rand); + else + nvrec_trace(1,"%s:rand nul", __func__); + nvrec_config_set_string(nv_record_config.config, BAIDU_DATA_SECTIN, BAIDU_DATA_RAND_KEY, rand); + nvrec_trace(2,"%s: use %d ms", __func__, TICKS_TO_MS(hal_sys_timer_get()-t)); + nv_record_config.is_update = true; + +#if defined(NVREC_BAIDU_DATA_FLUSH_DIRECT) + nv_record_flash_flush_int(false); +#endif + nvrec_trace(2,"%s: use %d ms", __func__, TICKS_TO_MS(hal_sys_timer_get()-t)); + + return 0; +} + +int nvrec_clear_rand(void) +{ + nvrec_set_rand(NULL); + return 0; +} + +int nvrec_dev_get_sn(char *sn) +{ + unsigned int sn_addr; + if (NVREC_DEV_VERSION_1 == nv_record_dev_rev) + { + return -1; + } + else + { + sn_addr = (unsigned int)(__factory_start + rev2_dev_prod_sn); + } + + if(false == dev_sector_valid) + return -1; + if (NULL == sn) + return -1; + + memcpy((void *)sn, (void *)sn_addr, BAIDU_DATA_SN_LEN); + + return 0; +} +#endif + +#endif // !defined(NEW_NV_RECORD_ENABLED) + +bool nvrec_dev_data_open(void) +{ + uint32_t dev_zone_crc,dev_zone_flsh_crc; + uint32_t vermagic; + + vermagic = __factory_start[dev_version_and_magic]; + nvrec_trace(2,"%s,vermagic=0x%x",__func__,vermagic); + if ((nvrec_dev_magic != (vermagic&0xFFFF)) || + ((vermagic >> 16) > NVREC_DEV_NEWEST_REV)) + { + dev_sector_valid = false; + nvrec_trace(1,"%s,dev sector invalid.",__func__); + return dev_sector_valid; + } + + // following the nv rec version number programmed by the downloader tool, + // to be backward compatible + nv_record_dev_rev = vermagic >> 16; + nvrec_trace(1,"Nv record dev version %d", nv_record_dev_rev); + + if (NVREC_DEV_VERSION_1 == nv_record_dev_rev) + { + dev_zone_flsh_crc = __factory_start[dev_crc]; + dev_zone_crc = crc32(0,(uint8_t *)(&__factory_start[dev_reserv1]),(dev_data_len-dev_reserv1)*sizeof(uint32_t)); + } + else + { + // check the data length + if ((rev2_dev_section_start_reserved*sizeof(uint32_t)) + __factory_start[rev2_dev_data_len] + > 4096) + { + nvrec_trace(1,"nv rec dev data len %d has exceeds the facory sector size!.", + __factory_start[rev2_dev_data_len]); + dev_sector_valid = false; + return false; + } + + // assure that in future, if the nv dev data structure is extended, the former tool + // and former bin can still be workable + dev_zone_flsh_crc = __factory_start[rev2_dev_crc]; + dev_zone_crc = crc32(0,(uint8_t *)(&__factory_start[rev2_dev_section_start_reserved]), + __factory_start[rev2_dev_data_len]); + } + + nvrec_trace(4,"%s: data len 0x%x,dev_zone_flsh_crc=0x%x,dev_zone_crc=0x%x",__func__, + __factory_start[rev2_dev_data_len],dev_zone_flsh_crc,dev_zone_crc); + if (dev_zone_flsh_crc == dev_zone_crc) + { + dev_sector_valid = true; + } + + if (dev_sector_valid) + { + nvrec_trace(1,"%s: nv rec dev is valid.", __func__); + } + else + { + nvrec_trace(1,"%s: nv rec dev is invalid.", __func__); + } + return dev_sector_valid; +} + +bool nvrec_dev_localname_addr_init(dev_addr_name *dev) +{ + uint32_t *p_devdata_cache = __factory_start; + size_t name_len = 0; + if(true == dev_sector_valid) + { + nvrec_trace(1,"%s: nv dev data valid", __func__); + if (NVREC_DEV_VERSION_1 == nv_record_dev_rev) + { + memcpy((void *) dev->btd_addr,(void *)&p_devdata_cache[dev_bt_addr],BTIF_BD_ADDR_SIZE); + memcpy((void *) dev->ble_addr,(void *)&p_devdata_cache[dev_ble_addr],BTIF_BD_ADDR_SIZE); + dev->localname = (char *)&p_devdata_cache[dev_name]; + } + else + { + memcpy((void *) dev->btd_addr,(void *)&p_devdata_cache[rev2_dev_bt_addr],BTIF_BD_ADDR_SIZE); + memcpy((void *) dev->ble_addr,(void *)&p_devdata_cache[rev2_dev_ble_addr],BTIF_BD_ADDR_SIZE); + dev->localname = (char *)&p_devdata_cache[rev2_dev_name]; + dev->ble_name = (char *)&p_devdata_cache[rev2_dev_ble_name]; + } + + if (strlen(dev->localname) < CLASSIC_BTNAME_LEN) { + name_len = strlen(dev->localname); + } + else { + name_len = CLASSIC_BTNAME_LEN - 1; + } + memcpy(classics_bt_name,dev->localname,name_len); + classics_bt_name[name_len] = '\0'; + bt_set_local_name(classics_bt_name); + bt_set_local_address(dev->btd_addr); + } + else + { + nvrec_trace(1,"%s: nv dev data invalid", __func__); + } + + nvrec_trace(0,"BT addr is:"); + DUMP8("%02x ", dev->btd_addr, BTIF_BD_ADDR_SIZE); + nvrec_trace(0,"BLE addr is:"); + DUMP8("%02x ", dev->ble_addr, BTIF_BD_ADDR_SIZE); + nvrec_trace(2,"localname=%s, namelen=%d", dev->localname, strlen(dev->localname)); + if (dev->ble_name) + nvrec_trace(2,"blename=%s, namelen=%d", dev->ble_name, strlen(dev->ble_name)); + + return dev_sector_valid; +} + +int nvrec_dev_force_get_btaddress(unsigned char *btd_addr) +{ + uint32_t *p_devdata_cache = __factory_start; + memcpy((void *) btd_addr,(void *)&p_devdata_cache[dev_bt_addr],BTIF_BD_ADDR_SIZE); + return 0; +} +static void nvrec_dev_data_fill_xtal_fcap(uint32_t *mem_pool,uint32_t val) +{ + uint8_t *btaddr = NULL; + uint8_t *bleaddr = NULL; + + assert(0 != mem_pool); + if (!dev_sector_valid) + { + mem_pool[dev_version_and_magic] = ((nv_record_dev_rev<<16)|nvrec_dev_magic); + } + + if (NVREC_DEV_VERSION_1 == nv_record_dev_rev) + { + if(dev_sector_valid) + { + memcpy((void *)mem_pool,(void *)__factory_start,0x1000); + mem_pool[dev_xtal_fcap] = val; + mem_pool[dev_crc] = crc32(0,(uint8_t *)(&mem_pool[dev_reserv1]),(dev_data_len-dev_reserv1)*sizeof(uint32_t)); + } + else + { + const char *localname = bt_get_local_name(); + unsigned int namelen = strlen(localname); + + btaddr = bt_get_local_address(); + bleaddr = bt_get_ble_local_address(); + + mem_pool[dev_reserv1] = 0; + mem_pool[dev_reserv2] = 0; + memcpy((void *)&mem_pool[dev_name],(void *)localname,(size_t)namelen); + nvrec_dev_rand_btaddr_gen(btaddr); + nvrec_dev_rand_btaddr_gen(bleaddr); + memcpy((void *)&mem_pool[dev_bt_addr],(void *)btaddr,BTIF_BD_ADDR_SIZE); + memcpy((void *)&mem_pool[dev_ble_addr],(void *)bleaddr,BTIF_BD_ADDR_SIZE); + memset((void *)&mem_pool[dev_dongle_addr],0x0,BTIF_BD_ADDR_SIZE); + mem_pool[dev_xtal_fcap] = val; + mem_pool[dev_crc] = crc32(0,(uint8_t *)(&mem_pool[dev_reserv1]),(dev_data_len-dev_reserv1)*sizeof(uint32_t)); + nvrec_trace(2,"%s: mem_pool[dev_crc]=%x.\n",__func__,mem_pool[dev_crc]); + } + } + else + { + if(dev_sector_valid) + { + memcpy((void *)mem_pool,(void *)__factory_start,0x1000); + mem_pool[rev2_dev_xtal_fcap] = val; + mem_pool[rev2_dev_crc] = crc32(0, + (uint8_t *)(&mem_pool[rev2_dev_section_start_reserved]),mem_pool[rev2_dev_data_len]); + } + else + { + const char *localname = bt_get_local_name(); + unsigned int namelen = strlen(localname); + + btaddr = bt_get_local_address(); + bleaddr = bt_get_ble_local_address(); + mem_pool[rev2_dev_section_start_reserved] = 0; + mem_pool[rev2_dev_reserv2] = 0; + memcpy((void *)&mem_pool[rev2_dev_name],(void *)localname,(size_t)namelen); + memcpy((void *)&mem_pool[rev2_dev_ble_name], (void *)bt_get_ble_local_name(), BLE_NAME_LEN_IN_NV); + nvrec_dev_rand_btaddr_gen(btaddr); + nvrec_dev_rand_btaddr_gen(bleaddr); + memcpy((void *)&mem_pool[rev2_dev_bt_addr],(void *)btaddr,BTIF_BD_ADDR_SIZE); + memcpy((void *)&mem_pool[rev2_dev_ble_addr],(void *)bleaddr,BTIF_BD_ADDR_SIZE); + memset((void *)&mem_pool[rev2_dev_dongle_addr],0x0,BTIF_BD_ADDR_SIZE); + mem_pool[rev2_dev_xtal_fcap] = val; + mem_pool[rev2_dev_data_len] = (rev2_dev_section_end-rev2_dev_section_start_reserved)*sizeof(uint32_t); + mem_pool[rev2_dev_crc] = crc32(0, + (uint8_t *)(&mem_pool[rev2_dev_section_start_reserved]), + mem_pool[rev2_dev_data_len]); + nvrec_trace(2,"%s: mem_pool[rev2_dev_crc] = 0x%x.\n", + __func__,mem_pool[rev2_dev_crc]); + } + } +} + +void nvrec_dev_flash_flush(unsigned char *mempool) +{ + uint32_t lock; +#ifdef nv_record_debug + uint32_t devdata[dev_data_len] = {0,}; + uint32_t recrc; +#endif + + if(NULL == mempool) + return; + lock = int_lock_global(); + pmu_flash_write_config(); + + hal_norflash_erase(HAL_NORFLASH_ID_0,(uint32_t)NVRECORD_CACHE_2_UNCACHE(__factory_start),0x1000); + hal_norflash_write(HAL_NORFLASH_ID_0,(uint32_t)NVRECORD_CACHE_2_UNCACHE(__factory_start),(uint8_t *)mempool,0x1000);//dev_data_len*sizeof(uint32_t)); + + pmu_flash_read_config(); + int_unlock_global(lock); + +#ifdef nv_record_debug + if (NVREC_DEV_VERSION_1 == nv_record_dev_rev) + { + memset(devdata,0x0,dev_data_len*sizeof(uint32_t)); + memcpy(devdata,__factory_start,dev_data_len*sizeof(uint32_t)); + recrc = crc32(0,(uint8_t *)(&devdata[dev_reserv1]),(dev_data_len-dev_reserv1)*sizeof(uint32_t)); + nvrec_trace(3,"%s: devdata[dev_crc]=%x.recrc=%x\n", __func__,devdata[dev_crc],recrc); + if(devdata[dev_crc] != recrc) + assert(0); + } +#endif +} + +void nvrec_dev_rand_btaddr_gen(uint8_t* bdaddr) +{ + unsigned int seed; + int i; + + OS_DUMP8("%x ",bdaddr,6); + seed = hal_sys_timer_get(); + for(i=0;i +#include +#include "cmsis.h" +#include "nvrec_config.h" +#include "bluetooth.h" +#include "me_api.h" +#include "hal_trace.h" +#if defined(NEW_NV_RECORD_ENABLED) +#include "nvrecord_extension.h" +#include "nvrecord_bt.h" +#include "nvrecord_env.h" +#include "nvrecord_ble.h" +#include "nvrecord_dma_config.h" +#include "nvrecord_fp_account_key.h" +#include "btif_sys_config.h" + +#define nvdev_tag "nvdev_tag" + +#else + +#define DDB_RECORD_NUM 9 +#define section_name_ddbrec "ddbrec" +#define nvrecord_mem_pool_size 4096 +#define nvrecord_tag "nvrecord" +#define nvdev_tag "nvdev_tag" +#define section_name_other "other" + + +/* + version|magic 16bit|16bit 0001 cb91 + crc 32bit + reserve[0] 32bit + reserve[1] 32bit + config_addr 32bit + heap_contents 32bit + mempool ... +*/ +#define nvrecord_struct_version 8 +#define nvrecord_magic 0xcb91 + +typedef enum +{ + pos_version_and_magic,// 0 + pos_crc, // 1 + pos_start_ram_addr, // 2 + pos_reserv2, // 3 + pos_config_addr, // 4 + pos_heap_contents, // 5 + +}nvrec_mempool_pre_enum; + +#define mempool_pre_offset (1+pos_config_addr+((sizeof(heap_handle_t)/sizeof(uint32_t))+1)) + +typedef enum +{ + NV_STATE_IDLE, + NV_STATE_MAIN_ERASING, + NV_STATE_MAIN_ERASED, + NV_STATE_MAIN_WRITTING, + NV_STATE_MAIN_WRITTEN, + NV_STATE_MAIN_DONE, + NV_STATE_BAK_ERASING, + NV_STATE_BAK_ERASED, + NV_STATE_BAK_WRITTING, + NV_STATE_BAK_WRITTEN, + NV_STATE_BAK_DONE, +}NV_STATE; + +typedef struct +{ + bool is_update; + NV_STATE state; + uint32_t written_size; + nvrec_config_t *config; +}nv_record_struct; + +typedef enum +{ + section_usrdata_ddbrecord, + section_none +}SECTIONS_ADP_ENUM; + +typedef struct btdevice_volume{ + int8_t a2dp_vol; + int8_t hfp_vol; +}btdevice_volume; + +typedef struct btdevice_profile{ + bool hfp_act; + bool hsp_act; + bool a2dp_act; + uint8_t a2dp_codectype; +}btdevice_profile; + +typedef struct _nvrec_btdevicerecord +{ + btif_device_record_t record; + btdevice_volume device_vol; + btdevice_profile device_plf; +#ifdef BTIF_DIP_DEVICE + uint16_t vend_id; + uint16_t vend_id_source; + uint16_t reserve; +#endif +} nvrec_btdevicerecord; + +extern uint8_t nv_record_dev_rev; + +void nv_record_init(void); +bt_status_t nv_record_open(SECTIONS_ADP_ENUM section_id); +bt_status_t nv_record_enum_dev_records(unsigned short index,btif_device_record_t* record); +bt_status_t nv_record_add(SECTIONS_ADP_ENUM type,void *record); +bt_status_t nv_record_ddbrec_find(const bt_bdaddr_t *bd_ddr, btif_device_record_t*record); +bt_status_t nv_record_ddbrec_delete(const bt_bdaddr_t *bdaddr); +int nv_record_btdevicerecord_find(const bt_bdaddr_t *bd_ddr, nvrec_btdevicerecord **record); +int nv_record_touch_cause_flush(void); + +int nv_record_get_paired_dev_count(void); +void nv_record_sector_clear(void); +void nv_record_flash_flush(void); +int nv_record_flash_flush_in_sleep(void); +void nv_record_execute_async_flush(void); + +int nv_record_enum_latest_two_paired_dev(btif_device_record_t* record1,btif_device_record_t* record2); +void nv_record_all_ddbrec_print(void); + +void nv_record_update_runtime_userdata(void); +bt_status_t nv_record_config_rebuild(void); +void nv_record_btdevicerecord_set_a2dp_vol(nvrec_btdevicerecord* pRecord, int8_t vol); +void nv_record_btdevicerecord_set_hfp_vol(nvrec_btdevicerecord* pRecord, int8_t vol); +void nv_record_btdevicevolume_set_a2dp_vol(btdevice_volume* device_vol, int8_t vol); +void nv_record_btdevicevolume_set_hfp_vol(btdevice_volume* device_vol, int8_t vol); +void nv_record_btdevicerecord_set_vend_id_and_source(nvrec_btdevicerecord* pRecord, int16_t vend_id, int16_t vend_id_source); +void nv_record_btdevicerecord_set_a2dp_profile_active_state(btdevice_profile* device_plf, bool isActive); +void nv_record_btdevicerecord_set_hfp_profile_active_state(btdevice_profile* device_plf, bool isActive); +void nv_record_btdevicerecord_set_hsp_profile_active_state(btdevice_profile* device_plf, bool isActive); +void nv_record_btdevicerecord_set_a2dp_profile_codec(btdevice_profile* device_plf, uint8_t a2dpCodec); + +#ifdef NVREC_BAIDU_DATA_SECTION +#define BAIDU_DATA_SECTIN ("baidu_data") +#define BAIDU_DATA_FM_KEY ("fmfreq") +#define BAIDU_DATA_RAND_KEY ("rand") + +#define BAIDU_DATA_DEF_RAND "abcdefghi" + +int nvrec_baidu_data_init(void); +int nvrec_get_fm_freq(void); +int nvrec_set_fm_freq(int fmfreq); +int nvrec_get_rand(char *rand); +int nvrec_set_rand(char *rand); +int nvrec_clear_rand(void); +int nvrec_dev_get_sn(char *sn); +#endif + +uint32_t nv_record_pre_write_operation(void); +void nv_record_post_write_operation(uint32_t lock); + +#endif // #if !defined(NEW_NV_RECORD_ENABLED) + +#define nv_record_debug +#ifdef nv_record_debug +#define nvrec_trace TRACE +#else +#define nvrec_trace(...) +#endif + +#define NVREC_DEV_NEWEST_REV 2 +#define NVREC_DEV_VERSION_1 1 + +#define BLE_NAME_LEN_IN_NV 32 + +/* + this is the nvrec dev zone struct : + version|magic 16bit|16bit + crc 32bit + reserve[0] 32bit + reserv[1] 32bit + dev local name max 249*8bit + dev bt addr 64bit + dev ble addr 64bit + calib data 32bit +*/ +#define nvrec_dev_version 1 +#define nvrec_dev_magic 0xba80 +typedef enum +{ + dev_version_and_magic, //0 + dev_crc, //1 + dev_reserv1, //2 + dev_reserv2, //3 + dev_name, //[4~66] + dev_bt_addr = 67, //[67~68] + dev_ble_addr = 69, //[69~70] + dev_dongle_addr = 71, + dev_xtal_fcap = 73, //73 + dev_data_len, +}nvrec_dev_enum; + +// following the former nv rec dev info +typedef enum +{ + rev2_dev_data_len = 75, //75, length of the valid content, excluding crc + rev2_dev_crc, //76, crc value of the following data + rev2_dev_section_start_reserved, //77 + rev2_dev_reserv2, //78 + rev2_dev_name, //[79~141] + rev2_dev_bt_addr = 142, //[142~143] + rev2_dev_ble_addr = 144, //[144~145] + rev2_dev_dongle_addr = 146, //[146~147] + rev2_dev_xtal_fcap = 148, //148 + rev2_dev_ble_name = 149, //[149~156] +#ifdef NVREC_BAIDU_DATA_SECTION + rev2_dev_prod_sn = 157, //[157~160] +#endif + // TODO: add the new section in the future if needed + + rev2_dev_section_end = 157, + +}nvrec_dev_rev_2_enum; + +int nvrec_dev_get_dongleaddr(bt_bdaddr_t *dongleaddr); +int nvrec_dev_get_btaddr(char *btaddr); +char* nvrec_dev_get_bt_name(void); +const char* nvrec_dev_get_ble_name(void); + +#ifdef __cplusplus +} +#endif +#endif /* __NVRECORD_H__*/ diff --git a/services/nvrecord/nvrecord_ble.c b/services/nvrecord/nvrecord_ble.c new file mode 100644 index 0000000..d5d5c64 --- /dev/null +++ b/services/nvrecord/nvrecord_ble.c @@ -0,0 +1,331 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if !defined(NEW_NV_RECORD_ENABLED) + +#include +#include "nvrecord.h" +#include "nvrecord_ble.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "co_math.h" +#include "tgt_hardware.h" + +#define ble_nv_debug +#ifdef ble_nv_debug +#define ble_trace TRACE +#else +#define ble_trace +#endif + +extern nv_record_struct nv_record_config; +static struct Ble_nvrecord *nvrecord_ble_p = NULL; + +static bool blerec_specific_value_prepare(const BleDeviceinfo* param_rec) +{ + // Preparations before adding new ble record: + // 1. If not existing. Check the record count. If it's BLE_RECORD_NUM, + // move 0-(BLE_RECORD_NUM-2) right side by one slot, to discard the last one and + // leave slot 0, decrease the record number. + // If it's smaller than BLE_RECORD_NUM, move 0-(count-1) right side by one slot, leave slot 0, + // don't change the record number. + // 2. If existing already and the location is entryToFree , move 0-(entryToFree-1) + // right side by one slot, leave slot 0. Decrease the record number for adding the new one. + + bool isEntryExisting = false; + uint8_t entryToFree = 0; + struct Ble_nvrecord *dest_ptr; + + dest_ptr = nvrecord_ble_p; + TRACE(3,"%s start search addr %08x list_num=%d", __func__, (uint32_t)dest_ptr, dest_ptr->saved_list_num); + if (dest_ptr->saved_list_num > 0) + { + for (uint8_t i = 0; i < dest_ptr->saved_list_num; i++) + { + if (0 == memcmp(dest_ptr->ble_nv[i].LTK, param_rec->LTK, BLE_LTK_SIZE)) + { + ble_trace(2,"%s Find the existing entry %d", __func__, i); + DUMP8("%02x ", (uint8_t *)param_rec, sizeof(BleDeviceinfo)); + DUMP8("%02x ", (uint8_t *)&dest_ptr->ble_nv[i], sizeof(BleDeviceinfo)); + if (!memcmp((uint8_t *)param_rec, (uint8_t *)&dest_ptr->ble_nv[i], sizeof(BleDeviceinfo))) + { + ble_trace(0,"The new coming BLE device info is the same as the recorded."); + return false; + } + memset(&(dest_ptr->ble_nv[i]), 0, sizeof(BleDeviceinfo)); + entryToFree = i; + dest_ptr->saved_list_num--; + isEntryExisting = true; + break; + } + } + } + else + { + return true; + } + + if (!isEntryExisting) + { + if (BLE_RECORD_NUM == dest_ptr->saved_list_num) + { + TRACE(0,"<=====>blerec list is full,delete the oldest and add param_rec to list"); + for (uint8_t k = 0;k < BLE_RECORD_NUM - 1;k++) + { + memcpy(&(dest_ptr->ble_nv[BLE_RECORD_NUM - 1 - k]), + &(dest_ptr->ble_nv[BLE_RECORD_NUM - 2 - k]), + sizeof(BleDeviceinfo)); + } + dest_ptr->saved_list_num--; + } + else + { + for (uint8_t k = 0;k < dest_ptr->saved_list_num;k++) + { + memcpy(&(dest_ptr->ble_nv[dest_ptr->saved_list_num - k]), + &(dest_ptr->ble_nv[dest_ptr->saved_list_num - 1 - k]), + sizeof(BleDeviceinfo)); + } + } + return true; + } + else + { + for(uint8_t list_updata = 0;list_updata < entryToFree; list_updata++) + { + memcpy(&(dest_ptr->ble_nv[entryToFree - list_updata]), + &(dest_ptr->ble_nv[entryToFree - list_updata - 1]), + sizeof(BleDeviceinfo)); + } + } + + return true; +} + +void nv_record_blerec_init(void) +{ + if (NULL == nvrecord_ble_p) + { + nvrecord_ble_p = (struct Ble_nvrecord *)nvrec_config_get_int(nv_record_config.config, + (const char *)section_name_ble_nvds, (const char *)NV_RECORD_BLE_KEY, NVRAM_BLE_INVALID); + } + + if (nvrecord_ble_p == (struct Ble_nvrecord *)NVRAM_BLE_INVALID){ + nvrecord_ble_p = (struct Ble_nvrecord *)pool_malloc(sizeof(struct Ble_nvrecord)); + if (!nvrecord_ble_p){ + ASSERT(0,"%s ble pool_malloc failed",__func__); + return; + } + TRACE(1,"ble nv malloc addr %08x", (uint32_t)nvrecord_ble_p); + + memset(nvrecord_ble_p, 0, sizeof(struct Ble_nvrecord)); + nvrecord_ble_p->saved_list_num = 0;//init saved num + + uint8_t index; + //avoid ble irk collision low probability + uint32_t generatedSeed = hal_sys_timer_get(); + for (uint8_t index = 0; index < sizeof(bt_addr); index++) + { + generatedSeed ^= (((uint32_t)(bt_addr[index])) << (hal_sys_timer_get()&0xF)); + } + srand(generatedSeed); + + // generate a new IRK + for (index = 0; index < BLE_IRK_SIZE; index++) + { + nvrecord_ble_p->loc_irk[index] = (uint8_t)co_rand_word(); + } + nvrec_config_set_int(nv_record_config.config, section_name_ble_nvds, + (const char *)NV_RECORD_BLE_KEY,(int)nvrecord_ble_p); + + } +} + +void nv_record_blerec_get_local_irk(uint8_t* pIrk) +{ + memcpy(pIrk, nvrecord_ble_p->loc_irk, BLE_IRK_SIZE); +} + +bool nv_record_blerec_get_bd_addr_from_irk(uint8_t* pBdAddr, uint8_t* pIrk) +{ + if (nvrecord_ble_p->saved_list_num > 0) + { + for (uint8_t index = 0; index < nvrecord_ble_p->saved_list_num; index++) + { + if (!memcmp(pIrk, nvrecord_ble_p->ble_nv[index].IRK, BLE_IRK_SIZE)) + { + memcpy(pBdAddr, nvrecord_ble_p->ble_nv[index].peer_bleAddr, BLE_ADDR_SIZE); + return true; + } + } + return false; + } + else + { + return false; + } +} + +int nv_record_blerec_add(const BleDeviceinfo *param_rec) +{ + int nRet = 0; + + uint8_t isNeedToUpdateNv = true; + isNeedToUpdateNv = blerec_specific_value_prepare(param_rec); + + if (isNeedToUpdateNv) + { + //add device info into nv struct + memcpy(nvrecord_ble_p->ble_nv[0].peer_bleAddr, param_rec->peer_bleAddr, BLE_ADDR_SIZE);//addr + nvrecord_ble_p->ble_nv[0].EDIV = param_rec->EDIV;//EDIV + memcpy(nvrecord_ble_p->ble_nv[0].RANDOM, param_rec->RANDOM, BLE_ENC_RANDOM_SIZE);//RANDOM + memcpy(nvrecord_ble_p->ble_nv[0].LTK, param_rec->LTK, BLE_LTK_SIZE);//LTK + memcpy(nvrecord_ble_p->ble_nv[0].IRK, param_rec->IRK, BLE_IRK_SIZE);//IRK + nvrecord_ble_p->ble_nv[0].bonded = param_rec->bonded;//bond status + nvrecord_ble_p->saved_list_num++;//updata saved num + + nv_record_update_runtime_userdata(); + TRACE(2,"%s CURRENT BLE LIST NUM=%d", __func__, nvrecord_ble_p->saved_list_num); + } +#ifdef ble_nv_debug + for (uint8_t k = 0;k < nvrecord_ble_p->saved_list_num;k++){ + TRACE(0,"========================================="); + TRACE(1,"Num %d BLE record:", k); + TRACE(0,"BLE addr:"); + DUMP8("%02x ", (uint8_t *)nvrecord_ble_p->ble_nv[k].peer_bleAddr, BLE_ADDR_SIZE); + TRACE(1,"NV EDIV %d and random is:", nvrecord_ble_p->ble_nv[k].EDIV); + DUMP8("%02x ", (uint8_t *)nvrecord_ble_p->ble_nv[k].RANDOM, BLE_ENC_RANDOM_SIZE); + TRACE(0,"NV LTK:"); + DUMP8("%02x ", (uint8_t *)nvrecord_ble_p->ble_nv[k].LTK, BLE_LTK_SIZE); + TRACE(0,"NV irk:"); + DUMP8("%02x ", (uint8_t *)nvrecord_ble_p->ble_nv[k].IRK, BLE_IRK_SIZE); + } +#endif + return nRet; +} + +uint8_t nv_record_ble_fill_irk(uint8_t* irkToFill) +{ + struct Ble_nvrecord *find_ptr; + + find_ptr = (struct Ble_nvrecord *)nvrec_config_get_int(nv_record_config.config, + (const char *)section_name_ble_nvds, + (const char *)NV_RECORD_BLE_KEY, + NVRAM_BLE_INVALID); + + TRACE(2,"%s find_ptr 0x%x", __FUNCTION__, (uint32_t)find_ptr); + + if (((struct Ble_nvrecord *)NVRAM_BLE_INVALID == find_ptr) || + (0 == find_ptr->saved_list_num)) + { + return 0; + } + + if (find_ptr->saved_list_num > 0) + { + for (uint8_t index = 0; index < find_ptr->saved_list_num; index++) + { + memcpy(irkToFill + index*BLE_IRK_SIZE, find_ptr->ble_nv[index].IRK, BLE_IRK_SIZE); + } + return find_ptr->saved_list_num; + } + else + { + return 0; + } +} + +//when master send encription req,if bonded,use ltk to bonding again(skip the pair step) +bool nv_record_ble_record_find_ltk_through_static_bd_addr(uint8_t* pBdAddr, uint8_t *ltk) +{ + struct Ble_nvrecord *find_ptr; + find_ptr = (struct Ble_nvrecord *)nvrec_config_get_int(nv_record_config.config, (const char *)section_name_ble_nvds,(const char *)NV_RECORD_BLE_KEY, NVRAM_BLE_INVALID); + if (find_ptr == (struct Ble_nvrecord *)NVRAM_BLE_INVALID) + { + TRACE(1,"%s find data failed",__func__); + return false; + } + + for (uint8_t find_index=0; find_indexsaved_list_num; find_index++) + { + if (!memcmp(find_ptr->ble_nv[find_index].peer_bleAddr, pBdAddr, BLE_ADDR_SIZE)) + { + ble_trace(2,"%s FIND LTK IN NV SUCCESS %08x", __func__, (uint32_t)&find_ptr->ble_nv[find_index].LTK); + memcpy(ltk, find_ptr->ble_nv[find_index].LTK, BLE_LTK_SIZE); + return true; + } + } + return false; +} + +bool nv_record_ble_record_Once_a_device_has_been_bonded(void) +{ + struct Ble_nvrecord *find_ptr; + + find_ptr=(struct Ble_nvrecord *)nvrec_config_get_int(nv_record_config.config, (const char *)section_name_ble_nvds,(const char *)NV_RECORD_BLE_KEY, NVRAM_BLE_INVALID); + if (find_ptr == (struct Ble_nvrecord *)NVRAM_BLE_INVALID){ + return false; + } + for(uint8_t find_index=0;find_indexsaved_list_num;find_index++){ + if(find_ptr->ble_nv[find_index].bonded==true){ + return true; + } + } + return false; +} + +void nv_record_ble_delete_entry(uint8_t* pBdAddr) +{ + struct Ble_nvrecord *find_ptr; + + find_ptr = (struct Ble_nvrecord *)nvrec_config_get_int(nv_record_config.config, + (const char *)section_name_ble_nvds, + (const char *)NV_RECORD_BLE_KEY, + NVRAM_BLE_INVALID); + + if (((struct Ble_nvrecord *)NVRAM_BLE_INVALID == find_ptr) || + (0 == find_ptr->saved_list_num)) + { + return; + } + + int8_t indexToDelete = -1; + + for (uint8_t find_index=0; find_index < find_ptr->saved_list_num; find_index++) + { + if (!memcmp(find_ptr->ble_nv[find_index].peer_bleAddr, pBdAddr, BLE_ADDR_SIZE)) + { + indexToDelete = find_index; + break; + } + } + + if (indexToDelete >= 0) + { + uint8_t index; + for (index = indexToDelete; index < find_ptr->saved_list_num - 1; index++) + { + memcpy(&(find_ptr->ble_nv[index]), + &(find_ptr->ble_nv[index + 1]), + sizeof(BleDeviceinfo)); + } + + memset((uint8_t *)&(find_ptr->ble_nv[index]), 0, sizeof(BleDeviceinfo)); + find_ptr->saved_list_num--; + nv_record_update_runtime_userdata(); + } +} +#endif // !defined(NEW_NV_RECORD_ENABLED) + diff --git a/services/nvrecord/nvrecord_ble.h b/services/nvrecord/nvrecord_ble.h new file mode 100644 index 0000000..fc8ffec --- /dev/null +++ b/services/nvrecord/nvrecord_ble.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if !defined(NEW_NV_RECORD_ENABLED) + +#ifndef NVRECORD_BLE_H +#define NVRECORD_BLE_H + +#define BLE_RECORD_NUM 5 +#define section_name_ble_nvds "blenvds" +#define NV_RECORD_BLE_KEY "ble_key" +#define NVRAM_BLE_INVALID (0xfae66666) + +#define BLE_ADDR_SIZE 6 +#define BLE_ENC_RANDOM_SIZE 8 +#define BLE_LTK_SIZE 16 +#define BLE_IRK_SIZE 16 + +#define BLE_STATIC_ADDR 0 +#define BLE_RANDOM_ADDR 1 + +typedef struct _BleDeviceRecord { + uint8_t peer_bleAddr[BLE_ADDR_SIZE]; + uint16_t EDIV; + uint8_t RANDOM[BLE_ENC_RANDOM_SIZE]; + uint8_t LTK[BLE_LTK_SIZE]; + uint8_t IRK[BLE_IRK_SIZE]; + uint8_t bonded; + +} BleDeviceinfo; + +struct Ble_nvrecord { + uint8_t loc_irk[BLE_IRK_SIZE]; + uint8_t saved_list_num; + BleDeviceinfo ble_nv[BLE_RECORD_NUM]; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int nv_record_blerec_add(const BleDeviceinfo *param_rec); +bool nv_record_ble_record_find_ltk_through_static_bd_addr(uint8_t *pBdAddr, uint8_t *ltk); +bool nv_record_ble_record_Once_a_device_has_been_bonded(void); +void nv_record_ble_delete_entry(uint8_t *pBdAddr); +uint8_t nv_record_ble_fill_irk(uint8_t *ltkToFill); +void nv_record_blerec_init(void); +void nv_record_blerec_get_local_irk(uint8_t *pIrk); +bool nv_record_blerec_get_bd_addr_from_irk(uint8_t *pBdAddr, uint8_t *pIrk); +void nv_record_tws_exchange_ble_info(void); + +#ifdef __cplusplus +} +#endif +#endif + +#endif // #if !defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nvrecord/nvrecord_dev.h b/services/nvrecord/nvrecord_dev.h new file mode 100644 index 0000000..807ddfe --- /dev/null +++ b/services/nvrecord/nvrecord_dev.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef NVRECORD_DEV_H +#define NVRECORD_DEV_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + unsigned char *btd_addr; + unsigned char *ble_addr; + const char *localname; + const char *ble_name; +}dev_addr_name; + +bool nvrec_dev_data_open(void); +bool nvrec_dev_localname_addr_init(dev_addr_name *dev); +int nvrec_dev_force_get_btaddress(unsigned char *btd_addr); +void nvrec_dev_flash_flush(unsigned char *mempool); +void nvrec_dev_rand_btaddr_gen(uint8_t* bdaddr); +void nvrec_dev_set_xtal_fcap(unsigned int xtal_fcap); +int nvrec_dev_get_xtal_fcap(unsigned int *xtal_fcap); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/services/nvrecord/nvrecord_env.c b/services/nvrecord/nvrecord_env.c new file mode 100644 index 0000000..2c09e7c --- /dev/null +++ b/services/nvrecord/nvrecord_env.c @@ -0,0 +1,139 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if !defined(NEW_NV_RECORD_ENABLED) + +#include +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "hal_trace.h" +#include "customparam_section.h" + +#define NV_RECORD_ENV_KEY "env_key" + +extern nv_record_struct nv_record_config; +static struct nvrecord_env_t *nvrecord_env_p = NULL; + +static int nv_record_env_new(void) +{ + + nvrecord_env_p = (struct nvrecord_env_t *)pool_malloc(sizeof(struct nvrecord_env_t)); + + if (!nvrecord_env_p) + { + TRACE(1,"%s pool_malloc failed ", __func__); + return -1; + } + nvrec_config_set_int(nv_record_config.config,section_name_other,(const char *)NV_RECORD_ENV_KEY,(int)nvrecord_env_p); + + nvrecord_env_p->media_language.language = NVRAM_ENV_MEDIA_LANGUAGE_DEFAULT; + nvrecord_env_p->ibrt_mode.mode = NVRAM_ENV_TWS_MODE_DEFAULT; + nvrecord_env_p->ibrt_mode.tws_connect_success = 0; + nvrecord_env_p->factory_tester_status.status = NVRAM_ENV_FACTORY_TESTER_STATUS_DEFAULT; + + nvrecord_env_p->aiManagerInfo.voice_key_enable = false; + nvrecord_env_p->aiManagerInfo.setedCurrentAi = 0; + nvrecord_env_p->aiManagerInfo.aiStatusDisableFlag = 0; + nvrecord_env_p->aiManagerInfo.amaAssistantEnableStatus = 1; + //nv_record_update_runtime_userdata(); + + TRACE(2,"%s nvrecord_env_p:0x%x",__func__, (uint32_t)nvrecord_env_p); + + return 0; +} + +static int nv_record_env_rebuild(void) +{ + if(nv_record_config_rebuild() != BT_STS_SUCCESS) + return -1; + + if(nv_record_env_new()) + return -1; + nv_record_config.is_update = true; + nv_record_config.state = NV_STATE_IDLE; + nv_record_config.written_size = 0; + nv_record_flash_flush(); + + return 0; +} + +int nv_record_env_init(void) +{ + int nRet = 0; + nv_record_open(section_usrdata_ddbrecord); + + nv_custom_parameter_section_init(); + + nvrecord_env_p = (struct nvrecord_env_t *)nvrec_config_get_int(nv_record_config.config, (const char *)section_name_other,(const char *)NV_RECORD_ENV_KEY, NVRAM_ENV_INVALID); + + if (nvrecord_env_p == (struct nvrecord_env_t *)NVRAM_ENV_INVALID) + { + TRACE(0,"NVRAM_ENV_INVALID !!"); + if (nv_record_env_rebuild() < 0) + nRet = -1; + else + TRACE(0,"NVRAM REBUILD SUCCESS !!"); + } + TRACE(2,"%s nvrecord_env_p: 0x%x",__func__, (uint32_t)nvrecord_env_p); + return nRet; +} + +int nv_record_env_get(struct nvrecord_env_t **nvrecord_env) +{ + if (!nvrecord_env) + return -1; + + if (!nvrecord_env_p) + return -1; + + *nvrecord_env = nvrecord_env_p; + + return 0; +} + +int nv_record_env_set(struct nvrecord_env_t *nvrecord_env) +{ + if (!nvrecord_env) + return -1; + + if (!nvrecord_env_p) + return -1; + + nv_record_update_runtime_userdata(); + + return 0; +} + +void nv_record_update_factory_tester_status(uint32_t status) +{ + if (nvrecord_env_p) + { + nvrecord_env_p->factory_tester_status.status = status; + } +} + +void nv_record_update_ibrt_info(uint32_t newMode,bt_bdaddr_t *ibrtPeerAddr) +{ + if (nvrecord_env_p) + { + TRACE(2,"##%s,%d",__func__,newMode); + nvrecord_env_p->ibrt_mode.mode = newMode; + nv_record_config.is_update = true; + memcpy(nvrecord_env_p->ibrt_mode.record.bdAddr.address,ibrtPeerAddr->address,6); + } +} + +#endif // #if !defined(NEW_NV_RECORD_ENABLED) + diff --git a/services/nvrecord/nvrecord_env.h b/services/nvrecord/nvrecord_env.h new file mode 100644 index 0000000..6475cbd --- /dev/null +++ b/services/nvrecord/nvrecord_env.h @@ -0,0 +1,94 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if !defined(NEW_NV_RECORD_ENABLED) + +#ifndef NVRECORD_ENV_H +#define NVRECORD_ENV_H + +#ifdef __cplusplus +extern "C" { +#endif +#include "me_api.h" + +#define NVRAM_ENV_INVALID (0xdead0000) +#define NVRAM_ENV_MEDIA_LANGUAGE_DEFAULT (0) +#define NVRAM_ENV_STREAM_VOLUME_A2DP_VOL_DEFAULT (AUDIO_OUTPUT_VOLUME_DEFAULT) +#define NVRAM_ENV_STREAM_VOLUME_HFP_VOL_DEFAULT (AUDIO_OUTPUT_VOLUME_DEFAULT) +#define NVRAM_ENV_TWS_MODE_DEFAULT (0xff) +#define NVRAM_ENV_FACTORY_TESTER_STATUS_DEFAULT (0xaabbccdd) +#define NVRAM_ENV_FACTORY_TESTER_STATUS_TEST_PASS (0xffffaa55) + +struct media_language_t +{ + int8_t language; +}; + +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) +struct src_snk_t +{ + int8_t src_snk_mode; +}; +#endif + +struct ibrt_mode_t +{ + uint32_t mode; + btif_device_record_t record; + bool tws_connect_success; +}; +struct factory_tester_status_t +{ + uint32_t status; +}; + +typedef struct +{ + bool voice_key_enable; + uint8_t setedCurrentAi; + uint8_t currentAiSpec; + uint8_t aiStatusDisableFlag; + uint8_t amaAssistantEnableStatus; //one bit for one AI assistant +} AI_MANAGER_INFO_T; + +struct nvrecord_env_t +{ + struct media_language_t media_language; +#if defined(APP_LINEIN_A2DP_SOURCE)||defined(APP_I2S_A2DP_SOURCE) + struct src_snk_t src_snk_flag; +#endif + struct ibrt_mode_t ibrt_mode; + struct factory_tester_status_t factory_tester_status; + + uint8_t flag_value[8]; + AI_MANAGER_INFO_T aiManagerInfo; +}; + +int nv_record_env_init(void); + +int nv_record_env_get(struct nvrecord_env_t **nvrecord_env); + +int nv_record_env_set(struct nvrecord_env_t *nvrecord_env); + +void nv_record_update_ibrt_info(uint32_t newMode,bt_bdaddr_t *ibrtPeerAddr); + +void nv_record_update_factory_tester_status(uint32_t status); + +#ifdef __cplusplus +} +#endif +#endif + +#endif // #if !defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nvrecord/nvrecord_fp_account_key.c b/services/nvrecord/nvrecord_fp_account_key.c new file mode 100644 index 0000000..c3994cb --- /dev/null +++ b/services/nvrecord/nvrecord_fp_account_key.c @@ -0,0 +1,156 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if !defined(NEW_NV_RECORD_ENABLED) + +#include +#include "nvrecord.h" +#include "nvrecord_fp_account_key.h" +#include "hal_trace.h" +#include "co_math.h" + + +extern nv_record_struct nv_record_config; +static NV_FP_ACCOUNT_KEY_RECORD_T *nvrecord_fp_account_key_p = NULL; + +NV_FP_ACCOUNT_KEY_RECORD_T* nv_record_get_fp_data_structure_info(void) +{ + return nvrecord_fp_account_key_p; +} + +void nv_record_update_fp_data_structure(NV_FP_ACCOUNT_KEY_RECORD_T* pFpData) +{ + if (!memcmp((uint8_t *)pFpData, (uint8_t *)nvrecord_fp_account_key_p, + sizeof(NV_FP_ACCOUNT_KEY_RECORD_T))) + { + // the updated fp data is the same as the local content, do nothing + + } + else + { + TRACE(0,"Fast pair non-volatile data needs to be updated to aligned with peer device."); + *nvrecord_fp_account_key_p = *pFpData; + nv_record_update_runtime_userdata(); + } +} + +void nv_record_fp_account_key_init(void) +{ + if (NULL == nvrecord_fp_account_key_p) + { + nvrecord_fp_account_key_p = + (NV_FP_ACCOUNT_KEY_RECORD_T *)nvrec_config_get_int(nv_record_config.config, + (const char *)section_name_fp_account_key, + (const char *)NV_RECORD_ACCOUNT_KEY, + NVRAM_ACCOUNT_KEY_INVALID); + } + + if ((NV_FP_ACCOUNT_KEY_RECORD_T *)NVRAM_ACCOUNT_KEY_INVALID == nvrecord_fp_account_key_p) + { + nvrecord_fp_account_key_p = (NV_FP_ACCOUNT_KEY_RECORD_T *)pool_malloc(sizeof(NV_FP_ACCOUNT_KEY_RECORD_T)); + if (!nvrecord_fp_account_key_p) + { + ASSERT(0,"%s pool_malloc failed",__func__); + return; + } + + memset(nvrecord_fp_account_key_p, 0, sizeof(NV_FP_ACCOUNT_KEY_RECORD_T)); + + nvrec_config_set_int(nv_record_config.config, section_name_fp_account_key, + (const char *)NV_RECORD_ACCOUNT_KEY, (int)nvrecord_fp_account_key_p); + } +} + +void nv_record_fp_account_key_add(NV_FP_ACCOUNT_KEY_ENTRY_T* param_rec) +{ + TRACE(0,"Add account key:"); + DUMP8("%02x ", param_rec->key, sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + + if (FP_ACCOUNT_KEY_RECORD_NUM == nvrecord_fp_account_key_p->key_count) + { + // discard the earliest key + memmove((uint8_t *)&(nvrecord_fp_account_key_p->accountKey[0]), + (uint8_t *)&(nvrecord_fp_account_key_p->accountKey[1]), + (FP_ACCOUNT_KEY_RECORD_NUM - 1)*sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + + nvrecord_fp_account_key_p->key_count--; + } + + memcpy((uint8_t *)&(nvrecord_fp_account_key_p->accountKey[nvrecord_fp_account_key_p->key_count]), + param_rec, + sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + + nvrecord_fp_account_key_p->key_count++; + + nv_record_update_runtime_userdata(); +} + +void nv_record_fp_account_info_reset(void) { + uint8_t size = nv_record_fp_account_key_count(); + for (uint8_t i = 0 ; i < size ; i++){ + memset((uint8_t *)&(nvrecord_fp_account_key_p->accountKey[i]), 0, + sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + } + nvrecord_fp_account_key_p->key_count = 0; + + nv_record_fp_update_name(NULL, 0); +} + +void nv_record_fp_account_key_delete(void) +{ + nv_record_fp_account_info_reset(); +} + +bool nv_record_fp_account_key_get_by_index(uint8_t index, uint8_t* outputKey) +{ + if (nvrecord_fp_account_key_p->key_count < (index + 1)) + { + return false; + } + + memcpy(outputKey, (uint8_t *)&(nvrecord_fp_account_key_p->accountKey[index]), + sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + + TRACE(1,"Get account key %d as:", index); + DUMP8("%02x ", outputKey, sizeof(NV_FP_ACCOUNT_KEY_ENTRY_T)); + + return true; +} + +uint8_t nv_record_fp_account_key_count(void) +{ + return nvrecord_fp_account_key_p->key_count; +} + +void nv_record_fp_update_name(uint8_t* ptrName, uint32_t nameLen) +{ + TRACE(1,"update name len %d", nameLen); + + memset(nvrecord_fp_account_key_p->name, 0, FP_MAX_NAME_LEN); + if (nameLen > 0) + { + DUMP8("0x%02x ", ptrName, nameLen); + memcpy(nvrecord_fp_account_key_p->name, ptrName, nameLen); + } + nvrecord_fp_account_key_p->nameLen = nameLen; + nv_record_update_runtime_userdata(); +} + +uint8_t* nv_record_fp_get_name_ptr(uint32_t* ptrNameLen) +{ + *ptrNameLen = nvrecord_fp_account_key_p->nameLen; + return nvrecord_fp_account_key_p->name; +} +#endif //#if !defined(NEW_NV_RECORD_ENABLED) diff --git a/services/nvrecord/nvrecord_fp_account_key.h b/services/nvrecord/nvrecord_fp_account_key.h new file mode 100644 index 0000000..bf34701 --- /dev/null +++ b/services/nvrecord/nvrecord_fp_account_key.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#if !defined(NEW_NV_RECORD_ENABLED) + +#ifndef __NVRECORD_FP_ACCOUNT_KEY_H__ +#define __NVRECORD_FP_ACCOUNT_KEY_H__ + +#define FP_ACCOUNT_KEY_RECORD_NUM 5 +#define section_name_fp_account_key "fpaccountkey" +#define NV_RECORD_ACCOUNT_KEY "account_key" +#define NVRAM_ACCOUNT_KEY_INVALID (0xFFFFFFFF) + +#define FP_ACCOUNT_KEY_SIZE 16 +#define FP_MAX_NAME_LEN 64 + +typedef struct +{ + uint8_t key[FP_ACCOUNT_KEY_SIZE]; + +} NV_FP_ACCOUNT_KEY_ENTRY_T; + +typedef struct +{ + uint8_t key_count; + NV_FP_ACCOUNT_KEY_ENTRY_T accountKey[FP_ACCOUNT_KEY_RECORD_NUM]; + uint16_t nameLen; + uint8_t name[FP_MAX_NAME_LEN]; +} NV_FP_ACCOUNT_KEY_RECORD_T; + +#ifdef __cplusplus +extern "C" { +#endif + +void nv_record_fp_account_key_add(NV_FP_ACCOUNT_KEY_ENTRY_T* param_rec); +void nv_record_fp_account_key_delete(); +void nv_record_fp_account_key_init(void); +bool nv_record_fp_account_key_get_by_index(uint8_t index, uint8_t* outputKey); +uint8_t nv_record_fp_account_key_count(void); +void nv_record_fp_update_name(uint8_t* ptrName, uint32_t nameLen); +uint8_t* nv_record_fp_get_name_ptr(uint32_t* ptrNameLen); +NV_FP_ACCOUNT_KEY_RECORD_T* nv_record_get_fp_data_structure_info(void); +void nv_record_update_fp_data_structure(NV_FP_ACCOUNT_KEY_RECORD_T* pFpData); + +#ifdef __cplusplus +} +#endif +#endif +#endif // #if !defined(NEW_NV_RECORD_ENABLED) diff --git a/services/osif/Makefile b/services/osif/Makefile new file mode 100644 index 0000000..d408fba --- /dev/null +++ b/services/osif/Makefile @@ -0,0 +1,13 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y += \ + -Iservices/nvrecord \ + $(BT_IF_INCLUDES) \ + -Iutils/heap \ + diff --git a/services/osif/ddbif.h b/services/osif/ddbif.h new file mode 100644 index 0000000..02ab805 --- /dev/null +++ b/services/osif/ddbif.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __DDBIF_H__ +#define __DDBIF_H__ + +#include "bluetooth.h" +#include "me_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void ddbif_list_saved_flash(void); + +bt_status_t ddbif_close(void); + +bt_status_t ddbif_add_record(btif_device_record_t *record); + +bt_status_t ddbif_open(const bt_bdaddr_t *bdAddr); + +bt_status_t ddbif_find_record(const bt_bdaddr_t *bdAddr, btif_device_record_t *record); + +bt_status_t ddbif_delete_record(const bt_bdaddr_t *bdAddr); + +bt_status_t ddbif_enum_device_records(I16 index, btif_device_record_t *record); + +#ifdef __cplusplus +} +#endif +#endif /*__DDBIF_H__*/ + diff --git a/services/osif/ddbif_bes.c b/services/osif/ddbif_bes.c new file mode 100644 index 0000000..91bb2f5 --- /dev/null +++ b/services/osif/ddbif_bes.c @@ -0,0 +1,406 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include +#include + +#include "hal_trace.h" +#include "bluetooth.h" +#include "me_api.h" + +#ifndef FPGA +#include "cmsis_os.h" +#include "cmsis.h" +#include "nvrecord.h" + +//static int DDB_Print_Node(BtDeviceRecord* record) +//{ +// nvrec_trace(0,"record_bdAddr = "); +// OS_DUMP8("%x ",record->bdAddr.addr,sizeof(record->bdAddr.addr)); +// nvrec_trace(0,"record_trusted = "); +// OS_DUMP8("%d ",&record->trusted,sizeof((uint8_t)record->trusted)); +// nvrec_trace(0,"record_linkKey = "); +// OS_DUMP8("%x ",record->linkKey,sizeof(record->linkKey)); +// nvrec_trace(0,"record_keyType = "); +// OS_DUMP8("%x ",&record->keyType,sizeof(record->keyType)); +// nvrec_trace(0,"record_pinLen = "); +// OS_DUMP8("%x ",&record->pinLen,sizeof(record->pinLen)); +// return 1; +//} + +void ddbif_list_saved_flash(void) +{ + nv_record_flash_flush(); +} + +bt_status_t ddbif_close(void) +{ + ddbif_list_saved_flash(); + return BT_STS_SUCCESS; +} + +bt_status_t ddbif_add_record(btif_device_record_t *record) +{ + return nv_record_add(section_usrdata_ddbrecord,(void *)record); +} + +bt_status_t ddbif_open(const bt_bdaddr_t *bdAddr) +{ + bt_status_t status = BT_STS_FAILED; + status = nv_record_open(section_usrdata_ddbrecord); + + return status; +} + +bt_status_t ddbif_find_record(const bt_bdaddr_t *bdAddr, btif_device_record_t *record) +{ + return nv_record_ddbrec_find(bdAddr,record); +} + +bt_status_t ddbif_delete_record(const bt_bdaddr_t *bdAddr) +{ + return nv_record_ddbrec_delete(bdAddr); +} + +bt_status_t ddbif_enum_device_records(I16 index, btif_device_record_t *record) +{ + return nv_record_enum_dev_records((unsigned short)index,record); +} +#else +typedef struct _DDB_List { + struct _DDB_List *next; + btif_device_record_t *record; +} DDB_List; + +static DDB_List *head = NULL; +static bt_bdaddr_t remDev_addr; +static int DDB_Print_Node(btif_device_record_t *record); +static int DDB_Print(); + +static void *DDB_Malloc (uint32_t size) +{ + return malloc(size); +} + +static void DDB_Free (void *p_mem) +{ + free(p_mem); +} + +static char POSSIBLY_UNUSED Hex2String(unsigned char *src, char* dest, + unsigned int srcLen, + unsigned int destLen) +{ + unsigned int i = 0; + unsigned char hb = 0, lb = 0; + + memset((char *)dest, 0, destLen); + for(i = 0 ; i < srcLen ; i++) { + hb = (src[i]&0xf0)>>4; + if( hb >= 0 && hb <= 9) + hb += 0x30; + else if( hb>=10 &&hb <=15 ) + hb = hb -10 + 'A'; + else + return 0; + + lb = src[i]&0x0f; + if( lb>=0 && lb<=9 ) + lb += 0x30; + else if( lb>=10 && lb<=15 ) + lb = lb - 10 + 'A'; + else + return 0; + + dest[i*2+0] = hb; + dest[i*2+1] = lb; + } + + return 1; +} + +static void DDB_List_delete(DDB_List *list_head) +{ + DDB_List *list = list_head,*list_tmp = NULL; + + while(NULL != list) { + list_tmp = list; + if(NULL != list->record) + DDB_Free(list->record); + + list = list->next; + DDB_Free(list_tmp); + } +} + +bt_status_t ddbif_close(void) +{ + DDB_List *Close_tmp = NULL; + Close_tmp = head; + + while(1) { + DDB_Print(); + + Close_tmp = Close_tmp->next; + if(Close_tmp == NULL) { + TRACE(0,"DDB_Close.\n"); + break; + } + } + + DDB_List_delete(head); + return BT_STS_SUCCESS; +} + +bt_status_t ddbif_add_record(btif_device_record_t *record) +{ + DDB_List *ptr = NULL; + DDB_List *tmp = NULL; + ptr = head; + + tmp = (DDB_List *)DDB_Malloc(sizeof(DDB_List)); + if(tmp == NULL) { + TRACE(0,"DDB_AddRecord head == NULL:There is no enough space for DDB_List.\n"); + return BT_STS_FAILED; + } + tmp->next = NULL; + + tmp->record = (btif_device_record_t *)DDB_Malloc(sizeof(btif_device_record_t)); + if(NULL == tmp->record) { + TRACE(0,"DDB_AddRecord head == NULL:There is no enough space for DDB_List.record.\n"); + return BT_STS_FAILED; + } + + if(head == NULL) { + memcpy(tmp->record->bdAddr.address,record->bdAddr.address,sizeof(record->bdAddr.address)); + tmp->record->keyType = record->keyType; + memcpy(tmp->record->linkKey,record->linkKey,sizeof(record->linkKey)); + tmp->record->pinLen = record->pinLen; + tmp->record->trusted = record->trusted; + + head = tmp; + memcpy(remDev_addr.address,tmp->record->bdAddr.address,sizeof(tmp->record->bdAddr.address)); + TRACE(0,"DDB_AddRecord head:\n"); + DDB_Print_Node(tmp->record); + DDB_Print(); + + return BT_STS_SUCCESS; + } + + while((ptr->next != NULL) && + (memcmp(ptr->record->bdAddr.address, record->bdAddr.address, + sizeof(ptr->record->bdAddr.address)))) { + ptr = ptr->next; + } + + if(!memcmp(ptr->record->bdAddr.address, record->bdAddr.address, + sizeof(ptr->record->bdAddr.address))) { + ptr->record->keyType = record->keyType; + memcpy(ptr->record->linkKey,record->linkKey,sizeof(record->linkKey)); + ptr->record->pinLen = record->pinLen; + ptr->record->trusted = record->trusted; + TRACE(0,"DDB_AddRecord head::\n"); + DDB_Print_Node(ptr->record); + DDB_Print(); + free(tmp->record); + free(tmp); + return BT_STS_SUCCESS; + } + + if(ptr->next == NULL) { + tmp->next = NULL; + memcpy(tmp->record->bdAddr.address,record->bdAddr.address,sizeof(record->bdAddr.address)); + tmp->record->keyType = record->keyType; + memcpy(tmp->record->linkKey,record->linkKey,sizeof(record->linkKey)); + tmp->record->pinLen = record->pinLen; + tmp->record->trusted = record->trusted; + + memcpy(remDev_addr.address,tmp->record->bdAddr.address,sizeof(tmp->record->bdAddr.address)); + + ptr->next = tmp; + TRACE(0,"DDB_AddRecord head:::\n"); + DDB_Print_Node(tmp->record); + DDB_Print(); + + return BT_STS_SUCCESS; + } + + return BT_STS_FAILED; +} + + +bt_status_t ddbif_open(const bt_bdaddr_t *bdAddr) +{ +// DDB_List *head = NULL; + return BT_STS_SUCCESS; +} + +static int DDB_Print_Node(btif_device_record_t *record) +{ + int i; + + for(i = 0; i < 6; i++) { + TRACE(1,"%x ",record->bdAddr.address[i]); + } + TRACE(0,"\n"); +/* + for(i=0; i<16; i++) + { + TRACE(1,"%x ",record->linkKey[i]); + } + TRACE(0,"\n"); + + TRACE(3,"%d,%d,%d\n",record->keyType,record->pinLen,record->trusted); + */ + return 1; + +} + +static int DDB_Print() +{ + DDB_List *Print_tmp = NULL; + Print_tmp = head; + + if(Print_tmp == NULL) { + TRACE(0,"DDB list is null!\n"); + return 0; + } + + TRACE(0,"-----------------DDB list-------------------\n"); + while(Print_tmp != NULL) { + DDB_Print_Node(Print_tmp->record); + Print_tmp = Print_tmp->next; + } + TRACE(0,"--------------------end---------------------\n"); + return 0; +} + +bt_status_t ddbif_find_record(const bt_bdaddr_t *bdAddr, btif_device_record_t *record) +{ + DDB_List *FindRecord_tmp = NULL; + FindRecord_tmp = head; + + if(head == NULL) { + TRACE(0,"DDB_FindRecord:DDB is null!\n"); + return BT_STS_FAILED; + } + + while(memcmp(FindRecord_tmp->record->bdAddr.address, bdAddr->address, + sizeof(FindRecord_tmp->record->bdAddr.address)) && (FindRecord_tmp->next != NULL)) { + FindRecord_tmp = FindRecord_tmp->next; + } + + if(!memcmp(FindRecord_tmp->record->bdAddr.address,bdAddr->address, + sizeof(FindRecord_tmp->record->bdAddr.address))) { + memcpy(record->bdAddr.address, FindRecord_tmp->record->bdAddr.address, + sizeof(FindRecord_tmp->record->bdAddr.address)); + record->keyType = FindRecord_tmp->record->keyType; + memcpy(record->linkKey,FindRecord_tmp->record->linkKey, + sizeof(FindRecord_tmp->record->linkKey)); + record->pinLen = FindRecord_tmp->record->pinLen; + record->trusted = FindRecord_tmp->record->trusted; + TRACE(0,"DDB_FindRecord:\n"); + DDB_Print_Node(record); + return BT_STS_SUCCESS; + } + + if(FindRecord_tmp->next == NULL) { + TRACE(0,"DDB_FindRecord ends.\n"); + return BT_STS_FAILED; + } + + return BT_STS_FAILED; +} + +bt_status_t ddbif_delete_record(const bt_bdaddr_t *bdAddr) +{ + DDB_List *checkingAddr = NULL; + DDB_List *checkedAddr = NULL; + checkingAddr = head; + + if(head == NULL) { + TRACE(0,"DDB_DeleteRecord:list is null!\n"); + return BT_STS_FAILED; + } + + while(memcmp(checkingAddr->record->bdAddr.address,bdAddr->address, + sizeof(checkingAddr->record->bdAddr.address)) && (checkingAddr->next != NULL)) { + checkedAddr = checkingAddr; + checkingAddr = checkingAddr->next; + } + + if(!memcmp(checkingAddr->record->bdAddr.address,bdAddr->address, + sizeof(checkingAddr->record->bdAddr.address))) { + if(checkingAddr == head) { + head = checkingAddr->next; + free(checkingAddr->record); + free(checkingAddr); + + DDB_Print(); + return BT_STS_SUCCESS; + } else { + checkedAddr->next = checkingAddr->next; + free(checkingAddr->record); + free(checkingAddr); + + DDB_Print(); + return BT_STS_SUCCESS; + } + } + + if(checkingAddr->next == NULL) { + return BT_STS_FAILED; + } + + return BT_STS_FAILED; +} + +bt_status_t ddbif_enum_device_records(I16 index, btif_device_record_t *record) +{ + DDB_List *databaselist; + databaselist = head; + + if(head == NULL) { + TRACE(0,"DDB_EnumDeviceRecords:No records!\n"); + return BT_STS_FAILED; + } + + TRACE(1,"index=%d\n",(uint32_t)index); + while(databaselist != NULL) { + if(!index) { + break; + } + databaselist = databaselist->next; + index--; + } + + if((index == 0) && (databaselist != NULL)) { + TRACE(0,"Enum record:\n"); + DDB_Print_Node(databaselist->record); + TRACE(0,"Enumeration ends!\n\n"); + return BT_STS_SUCCESS; + } + + if(databaselist == NULL) { + TRACE(0,"Enumeration failed.\n"); + return BT_STS_FAILED; + } + + return BT_STS_FAILED; +} +#endif + + diff --git a/services/osif/osif.h b/services/osif/osif.h new file mode 100644 index 0000000..2a8f736 --- /dev/null +++ b/services/osif/osif.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __OSIF_H__ +#define __OSIF_H__ +#include + +typedef uint32_t osif_timer_t; + +typedef void (*osif_timer_callback)(void); + +#if defined(__cplusplus) +extern "C" { +#endif + +bool osif_init(void); + +uint32_t osif_get_sys_time(void); + +uint16_t osif_rand(void); + +void osif_stop_hardware(void); + +void osif_resume_hardware(void); + +void osif_memcopy(uint8_t *dest, const uint8_t *source, uint32_t numBytes); + +bool osif_memcmp(const uint8_t *buffer1, uint16_t len1, const uint8_t *buffer2, uint16_t len2); + +void osif_memset(uint8_t *dest, uint8_t byte, uint32_t len); + +uint8_t osif_strcmp(const char *Str1, const char *Str2); + +uint16_t osif_strlen(const char *Str); + +void osif_assert(const char *expression, const char *file, uint16_t line); + +void osif_lock_stack(void); + +void osif_unlock_stack(void); + +void osif_notify_evm(void); + +void osif_start_timer(osif_timer_t t, osif_timer_callback func); + +void osif_cancel_timer(void); + +uint8_t osif_lock_is_exist(void); + +#if defined(__cplusplus) +} +#endif + +#endif /*__OSIF_H__*/ + diff --git a/services/osif/osif_rtx.c b/services/osif/osif_rtx.c new file mode 100644 index 0000000..f11c3fc --- /dev/null +++ b/services/osif/osif_rtx.c @@ -0,0 +1,195 @@ + +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include +#include +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "osif.h" + + +extern osMessageQId evm_queue_id; +static void __timer_wrapper_callback(void const *n); + +static osif_timer_callback __timer_wrapper_notify_func = NULL; +static osTimerId __timer_wrapper_id = NULL; +osTimerDef(__timer_wrapper__, __timer_wrapper_callback); + +osMutexId __mutex_wrapper_id = NULL; +osMutexDef (__mutex_wrapper); + +osMutexId __mutex_stophardware_id = NULL; +osMutexDef(__mutex_stophardware); + +bool osif_init(void) +{ + if (__mutex_wrapper_id == NULL) + __mutex_wrapper_id = osMutexCreate((osMutex(__mutex_wrapper))); + + if (__mutex_stophardware_id == NULL) + __mutex_stophardware_id = osMutexCreate((osMutex(__mutex_stophardware))); + + if (__timer_wrapper_id == NULL) + __timer_wrapper_id = osTimerCreate(osTimer(__timer_wrapper__), osTimerOnce, (void *)0); + + return true; +} + +uint32_t osif_get_sys_time(void) +{ + return hal_sys_timer_get(); +} + +uint16_t osif_rand(void) +{ + return rand(); +} + +void osif_stop_hardware(void) +{ + osMutexWait(__mutex_stophardware_id, osWaitForever); +} + +void osif_resume_hardware(void) +{ + osMutexRelease(__mutex_stophardware_id); +} + +void osif_memcopy(uint8_t *dest, const uint8_t *source, uint32_t numBytes) +{ + memcpy(dest, source, numBytes); +} + +bool osif_memcmp(const uint8_t *buffer1, uint16_t len1, const uint8_t *buffer2, uint16_t len2) +{ + int r = 0; + r = memcmp(buffer1, buffer2, len1>len2?len2:len1); + return (r == 0?1:0); +} + +void osif_memset(uint8_t *dest, uint8_t byte, uint32_t len) +{ + memset(dest, byte, len); +} + +uint8_t osif_strcmp(const char *Str1, const char *Str2) +{ + int r = 0; + r = strcmp(Str1, Str2); + return (r == 0?0:1); +} + +uint16_t osif_strlen(const char *Str) +{ + return strlen(Str); +} + +void osif_assert(const char *expression, const char *file, uint16_t line) +{ + ASSERT(0,"OS_Assert exp: %s, func: %s, line %d\r\n", expression, file, line); + while(1); +} +extern void OS_LockStack_Info_Print(void); +void osif_lock_stack(void) +{ + osThreadId request = 0; +#if (osCMSIS < 0x20000U) + osThreadId hold = 0; +#endif + unsigned int t = 0; + osStatus status; + bool success; + + if(NULL == __mutex_wrapper_id) + return; + + request = osThreadGetId(); +#if (osCMSIS < 0x20000U) + hold = osMutexGetOwner(__mutex_wrapper_id); +#endif + t = hal_sys_timer_get(); + status = osMutexWait(__mutex_wrapper_id, 8000); + t = TICKS_TO_MS(hal_sys_timer_get()-t); + + if ((t > 10) || (status != osOK)) { + TRACE(2,"stack lock wait %d ms, status=0x%x", t, status); + TRACE(1,"request thread=%p", request); +#if (osCMSIS < 0x20000U) + TRACE(1,"hold thread=%p", hold); +#endif + } + + success = (status == osOK); + if (!success) { + TRACE(1,"request thread=%p", request); +#if (osCMSIS < 0x20000U) + osThreadShow(request); + TRACE(1,"hold thread=%p", hold); + osThreadShow(hold); +#endif + OS_LockStack_Info_Print(); + ASSERT(0,"cannot lock stack %d\n", status); + return; + } +} + +void osif_unlock_stack(void) +{ + if(NULL == __mutex_wrapper_id) + return; + + osMutexRelease(__mutex_wrapper_id); +} + +extern uint32_t rt_mbx_check (void* mailbox); + +void osif_notify_evm(void) +{ + if (osMessageGetSpace (evm_queue_id) > 5 ) { + osMessagePut(evm_queue_id, 0xFF, 0); + } +} + +static void __timer_wrapper_callback(void const *n) +{ + if(__timer_wrapper_notify_func) + __timer_wrapper_notify_func(); +} + +void osif_start_timer(osif_timer_t t, osif_timer_callback func) +{ + __timer_wrapper_notify_func = func; + + osTimerStart(__timer_wrapper_id, (t>>4)+0x5); +} + +void osif_cancel_timer(void) +{ + osTimerStop(__timer_wrapper_id); +} + +uint8_t osif_lock_is_exist(void) +{ + if(NULL == __mutex_wrapper_id) + return 0; + else + return 1; +} + diff --git a/services/ota/Makefile b/services/ota/Makefile new file mode 100644 index 0000000..435d30e --- /dev/null +++ b/services/ota/Makefile @@ -0,0 +1,87 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +subdir-ccflags-y += \ + -Iplatform/drivers/ana \ + -Iplatform/hal \ + -Iservices/bluedroid/adapter/src \ + -Iapps/key \ + -Iservices/audio_eq \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + $(BT_IF_INCLUDES) \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/nv_section/factory_section \ + -Iservices/resources \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iplatform/drivers/main \ + -Iplatform/drivers/norflash \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iutils/retention_ram \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/hwtimer_list/ \ + -Iutils/intersyshci \ + -Iutils/boot_struct \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iapps/factory \ + -Iapps/ota \ + -Iservices/ble_app \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/bridge/ \ + -Iservices/ble_stack/hl/src/gap/ \ + -Iservices/ble_stack/hl/src/gap/gapc/ \ + -Iservices/ble_stack/hl/src/gap/gapm/ \ + -Iservices/ble_stack/hl/src/gap/smpc/ \ + -Iservices/ble_stack/ke/src/ \ + -Iservices/ble_stack/hl/src/gatt/attc/ \ + -Iservices/ble_stack/hl/src/gatt/attm/ \ + -Iservices/ble_stack/hl/src/gatt/atts/ \ + -Iservices/ble_stack/hl/src/gatt/gattc/ \ + -Iservices/ble_stack/hl/src/gatt/gattm/ \ + -Iservices/ble_stack/hl/src/gatt/ \ + -Iservices/ble_stack/hl/src/l2c/l2cc/ \ + -Iservices/ble_stack/hl/src/l2c/l2cm/ \ + -Iservices/ble_stack/hci/api/ \ + -Iservices/ble_stack/hci/src/ \ + -Iservices/ble_stack/app/src/ \ + -Iservices/ble_profiles/htp/htpt/api/ \ + -Iservices/ble_profiles/htp/htpt/src/ \ + -Iservices/ble_profiles/htp/ \ + -Iservices/ble_profiles/datapath/datapathps/api/ \ + -Iservices/ble_app/app_main/ \ + -Iservices/ble_app/app_htp/ \ + -Iservices/ble_app/app_datapath/ \ + -Iservices/bt_app \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/ble_app/app_vob \ + -Iservices/multimedia/speech/codec/codecs/adpcm \ + -Iservices/ble_app/app_smartvoice \ + -Iservices/ble_profiles/smartvoice \ + -Iservices/anc_spp_tool \ + -Iutils/crc32 \ + -Ithirdparty/userapi \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/audio/codec/sbc/src/inc \ + -Iservices/app_tws/inc \ + -Iservices/app_ibrt/inc \ + -Iservices/ibrt_core/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/norflash_api diff --git a/services/ota/ota_common.cpp b/services/ota/ota_common.cpp new file mode 100644 index 0000000..69de47c --- /dev/null +++ b/services/ota/ota_common.cpp @@ -0,0 +1,1649 @@ +/** + * @file ota_common.cpp + * @author BES AI team + * @version 0.1 + * @date 2020-04-17 + * + * @copyright Copyright (c) 2015-2020 BES Technic. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + */ + +/*****************************header include********************************/ +#include "string.h" +#include "cmsis.h" +#include "hal_timer.h" +#include "norflash_drv.h" +#include "norflash_api.h" +#include "crc32.h" +#include "bt_drv_reg_op.h" +#include "app_bt.h" +#include "app.h" +#include "apps.h" +#include "nvrecord_ota.h" +#include "app_utils.h" +#include "ota_dbg.h" +#include "ota_common.h" + +#ifdef IBRT +#include "app_tws_ibrt.h" +#include "app_tws_ctrl_thread.h" +#include "app_ibrt_ota_cmd.h" +#include "app_tws_if.h" +#include "app_ibrt_ui.h" +#include "app_ibrt_if.h" +#endif + +/*********************external function declearation************************/ + +/************************private macro defination***************************/ +#define OTA_BOOT_INFO_FLASH_OFFSET 0x1000 +#define OTA_BREAKPOINT_STORE_GRANULARITY (256 * 1024) // must be 4KB aligned +#define LEN_OF_IMAGE_TAIL_TO_FIND_SANITY_CRC 512 +#define INVALID_VERSION_STR "BESTECHNIC" + +#define NORFLASH_API_MODE_ASYNC true +#define OTA_DEFAULT_NORFLASH_API_MODE NORFLASH_API_MODE_ASYNC + +#define CASES(prefix, item) \ + case prefix##item: \ + str = #item; \ + break; + +/************************private type defination****************************/ + +/**********************private function declearation************************/ + +/************************private variable defination************************/ +__attribute__((unused)) static const char *imageSanityKeyWord = "CRC32_OF_IMAGE=0x"; +__attribute__((unused)) static const char *oldImageSanityKeyWord = "CRC32_OF_IMAGE="; + +#ifdef IBRT +static void _ota_tws_thread(const void *arg); +osThreadDef(_ota_tws_thread, osPriorityNormal, 1, 1024, "ota_tws"); + +static osEvent evt; + +/// tws relay OTA command/data TX thread ID +osThreadId txThreadId = NULL; + +/// tws relay OTA command/data RX thread ID +osThreadId rxThreadId; + +osMutexDef(twsTxQueueMutex); +osMutexDef(twsRxQueueMutex); + +/// tws relay data TX queue mutex +osMutexId txQueueMutexID = NULL; + +/// tws relay data RX queue mutex +osMutexId rxQueueMutexID = NULL; + +uint8_t relayBuf[TWS_RELAY_DATA_MAX_SIZE]; +#endif + +OTA_COMMON_ENV_T otaEnv; + + +/****************************function defination****************************/ + +/** + * @brief Convert OTA command to string + * + * @param cmd @see OTA_COMMAND_E + * @return char* string of OTA_COMMAND + */ +static char *_cmd2str(OTA_COMMAND_E cmd) +{ + const char *str = NULL; + + switch (cmd) + { + CASES(OTA_COMMAND_, BEGIN); + CASES(OTA_COMMAND_, APPLY); + CASES(OTA_COMMAND_, DATA); + CASES(OTA_COMMAND_, ABORT); +#ifdef IBRT + CASES(OTA_COMMAND_, RSP); +#endif + // CASES(OTA_COMMAND_, ); + + default: + str = "INVALID"; + break; + } + + return (char *)str; +} + +/** + * @brief Convert OTA user to string + * + * @param user @see OTA_USER_E + * @return char* OTA_USER string + */ +static char *_user2str(OTA_USER_E user) +{ + const char *str = NULL; + + switch (user) + { + CASES(OTA_USER_, BES); + CASES(OTA_USER_, COLORFUL); + CASES(OTA_USER_, RED); + CASES(OTA_USER_, ORANGE); + CASES(OTA_USER_, GREEN); + // CASES(OTA_USER_, ); + + default: + str = "INVALID"; + break; + } + + return (char *)str; +} + +/** + * @brief Convert OTA path into string + * + * @param path @see OTA_PATH_E + * @return char* OTA_PATH string + */ +static char *_path2str(OTA_PATH_E path) +{ + const char *str = NULL; + + switch (path) + { + CASES(OTA_PATH_, BT); + CASES(OTA_PATH_, BLE); + // CASES(OTA_PATH_, ); + + default: + str = "INVALID"; + break; + } + + return (char *)str; +} + +/** + * @brief Convert OTA stage into string + * + * @param stage @see OTA_STAGE_E + * @return char* OTA_STAGE string + */ +static char *_stage2str(OTA_STAGE_E stage) +{ + const char *str = NULL; + + switch (stage) + { + CASES(OTA_STAGE_, IDLE); + CASES(OTA_STAGE_, ONGOING); + CASES(OTA_STAGE_, DONE); + // CASES(OTA_STAGE_, ); + + default: + str = "INVALID"; + break; + } + + return (char *)str; +} + +static char *_sts2str(OTA_STATUS_E sts) +{ + const char *str = NULL; + + switch (sts) + { + CASES(OTA_STATUS_, OK); + CASES(OTA_STATUS_, ERROR); + CASES(OTA_STATUS_, ERROR_RELAY_TIMEOUT); + CASES(OTA_STATUS_, ERROR_CHECKSUM); + CASES(OTA_STATUS_, ERROR_NOT_ALLOWED); + // CASES(OTA_STATUS_, ); + + default: + str = "INVALID"; + break; + } + + return (char *)str; +} + +/** + * @brief Find key word in upgrade data. + * + * This function is used to find out the key word at the end of upgrade data, + * these key words are generated by python script by calculate the crc of whole + * upgrade image and write the result at the end of the image in string format. + * This is used to do sanity check. + * + * @param tgtArray source array to search the key word + * @param tgtArrayLen source array length + * @param keyArray key word array + * @param keyArrayLen key word length + * @return int32_t index of the key word in dstArry + */ +__attribute__((unused)) static int32_t _find_key_word(uint8_t *tgtArray, + uint32_t tgtArrayLen, + uint8_t *keyArray, + uint32_t keyArrayLen) +{ + if ((keyArrayLen > 0) && (tgtArrayLen >= keyArrayLen)) + { + uint32_t index = 0, targetIndex = 0; + for (targetIndex = 0; targetIndex < tgtArrayLen; targetIndex++) + { + for (index = 0; index < keyArrayLen; index++) + { + if (tgtArray[targetIndex + index] != keyArray[index]) + { + break; + } + } + + if (index == keyArrayLen) + { + return targetIndex; + } + } + + return -1; + } + else + { + return -1; + } +} + +/** + * @brief Convert ASCII code into hex format. + * + * @param asciiCode ASCII code to convert + * @return uint8_t convert result + */ +__attribute__((unused)) static uint8_t _ascii2hex(uint8_t asciiCode) +{ + if ((asciiCode >= '0') && (asciiCode <= '9')) + { + return asciiCode - '0'; + } + else if ((asciiCode >= 'a') && (asciiCode <= 'f')) + { + return asciiCode - 'a' + 10; + } + else if ((asciiCode >= 'A') && (asciiCode <= 'F')) + { + return asciiCode - 'A' + 10; + } + else + { + return 0xff; + } +} + +/** + * @brief Update the stage of OTA progress. + * + * @param stage OTA stage to update, + * @see OTA_STAGE_E to get more details. + */ +static void _set_ota_stage(OTA_STAGE_E stage) +{ + LOG_D("stage update:%s->%s", + _stage2str(otaEnv.currentStage), + _stage2str(stage)); + + otaEnv.currentStage = stage; +} + +static void _update_ota_user(OTA_USER_E user) +{ + ASSERT((OTA_USER_NUM == otaEnv.currentUser) || (OTA_USER_NUM == user), + "try to set a ota user while the current user is not null"); + + LOG_I("ota user update:%s->%s", + _user2str(otaEnv.currentUser), + _user2str(user)); + + otaEnv.currentUser = user; +} + + +/** + * @brief Enter OTA state handler. + * + * This function is used to require the relative system resources to gurantee + * the performance for both OTA progress and other functionalities + * + * @param path Current OTA path, + * @see OTA_PATH_E to get more details. + */ +static void _enter_ota_state(OTA_PATH_E path) +{ + LOG_I("%s", __func__); + + if (otaEnv.isInOtaState) + { + LOG_W("ALREADY in OTA state"); + } + else + { + /// 1. guarantee performance->switch to the highest freq + app_sysfreq_req(APP_SYSFREQ_USER_OTA, APP_SYSFREQ_104M); + +#ifdef IBRT + /// 2. guarantee performance->decrease the communication interval of TWS connection + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + btdrv_reg_op_set_tws_link_duration(IBRT_TWS_LINK_LARGE_DURATION); + btdrv_reg_op_set_private_tws_poll_interval(p_ibrt_ctrl->config.default_private_poll_interval, + p_ibrt_ctrl->config.default_private_poll_interval_in_sco); + + /// 3. guarantee performance->exit bt sniff mode + app_ibrt_ui_judge_link_policy(OTA_START_TRIGGER, BTIF_BLP_DISABLE_ALL); + + if (app_tws_ibrt_tws_link_connected() && \ + (p_ibrt_ctrl->nv_role == IBRT_MASTER) && \ + p_ibrt_ctrl->p_tws_remote_dev) + { + btif_me_stop_sniff(p_ibrt_ctrl->p_tws_remote_dev); + } + + app_ibrt_if_tws_sniff_block(15); +#else + /// 3. guarantee performance->exit bt sniff mode + app_bt_active_mode_set(ACTIVE_MODE_KEEPER_OTA, UPDATE_ACTIVE_MODE_FOR_ALL_LINKS); +#endif + + /// update the OTA path + LOG_I("OTA path update:%s->%s", _path2str(otaEnv.currentPath), _path2str(path)); + otaEnv.currentPath = path; + + /// 4. guarantee performance->decrease the BLE connection interval +#ifdef BLE_ENABLE + if (OTA_PATH_BLE == otaEnv.currentPath) + { + app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_OTA, true); + } +#endif + } +} + +/** + * @brief Exit the OTA state handler. + * + * This function is used to release the system resources which are required + * when enter the OTA state + * + */ +__attribute__((unused)) static void _exit_ota_state(void) +{ + LOG_I("%s", __func__); + + if (otaEnv.isInOtaState) + { +#ifdef IBRT + app_ibrt_ui_judge_link_policy(OTA_STOP_TRIGGER, BTIF_BLP_SNIFF_MODE); +#else + app_bt_active_mode_clear(ACTIVE_MODE_KEEPER_OTA, UPDATE_ACTIVE_MODE_FOR_ALL_LINKS); +#endif + + /// release the short TWS communication interval +#ifdef IBRT + ibrt_ctrl_t *p_ibrt_ctrl = app_tws_ibrt_get_bt_ctrl_ctx(); + btdrv_reg_op_set_tws_link_duration(IBRT_TWS_LINK_DEFAULT_DURATION); + btdrv_reg_op_set_private_tws_poll_interval(p_ibrt_ctrl->config.long_private_poll_interval, + p_ibrt_ctrl->config.default_private_poll_interval_in_sco); +#endif + + /// release the short BLE connection interval +#ifdef BLE_ENABLE + app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_OTA, false); + app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_OTA_SLOWER, false); +#endif + + /// update the OTA path to invalid + otaEnv.currentPath = OTA_PATH_INVALID; + + /// release the system frequency + app_sysfreq_req(APP_SYSFREQ_USER_OTA, APP_SYSFREQ_32K); + + otaEnv.isInOtaState = false; + } + else + { + LOG_W("NOT in OTA STATE"); + } +} + +#ifdef IBRT + +/** + * @brief Do the sanity check for the upgrade file. + * + * Currently, this function uses the CRC that was inserted by the build process. + * This CRC check does not verify the last x bytes of the image. x varies + * depending on order of the key/value pair order but is < 512 bytes. + * + * @return true Sanity check success. + * @return false Sanity check failed. + */ +static bool _image_sanity_check(void) +{ + // find the location of the CRC key word string + uint8_t *ptrOfTheLast4KImage = (uint8_t *)(OTA_FLASH_LOGIC_ADDR + + NEW_IMAGE_FLASH_OFFSET + + otaEnv.totalImageSize - + LEN_OF_IMAGE_TAIL_TO_FIND_SANITY_CRC); + + uint32_t sanityCrc32; + uint32_t crc32ImageOffset; + int32_t sanity_crc_location = _find_key_word(ptrOfTheLast4KImage, + LEN_OF_IMAGE_TAIL_TO_FIND_SANITY_CRC, + (uint8_t *)imageSanityKeyWord, + strlen(imageSanityKeyWord)); + if (-1 == sanity_crc_location) + { + sanity_crc_location = _find_key_word(ptrOfTheLast4KImage, + LEN_OF_IMAGE_TAIL_TO_FIND_SANITY_CRC, + (uint8_t *)oldImageSanityKeyWord, + strlen(oldImageSanityKeyWord)); + if (-1 == sanity_crc_location) + { + // if no sanity crc, fail the check + return false; + } + else + { + crc32ImageOffset = sanity_crc_location + + otaEnv.totalImageSize - + LEN_OF_IMAGE_TAIL_TO_FIND_SANITY_CRC + + strlen(oldImageSanityKeyWord); + sanityCrc32 = *(uint32_t *)(OTA_FLASH_LOGIC_ADDR + NEW_IMAGE_FLASH_OFFSET + crc32ImageOffset); + } + } + else + { + crc32ImageOffset = sanity_crc_location + + otaEnv.totalImageSize - + LEN_OF_IMAGE_TAIL_TO_FIND_SANITY_CRC + + strlen(imageSanityKeyWord); + + sanityCrc32 = 0; + uint8_t *crcString = (uint8_t *)(OTA_FLASH_LOGIC_ADDR + NEW_IMAGE_FLASH_OFFSET + crc32ImageOffset); + + for (uint8_t index = 0; index < 8; index++) + { + sanityCrc32 |= (_ascii2hex(crcString[index]) << (28 - 4 * index)); + } + } + + LOG_D("Bytes to generate crc32 is %d", crc32ImageOffset); + LOG_D("sanity_crc_location is %d", sanity_crc_location); + + LOG_D("sanityCrc32 is 0x%x", sanityCrc32); + + // generate the CRC from image data + uint32_t calculatedCrc32 = 0; + calculatedCrc32 = crc32(calculatedCrc32, (uint8_t *)(OTA_FLASH_LOGIC_ADDR + NEW_IMAGE_FLASH_OFFSET), crc32ImageOffset); + + LOG_D("calculatedCrc32 is 0x%x", calculatedCrc32); + + if (sanityCrc32 == calculatedCrc32) + { + return true; + } + + return false; +} + +static enum NORFLASH_API_MODULE_ID_T +_get_flash_module_from_ota_device(OTA_DEVICE_E device) +{ + enum NORFLASH_API_MODULE_ID_T mod = NORFLASH_API_MODULE_ID_COUNT; + + switch (device) + { + case OTA_DEVICE_APP: + mod = NORFLASH_API_MODULE_ID_OTA; + break; + case OTA_DEVICE_HOTWORD: + mod = NORFLASH_API_MODULE_ID_HOTWORD_MODEL; + break; + + default: + ASSERT(0, "invalid OTA device received in %s", __func__); + break; + } + + return mod; +} + +static void _flush_data_to_flash(uint8_t *ptrSource, + uint32_t lengthToBurn, + uint32_t offsetInFlashToProgram, + bool synWrite) +{ + + LOG_D("flush %d bytes to flash offset 0x%x", lengthToBurn, offsetInFlashToProgram); + enum NORFLASH_API_MODULE_ID_T mod = _get_flash_module_from_ota_device(otaEnv.deviceId); + + uint32_t preBytes = (FLASH_SECTOR_SIZE_IN_BYTES - + (offsetInFlashToProgram % FLASH_SECTOR_SIZE_IN_BYTES)) % + FLASH_SECTOR_SIZE_IN_BYTES; + + if (lengthToBurn < preBytes) + { + preBytes = lengthToBurn; + } + + uint32_t middleBytes = 0; + if (lengthToBurn > preBytes) + { + middleBytes = ((lengthToBurn - preBytes) / FLASH_SECTOR_SIZE_IN_BYTES * FLASH_SECTOR_SIZE_IN_BYTES); + } + + uint32_t postBytes = 0; + if (lengthToBurn > (preBytes + middleBytes)) + { + postBytes = (offsetInFlashToProgram + lengthToBurn) % FLASH_SECTOR_SIZE_IN_BYTES; + } + + LOG_D("Prebytes is %d middlebytes is %d postbytes is %d", preBytes, middleBytes, postBytes); + + if (preBytes > 0) + { + app_flash_page_program(mod, offsetInFlashToProgram, ptrSource, preBytes, synWrite); + + ptrSource += preBytes; + offsetInFlashToProgram += preBytes; + } + + uint32_t sectorIndexInFlash = offsetInFlashToProgram / FLASH_SECTOR_SIZE_IN_BYTES; + + if (middleBytes > 0) + { + uint32_t sectorCntToProgram = middleBytes / FLASH_SECTOR_SIZE_IN_BYTES; + for (uint32_t sector = 0; sector < sectorCntToProgram; sector++) + { + app_flash_page_erase(mod, sectorIndexInFlash * FLASH_SECTOR_SIZE_IN_BYTES); + app_flash_page_program(mod, + sectorIndexInFlash * FLASH_SECTOR_SIZE_IN_BYTES, + ptrSource + sector * FLASH_SECTOR_SIZE_IN_BYTES, + FLASH_SECTOR_SIZE_IN_BYTES, + synWrite); + + sectorIndexInFlash++; + } + + ptrSource += middleBytes; + } + + if (postBytes > 0) + { + app_flash_page_erase(mod, sectorIndexInFlash * FLASH_SECTOR_SIZE_IN_BYTES); + app_flash_page_program(mod, + sectorIndexInFlash * FLASH_SECTOR_SIZE_IN_BYTES, + ptrSource, + postBytes, + synWrite); + } + + app_flush_pending_flash_op(mod, NORFLASH_API_ALL); +} + +/** + * NOTE that this function is stil needed since the OTA bootloader uses the CRC + * that is passed into it to re-verify the image and that CRC is for the entire + * image. + */ +static bool _compute_whole_image_crc(void) +{ + uint32_t processedDataSize = 0; + uint32_t crc32Value = 0; + uint32_t bytes_to_use = 0; + uint32_t lock; + + while (processedDataSize < otaEnv.totalImageSize) + { + if (otaEnv.totalImageSize - processedDataSize > OTA_DATA_CACHE_BUFFER_SIZE) + { + bytes_to_use = OTA_DATA_CACHE_BUFFER_SIZE; + } + else + { + bytes_to_use = otaEnv.totalImageSize - processedDataSize; + } + + lock = int_lock_global(); + norflash_sync_read(NORFLASH_API_MODULE_ID_OTA, + (OTA_FLASH_LOGIC_ADDR + NEW_IMAGE_FLASH_OFFSET + processedDataSize), + otaEnv.dataCacheBuffer, + OTA_DATA_CACHE_BUFFER_SIZE); + // memcpy(otaEnv.dataCacheBuffer, (uint8_t *)(OTA_FLASH_LOGIC_ADDR + NEW_IMAGE_FLASH_OFFSET + processedDataSize), + // OTA_DATA_CACHE_BUFFER_SIZE); + int_unlock_global(lock); + + if (0 == processedDataSize) + { + if (*(uint32_t *)otaEnv.dataCacheBuffer != NORMAL_BOOT) + { + LOG_D("first 32bit value is not NORMAL_BOOT"); + return false; + } + else + { + *(uint32_t *)otaEnv.dataCacheBuffer = 0xFFFFFFFF; + } + } + + LOG_D("bytes to verify =%d.", bytes_to_use); + + crc32Value = crc32(crc32Value, (uint8_t *)otaEnv.dataCacheBuffer, bytes_to_use); + + processedDataSize += bytes_to_use; + } + + LOG_D("Computed CRC32 is 0x%x.", crc32Value); + + /* This crc value will be passed to the ota app in GSoundOtaApply(). */ + otaEnv.crc32OfImage = crc32Value; + return true; +} + +static void _update_boot_info(OTA_BOOT_INFO_T *otaBootInfo) +{ + ASSERT(OTA_DEVICE_APP == otaEnv.deviceId, "illegal OTA device try to update boot info"); + hal_norflash_disable_protection(HAL_NORFLASH_ID_0); + enum NORFLASH_API_MODULE_ID_T mod = _get_flash_module_from_ota_device(otaEnv.deviceId); + app_flash_page_erase(mod, OTA_BOOT_INFO_FLASH_OFFSET); + app_flash_page_program(mod, + OTA_BOOT_INFO_FLASH_OFFSET, + (uint8_t *)otaBootInfo, + sizeof(OTA_BOOT_INFO_T), + true); +} + +static void _update_magic_number(uint32_t newMagicNumber) +{ + ASSERT(OTA_DEVICE_APP == otaEnv.deviceId, "illegal device %d to update magic number", + otaEnv.deviceId); + memcpy(otaEnv.dataCacheBuffer, + (uint8_t *)(OTA_FLASH_LOGIC_ADDR + otaEnv.newImageFlashOffset), + FLASH_SECTOR_SIZE_IN_BYTES); + + *(uint32_t *)otaEnv.dataCacheBuffer = newMagicNumber; + enum NORFLASH_API_MODULE_ID_T mod = _get_flash_module_from_ota_device(otaEnv.deviceId); + app_flash_page_erase(mod, otaEnv.newImageFlashOffset); + + app_flash_page_program(mod, + otaEnv.newImageFlashOffset, + otaEnv.dataCacheBuffer, + FLASH_SECTOR_SIZE_IN_BYTES, + true); + + app_flush_pending_flash_op(mod, NORFLASH_API_ALL); +} + +static void _update_peer_result(OTA_STATUS_E ret) +{ + LOG_D("update peer result:%s->%s", + _sts2str(otaEnv.peerResult), + _sts2str(ret)); + + otaEnv.peerResult = ret; +} + +OTA_STATUS_E ota_common_get_peer_result(void) +{ + return otaEnv.peerResult; +} + +static bool _relay_data_needed(void) +{ + bool ret = true; + + if (!app_tws_ibrt_tws_link_connected()) + { + ret = false; + } + + if (OTA_STAGE_IDLE == otaEnv.currentStage) + { + ret = false; + } + + /// check the customized relay_data_needed permission + if (ret && otaEnv.customRelayNeededHandler) + { + ret = otaEnv.customRelayNeededHandler(); + } + + return ret; +} + +static void _ota_relay_data(OTA_COMMAND_E cmdType, + const uint8_t *dataPtr, + uint16_t length) +{ + uint8_t frameNum = 0; + uint16_t frameLen = 0; + OTA_TWS_DATA_T tCmd = { + cmdType, + }; + + ASSERT(length <= ARRAY_SIZE(tCmd.data), "ILLEGAL relay packet length"); + + /// split packet into servel frame to fulfill the max TWS data + /// transmission length requirement + if (length % OTA_TWS_PAYLOAD_MAX_LEN) + { + frameNum = length / OTA_TWS_PAYLOAD_MAX_LEN + 1; + } + else + { + frameNum = length / OTA_TWS_PAYLOAD_MAX_LEN; + } + + LOG_D("packet len:%d, splited frame num:%d", length, frameNum); + + /// push all data into queue + for (uint8_t i = 0; i < frameNum; i++) + { + if ((i + 1) == frameNum) + { + tCmd.magicCode = OTA_RELAY_PACKET_MAGIC_CODE_COMPLETE; + tCmd.length = length % OTA_TWS_PAYLOAD_MAX_LEN; + } + else + { + tCmd.magicCode = OTA_RELAY_PACKET_MAGIC_CODE_INCOMPLETE; + tCmd.length = OTA_TWS_PAYLOAD_MAX_LEN; + } + + frameLen = OTA_TWS_HEAD_SIZE + tCmd.length; + + memcpy(tCmd.data, dataPtr + i * OTA_TWS_PAYLOAD_MAX_LEN, tCmd.length); + + osMutexWait(txQueueMutexID, osWaitForever); + ASSERT(CQ_OK == EnCQueue(&otaEnv.txQueue, (CQItemType *)&frameLen, sizeof(frameLen)), + "%s failed to push data to queue", __func__); + ASSERT(CQ_OK == EnCQueue(&otaEnv.txQueue, (CQItemType *)&tCmd, frameLen), + "%s failed to push data to queue", __func__); + osMutexRelease(txQueueMutexID); + } + + /// inform tx thread to handle the data to be transmitted + osSignalSet(txThreadId, OTA_TWS_TX_SIGNAL); +} + +/** + * @brief Check the validity of received data frame. + * + * @param dataPtr Pointer of received data + * @param length length of received data + * @return true Received data frame is valid + * @return false Received data frame is invalid + */ +static bool _tws_frame_validity_check(uint8_t *dataPtr, uint32_t length) +{ + bool isValid = true; + + OTA_TWS_DATA_T *otaTwsData = (OTA_TWS_DATA_T *)dataPtr; + + ASSERT(TWS_RELAY_DATA_MAX_SIZE >= length, "received overloaded data packet!!!"); + if (OTA_RELAY_PACKET_MAGIC_CODE_INCOMPLETE == otaEnv.currentMagicCode && + otaTwsData->cmdType != otaEnv.currentCmdType) + { + ASSERT(0, "bad frame is received!!!"); + } + + if (length != otaTwsData->length + OTA_TWS_HEAD_SIZE) + { + LOG_W("INVALID packet, dataLen:%d, expected dataLen:%d", + length, + otaTwsData->length + OTA_TWS_HEAD_SIZE); + isValid = false; + } + + if (OTA_RELAY_PACKET_MAGIC_CODE_COMPLETE != otaTwsData->magicCode && + OTA_RELAY_PACKET_MAGIC_CODE_INCOMPLETE != otaTwsData->magicCode) + { + LOG_W("INVALID magic code:0x%08x", otaTwsData->magicCode); + isValid = false; + } + + return isValid; +} + +/** + * @brief Response the master for the OTA_COMMAND received. + * + * This function will response the master after a whole packet receiving is + * done. + * + * @param status Status of receiving TWS relay data + */ +static void _tws_rsp(OTA_STATUS_E status) +{ + LOG_D("[%s] status:%s", __func__, _sts2str(status)); + + OTA_STATUS_E rsp = status; + _ota_relay_data(OTA_COMMAND_RSP, (const uint8_t *)&rsp, sizeof(rsp)); +} +#endif + +OTA_COMMON_ENV_T *ota_common_get_env(void) +{ + return &otaEnv; +} + +/** + * @brief Reset the OTA environment. + * + */ +static void _reset_env(void) +{ + LOG_D("[%s]", __func__); + memset(&otaEnv, 0, sizeof(otaEnv)); + +#ifdef __APP_USER_DATA_NV_FLASH_OFFSET__ + otaEnv.userDataNvFlashOffset = __APP_USER_DATA_NV_FLASH_OFFSET__; +#else + otaEnv.userDataNvFlashOffset = hal_norflash_get_flash_total_size(HAL_NORFLASH_ID_0) - 2 * 4096; +#endif + + otaEnv.flashOffsetOfUserDataPool = otaEnv.userDataNvFlashOffset; + _update_ota_user(OTA_USER_NUM); + +#ifdef OTA_NVRAM + // gOtaCtx.cfg.clearUserData = false; + // gOtaCtx.flashOffsetOfFactoryDataPool = + // otaEnv.otaCommon->userDataNvFlashOffset + FLASH_SECTOR_SIZE_IN_BYTES; +#endif + +#ifdef IBRT + /// init tws TX queue + osMutexWait(txQueueMutexID, osWaitForever); + InitCQueue(&(otaEnv.txQueue), ARRAY_SIZE(otaEnv.txBuf), (CQItemType *)otaEnv.txBuf); + osMutexRelease(txQueueMutexID); + + /// init tws RX queue + osMutexWait(rxQueueMutexID, osWaitForever); + InitCQueue(&(otaEnv.rxQueue), ARRAY_SIZE(otaEnv.rxBuf), (CQItemType *)otaEnv.rxBuf); + osMutexRelease(rxQueueMutexID); +#endif +} + +void ota_common_init_handler(void) +{ + LOG_D("[%s]", __func__); + + /// init OTA related nvrecord pointer + nv_record_ota_init(); + + /// init common used flash module + ota_common_init_flash((uint8_t)NORFLASH_API_MODULE_ID_OTA, + 0, + (OTA_FLASH_LOGIC_ADDR + ( +#ifdef __APP_USER_DATA_NV_FLASH_OFFSET__ + __APP_USER_DATA_NV_FLASH_OFFSET__ +#else + (hal_norflash_get_flash_total_size(HAL_NORFLASH_ID_0) - 2 * 4096) +#endif + & 0xffffff)), + 0); + +#ifdef IBRT + if (txThreadId == NULL) + { + txThreadId = osThreadCreate(osThread(_ota_tws_thread), NULL); + } + + /// init tws TX queue mutex + if (txQueueMutexID == NULL) + { + txQueueMutexID = osMutexCreate((osMutex(twsTxQueueMutex))); + } + + /// init tws RX queue mutex + if (rxQueueMutexID == NULL) + { + rxQueueMutexID = osMutexCreate((osMutex(twsRxQueueMutex))); + } +#endif + + _reset_env(); +} + +void ota_common_enable_sanity_check(bool enable) +{ + LOG_I("sanity check enable state update:%d->%d", + otaEnv.sanityCheckEnable, enable); + otaEnv.sanityCheckEnable = enable; +} + +void ota_common_init_flash(uint8_t module, + uint32_t baseAddr, + uint32_t len, + uint32_t imageHandler) +{ + enum NORFLASH_API_RET_T ret; + uint32_t block_size = 0; + uint32_t sector_size = 0; + uint32_t page_size = 0; + + hal_norflash_get_size(HAL_NORFLASH_ID_0, + NULL, + &block_size, + §or_size, + &page_size); + + LOG_I("%s module:%d, startAddr:0x%x, len:0x%x", __func__, module, baseAddr, len); + ret = norflash_api_register((NORFLASH_API_MODULE_ID_T)module, + HAL_NORFLASH_ID_0, + baseAddr, + len, + block_size, + sector_size, + page_size, + OTA_NORFLASH_BUFFER_LEN, + (NORFLASH_API_OPERA_CB)imageHandler); + + ASSERT(ret == NORFLASH_API_OK, + "ota_init_flash: norflash_api register failed,ret = %d.", + ret); + +#ifdef FLASH_SUSPEND + norflash_suspend_check_irq(AUDMA_IRQn); + norflash_suspend_check_irq(ISDATA_IRQn); + norflash_suspend_check_irq(ISDATA1_IRQn); +#endif +} + +bool ota_common_is_in_progress(void) +{ + bool ret = false; + + if (OTA_STAGE_IDLE != otaEnv.currentStage) + { + ret = true; + } + + return ret; +} + +void ota_common_registor_command_handler(OTA_COMMAND_E cmdType, + void *cmdHandler) +{ + if (otaEnv.cmdHandler[cmdType]) + { + LOG_W("handler for OTA command %d is not NULL", cmdType); + } + + otaEnv.cmdHandler[cmdType] = (OTA_CMD_HANDLER_T)cmdHandler; +} + +OTA_STATUS_E ota_common_command_received_handler(OTA_COMMAND_E cmdType, + void *cmdInfo, + uint16_t cmdLen) +{ + LOG_D("cmd received:%s", _cmd2str(cmdType)); + otaEnv.status = OTA_STATUS_OK; + OTA_STATUS_E temp = OTA_STATUS_OK; + + /// init OTA progress when received begin command + if (OTA_COMMAND_BEGIN == cmdType) + { + ASSERT(OTA_STAGE_IDLE == otaEnv.currentStage, "Received begin command while not in IDLE stage"); + OTA_BEGIN_PARAM_T *c = (OTA_BEGIN_PARAM_T *)cmdInfo; + + /// update the ota user to ota common layer + _update_ota_user(c->user); + + /// update the new image size according to the image size param + LOG_I("total image size update:%d->%d", otaEnv.totalImageSize, c->imageSize); + otaEnv.totalImageSize = c->imageSize; + + /// update the new image offset according to the start offset param + ASSERT(0 == (c->startOffset % FLASH_SECTOR_SIZE_IN_BYTES), + "Resumed start offset is not 4KB aligned!"); + LOG_I("programOffset&receivedDataSize is update:%d->%d", + otaEnv.newImageProgramOffset, + c->startOffset); + otaEnv.newImageProgramOffset = c->startOffset; + otaEnv.receivedDataSize = c->startOffset; + + /// update the device index + LOG_I("deviceId update:%d->%d", otaEnv.deviceId, c->device); + otaEnv.deviceId = c->device; + + /// update the version info and version length + memcpy(otaEnv.version, c->version, c->versionLen); + otaEnv.versionLen = c->versionLen; + + /// update the flash offset of new image + LOG_I("newImageFlashOffset update:0x%02x->0x%02x", otaEnv.newImageFlashOffset, c->flashOffset); + otaEnv.newImageFlashOffset = c->flashOffset; + + /// set the OTA stage to ongoing + _set_ota_stage(OTA_STAGE_ONGOING); + + /// system layer configurations to guarentee the performance + /// of all functionalities + _enter_ota_state(c->path); + } + + /// execute the custom configuration + if(OTA_COMMAND_NUM != cmdType) + { + if (otaEnv.cmdHandler[cmdType]) + { + temp = otaEnv.cmdHandler[cmdType](cmdInfo, cmdLen); + LOG_I("ota command %s handle done, status:%s", _cmd2str(cmdType), _sts2str(temp)); + + if (OTA_STATUS_OK != temp) + { + otaEnv.status = temp; + } + } + else + { + LOG_W("ota cmd %s is not handled by customor", _cmd2str(cmdType)); + } + } + else + { + LOG_E("INVALID cmd:%d", cmdType); + } + + /// update the OTA progress + if (OTA_STATUS_OK == otaEnv.status) + { + if (!nv_record_ota_update_info(otaEnv.currentUser, + otaEnv.deviceId, + otaEnv.currentStage, + otaEnv.totalImageSize, + otaEnv.version)) + { + LOG_W("update info failed"); + otaEnv.status = OTA_STATUS_ERROR; + } + } + + /// special process for OTA_ABORT&&OTA_APPLY command + if ((OTA_COMMAND_ABORT == cmdType) || + (OTA_COMMAND_APPLY == cmdType)) + { + _reset_env(); + } + + LOG_I("%s cmd process result:%s", __func__, _sts2str(otaEnv.status)); + return otaEnv.status; +} + +#ifdef OTA_NVRAM +static void ota_update_nv_data(void) +{ + if (otaEnv.configuration.isToClearUserData) + { + enum NORFLASH_API_MODULE_ID_T mod = _get_flash_module_from_ota_device(otaEnv.deviceId); + app_flash_page_erase(mod, sectorIndexInFlash * FLASH_SECTOR_SIZE_IN_BYTES); + } + + if (otaEnv.configuration.isToRenameBT || + otaEnv.configuration.isToRenameBLE || + otaEnv.configuration.isToUpdateBTAddr || + otaEnv.configuration.isToUpdateBLEAddr) + { + uint32_t *pOrgFactoryData, *pUpdatedFactoryData; + pOrgFactoryData = (uint32_t *)(OTA_FLASH_LOGIC_ADDR + otaEnv.flashOffsetOfFactoryDataPool); + memcpy(otaEnv.dataCacheBuffer, (uint8_t *)pOrgFactoryData, FLASH_SECTOR_SIZE_IN_BYTES); + pUpdatedFactoryData = (uint32_t *)&(otaEnv.dataCacheBuffer); + + if (NVREC_DEV_VERSION_1 == nv_record_dev_rev) + { + if (otaEnv.configuration.isToRenameBT) + { + memset((uint8_t *)(pUpdatedFactoryData + dev_name), + 0, + sizeof(uint32_t) * (dev_bt_addr - dev_name)); + + memcpy((uint8_t *)(pUpdatedFactoryData + dev_name), + (uint8_t *)(otaEnv.configuration.newBTName), + NAME_LENGTH); + } + + if (otaEnv.configuration.isToUpdateBTAddr) + { + memcpy((uint8_t *)(pUpdatedFactoryData + dev_bt_addr), + (uint8_t *)(otaEnv.configuration.newBTAddr), + BD_ADDR_LENGTH); + } + + if (otaEnv.configuration.isToUpdateBLEAddr) + { + memcpy((uint8_t *)(pUpdatedFactoryData + dev_ble_addr), + (uint8_t *)(otaEnv.configuration.newBLEAddr), + BD_ADDR_LENGTH); + } + + pUpdatedFactoryData[dev_crc] = crc32(0, + (uint8_t *)(&pUpdatedFactoryData[dev_reserv1]), + (dev_data_len - dev_reserv1) * sizeof(uint32_t)); + } + else + { + if (otaEnv.configuration.isToRenameBT) + { + memset((uint8_t *)(pUpdatedFactoryData + rev2_dev_name), + 0, + sizeof(uint32_t) * (rev2_dev_bt_addr - rev2_dev_name)); + + memcpy((uint8_t *)(pUpdatedFactoryData + rev2_dev_name), + (uint8_t *)(otaEnv.configuration.newBTName), + NAME_LENGTH); + } + + if (otaEnv.configuration.isToRenameBLE) + { + memset((uint8_t *)(pUpdatedFactoryData + rev2_dev_ble_name), + 0, + sizeof(uint32_t) * (rev2_dev_section_end - rev2_dev_ble_name)); + + memcpy((uint8_t *)(pUpdatedFactoryData + rev2_dev_ble_name), + (uint8_t *)(otaEnv.configuration.newBleName), + BLE_NAME_LEN_IN_NV); + } + + if (otaEnv.configuration.isToUpdateBTAddr) + { + memcpy((uint8_t *)(pUpdatedFactoryData + rev2_dev_bt_addr), + (uint8_t *)(otaEnv.configuration.newBTAddr), + BD_ADDR_LENGTH); + } + + if (otaEnv.configuration.isToUpdateBLEAddr) + { + memcpy((uint8_t *)(pUpdatedFactoryData + rev2_dev_ble_addr), + (uint8_t *)(otaEnv.configuration.newBLEAddr), + BD_ADDR_LENGTH); + } + + pUpdatedFactoryData[dev_crc] = crc32(0, + (uint8_t *)(&pUpdatedFactoryData[rev2_dev_section_start_reserved]), + pUpdatedFactoryData[rev2_dev_data_len]); + } + + enum NORFLASH_API_MODULE_ID_T mod = _get_flash_module_from_ota_device(otaEnv.deviceId); + app_flash_page_erase(mod, sectorIndexInFlash * FLASH_SECTOR_SIZE_IN_BYTES); + + app_flash_page_program(mod, + otaEnv.flashOffsetOfFactoryDataPool, + (uint8_t *)pUpdatedFactoryData, + FLASH_SECTOR_SIZE_IN_BYTES); + } +} +#endif + +#ifdef IBRT +void ota_common_registor_relay_needed_handler(void *handler) +{ + if (otaEnv.customRelayNeededHandler) + { + LOG_W("handler for custom relay needed judge is not NULL"); + } + + otaEnv.customRelayNeededHandler = (CUSTOM_RELAY_NEEDED_FUNC_T)handler; +} + +void ota_common_registor_peer_cmd_received_handler(void *handler) +{ + if (otaEnv.peerCmdReceivedHandler) + { + LOG_W("handler for peer cmd received is not NULL"); + } + + otaEnv.peerCmdReceivedHandler = (PEER_CMD_RECEIVED_HANDLER_T)handler; +} + +OTA_STATUS_E ota_common_relay_data_to_peer(OTA_COMMAND_E cmdType, const uint8_t *data, uint16_t len) +{ + OTA_STATUS_E status = OTA_STATUS_OK; + if (_relay_data_needed()) + { + _ota_relay_data(cmdType, (const uint8_t *)data, len); + } + else + { + status = OTA_STATUS_ERROR; + } + + return status; +} + +OTA_STATUS_E ota_common_receive_peer_rsp(void) +{ + OTA_STATUS_E status = OTA_STATUS_OK; + + if (_relay_data_needed()) + { + /// get current thread ID as tws rx thread + rxThreadId = osThreadGetId(); + + /// pending current thread to waitting for slave response + evt = osSignalWait(OTA_TWS_RX_SIGNAL, OTA_TWS_RELAY_WAITTIME); + + if (evt.status == osEventTimeout) + { + status = OTA_STATUS_ERROR_RELAY_TIMEOUT; + LOG_W("[%s]SignalWait TIMEOUT!", __func__); + } + else if (osEventSignal == evt.status) + { + status = ota_common_get_peer_result(); + } + + ///.clear the excute result of this time + _update_peer_result(OTA_STATUS_OK); + } + else + { + status = OTA_STATUS_ERROR; + } + + return status; +} + +OTA_STATUS_E ota_common_fw_data_write(const uint8_t *data, uint16_t len) +{ + OTA_STATUS_E status = OTA_STATUS_OK; + uint16_t leftDataSize = len; + uint32_t offsetInReceivedRawData = 0; + + do + { + uint32_t bytesToCopy; + // copy to data buffer + if ((otaEnv.dataCacheBufferOffset + leftDataSize) > + OTA_DATA_CACHE_BUFFER_SIZE) + { + bytesToCopy = OTA_DATA_CACHE_BUFFER_SIZE - + otaEnv.dataCacheBufferOffset; + } + else + { + bytesToCopy = leftDataSize; + } + + leftDataSize -= bytesToCopy; + + memcpy(&otaEnv.dataCacheBuffer[otaEnv.dataCacheBufferOffset], + &data[offsetInReceivedRawData], + bytesToCopy); + offsetInReceivedRawData += bytesToCopy; + otaEnv.dataCacheBufferOffset += bytesToCopy; + + ASSERT(otaEnv.dataCacheBufferOffset <= OTA_DATA_CACHE_BUFFER_SIZE, + "bad math in %s", + __func__); + if (OTA_DATA_CACHE_BUFFER_SIZE == otaEnv.dataCacheBufferOffset) + { + _flush_data_to_flash(otaEnv.dataCacheBuffer, + OTA_DATA_CACHE_BUFFER_SIZE, + (otaEnv.newImageProgramOffset + + otaEnv.newImageFlashOffset), + false); + otaEnv.newImageProgramOffset += OTA_DATA_CACHE_BUFFER_SIZE; + otaEnv.dataCacheBufferOffset = 0; + } + } while (offsetInReceivedRawData < len); + + otaEnv.receivedDataSize += len; + + // check whether all image data has been received + if (otaEnv.receivedDataSize == otaEnv.totalImageSize) + { + LOG_D("The final image programming and crc32 check."); + + // flush any partial buffer to flash + if (otaEnv.dataCacheBufferOffset != 0) + { + _flush_data_to_flash(otaEnv.dataCacheBuffer, + otaEnv.dataCacheBufferOffset, + (otaEnv.newImageProgramOffset + + otaEnv.newImageFlashOffset), + true); + } + + if (OTA_DEVICE_APP == otaEnv.deviceId) + { + bool check = true; + + /// check the sanity if required + if (otaEnv.sanityCheckEnable) + { + check = _image_sanity_check(); + } + + if (check) + { + /// update the magic code of the application image + _update_magic_number(NORMAL_BOOT); + + /// check the crc32 of the received image data + if (_compute_whole_image_crc()) + { + LOG_I("Whole image verification pass."); + + /// update the OTA stage to OTA done + _set_ota_stage(OTA_STAGE_DONE); + } + else + { + LOG_W("image verification failed @%d", __LINE__); + + /// update the OTA stage to OTA idle + _set_ota_stage(OTA_STAGE_IDLE); + } + } + else + { + /// sanity check failed + LOG_W("image verification failed @%d", __LINE__); + + /// update the OTA stage to OTA idle + _set_ota_stage(OTA_STAGE_IDLE); + } + } + else + { + LOG_I("download finished, device:%d", otaEnv.deviceId); + + /// update the OTA stage to OTA idle + _set_ota_stage(OTA_STAGE_DONE); + } + + /// whole image verification failed somehow + if (OTA_STAGE_IDLE == otaEnv.currentStage) + { + nv_record_ota_update_info(otaEnv.currentUser, + otaEnv.deviceId, + otaEnv.currentStage, + 0, + INVALID_VERSION_STR); + + status = OTA_STATUS_ERROR_CHECKSUM; + } + else //!< whole image verification passed + { + nv_record_ota_update_info(otaEnv.currentUser, + otaEnv.deviceId, + otaEnv.currentStage, + otaEnv.totalImageSize, + otaEnv.version); + } + + /// exit the OTA state + _exit_ota_state(); + } + else //!< whole image revceive not finished + { + LOG_D("Received image size:%d", otaEnv.receivedDataSize); + + /// update the break point if it is changed + if ((otaEnv.receivedDataSize - otaEnv.breakPoint) >= + OTA_BREAKPOINT_STORE_GRANULARITY) + { + otaEnv.breakPoint = (otaEnv.receivedDataSize / + OTA_BREAKPOINT_STORE_GRANULARITY) * + OTA_BREAKPOINT_STORE_GRANULARITY; + + LOG_I("update record offset to %d", otaEnv.breakPoint); + nv_record_ota_update_breakpoint(otaEnv.currentUser, + otaEnv.deviceId, + otaEnv.breakPoint); + } + } + + return status; +} + +void ota_common_apply_current_fw(void) +{ + OTA_BOOT_INFO_T otaBootInfo = {COPY_NEW_IMAGE, + otaEnv.totalImageSize, + otaEnv.crc32OfImage}; + _update_boot_info(&otaBootInfo); + +#ifdef OTA_NVRAM + ota_update_nv_data(); +#endif + + app_start_postponed_reset(); +} + +void ota_common_on_relay_data_received(uint8_t *ptrParam, uint32_t paramLen) +{ + ASSERT(ptrParam, "invalid data pointer received in %s", __func__); + ASSERT(paramLen <= TWS_RELAY_DATA_MAX_SIZE, "illegal parameter length received in %s", __func__); + + OTA_TWS_DATA_T *otaTwsData = (OTA_TWS_DATA_T *)ptrParam; + LOG_D("[%s] paramLen:%d, cmdType:%d|%s", __func__, paramLen, otaTwsData->cmdType, _cmd2str(otaTwsData->cmdType)); + + OTA_STATUS_E status = OTA_STATUS_OK; + OTA_BEGIN_PARAM_T *beginInfo = NULL; + uint16_t packetLen = 0; + + if (_tws_frame_validity_check(ptrParam, paramLen)) + { + /// update the magic code and command type + otaEnv.currentMagicCode = otaTwsData->magicCode; + otaEnv.currentCmdType = otaTwsData->cmdType; + + /// push received data into tws OTA data receive queue + osMutexWait(rxQueueMutexID, osWaitForever); + ASSERT(CQ_OK == EnCQueue(&otaEnv.rxQueue, (CQItemType *)otaTwsData->data, (paramLen - OTA_TWS_HEAD_SIZE)), + "%s failed to push data to queue, avaiable:%d, push:%d", + __func__, + AvailableOfCQueue(&otaEnv.rxQueue), + (paramLen - OTA_TWS_HEAD_SIZE)); + osMutexRelease(rxQueueMutexID); + + /// whole packet from APP received done + if (OTA_RELAY_PACKET_MAGIC_CODE_COMPLETE == otaEnv.currentMagicCode) + { + osMutexWait(rxQueueMutexID, osWaitForever); + packetLen = LengthOfCQueue(&otaEnv.rxQueue); + LOG_D("length of rx queue:%d", packetLen); + DeCQueue(&otaEnv.rxQueue, otaEnv.tempRxBuf, packetLen); + osMutexRelease(rxQueueMutexID); + + switch (otaEnv.currentCmdType) + { + case OTA_COMMAND_RSP: + /// retrieve and update the status of peer + status = ((OTA_RESPONSE_PARAM_T *)otaEnv.tempRxBuf)->status; + _update_peer_result(status); + + /// inform the receiving thread to proceed + osSignalSet(rxThreadId, OTA_TWS_RX_SIGNAL); + break; + + /// add other supported command here + case OTA_COMMAND_BEGIN: + beginInfo = (OTA_BEGIN_PARAM_T *)otaTwsData->data; + if (beginInfo->initializer) + { + beginInfo->initializer(); + } + else + { + LOG_E("initializer not registored"); + } + case OTA_COMMAND_DATA: + case OTA_COMMAND_APPLY: + case OTA_COMMAND_ABORT: + if (otaEnv.peerCmdReceivedHandler) + { + status = otaEnv.peerCmdReceivedHandler(otaEnv.currentCmdType, + (const uint8_t*)otaEnv.tempRxBuf, + packetLen); + } + else + { + LOG_W("peerCmdReceivedHandler is not registored"); + } + + break; + + default: + ASSERT(0, "INVALID cmd received"); + status = OTA_STATUS_ERROR; + break; + } + + /// response to master if needed + if (OTA_COMMAND_RSP != otaTwsData->cmdType) + { + _tws_rsp(status); + } + + otaEnv.currentMagicCode = OTA_RELAY_PACKET_MAGIC_CODE_INVALID; + otaEnv.currentCmdType = OTA_COMMAND_NUM; + } + } + else + { + LOG_W("Received data frame is invalid"); + status = OTA_STATUS_ERROR; + + switch (otaTwsData->cmdType) + { + case OTA_COMMAND_RSP: + _update_peer_result(status); + osSignalSet(rxThreadId, OTA_TWS_RX_SIGNAL); + break; + + case OTA_COMMAND_BEGIN: + case OTA_COMMAND_DATA: + case OTA_COMMAND_APPLY: + case OTA_COMMAND_ABORT: + _tws_rsp(status); + break; + + default: + ASSERT(0, "INVALID command received"); + break; + } + } +} + +POSSIBLY_UNUSED static void _ota_tws_deinit(void) +{ + ResetCQueue(&otaEnv.txQueue); + ResetCQueue(&otaEnv.rxQueue); + memset(otaEnv.txBuf, 0, ARRAY_SIZE(otaEnv.txBuf)); + memset(otaEnv.rxBuf, 0, ARRAY_SIZE(otaEnv.rxBuf)); + memset(otaEnv.tempRxBuf, 0, ARRAY_SIZE(otaEnv.tempRxBuf)); + + if (txThreadId) + { + osThreadTerminate(txThreadId); + txThreadId = NULL; + } + + if (txQueueMutexID != NULL) + { + osMutexDelete(txQueueMutexID); + txQueueMutexID = NULL; + } + + if (rxQueueMutexID != NULL) + { + osMutexDelete(rxQueueMutexID); + rxQueueMutexID = NULL; + } +} + +static void _ota_tws_thread(const void *arg) +{ + volatile uint16_t qLen = 0; + volatile uint16_t packetLen = 0; + + while (1) + { + osMutexWait(txQueueMutexID, osWaitForever); + qLen = LengthOfCQueue(&otaEnv.txQueue); + osMutexRelease(txQueueMutexID); + LOG_D("queued data len:%d", qLen); + + while (qLen) + { + /// check the validity of queue length + /// ASSERT(qLen <= OTA_MAX_MTU, "invalid OTA relay data len"); + + osMutexWait(txQueueMutexID, osWaitForever); + /// retrive and check the validity of packet length + DeCQueue(&otaEnv.txQueue, (CQItemType *)&packetLen, 2); + ASSERT(packetLen <= TWS_RELAY_DATA_MAX_SIZE, "invalid OTA relay data len:%d", packetLen); + + /// retrieve the data to transmit + DeCQueue(&otaEnv.txQueue, (CQItemType *)relayBuf, packetLen); + osMutexRelease(txQueueMutexID); + + LOG_D("send data len:%d", packetLen); + + /// send data to peer + tws_ctrl_send_cmd(IBRT_COMMON_OTA, relayBuf, packetLen); + memset(relayBuf, 0, TWS_RELAY_DATA_MAX_SIZE); + + osMutexWait(txQueueMutexID, osWaitForever); + qLen = LengthOfCQueue(&otaEnv.txQueue); + osMutexRelease(txQueueMutexID); + } + + osSignalWait(OTA_TWS_TX_SIGNAL, osWaitForever); + } +} + +static void _sync_info_prepare_handler(uint8_t *buf, uint16_t *length) +{ + *length = OTA_DEVICE_CNT * sizeof(NV_OTA_INFO_T); + + void *otaInfo = NULL; + nv_record_ota_get_ptr(&otaInfo); + + memcpy(buf, otaInfo, *length); +} + +static void _sync_info_received_handler(uint8_t *buf, uint16_t length) +{ + // uodate gsound info + // TODO: +} + +void ota_common_tws_sync_init(void) +{ + TWS_SYNC_USER_T userOta = { + _sync_info_prepare_handler, + _sync_info_received_handler, + _sync_info_prepare_handler, + NULL, + NULL, + }; + + app_tws_if_register_sync_user(TWS_SYNC_USER_OTA, &userOta); +} +#endif diff --git a/services/ota/ota_common.h b/services/ota/ota_common.h new file mode 100644 index 0000000..6547351 --- /dev/null +++ b/services/ota/ota_common.h @@ -0,0 +1,670 @@ +/** + * @file ota_common.h + * @author BES AI team + * @version 0.1 + * @date 2020-04-17 + * + * @copyright Copyright (c) 2015-2020 BES Technic. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + */ + +#ifndef __OTA_COMMON_H__ +#define __OTA_COMMON_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +/*****************************header include********************************/ +#include "cmsis_os.h" +#include "cqueue.h" + +/******************************macro defination*****************************/ +/** + * @brief Flash base address. + * + */ +#define OTA_FLASH_LOGIC_ADDR (FLASH_NC_BASE) + +/** + * @brief max version string length supported by ota common layer. + * + */ +#define MAX_VERSION_LEN 20 + + +/** + * @brief boot up flag + * + */ +#ifndef NORMAL_BOOT +#define NORMAL_BOOT 0xBE57EC1C +#endif + +/** + * @brief This flag is used to inform OTA bin to copy the new image to APP + * image section. + * + */ +#ifndef COPY_NEW_IMAGE +#define COPY_NEW_IMAGE 0x5A5A5A5A +#endif + + +/** + * @brief offset in flash to write the new image. + * + */ +#ifndef NEW_IMAGE_FLASH_OFFSET +#define NEW_IMAGE_FLASH_OFFSET 0x180000 +#endif + + +/** + * @brief flash sector size + * + * 4K is the page size of flash + * + */ +#ifndef FLASH_SECTOR_SIZE_IN_BYTES +#define FLASH_SECTOR_SIZE_IN_BYTES 4096 +#endif + + +/** + * @brief cache buffer size for OTA data. + * + */ +#ifndef OTA_DATA_CACHE_BUFFER_SIZE +#define OTA_DATA_CACHE_BUFFER_SIZE FLASH_SECTOR_SIZE_IN_BYTES +#endif + + +/** + * @brief this value is used for configure the norflash write buffer. + * + */ +#define OTA_NORFLASH_BUFFER_LEN (OTA_DATA_CACHE_BUFFER_SIZE * 2) + + +/** + * @brief this flag is used to mark if platform support automatic OTA. + * + * If Target indicates the device supports Automatic OTA, then the new firmware + * image does not have to be applied immediately after firmware transfer has + * completed. Instead the device can choose an opportune moment to perform the + * Apply. + * + */ +#define SUPPORT_AUTOMATIC_OTA false + + +#ifdef IBRT +/// max data size per packet of tws relay +/// this value should equal to @see APP_TWS_CTRL_BUFFER_MAX_LEN +#define TWS_RELAY_DATA_MAX_SIZE 512 + +/// max data size per packet of OTA APP +/// NOTE: this value depends on specific OTA spec +#define OTA_MAX_MTU 700 + +#define OTA_RELAY_PACKET_MAGIC_CODE_INVALID 0x44454144 + +/// mark the whole packet data from APP is completely transmitted +#define OTA_RELAY_PACKET_MAGIC_CODE_COMPLETE 0x28269395 + +/// mark the whole packet data from APP is not completely transmitted +#define OTA_RELAY_PACKET_MAGIC_CODE_INCOMPLETE 0x17188284 + +/// prefix of the gsuond_tws_data see @OTA_TWS_DATA_T +#define OTA_TWS_HEAD_SIZE (sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t)) + +/// payload max length is tws_buffer_size minimize the prefix, see @GSOUND_OTA_TWS_T +#define OTA_TWS_PAYLOAD_MAX_LEN (TWS_RELAY_DATA_MAX_SIZE - OTA_TWS_HEAD_SIZE) + +#define OTA_TWS_RX_SIGNAL (1 << 10) +#define OTA_TWS_TX_SIGNAL (1 << 11) + +#define OTA_TWS_RELAY_WAITTIME 2000 +#endif // #ifdef IBRT + + +#ifdef OTA_NVRAM +#define BD_ADDR_LENGTH 6 +#define NAME_LENGTH 32 +#endif + +/******************************type defination******************************/ +/** + * @brief Boot up info structure. + * + */ +typedef struct +{ + uint32_t magicNumber; + uint32_t imageSize; + uint32_t imageCrc; +}__attribute__ ((__packed__)) OTA_BOOT_INFO_T; + +/** + * @brief enum for OTA command. + * + */ +typedef enum +{ + OTA_COMMAND_BEGIN = 0, //!< OTA_BEGIN command identifier + OTA_COMMAND_DATA = 1, //!< OTA_DATA command identifier + OTA_COMMAND_APPLY = 2, //!< OTA_APPLY command identifier + OTA_COMMAND_ABORT = 3, //!< OTA_ABORT command identifier +#ifdef IBRT + OTA_COMMAND_RSP = 4, //!< used to response the tws OTA data relay +#endif + + OTA_COMMAND_NUM, //!< number of valid OTA command +}OTA_COMMAND_E; + +/** + * @brief enum for OTA user. + * + */ +typedef enum +{ + OTA_USER_BES = 0, //!< OTA user: BES + OTA_USER_COLORFUL = 1, //!< OTA user: GOOGLE + OTA_USER_ORANGE = 2, //!< OTA user: ALI + OTA_USER_RED = 3, //!< OTA user: HUAWEI + OTA_USER_GREEN = 4, //!< OTA user: OPPO + // and other possible OTA user here + + OTA_USER_NUM, //!< OTA user number +} OTA_USER_E; + +/** + * @brief enum for OTA path. + * + */ +typedef enum +{ + OTA_PATH_INVALID = 0, //!< invalid OTA path + OTA_PATH_BT = 1, //!< OTA path: BT + OTA_PATH_BLE = 2, //!< OTA path: BLE +} OTA_PATH_E; + +/** + * @brief enum for OTA device. + * + */ +typedef enum +{ + OTA_DEVICE_APP = 0, + OTA_DEVICE_HOTWORD = 1, + // OTA_DEVICE_BOX = 2, + + OTA_DEVICE_NUM, +}OTA_DEVICE_E; + +/** + * @brief enum for OTA status + * + */ +typedef enum +{ + OTA_STATUS_OK = 0, //!< status OK + OTA_STATUS_ERROR = 1, //!< status error + OTA_STATUS_ERROR_RELAY_TIMEOUT = 2, //!< tws data relay timeout + OTA_STATUS_ERROR_CHECKSUM = 3, //!< checksum error + OTA_STATUS_ERROR_NOT_ALLOWED = 4, //!< ota not allowed error + + OTA_STATUS_NUM, +}OTA_STATUS_E; + +/** + * @brief enum for OTA stage + * + */ +typedef enum +{ + OTA_STAGE_IDLE = 0, //!< OTA is in idle state + OTA_STAGE_ONGOING = 1, //!< OTA is ongoing + OTA_STAGE_DONE = 2, //!< OTA is done + OTA_STAGE_APPLY = 3, //!< OTA is ready to apply, + //!< will apply at convenience + + OTA_STAGE_NUM, //!< OTA stage number +}OTA_STAGE_E; + +typedef void(*CUSTOM_INITIALIZER_T)(void); + +/** + * @brief the data structure of OTA_BEGIN command. + * + * common used information for OTA_BEGIN command in OTA common layer + * the param 'customize' is used to pass the user-specific info which + * will be handled in the function registored with + * @see ota_common_registor_command_handler. + * + */ +typedef struct +{ + OTA_PATH_E path; //!< used to mark the OTA path + OTA_USER_E user; //!< used to mark the OTA user + OTA_DEVICE_E device; //!< used to mark the OTA device + CUSTOM_INITIALIZER_T initializer; //!< used to init the custom OTA context + uint32_t imageSize; //!< total size of the upgrade image + uint32_t flashOffset; //!< flash offset to write the new image + uint32_t startOffset; //!< offset in upgrade image to start update + char version[MAX_VERSION_LEN]; //!< string of version to update + uint8_t versionLen; //!< length of the version string + void *customize; //!< customized information pointer + uint32_t customizeLen; //!< customized information length +} OTA_BEGIN_PARAM_T; + +/** + * @brief the data structure of OTA_DATA command. + * + * common used information for OTA_DATA command in OTA common layer + * the param 'customize' is used to pass the user-specific info which + * will be handled in the function registored with + * @see ota_common_registor_command_handler. + * + */ +typedef struct +{ + uint32_t offset; //!< offset in the whole upgrade image of this packet of data + uint16_t len; //!< length of upgrade data + const uint8_t *data; //!< pointer of upgrade data + uint32_t customizeLen; //!< customized information length + void *customize; //!< customized information pointer +} OTA_DATA_PARAM_T; + +/** + * @brief the data structure of OTA_APPLY command. + * + * common used information for OTA_APPLY command in OTA common layer + * the param 'customize' is used to pass the user-specific info which + * will be handled in the function registored with + * @see ota_common_registor_command_handler. + * + */ +typedef struct +{ + bool applyNow; //!< mark if force apply the upgrade image + uint32_t customizeLen; //!< customized information length + void *customize; //!< customized information pointer +} OTA_APPLY_PARAM_T; + +/** + * @brief the data structure of OTA_ABORT command. + * + * common used information for OTA_ABORT command in OTA common layer + * the param 'customize' is used to pass the user-specific info which + * will be handled in the function registored with + * @see ota_common_registor_command_handler. + * + */ +typedef struct +{ + uint32_t customizeLen; //!< customized information length + void *customize; //!< customized information pointer +} OTA_ABORT_PARAM_T; + +/** + * @brief the data structure of OTA_RESPONSE command. + * + * common used information for OTA_RESPONSE command in OTA common layer + * + */ +typedef struct +{ + OTA_STATUS_E status; //!< status of received data +}OTA_RESPONSE_PARAM_T; + + +#ifdef OTA_NVRAM +typedef struct +{ + uint32_t lengthOfFollowingData; //!< + uint32_t newImageOffsetInFlash; //!< the offset of the flash to start writing the image + + uint32_t clearUserData : 1; //!< flag to mark if need to clear the user data section + uint32_t updateBTName : 1; //!< flag to mark if need to update the BT name + uint32_t updateLEName : 1; //!< flag to mark if need to update the BLE name + uint32_t updateBTAddr : 1; //!< flag to mark if need to update the BT address + uint32_t updateBLEAddr : 1; //!< flag to mark if need to update the BLE address + uint32_t reserve : 27; //!< reserved for future use + + uint8_t newBTName[NAME_LENGTH]; //!< BT name to update + uint8_t newLEName[NAME_LENGTH]; //!< BLE name to update + uint8_t newBTAddr[BD_ADDR_LENGTH]; //!< BT address to update + uint8_t newLEAddr[BD_ADDR_LENGTH]; //!< BLE address to update + + uint32_t crc; //!< CRC of data in this structure(except for crc itself) +}__attribute__ ((__packed__))OTA_FLOW_CONFIGURATION_T; +#endif + +#ifdef IBRT +/** + * @brief OTA relay packet type + * + */ +typedef enum +{ + OTA_RELAY_PACKET_TYPE_BEGIN = 0, + OTA_RELAY_PACKET_TYPE_DATA = 1, + OTA_RELAY_PACKET_TYPE_APPLY = 2, + OTA_RELAY_PACKET_TYPE_ABORT = 3, + OTA_RELAY_PACKET_TYPE_RSP = 4, + + OTA_RELAY_PACKET_TYPE_NUM, +} OTA_RELAY_PACKET_TYPE_E; + +/** + * @brief OTA relay packet data structure. + * + */ +typedef struct +{ + OTA_COMMAND_E cmdType; + uint32_t magicCode; + uint16_t length; + uint8_t data[OTA_TWS_PAYLOAD_MAX_LEN]; +} __attribute__((__packed__)) OTA_TWS_DATA_T; + +/** + * @brief Used for customer to determain if relay command/data needed. + * + */ +typedef bool(*CUSTOM_RELAY_NEEDED_FUNC_T)(void); + +/** + * @brief Used for peer command handling + * + */ +typedef OTA_STATUS_E (*PEER_CMD_RECEIVED_HANDLER_T)(OTA_COMMAND_E cmdType, + const uint8_t *data, + uint16_t len); +#endif + +typedef OTA_STATUS_E(*OTA_CMD_HANDLER_T)(const void *cmd, uint16_t cmdLen); + +typedef struct +{ + /// used to record the OTA command execution result + /// NOTE: this could be used by customers + OTA_STATUS_E status; + + /// used to mark if device currently in OTA state + bool isInOtaState; + + /// used to cache OTA data + uint8_t dataCacheBuffer[OTA_DATA_CACHE_BUFFER_SIZE]; + + /// used to mark OTA stage, @see OTA_STAGE_E to get more details + OTA_STAGE_E currentStage; + + /// current OTA user, @see OTA_USER_E to get more details + OTA_USER_E currentUser; + + /// current device ID, @see OTA_DEVICE_E to get more details + OTA_DEVICE_E deviceId; + + /// current OTA path, @see OTA_PATH_E to get more details + OTA_PATH_E currentPath; + + /// sanity check enable flag + /// 1 - sanity check enabled + /// 2 - sanity check disabled + bool sanityCheckEnable; + + /// total size of current OTA file + uint32_t totalImageSize; + + /// crc32 value of whole OTA image + uint32_t crc32OfImage; + + /// string of version info + char version[MAX_VERSION_LEN]; + + /// length of the version string + uint8_t versionLen; + + /// received data length + uint32_t receivedDataSize; + + /// break point of OTA progress + uint32_t breakPoint; + + /// offset of data cached in cache-buffer + uint32_t dataCacheBufferOffset; + + /// Flash Offset For New Image + uint32_t newImageFlashOffset; + + /// offset of data programmed in new image flash section + uint32_t newImageProgramOffset; + + /// offset in flash of user data section + uint32_t userDataNvFlashOffset; + + /// flash offset of user data pool + uint32_t flashOffsetOfUserDataPool; + + /// OTA user-specific command handlers, should registor this handler array + /// with @see ota_common_registor_command_handler + OTA_CMD_HANDLER_T cmdHandler[OTA_COMMAND_NUM + 1]; + +#ifdef OTA_NVRAM + uint32_t flashOffsetOfFactoryDataPool; + OTA_FLOW_CONFIGURATION_T configuration; +#endif + +#ifdef IBRT + /// tws relay data TX queue + CQueue txQueue; + + /// tws relay data TX buffer + uint8_t txBuf[OTA_MAX_MTU]; + + /// tws relay data RX queue + CQueue rxQueue; + + /// tws relay data RX buffer + uint8_t rxBuf[OTA_MAX_MTU]; + + /// used to retrieve data from RX queue + uint8_t tempRxBuf[OTA_MAX_MTU]; + + /// peer result of handling received relay data + OTA_STATUS_E peerResult; + + /// current receiving magic code of relay frame + /// used to mark if whole packet from APP is received + uint32_t currentMagicCode; + + /// current receiving command type + OTA_COMMAND_E currentCmdType; + + /// customized relay needed check handler + CUSTOM_RELAY_NEEDED_FUNC_T customRelayNeededHandler; + + /// peer data received handler + PEER_CMD_RECEIVED_HANDLER_T peerCmdReceivedHandler; +#endif +} OTA_COMMON_ENV_T; + +/****************************function declearation**************************/ +/** + * @brief Initialize the common used OTA context. + * + */ +void ota_common_init_handler(void); + +/** + * @brief Enable/disable the sanity check. + * + * @param enable switch on/off + */ +void ota_common_enable_sanity_check(bool enable); + +/** + * @brief Init OTA used flash module. + * + * @param module flash module, + * @see NORFLASH_API_MODULE_ID_T to get more details + * @param baseAddr base address of flash module + * @param len length of the flash module + * @param imageHandler handler + */ +void ota_common_init_flash(uint8_t module, + uint32_t baseAddr, + uint32_t len, + uint32_t imageHandler); + +/** + * @brief Get the pointer of otaEnv. + * + * This function is used to pass the pointer of otaEnv to up-layer OTA applications + * to use the common OTA info. + * + * @return OTA_COMMON_ENV_T* pointer of the otaEnv. + */ +OTA_COMMON_ENV_T* ota_common_get_env(void); + +/** + * @brief Judge if currently OTA is in progress. + * + * This function is used to judge if OTA progress is ongoing or not. + * NOTE: this function will return true if current OTA stage is not OTA_STAGE_IDLE + * + * @return true OTA in progress + * @return false OTA not in progress + */ +bool ota_common_is_in_progress(void); + +/** + * @brief Registor customized OTA command handler. + * + * Registor OTA uer-specific OTA command handlers, these functions are used to + * mainten the status of specific OTA user layer and handle the user-specific + * configurations. + * + * @param cmdType command type received, + * @see OTA_COMMAND_E to get more details + * @param cmdHandler handler to registor, + * must in type @see OTA_CMD_HANDLER_T + */ +void ota_common_registor_command_handler(OTA_COMMAND_E cmdType, + void *cmdHandler); + +/** + * @brief Handler of received OTA command. + * + * Handle the received OTA command and informations. + * + * @param cmdType receive command type + * @param cmdInfo pointer of received command information + * @param cmdLen length of received command information + * @return OTA_STATUS_E result of handling received OTA command + */ +OTA_STATUS_E ota_common_command_received_handler(OTA_COMMAND_E cmdType, + void *cmdInfo, + uint16_t cmdLen); + +#ifdef IBRT +/** + * @brief Registor customized relay needed handler. + * + * Relay needed is set to true by default, so the customized relay needed check + * handler only need to return false when relay is not needed. And the customized + * check function should in type of @see CUSTOM_RELAY_NEEDED_FUNC_T + * + * @param handler customized function handler + * + */ +void ota_common_registor_relay_needed_handler(void *handler); + +/** + * @brief Registor customized peer command recevied handler. + * + * @param handler customized function handler for received peer command + */ +void ota_common_registor_peer_cmd_received_handler(void *handler); + +/** + * @brief Relay data to peer handler. + * + * @param cmdType OTA command to relay, @see OTA_COMMAND_E to get more info + * @param data pointer of OTA data to relay + * @param len length of OTA data to realy + * @return OTA_STATUS_E result of the OTA data relay operation + */ +OTA_STATUS_E ota_common_relay_data_to_peer(OTA_COMMAND_E cmdType, + const uint8_t *data, + uint16_t len); + +/** + * @brief Receive the OTA relay response. + * + * NOTE: This function will block the current thread until response from peer + * received or timeout. + * + * @return OTA_STATUS_E OTA relay receive result. + */ +OTA_STATUS_E ota_common_receive_peer_rsp(void); + +/** + * @brief Write the received firmware data into flash. + * + * @param data pointer of received firmware data + * @param len lenght of received firmware data + * @return OTA_STATUS_E Operation excution result + */ +OTA_STATUS_E ota_common_fw_data_write(const uint8_t *data, uint16_t len); + +/** + * @brief Apply current firmware handler. + * + */ +void ota_common_apply_current_fw(void); + +/** + * @brief Get the result of peer response to tws relay data. + * + * @return OTA_STATUS_E response of peer to the relay data, + * @see OTA_STATUS_E to get more details + */ +OTA_STATUS_E ota_common_get_peer_result(void); + +/** + * @brief OTA realy data received handler. + * + * This function is used to handle received tws relay OTA data, transmit could be: + * 1. master->slave: relay OTA commands + * 2. slave->master: response to master + * + * @param ptrParam pointer of received data + * @param paramLen length of received data + */ +void ota_common_on_relay_data_received(uint8_t *ptrParam, uint32_t paramLen); + +/** + * @brief OTA sync tws info initializer. + * + */ +void ota_common_tws_sync_init(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __OTA_COMMON_H__ */ \ No newline at end of file diff --git a/services/ota/ota_dbg.h b/services/ota/ota_dbg.h new file mode 100644 index 0000000..3b3ab2c --- /dev/null +++ b/services/ota/ota_dbg.h @@ -0,0 +1,45 @@ +/** + * @file ota_dbg.h + * @author BES AI team + * @version 0.1 + * @date 2020-04-22 + * + * @copyright Copyright (c) 2015-2020 BES Technic. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + */ + +#ifndef __OTA_DBG_H__ +#define __OTA_DBG_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +/*****************************header include********************************/ +#include "hal_trace.h" + +/******************************macro defination*****************************/ +#define LOG_V(str, ...) LOG_VERBOSE(LOG_MOD(OTA), str, ##__VA_ARGS__) +#define LOG_D(str, ...) LOG_DEBUG(LOG_MOD(OTA), str, ##__VA_ARGS__) +#define LOG_I(str, ...) LOG_INFO(LOG_MOD(OTA), str, ##__VA_ARGS__) +#define LOG_W(str, ...) LOG_WARN(LOG_MOD(OTA), str, ##__VA_ARGS__) +#define LOG_E(str, ...) LOG_ERROR(LOG_MOD(OTA), str, ##__VA_ARGS__) + +/******************************type defination******************************/ + +/****************************function declearation**************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef __OTA_DBG_H__ */ \ No newline at end of file diff --git a/services/overlay/Makefile b/services/overlay/Makefile new file mode 100644 index 0000000..a2b6b88 --- /dev/null +++ b/services/overlay/Makefile @@ -0,0 +1,7 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + diff --git a/services/overlay/app_overlay.cpp b/services/overlay/app_overlay.cpp new file mode 100644 index 0000000..0ae9c8f --- /dev/null +++ b/services/overlay/app_overlay.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "app_overlay.h" +#include "hal_trace.h" +#include "hal_location.h" + +osMutexDef(app_overlay_mutex); + +static osMutexId app_overlay_mutex_id = NULL; +static APP_OVERLAY_ID_T app_overlay_id = APP_OVERLAY_ID_QTY; + +APP_OVERLAY_ID_T app_get_current_overlay(void) +{ + return app_overlay_id; +} + +void app_overlay_select(enum APP_OVERLAY_ID_T id) +{ +#ifndef FPGA + TRACE(3,"%s id:%d:%d",__func__, id, app_overlay_id); + + osMutexWait(app_overlay_mutex_id, osWaitForever); + if (app_overlay_id==APP_OVERLAY_ID_QTY){ + app_overlay_load(id); + }else if (app_overlay_id!=APP_OVERLAY_ID_QTY){ + if (app_overlay_id!=id){ + app_overlay_unload(app_overlay_id); + app_overlay_load(id); + } + } + app_overlay_id = id; + osMutexRelease(app_overlay_mutex_id); +#endif +} + +void app_overlay_unloadall(void) +{ + osMutexWait(app_overlay_mutex_id, osWaitForever); + if (app_overlay_id != APP_OVERLAY_ID_QTY){ + app_overlay_unload(app_overlay_id); + } + app_overlay_id = APP_OVERLAY_ID_QTY; + osMutexRelease(app_overlay_mutex_id); +} + +void app_overlay_open(void) +{ + if (app_overlay_mutex_id == NULL) { + app_overlay_mutex_id = osMutexCreate(osMutex(app_overlay_mutex)); + } +} + +void app_overlay_close(void) +{ + app_overlay_unloadall(); + if (app_overlay_mutex_id != NULL){ + osMutexDelete(app_overlay_mutex_id); + app_overlay_mutex_id = NULL; + } +} + + diff --git a/services/overlay/app_overlay.h b/services/overlay/app_overlay.h new file mode 100644 index 0000000..9b0106b --- /dev/null +++ b/services/overlay/app_overlay.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_OVERLAY_H__ +#define __APP_OVERLAY_H__ + +#include "plat_types.h" +#include "hal_overlay.h" + +#define app_overlay_load(id) hal_overlay_load((enum HAL_OVERLAY_ID_T)id) +#define app_overlay_unload(id) hal_overlay_unload((enum HAL_OVERLAY_ID_T)id) +#define app_overlay_get_text_size(id) hal_overlay_get_text_size((enum HAL_OVERLAY_ID_T)id) +#define app_overlay_get_text_all_size hal_overlay_get_text_all_size +#define app_overlay_get_text_address hal_overlay_get_text_address +#define app_overlay_get_text_free_size(id) hal_overlay_get_text_free_size((enum HAL_OVERLAY_ID_T)id) +#define app_overlay_get_text_free_addr(id) hal_overlay_get_text_free_addr((enum HAL_OVERLAY_ID_T)id) +//#define app_overlay_is_used hal_overlay_is_used + +enum APP_OVERLAY_ID_T { + APP_OVERLAY_HFP = HAL_OVERLAY_ID_0, + APP_OVERLAY_A2DP = HAL_OVERLAY_ID_1, + APP_OVERLAY_FM = HAL_OVERLAY_ID_2, + APP_OVERLAY_AAC = HAL_OVERLAY_ID_3, + APP_OVERLAY_A2DP_AAC = HAL_OVERLAY_ID_4, + APP_OVERLAY_MPA = HAL_OVERLAY_ID_5, +#if defined(A2DP_SCALABLE_ON) + APP_OVERLAY_A2DP_SCALABLE= HAL_OVERLAY_ID_6, +#elif defined(A2DP_LHDC_ON) + APP_OVERLAY_A2DP_LHDC = HAL_OVERLAY_ID_6, +#else + APP_OVERLAY_WAV = HAL_OVERLAY_ID_6, +#endif +#ifdef OPUS_IN_OVERLAY + APP_OVERLAY_OPUS = HAL_OVERLAY_ID_7, +#elif defined(A2DP_LDAC_ON) + APP_OVERLAY_A2DP_LDAC = HAL_OVERLAY_ID_7, +#endif + + APP_OVERLAY_ID_QTY = HAL_OVERLAY_ID_QTY, + APP_OVERLAY_ID_IN_CFG = HAL_OVERLAY_ID_IN_CFG, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +void app_overlay_select(enum APP_OVERLAY_ID_T id); + +void app_overlay_unloadall(void); + +void app_overlay_open(void); + +void app_overlay_close(void); + +enum APP_OVERLAY_ID_T app_get_current_overlay(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/services/resources/Makefile b/services/resources/Makefile new file mode 100644 index 0000000..12a13ed --- /dev/null +++ b/services/resources/Makefile @@ -0,0 +1,14 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y += \ + -Iutils/crc32 + +ifeq ($(VOICE_PROMPT),1) +CFLAGS_resources.o += -DMEDIA_PLAYER_SUPPORT +endif + diff --git a/services/resources/resources.cpp b/services/resources/resources.cpp new file mode 100644 index 0000000..735bc85 --- /dev/null +++ b/services/resources/resources.cpp @@ -0,0 +1,388 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "stdio.h" +#include "cmsis_os.h" +#include "string.h" + +#include "hal_timer.h" +#include "hal_trace.h" + +#include "crc32.h" +#include "resources.h" + +#ifdef MEDIA_PLAYER_SUPPORT + +typedef struct { + UINT32 MARK; + UINT16 ID; // resource id + UINT16 count; // count of resource + UINT32 total_size; // size include resource header, header list and data +} ResourceHeader_t; + + +typedef struct { + UINT16 audio_id; // audio id + UINT16 type; + UINT32 size; + UINT32 offset; +} AudioHeader_t; + +typedef struct _AUDIO_List +{ + struct _AUDIO_List *next; + AudioHeader_t record; +} AUDIO_List; + + + +#define AUDIO_TOOL_VERSION 0x6001 +#define MAGIC_NUMBER 0xC0BA +#define AUDIO_TOOL_RES_MARK 0xDDCCBBAA + +UINT16 gVersionNO = 0; +UINT32 gReserver1 = 0; +UINT32 gReserver2 = 0; + +ResourceHeader_t *gpResourceBase = NULL; // base address of resource data, will be set by boot monitor + +AUDIO_List *gpAudioList = NULL; +AUDIO_List *gpAudioList_CN = NULL; + +uint8_t *gpAudioDataBase = NULL; +uint8_t *gpAudioDataBase_CN = NULL; + + +//uint8_t os_pool_audio_List[sizeof(AUDIO_List)*MAX_RECORD_NUM ] __attribute__((section(".audioList"))); +AUDIO_List os_pool_audio_List[MAX_RECORD_NUM]; //__attribute__((section(".audioList"))); +//osPoolDef_t os_pool_def_audio_List = { MAX_RECORD_NUM, sizeof(AUDIO_List), os_pool_audio_List };//osPoolDef(name, no, type) +//osPoolId AUDIO_ListPool_Id; + +AUDIO_List os_pool_audio_List_CN[MAX_RECORD_NUM]; + +UINT8* aud_get_reouce(AUD_ID_ENUM id, UINT32* leng, UINT16* type) +{ + AUDIO_List * list = gpAudioList; + + *leng = 0, *type = 0; + + while(list) + { + if (list->record.audio_id == id) + { + *leng = list->record.size; + *type = list->record.type; + return (UINT8*) (gpAudioDataBase + list->record.offset); + } + list = list->next; + } + + return 0; +} + +UINT8* aud_get_reouce_chinese(AUD_ID_ENUM id, UINT32* leng, UINT16* type) +{ + AUDIO_List * list = gpAudioList_CN; + + *leng = 0, *type = 0; + + while(list) + { + if (list->record.audio_id == id) + { + *leng = list->record.size; + *type = list->record.type; + return (UINT8*) (gpAudioDataBase_CN + list->record.offset); + } + list = list->next; + } + + return 0; +} + +/* +--1.Version No&Magic No.<4> +--2.CRC <4> +--3.Reserver1 <4> total length = 5+6+7+... +--4.Reserver2 <4> +--5.ResourceHeader_t <8> +--6.AUDIO_HEAD_LIST X count <16 x count> +--7.file.. gpAudioDataBase.. offset +--.... another resource +*/ +void init_audio_resource(void* gResource) +{ + uint32_t crc; + uint32_t *pcrc; + uint32_t data; + + UINT32 res_addr; + ResourceHeader_t *pRes; + + data = *((UINT32*)gResource); + gVersionNO = 0xFFFF & (data>>16); + gReserver1 = *((UINT32*)((uint32_t)gResource+2*sizeof(UINT32))); + + pcrc = (uint32_t *)((uint32_t)gResource+sizeof(UINT32)); /*crc*/ + + gpResourceBase = (ResourceHeader_t *) ((uint32_t)gResource + 4*sizeof(uint32_t)); +/********************************************************/ + crc = crc32(0, (uint8_t *)((uint32_t)gpResourceBase) , gReserver1); + TRACE(3,"%s, *pcrc: %x , crc: %x",__func__, *pcrc, crc); + if (*pcrc != crc) + return; + + res_addr = (uint32_t)gpResourceBase; + pRes = (ResourceHeader_t *)gpResourceBase; + + while((UINT32)pRes < (UINT32)gpResourceBase +gReserver1 && pRes->MARK == AUDIO_TOOL_RES_MARK) + { + if (pRes->ID == RES_ENGLISH_ID) + { + AUDIO_List * list; + memset(os_pool_audio_List, 0, sizeof(AUDIO_List)*MAX_RECORD_NUM); + memcpy((uint8_t *)os_pool_audio_List, (uint8_t *)((uint32_t)pRes+sizeof(ResourceHeader_t)),sizeof(AUDIO_List)* pRes->count); + + gpAudioList = (AUDIO_List *)os_pool_audio_List; + list = gpAudioList; + + gpAudioDataBase = (uint8_t *)pRes + sizeof(ResourceHeader_t) + sizeof(AUDIO_List)* pRes->count; + TRACE(3,"%s, english count: %d, leng: %d",__func__, pRes->count, pRes->total_size); + + for(int i=1; icount; i++) + { + list->next = &os_pool_audio_List[i]; + + list = list->next; + } + + TRACE(2,"%s, english list: %p",__func__, list); + + } + else if (pRes->ID == RES_CHINESE_ID) + { + + AUDIO_List * list; + TRACE(2,"%s, AUDIO_TOOL_RES_MARK: %d",__func__, pRes->count); + + memset(os_pool_audio_List_CN, 0, sizeof(AUDIO_List)*MAX_RECORD_NUM); + memcpy((uint8_t *)os_pool_audio_List_CN, (uint8_t *)((uint32_t)pRes+sizeof(ResourceHeader_t)),sizeof(AUDIO_List)* pRes->count); + + gpAudioList_CN= (AUDIO_List *)os_pool_audio_List_CN; + list = gpAudioList_CN; + + gpAudioDataBase_CN = (uint8_t *)pRes +sizeof(ResourceHeader_t) + sizeof(AUDIO_List)* pRes->count; + TRACE(3,"%s, chinese count: %d, leng: %d",__func__, pRes->count, pRes->total_size); + + for(int i=1; icount; i++) + { + list->next = &os_pool_audio_List_CN[i]; + + list = list->next; + } + } + + TRACE(3,"%s, %x, pRes->total_size: %x",__func__,res_addr, pRes->total_size); + + res_addr += pRes->total_size; + pRes = (ResourceHeader_t*)(res_addr); + + } + + TRACE(2,"%s, pRes add: %p",__func__, pRes); + +} + +#if 0 +UINT8 BIN_FILE[] = +{ +0xba,0xc0,0x01,0x60,0x18,0x17,0x81,0x7a,0x90,0x05,0x00,0x00,0x00,0x00,0x00,0x00, +0xaa,0xbb,0xcc,0xdd,0x00,0xff,0x1c,0x00,0xc8,0x02,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x02,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x03,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x04,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x05,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x06,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x07,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x08,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x09,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x51,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x0a,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x5a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x0b,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x0c,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x0d,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x0e,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x0f,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x10,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x11,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x12,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x13,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x15,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x16,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x17,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0xcf,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x18,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x19,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x1a,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x1b,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0xf3,0x00,0x00,0x00,0x34,0x34,0x34,0x35, +0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34, +0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36, +0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36, +0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35, +0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34, +0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34, +0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36, +0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35, +0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35, +0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34, +0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36, +0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36, +0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35, +0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34, +0x35,0x35,0x35,0x36,0x36,0x36,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x34, +0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0xaa,0xbb,0xcc,0xdd,0x01,0xff,0x1c,0x00, +0xc8,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x2d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x51,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x5a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x16,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0xcf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0x00,0x04,0x00,0x09,0x00,0x00,0x00, +0xf3,0x00,0x00,0x00,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31, +0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31, +0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33, +0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32, +0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32, +0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31, +0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33, +0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33, +0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32, +0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31, +0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31, +0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33, +0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32, +0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32, +0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31, +0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33, + +}; +void test_resource_load() +{ + UINT32 leng; + UINT16 type; + UINT8* data; + + init_audio_resource(BIN_FILE); + + data = aud_get_reouce(AUD_ID_BT_CALL_REFUSE, &leng, &type); + + TRACE(6,"====english_audio, leng = %d, type = %d, data[0] = %x, data[1]= %x, data[2]= %x, data[3]= %x", leng, type, data[0], data[1], data[2], data[3]); + + data = aud_get_reouce_chinese(AUD_ID_BT_CLEAR_SUCCESS, &leng, &type); + + TRACE(6,"====chinese_audio, leng = %d, type = %d, data[0] = %x, data[1]= %x, data[2]= %x, data[3]= %x", leng,type, data[0], data[1], data[2], data[3]); + + +}; +#endif +#endif + +const char *aud_id_str[] = +{ + "[POWER_ON]", + "[POWER_OFF]", + "[LANGUAGE_SWITCH]", + + "[NUM_0]", + "[NUM_1]", + "[NUM_2]", + "[NUM_3]", + "[NUM_4]", + "[NUM_5]", + "[NUM_6]", + "[NUM_7]", + "[NUM_8]", + "[NUM_9]", + + "[BT_PAIR_ENABLE]", + "[BT_PAIRING]", + "[BT_PAIRING_SUC]", + "[BT_PAIRING_FAIL]", + "[BT_CALL_REFUSE]", + "[BT_CALL_OVER]", + "[BT_CALL_ANSWER]", + "[BT_CALL_HUNG_UP]", + "[BT_CALL_INCOMING_CALL]", + "[BT_CALL_INCOMING_NUMBER]", + "[BT_CHARGE_PLEASE]", + "[BT_CHARGE_FINISH]", + "[BT_CLEAR_SUCCESS]", + "[BT_CLEAR_FAIL]", + "[BT_CONNECTED]", + "[BT_DIS_CONNECT]", + "[BT_WARNING]", + "[BT_ALEXA_START]", + "[FIND_MY_BUDS]", + "[TILE FIND]", + "[BT_ALEXA_STOP]", + "[BT_GSOUND_MIC_OPEN]", + "[BT_GSOUND_MIC_CLOSE]", + "[BT_GSOUND_NC]", + "[BT_MUTE]", + "[RING_WARNING]", +#ifdef __INTERACTION__ + "[BT_FINDME]", +#endif +}; + +const char *aud_id2str(UINT16 aud_id) +{ + const char *str = NULL; + + if (aud_id >= 0 && aud_id < MAX_RECORD_NUM) + { + str = aud_id_str[aud_id]; + } + else + { + str = "[UNKNOWN]"; + } + + return str; +} + diff --git a/services/resources/resources.h b/services/resources/resources.h new file mode 100644 index 0000000..cf5b643 --- /dev/null +++ b/services/resources/resources.h @@ -0,0 +1,95 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +//////////////////////////////////////////////////////////////// +// + +#ifndef __RESOURCES_H__ +#define __RESOURCES_H__ + +typedef enum { + AUD_ID_INVALID = -1, + AUD_ID_POWER_ON = 0x0, + AUD_ID_POWER_OFF, + AUD_ID_LANGUAGE_SWITCH, + + AUD_ID_NUM_0, + AUD_ID_NUM_1, + AUD_ID_NUM_2, + AUD_ID_NUM_3, + AUD_ID_NUM_4, + AUD_ID_NUM_5, + AUD_ID_NUM_6, + AUD_ID_NUM_7, + AUD_ID_NUM_8, + AUD_ID_NUM_9, + + AUD_ID_BT_PAIR_ENABLE, + AUD_ID_BT_PAIRING, + AUD_ID_BT_PAIRING_SUC, + AUD_ID_BT_PAIRING_FAIL, + AUD_ID_BT_CALL_REFUSE, + AUD_ID_BT_CALL_OVER, + AUD_ID_BT_CALL_ANSWER, + AUD_ID_BT_CALL_HUNG_UP, + AUD_ID_BT_CALL_INCOMING_CALL, + AUD_ID_BT_CALL_INCOMING_NUMBER, + AUD_ID_BT_CHARGE_PLEASE, + AUD_ID_BT_CHARGE_FINISH, + AUD_ID_BT_CLEAR_SUCCESS, + AUD_ID_BT_CLEAR_FAIL, + AUD_ID_BT_CONNECTED, + AUD_ID_BT_DIS_CONNECT, + AUD_ID_BT_WARNING, + AUDIO_ID_BT_ALEXA_START, + AUDIO_ID_FIND_MY_BUDS, + AUDIO_ID_FIND_TILE, + AUDIO_ID_BT_ALEXA_STOP, + AUDIO_ID_BT_GSOUND_MIC_OPEN, + AUDIO_ID_BT_GSOUND_MIC_CLOSE, + AUDIO_ID_BT_GSOUND_NC, + AUDIO_ID_BT_MUTE, + AUDIO_ID_BT_DU, + AUDIO_ID_BT_DUDU, + AUD_ID_RING_WARNING, +#ifdef __INTERACTION__ + AUD_ID_BT_FINDME, +#endif + MAX_RECORD_NUM, + AUD_ID_ENUM_BOTTOM = 0x1001, +} AUD_ID_ENUM; + +enum ENUM_RESOURCE_ID +{ + RES_ENGLISH_ID = 0xFF00, + RES_CHINESE_ID = 0xFF01, + + MAX_RES_LANGUAGE_ID +}; + +typedef uint8_t UINT8; +typedef uint16_t UINT16; +typedef uint32_t UINT32; + +void init_audio_resource(void* gResource); + +UINT8* aud_get_reouce(AUD_ID_ENUM id, UINT32* leng, UINT16* type); + +const char *aud_id2str(UINT16 aud_id); + +extern UINT8 BIN_FILE[]; + +#endif//__RESOURCES_H__ + diff --git a/services/through_put/Makefile b/services/through_put/Makefile new file mode 100644 index 0000000..7128fce --- /dev/null +++ b/services/through_put/Makefile @@ -0,0 +1,43 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +subdir-ccflags-y += -Iapps/common \ + -Iapps/key \ + -Iapps/main \ + -Iplatform/drivers/bt \ + -Iplatform/hal \ + -Iservices/ai_voice/audio \ + -Iservices/ai_voice/transport \ + -Iservices/ai_voice/manager \ + -Iservices/ai_voice/protocol/ama/ama_stream \ + -Iservices/app_ai/inc \ + -Iservices/app_ibrt/inc \ + -Iservices/app_tws/inc \ + -Iservices/ble_app/app_main \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/ble_ip \ + $(BT_IF_INCLUDES) \ + -Iservices/bt_app \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/multimedia/speech/inc \ + -Iservices/nvrecord \ + -Iservices/ibrt_core/inc \ + -Iservices/ibrt_ui/inc \ + -Iservices/ble_stack/common/api \ + -Iservices/ble_stack/hl/inc \ + -Iservices/ble_stack/ke/api \ + -Iservices/cp_accel \ + -Iservices/voicepath \ + -Iservices/voicepath/gsound/gsound_custom/inc \ + -Iservices/voicepath/gsound/gsound_target \ + -Iservices/voicepath/gsound/gsound_target_api_read_only \ + -Ithirdparty/userapi \ + -Iutils/cqueue \ + -Iutils/heap \ diff --git a/services/through_put/app_through_put.cpp b/services/through_put/app_through_put.cpp new file mode 100644 index 0000000..a2382ee --- /dev/null +++ b/services/through_put/app_through_put.cpp @@ -0,0 +1,300 @@ +#include "cmsis_os.h" +#include "hal_trace.h" +#include +#include "app_ai_if.h" +#include "app_ai_tws.h" +#include "app_ai_manager_api.h" +#include "app_ai_if_config.h" +#include "app_ai_if_thirdparty.h" +#include "app_ai_if_thirdparty.h" +#include "app_ai_if_custom_ui.h" +#include "app_through_put.h" + +#ifdef __AI_VOICE__ +#include "ai_manager.h" +#include "ai_control.h" +#include "ai_thread.h" +#include "app_ai_voice.h" +#endif + +static THROUGHPUT_TEST_ENV_T throughputTestEnv; +static THROUGHPUT_TEST_CONFIG_T throughputTestConfig; + +static uint32_t app_throughput_test_transmission_handler(void *param1, uint32_t param2); + +static APP_THROUGHPUT_CMD_INSTANCE_T *find_throughput_instance_by_code(uint16_t cmdCode) +{ + for (uint32_t index = 0; + index < APP_THROUGHPUT_CMD_INSTANCE_NUMBER; + index++) + { + if (through_put_table[index].cmdCode == cmdCode) + { + return &through_put_table[index]; + } + } + + return NULL; +} + +bool app_throughput_send_command(APP_THROUGHPUT_CMD_CODE_E cmdCode, + uint8_t *ptrParam, uint32_t paramLen) +{ + APP_THROUGHPUT_CMD_PAYLOAD_T payload; + uint16_t cmd_len = 0; + + if (THROUGHPUT_DATA_MAX_SIZE < paramLen) + { + TRACE(1,"%s error ", __func__); + return false; + } + + payload.cmdCode = cmdCode; + payload.paramLen = paramLen; + memcpy(payload.param, ptrParam, paramLen); + + cmd_len = (uint32_t)THROUGHPUT_CMD_PAYLOAD_HEADER_LEN + payload.paramLen; + app_ai_if_custom_ui_send_cmd((uint8_t *)&payload, cmd_len); + + return true; +} + +uint32_t app_throughput_cmd_send_done(void *param1, uint32_t param2) +{ + if (throughputTestEnv.isThroughputTestOn && \ + ((app_ai_get_transport_type() == AI_TRANSPORT_BLE) ||\ + (WITHOUT_RSP == throughputTestConfig.responseModel))) + { + app_throughput_test_transmission_handler(NULL, 0); + } + + return 0; +} + +uint32_t app_throughput_receive_cmd(void *param1, uint32_t param2) +{ + uint8_t *ptrbuf = NULL; + uint32_t data_length = 0; + APP_THROUGHPUT_CMD_PAYLOAD_T* pPayload = NULL; + + TRACE(2,"%s data len %d", __func__, param2); + //DUMP8("0x%02x ", param1, param2); + + data_length = param2; + while(data_length) { + ptrbuf = (uint8_t *)((uint32_t)param1 + param2 - data_length); + + pPayload = (APP_THROUGHPUT_CMD_PAYLOAD_T *)ptrbuf; + data_length -= THROUGHPUT_CMD_PAYLOAD_HEADER_LEN; + if(data_length < pPayload->paramLen) { + TRACE(3,"%s error data_length %d paramLen %d", __func__, data_length, pPayload->paramLen); + return 2; + } + TRACE(3,"%s data_length %d paramLen %d", __func__, data_length, pPayload->paramLen); + data_length -= pPayload->paramLen; + + // check parameter length + if (pPayload->paramLen > sizeof(pPayload->param)) { + TRACE(0,"SV COMMAND PARAM ERROR LENGTH"); + return 4; + } + + APP_THROUGHPUT_CMD_INSTANCE_T *pInstance = find_throughput_instance_by_code(pPayload->cmdCode); + + // execute the command handler + if (pInstance) + { + pInstance->cmdHandler((APP_THROUGHPUT_CMD_CODE_E)(pPayload->cmdCode), pPayload->param, pPayload->paramLen); + } + } + + return 0; +} + +#define APP_THROUGHPUT_PRE_CONFIG_PENDING_TIME_IN_MS 2000 +static void app_throughput_pre_config_pending_timer_cb(void const *n); +osTimerDef (APP_THROUGHPUT_PRE_CONFIG_PENDING_TIMER, app_throughput_pre_config_pending_timer_cb); +osTimerId app_throughput_pre_config_pending_timer_id = NULL; + +static void app_throughput_test_data_xfer_lasting_timer_cb(void const *n); +osTimerDef (APP_THROUGHPUT_TEST_DATA_XFER_LASTING_TIMER, app_throughput_test_data_xfer_lasting_timer_cb); +osTimerId app_throughput_test_data_xfer_lasting_timer_id = NULL; + + +static uint8_t app_throughput_datapattern[THROUGHPUT_DATA_MAX_SIZE]; + +static void app_throughput_test_data_xfer_lasting_timer_cb(void const *n) +{ + app_throughput_send_command(THROUGHPUT_OP_THROUGHPUT_TEST_DONE, NULL, 0); + + app_stop_throughput_test(); +} + +static void app_throughput_pre_config_pending_timer_cb(void const *n) +{ + // inform the configuration + app_throughput_send_command(THROUGHPUT_OP_INFORM_THROUGHPUT_TEST_CONFIG, + (uint8_t *)&throughputTestConfig, sizeof(throughputTestConfig)); + + if (UP_STREAM == throughputTestConfig.direction) + { + app_throughput_test_transmission_handler(NULL, 0); + #ifndef SLAVE_ADV_BLE + osTimerStart(app_throughput_test_data_xfer_lasting_timer_id, + throughputTestConfig.lastTimeInSecond*1000); + #endif + } +} + +void app_throughput_test_init(void) +{ + memset(&throughputTestEnv, 0x00, sizeof(throughputTestEnv)); + memset(&throughputTestConfig, 0x00, sizeof(throughputTestConfig)); + + app_throughput_pre_config_pending_timer_id = + osTimerCreate(osTimer(APP_THROUGHPUT_PRE_CONFIG_PENDING_TIMER), + osTimerOnce, NULL); + + app_throughput_test_data_xfer_lasting_timer_id = + osTimerCreate(osTimer(APP_THROUGHPUT_TEST_DATA_XFER_LASTING_TIMER), + osTimerOnce, NULL); +} + +static uint32_t app_throughput_test_transmission_handler(void *param1, uint32_t param2) +{ + if (UP_STREAM == throughputTestConfig.direction) + { + app_throughput_send_command(THROUGHPUT_OP_THROUGHPUT_TEST_DATA, + app_throughput_datapattern, throughputTestConfig.dataPacketSize - 4); + } + + return 0; +} + +static void app_throughput_test_data_handler(APP_THROUGHPUT_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + if ((WITH_RSP == throughputTestConfig.responseModel) && + (AI_TRANSPORT_SPP == app_ai_get_transport_type())) + { + app_throughput_send_command(THROUGHPUT_OP_THROUGHPUT_TEST_DATA_ACK, NULL, 0); + } +} + +static void app_throughput_test_data_ack_handler(APP_THROUGHPUT_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + if (throughputTestEnv.isThroughputTestOn && + (WITH_RSP == throughputTestConfig.responseModel)) + { + app_throughput_test_transmission_handler(NULL, 0); + } +} + +static void app_throughput_test_done_signal_handler(APP_THROUGHPUT_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + app_stop_throughput_test(); +} + +void app_stop_throughput_test(void) +{ + throughputTestEnv.isThroughputTestOn = false; + osTimerStop(app_throughput_pre_config_pending_timer_id); + osTimerStop(app_throughput_test_data_xfer_lasting_timer_id); +} + +static void app_throughput_test_config_handler(APP_THROUGHPUT_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + throughputTestConfig = *(THROUGHPUT_TEST_CONFIG_T *)ptrParam; + + TRACE(4,"%s patter %d time %d response %d", __func__, \ + throughputTestConfig.dataPattern, \ + throughputTestConfig.lastTimeInSecond, \ + throughputTestConfig.responseModel); + + // generate the data pattern + switch (throughputTestConfig.dataPattern) + { + case PATTERN_RANDOM: + { + for (uint32_t index = 0;index < THROUGHPUT_DATA_MAX_SIZE;index++) + { + app_throughput_datapattern[index] = (uint8_t)rand(); + } + break; + } + case PATTERN_11110000: + { + memset(app_throughput_datapattern, 0xF0, THROUGHPUT_DATA_MAX_SIZE); + break; + } + case PATTERN_10101010: + { + memset(app_throughput_datapattern, 0xAA, THROUGHPUT_DATA_MAX_SIZE); + break; + } + case PATTERN_ALL_1: + { + memset(app_throughput_datapattern, 0xFF, THROUGHPUT_DATA_MAX_SIZE); + break; + } + case PATTERN_ALL_0: + { + memset(app_throughput_datapattern, 0, THROUGHPUT_DATA_MAX_SIZE); + break; + } + case PATTERN_00001111: + { + memset(app_throughput_datapattern, 0x0F, THROUGHPUT_DATA_MAX_SIZE); + break; + } + case PATTERN_0101: + { + memset(app_throughput_datapattern, 0x55, THROUGHPUT_DATA_MAX_SIZE); + break; + } + default: + throughputTestConfig.dataPattern = 0; + break; + } + + throughputTestEnv.isThroughputTestOn = true; + throughputTestEnv.conidx = app_ai_if_get_ble_connection_index(); + TRACE(2, "conidx 0x%x useSpecificConnParameter %d", throughputTestEnv.conidx, throughputTestConfig.isToUseSpecificConnParameter); + + // check whether need to use the new conn parameter + if (AI_TRANSPORT_BLE == app_ai_get_transport_type() + && throughputTestConfig.isToUseSpecificConnParameter) + { + if (throughputTestEnv.conidx != 0xFF) + { + l2cap_update_param(throughputTestEnv.conidx, throughputTestConfig.minConnIntervalInMs, + throughputTestConfig.maxConnIntervalInMs, + THROUGHPUT_BLE_CONNECTION_SUPERVISOR_TIMEOUT_IN_MS, + THROUGHPUT_BLE_CONNECTION_SLAVELATENCY); + } + + osTimerStart(app_throughput_pre_config_pending_timer_id, + APP_THROUGHPUT_PRE_CONFIG_PENDING_TIME_IN_MS); + } + else + { + app_throughput_send_command(THROUGHPUT_OP_INFORM_THROUGHPUT_TEST_CONFIG, + (uint8_t *)&throughputTestConfig, sizeof(throughputTestConfig)); + + if (UP_STREAM == throughputTestConfig.direction) + { + app_throughput_test_transmission_handler(NULL, 0); + osTimerStart(app_throughput_test_data_xfer_lasting_timer_id, + throughputTestConfig.lastTimeInSecond*1000); + } + } +} + + +APP_THROUGHPUT_CMD_INSTANCE_T through_put_table[APP_THROUGHPUT_CMD_INSTANCE_NUMBER] = +{ + {THROUGHPUT_OP_INFORM_THROUGHPUT_TEST_CONFIG, app_throughput_test_config_handler}, + {THROUGHPUT_OP_THROUGHPUT_TEST_DATA, app_throughput_test_data_handler}, + {THROUGHPUT_OP_THROUGHPUT_TEST_DATA_ACK, app_throughput_test_data_ack_handler}, + {THROUGHPUT_OP_THROUGHPUT_TEST_DONE, app_throughput_test_done_signal_handler} +}; + diff --git a/services/through_put/app_through_put.h b/services/through_put/app_through_put.h new file mode 100644 index 0000000..624bceb --- /dev/null +++ b/services/through_put/app_through_put.h @@ -0,0 +1,177 @@ +#ifndef APP_THROUGH_PUT_H_ +#define APP_THROUGH_PUT_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "app_spp.h" + +#define APP_THROUGHPUT_CMD_INSTANCE_NUMBER 4 + +#define THROUGHPUT_BLE_CONNECTION_INTERVAL_MIN_IN_MS 50 +#define THROUGHPUT_BLE_CONNECTION_INTERVAL_MAX_IN_MS 60 +#define THROUGHPUT_BLE_CONNECTION_SUPERVISOR_TIMEOUT_IN_MS 20000 +#define THROUGHPUT_BLE_CONNECTION_SLAVELATENCY 0 + +typedef enum +{ + PATTERN_RANDOM = 0, + PATTERN_11110000, + PATTERN_10101010, + PATTERN_ALL_1, + PATTERN_ALL_0, + PATTERN_00001111, + PATTERN_0101, +} THROUGHPUT_TEST_DATA_PATTER_E; + +typedef enum +{ + UP_STREAM = 0, + DOWN_STREAM +} THROUGHPUT_TEST_DATA_DIRECTION_E; + +typedef enum +{ + WITHOUT_RSP = 0, + WITH_RSP +} THROUGHPUT_TEST_RESPONSE_MODEL_E; + + +typedef struct +{ + bool isThroughputTestOn; + uint8_t conidx; +} THROUGHPUT_TEST_ENV_T; + +typedef struct +{ + uint8_t dataPattern; + uint16_t lastTimeInSecond; + uint16_t dataPacketSize; + uint8_t direction; + uint8_t responseModel; + uint8_t isToUseSpecificConnParameter; + uint16_t minConnIntervalInMs; + uint16_t maxConnIntervalInMs; + uint8_t reserve[4]; +} __attribute__((__packed__)) THROUGHPUT_TEST_CONFIG_T; + +/** + * @brief The command code + * + */ +typedef enum +{ +#ifdef __GMA_VOICE__ + /* 9 */ THROUGHPUT_OP_INFORM_THROUGHPUT_TEST_CONFIG = 0x89, + /* 10 */ THROUGHPUT_OP_THROUGHPUT_TEST_DATA = 0x8A, + /* 11 */ THROUGHPUT_OP_THROUGHPUT_TEST_DATA_ACK = 0x8B, + /* 12 */ THROUGHPUT_OP_THROUGHPUT_TEST_DONE = 0x8C, +#else + /* 9 */ THROUGHPUT_OP_INFORM_THROUGHPUT_TEST_CONFIG = 0x8009, + /* 10 */ THROUGHPUT_OP_THROUGHPUT_TEST_DATA = 0x800A, + /* 11 */ THROUGHPUT_OP_THROUGHPUT_TEST_DATA_ACK = 0x800B, + /* 12 */ THROUGHPUT_OP_THROUGHPUT_TEST_DONE = 0x800C, +#endif +} APP_THROUGHPUT_CMD_CODE_E; + +/** + * @brief custom command playload + * + */ +#define THROUGHPUT_CMD_PAYLOAD_HEADER_LEN (2*sizeof(uint16_t)) + #define THROUGHPUT_DATA_MAX_SIZE (L2CAP_MTU - THROUGHPUT_CMD_PAYLOAD_HEADER_LEN) +typedef struct +{ + uint16_t cmdCode; /**< command code, from APP_SV_CMD_CODE_E */ + uint16_t paramLen; /**< length of the following parameter */ + uint8_t param[THROUGHPUT_DATA_MAX_SIZE]; +} APP_THROUGHPUT_CMD_PAYLOAD_T; + +/** + * @brief through put command definition data structure + * + */ +typedef void (*app_through_cmd_handler_t)(APP_THROUGHPUT_CMD_CODE_E cmdCode, uint8_t* ptrParam, uint32_t paramLen); +typedef struct +{ + uint32_t cmdCode; + app_through_cmd_handler_t cmdHandler; /**< command handler function */ +} APP_THROUGHPUT_CMD_INSTANCE_T; +extern APP_THROUGHPUT_CMD_INSTANCE_T through_put_table[]; + +#ifdef __cplusplus +extern "C" { +#endif + + +/*--------------------------------------------------------------------------- + * app_throughput_cmd_send_done + *--------------------------------------------------------------------------- + * + *Synopsis: + * thourghput cmd send done callback + * + * Parameters: + * param1 -- callback data + * param2 -- callback data length + * + * Return: + * void + */ +uint32_t app_throughput_cmd_send_done(void *param1, uint32_t param2); + +/*--------------------------------------------------------------------------- + * app_throughput_receive_cmd + *--------------------------------------------------------------------------- + * + *Synopsis: + * thourghput receive and handle cmd + * + * Parameters: + * param1 -- receive data + * param2 -- receive data length + * + * Return: + * void + */ +uint32_t app_throughput_receive_cmd(void *param1, uint32_t param2); + +/*--------------------------------------------------------------------------- + * app_stop_throughput_test + *--------------------------------------------------------------------------- + * + *Synopsis: + * stop throughput test + * + * Parameters: + * void + * + * Return: + * void + */ +void app_stop_throughput_test(void); + +/*--------------------------------------------------------------------------- + * app_throughput_test_init + *--------------------------------------------------------------------------- + * + *Synopsis: + * init throughput test + * + * Parameters: + * void + * + * Return: + * void + */ +void app_throughput_test_init(void); + +#ifdef __cplusplus + } +#endif + + +#endif //APP_THROUGH_PUT_H_ + diff --git a/services/tota/Makefile b/services/tota/Makefile new file mode 100644 index 0000000..06601b8 --- /dev/null +++ b/services/tota/Makefile @@ -0,0 +1,94 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +src_obj := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +TOTA_LIB_NAME := libtota + +$(TOTA_LIB_NAME)-y := $(src_obj) + +obj-y += $(TOTA_LIB_NAME).a + +subdir-ccflags-y += -Iplatform/drivers/ana \ + -Iplatform/hal \ + -Iservices/bluedroid/adapter/src \ + -Iapps/key \ + -Iservices/app_tws/inc \ + -Iservices/audio_eq \ + -Iservices/fs/fat \ + -Iservices/fs/sd \ + -Iservices/fs/fat/ChaN \ + $(BT_IF_INCLUDES) \ + -Iservices/overlay \ + -Iservices/nvrecord \ + -Iservices/resources \ + -Iservices/multimedia/audio/codec/sbc/inc \ + -Iservices/bt_app/a2dp_codecs/include \ + -Iplatform/drivers/uarthci \ + -Iplatform/drivers/ana \ + -Iplatform/drivers/bt \ + -Iutils/cqueue \ + -Iutils/heap \ + -Iutils/retention_ram \ + -Iservices/audioflinger \ + -Iutils/lockcqueue \ + -Iutils/intersyshci \ + -Iutils/boot_struct \ + -Iutils/encrypt \ + -Iutils/sha256 \ + -Iapps/main \ + -Iapps/common \ + -Iapps/audioplayers \ + -Iservices/app_ai/inc \ + -Iapps/factory \ + -Iservices/ble_app \ + -Iservices/ble_app/app_tota \ + -Iservices/ble_stack/ble_ip \ + -Iservices/ble_stack/hl/api \ + -Iservices/ble_stack/app/api/ \ + -Iservices/ble_stack/common/api/ \ + -Iservices/ble_stack/hl/inc/ \ + -Iservices/ble_stack/ke/api \ + -Iservices/bridge/ \ + -Iservices/ble_stack/hl/src/gap/ \ + -Iservices/ble_stack/hl/src/gap/gapc/ \ + -Iservices/ble_stack/hl/src/gap/gapm/ \ + -Iservices/ble_stack/hl/src/gap/smpc/ \ + -Iservices/ble_stack/ke/src/ \ + -Iservices/ble_stack/hl/src/gatt/attc/ \ + -Iservices/ble_stack/hl/src/gatt/attm/ \ + -Iservices/ble_stack/hl/src/gatt/atts/ \ + -Iservices/ble_stack/hl/src/gatt/gattc/ \ + -Iservices/ble_stack/hl/src/gatt/gattm/ \ + -Iservices/ble_stack/hl/src/gatt/ \ + -Iservices/ble_stack/hl/src/l2c/l2cc/ \ + -Iservices/ble_stack/hl/src/l2c/l2cm/ \ + -Iservices/ble_stack/hci/api/ \ + -Iservices/ble_stack/hci/src/ \ + -Iservices/ble_stack/app/src/ \ + -Iservices/ble_profiles/htp/htpt/api/ \ + -Iservices/ble_profiles/htp/htpt/src/ \ + -Iservices/ble_profiles/htp/ \ + -Iservices/ble_profiles/datapath/datapathps/api/ \ + -Iservices/ble_app/app_main/ \ + -Iservices/ble_app/app_htp/ \ + -Iservices/ble_app/app_datapath/ \ + -Iservices/bt_app \ + -Iservices/ble_app/app_vob \ + -Iservices/multimedia/speech/codec/codecs/adpcm \ + -Iservices/ble_app/app_smartvoice \ + -Iservices/ble_profiles/smartvoice \ + -Iservices/anc_spp_tool \ + -Iservices/tws/inc \ + -Iservices/ibrt_core/inc \ + -Iutils/crc32 \ + -Iservices/app_ibrt/inc \ + -Ithirdparty/userapi \ + -Iapps/battery \ + -Iservices/nv_section/factory_section \ + -Iservices/ \ + -Iservices/app_tws/inc/ + diff --git a/services/tota/app_spp_tota.cpp b/services/tota/app_spp_tota.cpp new file mode 100644 index 0000000..8f90c7a --- /dev/null +++ b/services/tota/app_spp_tota.cpp @@ -0,0 +1,373 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_chipid.h" +#include "analog.h" +#include "app_audio.h" +#include "app_status_ind.h" +#include "app_bt_stream.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +//#include "nvrecord_dev.h" + +#include "bluetooth.h" +#include "cqueue.h" +#include "resources.h" +#include "app_spp_tota.h" +#include "app_tota_cmd_code.h" +#include "app_tota.h" +#include "app_spp.h" +#include "app_tota_cmd_handler.h" +#include "app_tota_data_handler.h" +#include "plat_types.h" +#include "spp_api.h" +#include "sdp_api.h" +//#include "app_bt_conn_mgr.h" + +#include "tota_stream_data_transfer.h" + +static bool isTotaSppConnected = false; +static struct spp_device *tota_spp_dev = NULL; +static struct spp_service *totaSppService = NULL; + +osMutexDef(tota_spp_mutex); +osMutexDef(tota_credit_mutex); + +static btif_sdp_record_t *tota_sdp_record = NULL; + + +static uint8_t totaSppTxBuf[TOTA_SPP_TX_BUF_SIZE]; +static uint8_t spp_rx_buf[SPP_RECV_BUFFER_SIZE]; + +static uint32_t occupiedTotaSppTxBufSize; +static uint32_t offsetToFillTotaSppTxData; +static uint8_t* ptrTotaSppTxBuf; + +#if (TOTA_SHARE_TX_RX_BUF==1) +static const bool spp_share_application_rx_tx_buf = true; +#else +static const bool spp_share_application_rx_tx_buf = false; +#endif + +/**/ +static map s_module_map; +static tota_callback_func_t s_module_func; +static APP_TOTA_MODULE_E s_module; + +/* register callback module */ +void tota_callback_module_register(APP_TOTA_MODULE_E module, tota_callback_func_t tota_callback_func) +{ + map::iterator it = s_module_map.find(module); + if ( it == s_module_map.end() ) + { + TOTA_LOG_DBG(0, "add to map"); + s_module_map.insert(make_pair(module, tota_callback_func)); + } + else + { + TOTA_LOG_DBG(0, "already exist, not add"); + } +} +/* set current module */ +void tota_callback_module_set(APP_TOTA_MODULE_E module) +{ + map::iterator it = s_module_map.find(module); + if ( it != s_module_map.end() ) + { + s_module = module; + s_module_func = it->second; + + TOTA_LOG_DBG(1, "set %d module success", module); + } + else + { + TOTA_LOG_DBG(0, "not find callback func by module"); + } +} + +/* get current module */ +APP_TOTA_MODULE_E tota_callback_module_get() +{ + return s_module; +} + +/* is tota busy, use to handle sniff */ +bool spp_tota_in_progress(void) +{ + TOTA_LOG_DBG(2,"[%s] isTotaSppConnected:%d", __func__, isTotaSppConnected); + if(isTotaSppConnected == true) + return true; + else + return false; +} + +void app_spp_tota_share_buf_create(uint8_t** tota_tx_buf, uint8_t** tota_rx_buf) +{ + *tota_tx_buf = NULL; + *tota_rx_buf = NULL; + + if(spp_share_application_rx_tx_buf == true){ + *tota_tx_buf = totaSppTxBuf; + *tota_rx_buf = spp_rx_buf; + } +} + +bool app_spp_tota_is_to_share_buf(void) +{ + return spp_share_application_rx_tx_buf; +} + +uint8_t * app_spp_tota_share_tx_buf_get(void) +{ + return (spp_share_application_rx_tx_buf == true)?(totaSppTxBuf):(NULL); +} +uint8_t * app_spp_tota_share_rx_buf_get(void) +{ + return (spp_share_application_rx_tx_buf == true)?(spp_rx_buf):(NULL); +} + +uint16_t app_spp_tota_tx_buf_size(void) +{ + return TOTA_SPP_TX_BUF_SIZE; +} + +void app_spp_tota_init_tx_buf(uint8_t* ptr) +{ + ptrTotaSppTxBuf = ptr; + occupiedTotaSppTxBufSize = 0; + offsetToFillTotaSppTxData = 0; +} + +extern "C" APP_TOTA_CMD_RET_STATUS_E app_tota_data_received(uint8_t* ptrData, uint32_t dataLength); +extern "C" APP_TOTA_CMD_RET_STATUS_E app_tota_cmd_received(uint8_t* ptrData, uint32_t dataLength); + + +/**************************************************************************** + * TOTA SPP SDP Entries + ****************************************************************************/ + +/*--------------------------------------------------------------------------- + * + * ServiceClassIDList + */ +static const U8 TotaSppClassId[] = { + SDP_ATTRIB_HEADER_8BIT(3), /* Data Element Sequence, 6 bytes */ + SDP_UUID_16BIT(SC_SERIAL_PORT), /* Hands-Free UUID in Big Endian */ +}; + +static const U8 TotaSppProtoDescList[] = { + SDP_ATTRIB_HEADER_8BIT(12), /* Data element sequence, 12 bytes */ + + /* Each element of the list is a Protocol descriptor which is a + * data element sequence. The first element is L2CAP which only + * has a UUID element. + */ + SDP_ATTRIB_HEADER_8BIT(3), /* Data element sequence for L2CAP, 3 + * bytes + */ + + SDP_UUID_16BIT(PROT_L2CAP), /* Uuid16 L2CAP */ + + /* Next protocol descriptor in the list is RFCOMM. It contains two + * elements which are the UUID and the channel. Ultimately this + * channel will need to filled in with value returned by RFCOMM. + */ + + /* Data element sequence for RFCOMM, 5 bytes */ + SDP_ATTRIB_HEADER_8BIT(5), + + SDP_UUID_16BIT(PROT_RFCOMM), /* Uuid16 RFCOMM */ + + /* Uint8 RFCOMM channel number - value can vary */ + SDP_UINT_8BIT(RFCOMM_CHANNEL_TOTA) +}; + +/* + * BluetoothProfileDescriptorList + */ +static const U8 TotaSppProfileDescList[] = { + SDP_ATTRIB_HEADER_8BIT(8), /* Data element sequence, 8 bytes */ + + /* Data element sequence for ProfileDescriptor, 6 bytes */ + SDP_ATTRIB_HEADER_8BIT(6), + + SDP_UUID_16BIT(SC_SERIAL_PORT), /* Uuid16 SPP */ + SDP_UINT_16BIT(0x0102) /* As per errata 2239 */ +}; + +/* + * * OPTIONAL * ServiceName + */ +static const U8 TotaSppServiceName1[] = { + SDP_TEXT_8BIT(5), /* Null terminated text string */ + 'S', 'p', 'p', '1', '\0' +}; + +static const U8 TotaSppServiceName2[] = { + SDP_TEXT_8BIT(5), /* Null terminated text string */ + 'S', 'p', 'p', '2', '\0' +}; + +/* SPP attributes. + * + * This is a ROM template for the RAM structure used to register the + * SPP SDP record. + */ +//static const SdpAttribute TotaSppSdpAttributes1[] = { +static sdp_attribute_t TotaSppSdpAttributes1[] = { + + SDP_ATTRIBUTE(AID_SERVICE_CLASS_ID_LIST, TotaSppClassId), + + SDP_ATTRIBUTE(AID_PROTOCOL_DESC_LIST, TotaSppProtoDescList), + + SDP_ATTRIBUTE(AID_BT_PROFILE_DESC_LIST, TotaSppProfileDescList), + + /* SPP service name*/ + SDP_ATTRIBUTE((AID_SERVICE_NAME + 0x0100), TotaSppServiceName1), +}; + +/* +static sdp_attribute_t TotaSppSdpAttributes2[] = { + + SDP_ATTRIBUTE(AID_SERVICE_CLASS_ID_LIST, TotaSppClassId), + + SDP_ATTRIBUTE(AID_PROTOCOL_DESC_LIST, TotaSppProtoDescList), + + SDP_ATTRIBUTE(AID_BT_PROFILE_DESC_LIST, TotaSppProfileDescList), + + + SDP_ATTRIBUTE((AID_SERVICE_NAME + 0x0100), TotaSppServiceName2), +}; +*/ + +int tota_spp_handle_data_event_func(void *pDev, uint8_t process, uint8_t *pData, uint16_t dataLen) +{ + TOTA_LOG_DBG(2,"[%s]data receive length = %d", __func__, dataLen); + TOTA_LOG_DUMP("[0x%x]", pData, dataLen); + + if ( s_module_func.tota_spp_data_receive_hanle != NULL ) + s_module_func.tota_spp_data_receive_hanle(pData, (uint32_t)dataLen); + + // the first two bytes of the data packet is the fixed value 0xFFFF + app_tota_handle_received_data(pData, dataLen); + + return 0; +} + +static void spp_tota_callback(struct spp_device *locDev, struct spp_callback_parms *Info) +{ + if (BTIF_SPP_EVENT_REMDEV_CONNECTED == Info->event) + { + TOTA_LOG_DBG(1,"::BTIF_SPP_EVENT_REMDEV_CONNECTED %d\n", Info->event); + isTotaSppConnected = true; + app_tota_connected(APP_TOTA_CONNECTED); + app_tota_update_datapath(APP_TOTA_VIA_SPP); + //conn_stop_connecting_mobile_supervising(); + if ( s_module_func.tota_spp_connected != NULL ) + s_module_func.tota_spp_connected(); + } + else if (BTIF_SPP_EVENT_REMDEV_DISCONNECTED == Info->event) + { + TOTA_LOG_DBG(1,"::BTIF_SPP_EVENT_REMDEV_DISCONNECTED %d\n", Info->event); + isTotaSppConnected = false; + app_tota_disconnected(APP_TOTA_DISCONNECTED); + app_tota_update_datapath(APP_TOTA_PATH_IDLE); + if ( s_module_func.tota_spp_disconnected != NULL ) + s_module_func.tota_spp_disconnected(); + } + else if (BTIF_SPP_EVENT_DATA_SENT == Info->event) + { + app_tota_tx_done_callback(); + if ( s_module_func.tota_spp_tx_done != NULL ) + s_module_func.tota_spp_tx_done(); + } + else + { + TOTA_LOG_DBG(1,"::unknown event %d\n", Info->event); + } +} + +bool app_spp_tota_send_data(uint8_t* ptrData, uint16_t length) +{ + if (!isTotaSppConnected) + { + return false; + } + btif_spp_write(tota_spp_dev, (char *)ptrData, &length); + return true; +} + +void app_spp_tota_init(void) +{ + uint8_t *rx_buf; + uint8_t * tx_buf; + osMutexId mid; + btif_sdp_record_param_t param; + + if(tota_spp_dev == NULL) + tota_spp_dev = btif_create_spp_device(); + + if(app_spp_tota_is_to_share_buf() == true){ + app_spp_tota_share_buf_create(&tx_buf,&rx_buf); + }else{ + rx_buf = &spp_rx_buf[0]; + tx_buf = &totaSppTxBuf[0]; + } + + tota_spp_dev->rx_buffer = rx_buf; + + app_spp_tota_init_tx_buf(tx_buf); + btif_spp_init_rx_buf(tota_spp_dev, rx_buf, SPP_RECV_BUFFER_SIZE); + + + mid = osMutexCreate(osMutex(tota_spp_mutex)); + if (!mid) { + ASSERT(0, "cannot create mutex"); + } + + osMutexId creditMutex = osMutexCreate(osMutex(tota_credit_mutex)); + + tota_spp_dev->creditMutex = creditMutex; + + if (tota_sdp_record == NULL) + tota_sdp_record = btif_sdp_create_record(); + + param.attrs = &TotaSppSdpAttributes1[0], + param.attr_count = ARRAY_SIZE(TotaSppSdpAttributes1); + param.COD = BTIF_COD_MAJOR_PERIPHERAL; + btif_sdp_record_setup(tota_sdp_record, ¶m); + + if(totaSppService == NULL) + totaSppService = btif_create_spp_service(); + + totaSppService->rf_service.serviceId = RFCOMM_CHANNEL_TOTA; + totaSppService->numPorts = 0; + btif_spp_service_setup(tota_spp_dev, totaSppService, tota_sdp_record); + + tota_spp_dev->portType = BTIF_SPP_SERVER_PORT; + tota_spp_dev->app_id = BTIF_APP_SPP_SERVER_TOTA_ID; + tota_spp_dev->spp_handle_data_event_func = tota_spp_handle_data_event_func; + btif_spp_init_device(tota_spp_dev, 5, mid); + + btif_spp_open(tota_spp_dev, NULL, spp_tota_callback); +} diff --git a/services/tota/app_spp_tota.h b/services/tota/app_spp_tota.h new file mode 100644 index 0000000..b808860 --- /dev/null +++ b/services/tota/app_spp_tota.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_SPP_TOTA_H__ +#define __APP_SPP_TOTA_H__ +#include +#include +using namespace std; + +#define TOTA_SPP_ID 0 +#define TOTA_SPP_MAX_PACKET_SIZE 600 +#define TOTA_SPP_MAX_PACKET_NUM 5 + + +#define TOTA_SPP_TX_BUF_SIZE (TOTA_SPP_MAX_PACKET_SIZE*TOTA_SPP_MAX_PACKET_NUM) + +#define APP_TOTA_DATA_CMD_TIME_OUT_IN_MS 5000 + +/** + * @brief Type of the tota module + * + */ +typedef enum +{ + APP_TOTA_AUDIO_DUMP = 0, + APP_TOTA_MIC, + APP_TOTA_FLASH, + APP_TOTA_ANC, + APP_TOTA_GENERAL, + APP_TOTA_CUSTOM, + + APP_TOTA_MODULE_NONE = 0xFF +} APP_TOTA_MODULE_E; + + +typedef struct{ + void (*tota_spp_connected)(void); + void (*tota_spp_disconnected)(void); + void (*tota_spp_tx_done)(void); + void (*tota_spp_data_receive_hanle)(uint8_t * buf, uint32_t len); +}tota_callback_func_t; + + +void tota_callback_module_register(APP_TOTA_MODULE_E module, tota_callback_func_t tota_callback_func); +void tota_callback_module_set(APP_TOTA_MODULE_E module); +APP_TOTA_MODULE_E tota_callback_module_get(); + + + +typedef void(*app_spp_tota_tx_done_t)(void); +void app_spp_tota_register_tx_done(app_spp_tota_tx_done_t callback); +void app_spp_tota_init(void); + + +uint16_t app_spp_tota_tx_buf_size(void); +void app_spp_tota_init_tx_buf(uint8_t* ptr); +uint8_t* app_spp_tota_fill_data_into_tx_buf(uint8_t* ptrData, uint32_t dataLen); + +bool app_spp_tota_send_data(uint8_t* ptrData, uint16_t length); + +/* for sniff */ +bool spp_tota_in_progress(void); + +#endif + diff --git a/services/tota/app_spp_tota_general_service.cpp b/services/tota/app_spp_tota_general_service.cpp new file mode 100644 index 0000000..90bf1fc --- /dev/null +++ b/services/tota/app_spp_tota_general_service.cpp @@ -0,0 +1,417 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include +#include "cmsis_os.h" +#include "hal_uart.h" +#include "hal_timer.h" +#include "audioflinger.h" +#include "lockcqueue.h" +#include "hal_trace.h" +#include "hal_cmu.h" +#include "hal_chipid.h" +#include "analog.h" +#include "app_audio.h" +#include "app_status_ind.h" +#include "app_bt_stream.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +//#include "nvrecord_dev.h" + +#include "bluetooth.h" +#include "cqueue.h" +#ifdef MBED +#include "rtos.h" +#endif +#include "resources.h" +#include "app_spp_tota.h" +#include "app_tota_cmd_code.h" +#include "app_tota.h" +#include "app_spp.h" +#include "app_tota_cmd_handler.h" +#include "app_tota_data_handler.h" + +#include "plat_types.h" +#include "sdp_api.h" + +osMutexDef(tota_spp_gen_mutex); + +static bool isTotaSppGeneralConnected = false; +static struct spp_device *tota_spp_gen_dev = NULL; +static struct spp_service *totaSppGenService = NULL; +static btif_sdp_record_t *tota_sdp_gen_record = NULL; + +osThreadId tota_spp_gen_read_thread_id = NULL; + +static app_spp_tota_tx_done_t app_spp_tota_gen_tx_done_func = NULL; + +#if (TOTA_SHARE_TX_RX_BUF==1) +extern void app_spp_tota_share_buf_create(uint8_t** tota_tx_buf, uint8_t** tota_rx_buf); +extern bool app_spp_tota_is_to_share_buf(void); +extern uint8_t * app_spp_tota_share_tx_buf_get(void); +extern uint8_t * app_spp_tota_share_rx_buf_get(void); +extern uint16_t app_spp_tota_tx_buf_size(void); +#else +static uint8_t spp_rx_buf[SPP_RECV_BUFFER_SIZE]; +static uint8_t totaSppGenTxBuf[TOTA_SPP_TX_BUF_SIZE]; +#endif + +static uint32_t occupiedTotaSppGenTxBufSize; +static uint32_t offsetToFillTotaSppGenTxData; +static uint8_t* ptrTotaSppGenTxBuf; + +uint16_t app_spp_tota_gen_tx_buf_size(void) +{ + return TOTA_SPP_TX_BUF_SIZE; +} + +void app_spp_tota_gen_init_tx_buf(uint8_t* ptr) +{ + ptrTotaSppGenTxBuf = ptr; + occupiedTotaSppGenTxBufSize = 0; + offsetToFillTotaSppGenTxData = 0; +} + +static void app_spp_tota_gen_free_tx_buf(uint8_t* ptrData, uint32_t dataLen) +{ + if (occupiedTotaSppGenTxBufSize > 0) + { + occupiedTotaSppGenTxBufSize -= dataLen; + } + TOTA_LOG_DBG(1,"occupiedTotaSppGenTxBufSize %d", occupiedTotaSppGenTxBufSize); +} + +uint8_t* app_spp_tota_gen_fill_data_into_tx_buf(uint8_t* ptrData, uint32_t dataLen) +{ + ASSERT((occupiedTotaSppGenTxBufSize + dataLen) < TOTA_SPP_TX_BUF_SIZE, + "Pending SPP General tx data has exceeded the tx buffer size !"); + + + if ((offsetToFillTotaSppGenTxData + dataLen) > TOTA_SPP_TX_BUF_SIZE) + { + offsetToFillTotaSppGenTxData = 0; + } + + uint8_t* filledPtr = ptrTotaSppGenTxBuf + offsetToFillTotaSppGenTxData; + memcpy(filledPtr, ptrData, dataLen); + + offsetToFillTotaSppGenTxData += dataLen; + + occupiedTotaSppGenTxBufSize += dataLen; + + TOTA_LOG_DBG(3,"dataLen %d offsetToFillTotaSppGenTxData %d occupiedTotaSppGenTxBufSize %d", + dataLen, offsetToFillTotaSppGenTxData, occupiedTotaSppGenTxBufSize); + + return filledPtr; +} + +extern "C" APP_TOTA_CMD_RET_STATUS_E app_tota_data_received(uint8_t* ptrData, uint32_t dataLength); +extern "C" APP_TOTA_CMD_RET_STATUS_E app_tota_cmd_received(uint8_t* ptrData, uint32_t dataLength); + + +/**************************************************************************** + * TOTA SPP SDP Entries + ****************************************************************************/ + #if 0 + static const U8 TotaGenClassId[] = { + SDP_ATTRIB_HEADER_8BIT(3), /* Data Element Sequence, 6 bytes */ + SDP_UUID_16BIT(SC_SERIAL_PORT), /* Hands-Free UUID in Big Endian */ +}; +//#else +/* 128 bit UUID in Big Endian a8b1fbc4-7855-4235-8633-ff36c8235e16 */ +static const uint8_t TOTA_GENERAL_UUID_128[16] = { + 0x16, 0x5e, 0x23, 0xc8, 0x36, 0xff, 0x33, 0x86, 0x35, 0x42, 0x55, 0x78, 0xc4, 0xfb, 0xb1, 0xa8}; + +/*--------------------------------------------------------------------------- + * + * ServiceClassIDList + */ +static const U8 TotaGenClassId[] = { + SDP_ATTRIB_HEADER_8BIT(17), /* Data Element Sequence, 17 bytes */ + SDP_UUID_128BIT(TOTA_GENERAL_UUID_128), /* 128 bit UUID in Big Endian */ +}; +#else +static const U8 TotaGenClassId[] = { + SDP_ATTRIB_HEADER_8BIT(17), + DETD_UUID + DESD_16BYTES, + 0x8a, + 0x48,\ + 0x2a,\ + 0x08,\ + 0x55,\ + 0x07,\ + 0x42,\ + 0xac,\ + 0xb6,\ + 0x73,\ + 0xa8,\ + 0x8d,\ + 0xf4,\ + 0x8b,\ + 0x3f,\ + 0xc7, +}; + +#endif + +static const U8 TotaSppGenProtoDescList[] = { + SDP_ATTRIB_HEADER_8BIT(12), /* Data element sequence, 12 bytes */ + + /* Each element of the list is a Protocol descriptor which is a + * data element sequence. The first element is L2CAP which only + * has a UUID element. + */ + SDP_ATTRIB_HEADER_8BIT(3), /* Data element sequence for L2CAP, 3 + * bytes + */ + + SDP_UUID_16BIT(PROT_L2CAP), /* Uuid16 L2CAP */ + + /* Next protocol descriptor in the list is RFCOMM. It contains two + * elements which are the UUID and the channel. Ultimately this + * channel will need to filled in with value returned by RFCOMM. + */ + + /* Data element sequence for RFCOMM, 5 bytes */ + SDP_ATTRIB_HEADER_8BIT(5), + + SDP_UUID_16BIT(PROT_RFCOMM), /* Uuid16 RFCOMM */ + + /* Uint8 RFCOMM channel number - value can vary */ + SDP_UINT_8BIT(RFCOMM_CHANNEL_TOTA_GENERAL) +}; + +/* + * BluetoothProfileDescriptorList + */ +static const U8 TotaSppGenProfileDescList[] = { + SDP_ATTRIB_HEADER_8BIT(8), /* Data element sequence, 8 bytes */ + + /* Data element sequence for ProfileDescriptor, 6 bytes */ + SDP_ATTRIB_HEADER_8BIT(6), + + SDP_UUID_16BIT(SC_SERIAL_PORT), /* Uuid16 SPP */ + SDP_UINT_16BIT(0x0102) /* As per errata 2239 */ +}; + +/* + * * OPTIONAL * ServiceName + */ +static const U8 TotaSppGenServiceName1[] = { + SDP_TEXT_8BIT(8), /* Null terminated text string */ + 'S', 'p', 'p', 'G','e','n', '1','\0' +}; + +static const U8 TotaSppGenServiceName2[] = { + SDP_TEXT_8BIT(8), /* Null terminated text string */ + 'S', 'p', 'p', 'G','e','n', '2','\0' +}; + +/* SPP attributes. + * + * This is a ROM template for the RAM structure used to register the + * SPP SDP record. + */ +static sdp_attribute_t TotaSppGenSdpAttributes1[] = { + + SDP_ATTRIBUTE(AID_SERVICE_CLASS_ID_LIST, TotaGenClassId), + + SDP_ATTRIBUTE(AID_PROTOCOL_DESC_LIST, TotaSppGenProtoDescList), + + SDP_ATTRIBUTE(AID_BT_PROFILE_DESC_LIST, TotaSppGenProfileDescList), + + // SPP service name + SDP_ATTRIBUTE((AID_SERVICE_NAME + 0x0100), TotaSppGenServiceName1), +}; + +/* +static sdp_attribute_t TotaSppGenSdpAttributes2[] = { + + SDP_ATTRIBUTE(AID_SERVICE_CLASS_ID_LIST, TotaGenClassId), + + SDP_ATTRIBUTE(AID_PROTOCOL_DESC_LIST, TotaSppGenProtoDescList), + + SDP_ATTRIBUTE(AID_BT_PROFILE_DESC_LIST, TotaSppGenProfileDescList), + + // SPP service name + SDP_ATTRIBUTE((AID_SERVICE_NAME + 0x0100), TotaSppGenServiceName2), +}; +*/ + +extern "C" void reset_programmer_state(unsigned char **buf, size_t *len); +extern unsigned char *g_buf; +extern size_t g_len; + +static int tota_general_spp_handle_data_event_func(void *pDev, uint8_t process, uint8_t *pData, uint16_t dataLen) +{ + TOTA_LOG_DBG(2,"[%s]data receive length = %d", __func__, dataLen); + TOTA_LOG_DUMP("[0x%x]", pData, dataLen); + // the first two bytes of the data packet is the fixed value 0xFFFF + app_tota_handle_received_data(pData, dataLen); + + return 0; +} + +#if 0 +static void tota_spp_general_read_thread(const void *arg) +{ + uint8_t buffer[TOTA_SPP_MAX_PACKET_SIZE]; + U16 maxBytes; + + while (1) + { + maxBytes = TOTA_SPP_MAX_PACKET_SIZE; + + btif_spp_read(tota_spp_gen_dev, (char *)buffer, &maxBytes); + TOTA_LOG_DBG(2,"[%s]general data receive length = %d",__func__,maxBytes); + TOTA_LOG_DUMP("[0x%x]",buffer,maxBytes); + + // the first two bytes of the data packet is the fixed value 0xFFFF + app_tota_handle_received_data(buffer, maxBytes); + } +} + +static void app_spp_tota_gen_create_read_thread(void) +{ + TOTA_LOG_DBG(2,"%s %d\n", __func__, __LINE__); + tota_spp_gen_read_thread_id = osThreadCreate(osThread(tota_spp_general_read_thread), NULL); +} + +static void app_spp_tota_gen_close_read_thread(void) +{ + TOTA_LOG_DBG(2,"%s %d\n", __func__, __LINE__); + if(tota_spp_gen_read_thread_id) + { + osThreadTerminate(tota_spp_gen_read_thread_id); + tota_spp_gen_read_thread_id = NULL; + } +} +#endif +static void spp_tota_gen_callback(struct spp_device *locDev, struct spp_callback_parms *Info) +{ + TOTA_LOG_DBG(1,"%s",__func__); + if (BTIF_SPP_EVENT_REMDEV_CONNECTED == Info->event) + { + TOTA_LOG_DBG(1,"::SPP_GENERAL_EVENT_REMDEV_CONNECTED %d\n", Info->event); + isTotaSppGeneralConnected = true; +// app_spp_tota_gen_create_read_thread(); + app_tota_general_connected(APP_TOTA_CONNECTED); + app_tota_update_datapath(APP_TOTA_GEN_VIA_SPP); + //conn_stop_connecting_mobile_supervising(); + } + else if (BTIF_SPP_EVENT_REMDEV_DISCONNECTED == Info->event) + { + TOTA_LOG_DBG(1,"::SPP_GENERAL_EVENT_REMDEV_DISCONNECTED %d\n", Info->event); + isTotaSppGeneralConnected = false; +// app_spp_tota_gen_close_read_thread(); + app_tota_disconnected(APP_TOTA_DISCONNECTED); + app_tota_update_datapath(APP_TOTA_PATH_IDLE); + + app_spp_tota_gen_tx_done_func = NULL; + } + else if (BTIF_SPP_EVENT_DATA_SENT == Info->event) + { + //app_spp_tota_gen_free_tx_buf(Info->tx_buf, Info->tx_data_len); + struct spp_tx_done *pTxDone = (struct spp_tx_done *)(Info->p.other); + app_spp_tota_gen_free_tx_buf(pTxDone->tx_buf, pTxDone->tx_data_length); + if (app_spp_tota_gen_tx_done_func) + { + app_spp_tota_gen_tx_done_func(); + } + } + else + { + TOTA_LOG_DBG(1,"::spp general unknown event %d\n", Info->event); + } +} + +static void app_spp_tota_gen_send_data(uint8_t* ptrData, uint16_t length) +{ + if (!isTotaSppGeneralConnected) + { + return; + } + + btif_spp_write(tota_spp_gen_dev, (char *)ptrData, &length); +} + +void app_tota_gen_send_cmd_via_spp(uint8_t* ptrData, uint32_t length) +{ + uint8_t* ptrBuf = app_spp_tota_gen_fill_data_into_tx_buf(ptrData, length); + app_spp_tota_gen_send_data(ptrBuf, (uint16_t)length); +} + +void app_tota_gen_send_data_via_spp(uint8_t* ptrData, uint32_t length) +{ + TOTA_LOG_DBG(2,"[%s]tota gen send data length = %d",__func__,length); + uint8_t* ptrBuf = app_spp_tota_gen_fill_data_into_tx_buf(ptrData, length); + app_spp_tota_gen_send_data(ptrBuf, (uint16_t)length); +} + +void app_spp_tota_gen_init(void) +{ + uint8_t *rx_buf; + uint8_t *tx_buf; + osMutexId mid; + btif_sdp_record_param_t param; + + if (tota_spp_gen_dev == NULL) + { + tota_spp_gen_dev = btif_create_spp_device(); + } + + if(app_spp_tota_is_to_share_buf() == true){ + app_spp_tota_share_buf_create(&tx_buf,&rx_buf); + } +#if (TOTA_SHARE_TX_RX_BUF==0) + else{ + rx_buf = &spp_rx_buf[0]; + tx_buf = &totaSppGenTxBuf[0]; + } +#endif + tota_spp_gen_dev->rx_buffer = rx_buf; + + app_spp_tota_gen_init_tx_buf(tx_buf); + btif_spp_init_rx_buf(tota_spp_gen_dev, rx_buf, SPP_RECV_BUFFER_SIZE); + + mid = osMutexCreate(osMutex(tota_spp_gen_mutex)); + if (!mid) { + ASSERT(0, "cannot create mutex"); + } + + if (tota_sdp_gen_record == NULL) + tota_sdp_gen_record = btif_sdp_create_record(); + + param.attrs = &TotaSppGenSdpAttributes1[0], + param.attr_count = ARRAY_SIZE(TotaSppGenSdpAttributes1); + param.COD = BTIF_COD_MAJOR_PERIPHERAL; + btif_sdp_record_setup(tota_sdp_gen_record, ¶m); + + if(totaSppGenService == NULL) + totaSppGenService = btif_create_spp_service(); + + totaSppGenService->rf_service.serviceId = RFCOMM_CHANNEL_TOTA_GENERAL; + totaSppGenService->numPorts = 0; + btif_spp_service_setup(tota_spp_gen_dev, totaSppGenService, tota_sdp_gen_record); + + tota_spp_gen_dev->portType = BTIF_SPP_SERVER_PORT; + tota_spp_gen_dev->app_id = BTIF_APP_SPP_SERVER_TOTA_GENERAL_ID; + tota_spp_gen_dev->spp_handle_data_event_func = tota_general_spp_handle_data_event_func; + + btif_spp_init_device(tota_spp_gen_dev, 5, mid); + + btif_spp_open(tota_spp_gen_dev, NULL,spp_tota_gen_callback); + +} diff --git a/services/tota/app_spp_tota_general_service.h b/services/tota/app_spp_tota_general_service.h new file mode 100644 index 0000000..37025b3 --- /dev/null +++ b/services/tota/app_spp_tota_general_service.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_SPP_TOTA_GEN_H__ +#define __APP_SPP_TOTA_GEN_H__ + +void app_spp_tota_gen_init(void); + +uint16_t app_spp_tota_gen_tx_buf_size(void); +void app_spp_tota_gen_init_tx_buf(uint8_t* ptr); +void app_tota_gen_send_cmd_via_spp(uint8_t* ptrData, uint32_t length); +void app_tota_gen_send_data_via_spp(uint8_t* ptrData, uint32_t length); + +#endif + diff --git a/services/tota/app_tota.cpp b/services/tota/app_tota.cpp new file mode 100644 index 0000000..6d27e0f --- /dev/null +++ b/services/tota/app_tota.cpp @@ -0,0 +1,249 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_trace.h" +#include "hal_timer.h" +#include "app_audio.h" +#include "app_utils.h" +#include "hal_aud.h" +#include "hal_norflash.h" +#include "pmu.h" +#include "string.h" +#include "stdio.h" +#include "stdarg.h" +#include "cmsis_os.h" +#include "app_tota.h" +#include "app_tota_cmd_code.h" +#include "app_tota_cmd_handler.h" +#include "app_tota_data_handler.h" +#include "app_spp_tota.h" +#include "cqueue.h" +#include "app_ble_rx_handler.h" +#include "rwapp_config.h" +#include "btapp.h" +#include "app_bt.h" +#include "apps.h" +#include "app_thread.h" +#include "cqueue.h" +#include "hal_location.h" +#include "app_hfp.h" +#include "bt_drv_reg_op.h" +#if defined(IBRT) +#include "app_tws_ibrt.h" +#endif +#include "cmsis.h" +#include "app_battery.h" +#include "crc32.h" +#include "factory_section.h" +#include "app_ibrt_rssi.h" +#include "app_spp_tota_general_service.h" +#include "tota_stream_data_transfer.h" +#include "app_tota_flash_program.h" +#include "app_tota_audio_dump.h" +#include "app_tota_mic.h" +#include "app_tota_anc.h" +#include "app_tota_general.h" +#include "app_tota_custom.h" +#include "app_tota_conn.h" +#include "aes.h" + + + +typedef struct +{ + uint8_t connectedType; + APP_TOTA_TRANSMISSION_PATH_E dataPath; +} APP_TOTA_ENV_T; + +static APP_TOTA_ENV_T app_tota_env= +{ + 0, +}; + +bool app_is_in_tota_mode(void) +{ + return app_tota_env.connectedType; +} + + +void app_tota_init(void) +{ + TOTA_LOG_DBG(0,"Init application test over the air."); + app_spp_tota_init(); + app_spp_tota_gen_init(); + app_tota_cmd_handler_init(); + + app_tota_stream_data_transfer_init(); + /* register callback modules */ + app_tota_mic_init(); + app_tota_anc_init(); + app_tota_audio_dump_init(); + app_tota_general_init(); + app_tota_custom_init(); + app_tota_flash_init(); + + /* set module to access spp callback */ + //tota_callback_module_set(APP_TOTA_AUDIO_DUMP); + tota_callback_module_set(APP_TOTA_ANC); + +#if (BLE_APP_TOTA) + app_ble_rx_handler_init(); +#endif +} + +void app_tota_connected(uint8_t connType) +{ + TOTA_LOG_DBG(0,"Tota is connected."); + app_tota_env.connectedType |= connType; +} + +void app_tota_disconnected(uint8_t disconnType) +{ + TOTA_LOG_DBG(0,"Tota is disconnected."); + app_tota_env.connectedType &= disconnType; +} + +void app_tota_general_connected(uint8_t connType) +{ + TOTA_LOG_DBG(0,"Tota gen is connected."); + app_tota_env.connectedType |= connType; +} + +void app_tota_update_datapath(APP_TOTA_TRANSMISSION_PATH_E dataPath) +{ + app_tota_env.dataPath = dataPath; +} + +APP_TOTA_TRANSMISSION_PATH_E app_tota_get_datapath(void) +{ + return app_tota_env.dataPath; +} + + + + +/*---------------------------------------------------------------------------------------------------------------------------*/ + +static bool _is_tota_connect = false; + +/**/ +void tota_connected_handle() +{ + _is_tota_connect = true; +} + +/**/ +void tota_disconnected_handle() +{ + _is_tota_connect = false; +} + +bool is_tota_connected() +{ + return _is_tota_connect; +} + +/* +** @func: encrypt && decrypt +*/ +static uint8_t encrypt_data[MAX_SPP_PACKET_SIZE]; +static uint8_t decrypt_data[MAX_SPP_PACKET_SIZE]; + +static __unused uint8_t key[ENCRYPT_KEY_SIZE] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; +static __unused uint8_t iv[ENCRYPT_KEY_SIZE] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; + +void tota_set_encrypt_key_from_hash_key(uint8_t * hash_key) +{ + for (uint8_t i = 0; i < ENCRYPT_KEY_SIZE; i ++) + { + key[i] = hash_key[2*i]; + } + TOTA_LOG_DBG(0,"aes key:"); + DUMP8("%02x ", key, ENCRYPT_KEY_SIZE); +} + +void test_aes_encode_decode() +{ + uint8_t w[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + uint8_t z[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t x[16] = {1, 1, 1, 1, 1, 1, 1, 1}; + + uint8_t dw[16]= {0x69, 0x0a, 0x6c, 0x5e, 0xd6, 0x66, 0x51, 0x25, 0x97, 0xfa, 0x1e, 0x6e, 0xcc, 0xfc, 0x1b, 0xdb}; + uint8_t dz[16]= {0x50, 0xfe, 0x67, 0xcc, 0x99, 0x6d, 0x32, 0xb6, 0xda, 0x09, 0x37, 0xe9, 0x9b, 0xaf, 0xec, 0x60}; + uint32_t length = 0; + tota_encrypt_packet(w, 16, &length); + osDelay(50); + tota_encrypt_packet(z, 16, &length); + osDelay(50); + tota_decrypt_packet(dw, 16, &length); + osDelay(50); + tota_decrypt_packet(dz, 16, &length); + + tota_encrypt_packet(x, 8, &length); + osDelay(50); +} + +uint8_t * tota_encrypt_packet(uint8_t * in, uint32_t inLen, uint32_t * poutLen) +{ + uint32_t morebytes = inLen % ENCRYPT_KEY_SIZE? ENCRYPT_KEY_SIZE: 0; + uint32_t outLen = (inLen/ENCRYPT_KEY_SIZE)*ENCRYPT_KEY_SIZE + morebytes; + TOTA_LOG_DBG(0,"raw data:"); + DUMP8("0x%02x, ", in, inLen); +#if defined(TOTA) + AES128_CBC_encrypt_buffer(encrypt_data, in, inLen, key, iv); +#endif + *poutLen = outLen; + TOTA_LOG_DBG(2,"encrypt data: %u -> %u", inLen, outLen); + DUMP8("0x%02x, ", encrypt_data, *poutLen); + return encrypt_data; +} + +/* +** inLen must 16 times +*/ +uint8_t * tota_decrypt_packet(uint8_t * in, uint32_t inLen, uint32_t * poutLen) +{ + uint32_t morebytes = inLen % ENCRYPT_KEY_SIZE? ENCRYPT_KEY_SIZE: 0; + uint32_t outLen = (inLen/ENCRYPT_KEY_SIZE)*ENCRYPT_KEY_SIZE + morebytes; + TOTA_LOG_DBG(0,"raw data:"); + DUMP8("0x%02x, ", in, inLen); +#if defined(TOTA) + AES128_CBC_decrypt_buffer(decrypt_data, in, inLen, key, iv); +#endif + *poutLen = outLen; + TOTA_LOG_DBG(2,"decrypt data: %u -> %u", inLen, outLen); + DUMP8("0x%02x, ", decrypt_data, *poutLen); + return decrypt_data; +} + +//TODO: +static char strBuf[MAX_SPP_PACKET_SIZE-4]; +void tota_printf(const char * format, ...) +{ + va_list vlist; + va_start(vlist, format); + vsprintf(strBuf, format, vlist); + va_end(vlist); + app_tota_send_command(OP_TOTA_STRING, (uint8_t*)strBuf, strlen(strBuf), app_tota_get_datapath()); +} + +/*---------------------------------------------------------------------------------------------------------------------------*/ +static void app_tota_demo_cmd_handler(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + TOTA_LOG_DBG(2,"Func code 0x%x, param len %d", funcCode, paramLen); + TOTA_LOG_DBG(0,"Param content:"); + DUMP8("%02x ", ptrParam, paramLen); +} +TOTA_COMMAND_TO_ADD(OP_TOTA_DEMO_CMD, app_tota_demo_cmd_handler, false, 0, NULL ); \ No newline at end of file diff --git a/services/tota/app_tota.h b/services/tota/app_tota.h new file mode 100644 index 0000000..f422046 --- /dev/null +++ b/services/tota/app_tota.h @@ -0,0 +1,244 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TOTA_H__ +#define __APP_TOTA_H__ + +#include "app_tota_cmd_code.h" + +#define APP_TOTA_PATH_TYPE_SPP (1 << 0) + +#define APP_TOTA_PATH_TYPE (APP_TOTA_PATH_TYPE_SPP) + +#define APP_TOTA_CONNECTED (1 << 0) +#define APP_TOTA_DISCONNECTED (~(1 << 0)) + +#define TOTA_SHARE_TX_RX_BUF 1 + +#ifdef __cplusplus +extern "C" { +#endif +#define TOTA_SERVICE_CMD_PARAM_LENGTH 128 +#if 0//if support write flash block cmd,the buffer size must be 4k +#define TOTA_SERVICE_DATA_WRITE_LENGTH 4*1024 +#define TOTA_SERVICE_DATA_READ_LENGTH 4*1024 +#else +#define TOTA_SERVICE_DATA_WRITE_LENGTH 4*32 +#define TOTA_SERVICE_DATA_READ_LENGTH 4*32 +#endif +#define FLASH_SECTOR_SIZE_IN_BYTES 4*1024 +#define TOTA_DATA_BUFFER_SIZE_FOR_BURNING FLASH_SECTOR_SIZE_IN_BYTES +#define TOTA_SERVICE_SYNC_WORD 0x54534542 +#define TOTA_SERVICE_SYNC_DATA_1 0xbe +#define TOTA_SERVICE_SYNC_DATA_2 0xca +#define TOTA_SERVICE_XFER_OUT_DATA_SIZE 500 +#define BT_LOCAL_NAME_LEN 64 +#define DANGLE_TRANS_MAX_SIZE 248 +#define DUMP_BYTES 32 + +enum{ + TOTA_SERVICE_DATA_XFER_ADDR_WRITE, + TOTA_SERVICE_DATA_XFER_ADDR_READ, + TOTA_SERVICE_DATA_XFER_ADDR_NONE, +}; + + +typedef enum{ + TOTA_SERVICE_GENERAL_CMD_PARSER_NONE, + TOTA_SERVICE_GENERAL_CMD_STATE_PARSER_SYNC, + TOTA_SERVICE_GENERAL_CMD_STATE_PARSER_DATA, + TOTA_SERVICE_GENERAL_CMD_STATE_PARSER_EXTRAL, +}TOTA_SERVICE_GENERAL_CMD_PARSER_STATE; + + +typedef enum{ + TOTA_SERVICE_INIT_SYNC = 0, /*valid payload: |2 bytes sync word | */ + TOTA_SERVICE_CMD_WRITE_FLASH, /*valid payload: |4 bytes address|4 bytes write data length| */ + TOTA_SERVICE_CMD_READ_FLASH, /*valid payload: |1 byte start_or_stop|4 bytes address|4 bytes read data length| */ + TOTA_SERVICE_CMD_WRITE_AI_ENV_DATA, /*valid payload: |4 bytes write data length| */ + TOTA_SERVICE_CMD_VERIFY_AI_ENV_DATA, /*valid payload: |4 bytes magic code |4 bytes CRC| */ + TOTA_SERVICE_CMD_READ_AI_ENV_DATA, /*valid payload: |1 byte start_or_stop|4 bytes read data length | */ + TOTA_SERVICE_CMD_READ_ACK, /*valid rsp payload: |1 bytes| */ + TOTA_SERVICE_CMD_GET_BAT, /*valid rsp payload: |4 bytes| */ + TOTA_SERVICE_CMD_GET_FW_VERSION, /*valid rsp payload: |4 bytes| */ + TOTA_SERVICE_CMD_GET_BT_LOCAL_NAME, /*valid rsp payload: |x bytes| */ + TOTA_SERVICE_CMD_GET_BT_ADDR, /*valid rsp payload: |6 bytes| */ + TOTA_SERVICE_CMD_CLEAR_PAIRING_INFO, + TOTA_SERVICE_CMD_GENERAL_TEST, + TOTA_SERVICE_CMD_SHUTDOWM, + TOTA_SERVICE_CMD_MIC_TEST_ON, + TOTA_SERVICE_CMD_MIC_TEST_OFF, + TOTA_SERVICE_CMD_MIC_SWITCH, + TOTA_SERVICE_CMD_COUNT = 0xff, /*valid payload */ +}TOTA_GENERAL_CMD_E; + +typedef enum{ + TOTA_SERVICE_SEND_STATUS_NO_ERROR = 0, + TOTA_SERVICE_SEND_STATUS_INVALID_CMD = 1, + TOTA_SERVICE_SEND_STATUS_PARAM_ERR = 2, + TOTA_SERVICE_SEND_STATUS_END = 3, +}TOTA_SERVICE_SEND_STATUS_E; + + +typedef struct{ + uint16_t cmd; + uint16_t len; +}TOTA_SERVICE_CMD_RSP_HEADER_T; + +typedef struct{ + uint8_t is_to_start; + uint32_t start_addr; + uint32_t len; +}__attribute__ ((__packed__)) TOTA_SERVICE_CMD_READ_FLASH_BODY_STRUCT_T; + +typedef struct{ + uint32_t start_addr; + uint32_t len; +}TOTA_SERVICE_CMD_WRITE_FLASH_BODY_STRUCT_T; + +typedef struct{ + uint8_t is_to_start; + uint32_t start_addr; + uint32_t len; + uint8_t read_ai_env_ack; +}__attribute__ ((__packed__)) TOTA_SERVICE_CMD_READ_AI_ENV_DATA_BODY_STRUCT_T; + +typedef struct{ + uint32_t len; +}TOTA_SERVICE_CMD_WRITE_AI_ENV_DATA_BODY_STRUCT_T; + +typedef struct{ + TOTA_SERVICE_CMD_RSP_HEADER_T cmd_rsp_header; + uint8_t ack_val; +}__attribute__ ((__packed__)) TOTA_SERVICE_CMD_SYNC_ACK; + +typedef struct{ + TOTA_SERVICE_CMD_RSP_HEADER_T cmd_rsp_header; + uint8_t write_ai_env_ack; +} __attribute__ ((__packed__)) TOTA_SERVICE_CMD_WRITE_AI_ENV_DATA_ACK_STRUCT_T; + +typedef struct{ + TOTA_SERVICE_CMD_RSP_HEADER_T cmd_rsp_header; + uint8_t verify_ai_env_ack; +} __attribute__ ((__packed__)) TOTA_SERVICE_CMD_VERIFY_AI_ENV_DATA_ACK_STRUCT_T; + +typedef uint32_t BAT_VAL_BYTES; +typedef struct{ + TOTA_SERVICE_CMD_RSP_HEADER_T cmd_rsp_header; + BAT_VAL_BYTES bat_val; +}TOTA_SERVICE_CMD_GET_BAT_VAL_BODY_STRUCT_T; + +typedef struct{ + TOTA_SERVICE_CMD_RSP_HEADER_T cmd_rsp_header; + uint8_t fw_version[4]; +}TOTA_SERVICE_CMD_GET_FW_VERSION_BODY_STRUCT_T; + +typedef struct{ + TOTA_SERVICE_CMD_RSP_HEADER_T cmd_rsp_header; + char bt_local_name[BT_LOCAL_NAME_LEN]; +}__attribute__ ((__packed__))TOTA_SERVICE_CMD_GET_BT_LOCAL_NAME_BODY_STRUCT_T; + +typedef struct{ + TOTA_SERVICE_CMD_RSP_HEADER_T cmd_rsp_header; + uint8_t bt_addr[6]; +}__attribute__ ((__packed__))TOTA_SERVICE_CMD_GET_BT_ADDR_BODY_STRUCT_T; + +typedef struct{ + TOTA_SERVICE_CMD_RSP_HEADER_T cmd_rsp_header; + uint8_t test_val[7]; +}__attribute__ ((__packed__))TOTA_SERVICE_CMD_GET_TEST_VAL_BODY_STRUCT_T; + +typedef struct{ + uint32_t prefix; + uint16_t cmd; + uint8_t seq; + uint8_t len; +}msg_header_t; + +typedef struct{ + msg_header_t hdr; + unsigned char cmd_param[TOTA_SERVICE_CMD_PARAM_LENGTH]; +}TOTA_GENERAL_CMD_STRUCT_T; + +typedef struct{ + uint8_t* tota_write_buff_ptr; + uint16_t tota_data_write_buf_block_lenth; + uint16_t tota_data_written_lenth_in_block; + + uint32_t tota_data_need_write_flash_begin_addr; + uint32_t tota_data_tota_need_write_lenth; + uint32_t tota_data_tota_already_receive_length; + uint32_t tota_data_written_in_flash_pos ; + uint32_t tota_offset_in_flash_of_current_block; + uint32_t tota_offset_of_data_of_current_block; +}TOTA_SERVICE_DATA_WRITE_STRUCT_T; + +typedef struct{ + uint8_t* tota_read_buff_ptr; + uint16_t tota_data_read_buf_block_lenth; + uint16_t tota_data_have_read_lenth_in_block; + + uint32_t tota_data_need_read_flash_begin_addr; + uint32_t tota_data_tota_need_read_lenth; + uint32_t tota_data_tota_already_sent_length; + uint32_t tota_data_have_read_in_flash_pos ; + uint32_t tota_offset_in_flash_of_current_block; + uint32_t tota_offset_of_data_of_current_block; +}TOTA_SERVICE_DATA_READ_STRUCT_T; + + +/** + * @brief The format of the segment verification request + * + */ +typedef struct +{ + uint32_t magicCode; // should be OTA_START_MAGIC_CODE + uint32_t crc32OfSegment; // crc32 of the 1 segment +} __attribute__ ((__packed__)) TOTA_SEGMENT_VERIFY_T; + +void app_tota_init(void); +void app_tota_connected(uint8_t connType); +void app_tota_disconnected(uint8_t disconnType); +void app_tota_general_connected(uint8_t connType); +bool app_is_in_tota_mode(void); +void app_tota_update_datapath(APP_TOTA_TRANSMISSION_PATH_E dataPath); +APP_TOTA_TRANSMISSION_PATH_E app_tota_get_datapath(void); + + +/* interface */ +void tota_connected_handle(); +void tota_disconnected_handle(); +bool is_tota_connected(); +void tota_set_encrypt_key_from_hash_key(uint8_t * set_key); + + +uint8_t * tota_encrypt_packet(uint8_t * in, uint32_t inLen, uint32_t * poutLen); +uint8_t * tota_decrypt_packet(uint8_t * in, uint32_t inLen, uint32_t * poutLen); + +void tota_printf(const char * format, ...); + + +/*todo: for test*/ +void test_aes_encode_decode(); + + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/services/tota/app_tota_anc.cpp b/services/tota/app_tota_anc.cpp new file mode 100644 index 0000000..9bb6337 --- /dev/null +++ b/services/tota/app_tota_anc.cpp @@ -0,0 +1,104 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "app_spp_tota.h" +#include +#include "cmsis_os.h" +#include "app_tota_cmd_code.h" +#include "anc_parse_data.h" +#include "app_tota_anc.h" + + +osTimerId app_check_send_synccmd_timer = NULL; +static void app_synccmd_timehandler(void const *param); +osTimerDef (APP_SYNCCMD, app_synccmd_timehandler); + +static void app_synccmd_timehandler(void const *param) +{ + send_sync_cmd_to_tool(); +} + +APP_TOTA_CMD_RET_STATUS_E app_anc_tota_cmd_received(uint8_t* ptrData, uint32_t dataLength) +{ + TOTA_LOG_DBG(2,"[%s] length:%d", __func__, dataLength); + TOTA_LOG_DBG(1,"[%s] data:", __func__); + TOTA_LOG_DUMP("0x%02x ", ptrData, dataLength); + + anc_handle_received_data(ptrData, dataLength); + + if(get_send_sync_flag() == 1) + { + osTimerStop(app_check_send_synccmd_timer); + } + return TOTA_NO_ERROR; +} + +static bool is_connected = false; + +/*-----------------------------------------------------------------------------*/ + +static void _tota_spp_connected(void); +static void _tota_spp_disconnected(void); +static void _tota_spp_tx_done(void); +static void _tota_spp_data_receive_handle(uint8_t * buf, uint32_t len); + +static tota_callback_func_t s_func = { + _tota_spp_connected, + _tota_spp_disconnected, + _tota_spp_tx_done, + _tota_spp_data_receive_handle +}; + +static APP_TOTA_MODULE_E s_module = APP_TOTA_ANC; + +void app_tota_anc_init() +{ + tota_callback_module_register(s_module, s_func); + reset_programmer_state(&g_buf, &g_len); + + if (app_check_send_synccmd_timer == NULL) + app_check_send_synccmd_timer = osTimerCreate (osTimer(APP_SYNCCMD), osTimerPeriodic, NULL); +} + +static void _tota_spp_connected(void) +{ + anc_data_buff_init(); + //add a send sync timer + osTimerStop(app_check_send_synccmd_timer); + osTimerStart(app_check_send_synccmd_timer, 2000); + is_connected = true; +} + +static void _tota_spp_disconnected(void) +{ + anc_data_buff_deinit(); + osTimerStop(app_check_send_synccmd_timer); + is_connected = false; +} + +static void _tota_spp_tx_done(void) +{ + if ( is_connected ) + // TODO: + ;//bulk_read_done(); +} + +static void _tota_spp_data_receive_handle(uint8_t * buf, uint32_t len) +{ + app_anc_tota_cmd_received(buf, len); +} + +/*-----------------------------------------------------------------------------*/ diff --git a/services/tota/app_tota_anc.h b/services/tota/app_tota_anc.h new file mode 100644 index 0000000..fcf37d7 --- /dev/null +++ b/services/tota/app_tota_anc.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __APP_TOTA_ANC_H__ +#define __APP_TOTA_ANC_H__ + + +/* from other files */ +extern unsigned char *g_buf; +extern size_t g_len; + + +extern "C" void bulk_read_done(void); +extern "C" void reset_programmer_state(unsigned char **buf, size_t *len); +extern "C" void send_sync_cmd_to_tool(); +extern "C" int anc_handle_received_data(uint8_t* ptrParam, uint32_t paramLen); +extern "C" int get_send_sync_flag(void); + + + +/* interface */ +void app_tota_anc_init(); + +#endif + diff --git a/services/tota/app_tota_audio_dump.cpp b/services/tota/app_tota_audio_dump.cpp new file mode 100644 index 0000000..4d37d72 --- /dev/null +++ b/services/tota/app_tota_audio_dump.cpp @@ -0,0 +1,181 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "app_tota.h" +#include "app_spp_tota.h" +#include "app_tota_cmd_code.h" +#include "app_tota_audio_dump.h" +#include "app_tota_cmd_handler.h" +#include "tota_stream_data_transfer.h" +#include "cmsis_os.h" + +// #define _TOTA_AUDIO_DUMP_DEBUG + +static void _tota_audio_dump_connected(void); +static void _tota_audio_dump_disconnected(void); +static void _tota_audio_dump_tx_done(void); +static void _tota_audio_dump_receive_handle(uint8_t * buf, uint32_t len); + +/**/ +static void _audio_dump_control(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen); + +#ifdef _TOTA_AUDIO_DUMP_DEBUG +/* only for test */ +static void test_init(); +#endif + +/**/ +static tota_callback_func_t s_func = { + _tota_audio_dump_connected, + _tota_audio_dump_disconnected, + _tota_audio_dump_tx_done, + _tota_audio_dump_receive_handle +}; + +static APP_TOTA_MODULE_E s_module = APP_TOTA_AUDIO_DUMP; + + +void app_tota_audio_dump_init() +{ + TOTA_LOG_DBG(1, "[%s] ...", __func__); + + tota_callback_module_register(s_module, s_func); +} + +static void _tota_audio_dump_connected(void) +{ + TOTA_LOG_DBG(1, "[%s] ...", __func__); + +#ifdef _TOTA_AUDIO_DUMP_DEBUG + test_init(); +#endif +} + +static void _tota_audio_dump_disconnected(void) +{ + TOTA_LOG_DBG(1, "[%s] ...", __func__); +} + +static void _tota_audio_dump_tx_done(void) +{ + ; +} + +static void _tota_audio_dump_receive_handle(uint8_t * buf, uint32_t len) +{ + ; +} + +/*-----------------------------------------------------------------------------*/ +void app_tota_audio_dump_start() +{ + TOTA_LOG_DBG(1, "[%s] ...", __func__); + + app_tota_stream_data_start(s_module); + app_tota_audio_dump_flush(); +} + +void app_tota_audio_dump_stop() +{ + TOTA_LOG_DBG(1, "[%s] ...", __func__); + + app_tota_stream_data_end(); +} + +void app_tota_audio_dump_flush() +{ + TOTA_LOG_DBG(1, "[%s] ...", __func__); + + app_tota_stream_data_flush(); +} + +bool app_tota_audio_dump_send(uint8_t * pdata, uint32_t dataLen) +{ + return app_tota_send_stream_data(pdata, dataLen); +} + +/*-----------------------------------------------------------------------------*/ +static void _audio_dump_control(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + switch (funcCode) + { + case OP_TOTA_AUDIO_DUMP_START: + TOTA_LOG_DBG(0, "tota_audio_dump start"); + app_tota_audio_dump_start(); + break; + + case OP_TOTA_AUDIO_DUMP_STOP: + TOTA_LOG_DBG(0, "tota_audio_dump stop"); + app_tota_audio_dump_stop(); + break; + + case OP_TOTA_AUDIO_DUMP_CONTROL: + TOTA_LOG_DBG(0, "tota_audio_dump contorl"); + // TODO: Can get or set info + app_tota_send_response_to_command(funcCode, TOTA_NO_ERROR, (uint8_t *)".pcm", sizeof(".pcm"), app_tota_get_datapath()); + break; + + default: + break; + } +} + +#ifdef _TOTA_AUDIO_DUMP_DEBUG +/*-----------------------------------------------------------------------------*/ +/*----------------------------------TEST---------------------------------------*/ +/*-----------------------------------------------------------------------------*/ +#define TOTA_TEST_STACK_SIZE (1024 * 2) +static void tota_audio_dump_test_thread(void const *argument); +osThreadId tota_audio_dump_test_thread_tid; +osThreadDef(tota_audio_dump_test_thread, osPriorityNormal, 1, TOTA_TEST_STACK_SIZE, "TOTA_TEST_THREAD");//osPriorityHigh + +static uint16_t audio_cnt = 0; + +uint16_t audioBuf[512]; + +static void tota_audio_dump_test_thread(void const *argument) +{ + app_tota_audio_dump_flush(); + while (true) + { + osDelay(1000); + for (uint16_t i=0; i + +#ifdef __cplusplus +extern "C" { +#endif + +void app_tota_audio_dump_init(); + +void app_tota_audio_dump_start(); +void app_tota_audio_dump_stop(); +void app_tota_audio_dump_flush(); +bool app_tota_audio_dump_send(uint8_t * pdata, uint32_t dataLen); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/services/tota/app_tota_cmd_code.h b/services/tota/app_tota_cmd_code.h new file mode 100644 index 0000000..0e1f6aa --- /dev/null +++ b/services/tota/app_tota_cmd_code.h @@ -0,0 +1,204 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TOTA_CMD_CODE_H__ +#define __APP_TOTA_CMD_CODE_H__ + +#include "hal_trace.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LOG_TAG "[TOTA_CONTROL] " + +#define TOTA_CONTROL_DEBUG + +#ifdef TOTA_CONTROL_DEBUG +#define TOTA_LOG_DBG(num,str,...) TRACE(num,LOG_TAG""str, ##__VA_ARGS__) // DEBUG OUTPUT +#define TOTA_LOG_MSG(num,str,...) TRACE(num,LOG_TAG""str, ##__VA_ARGS__) // MESSAGE OUTPUT +#define TOTA_LOG_ERR(num,str,...) TRACE(num,LOG_TAG"err:"""str, ##__VA_ARGS__) // ERROR OUTPUT + +#define TOTA_LOG_FUNC_LINE() TRACE(2,LOG_TAG"%s:%d\n", __FUNCTION__, __LINE__) +#define TOTA_LOG_FUNC_IN() TRACE(1,LOG_TAG"%s ++++\n", __FUNCTION__) +#define TOTA_LOG_FUNC_OUT() TRACE(1,LOG_TAG"%s ----\n", __FUNCTION__) + +#define TOTA_LOG_DUMP DUMP8 +#else +#define TOTA_LOG_DBG(str,...) +#define TOTA_LOG_MSG(num,str,...) TRACE(num,LOG_TAG""str, ##__VA_ARGS__) +#define TOTA_LOG_ERR(num,str,...) TRACE(num,LOG_TAG"err:"""str, ##__VA_ARGS__) + +#define TOTA_LOG_FUNC_LINE() +#define TOTA_LOG_FUNC_IN() +#define TOTA_LOG_FUNC_OUT() + +#define TOTA_LOG_DUMP +#endif + +extern uint32_t __tota_handler_table_start[]; +extern uint32_t __tota_handler_table_end[]; + +#define INVALID_TOTA_ENTRY_INDEX 0xFFFF +#define TOTA_CMD_CODE_SIZE sizeof(uint16_t) + +/** + * @brief Type of the tota transmission path. + * + */ +typedef enum +{ + APP_TOTA_VIA_SPP = 0, + APP_TOTA_VIA_NOTIFICATION, + APP_TOTA_VIA_INDICATION, + APP_TOTA_GEN_VIA_SPP, + APP_TOTA_TRANSMISSION_PATH_COUNT, + + APP_TOTA_PATH_IDLE = 0xff +} APP_TOTA_TRANSMISSION_PATH_E; + +/** + * @brief The command code + * + */ +typedef enum +{ + /* basic cmd */ + OP_TOTA_STRING = 0x1000, + OP_TOTA_CONN_INITIATE = 0x1001, + OP_TOTA_CONN_RESPONSE = 0x1002, + OP_TOTA_CONN_CONFIRM = 0x1003, + + /* response cmd */ + OP_TOTA_RESPONSE_TO_CMD = 0x6000, /**< the payload is: OP_TOTA_RESPONSE_TO_CMD + paramLen + BLE_TOTA_CMD_RSP_T */ + OP_TOTA_SPP_DATA_ACK = 0x6001, + + /* test cmd: test ok */ + OP_TOTA_TEST_CMD = 0x6100, + OP_TOTA_ECHO_TEST_CMD = 0x6101, + OP_TOTA_DEMO_CMD = 0x6102, + + /* flash cmd: test ok */ + OP_TOTA_WRITE_FLASH_CMD = 0x6200, + OP_TOTA_ERASE_FLASH_CMD = 0x6201, + + /* general info cmd: test ok */ + OP_TOTA_GENERAL_INFO_CMD = 0x6300, + OP_TOTA_MERIDIAN_EFFECT_CMD = 0x6301, + OP_TOTA_EQ_SELECT_CMD = 0x6302, + OP_TOTA_VOLUME_PLUS_CMD = 0x6303, + OP_TOTA_VOLUME_DEC_CMD = 0x6304, + OP_TOTA_VOLUME_SET_CMD = 0x6305, + OP_TOTA_VOLUME_GET_CMD = 0x6306, + OP_TOTA_EQ_SET_CMD = 0x6307, + OP_TOTA_EQ_GET_CMD = 0x6308, + + /* audio dump and mic cmd */ + OP_TOTA_AUDIO_DUMP_START = 0x6400, + OP_TOTA_AUDIO_DUMP_STOP = 0x6401, + OP_TOTA_AUDIO_DUMP_CONTROL = 0x6402, + OP_TOTA_MIC_TEST_ON = 0x6403, + OP_TOTA_MIC_TEST_OFF = 0x6404, + OP_TOTA_MIC_SWITCH = 0x6405, + + /* custom cmd */ + // TODO: + OP_TOTA_FACTORY_RESET = 0x8000, + OP_TOTA_CLEAR_PAIRING_INFO = 0x8001, + OP_TOTA_SHUTDOWM = 0x8002, + OP_TOTA_REBOOT = 0x8003, + + // TODO:? + OP_TOTA_RAW_DATA_SET_CMD = 0x9100, + + /* commond count */ + OP_TOTA_COMMAND_COUNT, + /* to mark that it's a data packet */ + OP_TOTA_STREAM_DATA = 0xFFFF, +} APP_TOTA_CMD_CODE_E; + +/** + * @brief The tota command handling return status + * + */ +typedef enum +{ + TOTA_NO_ERROR = 0, + TOTA_INVALID_CMD = 1, + TOTA_INVALID_DATA_PACKET = 2, + TOTA_PARAM_LEN_OUT_OF_RANGE = 3, + TOTA_PARAMETER_LENGTH_TOO_SHORT = 4, + TOTA_PARAM_LEN_TOO_SHORT = 5, + TOTA_CMD_HANDLING_FAILED = 6, + TOTA_WAITING_RSP_TIMEOUT = 7, + TOTA_DATA_XFER_ALREADY_STARTED = 8, + TOTA_DATA_XFER_NOT_STARTED_YET = 9, + TOTA_DATA_SEGMENT_CRC_CHECK_FAILED = 10, + TOTA_WHOLE_DATA_CRC_CHECK_FAILED = 11, + TOTA_DATA_XFER_LEN_NOT_MATCHED = 12, + TOTA_WRITE_FLASH_CRC_CHECK_FAILED = 13, + TOTA_MIC_SWITCH_FAILED, + // TO ADD: new return status +} APP_TOTA_CMD_RET_STATUS_E; + +/** + * @brief Format of the tota command handler function, called when the command is received + * + * @param cmdCode Custom command code + * @param ptrParam Pointer of the received parameter + * @param paramLen Length of the recevied parameter + * + */ +typedef void (*app_tota_cmd_handler_t)(APP_TOTA_CMD_CODE_E cmdCode, uint8_t* ptrParam, uint32_t paramLen); + +/** + * @brief Format of the tota command response handler function, + * called when the response to formerly sent command is received + * + * @param retStatus Handling return status of the command + * @param ptrParam Pointer of the received parameter + * @param paramLen Length of the recevied parameter + * + */ +typedef void (*app_tota_cmd_response_handler_t)(APP_TOTA_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen); + +/** + * @brief Smart voice command definition data structure + * + */ +typedef struct +{ + uint32_t cmdCode; + app_tota_cmd_handler_t cmdHandler; /**< command handler function */ + uint16_t isNeedResponse; /**< true if needs the response from the peer device */ + uint16_t timeoutWaitingRspInMs; /**< time-out of waiting for response in milli-seconds */ + app_tota_cmd_response_handler_t cmdRspHandler; /**< command response handler function */ +} APP_TOTA_CMD_INSTANCE_T; + + +#define TOTA_COMMAND_TO_ADD(cmdCode, cmdHandler, isNeedResponse, timeoutWaitingRspInMs, cmdRspHandler) \ + static const APP_TOTA_CMD_INSTANCE_T cmdCode##_entry __attribute__((used, section(".tota_handler_table"))) = \ + {(cmdCode), (cmdHandler), (isNeedResponse), (timeoutWaitingRspInMs), (cmdRspHandler)}; + +#define TOTA_COMMAND_PTR_FROM_ENTRY_INDEX(index) \ + ((APP_TOTA_CMD_INSTANCE_T *)((uint32_t)__tota_handler_table_start + (index)*sizeof(APP_TOTA_CMD_INSTANCE_T))) + +#ifdef __cplusplus + } +#endif + + +#endif // #ifndef __APP_TOTA_CMD_CODE_H__ + diff --git a/services/tota/app_tota_cmd_handler.cpp b/services/tota/app_tota_cmd_handler.cpp new file mode 100644 index 0000000..d9b5879 --- /dev/null +++ b/services/tota/app_tota_cmd_handler.cpp @@ -0,0 +1,515 @@ +/** + **************************************************************************************** + * + * @file app_totac_cmd_handler.c + * + * @date 24th April 2018 + * + * @brief The framework of the tota command handler + * + * Copyright (C) 2017 + * + * + **************************************************************************************** + */ +#include "string.h" +#include "cmsis_os.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "apps.h" +#include "stdbool.h" +#include "app_tota.h" +#include "app_tota_cmd_handler.h" +#include "app_tota_cmd_code.h" +//#include "rwapp_config.h" +#include "app_spp_tota.h" +#include "app_tota_ble.h" +#include "app_spp_tota_general_service.h" + +#include "tota_stream_data_transfer.h" + + +#define APP_TOTA_CMD_HANDLER_WAITING_RSP_TIMEOUT_SUPERVISOR_COUNT 8 + +/** + * @brief waiting response timeout supervision data structure + * + */ +typedef struct +{ + uint16_t entryIndex; /**< The command waiting for the response */ + uint16_t msTillTimeout; /**< run-time timeout left milliseconds */ +} APP_TOTA_CMD_WAITING_RSP_SUPERVISOR_T; + +/** + * @brief tota command handling environment + * + */ +typedef struct +{ + APP_TOTA_CMD_WAITING_RSP_SUPERVISOR_T waitingRspTimeoutInstance[APP_TOTA_CMD_HANDLER_WAITING_RSP_TIMEOUT_SUPERVISOR_COUNT]; + uint32_t lastSysTicks; + uint8_t timeoutSupervisorCount; + osTimerId supervisor_timer_id; + osMutexId mutex; +} APP_TOTA_CMD_HANDLER_ENV_T; + +static APP_TOTA_CMD_HANDLER_ENV_T tota_cmd_handler_env; + +osMutexDef(app_tota_cmd_handler_mutex); + +static void app_tota_cmd_handler_rsp_supervision_timer_cb(void const *n); +osTimerDef (APP_TOTA_CMD_HANDLER_RSP_SUPERVISION_TIMER, app_tota_cmd_handler_rsp_supervision_timer_cb); + +static void app_tota_cmd_handler_remove_waiting_rsp_timeout_supervision(uint16_t entryIndex); +static void app_tota_cmd_handler_add_waiting_rsp_timeout_supervision(uint16_t entryIndex); + +/** + * @brief Callback function of the waiting response supervisor timer. + * + */ +static void app_tota_cmd_handler_rsp_supervision_timer_cb(void const *n) +{ + uint32_t entryIndex = tota_cmd_handler_env.waitingRspTimeoutInstance[0].entryIndex; + + app_tota_cmd_handler_remove_waiting_rsp_timeout_supervision(entryIndex); + + // it means time-out happens before the response is received from the peer device, + // trigger the response handler + TOTA_COMMAND_PTR_FROM_ENTRY_INDEX(entryIndex)->cmdRspHandler(TOTA_WAITING_RSP_TIMEOUT, NULL, 0); +} + +APP_TOTA_CMD_INSTANCE_T* app_tota_cmd_handler_get_entry_pointer_from_cmd_code(APP_TOTA_CMD_CODE_E cmdCode) +{ + for (uint32_t index = 0; + index < ((uint32_t)__tota_handler_table_end-(uint32_t)__tota_handler_table_start)/sizeof(APP_TOTA_CMD_INSTANCE_T);index++) + { + if (TOTA_COMMAND_PTR_FROM_ENTRY_INDEX(index)->cmdCode == cmdCode) + { + return TOTA_COMMAND_PTR_FROM_ENTRY_INDEX(index); + } + } + + return NULL; +} + +uint16_t app_tota_cmd_handler_get_entry_index_from_cmd_code(APP_TOTA_CMD_CODE_E cmdCode) +{ + + for (uint32_t index = 0; + index < ((uint32_t)__tota_handler_table_end-(uint32_t)__tota_handler_table_start)/sizeof(APP_TOTA_CMD_INSTANCE_T);index++) + { + if (TOTA_COMMAND_PTR_FROM_ENTRY_INDEX(index)->cmdCode == cmdCode) + { + return index; + } + } + + return INVALID_TOTA_ENTRY_INDEX; +} + +void app_tota_get_cmd_response_handler(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + // parameter length check + if (paramLen > sizeof(APP_TOTA_CMD_RSP_T)) + { + return; + } + + if (0 == tota_cmd_handler_env.timeoutSupervisorCount) + { + return; + } + + APP_TOTA_CMD_RSP_T* rsp = (APP_TOTA_CMD_RSP_T *)ptrParam; + + + uint16_t entryIndex = app_tota_cmd_handler_get_entry_index_from_cmd_code((APP_TOTA_CMD_CODE_E)(rsp->cmdCodeToRsp)); + if (INVALID_TOTA_ENTRY_INDEX == entryIndex) + { + return; + } + + // remove the function code from the time-out supervision chain + app_tota_cmd_handler_remove_waiting_rsp_timeout_supervision(entryIndex); + + APP_TOTA_CMD_INSTANCE_T* ptCmdInstance = TOTA_COMMAND_PTR_FROM_ENTRY_INDEX(entryIndex); + + // call the response handler + if (ptCmdInstance->cmdRspHandler) + { + ptCmdInstance->cmdRspHandler((APP_TOTA_CMD_RET_STATUS_E)(rsp->cmdRetStatus), rsp->rspData, rsp->rspDataLen); + } +} + + + +/** + * @brief Refresh the waiting response supervisor list + * + */ +static void app_tota_cmd_refresh_supervisor_env(void) +{ + // do nothing if no supervisor was added + if (tota_cmd_handler_env.timeoutSupervisorCount > 0) + { + uint32_t currentTicks = GET_CURRENT_TICKS(); + uint32_t passedTicks; + if (currentTicks >= tota_cmd_handler_env.lastSysTicks) + { + passedTicks = (currentTicks - tota_cmd_handler_env.lastSysTicks); + } + else + { + passedTicks = (hal_sys_timer_get_max() - tota_cmd_handler_env.lastSysTicks + 1) + currentTicks; + } + + uint32_t deltaMs = TICKS_TO_MS(passedTicks); + + APP_TOTA_CMD_WAITING_RSP_SUPERVISOR_T* pRspSupervisor = &(tota_cmd_handler_env.waitingRspTimeoutInstance[0]); + for (uint32_t index = 0;index < tota_cmd_handler_env.timeoutSupervisorCount;index++) + { + if (pRspSupervisor[index].msTillTimeout > deltaMs) + { + pRspSupervisor[index].msTillTimeout -= deltaMs; + } + else + { + pRspSupervisor[index].msTillTimeout = 0; + } + } + } + + tota_cmd_handler_env.lastSysTicks = GET_CURRENT_TICKS(); +} + +/** + * @brief Remove the time-out supervision of waiting response + * + * @param entryIndex Entry index of the command table + * + */ +static void app_tota_cmd_handler_remove_waiting_rsp_timeout_supervision(uint16_t entryIndex) +{ + ASSERT(tota_cmd_handler_env.timeoutSupervisorCount > 0, + "%s The BLE tota command time-out supervisor is already empty!!!", __FUNCTION__); + + osMutexWait(tota_cmd_handler_env.mutex, osWaitForever); + + uint32_t index; + for (index = 0;index < tota_cmd_handler_env.timeoutSupervisorCount;index++) + { + if (tota_cmd_handler_env.waitingRspTimeoutInstance[index].entryIndex == entryIndex) + { + memcpy(&(tota_cmd_handler_env.waitingRspTimeoutInstance[index]), + &(tota_cmd_handler_env.waitingRspTimeoutInstance[index + 1]), + (tota_cmd_handler_env.timeoutSupervisorCount - index - 1)*sizeof(APP_TOTA_CMD_WAITING_RSP_SUPERVISOR_T)); + break; + } + } + + // cannot find it, directly return + if (index == tota_cmd_handler_env.timeoutSupervisorCount) + { + goto exit; + } + + tota_cmd_handler_env.timeoutSupervisorCount--; + + //TOTA_LOG_DBG(1,"decrease the supervisor timer to %d", tota_cmd_handler_env.timeoutSupervisorCount); + + if (tota_cmd_handler_env.timeoutSupervisorCount > 0) + { + // refresh supervisor environment firstly + app_tota_cmd_refresh_supervisor_env(); + + // start timer, the first entry is the most close one + osTimerStart(tota_cmd_handler_env.supervisor_timer_id, + tota_cmd_handler_env.waitingRspTimeoutInstance[0].msTillTimeout); + } + else + { + // no supervisor, directly stop the timer + osTimerStop(tota_cmd_handler_env.supervisor_timer_id); + } + +exit: + osMutexRelease(tota_cmd_handler_env.mutex); +} + +/** + * @brief Add the time-out supervision of waiting response + * + * @param entryIndex Index of the command entry + * + */ +static void app_tota_cmd_handler_add_waiting_rsp_timeout_supervision(uint16_t entryIndex) +{ + ASSERT(tota_cmd_handler_env.timeoutSupervisorCount < APP_TOTA_CMD_HANDLER_WAITING_RSP_TIMEOUT_SUPERVISOR_COUNT, + "%s The tota command response time-out supervisor is full!!!", __FUNCTION__); + + osMutexWait(tota_cmd_handler_env.mutex, osWaitForever); + + // refresh supervisor environment firstly + app_tota_cmd_refresh_supervisor_env(); + + APP_TOTA_CMD_INSTANCE_T* pInstance = TOTA_COMMAND_PTR_FROM_ENTRY_INDEX(entryIndex); + + APP_TOTA_CMD_WAITING_RSP_SUPERVISOR_T waitingRspTimeoutInstance[APP_TOTA_CMD_HANDLER_WAITING_RSP_TIMEOUT_SUPERVISOR_COUNT]; + + uint32_t index = 0, insertedIndex = 0; + for (index = 0;index < tota_cmd_handler_env.timeoutSupervisorCount;index++) + { + uint32_t msTillTimeout = tota_cmd_handler_env.waitingRspTimeoutInstance[index].msTillTimeout; + + // in the order of low to high + if ((tota_cmd_handler_env.waitingRspTimeoutInstance[index].entryIndex != entryIndex) && + (pInstance->timeoutWaitingRspInMs >= msTillTimeout)) + { + waitingRspTimeoutInstance[insertedIndex++] = tota_cmd_handler_env.waitingRspTimeoutInstance[index]; + } + else if (pInstance->timeoutWaitingRspInMs < msTillTimeout) + { + waitingRspTimeoutInstance[insertedIndex].entryIndex = entryIndex; + waitingRspTimeoutInstance[insertedIndex].msTillTimeout = pInstance->timeoutWaitingRspInMs; + + insertedIndex++; + } + } + + // biggest one? then put it at the end of the list + if (tota_cmd_handler_env.timeoutSupervisorCount == index) + { + waitingRspTimeoutInstance[insertedIndex].entryIndex = entryIndex; + waitingRspTimeoutInstance[insertedIndex].msTillTimeout = pInstance->timeoutWaitingRspInMs; + + insertedIndex++; + } + + // copy to the global variable + memcpy((uint8_t *)&(tota_cmd_handler_env.waitingRspTimeoutInstance), (uint8_t *)&waitingRspTimeoutInstance, + insertedIndex*sizeof(APP_TOTA_CMD_WAITING_RSP_SUPERVISOR_T)); + + tota_cmd_handler_env.timeoutSupervisorCount = insertedIndex; + + //TOTA_LOG_DBG(1,"increase the supervisor timer to %d", tota_cmd_handler_env.timeoutSupervisorCount); + + + osMutexRelease(tota_cmd_handler_env.mutex); + + // start timer, the first entry is the most close one + osTimerStart(tota_cmd_handler_env.supervisor_timer_id, tota_cmd_handler_env.waitingRspTimeoutInstance[0].msTillTimeout); + +} + +/** + * @brief Receive the data from the peer device and parse them + * + * @param ptrData Pointer of the received data + * @param dataLength Length of the received data + * + * @return APP_TOTA_CMD_RET_STATUS_E + */ +APP_TOTA_CMD_RET_STATUS_E app_tota_cmd_received(uint8_t* ptrData, uint32_t dataLength) +{ + TOTA_LOG_DBG(0,"TOTA Receive data:"); + TOTA_LOG_DUMP("0x%02x ", ptrData, dataLength); + APP_TOTA_CMD_PAYLOAD_T* pPayload = (APP_TOTA_CMD_PAYLOAD_T *)ptrData; + + // check command code + if (pPayload->cmdCode >= OP_TOTA_COMMAND_COUNT || pPayload->cmdCode < OP_TOTA_STRING) + { + TOTA_LOG_DBG(1,"[%s]error TOTA_INVALID_CMD",__func__); + return TOTA_INVALID_CMD; + } + + // check parameter length + if (pPayload->paramLen > sizeof(pPayload->param)) + { + TOTA_LOG_DBG(1,"[%s]error TOTA_PARAM_LEN_OUT_OF_RANGE",__func__); + return TOTA_PARAM_LEN_OUT_OF_RANGE; + } + + APP_TOTA_CMD_INSTANCE_T* pInstance = + app_tota_cmd_handler_get_entry_pointer_from_cmd_code((APP_TOTA_CMD_CODE_E)(pPayload->cmdCode)); + + // execute the command handler + pInstance->cmdHandler((APP_TOTA_CMD_CODE_E)(pPayload->cmdCode), pPayload->param, pPayload->paramLen); + + return TOTA_NO_ERROR; +} + +#if defined(APP_ANC_TEST) + + +#endif +static void app_tota_cmd_send(APP_TOTA_TRANSMISSION_PATH_E path, APP_TOTA_CMD_PAYLOAD_T* ptPayLoad) +{ + TOTA_LOG_DBG(1,"Send tota cmd: size=%u", (uint32_t)(&(((APP_TOTA_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + TOTA_LOG_DUMP("%02x ", (uint8_t *)ptPayLoad, + (uint32_t)(&(((APP_TOTA_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + + app_tota_send_data_via_spp((uint8_t *)ptPayLoad, (uint32_t)(&(((APP_TOTA_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + +#if 0 + switch (path) + { + case APP_TOTA_VIA_SPP: + app_tota_send_cmd_via_spp((uint8_t *)ptPayLoad, + (uint32_t)(&(((APP_TOTA_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + break; +#ifdef BLE_TOTA_ENABLED + case APP_TOTA_VIA_NOTIFICATION: + app_tota_send_notification((uint8_t *)ptPayLoad, + (uint32_t)(&(((APP_TOTA_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + break; + case APP_TOTA_VIA_INDICATION: + app_tota_send_indication((uint8_t *)ptPayLoad, + (uint32_t)(&(((APP_TOTA_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + break; +#endif + case APP_TOTA_GEN_VIA_SPP: + app_tota_gen_send_cmd_via_spp((uint8_t *)ptPayLoad, + (uint32_t)(&(((APP_TOTA_CMD_PAYLOAD_T *)0)->param)) + ptPayLoad->paramLen); + break; + default: + break; + } +#endif +} + +/** + * @brief Send response to the command request + * + * @param responsedCmdCode Command code of the responsed command request + * @param returnStatus Handling result + * @param rspData Pointer of the response data + * @param rspDataLen Length of the response data + * @param path Path of the data transmission + * + * @return APP_TOTA_CMD_RET_STATUS_E + */ +APP_TOTA_CMD_RET_STATUS_E app_tota_send_response_to_command + (APP_TOTA_CMD_CODE_E responsedCmdCode, APP_TOTA_CMD_RET_STATUS_E returnStatus, + uint8_t* rspData, uint32_t rspDataLen, APP_TOTA_TRANSMISSION_PATH_E path) +{ + TOTA_LOG_DBG(1,"[%s]",__func__); + // check responsedCmdCode's validity + if (responsedCmdCode >= OP_TOTA_COMMAND_COUNT || responsedCmdCode < OP_TOTA_RESPONSE_TO_CMD) + { + return TOTA_INVALID_CMD; + } + + APP_TOTA_CMD_PAYLOAD_T payload; + + APP_TOTA_CMD_RSP_T* pResponse = (APP_TOTA_CMD_RSP_T *)&(payload.param); + + // check parameter length + if (rspDataLen > sizeof(pResponse->rspData)) + { + return TOTA_PARAM_LEN_OUT_OF_RANGE; + } + + pResponse->cmdCodeToRsp = responsedCmdCode; + pResponse->cmdRetStatus = returnStatus; + pResponse->rspDataLen = rspDataLen; + memcpy(pResponse->rspData, rspData, rspDataLen); + + payload.paramLen = 3*sizeof(uint16_t) + rspDataLen; + + payload.cmdCode = OP_TOTA_RESPONSE_TO_CMD; + + app_tota_cmd_send(path, &payload); + + return TOTA_NO_ERROR; +} + +/** + * @brief Send the tota command to the peer device + * + * @param cmdCode Command code + * @param ptrParam Pointer of the output parameter + * @param paramLen Length of the output parameter + * @param path Path of the data transmission + * + * @return APP_TOTA_CMD_RET_STATUS_E + */ +APP_TOTA_CMD_RET_STATUS_E app_tota_send_command(APP_TOTA_CMD_CODE_E cmdCode, + uint8_t* ptrParam, uint32_t paramLen, APP_TOTA_TRANSMISSION_PATH_E path) +{ + // check cmdCode's validity + if (cmdCode >= OP_TOTA_COMMAND_COUNT) + { + TOTA_LOG_DBG(0, "OP_TOTA_COMMAND_COUNT"); + return TOTA_INVALID_CMD; + } + + APP_TOTA_CMD_PAYLOAD_T payload; + + // check parameter length + if (paramLen > sizeof(payload.param)) + { + TOTA_LOG_DBG(0, "TOTA_PARAM_LEN_OUT_OF_RANGE"); + return TOTA_PARAM_LEN_OUT_OF_RANGE; + } + + uint16_t entryIndex = app_tota_cmd_handler_get_entry_index_from_cmd_code(cmdCode); + if (INVALID_TOTA_ENTRY_INDEX == entryIndex) + { + TOTA_LOG_DBG(0, "TOTA_INVALID_CMD"); + return TOTA_INVALID_CMD; + } + + /* cmd filter */ +#if TOTA_ENCODE + if ( !is_tota_connected() ) + { + if (cmdCode > OP_TOTA_CONN_CONFIRM) + { + TOTA_LOG_DBG(0, "COMMAMD NOT PERMIT. PERMISSION DENIED"); + return TOTA_INVALID_CMD; + } + + } + else + { + // may encrypt here + } +#endif + + APP_TOTA_CMD_INSTANCE_T* pInstance = TOTA_COMMAND_PTR_FROM_ENTRY_INDEX(entryIndex); + + // wrap the command payload + payload.cmdCode = cmdCode; + payload.paramLen = paramLen; + memcpy(payload.param, ptrParam, paramLen); + + // send out the data + app_tota_cmd_send(path, &payload); + + // insert into time-out supervison + if (pInstance->isNeedResponse) + { + app_tota_cmd_handler_add_waiting_rsp_timeout_supervision(entryIndex); + } + + return TOTA_NO_ERROR; +} + +/** + * @brief Initialize the tota command handler framework + * + */ +void app_tota_cmd_handler_init(void) +{ + memset((uint8_t *)&tota_cmd_handler_env, 0, sizeof(tota_cmd_handler_env)); + + tota_cmd_handler_env.supervisor_timer_id = + osTimerCreate(osTimer(APP_TOTA_CMD_HANDLER_RSP_SUPERVISION_TIMER), osTimerOnce, NULL); + + tota_cmd_handler_env.mutex = osMutexCreate((osMutex(app_tota_cmd_handler_mutex))); +} + +TOTA_COMMAND_TO_ADD(OP_TOTA_RESPONSE_TO_CMD, app_tota_get_cmd_response_handler, false, 0, NULL ); + + diff --git a/services/tota/app_tota_cmd_handler.h b/services/tota/app_tota_cmd_handler.h new file mode 100644 index 0000000..05a68cb --- /dev/null +++ b/services/tota/app_tota_cmd_handler.h @@ -0,0 +1,81 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TOTA_CMD_HANDLER_H__ +#define __APP_TOTA_CMD_HANDLER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_timer.h" +#include "app_tota_cmd_code.h" + +#define GET_CURRENT_TICKS() hal_sys_timer_get() +#define GET_CURRENT_MS() TICKS_TO_MS(GET_CURRENT_TICKS()) + + +/**< maximum payload size of one smart voice command */ +#define TOTA_MAXIMUM_DATA_PACKET_LEN 660 //672 +#define APP_TOTA_CMD_MAXIMUM_PAYLOAD_SIZE TOTA_MAXIMUM_DATA_PACKET_LEN + +/** + * @brief BLE custom command playload + * + */ +typedef struct +{ + uint16_t cmdCode; /**< command code, from APP_TOTA_CMD_CODE_E */ + uint16_t paramLen; /**< length of the following parameter */ + uint8_t param[APP_TOTA_CMD_MAXIMUM_PAYLOAD_SIZE - 2*sizeof(uint16_t)]; +} APP_TOTA_CMD_PAYLOAD_T; + +/** + * @brief Command response parameter structure + * + */ +typedef struct +{ + uint16_t cmdCodeToRsp; /**< tell which command code to response */ + uint16_t cmdRetStatus; /**< handling result of the command, from APP_TOTA_CMD_RET_STATUS_E */ + uint16_t rspDataLen; /**< length of the response data */ + uint8_t rspData[APP_TOTA_CMD_MAXIMUM_PAYLOAD_SIZE - 5*sizeof(uint16_t)]; +} APP_TOTA_CMD_RSP_T; + +void app_tota_get_cmd_response_handler(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen); +void app_tota_data_xfer_control_handler(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen); +void app_tota_control_data_xfer(bool isStartXfer); +void app_tota_start_data_xfer_control_rsp_handler(APP_TOTA_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen); +void app_tota_stop_data_xfer_control_rsp_handler(APP_TOTA_CMD_RET_STATUS_E retStatus, uint8_t* ptrParam, uint32_t paramLen); +APP_TOTA_CMD_RET_STATUS_E app_tota_send_response_to_command(APP_TOTA_CMD_CODE_E responsedCmdCode, APP_TOTA_CMD_RET_STATUS_E returnStatus, + uint8_t* rspData, uint32_t rspDataLen, APP_TOTA_TRANSMISSION_PATH_E path); +APP_TOTA_CMD_RET_STATUS_E app_tota_send_command(APP_TOTA_CMD_CODE_E cmdCode, uint8_t* ptrParam, uint32_t paramLen, APP_TOTA_TRANSMISSION_PATH_E path); +void app_tota_cmd_handler_init(void); +APP_TOTA_CMD_INSTANCE_T* app_tota_cmd_handler_get_entry_pointer_from_cmd_code(APP_TOTA_CMD_CODE_E cmdCode); +uint16_t app_tota_cmd_handler_get_entry_index_from_cmd_code(APP_TOTA_CMD_CODE_E cmdCode); +APP_TOTA_CMD_RET_STATUS_E app_tota_cmd_received(uint8_t* ptrData, uint32_t dataLength); +#if defined(APP_ANC_TEST) +APP_TOTA_CMD_RET_STATUS_E app_anc_tota_cmd_received(uint8_t* ptrData, uint32_t dataLength); +#endif + + + + +#ifdef __cplusplus + } +#endif + +#endif // #ifndef __APP_TOTA_CMD_HANDLER_H__ + diff --git a/services/tota/app_tota_conn.cpp b/services/tota/app_tota_conn.cpp new file mode 100644 index 0000000..eb7efa7 --- /dev/null +++ b/services/tota/app_tota_conn.cpp @@ -0,0 +1,184 @@ +/******************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + *******************************************************************************/ + +#include "app_tota_conn.h" +#include "app_tota_cmd_code.h" +#include "app_tota.h" +#include "app_tota_cmd_handler.h" +#include "stdlib.h" +#include "string.h" +#include "sha256.h" + +static bool _is_tota_initiate = false; + +typedef struct { + uint8_t length; + uint8_t random_key[MAX_RANDOM_KEY_SIZE]; +}TOTA_CONN_STRUCT_T; + +typedef TOTA_CONN_STRUCT_T random_key_t; + +typedef struct{ + /* local & peer random list */ + random_key_t random_a; + random_key_t random_b; + /* hash key generate from (random_a, random_b) */ + uint8_t hash_key[HASH_KEY_SIZE]; + /* encrypt key generate from hash key */ + uint8_t encrypt_key[ENCRYPT_KEY_SIZE]; +}TOTA_CONN_PARAMETER_T; + +static TOTA_CONN_PARAMETER_T keyManager; + + +/* +** @ +*/ +static void _tota_conn_and_update_key_handle(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen); + +static uint8_t _generate_random_algorithm(uint8_t id, uint8_t a, uint8_t b); + +/* generate key */ +static void _generate_random_key(); + +/* calculate key */ +static void _calculate_encrypt_key(); + +static uint8_t _generate_random_algorithm(uint8_t id, uint8_t a, uint8_t b) +{ + uint8_t op = id % 6; + switch (op) + { + case 0: + return a + b; + case 1: + return a * b; + case 2: + return a & b; + case 3: + return a | b; + case 4: + return a ^ b; + case 5: + return a*a + b*b; + default: + return 0; + } +} + +static void _generate_random_key() +{ + uint8_t random_length = rand() % (MAX_RANDOM_KEY_SIZE + 1); + if ( random_length < 16 ) + { + random_length += 16; + } + keyManager.random_a.length = random_length; + uint32_t * prandom = (uint32_t *)keyManager.random_a.random_key; + for ( uint8_t i = 0; i < (random_length+3)/4; i ++ ) + { + prandom[i] = rand(); + } + TOTA_LOG_DBG(1, "generate random : 0x%x", random_length); + TOTA_LOG_DUMP("%02x ", keyManager.random_a.random_key, random_length); +} + +static void _calculate_encrypt_key() +{ + uint8_t random_key[MAX_RANDOM_KEY_SIZE]; + random_key_t * prandom_a = &keyManager.random_a; + random_key_t * prandom_b = &keyManager.random_b; + + /* align random list */ + if ( prandom_a->length > prandom_b->length ) + { + memset(prandom_b->random_key + prandom_b->length, 0, prandom_a->length - prandom_b->length); + prandom_b->length = prandom_a->length; + } + else if ( prandom_a->length < prandom_b->length ) + { + memset(prandom_a->random_key + prandom_a->length, 0, prandom_b->length - prandom_a->length); + prandom_a->length = prandom_b->length; + } + else + { + TOTA_LOG_DBG(0, "random list is the same size"); + } + TOTA_LOG_DBG(1, "random list a : 0x%x", prandom_a->length); + TOTA_LOG_DUMP("%02x ", keyManager.random_a.random_key, prandom_a->length); + TOTA_LOG_DBG(1, "random list b : 0x%x", prandom_b->length); + TOTA_LOG_DUMP("%02x ", keyManager.random_b.random_key, prandom_b->length); + + /* calculate random_key */ + for ( uint8_t i = 0; i < prandom_a->length; i ++ ) + { + random_key[i] = _generate_random_algorithm(i,prandom_a->random_key[i], prandom_b->random_key[i]); + } + + TOTA_LOG_DBG(0,"generate random key:"); + TOTA_LOG_DUMP("%02x ", random_key, prandom_a->length); +#if defined(TOTA) + SHA256_hash(random_key, prandom_a->length, keyManager.hash_key); +#endif + TOTA_LOG_DBG(0,"generate hash key:"); + TOTA_LOG_DUMP("\\x%02x", keyManager.hash_key, HASH_KEY_SIZE); +} + +static void _tota_conn_and_update_key_handle(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + TOTA_CONN_STRUCT_T * pConn = (TOTA_CONN_STRUCT_T *)ptrParam; + + switch ( funcCode ) + { + case OP_TOTA_STRING: + TOTA_LOG_DBG(0, "not willing to receive this CMD"); + break; + case OP_TOTA_CONN_RESPONSE: + TOTA_LOG_DBG(0, "not willing to receive this CMD"); + break; + case OP_TOTA_CONN_INITIATE: + _is_tota_initiate = true; + keyManager.random_b = *pConn; + _generate_random_key(); + app_tota_send_command(OP_TOTA_CONN_RESPONSE, (uint8_t*)&keyManager.random_a, keyManager.random_a.length+1, app_tota_get_datapath()); + _calculate_encrypt_key(); + break; + case OP_TOTA_CONN_CONFIRM: + if ( _is_tota_initiate ) + { + _is_tota_initiate = false; + if ( memcmp(keyManager.hash_key, pConn->random_key, HASH_KEY_SIZE) == 0 ) + { + tota_set_encrypt_key_from_hash_key(keyManager.hash_key); + tota_connected_handle(); + TOTA_LOG_DBG(0, "tota connect success"); + tota_printf("connect success."); + } + else + { + TOTA_LOG_DBG(0, "tota connect failed"); + tota_printf("connect failed."); + } + } + default: + ; + } +} + +TOTA_COMMAND_TO_ADD(OP_TOTA_CONN_INITIATE, _tota_conn_and_update_key_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_CONN_RESPONSE, _tota_conn_and_update_key_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_CONN_CONFIRM , _tota_conn_and_update_key_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_STRING , _tota_conn_and_update_key_handle, false, 0, NULL ); \ No newline at end of file diff --git a/services/tota/app_tota_conn.h b/services/tota/app_tota_conn.h new file mode 100644 index 0000000..161ecff --- /dev/null +++ b/services/tota/app_tota_conn.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __APP_TOTA_CONN_H__ +#define __APP_TOTA_CONN_H__ + + +/* enable or disable TOTA_ENCODE */ +#define TOTA_ENCODE 1 + + +/* unit: byte */ +#define HASH_KEY_SIZE 32 +#define ENCRYPT_KEY_SIZE 16 +#define RANDOM_KEY_SIZE 16 +#define MAX_RANDOM_KEY_SIZE 128 + +#endif \ No newline at end of file diff --git a/services/tota/app_tota_custom.cpp b/services/tota/app_tota_custom.cpp new file mode 100644 index 0000000..2d02aa2 --- /dev/null +++ b/services/tota/app_tota_custom.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "app_spp_tota.h" +#include "tota_stream_data_transfer.h" +#include "app_tota_cmd_code.h" +#include "app_bt_stream.h" +#include "app_audio.h" +#include "nvrecord.h" +#include "nvrecord_env.h" +#include "app_ibrt_nvrecord.h" +#include "app_tota.h" +#include "app_tota_cmd_handler.h" +#include "apps.h" +#include "cmsis_os.h" + +/**/ +static void _custom_cmd_handle(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen); + +/*-----------------------------------------------------------------------------*/ +static void _tota_spp_connected(void); +static void _tota_spp_disconnected(void); +static void _tota_spp_tx_done(void); +static void _tota_spp_data_receive_handle(uint8_t * buf, uint32_t len); + +static tota_callback_func_t s_func = { + _tota_spp_connected, + _tota_spp_disconnected, + _tota_spp_tx_done, + _tota_spp_data_receive_handle +}; + +static APP_TOTA_MODULE_E s_module = APP_TOTA_CUSTOM; + +void app_tota_custom_init() +{ + tota_callback_module_register(s_module, s_func); +} + +static void _tota_spp_connected(void) +{ + ; +} + +static void _tota_spp_disconnected(void) +{ + ; +} + +static void _tota_spp_tx_done(void) +{ + ; +} + +static void _tota_spp_data_receive_handle(uint8_t * buf, uint32_t len) +{ + ; +} +/*-----------------------------------------------------------------------------*/ + + +static void _custom_cmd_handle(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + TOTA_LOG_DBG(2,"Func code 0x%x, param len %d", funcCode, paramLen); + TOTA_LOG_DBG(0,"Param content:"); + DUMP8("%02x ", ptrParam, paramLen); + APP_TOTA_CMD_RET_STATUS_E rsp_status = TOTA_NO_ERROR; + app_tota_send_response_to_command(funcCode,rsp_status,NULL,0,app_tota_get_datapath()); + switch (funcCode) + { + case OP_TOTA_FACTORY_RESET: + TRACE(0,"##### custom: factory reset"); + app_reset(); + break; + case OP_TOTA_CLEAR_PAIRING_INFO: + TRACE(0,"##### custom: clear pairing info"); + app_ibrt_nvrecord_delete_all_mobile_record(); + break; + case OP_TOTA_SHUTDOWM: + TRACE(0,"##### custom: shutdown"); + app_shutdown(); + break; + case OP_TOTA_REBOOT: + TRACE(0,"##### custom: reboot"); + // TODO: + break; + default: + ; + } + +} + +TOTA_COMMAND_TO_ADD(OP_TOTA_FACTORY_RESET, _custom_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_CLEAR_PAIRING_INFO, _custom_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_SHUTDOWM, _custom_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_REBOOT, _custom_cmd_handle, false, 0, NULL ); diff --git a/services/tota/app_tota_custom.h b/services/tota/app_tota_custom.h new file mode 100644 index 0000000..3885e46 --- /dev/null +++ b/services/tota/app_tota_custom.h @@ -0,0 +1,22 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __APP_TOTA_CUSTOM_H__ +#define __APP_TOTA_CUSTOM_H__ + +void app_tota_custom_init(); + +#endif diff --git a/services/tota/app_tota_data_handler.cpp b/services/tota/app_tota_data_handler.cpp new file mode 100644 index 0000000..fe87a56 --- /dev/null +++ b/services/tota/app_tota_data_handler.cpp @@ -0,0 +1,176 @@ +/** + **************************************************************************************** + * + * @file app_tota_data_handler.c + * + * @date 24th April 2018 + * + * @brief The framework of the tota data handler + * + * Copyright (C) 2017 + * + * + **************************************************************************************** + */ +#include "string.h" +#include "cmsis_os.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "apps.h" +#include "stdbool.h" +#include "app_tota.h" +#include "app_tota_cmd_code.h" +#include "app_tota_cmd_handler.h" +#include "app_tota_data_handler.h" +//#include "rwapp_config.h" +#include "crc32.h" +#include "app_spp_tota.h" +#include "app_spp_tota_general_service.h" +#include "app_tota_conn.h" +#include "tota_buffer_manager.h" +#include "tota_stream_data_transfer.h" +/** + * @brief tota data handling environment + * + */ + +typedef struct +{ + uint8_t isDataXferInProgress; + uint8_t isCrcCheckEnabled; + uint32_t wholeDataXferLen; + uint32_t dataXferLenUntilLastSegVerification; + uint32_t currentWholeCrc32; + uint32_t wholeCrc32UntilLastSeg; + uint32_t crc32OfCurrentSeg; +} APP_TOTA_DATA_HANDLER_ENV_T; + +#define APP_TOTA_TX_BUF_SIZE 2046 +static uint8_t app_tota_tmpDataXferBuf[APP_TOTA_TX_BUF_SIZE]; + + +/*static receive_data_callback recervice_data_cb = NULL; +void app_tota_data_received_callback_handler_register(receive_data_callback cb ) +{ + recervice_data_cb = cb; +} +__attribute__((weak)) void app_tota_data_received_callback(uint8_t* ptrData, uint32_t dataLength) +{ + if(recervice_data_cb != NULL){ + recervice_data_cb(ptrData,dataLength); + } +} +*/ + +/** + * @brief Receive the data from the peer device and parse them + * + * @param ptrData Pointer of the received data + * @param dataLength Length of the received data + * + * @return APP_TOTA_CMD_RET_STATUS_E + */ +APP_TOTA_CMD_RET_STATUS_E app_tota_data_received(uint8_t* ptrData, uint32_t dataLength) +{ + TOTA_LOG_DBG(0, ">>> app_tota_data_received"); + if ((OP_TOTA_STREAM_DATA != (APP_TOTA_CMD_CODE_E)(((uint16_t *)ptrData)[0])) || + (dataLength < TOTA_CMD_CODE_SIZE)) + { + return TOTA_INVALID_DATA_PACKET; + } + APP_TOTA_TRANSMISSION_PATH_E dataPath = app_tota_get_datapath(); + + + APP_TOTA_DATA_ACK_T tAck = {0}; + app_tota_send_command(OP_TOTA_SPP_DATA_ACK, (uint8_t *)&tAck, sizeof(tAck), dataPath); + return TOTA_NO_ERROR; +} + +void app_tota_send_data(APP_TOTA_TRANSMISSION_PATH_E path, uint8_t* ptrData, uint32_t dataLength) +{ + if (path < APP_TOTA_TRANSMISSION_PATH_COUNT) + { + ((uint16_t *)app_tota_tmpDataXferBuf)[0] = OP_TOTA_STREAM_DATA; + memcpy(app_tota_tmpDataXferBuf + TOTA_CMD_CODE_SIZE, ptrData, dataLength); + + switch (path) + { + case APP_TOTA_VIA_SPP: + app_tota_send_data_via_spp(app_tota_tmpDataXferBuf, dataLength + TOTA_CMD_CODE_SIZE); + break; + case APP_TOTA_GEN_VIA_SPP: + app_tota_gen_send_data_via_spp(app_tota_tmpDataXferBuf, dataLength + TOTA_CMD_CODE_SIZE); + break; + default: + break; + } + } +} + +#if defined(APP_ANC_TEST) +void app_anc_tota_send_data(APP_TOTA_TRANSMISSION_PATH_E path, uint8_t* ptrData, uint32_t dataLength) +{ + if (path < APP_TOTA_TRANSMISSION_PATH_COUNT) + { + switch (path) + { + case APP_TOTA_VIA_SPP: + app_tota_send_data_via_spp(ptrData, dataLength); + break; + default: + break; + } + } +} +#endif + + +void app_tota_handle_received_data(uint8_t* buffer, uint16_t maxBytes) +{ + TOTA_LOG_DBG(2,"[%s]data receive data length = %d",__func__,maxBytes); + uint8_t * _buf = buffer; + uint32_t _bufLen = maxBytes; + + if (OP_TOTA_STREAM_DATA == *(uint16_t *)buffer) + { + TOTA_LOG_DBG(0,"APP TOTA DATA RECEIVED"); + app_tota_data_received(_buf, _bufLen); + } + else + { + if ( OP_TOTA_STRING == *(uint16_t *)buffer ) + { + TOTA_LOG_DBG(0,"APP TOTA STRING RECEIVED"); + } + else + { +#if defined(TOTA_ENCODE) && TOTA_ENCODE + if ( is_tota_connected() ) + { + TOTA_LOG_DBG(0,"APP TOTA ENCRYPT DATA RECEIVED"); + _buf = tota_decrypt_packet(buffer, maxBytes, &_bufLen); + } + else + { + if ( *(uint16_t *)buffer <= OP_TOTA_CONN_CONFIRM ) + { + TOTA_LOG_DBG(0,"APP TOTA UNCRYPT CONN COMMAND"); + } + else + { + // TODO + TOTA_LOG_DBG(0,"TOTA UNCONNECT: COMMAND NOT SUPPORT"); + return; + } + } + app_tota_cmd_received(_buf, _bufLen); +#else + TOTA_LOG_DBG(0,"APP TOTA CMD RECEIVED"); + app_tota_cmd_received(_buf, _bufLen); +#endif + } + + } + +} + diff --git a/services/tota/app_tota_data_handler.h b/services/tota/app_tota_data_handler.h new file mode 100644 index 0000000..45789dd --- /dev/null +++ b/services/tota/app_tota_data_handler.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __APP_TOTA_DATA_HANDLER_H__ +#define __APP_TOTA_DATA_HANDLER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_tota_cmd_code.h" + +typedef struct +{ + uint8_t isHasCrcCheck : 1; + uint8_t reserved : 7; + uint8_t reservedBytes[7]; +} APP_TOTA_START_DATA_XFER_T; + +typedef struct +{ + uint8_t isHasWholeCrcCheck : 1; + uint8_t reserved : 7; + uint8_t reservedBytes1[3]; + uint32_t wholeDataLenToCheck; + uint32_t crc32OfWholeData; +} APP_TOTA_STOP_DATA_XFER_T; + +typedef struct +{ + uint32_t segmentDataLen; + uint32_t crc32OfSegment; + uint8_t reserved[4]; +} APP_TOTA_VERIFY_DATA_SEGMENT_T; + +typedef struct +{ + uint32_t reserved; +} APP_TOTA_START_DATA_XFER_RSP_T; + +typedef struct +{ + uint32_t reserved; +} APP_TOTA_STOP_DATA_XFER_RSP_T; + +typedef struct +{ + uint32_t reserved; +} APP_TOTA_VERIFY_DATA_SEGMENT_RSP_T; + +typedef struct +{ + uint32_t dataLenReceivedByPeerDev; +} APP_TOTA_DATA_ACK_T; + +typedef void(* receive_data_callback)(uint8_t* ptrData, uint32_t dataLength); + +//void app_tota_data_reset_env(void); + +void app_tota_data_xfer_started(APP_TOTA_CMD_RET_STATUS_E retStatus); +void app_tota_data_xfer_stopped(APP_TOTA_CMD_RET_STATUS_E retStatus); +void app_tota_data_segment_verified(APP_TOTA_CMD_RET_STATUS_E retStatus); +//void app_tota_data_received_callback(uint8_t* ptrData, uint32_t dataLength); +void app_tota_send_data(APP_TOTA_TRANSMISSION_PATH_E path, uint8_t* ptrData, uint32_t dataLength); +void app_tota_send_data_stream(APP_TOTA_TRANSMISSION_PATH_E path, uint8_t* ptrData, uint32_t dataLength); +void app_tota_start_data_xfer(APP_TOTA_TRANSMISSION_PATH_E path, APP_TOTA_START_DATA_XFER_T* req); +void app_tota_stop_data_xfer(APP_TOTA_TRANSMISSION_PATH_E path, APP_TOTA_STOP_DATA_XFER_T* req); +APP_TOTA_CMD_RET_STATUS_E app_tota_data_received(uint8_t* ptrData, uint32_t dataLength); +bool app_tota_data_is_data_transmission_started(void); +void app_tota_handle_received_data(uint8_t* buffer, uint16_t maxBytes); +void app_tota_kickoff_dataxfer(void); +void app_tota_stop_dataxfer(void); +void app_tota_data_ack_received(uint32_t dataLength); +void app_tota_data_received_callback_handler_register(receive_data_callback cb ); + +#if defined(APP_ANC_TEST) +void app_anc_tota_send_data(APP_TOTA_TRANSMISSION_PATH_E path, uint8_t* ptrData, uint32_t dataLength); +#endif + +#ifdef __cplusplus + } +#endif + +#endif // #ifndef __APP_TOTA_DATA_HANDLER_H__ \ No newline at end of file diff --git a/services/tota/app_tota_flash_program.cpp b/services/tota/app_tota_flash_program.cpp new file mode 100644 index 0000000..0188b68 --- /dev/null +++ b/services/tota/app_tota_flash_program.cpp @@ -0,0 +1,354 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "app_tota_cmd_code.h" +#include "app_spp_tota.h" +#include "app_tota.h" +#include "app_tota_cmd_handler.h" +#include "hal_norflash.h" +#include "pmu.h" +#include "string.h" +#include "cmsis.h" +#include "crc32.h" +#include "cmsis_os.h" +#include "app_tota_flash_program.h" + +#define TOTA_CACHE_2_UNCACHE(addr) ((unsigned int *)((unsigned int)(addr) & ~(0x04000000))) + +static uint8_t sector_buffer[FLASH_SECTOR_SIZE_IN_BYTES]; +static uint32_t sector_size = FLASH_SECTOR_SIZE_IN_BYTES; + +/* +** handle flash cmd +** -> OP_TOTA_WRITE_FLASH_CMD +** -> OP_TOTA_ERASE_FLASH_CMD +*/ +static void _tota_flash_cmd_handle(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen); + +/* +** just use this function to write data to flash with proper address +** already handle sector alignment +** write flash success -> return true +** write flash failed -> return false +*/ +static bool _write_flash_with_crc_check(uint32_t startAddr, uint8_t * dataBuf, uint32_t dataLen, uint32_t crc); + +/* +** just use this function to erase flash with proper address and length +** already handle sector alignment +*/ +static void _erase_flash(uint32_t startAddr, uint32_t dataLen); + +/*------------------------------------------------------------------------------------------------------*/ +static void _tota_spp_connected(void); +static void _tota_spp_disconnected(void); +static void _tota_spp_tx_done(void); +static void _tota_spp_data_receive_handle(uint8_t * buf, uint32_t len); + +static tota_callback_func_t s_func = { + _tota_spp_connected, + _tota_spp_disconnected, + _tota_spp_tx_done, + _tota_spp_data_receive_handle +}; + +static APP_TOTA_MODULE_E s_module = APP_TOTA_FLASH; + +void app_tota_flash_init() +{ + tota_callback_module_register(s_module, s_func); +} + +static void _tota_spp_connected(void) +{ + ; +} + +static void _tota_spp_disconnected(void) +{ + ; +} + +static void _tota_spp_tx_done(void) +{ + ; +} + +static void _tota_spp_data_receive_handle(uint8_t * buf, uint32_t len) +{ + ; +} + +/*------------------------------------------------------------------------------------------------------*/ + +/* for debug and test */ +void tota_show_flash_test(uint32_t startAddr, uint32_t len) +{ + uint8_t * pbuf = (uint8_t*)startAddr; + for ( uint32_t i = 0; i < len; i ++ ) + { + TOTA_LOG_DBG(3, "%d: [0x%2x] || [%c]", i, pbuf[i], (char)pbuf[i]); + } +} + +/* for debug and test */ +void tota_write_flash_test(uint32_t startAddr, uint8_t * dataBuf, uint32_t dataLen) +{ + uint32_t lock; + uint32_t s1, s2, s3, s4; + hal_norflash_get_size(HAL_NORFLASH_ID_0, &s1, &s2, &s3, &s4); + TOTA_LOG_DBG(4,"-- %u %u %u %u --", s1, s2, s3, s4); + TOTA_LOG_DBG(2,"flush %d bytes to flash addr 0x%x", dataLen, startAddr); + TOTA_LOG_DBG(1,"data: %s", (char *)dataBuf); + + lock=int_lock_global(); + pmu_flash_write_config(); + hal_norflash_erase(HAL_NORFLASH_ID_0, (uint32_t)(startAddr), FLASH_SECTOR_SIZE_IN_BYTES); + hal_norflash_write(HAL_NORFLASH_ID_0, (uint32_t)(startAddr), dataBuf, dataLen); + pmu_flash_read_config(); + int_unlock_global(lock); + + uint8_t * pbuf = (uint8_t*)startAddr; + for ( uint32_t i = 0; i < dataLen; i ++ ) + { + TOTA_LOG_DBG(3, "%d: [0x%2x] || [0x%2x]", i, pbuf[i], dataBuf[i]); + } +} + +static void _tota_flash_cmd_handle(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + TOTA_LOG_DBG(2,"Func code 0x%x, param len %d", funcCode, paramLen); + TOTA_LOG_DBG(1,"function: %s", __func__); + APP_TOTA_TRANSMISSION_PATH_E dataPath = app_tota_get_datapath(); + APP_TOTA_CMD_RET_STATUS_E rsp_status = TOTA_NO_ERROR; + TOTA_WRITE_FLASH_STRUCT_T * pflash_write_struct = (TOTA_WRITE_FLASH_STRUCT_T *)ptrParam; + TOTA_ERASE_FLASH_STRUCT_T * pflash_erase_struct = (TOTA_ERASE_FLASH_STRUCT_T *)ptrParam; + uint32_t crc; + switch (funcCode) + { + case OP_TOTA_WRITE_FLASH_CMD: + TOTA_LOG_DBG(2, "write flash: %d bytes, crc: 0x%x", pflash_write_struct->dataLen, pflash_write_struct->dataCrc); + pflash_write_struct->dataBuf[pflash_write_struct->dataLen] = '\0'; + TOTA_LOG_DBG(1, "write flash: %s", (char*)pflash_write_struct->dataBuf); + rsp_status = TOTA_WRITE_FLASH_CRC_CHECK_FAILED; + crc = crc32(0, pflash_write_struct->dataBuf, pflash_write_struct->dataLen); + TOTA_LOG_DBG(1, "crc 0x%x || 0x%x", crc, pflash_write_struct->dataCrc); + if ( crc == pflash_write_struct->dataCrc ) + { + if ( _write_flash_with_crc_check(pflash_write_struct->address, pflash_write_struct->dataBuf, pflash_write_struct->dataLen, pflash_write_struct->dataCrc) ) + { + rsp_status = TOTA_NO_ERROR; + } + } + + else + { + TOTA_LOG_DBG(0, "crc error..."); + } + //tota_show_flash_test(TOTA_FLASH_TEST_ADDR-10, 30); + break; + case OP_TOTA_ERASE_FLASH_CMD: + TOTA_LOG_DBG(0,"erase flash"); + TOTA_LOG_DBG(2, "erase flash: 0x%x bytes, length: %u", pflash_erase_struct->address, pflash_erase_struct->length); + _erase_flash(pflash_erase_struct->address, pflash_erase_struct->length); + //tota_show_flash_test(TOTA_FLASH_TEST_ADDR-10, 30); + break; + default: + TOTA_LOG_DBG(0,"error function code"); + } + app_tota_send_response_to_command(funcCode, rsp_status, NULL, 0, dataPath); +} + +static bool _write_flash_with_crc_check(uint32_t startAddr, uint8_t * dataBuf, uint32_t dataLen, uint32_t crc) +{ + uint32_t lock; + TOTA_LOG_DBG(2,"flush %d bytes to flash addr 0x%x", dataLen, startAddr); + //TOTA_LOG_DBG(1,"data: %s", (char *)dataBuf); + + uint32_t pre_bytes = 0, middle_bytes = 0, post_bytes = 0; + uint32_t base1 = startAddr - startAddr%sector_size; + uint32_t base2 = startAddr + dataLen - (startAddr+dataLen)%sector_size; + uint32_t exist_bytes; + uint32_t middle_start_addr; + uint32_t buffer_offset; + if ( startAddr % sector_size == 0 ) + { + pre_bytes = 0; + middle_bytes = dataLen - dataLen%sector_size; + post_bytes = dataLen - middle_bytes; + } + else + { + if ( base1 == base2 ) + { + pre_bytes = dataLen; + } + else + { + pre_bytes = sector_size - startAddr%sector_size; + middle_bytes = base2 - base1 - sector_size; + post_bytes = startAddr + dataLen - base2; + } + } + TOTA_LOG_DBG(3, "pre:%u, middle:%u, post:%u", pre_bytes, middle_bytes, post_bytes); + + if ( pre_bytes != 0 ) + { + memcpy(sector_buffer, (uint8_t*)base1, sector_size); + if ( base1 == base2 ) + memcpy(sector_buffer+(startAddr-base1), dataBuf, dataLen); + else + memcpy(sector_buffer+(startAddr-base1), dataBuf, sector_size-(startAddr-base1)); + lock=int_lock_global(); + pmu_flash_write_config(); + hal_norflash_erase(HAL_NORFLASH_ID_0, base1, sector_size); + hal_norflash_write(HAL_NORFLASH_ID_0, base1, sector_buffer, sector_size); + pmu_flash_read_config(); + int_unlock_global(lock); + } + if ( middle_bytes != 0 ) + { + if ( base1 != startAddr ) + middle_start_addr = base1+sector_size; + else + middle_start_addr = base1; + buffer_offset = middle_start_addr - startAddr; + lock=int_lock_global(); + pmu_flash_write_config(); + for ( uint32_t i = 0; i < middle_bytes/sector_size; i++ ) + { + hal_norflash_erase(HAL_NORFLASH_ID_0, middle_start_addr+(i*sector_size), sector_size); + hal_norflash_write(HAL_NORFLASH_ID_0, middle_start_addr+(i*sector_size), dataBuf+buffer_offset+(i*sector_size), sector_size); + } + pmu_flash_read_config(); + int_unlock_global(lock); + } + if ( post_bytes != 0 ) + { + exist_bytes = sector_size - post_bytes; + memcpy(sector_buffer, (uint8_t*)(base2+post_bytes), exist_bytes); + + lock=int_lock_global(); + pmu_flash_write_config(); + + hal_norflash_erase(HAL_NORFLASH_ID_0, base2, FLASH_SECTOR_SIZE_IN_BYTES); + hal_norflash_write(HAL_NORFLASH_ID_0, base2, dataBuf+(base2-startAddr), post_bytes); + hal_norflash_write(HAL_NORFLASH_ID_0, base2+post_bytes, sector_buffer, exist_bytes); + + pmu_flash_read_config(); + int_unlock_global(lock); + } + + // read and check crc + const uint32_t read_size = 1024; + uint8_t read_buffer[read_size]; + uint32_t left_bytes = dataLen; + uint32_t read_offset = 0; + uint32_t calculate_crc = 0; + while ( left_bytes > read_size ) + { + memcpy(read_buffer, (uint8_t*)(startAddr+read_offset), read_size); + calculate_crc = crc32(calculate_crc, read_buffer, read_size); + read_offset += read_size; + left_bytes -= read_size; + } + if ( left_bytes != 0 ) + { + memcpy(read_buffer, (uint8_t*)(startAddr+read_offset), left_bytes); + calculate_crc = crc32(calculate_crc, read_buffer, left_bytes); + } + + return crc == calculate_crc; +} + +static void _erase_flash(uint32_t startAddr, uint32_t dataLen) +{ + uint32_t lock; + TOTA_LOG_DBG(2,"erase %d bytes from flash addr 0x%x", dataLen, startAddr); + + uint32_t pre_bytes = 0, middle_bytes = 0, post_bytes = 0; + uint32_t base1 = startAddr - startAddr%sector_size; + uint32_t base2 = startAddr + dataLen - (startAddr+dataLen)%sector_size; + uint32_t exist_bytes; + uint32_t middle_start_addr; + if ( startAddr % sector_size == 0 ) + { + pre_bytes = 0; + middle_bytes = dataLen - dataLen%sector_size; + post_bytes = dataLen - middle_bytes; + } + else + { + if ( base1 == base2 ) + { + pre_bytes = dataLen; + } + else + { + pre_bytes = sector_size - startAddr%sector_size; + middle_bytes = base2 - base1 - sector_size; + post_bytes = startAddr + dataLen - base2; + } + } + TOTA_LOG_DBG(3, "pre:%u, middle:%u, post:%u", pre_bytes, middle_bytes, post_bytes); + + if ( pre_bytes != 0 ) + { + memcpy(sector_buffer, (uint8_t*)base1, sector_size); + if ( base1 == base2 ) + memset(sector_buffer+(startAddr-base1), 0xff, dataLen); + else + memset(sector_buffer+(startAddr-base1), 0xff, sector_size-(startAddr-base1)); + lock=int_lock_global(); + pmu_flash_write_config(); + hal_norflash_erase(HAL_NORFLASH_ID_0, base1, sector_size); + hal_norflash_write(HAL_NORFLASH_ID_0, base1, sector_buffer, sector_size); + pmu_flash_read_config(); + int_unlock_global(lock); + } + if ( middle_bytes != 0 ) + { + if ( base1 != startAddr ) + middle_start_addr = base1+sector_size; + else + middle_start_addr = base1; + lock=int_lock_global(); + pmu_flash_write_config(); + for ( uint32_t i = 0; i < middle_bytes/sector_size; i++ ) + { + hal_norflash_erase(HAL_NORFLASH_ID_0, middle_start_addr+(i*sector_size), sector_size); + } + pmu_flash_read_config(); + int_unlock_global(lock); + } + if ( post_bytes != 0 ) + { + exist_bytes = sector_size - post_bytes; + memcpy(sector_buffer, (uint8_t*)(base2+post_bytes), exist_bytes); + + lock=int_lock_global(); + pmu_flash_write_config(); + + hal_norflash_erase(HAL_NORFLASH_ID_0, base2, FLASH_SECTOR_SIZE_IN_BYTES); + hal_norflash_write(HAL_NORFLASH_ID_0, base2+post_bytes, sector_buffer, exist_bytes); + + pmu_flash_read_config(); + int_unlock_global(lock); + } +} + +TOTA_COMMAND_TO_ADD(OP_TOTA_WRITE_FLASH_CMD, _tota_flash_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_ERASE_FLASH_CMD, _tota_flash_cmd_handle, false, 0, NULL ); \ No newline at end of file diff --git a/services/tota/app_tota_flash_program.h b/services/tota/app_tota_flash_program.h new file mode 100644 index 0000000..a006803 --- /dev/null +++ b/services/tota/app_tota_flash_program.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __APP_TOTA_FLASH_PROGRAM_H__ +#define __APP_TOTA_FLASH_PROGRAM_H__ + + +//TODO: +#define MAX_FLASH_HANDLE_SIZE 650 +#define TOTA_FLASH_TEST_ADDR (0x200000+FLASH_NC_BASE+4096) + + +void app_tota_flash_init(); + +void tota_write_flash_test(uint32_t startAddr, uint8_t * dataBuf, uint32_t dataLen); + +/* +** 4 + 650 + 2 + 4 = 660 +*/ +typedef struct{ + uint32_t address; + uint16_t dataLen; + uint32_t dataCrc; + uint8_t dataBuf[MAX_FLASH_HANDLE_SIZE]; +}TOTA_WRITE_FLASH_STRUCT_T; + + +typedef struct{ + uint32_t address; + uint16_t length; +}TOTA_ERASE_FLASH_STRUCT_T; + + +#endif diff --git a/services/tota/app_tota_general.cpp b/services/tota/app_tota_general.cpp new file mode 100644 index 0000000..e4ca9fd --- /dev/null +++ b/services/tota/app_tota_general.cpp @@ -0,0 +1,239 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "bluetooth.h" +#include "hal_cmu.h" +#include "app_tota_cmd_code.h" +#include "app_spp_tota.h" +#include "app_tota.h" +#include "app_tota_cmd_handler.h" +#include "cmsis.h" +#include "crc32.h" +#include "app_hfp.h" +#include "app_key.h" +#include "app_tota_general.h" +#include "app_spp_tota.h" +#include "nvrecord_ble.h" +/* +** general info struct +** -> bt name +** -> ble name +** -> bt local/peer addr +** -> ble local/peer addr +** -> ibrt role +** -> crystal freq +** -> xtal fcap +** -> bat volt/level/status +** -> fw version +** -> ear location +** -> rssi info +*/ + +/*------------------------------------------------------------------------------------------------------------------------*/ + +/* +** general info +*/ +static general_info_t general_info; + + +/* +** get general info +*/ +static void __get_general_info(); + +/* +** handle general cmd +*/ +static void __tota_general_cmd_handle(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen); + +/*------------------------------------------------------------------------------------------------------------------------*/ +static void _tota_spp_connected(void); +static void _tota_spp_disconnected(void); +static void _tota_spp_tx_done(void); +static void _tota_spp_data_receive_handle(uint8_t * buf, uint32_t len); + +static tota_callback_func_t s_func = { + _tota_spp_connected, + _tota_spp_disconnected, + _tota_spp_tx_done, + _tota_spp_data_receive_handle +}; + +static APP_TOTA_MODULE_E s_module = APP_TOTA_GENERAL; + +void app_tota_general_init() +{ + tota_callback_module_register(s_module, s_func); +} + +static void _tota_spp_connected(void) +{ + ; +} + +static void _tota_spp_disconnected(void) +{ + ; +} + +static void _tota_spp_tx_done(void) +{ + ; +} + +static void _tota_spp_data_receive_handle(uint8_t * buf, uint32_t len) +{ + ; +} + + +/*------------------------------------------------------------------------------------------------------------------------*/ + +static void __tota_general_cmd_handle(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + TOTA_LOG_DBG(2,"Func code 0x%x, param len %d", funcCode, paramLen); + TOTA_LOG_DBG(0,"Param content:"); + DUMP8("%02x ", ptrParam, paramLen); + uint8_t resData[48]={0}; + uint32_t resLen=1; + uint8_t volume_level; + switch (funcCode) + { + case OP_TOTA_GENERAL_INFO_CMD: + __get_general_info(); + app_tota_send_response_to_command(funcCode,TOTA_NO_ERROR,(uint8_t *)&general_info, sizeof(general_info_t),app_tota_get_datapath()); + // for test + // app_tota_send_response_to_command(funcCode,TOTA_NO_ERROR,(uint8_t *)&resLen, sizeof(uint32_t),app_tota_get_datapath()); + return ; + case OP_TOTA_MERIDIAN_EFFECT_CMD: + resData[0] = app_meridian_eq(ptrParam[0]); + break; + case OP_TOTA_EQ_SELECT_CMD: + break; + case OP_TOTA_VOLUME_PLUS_CMD: + app_bt_volumeup(); + volume_level = app_bt_stream_local_volume_get(); + resData[0] = volume_level; + TRACE(1,"volume = %d",volume_level); + break; + case OP_TOTA_VOLUME_DEC_CMD: + app_bt_volumedown(); + volume_level = app_bt_stream_local_volume_get(); + resData[0] = volume_level; + resLen = 1; + TRACE(1,"volume = %d",volume_level); + break; + case OP_TOTA_VOLUME_SET_CMD: + //uint8_t scolevel = ptrParam[0]; + //uint8_t a2dplevel = ptrParam[1]; + app_bt_set_volume(APP_BT_STREAM_HFP_PCM,ptrParam[0]); + app_bt_set_volume(APP_BT_STREAM_A2DP_SBC,ptrParam[1]); + btapp_hfp_report_speak_gain(); + btapp_a2dp_report_speak_gain(); + break; + case OP_TOTA_VOLUME_GET_CMD: + resData[0] = app_bt_stream_hfpvolume_get(); + resData[1] = app_bt_stream_a2dpvolume_get(); + resLen = 2; + break; + case OP_TOTA_EQ_SET_CMD: + //int eq_index = ptrParam[0]; + if (ptrParam[0] == 3) + resData[0] = app_meridian_eq(true); + else + resData[0] = app_audio_set_eq(ptrParam[0]); + resLen = 1; + break; + case OP_TOTA_EQ_GET_CMD: + resData[0] = app_audio_get_eq(); + resLen = 1; + break; + case OP_TOTA_RAW_DATA_SET_CMD: + app_ibrt_debug_parse(ptrParam, paramLen); + break; + default: + TRACE(1,"wrong cmd 0x%x",funcCode); + resData[0] = -1; + return; + } + app_tota_send_response_to_command(funcCode,TOTA_NO_ERROR,resData,resLen,app_tota_get_datapath()); +} + +/* get general info */ +static void __get_general_info() +{ + /* get bt-ble name */ + uint8_t* factory_name_ptr =factory_section_get_bt_name(); + if ( factory_name_ptr != NULL ) + { + uint16_t valid_len = strlen((char*)factory_name_ptr) > BT_BLE_LOCAL_NAME_LEN? BT_BLE_LOCAL_NAME_LEN:strlen((char*)factory_name_ptr); + memcpy(general_info.btName,factory_name_ptr,valid_len); + } + + factory_name_ptr =factory_section_get_ble_name(); + if ( factory_name_ptr != NULL ) + { + uint16_t valid_len = strlen((char*)factory_name_ptr) > BT_BLE_LOCAL_NAME_LEN? BT_BLE_LOCAL_NAME_LEN:strlen((char*)factory_name_ptr); + memcpy(general_info.bleName,factory_name_ptr,valid_len); + } + + /* get bt-ble peer addr */ + ibrt_config_t addrInfo; + app_ibrt_ui_test_config_load(&addrInfo); + general_info.ibrtRole = addrInfo.nv_role; + memcpy(general_info.btLocalAddr.address, addrInfo.local_addr.address, 6); + memcpy(general_info.btPeerAddr.address, addrInfo.peer_addr.address, 6); + + #ifdef BLE + memcpy(general_info.bleLocalAddr.address, bt_get_ble_local_address(), 6); + memcpy(general_info.blePeerAddr.address, nv_record_tws_get_peer_ble_addr(), 6); + #endif + + /* get crystal info */ + general_info.crystal_freq = hal_cmu_get_crystal_freq(); + + /* factory_section_xtal_fcap_get */ + factory_section_xtal_fcap_get(&general_info.xtal_fcap); + + /* get battery info (volt level)*/ + app_battery_get_info(&general_info.battery_volt,&general_info.battery_level,&general_info.battery_status); + + /* get firmware version */ +#ifdef FIRMWARE_REV + system_get_info(&general_info.fw_version[0],&general_info.fw_version[1],&general_info.fw_version[2],&general_info.fw_version[3]); + TRACE(4,"firmware version = %d.%d.%d.%d",general_info.fw_version[0],general_info.fw_version[1],general_info.fw_version[2],general_info.fw_version[3]); +#endif + + /* get ear location info */ + if ( app_tws_is_right_side() ) general_info.ear_location = EAR_SIDE_RIGHT; + else if ( app_tws_is_left_side() ) general_info.ear_location = EAR_SIDE_LEFT; + else general_info.ear_location = EAR_SIDE_UNKNOWN; + + app_ibrt_rssi_get_stutter(general_info.rssi, &general_info.rssi_len); +} + + +/* general command */ +TOTA_COMMAND_TO_ADD(OP_TOTA_GENERAL_INFO_CMD, __tota_general_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_MERIDIAN_EFFECT_CMD, __tota_general_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_EQ_SELECT_CMD, __tota_general_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_VOLUME_PLUS_CMD, __tota_general_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_VOLUME_DEC_CMD, __tota_general_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_VOLUME_SET_CMD, __tota_general_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_VOLUME_GET_CMD, __tota_general_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_EQ_SET_CMD, __tota_general_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_EQ_GET_CMD, __tota_general_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_RAW_DATA_SET_CMD, __tota_general_cmd_handle, false, 0, NULL ); diff --git a/services/tota/app_tota_general.h b/services/tota/app_tota_general.h new file mode 100644 index 0000000..6d210bd --- /dev/null +++ b/services/tota/app_tota_general.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __APP_TOTA_GENERAL_H__ +#define __APP_TOTA_GENERAL_H__ + +#include "app_battery.h" +#include "factory_section.h" +#include "app_ibrt_rssi.h" +#include "app_ibrt_ui_test.h" +#include "app_tws_ibrt.h" +#include "app_bt_stream.h" +#include "app_tws_if.h" + +#define BT_BLE_LOCAL_NAME_LEN 32 + +typedef struct{ + /* bt-ble info */ + char btName[BT_BLE_LOCAL_NAME_LEN]; // 32 bytes + char bleName[BT_BLE_LOCAL_NAME_LEN]; // 32 bytes + bt_bdaddr_t btLocalAddr; // 6 bytes + bt_bdaddr_t btPeerAddr; // 6 bytes + bt_bdaddr_t bleLocalAddr; // 6 bytes + bt_bdaddr_t blePeerAddr; // 6 bytes + + /* ibrt info */ + ibrt_role_e ibrtRole; // 1 byte + + /* crystal info */ + uint32_t crystal_freq; // 4 bytes + uint32_t xtal_fcap; // 4 bytes + + /* battery info */ + APP_BATTERY_MV_T battery_volt; // 2 bytes + uint8_t battery_level; // 1 byte + APP_BATTERY_STATUS_T battery_status; // 4 bytes + + /* firmware info */ + uint8_t fw_version[4]; // 4 bytes + + /* ear location info */ + APP_TWS_SIDE_T ear_location; // 4 byte + + /* rssi info */ + uint8_t rssi[48]; // 48 bytes + uint32_t rssi_len; // 4 bytes +} general_info_t; + +/*--functions from other file--*/ +#ifdef FIRMWARE_REV +extern "C" void system_get_info(uint8_t *fw_rev_0, uint8_t *fw_rev_1, uint8_t *fw_rev_2, uint8_t *fw_rev_3); +#endif + +extern void app_bt_volumeup(); +extern void app_bt_volumedown(); +extern int app_bt_stream_local_volume_get(void); +extern uint8_t app_audio_get_eq(); +extern int app_audio_set_eq(uint8_t index); +extern bool app_meridian_eq(bool onoff); +extern bool app_is_meridian_on(); + +#ifdef BLE +extern unsigned char *bt_get_ble_local_address(void); +#endif +/*--functions from other file--*/ + + +/*--interface--*/ +void app_tota_general_init(); + + +#endif + diff --git a/services/tota/app_tota_mic.cpp b/services/tota/app_tota_mic.cpp new file mode 100644 index 0000000..2ec51de --- /dev/null +++ b/services/tota/app_tota_mic.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "app_spp_tota.h" +#include "tota_stream_data_transfer.h" +#include "app_tota_cmd_code.h" +#include "app_bt_stream.h" +#include "app_audio.h" +#include "app_tota.h" +#include "app_tota_cmd_handler.h" +#include "app_tota_mic.h" +#include "cmsis_os.h" + +static void _tota_spp_connected(void); +static void _tota_spp_disconnected(void); +static void _tota_spp_tx_done(void); +static void _tota_spp_data_receive_handle(uint8_t * buf, uint32_t len); +/**/ +static void _mic_cmd_handle(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen); + +/**/ +static tota_callback_func_t s_func = { + _tota_spp_connected, + _tota_spp_disconnected, + _tota_spp_tx_done, + _tota_spp_data_receive_handle +}; + +static APP_TOTA_MODULE_E s_module = APP_TOTA_MIC; + + +void app_tota_mic_init() +{ + tota_callback_module_register(s_module, s_func); +} + +static void _tota_spp_connected(void) +{ + ; +} + +static void _tota_spp_disconnected(void) +{ + ; +} + +static void _tota_spp_tx_done(void) +{ + ; +} + +static void _tota_spp_data_receive_handle(uint8_t * buf, uint32_t len) +{ + ; +} + + + +/*-----------------------------------------------------------------------------*/ +static void _mic_cmd_handle(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + TOTA_LOG_DBG(2,"Func code 0x%x, param len %d", funcCode, paramLen); + TOTA_LOG_DBG(0,"Param content:"); + DUMP8("%02x ", ptrParam, paramLen); + APP_TOTA_CMD_RET_STATUS_E rsp_status = TOTA_NO_ERROR; + uint8_t resData[48]={0}; + uint32_t resLen=1; + switch (funcCode) + { + case OP_TOTA_MIC_TEST_ON: + TRACE(0,"#####mic test on:"); +#ifdef __FACTORY_MODE_SUPPORT__ + app_audio_sendrequest(APP_BT_STREAM_INVALID, (uint8_t)APP_BT_SETTING_CLOSEALL, 0); + app_audio_sendrequest(APP_FACTORYMODE_AUDIO_LOOP, (uint8_t)APP_BT_SETTING_OPEN, 0); +#endif + break; + case OP_TOTA_MIC_TEST_OFF: + TRACE(0,"#####mic test off:"); +#ifdef __FACTORY_MODE_SUPPORT__ + app_audio_sendrequest(APP_FACTORYMODE_AUDIO_LOOP, (uint8_t)APP_BT_SETTING_CLOSE, 0); +#endif + break; + case OP_TOTA_MIC_SWITCH: + TRACE(0,"####mic switch test, do role switch"); + if ( !app_ibrt_ui_tws_switch() ) + rsp_status = TOTA_MIC_SWITCH_FAILED; + break; + default: + ; + } + app_tota_send_response_to_command(funcCode,rsp_status,resData,resLen,app_tota_get_datapath()); +} + +TOTA_COMMAND_TO_ADD(OP_TOTA_MIC_TEST_ON, _mic_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_MIC_TEST_OFF, _mic_cmd_handle, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_MIC_SWITCH, _mic_cmd_handle, false, 0, NULL ); diff --git a/services/tota/app_tota_mic.h b/services/tota/app_tota_mic.h new file mode 100644 index 0000000..43675f4 --- /dev/null +++ b/services/tota/app_tota_mic.h @@ -0,0 +1,26 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __APP_TOTA_MIC_H__ +#define __APP_TOTA_MIC_H__ + + +extern "C" bool app_ibrt_ui_tws_switch(void); + +void app_tota_mic_init(); + + +#endif \ No newline at end of file diff --git a/services/tota/tota_buffer_manager.cpp b/services/tota/tota_buffer_manager.cpp new file mode 100644 index 0000000..abc0316 --- /dev/null +++ b/services/tota/tota_buffer_manager.cpp @@ -0,0 +1,141 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "tota_buffer_manager.h" +#include "app_tota_cmd_code.h" +#include "cmsis_os.h" +#include "string.h" + +osMutexDef (stream_buf_mutex); +osMutexId stream_buf_mutex_id; + +static stream_buf_t stream_buf; +static osThreadId father_thread_tid; + +void tota_stream_buffer_init(osThreadId tid) +{ + stream_buf.dataSize = 0; + stream_buf.availableSpace = TOTA_STREAM_BUF_SIZE; + stream_buf.readPos = 0; + stream_buf.writePos = 0; + stream_buf.flushBytes = 0; + + stream_buf_mutex_id = osMutexCreate(osMutex(stream_buf_mutex)); + father_thread_tid = tid; +} + +bool tota_stream_buffer_write(uint8_t * buf, uint32_t bufLen) +{ + osMutexWait(stream_buf_mutex_id, osWaitForever); + if ( stream_buf.availableSpace > bufLen ) + { + // write to stream buf + if ( stream_buf.writePos + bufLen <= TOTA_STREAM_BUF_SIZE ) + { + memcpy(stream_buf.buf + stream_buf.writePos, buf, bufLen); + + stream_buf.writePos += bufLen; + if ( stream_buf.writePos == TOTA_STREAM_BUF_SIZE ) + stream_buf.writePos = 0; + } + else + { + uint32_t part1 = TOTA_STREAM_BUF_SIZE - stream_buf.writePos; + memcpy(stream_buf.buf + stream_buf.writePos, buf , part1); + memcpy(stream_buf.buf , buf + part1, bufLen-part1); + stream_buf.writePos = bufLen-part1; + } + + stream_buf.dataSize += bufLen; + stream_buf.availableSpace -= bufLen; + + TOTA_LOG_DBG(1, "buffer> after write: %5u bytes", bufLen); + TOTA_LOG_DBG(4, "buffer> size:%5u available:%5u writepos:%5u readpos:%5u:", stream_buf.dataSize, stream_buf.availableSpace, stream_buf.writePos, stream_buf.readPos); + + osMutexRelease(stream_buf_mutex_id); + /* set signal to father thread, has data */ + osSignalSet(father_thread_tid, 0x0001); + + return true; + } + else + { + osMutexRelease(stream_buf_mutex_id); + return false; + } +} + + +bool tota_stream_buffer_read(uint8_t * rbuf, uint32_t readSize, uint32_t * flushbytes) +{ + osMutexWait(stream_buf_mutex_id, osWaitForever); + if ( readSize < stream_buf.dataSize ) + { + if ( stream_buf.readPos + readSize <= TOTA_STREAM_BUF_SIZE ) + { + memcpy(rbuf, stream_buf.buf + stream_buf.readPos, readSize); + stream_buf.readPos += readSize; + if ( stream_buf.readPos == TOTA_STREAM_BUF_SIZE ) + stream_buf.readPos = 0; + } + else + { + uint32_t part1 = TOTA_STREAM_BUF_SIZE - stream_buf.readPos; + memcpy(rbuf , stream_buf.buf + stream_buf.readPos, part1); + memcpy(rbuf + part1, stream_buf.buf , readSize-part1); + stream_buf.readPos = readSize-part1; + } + stream_buf.dataSize -= readSize; + stream_buf.availableSpace += readSize; + /* debug */ + TOTA_LOG_DBG(1, "buffer> after read: %5u bytes", readSize); + TOTA_LOG_DBG(4, "buffer> size:%5u available:%5u writepos:%5u readpos:%5u:", stream_buf.dataSize, stream_buf.availableSpace, stream_buf.writePos, stream_buf.readPos); + if ( flushbytes != NULL ) + { + *flushbytes = stream_buf.flushBytes; + stream_buf.flushBytes = 0; + } + osMutexRelease(stream_buf_mutex_id); + return true; + } + else + { + osMutexRelease(stream_buf_mutex_id); + return false; + } +} + +void tota_stream_buffer_flush(void) +{ + osMutexWait(stream_buf_mutex_id, osWaitForever); + stream_buf.flushBytes = stream_buf.dataSize; + stream_buf.availableSpace = TOTA_STREAM_BUF_SIZE; + stream_buf.dataSize = 0; + stream_buf.readPos = 0; + stream_buf.writePos = 0; + osMutexRelease(stream_buf_mutex_id); +} + +void tota_stream_buffer_clean(void) +{ + osMutexWait(stream_buf_mutex_id, osWaitForever); + stream_buf.flushBytes = 0; + stream_buf.availableSpace = TOTA_STREAM_BUF_SIZE; + stream_buf.dataSize = 0; + stream_buf.readPos = 0; + stream_buf.writePos = 0; + osMutexRelease(stream_buf_mutex_id); +} \ No newline at end of file diff --git a/services/tota/tota_buffer_manager.h b/services/tota/tota_buffer_manager.h new file mode 100644 index 0000000..3bd96f8 --- /dev/null +++ b/services/tota/tota_buffer_manager.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __TOTA_BUFFER_MANAGER_H__ +#define __TOTA_BUFFER_MANAGER_H__ + +#include +#include +#include "cmsis_os.h" + +#define TOTA_STREAM_BUF_SIZE (24 * 1024 * 2 * 1 * 1) + +typedef struct{ + uint8_t buf[TOTA_STREAM_BUF_SIZE]; + uint32_t dataSize; + uint32_t availableSpace; + uint32_t writePos; + uint32_t readPos; + uint32_t flushBytes; +} stream_buf_t; + +void tota_stream_buffer_init(osThreadId tid); +bool tota_stream_buffer_write(uint8_t * buf, uint32_t bufLen); +bool tota_stream_buffer_read(uint8_t * rbuf, uint32_t readSize, uint32_t * flushbytes = NULL); +void tota_stream_buffer_flush(void); +void tota_stream_buffer_clean(void); + + + +#endif + diff --git a/services/tota/tota_stream_data_transfer.cpp b/services/tota/tota_stream_data_transfer.cpp new file mode 100644 index 0000000..8dcb79a --- /dev/null +++ b/services/tota/tota_stream_data_transfer.cpp @@ -0,0 +1,230 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "string.h" +#include "cmsis_os.h" +#include "hal_trace.h" +#include "hal_timer.h" +#include "apps.h" +#include "stdbool.h" +#include "app_tota.h" +#include "app_tota_cmd_code.h" +#include "app_tota_cmd_handler.h" +#include "app_tota_data_handler.h" +#include "app_utils.h" +#include "crc32.h" +#include "app_spp_tota.h" +#include "app_spp_tota_general_service.h" +#include "tota_buffer_manager.h" +#include "tota_stream_data_transfer.h" +#include "app_tota_conn.h" + +/* +** stream control strcut +** stream packet format: +** # header + body # +** > header: 2 bytes +** > body : 664 bytes +** +** note: stream will never be encrypted! +*/ +typedef struct{ + uint32_t flush_bytes; + bool is_streaming; + uint8_t module; + + osMutexId mutex; + osSemaphoreId sem; +}stream_control_t; + +stream_control_t stream_control; + +osMutexDef (tota_tx_buf_mutex); +osMutexId tota_tx_buf_mutex_id; + +#define SPP_BUFFER_NUM 5 + +static uint8_t spp_tx_buffer[MAX_SPP_PACKET_SIZE*SPP_BUFFER_NUM]; +static uint8_t tx_buf_index = 0; + + +/* static function */ +static bool _tota_send_stream_packet(uint8_t * pdata, uint32_t dataLen); +static void _tota_stream_data_init(); +static void _update_tx_buf(); +static uint8_t * _get_tx_buf_ptr(); + +// Semaphore +osSemaphoreDef(app_tota_send_data_sem); + +// define stream data transfer thread +#define TOTA_STREAM_DATA_STACK_SIZE 2048 +static void tota_stream_data_transfer_thread(void const *argument); +osThreadId tota_stream_thread_tid; +osThreadDef(tota_stream_data_transfer_thread, osPriorityHigh, 1, TOTA_STREAM_DATA_STACK_SIZE, "TOTA_STREAM_DATA_THREAD"); + +static void tota_stream_data_transfer_thread(void const *argument) +{ + // TODO: max speed + uint8_t buf[MAX_SPP_PACKET_SIZE]; + while ( true ) + { + app_sysfreq_req(APP_SYSFREQ_USER_OTA, APP_SYSFREQ_32K); + osSignalWait(0x0001, osWaitForever); + app_sysfreq_req(APP_SYSFREQ_USER_OTA, APP_SYSFREQ_208M); + while ( tota_stream_buffer_read(buf + STREAM_HEADER_SIZE, MAX_SPP_PACKET_SIZE - STREAM_HEADER_SIZE) ) + { + _tota_send_stream_packet(buf, MAX_SPP_PACKET_SIZE); + } + } +} + +void app_tota_stream_data_transfer_init() +{ + stream_control.sem = osSemaphoreCreate(osSemaphore(app_tota_send_data_sem), SPP_BUFFER_NUM); + tota_stream_thread_tid = osThreadCreate(osThread(tota_stream_data_transfer_thread), NULL); + _tota_stream_data_init(); +} + +// stream start +void app_tota_stream_data_start(uint16_t set_module) +{ + stream_control.module = set_module; + stream_control.is_streaming = true; +} + +// stream end +void app_tota_stream_data_end() +{ + stream_control.is_streaming = false; +} + +// stream send data while stream is start +bool app_tota_send_stream_data(uint8_t * pdata, uint32_t dataLen) +{ + if ( !stream_control.is_streaming ) + { + TOTA_LOG_DBG(0, "error: data stream not start."); + return false; + } + if ( tota_stream_buffer_write(pdata, dataLen) ) + { + TOTA_LOG_DBG(0, "send to stream buffer ok."); + return true; + } + else + { + TOTA_LOG_DBG(0, "send to stream buffer error."); + return false; + } +} + +// stream flush +void app_tota_stream_data_flush() +{ + tota_stream_buffer_flush(); +} + +// stream clean +void app_tota_stream_data_clean() +{ + tota_stream_buffer_clean(); +} + + +bool app_tota_send_data_via_spp(uint8_t * pdata, uint32_t dataLen) +{ + osSemaphoreWait(stream_control.sem, osWaitForever); + osMutexRelease(tota_tx_buf_mutex_id); + uint8_t * pbuf = pdata; + uint32_t bufLen = dataLen; +#if TOTA_ENCODE + if ( ((uint16_t *)pdata)[0] == OP_TOTA_STRING ) + { + TOTA_LOG_DBG(0, "yeah! This is a string. Do not encrypt"); + } + else if ( is_tota_connected() ) + { + pbuf = tota_encrypt_packet(pdata, dataLen, &bufLen); + } +#endif + memcpy(_get_tx_buf_ptr(), pbuf, bufLen); + + if ( app_spp_tota_send_data(_get_tx_buf_ptr(), bufLen) ) + { + _update_tx_buf(); + osMutexRelease(tota_tx_buf_mutex_id); + return true; + } + else + { + osMutexRelease(tota_tx_buf_mutex_id); + osSemaphoreRelease(stream_control.sem); + return false; + } + +} + +void app_tota_tx_done_callback() +{ + osSemaphoreRelease(stream_control.sem); +} + +bool is_stream_data_running() +{ + return stream_control.is_streaming; +} + +// send stream packet with header. packet size:666 +static bool _tota_send_stream_packet(uint8_t * pdata, uint32_t dataLen) +{ + osSemaphoreWait(stream_control.sem, osWaitForever); + osMutexRelease(tota_tx_buf_mutex_id); + ((uint16_t *)pdata)[0] = (OP_TOTA_STREAM_DATA - stream_control.module); + memcpy(_get_tx_buf_ptr(), pdata, dataLen); + if ( app_spp_tota_send_data(_get_tx_buf_ptr(), dataLen) ) + { + _update_tx_buf(); + osMutexRelease(tota_tx_buf_mutex_id); + return true; + } + else + { + osMutexRelease(tota_tx_buf_mutex_id); + osSemaphoreRelease(stream_control.sem); + return false; + } +} + +static void _tota_stream_data_init() +{ + tota_stream_buffer_init(tota_stream_thread_tid); + stream_control.module = 0; + stream_control.is_streaming = false; +} + +static void _update_tx_buf() +{ + tx_buf_index = (tx_buf_index + 1) % 5; +} + + +static uint8_t * _get_tx_buf_ptr() +{ + return (spp_tx_buffer + tx_buf_index*MAX_SPP_PACKET_SIZE); +} + + diff --git a/services/tota/tota_stream_data_transfer.h b/services/tota/tota_stream_data_transfer.h new file mode 100644 index 0000000..be5b10c --- /dev/null +++ b/services/tota/tota_stream_data_transfer.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __TOTA_STREAM_DATA_TRANSFER_H__ +#define __TOTA_STREAM_DATA_TRANSFER_H__ + +#include + + +#define MAX_SPP_PACKET_SIZE 666 +#define STREAM_HEADER_SIZE 2 + + +void app_tota_stream_data_transfer_init(); + +/* interface for streaming */ +void app_tota_stream_data_start(uint16_t set_module = 0); +void app_tota_stream_data_end(); +bool app_tota_send_stream_data(uint8_t * pdata, uint32_t dataLen); +void app_tota_stream_data_flush(); +void app_tota_stream_data_clean(); + +/* interface for send data */ +bool app_tota_send_data_via_spp(uint8_t* ptrData, uint32_t length); + +/* interface for app_tota */ +bool is_stream_data_running(); +void app_tota_tx_done_callback(); + +#endif diff --git a/services/tota/tota_test.cpp b/services/tota/tota_test.cpp new file mode 100644 index 0000000..c0e3dae --- /dev/null +++ b/services/tota/tota_test.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include +#include "app_tota_cmd_code.h" +#include "app_tota_data_handler.h" +#include "app_utils.h" +#include "cmsis_os.h" +#include "tota_buffer_manager.h" +#include "string.h" +#include "tota_stream_data_transfer.h" +#include "stdio.h" +#include "stdarg.h" +#include "app_tota_flash_program.h" +#include "crc32.h" +#include "app_tota.h" + +uint8_t flash_wbuf[] = "hello"; + +static void tota_test_cmd(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + tota_printf("this is cmd test\r\n"); + tota_printf("hello1\r\n"); + tota_printf("hello2\r\n"); + tota_printf("hello3\r\n"); + tota_printf("hello4\r\n"); + tota_printf("will write data to flash"); + test_aes_encode_decode(); + tota_write_flash_test(TOTA_FLASH_TEST_ADDR, flash_wbuf, strlen((char*)flash_wbuf)); +} + +static void tota_echo_test_cmd(APP_TOTA_CMD_CODE_E funcCode, uint8_t* ptrParam, uint32_t paramLen) +{ + tota_printf("echo: \r\n"); + app_tota_send_data_via_spp(ptrParam, paramLen); +} + +TOTA_COMMAND_TO_ADD(OP_TOTA_ECHO_TEST_CMD, tota_echo_test_cmd, false, 0, NULL ); +TOTA_COMMAND_TO_ADD(OP_TOTA_TEST_CMD, tota_test_cmd, false, 0, NULL ); diff --git a/tests/anc_usb/Makefile b/tests/anc_usb/Makefile new file mode 100644 index 0000000..590b75b --- /dev/null +++ b/tests/anc_usb/Makefile @@ -0,0 +1,292 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +#obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := + +ifeq ($(ROM_BUILD),1) +obj-y += ../../tests/rom/startup_ARMCM.S +else +obj-y += ../../platform/main/startup_main.S +endif + +obj-y += main.c +ifeq ($(ANC_APP),1) +obj-y += anc_usb_app.c +endif +obj-y += usb_audio_app.c +obj-y += dualadc_audio_app.c +obj-y += adda_loop_app.c +obj-y += safe_queue.c +obj-y += memutils.c +ifeq ($(MIC_KEY),1) +obj-y += mic_key.c +endif +ifeq ($(VENDOR_MSG_SUPPT),1) +obj-y += usb_vendor_msg.c +endif + +obj-y += ../../services/audio_process/ +obj-y += ../../services/multimedia/ +obj-y += ../../services/nv_section/ +obj-y += ../../utils/crc32/ + +ifeq ($(USB_AUDIO_SPEECH),1) +obj-y += speech_process.c +obj-y += ../../apps/audioplayers/bt_sco_chain.c +obj-y += ../../apps/audioplayers/bt_sco_chain_cfg_default.c +obj-y += ../../apps/audioplayers/bt_sco_chain_tuning.cpp +obj-y += ../../services/audio_dump/ +obj-y += ../../utils/heap/ + +ccflags-y += \ + -Iapps/audioplayers \ + -Iapps/common +endif + +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +ifeq ($(INTSRAM_RUN),1) +asflags-y += -DINTSRAM_RUN +ccflags-y += -DINTSRAM_RUN +endif + +ccflags-y += \ + -Iutils/boot_struct \ + -Iutils/crc32 \ + -Iutils/heap \ + -Iutils/hexdump \ + -Iutils/hwtimer_list \ + -Iplatform/drivers/usb/usb_dev/inc \ + -Iplatform/drivers/ana \ + -Iservices/multimedia/audio/process/adp/include \ + -Iservices/multimedia/audio/process/anc/include \ + -Iservices/multimedia/audio/process/filters/include \ + -Iservices/multimedia/audio/process/resample/include \ + -Iservices/audio_dump/include \ + -Iservices/multimedia/speech/inc \ + -Iservices/audio_process \ + -Iservices/nv_section/aud_section \ + -Iservices/nv_section/include + +CFLAGS_usb_audio_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) +CFLAGS_adda_loop_app.o += -DAUDIO_OUTPUT_VOLUME_DEFAULT=$(AUDIO_OUTPUT_VOLUME_DEFAULT) + +ifneq ($(DEBUG_PORT),) +CFLAGS_main.o += -DDEBUG_PORT=$(DEBUG_PORT) +endif + +ifeq ($(USB_AUDIO_SPEECH),1) +CFLAGS_main.o += -DUSB_AUDIO_SPEECH +endif + +ANC_USB_CFG_FLAGS := + +# ANC option +ifeq ($(ANC_APP),1) +ANC_USB_CFG_FLAGS += -DANC_APP +endif + +# USB audio option +ifeq ($(USB_AUDIO_APP),1) +ANC_USB_CFG_FLAGS += -DUSB_AUDIO_APP +endif + +ifeq ($(USB_I2S_APP),1) +ANC_USB_CFG_FLAGS += -DUSB_I2S_APP +ifneq ($(USB_I2S_ID),) +ANC_USB_CFG_FLAGS += -DUSB_I2S_ID=$(USB_I2S_ID) +endif +endif + +ifeq ($(USB_HIGH_SPEED),1) +ANC_USB_CFG_FLAGS += -DUSB_HIGH_SPEED +endif + +ifeq ($(AUDIO_RESAMPLE),1) +ANC_USB_CFG_FLAGS += -D__AUDIO_RESAMPLE__ +endif + +ifeq ($(ADC_CH_SEP_BUFF),1) +ANC_USB_CFG_FLAGS += -DADC_CH_SEP_BUFF +endif + +include platform/drivers/usb/usb_dev/uaud_cfg_flags.mk + +platform/drivers/usb/usb_dev/uaud_cfg_flags.mk: ; + +ANC_USB_CFG_FLAGS += $(UAUD_CFG_FLAGS) + +# USB audio configuration +ifeq ($(USB_AUDIO_DYN_CFG),1) +ifneq ($(USB_AUDIO_RECV_ENABLE),0) +ifneq ($(AUDIO_RESAMPLE),1) +SW_CAPTURE_RESAMPLE ?= 1 +endif +endif +endif + +ifeq ($(AUDIO_PLAYBACK_24BIT),1) +ANC_USB_CFG_FLAGS += -DAUDIO_PLAYBACK_24BIT +endif + +# DSD configuration +ifeq ($(HW_FIR_DSD_PROCESS),1) +ifeq ($(HW_FIR_DSD_BUF_MID_ADDR),) +$(error HW_FIR_DSD_BUF_MID_ADDR must be defined with HW_FIR_DSD_PROCESS) +endif +ANC_USB_CFG_FLAGS += -D__HW_FIR_DSD_PROCESS__ -DHW_FIR_DSD_BUF_MID_ADDR=$(HW_FIR_DSD_BUF_MID_ADDR) +endif + +ifeq ($(CODEC_DSD),1) +ANC_USB_CFG_FLAGS += -DCODEC_DSD +endif + +# EQ configuration +ifeq ($(HW_FIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__HW_FIR_EQ_PROCESS__ +endif + +ifeq ($(HW_IIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__HW_IIR_EQ_PROCESS__ +endif + +ifeq ($(SW_IIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__SW_IIR_EQ_PROCESS__ +endif + +ifeq ($(HW_DAC_IIR_EQ_PROCESS),1) +ANC_USB_CFG_FLAGS += -D__HW_DAC_IIR_EQ_PROCESS__ +endif + +ifeq ($(AUDIO_RESAMPLE),1) +ifeq ($(SW_PLAYBACK_RESAMPLE),1) +ANC_USB_CFG_FLAGS += -DSW_PLAYBACK_RESAMPLE +endif +endif + +ifeq ($(SW_CAPTURE_RESAMPLE),1) +ANC_USB_CFG_FLAGS += -DSW_CAPTURE_RESAMPLE +endif + +CFLAGS_main.o += $(ANC_USB_CFG_FLAGS) +CFLAGS_usb_audio_app.o += $(ANC_USB_CFG_FLAGS) +CFLAGS_anc_usb_app.o += $(ANC_USB_CFG_FLAGS) + +ifeq ($(ANC_KEY_DOUBLE_CLICK_ON_OFF),1) +CFLAGS_anc_usb_app.o += -DANC_KEY_DOUBLE_CLICK_ON_OFF +endif + +ifeq ($(ANC_FF_ENABLED),1) +CFLAGS_anc_usb_app.o += -DANC_FF_ENABLED +endif + +ifeq ($(ANC_FB_ENABLED),1) +CFLAGS_anc_usb_app.o += -DANC_FB_ENABLED +endif + +ifeq ($(AUDIO_SECTION_SUPPT),1) +CFLAGS_anc_usb_app.o += -D__AUDIO_SECTION_SUPPT__ +endif + +ifeq ($(ANC_INIT_OFF),1) +CFLAGS_anc_usb_app.o += -DANC_INIT_OFF +endif + +ifeq ($(ADDA_LOOP_APP),1) +CFLAGS_main.o += -DADDA_LOOP_APP +endif + +ifeq ($(PC_CMD_UART),1) +CFLAGS_main.o += -D__PC_CMD_UART__ +endif + +ifeq ($(JTAG_ENABLE),1) +CFLAGS_main.o += -DJTAG_ENABLE +endif + +ifeq ($(DEBUG_MODE_USB_DOWNLOAD),1) +CFLAGS_main.o += -DDEBUG_MODE_USB_DOWNLOAD +endif + +ifeq ($(DELAY_STREAM_OPEN),1) +CFLAGS_usb_audio_app.o += -DDELAY_STREAM_OPEN +endif + +ifeq ($(NOISE_GATING),1) +CFLAGS_usb_audio_app.o += -DNOISE_GATING +endif + +ifeq ($(NOISE_REDUCTION),1) +CFLAGS_usb_audio_app.o += -DNOISE_REDUCTION +endif + +ifeq ($(ANC_L_R_MISALIGN_WORKAROUND),1) +CFLAGS_usb_audio_app.o += -DANC_L_R_MISALIGN_WORKAROUND +endif + +ifeq ($(ANDROID_ACCESSORY_SPEC),1) +CFLAGS_usb_audio_app.o += -DANDROID_ACCESSORY_SPEC +ifeq ($(ANDROID_VOICE_CMD_KEY),1) +CFLAGS_usb_audio_app.o += -DANDROID_VOICE_CMD_KEY +endif +endif + +ifeq ($(DUAL_AUX_MIC_MORE_FILTER),1) +CFLAGS_usb_audio_app.o += -DDUAL_AUX_MIC_MORE_FILTER +endif + +ifeq ($(FREQ_RESP_EQ),1) +CFLAGS_usb_audio_app.o += -DFREQ_RESP_EQ +endif + +ifeq ($(KEEP_SAME_LATENCY),1) +CFLAGS_usb_audio_app.o += -DKEEP_SAME_LATENCY +CFLAGS_speech_process.o += -DKEEP_SAME_LATENCY +endif + +ifeq ($(USB_AUDIO_PWRKEY_TEST),1) +CFLAGS_usb_audio_app.o += -DUSB_AUDIO_PWRKEY_TEST +endif + +ifeq ($(AUDIO_RESAMPLE),1) +# If neither best1000 nor best2000 +ifeq ($(filter best1000 best2000,$(CHIP)),) +PLL_TUNE_SAMPLE_RATE ?= 1 +endif +ifeq ($(PLL_TUNE_SAMPLE_RATE),1) +CFLAGS_usb_audio_app.o += -DPLL_TUNE_SAMPLE_RATE +endif +ifeq ($(PLL_TUNE_XTAL),1) +CFLAGS_usb_audio_app.o += -DPLL_TUNE_XTAL +endif +endif + +ifeq ($(TARGET_TO_MAX_DIFF),1) +CFLAGS_usb_audio_app.o += -DTARGET_TO_MAX_DIFF +endif + +ifneq ($(USB_AUDIO_RECV_ENABLE),0) +CFLAGS_usb_audio_app.o += -DUSB_AUDIO_RECV_ENABLE +endif +ifneq ($(USB_AUDIO_SEND_ENABLE),0) +CFLAGS_usb_audio_app.o += -DUSB_AUDIO_SEND_ENABLE +endif + +ifeq ($(USB_EQ_TUNING), 1) +CFLAGS_main.o += -DUSB_EQ_TUNING +CFLAGS_usb_vendor_msg.o += -DUSB_EQ_TUNING +endif + +ifeq ($(VENDOR_MSG_SUPPT), 1) +CFLAGS_main.o += -D_VENDOR_MSG_SUPPT_ +CFLAGS_usb_vendor_msg.o += -D_VENDOR_MSG_SUPPT_ +CFLAGS_usb_audio_app.o += -D_VENDOR_MSG_SUPPT_ +endif + +ifeq ($(CHIP_HAS_DCO), 1) +CFLAGS_main.o += -DCHIP_HAS_DCO +CFLAGS_usb_vendor_msg.o += -DCHIP_HAS_DCO +CFLAGS_usb_audio_app.o += -DCHIP_HAS_DCO +endif \ No newline at end of file diff --git a/tests/anc_usb/adda_loop_app.c b/tests/anc_usb/adda_loop_app.c new file mode 100644 index 0000000..066576b --- /dev/null +++ b/tests/anc_usb/adda_loop_app.c @@ -0,0 +1,211 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_sysfreq.h" +#include "hal_aud.h" +#include "tgt_hardware.h" +#include "string.h" +#include "audioflinger.h" +#include "adda_loop_app.h" + +#define ADDA_SAMPLE_RATE 48000 +#define ADDA_SAMPLE_SIZE 2 + +#define ADDA_PLAYBACK_CHAN 2 +#define ADDA_CAPTURE_CHAN 2 + +#define RATE_TO_SIZE(n) (((n) + (1000 - 1)) / 1000) + +#define ADDA_PLAYBACK_FRAME_SIZE (RATE_TO_SIZE(ADDA_SAMPLE_RATE) * ADDA_SAMPLE_SIZE * ADDA_PLAYBACK_CHAN) +#define ADDA_CAPTURE_FRAME_SIZE (RATE_TO_SIZE(ADDA_SAMPLE_RATE) * ADDA_SAMPLE_SIZE * ADDA_CAPTURE_CHAN) + +#define PLAYBACK_FRAME_NUM 4 +#define CAPTURE_FRAME_NUM 8 + +#define ADDA_NON_EXP_ALIGN(val, exp) (((val) + ((exp) - 1)) / (exp) * (exp)) +#define BUFF_ALIGN (4 * 4) + +#define PLAYBACK_SIZE ADDA_NON_EXP_ALIGN(ADDA_PLAYBACK_FRAME_SIZE * PLAYBACK_FRAME_NUM, BUFF_ALIGN) +#define CAPTURE_SIZE ADDA_NON_EXP_ALIGN(ADDA_CAPTURE_FRAME_SIZE * CAPTURE_FRAME_NUM, BUFF_ALIGN) + +#define ALIGNED4 ALIGNED(4) + +static uint8_t ALIGNED4 adda_playback_buf[PLAYBACK_SIZE]; +static uint8_t ALIGNED4 adda_capture_buf[CAPTURE_SIZE]; + +static uint32_t cap_rpos; +static uint32_t cap_wpos; + +static enum AUD_BITS_T sample_size_to_enum(uint32_t size) +{ + if (size == 2) { + return AUD_BITS_16; + } else if (size == 4) { + return AUD_BITS_24; + } else { + ASSERT(false, "%s: Invalid sample size: %u", __FUNCTION__, size); + } + + return 0; +} + +static enum AUD_CHANNEL_NUM_T chan_num_to_enum(uint32_t num) +{ + if (num == 2) { + return AUD_CHANNEL_NUM_2; + } else if (num == 1) { + return AUD_CHANNEL_NUM_1; + } else { + ASSERT(false, "%s: Invalid channel num: %u", __FUNCTION__, num); + } + + return 0; +} + +static uint32_t adda_data_playback(uint8_t *buf, uint32_t len) +{ + uint32_t cur_time; + int16_t *src; + int16_t *dst; + int16_t *src_end; + int16_t *dst_end; + uint32_t avail; + + cur_time = hal_sys_timer_get(); + + if (cap_wpos >= cap_rpos) { + avail = cap_wpos - cap_rpos; + } else { + avail = sizeof(adda_capture_buf) + cap_wpos - cap_rpos; + } + + if (avail * ADDA_PLAYBACK_CHAN / ADDA_CAPTURE_CHAN >= len) { + src = (int16_t *)(adda_capture_buf + cap_rpos); + src_end = (int16_t *)(adda_capture_buf + sizeof(adda_capture_buf)); + dst = (int16_t *)buf; + dst_end = (int16_t *)(buf + len); + + while (dst < dst_end) { + *dst++ = *src++; + if (src == src_end) { + src = (int16_t *)adda_capture_buf; + } +#if (ADDA_PLAYBACK_CHAN == 2) && (ADDA_CAPTURE_CHAN == 1) + *dst = *(dst - 1); + dst++; +#endif + } + + cap_rpos = (uint32_t)src - (uint32_t)adda_capture_buf; + } else { + memset(buf, 0, len); + } + + TRACE(5,"[%X] playback: len=%4u wpos=%4u rpos=%4u avail=%4u", cur_time, len, cap_wpos, cap_rpos, avail); + return 0; +} + +static uint32_t adda_data_capture(uint8_t *buf, uint32_t len) +{ + uint32_t cur_time; + + cur_time = hal_sys_timer_get(); + + cap_wpos += len; + if (cap_wpos >= sizeof(adda_capture_buf)) { + cap_wpos = 0; + } + + TRACE(4,"[%X] capture : len=%4u wpos=%4u rpos=%4u", cur_time, len, cap_wpos, cap_rpos); + return 0; +} + +static void adda_loop_start(void) +{ + int ret = 0; + struct AF_STREAM_CONFIG_T stream_cfg; + + hal_sysfreq_req(HAL_SYSFREQ_USER_APP_2, HAL_CMU_FREQ_52M); + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + stream_cfg.bits = sample_size_to_enum(ADDA_SAMPLE_SIZE); + stream_cfg.channel_num = chan_num_to_enum(ADDA_PLAYBACK_CHAN); + stream_cfg.sample_rate = ADDA_SAMPLE_RATE; + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.vol = AUDIO_OUTPUT_VOLUME_DEFAULT; + stream_cfg.handler = adda_data_playback; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.data_ptr = adda_playback_buf; + stream_cfg.data_size = sizeof(adda_playback_buf); + + TRACE(3,"[%s] playback sample_rate: %d, bits = %d", __func__, stream_cfg.sample_rate, stream_cfg.bits); + + ret = af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + ASSERT(ret == 0, "af_stream_open playback failed: %d", ret); + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + stream_cfg.bits = sample_size_to_enum(ADDA_SAMPLE_SIZE); + stream_cfg.channel_num = chan_num_to_enum(ADDA_CAPTURE_CHAN); + stream_cfg.sample_rate = ADDA_SAMPLE_RATE; + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.vol = CODEC_SADC_VOL; + stream_cfg.handler = adda_data_capture; + stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; + stream_cfg.data_ptr = adda_capture_buf; + stream_cfg.data_size = sizeof(adda_capture_buf); + + TRACE(3,"[%s] capture sample_rate: %d, bits = %d", __func__, stream_cfg.sample_rate, stream_cfg.bits); + + ret = af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + ASSERT(ret == 0, "af_stream_open catpure failed: %d", ret); + + ret = af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + ASSERT(ret == 0, "af_stream_start playback failed: %d", ret); + + ret = af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + ASSERT(ret == 0, "af_stream_start catpure failed: %d", ret); +} + +static void adda_loop_stop(void) +{ + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + + hal_sysfreq_req(HAL_SYSFREQ_USER_APP_2, HAL_CMU_FREQ_32K); +} + +void adda_loop_app(bool on) +{ + if (on) { + adda_loop_start(); + } else { + adda_loop_stop(); + } +} + +void adda_loop_app_loop(void) +{ +#ifndef RTOS + extern void af_thread(void const *argument); + af_thread(NULL); +#endif +} + diff --git a/tests/anc_usb/adda_loop_app.h b/tests/anc_usb/adda_loop_app.h new file mode 100644 index 0000000..057868d --- /dev/null +++ b/tests/anc_usb/adda_loop_app.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ADDA_LOOP_APP_H__ +#define __ADDA_LOOP_APP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +void adda_loop_app(bool on); + +void adda_loop_app_loop(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tests/anc_usb/anc_usb_app.c b/tests/anc_usb/anc_usb_app.c new file mode 100644 index 0000000..ce2b696 --- /dev/null +++ b/tests/anc_usb/anc_usb_app.c @@ -0,0 +1,1057 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "anc_process.h" +#include "anc_usb_app.h" +#include "audioflinger.h" +#include "cmsis.h" +#include "hal_codec.h" +#include "hal_key.h" +#include "hal_sleep.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hwtimer_list.h" +#include "pmu.h" +#include "usb_audio_app.h" +#include "tgt_hardware.h" + +#ifdef ANC_SWITCH_GPADC_CHAN +#include "hal_gpadc.h" +#endif + +#define ANC_KEY_CPU_WAKE_USER HAL_CPU_WAKE_LOCK_USER_4 +#define ANC_STATE_CPU_WAKE_USER HAL_CPU_WAKE_LOCK_USER_5 + +#define ANC_FADE_IN_OUT +#define ANC_FADE_GAIN_STEP 1 +#define ANC_MODE_SWITCH_WITHOUT_FADE + +#ifndef ANC_INIT_ON_TIMEOUT_MS +#ifdef CHIP_BEST1000 +#define ANC_INIT_ON_TIMEOUT_MS 1200 +#else +#define ANC_INIT_ON_TIMEOUT_MS 200 +#endif +#endif +#ifndef ANC_SHUTDOWN_TIMEOUT_MS +#define ANC_SHUTDOWN_TIMEOUT_MS 5000 +#endif + +#ifndef ANC_SWITCH_CHECK_INTERVAL +#define ANC_SWITCH_CHECK_INTERVAL MS_TO_TICKS(500) +#endif + +#ifdef ANC_COEF_NUM +#if (ANC_COEF_NUM < 1) +#error "Invalid ANC_COEF_NUM configuration" +#endif +#else +#define ANC_COEF_NUM (1) +#endif + +#define KEY_PROCESS_TIMER_INTERVAL (MS_TO_TICKS(1) / 2) +#define FADE_TIMER_INTERVAL (MS_TO_TICKS(1) / 2) + +enum ANC_STATUS_T { + ANC_STATUS_NULL = 0, + ANC_STATUS_INIT, + ANC_STATUS_FADEIN, + ANC_STATUS_ENABLE, + ANC_STATUS_FADEOUT, + ANC_STATUS_DISABLE, + ANC_STATUS_INIT_CLOSE, +}; + +enum ANC_KEY_STATE_T { + ANC_KEY_STATE_NULL = 0, + ANC_KEY_STATE_CLOSE, + ANC_KEY_STATE_OPEN, + ANC_KEY_STATE_DEBOUNCE, +}; + +enum ANC_CTRL_SM_T { + ANC_CTRL_SM_OFF = 0, + ANC_CTRL_SM_COEF_0, + ANC_CTRL_SM_COEF_N = ANC_CTRL_SM_COEF_0 + ANC_COEF_NUM - 1, + + ANC_CTRL_SM_QTY +}; + +static enum ANC_STATUS_T anc_status = ANC_STATUS_NULL; +static enum ANC_KEY_STATE_T prev_key_state = ANC_KEY_STATE_NULL; +static enum HAL_KEY_EVENT_T anc_key_event = HAL_KEY_EVENT_NONE; +static enum ANC_CTRL_SM_T anc_ctrl_sm = ANC_CTRL_SM_OFF; +#ifdef ANC_TALK_THROUGH +static bool talk_through = false; +#endif + +static uint32_t anc_init_time; +static uint32_t anc_close_time; + +static enum ANC_INDEX cur_coef_index = ANC_INDEX_0; + +static enum AUD_SAMPRATE_T anc_sample_rate[AUD_STREAM_NUM]; + +static bool anc_running = false; + +#ifdef ANC_SWITCH_GPIO_PIN +static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_anc = {ANC_SWITCH_GPIO_PIN, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_PULLUP_ENABLE}; +static bool gpio_pending; +static bool gpio_irq_en; +static enum HAL_GPIO_IRQ_POLARITY_T gpio_irq_polarity; +#endif + +// ANC_SWITCH_GPADC_CHAN +static HWTIMER_ID gpadc_timer; + +// ANC_FADE_IN_OUT +static uint8_t fadein_cnt = 0; +static uint8_t fadeout_cnt = 0; +static uint32_t prev_fade_time = 0; + +#ifdef CFG_HW_ANC_LED_PIN +const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_anc_led[] = { + {CFG_HW_ANC_LED_PIN, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL}, +}; +#endif +#ifdef CFG_HW_ANC_LED_PIN2 +const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_anc_led2[] = { + {CFG_HW_ANC_LED_PIN2, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL}, +}; +#endif + +static void anc_full_open(void); +static void anc_full_close(void); + +// ANC_FADE_IN_OUT +int anc_usb_app_fadein(enum ANC_TYPE_T anc_type) +{ + + + int32_t gain0_curr, gain1_curr; + int32_t gain0_tg, gain1_tg; + + anc_get_gain(&gain0_curr, &gain1_curr,anc_type); + anc_get_cfg_gain(&gain0_tg, &gain1_tg,anc_type); + +/* + anc_set_gain(gain0_tg, gain1_tg,anc_type); + + return 0; +*/ + if (gain0_tg > 0) { + if (gain0_curr < gain0_tg) { + if (gain0_curr + ANC_FADE_GAIN_STEP < gain0_tg) { + gain0_curr += ANC_FADE_GAIN_STEP; + } else { + gain0_curr = gain0_tg; + } + } + } else { + if (gain0_curr > gain0_tg) { + if (gain0_curr - ANC_FADE_GAIN_STEP > gain0_tg) { + gain0_curr -= ANC_FADE_GAIN_STEP; + } else { + gain0_curr = gain0_tg; + } + } + } + + if (gain1_tg > 0) { + if (gain1_curr < gain1_tg) { + if (gain1_curr + ANC_FADE_GAIN_STEP < gain1_tg) { + gain1_curr += ANC_FADE_GAIN_STEP; + } else { + gain1_curr = gain1_tg; + } + } + } else { + if (gain1_curr > gain1_tg) { + if (gain1_curr - ANC_FADE_GAIN_STEP > gain1_tg) { + gain1_curr -= ANC_FADE_GAIN_STEP; + } else { + gain1_curr = gain1_tg; + } + } + } + + //TRACE(3,"[%s] cur gain: %d %d", __func__, gain0_curr, gain1_curr); + anc_set_gain(gain0_curr, gain1_curr,anc_type); + + if ((gain0_curr == gain0_tg) && (gain1_curr == gain1_tg)) { + return 0; + } + + return 1; +} + +int anc_usb_app_fadeout(enum ANC_TYPE_T anc_type) +{ + +/* + anc_set_gain(0, 0,anc_type); + + return 0; +*/ + + int32_t gain0_curr, gain1_curr; + + anc_get_gain(&gain0_curr, &gain1_curr,anc_type); + + if (gain0_curr > 0) { + if (gain0_curr > ANC_FADE_GAIN_STEP) { + gain0_curr -= ANC_FADE_GAIN_STEP; + } else { + gain0_curr = 0; + } + } else if (gain0_curr < 0) { + if (gain0_curr < -ANC_FADE_GAIN_STEP) { + gain0_curr += ANC_FADE_GAIN_STEP; + } else { + gain0_curr = 0; + } + } + + if (gain1_curr > 0) { + if (gain1_curr > ANC_FADE_GAIN_STEP) { + gain1_curr -= ANC_FADE_GAIN_STEP; + } else { + gain1_curr = 0; + } + } else if (gain1_curr < 0) { + if (gain1_curr < -ANC_FADE_GAIN_STEP) { + gain1_curr += ANC_FADE_GAIN_STEP; + } else { + gain1_curr = 0; + } + } + + // TRACE(3,"[%s] gain: %d, %d", __func__, gain0_curr, gain1_curr); + anc_set_gain(gain0_curr, gain1_curr,anc_type); + + if ((gain0_curr == 0) && (gain1_curr == 0)) { + return 0; + } + + return 1; +} + +void anc_usb_app(bool on) +{ + TRACE(2,"%s: on=%d", __func__, on); + + if (anc_running==on) + return; + else + anc_running=on; + + if (on) { + anc_enable(); + } else { + anc_disable(); + } + +#ifdef CFG_HW_ANC_LED_PIN + if (on) { + hal_gpio_pin_set(CFG_HW_ANC_LED_PIN); + } else { + hal_gpio_pin_clr(CFG_HW_ANC_LED_PIN); + } +#endif +#ifdef CFG_HW_ANC_LED_PIN2 + if (on) { + hal_gpio_pin_set(CFG_HW_ANC_LED_PIN2); + } else { + hal_gpio_pin_clr(CFG_HW_ANC_LED_PIN2); + } +#endif +} + +bool anc_usb_app_get_status() +{ + return anc_running; +} + +#ifdef ANC_SWITCH_GPIO_PIN +static void anc_key_gpio_handler(enum HAL_GPIO_PIN_T pin) +{ + struct HAL_GPIO_IRQ_CFG_T gpiocfg; + + gpiocfg.irq_enable = false; + hal_gpio_setup_irq((enum HAL_GPIO_PIN_T)pinmux_anc.pin, &gpiocfg); + + gpio_irq_en = false; + gpio_pending = true; + + hal_cpu_wake_lock(ANC_KEY_CPU_WAKE_USER); +} + +static void anc_key_gpio_irq_setup(enum HAL_GPIO_IRQ_POLARITY_T polarity) +{ + struct HAL_GPIO_IRQ_CFG_T gpiocfg; + + if (gpio_irq_en && gpio_irq_polarity == polarity) { + return; + } + + gpio_irq_polarity = polarity; + gpio_irq_en = true; + + gpiocfg.irq_enable = true; + gpiocfg.irq_debounce = true; + gpiocfg.irq_polarity = polarity; + gpiocfg.irq_handler = anc_key_gpio_handler; + gpiocfg.irq_type = HAL_GPIO_IRQ_TYPE_LEVEL_SENSITIVE; + + hal_gpio_setup_irq((enum HAL_GPIO_PIN_T)pinmux_anc.pin, &gpiocfg); +} +#endif + +static enum ANC_KEY_STATE_T anc_key_level_to_state(bool level) +{ + enum ANC_KEY_STATE_T key_state; + +#ifdef ANC_SWITCH_GPIO_PIN + anc_key_gpio_irq_setup(level ? HAL_GPIO_IRQ_POLARITY_LOW_FALLING : HAL_GPIO_IRQ_POLARITY_HIGH_RISING); +#endif + + key_state = level ? ANC_KEY_STATE_OPEN : ANC_KEY_STATE_CLOSE; + + return key_state; +} + +enum ANC_KEY_STATE_T anc_key_get_state(bool init_state) +{ + enum ANC_KEY_STATE_T key_state = ANC_KEY_STATE_NULL; + uint8_t level; + +#if defined(ANC_SWITCH_GPIO_PIN) + level = hal_gpio_pin_get_val((enum HAL_GPIO_PIN_T)pinmux_anc.pin); + + level = level ? true : false; + +#elif defined(ANC_SWITCH_GPADC_CHAN) + HAL_GPADC_MV_T volt = 0; + + if (hal_gpadc_get_volt(ANC_SWITCH_GPADC_CHAN, &volt)) { + level = volt > ANC_SWITCH_VOLTAGE_THRESHOLD ? ANC_SWITCH_LEVEL_HIGH : ANC_SWITCH_LEVEL_LOW; + // TRACE(3,"[%s] level = %d, volt = %d", __func__, level, volt); + } else { + // TRACE(1,"[%s] else...", __func__); + return ANC_KEY_STATE_NULL; + } +#else + return key_state; +#endif + + static uint32_t s_time; + static bool key_trigger = false; + static bool key_level = false; + + if (init_state) { + key_level = level; + return anc_key_level_to_state(level); + } + + if (key_trigger) { + if (key_level == level) { + key_trigger = false; + } else { + uint32_t diff_time_ms; + + diff_time_ms = TICKS_TO_MS(hal_sys_timer_get() - s_time); + + if(diff_time_ms >= 200) { + key_level = level; + key_trigger = false; + } + } + } else { + if (key_level != level) { + s_time = hal_sys_timer_get(); + key_trigger = true; + } + } + + if (key_trigger) { + key_state = ANC_KEY_STATE_DEBOUNCE; + } else { + key_state = anc_key_level_to_state(level); + } + + return key_state; +} + +static void anc_key_proc_open(bool from_key) +{ + int POSSIBLY_UNUSED ret; + uint32_t POSSIBLY_UNUSED time; + + time = hal_sys_timer_get(); + + if (anc_status == ANC_STATUS_INIT_CLOSE) { + TRACE(1,"[ANC KEY PROC] ANC INIT_CLOSE => INIT T:%u", time); + + anc_status = ANC_STATUS_INIT; + } else if (anc_status == ANC_STATUS_NULL) { + TRACE(1,"[ANC KEY PROC] ANC NULL => INIT T:%u", time); + + anc_full_open(); +#ifdef ANC_MODE_SWITCH_WITHOUT_FADE + } else if (anc_status == ANC_STATUS_ENABLE) { +#ifdef ANC_FF_ENABLED + ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],cur_coef_index,ANC_FEEDFORWARD,ANC_GAIN_NO_DELAY); + TRACE(2,"[ANC KEY PROC] updata coefs ff %d: ret=%d", cur_coef_index, ret); +#endif +#ifdef ANC_FB_ENABLED + ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],cur_coef_index,ANC_FEEDBACK,ANC_GAIN_NO_DELAY); + TRACE(2,"[ANC KEY PROC] updata coefs fb %d: ret=%d", cur_coef_index, ret); +#endif +#if defined(AUDIO_ANC_FB_MC_HW) + ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],cur_coef_index, ANC_MUSICCANCLE, ANC_GAIN_NO_DELAY); + TRACE(2,"[ANC KEY PROC] anc_select_coef mc %d: ret=%d", cur_coef_index, ret); +#endif +#if defined(AUDIO_ANC_TT_HW) + ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],cur_coef_index, ANC_TALKTHRU, ANC_GAIN_NO_DELAY); + TRACE(2,"[ANC KEY PROC] anc_select_coef tt %d: ret=%d", cur_coef_index, ret); +#endif + +#endif + }else{ + if (from_key && anc_status == ANC_STATUS_INIT) { + TRACE(1,"[ANC KEY PROC] ANC ON2 T:%u", time); + // Let state machine enable ANC + return; + } + + TRACE(1,"[ANC KEY PROC] ANC ON T:%u", time); + +#ifdef ANC_FF_ENABLED + ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],cur_coef_index,ANC_FEEDFORWARD,ANC_GAIN_DELAY); + TRACE(2,"[ANC KEY PROC] anc_select_coef ff %d: ret=%d", cur_coef_index, ret); +#endif +#ifdef ANC_FB_ENABLED + ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],cur_coef_index,ANC_FEEDBACK,ANC_GAIN_DELAY); + TRACE(2,"[ANC KEY PROC] anc_select_coef fb %d: ret=%d", cur_coef_index, ret); +#endif +#if defined(AUDIO_ANC_FB_MC_HW) + ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],cur_coef_index, ANC_MUSICCANCLE, ANC_GAIN_DELAY); + TRACE(2,"[ANC KEY PROC] anc_select_coef mc %d: ret=%d", cur_coef_index, ret); +#endif +#if defined(AUDIO_ANC_TT_HW) + ret = anc_select_coef(anc_sample_rate[AUD_STREAM_PLAYBACK],cur_coef_index, ANC_TALKTHRU, ANC_GAIN_DELAY); + TRACE(2,"[ANC KEY PROC] anc_select_coef tt %d: ret=%d", cur_coef_index, ret); +#endif + + anc_usb_app(true); +#ifdef ANC_FADE_IN_OUT + fadein_cnt = 0; + anc_status = ANC_STATUS_FADEIN; +#else + { + int32_t gain_ch_l, gain_ch_r; +#if defined(AUDIO_ANC_TT_HW) + anc_get_cfg_gain(&gain_ch_l, &gain_ch_r,ANC_TALKTHRU); + anc_set_gain(gain_ch_l,gain_ch_r,ANC_TALKTHRU); +#endif +#ifdef ANC_FF_ENABLED + anc_get_cfg_gain(&gain_ch_l, &gain_ch_r,ANC_FEEDFORWARD); + anc_set_gain(gain_ch_l,gain_ch_r,ANC_FEEDFORWARD); +#endif +#ifdef ANC_FB_ENABLED + anc_get_cfg_gain(&gain_ch_l, &gain_ch_r,ANC_FEEDBACK); + anc_set_gain(gain_ch_l,gain_ch_r,ANC_FEEDBACK); +#endif +#ifdef AUDIO_ANC_FB_MC_HW + anc_get_cfg_gain(&gain_ch_l, &gain_ch_r,ANC_MUSICCANCLE); + anc_set_gain(gain_ch_l,gain_ch_r,ANC_MUSICCANCLE); +#endif + } + anc_status = ANC_STATUS_ENABLE; +#endif + } +} + +static void anc_key_proc_close(bool from_key) +{ + uint32_t time; + + time = hal_sys_timer_get(); + anc_close_time = time; + + if (anc_status == ANC_STATUS_INIT) { + TRACE(1,"[ANC KEY PROC] ANC INIT => INIT_CLOSE T:%u", time); + + anc_status = ANC_STATUS_INIT_CLOSE; + } else if (anc_status == ANC_STATUS_INIT_CLOSE || anc_status == ANC_STATUS_DISABLE) { + if (from_key) { + TRACE(1,"[ANC KEY PROC] ANC OFF2 T:%u", time); + // Let state machine to shutdown ANC + return; + } + + TRACE(1,"[ANC KEY PROC] ANC CLOSE => NULL T:%u", time); + + anc_full_close(); + } else { + TRACE(1,"[ANC KEY PROC] ANC OFF T:%u", time); + +#ifdef ANC_FADE_IN_OUT + fadeout_cnt = 0; + anc_status = ANC_STATUS_FADEOUT; +#else + anc_usb_app(false); + anc_status = ANC_STATUS_DISABLE; +#endif + } +} + +void anc_switch_on_off_ctrl(void) +{ + uint32_t lock; + enum ANC_KEY_STATE_T key_state = ANC_KEY_STATE_NULL; + + lock = int_lock(); + // Check if there is a state change + if (anc_key_event != HAL_KEY_EVENT_NONE) { + key_state = prev_key_state; + anc_key_event = HAL_KEY_EVENT_NONE; + } + int_unlock(lock); + + if(key_state == ANC_KEY_STATE_OPEN) { + anc_key_proc_open(true); + } else if(key_state == ANC_KEY_STATE_CLOSE) { + anc_key_proc_close(true); + } +} + +void anc_double_click_on_off(void) +{ + uint32_t lock; + enum HAL_KEY_EVENT_T event; + + lock = int_lock(); + event = anc_key_event; + anc_key_event = HAL_KEY_EVENT_NONE; + hal_cpu_wake_unlock(ANC_KEY_CPU_WAKE_USER); + int_unlock(lock); + + if (event == HAL_KEY_EVENT_NONE) { + return; + } else if (event == HAL_KEY_EVENT_DOUBLECLICK) { + prev_key_state = (prev_key_state == ANC_KEY_STATE_OPEN) ? ANC_KEY_STATE_CLOSE : ANC_KEY_STATE_OPEN; + if (prev_key_state == ANC_KEY_STATE_OPEN) { + anc_key_proc_open(true); + } else { + anc_key_proc_close(true); + } + } +} + +void anc_click_on_off(void) +{ + enum ANC_STATE_UPDATE_T { + ANC_STATE_UPDATE_NULL = 0, + ANC_STATE_UPDATE_TALK_THROUGH, + ANC_STATE_UPDATE_COEF, + }; + + enum HAL_KEY_EVENT_T event; + enum ANC_STATE_UPDATE_T state_update = ANC_STATE_UPDATE_NULL; + uint8_t click_cnt = 0; + uint32_t lock; + + lock = int_lock(); + event = anc_key_event; + anc_key_event = HAL_KEY_EVENT_NONE; + hal_cpu_wake_unlock(ANC_KEY_CPU_WAKE_USER); + int_unlock(lock); + + if (event == HAL_KEY_EVENT_NONE) { + return; +#ifdef ANC_TALK_THROUGH + } else if (event == HAL_KEY_EVENT_LONGPRESS) { + talk_through = !talk_through; + if (talk_through) { + state_update = ANC_STATE_UPDATE_TALK_THROUGH; + cur_coef_index = ANC_COEF_NUM; + TRACE(0,"[ANC KEY PROC] anc_talk_through on"); + } else { + state_update = ANC_STATE_UPDATE_COEF; + TRACE(0,"[ANC KEY PROC] anc_talk_through off"); + } +#endif + } else if (event == HAL_KEY_EVENT_CLICK) { + click_cnt = 1; + } if (event == HAL_KEY_EVENT_DOUBLECLICK) { + click_cnt = 2; + } if (event == HAL_KEY_EVENT_TRIPLECLICK) { + click_cnt = 3; + } + + if (click_cnt > 0) { + anc_ctrl_sm = (anc_ctrl_sm + click_cnt) % ANC_CTRL_SM_QTY; + state_update = ANC_STATE_UPDATE_COEF; +#ifdef ANC_TALK_THROUGH + talk_through = false; +#endif + } + + if (state_update == ANC_STATE_UPDATE_COEF) { + if (anc_ctrl_sm >= ANC_CTRL_SM_COEF_0 && anc_ctrl_sm <= ANC_CTRL_SM_COEF_N) { + cur_coef_index = anc_ctrl_sm - ANC_CTRL_SM_COEF_0; + } + } + + if (state_update != ANC_STATE_UPDATE_NULL) { + if (anc_ctrl_sm == ANC_CTRL_SM_OFF && state_update != ANC_STATE_UPDATE_TALK_THROUGH) { + anc_key_proc_close(true); + } else { + anc_key_proc_open(true); + } + } +} + +static void anc_key_process(void) +{ +#if defined(ANC_SWITCH_GPIO_PIN) || defined(ANC_SWITCH_GPADC_CHAN) + + anc_switch_on_off_ctrl(); + +#elif defined(ANC_KEY_DOUBLE_CLICK_ON_OFF) + + anc_double_click_on_off(); + +#else + + anc_click_on_off(); + +#endif +} + +void anc_state_transition(void) +{ + uint32_t t_time; +#ifdef ANC_FADE_IN_OUT + int res_ff = 0, res_fb = 0; +#ifdef AUDIO_ANC_TT_HW + int res_tt = 0; +#endif +#ifdef AUDIO_ANC_FB_MC_HW + int res_mc = 0; +#endif +#endif + + t_time = hal_sys_timer_get(); + + if (anc_status == ANC_STATUS_INIT) { + if (t_time - anc_init_time >= MS_TO_TICKS(ANC_INIT_ON_TIMEOUT_MS)) { + //TRACE(2,"[%s] anc init on T:%u", __func__, t_time); + anc_key_proc_open(false); + // fadein or open + } + } + +#ifdef ANC_FADE_IN_OUT + if(anc_status == ANC_STATUS_FADEIN) + { + // process + if(fadein_cnt == 0) + { + TRACE(2,"[%s] anc fadein started T:%u", __func__, t_time); + prev_fade_time = t_time; + fadein_cnt++; + } + else if(fadein_cnt == 1) + { + // delay 60 ticks + if(t_time - prev_fade_time >= 60) + { + fadein_cnt++; + prev_fade_time = t_time; + } + } + else + { + // delay 1 ticks + if(t_time > prev_fade_time) + { + //TRACE(2,"[%s] anc_usb_app_fadein T:%u", __func__, t_time); +#ifdef AUDIO_ANC_TT_HW + res_tt = anc_usb_app_fadein(ANC_TALKTHRU); +#endif +#ifdef ANC_FF_ENABLED + res_ff = anc_usb_app_fadein(ANC_FEEDFORWARD); +#endif +#ifdef ANC_FB_ENABLED + res_fb = anc_usb_app_fadein(ANC_FEEDBACK); +#endif +#ifdef AUDIO_ANC_FB_MC_HW + res_mc = anc_usb_app_fadein(ANC_MUSICCANCLE); +#endif + if(res_ff==0&&res_fb==0 +#ifdef AUDIO_ANC_TT_HW + &&res_tt==0 +#endif +#ifdef AUDIO_ANC_FB_MC_HW + &&res_mc==0 +#endif + ) + { + anc_status = ANC_STATUS_ENABLE; + TRACE(2,"[%s] anc fadein done T:%u", __func__, t_time); + } + else + { + prev_fade_time = t_time; + } + } + } + } + else if(anc_status == ANC_STATUS_FADEOUT) + { + // process + if(fadeout_cnt == 0) + { + TRACE(2,"[%s] anc fadeout started T:%u", __func__, t_time); + prev_fade_time = t_time; + fadeout_cnt++; + } + else if(fadeout_cnt == 1) + { + // delay 1 ticks + if(t_time > prev_fade_time) + { + //TRACE(2,"[%s] anc_usb_app_fadeout T:%u", __func__, t_time); +#ifdef AUDIO_ANC_TT_HW + res_tt = anc_usb_app_fadeout(ANC_TALKTHRU); +#endif +#ifdef ANC_FF_ENABLED + res_ff = anc_usb_app_fadeout(ANC_FEEDFORWARD); +#endif +#ifdef ANC_FB_ENABLED + res_fb = anc_usb_app_fadeout(ANC_FEEDBACK); +#endif +#ifdef AUDIO_ANC_FB_MC_HW + res_mc = anc_usb_app_fadein(ANC_MUSICCANCLE); +#endif + if(res_ff==0&&res_fb==0 +#ifdef AUDIO_ANC_TT_HW + &&res_tt==0 +#endif +#ifdef AUDIO_ANC_FB_MC_HW + &&res_mc==0 +#endif + ) + { + fadeout_cnt++; + } + + prev_fade_time = t_time; + } + } + else + { + anc_usb_app(false); + anc_status = ANC_STATUS_DISABLE; + TRACE(2,"[%s] anc fadeout done T:%u", __func__, t_time); + } + } +#endif + + if (anc_status == ANC_STATUS_INIT_CLOSE || anc_status == ANC_STATUS_DISABLE) { + if(t_time - anc_close_time >= MS_TO_TICKS(ANC_SHUTDOWN_TIMEOUT_MS)) { + //TRACE(2,"[%s] anc shutdown T:%u", __func__, t_time); + anc_key_proc_close(false); + } + } + + if (anc_status == ANC_STATUS_NULL || anc_status == ANC_STATUS_ENABLE) { + hal_cpu_wake_unlock(ANC_STATE_CPU_WAKE_USER); + } else { + hal_cpu_wake_lock(ANC_STATE_CPU_WAKE_USER); + } +} + +int anc_usb_app_key(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event) +{ +#if !defined(ANC_SWITCH_GPIO_PIN) && !defined(ANC_SWITCH_GPADC_CHAN) + +#ifdef ANC_KEY_DOUBLE_CLICK_ON_OFF + + if (code == ANC_FUNCTION_KEY) { + if (event == HAL_KEY_EVENT_DOUBLECLICK) { + anc_key_event = event; + hal_cpu_wake_lock(ANC_KEY_CPU_WAKE_USER); + // The key event has been processed + return 0; + } + } + +#else + + if (code == ANC_FUNCTION_KEY) { + if (event == HAL_KEY_EVENT_CLICK || event == HAL_KEY_EVENT_DOUBLECLICK || + event == HAL_KEY_EVENT_TRIPLECLICK || event == HAL_KEY_EVENT_LONGPRESS) { + anc_key_event = event; + hal_cpu_wake_lock(ANC_KEY_CPU_WAKE_USER); + } + // The key event has been processed + return 0; + } + +#endif + +#endif + + // Let other applications check the key event + return 1; +} + +void anc_key_check(void) +{ + enum ANC_KEY_STATE_T key_state; + +#ifdef ANC_SWITCH_GPIO_PIN + uint32_t lock; + + gpio_pending = false; +#endif + + key_state = anc_key_get_state(false); + + if (key_state == ANC_KEY_STATE_NULL) { + return; + } else if (key_state == ANC_KEY_STATE_DEBOUNCE) { + hal_cpu_wake_lock(ANC_KEY_CPU_WAKE_USER); + } else if (key_state != prev_key_state) { + prev_key_state = key_state; + // Reuse click event to tag a state change + anc_key_event = HAL_KEY_EVENT_CLICK; + hal_cpu_wake_lock(ANC_KEY_CPU_WAKE_USER); + } else if (anc_key_event == HAL_KEY_EVENT_NONE) { +#ifdef ANC_SWITCH_GPIO_PIN + lock = int_lock(); + if (!gpio_pending) { + hal_cpu_wake_unlock(ANC_KEY_CPU_WAKE_USER); + } + int_unlock(lock); +#else + hal_cpu_wake_unlock(ANC_KEY_CPU_WAKE_USER); +#endif + } +} + +void anc_key_gpadc_timer_handler(void *param) +{ + hwtimer_start(gpadc_timer, ANC_SWITCH_CHECK_INTERVAL); +} + +static void anc_key_init(void) +{ +#if defined(ANC_SWITCH_GPIO_PIN) + hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&pinmux_anc, 1); + hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)pinmux_anc.pin, HAL_GPIO_DIR_IN, 0); + // Make sure gpio value is ready + hal_sys_timer_delay(3); +#elif defined(ANC_SWITCH_GPADC_CHAN) + hal_gpadc_open(ANC_SWITCH_GPADC_CHAN, HAL_GPADC_ATP_20MS, NULL); + // Make sure gpadc channel data is ready + hal_sys_timer_delay(6); + gpadc_timer = hwtimer_alloc(anc_key_gpadc_timer_handler, NULL); + ASSERT(gpadc_timer, "Failed to alloc gpadc timer"); + hwtimer_start(gpadc_timer, ANC_SWITCH_CHECK_INTERVAL); +#endif + + // Add other key initialize +} + +#if defined(USB_AUDIO_DYN_CFG) && !defined(__AUDIO_RESAMPLE__) +static void anc_sample_rate_change(enum AUD_STREAM_T stream, enum AUD_SAMPRATE_T rate, enum AUD_SAMPRATE_T *new_play, enum AUD_SAMPRATE_T *new_cap) +{ + enum AUD_SAMPRATE_T play_rate, cap_rate; + + if (anc_sample_rate[stream] != rate) { +#ifdef CHIP_BEST1000 + if (stream == AUD_STREAM_PLAYBACK) { + play_rate = rate; + cap_rate = rate * (anc_sample_rate[AUD_STREAM_CAPTURE] / anc_sample_rate[AUD_STREAM_PLAYBACK]); + } else { + play_rate = rate / (anc_sample_rate[AUD_STREAM_CAPTURE] / anc_sample_rate[AUD_STREAM_PLAYBACK]); + cap_rate = rate; + } +#else + play_rate = rate; + cap_rate = rate; +#ifdef ANC_FF_ENABLED + anc_select_coef(play_rate,cur_coef_index, ANC_FEEDFORWARD, ANC_GAIN_NO_DELAY); +#endif + +#ifdef ANC_FB_ENABLED + anc_select_coef(play_rate,cur_coef_index, ANC_FEEDBACK, ANC_GAIN_NO_DELAY); +#endif + +#if defined(AUDIO_ANC_FB_MC_HW) + anc_select_coef(play_rate,cur_coef_index, ANC_MUSICCANCLE, ANC_GAIN_NO_DELAY); +#endif + +#if defined(AUDIO_ANC_TT_HW) + anc_select_coef(play_rate,cur_coef_index, ANC_TALKTHRU, ANC_GAIN_NO_DELAY); +#endif + +#endif + + TRACE(5,"%s: Update anc sample rate from %u/%u to %u/%u", __func__, + anc_sample_rate[AUD_STREAM_PLAYBACK], anc_sample_rate[AUD_STREAM_CAPTURE], play_rate, cap_rate); + + if (new_play) { + *new_play= play_rate; + } + if (new_cap) { + *new_cap = cap_rate; + } + + anc_sample_rate[AUD_STREAM_PLAYBACK] = play_rate; + anc_sample_rate[AUD_STREAM_CAPTURE] = cap_rate; + } +} +#endif + +static void anc_full_open(void) +{ + AF_ANC_HANDLER POSSIBLY_UNUSED handler; + +#if defined(USB_AUDIO_DYN_CFG) && !defined(__AUDIO_RESAMPLE__) + handler = anc_sample_rate_change; +#else + handler = NULL; +#endif + +#ifdef USB_AUDIO_APP + usb_audio_keep_streams_running(true); +#endif + + pmu_anc_config(1); + +#ifdef ANC_FF_ENABLED + af_anc_open(ANC_FEEDFORWARD, anc_sample_rate[AUD_STREAM_PLAYBACK], anc_sample_rate[AUD_STREAM_CAPTURE], handler); + anc_open(ANC_FEEDFORWARD); +#endif + +#ifdef ANC_FB_ENABLED + af_anc_open(ANC_FEEDBACK, anc_sample_rate[AUD_STREAM_PLAYBACK], anc_sample_rate[AUD_STREAM_CAPTURE], handler); + anc_open(ANC_FEEDBACK); +#if defined(AUDIO_ANC_FB_MC_HW) + anc_open(ANC_MUSICCANCLE); +#endif +#endif + +#if defined(AUDIO_ANC_TT_HW) + anc_open(ANC_TALKTHRU); +#endif + + + anc_init_time = hal_sys_timer_get(); + anc_status = ANC_STATUS_INIT; +} + +static void anc_full_close(void) +{ + +#if defined(AUDIO_ANC_TT_HW) + anc_close(ANC_TALKTHRU); +#endif + +#ifdef ANC_FF_ENABLED + anc_close(ANC_FEEDFORWARD); + af_anc_close(ANC_FEEDFORWARD); +#endif + +#ifdef ANC_FB_ENABLED +#if defined(AUDIO_ANC_FB_MC_HW) + anc_close(ANC_MUSICCANCLE); +#endif + anc_close(ANC_FEEDBACK); + af_anc_close(ANC_FEEDBACK); +#endif + + pmu_anc_config(0); + + anc_status = ANC_STATUS_NULL; + +#ifdef USB_AUDIO_APP + usb_audio_keep_streams_running(false); +#endif +} + +void anc_usb_app_loop(void) +{ +#if defined(ANC_SWITCH_GPIO_PIN) || defined(ANC_SWITCH_GPADC_CHAN) + anc_key_check(); +#endif + anc_key_process(); + anc_state_transition(); +} + +void anc_usb_app_init(enum AUD_IO_PATH_T input_path, enum AUD_SAMPRATE_T playback_rate, enum AUD_SAMPRATE_T capture_rate) +{ + enum ANC_KEY_STATE_T key_state; + +#ifdef CFG_HW_ANC_LED_PIN + hal_iomux_init(pinmux_anc_led, ARRAY_SIZE(pinmux_anc_led)); + hal_gpio_pin_set_dir(CFG_HW_ANC_LED_PIN, HAL_GPIO_DIR_OUT, 0); +#endif +#ifdef CFG_HW_ANC_LED_PIN2 + hal_iomux_init(pinmux_anc_led2, ARRAY_SIZE(pinmux_anc_led2)); + hal_gpio_pin_set_dir(CFG_HW_ANC_LED_PIN2, HAL_GPIO_DIR_OUT, 0); +#endif + + anc_key_init(); + +#ifdef __AUDIO_SECTION_SUPPT__ + anc_load_cfg(); +#endif + + anc_sample_rate[AUD_STREAM_PLAYBACK] = hal_codec_anc_convert_rate(playback_rate); + anc_sample_rate[AUD_STREAM_CAPTURE] = hal_codec_anc_convert_rate(capture_rate); + +#if defined(ANC_SWITCH_GPIO_PIN) || defined(ANC_SWITCH_GPADC_CHAN) + key_state = anc_key_get_state(true); + prev_key_state = key_state; +#elif defined(ANC_KEY_DOUBLE_CLICK_ON_OFF) + key_state = ANC_KEY_STATE_OPEN; + prev_key_state = key_state; +#else + key_state = ANC_KEY_STATE_OPEN; + anc_ctrl_sm = ANC_CTRL_SM_COEF_0 + cur_coef_index; +#endif + +#ifdef ANC_INIT_OFF + key_state = ANC_KEY_STATE_CLOSE; + prev_key_state = key_state; + anc_ctrl_sm = ANC_CTRL_SM_OFF; +#endif + + if (key_state == ANC_KEY_STATE_OPEN) { + anc_full_open(); + } +} + +void anc_usb_app_term(void) +{ + anc_full_close(); +} + diff --git a/tests/anc_usb/anc_usb_app.h b/tests/anc_usb/anc_usb_app.h new file mode 100644 index 0000000..5d00204 --- /dev/null +++ b/tests/anc_usb/anc_usb_app.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __ANC_USB_APP_H__ +#define __ANC_USB_APP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_aud.h" +#include "hal_key.h" + +void anc_usb_app(bool on); + +bool anc_usb_app_get_status(); + +void anc_usb_app_init(enum AUD_IO_PATH_T input_path, enum AUD_SAMPRATE_T playback_rate, enum AUD_SAMPRATE_T capture_rate); + +void anc_usb_app_term(void); + +void anc_usb_app_loop(void); + +int anc_usb_app_key(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/tests/anc_usb/dualadc_audio_app.c b/tests/anc_usb/dualadc_audio_app.c new file mode 100644 index 0000000..724552f --- /dev/null +++ b/tests/anc_usb/dualadc_audio_app.c @@ -0,0 +1,405 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_aud.h" +#include "string.h" +#include "pmu.h" +#include "analog.h" +#include "audioflinger.h" + + +static uint8_t *playback_buf; +static uint32_t playback_size; + +static uint8_t *capture_buf; +static uint32_t capture_size; + + +/* +static void get_mic_data_max(short *buf, uint32_t len) +{ + int max0 = -32768, min0 = 32767, diff0 = 0; + int max1 = -32768, min1 = 32767, diff1 = 0; + + for(uint32_t i=0; imax0) + { + max0 = buf[i+0]; + } + + if(buf[i+0]max1) + { + max1 = buf[i+1]; + } + + if(buf[i+1]= playback_size) { + pos = 0; + } + stime = hal_sys_timer_get(); + + TRACE(4,"%s irqDur:%d Len:%d pos:%d", __func__, TICKS_TO_MS(stime - preIrqTime), len, pos); + + preIrqTime = stime; +#endif + return 0; +} + +#if 1 +#define MWSPT_NSEC 3 +//static const int NL[MWSPT_NSEC] = { 1, 3, 1 }; +static const float NUM[MWSPT_NSEC][3] = { + { + 0.0002616526908, 0, 0 + }, + { + 1, 2, 1 + }, + { + 1, 0, 0 + } +}; + + +//static const int DL[MWSPT_NSEC] = { 1, 3, 1 }; +static const float DEN[MWSPT_NSEC][3] = { + { + 1, 0, 0 + }, + { + 1, -1.953727961, 0.9547745585 + }, + { + 1, 0, 0 + } +}; + +#else + +#define MWSPT_NSEC 3 +static const int NL[MWSPT_NSEC] = { 1,3,1 }; +static const float NUM[MWSPT_NSEC][3] = { + { + 0.0002616526908, 0, 0 + }, + { + 1, 2, 1 + }, + { + 1, 0, 0 + } +}; +static const int DL[MWSPT_NSEC] = { 1,3,1 }; +static const float DEN[MWSPT_NSEC][3] = { + { + 1, 0, 0 + }, + { + 1, -1.953727961, 0.9547745585 + }, + { + 1, 0, 0 + } +}; + +#endif + +static uint32_t dualadc_audio_data_capture(uint8_t *buf, uint32_t len) +{ + +TRACE(0,"capture"); + + + +#if 0 + if(buf==capture_buf) + { + short *BufSrcL = (short *)capture_buf; + short *BufSrcR = (short *)(capture_buf+2); + short *BufDstL = (short *)playback_buf; + short *BufDstR = (short *)(playback_buf+2); + + for(int i=0,j=0;i32600) + { + OutValue = ((int)BufSrcR[i]) << 6; + } + else if (PcmValue>(32600 / 2) && PcmValue<32600) + { + if (BufSrcR[i]>512) + { + OutValue = PcmValue*(32600 - PcmValue) + (((int)BufSrcR[i]) << 6)*(PcmValue - (32600 / 2)); + OutValue = OutValue / (32600 / 2); + } + else + { + OutValue = PcmValue; + } + } + else if (PcmValue<-32700) + { + OutValue = ((int)BufSrcR[i]) << 6; + } + else if (PcmValue >-32700 && PcmValue < -(32700 / 2)) + { + + if (BufSrcR[i] <-512) + { + OutValue = PcmValue*(-PcmValue - (32700 / 2)) + (((int)BufSrcR[i]) << 6)*(32700 + PcmValue); + OutValue= OutValue/ (32700 / 2); + } + else + { + OutValue = PcmValue; + } + + } + else + { + OutValue= PcmValue; + } + + OutValue=OutValue>>6; + // OutValue=BufSrcR[i]; + + + { + static float y0 = 0, y1 = 0, y2 = 0, x0 = 0, x1 = 0, x2 = 0; + + x0 = (OutValue* NUM[0][0]); + + y0 = x0*NUM[1][0] + x1*NUM[1][1] + x2*NUM[1][2] - y1*DEN[1][1] - y2*DEN[1][2]; + + y2 = y1; + y1 = y0; + x2 = x1; + x1 = x0; + + if (y0 > 32767.0f) + { + y0 = 32767.0f; + } + + if (y0 < -32768.0f) + { + y0 = -32768.0f; + } + + OutValue = (short)y0; + } + + + BufDstL[j]=OutValue; + BufDstR[j]=OutValue; + } + + +#endif + + + + + + +#if 0 + uint32_t stime; + uint32_t pos; + static uint32_t preIrqTime = 0; + + pos = buf + len - capture_buf; + if (pos >= capture_size) { + pos = 0; + } + stime = hal_sys_timer_get(); + + TRACE(4,"%s irqDur:%d Len:%d pos:%d", __func__, TICKS_TO_MS(stime - preIrqTime), len, pos); + + preIrqTime = stime; +#endif + return 0; +} + + + +void dualadc_audio_app(bool on) +{ + + struct AF_STREAM_CONFIG_T stream_cfg; + enum AUD_SAMPRATE_T sample_rate_play; + enum AUD_SAMPRATE_T POSSIBLY_UNUSED sample_rate_capture; + + static bool isRun = false; + + if (isRun==on) + return; + else + isRun=on; + + TRACE(2,"%s: on=%d", __FUNCTION__, on); + + + sample_rate_play = AUD_SAMPRATE_192000; + sample_rate_capture = AUD_SAMPRATE_192000; + + + if (on){ + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; + stream_cfg.sample_rate = sample_rate_play; + + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.vol = 0x06; + + stream_cfg.handler = dualadc_audio_data_playback; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + + stream_cfg.data_ptr = playback_buf; + stream_cfg.data_size = playback_size; + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + + + stream_cfg.bits = AUD_BITS_16; + stream_cfg.channel_num = AUD_CHANNEL_NUM_2; + stream_cfg.sample_rate = sample_rate_capture; + stream_cfg.vol = 0x01; + + stream_cfg.handler = dualadc_audio_data_capture; + stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; + + stream_cfg.data_ptr = capture_buf; + stream_cfg.data_size = capture_size; + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + + }else{ + + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + } +} + +void dualadc_audio_app_init(uint8_t *play_buf, uint32_t play_size, uint8_t *cap_buf, uint32_t cap_size) +{ + playback_buf = play_buf; + playback_size = play_size; + capture_buf = cap_buf; + capture_size = cap_size; +} + +void dualadc_audio_app_term(void) +{ + playback_buf = NULL; + playback_size = 0; + capture_buf = NULL; + capture_size = 0; +} + diff --git a/tests/anc_usb/dualadc_audio_app.h b/tests/anc_usb/dualadc_audio_app.h new file mode 100644 index 0000000..98a8364 --- /dev/null +++ b/tests/anc_usb/dualadc_audio_app.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __DUALADC_AUDIO_TEST_H__ +#define __DUALADC_AUDIO_TEST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "plat_types.h" + +void dualadc_audio_app(bool on); + +void dualadc_audio_app_init(uint8_t *play_buf, uint32_t play_size, uint8_t *cap_buf, uint32_t cap_size); + +void dualadc_audio_app_term(void); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/tests/anc_usb/main.c b/tests/anc_usb/main.c new file mode 100644 index 0000000..3aec694 --- /dev/null +++ b/tests/anc_usb/main.c @@ -0,0 +1,503 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" +#include "hal_bootmode.h" +#include "hal_cmu.h" +#include "hal_dma.h" +#include "hal_gpadc.h" +#include "hal_iomux.h" +#include "hal_key.h" +#include "hal_norflash.h" +#include "hal_sleep.h" +#include "hal_sysfreq.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "cmsis.h" +#include "main_entry.h" +#include "pmu.h" +#include "analog.h" +#include "string.h" +#include "hwtimer_list.h" +#include "audioflinger.h" +#include "anc_usb_app.h" +#include "usb_audio_app.h" +#include "dualadc_audio_app.h" +#include "adda_loop_app.h" +#include "usb_audio_frm_defs.h" +#include "tgt_hardware.h" +#include "audio_process.h" +#if defined(_VENDOR_MSG_SUPPT_) +#include "usb_vendor_msg.h" +#endif + +#ifdef RTOS +#include "cmsis_os.h" +#endif +#ifdef __PC_CMD_UART__ +#include "hal_cmd.h" +#endif + +#ifdef USB_AUDIO_SPEECH +#define CODEC_BUFF_FRAME_NUM (2 * 16) +#define USB_BUFF_FRAME_NUM (CODEC_BUFF_FRAME_NUM * 2) +#else +#define CODEC_BUFF_FRAME_NUM 4 +#define USB_BUFF_FRAME_NUM 10 +#endif + +#if (CODEC_BUFF_FRAME_NUM >= USB_BUFF_FRAME_NUM) +#error "Codec buffer frame num should be less than usb buffer frame num (on the requirement of conflict ctrl)" +#endif + +#ifdef USB_AUDIO_DYN_CFG + +#define USB_AUDIO_PLAYBACK_BUFF_SIZE NON_EXP_ALIGN(MAX_FRAME_SIZE_PLAYBACK * CODEC_BUFF_FRAME_NUM, DAC_BUFF_ALIGN) +#define USB_AUDIO_CAPTURE_BUFF_SIZE NON_EXP_ALIGN(MAX_FRAME_SIZE_CAPTURE * CODEC_BUFF_FRAME_NUM, ADC_BUFF_ALIGN) + +#define USB_AUDIO_RECV_BUFF_SIZE NON_EXP_ALIGN(MAX_FRAME_SIZE_RECV * USB_BUFF_FRAME_NUM, RECV_BUFF_ALIGN) +#define USB_AUDIO_SEND_BUFF_SIZE NON_EXP_ALIGN(MAX_FRAME_SIZE_SEND * USB_BUFF_FRAME_NUM, SEND_BUFF_ALIGN) + +#if defined(CHIP_BEST1000) +// FIR EQ is working on 16-bit +// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int16_t) +#define USB_AUDIO_FIR_EQ_BUFF_SIZE USB_AUDIO_PLAYBACK_BUFF_SIZE +#elif defined(CHIP_BEST2000) +// FIR EQ is working on 32-bit +// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int32_t) +#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE*2) +#elif defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) +// FIR EQ is working on 32-bit +// FIR_EQ_buffer_size = max_playback_symbol_number_in_buffer * sizeof(int32_t) +#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE) +#define USB_AUDIO_IIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE) +#define USB_AUDIO_DSD_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE*16) +#endif + +#else // !USB_AUDIO_DYN_CFG + +#define USB_AUDIO_PLAYBACK_BUFF_SIZE NON_EXP_ALIGN(FRAME_SIZE_PLAYBACK * CODEC_BUFF_FRAME_NUM, DAC_BUFF_ALIGN) +#define USB_AUDIO_CAPTURE_BUFF_SIZE NON_EXP_ALIGN(FRAME_SIZE_CAPTURE * CODEC_BUFF_FRAME_NUM, ADC_BUFF_ALIGN) + +#define USB_AUDIO_RECV_BUFF_SIZE NON_EXP_ALIGN(FRAME_SIZE_RECV * USB_BUFF_FRAME_NUM, RECV_BUFF_ALIGN) +#define USB_AUDIO_SEND_BUFF_SIZE NON_EXP_ALIGN(FRAME_SIZE_SEND * USB_BUFF_FRAME_NUM, SEND_BUFF_ALIGN) + +#if defined(CHIP_BEST1000) +// FIR EQ is working on 16-bit +#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE * sizeof(int16_t) / SAMPLE_SIZE_PLAYBACK) +#elif defined(CHIP_BEST2000) +// FIR EQ is working on 32-bit +#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE * sizeof(int32_t) / SAMPLE_SIZE_PLAYBACK) +#elif defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) +// FIR EQ is working on 32-bit +#define USB_AUDIO_FIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE) +#define USB_AUDIO_IIR_EQ_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE) +#define USB_AUDIO_DSD_BUFF_SIZE (USB_AUDIO_PLAYBACK_BUFF_SIZE*16) +#endif + +#endif // !USB_AUDIO_DYN_CFG + +#if (defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_))) && (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) +// Resample input buffer size should be (half_of_max_sample_num * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE). +// half_of_max_sample_num = 48000 / 1000 * CODEC_BUFF_FRAME_NUM / 2 * 48 / 44 +#define RESAMPLE_INPUT_BUFF_SIZE ALIGN(48000 / 1000 * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE * CODEC_BUFF_FRAME_NUM / 2 * 48 / 44, 4) +#else +#define RESAMPLE_INPUT_BUFF_SIZE 0 +#endif +// Resample history buffer size should be +// sizeof(struct RESAMPLE_CTRL_T) + ((SAMPLE_NUM + phase_coef_num) * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) +#define RESAMPLE_HISTORY_BUFF_SIZE (50 + (256 * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE)) +#define USB_AUDIO_RESAMPLE_BUFF_SIZE (RESAMPLE_INPUT_BUFF_SIZE + RESAMPLE_HISTORY_BUFF_SIZE) + +#define ALIGNED4 ALIGNED(4) + +#if defined(USB_AUDIO_APP) || defined(DUALADC_AUDIO_TEST) + +#ifdef AUDIO_ANC_FB_MC +static uint8_t ALIGNED4 playback_buff[USB_AUDIO_PLAYBACK_BUFF_SIZE * 9];//max 48->384 or 44.1->44.1*8; +#else +static uint8_t ALIGNED4 playback_buff[USB_AUDIO_PLAYBACK_BUFF_SIZE]; +#endif + +static uint8_t ALIGNED4 capture_buff[USB_AUDIO_CAPTURE_BUFF_SIZE]; + +#endif + +#ifdef USB_AUDIO_APP + +#if defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) +static uint8_t ALIGNED4 eq_buff[USB_AUDIO_FIR_EQ_BUFF_SIZE+USB_AUDIO_IIR_EQ_BUFF_SIZE]; +#elif defined(__HW_FIR_EQ_PROCESS__) && !defined(__HW_IIR_EQ_PROCESS__) +static uint8_t ALIGNED4 eq_buff[USB_AUDIO_FIR_EQ_BUFF_SIZE]; +#elif !defined(__HW_FIR_EQ_PROCESS__) && defined(__HW_IIR_EQ_PROCESS__) +static uint8_t ALIGNED4 eq_buff[USB_AUDIO_IIR_EQ_BUFF_SIZE]; +#else +static uint8_t ALIGNED4 eq_buff[0]; +#endif + +#ifdef SW_CAPTURE_RESAMPLE +static uint8_t ALIGNED4 resample_buff[USB_AUDIO_RESAMPLE_BUFF_SIZE]; +#else +static uint8_t ALIGNED4 resample_buff[0]; +#endif + +static uint8_t ALIGNED4 recv_buff[USB_AUDIO_RECV_BUFF_SIZE]; +static uint8_t ALIGNED4 send_buff[USB_AUDIO_SEND_BUFF_SIZE]; + +#ifdef USB_AUDIO_MULTIFUNC +static uint8_t ALIGNED4 recv2_buff[USB_AUDIO_RECV_BUFF_SIZE]; +#endif + +#endif + +#ifdef CFG_HW_KEY_LED_PIN +const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_key_led[1] = { + {CFG_HW_KEY_LED_PIN, HAL_IOMUX_FUNC_AS_GPIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL}, +}; +#endif + +#ifdef CFG_MIC_KEY +extern void mic_key_open (void); +#endif + +static void uart_i2c_switch(void) +{ + static int flag = 0; + + flag ^= 1; + + if (flag) { + hal_iomux_set_analog_i2c(); + } else { + hal_iomux_set_uart0(); + } +} + +static int key_event_process(uint32_t key_code, uint8_t key_event) +{ + TRACE(3,"%s: code=0x%X, event=%u", __FUNCTION__, key_code, key_event); + +#ifdef CFG_HW_KEY_LED_PIN + if (key_event == HAL_KEY_EVENT_DOWN) { + hal_gpio_pin_set(CFG_HW_KEY_LED_PIN); + } else if (key_event == HAL_KEY_EVENT_UP) { + hal_gpio_pin_clr(CFG_HW_KEY_LED_PIN); + } +#endif + +#ifdef USB_AUDIO_APP + if (usb_audio_app_key(key_code, key_event) == 0) { + return 0; + } +#endif + +#ifdef ANC_APP + if (anc_usb_app_key(key_code, key_event) == 0) { + return 0; + } +#endif + + if (key_event == HAL_KEY_EVENT_CLICK) { + if (key_code == HAL_KEY_CODE_FN9) { + uart_i2c_switch(); + } + } + + return 0; +} + +void anc_usb_open(void) +{ + TRACE(1,"%s", __FUNCTION__); + +#ifdef __AUDIO_RESAMPLE__ + hal_cmu_audio_resample_enable(); +#endif +#ifdef USB_AUDIO_APP + struct USB_AUDIO_BUF_CFG cfg; + + memset(&cfg, 0, sizeof(cfg)); + cfg.play_buf = playback_buff; +#ifdef AUDIO_ANC_FB_MC + cfg.play_size = sizeof(playback_buff) / 9; +#else + cfg.play_size = sizeof(playback_buff); +#endif + cfg.cap_buf = capture_buff; + cfg.cap_size = sizeof(capture_buff); + cfg.recv_buf = recv_buff; + cfg.recv_size = sizeof(recv_buff); + cfg.send_buf = send_buff; + cfg.send_size = sizeof(send_buff); + cfg.eq_buf = eq_buff; + cfg.eq_size = sizeof(eq_buff); + cfg.resample_buf = resample_buff; + cfg.resample_size = sizeof(resample_buff); +#ifdef USB_AUDIO_MULTIFUNC + cfg.recv2_buf = recv2_buff; + cfg.recv2_size = sizeof(recv2_buff); +#endif + + usb_audio_app_init(&cfg); + usb_audio_app(true); +#endif + +#ifdef ANC_APP + anc_usb_app_init(AUD_INPUT_PATH_MAINMIC, SAMPLE_RATE_PLAYBACK, SAMPLE_RATE_CAPTURE); +#endif + +#ifdef DUALADC_AUDIO_TEST + dualadc_audio_app_init(playback_buff, USB_AUDIO_PLAYBACK_BUFF_SIZE, + capture_buff, USB_AUDIO_CAPTURE_BUFF_SIZE); + dualadc_audio_app(true); +#endif + +#ifdef ADDA_LOOP_APP + adda_loop_app(true); +#endif + +#if defined(_VENDOR_MSG_SUPPT_) +#ifndef USB_ANC_MC_EQ_TUNING + vendor_info_init(); +#endif +#endif + +#if defined(CFG_MIC_KEY) + mic_key_open(); +#endif + + // Allow sleep + hal_sysfreq_req(HAL_SYSFREQ_USER_INIT, HAL_CMU_FREQ_32K); + + while (1) { +#ifdef USB_AUDIO_APP + usb_audio_app_loop(); +#endif + +#ifdef ANC_APP + anc_usb_app_loop(); +#endif + +#ifdef ADDA_LOOP_APP + adda_loop_app_loop(); +#endif + +#ifdef RTOS + // Let the task sleep + osDelay(20); +#else // !RTOS + +#ifdef USB_EQ_TUNING + audio_eq_usb_eq_update(); +#endif + + hal_sleep_enter_sleep(); + +#endif // !RTOS + } +} + +#ifdef CFG_HW_GPADCKEY +void gpadc_key_handler(uint16_t irq_val, HAL_GPADC_MV_T volt) +{ + static uint16_t stable_cnt = 0; + static uint16_t click_cnt = 0; + static uint32_t click_time; + uint32_t time; + enum HAL_KEY_EVENT_T event; + bool send_event = false; + + time = hal_sys_timer_get(); + + if (volt < 100) { + stable_cnt++; + //TRACE(5,"adc_key down: volt=%u stable=%u click_cnt=%u click_time=%u time=%u", volt, stable_cnt, click_cnt, click_time, time); + } else { + if (stable_cnt > 1) { + //TRACE(5,"adc_key up: volt=%u stable=%u click_cnt=%u click_time=%u time=%u", volt, stable_cnt, click_cnt, click_time, time); + if (click_cnt == 0 || (time - click_time) < MS_TO_TICKS(500)) { + click_time = time; + click_cnt++; + if (click_cnt >= 3) { + send_event = true; + } + } else { + send_event = true; + } + } + stable_cnt = 0; + + if (click_cnt > 0 && (time - click_time) >= MS_TO_TICKS(500)) { + send_event = true; + } + + if (send_event) { + //TRACE(5,"adc_key click: volt=%u stable=%u click_cnt=%u click_time=%u time=%u", volt, stable_cnt, click_cnt, click_time, time); + if (click_cnt == 1) { + event = HAL_KEY_EVENT_CLICK; + } else if (click_cnt == 2) { + event = HAL_KEY_EVENT_DOUBLECLICK; + } else { + event = HAL_KEY_EVENT_TRIPLECLICK; + } + key_event_process(CFG_HW_GPADCKEY, event); + click_cnt = 0; + } + } +} +#endif + +#ifdef DEBUG_MODE_USB_DOWNLOAD +static void process_usb_download_mode(void) +{ + if (pmu_charger_get_status() == PMU_CHARGER_PLUGIN && hal_pwrkey_pressed()) { + hal_sw_bootmode_set(HAL_SW_BOOTMODE_FORCE_USB_DLD); + hal_cmu_sys_reboot(); + } +} +#endif + +// GDB can set a breakpoint on the main function only if it is +// declared as below, when linking with STD libraries. +int MAIN_ENTRY(void) +{ +#ifdef INTSRAM_RUN +// hal_norflash_sleep(HAL_NORFLASH_ID_0); +#endif + +#ifdef DEBUG_MODE_USB_DOWNLOAD + process_usb_download_mode(); +#endif + + hal_cmu_simu_init(); + hwtimer_init(); + hal_audma_open(); + hal_gpdma_open(); + +#if (DEBUG_PORT == 2) + hal_iomux_set_analog_i2c(); + hal_iomux_set_uart1(); + hal_trace_open(HAL_TRACE_TRANSPORT_UART1); +#else + hal_iomux_set_uart0(); + hal_trace_open(HAL_TRACE_TRANSPORT_UART0); +#endif + +#if !defined(SIMU) && !defined(FPGA) + uint8_t flash_id[HAL_NORFLASH_DEVICE_ID_LEN]; + hal_norflash_get_id(HAL_NORFLASH_ID_0, flash_id, ARRAY_SIZE(flash_id)); + TRACE(3,"FLASH_ID: %02X-%02X-%02X", flash_id[0], flash_id[1], flash_id[2]); +#endif + + pmu_open(); + analog_open(); + af_open(); + hal_sleep_start_stats(10000, 10000); + +#ifdef CHIP_BEST1000 + hal_cmu_force_bt_sleep(); +#endif + + hal_key_open(0, key_event_process); +#ifdef CFG_HW_GPADCKEY + hal_gpadc_open(HAL_GPADC_CHAN_3, HAL_GPADC_ATP_20MS, gpadc_key_handler); +#endif + +#ifdef CFG_HW_KEY_LED_PIN + hal_iomux_init(pinmux_key_led, ARRAY_SIZE(pinmux_key_led)); + hal_gpio_pin_set_dir(CFG_HW_KEY_LED_PIN, HAL_GPIO_DIR_OUT, 0); +#endif + +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__)|| defined(__HW_DAC_IIR_EQ_PROCESS__)|| defined(__HW_IIR_EQ_PROCESS__) + audio_process_init(); + // TODO: Get EQ store parameter + // audio_eq_fir_update_cfg(int16_t *coef, int16_t num); + // audio_eq_iir_update_cfg(int *gain, int num); +#endif + + anc_usb_open(); + + TRACE(0,"byebye~~~\n"); + + hal_sys_timer_delay(MS_TO_TICKS(200)); + + pmu_shutdown(); + + return 0; +} + +//-------------------------------------------------------------------------------- +// Start of Programmer Entry +//-------------------------------------------------------------------------------- +#ifdef PROGRAMMER +#include "cmsis_nvic.h" +#include "hal_chipid.h" +#include "tool_msg.h" + +extern uint32_t __StackTop[]; +extern uint32_t __StackLimit[]; +extern uint32_t __bss_start__[]; +extern uint32_t __bss_end__[]; + +#define EXEC_STRUCT_LOC __attribute__((section(".exec_struct"))) + +bool task_yield(void) +{ + return true; +} + +void anc_usb_ramrun_main(void) +{ + uint32_t *dst; + + for (dst = __bss_start__; dst < __bss_end__; dst++) { + *dst = 0; + } + + NVIC_InitVectors(); +#ifdef UNALIGNED_ACCESS + SystemInit(); +#endif + hal_cmu_setup(); + main(); + +#if !defined(PROGRAMMER_INFLASH) + SAFE_PROGRAM_STOP(); +#endif +} + +void anc_usb_ramrun_start(void) +{ + GotBaseInit(); +#ifdef __ARM_ARCH_8M_MAIN__ + __set_MSPLIM((uint32_t)__StackLimit); +#endif + __set_MSP((uint32_t)__StackTop); + anc_usb_ramrun_main(); +} + +const struct exec_struct_t EXEC_STRUCT_LOC ramrun_struct = { + .entry = (uint32_t)anc_usb_ramrun_start, + .param = 0, + .sp = 0, + .exec_addr = (uint32_t)&ramrun_struct, +}; + +void programmer_start(void) __attribute__((weak,alias("anc_usb_ramrun_main"))); +#endif +//-------------------------------------------------------------------------------- +// End of Programmer Entry +//-------------------------------------------------------------------------------- + diff --git a/tests/anc_usb/memutils.c b/tests/anc_usb/memutils.c new file mode 100644 index 0000000..2a86e9d --- /dev/null +++ b/tests/anc_usb/memutils.c @@ -0,0 +1,94 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "string.h" +#include "memutils.h" + +#define ALIGNED32(a) (((uint32_t)(a) & 3) == 0) +#define ALIGNED16(a) (((uint32_t)(a) & 1) == 0) + +void *copy_mem32(void *dst, const void *src, unsigned int size) +{ + uint32_t *d = dst; + const uint32_t *s = src; + const uint32_t *e = s + size / 4; + + while (s < e) { + *d++ = *s++; + } + + return dst; +} + +void *copy_mem16(void *dst, const void *src, unsigned int size) +{ + uint16_t *d = dst; + const uint16_t *s = src; + const uint16_t *e = s + size / 2; + + while (s < e) { + *d++ = *s++; + } + + return dst; +} + +void *copy_mem(void *dst, const void *src, unsigned int size) +{ + if (ALIGNED32(dst) && ALIGNED32(src) && ALIGNED32(size)) { + return copy_mem32(dst, src, size); + } else if (ALIGNED16(dst) && ALIGNED16(src) && ALIGNED16(size)) { + return copy_mem16(dst, src, size); + } else { + return memcpy(dst, src, size); + } +} + +void *zero_mem32(void *dst, unsigned int size) +{ + uint32_t *d = dst; + uint32_t count = size / 4; + + while (count--) { + *d++ = 0; + } + + return dst; +} + +void *zero_mem16(void *dst, unsigned int size) +{ + uint16_t *d = dst; + uint32_t count = size / 2; + + while (count--) { + *d++ = 0; + } + + return dst; +} + +void *zero_mem(void *dst, unsigned int size) +{ + if (ALIGNED32(dst) && ALIGNED32(size)) { + return zero_mem32(dst, size); + } else if (ALIGNED16(dst) && ALIGNED16(size)) { + return zero_mem16(dst, size); + } else { + return memset(dst, 0, size); + } +} + diff --git a/tests/anc_usb/memutils.h b/tests/anc_usb/memutils.h new file mode 100644 index 0000000..a9f0580 --- /dev/null +++ b/tests/anc_usb/memutils.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __MEMUTILS_H__ +#define __MEMUTILS_H__ + +void *copy_mem32(void *dst, const void *src, unsigned int size); + +void *copy_mem16(void *dst, const void *src, unsigned int size); + +void *copy_mem(void *dst, const void *src, unsigned int size); + +void *zero_mem32(void *dst, unsigned int size); + +void *zero_mem16(void *dst, unsigned int size); + +void *zero_mem(void *dst, unsigned int size); + +#endif + diff --git a/tests/anc_usb/mic_key.c b/tests/anc_usb/mic_key.c new file mode 100644 index 0000000..fc710d6 --- /dev/null +++ b/tests/anc_usb/mic_key.c @@ -0,0 +1,154 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifdef CFG_MIC_KEY + +#include "hal_timer.h" +#include "hal_trace.h" +#include "hwtimer_list.h" +#include "hal_iomux.h" +#include "hal_gpadc.h" +#include "analog.h" +#include "usb_audio.h" +#include "tgt_hardware.h" + +#define MIC_KEY_CHK_TIMES 20 +#define MIC_KEY_SKIP_CNT 8 +#define MIC_KEY_CHK_INTERVAL MS_TO_TICKS(1) // in ticks + +static struct { + HWTIMER_ID chk_timer; + + uint16_t chk_val[MIC_KEY_CHK_TIMES-MIC_KEY_SKIP_CNT]; + + uint8_t chk_times; + uint8_t gpio_dn; + uint8_t key_dn[MIC_KEY_NUM]; +} s_mic_key_ctx; + +extern void mic_key_gpio_irq_set (void); + +void mic_key_irq_hdl (uint16_t irq_val, HAL_GPADC_MV_T volt) +{ + hal_gpadc_close(mic_key_gpadc_chan); + + if (++s_mic_key_ctx.chk_times >= MIC_KEY_CHK_TIMES) { + + uint8_t i, j; + uint32_t mean; + + for (i = 0; i < MIC_KEY_NUM; i++) { + mean = 0; + + for (j = 0; j < MIC_KEY_CHK_TIMES-MIC_KEY_SKIP_CNT; j++) { + mean += (uint32_t)s_mic_key_ctx.chk_val[j]; + } + mean /= MIC_KEY_CHK_TIMES-MIC_KEY_SKIP_CNT; + + if ((mean > mic_key_cfg_lst[i].ref_vol_low) && (mean <= mic_key_cfg_lst[i].ref_vol_high)) + break; + } + + if (i < MIC_KEY_NUM) { + TRACE(2,"ana_key: key[%d] matched at [%dmv]", i, mean); + usb_audio_hid_set_event(mic_key_cfg_lst[i].hid_evt, 1); + s_mic_key_ctx.key_dn[i] = 1; + } else { + TRACE(1,"ana_key: no key matched [%dmv]", mean); + } + + return; + } + + if (s_mic_key_ctx.chk_times > MIC_KEY_SKIP_CNT) { + s_mic_key_ctx.chk_val[s_mic_key_ctx.chk_times - MIC_KEY_SKIP_CNT - 1] = volt; + } + + hwtimer_start(s_mic_key_ctx.chk_timer, MIC_KEY_CHK_INTERVAL); +} + +void mic_key_gpio_det_irq_hdl (enum HAL_GPIO_PIN_T pin) +{ + if (pin != mic_key_det_gpio_pin) + return; + + TRACE(1,"GPIO detected at status[%d]", s_mic_key_ctx.gpio_dn); + if (s_mic_key_ctx.gpio_dn) { + + uint8_t i; + + for (i = 0; i < MIC_KEY_NUM; i++) { + if (s_mic_key_ctx.key_dn[i]) { + break; + } + } + if (i < MIC_KEY_NUM) { + usb_audio_hid_set_event(mic_key_cfg_lst[i].hid_evt, 0); + s_mic_key_ctx.key_dn[i] = 0; + } + + s_mic_key_ctx.gpio_dn = 0; + } else { + s_mic_key_ctx.chk_times = 0; + s_mic_key_ctx.gpio_dn = 1; + hal_gpadc_open(mic_key_gpadc_chan, HAL_GPADC_ATP_ONESHOT, mic_key_irq_hdl); + } + + mic_key_gpio_irq_set(); +} + + +void mic_key_periodic_check (void* param) +{ + hal_gpadc_open(mic_key_gpadc_chan, HAL_GPADC_ATP_ONESHOT, mic_key_irq_hdl); +} + +void mic_key_gpio_irq_set (void) +{ + struct HAL_GPIO_IRQ_CFG_T cfg; + + cfg.irq_debounce = 1; + cfg.irq_enable = 1; + cfg.irq_type = HAL_GPIO_IRQ_TYPE_EDGE_SENSITIVE; + if (s_mic_key_ctx.gpio_dn) { + cfg.irq_polarity = HAL_GPIO_IRQ_POLARITY_HIGH_RISING; + } else { + cfg.irq_polarity = HAL_GPIO_IRQ_POLARITY_LOW_FALLING; + } + cfg.irq_handler = mic_key_gpio_det_irq_hdl; + + hal_gpio_setup_irq(mic_key_det_gpio_pin, &cfg); +} + +void mic_key_open (void) +{ + struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_key_det[] = { + {0, HAL_IOMUX_FUNC_GPIO, HAL_IOMUX_PIN_VOLTAGE_MEM, HAL_IOMUX_PIN_NOPULL}, + }; + + TRACE(1,"%s", __func__); + + pinmux_key_det[0].pin = mic_key_det_gpio_pin; + hal_iomux_init(pinmux_key_det, ARRAY_SIZE(pinmux_key_det)); + + analog_aud_mickey_enable(true); + + s_mic_key_ctx.chk_timer = hwtimer_alloc(mic_key_periodic_check, NULL); + hal_gpio_pin_set_dir(mic_key_det_gpio_pin, HAL_GPIO_DIR_IN, 0); + mic_key_gpio_irq_set(); +} + + +#endif diff --git a/tests/anc_usb/safe_queue.c b/tests/anc_usb/safe_queue.c new file mode 100644 index 0000000..85c4091 --- /dev/null +++ b/tests/anc_usb/safe_queue.c @@ -0,0 +1,161 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis.h" +#include "safe_queue.h" +#include "hal_trace.h" + +void safe_queue_init(struct SAFE_QUEUE_T *queue, uint32_t *items, uint32_t size) +{ + // queue->first points to the first valid item + queue->first = 0; + // queue->last points to the first empty slot (beyond the last valid item) + queue->last = 0; + queue->count = 0; + queue->size = size; + queue->watermark = 0; + queue->items = items; +} + +int safe_queue_put(struct SAFE_QUEUE_T *queue, uint32_t item) +{ + int ret = 0; + uint32_t lock; + + lock = int_lock(); + + if (queue->count >= queue->size) { + ret = 1; + } else { + queue->items[queue->last] = item; + queue->last++; + if (queue->last >= queue->size) { + queue->last = 0; + } + + queue->count++; + if (queue->count > queue->watermark) { + queue->watermark = queue->count; + } + } + + int_unlock(lock); + + return ret; +} + +int safe_queue_get(struct SAFE_QUEUE_T *queue, uint32_t *itemp) +{ + int ret = 0; + uint32_t lock; + + lock = int_lock(); + + if (queue->count == 0) { + ret = 1; + } else { + if (itemp) { + *itemp = queue->items[queue->first]; + } + queue->first++; + if (queue->first >= queue->size) { + queue->first = 0; + } + + queue->count--; + } + + int_unlock(lock); + + return ret; +} + +int safe_queue_pop(struct SAFE_QUEUE_T *queue, uint32_t *itemp) +{ + int ret = 0; + uint32_t lock; + + lock = int_lock(); + + if (queue->count == 0) { + ret = 1; + } else { + if (queue->last) { + queue->last--; + } else { + queue->last = queue->size - 1; + } + if (itemp) { + *itemp = queue->items[queue->last]; + } + + queue->count--; + } + + int_unlock(lock); + + return ret; +} + +int safe_queue_peek(const struct SAFE_QUEUE_T *queue, int offset, uint32_t *itemp) +{ + int ret = 0; + uint32_t lock; + uint8_t idx; + + lock = int_lock(); + + if (offset >= 0 && offset < queue->count) { + idx = queue->first + offset; + } else if (offset < 0 && -offset <= queue->count) { + idx = queue->size + queue->last + offset; + } else { + ret = 1; + } + + if (ret == 0) { + if (idx >= queue->size) { + idx -= queue->size; + } + + *itemp = queue->items[idx]; + } + + int_unlock(lock); + + return ret; +} + +uint32_t safe_queue_watermark(const struct SAFE_QUEUE_T *queue) +{ + return queue->watermark; +} + +int safe_queue_dump(const struct SAFE_QUEUE_T *queue) +{ + uint32_t cnt; + int i; + uint32_t item; + + cnt = queue->count; + for (i = 0; i < cnt; i++) { + if (safe_queue_peek(queue, i, &item)) { + break; + } + TRACE_IMM(3,"SAFE-QUEUE-DUMP: [%02d/%02d] 0x%08x", i, cnt, item); + } + + return 0; +} diff --git a/tests/anc_usb/safe_queue.h b/tests/anc_usb/safe_queue.h new file mode 100644 index 0000000..a5abf95 --- /dev/null +++ b/tests/anc_usb/safe_queue.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SAFE_QUEUE_H__ +#define __SAFE_QUEUE_H__ + +#include "plat_types.h" + +struct SAFE_QUEUE_T { + uint8_t first; + uint8_t last; + uint8_t count; + uint8_t size; + uint8_t watermark; + uint32_t *items; +}; + +void safe_queue_init(struct SAFE_QUEUE_T *queue, uint32_t *items, uint32_t size); + +int safe_queue_put(struct SAFE_QUEUE_T *queue, uint32_t item); + +int safe_queue_get(struct SAFE_QUEUE_T *queue, uint32_t *itemp); + +int safe_queue_pop(struct SAFE_QUEUE_T *queue, uint32_t *itemp); + +int safe_queue_peek(const struct SAFE_QUEUE_T *queue, int offset, uint32_t *itemp); + +uint32_t safe_queue_watermark(const struct SAFE_QUEUE_T *queue); + +int safe_queue_dump(const struct SAFE_QUEUE_T *queue); + +#endif diff --git a/tests/anc_usb/speech_process.c b/tests/anc_usb/speech_process.c new file mode 100644 index 0000000..a0dbebd --- /dev/null +++ b/tests/anc_usb/speech_process.c @@ -0,0 +1,261 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "speech_process.h" +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_sysfreq.h" +#include "cmsis.h" + +#if defined(SPEECH_TX_AEC2FLOAT) && !defined(KEEP_SAME_LATENCY) +#error "capture/playback size should be equal when enable AEC" +#endif + +#include "bt_sco_chain.h" +#include "iir_resample.h" +#include "speech_utils.h" +#include "speech_memory.h" + +#define MED_MEM_POOL_SIZE (1024*160) +static uint8_t g_medMemPool[MED_MEM_POOL_SIZE]; + +#define FFSE_SAMPLE_RATE (16000) + +int capture_channel_num = 1; +int capture_sample_rate = 48000; +int capture_sample_bit = 16; +int playback_channel_num = 2; +int playback_sample_rate = 48000; +int playback_sample_bit = 24; + +int send_channel_num = 2; +int recv_channel_num = 2; + +// resample related +static bool resample_needed_flag = false; +static IirResampleState *upsample_st; +static IirResampleState *downsample_st[4]; +int16_t *capture_buffer_deinter = NULL; +int16_t *process_buffer = NULL; +int16_t *process_buffer_inter = NULL; + +static short *aec_echo_buf = NULL; +static IirResampleState *rx_downsample_st; + +static volatile bool is_speech_init = false; + +static void speech_deinterleave(int16_t *in, int16_t *out, int len, int ch_num) +{ + int len_per_channel = len / ch_num; + + for (int i = 0, j = 0; i < len; i += ch_num, j++) { + int16_t *pout = &out[j]; + int16_t *pin = &in[i]; + for (int c= 0; c < ch_num; c++) { + *pout = *pin; + pout += len_per_channel; + pin += 1; + } + } +} + +static void speech_interleave(int16_t *in, int16_t *out, int len, int ch_num) +{ + int len_per_channel = len / ch_num; + + for (int i = 0, j = 0; j < len; i++, j += ch_num) { + int16_t *pout = &out[j]; + int16_t *pin = &in[i]; + for (int c= 0; c < ch_num; c++) { + *pout = *pin; + pout += 1; + pin += len_per_channel; + } + } +} + +static void speech_extend(int16_t *in, int16_t *out, int len, int ch_num) +{ + int16_t *pout = out + len * ch_num - 1; + for (int i = len - 1; i >= 0; i--) { + for (int c= 0; c < ch_num; c++) { + *pout-- = in[i]; + } + } +} + +// This function output remains the same sample rate as input, +// output channel number shoule be CHAN_NUM_SEND. +// TODO: add multi-channel support in iir resampler +void speech_process_capture_run(uint8_t *buf, uint32_t *len) +{ + //TRACE(2,"[%s], pcm_len: %d", __FUNCTION__, *len / 2); + + if (is_speech_init == false) + return; + + int16_t *pcm_buf = (int16_t *)buf; + int pcm_len = *len / 2; + int process_len = pcm_len * FFSE_SAMPLE_RATE / capture_sample_rate; + + if (resample_needed_flag == true) { + if (capture_channel_num > 1) + speech_deinterleave(pcm_buf, capture_buffer_deinter, pcm_len, capture_channel_num); + else + speech_copy_int16(capture_buffer_deinter, pcm_buf, pcm_len); + + int in_len_per_channel = pcm_len / capture_channel_num; + int out_len_per_channel = process_len / capture_channel_num; + for (int i = 0; i < capture_channel_num; i++) { + iir_resample_process(downsample_st[i], &capture_buffer_deinter[i * in_len_per_channel], + &process_buffer[i * out_len_per_channel], in_len_per_channel); + } + + if (capture_channel_num > 1) + speech_interleave(process_buffer, process_buffer_inter, process_len, capture_channel_num); + else + speech_copy_int16(process_buffer_inter, process_buffer, process_len); + + speech_tx_process(process_buffer_inter, aec_echo_buf, &process_len); + + iir_resample_process(upsample_st, process_buffer_inter, pcm_buf, process_len); + + if (send_channel_num > 1) + speech_extend(pcm_buf, pcm_buf, in_len_per_channel, send_channel_num); + } else { + speech_tx_process(pcm_buf, aec_echo_buf, &process_len); + + if (send_channel_num > 1) + speech_extend(pcm_buf, pcm_buf, process_len, send_channel_num); + } + + pcm_len = pcm_len / capture_channel_num * send_channel_num; + *len = pcm_len * sizeof(int16_t); +} + +void speech_process_playback_run(uint8_t *buf, uint32_t *len) +{ + //TRACE(2,"[%s] pcm_len: %d", __FUNCTION__, *len / 2); + + if (is_speech_init == false) + return; + +#if defined(SPEECH_TX_AEC2FLOAT) + int16_t *pcm_buf = (int16_t *)buf; + int pcm_len = *len / 2; + + if (resample_needed_flag == true) { + // Convert to 16bit if necessary + if (playback_sample_bit == 24) { + int32_t *pcm32 = (int32_t *)buf; + for (int i = 0; i < pcm_len / 2; i++) { + pcm_buf[i] = (pcm32[i] >> 8); + } + pcm_len >>= 1; + } + + // Convert to mono if necessary, choose left channel + if (playback_channel_num == 2) { + for (int i = 0, j = 0; i < pcm_len; i += 2, j++) + pcm_buf[j] = pcm_buf[i]; + pcm_len >>= 1; + } + + iir_resample_process(rx_downsample_st, pcm_buf, pcm_buf, pcm_len); + } + speech_copy_int16(aec_echo_buf, pcm_buf, pcm_len * FFSE_SAMPLE_RATE / capture_sample_rate); +#endif +} + +void speech_process_init(int tx_sample_rate, int tx_channel_num, int tx_sample_bit, + int rx_sample_rate, int rx_channel_num, int rx_sample_bit, + int tx_frame_ms, int rx_frame_ms, + int tx_send_channel_num, int rx_recv_channel_num) +{ + ASSERT(tx_sample_rate == 16000 || tx_sample_rate == 48000, "[%s] sample rate(%d) not supported", __FUNCTION__, tx_sample_rate); + ASSERT(tx_frame_ms == 16, "[%s] just support 16ms frame", __func__); + + capture_sample_rate = tx_sample_rate; + capture_channel_num = tx_channel_num; + capture_sample_bit = tx_sample_bit; + playback_sample_rate = rx_sample_rate; + playback_channel_num = rx_channel_num; + playback_sample_bit = rx_sample_bit; + + send_channel_num = tx_send_channel_num; + recv_channel_num = rx_recv_channel_num; + + resample_needed_flag = (capture_sample_rate != FFSE_SAMPLE_RATE); + + TRACE(5,"[%s] sample_rate: %d, frame_ms: %d, channel_num: %d, resample_needed_flag: %d", __FUNCTION__, + tx_sample_rate, tx_frame_ms, tx_channel_num, resample_needed_flag); + + speech_init(FFSE_SAMPLE_RATE, FFSE_SAMPLE_RATE, tx_frame_ms, tx_frame_ms, tx_frame_ms, &g_medMemPool[0], MED_MEM_POOL_SIZE); + + if (resample_needed_flag == true) { + capture_buffer_deinter = speech_calloc(SPEECH_FRAME_MS_TO_LEN(capture_sample_rate, tx_frame_ms) * capture_channel_num, sizeof(int16_t)); + + // Resample state must be created after speech init, as it uses speech heap + process_buffer = speech_calloc(SPEECH_FRAME_MS_TO_LEN(FFSE_SAMPLE_RATE, tx_frame_ms) * capture_channel_num, sizeof(int16_t)); + process_buffer_inter = speech_calloc(SPEECH_FRAME_MS_TO_LEN(FFSE_SAMPLE_RATE, tx_frame_ms) * capture_channel_num, sizeof(int16_t)); + + upsample_st = iir_resample_init(SPEECH_FRAME_MS_TO_LEN(FFSE_SAMPLE_RATE, tx_frame_ms), iir_resample_choose_mode(FFSE_SAMPLE_RATE, capture_sample_rate)); + + // as iir resample can only deal with mono signal, we should init channel_num states + for (int i = 0; i < capture_channel_num; i++) { + downsample_st[i] = iir_resample_init(SPEECH_FRAME_MS_TO_LEN(capture_sample_rate, tx_frame_ms), iir_resample_choose_mode(capture_sample_rate, FFSE_SAMPLE_RATE)); + } + + // + aec_echo_buf = speech_calloc(SPEECH_FRAME_MS_TO_LEN(FFSE_SAMPLE_RATE, rx_frame_ms), sizeof(int16_t)); + rx_downsample_st = iir_resample_init(SPEECH_FRAME_MS_TO_LEN(playback_sample_rate, rx_frame_ms), iir_resample_choose_mode(playback_sample_rate, FFSE_SAMPLE_RATE)); + } + + is_speech_init = true; +} + +void speech_process_deinit(void) +{ + if (is_speech_init == false) + return; + + if (resample_needed_flag == true) { + speech_free(capture_buffer_deinter); + + speech_free(process_buffer); + speech_free(process_buffer_inter); + + iir_resample_destroy(upsample_st); + + for (int i = 0; i < capture_channel_num; i++) { + iir_resample_destroy(downsample_st[i]); + } + + speech_free(aec_echo_buf); + iir_resample_destroy(rx_downsample_st); + + resample_needed_flag = false; + } + + speech_deinit(); + + is_speech_init = false; +} + +enum HAL_CMU_FREQ_T speech_process_need_freq(void) +{ + return HAL_CMU_FREQ_208M; +} + diff --git a/tests/anc_usb/speech_process.h b/tests/anc_usb/speech_process.h new file mode 100644 index 0000000..004b297 --- /dev/null +++ b/tests/anc_usb/speech_process.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __SPEECH_PROCESS_H__ +#define __SPEECH_PROCESS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_sysfreq.h" + +enum HAL_CMU_FREQ_T speech_process_need_freq(void); + +void speech_process_init(int tx_sample_rate, int tx_channel_num, int tx_sample_bit, + int rx_sample_rate, int rx_channel_num, int rx_sample_bit, + int tx_frame_ms, int rx_frame_ms, + int tx_send_channel_num, int rx_recv_channel_num); +void speech_process_deinit(void); +void speech_process_capture_run(uint8_t *buf, uint32_t *len); +void speech_process_playback_run(uint8_t *buf, uint32_t *len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tests/anc_usb/usb_audio_app.c b/tests/anc_usb/usb_audio_app.c new file mode 100644 index 0000000..0ab47a7 --- /dev/null +++ b/tests/anc_usb/usb_audio_app.c @@ -0,0 +1,6266 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "hal_timer.h" +#include "hal_trace.h" +#include "hal_sysfreq.h" +#include "hal_aud.h" +#include "hal_sleep.h" +#include "hal_location.h" +#include "hal_codec.h" +#include "string.h" +#include "pmu.h" +#include "analog.h" +#include "audioflinger.h" +#include "usb_audio.h" +#include "usb_audio_sync.h" +#include "usb_audio_app.h" +#include "usb_audio_frm_defs.h" +#include "cmsis.h" +#include "safe_queue.h" +#include "memutils.h" +#include "tgt_hardware.h" +#include "audio_resample_ex.h" +#include "resample_coef.h" + +#ifdef _VENDOR_MSG_SUPPT_ +#include "usb_vendor_msg.h" +#endif + +#if defined(USB_AUDIO_SPEECH) +#include "speech_process.h" +#include "app_overlay.h" +#endif + +#if defined(__HW_FIR_DSD_PROCESS__) +#include "dsd_process.h" +#endif + +#if defined(AUDIO_ANC_FB_MC) +#include"anc_process.h" +#endif + +#include "hw_codec_iir_process.h" +#include "hw_iir_process.h" + +#ifdef __AUDIO_RESAMPLE__ +#ifdef SW_PLAYBACK_RESAMPLE +#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) +#error "Software playback resample conflicts with ANC/AuxMic" +#endif +#else +#ifdef CHIP_BEST1000 +#error "No hardware playback resample support" +#endif +#endif + +#ifndef SW_CAPTURE_RESAMPLE +#if defined(CHIP_BEST1000) || defined(CHIP_BEST2000) +#error "No hardware capture resample support" +#endif +#endif +#endif // __AUDIO_RESAMPLE__ + +#ifdef CODEC_DSD +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__)|| defined(__HW_IIR_EQ_PROCESS__) || defined(__HW_DAC_IIR_EQ_PROCESS__) +#error "EQ conflicts with CODEC_DSD" +#endif +#ifdef FREQ_RESP_EQ +#error "FREQ_RESP_EQ conflicts with CODEC_DSD" +#endif +#ifdef __HW_FIR_DSD_PROCESS__ +#error "__HW_FIR_DSD_PROCESS__ conflicts with CODEC_DSD" +#endif +#ifdef AUDIO_ANC_FB_MC +#error "AUDIO_ANC_FB_MC conflicts with CODEC_DSD" +#endif +#ifdef NOISE_GATING +#error "NOISE_GATING conflicts with CODEC_DSD" +#endif +#ifdef NOISE_REDUCTION +#error "NOISE_REDUCTION conflicts with CODEC_DSD" +#endif +#endif + +#if defined(__SW_IIR_EQ_PROCESS__) +static uint8_t audio_eq_sw_iir_index = 0; +extern const IIR_CFG_T * const audio_eq_sw_iir_cfg_list[]; +#endif + +#if defined(__HW_FIR_EQ_PROCESS__) +static uint8_t audio_eq_hw_fir_index = 0; +extern const FIR_CFG_T * const audio_eq_hw_fir_cfg_list[]; +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) +static uint8_t audio_eq_hw_dac_iir_index = 0; +extern const IIR_CFG_T * const audio_eq_hw_dac_iir_cfg_list[]; +#endif + +#if defined(__HW_IIR_EQ_PROCESS__) +static uint8_t audio_eq_hw_iir_index = 0; +extern const IIR_CFG_T * const audio_eq_hw_iir_cfg_list[]; +#endif + +#define KEY_TRACE +//#define UNMUTE_WHEN_SET_VOL +#define STREAM_RATE_BITS_SETUP + +#if defined(USB_AUDIO_DYN_CFG) && defined(ANC_L_R_MISALIGN_WORKAROUND) +#ifndef AUDIO_PLAYBACK_24BIT +//#define AUDIO_PLAYBACK_24BIT +#endif +#endif + +#if defined(__HW_FIR_DSD_PROCESS__) || defined(CODEC_DSD) +#define DSD_SUPPORT +#endif + +#ifdef TARGET_TO_MAX_DIFF +#if defined(USB_AUDIO_RECV_ENABLE) && defined(USB_AUDIO_SEND_ENABLE) +#if defined(__AUDIO_RESAMPLE__) && defined(PLL_TUNE_SAMPLE_RATE) +#define UAUD_SYNC_STREAM_TARGET +#else +#error "TARGET_TO_MAX_DIFF can be enabled only with __AUDIO_RESAMPLE__ and PLL_TUNE_SAMPLE_RATE if both playback and capture streams exist" +#endif +#endif + +#ifdef USB_AUDIO_MULTIFUNC +#error "TARGET_TO_MAX_DIFF can NOT be enabled with USB_AUDIO_MULTIFUNC" +#endif +#endif // TARGET_TO_MAX_DIFF + +#define VERBOSE_TRACE 0 //0xFFFF + +#ifdef TIMER1_BASE +#define TRACE_TIME(num,s, ...) TRACE(num+1,"[%u] " s, FAST_TICKS_TO_US(hal_fast_sys_timer_get()), ##__VA_ARGS__) +#else +#define TRACE_TIME(num,s, ...) TRACE(num+1,"[%X] " s, hal_sys_timer_get(), ##__VA_ARGS__) +#endif + +#define USB_AUDIO_CPU_WAKE_USER HAL_CPU_WAKE_LOCK_USER_3 + +#define RECV_PAUSED_SAMPLE_RATE_FLAG (1 << 31) + +#define DIFF_ERR_THRESH_PLAYBACK (sample_rate_recv / 1000 / 2) +#define DIFF_ERR_THRESH_CAPTURE (sample_rate_send / 1000 / 2) + +#define DIFF_SYNC_THRESH_PLAYBACK 10 +#define DIFF_SYNC_THRESH_CAPTURE 10 + +#define DIFF_AVG_CNT 30 + +#define MAX_TARGET_RATIO 0.000020f + +#define MIN_VOLUME_VAL (TGT_VOLUME_LEVEL_MUTE) +#define MAX_VOLUME_VAL (TGT_VOLUME_LEVEL_QTY - 1) + +#define MIN_CAP_VOLUME_VAL (TGT_ADC_VOL_LEVEL_0) +#define MAX_CAP_VOLUME_VAL (TGT_ADC_VOL_LEVEL_QTY - 1) + +#define NOISE_GATING_INTERVAL MS_TO_TICKS(800) +#define NOISE_GATING_THRESH_16BIT 3 // -80dB +#define NOISE_GATING_THRESH_24BIT (NOISE_GATING_THRESH_16BIT << 8) + +#define NOISE_REDUCTION_INTERVAL MS_TO_TICKS(100) +#define NOISE_REDUCTION_MATCH_CNT 200 +#define NOISE_REDUCTION_THRESH_16BIT 100 // -50dB +#define NOISE_REDUCTION_THRESH_24BIT (NOISE_REDUCTION_THRESH_16BIT << 8) + +#define CONFLICT_CMD_TRIG_COUNT 10 +#define CONFLICT_CMD_TRIG_INTERVAL MS_TO_TICKS(20000) +#define CONFLICT_STATE_RESET_INTERVAL MS_TO_TICKS(10000) + +#define CAPTURE_STABLE_INTERVAL MS_TO_TICKS(200) + +#define USB_MAX_XFER_INTERVAL MS_TO_TICKS(10) + +#define USB_XFER_ERR_REPORT_INTERVAL MS_TO_TICKS(5000) + +#define USB_AUDIO_MIN_DBVAL (-99) + +#define USB_AUDIO_VOL_UPDATE_STEP 0.00002 + +#ifndef USB_AUDIO_KEY_MAP +#ifdef ANDROID_ACCESSORY_SPEC +#ifdef ANDROID_VOICE_CMD_KEY +#define USB_AUDIO_KEY_VOICE_CMD \ + { USB_AUDIO_HID_VOICE_CMD, HAL_KEY_CODE_FN4, KEY_EVENT_SET2(DOWN, UP), }, +#else +#define USB_AUDIO_KEY_VOICE_CMD +#endif +#define USB_AUDIO_KEY_MAP { \ + { USB_AUDIO_HID_PLAY_PAUSE, HAL_KEY_CODE_FN1, KEY_EVENT_SET2(DOWN, UP), }, \ + { USB_AUDIO_HID_VOL_UP, HAL_KEY_CODE_FN2, KEY_EVENT_SET2(DOWN, UP), }, \ + { USB_AUDIO_HID_VOL_DOWN, HAL_KEY_CODE_FN3, KEY_EVENT_SET2(DOWN, UP), }, \ + USB_AUDIO_KEY_VOICE_CMD \ +} +#else +#define USB_AUDIO_KEY_MAP { \ + { USB_AUDIO_HID_PLAY_PAUSE, HAL_KEY_CODE_FN1, KEY_EVENT_SET(CLICK), }, \ + { USB_AUDIO_HID_SCAN_NEXT, HAL_KEY_CODE_FN1, KEY_EVENT_SET(DOUBLECLICK), }, \ + { USB_AUDIO_HID_SCAN_PREV, HAL_KEY_CODE_FN1, KEY_EVENT_SET(TRIPLECLICK), }, \ + { USB_AUDIO_HID_VOL_UP, HAL_KEY_CODE_FN2, KEY_EVENT_SET4(CLICK, DOUBLECLICK, TRIPLECLICK, REPEAT), }, \ + { USB_AUDIO_HID_VOL_DOWN, HAL_KEY_CODE_FN3, KEY_EVENT_SET4(CLICK, DOUBLECLICK, TRIPLECLICK, REPEAT), }, \ + { USB_AUDIO_HID_HOOK_SWITCH, HAL_KEY_CODE_FN4, KEY_EVENT_SET(CLICK), }, \ +} +#endif +#endif + +enum AUDIO_CMD_T { + AUDIO_CMD_START_PLAY = 0, + AUDIO_CMD_STOP_PLAY, + AUDIO_CMD_START_CAPTURE, + AUDIO_CMD_STOP_CAPTURE, + AUDIO_CMD_SET_VOLUME, + AUDIO_CMD_SET_CAP_VOLUME, + AUDIO_CMD_MUTE_CTRL, + AUDIO_CMD_CAP_MUTE_CTRL, + AUDIO_CMD_USB_RESET, + AUDIO_CMD_USB_DISCONNECT, + AUDIO_CMD_USB_CONFIG, + AUDIO_CMD_USB_SLEEP, + AUDIO_CMD_USB_WAKEUP, + AUDIO_CMD_RECV_PAUSE, + AUDIO_CMD_RECV_CONTINUE, + AUDIO_CMD_SET_RECV_RATE, + AUDIO_CMD_SET_SEND_RATE, + AUDIO_CMD_RESET_CODEC, + AUDIO_CMD_NOISE_GATING, + AUDIO_CMD_NOISE_REDUCTION, + AUDIO_CMD_TUNE_RATE, + AUDIO_CMD_SET_DSD_CFG, + + TEST_CMD_PERF_TEST_POWER, + TEST_CMD_PA_ON_OFF, + + AUDIO_CMD_QTY +}; + +enum AUDIO_ITF_STATE_T { + AUDIO_ITF_STATE_STOPPED = 0, + AUDIO_ITF_STATE_STARTED, +}; + +enum AUDIO_STREAM_REQ_USER_T { + AUDIO_STREAM_REQ_USB = 0, + AUDIO_STREAM_REQ_ANC, + + AUDIO_STREAM_REQ_USER_QTY, + AUDIO_STREAM_REQ_USER_ALL = AUDIO_STREAM_REQ_USER_QTY, +}; + +enum AUDIO_STREAM_STATUS_T { + AUDIO_STREAM_OPENED = 0, + AUDIO_STREAM_STARTED, + + AUDIO_STREAM_STATUS_QTY +}; + +enum AUDIO_STREAM_RUNNING_T { + AUDIO_STREAM_RUNNING_NULL, + AUDIO_STREAM_RUNNING_ENABLED, + AUDIO_STREAM_RUNNING_DISABLED, +}; + +enum CODEC_CONFIG_LOCK_USER_T { + CODEC_CONFIG_LOCK_RESTART_PLAY, + CODEC_CONFIG_LOCK_RESTART_CAP, + + CODEC_CONFIG_LOCK_USER_QTY +}; + +enum CODEC_MUTE_USER_T { + CODEC_MUTE_USER_CMD, + CODEC_MUTE_USER_NOISE_GATING, + + CODEC_MUTE_USER_QTY, + CODEC_MUTE_USER_ALL = CODEC_MUTE_USER_QTY, +}; + +struct USB_AUDIO_KEY_MAP_T { + enum USB_AUDIO_HID_EVENT_T hid_event; + enum HAL_KEY_CODE_T key_code; + uint32_t key_event_bitset; +}; + +STATIC_ASSERT(8 * sizeof(((struct USB_AUDIO_KEY_MAP_T *)0)->key_event_bitset) >= HAL_KEY_EVENT_NUM, + "key_event_bitset size is too small"); + +#ifdef USB_AUDIO_DYN_CFG + +static enum AUD_SAMPRATE_T sample_rate_play; +static enum AUD_SAMPRATE_T sample_rate_cap; +static enum AUD_SAMPRATE_T sample_rate_recv; +static enum AUD_SAMPRATE_T sample_rate_send; +static enum AUD_SAMPRATE_T new_sample_rate_recv; +static enum AUD_SAMPRATE_T new_sample_rate_send; +#ifdef AUDIO_PLAYBACK_24BIT +static +#ifndef CODEC_DSD + const +#endif + uint8_t sample_size_play = 4; +#else +static uint8_t sample_size_play; +#endif +static const uint8_t sample_size_cap = SAMPLE_SIZE_CAPTURE; +static uint8_t sample_size_recv; +static const uint8_t sample_size_send = SAMPLE_SIZE_SEND; +static uint8_t new_sample_size_recv; + +#else // !USB_AUDIO_DYN_CFG + +static const enum AUD_SAMPRATE_T sample_rate_play = SAMPLE_RATE_PLAYBACK; +static const enum AUD_SAMPRATE_T sample_rate_cap = SAMPLE_RATE_CAPTURE; +static const enum AUD_SAMPRATE_T sample_rate_recv = SAMPLE_RATE_RECV; +static const enum AUD_SAMPRATE_T sample_rate_send = SAMPLE_RATE_SEND; +static +#ifndef CODEC_DSD + const +#endif + uint8_t sample_size_play = SAMPLE_SIZE_PLAYBACK; +static const uint8_t sample_size_cap = SAMPLE_SIZE_CAPTURE; +static const uint8_t sample_size_recv = SAMPLE_SIZE_RECV; +static const uint8_t sample_size_send = SAMPLE_SIZE_SEND; + +#endif // !USB_AUDIO_DYN_CFG + +#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) +#ifdef USB_AUDIO_DYN_CFG +static enum AUD_SAMPRATE_T sample_rate_ref_cap; +#else // !USB_AUDIO_DYN_CFG +#ifdef __AUDIO_RESAMPLE__ +static const enum AUD_SAMPRATE_T sample_rate_ref_cap = SAMPLE_RATE_CAPTURE; +#elif defined(USB_AUDIO_16K) +static const enum AUD_SAMPRATE_T sample_rate_ref_cap = SAMPLE_RATE_CAPTURE; +#else +static const enum AUD_SAMPRATE_T sample_rate_ref_cap = (SAMPLE_RATE_RECV % AUD_SAMPRATE_8000) ? AUD_SAMPRATE_44100 : AUD_SAMPRATE_48000; +#endif +#endif // !USB_AUDIO_DYN_CFG +#endif // (CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) + +static enum AUDIO_ITF_STATE_T playback_state = AUDIO_ITF_STATE_STOPPED; +static enum AUDIO_ITF_STATE_T capture_state = AUDIO_ITF_STATE_STOPPED; +static enum AUDIO_ITF_STATE_T recv_state = AUDIO_ITF_STATE_STOPPED; +static enum AUDIO_ITF_STATE_T send_state = AUDIO_ITF_STATE_STOPPED; + +static uint8_t codec_stream_map[AUD_STREAM_NUM][AUDIO_STREAM_STATUS_QTY]; +static uint8_t eq_opened; +static enum AUDIO_STREAM_RUNNING_T streams_running_req; + +static uint8_t playback_paused; + +static uint8_t playback_conflicted; +static uint8_t capture_conflicted; + +#ifdef NOISE_GATING +enum NOISE_GATING_CMD_T { + NOISE_GATING_CMD_NULL, + NOISE_GATING_CMD_MUTE, + NOISE_GATING_CMD_UNMUTE, +}; +static enum NOISE_GATING_CMD_T noise_gating_cmd = NOISE_GATING_CMD_NULL; +static uint32_t last_high_signal_time; + +#ifdef NOISE_REDUCTION +enum NOISE_REDUCTION_CMD_T { + NOISE_REDUCTION_CMD_NULL, + NOISE_REDUCTION_CMD_FIRE, + NOISE_REDUCTION_CMD_RESTORE, +}; +static enum NOISE_REDUCTION_CMD_T noise_reduction_cmd = NOISE_REDUCTION_CMD_NULL; +static bool nr_active; +static bool prev_samp_positive[2]; +static uint16_t prev_zero_diff[2][2]; +static uint16_t cur_zero_diff[2][2]; +static uint16_t nr_cont_cnt; +static uint32_t last_nr_restore_time; + +static void restore_noise_reduction_status(void); +#endif +#endif + +static uint8_t *playback_buf; +static uint32_t playback_size; +static uint32_t playback_pos; + +#ifdef AUDIO_ANC_FB_MC +static int32_t playback_samplerate_ratio; +#endif + +static uint8_t *capture_buf; +static uint32_t capture_size; +static uint32_t capture_pos; + +static uint8_t *playback_eq_buf; +static uint32_t playback_eq_size; + +#ifdef USB_AUDIO_DYN_CFG +#ifdef KEEP_SAME_LATENCY +static uint32_t playback_max_size; +static uint32_t capture_max_size; +static uint32_t usb_recv_max_size; +static uint32_t usb_send_max_size; +#endif +static uint8_t playback_itf_set; +static uint8_t capture_itf_set; +#endif + +#ifdef SW_CAPTURE_RESAMPLE +static RESAMPLE_ID resample_id; +static bool resample_cap_enabled; +static uint8_t *resample_history_buf; +static uint32_t resample_history_size; +static uint8_t *resample_input_buf; +static uint32_t resample_input_size; +#endif + +static uint8_t *usb_recv_buf; +static uint32_t usb_recv_size; +static uint32_t usb_recv_rpos; +static uint32_t usb_recv_wpos; + +static uint8_t *usb_send_buf; +static uint32_t usb_send_size; +static uint32_t usb_send_rpos; +static uint32_t usb_send_wpos; + +static uint8_t usb_configured; + +static uint8_t usb_recv_valid; +static uint8_t usb_send_valid; + +static uint8_t usb_recv_init_rpos; +static uint8_t usb_send_init_wpos; + +static uint8_t codec_play_seq; +static uint8_t codec_cap_seq; +static volatile uint8_t usb_recv_seq; +static volatile uint8_t usb_send_seq; + +static uint8_t codec_play_valid; +static uint8_t codec_cap_valid; + +#ifdef USB_AUDIO_MULTIFUNC +static const uint8_t playback_vol = AUDIO_OUTPUT_VOLUME_DEFAULT; +#else +static uint8_t playback_vol; +#endif +static uint8_t new_playback_vol; +static uint8_t new_mute_state; +static uint8_t mute_user_map; +STATIC_ASSERT(sizeof(mute_user_map) * 8 >= CODEC_MUTE_USER_QTY, "mute_user_map size too small"); + +static uint8_t capture_vol; +static uint8_t new_capture_vol; +static uint8_t new_cap_mute_state; + +static uint32_t last_usb_recv_err_time; +static uint32_t usb_recv_err_cnt; +static uint32_t usb_recv_ok_cnt; + +static uint32_t last_usb_send_err_time; +static uint32_t usb_send_err_cnt; +static uint32_t usb_send_ok_cnt; + +#ifdef USB_AUDIO_MULTIFUNC +static uint8_t playback_conflicted2; +static enum AUDIO_ITF_STATE_T recv2_state = AUDIO_ITF_STATE_STOPPED; +static uint8_t *usb_recv2_buf; +static uint32_t usb_recv2_size; +static uint32_t usb_recv2_rpos; +static uint32_t usb_recv2_wpos; +static uint8_t usb_recv2_valid; +static uint8_t usb_recv2_init_rpos; +static uint8_t new_playback2_vol; +static uint8_t new_mute2_state; +static float new_playback_coef; +static float new_playback2_coef; +static float playback_coef; +static float playback2_coef; + +static uint32_t last_usb_recv2_err_time; +static uint32_t usb_recv2_err_cnt; +static uint32_t usb_recv2_ok_cnt; + +static float playback_gain_to_float(uint32_t level); +#endif + +static uint8_t codec_config_lock; +STATIC_ASSERT(sizeof(codec_config_lock) * 8 >= CODEC_CONFIG_LOCK_USER_QTY, "codec_config_lock size too small"); + +static struct USB_AUDIO_STREAM_INFO_T playback_info; +static struct USB_AUDIO_STREAM_INFO_T capture_info; + +static uint8_t nonconflict_start; +static uint16_t conflict_cnt; +static uint32_t conflict_time; +static uint32_t nonconflict_time; + +static uint32_t codec_cap_start_time; + +static uint32_t last_usb_recv_time; +static uint32_t last_usb_send_time; + +#define CMD_LIST_SIZE 30 +static uint32_t cmd_list[CMD_LIST_SIZE]; +static uint32_t cmd_watermark; +static struct SAFE_QUEUE_T cmd_queue; + +#define EXTRACT_CMD(d) ((d) & 0xFF) +#define EXTRACT_SEQ(d) (((d) >> 8) & 0xFF) +#define EXTRACT_ARG(d) (((d) >> 16) & 0xFF) +#define MAKE_QUEUE_DATA(c, s, a) (((c) & 0xFF) | ((s) & 0xFF) << 8 | ((a) & 0xFF) << 16) +STATIC_ASSERT(AUDIO_CMD_QTY <= 0xFF, "audio cmd num exceeds size in queue"); +STATIC_ASSERT(USB_AUDIO_STATE_EVENT_QTY <= 0xFF, "uaud evt num exceeds size in queue"); +STATIC_ASSERT(sizeof(usb_recv_seq) <= 1, "usb recv seq exceeds size in queue"); +STATIC_ASSERT(sizeof(usb_send_seq) <= 1, "usb send seq exceeds size in queue"); + +static const struct USB_AUDIO_KEY_MAP_T key_map[] = USB_AUDIO_KEY_MAP; + +#ifdef PERF_TEST_POWER_KEY +static enum HAL_CODEC_PERF_TEST_POWER_T perft_power_type; +#endif +#ifdef PA_ON_OFF_KEY +static bool pa_on_off_muted; +#endif + +static float rate_tune_ratio[AUD_STREAM_NUM]; + +#ifdef DSD_SUPPORT +static bool usb_dsd_enabled; +static bool codec_dsd_enabled; +static uint16_t usb_dsd_cont_cnt = 0; +#ifdef CODEC_DSD +static uint8_t dsd_saved_sample_size; +#endif +#endif + +#ifdef BT_USB_AUDIO_DUAL_MODE +static USB_AUDIO_ENQUEUE_CMD_CALLBACK enqueue_cmd_cb; +#endif + +static void enqueue_unique_cmd(enum AUDIO_CMD_T cmd); +static void usb_audio_set_codec_volume(enum AUD_STREAM_T stream, uint8_t vol); +static void usb_audio_cmd_tune_rate(enum AUD_STREAM_T stream); + +#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) + +extern void damic_init(void); +extern void damic_deinit(void); + +// second-order IR filter +short soir_filter(int32_t PcmValue) +{ + float gain = 2.0F; + const float NUM[3] = {0.013318022713065147, 0.02375408448278904, 0.010780527256429195}; + const float DEN[3] = {1, -1.6983977556228638, 0.74625039100646973}; + + static float y0 = 0, y1 = 0, y2 = 0, x0 = 0, x1 = 0, x2 = 0; + int32_t PcmOut = 0; + + // Left channel + x0 = PcmValue* gain; + y0 = x0*NUM[0] + x1*NUM[1] + x2*NUM[2] - y1*DEN[1] - y2*DEN[2]; + y2 = y1; + y1 = y0; + x2 = x1; + x1 = x0; + + PcmOut = (int32_t)y0; + + PcmOut = __SSAT(PcmOut,16); + + return (short)PcmOut; +} + +#ifdef DUAL_AUX_MIC_MORE_FILTER +// second-order IR filter +short soir_filter1(int32_t PcmValue) +{ + //float gain = 0.003031153698; + const float NUM[3] = {0.013318022713065147, 0.02375408448278904, 0.010780527256429195}; + const float DEN[3] = {1, -1.6983977556228638, 0.74625039100646973}; + + static float y0 = 0, y1 = 0, y2 = 0, x0 = 0, x1 = 0, x2 = 0; + int32_t PcmOut = 0; + + // Left channel + //x0 = PcmValue* gain; + x0 = PcmValue; + y0 = x0*NUM[0] + x1*NUM[1] + x2*NUM[2] - y1*DEN[1] - y2*DEN[2]; + y2 = y1; + y1 = y0; + x2 = x1; + x1 = x0; + + PcmOut = (int32_t)y0; + + PcmOut = __SSAT(PcmOut,16); + + return (short)PcmOut; +} + +// second-order IR filter +short soir_filter2(int32_t PcmValue) +{ + //float gain = 0.003031153698; + const float NUM[3] = {0.013318022713065147, 0.02375408448278904, 0.010780527256429195}; + const float DEN[3] = {1, -1.6983977556228638, 0.74625039100646973}; + + static float y0 = 0, y1 = 0, y2 = 0, x0 = 0, x1 = 0, x2 = 0; + int32_t PcmOut = 0; + + // Left channel + //x0 = PcmValue* gain; + x0 = PcmValue; + y0 = x0*NUM[0] + x1*NUM[1] + x2*NUM[2] - y1*DEN[1] - y2*DEN[2]; + y2 = y1; + y1 = y0; + x2 = x1; + x1 = x0; + + PcmOut = (int32_t)y0; + + PcmOut = __SSAT(PcmOut,16); + + return (short)PcmOut; +} +#endif + +static float s_f_amic3_dc; +static float s_f_amic4_dc; +static short s_amic3_dc; +static short s_amic4_dc; + +static void init_amic_dc (void) +{ + s_amic3_dc = 0; + s_amic4_dc = 0; + s_f_amic3_dc = 0.0; + s_f_amic4_dc = 0.0; +} + +static void get_amic_dc (short* src, uint32_t samp_cnt, uint32_t step) +{ + uint32_t i = 0; + + float u3_1 = 0.00001; + float u3_2 = 1 - u3_1; + + float u4_1 = 0.00001; + float u4_2 = 1 - u4_1; + + for (i = 0; i < samp_cnt; i+=(2< AUD_SAMPRATE_96000) { + // Sample rate higher than 96K will require higher system freq, which consumes more power + return 0; + } + + int32_t *src_buf = (int32_t *)buf; + int32_t *dst_buf = (int32_t *)buf; + uint32_t mono_samp_num = len / 2 / sample_size_play; + int32_t start_idx, in_idx, coef_idx; + int32_t in_l, in_r; + float out_l, out_r; + uint8_t new_seq_idx = !freq_resp_eq_hist_idx; + + if (mono_samp_num >= (FREQ_RESP_EQ_COEF_NUM - 1)) { + start_idx = (mono_samp_num - FREQ_RESP_EQ_COEF_NUM + 1) * 2; + for (in_idx = 0; in_idx < (FREQ_RESP_EQ_COEF_NUM - 1) * 2; in_idx++) { + freq_resp_eq_hist[new_seq_idx][in_idx] = src_buf[start_idx + in_idx]; + } + } else { + start_idx = (FREQ_RESP_EQ_COEF_NUM - 1 - mono_samp_num) * 2; + for (in_idx = 0; in_idx < start_idx; in_idx++) { + freq_resp_eq_hist[new_seq_idx][in_idx] = freq_resp_eq_hist[freq_resp_eq_hist_idx][mono_samp_num * 2 + in_idx]; + } + for (in_idx = 0; in_idx < mono_samp_num * 2; in_idx++) { + freq_resp_eq_hist[new_seq_idx][start_idx + in_idx] = src_buf[in_idx]; + } + } + + for (in_idx = mono_samp_num - 1; in_idx >= 0; in_idx--) { + out_l = 0; + out_r = 0; + for (coef_idx = 0; coef_idx < FREQ_RESP_EQ_COEF_NUM; coef_idx++) { + if (in_idx + coef_idx - FREQ_RESP_EQ_COEF_NUM + 1 >= 0) { + in_l = src_buf[(in_idx + coef_idx - FREQ_RESP_EQ_COEF_NUM + 1) * 2]; + in_r = src_buf[(in_idx + coef_idx - FREQ_RESP_EQ_COEF_NUM + 1) * 2 + 1]; + } else { + in_l = freq_resp_eq_hist[freq_resp_eq_hist_idx][(in_idx + coef_idx) * 2]; + in_r = freq_resp_eq_hist[freq_resp_eq_hist_idx][(in_idx + coef_idx) * 2 + 1]; + } + out_l += in_l * freq_resp_eq_coef[coef_idx]; + out_r += in_r * freq_resp_eq_coef[coef_idx]; + } + + // TODO: Is it really neccessary to round the float? + //dst_buf[in_idx * 2] = __SSAT(ftoi_nearest(out_l), 24); + //dst_buf[in_idx * 2 + 1] = __SSAT(ftoi_nearest(out_r), 24); + dst_buf[in_idx * 2] = __SSAT((int32_t)out_l, 24); + dst_buf[in_idx * 2 + 1] = __SSAT((int32_t)out_r, 24); + } + + freq_resp_eq_hist_idx = new_seq_idx; + + return 0; +} + +#endif // FREQ_RESP_EQ + +static enum AUD_BITS_T sample_size_to_enum_playback(uint32_t size) +{ + if (size == 2) { + return AUD_BITS_16; + } else if (size == 4) { + return AUD_BITS_24; + } else { + ASSERT(false, "%s: Invalid sample size: %u", __FUNCTION__, size); + } + + return 0; +} + +static enum AUD_BITS_T sample_size_to_enum_capture(uint32_t size) +{ + if (size == 2) { + return AUD_BITS_16; + } else if (size == 4) { +#ifdef USB_AUDIO_SEND_32BIT + return AUD_BITS_32; +#else + return AUD_BITS_24; +#endif + } else { + ASSERT(false, "%s: Invalid sample size: %u", __FUNCTION__, size); + } + + return 0; +} + +static enum AUD_CHANNEL_NUM_T chan_num_to_enum(uint32_t num) +{ + return AUD_CHANNEL_NUM_1 + (num - 1); +} + +static uint32_t POSSIBLY_UNUSED byte_to_samp_playback(uint32_t n) +{ +#if defined(USB_AUDIO_DYN_CFG) || defined(CODEC_DSD) + return n / sample_size_play / CHAN_NUM_PLAYBACK; +#else + return BYTE_TO_SAMP_PLAYBACK(n); +#endif +} + +static uint32_t POSSIBLY_UNUSED byte_to_samp_capture(uint32_t n) +{ +#ifdef USB_AUDIO_DYN_CFG + return n / sample_size_cap / CHAN_NUM_CAPTURE; +#else + return BYTE_TO_SAMP_CAPTURE(n); +#endif +} + +static uint32_t POSSIBLY_UNUSED byte_to_samp_recv(uint32_t n) +{ +#ifdef USB_AUDIO_DYN_CFG + return n / sample_size_recv / CHAN_NUM_RECV; +#else + return BYTE_TO_SAMP_RECV(n); +#endif +} + +static uint32_t POSSIBLY_UNUSED byte_to_samp_send(uint32_t n) +{ +#ifdef USB_AUDIO_DYN_CFG + return n / sample_size_send / CHAN_NUM_SEND; +#else + return BYTE_TO_SAMP_SEND(n); +#endif +} + +static uint32_t POSSIBLY_UNUSED samp_to_byte_playback(uint32_t n) +{ +#if defined(USB_AUDIO_DYN_CFG) || defined(CODEC_DSD) + return n * sample_size_play * CHAN_NUM_PLAYBACK; +#else + return SAMP_TO_BYTE_PLAYBACK(n); +#endif +} + +static uint32_t POSSIBLY_UNUSED samp_to_byte_capture(uint32_t n) +{ +#ifdef USB_AUDIO_DYN_CFG + return n * sample_size_cap * CHAN_NUM_CAPTURE; +#else + return SAMP_TO_BYTE_CAPTURE(n); +#endif +} + +static uint32_t POSSIBLY_UNUSED samp_to_byte_recv(uint32_t n) +{ +#ifdef USB_AUDIO_DYN_CFG + return n * sample_size_recv * CHAN_NUM_RECV; +#else + return SAMP_TO_BYTE_RECV(n); +#endif +} + +static uint32_t POSSIBLY_UNUSED samp_to_byte_send(uint32_t n) +{ +#ifdef USB_AUDIO_DYN_CFG + return n * sample_size_send * CHAN_NUM_SEND; +#else + return SAMP_TO_BYTE_SEND(n); +#endif +} + +static uint32_t playback_to_recv_len(uint32_t n) +{ +#if defined(USB_AUDIO_DYN_CFG) || defined(CODEC_DSD) + uint32_t len; + + // 1) When changing recv sample rate, the play stream will be stopped and then restarted. + // So when calculating the len, play sample rate has been changed according to recv sample rate. + // 2) Play and recv sample rates are integral multiple of each other. + + len = samp_to_byte_recv(byte_to_samp_playback(n)); + if (sample_rate_recv == sample_rate_play) { + return len; + } else if (sample_rate_recv < sample_rate_play) { + return len / (sample_rate_play / sample_rate_recv); + } else { + return len * (sample_rate_recv / sample_rate_play); + } +#else + return PLAYBACK_TO_RECV_LEN(n); +#endif +} + +static uint32_t capture_to_send_len(uint32_t n) +{ +#ifdef USB_AUDIO_DYN_CFG + uint32_t len; + enum AUD_SAMPRATE_T send_rate; + enum AUD_SAMPRATE_T cap_rate; + + // 1) When changing send sample rate, the cap stream will not be changed if the play stream is active. + // Moreover, the cap stream might be changed if changing recv sample rate (and then play sample rate). + // So when calculating the len, cap sample rate might be inconsistent with send sample rate. + // 2) Resample might be applied to the cap stream. Cap and send sample rates have no integral multiple relationship. + + send_rate = sample_rate_send; + cap_rate = sample_rate_cap; + + len = samp_to_byte_send(byte_to_samp_capture(n)); + if (send_rate == cap_rate) { + return len; + } else { + // Unlikely to overflow for the max send_rate is 48000 + return ALIGN((len * send_rate + cap_rate - 1) / cap_rate, sample_size_send * CHAN_NUM_SEND); + } +#else + return CAPTURE_TO_SEND_LEN(n); +#endif +} + +#ifdef USB_AUDIO_DYN_CFG +static uint32_t POSSIBLY_UNUSED capture_to_ref_len(uint32_t n) +{ + uint32_t len; + + len = samp_to_byte_send(byte_to_samp_capture(n)); + +#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) + // Capture reference sample rate and capture sample rate are integral multiple of each other. + + if (sample_rate_ref_cap == sample_rate_cap) { + return len; + } else if (sample_rate_ref_cap < sample_rate_cap) { + return len / (sample_rate_cap / sample_rate_ref_cap); + } else { + return len * (sample_rate_ref_cap / sample_rate_cap); + } +#else + return len; +#endif +} + +#ifdef KEEP_SAME_LATENCY +static uint32_t calc_usb_recv_size(enum AUD_SAMPRATE_T rate, uint8_t sample_size) +{ + uint32_t size; + size = (SAMP_RATE_TO_FRAME_SIZE(rate) * sample_size * CHAN_NUM_RECV) * (usb_recv_max_size / MAX_FRAME_SIZE_RECV); + return NON_EXP_ALIGN(size, RECV_BUFF_ALIGN); +} + +static uint32_t calc_usb_send_size(enum AUD_SAMPRATE_T rate) +{ + uint32_t size; + size = samp_to_byte_send(SAMP_RATE_TO_FRAME_SIZE(rate)) * usb_send_max_size / MAX_FRAME_SIZE_SEND; + return NON_EXP_ALIGN(size, SEND_BUFF_ALIGN); +} + +static uint32_t calc_playback_size(enum AUD_SAMPRATE_T rate) +{ + uint32_t size; + size = samp_to_byte_playback(SAMP_RATE_TO_FRAME_SIZE(rate)) * (playback_max_size / MAX_FRAME_SIZE_PLAYBACK); + return NON_EXP_ALIGN(size, DAC_BUFF_ALIGN); +} + +static uint32_t calc_capture_size(enum AUD_SAMPRATE_T rate) +{ + uint32_t size; + size = samp_to_byte_capture(SAMP_RATE_TO_FRAME_SIZE(rate)) * (capture_max_size / MAX_FRAME_SIZE_CAPTURE); + return NON_EXP_ALIGN(size, ADC_BUFF_ALIGN); +} +#endif +#endif + +static void record_conflict(int conflicted) +{ + uint32_t lock; + uint32_t interval; + bool reset = false; + + lock = int_lock(); + + if (conflicted) { + nonconflict_start = 0; + if (conflict_cnt == 0) { + conflict_time = hal_sys_timer_get(); + } + conflict_cnt++; + + if (conflict_cnt >= CONFLICT_CMD_TRIG_COUNT) { + interval = hal_sys_timer_get() - conflict_time; + if (interval < CONFLICT_CMD_TRIG_INTERVAL) { + //TRACE(2,"RESET CODEC: conflict cnt=%u interval=%u ms", conflict_cnt, TICKS_TO_MS(interval)); + reset = true; + } + conflict_cnt = 0; + } + } else { + if (nonconflict_start == 0) { + nonconflict_start = 1; + if (conflict_cnt) { + nonconflict_time = hal_sys_timer_get(); + } + } else { + if (conflict_cnt) { + interval = hal_sys_timer_get() - nonconflict_time; + if (interval >= CONFLICT_STATE_RESET_INTERVAL) { + //TRACE(2,"RESET CONFLICT STATE: conflict cnt=%u nonconflict interval=%u ms", conflict_cnt, TICKS_TO_MS(interval)); + conflict_cnt = 0; + } + } + } + } + + int_unlock(lock); + + if (reset) { + // Avoid invoking cmd callback when irq is locked + enqueue_unique_cmd(AUDIO_CMD_RESET_CODEC); + } +} + +static void reset_conflict(void) +{ + uint32_t lock; + + lock = int_lock(); + conflict_cnt = 0; + nonconflict_start = 0; + int_unlock(lock); +} + +uint8_t usb_audio_get_eq_index(AUDIO_EQ_TYPE_T audio_eq_type,uint8_t anc_status) +{ + uint8_t index_eq=0; + +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__)|| defined(__HW_DAC_IIR_EQ_PROCESS__)|| defined(__HW_IIR_EQ_PROCESS__) + switch (audio_eq_type) + { +#if defined(__SW_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_SW_IIR: + { + if(anc_status) + { + index_eq=audio_eq_sw_iir_index+1; + } + else + { + index_eq=audio_eq_sw_iir_index; + } + + } + break; +#endif + +#if defined(__HW_FIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_FIR: + { +#ifdef USB_AUDIO_DYN_CFG + if(sample_rate_recv == AUD_SAMPRATE_44100) { + index_eq = 0; + } else if(sample_rate_recv == AUD_SAMPRATE_48000) { + index_eq = 1; + } else if(sample_rate_recv == AUD_SAMPRATE_96000) { + index_eq = 2; + } else if(sample_rate_recv == AUD_SAMPRATE_192000) { + index_eq = 3; + } else { + ASSERT(0, "[%s] sample_rate_recv(%d) is not supported", __func__, sample_rate_recv); + } + audio_eq_hw_fir_index=index_eq; +#else + index_eq=audio_eq_hw_fir_index; +#endif + if(anc_status) + { + index_eq=index_eq+4; + } + } + break; +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_DAC_IIR: + { + if(anc_status) + { + index_eq=audio_eq_hw_dac_iir_index+1; + } + else + { + index_eq=audio_eq_hw_dac_iir_index; + } + } + break; +#endif + +#if defined(__HW_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_IIR: + { + if(anc_status) + { + index_eq=audio_eq_hw_iir_index+1; + } + else + { + index_eq=audio_eq_hw_iir_index; + } + } + break; +#endif + default: + { + ASSERT(false,"[%s]Error eq type!",__func__); + } + } +#endif + return index_eq; +} + + +uint32_t usb_audio_set_eq(AUDIO_EQ_TYPE_T audio_eq_type,uint8_t index) +{ + const FIR_CFG_T *fir_cfg=NULL; + const IIR_CFG_T *iir_cfg=NULL; + + TRACE(3,"[%s]audio_eq_type=%d,index=%d", __func__, audio_eq_type,index); + +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__)|| defined(__HW_DAC_IIR_EQ_PROCESS__)|| defined(__HW_IIR_EQ_PROCESS__) + switch (audio_eq_type) + { +#if defined(__SW_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_SW_IIR: + { + if(index >= EQ_SW_IIR_LIST_NUM) + { + TRACE(2,"[%s] index[%d] > EQ_SW_IIR_LIST_NUM", __func__, index); + return 1; + } + + iir_cfg=audio_eq_sw_iir_cfg_list[index]; + } + break; +#endif + +#if defined(__HW_FIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_FIR: + { + if(index >= EQ_HW_FIR_LIST_NUM) + { + TRACE(2,"[%s] index[%d] > EQ_HW_FIR_LIST_NUM", __func__, index); + return 1; + } + + fir_cfg=audio_eq_hw_fir_cfg_list[index]; + } + break; +#endif + +#if defined(__HW_DAC_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_DAC_IIR: + { + if(index >= EQ_HW_DAC_IIR_LIST_NUM) + { + TRACE(2,"[%s] index[%d] > EQ_HW_DAC_IIR_LIST_NUM", __func__, index); + return 1; + } + + iir_cfg=audio_eq_hw_dac_iir_cfg_list[index]; + } + break; +#endif + +#if defined(__HW_IIR_EQ_PROCESS__) + case AUDIO_EQ_TYPE_HW_IIR: + { + if(index >= EQ_HW_IIR_LIST_NUM) + { + TRACE(2,"[%s] index[%d] > EQ_HW_IIR_LIST_NUM", __func__, index); + return 1; + } + + iir_cfg=audio_eq_hw_iir_cfg_list[index]; + } + break; +#endif + default: + { + ASSERT(false,"[%s]Error eq type!",__func__); + } + } +#endif + + return audio_eq_set_cfg(fir_cfg,iir_cfg,audio_eq_type); +} + +static void set_codec_config_status(enum CODEC_CONFIG_LOCK_USER_T user, bool lock) +{ + if (lock) { + codec_config_lock |= (1 << user); + } else { + codec_config_lock &= ~(1 << user); + } +} + +static void usb_audio_codec_mute(enum CODEC_MUTE_USER_T user) +{ + TRACE(3,"%s: user=%d map=0x%02X", __FUNCTION__, user, mute_user_map); + + if (user >= CODEC_MUTE_USER_QTY || mute_user_map == 0) { + af_stream_mute(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, true); + } + if (user < CODEC_MUTE_USER_QTY) { + mute_user_map |= (1 << user); + } +} + +static void usb_audio_codec_unmute(enum CODEC_MUTE_USER_T user) +{ + uint8_t old_map; + STATIC_ASSERT(sizeof(old_map) * 8 >= CODEC_MUTE_USER_QTY, "old_map size too small"); + + TRACE(3,"%s: user=%d map=0x%02X", __FUNCTION__, user, mute_user_map); + + old_map = mute_user_map; + + if (user < CODEC_MUTE_USER_QTY) { + mute_user_map &= ~(1 << user); + } + if (user >= CODEC_MUTE_USER_QTY || (old_map && mute_user_map == 0)) { + af_stream_mute(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, false); + } +} + +#ifdef AUDIO_ANC_FB_MC + +#define DELAY_SAMPLE_MC (33*2) // 2:ch +static int32_t delay_buf[DELAY_SAMPLE_MC]; +static int32_t mid_p_8_old_l=0; +static int32_t mid_p_8_old_r=0; +static uint32_t audio_mc_data_playback(uint8_t *buf, uint32_t mc_len_bytes) +{ + //uint32_t begin_time; + //uint32_t end_time; + //begin_time = hal_sys_timer_get(); + //TRACE(1,"cancel: %d",begin_time); + + float left_gain; + float right_gain; + uint32_t playback_len_bytes; + int i,j,k; + int delay_sample; + + hal_codec_get_dac_gain(&left_gain,&right_gain); + + //TRACE(1,"playback_samplerate_ratio: %d",playback_samplerate_ratio); + + //TRACE(1,"left_gain: %d",(int)(left_gain*(1<<12))); + //TRACE(1,"right_gain: %d",(int)(right_gain*(1<<12))); + + playback_len_bytes=mc_len_bytes/playback_samplerate_ratio; + + if (sample_size_play == 2) + { + int16_t *sour_p=(int16_t *)(playback_buf+playback_size/2); + int16_t *mid_p=(int16_t *)(buf); + int16_t *mid_p_8=(int16_t *)(buf+mc_len_bytes-mc_len_bytes/8); + int16_t *dest_p=(int16_t *)buf; + int i,j,k; + + if(buf == (playback_buf+playback_size)) + { + sour_p=(int16_t *)playback_buf; + } + + delay_sample=DELAY_SAMPLE_MC; + + for(i=0,j=0;i USB_MAX_XFER_INTERVAL) { +_invalid_play: + zero_mem32(buf, len); + conv_buf = buf; + // If usb recv is stopped, set usb_recv_rpos to the value of usb_recv_wpos -- avoid playing noise. + // Otherwise set usb_recv_rpos to 0 -- avoid buffer conflicts at usb recv startup. + new_rpos = (recv_state == AUDIO_ITF_STATE_STOPPED) ? usb_recv_wpos : 0; + conflicted = 0; +#ifdef USB_AUDIO_MULTIFUNC + new_rpos2 = (recv2_state == AUDIO_ITF_STATE_STOPPED) ? usb_recv2_wpos : 0; + conflicted2 = 0; +#endif + + goto _conv_end; + } + + //---------------------------------------- + // Check conflict + //---------------------------------------- + + usb_len = playback_to_recv_len(len); + conflicted = 0; +#ifdef USB_AUDIO_MULTIFUNC + conflicted2 = 0; +#endif + + lock = int_lock(); + wpos = usb_recv_wpos; + if (init_pos) { + old_rpos = wpos + reset_len; + if (old_rpos >= usb_recv_size) { + old_rpos -= usb_recv_size; + } + usb_recv_rpos = old_rpos; + usb_recv_init_rpos = 1; + } else { + old_rpos = usb_recv_rpos; + } + saved_old_rpos = old_rpos; + new_rpos = usb_recv_rpos + usb_len; + if (new_rpos >= usb_recv_size) { + new_rpos -= usb_recv_size; + } + if (recv_valid && init_pos == 0) { + if (old_rpos <= wpos) { + if (new_rpos < old_rpos || wpos < new_rpos) { + if (recv_state == AUDIO_ITF_STATE_STOPPED) { + if (new_rpos < old_rpos) { + zero_mem(usb_recv_buf + wpos, usb_recv_size - wpos); + zero_mem(usb_recv_buf, new_rpos); + } else { + zero_mem(usb_recv_buf + wpos, new_rpos - wpos); + } + wpos = new_rpos; + usb_recv_wpos = new_rpos; + } else { + conflicted = 1; + } + } + } else { + if (wpos < new_rpos && new_rpos < old_rpos) { + if (recv_state == AUDIO_ITF_STATE_STOPPED) { + zero_mem(usb_recv_buf + wpos, new_rpos - wpos); + wpos = new_rpos; + usb_recv_wpos = new_rpos; + } else { + conflicted = 1; + } + } + } + if (conflicted) { + // Reset read position + old_rpos = wpos + reset_len; + if (old_rpos >= usb_recv_size) { + old_rpos -= usb_recv_size; + } + new_rpos = old_rpos + usb_len; + if (new_rpos >= usb_recv_size) { + new_rpos -= usb_recv_size; + } + // Update global read position + usb_recv_rpos = old_rpos; + } + } + +#ifdef USB_AUDIO_MULTIFUNC + wpos2 = usb_recv2_wpos; + if (init_pos2) { + old_rpos2 = wpos2 + reset_len2; + if (old_rpos2 >= usb_recv2_size) { + old_rpos2 -= usb_recv2_size; + } + usb_recv2_rpos = old_rpos2; + usb_recv2_init_rpos = 1; + } else { + old_rpos2 = usb_recv2_rpos; + } + saved_old_rpos2 = old_rpos2; + new_rpos2 = usb_recv2_rpos + usb_len; + if (new_rpos2 >= usb_recv2_size) { + new_rpos2 -= usb_recv2_size; + } + if (recv2_valid && init_pos2 == 0) { + if (old_rpos2 <= wpos2) { + if (new_rpos2 < old_rpos2 || wpos2 < new_rpos2) { + if (recv2_state == AUDIO_ITF_STATE_STOPPED) { + if (new_rpos2 < old_rpos2) { + zero_mem(usb_recv2_buf + wpos2, usb_recv2_size - wpos2); + zero_mem(usb_recv2_buf, new_rpos2); + } else { + zero_mem(usb_recv2_buf + wpos2, new_rpos2 - wpos2); + } + wpos2 = new_rpos2; + usb_recv2_wpos = new_rpos2; + } else { + conflicted2 = 1; + } + } + } else { + if (wpos2 < new_rpos2 && new_rpos2 < old_rpos2) { + if (recv2_state == AUDIO_ITF_STATE_STOPPED) { + zero_mem(usb_recv2_buf + wpos2, new_rpos2 - wpos2); + wpos2 = new_rpos2; + usb_recv2_wpos = new_rpos2; + } else { + conflicted2 = 1; + } + } + } + if (conflicted2) { + // Reset read position + old_rpos2 = wpos2 + reset_len2; + if (old_rpos2 >= usb_recv2_size) { + old_rpos2 -= usb_recv2_size; + } + new_rpos2 = old_rpos2 + usb_len; + if (new_rpos2 >= usb_recv2_size) { + new_rpos2 -= usb_recv2_size; + } + // Update global read position + usb_recv2_rpos = old_rpos2; + } + } +#endif + int_unlock(lock); + + if (conflicted) { + TRACE(4,"playback: Error: rpos=%u goes beyond wpos=%u with usb_len=%u. Reset to %u", saved_old_rpos, wpos, usb_len, old_rpos); + } +#ifdef USB_AUDIO_MULTIFUNC + if (conflicted2) { + TRACE(4,"playback: Error: rpos2=%u goes beyond wpos2=%u with usb_len=%u. Reset to %u", saved_old_rpos2, wpos2, usb_len, old_rpos2); + } +#endif + +#if (VERBOSE_TRACE & (1 << 0)) + { + int hw_play_pos = af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + uint32_t play_pos = buf - playback_buf; +#ifdef USB_AUDIO_MULTIFUNC + if (recv_valid == 0) { + old_rpos = -1; + wpos = -1; + } + if (recv2_valid == 0) { + old_rpos2 = -1; + wpos2 = -1; + } + TRACE_TIME(8,"playback: rpos=%d/%d usb_len=%d wpos=%d/%d play_pos=%d len=%d hw_play_pos=%d", old_rpos, old_rpos2, usb_len, + wpos, wpos2, play_pos, len, hw_play_pos); +#else + TRACE_TIME(6,"playback: rpos=%d usb_len=%d wpos=%d play_pos=%d len=%d hw_play_pos=%d", old_rpos, usb_len, + wpos, play_pos, len, hw_play_pos); +#endif + } +#endif + + if (codec_play_seq != usb_recv_seq) { + goto _invalid_play; + } + +#ifdef USB_AUDIO_MULTIFUNC + record_conflict(conflicted || conflicted2); +#else + record_conflict(conflicted); +#endif + + //---------------------------------------- + // USB->CODEC stream format conversion start + //---------------------------------------- + + conv_buf = buf; + +#ifdef USB_AUDIO_MULTIFUNC + + { + uint8_t POSSIBLY_UNUSED *cur_buf, *buf_end, *usb_cur_buf, *usb_buf_end, *usb_cur_buf2, *usb_buf_end2; + uint32_t codec_step, usb_step; + float cur_gain, new_gain, cur_gain2, new_gain2, gain_step; + + cur_buf = conv_buf; + buf_end = conv_buf + len; + usb_cur_buf = usb_recv_buf + old_rpos; + usb_buf_end = usb_recv_buf + usb_recv_size; + usb_cur_buf2 = usb_recv2_buf + old_rpos2; + usb_buf_end2 = usb_recv2_buf + usb_recv2_size; + + cur_gain = playback_coef; + new_gain = new_playback_coef; + cur_gain2 = playback2_coef; + new_gain2 = new_playback2_coef; + gain_step = USB_AUDIO_VOL_UPDATE_STEP; + + ASSERT(sample_rate_play == sample_rate_recv, "2:1: Invalid sample_rate_play=%u sample_rate_recv=%u", + sample_rate_play, sample_rate_recv); + + if (0) { + + } else if (sample_size_play == 4 && (sample_size_recv == 4 || sample_size_recv == 3 || sample_size_recv == 2)) { + + int32_t left, right; + int32_t left2, right2; + + if (sample_size_recv == 4) { + usb_step = 8; + } else if (sample_size_recv == 3) { + usb_step = 6; + } else { + usb_step = 4; + } + + codec_step = 8; + + while (cur_buf + codec_step <= buf_end) { + if (usb_cur_buf + usb_step > usb_buf_end) { + usb_cur_buf = usb_recv_buf; + } + if (usb_cur_buf2 + usb_step > usb_buf_end2) { + usb_cur_buf2 = usb_recv2_buf; + } + if (recv_valid) { + if (usb_step == 8) { + left = *(int32_t *)usb_cur_buf; + right = *((int32_t *)usb_cur_buf + 1); + } else if (usb_step == 6) { + left = ((usb_cur_buf[0] << 8) | (usb_cur_buf[1] << 16) | (usb_cur_buf[2] << 24)); + right = ((usb_cur_buf[3] << 8) | (usb_cur_buf[4] << 16) | (usb_cur_buf[5] << 24)); + } else { + left = *(int16_t *)usb_cur_buf << 16; + right = *((int16_t *)usb_cur_buf + 1) << 16; + } + if (cur_gain > new_gain) { + cur_gain -= gain_step; + if (cur_gain < new_gain) { + cur_gain = new_gain; + } + } else if (cur_gain < new_gain) { + cur_gain += gain_step; + if (cur_gain > new_gain) { + cur_gain = new_gain; + } + } + left = (int32_t)(left * cur_gain); + right = (int32_t)(right * cur_gain); + } else { + left = right = 0; + } + if (recv2_valid) { + if (usb_step == 8) { + left2 = *(int32_t *)usb_cur_buf2; + right2 = *((int32_t *)usb_cur_buf2 + 1); + } else if (usb_step == 6) { + left2 = ((usb_cur_buf2[0] << 8) | (usb_cur_buf2[1] << 16) | (usb_cur_buf2[2] << 24)); + right2 = ((usb_cur_buf2[3] << 8) | (usb_cur_buf2[4] << 16) | (usb_cur_buf2[5] << 24)); + } else { + left2 = *(int16_t *)usb_cur_buf2 << 16; + right2 = *((int16_t *)usb_cur_buf2 + 1) << 16; + } + if (cur_gain2 > new_gain2) { + cur_gain2 -= gain_step; + if (cur_gain2 < new_gain2) { + cur_gain2 = new_gain2; + } + } else if (cur_gain2 < new_gain2) { + cur_gain2 += gain_step; + if (cur_gain2 > new_gain2) { + cur_gain2 = new_gain2; + } + } + left2 = (int32_t)(left2 * cur_gain2); + right2 = (int32_t)(right2 * cur_gain2); + } else { + left2 = right2 = 0; + } + left = __QADD(left, left2); + right = __QADD(right, right2); + // Convert to 24-bit sample + left >>= 8; + right >>= 8; + + *(int32_t *)cur_buf = left; + *((int32_t *)cur_buf + 1) = right; + + cur_buf += codec_step; + usb_cur_buf += usb_step; + usb_cur_buf2 += usb_step; + } + } else if (sample_size_play == 2 && sample_size_recv == 2) { + + int32_t left, right; + int32_t left2, right2; + + usb_step = 4; + codec_step = 4; + + while (cur_buf + codec_step <= buf_end) { + if (usb_cur_buf + usb_step > usb_buf_end) { + usb_cur_buf = usb_recv_buf; + } + if (usb_cur_buf2 + usb_step > usb_buf_end2) { + usb_cur_buf2 = usb_recv2_buf; + } + if (recv_valid) { + left = *(int16_t *)usb_cur_buf; + right = *((int16_t *)usb_cur_buf + 1); + if (cur_gain > new_gain) { + cur_gain -= gain_step; + if (cur_gain < new_gain) { + cur_gain = new_gain; + } + } else if (cur_gain < new_gain) { + cur_gain += gain_step; + if (cur_gain > new_gain) { + cur_gain = new_gain; + } + } + left = (int32_t)(left * cur_gain); + right = (int32_t)(right * cur_gain); + } else { + left = right = 0; + } + if (recv2_valid) { + left2 = *(int16_t *)usb_cur_buf2; + right2 = *((int16_t *)usb_cur_buf2 + 1); + if (cur_gain2 > new_gain2) { + cur_gain2 -= gain_step; + if (cur_gain2 < new_gain2) { + cur_gain2 = new_gain2; + } + } else if (cur_gain2 < new_gain2) { + cur_gain2 += gain_step; + if (cur_gain2 > new_gain2) { + cur_gain2 = new_gain2; + } + } + left2 = (int32_t)(left2 * cur_gain2); + right2 = (int32_t)(right2 * cur_gain2); + } else { + left2 = right2 = 0; + } + left = __SSAT(left + left2, 16); + right = __SSAT(right + right2, 16); + + *(int16_t *)cur_buf = left; + *((int16_t *)cur_buf + 1) = right; + + cur_buf += codec_step; + usb_cur_buf += usb_step; + } + + } else { + + ASSERT(false, "2:3: Invalid sample_size_play=%u sample_size_recv=%u", + sample_size_play, sample_size_recv); + + } + + playback_coef = cur_gain; + playback2_coef = cur_gain2; + } + +#else + + { + uint8_t POSSIBLY_UNUSED *cur_buf, *buf_end, *usb_cur_buf, *usb_buf_end; + uint32_t codec_step, usb_step; + bool down_sampling = false; + + cur_buf = conv_buf; + buf_end = conv_buf + len; + usb_cur_buf = usb_recv_buf + old_rpos; + usb_buf_end = usb_recv_buf + usb_recv_size; + + if (0) { + +#ifdef CODEC_DSD + } else if (codec_dsd_enabled) { + + ASSERT(sample_size_play == 2, "Bad DSD playback sample size: %u", sample_size_play); + ASSERT(sample_size_recv == 4 || sample_size_recv == 3, "Bad DSD recv sample size: %u", sample_size_recv); + + uint32_t left, right; + + if (sample_size_recv == 4) { + usb_step = 8; + } else { + usb_step = 6; + } + + codec_step = 4; + + while (cur_buf + codec_step <= buf_end) { + if (usb_cur_buf + usb_step > usb_buf_end) { + usb_cur_buf = usb_recv_buf; + } + if (usb_step == 8) { + left = *(uint32_t *)usb_cur_buf; + right = *((uint32_t *)usb_cur_buf + 1); + } else { + left = ((usb_cur_buf[0] << 8) | (usb_cur_buf[1] << 16)); + right = ((usb_cur_buf[3] << 8) | (usb_cur_buf[4] << 16)); + } + + left = __RBIT(left) >> 8; + right = __RBIT(right) >> 8; + + *(uint16_t *)cur_buf = left; + *((uint16_t *)cur_buf + 1) = right; + + cur_buf += codec_step; + usb_cur_buf += usb_step; + } +#endif + + } else if (sample_size_play == 4 && (sample_size_recv == 4 || sample_size_recv == 3 || sample_size_recv == 2)) { + + int32_t left, right; + + if (sample_size_recv == 4) { + usb_step = 8; + } else if (sample_size_recv == 3) { + usb_step = 6; + } else { + usb_step = 4; + } + + if ((sample_rate_play == 96000 && sample_rate_recv == 48000) || + (sample_rate_play == 88200 && sample_rate_recv == 44100)) { + codec_step = 16; + } else if (sample_rate_play == sample_rate_recv) { + codec_step = 8; + } else if (sample_rate_play == 96000 && sample_rate_recv == 192000) { + codec_step = 8; + down_sampling = true; + } else { + ASSERT(false, "1: Invalid sample_rate_play=%u sample_rate_recv=%u", + sample_rate_play, sample_rate_recv); + } + + while (cur_buf + codec_step <= buf_end) { + if (usb_cur_buf + usb_step > usb_buf_end) { + usb_cur_buf = usb_recv_buf; + } + if (usb_step == 8) { + left = *(int32_t *)usb_cur_buf; + right = *((int32_t *)usb_cur_buf + 1); + } else if (usb_step == 6) { + left = ((usb_cur_buf[0] << 8) | (usb_cur_buf[1] << 16) | (usb_cur_buf[2] << 24)); + right = ((usb_cur_buf[3] << 8) | (usb_cur_buf[4] << 16) | (usb_cur_buf[5] << 24)); + } else { + left = *(int16_t *)usb_cur_buf << 16; + right = *((int16_t *)usb_cur_buf + 1) << 16; + } + // Convert to 24-bit sample + left >>= 8; + right >>= 8; + + if (down_sampling) { + int32_t left_next, right_next; + + usb_cur_buf += usb_step; + if (usb_cur_buf + usb_step > usb_buf_end) { + usb_cur_buf = usb_recv_buf; + } + if (usb_step == 8) { + left_next = *(int32_t *)usb_cur_buf; + right_next = *((int32_t *)usb_cur_buf + 1); + } else if (usb_step == 6) { + left_next = ((usb_cur_buf[0] << 8) | (usb_cur_buf[1] << 16) | (usb_cur_buf[2] << 24)); + right_next = ((usb_cur_buf[3] << 8) | (usb_cur_buf[4] << 16) | (usb_cur_buf[5] << 24)); + } else { + left_next = *(int16_t *)usb_cur_buf << 16; + right_next = *((int16_t *)usb_cur_buf + 1) << 16; + } + // Convert to 24-bit sample + left_next >>= 8; + right_next >>= 8; + + // The addition of two 24-bit integers will not saturate + left = (left + left_next) / 2; + right = (right + right_next) / 2; + } + + *(int32_t *)cur_buf = left; + *((int32_t *)cur_buf + 1) = right; + if (codec_step == 16) { + *((int32_t *)cur_buf + 2) = left; + *((int32_t *)cur_buf + 3) = right; + } + + cur_buf += codec_step; + usb_cur_buf += usb_step; + } + + } else if (sample_size_play == 2 && sample_size_recv == 2) { + + int16_t left, right; + + usb_step = 4; + + if ((sample_rate_play == 96000 && sample_rate_recv == 48000) || + (sample_rate_play == 88200 && sample_rate_recv == 44100)) { + codec_step = 8; + } else if (sample_rate_play == sample_rate_recv) { + codec_step = 4; + } else if (sample_rate_play == 96000 && sample_rate_recv == 192000) { + codec_step = 4; + down_sampling = true; + } else { + ASSERT(false, "2: Invalid sample_rate_play=%u sample_rate_recv=%u", + sample_rate_play, sample_rate_recv); + } + + while (cur_buf + codec_step <= buf_end) { + if (usb_cur_buf + usb_step > usb_buf_end) { + usb_cur_buf = usb_recv_buf; + } + left = *(int16_t *)usb_cur_buf; + right = *((int16_t *)usb_cur_buf + 1); + if (down_sampling) { + // Use 32-bit integers to avoid saturation + int32_t left32, right32; + + usb_cur_buf += usb_step; + if (usb_cur_buf + usb_step > usb_buf_end) { + usb_cur_buf = usb_recv_buf; + } + left32 = *(int16_t *)usb_cur_buf; + right32 = *((int16_t *)usb_cur_buf + 1); + left = (left + left32) / 2; + right = (right + right32) / 2; + } + *(int16_t *)cur_buf = left; + *((int16_t *)cur_buf + 1) = right; + if (codec_step == 8) { + *((int16_t *)cur_buf + 2) = left; + *((int16_t *)cur_buf + 3) = right; + } + cur_buf += codec_step; + usb_cur_buf += usb_step; + } + + } else { + + ASSERT(false, "3: Invalid sample_size_play=%u sample_size_recv=%u", + sample_size_play, sample_size_recv); + + } + + } + +#endif // !USB_AUDIO_MULTIFUNC + + //---------------------------------------- + // USB->CODEC stream format conversion end + //---------------------------------------- +_conv_end: + + play_next = buf + len - playback_buf; + if (play_next >= playback_size) { + play_next -= playback_size; + } + + lock = int_lock(); + if (codec_play_seq == usb_recv_seq) { +#ifdef USB_AUDIO_MULTIFUNC + if (playback_state == AUDIO_ITF_STATE_STARTED) { + if (recv_valid) { + usb_recv_rpos = new_rpos; + } + if (recv2_valid) { + usb_recv2_rpos = new_rpos2; + } + } else { + if (recv_valid) { + usb_recv_rpos = 0; + } + if (recv2_valid) { + usb_recv2_rpos = 0; + } + } + if (conflicted) { + playback_conflicted = conflicted; + } + if (conflicted2) { + playback_conflicted2 = conflicted2; + } +#else + if (playback_state == AUDIO_ITF_STATE_STARTED) { + usb_recv_rpos = new_rpos; + } else { + usb_recv_rpos = 0; + } + if (conflicted) { + playback_conflicted = conflicted; + } +#endif + playback_pos = play_next; + } + int_unlock(lock); + + //---------------------------------------- + // Audio processing start + //---------------------------------------- + +#ifdef FREQ_RESP_EQ + freq_resp_eq_run(conv_buf, len); +#endif +#if defined(__HW_FIR_DSD_PROCESS__) + if (codec_dsd_enabled) { + dsd_process(conv_buf,len); + } +#endif + +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__)|| defined(__HW_IIR_EQ_PROCESS__) + if (eq_opened) { + audio_process_run(conv_buf, len); + } +#endif + + // If conv_buf != buf, copy the output to buf + + //---------------------------------------- + // Audio processing end + //---------------------------------------- + +#ifdef NOISE_GATING + bool noise_mute = true; +#ifdef NOISE_REDUCTION + bool nr_fire = true; + uint8_t chan = 0; +#endif + + if (sample_size_play == 2) { + int16_t *samp = (int16_t *)buf; + for (uint32_t i = 0; i < len / 2; i++) { + if (ABS(samp[i]) >= NOISE_GATING_THRESH_16BIT) { + noise_mute = false; + break; + } + // NOISE_REDUCTION is unstable for 16-bit streams for unknown reasons. Skip by now. + } + } else { + int32_t *samp = (int32_t *)buf; + for (uint32_t i = 0; i < len / 4; i++) { + if (ABS(samp[i]) >= NOISE_GATING_THRESH_24BIT) { + noise_mute = false; +#ifndef NOISE_REDUCTION + break; +#endif + } +#ifdef NOISE_REDUCTION + if (nr_fire) { + if (ABS(samp[i]) >= NOISE_REDUCTION_THRESH_24BIT) { + nr_fire = false; + } else { + cur_zero_diff[chan][0]++; + cur_zero_diff[chan][1]++; + if ((prev_samp_positive[chan] && samp[i] < 0) || + (!prev_samp_positive[chan] && samp[i] >= 0)) { + if (ABS(cur_zero_diff[chan][prev_samp_positive[chan]] - + prev_zero_diff[chan][prev_samp_positive[chan]]) < 2) { + if (nr_cont_cnt < NOISE_REDUCTION_MATCH_CNT) { + nr_cont_cnt++; + } + } else if (nr_cont_cnt > 2) { + nr_fire = false; + } + prev_zero_diff[chan][prev_samp_positive[chan]] = cur_zero_diff[chan][prev_samp_positive[chan]]; + cur_zero_diff[chan][prev_samp_positive[chan]] = 0; + } + prev_samp_positive[chan] = (samp[i] >= 0); + // Switch channel + chan = !chan; + } + } +#endif + } + } + +#ifdef NOISE_REDUCTION + if (noise_mute) { + nr_fire = false; + } + if (nr_fire) { + if (nr_cont_cnt >= NOISE_REDUCTION_MATCH_CNT && + !nr_active && noise_reduction_cmd != NOISE_REDUCTION_CMD_FIRE) { + if (cur_time - last_nr_restore_time >= NOISE_REDUCTION_INTERVAL) { + TRACE(8,"\nFire noise reduction: cur0=%u/%u cur1=%u/%u prev0=%u/%u prev1=%u/%u\n", + cur_zero_diff[0][0], cur_zero_diff[0][1], cur_zero_diff[1][0], cur_zero_diff[1][1], + prev_zero_diff[0][0], prev_zero_diff[0][1], prev_zero_diff[1][0], prev_zero_diff[1][1]); + noise_reduction_cmd = NOISE_REDUCTION_CMD_FIRE; + enqueue_unique_cmd(AUDIO_CMD_NOISE_REDUCTION); + } + } + } else { + if (nr_active && noise_reduction_cmd != NOISE_REDUCTION_CMD_RESTORE) { + TRACE(8,"\nRestore noise reduction: cur0=%u/%u cur1=%u/%u prev0=%u/%u prev1=%u/%u\n", + cur_zero_diff[0][0], cur_zero_diff[0][1], cur_zero_diff[1][0], cur_zero_diff[1][1], + prev_zero_diff[0][0], prev_zero_diff[0][1], prev_zero_diff[1][0], prev_zero_diff[1][1]); + noise_reduction_cmd = NOISE_REDUCTION_CMD_RESTORE; + enqueue_unique_cmd(AUDIO_CMD_NOISE_REDUCTION); + } + memset(prev_zero_diff, 0, sizeof(prev_zero_diff)); + memset(cur_zero_diff, 0, sizeof(cur_zero_diff)); + nr_cont_cnt = 0; + last_nr_restore_time = cur_time; + } +#endif + + if (noise_mute) { + if ((mute_user_map & (1 << CODEC_MUTE_USER_NOISE_GATING)) == 0 && noise_gating_cmd != NOISE_GATING_CMD_MUTE) { + if (cur_time - last_high_signal_time >= NOISE_GATING_INTERVAL) { + noise_gating_cmd = NOISE_GATING_CMD_MUTE; + enqueue_unique_cmd(AUDIO_CMD_NOISE_GATING); + } + } + } else { + if ((mute_user_map & (1 << CODEC_MUTE_USER_NOISE_GATING)) && noise_gating_cmd != NOISE_GATING_CMD_UNMUTE) { + noise_gating_cmd = NOISE_GATING_CMD_UNMUTE; + enqueue_unique_cmd(AUDIO_CMD_NOISE_GATING); + } + last_high_signal_time = cur_time; + } +#endif + +#if (VERBOSE_TRACE & (1 << 1)) + { + int hw_play_pos = af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + TRACE_TIME(2,"playbackEnd: playback_pos=%u hw_play_pos=%d", playback_pos, hw_play_pos); + } +#endif + + return 0; +} + +static uint32_t usb_audio_data_capture(uint8_t *buf, uint32_t len) +{ + uint32_t usb_len; + uint32_t old_wpos, saved_old_wpos, new_wpos, rpos; + uint8_t init_pos; + uint8_t conflicted; + uint32_t reset_len = usb_send_size / 2; + uint32_t cap_next; + uint32_t lock; + uint8_t *conv_buf; + uint32_t cur_time; + uint32_t usb_time; +#ifdef SW_CAPTURE_RESAMPLE + enum RESAMPLE_STATUS_T ret; + struct RESAMPLE_IO_BUF_T io; + uint32_t in_size; + uint32_t out_size; + uint32_t resample_frame_len = 0; +#endif + + usb_time = last_usb_send_time; + cur_time = hal_sys_timer_get(); + + ASSERT(((uint32_t)buf & 0x3) == 0, "%s: Invalid buf: %p", __FUNCTION__, buf); + + if (codec_cap_valid == 0 && cur_time - codec_cap_start_time >= CAPTURE_STABLE_INTERVAL) { + codec_cap_valid = 1; + } + + if (codec_cap_seq != usb_send_seq || + capture_state == AUDIO_ITF_STATE_STOPPED || + send_state == AUDIO_ITF_STATE_STOPPED || + codec_cap_valid == 0 || + usb_send_valid == 0 || + cur_time - usb_time > USB_MAX_XFER_INTERVAL) { +_invalid_cap: + new_wpos = 0; + conflicted = 0; + goto _conv_end; + } + + if (usb_send_init_wpos) { + init_pos = 0; + } else { + init_pos = 1; + } + + //---------------------------------------- + // Check conflict + //---------------------------------------- + + usb_len = capture_to_send_len(len); + conflicted = 0; + + lock = int_lock(); + rpos = usb_send_rpos; + if (init_pos) { + old_wpos = rpos + reset_len; + if (old_wpos >= usb_send_size) { + old_wpos -= usb_send_size; + } + usb_send_wpos = old_wpos; + usb_send_init_wpos = 1; + } else { + old_wpos = usb_send_wpos; + } + saved_old_wpos = old_wpos; + new_wpos = usb_send_wpos + usb_len; + if (new_wpos >= usb_send_size) { + new_wpos -= usb_send_size; + } + if (init_pos == 0) { + if (old_wpos <= rpos) { + if (new_wpos < old_wpos || rpos < new_wpos) { + conflicted = 1; + } + } else { + if (rpos < new_wpos && new_wpos < old_wpos) { + conflicted = 1; + } + } + if (conflicted) { + // Reset write position + old_wpos = rpos + reset_len; + if (old_wpos >= usb_send_size) { + old_wpos -= usb_send_size; + } + new_wpos = old_wpos + usb_len; + if (new_wpos >= usb_send_size) { + new_wpos -= usb_send_size; + } + // Update global write position + usb_send_wpos = old_wpos; + } + } + int_unlock(lock); + + if (conflicted) { + TRACE(4,"capture: Error: wpos=%u goes beyond rpos=%u with usb_len=%u. Reset to %u", saved_old_wpos, rpos, usb_len, old_wpos); + } + +#if (VERBOSE_TRACE & (1 << 2)) + TRACE_TIME(5,"capture: wpos=%u usb_len=%u rpos=%u cap_pos=%u len=%u", old_wpos, usb_len, rpos, buf + len - capture_buf, len); +#endif + + if (codec_cap_seq != usb_send_seq) { + goto _invalid_cap; + } + + record_conflict(conflicted); + + //---------------------------------------- + // Audio processing start + //---------------------------------------- + + // TODO ... + + //---------------------------------------- + // Audio processing end + //---------------------------------------- + + //---------------------------------------- + // Speech processing start + //---------------------------------------- +#ifdef USB_AUDIO_SPEECH + speech_process_capture_run(buf, &len); +#endif + //---------------------------------------- + // Speech processing end + //---------------------------------------- + + //---------------------------------------- + // CODEC->USB stream format conversion start + //---------------------------------------- + + conv_buf = buf; + + { + uint8_t POSSIBLY_UNUSED *cur_buf, *buf_end, *dst_buf_start, *dst_cur_buf, *dst_buf_end; + + cur_buf = conv_buf; + buf_end = conv_buf + len; +#ifdef SW_CAPTURE_RESAMPLE + if (resample_cap_enabled) { +#if (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) +#if (defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_))) + // codec capture buffer --(ref rate conversion)--> resample input buffer --(resample)--> usb send buffer + +#ifdef USB_AUDIO_DYN_CFG + // Resample frame len is the capture reference len after reference rate conversion + resample_frame_len = capture_to_ref_len(len); +#else + // Resample frame len is the capture len + resample_frame_len = len; +#endif + ASSERT(resample_frame_len <= resample_input_size, + "resample_input_size too small: %u len=%u resample_frame_len=%u", + resample_input_size, len, resample_frame_len); + + dst_buf_start = resample_input_buf; + dst_cur_buf = resample_input_buf; + dst_buf_end = resample_input_buf + resample_frame_len; +#else // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) + // codec capture buffer --(resample)--> usb send buffer + + resample_input_buf = cur_buf; + // Resample frame len is the capture len + resample_frame_len = len; + + dst_buf_start = cur_buf; + dst_cur_buf = cur_buf; + dst_buf_end = cur_buf + len; +#endif // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) +#elif (CHAN_NUM_CAPTURE == 2) && (CHAN_NUM_SEND == 1) + // codec capture buffer --(chan num conversion)--> codec capture buffer --(resample)--> usb send buffer + + resample_input_buf = cur_buf; + // Resample frame len is half of the capture len + resample_frame_len = len / 2; + + dst_buf_start = cur_buf; + dst_cur_buf = cur_buf; + dst_buf_end = cur_buf + resample_frame_len; +#elif (CHAN_NUM_CAPTURE == 1) && (CHAN_NUM_SEND == 2) + // codec capture buffer --(resample)--> usb send buffer --(chan num conversion)--> usb send buffer + + // Resample frame len is the capture len + resample_frame_len = len; + + io.in = cur_buf; + io.in_size = resample_frame_len; + io.out = usb_send_buf + old_wpos; + io.out_size = usb_len / 2; + io.out_cyclic_start = usb_send_buf; + io.out_cyclic_end = usb_send_buf + usb_send_size; + + ret = audio_resample_ex_run(resample_id, &io, &in_size, &out_size); + ASSERT((ret == RESAMPLE_STATUS_IN_EMPTY || ret == RESAMPLE_STATUS_DONE) && io.out_size >= out_size, + "Failed to resample: %d io.out_size=%u in_size=%u out_size=%u", + ret, io.out_size, in_size, out_size); + + uint32_t diff = usb_len - out_size * 2; + if (new_wpos >= diff) { + new_wpos -= diff; + } else { + new_wpos = new_wpos + usb_send_size - diff; + } + +#if (VERBOSE_TRACE & (1 << 3)) + TRACE(5,"cap_resample: new_wpos=%u, in: %u -> %u, out: %u -> %u", new_wpos, io.in_size, in_size, io.out_size, out_size); +#endif + + dst_buf_start = usb_send_buf; + dst_cur_buf = usb_send_buf + old_wpos; + dst_buf_end = usb_send_buf + usb_send_size; + cur_buf = dst_cur_buf; + buf_end = cur_buf + out_size; + if (buf_end >= usb_send_buf + usb_send_size) { + buf_end -= usb_send_size; + } +#else +#error "Unsupported CHAN_NUM_CAPTURE and CHAN_NUM_SEND configuration" +#endif + } else +#endif // SW_CAPTURE_RESAMPLE + { + dst_buf_start = usb_send_buf; + dst_cur_buf = usb_send_buf + old_wpos; + dst_buf_end = usb_send_buf + usb_send_size; + } + +#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) + + // Assuming codec adc records stereo data, and usb sends 48K/44.1K stereo data +#if (CHAN_NUM_CAPTURE != 2) || (CHAN_NUM_SEND != 2) +#error "Unsupported CHAN_NUM_CAPTURE and CHAN_NUM_SEND configuration" +#endif + + { +#define MERGE_VER 2 +#if (MERGE_VER == 2) +#define THRES_MIC3 32500 +#else +#define THRES_MIC3 27168 +#endif +#define SHIFT_BITS 4 + + uint32_t i = 0; + short* BufSrc = (short*)cur_buf; + short* BufDst = (short*)dst_cur_buf; + short* BufDstStart = (short*)dst_buf_start; + short* BufDstEnd = (short*)dst_buf_end; + + int32_t PcmValue = 0; + int32_t BufSrcRVal = 0; + + uint32_t step; + + //TRACE(3,"%s - %d, %d", __func__, BufSrc[0], BufSrc[1]); + //TRACE(2,"%s - %d", __func__, TICKS_TO_MS(cur_time)); + + if (sample_rate_cap == 384000 || sample_rate_cap == 352800) { + step = 2; + } else if (sample_rate_cap == 192000 || sample_rate_cap == 176400) { + step = 1; + } else { + ASSERT(false, "1: Invalid sample_rate_cap=%u sample_rate_ref_cap=%u sample_rate_send=%u", sample_rate_cap, sample_rate_ref_cap, sample_rate_send); + } + + get_amic_dc(BufSrc, len>>2, step); + + for (i = 0; i < (len>>2); i += step) + { + if (step == 2) { + if (!(i&0x1)) { + PcmValue = ((int32_t)(BufSrc[i<<1])); + BufSrcRVal = ((int32_t)(BufSrc[(i<<1)+1])); +#if (MERGE_VER == 2) + if ((PcmValue < THRES_MIC3) && (PcmValue > -THRES_MIC3)) { + PcmValue = (PcmValue - s_amic3_dc)>>SHIFT_BITS; + } else { + PcmValue = BufSrcRVal - s_amic4_dc; + } +#else // (MERGE_VER == 1) + PcmValue -= s_amic3_dc; + if ((PcmValue < THRES_MIC3) && (PcmValue > -THRES_MIC3)) { + PcmValue >>= SHIFT_BITS; + } else { + PcmValue = BufSrcRVal - s_amic4_dc; + } +#endif // MERGE_VER + PcmValue = soir_filter(PcmValue); +#ifdef DUAL_AUX_MIC_MORE_FILTER + PcmValue = soir_filter1(PcmValue); + PcmValue = soir_filter2(PcmValue); +#endif + if (!(i&7)) { + if (BufDst + 2 > BufDstEnd) { + BufDst = BufDstStart; + } + *BufDst++ = PcmValue; + *BufDst++ = PcmValue; + } + } + } else { + if (!(i&0x1)) { + PcmValue = ((int32_t)(BufSrc[i<<1])); + BufSrcRVal = ((int32_t)(BufSrc[(i<<1)+1])); +#if (MERGE_VER == 2) + if ((PcmValue < THRES_MIC3) && (PcmValue > -THRES_MIC3)) { + PcmValue = (PcmValue-s_amic3_dc)>>SHIFT_BITS; + } else { + PcmValue = BufSrcRVal-s_amic4_dc; + } +#else // (MERGE_VER == 1) + PcmValue -= s_amic3_dc; + if ((PcmValue < THRES_MIC3) && (PcmValue > -THRES_MIC3)) { + PcmValue >>= SHIFT_BITS; + } else { + PcmValue = BufSrcRVal - s_amic4_dc; + } +#endif // MERGE_VER + PcmValue = soir_filter(PcmValue); +#ifdef DUAL_AUX_MIC_MORE_FILTER + PcmValue = soir_filter1(PcmValue); + PcmValue = soir_filter2(PcmValue); +#endif + if (!(i&3)) { + if (BufDst + 2 > BufDstEnd) { + BufDst = BufDstStart; + } + *BufDst++ = PcmValue; + *BufDst++ = PcmValue; + } + } + } + } + } + +#elif defined(CHIP_BEST1000) && defined(ANC_APP) + + // Assuming codec adc records stereo data, and usb sends 48K/44.1K stereo data +#if (CHAN_NUM_CAPTURE != 2) || (CHAN_NUM_SEND != 2) +#error "Unsupported CHAN_NUM_CAPTURE and CHAN_NUM_SEND configuration" +#endif + + if ((sample_rate_ref_cap == 48000 || sample_rate_ref_cap == 44100) && + (sample_rate_cap == sample_rate_ref_cap * 2 || sample_rate_cap == sample_rate_ref_cap * 4 || + sample_rate_cap == sample_rate_ref_cap * 8 || sample_rate_cap == sample_rate_ref_cap * 16)) { + + uint32_t POSSIBLY_UNUSED factor = sample_rate_cap / sample_rate_ref_cap; + int32_t POSSIBLY_UNUSED left = 0; + int32_t POSSIBLY_UNUSED right = 0; + uint32_t step = factor * 4; + + while (cur_buf + step <= buf_end) { + if (dst_cur_buf + 4 > dst_buf_end) { + dst_cur_buf = dst_buf_start; + } + + // Downsampling the adc data +#if 1 + left = 0; + right = 0; + for (int i = 0; i < factor; i++) { + left += *(int16_t *)(cur_buf + 4 * i); + right += *(int16_t *)(cur_buf + 4 * i + 2); + } + *(int16_t *)dst_cur_buf = left / factor; + *(int16_t *)(dst_cur_buf + 2) = right / factor; +#else + *(int16_t *)dst_cur_buf = *(int16_t *)cur_buf; + *(int16_t *)(dst_cur_buf + 2) = *(int16_t *)(cur_buf + 2); +#endif + + // Move to next data + dst_cur_buf += 4; + cur_buf += step; + } + + } else { + ASSERT(false, "2: Invalid sample_rate_cap=%u sample_rate_ref_cap=%u sample_rate_send=%u", sample_rate_cap, sample_rate_ref_cap, sample_rate_send); + } + +#else // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) + +#ifndef SW_CAPTURE_RESAMPLE + ASSERT(sample_rate_cap == sample_rate_send,"3: Invalid sample_rate_cap=%u sample_rate_send=%u", sample_rate_cap, sample_rate_send); +#endif + +// When USB_AUDIO_SPEECH is enable, buf after algorithm shoule be CHAN_NUM_SEND, +// do not need to convert any more. +#if (CHAN_NUM_CAPTURE == 2) && (CHAN_NUM_SEND == 1) && !defined(USB_AUDIO_SPEECH) + + // Assuming codec adc always records stereo data + + while (cur_buf + 4 <= buf_end) { + // Copy left channel data + if (dst_cur_buf + 2 > dst_buf_end) { + dst_cur_buf = dst_buf_start; + } + *(int16_t *)dst_cur_buf = *(int16_t *)cur_buf; + + // Move to next data + dst_cur_buf += 2; + cur_buf += 4; + } + +#elif (CHAN_NUM_CAPTURE == 1) && (CHAN_NUM_SEND == 2) && !defined(USB_AUDIO_SPEECH) + + // Assuming codec adc always records mono data + +#ifdef SW_CAPTURE_RESAMPLE +#if (CHAN_NUM_CAPTURE == 1) && (CHAN_NUM_SEND == 2) + if (resample_cap_enabled) { + //ASSERT(cur_buf == dst_cur_buf, "Bad assumption"); + uint32_t src_len; + + if (buf_end < cur_buf) { + src_len = buf_end + usb_send_size - cur_buf; + } else { + src_len = buf_end - cur_buf; + } + cur_buf = buf_end - 2; + if (cur_buf < dst_buf_start) { + cur_buf += usb_send_size; + } + dst_cur_buf += src_len * 2 - 4; + if (dst_cur_buf >= dst_buf_end) { + dst_cur_buf -= usb_send_size; + } + while (src_len > 0) { + *(int16_t *)dst_cur_buf = *(int16_t *)cur_buf; + *(int16_t *)(dst_cur_buf + 2) = *(int16_t *)cur_buf; + + // Move to next data + src_len -= 2; + cur_buf -= 2; + if (cur_buf < dst_buf_start) { + cur_buf += usb_send_size; + } + dst_cur_buf -= 4; + if (dst_cur_buf < dst_buf_start) { + dst_cur_buf += usb_send_size; + } + } + } else +#endif +#endif + { + while (cur_buf + 2 <= buf_end) { + // Duplicate the mono data + if (dst_cur_buf + 4 > dst_buf_end) { + dst_cur_buf = dst_buf_start; + } + *(int16_t *)dst_cur_buf = *(int16_t *)cur_buf; + *(int16_t *)(dst_cur_buf + 2) = *(int16_t *)cur_buf; + + // Move to next data + dst_cur_buf += 4; + cur_buf += 2; + } + } + +#else // (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) + + // The channel numbers of codec adc and USB data are the same + + if (sample_size_cap == sample_size_send) { +#if ((CHAN_NUM_CAPTURE & 1) == 0) +#define COPY_MEM(dst, src, size) copy_mem32(dst, src, size) +#else +#define COPY_MEM(dst, src, size) copy_mem16(dst, src, size) +#endif + if (dst_cur_buf != cur_buf) { + if (dst_cur_buf + len <= dst_buf_end) { + COPY_MEM(dst_cur_buf, cur_buf, len); + } else { + uint32_t copy_len; + + if (dst_cur_buf >= dst_buf_end) { + copy_len = 0; + } else { + copy_len = dst_buf_end - dst_cur_buf; + COPY_MEM(dst_cur_buf, cur_buf, copy_len); + } + COPY_MEM(dst_buf_start, cur_buf + copy_len, len - copy_len); + } + } +#undef COPY_MEM + } else if (sample_size_cap == 4 && sample_size_send == 3) { + uint32_t codec_step, usb_step; + uint32_t ch; + + codec_step = CHAN_NUM_CAPTURE * 4; + usb_step = CHAN_NUM_SEND * 3; + + while (cur_buf + codec_step <= buf_end) { + if (dst_cur_buf + usb_step > dst_buf_end) { + dst_cur_buf = dst_buf_start; + } + for (ch = 0; ch < CHAN_NUM_CAPTURE; ch++) { + *(uint16_t *)dst_cur_buf = *(uint16_t *)cur_buf; + *(uint8_t *)(dst_cur_buf + 2) = *(uint8_t *)(cur_buf + 2); + // Move to next channel + dst_cur_buf += 3; + cur_buf += 4; + } + } + } else { + ASSERT(false, "4: Invalid sample_size_cap=%u sample_size_send=%u", sample_size_cap, sample_size_send); + } + +#endif // (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) + +#endif // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) + +#ifdef SW_CAPTURE_RESAMPLE +#if !((CHAN_NUM_CAPTURE == 1) && (CHAN_NUM_SEND == 2)) + if (resample_cap_enabled) { + io.in = resample_input_buf; + io.in_size = resample_frame_len; + io.out = usb_send_buf + old_wpos; + io.out_size = usb_len; + io.out_cyclic_start = usb_send_buf; + io.out_cyclic_end = usb_send_buf + usb_send_size; + + ret = audio_resample_ex_run(resample_id, &io, &in_size, &out_size); + ASSERT((ret == RESAMPLE_STATUS_IN_EMPTY || ret == RESAMPLE_STATUS_DONE) && io.out_size >= out_size, + "Failed to resample: %d io.out_size=%u io.in_size=%u in_size=%u out_size=%u", + ret, io.out_size, io.in_size, in_size, out_size); + + uint32_t diff = usb_len - out_size; + if (new_wpos >= diff) { + new_wpos -= diff; + } else { + new_wpos = new_wpos + usb_send_size - diff; + } + +#if (VERBOSE_TRACE & (1 << 3)) + TRACE(5,"cap_resample: new_wpos=%u, in: %u -> %u, out: %u -> %u", new_wpos, io.in_size, in_size, io.out_size, out_size); +#endif + } +#endif +#endif + } + + //---------------------------------------- + // CODEC->USB stream format conversion end + //---------------------------------------- +_conv_end: + + cap_next = buf + len - capture_buf; + if (cap_next >= capture_size) { + cap_next -= capture_size; + } + + lock = int_lock(); + if (codec_cap_seq == usb_send_seq) { + if (capture_state == AUDIO_ITF_STATE_STARTED) { + usb_send_wpos = new_wpos; + } else { + usb_send_wpos = 0; + } + capture_pos = cap_next; + if (conflicted) { + capture_conflicted = conflicted; + } + } + int_unlock(lock); + +#if (VERBOSE_TRACE & (1 << 4)) + TRACE_TIME(0,"captureEnd"); +#endif + + return 0; +} + +static void update_playback_sync_info(void) +{ + playback_info.err_thresh = DIFF_ERR_THRESH_PLAYBACK; + playback_info.samp_rate = sample_rate_play; + playback_info.samp_cnt = byte_to_samp_recv(usb_recv_size); +#ifdef TARGET_TO_MAX_DIFF + playback_info.max_target_thresh = playback_info.samp_cnt / 2; + playback_info.diff_target = byte_to_samp_recv(playback_to_recv_len(playback_size / 2)) + playback_info.samp_cnt / 2; + playback_info.diff_target = usb_audio_sync_normalize_diff(-playback_info.diff_target, playback_info.samp_cnt); +#endif + + TRACE(4,"%s: rate=%u cnt=%u (%u)", __FUNCTION__, playback_info.samp_rate, playback_info.samp_cnt, usb_recv_size); +} + +static void update_capture_sync_info(void) +{ + capture_info.err_thresh = DIFF_ERR_THRESH_CAPTURE; + capture_info.samp_rate = sample_rate_cap; + capture_info.samp_cnt = byte_to_samp_send(usb_send_size); +#ifdef TARGET_TO_MAX_DIFF + capture_info.max_target_thresh = capture_info.samp_cnt / 2; + capture_info.diff_target = byte_to_samp_send(capture_to_send_len(capture_size / 2)) + capture_info.samp_cnt / 2; + capture_info.diff_target = usb_audio_sync_normalize_diff(capture_info.diff_target, capture_info.samp_cnt); +#endif + + TRACE(4,"%s: rate=%u cnt=%u (%u)", __FUNCTION__, capture_info.samp_rate, capture_info.samp_cnt, usb_send_size); +} + +static int usb_audio_open_codec_stream(enum AUD_STREAM_T stream, enum AUDIO_STREAM_REQ_USER_T user) +{ + int ret = 0; + struct AF_STREAM_CONFIG_T stream_cfg; + + TRACE(4,"%s: stream=%d user=%d map=0x%x", __FUNCTION__, stream, user, codec_stream_map[stream][AUDIO_STREAM_OPENED]); + + if (user >= AUDIO_STREAM_REQ_USER_QTY || codec_stream_map[stream][AUDIO_STREAM_OPENED] == 0) { + memset(&stream_cfg, 0, sizeof(stream_cfg)); + + if (stream == AUD_STREAM_PLAYBACK) { +#if defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY) + playback_size = calc_playback_size(sample_rate_play); +#endif + + update_playback_sync_info(); + +#ifdef CODEC_DSD + if (codec_dsd_enabled) { + stream_cfg.bits = AUD_BITS_24; + } else +#endif + { + stream_cfg.bits = sample_size_to_enum_playback(sample_size_play); + } + stream_cfg.sample_rate = sample_rate_play; + stream_cfg.channel_num = chan_num_to_enum(CHAN_NUM_PLAYBACK); +#ifdef USB_I2S_APP +#if defined(USB_I2S_ID) && (USB_I2S_ID == 0) + stream_cfg.device = AUD_STREAM_USE_I2S0_MASTER; +#else + stream_cfg.device = AUD_STREAM_USE_I2S1_MASTER; +#endif +#else + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; +#endif + stream_cfg.vol = playback_vol; + stream_cfg.handler = usb_audio_data_playback; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.data_ptr = playback_buf; + stream_cfg.data_size = playback_size; + + //TRACE(3,"[%s] sample_rate: %d, bits = %d", __func__, stream_cfg.sample_rate, stream_cfg.bits); + + ret = af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + ASSERT(ret == 0, "af_stream_open playback failed: %d", ret); + +#ifdef AUDIO_ANC_FB_MC + stream_cfg.bits = sample_size_to_enum_playback(sample_size_play); + stream_cfg.sample_rate = sample_rate_play; + stream_cfg.channel_num = chan_num_to_enum(CHAN_NUM_PLAYBACK); + stream_cfg.device = AUD_STREAM_USE_MC; + stream_cfg.vol = playback_vol; + stream_cfg.handler = audio_mc_data_playback; + stream_cfg.io_path = AUD_OUTPUT_PATH_SPEAKER; + stream_cfg.data_ptr = playback_buf+playback_size; + + mid_p_8_old_l=0; + mid_p_8_old_r=0; + + if(sample_rate_play==AUD_SAMPRATE_8000) + { + playback_samplerate_ratio=8*6; + } + else if(sample_rate_play==AUD_SAMPRATE_16000) + { + playback_samplerate_ratio=8*3; + } + else if((sample_rate_play==AUD_SAMPRATE_44100)||(sample_rate_play==AUD_SAMPRATE_48000)||(sample_rate_play==AUD_SAMPRATE_50781)) + { + playback_samplerate_ratio=8; + } + else if((sample_rate_play==AUD_SAMPRATE_88200)||(sample_rate_play==AUD_SAMPRATE_96000)) + { + playback_samplerate_ratio=4; + } + else if((sample_rate_play==AUD_SAMPRATE_176400)||(sample_rate_play==AUD_SAMPRATE_192000)) + { + playback_samplerate_ratio=2; + } + else if(sample_rate_play==AUD_SAMPRATE_384000) + { + playback_samplerate_ratio=1; + } + else + { + playback_samplerate_ratio=1; + ASSERT(false, "Music cancel can't support playback sample rate:%d",sample_rate_play); + } + + anc_mc_run_init((sample_rate_play*playback_samplerate_ratio)/8); + + stream_cfg.data_size = playback_size*playback_samplerate_ratio; + + //TRACE(3,"[%s] sample_rate: %d, bits = %d", __func__, stream_cfg.sample_rate, stream_cfg.bits); + + ret = af_stream_open(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &stream_cfg); + ASSERT(ret == 0, "af_stream_open playback failed: %d", ret); +#endif + } else { +#if defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY) + capture_size = calc_capture_size(sample_rate_cap); +#endif + + update_capture_sync_info(); + + stream_cfg.bits = sample_size_to_enum_capture(sample_size_cap); + stream_cfg.sample_rate = sample_rate_cap; + stream_cfg.channel_num = chan_num_to_enum(CHAN_NUM_CAPTURE); +#ifdef ANC_PROD_TEST + stream_cfg.channel_map=anc_fb_mic_ch_l|anc_fb_mic_ch_r; +#endif +#ifdef USB_I2S_APP +#if defined(USB_I2S_ID) && (USB_I2S_ID == 0) + stream_cfg.device = AUD_STREAM_USE_I2S0_MASTER; +#else + stream_cfg.device = AUD_STREAM_USE_I2S1_MASTER; +#endif +#else + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; +#endif + stream_cfg.vol = capture_vol; + stream_cfg.handler = usb_audio_data_capture; +#if !defined(USB_AUDIO_SPEECH) && defined(BTUSB_AUDIO_MODE) + stream_cfg.io_path = AUD_INPUT_PATH_USBAUDIO; +#else + stream_cfg.io_path = AUD_INPUT_PATH_MAINMIC; +#endif + stream_cfg.data_ptr = capture_buf; + stream_cfg.data_size = capture_size; + + //TRACE(4,"[%s] sample_rate: %d, bits = %d, ch_num = %d", __func__, stream_cfg.sample_rate, stream_cfg.bits, stream_cfg.channel_num); + + ret = af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + ASSERT(ret == 0, "af_stream_open catpure failed: %d", ret); + } + } + + if (user < AUDIO_STREAM_REQ_USER_QTY) { + codec_stream_map[stream][AUDIO_STREAM_OPENED] |= (1 << user); + } + + return ret; +} + +static int usb_audio_close_codec_stream(enum AUD_STREAM_T stream, enum AUDIO_STREAM_REQ_USER_T user) +{ + int ret = 0; + + TRACE(4,"%s: stream=%d user=%d map=0x%x", __FUNCTION__, stream, user, codec_stream_map[stream][AUDIO_STREAM_OPENED]); + + if (user < AUDIO_STREAM_REQ_USER_QTY) { + codec_stream_map[stream][AUDIO_STREAM_OPENED] &= ~(1 << user); + } + + if (user >= AUDIO_STREAM_REQ_USER_QTY || codec_stream_map[stream][AUDIO_STREAM_OPENED] == 0) { + ret = af_stream_close(AUD_STREAM_ID_0, stream); + +#ifdef AUDIO_ANC_FB_MC + if(stream == AUD_STREAM_PLAYBACK) + { + ret = af_stream_close(AUD_STREAM_ID_2, stream); + } +#endif + } + + return ret; +} + +static int usb_audio_open_eq(void) +{ + int ret = 0; + + TRACE(4,"[%s] EQ: sample_rate_recv=%d, sample_rate_play=%d, sample_bits=%d", __func__, + sample_rate_recv, sample_rate_play, sample_size_to_enum_playback(sample_size_play)); + +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || defined(__HW_IIR_EQ_PROCESS__) || defined(__HW_DAC_IIR_EQ_PROCESS__) + enum AUD_BITS_T sample_bits = sample_size_to_enum_playback(sample_size_play); + enum AUD_CHANNEL_NUM_T chan_num = chan_num_to_enum(CHAN_NUM_PLAYBACK); + ret = audio_process_open(sample_rate_play, sample_bits, chan_num, playback_eq_size/2, playback_eq_buf, playback_eq_size); + + //TRACE(1,"audio_process_open: %d", ret); + +#ifdef __SW_IIR_EQ_PROCESS__ + usb_audio_set_eq(AUDIO_EQ_TYPE_SW_IIR,usb_audio_get_eq_index(AUDIO_EQ_TYPE_SW_IIR,0)); +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ + usb_audio_set_eq(AUDIO_EQ_TYPE_HW_FIR,usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_FIR,0)); +#endif + +#ifdef __HW_DAC_IIR_EQ_PROCESS__ + usb_audio_set_eq(AUDIO_EQ_TYPE_HW_DAC_IIR,usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_DAC_IIR,0)); +#endif + +#ifdef __HW_IIR_EQ_PROCESS__ + usb_audio_set_eq(AUDIO_EQ_TYPE_HW_IIR,usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_IIR,0)); +#endif + +#endif + + eq_opened = 1; + + return ret; +} + +static int usb_audio_close_eq(void) +{ + int ret = 0; + +#if defined(__SW_IIR_EQ_PROCESS__) || defined(__HW_FIR_EQ_PROCESS__) || defined(__HW_IIR_EQ_PROCESS__) || defined(__HW_DAC_IIR_EQ_PROCESS__) + ret = audio_process_close(); +#endif + + eq_opened = 0; + + return ret; +} + +static int usb_audio_start_codec_stream(enum AUD_STREAM_T stream, enum AUDIO_STREAM_REQ_USER_T user) +{ + int ret = 0; + + TRACE(4,"%s: stream=%d user=%d map=0x%x", __FUNCTION__, stream, user, codec_stream_map[stream][AUDIO_STREAM_STARTED]); + + if (user >= AUDIO_STREAM_REQ_USER_QTY || codec_stream_map[stream][AUDIO_STREAM_STARTED] == 0) { + reset_conflict(); + + if (stream == AUD_STREAM_PLAYBACK) { + zero_mem32(playback_buf, playback_size); + codec_play_valid = 0; + usb_recv_init_rpos = 0; + playback_pos = 0; + playback_conflicted = 0; +#ifdef USB_AUDIO_MULTIFUNC + usb_recv2_init_rpos = 0; + playback_conflicted2 = 0; +#endif +#ifdef DSD_SUPPORT + if (codec_dsd_enabled) { +#if defined(__HW_FIR_DSD_PROCESS__) + uint8_t *dsd_buf; + uint32_t dsd_size; + + // DoP format requirement + dsd_size = playback_size * 16;; + dsd_buf = (uint8_t *)(HW_FIR_DSD_BUF_MID_ADDR - dsd_size / 2); + dsd_open(sample_rate_play,AUD_BITS_24,AUD_CHANNEL_NUM_2,dsd_buf,dsd_size); +#elif defined(CODEC_DSD) + af_dsd_enable(); +#endif + } +#endif + usb_audio_open_eq(); + } else { +#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) + damic_init(); + init_amic_dc(); +#endif + +#ifdef USB_AUDIO_SPEECH + app_overlay_select(APP_OVERLAY_HFP); + + speech_process_init(sample_rate_cap, CHAN_NUM_CAPTURE, sample_size_to_enum_playback(sample_size_cap), + sample_rate_play, CHAN_NUM_PLAYBACK, sample_size_to_enum_playback(sample_size_play), + 16, 16, + CHAN_NUM_SEND, CHAN_NUM_RECV); +#endif + + codec_cap_valid = 0; + usb_send_init_wpos = 0; + capture_pos = 0; + capture_conflicted = 0; + } + + // Tune rate according to the newest sync ratio info + usb_audio_cmd_tune_rate(stream); + + ret = af_stream_start(AUD_STREAM_ID_0, stream); + ASSERT(ret == 0, "af_stream_start %d failed: %d", stream, ret); + + if (stream == AUD_STREAM_PLAYBACK) { +#ifdef AUDIO_ANC_FB_MC + ret = af_stream_start(AUD_STREAM_ID_2, stream); + ASSERT(ret == 0, "af_stream_start %d failed: %d", stream, ret); +#endif + } else { + codec_cap_start_time = hal_sys_timer_get(); + } + } + + if (user < AUDIO_STREAM_REQ_USER_QTY) { + codec_stream_map[stream][AUDIO_STREAM_STARTED] |= (1 << user); + } + + return ret; +} + +static int usb_audio_stop_codec_stream(enum AUD_STREAM_T stream, enum AUDIO_STREAM_REQ_USER_T user) +{ + int ret = 0; + + TRACE(4,"%s: stream=%d user=%d map=0x%x", __FUNCTION__, stream, user, codec_stream_map[stream][AUDIO_STREAM_STARTED]); + + if (user < AUDIO_STREAM_REQ_USER_QTY) { + codec_stream_map[stream][AUDIO_STREAM_STARTED] &= ~(1 << user); + } + + if (user >= AUDIO_STREAM_REQ_USER_QTY || codec_stream_map[stream][AUDIO_STREAM_STARTED] == 0) { + ret = af_stream_stop(AUD_STREAM_ID_0, stream); + + if (stream == AUD_STREAM_PLAYBACK) { +#ifdef AUDIO_ANC_FB_MC + ret = af_stream_stop(AUD_STREAM_ID_2, stream); +#endif +#ifdef DSD_SUPPORT + if (codec_dsd_enabled) { +#if defined(__HW_FIR_DSD_PROCESS__) + dsd_close(); +#elif defined(CODEC_DSD) + af_dsd_disable(); +#endif + } +#endif + usb_audio_close_eq(); + } else { +#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) + damic_deinit(); +#endif + +#ifdef USB_AUDIO_SPEECH + speech_process_deinit(); + app_overlay_unloadall(); +#endif + } + } + + return ret; +} + +static int usb_audio_start_usb_stream(enum AUD_STREAM_T stream) +{ + int ret; + + reset_conflict(); + + if (stream == AUD_STREAM_PLAYBACK) { + usb_audio_sync_reset(&playback_info); + + usb_recv_valid = 0; +#ifdef USB_AUDIO_MULTIFUNC + if (recv2_state == AUDIO_ITF_STATE_STOPPED) +#endif + { + usb_recv_seq++; + } + + usb_recv_rpos = 0; + usb_recv_wpos = usb_recv_size / 2; + zero_mem32(usb_recv_buf, usb_recv_size); + + usb_recv_err_cnt = 0; + +#ifdef DSD_SUPPORT + usb_dsd_enabled = false; + usb_dsd_cont_cnt = 0; +#endif + + ret = usb_audio_start_recv(usb_recv_buf, usb_recv_wpos, usb_recv_size); + if (ret == 1) { + TRACE(0,"usb_audio_start_recv failed: usb not configured"); + } else { + ASSERT(ret == 0, "usb_audio_start_recv failed: %d", ret); + } + } else { +#ifndef UAUD_SYNC_STREAM_TARGET + if (recv_state == AUDIO_ITF_STATE_STOPPED) +#endif + { + usb_audio_sync_reset(&capture_info); + } + + usb_send_valid = 0; + usb_send_seq++; + + usb_send_rpos = usb_send_size / 2; + usb_send_wpos = 0; + zero_mem32(usb_send_buf, usb_send_size); + + usb_send_err_cnt = 0; + + ret = usb_audio_start_send(usb_send_buf, usb_send_rpos, usb_send_size); + if (ret == 1) { + TRACE(0,"usb_audio_start_send failed: usb not configured"); + } else { + ASSERT(ret == 0, "usb_audio_start_send failed: %d", ret); + } + } + + return ret; +} + +static int usb_audio_stop_usb_stream(enum AUD_STREAM_T stream) +{ + if (stream == AUD_STREAM_PLAYBACK) { + usb_audio_stop_recv(); + +#ifdef DSD_SUPPORT + usb_dsd_enabled = false; +#endif + + usb_audio_sync_reset(&playback_info); + } else { + usb_audio_stop_send(); + +#ifndef UAUD_SYNC_STREAM_TARGET + if (recv_state == AUDIO_ITF_STATE_STOPPED) +#endif + { + usb_audio_sync_reset(&capture_info); + } + } + + return 0; +} + +static void usb_audio_set_codec_volume(enum AUD_STREAM_T stream, uint8_t vol) +{ + struct AF_STREAM_CONFIG_T *cfg; + uint8_t POSSIBLY_UNUSED old_vol; + uint32_t ret; + + ret = af_stream_get_cfg(AUD_STREAM_ID_0, stream, &cfg, true); + if (ret == 0) { + old_vol = cfg->vol; + if (old_vol != vol) { + cfg->vol = vol; + af_stream_setup(AUD_STREAM_ID_0, stream, cfg); + } + } + +#ifdef AUDIO_ANC_FB_MC + if (stream == AUD_STREAM_PLAYBACK) { + ret = af_stream_get_cfg(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &cfg, true); + if (ret == 0) { + if (cfg->vol != vol) { + cfg->vol = vol; + af_stream_setup(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, cfg); + } + } + } +#endif +} + +static void usb_audio_enqueue_cmd(uint32_t data) +{ + int ret; + uint32_t mark; + + ret = safe_queue_put(&cmd_queue, data); + ASSERT(ret == 0 || safe_queue_dump(&cmd_queue), "%s: cmd queue overflow", __FUNCTION__); + + hal_cpu_wake_lock(USB_AUDIO_CPU_WAKE_USER); + + mark = safe_queue_watermark(&cmd_queue); + if (mark > cmd_watermark) { + cmd_watermark = mark; + TRACE(2,"%s: new watermark %u", __FUNCTION__, mark); + } + +#ifdef BT_USB_AUDIO_DUAL_MODE + if (enqueue_cmd_cb) { + enqueue_cmd_cb(data); + } +#endif +} + +#ifdef BT_USB_AUDIO_DUAL_MODE +void usb_audio_set_enqueue_cmd_callback(USB_AUDIO_ENQUEUE_CMD_CALLBACK cb) +{ + enqueue_cmd_cb = cb; +} +#endif + +static void enqueue_unique_cmd_with_opp(enum AUDIO_CMD_T cmd, uint8_t seq, uint8_t arg, enum AUDIO_CMD_T oppsite_cmd) +{ + uint32_t last[3]; + uint32_t lock; + bool dup = false; + + lock = int_lock(); + if (safe_queue_peek(&cmd_queue, -1, &last[0]) == 0 && + safe_queue_peek(&cmd_queue, -2, &last[1]) == 0 && + safe_queue_peek(&cmd_queue, -3, &last[2]) == 0) { + if (EXTRACT_CMD(last[0]) == cmd) { + dup = true; + safe_queue_pop(&cmd_queue, NULL); + } else if (EXTRACT_CMD(last[0]) == oppsite_cmd && + EXTRACT_CMD(last[1]) == cmd && + EXTRACT_CMD(last[2]) == oppsite_cmd) { + dup = true; + safe_queue_pop(&cmd_queue, NULL); + safe_queue_pop(&cmd_queue, NULL); + } + } + int_unlock(lock); + + usb_audio_enqueue_cmd(MAKE_QUEUE_DATA(cmd, seq, arg)); + + if (dup) { + TRACE(2,"%s: Remove old duplicate cmd %d", __FUNCTION__, cmd); + } +} + +static void enqueue_unique_cmd_arg(enum AUDIO_CMD_T cmd, uint8_t seq, uint8_t arg) +{ + uint32_t last; + uint32_t cur; + uint32_t lock; + bool enqueue = true; + + cur = MAKE_QUEUE_DATA(cmd, seq, arg); + + lock = int_lock(); + if (safe_queue_peek(&cmd_queue, -1, &last) == 0) { + if (last == cur) { + enqueue = false; + } + } + int_unlock(lock); + + if (enqueue) { + usb_audio_enqueue_cmd(cur); + } else { + TRACE(2,"%s: Skip duplicate cmd %d", __FUNCTION__, cmd); + } +} + +static void enqueue_unique_cmd(enum AUDIO_CMD_T cmd) +{ + enqueue_unique_cmd_arg(cmd, 0, 0); +} + +static void usb_audio_playback_start(enum USB_AUDIO_ITF_CMD_T cmd) +{ + if (cmd == USB_AUDIO_ITF_STOP) { + // Stop the stream right now + if (recv_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_usb_stream(AUD_STREAM_PLAYBACK); + recv_state = AUDIO_ITF_STATE_STOPPED; + } + +#ifdef USB_AUDIO_DYN_CFG + playback_itf_set = 0; +#ifdef USB_AUDIO_UAC2 + enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_PLAY, usb_recv_seq, 0, AUDIO_CMD_START_PLAY); +#else + enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_PLAY, usb_recv_seq, 0, AUDIO_CMD_SET_RECV_RATE); +#endif +#else + +#ifdef USB_AUDIO_MULTIFUNC + if (recv2_state == AUDIO_ITF_STATE_STARTED) { + return; + } +#endif + + enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_PLAY, usb_recv_seq, 0, AUDIO_CMD_START_PLAY); +#endif + } else { +#ifdef USB_AUDIO_DYN_CFG + if (cmd == USB_AUDIO_ITF_START_16BIT) { + new_sample_size_recv = 2; + } else if (cmd == USB_AUDIO_ITF_START_24BIT) { + new_sample_size_recv = 3; + } else { + new_sample_size_recv = 4; + } + playback_itf_set = 1; + + // Some host applications will not stop current stream before changing sample size + if (recv_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_usb_stream(AUD_STREAM_PLAYBACK); + recv_state = AUDIO_ITF_STATE_STOPPED; + } + +#ifdef USB_AUDIO_UAC2 +#ifdef KEEP_SAME_LATENCY + usb_recv_size = calc_usb_recv_size(new_sample_rate_recv, new_sample_size_recv); + TRACE(2,"%s: Set usb_recv_size=%u", __FUNCTION__, usb_recv_size); +#endif + + usb_audio_start_usb_stream(AUD_STREAM_PLAYBACK); + recv_state = AUDIO_ITF_STATE_STARTED; + + enqueue_unique_cmd_with_opp(AUDIO_CMD_START_PLAY, usb_recv_seq, 0, AUDIO_CMD_STOP_PLAY); +#else + // Wait for sampling freq ctrl msg to start the stream +#endif + return; +#else + if (recv_state == AUDIO_ITF_STATE_STOPPED) { + usb_audio_start_usb_stream(AUD_STREAM_PLAYBACK); + recv_state = AUDIO_ITF_STATE_STARTED; + } + +#ifdef USB_AUDIO_MULTIFUNC + if (recv2_state == AUDIO_ITF_STATE_STARTED) { + return; + } +#endif + + enqueue_unique_cmd_with_opp(AUDIO_CMD_START_PLAY, usb_recv_seq, 0, AUDIO_CMD_STOP_PLAY); +#endif + } +} + +static void usb_audio_capture_start(enum USB_AUDIO_ITF_CMD_T cmd) +{ + if (cmd == USB_AUDIO_ITF_STOP) { + // Stop the stream right now + if (send_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_usb_stream(AUD_STREAM_CAPTURE); + send_state = AUDIO_ITF_STATE_STOPPED; + } + +#ifdef USB_AUDIO_DYN_CFG + capture_itf_set = 0; +#ifdef USB_AUDIO_UAC2 + enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_CAPTURE, usb_send_seq, 0, AUDIO_CMD_START_CAPTURE); +#else + enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_CAPTURE, usb_send_seq, 0, AUDIO_CMD_SET_SEND_RATE); +#endif +#else + enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_CAPTURE, usb_send_seq, 0, AUDIO_CMD_START_CAPTURE); +#endif + } else { +#ifdef USB_AUDIO_DYN_CFG + capture_itf_set = 1; + + // Some host applications will not stop current stream before changing sample size + if (send_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_usb_stream(AUD_STREAM_CAPTURE); + send_state = AUDIO_ITF_STATE_STOPPED; + } + +#ifdef USB_AUDIO_UAC2 + usb_audio_start_usb_stream(AUD_STREAM_CAPTURE); + send_state = AUDIO_ITF_STATE_STARTED; + + enqueue_unique_cmd_with_opp(AUDIO_CMD_START_CAPTURE, usb_send_seq, 0, AUDIO_CMD_STOP_CAPTURE); +#else + // Wait for sampling freq ctrl msg to start the stream +#endif + return; +#else + if (send_state == AUDIO_ITF_STATE_STOPPED) { + usb_audio_start_usb_stream(AUD_STREAM_CAPTURE); + send_state = AUDIO_ITF_STATE_STARTED; + } + + enqueue_unique_cmd_with_opp(AUDIO_CMD_START_CAPTURE, usb_send_seq, 0, AUDIO_CMD_STOP_CAPTURE); +#endif + } +} + +static void usb_audio_mute_control(uint32_t mute) +{ + TRACE(1,"MUTE CTRL: %u", mute); + + new_mute_state = mute; +#ifdef USB_AUDIO_MULTIFUNC + if (mute) { + new_playback_coef = 0; + } else { + new_playback_coef = playback_gain_to_float(new_playback_vol); + } +#endif + usb_audio_enqueue_cmd(AUDIO_CMD_MUTE_CTRL); +} + +static void usb_audio_cap_mute_control(uint32_t mute) +{ + TRACE(1,"CAP MUTE CTRL: %u", mute); + + new_cap_mute_state = mute; + usb_audio_enqueue_cmd(AUDIO_CMD_CAP_MUTE_CTRL); +} + +static void usb_audio_vol_control(uint32_t percent) +{ + if (percent >= 100) { + new_playback_vol = MAX_VOLUME_VAL; + } else { + new_playback_vol = MIN_VOLUME_VAL + (percent * (MAX_VOLUME_VAL - MIN_VOLUME_VAL) + 50) / 100; + } + + TRACE(2,"VOL CTRL: percent=%u new_playback_vol=%u", percent, new_playback_vol); + +#ifdef USB_AUDIO_MULTIFUNC + new_playback_coef = playback_gain_to_float(new_playback_vol); +#else + usb_audio_enqueue_cmd(AUDIO_CMD_SET_VOLUME); +#endif +} + +static void usb_audio_cap_vol_control(uint32_t percent) +{ + if (percent >= 100) { + new_capture_vol = MAX_CAP_VOLUME_VAL; + } else { + new_capture_vol = MIN_CAP_VOLUME_VAL + (percent * (MAX_CAP_VOLUME_VAL - MIN_CAP_VOLUME_VAL) + 50) / 100; + } + + TRACE(2,"CAP VOL CTRL: percent=%u new_capture_vol=%u", percent, new_capture_vol); + + usb_audio_enqueue_cmd(AUDIO_CMD_SET_CAP_VOLUME); +} + +static uint32_t usb_audio_get_vol_percent(void) +{ + if (new_playback_vol >= MAX_VOLUME_VAL) { + return 100; + } else if (new_playback_vol <= MIN_VOLUME_VAL) { + return 0; + } else { + return ((new_playback_vol - MIN_VOLUME_VAL) * 100 + (MAX_VOLUME_VAL - MIN_VOLUME_VAL) / 2) + / (MAX_VOLUME_VAL - MIN_VOLUME_VAL); + } +} + +static uint32_t usb_audio_get_cap_vol_percent(void) +{ + if (new_capture_vol >= MAX_CAP_VOLUME_VAL) { + return 100; + } else if (new_capture_vol <= MIN_CAP_VOLUME_VAL) { + return 0; + } else { + return ((new_capture_vol - MIN_CAP_VOLUME_VAL) * 100 + (MAX_CAP_VOLUME_VAL - MIN_CAP_VOLUME_VAL) / 2) + / (MAX_CAP_VOLUME_VAL - MIN_CAP_VOLUME_VAL); + } +} + +static void usb_audio_tune_rate(enum AUD_STREAM_T stream, float ratio) +{ + bool update_play, update_cap; + + update_play = true; + update_cap = false; + +#if defined(__AUDIO_RESAMPLE__) && defined(PLL_TUNE_SAMPLE_RATE) +#ifdef UAUD_SYNC_STREAM_TARGET + if (stream == AUD_STREAM_PLAYBACK) { + update_play = true; + update_cap = false; + } else { + update_play = false; + update_cap = true; + } +#else + update_play = true; + update_cap = true; +#endif +#endif + + if (update_play) { + rate_tune_ratio[AUD_STREAM_PLAYBACK] = rate_tune_ratio[AUD_STREAM_PLAYBACK] + + ratio + rate_tune_ratio[AUD_STREAM_PLAYBACK] * ratio; + } + if (update_cap) { + rate_tune_ratio[AUD_STREAM_CAPTURE] = rate_tune_ratio[AUD_STREAM_CAPTURE] + + ratio + rate_tune_ratio[AUD_STREAM_CAPTURE] * ratio; + } + + TRACE(4,"%s[%u]: ratio=%d resample_ratio=%d", __FUNCTION__, stream, FLOAT_TO_PPB_INT(ratio), + update_cap ? FLOAT_TO_PPB_INT(rate_tune_ratio[stream]) : FLOAT_TO_PPB_INT(rate_tune_ratio[AUD_STREAM_PLAYBACK])); + + enqueue_unique_cmd_arg(AUDIO_CMD_TUNE_RATE, 0, stream); +} + +static void usb_audio_data_recv_handler(const struct USB_AUDIO_XFER_INFO_T *info) +{ + const uint8_t *data; + uint32_t size; + uint32_t old_wpos, new_wpos, wpos_boundary, rpos; + uint32_t old_play_pos = 0; + uint32_t play_pos; + uint32_t lock; + int conflicted; + uint32_t recv_samp, play_samp; + uint32_t cur_time; + + cur_time = hal_sys_timer_get(); + last_usb_recv_time = cur_time; + + data = info->data; + size = info->size; + + if (info->cur_compl_err || info->next_xfer_err) { + if (usb_recv_err_cnt == 0) { + usb_recv_err_cnt++; + usb_recv_ok_cnt = 0; + last_usb_recv_err_time = cur_time; + } else { + usb_recv_err_cnt++; + } + } else { + if (usb_recv_err_cnt) { + usb_recv_ok_cnt++; + } + } + if (usb_recv_err_cnt && cur_time - last_usb_recv_err_time >= USB_XFER_ERR_REPORT_INTERVAL) { + if (info->cur_compl_err || info->next_xfer_err) { + TRACE(2,"recv: ERROR: cur_err=%d next_err=%d", info->cur_compl_err, info->next_xfer_err); + } + TRACE(3,"recv: ERROR-CNT: err=%u ok=%u in %u ms", usb_recv_err_cnt, usb_recv_ok_cnt, TICKS_TO_MS(USB_XFER_ERR_REPORT_INTERVAL)); + usb_recv_err_cnt = 0; + } + + if (usb_recv_buf <= data && data <= usb_recv_buf + usb_recv_size) { + if (data != usb_recv_buf + usb_recv_wpos) { + TRACE(3,"recv: WARNING: Invalid wpos=0x%x data=%p recv_buf=%p. IRQ missing?", usb_recv_wpos, data, usb_recv_buf); + usb_recv_wpos = data - usb_recv_buf; + } + } + + old_wpos = usb_recv_wpos; + new_wpos = old_wpos + size; + if (new_wpos >= usb_recv_size) { + new_wpos -= usb_recv_size; + } + + if (recv_state == AUDIO_ITF_STATE_STOPPED || + size == 0 || // rx paused + 0) { + usb_recv_valid = 0; + } else { + if (info->cur_compl_err == 0) { + usb_recv_valid = 1; + } + } + + if (usb_recv_valid == 0 || + usb_recv_init_rpos == 0 || + codec_config_lock || + codec_play_seq != usb_recv_seq || + codec_play_valid == 0 || + playback_state == AUDIO_ITF_STATE_STOPPED || + 0) { + usb_recv_wpos = new_wpos; + return; + } + + conflicted = 0; + + lock = int_lock(); + if (playback_conflicted) { + playback_conflicted = 0; + rpos = 0; // Avoid compiler warnings + conflicted = 1; + } else { + rpos = usb_recv_rpos; + old_play_pos = playback_pos; + play_pos = af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + } + int_unlock(lock); + + if (conflicted == 0) { + if (info->pool_enabled) { + // USBC will write to memory pool. + wpos_boundary = new_wpos; + } else { + // USBC will write to new_wpos directly, so the buffer [new_wpos, new_wpos + info->next_size) must be protected too. + wpos_boundary = new_wpos + info->next_size; + if (wpos_boundary >= usb_recv_size) { + wpos_boundary -= usb_recv_size; + } + } + + if (old_wpos <= rpos) { + if (wpos_boundary < old_wpos || rpos < wpos_boundary) { + conflicted = 1; + } + } else { + if (rpos < wpos_boundary && wpos_boundary < old_wpos) { + conflicted = 1; + } + } + + if (conflicted) { + uint32_t reset_len = usb_recv_size / 2; + uint32_t saved_old_wpos = old_wpos; + + // Reset write position + old_wpos = rpos + reset_len; + if (old_wpos >= usb_recv_size) { + old_wpos -= usb_recv_size; + } + new_wpos = old_wpos + size; + if (new_wpos >= usb_recv_size) { + new_wpos -= usb_recv_size; + } + +#if 0 + usb_audio_stop_recv(); + usb_audio_start_recv(usb_recv_buf, new_wpos, usb_recv_size); +#else + usb_audio_set_recv_pos(new_wpos); +#endif + + TRACE(4,"recv: Error: wpos=%u goes beyond rpos=%u with len=%u. Reset to %u", saved_old_wpos, rpos, size, old_wpos); + } + record_conflict(conflicted); + } + + usb_recv_wpos = new_wpos; + +#if (VERBOSE_TRACE & (1 << 5)) + { + int hw_play_pos = af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + TRACE_TIME(5,"recv: wpos=%u size=%u rpos=%u playback_pos=%u hw_play_pos=%d", old_wpos, size, + rpos, playback_pos, hw_play_pos); + } +#endif + + if (conflicted) { + usb_audio_sync_reset(&playback_info); + return; + } + + if (usb_recv_buf <= data && data <= usb_recv_buf + usb_recv_size) { + recv_samp = byte_to_samp_recv(new_wpos); + } else { + recv_samp = -1; + } + + if ((int)play_pos >= 0) { + if (play_pos >= playback_size) { + play_pos = 0; + } + // Count the bytes of data waiting to play in the codec buffer + uint32_t bytes_to_play; + if (old_play_pos <= play_pos) { + bytes_to_play = playback_size + old_play_pos - play_pos; + } else { + bytes_to_play = old_play_pos - play_pos; + } + uint32_t usb_bytes_to_play; + usb_bytes_to_play = playback_to_recv_len(bytes_to_play); + if (rpos >= usb_bytes_to_play) { + play_pos = rpos - usb_bytes_to_play; + } else { + play_pos = usb_recv_size + rpos - usb_bytes_to_play; + } + play_samp = byte_to_samp_recv(play_pos); + } else { + play_samp = -1; + } + + if (recv_samp != -1 && play_samp != -1) { + enum UAUD_SYNC_RET_T ret; + float ratio; + + ret = usb_audio_sync(play_samp, recv_samp, &playback_info, &ratio); + if (ret == UAUD_SYNC_START) { + usb_audio_tune_rate(AUD_STREAM_PLAYBACK, ratio); + } + } else { + //TRACE(2,"recv_hdlr: recv_samp=0x%08x play_samp=0x%08x", recv_samp, play_samp); + } + +#ifdef DSD_SUPPORT + if (sample_size_recv == 3 && (sample_rate_recv == 176400 || sample_rate_recv == 352800)) { + // First DoP solution marks + static const uint8_t pattern[2] = { 0x05, 0xFA, }; + // Second DoP solution marks -- not supported yet + //static const uint8_t pattern2[2] = { 0x06, 0xF9, }; + static const uint16_t dsd_detect_thresh = 32; + uint8_t idx; + const uint8_t *dsd, *dsd_end, *dsd_end2; + bool dsd_valid = true; + + dsd = data + 2; + dsd_end = data + size; + dsd_end2 = usb_recv_buf + usb_recv_size; + if (dsd_end <= dsd_end2) { + dsd_end2 = NULL; + } else { + dsd_end = dsd_end2; + dsd_end2 = data + size - usb_recv_size; + } + if (*dsd == pattern[0]) { + idx = 0; + } else { + idx = 1; + } + +_check_dsd: + while (dsd < dsd_end) { + if (*dsd == pattern[idx]) { +#if (CHAN_NUM_RECV == 2) + dsd += 3; + if (dsd >= dsd_end || *dsd != pattern[idx]) { + dsd_valid = false; + break; + } +#endif + if (usb_dsd_cont_cnt < dsd_detect_thresh) { + usb_dsd_cont_cnt += CHAN_NUM_RECV; + } + idx = !idx; + dsd += 3; + } else { + dsd_valid = false; + break; + } + } + if (dsd_valid && dsd_end2) { + dsd = usb_recv_buf + 2; + dsd_end = dsd_end2; + dsd_end2 = NULL; + goto _check_dsd; + } + + if (dsd_valid && usb_dsd_cont_cnt < dsd_detect_thresh) { + dsd_valid = false; + } + if (!dsd_valid) { + usb_dsd_cont_cnt = 0; + } + + if (dsd_valid != usb_dsd_enabled) { + usb_dsd_enabled = dsd_valid; + enqueue_unique_cmd(AUDIO_CMD_SET_DSD_CFG); + } + } +#endif +} + +static void usb_audio_data_send_handler(const struct USB_AUDIO_XFER_INFO_T *info) +{ + const uint8_t *data; + uint32_t size; + uint32_t old_rpos, new_rpos, rpos_boundary, wpos; + uint32_t old_cap_pos = 0; + uint32_t cap_pos; + uint32_t lock; + int conflicted; + uint32_t send_samp, cap_samp; + uint32_t cur_time; + + cur_time = hal_sys_timer_get(); + last_usb_send_time = cur_time; + + data = info->data; + size = info->size; + + if (info->cur_compl_err || info->next_xfer_err) { + if (usb_send_err_cnt == 0) { + usb_send_err_cnt++; + usb_send_ok_cnt = 0; + last_usb_send_err_time = cur_time; + } else { + usb_send_err_cnt++; + } + } else { + if (usb_send_err_cnt) { + usb_send_ok_cnt++; + } + } + if (usb_send_err_cnt && cur_time - last_usb_send_err_time >= USB_XFER_ERR_REPORT_INTERVAL) { + if (info->cur_compl_err || info->next_xfer_err) { + TRACE(2,"send: ERROR: cur_err=%d next_err=%d", info->cur_compl_err, info->next_xfer_err); + } + TRACE(3,"send: ERROR-CNT: err=%u ok=%u in %u ms", usb_send_err_cnt, usb_send_ok_cnt, TICKS_TO_MS(USB_XFER_ERR_REPORT_INTERVAL)); + usb_send_err_cnt = 0; + } + + if (info->pool_enabled) { + // The buffer [data, size) has been sent completely, and + // the buffer [data + size, data + size + info->next_size) has been copied to memory pool. + // Make usb_send_rpos point to the pending send buffer + data += size; + if (data >= usb_send_buf + usb_send_size) { + data -= usb_send_size; + } + size = info->next_size; + } + + if (usb_send_buf <= data && data <= usb_send_buf + usb_send_size) { + if (data != usb_send_buf + usb_send_rpos) { + if (usb_send_valid == 0 && info->pool_enabled && info->data != usb_send_buf + usb_send_rpos) { + TRACE(3,"send: WARNING: Invalid rpos=0x%x data=%p send_buf=%p. IRQ missing?", usb_send_rpos, data, usb_send_buf); + } + usb_send_rpos = data - usb_send_buf; + } + } + + old_rpos = usb_send_rpos; + new_rpos = old_rpos + size; + if (new_rpos >= usb_send_size) { + new_rpos -= usb_send_size; + } + + if (send_state == AUDIO_ITF_STATE_STOPPED || + size == 0 || // tx paused + 0) { + usb_send_valid = 0; + } else { + if (info->cur_compl_err == 0) { + usb_send_valid = 1; + } + } + + if (usb_send_valid == 0 || + usb_send_init_wpos == 0 || + codec_config_lock || + codec_cap_seq != usb_send_seq || + codec_cap_valid == 0 || + capture_state == AUDIO_ITF_STATE_STOPPED || + 0) { + usb_send_rpos = new_rpos; + if (usb_send_valid) { + // Zero the send buffer next to the part being sent by USB h/w + if (info->pool_enabled) { + uint32_t clr_len; + + clr_len = samp_to_byte_send(SAMP_RATE_TO_FRAME_SIZE(sample_rate_send)); + if (usb_send_rpos + clr_len <= usb_send_size) { + zero_mem16(usb_send_buf + usb_send_rpos, clr_len); + } else { + zero_mem16(usb_send_buf + usb_send_rpos, usb_send_size - usb_send_rpos); + zero_mem16(usb_send_buf, clr_len - (usb_send_size - usb_send_rpos)); + } + } else { + // If no pool is enabled, the send pkt size is a fixed value, and + // the send buffer size is a integral multiple of the send pkt size + if (usb_send_rpos + size + size <= usb_send_size) { + zero_mem32(usb_send_buf + usb_send_rpos + size, size); + } else { + zero_mem32(usb_send_buf, size); + } + } + } + return; + } + + conflicted = 0; + + lock = int_lock(); + if (capture_conflicted) { + capture_conflicted = 0; + wpos = 0; // Avoid compiler warnings + conflicted = 1; + } else { + wpos = usb_send_wpos; + old_cap_pos = capture_pos; + cap_pos = af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + } + int_unlock(lock); + + if (conflicted == 0) { + if (info->pool_enabled) { + // old_rpos points to the pending send buffer, which has been copied to memory pool. + // USBC will read from memory pool. + rpos_boundary = new_rpos; + } else { + // old_rpos points to the buffer just sent completely. + // USBC will read from new_rpos directly, so the buffer [new_rpos, new_rpos + info->next_size) must be protected too. + rpos_boundary = new_rpos + info->next_size; + if (rpos_boundary >= usb_recv_size) { + rpos_boundary -= usb_recv_size; + } + } + + if (old_rpos <= wpos) { + if (new_rpos < old_rpos || wpos < new_rpos) { + conflicted = 1; + } + } else { + if (wpos < new_rpos && new_rpos < old_rpos) { + conflicted = 1; + } + } + + if (conflicted) { + uint32_t reset_len = usb_send_size / 2; + uint32_t saved_old_rpos = old_rpos; + + // Reset read position + old_rpos = wpos + reset_len; + if (old_rpos >= usb_send_size) { + old_rpos -= usb_send_size; + } + new_rpos = old_rpos + size; + if (new_rpos >= usb_send_size) { + new_rpos -= usb_send_size; + } + +#if 0 + usb_audio_stop_send(); + usb_audio_start_send(usb_send_buf, new_rpos, usb_send_size); +#else + usb_audio_set_send_pos(new_rpos); +#endif + + TRACE(4,"send: Error: rpos=%u goes beyond wpos=%u with len=%u. Reset to %u", saved_old_rpos, wpos, size, old_rpos); + } + record_conflict(conflicted); + } + + usb_send_rpos = new_rpos; + +#if (VERBOSE_TRACE & (1 << 6)) + TRACE_TIME(3,"send: rpos=%u size=%u wpos=%u", old_rpos, size, wpos); +#endif + + if (conflicted) { + usb_audio_sync_reset(&capture_info); + return; + } + +#ifndef UAUD_SYNC_STREAM_TARGET + // Recv takes precedence + if (recv_state == AUDIO_ITF_STATE_STARTED) { + return; + } +#endif + + if (usb_send_buf <= data && data <= usb_send_buf + usb_send_size) { + send_samp = byte_to_samp_send(new_rpos); + } else { + send_samp = -1; + } + + if ((int)cap_pos >= 0) { + if (cap_pos >= capture_size) { + cap_pos = 0; + } + // Count the bytes of data newly captured in the codec buffer + uint32_t bytes_cap; + if (old_cap_pos <= cap_pos) { + bytes_cap = cap_pos - old_cap_pos; + } else { + bytes_cap = capture_size + cap_pos - old_cap_pos; + } + uint32_t usb_bytes_cap; + usb_bytes_cap = capture_to_send_len(bytes_cap); + cap_pos = wpos + usb_bytes_cap; + if (cap_pos >= usb_send_size) { + cap_pos -= usb_send_size; + } + cap_samp = byte_to_samp_send(cap_pos); + } else { + cap_samp = -1; + } + + if (send_samp != -1 && cap_samp != -1) { + enum UAUD_SYNC_RET_T ret; + float ratio; + + ret = usb_audio_sync(cap_samp, send_samp, &capture_info, &ratio); + if (ret == UAUD_SYNC_START) { + usb_audio_tune_rate(AUD_STREAM_CAPTURE, ratio); + } + } else { + //TRACE(2,"send_hdlr: send_samp=0x%08x cap_samp=0x%08x", send_samp, cap_samp); + } +} + +#ifdef USB_AUDIO_MULTIFUNC +static float playback_gain_to_float(uint32_t level) +{ + int32_t db; + + if (level > MAX_VOLUME_VAL || level < MIN_VOLUME_VAL) { + return 0; + } + + db = codec_dac_vol[level].sdac_volume; + if (db <= USB_AUDIO_MIN_DBVAL) { + return 0; + } + + return db_to_float(db); +} + +static void usb_audio_playback2_start(enum USB_AUDIO_ITF_CMD_T cmd) +{ + if (cmd == USB_AUDIO_ITF_STOP) { + // Stop the stream right now + if (recv2_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_recv2(); + if (recv_state == AUDIO_ITF_STATE_STOPPED && send_state == AUDIO_ITF_STATE_STOPPED) { + usb_audio_sync_reset(&playback_info); + } + recv2_state = AUDIO_ITF_STATE_STOPPED; + } + + if (recv_state == AUDIO_ITF_STATE_STARTED) { + return; + } + + enqueue_unique_cmd_with_opp(AUDIO_CMD_STOP_PLAY, usb_recv_seq, 0, AUDIO_CMD_START_PLAY); + } else { + if (recv2_state == AUDIO_ITF_STATE_STOPPED) { + int ret; + + reset_conflict(); + + if (recv_state == AUDIO_ITF_STATE_STOPPED && send_state == AUDIO_ITF_STATE_STOPPED) { + usb_audio_sync_reset(&playback_info); + } + + usb_recv2_valid = 0; + if (recv_state == AUDIO_ITF_STATE_STOPPED) { + usb_recv_seq++; + } + + usb_recv2_rpos = 0; + usb_recv2_wpos = usb_recv_size / 2; + zero_mem32(usb_recv2_buf, usb_recv2_size); + + usb_recv2_err_cnt = 0; + + ret = usb_audio_start_recv2(usb_recv2_buf, usb_recv2_wpos, usb_recv2_size); + if (ret == 1) { + TRACE(0,"usb_audio_start_recv2 failed: usb not configured"); + } else { + ASSERT(ret == 0, "usb_audio_start_recv2 failed: %d", ret); + } + recv2_state = AUDIO_ITF_STATE_STARTED; + } + + if (recv_state == AUDIO_ITF_STATE_STARTED) { + return; + } + + enqueue_unique_cmd_with_opp(AUDIO_CMD_START_PLAY, usb_recv_seq, 0, AUDIO_CMD_STOP_PLAY); + } +} + +static void usb_audio_mute2_control(uint32_t mute) +{ + TRACE(1,"MUTE2 CTRL: %u", mute); + + new_mute2_state = mute; + if (mute) { + new_playback2_coef = 0; + } else { + new_playback2_coef = playback_gain_to_float(new_playback2_vol); + } + usb_audio_enqueue_cmd(AUDIO_CMD_MUTE_CTRL); +} + +static void usb_audio_vol2_control(uint32_t percent) +{ + if (percent >= 100) { + new_playback2_vol = MAX_VOLUME_VAL; + } else { + new_playback2_vol = MIN_VOLUME_VAL + (percent * (MAX_VOLUME_VAL - MIN_VOLUME_VAL) + 50) / 100; + } + + new_playback2_coef = playback_gain_to_float(new_playback2_vol); + + TRACE(2,"VOL2 CTRL: percent=%u new_playback_vol=%u", percent, new_playback2_vol); +} + +static uint32_t usb_audio_get_vol2_percent(void) +{ + if (new_playback2_vol >= MAX_VOLUME_VAL) { + return 100; + } else { + return ((new_playback2_vol - MIN_VOLUME_VAL) * 100 + (MAX_VOLUME_VAL - MIN_VOLUME_VAL) / 2) + / (MAX_VOLUME_VAL - MIN_VOLUME_VAL); + } +} + +static void usb_audio_data_recv2_handler(const struct USB_AUDIO_XFER_INFO_T *info) +{ + const uint8_t *data; + uint32_t size; + uint32_t old_wpos, new_wpos, wpos_boundary, rpos; + uint32_t old_play_pos = 0; + uint32_t play_pos; + uint32_t lock; + int conflicted; + uint32_t recv_samp, play_samp; + uint32_t cur_time; + + cur_time = hal_sys_timer_get(); + last_usb_recv_time = cur_time; + + data = info->data; + size = info->size; + + if (info->cur_compl_err || info->next_xfer_err) { + if (usb_recv2_err_cnt == 0) { + usb_recv2_err_cnt++; + usb_recv2_ok_cnt = 0; + last_usb_recv2_err_time = cur_time; + } else { + usb_recv2_err_cnt++; + } + } else { + if (usb_recv2_err_cnt) { + usb_recv2_ok_cnt++; + } + } + if (usb_recv2_err_cnt && cur_time - last_usb_recv2_err_time >= USB_XFER_ERR_REPORT_INTERVAL) { + if (info->cur_compl_err || info->next_xfer_err) { + TRACE(2,"recv2: ERROR: cur_err=%d next_err=%d", info->cur_compl_err, info->next_xfer_err); + } + TRACE(3,"recv2: ERROR-CNT: err=%u ok=%u in %u ms", usb_recv2_err_cnt, usb_recv2_ok_cnt, TICKS_TO_MS(USB_XFER_ERR_REPORT_INTERVAL)); + usb_recv2_err_cnt = 0; + } + + if (usb_recv2_buf <= data && data <= usb_recv2_buf + usb_recv2_size) { + if (data != usb_recv2_buf + usb_recv2_wpos) { + TRACE(3,"recv2: WARNING: Invalid wpos=0x%x data=%p recv2_buf=%p. IRQ missing?", usb_recv2_wpos, data, usb_recv2_buf); + usb_recv2_wpos = data - usb_recv2_buf; + } + } + + old_wpos = usb_recv2_wpos; + new_wpos = old_wpos + size; + if (new_wpos >= usb_recv2_size) { + new_wpos -= usb_recv2_size; + } + + if (codec_config_lock || + codec_play_seq != usb_recv_seq || + codec_play_valid == 0 || + playback_state == AUDIO_ITF_STATE_STOPPED || + recv2_state == AUDIO_ITF_STATE_STOPPED || + size == 0 || // rx paused + 0) { + usb_recv2_valid = 0; + } else { + if (info->cur_compl_err == 0) { + usb_recv2_valid = 1; + } + } + + if (usb_recv2_valid == 0 || usb_recv2_init_rpos == 0) { + usb_recv2_wpos = new_wpos; + return; + } + + conflicted = 0; + + lock = int_lock(); + if (playback_conflicted2) { + playback_conflicted2 = 0; + rpos = 0; // Avoid compiler warnings + conflicted = 1; + } else { + rpos = usb_recv2_rpos; + old_play_pos = playback_pos; + play_pos = af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + } + int_unlock(lock); + + if (conflicted == 0) { + if (info->pool_enabled) { + // USBC will write to memory pool. + wpos_boundary = new_wpos; + } else { + // USBC will write to new_wpos directly, so the buffer [new_wpos, new_wpos + info->next_size) must be protected too. + wpos_boundary = new_wpos + info->next_size; + if (wpos_boundary >= usb_recv2_size) { + wpos_boundary -= usb_recv2_size; + } + } + + if (old_wpos <= rpos) { + if (wpos_boundary < old_wpos || rpos < wpos_boundary) { + conflicted = 1; + } + } else { + if (rpos < wpos_boundary && wpos_boundary < old_wpos) { + conflicted = 1; + } + } + + if (conflicted) { + uint32_t reset_len = usb_recv2_size / 2; + uint32_t saved_old_wpos = old_wpos; + + // Reset read position + old_wpos = rpos + reset_len; + if (old_wpos >= usb_recv2_size) { + old_wpos -= usb_recv2_size; + } + new_wpos = old_wpos + size; + if (new_wpos >= usb_recv2_size) { + new_wpos -= usb_recv2_size; + } + +#if 0 + usb_audio_stop_recv(); + usb_audio_start_recv(usb_recv2_buf, new_wpos, usb_recv2_size); +#else + usb_audio_set_recv2_pos(new_wpos); +#endif + + TRACE(4,"recv2: Error: wpos=%u goes beyond rpos=%u with len=%u. Reset to %u", saved_old_wpos, rpos, size, old_wpos); + } + record_conflict(conflicted); + } + + usb_recv2_wpos = new_wpos; + +#if (VERBOSE_TRACE & (1 << 5)) + { + int hw_play_pos = af_stream_get_cur_dma_pos(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK); + TRACE_TIME(5,"recv2: wpos=%u size=%u rpos=%u playback_pos=%u hw_play_pos=%d", old_wpos, size, + rpos, playback_pos, hw_play_pos); + } +#endif + + if (conflicted) { + usb_audio_sync_reset(&playback_info); + return; + } + + // Recv and send takes precedence + if (recv_state == AUDIO_ITF_STATE_STARTED || send_state == AUDIO_ITF_STATE_STARTED) { + return; + } + + if (usb_recv2_buf <= data && data <= usb_recv2_buf + usb_recv2_size) { + recv_samp = byte_to_samp_recv(new_wpos); + } else { + recv_samp = -1; + } + + if ((int)play_pos >= 0) { + if (play_pos >= playback_size) { + play_pos = 0; + } + // Count the bytes of data waiting to play in the codec buffer + uint32_t bytes_to_play; + if (old_play_pos <= play_pos) { + bytes_to_play = playback_size + old_play_pos - play_pos; + } else { + bytes_to_play = old_play_pos - play_pos; + } + uint32_t usb_bytes_to_play; + usb_bytes_to_play = playback_to_recv_len(bytes_to_play); + if (rpos >= usb_bytes_to_play) { + play_pos = rpos - usb_bytes_to_play; + } else { + play_pos = usb_recv2_size + rpos - usb_bytes_to_play; + } + play_samp = byte_to_samp_recv(play_pos); + } else { + play_samp = -1; + } + + if (recv_samp != -1 && play_samp != -1) { + enum UAUD_SYNC_RET_T ret; + float ratio; + + ret = usb_audio_sync(play_samp, recv_samp, &playback_info, &ratio); + if (ret == UAUD_SYNC_START) { + usb_audio_tune_rate(AUD_STREAM_PLAYBACK, ratio); + } + } else { + //TRACE(2,"recv_hdlr: recv_samp=0x%08x play_samp=0x%08x", recv_samp, play_samp); + } +} +#endif + +static void usb_audio_reset_usb_stream_state(bool init) +{ + if (init) { + recv_state = AUDIO_ITF_STATE_STOPPED; + send_state = AUDIO_ITF_STATE_STOPPED; + +#ifdef USB_AUDIO_DYN_CFG + // Reset itf setting + playback_itf_set = 0; + capture_itf_set = 0; +#endif + + // Reset mute and volume setting + new_mute_state = 0; + new_cap_mute_state = 0; + + new_playback_vol = AUDIO_OUTPUT_VOLUME_DEFAULT; + if (new_playback_vol > MAX_VOLUME_VAL) { + new_playback_vol = MAX_VOLUME_VAL; + } else if (new_playback_vol < MIN_VOLUME_VAL) { + new_playback_vol = MIN_VOLUME_VAL; + } + + new_capture_vol = CODEC_SADC_VOL; + if (new_capture_vol > MAX_CAP_VOLUME_VAL) { + new_capture_vol = MAX_CAP_VOLUME_VAL; + } else if (new_capture_vol < MIN_CAP_VOLUME_VAL) { + new_capture_vol = MIN_CAP_VOLUME_VAL; + } + +#ifdef USB_AUDIO_MULTIFUNC + new_playback_coef = playback_gain_to_float(new_playback_vol); + playback_coef = new_playback_coef; + + recv2_state = AUDIO_ITF_STATE_STOPPED; + new_mute2_state = 0; + new_playback2_vol = AUDIO_OUTPUT_VOLUME_DEFAULT; + if (new_playback2_vol > MAX_VOLUME_VAL) { + new_playback2_vol = MAX_VOLUME_VAL; + } else if (new_playback2_vol < MIN_VOLUME_VAL) { + new_playback2_vol = MIN_VOLUME_VAL; + } + new_playback2_coef = playback_gain_to_float(new_playback2_vol); + playback2_coef = new_playback2_coef; +#endif + } else { + if (recv_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_usb_stream(AUD_STREAM_PLAYBACK); + recv_state = AUDIO_ITF_STATE_STOPPED; + } + if (send_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_usb_stream(AUD_STREAM_CAPTURE); + send_state = AUDIO_ITF_STATE_STOPPED; + } + +#ifdef USB_AUDIO_MULTIFUNC + if (recv2_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_recv2(); + if (recv_state == AUDIO_ITF_STATE_STOPPED && send_state == AUDIO_ITF_STATE_STOPPED) { + usb_audio_sync_reset(&playback_info); + } + recv2_state = AUDIO_ITF_STATE_STOPPED; + } +#endif + + // Keep old itf setting unless it is in init mode + + // Keep old mute and playback volume setting unless it is in init mode + } +} + +static void usb_audio_reset_codec_stream_state(bool init) +{ + playback_state = AUDIO_ITF_STATE_STOPPED; + capture_state = AUDIO_ITF_STATE_STOPPED; + +#ifndef USB_AUDIO_MULTIFUNC + playback_vol = new_playback_vol; +#endif + capture_vol = new_capture_vol; + + playback_paused = 0; + + playback_conflicted = 0; +#ifdef USB_AUDIO_MULTIFUNC + playback_conflicted2 = 0; +#endif + capture_conflicted = 0; + + // Keep old mute setting unless it is in init mode + if (init) { +#ifdef PERF_TEST_POWER_KEY + perft_power_type = 0; + af_codec_set_perf_test_power(perft_power_type); +#endif +#ifdef PA_ON_OFF_KEY + if (pa_on_off_muted) { + pa_on_off_muted = false; + if (mute_user_map == 0) { + usb_audio_codec_unmute(CODEC_MUTE_USER_ALL); + } + } +#endif + if (mute_user_map) { + mute_user_map = 0; + usb_audio_codec_unmute(CODEC_MUTE_USER_ALL); + } +#if defined(NOISE_GATING) && defined(NOISE_REDUCTION) + restore_noise_reduction_status(); +#endif + } +} + +#ifdef USB_AUDIO_DYN_CFG +static void usb_audio_set_recv_rate(enum AUD_SAMPRATE_T rate) +{ +#ifndef USB_AUDIO_UAC2 + if (playback_itf_set == 0) { + TRACE(1,"\nWARNING: Set recv rate while itf not set: %d\n", rate); + return; + } +#endif + + // Some host applications will not stop current stream before changing sample rate + if (recv_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_usb_stream(AUD_STREAM_PLAYBACK); + recv_state = AUDIO_ITF_STATE_STOPPED; + } + + TRACE(3,"%s: Change recv sample rate from %u to %u", __FUNCTION__, sample_rate_recv, rate); + + new_sample_rate_recv = rate; + +#ifdef KEEP_SAME_LATENCY + usb_recv_size = calc_usb_recv_size(new_sample_rate_recv, new_sample_size_recv); + TRACE(2,"%s: Set usb_recv_size=%u", __FUNCTION__, usb_recv_size); +#endif + + if (playback_itf_set) { + usb_audio_start_usb_stream(AUD_STREAM_PLAYBACK); + recv_state = AUDIO_ITF_STATE_STARTED; + } + +#ifdef USB_AUDIO_UAC2 + enqueue_unique_cmd_arg(AUDIO_CMD_SET_RECV_RATE, usb_recv_seq, 0); +#else + enqueue_unique_cmd_with_opp(AUDIO_CMD_SET_RECV_RATE, usb_recv_seq, 0, AUDIO_CMD_STOP_PLAY); +#endif +} + +static void usb_audio_set_send_rate(enum AUD_SAMPRATE_T rate) +{ +#ifndef USB_AUDIO_UAC2 + if (capture_itf_set == 0) { + TRACE(1,"\nWARNING: Set send rate while itf not set: %d\n", rate); + return; + } +#endif + + // Some host applications will not stop current stream before changing sample rate + if (send_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_usb_stream(AUD_STREAM_CAPTURE); + send_state = AUDIO_ITF_STATE_STOPPED; + } + + TRACE(3,"%s: Change send sample rate from %u to %u", __FUNCTION__, sample_rate_send, rate); + + new_sample_rate_send = rate; + +#ifdef KEEP_SAME_LATENCY + usb_send_size = calc_usb_send_size(new_sample_rate_send); + TRACE(2,"%s: Set usb_send_size=%u", __FUNCTION__, usb_send_size); +#endif + + if (capture_itf_set) { + usb_audio_start_usb_stream(AUD_STREAM_CAPTURE); + send_state = AUDIO_ITF_STATE_STARTED; + } + +#ifdef USB_AUDIO_UAC2 + enqueue_unique_cmd_arg(AUDIO_CMD_SET_SEND_RATE, usb_send_seq, 0); +#else + enqueue_unique_cmd_with_opp(AUDIO_CMD_SET_SEND_RATE, usb_send_seq, 0, AUDIO_CMD_STOP_CAPTURE); +#endif +} +#endif + +static void usb_audio_state_control(enum USB_AUDIO_STATE_EVENT_T event, uint32_t param) +{ + TRACE(3,"%s: %d (%u)", __FUNCTION__, event, param); + + if (event == USB_AUDIO_STATE_RESET || event == USB_AUDIO_STATE_DISCONNECT || event == USB_AUDIO_STATE_CONFIG) { + usb_audio_reset_usb_stream_state(true); + } else if (event == USB_AUDIO_STATE_SLEEP || event == USB_AUDIO_STATE_WAKEUP) { + usb_audio_reset_usb_stream_state(false); + } + + if (event == USB_AUDIO_STATE_RESET) { + usb_audio_enqueue_cmd(AUDIO_CMD_USB_RESET); + } else if (event == USB_AUDIO_STATE_DISCONNECT) { + usb_audio_enqueue_cmd(AUDIO_CMD_USB_DISCONNECT); + } else if (event == USB_AUDIO_STATE_CONFIG) { + usb_audio_enqueue_cmd(AUDIO_CMD_USB_CONFIG); + } else if (event == USB_AUDIO_STATE_SLEEP) { + usb_audio_enqueue_cmd(AUDIO_CMD_USB_SLEEP); + } else if (event == USB_AUDIO_STATE_WAKEUP) { + usb_audio_enqueue_cmd(AUDIO_CMD_USB_WAKEUP); + } else if (event == USB_AUDIO_STATE_RECV_PAUSE || event == USB_AUDIO_STATE_RECV2_PAUSE) { +#ifndef USB_AUDIO_MULTIFUNC + enqueue_unique_cmd_with_opp(AUDIO_CMD_RECV_PAUSE, usb_recv_seq, 0, AUDIO_CMD_RECV_CONTINUE); +#endif + } else if (event == USB_AUDIO_STATE_RECV_CONTINUE || event == USB_AUDIO_STATE_RECV2_CONTINUE) { +#ifndef USB_AUDIO_MULTIFUNC + enqueue_unique_cmd_with_opp(AUDIO_CMD_RECV_CONTINUE, usb_recv_seq, 0, AUDIO_CMD_RECV_PAUSE); +#endif +#ifdef USB_AUDIO_DYN_CFG + } else if (event == USB_AUDIO_STATE_SET_RECV_RATE) { + usb_audio_set_recv_rate(param); + } else if (event == USB_AUDIO_STATE_SET_SEND_RATE) { + usb_audio_set_send_rate(param); +#endif + } else { + ASSERT(false, "Bad state event"); + } +} + +static void usb_audio_acquire_freq(void) +{ + enum HAL_CMU_FREQ_T freq; + +#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) +#ifdef SW_CAPTURE_RESAMPLE + if (resample_cap_enabled) { + freq = HAL_CMU_FREQ_104M; + } else +#endif + if (capture_state == AUDIO_ITF_STATE_STARTED) { +#ifdef DUAL_AUX_MIC_MORE_FILTER + freq = HAL_CMU_FREQ_104M; +#else + freq = HAL_CMU_FREQ_78M; +#endif + } else +#else // !(CHIP_BEST1000 && _DUAL_AUX_MIC_) +#ifdef SW_CAPTURE_RESAMPLE + if (resample_cap_enabled) { +#ifdef CHIP_BEST1000 + freq = HAL_CMU_FREQ_78M; +#else + freq = HAL_CMU_FREQ_52M; +#endif + } else +#endif +#endif // !(CHIP_BEST1000 && _DUAL_AUX_MIC_) + { + freq = HAL_CMU_FREQ_52M; + } + +#if defined(USB_HIGH_SPEED) && defined(USB_AUDIO_UAC2) + if (playback_state == AUDIO_ITF_STATE_STARTED && sample_rate_play >= AUD_SAMPRATE_352800) { + if (freq < HAL_CMU_FREQ_104M) { + freq = HAL_CMU_FREQ_104M; + } + } +#endif + +#ifdef AUDIO_ANC_FB_MC + if (freq < HAL_CMU_FREQ_104M) { + freq = HAL_CMU_FREQ_104M; + } +#endif + +#ifdef __HW_FIR_DSD_PROCESS__ + if (freq < HAL_CMU_FREQ_104M) { + freq = HAL_CMU_FREQ_104M; + } +#endif + +#ifdef USB_AUDIO_SPEECH + enum HAL_CMU_FREQ_T speech_freq; + + speech_freq = speech_process_need_freq(); + if (freq < speech_freq) { + freq = speech_freq; + } +#endif + + hal_sysfreq_req(HAL_SYSFREQ_USER_APP_2, freq); + //TRACE(2,"[%s] app_sysfreq_req %d", __FUNCTION__, freq); + //TRACE(2,"[%s] sys freq calc : %d\n", __FUNCTION__, hal_sys_timer_calc_cpu_freq(5, 0)); +} + +static void usb_audio_release_freq(void) +{ + hal_sysfreq_req(HAL_SYSFREQ_USER_APP_2, HAL_CMU_FREQ_32K); +} + +static void usb_audio_update_freq(void) +{ + usb_audio_acquire_freq(); +} + +#ifdef SW_CAPTURE_RESAMPLE + +static enum AUD_CHANNEL_NUM_T get_capture_resample_chan_num(void) +{ +#if (CHAN_NUM_CAPTURE == CHAN_NUM_SEND) + return chan_num_to_enum(CHAN_NUM_CAPTURE); +#else + return AUD_CHANNEL_NUM_1; +#endif +} + +static void capture_stream_resample_config(void) +{ + struct RESAMPLE_CFG_T cfg; + enum RESAMPLE_STATUS_T ret; + enum AUD_SAMPRATE_T cap_rate; + +#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) + cap_rate = sample_rate_ref_cap; +#else + cap_rate = sample_rate_cap; +#endif + +#ifndef __AUDIO_RESAMPLE__ + if (cap_rate == sample_rate_send) { + if (resample_cap_enabled) { + TRACE(1,"!!! %s: Disable capture resample", __FUNCTION__); + + audio_resample_ex_close(resample_id); + resample_cap_enabled = false; + } + } else +#endif + { + if (!resample_cap_enabled) { + // Resample chan num is usb send chan num + memset(&cfg, 0, sizeof(cfg)); + cfg.chans = get_capture_resample_chan_num(); + cfg.bits = sample_size_to_enum_capture(sample_size_cap); +#ifdef __AUDIO_RESAMPLE__ + if (sample_rate_send % AUD_SAMPRATE_8000) { + ASSERT(hal_cmu_get_crystal_freq() / (CODEC_FREQ_44_1K_SERIES / sample_rate_send) == cap_rate, + "%s: Bad cap_rate=%u with sample_rate_send=%u", __FUNCTION__, cap_rate, sample_rate_send); +#if (CODEC_FREQ_26M / CODEC_FREQ_CRYSTAL * CODEC_FREQ_CRYSTAL == CODEC_FREQ_26M) + cfg.coef = &resample_coef_50p7k_to_44p1k; +#else + cfg.coef = &resample_coef_46p8k_to_44p1k; +#endif + } else { + ASSERT(hal_cmu_get_crystal_freq() / (CODEC_FREQ_48K_SERIES / sample_rate_send) == cap_rate, + "%s: Bad cap_rate=%u with sample_rate_send=%u", __FUNCTION__, cap_rate, sample_rate_send); +#if (CODEC_FREQ_26M / CODEC_FREQ_CRYSTAL * CODEC_FREQ_CRYSTAL == CODEC_FREQ_26M) + cfg.coef = &resample_coef_50p7k_to_48k; +#else + cfg.coef = &resample_coef_46p8k_to_48k; +#endif + } +#else + if (sample_rate_send % AUD_SAMPRATE_8000) { + ASSERT(CODEC_FREQ_48K_SERIES / (CODEC_FREQ_44_1K_SERIES / sample_rate_send) == cap_rate, + "%s: Bad cap_rate=%u with sample_rate_send=%u", __FUNCTION__, cap_rate, sample_rate_send); + cfg.coef = &resample_coef_48k_to_44p1k; + } else { + ASSERT(CODEC_FREQ_44_1K_SERIES / (CODEC_FREQ_48K_SERIES / sample_rate_send) == cap_rate, + "%s: Bad cap_rate=%u with sample_rate_send=%u", __FUNCTION__, cap_rate, sample_rate_send); + cfg.coef = &resample_coef_44p1k_to_48k; + } +#endif + cfg.buf = resample_history_buf; + cfg.size = resample_history_size; + + TRACE(3,"!!! %s: Enable capture resample %u => %u", __FUNCTION__, cap_rate, sample_rate_send); + + ret = audio_resample_ex_open(&cfg, &resample_id); + ASSERT(ret == RESAMPLE_STATUS_OK, "%s: Failed to init resample: %d", __FUNCTION__, ret); + + resample_cap_enabled = true; + } + } +} + +#endif + +static void usb_audio_init_streams(enum AUDIO_STREAM_REQ_USER_T user) +{ + bool action; + + action = false; +#ifndef DELAY_STREAM_OPEN + if (user == AUDIO_STREAM_REQ_USB) { + action = true; + } +#endif +#ifdef ANC_L_R_MISALIGN_WORKAROUND + if (user == AUDIO_STREAM_REQ_ANC) { + action = true; + } +#endif + if (action) + { + usb_audio_open_codec_stream(AUD_STREAM_PLAYBACK, user); + usb_audio_open_codec_stream(AUD_STREAM_CAPTURE, user); + } + +#ifdef ANC_L_R_MISALIGN_WORKAROUND + if (user == AUDIO_STREAM_REQ_ANC) { + usb_audio_start_codec_stream(AUD_STREAM_PLAYBACK, user); + usb_audio_start_codec_stream(AUD_STREAM_CAPTURE, user); + } +#endif +} + +static void usb_audio_term_streams(enum AUDIO_STREAM_REQ_USER_T user) +{ + // Ensure all the streams for this user are stopped and closed + usb_audio_stop_codec_stream(AUD_STREAM_CAPTURE, user); + usb_audio_stop_codec_stream(AUD_STREAM_PLAYBACK, user); + + usb_audio_close_codec_stream(AUD_STREAM_CAPTURE, user); + usb_audio_close_codec_stream(AUD_STREAM_PLAYBACK, user); +} + +#if defined(ANDROID_ACCESSORY_SPEC) || defined(CFG_MIC_KEY) +static void hid_data_send_handler(enum USB_AUDIO_HID_EVENT_T event, int error) +{ + TRACE(2,"HID SENT: event=0x%04x error=%d", event, error); +} +#endif + +static void usb_audio_itf_callback(enum USB_AUDIO_ITF_ID_T id, enum USB_AUDIO_ITF_CMD_T cmd) +{ + if (0) { +#ifdef USB_AUDIO_MULTIFUNC + } else if (id == USB_AUDIO_ITF_ID_RECV2) { + usb_audio_playback2_start(cmd); +#endif + } else if (id == USB_AUDIO_ITF_ID_RECV) { + usb_audio_playback_start(cmd); + } else { + usb_audio_capture_start(cmd); + } +} + +static void usb_audio_mute_callback(enum USB_AUDIO_ITF_ID_T id, uint32_t mute) +{ + if (0) { +#ifdef USB_AUDIO_MULTIFUNC + } else if (id == USB_AUDIO_ITF_ID_RECV2) { + usb_audio_mute2_control(mute); +#endif + } else if (id == USB_AUDIO_ITF_ID_RECV) { + usb_audio_mute_control(mute); + } else { + usb_audio_cap_mute_control(mute); + } +} + +static void usb_audio_set_volume(enum USB_AUDIO_ITF_ID_T id, uint32_t percent) +{ + if (0) { +#ifdef USB_AUDIO_MULTIFUNC + } else if (id == USB_AUDIO_ITF_ID_RECV2) { + usb_audio_vol2_control(percent); +#endif + } else if (id == USB_AUDIO_ITF_ID_RECV) { + usb_audio_vol_control(percent); + } else { + usb_audio_cap_vol_control(percent); + } +} + +static uint32_t usb_audio_get_volume(enum USB_AUDIO_ITF_ID_T id) +{ + uint32_t percent = 0; + + if (0) { +#ifdef USB_AUDIO_MULTIFUNC + } else if (id == USB_AUDIO_ITF_ID_RECV2) { + percent = usb_audio_get_vol2_percent(); +#endif + } else if (id == USB_AUDIO_ITF_ID_RECV) { + percent = usb_audio_get_vol_percent(); + } else { + percent = usb_audio_get_cap_vol_percent(); + } + + return percent; +} + +static void usb_audio_xfer_callback(enum USB_AUDIO_ITF_ID_T id, const struct USB_AUDIO_XFER_INFO_T *info) +{ + if (0) { +#ifdef USB_AUDIO_MULTIFUNC + } else if (id == USB_AUDIO_ITF_ID_RECV2) { + usb_audio_data_recv2_handler(info); +#endif + } else if (id == USB_AUDIO_ITF_ID_RECV) { + usb_audio_data_recv_handler(info); + } else { + usb_audio_data_send_handler(info); + } +} + +static void usb_audio_stream_running_handler(void) +{ + enum AUDIO_STREAM_RUNNING_T req; + uint32_t lock; + + req = streams_running_req; + + if (req == AUDIO_STREAM_RUNNING_NULL) { + return; + } else if (req == AUDIO_STREAM_RUNNING_ENABLED) { + usb_audio_init_streams(AUDIO_STREAM_REQ_ANC); + } else if (req == AUDIO_STREAM_RUNNING_DISABLED) { + usb_audio_term_streams(AUDIO_STREAM_REQ_ANC); + } + + lock = int_lock(); + if (req == streams_running_req) { + streams_running_req = AUDIO_STREAM_RUNNING_NULL; + } + int_unlock(lock); +} + +void usb_audio_keep_streams_running(bool enable) +{ + if (enable) { + streams_running_req = AUDIO_STREAM_RUNNING_ENABLED; + } else { + streams_running_req = AUDIO_STREAM_RUNNING_DISABLED; + } + + // TODO: Move usb_audio_stream_running_handler() into usb_audio_app_loop() ? + // How to ensure that streams are opened before ANC is enabled? + usb_audio_stream_running_handler(); +} + +#ifdef USB_AUDIO_DYN_CFG + +static enum AUD_SAMPRATE_T calc_play_sample_rate(enum AUD_SAMPRATE_T usb_rate) +{ + enum AUD_SAMPRATE_T codec_rate; + +#if defined(CHIP_BEST1000) && defined(ANC_APP) + + codec_rate = (usb_rate % AUD_SAMPRATE_8000) ? AUD_SAMPRATE_88200 : AUD_SAMPRATE_96000; + +#else + + codec_rate = usb_rate; + +#if defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) + if (codec_rate % AUD_SAMPRATE_8000) { + codec_rate = hal_cmu_get_crystal_freq() / (CODEC_FREQ_44_1K_SERIES / codec_rate); + } else { + codec_rate = hal_cmu_get_crystal_freq() / (CODEC_FREQ_48K_SERIES / codec_rate); + } +#endif + +#endif + + return codec_rate; +} + +#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) +static enum AUD_SAMPRATE_T calc_anc_cap_sample_rate_best1000(enum AUD_SAMPRATE_T usb_rate, enum AUD_SAMPRATE_T play_rate) +{ + enum AUD_SAMPRATE_T rate_cap; + +#ifdef ANC_APP + +#ifdef AUD_PLL_DOUBLE +#if defined(_DUAL_AUX_MIC_) || defined(CAPTURE_ANC_DATA) + rate_cap = play_rate * 8; +#else + rate_cap = play_rate * 2; +#endif +#else // !AUD_PLL_DOUBLE +#if defined(_DUAL_AUX_MIC_) || defined(CAPTURE_ANC_DATA) + rate_cap = play_rate * 4; +#else + rate_cap = play_rate; +#endif +#endif // !AUD_PLL_DOUBLE + +#else // _DUAL_AUX_MIC_ + + // Capture reference + enum AUD_SAMPRATE_T rate_cap_ref; + + rate_cap_ref = (usb_rate % AUD_SAMPRATE_8000) ? AUD_SAMPRATE_44100 : AUD_SAMPRATE_48000; + + rate_cap = rate_cap_ref * 4; + +#endif + + return rate_cap; +} +#endif + +static enum AUD_SAMPRATE_T calc_cap_sample_rate(enum AUD_SAMPRATE_T usb_rate, enum AUD_SAMPRATE_T play_rate) +{ +#if defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_)) + + return calc_anc_cap_sample_rate_best1000(usb_rate, play_rate); + +#else // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) + + enum AUD_SAMPRATE_T codec_rate; + +#ifdef __AUDIO_RESAMPLE__ + + codec_rate = usb_rate; + +#ifdef SW_CAPTURE_RESAMPLE + if (codec_rate % AUD_SAMPRATE_8000) { + codec_rate = hal_cmu_get_crystal_freq() / (CODEC_FREQ_44_1K_SERIES / codec_rate); + } else { + codec_rate = hal_cmu_get_crystal_freq() / (CODEC_FREQ_48K_SERIES / codec_rate); + } +#endif + +#else // ! __AUDIO_RESAMPLE__ + + bool usb_rate_44p1k; + bool play_rate_44p1k; + + usb_rate_44p1k = !!(usb_rate % AUD_SAMPRATE_8000); + play_rate_44p1k = !!(play_rate % AUD_SAMPRATE_8000); + + if (usb_rate_44p1k ^ play_rate_44p1k) { + // Playback pll is NOT compatible with capture sample rate + if (usb_rate_44p1k) { + codec_rate = CODEC_FREQ_48K_SERIES / (CODEC_FREQ_44_1K_SERIES / usb_rate); + } else { + codec_rate = CODEC_FREQ_44_1K_SERIES / (CODEC_FREQ_48K_SERIES / usb_rate); + } + } else { + // Playback pll is compatible with capture sample rate + codec_rate = usb_rate; + } + +#endif // !__AUDIO_RESAMPLE__ + + return codec_rate; + +#endif // !(CHIP_BEST1000 && (ANC_APP || _DUAL_AUX_MIC_)) +} + +#endif // USB_AUDIO_DYN_CFG + +static void POSSIBLY_UNUSED usb_audio_update_codec_stream(enum AUD_STREAM_T stream) +{ + bool update_play; + bool update_cap; +#ifdef STREAM_RATE_BITS_SETUP + struct AF_STREAM_CONFIG_T *cfg, stream_cfg; + uint32_t ret; +#endif + + update_play = false; + update_cap = false; + +#ifdef USB_AUDIO_DYN_CFG + enum AUD_SAMPRATE_T new_recv_rate; + enum AUD_SAMPRATE_T new_send_rate; + enum AUD_SAMPRATE_T play_rate; + enum AUD_SAMPRATE_T cap_rate; + uint8_t new_recv_size; + uint32_t lock; + + lock = int_lock(); + new_recv_rate = new_sample_rate_recv; + new_recv_size = new_sample_size_recv; + new_send_rate = new_sample_rate_send; + int_unlock(lock); + + play_rate = sample_rate_play; + cap_rate = sample_rate_cap; + + if (stream == AUD_STREAM_PLAYBACK) { + if (sample_rate_recv == new_recv_rate && sample_size_recv == new_recv_size) { + // No change + goto _done_rate_size_check; + } +#ifdef AUDIO_PLAYBACK_24BIT + if (sample_rate_recv == new_recv_rate && sample_size_recv != new_recv_size) { + // No codec change. Only a change in usb sample size + TRACE(3,"%s:1: Update recv sample size from %u to %u", __FUNCTION__, sample_size_recv, new_recv_size); + sample_size_recv = new_recv_size; + update_playback_sync_info(); + goto _done_rate_size_check; + } +#endif + } else { + if (sample_rate_send == new_send_rate) { + // No change + goto _done_rate_size_check; + } + } + + if (stream == AUD_STREAM_PLAYBACK) { + play_rate = calc_play_sample_rate(new_recv_rate); + if (sample_rate_play == play_rate) { + if (sample_size_recv == new_recv_size) { + // No codec change. Only a change in usb sample rate + TRACE(3,"%s:1: Update recv sample rate from %u to %u", __FUNCTION__, sample_rate_recv, new_recv_rate); + sample_rate_recv = new_recv_rate; + update_playback_sync_info(); + goto _done_rate_size_check; + } + } else { +#ifndef __AUDIO_RESAMPLE__ + bool new_rate_44p1k; + bool old_rate_44p1k; + + new_rate_44p1k = !!(play_rate % AUD_SAMPRATE_8000); + old_rate_44p1k = !!(sample_rate_play % AUD_SAMPRATE_8000); + + if (new_rate_44p1k ^ old_rate_44p1k) { + cap_rate = calc_cap_sample_rate(new_send_rate, play_rate); + update_cap = true; + } +#endif + } + update_play = true; + } else { +#ifndef __AUDIO_RESAMPLE__ + if (playback_state == AUDIO_ITF_STATE_STOPPED) { + bool usb_rate_44p1k; + bool play_rate_44p1k; + + usb_rate_44p1k = !!(new_send_rate % AUD_SAMPRATE_8000); + play_rate_44p1k = !!(play_rate % AUD_SAMPRATE_8000); + + if (usb_rate_44p1k ^ play_rate_44p1k) { + play_rate = calc_play_sample_rate(usb_rate_44p1k ? AUD_SAMPRATE_44100 : AUD_SAMPRATE_48000); + update_play = true; + } + } +#endif + cap_rate = calc_cap_sample_rate(new_send_rate, play_rate); + if (sample_rate_cap == cap_rate) { + // No codec change. Only a change in usb sample rate + TRACE(3,"%s:1: Update send sample rate from %u to %u", __FUNCTION__, sample_rate_send, new_send_rate); + sample_rate_send = new_send_rate; + update_capture_sync_info(); + goto _done_rate_size_check; + } + update_cap = true; + } + +_done_rate_size_check:; +#endif + +#ifdef DSD_SUPPORT + bool new_dsd_state; + + new_dsd_state = usb_dsd_enabled; + if (stream == AUD_STREAM_PLAYBACK) { + if (codec_dsd_enabled != new_dsd_state) { + update_play = true; + } + } +#endif + + if (!update_play && !update_cap) { + return; + } + + // 1) To avoid L/R sample misalignment, streams must be stopped before changing sample rate + // 2) To avoid FIFO corruption, streams must be stopped before changing sample size + if (update_cap && codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_STARTED]) { + set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_CAP, true); + usb_audio_stop_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); + } + if (update_play && codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_STARTED]) { + set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_PLAY, true); + usb_audio_stop_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USER_ALL); + } + + if (update_play) { +#ifdef USB_AUDIO_DYN_CFG + if (sample_rate_recv != new_recv_rate) { + TRACE(3,"%s:2: Update recv sample rate from %u to %u", __FUNCTION__, sample_rate_recv, new_recv_rate); + sample_rate_recv = new_recv_rate; + } + if (sample_rate_play != play_rate) { + TRACE(3,"%s:2: Update play sample rate from %u to %u", __FUNCTION__, sample_rate_play, play_rate); + sample_rate_play = play_rate; + } + if (sample_size_recv != new_recv_size) { + TRACE(3,"%s:2: Update recv sample size from %u to %u", __FUNCTION__, sample_size_recv, new_recv_size); + sample_size_recv = new_recv_size; +#ifndef AUDIO_PLAYBACK_24BIT + uint8_t old_play_size; + + old_play_size = sample_size_play; + sample_size_play = (new_recv_size == 2) ? 2 : 4; + TRACE(3,"%s:2: Update play sample size from %u to %u", __FUNCTION__, old_play_size, sample_size_play); +#endif + } +#endif +#ifdef DSD_SUPPORT + if (codec_dsd_enabled != new_dsd_state) { + codec_dsd_enabled = new_dsd_state; +#ifdef CODEC_DSD + uint8_t old_play_size; + + old_play_size = sample_size_play; + if (codec_dsd_enabled) { + playback_size /= ((sample_size_play + 1) / 2); + dsd_saved_sample_size = sample_size_play; + sample_size_play = 2; + } else { + playback_size *= ((dsd_saved_sample_size + 1) / 2); + sample_size_play = dsd_saved_sample_size; + } + TRACE(4,"%s:2: CODEC_DSD=%u update play sample size from %u to %u", __FUNCTION__, codec_dsd_enabled, old_play_size, sample_size_play); +#endif + } +#endif + } + if (update_cap) { +#ifdef USB_AUDIO_DYN_CFG + if (sample_rate_send != new_send_rate) { + TRACE(3,"%s:2: Update send sample rate from %u to %u", __FUNCTION__, sample_rate_send, new_send_rate); + sample_rate_send = new_send_rate; + } + if (sample_rate_cap != cap_rate) { + TRACE(3,"%s:2: Update cap sample rate from %u to %u", __FUNCTION__, sample_rate_cap, cap_rate); + sample_rate_cap = cap_rate; + } +#endif + } + +#if defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY) + playback_size = calc_playback_size(sample_rate_play); + capture_size = calc_capture_size(sample_rate_cap); +#endif + +#ifdef SW_CAPTURE_RESAMPLE + // Check whether to start capture resample + if (update_cap && capture_state == AUDIO_ITF_STATE_STARTED) { + capture_stream_resample_config(); + } +#endif + +#ifdef STREAM_RATE_BITS_SETUP + if (update_play) { + update_playback_sync_info(); + + ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &cfg, true); + if (ret == 0) { + // Changes in AF_STREAM_CONFIG_T::bits must be in another cfg variable + stream_cfg = *cfg; +#ifdef CODEC_DSD + if (codec_dsd_enabled) { + stream_cfg.bits = AUD_BITS_24; + } else +#endif + { + stream_cfg.bits = sample_size_to_enum_playback(sample_size_play); + } + stream_cfg.sample_rate = sample_rate_play; +#if (defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY)) || defined(CODEC_DSD) + stream_cfg.data_size = playback_size; +#endif + af_stream_setup(AUD_STREAM_ID_0, AUD_STREAM_PLAYBACK, &stream_cfg); + } + +#ifdef AUDIO_ANC_FB_MC + ret = af_stream_get_cfg(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &cfg, true); + if (ret == 0) { + // Changes in AF_STREAM_CONFIG_T::bits must be in another cfg variable + stream_cfg = *cfg; + stream_cfg.bits = sample_size_to_enum_playback(sample_size_play); + + if(sample_rate_play==AUD_SAMPRATE_8000) + { + playback_samplerate_ratio=8*6; + } + else if(sample_rate_play==AUD_SAMPRATE_16000) + { + playback_samplerate_ratio=8*3; + } + else if((sample_rate_play==AUD_SAMPRATE_44100)||(sample_rate_play==AUD_SAMPRATE_48000)||(sample_rate_play==AUD_SAMPRATE_50781)) + { + playback_samplerate_ratio=8; + } + else if((sample_rate_play==AUD_SAMPRATE_88200)||(sample_rate_play==AUD_SAMPRATE_96000)) + { + playback_samplerate_ratio=4; + } + else if((sample_rate_play==AUD_SAMPRATE_176400)||(sample_rate_play==AUD_SAMPRATE_192000)) + { + playback_samplerate_ratio=2; + } + else if(sample_rate_play==AUD_SAMPRATE_384000) + { + playback_samplerate_ratio=1; + } + else + { + playback_samplerate_ratio=1; + ASSERT(false, "Music cancel can't support playback sample rate:%d",sample_rate_play); + } + + stream_cfg.data_ptr = playback_buf+playback_size; + stream_cfg.data_size = playback_size*playback_samplerate_ratio; + + stream_cfg.sample_rate = sample_rate_play; + af_stream_setup(AUD_STREAM_ID_2, AUD_STREAM_PLAYBACK, &stream_cfg); + anc_mc_run_setup((sample_rate_play*playback_samplerate_ratio)/8); + } +#endif + } + if (update_cap) { + update_capture_sync_info(); + + ret = af_stream_get_cfg(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &cfg, true); + if (ret == 0) { + stream_cfg = *cfg; + stream_cfg.bits = sample_size_to_enum_capture(sample_size_cap); +#if defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY) + stream_cfg.data_size = capture_size; +#endif + stream_cfg.sample_rate = sample_rate_cap; + af_stream_setup(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + } + } +#else // !STREAM_RATE_BITS_SETUP + // Close streams + if (update_cap && codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_OPENED]) { + usb_audio_close_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); + } + if (update_play && codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_OPENED]) { + usb_audio_close_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USER_ALL); + } + // Open streams + if (update_play && codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_OPENED]) { + usb_audio_open_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USER_ALL); + } + if (update_cap && codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_OPENED]) { + usb_audio_open_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); + } +#endif // !STREAM_RATE_BITS_SETUP + + if (update_play && codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_STARTED]) { + usb_audio_start_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USER_ALL); + set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_PLAY, false); + } + if (update_cap && codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_STARTED]) { + usb_audio_start_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); + set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_CAP, false); + } +} + +static void start_play(uint8_t seq) +{ + if (playback_state == AUDIO_ITF_STATE_STOPPED) { +#ifdef FREQ_RESP_EQ + freq_resp_eq_init(); +#endif + +#ifdef DELAY_STREAM_OPEN + usb_audio_open_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USB); +#endif + +#ifdef NOISE_GATING + last_high_signal_time = hal_sys_timer_get(); +#ifdef NOISE_REDUCTION + last_nr_restore_time = hal_sys_timer_get(); +#endif +#endif + + usb_audio_start_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USB); + + playback_state = AUDIO_ITF_STATE_STARTED; + } + + codec_play_seq = seq; + playback_paused = 0; + + usb_audio_update_freq(); +} + +static void usb_audio_cmd_start_play(uint8_t seq) +{ +#if defined(USB_AUDIO_DYN_CFG) && defined(USB_AUDIO_UAC2) + usb_audio_update_codec_stream(AUD_STREAM_PLAYBACK); +#endif + + start_play(seq); +} + +static void usb_audio_cmd_stop_play(void) +{ + if (playback_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USB); + +#ifdef PA_ON_OFF_KEY + if (pa_on_off_muted) { + pa_on_off_muted = false; + if (mute_user_map == 0) { + usb_audio_codec_unmute(CODEC_MUTE_USER_ALL); + } + } +#endif +#ifdef NOISE_GATING + // Restore the noise gating status + if (mute_user_map & (1 << CODEC_MUTE_USER_NOISE_GATING)) { + usb_audio_codec_unmute(CODEC_MUTE_USER_NOISE_GATING); + } +#ifdef NOISE_REDUCTION + restore_noise_reduction_status(); +#endif +#endif + +#ifdef DELAY_STREAM_OPEN + usb_audio_close_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USB); +#endif + + playback_paused = 0; + playback_state = AUDIO_ITF_STATE_STOPPED; +#ifdef DSD_SUPPORT + if (codec_dsd_enabled) { + usb_audio_update_codec_stream(AUD_STREAM_PLAYBACK); + } +#endif + } + + usb_audio_update_freq(); +} + +static void start_capture(uint8_t seq) +{ + if (capture_state == AUDIO_ITF_STATE_STOPPED) { +#ifdef SW_CAPTURE_RESAMPLE + // Check whether to start capture resample + capture_stream_resample_config(); +#endif + +#ifdef DELAY_STREAM_OPEN + usb_audio_open_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USB); +#endif + usb_audio_start_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USB); + + capture_state = AUDIO_ITF_STATE_STARTED; + } + + codec_cap_seq = seq; + + usb_audio_update_freq(); +} + +static void usb_audio_cmd_start_capture(uint8_t seq) +{ + start_capture(seq); +} + +static void usb_audio_cmd_stop_capture(void) +{ + if (capture_state == AUDIO_ITF_STATE_STARTED) { + usb_audio_stop_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USB); + +#ifdef DELAY_STREAM_OPEN + usb_audio_close_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USB); +#endif + +#ifdef SW_CAPTURE_RESAMPLE + if (resample_cap_enabled) { + audio_resample_ex_close(resample_id); + resample_cap_enabled = false; + } +#endif + + capture_state = AUDIO_ITF_STATE_STOPPED; + } + + usb_audio_update_freq(); +} + +static void usb_audio_cmd_set_volume(void) +{ +#ifndef USB_AUDIO_MULTIFUNC + playback_vol = new_playback_vol; +#endif + + usb_audio_set_codec_volume(AUD_STREAM_PLAYBACK, playback_vol); + +#ifdef UNMUTE_WHEN_SET_VOL + // Unmute if muted before + if (mute_user_map & (1 << CODEC_MUTE_USER_CMD)) { + usb_audio_codec_unmute(CODEC_MUTE_USER_CMD); + } +#endif +} + +static void usb_audio_cmd_set_cap_volume(void) +{ + capture_vol = new_capture_vol; + + usb_audio_set_codec_volume(AUD_STREAM_CAPTURE, capture_vol); +} + +static void usb_audio_cmd_mute_ctrl(void) +{ + uint8_t mute; + +#ifdef USB_AUDIO_MULTIFUNC + mute = new_mute_state && new_mute2_state; +#else + mute = new_mute_state; +#endif + + if (mute) { + usb_audio_codec_mute(CODEC_MUTE_USER_CMD); + } else { + usb_audio_codec_unmute(CODEC_MUTE_USER_CMD); + } +} + +static void usb_audio_cmd_cap_mute_ctrl(void) +{ + uint8_t mute; + + mute = new_cap_mute_state; + + af_stream_mute(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, mute); +} + +static void usb_audio_cmd_usb_state(enum AUDIO_CMD_T cmd) +{ + usb_audio_cmd_stop_capture(); + usb_audio_cmd_stop_play(); + + if (cmd == AUDIO_CMD_USB_RESET || cmd == AUDIO_CMD_USB_WAKEUP) { + usb_audio_acquire_freq(); + if (cmd == AUDIO_CMD_USB_RESET) { + usb_audio_term_streams(AUDIO_STREAM_REQ_USB); + } + usb_audio_reset_codec_stream_state(cmd == AUDIO_CMD_USB_RESET); + usb_audio_init_streams(AUDIO_STREAM_REQ_USB); + } else if (cmd == AUDIO_CMD_USB_DISCONNECT || cmd == AUDIO_CMD_USB_SLEEP) { + usb_audio_term_streams(AUDIO_STREAM_REQ_USB); + usb_audio_reset_codec_stream_state(cmd == AUDIO_CMD_USB_DISCONNECT); + if (cmd == AUDIO_CMD_USB_DISCONNECT || usb_configured) { + usb_audio_release_freq(); + } + } else if (cmd == AUDIO_CMD_USB_CONFIG) { + usb_configured = 1; + usb_audio_reset_codec_stream_state(true); + } +} + +static void usb_audio_cmd_recv_pause(uint8_t seq) +{ + TRACE(3,"%s: Recv pause: seq=%u usb_recv_seq=%u", __FUNCTION__, seq, usb_recv_seq); + + if (seq == usb_recv_seq) { + usb_audio_cmd_stop_play(); + playback_paused = 1; + } +} + +static void usb_audio_cmd_recv_continue(uint8_t seq) +{ + TRACE(3,"%s: Recv continue: seq=%u usb_recv_seq=%u", __FUNCTION__, seq, usb_recv_seq); + + if (seq == usb_recv_seq && playback_paused) { + start_play(seq); + //playback_paused = 0; + } +} + +#ifdef USB_AUDIO_DYN_CFG +static void usb_audio_cmd_set_playback_rate(uint8_t seq, uint8_t index) +{ +#ifndef USB_AUDIO_UAC2 + if (seq != usb_recv_seq) { + TRACE(3,"%s: Bad seq: seq=%u usb_recv_seq=%u", __FUNCTION__, seq, usb_recv_seq); + return; + } +#endif + + usb_audio_update_codec_stream(AUD_STREAM_PLAYBACK); + +#ifndef USB_AUDIO_UAC2 + start_play(seq); +#endif +} + +static void usb_audio_cmd_set_capture_rate(uint8_t seq, uint8_t index) +{ +#ifndef USB_AUDIO_UAC2 + if (seq != usb_send_seq) { + TRACE(3,"%s: Bad seq: seq=%u usb_send_seq=%u", __FUNCTION__, seq, usb_send_seq); + return; + } +#endif + + usb_audio_update_codec_stream(AUD_STREAM_CAPTURE); + +#ifndef USB_AUDIO_UAC2 + start_capture(seq); +#endif +} +#endif + +static void usb_audio_cmd_reset_codec(void) +{ + TRACE(1,"%s: RESET CODEC", __FUNCTION__); + + // Regarding PLL reconfiguration, stream stop and start are enough. + // Complete DAC/ADC reset (including analog parts) can be achieved by + // stream close and open, which need to invoke explicitly here if + // DELAY_STREAM_OPEN is not defined. + + if (codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_STARTED]) { + set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_CAP, true); + usb_audio_stop_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); + } + + if (codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_STARTED]) { + set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_PLAY, true); + usb_audio_stop_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USER_ALL); + } + + rate_tune_ratio[AUD_STREAM_PLAYBACK] = 0; + rate_tune_ratio[AUD_STREAM_CAPTURE] = 0; +#ifdef __AUDIO_RESAMPLE__ +#ifdef PLL_TUNE_SAMPLE_RATE + af_codec_tune_resample_rate(AUD_STREAM_PLAYBACK, rate_tune_ratio[AUD_STREAM_PLAYBACK]); + af_codec_tune_resample_rate(AUD_STREAM_CAPTURE, rate_tune_ratio[AUD_STREAM_CAPTURE]); +#elif defined(PLL_TUNE_XTAL) + af_codec_tune_xtal(rate_tune_ratio[AUD_STREAM_PLAYBACK]); +#endif +#else + af_codec_tune_pll(rate_tune_ratio[AUD_STREAM_PLAYBACK]); +#endif + + if (codec_stream_map[AUD_STREAM_PLAYBACK][AUDIO_STREAM_STARTED]) { + usb_audio_start_codec_stream(AUD_STREAM_PLAYBACK, AUDIO_STREAM_REQ_USER_ALL); + set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_PLAY, false); + } + + if (codec_stream_map[AUD_STREAM_CAPTURE][AUDIO_STREAM_STARTED]) { + usb_audio_start_codec_stream(AUD_STREAM_CAPTURE, AUDIO_STREAM_REQ_USER_ALL); + set_codec_config_status(CODEC_CONFIG_LOCK_RESTART_CAP, false); + } +} + +#ifdef NOISE_GATING +static void usb_audio_cmd_noise_gating(void) +{ + uint32_t lock; + enum NOISE_GATING_CMD_T cmd; + + lock = int_lock(); + cmd = noise_gating_cmd; + noise_gating_cmd = NOISE_GATING_CMD_NULL; + int_unlock(lock); + + TRACE(3,"%s: cmd=%d map=0x%02X", __FUNCTION__, cmd, mute_user_map); + + if (cmd == NOISE_GATING_CMD_MUTE) { + if ((mute_user_map & (1 << CODEC_MUTE_USER_NOISE_GATING)) == 0) { + usb_audio_codec_mute(CODEC_MUTE_USER_NOISE_GATING); + } + } else if (cmd == NOISE_GATING_CMD_UNMUTE) { + if (mute_user_map & (1 << CODEC_MUTE_USER_NOISE_GATING)) { + usb_audio_codec_unmute(CODEC_MUTE_USER_NOISE_GATING); + } + } +} + +#ifdef NOISE_REDUCTION +static void restore_noise_reduction_status(void) +{ + if (nr_active) { + nr_active = false; + af_codec_set_noise_reduction(false); + } + prev_samp_positive[0] = prev_samp_positive[1] = false; + memset(prev_zero_diff, 0, sizeof(prev_zero_diff)); + memset(cur_zero_diff, 0, sizeof(cur_zero_diff)); + nr_cont_cnt = 0; +} + +static void usb_audio_cmd_noise_reduction(void) +{ + uint32_t lock; + enum NOISE_REDUCTION_CMD_T cmd; + + lock = int_lock(); + cmd = noise_reduction_cmd; + noise_reduction_cmd = NOISE_REDUCTION_CMD_NULL; + int_unlock(lock); + + TRACE(2,"%s: cmd=%d", __FUNCTION__, cmd); + + if (cmd == NOISE_REDUCTION_CMD_FIRE) { + nr_active = true; + af_codec_set_noise_reduction(true); + } else if (cmd == NOISE_REDUCTION_CMD_RESTORE) { + nr_active = false; + af_codec_set_noise_reduction(false); + } +} +#endif +#endif + +static void usb_audio_cmd_tune_rate(enum AUD_STREAM_T stream) +{ +#ifdef __AUDIO_RESAMPLE__ +#ifdef PLL_TUNE_SAMPLE_RATE + bool update_play, update_cap; + + update_play = true; + update_cap = false; + +#ifdef UAUD_SYNC_STREAM_TARGET + if (stream == AUD_STREAM_PLAYBACK) { + update_play = true; + update_cap = false; + } else { + update_play = false; + update_cap = true; + } +#else + update_play = true; + update_cap = true; +#endif + +#ifdef SW_RESAMPLE + if (update_play) { + audio_resample_ex_set_ratio_step(play_resample_id, nominal_ratio_step * rate_tune_ratio[AUD_STREAM_PLAYBACK]); + } + if (update_cap) { + audio_resample_ex_set_ratio_step(cap_resample_id, nominal_ratio_step * rate_tune_ratio[AUD_STREAM_CAPTURE]); + } +#else + if (update_play) { + af_codec_tune_resample_rate(AUD_STREAM_PLAYBACK, rate_tune_ratio[AUD_STREAM_PLAYBACK]); + } + if (update_cap) { + af_codec_tune_resample_rate(AUD_STREAM_CAPTURE, rate_tune_ratio[AUD_STREAM_CAPTURE]); + } +#endif +#elif defined(PLL_TUNE_XTAL) + af_codec_tune_xtal(rate_tune_ratio[AUD_STREAM_PLAYBACK]); +#endif +#else // !__AUDIO_RESAMPLE__ + af_codec_tune_pll(rate_tune_ratio[AUD_STREAM_PLAYBACK]); +#endif // !__AUDIO_RESAMPLE__ +} + +#ifdef DSD_SUPPORT +static void usb_audio_cmd_set_dsd_cfg(void) +{ + if (codec_dsd_enabled != usb_dsd_enabled) { + TRACE(3,"%s: %d => %d", __FUNCTION__, codec_dsd_enabled, usb_dsd_enabled); + usb_audio_update_codec_stream(AUD_STREAM_PLAYBACK); + } +} +#endif + +#ifdef PERF_TEST_POWER_KEY +static void test_cmd_perf_test_power(void) +{ + perft_power_type++; + if (perft_power_type >= HAL_CODEC_PERF_TEST_QTY) { + perft_power_type = 0; + } + + TRACE(2,"%s: %d", __FUNCTION__, perft_power_type); + + af_codec_set_perf_test_power(perft_power_type); +} +#endif + +#ifdef PA_ON_OFF_KEY +static void test_cmd_pa_on_off(void) +{ + pa_on_off_muted = !pa_on_off_muted; + + TRACE(2,"%s: %d", __FUNCTION__, pa_on_off_muted); + + if (pa_on_off_muted) { + usb_audio_codec_mute(CODEC_MUTE_USER_ALL); + } else { + usb_audio_codec_unmute(CODEC_MUTE_USER_ALL); +#ifdef PERF_TEST_POWER_KEY + af_codec_set_perf_test_power(perft_power_type); +#endif + } +} +#endif + +static void usb_audio_cmd_handler(void *param) +{ + uint32_t data; + enum AUDIO_CMD_T cmd; + uint8_t seq; + uint8_t POSSIBLY_UNUSED arg; + + hal_cpu_wake_unlock(USB_AUDIO_CPU_WAKE_USER); + + while (safe_queue_get(&cmd_queue, &data) == 0) { + cmd = EXTRACT_CMD(data); + seq = EXTRACT_SEQ(data); + arg = EXTRACT_ARG(data); + TRACE(4,"%s: cmd=%d seq=%d arg=%d", __FUNCTION__, cmd, seq, arg); + + switch (cmd) { + case AUDIO_CMD_START_PLAY: + usb_audio_cmd_start_play(seq); + break; + + case AUDIO_CMD_STOP_PLAY: + usb_audio_cmd_stop_play(); + break; + + case AUDIO_CMD_START_CAPTURE: + usb_audio_cmd_start_capture(seq); + break; + + case AUDIO_CMD_STOP_CAPTURE: + usb_audio_cmd_stop_capture(); + break; + + case AUDIO_CMD_SET_VOLUME: + usb_audio_cmd_set_volume(); + break; + + case AUDIO_CMD_SET_CAP_VOLUME: + usb_audio_cmd_set_cap_volume(); + break; + + case AUDIO_CMD_MUTE_CTRL: + usb_audio_cmd_mute_ctrl(); + break; + + case AUDIO_CMD_CAP_MUTE_CTRL: + usb_audio_cmd_cap_mute_ctrl(); + break; + + case AUDIO_CMD_USB_RESET: + case AUDIO_CMD_USB_DISCONNECT: + case AUDIO_CMD_USB_CONFIG: + case AUDIO_CMD_USB_SLEEP: + case AUDIO_CMD_USB_WAKEUP: + usb_audio_cmd_usb_state(cmd); + break; + + case AUDIO_CMD_RECV_PAUSE: + usb_audio_cmd_recv_pause(seq); + break; + case AUDIO_CMD_RECV_CONTINUE: + usb_audio_cmd_recv_continue(seq); + break; + +#ifdef USB_AUDIO_DYN_CFG + case AUDIO_CMD_SET_RECV_RATE: + usb_audio_cmd_set_playback_rate(seq, arg); + break; + case AUDIO_CMD_SET_SEND_RATE: + usb_audio_cmd_set_capture_rate(seq, arg); + break; +#endif + + case AUDIO_CMD_RESET_CODEC: + usb_audio_cmd_reset_codec(); + break; + +#ifdef NOISE_GATING + case AUDIO_CMD_NOISE_GATING: + usb_audio_cmd_noise_gating(); + break; + +#ifdef NOISE_REDUCTION + case AUDIO_CMD_NOISE_REDUCTION: + usb_audio_cmd_noise_reduction(); + break; +#endif +#endif + + case AUDIO_CMD_TUNE_RATE: + usb_audio_cmd_tune_rate((enum AUD_STREAM_T)arg); + break; + +#ifdef DSD_SUPPORT + case AUDIO_CMD_SET_DSD_CFG: + usb_audio_cmd_set_dsd_cfg(); + break; +#endif + +#ifdef PERF_TEST_POWER_KEY + case TEST_CMD_PERF_TEST_POWER: + test_cmd_perf_test_power(); + break; +#endif + +#ifdef PA_ON_OFF_KEY + case TEST_CMD_PA_ON_OFF: + test_cmd_pa_on_off(); + break; +#endif + + default: + ASSERT(false, "%s: Invalid cmd %d", __FUNCTION__, cmd); + break; + } + } +} + +void usb_audio_app_init(const struct USB_AUDIO_BUF_CFG *cfg) +{ +#ifdef USB_AUDIO_DYN_CFG + ASSERT(cfg->play_size / MAX_FRAME_SIZE_PLAYBACK < cfg->recv_size / MAX_FRAME_SIZE_RECV, + "%s: play frames %u should < recv frames %u", __FUNCTION__, + cfg->play_size / MAX_FRAME_SIZE_PLAYBACK, cfg->recv_size / MAX_FRAME_SIZE_RECV); + ASSERT(cfg->cap_size / MAX_FRAME_SIZE_CAPTURE < cfg->send_size / MAX_FRAME_SIZE_SEND, + "%s: cap frames %u should < send frames %u", __FUNCTION__, + cfg->cap_size / MAX_FRAME_SIZE_CAPTURE, cfg->send_size / MAX_FRAME_SIZE_SEND); +#else + ASSERT(cfg->play_size / FRAME_SIZE_PLAYBACK < cfg->recv_size / FRAME_SIZE_RECV, + "%s: play frames %u should < recv frames %u", __FUNCTION__, + cfg->play_size / FRAME_SIZE_PLAYBACK, cfg->recv_size / FRAME_SIZE_RECV); + ASSERT(cfg->cap_size / FRAME_SIZE_CAPTURE < cfg->send_size / FRAME_SIZE_SEND, + "%s: cap frames %u should < send frames %u", __FUNCTION__, + cfg->cap_size / FRAME_SIZE_CAPTURE, cfg->send_size / FRAME_SIZE_SEND); +#endif + +#ifdef SW_CAPTURE_RESAMPLE + enum AUD_CHANNEL_NUM_T chans; + enum AUD_BITS_T bits; + uint8_t phase_coef_num; + uint32_t resamp_calc_size; + + chans = get_capture_resample_chan_num(); + bits = sample_size_to_enum_capture(sample_size_cap); + // Max phase coef num + phase_coef_num = 100; + + resamp_calc_size = audio_resample_ex_get_buffer_size(chans, bits, phase_coef_num); + ASSERT(cfg->resample_size > resamp_calc_size, + "%s: Resample size too small %u (should > %u)", __FUNCTION__, + cfg->resample_size, resamp_calc_size); + + resample_history_buf = (uint8_t *)ALIGN((uint32_t)cfg->resample_buf, 4); + resample_history_size = resamp_calc_size; + resample_input_buf = (uint8_t *)resample_history_buf + resample_history_size; + ASSERT(cfg->resample_buf + cfg->resample_size > resample_input_buf, + "%s: Resample size too small: %u", __FUNCTION__, cfg->resample_size); + resample_input_size = cfg->resample_buf + cfg->resample_size - resample_input_buf; +#endif + + playback_buf = cfg->play_buf; + capture_buf = cfg->cap_buf; + usb_recv_buf = cfg->recv_buf; + usb_send_buf = cfg->send_buf; + playback_eq_buf = cfg->eq_buf; + playback_eq_size = cfg->eq_size; + +#if defined(USB_AUDIO_DYN_CFG) && defined(KEEP_SAME_LATENCY) + playback_max_size = cfg->play_size; + capture_max_size = cfg->cap_size; + usb_recv_max_size = cfg->recv_size; + usb_send_max_size = cfg->send_size; +#else + playback_size = cfg->play_size; + capture_size = cfg->cap_size; + usb_recv_size = cfg->recv_size; + usb_send_size = cfg->send_size; +#endif + + playback_pos = 0; + usb_recv_rpos = 0; + usb_recv_wpos = cfg->recv_size / 2; + capture_pos = 0; + usb_send_rpos = cfg->send_size / 2; + usb_send_wpos = 0; + +#ifdef USB_AUDIO_MULTIFUNC + usb_recv2_buf = cfg->recv2_buf; + usb_recv2_size = cfg->recv2_size; + usb_recv2_rpos = 0; + usb_recv2_wpos = cfg->recv2_size / 2; +#endif + + playback_info.id = 0; + playback_info.sync_thresh = DIFF_SYNC_THRESH_PLAYBACK; + playback_info.diff_avg_cnt = DIFF_AVG_CNT; +#ifdef TARGET_TO_MAX_DIFF + playback_info.diff_target_enabled = true; + playback_info.max_target_ratio = MAX_TARGET_RATIO; + playback_info.time_to_ms = NULL; +#endif + capture_info.id = 1; + capture_info.sync_thresh = DIFF_SYNC_THRESH_CAPTURE; + capture_info.diff_avg_cnt = DIFF_AVG_CNT; +#ifdef TARGET_TO_MAX_DIFF + capture_info.diff_target_enabled = true; + capture_info.max_target_ratio = MAX_TARGET_RATIO; + capture_info.time_to_ms = NULL; +#endif + + safe_queue_init(&cmd_queue, cmd_list, CMD_LIST_SIZE); + +#ifdef USB_AUDIO_PWRKEY_TEST + hal_cmu_simu_set_val(0); +#endif +} + +void usb_audio_app_term(void) +{ + playback_buf = NULL; + playback_size = 0; + capture_buf = NULL; + capture_size = 0; + usb_recv_buf = NULL; + usb_recv_size = 0; + usb_send_buf = NULL; + usb_send_size = 0; + + playback_pos = 0; + usb_recv_rpos = 0; + usb_recv_wpos = 0; + + capture_pos = 0; + usb_send_rpos = 0; + usb_send_wpos = 0; + +#ifdef USB_AUDIO_MULTIFUNC + usb_recv2_buf = NULL; + usb_recv2_size = 0; + usb_recv2_rpos = 0; + usb_recv2_wpos = 0; +#endif +} + +void usb_audio_app(bool on) +{ + static const struct USB_AUDIO_CFG_T usb_audio_cfg = { + .recv_sample_rate = SAMPLE_RATE_RECV, + .send_sample_rate = SAMPLE_RATE_SEND, + .itf_callback = usb_audio_itf_callback, + .mute_callback = usb_audio_mute_callback, + .set_volume = usb_audio_set_volume, + .get_volume = usb_audio_get_volume, + .state_callback = usb_audio_state_control, + .xfer_callback = usb_audio_xfer_callback, +#if defined(ANDROID_ACCESSORY_SPEC) || defined(CFG_MIC_KEY) + // Applications are responsible for clearing HID events + .hid_send_callback = hid_data_send_handler, +#else + // HID events will be cleared automatically once they are sent + .hid_send_callback = NULL, +#endif +#ifdef _VENDOR_MSG_SUPPT_ + .vendor_msg_callback = usb_vendor_callback, + .vendor_rx_buf = vendor_msg_rx_buf, + .vendor_rx_size = VENDOR_RX_BUF_SZ, +#endif + }; + static bool isRun = false; + int ret; + + if (isRun==on) + return; + else + isRun=on; + + TRACE(2,"%s: on=%d", __FUNCTION__, on); + + if (on) { + usb_audio_acquire_freq(); + + usb_audio_reset_usb_stream_state(true); + usb_audio_reset_codec_stream_state(true); + +#ifdef USB_AUDIO_DYN_CFG + sample_rate_recv = new_sample_rate_recv = usb_audio_cfg.recv_sample_rate; + sample_rate_send = new_sample_rate_send = usb_audio_cfg.send_sample_rate; + // Init codec sample rates after initializing usb sample rates + sample_rate_play = calc_play_sample_rate(sample_rate_recv); + sample_rate_cap = calc_cap_sample_rate(sample_rate_send, sample_rate_play); + // TODO: Check whether 16-bit sample is enabled + sample_size_recv = new_sample_size_recv = 2; +#ifndef AUDIO_PLAYBACK_24BIT + sample_size_play = 2; +#endif + +#ifdef KEEP_SAME_LATENCY + usb_recv_size = calc_usb_recv_size(sample_rate_recv, sample_size_recv); + usb_send_size = calc_usb_send_size(sample_rate_send); + playback_size = calc_playback_size(sample_rate_play); + capture_size = calc_capture_size(sample_rate_cap); +#endif +#endif + + TRACE(3,"CODEC playback sample: rate=%u size=%u chan=%u", sample_rate_play, sample_size_play, CHAN_NUM_PLAYBACK); + TRACE(3,"CODEC capture sample: rate=%u size=%u chan=%u", sample_rate_cap, sample_size_cap, CHAN_NUM_CAPTURE); + TRACE(2,"USB recv sample: rate=%u size=%u", sample_rate_recv, sample_size_recv); + TRACE(2,"USB send sample: rate=%u size=%u", sample_rate_send, sample_size_send); + + usb_audio_init_streams(AUDIO_STREAM_REQ_USB); + + pmu_usb_config(PMU_USB_CONFIG_TYPE_DEVICE); + ret = usb_audio_open(&usb_audio_cfg); + ASSERT(ret == 0, "usb_audio_open failed: %d", ret); + } else { + usb_audio_close(); + pmu_usb_config(PMU_USB_CONFIG_TYPE_NONE); + + usb_audio_term_streams(AUDIO_STREAM_REQ_USB); + + usb_audio_reset_usb_stream_state(true); + usb_audio_reset_codec_stream_state(true); + + usb_audio_release_freq(); + } +} + +static void app_key_trace(uint32_t line, enum HAL_KEY_CODE_T code, + enum HAL_KEY_EVENT_T event, enum USB_AUDIO_HID_EVENT_T uevt, int state) +{ +#ifdef KEY_TRACE + TRACE(5,"APPKEY/%u: code=%d event=%d uevt=%s state=%d", + line, code, event, usb_audio_get_hid_event_name(uevt), state); +#endif +} + +int usb_audio_app_key(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event) +{ + int i; + enum USB_AUDIO_HID_EVENT_T uevt; + int state; + + if (event == HAL_KEY_EVENT_CLICK && playback_state == AUDIO_ITF_STATE_STARTED) { +#ifdef PERF_TEST_POWER_KEY + if (code == PERF_TEST_POWER_KEY) { + enqueue_unique_cmd(TEST_CMD_PERF_TEST_POWER); + } +#endif +#ifdef PA_ON_OFF_KEY + if (code == PA_ON_OFF_KEY) { + enqueue_unique_cmd(TEST_CMD_PA_ON_OFF); + } +#endif + } + +#ifdef USB_AUDIO_PWRKEY_TEST + if (code == HAL_KEY_CODE_PWR) { + uevt = hal_cmu_simu_get_val(); + if (uevt == 0) { + uevt = USB_AUDIO_HID_VOL_UP; + } +#if defined(ANDROID_ACCESSORY_SPEC) || defined(CFG_MIC_KEY) + if (event == HAL_KEY_EVENT_DOWN || event == HAL_KEY_EVENT_UP) { + state = (event != HAL_KEY_EVENT_UP); + app_key_trace(__LINE__, code, event, uevt, state); + usb_audio_hid_set_event(uevt, state); + } + // The key event has been processed + return 0; +#else + if (event == HAL_KEY_EVENT_CLICK) { + state = 1; + app_key_trace(__LINE__, code, event, uevt, state); + usb_audio_hid_set_event(uevt, state); + return 0; + } + // Let other applications check the key event + return 1; +#endif + } +#endif + + if (code != HAL_KEY_CODE_NONE) { + for (i = 0; i < ARRAY_SIZE(key_map); i++) { + if (key_map[i].key_code == code && (key_map[i].key_event_bitset & (1 << event))) { + break; + } + } + if (i < ARRAY_SIZE(key_map)) { + uevt = key_map[i].hid_event; + if (uevt != 0) { +#if defined(ANDROID_ACCESSORY_SPEC) || defined(CFG_MIC_KEY) + state = (event != HAL_KEY_EVENT_UP); +#else + state = 1; +#endif + app_key_trace(__LINE__, code, event, uevt, state); + usb_audio_hid_set_event(uevt, state); + // The key event has been processed + return 0; + } + } + } + + // Let other applications check the key event + return 1; +} + +#ifdef ANC_APP +extern bool anc_usb_app_get_status(); +static uint8_t anc_status = 0; +static uint8_t anc_status_record = 0xff; +#endif + +void usb_audio_eq_loop(void) +{ +#ifdef ANC_APP + anc_status = anc_usb_app_get_status(); + if(anc_status_record != anc_status&&eq_opened == 1) + { + anc_status_record = anc_status; + TRACE(2,"[%s]anc_status = %d", __func__, anc_status); +#ifdef __SW_IIR_EQ_PROCESS__ + usb_audio_set_eq(AUDIO_EQ_TYPE_SW_IIR,usb_audio_get_eq_index(AUDIO_EQ_TYPE_SW_IIR,anc_status)); +#endif + +#ifdef __HW_FIR_EQ_PROCESS__ + usb_audio_set_eq(AUDIO_EQ_TYPE_HW_FIR,usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_FIR,anc_status)); +#endif + +#ifdef __HW_DAC_IIR_EQ_PROCESS__ + usb_audio_set_eq(AUDIO_EQ_TYPE_HW_DAC_IIR,usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_DAC_IIR,anc_status)); +#endif + +#ifdef __HW_IIR_EQ_PROCESS__ + usb_audio_set_eq(AUDIO_EQ_TYPE_HW_IIR,usb_audio_get_eq_index(AUDIO_EQ_TYPE_HW_IIR,anc_status)); +#endif + } +#endif +} + +void usb_audio_app_loop(void) +{ + usb_audio_cmd_handler(NULL); + + usb_audio_eq_loop(); + +#ifndef RTOS + extern void af_thread(void const *argument); + af_thread(NULL); +#endif +} + +uint32_t usb_audio_get_capture_sample_rate(void) +{ + return sample_rate_cap; +} + diff --git a/tests/anc_usb/usb_audio_app.h b/tests/anc_usb/usb_audio_app.h new file mode 100644 index 0000000..9673148 --- /dev/null +++ b/tests/anc_usb/usb_audio_app.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __USB_AUDIO_APP_H__ +#define __USB_AUDIO_APP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" +#include "hal_key.h" +#include "audio_process.h" + +struct USB_AUDIO_BUF_CFG { + uint8_t *play_buf; + uint32_t play_size; + uint8_t *cap_buf; + uint32_t cap_size; + uint8_t *recv_buf; + uint32_t recv_size; + uint8_t *send_buf; + uint32_t send_size; + uint8_t *eq_buf; + uint32_t eq_size; + uint8_t *resample_buf; + uint32_t resample_size; +#ifdef USB_AUDIO_MULTIFUNC + uint8_t *recv2_buf; + uint32_t recv2_size; +#endif +}; + +typedef void (*USB_AUDIO_ENQUEUE_CMD_CALLBACK)(uint32_t data); + +void usb_audio_app(bool on); +void usb_audio_keep_streams_running(bool enable); +void usb_audio_app_init(const struct USB_AUDIO_BUF_CFG *cfg); + +void usb_audio_app_term(void); +int usb_audio_app_key(enum HAL_KEY_CODE_T code, enum HAL_KEY_EVENT_T event); +void usb_audio_app_loop(void); +uint32_t usb_audio_get_capture_sample_rate(void); + +uint32_t usb_audio_set_eq(AUDIO_EQ_TYPE_T audio_eq_type,uint8_t index); +uint8_t usb_audio_get_eq_index(AUDIO_EQ_TYPE_T audio_eq_type,uint8_t anc_status); + +void usb_audio_set_enqueue_cmd_callback(USB_AUDIO_ENQUEUE_CMD_CALLBACK cb); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tests/anc_usb/usb_audio_frm_defs.h b/tests/anc_usb/usb_audio_frm_defs.h new file mode 100644 index 0000000..8ebf602 --- /dev/null +++ b/tests/anc_usb/usb_audio_frm_defs.h @@ -0,0 +1,232 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __USB_AUDIO_FRM_DEFS_H__ +#define __USB_AUDIO_FRM_DEFS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +// Recv/send sample rates +#if 0 +#elif defined(USB_AUDIO_384K) +#define SAMPLE_RATE_RECV 384000 +#define SAMPLE_RATE_SEND 48000 +#elif defined(USB_AUDIO_352_8K) +#define SAMPLE_RATE_RECV 352800 +#define SAMPLE_RATE_SEND 44100 +#elif defined(USB_AUDIO_192K) +#define SAMPLE_RATE_RECV 192000 +#define SAMPLE_RATE_SEND 48000 +#elif defined(USB_AUDIO_176_4K) +#define SAMPLE_RATE_RECV 176400 +#define SAMPLE_RATE_SEND 44100 +#elif defined(USB_AUDIO_96K) +#define SAMPLE_RATE_RECV 96000 +#define SAMPLE_RATE_SEND 48000 +#elif defined(USB_AUDIO_48K) +#define SAMPLE_RATE_RECV 48000 +#define SAMPLE_RATE_SEND 48000 +#elif defined(USB_AUDIO_44_1K) +#define SAMPLE_RATE_RECV 44100 +#define SAMPLE_RATE_SEND 44100 +#elif defined(USB_AUDIO_16K) +#define SAMPLE_RATE_RECV 16000 +#define SAMPLE_RATE_SEND 16000 +#else // 48K by default +#define SAMPLE_RATE_RECV 48000 +#define SAMPLE_RATE_SEND 48000 +#endif + +// Playback sample rate +#if defined(CHIP_BEST1000) && defined(ANC_APP) +#if (SAMPLE_RATE_RECV % 8000) +#define SAMPLE_RATE_PLAYBACK 88200 +#else +#define SAMPLE_RATE_PLAYBACK 96000 +#endif +#elif defined(__AUDIO_RESAMPLE__) && defined(SW_PLAYBACK_RESAMPLE) +#define SAMPLE_RATE_PLAYBACK 50781 +#else +#define SAMPLE_RATE_PLAYBACK SAMPLE_RATE_RECV +#endif + +// Capture sample rate +#if defined(CHIP_BEST1000) && defined(ANC_APP) +#ifdef AUD_PLL_DOUBLE +#if defined(_DUAL_AUX_MIC_) || defined(CAPTURE_ANC_DATA) +#define SAMPLE_RATE_CAPTURE (SAMPLE_RATE_PLAYBACK * 8) +#else +#define SAMPLE_RATE_CAPTURE (SAMPLE_RATE_PLAYBACK * 2) +#endif +#else // !AUD_PLL_DOUBLE +#if defined(_DUAL_AUX_MIC_) || defined(CAPTURE_ANC_DATA) +#define SAMPLE_RATE_CAPTURE (SAMPLE_RATE_PLAYBACK * 4) +#else +#define SAMPLE_RATE_CAPTURE SAMPLE_RATE_PLAYBACK +#endif +#endif // !AUD_PLL_DOUBLE +#else // !(CHIP_BEST1000 && ANC_APP) +#if defined(CHIP_BEST1000) && defined(_DUAL_AUX_MIC_) +#define SAMPLE_RATE_CAPTURE (SAMPLE_RATE_SEND * 4) +#elif defined(__AUDIO_RESAMPLE__) && defined(SW_CAPTURE_RESAMPLE) +#define SAMPLE_RATE_CAPTURE 50781 +#else +#define SAMPLE_RATE_CAPTURE SAMPLE_RATE_SEND +#endif +#endif // !(CHIP_BEST1000 && ANC_APP) + +#ifdef USB_AUDIO_32BIT +#define SAMPLE_SIZE_PLAYBACK 4 +#define SAMPLE_SIZE_RECV 4 +#elif defined(USB_AUDIO_24BIT) +#define SAMPLE_SIZE_PLAYBACK 4 +#define SAMPLE_SIZE_RECV 3 +#else +#ifdef AUDIO_PLAYBACK_24BIT +#define SAMPLE_SIZE_PLAYBACK 4 +#else +#define SAMPLE_SIZE_PLAYBACK 2 +#endif +#define SAMPLE_SIZE_RECV 2 +#endif + +#ifdef USB_AUDIO_SEND_32BIT +#define SAMPLE_SIZE_CAPTURE 4 +#define SAMPLE_SIZE_SEND 4 +#elif defined(USB_AUDIO_SEND_24BIT) +#define SAMPLE_SIZE_CAPTURE 4 +#define SAMPLE_SIZE_SEND 3 +#else +#define SAMPLE_SIZE_CAPTURE 2 +#define SAMPLE_SIZE_SEND 2 +#endif + +#define CHAN_NUM_PLAYBACK 2 +#define CHAN_NUM_RECV 2 +#ifdef USB_AUDIO_SEND_CHAN +#define CHAN_NUM_SEND USB_AUDIO_SEND_CHAN +#else +#define CHAN_NUM_SEND 2 +#endif +#if defined(CHIP_BEST1000) && defined(ANC_APP) +#define CHAN_NUM_CAPTURE 2 +#elif defined(USB_AUDIO_SPEECH) +#define CHAN_NUM_CAPTURE SPEECH_CODEC_CAPTURE_CHANNEL_NUM +#else +#define CHAN_NUM_CAPTURE CHAN_NUM_SEND +#endif + +#define BYTE_TO_SAMP_PLAYBACK(n) ((n) / SAMPLE_SIZE_PLAYBACK / CHAN_NUM_PLAYBACK) +#define SAMP_TO_BYTE_PLAYBACK(n) ((n) * SAMPLE_SIZE_PLAYBACK * CHAN_NUM_PLAYBACK) + +#define BYTE_TO_SAMP_CAPTURE(n) ((n) / SAMPLE_SIZE_CAPTURE / CHAN_NUM_CAPTURE) +#define SAMP_TO_BYTE_CAPTURE(n) ((n) * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) + +#define BYTE_TO_SAMP_RECV(n) ((n) / SAMPLE_SIZE_RECV / CHAN_NUM_RECV) +#define SAMP_TO_BYTE_RECV(n) ((n) * SAMPLE_SIZE_RECV * CHAN_NUM_RECV) + +#define BYTE_TO_SAMP_SEND(n) ((n) / SAMPLE_SIZE_SEND / CHAN_NUM_SEND) +#define SAMP_TO_BYTE_SEND(n) ((n) * SAMPLE_SIZE_SEND * CHAN_NUM_SEND) + +#define SAMP_RATE_TO_FRAME_SIZE(n) (((n) + (1000 - 1)) / 1000) + +#define SAMPLE_FRAME_PLAYBACK SAMP_RATE_TO_FRAME_SIZE(SAMPLE_RATE_PLAYBACK) +#define SAMPLE_FRAME_CAPTURE SAMP_RATE_TO_FRAME_SIZE(SAMPLE_RATE_CAPTURE) + +#define SAMPLE_FRAME_RECV SAMP_RATE_TO_FRAME_SIZE(SAMPLE_RATE_RECV) +#define SAMPLE_FRAME_SEND SAMP_RATE_TO_FRAME_SIZE(SAMPLE_RATE_SEND) + +#define FRAME_SIZE_PLAYBACK SAMP_TO_BYTE_PLAYBACK(SAMPLE_FRAME_PLAYBACK) +#define FRAME_SIZE_CAPTURE SAMP_TO_BYTE_CAPTURE(SAMPLE_FRAME_CAPTURE) + +#define FRAME_SIZE_RECV SAMP_TO_BYTE_RECV(SAMPLE_FRAME_RECV) +#define FRAME_SIZE_SEND SAMP_TO_BYTE_SEND(SAMPLE_FRAME_SEND) + +#define PLAYBACK_TO_RECV_LEN(n) (SAMP_TO_BYTE_RECV((BYTE_TO_SAMP_PLAYBACK(n) * \ + (SAMPLE_RATE_RECV / 100) + (SAMPLE_RATE_PLAYBACK / 100) - 1) / (SAMPLE_RATE_PLAYBACK / 100))) +#define CAPTURE_TO_SEND_LEN(n) (SAMP_TO_BYTE_SEND((BYTE_TO_SAMP_CAPTURE(n) * \ + (SAMPLE_RATE_SEND / 100) + (SAMPLE_RATE_CAPTURE / 100) - 1) / (SAMPLE_RATE_CAPTURE / 100))) + +#ifdef USB_HIGH_SPEED +#if defined(USB_AUDIO_384K) || defined(USB_AUDIO_352_8K) +#define MAX_FRAME_SIZE_PLAYBACK (SAMP_RATE_TO_FRAME_SIZE(384000) * 4 * CHAN_NUM_PLAYBACK) +#else +#define MAX_FRAME_SIZE_PLAYBACK (SAMP_RATE_TO_FRAME_SIZE(192000) * 4 * CHAN_NUM_PLAYBACK) +#endif +#else +// Same as (SAMP_RATE_TO_FRAME_SIZE(192000) * 2 * CHAN_NUM_PLAYBACK) +#define MAX_FRAME_SIZE_PLAYBACK (SAMP_RATE_TO_FRAME_SIZE(96000) * 4 * CHAN_NUM_PLAYBACK) +#endif +#if (defined(__AUDIO_RESAMPLE__) && defined(SW_CAPTURE_RESAMPLE)) || \ + (defined(CHIP_BEST1000) && (defined(ANC_APP) || defined(_DUAL_AUX_MIC_))) +// Fixed capture sample rate +#define MAX_FRAME_SIZE_CAPTURE (SAMP_RATE_TO_FRAME_SIZE(SAMPLE_RATE_CAPTURE) * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) +#else +#define MAX_FRAME_SIZE_CAPTURE (SAMP_RATE_TO_FRAME_SIZE(48000) * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) +#endif + +#ifdef USB_HIGH_SPEED +#if defined(USB_AUDIO_384K) || defined(USB_AUDIO_352_8K) +#define MAX_FRAME_SIZE_RECV (SAMP_RATE_TO_FRAME_SIZE(384000) * 4 * CHAN_NUM_RECV) +#else +#define MAX_FRAME_SIZE_RECV (SAMP_RATE_TO_FRAME_SIZE(192000) * 4 * CHAN_NUM_RECV) +#endif +#else +// Same as (SAMP_RATE_TO_FRAME_SIZE(192000) * 2 * CHAN_NUM_RECV) +#define MAX_FRAME_SIZE_RECV (SAMP_RATE_TO_FRAME_SIZE(96000) * 4 * CHAN_NUM_RECV) +#endif +#define MAX_FRAME_SIZE_SEND (SAMP_RATE_TO_FRAME_SIZE(48000) * SAMPLE_SIZE_SEND * CHAN_NUM_SEND) + +// ---------------- +// Buffer alignment +// ---------------- + +#define AF_DMA_LIST_CNT 4 + +#ifdef ADC_CH_SEP_BUFF +#define ADC_BURST_NUM 4 +#define ADC_ALL_CH_DMA_BURST_SIZE (ADC_BURST_NUM * SAMPLE_SIZE_CAPTURE * CHAN_NUM_CAPTURE) +#define ADC_BUFF_ALIGN (ADC_ALL_CH_DMA_BURST_SIZE * AF_DMA_LIST_CNT) +#else +#define ADC_BUFF_ALIGN (4 * AF_DMA_LIST_CNT) +#endif +#if defined(__HW_FIR_DSD_PROCESS__) +// FIR DSD requires DAC buffer is aligned to 16-sample boundary for each FIR DMA process loop +#define DAC_BUFF_ALIGN (16 * SAMPLE_SIZE_PLAYBACK * CHAN_NUM_PLAYBACK * 2) +#else +#define DAC_BUFF_ALIGN (4 * AF_DMA_LIST_CNT) +#endif + +// USB buffer is split into 2 parts, and transfers from the second half (similar to PING-PONG buffer) +#ifdef USB_AUDIO_DYN_CFG +// RECV type-I frame slot (sample_size*chan_num): 2*2=4, 3*2=6, 4*2=8. The least common multiple is 24 +#define RECV_BUFF_ALIGN (2 * 24) +// SEND type-I frame slot (sample_size*chan_num): 2*2=4. The least common multiple is 4 +#define SEND_BUFF_ALIGN (2 * 4) +#else +// If usb rx/tx pool is NOT used, the buffer size should be aligned to frame packet size +#define RECV_BUFF_ALIGN SAMP_TO_BYTE_RECV(2) +#define SEND_BUFF_ALIGN SAMP_TO_BYTE_SEND(2) +#endif + +#define NON_EXP_ALIGN(val, exp) (((val) + ((exp) - 1)) / (exp) * (exp)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tests/anc_usb/usb_vendor_msg.c b/tests/anc_usb/usb_vendor_msg.c new file mode 100644 index 0000000..9064bd1 --- /dev/null +++ b/tests/anc_usb/usb_vendor_msg.c @@ -0,0 +1,266 @@ +#ifdef _VENDOR_MSG_SUPPT_ + +#include +#include "stdlib.h" +#include +#include "hal_trace.h" +#include "crc32.h" +#include "hal_norflash.h" +#include "pmu.h" +#include "cmsis.h" +#include "hal_cmu.h" +#include "tgt_hardware.h" +#include "hal_timer.h" +#include "hal_bootmode.h" +#ifdef USB_EQ_TUNING +#include "hal_cmd.h" +#endif + +#ifdef USB_ANC_MC_EQ_TUNING +#include "anc_process.h" +#endif + +#include "usb_vendor_msg.h" + +#define SYS_CHECK_VAL "1.1" + +#define FACT_SEC_VER 2 +#define FACT_SEC_MAGIC 0xba80 + +typedef enum { + FACT_SEC_VER_MAGIC, + FACT_SEC_CRC, + + FACT_SEC_DATA_START, + FACT_SEC_SEQ = FACT_SEC_DATA_START, + FACT_SEC_PROD_SN, + FACT_SEC_END = FACT_SEC_PROD_SN + 8, + + FACT_SEC_NUM = 256 +} FACT_SEC_E; + +typedef enum { + PC_TOOL_CMD_IDLE, + PC_TOOL_CMD_GET_FW_VER, + PC_TOOL_CMD_GET_PROD_SN, +// QUERY_VOLTAGE, +// BURN_SN, + PC_TOOL_CMD_SYS_REBOOT, + PC_TOOL_CMD_SYS_SHUTDOWN, + PC_TOOL_CMD_PING, + PC_TOOL_CMD_CHECK, + PC_TOOL_CMD_FW_UPDATE, +#ifdef USB_EQ_TUNING + PC_TOOL_CMD_EQ_TUNING, +#endif +#ifdef USB_ANC_MC_EQ_TUNING + PC_TOOL_CMD_ANC_MC_EQ_TUNING, +#endif + PC_TOOL_CMD_NUM, +}PC_TOOL_CMD_E; + +static char* s_pc_cmd_lst[PC_TOOL_CMD_NUM] = { + " ", + "QUERY_SW_VER", + "QUERY_SN", +// "QUERY_VOL", +// "BURN_SN", + "SYS_REBOOT", + "SYS_SHUTDOWN", + "PING_THROUGH_VENDOR", + "CHECK", + "FW_UPDATE", +#ifdef USB_EQ_TUNING + "EQ<", +#endif +#ifdef USB_ANC_MC_EQ_TUNING + "ANC_MC_EQ", +#endif +}; + +static PC_TOOL_CMD_E s_cur_cmd = PC_TOOL_CMD_IDLE; + +static uint8_t* s_sn_ptr; +static uint8_t* s_fw_ver_ptr; + +static uint8_t s_sn_sz; +static uint8_t s_fw_ver_sz; + +uint8_t vendor_msg_rx_buf[VENDOR_RX_BUF_SZ]; + +extern void analog_aud_codec_mute(void); + +int WEAK vendor_get_sn_info(uint8_t **p_ptr, uint8_t *p_size) +{ + static const char sn[] = "SN-001"; + + *p_ptr = (uint8_t *)sn; + *p_size = sizeof(sn) - 1; + return 0; +} + +int WEAK vendor_get_fw_ver_info(uint8_t **p_ptr, uint8_t *p_size) +{ + static const char ver[] = "VER-001"; + + *p_ptr = (uint8_t *)ver; + *p_size = sizeof(ver) - 1; + return 0; +} + +void vendor_info_init (void) +{ + vendor_get_sn_info(&s_sn_ptr, &s_sn_sz); + vendor_get_fw_ver_info(&s_fw_ver_ptr, &s_fw_ver_sz); +} + +static void pc_usb_cmd_set (struct USB_AUDIO_VENDOR_MSG_T* msg) +{ + size_t ret; + uint8_t cmd_id = 0; + + if (0 == msg->length) + return; + + for (cmd_id = 1; cmd_id < PC_TOOL_CMD_NUM; cmd_id++) { + ret = memcmp((void *)msg->data, (void *)s_pc_cmd_lst[cmd_id], strlen((char *)s_pc_cmd_lst[cmd_id])); + if (!ret) break; + } + + if (cmd_id > (PC_TOOL_CMD_NUM-1)) { + return; + } + + s_cur_cmd = cmd_id; + //TRACE(3,"%s: cmd[%s], id[%d]", __func__, s_pc_cmd_lst[cmd_id], s_cur_cmd); + msg->data += strlen((char*)s_pc_cmd_lst[cmd_id]); +#ifdef USB_ANC_MC_EQ_TUNING + msg->length -=strlen((char*)s_pc_cmd_lst[cmd_id]); +#endif + + switch (s_cur_cmd) { +#ifdef USB_EQ_TUNING + case PC_TOOL_CMD_EQ_TUNING: + hal_cmd_list_process(msg->data); + break; +#endif + +#ifdef USB_ANC_MC_EQ_TUNING + case PC_TOOL_CMD_ANC_MC_EQ_TUNING: + //TRACE(1,"recev len:%d",msg->length); + /* + TRACE(0,"***********recev test*************"); + for(int i=0;ilength;i++) + { + TRACE(2,"msg->data[%d]:0x%x",i,msg->data[i]); + } + TRACE(0,"***********recev test*************"); + */ + anc_cmd_receve_process(msg->data,msg->length); + break; +#endif + default: + break; + } +} + +static void pc_usb_cmd_exec (struct USB_AUDIO_VENDOR_MSG_T* msg) +{ + //TRACE(2,"%s: cmd[%d]", __func__, s_cur_cmd); + static const char* s_str_ret1 = "1"; +#ifdef USB_EQ_TUNING + static const char* s_str_ret0 = "0"; +#endif + static const char* s_str_failure = "failure"; + + switch (s_cur_cmd) { + case PC_TOOL_CMD_GET_FW_VER: + msg->data = s_fw_ver_ptr; + msg->length = strlen((char*)s_fw_ver_ptr); + break; + + case PC_TOOL_CMD_GET_PROD_SN: + msg->data = s_sn_ptr; + msg->length = strlen((char*)s_sn_ptr); + break; + + case PC_TOOL_CMD_SYS_REBOOT: + //TRACE(0,"-> cmd_exec: reboot....."); + hal_sys_timer_delay(MS_TO_TICKS(500)); + hal_cmu_sys_reboot(); + break; + + case PC_TOOL_CMD_SYS_SHUTDOWN: + pmu_shutdown(); + break; + + case PC_TOOL_CMD_PING: + msg->data = (uint8_t *)s_pc_cmd_lst[PC_TOOL_CMD_PING]; + msg->length = (uint32_t)strlen((const char *)msg->data); + break; + + case PC_TOOL_CMD_CHECK: + msg->data = (uint8_t*)SYS_CHECK_VAL; + msg->length = strlen((char*)SYS_CHECK_VAL); + break; + + case PC_TOOL_CMD_FW_UPDATE: + hal_sw_bootmode_clear(1<<8); // to clear HAL_SW_BOOTMODE_FORCE_UART_DLD + hal_sw_bootmode_set(1<<7); // to set HAL_SW_BOOTMODE_FORCE_USB_DLD +#ifdef TGT_PLL_FREQ + extern void pll_config_update (uint32_t); + pll_config_update(960000000); +#endif + analog_aud_codec_mute(); + msg->data = (uint8_t*)s_str_ret1; + msg->length = (uint32_t)strlen(s_str_ret1); + break; + +#ifdef USB_EQ_TUNING + case PC_TOOL_CMD_EQ_TUNING: + hal_cmd_tx_process(&msg->data, &msg->length); + if (!msg->length) { + msg->data = (uint8_t*)s_str_ret0; + msg->length = (uint32_t)strlen(s_str_ret0); + } + break; +#endif + +#ifdef USB_ANC_MC_EQ_TUNING + case PC_TOOL_CMD_ANC_MC_EQ_TUNING: + anc_cmd_send_process(&msg->data, &msg->length); + TRACE(1,"sned len:%d",msg->length); + +/* TRACE(0,"***********send test*************"); + for(int i=0;ilength;i++) + { + TRACE(2,"msg->data[%d]:0x%x",i,msg->data[i]); + } + TRACE(0,"***********send test*************"); + */ + break; +#endif + + default: + msg->data = (uint8_t*)s_str_failure; + msg->length = (uint32_t)strlen(s_str_failure); + break; + } + + s_cur_cmd = PC_TOOL_CMD_IDLE; +} + + +int usb_vendor_callback (struct USB_AUDIO_VENDOR_MSG_T* msg) +{ + + if (0 == msg->length) { + pc_usb_cmd_exec(msg); + } else { + pc_usb_cmd_set(msg); + } + + return 0; +} + +#endif diff --git a/tests/anc_usb/usb_vendor_msg.h b/tests/anc_usb/usb_vendor_msg.h new file mode 100644 index 0000000..6d5b009 --- /dev/null +++ b/tests/anc_usb/usb_vendor_msg.h @@ -0,0 +1,17 @@ +#ifndef _USB_VENDOR_MSG_H_ +#define _USB_VENDOR_MSG_H_ + +#include "usb_audio.h" + +#ifdef USB_ANC_MC_EQ_TUNING +#define VENDOR_RX_BUF_SZ 5000 +#else +#define VENDOR_RX_BUF_SZ 240 +#endif +extern uint8_t vendor_msg_rx_buf[VENDOR_RX_BUF_SZ]; + +int usb_vendor_callback (struct USB_AUDIO_VENDOR_MSG_T *msg); + +void vendor_info_init (void); + +#endif // _USB_VENDOR_MSG_H_ diff --git a/thirdparty/Makefile b/thirdparty/Makefile new file mode 100644 index 0000000..db2b643 --- /dev/null +++ b/thirdparty/Makefile @@ -0,0 +1,15 @@ +obj-y := userapi/ + +ifeq ($(TILE_DATAPATH_ENABLED), 1) +obj-y += tile +endif + +ifeq ($(THIRDPARTY_LIB),) +THIRDPARTY_LIB := demo +$(info demo) +else ifeq ($(THIRDPARTY_LIB),voicespot) +KBUILD_CPPFLAGS += -D_VOICESPOT_ +endif + +obj-y += $(foreach lib,$(THIRDPARTY_LIB),$(lib)_lib/) + diff --git a/thirdparty/audio_codec_lib/Makefile b/thirdparty/audio_codec_lib/Makefile new file mode 100644 index 0000000..a2b6b88 --- /dev/null +++ b/thirdparty/audio_codec_lib/Makefile @@ -0,0 +1,7 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + diff --git a/thirdparty/audio_codec_lib/ldac/Makefile b/thirdparty/audio_codec_lib/ldac/Makefile new file mode 100644 index 0000000..c1ca4cd --- /dev/null +++ b/thirdparty/audio_codec_lib/ldac/Makefile @@ -0,0 +1,14 @@ +#obj-y := src/ + +APP_LDAC_LIB_NAME := ldac_lib +obj-y += $(APP_LDAC_LIB_NAME).a +subdir-ccflags-y += \ + -Ithirdparty/audio_codec_lib/ldac/inc \ + -Iservices/multimedia/speech/process/common/include \ + -Iservices/bt_app + +subdir-ccflags-y += -Wall -Wno-long-long + + + + \ No newline at end of file diff --git a/thirdparty/audio_codec_lib/ldac/inc/ldacBT.h b/thirdparty/audio_codec_lib/ldac/inc/ldacBT.h new file mode 100644 index 0000000..d051a31 --- /dev/null +++ b/thirdparty/audio_codec_lib/ldac/inc/ldacBT.h @@ -0,0 +1,667 @@ +/******************************************************************************* + * + * Copyright (C) 2013 - 2017 Sony Corporation + * + ******************************************************************************/ + +#ifndef _LDACBT_H_ +#define _LDACBT_H_ +#ifdef __cplusplus +extern "C" { +#endif +#ifndef LDACBT_API +#define LDACBT_API +#endif /* LDACBT_API */ + +/* This file contains the definitions, declarations and macros for an implimentation of +#ifdef _ENCODE_ONLY + * LDAC encode processing. +#endif +#ifdef _DECODE_ONLY + * LDAC decode processing. +#endif +#ifndef _ENCODE_ONLY +#ifndef _DECODE_ONLY + * LDAC encode and decode processing. +#endif +#endif + * +#ifndef _DECODE_ONLY + * The basic flow of the encode processing is as follows: + * - The program creates an handle of an LDAC api using ldacBT_get_handle(). + * - The program initialize the handle for encode using ldacBT_init_handle_encode(). + * - The program calls ldacBT_encode() to encode data. + * - If the program demands to control the Encode Quality Mode Index, then one of the following + * should be called: + * - ldacBT_set_eqmid() + * - ldacBT_alter_eqmid() + * - The program finishes the encoding with passing NULL to input pcm buffer for ldacBT_encode(), + * which enables the encoder to encode remaining data in its input buffers. + * - The handle may be closed using ldacBT_close_handle() then used again, or released with + * ldacBT_free_handle(). + * - The rest of the set functions should be called only if it is needed by the client. +#endif // _DECODE_ONLY +#ifndef _ENCODE_ONLY + * The basic flow of the decode processing is as follows: + * - The program creates an handle of an LDAC api using ldacBT_get_handle(). + * - The program initialize the handle for decode using ldacBT_init_handle_decode(). + * - The program calls ldacBT_decode() to decode data. + * - The handle may be closed using ldacBT_close_handle() then used again, or released with + * ldacBT_free_handle(). + * - The rest of the set functions should be called only if it is needed by the client. +#endif // _ENCODE_ONLY + * + * + * Note for an implimentation + * - Error processing + * When continuous processing for next frame is performed after error detection, following + * processing must be carried out using C function provided in the library. +#ifdef _ENCODE_ONLY + * - Release of internal variables in encode processing using ldacBT_close_handle(). + * - Allocation and initialization of internal variables in encode processing using + * ldacBT_init_handle_encode(). + * Note that the encoded output for a few frames will not be present just after error recovery. +#endif // _ENCODE_ONLY +#ifdef _DECODE_ONLY + * - Release of internal variables in decode processing using ldacBT_close_handle(). + * - Allocation and initialization of internal variables in decode processing using + * ldacBT_init_handle_decode(). + * Note that the first decoded out PCM signal will not be present just after error recovery. +#endif // _DECODE_ONLY +#ifndef _ENCODE_ONLY +#ifndef _DECODE_ONLY + * - Release of internal variables in encode/decode processing using ldacBT_close_handle(). + * - Allocation and initialization of internal variables in encode/decode processing using + * ldacBT_init_handle_encode() for encode, ldacBT_init_handle_decode() for decode. + * Note that the encoded output for a few frames will not be present just after error recovery. + * Note that the first decoded out PCM signal will not be present just after error recovery. +#endif +#endif + * +#ifndef _DECODE_ONLY + * - Resuming of the encode processing from an interruption + * In case of resuming of the encode processing from interruption (such as changing + * configuration, seeking and playback), initialization of internal variables in encode + * processing must be carried out as error processing described above. + * Note that the encoded output for a few frames will not be present just after initialization + * as above. +#endif +#ifndef _ENCODE_ONLY + * Resuming of the decode processing from an interruption + * In case of resuming of the decode processing from interruption (such as changing + * configuration, seeking and playback), initialization of internal variables in decode + * processing must be carried out as error processing described above. + * Note that the first decoded out PCM signal will not be present just after initialization + * as above. +#endif + * + * + * Glossary + * channel_config_index (cci) + * The channel setting information for ldaclib. + * See ldacBT_cm_to_cci() to get value from channel_mode. + * + * channel_mode (cm) + * The channel setting information for LDAC specification of Bluetooth A2DP. + * See ldacBT_cci_to_cm() to get value from channel_config_index. + * + * ldac_transport_frame + * See LDAC specification of bluetooth A2DP. + * + * Maximum Transmission Unit (MTU) + * The minimum MTU that a L2CAP implementation for LDAC shall support is 679 bytes, because LDAC + * is optimized with 2-DH5 packet as its target. + * + * frame + * An audio signal sequence representing a certain number of PCM audio signals. + * Encoding and decoding are processed frame by frame in LDAC. Number of samples in a frame is + * determined by sampling frequency as described below. + * + * Sampling frequency and frame sample. + * Supported sampling frequencies are 44.1, 48, 88.2 and 96 kHz. + * The relationship between sampling frequency and frame sample in LDAC are shown below. + * -------------------------------------------------------- + * | sampling frequency [kHz] | 44.1 | 48 | 88.2 | 96 | + * | frame sample [samples/channel] | 128 | 256 | + * -------------------------------------------------------- + * Though the frame size varies in LDAC core as described in the table, the number of samples in + * input PCM signal for encoding is fixed to 128 sample/channel, and it is not affected by + * sampling frequency. + */ +#define LDACBT_ENC_LSU 128 +#define LDACBT_MAX_LSU 512 + +/* channel_config_index. + * Supported value are below. + */ +#define LDAC_CCI_MONO 0 /* MONO */ +#define LDAC_CCI_DUAL_CHANNEL 1 /* DUAL CHANNEL */ +#define LDAC_CCI_STEREO 2 /* STEREO */ + +/* PCM format. + * Supported PCM format are shown below. + * - LDACBT_SMPL_FMT_S16 : signed 16bits little endian. + * - LDACBT_SMPL_FMT_S24 : signed 24bits little endian. + * - LDACBT_SMPL_FMT_S32 : signed 32bits little endian. + * - LDACBT_SMPL_FMT_F32 : single-precision floating point. + * The data sequency must be interleaved format by 1 sample. + * Ex) 2 channel audio, the data sequences are aligned as below. + * seq : |L[0]|R[0]|L[1]|R[1]|... + */ +typedef enum { + LDACBT_SMPL_FMT_S16 = 0x2, + LDACBT_SMPL_FMT_S24 = 0x3, + LDACBT_SMPL_FMT_S32 = 0x4, + LDACBT_SMPL_FMT_F32 = 0x5, +} LDACBT_SMPL_FMT_T; + +#ifndef _DECODE_ONLY +/* Encode Quality Mode Index. (EQMID) + * The configuration of encoding in LDAC will be coordinated by "Encode Quality Mode Index" + * parameter. Configurable values are shown below. + * - LDACBT_EQMID_HQ : Encode setting for High Quality. + * - LDACBT_EQMID_SQ : Encode setting for Standard Quality. + * - LDACBT_EQMID_MQ : Encode setting for Mobile use Quality. + */ +enum { + LDACBT_EQMID_HQ = 0, + LDACBT_EQMID_SQ, + LDACBT_EQMID_MQ, + LDACBT_EQMID_NUM, /* terminater */ +}; + +/* Bit rates + * Bit rates in each EQMID are depend on sampling frequency. + * In this API specification, these relations are shown below. + * ___________________________________________ + * | | Sampling Frequency[kHz] | + * | EQMID | 44.1, 88.2 | 48, 96 | + * +-----------------+------------+------------+ + * | LDACBT_EQMID_HQ | 909kbps | 990kbps | + * | LDACBT_EQMID_SQ | 606kbps | 660kbps | + * | LDACBT_EQMID_MQ | 303kbps | 330kbps | + * ------------------------------------------- + */ +#endif + +/* Maximum size of the "ldac_transport_frame" sequence at transportation. */ +#define LDACBT_MAX_NBYTES 1024 /* byte */ + +/* Maximum number of channel for LDAC */ +#define LDAC_PRCNCH 2 + +/* LDAC handle type */ +typedef struct _st_ldacbt_handle * HANDLE_LDAC_BT; + +/* Allocation of LDAC handle. + * Format + * HANDLE_LDAC_BT ldacBT_get_handle( void ); + * Arguments + * None. + * Return value + * HANDLE_LDAC_BT for success, NULL for failure. + */ +LDACBT_API HANDLE_LDAC_BT ldacBT_get_handle( void ); + +/* Release of LDAC handle. + * Format + * void ldacBT_free_handle( HANDLE_LDAC_BT hLdacBt ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * Return value + * None. + */ +LDACBT_API void ldacBT_free_handle( HANDLE_LDAC_BT hLdacBt ); + +/* Closing of initialized LDAC handle. + * Closed handle can be initialized and used again. + * Format + * void ldacBT_close_handle( HANDLE_LDAC_BT hLdacBt ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * Return value + * None. + */ +LDACBT_API void ldacBT_close_handle( HANDLE_LDAC_BT hLdacBt ); + +/* Acquisition of the library version. + * Format + * int ldacBT_get_version( void ); + * Arguments + * None. + * Return value + * int : version number. + * 23-16 bit : major version + * 15- 8 bit : minor version + * 7- 0 bit : branch version + * Ex) 0x00010203 -> version 1.02.03 + */ +LDACBT_API int ldacBT_get_version( void ); + +/* Acquisition of the sampling frequency in current configuration. +#ifdef _ENCODE_ONLY + * The LDAC handle must be initialized by API function ldacBT_init_handle_encode() prior to + * calling this function. +#endif +#ifdef _DECODE_ONLY + * The LDAC handle must be initialized by API function ldacBT_init_handle_decode() prior to + * calling this function. +#endif +#ifndef _ENCODE_ONLY +#ifndef _DECODE_ONLY + * The LDAC handle must be initialized by API function ldacBT_init_handle_encode() or + * ldacBT_init_handle_decode() prior to calling this function. +#endif +#endif + * Format + * int ldacBT_get_sampling_freq( HANDLE_LDAC_BT hLdacBt ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * Return value + * int : sampling frequency in current configuration. -1 for failure. + */ +LDACBT_API int ldacBT_get_sampling_freq( HANDLE_LDAC_BT hLdacBt ); + +/* Acquisition of the Bit-rate. +#ifdef _ENCODE_ONLY + * The LDAC handle must be initialized by API function ldacBT_init_handle_encode() prior to + * calling this function. +#endif +#ifdef _DECODE_ONLY + * The LDAC handle must be initialized by API function ldacBT_init_handle_decode() prior to + * calling this function. +#endif +#ifndef _ENCODE_ONLY +#ifndef _DECODE_ONLY + * The LDAC handle must be initialized by API function ldacBT_init_handle_encode() or + * ldacBT_init_handle_decode() prior to calling this function. +#endif +#endif + * Format + * int ldacBT_get_bitrate( HANDLE_LDAC_BT hLdacBt ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * Return value + * int : Bit-rate for previously processed ldac_transport_frame for success. -1 for failure. + */ +LDACBT_API int ldacBT_get_bitrate( HANDLE_LDAC_BT hLdacBt ); + +#ifndef _DECODE_ONLY +/* Initialization of a LDAC handle for encode processing. + * The LDAC handle must be allocated by API function ldacBT_get_handle() prior to calling this API. + * "mtu" value should be configured to MTU size of AVDTP Transport Channel, which is determined by + * SRC and SNK devices in Bluetooth transmission. + * "eqmid" is configured to desired value of "Encode Quality Mode Index". + * "cm" is configured to channel_mode in LDAC, which is determined by SRC and SNK devices in + * Bluetooth transmission. + * "fmt" is configured to input pcm audio format. + * When the configuration of "mtu", "cm", or "sf" changed, the re-initialization is required. + * + * Format + * int ldacBT_init_handle_encode( HANDLE_LDAC_BT hLdacBt, int mtu, int eqmid, int cm, + * LDACBT_SMPL_FMT_T fmt, int sf ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * mtu int MTU value. Unit:Byte. + * eqmid int Encode Quality Mode Index. + * cm int Information of the channel_mode. + * fmt LDACBT_SMPL_FMT_T Audio format type of input pcm. + * sf int Sampling frequency of input pcm. + * Return value + * int : 0 for success, -1 for failure. + */ +LDACBT_API int ldacBT_init_handle_encode( HANDLE_LDAC_BT hLdacBt, int mtu, int eqmid, int cm, + LDACBT_SMPL_FMT_T fmt, int sf ); + +/* Configuration of Encode Quality Mode Index. + * The LDAC handle must be initialized by API function ldacBT_init_handle_encode() prior to + * calling this function. + * The API function can be called at any time, after the completion of initializing. + * Format + * int ldacBT_set_eqmid( HANDLE_LDAC_BT hLdacBt, int eqmid ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * eqmid int Encode Quality Mode Index. + * Return value + * int : 0 for success, -1 for failure. + */ +LDACBT_API int ldacBT_set_eqmid( HANDLE_LDAC_BT hLdacBt, int eqmid ); + +/* Acquisition of prescribed Encode Quality Mode Index in current configuration. + * The LDAC handle must be initialized by API function ldacBT_init_handle_encode() prior to + * calling this function. + * Format + * int ldacBT_get_eqmid( HANDLE_LDAC_BT hLdacBt ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * Return value + * int : Encode Quality Mode Index for success, -1 for failure. + */ +LDACBT_API int ldacBT_get_eqmid( HANDLE_LDAC_BT hLdacBt ); + +/* Changing of configuration for Encode Quality Mode Index by one step. + * The LDAC handle must be initialized by API function ldacBT_init_handle_encode() prior to + * calling this function. + * Configuralbe values for "priority" are shown below. + * - LDACBT_EQMID_INC_QUALITY : Adjustment for EQMID by one step for the direction of + * getting close to LDACBT_EQMID_HQ. + * - LDACBT_EQMID_INC_CONNECTION : Adjustment for EQMID by one step for the direction of + * getting away from LDACBT_EQMID_HQ. + * For restoring prescribed value for "Encode Quality Mode Index", it must be configured again by + * API function ldacBT_init_handle_encode() or ldacBT_set_qmode(). + * A transition to the state other than "Encode Quality Mode Index" mention before may be occurred + * caused by an adjustment using this API function. + * The API function can be called at any time, after the completion of initializing. + * Format + * int ldacBT_alter_eqmid_priority( HANDLE_LDAC_BT hLdacBt, int priority ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * priority int The direction of changing EQMID. + * Return value + * int : 0 for success, -1 for failure. + */ +#define LDACBT_EQMID_INC_QUALITY 1 +#define LDACBT_EQMID_INC_CONNECTION -1 +LDACBT_API int ldacBT_alter_eqmid_priority( HANDLE_LDAC_BT hLdacBt, int priority ); + + +/* LDAC encode processing. + * The LDAC handle must be initialized by API function ldacBT_init_handle_encode() prior to calling + * this API function. + * + * Number of samples in input PCM signal for encoding is fixed to 128 samples per channel, and it + * is not affected by sampling frequency. + * + * The region in input signal buffer without any PCM signal must be filled with zero, if the + * number of samples is less than 128 samples. + * + * The format of PCM signal is determined by "fmt" configured by API function + * ldacBT_init_handle_encode(). + * + * Total size of referenced PCM signal (in byte) will be set in "pcm_used" on return. The value of + * "Number of input samples * Number of channels * sizeof(PCM word length)" will be set in normal. + * + * Finalize processing of encode will be carried out with setting "p_pcm" as zero. + * + * + * An output data in "ldac_transport_frame" sequence will be set to "p_stream" after several frame + * processing. So the output is not necessarily present at each calling of this API function. + * + * The presence of the output can be verified by checking whether the value of "stream_wrote", + * representing the number of written bytes for "p_stream", is positive or not. + * + * In addition, encoded data size for output will be determined by the value of "mtu" configured + * by API function ldacBT_init_handle_encode(). + * + * The number of "ldac_transport_frame" corresponding to "ldac_transport_frame" sequence as output + * will be set to "frame_num". + * + * Format + * int ldacBT_encode( HANDLE_LDAC_BT hLdacBt, void *p_pcm, int *pcm_used, + * unsigned char *p_stream, int *stream_sz, int *frame_num ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * p_pcm void * Input PCM signal sequence + * pcm_used int * Data size of referenced PCM singnal. Unit:Byte. + * p_stream unsigned char * Output "ldac_transport_frame" sequence. + * stream_sz int * Size of output data. Unit:Byte. + * frame_num int * Number of output "ldac_transport_frame" + * Return value + * int : 0 for success, -1 for failure. + */ +LDACBT_API int ldacBT_encode( HANDLE_LDAC_BT hLdacBt, void *p_pcm, int *pcm_used, + unsigned char *p_stream, int *stream_sz, int *frame_num ); +#endif /* _DECODE_ONLY */ +#ifndef _ENCODE_ONLY +/* for decode */ +/* Initialization of a LDAC handle for decode processing. + * The LDAC handle must be allocated by API function ldac_get_handle() prior to calling this + * function. + * "cm" is configured to channel_mode in LDAC, which is determined by SRC and SNK devices in + * Bluetooth transmission. + * "sf" is configured to sampling frequency, which is determined by SRC and SNK devices in + * Bluetooth transmission. + * Reserved arguments must be set to "0". + * Format + * int ldacBT_init_handle_decode( HANDLE_LDAC_BT hLdacBt, int cm, int sf, int nshift, + * int var0, int var1 ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * cm int Information of the channel_mode. + * sf int Sampling frequency of input LDAC bit stream. + * nshift int Reserved, must be "0". + * var0 int Reserved, must be "0". + * var1 int Reserved, must be "0". + * Return value + * int : 0 for success, -1 for failure. + */ +LDACBT_API int ldacBT_init_handle_decode( HANDLE_LDAC_BT hLdacBt, int cm, int sf, + int var0, int var1, int var2 ); + +/* LDAC decode processing. + * The LDAC handle must be initialized by API function ldacBT_init_handle_decode() prior to + * calling this function. + * < Regarding on input "ldac_transport_frame" > + * The valid data size of "ldac_transport_frame" must be set in "stream_bytes". + * Referenced data size of "ldac_transport_frame" for decode processing will be set in + * "used_bytes" on return. + * As a reading once of "ldac_transport_frame" is performed by internal processing with + * looking ahead of two bytes, "LDAC_MAX_NBYTES+2" bytes must be allocated for + * "ldac_transport_frame" (p_bs) in API function caller side. + * < Regarding on output PCM signal > + * "fmt" is configured to output pcm audio format. + * The size of output PCM signal will be set to "wrote_bytes". The value of + * "frame sample" * "Number of channels" * "bit length of pcm sample"/8 will be set in normal. + * The first decoded out PCM signal just after initialization will not be present. + * + * Format + * int ldac_decode ( HANDLE_LDAC_BT hLdacBt, unsigned char * p_bs, unsigned char * p_pcm + * LDACBT_SMPL_FMT_T fmt, int bs_bytes, + * int *used_bytes, int *wrote_bytes ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * p_bs unsigned char * Pointer to "ldac_transport_frame". + * p_pcm unsigned char * Decoded out PCM signal sequence. + * fmt LDACBT_SMPL_FMT_T Audio format type of output pcm. + * bs_bytes int * Data size of input "ldac_transport_frame". Unit: Byte. + * used_bytes int * Data size of referenced "ldac_transport_frame". Unit: Byte. + * wrote_bytes int * Size of decoded out PCM signal. Unit: Byte. + * Return value + * int : 0 for success, -1 for failure. + */ +LDACBT_API int ldacBT_decode( HANDLE_LDAC_BT hLdacBt, unsigned char *p_bs, unsigned char *p_pcm, + LDACBT_SMPL_FMT_T fmt, int bs_bytes, + int *used_bytes, int *wrote_bytes ); + +#endif /* _ENCODE_ONLY */ + +/* Acquisition of previously established error code. + * The LDAC handle must be allocated by API function ldacBT_get_handle() prior to calling this function. + * The details of error code are described below at the end of this header file. + * Tips for error code handling. + * The macro function LDACBT_FATAL() is useful to determine whether the error code is Fatal or not. + * Ex.) if( LDACBT_FATAL(err) ) // Fatal Error occurred. + * + * The macro function LDACBT_ERROR() is useful to determine whether the error occurred or not. + * Ex.) if( LDACBT_ERROR(err) ) // Error occurred. + * + * The macro function LDACBT_HANDLE_ERR() is useful to get the handle level error code. + * Ex.) err_handle_lv = LDACBT_HANDLE_ERR(err); + * + * The macro function LDACBT_BLOCK_ERR() is useful to get the block level error code. + * Ex.) err_block_lv = LDACBT_BLOCK_ERR(err); + * + * Format + * int ldacBT_get_error_code( HANDLE_LDAC_BT hLdacBt ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * Return value + * int : Error code. + */ +LDACBT_API int ldacBT_get_error_code( HANDLE_LDAC_BT hLdacBt ); + +/******************************************************************************* + Error Code +*******************************************************************************/ +#define LDACBT_ERR_NONE 0 + +/* Non Fatal Error ***********************************************************/ +#define LDACBT_ERR_NON_FATAL 1 + +/* Non Fatal Error (Block Level) *********************************************/ +#define LDACBT_ERR_BIT_ALLOCATION 5 + +/* Non Fatal Error (Handle Level) ********************************************/ +#define LDACBT_ERR_NOT_IMPLEMENTED 128 +#define LDACBT_ERR_NON_FATAL_ENCODE 132 +#define LDACBT_ERR_RESTRICTED_BY_NUM_FRAMES 255 + +/* Fatal Error ***************************************************************/ +#define LDACBT_ERR_FATAL 256 + +/* Fatal Error (Block Level) *************************************************/ +#define LDACBT_ERR_SYNTAX_BAND 260 +#define LDACBT_ERR_SYNTAX_GRAD_A 261 +#define LDACBT_ERR_SYNTAX_GRAD_B 262 +#define LDACBT_ERR_SYNTAX_GRAD_C 263 +#define LDACBT_ERR_SYNTAX_GRAD_D 264 +#define LDACBT_ERR_SYNTAX_GRAD_E 265 +#define LDACBT_ERR_SYNTAX_IDSF 266 +#define LDACBT_ERR_SYNTAX_SPEC 267 + +#define LDACBT_ERR_BIT_PACKING 280 + +#define LDACBT_ERR_ALLOC_MEMORY 300 + +/* Fatal Error (Handle Level) ************************************************/ +#define LDACBT_ERR_FATAL_HANDLE 512 + +#define LDACBT_ERR_ILL_SYNCWORD 516 +#define LDACBT_ERR_ILL_SMPL_FORMAT 517 +#define LDACBT_ERR_ILL_PARAM 518 + +#define LDACBT_ERR_ASSERT_SAMPLING_FREQ 530 +#define LDACBT_ERR_ASSERT_SUP_SAMPLING_FREQ 531 +#define LDACBT_ERR_CHECK_SAMPLING_FREQ 532 +#define LDACBT_ERR_ASSERT_CHANNEL_CONFIG 533 +#define LDACBT_ERR_CHECK_CHANNEL_CONFIG 534 +#define LDACBT_ERR_ASSERT_FRAME_LENGTH 535 +#define LDACBT_ERR_ASSERT_SUP_FRAME_LENGTH 536 +#define LDACBT_ERR_ASSERT_FRAME_STATUS 537 +#define LDACBT_ERR_ASSERT_NSHIFT 538 +#define LDACBT_ERR_ASSERT_CHANNEL_MODE 539 + +#define LDACBT_ERR_ENC_INIT_ALLOC 550 +#define LDACBT_ERR_ENC_ILL_GRADMODE 551 +#define LDACBT_ERR_ENC_ILL_GRADPAR_A 552 +#define LDACBT_ERR_ENC_ILL_GRADPAR_B 553 +#define LDACBT_ERR_ENC_ILL_GRADPAR_C 554 +#define LDACBT_ERR_ENC_ILL_GRADPAR_D 555 +#define LDACBT_ERR_ENC_ILL_NBANDS 556 +#define LDACBT_ERR_PACK_BLOCK_FAILED 557 + +#define LDACBT_ERR_DEC_INIT_ALLOC 570 +#define LDACBT_ERR_INPUT_BUFFER_SIZE 571 +#define LDACBT_ERR_UNPACK_BLOCK_FAILED 572 +#define LDACBT_ERR_UNPACK_BLOCK_ALIGN 573 +#define LDACBT_ERR_UNPACK_FRAME_ALIGN 574 +#define LDACBT_ERR_FRAME_LENGTH_OVER 575 +#define LDACBT_ERR_FRAME_ALIGN_OVER 576 + + +/* LDAC API for Encode */ +#define LDACBT_ERR_ALTER_EQMID_LIMITED 21 +#define LDACBT_ERR_HANDLE_NOT_INIT 1000 +#define LDACBT_ERR_ILL_EQMID 1024 +#define LDACBT_ERR_ILL_SAMPLING_FREQ 1025 +#define LDACBT_ERR_ILL_NUM_CHANNEL 1026 +#define LDACBT_ERR_ILL_MTU_SIZE 1027 +/* LDAC API for Decode */ +#define LDACBT_ERR_DEC_CONFIG_UPDATED 40 + + +/* Macro Functions for Error Code ********************************************/ +#define LDACBT_API_ERR(err) ((err >> 20) & 0x0FFF) +#define LDACBT_HANDLE_ERR(err) ((err >> 10) & 0x03FF) +#define LDACBT_BLOCK_ERR(err) ( err & 0x03FF) +#define LDACBT_ERROR(err) ((LDACBT_ERR_NON_FATAL) <= LDACBT_API_ERR(err) ? 1 : 0) +#define LDACBT_FATAL(err) ((LDACBT_ERR_FATAL) <= LDACBT_API_ERR(err) ? 1 : 0) + + + +/* Codec Specific Information Elements for LDAC + * (based on "LDAC Specification of Bluetooth A2DP Rev.2.0.1") + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * service_caps[4] | SONY ID | Octet0 + * service_caps[5] | SONY ID | Octet1 + * service_caps[6] | SONY ID | Octet2 + * service_caps[7] | SONY ID | Octet3 + * service_caps[8] | SONY Specific Codec ID | Octet4 + * service_caps[9] | SONY Specific Codec ID | Octet5 + * service_caps[A] | RFA | Sampling Frequency | Octet6 + * service_caps[B] | RFA | Channel Mode ID | Octet7 + */ +#define LDACBT_MEDIA_CODEC_SC_SZ (10+2) + +/* [Octet 0-3] Vendor ID for SONY */ +#define LDACBT_VENDOR_ID0 0x2D +#define LDACBT_VENDOR_ID1 0x01 +#define LDACBT_VENDOR_ID2 0x0 +#define LDACBT_VENDOR_ID3 0x0 + +/* [Octet 4-5] Vendor Specific A2DP Codec ID for LDAC */ +#define LDACBT_CODEC_ID0 0xAA +#define LDACBT_CODEC_ID1 0x00 + +/* [Octet 6] + * [b7,b6] : RFA + * Reserved for future additions. + * Bits with this designation shall be set to zero. + * Receivers shall ignore these bits. + * ----------------------------------------------------- + * [b5-b0] : Sampling frequency and its associated bit field in LDAC are shown below. + * | 5 | 4 | 3 | 2 | 1 | 0 | + * | o | | | | | | 44100 + * | | o | | | | | 48000 + * | | | o | | | | 88200 + * | | | | o | | | 96000 + * | | | | | o | | 176400 + * | | | | | | o | 192000 + * + */ +/* Support for 44.1kHz sampling frequency */ +#define LDACBT_SAMPLING_FREQ_044100 0x20 +/* Support for 48kHz sampling frequency */ +#define LDACBT_SAMPLING_FREQ_048000 0x10 +/* Support for 88.2kHz sampling frequency */ +#define LDACBT_SAMPLING_FREQ_088200 0x08 +/* Support for 96kHz sampling frequency */ +#define LDACBT_SAMPLING_FREQ_096000 0x04 +/* Support for 176.4kHz sampling frequency */ +#define LDACBT_SAMPLING_FREQ_176400 0x02 +/* Support for 192kHz sampling frequency */ +#define LDACBT_SAMPLING_FREQ_192000 0x01 + +/* [Octet 7] + * [b7-b3] : RFA + * Reserved for future additions. + * Bits with this designation shall be set to zero. + * Receivers shall ignore these bits. + * ------------------------------------------------------ + * [b2-b0] : Channel mode and its associated bit field in LDAC are shown below. + * | 2 | 1 | 0 | + * | o | | | MONO + * | | o | | DUAL CHANNEL + * | | | o | STEREO + */ +/* Support for MONO */ +#define LDACBT_CHANNEL_MODE_MONO 0x04 +/* Support for DUAL CHANNEL */ +#define LDACBT_CHANNEL_MODE_DUAL_CHANNEL 0x02 +/* Support for STEREO */ +#define LDACBT_CHANNEL_MODE_STEREO 0x01 + +#ifdef __cplusplus +} +#endif +#endif /* _LDACBT_H_ */ diff --git a/thirdparty/audio_codec_lib/liblhdc-dec/Makefile b/thirdparty/audio_codec_lib/liblhdc-dec/Makefile new file mode 100644 index 0000000..6fea250 --- /dev/null +++ b/thirdparty/audio_codec_lib/liblhdc-dec/Makefile @@ -0,0 +1,56 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) +auth_type := -DLICE_KEY_TYPE_KEYPRO +# -DHAVE_TEST_KEY + +ifeq ($(A2DP_LHDC_LARC), 1) +auth_type += -DHAVE_LARC +endif + +ifneq ($(GEN_LIB), 1) +auth_type += -DHAVE_TEST_KEY +endif + +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.S)) +obj_s += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.s)) +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)dec_src/*.c)) +obj_c += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +ifeq ($(A2DP_DECODER_VER),2) +ifeq ($(A2DP_LHDC_V3),1) +LHDC_LIB_NAME := BEST2300P_LibLHDC_V2_V3_3_1_0_SAVI_KEYPRO_UUID +else +LHDC_LIB_NAME := BEST2300P_LibLHDC_V2_V3_3_1_0_SAVI_KEYPRO_UUID +endif +else +LHDC_LIB_NAME := liblhdc-dec +endif + +$(LHDC_LIB_NAME)-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +obj-y += $(LHDC_LIB_NAME).a + +#CFLAGS_dec.o += -lc -O3 -Wchar-subscripts -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant +#CFLAGS_cirbuf.o += -lc -O3 -Wchar-subscripts -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant +#CFLAGS_lhdcUtil.o += -lc -O3 -Wchar-subscripts -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant +#CFLAGS_encdec.o += -lc -O3 -Wchar-subscripts -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant +#CFLAGS_lic_check.o += -lc -O3 -Wchar-subscripts -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant +#CFLAGS_licdecrypt.o += -lc -O3 -Wchar-subscripts -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant +ccflags-y += -lc -O3 -Wchar-subscripts -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant $(DEF) + +subdir-ccflags-y += \ + -Iservices/tws/inc \ + -Iutils/heap \ + -Iutils/cqueue \ + -Iapps/audioplayers \ + -Iservices/bt_app \ + -Iplatform \ + -Ithirdparty/audio_codec_lib/liblhdc-dec/dec_src \ + -Ithirdparty/audio_codec_lib/liblhdc-dec \ + -Iservices/ble_stack/ke/api \ + -Iservices/ble_stack/ble_ip \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/nvrecord \ + -Iservices/bt_if/inc \ + -Iconfig \ + -Iservices/ble_stack/hl/api diff --git a/thirdparty/audio_codec_lib/liblhdc-dec/inc/lhdcUtil.h b/thirdparty/audio_codec_lib/liblhdc-dec/inc/lhdcUtil.h new file mode 100644 index 0000000..01d4ef1 --- /dev/null +++ b/thirdparty/audio_codec_lib/liblhdc-dec/inc/lhdcUtil.h @@ -0,0 +1,56 @@ +/* + * lhdcUtil.h + * + * Created on: 2001/1/3 + * Author: eric.lee + */ + +#ifndef LHDC_UTIL_H +#define LHDC_UTIL_H + +#include "bluetooth.h" + + +// Define for LHDC stream type. +typedef enum { + LHDC_STRM_TYPE_COMBINE, + LHDC_STRM_TYPE_SPLIT +}LHDC_STRM_TYPE; + +typedef enum { + VERSION_2 = 200, + VERSION_3 = 300 +}lhdc_ver_t; + +typedef enum { + LHDCV2_BLOCK_SIZE = 512, + LHDCV3_BLOCK_SIZE = 256, +}lhdc_block_size_t; + +typedef struct bes_bt_local_info_t{ + uint8_t bt_addr[BTIF_BD_ADDR_SIZE]; + const char *bt_name; + uint8_t bt_len; + uint8_t ble_addr[BTIF_BD_ADDR_SIZE]; + const char *ble_name; + uint8_t ble_len; +}bes_bt_local_info; + + +#define A2DP_LHDC_HDR_LATENCY_LOW 0x00 +#define A2DP_LHDC_HDR_LATENCY_MID 0x01 +#define A2DP_LHDC_HDR_LATENCY_HIGH 0x02 +#define A2DP_LHDC_HDR_LATENCY_MASK (A2DP_LHDC_HDR_LATENCY_MID | A2DP_LHDC_HDR_LATENCY_HIGH) + +#define A2DP_LHDC_HDR_FRAME_NO_MASK 0xfc + +typedef int (*LHDC_GET_BT_INFO)(bes_bt_local_info * bt_info); + +void lhdcInit(uint32_t bitPerSample, uint32_t sampleRate, uint32_t scaleTo16Bits, lhdc_ver_t version); +bool lhdcReadyForInput(void); +uint32_t lhdcPutData(uint8_t * pInpBuf, uint32_t NumBytes); +uint32_t lhdcDecodeProcess(uint8_t * pOutBuf); +void lhdcDestroy(); +bool lhdcSetLicenseKeyTable(uint8_t * licTable, LHDC_GET_BT_INFO pFunc); +char * getVersionCode(); +#endif /* End of LHDC_UTIL_H */ diff --git a/thirdparty/demo_lib/Makefile b/thirdparty/demo_lib/Makefile new file mode 100644 index 0000000..660087d --- /dev/null +++ b/thirdparty/demo_lib/Makefile @@ -0,0 +1,11 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + + + + + diff --git a/thirdparty/demo_lib/demo_lib.c b/thirdparty/demo_lib/demo_lib.c new file mode 100644 index 0000000..273241f --- /dev/null +++ b/thirdparty/demo_lib/demo_lib.c @@ -0,0 +1,11 @@ +#include "cmsis_os.h" +#include "cmsis.h" +#include +#include "hal_trace.h" +#include "demo_lib.h" + + + + + + diff --git a/thirdparty/demo_lib/demo_lib.h b/thirdparty/demo_lib/demo_lib.h new file mode 100644 index 0000000..c505ce8 --- /dev/null +++ b/thirdparty/demo_lib/demo_lib.h @@ -0,0 +1,16 @@ +#ifndef __DEMO_LIB_H +#define __DEMO_LIB_H + + + +#ifdef __cplusplus +extern "C"{ +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/noise_tracker_lib/Makefile b/thirdparty/noise_tracker_lib/Makefile new file mode 100644 index 0000000..8d6897e --- /dev/null +++ b/thirdparty/noise_tracker_lib/Makefile @@ -0,0 +1,9 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +subdir-ccflags-y += \ + -Iservices/audio_dump/include \ diff --git a/thirdparty/noise_tracker_lib/noise_tracker.c b/thirdparty/noise_tracker_lib/noise_tracker.c new file mode 100644 index 0000000..81aaf85 --- /dev/null +++ b/thirdparty/noise_tracker_lib/noise_tracker.c @@ -0,0 +1,59 @@ +#include +#include "noise_tracker.h" +#include "audio_dump.h" +#include "hal_trace.h" + +//#define NT_DUMP_AUDIO_DATA + +#define SQUARE(x) ((x) * (x)) +#define LIN2DB(x) (10.f * log10f(x)) + +#define NORMAL_SCALE (1.f/32768/32768) + +static NoiseTrackerCallback _callback; +static int _threshold; +static int _ch_num; + +static float vec_power(int16_t *buf, uint32_t len, int stride) +{ + float sum = 0.f; + for (uint32_t i = 0; i < len; i += stride) + sum += SQUARE(buf[i]); + + return sum; +} + +void noise_tracker_init(NoiseTrackerCallback cb, int ch_num, int threshold) +{ + _callback = cb; + _threshold = threshold; + _ch_num = ch_num; + +#ifdef NT_DUMP_AUDIO_DATA + audio_dump_init(240 * ANC_NOISE_TRACKER_CHANNEL_NUM, sizeof(int16_t), 1); +#endif +} + +void noise_tracker_process(int16_t *buf, uint32_t len) +{ + float scale = 1.f / len * NORMAL_SCALE; + float maxPowerdB = -90; + +#ifdef NT_DUMP_AUDIO_DATA + audio_dump_clear_up(); + audio_dump_add_channel_data(0, buf, len); + audio_dump_run(); +#endif + + for (int i = 0; i < _ch_num; i++) { + float power = vec_power(&buf[i], len, _ch_num) * scale; + float powerdB = LIN2DB(power); + maxPowerdB = MAX(maxPowerdB, powerdB); + + //TRACE(3,"[%s] powerdB ch[%d] = %d", __FUNCTION__, i, (int)powerdB); + } + + if (maxPowerdB > _threshold) { + _callback(maxPowerdB); + } +} diff --git a/thirdparty/noise_tracker_lib/noise_tracker.h b/thirdparty/noise_tracker_lib/noise_tracker.h new file mode 100644 index 0000000..2c71ad0 --- /dev/null +++ b/thirdparty/noise_tracker_lib/noise_tracker.h @@ -0,0 +1,20 @@ +#ifndef NOISE_TRACKER_H +#define NOISE_TRACKER_H + +#include + +typedef void (*NoiseTrackerCallback)(float); + +#ifdef __cplusplus +extern "C" { +#endif + +void noise_tracker_init(NoiseTrackerCallback cb, int ch_num, int threshold); + +void noise_tracker_process(int16_t *buf, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/thirdparty/userapi/Makefile b/thirdparty/userapi/Makefile new file mode 100644 index 0000000..84920b3 --- /dev/null +++ b/thirdparty/userapi/Makefile @@ -0,0 +1,13 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + +obj-y += $(foreach lib,$(THIRDPARTY_LIB),$(lib)_app/) + +subdir-ccflags-y += \ + -Iutils/list + + diff --git a/thirdparty/userapi/app_thirdparty.cpp b/thirdparty/userapi/app_thirdparty.cpp new file mode 100644 index 0000000..40e9063 --- /dev/null +++ b/thirdparty/userapi/app_thirdparty.cpp @@ -0,0 +1,131 @@ +#include "cmsis_os.h" +#include "cmsis.h" +#include "list.h" +#include "hal_trace.h" +#include +#include "app_thirdparty.h" + + +APP_THIRDPARTY_HANDLE_TAB_T app_thirdparty_handle_table; + +void app_thirdparty_callback_init(THIRDPARTY_CALLBACK_TYPE type, APP_THIRDPARTY_CUSTOM_CB_T cb) +{ + TRACE(2, "%s type %d", __func__, type); + switch (type) + { + case THIRDPARTY_DATA_COME_CALLBACK: + app_thirdparty_handle_table._app_thirdparty_data_come_callback = cb; + break; + case THIRDPARTY_WAKE_UP_CALLBACK: + app_thirdparty_handle_table._app_thirdparty_wake_up_callback = cb; + break; + case THIRDPARTY_START_SPEECH_CALLBACK: + app_thirdparty_handle_table._app_thirdparty_start_callback = cb; + break; + case THIRDPARTY_STOP_SPEECH_CALLBACK: + app_thirdparty_handle_table._app_thirdparty_stop_callback = cb; + break; + default: + break; + } +} + +uint32_t app_thirdparty_callback_handble(THIRDPARTY_CALLBACK_TYPE type, void* param1, uint32_t param2) +{ + uint32_t ret = 0xFFFFFFFF; + //TRACE(2, "%s type %d", __func__, type); + + switch (type) + { + case THIRDPARTY_DATA_COME_CALLBACK: + if (app_thirdparty_handle_table._app_thirdparty_data_come_callback) + { + ret = app_thirdparty_handle_table._app_thirdparty_data_come_callback(param1, param2); + } + break; + case THIRDPARTY_WAKE_UP_CALLBACK: + if (app_thirdparty_handle_table._app_thirdparty_wake_up_callback) + { + ret = app_thirdparty_handle_table._app_thirdparty_wake_up_callback(param1, param2); + } + break; + case THIRDPARTY_START_SPEECH_CALLBACK: + if (app_thirdparty_handle_table._app_thirdparty_start_callback) + { + ret = app_thirdparty_handle_table._app_thirdparty_start_callback(param1, param2); + } + break; + case THIRDPARTY_STOP_SPEECH_CALLBACK: + if (app_thirdparty_handle_table._app_thirdparty_stop_callback) + { + ret = app_thirdparty_handle_table._app_thirdparty_stop_callback(param1, param2); + } + break; + default: + break; + } + + return ret; +} + +int app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_ID funcId,THIRDPARTY_EVENT_TYPE event_type) +{ + TRACE(3, "%s funcId=%d event_type=0x%x", __func__, funcId, event_type); + const APP_THIRDPARTY_HANDLE *dest_handle; + + if (app_thirdparty_handle_table.thirdparty_func_id == funcId) + { + for (uint32_t index = 0; + index < app_thirdparty_handle_table.thirdparty_handler_cnt; + index++) + { + dest_handle = &app_thirdparty_handle_table.thirdparty_handler_tab[index]; + if (dest_handle->thirdparty_sign.event == event_type) + { + TRACE(1,"find index=%d",index); + if (dest_handle->function) + { + return dest_handle->function(dest_handle->status, dest_handle->param); + } + } + } + } + + return 0; +} + + +void app_thirdparty_init(void) +{ +#ifdef __ALEXA_WWE + app_thirdparty_handle_table.thirdparty_handler_tab = THIRDPARTY_GET_HANDLER_TAB(ALEXA_WWE_LIB_NAME); + app_thirdparty_handle_table.thirdparty_handler_cnt = THIRDPARTY_GET_HANDLER_TAB_SIZE(ALEXA_WWE_LIB_NAME); +#elif defined(__KWS_ALEXA__) + app_thirdparty_handle_table.thirdparty_handler_tab = THIRDPARTY_GET_HANDLER_TAB(KWS_ALEXA_LIB_NAME); + app_thirdparty_handle_table.thirdparty_handler_cnt = THIRDPARTY_GET_HANDLER_TAB_SIZE(KWS_ALEXA_LIB_NAME); +#elif defined(__CYBERON) + app_thirdparty_handle_table.thirdparty_handler_tab = THIRDPARTY_GET_HANDLER_TAB(CYBERON_LIB_NAME); + app_thirdparty_handle_table.thirdparty_handler_cnt = THIRDPARTY_GET_HANDLER_TAB_SIZE(CYBERON_LIB_NAME); +#elif defined(__KNOWLES) + app_thirdparty_handle_table.thirdparty_handler_tab = THIRDPARTY_GET_HANDLER_TAB(KNOWLES_LIB_NAME); + app_thirdparty_handle_table.thirdparty_handler_cnt = THIRDPARTY_GET_HANDLER_TAB_SIZE(KNOWLES_LIB_NAME); +#elif defined(ANC_NOISE_TRACKER) + app_thirdparty_handle_table.thirdparty_handler_tab = THIRDPARTY_GET_HANDLER_TAB(NOISE_TRACKER_LIB_NAME); + app_thirdparty_handle_table.thirdparty_handler_cnt = THIRDPARTY_GET_HANDLER_TAB_SIZE(NOISE_TRACKER_LIB_NAME); +#elif defined(_VOICESPOT_) + app_thirdparty_handle_table.thirdparty_handler_tab = THIRDPARTY_GET_HANDLER_TAB(VOICESPOT_LIB_NAME); + app_thirdparty_handle_table.thirdparty_handler_cnt = THIRDPARTY_GET_HANDLER_TAB_SIZE(VOICESPOT_LIB_NAME); +#elif defined(__BIXBY) + app_thirdparty_handle_table.thirdparty_handler_tab = THIRDPARTY_GET_HANDLER_TAB(BIXBY_NAME); + app_thirdparty_handle_table.thirdparty_handler_cnt = THIRDPARTY_GET_HANDLER_TAB_SIZE(BIXBY_NAME); +#else + app_thirdparty_handle_table.thirdparty_handler_tab = THIRDPARTY_GET_HANDLER_TAB(DEMO_LIB_NAME); + app_thirdparty_handle_table.thirdparty_handler_cnt = THIRDPARTY_GET_HANDLER_TAB_SIZE(DEMO_LIB_NAME); +#endif + + app_thirdparty_handle_table.thirdparty_func_id = app_thirdparty_handle_table.thirdparty_handler_tab[0].thirdparty_sign.func_id; + app_thirdparty_handle_table.thirdparty_lib_id = app_thirdparty_handle_table.thirdparty_handler_tab[0].thirdparty_sign.lib_id; + + TRACE(3, "%s cnt=%d id=%d", __func__, app_thirdparty_handle_table.thirdparty_handler_cnt, app_thirdparty_handle_table.thirdparty_lib_id); +} + diff --git a/thirdparty/userapi/app_thirdparty.h b/thirdparty/userapi/app_thirdparty.h new file mode 100644 index 0000000..2e6210b --- /dev/null +++ b/thirdparty/userapi/app_thirdparty.h @@ -0,0 +1,157 @@ +#ifndef __APP_THIRDPARTY_H__ +#define __APP_THIRDPARTY_H__ + +#define INVALID_THIRDPARTY_ENTRY_INDEX 0xFFFF +#define APP_THIRDPARTY_DISABLE 0x5A5A + +#define ALEXA_WWE_LIB_NAME alexa_wwe +#define KWS_ALEXA_LIB_NAME kws_demo +#define CYBERON_LIB_NAME cyberon +#define KNOWLES_LIB_NAME knowles +#define NOISE_TRACKER_LIB_NAME nt_demo +#define VOICESPOT_LIB_NAME kws_engine +#define DEMO_LIB_NAME demo +#define BIXBY_NAME bixby + + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +typedef enum +{ + THIRDPARTY_FUNC_DEMO, // Each library has a unique id + THIRDPARTY_FUNC_NO1, // KWS + THIRDPARTY_FUNC_NO2, // knowles + THIRDPARTY_FUNC_NO3, // Noise tracker for anc + THIRDPARTY_FUNC_KWS, // key words + THIRDPARTY_FUNC_NUMBER, +} THIRDPARTY_FUNC_ID; + +typedef enum +{ + THIRDPARTY_ID_DEMO, // Each library has a unique id + THIRDPARTY_ID_BES_ALEXA, // key words + THIRDPARTY_ID_ALEXA_WWE, // AMA wakeup word engine + THIRDPARTY_ID_BIXBY, // Bixby wakeup word engine + THIRDPARTY_ID_NUMBER, +} THIRDPARTY_LIB_ID; + +typedef enum +{ + THIRDPARTY_INIT = 0x00, + THIRDPARTY_START = 0x01, + THIRDPARTY_STOP = 0x02, + THIRDPARTY_START2MIC = 0x03, + THIRDPARTY_STOP2MIC = 0x04, + THIRDPARTY_DEINIT = 0x05, + THIRDPARTY_BT_CONNECTABLE = 0x06, + THIRDPARTY_BT_DISCOVERABLE = 0x07, + THIRDPARTY_BT_CONNECTED = 0x08, + THIRDPARTY_A2DP_STREAMING = 0x09, + THIRDPARTY_HFP_SETUP = 0x0A, + THIRDPARTY_MIC_OPEN = 0x0B, + THIRDPARTY_MIC_CLOSE = 0x0C, + THIRDPARTY_BURSTING = 0x0D, + THIRDPARTY_AI_PROVIDE_SPEECH = 0x0E, + THIRDPARTY_AI_STOP_SPEECH = 0x0F, + THIRDPARTY_AI_CONNECT = 0x10, + THIRDPARTY_AI_DISCONNECT = 0x11, + THIRDPARTY_CALL_START = 0x12, + THIRDPARTY_CALL_STOP = 0x13, + THIRDPARTY_OTHER_EVENT = 0x14, + THIRDPARTY_EVENT_NUMBER, +}THIRDPARTY_EVENT_TYPE; + +typedef enum +{ + THIRDPARTY_DATA_COME_CALLBACK = 0x0, + THIRDPARTY_WAKE_UP_CALLBACK, + THIRDPARTY_START_SPEECH_CALLBACK, + THIRDPARTY_STOP_SPEECH_CALLBACK, +}THIRDPARTY_CALLBACK_TYPE; + +//the ai wake up type +typedef enum { + THIRDPARTY_TYPE__NONE, + THIRDPARTY_TYPE__PRESS_AND_HOLD, + THIRDPARTY_TYPE__TAP, + THIRDPARTY_TYPE__KEYWORD_WAKEUP +} THIRDPARTY_WAKE_UP_TYPE_E; + +typedef int (*APP_THIRDPARTY_HANDLE_CB_T)(unsigned char, void *param); +typedef uint32_t (*APP_THIRDPARTY_CUSTOM_CB_T)(void*, uint32_t); + +typedef struct { + int score; + uint32_t start_index; + uint32_t end_index; + THIRDPARTY_WAKE_UP_TYPE_E wake_up_type; +}APP_THIRDPARTY_WAKE_WORD_T; + +typedef struct { + THIRDPARTY_FUNC_ID func_id; + THIRDPARTY_LIB_ID lib_id; + THIRDPARTY_EVENT_TYPE event; +}APP_THIRDPARTY_SIGN; + +typedef struct { + APP_THIRDPARTY_SIGN thirdparty_sign; + APP_THIRDPARTY_HANDLE_CB_T function; + unsigned char status; + void *param; +} APP_THIRDPARTY_HANDLE; + +typedef struct +{ + // Pointer to the thirdparty handler table + const APP_THIRDPARTY_HANDLE *thirdparty_handler_tab; + // Number of thirdparty handler + uint16_t thirdparty_handler_cnt; + THIRDPARTY_FUNC_ID thirdparty_func_id; + THIRDPARTY_LIB_ID thirdparty_lib_id; + + APP_THIRDPARTY_CUSTOM_CB_T _app_thirdparty_data_come_callback; + APP_THIRDPARTY_CUSTOM_CB_T _app_thirdparty_wake_up_callback; + APP_THIRDPARTY_CUSTOM_CB_T _app_thirdparty_start_callback; + APP_THIRDPARTY_CUSTOM_CB_T _app_thirdparty_stop_callback; +}APP_THIRDPARTY_HANDLE_TAB_T; + + +#define _THIRDPARTY_HANDLER_TAB(id_name) const APP_THIRDPARTY_HANDLE id_name##_handler_tab[] = +#define _THIRDPARTY_GET_HANDLER_TAB(id_name) id_name##_handler_tab +#define _THIRDPARTY_HANDLER_TAB_SIZE(id_name) const uint32_t id_name##_handler_tab_size = ARRAY_SIZE(id_name##_handler_tab); +#define _THIRDPARTY_GET_HANDLER_TAB_SIZE(id_name) id_name##_handler_tab_size +#define _EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(id_name) extern const APP_THIRDPARTY_HANDLE id_name##_handler_tab[]; \ + extern const uint32_t id_name##_handler_tab_size; + +#define THIRDPARTY_HANDLER_TAB(id_name) _THIRDPARTY_HANDLER_TAB(id_name) +#define THIRDPARTY_GET_HANDLER_TAB(id_name) _THIRDPARTY_GET_HANDLER_TAB(id_name) +#define THIRDPARTY_HANDLER_TAB_SIZE(id_name) _THIRDPARTY_HANDLER_TAB_SIZE(id_name) +#define THIRDPARTY_GET_HANDLER_TAB_SIZE(id_name) _THIRDPARTY_GET_HANDLER_TAB_SIZE(id_name) +#define EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(id_name) _EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(id_name) + +EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(ALEXA_WWE_LIB_NAME) +EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(KWS_ALEXA_LIB_NAME) +EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(CYBERON_LIB_NAME) +EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(KNOWLES_LIB_NAME) +EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(NOISE_TRACKER_LIB_NAME) +EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(VOICESPOT_LIB_NAME) +EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(DEMO_LIB_NAME) +EXTERN_THIRDPARTY_HANDLER_TAB_AND_SIZE(BIXBY_NAME) + +#ifdef __cplusplus +extern "C" { +#endif + +void app_thirdparty_callback_init(THIRDPARTY_CALLBACK_TYPE type, APP_THIRDPARTY_CUSTOM_CB_T cb); +uint32_t app_thirdparty_callback_handble(THIRDPARTY_CALLBACK_TYPE type, void* param1, uint32_t param2); +int app_thirdparty_specific_lib_event_handle(THIRDPARTY_FUNC_ID funcId,THIRDPARTY_EVENT_TYPE event_type); +void app_thirdparty_init(void); + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/thirdparty/userapi/demo_app/LibDemo.cpp b/thirdparty/userapi/demo_app/LibDemo.cpp new file mode 100644 index 0000000..ebf40e8 --- /dev/null +++ b/thirdparty/userapi/demo_app/LibDemo.cpp @@ -0,0 +1,41 @@ +#include "cmsis_os.h" +#include "cmsis.h" +#include "cqueue.h" +#include "hal_trace.h" +#include +#include "demo_lib.h" +#include "LibDemo.h" + + +int demo_example_init(bool on,void *param) +{ + TRACE(0,"demo_example_init"); + return 0; +} + +int demo_example_start(bool on,void *param) +{ + TRACE(0,"demo_example_start"); + return 0; +} + +int demo_example_stop(bool on,void *param) +{ + TRACE(0,"demo_example_stop"); + return 0; +} + + +#include "app_thirdparty.h" + + +THIRDPARTY_HANDLER_TAB(DEMO_LIB_NAME) +{ + {{THIRDPARTY_FUNC_DEMO,THIRDPARTY_ID_DEMO,THIRDPARTY_START},(APP_THIRDPARTY_HANDLE_CB_T)demo_example_start,true,NULL}, + {{THIRDPARTY_FUNC_DEMO,THIRDPARTY_ID_DEMO,THIRDPARTY_STOP},(APP_THIRDPARTY_HANDLE_CB_T)demo_example_stop,true,NULL}, + {{THIRDPARTY_FUNC_DEMO,THIRDPARTY_ID_DEMO,THIRDPARTY_INIT},(APP_THIRDPARTY_HANDLE_CB_T)demo_example_init,true,NULL}, +}; + +THIRDPARTY_HANDLER_TAB_SIZE(DEMO_LIB_NAME) + + diff --git a/thirdparty/userapi/demo_app/LibDemo.h b/thirdparty/userapi/demo_app/LibDemo.h new file mode 100644 index 0000000..eaba78c --- /dev/null +++ b/thirdparty/userapi/demo_app/LibDemo.h @@ -0,0 +1,23 @@ +#ifndef __LIBDEMO_H__ +#define __LIBDEMO_H__ + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus + } +#endif + + + + + + + + +#endif diff --git a/thirdparty/userapi/demo_app/Makefile b/thirdparty/userapi/demo_app/Makefile new file mode 100644 index 0000000..95d0fd0 --- /dev/null +++ b/thirdparty/userapi/demo_app/Makefile @@ -0,0 +1,16 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + + +subdir-ccflags-y += \ + -Ithirdparty/demo_lib \ + -Iapps/audioplayers \ + -Iapps/common \ + -Iservices/bt_app \ + -Iservices/resources \ + -Iutils/cqueue \ + -Ithirdparty/userapi diff --git a/thirdparty/userapi/noise_tracker_app/Makefile b/thirdparty/userapi/noise_tracker_app/Makefile new file mode 100644 index 0000000..62740ce --- /dev/null +++ b/thirdparty/userapi/noise_tracker_app/Makefile @@ -0,0 +1,28 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + + +subdir-ccflags-y += \ + -Ithirdparty/noise_tracker_lib \ + -Iapps/audioplayers \ + -Iapps/common \ + -Iapps/key \ + -Iutils/heap \ + -Irtos/rtx/TARGET_CORTEX_M \ + -Iservices/bt_app \ + -Iservices/audio_dump/include \ + -Iplatform/drivers/ana \ + -Iservices/resources \ + -Iutils/cqueue \ + -Ithirdparty/userapi \ + $(BT_IF_INCLUDES) \ + -Iservices/multimedia/speech/inc \ + $(BT_PROFILES_INCLUDES) \ + +ifeq ($(VOICE_DETECTOR_EN),1) +subdir-ccflags-y += -Iapps/voice_detector +endif diff --git a/thirdparty/userapi/noise_tracker_app/NoiseTrackerDemo.cpp b/thirdparty/userapi/noise_tracker_app/NoiseTrackerDemo.cpp new file mode 100644 index 0000000..3fe7d21 --- /dev/null +++ b/thirdparty/userapi/noise_tracker_app/NoiseTrackerDemo.cpp @@ -0,0 +1,209 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "cmsis_os.h" +#include "cmsis.h" +#include "hal_trace.h" +#include +#include "app_utils.h" +#include "hal_timer.h" +#include + +// for audio +#include "audioflinger.h" +#include "app_audio.h" +#include "app_bt_stream.h" +#include "app_media_player.h" +#include "speech_ssat.h" +#include "speech_memory.h" +#include "audio_dump.h" + +#include "noise_tracker.h" +#include "noise_tracker_callback.h" + + +/**< NT Engine hooks */ +#define NT_ENGINE_INIT(callback, ch, threshold) noise_tracker_init(callback, ch, threshold) +#define NT_ENGINE_FEED(frame, n_samples) noise_tracker_process(frame, n_samples) + + +/**< NT configuration settings */ +#define NT_MIC_BITS_PER_SAMPLE (AUD_BITS_16) +#define NT_MIC_SAMPLE_RATE (16000) // (AUD_SAMPRATE_8000) +#define NT_MIC_VOLUME (16) + + +/**< NT Engine configuration settings */ +#define NT_ENGINE_SAMPLES_PER_FRAME (240) +#define NT_ENGINE_SAMPLE_RATE (16000) +#define NT_ENGINE_SYSFREQ (APP_SYSFREQ_26M) // (APP_SYSFREQ_26M) + + +/* Utility functions */ +#define NT_TRACE(s, ...) TRACE(1,"%s: " s, __FUNCTION__, ## __VA_ARGS__); +#define ALIGN4 __attribute__((aligned(4))) + + +/* Calcluate the audio-capture frame length, FRAME_LEN, based of decimation rate (1 or 2): */ +#define FRAME_LEN (NT_ENGINE_SAMPLES_PER_FRAME * (NT_MIC_SAMPLE_RATE / NT_ENGINE_SAMPLE_RATE)) +#define CAPTURE_CHANNEL_NUM (ANC_NOISE_TRACKER_CHANNEL_NUM) +#define CAPTURE_BUF_SIZE (FRAME_LEN * CAPTURE_CHANNEL_NUM * 2 * 2) +static uint8_t codec_capture_buf[CAPTURE_BUF_SIZE] ALIGN4; + +STATIC_ASSERT(FRAME_LEN == NT_ENGINE_SAMPLES_PER_FRAME, "NT_ENGINE Config error"); + + +/* Local state */ +static bool nt_demo_is_streaming = false; +extern uint8_t bt_sco_mode; + + + +/** + * @breif Handle one-time initialization, like setting up the memory pool + */ +static int nt_demo_init(bool, const void *) +{ + static bool done; + + NT_TRACE(0,"Initialize kws_demo"); + if (done) return 0; + + done = true; + + return 0; +} + +/** + * @brief DC block IIR filter + * + * @param inout Pointer of the PCM data (modify inplace). + * @param in_len Length of the PCM data in the buffer in samples. + * + */ +static void filter_iir_dc_block(short *inout, int in_len, int stride) +{ + static int z = 0; + int tmp; + + for (int i = 0; i < in_len; i += stride) + { + z = (15 * z + inout[i]) >> 4; + tmp = inout[i] - z; + inout[i] = speech_ssat_int16(tmp); + } +} + + +/** + * @brief Process the collected PCM data from MIC. + * Resample audio stream to 8KHz and pass audio to kws lib. + * + * @param buf Pointer of the PCM data buffer to access. + * @param length Length of the PCM data in the buffer in bytes. + * + * @return uint32_t 0 means no error happened + */ +static uint32_t nt_demo_stream_handler(uint8_t *buf, uint32_t length) +{ + ASSERT(length == FRAME_LEN * CAPTURE_CHANNEL_NUM * sizeof(int16_t), "stream length not matched"); + + short *pcm_buf = (short*)buf; + uint32_t pcm_len = length / 2; + + filter_iir_dc_block(pcm_buf, pcm_len, ANC_NOISE_TRACKER_CHANNEL_NUM); + NT_ENGINE_FEED(pcm_buf, pcm_len); + + return 0; +} + + +/** + * @brief Setup audio streaming from MIC + * + * @param do_stream start / stop streaming + * + * @return int 0 means no error happened + */ +static int nt_demo_stream_start(bool do_stream, const void *) +{ + struct AF_STREAM_CONFIG_T stream_cfg; + + NT_TRACE(3,"Is running:%d enable:%d, bt_sco_mode:%d", + nt_demo_is_streaming, do_stream, bt_sco_mode); + + if (bt_sco_mode) + return 0; + + if (nt_demo_is_streaming == do_stream) + return 0; + nt_demo_is_streaming = do_stream; + + if (do_stream) { + // Request sufficient system clock + app_sysfreq_req(APP_SYSFREQ_USER_APP_NT, NT_ENGINE_SYSFREQ); + NT_TRACE(1,"sys freq calc: %d Hz", hal_sys_timer_calc_cpu_freq(5, 0)); + + nt_demo_init(true, NULL); + + // Initialize the NT ENGINE and install word-callback + NT_ENGINE_INIT(nt_demo_words_cb, ANC_NOISE_TRACKER_CHANNEL_NUM, -20); + + memset(&stream_cfg, 0, sizeof(stream_cfg)); + stream_cfg.sample_rate = (AUD_SAMPRATE_T)NT_MIC_SAMPLE_RATE; + stream_cfg.bits = NT_MIC_BITS_PER_SAMPLE; + stream_cfg.vol = NT_MIC_VOLUME; + stream_cfg.device = AUD_STREAM_USE_INT_CODEC; + stream_cfg.io_path = AUD_INPUT_PATH_NTMIC; + stream_cfg.channel_num = (enum AUD_CHANNEL_NUM_T)ANC_NOISE_TRACKER_CHANNEL_NUM; + stream_cfg.handler = nt_demo_stream_handler; + stream_cfg.data_ptr = codec_capture_buf; + stream_cfg.data_size = CAPTURE_BUF_SIZE; + + af_stream_open(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE, &stream_cfg); + af_stream_start(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + + NT_TRACE(0,"audio capture ON"); + + + } + else { + af_stream_stop(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + af_stream_close(AUD_STREAM_ID_0, AUD_STREAM_CAPTURE); + + app_sysfreq_req(APP_SYSFREQ_USER_APP_NT, APP_SYSFREQ_32K); + TRACE(1,"sys freq calc:(32K) %d Hz", hal_sys_timer_calc_cpu_freq(5, 0)); + + NT_TRACE(0,"audio capture OFF"); + } + + return 0; +} + + + +#include "app_thirdparty.h" + +#define TP_EVENT(event, handler) {THIRDPARTY_FUNC_NO3, THIRDPARTY_ID_DEMO, THIRDPARTY_ ## event}, (APP_THIRDPARTY_HANDLE_CB_T)handler + +THIRDPARTY_HANDLER_TAB(NOISE_TRACKER_LIB_NAME) +{ +// {TP_EVENT(INIT, nt_demo_init), true, NULL}, + {TP_EVENT(START, nt_demo_stream_start), true, NULL}, + {TP_EVENT(STOP, nt_demo_stream_start), false, NULL}, +}; + +THIRDPARTY_HANDLER_TAB_SIZE(NOISE_TRACKER_LIB_NAME) + diff --git a/thirdparty/userapi/noise_tracker_app/noise_tracker_callback.c b/thirdparty/userapi/noise_tracker_app/noise_tracker_callback.c new file mode 100644 index 0000000..dd3a2e1 --- /dev/null +++ b/thirdparty/userapi/noise_tracker_app/noise_tracker_callback.c @@ -0,0 +1,14 @@ +#include "noise_tracker_callback.h" +#include "hal_trace.h" + +/** + * @brief Trigger word callback from kws lib + * + * @param word Detected word + * @param score Score of word + * + */ +void nt_demo_words_cb(float power) +{ + TRACE(1,"active power %d", (int)(power)); +} \ No newline at end of file diff --git a/thirdparty/userapi/noise_tracker_app/noise_tracker_callback.h b/thirdparty/userapi/noise_tracker_app/noise_tracker_callback.h new file mode 100644 index 0000000..047675d --- /dev/null +++ b/thirdparty/userapi/noise_tracker_app/noise_tracker_callback.h @@ -0,0 +1,14 @@ +#ifndef NOISE_TRACKER_CALLBACK_H +#define NOISE_TRACKER_CALLBACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +void nt_demo_words_cb(float power); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/utils/boot_struct/Makefile b/utils/boot_struct/Makefile new file mode 100644 index 0000000..5b9bcb1 --- /dev/null +++ b/utils/boot_struct/Makefile @@ -0,0 +1,11 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y := -Iplatform/hal + +ifeq ($(SECURE_BOOT),1) +ccflags-y += -DSECURE_BOOT +endif diff --git a/utils/boot_struct/boot_struct.c b/utils/boot_struct/boot_struct.c new file mode 100644 index 0000000..c867692 --- /dev/null +++ b/utils/boot_struct/boot_struct.c @@ -0,0 +1,213 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "tool_msg.h" +#include "reboot_param.h" +#include "norflash_cfg.h" +#include "hal_cmu.h" + +extern const char sys_build_info[]; + +#ifdef USER_SECURE_BOOT +extern const unsigned int system_info; +#endif + +// ----------------------------------------------------------- +// Boot struct and code sig struct +// ----------------------------------------------------------- +#if defined(PROGRAMMER_INFLASH) +#undef PROGRAMMER +#endif + +#define BOOT_STRUCT_LOC __attribute((section(".boot_struct"))) + +#ifdef USER_SECURE_BOOT +#define DEFAULT_BUILD_INFO ((uint32_t)&system_info) +#else +#define DEFAULT_BUILD_INFO ((uint32_t)sys_build_info) +#endif + +#define DEFAULT_CODE_SIG \ + { \ + .code_size = 0, \ + .sig_len = SIG_LEN, \ + } + +#ifdef SIMU +#define DEFAULT_NORFLASH_SAMDLY 0x1 +#define DEFAULT_NORFLASH_MOD_CLK HAL_CMU_FREQ_26M +#define DEFAULT_NORFLASH_RDCMD 0x03 +#else +#define DEFAULT_NORFLASH_SAMDLY 0x2 +// Select 26M for 40M crystal case +#define DEFAULT_NORFLASH_MOD_CLK HAL_CMU_FREQ_104M +// Below 50M: 0x03, Above 50M: 0x0B +#define DEFAULT_NORFLASH_RDCMD 0x0B +#endif + +#define DEFAULT_NORFLASH_CFG \ + { \ + .neg_phase = 0, \ + .pos_neg = 0, \ + .cmdquad = 0, \ + .div = 0x2, \ + .samdly = DEFAULT_NORFLASH_SAMDLY, \ + .dualmode = 1, \ + .holdpin = 0, \ + .wprpin = 0, \ + .quadmode = 0, \ + .mod_clk = DEFAULT_NORFLASH_MOD_CLK, \ + .spiruen = 0, \ + .spirden = 0, \ + .dualiocmd = 0xBB, \ + .rdcmd = DEFAULT_NORFLASH_RDCMD, \ + .frdcmd = 0x0B, \ + .qrdcmd = 0xEB, \ + } + +#ifdef SECURE_BOOT_V1 + +#ifdef PROGRAMMER + +struct programmer_boot_struct_t { + struct boot_struct_v1_t boot_struct; + struct code_sig_struct_t code_sig_struct; +}; + +const struct programmer_boot_struct_t BOOT_STRUCT_LOC programmer_boot_struct = { + .boot_struct = { + .hdr = { + .magic = BOOT_MAGIC_NUMBER, + .security = 1, + .hash_type = BOOT_HASH_TYPE_SHA256, + .key_type = BOOT_KEY_TYPE_RSA2048, + .key_len = KEY_LEN, + .sig_len = SIG_LEN, + .build_info_start = ((uint32_t)sys_build_info), + }, + }, + .code_sig_struct = DEFAULT_CODE_SIG, +}; + +#elif defined(SECURE_BOOT) + +struct secure_boot_struct_t { + struct boot_struct_v1_t boot_struct; + struct code_sig_struct_t code_sig_struct; + struct norflash_cfg_struct_t norflash_cfg; +}; + +const struct secure_boot_struct_t BOOT_STRUCT_LOC secure_boot_struct = { + .boot_struct = { + .hdr = { + .magic = ~0UL, + .security = 1, + .hash_type = BOOT_HASH_TYPE_SHA256, + .key_type = BOOT_KEY_TYPE_RSA2048, + .key_len = KEY_LEN, + .sig_len = SIG_LEN, + .build_info_start = DEFAULT_BUILD_INFO, + }, + }, + .code_sig_struct = DEFAULT_CODE_SIG, + .norflash_cfg = DEFAULT_NORFLASH_CFG, +}; + +#else + +const struct boot_hdr_v1_t BOOT_STRUCT_LOC boot_struct = { + .magic = ~0UL, + .security = 0, + .build_info_start = DEFAULT_BUILD_INFO, +}; + +#endif + +#else // !SECURE_BOOT_V1 + +#ifdef PROGRAMMER + +union programmer_boot_struct_t { + // To keep compatible with the old download tools when downloadig non-secure images + struct { + struct boot_struct_v1_t dummy; + struct code_sig_struct_t code_sig_struct; + } s_v1; + struct { + struct boot_struct_t boot_struct; + struct code_sig_struct_t code_sig_struct; + } s; +}; + +const union programmer_boot_struct_t BOOT_STRUCT_LOC programmer_boot_struct = { + .s = { + .boot_struct = { + .hdr = { + .magic = BOOT_MAGIC_NUMBER, + .security = 1, + .version = BOOT_STRUCT_VERSION, + .build_info_start = ((uint32_t)sys_build_info), + }, + }, + .code_sig_struct = DEFAULT_CODE_SIG, + }, +}; + +#elif defined(SECURE_BOOT) + +struct secure_boot_struct_t { + struct boot_struct_t boot_struct; + struct code_sig_struct_t code_sig_struct; + struct norflash_cfg_struct_t norflash_cfg; +}; + +const struct secure_boot_struct_t BOOT_STRUCT_LOC secure_boot_struct = { + .boot_struct = { + .hdr = { + .magic = ~0UL, + .security = 1, + .version = BOOT_STRUCT_VERSION, + .build_info_start = DEFAULT_BUILD_INFO, + }, + }, + .code_sig_struct = DEFAULT_CODE_SIG, + .norflash_cfg = DEFAULT_NORFLASH_CFG, +}; + +#else + +const struct boot_hdr_t BOOT_STRUCT_LOC boot_struct = { + .magic = ~0UL, + .security = 0, + .version = BOOT_STRUCT_VERSION, + .build_info_start = DEFAULT_BUILD_INFO, +}; + +#endif + +#endif // !SECURE_BOOT_V1 + +// ----------------------------------------------------------- +// Reboot param +// ----------------------------------------------------------- + +#ifdef __ARMCC_VERSION +#define REBOOT_PARAM_LOC __attribute((section(".bss.reboot_param"))) +#else +#define REBOOT_PARAM_LOC __attribute((section(".reboot_param"))) +#endif + +struct REBOOT_PARAM_T REBOOT_PARAM_LOC reboot_param; + diff --git a/utils/boot_struct/norflash_cfg.h b/utils/boot_struct/norflash_cfg.h new file mode 100644 index 0000000..50d6bcd --- /dev/null +++ b/utils/boot_struct/norflash_cfg.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __NORFLASH_CFG_H__ +#define __NORFLASH_CFG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "plat_types.h" + +#define STATUS_S10_LB_BIT_SHIFT 2 +#define STATUS_S10_LB_BIT_MASK (1 << STATUS_S10_LB_BIT_SHIFT) + +#define STATUS_S11_LB1_BIT_SHIFT 3 +#define STATUS_S11_LB1_BIT_MASK (1 << STATUS_S11_LB1_BIT_SHIFT) + +enum SEC_REG_BASE_T { + SEC_REG_BASE_0X1000, + SEC_REG_BASE_0X0000, +}; + +enum SEC_REG_SIZE_T { + SEC_REG_SIZE_1024, + SEC_REG_SIZE_512, + SEC_REG_SIZE_256, +}; + +enum SEC_REG_OFFSET_T { + SEC_REG_OFFSET_0X1000, + SEC_REG_OFFSET_0X0100, +}; + +enum SEC_REG_CNT_T { + SEC_REG_CNT_3, + SEC_REG_CNT_4, +}; + +enum SEC_REG_PP_T { + SEC_REG_PP_256, + SEC_REG_PP_1024, +}; + +enum SEC_REG_LB_T { + SEC_REG_LB_S11_S13, + SEC_REG_LB_S10, +}; + +struct norflash_cfg_struct_t { + uint8_t neg_phase:1; + uint8_t pos_neg:1; + uint8_t cmdquad:1; + uint8_t samdly:3; + + uint8_t div; /* least 2 */ + + uint8_t dualmode:1; + uint8_t holdpin:1; + uint8_t wprpin:1; + uint8_t quadmode:1; + uint8_t mod_clk:4; + + uint8_t spiruen:3; + uint8_t spirden:3; + + uint8_t dualiocmd; + uint8_t rdcmd; + uint8_t frdcmd; + uint8_t qrdcmd; /* quad io cmd */ +}; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/utils/boot_struct/reboot_param.h b/utils/boot_struct/reboot_param.h new file mode 100644 index 0000000..0f51705 --- /dev/null +++ b/utils/boot_struct/reboot_param.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __REBOOT_PARAM_H__ +#define __REBOOT_PARAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" + +struct REBOOT_PARAM_T { + uint32_t reserved[4]; +}; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/utils/boot_struct/tool_msg.h b/utils/boot_struct/tool_msg.h new file mode 100644 index 0000000..faf2b7f --- /dev/null +++ b/utils/boot_struct/tool_msg.h @@ -0,0 +1,265 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __TOOL_MSG_H__ +#define __TOOL_MSG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOOT_MAGIC_NUMBER 0xBE57EC1C +#define BOOT_HASH_TYPE_MD5 1 +#define BOOT_HASH_TYPE_SHA256 2 +#define BOOT_KEY_TYPE_RSA2048 1 +#define BOOT_KEY_TYPE_ECDSA192 2 +#define BOOT_KEY_TYPE_ECDSA256 3 + +#define SEC_KEY_VERSION 0 +#define BOOT_STRUCT_VERSION 0 + +#define PREFIX_CHAR 0xBE + +#define KEY_LEN (4 + 256 + 256) +#define SIG_LEN 256 +#define HASH_LEN 32 + +#ifndef MAX_TOOL_MSG_DATA_LEN +// Max msg: flash cmd msg with 4-byte address and 16-byte data (1 + 4 + 16) +#define MAX_TOOL_MSG_DATA_LEN 21 +#endif + +#define MAX_READ_DATA_LEN 16 +#define MAX_WRITE_DATA_LEN 16 +#define MAX_FLASH_CMD_DATA_LEN 16 + +#define MIN_SIGNED_CODE_SIZE 32 + +#ifdef SECURE_BOOT_V1 +#define BOOT_STRUCT_V1_OFFSET_TO_SIGN(b) \ + ((unsigned char *)&((struct boot_struct_v1_t *)(b))->hdr.security) +#define BOOT_STRUCT_V1_LEN_TO_SIGN \ + ((unsigned long)&((struct boot_struct_v1_t *)0)->sig[0] - \ + (unsigned long)&((struct boot_struct_v1_t *)0)->hdr.security) +#endif + +#define SEC_KEY_OFFSET_TO_HASH(b) \ + ((unsigned char *)&((struct sec_key_struct_t *)(b))->version) +#define SEC_KEY_LEN_TO_HASH \ + ((unsigned long)&((struct sec_key_struct_t *)0)->hash[0] - \ + (unsigned long)&((struct sec_key_struct_t *)0)->version) + +#define SIG_MSG_OVERHEAD 8 +#define SIG_MSG_V1_EXTRA_DATA_LEN (sizeof(struct boot_struct_v1_t) + sizeof(struct code_sig_struct_t)) +#define SIG_MSG_V1_TOTAL_LEN (SIG_MSG_OVERHEAD + SIG_MSG_V1_EXTRA_DATA_LEN) +#define SIG_MSG_EXTRA_DATA_LEN (sizeof(struct boot_struct_t) + sizeof(struct code_sig_struct_t)) +#define SIG_MSG_TOTAL_LEN (SIG_MSG_OVERHEAD + SIG_MSG_EXTRA_DATA_LEN) + +#define CODE_MSG_OVERHEAD 8 +#define BURN_DATA_MSG_OVERHEAD 16 + +#define SECTOR_SIZE_64K (1 << 16) +#define SECTOR_SIZE_32K (1 << 15) +#define SECTOR_SIZE_16K (1 << 14) +#define SECTOR_SIZE_4K (1 << 12) + +#define MSG_TOTAL_LEN(msg) (sizeof(struct msg_hdr_t) + ((struct msg_hdr_t *)(msg))->len + 1) + +enum MSG_TYPE { + TYPE_SYS = 0x00, + TYPE_READ = 0x01, + TYPE_WRITE = 0x02, + TYPE_BULK_READ = 0x03, +#if defined(TEST_OVER_THE_AIR_ENANBLED) + TYPE_EXT_WRITE = 0x04, + TYPE_BULK_WRITE_START = 0x05, + TYPE_BULK_WRITE_DATA = 0x06, +#endif + TYPE_NOTIF = 0x10, + TYPE_SYNC = 0x50, + TYPE_SIG_INFO = 0x51, + TYPE_SIG = 0x52, + TYPE_CODE_INFO = 0x53, + TYPE_CODE = 0x54, + TYPE_RUN = 0x55, + TYPE_SECTOR_SIZE = 0x60, + TYPE_ERASE_BURN_START = 0x61, + TYPE_ERASE_BURN_DATA = 0x62, + TYPE_OBSOLETED_63 = 0x63, + TYPE_OBSOLETED_64 = 0x64, + TYPE_FLASH_CMD = 0x65, + TYPE_GET_SECTOR_INFO = 0x66, + TYPE_SEC_REG_ERASE_BURN_START = 0x67, + TYPE_SEC_REG_ERASE_BURN_DATA = 0x68, + + // Extended types + TYPE_PROD_TEST = 0x81, + TYPE_RUNTIME_CMD = 0x82, + TYPE_BT_CALIB_CMD = 0x83, + TYPE_PROTO_EL = 0xA0, + + TYPE_INVALID = 0xFF, +}; + +enum SYS_CMD_TYPE { + SYS_CMD_REBOOT = 0xF1, + SYS_CMD_SHUTDOWN = 0xF2, + SYS_CMD_FLASH_BOOT = 0xF3, + SYS_CMD_SET_BOOTMODE = 0xE1, + SYS_CMD_CLR_BOOTMODE = 0xE2, + SYS_CMD_GET_BOOTMODE = 0xE3, + SYS_CMD_SET_DLD_RATE = 0xD1, +}; + +enum ERR_CODE { + ERR_NONE = 0x00, + ERR_LEN = 0x01, + ERR_CHECKSUM = 0x02, + ERR_NOT_SYNC = 0x03, + ERR_NOT_SEC = 0x04, + ERR_SYNC_WORD = 0x05, + ERR_SYS_CMD = 0x06, + ERR_DATA_ADDR = 0x07, + ERR_DATA_LEN = 0x08, + ERR_ACCESS_RIGHT = 0x09, + + ERR_TYPE_INVALID = 0x0F, + + //ERR_BOOT_OK = 0x10, + ERR_BOOT_MAGIC = 0x11, + ERR_BOOT_SEC = 0x12, + ERR_BOOT_HASH_TYPE = 0x13, + ERR_BOOT_KEY_TYPE = 0x14, + ERR_BOOT_KEY_LEN = 0x15, + ERR_BOOT_SIG_LEN = 0x16, + ERR_BOOT_SIG = 0x17, + ERR_BOOT_CRC = 0x18, + ERR_BOOT_LEN = 0x19, + ERR_SIG_CODE_SIZE = 0x1A, + ERR_SIG_SIG_LEN = 0x1B, + ERR_SIG_INFO_MISSING = 0x1C, + ERR_BOOT_KEY_ID = 0x1D, + ERR_BOOT_HASH = 0x1E, + + ERR_CODE_OK = 0x20, + ERR_BOOT_MISSING = 0x21, + ERR_CODE_SIZE_SIG = 0x22, + ERR_CODE_ADDR_SIZE = 0x23, + ERR_CODE_INFO_MISSING = 0x24, + ERR_CODE_CRC = 0x25, + ERR_CODE_SIG = 0x26, + + ERR_CODE_MISSING = 0x31, + ERR_VERSION = 0x32, + + ERR_BURN_OK = 0x60, + ERR_SECTOR_SIZE = 0x61, + ERR_SECTOR_SEQ_OVERFLOW = 0x62, + ERR_BURN_INFO_MISSING = 0x63, + ERR_SECTOR_DATA_LEN = 0x64, + ERR_SECTOR_DATA_CRC = 0x65, + ERR_SECTOR_SEQ = 0x66, + ERR_ERASE_FLSH = 0x67, + ERR_BURN_FLSH = 0x68, + ERR_VERIFY_FLSH = 0x69, + ERR_FLASH_CMD = 0x6A, + + ERR_TYPE_MISMATCHED = 0xE1, + ERR_SEQ_MISMATCHED = 0xE2, + ERR_BUF_TOO_SMALL = 0xE3, + + ERR_INTERNAL = 0xFF, +}; + +enum PARSE_STATE { + PARSE_HEADER, + PARSE_DATA, + PARSE_EXTRA, +}; + +struct msg_hdr_t { + unsigned char prefix; + unsigned char type; + unsigned char seq; + unsigned char len; +}; + +struct message_t { + struct msg_hdr_t hdr; + // data and 1-byte check_sum + unsigned char data[MAX_TOOL_MSG_DATA_LEN + 1]; +}; + +struct sec_key_struct_t { + unsigned int magic; + unsigned short version; + unsigned char hash_type; + unsigned char key_type; + unsigned short key_len; + unsigned short sig_len; + unsigned int reserved[5]; + unsigned char key[KEY_LEN]; + unsigned char hash[HASH_LEN]; +}; + +struct boot_hdr_v1_t { + unsigned int magic; + unsigned short security; + unsigned char hash_type; + unsigned char key_type; + unsigned short key_len; + unsigned short sig_len; + unsigned int build_info_start; +}; + +struct boot_struct_v1_t { + struct boot_hdr_v1_t hdr; + unsigned char key[KEY_LEN]; + unsigned char sig[SIG_LEN]; +}; + +struct boot_hdr_t { + unsigned int magic; + unsigned short security; + unsigned short version; + unsigned int reserved; + unsigned int build_info_start; +}; + +struct boot_struct_t { + struct boot_hdr_t hdr; + unsigned int reserved[4]; +}; + +struct code_sig_struct_t { + unsigned int code_size; + unsigned short sig_len; + unsigned short reserved; + unsigned char sig[SIG_LEN]; +}; + +struct exec_struct_t { + unsigned int entry; + unsigned int param; + unsigned int sp; + unsigned int exec_addr; +}; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/utils/build_info/build_info.c b/utils/build_info/build_info.c new file mode 100644 index 0000000..60d47a1 --- /dev/null +++ b/utils/build_info/build_info.c @@ -0,0 +1,67 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_addr_map.h" + +#define BUILD_INFO_LOCATION __attribute__((section(".build_info"))) + +#define TO_STR_A(s) # s +#define TO_STR(s) TO_STR_A(s) + +#ifdef TRACE_CRLF +#define NEW_LINE_STR "\r\n" +#else +#define NEW_LINE_STR "\n" +#endif + +const char BUILD_INFO_LOCATION sys_build_info[] = +#if defined(ROM_BUILD) || defined(PROGRAMMER) + __DATE__ " " __TIME__ " " TO_STR(REVISION_INFO); +#else + NEW_LINE_STR "CHIP=" TO_STR(CHIP) +#ifdef CHIP_SUBTYPE + NEW_LINE_STR "CHIP_SUBTYPE=" TO_STR(CHIP_SUBTYPE) +#endif + NEW_LINE_STR "KERNEL=" TO_STR(KERNEL) +#ifdef SOFTWARE_VERSION + NEW_LINE_STR "SW_VER=" TO_STR(SOFTWARE_VERSION) +#endif +#ifdef OTA_BOOT_SIZE + NEW_LINE_STR "SW_TYPE=OTA" + NEW_LINE_STR "OTA_BOOT_SIZE=" TO_STR(OTA_BOOT_SIZE) +#else + NEW_LINE_STR "CRASH_DUMP_SIZE=" TO_STR(CRASH_DUMP_SECTION_SIZE) + NEW_LINE_STR "AUD_SEC_SIZE=" TO_STR(AUD_SECTION_SIZE) + NEW_LINE_STR "USER_SEC_SIZE=" TO_STR(USERDATA_SECTION_SIZE) + NEW_LINE_STR "FACT_SEC_SIZE=" TO_STR(FACTORY_SECTION_SIZE) + NEW_LINE_STR "NV_REC_DEV_VER=" TO_STR(NV_REC_DEV_VER) +#endif + NEW_LINE_STR "FLASH_BASE=" TO_STR(FLASH_NC_BASE) + NEW_LINE_STR "FLASH_SIZE=" TO_STR(FLASH_SIZE) +#ifdef OTA_CODE_OFFSET + NEW_LINE_STR "OTA_CODE_OFFSET=" TO_STR(OTA_CODE_OFFSET) +#endif +#ifdef OTA_REMAP_OFFSET + NEW_LINE_STR "OTA_REMAP_OFFSET=" TO_STR(OTA_REMAP_OFFSET) +#endif + NEW_LINE_STR "CRC32_OF_IMAGE=0x00000000" + //-------------------- + // Add new items above + //-------------------- + NEW_LINE_STR "BUILD_DATE=" __DATE__ " " __TIME__ + NEW_LINE_STR "REV_INFO=" TO_STR(REVISION_INFO) + NEW_LINE_STR; +#endif + diff --git a/utils/cqueue/Makefile b/utils/cqueue/Makefile new file mode 100644 index 0000000..0cbb33d --- /dev/null +++ b/utils/cqueue/Makefile @@ -0,0 +1,17 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -Iplatform/cmsis/inc/ \ + +ifeq ($(ROM_UTILS_ON),1) +ccflags-y += -DCQ_FUNC_ATTR=WEAK +else +ccflags-y += -DCQ_FUNC_ATTR= +endif + diff --git a/utils/cqueue/cqueue.c b/utils/cqueue/cqueue.c new file mode 100644 index 0000000..da0e0f1 --- /dev/null +++ b/utils/cqueue/cqueue.c @@ -0,0 +1,420 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/*** +* cqueue.c - c circle queue c file +*/ + +#include "cqueue.h" +#include +#include "cmsis.h" +#include "hal_uart.h" +#include + +//#define DEBUG_CQUEUE 1 + +CQ_FUNC_ATTR +int InitCQueue(CQueue *Q, unsigned int size, CQItemType *buf) +{ + Q->size = size; + Q->base = buf; + Q->len = 0; + if (!Q->base) + return CQ_ERR; + + Q->read = Q->write = 0; + return CQ_OK; +} + +CQ_FUNC_ATTR +int IsEmptyCQueue(CQueue *Q) +{ + if (Q->len == 0) + return CQ_OK; + else + return CQ_ERR; +} + +CQ_FUNC_ATTR +int LengthOfCQueue(CQueue *Q) +{ + return Q->len; +} + +CQ_FUNC_ATTR +int AvailableOfCQueue(CQueue *Q) +{ + return (Q->size - Q->len); +} + +#if 1 +CQ_FUNC_ATTR +int EnCQueue(CQueue *Q, CQItemType *e, unsigned int len) +{ + if (AvailableOfCQueue(Q) < len) { + return CQ_ERR; + } + + Q->len += len; + + uint32_t bytesToTheEnd = Q->size - Q->write; + if (bytesToTheEnd > len) + { + memcpy((uint8_t *)&Q->base[Q->write], (uint8_t *)e, len); + Q->write += len; + } + else + { + memcpy((uint8_t *)&Q->base[Q->write], (uint8_t *)e, bytesToTheEnd); + memcpy((uint8_t *)&Q->base[0], (((uint8_t *)e)+bytesToTheEnd), len-bytesToTheEnd); + Q->write = len-bytesToTheEnd; + } + + return CQ_OK; +} + + +int EnCQueue_AI(CQueue *Q, CQItemType *e, unsigned int len) +{ + uint32_t bytesToTheEnd = Q->size - Q->write; + uint32_t readBytesToTheEnd = Q->size - Q->read; + + if(AvailableOfCQueue(Q) < len) { + if(readBytesToTheEnd > len) { + Q->read += len; + } else { + Q->read = len - readBytesToTheEnd; + } + } else { + Q->len += len; + } + + if (bytesToTheEnd > len) { + memcpy((uint8_t *)&Q->base[Q->write], (uint8_t *)e, len); + Q->write += len; + } else { + memcpy((uint8_t *)&Q->base[Q->write], (uint8_t *)e, bytesToTheEnd); + memcpy((uint8_t *)&Q->base[0], (((uint8_t *)e)+bytesToTheEnd), len-bytesToTheEnd); + Q->write = len-bytesToTheEnd; + } + + return CQ_OK; +} + +#else +static inline void memcpy_u8(void *dst, void *src, unsigned int len) +{ + unsigned int i = 0; + unsigned int *d8, *s8; + d8 = dst; + s8 = src; + for(i=0;i < len;i++) + d8[i] = s8[i]; +} + +static inline void memcpy_u32(void *dst, void *src, unsigned int len) +{ + unsigned int i = 0; + unsigned int *d32, *s32; + d32 = dst; + s32 = src; + for(i = 0;i < len;i++) + d32[i] = s32[i]; +} + +CQ_FUNC_ATTR +int EnCQueue(CQueue *Q, CQItemType *e, unsigned int len) +{ + unsigned char *src = e; + unsigned char *dst = &(Q->base[Q->write]); + + unsigned int cnt_u8; + unsigned int cnt_u32; + unsigned int cnt_u32_res; + + unsigned int front_u8; + unsigned int front_u32; + unsigned int front_u32_res; + + unsigned int end_u8; + unsigned int end_u32; + unsigned int end_u32_res; + + bool unaligned_en; + + if (AvailableOfCQueue(Q) < len) { + return CQ_ERR; + } + + Q->len += len; + + end_u8 = Q->size - Q->write; + end_u32 = end_u8 / 4; + end_u32_res = end_u8 % 4; + + cnt_u8 = len; + cnt_u32 = cnt_u8 / 4; + cnt_u32_res = cnt_u8 % 4; + + unaligned_en = config_unaligned_access(true); + + if(cnt_u8 <= end_u8) + { + memcpy_u32(dst, src, cnt_u32); + + if(cnt_u32_res) + { + src += cnt_u32 * 4; + dst += cnt_u32 * 4; + memcpy_u8(dst, src, cnt_u32_res); + } + + // Deal with Q->write + Q->write += cnt_u8; + + } + else + { + front_u8 = len - end_u8; + front_u32 = front_u8 / 4; + front_u32_res = front_u8 % 4; + + // Deal with end data + memcpy_u32(dst, src, end_u32); + src += end_u32 * 4; + dst += end_u32 * 4; + + memcpy_u8(dst, src, end_u32_res); + src += end_u32_res; + dst = &(Q->base[0]); + + // Deal with front data + memcpy_u32(dst, src, front_u32); + + if(front_u32_res) + { + src += front_u32 * 4; + dst += front_u32 * 4; + + memcpy_u8(dst, src, front_u32_res); + } + + // Deal with Q->write + Q->write = front_u8; + } + + config_unaligned_access(unaligned_en); + + return CQ_OK; +} + +void memcpy_fast(char *dst, char *src, unsigned int len) +{ + int size = len/4; + int mod = len%4; + + int *Dst = (int *)dst; + int *Src = (int *)src; + + int dst_offset = (int)Dst - (int)dst; + int src_offset = (int)Src -(int)src; + + if(!dst_offset && !src_offset){ + memcpy_u32(Dst, Src, size); + if(mod){ + memcpy_u8(Dst + size, Src + size, mod); + } + }else{ + memcpy_u8(dst, src, len); + } +} + +#endif + +CQ_FUNC_ATTR +int EnCQueueFront(CQueue *Q, CQItemType *e, unsigned int len) +{ + if (AvailableOfCQueue(Q) < len) { + return CQ_ERR; + } + + Q->len += len; + + /* walk to last item , revert write */ + e = e + len - 1; + + if(Q->read == 0) + Q->read = Q->size - 1; + else + Q->read--; + + while(len > 0) { + Q->base[Q->read] = *e; + + --Q->read; + --e; + --len; + + if(Q->read < 0) + Q->read = Q->size - 1; + } + + /* we walk one more, walk back */ + if(Q->read == Q->size - 1) + Q->read = 0; + else + ++Q->read; + + return CQ_OK; +} + +CQ_FUNC_ATTR +int DeCQueue(CQueue *Q, CQItemType *e, unsigned int len) +{ + if(LengthOfCQueue(Q) < len) + return CQ_ERR; + + Q->len -= len; + + if(e != NULL) + { + uint32_t bytesToTheEnd = Q->size - Q->read; + if (bytesToTheEnd > len) + { + memcpy((uint8_t *)e, (uint8_t *)&Q->base[Q->read], len); + Q->read += len; + } + else + { + memcpy((uint8_t *)e, (uint8_t *)&Q->base[Q->read], bytesToTheEnd); + memcpy((((uint8_t *)e)+bytesToTheEnd), (uint8_t *)&Q->base[0], len-bytesToTheEnd); + Q->read = len-bytesToTheEnd; + } + } + else + { + if (0 < Q->size) + { + Q->read = (Q->read+len)%Q->size; + } + else + { + Q->read = 0; + } + } + + return CQ_OK; +} + +CQ_FUNC_ATTR +int PeekCQueue(CQueue *Q, unsigned int len_want, CQItemType **e1, unsigned int *len1, CQItemType **e2, unsigned int *len2) +{ + if(LengthOfCQueue(Q) < len_want) { + return CQ_ERR; + } + + *e1 = &(Q->base[Q->read]); + if((Q->write > Q->read) || (Q->size - Q->read >= len_want)) { + *len1 = len_want; + *e2 = NULL; + *len2 = 0; + return CQ_OK; + } + else { + *len1 = Q->size - Q->read; + *e2 = &(Q->base[0]); + *len2 = len_want - *len1; + return CQ_OK; + } + + return CQ_ERR; +} + +int PeekCQueueToBuf(CQueue *Q, CQItemType *e, unsigned int len) +{ + int status = CQ_OK; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + + status = PeekCQueue(Q, len, &e1, &len1, &e2, &len2); + + if(status == CQ_OK) { + if (len == (len1 + len2)) { + memcpy(e, e1, len1); + memcpy(e + len1, e2, len2); + } else { + status = CQ_ERR; + } + } + + return status; +} + +int PullCQueue(CQueue *Q, CQItemType *e, unsigned int len) +{ + int status = CQ_OK; + unsigned char *e1 = NULL, *e2 = NULL; + unsigned int len1 = 0, len2 = 0; + + status = PeekCQueue(Q, len, &e1, &len1, &e2, &len2); + + if(status == CQ_OK){ + if (len == (len1 + len2)){ + memcpy(e, e1, len1); + memcpy(e + len1, e2, len2); + DeCQueue(Q, 0, len); + }else{ + status = CQ_ERR; + } + } + + return status; +} + +#ifdef DEBUG_CQUEUE +int DumpCQueue(CQueue *Q) +{ + CQItemType e; + int len = 0, i = 0; + + len = LengthOfCQueue(Q); + + if(len <= 0) + return CQ_ERR; + + i = Q->read; + while(len > 0) { + e = Q->base[i]; + + TRACE(stderr, "-0x%x", e); + TRACE(stderr, "-%c", e); + + ++i; + --len; + if(i == Q->size) + i = 0; + } + + return CQ_ERR; +} +#endif + +void ResetCQueue(CQueue *Q) +{ + Q->len = 0; + Q->read = Q->write = 0; +} + + diff --git a/utils/cqueue/cqueue.h b/utils/cqueue/cqueue.h new file mode 100644 index 0000000..efec1a7 --- /dev/null +++ b/utils/cqueue/cqueue.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/*** +* cqueue.h - c circle queue c header +*/ + +#ifndef C_QUEUE_H +#define C_QUEUE_H 1 + +#if defined(__cplusplus) +extern "C" { +#endif + +enum { + CQ_OK = 0, + CQ_ERR, +}; + +typedef unsigned char CQItemType; + +typedef struct __CQueue +{ + int read; + int write; + int size; + int len; + CQItemType *base; +}CQueue; + +/* Init Queue */ +int InitCQueue(CQueue *Q, unsigned int size, CQItemType *buf); +/* Is Queue Empty */ +int IsEmptyCQueue(CQueue *Q); +/* Filled Length Of Queue */ +int LengthOfCQueue(CQueue *Q); +/* Empty Length Of Queue */ +int AvailableOfCQueue(CQueue *Q); +/* Push Data Into Queue (Tail) */ +int EnCQueue(CQueue *Q, CQItemType *e, unsigned int len); +/* Push Data Into Queue (Tail) */ +int EnCQueue_AI(CQueue *Q, CQItemType *e, unsigned int len); +/* Push Data Into Front Of Queue */ +int EnCQueueFront(CQueue *Q, CQItemType *e, unsigned int len); +/* Pop Data Data From Queue (Front) */ +int DeCQueue(CQueue *Q, CQItemType *e, unsigned int len); +/* Peek But Not Pop Data From Queue (Front) */ +int PeekCQueue(CQueue *Q, unsigned int len_want, CQItemType **e1, unsigned int *len1, CQItemType **e2, unsigned int *len2); +/* Peek data to buf e, But Not Pop Data From Queue (Front) */ +int PeekCQueueToBuf(CQueue *Q, CQItemType *e, unsigned int len); +int PullCQueue(CQueue *Q, CQItemType *e, unsigned int len); +/* Dump Queue */ +int DumpCQueue(CQueue *Q); + +void ResetCQueue(CQueue *Q); + +#if defined(__cplusplus) +} +#endif + +#endif /* C_QUEUE_H */ diff --git a/utils/crash_catcher/CrashCatcher.c b/utils/crash_catcher/CrashCatcher.c new file mode 100644 index 0000000..f9b9014 --- /dev/null +++ b/utils/crash_catcher/CrashCatcher.c @@ -0,0 +1,405 @@ +/* Copyright (C) 2018 Adam Green (https://github.com/adamgreen) + + 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. +*/ +#include +#include "CrashCatcherPriv.h" +#include +//#include "cmsis_os.h" +#include "cmsis_nvic.h" + + +/* Test harness will define this value on 64-bit machine to provide upper 32-bits of pointer addresses. */ +CRASH_CATCHER_TEST_WRITEABLE uint64_t g_crashCatcherTestBaseAddress; + +/* The unit tests can point the core to a fake location for the SCB->CPUID register. */ +CRASH_CATCHER_TEST_WRITEABLE uint32_t* g_pCrashCatcherCpuId = (uint32_t*)0xE000ED00; + +/* The unit tests can point the core to a fake location for the fault status registers. */ +CRASH_CATCHER_TEST_WRITEABLE uint32_t* g_pCrashCatcherFaultStatusRegisters = (uint32_t*)0xE000ED28; + +/* The unit tests can point the core to a fake location for the Coprocessor Access Control Register. */ +CRASH_CATCHER_TEST_WRITEABLE uint32_t* g_pCrashCatcherCoprocessorAccessControlRegister = (uint32_t*)0xE000ED88; + + +/* Fault handler will switch MSP to use this area as the stack while CrashCatcher code is running. + NOTE: If you change the size of this buffer, it also needs to be changed in the HardFault_Handler (in + FaultHandler_arm*.S) when initializing the stack pointer. */ +uint32_t g_crashCatcherStack[CRASH_CATCHER_STACK_WORD_COUNT]; + + +typedef struct +{ + const CrashCatcherExceptionRegisters* pExceptionRegisters; + CrashCatcherStackedRegisters* pSP; + uint32_t flags; + CrashCatcherInfo info; +} Object; + + +static Object initStackPointers(const CrashCatcherExceptionRegisters* pExceptionRegisters); +static uint32_t getAddressOfExceptionStack(const CrashCatcherExceptionRegisters* pExceptionRegisters); +static void* uint32AddressToPointer(uint32_t address); +static void advanceStackPointerToValueBeforeException(Object* pObject); +static int areFloatingPointRegistersAutoStacked(const Object* pObject); +static void initFloatingPointFlag(Object* pObject); +static int areFloatingPointCoprocessorsEnabled(void); +static void initIsBKPT(Object* pObject); +static int isBKPT(uint16_t instruction); +static void setStackSentinel(void); +static void dumpSignature(void); +static void dumpFlags(const Object* pObject); +static void dumpR0toR3(const Object* pObject); +static void dumpR4toR11(const Object* pObject); +static void dumpR12(const Object* pObject); +static void dumpSP(const Object* pObject); +static void dumpLR_PC_PSR(const Object* pObject); +static void dumpMSPandPSPandExceptionPSR(const Object* pObject); +static void dumpFloatingPointRegisters(const Object* pObject); +static void dumpMemoryRegions(const CrashCatcherMemoryRegion* pRegion); +static void checkStackSentinelForStackOverflow(void); +static int isARMv6MDevice(void); +static void dumpFaultStatusRegisters(void); +static void advanceProgramCounterPastHardcodedBreakpoint(const Object* pObject); +static void dumpMSPandPSPandExceptionPSRinAssert(const Object* pObject); + +struct TaskRegs { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t r12; + uint32_t sp; + uint32_t lr; + uint32_t pc; + uint32_t psr; +}; +static void dumpTaskRegs(const struct TaskRegs *regs); + +void AssertCatcher_Entry(void) +{ + register uint32_t r0 asm("r0"); + register uint32_t r1 asm("r1"); + register uint32_t r2 asm("r2"); + register uint32_t r3 asm("r3"); + register uint32_t r4 asm("r4"); + register uint32_t r5 asm("r5"); + register uint32_t r6 asm("r6"); + register uint32_t r7 asm("r7"); + register uint32_t r8 asm("r8"); + register uint32_t r9 asm("r9"); + register uint32_t r10 asm("r10"); + register uint32_t r11 asm("r11"); + register uint32_t r12 asm("r12"); + register uint32_t sp asm("sp"); + register uint32_t lr asm("lr"); + uint32_t pc; + struct TaskRegs regs; + +#ifdef __ARMCC_VERSION + asm volatile ("" : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), "=r"(r7), + "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11), "=r"(r12), "=r"(sp), "=r"(lr)); +#endif + + regs.r0 = r0; + regs.r1 = r1; + regs.r2 = r2; + regs.r3 = r3; + regs.r4 = r4; + regs.r5 = r5; + regs.r6 = r6; + regs.r7 = r7; + regs.r8 = r8; + regs.r9 = r9; + regs.r10 = r10; + regs.r11 = r11; + regs.r12 = r12; + regs.sp = sp; + regs.lr = lr; + __asm volatile ("mov %0, r15" : "=r" (pc)); + regs.psr = __get_xPSR(); + regs.pc = pc; + + int ret; + Object object; + object.flags = 0; + + do + { + ret = CrashCatcher_DumpStart(NULL); + if (ret) + break; + + dumpSignature(); + dumpFlags(&object); + + dumpTaskRegs(®s); + + dumpMSPandPSPandExceptionPSRinAssert(NULL); + /* + if (object.flags & CRASH_CATCHER_FLAGS_FLOATING_POINT) + dumpFloatingPointRegisters(&object); + */ + dumpMemoryRegions(CrashCatcher_GetMemoryRegions()); + if (!isARMv6MDevice()) + dumpFaultStatusRegisters(); + + } + while (CrashCatcher_DumpEnd() == CRASH_CATCHER_TRY_AGAIN); +} + +void CrashCatcher_Entry(const CrashCatcherExceptionRegisters* pExceptionRegisters) +{ + int ret; + Object object = initStackPointers(pExceptionRegisters); + advanceStackPointerToValueBeforeException(&object); + initFloatingPointFlag(&object); + initIsBKPT(&object); + + do + { + setStackSentinel(); + ret = CrashCatcher_DumpStart(&object.info); + if (ret) + break; + + dumpSignature(); + dumpFlags(&object); + dumpR0toR3(&object); + dumpR4toR11(&object); + dumpR12(&object); + dumpSP(&object); + dumpLR_PC_PSR(&object); + dumpMSPandPSPandExceptionPSR(&object); + if (object.flags & CRASH_CATCHER_FLAGS_FLOATING_POINT) + dumpFloatingPointRegisters(&object); + dumpMemoryRegions(CrashCatcher_GetMemoryRegions()); + if (!isARMv6MDevice()) + dumpFaultStatusRegisters(); + checkStackSentinelForStackOverflow(); + } + while (CrashCatcher_DumpEnd() == CRASH_CATCHER_TRY_AGAIN); + + advanceProgramCounterPastHardcodedBreakpoint(&object); +} + +static Object initStackPointers(const CrashCatcherExceptionRegisters* pExceptionRegisters) +{ + Object object; + object.pExceptionRegisters = pExceptionRegisters; + object.info.sp = getAddressOfExceptionStack(pExceptionRegisters); + object.pSP = uint32AddressToPointer(object.info.sp); + object.flags = 0; + return object; +} + +static uint32_t getAddressOfExceptionStack(const CrashCatcherExceptionRegisters* pExceptionRegisters) +{ + /*always return psp */ + return pExceptionRegisters->psp; + /* + if (pExceptionRegisters->exceptionLR & LR_PSP) + return pExceptionRegisters->psp; + else + return pExceptionRegisters->msp; + */ +} + +static void* uint32AddressToPointer(uint32_t address) +{ + if (sizeof(uint32_t*) == 8) + return (void*)(unsigned long)((uint64_t)address | g_crashCatcherTestBaseAddress); + else + return (void*)(unsigned long)address; +} + +static void advanceStackPointerToValueBeforeException(Object* pObject) +{ + /* Cortex-M processor always push 8 integer registers on the stack. */ + pObject->info.sp += 8 * sizeof(uint32_t); + /* ARMv7-M processors can also push 16 single-precision floating point registers, FPSCR and a padding word. */ + if (areFloatingPointRegistersAutoStacked(pObject)) + pObject->info.sp += (16 + 1 + 1) * sizeof(uint32_t); + /* Cortex-M processor may also have had to force 8-byte alignment before auto stacking registers. */ + pObject->info.sp |= (pObject->pSP->psr & PSR_STACK_ALIGN) ? 4 : 0; +} + +static int areFloatingPointRegistersAutoStacked(const Object* pObject) +{ + //return 0 == (pObject->pExceptionRegisters->exceptionLR & LR_FLOAT); + return 0; +} + +static void initFloatingPointFlag(Object* pObject) +{ + if (areFloatingPointCoprocessorsEnabled()) + pObject->flags |= CRASH_CATCHER_FLAGS_FLOATING_POINT; +} + +static int areFloatingPointCoprocessorsEnabled(void) +{ + static const uint32_t coProcessor10and11EnabledBits = 5 << 20; + uint32_t coprocessorAccessControl = *g_pCrashCatcherCoprocessorAccessControlRegister; + + return (coprocessorAccessControl & (coProcessor10and11EnabledBits)) == coProcessor10and11EnabledBits; +} + +static void initIsBKPT(Object* pObject) +{ + const uint16_t* pInstruction = uint32AddressToPointer(pObject->pSP->pc); + + pObject->info.isBKPT = isBKPT(*pInstruction); +} + +static int isBKPT(uint16_t instruction) +{ + return (instruction & 0xFF00) == 0xBE00; +} + +static void setStackSentinel(void) +{ + g_crashCatcherStack[0] = CRASH_CATCHER_STACK_SENTINEL; +} + +static void dumpSignature(void) +{ + static const uint8_t signature[4] = {CRASH_CATCHER_SIGNATURE_BYTE0, + CRASH_CATCHER_SIGNATURE_BYTE1, + CRASH_CATCHER_VERSION_MAJOR, + CRASH_CATCHER_VERSION_MINOR}; + + CrashCatcher_DumpMemory(signature, CRASH_CATCHER_BYTE, sizeof(signature)); +} + +static void dumpFlags(const Object* pObject) +{ + CrashCatcher_DumpMemory(&pObject->flags, CRASH_CATCHER_BYTE, sizeof(pObject->flags)); +} + +static void dumpR0toR3(const Object* pObject) +{ + CrashCatcher_DumpMemory(&pObject->pSP->r0, CRASH_CATCHER_BYTE, 4 * sizeof(uint32_t)); +} + +static void dumpTaskRegs(const struct TaskRegs *regs) +{ + CrashCatcher_DumpMemory(regs, CRASH_CATCHER_BYTE, sizeof(struct TaskRegs)); +} + +static void dumpR4toR11(const Object* pObject) +{ + CrashCatcher_DumpMemory(&pObject->pExceptionRegisters->r4, CRASH_CATCHER_BYTE, (11 - 4 + 1) * sizeof(uint32_t)); +} + +static void dumpR12(const Object* pObject) +{ + CrashCatcher_DumpMemory(&pObject->pSP->r12, CRASH_CATCHER_BYTE, sizeof(uint32_t)); +} + +static void dumpSP(const Object* pObject) +{ + CrashCatcher_DumpMemory(&pObject->info.sp, CRASH_CATCHER_BYTE, sizeof(uint32_t)); +} + +static void dumpLR_PC_PSR(const Object* pObject) +{ + CrashCatcher_DumpMemory(&pObject->pSP->lr, CRASH_CATCHER_BYTE, 3 * sizeof(uint32_t)); +} + +static void dumpMSPandPSPandExceptionPSR(const Object* pObject) +{ + CrashCatcher_DumpMemory(&pObject->pExceptionRegisters->msp, CRASH_CATCHER_BYTE, 3 * sizeof(uint32_t)); +} + +static void dumpMSPandPSPandExceptionPSRinAssert(const Object* pObject) +{ + uint32_t msp = __get_MSP(); + uint32_t psp = __get_PSP(); + uint32_t exceptionPSR = __get_xPSR(); + + CrashCatcher_DumpMemory(&msp, CRASH_CATCHER_BYTE, sizeof(uint32_t)); + CrashCatcher_DumpMemory(&psp, CRASH_CATCHER_BYTE, sizeof(uint32_t)); + CrashCatcher_DumpMemory(&exceptionPSR, CRASH_CATCHER_BYTE, sizeof(uint32_t)); +} + +static void dumpFloatingPointRegisters(const Object* pObject) +{ + uint32_t allFloatingPointRegisters[32 + 1]; + if (areFloatingPointRegistersAutoStacked(pObject)) + { + /* Copy the upper floats first as that will cause a lazy copy of the auto-stacked registers. */ + CrashCatcher_CopyUpperFloatingPointRegisters(&allFloatingPointRegisters[16]); + memcpy(&allFloatingPointRegisters[0], &pObject->pSP->floats, sizeof(pObject->pSP->floats)); + allFloatingPointRegisters[32] = pObject->pSP->fpscr; + } + else + { + CrashCatcher_CopyAllFloatingPointRegisters(allFloatingPointRegisters); + } + CrashCatcher_DumpMemory(allFloatingPointRegisters, CRASH_CATCHER_BYTE, sizeof(allFloatingPointRegisters)); +} + +static void dumpMemoryRegions(const CrashCatcherMemoryRegion* pRegion) +{ + while (pRegion && pRegion->startAddress != 0xFFFFFFFF) + { + /* Just dump the two addresses in pRegion. The element size isn't required. */ + CrashCatcher_DumpMemory(pRegion, CRASH_CATCHER_BYTE, 2 * sizeof(uint32_t)); + CrashCatcher_DumpMemory(uint32AddressToPointer(pRegion->startAddress), + pRegion->elementSize, + (pRegion->endAddress - pRegion->startAddress) / pRegion->elementSize); + pRegion++; + } +} + +static void checkStackSentinelForStackOverflow(void) +{ + if (g_crashCatcherStack[0] != CRASH_CATCHER_STACK_SENTINEL) + { + uint8_t value[4] = {0xAC, 0xCE, 0x55, 0xED}; + CrashCatcher_DumpMemory(value, CRASH_CATCHER_BYTE, sizeof(value)); + } +} + +static int isARMv6MDevice(void) +{ + static const uint32_t armv6mArchitecture = 0xC << 16; + uint32_t cpuId = *g_pCrashCatcherCpuId; + uint32_t architecture = cpuId & (0xF << 16); + + return (architecture == armv6mArchitecture); +} + +static void dumpFaultStatusRegisters(void) +{ + uint32_t faultStatusRegistersAddress = (uint32_t)(unsigned long)g_pCrashCatcherFaultStatusRegisters; + CrashCatcherMemoryRegion faultStatusRegion[] = { {faultStatusRegistersAddress, + faultStatusRegistersAddress + 5 * sizeof(uint32_t), + CRASH_CATCHER_WORD}, + {0xFFFFFFFF, 0xFFFFFFFF, CRASH_CATCHER_BYTE} }; + dumpMemoryRegions(faultStatusRegion); +} + +static void advanceProgramCounterPastHardcodedBreakpoint(const Object* pObject) +{ + if (pObject->info.isBKPT) + pObject->pSP->pc += 2; +} diff --git a/utils/crash_catcher/CrashCatcherPriv.h b/utils/crash_catcher/CrashCatcherPriv.h new file mode 100644 index 0000000..46425c6 --- /dev/null +++ b/utils/crash_catcher/CrashCatcherPriv.h @@ -0,0 +1,77 @@ +/* Copyright (C) 2017 Adam Green (https://github.com/adamgreen) + + 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. +*/ +/* Private header file shared with unit tests. */ +#ifndef _CRASH_CATCHER_PRIV_H_ +#define _CRASH_CATCHER_PRIV_H_ + + +/* Definitions used by assembly language and C code. */ +#define CRASH_CATCHER_STACK_WORD_COUNT 125 + + +/* Definitions only required from C code. */ +#if !__ASSEMBLER__ + +#include +#include "CrashCatcherApi.h" + + +/* Bit in LR to indicate whether PSP was used for automatic stacking of registers during exception entry. */ +#define LR_PSP (1 << 2) + +/* Bit in LR set to 0 when automatic stacking of floating point registers occurs during exception handling. */ +#define LR_FLOAT (1 << 4) + + +/* Bit in auto stacked xPSR which indicates whether stack was force 8-byte aligned. */ +#define PSR_STACK_ALIGN (1 << 9) + + +/* This structure contains the integer registers that are automatically stacked by Cortex-M processor when it enters + an exception handler. */ +typedef struct +{ + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t psr; + /* The following floating point registers are only stacked when the LR_FLOAT bit is set in exceptionLR. */ + uint32_t floats[16]; + uint32_t fpscr; + uint32_t reserved; /* keeps 8-byte alignment */ +} CrashCatcherStackedRegisters; + + +/* This is the area of memory that would normally be used for the stack when running on an actual Cortex-M + processor. Unit tests can write to this buffer to simulate stack overflow. */ +extern uint32_t g_crashCatcherStack[CRASH_CATCHER_STACK_WORD_COUNT]; + + +/* Called from CrashCatcher core to copy all floating point registers to supplied buffer. The supplied buffer must be + large enough to contain 33 32-bit values (S0-S31 & FPCSR). */ +void CrashCatcher_CopyAllFloatingPointRegisters(uint32_t* pBuffer); + +/* Called from CrashCatcher core to copy upper 16 floating point registers to supplied buffer. The supplied buffer must be + large enough to contain 16 32-bit values (S16-S31). */ +void CrashCatcher_CopyUpperFloatingPointRegisters(uint32_t* pBuffer); + +#endif // #if !__ASSEMBLER__ + + +#endif /* _CRASH_CATCHER_PRIV_H_ */ diff --git a/utils/crash_catcher/CrashCatcher_armv7m.S b/utils/crash_catcher/CrashCatcher_armv7m.S new file mode 100644 index 0000000..26d1c2d --- /dev/null +++ b/utils/crash_catcher/CrashCatcher_armv7m.S @@ -0,0 +1,112 @@ +/* Copyright (C) 2018 Adam Green (https://github.com/adamgreen) + + 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. +*/ +#include "CrashCatcherPriv.h" + +/* Implementation of ARMv7-M assembly language code to trap exceptions and call CrashCatcher_Entry(). */ + .text + .syntax unified + + /* Called on Hard Fault exception. Stacks important registers and calls CrashCatcher_Entry(). + + extern "C" void HardFault_Handler(void); + */ + .global gdb_fault_handler + .type gdb_fault_handler, %function + .thumb_func +gdb_fault_handler: + /* Push the following onto the stack (see CrashCatcherExceptionRegisters structure). The g_crashCatcherStack buffer + is reserved for use as the stack while CrashCatcher is running. + exceptionPSR + psp + msp + r4 + r5 + r6 + r7 + r8 + r9 + r10 + r11 + exceptionLR */ + mrs r3, xpsr + mrs r2, psp + mrs r1, msp + ldr sp, =(g_crashCatcherStack + 4 * CRASH_CATCHER_STACK_WORD_COUNT) + push.w {r1-r11,lr} + + // Call CrashCatcher_Entry with first argument pointing to registers that were just stacked. + mov r0, sp + bl CrashCatcher_Entry + + // Only make it back here when CrashCatcher_DumpEnd() returns CRASH_CATCHER_EXIT to indicate that it would like + // execution to be restored back to the faulting code (typically a hard coded breakpoint). + // Restore non-volatile registers and SP to values they had upon entry to fault handler before resuming execution + // at point of fault. + pop.w {r1-r11,lr} + mov sp, r1 + bx lr + + // Let assembler know that we have hit the end of the HardFault_Handler function. + .pool + .size gdb_fault_handler, .-gdb_fault_handler + + + + /* Called from CrashCatcher core to copy all floating point registers to supplied buffer. The supplied buffer must + be large enough to contain 33 32-bit values (S0-S31 & FPSCR). + + void CrashCatcher_CopyAllFloatingPointRegisters(uint32_t* pBuffer); + */ + .global CrashCatcher_CopyAllFloatingPointRegisters + .type CrashCatcher_CopyAllFloatingPointRegisters, %function + .thumb_func +CrashCatcher_CopyAllFloatingPointRegisters: + // Grab a copy of FPSCR before issuing any other FP instructions. + vmrs r1, fpscr + + // Move s0 - s31 to pBuffer. + vstmia.32 r0!, {s0 - s31} + + // Move fpscr to pBuffer. + str r1, [r0] + + // Return to caller. + bx lr + + .pool + .size CrashCatcher_CopyAllFloatingPointRegisters, .-CrashCatcher_CopyAllFloatingPointRegisters + + + + /* Called from CrashCatcher core to copy upper 16 floating point registers to supplied buffer. The supplied buffer + must be large enough to contain 16 32-bit values (S16-S31). + + void CrashCatcher_CopyUpperFloatingPointRegisters(uint32_t* pBuffer); + */ + .global CrashCatcher_CopyUpperFloatingPointRegisters + .type CrashCatcher_CopyUpperFloatingPointRegisters, %function + .thumb_func +CrashCatcher_CopyUpperFloatingPointRegisters: + // Move s16 - s31 to pBuffer. + vstmia.32 r0!, {s16 - s31} + + // Return to caller. + bx lr + + .pool + .size CrashCatcher_CopyUpperFloatingPointRegisters, .-CrashCatcher_CopyUpperFloatingPointRegisters + + + .end diff --git a/utils/crash_catcher/HexDump.c b/utils/crash_catcher/HexDump.c new file mode 100644 index 0000000..b132cb0 --- /dev/null +++ b/utils/crash_catcher/HexDump.c @@ -0,0 +1,244 @@ +/* Copyright (C) 2018 Adam Green (https://github.com/adamgreen) + + 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. +*/ +#include +#include +#include "hal_timer.h" +#include "hal_trace.h" +#include "string.h" +//#include "cmsis_os.h" +#include "coredump_section.h" +#include "xyzmodem.h" + +//CRASH_CATCHER_TEST_WRITEABLE CrashCatcherReturnCodes g_crashCatcherDumpEndReturn = CRASH_CATCHER_TRY_AGAIN; +static void printString(const char *pString); +//static void waitForUserInput(void); +static void dumpBytes(const uint8_t* pMemory, size_t elementCount); +static void dumpByteAsHex(uint8_t byte); +static void dumpHexDigit(uint8_t nibble); +static void dumpHalfwords(const uint16_t* pMemory, size_t elementCount); +static void dumpWords(const uint32_t* pMemory, size_t elementCount); + +void CrashCatcher_putc(char c) +{ + hal_trace_output((const unsigned char *)&c,1); +} + +extern uint32_t __data_start__, __data_end__; +extern uint32_t __bss_start__, __bss_end__; +extern uint32_t __StackLimit, __StackTop; +extern uint32_t __overlay_text_exec_start__; +extern uint32_t __fast_sram_end__; + +const CrashCatcherMemoryRegion* CrashCatcher_GetMemoryRegions(void) +{ + static CrashCatcherMemoryRegion regions[4]; + int j=0; + + regions[j].startAddress = (uint32_t)&__data_start__; + regions[j].endAddress = (uint32_t)&__data_end__; + regions[j].elementSize = CRASH_CATCHER_BYTE; + j++; + + regions[j].startAddress = (uint32_t)&__bss_start__; + regions[j].endAddress = (uint32_t)&__bss_end__; + regions[j].elementSize = CRASH_CATCHER_BYTE; + j++; + + regions[j].startAddress = (uint32_t)&__StackLimit; + regions[j].endAddress = (uint32_t)&__StackTop; + regions[j].elementSize = CRASH_CATCHER_BYTE; + j++; + /* + regions[j].startAddress = (uint32_t)&__overlay_text_exec_start__; + regions[j].endAddress = (uint32_t)&__fast_sram_end__; + regions[j].elementSize = CRASH_CATCHER_BYTE; + j++; + + regions[j].startAddress = 0x0c000000; + regions[j].endAddress = 0x0c0c8000; + regions[j].elementSize = CRASH_CATCHER_BYTE; + j++; + */ + + regions[j].startAddress = 0xFFFFFFFF; + regions[j].endAddress = 0xFFFFFFFF; + regions[j].elementSize = CRASH_CATCHER_BYTE; + return regions; +} + +static enum { + DUMP_TERM, + DUMP_XMODEM, + DUMP_FLASH +} dump_direction = DUMP_TERM; + +int CrashCatcher_DumpStart(const CrashCatcherInfo* pInfo) +{ + int ret; + + printString("\r\n\r\n"); + /* + if (pInfo->isBKPT) + printString("BREAKPOINT"); + else + */ + printString("CRASH"); + printString(" ENCOUNTERED\r\n" + "Enable XMODEM and then press any key to start dump.\r\n"); + //waitForUserInput(); + hal_trace_flush_buffer(); + +#ifdef CORE_DUMP_TO_FLASH + core_dump_erase_section(); + dump_direction = DUMP_FLASH; + return 0; +#endif + + ret = xmodem_start_xfer(120); + if (!ret) { + dump_direction = DUMP_XMODEM; + return 0; + } + + return 0; +} + +static void printString(const char *pString) +{ + while (*pString) + CrashCatcher_putc(*pString++); +} + +#if 0 +static void waitForUserInput(void) +{ + CrashCatcher_getc(); +} +#endif + +void CrashCatcher_DumpMemory(const void* pvMemory, CrashCatcherElementSizes elementSize, size_t elementCount) +{ + switch (elementSize) + { + case CRASH_CATCHER_BYTE: + dumpBytes(pvMemory, elementCount); + break; + case CRASH_CATCHER_HALFWORD: + dumpHalfwords(pvMemory, elementCount); + break; + case CRASH_CATCHER_WORD: + dumpWords(pvMemory, elementCount); + break; + } + printString("\r\n"); + +#ifdef CORE_DUMP_TO_FLASH + if (elementSize * elementCount >= COREDUMP_SECTOR_SIZE) + { + core_dump_write_large(pvMemory, elementSize * elementCount); + } + else + { + core_dump_write(pvMemory, elementSize * elementCount); + } +#endif +} + +static void dumpBytes(const uint8_t* pMemory, size_t elementCount) +{ + size_t i; + + if (dump_direction == DUMP_TERM) { + for (i = 0 ; i < elementCount ; i++) { + /* Only dump 16 bytes to a single line before introducing a line break. */ + if (i != 0 && (i & 0xF) == 0) { + printString("\r\n"); + hal_trace_flush_buffer(); + } + dumpByteAsHex(*pMemory++); + } + } else if (dump_direction == DUMP_XMODEM) { + const uint8_t *buf = pMemory; + int len; + + len = xmodem_send_stream(buf, elementCount, 1); + if (len < 0) { + //printString("#####error"); + } + } +} + +static void dumpByteAsHex(uint8_t byte) +{ + dumpHexDigit(byte >> 4); + dumpHexDigit(byte & 0xF); +} + +static void dumpHexDigit(uint8_t nibble) +{ + static const char hexToASCII[] = "0123456789ABCDEF"; + + assert( nibble < 16 ); + CrashCatcher_putc(hexToASCII[nibble]); +} + +static void dumpHalfwords(const uint16_t* pMemory, size_t elementCount) +{ + size_t i; + for (i = 0 ; i < elementCount ; i++) + { + uint16_t val = *pMemory++; + /* Only dump 8 halfwords to a single line before introducing a line break. */ + if (i != 0 && (i & 0x7) == 0) + printString("\r\n"); + dumpBytes((uint8_t*)&val, sizeof(val)); + } +} + +static void dumpWords(const uint32_t* pMemory, size_t elementCount) +{ + size_t i; + for (i = 0 ; i < elementCount ; i++) + { + uint32_t val = *pMemory++; + /* Only dump 4 words to a single line before introducing a line break. */ + if (i != 0 && (i & 0x3) == 0) { + printString("\r\n"); + } + dumpBytes((uint8_t*)&val, sizeof(val)); + } +} + + +CrashCatcherReturnCodes CrashCatcher_DumpEnd(void) +{ + char end_info[] = "\r\nEnd of dump\r\n"; + + if (dump_direction == DUMP_XMODEM) { + int len = (strlen(end_info) + 1) / 2 * 2; + xmodem_send_stream((const uint8_t *)end_info, len, 0); + xmodem_stop_xfer(); + } else { + printString(end_info); + } + + return CRASH_CATCHER_EXIT; + #if 0 + if (g_crashCatcherDumpEndReturn == CRASH_CATCHER_TRY_AGAIN && g_info.isBKPT) + return CRASH_CATCHER_EXIT; + else + return g_crashCatcherDumpEndReturn; + #endif +} diff --git a/utils/crash_catcher/Makefile b/utils/crash_catcher/Makefile new file mode 100644 index 0000000..76ad201 --- /dev/null +++ b/utils/crash_catcher/Makefile @@ -0,0 +1,16 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_s := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.S)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -Iutils/crash_catcher/include \ + -Iutils/libc/inc \ + -Iplatform/cmsis/inc/ \ + -Iservices/nv_section/log_section \ + -Irtos/rtx/TARGET_CORTEX_M/ \ + -Iutils/xyzmodem/ + diff --git a/utils/crash_catcher/include/CrashCatcher.h b/utils/crash_catcher/include/CrashCatcher.h new file mode 100644 index 0000000..562dbe2 --- /dev/null +++ b/utils/crash_catcher/include/CrashCatcher.h @@ -0,0 +1,158 @@ +/* Copyright (C) 2018 Adam Green (https://github.com/adamgreen) + + 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. +*/ +#ifndef _CRASH_CATCHER_H_ +#define _CRASH_CATCHER_H_ + + +#include +#include + + +#define TRUE 1 +#define FALSE 0 + + +/* The crash dump start with a four byte header. The first two bytes are "cC", the third byte is the major version + number, and the fourth bytes is the minor version number. */ +#define CRASH_CATCHER_SIGNATURE_BYTE0 'c' +#define CRASH_CATCHER_SIGNATURE_BYTE1 'C' +#define CRASH_CATCHER_VERSION_MAJOR 3 +#define CRASH_CATCHER_VERSION_MINOR 0 + +/* The second word of the dump contains flags. These are the allowed flags. */ +/* Flag to indicate that 32 single-precision floating point registers and FPSCR will follow integer registers. */ +#define CRASH_CATCHER_FLAGS_FLOATING_POINT (1 << 0) + + +/* This magic value will be found as the last word in a crash dump if the fault handler overflowed the stack while + generating the crash dump. */ +#define CRASH_CATCHER_STACK_SENTINEL 0xACCE55ED + + +/* Particulars of crash provided to CrashCatcher_DumpStart(). */ +typedef struct +{ + /* The SP, Stack Pointer, contained this value at the time of the fault. */ + uint32_t sp; + /* Was this fault actually just a hardcoded breakpoint from which it is safe to continue. */ + int isBKPT; +} CrashCatcherInfo; + + +/* The crash dump will have one of these entries for each memory region included in the dump file. */ +typedef struct +{ + uint32_t startAddress; + uint32_t endAddress; +} CrashCatcherMemoryRegionInfo; + +/* Supported element sizes to be used with CrashCatcher_DumpMemory calls. */ +typedef enum +{ + CRASH_CATCHER_BYTE = 1, + CRASH_CATCHER_HALFWORD = 2, + CRASH_CATCHER_WORD = 4 +} CrashCatcherElementSizes; + + +/* Codes to be returned from an implementation's CrashCathcer_DumpEnd() handler. */ +typedef enum +{ + /* Crash Catcher should loop around and try dumping again incase user missed it previous time. */ + CRASH_CATCHER_TRY_AGAIN = 0, + /* Crash Catcher should exit and return to caller. This is used during unit testing or if the crash cause was + actually a hardcoded breakpoint that should be logged and then execution continued. */ + CRASH_CATCHER_EXIT +} CrashCatcherReturnCodes; + + +/* An array of these structures is returned from CrashCatcher_GetMemoryRegions() to indicate what regions of memory + should be dumped as part of the crash dump. The last entry should contain a starting address of 0xFFFFFFFF to + indicate that the end of the list has been encountered. */ +typedef struct +{ + /* The first address of the element to be dumped for this region of memory. */ + /* The last region in the array return from CrashCatcher_GetMemoryRegions() must set this to 0xFFFFFFFF */ + uint32_t startAddress; + /* Stop dumping the region once this address is encountered. The dump isn't inclusive of this address. */ + /* It must be greater than startAddress. */ + uint32_t endAddress; + /* This should be set to CRASH_CATCHER_BYTE except for peripheral registers which don't support 8-bit reads. */ + CrashCatcherElementSizes elementSize; +} CrashCatcherMemoryRegion; + + +#ifdef __cplusplus +extern "C" +{ +#endif +/* The following functions must be provided by a specific dumping implementation. The Core CrashCatcher calls these + routines to have an implementation dump the bytes associated with the current crash. */ + +/* Called at the beginning of crash dump. You should provide an implementation which prepares for the dump by opening + a dump file, prompting the user to begin a crash dump, or whatever makes sense for your scenario. */ +int CrashCatcher_DumpStart(const CrashCatcherInfo* pInfo); + +/* Called to obtain an array of regions in memory that should be dumped as part of the crash. This will typically + be all RAM regions that contain volatile data. For some crash scenarios, a user may decide to also add peripheral + registers of interest (ie. dump some ethernet registers when you are encountering crashes in the network stack.) + If NULL is returned from this function, the core will only dump the registers. */ +const CrashCatcherMemoryRegion* CrashCatcher_GetMemoryRegions(void); + +/* Called to dump the next chunk of memory to the dump (this memory may point to register contents which has been copied + to memory by CrashCatcher already. The element size will be 8-bits, 16-bits, or 32-bits. The implementation should + use reads of the specified size since some memory locations may only support the indicated size. */ +void CrashCatcher_DumpMemory(const void* pvMemory, CrashCatcherElementSizes elementSize, size_t elementCount); + +/* Called at the end of crash dump. You should provide an implementation which cleans up at the end of dump. This could + include closing a dump file, blinking LEDs, infinite looping, and/or returning CRASH_CATCHER_TRY_AGAIN if + CrashCatcher should prepare to dump again incase user missed the first attempt. */ +CrashCatcherReturnCodes CrashCatcher_DumpEnd(void); + + +/* The following functions must be provided by a hex dumping implementation. Such implementations will also have to + implement the core CrashCatcher_GetMemoryRegions() API as well. The HexDump version of CrashCatcher calls these + routines to have an implementation query the user when they are ready for the dump to start and actually dump the + hex data to the user a character at a time. */ + +/* Called to receive a character of data from the user. Typically this is in response to a "Press any key" type of + prompt to the user. This function should be blocking. */ +int CrashCatcher_getc(void); + +/* Called to send a character of hex dump data to the user. */ +void CrashCatcher_putc(char c); + +#ifdef __cplusplus +} +#endif + + +/* Macros which can generate a few forms of crashes. */ +#define CRASH_CATCHER_READ_FAULT() (*(volatile unsigned int*)0xFFFFFFF0) +#define CRASH_CATCHER_WRITE_FAULT() (*(volatile unsigned int*)0xFFFFFFF0 = 0x0) +#define CRASH_CATCHER_INVALID_INSTRUCTION() { __asm volatile (".word 0xDE00"); } + +/* Macro used to insert hardcoded breakpoint into user's code. */ +#define CRASH_CATCHER_BREAKPOINT() { __asm volatile ("bkpt #0"); } + +/* Macro used to make some globals writeable from unit tests but constant when running on ARM processors. */ +#ifdef RUNNING_HOST_TESTS + #define CRASH_CATCHER_TEST_WRITEABLE +#else + #define CRASH_CATCHER_TEST_WRITEABLE static const +#endif + + +#endif /* _CRASH_CATCHER_H_ */ diff --git a/utils/crash_catcher/include/CrashCatcherApi.h b/utils/crash_catcher/include/CrashCatcherApi.h new file mode 100644 index 0000000..caaae82 --- /dev/null +++ b/utils/crash_catcher/include/CrashCatcherApi.h @@ -0,0 +1,28 @@ +#ifndef __CRASH_CATCHER_API_H__ +#define __CRASH_CATCHER_API_H__ + +/* This structure is filled in by the Hard Fault exception handler (or unit test) and then passed in as a parameter to + CrashCatcher_Entry(). */ +typedef struct +{ + uint32_t msp; + uint32_t psp; + uint32_t exceptionPSR; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t exceptionLR; +} CrashCatcherExceptionRegisters; + +/* The main entry point into CrashCatcher. Is called from the HardFault exception handler and unit tests. */ +void CrashCatcher_Entry(const CrashCatcherExceptionRegisters* pExceptionRegisters); + +/* The main entry point When software Assert.*/ +void AssertCatcher_Entry(void); + +#endif /* __CRASH_CATCHER_API_H__*/ diff --git a/utils/crash_catcher/include/FloatMocks.h b/utils/crash_catcher/include/FloatMocks.h new file mode 100644 index 0000000..958bc2a --- /dev/null +++ b/utils/crash_catcher/include/FloatMocks.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2015 Adam Green (https://github.com/adamgreen) + + 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. +*/ +#ifndef _FLOAT_MOCKS_H_ +#define _FLOAT_MOCKS_H_ + +#include +#include + + +void FloatMocks_Init(void); +void FloatMocks_Uninit(void); + +void FloatMocks_SetAllFloatingPointRegisters(const uint32_t* pFloatRegisters); +void FloatMocks_SetUpperFloatingPointRegisters(const uint32_t* pFloatRegisters); + + +#endif /* _FLOAT_MOCKS_H_ */ diff --git a/utils/crc16/Makefile b/utils/crc16/Makefile new file mode 100644 index 0000000..0fb5466 --- /dev/null +++ b/utils/crc16/Makefile @@ -0,0 +1,4 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj-y := $(obj-y:.c=.o) diff --git a/utils/crc16/crc16.c b/utils/crc16/crc16.c new file mode 100644 index 0000000..222bdaf --- /dev/null +++ b/utils/crc16/crc16.c @@ -0,0 +1,74 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/* + * crc16.c + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + + #include "crc16.h" + + /** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */ +unsigned short const crc16_table[256] = { + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 +}; + +/** + * crc16 - compute the CRC-16 for the data buffer + * @crc: previous CRC value + * @buffer: data pointer + * @len: number of bytes in the buffer + * + * Returns the updated CRC value. + */ +unsigned short _crc16(unsigned short crc, unsigned char const *buffer, unsigned int len) +{ + while (len--) + crc = crc16_byte(crc, *buffer++); + return crc; +} diff --git a/utils/crc16/crc16.h b/utils/crc16/crc16.h new file mode 100644 index 0000000..3b5090f --- /dev/null +++ b/utils/crc16/crc16.h @@ -0,0 +1,35 @@ +/* + * crc16.h - CRC-16 routine + * + * Implements the standard CRC-16: + * Width 16 + * Poly 0x8005 (x^16 + x^15 + x^2 + 1) + * Init 0 + * + * Copyright (c) 2005 Ben Gardner + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#ifndef __CRC16_H +#define __CRC16_H + +extern unsigned short const crc16_table[256]; + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned short _crc16(unsigned short crc, const unsigned char *buffer, unsigned int len); + +#ifdef __cplusplus +} +#endif + +static inline unsigned short crc16_byte(unsigned short crc, const unsigned char data) +{ + return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff]; +} + +#endif /* __CRC16_H */ diff --git a/utils/crc32/Makefile b/utils/crc32/Makefile new file mode 100644 index 0000000..d31ac7a --- /dev/null +++ b/utils/crc32/Makefile @@ -0,0 +1,18 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj-y := $(obj-y:.c=.o) + +ifeq ($(CRC32_ROM),1) +ccflags-y += -Iutils/rom_utils +EXCLUDE_OBJS := crc32.o +else +EXCLUDE_OBJS := crc32_rom.o +endif + +obj-y := $(filter-out $(EXCLUDE_OBJS),$(obj-y)) + +ifeq ($(MAKE_CRC32_TABLE),1) +ccflags-y += -DMAKE_CRC32_TABLE +endif + diff --git a/utils/crc32/crc32.c b/utils/crc32/crc32.c new file mode 100644 index 0000000..7eae627 --- /dev/null +++ b/utils/crc32/crc32.c @@ -0,0 +1,134 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +// Referenced from http://www.w3.org/TR/PNG/#D-CRCAppendix + +#include "crc32.h" + +#ifdef MAKE_CRC32_TABLE + +static unsigned long crc_table[256]; +static int crc_table_computed = 0; + +static void make_crc_table(void) +{ + unsigned long c; + unsigned long n, k; + + for (n = 0; n < 256; n++) { + c = n; + for (k = 0; k < 8; k++) { + if (c & 1) + c = 0xedb88320L ^ (c >> 1); + else + c = c >> 1; + } + crc_table[n] = c; + } +} + +#else + +static const unsigned long crc_table[256] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, +}; + +#endif + +unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len) +{ + unsigned long c; + +#ifdef MAKE_CRC32_TABLE + if (crc_table_computed == 0) { + make_crc_table(); + crc_table_computed = 1; + } +#endif + + c = crc ^ 0xffffffffL; + + while (len) { + c = crc_table[(c ^ (*buf++)) & 0xff] ^ (c >> 8); + len--; + } + + return c ^ 0xffffffffL; +} + diff --git a/utils/crc32/crc32.h b/utils/crc32/crc32.h new file mode 100644 index 0000000..16b8ff3 --- /dev/null +++ b/utils/crc32/crc32.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __CRC32_H__ +#define __CRC32_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/utils/crc32/crc32_rom.c b/utils/crc32/crc32_rom.c new file mode 100644 index 0000000..10929da --- /dev/null +++ b/utils/crc32/crc32_rom.c @@ -0,0 +1,24 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "crc32.h" +#include "export_fn_rom.h" + +unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len) +{ + return __export_fn_rom.crc32(crc, buf, len); +} + diff --git a/utils/encrypt/Makefile b/utils/encrypt/Makefile new file mode 100644 index 0000000..b157c66 --- /dev/null +++ b/utils/encrypt/Makefile @@ -0,0 +1,17 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) +src_obj := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ENCRYPT_LIB_NAME := libcryption +$(ENCRYPT_LIB_NAME)-y := $(src_obj) +obj-y += $(ENCRYPT_LIB_NAME).a + +ccflags-y := \ + -Iservices/bt_profiles/inc/ \ + -Iservices/bt_if/inc/ \ + -Iservices/bt_app/ \ + -Iapps/common/ \ + -Iutils/cqueue diff --git a/utils/encrypt/_sha256.h b/utils/encrypt/_sha256.h new file mode 100644 index 0000000..8ff3988 --- /dev/null +++ b/utils/encrypt/_sha256.h @@ -0,0 +1,86 @@ + +/** @file + * + * @defgroup sha256 SHA-256 hash library + * @{ + * @ingroup app_common + * + * @brief This module calculates SHA-256 (SHA-2, FIPS-180) hashes. + * + * @details To use this module, first call @ref sha256_init on a @ref sha256_context_t instance. Then call @ref + * sha256_update with the data to be hashed. This step can optionally be done with multiple + * calls to @ref sha256_update, each with a section of the data (in the correct order). + * After all data has been passed to @ref sha256_update, call @ref sha256_final to finalize + * and extract the hash value. + * + * This code is adapted from code by Brad Conte, retrieved from + * https://github.com/B-Con/crypto-algorithms. + * + */ + +#ifndef SHA256_H +#define SHA256_H + + +#include + +#define SHA256_DIGEST_SIZE 32 + +/**@brief Current state of a hash operation. + */ +typedef struct { + uint64_t count; + union { + uint8_t buf[64]; + uint32_t buf32[64 / 4]; + }; + uint32_t state[8]; // upto SHA2 +}SHA256_CTX; + +/**@brief Function for initializing a @ref sha256_context_t instance. + * + * @param[out] ctx Context instance to be initialized. + * + * @retval BES_SUCCESS If the instance was successfully initialized. + * @retval BES_ERROR_NULL If the parameter was NULL. + */ +uint32_t _sha256_init(SHA256_CTX *ctx); + +/**@brief Function for calculating the hash of an array of uint8_t data. + * + * @details This function can be called multiple times in sequence. This is equivalent to calling + * the function once on a concatenation of the data from the different calls. + * + * @param[in,out] ctx Hash instance. + * @param[in] data Data to be hashed. + * @param[in] len Length of the data to be hashed. + * + * @retval BES_SUCCESS If the data was successfully hashed. + * @retval BES_ERROR_NULL If the ctx parameter was NULL or the data parameter was NULL, while the len parameter was not zero. + */ +uint32_t _sha256_update(SHA256_CTX *ctx, const uint8_t * data, uint32_t len); + +/**@brief Function for extracting the hash value from a hash instance. + * + * @details This function should be called after all data to be hashed has been passed to the hash + * instance (by one or more calls to @ref sha256_update). + * + * Do not call @ref sha256_update again after @ref sha256_final has been called. + * + * @param[in,out] ctx Hash instance. + * @param[out] hash Array to hold the extracted hash value (assumed to be 32 bytes long). + * @param[in] le Store the hash in little-endian. + * + * @retval BES_SUCCESS If the has value was successfully extracted. + * @retval BES_ERROR_NULL If a parameter was NULL. + */ +uint32_t _sha256_final(SHA256_CTX *ctx, uint8_t * hash, uint8_t le); + + +#ifdef __cplusplus +} +#endif + +#endif // SHA256_H + +/** @} */ diff --git a/utils/encrypt/aes.h b/utils/encrypt/aes.h new file mode 100644 index 0000000..95d153d --- /dev/null +++ b/utils/encrypt/aes.h @@ -0,0 +1,47 @@ +#ifndef _AES_H_ +#define _AES_H_ + +#include + + +// #define the macros below to 1/0 to enable/disable the mode of operation. +// +// CBC enables AES128 encryption in CBC-mode of operation and handles 0-padding. +// ECB enables the basic ECB 16-byte block algorithm. Both can be enabled simultaneously. +#if defined(__cplusplus) +extern "C" { +#endif + +// The #ifndef-guard allows it to be configured before #include'ing or at compile time. +#ifndef CBC +#define CBC 1 +#endif + +#ifndef ECB +#define ECB 1 +#endif + + + +#if defined(ECB) && ECB + +void AES128_ECB_encrypt(uint8_t* input, const uint8_t* key, uint8_t *output); +void AES128_ECB_decrypt(uint8_t* input, const uint8_t* key, uint8_t *output); + +#endif // #if defined(ECB) && ECB + + +#if defined(CBC) && CBC + +void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); +void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); + +#endif // #if defined(CBC) && CBC + +void AES128_CTR_encrypt_buffer(uint8_t* input, uint32_t length, const uint8_t* key, uint8_t* iv, uint8_t* output); + +#if defined(__cplusplus) +} +#endif + +#endif //_AES_H_ diff --git a/utils/encrypt/types.h b/utils/encrypt/types.h new file mode 100644 index 0000000..9ee8143 --- /dev/null +++ b/utils/encrypt/types.h @@ -0,0 +1,108 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_TYPES_H_ +#define _UECC_TYPES_H_ + +#ifndef uECC_PLATFORM + #if __AVR__ + #define uECC_PLATFORM uECC_avr + #elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */ + #define uECC_PLATFORM uECC_arm_thumb2 + #elif defined(__thumb__) + #define uECC_PLATFORM uECC_arm_thumb + #elif defined(__arm__) || defined(_M_ARM) + #define uECC_PLATFORM uECC_arm + #elif defined(__aarch64__) + #define uECC_PLATFORM uECC_arm64 + #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__) + #define uECC_PLATFORM uECC_x86 + #elif defined(__amd64__) || defined(_M_X64) + #define uECC_PLATFORM uECC_x86_64 + #else + #define uECC_PLATFORM uECC_arch_other + #endif +#endif + +#ifndef uECC_ARM_USE_UMAAL + #if (uECC_PLATFORM == uECC_arm) && (__ARM_ARCH >= 6) + #define uECC_ARM_USE_UMAAL 1 + #elif (uECC_PLATFORM == uECC_arm_thumb2) && (__ARM_ARCH >= 6) && !__ARM_ARCH_7M__ + #define uECC_ARM_USE_UMAAL 1 + #else + #define uECC_ARM_USE_UMAAL 0 + #endif +#endif + +#ifndef uECC_WORD_SIZE + #if uECC_PLATFORM == uECC_avr + #define uECC_WORD_SIZE 1 + #elif (uECC_PLATFORM == uECC_x86_64 || uECC_PLATFORM == uECC_arm64) + #define uECC_WORD_SIZE 8 + #else + #define uECC_WORD_SIZE 4 + #endif +#endif + +#if (uECC_WORD_SIZE != 1) && (uECC_WORD_SIZE != 4) && (uECC_WORD_SIZE != 8) + #error "Unsupported value for uECC_WORD_SIZE" +#endif + +#if ((uECC_PLATFORM == uECC_avr) && (uECC_WORD_SIZE != 1)) + #pragma message ("uECC_WORD_SIZE must be 1 for AVR") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 1 +#endif + +#if ((uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ + uECC_PLATFORM == uECC_arm_thumb2) && \ + (uECC_WORD_SIZE != 4)) + #pragma message ("uECC_WORD_SIZE must be 4 for ARM") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 4 +#endif + +#if defined(__SIZEOF_INT128__) || ((__clang_major__ * 100 + __clang_minor__) >= 302) + #define SUPPORTS_INT128 1 +#else + #define SUPPORTS_INT128 0 +#endif + +typedef int8_t wordcount_t; +typedef int16_t bitcount_t; +typedef int8_t cmpresult_t; + +#if (uECC_WORD_SIZE == 1) + +typedef uint8_t uECC_word_t; +typedef uint16_t uECC_dword_t; + +#define HIGH_BIT_SET 0x80 +#define uECC_WORD_BITS 8 +#define uECC_WORD_BITS_SHIFT 3 +#define uECC_WORD_BITS_MASK 0x07 + +#elif (uECC_WORD_SIZE == 4) + +typedef uint32_t uECC_word_t; +typedef uint64_t uECC_dword_t; + +#define HIGH_BIT_SET 0x80000000 +#define uECC_WORD_BITS 32 +#define uECC_WORD_BITS_SHIFT 5 +#define uECC_WORD_BITS_MASK 0x01F + +#elif (uECC_WORD_SIZE == 8) + +typedef uint64_t uECC_word_t; +#if SUPPORTS_INT128 +typedef unsigned __int128 uECC_dword_t; +#endif + +#define HIGH_BIT_SET 0x8000000000000000ull +#define uECC_WORD_BITS 64 +#define uECC_WORD_BITS_SHIFT 6 +#define uECC_WORD_BITS_MASK 0x03F + +#endif /* uECC_WORD_SIZE */ + +#endif /* _UECC_TYPES_H_ */ diff --git a/utils/encrypt/uECC.h b/utils/encrypt/uECC.h new file mode 100644 index 0000000..43a19d6 --- /dev/null +++ b/utils/encrypt/uECC.h @@ -0,0 +1,365 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_H_ +#define _UECC_H_ + +#include + +/* Platform selection options. +If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros. +Possible values for uECC_PLATFORM are defined below: */ +#define uECC_arch_other 0 +#define uECC_x86 1 +#define uECC_x86_64 2 +#define uECC_arm 3 +#define uECC_arm_thumb 4 +#define uECC_arm_thumb2 5 +#define uECC_arm64 6 +#define uECC_avr 7 + +/* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes). +If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your +platform. */ + +/* Optimization level; trade speed for code size. + Larger values produce code that is faster but larger. + Currently supported values are 0 - 4; 0 is unusably slow for most applications. + Optimization level 4 currently only has an effect ARM platforms where more than one + curve is enabled. */ +#ifndef uECC_OPTIMIZATION_LEVEL + #define uECC_OPTIMIZATION_LEVEL 2 +#endif + +/* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be +used for (scalar) squaring instead of the generic multiplication function. This can make things +faster somewhat faster, but increases the code size. */ +#ifndef uECC_SQUARE_FUNC + #define uECC_SQUARE_FUNC 0 +#endif + +/* uECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will switch to native +little-endian format for *all* arrays passed in and out of the public API. This includes public +and private keys, shared secrets, signatures and message hashes. +Using this switch reduces the amount of call stack memory used by uECC, since less intermediate +translations are required. +Note that this will *only* work on native little-endian processors and it will treat the uint8_t +arrays passed into the public API as word arrays, therefore requiring the provided byte arrays +to be word aligned on architectures that do not support unaligned accesses. +IMPORTANT: Keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible +with keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use +the same endianness. */ +#ifndef uECC_VLI_NATIVE_LITTLE_ENDIAN + #define uECC_VLI_NATIVE_LITTLE_ENDIAN 0 +#endif + +/* Curve support selection. Set to 0 to remove that curve. */ +#ifndef uECC_SUPPORTS_secp160r1 + #define uECC_SUPPORTS_secp160r1 1 +#endif +#ifndef uECC_SUPPORTS_secp192r1 + #define uECC_SUPPORTS_secp192r1 1 +#endif +#ifndef uECC_SUPPORTS_secp224r1 + #define uECC_SUPPORTS_secp224r1 1 +#endif +#ifndef uECC_SUPPORTS_secp256r1 + #define uECC_SUPPORTS_secp256r1 1 +#endif +#ifndef uECC_SUPPORTS_secp256k1 + #define uECC_SUPPORTS_secp256k1 1 +#endif + +/* Specifies whether compressed point format is supported. + Set to 0 to disable point compression/decompression functions. */ +#ifndef uECC_SUPPORT_COMPRESSED_POINT + #define uECC_SUPPORT_COMPRESSED_POINT 1 +#endif + +struct uECC_Curve_t; +typedef const struct uECC_Curve_t * uECC_Curve; + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if uECC_SUPPORTS_secp160r1 +uECC_Curve uECC_secp160r1(void); +#endif +#if uECC_SUPPORTS_secp192r1 +uECC_Curve uECC_secp192r1(void); +#endif +#if uECC_SUPPORTS_secp224r1 +uECC_Curve uECC_secp224r1(void); +#endif +#if uECC_SUPPORTS_secp256r1 +uECC_Curve uECC_secp256r1(void); +#endif +#if uECC_SUPPORTS_secp256k1 +uECC_Curve uECC_secp256k1(void); +#endif + +/* uECC_RNG_Function type +The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if +'dest' was filled with random data, or 0 if the random data could not be generated. +The filled-in values should be either truly random, or from a cryptographically-secure PRNG. + +A correctly functioning RNG function must be set (using uECC_set_rng()) before calling +uECC_make_key() or uECC_sign(). + +Setting a correctly functioning RNG function improves the resistance to side-channel attacks +for uECC_shared_secret() and uECC_sign_deterministic(). + +A correct RNG function is set by default when building for Windows, Linux, or OS X. +If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom, +you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined +RNG function; you must provide your own. +*/ +typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size); + +/* uECC_set_rng() function. +Set the function that will be used to generate random bytes. The RNG function should +return 1 if the random data was generated, or 0 if the random data could not be generated. + +On platforms where there is no predefined RNG function (eg embedded platforms), this must +be called before uECC_make_key() or uECC_sign() are used. + +Inputs: + rng_function - The function that will be used to generate random bytes. +*/ +void uECC_set_rng(uECC_RNG_Function rng_function); + +/* uECC_get_rng() function. + +Returns the function that will be used to generate random bytes. +*/ +uECC_RNG_Function uECC_get_rng(void); + +/* uECC_curve_private_key_size() function. + +Returns the size of a private key for the curve in bytes. +*/ +int uECC_curve_private_key_size(uECC_Curve curve); + +/* uECC_curve_public_key_size() function. + +Returns the size of a public key for the curve in bytes. +*/ +int uECC_curve_public_key_size(uECC_Curve curve); + +/* uECC_make_key() function. +Create a public/private key pair. + +Outputs: + public_key - Will be filled in with the public key. Must be at least 2 * the curve size + (in bytes) long. For example, if the curve is secp256r1, public_key must be 64 + bytes long. + private_key - Will be filled in with the private key. Must be as long as the curve order; this + is typically the same as the curve size, except for secp160r1. For example, if the + curve is secp256r1, private_key must be 32 bytes long. + + For secp160r1, private_key must be 21 bytes long! Note that the first byte will + almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero). + +Returns 1 if the key pair was generated successfully, 0 if an error occurred. +*/ +int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve); + +/* uECC_shared_secret() function. +Compute a shared secret given your secret key and someone else's public key. +Note: It is recommended that you hash the result of uECC_shared_secret() before using it for +symmetric encryption or HMAC. + +Inputs: + public_key - The public key of the remote party. + private_key - Your private key. + +Outputs: + secret - Will be filled in with the shared secret value. Must be the same size as the + curve size; for example, if the curve is secp256r1, secret must be 32 bytes long. + +Returns 1 if the shared secret was generated successfully, 0 if an error occurred. +*/ +int uECC_shared_secret(const uint8_t *public_key, + const uint8_t *private_key, + uint8_t *secret, + uECC_Curve curve); + +#if uECC_SUPPORT_COMPRESSED_POINT +/* uECC_compress() function. +Compress a public key. + +Inputs: + public_key - The public key to compress. + +Outputs: + compressed - Will be filled in with the compressed public key. Must be at least + (curve size + 1) bytes long; for example, if the curve is secp256r1, + compressed must be 33 bytes long. +*/ +void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve); + +/* uECC_decompress() function. +Decompress a compressed public key. + +Inputs: + compressed - The compressed public key. + +Outputs: + public_key - Will be filled in with the decompressed public key. +*/ +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve); +#endif /* uECC_SUPPORT_COMPRESSED_POINT */ + +/* uECC_valid_public_key() function. +Check to see if a public key is valid. + +Note that you are not required to check for a valid public key before using any other uECC +functions. However, you may wish to avoid spending CPU time computing a shared secret or +verifying a signature using an invalid public key. + +Inputs: + public_key - The public key to check. + +Returns 1 if the public key is valid, 0 if it is invalid. +*/ +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve); + +/* uECC_compute_public_key() function. +Compute the corresponding public key for a private key. + +Inputs: + private_key - The private key to compute the public key for + +Outputs: + public_key - Will be filled in with the corresponding public key + +Returns 1 if the key was computed successfully, 0 if an error occurred. +*/ +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve); + +/* uECC_sign() function. +Generate an ECDSA signature for a given hash value. + +Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to +this function along with your private key. + +Inputs: + private_key - Your private key. + message_hash - The hash of the message to sign. + hash_size - The size of message_hash in bytes. + +Outputs: + signature - Will be filled in with the signature value. Must be at least 2 * curve size long. + For example, if the curve is secp256r1, signature must be 64 bytes long. + +Returns 1 if the signature generated successfully, 0 if an error occurred. +*/ +int uECC_sign(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + uint8_t *signature, + uECC_Curve curve); + +/* uECC_HashContext structure. +This is used to pass in an arbitrary hash function to uECC_sign_deterministic(). +The structure will be used for multiple hash computations; each time a new hash +is computed, init_hash() will be called, followed by one or more calls to +update_hash(), and finally a call to finish_hash() to produce the resulting hash. + +The intention is that you will create a structure that includes uECC_HashContext +followed by any hash-specific data. For example: + +typedef struct SHA256_HashContext { + uECC_HashContext uECC; + SHA256_CTX ctx; +} SHA256_HashContext; + +void init_SHA256(uECC_HashContext *base) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Init(&context->ctx); +} + +void update_SHA256(uECC_HashContext *base, + const uint8_t *message, + unsigned message_size) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Update(&context->ctx, message, message_size); +} + +void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Final(hash_result, &context->ctx); +} + +... when signing ... +{ + uint8_t tmp[32 + 32 + 64]; + SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}}; + uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature); +} +*/ +typedef struct uECC_HashContext { + void (*init_hash)(const struct uECC_HashContext *context); + void (*update_hash)(const struct uECC_HashContext *context, + const uint8_t *message, + unsigned message_size); + void (*finish_hash)(const struct uECC_HashContext *context, uint8_t *hash_result); + unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */ + unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */ + uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */ +} uECC_HashContext; + +/* uECC_sign_deterministic() function. +Generate an ECDSA signature for a given hash value, using a deterministic algorithm +(see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling +this function; however, if the RNG is defined it will improve resistance to side-channel +attacks. + +Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it to +this function along with your private key and a hash context. Note that the message_hash +does not need to be computed with the same hash function used by hash_context. + +Inputs: + private_key - Your private key. + message_hash - The hash of the message to sign. + hash_size - The size of message_hash in bytes. + hash_context - A hash context to use. + +Outputs: + signature - Will be filled in with the signature value. + +Returns 1 if the signature generated successfully, 0 if an error occurred. +*/ +int uECC_sign_deterministic(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + const uECC_HashContext *hash_context, + uint8_t *signature, + uECC_Curve curve); + +/* uECC_verify() function. +Verify an ECDSA signature. + +Usage: Compute the hash of the signed data using the same hash as the signer and +pass it to this function along with the signer's public key and the signature values (r and s). + +Inputs: + public_key - The signer's public key. + message_hash - The hash of the signed data. + hash_size - The size of message_hash in bytes. + signature - The signature value. + +Returns 1 if the signature is valid, 0 if it is invalid. +*/ +int uECC_verify(const uint8_t *public_key, + const uint8_t *message_hash, + unsigned hash_size, + const uint8_t *signature, + uECC_Curve curve); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _UECC_H_ */ diff --git a/utils/encrypt/uECC_vli.h b/utils/encrypt/uECC_vli.h new file mode 100644 index 0000000..864cc33 --- /dev/null +++ b/utils/encrypt/uECC_vli.h @@ -0,0 +1,172 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_VLI_H_ +#define _UECC_VLI_H_ + +#include "uECC.h" +#include "types.h" + +/* Functions for raw large-integer manipulation. These are only available + if uECC.c is compiled with uECC_ENABLE_VLI_API defined to 1. */ +#ifndef uECC_ENABLE_VLI_API + #define uECC_ENABLE_VLI_API 0 +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if uECC_ENABLE_VLI_API + +void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words); + +/* Constant-time comparison to zero - secure way to compare long integers */ +/* Returns 1 if vli == 0, 0 otherwise. */ +uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words); + +/* Returns nonzero if bit 'bit' of vli is set. */ +uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit); + +/* Counts the number of bits required to represent vli. */ +bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words); + +/* Sets dest = src. */ +void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words); + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns one if left == right, zero otherwise */ +uECC_word_t uECC_vli_equal(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns sign of left - right, in constant time. */ +cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right, wordcount_t num_words); + +/* Computes vli = vli >> 1. */ +void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words); + +/* Computes result = left + right, returning carry. Can modify in place. */ +uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left - right, returning borrow. Can modify in place. */ +uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left * right. Result must be 2 * num_words long. */ +void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left^2. Result must be 2 * num_words long. */ +void uECC_vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words); + +/* Computes result = (left + right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +void uECC_vli_modAdd(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = (left - right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +void uECC_vli_modSub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = product % mod, where product is 2N words long. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_mmod(uECC_word_t *result, + uECC_word_t *product, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Calculates result = product (mod curve->p), where product is up to + 2 * curve->num_words long. */ +void uECC_vli_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve); + +/* Computes result = (left * right) % mod. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_modMult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = (left * right) % curve->p. */ +void uECC_vli_modMult_fast(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + uECC_Curve curve); + +/* Computes result = left^2 % mod. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = left^2 % curve->p. */ +void uECC_vli_modSquare_fast(uECC_word_t *result, const uECC_word_t *left, uECC_Curve curve); + +/* Computes result = (1 / input) % mod.*/ +void uECC_vli_modInv(uECC_word_t *result, + const uECC_word_t *input, + const uECC_word_t *mod, + wordcount_t num_words); + +#if uECC_SUPPORT_COMPRESSED_POINT +/* Calculates a = sqrt(a) (mod curve->p) */ +void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve); +#endif + +/* Converts an integer in uECC native format to big-endian bytes. */ +void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes, const uECC_word_t *native); +/* Converts big-endian bytes to an integer in uECC native format. */ +void uECC_vli_bytesToNative(uECC_word_t *native, const uint8_t *bytes, int num_bytes); + +unsigned uECC_curve_num_words(uECC_Curve curve); +unsigned uECC_curve_num_bytes(uECC_Curve curve); +unsigned uECC_curve_num_bits(uECC_Curve curve); +unsigned uECC_curve_num_n_words(uECC_Curve curve); +unsigned uECC_curve_num_n_bytes(uECC_Curve curve); +unsigned uECC_curve_num_n_bits(uECC_Curve curve); + +const uECC_word_t *uECC_curve_p(uECC_Curve curve); +const uECC_word_t *uECC_curve_n(uECC_Curve curve); +const uECC_word_t *uECC_curve_G(uECC_Curve curve); +const uECC_word_t *uECC_curve_b(uECC_Curve curve); + +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve); + +/* Multiplies a point by a scalar. Points are represented by the X coordinate followed by + the Y coordinate in the same array, both coordinates are curve->num_words long. Note + that scalar must be curve->num_n_words long (NOT curve->num_words). */ +void uECC_point_mult(uECC_word_t *result, + const uECC_word_t *point, + const uECC_word_t *scalar, + uECC_Curve curve); + +/* Generates a random integer in the range 0 < random < top. + Both random and top have num_words words. */ +int uECC_generate_random_int(uECC_word_t *random, + const uECC_word_t *top, + wordcount_t num_words); + +#endif /* uECC_ENABLE_VLI_API */ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _UECC_VLI_H_ */ diff --git a/utils/heap/Makefile b/utils/heap/Makefile new file mode 100644 index 0000000..c25660e --- /dev/null +++ b/utils/heap/Makefile @@ -0,0 +1,11 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -Iplatform/cmsis/inc/ \ + diff --git a/utils/heap/heap_api.c b/utils/heap/heap_api.c new file mode 100644 index 0000000..e1201a1 --- /dev/null +++ b/utils/heap/heap_api.c @@ -0,0 +1,236 @@ +#include "multi_heap.h" +#include "heap_api.h" +#include "string.h" +#include "hal_trace.h" + +// #define HEAP_API_DEBUG + +#if 0 +extern uint32_t __HeapBase; +extern uint32_t __HeapLimit; +static heap_handle_t global_heap = NULL; + +void *malloc(size_t size) +{ + if (global_heap == NULL) + global_heap = heap_register((void *)&__HeapBase,(&__HeapLimit - &__HeapBase)); + return heap_malloc(global_heap,size); +} + +void free(void *ptr) +{ + heap_free(global_heap,ptr); +} + +void *calloc(size_t nmemb, size_t size) +{ + void *ptr = malloc(nmemb*size); + if (ptr != NULL) + memset(ptr,0,nmemb*size); + return ptr; +} +void *realloc(void *ptr, size_t size) +{ + return heap_realloc(global_heap,ptr,size); +} +#endif + +// TODO: multi heap and block +#define MED_HEAP_BLOCK_MAX_NUM (3) +static int g_block_index = 0; +static int g_switch_cp = 0; +// NOTE: Can use g_med_heap_begin_addr and g_med_heap_size to optimize free speed +// static void *g_med_heap_begin_addr[MED_HEAP_BLOCK_MAX_NUM]; +// static size_t g_med_heap_size[MED_HEAP_BLOCK_MAX_NUM]; + +static heap_handle_t g_med_heap[MED_HEAP_BLOCK_MAX_NUM]; +static heap_handle_t g_cp_heap; + +void heap_memory_info(heap_handle_t heap, size_t *total, size_t *used, size_t *max_used) +{ + multi_heap_info_t info; + heap_get_info(heap, &info); + + if (total != NULL) + *total = info.total_bytes; + + if (used != NULL) + *used = info.total_allocated_bytes; + + if (max_used != NULL) + *max_used = info.total_bytes - info.minimum_free_bytes; +} + +static int med_help_get_index(void *ptr) +{ + int index = 0; + int diff_addr = 0; + multi_heap_info_t info; + + for (index = 0; index < g_block_index; index++) + { + heap_get_info(g_med_heap[index], &info); + diff_addr = (char *)ptr - (char *)g_med_heap[index]; + +#ifdef HEAP_API_DEBUG + TRACE(3,"[%s] index = %d, diff_addr = %d", __func__, index, diff_addr); +#endif + + if ((diff_addr > 0) && (diff_addr < info.total_bytes)) + { + break; + } + } + + ASSERT(index < g_block_index, "[%s] Can not find ptr = %p", __func__, ptr); + + return index; +} + +static void med_heap_reset(void) +{ + g_block_index = 0; + g_switch_cp = 0; + + for (int i = 0; i < MED_HEAP_BLOCK_MAX_NUM; i++) + { + // g_med_heap_begin_addr[i] = NULL; + // g_med_heap_size[i] = NULL; + g_med_heap[i] = NULL; + } + g_cp_heap = NULL; +} + +void med_heap_set_cp(int switch_cp) +{ + TRACE(2,"[%s] switch_cp: %d", __func__, switch_cp); + g_switch_cp = switch_cp; +} + +void med_heap_add_block(void *begin_addr, size_t size) +{ + TRACE(4,"[%s] g_block_index = %d, begin_addr = %p, size = %d", __func__, g_block_index, begin_addr, size); + ASSERT(g_block_index < MED_HEAP_BLOCK_MAX_NUM, "[%s] g_block_index(%d) >= MED_HEAP_BLOCK_MAX_NUM", __func__, g_block_index); + + memset(begin_addr, 0, size); + if (g_switch_cp) + { + g_cp_heap = heap_register(begin_addr, size); + } + else + { + g_med_heap[g_block_index] = heap_register(begin_addr, size); + // g_med_heap_begin_addr[g_block_index] = begin_addr; + // g_med_heap_size[g_block_index] = size; + + g_block_index++; + } +} + +void med_heap_init(void *begin_addr, size_t size) +{ + med_heap_reset(); + med_heap_add_block(begin_addr, size); +} + +void *med_malloc(size_t size) +{ + int index = 0; + void *ptr = NULL; + + if (size == 0) + return NULL; + + if (g_switch_cp) + { + ptr = heap_malloc(g_cp_heap, size); + goto exit; + } + + for (index = 0; index < g_block_index; index++) + { + if (multi_heap_free_size(g_med_heap[index]) >= size) + { + break; + } + } + +#ifdef HEAP_API_DEBUG + TRACE(3,"[%s] index = %d, size = %d", __func__, index, size); +#endif + + ASSERT(index < g_block_index, "[%s] index = %d, g_block_index = %d. Can not malloc any RAM", __func__, index, g_block_index); + + ptr = heap_malloc(g_med_heap[index], size); + +exit: + ASSERT(ptr != NULL, "[%s]: no memory, needed size %d", __FUNCTION__, size); + + return ptr; +} + +void med_free(void *p) +{ + if (p) + { + if (g_switch_cp) + { + heap_free(g_cp_heap, p); + } + else + { + int index = med_help_get_index(p); + heap_free(g_med_heap[index], p); + } + + p = NULL; + } +} + +void *med_calloc(size_t nmemb, size_t size) +{ + if (size == 0) + return NULL; + + void *ptr = med_malloc(nmemb * size); + + if (ptr) + { + memset(ptr, 0 , nmemb * size); + } + + return ptr; +} + +void *med_realloc(void *ptr, size_t size) +{ + // TODO: Do not support multi blocks + // TODO: Do not support cp + void *newptr = heap_realloc(g_med_heap[0],ptr,size); + + ASSERT(newptr != NULL, "[%s]: no memory, needed size %d", __FUNCTION__, size); + + return newptr; +} + +void med_memory_info(size_t *total, + size_t *used, + size_t *max_used) +{ + size_t _total = 0; + size_t _used = 0; + size_t _max_used = 0; + + for (int i = 0; i < g_block_index; i++) + { + heap_memory_info(g_med_heap[i], &_total, &_used, &_max_used); + *total += _total; + *used += _used; + *max_used += _max_used; + +#ifdef HEAP_API_DEBUG + TRACE(4,"[%s] %d: g_med_heap = %p, size = %d", __func__, i, g_med_heap[i], _total); +#endif + } +} + diff --git a/utils/heap/heap_api.h b/utils/heap/heap_api.h new file mode 100644 index 0000000..b5bdd9b --- /dev/null +++ b/utils/heap/heap_api.h @@ -0,0 +1,83 @@ +#ifndef __HEAP_API__ +#define __HEAP_API__ +#include "stdint.h" +#include "string.h" +#include "multi_heap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SYSPOOL_PURE __attribute__((__const__)) + +void syspool_init(void); +void syspool_init_specific_size(uint32_t size); +int syspool_free_size(void); +int syspool_get_buff(uint8_t **buff, uint32_t size); +int syspool_get_available(uint8_t **buff); +uint8_t* syspool_start_addr(void) SYSPOOL_PURE; +uint32_t syspool_total_size(void); +uint32_t syspool_original_size(void) SYSPOOL_PURE; + +#if defined(A2DP_LDAC_ON) +int syspool_force_used_size(uint32_t size); +#endif + +#define heap_malloc multi_heap_malloc + +#define heap_free multi_heap_free + +#define heap_realloc multi_heap_realloc + +#define heap_get_allocated_size multi_heap_get_allocated_size + +#define heap_register multi_heap_register + +#define heap_free_size multi_heap_free_size + +#define heap_minimum_free_size multi_heap_minimum_free_size + +#define heap_get_info multi_heap_get_info + +#define heap_dump multi_heap_dump + +#define heap_check multi_heap_check + +typedef struct multi_heap_info *heap_handle_t; +heap_handle_t heap_register(void *start, size_t size); +void *heap_malloc(heap_handle_t heap, size_t size); +void heap_free(heap_handle_t heap, void *p); +void *heap_realloc(heap_handle_t heap, void *p, size_t size); +size_t heap_get_allocated_size(heap_handle_t heap, void *p); +void heap_set_lock(heap_handle_t heap, void* lock); +void heap_dump(heap_handle_t heap); +bool heap_check(heap_handle_t heap, bool print_errors); +size_t heap_free_size(heap_handle_t heap); +size_t heap_minimum_free_size(heap_handle_t heap); +void heap_get_info(heap_handle_t heap, multi_heap_info_t *info); +void heap_memory_info(heap_handle_t heap, + size_t *total, + size_t *used, + size_t *max_used); + +#if 0 +void *malloc(size_t size); +void free(void *p); +void *calloc(size_t nmemb, size_t size); +void *realloc(void *ptr, size_t size); +#endif +void med_heap_init(void *begin_addr, size_t size); +void med_heap_set_cp(int switch_cp); +void med_heap_add_block(void *begin_addr, size_t size); +void *med_malloc(size_t size); +void med_free(void *p); +void *med_calloc(size_t nmemb, size_t size); +void *med_realloc(void *ptr, size_t size); +void med_memory_info(size_t *total, + size_t *used, + size_t *max_used); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/utils/heap/med_memory.h b/utils/heap/med_memory.h new file mode 100644 index 0000000..c7a874c --- /dev/null +++ b/utils/heap/med_memory.h @@ -0,0 +1 @@ +#include "heap_api.h" diff --git a/utils/heap/multi_heap.c b/utils/heap/multi_heap.c new file mode 100644 index 0000000..3b00327 --- /dev/null +++ b/utils/heap/multi_heap.c @@ -0,0 +1,754 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// 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. +#include +#include +#include +#include +#include +#include +#include +#include +#include "multi_heap_internal.h" +#include "hal_trace.h" + +/* Note: Keep platform-specific parts in this header, this source + file should depend on libc only */ +#include "multi_heap_platform.h" + +#ifndef MULTI_HEAP_POISONING +/* if no heap poisoning, public API aliases directly to these implementations */ +void *multi_heap_malloc(multi_heap_handle_t heap, size_t size) + __attribute__((alias("multi_heap_malloc_impl"))); + +void multi_heap_free(multi_heap_handle_t heap, void *p) + __attribute__((alias("multi_heap_free_impl"))); + +void *multi_heap_realloc(multi_heap_handle_t heap, void *p, size_t size) + __attribute__((alias("multi_heap_realloc_impl"))); + +size_t multi_heap_get_allocated_size(multi_heap_handle_t heap, void *p) + __attribute__((alias("multi_heap_get_allocated_size_impl"))); + +multi_heap_handle_t multi_heap_register(void *start, size_t size) + __attribute__((alias("multi_heap_register_impl"))); + +void multi_heap_get_info(multi_heap_handle_t heap, multi_heap_info_t *info) + __attribute__((alias("multi_heap_get_info_impl"))); + +size_t multi_heap_free_size(multi_heap_handle_t heap) + __attribute__((alias("multi_heap_free_size_impl"))); + +size_t multi_heap_minimum_free_size(multi_heap_handle_t heap) + __attribute__((alias("multi_heap_minimum_free_size_impl"))); + +void *multi_heap_get_block_address(multi_heap_block_handle_t block) + __attribute__((alias("multi_heap_get_block_address_impl"))); + +void *multi_heap_get_block_owner(multi_heap_block_handle_t block) +{ + return NULL; +} + +#endif + +#define HEAP_ALIGN(X) ((X) & ~(sizeof(void *)-1)) +#define HEAP_ALIGN_UP(X) HEAP_ALIGN((X)+sizeof(void *)-1) + +struct heap_block; + +/* Block in the heap + + Heap implementation uses two single linked lists, a block list (all blocks) and a free list (free blocks). + + 'header' holds a pointer to the next block (used or free) ORed with a free flag (the LSB of the pointer.) is_free() and get_next_block() utility functions allow typed access to these values. + + 'next_free' is valid if the block is free and is a pointer to the next block in the free list. +*/ +typedef struct heap_block { + intptr_t header; /* Encodes next block in heap (used or unused) and also free/used flag */ + union { + uint8_t data[1]; /* First byte of data, valid if block is used. Actual size of data is 'block_data_size(block)' */ + struct heap_block *next_free; /* Pointer to next free block, valid if block is free */ + }; +} heap_block_t; + +/* These masks apply to the 'header' field of heap_block_t */ +#define BLOCK_FREE_FLAG 0x1 /* If set, this block is free & next_free pointer is valid */ +#define NEXT_BLOCK_MASK (~3) /* AND header with this mask to get pointer to next block (free or used) */ + +/* Metadata header for the heap, stored at the beginning of heap space. + + 'first_block' is a "fake" first block, minimum length, used to provide a pointer to the first used & free block in + the heap. This block is never allocated or merged into an adjacent block. + + 'last_block' is a pointer to a final free block of length 0, which is added at the end of the heap when it is + registered. This block is also never allocated or merged into an adjacent block. + */ +typedef struct multi_heap_info { + void *lock; + size_t total_bytes; + size_t free_bytes; + size_t minimum_free_bytes; + heap_block_t *last_block; + heap_block_t first_block; /* initial 'free block', never allocated */ +#if defined(MULTI_HEAP_DEFAULT_INT_LOCK) + size_t int_lock; +#endif +} heap_t; + +/* Given a pointer to the 'data' field of a block (ie the previous malloc/realloc result), return a pointer to the + containing block. +*/ +static inline heap_block_t *get_block(const void *data_ptr) +{ + return (heap_block_t *)((char *)data_ptr - offsetof(heap_block_t, data)); +} + +/* Return the next sequential block in the heap. + */ +static inline heap_block_t *get_next_block(const heap_block_t *block) +{ + intptr_t next = block->header & NEXT_BLOCK_MASK; + if (next == 0) { + return NULL; /* last_block */ + } + assert(next > (intptr_t)block); + return (heap_block_t *)next; +} + +/* Return true if this block is free. */ +static inline bool is_free(const heap_block_t *block) +{ + return block->header & BLOCK_FREE_FLAG; +} + +/* Return true if this block is the first in the heap */ +static inline bool is_first_block(const heap_t *heap, const heap_block_t *block) +{ + return (block == &heap->first_block); +} + +/* Return true if this block is the last_block in the heap + (the only block with no next pointer) */ +static inline bool is_last_block(const heap_block_t *block) +{ + return (block->header & NEXT_BLOCK_MASK) == 0; +} + +/* Data size of the block (excludes this block's header) */ +static inline size_t block_data_size(const heap_block_t *block) +{ + intptr_t next = (intptr_t)block->header & NEXT_BLOCK_MASK; + intptr_t this = (intptr_t)block; + if (next == 0) { + return 0; /* this is the last block in the heap */ + } + return next - this - sizeof(block->header); +} + +/* Check a block is valid for this heap. Used to verify parameters. */ +static void assert_valid_block(const heap_t *heap, const heap_block_t *block) +{ + MULTI_HEAP_ASSERT(block >= &heap->first_block && block <= heap->last_block, + block); // block not in heap + if (heap < (const heap_t *)heap->last_block) { + const heap_block_t *next = get_next_block(block); + MULTI_HEAP_ASSERT(next >= &heap->first_block && next <= heap->last_block, block); // Next block not in heap + if (is_free(block)) { + // Check block->next_free is valid + MULTI_HEAP_ASSERT(block->next_free >= &heap->first_block && block->next_free <= heap->last_block, &block->next_free); + } + } +} + +/* Get the first free block before 'block' in the heap. 'block' can be a free block or in use. + + Result is always the closest free block to 'block' in the heap, that is located before 'block'. There may be multiple + allocated blocks between the result and 'block'. + + If 'block' is free, the result's 'next_free' pointer will already point to 'block'. + + Result will never be NULL, but it may be the header block heap->first_block. +*/ +static heap_block_t *get_prev_free_block(heap_t *heap, const heap_block_t *block) +{ + assert(!is_first_block(heap, block)); /* can't look for a block before first_block */ + + for (heap_block_t *b = &heap->first_block; b != NULL && b < block; b = b->next_free) { + MULTI_HEAP_ASSERT(is_free(b), b); // Block should be free + if (b->next_free == NULL || b->next_free >= block) { + if (is_free(block)) { + /* if block is on freelist, 'b' should be the item before it. */ + MULTI_HEAP_ASSERT(b->next_free == block, &b->next_free); + } + return b; /* b is the last free block before 'block' */ + } + } + abort(); /* There should always be a previous free block, even if it's heap->first_block */ +} + +/* Merge some block 'a' into the following block 'b'. + + If both blocks are free, resulting block is marked free. + If only one block is free, resulting block is marked in use. No data is moved. + + This operation may fail if block 'a' is the first block or 'b' is the last block, + the caller should check block_data_size() to know if anything happened here or not. +*/ +static heap_block_t *merge_adjacent(heap_t *heap, heap_block_t *a, heap_block_t *b) +{ + assert(a < b); + + /* Can't merge header blocks, just return the non-header block as-is */ + if (is_last_block(b)) { + return a; + } + if (is_first_block(heap, a)) { + return b; + } + + MULTI_HEAP_ASSERT(get_next_block(a) == b, a); // Blocks should be in order + + bool free = is_free(a) && is_free(b); /* merging two free blocks creates a free block */ + if (!free && (is_free(a) || is_free(b))) { + /* only one of these blocks is free, so resulting block will be a used block. + means we need to take the free block out of the free list + */ + heap_block_t *free_block = is_free(a) ? a : b; + heap_block_t *prev_free = get_prev_free_block(heap, free_block); + MULTI_HEAP_ASSERT(free_block->next_free > prev_free, &free_block->next_free); // Next free block should be after prev one + prev_free->next_free = free_block->next_free; + + heap->free_bytes -= block_data_size(free_block); + } + + a->header = b->header & NEXT_BLOCK_MASK; + MULTI_HEAP_ASSERT(a->header != 0, a); + if (free) { + a->header |= BLOCK_FREE_FLAG; + if (b->next_free != NULL) { + MULTI_HEAP_ASSERT(b->next_free > a, &b->next_free); + MULTI_HEAP_ASSERT(b->next_free > b, &b->next_free); + } + a->next_free = b->next_free; + + /* b's header can be put into the pool of free bytes */ + heap->free_bytes += sizeof(a->header); + } + +#ifdef MULTI_HEAP_POISONING_SLOW + /* b's former block header needs to be replaced with a fill pattern */ + multi_heap_internal_poison_fill_region(b, sizeof(heap_block_t), free); +#endif + + return a; +} + +/* Split a block so it can hold at least 'size' bytes of data, making any spare + space into a new free block. + + 'block' should be marked in-use when this function is called (implementation detail, this function + doesn't set the next_free pointer). + + 'prev_free_block' is the free block before 'block', if already known. Can be NULL if not yet known. + (This is a performance optimisation to avoid walking the freelist twice when possible.) +*/ +static void split_if_necessary(heap_t *heap, heap_block_t *block, size_t size, heap_block_t *prev_free_block) +{ + const size_t block_size = block_data_size(block); + MULTI_HEAP_ASSERT(!is_free(block), block); // split block shouldn't be free + MULTI_HEAP_ASSERT(size <= block_size, block); // size should be valid + size = HEAP_ALIGN_UP(size); + + /* can't split the head or tail block */ + assert(!is_first_block(heap, block)); + assert(!is_last_block(block)); + + heap_block_t *new_block = (heap_block_t *)(block->data + size); + heap_block_t *next_block = get_next_block(block); + + if (is_free(next_block) && !is_last_block(next_block)) { + /* The next block is free, just extend it upwards. */ + new_block->header = next_block->header; + new_block->next_free = next_block->next_free; + if (prev_free_block == NULL) { + prev_free_block = get_prev_free_block(heap, block); + } + /* prev_free_block should point to the next block (which we found to be free). */ + MULTI_HEAP_ASSERT(prev_free_block->next_free == next_block, + &prev_free_block->next_free); // free blocks should be in order + /* Note: We have not introduced a new block header, hence the simple math. */ + heap->free_bytes += block_size - size; +#ifdef MULTI_HEAP_POISONING_SLOW + /* next_block header needs to be replaced with a fill pattern */ + multi_heap_internal_poison_fill_region(next_block, sizeof(heap_block_t), true /* free */); +#endif + } else { + /* Insert a free block between the current and the next one. */ + if (block_data_size(block) < size + sizeof(heap_block_t)) { + /* Can't split 'block' if we're not going to get a usable free block afterwards */ + return; + } + if (prev_free_block == NULL) { + prev_free_block = get_prev_free_block(heap, block); + } + new_block->header = block->header | BLOCK_FREE_FLAG; + new_block->next_free = prev_free_block->next_free; + /* prev_free_block should point to a free block after new_block */ + MULTI_HEAP_ASSERT(prev_free_block->next_free > new_block, + &prev_free_block->next_free); // free blocks should be in order + heap->free_bytes += block_data_size(new_block); + } + block->header = (intptr_t)new_block; + prev_free_block->next_free = new_block; +} + +void *multi_heap_get_block_address_impl(multi_heap_block_handle_t block) +{ + return ((char *)block + offsetof(heap_block_t, data)); +} + +size_t multi_heap_get_allocated_size_impl(multi_heap_handle_t heap, void *p) +{ + heap_block_t *pb = get_block(p); + + assert_valid_block(heap, pb); + MULTI_HEAP_ASSERT(!is_free(pb), pb); // block shouldn't be free + return block_data_size(pb); +} + +multi_heap_handle_t multi_heap_register_impl(void *start, size_t size) +{ + TRACE(2,"multi_heap_register_impl start=%p,size=%d",start,size); + heap_t *heap = (heap_t *)HEAP_ALIGN_UP((intptr_t)start); + uintptr_t end = HEAP_ALIGN((uintptr_t)start + size); + if (end - (uintptr_t)start < sizeof(heap_t) + 2*sizeof(heap_block_t)) { + return NULL; /* 'size' is too small to fit a heap here */ + } +#if defined(MULTI_HEAP_DEFAULT_INT_LOCK) + heap->lock = (void *)(&heap->int_lock); +#else + heap->lock = NULL; +#endif + heap->last_block = (heap_block_t *)(end - sizeof(heap_block_t)); + + /* first 'real' (allocatable) free block goes after the heap structure */ + heap_block_t *first_free_block = (heap_block_t *)((intptr_t)start + sizeof(heap_t)); + first_free_block->header = (intptr_t)heap->last_block | BLOCK_FREE_FLAG; + first_free_block->next_free = heap->last_block; + + /* last block is 'free' but has a NULL next pointer */ + heap->last_block->header = BLOCK_FREE_FLAG; + heap->last_block->next_free = NULL; + + /* first block also 'free' but has legitimate length, + malloc will never allocate into this block. */ + heap->first_block.header = (intptr_t)first_free_block | BLOCK_FREE_FLAG; + heap->first_block.next_free = first_free_block; + + /* free bytes is: + - total bytes in heap + - minus heap_t header at top (includes heap->first_block) + - minus header of first_free_block + - minus whole block at heap->last_block + */ + heap->free_bytes = HEAP_ALIGN(size) - sizeof(heap_t) - sizeof(first_free_block->header) - sizeof(heap_block_t); + heap->minimum_free_bytes = heap->free_bytes; + heap->total_bytes = HEAP_ALIGN(size); + return heap; +} + +void multi_heap_set_lock(multi_heap_handle_t heap, void *lock) +{ + heap->lock = lock; +} + +void inline multi_heap_internal_lock(multi_heap_handle_t heap) +{ + MULTI_HEAP_LOCK(heap->lock); +} + +void inline multi_heap_internal_unlock(multi_heap_handle_t heap) +{ + MULTI_HEAP_UNLOCK(heap->lock); +} + +multi_heap_block_handle_t multi_heap_get_first_block(multi_heap_handle_t heap) +{ + return &heap->first_block; +} + +multi_heap_block_handle_t multi_heap_get_next_block(multi_heap_handle_t heap, multi_heap_block_handle_t block) +{ + heap_block_t *next = get_next_block(block); + /* check for valid free last block to avoid assert in assert_valid_block */ + if (next == heap->last_block && is_last_block(next) && is_free(next)) { + return NULL; + } + assert_valid_block(heap, next); + return next; +} + +bool multi_heap_is_free(multi_heap_block_handle_t block) +{ + return is_free(block); +} + +void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size) +{ + heap_block_t *best_block = NULL; + heap_block_t *prev_free = NULL; + heap_block_t *prev = NULL; + size_t best_size = SIZE_MAX; + size = HEAP_ALIGN_UP(size); + + if (size == 0 || heap == NULL) { + return NULL; + } + + multi_heap_internal_lock(heap); + + /* Note: this check must be done while holding the lock as both + malloc & realloc may temporarily shrink the free_bytes value + before they split a large block. This can result in false negatives, + especially if the heap is unfragmented. + */ + if (heap->free_bytes < size) { + MULTI_HEAP_UNLOCK(heap->lock); + ASSERT(0, "[%s] need size = %d, heap->free_bytes = %d", __func__, size, heap->free_bytes); + return NULL; + } + + /* Find best free block to perform the allocation in */ + prev = &heap->first_block; + for (heap_block_t *b = heap->first_block.next_free; b != NULL; b = b->next_free) { + MULTI_HEAP_ASSERT(b > prev, &prev->next_free); // free blocks should be ascending in address + MULTI_HEAP_ASSERT(is_free(b), b); // block should be free + size_t bs = block_data_size(b); + if (bs >= size && bs < best_size) { + best_block = b; + best_size = bs; + prev_free = prev; + if (bs == size) { + break; /* we've found a perfect sized block */ + } + } + prev = b; + } + + if (best_block == NULL) { + multi_heap_internal_unlock(heap); + return NULL; /* No room in heap */ + } + + prev_free->next_free = best_block->next_free; + best_block->header &= ~BLOCK_FREE_FLAG; + + heap->free_bytes -= block_data_size(best_block); + + split_if_necessary(heap, best_block, size, prev_free); + + if (heap->free_bytes < heap->minimum_free_bytes) { + heap->minimum_free_bytes = heap->free_bytes; + } + + multi_heap_internal_unlock(heap); + + return best_block->data; +} + +void multi_heap_free_impl(multi_heap_handle_t heap, void *p) +{ + heap_block_t *pb = get_block(p); + + if (heap == NULL || p == NULL) { + return; + } + + multi_heap_internal_lock(heap); + + assert_valid_block(heap, pb); + MULTI_HEAP_ASSERT(!is_free(pb), pb); // block should not be free + MULTI_HEAP_ASSERT(!is_last_block(pb), pb); // block should not be last block + MULTI_HEAP_ASSERT(!is_first_block(heap, pb), pb); // block should not be first block + + heap_block_t *next = get_next_block(pb); + + /* Update freelist pointers */ + heap_block_t *prev_free = get_prev_free_block(heap, pb); + // freelist validity check + MULTI_HEAP_ASSERT(prev_free->next_free == NULL || prev_free->next_free > pb, &prev_free->next_free); + pb->next_free = prev_free->next_free; + prev_free->next_free = pb; + + /* Mark this block as free */ + pb->header |= BLOCK_FREE_FLAG; + + heap->free_bytes += block_data_size(pb); + + /* Try and merge previous free block into this one */ + if (get_next_block(prev_free) == pb) { + pb = merge_adjacent(heap, prev_free, pb); + } + + /* If next block is free, try to merge the two */ + if (is_free(next)) { + pb = merge_adjacent(heap, pb, next); + } + + multi_heap_internal_unlock(heap); +} + + +void *multi_heap_realloc_impl(multi_heap_handle_t heap, void *p, size_t size) +{ + heap_block_t *pb = get_block(p); + void *result; + size = HEAP_ALIGN_UP(size); + + assert(heap != NULL); + + if (p == NULL) { + return multi_heap_malloc_impl(heap, size); + } + + assert_valid_block(heap, pb); + // non-null realloc arg should be allocated + MULTI_HEAP_ASSERT(!is_free(pb), pb); + + if (size == 0) { + /* note: calling multi_free_impl() here as we've already been + through any poison-unwrapping */ + multi_heap_free_impl(heap, p); + return NULL; + } + + if (heap == NULL) { + return NULL; + } + + multi_heap_internal_lock(heap); + result = NULL; + + if (size <= block_data_size(pb)) { + // Shrinking.... + split_if_necessary(heap, pb, size, NULL); + result = pb->data; + } + else if (heap->free_bytes < size - block_data_size(pb)) { + // Growing, but there's not enough total free space in the heap + multi_heap_internal_unlock(heap); + return NULL; + } + + // New size is larger than existing block + if (result == NULL) { + // See if we can grow into one or both adjacent blocks + heap_block_t *orig_pb = pb; + size_t orig_size = block_data_size(orig_pb); + heap_block_t *next = get_next_block(pb); + heap_block_t *prev = get_prev_free_block(heap, pb); + + // Can only grow into the previous free block if it's adjacent + size_t prev_grow_size = (get_next_block(prev) == pb) ? block_data_size(prev) : 0; + + // Can grow into next block? (we may also need to grow into 'prev' to get to our desired size) + if (is_free(next) && (block_data_size(pb) + block_data_size(next) + prev_grow_size >= size)) { + pb = merge_adjacent(heap, pb, next); + } + + // Can grow into previous block? + // (try this even if we're already big enough from growing into 'next', as it reduces fragmentation) + if (prev_grow_size > 0 && (block_data_size(pb) + prev_grow_size >= size)) { + pb = merge_adjacent(heap, prev, pb); + // this doesn't guarantee we'll be left with a big enough block, as it's + // possible for the merge to fail if prev == heap->first_block + } + + if (block_data_size(pb) >= size) { + memmove(pb->data, orig_pb->data, orig_size); + split_if_necessary(heap, pb, size, NULL); + result = pb->data; + } + } + + if (result == NULL) { + // Need to allocate elsewhere and copy data over + // + // (Calling _impl versions here as we've already been through any + // unwrapping for heap poisoning features.) + result = multi_heap_malloc_impl(heap, size); + if (result != NULL) { + memcpy(result, pb->data, block_data_size(pb)); + multi_heap_free_impl(heap, pb->data); + } + } + + if (heap->free_bytes < heap->minimum_free_bytes) { + heap->minimum_free_bytes = heap->free_bytes; + } + + multi_heap_internal_unlock(heap); + return result; +} + +#define FAIL_PRINT(num,MSG, ...) do { \ + if (print_errors) { \ + MULTI_HEAP_STDERR_PRINTF(num,MSG, __VA_ARGS__); \ + } \ + valid = false; \ + } \ + while(0) + +bool multi_heap_check(multi_heap_handle_t heap, bool print_errors) +{ + bool valid = true; + size_t total_free_bytes = 0; + assert(heap != NULL); + + multi_heap_internal_lock(heap); + + heap_block_t *prev = NULL; + heap_block_t *prev_free = NULL; + heap_block_t *expected_free = NULL; + + /* note: not using get_next_block() in loop, so that assertions aren't checked here */ + for(heap_block_t *b = &heap->first_block; b != NULL; b = (heap_block_t *)(b->header & NEXT_BLOCK_MASK)) { + if (b == prev) { + FAIL_PRINT(1,"CORRUPT HEAP: Block %p points to itself\n", b); + goto done; + } + if (b < prev) { + FAIL_PRINT(2,"CORRUPT HEAP: Block %p is before prev block %p\n", b, prev); + goto done; + } + if (b > heap->last_block || b < &heap->first_block) { + FAIL_PRINT(2,"CORRUPT HEAP: Block %p is outside heap (last valid block %p)\n", b, prev); + goto done; + } + if (is_free(b)) { + if (prev != NULL && is_free(prev) && !is_first_block(heap, prev) && !is_last_block(b)) { + FAIL_PRINT(2,"CORRUPT HEAP: Two adjacent free blocks found, %p and %p\n", prev, b); + } + if (expected_free != NULL && expected_free != b) { + FAIL_PRINT(3,"CORRUPT HEAP: Prev free block %p pointed to next free %p but this free block is %p\n", + prev_free, expected_free, b); + } + prev_free = b; + expected_free = b->next_free; + if (!is_first_block(heap, b)) { + total_free_bytes += block_data_size(b); + } + } + prev = b; + +#ifdef MULTI_HEAP_POISONING + if (!is_last_block(b)) { + /* For slow heap poisoning, any block should contain correct poisoning patterns and/or fills */ + bool poison_ok; + if (is_free(b) && b != heap->last_block) { + uint32_t block_len = (intptr_t)get_next_block(b) - (intptr_t)b - sizeof(heap_block_t); + poison_ok = multi_heap_internal_check_block_poisoning(&b[1], block_len, true, print_errors); + } + else { + poison_ok = multi_heap_internal_check_block_poisoning(b->data, block_data_size(b), false, print_errors); + } + valid = poison_ok && valid; + } +#endif + + } /* for(heap_block_t b = ... */ + + if (prev != heap->last_block) { + FAIL_PRINT(2,"CORRUPT HEAP: Last block %p not %p\n", prev, heap->last_block); + } + if (!is_free(heap->last_block)) { + FAIL_PRINT(1,"CORRUPT HEAP: Expected prev block %p to be free\n", heap->last_block); + } + + if (heap->free_bytes != total_free_bytes) { + FAIL_PRINT(2,"CORRUPT HEAP: Expected %u free bytes counted %u\n", (unsigned)heap->free_bytes, (unsigned)total_free_bytes); + } + + done: + multi_heap_internal_unlock(heap); + + return valid; +} + +void multi_heap_dump(multi_heap_handle_t heap) +{ + assert(heap != NULL); + + multi_heap_internal_lock(heap); + MULTI_HEAP_STDERR_PRINTF(3,"Heap start %p end %p\nFirst free block %p\n", &heap->first_block, heap->last_block, heap->first_block.next_free); + for(heap_block_t *b = &heap->first_block; b != NULL; b = get_next_block(b)) { + MULTI_HEAP_STDERR_PRINTF(3,"Block %p data size 0x%08x bytes next block %p", b, block_data_size(b), get_next_block(b)); + if (is_free(b)) { + MULTI_HEAP_STDERR_PRINTF(1," FREE. Next free %p\n", b->next_free); + } else { + MULTI_HEAP_STDERR_PRINTF(1,"%s", "\n"); /* C macros & optional __VA_ARGS__ */ + } + } + multi_heap_internal_unlock(heap); +} + +size_t multi_heap_free_size_impl(multi_heap_handle_t heap) +{ + if (heap == NULL) { + return 0; + } + return heap->free_bytes; +} + +size_t multi_heap_minimum_free_size_impl(multi_heap_handle_t heap) +{ + if (heap == NULL) { + return 0; + } + return heap->minimum_free_bytes; +} + +void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info) +{ + memset(info, 0, sizeof(multi_heap_info_t)); + + if (heap == NULL) { + return; + } + + multi_heap_internal_lock(heap); + for(heap_block_t *b = get_next_block(&heap->first_block); !is_last_block(b); b = get_next_block(b)) { + info->total_blocks++; + if (is_free(b)) { + size_t s = block_data_size(b); + info->total_free_bytes += s; + if (s > info->largest_free_block) { + info->largest_free_block = s; + } + info->free_blocks++; + } else { + info->total_allocated_bytes += block_data_size(b); + info->allocated_blocks++; + } + } + + info->minimum_free_bytes = heap->minimum_free_bytes; + info->total_bytes = heap->total_bytes; + // heap has wrong total size (address printed here is not indicative of the real error) + MULTI_HEAP_ASSERT(info->total_free_bytes == heap->free_bytes, heap); + + multi_heap_internal_unlock(heap); + +} \ No newline at end of file diff --git a/utils/heap/multi_heap.h b/utils/heap/multi_heap.h new file mode 100644 index 0000000..707b6ee --- /dev/null +++ b/utils/heap/multi_heap.h @@ -0,0 +1,172 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// 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. +#pragma once +#include +#include +#include + +/* multi_heap is a heap implementation for handling multiple + heterogenous heaps in a single program. + + Any contiguous block of memory can be registered as a heap. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Opaque handle to a registered heap */ +typedef struct multi_heap_info *multi_heap_handle_t; + +/** @brief malloc() a buffer in a given heap + * + * Semantics are the same as standard malloc(), only the returned buffer will be allocated in the specified heap. + * + * @param heap Handle to a registered heap. + * @param size Size of desired buffer. + * + * @return Pointer to new memory, or NULL if allocation fails. + */ +void *multi_heap_malloc(multi_heap_handle_t heap, size_t size); + +/** @brief free() a buffer in a given heap. + * + * Semantics are the same as standard free(), only the argument 'p' must be NULL or have been allocated in the specified heap. + * + * @param heap Handle to a registered heap. + * @param p NULL, or a pointer previously returned from multi_heap_malloc() or multi_heap_realloc() for the same heap. + */ +void multi_heap_free(multi_heap_handle_t heap, void *p); + +/** @brief realloc() a buffer in a given heap. + * + * Semantics are the same as standard realloc(), only the argument 'p' must be NULL or have been allocated in the specified heap. + * + * @param heap Handle to a registered heap. + * @param p NULL, or a pointer previously returned from multi_heap_malloc() or multi_heap_realloc() for the same heap. + * @param size Desired new size for buffer. + * + * @return New buffer of 'size' containing contents of 'p', or NULL if reallocation failed. + */ +void *multi_heap_realloc(multi_heap_handle_t heap, void *p, size_t size); + + +/** @brief Return the size that a particular pointer was allocated with. + * + * @param heap Handle to a registered heap. + * @param p Pointer, must have been previously returned from multi_heap_malloc() or multi_heap_realloc() for the same heap. + * + * @return Size of the memory allocated at this block. May be more than the original size argument, due + * to padding and minimum block sizes. + */ +size_t multi_heap_get_allocated_size(multi_heap_handle_t heap, void *p); + + +/** @brief Register a new heap for use + * + * This function initialises a heap at the specified address, and returns a handle for future heap operations. + * + * There is no equivalent function for deregistering a heap - if all blocks in the heap are free, you can immediately start using the memory for other purposes. + * + * @param start Start address of the memory to use for a new heap. + * @param size Size (in bytes) of the new heap. + * + * @return Handle of a new heap ready for use, or NULL if the heap region was too small to be initialised. + */ +multi_heap_handle_t multi_heap_register(void *start, size_t size); + + +/** @brief Associate a private lock pointer with a heap + * + * The lock argument is supplied to the MULTI_HEAP_LOCK() and MULTI_HEAP_UNLOCK() macros, defined in multi_heap_platform.h. + * + * The lock in question must be recursive. + * + * When the heap is first registered, the associated lock is NULL. + * + * @param heap Handle to a registered heap. + * @param lock Optional pointer to a locking structure to associate with this heap. + */ +void multi_heap_set_lock(multi_heap_handle_t heap, void* lock); + +/** @brief Dump heap information to stdout + * + * For debugging purposes, this function dumps information about every block in the heap to stdout. + * + * @param heap Handle to a registered heap. + */ +void multi_heap_dump(multi_heap_handle_t heap); + +/** @brief Check heap integrity + * + * Walks the heap and checks all heap data structures are valid. If any errors are detected, an error-specific message + * can be optionally printed to stderr. Print behaviour can be overriden at compile time by defining + * MULTI_CHECK_FAIL_PRINTF in multi_heap_platform.h. + * + * @param heap Handle to a registered heap. + * @param print_errors If true, errors will be printed to stderr. + * @return true if heap is valid, false otherwise. + */ +bool multi_heap_check(multi_heap_handle_t heap, bool print_errors); + +/** @brief Return free heap size + * + * Returns the number of bytes available in the heap. + * + * Equivalent to the total_free_bytes member returned by multi_heap_get_heap_info(). + * + * Note that the heap may be fragmented, so the actual maximum size for a single malloc() may be lower. To know this + * size, see the largest_free_block member returned by multi_heap_get_heap_info(). + * + * @param heap Handle to a registered heap. + * @return Number of free bytes. + */ +size_t multi_heap_free_size(multi_heap_handle_t heap); + +/** @brief Return the lifetime minimum free heap size + * + * Equivalent to the minimum_free_bytes member returned by multi_heap_get_info(). + * + * Returns the lifetime "low water mark" of possible values returned from multi_free_heap_size(), for the specified + * heap. + * + * @param heap Handle to a registered heap. + * @return Number of free bytes. + */ +size_t multi_heap_minimum_free_size(multi_heap_handle_t heap); + +/** @brief Structure to access heap metadata via multi_heap_get_info */ +typedef struct { + size_t total_free_bytes; ///< Total free bytes in the heap. Equivalent to multi_free_heap_size(). + size_t total_allocated_bytes; ///< Total bytes allocated to data in the heap. + size_t largest_free_block; ///< Size of largest free block in the heap. This is the largest malloc-able size. + size_t minimum_free_bytes; ///< Lifetime minimum free heap size. Equivalent to multi_minimum_free_heap_size(). + size_t allocated_blocks; ///< Number of (variable size) blocks allocated in the heap. + size_t free_blocks; ///< Number of (variable size) free blocks in the heap. + size_t total_blocks; ///< Total number of (variable size) blocks in the heap. + size_t total_bytes; +} multi_heap_info_t; + +/** @brief Return metadata about a given heap + * + * Fills a multi_heap_info_t structure with information about the specified heap. + * + * @param heap Handle to a registered heap. + * @param info Pointer to a structure to fill with heap metadata. + */ +void multi_heap_get_info(multi_heap_handle_t heap, multi_heap_info_t *info); + +#ifdef __cplusplus +} +#endif diff --git a/utils/heap/multi_heap_internal.h b/utils/heap/multi_heap_internal.h new file mode 100644 index 0000000..95c9614 --- /dev/null +++ b/utils/heap/multi_heap_internal.h @@ -0,0 +1,70 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// 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. +#pragma once + +#define MULTI_HEAP_DEFAULT_INT_LOCK (1) + +/* Opaque handle to a heap block */ +typedef const struct heap_block *multi_heap_block_handle_t; + +/* Internal definitions for the "implementation" of the multi_heap API, + as defined in multi_heap.c. + + If heap poisioning is disabled, these are aliased directly to the public API. + + If heap poisoning is enabled, wrapper functions call each of these. +*/ +void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size); +void multi_heap_free_impl(multi_heap_handle_t heap, void *p); +void *multi_heap_realloc_impl(multi_heap_handle_t heap, void *p, size_t size); +multi_heap_handle_t multi_heap_register_impl(void *start, size_t size); +void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info); +size_t multi_heap_free_size_impl(multi_heap_handle_t heap); +size_t multi_heap_minimum_free_size_impl(multi_heap_handle_t heap); +size_t multi_heap_get_allocated_size_impl(multi_heap_handle_t heap, void *p); +void *multi_heap_get_block_address_impl(multi_heap_block_handle_t block); + +/* Some internal functions for heap poisoning use */ + +/* Check an allocated block's poison bytes are correct. Called by multi_heap_check(). */ +bool multi_heap_internal_check_block_poisoning(void *start, size_t size, bool is_free, bool print_errors); + +/* Fill a region of memory with the free or malloced pattern. + Called when merging blocks, to overwrite the old block header. +*/ +void multi_heap_internal_poison_fill_region(void *start, size_t size, bool is_free); + +/* Allow heap poisoning to lock/unlock the heap to avoid race conditions + if multi_heap_check() is running concurrently. +*/ +void multi_heap_internal_lock(multi_heap_handle_t heap); + +void multi_heap_internal_unlock(multi_heap_handle_t heap); + +/* Some internal functions for heap debugging code to use */ + +/* Get the handle to the first (fixed free) block in a heap */ +multi_heap_block_handle_t multi_heap_get_first_block(multi_heap_handle_t heap); + +/* Get the handle to the next block in a heap, with validation */ +multi_heap_block_handle_t multi_heap_get_next_block(multi_heap_handle_t heap, multi_heap_block_handle_t block); + +/* Test if a heap block is free */ +bool multi_heap_is_free(const multi_heap_block_handle_t block); + +/* Get the data address of a heap block */ +void *multi_heap_get_block_address(multi_heap_block_handle_t block); + +/* Get the owner identification for a heap block */ +void *multi_heap_get_block_owner(multi_heap_block_handle_t block); diff --git a/utils/heap/multi_heap_platform.h b/utils/heap/multi_heap_platform.h new file mode 100644 index 0000000..8719f53 --- /dev/null +++ b/utils/heap/multi_heap_platform.h @@ -0,0 +1,93 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// 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. +#pragma once + +#ifdef ESP_PLATFORM + +#include +#include +#include + +/* Because malloc/free can happen inside an ISR context, + we need to use portmux spinlocks here not RTOS mutexes */ +#define MULTI_HEAP_LOCK(PLOCK) do { \ + if((PLOCK) != NULL) { \ + portENTER_CRITICAL((portMUX_TYPE *)(PLOCK)); \ + } \ + } while(0) + + +#define MULTI_HEAP_UNLOCK(PLOCK) do { \ + if ((PLOCK) != NULL) { \ + portEXIT_CRITICAL((portMUX_TYPE *)(PLOCK)); \ + } \ + } while(0) + +/* Not safe to use std i/o while in a portmux critical section, + can deadlock, so we use the ROM equivalent functions. */ + +#define MULTI_HEAP_PRINTF ets_printf +#define MULTI_HEAP_STDERR_PRINTF(MSG, ...) ets_printf(MSG, __VA_ARGS__) + +inline static void multi_heap_assert(bool condition, const char *format, int line, intptr_t address) +{ + /* Can't use libc assert() here as it calls printf() which can cause another malloc() for a newlib lock. + + Also, it's useful to be able to print the memory address where corruption was detected. + */ +#ifndef NDEBUG + if(!condition) { +#ifndef CONFIG_OPTIMIZATION_ASSERTIONS_SILENT + ets_printf(format, line, address); +#endif // CONFIG_OPTIMIZATION_ASSERTIONS_SILENT + abort(); + } +#else // NDEBUG + (void) condition; +#endif // NDEBUG +} + +#define MULTI_HEAP_ASSERT(CONDITION, ADDRESS) \ + multi_heap_assert((CONDITION), "CORRUPT HEAP: multi_heap.c:%d detected at 0x%08x\n", \ + __LINE__, (intptr_t)(ADDRESS)) + +#ifdef CONFIG_HEAP_TASK_TRACKING +#include +#define MULTI_HEAP_BLOCK_OWNER TaskHandle_t task; +#define MULTI_HEAP_SET_BLOCK_OWNER(HEAD) (HEAD)->task = xTaskGetCurrentTaskHandle() +#define MULTI_HEAP_GET_BLOCK_OWNER(HEAD) ((HEAD)->task) +#else +#define MULTI_HEAP_BLOCK_OWNER +#define MULTI_HEAP_SET_BLOCK_OWNER(HEAD) +#define MULTI_HEAP_GET_BLOCK_OWNER(HEAD) (NULL) +#endif + +#else // ESP_PLATFORM +#include "stdint.h" +#include "cmsis.h" +#include "assert.h" +#include "hal_trace.h" + +#define MULTI_HEAP_PRINTF hal_trace_printf +#define MULTI_HEAP_STDERR_PRINTF(num,MSG, ...) hal_trace_printf(num,MSG, __VA_ARGS__) +#define MULTI_HEAP_LOCK(PLOCK) do {if((PLOCK) != NULL) { uint32_t lockd = int_lock(); *((uint32_t *)(PLOCK)) = lockd; }} while (0) +#define MULTI_HEAP_UNLOCK(PLOCK) do {if((PLOCK) != NULL) { int_unlock(*(((uint32_t *)(PLOCK))));}} while(0) + +#define MULTI_HEAP_ASSERT(CONDITION, ADDRESS) do {if (!(CONDITION)) {assert(0 && "Heap corrupt");} } while (0) + +#define MULTI_HEAP_BLOCK_OWNER +#define MULTI_HEAP_SET_BLOCK_OWNER(HEAD) +#define MULTI_HEAP_GET_BLOCK_OWNER(HEAD) (NULL) + +#endif diff --git a/utils/heap/pool_api.c b/utils/heap/pool_api.c new file mode 100644 index 0000000..adff440 --- /dev/null +++ b/utils/heap/pool_api.c @@ -0,0 +1,97 @@ +#include "heap_api.h" +#include "hal_trace.h" + +extern uint8_t __StackLimit[]; +extern uint8_t __HeapLimit[]; + +uint8_t *syspool_addr = NULL; +uint32_t syspool_size = 0; + +static uint32_t syspoll_used = 0; + +static void syspool_init_addr(void) +{ + syspool_addr = __HeapLimit; + syspool_size = syspool_original_size(); +} + +uint32_t syspool_original_size(void) +{ + return __StackLimit - __HeapLimit - 512; +} + +void syspool_init() +{ + syspool_init_addr(); + syspoll_used = 0; + memset(syspool_addr,0,syspool_size); + TRACE(2,"syspool_init: %p,0x%x",syspool_addr,syspool_size); +} + +void syspool_init_specific_size(uint32_t size) +{ + syspool_init_addr(); + syspoll_used = 0; + TRACE(2,"syspool_init_specific_size: %d/%d",size, syspool_size); + if(size 0x1000) { + line_buf[pos++] = hex_asc_upper[(i >> 12) & 0xF]; + } + if (len > 0x100) { + line_buf[pos++] = hex_asc_upper[(i >> 8) & 0xF]; + } + if (len > 0x10) { + line_buf[pos++] = hex_asc_upper[(i >> 4) & 0xF]; + } + line_buf[pos++] = hex_asc_upper[(i & 0xF)]; + line_buf[pos++] = ':'; + for (j = 0; j < line_len && pos + 3 < sizeof(line_buf); j++) { + line_buf[pos++] = ' '; + line_buf[pos++] = hex_asc_upper[(buf[i + j] & 0xF0) >> 4]; + line_buf[pos++] = hex_asc_upper[(buf[i + j] & 0x0F)]; + } +#ifndef __ARM_EABI__ + if (pos < sizeof(line_buf)) { + line_buf[pos++] = '\0'; + } else { + line_buf[sizeof(line_buf) - 1] = '\0'; + } + printf("%s\r\n", line_buf); +#else + if (pos < sizeof(line_buf)) { + line_buf[pos++] = '\0'; + } else { + line_buf[sizeof(line_buf) - 1] = '\0'; + } + LOG_INFO(LOG_ATTR_NO_ID | (now ? LOG_ATTR_IMM : 0), line_buf); +#endif + } +} + +void dump_buffer(const void *buf, size_t len) +{ + dump_buffer_internal((const unsigned char *)buf, len, 0); +} + +void dump_buffer_imm(const void *buf, size_t len) +{ + dump_buffer_internal((const unsigned char *)buf, len, 1); +} + diff --git a/utils/hexdump/hexdump.h b/utils/hexdump/hexdump.h new file mode 100644 index 0000000..2460394 --- /dev/null +++ b/utils/hexdump/hexdump.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HEXDUMP_H__ +#define __HEXDUMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void dump_buffer(const void *buf, size_t len); + +void dump_buffer_imm(const void *buf, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/utils/hwtimer_list/Makefile b/utils/hwtimer_list/Makefile new file mode 100644 index 0000000..a10e024 --- /dev/null +++ b/utils/hwtimer_list/Makefile @@ -0,0 +1,11 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj-y := $(obj-y:.c=.o) + +ccflags-y := -Iplatform/hal -Iplatform/cmsis + +ifneq ($(HWTIMER_NUM),) +ccflags-y += -DHWTIMER_NUM=$(HWTIMER_NUM) +endif + diff --git a/utils/hwtimer_list/hwtimer_list.c b/utils/hwtimer_list/hwtimer_list.c new file mode 100644 index 0000000..9053d7e --- /dev/null +++ b/utils/hwtimer_list/hwtimer_list.c @@ -0,0 +1,587 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "plat_types.h" +#include "hwtimer_list.h" +#define IGNORE_HAL_TIMER_RAW_API_CHECK +#include "hal_timer_raw.h" +#include "hal_trace.h" +#include "stdio.h" +#include "cmsis.h" + +#if defined(ROM_BUILD) && !defined(SIMU) && !defined(FPGA) +#error "The user of raw timer API must be unique. Now rom is using raw timer API." +#endif + +#define CHECK_ACTIVE_NULL_IN_IRQ 1 + +#ifndef HWTIMER_NUM +#define HWTIMER_NUM 10 +#endif + +//#define HWTIMER_TEST + +enum HWTIMER_STATE_T { + HWTIMER_STATE_FREE = 0, + HWTIMER_STATE_ALLOC, + HWTIMER_STATE_ACTIVE, + HWTIMER_STATE_FIRED, + HWTIMER_STATE_CALLBACK, + + HWTIMER_STATE_QTY +}; + +struct HWTIMER_T { + enum HWTIMER_STATE_T state; + struct HWTIMER_T *next; + uint32_t time; + HWTIMER_CALLBACK_T callback; + void *param; +}; + +struct HWTIMER_LIST_T { + struct HWTIMER_T timer[HWTIMER_NUM]; + struct HWTIMER_T *free; + struct HWTIMER_T *active; + struct HWTIMER_T *fired; +}; + +static struct HWTIMER_LIST_T hwtimer_list; +static uint32_t err_irq_active_null = 0; +static uint32_t err_irq_early = 0; + +static void hwtimer_handler(uint32_t elapsed) +{ + struct HWTIMER_T *pre; + struct HWTIMER_T *last; + uint32_t lock = 0; + + lock = int_lock(); + + if (hwtimer_list.active == NULL) { + err_irq_active_null++; + TRACE(1,"HWTIMER irq when active is null: might be deleted? %u", err_irq_active_null); +#if (CHECK_ACTIVE_NULL_IN_IRQ) + ASSERT(hal_timer_is_enabled() == 0, "HWTIMER collapsed: irq when active is null"); +#endif + goto _exit; + } + // Update elapsed time + elapsed = hal_timer_get_elapsed_time(); + if (hwtimer_list.active->time > elapsed + HAL_TIMER_LOAD_DELTA) { + err_irq_early++; + TRACE(1,"HWTIMER irq occurred early: old active timer might be deleted? %u", err_irq_early); + ASSERT(hal_timer_is_enabled(), "HWTIMER collapsed: irq occurred too early"); + goto _exit; + } + + if (elapsed > hwtimer_list.active->time) { + elapsed -= hwtimer_list.active->time; + } else { + elapsed = 0; + } + pre = hwtimer_list.active; + // TODO: Check state here ? + pre->state = HWTIMER_STATE_FIRED; + last = hwtimer_list.active->next; + while (last && last->time <= elapsed) { + elapsed -= last->time; + pre = last; + // TODO: Check state here ? + pre->state = HWTIMER_STATE_FIRED; + last = last->next; + } + pre->next = NULL; + hwtimer_list.fired = hwtimer_list.active; + hwtimer_list.active = last; + if (last) { + last->time -= elapsed; + hal_timer_start(last->time); +#if (CHECK_ACTIVE_NULL_IN_IRQ) + } else { + hal_timer_stop(); +#endif + } + + while (hwtimer_list.fired) { + last = hwtimer_list.fired; + hwtimer_list.fired = last->next; + // TODO: Check state here ? + last->state = HWTIMER_STATE_CALLBACK; + last->next = NULL; + // Now this timer can be restarted, but not stopped or freed + if (last->callback) { + int_unlock(lock); + last->callback(last->param); + lock = int_lock(); + } + if (last->state == HWTIMER_STATE_CALLBACK) { + last->state = HWTIMER_STATE_ALLOC; + } + } + +_exit: + int_unlock(lock); +} + +void hwtimer_init(void) +{ + int i; + + for (i = 0; i < HWTIMER_NUM - 1; i++) { + hwtimer_list.timer[i].state = HWTIMER_STATE_FREE; + hwtimer_list.timer[i].next = &hwtimer_list.timer[i + 1]; + } + hwtimer_list.timer[HWTIMER_NUM - 1].next = NULL; + hwtimer_list.free = &hwtimer_list.timer[0]; + hwtimer_list.active = NULL; + hwtimer_list.fired = NULL; + hal_timer_setup(HAL_TIMER_TYPE_ONESHOT, hwtimer_handler); +} + +HWTIMER_ID hwtimer_alloc(HWTIMER_CALLBACK_T callback, void *param) +{ + struct HWTIMER_T *timer; + uint32_t lock; + + timer = NULL; + + lock = int_lock(); + if (hwtimer_list.free != NULL) { + timer = hwtimer_list.free; + hwtimer_list.free = hwtimer_list.free->next; + } + int_unlock(lock); + + if (timer == NULL) { + return NULL; + } + + ASSERT(timer->state == HWTIMER_STATE_FREE, "HWTIMER-ALLOC: Invalid state: %d", timer->state); + timer->state = HWTIMER_STATE_ALLOC; + timer->callback = callback; + timer->param = param; + timer->next = NULL; + + return timer; +} + +enum E_HWTIMER_T hwtimer_free(HWTIMER_ID id) +{ + enum E_HWTIMER_T ret; + struct HWTIMER_T *timer; + uint32_t lock; + + timer = (struct HWTIMER_T *)id; + + if (timer < &hwtimer_list.timer[0] || timer > &hwtimer_list.timer[HWTIMER_NUM - 1]) { + return E_HWTIMER_INVAL_ID; + } + + ret = E_HWTIMER_OK; + + lock = int_lock(); + + if (timer->state != HWTIMER_STATE_ALLOC) { + ret = E_HWTIMER_INVAL_ST; + goto _exit; + } + timer->state = HWTIMER_STATE_FREE; + + timer->next = hwtimer_list.free; + hwtimer_list.free = timer; + +_exit: + int_unlock(lock); + + return ret; +} + +static enum E_HWTIMER_T __hwtimer_start_int(HWTIMER_ID id, int update, HWTIMER_CALLBACK_T callback, void *param, unsigned int ticks) +{ + enum E_HWTIMER_T ret; + struct HWTIMER_T *timer; + struct HWTIMER_T *pre; + struct HWTIMER_T *next; + uint32_t lock; + uint32_t cur_time; + + timer = (struct HWTIMER_T *)id; + + if (timer < &hwtimer_list.timer[0] || timer > &hwtimer_list.timer[HWTIMER_NUM - 1]) { + return E_HWTIMER_INVAL_ID; + } + + if (ticks < HAL_TIMER_LOAD_DELTA) { + ticks = HAL_TIMER_LOAD_DELTA; + } + + ret = E_HWTIMER_OK; + + lock = int_lock(); + + if (timer->state != HWTIMER_STATE_ALLOC && timer->state != HWTIMER_STATE_CALLBACK) { + ret = E_HWTIMER_INVAL_ST; + goto _exit; + } + timer->state = HWTIMER_STATE_ACTIVE; + + if (update) { + timer->callback = callback; + timer->param = param; + } + + if (hwtimer_list.active == NULL) { + timer->next = NULL; + hwtimer_list.active = timer; + hal_timer_start(ticks); + } else { + cur_time = hal_timer_get(); + ASSERT(cur_time <= hwtimer_list.active->time || cur_time <= HAL_TIMER_LOAD_DELTA, + "HWTIMER-START collapsed: cur=%u active=%u", + cur_time, hwtimer_list.active->time); + if (cur_time > ticks) { + hwtimer_list.active->time = cur_time - ticks; + timer->next = hwtimer_list.active; + hwtimer_list.active = timer; + hal_timer_stop(); + hal_timer_start(ticks); + } else { + pre = hwtimer_list.active; + next = hwtimer_list.active->next; + ticks -= cur_time; + while (next && next->time < ticks) { + ticks -= next->time; + pre = next; + next = next->next; + } + if (next) { + next->time -= ticks; + } + pre->next = timer; + timer->next = next; + } + } + timer->time = ticks; + +_exit: + int_unlock(lock); + + return ret; +} + +enum E_HWTIMER_T hwtimer_start(HWTIMER_ID id, unsigned int ticks) +{ + return __hwtimer_start_int(id, 0, NULL, NULL, ticks); +} + +enum E_HWTIMER_T hwtimer_update_then_start(HWTIMER_ID id, HWTIMER_CALLBACK_T callback, void *param, unsigned int ticks) +{ + return __hwtimer_start_int(id, 1, callback, param, ticks); +} + +enum E_HWTIMER_T hwtimer_update(HWTIMER_ID id, HWTIMER_CALLBACK_T callback, void *param) +{ + enum E_HWTIMER_T ret; + struct HWTIMER_T *timer; + uint32_t lock; + + timer = (struct HWTIMER_T *)id; + + if (timer < &hwtimer_list.timer[0] || timer > &hwtimer_list.timer[HWTIMER_NUM - 1]) { + return E_HWTIMER_INVAL_ID; + } + + ret = E_HWTIMER_OK; + + lock = int_lock(); + + if (timer->state == HWTIMER_STATE_ALLOC || timer->state == HWTIMER_STATE_CALLBACK) { + timer->callback = callback; + timer->param = param; + } else { + ret = E_HWTIMER_INVAL_ST; + } + + int_unlock(lock); + + return ret; +} + +enum E_HWTIMER_T hwtimer_stop(HWTIMER_ID id) +{ + enum E_HWTIMER_T ret; + struct HWTIMER_T *timer; + struct HWTIMER_T *pre; + struct HWTIMER_T *next; + uint32_t cur_time; + uint32_t elapsed_time; + uint32_t lock; + + timer = (struct HWTIMER_T *)id; + + if (timer < &hwtimer_list.timer[0] || timer > &hwtimer_list.timer[HWTIMER_NUM - 1]) { + return E_HWTIMER_INVAL_ID; + } + + ret = E_HWTIMER_OK; + + lock = int_lock(); + + if (timer->state == HWTIMER_STATE_ALLOC) { + // Already stopped + goto _exit; + } else if (timer->state == HWTIMER_STATE_ACTIVE) { + // Active timer + if (hwtimer_list.active == timer) { + cur_time = hal_timer_get(); + ASSERT(cur_time <= hwtimer_list.active->time || cur_time <= HAL_TIMER_LOAD_DELTA, + "HWTIMER-STOP collapsed: cur=%u active=%u", + cur_time, hwtimer_list.active->time); + hal_timer_stop(); + next = hwtimer_list.active->next; + if (next) { + if (cur_time == 0) { + elapsed_time = hal_timer_get_elapsed_time(); + ASSERT(elapsed_time + HAL_TIMER_LOAD_DELTA >= hwtimer_list.active->time, + "HWTIMER-STOP collapsed: elapsed=%u active=%u", + elapsed_time, hwtimer_list.active->time); + if (elapsed_time > hwtimer_list.active->time) { + elapsed_time -= hwtimer_list.active->time; + } else { + elapsed_time = 0; + } + pre = next; + while (pre && pre->time <= elapsed_time) { + elapsed_time -= pre->time; + pre->time = 0; + pre = pre->next; + } + if (pre) { + pre->time -= elapsed_time; + } + } else { + next->time += cur_time; + } + hal_timer_start(next->time); + } + hwtimer_list.active = next; + } else if (hwtimer_list.active) { + pre = hwtimer_list.active; + next = hwtimer_list.active->next; + while (next && next != timer) { + pre = next; + next = next->next; + } + if (next == timer) { + pre->next = next->next; + if (next->next) { + next->next->time += timer->time; + } + } else { + ret = E_HWTIMER_NOT_FOUND; + } + } else { + ret = E_HWTIMER_NOT_FOUND; + } + ASSERT(ret == E_HWTIMER_OK, "HWTIMER-STOP collapsed: active timer 0x%08x not in list 0x%08x", + (uint32_t)timer, (uint32_t)hwtimer_list.active); + } else if (timer->state == HWTIMER_STATE_FIRED) { + // Fired timer + if (hwtimer_list.fired == timer) { + // The timer handler is preempted + hwtimer_list.fired = hwtimer_list.fired->next; + } else if (hwtimer_list.fired) { + pre = hwtimer_list.fired; + next = hwtimer_list.fired->next; + while (next && next != timer) { + pre = next; + next = next->next; + } + if (next == timer) { + pre->next = next->next; + } else { + ret = E_HWTIMER_NOT_FOUND; + } + } else { + ret = E_HWTIMER_NOT_FOUND; + } + ASSERT(ret == E_HWTIMER_OK, "HWTIMER-STOP collapsed: fired timer 0x%08x not in list 0x%08x", + (uint32_t)timer, (uint32_t)hwtimer_list.fired); + } else if (timer->state == HWTIMER_STATE_CALLBACK) { + // The timer handler is preempted and timer is being handled + ret = E_HWTIMER_IN_CALLBACK; + } else { + // Invalid state + ret = E_HWTIMER_INVAL_ST; + } + + if (ret == E_HWTIMER_OK) { + timer->state = HWTIMER_STATE_ALLOC; + timer->next = NULL; + } + +_exit: + int_unlock(lock); + + return ret; +} + +#ifdef HWTIMER_TEST + +int hwtimer_get_index(HWTIMER_ID id) +{ + struct HWTIMER_T *timer; + int i; + + timer = (struct HWTIMER_T *)id; + + if (timer < &hwtimer_list.timer[0] || timer > &hwtimer_list.timer[HWTIMER_NUM - 1]) { + return -1; + } + + for (i = 0; i < HWTIMER_NUM; i++) { + if (timer == &hwtimer_list.timer[i]) { + return i; + } + } + + return -1; +} + +void hwtimer_dump(void) +{ + int i; + int idx; + bool checked[HWTIMER_NUM]; + char buf[100], *pos; + const char *end = buf + sizeof(buf); + struct HWTIMER_T *timer; + uint32_t lock; + enum HWTIMER_STATE_T state; + + for (i = 0; i < HWTIMER_NUM; i++) { + checked[i] = false; + } + + TRACE(0,"------\nHWTIMER LIST DUMP"); + lock = int_lock(); + for (i = 0; i < 3; i++) { + pos = buf; + if (i == 0) { + pos += snprintf(pos, end - pos, "ACTIVE: "); + timer = hwtimer_list.active; + state = HWTIMER_STATE_ACTIVE; + } else if (i == 1) { + pos += snprintf(pos, end - pos, "FIRED : "); + timer = hwtimer_list.fired; + state = HWTIMER_STATE_FIRED; + } else { + pos += snprintf(pos, end - pos, "FREE : "); + timer = hwtimer_list.free; + state = HWTIMER_STATE_FREE; + } + while (timer) { + idx = hwtimer_get_index(timer); + if (idx == -1) { + pos += snprintf(pos, end - pos, "", timer); + break; + } else if (checked[idx]) { + pos += snprintf(pos, end - pos, "", idx); + break; + } else if (timer->state != state) { + pos += snprintf(pos, end - pos, " ", timer->state, idx); + } else if (state == HWTIMER_STATE_ACTIVE) { + pos += snprintf(pos, end - pos, "%d-%u ", idx, timer->time); + } else { + pos += snprintf(pos, end - pos, "%d ", idx); + } + checked[idx] = true; + timer = timer->next; + } + TRACE(buf); + } + int_unlock(lock); + pos = buf; + pos += snprintf(pos, end - pos, "ALLOC : "); + for (i = 0; i < HWTIMER_NUM; i++) { + if (!checked[i]) { + if (hwtimer_list.timer[i].state == HWTIMER_STATE_ALLOC) { + pos += snprintf(pos, end - pos, "%d ", i); + } else { + pos += snprintf(pos, end - pos, " ", hwtimer_list.timer[i].state, i); + } + } + } + pos += snprintf(pos, end - pos, "\n------"); + TRACE(buf); +} + +#define HWTIMER_TEST_NUM (HWTIMER_NUM + 2) + +static HWTIMER_ID test_id[HWTIMER_TEST_NUM]; + +static void timer_stop_test(int id) +{ + int ret; + + ret = hwtimer_stop(test_id[id]); + TRACE(3,"[%u] Stop %d / %d", hal_sys_timer_get(), id, ret); + hwtimer_dump(); +} + +static void timer_callback(void *param) +{ + int id; + + id = (int)param; + + TRACE(2,"[%u] TIMER-CALLBACK: %d", hal_sys_timer_get(), id); + + if (id == 3) { + timer_stop_test(3); + timer_stop_test(5); + timer_stop_test(7); + } +} + +void hwtimer_test(void) +{ + int i; + int ret; + uint32_t lock; + + hwtimer_init(); + + for (i = 0; i < HWTIMER_TEST_NUM; i++) { + test_id[i] = hwtimer_alloc(timer_callback, (void *)i); + ret = hwtimer_start(test_id[i], (i + 1) * 10); + TRACE(4,"[%u] START-TIMER: %u / %p / %d", hal_sys_timer_get(), i, test_id[i], ret); + } + + hwtimer_dump(); + + lock = int_lock(); + hal_sys_timer_delay(55); + timer_stop_test(0); + timer_stop_test(2); + int_unlock(lock); + + hal_sys_timer_delay(300); + hwtimer_dump(); +} + +#endif + diff --git a/utils/hwtimer_list/hwtimer_list.h b/utils/hwtimer_list/hwtimer_list.h new file mode 100644 index 0000000..fb49d37 --- /dev/null +++ b/utils/hwtimer_list/hwtimer_list.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __HWTIMER_LIST_H__ +#define __HWTIMER_LIST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *HWTIMER_ID; + +typedef void (*HWTIMER_CALLBACK_T)(void *param); + +enum E_HWTIMER_T { + E_HWTIMER_OK = 0, + E_HWTIMER_FAILED, + E_HWTIMER_INVAL_ID, + E_HWTIMER_INVAL_ST, + E_HWTIMER_IN_CALLBACK, + E_HWTIMER_NOT_FOUND, +}; + +void hwtimer_init(void); + +HWTIMER_ID hwtimer_alloc(HWTIMER_CALLBACK_T callback, void *param); + +enum E_HWTIMER_T hwtimer_free(HWTIMER_ID id); + +enum E_HWTIMER_T hwtimer_start(HWTIMER_ID id, unsigned int ticks); + +enum E_HWTIMER_T hwtimer_update_then_start(HWTIMER_ID id, HWTIMER_CALLBACK_T callback, void *param, unsigned int ticks); + +enum E_HWTIMER_T hwtimer_update(HWTIMER_ID id, HWTIMER_CALLBACK_T callback, void *param); + +enum E_HWTIMER_T hwtimer_stop(HWTIMER_ID id); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/utils/intersyshci/Makefile b/utils/intersyshci/Makefile new file mode 100644 index 0000000..e9cd5c0 --- /dev/null +++ b/utils/intersyshci/Makefile @@ -0,0 +1,50 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)intersyshci.cpp)) + +ifeq ($(ENHANCED_STACK),1) +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)trans_adapt_v2.cpp)) +else +obj_cpp += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)trans_adapt_v1.cpp)) +endif + +src_obj := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +INTERSYSHCI_LIB_NAME := libintersyshci + +ifeq ($(INTERSYS_NO_THREAD),1) +INTERSYSHCI_LIB_NAME := $(INTERSYSHCI_LIB_NAME)_nothread +endif + +ifeq ($(BYPASS_STACK_AUDIO_STREAM),1) +INTERSYSHCI_LIB_NAME := $(INTERSYSHCI_LIB_NAME)_bypasssas +endif + +ifeq ($(ENHANCED_STACK),1) +INTERSYSHCI_LIB_NAME := $(INTERSYSHCI_LIB_NAME)_enhanced_stack +endif + +ifeq ($(KERNEL),RTX) +INTERSYSHCI_LIB_NAME := $(INTERSYSHCI_LIB_NAME)_RTX +endif + +ifeq ($(KERNEL),RTX5) +INTERSYSHCI_LIB_NAME := $(INTERSYSHCI_LIB_NAME)_RTX5 +endif + +$(INTERSYSHCI_LIB_NAME)-y := $(src_obj) +obj-y += $(INTERSYSHCI_LIB_NAME).a +ccflags-y := \ + $(BT_IF_INCLUDES) \ + $(BT_PROFILES_INCLUDES) \ + -Iservices/bt_app/ \ + -Iapps/common/ \ + -Iutils/cqueue \ + -Iplatform/drivers/bt + +ifeq ($(INTERSYS_NO_THREAD),1) +CFLAGS_intersyshci.o += -D_INTERSYS_NO_THREAD_ +endif + diff --git a/utils/intersyshci/intersyshci.h b/utils/intersyshci/intersyshci.h new file mode 100644 index 0000000..d573ea7 --- /dev/null +++ b/utils/intersyshci/intersyshci.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __INTERSYSHCI_H__ +#define __INTERSYSHCI_H__ + +#include "trans_adapt.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +void BESHCI_BufferAvai(void *packet); +void BESHCI_Open(void); +void BESHCI_Close(void); +void BESHCI_Poll(void); +void BESHCI_LockBuffer(void); +void BESHCI_UNLockBuffer(void); +void BESHCI_SCO_Data_Start(void); +void BESHCI_SCO_Data_Stop(void); +void uartrxtx(void const *argument); + +bool BESHCI_Controller_Log_Handler(const unsigned char *p_buff, uint32_t length); +void BESHCI_Dump_A2DP_Seq(const unsigned char *p_buff, uint32_t length); +typedef bool (*intersys_hci_cmd_filter_handler_func)(uint8_t* pbuf, uint32_t length); +void intersys_register_hci_cmd_filter_handler_callback(intersys_hci_cmd_filter_handler_func func); + +#if defined(__cplusplus) +} +#endif + +#endif /* __INTERSYSHCI_H__ */ diff --git a/utils/intersyshci/trans_adapt.h b/utils/intersyshci/trans_adapt.h new file mode 100644 index 0000000..85b2184 --- /dev/null +++ b/utils/intersyshci/trans_adapt.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __TRANS_ADAPT_H__ +#define __TRANS_ADAPT_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(ENHANCED_STACK) +#include "trans_adapt_v2.h" +#else +#include "trans_adapt_v1.h" +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* __TRANS_ADAPT_H__ */ diff --git a/utils/intersyshci/trans_adapt_v1.h b/utils/intersyshci/trans_adapt_v1.h new file mode 100644 index 0000000..9e169c4 --- /dev/null +++ b/utils/intersyshci/trans_adapt_v1.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __TRANS_ADAPT_V1_H__ +#define __TRANS_ADAPT_V1_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +void BESHCI_SendData(void *packet); +int BESHCI_SendBuffer(unsigned char packet_type, unsigned char *packet, int size); +unsigned short hci_h4_receive_msg( const uint8_t *buf, uint32_t size); + +#if defined(__cplusplus) +} +#endif + +#endif /* __TRANS_ADAPT_V1_H__ */ diff --git a/utils/intersyshci/trans_adapt_v2.h b/utils/intersyshci/trans_adapt_v2.h new file mode 100644 index 0000000..292ef06 --- /dev/null +++ b/utils/intersyshci/trans_adapt_v2.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#ifndef __TRANS_ADAPT_V2_H__ +#define __TRANS_ADAPT_V2_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +void BESHCI_SendData(unsigned char type, unsigned short cmd_conn, unsigned short len, unsigned char *buffer); +int BESHCI_SendBuffer(unsigned char packet_type, unsigned char *packet, int size); +unsigned short hci_h4_receive_msg( const uint8_t *buf, uint32_t size); + +#if defined(__cplusplus) +} +#endif + +#endif /* __TRANS_ADAPT_V2_H__ */ diff --git a/utils/kfifo/Makefile b/utils/kfifo/Makefile new file mode 100644 index 0000000..906194e --- /dev/null +++ b/utils/kfifo/Makefile @@ -0,0 +1,22 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -I$(obj)/../../mbed/api/ \ + -I$(obj)/../../mbed/common \ + -I$(obj)/../../mbed/targets/hal/TARGET_BEST/TARGET_BEST100X/TARGET_MBED_BEST1000/ \ + -I$(obj)/../../cmsis/inc/ \ + -I$(obj)/../../mbed/targets/hal/TARGET_BEST/TARGET_BEST100X/ \ + -I$(obj)/../../mbed/hal/ \ + -I$(obj)/../../fs/fat/ \ + -I$(obj)/../../fs/sd/ \ + -I$(obj)/../../fs/fat/ChaN \ + -I$(obj)/../../rtos/rtos/ \ + -I$(obj)/../../iabt/inc/ + +ccflags-y += -DTARGET_LPC1768 -DWORDS_STACK_SIZE=1024 -DOS_TIMERSTKSZ=1024 -D__CORTEX_M4 diff --git a/utils/kfifo/kfifo.c b/utils/kfifo/kfifo.c new file mode 100644 index 0000000..67a08e2 --- /dev/null +++ b/utils/kfifo/kfifo.c @@ -0,0 +1,148 @@ +#include +#include +#include "kfifo.h" +#include "hal_trace.h" + +static int is_power_of_2(unsigned int n) +{ + int r = 0; + if (n != 0 && ((n & (n - 1)) == 0)) + r = 1; + + return r; +} + +void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int len) +{ + ASSERT(is_power_of_2(len), "kfifo_init : len %d not power of 2!!!!!", len); + + fifo->size = len; + fifo->buffer = buffer; + fifo->in = fifo->out = 0; +} +unsigned int kfifo_put(struct kfifo *fifo, unsigned char *buffer, unsigned int len) +{ + unsigned int l; + len = MIN(len, fifo->size - fifo->in + fifo->out); + __sync_synchronize(); + + l = MIN(len, fifo->size - (fifo->in & (fifo->size - 1))); + memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l); + memcpy(fifo->buffer, buffer + l, len - l); + + __sync_synchronize(); + fifo->in += len; + + return len; +} +unsigned int kfifo_get(struct kfifo *fifo, unsigned char *buffer, unsigned int len) +{ + unsigned int l; + len = MIN(len, fifo->in - fifo->out); + __sync_synchronize(); + + l = MIN(len, fifo->size - (fifo->out & (fifo->size - 1))); + memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l); + memcpy(buffer + l, fifo->buffer, len - l); + + __sync_synchronize(); + fifo->out += len; + + return len; +} +unsigned int kfifo_peek(struct kfifo *fifo, unsigned int len_want, unsigned char **buff1, unsigned char **buff2, unsigned int *len1, unsigned int *len2) +{ + unsigned int l,len; + + *buff1 = *buff2 = NULL; + *len1 = *len2 = 0; + len = MIN(len_want, fifo->in - fifo->out); + if (len < len_want) { + return 0; + } + + __sync_synchronize(); + l = MIN(len, fifo->size - (fifo->out & (fifo->size - 1))); + *buff1 = fifo->buffer + (fifo->out & (fifo->size - 1)); + *len1 = l; + if (l < len) { + *buff2 = fifo->buffer; + *len2 = len-l; + } + + return len_want; +} + +unsigned int kfifo_peek_to_buf(struct kfifo *fifo, unsigned char *buff, unsigned int len) +{ + unsigned char *buf1 = NULL, *buf2 = NULL; + unsigned int len1 = 0, len2 = 0; + + kfifo_peek(fifo, len, &buf1, &buf2, &len1, &len2); + + if (len == (len1 + len2)) { + memcpy(buff, buf1, len1); + memcpy(buff + len1, buf2, len2); + } else { + return 0; + } + + return len; +} + +unsigned int kfifo_len(struct kfifo *fifo) +{ + return (fifo->in-fifo->out); +} + +#if 0 +struct kfifo test_kfifo; +unsigned char kfifo_buffer[32]; +void kfifo_test(void) +{ + unsigned char b[10]; + kfifo_init(&test_kfifo, kfifo_buffer, 32); + TRACE(1,"init 32 : fifo size %d", test_kfifo.size); + + kfifo_put(&test_kfifo, "1234567890", 10); + TRACE(1,"put 10 : fifo len %d", kfifo_len(&test_kfifo)); + + kfifo_put(&test_kfifo, "abcdefghij", 10); + TRACE(1,"put 10 : fifo len %d", kfifo_len(&test_kfifo)); + + kfifo_put(&test_kfifo, "!@#$%^&*()", 10); + TRACE(1,"put 10 : fifo len %d", kfifo_len(&test_kfifo)); + + kfifo_put(&test_kfifo, "VVVV", 4); + TRACE(1,"put 4 : fifo len %d", kfifo_len(&test_kfifo)); + + kfifo_get(&test_kfifo, b, 2); + TRACE(1,"get 2 : fifo len %d", kfifo_len(&test_kfifo)); + TRACE(0,"data:"); + for(int i = 0; i < 2; ++i) { + TRACE(1,"%c-", b[i]); + } + TRACE(0," "); + kfifo_get(&test_kfifo, b, 10); + TRACE(1,"get 10 : fifo len %d", kfifo_len(&test_kfifo)); + TRACE(0,"data:"); + for(int i = 0; i < 10; ++i) { + TRACE(1,"%c-", b[i]); + } + TRACE(0," "); + kfifo_get(&test_kfifo, b, 10); + TRACE(1,"get 10 : fifo len %d", kfifo_len(&test_kfifo)); + TRACE(0,"data:"); + for(int i = 0; i < 10; ++i) { + TRACE(1,"%c-", b[i]); + } + TRACE(0," "); + kfifo_get(&test_kfifo, b, 10); + TRACE(1,"get 10 : fifo len %d", kfifo_len(&test_kfifo)); + TRACE(0,"data:"); + for(int i = 0; i < 10; ++i) { + TRACE(1,"%c-", b[i]); + } + TRACE(0," "); +} +#endif diff --git a/utils/kfifo/kfifo.h b/utils/kfifo/kfifo.h new file mode 100644 index 0000000..59e1b70 --- /dev/null +++ b/utils/kfifo/kfifo.h @@ -0,0 +1,28 @@ +#ifndef KFIFO_H +#define KFIFO_H 1 + +#include "plat_types.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +struct kfifo { + unsigned char *buffer; /* the buffer holding the data */ + unsigned int size; /* the size of the allocated buffer */ + unsigned int in; /* data is added at offset (in % size) */ + unsigned int out; /* data is extracted from off. (out % size) */ +}; + +void kfifo_init(struct kfifo *k, unsigned char *buff, unsigned int len); +unsigned int kfifo_put(struct kfifo *k, unsigned char *buff, unsigned int len); +unsigned int kfifo_get(struct kfifo *k, unsigned char *buff, unsigned int len); +unsigned int kfifo_peek(struct kfifo *k, unsigned int len_want, unsigned char **buff1, unsigned char **buff2, unsigned int *len1, unsigned int *len2); +unsigned int kfifo_peek_to_buf(struct kfifo *fifo, unsigned char *buff, unsigned int len); +unsigned int kfifo_len(struct kfifo *fifo); + +#if defined(__cplusplus) +} +#endif + +#endif /* KFIFO_H */ diff --git a/utils/libc/Makefile b/utils/libc/Makefile new file mode 100644 index 0000000..5e8a684 --- /dev/null +++ b/utils/libc/Makefile @@ -0,0 +1,36 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +ifeq ($(NOSTD),1) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) + +# Use relative path to specify the include path (so that no change is needed after rename) +ccflags-y := -I$(obj)/inc + +ifeq ($(LIBC_ROM),1) +CFLAGS_libc_rom.o += -Iutils/rom_utils + +EXCLUDE_OBJS := strsep.o strtok.o strncat.o strnicmp.o strstr.o memset.o memcpy.o memmove.o \ + atoi.o strtol.o strtoul.o qsort.o bsearch.o \ + vsprintf.o vsscanf.o +else +EXCLUDE_OBJS := libc_rom.o +endif + +obj-y := $(filter-out $(EXCLUDE_OBJS),$(obj-y)) + +else # !NOSTD + +obj-y := libc_rom.o + +CFLAGS_libc_rom.o += -Iutils/rom_utils +# Avoid conflicting with libc in toolchain +CFLAGS_libc_rom.o += -DNO_STRTOL +CFLAGS_libc_rom.o += -DNO_STRTOUL +CFLAGS_libc_rom.o += -DNO_VSSCANF +CFLAGS_libc_rom.o += -DNO_ASSERT + +endif # !NOSTD + diff --git a/utils/libc/inc/assert.h b/utils/libc/inc/assert.h new file mode 100644 index 0000000..df901fa --- /dev/null +++ b/utils/libc/inc/assert.h @@ -0,0 +1,27 @@ +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef assert +#undef assert +#endif + +#define STRINGIFY_VALUE(s) STRINGIFY(s) +#define STRINGIFY(s) #s + +void __assert(const char* fmt); + +#define assert(boolcondition) { if(!(boolcondition)) __assert( \ + "ASSERTION FAILED in file : " \ + __FILE__ \ + " at line" \ + STRINGIFY_VALUE(__LINE__)); } + +#ifdef __cplusplus +} // extern C +#endif + +#endif /* _ASSERT_H_ */ diff --git a/utils/libc/inc/ctype.h b/utils/libc/inc/ctype.h new file mode 100644 index 0000000..d5808b2 --- /dev/null +++ b/utils/libc/inc/ctype.h @@ -0,0 +1,55 @@ +#ifndef CTYPE_H +#define CTYPE_H + +/* + * NOTE! This ctype does not handle EOF like the standard C + * library is required to. + */ + +#define _U 0x01 /* upper */ +#define _L 0x02 /* lower */ +#define _D 0x04 /* digit */ +#define _C 0x08 /* cntrl */ +#define _P 0x10 /* punct */ +#define _S 0x20 /* white space (space/lf/tab) */ +#define _X 0x40 /* hex digit */ +#define _SP 0x80 /* hard space (0x20) */ + +extern const unsigned char _ctype[]; + +#define __ismask(x) (_ctype[(int)(unsigned char)(x)]) + +#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) +#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) +#define iscntrl(c) ((__ismask(c)&(_C)) != 0) +#define isdigit(c) ((__ismask(c)&(_D)) != 0) +#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) +#define islower(c) ((__ismask(c)&(_L)) != 0) +#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) +#define ispunct(c) ((__ismask(c)&(_P)) != 0) +#define isspace(c) ((__ismask(c)&(_S)) != 0) +#define isupper(c) ((__ismask(c)&(_U)) != 0) +#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) + +#define isascii(c) (((unsigned char)(c))<=0x7f) +#define toascii(c) (((unsigned char)(c))&0x7f) + +static inline unsigned char __tolower(unsigned char c) +{ + if (isupper(c)) + c -= 'A'-'a'; + return c; +} + +static inline unsigned char __toupper(unsigned char c) +{ + if (islower(c)) + c -= 'a'-'A'; + return c; +} + +#define tolower(c) __tolower(c) +#define toupper(c) __toupper(c) + + +#endif /* CTYPE_H */ diff --git a/utils/libc/inc/errno.h b/utils/libc/inc/errno.h new file mode 100644 index 0000000..54064fe --- /dev/null +++ b/utils/libc/inc/errno.h @@ -0,0 +1,131 @@ +#ifndef _GENERIC_ERRNO_H +#define _GENERIC_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#endif diff --git a/utils/libc/inc/stdarg.h b/utils/libc/inc/stdarg.h new file mode 100644 index 0000000..4d3093e --- /dev/null +++ b/utils/libc/inc/stdarg.h @@ -0,0 +1,133 @@ +/* Copyright (C) 1989, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* + * ISO C Standard: 7.15 Variable arguments + */ + +#ifndef _STDARG_H +#ifndef _ANSI_STDARG_H_ +#ifndef __need___va_list +#define _STDARG_H +#define _ANSI_STDARG_H_ +#endif /* not __need___va_list */ +#undef __need___va_list + +/* Define __gnuc_va_list. */ + +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST +typedef __builtin_va_list __gnuc_va_list; +#endif + +/* Define the standard macros for the user, + if this invocation was from the user program. */ +#ifdef _STDARG_H + +#define va_start(v,l) __builtin_va_start(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v,l) __builtin_va_arg(v,l) +#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L +#define va_copy(d,s) __builtin_va_copy(d,s) +#endif +#define __va_copy(d,s) __builtin_va_copy(d,s) + +/* Define va_list, if desired, from __gnuc_va_list. */ +/* We deliberately do not define va_list when called from + stdio.h, because ANSI C says that stdio.h is not supposed to define + va_list. stdio.h needs to have access to that data type, + but must not use that name. It should use the name __gnuc_va_list, + which is safe because it is reserved for the implementation. */ + +#ifdef _HIDDEN_VA_LIST /* On OSF1, this means varargs.h is "half-loaded". */ +#undef _VA_LIST +#endif + +#ifdef _BSD_VA_LIST +#undef _BSD_VA_LIST +#endif + +#if defined(__svr4__) || (defined(_SCO_DS) && !defined(__VA_LIST)) +/* SVR4.2 uses _VA_LIST for an internal alias for va_list, + so we must avoid testing it and setting it here. + SVR4 uses _VA_LIST as a flag in stdarg.h, but we should + have no conflict with that. */ +#ifndef _VA_LIST_ +#define _VA_LIST_ +#ifdef __i860__ +#ifndef _VA_LIST +#define _VA_LIST va_list +#endif +#endif /* __i860__ */ +typedef __gnuc_va_list va_list; +#ifdef _SCO_DS +#define __VA_LIST +#endif +#endif /* _VA_LIST_ */ +#else /* not __svr4__ || _SCO_DS */ + +/* The macro _VA_LIST_ is the same thing used by this file in Ultrix. + But on BSD NET2 we must not test or define or undef it. + (Note that the comments in NET 2's ansi.h + are incorrect for _VA_LIST_--see stdio.h!) */ +#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) +/* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */ +#ifndef _VA_LIST_DEFINED +/* The macro _VA_LIST is used in SCO Unix 3.2. */ +#ifndef _VA_LIST +/* The macro _VA_LIST_T_H is used in the Bull dpx2 */ +#ifndef _VA_LIST_T_H +/* The macro __va_list__ is used by BeOS. */ +#ifndef __va_list__ +typedef __gnuc_va_list va_list; +#endif /* not __va_list__ */ +#endif /* not _VA_LIST_T_H */ +#endif /* not _VA_LIST */ +#endif /* not _VA_LIST_DEFINED */ +#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__)) +#define _VA_LIST_ +#endif +#ifndef _VA_LIST +#define _VA_LIST +#endif +#ifndef _VA_LIST_DEFINED +#define _VA_LIST_DEFINED +#endif +#ifndef _VA_LIST_T_H +#define _VA_LIST_T_H +#endif +#ifndef __va_list__ +#define __va_list__ +#endif + +#endif /* not _VA_LIST_, except on certain systems */ + +#endif /* not __svr4__ */ + +#endif /* _STDARG_H */ + +#endif /* not _ANSI_STDARG_H_ */ +#endif /* not _STDARG_H */ diff --git a/utils/libc/inc/stdbool.h b/utils/libc/inc/stdbool.h new file mode 100644 index 0000000..9f1fecd --- /dev/null +++ b/utils/libc/inc/stdbool.h @@ -0,0 +1,12 @@ +#ifndef STD_BOOL_H +#define STD_BOOL_H + +#ifdef __cplusplus +#else +typedef unsigned char bool; +#define true 1 +#define false 0 +#endif + +#endif + diff --git a/utils/libc/inc/stddef.h b/utils/libc/inc/stddef.h new file mode 100644 index 0000000..dce8809 --- /dev/null +++ b/utils/libc/inc/stddef.h @@ -0,0 +1,12 @@ +#ifndef STDDEF_H +#define STDDEF_H + +#undef NULL +#ifndef __cplusplus +#define NULL ((void *)0) +#else /* C++ */ +#define NULL 0 +#endif /* C++ */ + +#endif + diff --git a/utils/libc/inc/stdint.h b/utils/libc/inc/stdint.h new file mode 100644 index 0000000..0750cc8 --- /dev/null +++ b/utils/libc/inc/stdint.h @@ -0,0 +1,224 @@ +#ifndef STDINT_H +#define STDINT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * 7.18.2 Limits of specified-width integer types + */ + +/* 7.18.2.1 Limits of exact-width integer types */ + +/* minimum values of exact-width signed integer types */ +#define INT8_MIN (-INT8_MAX-1) /* int8_t */ +#define INT16_MIN (-INT16_MAX-1) /* int16_t */ +#define INT32_MIN (-INT32_MAX-1) /* int32_t */ +#define INT64_MIN (-INT64_MAX-1) /* int64_t */ + +#define SCHAR_MIN (-SCHAR_MAX-1) /* signed char */ +#define SHRT_MIN (-SHRT_MAX-1) /* short */ +#define INT_MIN (-INT_MAX-1) /* int */ +#define LONG_MIN (-LONG_MAX-1) /* long */ +#define LLONG_MIN (-LLONG_MAX-1) /* long long */ + +#ifdef __INT8_MAX__ +/* maximum values of exact-width signed integer types */ +#define INT8_MAX __INT8_MAX__ /* int8_t */ +#define INT16_MAX __INT16_MAX__ /* int16_t */ +#define INT32_MAX __INT32_MAX__ /* int32_t */ +#define INT64_MAX __INT64_MAX__ /* int64_t */ + +#define SCHAR_MAX __SCHAR_MAX__ /* signed char */ +#define SHRT_MAX __SHRT_MAX__ /* short */ +#define INT_MAX __INT_MAX__ /* int */ +#define LONG_MAX __LONG_MAX__ /* long */ +#define LLONG_MAX __LONG_LONG_MAX__ /* long long */ + +/* maximum values of exact-width unsigned integer types */ +#define UINT8_MAX __UINT8_MAX__ /* uint8_t */ +#define UINT16_MAX __UINT16_MAX__ /* uint16_t */ +#define UINT32_MAX __UINT32_MAX__ /* uint32_t */ +#define UINT64_MAX __UINT64_MAX__ /* uint64_t */ + +#else +/* maximum values of exact-width signed integer types */ +#define INT8_MAX 0x7f /* int8_t */ +#define INT16_MAX 0x7fff /* int16_t */ +#define INT32_MAX 0x7fffffff /* int32_t */ +#define INT64_MAX 0x7fffffffffffffffLL /* int64_t */ + +#define SCHAR_MAX 0x7f /* signed char */ +#define SHRT_MAX 0x7fff /* short */ +#define INT_MAX 0x7fffffff /* int */ +#define LONG_MAX 0x7fffffff /* long */ +#define LLONG_MAX 0x7fffffffffffffffLL /* long long */ + +/* maximum values of exact-width unsigned integer types */ +#define UINT8_MAX 0xff /* uint8_t */ +#define UINT16_MAX 0xffff /* uint16_t */ +#define UINT32_MAX 0xffffffffU /* uint32_t */ +#define UINT64_MAX 0xffffffffffffffffULL /* uint64_t */ +#endif + +#define USCHAR_MAX (2U*SCHAR_MAX+1) /* unsigned char */ +#define USHRT_MAX (2U*SHRT_MAX+1) /* unsigned short */ +#define UINT_MAX (2U*INT_MAX+1) /* unsigned int */ +#define ULONG_MAX (2UL*LONG_MAX+1) /* unsigned long */ +#define ULLONG_MAX (2ULL*LLONG_MAX+1) /* unsigned long long */ + +/* 7.18.2.2 Limits of minimum-width integer types */ + +/* minimum values of minimum-width signed integer types */ +#define INT_LEAST8_MIN (-INT_LEAST8_MAX-1) /* int_least8_t */ +#define INT_LEAST16_MIN (-INT_LEAST16_MAX-1) /* int_least16_t */ +#define INT_LEAST32_MIN (-INT_LEAST32_MAX-1) /* int_least32_t */ +#define INT_LEAST64_MIN (-INT_LEAST64_MAX-1) /* int_least64_t */ + +#ifdef __INT_LEAST8_MAX__ +/* maximum values of minimum-width signed integer types */ +#define INT_LEAST8_MAX __INT_LEAST8_MAX__ /* int_least8_t */ +#define INT_LEAST16_MAX __INT_LEAST16_MAX__ /* int_least16_t */ +#define INT_LEAST32_MAX __INT_LEAST32_MAX__ /* int_least32_t */ +#define INT_LEAST64_MAX __INT_LEAST64_MAX__ /* int_least64_t */ + +/* maximum values of minimum-width unsigned integer types */ +#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__ /* uint_least8_t */ +#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__ /* uint_least16_t */ +#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__ /* uint_least32_t */ +#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__ /* uint_least64_t */ +#else +/* maximum values of minimum-width signed integer types */ +#define INT_LEAST8_MAX 0x7f /* int_least8_t */ +#define INT_LEAST16_MAX 0x7fff /* int_least16_t */ +#define INT_LEAST32_MAX 0x7fffffff /* int_least32_t */ +#define INT_LEAST64_MAX 0x7fffffffffffffffLL /* int_least64_t */ + +/* maximum values of minimum-width unsigned integer types */ +#define UINT_LEAST8_MAX 0xff /* uint_least8_t */ +#define UINT_LEAST16_MAX 0xffff /* uint_least16_t */ +#define UINT_LEAST32_MAX 0xffffffffU /* uint_least32_t */ +#define UINT_LEAST64_MAX 0xffffffffffffffffULL /* uint_least64_t */ +#endif + +/* 7.18.2.3 Limits of fastest minimum-width integer types */ + +/* minimum values of fastest minimum-width signed integer types */ +#define INT_FAST8_MIN (-INT_FAST8_MAX-1) /* int_fast8_t */ +#define INT_FAST16_MIN (-INT_FAST16_MAX-1) /* int_fast16_t */ +#define INT_FAST32_MIN (-INT_FAST32_MAX-1) /* int_fast32_t */ +#define INT_FAST64_MIN (-INT_FAST64_MAX-1) /* int_fast64_t */ + +#ifdef INT_FAST8_MAX +/* maximum values of fastest minimum-width signed integer types */ +#define INT_FAST8_MAX __INT_FAST8_MAX__ /* int_fast8_t */ +#define INT_FAST16_MAX __INT_FAST16_MAX__ /* int_fast16_t */ +#define INT_FAST32_MAX __INT_FAST32_MAX__ /* int_fast32_t */ +#define INT_FAST64_MAX __INT_FAST64_MAX__ /* int_fast64_t */ + +/* maximum values of fastest minimum-width unsigned integer types */ +#define UINT_FAST8_MAX __UINT_FAST8_MAX__ /* uint_fast8_t */ +#define UINT_FAST16_MAX __UINT_FAST16_MAX__ /* uint_fast16_t */ +#define UINT_FAST32_MAX __UINT_FAST32_MAX__ /* uint_fast32_t */ +#define UINT_FAST64_MAX __UINT_FAST64_MAX__ /* uint_fast64_t */ +#else +/* maximum values of fastest minimum-width signed integer types */ +#define INT_FAST8_MAX 0x7fffffff /* int_fast8_t */ +#define INT_FAST16_MAX 0x7fffffff /* int_fast16_t */ +#define INT_FAST32_MAX 0x7fffffff /* int_fast32_t */ +#define INT_FAST64_MAX 0x7fffffffffffffffLL /* int_fast64_t */ + +/* maximum values of fastest minimum-width unsigned integer types */ +#define UINT_FAST8_MAX 0xffffffffU /* uint_fast8_t */ +#define UINT_FAST16_MAX 0xffffffffU /* uint_fast16_t */ +#define UINT_FAST32_MAX 0xffffffffU /* uint_fast32_t */ +#define UINT_FAST64_MAX 0xffffffffffffffffULL /* uint_fast64_t */ +#endif + +/* 7.18.2.4 Limits of integer types capable of holding object pointers */ + +#define INTPTR_MIN (-INTPTR_MAX-1) /* intptr_t */ +#ifdef __INTPTR_MAX__ +#define INTPTR_MAX __INTPTR_MAX__ /* intptr_t */ +#define UINTPTR_MAX __UINTPTR_MAX__ /* uintptr_t */ +#else +#define INTPTR_MAX 0x7fffffffL /* intptr_t */ +#define UINTPTR_MAX 0xffffffffUL /* uintptr_t */ +#endif + +/* 7.18.2.5 Limits of greatest-width integer types */ + +#define INTMAX_MIN (-INTMAX_MAX-1) /* intmax_t */ +#ifdef __INTMAX_MAX__ +#define INTMAX_MAX __INTMAX_MAX__ /* intmax_t */ +#define UINTMAX_MAX __UINTMAX_MAX__ /* uintmax_t */ +#else +#define INTMAX_MAX 0x7fffffffffffffffLL /* intmax_t */ +#define UINTMAX_MAX 0xffffffffffffffffULL /* uintmax_t */ +#endif + +/* + * 7.18.3 Limits of other integer types + */ + +/* limits of ptrdiff_t */ +#define PTRDIFF_MIN (-PTRDIFF_MAX-1) /* ptrdiff_t */ +#ifdef __PTRDIFF_MAX__ +#define PTRDIFF_MAX __PTRDIFF_MAX__ /* ptrdiff_t */ +#else +#define PTRDIFF_MAX 0x7fffffffL /* ptrdiff_t */ +#endif + +/* limits of sig_atomic_t */ +#define SIG_ATOMIC_MIN (-SIG_ATOMIC_MAX-1) /* sig_atomic_t */ +#ifdef __SIG_ATOMIC_MAX__ +#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__ /* sig_atomic_t */ +#else +#define SIG_ATOMIC_MAX 0x7fffffff /* sig_atomic_t */ +#endif + +/* limit of size_t */ +#ifdef __SIZE_MAX__ +#define SIZE_MAX __SIZE_MAX__ /* size_t */ +#else +#define SIZE_MAX 0xffffffffUL /* size_t */ +#endif + + +typedef unsigned char uint8_t; +typedef signed char int8_t; +typedef unsigned short int uint16_t; +typedef signed short int int16_t; +typedef unsigned int uint32_t; +typedef signed int int32_t; +typedef char boolean; + +typedef unsigned long long uint64_t; +typedef signed long long int64_t; + +#ifndef size_t +typedef unsigned int size_t; +#endif + +#ifndef ssize_t +typedef int ssize_t; +#endif + +typedef unsigned long long uintmax_t; +typedef long long intmax_t; + +typedef int intptr_t; + +typedef unsigned int uintptr_t; + +typedef int ptrdiff_t; + +typedef int sig_atomic_t; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/utils/libc/inc/stdio.h b/utils/libc/inc/stdio.h new file mode 100644 index 0000000..52e1d49 --- /dev/null +++ b/utils/libc/inc/stdio.h @@ -0,0 +1,30 @@ +#ifndef STDIO_H +#define STDIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stddef.h" +#include "stdint.h" +#include "stdarg.h" + +/* Standard sprintf() function. Work as the libc one. */ +int sprintf(char * buf, const char *fmt, ...); +/* Standard snprintf() function from BSD, more secure... */ +int snprintf(char * buf, size_t size, const char *fmt, ...); +/* Standard sscanf() function. Work as the libc one. */ +int sscanf(const char * buf, const char * fmt, ...); +/* If you need to code your own printf... */ +int vsprintf(char *buf, const char *fmt, va_list ap); +int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap); +int vsscanf(const char *fp, const char *fmt0, va_list ap); + +#ifdef __cplusplus +} +#endif + +#endif /* STDIO_H */ + + + diff --git a/utils/libc/inc/stdlib.h b/utils/libc/inc/stdlib.h new file mode 100644 index 0000000..7f6c1ab --- /dev/null +++ b/utils/libc/inc/stdlib.h @@ -0,0 +1,33 @@ +#ifndef STDLIB_H +#define STDLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stddef.h" +#include "stdint.h" + +/* Standard atoi() function. Work as the libc one. */ +int atoi(const char *s); +#define atol(str) ((long) atoi((str))) + +long strtol(const char *nptr, char **endptr, int base); +unsigned long strtoul(const char *nptr, char **endptr, int base); + +/* Standard random functions, work as the libc ones. */ +#define RAND_MAX 32767 + +int rand(void); +void srand(unsigned int seed); + +void qsort(void *baseP, size_t nElem, size_t width, int (*compar)(const void *, const void *)); + +void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/utils/libc/inc/string.h b/utils/libc/inc/string.h new file mode 100644 index 0000000..425c26b --- /dev/null +++ b/utils/libc/inc/string.h @@ -0,0 +1,70 @@ +#ifndef STRING_H +#define STRING_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stddef.h" +#include "stdint.h" +#include "plat_types.h" + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +extern char * strsep(char **stringp, const char *delim); + +/* + * Awkward, bug-prone, non-reentrant, Bad Thing altogether + * Use strsep instead if possible + */ +extern char * strtok(char *,const char *); +/* + * Same as strtok, but reentrant, and needs its own buffer + * Still awkward and bug-prone... + */ +extern char * strtok_r(char *,const char *, char **); + +extern char * strcpy(char *,const char *); +extern char * strncpy(char *,const char *, size_t); + +extern char * strcat(char *, const char *); +extern char * strncat(char *, const char *,size_t); + +extern int strcmp(const char *,const char *); +extern int strncmp(const char *,const char *,size_t); +extern int strnicmp(const char *, const char *, size_t); + +extern char * strchr(const char *,int); +extern char * strrchr(const char *,int); +extern char * strstr(const char *,const char *); + +extern size_t strlen(const char *); +extern size_t strnlen(const char *,size_t); + +extern void * memset(void *,int,size_t); +extern void * memcpy(void *,const void *,size_t); +extern void * memmove(void *,const void *,size_t); + +extern void * memscan(void *,int,size_t); +extern int memcmp(const void *,const void *,size_t); +extern void * memchr(const void *,int,size_t); + +size_t strcspn(const char *s, const char *reject); +size_t strspn(const char *s1, const char *s2); + +#ifdef __cplusplus +} +#endif + + +#endif /* STRING_H */ + diff --git a/utils/libc/libc_rom.c b/utils/libc/libc_rom.c new file mode 100644 index 0000000..ed8b6ec --- /dev/null +++ b/utils/libc/libc_rom.c @@ -0,0 +1,165 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "string.h" +#include "stdlib.h" +#include "stdio.h" + +#include "export_fn_rom.h" + +char * +strsep(char **stringp, const char *delim) +{ + return __export_fn_rom.strsep(stringp, delim); +} + +char * +strtok(char *s, const char *delim) +{ + static char *lasts; + + return strtok_r(s, delim, &lasts); +} + +char * +strtok_r(char *s, const char *delim, char **lasts) +{ + return __export_fn_rom.strtok_r(s, delim, lasts); +} + +char * +strncat (s1, s2, n) + char *s1; + const char *s2; + size_t n; +{ + return __export_fn_rom.strncat(s1, s2, n); +} + +int +strnicmp(s1, s2, n) + const char *s1; + const char *s2; + size_t n; +{ + return __export_fn_rom.strnicmp(s1, s2, n); +} + +char * +strstr(s, find) + const char *s, *find; +{ + return __export_fn_rom.strstr(s, find); +} + +void * +memset(dst0, c0, length) + void *dst0; + int c0; + size_t length; +{ + return __export_fn_rom.memset(dst0, c0, length); +} + +void * memcpy(void *dst,const void *src, size_t length) +{ + return __export_fn_rom.memcpy(dst, src, length); +} + +void * memmove(void *dst,const void *src, size_t length) +{ + return __export_fn_rom.memmove(dst, src, length); +} + +int atoi(const char *s) +{ + return __export_fn_rom.atoi(s); +} + +#ifndef NO_STRTOL +long strtol(const char *nptr, char **endptr, int base) +{ + return __export_fn_rom.strtol(nptr, endptr, base); +} +#endif + +#ifndef NO_STRTOUL +unsigned long strtoul(const char *nptr, char **endptr, int base) +{ + return __export_fn_rom.strtoul(nptr, endptr, base); +} +#endif + +void qsort(void *baseP, size_t nElem, size_t width, int (*compar)(const void *, const void *)) +{ + return __export_fn_rom.qsort(baseP, nElem, width, compar); +} + +void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)) +{ + return __export_fn_rom.bsearch(key, base, nmemb, size, compar); +} + +int sprintf(char * buf, const char *fmt, ...) +{ + va_list ap; + int len; + + va_start(ap, fmt); + len = __export_fn_rom.vsnprintf(buf, -(size_t)buf, fmt, ap); + va_end(ap); + return (len); +} + +int snprintf(char * buf, size_t size, const char *fmt, ...) +{ + va_list ap; + int len; + + va_start(ap, fmt); + len = __export_fn_rom.vsnprintf(buf, size, fmt, ap); + va_end(ap); + return (len); +} + +int vsprintf(char *buf, const char *fmt, va_list ap) +{ + return __export_fn_rom.vsprintf(buf, fmt, ap); +} + +int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap) +{ + return __export_fn_rom.vsnprintf(buf, size, fmt, ap); +} + +#ifndef NO_VSSCANF +int sscanf(const char * buf, const char * fmt, ...) +{ + va_list args; + int i; + + va_start(args,fmt); + i = __export_fn_rom.vsscanf(buf,fmt,args); + va_end(args); + return i; +} + +int vsscanf(const char *fp, const char *fmt0, va_list ap) +{ + return __export_fn_rom.vsscanf(fp, fmt0, ap); +} +#endif + diff --git a/utils/list/Makefile b/utils/list/Makefile new file mode 100644 index 0000000..a2b6b88 --- /dev/null +++ b/utils/list/Makefile @@ -0,0 +1,7 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.cpp $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.cpp=.o) +obj-y := $(obj-y:.S=.o) + diff --git a/utils/list/list.c b/utils/list/list.c new file mode 100644 index 0000000..3300594 --- /dev/null +++ b/utils/list/list.c @@ -0,0 +1,321 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "stdio.h" +#include "cmsis_os.h" +#include "hal_trace.h" +#include "string.h" +#include "list.h" + +osPoolId list_t_mempool = NULL; +osPoolDef (list_t_mempool, 3, list_t); +osPoolId list_node_t_mempool = NULL; +osPoolDef (list_node_t_mempool, 50, list_node_t); + +static list_node_t *list_free_node_(list_t *list, list_node_t *node); + +int list_init(void) +{ + if (list_t_mempool == NULL) + list_t_mempool = osPoolCreate(osPool(list_t_mempool)); + + if (list_node_t_mempool == NULL) + list_node_t_mempool = osPoolCreate(osPool(list_node_t_mempool)); + + return 0; +} + +inline static list_node_t *malloc_list_node (void) +{ + list_node_t *node = (list_node_t *)osPoolCAlloc (list_node_t_mempool); + ASSERT(node,"[%s] failed",__func__); + return node; +} + +inline static void free_list_node(list_node_t *node) +{ + osPoolFree (list_node_t_mempool, node); +} + +inline static list_t *malloc_list(void) +{ + list_t *list = (list_t *)osPoolCAlloc (list_t_mempool); + ASSERT(list,"[%s] failed",__func__); + return list; +} + +inline static void free_list(list_t *list) +{ + osPoolFree (list_t_mempool, list); +} + + +// Returns a new, empty list. Returns NULL if not enough memory could be allocated +// for the list structure. The returned list must be freed with |list_free|. The +// |callback| specifies a function to be called whenever a list element is removed +// from the list. It can be used to release resources held by the list element, e.g. +// memory or file descriptor. |callback| may be NULL if no cleanup is necessary on +// element removal. +list_t *list_new(list_free_cb callback, list_mempool_zmalloc zmalloc, list_mempool_free free) { + list_t *list = NULL; + if (zmalloc){ + list = (list_t *)zmalloc(sizeof(list_t)); + if (list){ + list->mempool_functions.zmalloc = zmalloc; + list->mempool_functions.free = free; + list->free_cb = callback; + } + }else{ + list = (list_t *)malloc_list(); + if (list){ + list->free_cb = callback; + } + } + return list; +} + +// Frees the list. This function accepts NULL as an argument, in which case it +// behaves like a no-op. +void list_free(list_t *list) { + if (list != NULL) + list_clear(list); + if (list->mempool_functions.free) + list->mempool_functions.free(list); + else + free_list(list); +} + +// Returns true if the list is empty (has no elements), false otherwise. +// Note that a NULL list is not the same as an empty list. This function +// does not accept a NULL list. +bool list_is_empty(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + return (list->length == 0); +} + +// Returns the length of the list. This function does not accept a NULL list. +size_t list_length(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + return list->length; +} + +// Returns the first element in the list without removing it. |list| may not +// be NULL or empty. +void *list_front(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + ASSERT(!list_is_empty(list),"%s",__func__); + return list->head->data; +} + +// Returns the last element in the list without removing it. |list| may not +// be NULL or empty. +void *list_back(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + ASSERT(!list_is_empty(list),"%s",__func__); + + return list->tail->data; +} + +bool list_insert_after(list_t *list, list_node_t *prev_node, void *data) { + list_node_t *node; + ASSERT(list != NULL,"%s",__func__); + ASSERT(prev_node != NULL,"%s",__func__); + ASSERT(data != NULL,"%s",__func__); + + if (list->mempool_functions.zmalloc) + node = (list_node_t *)list->mempool_functions.zmalloc(sizeof(list_node_t)); + else + node = (list_node_t *)malloc_list_node(); + + if (!node) + return false; + + node->next = prev_node->next; + node->data = data; + prev_node->next = node; + if (list->tail == prev_node) + list->tail = node; + ++list->length; + return true; +} + +#include "stdio.h" +// Inserts |data| at the beginning of |list|. Neither |data| nor |list| may be NULL. +// This function does not make a copy of |data| so the pointer must remain valid +// at least until the element is removed from the list or the list is freed. +// Returns true if |data| could be inserted, false otherwise (e.g. out of memory). +bool list_prepend(list_t *list, void *data) { + list_node_t *node; + ASSERT(list != NULL,"%s",__func__); + ASSERT(data != NULL,"%s",__func__); + + if (list->mempool_functions.zmalloc) + node = (list_node_t *)list->mempool_functions.zmalloc(sizeof(list_node_t)); + else + node = (list_node_t *)malloc_list_node(); + + if (!node) + return false; + node->next = list->head; + node->data = data; + list->head = node; + if (list->tail == NULL) + list->tail = list->head; + ++list->length; + return true; +} + +// Inserts |data| at the end of |list|. Neither |data| nor |list| may be NULL. +// This function does not make a copy of |data| so the pointer must remain valid +// at least until the element is removed from the list or the list is freed. +// Returns true if |data| could be inserted, false otherwise (e.g. out of memory). +bool list_append(list_t *list, void *data) { + list_node_t *node; + ASSERT(list != NULL,"%s",__func__); + ASSERT(data != NULL,"%s",__func__); + + if (list->mempool_functions.zmalloc) + node = (list_node_t *)list->mempool_functions.zmalloc(sizeof(list_node_t)); + else + node = (list_node_t *)malloc_list_node(); + + if (!node) + return false; + node->next = NULL; + node->data = data; + if (list->tail == NULL) { + list->head = node; + list->tail = node; + } else { + list->tail->next = node; + list->tail = node; + } + ++list->length; + return true; +} + +// Removes |data| from the list. Neither |list| nor |data| may be NULL. If |data| +// is inserted multiple times in the list, this function will only remove the first +// instance. If a free function was specified in |list_new|, it will be called back +// with |data|. This function returns true if |data| was found in the list and removed, +// false otherwise. +bool list_remove(list_t *list, void *data) { + list_node_t *prev, *node; + ASSERT(list != NULL,"%s",__func__); + ASSERT(data != NULL,"%s",__func__); + + if (list_is_empty(list)) + return false; + + if (list->head->data == data) { + list_node_t *next = list_free_node_(list, list->head); + if (list->tail == list->head) + list->tail = next; + list->head = next; + return true; + } + + for (prev = list->head, node = list->head->next; node; prev = node, node = node->next) + if (node->data == data) { + prev->next = list_free_node_(list, node); + if (list->tail == node) + list->tail = prev; + return true; + } + + return false; +} + +// Removes all elements in the list. Calling this function will return the list to the +// same state it was in after |list_new|. |list| may not be NULL. +void list_clear(list_t *list) { + list_node_t *node; + ASSERT(list != NULL,"%s",__func__); + for (node = list->head; node; ) + node = list_free_node_(list, node); + list->head = NULL; + list->tail = NULL; + list->length = 0; +} + +// Iterates through the entire |list| and calls |callback| for each data element. +// If the list is empty, |callback| will never be called. It is safe to mutate the +// list inside the callback. If an element is added before the node being visited, +// there will be no callback for the newly-inserted node. Neither |list| nor +// |callback| may be NULL. +void list_foreach(const list_t *list, list_iter_cb callback) { + list_node_t *node; + ASSERT(list != NULL,"%s",__func__); + ASSERT(callback != NULL,"%s",__func__); + + for (node = list->head; node; ) { + list_node_t *next = node->next; + callback(node->data); + node = next; + } +} + +// Returns an iterator to the first element in |list|. |list| may not be NULL. +// The returned iterator is valid as long as it does not equal the value returned +// by |list_end|. +list_node_t *list_begin(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + return list->head; +} + +// Returns an iterator that points past the end of the list. In other words, +// this function returns the value of an invalid iterator for the given list. +// When an iterator has the same value as what's returned by this function, you +// may no longer call |list_next| with the iterator. |list| may not be NULL. +list_node_t *list_end(const list_t *list) { + ASSERT(list != NULL,"%s",__func__); + return NULL; +} + +// Given a valid iterator |node|, this function returns the next value for the +// iterator. If the returned value equals the value returned by |list_end|, the +// iterator has reached the end of the list and may no longer be used for any +// purpose. +list_node_t *list_next(const list_node_t *node) { + ASSERT(node != NULL,"%s",__func__); + return node->next; +} + +// Returns the value stored at the location pointed to by the iterator |node|. +// |node| must not equal the value returned by |list_end|. +void *list_node(const list_node_t *node) { + ASSERT(node != NULL,"%s",__func__); + return node->data; +} + +static list_node_t *list_free_node_(list_t *list, list_node_t *node) { + list_node_t *next; + ASSERT(list != NULL,"%s",__func__); + ASSERT(node != NULL,"%s",__func__); + + next = node->next; + + if (list->free_cb) + list->free_cb(node->data); + + if (list->mempool_functions.free) + list->mempool_functions.free(node); + else + free_list_node(node); + + --list->length; + + return next; +} diff --git a/utils/list/list.h b/utils/list/list.h new file mode 100644 index 0000000..dd1eb5b --- /dev/null +++ b/utils/list/list.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#pragma once + +#ifndef __LIST_H__ +#define __LIST_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*list_mempool_zmalloc)(size_t); +typedef void (*list_mempool_free)(void *); + +typedef struct { + list_mempool_zmalloc zmalloc; + list_mempool_free free; +} list_mempool_functions_t; + +typedef void (*list_free_cb)(void *data); +typedef bool (*list_iter_cb)(void *data); + +typedef struct list_node_t { + struct list_node_t *next; + void *data; +} list_node_t; + +typedef struct list_t { + list_node_t *head; + list_node_t *tail; + size_t length; + list_free_cb free_cb; + list_mempool_functions_t mempool_functions; +} list_t; + +struct list_node_t; +typedef struct list_node_t list_node_t; +//struct list_t; +typedef struct list_t list_t; + +int list_init(void); + +// Lifecycle. +list_t *list_new(list_free_cb callback, list_mempool_zmalloc zmalloc, list_mempool_free free); +void list_free(list_t *list); + +// Accessors. +bool list_is_empty(const list_t *list); +size_t list_length(const list_t *list); +void *list_front(const list_t *list); +void *list_back(const list_t *list); + +// Mutators. +bool list_insert_after(list_t *list, list_node_t *prev_node, void *data); +bool list_prepend(list_t *list, void *data); +bool list_append(list_t *list, void *data); +bool list_remove(list_t *list, void *data); +void list_clear(list_t *list); + +// Iteration. +void list_foreach(const list_t *list, list_iter_cb callback); + +list_node_t *list_begin(const list_t *list); +list_node_t *list_end(const list_t *list); +list_node_t *list_next(const list_node_t *node); +void *list_node(const list_node_t *node); + +#ifdef __cplusplus + } +#endif + +#endif//__FMDEC_H__ + diff --git a/utils/lockcqueue/Makefile b/utils/lockcqueue/Makefile new file mode 100644 index 0000000..5225cda --- /dev/null +++ b/utils/lockcqueue/Makefile @@ -0,0 +1,10 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + diff --git a/utils/lockcqueue/lockcqueue.c b/utils/lockcqueue/lockcqueue.c new file mode 100644 index 0000000..2ae287c --- /dev/null +++ b/utils/lockcqueue/lockcqueue.c @@ -0,0 +1,50 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/*** + * lock cqueue + * YuLongWang @2015 +*/ + +#include "stdio.h" +#include "cmsis_os.h" +#include "lockcqueue.h" + +int lockcqueue_init(struct lockcqueue *q, uint32_t size, uint8_t *buf) +{ + InitCQueue(&q->cqueue, size, buf); + q->os_mutex_def_name.mutex = q->os_mutex_cb_name; + q->queue_mutex_id = osMutexCreate(&q->os_mutex_def_name); +} + +int lockcqueue_enqueue(struct lockcqueue *q, uint8_t *buf, uint32_t size) +{ + int ret = 0; + osMutexWait(q->queue_mutex_id, osWaitForever); + ret = EnCQueue(&q->cqueue, buf, size); + osMutexRelease(q->queue_mutex_id); + + return ret; +} + +int lockcqueue_dequeue(struct lockcqueue *q, uint8_t *buf, uint32_t size) +{ + int ret = 0; + osMutexWait(q->queue_mutex_id, osWaitForever); + ret = DeCQueue(&q->cqueue, buf, size); + osMutexRelease(q->queue_mutex_id); + + return ret; +} diff --git a/utils/lockcqueue/lockcqueue.h b/utils/lockcqueue/lockcqueue.h new file mode 100644 index 0000000..f7b61d4 --- /dev/null +++ b/utils/lockcqueue/lockcqueue.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +/*** + * lock cqueue + * YuLongWang @2015 +*/ + +#ifndef LOCKCQUEUE_H +#define LOCKCQUEUE_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "cqueue.h" + +struct lockcqueue { + CQueue cqueue; + osMutexId queue_mutex_id; + uint32_t os_mutex_cb_name[3]; + osMutexDef_t os_mutex_def_name; +}; + +int lockcqueue_init(struct lockcqueue *q, uint32_t size, uint8_t *buf); +int lockcqueue_enqueue(struct lockcqueue *q, uint8_t *buf, uint32_t size); +int lockcqueue_dequeue(struct lockcqueue *q, uint8_t *buf, uint32_t size); + +#if defined(__cplusplus) +} +#endif + +#endif /* LOCKCQUEUE_H */ diff --git a/utils/retention_ram/Makefile b/utils/retention_ram/Makefile new file mode 100644 index 0000000..11a3d43 --- /dev/null +++ b/utils/retention_ram/Makefile @@ -0,0 +1,10 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c $(cur_dir)*.S)) +obj-y := $(obj-y:.c=.o) +obj-y := $(obj-y:.S=.o) + +ccflags-y := -Iplatform/hal \ + + + diff --git a/utils/retention_ram/retention_ram.c b/utils/retention_ram/retention_ram.c new file mode 100644 index 0000000..023f2a4 --- /dev/null +++ b/utils/retention_ram/retention_ram.c @@ -0,0 +1,81 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "string.h" +#include "retention_ram.h" +#include "hal_timer.h" +#include "hal_trace.h" + +#define OTA_RANDOM_BLE_BD_ADDR_MAGIC_CODE 0x51544F55 +#define BLE_BD_ADDR_LEN 6 +typedef struct +{ + uint32_t magicCode; // 0x51544F55: "UOTA" means the OTA firmware should use the BD address + // in this structure, otherwise it will generate a random BD address + uint8_t bleBdAddr[BLE_BD_ADDR_LEN]; +} BLE_BD_ADDR_FOR_OTA_T; + +// retained across the HW reset +BLE_BD_ADDR_FOR_OTA_T __attribute((section(".reboot_param"))) bleBdAddrForOta; +void fillBleBdAddrForOta(uint8_t* bdAddr) +{ + bleBdAddrForOta.magicCode = OTA_RANDOM_BLE_BD_ADDR_MAGIC_CODE; + memcpy(&(bleBdAddrForOta.bleBdAddr), bdAddr, BLE_BD_ADDR_LEN); +} + +extern uint8_t ble_addr[BLE_BD_ADDR_LEN]; +static unsigned int seed = 1; + +static void set_rand_seed(unsigned int init) +{ + seed = init; +} + +static int get_rand(void) +{ + //Based on Knuth "The Art of Computer Programming" + seed = seed * 1103515245 + 12345; + return ( (unsigned int) (seed / 65536) % (32767+1) ); +} + +void otaConfigureBleBdAddr(void) +{ + if (OTA_RANDOM_BLE_BD_ADDR_MAGIC_CODE == bleBdAddrForOta.magicCode) + { + // use the BD address saved in bleBdAddrForOta + memcpy(&ble_addr, &(bleBdAddrForOta.bleBdAddr), BLE_BD_ADDR_LEN); + + // clear the magic code + bleBdAddrForOta.magicCode = 0; + } + else + { + // generate the random BD static address + int randomData; + + for (uint32_t index = 0;index < BLE_BD_ADDR_LEN/2;index++) + { + set_rand_seed(hal_sys_timer_get()); + randomData = get_rand(); + TRACE(2,"randomData %d is 0x%x", index, randomData); + memcpy(&(ble_addr[index*2]), (uint8_t *)&randomData, 2); + } + + // top two bits of the random static BD address are 1 + ble_addr[5] |= 0xC0; + } +} + + diff --git a/utils/retention_ram/retention_ram.h b/utils/retention_ram/retention_ram.h new file mode 100644 index 0000000..d56983f --- /dev/null +++ b/utils/retention_ram/retention_ram.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __RETENTION_RAM_H__ +#define __RETENTION_RAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" + + +void fillBleBdAddrForOta(uint8_t* bdAddr); +void otaConfigureBleBdAddr(void); + + +#ifdef __cplusplus +} +#endif + +#endif // #define __RETENTION_RAM_H__ + diff --git a/utils/rom_utils/Makefile b/utils/rom_utils/Makefile new file mode 100644 index 0000000..b3ce1ea --- /dev/null +++ b/utils/rom_utils/Makefile @@ -0,0 +1,25 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +rulib-y := + +rulib-y += $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)$(CHIP)/*.c $(cur_dir)$(CHIP)/*.cpp $(cur_dir)$(CHIP)/*.S)) + +rulib-y := $(rulib-y:.c=.o) +rulib-y := $(rulib-y:.cpp=.o) +rulib-y := $(rulib-y:.S=.o) + +-include $(cur_dir)$(CHIP)/Makefile +$(cur_dir)$(CHIP)/Makefile: ; + +ifeq ($(rulib-y),) +rulib-y := rom_utils_dummy.o +endif + +ROM_UTILS_LIB := $(CHIP)_librom_utils + +$(ROM_UTILS_LIB)-y := $(rulib-y) + +obj-y := $(ROM_UTILS_LIB).a + +ccflags-y += \ + diff --git a/utils/rom_utils/export_fn_rom.h b/utils/rom_utils/export_fn_rom.h new file mode 100644 index 0000000..e3f372a --- /dev/null +++ b/utils/rom_utils/export_fn_rom.h @@ -0,0 +1,109 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#ifndef __EXPORT_FN_ROM_H__ +#define __EXPORT_FN_ROM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stdint.h" +#include "stdarg.h" + +typedef void (*__BOOT_FROM_FLASH_REENT)(void); +typedef unsigned long (*__CRC32)(unsigned long crc, const unsigned char *buf, unsigned int len); +typedef int (*__VERIFY_SIGNATURE)(const unsigned char *key, const unsigned char *sig, const unsigned char *data, unsigned int len); +typedef const uint8_t* (*__SHA256_HASH)(const void* data, uint32_t len, uint8_t* digest); +typedef void (*__SHA256_INIT)(void* ctx); +typedef void (*__SHA256_UPDATE)(void* ctx, const void* data, uint32_t len); +typedef const uint8_t* (*__SHA256_FINAL)(void* ctx); + +typedef char * (*__STRSEP)(char **stringp, const char *delim); +typedef char * (*__STRTOK_R)(char *,const char *, char **); +typedef char * (*__STRCPY)(char *,const char *); +typedef char * (*__STRNCPY)(char *,const char *, size_t); +typedef char * (*__STRCAT)(char *, const char *); +typedef char * (*__STRNCAT)(char *, const char *,size_t); +typedef int (*__STRCMP)(const char *,const char *); +typedef int (*__STRNCMP)(const char *,const char *,size_t); +typedef int (*__STRNICMP)(const char *, const char *, size_t); +typedef char * (*__STRCHR)(const char *,int); +typedef char * (*__STRRCHR)(const char *,int); +typedef char * (*__STRSTR)(const char *,const char *); +typedef size_t (*__STRLEN)(const char *); +typedef size_t (*__STRNLEN)(const char *,size_t); +typedef void * (*__MEMSET)(void *,int,size_t); +typedef void * (*__MEMCPY)(void *,const void *,size_t); +typedef void * (*__MEMMOVE)(void *,const void *,size_t); +typedef void * (*__MEMSCAN)(void *,int,size_t); +typedef int (*__MEMCMP)(const void *,const void *,size_t); +typedef void * (*__MEMCHR)(const void *,int,size_t); +typedef size_t (*__STRCSPN)(const char *s, const char *reject); +typedef size_t (*__STRSPN)(const char *s1, const char *s2); +typedef int (*__SPRINTF)(char * buf, const char *fmt, ...); +typedef int (*__SNPRINTF)(char * buf, size_t len, const char *fmt, ...); +typedef int (*__SSCANF)(const char * buf, const char * fmt, ...); +typedef int (*__VSPRINTF)(char *buf, const char *fmt, va_list ap); +typedef int (*__VSNPRINTF)(char *buf, size_t size, const char *fmt, va_list ap); +typedef int (*__VSSCANF)(const char *fp, const char *fmt0, va_list ap); +typedef int (*__ATOI)(const char *s); +typedef long (*__STRTOL)(const char *nptr, char **endptr, int base); +typedef unsigned long (*__STRTOUL)(const char *nptr, char **endptr, int base); +typedef void (*__QSORT)(void *baseP, size_t nElem, size_t width, int (*compar)(const void *, const void *)); +typedef void * (*__BSEARCH)(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); + +struct EXPORT_FN_ROM_T { + __BOOT_FROM_FLASH_REENT boot_from_flash_reent; + __CRC32 crc32; + __VERIFY_SIGNATURE verify_signature; + __SHA256_HASH SHA256_hash; + __SHA256_INIT SHA256_init; + __SHA256_UPDATE SHA256_update; + __SHA256_FINAL SHA256_final; + + __STRSEP strsep; + __STRTOK_R strtok_r; + __STRNCAT strncat; + __STRNICMP strnicmp; + __STRSTR strstr; + __MEMSET memset; + __MEMCPY memcpy; + __MEMMOVE memmove; + __ATOI atoi; + __STRTOL strtol; + __STRTOUL strtoul; + __QSORT qsort; + __BSEARCH bsearch; + __SPRINTF sprintf; + __SNPRINTF snprintf; + __SSCANF sscanf; + __VSPRINTF vsprintf; + __VSNPRINTF vsnprintf; + __VSSCANF vsscanf; + +#ifdef CHIP_HAS_AUDIO_CONST_ROM + const unsigned int *audio_const; +#endif +}; + +extern struct EXPORT_FN_ROM_T __export_fn_rom; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/utils/sha256/Makefile b/utils/sha256/Makefile new file mode 100644 index 0000000..6675804 --- /dev/null +++ b/utils/sha256/Makefile @@ -0,0 +1,14 @@ +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj-y := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj-y := $(obj-y:.c=.o) + +ifeq ($(SHA256_ROM),1) +ccflags-y += -Iutils/rom_utils +EXCLUDE_OBJS := sha256.o +else +EXCLUDE_OBJS := sha256_rom.o +endif + +obj-y := $(filter-out $(EXCLUDE_OBJS),$(obj-y)) + diff --git a/utils/sha256/hash-internal.h b/utils/sha256/hash-internal.h new file mode 100644 index 0000000..e04c203 --- /dev/null +++ b/utils/sha256/hash-internal.h @@ -0,0 +1,66 @@ +/* + * Copyright 2007 The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Google Inc. 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 Google Inc. ``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 Google Inc. 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 SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_ +#define SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct HASH_CTX; // forward decl + +typedef struct HASH_VTAB { + void (* const init)(struct HASH_CTX*); + void (* const update)(struct HASH_CTX*, const void*, uint32_t); + const uint8_t* (* const final)(struct HASH_CTX*); + const uint8_t* (* const hash)(const void*, uint32_t, uint8_t*); + int size; +} HASH_VTAB; + +typedef struct HASH_CTX { + const HASH_VTAB * f; + uint64_t count; + union { + uint8_t buf[64]; + uint32_t buf32[64 / 4]; + }; + uint32_t state[8]; // upto SHA2 +} HASH_CTX; + +#define HASH_init(ctx) (ctx)->f->init(ctx) +#define HASH_update(ctx, data, len) (ctx)->f->update(ctx, data, len) +#define HASH_final(ctx) (ctx)->f->final(ctx) +#define HASH_hash(data, len, digest) (ctx)->f->hash(data, len, digest) +#define HASH_size(ctx) (ctx)->f->size + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // SYSTEM_CORE_INCLUDE_MINCRYPT_HASH_INTERNAL_H_ diff --git a/utils/sha256/sha256.c b/utils/sha256/sha256.c new file mode 100644 index 0000000..a52d614 --- /dev/null +++ b/utils/sha256/sha256.c @@ -0,0 +1,281 @@ +/* sha256.c +** +** Copyright 2013, The Android Open Source Project +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of Google Inc. 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 Google Inc. ``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 Google Inc. 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. +*/ + +// Optimized for minimal code size. + +#include "sha256.h" + +#include +#include +#include + +#include "cmsis.h" +#include "hal_timer.h" +#include "hal_sec_eng.h" +#include "plat_addr_map.h" + +#define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits)))) +#define shr(value, bits) ((value) >> (bits)) + +static const uint32_t K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; + +static void SHA256_Transform(SHA256_CTX* ctx) { + uint32_t W[64]; + uint32_t A, B, C, D, E, F, G, H; +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + uint32_t* p32 = ctx->buf32; +#else + uint8_t* p = ctx->buf; +#endif + int t; + + for(t = 0; t < 16; ++t) { +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + W[t] = __REV(*p32++); +#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + W[t] = *p32++; +#else + uint32_t tmp = *p++ << 24; + tmp |= *p++ << 16; + tmp |= *p++ << 8; + tmp |= *p++; + W[t] = tmp; +#endif + } + + for(; t < 64; t++) { + uint32_t s0 = ror(W[t-15], 7) ^ ror(W[t-15], 18) ^ shr(W[t-15], 3); + uint32_t s1 = ror(W[t-2], 17) ^ ror(W[t-2], 19) ^ shr(W[t-2], 10); + W[t] = W[t-16] + s0 + W[t-7] + s1; + } + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + + for(t = 0; t < 64; t++) { + uint32_t s0 = ror(A, 2) ^ ror(A, 13) ^ ror(A, 22); + uint32_t maj = (A & B) ^ (A & C) ^ (B & C); + uint32_t t2 = s0 + maj; + uint32_t s1 = ror(E, 6) ^ ror(E, 11) ^ ror(E, 25); + uint32_t ch = (E & F) ^ ((~E) & G); + uint32_t t1 = H + s1 + ch + K[t] + W[t]; + + H = G; + G = F; + F = E; + E = D + t1; + D = C; + C = B; + B = A; + A = t1 + t2; + } + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; +} + +static const HASH_VTAB SHA256_VTAB = { + SHA256_init, + SHA256_update, + SHA256_final, + SHA256_hash, + SHA256_DIGEST_SIZE +}; + +void SHA256_init(SHA256_CTX* ctx) { + ctx->f = &SHA256_VTAB; + ctx->state[0] = 0x6a09e667; + ctx->state[1] = 0xbb67ae85; + ctx->state[2] = 0x3c6ef372; + ctx->state[3] = 0xa54ff53a; + ctx->state[4] = 0x510e527f; + ctx->state[5] = 0x9b05688c; + ctx->state[6] = 0x1f83d9ab; + ctx->state[7] = 0x5be0cd19; + ctx->count = 0; +} + + +void SHA256_update(SHA256_CTX* ctx, const void* data, uint32_t len) { + uint32_t i = (uint32_t) (ctx->count & 63); + const uint8_t* p = (const uint8_t*)data; + + ctx->count += len; + +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + if (len >= 4 && (i & 0x3) == 0 && ((uint32_t)p & 0x3) == 0) { + const uint32_t *p32 = (const uint32_t *)p; + int k = i / 4; + while (len >= 4) { + len -= 4; +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + ctx->buf32[k++] = *p32++; +#else + ctx->buf32[k++] = __REV(*p32++); +#endif + if (k == 64 / 4) { + SHA256_Transform(ctx); + k = 0; + } + } + i = k * 4; + p = (const uint8_t *)p32; + } +#endif + + while (len--) { + ctx->buf[i++] = *p++; + if (i == 64) { + SHA256_Transform(ctx); + i = 0; + } + } +} + +const uint8_t* SHA256_final(SHA256_CTX* ctx) { + uint8_t *p = ctx->buf; + uint64_t cnt = ctx->count * 8; + uint32_t i; + + SHA256_update(ctx, (uint8_t*)"\x80", 1); + while ((ctx->count & 63) != 56) { + SHA256_update(ctx, (uint8_t*)"\0", 1); + } + for (i = 0; i < 8; ++i) { + uint8_t tmp = (uint8_t) (cnt >> ((7 - i) * 8)); + SHA256_update(ctx, &tmp, 1); + } + + for (i = 0; i < 8; i++) { + uint32_t tmp = ctx->state[i]; + *p++ = tmp >> 24; + *p++ = tmp >> 16; + *p++ = tmp >> 8; + *p++ = tmp >> 0; + } + + return ctx->buf; +} + +/* Convenience function */ +const uint8_t* SHA256_hash2(const void* data1, uint32_t len1, const void* data2, uint32_t len2, uint8_t* digest) +{ + SHA256_CTX ctx; + SHA256_init(&ctx); + if (data1 && len1) { + SHA256_update(&ctx, data1, len1); + } + if (data2 && len2) { + SHA256_update(&ctx, data2, len2); + } + memcpy(digest, SHA256_final(&ctx), SHA256_DIGEST_SIZE); + return digest; +} + +const uint8_t* SHA256_hash(const void* data, uint32_t len, uint8_t* digest) +{ + return SHA256_hash2(data, len, NULL, 0, digest); +} + +#if defined(SEC_ENG_BASE) && defined(SEC_ENG_HAS_HASH) +static int hw_eng_en; +#endif + +void hash_hardware_engine_enable(int enable) +{ +#if defined(SEC_ENG_BASE) && defined(SEC_ENG_HAS_HASH) + hw_eng_en = enable; +#endif +} + +const uint8_t* hash_sha256(const void* data, uint32_t len, uint8_t* digest) +{ +#if defined(SEC_ENG_BASE) && defined(SEC_ENG_HAS_HASH) + if (hw_eng_en) { + enum HAL_SE_RET_T ret; + struct HAL_SE_HASH_CFG_T cfg; + uint32_t time; + + ret = hal_se_open(); + if (ret != HAL_SE_OK) { + goto _exit; + } + + memset(&cfg, 0, sizeof(cfg)); + cfg.done_hdlr = NULL; + cfg.in = data; + cfg.in_len = len; + + ret = hal_se_hash(HAL_SE_HASH_SHA256, &cfg); + if (ret != HAL_SE_OK) { + goto _exit; + } + + time = hal_sys_timer_get(); + while (hal_se_hash_busy() && (hal_sys_timer_get() - time < MS_TO_TICKS(10000))) {} + + ret = hal_se_hash_get_digest(&digest[0], SHA256_DIGEST_SIZE, &len); + +_exit: + hal_se_close(); + if (ret == HAL_SE_OK) { + return digest; + } + } +#endif + + return SHA256_hash(data, len, digest); +} + diff --git a/utils/sha256/sha256.h b/utils/sha256/sha256.h new file mode 100644 index 0000000..271c6ae --- /dev/null +++ b/utils/sha256/sha256.h @@ -0,0 +1,56 @@ +/* + * Copyright 2011 The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Google Inc. 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 Google Inc. ``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 Google Inc. 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 SYSTEM_CORE_INCLUDE_MINCRYPT_SHA256_H_ +#define SYSTEM_CORE_INCLUDE_MINCRYPT_SHA256_H_ + +#include +#include "hash-internal.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef HASH_CTX SHA256_CTX; + +void SHA256_init(SHA256_CTX* ctx); +void SHA256_update(SHA256_CTX* ctx, const void* data, uint32_t len); +const uint8_t* SHA256_final(SHA256_CTX* ctx); + +// Convenience method. Returns digest address. +const uint8_t* SHA256_hash2(const void* data1, uint32_t len1, const void* data2, uint32_t len2, uint8_t* digest); +const uint8_t* SHA256_hash(const void* data, uint32_t len, uint8_t* digest); + +void hash_hardware_engine_enable(int enable); +const uint8_t* hash_sha256(const void* data, uint32_t len, uint8_t* digest); + +#define SHA256_DIGEST_SIZE 32 + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // SYSTEM_CORE_INCLUDE_MINCRYPT_SHA256_H_ diff --git a/utils/sha256/sha256_rom.c b/utils/sha256/sha256_rom.c new file mode 100644 index 0000000..0473a79 --- /dev/null +++ b/utils/sha256/sha256_rom.c @@ -0,0 +1,39 @@ +/*************************************************************************** + * + * Copyright 2015-2020 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ +#include "sha256.h" +#include "stddef.h" +#include "export_fn_rom.h" + +void SHA256_init(SHA256_CTX* ctx) +{ + __export_fn_rom.SHA256_init(ctx); +} + +void SHA256_update(SHA256_CTX* ctx, const void* data, uint32_t len) +{ + __export_fn_rom.SHA256_update(ctx, data, len); +} + +const uint8_t* SHA256_final(SHA256_CTX* ctx) +{ + return __export_fn_rom.SHA256_final(ctx); +} + +const uint8_t* SHA256_hash(const void* data, uint32_t len, uint8_t* digest) +{ + return __export_fn_rom.SHA256_hash(data, len, digest); +} + diff --git a/utils/xyzmodem/Makefile b/utils/xyzmodem/Makefile new file mode 100644 index 0000000..e5446b8 --- /dev/null +++ b/utils/xyzmodem/Makefile @@ -0,0 +1,10 @@ + +cur_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +obj_c := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.c)) +obj_cpp := $(patsubst $(cur_dir)%,%,$(wildcard $(cur_dir)*.cpp)) + +obj-y := $(obj_c:.c=.o) $(obj_s:.S=.o) $(obj_cpp:.cpp=.o) + +ccflags-y := \ + -I$(obj)/../../platform/hal/ diff --git a/utils/xyzmodem/xyzmodem.c b/utils/xyzmodem/xyzmodem.c new file mode 100644 index 0000000..9561b70 --- /dev/null +++ b/utils/xyzmodem/xyzmodem.c @@ -0,0 +1,385 @@ +/*************************************************************************** + * + * Copyright 2015-2019 BES. + * All rights reserved. All unpublished rights reserved. + * + * No part of this work may be used or reproduced in any form or by any + * means, or stored in a database or retrieval system, without prior written + * permission of BES. + * + * Use of this work is governed by a license granted by BES. + * This work contains confidential and proprietary information of + * BES. which is protected by copyright, trade secret, + * trademark and other intellectual property rights. + * + ****************************************************************************/ + +#include "hal_trace.h" +#include "hal_uart.h" +#include "string.h" +#include "hal_timer.h" + +#define SOH 0x01 +#define STX 0x02 +#define EOT 0x04 +#define ACK 0x06 +#define NAK 0x15 +#define CAN 0x18 +#define CTRLZ 0x1A + +#define DLY_1S 1000 +#define MAXRETRANS 25 +#define TRANSMIT_XMODEM_1K + +/* CRC16 implementation acording to CCITT standards */ + +static const unsigned short crc16tab[256]= { + 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, + 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, + 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, + 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, + 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, + 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, + 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, + 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, + 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, + 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, + 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, + 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, + 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, + 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, + 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, + 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, + 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, + 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, + 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, + 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, + 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, + 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, + 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, + 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, + 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, + 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, + 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, + 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, + 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, + 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, + 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, + 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 +}; + +static unsigned short crc16_ccitt(const void *buf, int len) +{ + register int counter; + register unsigned short crc = 0; + for( counter = 0; counter < len; counter++) + crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *(char *)buf++)&0x00FF]; + return crc; +} + +static int check(int crc, const uint8_t *buf, int sz) __attribute__((unused)); +static int check(int crc, const uint8_t *buf, int sz) +{ + if (crc) { + unsigned short crc = crc16_ccitt(buf, sz); + unsigned short tcrc = (buf[sz]<<8)+buf[sz+1]; + if (crc == tcrc) + return 1; + } + else { + int i; + unsigned char cks = 0; + for (i = 0; i < sz; ++i) { + cks += buf[i]; + } + if (cks == buf[sz]) + return 1; + } + + return 0; +} + +static enum HAL_UART_ID_T trace_uart = HAL_UART_ID_0; + +static struct HAL_UART_CFG_T uart_cfg_nodma = { + .parity = HAL_UART_PARITY_NONE, + .stop = HAL_UART_STOP_BITS_1, + .data = HAL_UART_DATA_BITS_8, + .flow = HAL_UART_FLOW_CONTROL_NONE,//HAL_UART_FLOW_CONTROL_RTSCTS, + .tx_level = HAL_UART_FIFO_LEVEL_1_2, + .rx_level = HAL_UART_FIFO_LEVEL_1_2, + .baud = 921600, + .dma_rx = false, + .dma_tx = false, + .dma_rx_stop_on_err = false, +}; + + +static uint8_t _inbyte(unsigned int delay) +{ + return hal_uart_blocked_getc(trace_uart); +} + +static int _outbyte(uint8_t c) +{ + return hal_uart_blocked_putc(trace_uart, c); +} + +static void flushinput(void) +{ + while (_inbyte(((DLY_1S)*3)>>1) >= 0) + ; +} + +static unsigned char packet_no = 1; +static unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */ +static uint32_t packet_size = 1024; +static int crc_enabled; +static int packet_idx; + +static int xmodem_fill_packet(uint8_t *buff, uint8_t packetno, int len, int crc) +{ + int c = len; + int bufsz; + int i; + +#ifdef TRANSMIT_XMODEM_1K + buff[0] = STX; bufsz = 1024; +#else + buff[0] = SOH; bufsz = 128; +#endif + buff[1] = packetno; + buff[2] = ~packetno; + + //TRACE_IMM(4,"buff %p, packetno %d, len %d, crc %d", buff, packetno, len, crc); + if (c < bufsz) + buff[3+c] = CTRLZ; + if (crc) { + unsigned short ccrc = crc16_ccitt(&buff[3], bufsz); + buff[bufsz+3] = (ccrc>>8) & 0xFF; + buff[bufsz+4] = ccrc & 0xFF; + } + else { + unsigned char ccks = 0; + for (i = 3; i < bufsz+3; ++i) { + ccks += buff[i]; + } + buff[bufsz+3] = ccks; + } + return 0; +} + +static int xmodem_send_one_packet(void) +{ + int retry = 0; + int bufsz; + int crc = 1; + int i; + uint8_t c; + +#ifdef TRANSMIT_XMODEM_1K + bufsz = 1024; +#else + bufsz = 128; +#endif + packet_size = bufsz; + for (retry = 0; retry < MAXRETRANS; ++retry) { + for (i = 0; i < bufsz+4+(crc?1:0); ++i) { + _outbyte(xbuff[i]); + } + if ((c = _inbyte(DLY_1S)) >= 0 ) { + switch (c) { + case ACK: + return 0; + case CAN: + if ((c = _inbyte(DLY_1S)) == CAN) { + _outbyte(ACK); + flushinput(); + return -1; /* canceled by remote */ + } + break; + case NAK: + default: + break; + } + } + } + _outbyte(CAN); + _outbyte(CAN); + _outbyte(CAN); + flushinput(); + return -4; /* xmit error */ +} + +static int xmodem_connect_host(void) +{ + uint8_t c; + int retry; + + for( retry = 0; retry < 16; ++retry) { + if ((c = _inbyte((DLY_1S)<<1)) >= 0) { + switch (c) { + case 'C': + crc_enabled = 1; + return 0; + case NAK: + crc_enabled = 0; + return 0; + case CAN: + if ((c = _inbyte(DLY_1S)) == CAN) { + _outbyte(ACK); + flushinput(); + return -1; /* canceled by remote */ + } + break; + default: + break; + } + } + } + return -2; /* no sync */ +} + +static uint32_t filled_one_payload(uint8_t *dst, const uint8_t *data, size_t len, int ascii) +{ + static const char hexToASCII[] = "0123456789ABCDEF"; + int i; + uint8_t byte; + int c; + + if (ascii) { + for( i = 0; i < len; i++) { + c = *(data + i); + byte = c >> 4; + dst[i * 2] = hexToASCII[byte]; + byte = c & 0x0F; + dst[i * 2 + 1] = hexToASCII[byte]; + } + } else { + for( i = 0; i < len; i++) { + byte = *(data + i); + dst[i] = byte; + } + } + + return len << ascii; +} + +int xmodem_send_stream(const uint8_t *data, size_t size, int ascii) +{ + uint32_t left; + uint8_t *payload; + uint32_t filled; + int packet_room; + int xfer; + int ret; + uint8_t *dst; + const uint8_t *src; + + left = size; + + payload = &xbuff[3]; + + TRACE(1,"send size %d", size); + if ((ascii == 0) && (size % 2 != 0)) { + /* + * if don't need convert to ascii, the size should be multi of 2, + * because the packet should include ascii and binary at same time; + */ + return -1; + } + src = data; + while (left > 0) { + packet_room = packet_size - packet_idx; + if (left > (packet_room >> ascii)) + xfer = packet_room >> ascii; + else + xfer = left; + + /* + TRACE_IMM(2,"left %d packet room %d", left, packet_room); + TRACE_IMM(1,"xfer %d", xfer); + */ + dst = payload + packet_idx; + filled = filled_one_payload(dst, src, xfer, ascii); + src += xfer; + if ((filled + packet_idx) == packet_size ) { + xmodem_fill_packet(xbuff, packet_no, 1024, crc_enabled); + ret = xmodem_send_one_packet(); + //ret = 0; + if (ret == 0) + packet_no++; + memset(xbuff, 0, sizeof(xbuff)); + packet_idx = 0; + } else { + packet_idx += filled; + } + + left -= xfer; + } + + return size; +} + +static int xmodem_open_uart(int uart_id) +{ + uint32_t baud; + + TRACE_IMM(0,"\r\n XMODEM start ...."); + baud = hal_trace_get_baudrate(); + hal_trace_flush_buffer(); + hal_sys_timer_delay_us(3000); + hal_trace_close(); + uart_cfg_nodma.baud = baud; + hal_uart_open(trace_uart, &uart_cfg_nodma); + + return 0; +} + +int xmodem_start_xfer(uint32_t wait) +{ + int ret; + int delay = wait; + + while (!hal_uart_readable(trace_uart) && (delay > 0)) { + hal_sys_timer_delay(MS_TO_HWTICKS(1000)); + delay--; + TRACE_NOCRLF(1,"\b\b\b%3d", delay); + hal_trace_flush_buffer(); + } + if (delay == 0) { + TRACE_IMM(0,"\r\ntime out, cannot start XMODEM...."); + return -1; + } + + xmodem_open_uart(0); + ret = xmodem_connect_host(); + if (ret != 0) { + _outbyte(CAN); + _outbyte(CAN); + _outbyte(CAN); + flushinput(); + return -2; + } + return 0; +} + +int xmodem_stop_xfer(void) +{ + int ret = -1; + int retry; + int c; + + xmodem_fill_packet(xbuff, packet_no, packet_idx, crc_enabled); + ret = xmodem_send_one_packet(); + if (!ret) { + for (retry = 0; retry < 10; ++retry) { + _outbyte(EOT); + if ((c = _inbyte((DLY_1S)<<1)) == ACK) + return 0; + } + flushinput(); + } + return ret; +} + diff --git a/utils/xyzmodem/xyzmodem.h b/utils/xyzmodem/xyzmodem.h new file mode 100644 index 0000000..120379d --- /dev/null +++ b/utils/xyzmodem/xyzmodem.h @@ -0,0 +1,15 @@ +#ifndef __XYZ_MODEM__ +#define __XYZ_MODEM__ + +/* + * start xmodem transfer + * param: wait, connect timeout in seconds + * return, 0 is ok + * other value is error; + */ +int xmodem_start_xfer(uint32_t wait); +int xmodem_stop_xfer(void); +int xmodem_send_stream(const uint8_t *data, size_t size, int ascii); + +#endif /*__XYZ_MODEM__*/ +